diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index a67a95325dfd..ef76161daea1 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -52,6 +52,14 @@ # xargs -n1 | sort | uniq -d; # done +# 20230509: OpenSSL 3.0.8 + +OLD_LIBS+=lib/libcrypto.so.111 +OLD_FILES+=usr/lib/engines/capi.so +OLD_FILES+=usr/lib/engines/padlock.so +OLD_LIBS+=usr/lib/libssl.so.111 +OLD_DIRS+=usr/lib/engines + # 20230505: md5 tests are now self-contained OLD_FILES+=usr/tests/sbin/md5/1.inp OLD_FILES+=usr/tests/sbin/md5/1.sha512-p.chk diff --git a/crypto/openssl/ACKNOWLEDGEMENTS b/crypto/openssl/ACKNOWLEDGEMENTS deleted file mode 100644 index d21dccbb79cf..000000000000 --- a/crypto/openssl/ACKNOWLEDGEMENTS +++ /dev/null @@ -1,2 +0,0 @@ -Please https://www.openssl.org/community/thanks.html for the current -acknowledgements. diff --git a/crypto/openssl/ACKNOWLEDGEMENTS.md b/crypto/openssl/ACKNOWLEDGEMENTS.md new file mode 100644 index 000000000000..a4dab0c4fff4 --- /dev/null +++ b/crypto/openssl/ACKNOWLEDGEMENTS.md @@ -0,0 +1,6 @@ +Acknowlegements +=============== + +Please see our [Thanks!][] page for the current acknowledgements. + +[Thanks!]: https://www.openssl.org/community/thanks.html diff --git a/crypto/openssl/AUTHORS b/crypto/openssl/AUTHORS deleted file mode 100644 index dac46f8b7e08..000000000000 --- a/crypto/openssl/AUTHORS +++ /dev/null @@ -1,42 +0,0 @@ -# This is the list of OpenSSL authors for copyright purposes. -# -# This does not necessarily list everyone who has contributed code, since in -# some cases, their employer may be the copyright holder. To see the full list -# of contributors, see the revision history in source control. -OpenSSL Software Services, Inc. -OpenSSL Software Foundation, Inc. - -# Individuals -Andy Polyakov -Ben Laurie -Ben Kaduk -Bernd Edlinger -Bodo Möller -David Benjamin -David von Oheimb -Dmitry Belyavskiy (Дмитрий Белявский) -Emilia Käsper -Eric Young -Geoff Thorpe -Holger Reif -Kurt Roeckx -Lutz Jänicke -Mark J. Cox -Matt Caswell -Matthias St. Pierre -Nicola Tuveri -Nils Larsch -Patrick Steuer -Paul Dale -Paul C. Sutton -Paul Yang -Ralf S. Engelschall -Rich Salz -Richard Levitte -Shane Lontis -Stephen Henson -Steve Marquess -Tim Hudson -Tomáš Mráz -Ulf Möller -Viktor Dukhovni diff --git a/crypto/openssl/AUTHORS.md b/crypto/openssl/AUTHORS.md new file mode 100644 index 000000000000..dc6b534b82a5 --- /dev/null +++ b/crypto/openssl/AUTHORS.md @@ -0,0 +1,51 @@ +Authors +======= + +This is the list of OpenSSL authors for copyright purposes. +It does not necessarily list everyone who has contributed code, +since in some cases, their employer may be the copyright holder. +To see the full list of contributors, see the revision history in +source control. + +Groups +------ + + * OpenSSL Software Services, Inc. + * OpenSSL Software Foundation, Inc. + +Individuals +----------- + + * Andy Polyakov + * Ben Laurie + * Ben Kaduk + * Bernd Edlinger + * Bodo Möller + * David Benjamin + * David von Oheimb + * Dmitry Belyavskiy (Дмитрий Белявский) + * Emilia Käsper + * Eric Young + * Geoff Thorpe + * Holger Reif + * Kurt Roeckx + * Lutz Jänicke + * Mark J. Cox + * Matt Caswell + * Matthias St. Pierre + * Nicola Tuveri + * Nils Larsch + * Patrick Steuer + * Paul Dale + * Paul C. Sutton + * Paul Yang + * Ralf S. Engelschall + * Rich Salz + * Richard Levitte + * Shane Lontis + * Stephen Henson + * Steve Marquess + * Tim Hudson + * Tomáš Mráz + * Ulf Möller + * Viktor Dukhovni diff --git a/crypto/openssl/CHANGES b/crypto/openssl/CHANGES deleted file mode 100644 index 459605bf71b6..000000000000 --- a/crypto/openssl/CHANGES +++ /dev/null @@ -1,13904 +0,0 @@ - - OpenSSL CHANGES - _______________ - - This is a high-level summary of the most important changes. - For a full list of changes, see the git commit log; for example, - https://github.com/openssl/openssl/commits/ and pick the appropriate - release branch. - - Changes between 1.1.1s and 1.1.1t [7 Feb 2023] - - *) Fixed X.400 address type confusion in X.509 GeneralName. - - There is a type confusion vulnerability relating to X.400 address processing - inside an X.509 GeneralName. X.400 addresses were parsed as an ASN1_STRING - but subsequently interpreted by GENERAL_NAME_cmp as an ASN1_TYPE. This - vulnerability may allow an attacker who can provide a certificate chain and - CRL (neither of which need have a valid signature) to pass arbitrary - pointers to a memcmp call, creating a possible read primitive, subject to - some constraints. Refer to the advisory for more information. Thanks to - David Benjamin for discovering this issue. (CVE-2023-0286) - - This issue has been fixed by changing the public header file definition of - GENERAL_NAME so that x400Address reflects the implementation. It was not - possible for any existing application to successfully use the existing - definition; however, if any application references the x400Address field - (e.g. in dead code), note that the type of this field has changed. There is - no ABI change. - [Hugo Landau] - - *) Fixed Use-after-free following BIO_new_NDEF. - - The public API function BIO_new_NDEF is a helper function used for - streaming ASN.1 data via a BIO. It is primarily used internally to OpenSSL - to support the SMIME, CMS and PKCS7 streaming capabilities, but may also - be called directly by end user applications. - - The function receives a BIO from the caller, prepends a new BIO_f_asn1 - filter BIO onto the front of it to form a BIO chain, and then returns - the new head of the BIO chain to the caller. Under certain conditions, - for example if a CMS recipient public key is invalid, the new filter BIO - is freed and the function returns a NULL result indicating a failure. - However, in this case, the BIO chain is not properly cleaned up and the - BIO passed by the caller still retains internal pointers to the previously - freed filter BIO. If the caller then goes on to call BIO_pop() on the BIO - then a use-after-free will occur. This will most likely result in a crash. - (CVE-2023-0215) - [Viktor Dukhovni, Matt Caswell] - - *) Fixed Double free after calling PEM_read_bio_ex. - - The function PEM_read_bio_ex() reads a PEM file from a BIO and parses and - decodes the "name" (e.g. "CERTIFICATE"), any header data and the payload - data. If the function succeeds then the "name_out", "header" and "data" - arguments are populated with pointers to buffers containing the relevant - decoded data. The caller is responsible for freeing those buffers. It is - possible to construct a PEM file that results in 0 bytes of payload data. - In this case PEM_read_bio_ex() will return a failure code but will populate - the header argument with a pointer to a buffer that has already been freed. - If the caller also frees this buffer then a double free will occur. This - will most likely lead to a crash. - - The functions PEM_read_bio() and PEM_read() are simple wrappers around - PEM_read_bio_ex() and therefore these functions are also directly affected. - - These functions are also called indirectly by a number of other OpenSSL - functions including PEM_X509_INFO_read_bio_ex() and - SSL_CTX_use_serverinfo_file() which are also vulnerable. Some OpenSSL - internal uses of these functions are not vulnerable because the caller does - not free the header argument if PEM_read_bio_ex() returns a failure code. - (CVE-2022-4450) - [Kurt Roeckx, Matt Caswell] - - *) Fixed Timing Oracle in RSA Decryption. - - A timing based side channel exists in the OpenSSL RSA Decryption - implementation which could be sufficient to recover a plaintext across - a network in a Bleichenbacher style attack. To achieve a successful - decryption an attacker would have to be able to send a very large number - of trial messages for decryption. The vulnerability affects all RSA padding - modes: PKCS#1 v1.5, RSA-OEAP and RSASVE. - (CVE-2022-4304) - [Dmitry Belyavsky, Hubert Kario] - - Changes between 1.1.1r and 1.1.1s [1 Nov 2022] - - *) Fixed a regression introduced in 1.1.1r version not refreshing the - certificate data to be signed before signing the certificate. - [Gibeom Gwon] - - Changes between 1.1.1q and 1.1.1r [11 Oct 2022] - - *) Fixed the linux-mips64 Configure target which was missing the - SIXTY_FOUR_BIT bn_ops flag. This was causing heap corruption on that - platform. - [Adam Joseph] - - *) Fixed a strict aliasing problem in bn_nist. Clang-14 optimisation was - causing incorrect results in some cases as a result. - [Paul Dale] - - *) Fixed SSL_pending() and SSL_has_pending() with DTLS which were failing to - report correct results in some cases - [Matt Caswell] - - *) Fixed a regression introduced in 1.1.1o for re-signing certificates with - different key sizes - [Todd Short] - - *) Added the loongarch64 target - [Shi Pujin] - - *) Fixed a DRBG seed propagation thread safety issue - [Bernd Edlinger] - - *) Fixed a memory leak in tls13_generate_secret - [Bernd Edlinger] - - *) Fixed reported performance degradation on aarch64. Restored the - implementation prior to commit 2621751 ("aes/asm/aesv8-armx.pl: avoid - 32-bit lane assignment in CTR mode") for 64bit targets only, since it is - reportedly 2-17% slower and the silicon errata only affects 32bit targets. - The new algorithm is still used for 32 bit targets. - [Bernd Edlinger] - - *) Added a missing header for memcmp that caused compilation failure on some - platforms - [Gregor Jasny] - - Changes between 1.1.1p and 1.1.1q [5 Jul 2022] - - *) AES OCB mode for 32-bit x86 platforms using the AES-NI assembly optimised - implementation would not encrypt the entirety of the data under some - circumstances. This could reveal sixteen bytes of data that was - preexisting in the memory that wasn't written. In the special case of - "in place" encryption, sixteen bytes of the plaintext would be revealed. - - Since OpenSSL does not support OCB based cipher suites for TLS and DTLS, - they are both unaffected. - (CVE-2022-2097) - [Alex Chernyakhovsky, David Benjamin, Alejandro Sedeño] - - Changes between 1.1.1o and 1.1.1p [21 Jun 2022] - - *) In addition to the c_rehash shell command injection identified in - CVE-2022-1292, further bugs where the c_rehash script does not - properly sanitise shell metacharacters to prevent command injection have been - fixed. - - When the CVE-2022-1292 was fixed it was not discovered that there - are other places in the script where the file names of certificates - being hashed were possibly passed to a command executed through the shell. - - This script is distributed by some operating systems in a manner where - it is automatically executed. On such operating systems, an attacker - could execute arbitrary commands with the privileges of the script. - - Use of the c_rehash script is considered obsolete and should be replaced - by the OpenSSL rehash command line tool. - (CVE-2022-2068) - [Daniel Fiala, Tomáš Mráz] - - *) When OpenSSL TLS client is connecting without any supported elliptic - curves and TLS-1.3 protocol is disabled the connection will no longer fail - if a ciphersuite that does not use a key exchange based on elliptic - curves can be negotiated. - [Tomáš Mráz] - - Changes between 1.1.1n and 1.1.1o [3 May 2022] - - *) Fixed a bug in the c_rehash script which was not properly sanitising shell - metacharacters to prevent command injection. This script is distributed - by some operating systems in a manner where it is automatically executed. - On such operating systems, an attacker could execute arbitrary commands - with the privileges of the script. - - Use of the c_rehash script is considered obsolete and should be replaced - by the OpenSSL rehash command line tool. - (CVE-2022-1292) - [Tomáš Mráz] - - Changes between 1.1.1m and 1.1.1n [15 Mar 2022] - - *) Fixed a bug in the BN_mod_sqrt() function that can cause it to loop forever - for non-prime moduli. - - Internally this function is used when parsing certificates that contain - elliptic curve public keys in compressed form or explicit elliptic curve - parameters with a base point encoded in compressed form. - - It is possible to trigger the infinite loop by crafting a certificate that - has invalid explicit curve parameters. - - Since certificate parsing happens prior to verification of the certificate - signature, any process that parses an externally supplied certificate may - thus be subject to a denial of service attack. The infinite loop can also - be reached when parsing crafted private keys as they can contain explicit - elliptic curve parameters. - - Thus vulnerable situations include: - - - TLS clients consuming server certificates - - TLS servers consuming client certificates - - Hosting providers taking certificates or private keys from customers - - Certificate authorities parsing certification requests from subscribers - - Anything else which parses ASN.1 elliptic curve parameters - - Also any other applications that use the BN_mod_sqrt() where the attacker - can control the parameter values are vulnerable to this DoS issue. - (CVE-2022-0778) - [Tomáš Mráz] - - *) Add ciphersuites based on DHE_PSK (RFC 4279) and ECDHE_PSK (RFC 5489) - to the list of ciphersuites providing Perfect Forward Secrecy as - required by SECLEVEL >= 3. - - [Dmitry Belyavskiy, Nicola Tuveri] - - Changes between 1.1.1l and 1.1.1m [14 Dec 2021] - - *) Avoid loading of a dynamic engine twice. - - [Bernd Edlinger] - - *) Fixed building on Debian with kfreebsd kernels - - [Mattias Ellert] - - *) Prioritise DANE TLSA issuer certs over peer certs - - [Viktor Dukhovni] - - *) Fixed random API for MacOS prior to 10.12 - - These MacOS versions don't support the CommonCrypto APIs - - [Lenny Primak] - - Changes between 1.1.1k and 1.1.1l [24 Aug 2021] - - *) Fixed an SM2 Decryption Buffer Overflow. - - In order to decrypt SM2 encrypted data an application is expected to call the - API function EVP_PKEY_decrypt(). Typically an application will call this - function twice. The first time, on entry, the "out" parameter can be NULL and, - on exit, the "outlen" parameter is populated with the buffer size required to - hold the decrypted plaintext. The application can then allocate a sufficiently - sized buffer and call EVP_PKEY_decrypt() again, but this time passing a non-NULL - value for the "out" parameter. - - A bug in the implementation of the SM2 decryption code means that the - calculation of the buffer size required to hold the plaintext returned by the - first call to EVP_PKEY_decrypt() can be smaller than the actual size required by - the second call. This can lead to a buffer overflow when EVP_PKEY_decrypt() is - called by the application a second time with a buffer that is too small. - - A malicious attacker who is able present SM2 content for decryption to an - application could cause attacker chosen data to overflow the buffer by up to a - maximum of 62 bytes altering the contents of other data held after the - buffer, possibly changing application behaviour or causing the application to - crash. The location of the buffer is application dependent but is typically - heap allocated. - (CVE-2021-3711) - [Matt Caswell] - - *) Fixed various read buffer overruns processing ASN.1 strings - - ASN.1 strings are represented internally within OpenSSL as an ASN1_STRING - structure which contains a buffer holding the string data and a field holding - the buffer length. This contrasts with normal C strings which are repesented as - a buffer for the string data which is terminated with a NUL (0) byte. - - Although not a strict requirement, ASN.1 strings that are parsed using OpenSSL's - own "d2i" functions (and other similar parsing functions) as well as any string - whose value has been set with the ASN1_STRING_set() function will additionally - NUL terminate the byte array in the ASN1_STRING structure. - - However, it is possible for applications to directly construct valid ASN1_STRING - structures which do not NUL terminate the byte array by directly setting the - "data" and "length" fields in the ASN1_STRING array. This can also happen by - using the ASN1_STRING_set0() function. - - Numerous OpenSSL functions that print ASN.1 data have been found to assume that - the ASN1_STRING byte array will be NUL terminated, even though this is not - guaranteed for strings that have been directly constructed. Where an application - requests an ASN.1 structure to be printed, and where that ASN.1 structure - contains ASN1_STRINGs that have been directly constructed by the application - without NUL terminating the "data" field, then a read buffer overrun can occur. - - The same thing can also occur during name constraints processing of certificates - (for example if a certificate has been directly constructed by the application - instead of loading it via the OpenSSL parsing functions, and the certificate - contains non NUL terminated ASN1_STRING structures). It can also occur in the - X509_get1_email(), X509_REQ_get1_email() and X509_get1_ocsp() functions. - - If a malicious actor can cause an application to directly construct an - ASN1_STRING and then process it through one of the affected OpenSSL functions - then this issue could be hit. This might result in a crash (causing a Denial of - Service attack). It could also result in the disclosure of private memory - contents (such as private keys, or sensitive plaintext). - (CVE-2021-3712) - [Matt Caswell] - - Changes between 1.1.1j and 1.1.1k [25 Mar 2021] - - *) Fixed a problem with verifying a certificate chain when using the - X509_V_FLAG_X509_STRICT flag. This flag enables additional security checks - of the certificates present in a certificate chain. It is not set by - default. - - Starting from OpenSSL version 1.1.1h a check to disallow certificates in - the chain that have explicitly encoded elliptic curve parameters was added - as an additional strict check. - - An error in the implementation of this check meant that the result of a - previous check to confirm that certificates in the chain are valid CA - certificates was overwritten. This effectively bypasses the check - that non-CA certificates must not be able to issue other certificates. - - If a "purpose" has been configured then there is a subsequent opportunity - for checks that the certificate is a valid CA. All of the named "purpose" - values implemented in libcrypto perform this check. Therefore, where - a purpose is set the certificate chain will still be rejected even when the - strict flag has been used. A purpose is set by default in libssl client and - server certificate verification routines, but it can be overridden or - removed by an application. - - In order to be affected, an application must explicitly set the - X509_V_FLAG_X509_STRICT verification flag and either not set a purpose - for the certificate verification or, in the case of TLS client or server - applications, override the default purpose. - (CVE-2021-3450) - [Tomáš Mráz] - - *) Fixed an issue where an OpenSSL TLS server may crash if sent a maliciously - crafted renegotiation ClientHello message from a client. If a TLSv1.2 - renegotiation ClientHello omits the signature_algorithms extension (where - it was present in the initial ClientHello), but includes a - signature_algorithms_cert extension then a NULL pointer dereference will - result, leading to a crash and a denial of service attack. - - A server is only vulnerable if it has TLSv1.2 and renegotiation enabled - (which is the default configuration). OpenSSL TLS clients are not impacted - by this issue. - (CVE-2021-3449) - [Peter Kästle and Samuel Sapalski] - - Changes between 1.1.1i and 1.1.1j [16 Feb 2021] - - *) Fixed the X509_issuer_and_serial_hash() function. It attempts to - create a unique hash value based on the issuer and serial number data - contained within an X509 certificate. However it was failing to correctly - handle any errors that may occur while parsing the issuer field (which might - occur if the issuer field is maliciously constructed). This may subsequently - result in a NULL pointer deref and a crash leading to a potential denial of - service attack. - (CVE-2021-23841) - [Matt Caswell] - - *) Fixed the RSA_padding_check_SSLv23() function and the RSA_SSLV23_PADDING - padding mode to correctly check for rollback attacks. This is considered a - bug in OpenSSL 1.1.1 because it does not support SSLv2. In 1.0.2 this is - CVE-2021-23839. - [Matt Caswell] - - *) Fixed the EVP_CipherUpdate, EVP_EncryptUpdate and EVP_DecryptUpdate - functions. Previously they could overflow the output length argument in some - cases where the input length is close to the maximum permissable length for - an integer on the platform. In such cases the return value from the function - call would be 1 (indicating success), but the output length value would be - negative. This could cause applications to behave incorrectly or crash. - (CVE-2021-23840) - [Matt Caswell] - - *) Fixed SRP_Calc_client_key so that it runs in constant time. The previous - implementation called BN_mod_exp without setting BN_FLG_CONSTTIME. This - could be exploited in a side channel attack to recover the password. Since - the attack is local host only this is outside of the current OpenSSL - threat model and therefore no CVE is assigned. - - Thanks to Mohammed Sabt and Daniel De Almeida Braga for reporting this - issue. - [Matt Caswell] - - Changes between 1.1.1h and 1.1.1i [8 Dec 2020] - - *) Fixed NULL pointer deref in the GENERAL_NAME_cmp function - This function could crash if both GENERAL_NAMEs contain an EDIPARTYNAME. - If an attacker can control both items being compared then this could lead - to a possible denial of service attack. OpenSSL itself uses the - GENERAL_NAME_cmp function for two purposes: - 1) Comparing CRL distribution point names between an available CRL and a - CRL distribution point embedded in an X509 certificate - 2) When verifying that a timestamp response token signer matches the - timestamp authority name (exposed via the API functions - TS_RESP_verify_response and TS_RESP_verify_token) - (CVE-2020-1971) - [Matt Caswell] - - *) Add support for Apple Silicon M1 Macs with the darwin64-arm64-cc target. - [Stuart Carnie] - - *) The security callback, which can be customised by application code, supports - the security operation SSL_SECOP_TMP_DH. This is defined to take an EVP_PKEY - in the "other" parameter. In most places this is what is passed. All these - places occur server side. However there was one client side call of this - security operation and it passed a DH object instead. This is incorrect - according to the definition of SSL_SECOP_TMP_DH, and is inconsistent with all - of the other locations. Therefore this client side call has been changed to - pass an EVP_PKEY instead. - [Matt Caswell] - - *) In 1.1.1h, an expired trusted (root) certificate was not anymore rejected - when validating a certificate path. This check is restored in 1.1.1i. - [David von Oheimb] - - Changes between 1.1.1g and 1.1.1h [22 Sep 2020] - - *) Certificates with explicit curve parameters are now disallowed in - verification chains if the X509_V_FLAG_X509_STRICT flag is used. - [Tomas Mraz] - - *) The 'MinProtocol' and 'MaxProtocol' configuration commands now silently - ignore TLS protocol version bounds when configuring DTLS-based contexts, and - conversely, silently ignore DTLS protocol version bounds when configuring - TLS-based contexts. The commands can be repeated to set bounds of both - types. The same applies with the corresponding "min_protocol" and - "max_protocol" command-line switches, in case some application uses both TLS - and DTLS. - - SSL_CTX instances that are created for a fixed protocol version (e.g. - TLSv1_server_method()) also silently ignore version bounds. Previously - attempts to apply bounds to these protocol versions would result in an - error. Now only the "version-flexible" SSL_CTX instances are subject to - limits in configuration files in command-line options. - [Viktor Dukhovni] - - *) Handshake now fails if Extended Master Secret extension is dropped - on renegotiation. - [Tomas Mraz] - - *) Accidentally, an expired trusted (root) certificate is not anymore rejected - when validating a certificate path. - [David von Oheimb] - - *) The Oracle Developer Studio compiler will start reporting deprecated APIs - - Changes between 1.1.1f and 1.1.1g [21 Apr 2020] - - *) Fixed segmentation fault in SSL_check_chain() - Server or client applications that call the SSL_check_chain() function - during or after a TLS 1.3 handshake may crash due to a NULL pointer - dereference as a result of incorrect handling of the - "signature_algorithms_cert" TLS extension. The crash occurs if an invalid - or unrecognised signature algorithm is received from the peer. This could - be exploited by a malicious peer in a Denial of Service attack. - (CVE-2020-1967) - [Benjamin Kaduk] - - *) Added AES consttime code for no-asm configurations - an optional constant time support for AES was added - when building openssl for no-asm. - Enable with: ./config no-asm -DOPENSSL_AES_CONST_TIME - Disable with: ./config no-asm -DOPENSSL_NO_AES_CONST_TIME - At this time this feature is by default disabled. - It will be enabled by default in 3.0. - [Bernd Edlinger] - - Changes between 1.1.1e and 1.1.1f [31 Mar 2020] - - *) Revert the change of EOF detection while reading in libssl to avoid - regressions in applications depending on the current way of reporting - the EOF. As the existing method is not fully accurate the change to - reporting the EOF via SSL_ERROR_SSL is kept on the current development - branch and will be present in the 3.0 release. - [Tomas Mraz] - - *) Revised BN_generate_prime_ex to not avoid factors 3..17863 in p-1 - when primes for RSA keys are computed. - Since we previously always generated primes == 2 (mod 3) for RSA keys, - the 2-prime and 3-prime RSA modules were easy to distinguish, since - N = p*q = 1 (mod 3), but N = p*q*r = 2 (mod 3). Therefore fingerprinting - 2-prime vs. 3-prime RSA keys was possible by computing N mod 3. - This avoids possible fingerprinting of newly generated RSA modules. - [Bernd Edlinger] - - Changes between 1.1.1d and 1.1.1e [17 Mar 2020] - *) Properly detect EOF while reading in libssl. Previously if we hit an EOF - while reading in libssl then we would report an error back to the - application (SSL_ERROR_SYSCALL) but errno would be 0. We now add - an error to the stack (which means we instead return SSL_ERROR_SSL) and - therefore give a hint as to what went wrong. - [Matt Caswell] - - *) Check that ed25519 and ed448 are allowed by the security level. Previously - signature algorithms not using an MD were not being checked that they were - allowed by the security level. - [Kurt Roeckx] - - *) Fixed SSL_get_servername() behaviour. The behaviour of SSL_get_servername() - was not quite right. The behaviour was not consistent between resumption - and normal handshakes, and also not quite consistent with historical - behaviour. The behaviour in various scenarios has been clarified and - it has been updated to make it match historical behaviour as closely as - possible. - [Matt Caswell] - - *) [VMS only] The header files that the VMS compilers include automatically, - __DECC_INCLUDE_PROLOGUE.H and __DECC_INCLUDE_EPILOGUE.H, use pragmas that - the C++ compiler doesn't understand. This is a shortcoming in the - compiler, but can be worked around with __cplusplus guards. - - C++ applications that use OpenSSL libraries must be compiled using the - qualifier '/NAMES=(AS_IS,SHORTENED)' to be able to use all the OpenSSL - functions. Otherwise, only functions with symbols of less than 31 - characters can be used, as the linker will not be able to successfully - resolve symbols with longer names. - [Richard Levitte] - - *) Corrected the documentation of the return values from the EVP_DigestSign* - set of functions. The documentation mentioned negative values for some - errors, but this was never the case, so the mention of negative values - was removed. - - Code that followed the documentation and thereby check with something - like 'EVP_DigestSignInit(...) <= 0' will continue to work undisturbed. - [Richard Levitte] - - *) Fixed an an overflow bug in the x64_64 Montgomery squaring procedure - used in exponentiation with 512-bit moduli. No EC algorithms are - affected. Analysis suggests that attacks against 2-prime RSA1024, - 3-prime RSA1536, and DSA1024 as a result of this defect would be very - difficult to perform and are not believed likely. Attacks against DH512 - are considered just feasible. However, for an attack the target would - have to re-use the DH512 private key, which is not recommended anyway. - Also applications directly using the low level API BN_mod_exp may be - affected if they use BN_FLG_CONSTTIME. - (CVE-2019-1551) - [Andy Polyakov] - - *) Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY. - The presence of this system service is determined at run-time. - [Richard Levitte] - - *) Added newline escaping functionality to a filename when using openssl dgst. - This output format is to replicate the output format found in the '*sum' - checksum programs. This aims to preserve backward compatibility. - [Matt Eaton, Richard Levitte, and Paul Dale] - - *) Print all values for a PKCS#12 attribute with 'openssl pkcs12', not just - the first value. - [Jon Spillett] - - 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 - thing, to include one public OpenSSL head file each. This tests that - the public header files can be usefully included in a C++ application. - - This test isn't enabled by default. It can be enabled with the option - 'enable-buildtest-c++'. - [Richard Levitte] - - *) Enable SHA3 pre-hashing for ECDSA and DSA. - [Patrick Steuer] - - *) Change the default RSA, DSA and DH size to 2048 bit instead of 1024. - This changes the size when using the genpkey app when no size is given. It - fixes an omission in earlier changes that changed all RSA, DSA and DH - generation apps to use 2048 bits by default. - [Kurt Roeckx] - - *) Reorganize the manual pages to consistently have RETURN VALUES, - EXAMPLES, SEE ALSO and HISTORY come in that order, and adjust - util/fix-doc-nits accordingly. - [Paul Yang, Joshua Lock] - - *) Add the missing accessor EVP_PKEY_get0_engine() - [Matt Caswell] - - *) Have apps like 's_client' and 's_server' output the signature scheme - along with other cipher suite parameters when debugging. - [Lorinczy Zsigmond] - - *) Make OPENSSL_config() error agnostic again. - [Richard Levitte] - - *) Do the error handling in RSA decryption constant time. - [Bernd Edlinger] - - *) Prevent over long nonces in ChaCha20-Poly1305. - - ChaCha20-Poly1305 is an AEAD cipher, and requires a unique nonce input - for every encryption operation. RFC 7539 specifies that the nonce value - (IV) should be 96 bits (12 bytes). OpenSSL allows a variable nonce length - and front pads the nonce with 0 bytes if it is less than 12 - bytes. However it also incorrectly allows a nonce to be set of up to 16 - bytes. In this case only the last 12 bytes are significant and any - additional leading bytes are ignored. - - It is a requirement of using this cipher that nonce values are - unique. Messages encrypted using a reused nonce value are susceptible to - serious confidentiality and integrity attacks. If an application changes - the default nonce length to be longer than 12 bytes and then makes a - change to the leading bytes of the nonce expecting the new value to be a - new unique nonce then such an application could inadvertently encrypt - messages with a reused nonce. - - Additionally the ignored bytes in a long nonce are not covered by the - integrity guarantee of this cipher. Any application that relies on the - integrity of these ignored leading bytes of a long nonce may be further - affected. Any OpenSSL internal use of this cipher, including in SSL/TLS, - is safe because no such use sets such a long nonce value. However user - applications that use this cipher directly and set a non-default nonce - length to be longer than 12 bytes may be vulnerable. - - This issue was reported to OpenSSL on 16th of March 2019 by Joran Dirk - Greef of Ronomon. - (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] - - Changes between 1.1.1a and 1.1.1b [26 Feb 2019] - - *) Added SCA hardening for modular field inversion in EC_GROUP through - a new dedicated field_inv() pointer in EC_METHOD. - This also addresses a leakage affecting conversions from projective - to affine coordinates. - [Billy Bob Brumley, Nicola Tuveri] - - *) Change the info callback signals for the start and end of a post-handshake - message exchange in TLSv1.3. In 1.1.1/1.1.1a we used SSL_CB_HANDSHAKE_START - and SSL_CB_HANDSHAKE_DONE. Experience has shown that many applications get - confused by this and assume that a TLSv1.2 renegotiation has started. This - can break KeyUpdate handling. Instead we no longer signal the start and end - of a post handshake message exchange (although the messages themselves are - still signalled). This could break some applications that were expecting - the old signals. However without this KeyUpdate is not usable for many - applications. - [Matt Caswell] - - *) Fix a bug in the computation of the endpoint-pair shared secret used - by DTLS over SCTP. This breaks interoperability with older versions - of OpenSSL like OpenSSL 1.1.0 and OpenSSL 1.0.2. There is a runtime - switch SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG (off by default) enabling - interoperability with such broken implementations. However, enabling - this switch breaks interoperability with correct implementations. - - *) Fix a use after free bug in d2i_X509_PUBKEY when overwriting a - re-used X509_PUBKEY object if the second PUBKEY is malformed. - [Bernd Edlinger] - - *) Move strictness check from EVP_PKEY_asn1_new() to EVP_PKEY_asn1_add0(). - [Richard Levitte] - - *) Remove the 'dist' target and add a tarball building script. The - 'dist' target has fallen out of use, and it shouldn't be - necessary to configure just to create a source distribution. - [Richard Levitte] - - *) Added support for Linux Kernel TLS data-path. The Linux Kernel data-path - improves application performance by removing data copies and providing - applications with zero-copy system calls such as sendfile and splice. - [Boris Pismenny] - - Changes between 1.1.1 and 1.1.1a [20 Nov 2018] - - *) Timing vulnerability in DSA signature generation - - The OpenSSL DSA signature algorithm has been shown to be vulnerable to a - timing side channel attack. An attacker could use variations in the signing - algorithm to recover the private key. - - This issue was reported to OpenSSL on 16th October 2018 by Samuel Weiser. - (CVE-2018-0734) - [Paul Dale] - - *) Timing vulnerability in ECDSA signature generation - - The OpenSSL ECDSA signature algorithm has been shown to be vulnerable to a - timing side channel attack. An attacker could use variations in the signing - algorithm to recover the private key. - - This issue was reported to OpenSSL on 25th October 2018 by Samuel Weiser. - (CVE-2018-0735) - [Paul Dale] - - *) Added EVP_PKEY_ECDH_KDF_X9_63 and ecdh_KDF_X9_63() as replacements for - the EVP_PKEY_ECDH_KDF_X9_62 KDF type and ECDH_KDF_X9_62(). The old names - are retained for backwards compatibility. - [Antoine Salon] - - *) Fixed the issue that RAND_add()/RAND_seed() silently discards random input - if its length exceeds 4096 bytes. The limit has been raised to a buffer size - of two gigabytes and the error handling improved. - - This issue was reported to OpenSSL by Dr. Falko Strenzke. It has been - categorized as a normal bug, not a security issue, because the DRBG reseeds - automatically and is fully functional even without additional randomness - provided by the application. - - Changes between 1.1.0i and 1.1.1 [11 Sep 2018] - - *) Add a new ClientHello callback. Provides a callback interface that gives - the application the ability to adjust the nascent SSL object at the - earliest stage of ClientHello processing, immediately after extensions have - been collected but before they have been processed. In particular, this - callback can adjust the supported TLS versions in response to the contents - of the ClientHello - [Benjamin Kaduk] - - *) Add SM2 base algorithm support. - [Jack Lloyd] - - *) s390x assembly pack: add (improved) hardware-support for the following - cryptographic primitives: sha3, shake, aes-gcm, aes-ccm, aes-ctr, aes-ofb, - aes-cfb/cfb8, aes-ecb. - [Patrick Steuer] - - *) Make EVP_PKEY_asn1_new() a bit stricter about its input. A NULL pem_str - parameter is no longer accepted, as it leads to a corrupt table. NULL - pem_str is reserved for alias entries only. - [Richard Levitte] - - *) Use the new ec_scalar_mul_ladder scaffold to implement a specialized ladder - step for prime curves. The new implementation is based on formulae from - differential addition-and-doubling in homogeneous projective coordinates - from Izu-Takagi "A fast parallel elliptic curve multiplication resistant - against side channel attacks" and Brier-Joye "Weierstrass Elliptic Curves - and Side-Channel Attacks" Eq. (8) for y-coordinate recovery, modified - to work in projective coordinates. - [Billy Bob Brumley, Nicola Tuveri] - - *) Change generating and checking of primes so that the error rate of not - being prime depends on the intended use based on the size of the input. - For larger primes this will result in more rounds of Miller-Rabin. - The maximal error rate for primes with more than 1080 bits is lowered - to 2^-128. - [Kurt Roeckx, Annie Yousar] - - *) Increase the number of Miller-Rabin rounds for DSA key generating to 64. - [Kurt Roeckx] - - *) The 'tsget' script is renamed to 'tsget.pl', to avoid confusion when - moving between systems, and to avoid confusion when a Windows build is - done with mingw vs with MSVC. For POSIX installs, there's still a - symlink or copy named 'tsget' to avoid that confusion as well. - [Richard Levitte] - - *) Revert blinding in ECDSA sign and instead make problematic addition - length-invariant. Switch even to fixed-length Montgomery multiplication. - [Andy Polyakov] - - *) Use the new ec_scalar_mul_ladder scaffold to implement a specialized ladder - step for binary curves. The new implementation is based on formulae from - differential addition-and-doubling in mixed Lopez-Dahab projective - coordinates, modified to independently blind the operands. - [Billy Bob Brumley, Sohaib ul Hassan, Nicola Tuveri] - - *) Add a scaffold to optionally enhance the Montgomery ladder implementation - for `ec_scalar_mul_ladder` (formerly `ec_mul_consttime`) allowing - EC_METHODs to implement their own specialized "ladder step", to take - advantage of more favorable coordinate systems or more efficient - differential addition-and-doubling algorithms. - [Billy Bob Brumley, Sohaib ul Hassan, Nicola Tuveri] - - *) Modified the random device based seed sources to keep the relevant - file descriptors open rather than reopening them on each access. - This allows such sources to operate in a chroot() jail without - the associated device nodes being available. This behaviour can be - controlled using RAND_keep_random_devices_open(). - [Paul Dale] - - *) Numerous side-channel attack mitigations have been applied. This may have - performance impacts for some algorithms for the benefit of improved - security. Specific changes are noted in this change log by their respective - authors. - [Matt Caswell] - - *) AIX shared library support overhaul. Switch to AIX "natural" way of - handling shared libraries, which means collecting shared objects of - different versions and bitnesses in one common archive. This allows to - mitigate conflict between 1.0 and 1.1 side-by-side installations. It - doesn't affect the way 3rd party applications are linked, only how - multi-version installation is managed. - [Andy Polyakov] - - *) Make ec_group_do_inverse_ord() more robust and available to other - EC cryptosystems, so that irrespective of BN_FLG_CONSTTIME, SCA - mitigations are applied to the fallback BN_mod_inverse(). - When using this function rather than BN_mod_inverse() directly, new - EC cryptosystem implementations are then safer-by-default. - [Billy Bob Brumley] - - *) Add coordinate blinding for EC_POINT and implement projective - coordinate blinding for generic prime curves as a countermeasure to - chosen point SCA attacks. - [Sohaib ul Hassan, Nicola Tuveri, Billy Bob Brumley] - - *) Add blinding to ECDSA and DSA signatures to protect against side channel - attacks discovered by Keegan Ryan (NCC Group). - [Matt Caswell] - - *) Enforce checking in the pkeyutl command line app to ensure that the input - length does not exceed the maximum supported digest length when performing - a sign, verify or verifyrecover operation. - [Matt Caswell] - - *) SSL_MODE_AUTO_RETRY is enabled by default. Applications that use blocking - I/O in combination with something like select() or poll() will hang. This - can be turned off again using SSL_CTX_clear_mode(). - Many applications do not properly handle non-application data records, and - TLS 1.3 sends more of such records. Setting SSL_MODE_AUTO_RETRY works - around the problems in those applications, but can also break some. - It's recommended to read the manpages about SSL_read(), SSL_write(), - SSL_get_error(), SSL_shutdown(), SSL_CTX_set_mode() and - SSL_CTX_set_read_ahead() again. - [Kurt Roeckx] - - *) When unlocking a pass phrase protected PEM file or PKCS#8 container, we - now allow empty (zero character) pass phrases. - [Richard Levitte] - - *) Apply blinding to binary field modular inversion and remove patent - pending (OPENSSL_SUN_GF2M_DIV) BN_GF2m_mod_div implementation. - [Billy Bob Brumley] - - *) Deprecate ec2_mult.c and unify scalar multiplication code paths for - binary and prime elliptic curves. - [Billy Bob Brumley] - - *) Remove ECDSA nonce padding: EC_POINT_mul is now responsible for - constant time fixed point multiplication. - [Billy Bob Brumley] - - *) Revise elliptic curve scalar multiplication with timing attack - defenses: ec_wNAF_mul redirects to a constant time implementation - when computing fixed point and variable point multiplication (which - in OpenSSL are mostly used with secret scalars in keygen, sign, - ECDH derive operations). - [Billy Bob Brumley, Nicola Tuveri, Cesar Pereida García, - Sohaib ul Hassan] - - *) Updated CONTRIBUTING - [Rich Salz] - - *) Updated DRBG / RAND to request nonce and additional low entropy - randomness from the system. - [Matthias St. Pierre] - - *) Updated 'openssl rehash' to use OpenSSL consistent default. - [Richard Levitte] - - *) Moved the load of the ssl_conf module to libcrypto, which helps - loading engines that libssl uses before libssl is initialised. - [Matt Caswell] - - *) Added EVP_PKEY_sign() and EVP_PKEY_verify() for EdDSA - [Matt Caswell] - - *) Fixed X509_NAME_ENTRY_set to get multi-valued RDNs right in all cases. - [Ingo Schwarze, Rich Salz] - - *) Added output of accepting IP address and port for 'openssl s_server' - [Richard Levitte] - - *) Added a new API for TLSv1.3 ciphersuites: - SSL_CTX_set_ciphersuites() - SSL_set_ciphersuites() - [Matt Caswell] - - *) Memory allocation failures consistently add an error to the error - stack. - [Rich Salz] - - *) Don't use OPENSSL_ENGINES and OPENSSL_CONF environment values - in libcrypto when run as setuid/setgid. - [Bernd Edlinger] - - *) Load any config file by default when libssl is used. - [Matt Caswell] - - *) Added new public header file and documentation - for the RAND_DRBG API. See manual page RAND_DRBG(7) for an overview. - [Matthias St. Pierre] - - *) QNX support removed (cannot find contributors to get their approval - for the license change). - [Rich Salz] - - *) TLSv1.3 replay protection for early data has been implemented. See the - SSL_read_early_data() man page for further details. - [Matt Caswell] - - *) Separated TLSv1.3 ciphersuite configuration out from TLSv1.2 ciphersuite - configuration. TLSv1.3 ciphersuites are not compatible with TLSv1.2 and - below. Similarly TLSv1.2 ciphersuites are not compatible with TLSv1.3. - In order to avoid issues where legacy TLSv1.2 ciphersuite configuration - would otherwise inadvertently disable all TLSv1.3 ciphersuites the - configuration has been separated out. See the ciphers man page or the - SSL_CTX_set_ciphersuites() man page for more information. - [Matt Caswell] - - *) On POSIX (BSD, Linux, ...) systems the ocsp(1) command running - in responder mode now supports the new "-multi" option, which - spawns the specified number of child processes to handle OCSP - requests. The "-timeout" option now also limits the OCSP - responder's patience to wait to receive the full client request - on a newly accepted connection. Child processes are respawned - as needed, and the CA index file is automatically reloaded - when changed. This makes it possible to run the "ocsp" responder - as a long-running service, making the OpenSSL CA somewhat more - feature-complete. In this mode, most diagnostic messages logged - after entering the event loop are logged via syslog(3) rather than - written to stderr. - [Viktor Dukhovni] - - *) Added support for X448 and Ed448. Heavily based on original work by - Mike Hamburg. - [Matt Caswell] - - *) Extend OSSL_STORE with capabilities to search and to narrow the set of - objects loaded. This adds the functions OSSL_STORE_expect() and - OSSL_STORE_find() as well as needed tools to construct searches and - get the search data out of them. - [Richard Levitte] - - *) Support for TLSv1.3 added. Note that users upgrading from an earlier - version of OpenSSL should review their configuration settings to ensure - that they are still appropriate for TLSv1.3. For further information see: - https://wiki.openssl.org/index.php/TLS1.3 - [Matt Caswell] - - *) Grand redesign of the OpenSSL random generator - - The default RAND method now utilizes an AES-CTR DRBG according to - NIST standard SP 800-90Ar1. The new random generator is essentially - a port of the default random generator from the OpenSSL FIPS 2.0 - object module. It is a hybrid deterministic random bit generator - using an AES-CTR bit stream and which seeds and reseeds itself - automatically using trusted system entropy sources. - - Some of its new features are: - o Support for multiple DRBG instances with seed chaining. - o The default RAND method makes use of a DRBG. - o There is a public and private DRBG instance. - o The DRBG instances are fork-safe. - o Keep all global DRBG instances on the secure heap if it is enabled. - o The public and private DRBG instance are per thread for lock free - operation - [Paul Dale, Benjamin Kaduk, Kurt Roeckx, Rich Salz, Matthias St. Pierre] - - *) Changed Configure so it only says what it does and doesn't dump - so much data. Instead, ./configdata.pm should be used as a script - to display all sorts of configuration data. - [Richard Levitte] - - *) Added processing of "make variables" to Configure. - [Richard Levitte] - - *) Added SHA512/224 and SHA512/256 algorithm support. - [Paul Dale] - - *) The last traces of Netware support, first removed in 1.1.0, have - now been removed. - [Rich Salz] - - *) Get rid of Makefile.shared, and in the process, make the processing - of certain files (rc.obj, or the .def/.map/.opt files produced from - the ordinal files) more visible and hopefully easier to trace and - debug (or make silent). - [Richard Levitte] - - *) Make it possible to have environment variable assignments as - arguments to config / Configure. - [Richard Levitte] - - *) Add multi-prime RSA (RFC 8017) support. - [Paul Yang] - - *) Add SM3 implemented according to GB/T 32905-2016 - [ Jack Lloyd , - Ronald Tse , - Erick Borsboom ] - - *) Add 'Maximum Fragment Length' TLS extension negotiation and support - as documented in RFC6066. - Based on a patch from Tomasz Moń - [Filipe Raimundo da Silva] - - *) Add SM4 implemented according to GB/T 32907-2016. - [ Jack Lloyd , - Ronald Tse , - Erick Borsboom ] - - *) Reimplement -newreq-nodes and ERR_error_string_n; the - original author does not agree with the license change. - [Rich Salz] - - *) Add ARIA AEAD TLS support. - [Jon Spillett] - - *) Some macro definitions to support VS6 have been removed. Visual - Studio 6 has not worked since 1.1.0 - [Rich Salz] - - *) Add ERR_clear_last_mark(), to allow callers to clear the last mark - without clearing the errors. - [Richard Levitte] - - *) Add "atfork" functions. If building on a system that without - pthreads, see doc/man3/OPENSSL_fork_prepare.pod for application - requirements. The RAND facility now uses/requires this. - [Rich Salz] - - *) Add SHA3. - [Andy Polyakov] - - *) The UI API becomes a permanent and integral part of libcrypto, i.e. - not possible to disable entirely. However, it's still possible to - disable the console reading UI method, UI_OpenSSL() (use UI_null() - as a fallback). - - To disable, configure with 'no-ui-console'. 'no-ui' is still - possible to use as an alias. Check at compile time with the - macro OPENSSL_NO_UI_CONSOLE. The macro OPENSSL_NO_UI is still - possible to check and is an alias for OPENSSL_NO_UI_CONSOLE. - [Richard Levitte] - - *) Add a STORE module, which implements a uniform and URI based reader of - stores that can contain keys, certificates, CRLs and numerous other - objects. The main API is loosely based on a few stdio functions, - and includes OSSL_STORE_open, OSSL_STORE_load, OSSL_STORE_eof, - OSSL_STORE_error and OSSL_STORE_close. - The implementation uses backends called "loaders" to implement arbitrary - URI schemes. There is one built in "loader" for the 'file' scheme. - [Richard Levitte] - - *) Add devcrypto engine. This has been implemented against cryptodev-linux, - then adjusted to work on FreeBSD 8.4 as well. - Enable by configuring with 'enable-devcryptoeng'. This is done by default - on BSD implementations, as cryptodev.h is assumed to exist on all of them. - [Richard Levitte] - - *) Module names can prefixed with OSSL_ or OPENSSL_. This affects - util/mkerr.pl, which is adapted to allow those prefixes, leading to - error code calls like this: - - OSSL_FOOerr(OSSL_FOO_F_SOMETHING, OSSL_FOO_R_WHATEVER); - - With this change, we claim the namespaces OSSL and OPENSSL in a manner - that can be encoded in C. For the foreseeable future, this will only - affect new modules. - [Richard Levitte and Tim Hudson] - - *) Removed BSD cryptodev engine. - [Rich Salz] - - *) Add a build target 'build_all_generated', to build all generated files - and only that. This can be used to prepare everything that requires - things like perl for a system that lacks perl and then move everything - to that system and do the rest of the build there. - [Richard Levitte] - - *) In the UI interface, make it possible to duplicate the user data. This - can be used by engines that need to retain the data for a longer time - than just the call where this user data is passed. - [Richard Levitte] - - *) Ignore the '-named_curve auto' value for compatibility of applications - with OpenSSL 1.0.2. - [Tomas Mraz ] - - *) Fragmented SSL/TLS alerts are no longer accepted. An alert message is 2 - bytes long. In theory it is permissible in SSLv3 - TLSv1.2 to fragment such - alerts across multiple records (some of which could be empty). In practice - it make no sense to send an empty alert record, or to fragment one. TLSv1.3 - prohibits this altogether and other libraries (BoringSSL, NSS) do not - support this at all. Supporting it adds significant complexity to the - record layer, and its removal is unlikely to cause interoperability - issues. - [Matt Caswell] - - *) Add the ASN.1 types INT32, UINT32, INT64, UINT64 and variants prefixed - with Z. These are meant to replace LONG and ZLONG and to be size safe. - The use of LONG and ZLONG is discouraged and scheduled for deprecation - in OpenSSL 1.2.0. - [Richard Levitte] - - *) Add the 'z' and 'j' modifiers to BIO_printf() et al formatting string, - 'z' is to be used for [s]size_t, and 'j' - with [u]int64_t. - [Richard Levitte, Andy Polyakov] - - *) Add EC_KEY_get0_engine(), which does for EC_KEY what RSA_get0_engine() - does for RSA, etc. - [Richard Levitte] - - *) Have 'config' recognise 64-bit mingw and choose 'mingw64' as the target - platform rather than 'mingw'. - [Richard Levitte] - - *) The functions X509_STORE_add_cert and X509_STORE_add_crl return - success if they are asked to add an object which already exists - in the store. This change cascades to other functions which load - certificates and CRLs. - [Paul Dale] - - *) x86_64 assembly pack: annotate code with DWARF CFI directives to - facilitate stack unwinding even from assembly subroutines. - [Andy Polyakov] - - *) Remove VAX C specific definitions of OPENSSL_EXPORT, OPENSSL_EXTERN. - Also remove OPENSSL_GLOBAL entirely, as it became a no-op. - [Richard Levitte] - - *) Remove the VMS-specific reimplementation of gmtime from crypto/o_times.c. - VMS C's RTL has a fully up to date gmtime() and gmtime_r() since V7.1, - which is the minimum version we support. - [Richard Levitte] - - *) Certificate time validation (X509_cmp_time) enforces stricter - compliance with RFC 5280. Fractional seconds and timezone offsets - are no longer allowed. - [Emilia Käsper] - - *) Add support for ARIA - [Paul Dale] - - *) s_client will now send the Server Name Indication (SNI) extension by - default unless the new "-noservername" option is used. The server name is - based on the host provided to the "-connect" option unless overridden by - using "-servername". - [Matt Caswell] - - *) Add support for SipHash - [Todd Short] - - *) OpenSSL now fails if it receives an unrecognised record type in TLS1.0 - or TLS1.1. Previously this only happened in SSLv3 and TLS1.2. This is to - prevent issues where no progress is being made and the peer continually - sends unrecognised record types, using up resources processing them. - [Matt Caswell] - - *) 'openssl passwd' can now produce SHA256 and SHA512 based output, - using the algorithm defined in - https://www.akkadia.org/drepper/SHA-crypt.txt - [Richard Levitte] - - *) Heartbeat support has been removed; the ABI is changed for now. - [Richard Levitte, Rich Salz] - - *) Support for SSL_OP_NO_ENCRYPT_THEN_MAC in SSL_CONF_cmd. - [Emilia Käsper] - - *) The RSA "null" method, which was partially supported to avoid patent - issues, has been replaced to always returns NULL. - [Rich Salz] - - - Changes between 1.1.0h and 1.1.0i [xx XXX xxxx] - - *) Client DoS due to large DH parameter - - During key agreement in a TLS handshake using a DH(E) based ciphersuite a - malicious server can send a very large prime value to the client. This will - cause the client to spend an unreasonably long period of time generating a - key for this prime resulting in a hang until the client has finished. This - could be exploited in a Denial Of Service attack. - - This issue was reported to OpenSSL on 5th June 2018 by Guido Vranken - (CVE-2018-0732) - [Guido Vranken] - - *) Cache timing vulnerability in RSA Key Generation - - The OpenSSL RSA Key generation algorithm has been shown to be vulnerable to - a cache timing side channel attack. An attacker with sufficient access to - mount cache timing attacks during the RSA key generation process could - recover the private key. - - This issue was reported to OpenSSL on 4th April 2018 by Alejandro Cabrera - Aldaya, Billy Brumley, Cesar Pereida Garcia and Luis Manuel Alvarez Tapia. - (CVE-2018-0737) - [Billy Brumley] - - *) Make EVP_PKEY_asn1_new() a bit stricter about its input. A NULL pem_str - parameter is no longer accepted, as it leads to a corrupt table. NULL - pem_str is reserved for alias entries only. - [Richard Levitte] - - *) Revert blinding in ECDSA sign and instead make problematic addition - length-invariant. Switch even to fixed-length Montgomery multiplication. - [Andy Polyakov] - - *) Change generating and checking of primes so that the error rate of not - being prime depends on the intended use based on the size of the input. - For larger primes this will result in more rounds of Miller-Rabin. - The maximal error rate for primes with more than 1080 bits is lowered - to 2^-128. - [Kurt Roeckx, Annie Yousar] - - *) Increase the number of Miller-Rabin rounds for DSA key generating to 64. - [Kurt Roeckx] - - *) Add blinding to ECDSA and DSA signatures to protect against side channel - attacks discovered by Keegan Ryan (NCC Group). - [Matt Caswell] - - *) When unlocking a pass phrase protected PEM file or PKCS#8 container, we - now allow empty (zero character) pass phrases. - [Richard Levitte] - - *) Certificate time validation (X509_cmp_time) enforces stricter - compliance with RFC 5280. Fractional seconds and timezone offsets - are no longer allowed. - [Emilia Käsper] - - *) Fixed a text canonicalisation bug in CMS - - Where a CMS detached signature is used with text content the text goes - through a canonicalisation process first prior to signing or verifying a - signature. This process strips trailing space at the end of lines, converts - line terminators to CRLF and removes additional trailing line terminators - at the end of a file. A bug in the canonicalisation process meant that - some characters, such as form-feed, were incorrectly treated as whitespace - and removed. This is contrary to the specification (RFC5485). This fix - could mean that detached text data signed with an earlier version of - OpenSSL 1.1.0 may fail to verify using the fixed version, or text data - signed with a fixed OpenSSL may fail to verify with an earlier version of - OpenSSL 1.1.0. A workaround is to only verify the canonicalised text data - and use the "-binary" flag (for the "cms" command line application) or set - the SMIME_BINARY/PKCS7_BINARY/CMS_BINARY flags (if using CMS_verify()). - [Matt Caswell] - - Changes between 1.1.0g and 1.1.0h [27 Mar 2018] - - *) Constructed ASN.1 types with a recursive definition could exceed the stack - - Constructed ASN.1 types with a recursive definition (such as can be found - in PKCS7) could eventually exceed the stack given malicious input with - excessive recursion. This could result in a Denial Of Service attack. There - are no such structures used within SSL/TLS that come from untrusted sources - so this is considered safe. - - This issue was reported to OpenSSL on 4th January 2018 by the OSS-fuzz - project. - (CVE-2018-0739) - [Matt Caswell] - - *) Incorrect CRYPTO_memcmp on HP-UX PA-RISC - - Because of an implementation bug the PA-RISC CRYPTO_memcmp function is - effectively reduced to only comparing the least significant bit of each - byte. This allows an attacker to forge messages that would be considered as - authenticated in an amount of tries lower than that guaranteed by the - security claims of the scheme. The module can only be compiled by the - HP-UX assembler, so that only HP-UX PA-RISC targets are affected. - - This issue was reported to OpenSSL on 2nd March 2018 by Peter Waltenberg - (IBM). - (CVE-2018-0733) - [Andy Polyakov] - - *) Add a build target 'build_all_generated', to build all generated files - and only that. This can be used to prepare everything that requires - things like perl for a system that lacks perl and then move everything - to that system and do the rest of the build there. - [Richard Levitte] - - *) Backport SSL_OP_NO_RENGOTIATION - - OpenSSL 1.0.2 and below had the ability to disable renegotiation using the - (undocumented) SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS flag. Due to the opacity - changes this is no longer possible in 1.1.0. Therefore the new - SSL_OP_NO_RENEGOTIATION option from 1.1.1-dev has been backported to - 1.1.0 to provide equivalent functionality. - - Note that if an application built against 1.1.0h headers (or above) is run - using an older version of 1.1.0 (prior to 1.1.0h) then the option will be - accepted but nothing will happen, i.e. renegotiation will not be prevented. - [Matt Caswell] - - *) Removed the OS390-Unix config target. It relied on a script that doesn't - exist. - [Rich Salz] - - *) rsaz_1024_mul_avx2 overflow bug on x86_64 - - There is an overflow bug in the AVX2 Montgomery multiplication procedure - used in exponentiation with 1024-bit moduli. No EC algorithms are affected. - Analysis suggests that attacks against RSA and DSA as a result of this - defect would be very difficult to perform and are not believed likely. - Attacks against DH1024 are considered just feasible, because most of the - work necessary to deduce information about a private key may be performed - offline. The amount of resources required for such an attack would be - significant. However, for an attack on TLS to be meaningful, the server - would have to share the DH1024 private key among multiple clients, which is - no longer an option since CVE-2016-0701. - - This only affects processors that support the AVX2 but not ADX extensions - like Intel Haswell (4th generation). - - This issue was reported to OpenSSL by David Benjamin (Google). The issue - was originally found via the OSS-Fuzz project. - (CVE-2017-3738) - [Andy Polyakov] - - Changes between 1.1.0f and 1.1.0g [2 Nov 2017] - - *) bn_sqrx8x_internal carry bug on x86_64 - - There is a carry propagating bug in the x86_64 Montgomery squaring - procedure. No EC algorithms are affected. Analysis suggests that attacks - against RSA and DSA as a result of this defect would be very difficult to - perform and are not believed likely. Attacks against DH are considered just - feasible (although very difficult) because most of the work necessary to - deduce information about a private key may be performed offline. The amount - of resources required for such an attack would be very significant and - likely only accessible to a limited number of attackers. An attacker would - additionally need online access to an unpatched system using the target - private key in a scenario with persistent DH parameters and a private - key that is shared between multiple clients. - - This only affects processors that support the BMI1, BMI2 and ADX extensions - like Intel Broadwell (5th generation) and later or AMD Ryzen. - - This issue was reported to OpenSSL by the OSS-Fuzz project. - (CVE-2017-3736) - [Andy Polyakov] - - *) Malformed X.509 IPAddressFamily could cause OOB read - - If an X.509 certificate has a malformed IPAddressFamily extension, - OpenSSL could do a one-byte buffer overread. The most likely result - would be an erroneous display of the certificate in text format. - - This issue was reported to OpenSSL by the OSS-Fuzz project. - (CVE-2017-3735) - [Rich Salz] - - Changes between 1.1.0e and 1.1.0f [25 May 2017] - - *) Have 'config' recognise 64-bit mingw and choose 'mingw64' as the target - platform rather than 'mingw'. - [Richard Levitte] - - *) Remove the VMS-specific reimplementation of gmtime from crypto/o_times.c. - VMS C's RTL has a fully up to date gmtime() and gmtime_r() since V7.1, - which is the minimum version we support. - [Richard Levitte] - - Changes between 1.1.0d and 1.1.0e [16 Feb 2017] - - *) Encrypt-Then-Mac renegotiation crash - - During a renegotiation handshake if the Encrypt-Then-Mac extension is - negotiated where it was not in the original handshake (or vice-versa) then - this can cause OpenSSL to crash (dependant on ciphersuite). Both clients - and servers are affected. - - This issue was reported to OpenSSL by Joe Orton (Red Hat). - (CVE-2017-3733) - [Matt Caswell] - - Changes between 1.1.0c and 1.1.0d [26 Jan 2017] - - *) Truncated packet could crash via OOB read - - If one side of an SSL/TLS path is running on a 32-bit host and a specific - cipher is being used, then a truncated packet can cause that host to - perform an out-of-bounds read, usually resulting in a crash. - - This issue was reported to OpenSSL by Robert Święcki of Google. - (CVE-2017-3731) - [Andy Polyakov] - - *) Bad (EC)DHE parameters cause a client crash - - If a malicious server supplies bad parameters for a DHE or ECDHE key - exchange then this can result in the client attempting to dereference a - NULL pointer leading to a client crash. This could be exploited in a Denial - of Service attack. - - This issue was reported to OpenSSL by Guido Vranken. - (CVE-2017-3730) - [Matt Caswell] - - *) BN_mod_exp may produce incorrect results on x86_64 - - There is a carry propagating bug in the x86_64 Montgomery squaring - procedure. No EC algorithms are affected. Analysis suggests that attacks - against RSA and DSA as a result of this defect would be very difficult to - perform and are not believed likely. Attacks against DH are considered just - feasible (although very difficult) because most of the work necessary to - deduce information about a private key may be performed offline. The amount - of resources required for such an attack would be very significant and - likely only accessible to a limited number of attackers. An attacker would - additionally need online access to an unpatched system using the target - private key in a scenario with persistent DH parameters and a private - key that is shared between multiple clients. For example this can occur by - default in OpenSSL DHE based SSL/TLS ciphersuites. Note: This issue is very - similar to CVE-2015-3193 but must be treated as a separate problem. - - This issue was reported to OpenSSL by the OSS-Fuzz project. - (CVE-2017-3732) - [Andy Polyakov] - - Changes between 1.1.0b and 1.1.0c [10 Nov 2016] - - *) ChaCha20/Poly1305 heap-buffer-overflow - - TLS connections using *-CHACHA20-POLY1305 ciphersuites are susceptible to - a DoS attack by corrupting larger payloads. This can result in an OpenSSL - crash. This issue is not considered to be exploitable beyond a DoS. - - This issue was reported to OpenSSL by Robert Święcki (Google Security Team) - (CVE-2016-7054) - [Richard Levitte] - - *) CMS Null dereference - - Applications parsing invalid CMS structures can crash with a NULL pointer - dereference. This is caused by a bug in the handling of the ASN.1 CHOICE - type in OpenSSL 1.1.0 which can result in a NULL value being passed to the - structure callback if an attempt is made to free certain invalid encodings. - Only CHOICE structures using a callback which do not handle NULL value are - affected. - - This issue was reported to OpenSSL by Tyler Nighswander of ForAllSecure. - (CVE-2016-7053) - [Stephen Henson] - - *) Montgomery multiplication may produce incorrect results - - There is a carry propagating bug in the Broadwell-specific Montgomery - multiplication procedure that handles input lengths divisible by, but - longer than 256 bits. Analysis suggests that attacks against RSA, DSA - and DH private keys are impossible. This is because the subroutine in - question is not used in operations with the private key itself and an input - of the attacker's direct choice. Otherwise the bug can manifest itself as - transient authentication and key negotiation failures or reproducible - erroneous outcome of public-key operations with specially crafted input. - Among EC algorithms only Brainpool P-512 curves are affected and one - presumably can attack ECDH key negotiation. Impact was not analyzed in - detail, because pre-requisites for attack are considered unlikely. Namely - multiple clients have to choose the curve in question and the server has to - share the private key among them, neither of which is default behaviour. - Even then only clients that chose the curve will be affected. - - This issue was publicly reported as transient failures and was not - initially recognized as a security issue. Thanks to Richard Morgan for - providing reproducible case. - (CVE-2016-7055) - [Andy Polyakov] - - *) Removed automatic addition of RPATH in shared libraries and executables, - as this was a remainder from OpenSSL 1.0.x and isn't needed any more. - [Richard Levitte] - - Changes between 1.1.0a and 1.1.0b [26 Sep 2016] - - *) Fix Use After Free for large message sizes - - The patch applied to address CVE-2016-6307 resulted in an issue where if a - message larger than approx 16k is received then the underlying buffer to - store the incoming message is reallocated and moved. Unfortunately a - dangling pointer to the old location is left which results in an attempt to - write to the previously freed location. This is likely to result in a - crash, however it could potentially lead to execution of arbitrary code. - - This issue only affects OpenSSL 1.1.0a. - - This issue was reported to OpenSSL by Robert Święcki. - (CVE-2016-6309) - [Matt Caswell] - - Changes between 1.1.0 and 1.1.0a [22 Sep 2016] - - *) OCSP Status Request extension unbounded memory growth - - A malicious client can send an excessively large OCSP Status Request - extension. If that client continually requests renegotiation, sending a - large OCSP Status Request extension each time, then there will be unbounded - memory growth on the server. This will eventually lead to a Denial Of - Service attack through memory exhaustion. Servers with a default - configuration are vulnerable even if they do not support OCSP. Builds using - the "no-ocsp" build time option are not affected. - - This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) - (CVE-2016-6304) - [Matt Caswell] - - *) SSL_peek() hang on empty record - - OpenSSL 1.1.0 SSL/TLS will hang during a call to SSL_peek() if the peer - sends an empty record. This could be exploited by a malicious peer in a - Denial Of Service attack. - - This issue was reported to OpenSSL by Alex Gaynor. - (CVE-2016-6305) - [Matt Caswell] - - *) Excessive allocation of memory in tls_get_message_header() and - dtls1_preprocess_fragment() - - A (D)TLS message includes 3 bytes for its length in the header for the - message. This would allow for messages up to 16Mb in length. Messages of - this length are excessive and OpenSSL includes a check to ensure that a - peer is sending reasonably sized messages in order to avoid too much memory - being consumed to service a connection. A flaw in the logic of version - 1.1.0 means that memory for the message is allocated too early, prior to - the excessive message length check. Due to way memory is allocated in - OpenSSL this could mean an attacker could force up to 21Mb to be allocated - to service a connection. This could lead to a Denial of Service through - memory exhaustion. However, the excessive message length check still takes - place, and this would cause the connection to immediately fail. Assuming - that the application calls SSL_free() on the failed connection in a timely - manner then the 21Mb of allocated memory will then be immediately freed - again. Therefore the excessive memory allocation will be transitory in - nature. This then means that there is only a security impact if: - - 1) The application does not call SSL_free() in a timely manner in the event - that the connection fails - or - 2) The application is working in a constrained environment where there is - very little free memory - or - 3) The attacker initiates multiple connection attempts such that there are - multiple connections in a state where memory has been allocated for the - connection; SSL_free() has not yet been called; and there is insufficient - memory to service the multiple requests. - - Except in the instance of (1) above any Denial Of Service is likely to be - transitory because as soon as the connection fails the memory is - subsequently freed again in the SSL_free() call. However there is an - increased risk during this period of application crashes due to the lack of - memory - which would then mean a more serious Denial of Service. - - This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) - (CVE-2016-6307 and CVE-2016-6308) - [Matt Caswell] - - *) solaris-x86-cc, i.e. 32-bit configuration with vendor compiler, - had to be removed. Primary reason is that vendor assembler can't - assemble our modules with -KPIC flag. As result it, assembly - support, was not even available as option. But its lack means - lack of side-channel resistant code, which is incompatible with - security by todays standards. Fortunately gcc is readily available - prepackaged option, which we firmly point at... - [Andy Polyakov] - - Changes between 1.0.2h and 1.1.0 [25 Aug 2016] - - *) Windows command-line tool supports UTF-8 opt-in option for arguments - and console input. Setting OPENSSL_WIN32_UTF8 environment variable - (to any value) allows Windows user to access PKCS#12 file generated - with Windows CryptoAPI and protected with non-ASCII password, as well - as files generated under UTF-8 locale on Linux also protected with - non-ASCII password. - [Andy Polyakov] - - *) To mitigate the SWEET32 attack (CVE-2016-2183), 3DES cipher suites - have been disabled by default and removed from DEFAULT, just like RC4. - See the RC4 item below to re-enable both. - [Rich Salz] - - *) The method for finding the storage location for the Windows RAND seed file - has changed. First we check %RANDFILE%. If that is not set then we check - the directories %HOME%, %USERPROFILE% and %SYSTEMROOT% in that order. If - all else fails we fall back to C:\. - [Matt Caswell] - - *) The EVP_EncryptUpdate() function has had its return type changed from void - to int. A return of 0 indicates and error while a return of 1 indicates - success. - [Matt Caswell] - - *) The flags RSA_FLAG_NO_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME and - DH_FLAG_NO_EXP_CONSTTIME which previously provided the ability to switch - off the constant time implementation for RSA, DSA and DH have been made - no-ops and deprecated. - [Matt Caswell] - - *) Windows RAND implementation was simplified to only get entropy by - calling CryptGenRandom(). Various other RAND-related tickets - were also closed. - [Joseph Wylie Yandle, Rich Salz] - - *) The stack and lhash API's were renamed to start with OPENSSL_SK_ - and OPENSSL_LH_, respectively. The old names are available - with API compatibility. They new names are now completely documented. - [Rich Salz] - - *) Unify TYPE_up_ref(obj) methods signature. - SSL_CTX_up_ref(), SSL_up_ref(), X509_up_ref(), EVP_PKEY_up_ref(), - X509_CRL_up_ref(), X509_OBJECT_up_ref_count() methods are now returning an - int (instead of void) like all others TYPE_up_ref() methods. - So now these methods also check the return value of CRYPTO_atomic_add(), - and the validity of object reference counter. - [fdasilvayy@gmail.com] - - *) With Windows Visual Studio builds, the .pdb files are installed - alongside the installed libraries and executables. For a static - library installation, ossl_static.pdb is the associate compiler - generated .pdb file to be used when linking programs. - [Richard Levitte] - - *) Remove openssl.spec. Packaging files belong with the packagers. - [Richard Levitte] - - *) Automatic Darwin/OSX configuration has had a refresh, it will now - recognise x86_64 architectures automatically. You can still decide - to build for a different bitness with the environment variable - KERNEL_BITS (can be 32 or 64), for example: - - KERNEL_BITS=32 ./config - - [Richard Levitte] - - *) Change default algorithms in pkcs8 utility to use PKCS#5 v2.0, - 256 bit AES and HMAC with SHA256. - [Steve Henson] - - *) Remove support for MIPS o32 ABI on IRIX (and IRIX only). - [Andy Polyakov] - - *) Triple-DES ciphers have been moved from HIGH to MEDIUM. - [Rich Salz] - - *) To enable users to have their own config files and build file templates, - Configure looks in the directory indicated by the environment variable - OPENSSL_LOCAL_CONFIG_DIR as well as the in-source Configurations/ - directory. On VMS, OPENSSL_LOCAL_CONFIG_DIR is expected to be a logical - name and is used as is. - [Richard Levitte] - - *) The following datatypes were made opaque: X509_OBJECT, X509_STORE_CTX, - X509_STORE, X509_LOOKUP, and X509_LOOKUP_METHOD. The unused type - X509_CERT_FILE_CTX was removed. - [Rich Salz] - - *) "shared" builds are now the default. To create only static libraries use - the "no-shared" Configure option. - [Matt Caswell] - - *) Remove the no-aes, no-hmac, no-rsa, no-sha and no-md5 Configure options. - All of these option have not worked for some while and are fundamental - algorithms. - [Matt Caswell] - - *) Make various cleanup routines no-ops and mark them as deprecated. Most - global cleanup functions are no longer required because they are handled - via auto-deinit (see OPENSSL_init_crypto and OPENSSL_init_ssl man pages). - Explicitly de-initing can cause problems (e.g. where a library that uses - OpenSSL de-inits, but an application is still using it). The affected - functions are CONF_modules_free(), ENGINE_cleanup(), OBJ_cleanup(), - EVP_cleanup(), BIO_sock_cleanup(), CRYPTO_cleanup_all_ex_data(), - RAND_cleanup(), SSL_COMP_free_compression_methods(), ERR_free_strings() and - COMP_zlib_cleanup(). - [Matt Caswell] - - *) --strict-warnings no longer enables runtime debugging options - such as REF_DEBUG. Instead, debug options are automatically - enabled with '--debug' builds. - [Andy Polyakov, Emilia Käsper] - - *) Made DH and DH_METHOD opaque. The structures for managing DH objects - have been moved out of the public header files. New functions for managing - these have been added. - [Matt Caswell] - - *) Made RSA and RSA_METHOD opaque. The structures for managing RSA - objects have been moved out of the public header files. New - functions for managing these have been added. - [Richard Levitte] - - *) Made DSA and DSA_METHOD opaque. The structures for managing DSA objects - have been moved out of the public header files. New functions for managing - these have been added. - [Matt Caswell] - - *) Made BIO and BIO_METHOD opaque. The structures for managing BIOs have been - moved out of the public header files. New functions for managing these - have been added. - [Matt Caswell] - - *) Removed no-rijndael as a config option. Rijndael is an old name for AES. - [Matt Caswell] - - *) Removed the mk1mf build scripts. - [Richard Levitte] - - *) Headers are now wrapped, if necessary, with OPENSSL_NO_xxx, so - it is always safe to #include a header now. - [Rich Salz] - - *) Removed the aged BC-32 config and all its supporting scripts - [Richard Levitte] - - *) Removed support for Ultrix, Netware, and OS/2. - [Rich Salz] - - *) Add support for HKDF. - [Alessandro Ghedini] - - *) Add support for blake2b and blake2s - [Bill Cox] - - *) Added support for "pipelining". Ciphers that have the - EVP_CIPH_FLAG_PIPELINE flag set have a capability to process multiple - encryptions/decryptions simultaneously. There are currently no built-in - ciphers with this property but the expectation is that engines will be able - to offer it to significantly improve throughput. Support has been extended - into libssl so that multiple records for a single connection can be - processed in one go (for >=TLS 1.1). - [Matt Caswell] - - *) Added the AFALG engine. This is an async capable engine which is able to - offload work to the Linux kernel. In this initial version it only supports - AES128-CBC. The kernel must be version 4.1.0 or greater. - [Catriona Lucey] - - *) OpenSSL now uses a new threading API. It is no longer necessary to - set locking callbacks to use OpenSSL in a multi-threaded environment. There - are two supported threading models: pthreads and windows threads. It is - also possible to configure OpenSSL at compile time for "no-threads". The - old threading API should no longer be used. The functions have been - replaced with "no-op" compatibility macros. - [Alessandro Ghedini, Matt Caswell] - - *) Modify behavior of ALPN to invoke callback after SNI/servername - callback, such that updates to the SSL_CTX affect ALPN. - [Todd Short] - - *) Add SSL_CIPHER queries for authentication and key-exchange. - [Todd Short] - - *) Changes to the DEFAULT cipherlist: - - Prefer (EC)DHE handshakes over plain RSA. - - Prefer AEAD ciphers over legacy ciphers. - - Prefer ECDSA over RSA when both certificates are available. - - Prefer TLSv1.2 ciphers/PRF. - - Remove DSS, SEED, IDEA, CAMELLIA, and AES-CCM from the - default cipherlist. - [Emilia Käsper] - - *) Change the ECC default curve list to be this, in order: x25519, - secp256r1, secp521r1, secp384r1. - [Rich Salz] - - *) RC4 based libssl ciphersuites are now classed as "weak" ciphers and are - disabled by default. They can be re-enabled using the - enable-weak-ssl-ciphers option to Configure. - [Matt Caswell] - - *) If the server has ALPN configured, but supports no protocols that the - client advertises, send a fatal "no_application_protocol" alert. - This behaviour is SHALL in RFC 7301, though it isn't universally - implemented by other servers. - [Emilia Käsper] - - *) Add X25519 support. - Add ASN.1 and EVP_PKEY methods for X25519. This includes support - for public and private key encoding using the format documented in - draft-ietf-curdle-pkix-02. The corresponding EVP_PKEY method supports - key generation and key derivation. - - TLS support complies with draft-ietf-tls-rfc4492bis-08 and uses - X25519(29). - [Steve Henson] - - *) Deprecate SRP_VBASE_get_by_user. - SRP_VBASE_get_by_user had inconsistent memory management behaviour. - In order to fix an unavoidable memory leak (CVE-2016-0798), - SRP_VBASE_get_by_user was changed to ignore the "fake user" SRP - seed, even if the seed is configured. - - Users should use SRP_VBASE_get1_by_user instead. Note that in - SRP_VBASE_get1_by_user, caller must free the returned value. Note - also that even though configuring the SRP seed attempts to hide - invalid usernames by continuing the handshake with fake - credentials, this behaviour is not constant time and no strong - guarantees are made that the handshake is indistinguishable from - that of a valid user. - [Emilia Käsper] - - *) Configuration change; it's now possible to build dynamic engines - without having to build shared libraries and vice versa. This - only applies to the engines in engines/, those in crypto/engine/ - will always be built into libcrypto (i.e. "static"). - - Building dynamic engines is enabled by default; to disable, use - the configuration option "disable-dynamic-engine". - - The only requirements for building dynamic engines are the - presence of the DSO module and building with position independent - code, so they will also automatically be disabled if configuring - with "disable-dso" or "disable-pic". - - The macros OPENSSL_NO_STATIC_ENGINE and OPENSSL_NO_DYNAMIC_ENGINE - are also taken away from openssl/opensslconf.h, as they are - irrelevant. - [Richard Levitte] - - *) Configuration change; if there is a known flag to compile - position independent code, it will always be applied on the - libcrypto and libssl object files, and never on the application - object files. This means other libraries that use routines from - libcrypto / libssl can be made into shared libraries regardless - of how OpenSSL was configured. - - If this isn't desirable, the configuration options "disable-pic" - or "no-pic" can be used to disable the use of PIC. This will - also disable building shared libraries and dynamic engines. - [Richard Levitte] - - *) Removed JPAKE code. It was experimental and has no wide use. - [Rich Salz] - - *) The INSTALL_PREFIX Makefile variable has been renamed to - DESTDIR. That makes for less confusion on what this variable - is for. Also, the configuration option --install_prefix is - removed. - [Richard Levitte] - - *) Heartbeat for TLS has been removed and is disabled by default - for DTLS; configure with enable-heartbeats. Code that uses the - old #define's might need to be updated. - [Emilia Käsper, Rich Salz] - - *) Rename REF_CHECK to REF_DEBUG. - [Rich Salz] - - *) New "unified" build system - - The "unified" build system is aimed to be a common system for all - platforms we support. With it comes new support for VMS. - - This system builds supports building in a different directory tree - than the source tree. It produces one Makefile (for unix family - or lookalikes), or one descrip.mms (for VMS). - - The source of information to make the Makefile / descrip.mms is - small files called 'build.info', holding the necessary - information for each directory with source to compile, and a - template in Configurations, like unix-Makefile.tmpl or - descrip.mms.tmpl. - - With this change, the library names were also renamed on Windows - and on VMS. They now have names that are closer to the standard - on Unix, and include the major version number, and in certain - cases, the architecture they are built for. See "Notes on shared - libraries" in INSTALL. - - We rely heavily on the perl module Text::Template. - [Richard Levitte] - - *) Added support for auto-initialisation and de-initialisation of the library. - OpenSSL no longer requires explicit init or deinit routines to be called, - except in certain circumstances. See the OPENSSL_init_crypto() and - OPENSSL_init_ssl() man pages for further information. - [Matt Caswell] - - *) The arguments to the DTLSv1_listen function have changed. Specifically the - "peer" argument is now expected to be a BIO_ADDR object. - - *) Rewrite of BIO networking library. The BIO library lacked consistent - support of IPv6, and adding it required some more extensive - modifications. This introduces the BIO_ADDR and BIO_ADDRINFO types, - which hold all types of addresses and chains of address information. - It also introduces a new API, with functions like BIO_socket, - BIO_connect, BIO_listen, BIO_lookup and a rewrite of BIO_accept. - The source/sink BIOs BIO_s_connect, BIO_s_accept and BIO_s_datagram - have been adapted accordingly. - [Richard Levitte] - - *) RSA_padding_check_PKCS1_type_1 now accepts inputs with and without - the leading 0-byte. - [Emilia Käsper] - - *) CRIME protection: disable compression by default, even if OpenSSL is - compiled with zlib enabled. Applications can still enable compression - by calling SSL_CTX_clear_options(ctx, SSL_OP_NO_COMPRESSION), or by - using the SSL_CONF library to configure compression. - [Emilia Käsper] - - *) The signature of the session callback configured with - SSL_CTX_sess_set_get_cb was changed. The read-only input buffer - was explicitly marked as 'const unsigned char*' instead of - 'unsigned char*'. - [Emilia Käsper] - - *) Always DPURIFY. Remove the use of uninitialized memory in the - RNG, and other conditional uses of DPURIFY. This makes -DPURIFY a no-op. - [Emilia Käsper] - - *) Removed many obsolete configuration items, including - DES_PTR, DES_RISC1, DES_RISC2, DES_INT - MD2_CHAR, MD2_INT, MD2_LONG - BF_PTR, BF_PTR2 - IDEA_SHORT, IDEA_LONG - RC2_SHORT, RC2_LONG, RC4_LONG, RC4_CHUNK, RC4_INDEX - [Rich Salz, with advice from Andy Polyakov] - - *) Many BN internals have been moved to an internal header file. - [Rich Salz with help from Andy Polyakov] - - *) Configuration and writing out the results from it has changed. - Files such as Makefile include/openssl/opensslconf.h and are now - produced through general templates, such as Makefile.in and - crypto/opensslconf.h.in and some help from the perl module - Text::Template. - - Also, the center of configuration information is no longer - Makefile. Instead, Configure produces a perl module in - configdata.pm which holds most of the config data (in the hash - table %config), the target data that comes from the target - configuration in one of the Configurations/*.conf files (in - %target). - [Richard Levitte] - - *) To clarify their intended purposes, the Configure options - --prefix and --openssldir change their semantics, and become more - straightforward and less interdependent. - - --prefix shall be used exclusively to give the location INSTALLTOP - where programs, scripts, libraries, include files and manuals are - going to be installed. The default is now /usr/local. - - --openssldir shall be used exclusively to give the default - location OPENSSLDIR where certificates, private keys, CRLs are - managed. This is also where the default openssl.cnf gets - installed. - If the directory given with this option is a relative path, the - values of both the --prefix value and the --openssldir value will - be combined to become OPENSSLDIR. - The default for --openssldir is INSTALLTOP/ssl. - - Anyone who uses --openssldir to specify where OpenSSL is to be - installed MUST change to use --prefix instead. - [Richard Levitte] - - *) The GOST engine was out of date and therefore it has been removed. An up - to date GOST engine is now being maintained in an external repository. - See: https://wiki.openssl.org/index.php/Binaries. Libssl still retains - support for GOST ciphersuites (these are only activated if a GOST engine - is present). - [Matt Caswell] - - *) EGD is no longer supported by default; use enable-egd when - configuring. - [Ben Kaduk and Rich Salz] - - *) The distribution now has Makefile.in files, which are used to - create Makefile's when Configure is run. *Configure must be run - before trying to build now.* - [Rich Salz] - - *) The return value for SSL_CIPHER_description() for error conditions - has changed. - [Rich Salz] - - *) Support for RFC6698/RFC7671 DANE TLSA peer authentication. - - Obtaining and performing DNSSEC validation of TLSA records is - the application's responsibility. The application provides - the TLSA records of its choice to OpenSSL, and these are then - used to authenticate the peer. - - The TLSA records need not even come from DNS. They can, for - example, be used to implement local end-entity certificate or - trust-anchor "pinning", where the "pin" data takes the form - of TLSA records, which can augment or replace verification - based on the usual WebPKI public certification authorities. - [Viktor Dukhovni] - - *) Revert default OPENSSL_NO_DEPRECATED setting. Instead OpenSSL - continues to support deprecated interfaces in default builds. - However, applications are strongly advised to compile their - source files with -DOPENSSL_API_COMPAT=0x10100000L, which hides - the declarations of all interfaces deprecated in 0.9.8, 1.0.0 - or the 1.1.0 releases. - - In environments in which all applications have been ported to - not use any deprecated interfaces OpenSSL's Configure script - should be used with the --api=1.1.0 option to entirely remove - support for the deprecated features from the library and - unconditionally disable them in the installed headers. - Essentially the same effect can be achieved with the "no-deprecated" - argument to Configure, except that this will always restrict - the build to just the latest API, rather than a fixed API - version. - - As applications are ported to future revisions of the API, - they should update their compile-time OPENSSL_API_COMPAT define - accordingly, but in most cases should be able to continue to - compile with later releases. - - The OPENSSL_API_COMPAT versions for 1.0.0, and 0.9.8 are - 0x10000000L and 0x00908000L, respectively. However those - versions did not support the OPENSSL_API_COMPAT feature, and - so applications are not typically tested for explicit support - of just the undeprecated features of either release. - [Viktor Dukhovni] - - *) Add support for setting the minimum and maximum supported protocol. - It can bet set via the SSL_set_min_proto_version() and - SSL_set_max_proto_version(), or via the SSL_CONF's MinProtocol and - MaxProtocol. It's recommended to use the new APIs to disable - protocols instead of disabling individual protocols using - SSL_set_options() or SSL_CONF's Protocol. This change also - removes support for disabling TLS 1.2 in the OpenSSL TLS - client at compile time by defining OPENSSL_NO_TLS1_2_CLIENT. - [Kurt Roeckx] - - *) Support for ChaCha20 and Poly1305 added to libcrypto and libssl. - [Andy Polyakov] - - *) New EC_KEY_METHOD, this replaces the older ECDSA_METHOD and ECDH_METHOD - and integrates ECDSA and ECDH functionality into EC. Implementations can - now redirect key generation and no longer need to convert to or from - ECDSA_SIG format. - - Note: the ecdsa.h and ecdh.h headers are now no longer needed and just - include the ec.h header file instead. - [Steve Henson] - - *) Remove support for all 40 and 56 bit ciphers. This includes all the export - ciphers who are no longer supported and drops support the ephemeral RSA key - exchange. The LOW ciphers currently doesn't have any ciphers in it. - [Kurt Roeckx] - - *) Made EVP_MD_CTX, EVP_MD, EVP_CIPHER_CTX, EVP_CIPHER and HMAC_CTX - opaque. For HMAC_CTX, the following constructors and destructors - were added: - - HMAC_CTX *HMAC_CTX_new(void); - void HMAC_CTX_free(HMAC_CTX *ctx); - - For EVP_MD and EVP_CIPHER, complete APIs to create, fill and - destroy such methods has been added. See EVP_MD_meth_new(3) and - EVP_CIPHER_meth_new(3) for documentation. - - Additional changes: - 1) EVP_MD_CTX_cleanup(), EVP_CIPHER_CTX_cleanup() and - HMAC_CTX_cleanup() were removed. HMAC_CTX_reset() and - EVP_MD_CTX_reset() should be called instead to reinitialise - an already created structure. - 2) For consistency with the majority of our object creators and - destructors, EVP_MD_CTX_(create|destroy) were renamed to - EVP_MD_CTX_(new|free). The old names are retained as macros - for deprecated builds. - [Richard Levitte] - - *) Added ASYNC support. Libcrypto now includes the async sub-library to enable - cryptographic operations to be performed asynchronously as long as an - asynchronous capable engine is used. See the ASYNC_start_job() man page for - further details. Libssl has also had this capability integrated with the - introduction of the new mode SSL_MODE_ASYNC and associated error - SSL_ERROR_WANT_ASYNC. See the SSL_CTX_set_mode() and SSL_get_error() man - pages. This work was developed in partnership with Intel Corp. - [Matt Caswell] - - *) SSL_{CTX_}set_ecdh_auto() has been removed and ECDH is support is - always enabled now. If you want to disable the support you should - exclude it using the list of supported ciphers. This also means that the - "-no_ecdhe" option has been removed from s_server. - [Kurt Roeckx] - - *) SSL_{CTX}_set_tmp_ecdh() which can set 1 EC curve now internally calls - SSL_{CTX_}set1_curves() which can set a list. - [Kurt Roeckx] - - *) Remove support for SSL_{CTX_}set_tmp_ecdh_callback(). You should set the - curve you want to support using SSL_{CTX_}set1_curves(). - [Kurt Roeckx] - - *) State machine rewrite. The state machine code has been significantly - refactored in order to remove much duplication of code and solve issues - with the old code (see ssl/statem/README for further details). This change - does have some associated API changes. Notably the SSL_state() function - has been removed and replaced by SSL_get_state which now returns an - "OSSL_HANDSHAKE_STATE" instead of an int. SSL_set_state() has been removed - altogether. The previous handshake states defined in ssl.h and ssl3.h have - also been removed. - [Matt Caswell] - - *) All instances of the string "ssleay" in the public API were replaced - with OpenSSL (case-matching; e.g., OPENSSL_VERSION for #define's) - Some error codes related to internal RSA_eay API's were renamed. - [Rich Salz] - - *) The demo files in crypto/threads were moved to demo/threads. - [Rich Salz] - - *) Removed obsolete engines: 4758cca, aep, atalla, cswift, nuron, gmp, - sureware and ubsec. - [Matt Caswell, Rich Salz] - - *) New ASN.1 embed macro. - - New ASN.1 macro ASN1_EMBED. This is the same as ASN1_SIMPLE except the - structure is not allocated: it is part of the parent. That is instead of - - FOO *x; - - it must be: - - FOO x; - - This reduces memory fragmentation and make it impossible to accidentally - set a mandatory field to NULL. - - This currently only works for some fields specifically a SEQUENCE, CHOICE, - or ASN1_STRING type which is part of a parent SEQUENCE. Since it is - equivalent to ASN1_SIMPLE it cannot be tagged, OPTIONAL, SET OF or - SEQUENCE OF. - [Steve Henson] - - *) Remove EVP_CHECK_DES_KEY, a compile-time option that never compiled. - [Emilia Käsper] - - *) Removed DES and RC4 ciphersuites from DEFAULT. Also removed RC2 although - in 1.0.2 EXPORT was already removed and the only RC2 ciphersuite is also - an EXPORT one. COMPLEMENTOFDEFAULT has been updated accordingly to add - DES and RC4 ciphersuites. - [Matt Caswell] - - *) Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs. - This changes the decoding behaviour for some invalid messages, - though the change is mostly in the more lenient direction, and - legacy behaviour is preserved as much as possible. - [Emilia Käsper] - - *) Fix no-stdio build. - [ David Woodhouse and also - Ivan Nestlerode ] - - *) New testing framework - The testing framework has been largely rewritten and is now using - perl and the perl modules Test::Harness and an extended variant of - Test::More called OpenSSL::Test to do its work. All test scripts in - test/ have been rewritten into test recipes, and all direct calls to - executables in test/Makefile have become individual recipes using the - simplified testing OpenSSL::Test::Simple. - - For documentation on our testing modules, do: - - perldoc test/testlib/OpenSSL/Test/Simple.pm - perldoc test/testlib/OpenSSL/Test.pm - - [Richard Levitte] - - *) Revamped memory debug; only -DCRYPTO_MDEBUG and -DCRYPTO_MDEBUG_ABORT - are used; the latter aborts on memory leaks (usually checked on exit). - Some undocumented "set malloc, etc., hooks" functions were removed - and others were changed. All are now documented. - [Rich Salz] - - *) In DSA_generate_parameters_ex, if the provided seed is too short, - return an error - [Rich Salz and Ismo Puustinen ] - - *) Rewrite PSK to support ECDHE_PSK, DHE_PSK and RSA_PSK. Add ciphersuites - from RFC4279, RFC4785, RFC5487, RFC5489. - - Thanks to Christian J. Dietrich and Giuseppe D'Angelo for the - original RSA_PSK patch. - [Steve Henson] - - *) Dropped support for the SSL3_FLAGS_DELAY_CLIENT_FINISHED flag. This SSLeay - era flag was never set throughout the codebase (only read). Also removed - SSL3_FLAGS_POP_BUFFER which was only used if - SSL3_FLAGS_DELAY_CLIENT_FINISHED was also set. - [Matt Caswell] - - *) Changed the default name options in the "ca", "crl", "req" and "x509" - to be "oneline" instead of "compat". - [Richard Levitte] - - *) Remove SSL_OP_TLS_BLOCK_PADDING_BUG. This is SSLeay legacy, we're - not aware of clients that still exhibit this bug, and the workaround - hasn't been working properly for a while. - [Emilia Käsper] - - *) The return type of BIO_number_read() and BIO_number_written() as well as - the corresponding num_read and num_write members in the BIO structure has - changed from unsigned long to uint64_t. On platforms where an unsigned - long is 32 bits (e.g. Windows) these counters could overflow if >4Gb is - transferred. - [Matt Caswell] - - *) Given the pervasive nature of TLS extensions it is inadvisable to run - OpenSSL without support for them. It also means that maintaining - the OPENSSL_NO_TLSEXT option within the code is very invasive (and probably - not well tested). Therefore the OPENSSL_NO_TLSEXT option has been removed. - [Matt Caswell] - - *) Removed support for the two export grade static DH ciphersuites - EXP-DH-RSA-DES-CBC-SHA and EXP-DH-DSS-DES-CBC-SHA. These two ciphersuites - were newly added (along with a number of other static DH ciphersuites) to - 1.0.2. However the two export ones have *never* worked since they were - introduced. It seems strange in any case to be adding new export - ciphersuites, and given "logjam" it also does not seem correct to fix them. - [Matt Caswell] - - *) Version negotiation has been rewritten. In particular SSLv23_method(), - SSLv23_client_method() and SSLv23_server_method() have been deprecated, - and turned into macros which simply call the new preferred function names - TLS_method(), TLS_client_method() and TLS_server_method(). All new code - should use the new names instead. Also as part of this change the ssl23.h - header file has been removed. - [Matt Caswell] - - *) Support for Kerberos ciphersuites in TLS (RFC2712) has been removed. This - code and the associated standard is no longer considered fit-for-purpose. - [Matt Caswell] - - *) RT2547 was closed. When generating a private key, try to make the - output file readable only by the owner. This behavior change might - be noticeable when interacting with other software. - - *) Documented all exdata functions. Added CRYPTO_free_ex_index. - Added a test. - [Rich Salz] - - *) Added HTTP GET support to the ocsp command. - [Rich Salz] - - *) Changed default digest for the dgst and enc commands from MD5 to - sha256 - [Rich Salz] - - *) RAND_pseudo_bytes has been deprecated. Users should use RAND_bytes instead. - [Matt Caswell] - - *) Added support for TLS extended master secret from - draft-ietf-tls-session-hash-03.txt. Thanks for Alfredo Pironti for an - initial patch which was a great help during development. - [Steve Henson] - - *) All libssl internal structures have been removed from the public header - files, and the OPENSSL_NO_SSL_INTERN option has been removed (since it is - now redundant). Users should not attempt to access internal structures - directly. Instead they should use the provided API functions. - [Matt Caswell] - - *) config has been changed so that by default OPENSSL_NO_DEPRECATED is used. - Access to deprecated functions can be re-enabled by running config with - "enable-deprecated". In addition applications wishing to use deprecated - functions must define OPENSSL_USE_DEPRECATED. Note that this new behaviour - will, by default, disable some transitive includes that previously existed - in the header files (e.g. ec.h will no longer, by default, include bn.h) - [Matt Caswell] - - *) Added support for OCB mode. OpenSSL has been granted a patent license - compatible with the OpenSSL license for use of OCB. Details are available - at https://www.openssl.org/source/OCB-patent-grant-OpenSSL.pdf. Support - for OCB can be removed by calling config with no-ocb. - [Matt Caswell] - - *) SSLv2 support has been removed. It still supports receiving a SSLv2 - compatible client hello. - [Kurt Roeckx] - - *) Increased the minimal RSA keysize from 256 to 512 bits [Rich Salz], - done while fixing the error code for the key-too-small case. - [Annie Yousar ] - - *) CA.sh has been removed; use CA.pl instead. - [Rich Salz] - - *) Removed old DES API. - [Rich Salz] - - *) Remove various unsupported platforms: - Sony NEWS4 - BEOS and BEOS_R5 - NeXT - SUNOS - MPE/iX - Sinix/ReliantUNIX RM400 - DGUX - NCR - Tandem - Cray - 16-bit platforms such as WIN16 - [Rich Salz] - - *) Clean up OPENSSL_NO_xxx #define's - Use setbuf() and remove OPENSSL_NO_SETVBUF_IONBF - Rename OPENSSL_SYSNAME_xxx to OPENSSL_SYS_xxx - OPENSSL_NO_EC{DH,DSA} merged into OPENSSL_NO_EC - OPENSSL_NO_RIPEMD160, OPENSSL_NO_RIPEMD merged into OPENSSL_NO_RMD160 - OPENSSL_NO_FP_API merged into OPENSSL_NO_STDIO - Remove OPENSSL_NO_BIO OPENSSL_NO_BUFFER OPENSSL_NO_CHAIN_VERIFY - OPENSSL_NO_EVP OPENSSL_NO_FIPS_ERR OPENSSL_NO_HASH_COMP - OPENSSL_NO_LHASH OPENSSL_NO_OBJECT OPENSSL_NO_SPEED OPENSSL_NO_STACK - OPENSSL_NO_X509 OPENSSL_NO_X509_VERIFY - Remove MS_STATIC; it's a relic from platforms <32 bits. - [Rich Salz] - - *) Cleaned up dead code - Remove all but one '#ifdef undef' which is to be looked at. - [Rich Salz] - - *) Clean up calling of xxx_free routines. - Just like free(), fix most of the xxx_free routines to accept - NULL. Remove the non-null checks from callers. Save much code. - [Rich Salz] - - *) Add secure heap for storage of private keys (when possible). - Add BIO_s_secmem(), CBIGNUM, etc. - Contributed by Akamai Technologies under our Corporate CLA. - [Rich Salz] - - *) Experimental support for a new, fast, unbiased prime candidate generator, - bn_probable_prime_dh_coprime(). Not currently used by any prime generator. - [Felix Laurie von Massenbach ] - - *) New output format NSS in the sess_id command line tool. This allows - exporting the session id and the master key in NSS keylog format. - [Martin Kaiser ] - - *) Harmonize version and its documentation. -f flag is used to display - compilation flags. - [mancha ] - - *) Fix eckey_priv_encode so it immediately returns an error upon a failure - in i2d_ECPrivateKey. Thanks to Ted Unangst for feedback on this issue. - [mancha ] - - *) Fix some double frees. These are not thought to be exploitable. - [mancha ] - - *) A missing bounds check in the handling of the TLS heartbeat extension - can be used to reveal up to 64k of memory to a connected client or - server. - - Thanks for Neel Mehta of Google Security for discovering this bug and to - Adam Langley and Bodo Moeller for - preparing the fix (CVE-2014-0160) - [Adam Langley, Bodo Moeller] - - *) Fix for the attack described in the paper "Recovering OpenSSL - ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack" - by Yuval Yarom and Naomi Benger. Details can be obtained from: - http://eprint.iacr.org/2014/140 - - Thanks to Yuval Yarom and Naomi Benger for discovering this - flaw and to Yuval Yarom for supplying a fix (CVE-2014-0076) - [Yuval Yarom and Naomi Benger] - - *) Use algorithm specific chains in SSL_CTX_use_certificate_chain_file(): - this fixes a limitation in previous versions of OpenSSL. - [Steve Henson] - - *) Experimental encrypt-then-mac support. - - Experimental support for encrypt then mac from - draft-gutmann-tls-encrypt-then-mac-02.txt - - To enable it set the appropriate extension number (0x42 for the test - server) using e.g. -DTLSEXT_TYPE_encrypt_then_mac=0x42 - - For non-compliant peers (i.e. just about everything) this should have no - effect. - - WARNING: EXPERIMENTAL, SUBJECT TO CHANGE. - - [Steve Henson] - - *) Add EVP support for key wrapping algorithms, to avoid problems with - existing code the flag EVP_CIPHER_CTX_WRAP_ALLOW has to be set in - the EVP_CIPHER_CTX or an error is returned. Add AES and DES3 wrap - algorithms and include tests cases. - [Steve Henson] - - *) Extend CMS code to support RSA-PSS signatures and RSA-OAEP for - enveloped data. - [Steve Henson] - - *) Extended RSA OAEP support via EVP_PKEY API. Options to specify digest, - MGF1 digest and OAEP label. - [Steve Henson] - - *) Make openssl verify return errors. - [Chris Palmer and Ben Laurie] - - *) New function ASN1_TIME_diff to calculate the difference between two - ASN1_TIME structures or one structure and the current time. - [Steve Henson] - - *) Update fips_test_suite to support multiple command line options. New - test to induce all self test errors in sequence and check expected - failures. - [Steve Henson] - - *) Add FIPS_{rsa,dsa,ecdsa}_{sign,verify} functions which digest and - sign or verify all in one operation. - [Steve Henson] - - *) Add fips_algvs: a multicall fips utility incorporating all the algorithm - test programs and fips_test_suite. Includes functionality to parse - the minimal script output of fipsalgest.pl directly. - [Steve Henson] - - *) Add authorisation parameter to FIPS_module_mode_set(). - [Steve Henson] - - *) Add FIPS selftest for ECDH algorithm using P-224 and B-233 curves. - [Steve Henson] - - *) Use separate DRBG fields for internal and external flags. New function - FIPS_drbg_health_check() to perform on demand health checking. Add - generation tests to fips_test_suite with reduced health check interval to - demonstrate periodic health checking. Add "nodh" option to - fips_test_suite to skip very slow DH test. - [Steve Henson] - - *) New function FIPS_get_cipherbynid() to lookup FIPS supported ciphers - based on NID. - [Steve Henson] - - *) More extensive health check for DRBG checking many more failure modes. - New function FIPS_selftest_drbg_all() to handle every possible DRBG - combination: call this in fips_test_suite. - [Steve Henson] - - *) Add support for canonical generation of DSA parameter 'g'. See - FIPS 186-3 A.2.3. - - *) Add support for HMAC DRBG from SP800-90. Update DRBG algorithm test and - POST to handle HMAC cases. - [Steve Henson] - - *) Add functions FIPS_module_version() and FIPS_module_version_text() - to return numerical and string versions of the FIPS module number. - [Steve Henson] - - *) Rename FIPS_mode_set and FIPS_mode to FIPS_module_mode_set and - FIPS_module_mode. FIPS_mode and FIPS_mode_set will be implemented - outside the validated module in the FIPS capable OpenSSL. - [Steve Henson] - - *) Minor change to DRBG entropy callback semantics. In some cases - there is no multiple of the block length between min_len and - max_len. Allow the callback to return more than max_len bytes - of entropy but discard any extra: it is the callback's responsibility - to ensure that the extra data discarded does not impact the - requested amount of entropy. - [Steve Henson] - - *) Add PRNG security strength checks to RSA, DSA and ECDSA using - information in FIPS186-3, SP800-57 and SP800-131A. - [Steve Henson] - - *) CCM support via EVP. Interface is very similar to GCM case except we - must supply all data in one chunk (i.e. no update, final) and the - message length must be supplied if AAD is used. Add algorithm test - support. - [Steve Henson] - - *) Initial version of POST overhaul. Add POST callback to allow the status - of POST to be monitored and/or failures induced. Modify fips_test_suite - to use callback. Always run all selftests even if one fails. - [Steve Henson] - - *) XTS support including algorithm test driver in the fips_gcmtest program. - Note: this does increase the maximum key length from 32 to 64 bytes but - there should be no binary compatibility issues as existing applications - will never use XTS mode. - [Steve Henson] - - *) Extensive reorganisation of FIPS PRNG behaviour. Remove all dependencies - to OpenSSL RAND code and replace with a tiny FIPS RAND API which also - performs algorithm blocking for unapproved PRNG types. Also do not - set PRNG type in FIPS_mode_set(): leave this to the application. - Add default OpenSSL DRBG handling: sets up FIPS PRNG and seeds with - the standard OpenSSL PRNG: set additional data to a date time vector. - [Steve Henson] - - *) Rename old X9.31 PRNG functions of the form FIPS_rand* to FIPS_x931*. - This shouldn't present any incompatibility problems because applications - shouldn't be using these directly and any that are will need to rethink - anyway as the X9.31 PRNG is now deprecated by FIPS 140-2 - [Steve Henson] - - *) Extensive self tests and health checking required by SP800-90 DRBG. - Remove strength parameter from FIPS_drbg_instantiate and always - instantiate at maximum supported strength. - [Steve Henson] - - *) Add ECDH code to fips module and fips_ecdhvs for primitives only testing. - [Steve Henson] - - *) New algorithm test program fips_dhvs to handle DH primitives only testing. - [Steve Henson] - - *) New function DH_compute_key_padded() to compute a DH key and pad with - leading zeroes if needed: this complies with SP800-56A et al. - [Steve Henson] - - *) Initial implementation of SP800-90 DRBGs for Hash and CTR. Not used by - anything, incomplete, subject to change and largely untested at present. - [Steve Henson] - - *) Modify fipscanisteronly build option to only build the necessary object - files by filtering FIPS_EX_OBJ through a perl script in crypto/Makefile. - [Steve Henson] - - *) Add experimental option FIPSSYMS to give all symbols in - fipscanister.o and FIPS or fips prefix. This will avoid - conflicts with future versions of OpenSSL. Add perl script - util/fipsas.pl to preprocess assembly language source files - and rename any affected symbols. - [Steve Henson] - - *) Add selftest checks and algorithm block of non-fips algorithms in - FIPS mode. Remove DES2 from selftests. - [Steve Henson] - - *) Add ECDSA code to fips module. Add tiny fips_ecdsa_check to just - return internal method without any ENGINE dependencies. Add new - tiny fips sign and verify functions. - [Steve Henson] - - *) New build option no-ec2m to disable characteristic 2 code. - [Steve Henson] - - *) New build option "fipscanisteronly". This only builds fipscanister.o - and (currently) associated fips utilities. Uses the file Makefile.fips - instead of Makefile.org as the prototype. - [Steve Henson] - - *) Add some FIPS mode restrictions to GCM. Add internal IV generator. - Update fips_gcmtest to use IV generator. - [Steve Henson] - - *) Initial, experimental EVP support for AES-GCM. AAD can be input by - setting output buffer to NULL. The *Final function must be - called although it will not retrieve any additional data. The tag - can be set or retrieved with a ctrl. The IV length is by default 12 - bytes (96 bits) but can be set to an alternative value. If the IV - length exceeds the maximum IV length (currently 16 bytes) it cannot be - set before the key. - [Steve Henson] - - *) New flag in ciphers: EVP_CIPH_FLAG_CUSTOM_CIPHER. This means the - underlying do_cipher function handles all cipher semantics itself - including padding and finalisation. This is useful if (for example) - an ENGINE cipher handles block padding itself. The behaviour of - do_cipher is subtly changed if this flag is set: the return value - is the number of characters written to the output buffer (zero is - no longer an error code) or a negative error code. Also if the - input buffer is NULL and length 0 finalisation should be performed. - [Steve Henson] - - *) If a candidate issuer certificate is already part of the constructed - path ignore it: new debug notification X509_V_ERR_PATH_LOOP for this case. - [Steve Henson] - - *) Improve forward-security support: add functions - - void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx, int (*cb)(SSL *ssl, int is_forward_secure)) - void SSL_set_not_resumable_session_callback(SSL *ssl, int (*cb)(SSL *ssl, int is_forward_secure)) - - for use by SSL/TLS servers; the callback function will be called whenever a - new session is created, and gets to decide whether the session may be - cached to make it resumable (return 0) or not (return 1). (As by the - SSL/TLS protocol specifications, the session_id sent by the server will be - empty to indicate that the session is not resumable; also, the server will - not generate RFC 4507 (RFC 5077) session tickets.) - - A simple reasonable callback implementation is to return is_forward_secure. - This parameter will be set to 1 or 0 depending on the ciphersuite selected - by the SSL/TLS server library, indicating whether it can provide forward - security. - [Emilia Käsper (Google)] - - *) New -verify_name option in command line utilities to set verification - parameters by name. - [Steve Henson] - - *) Initial CMAC implementation. WARNING: EXPERIMENTAL, API MAY CHANGE. - Add CMAC pkey methods. - [Steve Henson] - - *) Experimental renegotiation in s_server -www mode. If the client - browses /reneg connection is renegotiated. If /renegcert it is - renegotiated requesting a certificate. - [Steve Henson] - - *) Add an "external" session cache for debugging purposes to s_server. This - should help trace issues which normally are only apparent in deployed - multi-process servers. - [Steve Henson] - - *) Extensive audit of libcrypto with DEBUG_UNUSED. Fix many cases where - return value is ignored. NB. The functions RAND_add(), RAND_seed(), - BIO_set_cipher() and some obscure PEM functions were changed so they - can now return an error. The RAND changes required a change to the - RAND_METHOD structure. - [Steve Henson] - - *) New macro __owur for "OpenSSL Warn Unused Result". This makes use of - a gcc attribute to warn if the result of a function is ignored. This - is enable if DEBUG_UNUSED is set. Add to several functions in evp.h - whose return value is often ignored. - [Steve Henson] - - *) New -noct, -requestct, -requirect and -ctlogfile options for s_client. - These allow SCTs (signed certificate timestamps) to be requested and - validated when establishing a connection. - [Rob Percival ] - - Changes between 1.0.2g and 1.0.2h [3 May 2016] - - *) Prevent padding oracle in AES-NI CBC MAC check - - A MITM attacker can use a padding oracle attack to decrypt traffic - when the connection uses an AES CBC cipher and the server support - AES-NI. - - This issue was introduced as part of the fix for Lucky 13 padding - attack (CVE-2013-0169). The padding check was rewritten to be in - constant time by making sure that always the same bytes are read and - compared against either the MAC or padding bytes. But it no longer - checked that there was enough data to have both the MAC and padding - bytes. - - This issue was reported by Juraj Somorovsky using TLS-Attacker. - (CVE-2016-2107) - [Kurt Roeckx] - - *) Fix EVP_EncodeUpdate overflow - - An overflow can occur in the EVP_EncodeUpdate() function which is used for - Base64 encoding of binary data. If an attacker is able to supply very large - amounts of input data then a length check can overflow resulting in a heap - corruption. - - Internally to OpenSSL the EVP_EncodeUpdate() function is primarily used by - the PEM_write_bio* family of functions. These are mainly used within the - OpenSSL command line applications, so any application which processes data - from an untrusted source and outputs it as a PEM file should be considered - vulnerable to this issue. User applications that call these APIs directly - with large amounts of untrusted data may also be vulnerable. - - This issue was reported by Guido Vranken. - (CVE-2016-2105) - [Matt Caswell] - - *) Fix EVP_EncryptUpdate overflow - - An overflow can occur in the EVP_EncryptUpdate() function. If an attacker - is able to supply very large amounts of input data after a previous call to - EVP_EncryptUpdate() with a partial block then a length check can overflow - resulting in a heap corruption. Following an analysis of all OpenSSL - internal usage of the EVP_EncryptUpdate() function all usage is one of two - forms. The first form is where the EVP_EncryptUpdate() call is known to be - the first called function after an EVP_EncryptInit(), and therefore that - specific call must be safe. The second form is where the length passed to - EVP_EncryptUpdate() can be seen from the code to be some small value and - therefore there is no possibility of an overflow. Since all instances are - one of these two forms, it is believed that there can be no overflows in - internal code due to this problem. It should be noted that - EVP_DecryptUpdate() can call EVP_EncryptUpdate() in certain code paths. - Also EVP_CipherUpdate() is a synonym for EVP_EncryptUpdate(). All instances - of these calls have also been analysed too and it is believed there are no - instances in internal usage where an overflow could occur. - - This issue was reported by Guido Vranken. - (CVE-2016-2106) - [Matt Caswell] - - *) Prevent ASN.1 BIO excessive memory allocation - - When ASN.1 data is read from a BIO using functions such as d2i_CMS_bio() - a short invalid encoding can cause allocation of large amounts of memory - potentially consuming excessive resources or exhausting memory. - - Any application parsing untrusted data through d2i BIO functions is - affected. The memory based functions such as d2i_X509() are *not* affected. - Since the memory based functions are used by the TLS library, TLS - applications are not affected. - - This issue was reported by Brian Carpenter. - (CVE-2016-2109) - [Stephen Henson] - - *) EBCDIC overread - - ASN1 Strings that are over 1024 bytes can cause an overread in applications - using the X509_NAME_oneline() function on EBCDIC systems. This could result - in arbitrary stack data being returned in the buffer. - - This issue was reported by Guido Vranken. - (CVE-2016-2176) - [Matt Caswell] - - *) Modify behavior of ALPN to invoke callback after SNI/servername - callback, such that updates to the SSL_CTX affect ALPN. - [Todd Short] - - *) Remove LOW from the DEFAULT cipher list. This removes singles DES from the - default. - [Kurt Roeckx] - - *) Only remove the SSLv2 methods with the no-ssl2-method option. When the - methods are enabled and ssl2 is disabled the methods return NULL. - [Kurt Roeckx] - - Changes between 1.0.2f and 1.0.2g [1 Mar 2016] - - * Disable weak ciphers in SSLv3 and up in default builds of OpenSSL. - Builds that are not configured with "enable-weak-ssl-ciphers" will not - provide any "EXPORT" or "LOW" strength ciphers. - [Viktor Dukhovni] - - * Disable SSLv2 default build, default negotiation and weak ciphers. SSLv2 - is by default disabled at build-time. Builds that are not configured with - "enable-ssl2" will not support SSLv2. Even if "enable-ssl2" is used, - users who want to negotiate SSLv2 via the version-flexible SSLv23_method() - will need to explicitly call either of: - - SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv2); - or - SSL_clear_options(ssl, SSL_OP_NO_SSLv2); - - as appropriate. Even if either of those is used, or the application - explicitly uses the version-specific SSLv2_method() or its client and - server variants, SSLv2 ciphers vulnerable to exhaustive search key - recovery have been removed. Specifically, the SSLv2 40-bit EXPORT - ciphers, and SSLv2 56-bit DES are no longer available. - (CVE-2016-0800) - [Viktor Dukhovni] - - *) Fix a double-free in DSA code - - A double free bug was discovered when OpenSSL parses malformed DSA private - keys and could lead to a DoS attack or memory corruption for applications - that receive DSA private keys from untrusted sources. This scenario is - considered rare. - - This issue was reported to OpenSSL by Adam Langley(Google/BoringSSL) using - libFuzzer. - (CVE-2016-0705) - [Stephen Henson] - - *) Disable SRP fake user seed to address a server memory leak. - - Add a new method SRP_VBASE_get1_by_user that handles the seed properly. - - SRP_VBASE_get_by_user had inconsistent memory management behaviour. - In order to fix an unavoidable memory leak, SRP_VBASE_get_by_user - was changed to ignore the "fake user" SRP seed, even if the seed - is configured. - - Users should use SRP_VBASE_get1_by_user instead. Note that in - SRP_VBASE_get1_by_user, caller must free the returned value. Note - also that even though configuring the SRP seed attempts to hide - invalid usernames by continuing the handshake with fake - credentials, this behaviour is not constant time and no strong - guarantees are made that the handshake is indistinguishable from - that of a valid user. - (CVE-2016-0798) - [Emilia Käsper] - - *) Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption - - In the BN_hex2bn function the number of hex digits is calculated using an - int value |i|. Later |bn_expand| is called with a value of |i * 4|. For - large values of |i| this can result in |bn_expand| not allocating any - memory because |i * 4| is negative. This can leave the internal BIGNUM data - field as NULL leading to a subsequent NULL ptr deref. For very large values - of |i|, the calculation |i * 4| could be a positive value smaller than |i|. - In this case memory is allocated to the internal BIGNUM data field, but it - is insufficiently sized leading to heap corruption. A similar issue exists - in BN_dec2bn. This could have security consequences if BN_hex2bn/BN_dec2bn - is ever called by user applications with very large untrusted hex/dec data. - This is anticipated to be a rare occurrence. - - All OpenSSL internal usage of these functions use data that is not expected - to be untrusted, e.g. config file data or application command line - arguments. If user developed applications generate config file data based - on untrusted data then it is possible that this could also lead to security - consequences. This is also anticipated to be rare. - - This issue was reported to OpenSSL by Guido Vranken. - (CVE-2016-0797) - [Matt Caswell] - - *) Fix memory issues in BIO_*printf functions - - The internal |fmtstr| function used in processing a "%s" format string in - the BIO_*printf functions could overflow while calculating the length of a - string and cause an OOB read when printing very long strings. - - Additionally the internal |doapr_outch| function can attempt to write to an - OOB memory location (at an offset from the NULL pointer) in the event of a - memory allocation failure. In 1.0.2 and below this could be caused where - the size of a buffer to be allocated is greater than INT_MAX. E.g. this - could be in processing a very long "%s" format string. Memory leaks can - also occur. - - The first issue may mask the second issue dependent on compiler behaviour. - These problems could enable attacks where large amounts of untrusted data - is passed to the BIO_*printf functions. If applications use these functions - in this way then they could be vulnerable. OpenSSL itself uses these - functions when printing out human-readable dumps of ASN.1 data. Therefore - applications that print this data could be vulnerable if the data is from - untrusted sources. OpenSSL command line applications could also be - vulnerable where they print out ASN.1 data, or if untrusted data is passed - as command line arguments. - - Libssl is not considered directly vulnerable. Additionally certificates etc - received via remote connections via libssl are also unlikely to be able to - trigger these issues because of message size limits enforced within libssl. - - This issue was reported to OpenSSL Guido Vranken. - (CVE-2016-0799) - [Matt Caswell] - - *) Side channel attack on modular exponentiation - - A side-channel attack was found which makes use of cache-bank conflicts on - the Intel Sandy-Bridge microarchitecture which could lead to the recovery - of RSA keys. The ability to exploit this issue is limited as it relies on - an attacker who has control of code in a thread running on the same - hyper-threaded core as the victim thread which is performing decryptions. - - This issue was reported to OpenSSL by Yuval Yarom, The University of - Adelaide and NICTA, Daniel Genkin, Technion and Tel Aviv University, and - Nadia Heninger, University of Pennsylvania with more information at - http://cachebleed.info. - (CVE-2016-0702) - [Andy Polyakov] - - *) Change the req app to generate a 2048-bit RSA/DSA key by default, - if no keysize is specified with default_bits. This fixes an - omission in an earlier change that changed all RSA/DSA key generation - apps to use 2048 bits by default. - [Emilia Käsper] - - Changes between 1.0.2e and 1.0.2f [28 Jan 2016] - *) DH small subgroups - - Historically OpenSSL only ever generated DH parameters based on "safe" - primes. More recently (in version 1.0.2) support was provided for - generating X9.42 style parameter files such as those required for RFC 5114 - support. The primes used in such files may not be "safe". Where an - application is using DH configured with parameters based on primes that are - not "safe" then an attacker could use this fact to find a peer's private - DH exponent. This attack requires that the attacker complete multiple - handshakes in which the peer uses the same private DH exponent. For example - this could be used to discover a TLS server's private DH exponent if it's - reusing the private DH exponent or it's using a static DH ciphersuite. - - OpenSSL provides the option SSL_OP_SINGLE_DH_USE for ephemeral DH (DHE) in - TLS. It is not on by default. If the option is not set then the server - reuses the same private DH exponent for the life of the server process and - would be vulnerable to this attack. It is believed that many popular - applications do set this option and would therefore not be at risk. - - The fix for this issue adds an additional check where a "q" parameter is - available (as is the case in X9.42 based parameters). This detects the - only known attack, and is the only possible defense for static DH - ciphersuites. This could have some performance impact. - - Additionally the SSL_OP_SINGLE_DH_USE option has been switched on by - default and cannot be disabled. This could have some performance impact. - - This issue was reported to OpenSSL by Antonio Sanso (Adobe). - (CVE-2016-0701) - [Matt Caswell] - - *) SSLv2 doesn't block disabled ciphers - - A malicious client can negotiate SSLv2 ciphers that have been disabled on - the server and complete SSLv2 handshakes even if all SSLv2 ciphers have - been disabled, provided that the SSLv2 protocol was not also disabled via - SSL_OP_NO_SSLv2. - - This issue was reported to OpenSSL on 26th December 2015 by Nimrod Aviram - and Sebastian Schinzel. - (CVE-2015-3197) - [Viktor Dukhovni] - - Changes between 1.0.2d and 1.0.2e [3 Dec 2015] - - *) BN_mod_exp may produce incorrect results on x86_64 - - There is a carry propagating bug in the x86_64 Montgomery squaring - procedure. No EC algorithms are affected. Analysis suggests that attacks - against RSA and DSA as a result of this defect would be very difficult to - perform and are not believed likely. Attacks against DH are considered just - feasible (although very difficult) because most of the work necessary to - deduce information about a private key may be performed offline. The amount - of resources required for such an attack would be very significant and - likely only accessible to a limited number of attackers. An attacker would - additionally need online access to an unpatched system using the target - private key in a scenario with persistent DH parameters and a private - key that is shared between multiple clients. For example this can occur by - default in OpenSSL DHE based SSL/TLS ciphersuites. - - This issue was reported to OpenSSL by Hanno Böck. - (CVE-2015-3193) - [Andy Polyakov] - - *) Certificate verify crash with missing PSS parameter - - The signature verification routines will crash with a NULL pointer - dereference if presented with an ASN.1 signature using the RSA PSS - algorithm and absent mask generation function parameter. Since these - routines are used to verify certificate signature algorithms this can be - used to crash any certificate verification operation and exploited in a - DoS attack. Any application which performs certificate verification is - vulnerable including OpenSSL clients and servers which enable client - authentication. - - This issue was reported to OpenSSL by Loïc Jonas Etienne (Qnective AG). - (CVE-2015-3194) - [Stephen Henson] - - *) X509_ATTRIBUTE memory leak - - When presented with a malformed X509_ATTRIBUTE structure OpenSSL will leak - memory. This structure is used by the PKCS#7 and CMS routines so any - application which reads PKCS#7 or CMS data from untrusted sources is - affected. SSL/TLS is not affected. - - This issue was reported to OpenSSL by Adam Langley (Google/BoringSSL) using - libFuzzer. - (CVE-2015-3195) - [Stephen Henson] - - *) Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs. - This changes the decoding behaviour for some invalid messages, - though the change is mostly in the more lenient direction, and - legacy behaviour is preserved as much as possible. - [Emilia Käsper] - - *) In DSA_generate_parameters_ex, if the provided seed is too short, - return an error - [Rich Salz and Ismo Puustinen ] - - Changes between 1.0.2c and 1.0.2d [9 Jul 2015] - - *) Alternate chains certificate forgery - - During certificate verification, OpenSSL will attempt to find an - alternative certificate chain if the first attempt to build such a chain - fails. An error in the implementation of this logic can mean that an - attacker could cause certain checks on untrusted certificates to be - bypassed, such as the CA flag, enabling them to use a valid leaf - certificate to act as a CA and "issue" an invalid certificate. - - This issue was reported to OpenSSL by Adam Langley/David Benjamin - (Google/BoringSSL). - [Matt Caswell] - - Changes between 1.0.2b and 1.0.2c [12 Jun 2015] - - *) Fix HMAC ABI incompatibility. The previous version introduced an ABI - incompatibility in the handling of HMAC. The previous ABI has now been - restored. - [Matt Caswell] - - Changes between 1.0.2a and 1.0.2b [11 Jun 2015] - - *) Malformed ECParameters causes infinite loop - - When processing an ECParameters structure OpenSSL enters an infinite loop - if the curve specified is over a specially malformed binary polynomial - field. - - This can be used to perform denial of service against any - system which processes public keys, certificate requests or - certificates. This includes TLS clients and TLS servers with - client authentication enabled. - - This issue was reported to OpenSSL by Joseph Barr-Pixton. - (CVE-2015-1788) - [Andy Polyakov] - - *) Exploitable out-of-bounds read in X509_cmp_time - - X509_cmp_time does not properly check the length of the ASN1_TIME - string and can read a few bytes out of bounds. In addition, - X509_cmp_time accepts an arbitrary number of fractional seconds in the - time string. - - An attacker can use this to craft malformed certificates and CRLs of - various sizes and potentially cause a segmentation fault, resulting in - a DoS on applications that verify certificates or CRLs. TLS clients - that verify CRLs are affected. TLS clients and servers with client - authentication enabled may be affected if they use custom verification - callbacks. - - This issue was reported to OpenSSL by Robert Swiecki (Google), and - independently by Hanno Böck. - (CVE-2015-1789) - [Emilia Käsper] - - *) PKCS7 crash with missing EnvelopedContent - - The PKCS#7 parsing code does not handle missing inner EncryptedContent - correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs - with missing content and trigger a NULL pointer dereference on parsing. - - Applications that decrypt PKCS#7 data or otherwise parse PKCS#7 - structures from untrusted sources are affected. OpenSSL clients and - servers are not affected. - - This issue was reported to OpenSSL by Michal Zalewski (Google). - (CVE-2015-1790) - [Emilia Käsper] - - *) CMS verify infinite loop with unknown hash function - - When verifying a signedData message the CMS code can enter an infinite loop - if presented with an unknown hash function OID. This can be used to perform - denial of service against any system which verifies signedData messages using - the CMS code. - This issue was reported to OpenSSL by Johannes Bauer. - (CVE-2015-1792) - [Stephen Henson] - - *) Race condition handling NewSessionTicket - - If a NewSessionTicket is received by a multi-threaded client when attempting to - reuse a previous ticket then a race condition can occur potentially leading to - a double free of the ticket data. - (CVE-2015-1791) - [Matt Caswell] - - *) Only support 256-bit or stronger elliptic curves with the - 'ecdh_auto' setting (server) or by default (client). Of supported - curves, prefer P-256 (both). - [Emilia Kasper] - - Changes between 1.0.2 and 1.0.2a [19 Mar 2015] - - *) ClientHello sigalgs DoS fix - - If a client connects to an OpenSSL 1.0.2 server and renegotiates with an - invalid signature algorithms extension a NULL pointer dereference will - occur. This can be exploited in a DoS attack against the server. - - This issue was was reported to OpenSSL by David Ramos of Stanford - University. - (CVE-2015-0291) - [Stephen Henson and Matt Caswell] - - *) Multiblock corrupted pointer fix - - OpenSSL 1.0.2 introduced the "multiblock" performance improvement. This - feature only applies on 64 bit x86 architecture platforms that support AES - NI instructions. A defect in the implementation of "multiblock" can cause - OpenSSL's internal write buffer to become incorrectly set to NULL when - using non-blocking IO. Typically, when the user application is using a - socket BIO for writing, this will only result in a failed connection. - However if some other BIO is used then it is likely that a segmentation - fault will be triggered, thus enabling a potential DoS attack. - - This issue was reported to OpenSSL by Daniel Danner and Rainer Mueller. - (CVE-2015-0290) - [Matt Caswell] - - *) Segmentation fault in DTLSv1_listen fix - - The DTLSv1_listen function is intended to be stateless and processes the - initial ClientHello from many peers. It is common for user code to loop - over the call to DTLSv1_listen until a valid ClientHello is received with - an associated cookie. A defect in the implementation of DTLSv1_listen means - that state is preserved in the SSL object from one invocation to the next - that can lead to a segmentation fault. Errors processing the initial - ClientHello can trigger this scenario. An example of such an error could be - that a DTLS1.0 only client is attempting to connect to a DTLS1.2 only - server. - - This issue was reported to OpenSSL by Per Allansson. - (CVE-2015-0207) - [Matt Caswell] - - *) Segmentation fault in ASN1_TYPE_cmp fix - - The function ASN1_TYPE_cmp will crash with an invalid read if an attempt is - made to compare ASN.1 boolean types. Since ASN1_TYPE_cmp is used to check - certificate signature algorithm consistency this can be used to crash any - certificate verification operation and exploited in a DoS attack. Any - application which performs certificate verification is vulnerable including - OpenSSL clients and servers which enable client authentication. - (CVE-2015-0286) - [Stephen Henson] - - *) Segmentation fault for invalid PSS parameters fix - - The signature verification routines will crash with a NULL pointer - dereference if presented with an ASN.1 signature using the RSA PSS - algorithm and invalid parameters. Since these routines are used to verify - certificate signature algorithms this can be used to crash any - certificate verification operation and exploited in a DoS attack. Any - application which performs certificate verification is vulnerable including - OpenSSL clients and servers which enable client authentication. - - This issue was was reported to OpenSSL by Brian Carpenter. - (CVE-2015-0208) - [Stephen Henson] - - *) ASN.1 structure reuse memory corruption fix - - Reusing a structure in ASN.1 parsing may allow an attacker to cause - memory corruption via an invalid write. Such reuse is and has been - strongly discouraged and is believed to be rare. - - Applications that parse structures containing CHOICE or ANY DEFINED BY - components may be affected. Certificate parsing (d2i_X509 and related - functions) are however not affected. OpenSSL clients and servers are - not affected. - (CVE-2015-0287) - [Stephen Henson] - - *) PKCS7 NULL pointer dereferences fix - - The PKCS#7 parsing code does not handle missing outer ContentInfo - correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs with - missing content and trigger a NULL pointer dereference on parsing. - - Applications that verify PKCS#7 signatures, decrypt PKCS#7 data or - otherwise parse PKCS#7 structures from untrusted sources are - affected. OpenSSL clients and servers are not affected. - - This issue was reported to OpenSSL by Michal Zalewski (Google). - (CVE-2015-0289) - [Emilia Käsper] - - *) DoS via reachable assert in SSLv2 servers fix - - A malicious client can trigger an OPENSSL_assert (i.e., an abort) in - servers that both support SSLv2 and enable export cipher suites by sending - a specially crafted SSLv2 CLIENT-MASTER-KEY message. - - This issue was discovered by Sean Burford (Google) and Emilia Käsper - (OpenSSL development team). - (CVE-2015-0293) - [Emilia Käsper] - - *) Empty CKE with client auth and DHE fix - - If client auth is used then a server can seg fault in the event of a DHE - ciphersuite being selected and a zero length ClientKeyExchange message - being sent by the client. This could be exploited in a DoS attack. - (CVE-2015-1787) - [Matt Caswell] - - *) Handshake with unseeded PRNG fix - - Under certain conditions an OpenSSL 1.0.2 client can complete a handshake - with an unseeded PRNG. The conditions are: - - The client is on a platform where the PRNG has not been seeded - automatically, and the user has not seeded manually - - A protocol specific client method version has been used (i.e. not - SSL_client_methodv23) - - A ciphersuite is used that does not require additional random data from - the PRNG beyond the initial ClientHello client random (e.g. PSK-RC4-SHA). - - If the handshake succeeds then the client random that has been used will - have been generated from a PRNG with insufficient entropy and therefore the - output may be predictable. - - For example using the following command with an unseeded openssl will - succeed on an unpatched platform: - - openssl s_client -psk 1a2b3c4d -tls1_2 -cipher PSK-RC4-SHA - (CVE-2015-0285) - [Matt Caswell] - - *) Use After Free following d2i_ECPrivatekey error fix - - A malformed EC private key file consumed via the d2i_ECPrivateKey function - could cause a use after free condition. This, in turn, could cause a double - free in several private key parsing functions (such as d2i_PrivateKey - or EVP_PKCS82PKEY) and could lead to a DoS attack or memory corruption - for applications that receive EC private keys from untrusted - sources. This scenario is considered rare. - - This issue was discovered by the BoringSSL project and fixed in their - commit 517073cd4b. - (CVE-2015-0209) - [Matt Caswell] - - *) X509_to_X509_REQ NULL pointer deref fix - - The function X509_to_X509_REQ will crash with a NULL pointer dereference if - the certificate key is invalid. This function is rarely used in practice. - - This issue was discovered by Brian Carpenter. - (CVE-2015-0288) - [Stephen Henson] - - *) Removed the export ciphers from the DEFAULT ciphers - [Kurt Roeckx] - - Changes between 1.0.1l and 1.0.2 [22 Jan 2015] - - *) Facilitate "universal" ARM builds targeting range of ARM ISAs, e.g. - ARMv5 through ARMv8, as opposite to "locking" it to single one. - So far those who have to target multiple platforms would compromise - and argue that binary targeting say ARMv5 would still execute on - ARMv8. "Universal" build resolves this compromise by providing - near-optimal performance even on newer platforms. - [Andy Polyakov] - - *) Accelerated NIST P-256 elliptic curve implementation for x86_64 - (other platforms pending). - [Shay Gueron & Vlad Krasnov (Intel Corp), Andy Polyakov] - - *) Add support for the SignedCertificateTimestampList certificate and - OCSP response extensions from RFC6962. - [Rob Stradling] - - *) Fix ec_GFp_simple_points_make_affine (thus, EC_POINTs_mul etc.) - for corner cases. (Certain input points at infinity could lead to - bogus results, with non-infinity inputs mapped to infinity too.) - [Bodo Moeller] - - *) Initial support for PowerISA 2.0.7, first implemented in POWER8. - This covers AES, SHA256/512 and GHASH. "Initial" means that most - common cases are optimized and there still is room for further - improvements. Vector Permutation AES for Altivec is also added. - [Andy Polyakov] - - *) Add support for little-endian ppc64 Linux target. - [Marcelo Cerri (IBM)] - - *) Initial support for AMRv8 ISA crypto extensions. This covers AES, - SHA1, SHA256 and GHASH. "Initial" means that most common cases - are optimized and there still is room for further improvements. - Both 32- and 64-bit modes are supported. - [Andy Polyakov, Ard Biesheuvel (Linaro)] - - *) Improved ARMv7 NEON support. - [Andy Polyakov] - - *) Support for SPARC Architecture 2011 crypto extensions, first - implemented in SPARC T4. This covers AES, DES, Camellia, SHA1, - SHA256/512, MD5, GHASH and modular exponentiation. - [Andy Polyakov, David Miller] - - *) Accelerated modular exponentiation for Intel processors, a.k.a. - RSAZ. - [Shay Gueron & Vlad Krasnov (Intel Corp)] - - *) Support for new and upcoming Intel processors, including AVX2, - BMI and SHA ISA extensions. This includes additional "stitched" - implementations, AESNI-SHA256 and GCM, and multi-buffer support - for TLS encrypt. - - This work was sponsored by Intel Corp. - [Andy Polyakov] - - *) Support for DTLS 1.2. This adds two sets of DTLS methods: DTLS_*_method() - supports both DTLS 1.2 and 1.0 and should use whatever version the peer - supports and DTLSv1_2_*_method() which supports DTLS 1.2 only. - [Steve Henson] - - *) Use algorithm specific chains in SSL_CTX_use_certificate_chain_file(): - this fixes a limitation in previous versions of OpenSSL. - [Steve Henson] - - *) Extended RSA OAEP support via EVP_PKEY API. Options to specify digest, - MGF1 digest and OAEP label. - [Steve Henson] - - *) Add EVP support for key wrapping algorithms, to avoid problems with - existing code the flag EVP_CIPHER_CTX_WRAP_ALLOW has to be set in - the EVP_CIPHER_CTX or an error is returned. Add AES and DES3 wrap - algorithms and include tests cases. - [Steve Henson] - - *) Add functions to allocate and set the fields of an ECDSA_METHOD - structure. - [Douglas E. Engert, Steve Henson] - - *) New functions OPENSSL_gmtime_diff and ASN1_TIME_diff to find the - difference in days and seconds between two tm or ASN1_TIME structures. - [Steve Henson] - - *) Add -rev test option to s_server to just reverse order of characters - received by client and send back to server. Also prints an abbreviated - summary of the connection parameters. - [Steve Henson] - - *) New option -brief for s_client and s_server to print out a brief summary - of connection parameters. - [Steve Henson] - - *) Add callbacks for arbitrary TLS extensions. - [Trevor Perrin and Ben Laurie] - - *) New option -crl_download in several openssl utilities to download CRLs - from CRLDP extension in certificates. - [Steve Henson] - - *) New options -CRL and -CRLform for s_client and s_server for CRLs. - [Steve Henson] - - *) New function X509_CRL_diff to generate a delta CRL from the difference - of two full CRLs. Add support to "crl" utility. - [Steve Henson] - - *) New functions to set lookup_crls function and to retrieve - X509_STORE from X509_STORE_CTX. - [Steve Henson] - - *) Print out deprecated issuer and subject unique ID fields in - certificates. - [Steve Henson] - - *) Extend OCSP I/O functions so they can be used for simple general purpose - HTTP as well as OCSP. New wrapper function which can be used to download - CRLs using the OCSP API. - [Steve Henson] - - *) Delegate command line handling in s_client/s_server to SSL_CONF APIs. - [Steve Henson] - - *) SSL_CONF* functions. These provide a common framework for application - configuration using configuration files or command lines. - [Steve Henson] - - *) SSL/TLS tracing code. This parses out SSL/TLS records using the - message callback and prints the results. Needs compile time option - "enable-ssl-trace". New options to s_client and s_server to enable - tracing. - [Steve Henson] - - *) New ctrl and macro to retrieve supported points extensions. - Print out extension in s_server and s_client. - [Steve Henson] - - *) New functions to retrieve certificate signature and signature - OID NID. - [Steve Henson] - - *) Add functions to retrieve and manipulate the raw cipherlist sent by a - client to OpenSSL. - [Steve Henson] - - *) New Suite B modes for TLS code. These use and enforce the requirements - of RFC6460: restrict ciphersuites, only permit Suite B algorithms and - only use Suite B curves. The Suite B modes can be set by using the - strings "SUITEB128", "SUITEB192" or "SUITEB128ONLY" for the cipherstring. - [Steve Henson] - - *) New chain verification flags for Suite B levels of security. Check - algorithms are acceptable when flags are set in X509_verify_cert. - [Steve Henson] - - *) Make tls1_check_chain return a set of flags indicating checks passed - by a certificate chain. Add additional tests to handle client - certificates: checks for matching certificate type and issuer name - comparison. - [Steve Henson] - - *) If an attempt is made to use a signature algorithm not in the peer - preference list abort the handshake. If client has no suitable - signature algorithms in response to a certificate request do not - use the certificate. - [Steve Henson] - - *) If server EC tmp key is not in client preference list abort handshake. - [Steve Henson] - - *) Add support for certificate stores in CERT structure. This makes it - possible to have different stores per SSL structure or one store in - the parent SSL_CTX. Include distinct stores for certificate chain - verification and chain building. New ctrl SSL_CTRL_BUILD_CERT_CHAIN - to build and store a certificate chain in CERT structure: returning - an error if the chain cannot be built: this will allow applications - to test if a chain is correctly configured. - - Note: if the CERT based stores are not set then the parent SSL_CTX - store is used to retain compatibility with existing behaviour. - - [Steve Henson] - - *) New function ssl_set_client_disabled to set a ciphersuite disabled - mask based on the current session, check mask when sending client - hello and checking the requested ciphersuite. - [Steve Henson] - - *) New ctrls to retrieve and set certificate types in a certificate - request message. Print out received values in s_client. If certificate - types is not set with custom values set sensible values based on - supported signature algorithms. - [Steve Henson] - - *) Support for distinct client and server supported signature algorithms. - [Steve Henson] - - *) Add certificate callback. If set this is called whenever a certificate - is required by client or server. An application can decide which - certificate chain to present based on arbitrary criteria: for example - supported signature algorithms. Add very simple example to s_server. - This fixes many of the problems and restrictions of the existing client - certificate callback: for example you can now clear an existing - certificate and specify the whole chain. - [Steve Henson] - - *) Add new "valid_flags" field to CERT_PKEY structure which determines what - the certificate can be used for (if anything). Set valid_flags field - in new tls1_check_chain function. Simplify ssl_set_cert_masks which used - to have similar checks in it. - - Add new "cert_flags" field to CERT structure and include a "strict mode". - This enforces some TLS certificate requirements (such as only permitting - certificate signature algorithms contained in the supported algorithms - extension) which some implementations ignore: this option should be used - with caution as it could cause interoperability issues. - [Steve Henson] - - *) Update and tidy signature algorithm extension processing. Work out - shared signature algorithms based on preferences and peer algorithms - and print them out in s_client and s_server. Abort handshake if no - shared signature algorithms. - [Steve Henson] - - *) Add new functions to allow customised supported signature algorithms - for SSL and SSL_CTX structures. Add options to s_client and s_server - to support them. - [Steve Henson] - - *) New function SSL_certs_clear() to delete all references to certificates - from an SSL structure. Before this once a certificate had been added - it couldn't be removed. - [Steve Henson] - - *) Integrate hostname, email address and IP address checking with certificate - verification. New verify options supporting checking in openssl utility. - [Steve Henson] - - *) Fixes and wildcard matching support to hostname and email checking - functions. Add manual page. - [Florian Weimer (Red Hat Product Security Team)] - - *) New functions to check a hostname email or IP address against a - certificate. Add options x509 utility to print results of checks against - a certificate. - [Steve Henson] - - *) Fix OCSP checking. - [Rob Stradling and Ben Laurie] - - *) Initial experimental support for explicitly trusted non-root CAs. - OpenSSL still tries to build a complete chain to a root but if an - intermediate CA has a trust setting included that is used. The first - setting is used: whether to trust (e.g., -addtrust option to the x509 - utility) or reject. - [Steve Henson] - - *) Add -trusted_first option which attempts to find certificates in the - trusted store even if an untrusted chain is also supplied. - [Steve Henson] - - *) MIPS assembly pack updates: support for MIPS32r2 and SmartMIPS ASE, - platform support for Linux and Android. - [Andy Polyakov] - - *) Support for linux-x32, ILP32 environment in x86_64 framework. - [Andy Polyakov] - - *) Experimental multi-implementation support for FIPS capable OpenSSL. - When in FIPS mode the approved implementations are used as normal, - when not in FIPS mode the internal unapproved versions are used instead. - This means that the FIPS capable OpenSSL isn't forced to use the - (often lower performance) FIPS implementations outside FIPS mode. - [Steve Henson] - - *) Transparently support X9.42 DH parameters when calling - PEM_read_bio_DHparameters. This means existing applications can handle - the new parameter format automatically. - [Steve Henson] - - *) Initial experimental support for X9.42 DH parameter format: mainly - to support use of 'q' parameter for RFC5114 parameters. - [Steve Henson] - - *) Add DH parameters from RFC5114 including test data to dhtest. - [Steve Henson] - - *) Support for automatic EC temporary key parameter selection. If enabled - the most preferred EC parameters are automatically used instead of - hardcoded fixed parameters. Now a server just has to call: - SSL_CTX_set_ecdh_auto(ctx, 1) and the server will automatically - support ECDH and use the most appropriate parameters. - [Steve Henson] - - *) Enhance and tidy EC curve and point format TLS extension code. Use - static structures instead of allocation if default values are used. - New ctrls to set curves we wish to support and to retrieve shared curves. - Print out shared curves in s_server. New options to s_server and s_client - to set list of supported curves. - [Steve Henson] - - *) New ctrls to retrieve supported signature algorithms and - supported curve values as an array of NIDs. Extend openssl utility - to print out received values. - [Steve Henson] - - *) Add new APIs EC_curve_nist2nid and EC_curve_nid2nist which convert - between NIDs and the more common NIST names such as "P-256". Enhance - ecparam utility and ECC method to recognise the NIST names for curves. - [Steve Henson] - - *) Enhance SSL/TLS certificate chain handling to support different - chains for each certificate instead of one chain in the parent SSL_CTX. - [Steve Henson] - - *) Support for fixed DH ciphersuite client authentication: where both - server and client use DH certificates with common parameters. - [Steve Henson] - - *) Support for fixed DH ciphersuites: those requiring DH server - certificates. - [Steve Henson] - - *) New function i2d_re_X509_tbs for re-encoding the TBS portion of - the certificate. - Note: Related 1.0.2-beta specific macros X509_get_cert_info, - X509_CINF_set_modified, X509_CINF_get_issuer, X509_CINF_get_extensions and - X509_CINF_get_signature were reverted post internal team review. - - Changes between 1.0.1k and 1.0.1l [15 Jan 2015] - - *) Build fixes for the Windows and OpenVMS platforms - [Matt Caswell and Richard Levitte] - - Changes between 1.0.1j and 1.0.1k [8 Jan 2015] - - *) Fix DTLS segmentation fault in dtls1_get_record. A carefully crafted DTLS - message can cause a segmentation fault in OpenSSL due to a NULL pointer - dereference. This could lead to a Denial Of Service attack. Thanks to - Markus Stenberg of Cisco Systems, Inc. for reporting this issue. - (CVE-2014-3571) - [Steve Henson] - - *) Fix DTLS memory leak in dtls1_buffer_record. A memory leak can occur in the - dtls1_buffer_record function under certain conditions. In particular this - could occur if an attacker sent repeated DTLS records with the same - sequence number but for the next epoch. The memory leak could be exploited - by an attacker in a Denial of Service attack through memory exhaustion. - Thanks to Chris Mueller for reporting this issue. - (CVE-2015-0206) - [Matt Caswell] - - *) Fix issue where no-ssl3 configuration sets method to NULL. When openssl is - built with the no-ssl3 option and a SSL v3 ClientHello is received the ssl - method would be set to NULL which could later result in a NULL pointer - dereference. Thanks to Frank Schmirler for reporting this issue. - (CVE-2014-3569) - [Kurt Roeckx] - - *) Abort handshake if server key exchange message is omitted for ephemeral - ECDH ciphersuites. - - Thanks to Karthikeyan Bhargavan of the PROSECCO team at INRIA for - reporting this issue. - (CVE-2014-3572) - [Steve Henson] - - *) Remove non-export ephemeral RSA code on client and server. This code - violated the TLS standard by allowing the use of temporary RSA keys in - non-export ciphersuites and could be used by a server to effectively - downgrade the RSA key length used to a value smaller than the server - certificate. Thanks for Karthikeyan Bhargavan of the PROSECCO team at - INRIA or reporting this issue. - (CVE-2015-0204) - [Steve Henson] - - *) Fixed issue where DH client certificates are accepted without verification. - An OpenSSL server will accept a DH certificate for client authentication - without the certificate verify message. This effectively allows a client to - authenticate without the use of a private key. This only affects servers - which trust a client certificate authority which issues certificates - containing DH keys: these are extremely rare and hardly ever encountered. - Thanks for Karthikeyan Bhargavan of the PROSECCO team at INRIA or reporting - this issue. - (CVE-2015-0205) - [Steve Henson] - - *) Ensure that the session ID context of an SSL is updated when its - SSL_CTX is updated via SSL_set_SSL_CTX. - - The session ID context is typically set from the parent SSL_CTX, - and can vary with the CTX. - [Adam Langley] - - *) Fix various certificate fingerprint issues. - - By using non-DER or invalid encodings outside the signed portion of a - certificate the fingerprint can be changed without breaking the signature. - Although no details of the signed portion of the certificate can be changed - this can cause problems with some applications: e.g. those using the - certificate fingerprint for blacklists. - - 1. Reject signatures with non zero unused bits. - - If the BIT STRING containing the signature has non zero unused bits reject - the signature. All current signature algorithms require zero unused bits. - - 2. Check certificate algorithm consistency. - - Check the AlgorithmIdentifier inside TBS matches the one in the - certificate signature. NB: this will result in signature failure - errors for some broken certificates. - - Thanks to Konrad Kraszewski from Google for reporting this issue. - - 3. Check DSA/ECDSA signatures use DER. - - Re-encode DSA/ECDSA signatures and compare with the original received - signature. Return an error if there is a mismatch. - - This will reject various cases including garbage after signature - (thanks to Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS - program for discovering this case) and use of BER or invalid ASN.1 INTEGERs - (negative or with leading zeroes). - - Further analysis was conducted and fixes were developed by Stephen Henson - of the OpenSSL core team. - - (CVE-2014-8275) - [Steve Henson] - - *) Correct Bignum squaring. Bignum squaring (BN_sqr) may produce incorrect - results on some platforms, including x86_64. This bug occurs at random - with a very low probability, and is not known to be exploitable in any - way, though its exact impact is difficult to determine. Thanks to Pieter - Wuille (Blockstream) who reported this issue and also suggested an initial - fix. Further analysis was conducted by the OpenSSL development team and - Adam Langley of Google. The final fix was developed by Andy Polyakov of - the OpenSSL core team. - (CVE-2014-3570) - [Andy Polyakov] - - *) Do not resume sessions on the server if the negotiated protocol - version does not match the session's version. Resuming with a different - version, while not strictly forbidden by the RFC, is of questionable - sanity and breaks all known clients. - [David Benjamin, Emilia Käsper] - - *) Tighten handling of the ChangeCipherSpec (CCS) message: reject - early CCS messages during renegotiation. (Note that because - renegotiation is encrypted, this early CCS was not exploitable.) - [Emilia Käsper] - - *) Tighten client-side session ticket handling during renegotiation: - ensure that the client only accepts a session ticket if the server sends - the extension anew in the ServerHello. Previously, a TLS client would - reuse the old extension state and thus accept a session ticket if one was - announced in the initial ServerHello. - - Similarly, ensure that the client requires a session ticket if one - was advertised in the ServerHello. Previously, a TLS client would - ignore a missing NewSessionTicket message. - [Emilia Käsper] - - Changes between 1.0.1i and 1.0.1j [15 Oct 2014] - - *) SRTP Memory Leak. - - A flaw in the DTLS SRTP extension parsing code allows an attacker, who - sends a carefully crafted handshake message, to cause OpenSSL to fail - to free up to 64k of memory causing a memory leak. This could be - exploited in a Denial Of Service attack. This issue affects OpenSSL - 1.0.1 server implementations for both SSL/TLS and DTLS regardless of - whether SRTP is used or configured. Implementations of OpenSSL that - have been compiled with OPENSSL_NO_SRTP defined are not affected. - - The fix was developed by the OpenSSL team. - (CVE-2014-3513) - [OpenSSL team] - - *) Session Ticket Memory Leak. - - When an OpenSSL SSL/TLS/DTLS server receives a session ticket the - integrity of that ticket is first verified. In the event of a session - ticket integrity check failing, OpenSSL will fail to free memory - causing a memory leak. By sending a large number of invalid session - tickets an attacker could exploit this issue in a Denial Of Service - attack. - (CVE-2014-3567) - [Steve Henson] - - *) Build option no-ssl3 is incomplete. - - When OpenSSL is configured with "no-ssl3" as a build option, servers - could accept and complete a SSL 3.0 handshake, and clients could be - configured to send them. - (CVE-2014-3568) - [Akamai and the OpenSSL team] - - *) Add support for TLS_FALLBACK_SCSV. - Client applications doing fallback retries should call - SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV). - (CVE-2014-3566) - [Adam Langley, Bodo Moeller] - - *) Add additional DigestInfo checks. - - Re-encode DigestInto in DER and check against the original when - verifying RSA signature: this will reject any improperly encoded - DigestInfo structures. - - Note: this is a precautionary measure and no attacks are currently known. - - [Steve Henson] - - Changes between 1.0.1h and 1.0.1i [6 Aug 2014] - - *) Fix SRP buffer overrun vulnerability. Invalid parameters passed to the - SRP code can be overrun an internal buffer. Add sanity check that - g, A, B < N to SRP code. - - Thanks to Sean Devlin and Watson Ladd of Cryptography Services, NCC - Group for discovering this issue. - (CVE-2014-3512) - [Steve Henson] - - *) A flaw in the OpenSSL SSL/TLS server code causes the server to negotiate - TLS 1.0 instead of higher protocol versions when the ClientHello message - is badly fragmented. This allows a man-in-the-middle attacker to force a - downgrade to TLS 1.0 even if both the server and the client support a - higher protocol version, by modifying the client's TLS records. - - Thanks to David Benjamin and Adam Langley (Google) for discovering and - researching this issue. - (CVE-2014-3511) - [David Benjamin] - - *) OpenSSL DTLS clients enabling anonymous (EC)DH ciphersuites are subject - to a denial of service attack. A malicious server can crash the client - with a null pointer dereference (read) by specifying an anonymous (EC)DH - ciphersuite and sending carefully crafted handshake messages. - - Thanks to Felix Gröbert (Google) for discovering and researching this - issue. - (CVE-2014-3510) - [Emilia Käsper] - - *) By sending carefully crafted DTLS packets an attacker could cause openssl - to leak memory. This can be exploited through a Denial of Service attack. - Thanks to Adam Langley for discovering and researching this issue. - (CVE-2014-3507) - [Adam Langley] - - *) An attacker can force openssl to consume large amounts of memory whilst - processing DTLS handshake messages. This can be exploited through a - Denial of Service attack. - Thanks to Adam Langley for discovering and researching this issue. - (CVE-2014-3506) - [Adam Langley] - - *) An attacker can force an error condition which causes openssl to crash - whilst processing DTLS packets due to memory being freed twice. This - can be exploited through a Denial of Service attack. - Thanks to Adam Langley and Wan-Teh Chang for discovering and researching - this issue. - (CVE-2014-3505) - [Adam Langley] - - *) If a multithreaded client connects to a malicious server using a resumed - session and the server sends an ec point format extension it could write - up to 255 bytes to freed memory. - - Thanks to Gabor Tyukasz (LogMeIn Inc) for discovering and researching this - issue. - (CVE-2014-3509) - [Gabor Tyukasz] - - *) A malicious server can crash an OpenSSL client with a null pointer - dereference (read) by specifying an SRP ciphersuite even though it was not - properly negotiated with the client. This can be exploited through a - Denial of Service attack. - - Thanks to Joonas Kuorilehto and Riku Hietamäki (Codenomicon) for - discovering and researching this issue. - (CVE-2014-5139) - [Steve Henson] - - *) A flaw in OBJ_obj2txt may cause pretty printing functions such as - X509_name_oneline, X509_name_print_ex et al. to leak some information - from the stack. Applications may be affected if they echo pretty printing - output to the attacker. - - Thanks to Ivan Fratric (Google) for discovering this issue. - (CVE-2014-3508) - [Emilia Käsper, and Steve Henson] - - *) Fix ec_GFp_simple_points_make_affine (thus, EC_POINTs_mul etc.) - for corner cases. (Certain input points at infinity could lead to - bogus results, with non-infinity inputs mapped to infinity too.) - [Bodo Moeller] - - Changes between 1.0.1g and 1.0.1h [5 Jun 2014] - - *) Fix for SSL/TLS MITM flaw. An attacker using a carefully crafted - handshake can force the use of weak keying material in OpenSSL - SSL/TLS clients and servers. - - Thanks to KIKUCHI Masashi (Lepidum Co. Ltd.) for discovering and - researching this issue. (CVE-2014-0224) - [KIKUCHI Masashi, Steve Henson] - - *) Fix DTLS recursion flaw. By sending an invalid DTLS handshake to an - OpenSSL DTLS client the code can be made to recurse eventually crashing - in a DoS attack. - - Thanks to Imre Rad (Search-Lab Ltd.) for discovering this issue. - (CVE-2014-0221) - [Imre Rad, Steve Henson] - - *) Fix DTLS invalid fragment vulnerability. A buffer overrun attack can - be triggered by sending invalid DTLS fragments to an OpenSSL DTLS - client or server. This is potentially exploitable to run arbitrary - code on a vulnerable client or server. - - Thanks to Jüri Aedla for reporting this issue. (CVE-2014-0195) - [Jüri Aedla, Steve Henson] - - *) Fix bug in TLS code where clients enable anonymous ECDH ciphersuites - are subject to a denial of service attack. - - Thanks to Felix Gröbert and Ivan Fratric at Google for discovering - this issue. (CVE-2014-3470) - [Felix Gröbert, Ivan Fratric, Steve Henson] - - *) Harmonize version and its documentation. -f flag is used to display - compilation flags. - [mancha ] - - *) Fix eckey_priv_encode so it immediately returns an error upon a failure - in i2d_ECPrivateKey. - [mancha ] - - *) Fix some double frees. These are not thought to be exploitable. - [mancha ] - - Changes between 1.0.1f and 1.0.1g [7 Apr 2014] - - *) A missing bounds check in the handling of the TLS heartbeat extension - can be used to reveal up to 64k of memory to a connected client or - server. - - Thanks for Neel Mehta of Google Security for discovering this bug and to - Adam Langley and Bodo Moeller for - preparing the fix (CVE-2014-0160) - [Adam Langley, Bodo Moeller] - - *) Fix for the attack described in the paper "Recovering OpenSSL - ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack" - by Yuval Yarom and Naomi Benger. Details can be obtained from: - http://eprint.iacr.org/2014/140 - - Thanks to Yuval Yarom and Naomi Benger for discovering this - flaw and to Yuval Yarom for supplying a fix (CVE-2014-0076) - [Yuval Yarom and Naomi Benger] - - *) TLS pad extension: draft-agl-tls-padding-03 - - Workaround for the "TLS hang bug" (see FAQ and PR#2771): if the - TLS client Hello record length value would otherwise be > 255 and - less that 512 pad with a dummy extension containing zeroes so it - is at least 512 bytes long. - - [Adam Langley, Steve Henson] - - Changes between 1.0.1e and 1.0.1f [6 Jan 2014] - - *) Fix for TLS record tampering bug. A carefully crafted invalid - handshake could crash OpenSSL with a NULL pointer exception. - Thanks to Anton Johansson for reporting this issues. - (CVE-2013-4353) - - *) Keep original DTLS digest and encryption contexts in retransmission - structures so we can use the previous session parameters if they need - to be resent. (CVE-2013-6450) - [Steve Henson] - - *) Add option SSL_OP_SAFARI_ECDHE_ECDSA_BUG (part of SSL_OP_ALL) which - avoids preferring ECDHE-ECDSA ciphers when the client appears to be - Safari on OS X. Safari on OS X 10.8..10.8.3 advertises support for - several ECDHE-ECDSA ciphers, but fails to negotiate them. The bug - is fixed in OS X 10.8.4, but Apple have ruled out both hot fixing - 10.8..10.8.3 and forcing users to upgrade to 10.8.4 or newer. - [Rob Stradling, Adam Langley] - - Changes between 1.0.1d and 1.0.1e [11 Feb 2013] - - *) Correct fix for CVE-2013-0169. The original didn't work on AES-NI - supporting platforms or when small records were transferred. - [Andy Polyakov, Steve Henson] - - Changes between 1.0.1c and 1.0.1d [5 Feb 2013] - - *) Make the decoding of SSLv3, TLS and DTLS CBC records constant time. - - This addresses the flaw in CBC record processing discovered by - Nadhem Alfardan and Kenny Paterson. Details of this attack can be found - at: http://www.isg.rhul.ac.uk/tls/ - - Thanks go to Nadhem Alfardan and Kenny Paterson of the Information - Security Group at Royal Holloway, University of London - (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and - Emilia Käsper for the initial patch. - (CVE-2013-0169) - [Emilia Käsper, Adam Langley, Ben Laurie, Andy Polyakov, Steve Henson] - - *) Fix flaw in AESNI handling of TLS 1.2 and 1.1 records for CBC mode - ciphersuites which can be exploited in a denial of service attack. - Thanks go to and to Adam Langley for discovering - and detecting this bug and to Wolfgang Ettlinger - for independently discovering this issue. - (CVE-2012-2686) - [Adam Langley] - - *) Return an error when checking OCSP signatures when key is NULL. - This fixes a DoS attack. (CVE-2013-0166) - [Steve Henson] - - *) Make openssl verify return errors. - [Chris Palmer and Ben Laurie] - - *) Call OCSP Stapling callback after ciphersuite has been chosen, so - the right response is stapled. Also change SSL_get_certificate() - so it returns the certificate actually sent. - See http://rt.openssl.org/Ticket/Display.html?id=2836. - [Rob Stradling ] - - *) Fix possible deadlock when decoding public keys. - [Steve Henson] - - *) Don't use TLS 1.0 record version number in initial client hello - if renegotiating. - [Steve Henson] - - Changes between 1.0.1b and 1.0.1c [10 May 2012] - - *) Sanity check record length before skipping explicit IV in TLS - 1.2, 1.1 and DTLS to fix DoS attack. - - Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic - fuzzing as a service testing platform. - (CVE-2012-2333) - [Steve Henson] - - *) Initialise tkeylen properly when encrypting CMS messages. - Thanks to Solar Designer of Openwall for reporting this issue. - [Steve Henson] - - *) In FIPS mode don't try to use composite ciphers as they are not - approved. - [Steve Henson] - - Changes between 1.0.1a and 1.0.1b [26 Apr 2012] - - *) OpenSSL 1.0.0 sets SSL_OP_ALL to 0x80000FFFL and OpenSSL 1.0.1 and - 1.0.1a set SSL_OP_NO_TLSv1_1 to 0x00000400L which would unfortunately - mean any application compiled against OpenSSL 1.0.0 headers setting - SSL_OP_ALL would also set SSL_OP_NO_TLSv1_1, unintentionally disabling - TLS 1.1 also. Fix this by changing the value of SSL_OP_NO_TLSv1_1 to - 0x10000000L Any application which was previously compiled against - OpenSSL 1.0.1 or 1.0.1a headers and which cares about SSL_OP_NO_TLSv1_1 - will need to be recompiled as a result. Letting be results in - inability to disable specifically TLS 1.1 and in client context, - in unlike event, limit maximum offered version to TLS 1.0 [see below]. - [Steve Henson] - - *) In order to ensure interoperability SSL_OP_NO_protocolX does not - disable just protocol X, but all protocols above X *if* there are - protocols *below* X still enabled. In more practical terms it means - that if application wants to disable TLS1.0 in favor of TLS1.1 and - above, it's not sufficient to pass SSL_OP_NO_TLSv1, one has to pass - SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. This applies to - client side. - [Andy Polyakov] - - Changes between 1.0.1 and 1.0.1a [19 Apr 2012] - - *) Check for potentially exploitable overflows in asn1_d2i_read_bio - BUF_mem_grow and BUF_mem_grow_clean. Refuse attempts to shrink buffer - in CRYPTO_realloc_clean. - - Thanks to Tavis Ormandy, Google Security Team, for discovering this - issue and to Adam Langley for fixing it. - (CVE-2012-2110) - [Adam Langley (Google), Tavis Ormandy, Google Security Team] - - *) Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections. - [Adam Langley] - - *) Workarounds for some broken servers that "hang" if a client hello - record length exceeds 255 bytes. - - 1. Do not use record version number > TLS 1.0 in initial client - hello: some (but not all) hanging servers will now work. - 2. If we set OPENSSL_MAX_TLS1_2_CIPHER_LENGTH this will truncate - the number of ciphers sent in the client hello. This should be - set to an even number, such as 50, for example by passing: - -DOPENSSL_MAX_TLS1_2_CIPHER_LENGTH=50 to config or Configure. - Most broken servers should now work. - 3. If all else fails setting OPENSSL_NO_TLS1_2_CLIENT will disable - TLS 1.2 client support entirely. - [Steve Henson] - - *) Fix SEGV in Vector Permutation AES module observed in OpenSSH. - [Andy Polyakov] - - Changes between 1.0.0h and 1.0.1 [14 Mar 2012] - - *) Add compatibility with old MDC2 signatures which use an ASN1 OCTET - STRING form instead of a DigestInfo. - [Steve Henson] - - *) The format used for MDC2 RSA signatures is inconsistent between EVP - and the RSA_sign/RSA_verify functions. This was made more apparent when - OpenSSL used RSA_sign/RSA_verify for some RSA signatures in particular - those which went through EVP_PKEY_METHOD in 1.0.0 and later. Detect - the correct format in RSA_verify so both forms transparently work. - [Steve Henson] - - *) Some servers which support TLS 1.0 can choke if we initially indicate - support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA - encrypted premaster secret. As a workaround use the maximum permitted - client version in client hello, this should keep such servers happy - and still work with previous versions of OpenSSL. - [Steve Henson] - - *) Add support for TLS/DTLS heartbeats. - [Robin Seggelmann ] - - *) Add support for SCTP. - [Robin Seggelmann ] - - *) Improved PRNG seeding for VOS. - [Paul Green ] - - *) Extensive assembler packs updates, most notably: - - - x86[_64]: AES-NI, PCLMULQDQ, RDRAND support; - - x86[_64]: SSSE3 support (SHA1, vector-permutation AES); - - x86_64: bit-sliced AES implementation; - - ARM: NEON support, contemporary platforms optimizations; - - s390x: z196 support; - - *: GHASH and GF(2^m) multiplication implementations; - - [Andy Polyakov] - - *) Make TLS-SRP code conformant with RFC 5054 API cleanup - (removal of unnecessary code) - [Peter Sylvester ] - - *) Add TLS key material exporter from RFC 5705. - [Eric Rescorla] - - *) Add DTLS-SRTP negotiation from RFC 5764. - [Eric Rescorla] - - *) Add Next Protocol Negotiation, - http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-00. Can be - disabled with a no-npn flag to config or Configure. Code donated - by Google. - [Adam Langley and Ben Laurie] - - *) Add optional 64-bit optimized implementations of elliptic curves NIST-P224, - NIST-P256, NIST-P521, with constant-time single point multiplication on - typical inputs. Compiler support for the nonstandard type __uint128_t is - required to use this (present in gcc 4.4 and later, for 64-bit builds). - Code made available under Apache License version 2.0. - - Specify "enable-ec_nistp_64_gcc_128" on the Configure (or config) command - line to include this in your build of OpenSSL, and run "make depend" (or - "make update"). This enables the following EC_METHODs: - - EC_GFp_nistp224_method() - EC_GFp_nistp256_method() - EC_GFp_nistp521_method() - - EC_GROUP_new_by_curve_name() will automatically use these (while - EC_GROUP_new_curve_GFp() currently prefers the more flexible - implementations). - [Emilia Käsper, Adam Langley, Bodo Moeller (Google)] - - *) Use type ossl_ssize_t instead of ssize_t which isn't available on - all platforms. Move ssize_t definition from e_os.h to the public - header file e_os2.h as it now appears in public header file cms.h - [Steve Henson] - - *) New -sigopt option to the ca, req and x509 utilities. Additional - signature parameters can be passed using this option and in - particular PSS. - [Steve Henson] - - *) Add RSA PSS signing function. This will generate and set the - appropriate AlgorithmIdentifiers for PSS based on those in the - corresponding EVP_MD_CTX structure. No application support yet. - [Steve Henson] - - *) Support for companion algorithm specific ASN1 signing routines. - New function ASN1_item_sign_ctx() signs a pre-initialised - EVP_MD_CTX structure and sets AlgorithmIdentifiers based on - the appropriate parameters. - [Steve Henson] - - *) Add new algorithm specific ASN1 verification initialisation function - to EVP_PKEY_ASN1_METHOD: this is not in EVP_PKEY_METHOD since the ASN1 - handling will be the same no matter what EVP_PKEY_METHOD is used. - Add a PSS handler to support verification of PSS signatures: checked - against a number of sample certificates. - [Steve Henson] - - *) Add signature printing for PSS. Add PSS OIDs. - [Steve Henson, Martin Kaiser ] - - *) Add algorithm specific signature printing. An individual ASN1 method - can now print out signatures instead of the standard hex dump. - - More complex signatures (e.g. PSS) can print out more meaningful - information. Include DSA version that prints out the signature - parameters r, s. - [Steve Henson] - - *) Password based recipient info support for CMS library: implementing - RFC3211. - [Steve Henson] - - *) Split password based encryption into PBES2 and PBKDF2 functions. This - neatly separates the code into cipher and PBE sections and is required - for some algorithms that split PBES2 into separate pieces (such as - password based CMS). - [Steve Henson] - - *) Session-handling fixes: - - Fix handling of connections that are resuming with a session ID, - but also support Session Tickets. - - Fix a bug that suppressed issuing of a new ticket if the client - presented a ticket with an expired session. - - Try to set the ticket lifetime hint to something reasonable. - - Make tickets shorter by excluding irrelevant information. - - On the client side, don't ignore renewed tickets. - [Adam Langley, Bodo Moeller (Google)] - - *) Fix PSK session representation. - [Bodo Moeller] - - *) Add RC4-MD5 and AESNI-SHA1 "stitched" implementations. - - This work was sponsored by Intel. - [Andy Polyakov] - - *) Add GCM support to TLS library. Some custom code is needed to split - the IV between the fixed (from PRF) and explicit (from TLS record) - portions. This adds all GCM ciphersuites supported by RFC5288 and - RFC5289. Generalise some AES* cipherstrings to include GCM and - add a special AESGCM string for GCM only. - [Steve Henson] - - *) Expand range of ctrls for AES GCM. Permit setting invocation - field on decrypt and retrieval of invocation field only on encrypt. - [Steve Henson] - - *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support. - As required by RFC5289 these ciphersuites cannot be used if for - versions of TLS earlier than 1.2. - [Steve Henson] - - *) For FIPS capable OpenSSL interpret a NULL default public key method - as unset and return the appropriate default but do *not* set the default. - This means we can return the appropriate method in applications that - switch between FIPS and non-FIPS modes. - [Steve Henson] - - *) Redirect HMAC and CMAC operations to FIPS module in FIPS mode. If an - ENGINE is used then we cannot handle that in the FIPS module so we - keep original code iff non-FIPS operations are allowed. - [Steve Henson] - - *) Add -attime option to openssl utilities. - [Peter Eckersley , Ben Laurie and Steve Henson] - - *) Redirect DSA and DH operations to FIPS module in FIPS mode. - [Steve Henson] - - *) Redirect ECDSA and ECDH operations to FIPS module in FIPS mode. Also use - FIPS EC methods unconditionally for now. - [Steve Henson] - - *) New build option no-ec2m to disable characteristic 2 code. - [Steve Henson] - - *) Backport libcrypto audit of return value checking from 1.1.0-dev; not - all cases can be covered as some introduce binary incompatibilities. - [Steve Henson] - - *) Redirect RSA operations to FIPS module including keygen, - encrypt, decrypt, sign and verify. Block use of non FIPS RSA methods. - [Steve Henson] - - *) Add similar low level API blocking to ciphers. - [Steve Henson] - - *) Low level digest APIs are not approved in FIPS mode: any attempt - to use these will cause a fatal error. Applications that *really* want - to use them can use the private_* version instead. - [Steve Henson] - - *) Redirect cipher operations to FIPS module for FIPS builds. - [Steve Henson] - - *) Redirect digest operations to FIPS module for FIPS builds. - [Steve Henson] - - *) Update build system to add "fips" flag which will link in fipscanister.o - for static and shared library builds embedding a signature if needed. - [Steve Henson] - - *) Output TLS supported curves in preference order instead of numerical - order. This is currently hardcoded for the highest order curves first. - This should be configurable so applications can judge speed vs strength. - [Steve Henson] - - *) Add TLS v1.2 server support for client authentication. - [Steve Henson] - - *) Add support for FIPS mode in ssl library: disable SSLv3, non-FIPS ciphers - and enable MD5. - [Steve Henson] - - *) Functions FIPS_mode_set() and FIPS_mode() which call the underlying - FIPS modules versions. - [Steve Henson] - - *) Add TLS v1.2 client side support for client authentication. Keep cache - of handshake records longer as we don't know the hash algorithm to use - until after the certificate request message is received. - [Steve Henson] - - *) Initial TLS v1.2 client support. Add a default signature algorithms - extension including all the algorithms we support. Parse new signature - format in client key exchange. Relax some ECC signing restrictions for - TLS v1.2 as indicated in RFC5246. - [Steve Henson] - - *) Add server support for TLS v1.2 signature algorithms extension. Switch - to new signature format when needed using client digest preference. - All server ciphersuites should now work correctly in TLS v1.2. No client - support yet and no support for client certificates. - [Steve Henson] - - *) Initial TLS v1.2 support. Add new SHA256 digest to ssl code, switch - to SHA256 for PRF when using TLS v1.2 and later. Add new SHA256 based - ciphersuites. At present only RSA key exchange ciphersuites work with - TLS v1.2. Add new option for TLS v1.2 replacing the old and obsolete - SSL_OP_PKCS1_CHECK flags with SSL_OP_NO_TLSv1_2. New TLSv1.2 methods - and version checking. - [Steve Henson] - - *) New option OPENSSL_NO_SSL_INTERN. If an application can be compiled - with this defined it will not be affected by any changes to ssl internal - structures. Add several utility functions to allow openssl application - to work with OPENSSL_NO_SSL_INTERN defined. - [Steve Henson] - - *) A long standing patch to add support for SRP from EdelWeb (Peter - Sylvester and Christophe Renou) was integrated. - [Christophe Renou , Peter Sylvester - , Tom Wu , and - Ben Laurie] - - *) Add functions to copy EVP_PKEY_METHOD and retrieve flags and id. - [Steve Henson] - - *) Permit abbreviated handshakes when renegotiating using the function - SSL_renegotiate_abbreviated(). - [Robin Seggelmann ] - - *) Add call to ENGINE_register_all_complete() to - ENGINE_load_builtin_engines(), so some implementations get used - automatically instead of needing explicit application support. - [Steve Henson] - - *) Add support for TLS key exporter as described in RFC5705. - [Robin Seggelmann , Steve Henson] - - *) Initial TLSv1.1 support. Since TLSv1.1 is very similar to TLS v1.0 only - a few changes are required: - - Add SSL_OP_NO_TLSv1_1 flag. - Add TLSv1_1 methods. - Update version checking logic to handle version 1.1. - Add explicit IV handling (ported from DTLS code). - Add command line options to s_client/s_server. - [Steve Henson] - - Changes between 1.0.0g and 1.0.0h [12 Mar 2012] - - *) Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness - in CMS and PKCS7 code. When RSA decryption fails use a random key for - content decryption and always return the same error. Note: this attack - needs on average 2^20 messages so it only affects automated senders. The - old behaviour can be re-enabled in the CMS code by setting the - CMS_DEBUG_DECRYPT flag: this is useful for debugging and testing where - an MMA defence is not necessary. - Thanks to Ivan Nestlerode for discovering - this issue. (CVE-2012-0884) - [Steve Henson] - - *) Fix CVE-2011-4619: make sure we really are receiving a - client hello before rejecting multiple SGC restarts. Thanks to - Ivan Nestlerode for discovering this bug. - [Steve Henson] - - Changes between 1.0.0f and 1.0.0g [18 Jan 2012] - - *) Fix for DTLS DoS issue introduced by fix for CVE-2011-4109. - Thanks to Antonio Martin, Enterprise Secure Access Research and - Development, Cisco Systems, Inc. for discovering this bug and - preparing a fix. (CVE-2012-0050) - [Antonio Martin] - - Changes between 1.0.0e and 1.0.0f [4 Jan 2012] - - *) Nadhem Alfardan and Kenny Paterson have discovered an extension - of the Vaudenay padding oracle attack on CBC mode encryption - which enables an efficient plaintext recovery attack against - the OpenSSL implementation of DTLS. Their attack exploits timing - differences arising during decryption processing. A research - paper describing this attack can be found at: - http://www.isg.rhul.ac.uk/~kp/dtls.pdf - Thanks go to Nadhem Alfardan and Kenny Paterson of the Information - Security Group at Royal Holloway, University of London - (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann - and Michael Tuexen - for preparing the fix. (CVE-2011-4108) - [Robin Seggelmann, Michael Tuexen] - - *) Clear bytes used for block padding of SSL 3.0 records. - (CVE-2011-4576) - [Adam Langley (Google)] - - *) Only allow one SGC handshake restart for SSL/TLS. Thanks to George - Kadianakis for discovering this issue and - Adam Langley for preparing the fix. (CVE-2011-4619) - [Adam Langley (Google)] - - *) Check parameters are not NULL in GOST ENGINE. (CVE-2012-0027) - [Andrey Kulikov ] - - *) Prevent malformed RFC3779 data triggering an assertion failure. - Thanks to Andrew Chi, BBN Technologies, for discovering the flaw - and Rob Austein for fixing it. (CVE-2011-4577) - [Rob Austein ] - - *) Improved PRNG seeding for VOS. - [Paul Green ] - - *) Fix ssl_ciph.c set-up race. - [Adam Langley (Google)] - - *) Fix spurious failures in ecdsatest.c. - [Emilia Käsper (Google)] - - *) Fix the BIO_f_buffer() implementation (which was mixing different - interpretations of the '..._len' fields). - [Adam Langley (Google)] - - *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than - BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent - threads won't reuse the same blinding coefficients. - - This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING - lock to call BN_BLINDING_invert_ex, and avoids one use of - BN_BLINDING_update for each BN_BLINDING structure (previously, - the last update always remained unused). - [Emilia Käsper (Google)] - - *) In ssl3_clear, preserve s3->init_extra along with s3->rbuf. - [Bob Buckholz (Google)] - - Changes between 1.0.0d and 1.0.0e [6 Sep 2011] - - *) Fix bug where CRLs with nextUpdate in the past are sometimes accepted - by initialising X509_STORE_CTX properly. (CVE-2011-3207) - [Kaspar Brand ] - - *) Fix SSL memory handling for (EC)DH ciphersuites, in particular - for multi-threaded use of ECDH. (CVE-2011-3210) - [Adam Langley (Google)] - - *) Fix x509_name_ex_d2i memory leak on bad inputs. - [Bodo Moeller] - - *) Remove hard coded ecdsaWithSHA1 signature tests in ssl code and check - signature public key algorithm by using OID xref utilities instead. - Before this you could only use some ECC ciphersuites with SHA1 only. - [Steve Henson] - - *) Add protection against ECDSA timing attacks as mentioned in the paper - by Billy Bob Brumley and Nicola Tuveri, see: - - http://eprint.iacr.org/2011/232.pdf - - [Billy Bob Brumley and Nicola Tuveri] - - Changes between 1.0.0c and 1.0.0d [8 Feb 2011] - - *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014 - [Neel Mehta, Adam Langley, Bodo Moeller (Google)] - - *) Fix bug in string printing code: if *any* escaping is enabled we must - escape the escape character (backslash) or the resulting string is - ambiguous. - [Steve Henson] - - Changes between 1.0.0b and 1.0.0c [2 Dec 2010] - - *) Disable code workaround for ancient and obsolete Netscape browsers - and servers: an attacker can use it in a ciphersuite downgrade attack. - Thanks to Martin Rex for discovering this bug. CVE-2010-4180 - [Steve Henson] - - *) Fixed J-PAKE implementation error, originally discovered by - Sebastien Martini, further info and confirmation from Stefan - Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252 - [Ben Laurie] - - Changes between 1.0.0a and 1.0.0b [16 Nov 2010] - - *) Fix extension code to avoid race conditions which can result in a buffer - overrun vulnerability: resumed sessions must not be modified as they can - be shared by multiple threads. CVE-2010-3864 - [Steve Henson] - - *) Fix WIN32 build system to correctly link an ENGINE directory into - a DLL. - [Steve Henson] - - Changes between 1.0.0 and 1.0.0a [01 Jun 2010] - - *) Check return value of int_rsa_verify in pkey_rsa_verifyrecover - (CVE-2010-1633) - [Steve Henson, Peter-Michael Hager ] - - Changes between 0.9.8n and 1.0.0 [29 Mar 2010] - - *) Add "missing" function EVP_CIPHER_CTX_copy(). This copies a cipher - context. The operation can be customised via the ctrl mechanism in - case ENGINEs want to include additional functionality. - [Steve Henson] - - *) Tolerate yet another broken PKCS#8 key format: private key value negative. - [Steve Henson] - - *) Add new -subject_hash_old and -issuer_hash_old options to x509 utility to - output hashes compatible with older versions of OpenSSL. - [Willy Weisz ] - - *) Fix compression algorithm handling: if resuming a session use the - compression algorithm of the resumed session instead of determining - it from client hello again. Don't allow server to change algorithm. - [Steve Henson] - - *) Add load_crls() function to apps tidying load_certs() too. Add option - to verify utility to allow additional CRLs to be included. - [Steve Henson] - - *) Update OCSP request code to permit adding custom headers to the request: - some responders need this. - [Steve Henson] - - *) The function EVP_PKEY_sign() returns <=0 on error: check return code - correctly. - [Julia Lawall ] - - *) Update verify callback code in apps/s_cb.c and apps/verify.c, it - needlessly dereferenced structures, used obsolete functions and - didn't handle all updated verify codes correctly. - [Steve Henson] - - *) Disable MD2 in the default configuration. - [Steve Henson] - - *) In BIO_pop() and BIO_push() use the ctrl argument (which was NULL) to - indicate the initial BIO being pushed or popped. This makes it possible - to determine whether the BIO is the one explicitly called or as a result - of the ctrl being passed down the chain. Fix BIO_pop() and SSL BIOs so - it handles reference counts correctly and doesn't zero out the I/O bio - when it is not being explicitly popped. WARNING: applications which - included workarounds for the old buggy behaviour will need to be modified - or they could free up already freed BIOs. - [Steve Henson] - - *) Extend the uni2asc/asc2uni => OPENSSL_uni2asc/OPENSSL_asc2uni - renaming to all platforms (within the 0.9.8 branch, this was - done conditionally on Netware platforms to avoid a name clash). - [Guenter ] - - *) Add ECDHE and PSK support to DTLS. - [Michael Tuexen ] - - *) Add CHECKED_STACK_OF macro to safestack.h, otherwise safestack can't - be used on C++. - [Steve Henson] - - *) Add "missing" function EVP_MD_flags() (without this the only way to - retrieve a digest flags is by accessing the structure directly. Update - EVP_MD_do_all*() and EVP_CIPHER_do_all*() to include the name a digest - or cipher is registered as in the "from" argument. Print out all - registered digests in the dgst usage message instead of manually - attempting to work them out. - [Steve Henson] - - *) If no SSLv2 ciphers are used don't use an SSLv2 compatible client hello: - this allows the use of compression and extensions. Change default cipher - string to remove SSLv2 ciphersuites. This effectively avoids ancient SSLv2 - by default unless an application cipher string requests it. - [Steve Henson] - - *) Alter match criteria in PKCS12_parse(). It used to try to use local - key ids to find matching certificates and keys but some PKCS#12 files - don't follow the (somewhat unwritten) rules and this strategy fails. - Now just gather all certificates together and the first private key - then look for the first certificate that matches the key. - [Steve Henson] - - *) Support use of registered digest and cipher names for dgst and cipher - commands instead of having to add each one as a special case. So now - you can do: - - openssl sha256 foo - - as well as: - - openssl dgst -sha256 foo - - and this works for ENGINE based algorithms too. - - [Steve Henson] - - *) Update Gost ENGINE to support parameter files. - [Victor B. Wagner ] - - *) Support GeneralizedTime in ca utility. - [Oliver Martin , Steve Henson] - - *) Enhance the hash format used for certificate directory links. The new - form uses the canonical encoding (meaning equivalent names will work - even if they aren't identical) and uses SHA1 instead of MD5. This form - is incompatible with the older format and as a result c_rehash should - be used to rebuild symbolic links. - [Steve Henson] - - *) Make PKCS#8 the default write format for private keys, replacing the - traditional format. This form is standardised, more secure and doesn't - include an implicit MD5 dependency. - [Steve Henson] - - *) Add a $gcc_devteam_warn option to Configure. The idea is that any code - committed to OpenSSL should pass this lot as a minimum. - [Steve Henson] - - *) Add session ticket override functionality for use by EAP-FAST. - [Jouni Malinen ] - - *) Modify HMAC functions to return a value. Since these can be implemented - in an ENGINE errors can occur. - [Steve Henson] - - *) Type-checked OBJ_bsearch_ex. - [Ben Laurie] - - *) Type-checked OBJ_bsearch. Also some constification necessitated - by type-checking. Still to come: TXT_DB, bsearch(?), - OBJ_bsearch_ex, qsort, CRYPTO_EX_DATA, ASN1_VALUE, ASN1_STRING, - CONF_VALUE. - [Ben Laurie] - - *) New function OPENSSL_gmtime_adj() to add a specific number of days and - seconds to a tm structure directly, instead of going through OS - specific date routines. This avoids any issues with OS routines such - as the year 2038 bug. New *_adj() functions for ASN1 time structures - and X509_time_adj_ex() to cover the extended range. The existing - X509_time_adj() is still usable and will no longer have any date issues. - [Steve Henson] - - *) Delta CRL support. New use deltas option which will attempt to locate - and search any appropriate delta CRLs available. - - This work was sponsored by Google. - [Steve Henson] - - *) Support for CRLs partitioned by reason code. Reorganise CRL processing - code and add additional score elements. Validate alternate CRL paths - as part of the CRL checking and indicate a new error "CRL path validation - error" in this case. Applications wanting additional details can use - the verify callback and check the new "parent" field. If this is not - NULL CRL path validation is taking place. Existing applications won't - see this because it requires extended CRL support which is off by - default. - - This work was sponsored by Google. - [Steve Henson] - - *) Support for freshest CRL extension. - - This work was sponsored by Google. - [Steve Henson] - - *) Initial indirect CRL support. Currently only supported in the CRLs - passed directly and not via lookup. Process certificate issuer - CRL entry extension and lookup CRL entries by bother issuer name - and serial number. Check and process CRL issuer entry in IDP extension. - - This work was sponsored by Google. - [Steve Henson] - - *) Add support for distinct certificate and CRL paths. The CRL issuer - certificate is validated separately in this case. Only enabled if - an extended CRL support flag is set: this flag will enable additional - CRL functionality in future. - - This work was sponsored by Google. - [Steve Henson] - - *) Add support for policy mappings extension. - - This work was sponsored by Google. - [Steve Henson] - - *) Fixes to pathlength constraint, self issued certificate handling, - policy processing to align with RFC3280 and PKITS tests. - - This work was sponsored by Google. - [Steve Henson] - - *) Support for name constraints certificate extension. DN, email, DNS - and URI types are currently supported. - - This work was sponsored by Google. - [Steve Henson] - - *) To cater for systems that provide a pointer-based thread ID rather - than numeric, deprecate the current numeric thread ID mechanism and - replace it with a structure and associated callback type. This - mechanism allows a numeric "hash" to be extracted from a thread ID in - either case, and on platforms where pointers are larger than 'long', - mixing is done to help ensure the numeric 'hash' is usable even if it - can't be guaranteed unique. The default mechanism is to use "&errno" - as a pointer-based thread ID to distinguish between threads. - - Applications that want to provide their own thread IDs should now use - CRYPTO_THREADID_set_callback() to register a callback that will call - either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer(). - - Note that ERR_remove_state() is now deprecated, because it is tied - to the assumption that thread IDs are numeric. ERR_remove_state(0) - to free the current thread's error state should be replaced by - ERR_remove_thread_state(NULL). - - (This new approach replaces the functions CRYPTO_set_idptr_callback(), - CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in - OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an - application was previously providing a numeric thread callback that - was inappropriate for distinguishing threads, then uniqueness might - have been obtained with &errno that happened immediately in the - intermediate development versions of OpenSSL; this is no longer the - case, the numeric thread callback will now override the automatic use - of &errno.) - [Geoff Thorpe, with help from Bodo Moeller] - - *) Initial support for different CRL issuing certificates. This covers a - simple case where the self issued certificates in the chain exist and - the real CRL issuer is higher in the existing chain. - - This work was sponsored by Google. - [Steve Henson] - - *) Removed effectively defunct crypto/store from the build. - [Ben Laurie] - - *) Revamp of STACK to provide stronger type-checking. Still to come: - TXT_DB, bsearch(?), OBJ_bsearch, qsort, CRYPTO_EX_DATA, ASN1_VALUE, - ASN1_STRING, CONF_VALUE. - [Ben Laurie] - - *) Add a new SSL_MODE_RELEASE_BUFFERS mode flag to release unused buffer - RAM on SSL connections. This option can save about 34k per idle SSL. - [Nick Mathewson] - - *) Revamp of LHASH to provide stronger type-checking. Still to come: - STACK, TXT_DB, bsearch, qsort. - [Ben Laurie] - - *) Initial support for Cryptographic Message Syntax (aka CMS) based - on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility, - support for data, signedData, compressedData, digestedData and - encryptedData, envelopedData types included. Scripts to check against - RFC4134 examples draft and interop and consistency checks of many - content types and variants. - [Steve Henson] - - *) Add options to enc utility to support use of zlib compression BIO. - [Steve Henson] - - *) Extend mk1mf to support importing of options and assembly language - files from Configure script, currently only included in VC-WIN32. - The assembly language rules can now optionally generate the source - files from the associated perl scripts. - [Steve Henson] - - *) Implement remaining functionality needed to support GOST ciphersuites. - Interop testing has been performed using CryptoPro implementations. - [Victor B. Wagner ] - - *) s390x assembler pack. - [Andy Polyakov] - - *) ARMv4 assembler pack. ARMv4 refers to v4 and later ISA, not CPU - "family." - [Andy Polyakov] - - *) Implement Opaque PRF Input TLS extension as specified in - draft-rescorla-tls-opaque-prf-input-00.txt. Since this is not an - official specification yet and no extension type assignment by - IANA exists, this extension (for now) will have to be explicitly - enabled when building OpenSSL by providing the extension number - to use. For example, specify an option - - -DTLSEXT_TYPE_opaque_prf_input=0x9527 - - to the "config" or "Configure" script to enable the extension, - assuming extension number 0x9527 (which is a completely arbitrary - and unofficial assignment based on the MD5 hash of the Internet - Draft). Note that by doing so, you potentially lose - interoperability with other TLS implementations since these might - be using the same extension number for other purposes. - - SSL_set_tlsext_opaque_prf_input(ssl, src, len) is used to set the - opaque PRF input value to use in the handshake. This will create - an internal copy of the length-'len' string at 'src', and will - return non-zero for success. - - To get more control and flexibility, provide a callback function - by using - - SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) - SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) - - where - - int (*cb)(SSL *, void *peerinput, size_t len, void *arg); - void *arg; - - Callback function 'cb' will be called in handshakes, and is - expected to use SSL_set_tlsext_opaque_prf_input() as appropriate. - Argument 'arg' is for application purposes (the value as given to - SSL_CTX_set_tlsext_opaque_prf_input_callback_arg() will directly - be provided to the callback function). The callback function - has to return non-zero to report success: usually 1 to use opaque - PRF input just if possible, or 2 to enforce use of the opaque PRF - input. In the latter case, the library will abort the handshake - if opaque PRF input is not successfully negotiated. - - Arguments 'peerinput' and 'len' given to the callback function - will always be NULL and 0 in the case of a client. A server will - see the client's opaque PRF input through these variables if - available (NULL and 0 otherwise). Note that if the server - provides an opaque PRF input, the length must be the same as the - length of the client's opaque PRF input. - - Note that the callback function will only be called when creating - a new session (session resumption can resume whatever was - previously negotiated), and will not be called in SSL 2.0 - handshakes; thus, SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) or - SSL_set_options(ssl, SSL_OP_NO_SSLv2) is especially recommended - for applications that need to enforce opaque PRF input. - - [Bodo Moeller] - - *) Update ssl code to support digests other than SHA1+MD5 for handshake - MAC. - - [Victor B. Wagner ] - - *) Add RFC4507 support to OpenSSL. This includes the corrections in - RFC4507bis. The encrypted ticket format is an encrypted encoded - SSL_SESSION structure, that way new session features are automatically - supported. - - If a client application caches session in an SSL_SESSION structure - support is transparent because tickets are now stored in the encoded - SSL_SESSION. - - The SSL_CTX structure automatically generates keys for ticket - protection in servers so again support should be possible - with no application modification. - - If a client or server wishes to disable RFC4507 support then the option - SSL_OP_NO_TICKET can be set. - - Add a TLS extension debugging callback to allow the contents of any client - or server extensions to be examined. - - This work was sponsored by Google. - [Steve Henson] - - *) Final changes to avoid use of pointer pointer casts in OpenSSL. - OpenSSL should now compile cleanly on gcc 4.2 - [Peter Hartley , Steve Henson] - - *) Update SSL library to use new EVP_PKEY MAC API. Include generic MAC - support including streaming MAC support: this is required for GOST - ciphersuite support. - [Victor B. Wagner , Steve Henson] - - *) Add option -stream to use PKCS#7 streaming in smime utility. New - function i2d_PKCS7_bio_stream() and PEM_write_PKCS7_bio_stream() - to output in BER and PEM format. - [Steve Henson] - - *) Experimental support for use of HMAC via EVP_PKEY interface. This - allows HMAC to be handled via the EVP_DigestSign*() interface. The - EVP_PKEY "key" in this case is the HMAC key, potentially allowing - ENGINE support for HMAC keys which are unextractable. New -mac and - -macopt options to dgst utility. - [Steve Henson] - - *) New option -sigopt to dgst utility. Update dgst to use - EVP_Digest{Sign,Verify}*. These two changes make it possible to use - alternative signing parameters such as X9.31 or PSS in the dgst - utility. - [Steve Henson] - - *) Change ssl_cipher_apply_rule(), the internal function that does - the work each time a ciphersuite string requests enabling - ("foo+bar"), moving ("+foo+bar"), disabling ("-foo+bar", or - removing ("!foo+bar") a class of ciphersuites: Now it maintains - the order of disabled ciphersuites such that those ciphersuites - that most recently went from enabled to disabled not only stay - in order with respect to each other, but also have higher priority - than other disabled ciphersuites the next time ciphersuites are - enabled again. - - This means that you can now say, e.g., "PSK:-PSK:HIGH" to enable - the same ciphersuites as with "HIGH" alone, but in a specific - order where the PSK ciphersuites come first (since they are the - most recently disabled ciphersuites when "HIGH" is parsed). - - Also, change ssl_create_cipher_list() (using this new - functionality) such that between otherwise identical - ciphersuites, ephemeral ECDH is preferred over ephemeral DH in - the default order. - [Bodo Moeller] - - *) Change ssl_create_cipher_list() so that it automatically - arranges the ciphersuites in reasonable order before starting - to process the rule string. Thus, the definition for "DEFAULT" - (SSL_DEFAULT_CIPHER_LIST) now is just "ALL:!aNULL:!eNULL", but - remains equivalent to "AES:ALL:!aNULL:!eNULL:+aECDH:+kRSA:+RC4:@STRENGTH". - This makes it much easier to arrive at a reasonable default order - in applications for which anonymous ciphers are OK (meaning - that you can't actually use DEFAULT). - [Bodo Moeller; suggested by Victor Duchovni] - - *) Split the SSL/TLS algorithm mask (as used for ciphersuite string - processing) into multiple integers instead of setting - "SSL_MKEY_MASK" bits, "SSL_AUTH_MASK" bits, "SSL_ENC_MASK", - "SSL_MAC_MASK", and "SSL_SSL_MASK" bits all in a single integer. - (These masks as well as the individual bit definitions are hidden - away into the non-exported interface ssl/ssl_locl.h, so this - change to the definition of the SSL_CIPHER structure shouldn't - affect applications.) This give us more bits for each of these - categories, so there is no longer a need to coagulate AES128 and - AES256 into a single algorithm bit, and to coagulate Camellia128 - and Camellia256 into a single algorithm bit, which has led to all - kinds of kludges. - - Thus, among other things, the kludge introduced in 0.9.7m and - 0.9.8e for masking out AES256 independently of AES128 or masking - out Camellia256 independently of AES256 is not needed here in 0.9.9. - - With the change, we also introduce new ciphersuite aliases that - so far were missing: "AES128", "AES256", "CAMELLIA128", and - "CAMELLIA256". - [Bodo Moeller] - - *) Add support for dsa-with-SHA224 and dsa-with-SHA256. - Use the leftmost N bytes of the signature input if the input is - larger than the prime q (with N being the size in bytes of q). - [Nils Larsch] - - *) Very *very* experimental PKCS#7 streaming encoder support. Nothing uses - it yet and it is largely untested. - [Steve Henson] - - *) Add support for the ecdsa-with-SHA224/256/384/512 signature types. - [Nils Larsch] - - *) Initial incomplete changes to avoid need for function casts in OpenSSL - some compilers (gcc 4.2 and later) reject their use. Safestack is - reimplemented. Update ASN1 to avoid use of legacy functions. - [Steve Henson] - - *) Win32/64 targets are linked with Winsock2. - [Andy Polyakov] - - *) Add an X509_CRL_METHOD structure to allow CRL processing to be redirected - to external functions. This can be used to increase CRL handling - efficiency especially when CRLs are very large by (for example) storing - the CRL revoked certificates in a database. - [Steve Henson] - - *) Overhaul of by_dir code. Add support for dynamic loading of CRLs so - new CRLs added to a directory can be used. New command line option - -verify_return_error to s_client and s_server. This causes real errors - to be returned by the verify callback instead of carrying on no matter - what. This reflects the way a "real world" verify callback would behave. - [Steve Henson] - - *) GOST engine, supporting several GOST algorithms and public key formats. - Kindly donated by Cryptocom. - [Cryptocom] - - *) Partial support for Issuing Distribution Point CRL extension. CRLs - partitioned by DP are handled but no indirect CRL or reason partitioning - (yet). Complete overhaul of CRL handling: now the most suitable CRL is - selected via a scoring technique which handles IDP and AKID in CRLs. - [Steve Henson] - - *) New X509_STORE_CTX callbacks lookup_crls() and lookup_certs() which - will ultimately be used for all verify operations: this will remove the - X509_STORE dependency on certificate verification and allow alternative - lookup methods. X509_STORE based implementations of these two callbacks. - [Steve Henson] - - *) Allow multiple CRLs to exist in an X509_STORE with matching issuer names. - Modify get_crl() to find a valid (unexpired) CRL if possible. - [Steve Henson] - - *) New function X509_CRL_match() to check if two CRLs are identical. Normally - this would be called X509_CRL_cmp() but that name is already used by - a function that just compares CRL issuer names. Cache several CRL - extensions in X509_CRL structure and cache CRLDP in X509. - [Steve Henson] - - *) Store a "canonical" representation of X509_NAME structure (ASN1 Name) - this maps equivalent X509_NAME structures into a consistent structure. - Name comparison can then be performed rapidly using memcmp(). - [Steve Henson] - - *) Non-blocking OCSP request processing. Add -timeout option to ocsp - utility. - [Steve Henson] - - *) Allow digests to supply their own micalg string for S/MIME type using - the ctrl EVP_MD_CTRL_MICALG. - [Steve Henson] - - *) During PKCS7 signing pass the PKCS7 SignerInfo structure to the - EVP_PKEY_METHOD before and after signing via the EVP_PKEY_CTRL_PKCS7_SIGN - ctrl. It can then customise the structure before and/or after signing - if necessary. - [Steve Henson] - - *) New function OBJ_add_sigid() to allow application defined signature OIDs - to be added to OpenSSLs internal tables. New function OBJ_sigid_free() - to free up any added signature OIDs. - [Steve Henson] - - *) New functions EVP_CIPHER_do_all(), EVP_CIPHER_do_all_sorted(), - EVP_MD_do_all() and EVP_MD_do_all_sorted() to enumerate internal - digest and cipher tables. New options added to openssl utility: - list-message-digest-algorithms and list-cipher-algorithms. - [Steve Henson] - - *) Change the array representation of binary polynomials: the list - of degrees of non-zero coefficients is now terminated with -1. - Previously it was terminated with 0, which was also part of the - value; thus, the array representation was not applicable to - polynomials where t^0 has coefficient zero. This change makes - the array representation useful in a more general context. - [Douglas Stebila] - - *) Various modifications and fixes to SSL/TLS cipher string - handling. For ECC, the code now distinguishes between fixed ECDH - with RSA certificates on the one hand and with ECDSA certificates - on the other hand, since these are separate ciphersuites. The - unused code for Fortezza ciphersuites has been removed. - - For consistency with EDH, ephemeral ECDH is now called "EECDH" - (not "ECDHE"). For consistency with the code for DH - certificates, use of ECDH certificates is now considered ECDH - authentication, not RSA or ECDSA authentication (the latter is - merely the CA's signing algorithm and not actively used in the - protocol). - - The temporary ciphersuite alias "ECCdraft" is no longer - available, and ECC ciphersuites are no longer excluded from "ALL" - and "DEFAULT". The following aliases now exist for RFC 4492 - ciphersuites, most of these by analogy with the DH case: - - kECDHr - ECDH cert, signed with RSA - kECDHe - ECDH cert, signed with ECDSA - kECDH - ECDH cert (signed with either RSA or ECDSA) - kEECDH - ephemeral ECDH - ECDH - ECDH cert or ephemeral ECDH - - aECDH - ECDH cert - aECDSA - ECDSA cert - ECDSA - ECDSA cert - - AECDH - anonymous ECDH - EECDH - non-anonymous ephemeral ECDH (equivalent to "kEECDH:-AECDH") - - [Bodo Moeller] - - *) Add additional S/MIME capabilities for AES and GOST ciphers if supported. - Use correct micalg parameters depending on digest(s) in signed message. - [Steve Henson] - - *) Add engine support for EVP_PKEY_ASN1_METHOD. Add functions to process - an ENGINE asn1 method. Support ENGINE lookups in the ASN1 code. - [Steve Henson] - - *) Initial engine support for EVP_PKEY_METHOD. New functions to permit - an engine to register a method. Add ENGINE lookups for methods and - functional reference processing. - [Steve Henson] - - *) New functions EVP_Digest{Sign,Verify)*. These are enhanced versions of - EVP_{Sign,Verify}* which allow an application to customise the signature - process. - [Steve Henson] - - *) New -resign option to smime utility. This adds one or more signers - to an existing PKCS#7 signedData structure. Also -md option to use an - alternative message digest algorithm for signing. - [Steve Henson] - - *) Tidy up PKCS#7 routines and add new functions to make it easier to - create PKCS7 structures containing multiple signers. Update smime - application to support multiple signers. - [Steve Henson] - - *) New -macalg option to pkcs12 utility to allow setting of an alternative - digest MAC. - [Steve Henson] - - *) Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC. - Reorganize PBE internals to lookup from a static table using NIDs, - add support for HMAC PBE OID translation. Add a EVP_CIPHER ctrl: - EVP_CTRL_PBE_PRF_NID this allows a cipher to specify an alternative - PRF which will be automatically used with PBES2. - [Steve Henson] - - *) Replace the algorithm specific calls to generate keys in "req" with the - new API. - [Steve Henson] - - *) Update PKCS#7 enveloped data routines to use new API. This is now - supported by any public key method supporting the encrypt operation. A - ctrl is added to allow the public key algorithm to examine or modify - the PKCS#7 RecipientInfo structure if it needs to: for RSA this is - a no op. - [Steve Henson] - - *) Add a ctrl to asn1 method to allow a public key algorithm to express - a default digest type to use. In most cases this will be SHA1 but some - algorithms (such as GOST) need to specify an alternative digest. The - return value indicates how strong the preference is 1 means optional and - 2 is mandatory (that is it is the only supported type). Modify - ASN1_item_sign() to accept a NULL digest argument to indicate it should - use the default md. Update openssl utilities to use the default digest - type for signing if it is not explicitly indicated. - [Steve Henson] - - *) Use OID cross reference table in ASN1_sign() and ASN1_verify(). New - EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant - signing method from the key type. This effectively removes the link - between digests and public key types. - [Steve Henson] - - *) Add an OID cross reference table and utility functions. Its purpose is to - translate between signature OIDs such as SHA1WithrsaEncryption and SHA1, - rsaEncryption. This will allow some of the algorithm specific hackery - needed to use the correct OID to be removed. - [Steve Henson] - - *) Remove algorithm specific dependencies when setting PKCS7_SIGNER_INFO - structures for PKCS7_sign(). They are now set up by the relevant public - key ASN1 method. - [Steve Henson] - - *) Add provisional EC pkey method with support for ECDSA and ECDH. - [Steve Henson] - - *) Add support for key derivation (agreement) in the API, DH method and - pkeyutl. - [Steve Henson] - - *) Add DSA pkey method and DH pkey methods, extend DH ASN1 method to support - public and private key formats. As a side effect these add additional - command line functionality not previously available: DSA signatures can be - generated and verified using pkeyutl and DH key support and generation in - pkey, genpkey. - [Steve Henson] - - *) BeOS support. - [Oliver Tappe ] - - *) New make target "install_html_docs" installs HTML renditions of the - manual pages. - [Oliver Tappe ] - - *) New utility "genpkey" this is analogous to "genrsa" etc except it can - generate keys for any algorithm. Extend and update EVP_PKEY_METHOD to - support key and parameter generation and add initial key generation - functionality for RSA. - [Steve Henson] - - *) Add functions for main EVP_PKEY_method operations. The undocumented - functions EVP_PKEY_{encrypt,decrypt} have been renamed to - EVP_PKEY_{encrypt,decrypt}_old. - [Steve Henson] - - *) Initial definitions for EVP_PKEY_METHOD. This will be a high level public - key API, doesn't do much yet. - [Steve Henson] - - *) New function EVP_PKEY_asn1_get0_info() to retrieve information about - public key algorithms. New option to openssl utility: - "list-public-key-algorithms" to print out info. - [Steve Henson] - - *) Implement the Supported Elliptic Curves Extension for - ECC ciphersuites from draft-ietf-tls-ecc-12.txt. - [Douglas Stebila] - - *) Don't free up OIDs in OBJ_cleanup() if they are in use by EVP_MD or - EVP_CIPHER structures to avoid later problems in EVP_cleanup(). - [Steve Henson] - - *) New utilities pkey and pkeyparam. These are similar to algorithm specific - utilities such as rsa, dsa, dsaparam etc except they process any key - type. - [Steve Henson] - - *) Transfer public key printing routines to EVP_PKEY_ASN1_METHOD. New - functions EVP_PKEY_print_public(), EVP_PKEY_print_private(), - EVP_PKEY_print_param() to print public key data from an EVP_PKEY - structure. - [Steve Henson] - - *) Initial support for pluggable public key ASN1. - De-spaghettify the public key ASN1 handling. Move public and private - key ASN1 handling to a new EVP_PKEY_ASN1_METHOD structure. Relocate - algorithm specific handling to a single module within the relevant - algorithm directory. Add functions to allow (near) opaque processing - of public and private key structures. - [Steve Henson] - - *) Implement the Supported Point Formats Extension for - ECC ciphersuites from draft-ietf-tls-ecc-12.txt. - [Douglas Stebila] - - *) Add initial support for RFC 4279 PSK TLS ciphersuites. Add members - for the psk identity [hint] and the psk callback functions to the - SSL_SESSION, SSL and SSL_CTX structure. - - New ciphersuites: - PSK-RC4-SHA, PSK-3DES-EDE-CBC-SHA, PSK-AES128-CBC-SHA, - PSK-AES256-CBC-SHA - - New functions: - SSL_CTX_use_psk_identity_hint - SSL_get_psk_identity_hint - SSL_get_psk_identity - SSL_use_psk_identity_hint - - [Mika Kousa and Pasi Eronen of Nokia Corporation] - - *) Add RFC 3161 compliant time stamp request creation, response generation - and response verification functionality. - [Zoltán Glózik , The OpenTSA Project] - - *) Add initial support for TLS extensions, specifically for the server_name - extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now - have new members for a host name. The SSL data structure has an - additional member SSL_CTX *initial_ctx so that new sessions can be - stored in that context to allow for session resumption, even after the - SSL has been switched to a new SSL_CTX in reaction to a client's - server_name extension. - - New functions (subject to change): - - SSL_get_servername() - SSL_get_servername_type() - SSL_set_SSL_CTX() - - New CTRL codes and macros (subject to change): - - SSL_CTRL_SET_TLSEXT_SERVERNAME_CB - - SSL_CTX_set_tlsext_servername_callback() - SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG - - SSL_CTX_set_tlsext_servername_arg() - SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name() - - openssl s_client has a new '-servername ...' option. - - openssl s_server has new options '-servername_host ...', '-cert2 ...', - '-key2 ...', '-servername_fatal' (subject to change). This allows - testing the HostName extension for a specific single host name ('-cert' - and '-key' remain fallbacks for handshakes without HostName - negotiation). If the unrecognized_name alert has to be sent, this by - default is a warning; it becomes fatal with the '-servername_fatal' - option. - - [Peter Sylvester, Remy Allais, Christophe Renou] - - *) Whirlpool hash implementation is added. - [Andy Polyakov] - - *) BIGNUM code on 64-bit SPARCv9 targets is switched from bn(64,64) to - bn(64,32). Because of instruction set limitations it doesn't have - any negative impact on performance. This was done mostly in order - to make it possible to share assembler modules, such as bn_mul_mont - implementations, between 32- and 64-bit builds without hassle. - [Andy Polyakov] - - *) Move code previously exiled into file crypto/ec/ec2_smpt.c - to ec2_smpl.c, and no longer require the OPENSSL_EC_BIN_PT_COMP - macro. - [Bodo Moeller] - - *) New candidate for BIGNUM assembler implementation, bn_mul_mont, - dedicated Montgomery multiplication procedure, is introduced. - BN_MONT_CTX is modified to allow bn_mul_mont to reach for higher - "64-bit" performance on certain 32-bit targets. - [Andy Polyakov] - - *) New option SSL_OP_NO_COMP to disable use of compression selectively - in SSL structures. New SSL ctrl to set maximum send fragment size. - Save memory by setting the I/O buffer sizes dynamically instead of - using the maximum available value. - [Steve Henson] - - *) New option -V for 'openssl ciphers'. This prints the ciphersuite code - in addition to the text details. - [Bodo Moeller] - - *) Very, very preliminary EXPERIMENTAL support for printing of general - ASN1 structures. This currently produces rather ugly output and doesn't - handle several customised structures at all. - [Steve Henson] - - *) Integrated support for PVK file format and some related formats such - as MS PUBLICKEYBLOB and PRIVATEKEYBLOB. Command line switches to support - these in the 'rsa' and 'dsa' utilities. - [Steve Henson] - - *) Support for PKCS#1 RSAPublicKey format on rsa utility command line. - [Steve Henson] - - *) Remove the ancient ASN1_METHOD code. This was only ever used in one - place for the (very old) "NETSCAPE" format certificates which are now - handled using new ASN1 code equivalents. - [Steve Henson] - - *) Let the TLSv1_method() etc. functions return a 'const' SSL_METHOD - pointer and make the SSL_METHOD parameter in SSL_CTX_new, - SSL_CTX_set_ssl_version and SSL_set_ssl_method 'const'. - [Nils Larsch] - - *) Modify CRL distribution points extension code to print out previously - unsupported fields. Enhance extension setting code to allow setting of - all fields. - [Steve Henson] - - *) Add print and set support for Issuing Distribution Point CRL extension. - [Steve Henson] - - *) Change 'Configure' script to enable Camellia by default. - [NTT] - - Changes between 0.9.8m and 0.9.8n [24 Mar 2010] - - *) When rejecting SSL/TLS records due to an incorrect version number, never - update s->server with a new major version number. As of - - OpenSSL 0.9.8m if 'short' is a 16-bit type, - - OpenSSL 0.9.8f if 'short' is longer than 16 bits, - the previous behavior could result in a read attempt at NULL when - receiving specific incorrect SSL/TLS records once record payload - protection is active. (CVE-2010-0740) - [Bodo Moeller, Adam Langley ] - - *) Fix for CVE-2010-0433 where some kerberos enabled versions of OpenSSL - could be crashed if the relevant tables were not present (e.g. chrooted). - [Tomas Hoger ] - - Changes between 0.9.8l and 0.9.8m [25 Feb 2010] - - *) Always check bn_wexpand() return values for failure. (CVE-2009-3245) - [Martin Olsson, Neel Mehta] - - *) Fix X509_STORE locking: Every 'objs' access requires a lock (to - accommodate for stack sorting, always a write lock!). - [Bodo Moeller] - - *) On some versions of WIN32 Heap32Next is very slow. This can cause - excessive delays in the RAND_poll(): over a minute. As a workaround - include a time check in the inner Heap32Next loop too. - [Steve Henson] - - *) The code that handled flushing of data in SSL/TLS originally used the - BIO_CTRL_INFO ctrl to see if any data was pending first. This caused - the problem outlined in PR#1949. The fix suggested there however can - trigger problems with buggy BIO_CTRL_WPENDING (e.g. some versions - of Apache). So instead simplify the code to flush unconditionally. - This should be fine since flushing with no data to flush is a no op. - [Steve Henson] - - *) Handle TLS versions 2.0 and later properly and correctly use the - highest version of TLS/SSL supported. Although TLS >= 2.0 is some way - off ancient servers have a habit of sticking around for a while... - [Steve Henson] - - *) Modify compression code so it frees up structures without using the - ex_data callbacks. This works around a problem where some applications - call CRYPTO_cleanup_all_ex_data() before application exit (e.g. when - restarting) then use compression (e.g. SSL with compression) later. - This results in significant per-connection memory leaks and - has caused some security issues including CVE-2008-1678 and - CVE-2009-4355. - [Steve Henson] - - *) Constify crypto/cast (i.e., ): a CAST_KEY doesn't - change when encrypting or decrypting. - [Bodo Moeller] - - *) Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to - connect and renegotiate with servers which do not support RI. - Until RI is more widely deployed this option is enabled by default. - [Steve Henson] - - *) Add "missing" ssl ctrls to clear options and mode. - [Steve Henson] - - *) If client attempts to renegotiate and doesn't support RI respond with - a no_renegotiation alert as required by RFC5746. Some renegotiating - TLS clients will continue a connection gracefully when they receive - the alert. Unfortunately OpenSSL mishandled this alert and would hang - waiting for a server hello which it will never receive. Now we treat a - received no_renegotiation alert as a fatal error. This is because - applications requesting a renegotiation might well expect it to succeed - and would have no code in place to handle the server denying it so the - only safe thing to do is to terminate the connection. - [Steve Henson] - - *) Add ctrl macro SSL_get_secure_renegotiation_support() which returns 1 if - peer supports secure renegotiation and 0 otherwise. Print out peer - renegotiation support in s_client/s_server. - [Steve Henson] - - *) Replace the highly broken and deprecated SPKAC certification method with - the updated NID creation version. This should correctly handle UTF8. - [Steve Henson] - - *) Implement RFC5746. Re-enable renegotiation but require the extension - as needed. Unfortunately, SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION - turns out to be a bad idea. It has been replaced by - SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with - SSL_CTX_set_options(). This is really not recommended unless you - know what you are doing. - [Eric Rescorla , Ben Laurie, Steve Henson] - - *) Fixes to stateless session resumption handling. Use initial_ctx when - issuing and attempting to decrypt tickets in case it has changed during - servername handling. Use a non-zero length session ID when attempting - stateless session resumption: this makes it possible to determine if - a resumption has occurred immediately after receiving server hello - (several places in OpenSSL subtly assume this) instead of later in - the handshake. - [Steve Henson] - - *) The functions ENGINE_ctrl(), OPENSSL_isservice(), - CMS_get1_RecipientRequest() and RAND_bytes() can return <=0 on error - fixes for a few places where the return code is not checked - correctly. - [Julia Lawall ] - - *) Add --strict-warnings option to Configure script to include devteam - warnings in other configurations. - [Steve Henson] - - *) Add support for --libdir option and LIBDIR variable in makefiles. This - makes it possible to install openssl libraries in locations which - have names other than "lib", for example "/usr/lib64" which some - systems need. - [Steve Henson, based on patch from Jeremy Utley] - - *) Don't allow the use of leading 0x80 in OIDs. This is a violation of - X690 8.9.12 and can produce some misleading textual output of OIDs. - [Steve Henson, reported by Dan Kaminsky] - - *) Delete MD2 from algorithm tables. This follows the recommendation in - several standards that it is not used in new applications due to - several cryptographic weaknesses. For binary compatibility reasons - the MD2 API is still compiled in by default. - [Steve Henson] - - *) Add compression id to {d2i,i2d}_SSL_SESSION so it is correctly saved - and restored. - [Steve Henson] - - *) Rename uni2asc and asc2uni functions to OPENSSL_uni2asc and - OPENSSL_asc2uni conditionally on Netware platforms to avoid a name - clash. - [Guenter ] - - *) Fix the server certificate chain building code to use X509_verify_cert(), - it used to have an ad-hoc builder which was unable to cope with anything - other than a simple chain. - [David Woodhouse , Steve Henson] - - *) Don't check self signed certificate signatures in X509_verify_cert() - by default (a flag can override this): it just wastes time without - adding any security. As a useful side effect self signed root CAs - with non-FIPS digests are now usable in FIPS mode. - [Steve Henson] - - *) In dtls1_process_out_of_seq_message() the check if the current message - is already buffered was missing. For every new message was memory - allocated, allowing an attacker to perform an denial of service attack - with sending out of seq handshake messages until there is no memory - left. Additionally every future message was buffered, even if the - sequence number made no sense and would be part of another handshake. - So only messages with sequence numbers less than 10 in advance will be - buffered. (CVE-2009-1378) - [Robin Seggelmann, discovered by Daniel Mentz] - - *) Records are buffered if they arrive with a future epoch to be - processed after finishing the corresponding handshake. There is - currently no limitation to this buffer allowing an attacker to perform - a DOS attack with sending records with future epochs until there is no - memory left. This patch adds the pqueue_size() function to determine - the size of a buffer and limits the record buffer to 100 entries. - (CVE-2009-1377) - [Robin Seggelmann, discovered by Daniel Mentz] - - *) Keep a copy of frag->msg_header.frag_len so it can be used after the - parent structure is freed. (CVE-2009-1379) - [Daniel Mentz] - - *) Handle non-blocking I/O properly in SSL_shutdown() call. - [Darryl Miles ] - - *) Add 2.5.4.* OIDs - [Ilya O. ] - - Changes between 0.9.8k and 0.9.8l [5 Nov 2009] - - *) Disable renegotiation completely - this fixes a severe security - problem (CVE-2009-3555) at the cost of breaking all - renegotiation. Renegotiation can be re-enabled by setting - SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION in s3->flags at - run-time. This is really not recommended unless you know what - you're doing. - [Ben Laurie] - - Changes between 0.9.8j and 0.9.8k [25 Mar 2009] - - *) Don't set val to NULL when freeing up structures, it is freed up by - underlying code. If sizeof(void *) > sizeof(long) this can result in - zeroing past the valid field. (CVE-2009-0789) - [Paolo Ganci ] - - *) Fix bug where return value of CMS_SignerInfo_verify_content() was not - checked correctly. This would allow some invalid signed attributes to - appear to verify correctly. (CVE-2009-0591) - [Ivan Nestlerode ] - - *) Reject UniversalString and BMPString types with invalid lengths. This - prevents a crash in ASN1_STRING_print_ex() which assumes the strings have - a legal length. (CVE-2009-0590) - [Steve Henson] - - *) Set S/MIME signing as the default purpose rather than setting it - unconditionally. This allows applications to override it at the store - level. - [Steve Henson] - - *) Permit restricted recursion of ASN1 strings. This is needed in practice - to handle some structures. - [Steve Henson] - - *) Improve efficiency of mem_gets: don't search whole buffer each time - for a '\n' - [Jeremy Shapiro ] - - *) New -hex option for openssl rand. - [Matthieu Herrb] - - *) Print out UTF8String and NumericString when parsing ASN1. - [Steve Henson] - - *) Support NumericString type for name components. - [Steve Henson] - - *) Allow CC in the environment to override the automatically chosen - compiler. Note that nothing is done to ensure flags work with the - chosen compiler. - [Ben Laurie] - - Changes between 0.9.8i and 0.9.8j [07 Jan 2009] - - *) Properly check EVP_VerifyFinal() and similar return values - (CVE-2008-5077). - [Ben Laurie, Bodo Moeller, Google Security Team] - - *) Enable TLS extensions by default. - [Ben Laurie] - - *) Allow the CHIL engine to be loaded, whether the application is - multithreaded or not. (This does not release the developer from the - obligation to set up the dynamic locking callbacks.) - [Sander Temme ] - - *) Use correct exit code if there is an error in dgst command. - [Steve Henson; problem pointed out by Roland Dirlewanger] - - *) Tweak Configure so that you need to say "experimental-jpake" to enable - JPAKE, and need to use -DOPENSSL_EXPERIMENTAL_JPAKE in applications. - [Bodo Moeller] - - *) Add experimental JPAKE support, including demo authentication in - s_client and s_server. - [Ben Laurie] - - *) Set the comparison function in v3_addr_canonize(). - [Rob Austein ] - - *) Add support for XMPP STARTTLS in s_client. - [Philip Paeps ] - - *) Change the server-side SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG behavior - to ensure that even with this option, only ciphersuites in the - server's preference list will be accepted. (Note that the option - applies only when resuming a session, so the earlier behavior was - just about the algorithm choice for symmetric cryptography.) - [Bodo Moeller] - - Changes between 0.9.8h and 0.9.8i [15 Sep 2008] - - *) Fix NULL pointer dereference if a DTLS server received - ChangeCipherSpec as first record (CVE-2009-1386). - [PR #1679] - - *) Fix a state transition in s3_srvr.c and d1_srvr.c - (was using SSL3_ST_CW_CLNT_HELLO_B, should be ..._ST_SW_SRVR_...). - [Nagendra Modadugu] - - *) The fix in 0.9.8c that supposedly got rid of unsafe - double-checked locking was incomplete for RSA blinding, - addressing just one layer of what turns out to have been - doubly unsafe triple-checked locking. - - So now fix this for real by retiring the MONT_HELPER macro - in crypto/rsa/rsa_eay.c. - - [Bodo Moeller; problem pointed out by Marius Schilder] - - *) Various precautionary measures: - - - Avoid size_t integer overflow in HASH_UPDATE (md32_common.h). - - - Avoid a buffer overflow in d2i_SSL_SESSION() (ssl_asn1.c). - (NB: This would require knowledge of the secret session ticket key - to exploit, in which case you'd be SOL either way.) - - - Change bn_nist.c so that it will properly handle input BIGNUMs - outside the expected range. - - - Enforce the 'num' check in BN_div() (bn_div.c) for non-BN_DEBUG - builds. - - [Neel Mehta, Bodo Moeller] - - *) Allow engines to be "soft loaded" - i.e. optionally don't die if - the load fails. Useful for distros. - [Ben Laurie and the FreeBSD team] - - *) Add support for Local Machine Keyset attribute in PKCS#12 files. - [Steve Henson] - - *) Fix BN_GF2m_mod_arr() top-bit cleanup code. - [Huang Ying] - - *) Expand ENGINE to support engine supplied SSL client certificate functions. - - This work was sponsored by Logica. - [Steve Henson] - - *) Add CryptoAPI ENGINE to support use of RSA and DSA keys held in Windows - keystores. Support for SSL/TLS client authentication too. - Not compiled unless enable-capieng specified to Configure. - - This work was sponsored by Logica. - [Steve Henson] - - *) Fix bug in X509_ATTRIBUTE creation: don't set attribute using - ASN1_TYPE_set1 if MBSTRING flag set. This bug would crash certain - attribute creation routines such as certificate requests and PKCS#12 - files. - [Steve Henson] - - Changes between 0.9.8g and 0.9.8h [28 May 2008] - - *) Fix flaw if 'Server Key exchange message' is omitted from a TLS - handshake which could lead to a client crash as found using the - Codenomicon TLS test suite (CVE-2008-1672) - [Steve Henson, Mark Cox] - - *) Fix double free in TLS server name extensions which could lead to - a remote crash found by Codenomicon TLS test suite (CVE-2008-0891) - [Joe Orton] - - *) Clear error queue in SSL_CTX_use_certificate_chain_file() - - Clear the error queue to ensure that error entries left from - older function calls do not interfere with the correct operation. - [Lutz Jaenicke, Erik de Castro Lopo] - - *) Remove root CA certificates of commercial CAs: - - The OpenSSL project does not recommend any specific CA and does not - have any policy with respect to including or excluding any CA. - Therefore it does not make any sense to ship an arbitrary selection - of root CA certificates with the OpenSSL software. - [Lutz Jaenicke] - - *) RSA OAEP patches to fix two separate invalid memory reads. - The first one involves inputs when 'lzero' is greater than - 'SHA_DIGEST_LENGTH' (it would read about SHA_DIGEST_LENGTH bytes - before the beginning of from). The second one involves inputs where - the 'db' section contains nothing but zeroes (there is a one-byte - invalid read after the end of 'db'). - [Ivan Nestlerode ] - - *) Partial backport from 0.9.9-dev: - - Introduce bn_mul_mont (dedicated Montgomery multiplication - procedure) as a candidate for BIGNUM assembler implementation. - While 0.9.9-dev uses assembler for various architectures, only - x86_64 is available by default here in the 0.9.8 branch, and - 32-bit x86 is available through a compile-time setting. - - To try the 32-bit x86 assembler implementation, use Configure - option "enable-montasm" (which exists only for this backport). - - As "enable-montasm" for 32-bit x86 disclaims code stability - anyway, in this constellation we activate additional code - backported from 0.9.9-dev for further performance improvements, - namely BN_from_montgomery_word. (To enable this otherwise, - e.g. x86_64, try "-DMONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD".) - - [Andy Polyakov (backport partially by Bodo Moeller)] - - *) Add TLS session ticket callback. This allows an application to set - TLS ticket cipher and HMAC keys rather than relying on hardcoded fixed - values. This is useful for key rollover for example where several key - sets may exist with different names. - [Steve Henson] - - *) Reverse ENGINE-internal logic for caching default ENGINE handles. - This was broken until now in 0.9.8 releases, such that the only way - a registered ENGINE could be used (assuming it initialises - successfully on the host) was to explicitly set it as the default - for the relevant algorithms. This is in contradiction with 0.9.7 - behaviour and the documentation. With this fix, when an ENGINE is - registered into a given algorithm's table of implementations, the - 'uptodate' flag is reset so that auto-discovery will be used next - time a new context for that algorithm attempts to select an - implementation. - [Ian Lister (tweaked by Geoff Thorpe)] - - *) Backport of CMS code to OpenSSL 0.9.8. This differs from the 0.9.9 - implementation in the following ways: - - Lack of EVP_PKEY_ASN1_METHOD means algorithm parameters have to be - hard coded. - - Lack of BER streaming support means one pass streaming processing is - only supported if data is detached: setting the streaming flag is - ignored for embedded content. - - CMS support is disabled by default and must be explicitly enabled - with the enable-cms configuration option. - [Steve Henson] - - *) Update the GMP engine glue to do direct copies between BIGNUM and - mpz_t when openssl and GMP use the same limb size. Otherwise the - existing "conversion via a text string export" trick is still used. - [Paul Sheer ] - - *) Zlib compression BIO. This is a filter BIO which compressed and - uncompresses any data passed through it. - [Steve Henson] - - *) Add AES_wrap_key() and AES_unwrap_key() functions to implement - RFC3394 compatible AES key wrapping. - [Steve Henson] - - *) Add utility functions to handle ASN1 structures. ASN1_STRING_set0(): - sets string data without copying. X509_ALGOR_set0() and - X509_ALGOR_get0(): set and retrieve X509_ALGOR (AlgorithmIdentifier) - data. Attribute function X509at_get0_data_by_OBJ(): retrieves data - from an X509_ATTRIBUTE structure optionally checking it occurs only - once. ASN1_TYPE_set1(): set and ASN1_TYPE structure copying supplied - data. - [Steve Henson] - - *) Fix BN flag handling in RSA_eay_mod_exp() and BN_MONT_CTX_set() - to get the expected BN_FLG_CONSTTIME behavior. - [Bodo Moeller (Google)] - - *) Netware support: - - - fixed wrong usage of ioctlsocket() when build for LIBC BSD sockets - - fixed do_tests.pl to run the test suite with CLIB builds too (CLIB_OPT) - - added some more tests to do_tests.pl - - fixed RunningProcess usage so that it works with newer LIBC NDKs too - - removed usage of BN_LLONG for CLIB builds to avoid runtime dependency - - added new Configure targets netware-clib-bsdsock, netware-clib-gcc, - netware-clib-bsdsock-gcc, netware-libc-bsdsock-gcc - - various changes to netware.pl to enable gcc-cross builds on Win32 - platform - - changed crypto/bio/b_sock.c to work with macro functions (CLIB BSD) - - various changes to fix missing prototype warnings - - fixed x86nasm.pl to create correct asm files for NASM COFF output - - added AES, WHIRLPOOL and CPUID assembler code to build files - - added missing AES assembler make rules to mk1mf.pl - - fixed order of includes in apps/ocsp.c so that e_os.h settings apply - [Guenter Knauf ] - - *) Implement certificate status request TLS extension defined in RFC3546. - A client can set the appropriate parameters and receive the encoded - OCSP response via a callback. A server can query the supplied parameters - and set the encoded OCSP response in the callback. Add simplified examples - to s_client and s_server. - [Steve Henson] - - Changes between 0.9.8f and 0.9.8g [19 Oct 2007] - - *) Fix various bugs: - + Binary incompatibility of ssl_ctx_st structure - + DTLS interoperation with non-compliant servers - + Don't call get_session_cb() without proposed session - + Fix ia64 assembler code - [Andy Polyakov, Steve Henson] - - Changes between 0.9.8e and 0.9.8f [11 Oct 2007] - - *) DTLS Handshake overhaul. There were longstanding issues with - OpenSSL DTLS implementation, which were making it impossible for - RFC 4347 compliant client to communicate with OpenSSL server. - Unfortunately just fixing these incompatibilities would "cut off" - pre-0.9.8f clients. To allow for hassle free upgrade post-0.9.8e - server keeps tolerating non RFC compliant syntax. The opposite is - not true, 0.9.8f client can not communicate with earlier server. - This update even addresses CVE-2007-4995. - [Andy Polyakov] - - *) Changes to avoid need for function casts in OpenSSL: some compilers - (gcc 4.2 and later) reject their use. - [Kurt Roeckx , Peter Hartley , - Steve Henson] - - *) Add RFC4507 support to OpenSSL. This includes the corrections in - RFC4507bis. The encrypted ticket format is an encrypted encoded - SSL_SESSION structure, that way new session features are automatically - supported. - - If a client application caches session in an SSL_SESSION structure - support is transparent because tickets are now stored in the encoded - SSL_SESSION. - - The SSL_CTX structure automatically generates keys for ticket - protection in servers so again support should be possible - with no application modification. - - If a client or server wishes to disable RFC4507 support then the option - SSL_OP_NO_TICKET can be set. - - Add a TLS extension debugging callback to allow the contents of any client - or server extensions to be examined. - - This work was sponsored by Google. - [Steve Henson] - - *) Add initial support for TLS extensions, specifically for the server_name - extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now - have new members for a host name. The SSL data structure has an - additional member SSL_CTX *initial_ctx so that new sessions can be - stored in that context to allow for session resumption, even after the - SSL has been switched to a new SSL_CTX in reaction to a client's - server_name extension. - - New functions (subject to change): - - SSL_get_servername() - SSL_get_servername_type() - SSL_set_SSL_CTX() - - New CTRL codes and macros (subject to change): - - SSL_CTRL_SET_TLSEXT_SERVERNAME_CB - - SSL_CTX_set_tlsext_servername_callback() - SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG - - SSL_CTX_set_tlsext_servername_arg() - SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name() - - openssl s_client has a new '-servername ...' option. - - openssl s_server has new options '-servername_host ...', '-cert2 ...', - '-key2 ...', '-servername_fatal' (subject to change). This allows - testing the HostName extension for a specific single host name ('-cert' - and '-key' remain fallbacks for handshakes without HostName - negotiation). If the unrecognized_name alert has to be sent, this by - default is a warning; it becomes fatal with the '-servername_fatal' - option. - - [Peter Sylvester, Remy Allais, Christophe Renou, Steve Henson] - - *) Add AES and SSE2 assembly language support to VC++ build. - [Steve Henson] - - *) Mitigate attack on final subtraction in Montgomery reduction. - [Andy Polyakov] - - *) Fix crypto/ec/ec_mult.c to work properly with scalars of value 0 - (which previously caused an internal error). - [Bodo Moeller] - - *) Squeeze another 10% out of IGE mode when in != out. - [Ben Laurie] - - *) AES IGE mode speedup. - [Dean Gaudet (Google)] - - *) Add the Korean symmetric 128-bit cipher SEED (see - http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp) and - add SEED ciphersuites from RFC 4162: - - TLS_RSA_WITH_SEED_CBC_SHA = "SEED-SHA" - TLS_DHE_DSS_WITH_SEED_CBC_SHA = "DHE-DSS-SEED-SHA" - TLS_DHE_RSA_WITH_SEED_CBC_SHA = "DHE-RSA-SEED-SHA" - TLS_DH_anon_WITH_SEED_CBC_SHA = "ADH-SEED-SHA" - - To minimize changes between patchlevels in the OpenSSL 0.9.8 - series, SEED remains excluded from compilation unless OpenSSL - is configured with 'enable-seed'. - [KISA, Bodo Moeller] - - *) Mitigate branch prediction attacks, which can be practical if a - single processor is shared, allowing a spy process to extract - information. For detailed background information, see - http://eprint.iacr.org/2007/039 (O. Aciicmez, S. Gueron, - J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL - and Necessary Software Countermeasures"). The core of the change - are new versions BN_div_no_branch() and - BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(), - respectively, which are slower, but avoid the security-relevant - conditional branches. These are automatically called by BN_div() - and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for one - of the input BIGNUMs. Also, BN_is_bit_set() has been changed to - remove a conditional branch. - - BN_FLG_CONSTTIME is the new name for the previous - BN_FLG_EXP_CONSTTIME flag, since it now affects more than just - modular exponentiation. (Since OpenSSL 0.9.7h, setting this flag - in the exponent causes BN_mod_exp_mont() to use the alternative - implementation in BN_mod_exp_mont_consttime().) The old name - remains as a deprecated alias. - - Similarly, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general - RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses - constant-time implementations for more than just exponentiation. - Here too the old name is kept as a deprecated alias. - - BN_BLINDING_new() will now use BN_dup() for the modulus so that - the BN_BLINDING structure gets an independent copy of the - modulus. This means that the previous "BIGNUM *m" argument to - BN_BLINDING_new() and to BN_BLINDING_create_param() now - essentially becomes "const BIGNUM *m", although we can't actually - change this in the header file before 0.9.9. It allows - RSA_setup_blinding() to use BN_with_flags() on the modulus to - enable BN_FLG_CONSTTIME. - - [Matthew D Wood (Intel Corp)] - - *) In the SSL/TLS server implementation, be strict about session ID - context matching (which matters if an application uses a single - external cache for different purposes). Previously, - out-of-context reuse was forbidden only if SSL_VERIFY_PEER was - set. This did ensure strict client verification, but meant that, - with applications using a single external cache for quite - different requirements, clients could circumvent ciphersuite - restrictions for a given session ID context by starting a session - in a different context. - [Bodo Moeller] - - *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that - a ciphersuite string such as "DEFAULT:RSA" cannot enable - authentication-only ciphersuites. - [Bodo Moeller] - - *) Update the SSL_get_shared_ciphers() fix CVE-2006-3738 which was - not complete and could lead to a possible single byte overflow - (CVE-2007-5135) [Ben Laurie] - - Changes between 0.9.8d and 0.9.8e [23 Feb 2007] - - *) Since AES128 and AES256 (and similarly Camellia128 and - Camellia256) share a single mask bit in the logic of - ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a - kludge to work properly if AES128 is available and AES256 isn't - (or if Camellia128 is available and Camellia256 isn't). - [Victor Duchovni] - - *) Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c - (within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters): - When a point or a seed is encoded in a BIT STRING, we need to - prevent the removal of trailing zero bits to get the proper DER - encoding. (By default, crypto/asn1/a_bitstr.c assumes the case - of a NamedBitList, for which trailing 0 bits need to be removed.) - [Bodo Moeller] - - *) Have SSL/TLS server implementation tolerate "mismatched" record - protocol version while receiving ClientHello even if the - ClientHello is fragmented. (The server can't insist on the - particular protocol version it has chosen before the ServerHello - message has informed the client about his choice.) - [Bodo Moeller] - - *) Add RFC 3779 support. - [Rob Austein for ARIN, Ben Laurie] - - *) Load error codes if they are not already present instead of using a - static variable. This allows them to be cleanly unloaded and reloaded. - Improve header file function name parsing. - [Steve Henson] - - *) extend SMTP and IMAP protocol emulation in s_client to use EHLO - or CAPABILITY handshake as required by RFCs. - [Goetz Babin-Ebell] - - Changes between 0.9.8c and 0.9.8d [28 Sep 2006] - - *) Introduce limits to prevent malicious keys being able to - cause a denial of service. (CVE-2006-2940) - [Steve Henson, Bodo Moeller] - - *) Fix ASN.1 parsing of certain invalid structures that can result - in a denial of service. (CVE-2006-2937) [Steve Henson] - - *) Fix buffer overflow in SSL_get_shared_ciphers() function. - (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team] - - *) Fix SSL client code which could crash if connecting to a - malicious SSLv2 server. (CVE-2006-4343) - [Tavis Ormandy and Will Drewry, Google Security Team] - - *) Since 0.9.8b, ciphersuite strings naming explicit ciphersuites - match only those. Before that, "AES256-SHA" would be interpreted - as a pattern and match "AES128-SHA" too (since AES128-SHA got - the same strength classification in 0.9.7h) as we currently only - have a single AES bit in the ciphersuite description bitmap. - That change, however, also applied to ciphersuite strings such as - "RC4-MD5" that intentionally matched multiple ciphersuites -- - namely, SSL 2.0 ciphersuites in addition to the more common ones - from SSL 3.0/TLS 1.0. - - So we change the selection algorithm again: Naming an explicit - ciphersuite selects this one ciphersuite, and any other similar - ciphersuite (same bitmap) from *other* protocol versions. - Thus, "RC4-MD5" again will properly select both the SSL 2.0 - ciphersuite and the SSL 3.0/TLS 1.0 ciphersuite. - - Since SSL 2.0 does not have any ciphersuites for which the - 128/256 bit distinction would be relevant, this works for now. - The proper fix will be to use different bits for AES128 and - AES256, which would have avoided the problems from the beginning; - however, bits are scarce, so we can only do this in a new release - (not just a patchlevel) when we can change the SSL_CIPHER - definition to split the single 'unsigned long mask' bitmap into - multiple values to extend the available space. - - [Bodo Moeller] - - Changes between 0.9.8b and 0.9.8c [05 Sep 2006] - - *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher - (CVE-2006-4339) [Ben Laurie and Google Security Team] - - *) Add AES IGE and biIGE modes. - [Ben Laurie] - - *) Change the Unix randomness entropy gathering to use poll() when - possible instead of select(), since the latter has some - undesirable limitations. - [Darryl Miles via Richard Levitte and Bodo Moeller] - - *) Disable "ECCdraft" ciphersuites more thoroughly. Now special - treatment in ssl/ssl_ciph.s makes sure that these ciphersuites - cannot be implicitly activated as part of, e.g., the "AES" alias. - However, please upgrade to OpenSSL 0.9.9[-dev] for - non-experimental use of the ECC ciphersuites to get TLS extension - support, which is required for curve and point format negotiation - to avoid potential handshake problems. - [Bodo Moeller] - - *) Disable rogue ciphersuites: - - - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5") - - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5") - - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5") - - The latter two were purportedly from - draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really - appear there. - - Also deactivate the remaining ciphersuites from - draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as - unofficial, and the ID has long expired. - [Bodo Moeller] - - *) Fix RSA blinding Heisenbug (problems sometimes occurred on - dual-core machines) and other potential thread-safety issues. - [Bodo Moeller] - - *) Add the symmetric cipher Camellia (128-bit, 192-bit, 256-bit key - versions), which is now available for royalty-free use - (see http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html). - Also, add Camellia TLS ciphersuites from RFC 4132. - - To minimize changes between patchlevels in the OpenSSL 0.9.8 - series, Camellia remains excluded from compilation unless OpenSSL - is configured with 'enable-camellia'. - [NTT] - - *) Disable the padding bug check when compression is in use. The padding - bug check assumes the first packet is of even length, this is not - necessarily true if compression is enabled and can result in false - positives causing handshake failure. The actual bug test is ancient - code so it is hoped that implementations will either have fixed it by - now or any which still have the bug do not support compression. - [Steve Henson] - - Changes between 0.9.8a and 0.9.8b [04 May 2006] - - *) When applying a cipher rule check to see if string match is an explicit - cipher suite and only match that one cipher suite if it is. - [Steve Henson] - - *) Link in manifests for VC++ if needed. - [Austin Ziegler ] - - *) Update support for ECC-based TLS ciphersuites according to - draft-ietf-tls-ecc-12.txt with proposed changes (but without - TLS extensions, which are supported starting with the 0.9.9 - branch, not in the OpenSSL 0.9.8 branch). - [Douglas Stebila] - - *) New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free() to support - opaque EVP_CIPHER_CTX handling. - [Steve Henson] - - *) Fixes and enhancements to zlib compression code. We now only use - "zlib1.dll" and use the default __cdecl calling convention on Win32 - to conform with the standards mentioned here: - http://www.zlib.net/DLL_FAQ.txt - Static zlib linking now works on Windows and the new --with-zlib-include - --with-zlib-lib options to Configure can be used to supply the location - of the headers and library. Gracefully handle case where zlib library - can't be loaded. - [Steve Henson] - - *) Several fixes and enhancements to the OID generation code. The old code - sometimes allowed invalid OIDs (1.X for X >= 40 for example), couldn't - handle numbers larger than ULONG_MAX, truncated printing and had a - non standard OBJ_obj2txt() behaviour. - [Steve Henson] - - *) Add support for building of engines under engine/ as shared libraries - under VC++ build system. - [Steve Henson] - - *) Corrected the numerous bugs in the Win32 path splitter in DSO. - Hopefully, we will not see any false combination of paths any more. - [Richard Levitte] - - Changes between 0.9.8 and 0.9.8a [11 Oct 2005] - - *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING - (part of SSL_OP_ALL). This option used to disable the - countermeasure against man-in-the-middle protocol-version - rollback in the SSL 2.0 server implementation, which is a bad - idea. (CVE-2005-2969) - - [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center - for Information Security, National Institute of Advanced Industrial - Science and Technology [AIST], Japan)] - - *) Add two function to clear and return the verify parameter flags. - [Steve Henson] - - *) Keep cipherlists sorted in the source instead of sorting them at - runtime, thus removing the need for a lock. - [Nils Larsch] - - *) Avoid some small subgroup attacks in Diffie-Hellman. - [Nick Mathewson and Ben Laurie] - - *) Add functions for well-known primes. - [Nick Mathewson] - - *) Extended Windows CE support. - [Satoshi Nakamura and Andy Polyakov] - - *) Initialize SSL_METHOD structures at compile time instead of during - runtime, thus removing the need for a lock. - [Steve Henson] - - *) Make PKCS7_decrypt() work even if no certificate is supplied by - attempting to decrypt each encrypted key in turn. Add support to - smime utility. - [Steve Henson] - - Changes between 0.9.7h and 0.9.8 [05 Jul 2005] - - [NB: OpenSSL 0.9.7i and later 0.9.7 patch levels were released after - OpenSSL 0.9.8.] - - *) Add libcrypto.pc and libssl.pc for those who feel they need them. - [Richard Levitte] - - *) Change CA.sh and CA.pl so they don't bundle the CSR and the private - key into the same file any more. - [Richard Levitte] - - *) Add initial support for Win64, both IA64 and AMD64/x64 flavors. - [Andy Polyakov] - - *) Add -utf8 command line and config file option to 'ca'. - [Stefan and Geoff Thorpe] - - *) Add attribute functions to EVP_PKEY structure. Modify - PKCS12_create() to recognize a CSP name attribute and - use it. Make -CSP option work again in pkcs12 utility. - [Steve Henson] - - *) Add new functionality to the bn blinding code: - - automatic re-creation of the BN_BLINDING parameters after - a fixed number of uses (currently 32) - - add new function for parameter creation - - introduce flags to control the update behaviour of the - BN_BLINDING parameters - - hide BN_BLINDING structure - Add a second BN_BLINDING slot to the RSA structure to improve - performance when a single RSA object is shared among several - threads. - [Nils Larsch] - - *) Add support for DTLS. - [Nagendra Modadugu and Ben Laurie] - - *) Add support for DER encoded private keys (SSL_FILETYPE_ASN1) - to SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file() - [Walter Goulet] - - *) Remove buggy and incomplete DH cert support from - ssl/ssl_rsa.c and ssl/s3_both.c - [Nils Larsch] - - *) Use SHA-1 instead of MD5 as the default digest algorithm for - the apps/openssl applications. - [Nils Larsch] - - *) Compile clean with "-Wall -Wmissing-prototypes - -Wstrict-prototypes -Wmissing-declarations -Werror". Currently - DEBUG_SAFESTACK must also be set. - [Ben Laurie] - - *) Change ./Configure so that certain algorithms can be disabled by default. - The new counterpiece to "no-xxx" is "enable-xxx". - - The patented RC5 and MDC2 algorithms will now be disabled unless - "enable-rc5" and "enable-mdc2", respectively, are specified. - - (IDEA remains enabled despite being patented. This is because IDEA - is frequently required for interoperability, and there is no license - fee for non-commercial use. As before, "no-idea" can be used to - avoid this algorithm.) - - [Bodo Moeller] - - *) Add processing of proxy certificates (see RFC 3820). This work was - sponsored by KTH (The Royal Institute of Technology in Stockholm) and - EGEE (Enabling Grids for E-science in Europe). - [Richard Levitte] - - *) RC4 performance overhaul on modern architectures/implementations, such - as Intel P4, IA-64 and AMD64. - [Andy Polyakov] - - *) New utility extract-section.pl. This can be used specify an alternative - section number in a pod file instead of having to treat each file as - a separate case in Makefile. This can be done by adding two lines to the - pod file: - - =for comment openssl_section:XXX - - The blank line is mandatory. - - [Steve Henson] - - *) New arguments -certform, -keyform and -pass for s_client and s_server - to allow alternative format key and certificate files and passphrase - sources. - [Steve Henson] - - *) New structure X509_VERIFY_PARAM which combines current verify parameters, - update associated structures and add various utility functions. - - Add new policy related verify parameters, include policy checking in - standard verify code. Enhance 'smime' application with extra parameters - to support policy checking and print out. - [Steve Henson] - - *) Add a new engine to support VIA PadLock ACE extensions in the VIA C3 - Nehemiah processors. These extensions support AES encryption in hardware - as well as RNG (though RNG support is currently disabled). - [Michal Ludvig , with help from Andy Polyakov] - - *) Deprecate BN_[get|set]_params() functions (they were ignored internally). - [Geoff Thorpe] - - *) New FIPS 180-2 algorithms, SHA-224/-256/-384/-512 are implemented. - [Andy Polyakov and a number of other people] - - *) Improved PowerPC platform support. Most notably BIGNUM assembler - implementation contributed by IBM. - [Suresh Chari, Peter Waltenberg, Andy Polyakov] - - *) The new 'RSA_generate_key_ex' function now takes a BIGNUM for the public - exponent rather than 'unsigned long'. There is a corresponding change to - the new 'rsa_keygen' element of the RSA_METHOD structure. - [Jelte Jansen, Geoff Thorpe] - - *) Functionality for creating the initial serial number file is now - moved from CA.pl to the 'ca' utility with a new option -create_serial. - - (Before OpenSSL 0.9.7e, CA.pl used to initialize the serial - number file to 1, which is bound to cause problems. To avoid - the problems while respecting compatibility between different 0.9.7 - patchlevels, 0.9.7e employed 'openssl x509 -next_serial' in - CA.pl for serial number initialization. With the new release 0.9.8, - we can fix the problem directly in the 'ca' utility.) - [Steve Henson] - - *) Reduced header interdependencies by declaring more opaque objects in - ossl_typ.h. As a consequence, including some headers (eg. engine.h) will - give fewer recursive includes, which could break lazy source code - so - this change is covered by the OPENSSL_NO_DEPRECATED symbol. As always, - developers should define this symbol when building and using openssl to - ensure they track the recommended behaviour, interfaces, [etc], but - backwards-compatible behaviour prevails when this isn't defined. - [Geoff Thorpe] - - *) New function X509_POLICY_NODE_print() which prints out policy nodes. - [Steve Henson] - - *) Add new EVP function EVP_CIPHER_CTX_rand_key and associated functionality. - This will generate a random key of the appropriate length based on the - cipher context. The EVP_CIPHER can provide its own random key generation - routine to support keys of a specific form. This is used in the des and - 3des routines to generate a key of the correct parity. Update S/MIME - code to use new functions and hence generate correct parity DES keys. - Add EVP_CHECK_DES_KEY #define to return an error if the key is not - valid (weak or incorrect parity). - [Steve Henson] - - *) Add a local set of CRLs that can be used by X509_verify_cert() as well - as looking them up. This is useful when the verified structure may contain - CRLs, for example PKCS#7 signedData. Modify PKCS7_verify() to use any CRLs - present unless the new PKCS7_NO_CRL flag is asserted. - [Steve Henson] - - *) Extend ASN1 oid configuration module. It now additionally accepts the - syntax: - - shortName = some long name, 1.2.3.4 - [Steve Henson] - - *) Reimplemented the BN_CTX implementation. There is now no more static - limitation on the number of variables it can handle nor the depth of the - "stack" handling for BN_CTX_start()/BN_CTX_end() pairs. The stack - information can now expand as required, and rather than having a single - static array of bignums, BN_CTX now uses a linked-list of such arrays - allowing it to expand on demand whilst maintaining the usefulness of - BN_CTX's "bundling". - [Geoff Thorpe] - - *) Add a missing BN_CTX parameter to the 'rsa_mod_exp' callback in RSA_METHOD - to allow all RSA operations to function using a single BN_CTX. - [Geoff Thorpe] - - *) Preliminary support for certificate policy evaluation and checking. This - is initially intended to pass the tests outlined in "Conformance Testing - of Relying Party Client Certificate Path Processing Logic" v1.07. - [Steve Henson] - - *) bn_dup_expand() has been deprecated, it was introduced in 0.9.7 and - remained unused and not that useful. A variety of other little bignum - tweaks and fixes have also been made continuing on from the audit (see - below). - [Geoff Thorpe] - - *) Constify all or almost all d2i, c2i, s2i and r2i functions, along with - associated ASN1, EVP and SSL functions and old ASN1 macros. - [Richard Levitte] - - *) BN_zero() only needs to set 'top' and 'neg' to zero for correct results, - and this should never fail. So the return value from the use of - BN_set_word() (which can fail due to needless expansion) is now deprecated; - if OPENSSL_NO_DEPRECATED is defined, BN_zero() is a void macro. - [Geoff Thorpe] - - *) BN_CTX_get() should return zero-valued bignums, providing the same - initialised value as BN_new(). - [Geoff Thorpe, suggested by Ulf Möller] - - *) Support for inhibitAnyPolicy certificate extension. - [Steve Henson] - - *) An audit of the BIGNUM code is underway, for which debugging code is - enabled when BN_DEBUG is defined. This makes stricter enforcements on what - is considered valid when processing BIGNUMs, and causes execution to - assert() when a problem is discovered. If BN_DEBUG_RAND is defined, - further steps are taken to deliberately pollute unused data in BIGNUM - structures to try and expose faulty code further on. For now, openssl will - (in its default mode of operation) continue to tolerate the inconsistent - forms that it has tolerated in the past, but authors and packagers should - consider trying openssl and their own applications when compiled with - these debugging symbols defined. It will help highlight potential bugs in - their own code, and will improve the test coverage for OpenSSL itself. At - some point, these tighter rules will become openssl's default to improve - maintainability, though the assert()s and other overheads will remain only - in debugging configurations. See bn.h for more details. - [Geoff Thorpe, Nils Larsch, Ulf Möller] - - *) BN_CTX_init() has been deprecated, as BN_CTX is an opaque structure - that can only be obtained through BN_CTX_new() (which implicitly - initialises it). The presence of this function only made it possible - to overwrite an existing structure (and cause memory leaks). - [Geoff Thorpe] - - *) Because of the callback-based approach for implementing LHASH as a - template type, lh_insert() adds opaque objects to hash-tables and - lh_doall() or lh_doall_arg() are typically used with a destructor callback - to clean up those corresponding objects before destroying the hash table - (and losing the object pointers). So some over-zealous constifications in - LHASH have been relaxed so that lh_insert() does not take (nor store) the - objects as "const" and the lh_doall[_arg] callback wrappers are not - prototyped to have "const" restrictions on the object pointers they are - given (and so aren't required to cast them away any more). - [Geoff Thorpe] - - *) The tmdiff.h API was so ugly and minimal that our own timing utility - (speed) prefers to use its own implementation. The two implementations - haven't been consolidated as yet (volunteers?) but the tmdiff API has had - its object type properly exposed (MS_TM) instead of casting to/from "char - *". This may still change yet if someone realises MS_TM and "ms_time_***" - aren't necessarily the greatest nomenclatures - but this is what was used - internally to the implementation so I've used that for now. - [Geoff Thorpe] - - *) Ensure that deprecated functions do not get compiled when - OPENSSL_NO_DEPRECATED is defined. Some "openssl" subcommands and a few of - the self-tests were still using deprecated key-generation functions so - these have been updated also. - [Geoff Thorpe] - - *) Reorganise PKCS#7 code to separate the digest location functionality - into PKCS7_find_digest(), digest addition into PKCS7_bio_add_digest(). - New function PKCS7_set_digest() to set the digest type for PKCS#7 - digestedData type. Add additional code to correctly generate the - digestedData type and add support for this type in PKCS7 initialization - functions. - [Steve Henson] - - *) New function PKCS7_set0_type_other() this initializes a PKCS7 - structure of type "other". - [Steve Henson] - - *) Fix prime generation loop in crypto/bn/bn_prime.pl by making - sure the loop does correctly stop and breaking ("division by zero") - modulus operations are not performed. The (pre-generated) prime - table crypto/bn/bn_prime.h was already correct, but it could not be - re-generated on some platforms because of the "division by zero" - situation in the script. - [Ralf S. Engelschall] - - *) Update support for ECC-based TLS ciphersuites according to - draft-ietf-tls-ecc-03.txt: the KDF1 key derivation function with - SHA-1 now is only used for "small" curves (where the - representation of a field element takes up to 24 bytes); for - larger curves, the field element resulting from ECDH is directly - used as premaster secret. - [Douglas Stebila (Sun Microsystems Laboratories)] - - *) Add code for kP+lQ timings to crypto/ec/ectest.c, and add SEC2 - curve secp160r1 to the tests. - [Douglas Stebila (Sun Microsystems Laboratories)] - - *) Add the possibility to load symbols globally with DSO. - [Götz Babin-Ebell via Richard Levitte] - - *) Add the functions ERR_set_mark() and ERR_pop_to_mark() for better - control of the error stack. - [Richard Levitte] - - *) Add support for STORE in ENGINE. - [Richard Levitte] - - *) Add the STORE type. The intention is to provide a common interface - to certificate and key stores, be they simple file-based stores, or - HSM-type store, or LDAP stores, or... - NOTE: The code is currently UNTESTED and isn't really used anywhere. - [Richard Levitte] - - *) Add a generic structure called OPENSSL_ITEM. This can be used to - pass a list of arguments to any function as well as provide a way - for a function to pass data back to the caller. - [Richard Levitte] - - *) Add the functions BUF_strndup() and BUF_memdup(). BUF_strndup() - works like BUF_strdup() but can be used to duplicate a portion of - a string. The copy gets NUL-terminated. BUF_memdup() duplicates - a memory area. - [Richard Levitte] - - *) Add the function sk_find_ex() which works like sk_find(), but will - return an index to an element even if an exact match couldn't be - found. The index is guaranteed to point at the element where the - searched-for key would be inserted to preserve sorting order. - [Richard Levitte] - - *) Add the function OBJ_bsearch_ex() which works like OBJ_bsearch() but - takes an extra flags argument for optional functionality. Currently, - the following flags are defined: - - OBJ_BSEARCH_VALUE_ON_NOMATCH - This one gets OBJ_bsearch_ex() to return a pointer to the first - element where the comparing function returns a negative or zero - number. - - OBJ_BSEARCH_FIRST_VALUE_ON_MATCH - This one gets OBJ_bsearch_ex() to return a pointer to the first - element where the comparing function returns zero. This is useful - if there are more than one element where the comparing function - returns zero. - [Richard Levitte] - - *) Make it possible to create self-signed certificates with 'openssl ca' - in such a way that the self-signed certificate becomes part of the - CA database and uses the same mechanisms for serial number generation - as all other certificate signing. The new flag '-selfsign' enables - this functionality. Adapt CA.sh and CA.pl.in. - [Richard Levitte] - - *) Add functionality to check the public key of a certificate request - against a given private. This is useful to check that a certificate - request can be signed by that key (self-signing). - [Richard Levitte] - - *) Make it possible to have multiple active certificates with the same - subject in the CA index file. This is done only if the keyword - 'unique_subject' is set to 'no' in the main CA section (default - if 'CA_default') of the configuration file. The value is saved - with the database itself in a separate index attribute file, - named like the index file with '.attr' appended to the name. - [Richard Levitte] - - *) Generate multi-valued AVAs using '+' notation in config files for - req and dirName. - [Steve Henson] - - *) Support for nameConstraints certificate extension. - [Steve Henson] - - *) Support for policyConstraints certificate extension. - [Steve Henson] - - *) Support for policyMappings certificate extension. - [Steve Henson] - - *) Make sure the default DSA_METHOD implementation only uses its - dsa_mod_exp() and/or bn_mod_exp() handlers if they are non-NULL, - and change its own handlers to be NULL so as to remove unnecessary - indirection. This lets alternative implementations fallback to the - default implementation more easily. - [Geoff Thorpe] - - *) Support for directoryName in GeneralName related extensions - in config files. - [Steve Henson] - - *) Make it possible to link applications using Makefile.shared. - Make that possible even when linking against static libraries! - [Richard Levitte] - - *) Support for single pass processing for S/MIME signing. This now - means that S/MIME signing can be done from a pipe, in addition - cleartext signing (multipart/signed type) is effectively streaming - and the signed data does not need to be all held in memory. - - This is done with a new flag PKCS7_STREAM. When this flag is set - PKCS7_sign() only initializes the PKCS7 structure and the actual signing - is done after the data is output (and digests calculated) in - SMIME_write_PKCS7(). - [Steve Henson] - - *) Add full support for -rpath/-R, both in shared libraries and - applications, at least on the platforms where it's known how - to do it. - [Richard Levitte] - - *) In crypto/ec/ec_mult.c, implement fast point multiplication with - precomputation, based on wNAF splitting: EC_GROUP_precompute_mult() - will now compute a table of multiples of the generator that - makes subsequent invocations of EC_POINTs_mul() or EC_POINT_mul() - faster (notably in the case of a single point multiplication, - scalar * generator). - [Nils Larsch, Bodo Moeller] - - *) IPv6 support for certificate extensions. The various extensions - which use the IP:a.b.c.d can now take IPv6 addresses using the - formats of RFC1884 2.2 . IPv6 addresses are now also displayed - correctly. - [Steve Henson] - - *) Added an ENGINE that implements RSA by performing private key - exponentiations with the GMP library. The conversions to and from - GMP's mpz_t format aren't optimised nor are any montgomery forms - cached, and on x86 it appears OpenSSL's own performance has caught up. - However there are likely to be other architectures where GMP could - provide a boost. This ENGINE is not built in by default, but it can be - specified at Configure time and should be accompanied by the necessary - linker additions, eg; - ./config -DOPENSSL_USE_GMP -lgmp - [Geoff Thorpe] - - *) "openssl engine" will not display ENGINE/DSO load failure errors when - testing availability of engines with "-t" - the old behaviour is - produced by increasing the feature's verbosity with "-tt". - [Geoff Thorpe] - - *) ECDSA routines: under certain error conditions uninitialized BN objects - could be freed. Solution: make sure initialization is performed early - enough. (Reported and fix supplied by Nils Larsch - via PR#459) - [Lutz Jaenicke] - - *) Key-generation can now be implemented in RSA_METHOD, DSA_METHOD - and DH_METHOD (eg. by ENGINE implementations) to override the normal - software implementations. For DSA and DH, parameter generation can - also be overridden by providing the appropriate method callbacks. - [Geoff Thorpe] - - *) Change the "progress" mechanism used in key-generation and - primality testing to functions that take a new BN_GENCB pointer in - place of callback/argument pairs. The new API functions have "_ex" - postfixes and the older functions are reimplemented as wrappers for - the new ones. The OPENSSL_NO_DEPRECATED symbol can be used to hide - declarations of the old functions to help (graceful) attempts to - migrate to the new functions. Also, the new key-generation API - functions operate on a caller-supplied key-structure and return - success/failure rather than returning a key or NULL - this is to - help make "keygen" another member function of RSA_METHOD etc. - - Example for using the new callback interface: - - int (*my_callback)(int a, int b, BN_GENCB *cb) = ...; - void *my_arg = ...; - BN_GENCB my_cb; - - BN_GENCB_set(&my_cb, my_callback, my_arg); - - return BN_is_prime_ex(some_bignum, BN_prime_checks, NULL, &cb); - /* For the meaning of a, b in calls to my_callback(), see the - * documentation of the function that calls the callback. - * cb will point to my_cb; my_arg can be retrieved as cb->arg. - * my_callback should return 1 if it wants BN_is_prime_ex() - * to continue, or 0 to stop. - */ - - [Geoff Thorpe] - - *) Change the ZLIB compression method to be stateful, and make it - available to TLS with the number defined in - draft-ietf-tls-compression-04.txt. - [Richard Levitte] - - *) Add the ASN.1 structures and functions for CertificatePair, which - is defined as follows (according to X.509_4thEditionDraftV6.pdf): - - CertificatePair ::= SEQUENCE { - forward [0] Certificate OPTIONAL, - reverse [1] Certificate OPTIONAL, - -- at least one of the pair shall be present -- } - - Also implement the PEM functions to read and write certificate - pairs, and defined the PEM tag as "CERTIFICATE PAIR". - - This needed to be defined, mostly for the sake of the LDAP - attribute crossCertificatePair, but may prove useful elsewhere as - well. - [Richard Levitte] - - *) Make it possible to inhibit symlinking of shared libraries in - Makefile.shared, for Cygwin's sake. - [Richard Levitte] - - *) Extend the BIGNUM API by creating a function - void BN_set_negative(BIGNUM *a, int neg); - and a macro that behave like - int BN_is_negative(const BIGNUM *a); - - to avoid the need to access 'a->neg' directly in applications. - [Nils Larsch] - - *) Implement fast modular reduction for pseudo-Mersenne primes - used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c). - EC_GROUP_new_curve_GFp() will now automatically use this - if applicable. - [Nils Larsch ] - - *) Add new lock type (CRYPTO_LOCK_BN). - [Bodo Moeller] - - *) Change the ENGINE framework to automatically load engines - dynamically from specific directories unless they could be - found to already be built in or loaded. Move all the - current engines except for the cryptodev one to a new - directory engines/. - The engines in engines/ are built as shared libraries if - the "shared" options was given to ./Configure or ./config. - Otherwise, they are inserted in libcrypto.a. - /usr/local/ssl/engines is the default directory for dynamic - engines, but that can be overridden at configure time through - the usual use of --prefix and/or --openssldir, and at run - time with the environment variable OPENSSL_ENGINES. - [Geoff Thorpe and Richard Levitte] - - *) Add Makefile.shared, a helper makefile to build shared - libraries. Adapt Makefile.org. - [Richard Levitte] - - *) Add version info to Win32 DLLs. - [Peter 'Luna' Runestig" ] - - *) Add new 'medium level' PKCS#12 API. Certificates and keys - can be added using this API to created arbitrary PKCS#12 - files while avoiding the low level API. - - New options to PKCS12_create(), key or cert can be NULL and - will then be omitted from the output file. The encryption - algorithm NIDs can be set to -1 for no encryption, the mac - iteration count can be set to 0 to omit the mac. - - Enhance pkcs12 utility by making the -nokeys and -nocerts - options work when creating a PKCS#12 file. New option -nomac - to omit the mac, NONE can be set for an encryption algorithm. - New code is modified to use the enhanced PKCS12_create() - instead of the low level API. - [Steve Henson] - - *) Extend ASN1 encoder to support indefinite length constructed - encoding. This can output sequences tags and octet strings in - this form. Modify pk7_asn1.c to support indefinite length - encoding. This is experimental and needs additional code to - be useful, such as an ASN1 bio and some enhanced streaming - PKCS#7 code. - - Extend template encode functionality so that tagging is passed - down to the template encoder. - [Steve Henson] - - *) Let 'openssl req' fail if an argument to '-newkey' is not - recognized instead of using RSA as a default. - [Bodo Moeller] - - *) Add support for ECC-based ciphersuites from draft-ietf-tls-ecc-01.txt. - As these are not official, they are not included in "ALL"; - the "ECCdraft" ciphersuite group alias can be used to select them. - [Vipul Gupta and Sumit Gupta (Sun Microsystems Laboratories)] - - *) Add ECDH engine support. - [Nils Gura and Douglas Stebila (Sun Microsystems Laboratories)] - - *) Add ECDH in new directory crypto/ecdh/. - [Douglas Stebila (Sun Microsystems Laboratories)] - - *) Let BN_rand_range() abort with an error after 100 iterations - without success (which indicates a broken PRNG). - [Bodo Moeller] - - *) Change BN_mod_sqrt() so that it verifies that the input value - is really the square of the return value. (Previously, - BN_mod_sqrt would show GIGO behaviour.) - [Bodo Moeller] - - *) Add named elliptic curves over binary fields from X9.62, SECG, - and WAP/WTLS; add OIDs that were still missing. - - [Sheueling Chang Shantz and Douglas Stebila - (Sun Microsystems Laboratories)] - - *) Extend the EC library for elliptic curves over binary fields - (new files ec2_smpl.c, ec2_smpt.c, ec2_mult.c in crypto/ec/). - New EC_METHOD: - - EC_GF2m_simple_method - - New API functions: - - EC_GROUP_new_curve_GF2m - EC_GROUP_set_curve_GF2m - EC_GROUP_get_curve_GF2m - EC_POINT_set_affine_coordinates_GF2m - EC_POINT_get_affine_coordinates_GF2m - EC_POINT_set_compressed_coordinates_GF2m - - Point compression for binary fields is disabled by default for - patent reasons (compile with OPENSSL_EC_BIN_PT_COMP defined to - enable it). - - As binary polynomials are represented as BIGNUMs, various members - of the EC_GROUP and EC_POINT data structures can be shared - between the implementations for prime fields and binary fields; - the above ..._GF2m functions (except for EX_GROUP_new_curve_GF2m) - are essentially identical to their ..._GFp counterparts. - (For simplicity, the '..._GFp' prefix has been dropped from - various internal method names.) - - An internal 'field_div' method (similar to 'field_mul' and - 'field_sqr') has been added; this is used only for binary fields. - - [Sheueling Chang Shantz and Douglas Stebila - (Sun Microsystems Laboratories)] - - *) Optionally dispatch EC_POINT_mul(), EC_POINT_precompute_mult() - through methods ('mul', 'precompute_mult'). - - The generic implementations (now internally called 'ec_wNAF_mul' - and 'ec_wNAF_precomputed_mult') remain the default if these - methods are undefined. - - [Sheueling Chang Shantz and Douglas Stebila - (Sun Microsystems Laboratories)] - - *) New function EC_GROUP_get_degree, which is defined through - EC_METHOD. For curves over prime fields, this returns the bit - length of the modulus. - - [Sheueling Chang Shantz and Douglas Stebila - (Sun Microsystems Laboratories)] - - *) New functions EC_GROUP_dup, EC_POINT_dup. - (These simply call ..._new and ..._copy). - - [Sheueling Chang Shantz and Douglas Stebila - (Sun Microsystems Laboratories)] - - *) Add binary polynomial arithmetic software in crypto/bn/bn_gf2m.c. - Polynomials are represented as BIGNUMs (where the sign bit is not - used) in the following functions [macros]: - - BN_GF2m_add - BN_GF2m_sub [= BN_GF2m_add] - BN_GF2m_mod [wrapper for BN_GF2m_mod_arr] - BN_GF2m_mod_mul [wrapper for BN_GF2m_mod_mul_arr] - BN_GF2m_mod_sqr [wrapper for BN_GF2m_mod_sqr_arr] - BN_GF2m_mod_inv - BN_GF2m_mod_exp [wrapper for BN_GF2m_mod_exp_arr] - BN_GF2m_mod_sqrt [wrapper for BN_GF2m_mod_sqrt_arr] - BN_GF2m_mod_solve_quad [wrapper for BN_GF2m_mod_solve_quad_arr] - BN_GF2m_cmp [= BN_ucmp] - - (Note that only the 'mod' functions are actually for fields GF(2^m). - BN_GF2m_add() is misnomer, but this is for the sake of consistency.) - - For some functions, an the irreducible polynomial defining a - field can be given as an 'unsigned int[]' with strictly - decreasing elements giving the indices of those bits that are set; - i.e., p[] represents the polynomial - f(t) = t^p[0] + t^p[1] + ... + t^p[k] - where - p[0] > p[1] > ... > p[k] = 0. - This applies to the following functions: - - BN_GF2m_mod_arr - BN_GF2m_mod_mul_arr - BN_GF2m_mod_sqr_arr - BN_GF2m_mod_inv_arr [wrapper for BN_GF2m_mod_inv] - BN_GF2m_mod_div_arr [wrapper for BN_GF2m_mod_div] - BN_GF2m_mod_exp_arr - BN_GF2m_mod_sqrt_arr - BN_GF2m_mod_solve_quad_arr - BN_GF2m_poly2arr - BN_GF2m_arr2poly - - Conversion can be performed by the following functions: - - BN_GF2m_poly2arr - BN_GF2m_arr2poly - - bntest.c has additional tests for binary polynomial arithmetic. - - Two implementations for BN_GF2m_mod_div() are available. - The default algorithm simply uses BN_GF2m_mod_inv() and - BN_GF2m_mod_mul(). The alternative algorithm is compiled in only - if OPENSSL_SUN_GF2M_DIV is defined (patent pending; read the - copyright notice in crypto/bn/bn_gf2m.c before enabling it). - - [Sheueling Chang Shantz and Douglas Stebila - (Sun Microsystems Laboratories)] - - *) Add new error code 'ERR_R_DISABLED' that can be used when some - functionality is disabled at compile-time. - [Douglas Stebila ] - - *) Change default behaviour of 'openssl asn1parse' so that more - information is visible when viewing, e.g., a certificate: - - Modify asn1_parse2 (crypto/asn1/asn1_par.c) so that in non-'dump' - mode the content of non-printable OCTET STRINGs is output in a - style similar to INTEGERs, but with '[HEX DUMP]' prepended to - avoid the appearance of a printable string. - [Nils Larsch ] - - *) Add 'asn1_flag' and 'asn1_form' member to EC_GROUP with access - functions - EC_GROUP_set_asn1_flag() - EC_GROUP_get_asn1_flag() - EC_GROUP_set_point_conversion_form() - EC_GROUP_get_point_conversion_form() - These control ASN1 encoding details: - - Curves (i.e., groups) are encoded explicitly unless asn1_flag - has been set to OPENSSL_EC_NAMED_CURVE. - - Points are encoded in uncompressed form by default; options for - asn1_for are as for point2oct, namely - POINT_CONVERSION_COMPRESSED - POINT_CONVERSION_UNCOMPRESSED - POINT_CONVERSION_HYBRID - - Also add 'seed' and 'seed_len' members to EC_GROUP with access - functions - EC_GROUP_set_seed() - EC_GROUP_get0_seed() - EC_GROUP_get_seed_len() - This is used only for ASN1 purposes (so far). - [Nils Larsch ] - - *) Add 'field_type' member to EC_METHOD, which holds the NID - of the appropriate field type OID. The new function - EC_METHOD_get_field_type() returns this value. - [Nils Larsch ] - - *) Add functions - EC_POINT_point2bn() - EC_POINT_bn2point() - EC_POINT_point2hex() - EC_POINT_hex2point() - providing useful interfaces to EC_POINT_point2oct() and - EC_POINT_oct2point(). - [Nils Larsch ] - - *) Change internals of the EC library so that the functions - EC_GROUP_set_generator() - EC_GROUP_get_generator() - EC_GROUP_get_order() - EC_GROUP_get_cofactor() - are implemented directly in crypto/ec/ec_lib.c and not dispatched - to methods, which would lead to unnecessary code duplication when - adding different types of curves. - [Nils Larsch with input by Bodo Moeller] - - *) Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM - arithmetic, and such that modified wNAFs are generated - (which avoid length expansion in many cases). - [Bodo Moeller] - - *) Add a function EC_GROUP_check_discriminant() (defined via - EC_METHOD) that verifies that the curve discriminant is non-zero. - - Add a function EC_GROUP_check() that makes some sanity tests - on a EC_GROUP, its generator and order. This includes - EC_GROUP_check_discriminant(). - [Nils Larsch ] - - *) Add ECDSA in new directory crypto/ecdsa/. - - Add applications 'openssl ecparam' and 'openssl ecdsa' - (these are based on 'openssl dsaparam' and 'openssl dsa'). - - ECDSA support is also included in various other files across the - library. Most notably, - - 'openssl req' now has a '-newkey ecdsa:file' option; - - EVP_PKCS82PKEY (crypto/evp/evp_pkey.c) now can handle ECDSA; - - X509_PUBKEY_get (crypto/asn1/x_pubkey.c) and - d2i_PublicKey (crypto/asn1/d2i_pu.c) have been modified to make - them suitable for ECDSA where domain parameters must be - extracted before the specific public key; - - ECDSA engine support has been added. - [Nils Larsch ] - - *) Include some named elliptic curves, and add OIDs from X9.62, - SECG, and WAP/WTLS. Each curve can be obtained from the new - function - EC_GROUP_new_by_curve_name(), - and the list of available named curves can be obtained with - EC_get_builtin_curves(). - Also add a 'curve_name' member to EC_GROUP objects, which can be - accessed via - EC_GROUP_set_curve_name() - EC_GROUP_get_curve_name() - [Nils Larsch ] - - *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that - a ciphersuite string such as "DEFAULT:RSA" cannot enable - authentication-only ciphersuites. - [Bodo Moeller] - - *) Since AES128 and AES256 share a single mask bit in the logic of - ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a - kludge to work properly if AES128 is available and AES256 isn't. - [Victor Duchovni] - - *) Expand security boundary to match 1.1.1 module. - [Steve Henson] - - *) Remove redundant features: hash file source, editing of test vectors - modify fipsld to use external fips_premain.c signature. - [Steve Henson] - - *) New perl script mkfipsscr.pl to create shell scripts or batch files to - run algorithm test programs. - [Steve Henson] - - *) Make algorithm test programs more tolerant of whitespace. - [Steve Henson] - - *) Have SSL/TLS server implementation tolerate "mismatched" record - protocol version while receiving ClientHello even if the - ClientHello is fragmented. (The server can't insist on the - particular protocol version it has chosen before the ServerHello - message has informed the client about his choice.) - [Bodo Moeller] - - *) Load error codes if they are not already present instead of using a - static variable. This allows them to be cleanly unloaded and reloaded. - [Steve Henson] - - Changes between 0.9.7k and 0.9.7l [28 Sep 2006] - - *) Introduce limits to prevent malicious keys being able to - cause a denial of service. (CVE-2006-2940) - [Steve Henson, Bodo Moeller] - - *) Fix ASN.1 parsing of certain invalid structures that can result - in a denial of service. (CVE-2006-2937) [Steve Henson] - - *) Fix buffer overflow in SSL_get_shared_ciphers() function. - (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team] - - *) Fix SSL client code which could crash if connecting to a - malicious SSLv2 server. (CVE-2006-4343) - [Tavis Ormandy and Will Drewry, Google Security Team] - - *) Change ciphersuite string processing so that an explicit - ciphersuite selects this one ciphersuite (so that "AES256-SHA" - will no longer include "AES128-SHA"), and any other similar - ciphersuite (same bitmap) from *other* protocol versions (so that - "RC4-MD5" will still include both the SSL 2.0 ciphersuite and the - SSL 3.0/TLS 1.0 ciphersuite). This is a backport combining - changes from 0.9.8b and 0.9.8d. - [Bodo Moeller] - - Changes between 0.9.7j and 0.9.7k [05 Sep 2006] - - *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher - (CVE-2006-4339) [Ben Laurie and Google Security Team] - - *) Change the Unix randomness entropy gathering to use poll() when - possible instead of select(), since the latter has some - undesirable limitations. - [Darryl Miles via Richard Levitte and Bodo Moeller] - - *) Disable rogue ciphersuites: - - - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5") - - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5") - - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5") - - The latter two were purportedly from - draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really - appear there. - - Also deactivate the remaining ciphersuites from - draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as - unofficial, and the ID has long expired. - [Bodo Moeller] - - *) Fix RSA blinding Heisenbug (problems sometimes occurred on - dual-core machines) and other potential thread-safety issues. - [Bodo Moeller] - - Changes between 0.9.7i and 0.9.7j [04 May 2006] - - *) Adapt fipsld and the build system to link against the validated FIPS - module in FIPS mode. - [Steve Henson] - - *) Fixes for VC++ 2005 build under Windows. - [Steve Henson] - - *) Add new Windows build target VC-32-GMAKE for VC++. This uses GNU make - from a Windows bash shell such as MSYS. It is autodetected from the - "config" script when run from a VC++ environment. Modify standard VC++ - build to use fipscanister.o from the GNU make build. - [Steve Henson] - - Changes between 0.9.7h and 0.9.7i [14 Oct 2005] - - *) Wrapped the definition of EVP_MAX_MD_SIZE in a #ifdef OPENSSL_FIPS. - The value now differs depending on if you build for FIPS or not. - BEWARE! A program linked with a shared FIPSed libcrypto can't be - safely run with a non-FIPSed libcrypto, as it may crash because of - the difference induced by this change. - [Andy Polyakov] - - Changes between 0.9.7g and 0.9.7h [11 Oct 2005] - - *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING - (part of SSL_OP_ALL). This option used to disable the - countermeasure against man-in-the-middle protocol-version - rollback in the SSL 2.0 server implementation, which is a bad - idea. (CVE-2005-2969) - - [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center - for Information Security, National Institute of Advanced Industrial - Science and Technology [AIST], Japan)] - - *) Minimal support for X9.31 signatures and PSS padding modes. This is - mainly for FIPS compliance and not fully integrated at this stage. - [Steve Henson] - - *) For DSA signing, unless DSA_FLAG_NO_EXP_CONSTTIME is set, perform - the exponentiation using a fixed-length exponent. (Otherwise, - the information leaked through timing could expose the secret key - after many signatures; cf. Bleichenbacher's attack on DSA with - biased k.) - [Bodo Moeller] - - *) Make a new fixed-window mod_exp implementation the default for - RSA, DSA, and DH private-key operations so that the sequence of - squares and multiplies and the memory access pattern are - independent of the particular secret key. This will mitigate - cache-timing and potential related attacks. - - BN_mod_exp_mont_consttime() is the new exponentiation implementation, - and this is automatically used by BN_mod_exp_mont() if the new flag - BN_FLG_EXP_CONSTTIME is set for the exponent. RSA, DSA, and DH - will use this BN flag for private exponents unless the flag - RSA_FLAG_NO_EXP_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME, or - DH_FLAG_NO_EXP_CONSTTIME, respectively, is set. - - [Matthew D Wood (Intel Corp), with some changes by Bodo Moeller] - - *) Change the client implementation for SSLv23_method() and - SSLv23_client_method() so that is uses the SSL 3.0/TLS 1.0 - Client Hello message format if the SSL_OP_NO_SSLv2 option is set. - (Previously, the SSL 2.0 backwards compatible Client Hello - message format would be used even with SSL_OP_NO_SSLv2.) - [Bodo Moeller] - - *) Add support for smime-type MIME parameter in S/MIME messages which some - clients need. - [Steve Henson] - - *) New function BN_MONT_CTX_set_locked() to set montgomery parameters in - a threadsafe manner. Modify rsa code to use new function and add calls - to dsa and dh code (which had race conditions before). - [Steve Henson] - - *) Include the fixed error library code in the C error file definitions - instead of fixing them up at runtime. This keeps the error code - structures constant. - [Steve Henson] - - Changes between 0.9.7f and 0.9.7g [11 Apr 2005] - - [NB: OpenSSL 0.9.7h and later 0.9.7 patch levels were released after - OpenSSL 0.9.8.] - - *) Fixes for newer kerberos headers. NB: the casts are needed because - the 'length' field is signed on one version and unsigned on another - with no (?) obvious way to tell the difference, without these VC++ - complains. Also the "definition" of FAR (blank) is no longer included - nor is the error ENOMEM. KRB5_PRIVATE has to be set to 1 to pick up - some needed definitions. - [Steve Henson] - - *) Undo Cygwin change. - [Ulf Möller] - - *) Added support for proxy certificates according to RFC 3820. - Because they may be a security thread to unaware applications, - they must be explicitly allowed in run-time. See - docs/HOWTO/proxy_certificates.txt for further information. - [Richard Levitte] - - Changes between 0.9.7e and 0.9.7f [22 Mar 2005] - - *) Use (SSL_RANDOM_VALUE - 4) bytes of pseudo random data when generating - server and client random values. Previously - (SSL_RANDOM_VALUE - sizeof(time_t)) would be used which would result in - less random data when sizeof(time_t) > 4 (some 64 bit platforms). - - This change has negligible security impact because: - - 1. Server and client random values still have 24 bytes of pseudo random - data. - - 2. Server and client random values are sent in the clear in the initial - handshake. - - 3. The master secret is derived using the premaster secret (48 bytes in - size for static RSA ciphersuites) as well as client server and random - values. - - The OpenSSL team would like to thank the UK NISCC for bringing this issue - to our attention. - - [Stephen Henson, reported by UK NISCC] - - *) Use Windows randomness collection on Cygwin. - [Ulf Möller] - - *) Fix hang in EGD/PRNGD query when communication socket is closed - prematurely by EGD/PRNGD. - [Darren Tucker via Lutz Jänicke, resolves #1014] - - *) Prompt for pass phrases when appropriate for PKCS12 input format. - [Steve Henson] - - *) Back-port of selected performance improvements from development - branch, as well as improved support for PowerPC platforms. - [Andy Polyakov] - - *) Add lots of checks for memory allocation failure, error codes to indicate - failure and freeing up memory if a failure occurs. - [Nauticus Networks SSL Team , Steve Henson] - - *) Add new -passin argument to dgst. - [Steve Henson] - - *) Perform some character comparisons of different types in X509_NAME_cmp: - this is needed for some certificates that re-encode DNs into UTF8Strings - (in violation of RFC3280) and can't or won't issue name rollover - certificates. - [Steve Henson] - - *) Make an explicit check during certificate validation to see that - the CA setting in each certificate on the chain is correct. As a - side effect always do the following basic checks on extensions, - not just when there's an associated purpose to the check: - - - if there is an unhandled critical extension (unless the user - has chosen to ignore this fault) - - if the path length has been exceeded (if one is set at all) - - that certain extensions fit the associated purpose (if one has - been given) - [Richard Levitte] - - Changes between 0.9.7d and 0.9.7e [25 Oct 2004] - - *) Avoid a race condition when CRLs are checked in a multi threaded - environment. This would happen due to the reordering of the revoked - entries during signature checking and serial number lookup. Now the - encoding is cached and the serial number sort performed under a lock. - Add new STACK function sk_is_sorted(). - [Steve Henson] - - *) Add Delta CRL to the extension code. - [Steve Henson] - - *) Various fixes to s3_pkt.c so alerts are sent properly. - [David Holmes ] - - *) Reduce the chances of duplicate issuer name and serial numbers (in - violation of RFC3280) using the OpenSSL certificate creation utilities. - This is done by creating a random 64 bit value for the initial serial - number when a serial number file is created or when a self signed - certificate is created using 'openssl req -x509'. The initial serial - number file is created using 'openssl x509 -next_serial' in CA.pl - rather than being initialized to 1. - [Steve Henson] - - Changes between 0.9.7c and 0.9.7d [17 Mar 2004] - - *) Fix null-pointer assignment in do_change_cipher_spec() revealed - by using the Codenomicon TLS Test Tool (CVE-2004-0079) - [Joe Orton, Steve Henson] - - *) Fix flaw in SSL/TLS handshaking when using Kerberos ciphersuites - (CVE-2004-0112) - [Joe Orton, Steve Henson] - - *) Make it possible to have multiple active certificates with the same - subject in the CA index file. This is done only if the keyword - 'unique_subject' is set to 'no' in the main CA section (default - if 'CA_default') of the configuration file. The value is saved - with the database itself in a separate index attribute file, - named like the index file with '.attr' appended to the name. - [Richard Levitte] - - *) X509 verify fixes. Disable broken certificate workarounds when - X509_V_FLAGS_X509_STRICT is set. Check CRL issuer has cRLSign set if - keyUsage extension present. Don't accept CRLs with unhandled critical - extensions: since verify currently doesn't process CRL extensions this - rejects a CRL with *any* critical extensions. Add new verify error codes - for these cases. - [Steve Henson] - - *) When creating an OCSP nonce use an OCTET STRING inside the extnValue. - A clarification of RFC2560 will require the use of OCTET STRINGs and - some implementations cannot handle the current raw format. Since OpenSSL - copies and compares OCSP nonces as opaque blobs without any attempt at - parsing them this should not create any compatibility issues. - [Steve Henson] - - *) New md flag EVP_MD_CTX_FLAG_REUSE this allows md_data to be reused when - calling EVP_MD_CTX_copy_ex() to avoid calling OPENSSL_malloc(). Without - this HMAC (and other) operations are several times slower than OpenSSL - < 0.9.7. - [Steve Henson] - - *) Print out GeneralizedTime and UTCTime in ASN1_STRING_print_ex(). - [Peter Sylvester ] - - *) Use the correct content when signing type "other". - [Steve Henson] - - Changes between 0.9.7b and 0.9.7c [30 Sep 2003] - - *) Fix various bugs revealed by running the NISCC test suite: - - Stop out of bounds reads in the ASN1 code when presented with - invalid tags (CVE-2003-0543 and CVE-2003-0544). - - Free up ASN1_TYPE correctly if ANY type is invalid (CVE-2003-0545). - - If verify callback ignores invalid public key errors don't try to check - certificate signature with the NULL public key. - - [Steve Henson] - - *) New -ignore_err option in ocsp application to stop the server - exiting on the first error in a request. - [Steve Henson] - - *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate - if the server requested one: as stated in TLS 1.0 and SSL 3.0 - specifications. - [Steve Henson] - - *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional - extra data after the compression methods not only for TLS 1.0 - but also for SSL 3.0 (as required by the specification). - [Bodo Moeller; problem pointed out by Matthias Loepfe] - - *) Change X509_certificate_type() to mark the key as exported/exportable - when it's 512 *bits* long, not 512 bytes. - [Richard Levitte] - - *) Change AES_cbc_encrypt() so it outputs exact multiple of - blocks during encryption. - [Richard Levitte] - - *) Various fixes to base64 BIO and non blocking I/O. On write - flushes were not handled properly if the BIO retried. On read - data was not being buffered properly and had various logic bugs. - This also affects blocking I/O when the data being decoded is a - certain size. - [Steve Henson] - - *) Various S/MIME bugfixes and compatibility changes: - output correct application/pkcs7 MIME type if - PKCS7_NOOLDMIMETYPE is set. Tolerate some broken signatures. - Output CR+LF for EOL if PKCS7_CRLFEOL is set (this makes opening - of files as .eml work). Correctly handle very long lines in MIME - parser. - [Steve Henson] - - Changes between 0.9.7a and 0.9.7b [10 Apr 2003] - - *) Countermeasure against the Klima-Pokorny-Rosa extension of - Bleichbacher's attack on PKCS #1 v1.5 padding: treat - a protocol version number mismatch like a decryption error - in ssl3_get_client_key_exchange (ssl/s3_srvr.c). - [Bodo Moeller] - - *) Turn on RSA blinding by default in the default implementation - to avoid a timing attack. Applications that don't want it can call - RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING. - They would be ill-advised to do so in most cases. - [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller] - - *) Change RSA blinding code so that it works when the PRNG is not - seeded (in this case, the secret RSA exponent is abused as - an unpredictable seed -- if it is not unpredictable, there - is no point in blinding anyway). Make RSA blinding thread-safe - by remembering the creator's thread ID in rsa->blinding and - having all other threads use local one-time blinding factors - (this requires more computation than sharing rsa->blinding, but - avoids excessive locking; and if an RSA object is not shared - between threads, blinding will still be very fast). - [Bodo Moeller] - - *) Fixed a typo bug that would cause ENGINE_set_default() to set an - ENGINE as defaults for all supported algorithms irrespective of - the 'flags' parameter. 'flags' is now honoured, so applications - should make sure they are passing it correctly. - [Geoff Thorpe] - - *) Target "mingw" now allows native Windows code to be generated in - the Cygwin environment as well as with the MinGW compiler. - [Ulf Moeller] - - Changes between 0.9.7 and 0.9.7a [19 Feb 2003] - - *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked - via timing by performing a MAC computation even if incorrect - block cipher padding has been found. This is a countermeasure - against active attacks where the attacker has to distinguish - between bad padding and a MAC verification error. (CVE-2003-0078) - - [Bodo Moeller; problem pointed out by Brice Canvel (EPFL), - Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and - Martin Vuagnoux (EPFL, Ilion)] - - *) Make the no-err option work as intended. The intention with no-err - is not to have the whole error stack handling routines removed from - libcrypto, it's only intended to remove all the function name and - 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 its - own set of error texts inserted. The routines are there, just not - used by default when no-err is given. - [Richard Levitte] - - *) Add support for FreeBSD on IA64. - [dirk.meyer@dinoex.sub.org via Richard Levitte, resolves #454] - - *) Adjust DES_cbc_cksum() so it returns the same value as the MIT - Kerberos function mit_des_cbc_cksum(). Before this change, - the value returned by DES_cbc_cksum() was like the one from - mit_des_cbc_cksum(), except the bytes were swapped. - [Kevin Greaney and Richard Levitte] - - *) Allow an application to disable the automatic SSL chain building. - Before this a rather primitive chain build was always performed in - ssl3_output_cert_chain(): an application had no way to send the - correct chain if the automatic operation produced an incorrect result. - - Now the chain builder is disabled if either: - - 1. Extra certificates are added via SSL_CTX_add_extra_chain_cert(). - - 2. The mode flag SSL_MODE_NO_AUTO_CHAIN is set. - - The reasoning behind this is that an application would not want the - auto chain building to take place if extra chain certificates are - present and it might also want a means of sending no additional - certificates (for example the chain has two certificates and the - root is omitted). - [Steve Henson] - - *) Add the possibility to build without the ENGINE framework. - [Steven Reddie via Richard Levitte] - - *) Under Win32 gmtime() can return NULL: check return value in - OPENSSL_gmtime(). Add error code for case where gmtime() fails. - [Steve Henson] - - *) DSA routines: under certain error conditions uninitialized BN objects - could be freed. Solution: make sure initialization is performed early - enough. (Reported and fix supplied by Ivan D Nestlerode , - Nils Larsch via PR#459) - [Lutz Jaenicke] - - *) Another fix for SSLv2 session ID handling: the session ID was incorrectly - checked on reconnect on the client side, therefore session resumption - could still fail with a "ssl session id is different" error. This - behaviour is masked when SSL_OP_ALL is used due to - SSL_OP_MICROSOFT_SESS_ID_BUG being set. - Behaviour observed by Crispin Flowerday as - followup to PR #377. - [Lutz Jaenicke] - - *) IA-32 assembler support enhancements: unified ELF targets, support - for SCO/Caldera platforms, fix for Cygwin shared build. - [Andy Polyakov] - - *) Add support for FreeBSD on sparc64. As a consequence, support for - FreeBSD on non-x86 processors is separate from x86 processors on - the config script, much like the NetBSD support. - [Richard Levitte & Kris Kennaway ] - - Changes between 0.9.6h and 0.9.7 [31 Dec 2002] - - [NB: OpenSSL 0.9.6i and later 0.9.6 patch levels were released after - OpenSSL 0.9.7.] - - *) Fix session ID handling in SSLv2 client code: the SERVER FINISHED - code (06) was taken as the first octet of the session ID and the last - octet was ignored consequently. As a result SSLv2 client side session - caching could not have worked due to the session ID mismatch between - client and server. - Behaviour observed by Crispin Flowerday as - PR #377. - [Lutz Jaenicke] - - *) Change the declaration of needed Kerberos libraries to use EX_LIBS - instead of the special (and badly supported) LIBKRB5. LIBKRB5 is - removed entirely. - [Richard Levitte] - - *) The hw_ncipher.c engine requires dynamic locks. Unfortunately, it - seems that in spite of existing for more than a year, many application - author have done nothing to provide the necessary callbacks, which - means that this particular engine will not work properly anywhere. - This is a very unfortunate situation which forces us, in the name - of usability, to give the hw_ncipher.c a static lock, which is part - of libcrypto. - NOTE: This is for the 0.9.7 series ONLY. This hack will never - appear in 0.9.8 or later. We EXPECT application authors to have - dealt properly with this when 0.9.8 is released (unless we actually - make such changes in the libcrypto locking code that changes will - have to be made anyway). - [Richard Levitte] - - *) In asn1_d2i_read_bio() repeatedly call BIO_read() until all content - octets have been read, EOF or an error occurs. Without this change - some truncated ASN1 structures will not produce an error. - [Steve Henson] - - *) Disable Heimdal support, since it hasn't been fully implemented. - Still give the possibility to force the use of Heimdal, but with - warnings and a request that patches get sent to openssl-dev. - [Richard Levitte] - - *) Add the VC-CE target, introduce the WINCE sysname, and add - INSTALL.WCE and appropriate conditionals to make it build. - [Steven Reddie via Richard Levitte] - - *) Change the DLL names for Cygwin to cygcrypto-x.y.z.dll and - cygssl-x.y.z.dll, where x, y and z are the major, minor and - edit numbers of the version. - [Corinna Vinschen and Richard Levitte] - - *) Introduce safe string copy and catenation functions - (BUF_strlcpy() and BUF_strlcat()). - [Ben Laurie (CHATS) and Richard Levitte] - - *) Avoid using fixed-size buffers for one-line DNs. - [Ben Laurie (CHATS)] - - *) Add BUF_MEM_grow_clean() to avoid information leakage when - resizing buffers containing secrets, and use where appropriate. - [Ben Laurie (CHATS)] - - *) Avoid using fixed size buffers for configuration file location. - [Ben Laurie (CHATS)] - - *) Avoid filename truncation for various CA files. - [Ben Laurie (CHATS)] - - *) Use sizeof in preference to magic numbers. - [Ben Laurie (CHATS)] - - *) Avoid filename truncation in cert requests. - [Ben Laurie (CHATS)] - - *) Add assertions to check for (supposedly impossible) buffer - overflows. - [Ben Laurie (CHATS)] - - *) Don't cache truncated DNS entries in the local cache (this could - potentially lead to a spoofing attack). - [Ben Laurie (CHATS)] - - *) Fix various buffers to be large enough for hex/decimal - representations in a platform independent manner. - [Ben Laurie (CHATS)] - - *) Add CRYPTO_realloc_clean() to avoid information leakage when - resizing buffers containing secrets, and use where appropriate. - [Ben Laurie (CHATS)] - - *) Add BIO_indent() to avoid much slightly worrying code to do - indents. - [Ben Laurie (CHATS)] - - *) Convert sprintf()/BIO_puts() to BIO_printf(). - [Ben Laurie (CHATS)] - - *) buffer_gets() could terminate with the buffer only half - full. Fixed. - [Ben Laurie (CHATS)] - - *) Add assertions to prevent user-supplied crypto functions from - overflowing internal buffers by having large block sizes, etc. - [Ben Laurie (CHATS)] - - *) New OPENSSL_assert() macro (similar to assert(), but enabled - unconditionally). - [Ben Laurie (CHATS)] - - *) Eliminate unused copy of key in RC4. - [Ben Laurie (CHATS)] - - *) Eliminate unused and incorrectly sized buffers for IV in pem.h. - [Ben Laurie (CHATS)] - - *) Fix off-by-one error in EGD path. - [Ben Laurie (CHATS)] - - *) If RANDFILE path is too long, ignore instead of truncating. - [Ben Laurie (CHATS)] - - *) Eliminate unused and incorrectly sized X.509 structure - CBCParameter. - [Ben Laurie (CHATS)] - - *) Eliminate unused and dangerous function knumber(). - [Ben Laurie (CHATS)] - - *) Eliminate unused and dangerous structure, KSSL_ERR. - [Ben Laurie (CHATS)] - - *) Protect against overlong session ID context length in an encoded - session object. Since these are local, this does not appear to be - exploitable. - [Ben Laurie (CHATS)] - - *) Change from security patch (see 0.9.6e below) that did not affect - the 0.9.6 release series: - - Remote buffer overflow in SSL3 protocol - an attacker could - supply an oversized master key in Kerberos-enabled versions. - (CVE-2002-0657) - [Ben Laurie (CHATS)] - - *) Change the SSL kerb5 codes to match RFC 2712. - [Richard Levitte] - - *) Make -nameopt work fully for req and add -reqopt switch. - [Michael Bell , Steve Henson] - - *) The "block size" for block ciphers in CFB and OFB mode should be 1. - [Steve Henson, reported by Yngve Nysaeter Pettersen ] - - *) Make sure tests can be performed even if the corresponding algorithms - have been removed entirely. This was also the last step to make - OpenSSL compilable with DJGPP under all reasonable conditions. - [Richard Levitte, Doug Kaufman ] - - *) Add cipher selection rules COMPLEMENTOFALL and COMPLEMENTOFDEFAULT - to allow version independent disabling of normally unselected ciphers, - which may be activated as a side-effect of selecting a single cipher. - - (E.g., cipher list string "RSA" enables ciphersuites that are left - out of "ALL" because they do not provide symmetric encryption. - "RSA:!COMPLEMEMENTOFALL" avoids these unsafe ciphersuites.) - [Lutz Jaenicke, Bodo Moeller] - - *) Add appropriate support for separate platform-dependent build - directories. The recommended way to make a platform-dependent - build directory is the following (tested on Linux), maybe with - some local tweaks: - - # Place yourself outside of the OpenSSL source tree. In - # this example, the environment variable OPENSSL_SOURCE - # is assumed to contain the absolute OpenSSL source directory. - mkdir -p objtree/"`uname -s`-`uname -r`-`uname -m`" - cd objtree/"`uname -s`-`uname -r`-`uname -m`" - (cd $OPENSSL_SOURCE; find . -type f) | while read F; do - mkdir -p `dirname $F` - ln -s $OPENSSL_SOURCE/$F $F - done - - To be absolutely sure not to disturb the source tree, a "make clean" - is a good thing. If it isn't successful, don't worry about it, - it probably means the source directory is very clean. - [Richard Levitte] - - *) Make sure any ENGINE control commands make local copies of string - pointers passed to them whenever necessary. Otherwise it is possible - the caller may have overwritten (or deallocated) the original string - data when a later ENGINE operation tries to use the stored values. - [Götz Babin-Ebell ] - - *) Improve diagnostics in file reading and command-line digests. - [Ben Laurie aided and abetted by Solar Designer ] - - *) Add AES modes CFB and OFB to the object database. Correct an - error in AES-CFB decryption. - [Richard Levitte] - - *) Remove most calls to EVP_CIPHER_CTX_cleanup() in evp_enc.c, this - allows existing EVP_CIPHER_CTX structures to be reused after - calling EVP_*Final(). This behaviour is used by encryption - BIOs and some applications. This has the side effect that - applications must explicitly clean up cipher contexts with - EVP_CIPHER_CTX_cleanup() or they will leak memory. - [Steve Henson] - - *) Check the values of dna and dnb in bn_mul_recursive before calling - bn_mul_comba (a non zero value means the a or b arrays do not contain - n2 elements) and fallback to bn_mul_normal if either is not zero. - [Steve Henson] - - *) Fix escaping of non-ASCII characters when using the -subj option - of the "openssl req" command line tool. (Robert Joop ) - [Lutz Jaenicke] - - *) Make object definitions compliant to LDAP (RFC2256): SN is the short - form for "surname", serialNumber has no short form. - Use "mail" as the short name for "rfc822Mailbox" according to RFC2798; - therefore remove "mail" short name for "internet 7". - The OID for unique identifiers in X509 certificates is - x500UniqueIdentifier, not uniqueIdentifier. - Some more OID additions. (Michael Bell ) - [Lutz Jaenicke] - - *) Add an "init" command to the ENGINE config module and auto initialize - ENGINEs. Without any "init" command the ENGINE will be initialized - after all ctrl commands have been executed on it. If init=1 the - ENGINE is initialized at that point (ctrls before that point are run - on the uninitialized ENGINE and after on the initialized one). If - init=0 then the ENGINE will not be initialized at all. - [Steve Henson] - - *) Fix the 'app_verify_callback' interface so that the user-defined - argument is actually passed to the callback: In the - SSL_CTX_set_cert_verify_callback() prototype, the callback - declaration has been changed from - int (*cb)() - into - int (*cb)(X509_STORE_CTX *,void *); - in ssl_verify_cert_chain (ssl/ssl_cert.c), the call - i=s->ctx->app_verify_callback(&ctx) - has been changed into - i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg). - - To update applications using SSL_CTX_set_cert_verify_callback(), - a dummy argument can be added to their callback functions. - [D. K. Smetters ] - - *) Added the '4758cca' ENGINE to support IBM 4758 cards. - [Maurice Gittens , touchups by Geoff Thorpe] - - *) Add and OPENSSL_LOAD_CONF define which will cause - OpenSSL_add_all_algorithms() to load the openssl.cnf config file. - This allows older applications to transparently support certain - OpenSSL features: such as crypto acceleration and dynamic ENGINE loading. - Two new functions OPENSSL_add_all_algorithms_noconf() which will never - load the config file and OPENSSL_add_all_algorithms_conf() which will - always load it have also been added. - [Steve Henson] - - *) Add the OFB, CFB and CTR (all with 128 bit feedback) to AES. - Adjust NIDs and EVP layer. - [Stephen Sprunk and Richard Levitte] - - *) Config modules support in openssl utility. - - Most commands now load modules from the config file, - though in a few (such as version) this isn't done - because it couldn't be used for anything. - - In the case of ca and req the config file used is - the same as the utility itself: that is the -config - command line option can be used to specify an - alternative file. - [Steve Henson] - - *) Move default behaviour from OPENSSL_config(). If appname is NULL - use "openssl_conf" if filename is NULL use default openssl config file. - [Steve Henson] - - *) Add an argument to OPENSSL_config() to allow the use of an alternative - config section name. Add a new flag to tolerate a missing config file - and move code to CONF_modules_load_file(). - [Steve Henson] - - *) Support for crypto accelerator cards from Accelerated Encryption - Processing, www.aep.ie. (Use engine 'aep') - The support was copied from 0.9.6c [engine] and adapted/corrected - to work with the new engine framework. - [AEP Inc. and Richard Levitte] - - *) Support for SureWare crypto accelerator cards from Baltimore - Technologies. (Use engine 'sureware') - The support was copied from 0.9.6c [engine] and adapted - to work with the new engine framework. - [Richard Levitte] - - *) Have the CHIL engine fork-safe (as defined by nCipher) and actually - make the newer ENGINE framework commands for the CHIL engine work. - [Toomas Kiisk and Richard Levitte] - - *) Make it possible to produce shared libraries on ReliantUNIX. - [Robert Dahlem via Richard Levitte] - - *) Add the configuration target debug-linux-ppro. - Make 'openssl rsa' use the general key loading routines - implemented in apps.c, and make those routines able to - handle the key format FORMAT_NETSCAPE and the variant - FORMAT_IISSGC. - [Toomas Kiisk via Richard Levitte] - - *) Fix a crashbug and a logic bug in hwcrhk_load_pubkey(). - [Toomas Kiisk via Richard Levitte] - - *) Add -keyform to rsautl, and document -engine. - [Richard Levitte, inspired by Toomas Kiisk ] - - *) Change BIO_new_file (crypto/bio/bss_file.c) to use new - BIO_R_NO_SUCH_FILE error code rather than the generic - ERR_R_SYS_LIB error code if fopen() fails with ENOENT. - [Ben Laurie] - - *) Add new functions - ERR_peek_last_error - ERR_peek_last_error_line - ERR_peek_last_error_line_data. - These are similar to - ERR_peek_error - ERR_peek_error_line - ERR_peek_error_line_data, - but report on the latest error recorded rather than the first one - still in the error queue. - [Ben Laurie, Bodo Moeller] - - *) default_algorithms option in ENGINE config module. This allows things - like: - default_algorithms = ALL - default_algorithms = RSA, DSA, RAND, CIPHERS, DIGESTS - [Steve Henson] - - *) Preliminary ENGINE config module. - [Steve Henson] - - *) New experimental application configuration code. - [Steve Henson] - - *) Change the AES code to follow the same name structure as all other - symmetric ciphers, and behave the same way. Move everything to - the directory crypto/aes, thereby obsoleting crypto/rijndael. - [Stephen Sprunk and Richard Levitte] - - *) SECURITY: remove unsafe setjmp/signal interaction from ui_openssl.c. - [Ben Laurie and Theo de Raadt] - - *) Add option to output public keys in req command. - [Massimiliano Pala madwolf@openca.org] - - *) Use wNAFs in EC_POINTs_mul() for improved efficiency - (up to about 10% better than before for P-192 and P-224). - [Bodo Moeller] - - *) New functions/macros - - SSL_CTX_set_msg_callback(ctx, cb) - SSL_CTX_set_msg_callback_arg(ctx, arg) - SSL_set_msg_callback(ssl, cb) - SSL_set_msg_callback_arg(ssl, arg) - - to request calling a callback function - - void cb(int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, void *arg) - - whenever a protocol message has been completely received - (write_p == 0) or sent (write_p == 1). Here 'version' is the - protocol version according to which the SSL library interprets - the current protocol message (SSL2_VERSION, SSL3_VERSION, or - TLS1_VERSION). 'content_type' is 0 in the case of SSL 2.0, or - the content type as defined in the SSL 3.0/TLS 1.0 protocol - specification (change_cipher_spec(20), alert(21), handshake(22)). - 'buf' and 'len' point to the actual message, 'ssl' to the - SSL object, and 'arg' is the application-defined value set by - SSL[_CTX]_set_msg_callback_arg(). - - 'openssl s_client' and 'openssl s_server' have new '-msg' options - to enable a callback that displays all protocol messages. - [Bodo Moeller] - - *) Change the shared library support so shared libraries are built as - soon as the corresponding static library is finished, and thereby get - openssl and the test programs linked against the shared library. - This still only happens when the keyword "shard" has been given to - the configuration scripts. - - NOTE: shared library support is still an experimental thing, and - backward binary compatibility is still not guaranteed. - ["Maciej W. Rozycki" and Richard Levitte] - - *) Add support for Subject Information Access extension. - [Peter Sylvester ] - - *) Make BUF_MEM_grow() behaviour more consistent: Initialise to zero - additional bytes when new memory had to be allocated, not just - when reusing an existing buffer. - [Bodo Moeller] - - *) New command line and configuration option 'utf8' for the req command. - This allows field values to be specified as UTF8 strings. - [Steve Henson] - - *) Add -multi and -mr options to "openssl speed" - giving multiple parallel - runs for the former and machine-readable output for the latter. - [Ben Laurie] - - *) Add '-noemailDN' option to 'openssl ca'. This prevents inclusion - of the e-mail address in the DN (i.e., it will go into a certificate - extension only). The new configuration file option 'email_in_dn = no' - has the same effect. - [Massimiliano Pala madwolf@openca.org] - - *) Change all functions with names starting with des_ to be starting - with DES_ instead. Add wrappers that are compatible with libdes, - but are named _ossl_old_des_*. Finally, add macros that map the - des_* symbols to the corresponding _ossl_old_des_* if libdes - compatibility is desired. If OpenSSL 0.9.6c compatibility is - desired, the des_* symbols will be mapped to DES_*, with one - exception. - - Since we provide two compatibility mappings, the user needs to - define the macro OPENSSL_DES_LIBDES_COMPATIBILITY if libdes - compatibility is desired. The default (i.e., when that macro - isn't defined) is OpenSSL 0.9.6c compatibility. - - There are also macros that enable and disable the support of old - des functions altogether. Those are OPENSSL_ENABLE_OLD_DES_SUPPORT - and OPENSSL_DISABLE_OLD_DES_SUPPORT. If none or both of those - are defined, the default will apply: to support the old des routines. - - In either case, one must include openssl/des.h to get the correct - definitions. Do not try to just include openssl/des_old.h, that - won't work. - - NOTE: This is a major break of an old API into a new one. Software - authors are encouraged to switch to the DES_ style functions. Some - time in the future, des_old.h and the libdes compatibility functions - will be disable (i.e. OPENSSL_DISABLE_OLD_DES_SUPPORT will be the - default), and then completely removed. - [Richard Levitte] - - *) Test for certificates which contain unsupported critical extensions. - If such a certificate is found during a verify operation it is - rejected by default: this behaviour can be overridden by either - handling the new error X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION or - by setting the verify flag X509_V_FLAG_IGNORE_CRITICAL. A new function - X509_supported_extension() has also been added which returns 1 if a - particular extension is supported. - [Steve Henson] - - *) Modify the behaviour of EVP cipher functions in similar way to digests - to retain compatibility with existing code. - [Steve Henson] - - *) Modify the behaviour of EVP_DigestInit() and EVP_DigestFinal() to retain - compatibility with existing code. In particular the 'ctx' parameter does - not have to be to be initialized before the call to EVP_DigestInit() and - it is tidied up after a call to EVP_DigestFinal(). New function - EVP_DigestFinal_ex() which does not tidy up the ctx. Similarly function - EVP_MD_CTX_copy() changed to not require the destination to be - initialized valid and new function EVP_MD_CTX_copy_ex() added which - requires the destination to be valid. - - Modify all the OpenSSL digest calls to use EVP_DigestInit_ex(), - EVP_DigestFinal_ex() and EVP_MD_CTX_copy_ex(). - [Steve Henson] - - *) Change ssl3_get_message (ssl/s3_both.c) and the functions using it - so that complete 'Handshake' protocol structures are kept in memory - instead of overwriting 'msg_type' and 'length' with 'body' data. - [Bodo Moeller] - - *) Add an implementation of SSL_add_dir_cert_subjects_to_stack for Win32. - [Massimo Santin via Richard Levitte] - - *) Major restructuring to the underlying ENGINE code. This includes - reduction of linker bloat, separation of pure "ENGINE" manipulation - (initialisation, etc) from functionality dealing with implementations - of specific crypto interfaces. This change also introduces integrated - support for symmetric ciphers and digest implementations - so ENGINEs - can now accelerate these by providing EVP_CIPHER and EVP_MD - implementations of their own. This is detailed in crypto/engine/README - as it couldn't be adequately described here. However, there are a few - API changes worth noting - some RSA, DSA, DH, and RAND functions that - were changed in the original introduction of ENGINE code have now - reverted back - the hooking from this code to ENGINE is now a good - deal more passive and at run-time, operations deal directly with - RSA_METHODs, DSA_METHODs (etc) as they did before, rather than - dereferencing through an ENGINE pointer any more. Also, the ENGINE - functions dealing with BN_MOD_EXP[_CRT] handlers have been removed - - they were not being used by the framework as there is no concept of a - BIGNUM_METHOD and they could not be generalised to the new - 'ENGINE_TABLE' mechanism that underlies the new code. Similarly, - ENGINE_cpy() has been removed as it cannot be consistently defined in - the new code. - [Geoff Thorpe] - - *) Change ASN1_GENERALIZEDTIME_check() to allow fractional seconds. - [Steve Henson] - - *) Change mkdef.pl to sort symbols that get the same entry number, - and make sure the automatically generated functions ERR_load_* - become part of libeay.num as well. - [Richard Levitte] - - *) New function SSL_renegotiate_pending(). This returns true once - renegotiation has been requested (either SSL_renegotiate() call - or HelloRequest/ClientHello received from the peer) and becomes - false once a handshake has been completed. - (For servers, SSL_renegotiate() followed by SSL_do_handshake() - sends a HelloRequest, but does not ensure that a handshake takes - place. SSL_renegotiate_pending() is useful for checking if the - client has followed the request.) - [Bodo Moeller] - - *) New SSL option SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION. - By default, clients may request session resumption even during - renegotiation (if session ID contexts permit); with this option, - session resumption is possible only in the first handshake. - - SSL_OP_ALL is now 0x00000FFFL instead of 0x000FFFFFL. This makes - more bits available for options that should not be part of - SSL_OP_ALL (such as SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION). - [Bodo Moeller] - - *) Add some demos for certificate and certificate request creation. - [Steve Henson] - - *) Make maximum certificate chain size accepted from the peer application - settable (SSL*_get/set_max_cert_list()), as proposed by - "Douglas E. Engert" . - [Lutz Jaenicke] - - *) Add support for shared libraries for Unixware-7 - (Boyd Lynn Gerber ). - [Lutz Jaenicke] - - *) Add a "destroy" handler to ENGINEs that allows structural cleanup to - be done prior to destruction. Use this to unload error strings from - ENGINEs that load their own error strings. NB: This adds two new API - functions to "get" and "set" this destroy handler in an ENGINE. - [Geoff Thorpe] - - *) Alter all existing ENGINE implementations (except "openssl" and - "openbsd") to dynamically instantiate their own error strings. This - makes them more flexible to be built both as statically-linked ENGINEs - and self-contained shared-libraries loadable via the "dynamic" ENGINE. - Also, add stub code to each that makes building them as self-contained - shared-libraries easier (see README.ENGINE). - [Geoff Thorpe] - - *) Add a "dynamic" ENGINE that provides a mechanism for binding ENGINE - implementations into applications that are completely implemented in - self-contained shared-libraries. The "dynamic" ENGINE exposes control - commands that can be used to configure what shared-library to load and - to control aspects of the way it is handled. Also, made an update to - the README.ENGINE file that brings its information up-to-date and - provides some information and instructions on the "dynamic" ENGINE - (ie. how to use it, how to build "dynamic"-loadable ENGINEs, etc). - [Geoff Thorpe] - - *) Make it possible to unload ranges of ERR strings with a new - "ERR_unload_strings" function. - [Geoff Thorpe] - - *) Add a copy() function to EVP_MD. - [Ben Laurie] - - *) Make EVP_MD routines take a context pointer instead of just the - md_data void pointer. - [Ben Laurie] - - *) Add flags to EVP_MD and EVP_MD_CTX. EVP_MD_FLAG_ONESHOT indicates - that the digest can only process a single chunk of data - (typically because it is provided by a piece of - hardware). EVP_MD_CTX_FLAG_ONESHOT indicates that the application - is only going to provide a single chunk of data, and hence the - framework needn't accumulate the data for oneshot drivers. - [Ben Laurie] - - *) As with "ERR", make it possible to replace the underlying "ex_data" - functions. This change also alters the storage and management of global - ex_data state - it's now all inside ex_data.c and all "class" code (eg. - RSA, BIO, SSL_CTX, etc) no longer stores its own STACKS and per-class - index counters. The API functions that use this state have been changed - to take a "class_index" rather than pointers to the class's local STACK - and counter, and there is now an API function to dynamically create new - classes. This centralisation allows us to (a) plug a lot of the - thread-safety problems that existed, and (b) makes it possible to clean - up all allocated state using "CRYPTO_cleanup_all_ex_data()". W.r.t. (b) - such data would previously have always leaked in application code and - workarounds were in place to make the memory debugging turn a blind eye - to it. Application code that doesn't use this new function will still - leak as before, but their memory debugging output will announce it now - rather than letting it slide. - - Besides the addition of CRYPTO_cleanup_all_ex_data(), another API change - induced by the "ex_data" overhaul is that X509_STORE_CTX_init() now - has a return value to indicate success or failure. - [Geoff Thorpe] - - *) Make it possible to replace the underlying "ERR" functions such that the - global state (2 LHASH tables and 2 locks) is only used by the "default" - implementation. This change also adds two functions to "get" and "set" - the implementation prior to it being automatically set the first time - any other ERR function takes place. Ie. an application can call "get", - pass the return value to a module it has just loaded, and that module - can call its own "set" function using that value. This means the - module's "ERR" operations will use (and modify) the error state in the - application and not in its own statically linked copy of OpenSSL code. - [Geoff Thorpe] - - *) Give DH, DSA, and RSA types their own "**_up_ref()" function to increment - reference counts. This performs normal REF_PRINT/REF_CHECK macros on - the operation, and provides a more encapsulated way for external code - (crypto/evp/ and ssl/) to do this. Also changed the evp and ssl code - to use these functions rather than manually incrementing the counts. - - Also rename "DSO_up()" function to more descriptive "DSO_up_ref()". - [Geoff Thorpe] - - *) Add EVP test program. - [Ben Laurie] - - *) Add symmetric cipher support to ENGINE. Expect the API to change! - [Ben Laurie] - - *) New CRL functions: X509_CRL_set_version(), X509_CRL_set_issuer_name() - X509_CRL_set_lastUpdate(), X509_CRL_set_nextUpdate(), X509_CRL_sort(), - X509_REVOKED_set_serialNumber(), and X509_REVOKED_set_revocationDate(). - These allow a CRL to be built without having to access X509_CRL fields - directly. Modify 'ca' application to use new functions. - [Steve Henson] - - *) Move SSL_OP_TLS_ROLLBACK_BUG out of the SSL_OP_ALL list of recommended - bug workarounds. Rollback attack detection is a security feature. - The problem will only arise on OpenSSL servers when TLSv1 is not - available (sslv3_server_method() or SSL_OP_NO_TLSv1). - Software authors not wanting to support TLSv1 will have special reasons - for their choice and can explicitly enable this option. - [Bodo Moeller, Lutz Jaenicke] - - *) Rationalise EVP so it can be extended: don't include a union of - cipher/digest structures, add init/cleanup functions for EVP_MD_CTX - (similar to those existing for EVP_CIPHER_CTX). - Usage example: - - EVP_MD_CTX md; - - EVP_MD_CTX_init(&md); /* new function call */ - EVP_DigestInit(&md, EVP_sha1()); - EVP_DigestUpdate(&md, in, len); - EVP_DigestFinal(&md, out, NULL); - EVP_MD_CTX_cleanup(&md); /* new function call */ - - [Ben Laurie] - - *) Make DES key schedule conform to the usual scheme, as well as - correcting its structure. This means that calls to DES functions - now have to pass a pointer to a des_key_schedule instead of a - plain des_key_schedule (which was actually always a pointer - anyway): E.g., - - des_key_schedule ks; - - des_set_key_checked(..., &ks); - des_ncbc_encrypt(..., &ks, ...); - - (Note that a later change renames 'des_...' into 'DES_...'.) - [Ben Laurie] - - *) Initial reduction of linker bloat: the use of some functions, such as - PEM causes large amounts of unused functions to be linked in due to - poor organisation. For example pem_all.c contains every PEM function - which has a knock on effect of linking in large amounts of (unused) - ASN1 code. Grouping together similar functions and splitting unrelated - functions prevents this. - [Steve Henson] - - *) Cleanup of EVP macros. - [Ben Laurie] - - *) Change historical references to {NID,SN,LN}_des_ede and ede3 to add the - correct _ecb suffix. - [Ben Laurie] - - *) Add initial OCSP responder support to ocsp application. The - revocation information is handled using the text based index - use by the ca application. The responder can either handle - requests generated internally, supplied in files (for example - via a CGI script) or using an internal minimal server. - [Steve Henson] - - *) Add configuration choices to get zlib compression for TLS. - [Richard Levitte] - - *) Changes to Kerberos SSL for RFC 2712 compliance: - 1. Implemented real KerberosWrapper, instead of just using - KRB5 AP_REQ message. [Thanks to Simon Wilkinson ] - 2. Implemented optional authenticator field of KerberosWrapper. - - Added openssl-style ASN.1 macros for Kerberos ticket, ap_req, - and authenticator structs; see crypto/krb5/. - - Generalized Kerberos calls to support multiple Kerberos libraries. - [Vern Staats , - Jeffrey Altman - via Richard Levitte] - - *) Cause 'openssl speed' to use fully hard-coded DSA keys as it - already does with RSA. testdsa.h now has 'priv_key/pub_key' - values for each of the key sizes rather than having just - parameters (and 'speed' generating keys each time). - [Geoff Thorpe] - - *) Speed up EVP routines. - Before: -encrypt -type 8 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes -des-cbc 4408.85k 5560.51k 5778.46k 5862.20k 5825.16k -des-cbc 4389.55k 5571.17k 5792.23k 5846.91k 5832.11k -des-cbc 4394.32k 5575.92k 5807.44k 5848.37k 5841.30k -decrypt -des-cbc 3482.66k 5069.49k 5496.39k 5614.16k 5639.28k -des-cbc 3480.74k 5068.76k 5510.34k 5609.87k 5635.52k -des-cbc 3483.72k 5067.62k 5504.60k 5708.01k 5724.80k - After: -encrypt -des-cbc 4660.16k 5650.19k 5807.19k 5827.13k 5783.32k -decrypt -des-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k - [Ben Laurie] - - *) Added the OS2-EMX target. - ["Brian Havard" and Richard Levitte] - - *) Rewrite apps to use NCONF routines instead of the old CONF. New functions - to support NCONF routines in extension code. New function CONF_set_nconf() - to allow functions which take an NCONF to also handle the old LHASH - structure: this means that the old CONF compatible routines can be - retained (in particular wrt extensions) without having to duplicate the - code. New function X509V3_add_ext_nconf_sk to add extensions to a stack. - [Steve Henson] - - *) Enhance the general user interface with mechanisms for inner control - and with possibilities to have yes/no kind of prompts. - [Richard Levitte] - - *) Change all calls to low level digest routines in the library and - applications to use EVP. Add missing calls to HMAC_cleanup() and - don't assume HMAC_CTX can be copied using memcpy(). - [Verdon Walker , Steve Henson] - - *) Add the possibility to control engines through control names but with - arbitrary arguments instead of just a string. - Change the key loaders to take a UI_METHOD instead of a callback - function pointer. NOTE: this breaks binary compatibility with earlier - versions of OpenSSL [engine]. - Adapt the nCipher code for these new conditions and add a card insertion - callback. - [Richard Levitte] - - *) Enhance the general user interface with mechanisms to better support - dialog box interfaces, application-defined prompts, the possibility - to use defaults (for example default passwords from somewhere else) - and interrupts/cancellations. - [Richard Levitte] - - *) Tidy up PKCS#12 attribute handling. Add support for the CSP name - attribute in PKCS#12 files, add new -CSP option to pkcs12 utility. - [Steve Henson] - - *) Fix a memory leak in 'sk_dup()' in the case reallocation fails. (Also - tidy up some unnecessarily weird code in 'sk_new()'). - [Geoff, reported by Diego Tartara ] - - *) Change the key loading routines for ENGINEs to use the same kind - callback (pem_password_cb) as all other routines that need this - kind of callback. - [Richard Levitte] - - *) Increase ENTROPY_NEEDED to 32 bytes, as Rijndael can operate with - 256 bit (=32 byte) keys. Of course seeding with more entropy bytes - than this minimum value is recommended. - [Lutz Jaenicke] - - *) New random seeder for OpenVMS, using the system process statistics - that are easily reachable. - [Richard Levitte] - - *) Windows apparently can't transparently handle global - variables defined in DLLs. Initialisations such as: - - const ASN1_ITEM *it = &ASN1_INTEGER_it; - - won't compile. This is used by the any applications that need to - declare their own ASN1 modules. This was fixed by adding the option - EXPORT_VAR_AS_FN to all Win32 platforms, although this isn't strictly - needed for static libraries under Win32. - [Steve Henson] - - *) New functions X509_PURPOSE_set() and X509_TRUST_set() to handle - setting of purpose and trust fields. New X509_STORE trust and - purpose functions and tidy up setting in other SSL functions. - [Steve Henson] - - *) Add copies of X509_STORE_CTX fields and callbacks to X509_STORE - structure. These are inherited by X509_STORE_CTX when it is - initialised. This allows various defaults to be set in the - X509_STORE structure (such as flags for CRL checking and custom - purpose or trust settings) for functions which only use X509_STORE_CTX - internally such as S/MIME. - - Modify X509_STORE_CTX_purpose_inherit() so it only sets purposes and - trust settings if they are not set in X509_STORE. This allows X509_STORE - purposes and trust (in S/MIME for example) to override any set by default. - - Add command line options for CRL checking to smime, s_client and s_server - applications. - [Steve Henson] - - *) Initial CRL based revocation checking. If the CRL checking flag(s) - are set then the CRL is looked up in the X509_STORE structure and - its validity and signature checked, then if the certificate is found - in the CRL the verify fails with a revoked error. - - Various new CRL related callbacks added to X509_STORE_CTX structure. - - Command line options added to 'verify' application to support this. - - This needs some additional work, such as being able to handle multiple - CRLs with different times, extension based lookup (rather than just - by subject name) and ultimately more complete V2 CRL extension - handling. - [Steve Henson] - - *) Add a general user interface API (crypto/ui/). This is designed - to replace things like des_read_password and friends (backward - compatibility functions using this new API are provided). - The purpose is to remove prompting functions from the DES code - section as well as provide for prompting through dialog boxes in - a window system and the like. - [Richard Levitte] - - *) Add "ex_data" support to ENGINE so implementations can add state at a - per-structure level rather than having to store it globally. - [Geoff] - - *) Make it possible for ENGINE structures to be copied when retrieved by - ENGINE_by_id() if the ENGINE specifies a new flag: ENGINE_FLAGS_BY_ID_COPY. - This causes the "original" ENGINE structure to act like a template, - analogous to the RSA vs. RSA_METHOD type of separation. Because of this - operational state can be localised to each ENGINE structure, despite the - fact they all share the same "methods". New ENGINE structures returned in - this case have no functional references and the return value is the single - structural reference. This matches the single structural reference returned - by ENGINE_by_id() normally, when it is incremented on the pre-existing - ENGINE structure. - [Geoff] - - *) Fix ASN1 decoder when decoding type ANY and V_ASN1_OTHER: since this - needs to match any other type at all we need to manually clear the - tag cache. - [Steve Henson] - - *) Changes to the "openssl engine" utility to include; - - verbosity levels ('-v', '-vv', and '-vvv') that provide information - about an ENGINE's available control commands. - - executing control commands from command line arguments using the - '-pre' and '-post' switches. '-post' is only used if '-t' is - specified and the ENGINE is successfully initialised. The syntax for - the individual commands are colon-separated, for example; - openssl engine chil -pre FORK_CHECK:0 -pre SO_PATH:/lib/test.so - [Geoff] - - *) New dynamic control command support for ENGINEs. ENGINEs can now - declare their own commands (numbers), names (strings), descriptions, - and input types for run-time discovery by calling applications. A - subset of these commands are implicitly classed as "executable" - depending on their input type, and only these can be invoked through - the new string-based API function ENGINE_ctrl_cmd_string(). (Eg. this - can be based on user input, config files, etc). The distinction is - that "executable" commands cannot return anything other than a boolean - result and can only support numeric or string input, whereas some - discoverable commands may only be for direct use through - ENGINE_ctrl(), eg. supporting the exchange of binary data, function - pointers, or other custom uses. The "executable" commands are to - support parameterisations of ENGINE behaviour that can be - unambiguously defined by ENGINEs and used consistently across any - OpenSSL-based application. Commands have been added to all the - existing hardware-supporting ENGINEs, noticeably "SO_PATH" to allow - control over shared-library paths without source code alterations. - [Geoff] - - *) Changed all ENGINE implementations to dynamically allocate their - ENGINEs rather than declaring them statically. Apart from this being - necessary with the removal of the ENGINE_FLAGS_MALLOCED distinction, - this also allows the implementations to compile without using the - internal engine_int.h header. - [Geoff] - - *) Minor adjustment to "rand" code. RAND_get_rand_method() now returns a - 'const' value. Any code that should be able to modify a RAND_METHOD - should already have non-const pointers to it (ie. they should only - modify their own ones). - [Geoff] - - *) Made a variety of little tweaks to the ENGINE code. - - "atalla" and "ubsec" string definitions were moved from header files - to C code. "nuron" string definitions were placed in variables - rather than hard-coded - allowing parameterisation of these values - later on via ctrl() commands. - - Removed unused "#if 0"'d code. - - Fixed engine list iteration code so it uses ENGINE_free() to release - structural references. - - Constified the RAND_METHOD element of ENGINE structures. - - Constified various get/set functions as appropriate and added - missing functions (including a catch-all ENGINE_cpy that duplicates - all ENGINE values onto a new ENGINE except reference counts/state). - - Removed NULL parameter checks in get/set functions. Setting a method - or function to NULL is a way of cancelling out a previously set - value. Passing a NULL ENGINE parameter is just plain stupid anyway - and doesn't justify the extra error symbols and code. - - Deprecate the ENGINE_FLAGS_MALLOCED define and move the area for - flags from engine_int.h to engine.h. - - Changed prototypes for ENGINE handler functions (init(), finish(), - ctrl(), key-load functions, etc) to take an (ENGINE*) parameter. - [Geoff] - - *) Implement binary inversion algorithm for BN_mod_inverse in addition - to the algorithm using long division. The binary algorithm can be - used only if the modulus is odd. On 32-bit systems, it is faster - only for relatively small moduli (roughly 20-30% for 128-bit moduli, - roughly 5-15% for 256-bit moduli), so we use it only for moduli - up to 450 bits. In 64-bit environments, the binary algorithm - appears to be advantageous for much longer moduli; here we use it - for moduli up to 2048 bits. - [Bodo Moeller] - - *) Rewrite CHOICE field setting in ASN1_item_ex_d2i(). The old code - could not support the combine flag in choice fields. - [Steve Henson] - - *) Add a 'copy_extensions' option to the 'ca' utility. This copies - extensions from a certificate request to the certificate. - [Steve Henson] - - *) Allow multiple 'certopt' and 'nameopt' options to be separated - by commas. Add 'namopt' and 'certopt' options to the 'ca' config - file: this allows the display of the certificate about to be - signed to be customised, to allow certain fields to be included - or excluded and extension details. The old system didn't display - multicharacter strings properly, omitted fields not in the policy - and couldn't display additional details such as extensions. - [Steve Henson] - - *) Function EC_POINTs_mul for multiple scalar multiplication - of an arbitrary number of elliptic curve points - \sum scalars[i]*points[i], - optionally including the generator defined for the EC_GROUP: - scalar*generator + \sum scalars[i]*points[i]. - - EC_POINT_mul is a simple wrapper function for the typical case - that the point list has just one item (besides the optional - generator). - [Bodo Moeller] - - *) First EC_METHODs for curves over GF(p): - - EC_GFp_simple_method() uses the basic BN_mod_mul and BN_mod_sqr - operations and provides various method functions that can also - operate with faster implementations of modular arithmetic. - - EC_GFp_mont_method() reuses most functions that are part of - EC_GFp_simple_method, but uses Montgomery arithmetic. - - [Bodo Moeller; point addition and point doubling - implementation directly derived from source code provided by - Lenka Fibikova ] - - *) Framework for elliptic curves (crypto/ec/ec.h, crypto/ec/ec_lcl.h, - crypto/ec/ec_lib.c): - - Curves are EC_GROUP objects (with an optional group generator) - based on EC_METHODs that are built into the library. - - Points are EC_POINT objects based on EC_GROUP objects. - - Most of the framework would be able to handle curves over arbitrary - finite fields, but as there are no obvious types for fields other - than GF(p), some functions are limited to that for now. - [Bodo Moeller] - - *) Add the -HTTP option to s_server. It is similar to -WWW, but requires - that the file contains a complete HTTP response. - [Richard Levitte] - - *) Add the ec directory to mkdef.pl and mkfiles.pl. In mkdef.pl - change the def and num file printf format specifier from "%-40sXXX" - to "%-39s XXX". The latter will always guarantee a space after the - field while the former will cause them to run together if the field - is 40 of more characters long. - [Steve Henson] - - *) Constify the cipher and digest 'method' functions and structures - and modify related functions to take constant EVP_MD and EVP_CIPHER - pointers. - [Steve Henson] - - *) Hide BN_CTX structure details in bn_lcl.h instead of publishing them - in . Also further increase BN_CTX_NUM to 32. - [Bodo Moeller] - - *) Modify EVP_Digest*() routines so they now return values. Although the - internal software routines can never fail additional hardware versions - might. - [Steve Henson] - - *) Clean up crypto/err/err.h and change some error codes to avoid conflicts: - - Previously ERR_R_FATAL was too small and coincided with ERR_LIB_PKCS7 - (= ERR_R_PKCS7_LIB); it is now 64 instead of 32. - - ASN1 error codes - ERR_R_NESTED_ASN1_ERROR - ... - ERR_R_MISSING_ASN1_EOS - were 4 .. 9, conflicting with - ERR_LIB_RSA (= ERR_R_RSA_LIB) - ... - ERR_LIB_PEM (= ERR_R_PEM_LIB). - They are now 58 .. 63 (i.e., just below ERR_R_FATAL). - - Add new error code 'ERR_R_INTERNAL_ERROR'. - [Bodo Moeller] - - *) Don't overuse locks in crypto/err/err.c: For data retrieval, CRYPTO_r_lock - suffices. - [Bodo Moeller] - - *) New option '-subj arg' for 'openssl req' and 'openssl ca'. This - sets the subject name for a new request or supersedes the - subject name in a given request. Formats that can be parsed are - 'CN=Some Name, OU=myOU, C=IT' - and - 'CN=Some Name/OU=myOU/C=IT'. - - Add options '-batch' and '-verbose' to 'openssl req'. - [Massimiliano Pala ] - - *) Introduce the possibility to access global variables through - functions on platform were that's the best way to handle exporting - global variables in shared libraries. To enable this functionality, - one must configure with "EXPORT_VAR_AS_FN" or defined the C macro - "OPENSSL_EXPORT_VAR_AS_FUNCTION" in crypto/opensslconf.h (the latter - is normally done by Configure or something similar). - - To implement a global variable, use the macro OPENSSL_IMPLEMENT_GLOBAL - in the source file (foo.c) like this: - - OPENSSL_IMPLEMENT_GLOBAL(int,foo)=1; - OPENSSL_IMPLEMENT_GLOBAL(double,bar); - - To declare a global variable, use the macros OPENSSL_DECLARE_GLOBAL - and OPENSSL_GLOBAL_REF in the header file (foo.h) like this: - - OPENSSL_DECLARE_GLOBAL(int,foo); - #define foo OPENSSL_GLOBAL_REF(foo) - OPENSSL_DECLARE_GLOBAL(double,bar); - #define bar OPENSSL_GLOBAL_REF(bar) - - The #defines are very important, and therefore so is including the - header file everywhere where the defined globals are used. - - The macro OPENSSL_EXPORT_VAR_AS_FUNCTION also affects the definition - of ASN.1 items, but that structure is a bit different. - - The largest change is in util/mkdef.pl which has been enhanced with - better and easier to understand logic to choose which symbols should - go into the Windows .def files as well as a number of fixes and code - cleanup (among others, algorithm keywords are now sorted - lexicographically to avoid constant rewrites). - [Richard Levitte] - - *) In BN_div() keep a copy of the sign of 'num' before writing the - result to 'rm' because if rm==num the value will be overwritten - and produce the wrong result if 'num' is negative: this caused - problems with BN_mod() and BN_nnmod(). - [Steve Henson] - - *) Function OCSP_request_verify(). This checks the signature on an - OCSP request and verifies the signer certificate. The signer - certificate is just checked for a generic purpose and OCSP request - trust settings. - [Steve Henson] - - *) Add OCSP_check_validity() function to check the validity of OCSP - responses. OCSP responses are prepared in real time and may only - be a few seconds old. Simply checking that the current time lies - between thisUpdate and nextUpdate max reject otherwise valid responses - caused by either OCSP responder or client clock inaccuracy. Instead - we allow thisUpdate and nextUpdate to fall within a certain period of - the current time. The age of the response can also optionally be - checked. Two new options -validity_period and -status_age added to - ocsp utility. - [Steve Henson] - - *) If signature or public key algorithm is unrecognized print out its - OID rather that just UNKNOWN. - [Steve Henson] - - *) Change OCSP_cert_to_id() to tolerate a NULL subject certificate and - OCSP_cert_id_new() a NULL serialNumber. This allows a partial certificate - ID to be generated from the issuer certificate alone which can then be - passed to OCSP_id_issuer_cmp(). - [Steve Henson] - - *) New compilation option ASN1_ITEM_FUNCTIONS. This causes the new - ASN1 modules to export functions returning ASN1_ITEM pointers - instead of the ASN1_ITEM structures themselves. This adds several - new macros which allow the underlying ASN1 function/structure to - be accessed transparently. As a result code should not use ASN1_ITEM - references directly (such as &X509_it) but instead use the relevant - macros (such as ASN1_ITEM_rptr(X509)). This option is to allow - use of the new ASN1 code on platforms where exporting structures - is problematical (for example in shared libraries) but exporting - functions returning pointers to structures is not. - [Steve Henson] - - *) Add support for overriding the generation of SSL/TLS session IDs. - These callbacks can be registered either in an SSL_CTX or per SSL. - The purpose of this is to allow applications to control, if they wish, - the arbitrary values chosen for use as session IDs, particularly as it - can be useful for session caching in multiple-server environments. A - command-line switch for testing this (and any client code that wishes - to use such a feature) has been added to "s_server". - [Geoff Thorpe, Lutz Jaenicke] - - *) Modify mkdef.pl to recognise and parse preprocessor conditionals - of the form '#if defined(...) || defined(...) || ...' and - '#if !defined(...) && !defined(...) && ...'. This also avoids - the growing number of special cases it was previously handling. - [Richard Levitte] - - *) Make all configuration macros available for application by making - sure they are available in opensslconf.h, by giving them names starting - with "OPENSSL_" to avoid conflicts with other packages and by making - sure e_os2.h will cover all platform-specific cases together with - opensslconf.h. - Additionally, it is now possible to define configuration/platform- - specific names (called "system identities"). In the C code, these - are prefixed with "OPENSSL_SYSNAME_". e_os2.h will create another - macro with the name beginning with "OPENSSL_SYS_", which is determined - from "OPENSSL_SYSNAME_*" or compiler-specific macros depending on - what is available. - [Richard Levitte] - - *) New option -set_serial to 'req' and 'x509' this allows the serial - number to use to be specified on the command line. Previously self - signed certificates were hard coded with serial number 0 and the - CA options of 'x509' had to use a serial number in a file which was - auto incremented. - [Steve Henson] - - *) New options to 'ca' utility to support V2 CRL entry extensions. - Currently CRL reason, invalidity date and hold instruction are - supported. Add new CRL extensions to V3 code and some new objects. - [Steve Henson] - - *) New function EVP_CIPHER_CTX_set_padding() this is used to - disable standard block padding (aka PKCS#5 padding) in the EVP - API, which was previously mandatory. This means that the data is - not padded in any way and so the total length much be a multiple - of the block size, otherwise an error occurs. - [Steve Henson] - - *) Initial (incomplete) OCSP SSL support. - [Steve Henson] - - *) New function OCSP_parse_url(). This splits up a URL into its host, - port and path components: primarily to parse OCSP URLs. New -url - option to ocsp utility. - [Steve Henson] - - *) New nonce behavior. The return value of OCSP_check_nonce() now - reflects the various checks performed. Applications can decide - whether to tolerate certain situations such as an absent nonce - in a response when one was present in a request: the ocsp application - just prints out a warning. New function OCSP_add1_basic_nonce() - this is to allow responders to include a nonce in a response even if - the request is nonce-less. - [Steve Henson] - - *) Disable stdin buffering in load_cert (apps/apps.c) so that no certs are - skipped when using openssl x509 multiple times on a single input file, - e.g. "(openssl x509 -out cert1; openssl x509 -out cert2) ] - - *) New OCSP verify flag OCSP_TRUSTOTHER. When set the "other" certificates - passed by the function are trusted implicitly. If any of them signed the - response then it is assumed to be valid and is not verified. - [Steve Henson] - - *) In PKCS7_set_type() initialise content_type in PKCS7_ENC_CONTENT - to data. This was previously part of the PKCS7 ASN1 code. This - was causing problems with OpenSSL created PKCS#12 and PKCS#7 structures. - [Steve Henson, reported by Kenneth R. Robinette - ] - - *) Add CRYPTO_push_info() and CRYPTO_pop_info() calls to new ASN1 - routines: without these tracing memory leaks is very painful. - Fix leaks in PKCS12 and PKCS7 routines. - [Steve Henson] - - *) Make X509_time_adj() cope with the new behaviour of ASN1_TIME_new(). - Previously it initialised the 'type' argument to V_ASN1_UTCTIME which - effectively meant GeneralizedTime would never be used. Now it - is initialised to -1 but X509_time_adj() now has to check the value - and use ASN1_TIME_set() if the value is not V_ASN1_UTCTIME or - V_ASN1_GENERALIZEDTIME, without this it always uses GeneralizedTime. - [Steve Henson, reported by Kenneth R. Robinette - ] - - *) Fixes to BN_to_ASN1_INTEGER when bn is zero. This would previously - result in a zero length in the ASN1_INTEGER structure which was - not consistent with the structure when d2i_ASN1_INTEGER() was used - and would cause ASN1_INTEGER_cmp() to fail. Enhance s2i_ASN1_INTEGER() - to cope with hex and negative integers. Fix bug in i2a_ASN1_INTEGER() - where it did not print out a minus for negative ASN1_INTEGER. - [Steve Henson] - - *) Add summary printout to ocsp utility. The various functions which - convert status values to strings have been renamed to: - OCSP_response_status_str(), OCSP_cert_status_str() and - OCSP_crl_reason_str() and are no longer static. New options - to verify nonce values and to disable verification. OCSP response - printout format cleaned up. - [Steve Henson] - - *) Add additional OCSP certificate checks. These are those specified - in RFC2560. This consists of two separate checks: the CA of the - certificate being checked must either be the OCSP signer certificate - or the issuer of the OCSP signer certificate. In the latter case the - OCSP signer certificate must contain the OCSP signing extended key - usage. This check is performed by attempting to match the OCSP - signer or the OCSP signer CA to the issuerNameHash and issuerKeyHash - in the OCSP_CERTID structures of the response. - [Steve Henson] - - *) Initial OCSP certificate verification added to OCSP_basic_verify() - and related routines. This uses the standard OpenSSL certificate - verify routines to perform initial checks (just CA validity) and - to obtain the certificate chain. Then additional checks will be - performed on the chain. Currently the root CA is checked to see - if it is explicitly trusted for OCSP signing. This is used to set - a root CA as a global signing root: that is any certificate that - chains to that CA is an acceptable OCSP signing certificate. - [Steve Henson] - - *) New '-extfile ...' option to 'openssl ca' for reading X.509v3 - extensions from a separate configuration file. - As when reading extensions from the main configuration file, - the '-extensions ...' option may be used for specifying the - section to use. - [Massimiliano Pala ] - - *) New OCSP utility. Allows OCSP requests to be generated or - read. The request can be sent to a responder and the output - parsed, outputted or printed in text form. Not complete yet: - still needs to check the OCSP response validity. - [Steve Henson] - - *) New subcommands for 'openssl ca': - 'openssl ca -status ' prints the status of the cert with - the given serial number (according to the index file). - 'openssl ca -updatedb' updates the expiry status of certificates - in the index file. - [Massimiliano Pala ] - - *) New '-newreq-nodes' command option to CA.pl. This is like - '-newreq', but calls 'openssl req' with the '-nodes' option - so that the resulting key is not encrypted. - [Damien Miller ] - - *) New configuration for the GNU Hurd. - [Jonathan Bartlett via Richard Levitte] - - *) Initial code to implement OCSP basic response verify. This - is currently incomplete. Currently just finds the signer's - certificate and verifies the signature on the response. - [Steve Henson] - - *) New SSLeay_version code SSLEAY_DIR to determine the compiled-in - value of OPENSSLDIR. This is available via the new '-d' option - to 'openssl version', and is also included in 'openssl version -a'. - [Bodo Moeller] - - *) Allowing defining memory allocation callbacks that will be given - file name and line number information in additional arguments - (a const char* and an int). The basic functionality remains, as - well as the original possibility to just replace malloc(), - realloc() and free() by functions that do not know about these - additional arguments. To register and find out the current - settings for extended allocation functions, the following - functions are provided: - - CRYPTO_set_mem_ex_functions - CRYPTO_set_locked_mem_ex_functions - CRYPTO_get_mem_ex_functions - CRYPTO_get_locked_mem_ex_functions - - These work the same way as CRYPTO_set_mem_functions and friends. - CRYPTO_get_[locked_]mem_functions now writes 0 where such an - extended allocation function is enabled. - Similarly, CRYPTO_get_[locked_]mem_ex_functions writes 0 where - a conventional allocation function is enabled. - [Richard Levitte, Bodo Moeller] - - *) Finish off removing the remaining LHASH function pointer casts. - There should no longer be any prototype-casting required when using - the LHASH abstraction, and any casts that remain are "bugs". See - the callback types and macros at the head of lhash.h for details - (and "OBJ_cleanup" in crypto/objects/obj_dat.c as an example). - [Geoff Thorpe] - - *) Add automatic query of EGD sockets in RAND_poll() for the unix variant. - If /dev/[u]random devices are not available or do not return enough - entropy, EGD style sockets (served by EGD or PRNGD) will automatically - be queried. - The locations /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool, and - /etc/entropy will be queried once each in this sequence, querying stops - when enough entropy was collected without querying more sockets. - [Lutz Jaenicke] - - *) Change the Unix RAND_poll() variant to be able to poll several - random devices, as specified by DEVRANDOM, until a sufficient amount - of data has been collected. We spend at most 10 ms on each file - (select timeout) and read in non-blocking mode. DEVRANDOM now - defaults to the list "/dev/urandom", "/dev/random", "/dev/srandom" - (previously it was just the string "/dev/urandom"), so on typical - platforms the 10 ms delay will never occur. - Also separate out the Unix variant to its own file, rand_unix.c. - For VMS, there's a currently-empty rand_vms.c. - [Richard Levitte] - - *) Move OCSP client related routines to ocsp_cl.c. These - provide utility functions which an application needing - to issue a request to an OCSP responder and analyse the - response will typically need: as opposed to those which an - OCSP responder itself would need which will be added later. - - OCSP_request_sign() signs an OCSP request with an API similar - to PKCS7_sign(). OCSP_response_status() returns status of OCSP - response. OCSP_response_get1_basic() extracts basic response - from response. OCSP_resp_find_status(): finds and extracts status - information from an OCSP_CERTID structure (which will be created - when the request structure is built). These are built from lower - level functions which work on OCSP_SINGLERESP structures but - won't normally be used unless the application wishes to examine - extensions in the OCSP response for example. - - Replace nonce routines with a pair of functions. - OCSP_request_add1_nonce() adds a nonce value and optionally - generates a random value. OCSP_check_nonce() checks the - validity of the nonce in an OCSP response. - [Steve Henson] - - *) Change function OCSP_request_add() to OCSP_request_add0_id(). - This doesn't copy the supplied OCSP_CERTID and avoids the - need to free up the newly created id. Change return type - to OCSP_ONEREQ to return the internal OCSP_ONEREQ structure. - This can then be used to add extensions to the request. - Deleted OCSP_request_new(), since most of its functionality - is now in OCSP_REQUEST_new() (and the case insensitive name - clash) apart from the ability to set the request name which - will be added elsewhere. - [Steve Henson] - - *) Update OCSP API. Remove obsolete extensions argument from - various functions. Extensions are now handled using the new - OCSP extension code. New simple OCSP HTTP function which - can be used to send requests and parse the response. - [Steve Henson] - - *) Fix the PKCS#7 (S/MIME) code to work with new ASN1. Two new - ASN1_ITEM structures help with sign and verify. PKCS7_ATTR_SIGN - uses the special reorder version of SET OF to sort the attributes - and reorder them to match the encoded order. This resolves a long - standing problem: a verify on a PKCS7 structure just after signing - it used to fail because the attribute order did not match the - encoded order. PKCS7_ATTR_VERIFY does not reorder the attributes: - it uses the received order. This is necessary to tolerate some broken - software that does not order SET OF. This is handled by encoding - as a SEQUENCE OF but using implicit tagging (with UNIVERSAL class) - to produce the required SET OF. - [Steve Henson] - - *) Have mk1mf.pl generate the macros OPENSSL_BUILD_SHLIBCRYPTO and - OPENSSL_BUILD_SHLIBSSL and use them appropriately in the header - files to get correct declarations of the ASN.1 item variables. - [Richard Levitte] - - *) Rewrite of PKCS#12 code to use new ASN1 functionality. Replace many - PKCS#12 macros with real functions. Fix two unrelated ASN1 bugs: - asn1_check_tlen() would sometimes attempt to use 'ctx' when it was - NULL and ASN1_TYPE was not dereferenced properly in asn1_ex_c2i(). - New ASN1 macro: DECLARE_ASN1_ITEM() which just declares the relevant - ASN1_ITEM and no wrapper functions. - [Steve Henson] - - *) New functions or ASN1_item_d2i_fp() and ASN1_item_d2i_bio(). These - replace the old function pointer based I/O routines. Change most of - the *_d2i_bio() and *_d2i_fp() functions to use these. - [Steve Henson] - - *) Enhance mkdef.pl to be more accepting about spacing in C preprocessor - lines, recognize more "algorithms" that can be deselected, and make - it complain about algorithm deselection that isn't recognised. - [Richard Levitte] - - *) New ASN1 functions to handle dup, sign, verify, digest, pack and - unpack operations in terms of ASN1_ITEM. Modify existing wrappers - to use new functions. Add NO_ASN1_OLD which can be set to remove - some old style ASN1 functions: this can be used to determine if old - code will still work when these eventually go away. - [Steve Henson] - - *) New extension functions for OCSP structures, these follow the - same conventions as certificates and CRLs. - [Steve Henson] - - *) New function X509V3_add1_i2d(). This automatically encodes and - adds an extension. Its behaviour can be customised with various - flags to append, replace or delete. Various wrappers added for - certificates and CRLs. - [Steve Henson] - - *) Fix to avoid calling the underlying ASN1 print routine when - an extension cannot be parsed. Correct a typo in the - OCSP_SERVICELOC extension. Tidy up print OCSP format. - [Steve Henson] - - *) Make mkdef.pl parse some of the ASN1 macros and add appropriate - entries for variables. - [Steve Henson] - - *) Add functionality to apps/openssl.c for detecting locking - problems: As the program is single-threaded, all we have - to do is register a locking callback using an array for - storing which locks are currently held by the program. - [Bodo Moeller] - - *) Use a lock around the call to CRYPTO_get_ex_new_index() in - SSL_get_ex_data_X509_STORE_idx(), which is used in - ssl_verify_cert_chain() and thus can be called at any time - during TLS/SSL handshakes so that thread-safety is essential. - Unfortunately, the ex_data design is not at all suited - for multi-threaded use, so it probably should be abolished. - [Bodo Moeller] - - *) Added Broadcom "ubsec" ENGINE to OpenSSL. - [Broadcom, tweaked and integrated by Geoff Thorpe] - - *) Move common extension printing code to new function - X509V3_print_extensions(). Reorganise OCSP print routines and - implement some needed OCSP ASN1 functions. Add OCSP extensions. - [Steve Henson] - - *) New function X509_signature_print() to remove duplication in some - print routines. - [Steve Henson] - - *) Add a special meaning when SET OF and SEQUENCE OF flags are both - set (this was treated exactly the same as SET OF previously). This - is used to reorder the STACK representing the structure to match the - encoding. This will be used to get round a problem where a PKCS7 - structure which was signed could not be verified because the STACK - order did not reflect the encoded order. - [Steve Henson] - - *) Reimplement the OCSP ASN1 module using the new code. - [Steve Henson] - - *) Update the X509V3 code to permit the use of an ASN1_ITEM structure - for its ASN1 operations. The old style function pointers still exist - for now but they will eventually go away. - [Steve Henson] - - *) Merge in replacement ASN1 code from the ASN1 branch. This almost - completely replaces the old ASN1 functionality with a table driven - encoder and decoder which interprets an ASN1_ITEM structure describing - the ASN1 module. Compatibility with the existing ASN1 API (i2d,d2i) is - largely maintained. Almost all of the old asn1_mac.h macro based ASN1 - has also been converted to the new form. - [Steve Henson] - - *) Change BN_mod_exp_recp so that negative moduli are tolerated - (the sign is ignored). Similarly, ignore the sign in BN_MONT_CTX_set - so that BN_mod_exp_mont and BN_mod_exp_mont_word work - for negative moduli. - [Bodo Moeller] - - *) Fix BN_uadd and BN_usub: Always return non-negative results instead - of not touching the result's sign bit. - [Bodo Moeller] - - *) BN_div bugfix: If the result is 0, the sign (res->neg) must not be - set. - [Bodo Moeller] - - *) Changed the LHASH code to use prototypes for callbacks, and created - macros to declare and implement thin (optionally static) functions - that provide type-safety and avoid function pointer casting for the - type-specific callbacks. - [Geoff Thorpe] - - *) Added Kerberos Cipher Suites to be used with TLS, as written in - RFC 2712. - [Veers Staats , - Jeffrey Altman , via Richard Levitte] - - *) Reformat the FAQ so the different questions and answers can be divided - in sections depending on the subject. - [Richard Levitte] - - *) Have the zlib compression code load ZLIB.DLL dynamically under - Windows. - [Richard Levitte] - - *) New function BN_mod_sqrt for computing square roots modulo a prime - (using the probabilistic Tonelli-Shanks algorithm unless - p == 3 (mod 4) or p == 5 (mod 8), which are cases that can - be handled deterministically). - [Lenka Fibikova , Bodo Moeller] - - *) Make BN_mod_inverse faster by explicitly handling small quotients - in the Euclid loop. (Speed gain about 20% for small moduli [256 or - 512 bits], about 30% for larger ones [1024 or 2048 bits].) - [Bodo Moeller] - - *) New function BN_kronecker. - [Bodo Moeller] - - *) Fix BN_gcd so that it works on negative inputs; the result is - positive unless both parameters are zero. - Previously something reasonably close to an infinite loop was - possible because numbers could be growing instead of shrinking - in the implementation of Euclid's algorithm. - [Bodo Moeller] - - *) Fix BN_is_word() and BN_is_one() macros to take into account the - sign of the number in question. - - Fix BN_is_word(a,w) to work correctly for w == 0. - - The old BN_is_word(a,w) macro is now called BN_abs_is_word(a,w) - because its test if the absolute value of 'a' equals 'w'. - Note that BN_abs_is_word does *not* handle w == 0 reliably; - it exists mostly for use in the implementations of BN_is_zero(), - BN_is_one(), and BN_is_word(). - [Bodo Moeller] - - *) New function BN_swap. - [Bodo Moeller] - - *) Use BN_nnmod instead of BN_mod in crypto/bn/bn_exp.c so that - the exponentiation functions are more likely to produce reasonable - results on negative inputs. - [Bodo Moeller] - - *) Change BN_mod_mul so that the result is always non-negative. - Previously, it could be negative if one of the factors was negative; - I don't think anyone really wanted that behaviour. - [Bodo Moeller] - - *) Move BN_mod_... functions into new file crypto/bn/bn_mod.c - (except for exponentiation, which stays in crypto/bn/bn_exp.c, - and BN_mod_mul_reciprocal, which stays in crypto/bn/bn_recp.c) - and add new functions: - - BN_nnmod - BN_mod_sqr - BN_mod_add - BN_mod_add_quick - BN_mod_sub - BN_mod_sub_quick - BN_mod_lshift1 - BN_mod_lshift1_quick - BN_mod_lshift - BN_mod_lshift_quick - - These functions always generate non-negative results. - - BN_nnmod otherwise is like BN_mod (if BN_mod computes a remainder r - such that |m| < r < 0, BN_nnmod will output rem + |m| instead). - - BN_mod_XXX_quick(r, a, [b,] m) generates the same result as - BN_mod_XXX(r, a, [b,] m, ctx), but requires that a [and b] - be reduced modulo m. - [Lenka Fibikova , Bodo Moeller] - -#if 0 - The following entry accidentally appeared in the CHANGES file - distributed with OpenSSL 0.9.7. The modifications described in - it do *not* apply to OpenSSL 0.9.7. - - *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there - was actually never needed) and in BN_mul(). The removal in BN_mul() - required a small change in bn_mul_part_recursive() and the addition - of the functions bn_cmp_part_words(), bn_sub_part_words() and - bn_add_part_words(), which do the same thing as bn_cmp_words(), - bn_sub_words() and bn_add_words() except they take arrays with - differing sizes. - [Richard Levitte] -#endif - - *) In 'openssl passwd', verify passwords read from the terminal - unless the '-salt' option is used (which usually means that - verification would just waste user's time since the resulting - hash is going to be compared with some given password hash) - or the new '-noverify' option is used. - - This is an incompatible change, but it does not affect - non-interactive use of 'openssl passwd' (passwords on the command - line, '-stdin' option, '-in ...' option) and thus should not - cause any problems. - [Bodo Moeller] - - *) Remove all references to RSAref, since there's no more need for it. - [Richard Levitte] - - *) Make DSO load along a path given through an environment variable - (SHLIB_PATH) with shl_load(). - [Richard Levitte] - - *) Constify the ENGINE code as a result of BIGNUM constification. - Also constify the RSA code and most things related to it. In a - few places, most notable in the depth of the ASN.1 code, ugly - casts back to non-const were required (to be solved at a later - time) - [Richard Levitte] - - *) Make it so the openssl application has all engines loaded by default. - [Richard Levitte] - - *) Constify the BIGNUM routines a little more. - [Richard Levitte] - - *) Add the following functions: - - ENGINE_load_cswift() - ENGINE_load_chil() - ENGINE_load_atalla() - ENGINE_load_nuron() - ENGINE_load_builtin_engines() - - That way, an application can itself choose if external engines that - are built-in in OpenSSL shall ever be used or not. The benefit is - that applications won't have to be linked with libdl or other dso - libraries unless it's really needed. - - Changed 'openssl engine' to load all engines on demand. - Changed the engine header files to avoid the duplication of some - declarations (they differed!). - [Richard Levitte] - - *) 'openssl engine' can now list capabilities. - [Richard Levitte] - - *) Better error reporting in 'openssl engine'. - [Richard Levitte] - - *) Never call load_dh_param(NULL) in s_server. - [Bodo Moeller] - - *) Add engine application. It can currently list engines by name and - identity, and test if they are actually available. - [Richard Levitte] - - *) Improve RPM specification file by forcing symbolic linking and making - sure the installed documentation is also owned by root.root. - [Damien Miller ] - - *) Give the OpenSSL applications more possibilities to make use of - keys (public as well as private) handled by engines. - [Richard Levitte] - - *) Add OCSP code that comes from CertCo. - [Richard Levitte] - - *) Add VMS support for the Rijndael code. - [Richard Levitte] - - *) Added untested support for Nuron crypto accelerator. - [Ben Laurie] - - *) Add support for external cryptographic devices. This code was - previously distributed separately as the "engine" branch. - [Geoff Thorpe, Richard Levitte] - - *) Rework the filename-translation in the DSO code. It is now possible to - have far greater control over how a "name" is turned into a filename - depending on the operating environment and any oddities about the - different shared library filenames on each system. - [Geoff Thorpe] - - *) Support threads on FreeBSD-elf in Configure. - [Richard Levitte] - - *) Fix for SHA1 assembly problem with MASM: it produces - warnings about corrupt line number information when assembling - with debugging information. This is caused by the overlapping - of two sections. - [Bernd Matthes , Steve Henson] - - *) NCONF changes. - NCONF_get_number() has no error checking at all. As a replacement, - NCONF_get_number_e() is defined (_e for "error checking") and is - promoted strongly. The old NCONF_get_number is kept around for - binary backward compatibility. - Make it possible for methods to load from something other than a BIO, - by providing a function pointer that is given a name instead of a BIO. - For example, this could be used to load configuration data from an - LDAP server. - [Richard Levitte] - - *) Fix for non blocking accept BIOs. Added new I/O special reason - BIO_RR_ACCEPT to cover this case. Previously use of accept BIOs - with non blocking I/O was not possible because no retry code was - implemented. Also added new SSL code SSL_WANT_ACCEPT to cover - this case. - [Steve Henson] - - *) Added the beginnings of Rijndael support. - [Ben Laurie] - - *) Fix for bug in DirectoryString mask setting. Add support for - X509_NAME_print_ex() in 'req' and X509_print_ex() function - to allow certificate printing to more controllable, additional - 'certopt' option to 'x509' to allow new printing options to be - set. - [Steve Henson] - - *) Clean old EAY MD5 hack from e_os.h. - [Richard Levitte] - - Changes between 0.9.6l and 0.9.6m [17 Mar 2004] - - *) Fix null-pointer assignment in do_change_cipher_spec() revealed - by using the Codenomicon TLS Test Tool (CVE-2004-0079) - [Joe Orton, Steve Henson] - - Changes between 0.9.6k and 0.9.6l [04 Nov 2003] - - *) Fix additional bug revealed by the NISCC test suite: - - Stop bug triggering large recursion when presented with - certain ASN.1 tags (CVE-2003-0851) - [Steve Henson] - - Changes between 0.9.6j and 0.9.6k [30 Sep 2003] - - *) Fix various bugs revealed by running the NISCC test suite: - - Stop out of bounds reads in the ASN1 code when presented with - invalid tags (CVE-2003-0543 and CVE-2003-0544). - - If verify callback ignores invalid public key errors don't try to check - certificate signature with the NULL public key. - - [Steve Henson] - - *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate - if the server requested one: as stated in TLS 1.0 and SSL 3.0 - specifications. - [Steve Henson] - - *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional - extra data after the compression methods not only for TLS 1.0 - but also for SSL 3.0 (as required by the specification). - [Bodo Moeller; problem pointed out by Matthias Loepfe] - - *) Change X509_certificate_type() to mark the key as exported/exportable - when it's 512 *bits* long, not 512 bytes. - [Richard Levitte] - - Changes between 0.9.6i and 0.9.6j [10 Apr 2003] - - *) Countermeasure against the Klima-Pokorny-Rosa extension of - Bleichbacher's attack on PKCS #1 v1.5 padding: treat - a protocol version number mismatch like a decryption error - in ssl3_get_client_key_exchange (ssl/s3_srvr.c). - [Bodo Moeller] - - *) Turn on RSA blinding by default in the default implementation - to avoid a timing attack. Applications that don't want it can call - RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING. - They would be ill-advised to do so in most cases. - [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller] - - *) Change RSA blinding code so that it works when the PRNG is not - seeded (in this case, the secret RSA exponent is abused as - an unpredictable seed -- if it is not unpredictable, there - is no point in blinding anyway). Make RSA blinding thread-safe - by remembering the creator's thread ID in rsa->blinding and - having all other threads use local one-time blinding factors - (this requires more computation than sharing rsa->blinding, but - avoids excessive locking; and if an RSA object is not shared - between threads, blinding will still be very fast). - [Bodo Moeller] - - Changes between 0.9.6h and 0.9.6i [19 Feb 2003] - - *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked - via timing by performing a MAC computation even if incorrect - block cipher padding has been found. This is a countermeasure - against active attacks where the attacker has to distinguish - between bad padding and a MAC verification error. (CVE-2003-0078) - - [Bodo Moeller; problem pointed out by Brice Canvel (EPFL), - Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and - Martin Vuagnoux (EPFL, Ilion)] - - 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 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 - be read through on certain media, for example a swap space on disk. - [Geoff Thorpe] - - *) Bugfix: client side session caching did not work with external caching, - because the session->cipher setting was not restored when reloading - from the external cache. This problem was masked, when - SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG (part of SSL_OP_ALL) was set. - (Found by Steve Haslam .) - [Lutz Jaenicke] - - *) Fix client_certificate (ssl/s2_clnt.c): The permissible total - length of the REQUEST-CERTIFICATE message is 18 .. 34, not 17 .. 33. - [Zeev Lieber ] - - *) Undo an undocumented change introduced in 0.9.6e which caused - repeated calls to OpenSSL_add_all_ciphers() and - OpenSSL_add_all_digests() to be ignored, even after calling - EVP_cleanup(). - [Richard Levitte] - - *) Change the default configuration reader to deal with last line not - being properly terminated. - [Richard Levitte] - - *) Change X509_NAME_cmp() so it applies the special rules on handling - DN values that are of type PrintableString, as well as RDNs of type - emailAddress where the value has the type ia5String. - [stefank@valicert.com via Richard Levitte] - - *) Add a SSL_SESS_CACHE_NO_INTERNAL_STORE flag to take over half - the job SSL_SESS_CACHE_NO_INTERNAL_LOOKUP was inconsistently - doing, define a new flag (SSL_SESS_CACHE_NO_INTERNAL) to be - the bitwise-OR of the two for use by the majority of applications - wanting this behaviour, and update the docs. The documented - behaviour and actual behaviour were inconsistent and had been - changing anyway, so this is more a bug-fix than a behavioural - change. - [Geoff Thorpe, diagnosed by Nadav Har'El] - - *) Don't impose a 16-byte length minimum on session IDs in ssl/s3_clnt.c - (the SSL 3.0 and TLS 1.0 specifications allow any length up to 32 bytes). - [Bodo Moeller] - - *) Fix initialization code race conditions in - SSLv23_method(), SSLv23_client_method(), SSLv23_server_method(), - SSLv2_method(), SSLv2_client_method(), SSLv2_server_method(), - SSLv3_method(), SSLv3_client_method(), SSLv3_server_method(), - TLSv1_method(), TLSv1_client_method(), TLSv1_server_method(), - ssl2_get_cipher_by_char(), - ssl3_get_cipher_by_char(). - [Patrick McCormick , Bodo Moeller] - - *) Reorder cleanup sequence in SSL_CTX_free(): only remove the ex_data after - the cached sessions are flushed, as the remove_cb() might use ex_data - contents. Bug found by Sam Varshavchik - (see [openssl.org #212]). - [Geoff Thorpe, Lutz Jaenicke] - - *) Fix typo in OBJ_txt2obj which incorrectly passed the content - length, instead of the encoding length to d2i_ASN1_OBJECT. - [Steve Henson] - - Changes between 0.9.6f and 0.9.6g [9 Aug 2002] - - *) [In 0.9.6g-engine release:] - Fix crypto/engine/vendor_defns/cswift.h for WIN32 (use '_stdcall'). - [Lynn Gazis ] - - Changes between 0.9.6e and 0.9.6f [8 Aug 2002] - - *) Fix ASN1 checks. Check for overflow by comparing with LONG_MAX - and get fix the header length calculation. - [Florian Weimer , - Alon Kantor (and others), - Steve Henson] - - *) Use proper error handling instead of 'assertions' in buffer - overflow checks added in 0.9.6e. This prevents DoS (the - assertions could call abort()). - [Arne Ansper , Bodo Moeller] - - Changes between 0.9.6d and 0.9.6e [30 Jul 2002] - - *) Add various sanity checks to asn1_get_length() to reject - the ASN1 length bytes if they exceed sizeof(long), will appear - negative or the content length exceeds the length of the - supplied buffer. - [Steve Henson, Adi Stav , James Yonan ] - - *) Fix cipher selection routines: ciphers without encryption had no flags - for the cipher strength set and where therefore not handled correctly - by the selection routines (PR #130). - [Lutz Jaenicke] - - *) Fix EVP_dsa_sha macro. - [Nils Larsch] - - *) New option - SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS - for disabling the SSL 3.0/TLS 1.0 CBC vulnerability countermeasure - that was added in OpenSSL 0.9.6d. - - As the countermeasure turned out to be incompatible with some - broken SSL implementations, the new option is part of SSL_OP_ALL. - SSL_OP_ALL is usually employed when compatibility with weird SSL - implementations is desired (e.g. '-bugs' option to 's_client' and - 's_server'), so the new option is automatically set in many - applications. - [Bodo Moeller] - - *) Changes in security patch: - - Changes marked "(CHATS)" were sponsored by the Defense Advanced - Research Projects Agency (DARPA) and Air Force Research Laboratory, - Air Force Materiel Command, USAF, under agreement number - F30602-01-2-0537. - - *) Add various sanity checks to asn1_get_length() to reject - the ASN1 length bytes if they exceed sizeof(long), will appear - negative or the content length exceeds the length of the - supplied buffer. (CVE-2002-0659) - [Steve Henson, Adi Stav , James Yonan ] - - *) Assertions for various potential buffer overflows, not known to - happen in practice. - [Ben Laurie (CHATS)] - - *) Various temporary buffers to hold ASCII versions of integers were - too small for 64 bit platforms. (CVE-2002-0655) - [Matthew Byng-Maddick and Ben Laurie (CHATS)> - - *) Remote buffer overflow in SSL3 protocol - an attacker could - supply an oversized session ID to a client. (CVE-2002-0656) - [Ben Laurie (CHATS)] - - *) Remote buffer overflow in SSL2 protocol - an attacker could - supply an oversized client master key. (CVE-2002-0656) - [Ben Laurie (CHATS)] - - Changes between 0.9.6c and 0.9.6d [9 May 2002] - - *) Fix crypto/asn1/a_sign.c so that 'parameters' is omitted (not - encoded as NULL) with id-dsa-with-sha1. - [Nils Larsch ; problem pointed out by Bodo Moeller] - - *) Check various X509_...() return values in apps/req.c. - [Nils Larsch ] - - *) Fix BASE64 decode (EVP_DecodeUpdate) for data with CR/LF ended lines: - an end-of-file condition would erroneously be flagged, when the CRLF - was just at the end of a processed block. The bug was discovered when - processing data through a buffering memory BIO handing the data to a - BASE64-decoding BIO. Bug fund and patch submitted by Pavel Tsekov - and Nedelcho Stanev. - [Lutz Jaenicke] - - *) Implement a countermeasure against a vulnerability recently found - in CBC ciphersuites in SSL 3.0/TLS 1.0: Send an empty fragment - before application data chunks to avoid the use of known IVs - with data potentially chosen by the attacker. - [Bodo Moeller] - - *) Fix length checks in ssl3_get_client_hello(). - [Bodo Moeller] - - *) TLS/SSL library bugfix: use s->s3->in_read_app_data differently - to prevent ssl3_read_internal() from incorrectly assuming that - ssl3_read_bytes() found application data while handshake - processing was enabled when in fact s->s3->in_read_app_data was - merely automatically cleared during the initial handshake. - [Bodo Moeller; problem pointed out by Arne Ansper ] - - *) Fix object definitions for Private and Enterprise: they were not - recognized in their shortname (=lowercase) representation. Extend - obj_dat.pl to issue an error when using undefined keywords instead - of silently ignoring the problem (Svenning Sorensen - ). - [Lutz Jaenicke] - - *) Fix DH_generate_parameters() so that it works for 'non-standard' - generators, i.e. generators other than 2 and 5. (Previously, the - code did not properly initialise the 'add' and 'rem' values to - BN_generate_prime().) - - In the new general case, we do not insist that 'generator' is - actually a primitive root: This requirement is rather pointless; - a generator of the order-q subgroup is just as good, if not - better. - [Bodo Moeller] - - *) Map new X509 verification errors to alerts. Discovered and submitted by - Tom Wu . - [Lutz Jaenicke] - - *) Fix ssl3_pending() (ssl/s3_lib.c) to prevent SSL_pending() from - returning non-zero before the data has been completely received - when using non-blocking I/O. - [Bodo Moeller; problem pointed out by John Hughes] - - *) Some of the ciphers missed the strength entry (SSL_LOW etc). - [Ben Laurie, Lutz Jaenicke] - - *) Fix bug in SSL_clear(): bad sessions were not removed (found by - Yoram Zahavi ). - [Lutz Jaenicke] - - *) Add information about CygWin 1.3 and on, and preserve proper - configuration for the versions before that. - [Corinna Vinschen and Richard Levitte] - - *) Make removal from session cache (SSL_CTX_remove_session()) more robust: - check whether we deal with a copy of a session and do not delete from - the cache in this case. Problem reported by "Izhar Shoshani Levi" - . - [Lutz Jaenicke] - - *) Do not store session data into the internal session cache, if it - is never intended to be looked up (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP - flag is set). Proposed by Aslam . - [Lutz Jaenicke] - - *) Have ASN1_BIT_STRING_set_bit() really clear a bit when the requested - value is 0. - [Richard Levitte] - - *) [In 0.9.6d-engine release:] - Fix a crashbug and a logic bug in hwcrhk_load_pubkey(). - [Toomas Kiisk via Richard Levitte] - - *) Add the configuration target linux-s390x. - [Neale Ferguson via Richard Levitte] - - *) The earlier bugfix for the SSL3_ST_SW_HELLO_REQ_C case of - ssl3_accept (ssl/s3_srvr.c) incorrectly used a local flag - variable as an indication that a ClientHello message has been - received. As the flag value will be lost between multiple - invocations of ssl3_accept when using non-blocking I/O, the - function may not be aware that a handshake has actually taken - place, thus preventing a new session from being added to the - session cache. - - To avoid this problem, we now set s->new_session to 2 instead of - using a local variable. - [Lutz Jaenicke, Bodo Moeller] - - *) Bugfix: Return -1 from ssl3_get_server_done (ssl3/s3_clnt.c) - if the SSL_R_LENGTH_MISMATCH error is detected. - [Geoff Thorpe, Bodo Moeller] - - *) New 'shared_ldflag' column in Configure platform table. - [Richard Levitte] - - *) Fix EVP_CIPHER_mode macro. - ["Dan S. Camper" ] - - *) Fix ssl3_read_bytes (ssl/s3_pkt.c): To ignore messages of unknown - type, we must throw them away by setting rr->length to 0. - [D P Chang ] - - Changes between 0.9.6b and 0.9.6c [21 dec 2001] - - *) Fix BN_rand_range bug pointed out by Dominikus Scherkl - . (The previous implementation - worked incorrectly for those cases where range = 10..._2 and - 3*range is two bits longer than range.) - [Bodo Moeller] - - *) Only add signing time to PKCS7 structures if it is not already - present. - [Steve Henson] - - *) Fix crypto/objects/objects.h: "ld-ce" should be "id-ce", - OBJ_ld_ce should be OBJ_id_ce. - Also some ip-pda OIDs in crypto/objects/objects.txt were - incorrect (cf. RFC 3039). - [Matt Cooper, Frederic Giudicelli, Bodo Moeller] - - *) Release CRYPTO_LOCK_DYNLOCK when CRYPTO_destroy_dynlockid() - returns early because it has nothing to do. - [Andy Schneider ] - - *) [In 0.9.6c-engine release:] - Fix mutex callback return values in crypto/engine/hw_ncipher.c. - [Andy Schneider ] - - *) [In 0.9.6c-engine release:] - Add support for Cryptographic Appliance's keyserver technology. - (Use engine 'keyclient') - [Cryptographic Appliances and Geoff Thorpe] - - *) Add a configuration entry for OS/390 Unix. The C compiler 'c89' - is called via tools/c89.sh because arguments have to be - rearranged (all '-L' options must appear before the first object - modules). - [Richard Shapiro ] - - *) [In 0.9.6c-engine release:] - Add support for Broadcom crypto accelerator cards, backported - from 0.9.7. - [Broadcom, Nalin Dahyabhai , Mark Cox] - - *) [In 0.9.6c-engine release:] - Add support for SureWare crypto accelerator cards from - Baltimore Technologies. (Use engine 'sureware') - [Baltimore Technologies and Mark Cox] - - *) [In 0.9.6c-engine release:] - Add support for crypto accelerator cards from Accelerated - Encryption Processing, www.aep.ie. (Use engine 'aep') - [AEP Inc. and Mark Cox] - - *) Add a configuration entry for gcc on UnixWare. - [Gary Benson ] - - *) Change ssl/s2_clnt.c and ssl/s2_srvr.c so that received handshake - messages are stored in a single piece (fixed-length part and - variable-length part combined) and fix various bugs found on the way. - [Bodo Moeller] - - *) Disable caching in BIO_gethostbyname(), directly use gethostbyname() - instead. BIO_gethostbyname() does not know what timeouts are - appropriate, so entries would stay in cache even when they have - become invalid. - [Bodo Moeller; problem pointed out by Rich Salz - - *) Change ssl23_get_client_hello (ssl/s23_srvr.c) behaviour when - faced with a pathologically small ClientHello fragment that does - not contain client_version: Instead of aborting with an error, - simply choose the highest available protocol version (i.e., - TLS 1.0 unless it is disabled). In practice, ClientHello - messages are never sent like this, but this change gives us - strictly correct behaviour at least for TLS. - [Bodo Moeller] - - *) Fix SSL handshake functions and SSL_clear() such that SSL_clear() - never resets s->method to s->ctx->method when called from within - one of the SSL handshake functions. - [Bodo Moeller; problem pointed out by Niko Baric] - - *) In ssl3_get_client_hello (ssl/s3_srvr.c), generate a fatal alert - (sent using the client's version number) if client_version is - smaller than the protocol version in use. Also change - ssl23_get_client_hello (ssl/s23_srvr.c) to select TLS 1.0 if - the client demanded SSL 3.0 but only TLS 1.0 is enabled; then - the client will at least see that alert. - [Bodo Moeller] - - *) Fix ssl3_get_message (ssl/s3_both.c) to handle message fragmentation - correctly. - [Bodo Moeller] - - *) Avoid infinite loop in ssl3_get_message (ssl/s3_both.c) if a - client receives HelloRequest while in a handshake. - [Bodo Moeller; bug noticed by Andy Schneider ] - - *) Bugfix in ssl3_accept (ssl/s3_srvr.c): Case SSL3_ST_SW_HELLO_REQ_C - should end in 'break', not 'goto end' which circumvents various - cleanups done in state SSL_ST_OK. But session related stuff - must be disabled for SSL_ST_OK in the case that we just sent a - HelloRequest. - - Also avoid some overhead by not calling ssl_init_wbio_buffer() - before just sending a HelloRequest. - [Bodo Moeller, Eric Rescorla ] - - *) Fix ssl/s3_enc.c, ssl/t1_enc.c and ssl/s3_pkt.c so that we don't - reveal whether illegal block cipher padding was found or a MAC - verification error occurred. (Neither SSLerr() codes nor alerts - are directly visible to potential attackers, but the information - may leak via logfiles.) - - Similar changes are not required for the SSL 2.0 implementation - because the number of padding bytes is sent in clear for SSL 2.0, - and the extra bytes are just ignored. However ssl/s2_pkt.c - failed to verify that the purported number of padding bytes is in - the legal range. - [Bodo Moeller] - - *) Add OpenUNIX-8 support including shared libraries - (Boyd Lynn Gerber ). - [Lutz Jaenicke] - - *) Improve RSA_padding_check_PKCS1_OAEP() check again to avoid - 'wristwatch attack' using huge encoding parameters (cf. - James H. Manger's CRYPTO 2001 paper). Note that the - RSA_PKCS1_OAEP_PADDING case of RSA_private_decrypt() does not use - encoding parameters and hence was not vulnerable. - [Bodo Moeller] - - *) BN_sqr() bug fix. - [Ulf Möller, reported by Jim Ellis ] - - *) Rabin-Miller test analyses assume uniformly distributed witnesses, - so use BN_pseudo_rand_range() instead of using BN_pseudo_rand() - followed by modular reduction. - [Bodo Moeller; pointed out by Adam Young ] - - *) Add BN_pseudo_rand_range() with obvious functionality: BN_rand_range() - equivalent based on BN_pseudo_rand() instead of BN_rand(). - [Bodo Moeller] - - *) s3_srvr.c: allow sending of large client certificate lists (> 16 kB). - This function was broken, as the check for a new client hello message - to handle SGC did not allow these large messages. - (Tracked down by "Douglas E. Engert" .) - [Lutz Jaenicke] - - *) Add alert descriptions for TLSv1 to SSL_alert_desc_string[_long](). - [Lutz Jaenicke] - - *) Fix buggy behaviour of BIO_get_num_renegotiates() and BIO_ctrl() - for BIO_C_GET_WRITE_BUF_SIZE ("Stephen Hinton" ). - [Lutz Jaenicke] - - *) Rework the configuration and shared library support for Tru64 Unix. - The configuration part makes use of modern compiler features and - still retains old compiler behavior for those that run older versions - of the OS. The shared library support part includes a variant that - uses the RPATH feature, and is available through the special - configuration target "alpha-cc-rpath", which will never be selected - automatically. - [Tim Mooney via Richard Levitte] - - *) In ssl3_get_key_exchange (ssl/s3_clnt.c), call ssl3_get_message() - with the same message size as in ssl3_get_certificate_request(). - Otherwise, if no ServerKeyExchange message occurs, CertificateRequest - messages might inadvertently be reject as too long. - [Petr Lampa ] - - *) Enhanced support for IA-64 Unix platforms (well, Linux and HP-UX). - [Andy Polyakov] - - *) Modified SSL library such that the verify_callback that has been set - specifically for an SSL object with SSL_set_verify() is actually being - used. Before the change, a verify_callback set with this function was - ignored and the verify_callback() set in the SSL_CTX at the time of - the call was used. New function X509_STORE_CTX_set_verify_cb() introduced - to allow the necessary settings. - [Lutz Jaenicke] - - *) Initialize static variable in crypto/dsa/dsa_lib.c and crypto/dh/dh_lib.c - explicitly to NULL, as at least on Solaris 8 this seems not always to be - done automatically (in contradiction to the requirements of the C - standard). This made problems when used from OpenSSH. - [Lutz Jaenicke] - - *) In OpenSSL 0.9.6a and 0.9.6b, crypto/dh/dh_key.c ignored - dh->length and always used - - BN_rand_range(priv_key, dh->p). - - BN_rand_range() is not necessary for Diffie-Hellman, and this - specific range makes Diffie-Hellman unnecessarily inefficient if - dh->length (recommended exponent length) is much smaller than the - length of dh->p. We could use BN_rand_range() if the order of - the subgroup was stored in the DH structure, but we only have - dh->length. - - So switch back to - - BN_rand(priv_key, l, ...) - - where 'l' is dh->length if this is defined, or BN_num_bits(dh->p)-1 - otherwise. - [Bodo Moeller] - - *) In - - RSA_eay_public_encrypt - RSA_eay_private_decrypt - RSA_eay_private_encrypt (signing) - RSA_eay_public_decrypt (signature verification) - - (default implementations for RSA_public_encrypt, - RSA_private_decrypt, RSA_private_encrypt, RSA_public_decrypt), - always reject numbers >= n. - [Bodo Moeller] - - *) In crypto/rand/md_rand.c, use a new short-time lock CRYPTO_LOCK_RAND2 - to synchronize access to 'locking_thread'. This is necessary on - systems where access to 'locking_thread' (an 'unsigned long' - variable) is not atomic. - [Bodo Moeller] - - *) In crypto/rand/md_rand.c, set 'locking_thread' to current thread's ID - *before* setting the 'crypto_lock_rand' flag. The previous code had - a race condition if 0 is a valid thread ID. - [Travis Vitek ] - - *) Add support for shared libraries under Irix. - [Albert Chin-A-Young ] - - *) Add configuration option to build on Linux on both big-endian and - little-endian MIPS. - [Ralf Baechle ] - - *) Add the possibility to create shared libraries on HP-UX. - [Richard Levitte] - - Changes between 0.9.6a and 0.9.6b [9 Jul 2001] - - *) Change ssleay_rand_bytes (crypto/rand/md_rand.c) - to avoid a SSLeay/OpenSSL PRNG weakness pointed out by - Markku-Juhani O. Saarinen : - PRNG state recovery was possible based on the output of - one PRNG request appropriately sized to gain knowledge on - 'md' followed by enough consecutive 1-byte PRNG requests - to traverse all of 'state'. - - 1. When updating 'md_local' (the current thread's copy of 'md') - during PRNG output generation, hash all of the previous - 'md_local' value, not just the half used for PRNG output. - - 2. Make the number of bytes from 'state' included into the hash - independent from the number of PRNG bytes requested. - - The first measure alone would be sufficient to avoid - Markku-Juhani's attack. (Actually it had never occurred - to me that the half of 'md_local' used for chaining was the - half from which PRNG output bytes were taken -- I had always - assumed that the secret half would be used.) The second - measure makes sure that additional data from 'state' is never - mixed into 'md_local' in small portions; this heuristically - further strengthens the PRNG. - [Bodo Moeller] - - *) Fix crypto/bn/asm/mips3.s. - [Andy Polyakov] - - *) When only the key is given to "enc", the IV is undefined. Print out - an error message in this case. - [Lutz Jaenicke] - - *) Handle special case when X509_NAME is empty in X509 printing routines. - [Steve Henson] - - *) In dsa_do_verify (crypto/dsa/dsa_ossl.c), verify that r and s are - positive and less than q. - [Bodo Moeller] - - *) Don't change *pointer in CRYPTO_add_lock() is add_lock_callback is - used: it isn't thread safe and the add_lock_callback should handle - that itself. - [Paul Rose ] - - *) Verify that incoming data obeys the block size in - ssl3_enc (ssl/s3_enc.c) and tls1_enc (ssl/t1_enc.c). - [Bodo Moeller] - - *) Fix OAEP check. - [Ulf Möller, Bodo Möller] - - *) The countermeasure against Bleichbacher's attack on PKCS #1 v1.5 - RSA encryption was accidentally removed in s3_srvr.c in OpenSSL 0.9.5 - when fixing the server behaviour for backwards-compatible 'client - hello' messages. (Note that the attack is impractical against - SSL 3.0 and TLS 1.0 anyway because length and version checking - means that the probability of guessing a valid ciphertext is - around 2^-40; see section 5 in Bleichenbacher's CRYPTO '98 - paper.) - - Before 0.9.5, the countermeasure (hide the error by generating a - random 'decryption result') did not work properly because - ERR_clear_error() was missing, meaning that SSL_get_error() would - detect the supposedly ignored error. - - Both problems are now fixed. - [Bodo Moeller] - - *) In crypto/bio/bf_buff.c, increase DEFAULT_BUFFER_SIZE to 4096 - (previously it was 1024). - [Bodo Moeller] - - *) Fix for compatibility mode trust settings: ignore trust settings - unless some valid trust or reject settings are present. - [Steve Henson] - - *) Fix for blowfish EVP: its a variable length cipher. - [Steve Henson] - - *) Fix various bugs related to DSA S/MIME verification. Handle missing - parameters in DSA public key structures and return an error in the - DSA routines if parameters are absent. - [Steve Henson] - - *) In versions up to 0.9.6, RAND_file_name() resorted to file ".rnd" - in the current directory if neither $RANDFILE nor $HOME was set. - RAND_file_name() in 0.9.6a returned NULL in this case. This has - caused some confusion to Windows users who haven't defined $HOME. - Thus RAND_file_name() is changed again: e_os.h can define a - DEFAULT_HOME, which will be used if $HOME is not set. - For Windows, we use "C:"; on other platforms, we still require - environment variables. - - *) Move 'if (!initialized) RAND_poll()' into regions protected by - CRYPTO_LOCK_RAND. This is not strictly necessary, but avoids - having multiple threads call RAND_poll() concurrently. - [Bodo Moeller] - - *) In crypto/rand/md_rand.c, replace 'add_do_not_lock' flag by a - combination of a flag and a thread ID variable. - Otherwise while one thread is in ssleay_rand_bytes (which sets the - flag), *other* threads can enter ssleay_add_bytes without obeying - the CRYPTO_LOCK_RAND lock (and may even illegally release the lock - that they do not hold after the first thread unsets add_do_not_lock). - [Bodo Moeller] - - *) Change bctest again: '-x' expressions are not available in all - versions of 'test'. - [Bodo Moeller] - - Changes between 0.9.6 and 0.9.6a [5 Apr 2001] - - *) Fix a couple of memory leaks in PKCS7_dataDecode() - [Steve Henson, reported by Heyun Zheng ] - - *) Change Configure and Makefiles to provide EXE_EXT, which will contain - the default extension for executables, if any. Also, make the perl - scripts that use symlink() to test if it really exists and use "cp" - if it doesn't. All this made OpenSSL compilable and installable in - CygWin. - [Richard Levitte] - - *) Fix for asn1_GetSequence() for indefinite length constructed data. - If SEQUENCE is length is indefinite just set c->slen to the total - amount of data available. - [Steve Henson, reported by shige@FreeBSD.org] - [This change does not apply to 0.9.7.] - - *) Change bctest to avoid here-documents inside command substitution - (workaround for FreeBSD /bin/sh bug). - For compatibility with Ultrix, avoid shell functions (introduced - in the bctest version that searches along $PATH). - [Bodo Moeller] - - *) Rename 'des_encrypt' to 'des_encrypt1'. This avoids the clashes - with des_encrypt() defined on some operating systems, like Solaris - and UnixWare. - [Richard Levitte] - - *) Check the result of RSA-CRT (see D. Boneh, R. DeMillo, R. Lipton: - On the Importance of Eliminating Errors in Cryptographic - Computations, J. Cryptology 14 (2001) 2, 101-119, - http://theory.stanford.edu/~dabo/papers/faults.ps.gz). - [Ulf Moeller] - - *) MIPS assembler BIGNUM division bug fix. - [Andy Polyakov] - - *) Disabled incorrect Alpha assembler code. - [Richard Levitte] - - *) Fix PKCS#7 decode routines so they correctly update the length - after reading an EOC for the EXPLICIT tag. - [Steve Henson] - [This change does not apply to 0.9.7.] - - *) Fix bug in PKCS#12 key generation routines. This was triggered - if a 3DES key was generated with a 0 initial byte. Include - PKCS12_BROKEN_KEYGEN compilation option to retain the old - (but broken) behaviour. - [Steve Henson] - - *) Enhance bctest to search for a working bc along $PATH and print - it when found. - [Tim Rice via Richard Levitte] - - *) Fix memory leaks in err.c: free err_data string if necessary; - don't write to the wrong index in ERR_set_error_data. - [Bodo Moeller] - - *) Implement ssl23_peek (analogous to ssl23_read), which previously - did not exist. - [Bodo Moeller] - - *) Replace rdtsc with _emit statements for VC++ version 5. - [Jeremy Cooper ] - - *) Make it possible to reuse SSLv2 sessions. - [Richard Levitte] - - *) In copy_email() check for >= 0 as a return value for - X509_NAME_get_index_by_NID() since 0 is a valid index. - [Steve Henson reported by Massimiliano Pala ] - - *) Avoid coredump with unsupported or invalid public keys by checking if - X509_get_pubkey() fails in PKCS7_verify(). Fix memory leak when - PKCS7_verify() fails with non detached data. - [Steve Henson] - - *) Don't use getenv in library functions when run as setuid/setgid. - New function OPENSSL_issetugid(). - [Ulf Moeller] - - *) Avoid false positives in memory leak detection code (crypto/mem_dbg.c) - due to incorrect handling of multi-threading: - - 1. Fix timing glitch in the MemCheck_off() portion of CRYPTO_mem_ctrl(). - - 2. Fix logical glitch in is_MemCheck_on() aka CRYPTO_is_mem_check_on(). - - 3. Count how many times MemCheck_off() has been called so that - nested use can be treated correctly. This also avoids - inband-signalling in the previous code (which relied on the - assumption that thread ID 0 is impossible). - [Bodo Moeller] - - *) Add "-rand" option also to s_client and s_server. - [Lutz Jaenicke] - - *) Fix CPU detection on Irix 6.x. - [Kurt Hockenbury and - "Bruce W. Forsberg" ] - - *) Fix X509_NAME bug which produced incorrect encoding if X509_NAME - was empty. - [Steve Henson] - [This change does not apply to 0.9.7.] - - *) Use the cached encoding of an X509_NAME structure rather than - copying it. This is apparently the reason for the libsafe "errors" - but the code is actually correct. - [Steve Henson] - - *) Add new function BN_rand_range(), and fix DSA_sign_setup() to prevent - Bleichenbacher's DSA attack. - Extend BN_[pseudo_]rand: As before, top=1 forces the highest two bits - to be set and top=0 forces the highest bit to be set; top=-1 is new - and leaves the highest bit random. - [Ulf Moeller, Bodo Moeller] - - *) In the NCONF_...-based implementations for CONF_... queries - (crypto/conf/conf_lib.c), if the input LHASH is NULL, avoid using - a temporary CONF structure with the data component set to NULL - (which gives segmentation faults in lh_retrieve). - Instead, use NULL for the CONF pointer in CONF_get_string and - CONF_get_number (which may use environment variables) and directly - return NULL from CONF_get_section. - [Bodo Moeller] - - *) Fix potential buffer overrun for EBCDIC. - [Ulf Moeller] - - *) Tolerate nonRepudiation as being valid for S/MIME signing and certSign - keyUsage if basicConstraints absent for a CA. - [Steve Henson] - - *) Make SMIME_write_PKCS7() write mail header values with a format that - is more generally accepted (no spaces before the semicolon), since - some programs can't parse those values properly otherwise. Also make - sure BIO's that break lines after each write do not create invalid - headers. - [Richard Levitte] - - *) Make the CRL encoding routines work with empty SEQUENCE OF. The - macros previously used would not encode an empty SEQUENCE OF - and break the signature. - [Steve Henson] - [This change does not apply to 0.9.7.] - - *) Zero the premaster secret after deriving the master secret in - DH ciphersuites. - [Steve Henson] - - *) Add some EVP_add_digest_alias registrations (as found in - OpenSSL_add_all_digests()) to SSL_library_init() - aka OpenSSL_add_ssl_algorithms(). This provides improved - compatibility with peers using X.509 certificates - with unconventional AlgorithmIdentifier OIDs. - [Bodo Moeller] - - *) Fix for Irix with NO_ASM. - ["Bruce W. Forsberg" ] - - *) ./config script fixes. - [Ulf Moeller, Richard Levitte] - - *) Fix 'openssl passwd -1'. - [Bodo Moeller] - - *) Change PKCS12_key_gen_asc() so it can cope with non null - terminated strings whose length is passed in the passlen - parameter, for example from PEM callbacks. This was done - by adding an extra length parameter to asc2uni(). - [Steve Henson, reported by ] - - *) Fix C code generated by 'openssl dsaparam -C': If a BN_bin2bn - call failed, free the DSA structure. - [Bodo Moeller] - - *) Fix to uni2asc() to cope with zero length Unicode strings. - These are present in some PKCS#12 files. - [Steve Henson] - - *) Increase s2->wbuf allocation by one byte in ssl2_new (ssl/s2_lib.c). - Otherwise do_ssl_write (ssl/s2_pkt.c) will write beyond buffer limits - when writing a 32767 byte record. - [Bodo Moeller; problem reported by Eric Day ] - - *) In RSA_eay_public_{en,ed}crypt and RSA_eay_mod_exp (rsa_eay.c), - obtain lock CRYPTO_LOCK_RSA before setting rsa->_method_mod_{n,p,q}. - - (RSA objects have a reference count access to which is protected - by CRYPTO_LOCK_RSA [see rsa_lib.c, s3_srvr.c, ssl_cert.c, ssl_rsa.c], - so they are meant to be shared between threads.) - [Bodo Moeller, Geoff Thorpe; original patch submitted by - "Reddie, Steven" ] - - *) Fix a deadlock in CRYPTO_mem_leaks(). - [Bodo Moeller] - - *) Use better test patterns in bntest. - [Ulf Möller] - - *) rand_win.c fix for Borland C. - [Ulf Möller] - - *) BN_rshift bugfix for n == 0. - [Bodo Moeller] - - *) Add a 'bctest' script that checks for some known 'bc' bugs - so that 'make test' does not abort just because 'bc' is broken. - [Bodo Moeller] - - *) Store verify_result within SSL_SESSION also for client side to - avoid potential security hole. (Re-used sessions on the client side - always resulted in verify_result==X509_V_OK, not using the original - result of the server certificate verification.) - [Lutz Jaenicke] - - *) Fix ssl3_pending: If the record in s->s3->rrec is not of type - SSL3_RT_APPLICATION_DATA, return 0. - Similarly, change ssl2_pending to return 0 if SSL_in_init(s) is true. - [Bodo Moeller] - - *) Fix SSL_peek: - Both ssl2_peek and ssl3_peek, which were totally broken in earlier - releases, have been re-implemented by renaming the previous - implementations of ssl2_read and ssl3_read to ssl2_read_internal - and ssl3_read_internal, respectively, and adding 'peek' parameters - to them. The new ssl[23]_{read,peek} functions are calls to - ssl[23]_read_internal with the 'peek' flag set appropriately. - A 'peek' parameter has also been added to ssl3_read_bytes, which - does the actual work for ssl3_read_internal. - [Bodo Moeller] - - *) Initialise "ex_data" member of RSA/DSA/DH structures prior to calling - the method-specific "init()" handler. Also clean up ex_data after - calling the method-specific "finish()" handler. Previously, this was - happening the other way round. - [Geoff Thorpe] - - *) Increase BN_CTX_NUM (the number of BIGNUMs in a BN_CTX) to 16. - The previous value, 12, was not always sufficient for BN_mod_exp(). - [Bodo Moeller] - - *) Make sure that shared libraries get the internal name engine with - the full version number and not just 0. This should mark the - shared libraries as not backward compatible. Of course, this should - be changed again when we can guarantee backward binary compatibility. - [Richard Levitte] - - *) Fix typo in get_cert_by_subject() in by_dir.c - [Jean-Marc Desperrier ] - - *) Rework the system to generate shared libraries: - - - Make note of the expected extension for the shared libraries and - if there is a need for symbolic links from for example libcrypto.so.0 - to libcrypto.so.0.9.7. There is extended info in Configure for - that. - - - Make as few rebuilds of the shared libraries as possible. - - - Still avoid linking the OpenSSL programs with the shared libraries. - - - When installing, install the shared libraries separately from the - static ones. - [Richard Levitte] - - *) Fix SSL_CTX_set_read_ahead macro to actually use its argument. - - Copy SSL_CTX's read_ahead flag to SSL object directly in SSL_new - and not in SSL_clear because the latter is also used by the - accept/connect functions; previously, the settings made by - SSL_set_read_ahead would be lost during the handshake. - [Bodo Moeller; problems reported by Anders Gertz ] - - *) Correct util/mkdef.pl to be selective about disabled algorithms. - Previously, it would create entries for disabled algorithms no - matter what. - [Richard Levitte] - - *) Added several new manual pages for SSL_* function. - [Lutz Jaenicke] - - Changes between 0.9.5a and 0.9.6 [24 Sep 2000] - - *) In ssl23_get_client_hello, generate an error message when faced - with an initial SSL 3.0/TLS record that is too small to contain the - first two bytes of the ClientHello message, i.e. client_version. - (Note that this is a pathologic case that probably has never happened - in real life.) The previous approach was to use the version number - from the record header as a substitute; but our protocol choice - should not depend on that one because it is not authenticated - by the Finished messages. - [Bodo Moeller] - - *) More robust randomness gathering functions for Windows. - [Jeffrey Altman ] - - *) For compatibility reasons if the flag X509_V_FLAG_ISSUER_CHECK is - not set then we don't setup the error code for issuer check errors - to avoid possibly overwriting other errors which the callback does - handle. If an application does set the flag then we assume it knows - what it is doing and can handle the new informational codes - appropriately. - [Steve Henson] - - *) Fix for a nasty bug in ASN1_TYPE handling. ASN1_TYPE is used for - a general "ANY" type, as such it should be able to decode anything - including tagged types. However it didn't check the class so it would - wrongly interpret tagged types in the same way as their universal - counterpart and unknown types were just rejected. Changed so that the - tagged and unknown types are handled in the same way as a SEQUENCE: - that is the encoding is stored intact. There is also a new type - "V_ASN1_OTHER" which is used when the class is not universal, in this - case we have no idea what the actual type is so we just lump them all - together. - [Steve Henson] - - *) On VMS, stdout may very well lead to a file that is written to - in a record-oriented fashion. That means that every write() will - write a separate record, which will be read separately by the - programs trying to read from it. This can be very confusing. - - The solution is to put a BIO filter in the way that will buffer - text until a linefeed is reached, and then write everything a - line at a time, so every record written will be an actual line, - not chunks of lines and not (usually doesn't happen, but I've - seen it once) several lines in one record. BIO_f_linebuffer() is - the answer. - - Currently, it's a VMS-only method, because that's where it has - been tested well enough. - [Richard Levitte] - - *) Remove 'optimized' squaring variant in BN_mod_mul_montgomery, - it can return incorrect results. - (Note: The buggy variant was not enabled in OpenSSL 0.9.5a, - but it was in 0.9.6-beta[12].) - [Bodo Moeller] - - *) Disable the check for content being present when verifying detached - signatures in pk7_smime.c. Some versions of Netscape (wrongly) - include zero length content when signing messages. - [Steve Henson] - - *) New BIO_shutdown_wr macro, which invokes the BIO_C_SHUTDOWN_WR - BIO_ctrl (for BIO pairs). - [Bodo Möller] - - *) Add DSO method for VMS. - [Richard Levitte] - - *) Bug fix: Montgomery multiplication could produce results with the - wrong sign. - [Ulf Möller] - - *) Add RPM specification openssl.spec and modify it to build three - packages. The default package contains applications, application - documentation and run-time libraries. The devel package contains - include files, static libraries and function documentation. The - doc package contains the contents of the doc directory. The original - openssl.spec was provided by Damien Miller . - [Richard Levitte] - - *) Add a large number of documentation files for many SSL routines. - [Lutz Jaenicke ] - - *) Add a configuration entry for Sony News 4. - [NAKAJI Hiroyuki ] - - *) Don't set the two most significant bits to one when generating a - random number < q in the DSA library. - [Ulf Möller] - - *) New SSL API mode 'SSL_MODE_AUTO_RETRY'. This disables the default - behaviour that SSL_read may result in SSL_ERROR_WANT_READ (even if - the underlying transport is blocking) if a handshake took place. - (The default behaviour is needed by applications such as s_client - and s_server that use select() to determine when to use SSL_read; - but for applications that know in advance when to expect data, it - just makes things more complicated.) - [Bodo Moeller] - - *) Add RAND_egd_bytes(), which gives control over the number of bytes read - from EGD. - [Ben Laurie] - - *) Add a few more EBCDIC conditionals that make `req' and `x509' - work better on such systems. - [Martin Kraemer ] - - *) Add two demo programs for PKCS12_parse() and PKCS12_create(). - Update PKCS12_parse() so it copies the friendlyName and the - keyid to the certificates aux info. - [Steve Henson] - - *) Fix bug in PKCS7_verify() which caused an infinite loop - if there was more than one signature. - [Sven Uszpelkat ] - - *) Major change in util/mkdef.pl to include extra information - about each symbol, as well as presenting variables as well - as functions. This change means that there's n more need - to rebuild the .num files when some algorithms are excluded. - [Richard Levitte] - - *) Allow the verify time to be set by an application, - rather than always using the current time. - [Steve Henson] - - *) Phase 2 verify code reorganisation. The certificate - verify code now looks up an issuer certificate by a - number of criteria: subject name, authority key id - and key usage. It also verifies self signed certificates - by the same criteria. The main comparison function is - X509_check_issued() which performs these checks. - - Lot of changes were necessary in order to support this - without completely rewriting the lookup code. - - Authority and subject key identifier are now cached. - - The LHASH 'certs' is X509_STORE has now been replaced - by a STACK_OF(X509_OBJECT). This is mainly because an - LHASH can't store or retrieve multiple objects with - the same hash value. - - As a result various functions (which were all internal - use only) have changed to handle the new X509_STORE - structure. This will break anything that messed round - with X509_STORE internally. - - The functions X509_STORE_add_cert() now checks for an - exact match, rather than just subject name. - - The X509_STORE API doesn't directly support the retrieval - of multiple certificates matching a given criteria, however - this can be worked round by performing a lookup first - (which will fill the cache with candidate certificates) - and then examining the cache for matches. This is probably - the best we can do without throwing out X509_LOOKUP - entirely (maybe later...). - - The X509_VERIFY_CTX structure has been enhanced considerably. - - All certificate lookup operations now go via a get_issuer() - callback. Although this currently uses an X509_STORE it - can be replaced by custom lookups. This is a simple way - to bypass the X509_STORE hackery necessary to make this - work and makes it possible to use more efficient techniques - in future. A very simple version which uses a simple - STACK for its trusted certificate store is also provided - using X509_STORE_CTX_trusted_stack(). - - The verify_cb() and verify() callbacks now have equivalents - in the X509_STORE_CTX structure. - - X509_STORE_CTX also has a 'flags' field which can be used - to customise the verify behaviour. - [Steve Henson] - - *) Add new PKCS#7 signing option PKCS7_NOSMIMECAP which - excludes S/MIME capabilities. - [Steve Henson] - - *) When a certificate request is read in keep a copy of the - original encoding of the signed data and use it when outputting - again. Signatures then use the original encoding rather than - a decoded, encoded version which may cause problems if the - request is improperly encoded. - [Steve Henson] - - *) For consistency with other BIO_puts implementations, call - buffer_write(b, ...) directly in buffer_puts instead of calling - BIO_write(b, ...). - - In BIO_puts, increment b->num_write as in BIO_write. - [Peter.Sylvester@EdelWeb.fr] - - *) Fix BN_mul_word for the case where the word is 0. (We have to use - BN_zero, we may not return a BIGNUM with an array consisting of - words set to zero.) - [Bodo Moeller] - - *) Avoid calling abort() from within the library when problems are - detected, except if preprocessor symbols have been defined - (such as REF_CHECK, BN_DEBUG etc.). - [Bodo Moeller] - - *) New openssl application 'rsautl'. This utility can be - used for low level RSA operations. DER public key - BIO/fp routines also added. - [Steve Henson] - - *) New Configure entry and patches for compiling on QNX 4. - [Andreas Schneider ] - - *) A demo state-machine implementation was sponsored by - Nuron (http://www.nuron.com/) and is now available in - demos/state_machine. - [Ben Laurie] - - *) New options added to the 'dgst' utility for signature - generation and verification. - [Steve Henson] - - *) Unrecognized PKCS#7 content types are now handled via a - catch all ASN1_TYPE structure. This allows unsupported - types to be stored as a "blob" and an application can - encode and decode it manually. - [Steve Henson] - - *) Fix various signed/unsigned issues to make a_strex.c - compile under VC++. - [Oscar Jacobsson ] - - *) ASN1 fixes. i2d_ASN1_OBJECT was not returning the correct - length if passed a buffer. ASN1_INTEGER_to_BN failed - if passed a NULL BN and its argument was negative. - [Steve Henson, pointed out by Sven Heiberg ] - - *) Modification to PKCS#7 encoding routines to output definite - length encoding. Since currently the whole structures are in - memory there's not real point in using indefinite length - constructed encoding. However if OpenSSL is compiled with - the flag PKCS7_INDEFINITE_ENCODING the old form is used. - [Steve Henson] - - *) Added BIO_vprintf() and BIO_vsnprintf(). - [Richard Levitte] - - *) Added more prefixes to parse for in the strings written - through a logging bio, to cover all the levels that are available - through syslog. The prefixes are now: - - PANIC, EMERG, EMR => LOG_EMERG - ALERT, ALR => LOG_ALERT - CRIT, CRI => LOG_CRIT - ERROR, ERR => LOG_ERR - WARNING, WARN, WAR => LOG_WARNING - NOTICE, NOTE, NOT => LOG_NOTICE - INFO, INF => LOG_INFO - DEBUG, DBG => LOG_DEBUG - - and as before, if none of those prefixes are present at the - beginning of the string, LOG_ERR is chosen. - - On Win32, the LOG_* levels are mapped according to this: - - LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR => EVENTLOG_ERROR_TYPE - LOG_WARNING => EVENTLOG_WARNING_TYPE - LOG_NOTICE, LOG_INFO, LOG_DEBUG => EVENTLOG_INFORMATION_TYPE - - [Richard Levitte] - - *) Made it possible to reconfigure with just the configuration - argument "reconf" or "reconfigure". The command line arguments - are stored in Makefile.ssl in the variable CONFIGURE_ARGS, - and are retrieved from there when reconfiguring. - [Richard Levitte] - - *) MD4 implemented. - [Assar Westerlund , Richard Levitte] - - *) Add the arguments -CAfile and -CApath to the pkcs12 utility. - [Richard Levitte] - - *) The obj_dat.pl script was messing up the sorting of object - names. The reason was that it compared the quoted version - of strings as a result "OCSP" > "OCSP Signing" because - " > SPACE. Changed script to store unquoted versions of - names and add quotes on output. It was also omitting some - names from the lookup table if they were given a default - value (that is if SN is missing it is given the same - value as LN and vice versa), these are now added on the - grounds that if an object has a name we should be able to - look it up. Finally added warning output when duplicate - short or long names are found. - [Steve Henson] - - *) Changes needed for Tandem NSK. - [Scott Uroff ] - - *) Fix SSL 2.0 rollback checking: Due to an off-by-one error in - RSA_padding_check_SSLv23(), special padding was never detected - and thus the SSL 3.0/TLS 1.0 countermeasure against protocol - version rollback attacks was not effective. - - In s23_clnt.c, don't use special rollback-attack detection padding - (RSA_SSLV23_PADDING) if SSL 2.0 is the only protocol enabled in the - client; similarly, in s23_srvr.c, don't do the rollback check if - SSL 2.0 is the only protocol enabled in the server. - [Bodo Moeller] - - *) Make it possible to get hexdumps of unprintable data with 'openssl - asn1parse'. By implication, the functions ASN1_parse_dump() and - BIO_dump_indent() are added. - [Richard Levitte] - - *) New functions ASN1_STRING_print_ex() and X509_NAME_print_ex() - these print out strings and name structures based on various - flags including RFC2253 support and proper handling of - multibyte characters. Added options to the 'x509' utility - to allow the various flags to be set. - [Steve Henson] - - *) Various fixes to use ASN1_TIME instead of ASN1_UTCTIME. - Also change the functions X509_cmp_current_time() and - X509_gmtime_adj() work with an ASN1_TIME structure, - this will enable certificates using GeneralizedTime in validity - dates to be checked. - [Steve Henson] - - *) Make the NEG_PUBKEY_BUG code (which tolerates invalid - negative public key encodings) on by default, - NO_NEG_PUBKEY_BUG can be set to disable it. - [Steve Henson] - - *) New function c2i_ASN1_OBJECT() which acts on ASN1_OBJECT - content octets. An i2c_ASN1_OBJECT is unnecessary because - the encoding can be trivially obtained from the structure. - [Steve Henson] - - *) crypto/err.c locking bugfix: Use write locks (CRYPTO_w_[un]lock), - not read locks (CRYPTO_r_[un]lock). - [Bodo Moeller] - - *) A first attempt at creating official support for shared - libraries through configuration. I've kept it so the - default is static libraries only, and the OpenSSL programs - are always statically linked for now, but there are - preparations for dynamic linking in place. - This has been tested on Linux and Tru64. - [Richard Levitte] - - *) Randomness polling function for Win9x, as described in: - Peter Gutmann, Software Generation of Practically Strong - Random Numbers. - [Ulf Möller] - - *) Fix so PRNG is seeded in req if using an already existing - DSA key. - [Steve Henson] - - *) New options to smime application. -inform and -outform - allow alternative formats for the S/MIME message including - PEM and DER. The -content option allows the content to be - specified separately. This should allow things like Netscape - form signing output easier to verify. - [Steve Henson] - - *) Fix the ASN1 encoding of tags using the 'long form'. - [Steve Henson] - - *) New ASN1 functions, i2c_* and c2i_* for INTEGER and BIT - STRING types. These convert content octets to and from the - underlying type. The actual tag and length octets are - already assumed to have been read in and checked. These - are needed because all other string types have virtually - identical handling apart from the tag. By having versions - of the ASN1 functions that just operate on content octets - IMPLICIT tagging can be handled properly. It also allows - the ASN1_ENUMERATED code to be cut down because ASN1_ENUMERATED - and ASN1_INTEGER are identical apart from the tag. - [Steve Henson] - - *) Change the handling of OID objects as follows: - - - New object identifiers are inserted in objects.txt, following - the syntax given in objects.README. - - objects.pl is used to process obj_mac.num and create a new - obj_mac.h. - - obj_dat.pl is used to create a new obj_dat.h, using the data in - obj_mac.h. - - This is currently kind of a hack, and the perl code in objects.pl - isn't very elegant, but it works as I intended. The simplest way - to check that it worked correctly is to look in obj_dat.h and - check the array nid_objs and make sure the objects haven't moved - around (this is important!). Additions are OK, as well as - consistent name changes. - [Richard Levitte] - - *) Add BSD-style MD5-based passwords to 'openssl passwd' (option '-1'). - [Bodo Moeller] - - *) Addition of the command line parameter '-rand file' to 'openssl req'. - The given file adds to whatever has already been seeded into the - random pool through the RANDFILE configuration file option or - environment variable, or the default random state file. - [Richard Levitte] - - *) mkstack.pl now sorts each macro group into lexical order. - Previously the output order depended on the order the files - appeared in the directory, resulting in needless rewriting - of safestack.h . - [Steve Henson] - - *) Patches to make OpenSSL compile under Win32 again. Mostly - work arounds for the VC++ problem that it treats func() as - func(void). Also stripped out the parts of mkdef.pl that - added extra typesafe functions: these no longer exist. - [Steve Henson] - - *) Reorganisation of the stack code. The macros are now all - collected in safestack.h . Each macro is defined in terms of - a "stack macro" of the form SKM_(type, a, b). The - DEBUG_SAFESTACK is now handled in terms of function casts, - this has the advantage of retaining type safety without the - use of additional functions. If DEBUG_SAFESTACK is not defined - then the non typesafe macros are used instead. Also modified the - mkstack.pl script to handle the new form. Needs testing to see - if which (if any) compilers it chokes and maybe make DEBUG_SAFESTACK - the default if no major problems. Similar behaviour for ASN1_SET_OF - and PKCS12_STACK_OF. - [Steve Henson] - - *) When some versions of IIS use the 'NET' form of private key the - key derivation algorithm is different. Normally MD5(password) is - used as a 128 bit RC4 key. In the modified case - MD5(MD5(password) + "SGCKEYSALT") is used instead. Added some - new functions i2d_RSA_NET(), d2i_RSA_NET() etc which are the same - as the old Netscape_RSA functions except they have an additional - 'sgckey' parameter which uses the modified algorithm. Also added - an -sgckey command line option to the rsa utility. Thanks to - Adrian Peck for posting details of the modified - algorithm to openssl-dev. - [Steve Henson] - - *) The evp_local.h macros were using 'c.##kname' which resulted in - invalid expansion on some systems (SCO 5.0.5 for example). - Corrected to 'c.kname'. - [Phillip Porch ] - - *) New X509_get1_email() and X509_REQ_get1_email() functions that return - a STACK of email addresses from a certificate or request, these look - in the subject name and the subject alternative name extensions and - omit any duplicate addresses. - [Steve Henson] - - *) Re-implement BN_mod_exp2_mont using independent (and larger) windows. - This makes DSA verification about 2 % faster. - [Bodo Moeller] - - *) Increase maximum window size in BN_mod_exp_... to 6 bits instead of 5 - (meaning that now 2^5 values will be precomputed, which is only 4 KB - plus overhead for 1024 bit moduli). - This makes exponentiations about 0.5 % faster for 1024 bit - exponents (as measured by "openssl speed rsa2048"). - [Bodo Moeller] - - *) Rename memory handling macros to avoid conflicts with other - software: - Malloc => OPENSSL_malloc - Malloc_locked => OPENSSL_malloc_locked - Realloc => OPENSSL_realloc - Free => OPENSSL_free - [Richard Levitte] - - *) New function BN_mod_exp_mont_word for small bases (roughly 15% - faster than BN_mod_exp_mont, i.e. 7% for a full DH exchange). - [Bodo Moeller] - - *) CygWin32 support. - [John Jarvie ] - - *) The type-safe stack code has been rejigged. It is now only compiled - in when OpenSSL is configured with the DEBUG_SAFESTACK option and - by default all type-specific stack functions are "#define"d back to - standard stack functions. This results in more streamlined output - but retains the type-safety checking possibilities of the original - approach. - [Geoff Thorpe] - - *) The STACK code has been cleaned up, and certain type declarations - that didn't make a lot of sense have been brought in line. This has - also involved a cleanup of sorts in safestack.h to more correctly - map type-safe stack functions onto their plain stack counterparts. - This work has also resulted in a variety of "const"ifications of - lots of the code, especially "_cmp" operations which should normally - be prototyped with "const" parameters anyway. - [Geoff Thorpe] - - *) When generating bytes for the first time in md_rand.c, 'stir the pool' - by seeding with STATE_SIZE dummy bytes (with zero entropy count). - (The PRNG state consists of two parts, the large pool 'state' and 'md', - where all of 'md' is used each time the PRNG is used, but 'state' - is used only indexed by a cyclic counter. As entropy may not be - well distributed from the beginning, 'md' is important as a - chaining variable. However, the output function chains only half - of 'md', i.e. 80 bits. ssleay_rand_add, on the other hand, chains - all of 'md', and seeding with STATE_SIZE dummy bytes will result - in all of 'state' being rewritten, with the new values depending - on virtually all of 'md'. This overcomes the 80 bit limitation.) - [Bodo Moeller] - - *) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when - the handshake is continued after ssl_verify_cert_chain(); - otherwise, if SSL_VERIFY_NONE is set, remaining error codes - can lead to 'unexplainable' connection aborts later. - [Bodo Moeller; problem tracked down by Lutz Jaenicke] - - *) Major EVP API cipher revision. - Add hooks for extra EVP features. This allows various cipher - parameters to be set in the EVP interface. Support added for variable - key length ciphers via the EVP_CIPHER_CTX_set_key_length() function and - setting of RC2 and RC5 parameters. - - Modify EVP_OpenInit() and EVP_SealInit() to cope with variable key length - ciphers. - - Remove lots of duplicated code from the EVP library. For example *every* - cipher init() function handles the 'iv' in the same way according to the - cipher mode. They also all do nothing if the 'key' parameter is NULL and - for CFB and OFB modes they zero ctx->num. - - New functionality allows removal of S/MIME code RC2 hack. - - Most of the routines have the same form and so can be declared in terms - of macros. - - By shifting this to the top level EVP_CipherInit() it can be removed from - all individual ciphers. If the cipher wants to handle IVs or keys - differently it can set the EVP_CIPH_CUSTOM_IV or EVP_CIPH_ALWAYS_CALL_INIT - flags. - - Change lots of functions like EVP_EncryptUpdate() to now return a - value: although software versions of the algorithms cannot fail - any installed hardware versions can. - [Steve Henson] - - *) Implement SSL_OP_TLS_ROLLBACK_BUG: In ssl3_get_client_key_exchange, if - this option is set, tolerate broken clients that send the negotiated - protocol version number instead of the requested protocol version - number. - [Bodo Moeller] - - *) Call dh_tmp_cb (set by ..._TMP_DH_CB) with correct 'is_export' flag; - i.e. non-zero for export ciphersuites, zero otherwise. - Previous versions had this flag inverted, inconsistent with - rsa_tmp_cb (..._TMP_RSA_CB). - [Bodo Moeller; problem reported by Amit Chopra] - - *) Add missing DSA library text string. Work around for some IIS - key files with invalid SEQUENCE encoding. - [Steve Henson] - - *) Add a document (doc/standards.txt) that list all kinds of standards - and so on that are implemented in OpenSSL. - [Richard Levitte] - - *) Enhance c_rehash script. Old version would mishandle certificates - with the same subject name hash and wouldn't handle CRLs at all. - Added -fingerprint option to crl utility, to support new c_rehash - features. - [Steve Henson] - - *) Eliminate non-ANSI declarations in crypto.h and stack.h. - [Ulf Möller] - - *) Fix for SSL server purpose checking. Server checking was - rejecting certificates which had extended key usage present - but no ssl client purpose. - [Steve Henson, reported by Rene Grosser ] - - *) Make PKCS#12 code work with no password. The PKCS#12 spec - is a little unclear about how a blank password is handled. - Since the password in encoded as a BMPString with terminating - double NULL a zero length password would end up as just the - double NULL. However no password at all is different and is - handled differently in the PKCS#12 key generation code. NS - treats a blank password as zero length. MSIE treats it as no - password on export: but it will try both on import. We now do - the same: PKCS12_parse() tries zero length and no password if - the password is set to "" or NULL (NULL is now a valid password: - it wasn't before) as does the pkcs12 application. - [Steve Henson] - - *) Bugfixes in apps/x509.c: Avoid a memory leak; and don't use - perror when PEM_read_bio_X509_REQ fails, the error message must - be obtained from the error queue. - [Bodo Moeller] - - *) Avoid 'thread_hash' memory leak in crypto/err/err.c by freeing - it in ERR_remove_state if appropriate, and change ERR_get_state - accordingly to avoid race conditions (this is necessary because - thread_hash is no longer constant once set). - [Bodo Moeller] - - *) Bugfix for linux-elf makefile.one. - [Ulf Möller] - - *) RSA_get_default_method() will now cause a default - RSA_METHOD to be chosen if one doesn't exist already. - Previously this was only set during a call to RSA_new() - or RSA_new_method(NULL) meaning it was possible for - RSA_get_default_method() to return NULL. - [Geoff Thorpe] - - *) Added native name translation to the existing DSO code - that will convert (if the flag to do so is set) filenames - that are sufficiently small and have no path information - into a canonical native form. Eg. "blah" converted to - "libblah.so" or "blah.dll" etc. - [Geoff Thorpe] - - *) New function ERR_error_string_n(e, buf, len) which is like - ERR_error_string(e, buf), but writes at most 'len' bytes - including the 0 terminator. For ERR_error_string_n, 'buf' - may not be NULL. - [Damien Miller , Bodo Moeller] - - *) CONF library reworked to become more general. A new CONF - configuration file reader "class" is implemented as well as a - new functions (NCONF_*, for "New CONF") to handle it. The now - old CONF_* functions are still there, but are reimplemented to - work in terms of the new functions. Also, a set of functions - to handle the internal storage of the configuration data is - provided to make it easier to write new configuration file - reader "classes" (I can definitely see something reading a - configuration file in XML format, for example), called _CONF_*, - or "the configuration storage API"... - - The new configuration file reading functions are: - - NCONF_new, NCONF_free, NCONF_load, NCONF_load_fp, NCONF_load_bio, - NCONF_get_section, NCONF_get_string, NCONF_get_numbre - - NCONF_default, NCONF_WIN32 - - NCONF_dump_fp, NCONF_dump_bio - - NCONF_default and NCONF_WIN32 are method (or "class") choosers, - NCONF_new creates a new CONF object. This works in the same way - as other interfaces in OpenSSL, like the BIO interface. - NCONF_dump_* dump the internal storage of the configuration file, - which is useful for debugging. All other functions take the same - arguments as the old CONF_* functions with the exception of the - first that must be a `CONF *' instead of a `LHASH *'. - - To make it easier to use the new classes with the old CONF_* functions, - the function CONF_set_default_method is provided. - [Richard Levitte] - - *) Add '-tls1' option to 'openssl ciphers', which was already - mentioned in the documentation but had not been implemented. - (This option is not yet really useful because even the additional - experimental TLS 1.0 ciphers are currently treated as SSL 3.0 ciphers.) - [Bodo Moeller] - - *) Initial DSO code added into libcrypto for letting OpenSSL (and - OpenSSL-based applications) load shared libraries and bind to - them in a portable way. - [Geoff Thorpe, with contributions from Richard Levitte] - - Changes between 0.9.5 and 0.9.5a [1 Apr 2000] - - *) Make sure _lrotl and _lrotr are only used with MSVC. - - *) Use lock CRYPTO_LOCK_RAND correctly in ssleay_rand_status - (the default implementation of RAND_status). - - *) Rename openssl x509 option '-crlext', which was added in 0.9.5, - to '-clrext' (= clear extensions), as intended and documented. - [Bodo Moeller; inconsistency pointed out by Michael Attili - ] - - *) Fix for HMAC. It wasn't zeroing the rest of the block if the key length - was larger than the MD block size. - [Steve Henson, pointed out by Yost William ] - - *) Modernise PKCS12_parse() so it uses STACK_OF(X509) for its ca argument - fix a leak when the ca argument was passed as NULL. Stop X509_PUBKEY_set() - using the passed key: if the passed key was a private key the result - of X509_print(), for example, would be to print out all the private key - components. - [Steve Henson] - - *) des_quad_cksum() byte order bug fix. - [Ulf Möller, using the problem description in krb4-0.9.7, where - the solution is attributed to Derrick J Brashear ] - - *) Fix so V_ASN1_APP_CHOOSE works again: however its use is strongly - discouraged. - [Steve Henson, pointed out by Brian Korver ] - - *) For easily testing in shell scripts whether some command - 'openssl XXX' exists, the new pseudo-command 'openssl no-XXX' - returns with exit code 0 iff no command of the given name is available. - 'no-XXX' is printed in this case, 'XXX' otherwise. In both cases, - the output goes to stdout and nothing is printed to stderr. - Additional arguments are always ignored. - - Since for each cipher there is a command of the same name, - the 'no-cipher' compilation switches can be tested this way. - - ('openssl no-XXX' is not able to detect pseudo-commands such - as 'quit', 'list-XXX-commands', or 'no-XXX' itself.) - [Bodo Moeller] - - *) Update test suite so that 'make test' succeeds in 'no-rsa' configuration. - [Bodo Moeller] - - *) For SSL_[CTX_]set_tmp_dh, don't create a DH key if SSL_OP_SINGLE_DH_USE - is set; it will be thrown away anyway because each handshake creates - its own key. - ssl_cert_dup, which is used by SSL_new, now copies DH keys in addition - to parameters -- in previous versions (since OpenSSL 0.9.3) the - 'default key' from SSL_CTX_set_tmp_dh would always be lost, meaning - you effectively got SSL_OP_SINGLE_DH_USE when using this macro. - [Bodo Moeller] - - *) New s_client option -ign_eof: EOF at stdin is ignored, and - 'Q' and 'R' lose their special meanings (quit/renegotiate). - This is part of what -quiet does; unlike -quiet, -ign_eof - does not suppress any output. - [Richard Levitte] - - *) Add compatibility options to the purpose and trust code. The - purpose X509_PURPOSE_ANY is "any purpose" which automatically - accepts a certificate or CA, this was the previous behaviour, - with all the associated security issues. - - X509_TRUST_COMPAT is the old trust behaviour: only and - automatically trust self signed roots in certificate store. A - new trust setting X509_TRUST_DEFAULT is used to specify that - a purpose has no associated trust setting and it should instead - use the value in the default purpose. - [Steve Henson] - - *) Fix the PKCS#8 DSA private key code so it decodes keys again - and fix a memory leak. - [Steve Henson] - - *) In util/mkerr.pl (which implements 'make errors'), preserve - reason strings from the previous version of the .c file, as - the default to have only downcase letters (and digits) in - automatically generated reasons codes is not always appropriate. - [Bodo Moeller] - - *) In ERR_load_ERR_strings(), build an ERR_LIB_SYS error reason table - using strerror. Previously, ERR_reason_error_string() returned - library names as reason strings for SYSerr; but SYSerr is a special - case where small numbers are errno values, not library numbers. - [Bodo Moeller] - - *) Add '-dsaparam' option to 'openssl dhparam' application. This - converts DSA parameters into DH parameters. (When creating parameters, - DSA_generate_parameters is used.) - [Bodo Moeller] - - *) Include 'length' (recommended exponent length) in C code generated - by 'openssl dhparam -C'. - [Bodo Moeller] - - *) The second argument to set_label in perlasm was already being used - so couldn't be used as a "file scope" flag. Moved to third argument - which was free. - [Steve Henson] - - *) In PEM_ASN1_write_bio and some other functions, use RAND_pseudo_bytes - instead of RAND_bytes for encryption IVs and salts. - [Bodo Moeller] - - *) Include RAND_status() into RAND_METHOD instead of implementing - it only for md_rand.c Otherwise replacing the PRNG by calling - RAND_set_rand_method would be impossible. - [Bodo Moeller] - - *) Don't let DSA_generate_key() enter an infinite loop if the random - number generation fails. - [Bodo Moeller] - - *) New 'rand' application for creating pseudo-random output. - [Bodo Moeller] - - *) Added configuration support for Linux/IA64 - [Rolf Haberrecker ] - - *) Assembler module support for Mingw32. - [Ulf Möller] - - *) Shared library support for HPUX (in shlib/). - [Lutz Jaenicke and Anonymous] - - *) Shared library support for Solaris gcc. - [Lutz Behnke ] - - Changes between 0.9.4 and 0.9.5 [28 Feb 2000] - - *) PKCS7_encrypt() was adding text MIME headers twice because they - were added manually and by SMIME_crlf_copy(). - [Steve Henson] - - *) In bntest.c don't call BN_rand with zero bits argument. - [Steve Henson, pointed out by Andrew W. Gray ] - - *) BN_mul bugfix: In bn_mul_part_recursion() only the a>a[n] && b>b[n] - case was implemented. This caused BN_div_recp() to fail occasionally. - [Ulf Möller] - - *) Add an optional second argument to the set_label() in the perl - assembly language builder. If this argument exists and is set - to 1 it signals that the assembler should use a symbol whose - scope is the entire file, not just the current function. This - is needed with MASM which uses the format label:: for this scope. - [Steve Henson, pointed out by Peter Runestig ] - - *) Change the ASN1 types so they are typedefs by default. Before - almost all types were #define'd to ASN1_STRING which was causing - STACK_OF() problems: you couldn't declare STACK_OF(ASN1_UTF8STRING) - for example. - [Steve Henson] - - *) Change names of new functions to the new get1/get0 naming - convention: After 'get1', the caller owns a reference count - and has to call ..._free; 'get0' returns a pointer to some - data structure without incrementing reference counters. - (Some of the existing 'get' functions increment a reference - counter, some don't.) - Similarly, 'set1' and 'add1' functions increase reference - counters or duplicate objects. - [Steve Henson] - - *) Allow for the possibility of temp RSA key generation failure: - the code used to assume it always worked and crashed on failure. - [Steve Henson] - - *) Fix potential buffer overrun problem in BIO_printf(). - [Ulf Möller, using public domain code by Patrick Powell; problem - pointed out by David Sacerdote ] - - *) Support EGD . New functions - RAND_egd() and RAND_status(). In the command line application, - the EGD socket can be specified like a seed file using RANDFILE - or -rand. - [Ulf Möller] - - *) Allow the string CERTIFICATE to be tolerated in PKCS#7 structures. - Some CAs (e.g. Verisign) distribute certificates in this form. - [Steve Henson] - - *) Remove the SSL_ALLOW_ADH compile option and set the default cipher - list to exclude them. This means that no special compilation option - is needed to use anonymous DH: it just needs to be included in the - cipher list. - [Steve Henson] - - *) Change the EVP_MD_CTX_type macro so its meaning consistent with - EVP_MD_type. The old functionality is available in a new macro called - EVP_MD_md(). Change code that uses it and update docs. - [Steve Henson] - - *) ..._ctrl functions now have corresponding ..._callback_ctrl functions - where the 'void *' argument is replaced by a function pointer argument. - Previously 'void *' was abused to point to functions, which works on - many platforms, but is not correct. As these functions are usually - called by macros defined in OpenSSL header files, most source code - should work without changes. - [Richard Levitte] - - *) (which is created by Configure) now contains - sections with information on -D... compiler switches used for - compiling the library so that applications can see them. To enable - one of these sections, a pre-processor symbol OPENSSL_..._DEFINES - must be defined. E.g., - #define OPENSSL_ALGORITHM_DEFINES - #include - defines all pertinent NO_ symbols, such as NO_IDEA, NO_RSA, etc. - [Richard Levitte, Ulf and Bodo Möller] - - *) Bugfix: Tolerate fragmentation and interleaving in the SSL 3/TLS - record layer. - [Bodo Moeller] - - *) Change the 'other' type in certificate aux info to a STACK_OF - X509_ALGOR. Although not an AlgorithmIdentifier as such it has - the required ASN1 format: arbitrary types determined by an OID. - [Steve Henson] - - *) Add some PEM_write_X509_REQ_NEW() functions and a command line - argument to 'req'. This is not because the function is newer or - better than others it just uses the work 'NEW' in the certificate - request header lines. Some software needs this. - [Steve Henson] - - *) Reorganise password command line arguments: now passwords can be - obtained from various sources. Delete the PEM_cb function and make - it the default behaviour: i.e. if the callback is NULL and the - usrdata argument is not NULL interpret it as a null terminated pass - phrase. If usrdata and the callback are NULL then the pass phrase - is prompted for as usual. - [Steve Henson] - - *) Add support for the Compaq Atalla crypto accelerator. If it is installed, - the support is automatically enabled. The resulting binaries will - autodetect the card and use it if present. - [Ben Laurie and Compaq Inc.] - - *) Work around for Netscape hang bug. This sends certificate request - and server done in one record. Since this is perfectly legal in the - SSL/TLS protocol it isn't a "bug" option and is on by default. See - the bugs/SSLv3 entry for more info. - [Steve Henson] - - *) HP-UX tune-up: new unified configs, HP C compiler bug workaround. - [Andy Polyakov] - - *) Add -rand argument to smime and pkcs12 applications and read/write - of seed file. - [Steve Henson] - - *) New 'passwd' tool for crypt(3) and apr1 password hashes. - [Bodo Moeller] - - *) Add command line password options to the remaining applications. - [Steve Henson] - - *) Bug fix for BN_div_recp() for numerators with an even number of - bits. - [Ulf Möller] - - *) More tests in bntest.c, and changed test_bn output. - [Ulf Möller] - - *) ./config recognizes MacOS X now. - [Andy Polyakov] - - *) Bug fix for BN_div() when the first words of num and divisor are - equal (it gave wrong results if (rem=(n1-q*d0)&BN_MASK2) < d0). - [Ulf Möller] - - *) Add support for various broken PKCS#8 formats, and command line - options to produce them. - [Steve Henson] - - *) New functions BN_CTX_start(), BN_CTX_get() and BT_CTX_end() to - get temporary BIGNUMs from a BN_CTX. - [Ulf Möller] - - *) Correct return values in BN_mod_exp_mont() and BN_mod_exp2_mont() - for p == 0. - [Ulf Möller] - - *) Change the SSLeay_add_all_*() functions to OpenSSL_add_all_*() and - include a #define from the old name to the new. The original intent - was that statically linked binaries could for example just call - SSLeay_add_all_ciphers() to just add ciphers to the table and not - link with digests. This never worked because SSLeay_add_all_digests() - and SSLeay_add_all_ciphers() were in the same source file so calling - one would link with the other. They are now in separate source files. - [Steve Henson] - - *) Add a new -notext option to 'ca' and a -pubkey option to 'spkac'. - [Steve Henson] - - *) Use a less unusual form of the Miller-Rabin primality test (it used - a binary algorithm for exponentiation integrated into the Miller-Rabin - loop, our standard modexp algorithms are faster). - [Bodo Moeller] - - *) Support for the EBCDIC character set completed. - [Martin Kraemer ] - - *) Source code cleanups: use const where appropriate, eliminate casts, - use void * instead of char * in lhash. - [Ulf Möller] - - *) Bugfix: ssl3_send_server_key_exchange was not restartable - (the state was not changed to SSL3_ST_SW_KEY_EXCH_B, and because of - this the server could overwrite ephemeral keys that the client - has already seen). - [Bodo Moeller] - - *) Turn DSA_is_prime into a macro that calls BN_is_prime, - using 50 iterations of the Rabin-Miller test. - - DSA_generate_parameters now uses BN_is_prime_fasttest (with 50 - iterations of the Rabin-Miller test as required by the appendix - to FIPS PUB 186[-1]) instead of DSA_is_prime. - As BN_is_prime_fasttest includes trial division, DSA parameter - generation becomes much faster. - - This implies a change for the callback functions in DSA_is_prime - and DSA_generate_parameters: The callback function is called once - for each positive witness in the Rabin-Miller test, not just - occasionally in the inner loop; and the parameters to the - callback function now provide an iteration count for the outer - loop rather than for the current invocation of the inner loop. - DSA_generate_parameters additionally can call the callback - function with an 'iteration count' of -1, meaning that a - candidate has passed the trial division test (when q is generated - from an application-provided seed, trial division is skipped). - [Bodo Moeller] - - *) New function BN_is_prime_fasttest that optionally does trial - division before starting the Rabin-Miller test and has - an additional BN_CTX * argument (whereas BN_is_prime always - has to allocate at least one BN_CTX). - 'callback(1, -1, cb_arg)' is called when a number has passed the - trial division stage. - [Bodo Moeller] - - *) Fix for bug in CRL encoding. The validity dates weren't being handled - as ASN1_TIME. - [Steve Henson] - - *) New -pkcs12 option to CA.pl script to write out a PKCS#12 file. - [Steve Henson] - - *) New function BN_pseudo_rand(). - [Ulf Möller] - - *) Clean up BN_mod_mul_montgomery(): replace the broken (and unreadable) - bignum version of BN_from_montgomery() with the working code from - SSLeay 0.9.0 (the word based version is faster anyway), and clean up - the comments. - [Ulf Möller] - - *) Avoid a race condition in s2_clnt.c (function get_server_hello) that - made it impossible to use the same SSL_SESSION data structure in - SSL2 clients in multiple threads. - [Bodo Moeller] - - *) The return value of RAND_load_file() no longer counts bytes obtained - by stat(). RAND_load_file(..., -1) is new and uses the complete file - to seed the PRNG (previously an explicit byte count was required). - [Ulf Möller, Bodo Möller] - - *) Clean up CRYPTO_EX_DATA functions, some of these didn't have prototypes - used (char *) instead of (void *) and had casts all over the place. - [Steve Henson] - - *) Make BN_generate_prime() return NULL on error if ret!=NULL. - [Ulf Möller] - - *) Retain source code compatibility for BN_prime_checks macro: - BN_is_prime(..., BN_prime_checks, ...) now uses - BN_prime_checks_for_size to determine the appropriate number of - Rabin-Miller iterations. - [Ulf Möller] - - *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to - DH_CHECK_P_NOT_SAFE_PRIME. - (Check if this is true? OpenPGP calls them "strong".) - [Ulf Möller] - - *) Merge the functionality of "dh" and "gendh" programs into a new program - "dhparam". The old programs are retained for now but will handle DH keys - (instead of parameters) in future. - [Steve Henson] - - *) Make the ciphers, s_server and s_client programs check the return values - when a new cipher list is set. - [Steve Henson] - - *) Enhance the SSL/TLS cipher mechanism to correctly handle the TLS 56bit - ciphers. Before when the 56bit ciphers were enabled the sorting was - wrong. - - The syntax for the cipher sorting has been extended to support sorting by - cipher-strength (using the strength_bits hard coded in the tables). - The new command is "@STRENGTH" (see also doc/apps/ciphers.pod). - - Fix a bug in the cipher-command parser: when supplying a cipher command - string with an "undefined" symbol (neither command nor alphanumeric - [A-Za-z0-9], ssl_set_cipher_list used to hang in an endless loop. Now - an error is flagged. - - Due to the strength-sorting extension, the code of the - ssl_create_cipher_list() function was completely rearranged. I hope that - the readability was also increased :-) - [Lutz Jaenicke ] - - *) Minor change to 'x509' utility. The -CAcreateserial option now uses 1 - for the first serial number and places 2 in the serial number file. This - avoids problems when the root CA is created with serial number zero and - the first user certificate has the same issuer name and serial number - as the root CA. - [Steve Henson] - - *) Fixes to X509_ATTRIBUTE utilities, change the 'req' program so it uses - the new code. Add documentation for this stuff. - [Steve Henson] - - *) Changes to X509_ATTRIBUTE utilities. These have been renamed from - X509_*() to X509at_*() on the grounds that they don't handle X509 - structures and behave in an analogous way to the X509v3 functions: - they shouldn't be called directly but wrapper functions should be used - instead. - - So we also now have some wrapper functions that call the X509at functions - when passed certificate requests. (TO DO: similar things can be done with - PKCS#7 signed and unsigned attributes, PKCS#12 attributes and a few other - things. Some of these need some d2i or i2d and print functionality - because they handle more complex structures.) - [Steve Henson] - - *) Add missing #ifndefs that caused missing symbols when building libssl - as a shared library without RSA. Use #ifndef NO_SSL2 instead of - NO_RSA in ssl/s2*.c. - [Kris Kennaway , modified by Ulf Möller] - - *) Precautions against using the PRNG uninitialized: RAND_bytes() now - has a return value which indicates the quality of the random data - (1 = ok, 0 = not seeded). Also an error is recorded on the thread's - error queue. New function RAND_pseudo_bytes() generates output that is - guaranteed to be unique but not unpredictable. RAND_add is like - RAND_seed, but takes an extra argument for an entropy estimate - (RAND_seed always assumes full entropy). - [Ulf Möller] - - *) Do more iterations of Rabin-Miller probable prime test (specifically, - 3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes - instead of only 2 for all lengths; see BN_prime_checks_for_size definition - in crypto/bn/bn_prime.c for the complete table). This guarantees a - false-positive rate of at most 2^-80 for random input. - [Bodo Moeller] - - *) Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs. - [Bodo Moeller] - - *) New function X509_CTX_rget_chain() (renamed to X509_CTX_get1_chain - in the 0.9.5 release), this returns the chain - from an X509_CTX structure with a dup of the stack and all - the X509 reference counts upped: so the stack will exist - after X509_CTX_cleanup() has been called. Modify pkcs12.c - to use this. - - Also make SSL_SESSION_print() print out the verify return - code. - [Steve Henson] - - *) Add manpage for the pkcs12 command. Also change the default - behaviour so MAC iteration counts are used unless the new - -nomaciter option is used. This improves file security and - only older versions of MSIE (4.0 for example) need it. - [Steve Henson] - - *) Honor the no-xxx Configure options when creating .DEF files. - [Ulf Möller] - - *) Add PKCS#10 attributes to field table: challengePassword, - unstructuredName and unstructuredAddress. These are taken from - draft PKCS#9 v2.0 but are compatible with v1.2 provided no - international characters are used. - - More changes to X509_ATTRIBUTE code: allow the setting of types - based on strings. Remove the 'loc' parameter when adding - attributes because these will be a SET OF encoding which is sorted - in ASN1 order. - [Steve Henson] - - *) Initial changes to the 'req' utility to allow request generation - automation. This will allow an application to just generate a template - file containing all the field values and have req construct the - request. - - Initial support for X509_ATTRIBUTE handling. Stacks of these are - used all over the place including certificate requests and PKCS#7 - structures. They are currently handled manually where necessary with - some primitive wrappers for PKCS#7. The new functions behave in a - manner analogous to the X509 extension functions: they allow - attributes to be looked up by NID and added. - - Later something similar to the X509V3 code would be desirable to - automatically handle the encoding, decoding and printing of the - more complex types. The string types like challengePassword can - be handled by the string table functions. - - Also modified the multi byte string table handling. Now there is - a 'global mask' which masks out certain types. The table itself - can use the flag STABLE_NO_MASK to ignore the mask setting: this - is useful when for example there is only one permissible type - (as in countryName) and using the mask might result in no valid - types at all. - [Steve Henson] - - *) Clean up 'Finished' handling, and add functions SSL_get_finished and - SSL_get_peer_finished to allow applications to obtain the latest - Finished messages sent to the peer or expected from the peer, - respectively. (SSL_get_peer_finished is usually the Finished message - actually received from the peer, otherwise the protocol will be aborted.) - - As the Finished message are message digests of the complete handshake - (with a total of 192 bits for TLS 1.0 and more for SSL 3.0), they can - be used for external authentication procedures when the authentication - provided by SSL/TLS is not desired or is not enough. - [Bodo Moeller] - - *) Enhanced support for Alpha Linux is added. Now ./config checks if - the host supports BWX extension and if Compaq C is present on the - $PATH. Just exploiting of the BWX extension results in 20-30% - performance kick for some algorithms, e.g. DES and RC4 to mention - a couple. Compaq C in turn generates ~20% faster code for MD5 and - SHA1. - [Andy Polyakov] - - *) Add support for MS "fast SGC". This is arguably a violation of the - SSL3/TLS protocol. Netscape SGC does two handshakes: the first with - weak crypto and after checking the certificate is SGC a second one - with strong crypto. MS SGC stops the first handshake after receiving - the server certificate message and sends a second client hello. Since - a server will typically do all the time consuming operations before - expecting any further messages from the client (server key exchange - is the most expensive) there is little difference between the two. - - To get OpenSSL to support MS SGC we have to permit a second client - hello message after we have sent server done. In addition we have to - reset the MAC if we do get this second client hello. - [Steve Henson] - - *) Add a function 'd2i_AutoPrivateKey()' this will automatically decide - if a DER encoded private key is RSA or DSA traditional format. Changed - d2i_PrivateKey_bio() to use it. This is only needed for the "traditional" - format DER encoded private key. Newer code should use PKCS#8 format which - has the key type encoded in the ASN1 structure. Added DER private key - support to pkcs8 application. - [Steve Henson] - - *) SSL 3/TLS 1 servers now don't request certificates when an anonymous - ciphersuites has been selected (as required by the SSL 3/TLS 1 - specifications). Exception: When SSL_VERIFY_FAIL_IF_NO_PEER_CERT - is set, we interpret this as a request to violate the specification - (the worst that can happen is a handshake failure, and 'correct' - behaviour would result in a handshake failure anyway). - [Bodo Moeller] - - *) In SSL_CTX_add_session, take into account that there might be multiple - SSL_SESSION structures with the same session ID (e.g. when two threads - concurrently obtain them from an external cache). - The internal cache can handle only one SSL_SESSION with a given ID, - so if there's a conflict, we now throw out the old one to achieve - consistency. - [Bodo Moeller] - - *) Add OIDs for idea and blowfish in CBC mode. This will allow both - to be used in PKCS#5 v2.0 and S/MIME. Also add checking to - some routines that use cipher OIDs: some ciphers do not have OIDs - defined and so they cannot be used for S/MIME and PKCS#5 v2.0 for - example. - [Steve Henson] - - *) Simplify the trust setting structure and code. Now we just have - two sequences of OIDs for trusted and rejected settings. These will - typically have values the same as the extended key usage extension - and any application specific purposes. - - The trust checking code now has a default behaviour: it will just - check for an object with the same NID as the passed id. Functions can - be provided to override either the default behaviour or the behaviour - for a given id. SSL client, server and email already have functions - in place for compatibility: they check the NID and also return "trusted" - if the certificate is self signed. - [Steve Henson] - - *) Add d2i,i2d bio/fp functions for PrivateKey: these convert the - traditional format into an EVP_PKEY structure. - [Steve Henson] - - *) Add a password callback function PEM_cb() which either prompts for - a password if usr_data is NULL or otherwise assumes it is a null - terminated password. Allow passwords to be passed on command line - environment or config files in a few more utilities. - [Steve Henson] - - *) Add a bunch of DER and PEM functions to handle PKCS#8 format private - keys. Add some short names for PKCS#8 PBE algorithms and allow them - to be specified on the command line for the pkcs8 and pkcs12 utilities. - Update documentation. - [Steve Henson] - - *) Support for ASN1 "NULL" type. This could be handled before by using - ASN1_TYPE but there wasn't any function that would try to read a NULL - and produce an error if it couldn't. For compatibility we also have - ASN1_NULL_new() and ASN1_NULL_free() functions but these are faked and - don't allocate anything because they don't need to. - [Steve Henson] - - *) Initial support for MacOS is now provided. Examine INSTALL.MacOS - for details. - [Andy Polyakov, Roy Woods ] - - *) Rebuild of the memory allocation routines used by OpenSSL code and - possibly others as well. The purpose is to make an interface that - provide hooks so anyone can build a separate set of allocation and - deallocation routines to be used by OpenSSL, for example memory - pool implementations, or something else, which was previously hard - since Malloc(), Realloc() and Free() were defined as macros having - the values malloc, realloc and free, respectively (except for Win32 - compilations). The same is provided for memory debugging code. - OpenSSL already comes with functionality to find memory leaks, but - this gives people a chance to debug other memory problems. - - With these changes, a new set of functions and macros have appeared: - - CRYPTO_set_mem_debug_functions() [F] - CRYPTO_get_mem_debug_functions() [F] - CRYPTO_dbg_set_options() [F] - CRYPTO_dbg_get_options() [F] - CRYPTO_malloc_debug_init() [M] - - The memory debug functions are NULL by default, unless the library - is compiled with CRYPTO_MDEBUG or friends is defined. If someone - wants to debug memory anyway, CRYPTO_malloc_debug_init() (which - gives the standard debugging functions that come with OpenSSL) or - CRYPTO_set_mem_debug_functions() (tells OpenSSL to use functions - provided by the library user) must be used. When the standard - debugging functions are used, CRYPTO_dbg_set_options can be used to - request additional information: - CRYPTO_dbg_set_options(V_CYRPTO_MDEBUG_xxx) corresponds to setting - the CRYPTO_MDEBUG_xxx macro when compiling the library. - - Also, things like CRYPTO_set_mem_functions will always give the - expected result (the new set of functions is used for allocation - and deallocation) at all times, regardless of platform and compiler - options. - - To finish it up, some functions that were never use in any other - way than through macros have a new API and new semantic: - - CRYPTO_dbg_malloc() - CRYPTO_dbg_realloc() - CRYPTO_dbg_free() - - All macros of value have retained their old syntax. - [Richard Levitte and Bodo Moeller] - - *) Some S/MIME fixes. The OID for SMIMECapabilities was wrong, the - ordering of SMIMECapabilities wasn't in "strength order" and there - was a missing NULL in the AlgorithmIdentifier for the SHA1 signature - algorithm. - [Steve Henson] - - *) Some ASN1 types with illegal zero length encoding (INTEGER, - ENUMERATED and OBJECT IDENTIFIER) choked the ASN1 routines. - [Frans Heymans , modified by Steve Henson] - - *) Merge in my S/MIME library for OpenSSL. This provides a simple - S/MIME API on top of the PKCS#7 code, a MIME parser (with enough - functionality to handle multipart/signed properly) and a utility - called 'smime' to call all this stuff. This is based on code I - originally wrote for Celo who have kindly allowed it to be - included in OpenSSL. - [Steve Henson] - - *) Add variants des_set_key_checked and des_set_key_unchecked of - des_set_key (aka des_key_sched). Global variable des_check_key - decides which of these is called by des_set_key; this way - des_check_key behaves as it always did, but applications and - the library itself, which was buggy for des_check_key == 1, - have a cleaner way to pick the version they need. - [Bodo Moeller] - - *) New function PKCS12_newpass() which changes the password of a - PKCS12 structure. - [Steve Henson] - - *) Modify X509_TRUST and X509_PURPOSE so it also uses a static and - dynamic mix. In both cases the ids can be used as an index into the - table. Also modified the X509_TRUST_add() and X509_PURPOSE_add() - functions so they accept a list of the field values and the - application doesn't need to directly manipulate the X509_TRUST - structure. - [Steve Henson] - - *) Modify the ASN1_STRING_TABLE stuff so it also uses bsearch and doesn't - need initialising. - [Steve Henson] - - *) Modify the way the V3 extension code looks up extensions. This now - works in a similar way to the object code: we have some "standard" - extensions in a static table which is searched with OBJ_bsearch() - and the application can add dynamic ones if needed. The file - crypto/x509v3/ext_dat.h now has the info: this file needs to be - updated whenever a new extension is added to the core code and kept - in ext_nid order. There is a simple program 'tabtest.c' which checks - this. New extensions are not added too often so this file can readily - be maintained manually. - - There are two big advantages in doing things this way. The extensions - can be looked up immediately and no longer need to be "added" using - X509V3_add_standard_extensions(): this function now does nothing. - [Side note: I get *lots* of email saying the extension code doesn't - work because people forget to call this function] - Also no dynamic allocation is done unless new extensions are added: - so if we don't add custom extensions there is no need to call - X509V3_EXT_cleanup(). - [Steve Henson] - - *) Modify enc utility's salting as follows: make salting the default. Add a - magic header, so unsalted files fail gracefully instead of just decrypting - to garbage. This is because not salting is a big security hole, so people - should be discouraged from doing it. - [Ben Laurie] - - *) Fixes and enhancements to the 'x509' utility. It allowed a message - digest to be passed on the command line but it only used this - parameter when signing a certificate. Modified so all relevant - operations are affected by the digest parameter including the - -fingerprint and -x509toreq options. Also -x509toreq choked if a - DSA key was used because it didn't fix the digest. - [Steve Henson] - - *) Initial certificate chain verify code. Currently tests the untrusted - certificates for consistency with the verify purpose (which is set - when the X509_STORE_CTX structure is set up) and checks the pathlength. - - There is a NO_CHAIN_VERIFY compilation option to keep the old behaviour: - this is because it will reject chains with invalid extensions whereas - every previous version of OpenSSL and SSLeay made no checks at all. - - Trust code: checks the root CA for the relevant trust settings. Trust - settings have an initial value consistent with the verify purpose: e.g. - if the verify purpose is for SSL client use it expects the CA to be - trusted for SSL client use. However the default value can be changed to - permit custom trust settings: one example of this would be to only trust - certificates from a specific "secure" set of CAs. - - Also added X509_STORE_CTX_new() and X509_STORE_CTX_free() functions - which should be used for version portability: especially since the - verify structure is likely to change more often now. - - SSL integration. Add purpose and trust to SSL_CTX and SSL and functions - to set them. If not set then assume SSL clients will verify SSL servers - and vice versa. - - Two new options to the verify program: -untrusted allows a set of - untrusted certificates to be passed in and -purpose which sets the - intended purpose of the certificate. If a purpose is set then the - new chain verify code is used to check extension consistency. - [Steve Henson] - - *) Support for the authority information access extension. - [Steve Henson] - - *) Modify RSA and DSA PEM read routines to transparently handle - PKCS#8 format private keys. New *_PUBKEY_* functions that handle - public keys in a format compatible with certificate - SubjectPublicKeyInfo structures. Unfortunately there were already - functions called *_PublicKey_* which used various odd formats so - these are retained for compatibility: however the DSA variants were - never in a public release so they have been deleted. Changed dsa/rsa - utilities to handle the new format: note no releases ever handled public - keys so we should be OK. - - The primary motivation for this change is to avoid the same fiasco - that dogs private keys: there are several incompatible private key - formats some of which are standard and some OpenSSL specific and - require various evil hacks to allow partial transparent handling and - even then it doesn't work with DER formats. Given the option anything - other than PKCS#8 should be dumped: but the other formats have to - stay in the name of compatibility. - - With public keys and the benefit of hindsight one standard format - is used which works with EVP_PKEY, RSA or DSA structures: though - it clearly returns an error if you try to read the wrong kind of key. - - Added a -pubkey option to the 'x509' utility to output the public key. - Also rename the EVP_PKEY_get_*() to EVP_PKEY_rget_*() - (renamed to EVP_PKEY_get1_*() in the OpenSSL 0.9.5 release) and add - EVP_PKEY_rset_*() functions (renamed to EVP_PKEY_set1_*()) - that do the same as the EVP_PKEY_assign_*() except they up the - reference count of the added key (they don't "swallow" the - supplied key). - [Steve Henson] - - *) Fixes to crypto/x509/by_file.c the code to read in certificates and - CRLs would fail if the file contained no certificates or no CRLs: - added a new function to read in both types and return the number - read: this means that if none are read it will be an error. The - DER versions of the certificate and CRL reader would always fail - because it isn't possible to mix certificates and CRLs in DER format - without choking one or the other routine. Changed this to just read - a certificate: this is the best we can do. Also modified the code - in apps/verify.c to take notice of return codes: it was previously - attempting to read in certificates from NULL pointers and ignoring - any errors: this is one reason why the cert and CRL reader seemed - to work. It doesn't check return codes from the default certificate - routines: these may well fail if the certificates aren't installed. - [Steve Henson] - - *) Code to support otherName option in GeneralName. - [Steve Henson] - - *) First update to verify code. Change the verify utility - so it warns if it is passed a self signed certificate: - for consistency with the normal behaviour. X509_verify - has been modified to it will now verify a self signed - certificate if *exactly* the same certificate appears - in the store: it was previously impossible to trust a - single self signed certificate. This means that: - openssl verify ss.pem - now gives a warning about a self signed certificate but - openssl verify -CAfile ss.pem ss.pem - is OK. - [Steve Henson] - - *) For servers, store verify_result in SSL_SESSION data structure - (and add it to external session representation). - This is needed when client certificate verifications fails, - but an application-provided verification callback (set by - SSL_CTX_set_cert_verify_callback) allows accepting the session - anyway (i.e. leaves x509_store_ctx->error != X509_V_OK - but returns 1): When the session is reused, we have to set - ssl->verify_result to the appropriate error code to avoid - security holes. - [Bodo Moeller, problem pointed out by Lutz Jaenicke] - - *) Fix a bug in the new PKCS#7 code: it didn't consider the - case in PKCS7_dataInit() where the signed PKCS7 structure - didn't contain any existing data because it was being created. - [Po-Cheng Chen , slightly modified by Steve Henson] - - *) Add a salt to the key derivation routines in enc.c. This - forms the first 8 bytes of the encrypted file. Also add a - -S option to allow a salt to be input on the command line. - [Steve Henson] - - *) New function X509_cmp(). Oddly enough there wasn't a function - to compare two certificates. We do this by working out the SHA1 - hash and comparing that. X509_cmp() will be needed by the trust - code. - [Steve Henson] - - *) SSL_get1_session() is like SSL_get_session(), but increments - the reference count in the SSL_SESSION returned. - [Geoff Thorpe ] - - *) Fix for 'req': it was adding a null to request attributes. - Also change the X509_LOOKUP and X509_INFO code to handle - certificate auxiliary information. - [Steve Henson] - - *) Add support for 40 and 64 bit RC2 and RC4 algorithms: document - the 'enc' command. - [Steve Henson] - - *) Add the possibility to add extra information to the memory leak - detecting output, to form tracebacks, showing from where each - allocation was originated: CRYPTO_push_info("constant string") adds - the string plus current file name and line number to a per-thread - stack, CRYPTO_pop_info() does the obvious, CRYPTO_remove_all_info() - is like calling CYRPTO_pop_info() until the stack is empty. - Also updated memory leak detection code to be multi-thread-safe. - [Richard Levitte] - - *) Add options -text and -noout to pkcs7 utility and delete the - encryption options which never did anything. Update docs. - [Steve Henson] - - *) Add options to some of the utilities to allow the pass phrase - to be included on either the command line (not recommended on - OSes like Unix) or read from the environment. Update the - manpages and fix a few bugs. - [Steve Henson] - - *) Add a few manpages for some of the openssl commands. - [Steve Henson] - - *) Fix the -revoke option in ca. It was freeing up memory twice, - leaking and not finding already revoked certificates. - [Steve Henson] - - *) Extensive changes to support certificate auxiliary information. - This involves the use of X509_CERT_AUX structure and X509_AUX - functions. An X509_AUX function such as PEM_read_X509_AUX() - can still read in a certificate file in the usual way but it - will also read in any additional "auxiliary information". By - doing things this way a fair degree of compatibility can be - retained: existing certificates can have this information added - using the new 'x509' options. - - Current auxiliary information includes an "alias" and some trust - settings. The trust settings will ultimately be used in enhanced - certificate chain verification routines: currently a certificate - can only be trusted if it is self signed and then it is trusted - for all purposes. - [Steve Henson] - - *) Fix assembler for Alpha (tested only on DEC OSF not Linux or *BSD). - The problem was that one of the replacement routines had not been working - since SSLeay releases. For now the offending routine has been replaced - with non-optimised assembler. Even so, this now gives around 95% - performance improvement for 1024 bit RSA signs. - [Mark Cox] - - *) Hack to fix PKCS#7 decryption when used with some unorthodox RC2 - handling. Most clients have the effective key size in bits equal to - the key length in bits: so a 40 bit RC2 key uses a 40 bit (5 byte) key. - A few however don't do this and instead use the size of the decrypted key - to determine the RC2 key length and the AlgorithmIdentifier to determine - the effective key length. In this case the effective key length can still - be 40 bits but the key length can be 168 bits for example. This is fixed - by manually forcing an RC2 key into the EVP_PKEY structure because the - EVP code can't currently handle unusual RC2 key sizes: it always assumes - the key length and effective key length are equal. - [Steve Henson] - - *) Add a bunch of functions that should simplify the creation of - X509_NAME structures. Now you should be able to do: - X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, "Steve", -1, -1, 0); - and have it automatically work out the correct field type and fill in - the structures. The more adventurous can try: - X509_NAME_add_entry_by_txt(nm, field, MBSTRING_UTF8, str, -1, -1, 0); - and it will (hopefully) work out the correct multibyte encoding. - [Steve Henson] - - *) Change the 'req' utility to use the new field handling and multibyte - copy routines. Before the DN field creation was handled in an ad hoc - way in req, ca, and x509 which was rather broken and didn't support - BMPStrings or UTF8Strings. Since some software doesn't implement - BMPStrings or UTF8Strings yet, they can be enabled using the config file - using the dirstring_type option. See the new comment in the default - openssl.cnf for more info. - [Steve Henson] - - *) Make crypto/rand/md_rand.c more robust: - - Assure unique random numbers after fork(). - - Make sure that concurrent threads access the global counter and - md serializably so that we never lose entropy in them - or use exactly the same state in multiple threads. - Access to the large state is not always serializable because - the additional locking could be a performance killer, and - md should be large enough anyway. - [Bodo Moeller] - - *) New file apps/app_rand.c with commonly needed functionality - for handling the random seed file. - - Use the random seed file in some applications that previously did not: - ca, - dsaparam -genkey (which also ignored its '-rand' option), - s_client, - s_server, - x509 (when signing). - Except on systems with /dev/urandom, it is crucial to have a random - seed file at least for key creation, DSA signing, and for DH exchanges; - for RSA signatures we could do without one. - - gendh and gendsa (unlike genrsa) used to read only the first byte - of each file listed in the '-rand' option. The function as previously - found in genrsa is now in app_rand.c and is used by all programs - that support '-rand'. - [Bodo Moeller] - - *) In RAND_write_file, use mode 0600 for creating files; - don't just chmod when it may be too late. - [Bodo Moeller] - - *) Report an error from X509_STORE_load_locations - when X509_LOOKUP_load_file or X509_LOOKUP_add_dir failed. - [Bill Perry] - - *) New function ASN1_mbstring_copy() this copies a string in either - ASCII, Unicode, Universal (4 bytes per character) or UTF8 format - into an ASN1_STRING type. A mask of permissible types is passed - and it chooses the "minimal" type to use or an error if not type - is suitable. - [Steve Henson] - - *) Add function equivalents to the various macros in asn1.h. The old - macros are retained with an M_ prefix. Code inside the library can - use the M_ macros. External code (including the openssl utility) - should *NOT* in order to be "shared library friendly". - [Steve Henson] - - *) Add various functions that can check a certificate's extensions - to see if it usable for various purposes such as SSL client, - server or S/MIME and CAs of these types. This is currently - VERY EXPERIMENTAL but will ultimately be used for certificate chain - verification. Also added a -purpose flag to x509 utility to - print out all the purposes. - [Steve Henson] - - *) Add a CRYPTO_EX_DATA to X509 certificate structure and associated - functions. - [Steve Henson] - - *) New X509V3_{X509,CRL,REVOKED}_get_d2i() functions. These will search - for, obtain and decode and extension and obtain its critical flag. - This allows all the necessary extension code to be handled in a - single function call. - [Steve Henson] - - *) RC4 tune-up featuring 30-40% performance improvement on most RISC - platforms. See crypto/rc4/rc4_enc.c for further details. - [Andy Polyakov] - - *) New -noout option to asn1parse. This causes no output to be produced - its main use is when combined with -strparse and -out to extract data - from a file (which may not be in ASN.1 format). - [Steve Henson] - - *) Fix for pkcs12 program. It was hashing an invalid certificate pointer - when producing the local key id. - [Richard Levitte ] - - *) New option -dhparam in s_server. This allows a DH parameter file to be - stated explicitly. If it is not stated then it tries the first server - certificate file. The previous behaviour hard coded the filename - "server.pem". - [Steve Henson] - - *) Add -pubin and -pubout options to the rsa and dsa commands. These allow - a public key to be input or output. For example: - openssl rsa -in key.pem -pubout -out pubkey.pem - Also added necessary DSA public key functions to handle this. - [Steve Henson] - - *) Fix so PKCS7_dataVerify() doesn't crash if no certificates are contained - in the message. This was handled by allowing - X509_find_by_issuer_and_serial() to tolerate a NULL passed to it. - [Steve Henson, reported by Sampo Kellomaki ] - - *) Fix for bug in d2i_ASN1_bytes(): other ASN1 functions add an extra null - to the end of the strings whereas this didn't. This would cause problems - if strings read with d2i_ASN1_bytes() were later modified. - [Steve Henson, reported by Arne Ansper ] - - *) Fix for base64 decode bug. When a base64 bio reads only one line of - data and it contains EOF it will end up returning an error. This is - caused by input 46 bytes long. The cause is due to the way base64 - BIOs find the start of base64 encoded data. They do this by trying a - trial decode on each line until they find one that works. When they - do a flag is set and it starts again knowing it can pass all the - data directly through the decoder. Unfortunately it doesn't reset - the context it uses. This means that if EOF is reached an attempt - is made to pass two EOFs through the context and this causes the - resulting error. This can also cause other problems as well. As is - usual with these problems it takes *ages* to find and the fix is - trivial: move one line. - [Steve Henson, reported by ian@uns.ns.ac.yu (Ivan Nejgebauer) ] - - *) Ugly workaround to get s_client and s_server working under Windows. The - old code wouldn't work because it needed to select() on sockets and the - tty (for keypresses and to see if data could be written). Win32 only - supports select() on sockets so we select() with a 1s timeout on the - sockets and then see if any characters are waiting to be read, if none - are present then we retry, we also assume we can always write data to - the tty. This isn't nice because the code then blocks until we've - received a complete line of data and it is effectively polling the - keyboard at 1s intervals: however it's quite a bit better than not - working at all :-) A dedicated Windows application might handle this - with an event loop for example. - [Steve Henson] - - *) Enhance RSA_METHOD structure. Now there are two extra methods, rsa_sign - and rsa_verify. When the RSA_FLAGS_SIGN_VER option is set these functions - will be called when RSA_sign() and RSA_verify() are used. This is useful - if rsa_pub_dec() and rsa_priv_enc() equivalents are not available. - For this to work properly RSA_public_decrypt() and RSA_private_encrypt() - should *not* be used: RSA_sign() and RSA_verify() must be used instead. - This necessitated the support of an extra signature type NID_md5_sha1 - for SSL signatures and modifications to the SSL library to use it instead - of calling RSA_public_decrypt() and RSA_private_encrypt(). - [Steve Henson] - - *) Add new -verify -CAfile and -CApath options to the crl program, these - will lookup a CRL issuers certificate and verify the signature in a - similar way to the verify program. Tidy up the crl program so it - no longer accesses structures directly. Make the ASN1 CRL parsing a bit - less strict. It will now permit CRL extensions even if it is not - a V2 CRL: this will allow it to tolerate some broken CRLs. - [Steve Henson] - - *) Initialize all non-automatic variables each time one of the openssl - sub-programs is started (this is necessary as they may be started - multiple times from the "OpenSSL>" prompt). - [Lennart Bang, Bodo Moeller] - - *) Preliminary compilation option RSA_NULL which disables RSA crypto without - removing all other RSA functionality (this is what NO_RSA does). This - is so (for example) those in the US can disable those operations covered - by the RSA patent while allowing storage and parsing of RSA keys and RSA - key generation. - [Steve Henson] - - *) Non-copying interface to BIO pairs. - (still largely untested) - [Bodo Moeller] - - *) New function ANS1_tag2str() to convert an ASN1 tag to a descriptive - ASCII string. This was handled independently in various places before. - [Steve Henson] - - *) New functions UTF8_getc() and UTF8_putc() that parse and generate - UTF8 strings a character at a time. - [Steve Henson] - - *) Use client_version from client hello to select the protocol - (s23_srvr.c) and for RSA client key exchange verification - (s3_srvr.c), as required by the SSL 3.0/TLS 1.0 specifications. - [Bodo Moeller] - - *) Add various utility functions to handle SPKACs, these were previously - handled by poking round in the structure internals. Added new function - NETSCAPE_SPKI_print() to print out SPKAC and a new utility 'spkac' to - print, verify and generate SPKACs. Based on an original idea from - Massimiliano Pala but extensively modified. - [Steve Henson] - - *) RIPEMD160 is operational on all platforms and is back in 'make test'. - [Andy Polyakov] - - *) Allow the config file extension section to be overwritten on the - command line. Based on an original idea from Massimiliano Pala - . The new option is called -extensions - and can be applied to ca, req and x509. Also -reqexts to override - the request extensions in req and -crlexts to override the crl extensions - in ca. - [Steve Henson] - - *) Add new feature to the SPKAC handling in ca. Now you can include - the same field multiple times by preceding it by "XXXX." for example: - 1.OU="Unit name 1" - 2.OU="Unit name 2" - this is the same syntax as used in the req config file. - [Steve Henson] - - *) Allow certificate extensions to be added to certificate requests. These - are specified in a 'req_extensions' option of the req section of the - config file. They can be printed out with the -text option to req but - are otherwise ignored at present. - [Steve Henson] - - *) Fix a horrible bug in enc_read() in crypto/evp/bio_enc.c: if the first - data read consists of only the final block it would not decrypted because - EVP_CipherUpdate() would correctly report zero bytes had been decrypted. - A misplaced 'break' also meant the decrypted final block might not be - copied until the next read. - [Steve Henson] - - *) Initial support for DH_METHOD. Again based on RSA_METHOD. Also added - a few extra parameters to the DH structure: these will be useful if - for example we want the value of 'q' or implement X9.42 DH. - [Steve Henson] - - *) Initial support for DSA_METHOD. This is based on the RSA_METHOD and - provides hooks that allow the default DSA functions or functions on a - "per key" basis to be replaced. This allows hardware acceleration and - hardware key storage to be handled without major modification to the - library. Also added low level modexp hooks and CRYPTO_EX structure and - associated functions. - [Steve Henson] - - *) Add a new flag to memory BIOs, BIO_FLAG_MEM_RDONLY. This marks the BIO - as "read only": it can't be written to and the buffer it points to will - not be freed. Reading from a read only BIO is much more efficient than - a normal memory BIO. This was added because there are several times when - an area of memory needs to be read from a BIO. The previous method was - to create a memory BIO and write the data to it, this results in two - copies of the data and an O(n^2) reading algorithm. There is a new - function BIO_new_mem_buf() which creates a read only memory BIO from - an area of memory. Also modified the PKCS#7 routines to use read only - memory BIOs. - [Steve Henson] - - *) Bugfix: ssl23_get_client_hello did not work properly when called in - state SSL23_ST_SR_CLNT_HELLO_B, i.e. when the first 7 bytes of - a SSLv2-compatible client hello for SSLv3 or TLSv1 could be read, - but a retry condition occurred while trying to read the rest. - [Bodo Moeller] - - *) The PKCS7_ENC_CONTENT_new() function was setting the content type as - NID_pkcs7_encrypted by default: this was wrong since this should almost - always be NID_pkcs7_data. Also modified the PKCS7_set_type() to handle - the encrypted data type: this is a more sensible place to put it and it - allows the PKCS#12 code to be tidied up that duplicated this - functionality. - [Steve Henson] - - *) Changed obj_dat.pl script so it takes its input and output files on - the command line. This should avoid shell escape redirection problems - under Win32. - [Steve Henson] - - *) Initial support for certificate extension requests, these are included - in things like Xenroll certificate requests. Included functions to allow - extensions to be obtained and added. - [Steve Henson] - - *) -crlf option to s_client and s_server for sending newlines as - CRLF (as required by many protocols). - [Bodo Moeller] - - Changes between 0.9.3a and 0.9.4 [09 Aug 1999] - - *) Install libRSAglue.a when OpenSSL is built with RSAref. - [Ralf S. Engelschall] - - *) A few more ``#ifndef NO_FP_API / #endif'' pairs for consistency. - [Andrija Antonijevic ] - - *) Fix -startdate and -enddate (which was missing) arguments to 'ca' - program. - [Steve Henson] - - *) New function DSA_dup_DH, which duplicates DSA parameters/keys as - DH parameters/keys (q is lost during that conversion, but the resulting - DH parameters contain its length). - - For 1024-bit p, DSA_generate_parameters followed by DSA_dup_DH is - much faster than DH_generate_parameters (which creates parameters - where p = 2*q + 1), and also the smaller q makes DH computations - much more efficient (160-bit exponentiation instead of 1024-bit - exponentiation); so this provides a convenient way to support DHE - ciphersuites in SSL/TLS servers (see ssl/ssltest.c). It is of - utter importance to use - SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); - or - SSL_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); - when such DH parameters are used, because otherwise small subgroup - attacks may become possible! - [Bodo Moeller] - - *) Avoid memory leak in i2d_DHparams. - [Bodo Moeller] - - *) Allow the -k option to be used more than once in the enc program: - this allows the same encrypted message to be read by multiple recipients. - [Steve Henson] - - *) New function OBJ_obj2txt(buf, buf_len, a, no_name), this converts - an ASN1_OBJECT to a text string. If the "no_name" parameter is set then - it will always use the numerical form of the OID, even if it has a short - or long name. - [Steve Henson] - - *) Added an extra RSA flag: RSA_FLAG_EXT_PKEY. Previously the rsa_mod_exp - method only got called if p,q,dmp1,dmq1,iqmp components were present, - otherwise bn_mod_exp was called. In the case of hardware keys for example - no private key components need be present and it might store extra data - in the RSA structure, which cannot be accessed from bn_mod_exp. - By setting RSA_FLAG_EXT_PKEY rsa_mod_exp will always be called for - private key operations. - [Steve Henson] - - *) Added support for SPARC Linux. - [Andy Polyakov] - - *) pem_password_cb function type incompatibly changed from - typedef int pem_password_cb(char *buf, int size, int rwflag); - to - ....(char *buf, int size, int rwflag, void *userdata); - so that applications can pass data to their callbacks: - The PEM[_ASN1]_{read,write}... functions and macros now take an - additional void * argument, which is just handed through whenever - the password callback is called. - [Damien Miller ; tiny changes by Bodo Moeller] - - New function SSL_CTX_set_default_passwd_cb_userdata. - - Compatibility note: As many C implementations push function arguments - onto the stack in reverse order, the new library version is likely to - interoperate with programs that have been compiled with the old - pem_password_cb definition (PEM_whatever takes some data that - happens to be on the stack as its last argument, and the callback - just ignores this garbage); but there is no guarantee whatsoever that - this will work. - - *) The -DPLATFORM="\"$(PLATFORM)\"" definition and the similar -DCFLAGS=... - (both in crypto/Makefile.ssl for use by crypto/cversion.c) caused - problems not only on Windows, but also on some Unix platforms. - To avoid problematic command lines, these definitions are now in an - auto-generated file crypto/buildinf.h (created by crypto/Makefile.ssl - for standard "make" builds, by util/mk1mf.pl for "mk1mf" builds). - [Bodo Moeller] - - *) MIPS III/IV assembler module is reimplemented. - [Andy Polyakov] - - *) More DES library cleanups: remove references to srand/rand and - delete an unused file. - [Ulf Möller] - - *) Add support for the free Netwide assembler (NASM) under Win32, - since not many people have MASM (ml) and it can be hard to obtain. - This is currently experimental but it seems to work OK and pass all - the tests. Check out INSTALL.W32 for info. - [Steve Henson] - - *) Fix memory leaks in s3_clnt.c: All non-anonymous SSL3/TLS1 connections - without temporary keys kept an extra copy of the server key, - and connections with temporary keys did not free everything in case - of an error. - [Bodo Moeller] - - *) New function RSA_check_key and new openssl rsa option -check - for verifying the consistency of RSA keys. - [Ulf Moeller, Bodo Moeller] - - *) Various changes to make Win32 compile work: - 1. Casts to avoid "loss of data" warnings in p5_crpt2.c - 2. Change unsigned int to int in b_dump.c to avoid "signed/unsigned - comparison" warnings. - 3. Add sk__sort to DEF file generator and do make update. - [Steve Henson] - - *) Add a debugging option to PKCS#5 v2 key generation function: when - you #define DEBUG_PKCS5V2 passwords, salts, iteration counts and - derived keys are printed to stderr. - [Steve Henson] - - *) Copy the flags in ASN1_STRING_dup(). - [Roman E. Pavlov ] - - *) The x509 application mishandled signing requests containing DSA - keys when the signing key was also DSA and the parameters didn't match. - - It was supposed to omit the parameters when they matched the signing key: - the verifying software was then supposed to automatically use the CA's - parameters if they were absent from the end user certificate. - - Omitting parameters is no longer recommended. The test was also - the wrong way round! This was probably due to unusual behaviour in - EVP_cmp_parameters() which returns 1 if the parameters match. - This meant that parameters were omitted when they *didn't* match and - the certificate was useless. Certificates signed with 'ca' didn't have - this bug. - [Steve Henson, reported by Doug Erickson ] - - *) Memory leak checking (-DCRYPTO_MDEBUG) had some problems. - The interface is as follows: - Applications can use - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) aka MemCheck_start(), - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) aka MemCheck_stop(); - "off" is now the default. - The library internally uses - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) aka MemCheck_off(), - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) aka MemCheck_on() - to disable memory-checking temporarily. - - Some inconsistent states that previously were possible (and were - even the default) are now avoided. - - -DCRYPTO_MDEBUG_TIME is new and additionally stores the current time - with each memory chunk allocated; this is occasionally more helpful - than just having a counter. - - -DCRYPTO_MDEBUG_THREAD is also new and adds the thread ID. - - -DCRYPTO_MDEBUG_ALL enables all of the above, plus any future - extensions. - [Bodo Moeller] - - *) Introduce "mode" for SSL structures (with defaults in SSL_CTX), - which largely parallels "options", but is for changing API behaviour, - whereas "options" are about protocol behaviour. - Initial "mode" flags are: - - SSL_MODE_ENABLE_PARTIAL_WRITE Allow SSL_write to report success when - a single record has been written. - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER Don't insist that SSL_write - retries use the same buffer location. - (But all of the contents must be - copied!) - [Bodo Moeller] - - *) Bugfix: SSL_set_options ignored its parameter, only SSL_CTX_set_options - worked. - - *) Fix problems with no-hmac etc. - [Ulf Möller, pointed out by Brian Wellington ] - - *) New functions RSA_get_default_method(), RSA_set_method() and - RSA_get_method(). These allows replacement of RSA_METHODs without having - to mess around with the internals of an RSA structure. - [Steve Henson] - - *) Fix memory leaks in DSA_do_sign and DSA_is_prime. - Also really enable memory leak checks in openssl.c and in some - test programs. - [Chad C. Mulligan, Bodo Moeller] - - *) Fix a bug in d2i_ASN1_INTEGER() and i2d_ASN1_INTEGER() which can mess - up the length of negative integers. This has now been simplified to just - store the length when it is first determined and use it later, rather - than trying to keep track of where data is copied and updating it to - point to the end. - [Steve Henson, reported by Brien Wheeler - ] - - *) Add a new function PKCS7_signatureVerify. This allows the verification - of a PKCS#7 signature but with the signing certificate passed to the - function itself. This contrasts with PKCS7_dataVerify which assumes the - certificate is present in the PKCS#7 structure. This isn't always the - case: certificates can be omitted from a PKCS#7 structure and be - distributed by "out of band" means (such as a certificate database). - [Steve Henson] - - *) Complete the PEM_* macros with DECLARE_PEM versions to replace the - function prototypes in pem.h, also change util/mkdef.pl to add the - necessary function names. - [Steve Henson] - - *) mk1mf.pl (used by Windows builds) did not properly read the - options set by Configure in the top level Makefile, and Configure - was not even able to write more than one option correctly. - Fixed, now "no-idea no-rc5 -DCRYPTO_MDEBUG" etc. works as intended. - [Bodo Moeller] - - *) New functions CONF_load_bio() and CONF_load_fp() to allow a config - file to be loaded from a BIO or FILE pointer. The BIO version will - for example allow memory BIOs to contain config info. - [Steve Henson] - - *) New function "CRYPTO_num_locks" that returns CRYPTO_NUM_LOCKS. - Whoever hopes to achieve shared-library compatibility across versions - must use this, not the compile-time macro. - (Exercise 0.9.4: Which is the minimum library version required by - such programs?) - Note: All this applies only to multi-threaded programs, others don't - need locks. - [Bodo Moeller] - - *) Add missing case to s3_clnt.c state machine -- one of the new SSL tests - through a BIO pair triggered the default case, i.e. - SSLerr(...,SSL_R_UNKNOWN_STATE). - [Bodo Moeller] - - *) New "BIO pair" concept (crypto/bio/bss_bio.c) so that applications - can use the SSL library even if none of the specific BIOs is - appropriate. - [Bodo Moeller] - - *) Fix a bug in i2d_DSAPublicKey() which meant it returned the wrong value - for the encoded length. - [Jeon KyoungHo ] - - *) Add initial documentation of the X509V3 functions. - [Steve Henson] - - *) Add a new pair of functions PEM_write_PKCS8PrivateKey() and - PEM_write_bio_PKCS8PrivateKey() that are equivalent to - PEM_write_PrivateKey() and PEM_write_bio_PrivateKey() but use the more - secure PKCS#8 private key format with a high iteration count. - [Steve Henson] - - *) Fix determination of Perl interpreter: A perl or perl5 - _directory_ in $PATH was also accepted as the interpreter. - [Ralf S. Engelschall] - - *) Fix demos/sign/sign.c: well there wasn't anything strictly speaking - wrong with it but it was very old and did things like calling - PEM_ASN1_read() directly and used MD5 for the hash not to mention some - unusual formatting. - [Steve Henson] - - *) Fix demos/selfsign.c: it used obsolete and deleted functions, changed - to use the new extension code. - [Steve Henson] - - *) Implement the PEM_read/PEM_write functions in crypto/pem/pem_all.c - with macros. This should make it easier to change their form, add extra - arguments etc. Fix a few PEM prototypes which didn't have cipher as a - constant. - [Steve Henson] - - *) Add to configuration table a new entry that can specify an alternative - name for unistd.h (for pre-POSIX systems); we need this for NeXTstep, - according to Mark Crispin . - [Bodo Moeller] - -#if 0 - *) DES CBC did not update the IV. Weird. - [Ben Laurie] -#else - des_cbc_encrypt does not update the IV, but des_ncbc_encrypt does. - Changing the behaviour of the former might break existing programs -- - where IV updating is needed, des_ncbc_encrypt can be used. -#endif - - *) When bntest is run from "make test" it drives bc to check its - calculations, as well as internally checking them. If an internal check - fails, it needs to cause bc to give a non-zero result or make test carries - on without noticing the failure. Fixed. - [Ben Laurie] - - *) DES library cleanups. - [Ulf Möller] - - *) Add support for PKCS#5 v2.0 PBE algorithms. This will permit PKCS#8 to be - used with any cipher unlike PKCS#5 v1.5 which can at most handle 64 bit - ciphers. NOTE: although the key derivation function has been verified - against some published test vectors it has not been extensively tested - yet. Added a -v2 "cipher" option to pkcs8 application to allow the use - of v2.0. - [Steve Henson] - - *) Instead of "mkdir -p", which is not fully portable, use new - Perl script "util/mkdir-p.pl". - [Bodo Moeller] - - *) Rewrite the way password based encryption (PBE) is handled. It used to - assume that the ASN1 AlgorithmIdentifier parameter was a PBEParameter - structure. This was true for the PKCS#5 v1.5 and PKCS#12 PBE algorithms - but doesn't apply to PKCS#5 v2.0 where it can be something else. Now - the 'parameter' field of the AlgorithmIdentifier is passed to the - underlying key generation function so it must do its own ASN1 parsing. - This has also changed the EVP_PBE_CipherInit() function which now has a - 'parameter' argument instead of literal salt and iteration count values - and the function EVP_PBE_ALGOR_CipherInit() has been deleted. - [Steve Henson] - - *) Support for PKCS#5 v1.5 compatible password based encryption algorithms - and PKCS#8 functionality. New 'pkcs8' application linked to openssl. - Needed to change the PEM_STRING_EVP_PKEY value which was just "PRIVATE - KEY" because this clashed with PKCS#8 unencrypted string. Since this - value was just used as a "magic string" and not used directly its - value doesn't matter. - [Steve Henson] - - *) Introduce some semblance of const correctness to BN. Shame C doesn't - support mutable. - [Ben Laurie] - - *) "linux-sparc64" configuration (ultrapenguin). - [Ray Miller ] - "linux-sparc" configuration. - [Christian Forster ] - - *) config now generates no-xxx options for missing ciphers. - [Ulf Möller] - - *) Support the EBCDIC character set (work in progress). - File ebcdic.c not yet included because it has a different license. - [Martin Kraemer ] - - *) Support BS2000/OSD-POSIX. - [Martin Kraemer ] - - *) Make callbacks for key generation use void * instead of char *. - [Ben Laurie] - - *) Make S/MIME samples compile (not yet tested). - [Ben Laurie] - - *) Additional typesafe stacks. - [Ben Laurie] - - *) New configuration variants "bsdi-elf-gcc" (BSD/OS 4.x). - [Bodo Moeller] - - - Changes between 0.9.3 and 0.9.3a [29 May 1999] - - *) New configuration variant "sco5-gcc". - - *) Updated some demos. - [Sean O Riordain, Wade Scholine] - - *) Add missing BIO_free at exit of pkcs12 application. - [Wu Zhigang] - - *) Fix memory leak in conf.c. - [Steve Henson] - - *) Updates for Win32 to assembler version of MD5. - [Steve Henson] - - *) Set #! path to perl in apps/der_chop to where we found it - instead of using a fixed path. - [Bodo Moeller] - - *) SHA library changes for irix64-mips4-cc. - [Andy Polyakov] - - *) Improvements for VMS support. - [Richard Levitte] - - - Changes between 0.9.2b and 0.9.3 [24 May 1999] - - *) Bignum library bug fix. IRIX 6 passes "make test" now! - This also avoids the problems with SC4.2 and unpatched SC5. - [Andy Polyakov ] - - *) New functions sk_num, sk_value and sk_set to replace the previous macros. - These are required because of the typesafe stack would otherwise break - existing code. If old code used a structure member which used to be STACK - and is now STACK_OF (for example cert in a PKCS7_SIGNED structure) with - sk_num or sk_value it would produce an error because the num, data members - are not present in STACK_OF. Now it just produces a warning. sk_set - replaces the old method of assigning a value to sk_value - (e.g. sk_value(x, i) = y) which the library used in a few cases. Any code - that does this will no longer work (and should use sk_set instead) but - this could be regarded as a "questionable" behaviour anyway. - [Steve Henson] - - *) Fix most of the other PKCS#7 bugs. The "experimental" code can now - correctly handle encrypted S/MIME data. - [Steve Henson] - - *) Change type of various DES function arguments from des_cblock - (which means, in function argument declarations, pointer to char) - to des_cblock * (meaning pointer to array with 8 char elements), - which allows the compiler to do more typechecking; it was like - that back in SSLeay, but with lots of ugly casts. - - Introduce new type const_des_cblock. - [Bodo Moeller] - - *) Reorganise the PKCS#7 library and get rid of some of the more obvious - problems: find RecipientInfo structure that matches recipient certificate - and initialise the ASN1 structures properly based on passed cipher. - [Steve Henson] - - *) Belatedly make the BN tests actually check the results. - [Ben Laurie] - - *) Fix the encoding and decoding of negative ASN1 INTEGERS and conversion - to and from BNs: it was completely broken. New compilation option - NEG_PUBKEY_BUG to allow for some broken certificates that encode public - key elements as negative integers. - [Steve Henson] - - *) Reorganize and speed up MD5. - [Andy Polyakov ] - - *) VMS support. - [Richard Levitte ] - - *) New option -out to asn1parse to allow the parsed structure to be - output to a file. This is most useful when combined with the -strparse - option to examine the output of things like OCTET STRINGS. - [Steve Henson] - - *) Make SSL library a little more fool-proof by not requiring any longer - that SSL_set_{accept,connect}_state be called before - SSL_{accept,connect} may be used (SSL_set_..._state is omitted - in many applications because usually everything *appeared* to work as - intended anyway -- now it really works as intended). - [Bodo Moeller] - - *) Move openssl.cnf out of lib/. - [Ulf Möller] - - *) Fix various things to let OpenSSL even pass ``egcc -pipe -O2 -Wall - -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes - -Wmissing-declarations -Wnested-externs -Winline'' with EGCS 1.1.2+ - [Ralf S. Engelschall] - - *) Various fixes to the EVP and PKCS#7 code. It may now be able to - handle PKCS#7 enveloped data properly. - [Sebastian Akerman , modified by Steve] - - *) Create a duplicate of the SSL_CTX's CERT in SSL_new instead of - copying pointers. The cert_st handling is changed by this in - various ways (and thus what used to be known as ctx->default_cert - is now called ctx->cert, since we don't resort to s->ctx->[default_]cert - any longer when s->cert does not give us what we need). - ssl_cert_instantiate becomes obsolete by this change. - As soon as we've got the new code right (possibly it already is?), - we have solved a couple of bugs of the earlier code where s->cert - was used as if it could not have been shared with other SSL structures. - - Note that using the SSL API in certain dirty ways now will result - in different behaviour than observed with earlier library versions: - Changing settings for an SSL_CTX *ctx after having done s = SSL_new(ctx) - does not influence s as it used to. - - In order to clean up things more thoroughly, inside SSL_SESSION - we don't use CERT any longer, but a new structure SESS_CERT - that holds per-session data (if available); currently, this is - the peer's certificate chain and, for clients, the server's certificate - and temporary key. CERT holds only those values that can have - meaningful defaults in an SSL_CTX. - [Bodo Moeller] - - *) New function X509V3_EXT_i2d() to create an X509_EXTENSION structure - from the internal representation. Various PKCS#7 fixes: remove some - evil casts and set the enc_dig_alg field properly based on the signing - key type. - [Steve Henson] - - *) Allow PKCS#12 password to be set from the command line or the - environment. Let 'ca' get its config file name from the environment - variables "OPENSSL_CONF" or "SSLEAY_CONF" (for consistency with 'req' - and 'x509'). - [Steve Henson] - - *) Allow certificate policies extension to use an IA5STRING for the - organization field. This is contrary to the PKIX definition but - VeriSign uses it and IE5 only recognises this form. Document 'x509' - extension option. - [Steve Henson] - - *) Add PEDANTIC compiler flag to allow compilation with gcc -pedantic, - without disallowing inline assembler and the like for non-pedantic builds. - [Ben Laurie] - - *) Support Borland C++ builder. - [Janez Jere , modified by Ulf Möller] - - *) Support Mingw32. - [Ulf Möller] - - *) SHA-1 cleanups and performance enhancements. - [Andy Polyakov ] - - *) Sparc v8plus assembler for the bignum library. - [Andy Polyakov ] - - *) Accept any -xxx and +xxx compiler options in Configure. - [Ulf Möller] - - *) Update HPUX configuration. - [Anonymous] - - *) Add missing sk__unshift() function to safestack.h - [Ralf S. Engelschall] - - *) New function SSL_CTX_use_certificate_chain_file that sets the - "extra_cert"s in addition to the certificate. (This makes sense - only for "PEM" format files, as chains as a whole are not - DER-encoded.) - [Bodo Moeller] - - *) Support verify_depth from the SSL API. - x509_vfy.c had what can be considered an off-by-one-error: - Its depth (which was not part of the external interface) - was actually counting the number of certificates in a chain; - now it really counts the depth. - [Bodo Moeller] - - *) Bugfix in crypto/x509/x509_cmp.c: The SSLerr macro was used - instead of X509err, which often resulted in confusing error - messages since the error codes are not globally unique - (e.g. an alleged error in ssl3_accept when a certificate - didn't match the private key). - - *) New function SSL_CTX_set_session_id_context that allows to set a default - value (so that you don't need SSL_set_session_id_context for each - connection using the SSL_CTX). - [Bodo Moeller] - - *) OAEP decoding bug fix. - [Ulf Möller] - - *) Support INSTALL_PREFIX for package builders, as proposed by - David Harris. - [Bodo Moeller] - - *) New Configure options "threads" and "no-threads". For systems - where the proper compiler options are known (currently Solaris - and Linux), "threads" is the default. - [Bodo Moeller] - - *) New script util/mklink.pl as a faster substitute for util/mklink.sh. - [Bodo Moeller] - - *) Install various scripts to $(OPENSSLDIR)/misc, not to - $(INSTALLTOP)/bin -- they shouldn't clutter directories - such as /usr/local/bin. - [Bodo Moeller] - - *) "make linux-shared" to build shared libraries. - [Niels Poppe ] - - *) New Configure option no- (rsa, idea, rc5, ...). - [Ulf Möller] - - *) Add the PKCS#12 API documentation to openssl.txt. Preliminary support for - extension adding in x509 utility. - [Steve Henson] - - *) Remove NOPROTO sections and error code comments. - [Ulf Möller] - - *) Partial rewrite of the DEF file generator to now parse the ANSI - prototypes. - [Steve Henson] - - *) New Configure options --prefix=DIR and --openssldir=DIR. - [Ulf Möller] - - *) Complete rewrite of the error code script(s). It is all now handled - by one script at the top level which handles error code gathering, - header rewriting and C source file generation. It should be much better - than the old method: it now uses a modified version of Ulf's parser to - read the ANSI prototypes in all header files (thus the old K&R definitions - aren't needed for error creation any more) and do a better job of - translating function codes into names. The old 'ASN1 error code embedded - in a comment' is no longer necessary and it doesn't use .err files which - have now been deleted. Also the error code call doesn't have to appear all - on one line (which resulted in some large lines...). - [Steve Henson] - - *) Change #include filenames from to . - [Bodo Moeller] - - *) Change behaviour of ssl2_read when facing length-0 packets: Don't return - 0 (which usually indicates a closed connection), but continue reading. - [Bodo Moeller] - - *) Fix some race conditions. - [Bodo Moeller] - - *) Add support for CRL distribution points extension. Add Certificate - Policies and CRL distribution points documentation. - [Steve Henson] - - *) Move the autogenerated header file parts to crypto/opensslconf.h. - [Ulf Möller] - - *) Fix new 56-bit DES export ciphersuites: they were using 7 bytes instead of - 8 of keying material. Merlin has also confirmed interop with this fix - between OpenSSL and Baltimore C/SSL 2.0 and J/SSL 2.0. - [Merlin Hughes ] - - *) Fix lots of warnings. - [Richard Levitte ] - - *) In add_cert_dir() in crypto/x509/by_dir.c, break out of the loop if - the directory spec didn't end with a LIST_SEPARATOR_CHAR. - [Richard Levitte ] - - *) Fix problems with sizeof(long) == 8. - [Andy Polyakov ] - - *) Change functions to ANSI C. - [Ulf Möller] - - *) Fix typos in error codes. - [Martin Kraemer , Ulf Möller] - - *) Remove defunct assembler files from Configure. - [Ulf Möller] - - *) SPARC v8 assembler BIGNUM implementation. - [Andy Polyakov ] - - *) Support for Certificate Policies extension: both print and set. - Various additions to support the r2i method this uses. - [Steve Henson] - - *) A lot of constification, and fix a bug in X509_NAME_oneline() that could - return a const string when you are expecting an allocated buffer. - [Ben Laurie] - - *) Add support for ASN1 types UTF8String and VISIBLESTRING, also the CHOICE - types DirectoryString and DisplayText. - [Steve Henson] - - *) Add code to allow r2i extensions to access the configuration database, - add an LHASH database driver and add several ctx helper functions. - [Steve Henson] - - *) Fix an evil bug in bn_expand2() which caused various BN functions to - fail when they extended the size of a BIGNUM. - [Steve Henson] - - *) Various utility functions to handle SXNet extension. Modify mkdef.pl to - support typesafe stack. - [Steve Henson] - - *) Fix typo in SSL_[gs]et_options(). - [Nils Frostberg ] - - *) Delete various functions and files that belonged to the (now obsolete) - old X509V3 handling code. - [Steve Henson] - - *) New Configure option "rsaref". - [Ulf Möller] - - *) Don't auto-generate pem.h. - [Bodo Moeller] - - *) Introduce type-safe ASN.1 SETs. - [Ben Laurie] - - *) Convert various additional casted stacks to type-safe STACK_OF() variants. - [Ben Laurie, Ralf S. Engelschall, Steve Henson] - - *) Introduce type-safe STACKs. This will almost certainly break lots of code - that links with OpenSSL (well at least cause lots of warnings), but fear - not: the conversion is trivial, and it eliminates loads of evil casts. A - few STACKed things have been converted already. Feel free to convert more. - In the fullness of time, I'll do away with the STACK type altogether. - [Ben Laurie] - - *) Add `openssl ca -revoke ' facility which revokes a certificate - specified in by updating the entry in the index.txt file. - This way one no longer has to edit the index.txt file manually for - revoking a certificate. The -revoke option does the gory details now. - [Massimiliano Pala , Ralf S. Engelschall] - - *) Fix `openssl crl -noout -text' combination where `-noout' killed the - `-text' option at all and this way the `-noout -text' combination was - inconsistent in `openssl crl' with the friends in `openssl x509|rsa|dsa'. - [Ralf S. Engelschall] - - *) Make sure a corresponding plain text error message exists for the - X509_V_ERR_CERT_REVOKED/23 error number which can occur when a - verify callback function determined that a certificate was revoked. - [Ralf S. Engelschall] - - *) Bugfix: In test/testenc, don't test "openssl " for - ciphers that were excluded, e.g. by -DNO_IDEA. Also, test - all available ciphers including rc5, which was forgotten until now. - In order to let the testing shell script know which algorithms - are available, a new (up to now undocumented) command - "openssl list-cipher-commands" is used. - [Bodo Moeller] - - *) Bugfix: s_client occasionally would sleep in select() when - it should have checked SSL_pending() first. - [Bodo Moeller] - - *) New functions DSA_do_sign and DSA_do_verify to provide access to - the raw DSA values prior to ASN.1 encoding. - [Ulf Möller] - - *) Tweaks to Configure - [Niels Poppe ] - - *) Add support for PKCS#5 v2.0 ASN1 PBES2 structures. No other support, - yet... - [Steve Henson] - - *) New variables $(RANLIB) and $(PERL) in the Makefiles. - [Ulf Möller] - - *) New config option to avoid instructions that are illegal on the 80386. - The default code is faster, but requires at least a 486. - [Ulf Möller] - - *) Got rid of old SSL2_CLIENT_VERSION (inconsistently used) and - SSL2_SERVER_VERSION (not used at all) macros, which are now the - same as SSL2_VERSION anyway. - [Bodo Moeller] - - *) New "-showcerts" option for s_client. - [Bodo Moeller] - - *) Still more PKCS#12 integration. Add pkcs12 application to openssl - application. Various cleanups and fixes. - [Steve Henson] - - *) More PKCS#12 integration. Add new pkcs12 directory with Makefile.ssl and - modify error routines to work internally. Add error codes and PBE init - to library startup routines. - [Steve Henson] - - *) Further PKCS#12 integration. Added password based encryption, PKCS#8 and - packing functions to asn1 and evp. Changed function names and error - codes along the way. - [Steve Henson] - - *) PKCS12 integration: and so it begins... First of several patches to - slowly integrate PKCS#12 functionality into OpenSSL. Add PKCS#12 - objects to objects.h - [Steve Henson] - - *) Add a new 'indent' option to some X509V3 extension code. Initial ASN1 - and display support for Thawte strong extranet extension. - [Steve Henson] - - *) Add LinuxPPC support. - [Jeff Dubrule ] - - *) Get rid of redundant BN file bn_mulw.c, and rename bn_div64 to - bn_div_words in alpha.s. - [Hannes Reinecke and Ben Laurie] - - *) Make sure the RSA OAEP test is skipped under -DRSAref because - OAEP isn't supported when OpenSSL is built with RSAref. - [Ulf Moeller ] - - *) Move definitions of IS_SET/IS_SEQUENCE inside crypto/asn1/asn1.h - so they no longer are missing under -DNOPROTO. - [Soren S. Jorvang ] - - - Changes between 0.9.1c and 0.9.2b [22 Mar 1999] - - *) Make SSL_get_peer_cert_chain() work in servers. Unfortunately, it still - doesn't work when the session is reused. Coming soon! - [Ben Laurie] - - *) Fix a security hole, that allows sessions to be reused in the wrong - context thus bypassing client cert protection! All software that uses - client certs and session caches in multiple contexts NEEDS PATCHING to - allow session reuse! A fuller solution is in the works. - [Ben Laurie, problem pointed out by Holger Reif, Bodo Moeller (and ???)] - - *) Some more source tree cleanups (removed obsolete files - crypto/bf/asm/bf586.pl, test/test.txt and crypto/sha/asm/f.s; changed - permission on "config" script to be executable) and a fix for the INSTALL - document. - [Ulf Moeller ] - - *) Remove some legacy and erroneous uses of malloc, free instead of - Malloc, Free. - [Lennart Bang , with minor changes by Steve] - - *) Make rsa_oaep_test return non-zero on error. - [Ulf Moeller ] - - *) Add support for native Solaris shared libraries. Configure - solaris-sparc-sc4-pic, make, then run shlib/solaris-sc4.sh. It'd be nice - if someone would make that last step automatic. - [Matthias Loepfe ] - - *) ctx_size was not built with the right compiler during "make links". Fixed. - [Ben Laurie] - - *) Change the meaning of 'ALL' in the cipher list. It now means "everything - except NULL ciphers". This means the default cipher list will no longer - enable NULL ciphers. They need to be specifically enabled e.g. with - the string "DEFAULT:eNULL". - [Steve Henson] - - *) Fix to RSA private encryption routines: if p < q then it would - occasionally produce an invalid result. This will only happen with - externally generated keys because OpenSSL (and SSLeay) ensure p > q. - [Steve Henson] - - *) Be less restrictive and allow also `perl util/perlpath.pl - /path/to/bin/perl' in addition to `perl util/perlpath.pl /path/to/bin', - because this way one can also use an interpreter named `perl5' (which is - usually the name of Perl 5.xxx on platforms where an Perl 4.x is still - installed as `perl'). - [Matthias Loepfe ] - - *) Let util/clean-depend.pl work also with older Perl 5.00x versions. - [Matthias Loepfe ] - - *) Fix Makefile.org so CC,CFLAG etc are passed to 'make links' add - advapi32.lib to Win32 build and change the pem test comparison - to fc.exe (thanks to Ulrich Kroener for the - suggestion). Fix misplaced ASNI prototypes and declarations in evp.h - and crypto/des/ede_cbcm_enc.c. - [Steve Henson] - - *) DES quad checksum was broken on big-endian architectures. Fixed. - [Ben Laurie] - - *) Comment out two functions in bio.h that aren't implemented. Fix up the - Win32 test batch file so it (might) work again. The Win32 test batch file - is horrible: I feel ill.... - [Steve Henson] - - *) Move various #ifdefs around so NO_SYSLOG, NO_DIRENT etc are now selected - in e_os.h. Audit of header files to check ANSI and non ANSI - sections: 10 functions were absent from non ANSI section and not exported - from Windows DLLs. Fixed up libeay.num for new functions. - [Steve Henson] - - *) Make `openssl version' output lines consistent. - [Ralf S. Engelschall] - - *) Fix Win32 symbol export lists for BIO functions: Added - BIO_get_ex_new_index, BIO_get_ex_num, BIO_get_ex_data and BIO_set_ex_data - to ms/libeay{16,32}.def. - [Ralf S. Engelschall] - - *) Second round of fixing the OpenSSL perl/ stuff. It now at least compiled - fine under Unix and passes some trivial tests I've now added. But the - whole stuff is horribly incomplete, so a README.1ST with a disclaimer was - added to make sure no one expects that this stuff really works in the - OpenSSL 0.9.2 release. Additionally I've started to clean the XS sources - up and fixed a few little bugs and inconsistencies in OpenSSL.{pm,xs} and - openssl_bio.xs. - [Ralf S. Engelschall] - - *) Fix the generation of two part addresses in perl. - [Kenji Miyake , integrated by Ben Laurie] - - *) Add config entry for Linux on MIPS. - [John Tobey ] - - *) Make links whenever Configure is run, unless we are on Windoze. - [Ben Laurie] - - *) Permit extensions to be added to CRLs using crl_section in openssl.cnf. - Currently only issuerAltName and AuthorityKeyIdentifier make any sense - in CRLs. - [Steve Henson] - - *) Add a useful kludge to allow package maintainers to specify compiler and - other platforms details on the command line without having to patch the - Configure script every time: One now can use ``perl Configure - :
'', i.e. platform ids are allowed to have details appended - to them (separated by colons). This is treated as there would be a static - pre-configured entry in Configure's %table under key with value -
and ``perl Configure '' is called. So, when you want to - perform a quick test-compile under FreeBSD 3.1 with pgcc and without - assembler stuff you can use ``perl Configure "FreeBSD-elf:pgcc:-O6:::"'' - now, which overrides the FreeBSD-elf entry on-the-fly. - [Ralf S. Engelschall] - - *) Disable new TLS1 ciphersuites by default: they aren't official yet. - [Ben Laurie] - - *) Allow DSO flags like -fpic, -fPIC, -KPIC etc. to be specified - on the `perl Configure ...' command line. This way one can compile - OpenSSL libraries with Position Independent Code (PIC) which is needed - for linking it into DSOs. - [Ralf S. Engelschall] - - *) Remarkably, export ciphers were totally broken and no-one had noticed! - Fixed. - [Ben Laurie] - - *) Cleaned up the LICENSE document: The official contact for any license - questions now is the OpenSSL core team under openssl-core@openssl.org. - And add a paragraph about the dual-license situation to make sure people - recognize that _BOTH_ the OpenSSL license _AND_ the SSLeay license apply - to the OpenSSL toolkit. - [Ralf S. Engelschall] - - *) General source tree makefile cleanups: Made `making xxx in yyy...' - display consistent in the source tree and replaced `/bin/rm' by `rm'. - Additionally cleaned up the `make links' target: Remove unnecessary - semicolons, subsequent redundant removes, inline point.sh into mklink.sh - to speed processing and no longer clutter the display with confusing - stuff. Instead only the actually done links are displayed. - [Ralf S. Engelschall] - - *) Permit null encryption ciphersuites, used for authentication only. It used - to be necessary to set the preprocessor define SSL_ALLOW_ENULL to do this. - It is now necessary to set SSL_FORBID_ENULL to prevent the use of null - encryption. - [Ben Laurie] - - *) Add a bunch of fixes to the PKCS#7 stuff. It used to sometimes reorder - signed attributes when verifying signatures (this would break them), - the detached data encoding was wrong and public keys obtained using - X509_get_pubkey() weren't freed. - [Steve Henson] - - *) Add text documentation for the BUFFER functions. Also added a work around - to a Win95 console bug. This was triggered by the password read stuff: the - last character typed gets carried over to the next fread(). If you were - generating a new cert request using 'req' for example then the last - character of the passphrase would be CR which would then enter the first - field as blank. - [Steve Henson] - - *) Added the new `Includes OpenSSL Cryptography Software' button as - doc/openssl_button.{gif,html} which is similar in style to the old SSLeay - button and can be used by applications based on OpenSSL to show the - relationship to the OpenSSL project. - [Ralf S. Engelschall] - - *) Remove confusing variables in function signatures in files - ssl/ssl_lib.c and ssl/ssl.h. - [Lennart Bong ] - - *) Don't install bss_file.c under PREFIX/include/ - [Lennart Bong ] - - *) Get the Win32 compile working again. Modify mkdef.pl so it can handle - functions that return function pointers and has support for NT specific - stuff. Fix mk1mf.pl and VC-32.pl to support NT differences also. Various - #ifdef WIN32 and WINNTs sprinkled about the place and some changes from - unsigned to signed types: this was killing the Win32 compile. - [Steve Henson] - - *) Add new certificate file to stack functions, - SSL_add_dir_cert_subjects_to_stack() and - SSL_add_file_cert_subjects_to_stack(). These largely supplant - SSL_load_client_CA_file(), and can be used to add multiple certs easily - to a stack (usually this is then handed to SSL_CTX_set_client_CA_list()). - This means that Apache-SSL and similar packages don't have to mess around - to add as many CAs as they want to the preferred list. - [Ben Laurie] - - *) Experiment with doxygen documentation. Currently only partially applied to - ssl/ssl_lib.c. - See http://www.stack.nl/~dimitri/doxygen/index.html, and run doxygen with - openssl.doxy as the configuration file. - [Ben Laurie] - - *) Get rid of remaining C++-style comments which strict C compilers hate. - [Ralf S. Engelschall, pointed out by Carlos Amengual] - - *) Changed BN_RECURSION in bn_mont.c to BN_RECURSION_MONT so it is not - compiled in by default: it has problems with large keys. - [Steve Henson] - - *) Add a bunch of SSL_xxx() functions for configuring the temporary RSA and - DH private keys and/or callback functions which directly correspond to - their SSL_CTX_xxx() counterparts but work on a per-connection basis. This - is needed for applications which have to configure certificates on a - per-connection basis (e.g. Apache+mod_ssl) instead of a per-context basis - (e.g. s_server). - For the RSA certificate situation is makes no difference, but - for the DSA certificate situation this fixes the "no shared cipher" - problem where the OpenSSL cipher selection procedure failed because the - temporary keys were not overtaken from the context and the API provided - no way to reconfigure them. - The new functions now let applications reconfigure the stuff and they - are in detail: SSL_need_tmp_RSA, SSL_set_tmp_rsa, SSL_set_tmp_dh, - SSL_set_tmp_rsa_callback and SSL_set_tmp_dh_callback. Additionally a new - non-public-API function ssl_cert_instantiate() is used as a helper - function and also to reduce code redundancy inside ssl_rsa.c. - [Ralf S. Engelschall] - - *) Move s_server -dcert and -dkey options out of the undocumented feature - area because they are useful for the DSA situation and should be - recognized by the users. - [Ralf S. Engelschall] - - *) Fix the cipher decision scheme for export ciphers: the export bits are - *not* within SSL_MKEY_MASK or SSL_AUTH_MASK, they are within - SSL_EXP_MASK. So, the original variable has to be used instead of the - already masked variable. - [Richard Levitte ] - - *) Fix 'port' variable from `int' to `unsigned int' in crypto/bio/b_sock.c - [Richard Levitte ] - - *) Change type of another md_len variable in pk7_doit.c:PKCS7_dataFinal() - from `int' to `unsigned int' because it's a length and initialized by - EVP_DigestFinal() which expects an `unsigned int *'. - [Richard Levitte ] - - *) Don't hard-code path to Perl interpreter on shebang line of Configure - script. Instead use the usual Shell->Perl transition trick. - [Ralf S. Engelschall] - - *) Make `openssl x509 -noout -modulus' functional also for DSA certificates - (in addition to RSA certificates) to match the behaviour of `openssl dsa - -noout -modulus' as it's already the case for `openssl rsa -noout - -modulus'. For RSA the -modulus is the real "modulus" while for DSA - currently the public key is printed (a decision which was already done by - `openssl dsa -modulus' in the past) which serves a similar purpose. - Additionally the NO_RSA no longer completely removes the whole -modulus - option; it now only avoids using the RSA stuff. Same applies to NO_DSA - now, too. - [Ralf S. Engelschall] - - *) Add Arne Ansper's reliable BIO - this is an encrypted, block-digested - BIO. See the source (crypto/evp/bio_ok.c) for more info. - [Arne Ansper ] - - *) Dump the old yucky req code that tried (and failed) to allow raw OIDs - to be added. Now both 'req' and 'ca' can use new objects defined in the - config file. - [Steve Henson] - - *) Add cool BIO that does syslog (or event log on NT). - [Arne Ansper , integrated by Ben Laurie] - - *) Add support for new TLS ciphersuites, TLS_RSA_EXPORT56_WITH_RC4_56_MD5, - TLS_RSA_EXPORT56_WITH_RC2_CBC_56_MD5 and - TLS_RSA_EXPORT56_WITH_DES_CBC_SHA, as specified in "56-bit Export Cipher - Suites For TLS", draft-ietf-tls-56-bit-ciphersuites-00.txt. - [Ben Laurie] - - *) Add preliminary config info for new extension code. - [Steve Henson] - - *) Make RSA_NO_PADDING really use no padding. - [Ulf Moeller ] - - *) Generate errors when private/public key check is done. - [Ben Laurie] - - *) Overhaul for 'crl' utility. New function X509_CRL_print. Partial support - for some CRL extensions and new objects added. - [Steve Henson] - - *) Really fix the ASN1 IMPLICIT bug this time... Partial support for private - key usage extension and fuller support for authority key id. - [Steve Henson] - - *) Add OAEP encryption for the OpenSSL crypto library. OAEP is the improved - padding method for RSA, which is recommended for new applications in PKCS - #1 v2.0 (RFC 2437, October 1998). - OAEP (Optimal Asymmetric Encryption Padding) has better theoretical - foundations than the ad-hoc padding used in PKCS #1 v1.5. It is secure - against Bleichbacher's attack on RSA. - [Ulf Moeller , reformatted, corrected and integrated by - Ben Laurie] - - *) Updates to the new SSL compression code - [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] - - *) Fix so that the version number in the master secret, when passed - via RSA, checks that if TLS was proposed, but we roll back to SSLv3 - (because the server will not accept higher), that the version number - is 0x03,0x01, not 0x03,0x00 - [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] - - *) Run extensive memory leak checks on SSL apps. Fixed *lots* of memory - leaks in ssl/ relating to new X509_get_pubkey() behaviour. Also fixes - in apps/ and an unrelated leak in crypto/dsa/dsa_vrf.c - [Steve Henson] - - *) Support for RAW extensions where an arbitrary extension can be - created by including its DER encoding. See apps/openssl.cnf for - an example. - [Steve Henson] - - *) Make sure latest Perl versions don't interpret some generated C array - code as Perl array code in the crypto/err/err_genc.pl script. - [Lars Weber <3weber@informatik.uni-hamburg.de>] - - *) Modify ms/do_ms.bat to not generate assembly language makefiles since - not many people have the assembler. Various Win32 compilation fixes and - update to the INSTALL.W32 file with (hopefully) more accurate Win32 - build instructions. - [Steve Henson] - - *) Modify configure script 'Configure' to automatically create crypto/date.h - file under Win32 and also build pem.h from pem.org. New script - util/mkfiles.pl to create the MINFO file on environments that can't do a - 'make files': perl util/mkfiles.pl >MINFO should work. - [Steve Henson] - - *) Major rework of DES function declarations, in the pursuit of correctness - and purity. As a result, many evil casts evaporated, and some weirdness, - too. You may find this causes warnings in your code. Zapping your evil - casts will probably fix them. Mostly. - [Ben Laurie] - - *) Fix for a typo in asn1.h. Bug fix to object creation script - obj_dat.pl. It considered a zero in an object definition to mean - "end of object": none of the objects in objects.h have any zeros - so it wasn't spotted. - [Steve Henson, reported by Erwann ABALEA ] - - *) Add support for Triple DES Cipher Block Chaining with Output Feedback - Masking (CBCM). In the absence of test vectors, the best I have been able - to do is check that the decrypt undoes the encrypt, so far. Send me test - vectors if you have them. - [Ben Laurie] - - *) Correct calculation of key length for export ciphers (too much space was - allocated for null ciphers). This has not been tested! - [Ben Laurie] - - *) Modifications to the mkdef.pl for Win32 DEF file creation. The usage - message is now correct (it understands "crypto" and "ssl" on its - command line). There is also now an "update" option. This will update - the util/ssleay.num and util/libeay.num files with any new functions. - If you do a: - perl util/mkdef.pl crypto ssl update - it will update them. - [Steve Henson] - - *) Overhauled the Perl interface (perl/*): - - ported BN stuff to OpenSSL's different BN library - - made the perl/ source tree CVS-aware - - renamed the package from SSLeay to OpenSSL (the files still contain - their history because I've copied them in the repository) - - removed obsolete files (the test scripts will be replaced - by better Test::Harness variants in the future) - [Ralf S. Engelschall] - - *) First cut for a very conservative source tree cleanup: - 1. merge various obsolete readme texts into doc/ssleay.txt - where we collect the old documents and readme texts. - 2. remove the first part of files where I'm already sure that we no - longer need them because of three reasons: either they are just temporary - files which were left by Eric or they are preserved original files where - I've verified that the diff is also available in the CVS via "cvs diff - -rSSLeay_0_8_1b" or they were renamed (as it was definitely the case for - the crypto/md/ stuff). - [Ralf S. Engelschall] - - *) More extension code. Incomplete support for subject and issuer alt - name, issuer and authority key id. Change the i2v function parameters - and add an extra 'crl' parameter in the X509V3_CTX structure: guess - what that's for :-) Fix to ASN1 macro which messed up - IMPLICIT tag and add f_enum.c which adds a2i, i2a for ENUMERATED. - [Steve Henson] - - *) Preliminary support for ENUMERATED type. This is largely copied from the - INTEGER code. - [Steve Henson] - - *) Add new function, EVP_MD_CTX_copy() to replace frequent use of memcpy. - [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] - - *) Make sure `make rehash' target really finds the `openssl' program. - [Ralf S. Engelschall, Matthias Loepfe ] - - *) Squeeze another 7% of speed out of MD5 assembler, at least on a P2. I'd - like to hear about it if this slows down other processors. - [Ben Laurie] - - *) Add CygWin32 platform information to Configure script. - [Alan Batie ] - - *) Fixed ms/32all.bat script: `no_asm' -> `no-asm' - [Rainer W. Gerling ] - - *) New program nseq to manipulate netscape certificate sequences - [Steve Henson] - - *) Modify crl2pkcs7 so it supports multiple -certfile arguments. Fix a - few typos. - [Steve Henson] - - *) Fixes to BN code. Previously the default was to define BN_RECURSION - but the BN code had some problems that would cause failures when - doing certificate verification and some other functions. - [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] - - *) Add ASN1 and PEM code to support netscape certificate sequences. - [Steve Henson] - - *) Add ASN1 and PEM code to support netscape certificate sequences. - [Steve Henson] - - *) Add several PKIX and private extended key usage OIDs. - [Steve Henson] - - *) Modify the 'ca' program to handle the new extension code. Modify - openssl.cnf for new extension format, add comments. - [Steve Henson] - - *) More X509 V3 changes. Fix typo in v3_bitstr.c. Add support to 'req' - and add a sample to openssl.cnf so req -x509 now adds appropriate - CA extensions. - [Steve Henson] - - *) Continued X509 V3 changes. Add to other makefiles, integrate with the - error code, add initial support to X509_print() and x509 application. - [Steve Henson] - - *) Takes a deep breath and start adding X509 V3 extension support code. Add - files in crypto/x509v3. Move original stuff to crypto/x509v3/old. All this - stuff is currently isolated and isn't even compiled yet. - [Steve Henson] - - *) Continuing patches for GeneralizedTime. Fix up certificate and CRL - ASN1 to use ASN1_TIME and modify print routines to use ASN1_TIME_print. - Removed the versions check from X509 routines when loading extensions: - this allows certain broken certificates that don't set the version - properly to be processed. - [Steve Henson] - - *) Deal with irritating shit to do with dependencies, in YAAHW (Yet Another - Ad Hoc Way) - Makefile.ssls now all contain local dependencies, which - can still be regenerated with "make depend". - [Ben Laurie] - - *) Spelling mistake in C version of CAST-128. - [Ben Laurie, reported by Jeremy Hylton ] - - *) Changes to the error generation code. The perl script err-code.pl - now reads in the old error codes and retains the old numbers, only - adding new ones if necessary. It also only changes the .err files if new - codes are added. The makefiles have been modified to only insert errors - when needed (to avoid needlessly modifying header files). This is done - by only inserting errors if the .err file is newer than the auto generated - C file. To rebuild all the error codes from scratch (the old behaviour) - either modify crypto/Makefile.ssl to pass the -regen flag to err_code.pl - or delete all the .err files. - [Steve Henson] - - *) CAST-128 was incorrectly implemented for short keys. The C version has - been fixed, but is untested. The assembler versions are also fixed, but - new assembler HAS NOT BEEN GENERATED FOR WIN32 - the Makefile needs fixing - to regenerate it if needed. - [Ben Laurie, reported (with fix for C version) by Jun-ichiro itojun - Hagino ] - - *) File was opened incorrectly in randfile.c. - [Ulf Möller ] - - *) Beginning of support for GeneralizedTime. d2i, i2d, check and print - functions. Also ASN1_TIME suite which is a CHOICE of UTCTime or - GeneralizedTime. ASN1_TIME is the proper type used in certificates et - al: it's just almost always a UTCTime. Note this patch adds new error - codes so do a "make errors" if there are problems. - [Steve Henson] - - *) Correct Linux 1 recognition in config. - [Ulf Möller ] - - *) Remove pointless MD5 hash when using DSA keys in ca. - [Anonymous ] - - *) Generate an error if given an empty string as a cert directory. Also - generate an error if handed NULL (previously returned 0 to indicate an - error, but didn't set one). - [Ben Laurie, reported by Anonymous ] - - *) Add prototypes to SSL methods. Make SSL_write's buffer const, at last. - [Ben Laurie] - - *) Fix the dummy function BN_ref_mod_exp() in rsaref.c to have the correct - parameters. This was causing a warning which killed off the Win32 compile. - [Steve Henson] - - *) Remove C++ style comments from crypto/bn/bn_local.h. - [Neil Costigan ] - - *) The function OBJ_txt2nid was broken. It was supposed to return a nid - based on a text string, looking up short and long names and finally - "dot" format. The "dot" format stuff didn't work. Added new function - OBJ_txt2obj to do the same but return an ASN1_OBJECT and rewrote - OBJ_txt2nid to use it. OBJ_txt2obj can also return objects even if the - OID is not part of the table. - [Steve Henson] - - *) Add prototypes to X509 lookup/verify methods, fixing a bug in - X509_LOOKUP_by_alias(). - [Ben Laurie] - - *) Sort openssl functions by name. - [Ben Laurie] - - *) Get the gendsa program working (hopefully) and add it to app list. Remove - encryption from sample DSA keys (in case anyone is interested the password - was "1234"). - [Steve Henson] - - *) Make _all_ *_free functions accept a NULL pointer. - [Frans Heymans ] - - *) If a DH key is generated in s3_srvr.c, don't blow it by trying to use - NULL pointers. - [Anonymous ] - - *) s_server should send the CAfile as acceptable CAs, not its own cert. - [Bodo Moeller <3moeller@informatik.uni-hamburg.de>] - - *) Don't blow it for numeric -newkey arguments to apps/req. - [Bodo Moeller <3moeller@informatik.uni-hamburg.de>] - - *) Temp key "for export" tests were wrong in s3_srvr.c. - [Anonymous ] - - *) Add prototype for temp key callback functions - SSL_CTX_set_tmp_{rsa,dh}_callback(). - [Ben Laurie] - - *) Make DH_free() tolerate being passed a NULL pointer (like RSA_free() and - DSA_free()). Make X509_PUBKEY_set() check for errors in d2i_PublicKey(). - [Steve Henson] - - *) X509_name_add_entry() freed the wrong thing after an error. - [Arne Ansper ] - - *) rsa_eay.c would attempt to free a NULL context. - [Arne Ansper ] - - *) BIO_s_socket() had a broken should_retry() on Windoze. - [Arne Ansper ] - - *) BIO_f_buffer() didn't pass on BIO_CTRL_FLUSH. - [Arne Ansper ] - - *) Make sure the already existing X509_STORE->depth variable is initialized - in X509_STORE_new(), but document the fact that this variable is still - unused in the certificate verification process. - [Ralf S. Engelschall] - - *) Fix the various library and apps files to free up pkeys obtained from - X509_PUBKEY_get() et al. Also allow x509.c to handle netscape extensions. - [Steve Henson] - - *) Fix reference counting in X509_PUBKEY_get(). This makes - demos/maurice/example2.c work, amongst others, probably. - [Steve Henson and Ben Laurie] - - *) First cut of a cleanup for apps/. First the `ssleay' program is now named - `openssl' and second, the shortcut symlinks for the `openssl ' - are no longer created. This way we have a single and consistent command - line interface `openssl ', similar to `cvs '. - [Ralf S. Engelschall, Paul Sutton and Ben Laurie] - - *) ca.c: move test for DSA keys inside #ifndef NO_DSA. Make pubkey - BIT STRING wrapper always have zero unused bits. - [Steve Henson] - - *) Add CA.pl, perl version of CA.sh, add extended key usage OID. - [Steve Henson] - - *) Make the top-level INSTALL documentation easier to understand. - [Paul Sutton] - - *) Makefiles updated to exit if an error occurs in a sub-directory - make (including if user presses ^C) [Paul Sutton] - - *) Make Montgomery context stuff explicit in RSA data structure. - [Ben Laurie] - - *) Fix build order of pem and err to allow for generated pem.h. - [Ben Laurie] - - *) Fix renumbering bug in X509_NAME_delete_entry(). - [Ben Laurie] - - *) Enhanced the err-ins.pl script so it makes the error library number - global and can add a library name. This is needed for external ASN1 and - other error libraries. - [Steve Henson] - - *) Fixed sk_insert which never worked properly. - [Steve Henson] - - *) Fix ASN1 macros so they can handle indefinite length constructed - EXPLICIT tags. Some non standard certificates use these: they can now - be read in. - [Steve Henson] - - *) Merged the various old/obsolete SSLeay documentation files (doc/xxx.doc) - into a single doc/ssleay.txt bundle. This way the information is still - preserved but no longer messes up this directory. Now it's new room for - the new set of documentation files. - [Ralf S. Engelschall] - - *) SETs were incorrectly DER encoded. This was a major pain, because they - shared code with SEQUENCEs, which aren't coded the same. This means that - almost everything to do with SETs or SEQUENCEs has either changed name or - number of arguments. - [Ben Laurie, based on a partial fix by GP Jayan ] - - *) Fix test data to work with the above. - [Ben Laurie] - - *) Fix the RSA header declarations that hid a bug I fixed in 0.9.0b but - was already fixed by Eric for 0.9.1 it seems. - [Ben Laurie - pointed out by Ulf Möller ] - - *) Autodetect FreeBSD3. - [Ben Laurie] - - *) Fix various bugs in Configure. This affects the following platforms: - nextstep - ncr-scde - unixware-2.0 - unixware-2.0-pentium - sco5-cc. - [Ben Laurie] - - *) Eliminate generated files from CVS. Reorder tests to regenerate files - before they are needed. - [Ben Laurie] - - *) Generate Makefile.ssl from Makefile.org (to keep CVS happy). - [Ben Laurie] - - - Changes between 0.9.1b and 0.9.1c [23-Dec-1998] - - *) Added OPENSSL_VERSION_NUMBER to crypto/crypto.h and - changed SSLeay to OpenSSL in version strings. - [Ralf S. Engelschall] - - *) Some fixups to the top-level documents. - [Paul Sutton] - - *) Fixed the nasty bug where rsaref.h was not found under compile-time - because the symlink to include/ was missing. - [Ralf S. Engelschall] - - *) Incorporated the popular no-RSA/DSA-only patches - which allow to compile a RSA-free SSLeay. - [Andrew Cooke / Interrader Ldt., Ralf S. Engelschall] - - *) Fixed nasty rehash problem under `make -f Makefile.ssl links' - when "ssleay" is still not found. - [Ralf S. Engelschall] - - *) Added more platforms to Configure: Cray T3E, HPUX 11, - [Ralf S. Engelschall, Beckmann ] - - *) Updated the README file. - [Ralf S. Engelschall] - - *) Added various .cvsignore files in the CVS repository subdirs - to make a "cvs update" really silent. - [Ralf S. Engelschall] - - *) Recompiled the error-definition header files and added - missing symbols to the Win32 linker tables. - [Ralf S. Engelschall] - - *) Cleaned up the top-level documents; - o new files: CHANGES and LICENSE - o merged VERSION, HISTORY* and README* files a CHANGES.SSLeay - o merged COPYRIGHT into LICENSE - o removed obsolete TODO file - o renamed MICROSOFT to INSTALL.W32 - [Ralf S. Engelschall] - - *) Removed dummy files from the 0.9.1b source tree: - crypto/asn1/x crypto/bio/cd crypto/bio/fg crypto/bio/grep crypto/bio/vi - crypto/bn/asm/......add.c crypto/bn/asm/a.out crypto/dsa/f crypto/md5/f - crypto/pem/gmon.out crypto/perlasm/f crypto/pkcs7/build crypto/rsa/f - crypto/sha/asm/f crypto/threads/f ms/zzz ssl/f ssl/f.mak test/f - util/f.mak util/pl/f util/pl/f.mak crypto/bf/bf_locl.old apps/f - [Ralf S. Engelschall] - - *) Added various platform portability fixes. - [Mark J. Cox] - - *) The Genesis of the OpenSSL rpject: - We start with the latest (unreleased) SSLeay version 0.9.1b which Eric A. - Young and Tim J. Hudson created while they were working for C2Net until - summer 1998. - [The OpenSSL Project] - - - Changes between 0.9.0b and 0.9.1b [not released] - - *) Updated a few CA certificates under certs/ - [Eric A. Young] - - *) Changed some BIGNUM api stuff. - [Eric A. Young] - - *) Various platform ports: OpenBSD, Ultrix, IRIX 64bit, NetBSD, - DGUX x86, Linux Alpha, etc. - [Eric A. Young] - - *) New COMP library [crypto/comp/] for SSL Record Layer Compression: - RLE (dummy implemented) and ZLIB (really implemented when ZLIB is - available). - [Eric A. Young] - - *) Add -strparse option to asn1pars program which parses nested - binary structures - [Dr Stephen Henson ] - - *) Added "oid_file" to ssleay.cnf for "ca" and "req" programs. - [Eric A. Young] - - *) DSA fix for "ca" program. - [Eric A. Young] - - *) Added "-genkey" option to "dsaparam" program. - [Eric A. Young] - - *) Added RIPE MD160 (rmd160) message digest. - [Eric A. Young] - - *) Added -a (all) option to "ssleay version" command. - [Eric A. Young] - - *) Added PLATFORM define which is the id given to Configure. - [Eric A. Young] - - *) Added MemCheck_XXXX functions to crypto/mem.c for memory checking. - [Eric A. Young] - - *) Extended the ASN.1 parser routines. - [Eric A. Young] - - *) Extended BIO routines to support REUSEADDR, seek, tell, etc. - [Eric A. Young] - - *) Added a BN_CTX to the BN library. - [Eric A. Young] - - *) Fixed the weak key values in DES library - [Eric A. Young] - - *) Changed API in EVP library for cipher aliases. - [Eric A. Young] - - *) Added support for RC2/64bit cipher. - [Eric A. Young] - - *) Converted the lhash library to the crypto/mem.c functions. - [Eric A. Young] - - *) Added more recognized ASN.1 object ids. - [Eric A. Young] - - *) Added more RSA padding checks for SSL/TLS. - [Eric A. Young] - - *) Added BIO proxy/filter functionality. - [Eric A. Young] - - *) Added extra_certs to SSL_CTX which can be used - send extra CA certificates to the client in the CA cert chain sending - process. It can be configured with SSL_CTX_add_extra_chain_cert(). - [Eric A. Young] - - *) Now Fortezza is denied in the authentication phase because - this is key exchange mechanism is not supported by SSLeay at all. - [Eric A. Young] - - *) Additional PKCS1 checks. - [Eric A. Young] - - *) Support the string "TLSv1" for all TLS v1 ciphers. - [Eric A. Young] - - *) Added function SSL_get_ex_data_X509_STORE_CTX_idx() which gives the - ex_data index of the SSL context in the X509_STORE_CTX ex_data. - [Eric A. Young] - - *) Fixed a few memory leaks. - [Eric A. Young] - - *) Fixed various code and comment typos. - [Eric A. Young] - - *) A minor bug in ssl/s3_clnt.c where there would always be 4 0 - bytes sent in the client random. - [Edward Bishop ] diff --git a/crypto/openssl/CHANGES.md b/crypto/openssl/CHANGES.md new file mode 100644 index 000000000000..7cdd9d974536 --- /dev/null +++ b/crypto/openssl/CHANGES.md @@ -0,0 +1,19753 @@ +OpenSSL CHANGES +=============== + +This is a high-level summary of the most important changes. +For a full list of changes, see the [git commit log][log] and +pick the appropriate release branch. + + [log]: https://github.com/openssl/openssl/commits/ + +OpenSSL Releases +---------------- + + - [OpenSSL 3.0](#openssl-30) + - [OpenSSL 1.1.1](#openssl-111) + - [OpenSSL 1.1.0](#openssl-110) + - [OpenSSL 1.0.2](#openssl-102) + - [OpenSSL 1.0.1](#openssl-101) + - [OpenSSL 1.0.0](#openssl-100) + - [OpenSSL 0.9.x](#openssl-09x) + +OpenSSL 3.0 +----------- + +For OpenSSL 3.0 a [Migration guide][] has been added, so the CHANGES entries +listed here are only a brief description. +The migration guide contains more detailed information related to new features, +breaking changes, and mappings for the large list of deprecated functions. + +[Migration guide]: https://github.com/openssl/openssl/tree/master/doc/man7/migration_guide.pod + +### Changes between 3.0.7 and 3.0.8 [7 Feb 2023] + + * Fixed NULL dereference during PKCS7 data verification. + + A NULL pointer can be dereferenced when signatures are being + verified on PKCS7 signed or signedAndEnveloped data. In case the hash + algorithm used for the signature is known to the OpenSSL library but + the implementation of the hash algorithm is not available the digest + initialization will fail. There is a missing check for the return + value from the initialization function which later leads to invalid + usage of the digest API most likely leading to a crash. + ([CVE-2023-0401]) + + PKCS7 data is processed by the SMIME library calls and also by the + time stamp (TS) library calls. The TLS implementation in OpenSSL does + not call these functions however third party applications would be + affected if they call these functions to verify signatures on untrusted + data. + + *Tomáš Mráz* + + * Fixed X.400 address type confusion in X.509 GeneralName. + + There is a type confusion vulnerability relating to X.400 address processing + inside an X.509 GeneralName. X.400 addresses were parsed as an ASN1_STRING + but the public structure definition for GENERAL_NAME incorrectly specified + the type of the x400Address field as ASN1_TYPE. This field is subsequently + interpreted by the OpenSSL function GENERAL_NAME_cmp as an ASN1_TYPE rather + than an ASN1_STRING. + + When CRL checking is enabled (i.e. the application sets the + X509_V_FLAG_CRL_CHECK flag), this vulnerability may allow an attacker to + pass arbitrary pointers to a memcmp call, enabling them to read memory + contents or enact a denial of service. + ([CVE-2023-0286]) + + *Hugo Landau* + + * Fixed NULL dereference validating DSA public key. + + An invalid pointer dereference on read can be triggered when an + application tries to check a malformed DSA public key by the + EVP_PKEY_public_check() function. This will most likely lead + to an application crash. This function can be called on public + keys supplied from untrusted sources which could allow an attacker + to cause a denial of service attack. + + The TLS implementation in OpenSSL does not call this function + but applications might call the function if there are additional + security requirements imposed by standards such as FIPS 140-3. + ([CVE-2023-0217]) + + *Shane Lontis, Tomáš Mráz* + + * Fixed Invalid pointer dereference in d2i_PKCS7 functions. + + An invalid pointer dereference on read can be triggered when an + application tries to load malformed PKCS7 data with the + d2i_PKCS7(), d2i_PKCS7_bio() or d2i_PKCS7_fp() functions. + + The result of the dereference is an application crash which could + lead to a denial of service attack. The TLS implementation in OpenSSL + does not call this function however third party applications might + call these functions on untrusted data. + ([CVE-2023-0216]) + + *Tomáš Mráz* + + * Fixed Use-after-free following BIO_new_NDEF. + + The public API function BIO_new_NDEF is a helper function used for + streaming ASN.1 data via a BIO. It is primarily used internally to OpenSSL + to support the SMIME, CMS and PKCS7 streaming capabilities, but may also + be called directly by end user applications. + + The function receives a BIO from the caller, prepends a new BIO_f_asn1 + filter BIO onto the front of it to form a BIO chain, and then returns + the new head of the BIO chain to the caller. Under certain conditions, + for example if a CMS recipient public key is invalid, the new filter BIO + is freed and the function returns a NULL result indicating a failure. + However, in this case, the BIO chain is not properly cleaned up and the + BIO passed by the caller still retains internal pointers to the previously + freed filter BIO. If the caller then goes on to call BIO_pop() on the BIO + then a use-after-free will occur. This will most likely result in a crash. + ([CVE-2023-0215]) + + *Viktor Dukhovni, Matt Caswell* + + * Fixed Double free after calling PEM_read_bio_ex. + + The function PEM_read_bio_ex() reads a PEM file from a BIO and parses and + decodes the "name" (e.g. "CERTIFICATE"), any header data and the payload + data. If the function succeeds then the "name_out", "header" and "data" + arguments are populated with pointers to buffers containing the relevant + decoded data. The caller is responsible for freeing those buffers. It is + possible to construct a PEM file that results in 0 bytes of payload data. + In this case PEM_read_bio_ex() will return a failure code but will populate + the header argument with a pointer to a buffer that has already been freed. + If the caller also frees this buffer then a double free will occur. This + will most likely lead to a crash. + + The functions PEM_read_bio() and PEM_read() are simple wrappers around + PEM_read_bio_ex() and therefore these functions are also directly affected. + + These functions are also called indirectly by a number of other OpenSSL + functions including PEM_X509_INFO_read_bio_ex() and + SSL_CTX_use_serverinfo_file() which are also vulnerable. Some OpenSSL + internal uses of these functions are not vulnerable because the caller does + not free the header argument if PEM_read_bio_ex() returns a failure code. + ([CVE-2022-4450]) + + *Kurt Roeckx, Matt Caswell* + + * Fixed Timing Oracle in RSA Decryption. + + A timing based side channel exists in the OpenSSL RSA Decryption + implementation which could be sufficient to recover a plaintext across + a network in a Bleichenbacher style attack. To achieve a successful + decryption an attacker would have to be able to send a very large number + of trial messages for decryption. The vulnerability affects all RSA padding + modes: PKCS#1 v1.5, RSA-OEAP and RSASVE. + ([CVE-2022-4304]) + + *Dmitry Belyavsky, Hubert Kario* + + * Fixed X.509 Name Constraints Read Buffer Overflow. + + A read buffer overrun can be triggered in X.509 certificate verification, + specifically in name constraint checking. The read buffer overrun might + result in a crash which could lead to a denial of service attack. + In a TLS client, this can be triggered by connecting to a malicious + server. In a TLS server, this can be triggered if the server requests + client authentication and a malicious client connects. + ([CVE-2022-4203]) + + *Viktor Dukhovni* + + * Fixed X.509 Policy Constraints Double Locking security issue. + + If an X.509 certificate contains a malformed policy constraint and + policy processing is enabled, then a write lock will be taken twice + recursively. On some operating systems (most widely: Windows) this + results in a denial of service when the affected process hangs. Policy + processing being enabled on a publicly facing server is not considered + to be a common setup. + ([CVE-2022-3996]) + + *Paul Dale* + + * Our provider implementations of `OSSL_FUNC_KEYMGMT_EXPORT` and + `OSSL_FUNC_KEYMGMT_GET_PARAMS` for EC and SM2 keys now honor + `OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT` as set (and + default to `POINT_CONVERSION_UNCOMPRESSED`) when exporting + `OSSL_PKEY_PARAM_PUB_KEY`, instead of unconditionally using + `POINT_CONVERSION_COMPRESSED` as in previous 3.x releases. + For symmetry, our implementation of `EVP_PKEY_ASN1_METHOD->export_to` + for legacy EC and SM2 keys is also changed similarly to honor the + equivalent conversion format flag as specified in the underlying + `EC_KEY` object being exported to a provider, when this function is + called through `EVP_PKEY_export()`. + + *Nicola Tuveri* + +### Changes between 3.0.6 and 3.0.7 [1 Nov 2022] + + * Fixed two buffer overflows in punycode decoding functions. + + A buffer overrun can be triggered in X.509 certificate verification, + specifically in name constraint checking. Note that this occurs after + certificate chain signature verification and requires either a CA to + have signed the malicious certificate or for the application to continue + certificate verification despite failure to construct a path to a trusted + issuer. + + In a TLS client, this can be triggered by connecting to a malicious + server. In a TLS server, this can be triggered if the server requests + client authentication and a malicious client connects. + + An attacker can craft a malicious email address to overflow + an arbitrary number of bytes containing the `.` character (decimal 46) + on the stack. This buffer overflow could result in a crash (causing a + denial of service). + ([CVE-2022-3786]) + + An attacker can craft a malicious email address to overflow four + attacker-controlled bytes on the stack. This buffer overflow could + result in a crash (causing a denial of service) or potentially remote code + execution depending on stack layout for any given platform/compiler. + ([CVE-2022-3602]) + + *Paul Dale* + + * Removed all references to invalid OSSL_PKEY_PARAM_RSA names for CRT + parameters in OpenSSL code. + Applications should not use the names OSSL_PKEY_PARAM_RSA_FACTOR, + OSSL_PKEY_PARAM_RSA_EXPONENT and OSSL_PKEY_PARAM_RSA_COEFFICIENT. + Use the numbered names such as OSSL_PKEY_PARAM_RSA_FACTOR1 instead. + Using these invalid names may cause algorithms to use slower methods + that ignore the CRT parameters. + + *Shane Lontis* + + * Fixed a regression introduced in 3.0.6 version raising errors on some stack + operations. + + *Tomáš Mráz* + + * Fixed a regression introduced in 3.0.6 version not refreshing the certificate + data to be signed before signing the certificate. + + *Gibeom Gwon* + + * Added RIPEMD160 to the default provider. + + *Paul Dale* + + * Ensured that the key share group sent or accepted for the key exchange + is allowed for the protocol version. + + *Matt Caswell* + +### Changes between 3.0.5 and 3.0.6 [11 Oct 2022] + + * OpenSSL supports creating a custom cipher via the legacy + EVP_CIPHER_meth_new() function and associated function calls. This function + was deprecated in OpenSSL 3.0 and application authors are instead encouraged + to use the new provider mechanism in order to implement custom ciphers. + + OpenSSL versions 3.0.0 to 3.0.5 incorrectly handle legacy custom ciphers + passed to the EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() and + EVP_CipherInit_ex2() functions (as well as other similarly named encryption + and decryption initialisation functions). Instead of using the custom cipher + directly it incorrectly tries to fetch an equivalent cipher from the + available providers. An equivalent cipher is found based on the NID passed to + EVP_CIPHER_meth_new(). This NID is supposed to represent the unique NID for a + given cipher. However it is possible for an application to incorrectly pass + NID_undef as this value in the call to EVP_CIPHER_meth_new(). When NID_undef + is used in this way the OpenSSL encryption/decryption initialisation function + will match the NULL cipher as being equivalent and will fetch this from the + available providers. This will succeed if the default provider has been + loaded (or if a third party provider has been loaded that offers this + cipher). Using the NULL cipher means that the plaintext is emitted as the + ciphertext. + + Applications are only affected by this issue if they call + EVP_CIPHER_meth_new() using NID_undef and subsequently use it in a call to an + encryption/decryption initialisation function. Applications that only use + SSL/TLS are not impacted by this issue. + ([CVE-2022-3358]) + + *Matt Caswell* + + * Fix LLVM vs Apple LLVM version numbering confusion that caused build failures + on MacOS 10.11 + + *Richard Levitte* + + * Fixed the linux-mips64 Configure target which was missing the + SIXTY_FOUR_BIT bn_ops flag. This was causing heap corruption on that + platform. + + *Adam Joseph* + + * Fix handling of a ticket key callback that returns 0 in TLSv1.3 to not send a + ticket + + *Matt Caswell* + + * Correctly handle a retransmitted ClientHello in DTLS + + *Matt Caswell* + + * Fixed detection of ktls support in cross-compile environment on Linux + + *Tomas Mraz* + + * Fixed some regressions and test failures when running the 3.0.0 FIPS provider + against 3.0.x + + *Paul Dale* + + * Fixed SSL_pending() and SSL_has_pending() with DTLS which were failing to + report correct results in some cases + + *Matt Caswell* + + * Fix UWP builds by defining VirtualLock + + *Charles Milette* + + * For known safe primes use the minimum key length according to RFC 7919. + Longer private key sizes unnecessarily raise the cycles needed to compute the + shared secret without any increase of the real security. This fixes a + regression from 1.1.1 where these shorter keys were generated for the known + safe primes. + + *Tomas Mraz* + + * Added the loongarch64 target + + *Shi Pujin* + + * Fixed EC ASM flag passing. Flags for ASM implementations of EC curves were + only passed to the FIPS provider and not to the default or legacy provider. + + *Juergen Christ* + + * Fixed reported performance degradation on aarch64. Restored the + implementation prior to commit 2621751 ("aes/asm/aesv8-armx.pl: avoid + 32-bit lane assignment in CTR mode") for 64bit targets only, since it is + reportedly 2-17% slower and the silicon errata only affects 32bit targets. + The new algorithm is still used for 32 bit targets. + + *Bernd Edlinger* + + * Added a missing header for memcmp that caused compilation failure on some + platforms + + *Gregor Jasny* + +### Changes between 3.0.4 and 3.0.5 [5 Jul 2022] + + * The OpenSSL 3.0.4 release introduced a serious bug in the RSA + implementation for X86_64 CPUs supporting the AVX512IFMA instructions. + This issue makes the RSA implementation with 2048 bit private keys + incorrect on such machines and memory corruption will happen during + the computation. As a consequence of the memory corruption an attacker + may be able to trigger a remote code execution on the machine performing + the computation. + + SSL/TLS servers or other servers using 2048 bit RSA private keys running + on machines supporting AVX512IFMA instructions of the X86_64 architecture + are affected by this issue. + ([CVE-2022-2274]) + + *Xi Ruoyao* + + * AES OCB mode for 32-bit x86 platforms using the AES-NI assembly optimised + implementation would not encrypt the entirety of the data under some + circumstances. This could reveal sixteen bytes of data that was + preexisting in the memory that wasn't written. In the special case of + "in place" encryption, sixteen bytes of the plaintext would be revealed. + + Since OpenSSL does not support OCB based cipher suites for TLS and DTLS, + they are both unaffected. + ([CVE-2022-2097]) + + *Alex Chernyakhovsky, David Benjamin, Alejandro Sedeño* + +### Changes between 3.0.3 and 3.0.4 [21 Jun 2022] + + * In addition to the c_rehash shell command injection identified in + CVE-2022-1292, further bugs where the c_rehash script does not + properly sanitise shell metacharacters to prevent command injection have been + fixed. + + When the CVE-2022-1292 was fixed it was not discovered that there + are other places in the script where the file names of certificates + being hashed were possibly passed to a command executed through the shell. + + This script is distributed by some operating systems in a manner where + it is automatically executed. On such operating systems, an attacker + could execute arbitrary commands with the privileges of the script. + + Use of the c_rehash script is considered obsolete and should be replaced + by the OpenSSL rehash command line tool. + (CVE-2022-2068) + + *Daniel Fiala, Tomáš Mráz* + + * Case insensitive string comparison no longer uses locales. It has instead + been directly implemented. + + *Paul Dale* + +### Changes between 3.0.2 and 3.0.3 [3 May 2022] + + * Case insensitive string comparison is reimplemented via new locale-agnostic + comparison functions OPENSSL_str[n]casecmp always using the POSIX locale for + comparison. The previous implementation had problems when the Turkish locale + was used. + + *Dmitry Belyavskiy* + + * Fixed a bug in the c_rehash script which was not properly sanitising shell + metacharacters to prevent command injection. This script is distributed by + some operating systems in a manner where it is automatically executed. On + such operating systems, an attacker could execute arbitrary commands with the + privileges of the script. + + Use of the c_rehash script is considered obsolete and should be replaced + by the OpenSSL rehash command line tool. + (CVE-2022-1292) + + *Tomáš Mráz* + + * Fixed a bug in the function `OCSP_basic_verify` that verifies the signer + certificate on an OCSP response. The bug caused the function in the case + where the (non-default) flag OCSP_NOCHECKS is used to return a postivie + response (meaning a successful verification) even in the case where the + response signing certificate fails to verify. + + It is anticipated that most users of `OCSP_basic_verify` will not use the + OCSP_NOCHECKS flag. In this case the `OCSP_basic_verify` function will return + a negative value (indicating a fatal error) in the case of a certificate + verification failure. The normal expected return value in this case would be + 0. + + This issue also impacts the command line OpenSSL "ocsp" application. When + verifying an ocsp response with the "-no_cert_checks" option the command line + application will report that the verification is successful even though it + has in fact failed. In this case the incorrect successful response will also + be accompanied by error messages showing the failure and contradicting the + apparently successful result. + ([CVE-2022-1343]) + + *Matt Caswell* + + * Fixed a bug where the RC4-MD5 ciphersuite incorrectly used the + AAD data as the MAC key. This made the MAC key trivially predictable. + + An attacker could exploit this issue by performing a man-in-the-middle attack + to modify data being sent from one endpoint to an OpenSSL 3.0 recipient such + that the modified data would still pass the MAC integrity check. + + Note that data sent from an OpenSSL 3.0 endpoint to a non-OpenSSL 3.0 + endpoint will always be rejected by the recipient and the connection will + fail at that point. Many application protocols require data to be sent from + the client to the server first. Therefore, in such a case, only an OpenSSL + 3.0 server would be impacted when talking to a non-OpenSSL 3.0 client. + + If both endpoints are OpenSSL 3.0 then the attacker could modify data being + sent in both directions. In this case both clients and servers could be + affected, regardless of the application protocol. + + Note that in the absence of an attacker this bug means that an OpenSSL 3.0 + endpoint communicating with a non-OpenSSL 3.0 endpoint will fail to complete + the handshake when using this ciphersuite. + + The confidentiality of data is not impacted by this issue, i.e. an attacker + cannot decrypt data that has been encrypted using this ciphersuite - they can + only modify it. + + In order for this attack to work both endpoints must legitimately negotiate + the RC4-MD5 ciphersuite. This ciphersuite is not compiled by default in + OpenSSL 3.0, and is not available within the default provider or the default + ciphersuite list. This ciphersuite will never be used if TLSv1.3 has been + negotiated. In order for an OpenSSL 3.0 endpoint to use this ciphersuite the + following must have occurred: + + 1) OpenSSL must have been compiled with the (non-default) compile time option + enable-weak-ssl-ciphers + + 2) OpenSSL must have had the legacy provider explicitly loaded (either + through application code or via configuration) + + 3) The ciphersuite must have been explicitly added to the ciphersuite list + + 4) The libssl security level must have been set to 0 (default is 1) + + 5) A version of SSL/TLS below TLSv1.3 must have been negotiated + + 6) Both endpoints must negotiate the RC4-MD5 ciphersuite in preference to any + others that both endpoints have in common + (CVE-2022-1434) + + *Matt Caswell* + + * Fix a bug in the OPENSSL_LH_flush() function that breaks reuse of the memory + occuppied by the removed hash table entries. + + This function is used when decoding certificates or keys. If a long lived + process periodically decodes certificates or keys its memory usage will + expand without bounds and the process might be terminated by the operating + system causing a denial of service. Also traversing the empty hash table + entries will take increasingly more time. + + Typically such long lived processes might be TLS clients or TLS servers + configured to accept client certificate authentication. + (CVE-2022-1473) + + *Hugo Landau, Aliaksei Levin* + + * The functions `OPENSSL_LH_stats` and `OPENSSL_LH_stats_bio` now only report + the `num_items`, `num_nodes` and `num_alloc_nodes` statistics. All other + statistics are no longer supported. For compatibility, these statistics are + still listed in the output but are now always reported as zero. + + *Hugo Landau* + +### Changes between 3.0.1 and 3.0.2 [15 Mar 2022] + + * Fixed a bug in the BN_mod_sqrt() function that can cause it to loop forever + for non-prime moduli. + + Internally this function is used when parsing certificates that contain + elliptic curve public keys in compressed form or explicit elliptic curve + parameters with a base point encoded in compressed form. + + It is possible to trigger the infinite loop by crafting a certificate that + has invalid explicit curve parameters. + + Since certificate parsing happens prior to verification of the certificate + signature, any process that parses an externally supplied certificate may thus + be subject to a denial of service attack. The infinite loop can also be + reached when parsing crafted private keys as they can contain explicit + elliptic curve parameters. + + Thus vulnerable situations include: + + - TLS clients consuming server certificates + - TLS servers consuming client certificates + - Hosting providers taking certificates or private keys from customers + - Certificate authorities parsing certification requests from subscribers + - Anything else which parses ASN.1 elliptic curve parameters + + Also any other applications that use the BN_mod_sqrt() where the attacker + can control the parameter values are vulnerable to this DoS issue. + ([CVE-2022-0778]) + + *Tomáš Mráz* + + * Add ciphersuites based on DHE_PSK (RFC 4279) and ECDHE_PSK (RFC 5489) + to the list of ciphersuites providing Perfect Forward Secrecy as + required by SECLEVEL >= 3. + + *Dmitry Belyavskiy, Nicola Tuveri* + + * Made the AES constant time code for no-asm configurations + optional due to the resulting 95% performance degradation. + The AES constant time code can be enabled, for no assembly + builds, with: ./config no-asm -DOPENSSL_AES_CONST_TIME + + *Paul Dale* + + * Fixed PEM_write_bio_PKCS8PrivateKey() to make it possible to use empty + passphrase strings. + + *Darshan Sen* + + * The negative return value handling of the certificate verification callback + was reverted. The replacement is to set the verification retry state with + the SSL_set_retry_verify() function. + + *Tomáš Mráz* + +### Changes between 3.0.0 and 3.0.1 [14 Dec 2021] + + * Fixed invalid handling of X509_verify_cert() internal errors in libssl + Internally libssl in OpenSSL calls X509_verify_cert() on the client side to + verify a certificate supplied by a server. That function may return a + negative return value to indicate an internal error (for example out of + memory). Such a negative return value is mishandled by OpenSSL and will cause + an IO function (such as SSL_connect() or SSL_do_handshake()) to not indicate + success and a subsequent call to SSL_get_error() to return the value + SSL_ERROR_WANT_RETRY_VERIFY. This return value is only supposed to be + returned by OpenSSL if the application has previously called + SSL_CTX_set_cert_verify_callback(). Since most applications do not do this + the SSL_ERROR_WANT_RETRY_VERIFY return value from SSL_get_error() will be + totally unexpected and applications may not behave correctly as a result. The + exact behaviour will depend on the application but it could result in + crashes, infinite loops or other similar incorrect responses. + + This issue is made more serious in combination with a separate bug in OpenSSL + 3.0 that will cause X509_verify_cert() to indicate an internal error when + processing a certificate chain. This will occur where a certificate does not + include the Subject Alternative Name extension but where a Certificate + Authority has enforced name constraints. This issue can occur even with valid + chains. + ([CVE-2021-4044]) + + *Matt Caswell* + + * Corrected a few file name and file reference bugs in the build, + installation and setup scripts, which lead to installation verification + failures. Slightly enhanced the installation verification script. + + *Richard Levitte* + + * Fixed EVP_PKEY_eq() to make it possible to use it with strictly private + keys. + + *Richard Levitte* + + * Fixed PVK encoder to properly query for the passphrase. + + *Tomáš Mráz* + + * Multiple fixes in the OSSL_HTTP API functions. + + *David von Oheimb* + + * Allow sign extension in OSSL_PARAM_allocate_from_text() for the + OSSL_PARAM_INTEGER data type and return error on negative numbers + used with the OSSL_PARAM_UNSIGNED_INTEGER data type. Make + OSSL_PARAM_BLD_push_BN{,_pad}() return an error on negative numbers. + + *Richard Levitte* + + * Allow copying uninitialized digest contexts with EVP_MD_CTX_copy_ex. + + *Tomáš Mráz* + + * Fixed detection of ARMv7 and ARM64 CPU features on FreeBSD. + + *Allan Jude* + + * Multiple threading fixes. + + *Matt Caswell* + + * Added NULL digest implementation to keep compatibility with 1.1.1 version. + + *Tomáš Mráz* + + * Allow fetching an operation from the provider that owns an unexportable key + as a fallback if that is still allowed by the property query. + + *Richard Levitte* + +### Changes between 1.1.1 and 3.0.0 [7 sep 2021] + + * TLS_MAX_VERSION, DTLS_MAX_VERSION and DTLS_MIN_VERSION constants are now + deprecated. + + *Matt Caswell* + + * The `OPENSSL_s390xcap` environment variable can be used to set bits in the + S390X capability vector to zero. This simplifies testing of different code + paths on S390X architecture. + + *Patrick Steuer* + + * Encrypting more than 2^64 TLS records with AES-GCM is disallowed + as per FIPS 140-2 IG A.5 "Key/IV Pair Uniqueness Requirements from + SP 800-38D". The communication will fail at this point. + + *Paul Dale* + + * The EC_GROUP_clear_free() function is deprecated as there is nothing + confidential in EC_GROUP data. + + *Nicola Tuveri* + + * The byte order mark (BOM) character is ignored if encountered at the + beginning of a PEM-formatted file. + + *Dmitry Belyavskiy* + + * Added CMS support for the Russian GOST algorithms. + + *Dmitry Belyavskiy* + + * Due to move of the implementation of cryptographic operations + to the providers, validation of various operation parameters can + be postponed until the actual operation is executed where previously + it happened immediately when an operation parameter was set. + + For example when setting an unsupported curve with + EVP_PKEY_CTX_set_ec_paramgen_curve_nid() this function call will not + fail but later keygen operations with the EVP_PKEY_CTX will fail. + + *OpenSSL team members and many third party contributors* + + * The EVP_get_cipherbyname() function will return NULL for algorithms such as + "AES-128-SIV", "AES-128-CBC-CTS" and "CAMELLIA-128-CBC-CTS" which were + previously only accessible via low level interfaces. Use EVP_CIPHER_fetch() + instead to retrieve these algorithms from a provider. + + *Shane Lontis* + + * On build targets where the multilib postfix is set in the build + configuration the libdir directory was changing based on whether + the lib directory with the multilib postfix exists on the system + or not. This unpredictable behavior was removed and eventual + multilib postfix is now always added to the default libdir. Use + `--libdir=lib` to override the libdir if adding the postfix is + undesirable. + + *Jan Lána* + + * The triple DES key wrap functionality now conforms to RFC 3217 but is + no longer interoperable with OpenSSL 1.1.1. + + *Paul Dale* + + * The ERR_GET_FUNC() function was removed. With the loss of meaningful + function codes, this function can only cause problems for calling + applications. + + *Paul Dale* + + * Add a configurable flag to output date formats as ISO 8601. Does not + change the default date format. + + *William Edmisten* + + * Version of MSVC earlier than 1300 could get link warnings, which could + be suppressed if the undocumented -DI_CAN_LIVE_WITH_LNK4049 was set. + Support for this flag has been removed. + + *Rich Salz* + + * Rework and make DEBUG macros consistent. Remove unused -DCONF_DEBUG, + -DBN_CTX_DEBUG, and REF_PRINT. Add a new tracing category and use it for + printing reference counts. Rename -DDEBUG_UNUSED to -DUNUSED_RESULT_DEBUG + Fix BN_DEBUG_RAND so it compiles and, when set, force DEBUG_RAND to be set + also. Rename engine_debug_ref to be ENGINE_REF_PRINT also for consistency. + + *Rich Salz* + + * The signatures of the functions to get and set options on SSL and + SSL_CTX objects changed from "unsigned long" to "uint64_t" type. + Some source code changes may be required. + + *Rich Salz* + + * The public definitions of conf_method_st and conf_st have been + deprecated. They will be made opaque in a future release. + + *Rich Salz and Tomáš Mráz* + + * Client-initiated renegotiation is disabled by default. To allow it, use + the -client_renegotiation option, the SSL_OP_ALLOW_CLIENT_RENEGOTIATION + flag, or the "ClientRenegotiation" config parameter as appropriate. + + *Rich Salz* + + * Add "abspath" and "includedir" pragma's to config files, to prevent, + or modify relative pathname inclusion. + + *Rich Salz* + + * OpenSSL includes a cryptographic module that is intended to be FIPS 140-2 + validated. Please consult the README-FIPS and + README-PROVIDERS files, as well as the migration guide. + + *OpenSSL team members and many third party contributors* + + * For the key types DH and DHX the allowed settable parameters are now different. + + *Shane Lontis* + + * The openssl commands that read keys, certificates, and CRLs now + automatically detect the PEM or DER format of the input files. + + *David von Oheimb, Richard Levitte, and Tomáš Mráz* + + * Added enhanced PKCS#12 APIs which accept a library context. + + *Jon Spillett* + + * The default manual page suffix ($MANSUFFIX) has been changed to "ossl" + + *Matt Caswell* + + * Added support for Kernel TLS (KTLS). + + *Boris Pismenny, John Baldwin and Andrew Gallatin* + + * Support for RFC 5746 secure renegotiation is now required by default for + SSL or TLS connections to succeed. + + *Benjamin Kaduk* + + * The signature of the `copy` functional parameter of the + EVP_PKEY_meth_set_copy() function has changed so its `src` argument is + now `const EVP_PKEY_CTX *` instead of `EVP_PKEY_CTX *`. Similarly + the signature of the `pub_decode` functional parameter of the + EVP_PKEY_asn1_set_public() function has changed so its `pub` argument is + now `const X509_PUBKEY *` instead of `X509_PUBKEY *`. + + *David von Oheimb* + + * The error return values from some control calls (ctrl) have changed. + + *Paul Dale* + + * A public key check is now performed during EVP_PKEY_derive_set_peer(). + + *Shane Lontis* + + * Many functions in the EVP_ namespace that are getters of values from + implementations or contexts were renamed to include get or get0 in their + names. Old names are provided as macro aliases for compatibility and + are not deprecated. + + *Tomáš Mráz* + + * The EVP_PKEY_CTRL_PKCS7_ENCRYPT, EVP_PKEY_CTRL_PKCS7_DECRYPT, + EVP_PKEY_CTRL_PKCS7_SIGN, EVP_PKEY_CTRL_CMS_ENCRYPT, + EVP_PKEY_CTRL_CMS_DECRYPT, and EVP_PKEY_CTRL_CMS_SIGN control operations + are deprecated. + + *Tomáš Mráz* + + * The EVP_PKEY_public_check() and EVP_PKEY_param_check() functions now work for + more key types. + + * The output from the command line applications may have minor + changes. + + *Paul Dale* + + * The output from numerous "printing" may have minor changes. + + *David von Oheimb* + + * Windows thread synchronization uses read/write primitives (SRWLock) when + supported by the OS, otherwise CriticalSection continues to be used. + + *Vincent Drake* + + * Add filter BIO BIO_f_readbuffer() that allows BIO_tell() and BIO_seek() to + work on read only BIO source/sinks that do not support these functions. + This allows piping or redirection of a file BIO using stdin to be buffered + into memory. This is used internally in OSSL_DECODER_from_bio(). + + *Shane Lontis* + + * OSSL_STORE_INFO_get_type() may now return an additional value. In 1.1.1 + this function would return one of the values OSSL_STORE_INFO_NAME, + OSSL_STORE_INFO_PKEY, OSSL_STORE_INFO_PARAMS, OSSL_STORE_INFO_CERT or + OSSL_STORE_INFO_CRL. Decoded public keys would previously have been reported + as type OSSL_STORE_INFO_PKEY in 1.1.1. In 3.0 decoded public keys are now + reported as having the new type OSSL_STORE_INFO_PUBKEY. Applications + using this function should be amended to handle the changed return value. + + *Richard Levitte* + + * Improved adherence to Enhanced Security Services (ESS, RFC 2634 and RFC 5035) + for the TSP and CMS Advanced Electronic Signatures (CAdES) implementations. + As required by RFC 5035 check both ESSCertID and ESSCertIDv2 if both present. + Correct the semantics of checking the validation chain in case ESSCertID{,v2} + contains more than one certificate identifier: This means that all + certificates referenced there MUST be part of the validation chain. + + *David von Oheimb* + + * The implementation of older EVP ciphers related to CAST, IDEA, SEED, RC2, RC4, + RC5, DESX and DES have been moved to the legacy provider. + + *Matt Caswell* + + * The implementation of the EVP digests MD2, MD4, MDC2, WHIRLPOOL and + RIPEMD-160 have been moved to the legacy provider. + + *Matt Caswell* + + * The deprecated function EVP_PKEY_get0() now returns NULL being called for a + provided key. + + *Dmitry Belyavskiy* + + * The deprecated functions EVP_PKEY_get0_RSA(), + EVP_PKEY_get0_DSA(), EVP_PKEY_get0_EC_KEY(), EVP_PKEY_get0_DH(), + EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305() and EVP_PKEY_get0_siphash() as + well as the similarly named "get1" functions behave differently in + OpenSSL 3.0. + + *Matt Caswell* + + * A number of functions handling low-level keys or engines were deprecated + including EVP_PKEY_set1_engine(), EVP_PKEY_get0_engine(), EVP_PKEY_assign(), + EVP_PKEY_get0(), EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305() and + EVP_PKEY_get0_siphash(). + + *Matt Caswell* + + * PKCS#5 PBKDF1 key derivation has been moved from PKCS5_PBE_keyivgen() into + the legacy crypto provider as an EVP_KDF. Applications requiring this KDF + will need to load the legacy crypto provider. This includes these PBE + algorithms which use this KDF: + - NID_pbeWithMD2AndDES_CBC + - NID_pbeWithMD5AndDES_CBC + - NID_pbeWithSHA1AndRC2_CBC + - NID_pbeWithMD2AndRC2_CBC + - NID_pbeWithMD5AndRC2_CBC + - NID_pbeWithSHA1AndDES_CBC + + *Jon Spillett* + + * Deprecated obsolete BIO_set_callback(), BIO_get_callback(), and + BIO_debug_callback() functions. + + *Tomáš Mráz* + + * Deprecated obsolete EVP_PKEY_CTX_get0_dh_kdf_ukm() and + EVP_PKEY_CTX_get0_ecdh_kdf_ukm() functions. + + *Tomáš Mráz* + + * The RAND_METHOD APIs have been deprecated. + + *Paul Dale* + + * The SRP APIs have been deprecated. + + *Matt Caswell* + + * Add a compile time option to prevent the caching of provider fetched + algorithms. This is enabled by including the no-cached-fetch option + at configuration time. + + *Paul Dale* + + * pkcs12 now uses defaults of PBKDF2, AES and SHA-256, with a MAC iteration + count of PKCS12_DEFAULT_ITER. + + *Tomáš Mráz and Sahana Prasad* + + * The openssl speed command does not use low-level API calls anymore. + + *Tomáš Mráz* + + * Parallel dual-prime 1024-bit modular exponentiation for AVX512_IFMA + capable processors. + + *Ilya Albrekht, Sergey Kirillov, Andrey Matyukov (Intel Corp)* + + * Combining the Configure options no-ec and no-dh no longer disables TLSv1.3. + + *Matt Caswell* + + * Implemented support for fully "pluggable" TLSv1.3 groups. This means that + providers may supply their own group implementations (using either the "key + exchange" or the "key encapsulation" methods) which will automatically be + detected and used by libssl. + + *Matt Caswell, Nicola Tuveri* + + * The undocumented function X509_certificate_type() has been deprecated; + + *Rich Salz* + + * Deprecated the obsolete BN_pseudo_rand() and BN_pseudo_rand_range(). + + *Tomáš Mráz* + + * Removed RSA padding mode for SSLv23 (which was only used for + SSLv2). This includes the functions RSA_padding_check_SSLv23() and + RSA_padding_add_SSLv23() and the `-ssl` option in the deprecated + `rsautl` command. + + *Rich Salz* + + * Deprecated the obsolete X9.31 RSA key generation related functions. + + * While a callback function set via `SSL_CTX_set_cert_verify_callback()` + is not allowed to return a value > 1, this is no more taken as failure. + + *Viktor Dukhovni and David von Oheimb* + + * Deprecated the obsolete X9.31 RSA key generation related functions + BN_X931_generate_Xpq(), BN_X931_derive_prime_ex(), and + BN_X931_generate_prime_ex(). + + *Tomáš Mráz* + + * The default key generation method for the regular 2-prime RSA keys was + changed to the FIPS 186-4 B.3.6 method. + + *Shane Lontis* + + * Deprecated the BN_is_prime_ex() and BN_is_prime_fasttest_ex() functions. + + *Kurt Roeckx* + + * Deprecated EVP_MD_CTX_set_update_fn() and EVP_MD_CTX_update_fn(). + + *Rich Salz* + + * Deprecated the type OCSP_REQ_CTX and the functions OCSP_REQ_CTX_*() and + replaced with OSSL_HTTP_REQ_CTX and the functions OSSL_HTTP_REQ_CTX_*(). + + *Rich Salz, Richard Levitte, and David von Oheimb* + + * Deprecated `X509_http_nbio()` and `X509_CRL_http_nbio()`. + + *David von Oheimb* + + * Deprecated `OCSP_parse_url()`. + + *David von Oheimb* + + * Validation of SM2 keys has been separated from the validation of regular EC + keys. + + *Nicola Tuveri* + + * Behavior of the `pkey` app is changed, when using the `-check` or `-pubcheck` + switches: a validation failure triggers an early exit, returning a failure + exit status to the parent process. + + *Nicola Tuveri* + + * Changed behavior of SSL_CTX_set_ciphersuites() and SSL_set_ciphersuites() + to ignore unknown ciphers. + + *Otto Hollmann* + + * The `-cipher-commands` and `-digest-commands` options + of the command line utility `list` have been deprecated. + Instead use the `-cipher-algorithms` and `-digest-algorithms` options. + + *Dmitry Belyavskiy* + + * Added convenience functions for generating asymmetric key pairs: + The 'quick' one-shot (yet somewhat limited) function L + and macros for the most common cases: and L. + + *David von Oheimb* + + * All of the low level EC_KEY functions have been deprecated. + + *Shane Lontis, Paul Dale, Richard Levitte, and Tomáš Mráz* + + * Deprecated all the libcrypto and libssl error string loading + functions. + + *Richard Levitte* + + * The functions SSL_CTX_set_tmp_dh_callback and SSL_set_tmp_dh_callback, as + well as the macros SSL_CTX_set_tmp_dh() and SSL_set_tmp_dh() have been + deprecated. + + *Matt Caswell* + + * The `-crypt` option to the `passwd` command line tool has been removed. + + *Paul Dale* + + * The -C option to the `x509`, `dhparam`, `dsaparam`, and `ecparam` commands + were removed. + + *Rich Salz* + + * Add support for AES Key Wrap inverse ciphers to the EVP layer. + + *Shane Lontis* + + * Deprecated EVP_PKEY_set1_tls_encodedpoint() and + EVP_PKEY_get1_tls_encodedpoint(). + + *Matt Caswell* + + * The security callback, which can be customised by application code, supports + the security operation SSL_SECOP_TMP_DH. One location of the "other" parameter + was incorrectly passing a DH object. It now passed an EVP_PKEY in all cases. + + *Matt Caswell* + + * Add PKCS7_get_octet_string() and PKCS7_type_is_other() to the public + interface. Their functionality remains unchanged. + + *Jordan Montgomery* + + * Added new option for 'openssl list', '-providers', which will display the + list of loaded providers, their names, version and status. It optionally + displays their gettable parameters. + + *Paul Dale* + + * Removed EVP_PKEY_set_alias_type(). + + *Richard Levitte* + + * Deprecated `EVP_PKEY_CTX_set_rsa_keygen_pubexp()` and introduced + `EVP_PKEY_CTX_set1_rsa_keygen_pubexp()`, which is now preferred. + + *Jeremy Walch* + + * Changed all "STACK" functions to be macros instead of inline functions. Macro + parameters are still checked for type safety at compile time via helper + inline functions. + + *Matt Caswell* + + * Remove the RAND_DRBG API + + *Paul Dale and Matthias St. Pierre* + + * Allow `SSL_set1_host()` and `SSL_add1_host()` to take IP literal addresses + as well as actual hostnames. + + *David Woodhouse* + + * The 'MinProtocol' and 'MaxProtocol' configuration commands now silently + ignore TLS protocol version bounds when configuring DTLS-based contexts, and + conversely, silently ignore DTLS protocol version bounds when configuring + TLS-based contexts. The commands can be repeated to set bounds of both + types. The same applies with the corresponding "min_protocol" and + "max_protocol" command-line switches, in case some application uses both TLS + and DTLS. + + SSL_CTX instances that are created for a fixed protocol version (e.g. + `TLSv1_server_method()`) also silently ignore version bounds. Previously + attempts to apply bounds to these protocol versions would result in an + error. Now only the "version-flexible" SSL_CTX instances are subject to + limits in configuration files in command-line options. + + *Viktor Dukhovni* + + * Deprecated the `ENGINE` API. Engines should be replaced with providers + going forward. + + *Paul Dale* + + * Reworked the recorded ERR codes to make better space for system errors. + To distinguish them, the macro `ERR_SYSTEM_ERROR()` indicates if the + given code is a system error (true) or an OpenSSL error (false). + + *Richard Levitte* + + * Reworked the test perl framework to better allow parallel testing. + + *Nicola Tuveri and David von Oheimb* + + * Added ciphertext stealing algorithms AES-128-CBC-CTS, AES-192-CBC-CTS and + AES-256-CBC-CTS to the providers. CS1, CS2 and CS3 variants are supported. + + *Shane Lontis* + + * 'Configure' has been changed to figure out the configuration target if + none is given on the command line. Consequently, the 'config' script is + now only a mere wrapper. All documentation is changed to only mention + 'Configure'. + + *Rich Salz and Richard Levitte* + + * Added a library context `OSSL_LIB_CTX` that applications as well as + other libraries can use to form a separate context within which + libcrypto operations are performed. + + *Richard Levitte* + + * Added various `_ex` functions to the OpenSSL API that support using + a non-default `OSSL_LIB_CTX`. + + *OpenSSL team* + + * Handshake now fails if Extended Master Secret extension is dropped + on renegotiation. + + *Tomáš Mráz* + + * Dropped interactive mode from the `openssl` program. + + *Richard Levitte* + + * Deprecated `EVP_PKEY_cmp()` and `EVP_PKEY_cmp_parameters()`. + + *David von Oheimb and Shane Lontis* + + * Deprecated `EC_METHOD_get_field_type()`. + + *Billy Bob Brumley* + + * Deprecated EC_GFp_simple_method(), EC_GFp_mont_method(), + EC_GF2m_simple_method(), EC_GFp_nist_method(), EC_GFp_nistp224_method() + EC_GFp_nistp256_method(), and EC_GFp_nistp521_method(). + + *Billy Bob Brumley* + + * Deprecated EC_GROUP_new(), EC_GROUP_method_of(), and EC_POINT_method_of(). + + *Billy Bob Brumley* + + * Add CAdES-BES signature verification support, mostly derived + from ESSCertIDv2 TS (RFC 5816) contribution by Marek Klein. + + *Filipe Raimundo da Silva* + + * Add CAdES-BES signature scheme and attributes support (RFC 5126) to CMS API. + + *Antonio Iacono* + + * Added the AuthEnvelopedData content type structure (RFC 5083) with AES-GCM + parameter (RFC 5084) for the Cryptographic Message Syntax (CMS). + + *Jakub Zelenka* + + * Deprecated EC_POINT_make_affine() and EC_POINTs_make_affine(). + + *Billy Bob Brumley* + + * Deprecated EC_GROUP_precompute_mult(), EC_GROUP_have_precompute_mult(), and + EC_KEY_precompute_mult(). + + *Billy Bob Brumley* + + * Deprecated EC_POINTs_mul(). + + *Billy Bob Brumley* + + * Removed FIPS_mode() and FIPS_mode_set(). + + *Shane Lontis* + + * The SSL option SSL_OP_IGNORE_UNEXPECTED_EOF is introduced. + + *Dmitry Belyavskiy* + + * Deprecated EC_POINT_set_Jprojective_coordinates_GFp() and + EC_POINT_get_Jprojective_coordinates_GFp(). + + *Billy Bob Brumley* + + * Added OSSL_PARAM_BLD to the public interface. This allows OSSL_PARAM + arrays to be more easily constructed via a series of utility functions. + Create a parameter builder using OSSL_PARAM_BLD_new(), add parameters using + the various push functions and finally convert to a passable OSSL_PARAM + array using OSSL_PARAM_BLD_to_param(). + + *Paul Dale* + + * The security strength of SHA1 and MD5 based signatures in TLS has been + reduced. + + *Kurt Roeckx* + + * Added EVP_PKEY_set_type_by_keymgmt(), to initialise an EVP_PKEY to + contain a provider side internal key. + + *Richard Levitte* + + * ASN1_verify(), ASN1_digest() and ASN1_sign() have been deprecated. + + *Richard Levitte* + + * Project text documents not yet having a proper file name extension + (`HACKING`, `LICENSE`, `NOTES*`, `README*`, `VERSION`) have been renamed to + `*.md` as far as reasonable, else `*.txt`, for better use with file managers. + + *David von Oheimb* + + * The main project documents (README, NEWS, CHANGES, INSTALL, SUPPORT) + have been converted to Markdown with the goal to produce documents + which not only look pretty when viewed online in the browser, but + remain well readable inside a plain text editor. + + To achieve this goal, a 'minimalistic' Markdown style has been applied + which avoids formatting elements that interfere too much with the + reading flow in the text file. For example, it + + * avoids [ATX headings][] and uses [setext headings][] instead + (which works for `

` and `

` headings only). + * avoids [inline links][] and uses [reference links][] instead. + * avoids [fenced code blocks][] and uses [indented code blocks][] instead. + + [ATX headings]: https://github.github.com/gfm/#atx-headings + [setext headings]: https://github.github.com/gfm/#setext-headings + [inline links]: https://github.github.com/gfm/#inline-link + [reference links]: https://github.github.com/gfm/#reference-link + [fenced code blocks]: https://github.github.com/gfm/#fenced-code-blocks + [indented code blocks]: https://github.github.com/gfm/#indented-code-blocks + + *Matthias St. Pierre* + + * The test suite is changed to preserve results of each test recipe. + A new directory test-runs/ with subdirectories named like the + test recipes are created in the build tree for this purpose. + + *Richard Levitte* + + * Added an implementation of CMP and CRMF (RFC 4210, RFC 4211 RFC 6712). + This adds `crypto/cmp/`, `crpyto/crmf/`, `apps/cmp.c`, and `test/cmp_*`. + See L and L as starting points. + + *David von Oheimb, Martin Peylo* + + * Generalized the HTTP client code from `crypto/ocsp/` into `crpyto/http/`. + It supports arbitrary request and response content types, GET redirection, + TLS, connections via HTTP(S) proxies, connections and exchange via + user-defined BIOs (allowing implicit connections), persistent connections, + and timeout checks. See L etc. for details. + The legacy OCSP-focused (and only partly documented) API + is retained for backward compatibility, while most of it is deprecated. + + *David von Oheimb* + + * Added `util/check-format.pl`, a tool for checking adherence to the + OpenSSL coding style . + The checks performed are incomplete and yield some false positives. + Still the tool should be useful for detecting most typical glitches. + + *David von Oheimb* + + * `BIO_do_connect()` and `BIO_do_handshake()` have been extended: + If domain name resolution yields multiple IP addresses all of them are tried + after `connect()` failures. + + *David von Oheimb* + + * All of the low level RSA functions have been deprecated. + + *Paul Dale* + + * X509 certificates signed using SHA1 are no longer allowed at security + level 1 and above. + + *Kurt Roeckx* + + * The command line utilities dhparam, dsa, gendsa and dsaparam have been + modified to use PKEY APIs. These commands are now in maintenance mode + and no new features will be added to them. + + *Paul Dale* + + * The command line utility rsautl has been deprecated. + + *Paul Dale* + + * The command line utilities genrsa and rsa have been modified to use PKEY + APIs. They now write PKCS#8 keys by default. These commands are now in + maintenance mode and no new features will be added to them. + + *Paul Dale* + + * All of the low level DH functions have been deprecated. + + *Paul Dale and Matt Caswell* + + * All of the low level DSA functions have been deprecated. + + *Paul Dale* + + * Reworked the treatment of EC EVP_PKEYs with the SM2 curve to + automatically become EVP_PKEY_SM2 rather than EVP_PKEY_EC. + + *Richard Levitte* + + * Deprecated low level ECDH and ECDSA functions. + + *Paul Dale* + + * Deprecated EVP_PKEY_decrypt_old() and EVP_PKEY_encrypt_old(). + + *Richard Levitte* + + * Enhanced the documentation of EVP_PKEY_get_size(), EVP_PKEY_get_bits() + and EVP_PKEY_get_security_bits(). Especially EVP_PKEY_get_size() needed + a new formulation to include all the things it can be used for, + as well as words of caution. + + *Richard Levitte* + + * The SSL_CTX_set_tlsext_ticket_key_cb(3) function has been deprecated. + + *Paul Dale* + + * All of the low level HMAC functions have been deprecated. + + *Paul Dale and David von Oheimb* + + * Over two thousand fixes were made to the documentation, including: + - Common options (such as -rand/-writerand, TLS version control, etc) + were refactored and point to newly-enhanced descriptions in openssl.pod. + - Added style conformance for all options (with help from Richard Levitte), + documented all reported missing options, added a CI build to check + that all options are documented and that no unimplemented options + are documented. + - Documented some internals, such as all use of environment variables. + - Addressed all internal broken L<> references. + + *Rich Salz* + + * All of the low level CMAC functions have been deprecated. + + *Paul Dale* + + * The low-level MD2, MD4, MD5, MDC2, RIPEMD160 and Whirlpool digest + functions have been deprecated. + + *Paul Dale and David von Oheimb* + + * Corrected the documentation of the return values from the `EVP_DigestSign*` + set of functions. The documentation mentioned negative values for some + errors, but this was never the case, so the mention of negative values + was removed. + + Code that followed the documentation and thereby check with something + like `EVP_DigestSignInit(...) <= 0` will continue to work undisturbed. + + *Richard Levitte* + + * All of the low level cipher functions have been deprecated. + + *Matt Caswell and Paul Dale* + + * Removed include/openssl/opensslconf.h.in and replaced it with + include/openssl/configuration.h.in, which differs in not including + . A short header include/openssl/opensslconf.h + was added to include both. + + This allows internal hacks where one might need to modify the set + of configured macros, for example this if deprecated symbols are + still supposed to be available internally: + + #include + + #undef OPENSSL_NO_DEPRECATED + #define OPENSSL_SUPPRESS_DEPRECATED + + #include + + This should not be used by applications that use the exported + symbols, as that will lead to linking errors. + + *Richard Levitte* + + * Fixed an overflow bug in the x64_64 Montgomery squaring procedure + used in exponentiation with 512-bit moduli. No EC algorithms are + affected. Analysis suggests that attacks against 2-prime RSA1024, + 3-prime RSA1536, and DSA1024 as a result of this defect would be very + difficult to perform and are not believed likely. Attacks against DH512 + are considered just feasible. However, for an attack the target would + have to re-use the DH512 private key, which is not recommended anyway. + Also applications directly using the low-level API BN_mod_exp may be + affected if they use BN_FLG_CONSTTIME. + ([CVE-2019-1551]) + + *Andy Polyakov* + + * Most memory-debug features have been deprecated, and the functionality + replaced with no-ops. + + *Rich Salz* + + * Added documentation for the STACK API. + + *Rich Salz* + + * Introduced a new method type and API, OSSL_ENCODER, to represent + generic encoders. These do the same sort of job that PEM writers + and d2i functions do, but with support for methods supplied by + providers, and the possibility for providers to support other + formats as well. + + *Richard Levitte* + + * Introduced a new method type and API, OSSL_DECODER, to represent + generic decoders. These do the same sort of job that PEM readers + and i2d functions do, but with support for methods supplied by + providers, and the possibility for providers to support other + formats as well. + + *Richard Levitte* + + * Added a .pragma directive to the syntax of configuration files, to + allow varying behavior in a supported and predictable manner. + Currently added pragma: + + .pragma dollarid:on + + This allows dollar signs to be a keyword character unless it's + followed by a opening brace or parenthesis. This is useful for + platforms where dollar signs are commonly used in names, such as + volume names and system directory names on VMS. + + *Richard Levitte* + + * Added functionality to create an EVP_PKEY from user data. + + *Richard Levitte* + + * Change the interpretation of the '--api' configuration option to + mean that this is a desired API compatibility level with no + further meaning. The previous interpretation, that this would + also mean to remove all deprecated symbols up to and including + the given version, no requires that 'no-deprecated' is also used + in the configuration. + + When building applications, the desired API compatibility level + can be set with the OPENSSL_API_COMPAT macro like before. For + API compatibility version below 3.0, the old style numerical + value is valid as before, such as -DOPENSSL_API_COMPAT=0x10100000L. + For version 3.0 and on, the value is expected to be the decimal + value calculated from the major and minor version like this: + + MAJOR * 10000 + MINOR * 100 + + Examples: + + -DOPENSSL_API_COMPAT=30000 For 3.0 + -DOPENSSL_API_COMPAT=30200 For 3.2 + + To hide declarations that are deprecated up to and including the + given API compatibility level, -DOPENSSL_NO_DEPRECATED must be + given when building the application as well. + + *Richard Levitte* + + * Added the X509_LOOKUP_METHOD called X509_LOOKUP_store, to allow + access to certificate and CRL stores via URIs and OSSL_STORE + loaders. + + This adds the following functions: + + - X509_LOOKUP_store() + - X509_STORE_load_file() + - X509_STORE_load_path() + - X509_STORE_load_store() + - SSL_add_store_cert_subjects_to_stack() + - SSL_CTX_set_default_verify_store() + - SSL_CTX_load_verify_file() + - SSL_CTX_load_verify_dir() + - SSL_CTX_load_verify_store() + + *Richard Levitte* + + * Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY. + The presence of this system service is determined at run-time. + + *Richard Levitte* + + * Added functionality to create an EVP_PKEY context based on data + for methods from providers. This takes an algorithm name and a + property query string and simply stores them, with the intent + that any operation that uses this context will use those strings + to fetch the needed methods implicitly, thereby making the port + of application written for pre-3.0 OpenSSL easier. + + *Richard Levitte* + + * The undocumented function NCONF_WIN32() has been deprecated; for + conversion details see the HISTORY section of doc/man5/config.pod + + *Rich Salz* + + * Introduced the new functions EVP_DigestSignInit_ex() and + EVP_DigestVerifyInit_ex(). The macros EVP_DigestSignUpdate() and + EVP_DigestVerifyUpdate() have been converted to functions. See the man + pages for further details. + + *Matt Caswell* + + * Over two thousand fixes were made to the documentation, including: + adding missing command flags, better style conformance, documentation + of internals, etc. + + *Rich Salz, Richard Levitte* + + * s390x assembly pack: add hardware-support for P-256, P-384, P-521, + X25519, X448, Ed25519 and Ed448. + + *Patrick Steuer* + + * Print all values for a PKCS#12 attribute with 'openssl pkcs12', not just + the first value. + + *Jon Spillett* + + * Deprecated the public definition of `ERR_STATE` as well as the function + `ERR_get_state()`. This is done in preparation of making `ERR_STATE` an + opaque type. + + *Richard Levitte* + + * Added ERR functionality to give callers access to the stored function + names that have replaced the older function code based functions. + + New functions are ERR_peek_error_func(), ERR_peek_last_error_func(), + ERR_peek_error_data(), ERR_peek_last_error_data(), ERR_get_error_all(), + ERR_peek_error_all() and ERR_peek_last_error_all(). + + Deprecate ERR functions ERR_get_error_line(), ERR_get_error_line_data(), + ERR_peek_error_line_data(), ERR_peek_last_error_line_data() and + ERR_func_error_string(). + + *Richard Levitte* + + * Extended testing to be verbose for failing tests only. The make variables + VERBOSE_FAILURE or VF can be used to enable this: + + $ make VF=1 test # Unix + $ mms /macro=(VF=1) test ! OpenVMS + $ nmake VF=1 test # Windows + + *Richard Levitte* + + * Added the `-copy_extensions` option to the `x509` command for use with + `-req` and `-x509toreq`. When given with the `copy` or `copyall` argument, + all extensions in the request are copied to the certificate or vice versa. + + *David von Oheimb*, *Kirill Stefanenkov * + + * Added the `-copy_extensions` option to the `req` command for use with + `-x509`. When given with the `copy` or `copyall` argument, + all extensions in the certification request are copied to the certificate. + + *David von Oheimb* + + * The `x509`, `req`, and `ca` commands now make sure that X.509v3 certificates + they generate are by default RFC 5280 compliant in the following sense: + There is a subjectKeyIdentifier extension with a hash value of the public key + and for not self-signed certs there is an authorityKeyIdentifier extension + with a keyIdentifier field or issuer information identifying the signing key. + This is done unless some configuration overrides the new default behavior, + such as `subjectKeyIdentifier = none` and `authorityKeyIdentifier = none`. + + *David von Oheimb* + + * Added several checks to `X509_verify_cert()` according to requirements in + RFC 5280 in case `X509_V_FLAG_X509_STRICT` is set + (which may be done by using the CLI option `-x509_strict`): + * The basicConstraints of CA certificates must be marked critical. + * CA certificates must explicitly include the keyUsage extension. + * If a pathlenConstraint is given the key usage keyCertSign must be allowed. + * The issuer name of any certificate must not be empty. + * The subject name of CA certs, certs with keyUsage crlSign, + and certs without subjectAlternativeName must not be empty. + * If a subjectAlternativeName extension is given it must not be empty. + * The signatureAlgorithm field and the cert signature must be consistent. + * Any given authorityKeyIdentifier and any given subjectKeyIdentifier + must not be marked critical. + * The authorityKeyIdentifier must be given for X.509v3 certs + unless they are self-signed. + * The subjectKeyIdentifier must be given for all X.509v3 CA certs. + + *David von Oheimb* + + * Certificate verification using `X509_verify_cert()` meanwhile rejects EC keys + with explicit curve parameters (specifiedCurve) as required by RFC 5480. + + *Tomáš Mráz* + + * For built-in EC curves, ensure an EC_GROUP built from the curve name is + used even when parsing explicit parameters, when loading a encoded 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 + encoded, the output is still encoded with explicit parameters, even if + internally a "named" EC_GROUP is used for computation. + + *Nicola Tuveri* + + * Compute ECC cofactors if not provided during EC_GROUP construction. Before + this change, EC_GROUP_set_generator would accept order and/or cofactor as + NULL. After this change, only the cofactor parameter can be NULL. It also + does some minimal sanity checks on the passed order. + ([CVE-2019-1547]) + + *Billy Bob Brumley* + + * Fixed a padding oracle in PKCS7_dataDecode and CMS_decrypt_set1_pkey. + An attack is simple, if the first CMS_recipientInfo is valid but the + second CMS_recipientInfo is chosen ciphertext. If the second + recipientInfo decodes to PKCS #1 v1.5 form plaintext, the correct + encryption key will be replaced by garbage, and the message cannot be + decoded, but if the RSA decryption fails, the correct encryption key is + used and the recipient will not notice the attack. + As a work around for this potential attack the length of the decrypted + key must be equal to the cipher default key length, in case the + certifiate is not given and all recipientInfo are tried out. + The old behaviour can be re-enabled in the CMS code by setting the + CMS_DEBUG_DECRYPT flag. + + *Bernd Edlinger* + + * Early start up entropy quality from the DEVRANDOM seed source has been + improved for older Linux systems. The RAND subsystem will wait for + /dev/random to be producing output before seeding from /dev/urandom. + The seeded state is stored for future library initialisations using + a system global shared memory segment. The shared memory identifier + can be configured by defining OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID to + the desired value. The default identifier is 114. + + *Paul Dale* + + * Revised BN_generate_prime_ex to not avoid factors 2..17863 in p-1 + when primes for RSA keys are computed. + Since we previously always generated primes == 2 (mod 3) for RSA keys, + the 2-prime and 3-prime RSA modules were easy to distinguish, since + `N = p*q = 1 (mod 3)`, but `N = p*q*r = 2 (mod 3)`. Therefore fingerprinting + 2-prime vs. 3-prime RSA keys was possible by computing N mod 3. + This avoids possible fingerprinting of newly generated RSA modules. + + *Bernd Edlinger* + + * Correct the extended master secret constant on EBCDIC systems. Without this + fix TLS connections between an EBCDIC system and a non-EBCDIC system that + negotiate EMS will fail. Unfortunately this also means that TLS connections + between EBCDIC systems with this fix, and EBCDIC systems without this + fix will fail if they negotiate EMS. + + *Matt Caswell* + + * Changed the library initialisation so that the config file is now loaded + by default. This was already the case for libssl. It now occurs for both + libcrypto and libssl. Use the OPENSSL_INIT_NO_LOAD_CONFIG option to + `OPENSSL_init_crypto()` to suppress automatic loading of a config file. + + *Matt Caswell* + + * Introduced new error raising macros, `ERR_raise()` and `ERR_raise_data()`, + where the former acts as a replacement for `ERR_put_error()`, and the + latter replaces the combination `ERR_put_error()` + `ERR_add_error_data()`. + `ERR_raise_data()` adds more flexibility by taking a format string and + an arbitrary number of arguments following it, to be processed with + `BIO_snprintf()`. + + *Richard Levitte* + + * Introduced a new function, `OSSL_PROVIDER_available()`, which can be used + to check if a named provider is loaded and available. When called, it + will also activate all fallback providers if such are still present. + + *Richard Levitte* + + * Enforce a minimum DH modulus size of 512 bits. + + *Bernd Edlinger* + + * Changed DH parameters to generate the order q subgroup instead of 2q. + Previously generated DH parameters are still accepted by DH_check + but DH_generate_key works around that by clearing bit 0 of the + private key for those. This avoids leaking bit 0 of the private key. + + *Bernd Edlinger* + + * Significantly reduce secure memory usage by the randomness pools. + + *Paul Dale* + + * `{CRYPTO,OPENSSL}_mem_debug_{push,pop}` are now no-ops and have been + deprecated. + + *Rich Salz* + + * A new type, EVP_KEYEXCH, has been introduced to represent key exchange + algorithms. An implementation of a key exchange algorithm can be obtained + by using the function EVP_KEYEXCH_fetch(). An EVP_KEYEXCH algorithm can be + used in a call to EVP_PKEY_derive_init_ex() which works in a similar way to + the older EVP_PKEY_derive_init() function. See the man pages for the new + functions for further details. + + *Matt Caswell* + + * The EVP_PKEY_CTX_set_dh_pad() macro has now been converted to a function. + + *Matt Caswell* + + * Removed the function names from error messages and deprecated the + xxx_F_xxx define's. + + *Richard Levitte* + + * Removed NextStep support and the macro OPENSSL_UNISTD + + *Rich Salz* + + * Removed DES_check_key. Also removed OPENSSL_IMPLEMENT_GLOBAL, + OPENSSL_GLOBAL_REF, OPENSSL_DECLARE_GLOBAL. + Also removed "export var as function" capability; we do not export + variables, only functions. + + *Rich Salz* + + * RC5_32_set_key has been changed to return an int type, with 0 indicating + an error and 1 indicating success. In previous versions of OpenSSL this + was a void type. If a key was set longer than the maximum possible this + would crash. + + *Matt Caswell* + + * Support SM2 signing and verification schemes with X509 certificate. + + *Paul Yang* + + * Use SHA256 as the default digest for TS query in the `ts` app. + + *Tomáš Mráz* + + * Change PBKDF2 to conform to SP800-132 instead of the older PKCS5 RFC2898. + + *Shane Lontis* + + * Default cipher lists/suites are now available via a function, the + #defines are deprecated. + + *Todd Short* + + * Add target VC-WIN32-UWP, VC-WIN64A-UWP, VC-WIN32-ARM-UWP and + VC-WIN64-ARM-UWP in Windows OneCore target for making building libraries + for Windows Store apps easier. Also, the "no-uplink" option has been added. + + *Kenji Mouri* + + * Join the directories crypto/x509 and crypto/x509v3 + + *Richard Levitte* + + * Added command 'openssl kdf' that uses the EVP_KDF API. + + *Shane Lontis* + + * Added command 'openssl mac' that uses the EVP_MAC API. + + *Shane Lontis* + + * Added OPENSSL_info() to get diverse built-in OpenSSL data, such + as default directories. Also added the command 'openssl info' + for scripting purposes. + + *Richard Levitte* + + * The functions AES_ige_encrypt() and AES_bi_ige_encrypt() have been + deprecated. + + *Matt Caswell* + + * Add prediction resistance to the DRBG reseeding process. + + *Paul Dale* + + * Limit the number of blocks in a data unit for AES-XTS to 2^20 as + mandated by IEEE Std 1619-2018. + + *Paul Dale* + + * Added newline escaping functionality to a filename when using openssl dgst. + This output format is to replicate the output format found in the `*sum` + checksum programs. This aims to preserve backward compatibility. + + *Matt Eaton, Richard Levitte, and Paul Dale* + + * Removed the heartbeat message in DTLS feature, as it has very + little usage and doesn't seem to fulfill a valuable purpose. + The configuration option is now deprecated. + + *Richard Levitte* + + * Changed the output of 'openssl {digestname} < file' to display the + digest name in its output. + + *Richard Levitte* + + * Added a new generic trace API which provides support for enabling + instrumentation through trace output. + + *Richard Levitte & Matthias St. Pierre* + + * Added build tests for C++. These are generated files that only do one + thing, to include one public OpenSSL head file each. This tests that + the public header files can be usefully included in a C++ application. + + This test isn't enabled by default. It can be enabled with the option + 'enable-buildtest-c++'. + + *Richard Levitte* + + * Added KB KDF (EVP_KDF_KB) to EVP_KDF. + + *Robbie Harwood* + + * Added SSH KDF (EVP_KDF_SSHKDF) and KRB5 KDF (EVP_KDF_KRB5KDF) to EVP_KDF. + + *Simo Sorce* + + * Added Single Step KDF (EVP_KDF_SS), X963 KDF, and X942 KDF to EVP_KDF. + + *Shane Lontis* + + * Added KMAC to EVP_MAC. + + *Shane Lontis* + + * Added property based algorithm implementation selection framework to + the core. + + *Paul Dale* + + * Added SCA hardening for modular field inversion in EC_GROUP through + a new dedicated field_inv() pointer in EC_METHOD. + This also addresses a leakage affecting conversions from projective + to affine coordinates. + + *Billy Bob Brumley, Nicola Tuveri* + + * Added EVP_KDF, an EVP layer KDF API, to simplify adding KDF and PRF + implementations. This includes an EVP_PKEY to EVP_KDF bridge for + those algorithms that were already supported through the EVP_PKEY API + (scrypt, TLS1 PRF and HKDF). The low-level KDF functions for PBKDF2 + and scrypt are now wrappers that call EVP_KDF. + + *David Makepeace* + + * Build devcrypto engine as a dynamic engine. + + *Eneas U de Queiroz* + + * Add keyed BLAKE2 to EVP_MAC. + + *Antoine Salon* + + * Fix a bug in the computation of the endpoint-pair shared secret used + by DTLS over SCTP. This breaks interoperability with older versions + of OpenSSL like OpenSSL 1.1.0 and OpenSSL 1.0.2. There is a runtime + switch SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG (off by default) enabling + interoperability with such broken implementations. However, enabling + this switch breaks interoperability with correct implementations. + + * Fix a use after free bug in d2i_X509_PUBKEY when overwriting a + re-used X509_PUBKEY object if the second PUBKEY is malformed. + + *Bernd Edlinger* + + * Move strictness check from EVP_PKEY_asn1_new() to EVP_PKEY_asn1_add0(). + + *Richard Levitte* + + * Changed the license to the Apache License v2.0. + + *Richard Levitte* + + * Switch to a new version scheme using three numbers MAJOR.MINOR.PATCH. + + - Major releases (indicated by incrementing the MAJOR release number) + may introduce incompatible API/ABI changes. + - Minor releases (indicated by incrementing the MINOR release number) + may introduce new features but retain API/ABI compatibility. + - Patch releases (indicated by incrementing the PATCH number) + are intended for bug fixes and other improvements of existing + features only (like improving performance or adding documentation) + and retain API/ABI compatibility. + + *Richard Levitte* + + * Add support for RFC5297 SIV mode (siv128), including AES-SIV. + + *Todd Short* + + * Remove the 'dist' target and add a tarball building script. The + 'dist' target has fallen out of use, and it shouldn't be + necessary to configure just to create a source distribution. + + *Richard Levitte* + + * Recreate the OS390-Unix config target. It no longer relies on a + special script like it did for OpenSSL pre-1.1.0. + + *Richard Levitte* + + * Instead of having the source directories listed in Configure, add + a 'build.info' keyword SUBDIRS to indicate what sub-directories to + look into. + + *Richard Levitte* + + * Add GMAC to EVP_MAC. + + *Paul Dale* + + * Ported the HMAC, CMAC and SipHash EVP_PKEY_METHODs to EVP_MAC. + + *Richard Levitte* + + * Added EVP_MAC, an EVP layer MAC API, to simplify adding MAC + implementations. This includes a generic EVP_PKEY to EVP_MAC bridge, + to facilitate the continued use of MACs through raw private keys in + functionality such as `EVP_DigestSign*` and `EVP_DigestVerify*`. + + *Richard Levitte* + + * Deprecate ECDH_KDF_X9_62(). + + *Antoine Salon* + + * Added EVP_PKEY_ECDH_KDF_X9_63 and ecdh_KDF_X9_63() as replacements for + the EVP_PKEY_ECDH_KDF_X9_62 KDF type and ECDH_KDF_X9_62(). The old names + are retained for backwards compatibility. + + *Antoine Salon* + + * AES-XTS mode now enforces that its two keys are different to mitigate + the attacked described in "Efficient Instantiations of Tweakable + Blockciphers and Refinements to Modes OCB and PMAC" by Phillip Rogaway. + Details of this attack can be obtained from: + + + *Paul Dale* + + * Rename the object files, i.e. give them other names than in previous + versions. Their names now include the name of the final product, as + well as its type mnemonic (bin, lib, shlib). + + *Richard Levitte* + + * Added new option for 'openssl list', '-objects', which will display the + list of built in objects, i.e. OIDs with names. + + *Richard Levitte* + + * Added the options `-crl_lastupdate` and `-crl_nextupdate` to `openssl ca`, + allowing the `lastUpdate` and `nextUpdate` fields in the generated CRL to + be set explicitly. + + *Chris Novakovic* + + * Added support for Linux Kernel TLS data-path. The Linux Kernel data-path + improves application performance by removing data copies and providing + applications with zero-copy system calls such as sendfile and splice. + + *Boris Pismenny* + + * The SSL option SSL_OP_CLEANSE_PLAINTEXT is introduced. + + *Martin Elshuber* + + * `PKCS12_parse` now maintains the order of the parsed certificates + when outputting them via `*ca` (rather than reversing it). + + *David von Oheimb* + + * Deprecated pthread fork support methods. + + *Randall S. Becker* + + * Added support for FFDHE key exchange in TLS 1.3. + + *Raja Ashok* + + * Added a new concept for OpenSSL plugability: providers. This + functionality is designed to replace the ENGINE API and ENGINE + implementations, and to be much more dynamic, allowing provider + authors to introduce new algorithms among other things, as long as + there's an API that supports the algorithm type. + + With this concept comes a new core API for interaction between + libcrypto and provider implementations. Public libcrypto functions + that want to use providers do so through this core API. + + The main documentation for this core API is found in + doc/man7/provider.pod, doc/man7/provider-base.pod, and they in turn + refer to other manuals describing the API specific for supported + algorithm types (also called operations). + + *The OpenSSL team* + +OpenSSL 1.1.1 +------------- + +### Changes between 1.1.1l and 1.1.1m [xx XXX xxxx] + + * Avoid loading of a dynamic engine twice. + + *Bernd Edlinger* + + * Prioritise DANE TLSA issuer certs over peer certs + + *Viktor Dukhovni* + + * Fixed random API for MacOS prior to 10.12 + + These MacOS versions don't support the CommonCrypto APIs + + *Lenny Primak* + +### Changes between 1.1.1k and 1.1.1l [24 Aug 2021] + + * Fixed an SM2 Decryption Buffer Overflow. + + In order to decrypt SM2 encrypted data an application is expected to + call the API function EVP_PKEY_decrypt(). Typically an application will + call this function twice. The first time, on entry, the "out" parameter + can be NULL and, on exit, the "outlen" parameter is populated with the + buffer size required to hold the decrypted plaintext. The application + can then allocate a sufficiently sized buffer and call EVP_PKEY_decrypt() + again, but this time passing a non-NULL value for the "out" parameter. + + A bug in the implementation of the SM2 decryption code means that the + calculation of the buffer size required to hold the plaintext returned + by the first call to EVP_PKEY_decrypt() can be smaller than the actual + size required by the second call. This can lead to a buffer overflow + when EVP_PKEY_decrypt() is called by the application a second time with + a buffer that is too small. + + A malicious attacker who is able present SM2 content for decryption to + an application could cause attacker chosen data to overflow the buffer + by up to a maximum of 62 bytes altering the contents of other data held + after the buffer, possibly changing application behaviour or causing + the application to crash. The location of the buffer is application + dependent but is typically heap allocated. + ([CVE-2021-3711]) + + *Matt Caswell* + + * Fixed various read buffer overruns processing ASN.1 strings + + ASN.1 strings are represented internally within OpenSSL as an ASN1_STRING + structure which contains a buffer holding the string data and a field + holding the buffer length. This contrasts with normal C strings which + are repesented as a buffer for the string data which is terminated + with a NUL (0) byte. + + Although not a strict requirement, ASN.1 strings that are parsed using + OpenSSL's own "d2i" functions (and other similar parsing functions) as + well as any string whose value has been set with the ASN1_STRING_set() + function will additionally NUL terminate the byte array in the + ASN1_STRING structure. + + However, it is possible for applications to directly construct valid + ASN1_STRING structures which do not NUL terminate the byte array by + directly setting the "data" and "length" fields in the ASN1_STRING + array. This can also happen by using the ASN1_STRING_set0() function. + + Numerous OpenSSL functions that print ASN.1 data have been found to + assume that the ASN1_STRING byte array will be NUL terminated, even + though this is not guaranteed for strings that have been directly + constructed. Where an application requests an ASN.1 structure to be + printed, and where that ASN.1 structure contains ASN1_STRINGs that have + been directly constructed by the application without NUL terminating + the "data" field, then a read buffer overrun can occur. + + The same thing can also occur during name constraints processing + of certificates (for example if a certificate has been directly + constructed by the application instead of loading it via the OpenSSL + parsing functions, and the certificate contains non NUL terminated + ASN1_STRING structures). It can also occur in the X509_get1_email(), + X509_REQ_get1_email() and X509_get1_ocsp() functions. + + If a malicious actor can cause an application to directly construct an + ASN1_STRING and then process it through one of the affected OpenSSL + functions then this issue could be hit. This might result in a crash + (causing a Denial of Service attack). It could also result in the + disclosure of private memory contents (such as private keys, or + sensitive plaintext). + ([CVE-2021-3712]) + + *Matt Caswell* + +### Changes between 1.1.1j and 1.1.1k [25 Mar 2021] + + * Fixed a problem with verifying a certificate chain when using the + X509_V_FLAG_X509_STRICT flag. This flag enables additional security checks of + the certificates present in a certificate chain. It is not set by default. + + Starting from OpenSSL version 1.1.1h a check to disallow certificates in + the chain that have explicitly encoded elliptic curve parameters was added + as an additional strict check. + + An error in the implementation of this check meant that the result of a + previous check to confirm that certificates in the chain are valid CA + certificates was overwritten. This effectively bypasses the check + that non-CA certificates must not be able to issue other certificates. + + If a "purpose" has been configured then there is a subsequent opportunity + for checks that the certificate is a valid CA. All of the named "purpose" + values implemented in libcrypto perform this check. Therefore, where + a purpose is set the certificate chain will still be rejected even when the + strict flag has been used. A purpose is set by default in libssl client and + server certificate verification routines, but it can be overridden or + removed by an application. + + In order to be affected, an application must explicitly set the + X509_V_FLAG_X509_STRICT verification flag and either not set a purpose + for the certificate verification or, in the case of TLS client or server + applications, override the default purpose. + ([CVE-2021-3450]) + + *Tomáš Mráz* + + * Fixed an issue where an OpenSSL TLS server may crash if sent a maliciously + crafted renegotiation ClientHello message from a client. If a TLSv1.2 + renegotiation ClientHello omits the signature_algorithms extension (where it + was present in the initial ClientHello), but includes a + signature_algorithms_cert extension then a NULL pointer dereference will + result, leading to a crash and a denial of service attack. + + A server is only vulnerable if it has TLSv1.2 and renegotiation enabled + (which is the default configuration). OpenSSL TLS clients are not impacted by + this issue. + ([CVE-2021-3449]) + + *Peter Kästle and Samuel Sapalski* + +### Changes between 1.1.1i and 1.1.1j [16 Feb 2021] + + * Fixed the X509_issuer_and_serial_hash() function. It attempts to + create a unique hash value based on the issuer and serial number data + contained within an X509 certificate. However it was failing to correctly + handle any errors that may occur while parsing the issuer field (which might + occur if the issuer field is maliciously constructed). This may subsequently + result in a NULL pointer deref and a crash leading to a potential denial of + service attack. + ([CVE-2021-23841]) + + *Matt Caswell* + + * Fixed the RSA_padding_check_SSLv23() function and the RSA_SSLV23_PADDING + padding mode to correctly check for rollback attacks. This is considered a + bug in OpenSSL 1.1.1 because it does not support SSLv2. In 1.0.2 this is + CVE-2021-23839. + + *Matt Caswell* + + Fixed the EVP_CipherUpdate, EVP_EncryptUpdate and EVP_DecryptUpdate + functions. Previously they could overflow the output length argument in some + cases where the input length is close to the maximum permissable length for + an integer on the platform. In such cases the return value from the function + call would be 1 (indicating success), but the output length value would be + negative. This could cause applications to behave incorrectly or crash. + ([CVE-2021-23840]) + + *Matt Caswell* + + * Fixed SRP_Calc_client_key so that it runs in constant time. The previous + implementation called BN_mod_exp without setting BN_FLG_CONSTTIME. This + could be exploited in a side channel attack to recover the password. Since + the attack is local host only this is outside of the current OpenSSL + threat model and therefore no CVE is assigned. + + Thanks to Mohammed Sabt and Daniel De Almeida Braga for reporting this + issue. + + *Matt Caswell* + +### Changes between 1.1.1h and 1.1.1i [8 Dec 2020] + + * Fixed NULL pointer deref in the GENERAL_NAME_cmp function + This function could crash if both GENERAL_NAMEs contain an EDIPARTYNAME. + If an attacker can control both items being compared then this could lead + to a possible denial of service attack. OpenSSL itself uses the + GENERAL_NAME_cmp function for two purposes: + 1) Comparing CRL distribution point names between an available CRL and a + CRL distribution point embedded in an X509 certificate + 2) When verifying that a timestamp response token signer matches the + timestamp authority name (exposed via the API functions + TS_RESP_verify_response and TS_RESP_verify_token) + ([CVE-2020-1971]) + + *Matt Caswell* + +### Changes between 1.1.1g and 1.1.1h [22 Sep 2020] + + * Certificates with explicit curve parameters are now disallowed in + verification chains if the X509_V_FLAG_X509_STRICT flag is used. + + *Tomáš Mráz* + + * The 'MinProtocol' and 'MaxProtocol' configuration commands now silently + ignore TLS protocol version bounds when configuring DTLS-based contexts, and + conversely, silently ignore DTLS protocol version bounds when configuring + TLS-based contexts. The commands can be repeated to set bounds of both + types. The same applies with the corresponding "min_protocol" and + "max_protocol" command-line switches, in case some application uses both TLS + and DTLS. + + SSL_CTX instances that are created for a fixed protocol version (e.g. + TLSv1_server_method()) also silently ignore version bounds. Previously + attempts to apply bounds to these protocol versions would result in an + error. Now only the "version-flexible" SSL_CTX instances are subject to + limits in configuration files in command-line options. + + *Viktor Dukhovni* + + * Handshake now fails if Extended Master Secret extension is dropped + on renegotiation. + + *Tomáš Mráz* + + * The Oracle Developer Studio compiler will start reporting deprecated APIs + +### Changes between 1.1.1f and 1.1.1g [21 Apr 2020] + + * Fixed segmentation fault in SSL_check_chain() + Server or client applications that call the SSL_check_chain() function + during or after a TLS 1.3 handshake may crash due to a NULL pointer + dereference as a result of incorrect handling of the + "signature_algorithms_cert" TLS extension. The crash occurs if an invalid + or unrecognised signature algorithm is received from the peer. This could + be exploited by a malicious peer in a Denial of Service attack. + ([CVE-2020-1967]) + + *Benjamin Kaduk* + + * Added AES consttime code for no-asm configurations + an optional constant time support for AES was added + when building openssl for no-asm. + Enable with: ./config no-asm -DOPENSSL_AES_CONST_TIME + Disable with: ./config no-asm -DOPENSSL_NO_AES_CONST_TIME + At this time this feature is by default disabled. + It will be enabled by default in 3.0. + + *Bernd Edlinger* + +### Changes between 1.1.1e and 1.1.1f [31 Mar 2020] + + * Revert the change of EOF detection while reading in libssl to avoid + regressions in applications depending on the current way of reporting + the EOF. As the existing method is not fully accurate the change to + reporting the EOF via SSL_ERROR_SSL is kept on the current development + branch and will be present in the 3.0 release. + + *Tomáš Mráz* + + * Revised BN_generate_prime_ex to not avoid factors 3..17863 in p-1 + when primes for RSA keys are computed. + Since we previously always generated primes == 2 (mod 3) for RSA keys, + the 2-prime and 3-prime RSA modules were easy to distinguish, since + N = p*q = 1 (mod 3), but N = p*q*r = 2 (mod 3). Therefore fingerprinting + 2-prime vs. 3-prime RSA keys was possible by computing N mod 3. + This avoids possible fingerprinting of newly generated RSA modules. + + *Bernd Edlinger* + +### Changes between 1.1.1d and 1.1.1e [17 Mar 2020] + + * Properly detect EOF while reading in libssl. Previously if we hit an EOF + while reading in libssl then we would report an error back to the + application (SSL_ERROR_SYSCALL) but errno would be 0. We now add + an error to the stack (which means we instead return SSL_ERROR_SSL) and + therefore give a hint as to what went wrong. + + *Matt Caswell* + + * Check that ed25519 and ed448 are allowed by the security level. Previously + signature algorithms not using an MD were not being checked that they were + allowed by the security level. + + *Kurt Roeckx* + + * Fixed SSL_get_servername() behaviour. The behaviour of SSL_get_servername() + was not quite right. The behaviour was not consistent between resumption + and normal handshakes, and also not quite consistent with historical + behaviour. The behaviour in various scenarios has been clarified and + it has been updated to make it match historical behaviour as closely as + possible. + + *Matt Caswell* + + * *[VMS only]* The header files that the VMS compilers include automatically, + `__DECC_INCLUDE_PROLOGUE.H` and `__DECC_INCLUDE_EPILOGUE.H`, use pragmas + that the C++ compiler doesn't understand. This is a shortcoming in the + compiler, but can be worked around with `__cplusplus` guards. + + C++ applications that use OpenSSL libraries must be compiled using the + qualifier `/NAMES=(AS_IS,SHORTENED)` to be able to use all the OpenSSL + functions. Otherwise, only functions with symbols of less than 31 + characters can be used, as the linker will not be able to successfully + resolve symbols with longer names. + + *Richard Levitte* + + * Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY. + The presence of this system service is determined at run-time. + + *Richard Levitte* + + * Print all values for a PKCS#12 attribute with 'openssl pkcs12', not just + the first value. + + *Jon Spillett* + +### 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 encoded 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 + encoded, 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 + thing, to include one public OpenSSL head file each. This tests that + the public header files can be usefully included in a C++ application. + + This test isn't enabled by default. It can be enabled with the option + 'enable-buildtest-c++'. + + *Richard Levitte* + + * Enable SHA3 pre-hashing for ECDSA and DSA. + + *Patrick Steuer* + + * Change the default RSA, DSA and DH size to 2048 bit instead of 1024. + This changes the size when using the `genpkey` command when no size is given. + It fixes an omission in earlier changes that changed all RSA, DSA and DH + generation commands to use 2048 bits by default. + + *Kurt Roeckx* + + * Reorganize the manual pages to consistently have RETURN VALUES, + EXAMPLES, SEE ALSO and HISTORY come in that order, and adjust + util/fix-doc-nits accordingly. + + *Paul Yang, Joshua Lock* + + * Add the missing accessor EVP_PKEY_get0_engine() + + *Matt Caswell* + + * Have commands like `s_client` and `s_server` output the signature scheme + along with other cipher suite parameters when debugging. + + *Lorinczy Zsigmond* + + * Make OPENSSL_config() error agnostic again. + + *Richard Levitte* + + * Do the error handling in RSA decryption constant time. + + *Bernd Edlinger* + + * Prevent over long nonces in ChaCha20-Poly1305. + + ChaCha20-Poly1305 is an AEAD cipher, and requires a unique nonce input + for every encryption operation. RFC 7539 specifies that the nonce value + (IV) should be 96 bits (12 bytes). OpenSSL allows a variable nonce length + and front pads the nonce with 0 bytes if it is less than 12 + bytes. However it also incorrectly allows a nonce to be set of up to 16 + bytes. In this case only the last 12 bytes are significant and any + additional leading bytes are ignored. + + It is a requirement of using this cipher that nonce values are + unique. Messages encrypted using a reused nonce value are susceptible to + serious confidentiality and integrity attacks. If an application changes + the default nonce length to be longer than 12 bytes and then makes a + change to the leading bytes of the nonce expecting the new value to be a + new unique nonce then such an application could inadvertently encrypt + messages with a reused nonce. + + Additionally the ignored bytes in a long nonce are not covered by the + integrity guarantee of this cipher. Any application that relies on the + integrity of these ignored leading bytes of a long nonce may be further + affected. Any OpenSSL internal use of this cipher, including in SSL/TLS, + is safe because no such use sets such a long nonce value. However user + applications that use this cipher directly and set a non-default nonce + length to be longer than 12 bytes may be vulnerable. + + This issue was reported to OpenSSL on 16th of March 2019 by Joran Dirk + Greef of Ronomon. + ([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* + +### Changes between 1.1.1a and 1.1.1b [26 Feb 2019] + + * Change the info callback signals for the start and end of a post-handshake + message exchange in TLSv1.3. In 1.1.1/1.1.1a we used SSL_CB_HANDSHAKE_START + and SSL_CB_HANDSHAKE_DONE. Experience has shown that many applications get + confused by this and assume that a TLSv1.2 renegotiation has started. This + can break KeyUpdate handling. Instead we no longer signal the start and end + of a post handshake message exchange (although the messages themselves are + still signalled). This could break some applications that were expecting + the old signals. However without this KeyUpdate is not usable for many + applications. + + *Matt Caswell* + +### Changes between 1.1.1 and 1.1.1a [20 Nov 2018] + + * Timing vulnerability in DSA signature generation + + The OpenSSL DSA signature algorithm has been shown to be vulnerable to a + timing side channel attack. An attacker could use variations in the signing + algorithm to recover the private key. + + This issue was reported to OpenSSL on 16th October 2018 by Samuel Weiser. + ([CVE-2018-0734]) + + *Paul Dale* + + * Timing vulnerability in ECDSA signature generation + + The OpenSSL ECDSA signature algorithm has been shown to be vulnerable to a + timing side channel attack. An attacker could use variations in the signing + algorithm to recover the private key. + + This issue was reported to OpenSSL on 25th October 2018 by Samuel Weiser. + ([CVE-2018-0735]) + + *Paul Dale* + + * Fixed the issue that RAND_add()/RAND_seed() silently discards random input + if its length exceeds 4096 bytes. The limit has been raised to a buffer size + of two gigabytes and the error handling improved. + + This issue was reported to OpenSSL by Dr. Falko Strenzke. It has been + categorized as a normal bug, not a security issue, because the DRBG reseeds + automatically and is fully functional even without additional randomness + provided by the application. + +### Changes between 1.1.0i and 1.1.1 [11 Sep 2018] + + * Add a new ClientHello callback. Provides a callback interface that gives + the application the ability to adjust the nascent SSL object at the + earliest stage of ClientHello processing, immediately after extensions have + been collected but before they have been processed. In particular, this + callback can adjust the supported TLS versions in response to the contents + of the ClientHello + + *Benjamin Kaduk* + + * Add SM2 base algorithm support. + + *Jack Lloyd* + + * s390x assembly pack: add (improved) hardware-support for the following + cryptographic primitives: sha3, shake, aes-gcm, aes-ccm, aes-ctr, aes-ofb, + aes-cfb/cfb8, aes-ecb. + + *Patrick Steuer* + + * Make EVP_PKEY_asn1_new() a bit stricter about its input. A NULL pem_str + parameter is no longer accepted, as it leads to a corrupt table. NULL + pem_str is reserved for alias entries only. + + *Richard Levitte* + + * Use the new ec_scalar_mul_ladder scaffold to implement a specialized ladder + step for prime curves. The new implementation is based on formulae from + differential addition-and-doubling in homogeneous projective coordinates + from Izu-Takagi "A fast parallel elliptic curve multiplication resistant + against side channel attacks" and Brier-Joye "Weierstrass Elliptic Curves + and Side-Channel Attacks" Eq. (8) for y-coordinate recovery, modified + to work in projective coordinates. + + *Billy Bob Brumley, Nicola Tuveri* + + * Change generating and checking of primes so that the error rate of not + being prime depends on the intended use based on the size of the input. + For larger primes this will result in more rounds of Miller-Rabin. + The maximal error rate for primes with more than 1080 bits is lowered + to 2^-128. + + *Kurt Roeckx, Annie Yousar* + + * Increase the number of Miller-Rabin rounds for DSA key generating to 64. + + *Kurt Roeckx* + + * The 'tsget' script is renamed to 'tsget.pl', to avoid confusion when + moving between systems, and to avoid confusion when a Windows build is + done with mingw vs with MSVC. For POSIX installs, there's still a + symlink or copy named 'tsget' to avoid that confusion as well. + + *Richard Levitte* + + * Revert blinding in ECDSA sign and instead make problematic addition + length-invariant. Switch even to fixed-length Montgomery multiplication. + + *Andy Polyakov* + + * Use the new ec_scalar_mul_ladder scaffold to implement a specialized ladder + step for binary curves. The new implementation is based on formulae from + differential addition-and-doubling in mixed Lopez-Dahab projective + coordinates, modified to independently blind the operands. + + *Billy Bob Brumley, Sohaib ul Hassan, Nicola Tuveri* + + * Add a scaffold to optionally enhance the Montgomery ladder implementation + for `ec_scalar_mul_ladder` (formerly `ec_mul_consttime`) allowing + EC_METHODs to implement their own specialized "ladder step", to take + advantage of more favorable coordinate systems or more efficient + differential addition-and-doubling algorithms. + + *Billy Bob Brumley, Sohaib ul Hassan, Nicola Tuveri* + + * Modified the random device based seed sources to keep the relevant + file descriptors open rather than reopening them on each access. + This allows such sources to operate in a chroot() jail without + the associated device nodes being available. This behaviour can be + controlled using RAND_keep_random_devices_open(). + + *Paul Dale* + + * Numerous side-channel attack mitigations have been applied. This may have + performance impacts for some algorithms for the benefit of improved + security. Specific changes are noted in this change log by their respective + authors. + + *Matt Caswell* + + * AIX shared library support overhaul. Switch to AIX "natural" way of + handling shared libraries, which means collecting shared objects of + different versions and bitnesses in one common archive. This allows to + mitigate conflict between 1.0 and 1.1 side-by-side installations. It + doesn't affect the way 3rd party applications are linked, only how + multi-version installation is managed. + + *Andy Polyakov* + + * Make ec_group_do_inverse_ord() more robust and available to other + EC cryptosystems, so that irrespective of BN_FLG_CONSTTIME, SCA + mitigations are applied to the fallback BN_mod_inverse(). + When using this function rather than BN_mod_inverse() directly, new + EC cryptosystem implementations are then safer-by-default. + + *Billy Bob Brumley* + + * Add coordinate blinding for EC_POINT and implement projective + coordinate blinding for generic prime curves as a countermeasure to + chosen point SCA attacks. + + *Sohaib ul Hassan, Nicola Tuveri, Billy Bob Brumley* + + * Add blinding to ECDSA and DSA signatures to protect against side channel + attacks discovered by Keegan Ryan (NCC Group). + + *Matt Caswell* + + * Enforce checking in the `pkeyutl` command to ensure that the input + length does not exceed the maximum supported digest length when performing + a sign, verify or verifyrecover operation. + + *Matt Caswell* + + * SSL_MODE_AUTO_RETRY is enabled by default. Applications that use blocking + I/O in combination with something like select() or poll() will hang. This + can be turned off again using SSL_CTX_clear_mode(). + Many applications do not properly handle non-application data records, and + TLS 1.3 sends more of such records. Setting SSL_MODE_AUTO_RETRY works + around the problems in those applications, but can also break some. + It's recommended to read the manpages about SSL_read(), SSL_write(), + SSL_get_error(), SSL_shutdown(), SSL_CTX_set_mode() and + SSL_CTX_set_read_ahead() again. + + *Kurt Roeckx* + + * When unlocking a pass phrase protected PEM file or PKCS#8 container, we + now allow empty (zero character) pass phrases. + + *Richard Levitte* + + * Apply blinding to binary field modular inversion and remove patent + pending (OPENSSL_SUN_GF2M_DIV) BN_GF2m_mod_div implementation. + + *Billy Bob Brumley* + + * Deprecate ec2_mult.c and unify scalar multiplication code paths for + binary and prime elliptic curves. + + *Billy Bob Brumley* + + * Remove ECDSA nonce padding: EC_POINT_mul is now responsible for + constant time fixed point multiplication. + + *Billy Bob Brumley* + + * Revise elliptic curve scalar multiplication with timing attack + defenses: ec_wNAF_mul redirects to a constant time implementation + when computing fixed point and variable point multiplication (which + in OpenSSL are mostly used with secret scalars in keygen, sign, + ECDH derive operations). + *Billy Bob Brumley, Nicola Tuveri, Cesar Pereida García, + Sohaib ul Hassan* + + * Updated CONTRIBUTING + + *Rich Salz* + + * Updated DRBG / RAND to request nonce and additional low entropy + randomness from the system. + + *Matthias St. Pierre* + + * Updated 'openssl rehash' to use OpenSSL consistent default. + + *Richard Levitte* + + * Moved the load of the ssl_conf module to libcrypto, which helps + loading engines that libssl uses before libssl is initialised. + + *Matt Caswell* + + * Added EVP_PKEY_sign() and EVP_PKEY_verify() for EdDSA + + *Matt Caswell* + + * Fixed X509_NAME_ENTRY_set to get multi-valued RDNs right in all cases. + + *Ingo Schwarze, Rich Salz* + + * Added output of accepting IP address and port for 'openssl s_server' + + *Richard Levitte* + + * Added a new API for TLSv1.3 ciphersuites: + SSL_CTX_set_ciphersuites() + SSL_set_ciphersuites() + + *Matt Caswell* + + * Memory allocation failures consistently add an error to the error + stack. + + *Rich Salz* + + * Don't use OPENSSL_ENGINES and OPENSSL_CONF environment values + in libcrypto when run as setuid/setgid. + + *Bernd Edlinger* + + * Load any config file by default when libssl is used. + + *Matt Caswell* + + * Added new public header file and documentation + for the RAND_DRBG API. See manual page RAND_DRBG(7) for an overview. + + *Matthias St. Pierre* + + * QNX support removed (cannot find contributors to get their approval + for the license change). + + *Rich Salz* + + * TLSv1.3 replay protection for early data has been implemented. See the + SSL_read_early_data() man page for further details. + + *Matt Caswell* + + * Separated TLSv1.3 ciphersuite configuration out from TLSv1.2 ciphersuite + configuration. TLSv1.3 ciphersuites are not compatible with TLSv1.2 and + below. Similarly TLSv1.2 ciphersuites are not compatible with TLSv1.3. + In order to avoid issues where legacy TLSv1.2 ciphersuite configuration + would otherwise inadvertently disable all TLSv1.3 ciphersuites the + configuration has been separated out. See the ciphers man page or the + SSL_CTX_set_ciphersuites() man page for more information. + + *Matt Caswell* + + * On POSIX (BSD, Linux, ...) systems the ocsp(1) command running + in responder mode now supports the new "-multi" option, which + spawns the specified number of child processes to handle OCSP + requests. The "-timeout" option now also limits the OCSP + responder's patience to wait to receive the full client request + on a newly accepted connection. Child processes are respawned + as needed, and the CA index file is automatically reloaded + when changed. This makes it possible to run the "ocsp" responder + as a long-running service, making the OpenSSL CA somewhat more + feature-complete. In this mode, most diagnostic messages logged + after entering the event loop are logged via syslog(3) rather than + written to stderr. + + *Viktor Dukhovni* + + * Added support for X448 and Ed448. Heavily based on original work by + Mike Hamburg. + + *Matt Caswell* + + * Extend OSSL_STORE with capabilities to search and to narrow the set of + objects loaded. This adds the functions OSSL_STORE_expect() and + OSSL_STORE_find() as well as needed tools to construct searches and + get the search data out of them. + + *Richard Levitte* + + * Support for TLSv1.3 added. Note that users upgrading from an earlier + version of OpenSSL should review their configuration settings to ensure + that they are still appropriate for TLSv1.3. For further information see: + + + *Matt Caswell* + + * Grand redesign of the OpenSSL random generator + + The default RAND method now utilizes an AES-CTR DRBG according to + NIST standard SP 800-90Ar1. The new random generator is essentially + a port of the default random generator from the OpenSSL FIPS 2.0 + object module. It is a hybrid deterministic random bit generator + using an AES-CTR bit stream and which seeds and reseeds itself + automatically using trusted system entropy sources. + + Some of its new features are: + - Support for multiple DRBG instances with seed chaining. + - The default RAND method makes use of a DRBG. + - There is a public and private DRBG instance. + - The DRBG instances are fork-safe. + - Keep all global DRBG instances on the secure heap if it is enabled. + - The public and private DRBG instance are per thread for lock free + operation + + *Paul Dale, Benjamin Kaduk, Kurt Roeckx, Rich Salz, Matthias St. Pierre* + + * Changed Configure so it only says what it does and doesn't dump + so much data. Instead, ./configdata.pm should be used as a script + to display all sorts of configuration data. + + *Richard Levitte* + + * Added processing of "make variables" to Configure. + + *Richard Levitte* + + * Added SHA512/224 and SHA512/256 algorithm support. + + *Paul Dale* + + * The last traces of Netware support, first removed in 1.1.0, have + now been removed. + + *Rich Salz* + + * Get rid of Makefile.shared, and in the process, make the processing + of certain files (rc.obj, or the .def/.map/.opt files produced from + the ordinal files) more visible and hopefully easier to trace and + debug (or make silent). + + *Richard Levitte* + + * Make it possible to have environment variable assignments as + arguments to config / Configure. + + *Richard Levitte* + + * Add multi-prime RSA (RFC 8017) support. + + *Paul Yang* + + * Add SM3 implemented according to GB/T 32905-2016 + *Jack Lloyd ,* + *Ronald Tse ,* + *Erick Borsboom * + + * Add 'Maximum Fragment Length' TLS extension negotiation and support + as documented in RFC6066. + Based on a patch from Tomasz Moń + + *Filipe Raimundo da Silva* + + * Add SM4 implemented according to GB/T 32907-2016. + *Jack Lloyd ,* + *Ronald Tse ,* + *Erick Borsboom * + + * Reimplement -newreq-nodes and ERR_error_string_n; the + original author does not agree with the license change. + + *Rich Salz* + + * Add ARIA AEAD TLS support. + + *Jon Spillett* + + * Some macro definitions to support VS6 have been removed. Visual + Studio 6 has not worked since 1.1.0 + + *Rich Salz* + + * Add ERR_clear_last_mark(), to allow callers to clear the last mark + without clearing the errors. + + *Richard Levitte* + + * Add "atfork" functions. If building on a system that without + pthreads, see doc/man3/OPENSSL_fork_prepare.pod for application + requirements. The RAND facility now uses/requires this. + + *Rich Salz* + + * Add SHA3. + + *Andy Polyakov* + + * The UI API becomes a permanent and integral part of libcrypto, i.e. + not possible to disable entirely. However, it's still possible to + disable the console reading UI method, UI_OpenSSL() (use UI_null() + as a fallback). + + To disable, configure with 'no-ui-console'. 'no-ui' is still + possible to use as an alias. Check at compile time with the + macro OPENSSL_NO_UI_CONSOLE. The macro OPENSSL_NO_UI is still + possible to check and is an alias for OPENSSL_NO_UI_CONSOLE. + + *Richard Levitte* + + * Add a STORE module, which implements a uniform and URI based reader of + stores that can contain keys, certificates, CRLs and numerous other + objects. The main API is loosely based on a few stdio functions, + and includes OSSL_STORE_open, OSSL_STORE_load, OSSL_STORE_eof, + OSSL_STORE_error and OSSL_STORE_close. + The implementation uses backends called "loaders" to implement arbitrary + URI schemes. There is one built in "loader" for the 'file' scheme. + + *Richard Levitte* + + * Add devcrypto engine. This has been implemented against cryptodev-linux, + then adjusted to work on FreeBSD 8.4 as well. + Enable by configuring with 'enable-devcryptoeng'. This is done by default + on BSD implementations, as cryptodev.h is assumed to exist on all of them. + + *Richard Levitte* + + * Module names can prefixed with OSSL_ or OPENSSL_. This affects + util/mkerr.pl, which is adapted to allow those prefixes, leading to + error code calls like this: + + OSSL_FOOerr(OSSL_FOO_F_SOMETHING, OSSL_FOO_R_WHATEVER); + + With this change, we claim the namespaces OSSL and OPENSSL in a manner + that can be encoded in C. For the foreseeable future, this will only + affect new modules. + + *Richard Levitte and Tim Hudson* + + * Removed BSD cryptodev engine. + + *Rich Salz* + + * Add a build target 'build_all_generated', to build all generated files + and only that. This can be used to prepare everything that requires + things like perl for a system that lacks perl and then move everything + to that system and do the rest of the build there. + + *Richard Levitte* + + * In the UI interface, make it possible to duplicate the user data. This + can be used by engines that need to retain the data for a longer time + than just the call where this user data is passed. + + *Richard Levitte* + + * Ignore the '-named_curve auto' value for compatibility of applications + with OpenSSL 1.0.2. + + *Tomáš Mráz * + + * Fragmented SSL/TLS alerts are no longer accepted. An alert message is 2 + bytes long. In theory it is permissible in SSLv3 - TLSv1.2 to fragment such + alerts across multiple records (some of which could be empty). In practice + it make no sense to send an empty alert record, or to fragment one. TLSv1.3 + prohibits this altogether and other libraries (BoringSSL, NSS) do not + support this at all. Supporting it adds significant complexity to the + record layer, and its removal is unlikely to cause interoperability + issues. + + *Matt Caswell* + + * Add the ASN.1 types INT32, UINT32, INT64, UINT64 and variants prefixed + with Z. These are meant to replace LONG and ZLONG and to be size safe. + The use of LONG and ZLONG is discouraged and scheduled for deprecation + in OpenSSL 1.2.0. + + *Richard Levitte* + + * Add the 'z' and 'j' modifiers to BIO_printf() et al formatting string, + 'z' is to be used for [s]size_t, and 'j' - with [u]int64_t. + + *Richard Levitte, Andy Polyakov* + + * Add EC_KEY_get0_engine(), which does for EC_KEY what RSA_get0_engine() + does for RSA, etc. + + *Richard Levitte* + + * Have 'config' recognise 64-bit mingw and choose 'mingw64' as the target + platform rather than 'mingw'. + + *Richard Levitte* + + * The functions X509_STORE_add_cert and X509_STORE_add_crl return + success if they are asked to add an object which already exists + in the store. This change cascades to other functions which load + certificates and CRLs. + + *Paul Dale* + + * x86_64 assembly pack: annotate code with DWARF CFI directives to + facilitate stack unwinding even from assembly subroutines. + + *Andy Polyakov* + + * Remove VAX C specific definitions of OPENSSL_EXPORT, OPENSSL_EXTERN. + Also remove OPENSSL_GLOBAL entirely, as it became a no-op. + + *Richard Levitte* + + * Remove the VMS-specific reimplementation of gmtime from crypto/o_times.c. + VMS C's RTL has a fully up to date gmtime() and gmtime_r() since V7.1, + which is the minimum version we support. + + *Richard Levitte* + + * Certificate time validation (X509_cmp_time) enforces stricter + compliance with RFC 5280. Fractional seconds and timezone offsets + are no longer allowed. + + *Emilia Käsper* + + * Add support for ARIA + + *Paul Dale* + + * s_client will now send the Server Name Indication (SNI) extension by + default unless the new "-noservername" option is used. The server name is + based on the host provided to the "-connect" option unless overridden by + using "-servername". + + *Matt Caswell* + + * Add support for SipHash + + *Todd Short* + + * OpenSSL now fails if it receives an unrecognised record type in TLS1.0 + or TLS1.1. Previously this only happened in SSLv3 and TLS1.2. This is to + prevent issues where no progress is being made and the peer continually + sends unrecognised record types, using up resources processing them. + + *Matt Caswell* + + * 'openssl passwd' can now produce SHA256 and SHA512 based output, + using the algorithm defined in + + + *Richard Levitte* + + * Heartbeat support has been removed; the ABI is changed for now. + + *Richard Levitte, Rich Salz* + + * Support for SSL_OP_NO_ENCRYPT_THEN_MAC in SSL_CONF_cmd. + + *Emilia Käsper* + + * The RSA "null" method, which was partially supported to avoid patent + issues, has been replaced to always returns NULL. + + *Rich Salz* + +OpenSSL 1.1.0 +------------- + +### Changes between 1.1.0k and 1.1.0l [10 Sep 2019] + + * For built-in EC curves, ensure an EC_GROUP built from the curve name is + used even when parsing explicit parameters, when loading a encoded 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 + encoded, 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* + + * 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* + +### Changes between 1.1.0j and 1.1.0k [28 May 2019] + + * Change the default RSA, DSA and DH size to 2048 bit instead of 1024. + This changes the size when using the `genpkey` command when no size is given. + It fixes an omission in earlier changes that changed all RSA, DSA and DH + generation commands to use 2048 bits by default. + + *Kurt Roeckx* + + * Prevent over long nonces in ChaCha20-Poly1305. + + ChaCha20-Poly1305 is an AEAD cipher, and requires a unique nonce input + for every encryption operation. RFC 7539 specifies that the nonce value + (IV) should be 96 bits (12 bytes). OpenSSL allows a variable nonce length + and front pads the nonce with 0 bytes if it is less than 12 + bytes. However it also incorrectly allows a nonce to be set of up to 16 + bytes. In this case only the last 12 bytes are significant and any + additional leading bytes are ignored. + + It is a requirement of using this cipher that nonce values are + unique. Messages encrypted using a reused nonce value are susceptible to + serious confidentiality and integrity attacks. If an application changes + the default nonce length to be longer than 12 bytes and then makes a + change to the leading bytes of the nonce expecting the new value to be a + new unique nonce then such an application could inadvertently encrypt + messages with a reused nonce. + + Additionally the ignored bytes in a long nonce are not covered by the + integrity guarantee of this cipher. Any application that relies on the + integrity of these ignored leading bytes of a long nonce may be further + affected. Any OpenSSL internal use of this cipher, including in SSL/TLS, + is safe because no such use sets such a long nonce value. However user + applications that use this cipher directly and set a non-default nonce + length to be longer than 12 bytes may be vulnerable. + + This issue was reported to OpenSSL on 16th of March 2019 by Joran Dirk + Greef of Ronomon. + ([CVE-2019-1543]) + + *Matt Caswell* + + * Added SCA hardening for modular field inversion in EC_GROUP through + a new dedicated field_inv() pointer in EC_METHOD. + This also addresses a leakage affecting conversions from projective + to affine coordinates. + + *Billy Bob Brumley, Nicola Tuveri* + + * Fix a use after free bug in d2i_X509_PUBKEY when overwriting a + re-used X509_PUBKEY object if the second PUBKEY is malformed. + + *Bernd Edlinger* + + * Move strictness check from EVP_PKEY_asn1_new() to EVP_PKEY_asn1_add0(). + + *Richard Levitte* + + * Remove the 'dist' target and add a tarball building script. The + 'dist' target has fallen out of use, and it shouldn't be + necessary to configure just to create a source distribution. + + *Richard Levitte* + +### Changes between 1.1.0i and 1.1.0j [20 Nov 2018] + + * Timing vulnerability in DSA signature generation + + The OpenSSL DSA signature algorithm has been shown to be vulnerable to a + timing side channel attack. An attacker could use variations in the signing + algorithm to recover the private key. + + This issue was reported to OpenSSL on 16th October 2018 by Samuel Weiser. + ([CVE-2018-0734]) + + *Paul Dale* + + * Timing vulnerability in ECDSA signature generation + + The OpenSSL ECDSA signature algorithm has been shown to be vulnerable to a + timing side channel attack. An attacker could use variations in the signing + algorithm to recover the private key. + + This issue was reported to OpenSSL on 25th October 2018 by Samuel Weiser. + ([CVE-2018-0735]) + + *Paul Dale* + + * Add coordinate blinding for EC_POINT and implement projective + coordinate blinding for generic prime curves as a countermeasure to + chosen point SCA attacks. + + *Sohaib ul Hassan, Nicola Tuveri, Billy Bob Brumley* + +### Changes between 1.1.0h and 1.1.0i [14 Aug 2018] + + * Client DoS due to large DH parameter + + During key agreement in a TLS handshake using a DH(E) based ciphersuite a + malicious server can send a very large prime value to the client. This will + cause the client to spend an unreasonably long period of time generating a + key for this prime resulting in a hang until the client has finished. This + could be exploited in a Denial Of Service attack. + + This issue was reported to OpenSSL on 5th June 2018 by Guido Vranken + ([CVE-2018-0732]) + + *Guido Vranken* + + * Cache timing vulnerability in RSA Key Generation + + The OpenSSL RSA Key generation algorithm has been shown to be vulnerable to + a cache timing side channel attack. An attacker with sufficient access to + mount cache timing attacks during the RSA key generation process could + recover the private key. + + This issue was reported to OpenSSL on 4th April 2018 by Alejandro Cabrera + Aldaya, Billy Brumley, Cesar Pereida Garcia and Luis Manuel Alvarez Tapia. + ([CVE-2018-0737]) + + *Billy Brumley* + + * Make EVP_PKEY_asn1_new() a bit stricter about its input. A NULL pem_str + parameter is no longer accepted, as it leads to a corrupt table. NULL + pem_str is reserved for alias entries only. + + *Richard Levitte* + + * Revert blinding in ECDSA sign and instead make problematic addition + length-invariant. Switch even to fixed-length Montgomery multiplication. + + *Andy Polyakov* + + * Change generating and checking of primes so that the error rate of not + being prime depends on the intended use based on the size of the input. + For larger primes this will result in more rounds of Miller-Rabin. + The maximal error rate for primes with more than 1080 bits is lowered + to 2^-128. + + *Kurt Roeckx, Annie Yousar* + + * Increase the number of Miller-Rabin rounds for DSA key generating to 64. + + *Kurt Roeckx* + + * Add blinding to ECDSA and DSA signatures to protect against side channel + attacks discovered by Keegan Ryan (NCC Group). + + *Matt Caswell* + + * When unlocking a pass phrase protected PEM file or PKCS#8 container, we + now allow empty (zero character) pass phrases. + + *Richard Levitte* + + * Certificate time validation (X509_cmp_time) enforces stricter + compliance with RFC 5280. Fractional seconds and timezone offsets + are no longer allowed. + + *Emilia Käsper* + + * Fixed a text canonicalisation bug in CMS + + Where a CMS detached signature is used with text content the text goes + through a canonicalisation process first prior to signing or verifying a + signature. This process strips trailing space at the end of lines, converts + line terminators to CRLF and removes additional trailing line terminators + at the end of a file. A bug in the canonicalisation process meant that + some characters, such as form-feed, were incorrectly treated as whitespace + and removed. This is contrary to the specification (RFC5485). This fix + could mean that detached text data signed with an earlier version of + OpenSSL 1.1.0 may fail to verify using the fixed version, or text data + signed with a fixed OpenSSL may fail to verify with an earlier version of + OpenSSL 1.1.0. A workaround is to only verify the canonicalised text data + and use the "-binary" flag (for the "cms" command line application) or set + the SMIME_BINARY/PKCS7_BINARY/CMS_BINARY flags (if using CMS_verify()). + + *Matt Caswell* + +### Changes between 1.1.0g and 1.1.0h [27 Mar 2018] + + * Constructed ASN.1 types with a recursive definition could exceed the stack + + Constructed ASN.1 types with a recursive definition (such as can be found + in PKCS7) could eventually exceed the stack given malicious input with + excessive recursion. This could result in a Denial Of Service attack. There + are no such structures used within SSL/TLS that come from untrusted sources + so this is considered safe. + + This issue was reported to OpenSSL on 4th January 2018 by the OSS-fuzz + project. + ([CVE-2018-0739]) + + *Matt Caswell* + + * Incorrect CRYPTO_memcmp on HP-UX PA-RISC + + Because of an implementation bug the PA-RISC CRYPTO_memcmp function is + effectively reduced to only comparing the least significant bit of each + byte. This allows an attacker to forge messages that would be considered as + authenticated in an amount of tries lower than that guaranteed by the + security claims of the scheme. The module can only be compiled by the + HP-UX assembler, so that only HP-UX PA-RISC targets are affected. + + This issue was reported to OpenSSL on 2nd March 2018 by Peter Waltenberg + (IBM). + ([CVE-2018-0733]) + + *Andy Polyakov* + + * Add a build target 'build_all_generated', to build all generated files + and only that. This can be used to prepare everything that requires + things like perl for a system that lacks perl and then move everything + to that system and do the rest of the build there. + + *Richard Levitte* + + * Backport SSL_OP_NO_RENGOTIATION + + OpenSSL 1.0.2 and below had the ability to disable renegotiation using the + (undocumented) SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS flag. Due to the opacity + changes this is no longer possible in 1.1.0. Therefore the new + SSL_OP_NO_RENEGOTIATION option from 1.1.1-dev has been backported to + 1.1.0 to provide equivalent functionality. + + Note that if an application built against 1.1.0h headers (or above) is run + using an older version of 1.1.0 (prior to 1.1.0h) then the option will be + accepted but nothing will happen, i.e. renegotiation will not be prevented. + + *Matt Caswell* + + * Removed the OS390-Unix config target. It relied on a script that doesn't + exist. + + *Rich Salz* + + * rsaz_1024_mul_avx2 overflow bug on x86_64 + + There is an overflow bug in the AVX2 Montgomery multiplication procedure + used in exponentiation with 1024-bit moduli. No EC algorithms are affected. + Analysis suggests that attacks against RSA and DSA as a result of this + defect would be very difficult to perform and are not believed likely. + Attacks against DH1024 are considered just feasible, because most of the + work necessary to deduce information about a private key may be performed + offline. The amount of resources required for such an attack would be + significant. However, for an attack on TLS to be meaningful, the server + would have to share the DH1024 private key among multiple clients, which is + no longer an option since CVE-2016-0701. + + This only affects processors that support the AVX2 but not ADX extensions + like Intel Haswell (4th generation). + + This issue was reported to OpenSSL by David Benjamin (Google). The issue + was originally found via the OSS-Fuzz project. + ([CVE-2017-3738]) + + *Andy Polyakov* + +### Changes between 1.1.0f and 1.1.0g [2 Nov 2017] + + * bn_sqrx8x_internal carry bug on x86_64 + + There is a carry propagating bug in the x86_64 Montgomery squaring + procedure. No EC algorithms are affected. Analysis suggests that attacks + against RSA and DSA as a result of this defect would be very difficult to + perform and are not believed likely. Attacks against DH are considered just + feasible (although very difficult) because most of the work necessary to + deduce information about a private key may be performed offline. The amount + of resources required for such an attack would be very significant and + likely only accessible to a limited number of attackers. An attacker would + additionally need online access to an unpatched system using the target + private key in a scenario with persistent DH parameters and a private + key that is shared between multiple clients. + + This only affects processors that support the BMI1, BMI2 and ADX extensions + like Intel Broadwell (5th generation) and later or AMD Ryzen. + + This issue was reported to OpenSSL by the OSS-Fuzz project. + ([CVE-2017-3736]) + + *Andy Polyakov* + + * Malformed X.509 IPAddressFamily could cause OOB read + + If an X.509 certificate has a malformed IPAddressFamily extension, + OpenSSL could do a one-byte buffer overread. The most likely result + would be an erroneous display of the certificate in text format. + + This issue was reported to OpenSSL by the OSS-Fuzz project. + ([CVE-2017-3735]) + + *Rich Salz* + +### Changes between 1.1.0e and 1.1.0f [25 May 2017] + + * Have 'config' recognise 64-bit mingw and choose 'mingw64' as the target + platform rather than 'mingw'. + + *Richard Levitte* + + * Remove the VMS-specific reimplementation of gmtime from crypto/o_times.c. + VMS C's RTL has a fully up to date gmtime() and gmtime_r() since V7.1, + which is the minimum version we support. + + *Richard Levitte* + +### Changes between 1.1.0d and 1.1.0e [16 Feb 2017] + + * Encrypt-Then-Mac renegotiation crash + + During a renegotiation handshake if the Encrypt-Then-Mac extension is + negotiated where it was not in the original handshake (or vice-versa) then + this can cause OpenSSL to crash (dependant on ciphersuite). Both clients + and servers are affected. + + This issue was reported to OpenSSL by Joe Orton (Red Hat). + ([CVE-2017-3733]) + + *Matt Caswell* + +### Changes between 1.1.0c and 1.1.0d [26 Jan 2017] + + * Truncated packet could crash via OOB read + + If one side of an SSL/TLS path is running on a 32-bit host and a specific + cipher is being used, then a truncated packet can cause that host to + perform an out-of-bounds read, usually resulting in a crash. + + This issue was reported to OpenSSL by Robert Święcki of Google. + ([CVE-2017-3731]) + + *Andy Polyakov* + + * Bad (EC)DHE parameters cause a client crash + + If a malicious server supplies bad parameters for a DHE or ECDHE key + exchange then this can result in the client attempting to dereference a + NULL pointer leading to a client crash. This could be exploited in a Denial + of Service attack. + + This issue was reported to OpenSSL by Guido Vranken. + ([CVE-2017-3730]) + + *Matt Caswell* + + * BN_mod_exp may produce incorrect results on x86_64 + + There is a carry propagating bug in the x86_64 Montgomery squaring + procedure. No EC algorithms are affected. Analysis suggests that attacks + against RSA and DSA as a result of this defect would be very difficult to + perform and are not believed likely. Attacks against DH are considered just + feasible (although very difficult) because most of the work necessary to + deduce information about a private key may be performed offline. The amount + of resources required for such an attack would be very significant and + likely only accessible to a limited number of attackers. An attacker would + additionally need online access to an unpatched system using the target + private key in a scenario with persistent DH parameters and a private + key that is shared between multiple clients. For example this can occur by + default in OpenSSL DHE based SSL/TLS ciphersuites. Note: This issue is very + similar to CVE-2015-3193 but must be treated as a separate problem. + + This issue was reported to OpenSSL by the OSS-Fuzz project. + ([CVE-2017-3732]) + + *Andy Polyakov* + +### Changes between 1.1.0b and 1.1.0c [10 Nov 2016] + + * ChaCha20/Poly1305 heap-buffer-overflow + + TLS connections using `*-CHACHA20-POLY1305` ciphersuites are susceptible to + a DoS attack by corrupting larger payloads. This can result in an OpenSSL + crash. This issue is not considered to be exploitable beyond a DoS. + + This issue was reported to OpenSSL by Robert Święcki (Google Security Team) + ([CVE-2016-7054]) + + *Richard Levitte* + + * CMS Null dereference + + Applications parsing invalid CMS structures can crash with a NULL pointer + dereference. This is caused by a bug in the handling of the ASN.1 CHOICE + type in OpenSSL 1.1.0 which can result in a NULL value being passed to the + structure callback if an attempt is made to free certain invalid encodings. + Only CHOICE structures using a callback which do not handle NULL value are + affected. + + This issue was reported to OpenSSL by Tyler Nighswander of ForAllSecure. + ([CVE-2016-7053]) + + *Stephen Henson* + + * Montgomery multiplication may produce incorrect results + + There is a carry propagating bug in the Broadwell-specific Montgomery + multiplication procedure that handles input lengths divisible by, but + longer than 256 bits. Analysis suggests that attacks against RSA, DSA + and DH private keys are impossible. This is because the subroutine in + question is not used in operations with the private key itself and an input + of the attacker's direct choice. Otherwise the bug can manifest itself as + transient authentication and key negotiation failures or reproducible + erroneous outcome of public-key operations with specially crafted input. + Among EC algorithms only Brainpool P-512 curves are affected and one + presumably can attack ECDH key negotiation. Impact was not analyzed in + detail, because pre-requisites for attack are considered unlikely. Namely + multiple clients have to choose the curve in question and the server has to + share the private key among them, neither of which is default behaviour. + Even then only clients that chose the curve will be affected. + + This issue was publicly reported as transient failures and was not + initially recognized as a security issue. Thanks to Richard Morgan for + providing reproducible case. + ([CVE-2016-7055]) + + *Andy Polyakov* + + * Removed automatic addition of RPATH in shared libraries and executables, + as this was a remainder from OpenSSL 1.0.x and isn't needed any more. + + *Richard Levitte* + +### Changes between 1.1.0a and 1.1.0b [26 Sep 2016] + + * Fix Use After Free for large message sizes + + The patch applied to address CVE-2016-6307 resulted in an issue where if a + message larger than approx 16k is received then the underlying buffer to + store the incoming message is reallocated and moved. Unfortunately a + dangling pointer to the old location is left which results in an attempt to + write to the previously freed location. This is likely to result in a + crash, however it could potentially lead to execution of arbitrary code. + + This issue only affects OpenSSL 1.1.0a. + + This issue was reported to OpenSSL by Robert Święcki. + ([CVE-2016-6309]) + + *Matt Caswell* + +### Changes between 1.1.0 and 1.1.0a [22 Sep 2016] + + * OCSP Status Request extension unbounded memory growth + + A malicious client can send an excessively large OCSP Status Request + extension. If that client continually requests renegotiation, sending a + large OCSP Status Request extension each time, then there will be unbounded + memory growth on the server. This will eventually lead to a Denial Of + Service attack through memory exhaustion. Servers with a default + configuration are vulnerable even if they do not support OCSP. Builds using + the "no-ocsp" build time option are not affected. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-6304]) + + *Matt Caswell* + + * SSL_peek() hang on empty record + + OpenSSL 1.1.0 SSL/TLS will hang during a call to SSL_peek() if the peer + sends an empty record. This could be exploited by a malicious peer in a + Denial Of Service attack. + + This issue was reported to OpenSSL by Alex Gaynor. + ([CVE-2016-6305]) + + *Matt Caswell* + + * Excessive allocation of memory in tls_get_message_header() and + dtls1_preprocess_fragment() + + A (D)TLS message includes 3 bytes for its length in the header for the + message. This would allow for messages up to 16Mb in length. Messages of + this length are excessive and OpenSSL includes a check to ensure that a + peer is sending reasonably sized messages in order to avoid too much memory + being consumed to service a connection. A flaw in the logic of version + 1.1.0 means that memory for the message is allocated too early, prior to + the excessive message length check. Due to way memory is allocated in + OpenSSL this could mean an attacker could force up to 21Mb to be allocated + to service a connection. This could lead to a Denial of Service through + memory exhaustion. However, the excessive message length check still takes + place, and this would cause the connection to immediately fail. Assuming + that the application calls SSL_free() on the failed connection in a timely + manner then the 21Mb of allocated memory will then be immediately freed + again. Therefore the excessive memory allocation will be transitory in + nature. This then means that there is only a security impact if: + + 1) The application does not call SSL_free() in a timely manner in the event + that the connection fails + or + 2) The application is working in a constrained environment where there is + very little free memory + or + 3) The attacker initiates multiple connection attempts such that there are + multiple connections in a state where memory has been allocated for the + connection; SSL_free() has not yet been called; and there is insufficient + memory to service the multiple requests. + + Except in the instance of (1) above any Denial Of Service is likely to be + transitory because as soon as the connection fails the memory is + subsequently freed again in the SSL_free() call. However there is an + increased risk during this period of application crashes due to the lack of + memory - which would then mean a more serious Denial of Service. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + (CVE-2016-6307 and CVE-2016-6308) + + *Matt Caswell* + + * solaris-x86-cc, i.e. 32-bit configuration with vendor compiler, + had to be removed. Primary reason is that vendor assembler can't + assemble our modules with -KPIC flag. As result it, assembly + support, was not even available as option. But its lack means + lack of side-channel resistant code, which is incompatible with + security by todays standards. Fortunately gcc is readily available + prepackaged option, which we firmly point at... + + *Andy Polyakov* + +### Changes between 1.0.2h and 1.1.0 [25 Aug 2016] + + * Windows command-line tool supports UTF-8 opt-in option for arguments + and console input. Setting OPENSSL_WIN32_UTF8 environment variable + (to any value) allows Windows user to access PKCS#12 file generated + with Windows CryptoAPI and protected with non-ASCII password, as well + as files generated under UTF-8 locale on Linux also protected with + non-ASCII password. + + *Andy Polyakov* + + * To mitigate the SWEET32 attack ([CVE-2016-2183]), 3DES cipher suites + have been disabled by default and removed from DEFAULT, just like RC4. + See the RC4 item below to re-enable both. + + *Rich Salz* + + * The method for finding the storage location for the Windows RAND seed file + has changed. First we check %RANDFILE%. If that is not set then we check + the directories %HOME%, %USERPROFILE% and %SYSTEMROOT% in that order. If + all else fails we fall back to C:\. + + *Matt Caswell* + + * The EVP_EncryptUpdate() function has had its return type changed from void + to int. A return of 0 indicates and error while a return of 1 indicates + success. + + *Matt Caswell* + + * The flags RSA_FLAG_NO_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME and + DH_FLAG_NO_EXP_CONSTTIME which previously provided the ability to switch + off the constant time implementation for RSA, DSA and DH have been made + no-ops and deprecated. + + *Matt Caswell* + + * Windows RAND implementation was simplified to only get entropy by + calling CryptGenRandom(). Various other RAND-related tickets + were also closed. + + *Joseph Wylie Yandle, Rich Salz* + + * The stack and lhash API's were renamed to start with `OPENSSL_SK_` + and `OPENSSL_LH_`, respectively. The old names are available + with API compatibility. They new names are now completely documented. + + *Rich Salz* + + * Unify TYPE_up_ref(obj) methods signature. + SSL_CTX_up_ref(), SSL_up_ref(), X509_up_ref(), EVP_PKEY_up_ref(), + X509_CRL_up_ref(), X509_OBJECT_up_ref_count() methods are now returning an + int (instead of void) like all others TYPE_up_ref() methods. + So now these methods also check the return value of CRYPTO_atomic_add(), + and the validity of object reference counter. + + *fdasilvayy@gmail.com* + + * With Windows Visual Studio builds, the .pdb files are installed + alongside the installed libraries and executables. For a static + library installation, ossl_static.pdb is the associate compiler + generated .pdb file to be used when linking programs. + + *Richard Levitte* + + * Remove openssl.spec. Packaging files belong with the packagers. + + *Richard Levitte* + + * Automatic Darwin/OSX configuration has had a refresh, it will now + recognise x86_64 architectures automatically. You can still decide + to build for a different bitness with the environment variable + KERNEL_BITS (can be 32 or 64), for example: + + KERNEL_BITS=32 ./config + + *Richard Levitte* + + * Change default algorithms in pkcs8 utility to use PKCS#5 v2.0, + 256 bit AES and HMAC with SHA256. + + *Steve Henson* + + * Remove support for MIPS o32 ABI on IRIX (and IRIX only). + + *Andy Polyakov* + + * Triple-DES ciphers have been moved from HIGH to MEDIUM. + + *Rich Salz* + + * To enable users to have their own config files and build file templates, + Configure looks in the directory indicated by the environment variable + OPENSSL_LOCAL_CONFIG_DIR as well as the in-source Configurations/ + directory. On VMS, OPENSSL_LOCAL_CONFIG_DIR is expected to be a logical + name and is used as is. + + *Richard Levitte* + + * The following datatypes were made opaque: X509_OBJECT, X509_STORE_CTX, + X509_STORE, X509_LOOKUP, and X509_LOOKUP_METHOD. The unused type + X509_CERT_FILE_CTX was removed. + + *Rich Salz* + + * "shared" builds are now the default. To create only static libraries use + the "no-shared" Configure option. + + *Matt Caswell* + + * Remove the no-aes, no-hmac, no-rsa, no-sha and no-md5 Configure options. + All of these option have not worked for some while and are fundamental + algorithms. + + *Matt Caswell* + + * Make various cleanup routines no-ops and mark them as deprecated. Most + global cleanup functions are no longer required because they are handled + via auto-deinit (see OPENSSL_init_crypto and OPENSSL_init_ssl man pages). + Explicitly de-initing can cause problems (e.g. where a library that uses + OpenSSL de-inits, but an application is still using it). The affected + functions are CONF_modules_free(), ENGINE_cleanup(), OBJ_cleanup(), + EVP_cleanup(), BIO_sock_cleanup(), CRYPTO_cleanup_all_ex_data(), + RAND_cleanup(), SSL_COMP_free_compression_methods(), ERR_free_strings() and + COMP_zlib_cleanup(). + + *Matt Caswell* + + * --strict-warnings no longer enables runtime debugging options + such as REF_DEBUG. Instead, debug options are automatically + enabled with '--debug' builds. + + *Andy Polyakov, Emilia Käsper* + + * Made DH and DH_METHOD opaque. The structures for managing DH objects + have been moved out of the public header files. New functions for managing + these have been added. + + *Matt Caswell* + + * Made RSA and RSA_METHOD opaque. The structures for managing RSA + objects have been moved out of the public header files. New + functions for managing these have been added. + + *Richard Levitte* + + * Made DSA and DSA_METHOD opaque. The structures for managing DSA objects + have been moved out of the public header files. New functions for managing + these have been added. + + *Matt Caswell* + + * Made BIO and BIO_METHOD opaque. The structures for managing BIOs have been + moved out of the public header files. New functions for managing these + have been added. + + *Matt Caswell* + + * Removed no-rijndael as a config option. Rijndael is an old name for AES. + + *Matt Caswell* + + * Removed the mk1mf build scripts. + + *Richard Levitte* + + * Headers are now wrapped, if necessary, with OPENSSL_NO_xxx, so + it is always safe to #include a header now. + + *Rich Salz* + + * Removed the aged BC-32 config and all its supporting scripts + + *Richard Levitte* + + * Removed support for Ultrix, Netware, and OS/2. + + *Rich Salz* + + * Add support for HKDF. + + *Alessandro Ghedini* + + * Add support for blake2b and blake2s + + *Bill Cox* + + * Added support for "pipelining". Ciphers that have the + EVP_CIPH_FLAG_PIPELINE flag set have a capability to process multiple + encryptions/decryptions simultaneously. There are currently no built-in + ciphers with this property but the expectation is that engines will be able + to offer it to significantly improve throughput. Support has been extended + into libssl so that multiple records for a single connection can be + processed in one go (for >=TLS 1.1). + + *Matt Caswell* + + * Added the AFALG engine. This is an async capable engine which is able to + offload work to the Linux kernel. In this initial version it only supports + AES128-CBC. The kernel must be version 4.1.0 or greater. + + *Catriona Lucey* + + * OpenSSL now uses a new threading API. It is no longer necessary to + set locking callbacks to use OpenSSL in a multi-threaded environment. There + are two supported threading models: pthreads and windows threads. It is + also possible to configure OpenSSL at compile time for "no-threads". The + old threading API should no longer be used. The functions have been + replaced with "no-op" compatibility macros. + + *Alessandro Ghedini, Matt Caswell* + + * Modify behavior of ALPN to invoke callback after SNI/servername + callback, such that updates to the SSL_CTX affect ALPN. + + *Todd Short* + + * Add SSL_CIPHER queries for authentication and key-exchange. + + *Todd Short* + + * Changes to the DEFAULT cipherlist: + - Prefer (EC)DHE handshakes over plain RSA. + - Prefer AEAD ciphers over legacy ciphers. + - Prefer ECDSA over RSA when both certificates are available. + - Prefer TLSv1.2 ciphers/PRF. + - Remove DSS, SEED, IDEA, CAMELLIA, and AES-CCM from the + default cipherlist. + + *Emilia Käsper* + + * Change the ECC default curve list to be this, in order: x25519, + secp256r1, secp521r1, secp384r1. + + *Rich Salz* + + * RC4 based libssl ciphersuites are now classed as "weak" ciphers and are + disabled by default. They can be re-enabled using the + enable-weak-ssl-ciphers option to Configure. + + *Matt Caswell* + + * If the server has ALPN configured, but supports no protocols that the + client advertises, send a fatal "no_application_protocol" alert. + This behaviour is SHALL in RFC 7301, though it isn't universally + implemented by other servers. + + *Emilia Käsper* + + * Add X25519 support. + Add ASN.1 and EVP_PKEY methods for X25519. This includes support + for public and private key encoding using the format documented in + draft-ietf-curdle-pkix-02. The corresponding EVP_PKEY method supports + key generation and key derivation. + + TLS support complies with draft-ietf-tls-rfc4492bis-08 and uses + X25519(29). + + *Steve Henson* + + * Deprecate SRP_VBASE_get_by_user. + SRP_VBASE_get_by_user had inconsistent memory management behaviour. + In order to fix an unavoidable memory leak ([CVE-2016-0798]), + SRP_VBASE_get_by_user was changed to ignore the "fake user" SRP + seed, even if the seed is configured. + + Users should use SRP_VBASE_get1_by_user instead. Note that in + SRP_VBASE_get1_by_user, caller must free the returned value. Note + also that even though configuring the SRP seed attempts to hide + invalid usernames by continuing the handshake with fake + credentials, this behaviour is not constant time and no strong + guarantees are made that the handshake is indistinguishable from + that of a valid user. + + *Emilia Käsper* + + * Configuration change; it's now possible to build dynamic engines + without having to build shared libraries and vice versa. This + only applies to the engines in `engines/`, those in `crypto/engine/` + will always be built into libcrypto (i.e. "static"). + + Building dynamic engines is enabled by default; to disable, use + the configuration option "disable-dynamic-engine". + + The only requirements for building dynamic engines are the + presence of the DSO module and building with position independent + code, so they will also automatically be disabled if configuring + with "disable-dso" or "disable-pic". + + The macros OPENSSL_NO_STATIC_ENGINE and OPENSSL_NO_DYNAMIC_ENGINE + are also taken away from openssl/opensslconf.h, as they are + irrelevant. + + *Richard Levitte* + + * Configuration change; if there is a known flag to compile + position independent code, it will always be applied on the + libcrypto and libssl object files, and never on the application + object files. This means other libraries that use routines from + libcrypto / libssl can be made into shared libraries regardless + of how OpenSSL was configured. + + If this isn't desirable, the configuration options "disable-pic" + or "no-pic" can be used to disable the use of PIC. This will + also disable building shared libraries and dynamic engines. + + *Richard Levitte* + + * Removed JPAKE code. It was experimental and has no wide use. + + *Rich Salz* + + * The INSTALL_PREFIX Makefile variable has been renamed to + DESTDIR. That makes for less confusion on what this variable + is for. Also, the configuration option --install_prefix is + removed. + + *Richard Levitte* + + * Heartbeat for TLS has been removed and is disabled by default + for DTLS; configure with enable-heartbeats. Code that uses the + old #define's might need to be updated. + + *Emilia Käsper, Rich Salz* + + * Rename REF_CHECK to REF_DEBUG. + + *Rich Salz* + + * New "unified" build system + + The "unified" build system is aimed to be a common system for all + platforms we support. With it comes new support for VMS. + + This system builds supports building in a different directory tree + than the source tree. It produces one Makefile (for unix family + or lookalikes), or one descrip.mms (for VMS). + + The source of information to make the Makefile / descrip.mms is + small files called 'build.info', holding the necessary + information for each directory with source to compile, and a + template in Configurations, like unix-Makefile.tmpl or + descrip.mms.tmpl. + + With this change, the library names were also renamed on Windows + and on VMS. They now have names that are closer to the standard + on Unix, and include the major version number, and in certain + cases, the architecture they are built for. See "Notes on shared + libraries" in INSTALL. + + We rely heavily on the perl module Text::Template. + + *Richard Levitte* + + * Added support for auto-initialisation and de-initialisation of the library. + OpenSSL no longer requires explicit init or deinit routines to be called, + except in certain circumstances. See the OPENSSL_init_crypto() and + OPENSSL_init_ssl() man pages for further information. + + *Matt Caswell* + + * The arguments to the DTLSv1_listen function have changed. Specifically the + "peer" argument is now expected to be a BIO_ADDR object. + + * Rewrite of BIO networking library. The BIO library lacked consistent + support of IPv6, and adding it required some more extensive + modifications. This introduces the BIO_ADDR and BIO_ADDRINFO types, + which hold all types of addresses and chains of address information. + It also introduces a new API, with functions like BIO_socket, + BIO_connect, BIO_listen, BIO_lookup and a rewrite of BIO_accept. + The source/sink BIOs BIO_s_connect, BIO_s_accept and BIO_s_datagram + have been adapted accordingly. + + *Richard Levitte* + + * RSA_padding_check_PKCS1_type_1 now accepts inputs with and without + the leading 0-byte. + + *Emilia Käsper* + + * CRIME protection: disable compression by default, even if OpenSSL is + compiled with zlib enabled. Applications can still enable compression + by calling SSL_CTX_clear_options(ctx, SSL_OP_NO_COMPRESSION), or by + using the SSL_CONF library to configure compression. + + *Emilia Käsper* + + * The signature of the session callback configured with + SSL_CTX_sess_set_get_cb was changed. The read-only input buffer + was explicitly marked as `const unsigned char*` instead of + `unsigned char*`. + + *Emilia Käsper* + + * Always DPURIFY. Remove the use of uninitialized memory in the + RNG, and other conditional uses of DPURIFY. This makes -DPURIFY a no-op. + + *Emilia Käsper* + + * Removed many obsolete configuration items, including + DES_PTR, DES_RISC1, DES_RISC2, DES_INT + MD2_CHAR, MD2_INT, MD2_LONG + BF_PTR, BF_PTR2 + IDEA_SHORT, IDEA_LONG + RC2_SHORT, RC2_LONG, RC4_LONG, RC4_CHUNK, RC4_INDEX + + *Rich Salz, with advice from Andy Polyakov* + + * Many BN internals have been moved to an internal header file. + + *Rich Salz with help from Andy Polyakov* + + * Configuration and writing out the results from it has changed. + Files such as Makefile include/openssl/opensslconf.h and are now + produced through general templates, such as Makefile.in and + crypto/opensslconf.h.in and some help from the perl module + Text::Template. + + Also, the center of configuration information is no longer + Makefile. Instead, Configure produces a perl module in + configdata.pm which holds most of the config data (in the hash + table %config), the target data that comes from the target + configuration in one of the `Configurations/*.conf` files (in + %target). + + *Richard Levitte* + + * To clarify their intended purposes, the Configure options + --prefix and --openssldir change their semantics, and become more + straightforward and less interdependent. + + --prefix shall be used exclusively to give the location INSTALLTOP + where programs, scripts, libraries, include files and manuals are + going to be installed. The default is now /usr/local. + + --openssldir shall be used exclusively to give the default + location OPENSSLDIR where certificates, private keys, CRLs are + managed. This is also where the default openssl.cnf gets + installed. + If the directory given with this option is a relative path, the + values of both the --prefix value and the --openssldir value will + be combined to become OPENSSLDIR. + The default for --openssldir is INSTALLTOP/ssl. + + Anyone who uses --openssldir to specify where OpenSSL is to be + installed MUST change to use --prefix instead. + + *Richard Levitte* + + * The GOST engine was out of date and therefore it has been removed. An up + to date GOST engine is now being maintained in an external repository. + See: . Libssl still retains + support for GOST ciphersuites (these are only activated if a GOST engine + is present). + + *Matt Caswell* + + * EGD is no longer supported by default; use enable-egd when + configuring. + + *Ben Kaduk and Rich Salz* + + * The distribution now has Makefile.in files, which are used to + create Makefile's when Configure is run. *Configure must be run + before trying to build now.* + + *Rich Salz* + + * The return value for SSL_CIPHER_description() for error conditions + has changed. + + *Rich Salz* + + * Support for RFC6698/RFC7671 DANE TLSA peer authentication. + + Obtaining and performing DNSSEC validation of TLSA records is + the application's responsibility. The application provides + the TLSA records of its choice to OpenSSL, and these are then + used to authenticate the peer. + + The TLSA records need not even come from DNS. They can, for + example, be used to implement local end-entity certificate or + trust-anchor "pinning", where the "pin" data takes the form + of TLSA records, which can augment or replace verification + based on the usual WebPKI public certification authorities. + + *Viktor Dukhovni* + + * Revert default OPENSSL_NO_DEPRECATED setting. Instead OpenSSL + continues to support deprecated interfaces in default builds. + However, applications are strongly advised to compile their + source files with -DOPENSSL_API_COMPAT=0x10100000L, which hides + the declarations of all interfaces deprecated in 0.9.8, 1.0.0 + or the 1.1.0 releases. + + In environments in which all applications have been ported to + not use any deprecated interfaces OpenSSL's Configure script + should be used with the --api=1.1.0 option to entirely remove + support for the deprecated features from the library and + unconditionally disable them in the installed headers. + Essentially the same effect can be achieved with the "no-deprecated" + argument to Configure, except that this will always restrict + the build to just the latest API, rather than a fixed API + version. + + As applications are ported to future revisions of the API, + they should update their compile-time OPENSSL_API_COMPAT define + accordingly, but in most cases should be able to continue to + compile with later releases. + + The OPENSSL_API_COMPAT versions for 1.0.0, and 0.9.8 are + 0x10000000L and 0x00908000L, respectively. However those + versions did not support the OPENSSL_API_COMPAT feature, and + so applications are not typically tested for explicit support + of just the undeprecated features of either release. + + *Viktor Dukhovni* + + * Add support for setting the minimum and maximum supported protocol. + It can bet set via the SSL_set_min_proto_version() and + SSL_set_max_proto_version(), or via the SSL_CONF's MinProtocol and + MaxProtocol. It's recommended to use the new APIs to disable + protocols instead of disabling individual protocols using + SSL_set_options() or SSL_CONF's Protocol. This change also + removes support for disabling TLS 1.2 in the OpenSSL TLS + client at compile time by defining OPENSSL_NO_TLS1_2_CLIENT. + + *Kurt Roeckx* + + * Support for ChaCha20 and Poly1305 added to libcrypto and libssl. + + *Andy Polyakov* + + * New EC_KEY_METHOD, this replaces the older ECDSA_METHOD and ECDH_METHOD + and integrates ECDSA and ECDH functionality into EC. Implementations can + now redirect key generation and no longer need to convert to or from + ECDSA_SIG format. + + Note: the ecdsa.h and ecdh.h headers are now no longer needed and just + include the ec.h header file instead. + + *Steve Henson* + + * Remove support for all 40 and 56 bit ciphers. This includes all the export + ciphers who are no longer supported and drops support the ephemeral RSA key + exchange. The LOW ciphers currently doesn't have any ciphers in it. + + *Kurt Roeckx* + + * Made EVP_MD_CTX, EVP_MD, EVP_CIPHER_CTX, EVP_CIPHER and HMAC_CTX + opaque. For HMAC_CTX, the following constructors and destructors + were added: + + HMAC_CTX *HMAC_CTX_new(void); + void HMAC_CTX_free(HMAC_CTX *ctx); + + For EVP_MD and EVP_CIPHER, complete APIs to create, fill and + destroy such methods has been added. See EVP_MD_meth_new(3) and + EVP_CIPHER_meth_new(3) for documentation. + + Additional changes: + 1) `EVP_MD_CTX_cleanup()`, `EVP_CIPHER_CTX_cleanup()` and + `HMAC_CTX_cleanup()` were removed. `HMAC_CTX_reset()` and + `EVP_MD_CTX_reset()` should be called instead to reinitialise + an already created structure. + 2) For consistency with the majority of our object creators and + destructors, `EVP_MD_CTX_(create|destroy)` were renamed to + `EVP_MD_CTX_(new|free)`. The old names are retained as macros + for deprecated builds. + + *Richard Levitte* + + * Added ASYNC support. Libcrypto now includes the async sub-library to enable + cryptographic operations to be performed asynchronously as long as an + asynchronous capable engine is used. See the ASYNC_start_job() man page for + further details. Libssl has also had this capability integrated with the + introduction of the new mode SSL_MODE_ASYNC and associated error + SSL_ERROR_WANT_ASYNC. See the SSL_CTX_set_mode() and SSL_get_error() man + pages. This work was developed in partnership with Intel Corp. + + *Matt Caswell* + + * SSL_{CTX_}set_ecdh_auto() has been removed and ECDH is support is + always enabled now. If you want to disable the support you should + exclude it using the list of supported ciphers. This also means that the + "-no_ecdhe" option has been removed from s_server. + + *Kurt Roeckx* + + * SSL_{CTX}_set_tmp_ecdh() which can set 1 EC curve now internally calls + SSL_{CTX_}set1_curves() which can set a list. + + *Kurt Roeckx* + + * Remove support for SSL_{CTX_}set_tmp_ecdh_callback(). You should set the + curve you want to support using SSL_{CTX_}set1_curves(). + + *Kurt Roeckx* + + * State machine rewrite. The state machine code has been significantly + refactored in order to remove much duplication of code and solve issues + with the old code (see [ssl/statem/README.md](ssl/statem/README.md) for + further details). This change does have some associated API changes. + Notably the SSL_state() function has been removed and replaced by + SSL_get_state which now returns an "OSSL_HANDSHAKE_STATE" instead of an int. + SSL_set_state() has been removed altogether. The previous handshake states + defined in ssl.h and ssl3.h have also been removed. + + *Matt Caswell* + + * All instances of the string "ssleay" in the public API were replaced + with OpenSSL (case-matching; e.g., OPENSSL_VERSION for #define's) + Some error codes related to internal RSA_eay API's were renamed. + + *Rich Salz* + + * The demo files in crypto/threads were moved to demo/threads. + + *Rich Salz* + + * Removed obsolete engines: 4758cca, aep, atalla, cswift, nuron, gmp, + sureware and ubsec. + + *Matt Caswell, Rich Salz* + + * New ASN.1 embed macro. + + New ASN.1 macro ASN1_EMBED. This is the same as ASN1_SIMPLE except the + structure is not allocated: it is part of the parent. That is instead of + + FOO *x; + + it must be: + + FOO x; + + This reduces memory fragmentation and make it impossible to accidentally + set a mandatory field to NULL. + + This currently only works for some fields specifically a SEQUENCE, CHOICE, + or ASN1_STRING type which is part of a parent SEQUENCE. Since it is + equivalent to ASN1_SIMPLE it cannot be tagged, OPTIONAL, SET OF or + SEQUENCE OF. + + *Steve Henson* + + * Remove EVP_CHECK_DES_KEY, a compile-time option that never compiled. + + *Emilia Käsper* + + * Removed DES and RC4 ciphersuites from DEFAULT. Also removed RC2 although + in 1.0.2 EXPORT was already removed and the only RC2 ciphersuite is also + an EXPORT one. COMPLEMENTOFDEFAULT has been updated accordingly to add + DES and RC4 ciphersuites. + + *Matt Caswell* + + * Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs. + This changes the decoding behaviour for some invalid messages, + though the change is mostly in the more lenient direction, and + legacy behaviour is preserved as much as possible. + + *Emilia Käsper* + + * Fix no-stdio build. + *David Woodhouse and also* + *Ivan Nestlerode * + + * New testing framework + The testing framework has been largely rewritten and is now using + perl and the perl modules Test::Harness and an extended variant of + Test::More called OpenSSL::Test to do its work. All test scripts in + test/ have been rewritten into test recipes, and all direct calls to + executables in test/Makefile have become individual recipes using the + simplified testing OpenSSL::Test::Simple. + + For documentation on our testing modules, do: + + perldoc test/testlib/OpenSSL/Test/Simple.pm + perldoc test/testlib/OpenSSL/Test.pm + + *Richard Levitte* + + * Revamped memory debug; only -DCRYPTO_MDEBUG and -DCRYPTO_MDEBUG_ABORT + are used; the latter aborts on memory leaks (usually checked on exit). + Some undocumented "set malloc, etc., hooks" functions were removed + and others were changed. All are now documented. + + *Rich Salz* + + * In DSA_generate_parameters_ex, if the provided seed is too short, + return an error + + *Rich Salz and Ismo Puustinen * + + * Rewrite PSK to support ECDHE_PSK, DHE_PSK and RSA_PSK. Add ciphersuites + from RFC4279, RFC4785, RFC5487, RFC5489. + + Thanks to Christian J. Dietrich and Giuseppe D'Angelo for the + original RSA_PSK patch. + + *Steve Henson* + + * Dropped support for the SSL3_FLAGS_DELAY_CLIENT_FINISHED flag. This SSLeay + era flag was never set throughout the codebase (only read). Also removed + SSL3_FLAGS_POP_BUFFER which was only used if + SSL3_FLAGS_DELAY_CLIENT_FINISHED was also set. + + *Matt Caswell* + + * Changed the default name options in the "ca", "crl", "req" and "x509" + to be "oneline" instead of "compat". + + *Richard Levitte* + + * Remove SSL_OP_TLS_BLOCK_PADDING_BUG. This is SSLeay legacy, we're + not aware of clients that still exhibit this bug, and the workaround + hasn't been working properly for a while. + + *Emilia Käsper* + + * The return type of BIO_number_read() and BIO_number_written() as well as + the corresponding num_read and num_write members in the BIO structure has + changed from unsigned long to uint64_t. On platforms where an unsigned + long is 32 bits (e.g. Windows) these counters could overflow if >4Gb is + transferred. + + *Matt Caswell* + + * Given the pervasive nature of TLS extensions it is inadvisable to run + OpenSSL without support for them. It also means that maintaining + the OPENSSL_NO_TLSEXT option within the code is very invasive (and probably + not well tested). Therefore the OPENSSL_NO_TLSEXT option has been removed. + + *Matt Caswell* + + * Removed support for the two export grade static DH ciphersuites + EXP-DH-RSA-DES-CBC-SHA and EXP-DH-DSS-DES-CBC-SHA. These two ciphersuites + were newly added (along with a number of other static DH ciphersuites) to + 1.0.2. However the two export ones have *never* worked since they were + introduced. It seems strange in any case to be adding new export + ciphersuites, and given "logjam" it also does not seem correct to fix them. + + *Matt Caswell* + + * Version negotiation has been rewritten. In particular SSLv23_method(), + SSLv23_client_method() and SSLv23_server_method() have been deprecated, + and turned into macros which simply call the new preferred function names + TLS_method(), TLS_client_method() and TLS_server_method(). All new code + should use the new names instead. Also as part of this change the ssl23.h + header file has been removed. + + *Matt Caswell* + + * Support for Kerberos ciphersuites in TLS (RFC2712) has been removed. This + code and the associated standard is no longer considered fit-for-purpose. + + *Matt Caswell* + + * RT2547 was closed. When generating a private key, try to make the + output file readable only by the owner. This behavior change might + be noticeable when interacting with other software. + + * Documented all exdata functions. Added CRYPTO_free_ex_index. + Added a test. + + *Rich Salz* + + * Added HTTP GET support to the ocsp command. + + *Rich Salz* + + * Changed default digest for the dgst and enc commands from MD5 to + sha256 + + *Rich Salz* + + * RAND_pseudo_bytes has been deprecated. Users should use RAND_bytes instead. + + *Matt Caswell* + + * Added support for TLS extended master secret from + draft-ietf-tls-session-hash-03.txt. Thanks for Alfredo Pironti for an + initial patch which was a great help during development. + + *Steve Henson* + + * All libssl internal structures have been removed from the public header + files, and the OPENSSL_NO_SSL_INTERN option has been removed (since it is + now redundant). Users should not attempt to access internal structures + directly. Instead they should use the provided API functions. + + *Matt Caswell* + + * config has been changed so that by default OPENSSL_NO_DEPRECATED is used. + Access to deprecated functions can be re-enabled by running config with + "enable-deprecated". In addition applications wishing to use deprecated + functions must define OPENSSL_USE_DEPRECATED. Note that this new behaviour + will, by default, disable some transitive includes that previously existed + in the header files (e.g. ec.h will no longer, by default, include bn.h) + + *Matt Caswell* + + * Added support for OCB mode. OpenSSL has been granted a patent license + compatible with the OpenSSL license for use of OCB. Details are available + at . Support + for OCB can be removed by calling config with no-ocb. + + *Matt Caswell* + + * SSLv2 support has been removed. It still supports receiving a SSLv2 + compatible client hello. + + *Kurt Roeckx* + + * Increased the minimal RSA keysize from 256 to 512 bits [Rich Salz], + done while fixing the error code for the key-too-small case. + + *Annie Yousar * + + * CA.sh has been removed; use CA.pl instead. + + *Rich Salz* + + * Removed old DES API. + + *Rich Salz* + + * Remove various unsupported platforms: + Sony NEWS4 + BEOS and BEOS_R5 + NeXT + SUNOS + MPE/iX + Sinix/ReliantUNIX RM400 + DGUX + NCR + Tandem + Cray + 16-bit platforms such as WIN16 + + *Rich Salz* + + * Clean up OPENSSL_NO_xxx #define's + - Use setbuf() and remove OPENSSL_NO_SETVBUF_IONBF + - Rename OPENSSL_SYSNAME_xxx to OPENSSL_SYS_xxx + - OPENSSL_NO_EC{DH,DSA} merged into OPENSSL_NO_EC + - OPENSSL_NO_RIPEMD160, OPENSSL_NO_RIPEMD merged into OPENSSL_NO_RMD160 + - OPENSSL_NO_FP_API merged into OPENSSL_NO_STDIO + - Remove OPENSSL_NO_BIO OPENSSL_NO_BUFFER OPENSSL_NO_CHAIN_VERIFY + OPENSSL_NO_EVP OPENSSL_NO_FIPS_ERR OPENSSL_NO_HASH_COMP + OPENSSL_NO_LHASH OPENSSL_NO_OBJECT OPENSSL_NO_SPEED OPENSSL_NO_STACK + OPENSSL_NO_X509 OPENSSL_NO_X509_VERIFY + - Remove MS_STATIC; it's a relic from platforms <32 bits. + + *Rich Salz* + + * Cleaned up dead code + Remove all but one '#ifdef undef' which is to be looked at. + + *Rich Salz* + + * Clean up calling of xxx_free routines. + Just like free(), fix most of the xxx_free routines to accept + NULL. Remove the non-null checks from callers. Save much code. + + *Rich Salz* + + * Add secure heap for storage of private keys (when possible). + Add BIO_s_secmem(), CBIGNUM, etc. + Contributed by Akamai Technologies under our Corporate CLA. + + *Rich Salz* + + * Experimental support for a new, fast, unbiased prime candidate generator, + bn_probable_prime_dh_coprime(). Not currently used by any prime generator. + + *Felix Laurie von Massenbach * + + * New output format NSS in the sess_id command line tool. This allows + exporting the session id and the master key in NSS keylog format. + + *Martin Kaiser * + + * Harmonize version and its documentation. -f flag is used to display + compilation flags. + + *mancha * + + * Fix eckey_priv_encode so it immediately returns an error upon a failure + in i2d_ECPrivateKey. Thanks to Ted Unangst for feedback on this issue. + + *mancha * + + * Fix some double frees. These are not thought to be exploitable. + + *mancha * + + * A missing bounds check in the handling of the TLS heartbeat extension + can be used to reveal up to 64k of memory to a connected client or + server. + + Thanks for Neel Mehta of Google Security for discovering this bug and to + Adam Langley and Bodo Moeller for + preparing the fix ([CVE-2014-0160]) + + *Adam Langley, Bodo Moeller* + + * Fix for the attack described in the paper "Recovering OpenSSL + ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack" + by Yuval Yarom and Naomi Benger. Details can be obtained from: + + + Thanks to Yuval Yarom and Naomi Benger for discovering this + flaw and to Yuval Yarom for supplying a fix ([CVE-2014-0076]) + + *Yuval Yarom and Naomi Benger* + + * Use algorithm specific chains in SSL_CTX_use_certificate_chain_file(): + this fixes a limitation in previous versions of OpenSSL. + + *Steve Henson* + + * Experimental encrypt-then-mac support. + + Experimental support for encrypt then mac from + draft-gutmann-tls-encrypt-then-mac-02.txt + + To enable it set the appropriate extension number (0x42 for the test + server) using e.g. -DTLSEXT_TYPE_encrypt_then_mac=0x42 + + For non-compliant peers (i.e. just about everything) this should have no + effect. + + WARNING: EXPERIMENTAL, SUBJECT TO CHANGE. + + *Steve Henson* + + * Add EVP support for key wrapping algorithms, to avoid problems with + existing code the flag EVP_CIPHER_CTX_WRAP_ALLOW has to be set in + the EVP_CIPHER_CTX or an error is returned. Add AES and DES3 wrap + algorithms and include tests cases. + + *Steve Henson* + + * Extend CMS code to support RSA-PSS signatures and RSA-OAEP for + enveloped data. + + *Steve Henson* + + * Extended RSA OAEP support via EVP_PKEY API. Options to specify digest, + MGF1 digest and OAEP label. + + *Steve Henson* + + * Make openssl verify return errors. + + *Chris Palmer and Ben Laurie* + + * New function ASN1_TIME_diff to calculate the difference between two + ASN1_TIME structures or one structure and the current time. + + *Steve Henson* + + * Update fips_test_suite to support multiple command line options. New + test to induce all self test errors in sequence and check expected + failures. + + *Steve Henson* + + * Add FIPS_{rsa,dsa,ecdsa}_{sign,verify} functions which digest and + sign or verify all in one operation. + + *Steve Henson* + + * Add fips_algvs: a multicall fips utility incorporating all the algorithm + test programs and fips_test_suite. Includes functionality to parse + the minimal script output of fipsalgest.pl directly. + + *Steve Henson* + + * Add authorisation parameter to FIPS_module_mode_set(). + + *Steve Henson* + + * Add FIPS selftest for ECDH algorithm using P-224 and B-233 curves. + + *Steve Henson* + + * Use separate DRBG fields for internal and external flags. New function + FIPS_drbg_health_check() to perform on demand health checking. Add + generation tests to fips_test_suite with reduced health check interval to + demonstrate periodic health checking. Add "nodh" option to + fips_test_suite to skip very slow DH test. + + *Steve Henson* + + * New function FIPS_get_cipherbynid() to lookup FIPS supported ciphers + based on NID. + + *Steve Henson* + + * More extensive health check for DRBG checking many more failure modes. + New function FIPS_selftest_drbg_all() to handle every possible DRBG + combination: call this in fips_test_suite. + + *Steve Henson* + + * Add support for canonical generation of DSA parameter 'g'. See + FIPS 186-3 A.2.3. + + * Add support for HMAC DRBG from SP800-90. Update DRBG algorithm test and + POST to handle HMAC cases. + + *Steve Henson* + + * Add functions FIPS_module_version() and FIPS_module_version_text() + to return numerical and string versions of the FIPS module number. + + *Steve Henson* + + * Rename FIPS_mode_set and FIPS_mode to FIPS_module_mode_set and + FIPS_module_mode. FIPS_mode and FIPS_mode_set will be implemented + outside the validated module in the FIPS capable OpenSSL. + + *Steve Henson* + + * Minor change to DRBG entropy callback semantics. In some cases + there is no multiple of the block length between min_len and + max_len. Allow the callback to return more than max_len bytes + of entropy but discard any extra: it is the callback's responsibility + to ensure that the extra data discarded does not impact the + requested amount of entropy. + + *Steve Henson* + + * Add PRNG security strength checks to RSA, DSA and ECDSA using + information in FIPS186-3, SP800-57 and SP800-131A. + + *Steve Henson* + + * CCM support via EVP. Interface is very similar to GCM case except we + must supply all data in one chunk (i.e. no update, final) and the + message length must be supplied if AAD is used. Add algorithm test + support. + + *Steve Henson* + + * Initial version of POST overhaul. Add POST callback to allow the status + of POST to be monitored and/or failures induced. Modify fips_test_suite + to use callback. Always run all selftests even if one fails. + + *Steve Henson* + + * XTS support including algorithm test driver in the fips_gcmtest program. + Note: this does increase the maximum key length from 32 to 64 bytes but + there should be no binary compatibility issues as existing applications + will never use XTS mode. + + *Steve Henson* + + * Extensive reorganisation of FIPS PRNG behaviour. Remove all dependencies + to OpenSSL RAND code and replace with a tiny FIPS RAND API which also + performs algorithm blocking for unapproved PRNG types. Also do not + set PRNG type in FIPS_mode_set(): leave this to the application. + Add default OpenSSL DRBG handling: sets up FIPS PRNG and seeds with + the standard OpenSSL PRNG: set additional data to a date time vector. + + *Steve Henson* + + * Rename old X9.31 PRNG functions of the form `FIPS_rand*` to `FIPS_x931*`. + This shouldn't present any incompatibility problems because applications + shouldn't be using these directly and any that are will need to rethink + anyway as the X9.31 PRNG is now deprecated by FIPS 140-2 + + *Steve Henson* + + * Extensive self tests and health checking required by SP800-90 DRBG. + Remove strength parameter from FIPS_drbg_instantiate and always + instantiate at maximum supported strength. + + *Steve Henson* + + * Add ECDH code to fips module and fips_ecdhvs for primitives only testing. + + *Steve Henson* + + * New algorithm test program fips_dhvs to handle DH primitives only testing. + + *Steve Henson* + + * New function DH_compute_key_padded() to compute a DH key and pad with + leading zeroes if needed: this complies with SP800-56A et al. + + *Steve Henson* + + * Initial implementation of SP800-90 DRBGs for Hash and CTR. Not used by + anything, incomplete, subject to change and largely untested at present. + + *Steve Henson* + + * Modify fipscanisteronly build option to only build the necessary object + files by filtering FIPS_EX_OBJ through a perl script in crypto/Makefile. + + *Steve Henson* + + * Add experimental option FIPSSYMS to give all symbols in + fipscanister.o and FIPS or fips prefix. This will avoid + conflicts with future versions of OpenSSL. Add perl script + util/fipsas.pl to preprocess assembly language source files + and rename any affected symbols. + + *Steve Henson* + + * Add selftest checks and algorithm block of non-fips algorithms in + FIPS mode. Remove DES2 from selftests. + + *Steve Henson* + + * Add ECDSA code to fips module. Add tiny fips_ecdsa_check to just + return internal method without any ENGINE dependencies. Add new + tiny fips sign and verify functions. + + *Steve Henson* + + * New build option no-ec2m to disable characteristic 2 code. + + *Steve Henson* + + * New build option "fipscanisteronly". This only builds fipscanister.o + and (currently) associated fips utilities. Uses the file Makefile.fips + instead of Makefile.org as the prototype. + + *Steve Henson* + + * Add some FIPS mode restrictions to GCM. Add internal IV generator. + Update fips_gcmtest to use IV generator. + + *Steve Henson* + + * Initial, experimental EVP support for AES-GCM. AAD can be input by + setting output buffer to NULL. The `*Final` function must be + called although it will not retrieve any additional data. The tag + can be set or retrieved with a ctrl. The IV length is by default 12 + bytes (96 bits) but can be set to an alternative value. If the IV + length exceeds the maximum IV length (currently 16 bytes) it cannot be + set before the key. + + *Steve Henson* + + * New flag in ciphers: EVP_CIPH_FLAG_CUSTOM_CIPHER. This means the + underlying do_cipher function handles all cipher semantics itself + including padding and finalisation. This is useful if (for example) + an ENGINE cipher handles block padding itself. The behaviour of + do_cipher is subtly changed if this flag is set: the return value + is the number of characters written to the output buffer (zero is + no longer an error code) or a negative error code. Also if the + input buffer is NULL and length 0 finalisation should be performed. + + *Steve Henson* + + * If a candidate issuer certificate is already part of the constructed + path ignore it: new debug notification X509_V_ERR_PATH_LOOP for this case. + + *Steve Henson* + + * Improve forward-security support: add functions + + void SSL_CTX_set_not_resumable_session_callback( + SSL_CTX *ctx, int (*cb)(SSL *ssl, int is_forward_secure)) + void SSL_set_not_resumable_session_callback( + SSL *ssl, int (*cb)(SSL *ssl, int is_forward_secure)) + + for use by SSL/TLS servers; the callback function will be called whenever a + new session is created, and gets to decide whether the session may be + cached to make it resumable (return 0) or not (return 1). (As by the + SSL/TLS protocol specifications, the session_id sent by the server will be + empty to indicate that the session is not resumable; also, the server will + not generate RFC 4507 (RFC 5077) session tickets.) + + A simple reasonable callback implementation is to return is_forward_secure. + This parameter will be set to 1 or 0 depending on the ciphersuite selected + by the SSL/TLS server library, indicating whether it can provide forward + security. + + *Emilia Käsper (Google)* + + * New -verify_name option in command line utilities to set verification + parameters by name. + + *Steve Henson* + + * Initial CMAC implementation. WARNING: EXPERIMENTAL, API MAY CHANGE. + Add CMAC pkey methods. + + *Steve Henson* + + * Experimental renegotiation in s_server -www mode. If the client + browses /reneg connection is renegotiated. If /renegcert it is + renegotiated requesting a certificate. + + *Steve Henson* + + * Add an "external" session cache for debugging purposes to s_server. This + should help trace issues which normally are only apparent in deployed + multi-process servers. + + *Steve Henson* + + * Extensive audit of libcrypto with DEBUG_UNUSED. Fix many cases where + return value is ignored. NB. The functions RAND_add(), RAND_seed(), + BIO_set_cipher() and some obscure PEM functions were changed so they + can now return an error. The RAND changes required a change to the + RAND_METHOD structure. + + *Steve Henson* + + * New macro `__owur` for "OpenSSL Warn Unused Result". This makes use of + a gcc attribute to warn if the result of a function is ignored. This + is enable if DEBUG_UNUSED is set. Add to several functions in evp.h + whose return value is often ignored. + + *Steve Henson* + + * New -noct, -requestct, -requirect and -ctlogfile options for s_client. + These allow SCTs (signed certificate timestamps) to be requested and + validated when establishing a connection. + + *Rob Percival * + +OpenSSL 1.0.2 +------------- + +### Changes between 1.0.2s and 1.0.2t [10 Sep 2019] + + * For built-in EC curves, ensure an EC_GROUP built from the curve name is + used even when parsing explicit parameters, when loading a encoded 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 + encoded, 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* + + * Document issue with installation paths in diverse Windows builds + + '/usr/local/ssl' is an unsafe prefix for location to install OpenSSL + binaries and run-time config file. + ([CVE-2019-1552]) + + *Richard Levitte* + +### Changes between 1.0.2r and 1.0.2s [28 May 2019] + + * Change the default RSA, DSA and DH size to 2048 bit instead of 1024. + This changes the size when using the `genpkey` command when no size is given. + It fixes an omission in earlier changes that changed all RSA, DSA and DH + generation commands to use 2048 bits by default. + + *Kurt Roeckx* + + * Add FIPS support for Android Arm 64-bit + + Support for Android Arm 64-bit was added to the OpenSSL FIPS Object + Module in Version 2.0.10. For some reason, the corresponding target + 'android64-aarch64' was missing OpenSSL 1.0.2, whence it could not be + built with FIPS support on Android Arm 64-bit. This omission has been + fixed. + + *Matthias St. Pierre* + +### Changes between 1.0.2q and 1.0.2r [26 Feb 2019] + + * 0-byte record padding oracle + + If an application encounters a fatal protocol error and then calls + SSL_shutdown() twice (once to send a close_notify, and once to receive one) + then OpenSSL can respond differently to the calling application if a 0 byte + record is received with invalid padding compared to if a 0 byte record is + received with an invalid MAC. If the application then behaves differently + based on that in a way that is detectable to the remote peer, then this + amounts to a padding oracle that could be used to decrypt data. + + In order for this to be exploitable "non-stitched" ciphersuites must be in + use. Stitched ciphersuites are optimised implementations of certain + commonly used ciphersuites. Also the application must call SSL_shutdown() + twice even if a protocol error has occurred (applications should not do + this but some do anyway). + + This issue was discovered by Juraj Somorovsky, Robert Merget and Nimrod + Aviram, with additional investigation by Steven Collison and Andrew + Hourselt. It was reported to OpenSSL on 10th December 2018. + ([CVE-2019-1559]) + + *Matt Caswell* + + * Move strictness check from EVP_PKEY_asn1_new() to EVP_PKEY_asn1_add0(). + + *Richard Levitte* + +### Changes between 1.0.2p and 1.0.2q [20 Nov 2018] + + * Microarchitecture timing vulnerability in ECC scalar multiplication + + OpenSSL ECC scalar multiplication, used in e.g. ECDSA and ECDH, has been + shown to be vulnerable to a microarchitecture timing side channel attack. + An attacker with sufficient access to mount local timing attacks during + ECDSA signature generation could recover the private key. + + This issue was reported to OpenSSL on 26th October 2018 by Alejandro + Cabrera Aldaya, Billy Brumley, Sohaib ul Hassan, Cesar Pereida Garcia and + Nicola Tuveri. + ([CVE-2018-5407]) + + *Billy Brumley* + + * Timing vulnerability in DSA signature generation + + The OpenSSL DSA signature algorithm has been shown to be vulnerable to a + timing side channel attack. An attacker could use variations in the signing + algorithm to recover the private key. + + This issue was reported to OpenSSL on 16th October 2018 by Samuel Weiser. + ([CVE-2018-0734]) + + *Paul Dale* + + * Resolve a compatibility issue in EC_GROUP handling with the FIPS Object + Module, accidentally introduced while backporting security fixes from the + development branch and hindering the use of ECC in FIPS mode. + + *Nicola Tuveri* + +### Changes between 1.0.2o and 1.0.2p [14 Aug 2018] + + * Client DoS due to large DH parameter + + During key agreement in a TLS handshake using a DH(E) based ciphersuite a + malicious server can send a very large prime value to the client. This will + cause the client to spend an unreasonably long period of time generating a + key for this prime resulting in a hang until the client has finished. This + could be exploited in a Denial Of Service attack. + + This issue was reported to OpenSSL on 5th June 2018 by Guido Vranken + ([CVE-2018-0732]) + + *Guido Vranken* + + * Cache timing vulnerability in RSA Key Generation + + The OpenSSL RSA Key generation algorithm has been shown to be vulnerable to + a cache timing side channel attack. An attacker with sufficient access to + mount cache timing attacks during the RSA key generation process could + recover the private key. + + This issue was reported to OpenSSL on 4th April 2018 by Alejandro Cabrera + Aldaya, Billy Brumley, Cesar Pereida Garcia and Luis Manuel Alvarez Tapia. + ([CVE-2018-0737]) + + *Billy Brumley* + + * Make EVP_PKEY_asn1_new() a bit stricter about its input. A NULL pem_str + parameter is no longer accepted, as it leads to a corrupt table. NULL + pem_str is reserved for alias entries only. + + *Richard Levitte* + + * Revert blinding in ECDSA sign and instead make problematic addition + length-invariant. Switch even to fixed-length Montgomery multiplication. + + *Andy Polyakov* + + * Change generating and checking of primes so that the error rate of not + being prime depends on the intended use based on the size of the input. + For larger primes this will result in more rounds of Miller-Rabin. + The maximal error rate for primes with more than 1080 bits is lowered + to 2^-128. + + *Kurt Roeckx, Annie Yousar* + + * Increase the number of Miller-Rabin rounds for DSA key generating to 64. + + *Kurt Roeckx* + + * Add blinding to ECDSA and DSA signatures to protect against side channel + attacks discovered by Keegan Ryan (NCC Group). + + *Matt Caswell* + + * When unlocking a pass phrase protected PEM file or PKCS#8 container, we + now allow empty (zero character) pass phrases. + + *Richard Levitte* + + * Certificate time validation (X509_cmp_time) enforces stricter + compliance with RFC 5280. Fractional seconds and timezone offsets + are no longer allowed. + + *Emilia Käsper* + +### Changes between 1.0.2n and 1.0.2o [27 Mar 2018] + + * Constructed ASN.1 types with a recursive definition could exceed the stack + + Constructed ASN.1 types with a recursive definition (such as can be found + in PKCS7) could eventually exceed the stack given malicious input with + excessive recursion. This could result in a Denial Of Service attack. There + are no such structures used within SSL/TLS that come from untrusted sources + so this is considered safe. + + This issue was reported to OpenSSL on 4th January 2018 by the OSS-fuzz + project. + ([CVE-2018-0739]) + + *Matt Caswell* + +### Changes between 1.0.2m and 1.0.2n [7 Dec 2017] + + * Read/write after SSL object in error state + + OpenSSL 1.0.2 (starting from version 1.0.2b) introduced an "error state" + mechanism. The intent was that if a fatal error occurred during a handshake + then OpenSSL would move into the error state and would immediately fail if + you attempted to continue the handshake. This works as designed for the + explicit handshake functions (SSL_do_handshake(), SSL_accept() and + SSL_connect()), however due to a bug it does not work correctly if + SSL_read() or SSL_write() is called directly. In that scenario, if the + handshake fails then a fatal error will be returned in the initial function + call. If SSL_read()/SSL_write() is subsequently called by the application + for the same SSL object then it will succeed and the data is passed without + being decrypted/encrypted directly from the SSL/TLS record layer. + + In order to exploit this issue an application bug would have to be present + that resulted in a call to SSL_read()/SSL_write() being issued after having + already received a fatal error. + + This issue was reported to OpenSSL by David Benjamin (Google). + ([CVE-2017-3737]) + + *Matt Caswell* + + * rsaz_1024_mul_avx2 overflow bug on x86_64 + + There is an overflow bug in the AVX2 Montgomery multiplication procedure + used in exponentiation with 1024-bit moduli. No EC algorithms are affected. + Analysis suggests that attacks against RSA and DSA as a result of this + defect would be very difficult to perform and are not believed likely. + Attacks against DH1024 are considered just feasible, because most of the + work necessary to deduce information about a private key may be performed + offline. The amount of resources required for such an attack would be + significant. However, for an attack on TLS to be meaningful, the server + would have to share the DH1024 private key among multiple clients, which is + no longer an option since CVE-2016-0701. + + This only affects processors that support the AVX2 but not ADX extensions + like Intel Haswell (4th generation). + + This issue was reported to OpenSSL by David Benjamin (Google). The issue + was originally found via the OSS-Fuzz project. + ([CVE-2017-3738]) + + *Andy Polyakov* + +### Changes between 1.0.2l and 1.0.2m [2 Nov 2017] + + * bn_sqrx8x_internal carry bug on x86_64 + + There is a carry propagating bug in the x86_64 Montgomery squaring + procedure. No EC algorithms are affected. Analysis suggests that attacks + against RSA and DSA as a result of this defect would be very difficult to + perform and are not believed likely. Attacks against DH are considered just + feasible (although very difficult) because most of the work necessary to + deduce information about a private key may be performed offline. The amount + of resources required for such an attack would be very significant and + likely only accessible to a limited number of attackers. An attacker would + additionally need online access to an unpatched system using the target + private key in a scenario with persistent DH parameters and a private + key that is shared between multiple clients. + + This only affects processors that support the BMI1, BMI2 and ADX extensions + like Intel Broadwell (5th generation) and later or AMD Ryzen. + + This issue was reported to OpenSSL by the OSS-Fuzz project. + ([CVE-2017-3736]) + + *Andy Polyakov* + + * Malformed X.509 IPAddressFamily could cause OOB read + + If an X.509 certificate has a malformed IPAddressFamily extension, + OpenSSL could do a one-byte buffer overread. The most likely result + would be an erroneous display of the certificate in text format. + + This issue was reported to OpenSSL by the OSS-Fuzz project. + + *Rich Salz* + +### Changes between 1.0.2k and 1.0.2l [25 May 2017] + + * Have 'config' recognise 64-bit mingw and choose 'mingw64' as the target + platform rather than 'mingw'. + + *Richard Levitte* + +### Changes between 1.0.2j and 1.0.2k [26 Jan 2017] + + * Truncated packet could crash via OOB read + + If one side of an SSL/TLS path is running on a 32-bit host and a specific + cipher is being used, then a truncated packet can cause that host to + perform an out-of-bounds read, usually resulting in a crash. + + This issue was reported to OpenSSL by Robert Święcki of Google. + ([CVE-2017-3731]) + + *Andy Polyakov* + + * BN_mod_exp may produce incorrect results on x86_64 + + There is a carry propagating bug in the x86_64 Montgomery squaring + procedure. No EC algorithms are affected. Analysis suggests that attacks + against RSA and DSA as a result of this defect would be very difficult to + perform and are not believed likely. Attacks against DH are considered just + feasible (although very difficult) because most of the work necessary to + deduce information about a private key may be performed offline. The amount + of resources required for such an attack would be very significant and + likely only accessible to a limited number of attackers. An attacker would + additionally need online access to an unpatched system using the target + private key in a scenario with persistent DH parameters and a private + key that is shared between multiple clients. For example this can occur by + default in OpenSSL DHE based SSL/TLS ciphersuites. Note: This issue is very + similar to CVE-2015-3193 but must be treated as a separate problem. + + This issue was reported to OpenSSL by the OSS-Fuzz project. + ([CVE-2017-3732]) + + *Andy Polyakov* + + * Montgomery multiplication may produce incorrect results + + There is a carry propagating bug in the Broadwell-specific Montgomery + multiplication procedure that handles input lengths divisible by, but + longer than 256 bits. Analysis suggests that attacks against RSA, DSA + and DH private keys are impossible. This is because the subroutine in + question is not used in operations with the private key itself and an input + of the attacker's direct choice. Otherwise the bug can manifest itself as + transient authentication and key negotiation failures or reproducible + erroneous outcome of public-key operations with specially crafted input. + Among EC algorithms only Brainpool P-512 curves are affected and one + presumably can attack ECDH key negotiation. Impact was not analyzed in + detail, because pre-requisites for attack are considered unlikely. Namely + multiple clients have to choose the curve in question and the server has to + share the private key among them, neither of which is default behaviour. + Even then only clients that chose the curve will be affected. + + This issue was publicly reported as transient failures and was not + initially recognized as a security issue. Thanks to Richard Morgan for + providing reproducible case. + ([CVE-2016-7055]) + + *Andy Polyakov* + + * OpenSSL now fails if it receives an unrecognised record type in TLS1.0 + or TLS1.1. Previously this only happened in SSLv3 and TLS1.2. This is to + prevent issues where no progress is being made and the peer continually + sends unrecognised record types, using up resources processing them. + + *Matt Caswell* + +### Changes between 1.0.2i and 1.0.2j [26 Sep 2016] + + * Missing CRL sanity check + + A bug fix which included a CRL sanity check was added to OpenSSL 1.1.0 + but was omitted from OpenSSL 1.0.2i. As a result any attempt to use + CRLs in OpenSSL 1.0.2i will crash with a null pointer exception. + + This issue only affects the OpenSSL 1.0.2i + ([CVE-2016-7052]) + + *Matt Caswell* + +### Changes between 1.0.2h and 1.0.2i [22 Sep 2016] + + * OCSP Status Request extension unbounded memory growth + + A malicious client can send an excessively large OCSP Status Request + extension. If that client continually requests renegotiation, sending a + large OCSP Status Request extension each time, then there will be unbounded + memory growth on the server. This will eventually lead to a Denial Of + Service attack through memory exhaustion. Servers with a default + configuration are vulnerable even if they do not support OCSP. Builds using + the "no-ocsp" build time option are not affected. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-6304]) + + *Matt Caswell* + + * In order to mitigate the SWEET32 attack, the DES ciphers were moved from + HIGH to MEDIUM. + + This issue was reported to OpenSSL Karthikeyan Bhargavan and Gaetan + Leurent (INRIA) + ([CVE-2016-2183]) + + *Rich Salz* + + * OOB write in MDC2_Update() + + An overflow can occur in MDC2_Update() either if called directly or + through the EVP_DigestUpdate() function using MDC2. If an attacker + is able to supply very large amounts of input data after a previous + call to EVP_EncryptUpdate() with a partial block then a length check + can overflow resulting in a heap corruption. + + The amount of data needed is comparable to SIZE_MAX which is impractical + on most platforms. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-6303]) + + *Stephen Henson* + + * Malformed SHA512 ticket DoS + + If a server uses SHA512 for TLS session ticket HMAC it is vulnerable to a + DoS attack where a malformed ticket will result in an OOB read which will + ultimately crash. + + The use of SHA512 in TLS session tickets is comparatively rare as it requires + a custom server callback and ticket lookup mechanism. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-6302]) + + *Stephen Henson* + + * OOB write in BN_bn2dec() + + The function BN_bn2dec() does not check the return value of BN_div_word(). + This can cause an OOB write if an application uses this function with an + overly large BIGNUM. This could be a problem if an overly large certificate + or CRL is printed out from an untrusted source. TLS is not affected because + record limits will reject an oversized certificate before it is parsed. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-2182]) + + *Stephen Henson* + + * OOB read in TS_OBJ_print_bio() + + The function TS_OBJ_print_bio() misuses OBJ_obj2txt(): the return value is + the total length the OID text representation would use and not the amount + of data written. This will result in OOB reads when large OIDs are + presented. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-2180]) + + *Stephen Henson* + + * Pointer arithmetic undefined behaviour + + Avoid some undefined pointer arithmetic + + A common idiom in the codebase is to check limits in the following manner: + "p + len > limit" + + Where "p" points to some malloc'd data of SIZE bytes and + limit == p + SIZE + + "len" here could be from some externally supplied data (e.g. from a TLS + message). + + The rules of C pointer arithmetic are such that "p + len" is only well + defined where len <= SIZE. Therefore the above idiom is actually + undefined behaviour. + + For example this could cause problems if some malloc implementation + provides an address for "p" such that "p + len" actually overflows for + values of len that are too big and therefore p + len < limit. + + This issue was reported to OpenSSL by Guido Vranken + ([CVE-2016-2177]) + + *Matt Caswell* + + * Constant time flag not preserved in DSA signing + + Operations in the DSA signing algorithm should run in constant time in + order to avoid side channel attacks. A flaw in the OpenSSL DSA + implementation means that a non-constant time codepath is followed for + certain operations. This has been demonstrated through a cache-timing + attack to be sufficient for an attacker to recover the private DSA key. + + This issue was reported by César Pereida (Aalto University), Billy Brumley + (Tampere University of Technology), and Yuval Yarom (The University of + Adelaide and NICTA). + ([CVE-2016-2178]) + + *César Pereida* + + * DTLS buffered message DoS + + In a DTLS connection where handshake messages are delivered out-of-order + those messages that OpenSSL is not yet ready to process will be buffered + for later use. Under certain circumstances, a flaw in the logic means that + those messages do not get removed from the buffer even though the handshake + has been completed. An attacker could force up to approx. 15 messages to + remain in the buffer when they are no longer required. These messages will + be cleared when the DTLS connection is closed. The default maximum size for + a message is 100k. Therefore the attacker could force an additional 1500k + to be consumed per connection. By opening many simulataneous connections an + attacker could cause a DoS attack through memory exhaustion. + + This issue was reported to OpenSSL by Quan Luo. + ([CVE-2016-2179]) + + *Matt Caswell* + + * DTLS replay protection DoS + + A flaw in the DTLS replay attack protection mechanism means that records + that arrive for future epochs update the replay protection "window" before + the MAC for the record has been validated. This could be exploited by an + attacker by sending a record for the next epoch (which does not have to + decrypt or have a valid MAC), with a very large sequence number. This means + that all subsequent legitimate packets are dropped causing a denial of + service for a specific DTLS connection. + + This issue was reported to OpenSSL by the OCAP audit team. + ([CVE-2016-2181]) + + *Matt Caswell* + + * Certificate message OOB reads + + In OpenSSL 1.0.2 and earlier some missing message length checks can result + in OOB reads of up to 2 bytes beyond an allocated buffer. There is a + theoretical DoS risk but this has not been observed in practice on common + platforms. + + The messages affected are client certificate, client certificate request + and server certificate. As a result the attack can only be performed + against a client or a server which enables client authentication. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-6306]) + + *Stephen Henson* + +### Changes between 1.0.2g and 1.0.2h [3 May 2016] + + * Prevent padding oracle in AES-NI CBC MAC check + + A MITM attacker can use a padding oracle attack to decrypt traffic + when the connection uses an AES CBC cipher and the server support + AES-NI. + + This issue was introduced as part of the fix for Lucky 13 padding + attack ([CVE-2013-0169]). The padding check was rewritten to be in + constant time by making sure that always the same bytes are read and + compared against either the MAC or padding bytes. But it no longer + checked that there was enough data to have both the MAC and padding + bytes. + + This issue was reported by Juraj Somorovsky using TLS-Attacker. + + *Kurt Roeckx* + + * Fix EVP_EncodeUpdate overflow + + An overflow can occur in the EVP_EncodeUpdate() function which is used for + Base64 encoding of binary data. If an attacker is able to supply very large + amounts of input data then a length check can overflow resulting in a heap + corruption. + + Internally to OpenSSL the EVP_EncodeUpdate() function is primarily used by + the `PEM_write_bio*` family of functions. These are mainly used within the + OpenSSL command line applications, so any application which processes data + from an untrusted source and outputs it as a PEM file should be considered + vulnerable to this issue. User applications that call these APIs directly + with large amounts of untrusted data may also be vulnerable. + + This issue was reported by Guido Vranken. + ([CVE-2016-2105]) + + *Matt Caswell* + + * Fix EVP_EncryptUpdate overflow + + An overflow can occur in the EVP_EncryptUpdate() function. If an attacker + is able to supply very large amounts of input data after a previous call to + EVP_EncryptUpdate() with a partial block then a length check can overflow + resulting in a heap corruption. Following an analysis of all OpenSSL + internal usage of the EVP_EncryptUpdate() function all usage is one of two + forms. The first form is where the EVP_EncryptUpdate() call is known to be + the first called function after an EVP_EncryptInit(), and therefore that + specific call must be safe. The second form is where the length passed to + EVP_EncryptUpdate() can be seen from the code to be some small value and + therefore there is no possibility of an overflow. Since all instances are + one of these two forms, it is believed that there can be no overflows in + internal code due to this problem. It should be noted that + EVP_DecryptUpdate() can call EVP_EncryptUpdate() in certain code paths. + Also EVP_CipherUpdate() is a synonym for EVP_EncryptUpdate(). All instances + of these calls have also been analysed too and it is believed there are no + instances in internal usage where an overflow could occur. + + This issue was reported by Guido Vranken. + ([CVE-2016-2106]) + + *Matt Caswell* + + * Prevent ASN.1 BIO excessive memory allocation + + When ASN.1 data is read from a BIO using functions such as d2i_CMS_bio() + a short invalid encoding can cause allocation of large amounts of memory + potentially consuming excessive resources or exhausting memory. + + Any application parsing untrusted data through d2i BIO functions is + affected. The memory based functions such as d2i_X509() are *not* affected. + Since the memory based functions are used by the TLS library, TLS + applications are not affected. + + This issue was reported by Brian Carpenter. + ([CVE-2016-2109]) + + *Stephen Henson* + + * EBCDIC overread + + ASN1 Strings that are over 1024 bytes can cause an overread in applications + using the X509_NAME_oneline() function on EBCDIC systems. This could result + in arbitrary stack data being returned in the buffer. + + This issue was reported by Guido Vranken. + ([CVE-2016-2176]) + + *Matt Caswell* + + * Modify behavior of ALPN to invoke callback after SNI/servername + callback, such that updates to the SSL_CTX affect ALPN. + + *Todd Short* + + * Remove LOW from the DEFAULT cipher list. This removes singles DES from the + default. + + *Kurt Roeckx* + + * Only remove the SSLv2 methods with the no-ssl2-method option. When the + methods are enabled and ssl2 is disabled the methods return NULL. + + *Kurt Roeckx* + +### Changes between 1.0.2f and 1.0.2g [1 Mar 2016] + +* Disable weak ciphers in SSLv3 and up in default builds of OpenSSL. + Builds that are not configured with "enable-weak-ssl-ciphers" will not + provide any "EXPORT" or "LOW" strength ciphers. + + *Viktor Dukhovni* + +* Disable SSLv2 default build, default negotiation and weak ciphers. SSLv2 + is by default disabled at build-time. Builds that are not configured with + "enable-ssl2" will not support SSLv2. Even if "enable-ssl2" is used, + users who want to negotiate SSLv2 via the version-flexible SSLv23_method() + will need to explicitly call either of: + + SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv2); + or + SSL_clear_options(ssl, SSL_OP_NO_SSLv2); + + as appropriate. Even if either of those is used, or the application + explicitly uses the version-specific SSLv2_method() or its client and + server variants, SSLv2 ciphers vulnerable to exhaustive search key + recovery have been removed. Specifically, the SSLv2 40-bit EXPORT + ciphers, and SSLv2 56-bit DES are no longer available. + ([CVE-2016-0800]) + + *Viktor Dukhovni* + + * Fix a double-free in DSA code + + A double free bug was discovered when OpenSSL parses malformed DSA private + keys and could lead to a DoS attack or memory corruption for applications + that receive DSA private keys from untrusted sources. This scenario is + considered rare. + + This issue was reported to OpenSSL by Adam Langley(Google/BoringSSL) using + libFuzzer. + ([CVE-2016-0705]) + + *Stephen Henson* + + * Disable SRP fake user seed to address a server memory leak. + + Add a new method SRP_VBASE_get1_by_user that handles the seed properly. + + SRP_VBASE_get_by_user had inconsistent memory management behaviour. + In order to fix an unavoidable memory leak, SRP_VBASE_get_by_user + was changed to ignore the "fake user" SRP seed, even if the seed + is configured. + + Users should use SRP_VBASE_get1_by_user instead. Note that in + SRP_VBASE_get1_by_user, caller must free the returned value. Note + also that even though configuring the SRP seed attempts to hide + invalid usernames by continuing the handshake with fake + credentials, this behaviour is not constant time and no strong + guarantees are made that the handshake is indistinguishable from + that of a valid user. + ([CVE-2016-0798]) + + *Emilia Käsper* + + * Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption + + In the BN_hex2bn function the number of hex digits is calculated using an + int value `i`. Later `bn_expand` is called with a value of `i * 4`. For + large values of `i` this can result in `bn_expand` not allocating any + memory because `i * 4` is negative. This can leave the internal BIGNUM data + field as NULL leading to a subsequent NULL ptr deref. For very large values + of `i`, the calculation `i * 4` could be a positive value smaller than `i`. + In this case memory is allocated to the internal BIGNUM data field, but it + is insufficiently sized leading to heap corruption. A similar issue exists + in BN_dec2bn. This could have security consequences if BN_hex2bn/BN_dec2bn + is ever called by user applications with very large untrusted hex/dec data. + This is anticipated to be a rare occurrence. + + All OpenSSL internal usage of these functions use data that is not expected + to be untrusted, e.g. config file data or application command line + arguments. If user developed applications generate config file data based + on untrusted data then it is possible that this could also lead to security + consequences. This is also anticipated to be rare. + + This issue was reported to OpenSSL by Guido Vranken. + ([CVE-2016-0797]) + + *Matt Caswell* + + * Fix memory issues in `BIO_*printf` functions + + The internal `fmtstr` function used in processing a "%s" format string in + the `BIO_*printf` functions could overflow while calculating the length of a + string and cause an OOB read when printing very long strings. + + Additionally the internal `doapr_outch` function can attempt to write to an + OOB memory location (at an offset from the NULL pointer) in the event of a + memory allocation failure. In 1.0.2 and below this could be caused where + the size of a buffer to be allocated is greater than INT_MAX. E.g. this + could be in processing a very long "%s" format string. Memory leaks can + also occur. + + The first issue may mask the second issue dependent on compiler behaviour. + These problems could enable attacks where large amounts of untrusted data + is passed to the `BIO_*printf` functions. If applications use these functions + in this way then they could be vulnerable. OpenSSL itself uses these + functions when printing out human-readable dumps of ASN.1 data. Therefore + applications that print this data could be vulnerable if the data is from + untrusted sources. OpenSSL command line applications could also be + vulnerable where they print out ASN.1 data, or if untrusted data is passed + as command line arguments. + + Libssl is not considered directly vulnerable. Additionally certificates etc + received via remote connections via libssl are also unlikely to be able to + trigger these issues because of message size limits enforced within libssl. + + This issue was reported to OpenSSL Guido Vranken. + ([CVE-2016-0799]) + + *Matt Caswell* + + * Side channel attack on modular exponentiation + + A side-channel attack was found which makes use of cache-bank conflicts on + the Intel Sandy-Bridge microarchitecture which could lead to the recovery + of RSA keys. The ability to exploit this issue is limited as it relies on + an attacker who has control of code in a thread running on the same + hyper-threaded core as the victim thread which is performing decryptions. + + This issue was reported to OpenSSL by Yuval Yarom, The University of + Adelaide and NICTA, Daniel Genkin, Technion and Tel Aviv University, and + Nadia Heninger, University of Pennsylvania with more information at + . + ([CVE-2016-0702]) + + *Andy Polyakov* + + * Change the `req` command to generate a 2048-bit RSA/DSA key by default, + if no keysize is specified with default_bits. This fixes an + omission in an earlier change that changed all RSA/DSA key generation + commands to use 2048 bits by default. + + *Emilia Käsper* + +### Changes between 1.0.2e and 1.0.2f [28 Jan 2016] + + * DH small subgroups + + Historically OpenSSL only ever generated DH parameters based on "safe" + primes. More recently (in version 1.0.2) support was provided for + generating X9.42 style parameter files such as those required for RFC 5114 + support. The primes used in such files may not be "safe". Where an + application is using DH configured with parameters based on primes that are + not "safe" then an attacker could use this fact to find a peer's private + DH exponent. This attack requires that the attacker complete multiple + handshakes in which the peer uses the same private DH exponent. For example + this could be used to discover a TLS server's private DH exponent if it's + reusing the private DH exponent or it's using a static DH ciphersuite. + + OpenSSL provides the option SSL_OP_SINGLE_DH_USE for ephemeral DH (DHE) in + TLS. It is not on by default. If the option is not set then the server + reuses the same private DH exponent for the life of the server process and + would be vulnerable to this attack. It is believed that many popular + applications do set this option and would therefore not be at risk. + + The fix for this issue adds an additional check where a "q" parameter is + available (as is the case in X9.42 based parameters). This detects the + only known attack, and is the only possible defense for static DH + ciphersuites. This could have some performance impact. + + Additionally the SSL_OP_SINGLE_DH_USE option has been switched on by + default and cannot be disabled. This could have some performance impact. + + This issue was reported to OpenSSL by Antonio Sanso (Adobe). + ([CVE-2016-0701]) + + *Matt Caswell* + + * SSLv2 doesn't block disabled ciphers + + A malicious client can negotiate SSLv2 ciphers that have been disabled on + the server and complete SSLv2 handshakes even if all SSLv2 ciphers have + been disabled, provided that the SSLv2 protocol was not also disabled via + SSL_OP_NO_SSLv2. + + This issue was reported to OpenSSL on 26th December 2015 by Nimrod Aviram + and Sebastian Schinzel. + ([CVE-2015-3197]) + + *Viktor Dukhovni* + +### Changes between 1.0.2d and 1.0.2e [3 Dec 2015] + + * BN_mod_exp may produce incorrect results on x86_64 + + There is a carry propagating bug in the x86_64 Montgomery squaring + procedure. No EC algorithms are affected. Analysis suggests that attacks + against RSA and DSA as a result of this defect would be very difficult to + perform and are not believed likely. Attacks against DH are considered just + feasible (although very difficult) because most of the work necessary to + deduce information about a private key may be performed offline. The amount + of resources required for such an attack would be very significant and + likely only accessible to a limited number of attackers. An attacker would + additionally need online access to an unpatched system using the target + private key in a scenario with persistent DH parameters and a private + key that is shared between multiple clients. For example this can occur by + default in OpenSSL DHE based SSL/TLS ciphersuites. + + This issue was reported to OpenSSL by Hanno Böck. + ([CVE-2015-3193]) + + *Andy Polyakov* + + * Certificate verify crash with missing PSS parameter + + The signature verification routines will crash with a NULL pointer + dereference if presented with an ASN.1 signature using the RSA PSS + algorithm and absent mask generation function parameter. Since these + routines are used to verify certificate signature algorithms this can be + used to crash any certificate verification operation and exploited in a + DoS attack. Any application which performs certificate verification is + vulnerable including OpenSSL clients and servers which enable client + authentication. + + This issue was reported to OpenSSL by Loïc Jonas Etienne (Qnective AG). + ([CVE-2015-3194]) + + *Stephen Henson* + + * X509_ATTRIBUTE memory leak + + When presented with a malformed X509_ATTRIBUTE structure OpenSSL will leak + memory. This structure is used by the PKCS#7 and CMS routines so any + application which reads PKCS#7 or CMS data from untrusted sources is + affected. SSL/TLS is not affected. + + This issue was reported to OpenSSL by Adam Langley (Google/BoringSSL) using + libFuzzer. + ([CVE-2015-3195]) + + *Stephen Henson* + + * Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs. + This changes the decoding behaviour for some invalid messages, + though the change is mostly in the more lenient direction, and + legacy behaviour is preserved as much as possible. + + *Emilia Käsper* + + * In DSA_generate_parameters_ex, if the provided seed is too short, + return an error + + *Rich Salz and Ismo Puustinen * + +### Changes between 1.0.2c and 1.0.2d [9 Jul 2015] + + * Alternate chains certificate forgery + + During certificate verification, OpenSSL will attempt to find an + alternative certificate chain if the first attempt to build such a chain + fails. An error in the implementation of this logic can mean that an + attacker could cause certain checks on untrusted certificates to be + bypassed, such as the CA flag, enabling them to use a valid leaf + certificate to act as a CA and "issue" an invalid certificate. + + This issue was reported to OpenSSL by Adam Langley/David Benjamin + (Google/BoringSSL). + + *Matt Caswell* + +### Changes between 1.0.2b and 1.0.2c [12 Jun 2015] + + * Fix HMAC ABI incompatibility. The previous version introduced an ABI + incompatibility in the handling of HMAC. The previous ABI has now been + restored. + + *Matt Caswell* + +### Changes between 1.0.2a and 1.0.2b [11 Jun 2015] + + * Malformed ECParameters causes infinite loop + + When processing an ECParameters structure OpenSSL enters an infinite loop + if the curve specified is over a specially malformed binary polynomial + field. + + This can be used to perform denial of service against any + system which processes public keys, certificate requests or + certificates. This includes TLS clients and TLS servers with + client authentication enabled. + + This issue was reported to OpenSSL by Joseph Barr-Pixton. + ([CVE-2015-1788]) + + *Andy Polyakov* + + * Exploitable out-of-bounds read in X509_cmp_time + + X509_cmp_time does not properly check the length of the ASN1_TIME + string and can read a few bytes out of bounds. In addition, + X509_cmp_time accepts an arbitrary number of fractional seconds in the + time string. + + An attacker can use this to craft malformed certificates and CRLs of + various sizes and potentially cause a segmentation fault, resulting in + a DoS on applications that verify certificates or CRLs. TLS clients + that verify CRLs are affected. TLS clients and servers with client + authentication enabled may be affected if they use custom verification + callbacks. + + This issue was reported to OpenSSL by Robert Swiecki (Google), and + independently by Hanno Böck. + ([CVE-2015-1789]) + + *Emilia Käsper* + + * PKCS7 crash with missing EnvelopedContent + + The PKCS#7 parsing code does not handle missing inner EncryptedContent + correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs + with missing content and trigger a NULL pointer dereference on parsing. + + Applications that decrypt PKCS#7 data or otherwise parse PKCS#7 + structures from untrusted sources are affected. OpenSSL clients and + servers are not affected. + + This issue was reported to OpenSSL by Michal Zalewski (Google). + ([CVE-2015-1790]) + + *Emilia Käsper* + + * CMS verify infinite loop with unknown hash function + + When verifying a signedData message the CMS code can enter an infinite loop + if presented with an unknown hash function OID. This can be used to perform + denial of service against any system which verifies signedData messages using + the CMS code. + This issue was reported to OpenSSL by Johannes Bauer. + ([CVE-2015-1792]) + + *Stephen Henson* + + * Race condition handling NewSessionTicket + + If a NewSessionTicket is received by a multi-threaded client when attempting to + reuse a previous ticket then a race condition can occur potentially leading to + a double free of the ticket data. + ([CVE-2015-1791]) + + *Matt Caswell* + + * Only support 256-bit or stronger elliptic curves with the + 'ecdh_auto' setting (server) or by default (client). Of supported + curves, prefer P-256 (both). + + *Emilia Kasper* + +### Changes between 1.0.2 and 1.0.2a [19 Mar 2015] + + * ClientHello sigalgs DoS fix + + If a client connects to an OpenSSL 1.0.2 server and renegotiates with an + invalid signature algorithms extension a NULL pointer dereference will + occur. This can be exploited in a DoS attack against the server. + + This issue was was reported to OpenSSL by David Ramos of Stanford + University. + ([CVE-2015-0291]) + + *Stephen Henson and Matt Caswell* + + * Multiblock corrupted pointer fix + + OpenSSL 1.0.2 introduced the "multiblock" performance improvement. This + feature only applies on 64 bit x86 architecture platforms that support AES + NI instructions. A defect in the implementation of "multiblock" can cause + OpenSSL's internal write buffer to become incorrectly set to NULL when + using non-blocking IO. Typically, when the user application is using a + socket BIO for writing, this will only result in a failed connection. + However if some other BIO is used then it is likely that a segmentation + fault will be triggered, thus enabling a potential DoS attack. + + This issue was reported to OpenSSL by Daniel Danner and Rainer Mueller. + ([CVE-2015-0290]) + + *Matt Caswell* + + * Segmentation fault in DTLSv1_listen fix + + The DTLSv1_listen function is intended to be stateless and processes the + initial ClientHello from many peers. It is common for user code to loop + over the call to DTLSv1_listen until a valid ClientHello is received with + an associated cookie. A defect in the implementation of DTLSv1_listen means + that state is preserved in the SSL object from one invocation to the next + that can lead to a segmentation fault. Errors processing the initial + ClientHello can trigger this scenario. An example of such an error could be + that a DTLS1.0 only client is attempting to connect to a DTLS1.2 only + server. + + This issue was reported to OpenSSL by Per Allansson. + ([CVE-2015-0207]) + + *Matt Caswell* + + * Segmentation fault in ASN1_TYPE_cmp fix + + The function ASN1_TYPE_cmp will crash with an invalid read if an attempt is + made to compare ASN.1 boolean types. Since ASN1_TYPE_cmp is used to check + certificate signature algorithm consistency this can be used to crash any + certificate verification operation and exploited in a DoS attack. Any + application which performs certificate verification is vulnerable including + OpenSSL clients and servers which enable client authentication. + ([CVE-2015-0286]) + + *Stephen Henson* + + * Segmentation fault for invalid PSS parameters fix + + The signature verification routines will crash with a NULL pointer + dereference if presented with an ASN.1 signature using the RSA PSS + algorithm and invalid parameters. Since these routines are used to verify + certificate signature algorithms this can be used to crash any + certificate verification operation and exploited in a DoS attack. Any + application which performs certificate verification is vulnerable including + OpenSSL clients and servers which enable client authentication. + + This issue was was reported to OpenSSL by Brian Carpenter. + ([CVE-2015-0208]) + + *Stephen Henson* + + * ASN.1 structure reuse memory corruption fix + + Reusing a structure in ASN.1 parsing may allow an attacker to cause + memory corruption via an invalid write. Such reuse is and has been + strongly discouraged and is believed to be rare. + + Applications that parse structures containing CHOICE or ANY DEFINED BY + components may be affected. Certificate parsing (d2i_X509 and related + functions) are however not affected. OpenSSL clients and servers are + not affected. + ([CVE-2015-0287]) + + *Stephen Henson* + + * PKCS7 NULL pointer dereferences fix + + The PKCS#7 parsing code does not handle missing outer ContentInfo + correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs with + missing content and trigger a NULL pointer dereference on parsing. + + Applications that verify PKCS#7 signatures, decrypt PKCS#7 data or + otherwise parse PKCS#7 structures from untrusted sources are + affected. OpenSSL clients and servers are not affected. + + This issue was reported to OpenSSL by Michal Zalewski (Google). + ([CVE-2015-0289]) + + *Emilia Käsper* + + * DoS via reachable assert in SSLv2 servers fix + + A malicious client can trigger an OPENSSL_assert (i.e., an abort) in + servers that both support SSLv2 and enable export cipher suites by sending + a specially crafted SSLv2 CLIENT-MASTER-KEY message. + + This issue was discovered by Sean Burford (Google) and Emilia Käsper + (OpenSSL development team). + ([CVE-2015-0293]) + + *Emilia Käsper* + + * Empty CKE with client auth and DHE fix + + If client auth is used then a server can seg fault in the event of a DHE + ciphersuite being selected and a zero length ClientKeyExchange message + being sent by the client. This could be exploited in a DoS attack. + ([CVE-2015-1787]) + + *Matt Caswell* + + * Handshake with unseeded PRNG fix + + Under certain conditions an OpenSSL 1.0.2 client can complete a handshake + with an unseeded PRNG. The conditions are: + - The client is on a platform where the PRNG has not been seeded + automatically, and the user has not seeded manually + - A protocol specific client method version has been used (i.e. not + SSL_client_methodv23) + - A ciphersuite is used that does not require additional random data from + the PRNG beyond the initial ClientHello client random (e.g. PSK-RC4-SHA). + + If the handshake succeeds then the client random that has been used will + have been generated from a PRNG with insufficient entropy and therefore the + output may be predictable. + + For example using the following command with an unseeded openssl will + succeed on an unpatched platform: + + openssl s_client -psk 1a2b3c4d -tls1_2 -cipher PSK-RC4-SHA + ([CVE-2015-0285]) + + *Matt Caswell* + + * Use After Free following d2i_ECPrivatekey error fix + + A malformed EC private key file consumed via the d2i_ECPrivateKey function + could cause a use after free condition. This, in turn, could cause a double + free in several private key parsing functions (such as d2i_PrivateKey + or EVP_PKCS82PKEY) and could lead to a DoS attack or memory corruption + for applications that receive EC private keys from untrusted + sources. This scenario is considered rare. + + This issue was discovered by the BoringSSL project and fixed in their + commit 517073cd4b. + ([CVE-2015-0209]) + + *Matt Caswell* + + * X509_to_X509_REQ NULL pointer deref fix + + The function X509_to_X509_REQ will crash with a NULL pointer dereference if + the certificate key is invalid. This function is rarely used in practice. + + This issue was discovered by Brian Carpenter. + ([CVE-2015-0288]) + + *Stephen Henson* + + * Removed the export ciphers from the DEFAULT ciphers + + *Kurt Roeckx* + +### Changes between 1.0.1l and 1.0.2 [22 Jan 2015] + + * Facilitate "universal" ARM builds targeting range of ARM ISAs, e.g. + ARMv5 through ARMv8, as opposite to "locking" it to single one. + So far those who have to target multiple platforms would compromise + and argue that binary targeting say ARMv5 would still execute on + ARMv8. "Universal" build resolves this compromise by providing + near-optimal performance even on newer platforms. + + *Andy Polyakov* + + * Accelerated NIST P-256 elliptic curve implementation for x86_64 + (other platforms pending). + + *Shay Gueron & Vlad Krasnov (Intel Corp), Andy Polyakov* + + * Add support for the SignedCertificateTimestampList certificate and + OCSP response extensions from RFC6962. + + *Rob Stradling* + + * Fix ec_GFp_simple_points_make_affine (thus, EC_POINTs_mul etc.) + for corner cases. (Certain input points at infinity could lead to + bogus results, with non-infinity inputs mapped to infinity too.) + + *Bodo Moeller* + + * Initial support for PowerISA 2.0.7, first implemented in POWER8. + This covers AES, SHA256/512 and GHASH. "Initial" means that most + common cases are optimized and there still is room for further + improvements. Vector Permutation AES for Altivec is also added. + + *Andy Polyakov* + + * Add support for little-endian ppc64 Linux target. + + *Marcelo Cerri (IBM)* + + * Initial support for AMRv8 ISA crypto extensions. This covers AES, + SHA1, SHA256 and GHASH. "Initial" means that most common cases + are optimized and there still is room for further improvements. + Both 32- and 64-bit modes are supported. + + *Andy Polyakov, Ard Biesheuvel (Linaro)* + + * Improved ARMv7 NEON support. + + *Andy Polyakov* + + * Support for SPARC Architecture 2011 crypto extensions, first + implemented in SPARC T4. This covers AES, DES, Camellia, SHA1, + SHA256/512, MD5, GHASH and modular exponentiation. + + *Andy Polyakov, David Miller* + + * Accelerated modular exponentiation for Intel processors, a.k.a. + RSAZ. + + *Shay Gueron & Vlad Krasnov (Intel Corp)* + + * Support for new and upcoming Intel processors, including AVX2, + BMI and SHA ISA extensions. This includes additional "stitched" + implementations, AESNI-SHA256 and GCM, and multi-buffer support + for TLS encrypt. + + This work was sponsored by Intel Corp. + + *Andy Polyakov* + + * Support for DTLS 1.2. This adds two sets of DTLS methods: DTLS_*_method() + supports both DTLS 1.2 and 1.0 and should use whatever version the peer + supports and DTLSv1_2_*_method() which supports DTLS 1.2 only. + + *Steve Henson* + + * Use algorithm specific chains in SSL_CTX_use_certificate_chain_file(): + this fixes a limitation in previous versions of OpenSSL. + + *Steve Henson* + + * Extended RSA OAEP support via EVP_PKEY API. Options to specify digest, + MGF1 digest and OAEP label. + + *Steve Henson* + + * Add EVP support for key wrapping algorithms, to avoid problems with + existing code the flag EVP_CIPHER_CTX_WRAP_ALLOW has to be set in + the EVP_CIPHER_CTX or an error is returned. Add AES and DES3 wrap + algorithms and include tests cases. + + *Steve Henson* + + * Add functions to allocate and set the fields of an ECDSA_METHOD + structure. + + *Douglas E. Engert, Steve Henson* + + * New functions OPENSSL_gmtime_diff and ASN1_TIME_diff to find the + difference in days and seconds between two tm or ASN1_TIME structures. + + *Steve Henson* + + * Add -rev test option to s_server to just reverse order of characters + received by client and send back to server. Also prints an abbreviated + summary of the connection parameters. + + *Steve Henson* + + * New option -brief for s_client and s_server to print out a brief summary + of connection parameters. + + *Steve Henson* + + * Add callbacks for arbitrary TLS extensions. + + *Trevor Perrin and Ben Laurie* + + * New option -crl_download in several openssl utilities to download CRLs + from CRLDP extension in certificates. + + *Steve Henson* + + * New options -CRL and -CRLform for s_client and s_server for CRLs. + + *Steve Henson* + + * New function X509_CRL_diff to generate a delta CRL from the difference + of two full CRLs. Add support to "crl" utility. + + *Steve Henson* + + * New functions to set lookup_crls function and to retrieve + X509_STORE from X509_STORE_CTX. + + *Steve Henson* + + * Print out deprecated issuer and subject unique ID fields in + certificates. + + *Steve Henson* + + * Extend OCSP I/O functions so they can be used for simple general purpose + HTTP as well as OCSP. New wrapper function which can be used to download + CRLs using the OCSP API. + + *Steve Henson* + + * Delegate command line handling in s_client/s_server to SSL_CONF APIs. + + *Steve Henson* + + * `SSL_CONF*` functions. These provide a common framework for application + configuration using configuration files or command lines. + + *Steve Henson* + + * SSL/TLS tracing code. This parses out SSL/TLS records using the + message callback and prints the results. Needs compile time option + "enable-ssl-trace". New options to s_client and s_server to enable + tracing. + + *Steve Henson* + + * New ctrl and macro to retrieve supported points extensions. + Print out extension in s_server and s_client. + + *Steve Henson* + + * New functions to retrieve certificate signature and signature + OID NID. + + *Steve Henson* + + * Add functions to retrieve and manipulate the raw cipherlist sent by a + client to OpenSSL. + + *Steve Henson* + + * New Suite B modes for TLS code. These use and enforce the requirements + of RFC6460: restrict ciphersuites, only permit Suite B algorithms and + only use Suite B curves. The Suite B modes can be set by using the + strings "SUITEB128", "SUITEB192" or "SUITEB128ONLY" for the cipherstring. + + *Steve Henson* + + * New chain verification flags for Suite B levels of security. Check + algorithms are acceptable when flags are set in X509_verify_cert. + + *Steve Henson* + + * Make tls1_check_chain return a set of flags indicating checks passed + by a certificate chain. Add additional tests to handle client + certificates: checks for matching certificate type and issuer name + comparison. + + *Steve Henson* + + * If an attempt is made to use a signature algorithm not in the peer + preference list abort the handshake. If client has no suitable + signature algorithms in response to a certificate request do not + use the certificate. + + *Steve Henson* + + * If server EC tmp key is not in client preference list abort handshake. + + *Steve Henson* + + * Add support for certificate stores in CERT structure. This makes it + possible to have different stores per SSL structure or one store in + the parent SSL_CTX. Include distinct stores for certificate chain + verification and chain building. New ctrl SSL_CTRL_BUILD_CERT_CHAIN + to build and store a certificate chain in CERT structure: returning + an error if the chain cannot be built: this will allow applications + to test if a chain is correctly configured. + + Note: if the CERT based stores are not set then the parent SSL_CTX + store is used to retain compatibility with existing behaviour. + + *Steve Henson* + + * New function ssl_set_client_disabled to set a ciphersuite disabled + mask based on the current session, check mask when sending client + hello and checking the requested ciphersuite. + + *Steve Henson* + + * New ctrls to retrieve and set certificate types in a certificate + request message. Print out received values in s_client. If certificate + types is not set with custom values set sensible values based on + supported signature algorithms. + + *Steve Henson* + + * Support for distinct client and server supported signature algorithms. + + *Steve Henson* + + * Add certificate callback. If set this is called whenever a certificate + is required by client or server. An application can decide which + certificate chain to present based on arbitrary criteria: for example + supported signature algorithms. Add very simple example to s_server. + This fixes many of the problems and restrictions of the existing client + certificate callback: for example you can now clear an existing + certificate and specify the whole chain. + + *Steve Henson* + + * Add new "valid_flags" field to CERT_PKEY structure which determines what + the certificate can be used for (if anything). Set valid_flags field + in new tls1_check_chain function. Simplify ssl_set_cert_masks which used + to have similar checks in it. + + Add new "cert_flags" field to CERT structure and include a "strict mode". + This enforces some TLS certificate requirements (such as only permitting + certificate signature algorithms contained in the supported algorithms + extension) which some implementations ignore: this option should be used + with caution as it could cause interoperability issues. + + *Steve Henson* + + * Update and tidy signature algorithm extension processing. Work out + shared signature algorithms based on preferences and peer algorithms + and print them out in s_client and s_server. Abort handshake if no + shared signature algorithms. + + *Steve Henson* + + * Add new functions to allow customised supported signature algorithms + for SSL and SSL_CTX structures. Add options to s_client and s_server + to support them. + + *Steve Henson* + + * New function SSL_certs_clear() to delete all references to certificates + from an SSL structure. Before this once a certificate had been added + it couldn't be removed. + + *Steve Henson* + + * Integrate hostname, email address and IP address checking with certificate + verification. New verify options supporting checking in openssl utility. + + *Steve Henson* + + * Fixes and wildcard matching support to hostname and email checking + functions. Add manual page. + + *Florian Weimer (Red Hat Product Security Team)* + + * New functions to check a hostname email or IP address against a + certificate. Add options x509 utility to print results of checks against + a certificate. + + *Steve Henson* + + * Fix OCSP checking. + + *Rob Stradling and Ben Laurie* + + * Initial experimental support for explicitly trusted non-root CAs. + OpenSSL still tries to build a complete chain to a root but if an + intermediate CA has a trust setting included that is used. The first + setting is used: whether to trust (e.g., -addtrust option to the x509 + utility) or reject. + + *Steve Henson* + + * Add -trusted_first option which attempts to find certificates in the + trusted store even if an untrusted chain is also supplied. + + *Steve Henson* + + * MIPS assembly pack updates: support for MIPS32r2 and SmartMIPS ASE, + platform support for Linux and Android. + + *Andy Polyakov* + + * Support for linux-x32, ILP32 environment in x86_64 framework. + + *Andy Polyakov* + + * Experimental multi-implementation support for FIPS capable OpenSSL. + When in FIPS mode the approved implementations are used as normal, + when not in FIPS mode the internal unapproved versions are used instead. + This means that the FIPS capable OpenSSL isn't forced to use the + (often lower performance) FIPS implementations outside FIPS mode. + + *Steve Henson* + + * Transparently support X9.42 DH parameters when calling + PEM_read_bio_DHparameters. This means existing applications can handle + the new parameter format automatically. + + *Steve Henson* + + * Initial experimental support for X9.42 DH parameter format: mainly + to support use of 'q' parameter for RFC5114 parameters. + + *Steve Henson* + + * Add DH parameters from RFC5114 including test data to dhtest. + + *Steve Henson* + + * Support for automatic EC temporary key parameter selection. If enabled + the most preferred EC parameters are automatically used instead of + hardcoded fixed parameters. Now a server just has to call: + SSL_CTX_set_ecdh_auto(ctx, 1) and the server will automatically + support ECDH and use the most appropriate parameters. + + *Steve Henson* + + * Enhance and tidy EC curve and point format TLS extension code. Use + static structures instead of allocation if default values are used. + New ctrls to set curves we wish to support and to retrieve shared curves. + Print out shared curves in s_server. New options to s_server and s_client + to set list of supported curves. + + *Steve Henson* + + * New ctrls to retrieve supported signature algorithms and + supported curve values as an array of NIDs. Extend openssl utility + to print out received values. + + *Steve Henson* + + * Add new APIs EC_curve_nist2nid and EC_curve_nid2nist which convert + between NIDs and the more common NIST names such as "P-256". Enhance + ecparam utility and ECC method to recognise the NIST names for curves. + + *Steve Henson* + + * Enhance SSL/TLS certificate chain handling to support different + chains for each certificate instead of one chain in the parent SSL_CTX. + + *Steve Henson* + + * Support for fixed DH ciphersuite client authentication: where both + server and client use DH certificates with common parameters. + + *Steve Henson* + + * Support for fixed DH ciphersuites: those requiring DH server + certificates. + + *Steve Henson* + + * New function i2d_re_X509_tbs for re-encoding the TBS portion of + the certificate. + Note: Related 1.0.2-beta specific macros X509_get_cert_info, + X509_CINF_set_modified, X509_CINF_get_issuer, X509_CINF_get_extensions and + X509_CINF_get_signature were reverted post internal team review. + +OpenSSL 1.0.1 +------------- + +### Changes between 1.0.1t and 1.0.1u [22 Sep 2016] + + * OCSP Status Request extension unbounded memory growth + + A malicious client can send an excessively large OCSP Status Request + extension. If that client continually requests renegotiation, sending a + large OCSP Status Request extension each time, then there will be unbounded + memory growth on the server. This will eventually lead to a Denial Of + Service attack through memory exhaustion. Servers with a default + configuration are vulnerable even if they do not support OCSP. Builds using + the "no-ocsp" build time option are not affected. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-6304]) + + *Matt Caswell* + + * In order to mitigate the SWEET32 attack, the DES ciphers were moved from + HIGH to MEDIUM. + + This issue was reported to OpenSSL Karthikeyan Bhargavan and Gaetan + Leurent (INRIA) + ([CVE-2016-2183]) + + *Rich Salz* + + * OOB write in MDC2_Update() + + An overflow can occur in MDC2_Update() either if called directly or + through the EVP_DigestUpdate() function using MDC2. If an attacker + is able to supply very large amounts of input data after a previous + call to EVP_EncryptUpdate() with a partial block then a length check + can overflow resulting in a heap corruption. + + The amount of data needed is comparable to SIZE_MAX which is impractical + on most platforms. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-6303]) + + *Stephen Henson* + + * Malformed SHA512 ticket DoS + + If a server uses SHA512 for TLS session ticket HMAC it is vulnerable to a + DoS attack where a malformed ticket will result in an OOB read which will + ultimately crash. + + The use of SHA512 in TLS session tickets is comparatively rare as it requires + a custom server callback and ticket lookup mechanism. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-6302]) + + *Stephen Henson* + + * OOB write in BN_bn2dec() + + The function BN_bn2dec() does not check the return value of BN_div_word(). + This can cause an OOB write if an application uses this function with an + overly large BIGNUM. This could be a problem if an overly large certificate + or CRL is printed out from an untrusted source. TLS is not affected because + record limits will reject an oversized certificate before it is parsed. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-2182]) + + *Stephen Henson* + + * OOB read in TS_OBJ_print_bio() + + The function TS_OBJ_print_bio() misuses OBJ_obj2txt(): the return value is + the total length the OID text representation would use and not the amount + of data written. This will result in OOB reads when large OIDs are + presented. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-2180]) + + *Stephen Henson* + + * Pointer arithmetic undefined behaviour + + Avoid some undefined pointer arithmetic + + A common idiom in the codebase is to check limits in the following manner: + "p + len > limit" + + Where "p" points to some malloc'd data of SIZE bytes and + limit == p + SIZE + + "len" here could be from some externally supplied data (e.g. from a TLS + message). + + The rules of C pointer arithmetic are such that "p + len" is only well + defined where len <= SIZE. Therefore the above idiom is actually + undefined behaviour. + + For example this could cause problems if some malloc implementation + provides an address for "p" such that "p + len" actually overflows for + values of len that are too big and therefore p + len < limit. + + This issue was reported to OpenSSL by Guido Vranken + ([CVE-2016-2177]) + + *Matt Caswell* + + * Constant time flag not preserved in DSA signing + + Operations in the DSA signing algorithm should run in constant time in + order to avoid side channel attacks. A flaw in the OpenSSL DSA + implementation means that a non-constant time codepath is followed for + certain operations. This has been demonstrated through a cache-timing + attack to be sufficient for an attacker to recover the private DSA key. + + This issue was reported by César Pereida (Aalto University), Billy Brumley + (Tampere University of Technology), and Yuval Yarom (The University of + Adelaide and NICTA). + ([CVE-2016-2178]) + + *César Pereida* + + * DTLS buffered message DoS + + In a DTLS connection where handshake messages are delivered out-of-order + those messages that OpenSSL is not yet ready to process will be buffered + for later use. Under certain circumstances, a flaw in the logic means that + those messages do not get removed from the buffer even though the handshake + has been completed. An attacker could force up to approx. 15 messages to + remain in the buffer when they are no longer required. These messages will + be cleared when the DTLS connection is closed. The default maximum size for + a message is 100k. Therefore the attacker could force an additional 1500k + to be consumed per connection. By opening many simulataneous connections an + attacker could cause a DoS attack through memory exhaustion. + + This issue was reported to OpenSSL by Quan Luo. + ([CVE-2016-2179]) + + *Matt Caswell* + + * DTLS replay protection DoS + + A flaw in the DTLS replay attack protection mechanism means that records + that arrive for future epochs update the replay protection "window" before + the MAC for the record has been validated. This could be exploited by an + attacker by sending a record for the next epoch (which does not have to + decrypt or have a valid MAC), with a very large sequence number. This means + that all subsequent legitimate packets are dropped causing a denial of + service for a specific DTLS connection. + + This issue was reported to OpenSSL by the OCAP audit team. + ([CVE-2016-2181]) + + *Matt Caswell* + + * Certificate message OOB reads + + In OpenSSL 1.0.2 and earlier some missing message length checks can result + in OOB reads of up to 2 bytes beyond an allocated buffer. There is a + theoretical DoS risk but this has not been observed in practice on common + platforms. + + The messages affected are client certificate, client certificate request + and server certificate. As a result the attack can only be performed + against a client or a server which enables client authentication. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + ([CVE-2016-6306]) + + *Stephen Henson* + +### Changes between 1.0.1s and 1.0.1t [3 May 2016] + + * Prevent padding oracle in AES-NI CBC MAC check + + A MITM attacker can use a padding oracle attack to decrypt traffic + when the connection uses an AES CBC cipher and the server support + AES-NI. + + This issue was introduced as part of the fix for Lucky 13 padding + attack ([CVE-2013-0169]). The padding check was rewritten to be in + constant time by making sure that always the same bytes are read and + compared against either the MAC or padding bytes. But it no longer + checked that there was enough data to have both the MAC and padding + bytes. + + This issue was reported by Juraj Somorovsky using TLS-Attacker. + ([CVE-2016-2107]) + + *Kurt Roeckx* + + * Fix EVP_EncodeUpdate overflow + + An overflow can occur in the EVP_EncodeUpdate() function which is used for + Base64 encoding of binary data. If an attacker is able to supply very large + amounts of input data then a length check can overflow resulting in a heap + corruption. + + Internally to OpenSSL the EVP_EncodeUpdate() function is primarly used by + the `PEM_write_bio*` family of functions. These are mainly used within the + OpenSSL command line applications, so any application which processes data + from an untrusted source and outputs it as a PEM file should be considered + vulnerable to this issue. User applications that call these APIs directly + with large amounts of untrusted data may also be vulnerable. + + This issue was reported by Guido Vranken. + ([CVE-2016-2105]) + + *Matt Caswell* + + * Fix EVP_EncryptUpdate overflow + + An overflow can occur in the EVP_EncryptUpdate() function. If an attacker + is able to supply very large amounts of input data after a previous call to + EVP_EncryptUpdate() with a partial block then a length check can overflow + resulting in a heap corruption. Following an analysis of all OpenSSL + internal usage of the EVP_EncryptUpdate() function all usage is one of two + forms. The first form is where the EVP_EncryptUpdate() call is known to be + the first called function after an EVP_EncryptInit(), and therefore that + specific call must be safe. The second form is where the length passed to + EVP_EncryptUpdate() can be seen from the code to be some small value and + therefore there is no possibility of an overflow. Since all instances are + one of these two forms, it is believed that there can be no overflows in + internal code due to this problem. It should be noted that + EVP_DecryptUpdate() can call EVP_EncryptUpdate() in certain code paths. + Also EVP_CipherUpdate() is a synonym for EVP_EncryptUpdate(). All instances + of these calls have also been analysed too and it is believed there are no + instances in internal usage where an overflow could occur. + + This issue was reported by Guido Vranken. + ([CVE-2016-2106]) + + *Matt Caswell* + + * Prevent ASN.1 BIO excessive memory allocation + + When ASN.1 data is read from a BIO using functions such as d2i_CMS_bio() + a short invalid encoding can casuse allocation of large amounts of memory + potentially consuming excessive resources or exhausting memory. + + Any application parsing untrusted data through d2i BIO functions is + affected. The memory based functions such as d2i_X509() are *not* affected. + Since the memory based functions are used by the TLS library, TLS + applications are not affected. + + This issue was reported by Brian Carpenter. + ([CVE-2016-2109]) + + *Stephen Henson* + + * EBCDIC overread + + ASN1 Strings that are over 1024 bytes can cause an overread in applications + using the X509_NAME_oneline() function on EBCDIC systems. This could result + in arbitrary stack data being returned in the buffer. + + This issue was reported by Guido Vranken. + ([CVE-2016-2176]) + + *Matt Caswell* + + * Modify behavior of ALPN to invoke callback after SNI/servername + callback, such that updates to the SSL_CTX affect ALPN. + + *Todd Short* + + * Remove LOW from the DEFAULT cipher list. This removes singles DES from the + default. + + *Kurt Roeckx* + + * Only remove the SSLv2 methods with the no-ssl2-method option. When the + methods are enabled and ssl2 is disabled the methods return NULL. + + *Kurt Roeckx* + +### Changes between 1.0.1r and 1.0.1s [1 Mar 2016] + +* Disable weak ciphers in SSLv3 and up in default builds of OpenSSL. + Builds that are not configured with "enable-weak-ssl-ciphers" will not + provide any "EXPORT" or "LOW" strength ciphers. + + *Viktor Dukhovni* + +* Disable SSLv2 default build, default negotiation and weak ciphers. SSLv2 + is by default disabled at build-time. Builds that are not configured with + "enable-ssl2" will not support SSLv2. Even if "enable-ssl2" is used, + users who want to negotiate SSLv2 via the version-flexible SSLv23_method() + will need to explicitly call either of: + + SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv2); + or + SSL_clear_options(ssl, SSL_OP_NO_SSLv2); + + as appropriate. Even if either of those is used, or the application + explicitly uses the version-specific SSLv2_method() or its client and + server variants, SSLv2 ciphers vulnerable to exhaustive search key + recovery have been removed. Specifically, the SSLv2 40-bit EXPORT + ciphers, and SSLv2 56-bit DES are no longer available. + ([CVE-2016-0800]) + + *Viktor Dukhovni* + + * Fix a double-free in DSA code + + A double free bug was discovered when OpenSSL parses malformed DSA private + keys and could lead to a DoS attack or memory corruption for applications + that receive DSA private keys from untrusted sources. This scenario is + considered rare. + + This issue was reported to OpenSSL by Adam Langley(Google/BoringSSL) using + libFuzzer. + ([CVE-2016-0705]) + + *Stephen Henson* + + * Disable SRP fake user seed to address a server memory leak. + + Add a new method SRP_VBASE_get1_by_user that handles the seed properly. + + SRP_VBASE_get_by_user had inconsistent memory management behaviour. + In order to fix an unavoidable memory leak, SRP_VBASE_get_by_user + was changed to ignore the "fake user" SRP seed, even if the seed + is configured. + + Users should use SRP_VBASE_get1_by_user instead. Note that in + SRP_VBASE_get1_by_user, caller must free the returned value. Note + also that even though configuring the SRP seed attempts to hide + invalid usernames by continuing the handshake with fake + credentials, this behaviour is not constant time and no strong + guarantees are made that the handshake is indistinguishable from + that of a valid user. + ([CVE-2016-0798]) + + *Emilia Käsper* + + * Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption + + In the BN_hex2bn function the number of hex digits is calculated using an + int value `i`. Later `bn_expand` is called with a value of `i * 4`. For + large values of `i` this can result in `bn_expand` not allocating any + memory because `i * 4` is negative. This can leave the internal BIGNUM data + field as NULL leading to a subsequent NULL ptr deref. For very large values + of `i`, the calculation `i * 4` could be a positive value smaller than `i`. + In this case memory is allocated to the internal BIGNUM data field, but it + is insufficiently sized leading to heap corruption. A similar issue exists + in BN_dec2bn. This could have security consequences if BN_hex2bn/BN_dec2bn + is ever called by user applications with very large untrusted hex/dec data. + This is anticipated to be a rare occurrence. + + All OpenSSL internal usage of these functions use data that is not expected + to be untrusted, e.g. config file data or application command line + arguments. If user developed applications generate config file data based + on untrusted data then it is possible that this could also lead to security + consequences. This is also anticipated to be rare. + + This issue was reported to OpenSSL by Guido Vranken. + ([CVE-2016-0797]) + + *Matt Caswell* + + * Fix memory issues in `BIO_*printf` functions + + The internal `fmtstr` function used in processing a "%s" format string in + the `BIO_*printf` functions could overflow while calculating the length of a + string and cause an OOB read when printing very long strings. + + Additionally the internal `doapr_outch` function can attempt to write to an + OOB memory location (at an offset from the NULL pointer) in the event of a + memory allocation failure. In 1.0.2 and below this could be caused where + the size of a buffer to be allocated is greater than INT_MAX. E.g. this + could be in processing a very long "%s" format string. Memory leaks can + also occur. + + The first issue may mask the second issue dependent on compiler behaviour. + These problems could enable attacks where large amounts of untrusted data + is passed to the `BIO_*printf` functions. If applications use these functions + in this way then they could be vulnerable. OpenSSL itself uses these + functions when printing out human-readable dumps of ASN.1 data. Therefore + applications that print this data could be vulnerable if the data is from + untrusted sources. OpenSSL command line applications could also be + vulnerable where they print out ASN.1 data, or if untrusted data is passed + as command line arguments. + + Libssl is not considered directly vulnerable. Additionally certificates etc + received via remote connections via libssl are also unlikely to be able to + trigger these issues because of message size limits enforced within libssl. + + This issue was reported to OpenSSL Guido Vranken. + ([CVE-2016-0799]) + + *Matt Caswell* + + * Side channel attack on modular exponentiation + + A side-channel attack was found which makes use of cache-bank conflicts on + the Intel Sandy-Bridge microarchitecture which could lead to the recovery + of RSA keys. The ability to exploit this issue is limited as it relies on + an attacker who has control of code in a thread running on the same + hyper-threaded core as the victim thread which is performing decryptions. + + This issue was reported to OpenSSL by Yuval Yarom, The University of + Adelaide and NICTA, Daniel Genkin, Technion and Tel Aviv University, and + Nadia Heninger, University of Pennsylvania with more information at + . + ([CVE-2016-0702]) + + *Andy Polyakov* + + * Change the req command to generate a 2048-bit RSA/DSA key by default, + if no keysize is specified with default_bits. This fixes an + omission in an earlier change that changed all RSA/DSA key generation + commands to use 2048 bits by default. + + *Emilia Käsper* + +### Changes between 1.0.1q and 1.0.1r [28 Jan 2016] + + * Protection for DH small subgroup attacks + + As a precautionary measure the SSL_OP_SINGLE_DH_USE option has been + switched on by default and cannot be disabled. This could have some + performance impact. + + *Matt Caswell* + + * SSLv2 doesn't block disabled ciphers + + A malicious client can negotiate SSLv2 ciphers that have been disabled on + the server and complete SSLv2 handshakes even if all SSLv2 ciphers have + been disabled, provided that the SSLv2 protocol was not also disabled via + SSL_OP_NO_SSLv2. + + This issue was reported to OpenSSL on 26th December 2015 by Nimrod Aviram + and Sebastian Schinzel. + ([CVE-2015-3197]) + + *Viktor Dukhovni* + + * Reject DH handshakes with parameters shorter than 1024 bits. + + *Kurt Roeckx* + +### Changes between 1.0.1p and 1.0.1q [3 Dec 2015] + + * Certificate verify crash with missing PSS parameter + + The signature verification routines will crash with a NULL pointer + dereference if presented with an ASN.1 signature using the RSA PSS + algorithm and absent mask generation function parameter. Since these + routines are used to verify certificate signature algorithms this can be + used to crash any certificate verification operation and exploited in a + DoS attack. Any application which performs certificate verification is + vulnerable including OpenSSL clients and servers which enable client + authentication. + + This issue was reported to OpenSSL by Loïc Jonas Etienne (Qnective AG). + ([CVE-2015-3194]) + + *Stephen Henson* + + * X509_ATTRIBUTE memory leak + + When presented with a malformed X509_ATTRIBUTE structure OpenSSL will leak + memory. This structure is used by the PKCS#7 and CMS routines so any + application which reads PKCS#7 or CMS data from untrusted sources is + affected. SSL/TLS is not affected. + + This issue was reported to OpenSSL by Adam Langley (Google/BoringSSL) using + libFuzzer. + ([CVE-2015-3195]) + + *Stephen Henson* + + * Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs. + This changes the decoding behaviour for some invalid messages, + though the change is mostly in the more lenient direction, and + legacy behaviour is preserved as much as possible. + + *Emilia Käsper* + + * In DSA_generate_parameters_ex, if the provided seed is too short, + use a random seed, as already documented. + + *Rich Salz and Ismo Puustinen * + +### Changes between 1.0.1o and 1.0.1p [9 Jul 2015] + + * Alternate chains certificate forgery + + During certificate verfification, OpenSSL will attempt to find an + alternative certificate chain if the first attempt to build such a chain + fails. An error in the implementation of this logic can mean that an + attacker could cause certain checks on untrusted certificates to be + bypassed, such as the CA flag, enabling them to use a valid leaf + certificate to act as a CA and "issue" an invalid certificate. + + This issue was reported to OpenSSL by Adam Langley/David Benjamin + (Google/BoringSSL). + ([CVE-2015-1793]) + + *Matt Caswell* + + * Race condition handling PSK identify hint + + If PSK identity hints are received by a multi-threaded client then + the values are wrongly updated in the parent SSL_CTX structure. This can + result in a race condition potentially leading to a double free of the + identify hint data. + ([CVE-2015-3196]) + + *Stephen Henson* + +### Changes between 1.0.1n and 1.0.1o [12 Jun 2015] + + * Fix HMAC ABI incompatibility. The previous version introduced an ABI + incompatibility in the handling of HMAC. The previous ABI has now been + restored. + +### Changes between 1.0.1m and 1.0.1n [11 Jun 2015] + + * Malformed ECParameters causes infinite loop + + When processing an ECParameters structure OpenSSL enters an infinite loop + if the curve specified is over a specially malformed binary polynomial + field. + + This can be used to perform denial of service against any + system which processes public keys, certificate requests or + certificates. This includes TLS clients and TLS servers with + client authentication enabled. + + This issue was reported to OpenSSL by Joseph Barr-Pixton. + ([CVE-2015-1788]) + + *Andy Polyakov* + + * Exploitable out-of-bounds read in X509_cmp_time + + X509_cmp_time does not properly check the length of the ASN1_TIME + string and can read a few bytes out of bounds. In addition, + X509_cmp_time accepts an arbitrary number of fractional seconds in the + time string. + + An attacker can use this to craft malformed certificates and CRLs of + various sizes and potentially cause a segmentation fault, resulting in + a DoS on applications that verify certificates or CRLs. TLS clients + that verify CRLs are affected. TLS clients and servers with client + authentication enabled may be affected if they use custom verification + callbacks. + + This issue was reported to OpenSSL by Robert Swiecki (Google), and + independently by Hanno Böck. + ([CVE-2015-1789]) + + *Emilia Käsper* + + * PKCS7 crash with missing EnvelopedContent + + The PKCS#7 parsing code does not handle missing inner EncryptedContent + correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs + with missing content and trigger a NULL pointer dereference on parsing. + + Applications that decrypt PKCS#7 data or otherwise parse PKCS#7 + structures from untrusted sources are affected. OpenSSL clients and + servers are not affected. + + This issue was reported to OpenSSL by Michal Zalewski (Google). + ([CVE-2015-1790]) + + *Emilia Käsper* + + * CMS verify infinite loop with unknown hash function + + When verifying a signedData message the CMS code can enter an infinite loop + if presented with an unknown hash function OID. This can be used to perform + denial of service against any system which verifies signedData messages using + the CMS code. + This issue was reported to OpenSSL by Johannes Bauer. + ([CVE-2015-1792]) + + *Stephen Henson* + + * Race condition handling NewSessionTicket + + If a NewSessionTicket is received by a multi-threaded client when attempting to + reuse a previous ticket then a race condition can occur potentially leading to + a double free of the ticket data. + ([CVE-2015-1791]) + + *Matt Caswell* + + * Reject DH handshakes with parameters shorter than 768 bits. + + *Kurt Roeckx and Emilia Kasper* + + * dhparam: generate 2048-bit parameters by default. + + *Kurt Roeckx and Emilia Kasper* + +### Changes between 1.0.1l and 1.0.1m [19 Mar 2015] + + * Segmentation fault in ASN1_TYPE_cmp fix + + The function ASN1_TYPE_cmp will crash with an invalid read if an attempt is + made to compare ASN.1 boolean types. Since ASN1_TYPE_cmp is used to check + certificate signature algorithm consistency this can be used to crash any + certificate verification operation and exploited in a DoS attack. Any + application which performs certificate verification is vulnerable including + OpenSSL clients and servers which enable client authentication. + ([CVE-2015-0286]) + + *Stephen Henson* + + * ASN.1 structure reuse memory corruption fix + + Reusing a structure in ASN.1 parsing may allow an attacker to cause + memory corruption via an invalid write. Such reuse is and has been + strongly discouraged and is believed to be rare. + + Applications that parse structures containing CHOICE or ANY DEFINED BY + components may be affected. Certificate parsing (d2i_X509 and related + functions) are however not affected. OpenSSL clients and servers are + not affected. + ([CVE-2015-0287]) + + *Stephen Henson* + + * PKCS7 NULL pointer dereferences fix + + The PKCS#7 parsing code does not handle missing outer ContentInfo + correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs with + missing content and trigger a NULL pointer dereference on parsing. + + Applications that verify PKCS#7 signatures, decrypt PKCS#7 data or + otherwise parse PKCS#7 structures from untrusted sources are + affected. OpenSSL clients and servers are not affected. + + This issue was reported to OpenSSL by Michal Zalewski (Google). + ([CVE-2015-0289]) + + *Emilia Käsper* + + * DoS via reachable assert in SSLv2 servers fix + + A malicious client can trigger an OPENSSL_assert (i.e., an abort) in + servers that both support SSLv2 and enable export cipher suites by sending + a specially crafted SSLv2 CLIENT-MASTER-KEY message. + + This issue was discovered by Sean Burford (Google) and Emilia Käsper + (OpenSSL development team). + ([CVE-2015-0293]) + + *Emilia Käsper* + + * Use After Free following d2i_ECPrivatekey error fix + + A malformed EC private key file consumed via the d2i_ECPrivateKey function + could cause a use after free condition. This, in turn, could cause a double + free in several private key parsing functions (such as d2i_PrivateKey + or EVP_PKCS82PKEY) and could lead to a DoS attack or memory corruption + for applications that receive EC private keys from untrusted + sources. This scenario is considered rare. + + This issue was discovered by the BoringSSL project and fixed in their + commit 517073cd4b. + ([CVE-2015-0209]) + + *Matt Caswell* + + * X509_to_X509_REQ NULL pointer deref fix + + The function X509_to_X509_REQ will crash with a NULL pointer dereference if + the certificate key is invalid. This function is rarely used in practice. + + This issue was discovered by Brian Carpenter. + ([CVE-2015-0288]) + + *Stephen Henson* + + * Removed the export ciphers from the DEFAULT ciphers + + *Kurt Roeckx* + +### Changes between 1.0.1k and 1.0.1l [15 Jan 2015] + + * Build fixes for the Windows and OpenVMS platforms + + *Matt Caswell and Richard Levitte* + +### Changes between 1.0.1j and 1.0.1k [8 Jan 2015] + + * Fix DTLS segmentation fault in dtls1_get_record. A carefully crafted DTLS + message can cause a segmentation fault in OpenSSL due to a NULL pointer + dereference. This could lead to a Denial Of Service attack. Thanks to + Markus Stenberg of Cisco Systems, Inc. for reporting this issue. + ([CVE-2014-3571]) + + *Steve Henson* + + * Fix DTLS memory leak in dtls1_buffer_record. A memory leak can occur in the + dtls1_buffer_record function under certain conditions. In particular this + could occur if an attacker sent repeated DTLS records with the same + sequence number but for the next epoch. The memory leak could be exploited + by an attacker in a Denial of Service attack through memory exhaustion. + Thanks to Chris Mueller for reporting this issue. + ([CVE-2015-0206]) + + *Matt Caswell* + + * Fix issue where no-ssl3 configuration sets method to NULL. When openssl is + built with the no-ssl3 option and a SSL v3 ClientHello is received the ssl + method would be set to NULL which could later result in a NULL pointer + dereference. Thanks to Frank Schmirler for reporting this issue. + ([CVE-2014-3569]) + + *Kurt Roeckx* + + * Abort handshake if server key exchange message is omitted for ephemeral + ECDH ciphersuites. + + Thanks to Karthikeyan Bhargavan of the PROSECCO team at INRIA for + reporting this issue. + ([CVE-2014-3572]) + + *Steve Henson* + + * Remove non-export ephemeral RSA code on client and server. This code + violated the TLS standard by allowing the use of temporary RSA keys in + non-export ciphersuites and could be used by a server to effectively + downgrade the RSA key length used to a value smaller than the server + certificate. Thanks for Karthikeyan Bhargavan of the PROSECCO team at + INRIA or reporting this issue. + ([CVE-2015-0204]) + + *Steve Henson* + + * Fixed issue where DH client certificates are accepted without verification. + An OpenSSL server will accept a DH certificate for client authentication + without the certificate verify message. This effectively allows a client to + authenticate without the use of a private key. This only affects servers + which trust a client certificate authority which issues certificates + containing DH keys: these are extremely rare and hardly ever encountered. + Thanks for Karthikeyan Bhargavan of the PROSECCO team at INRIA or reporting + this issue. + ([CVE-2015-0205]) + + *Steve Henson* + + * Ensure that the session ID context of an SSL is updated when its + SSL_CTX is updated via SSL_set_SSL_CTX. + + The session ID context is typically set from the parent SSL_CTX, + and can vary with the CTX. + + *Adam Langley* + + * Fix various certificate fingerprint issues. + + By using non-DER or invalid encodings outside the signed portion of a + certificate the fingerprint can be changed without breaking the signature. + Although no details of the signed portion of the certificate can be changed + this can cause problems with some applications: e.g. those using the + certificate fingerprint for blacklists. + + 1. Reject signatures with non zero unused bits. + + If the BIT STRING containing the signature has non zero unused bits reject + the signature. All current signature algorithms require zero unused bits. + + 2. Check certificate algorithm consistency. + + Check the AlgorithmIdentifier inside TBS matches the one in the + certificate signature. NB: this will result in signature failure + errors for some broken certificates. + + Thanks to Konrad Kraszewski from Google for reporting this issue. + + 3. Check DSA/ECDSA signatures use DER. + + Re-encode DSA/ECDSA signatures and compare with the original received + signature. Return an error if there is a mismatch. + + This will reject various cases including garbage after signature + (thanks to Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS + program for discovering this case) and use of BER or invalid ASN.1 INTEGERs + (negative or with leading zeroes). + + Further analysis was conducted and fixes were developed by Stephen Henson + of the OpenSSL core team. + + ([CVE-2014-8275]) + + *Steve Henson* + + * Correct Bignum squaring. Bignum squaring (BN_sqr) may produce incorrect + results on some platforms, including x86_64. This bug occurs at random + with a very low probability, and is not known to be exploitable in any + way, though its exact impact is difficult to determine. Thanks to Pieter + Wuille (Blockstream) who reported this issue and also suggested an initial + fix. Further analysis was conducted by the OpenSSL development team and + Adam Langley of Google. The final fix was developed by Andy Polyakov of + the OpenSSL core team. + ([CVE-2014-3570]) + + *Andy Polyakov* + + * Do not resume sessions on the server if the negotiated protocol + version does not match the session's version. Resuming with a different + version, while not strictly forbidden by the RFC, is of questionable + sanity and breaks all known clients. + + *David Benjamin, Emilia Käsper* + + * Tighten handling of the ChangeCipherSpec (CCS) message: reject + early CCS messages during renegotiation. (Note that because + renegotiation is encrypted, this early CCS was not exploitable.) + + *Emilia Käsper* + + * Tighten client-side session ticket handling during renegotiation: + ensure that the client only accepts a session ticket if the server sends + the extension anew in the ServerHello. Previously, a TLS client would + reuse the old extension state and thus accept a session ticket if one was + announced in the initial ServerHello. + + Similarly, ensure that the client requires a session ticket if one + was advertised in the ServerHello. Previously, a TLS client would + ignore a missing NewSessionTicket message. + + *Emilia Käsper* + +### Changes between 1.0.1i and 1.0.1j [15 Oct 2014] + + * SRTP Memory Leak. + + A flaw in the DTLS SRTP extension parsing code allows an attacker, who + sends a carefully crafted handshake message, to cause OpenSSL to fail + to free up to 64k of memory causing a memory leak. This could be + exploited in a Denial Of Service attack. This issue affects OpenSSL + 1.0.1 server implementations for both SSL/TLS and DTLS regardless of + whether SRTP is used or configured. Implementations of OpenSSL that + have been compiled with OPENSSL_NO_SRTP defined are not affected. + + The fix was developed by the OpenSSL team. + ([CVE-2014-3513]) + + *OpenSSL team* + + * Session Ticket Memory Leak. + + When an OpenSSL SSL/TLS/DTLS server receives a session ticket the + integrity of that ticket is first verified. In the event of a session + ticket integrity check failing, OpenSSL will fail to free memory + causing a memory leak. By sending a large number of invalid session + tickets an attacker could exploit this issue in a Denial Of Service + attack. + ([CVE-2014-3567]) + + *Steve Henson* + + * Build option no-ssl3 is incomplete. + + When OpenSSL is configured with "no-ssl3" as a build option, servers + could accept and complete a SSL 3.0 handshake, and clients could be + configured to send them. + ([CVE-2014-3568]) + + *Akamai and the OpenSSL team* + + * Add support for TLS_FALLBACK_SCSV. + Client applications doing fallback retries should call + SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV). + ([CVE-2014-3566]) + + *Adam Langley, Bodo Moeller* + + * Add additional DigestInfo checks. + + Re-encode DigestInto in DER and check against the original when + verifying RSA signature: this will reject any improperly encoded + DigestInfo structures. + + Note: this is a precautionary measure and no attacks are currently known. + + *Steve Henson* + +### Changes between 1.0.1h and 1.0.1i [6 Aug 2014] + + * Fix SRP buffer overrun vulnerability. Invalid parameters passed to the + SRP code can be overrun an internal buffer. Add sanity check that + g, A, B < N to SRP code. + + Thanks to Sean Devlin and Watson Ladd of Cryptography Services, NCC + Group for discovering this issue. + ([CVE-2014-3512]) + + *Steve Henson* + + * A flaw in the OpenSSL SSL/TLS server code causes the server to negotiate + TLS 1.0 instead of higher protocol versions when the ClientHello message + is badly fragmented. This allows a man-in-the-middle attacker to force a + downgrade to TLS 1.0 even if both the server and the client support a + higher protocol version, by modifying the client's TLS records. + + Thanks to David Benjamin and Adam Langley (Google) for discovering and + researching this issue. + ([CVE-2014-3511]) + + *David Benjamin* + + * OpenSSL DTLS clients enabling anonymous (EC)DH ciphersuites are subject + to a denial of service attack. A malicious server can crash the client + with a null pointer dereference (read) by specifying an anonymous (EC)DH + ciphersuite and sending carefully crafted handshake messages. + + Thanks to Felix Gröbert (Google) for discovering and researching this + issue. + ([CVE-2014-3510]) + + *Emilia Käsper* + + * By sending carefully crafted DTLS packets an attacker could cause openssl + to leak memory. This can be exploited through a Denial of Service attack. + Thanks to Adam Langley for discovering and researching this issue. + ([CVE-2014-3507]) + + *Adam Langley* + + * An attacker can force openssl to consume large amounts of memory whilst + processing DTLS handshake messages. This can be exploited through a + Denial of Service attack. + Thanks to Adam Langley for discovering and researching this issue. + ([CVE-2014-3506]) + + *Adam Langley* + + * An attacker can force an error condition which causes openssl to crash + whilst processing DTLS packets due to memory being freed twice. This + can be exploited through a Denial of Service attack. + Thanks to Adam Langley and Wan-Teh Chang for discovering and researching + this issue. + ([CVE-2014-3505]) + + *Adam Langley* + + * If a multithreaded client connects to a malicious server using a resumed + session and the server sends an ec point format extension it could write + up to 255 bytes to freed memory. + + Thanks to Gabor Tyukasz (LogMeIn Inc) for discovering and researching this + issue. + ([CVE-2014-3509]) + + *Gabor Tyukasz* + + * A malicious server can crash an OpenSSL client with a null pointer + dereference (read) by specifying an SRP ciphersuite even though it was not + properly negotiated with the client. This can be exploited through a + Denial of Service attack. + + Thanks to Joonas Kuorilehto and Riku Hietamäki (Codenomicon) for + discovering and researching this issue. + ([CVE-2014-5139]) + + *Steve Henson* + + * A flaw in OBJ_obj2txt may cause pretty printing functions such as + X509_name_oneline, X509_name_print_ex et al. to leak some information + from the stack. Applications may be affected if they echo pretty printing + output to the attacker. + + Thanks to Ivan Fratric (Google) for discovering this issue. + ([CVE-2014-3508]) + + *Emilia Käsper, and Steve Henson* + + * Fix ec_GFp_simple_points_make_affine (thus, EC_POINTs_mul etc.) + for corner cases. (Certain input points at infinity could lead to + bogus results, with non-infinity inputs mapped to infinity too.) + + *Bodo Moeller* + +### Changes between 1.0.1g and 1.0.1h [5 Jun 2014] + + * Fix for SSL/TLS MITM flaw. An attacker using a carefully crafted + handshake can force the use of weak keying material in OpenSSL + SSL/TLS clients and servers. + + Thanks to KIKUCHI Masashi (Lepidum Co. Ltd.) for discovering and + researching this issue. ([CVE-2014-0224]) + + *KIKUCHI Masashi, Steve Henson* + + * Fix DTLS recursion flaw. By sending an invalid DTLS handshake to an + OpenSSL DTLS client the code can be made to recurse eventually crashing + in a DoS attack. + + Thanks to Imre Rad (Search-Lab Ltd.) for discovering this issue. + ([CVE-2014-0221]) + + *Imre Rad, Steve Henson* + + * Fix DTLS invalid fragment vulnerability. A buffer overrun attack can + be triggered by sending invalid DTLS fragments to an OpenSSL DTLS + client or server. This is potentially exploitable to run arbitrary + code on a vulnerable client or server. + + Thanks to Jüri Aedla for reporting this issue. ([CVE-2014-0195]) + + *Jüri Aedla, Steve Henson* + + * Fix bug in TLS code where clients enable anonymous ECDH ciphersuites + are subject to a denial of service attack. + + Thanks to Felix Gröbert and Ivan Fratric at Google for discovering + this issue. ([CVE-2014-3470]) + + *Felix Gröbert, Ivan Fratric, Steve Henson* + + * Harmonize version and its documentation. -f flag is used to display + compilation flags. + + *mancha * + + * Fix eckey_priv_encode so it immediately returns an error upon a failure + in i2d_ECPrivateKey. + + *mancha * + + * Fix some double frees. These are not thought to be exploitable. + + *mancha * + +### Changes between 1.0.1f and 1.0.1g [7 Apr 2014] + + * A missing bounds check in the handling of the TLS heartbeat extension + can be used to reveal up to 64k of memory to a connected client or + server. + + Thanks for Neel Mehta of Google Security for discovering this bug and to + Adam Langley and Bodo Moeller for + preparing the fix ([CVE-2014-0160]) + + *Adam Langley, Bodo Moeller* + + * Fix for the attack described in the paper "Recovering OpenSSL + ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack" + by Yuval Yarom and Naomi Benger. Details can be obtained from: + + + Thanks to Yuval Yarom and Naomi Benger for discovering this + flaw and to Yuval Yarom for supplying a fix ([CVE-2014-0076]) + + *Yuval Yarom and Naomi Benger* + + * TLS pad extension: draft-agl-tls-padding-03 + + Workaround for the "TLS hang bug" (see FAQ and PR#2771): if the + TLS client Hello record length value would otherwise be > 255 and + less that 512 pad with a dummy extension containing zeroes so it + is at least 512 bytes long. + + *Adam Langley, Steve Henson* + +### Changes between 1.0.1e and 1.0.1f [6 Jan 2014] + + * Fix for TLS record tampering bug. A carefully crafted invalid + handshake could crash OpenSSL with a NULL pointer exception. + Thanks to Anton Johansson for reporting this issues. + ([CVE-2013-4353]) + + * Keep original DTLS digest and encryption contexts in retransmission + structures so we can use the previous session parameters if they need + to be resent. ([CVE-2013-6450]) + + *Steve Henson* + + * Add option SSL_OP_SAFARI_ECDHE_ECDSA_BUG (part of SSL_OP_ALL) which + avoids preferring ECDHE-ECDSA ciphers when the client appears to be + Safari on OS X. Safari on OS X 10.8..10.8.3 advertises support for + several ECDHE-ECDSA ciphers, but fails to negotiate them. The bug + is fixed in OS X 10.8.4, but Apple have ruled out both hot fixing + 10.8..10.8.3 and forcing users to upgrade to 10.8.4 or newer. + + *Rob Stradling, Adam Langley* + +### Changes between 1.0.1d and 1.0.1e [11 Feb 2013] + + * Correct fix for CVE-2013-0169. The original didn't work on AES-NI + supporting platforms or when small records were transferred. + + *Andy Polyakov, Steve Henson* + +### Changes between 1.0.1c and 1.0.1d [5 Feb 2013] + + * Make the decoding of SSLv3, TLS and DTLS CBC records constant time. + + This addresses the flaw in CBC record processing discovered by + Nadhem Alfardan and Kenny Paterson. Details of this attack can be found + at: + + Thanks go to Nadhem Alfardan and Kenny Paterson of the Information + Security Group at Royal Holloway, University of London + (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and + Emilia Käsper for the initial patch. + ([CVE-2013-0169]) + + *Emilia Käsper, Adam Langley, Ben Laurie, Andy Polyakov, Steve Henson* + + * Fix flaw in AESNI handling of TLS 1.2 and 1.1 records for CBC mode + ciphersuites which can be exploited in a denial of service attack. + Thanks go to and to Adam Langley for discovering + and detecting this bug and to Wolfgang Ettlinger + for independently discovering this issue. + ([CVE-2012-2686]) + + *Adam Langley* + + * Return an error when checking OCSP signatures when key is NULL. + This fixes a DoS attack. ([CVE-2013-0166]) + + *Steve Henson* + + * Make openssl verify return errors. + + *Chris Palmer and Ben Laurie* + + * Call OCSP Stapling callback after ciphersuite has been chosen, so + the right response is stapled. Also change SSL_get_certificate() + so it returns the certificate actually sent. + See . + + *Rob Stradling * + + * Fix possible deadlock when decoding public keys. + + *Steve Henson* + + * Don't use TLS 1.0 record version number in initial client hello + if renegotiating. + + *Steve Henson* + +### Changes between 1.0.1b and 1.0.1c [10 May 2012] + + * Sanity check record length before skipping explicit IV in TLS + 1.2, 1.1 and DTLS to fix DoS attack. + + Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic + fuzzing as a service testing platform. + ([CVE-2012-2333]) + + *Steve Henson* + + * Initialise tkeylen properly when encrypting CMS messages. + Thanks to Solar Designer of Openwall for reporting this issue. + + *Steve Henson* + + * In FIPS mode don't try to use composite ciphers as they are not + approved. + + *Steve Henson* + +### Changes between 1.0.1a and 1.0.1b [26 Apr 2012] + + * OpenSSL 1.0.0 sets SSL_OP_ALL to 0x80000FFFL and OpenSSL 1.0.1 and + 1.0.1a set SSL_OP_NO_TLSv1_1 to 0x00000400L which would unfortunately + mean any application compiled against OpenSSL 1.0.0 headers setting + SSL_OP_ALL would also set SSL_OP_NO_TLSv1_1, unintentionally disabling + TLS 1.1 also. Fix this by changing the value of SSL_OP_NO_TLSv1_1 to + 0x10000000L Any application which was previously compiled against + OpenSSL 1.0.1 or 1.0.1a headers and which cares about SSL_OP_NO_TLSv1_1 + will need to be recompiled as a result. Letting be results in + inability to disable specifically TLS 1.1 and in client context, + in unlike event, limit maximum offered version to TLS 1.0 [see below]. + + *Steve Henson* + + * In order to ensure interoperability SSL_OP_NO_protocolX does not + disable just protocol X, but all protocols above X *if* there are + protocols *below* X still enabled. In more practical terms it means + that if application wants to disable TLS1.0 in favor of TLS1.1 and + above, it's not sufficient to pass `SSL_OP_NO_TLSv1`, one has to pass + `SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2`. This applies to + client side. + + *Andy Polyakov* + +### Changes between 1.0.1 and 1.0.1a [19 Apr 2012] + + * Check for potentially exploitable overflows in asn1_d2i_read_bio + BUF_mem_grow and BUF_mem_grow_clean. Refuse attempts to shrink buffer + in CRYPTO_realloc_clean. + + Thanks to Tavis Ormandy, Google Security Team, for discovering this + issue and to Adam Langley for fixing it. + ([CVE-2012-2110]) + + *Adam Langley (Google), Tavis Ormandy, Google Security Team* + + * Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections. + + *Adam Langley* + + * Workarounds for some broken servers that "hang" if a client hello + record length exceeds 255 bytes. + + 1. Do not use record version number > TLS 1.0 in initial client + hello: some (but not all) hanging servers will now work. + 2. If we set OPENSSL_MAX_TLS1_2_CIPHER_LENGTH this will truncate + the number of ciphers sent in the client hello. This should be + set to an even number, such as 50, for example by passing: + -DOPENSSL_MAX_TLS1_2_CIPHER_LENGTH=50 to config or Configure. + Most broken servers should now work. + 3. If all else fails setting OPENSSL_NO_TLS1_2_CLIENT will disable + TLS 1.2 client support entirely. + + *Steve Henson* + + * Fix SEGV in Vector Permutation AES module observed in OpenSSH. + + *Andy Polyakov* + +### Changes between 1.0.0h and 1.0.1 [14 Mar 2012] + + * Add compatibility with old MDC2 signatures which use an ASN1 OCTET + STRING form instead of a DigestInfo. + + *Steve Henson* + + * The format used for MDC2 RSA signatures is inconsistent between EVP + and the RSA_sign/RSA_verify functions. This was made more apparent when + OpenSSL used RSA_sign/RSA_verify for some RSA signatures in particular + those which went through EVP_PKEY_METHOD in 1.0.0 and later. Detect + the correct format in RSA_verify so both forms transparently work. + + *Steve Henson* + + * Some servers which support TLS 1.0 can choke if we initially indicate + support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA + encrypted premaster secret. As a workaround use the maximum permitted + client version in client hello, this should keep such servers happy + and still work with previous versions of OpenSSL. + + *Steve Henson* + + * Add support for TLS/DTLS heartbeats. + + *Robin Seggelmann * + + * Add support for SCTP. + + *Robin Seggelmann * + + * Improved PRNG seeding for VOS. + + *Paul Green * + + * Extensive assembler packs updates, most notably: + + - x86[_64]: AES-NI, PCLMULQDQ, RDRAND support; + - x86[_64]: SSSE3 support (SHA1, vector-permutation AES); + - x86_64: bit-sliced AES implementation; + - ARM: NEON support, contemporary platforms optimizations; + - s390x: z196 support; + - `*`: GHASH and GF(2^m) multiplication implementations; + + *Andy Polyakov* + + * Make TLS-SRP code conformant with RFC 5054 API cleanup + (removal of unnecessary code) + + *Peter Sylvester * + + * Add TLS key material exporter from RFC 5705. + + *Eric Rescorla* + + * Add DTLS-SRTP negotiation from RFC 5764. + + *Eric Rescorla* + + * Add Next Protocol Negotiation, + . Can be + disabled with a no-npn flag to config or Configure. Code donated + by Google. + + *Adam Langley and Ben Laurie* + + * Add optional 64-bit optimized implementations of elliptic curves NIST-P224, + NIST-P256, NIST-P521, with constant-time single point multiplication on + typical inputs. Compiler support for the nonstandard type `__uint128_t` is + required to use this (present in gcc 4.4 and later, for 64-bit builds). + Code made available under Apache License version 2.0. + + Specify "enable-ec_nistp_64_gcc_128" on the Configure (or config) command + line to include this in your build of OpenSSL, and run "make depend" (or + "make update"). This enables the following EC_METHODs: + + EC_GFp_nistp224_method() + EC_GFp_nistp256_method() + EC_GFp_nistp521_method() + + EC_GROUP_new_by_curve_name() will automatically use these (while + EC_GROUP_new_curve_GFp() currently prefers the more flexible + implementations). + + *Emilia Käsper, Adam Langley, Bodo Moeller (Google)* + + * Use type ossl_ssize_t instead of ssize_t which isn't available on + all platforms. Move ssize_t definition from e_os.h to the public + header file e_os2.h as it now appears in public header file cms.h + + *Steve Henson* + + * New -sigopt option to the ca, req and x509 utilities. Additional + signature parameters can be passed using this option and in + particular PSS. + + *Steve Henson* + + * Add RSA PSS signing function. This will generate and set the + appropriate AlgorithmIdentifiers for PSS based on those in the + corresponding EVP_MD_CTX structure. No application support yet. + + *Steve Henson* + + * Support for companion algorithm specific ASN1 signing routines. + New function ASN1_item_sign_ctx() signs a pre-initialised + EVP_MD_CTX structure and sets AlgorithmIdentifiers based on + the appropriate parameters. + + *Steve Henson* + + * Add new algorithm specific ASN1 verification initialisation function + to EVP_PKEY_ASN1_METHOD: this is not in EVP_PKEY_METHOD since the ASN1 + handling will be the same no matter what EVP_PKEY_METHOD is used. + Add a PSS handler to support verification of PSS signatures: checked + against a number of sample certificates. + + *Steve Henson* + + * Add signature printing for PSS. Add PSS OIDs. + + *Steve Henson, Martin Kaiser * + + * Add algorithm specific signature printing. An individual ASN1 method + can now print out signatures instead of the standard hex dump. + + More complex signatures (e.g. PSS) can print out more meaningful + information. Include DSA version that prints out the signature + parameters r, s. + + *Steve Henson* + + * Password based recipient info support for CMS library: implementing + RFC3211. + + *Steve Henson* + + * Split password based encryption into PBES2 and PBKDF2 functions. This + neatly separates the code into cipher and PBE sections and is required + for some algorithms that split PBES2 into separate pieces (such as + password based CMS). + + *Steve Henson* + + * Session-handling fixes: + - Fix handling of connections that are resuming with a session ID, + but also support Session Tickets. + - Fix a bug that suppressed issuing of a new ticket if the client + presented a ticket with an expired session. + - Try to set the ticket lifetime hint to something reasonable. + - Make tickets shorter by excluding irrelevant information. + - On the client side, don't ignore renewed tickets. + + *Adam Langley, Bodo Moeller (Google)* + + * Fix PSK session representation. + + *Bodo Moeller* + + * Add RC4-MD5 and AESNI-SHA1 "stitched" implementations. + + This work was sponsored by Intel. + + *Andy Polyakov* + + * Add GCM support to TLS library. Some custom code is needed to split + the IV between the fixed (from PRF) and explicit (from TLS record) + portions. This adds all GCM ciphersuites supported by RFC5288 and + RFC5289. Generalise some `AES*` cipherstrings to include GCM and + add a special AESGCM string for GCM only. + + *Steve Henson* + + * Expand range of ctrls for AES GCM. Permit setting invocation + field on decrypt and retrieval of invocation field only on encrypt. + + *Steve Henson* + + * Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support. + As required by RFC5289 these ciphersuites cannot be used if for + versions of TLS earlier than 1.2. + + *Steve Henson* + + * For FIPS capable OpenSSL interpret a NULL default public key method + as unset and return the appropriate default but do *not* set the default. + This means we can return the appropriate method in applications that + switch between FIPS and non-FIPS modes. + + *Steve Henson* + + * Redirect HMAC and CMAC operations to FIPS module in FIPS mode. If an + ENGINE is used then we cannot handle that in the FIPS module so we + keep original code iff non-FIPS operations are allowed. + + *Steve Henson* + + * Add -attime option to openssl utilities. + + *Peter Eckersley , Ben Laurie and Steve Henson* + + * Redirect DSA and DH operations to FIPS module in FIPS mode. + + *Steve Henson* + + * Redirect ECDSA and ECDH operations to FIPS module in FIPS mode. Also use + FIPS EC methods unconditionally for now. + + *Steve Henson* + + * New build option no-ec2m to disable characteristic 2 code. + + *Steve Henson* + + * Backport libcrypto audit of return value checking from 1.1.0-dev; not + all cases can be covered as some introduce binary incompatibilities. + + *Steve Henson* + + * Redirect RSA operations to FIPS module including keygen, + encrypt, decrypt, sign and verify. Block use of non FIPS RSA methods. + + *Steve Henson* + + * Add similar low-level API blocking to ciphers. + + *Steve Henson* + + * low-level digest APIs are not approved in FIPS mode: any attempt + to use these will cause a fatal error. Applications that *really* want + to use them can use the `private_*` version instead. + + *Steve Henson* + + * Redirect cipher operations to FIPS module for FIPS builds. + + *Steve Henson* + + * Redirect digest operations to FIPS module for FIPS builds. + + *Steve Henson* + + * Update build system to add "fips" flag which will link in fipscanister.o + for static and shared library builds embedding a signature if needed. + + *Steve Henson* + + * Output TLS supported curves in preference order instead of numerical + order. This is currently hardcoded for the highest order curves first. + This should be configurable so applications can judge speed vs strength. + + *Steve Henson* + + * Add TLS v1.2 server support for client authentication. + + *Steve Henson* + + * Add support for FIPS mode in ssl library: disable SSLv3, non-FIPS ciphers + and enable MD5. + + *Steve Henson* + + * Functions FIPS_mode_set() and FIPS_mode() which call the underlying + FIPS modules versions. + + *Steve Henson* + + * Add TLS v1.2 client side support for client authentication. Keep cache + of handshake records longer as we don't know the hash algorithm to use + until after the certificate request message is received. + + *Steve Henson* + + * Initial TLS v1.2 client support. Add a default signature algorithms + extension including all the algorithms we support. Parse new signature + format in client key exchange. Relax some ECC signing restrictions for + TLS v1.2 as indicated in RFC5246. + + *Steve Henson* + + * Add server support for TLS v1.2 signature algorithms extension. Switch + to new signature format when needed using client digest preference. + All server ciphersuites should now work correctly in TLS v1.2. No client + support yet and no support for client certificates. + + *Steve Henson* + + * Initial TLS v1.2 support. Add new SHA256 digest to ssl code, switch + to SHA256 for PRF when using TLS v1.2 and later. Add new SHA256 based + ciphersuites. At present only RSA key exchange ciphersuites work with + TLS v1.2. Add new option for TLS v1.2 replacing the old and obsolete + SSL_OP_PKCS1_CHECK flags with SSL_OP_NO_TLSv1_2. New TLSv1.2 methods + and version checking. + + *Steve Henson* + + * New option OPENSSL_NO_SSL_INTERN. If an application can be compiled + with this defined it will not be affected by any changes to ssl internal + structures. Add several utility functions to allow openssl application + to work with OPENSSL_NO_SSL_INTERN defined. + + *Steve Henson* + + * A long standing patch to add support for SRP from EdelWeb (Peter + Sylvester and Christophe Renou) was integrated. + *Christophe Renou , Peter Sylvester + , Tom Wu , and + Ben Laurie* + + * Add functions to copy EVP_PKEY_METHOD and retrieve flags and id. + + *Steve Henson* + + * Permit abbreviated handshakes when renegotiating using the function + SSL_renegotiate_abbreviated(). + + *Robin Seggelmann * + + * Add call to ENGINE_register_all_complete() to + ENGINE_load_builtin_engines(), so some implementations get used + automatically instead of needing explicit application support. + + *Steve Henson* + + * Add support for TLS key exporter as described in RFC5705. + + *Robin Seggelmann , Steve Henson* + + * Initial TLSv1.1 support. Since TLSv1.1 is very similar to TLS v1.0 only + a few changes are required: + + Add SSL_OP_NO_TLSv1_1 flag. + Add TLSv1_1 methods. + Update version checking logic to handle version 1.1. + Add explicit IV handling (ported from DTLS code). + Add command line options to s_client/s_server. + + *Steve Henson* + +OpenSSL 1.0.0 +------------- + +### Changes between 1.0.0s and 1.0.0t [3 Dec 2015] + + * X509_ATTRIBUTE memory leak + + When presented with a malformed X509_ATTRIBUTE structure OpenSSL will leak + memory. This structure is used by the PKCS#7 and CMS routines so any + application which reads PKCS#7 or CMS data from untrusted sources is + affected. SSL/TLS is not affected. + + This issue was reported to OpenSSL by Adam Langley (Google/BoringSSL) using + libFuzzer. + ([CVE-2015-3195]) + + *Stephen Henson* + + * Race condition handling PSK identify hint + + If PSK identity hints are received by a multi-threaded client then + the values are wrongly updated in the parent SSL_CTX structure. This can + result in a race condition potentially leading to a double free of the + identify hint data. + ([CVE-2015-3196]) + + *Stephen Henson* + +### Changes between 1.0.0r and 1.0.0s [11 Jun 2015] + + * Malformed ECParameters causes infinite loop + + When processing an ECParameters structure OpenSSL enters an infinite loop + if the curve specified is over a specially malformed binary polynomial + field. + + This can be used to perform denial of service against any + system which processes public keys, certificate requests or + certificates. This includes TLS clients and TLS servers with + client authentication enabled. + + This issue was reported to OpenSSL by Joseph Barr-Pixton. + ([CVE-2015-1788]) + + *Andy Polyakov* + + * Exploitable out-of-bounds read in X509_cmp_time + + X509_cmp_time does not properly check the length of the ASN1_TIME + string and can read a few bytes out of bounds. In addition, + X509_cmp_time accepts an arbitrary number of fractional seconds in the + time string. + + An attacker can use this to craft malformed certificates and CRLs of + various sizes and potentially cause a segmentation fault, resulting in + a DoS on applications that verify certificates or CRLs. TLS clients + that verify CRLs are affected. TLS clients and servers with client + authentication enabled may be affected if they use custom verification + callbacks. + + This issue was reported to OpenSSL by Robert Swiecki (Google), and + independently by Hanno Böck. + ([CVE-2015-1789]) + + *Emilia Käsper* + + * PKCS7 crash with missing EnvelopedContent + + The PKCS#7 parsing code does not handle missing inner EncryptedContent + correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs + with missing content and trigger a NULL pointer dereference on parsing. + + Applications that decrypt PKCS#7 data or otherwise parse PKCS#7 + structures from untrusted sources are affected. OpenSSL clients and + servers are not affected. + + This issue was reported to OpenSSL by Michal Zalewski (Google). + ([CVE-2015-1790]) + + *Emilia Käsper* + + * CMS verify infinite loop with unknown hash function + + When verifying a signedData message the CMS code can enter an infinite loop + if presented with an unknown hash function OID. This can be used to perform + denial of service against any system which verifies signedData messages using + the CMS code. + This issue was reported to OpenSSL by Johannes Bauer. + ([CVE-2015-1792]) + + *Stephen Henson* + + * Race condition handling NewSessionTicket + + If a NewSessionTicket is received by a multi-threaded client when attempting to + reuse a previous ticket then a race condition can occur potentially leading to + a double free of the ticket data. + ([CVE-2015-1791]) + + *Matt Caswell* + +### Changes between 1.0.0q and 1.0.0r [19 Mar 2015] + + * Segmentation fault in ASN1_TYPE_cmp fix + + The function ASN1_TYPE_cmp will crash with an invalid read if an attempt is + made to compare ASN.1 boolean types. Since ASN1_TYPE_cmp is used to check + certificate signature algorithm consistency this can be used to crash any + certificate verification operation and exploited in a DoS attack. Any + application which performs certificate verification is vulnerable including + OpenSSL clients and servers which enable client authentication. + ([CVE-2015-0286]) + + *Stephen Henson* + + * ASN.1 structure reuse memory corruption fix + + Reusing a structure in ASN.1 parsing may allow an attacker to cause + memory corruption via an invalid write. Such reuse is and has been + strongly discouraged and is believed to be rare. + + Applications that parse structures containing CHOICE or ANY DEFINED BY + components may be affected. Certificate parsing (d2i_X509 and related + functions) are however not affected. OpenSSL clients and servers are + not affected. + ([CVE-2015-0287]) + + *Stephen Henson* + + * PKCS7 NULL pointer dereferences fix + + The PKCS#7 parsing code does not handle missing outer ContentInfo + correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs with + missing content and trigger a NULL pointer dereference on parsing. + + Applications that verify PKCS#7 signatures, decrypt PKCS#7 data or + otherwise parse PKCS#7 structures from untrusted sources are + affected. OpenSSL clients and servers are not affected. + + This issue was reported to OpenSSL by Michal Zalewski (Google). + ([CVE-2015-0289]) + + *Emilia Käsper* + + * DoS via reachable assert in SSLv2 servers fix + + A malicious client can trigger an OPENSSL_assert (i.e., an abort) in + servers that both support SSLv2 and enable export cipher suites by sending + a specially crafted SSLv2 CLIENT-MASTER-KEY message. + + This issue was discovered by Sean Burford (Google) and Emilia Käsper + (OpenSSL development team). + ([CVE-2015-0293]) + + *Emilia Käsper* + + * Use After Free following d2i_ECPrivatekey error fix + + A malformed EC private key file consumed via the d2i_ECPrivateKey function + could cause a use after free condition. This, in turn, could cause a double + free in several private key parsing functions (such as d2i_PrivateKey + or EVP_PKCS82PKEY) and could lead to a DoS attack or memory corruption + for applications that receive EC private keys from untrusted + sources. This scenario is considered rare. + + This issue was discovered by the BoringSSL project and fixed in their + commit 517073cd4b. + ([CVE-2015-0209]) + + *Matt Caswell* + + * X509_to_X509_REQ NULL pointer deref fix + + The function X509_to_X509_REQ will crash with a NULL pointer dereference if + the certificate key is invalid. This function is rarely used in practice. + + This issue was discovered by Brian Carpenter. + ([CVE-2015-0288]) + + *Stephen Henson* + + * Removed the export ciphers from the DEFAULT ciphers + + *Kurt Roeckx* + +### Changes between 1.0.0p and 1.0.0q [15 Jan 2015] + + * Build fixes for the Windows and OpenVMS platforms + + *Matt Caswell and Richard Levitte* + +### Changes between 1.0.0o and 1.0.0p [8 Jan 2015] + + * Fix DTLS segmentation fault in dtls1_get_record. A carefully crafted DTLS + message can cause a segmentation fault in OpenSSL due to a NULL pointer + dereference. This could lead to a Denial Of Service attack. Thanks to + Markus Stenberg of Cisco Systems, Inc. for reporting this issue. + ([CVE-2014-3571]) + + *Steve Henson* + + * Fix DTLS memory leak in dtls1_buffer_record. A memory leak can occur in the + dtls1_buffer_record function under certain conditions. In particular this + could occur if an attacker sent repeated DTLS records with the same + sequence number but for the next epoch. The memory leak could be exploited + by an attacker in a Denial of Service attack through memory exhaustion. + Thanks to Chris Mueller for reporting this issue. + ([CVE-2015-0206]) + + *Matt Caswell* + + * Fix issue where no-ssl3 configuration sets method to NULL. When openssl is + built with the no-ssl3 option and a SSL v3 ClientHello is received the ssl + method would be set to NULL which could later result in a NULL pointer + dereference. Thanks to Frank Schmirler for reporting this issue. + ([CVE-2014-3569]) + + *Kurt Roeckx* + + * Abort handshake if server key exchange message is omitted for ephemeral + ECDH ciphersuites. + + Thanks to Karthikeyan Bhargavan of the PROSECCO team at INRIA for + reporting this issue. + ([CVE-2014-3572]) + + *Steve Henson* + + * Remove non-export ephemeral RSA code on client and server. This code + violated the TLS standard by allowing the use of temporary RSA keys in + non-export ciphersuites and could be used by a server to effectively + downgrade the RSA key length used to a value smaller than the server + certificate. Thanks for Karthikeyan Bhargavan of the PROSECCO team at + INRIA or reporting this issue. + ([CVE-2015-0204]) + + *Steve Henson* + + * Fixed issue where DH client certificates are accepted without verification. + An OpenSSL server will accept a DH certificate for client authentication + without the certificate verify message. This effectively allows a client to + authenticate without the use of a private key. This only affects servers + which trust a client certificate authority which issues certificates + containing DH keys: these are extremely rare and hardly ever encountered. + Thanks for Karthikeyan Bhargavan of the PROSECCO team at INRIA or reporting + this issue. + ([CVE-2015-0205]) + + *Steve Henson* + + * Correct Bignum squaring. Bignum squaring (BN_sqr) may produce incorrect + results on some platforms, including x86_64. This bug occurs at random + with a very low probability, and is not known to be exploitable in any + way, though its exact impact is difficult to determine. Thanks to Pieter + Wuille (Blockstream) who reported this issue and also suggested an initial + fix. Further analysis was conducted by the OpenSSL development team and + Adam Langley of Google. The final fix was developed by Andy Polyakov of + the OpenSSL core team. + ([CVE-2014-3570]) + + *Andy Polyakov* + + * Fix various certificate fingerprint issues. + + By using non-DER or invalid encodings outside the signed portion of a + certificate the fingerprint can be changed without breaking the signature. + Although no details of the signed portion of the certificate can be changed + this can cause problems with some applications: e.g. those using the + certificate fingerprint for blacklists. + + 1. Reject signatures with non zero unused bits. + + If the BIT STRING containing the signature has non zero unused bits reject + the signature. All current signature algorithms require zero unused bits. + + 2. Check certificate algorithm consistency. + + Check the AlgorithmIdentifier inside TBS matches the one in the + certificate signature. NB: this will result in signature failure + errors for some broken certificates. + + Thanks to Konrad Kraszewski from Google for reporting this issue. + + 3. Check DSA/ECDSA signatures use DER. + + Reencode DSA/ECDSA signatures and compare with the original received + signature. Return an error if there is a mismatch. + + This will reject various cases including garbage after signature + (thanks to Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS + program for discovering this case) and use of BER or invalid ASN.1 INTEGERs + (negative or with leading zeroes). + + Further analysis was conducted and fixes were developed by Stephen Henson + of the OpenSSL core team. + + ([CVE-2014-8275]) + + *Steve Henson* + +### Changes between 1.0.0n and 1.0.0o [15 Oct 2014] + + * Session Ticket Memory Leak. + + When an OpenSSL SSL/TLS/DTLS server receives a session ticket the + integrity of that ticket is first verified. In the event of a session + ticket integrity check failing, OpenSSL will fail to free memory + causing a memory leak. By sending a large number of invalid session + tickets an attacker could exploit this issue in a Denial Of Service + attack. + ([CVE-2014-3567]) + + *Steve Henson* + + * Build option no-ssl3 is incomplete. + + When OpenSSL is configured with "no-ssl3" as a build option, servers + could accept and complete a SSL 3.0 handshake, and clients could be + configured to send them. + ([CVE-2014-3568]) + + *Akamai and the OpenSSL team* + + * Add support for TLS_FALLBACK_SCSV. + Client applications doing fallback retries should call + SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV). + ([CVE-2014-3566]) + + *Adam Langley, Bodo Moeller* + + * Add additional DigestInfo checks. + + Reencode DigestInto in DER and check against the original when + verifying RSA signature: this will reject any improperly encoded + DigestInfo structures. + + Note: this is a precautionary measure and no attacks are currently known. + + *Steve Henson* + +### Changes between 1.0.0m and 1.0.0n [6 Aug 2014] + + * OpenSSL DTLS clients enabling anonymous (EC)DH ciphersuites are subject + to a denial of service attack. A malicious server can crash the client + with a null pointer dereference (read) by specifying an anonymous (EC)DH + ciphersuite and sending carefully crafted handshake messages. + + Thanks to Felix Gröbert (Google) for discovering and researching this + issue. + ([CVE-2014-3510]) + + *Emilia Käsper* + + * By sending carefully crafted DTLS packets an attacker could cause openssl + to leak memory. This can be exploited through a Denial of Service attack. + Thanks to Adam Langley for discovering and researching this issue. + ([CVE-2014-3507]) + + *Adam Langley* + + * An attacker can force openssl to consume large amounts of memory whilst + processing DTLS handshake messages. This can be exploited through a + Denial of Service attack. + Thanks to Adam Langley for discovering and researching this issue. + ([CVE-2014-3506]) + + *Adam Langley* + + * An attacker can force an error condition which causes openssl to crash + whilst processing DTLS packets due to memory being freed twice. This + can be exploited through a Denial of Service attack. + Thanks to Adam Langley and Wan-Teh Chang for discovering and researching + this issue. + ([CVE-2014-3505]) + + *Adam Langley* + + * If a multithreaded client connects to a malicious server using a resumed + session and the server sends an ec point format extension it could write + up to 255 bytes to freed memory. + + Thanks to Gabor Tyukasz (LogMeIn Inc) for discovering and researching this + issue. + ([CVE-2014-3509]) + + *Gabor Tyukasz* + + * A flaw in OBJ_obj2txt may cause pretty printing functions such as + X509_name_oneline, X509_name_print_ex et al. to leak some information + from the stack. Applications may be affected if they echo pretty printing + output to the attacker. + + Thanks to Ivan Fratric (Google) for discovering this issue. + ([CVE-2014-3508]) + + *Emilia Käsper, and Steve Henson* + + * Fix ec_GFp_simple_points_make_affine (thus, EC_POINTs_mul etc.) + for corner cases. (Certain input points at infinity could lead to + bogus results, with non-infinity inputs mapped to infinity too.) + + *Bodo Moeller* + +### Changes between 1.0.0l and 1.0.0m [5 Jun 2014] + + * Fix for SSL/TLS MITM flaw. An attacker using a carefully crafted + handshake can force the use of weak keying material in OpenSSL + SSL/TLS clients and servers. + + Thanks to KIKUCHI Masashi (Lepidum Co. Ltd.) for discovering and + researching this issue. ([CVE-2014-0224]) + + *KIKUCHI Masashi, Steve Henson* + + * Fix DTLS recursion flaw. By sending an invalid DTLS handshake to an + OpenSSL DTLS client the code can be made to recurse eventually crashing + in a DoS attack. + + Thanks to Imre Rad (Search-Lab Ltd.) for discovering this issue. + ([CVE-2014-0221]) + + *Imre Rad, Steve Henson* + + * Fix DTLS invalid fragment vulnerability. A buffer overrun attack can + be triggered by sending invalid DTLS fragments to an OpenSSL DTLS + client or server. This is potentially exploitable to run arbitrary + code on a vulnerable client or server. + + Thanks to Jüri Aedla for reporting this issue. ([CVE-2014-0195]) + + *Jüri Aedla, Steve Henson* + + * Fix bug in TLS code where clients enable anonymous ECDH ciphersuites + are subject to a denial of service attack. + + Thanks to Felix Gröbert and Ivan Fratric at Google for discovering + this issue. ([CVE-2014-3470]) + + *Felix Gröbert, Ivan Fratric, Steve Henson* + + * Harmonize version and its documentation. -f flag is used to display + compilation flags. + + *mancha * + + * Fix eckey_priv_encode so it immediately returns an error upon a failure + in i2d_ECPrivateKey. + + *mancha * + + * Fix some double frees. These are not thought to be exploitable. + + *mancha * + + * Fix for the attack described in the paper "Recovering OpenSSL + ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack" + by Yuval Yarom and Naomi Benger. Details can be obtained from: + + + Thanks to Yuval Yarom and Naomi Benger for discovering this + flaw and to Yuval Yarom for supplying a fix ([CVE-2014-0076]) + + *Yuval Yarom and Naomi Benger* + +### Changes between 1.0.0k and 1.0.0l [6 Jan 2014] + + * Keep original DTLS digest and encryption contexts in retransmission + structures so we can use the previous session parameters if they need + to be resent. ([CVE-2013-6450]) + + *Steve Henson* + + * Add option SSL_OP_SAFARI_ECDHE_ECDSA_BUG (part of SSL_OP_ALL) which + avoids preferring ECDHE-ECDSA ciphers when the client appears to be + Safari on OS X. Safari on OS X 10.8..10.8.3 advertises support for + several ECDHE-ECDSA ciphers, but fails to negotiate them. The bug + is fixed in OS X 10.8.4, but Apple have ruled out both hot fixing + 10.8..10.8.3 and forcing users to upgrade to 10.8.4 or newer. + + *Rob Stradling, Adam Langley* + +### Changes between 1.0.0j and 1.0.0k [5 Feb 2013] + + * Make the decoding of SSLv3, TLS and DTLS CBC records constant time. + + This addresses the flaw in CBC record processing discovered by + Nadhem Alfardan and Kenny Paterson. Details of this attack can be found + at: + + Thanks go to Nadhem Alfardan and Kenny Paterson of the Information + Security Group at Royal Holloway, University of London + (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and + Emilia Käsper for the initial patch. + ([CVE-2013-0169]) + + *Emilia Käsper, Adam Langley, Ben Laurie, Andy Polyakov, Steve Henson* + + * Return an error when checking OCSP signatures when key is NULL. + This fixes a DoS attack. ([CVE-2013-0166]) + + *Steve Henson* + + * Call OCSP Stapling callback after ciphersuite has been chosen, so + the right response is stapled. Also change SSL_get_certificate() + so it returns the certificate actually sent. + See . + (This is a backport) + + *Rob Stradling * + + * Fix possible deadlock when decoding public keys. + + *Steve Henson* + +### Changes between 1.0.0i and 1.0.0j [10 May 2012] + +[NB: OpenSSL 1.0.0i and later 1.0.0 patch levels were released after +OpenSSL 1.0.1.] + + * Sanity check record length before skipping explicit IV in DTLS + to fix DoS attack. + + Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic + fuzzing as a service testing platform. + ([CVE-2012-2333]) + + *Steve Henson* + + * Initialise tkeylen properly when encrypting CMS messages. + Thanks to Solar Designer of Openwall for reporting this issue. + + *Steve Henson* + +### Changes between 1.0.0h and 1.0.0i [19 Apr 2012] + + * Check for potentially exploitable overflows in asn1_d2i_read_bio + BUF_mem_grow and BUF_mem_grow_clean. Refuse attempts to shrink buffer + in CRYPTO_realloc_clean. + + Thanks to Tavis Ormandy, Google Security Team, for discovering this + issue and to Adam Langley for fixing it. + ([CVE-2012-2110]) + + *Adam Langley (Google), Tavis Ormandy, Google Security Team* + +### Changes between 1.0.0g and 1.0.0h [12 Mar 2012] + + * Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness + in CMS and PKCS7 code. When RSA decryption fails use a random key for + content decryption and always return the same error. Note: this attack + needs on average 2^20 messages so it only affects automated senders. The + old behaviour can be re-enabled in the CMS code by setting the + CMS_DEBUG_DECRYPT flag: this is useful for debugging and testing where + an MMA defence is not necessary. + Thanks to Ivan Nestlerode for discovering + this issue. ([CVE-2012-0884]) + + *Steve Henson* + + * Fix CVE-2011-4619: make sure we really are receiving a + client hello before rejecting multiple SGC restarts. Thanks to + Ivan Nestlerode for discovering this bug. + + *Steve Henson* + +### Changes between 1.0.0f and 1.0.0g [18 Jan 2012] + + * Fix for DTLS DoS issue introduced by fix for CVE-2011-4109. + Thanks to Antonio Martin, Enterprise Secure Access Research and + Development, Cisco Systems, Inc. for discovering this bug and + preparing a fix. ([CVE-2012-0050]) + + *Antonio Martin* + +### Changes between 1.0.0e and 1.0.0f [4 Jan 2012] + + * Nadhem Alfardan and Kenny Paterson have discovered an extension + of the Vaudenay padding oracle attack on CBC mode encryption + which enables an efficient plaintext recovery attack against + the OpenSSL implementation of DTLS. Their attack exploits timing + differences arising during decryption processing. A research + paper describing this attack can be found at: + + Thanks go to Nadhem Alfardan and Kenny Paterson of the Information + Security Group at Royal Holloway, University of London + (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann + and Michael Tuexen + for preparing the fix. ([CVE-2011-4108]) + + *Robin Seggelmann, Michael Tuexen* + + * Clear bytes used for block padding of SSL 3.0 records. + ([CVE-2011-4576]) + + *Adam Langley (Google)* + + * Only allow one SGC handshake restart for SSL/TLS. Thanks to George + Kadianakis for discovering this issue and + Adam Langley for preparing the fix. ([CVE-2011-4619]) + + *Adam Langley (Google)* + + * Check parameters are not NULL in GOST ENGINE. ([CVE-2012-0027]) + + *Andrey Kulikov * + + * Prevent malformed RFC3779 data triggering an assertion failure. + Thanks to Andrew Chi, BBN Technologies, for discovering the flaw + and Rob Austein for fixing it. ([CVE-2011-4577]) + + *Rob Austein * + + * Improved PRNG seeding for VOS. + + *Paul Green * + + * Fix ssl_ciph.c set-up race. + + *Adam Langley (Google)* + + * Fix spurious failures in ecdsatest.c. + + *Emilia Käsper (Google)* + + * Fix the BIO_f_buffer() implementation (which was mixing different + interpretations of the `..._len` fields). + + *Adam Langley (Google)* + + * Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than + BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent + threads won't reuse the same blinding coefficients. + + This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING + lock to call BN_BLINDING_invert_ex, and avoids one use of + BN_BLINDING_update for each BN_BLINDING structure (previously, + the last update always remained unused). + + *Emilia Käsper (Google)* + + * In ssl3_clear, preserve s3->init_extra along with s3->rbuf. + + *Bob Buckholz (Google)* + +### Changes between 1.0.0d and 1.0.0e [6 Sep 2011] + + * Fix bug where CRLs with nextUpdate in the past are sometimes accepted + by initialising X509_STORE_CTX properly. ([CVE-2011-3207]) + + *Kaspar Brand * + + * Fix SSL memory handling for (EC)DH ciphersuites, in particular + for multi-threaded use of ECDH. ([CVE-2011-3210]) + + *Adam Langley (Google)* + + * Fix x509_name_ex_d2i memory leak on bad inputs. + + *Bodo Moeller* + + * Remove hard coded ecdsaWithSHA1 signature tests in ssl code and check + signature public key algorithm by using OID xref utilities instead. + Before this you could only use some ECC ciphersuites with SHA1 only. + + *Steve Henson* + + * Add protection against ECDSA timing attacks as mentioned in the paper + by Billy Bob Brumley and Nicola Tuveri, see: + + + *Billy Bob Brumley and Nicola Tuveri* + +### Changes between 1.0.0c and 1.0.0d [8 Feb 2011] + + * Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014 + + *Neel Mehta, Adam Langley, Bodo Moeller (Google)* + + * Fix bug in string printing code: if *any* escaping is enabled we must + escape the escape character (backslash) or the resulting string is + ambiguous. + + *Steve Henson* + +### Changes between 1.0.0b and 1.0.0c [2 Dec 2010] + + * Disable code workaround for ancient and obsolete Netscape browsers + and servers: an attacker can use it in a ciphersuite downgrade attack. + Thanks to Martin Rex for discovering this bug. CVE-2010-4180 + + *Steve Henson* + + * Fixed J-PAKE implementation error, originally discovered by + Sebastien Martini, further info and confirmation from Stefan + Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252 + + *Ben Laurie* + +### Changes between 1.0.0a and 1.0.0b [16 Nov 2010] + + * Fix extension code to avoid race conditions which can result in a buffer + overrun vulnerability: resumed sessions must not be modified as they can + be shared by multiple threads. CVE-2010-3864 + + *Steve Henson* + + * Fix WIN32 build system to correctly link an ENGINE directory into + a DLL. + + *Steve Henson* + +### Changes between 1.0.0 and 1.0.0a [01 Jun 2010] + + * Check return value of int_rsa_verify in pkey_rsa_verifyrecover + ([CVE-2010-1633]) + + *Steve Henson, Peter-Michael Hager * + +### Changes between 0.9.8n and 1.0.0 [29 Mar 2010] + + * Add "missing" function EVP_CIPHER_CTX_copy(). This copies a cipher + context. The operation can be customised via the ctrl mechanism in + case ENGINEs want to include additional functionality. + + *Steve Henson* + + * Tolerate yet another broken PKCS#8 key format: private key value negative. + + *Steve Henson* + + * Add new -subject_hash_old and -issuer_hash_old options to x509 utility to + output hashes compatible with older versions of OpenSSL. + + *Willy Weisz * + + * Fix compression algorithm handling: if resuming a session use the + compression algorithm of the resumed session instead of determining + it from client hello again. Don't allow server to change algorithm. + + *Steve Henson* + + * Add load_crls() function to commands tidying load_certs() too. Add option + to verify utility to allow additional CRLs to be included. + + *Steve Henson* + + * Update OCSP request code to permit adding custom headers to the request: + some responders need this. + + *Steve Henson* + + * The function EVP_PKEY_sign() returns <=0 on error: check return code + correctly. + + *Julia Lawall * + + * Update verify callback code in `apps/s_cb.c` and `apps/verify.c`, it + needlessly dereferenced structures, used obsolete functions and + didn't handle all updated verify codes correctly. + + *Steve Henson* + + * Disable MD2 in the default configuration. + + *Steve Henson* + + * In BIO_pop() and BIO_push() use the ctrl argument (which was NULL) to + indicate the initial BIO being pushed or popped. This makes it possible + to determine whether the BIO is the one explicitly called or as a result + of the ctrl being passed down the chain. Fix BIO_pop() and SSL BIOs so + it handles reference counts correctly and doesn't zero out the I/O bio + when it is not being explicitly popped. WARNING: applications which + included workarounds for the old buggy behaviour will need to be modified + or they could free up already freed BIOs. + + *Steve Henson* + + * Extend the uni2asc/asc2uni => OPENSSL_uni2asc/OPENSSL_asc2uni + renaming to all platforms (within the 0.9.8 branch, this was + done conditionally on Netware platforms to avoid a name clash). + + *Guenter * + + * Add ECDHE and PSK support to DTLS. + + *Michael Tuexen * + + * Add CHECKED_STACK_OF macro to safestack.h, otherwise safestack can't + be used on C++. + + *Steve Henson* + + * Add "missing" function EVP_MD_flags() (without this the only way to + retrieve a digest flags is by accessing the structure directly. Update + `EVP_MD_do_all*()` and `EVP_CIPHER_do_all*()` to include the name a digest + or cipher is registered as in the "from" argument. Print out all + registered digests in the dgst usage message instead of manually + attempting to work them out. + + *Steve Henson* + + * If no SSLv2 ciphers are used don't use an SSLv2 compatible client hello: + this allows the use of compression and extensions. Change default cipher + string to remove SSLv2 ciphersuites. This effectively avoids ancient SSLv2 + by default unless an application cipher string requests it. + + *Steve Henson* + + * Alter match criteria in PKCS12_parse(). It used to try to use local + key ids to find matching certificates and keys but some PKCS#12 files + don't follow the (somewhat unwritten) rules and this strategy fails. + Now just gather all certificates together and the first private key + then look for the first certificate that matches the key. + + *Steve Henson* + + * Support use of registered digest and cipher names for dgst and cipher + commands instead of having to add each one as a special case. So now + you can do: + + openssl sha256 foo + + as well as: + + openssl dgst -sha256 foo + + and this works for ENGINE based algorithms too. + + *Steve Henson* + + * Update Gost ENGINE to support parameter files. + + *Victor B. Wagner * + + * Support GeneralizedTime in ca utility. + + *Oliver Martin , Steve Henson* + + * Enhance the hash format used for certificate directory links. The new + form uses the canonical encoding (meaning equivalent names will work + even if they aren't identical) and uses SHA1 instead of MD5. This form + is incompatible with the older format and as a result c_rehash should + be used to rebuild symbolic links. + + *Steve Henson* + + * Make PKCS#8 the default write format for private keys, replacing the + traditional format. This form is standardised, more secure and doesn't + include an implicit MD5 dependency. + + *Steve Henson* + + * Add a $gcc_devteam_warn option to Configure. The idea is that any code + committed to OpenSSL should pass this lot as a minimum. + + *Steve Henson* + + * Add session ticket override functionality for use by EAP-FAST. + + *Jouni Malinen * + + * Modify HMAC functions to return a value. Since these can be implemented + in an ENGINE errors can occur. + + *Steve Henson* + + * Type-checked OBJ_bsearch_ex. + + *Ben Laurie* + + * Type-checked OBJ_bsearch. Also some constification necessitated + by type-checking. Still to come: TXT_DB, bsearch(?), + OBJ_bsearch_ex, qsort, CRYPTO_EX_DATA, ASN1_VALUE, ASN1_STRING, + CONF_VALUE. + + *Ben Laurie* + + * New function OPENSSL_gmtime_adj() to add a specific number of days and + seconds to a tm structure directly, instead of going through OS + specific date routines. This avoids any issues with OS routines such + as the year 2038 bug. New `*_adj()` functions for ASN1 time structures + and X509_time_adj_ex() to cover the extended range. The existing + X509_time_adj() is still usable and will no longer have any date issues. + + *Steve Henson* + + * Delta CRL support. New use deltas option which will attempt to locate + and search any appropriate delta CRLs available. + + This work was sponsored by Google. + + *Steve Henson* + + * Support for CRLs partitioned by reason code. Reorganise CRL processing + code and add additional score elements. Validate alternate CRL paths + as part of the CRL checking and indicate a new error "CRL path validation + error" in this case. Applications wanting additional details can use + the verify callback and check the new "parent" field. If this is not + NULL CRL path validation is taking place. Existing applications won't + see this because it requires extended CRL support which is off by + default. + + This work was sponsored by Google. + + *Steve Henson* + + * Support for freshest CRL extension. + + This work was sponsored by Google. + + *Steve Henson* + + * Initial indirect CRL support. Currently only supported in the CRLs + passed directly and not via lookup. Process certificate issuer + CRL entry extension and lookup CRL entries by bother issuer name + and serial number. Check and process CRL issuer entry in IDP extension. + + This work was sponsored by Google. + + *Steve Henson* + + * Add support for distinct certificate and CRL paths. The CRL issuer + certificate is validated separately in this case. Only enabled if + an extended CRL support flag is set: this flag will enable additional + CRL functionality in future. + + This work was sponsored by Google. + + *Steve Henson* + + * Add support for policy mappings extension. + + This work was sponsored by Google. + + *Steve Henson* + + * Fixes to pathlength constraint, self issued certificate handling, + policy processing to align with RFC3280 and PKITS tests. + + This work was sponsored by Google. + + *Steve Henson* + + * Support for name constraints certificate extension. DN, email, DNS + and URI types are currently supported. + + This work was sponsored by Google. + + *Steve Henson* + + * To cater for systems that provide a pointer-based thread ID rather + than numeric, deprecate the current numeric thread ID mechanism and + replace it with a structure and associated callback type. This + mechanism allows a numeric "hash" to be extracted from a thread ID in + either case, and on platforms where pointers are larger than 'long', + mixing is done to help ensure the numeric 'hash' is usable even if it + can't be guaranteed unique. The default mechanism is to use "&errno" + as a pointer-based thread ID to distinguish between threads. + + Applications that want to provide their own thread IDs should now use + CRYPTO_THREADID_set_callback() to register a callback that will call + either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer(). + + Note that ERR_remove_state() is now deprecated, because it is tied + to the assumption that thread IDs are numeric. ERR_remove_state(0) + to free the current thread's error state should be replaced by + ERR_remove_thread_state(NULL). + + (This new approach replaces the functions CRYPTO_set_idptr_callback(), + CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in + OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an + application was previously providing a numeric thread callback that + was inappropriate for distinguishing threads, then uniqueness might + have been obtained with &errno that happened immediately in the + intermediate development versions of OpenSSL; this is no longer the + case, the numeric thread callback will now override the automatic use + of &errno.) + + *Geoff Thorpe, with help from Bodo Moeller* + + * Initial support for different CRL issuing certificates. This covers a + simple case where the self issued certificates in the chain exist and + the real CRL issuer is higher in the existing chain. + + This work was sponsored by Google. + + *Steve Henson* + + * Removed effectively defunct crypto/store from the build. + + *Ben Laurie* + + * Revamp of STACK to provide stronger type-checking. Still to come: + TXT_DB, bsearch(?), OBJ_bsearch, qsort, CRYPTO_EX_DATA, ASN1_VALUE, + ASN1_STRING, CONF_VALUE. + + *Ben Laurie* + + * Add a new SSL_MODE_RELEASE_BUFFERS mode flag to release unused buffer + RAM on SSL connections. This option can save about 34k per idle SSL. + + *Nick Mathewson* + + * Revamp of LHASH to provide stronger type-checking. Still to come: + STACK, TXT_DB, bsearch, qsort. + + *Ben Laurie* + + * Initial support for Cryptographic Message Syntax (aka CMS) based + on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility, + support for data, signedData, compressedData, digestedData and + encryptedData, envelopedData types included. Scripts to check against + RFC4134 examples draft and interop and consistency checks of many + content types and variants. + + *Steve Henson* + + * Add options to enc utility to support use of zlib compression BIO. + + *Steve Henson* + + * Extend mk1mf to support importing of options and assembly language + files from Configure script, currently only included in VC-WIN32. + The assembly language rules can now optionally generate the source + files from the associated perl scripts. + + *Steve Henson* + + * Implement remaining functionality needed to support GOST ciphersuites. + Interop testing has been performed using CryptoPro implementations. + + *Victor B. Wagner * + + * s390x assembler pack. + + *Andy Polyakov* + + * ARMv4 assembler pack. ARMv4 refers to v4 and later ISA, not CPU + "family." + + *Andy Polyakov* + + * Implement Opaque PRF Input TLS extension as specified in + draft-rescorla-tls-opaque-prf-input-00.txt. Since this is not an + official specification yet and no extension type assignment by + IANA exists, this extension (for now) will have to be explicitly + enabled when building OpenSSL by providing the extension number + to use. For example, specify an option + + -DTLSEXT_TYPE_opaque_prf_input=0x9527 + + to the "config" or "Configure" script to enable the extension, + assuming extension number 0x9527 (which is a completely arbitrary + and unofficial assignment based on the MD5 hash of the Internet + Draft). Note that by doing so, you potentially lose + interoperability with other TLS implementations since these might + be using the same extension number for other purposes. + + SSL_set_tlsext_opaque_prf_input(ssl, src, len) is used to set the + opaque PRF input value to use in the handshake. This will create + an internal copy of the length-'len' string at 'src', and will + return non-zero for success. + + To get more control and flexibility, provide a callback function + by using + + SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) + SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) + + where + + int (*cb)(SSL *, void *peerinput, size_t len, void *arg); + void *arg; + + Callback function 'cb' will be called in handshakes, and is + expected to use SSL_set_tlsext_opaque_prf_input() as appropriate. + Argument 'arg' is for application purposes (the value as given to + SSL_CTX_set_tlsext_opaque_prf_input_callback_arg() will directly + be provided to the callback function). The callback function + has to return non-zero to report success: usually 1 to use opaque + PRF input just if possible, or 2 to enforce use of the opaque PRF + input. In the latter case, the library will abort the handshake + if opaque PRF input is not successfully negotiated. + + Arguments 'peerinput' and 'len' given to the callback function + will always be NULL and 0 in the case of a client. A server will + see the client's opaque PRF input through these variables if + available (NULL and 0 otherwise). Note that if the server + provides an opaque PRF input, the length must be the same as the + length of the client's opaque PRF input. + + Note that the callback function will only be called when creating + a new session (session resumption can resume whatever was + previously negotiated), and will not be called in SSL 2.0 + handshakes; thus, SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) or + SSL_set_options(ssl, SSL_OP_NO_SSLv2) is especially recommended + for applications that need to enforce opaque PRF input. + + *Bodo Moeller* + + * Update ssl code to support digests other than SHA1+MD5 for handshake + MAC. + + *Victor B. Wagner * + + * Add RFC4507 support to OpenSSL. This includes the corrections in + RFC4507bis. The encrypted ticket format is an encrypted encoded + SSL_SESSION structure, that way new session features are automatically + supported. + + If a client application caches session in an SSL_SESSION structure + support is transparent because tickets are now stored in the encoded + SSL_SESSION. + + The SSL_CTX structure automatically generates keys for ticket + protection in servers so again support should be possible + with no application modification. + + If a client or server wishes to disable RFC4507 support then the option + SSL_OP_NO_TICKET can be set. + + Add a TLS extension debugging callback to allow the contents of any client + or server extensions to be examined. + + This work was sponsored by Google. + + *Steve Henson* + + * Final changes to avoid use of pointer pointer casts in OpenSSL. + OpenSSL should now compile cleanly on gcc 4.2 + + *Peter Hartley , Steve Henson* + + * Update SSL library to use new EVP_PKEY MAC API. Include generic MAC + support including streaming MAC support: this is required for GOST + ciphersuite support. + + *Victor B. Wagner , Steve Henson* + + * Add option -stream to use PKCS#7 streaming in smime utility. New + function i2d_PKCS7_bio_stream() and PEM_write_PKCS7_bio_stream() + to output in BER and PEM format. + + *Steve Henson* + + * Experimental support for use of HMAC via EVP_PKEY interface. This + allows HMAC to be handled via the `EVP_DigestSign*()` interface. The + EVP_PKEY "key" in this case is the HMAC key, potentially allowing + ENGINE support for HMAC keys which are unextractable. New -mac and + -macopt options to dgst utility. + + *Steve Henson* + + * New option -sigopt to dgst utility. Update dgst to use + `EVP_Digest{Sign,Verify}*`. These two changes make it possible to use + alternative signing parameters such as X9.31 or PSS in the dgst + utility. + + *Steve Henson* + + * Change ssl_cipher_apply_rule(), the internal function that does + the work each time a ciphersuite string requests enabling + ("foo+bar"), moving ("+foo+bar"), disabling ("-foo+bar", or + removing ("!foo+bar") a class of ciphersuites: Now it maintains + the order of disabled ciphersuites such that those ciphersuites + that most recently went from enabled to disabled not only stay + in order with respect to each other, but also have higher priority + than other disabled ciphersuites the next time ciphersuites are + enabled again. + + This means that you can now say, e.g., "PSK:-PSK:HIGH" to enable + the same ciphersuites as with "HIGH" alone, but in a specific + order where the PSK ciphersuites come first (since they are the + most recently disabled ciphersuites when "HIGH" is parsed). + + Also, change ssl_create_cipher_list() (using this new + functionality) such that between otherwise identical + ciphersuites, ephemeral ECDH is preferred over ephemeral DH in + the default order. + + *Bodo Moeller* + + * Change ssl_create_cipher_list() so that it automatically + arranges the ciphersuites in reasonable order before starting + to process the rule string. Thus, the definition for "DEFAULT" + (SSL_DEFAULT_CIPHER_LIST) now is just "ALL:!aNULL:!eNULL", but + remains equivalent to `"AES:ALL:!aNULL:!eNULL:+aECDH:+kRSA:+RC4:@STRENGTH"`. + This makes it much easier to arrive at a reasonable default order + in applications for which anonymous ciphers are OK (meaning + that you can't actually use DEFAULT). + + *Bodo Moeller; suggested by Victor Duchovni* + + * Split the SSL/TLS algorithm mask (as used for ciphersuite string + processing) into multiple integers instead of setting + "SSL_MKEY_MASK" bits, "SSL_AUTH_MASK" bits, "SSL_ENC_MASK", + "SSL_MAC_MASK", and "SSL_SSL_MASK" bits all in a single integer. + (These masks as well as the individual bit definitions are hidden + away into the non-exported interface ssl/ssl_locl.h, so this + change to the definition of the SSL_CIPHER structure shouldn't + affect applications.) This give us more bits for each of these + categories, so there is no longer a need to coagulate AES128 and + AES256 into a single algorithm bit, and to coagulate Camellia128 + and Camellia256 into a single algorithm bit, which has led to all + kinds of kludges. + + Thus, among other things, the kludge introduced in 0.9.7m and + 0.9.8e for masking out AES256 independently of AES128 or masking + out Camellia256 independently of AES256 is not needed here in 0.9.9. + + With the change, we also introduce new ciphersuite aliases that + so far were missing: "AES128", "AES256", "CAMELLIA128", and + "CAMELLIA256". + + *Bodo Moeller* + + * Add support for dsa-with-SHA224 and dsa-with-SHA256. + Use the leftmost N bytes of the signature input if the input is + larger than the prime q (with N being the size in bytes of q). + + *Nils Larsch* + + * Very *very* experimental PKCS#7 streaming encoder support. Nothing uses + it yet and it is largely untested. + + *Steve Henson* + + * Add support for the ecdsa-with-SHA224/256/384/512 signature types. + + *Nils Larsch* + + * Initial incomplete changes to avoid need for function casts in OpenSSL + some compilers (gcc 4.2 and later) reject their use. Safestack is + reimplemented. Update ASN1 to avoid use of legacy functions. + + *Steve Henson* + + * Win32/64 targets are linked with Winsock2. + + *Andy Polyakov* + + * Add an X509_CRL_METHOD structure to allow CRL processing to be redirected + to external functions. This can be used to increase CRL handling + efficiency especially when CRLs are very large by (for example) storing + the CRL revoked certificates in a database. + + *Steve Henson* + + * Overhaul of by_dir code. Add support for dynamic loading of CRLs so + new CRLs added to a directory can be used. New command line option + -verify_return_error to s_client and s_server. This causes real errors + to be returned by the verify callback instead of carrying on no matter + what. This reflects the way a "real world" verify callback would behave. + + *Steve Henson* + + * GOST engine, supporting several GOST algorithms and public key formats. + Kindly donated by Cryptocom. + + *Cryptocom* + + * Partial support for Issuing Distribution Point CRL extension. CRLs + partitioned by DP are handled but no indirect CRL or reason partitioning + (yet). Complete overhaul of CRL handling: now the most suitable CRL is + selected via a scoring technique which handles IDP and AKID in CRLs. + + *Steve Henson* + + * New X509_STORE_CTX callbacks lookup_crls() and lookup_certs() which + will ultimately be used for all verify operations: this will remove the + X509_STORE dependency on certificate verification and allow alternative + lookup methods. X509_STORE based implementations of these two callbacks. + + *Steve Henson* + + * Allow multiple CRLs to exist in an X509_STORE with matching issuer names. + Modify get_crl() to find a valid (unexpired) CRL if possible. + + *Steve Henson* + + * New function X509_CRL_match() to check if two CRLs are identical. Normally + this would be called X509_CRL_cmp() but that name is already used by + a function that just compares CRL issuer names. Cache several CRL + extensions in X509_CRL structure and cache CRLDP in X509. + + *Steve Henson* + + * Store a "canonical" representation of X509_NAME structure (ASN1 Name) + this maps equivalent X509_NAME structures into a consistent structure. + Name comparison can then be performed rapidly using memcmp(). + + *Steve Henson* + + * Non-blocking OCSP request processing. Add -timeout option to ocsp + utility. + + *Steve Henson* + + * Allow digests to supply their own micalg string for S/MIME type using + the ctrl EVP_MD_CTRL_MICALG. + + *Steve Henson* + + * During PKCS7 signing pass the PKCS7 SignerInfo structure to the + EVP_PKEY_METHOD before and after signing via the EVP_PKEY_CTRL_PKCS7_SIGN + ctrl. It can then customise the structure before and/or after signing + if necessary. + + *Steve Henson* + + * New function OBJ_add_sigid() to allow application defined signature OIDs + to be added to OpenSSLs internal tables. New function OBJ_sigid_free() + to free up any added signature OIDs. + + *Steve Henson* + + * New functions EVP_CIPHER_do_all(), EVP_CIPHER_do_all_sorted(), + EVP_MD_do_all() and EVP_MD_do_all_sorted() to enumerate internal + digest and cipher tables. New options added to openssl utility: + list-message-digest-algorithms and list-cipher-algorithms. + + *Steve Henson* + + * Change the array representation of binary polynomials: the list + of degrees of non-zero coefficients is now terminated with -1. + Previously it was terminated with 0, which was also part of the + value; thus, the array representation was not applicable to + polynomials where t^0 has coefficient zero. This change makes + the array representation useful in a more general context. + + *Douglas Stebila* + + * Various modifications and fixes to SSL/TLS cipher string + handling. For ECC, the code now distinguishes between fixed ECDH + with RSA certificates on the one hand and with ECDSA certificates + on the other hand, since these are separate ciphersuites. The + unused code for Fortezza ciphersuites has been removed. + + For consistency with EDH, ephemeral ECDH is now called "EECDH" + (not "ECDHE"). For consistency with the code for DH + certificates, use of ECDH certificates is now considered ECDH + authentication, not RSA or ECDSA authentication (the latter is + merely the CA's signing algorithm and not actively used in the + protocol). + + The temporary ciphersuite alias "ECCdraft" is no longer + available, and ECC ciphersuites are no longer excluded from "ALL" + and "DEFAULT". The following aliases now exist for RFC 4492 + ciphersuites, most of these by analogy with the DH case: + + kECDHr - ECDH cert, signed with RSA + kECDHe - ECDH cert, signed with ECDSA + kECDH - ECDH cert (signed with either RSA or ECDSA) + kEECDH - ephemeral ECDH + ECDH - ECDH cert or ephemeral ECDH + + aECDH - ECDH cert + aECDSA - ECDSA cert + ECDSA - ECDSA cert + + AECDH - anonymous ECDH + EECDH - non-anonymous ephemeral ECDH (equivalent to "kEECDH:-AECDH") + + *Bodo Moeller* + + * Add additional S/MIME capabilities for AES and GOST ciphers if supported. + Use correct micalg parameters depending on digest(s) in signed message. + + *Steve Henson* + + * Add engine support for EVP_PKEY_ASN1_METHOD. Add functions to process + an ENGINE asn1 method. Support ENGINE lookups in the ASN1 code. + + *Steve Henson* + + * Initial engine support for EVP_PKEY_METHOD. New functions to permit + an engine to register a method. Add ENGINE lookups for methods and + functional reference processing. + + *Steve Henson* + + * New functions `EVP_Digest{Sign,Verify)*`. These are enhanced versions of + `EVP_{Sign,Verify}*` which allow an application to customise the signature + process. + + *Steve Henson* + + * New -resign option to smime utility. This adds one or more signers + to an existing PKCS#7 signedData structure. Also -md option to use an + alternative message digest algorithm for signing. + + *Steve Henson* + + * Tidy up PKCS#7 routines and add new functions to make it easier to + create PKCS7 structures containing multiple signers. Update smime + application to support multiple signers. + + *Steve Henson* + + * New -macalg option to pkcs12 utility to allow setting of an alternative + digest MAC. + + *Steve Henson* + + * Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC. + Reorganize PBE internals to lookup from a static table using NIDs, + add support for HMAC PBE OID translation. Add a EVP_CIPHER ctrl: + EVP_CTRL_PBE_PRF_NID this allows a cipher to specify an alternative + PRF which will be automatically used with PBES2. + + *Steve Henson* + + * Replace the algorithm specific calls to generate keys in "req" with the + new API. + + *Steve Henson* + + * Update PKCS#7 enveloped data routines to use new API. This is now + supported by any public key method supporting the encrypt operation. A + ctrl is added to allow the public key algorithm to examine or modify + the PKCS#7 RecipientInfo structure if it needs to: for RSA this is + a no op. + + *Steve Henson* + + * Add a ctrl to asn1 method to allow a public key algorithm to express + a default digest type to use. In most cases this will be SHA1 but some + algorithms (such as GOST) need to specify an alternative digest. The + return value indicates how strong the preference is 1 means optional and + 2 is mandatory (that is it is the only supported type). Modify + ASN1_item_sign() to accept a NULL digest argument to indicate it should + use the default md. Update openssl utilities to use the default digest + type for signing if it is not explicitly indicated. + + *Steve Henson* + + * Use OID cross reference table in ASN1_sign() and ASN1_verify(). New + EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant + signing method from the key type. This effectively removes the link + between digests and public key types. + + *Steve Henson* + + * Add an OID cross reference table and utility functions. Its purpose is to + translate between signature OIDs such as SHA1WithrsaEncryption and SHA1, + rsaEncryption. This will allow some of the algorithm specific hackery + needed to use the correct OID to be removed. + + *Steve Henson* + + * Remove algorithm specific dependencies when setting PKCS7_SIGNER_INFO + structures for PKCS7_sign(). They are now set up by the relevant public + key ASN1 method. + + *Steve Henson* + + * Add provisional EC pkey method with support for ECDSA and ECDH. + + *Steve Henson* + + * Add support for key derivation (agreement) in the API, DH method and + pkeyutl. + + *Steve Henson* + + * Add DSA pkey method and DH pkey methods, extend DH ASN1 method to support + public and private key formats. As a side effect these add additional + command line functionality not previously available: DSA signatures can be + generated and verified using pkeyutl and DH key support and generation in + pkey, genpkey. + + *Steve Henson* + + * BeOS support. + + *Oliver Tappe * + + * New make target "install_html_docs" installs HTML renditions of the + manual pages. + + *Oliver Tappe * + + * New utility "genpkey" this is analogous to "genrsa" etc except it can + generate keys for any algorithm. Extend and update EVP_PKEY_METHOD to + support key and parameter generation and add initial key generation + functionality for RSA. + + *Steve Henson* + + * Add functions for main EVP_PKEY_method operations. The undocumented + functions `EVP_PKEY_{encrypt,decrypt}` have been renamed to + `EVP_PKEY_{encrypt,decrypt}_old`. + + *Steve Henson* + + * Initial definitions for EVP_PKEY_METHOD. This will be a high level public + key API, doesn't do much yet. + + *Steve Henson* + + * New function EVP_PKEY_asn1_get0_info() to retrieve information about + public key algorithms. New option to openssl utility: + "list-public-key-algorithms" to print out info. + + *Steve Henson* + + * Implement the Supported Elliptic Curves Extension for + ECC ciphersuites from draft-ietf-tls-ecc-12.txt. + + *Douglas Stebila* + + * Don't free up OIDs in OBJ_cleanup() if they are in use by EVP_MD or + EVP_CIPHER structures to avoid later problems in EVP_cleanup(). + + *Steve Henson* + + * New utilities pkey and pkeyparam. These are similar to algorithm specific + utilities such as rsa, dsa, dsaparam etc except they process any key + type. + + *Steve Henson* + + * Transfer public key printing routines to EVP_PKEY_ASN1_METHOD. New + functions EVP_PKEY_print_public(), EVP_PKEY_print_private(), + EVP_PKEY_print_param() to print public key data from an EVP_PKEY + structure. + + *Steve Henson* + + * Initial support for pluggable public key ASN1. + De-spaghettify the public key ASN1 handling. Move public and private + key ASN1 handling to a new EVP_PKEY_ASN1_METHOD structure. Relocate + algorithm specific handling to a single module within the relevant + algorithm directory. Add functions to allow (near) opaque processing + of public and private key structures. + + *Steve Henson* + + * Implement the Supported Point Formats Extension for + ECC ciphersuites from draft-ietf-tls-ecc-12.txt. + + *Douglas Stebila* + + * Add initial support for RFC 4279 PSK TLS ciphersuites. Add members + for the psk identity [hint] and the psk callback functions to the + SSL_SESSION, SSL and SSL_CTX structure. + + New ciphersuites: + PSK-RC4-SHA, PSK-3DES-EDE-CBC-SHA, PSK-AES128-CBC-SHA, + PSK-AES256-CBC-SHA + + New functions: + SSL_CTX_use_psk_identity_hint + SSL_get_psk_identity_hint + SSL_get_psk_identity + SSL_use_psk_identity_hint + + *Mika Kousa and Pasi Eronen of Nokia Corporation* + + * Add RFC 3161 compliant time stamp request creation, response generation + and response verification functionality. + + *Zoltán Glózik , The OpenTSA Project* + + * Add initial support for TLS extensions, specifically for the server_name + extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now + have new members for a host name. The SSL data structure has an + additional member `SSL_CTX *initial_ctx` so that new sessions can be + stored in that context to allow for session resumption, even after the + SSL has been switched to a new SSL_CTX in reaction to a client's + server_name extension. + + New functions (subject to change): + + SSL_get_servername() + SSL_get_servername_type() + SSL_set_SSL_CTX() + + New CTRL codes and macros (subject to change): + + SSL_CTRL_SET_TLSEXT_SERVERNAME_CB + - SSL_CTX_set_tlsext_servername_callback() + SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG + - SSL_CTX_set_tlsext_servername_arg() + SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name() + + openssl s_client has a new '-servername ...' option. + + openssl s_server has new options '-servername_host ...', '-cert2 ...', + '-key2 ...', '-servername_fatal' (subject to change). This allows + testing the HostName extension for a specific single host name ('-cert' + and '-key' remain fallbacks for handshakes without HostName + negotiation). If the unrecognized_name alert has to be sent, this by + default is a warning; it becomes fatal with the '-servername_fatal' + option. + + *Peter Sylvester, Remy Allais, Christophe Renou* + + * Whirlpool hash implementation is added. + + *Andy Polyakov* + + * BIGNUM code on 64-bit SPARCv9 targets is switched from bn(64,64) to + bn(64,32). Because of instruction set limitations it doesn't have + any negative impact on performance. This was done mostly in order + to make it possible to share assembler modules, such as bn_mul_mont + implementations, between 32- and 64-bit builds without hassle. + + *Andy Polyakov* + + * Move code previously exiled into file crypto/ec/ec2_smpt.c + to ec2_smpl.c, and no longer require the OPENSSL_EC_BIN_PT_COMP + macro. + + *Bodo Moeller* + + * New candidate for BIGNUM assembler implementation, bn_mul_mont, + dedicated Montgomery multiplication procedure, is introduced. + BN_MONT_CTX is modified to allow bn_mul_mont to reach for higher + "64-bit" performance on certain 32-bit targets. + + *Andy Polyakov* + + * New option SSL_OP_NO_COMP to disable use of compression selectively + in SSL structures. New SSL ctrl to set maximum send fragment size. + Save memory by setting the I/O buffer sizes dynamically instead of + using the maximum available value. + + *Steve Henson* + + * New option -V for 'openssl ciphers'. This prints the ciphersuite code + in addition to the text details. + + *Bodo Moeller* + + * Very, very preliminary EXPERIMENTAL support for printing of general + ASN1 structures. This currently produces rather ugly output and doesn't + handle several customised structures at all. + + *Steve Henson* + + * Integrated support for PVK file format and some related formats such + as MS PUBLICKEYBLOB and PRIVATEKEYBLOB. Command line switches to support + these in the 'rsa' and 'dsa' utilities. + + *Steve Henson* + + * Support for PKCS#1 RSAPublicKey format on rsa utility command line. + + *Steve Henson* + + * Remove the ancient ASN1_METHOD code. This was only ever used in one + place for the (very old) "NETSCAPE" format certificates which are now + handled using new ASN1 code equivalents. + + *Steve Henson* + + * Let the TLSv1_method() etc. functions return a 'const' SSL_METHOD + pointer and make the SSL_METHOD parameter in SSL_CTX_new, + SSL_CTX_set_ssl_version and SSL_set_ssl_method 'const'. + + *Nils Larsch* + + * Modify CRL distribution points extension code to print out previously + unsupported fields. Enhance extension setting code to allow setting of + all fields. + + *Steve Henson* + + * Add print and set support for Issuing Distribution Point CRL extension. + + *Steve Henson* + + * Change 'Configure' script to enable Camellia by default. + + *NTT* + +OpenSSL 0.9.x +------------- + +### Changes between 0.9.8m and 0.9.8n [24 Mar 2010] + + * When rejecting SSL/TLS records due to an incorrect version number, never + update s->server with a new major version number. As of + - OpenSSL 0.9.8m if 'short' is a 16-bit type, + - OpenSSL 0.9.8f if 'short' is longer than 16 bits, + the previous behavior could result in a read attempt at NULL when + receiving specific incorrect SSL/TLS records once record payload + protection is active. ([CVE-2010-0740]) + + *Bodo Moeller, Adam Langley * + + * Fix for CVE-2010-0433 where some kerberos enabled versions of OpenSSL + could be crashed if the relevant tables were not present (e.g. chrooted). + + *Tomas Hoger * + +### Changes between 0.9.8l and 0.9.8m [25 Feb 2010] + + * Always check bn_wexpand() return values for failure. ([CVE-2009-3245]) + + *Martin Olsson, Neel Mehta* + + * Fix X509_STORE locking: Every 'objs' access requires a lock (to + accommodate for stack sorting, always a write lock!). + + *Bodo Moeller* + + * On some versions of WIN32 Heap32Next is very slow. This can cause + excessive delays in the RAND_poll(): over a minute. As a workaround + include a time check in the inner Heap32Next loop too. + + *Steve Henson* + + * The code that handled flushing of data in SSL/TLS originally used the + BIO_CTRL_INFO ctrl to see if any data was pending first. This caused + the problem outlined in PR#1949. The fix suggested there however can + trigger problems with buggy BIO_CTRL_WPENDING (e.g. some versions + of Apache). So instead simplify the code to flush unconditionally. + This should be fine since flushing with no data to flush is a no op. + + *Steve Henson* + + * Handle TLS versions 2.0 and later properly and correctly use the + highest version of TLS/SSL supported. Although TLS >= 2.0 is some way + off ancient servers have a habit of sticking around for a while... + + *Steve Henson* + + * Modify compression code so it frees up structures without using the + ex_data callbacks. This works around a problem where some applications + call CRYPTO_cleanup_all_ex_data() before application exit (e.g. when + restarting) then use compression (e.g. SSL with compression) later. + This results in significant per-connection memory leaks and + has caused some security issues including CVE-2008-1678 and + CVE-2009-4355. + + *Steve Henson* + + * Constify crypto/cast (i.e., ): a CAST_KEY doesn't + change when encrypting or decrypting. + + *Bodo Moeller* + + * Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to + connect and renegotiate with servers which do not support RI. + Until RI is more widely deployed this option is enabled by default. + + *Steve Henson* + + * Add "missing" ssl ctrls to clear options and mode. + + *Steve Henson* + + * If client attempts to renegotiate and doesn't support RI respond with + a no_renegotiation alert as required by RFC5746. Some renegotiating + TLS clients will continue a connection gracefully when they receive + the alert. Unfortunately OpenSSL mishandled this alert and would hang + waiting for a server hello which it will never receive. Now we treat a + received no_renegotiation alert as a fatal error. This is because + applications requesting a renegotiation might well expect it to succeed + and would have no code in place to handle the server denying it so the + only safe thing to do is to terminate the connection. + + *Steve Henson* + + * Add ctrl macro SSL_get_secure_renegotiation_support() which returns 1 if + peer supports secure renegotiation and 0 otherwise. Print out peer + renegotiation support in s_client/s_server. + + *Steve Henson* + + * Replace the highly broken and deprecated SPKAC certification method with + the updated NID creation version. This should correctly handle UTF8. + + *Steve Henson* + + * Implement RFC5746. Re-enable renegotiation but require the extension + as needed. Unfortunately, SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION + turns out to be a bad idea. It has been replaced by + SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with + SSL_CTX_set_options(). This is really not recommended unless you + know what you are doing. + + *Eric Rescorla , Ben Laurie, Steve Henson* + + * Fixes to stateless session resumption handling. Use initial_ctx when + issuing and attempting to decrypt tickets in case it has changed during + servername handling. Use a non-zero length session ID when attempting + stateless session resumption: this makes it possible to determine if + a resumption has occurred immediately after receiving server hello + (several places in OpenSSL subtly assume this) instead of later in + the handshake. + + *Steve Henson* + + * The functions ENGINE_ctrl(), OPENSSL_isservice(), + CMS_get1_RecipientRequest() and RAND_bytes() can return <=0 on error + fixes for a few places where the return code is not checked + correctly. + + *Julia Lawall * + + * Add --strict-warnings option to Configure script to include devteam + warnings in other configurations. + + *Steve Henson* + + * Add support for --libdir option and LIBDIR variable in makefiles. This + makes it possible to install openssl libraries in locations which + have names other than "lib", for example "/usr/lib64" which some + systems need. + + *Steve Henson, based on patch from Jeremy Utley* + + * Don't allow the use of leading 0x80 in OIDs. This is a violation of + X690 8.9.12 and can produce some misleading textual output of OIDs. + + *Steve Henson, reported by Dan Kaminsky* + + * Delete MD2 from algorithm tables. This follows the recommendation in + several standards that it is not used in new applications due to + several cryptographic weaknesses. For binary compatibility reasons + the MD2 API is still compiled in by default. + + *Steve Henson* + + * Add compression id to {d2i,i2d}_SSL_SESSION so it is correctly saved + and restored. + + *Steve Henson* + + * Rename uni2asc and asc2uni functions to OPENSSL_uni2asc and + OPENSSL_asc2uni conditionally on Netware platforms to avoid a name + clash. + + *Guenter * + + * Fix the server certificate chain building code to use X509_verify_cert(), + it used to have an ad-hoc builder which was unable to cope with anything + other than a simple chain. + + *David Woodhouse , Steve Henson* + + * Don't check self signed certificate signatures in X509_verify_cert() + by default (a flag can override this): it just wastes time without + adding any security. As a useful side effect self signed root CAs + with non-FIPS digests are now usable in FIPS mode. + + *Steve Henson* + + * In dtls1_process_out_of_seq_message() the check if the current message + is already buffered was missing. For every new message was memory + allocated, allowing an attacker to perform an denial of service attack + with sending out of seq handshake messages until there is no memory + left. Additionally every future message was buffered, even if the + sequence number made no sense and would be part of another handshake. + So only messages with sequence numbers less than 10 in advance will be + buffered. ([CVE-2009-1378]) + + *Robin Seggelmann, discovered by Daniel Mentz* + + * Records are buffered if they arrive with a future epoch to be + processed after finishing the corresponding handshake. There is + currently no limitation to this buffer allowing an attacker to perform + a DOS attack with sending records with future epochs until there is no + memory left. This patch adds the pqueue_size() function to determine + the size of a buffer and limits the record buffer to 100 entries. + ([CVE-2009-1377]) + + *Robin Seggelmann, discovered by Daniel Mentz* + + * Keep a copy of frag->msg_header.frag_len so it can be used after the + parent structure is freed. ([CVE-2009-1379]) + + *Daniel Mentz* + + * Handle non-blocking I/O properly in SSL_shutdown() call. + + *Darryl Miles * + + * Add `2.5.4.*` OIDs + + *Ilya O. * + +### Changes between 0.9.8k and 0.9.8l [5 Nov 2009] + + * Disable renegotiation completely - this fixes a severe security + problem ([CVE-2009-3555]) at the cost of breaking all + renegotiation. Renegotiation can be re-enabled by setting + SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION in s3->flags at + run-time. This is really not recommended unless you know what + you're doing. + + *Ben Laurie* + +### Changes between 0.9.8j and 0.9.8k [25 Mar 2009] + + * Don't set val to NULL when freeing up structures, it is freed up by + underlying code. If `sizeof(void *) > sizeof(long)` this can result in + zeroing past the valid field. ([CVE-2009-0789]) + + *Paolo Ganci * + + * Fix bug where return value of CMS_SignerInfo_verify_content() was not + checked correctly. This would allow some invalid signed attributes to + appear to verify correctly. ([CVE-2009-0591]) + + *Ivan Nestlerode * + + * Reject UniversalString and BMPString types with invalid lengths. This + prevents a crash in ASN1_STRING_print_ex() which assumes the strings have + a legal length. ([CVE-2009-0590]) + + *Steve Henson* + + * Set S/MIME signing as the default purpose rather than setting it + unconditionally. This allows applications to override it at the store + level. + + *Steve Henson* + + * Permit restricted recursion of ASN1 strings. This is needed in practice + to handle some structures. + + *Steve Henson* + + * Improve efficiency of mem_gets: don't search whole buffer each time + for a '\n' + + *Jeremy Shapiro * + + * New -hex option for openssl rand. + + *Matthieu Herrb* + + * Print out UTF8String and NumericString when parsing ASN1. + + *Steve Henson* + + * Support NumericString type for name components. + + *Steve Henson* + + * Allow CC in the environment to override the automatically chosen + compiler. Note that nothing is done to ensure flags work with the + chosen compiler. + + *Ben Laurie* + +### Changes between 0.9.8i and 0.9.8j [07 Jan 2009] + + * Properly check EVP_VerifyFinal() and similar return values + ([CVE-2008-5077]). + + *Ben Laurie, Bodo Moeller, Google Security Team* + + * Enable TLS extensions by default. + + *Ben Laurie* + + * Allow the CHIL engine to be loaded, whether the application is + multithreaded or not. (This does not release the developer from the + obligation to set up the dynamic locking callbacks.) + + *Sander Temme * + + * Use correct exit code if there is an error in dgst command. + + *Steve Henson; problem pointed out by Roland Dirlewanger* + + * Tweak Configure so that you need to say "experimental-jpake" to enable + JPAKE, and need to use -DOPENSSL_EXPERIMENTAL_JPAKE in applications. + + *Bodo Moeller* + + * Add experimental JPAKE support, including demo authentication in + s_client and s_server. + + *Ben Laurie* + + * Set the comparison function in v3_addr_canonize(). + + *Rob Austein * + + * Add support for XMPP STARTTLS in s_client. + + *Philip Paeps * + + * Change the server-side SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG behavior + to ensure that even with this option, only ciphersuites in the + server's preference list will be accepted. (Note that the option + applies only when resuming a session, so the earlier behavior was + just about the algorithm choice for symmetric cryptography.) + + *Bodo Moeller* + +### Changes between 0.9.8h and 0.9.8i [15 Sep 2008] + + * Fix NULL pointer dereference if a DTLS server received + ChangeCipherSpec as first record ([CVE-2009-1386]). + + *PR #1679* + + * Fix a state transition in s3_srvr.c and d1_srvr.c + (was using SSL3_ST_CW_CLNT_HELLO_B, should be `..._ST_SW_SRVR_...`). + + *Nagendra Modadugu* + + * The fix in 0.9.8c that supposedly got rid of unsafe + double-checked locking was incomplete for RSA blinding, + addressing just one layer of what turns out to have been + doubly unsafe triple-checked locking. + + So now fix this for real by retiring the MONT_HELPER macro + in crypto/rsa/rsa_eay.c. + + *Bodo Moeller; problem pointed out by Marius Schilder* + + * Various precautionary measures: + + - Avoid size_t integer overflow in HASH_UPDATE (md32_common.h). + + - Avoid a buffer overflow in d2i_SSL_SESSION() (ssl_asn1.c). + (NB: This would require knowledge of the secret session ticket key + to exploit, in which case you'd be SOL either way.) + + - Change bn_nist.c so that it will properly handle input BIGNUMs + outside the expected range. + + - Enforce the 'num' check in BN_div() (bn_div.c) for non-BN_DEBUG + builds. + + *Neel Mehta, Bodo Moeller* + + * Allow engines to be "soft loaded" - i.e. optionally don't die if + the load fails. Useful for distros. + + *Ben Laurie and the FreeBSD team* + + * Add support for Local Machine Keyset attribute in PKCS#12 files. + + *Steve Henson* + + * Fix BN_GF2m_mod_arr() top-bit cleanup code. + + *Huang Ying* + + * Expand ENGINE to support engine supplied SSL client certificate functions. + + This work was sponsored by Logica. + + *Steve Henson* + + * Add CryptoAPI ENGINE to support use of RSA and DSA keys held in Windows + keystores. Support for SSL/TLS client authentication too. + Not compiled unless enable-capieng specified to Configure. + + This work was sponsored by Logica. + + *Steve Henson* + + * Fix bug in X509_ATTRIBUTE creation: don't set attribute using + ASN1_TYPE_set1 if MBSTRING flag set. This bug would crash certain + attribute creation routines such as certificate requests and PKCS#12 + files. + + *Steve Henson* + +### Changes between 0.9.8g and 0.9.8h [28 May 2008] + + * Fix flaw if 'Server Key exchange message' is omitted from a TLS + handshake which could lead to a client crash as found using the + Codenomicon TLS test suite ([CVE-2008-1672]) + + *Steve Henson, Mark Cox* + + * Fix double free in TLS server name extensions which could lead to + a remote crash found by Codenomicon TLS test suite ([CVE-2008-0891]) + + *Joe Orton* + + * Clear error queue in SSL_CTX_use_certificate_chain_file() + + Clear the error queue to ensure that error entries left from + older function calls do not interfere with the correct operation. + + *Lutz Jaenicke, Erik de Castro Lopo* + + * Remove root CA certificates of commercial CAs: + + The OpenSSL project does not recommend any specific CA and does not + have any policy with respect to including or excluding any CA. + Therefore it does not make any sense to ship an arbitrary selection + of root CA certificates with the OpenSSL software. + + *Lutz Jaenicke* + + * RSA OAEP patches to fix two separate invalid memory reads. + The first one involves inputs when 'lzero' is greater than + 'SHA_DIGEST_LENGTH' (it would read about SHA_DIGEST_LENGTH bytes + before the beginning of from). The second one involves inputs where + the 'db' section contains nothing but zeroes (there is a one-byte + invalid read after the end of 'db'). + + *Ivan Nestlerode * + + * Partial backport from 0.9.9-dev: + + Introduce bn_mul_mont (dedicated Montgomery multiplication + procedure) as a candidate for BIGNUM assembler implementation. + While 0.9.9-dev uses assembler for various architectures, only + x86_64 is available by default here in the 0.9.8 branch, and + 32-bit x86 is available through a compile-time setting. + + To try the 32-bit x86 assembler implementation, use Configure + option "enable-montasm" (which exists only for this backport). + + As "enable-montasm" for 32-bit x86 disclaims code stability + anyway, in this constellation we activate additional code + backported from 0.9.9-dev for further performance improvements, + namely BN_from_montgomery_word. (To enable this otherwise, + e.g. x86_64, try `-DMONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD`.) + + *Andy Polyakov (backport partially by Bodo Moeller)* + + * Add TLS session ticket callback. This allows an application to set + TLS ticket cipher and HMAC keys rather than relying on hardcoded fixed + values. This is useful for key rollover for example where several key + sets may exist with different names. + + *Steve Henson* + + * Reverse ENGINE-internal logic for caching default ENGINE handles. + This was broken until now in 0.9.8 releases, such that the only way + a registered ENGINE could be used (assuming it initialises + successfully on the host) was to explicitly set it as the default + for the relevant algorithms. This is in contradiction with 0.9.7 + behaviour and the documentation. With this fix, when an ENGINE is + registered into a given algorithm's table of implementations, the + 'uptodate' flag is reset so that auto-discovery will be used next + time a new context for that algorithm attempts to select an + implementation. + + *Ian Lister (tweaked by Geoff Thorpe)* + + * Backport of CMS code to OpenSSL 0.9.8. This differs from the 0.9.9 + implementation in the following ways: + + Lack of EVP_PKEY_ASN1_METHOD means algorithm parameters have to be + hard coded. + + Lack of BER streaming support means one pass streaming processing is + only supported if data is detached: setting the streaming flag is + ignored for embedded content. + + CMS support is disabled by default and must be explicitly enabled + with the enable-cms configuration option. + + *Steve Henson* + + * Update the GMP engine glue to do direct copies between BIGNUM and + mpz_t when openssl and GMP use the same limb size. Otherwise the + existing "conversion via a text string export" trick is still used. + + *Paul Sheer * + + * Zlib compression BIO. This is a filter BIO which compressed and + uncompresses any data passed through it. + + *Steve Henson* + + * Add AES_wrap_key() and AES_unwrap_key() functions to implement + RFC3394 compatible AES key wrapping. + + *Steve Henson* + + * Add utility functions to handle ASN1 structures. ASN1_STRING_set0(): + sets string data without copying. X509_ALGOR_set0() and + X509_ALGOR_get0(): set and retrieve X509_ALGOR (AlgorithmIdentifier) + data. Attribute function X509at_get0_data_by_OBJ(): retrieves data + from an X509_ATTRIBUTE structure optionally checking it occurs only + once. ASN1_TYPE_set1(): set and ASN1_TYPE structure copying supplied + data. + + *Steve Henson* + + * Fix BN flag handling in RSA_eay_mod_exp() and BN_MONT_CTX_set() + to get the expected BN_FLG_CONSTTIME behavior. + + *Bodo Moeller (Google)* + + * Netware support: + + - fixed wrong usage of ioctlsocket() when build for LIBC BSD sockets + - fixed do_tests.pl to run the test suite with CLIB builds too (CLIB_OPT) + - added some more tests to do_tests.pl + - fixed RunningProcess usage so that it works with newer LIBC NDKs too + - removed usage of BN_LLONG for CLIB builds to avoid runtime dependency + - added new Configure targets netware-clib-bsdsock, netware-clib-gcc, + netware-clib-bsdsock-gcc, netware-libc-bsdsock-gcc + - various changes to netware.pl to enable gcc-cross builds on Win32 + platform + - changed crypto/bio/b_sock.c to work with macro functions (CLIB BSD) + - various changes to fix missing prototype warnings + - fixed x86nasm.pl to create correct asm files for NASM COFF output + - added AES, WHIRLPOOL and CPUID assembler code to build files + - added missing AES assembler make rules to mk1mf.pl + - fixed order of includes in `apps/ocsp.c` so that `e_os.h` settings apply + + *Guenter Knauf * + + * Implement certificate status request TLS extension defined in RFC3546. + A client can set the appropriate parameters and receive the encoded + OCSP response via a callback. A server can query the supplied parameters + and set the encoded OCSP response in the callback. Add simplified examples + to s_client and s_server. + + *Steve Henson* + +### Changes between 0.9.8f and 0.9.8g [19 Oct 2007] + + * Fix various bugs: + + Binary incompatibility of ssl_ctx_st structure + + DTLS interoperation with non-compliant servers + + Don't call get_session_cb() without proposed session + + Fix ia64 assembler code + + *Andy Polyakov, Steve Henson* + +### Changes between 0.9.8e and 0.9.8f [11 Oct 2007] + + * DTLS Handshake overhaul. There were longstanding issues with + OpenSSL DTLS implementation, which were making it impossible for + RFC 4347 compliant client to communicate with OpenSSL server. + Unfortunately just fixing these incompatibilities would "cut off" + pre-0.9.8f clients. To allow for hassle free upgrade post-0.9.8e + server keeps tolerating non RFC compliant syntax. The opposite is + not true, 0.9.8f client can not communicate with earlier server. + This update even addresses CVE-2007-4995. + + *Andy Polyakov* + + * Changes to avoid need for function casts in OpenSSL: some compilers + (gcc 4.2 and later) reject their use. + *Kurt Roeckx , Peter Hartley , + Steve Henson* + + * Add RFC4507 support to OpenSSL. This includes the corrections in + RFC4507bis. The encrypted ticket format is an encrypted encoded + SSL_SESSION structure, that way new session features are automatically + supported. + + If a client application caches session in an SSL_SESSION structure + support is transparent because tickets are now stored in the encoded + SSL_SESSION. + + The SSL_CTX structure automatically generates keys for ticket + protection in servers so again support should be possible + with no application modification. + + If a client or server wishes to disable RFC4507 support then the option + SSL_OP_NO_TICKET can be set. + + Add a TLS extension debugging callback to allow the contents of any client + or server extensions to be examined. + + This work was sponsored by Google. + + *Steve Henson* + + * Add initial support for TLS extensions, specifically for the server_name + extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now + have new members for a host name. The SSL data structure has an + additional member `SSL_CTX *initial_ctx` so that new sessions can be + stored in that context to allow for session resumption, even after the + SSL has been switched to a new SSL_CTX in reaction to a client's + server_name extension. + + New functions (subject to change): + + SSL_get_servername() + SSL_get_servername_type() + SSL_set_SSL_CTX() + + New CTRL codes and macros (subject to change): + + SSL_CTRL_SET_TLSEXT_SERVERNAME_CB + - SSL_CTX_set_tlsext_servername_callback() + SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG + - SSL_CTX_set_tlsext_servername_arg() + SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name() + + openssl s_client has a new '-servername ...' option. + + openssl s_server has new options '-servername_host ...', '-cert2 ...', + '-key2 ...', '-servername_fatal' (subject to change). This allows + testing the HostName extension for a specific single host name ('-cert' + and '-key' remain fallbacks for handshakes without HostName + negotiation). If the unrecognized_name alert has to be sent, this by + default is a warning; it becomes fatal with the '-servername_fatal' + option. + + *Peter Sylvester, Remy Allais, Christophe Renou, Steve Henson* + + * Add AES and SSE2 assembly language support to VC++ build. + + *Steve Henson* + + * Mitigate attack on final subtraction in Montgomery reduction. + + *Andy Polyakov* + + * Fix crypto/ec/ec_mult.c to work properly with scalars of value 0 + (which previously caused an internal error). + + *Bodo Moeller* + + * Squeeze another 10% out of IGE mode when in != out. + + *Ben Laurie* + + * AES IGE mode speedup. + + *Dean Gaudet (Google)* + + * Add the Korean symmetric 128-bit cipher SEED (see + ) and + add SEED ciphersuites from RFC 4162: + + TLS_RSA_WITH_SEED_CBC_SHA = "SEED-SHA" + TLS_DHE_DSS_WITH_SEED_CBC_SHA = "DHE-DSS-SEED-SHA" + TLS_DHE_RSA_WITH_SEED_CBC_SHA = "DHE-RSA-SEED-SHA" + TLS_DH_anon_WITH_SEED_CBC_SHA = "ADH-SEED-SHA" + + To minimize changes between patchlevels in the OpenSSL 0.9.8 + series, SEED remains excluded from compilation unless OpenSSL + is configured with 'enable-seed'. + + *KISA, Bodo Moeller* + + * Mitigate branch prediction attacks, which can be practical if a + single processor is shared, allowing a spy process to extract + information. For detailed background information, see + (O. Aciicmez, S. Gueron, + J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL + and Necessary Software Countermeasures"). The core of the change + are new versions BN_div_no_branch() and + BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(), + respectively, which are slower, but avoid the security-relevant + conditional branches. These are automatically called by BN_div() + and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for one + of the input BIGNUMs. Also, BN_is_bit_set() has been changed to + remove a conditional branch. + + BN_FLG_CONSTTIME is the new name for the previous + BN_FLG_EXP_CONSTTIME flag, since it now affects more than just + modular exponentiation. (Since OpenSSL 0.9.7h, setting this flag + in the exponent causes BN_mod_exp_mont() to use the alternative + implementation in BN_mod_exp_mont_consttime().) The old name + remains as a deprecated alias. + + Similarly, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general + RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses + constant-time implementations for more than just exponentiation. + Here too the old name is kept as a deprecated alias. + + BN_BLINDING_new() will now use BN_dup() for the modulus so that + the BN_BLINDING structure gets an independent copy of the + modulus. This means that the previous `BIGNUM *m` argument to + BN_BLINDING_new() and to BN_BLINDING_create_param() now + essentially becomes `const BIGNUM *m`, although we can't actually + change this in the header file before 0.9.9. It allows + RSA_setup_blinding() to use BN_with_flags() on the modulus to + enable BN_FLG_CONSTTIME. + + *Matthew D Wood (Intel Corp)* + + * In the SSL/TLS server implementation, be strict about session ID + context matching (which matters if an application uses a single + external cache for different purposes). Previously, + out-of-context reuse was forbidden only if SSL_VERIFY_PEER was + set. This did ensure strict client verification, but meant that, + with applications using a single external cache for quite + different requirements, clients could circumvent ciphersuite + restrictions for a given session ID context by starting a session + in a different context. + + *Bodo Moeller* + + * Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that + a ciphersuite string such as "DEFAULT:RSA" cannot enable + authentication-only ciphersuites. + + *Bodo Moeller* + + * Update the SSL_get_shared_ciphers() fix CVE-2006-3738 which was + not complete and could lead to a possible single byte overflow + ([CVE-2007-5135]) [Ben Laurie] + +### Changes between 0.9.8d and 0.9.8e [23 Feb 2007] + + * Since AES128 and AES256 (and similarly Camellia128 and + Camellia256) share a single mask bit in the logic of + ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a + kludge to work properly if AES128 is available and AES256 isn't + (or if Camellia128 is available and Camellia256 isn't). + + *Victor Duchovni* + + * Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c + (within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters): + When a point or a seed is encoded in a BIT STRING, we need to + prevent the removal of trailing zero bits to get the proper DER + encoding. (By default, crypto/asn1/a_bitstr.c assumes the case + of a NamedBitList, for which trailing 0 bits need to be removed.) + + *Bodo Moeller* + + * Have SSL/TLS server implementation tolerate "mismatched" record + protocol version while receiving ClientHello even if the + ClientHello is fragmented. (The server can't insist on the + particular protocol version it has chosen before the ServerHello + message has informed the client about his choice.) + + *Bodo Moeller* + + * Add RFC 3779 support. + + *Rob Austein for ARIN, Ben Laurie* + + * Load error codes if they are not already present instead of using a + static variable. This allows them to be cleanly unloaded and reloaded. + Improve header file function name parsing. + + *Steve Henson* + + * extend SMTP and IMAP protocol emulation in s_client to use EHLO + or CAPABILITY handshake as required by RFCs. + + *Goetz Babin-Ebell* + +### Changes between 0.9.8c and 0.9.8d [28 Sep 2006] + + * Introduce limits to prevent malicious keys being able to + cause a denial of service. ([CVE-2006-2940]) + + *Steve Henson, Bodo Moeller* + + * Fix ASN.1 parsing of certain invalid structures that can result + in a denial of service. ([CVE-2006-2937]) [Steve Henson] + + * Fix buffer overflow in SSL_get_shared_ciphers() function. + ([CVE-2006-3738]) [Tavis Ormandy and Will Drewry, Google Security Team] + + * Fix SSL client code which could crash if connecting to a + malicious SSLv2 server. ([CVE-2006-4343]) + + *Tavis Ormandy and Will Drewry, Google Security Team* + + * Since 0.9.8b, ciphersuite strings naming explicit ciphersuites + match only those. Before that, "AES256-SHA" would be interpreted + as a pattern and match "AES128-SHA" too (since AES128-SHA got + the same strength classification in 0.9.7h) as we currently only + have a single AES bit in the ciphersuite description bitmap. + That change, however, also applied to ciphersuite strings such as + "RC4-MD5" that intentionally matched multiple ciphersuites -- + namely, SSL 2.0 ciphersuites in addition to the more common ones + from SSL 3.0/TLS 1.0. + + So we change the selection algorithm again: Naming an explicit + ciphersuite selects this one ciphersuite, and any other similar + ciphersuite (same bitmap) from *other* protocol versions. + Thus, "RC4-MD5" again will properly select both the SSL 2.0 + ciphersuite and the SSL 3.0/TLS 1.0 ciphersuite. + + Since SSL 2.0 does not have any ciphersuites for which the + 128/256 bit distinction would be relevant, this works for now. + The proper fix will be to use different bits for AES128 and + AES256, which would have avoided the problems from the beginning; + however, bits are scarce, so we can only do this in a new release + (not just a patchlevel) when we can change the SSL_CIPHER + definition to split the single 'unsigned long mask' bitmap into + multiple values to extend the available space. + + *Bodo Moeller* + +### Changes between 0.9.8b and 0.9.8c [05 Sep 2006] + + * Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher + ([CVE-2006-4339]) [Ben Laurie and Google Security Team] + + * Add AES IGE and biIGE modes. + + *Ben Laurie* + + * Change the Unix randomness entropy gathering to use poll() when + possible instead of select(), since the latter has some + undesirable limitations. + + *Darryl Miles via Richard Levitte and Bodo Moeller* + + * Disable "ECCdraft" ciphersuites more thoroughly. Now special + treatment in ssl/ssl_ciph.s makes sure that these ciphersuites + cannot be implicitly activated as part of, e.g., the "AES" alias. + However, please upgrade to OpenSSL 0.9.9[-dev] for + non-experimental use of the ECC ciphersuites to get TLS extension + support, which is required for curve and point format negotiation + to avoid potential handshake problems. + + *Bodo Moeller* + + * Disable rogue ciphersuites: + + - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5") + - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5") + - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5") + + The latter two were purportedly from + draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really + appear there. + + Also deactivate the remaining ciphersuites from + draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as + unofficial, and the ID has long expired. + + *Bodo Moeller* + + * Fix RSA blinding Heisenbug (problems sometimes occurred on + dual-core machines) and other potential thread-safety issues. + + *Bodo Moeller* + + * Add the symmetric cipher Camellia (128-bit, 192-bit, 256-bit key + versions), which is now available for royalty-free use + (see ). + Also, add Camellia TLS ciphersuites from RFC 4132. + + To minimize changes between patchlevels in the OpenSSL 0.9.8 + series, Camellia remains excluded from compilation unless OpenSSL + is configured with 'enable-camellia'. + + *NTT* + + * Disable the padding bug check when compression is in use. The padding + bug check assumes the first packet is of even length, this is not + necessarily true if compression is enabled and can result in false + positives causing handshake failure. The actual bug test is ancient + code so it is hoped that implementations will either have fixed it by + now or any which still have the bug do not support compression. + + *Steve Henson* + +### Changes between 0.9.8a and 0.9.8b [04 May 2006] + + * When applying a cipher rule check to see if string match is an explicit + cipher suite and only match that one cipher suite if it is. + + *Steve Henson* + + * Link in manifests for VC++ if needed. + + *Austin Ziegler * + + * Update support for ECC-based TLS ciphersuites according to + draft-ietf-tls-ecc-12.txt with proposed changes (but without + TLS extensions, which are supported starting with the 0.9.9 + branch, not in the OpenSSL 0.9.8 branch). + + *Douglas Stebila* + + * New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free() to support + opaque EVP_CIPHER_CTX handling. + + *Steve Henson* + + * Fixes and enhancements to zlib compression code. We now only use + "zlib1.dll" and use the default `__cdecl` calling convention on Win32 + to conform with the standards mentioned here: + + Static zlib linking now works on Windows and the new --with-zlib-include + --with-zlib-lib options to Configure can be used to supply the location + of the headers and library. Gracefully handle case where zlib library + can't be loaded. + + *Steve Henson* + + * Several fixes and enhancements to the OID generation code. The old code + sometimes allowed invalid OIDs (1.X for X >= 40 for example), couldn't + handle numbers larger than ULONG_MAX, truncated printing and had a + non standard OBJ_obj2txt() behaviour. + + *Steve Henson* + + * Add support for building of engines under engine/ as shared libraries + under VC++ build system. + + *Steve Henson* + + * Corrected the numerous bugs in the Win32 path splitter in DSO. + Hopefully, we will not see any false combination of paths any more. + + *Richard Levitte* + +### Changes between 0.9.8 and 0.9.8a [11 Oct 2005] + + * Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING + (part of SSL_OP_ALL). This option used to disable the + countermeasure against man-in-the-middle protocol-version + rollback in the SSL 2.0 server implementation, which is a bad + idea. ([CVE-2005-2969]) + + *Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center + for Information Security, National Institute of Advanced Industrial + Science and Technology [AIST], Japan)* + + * Add two function to clear and return the verify parameter flags. + + *Steve Henson* + + * Keep cipherlists sorted in the source instead of sorting them at + runtime, thus removing the need for a lock. + + *Nils Larsch* + + * Avoid some small subgroup attacks in Diffie-Hellman. + + *Nick Mathewson and Ben Laurie* + + * Add functions for well-known primes. + + *Nick Mathewson* + + * Extended Windows CE support. + + *Satoshi Nakamura and Andy Polyakov* + + * Initialize SSL_METHOD structures at compile time instead of during + runtime, thus removing the need for a lock. + + *Steve Henson* + + * Make PKCS7_decrypt() work even if no certificate is supplied by + attempting to decrypt each encrypted key in turn. Add support to + smime utility. + + *Steve Henson* + +### Changes between 0.9.7h and 0.9.8 [05 Jul 2005] + +[NB: OpenSSL 0.9.7i and later 0.9.7 patch levels were released after +OpenSSL 0.9.8.] + + * Add libcrypto.pc and libssl.pc for those who feel they need them. + + *Richard Levitte* + + * Change CA.sh and CA.pl so they don't bundle the CSR and the private + key into the same file any more. + + *Richard Levitte* + + * Add initial support for Win64, both IA64 and AMD64/x64 flavors. + + *Andy Polyakov* + + * Add -utf8 command line and config file option to 'ca'. + + *Stefan and Geoff Thorpe* + + * Add attribute functions to EVP_PKEY structure. Modify + PKCS12_create() to recognize a CSP name attribute and + use it. Make -CSP option work again in pkcs12 utility. + + *Steve Henson* + + * Add new functionality to the bn blinding code: + - automatic re-creation of the BN_BLINDING parameters after + a fixed number of uses (currently 32) + - add new function for parameter creation + - introduce flags to control the update behaviour of the + BN_BLINDING parameters + - hide BN_BLINDING structure + Add a second BN_BLINDING slot to the RSA structure to improve + performance when a single RSA object is shared among several + threads. + + *Nils Larsch* + + * Add support for DTLS. + + *Nagendra Modadugu and Ben Laurie* + + * Add support for DER encoded private keys (SSL_FILETYPE_ASN1) + to SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file() + + *Walter Goulet* + + * Remove buggy and incomplete DH cert support from + ssl/ssl_rsa.c and ssl/s3_both.c + + *Nils Larsch* + + * Use SHA-1 instead of MD5 as the default digest algorithm for + the `apps/openssl` commands. + + *Nils Larsch* + + * Compile clean with "-Wall -Wmissing-prototypes + -Wstrict-prototypes -Wmissing-declarations -Werror". Currently + DEBUG_SAFESTACK must also be set. + + *Ben Laurie* + + * Change ./Configure so that certain algorithms can be disabled by default. + The new counterpiece to "no-xxx" is "enable-xxx". + + The patented RC5 and MDC2 algorithms will now be disabled unless + "enable-rc5" and "enable-mdc2", respectively, are specified. + + (IDEA remains enabled despite being patented. This is because IDEA + is frequently required for interoperability, and there is no license + fee for non-commercial use. As before, "no-idea" can be used to + avoid this algorithm.) + + *Bodo Moeller* + + * Add processing of proxy certificates (see RFC 3820). This work was + sponsored by KTH (The Royal Institute of Technology in Stockholm) and + EGEE (Enabling Grids for E-science in Europe). + + *Richard Levitte* + + * RC4 performance overhaul on modern architectures/implementations, such + as Intel P4, IA-64 and AMD64. + + *Andy Polyakov* + + * New utility extract-section.pl. This can be used specify an alternative + section number in a pod file instead of having to treat each file as + a separate case in Makefile. This can be done by adding two lines to the + pod file: + + =for comment openssl_section:XXX + + The blank line is mandatory. + + *Steve Henson* + + * New arguments -certform, -keyform and -pass for s_client and s_server + to allow alternative format key and certificate files and passphrase + sources. + + *Steve Henson* + + * New structure X509_VERIFY_PARAM which combines current verify parameters, + update associated structures and add various utility functions. + + Add new policy related verify parameters, include policy checking in + standard verify code. Enhance 'smime' application with extra parameters + to support policy checking and print out. + + *Steve Henson* + + * Add a new engine to support VIA PadLock ACE extensions in the VIA C3 + Nehemiah processors. These extensions support AES encryption in hardware + as well as RNG (though RNG support is currently disabled). + + *Michal Ludvig , with help from Andy Polyakov* + + * Deprecate `BN_[get|set]_params()` functions (they were ignored internally). + + *Geoff Thorpe* + + * New FIPS 180-2 algorithms, SHA-224/-256/-384/-512 are implemented. + + *Andy Polyakov and a number of other people* + + * Improved PowerPC platform support. Most notably BIGNUM assembler + implementation contributed by IBM. + + *Suresh Chari, Peter Waltenberg, Andy Polyakov* + + * The new 'RSA_generate_key_ex' function now takes a BIGNUM for the public + exponent rather than 'unsigned long'. There is a corresponding change to + the new 'rsa_keygen' element of the RSA_METHOD structure. + + *Jelte Jansen, Geoff Thorpe* + + * Functionality for creating the initial serial number file is now + moved from CA.pl to the 'ca' utility with a new option -create_serial. + + (Before OpenSSL 0.9.7e, CA.pl used to initialize the serial + number file to 1, which is bound to cause problems. To avoid + the problems while respecting compatibility between different 0.9.7 + patchlevels, 0.9.7e employed 'openssl x509 -next_serial' in + CA.pl for serial number initialization. With the new release 0.9.8, + we can fix the problem directly in the 'ca' utility.) + + *Steve Henson* + + * Reduced header interdependencies by declaring more opaque objects in + ossl_typ.h. As a consequence, including some headers (eg. engine.h) will + give fewer recursive includes, which could break lazy source code - so + this change is covered by the OPENSSL_NO_DEPRECATED symbol. As always, + developers should define this symbol when building and using openssl to + ensure they track the recommended behaviour, interfaces, [etc], but + backwards-compatible behaviour prevails when this isn't defined. + + *Geoff Thorpe* + + * New function X509_POLICY_NODE_print() which prints out policy nodes. + + *Steve Henson* + + * Add new EVP function EVP_CIPHER_CTX_rand_key and associated functionality. + This will generate a random key of the appropriate length based on the + cipher context. The EVP_CIPHER can provide its own random key generation + routine to support keys of a specific form. This is used in the des and + 3des routines to generate a key of the correct parity. Update S/MIME + code to use new functions and hence generate correct parity DES keys. + Add EVP_CHECK_DES_KEY #define to return an error if the key is not + valid (weak or incorrect parity). + + *Steve Henson* + + * Add a local set of CRLs that can be used by X509_verify_cert() as well + as looking them up. This is useful when the verified structure may contain + CRLs, for example PKCS#7 signedData. Modify PKCS7_verify() to use any CRLs + present unless the new PKCS7_NO_CRL flag is asserted. + + *Steve Henson* + + * Extend ASN1 oid configuration module. It now additionally accepts the + syntax: + + shortName = some long name, 1.2.3.4 + + *Steve Henson* + + * Reimplemented the BN_CTX implementation. There is now no more static + limitation on the number of variables it can handle nor the depth of the + "stack" handling for BN_CTX_start()/BN_CTX_end() pairs. The stack + information can now expand as required, and rather than having a single + static array of bignums, BN_CTX now uses a linked-list of such arrays + allowing it to expand on demand whilst maintaining the usefulness of + BN_CTX's "bundling". + + *Geoff Thorpe* + + * Add a missing BN_CTX parameter to the 'rsa_mod_exp' callback in RSA_METHOD + to allow all RSA operations to function using a single BN_CTX. + + *Geoff Thorpe* + + * Preliminary support for certificate policy evaluation and checking. This + is initially intended to pass the tests outlined in "Conformance Testing + of Relying Party Client Certificate Path Processing Logic" v1.07. + + *Steve Henson* + + * bn_dup_expand() has been deprecated, it was introduced in 0.9.7 and + remained unused and not that useful. A variety of other little bignum + tweaks and fixes have also been made continuing on from the audit (see + below). + + *Geoff Thorpe* + + * Constify all or almost all d2i, c2i, s2i and r2i functions, along with + associated ASN1, EVP and SSL functions and old ASN1 macros. + + *Richard Levitte* + + * BN_zero() only needs to set 'top' and 'neg' to zero for correct results, + and this should never fail. So the return value from the use of + BN_set_word() (which can fail due to needless expansion) is now deprecated; + if OPENSSL_NO_DEPRECATED is defined, BN_zero() is a void macro. + + *Geoff Thorpe* + + * BN_CTX_get() should return zero-valued bignums, providing the same + initialised value as BN_new(). + + *Geoff Thorpe, suggested by Ulf Möller* + + * Support for inhibitAnyPolicy certificate extension. + + *Steve Henson* + + * An audit of the BIGNUM code is underway, for which debugging code is + enabled when BN_DEBUG is defined. This makes stricter enforcements on what + is considered valid when processing BIGNUMs, and causes execution to + assert() when a problem is discovered. If BN_DEBUG_RAND is defined, + further steps are taken to deliberately pollute unused data in BIGNUM + structures to try and expose faulty code further on. For now, openssl will + (in its default mode of operation) continue to tolerate the inconsistent + forms that it has tolerated in the past, but authors and packagers should + consider trying openssl and their own applications when compiled with + these debugging symbols defined. It will help highlight potential bugs in + their own code, and will improve the test coverage for OpenSSL itself. At + some point, these tighter rules will become openssl's default to improve + maintainability, though the assert()s and other overheads will remain only + in debugging configurations. See bn.h for more details. + + *Geoff Thorpe, Nils Larsch, Ulf Möller* + + * BN_CTX_init() has been deprecated, as BN_CTX is an opaque structure + that can only be obtained through BN_CTX_new() (which implicitly + initialises it). The presence of this function only made it possible + to overwrite an existing structure (and cause memory leaks). + + *Geoff Thorpe* + + * Because of the callback-based approach for implementing LHASH as a + template type, lh_insert() adds opaque objects to hash-tables and + lh_doall() or lh_doall_arg() are typically used with a destructor callback + to clean up those corresponding objects before destroying the hash table + (and losing the object pointers). So some over-zealous constifications in + LHASH have been relaxed so that lh_insert() does not take (nor store) the + objects as "const" and the `lh_doall[_arg]` callback wrappers are not + prototyped to have "const" restrictions on the object pointers they are + given (and so aren't required to cast them away any more). + + *Geoff Thorpe* + + * The tmdiff.h API was so ugly and minimal that our own timing utility + (speed) prefers to use its own implementation. The two implementations + haven't been consolidated as yet (volunteers?) but the tmdiff API has had + its object type properly exposed (MS_TM) instead of casting to/from + `char *`. This may still change yet if someone realises MS_TM and + `ms_time_***` + aren't necessarily the greatest nomenclatures - but this is what was used + internally to the implementation so I've used that for now. + + *Geoff Thorpe* + + * Ensure that deprecated functions do not get compiled when + OPENSSL_NO_DEPRECATED is defined. Some "openssl" subcommands and a few of + the self-tests were still using deprecated key-generation functions so + these have been updated also. + + *Geoff Thorpe* + + * Reorganise PKCS#7 code to separate the digest location functionality + into PKCS7_find_digest(), digest addition into PKCS7_bio_add_digest(). + New function PKCS7_set_digest() to set the digest type for PKCS#7 + digestedData type. Add additional code to correctly generate the + digestedData type and add support for this type in PKCS7 initialization + functions. + + *Steve Henson* + + * New function PKCS7_set0_type_other() this initializes a PKCS7 + structure of type "other". + + *Steve Henson* + + * Fix prime generation loop in crypto/bn/bn_prime.pl by making + sure the loop does correctly stop and breaking ("division by zero") + modulus operations are not performed. The (pre-generated) prime + table crypto/bn/bn_prime.h was already correct, but it could not be + re-generated on some platforms because of the "division by zero" + situation in the script. + + *Ralf S. Engelschall* + + * Update support for ECC-based TLS ciphersuites according to + draft-ietf-tls-ecc-03.txt: the KDF1 key derivation function with + SHA-1 now is only used for "small" curves (where the + representation of a field element takes up to 24 bytes); for + larger curves, the field element resulting from ECDH is directly + used as premaster secret. + + *Douglas Stebila (Sun Microsystems Laboratories)* + + * Add code for kP+lQ timings to crypto/ec/ectest.c, and add SEC2 + curve secp160r1 to the tests. + + *Douglas Stebila (Sun Microsystems Laboratories)* + + * Add the possibility to load symbols globally with DSO. + + *Götz Babin-Ebell via Richard Levitte* + + * Add the functions ERR_set_mark() and ERR_pop_to_mark() for better + control of the error stack. + + *Richard Levitte* + + * Add support for STORE in ENGINE. + + *Richard Levitte* + + * Add the STORE type. The intention is to provide a common interface + to certificate and key stores, be they simple file-based stores, or + HSM-type store, or LDAP stores, or... + NOTE: The code is currently UNTESTED and isn't really used anywhere. + + *Richard Levitte* + + * Add a generic structure called OPENSSL_ITEM. This can be used to + pass a list of arguments to any function as well as provide a way + for a function to pass data back to the caller. + + *Richard Levitte* + + * Add the functions BUF_strndup() and BUF_memdup(). BUF_strndup() + works like BUF_strdup() but can be used to duplicate a portion of + a string. The copy gets NUL-terminated. BUF_memdup() duplicates + a memory area. + + *Richard Levitte* + + * Add the function sk_find_ex() which works like sk_find(), but will + return an index to an element even if an exact match couldn't be + found. The index is guaranteed to point at the element where the + searched-for key would be inserted to preserve sorting order. + + *Richard Levitte* + + * Add the function OBJ_bsearch_ex() which works like OBJ_bsearch() but + takes an extra flags argument for optional functionality. Currently, + the following flags are defined: + + OBJ_BSEARCH_VALUE_ON_NOMATCH + This one gets OBJ_bsearch_ex() to return a pointer to the first + element where the comparing function returns a negative or zero + number. + + OBJ_BSEARCH_FIRST_VALUE_ON_MATCH + This one gets OBJ_bsearch_ex() to return a pointer to the first + element where the comparing function returns zero. This is useful + if there are more than one element where the comparing function + returns zero. + + *Richard Levitte* + + * Make it possible to create self-signed certificates with 'openssl ca' + in such a way that the self-signed certificate becomes part of the + CA database and uses the same mechanisms for serial number generation + as all other certificate signing. The new flag '-selfsign' enables + this functionality. Adapt CA.sh and CA.pl.in. + + *Richard Levitte* + + * Add functionality to check the public key of a certificate request + against a given private. This is useful to check that a certificate + request can be signed by that key (self-signing). + + *Richard Levitte* + + * Make it possible to have multiple active certificates with the same + subject in the CA index file. This is done only if the keyword + 'unique_subject' is set to 'no' in the main CA section (default + if 'CA_default') of the configuration file. The value is saved + with the database itself in a separate index attribute file, + named like the index file with '.attr' appended to the name. + + *Richard Levitte* + + * Generate multi-valued AVAs using '+' notation in config files for + req and dirName. + + *Steve Henson* + + * Support for nameConstraints certificate extension. + + *Steve Henson* + + * Support for policyConstraints certificate extension. + + *Steve Henson* + + * Support for policyMappings certificate extension. + + *Steve Henson* + + * Make sure the default DSA_METHOD implementation only uses its + dsa_mod_exp() and/or bn_mod_exp() handlers if they are non-NULL, + and change its own handlers to be NULL so as to remove unnecessary + indirection. This lets alternative implementations fallback to the + default implementation more easily. + + *Geoff Thorpe* + + * Support for directoryName in GeneralName related extensions + in config files. + + *Steve Henson* + + * Make it possible to link applications using Makefile.shared. + Make that possible even when linking against static libraries! + + *Richard Levitte* + + * Support for single pass processing for S/MIME signing. This now + means that S/MIME signing can be done from a pipe, in addition + cleartext signing (multipart/signed type) is effectively streaming + and the signed data does not need to be all held in memory. + + This is done with a new flag PKCS7_STREAM. When this flag is set + PKCS7_sign() only initializes the PKCS7 structure and the actual signing + is done after the data is output (and digests calculated) in + SMIME_write_PKCS7(). + + *Steve Henson* + + * Add full support for -rpath/-R, both in shared libraries and + applications, at least on the platforms where it's known how + to do it. + + *Richard Levitte* + + * In crypto/ec/ec_mult.c, implement fast point multiplication with + precomputation, based on wNAF splitting: EC_GROUP_precompute_mult() + will now compute a table of multiples of the generator that + makes subsequent invocations of EC_POINTs_mul() or EC_POINT_mul() + faster (notably in the case of a single point multiplication, + scalar * generator). + + *Nils Larsch, Bodo Moeller* + + * IPv6 support for certificate extensions. The various extensions + which use the IP:a.b.c.d can now take IPv6 addresses using the + formats of RFC1884 2.2 . IPv6 addresses are now also displayed + correctly. + + *Steve Henson* + + * Added an ENGINE that implements RSA by performing private key + exponentiations with the GMP library. The conversions to and from + GMP's mpz_t format aren't optimised nor are any montgomery forms + cached, and on x86 it appears OpenSSL's own performance has caught up. + However there are likely to be other architectures where GMP could + provide a boost. This ENGINE is not built in by default, but it can be + specified at Configure time and should be accompanied by the necessary + linker additions, eg; + ./config -DOPENSSL_USE_GMP -lgmp + + *Geoff Thorpe* + + * "openssl engine" will not display ENGINE/DSO load failure errors when + testing availability of engines with "-t" - the old behaviour is + produced by increasing the feature's verbosity with "-tt". + + *Geoff Thorpe* + + * ECDSA routines: under certain error conditions uninitialized BN objects + could be freed. Solution: make sure initialization is performed early + enough. (Reported and fix supplied by Nils Larsch + via PR#459) + + *Lutz Jaenicke* + + * Key-generation can now be implemented in RSA_METHOD, DSA_METHOD + and DH_METHOD (eg. by ENGINE implementations) to override the normal + software implementations. For DSA and DH, parameter generation can + also be overridden by providing the appropriate method callbacks. + + *Geoff Thorpe* + + * Change the "progress" mechanism used in key-generation and + primality testing to functions that take a new BN_GENCB pointer in + place of callback/argument pairs. The new API functions have `_ex` + postfixes and the older functions are reimplemented as wrappers for + the new ones. The OPENSSL_NO_DEPRECATED symbol can be used to hide + declarations of the old functions to help (graceful) attempts to + migrate to the new functions. Also, the new key-generation API + functions operate on a caller-supplied key-structure and return + success/failure rather than returning a key or NULL - this is to + help make "keygen" another member function of RSA_METHOD etc. + + Example for using the new callback interface: + + int (*my_callback)(int a, int b, BN_GENCB *cb) = ...; + void *my_arg = ...; + BN_GENCB my_cb; + + BN_GENCB_set(&my_cb, my_callback, my_arg); + + return BN_is_prime_ex(some_bignum, BN_prime_checks, NULL, &cb); + /* For the meaning of a, b in calls to my_callback(), see the + * documentation of the function that calls the callback. + * cb will point to my_cb; my_arg can be retrieved as cb->arg. + * my_callback should return 1 if it wants BN_is_prime_ex() + * to continue, or 0 to stop. + */ + + *Geoff Thorpe* + + * Change the ZLIB compression method to be stateful, and make it + available to TLS with the number defined in + draft-ietf-tls-compression-04.txt. + + *Richard Levitte* + + * Add the ASN.1 structures and functions for CertificatePair, which + is defined as follows (according to X.509_4thEditionDraftV6.pdf): + + CertificatePair ::= SEQUENCE { + forward [0] Certificate OPTIONAL, + reverse [1] Certificate OPTIONAL, + -- at least one of the pair shall be present -- } + + Also implement the PEM functions to read and write certificate + pairs, and defined the PEM tag as "CERTIFICATE PAIR". + + This needed to be defined, mostly for the sake of the LDAP + attribute crossCertificatePair, but may prove useful elsewhere as + well. + + *Richard Levitte* + + * Make it possible to inhibit symlinking of shared libraries in + Makefile.shared, for Cygwin's sake. + + *Richard Levitte* + + * Extend the BIGNUM API by creating a function + void BN_set_negative(BIGNUM *a, int neg); + and a macro that behave like + int BN_is_negative(const BIGNUM *a); + + to avoid the need to access 'a->neg' directly in applications. + + *Nils Larsch* + + * Implement fast modular reduction for pseudo-Mersenne primes + used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c). + EC_GROUP_new_curve_GFp() will now automatically use this + if applicable. + + *Nils Larsch * + + * Add new lock type (CRYPTO_LOCK_BN). + + *Bodo Moeller* + + * Change the ENGINE framework to automatically load engines + dynamically from specific directories unless they could be + found to already be built in or loaded. Move all the + current engines except for the cryptodev one to a new + directory engines/. + The engines in engines/ are built as shared libraries if + the "shared" options was given to ./Configure or ./config. + Otherwise, they are inserted in libcrypto.a. + /usr/local/ssl/engines is the default directory for dynamic + engines, but that can be overridden at configure time through + the usual use of --prefix and/or --openssldir, and at run + time with the environment variable OPENSSL_ENGINES. + + *Geoff Thorpe and Richard Levitte* + + * Add Makefile.shared, a helper makefile to build shared + libraries. Adapt Makefile.org. + + *Richard Levitte* + + * Add version info to Win32 DLLs. + + *Peter 'Luna' Runestig" * + + * Add new 'medium level' PKCS#12 API. Certificates and keys + can be added using this API to created arbitrary PKCS#12 + files while avoiding the low-level API. + + New options to PKCS12_create(), key or cert can be NULL and + will then be omitted from the output file. The encryption + algorithm NIDs can be set to -1 for no encryption, the mac + iteration count can be set to 0 to omit the mac. + + Enhance pkcs12 utility by making the -nokeys and -nocerts + options work when creating a PKCS#12 file. New option -nomac + to omit the mac, NONE can be set for an encryption algorithm. + New code is modified to use the enhanced PKCS12_create() + instead of the low-level API. + + *Steve Henson* + + * Extend ASN1 encoder to support indefinite length constructed + encoding. This can output sequences tags and octet strings in + this form. Modify pk7_asn1.c to support indefinite length + encoding. This is experimental and needs additional code to + be useful, such as an ASN1 bio and some enhanced streaming + PKCS#7 code. + + Extend template encode functionality so that tagging is passed + down to the template encoder. + + *Steve Henson* + + * Let 'openssl req' fail if an argument to '-newkey' is not + recognized instead of using RSA as a default. + + *Bodo Moeller* + + * Add support for ECC-based ciphersuites from draft-ietf-tls-ecc-01.txt. + As these are not official, they are not included in "ALL"; + the "ECCdraft" ciphersuite group alias can be used to select them. + + *Vipul Gupta and Sumit Gupta (Sun Microsystems Laboratories)* + + * Add ECDH engine support. + + *Nils Gura and Douglas Stebila (Sun Microsystems Laboratories)* + + * Add ECDH in new directory crypto/ecdh/. + + *Douglas Stebila (Sun Microsystems Laboratories)* + + * Let BN_rand_range() abort with an error after 100 iterations + without success (which indicates a broken PRNG). + + *Bodo Moeller* + + * Change BN_mod_sqrt() so that it verifies that the input value + is really the square of the return value. (Previously, + BN_mod_sqrt would show GIGO behaviour.) + + *Bodo Moeller* + + * Add named elliptic curves over binary fields from X9.62, SECG, + and WAP/WTLS; add OIDs that were still missing. + + *Sheueling Chang Shantz and Douglas Stebila (Sun Microsystems Laboratories)* + + * Extend the EC library for elliptic curves over binary fields + (new files ec2_smpl.c, ec2_smpt.c, ec2_mult.c in crypto/ec/). + New EC_METHOD: + + EC_GF2m_simple_method + + New API functions: + + EC_GROUP_new_curve_GF2m + EC_GROUP_set_curve_GF2m + EC_GROUP_get_curve_GF2m + EC_POINT_set_affine_coordinates_GF2m + EC_POINT_get_affine_coordinates_GF2m + EC_POINT_set_compressed_coordinates_GF2m + + Point compression for binary fields is disabled by default for + patent reasons (compile with OPENSSL_EC_BIN_PT_COMP defined to + enable it). + + As binary polynomials are represented as BIGNUMs, various members + of the EC_GROUP and EC_POINT data structures can be shared + between the implementations for prime fields and binary fields; + the above `..._GF2m functions` (except for EX_GROUP_new_curve_GF2m) + are essentially identical to their `..._GFp` counterparts. + (For simplicity, the `..._GFp` prefix has been dropped from + various internal method names.) + + An internal 'field_div' method (similar to 'field_mul' and + 'field_sqr') has been added; this is used only for binary fields. + + *Sheueling Chang Shantz and Douglas Stebila (Sun Microsystems Laboratories)* + + * Optionally dispatch EC_POINT_mul(), EC_POINT_precompute_mult() + through methods ('mul', 'precompute_mult'). + + The generic implementations (now internally called 'ec_wNAF_mul' + and 'ec_wNAF_precomputed_mult') remain the default if these + methods are undefined. + + *Sheueling Chang Shantz and Douglas Stebila (Sun Microsystems Laboratories)* + + * New function EC_GROUP_get_degree, which is defined through + EC_METHOD. For curves over prime fields, this returns the bit + length of the modulus. + + *Sheueling Chang Shantz and Douglas Stebila (Sun Microsystems Laboratories)* + + * New functions EC_GROUP_dup, EC_POINT_dup. + (These simply call ..._new and ..._copy). + + *Sheueling Chang Shantz and Douglas Stebila (Sun Microsystems Laboratories)* + + * Add binary polynomial arithmetic software in crypto/bn/bn_gf2m.c. + Polynomials are represented as BIGNUMs (where the sign bit is not + used) in the following functions [macros]: + + BN_GF2m_add + BN_GF2m_sub [= BN_GF2m_add] + BN_GF2m_mod [wrapper for BN_GF2m_mod_arr] + BN_GF2m_mod_mul [wrapper for BN_GF2m_mod_mul_arr] + BN_GF2m_mod_sqr [wrapper for BN_GF2m_mod_sqr_arr] + BN_GF2m_mod_inv + BN_GF2m_mod_exp [wrapper for BN_GF2m_mod_exp_arr] + BN_GF2m_mod_sqrt [wrapper for BN_GF2m_mod_sqrt_arr] + BN_GF2m_mod_solve_quad [wrapper for BN_GF2m_mod_solve_quad_arr] + BN_GF2m_cmp [= BN_ucmp] + + (Note that only the 'mod' functions are actually for fields GF(2^m). + BN_GF2m_add() is misnomer, but this is for the sake of consistency.) + + For some functions, an the irreducible polynomial defining a + field can be given as an 'unsigned int[]' with strictly + decreasing elements giving the indices of those bits that are set; + i.e., p[] represents the polynomial + f(t) = t^p[0] + t^p[1] + ... + t^p[k] + where + p[0] > p[1] > ... > p[k] = 0. + This applies to the following functions: + + BN_GF2m_mod_arr + BN_GF2m_mod_mul_arr + BN_GF2m_mod_sqr_arr + BN_GF2m_mod_inv_arr [wrapper for BN_GF2m_mod_inv] + BN_GF2m_mod_div_arr [wrapper for BN_GF2m_mod_div] + BN_GF2m_mod_exp_arr + BN_GF2m_mod_sqrt_arr + BN_GF2m_mod_solve_quad_arr + BN_GF2m_poly2arr + BN_GF2m_arr2poly + + Conversion can be performed by the following functions: + + BN_GF2m_poly2arr + BN_GF2m_arr2poly + + bntest.c has additional tests for binary polynomial arithmetic. + + Two implementations for BN_GF2m_mod_div() are available. + The default algorithm simply uses BN_GF2m_mod_inv() and + BN_GF2m_mod_mul(). The alternative algorithm is compiled in only + if OPENSSL_SUN_GF2M_DIV is defined (patent pending; read the + copyright notice in crypto/bn/bn_gf2m.c before enabling it). + + *Sheueling Chang Shantz and Douglas Stebila (Sun Microsystems Laboratories)* + + * Add new error code 'ERR_R_DISABLED' that can be used when some + functionality is disabled at compile-time. + + *Douglas Stebila * + + * Change default behaviour of 'openssl asn1parse' so that more + information is visible when viewing, e.g., a certificate: + + Modify asn1_parse2 (crypto/asn1/asn1_par.c) so that in non-'dump' + mode the content of non-printable OCTET STRINGs is output in a + style similar to INTEGERs, but with '[HEX DUMP]' prepended to + avoid the appearance of a printable string. + + *Nils Larsch * + + * Add 'asn1_flag' and 'asn1_form' member to EC_GROUP with access + functions + EC_GROUP_set_asn1_flag() + EC_GROUP_get_asn1_flag() + EC_GROUP_set_point_conversion_form() + EC_GROUP_get_point_conversion_form() + These control ASN1 encoding details: + - Curves (i.e., groups) are encoded explicitly unless asn1_flag + has been set to OPENSSL_EC_NAMED_CURVE. + - Points are encoded in uncompressed form by default; options for + asn1_for are as for point2oct, namely + POINT_CONVERSION_COMPRESSED + POINT_CONVERSION_UNCOMPRESSED + POINT_CONVERSION_HYBRID + + Also add 'seed' and 'seed_len' members to EC_GROUP with access + functions + EC_GROUP_set_seed() + EC_GROUP_get0_seed() + EC_GROUP_get_seed_len() + This is used only for ASN1 purposes (so far). + + *Nils Larsch * + + * Add 'field_type' member to EC_METHOD, which holds the NID + of the appropriate field type OID. The new function + EC_METHOD_get_field_type() returns this value. + + *Nils Larsch * + + * Add functions + EC_POINT_point2bn() + EC_POINT_bn2point() + EC_POINT_point2hex() + EC_POINT_hex2point() + providing useful interfaces to EC_POINT_point2oct() and + EC_POINT_oct2point(). + + *Nils Larsch * + + * Change internals of the EC library so that the functions + EC_GROUP_set_generator() + EC_GROUP_get_generator() + EC_GROUP_get_order() + EC_GROUP_get_cofactor() + are implemented directly in crypto/ec/ec_lib.c and not dispatched + to methods, which would lead to unnecessary code duplication when + adding different types of curves. + + *Nils Larsch with input by Bodo Moeller* + + * Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM + arithmetic, and such that modified wNAFs are generated + (which avoid length expansion in many cases). + + *Bodo Moeller* + + * Add a function EC_GROUP_check_discriminant() (defined via + EC_METHOD) that verifies that the curve discriminant is non-zero. + + Add a function EC_GROUP_check() that makes some sanity tests + on a EC_GROUP, its generator and order. This includes + EC_GROUP_check_discriminant(). + + *Nils Larsch * + + * Add ECDSA in new directory crypto/ecdsa/. + + Add applications 'openssl ecparam' and 'openssl ecdsa' + (these are based on 'openssl dsaparam' and 'openssl dsa'). + + ECDSA support is also included in various other files across the + library. Most notably, + - 'openssl req' now has a '-newkey ecdsa:file' option; + - EVP_PKCS82PKEY (crypto/evp/evp_pkey.c) now can handle ECDSA; + - X509_PUBKEY_get (crypto/asn1/x_pubkey.c) and + d2i_PublicKey (crypto/asn1/d2i_pu.c) have been modified to make + them suitable for ECDSA where domain parameters must be + extracted before the specific public key; + - ECDSA engine support has been added. + + *Nils Larsch * + + * Include some named elliptic curves, and add OIDs from X9.62, + SECG, and WAP/WTLS. Each curve can be obtained from the new + function + EC_GROUP_new_by_curve_name(), + and the list of available named curves can be obtained with + EC_get_builtin_curves(). + Also add a 'curve_name' member to EC_GROUP objects, which can be + accessed via + EC_GROUP_set_curve_name() + EC_GROUP_get_curve_name() + + *Nils Larsch * + + * Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that + a ciphersuite string such as "DEFAULT:RSA" cannot enable + authentication-only ciphersuites. + + *Bodo Moeller* + + * Since AES128 and AES256 share a single mask bit in the logic of + ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a + kludge to work properly if AES128 is available and AES256 isn't. + + *Victor Duchovni* + + * Expand security boundary to match 1.1.1 module. + + *Steve Henson* + + * Remove redundant features: hash file source, editing of test vectors + modify fipsld to use external fips_premain.c signature. + + *Steve Henson* + + * New perl script mkfipsscr.pl to create shell scripts or batch files to + run algorithm test programs. + + *Steve Henson* + + * Make algorithm test programs more tolerant of whitespace. + + *Steve Henson* + + * Have SSL/TLS server implementation tolerate "mismatched" record + protocol version while receiving ClientHello even if the + ClientHello is fragmented. (The server can't insist on the + particular protocol version it has chosen before the ServerHello + message has informed the client about his choice.) + + *Bodo Moeller* + + * Load error codes if they are not already present instead of using a + static variable. This allows them to be cleanly unloaded and reloaded. + + *Steve Henson* + +### Changes between 0.9.7k and 0.9.7l [28 Sep 2006] + + * Introduce limits to prevent malicious keys being able to + cause a denial of service. ([CVE-2006-2940]) + + *Steve Henson, Bodo Moeller* + + * Fix ASN.1 parsing of certain invalid structures that can result + in a denial of service. ([CVE-2006-2937]) [Steve Henson] + + * Fix buffer overflow in SSL_get_shared_ciphers() function. + ([CVE-2006-3738]) [Tavis Ormandy and Will Drewry, Google Security Team] + + * Fix SSL client code which could crash if connecting to a + malicious SSLv2 server. ([CVE-2006-4343]) + + *Tavis Ormandy and Will Drewry, Google Security Team* + + * Change ciphersuite string processing so that an explicit + ciphersuite selects this one ciphersuite (so that "AES256-SHA" + will no longer include "AES128-SHA"), and any other similar + ciphersuite (same bitmap) from *other* protocol versions (so that + "RC4-MD5" will still include both the SSL 2.0 ciphersuite and the + SSL 3.0/TLS 1.0 ciphersuite). This is a backport combining + changes from 0.9.8b and 0.9.8d. + + *Bodo Moeller* + +### Changes between 0.9.7j and 0.9.7k [05 Sep 2006] + + * Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher + ([CVE-2006-4339]) [Ben Laurie and Google Security Team] + + * Change the Unix randomness entropy gathering to use poll() when + possible instead of select(), since the latter has some + undesirable limitations. + + *Darryl Miles via Richard Levitte and Bodo Moeller* + + * Disable rogue ciphersuites: + + - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5") + - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5") + - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5") + + The latter two were purportedly from + draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really + appear there. + + Also deactivate the remaining ciphersuites from + draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as + unofficial, and the ID has long expired. + + *Bodo Moeller* + + * Fix RSA blinding Heisenbug (problems sometimes occurred on + dual-core machines) and other potential thread-safety issues. + + *Bodo Moeller* + +### Changes between 0.9.7i and 0.9.7j [04 May 2006] + + * Adapt fipsld and the build system to link against the validated FIPS + module in FIPS mode. + + *Steve Henson* + + * Fixes for VC++ 2005 build under Windows. + + *Steve Henson* + + * Add new Windows build target VC-32-GMAKE for VC++. This uses GNU make + from a Windows bash shell such as MSYS. It is autodetected from the + "config" script when run from a VC++ environment. Modify standard VC++ + build to use fipscanister.o from the GNU make build. + + *Steve Henson* + +### Changes between 0.9.7h and 0.9.7i [14 Oct 2005] + + * Wrapped the definition of EVP_MAX_MD_SIZE in a #ifdef OPENSSL_FIPS. + The value now differs depending on if you build for FIPS or not. + BEWARE! A program linked with a shared FIPSed libcrypto can't be + safely run with a non-FIPSed libcrypto, as it may crash because of + the difference induced by this change. + + *Andy Polyakov* + +### Changes between 0.9.7g and 0.9.7h [11 Oct 2005] + + * Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING + (part of SSL_OP_ALL). This option used to disable the + countermeasure against man-in-the-middle protocol-version + rollback in the SSL 2.0 server implementation, which is a bad + idea. ([CVE-2005-2969]) + + *Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center + for Information Security, National Institute of Advanced Industrial + Science and Technology [AIST, Japan)]* + + * Minimal support for X9.31 signatures and PSS padding modes. This is + mainly for FIPS compliance and not fully integrated at this stage. + + *Steve Henson* + + * For DSA signing, unless DSA_FLAG_NO_EXP_CONSTTIME is set, perform + the exponentiation using a fixed-length exponent. (Otherwise, + the information leaked through timing could expose the secret key + after many signatures; cf. Bleichenbacher's attack on DSA with + biased k.) + + *Bodo Moeller* + + * Make a new fixed-window mod_exp implementation the default for + RSA, DSA, and DH private-key operations so that the sequence of + squares and multiplies and the memory access pattern are + independent of the particular secret key. This will mitigate + cache-timing and potential related attacks. + + BN_mod_exp_mont_consttime() is the new exponentiation implementation, + and this is automatically used by BN_mod_exp_mont() if the new flag + BN_FLG_EXP_CONSTTIME is set for the exponent. RSA, DSA, and DH + will use this BN flag for private exponents unless the flag + RSA_FLAG_NO_EXP_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME, or + DH_FLAG_NO_EXP_CONSTTIME, respectively, is set. + + *Matthew D Wood (Intel Corp), with some changes by Bodo Moeller* + + * Change the client implementation for SSLv23_method() and + SSLv23_client_method() so that is uses the SSL 3.0/TLS 1.0 + Client Hello message format if the SSL_OP_NO_SSLv2 option is set. + (Previously, the SSL 2.0 backwards compatible Client Hello + message format would be used even with SSL_OP_NO_SSLv2.) + + *Bodo Moeller* + + * Add support for smime-type MIME parameter in S/MIME messages which some + clients need. + + *Steve Henson* + + * New function BN_MONT_CTX_set_locked() to set montgomery parameters in + a threadsafe manner. Modify rsa code to use new function and add calls + to dsa and dh code (which had race conditions before). + + *Steve Henson* + + * Include the fixed error library code in the C error file definitions + instead of fixing them up at runtime. This keeps the error code + structures constant. + + *Steve Henson* + +### Changes between 0.9.7f and 0.9.7g [11 Apr 2005] + +[NB: OpenSSL 0.9.7h and later 0.9.7 patch levels were released after +OpenSSL 0.9.8.] + + * Fixes for newer kerberos headers. NB: the casts are needed because + the 'length' field is signed on one version and unsigned on another + with no (?) obvious way to tell the difference, without these VC++ + complains. Also the "definition" of FAR (blank) is no longer included + nor is the error ENOMEM. KRB5_PRIVATE has to be set to 1 to pick up + some needed definitions. + + *Steve Henson* + + * Undo Cygwin change. + + *Ulf Möller* + + * Added support for proxy certificates according to RFC 3820. + Because they may be a security thread to unaware applications, + they must be explicitly allowed in run-time. See + docs/HOWTO/proxy_certificates.txt for further information. + + *Richard Levitte* + +### Changes between 0.9.7e and 0.9.7f [22 Mar 2005] + + * Use (SSL_RANDOM_VALUE - 4) bytes of pseudo random data when generating + server and client random values. Previously + (SSL_RANDOM_VALUE - sizeof(time_t)) would be used which would result in + less random data when sizeof(time_t) > 4 (some 64 bit platforms). + + This change has negligible security impact because: + + 1. Server and client random values still have 24 bytes of pseudo random + data. + + 2. Server and client random values are sent in the clear in the initial + handshake. + + 3. The master secret is derived using the premaster secret (48 bytes in + size for static RSA ciphersuites) as well as client server and random + values. + + The OpenSSL team would like to thank the UK NISCC for bringing this issue + to our attention. + + *Stephen Henson, reported by UK NISCC* + + * Use Windows randomness collection on Cygwin. + + *Ulf Möller* + + * Fix hang in EGD/PRNGD query when communication socket is closed + prematurely by EGD/PRNGD. + + *Darren Tucker via Lutz Jänicke, resolves #1014* + + * Prompt for pass phrases when appropriate for PKCS12 input format. + + *Steve Henson* + + * Back-port of selected performance improvements from development + branch, as well as improved support for PowerPC platforms. + + *Andy Polyakov* + + * Add lots of checks for memory allocation failure, error codes to indicate + failure and freeing up memory if a failure occurs. + + *Nauticus Networks SSL Team , Steve Henson* + + * Add new -passin argument to dgst. + + *Steve Henson* + + * Perform some character comparisons of different types in X509_NAME_cmp: + this is needed for some certificates that re-encode DNs into UTF8Strings + (in violation of RFC3280) and can't or won't issue name rollover + certificates. + + *Steve Henson* + + * Make an explicit check during certificate validation to see that + the CA setting in each certificate on the chain is correct. As a + side effect always do the following basic checks on extensions, + not just when there's an associated purpose to the check: + + - if there is an unhandled critical extension (unless the user + has chosen to ignore this fault) + - if the path length has been exceeded (if one is set at all) + - that certain extensions fit the associated purpose (if one has + been given) + + *Richard Levitte* + +### Changes between 0.9.7d and 0.9.7e [25 Oct 2004] + + * Avoid a race condition when CRLs are checked in a multi threaded + environment. This would happen due to the reordering of the revoked + entries during signature checking and serial number lookup. Now the + encoding is cached and the serial number sort performed under a lock. + Add new STACK function sk_is_sorted(). + + *Steve Henson* + + * Add Delta CRL to the extension code. + + *Steve Henson* + + * Various fixes to s3_pkt.c so alerts are sent properly. + + *David Holmes * + + * Reduce the chances of duplicate issuer name and serial numbers (in + violation of RFC3280) using the OpenSSL certificate creation utilities. + This is done by creating a random 64 bit value for the initial serial + number when a serial number file is created or when a self signed + certificate is created using 'openssl req -x509'. The initial serial + number file is created using 'openssl x509 -next_serial' in CA.pl + rather than being initialized to 1. + + *Steve Henson* + +### Changes between 0.9.7c and 0.9.7d [17 Mar 2004] + + * Fix null-pointer assignment in do_change_cipher_spec() revealed + by using the Codenomicon TLS Test Tool ([CVE-2004-0079]) + + *Joe Orton, Steve Henson* + + * Fix flaw in SSL/TLS handshaking when using Kerberos ciphersuites + ([CVE-2004-0112]) + + *Joe Orton, Steve Henson* + + * Make it possible to have multiple active certificates with the same + subject in the CA index file. This is done only if the keyword + 'unique_subject' is set to 'no' in the main CA section (default + if 'CA_default') of the configuration file. The value is saved + with the database itself in a separate index attribute file, + named like the index file with '.attr' appended to the name. + + *Richard Levitte* + + * X509 verify fixes. Disable broken certificate workarounds when + X509_V_FLAGS_X509_STRICT is set. Check CRL issuer has cRLSign set if + keyUsage extension present. Don't accept CRLs with unhandled critical + extensions: since verify currently doesn't process CRL extensions this + rejects a CRL with *any* critical extensions. Add new verify error codes + for these cases. + + *Steve Henson* + + * When creating an OCSP nonce use an OCTET STRING inside the extnValue. + A clarification of RFC2560 will require the use of OCTET STRINGs and + some implementations cannot handle the current raw format. Since OpenSSL + copies and compares OCSP nonces as opaque blobs without any attempt at + parsing them this should not create any compatibility issues. + + *Steve Henson* + + * New md flag EVP_MD_CTX_FLAG_REUSE this allows md_data to be reused when + calling EVP_MD_CTX_copy_ex() to avoid calling OPENSSL_malloc(). Without + this HMAC (and other) operations are several times slower than OpenSSL + < 0.9.7. + + *Steve Henson* + + * Print out GeneralizedTime and UTCTime in ASN1_STRING_print_ex(). + + *Peter Sylvester * + + * Use the correct content when signing type "other". + + *Steve Henson* + +### Changes between 0.9.7b and 0.9.7c [30 Sep 2003] + + * Fix various bugs revealed by running the NISCC test suite: + + Stop out of bounds reads in the ASN1 code when presented with + invalid tags (CVE-2003-0543 and CVE-2003-0544). + + Free up ASN1_TYPE correctly if ANY type is invalid ([CVE-2003-0545]). + + If verify callback ignores invalid public key errors don't try to check + certificate signature with the NULL public key. + + *Steve Henson* + + * New -ignore_err option in ocsp application to stop the server + exiting on the first error in a request. + + *Steve Henson* + + * In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate + if the server requested one: as stated in TLS 1.0 and SSL 3.0 + specifications. + + *Steve Henson* + + * In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional + extra data after the compression methods not only for TLS 1.0 + but also for SSL 3.0 (as required by the specification). + + *Bodo Moeller; problem pointed out by Matthias Loepfe* + + * Change X509_certificate_type() to mark the key as exported/exportable + when it's 512 *bits* long, not 512 bytes. + + *Richard Levitte* + + * Change AES_cbc_encrypt() so it outputs exact multiple of + blocks during encryption. + + *Richard Levitte* + + * Various fixes to base64 BIO and non blocking I/O. On write + flushes were not handled properly if the BIO retried. On read + data was not being buffered properly and had various logic bugs. + This also affects blocking I/O when the data being decoded is a + certain size. + + *Steve Henson* + + * Various S/MIME bugfixes and compatibility changes: + output correct application/pkcs7 MIME type if + PKCS7_NOOLDMIMETYPE is set. Tolerate some broken signatures. + Output CR+LF for EOL if PKCS7_CRLFEOL is set (this makes opening + of files as .eml work). Correctly handle very long lines in MIME + parser. + + *Steve Henson* + +### Changes between 0.9.7a and 0.9.7b [10 Apr 2003] + + * Countermeasure against the Klima-Pokorny-Rosa extension of + Bleichbacher's attack on PKCS #1 v1.5 padding: treat + a protocol version number mismatch like a decryption error + in ssl3_get_client_key_exchange (ssl/s3_srvr.c). + + *Bodo Moeller* + + * Turn on RSA blinding by default in the default implementation + to avoid a timing attack. Applications that don't want it can call + RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING. + They would be ill-advised to do so in most cases. + + *Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller* + + * Change RSA blinding code so that it works when the PRNG is not + seeded (in this case, the secret RSA exponent is abused as + an unpredictable seed -- if it is not unpredictable, there + is no point in blinding anyway). Make RSA blinding thread-safe + by remembering the creator's thread ID in rsa->blinding and + having all other threads use local one-time blinding factors + (this requires more computation than sharing rsa->blinding, but + avoids excessive locking; and if an RSA object is not shared + between threads, blinding will still be very fast). + + *Bodo Moeller* + + * Fixed a typo bug that would cause ENGINE_set_default() to set an + ENGINE as defaults for all supported algorithms irrespective of + the 'flags' parameter. 'flags' is now honoured, so applications + should make sure they are passing it correctly. + + *Geoff Thorpe* + + * Target "mingw" now allows native Windows code to be generated in + the Cygwin environment as well as with the MinGW compiler. + + *Ulf Moeller* + +### Changes between 0.9.7 and 0.9.7a [19 Feb 2003] + + * In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked + via timing by performing a MAC computation even if incorrect + block cipher padding has been found. This is a countermeasure + against active attacks where the attacker has to distinguish + between bad padding and a MAC verification error. ([CVE-2003-0078]) + + *Bodo Moeller; problem pointed out by Brice Canvel (EPFL), + Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and + Martin Vuagnoux (EPFL, Ilion)* + + * Make the no-err option work as intended. The intention with no-err + is not to have the whole error stack handling routines removed from + libcrypto, it's only intended to remove all the function name and + 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 its + own set of error texts inserted. The routines are there, just not + used by default when no-err is given. + + *Richard Levitte* + + * Add support for FreeBSD on IA64. + + *dirk.meyer@dinoex.sub.org via Richard Levitte, resolves #454* + + * Adjust DES_cbc_cksum() so it returns the same value as the MIT + Kerberos function mit_des_cbc_cksum(). Before this change, + the value returned by DES_cbc_cksum() was like the one from + mit_des_cbc_cksum(), except the bytes were swapped. + + *Kevin Greaney and Richard Levitte* + + * Allow an application to disable the automatic SSL chain building. + Before this a rather primitive chain build was always performed in + ssl3_output_cert_chain(): an application had no way to send the + correct chain if the automatic operation produced an incorrect result. + + Now the chain builder is disabled if either: + + 1. Extra certificates are added via SSL_CTX_add_extra_chain_cert(). + + 2. The mode flag SSL_MODE_NO_AUTO_CHAIN is set. + + The reasoning behind this is that an application would not want the + auto chain building to take place if extra chain certificates are + present and it might also want a means of sending no additional + certificates (for example the chain has two certificates and the + root is omitted). + + *Steve Henson* + + * Add the possibility to build without the ENGINE framework. + + *Steven Reddie via Richard Levitte* + + * Under Win32 gmtime() can return NULL: check return value in + OPENSSL_gmtime(). Add error code for case where gmtime() fails. + + *Steve Henson* + + * DSA routines: under certain error conditions uninitialized BN objects + could be freed. Solution: make sure initialization is performed early + enough. (Reported and fix supplied by Ivan D Nestlerode , + Nils Larsch via PR#459) + + *Lutz Jaenicke* + + * Another fix for SSLv2 session ID handling: the session ID was incorrectly + checked on reconnect on the client side, therefore session resumption + could still fail with a "ssl session id is different" error. This + behaviour is masked when SSL_OP_ALL is used due to + SSL_OP_MICROSOFT_SESS_ID_BUG being set. + Behaviour observed by Crispin Flowerday as + followup to PR #377. + + *Lutz Jaenicke* + + * IA-32 assembler support enhancements: unified ELF targets, support + for SCO/Caldera platforms, fix for Cygwin shared build. + + *Andy Polyakov* + + * Add support for FreeBSD on sparc64. As a consequence, support for + FreeBSD on non-x86 processors is separate from x86 processors on + the config script, much like the NetBSD support. + + *Richard Levitte & Kris Kennaway * + +### Changes between 0.9.6h and 0.9.7 [31 Dec 2002] + +[NB: OpenSSL 0.9.6i and later 0.9.6 patch levels were released after +OpenSSL 0.9.7.] + + * Fix session ID handling in SSLv2 client code: the SERVER FINISHED + code (06) was taken as the first octet of the session ID and the last + octet was ignored consequently. As a result SSLv2 client side session + caching could not have worked due to the session ID mismatch between + client and server. + Behaviour observed by Crispin Flowerday as + PR #377. + + *Lutz Jaenicke* + + * Change the declaration of needed Kerberos libraries to use EX_LIBS + instead of the special (and badly supported) LIBKRB5. LIBKRB5 is + removed entirely. + + *Richard Levitte* + + * The hw_ncipher.c engine requires dynamic locks. Unfortunately, it + seems that in spite of existing for more than a year, many application + author have done nothing to provide the necessary callbacks, which + means that this particular engine will not work properly anywhere. + This is a very unfortunate situation which forces us, in the name + of usability, to give the hw_ncipher.c a static lock, which is part + of libcrypto. + NOTE: This is for the 0.9.7 series ONLY. This hack will never + appear in 0.9.8 or later. We EXPECT application authors to have + dealt properly with this when 0.9.8 is released (unless we actually + make such changes in the libcrypto locking code that changes will + have to be made anyway). + + *Richard Levitte* + + * In asn1_d2i_read_bio() repeatedly call BIO_read() until all content + octets have been read, EOF or an error occurs. Without this change + some truncated ASN1 structures will not produce an error. + + *Steve Henson* + + * Disable Heimdal support, since it hasn't been fully implemented. + Still give the possibility to force the use of Heimdal, but with + warnings and a request that patches get sent to openssl-dev. + + *Richard Levitte* + + * Add the VC-CE target, introduce the WINCE sysname, and add + INSTALL.WCE and appropriate conditionals to make it build. + + *Steven Reddie via Richard Levitte* + + * Change the DLL names for Cygwin to cygcrypto-x.y.z.dll and + cygssl-x.y.z.dll, where x, y and z are the major, minor and + edit numbers of the version. + + *Corinna Vinschen and Richard Levitte* + + * Introduce safe string copy and catenation functions + (BUF_strlcpy() and BUF_strlcat()). + + *Ben Laurie (CHATS) and Richard Levitte* + + * Avoid using fixed-size buffers for one-line DNs. + + *Ben Laurie (CHATS)* + + * Add BUF_MEM_grow_clean() to avoid information leakage when + resizing buffers containing secrets, and use where appropriate. + + *Ben Laurie (CHATS)* + + * Avoid using fixed size buffers for configuration file location. + + *Ben Laurie (CHATS)* + + * Avoid filename truncation for various CA files. + + *Ben Laurie (CHATS)* + + * Use sizeof in preference to magic numbers. + + *Ben Laurie (CHATS)* + + * Avoid filename truncation in cert requests. + + *Ben Laurie (CHATS)* + + * Add assertions to check for (supposedly impossible) buffer + overflows. + + *Ben Laurie (CHATS)* + + * Don't cache truncated DNS entries in the local cache (this could + potentially lead to a spoofing attack). + + *Ben Laurie (CHATS)* + + * Fix various buffers to be large enough for hex/decimal + representations in a platform independent manner. + + *Ben Laurie (CHATS)* + + * Add CRYPTO_realloc_clean() to avoid information leakage when + resizing buffers containing secrets, and use where appropriate. + + *Ben Laurie (CHATS)* + + * Add BIO_indent() to avoid much slightly worrying code to do + indents. + + *Ben Laurie (CHATS)* + + * Convert sprintf()/BIO_puts() to BIO_printf(). + + *Ben Laurie (CHATS)* + + * buffer_gets() could terminate with the buffer only half + full. Fixed. + + *Ben Laurie (CHATS)* + + * Add assertions to prevent user-supplied crypto functions from + overflowing internal buffers by having large block sizes, etc. + + *Ben Laurie (CHATS)* + + * New OPENSSL_assert() macro (similar to assert(), but enabled + unconditionally). + + *Ben Laurie (CHATS)* + + * Eliminate unused copy of key in RC4. + + *Ben Laurie (CHATS)* + + * Eliminate unused and incorrectly sized buffers for IV in pem.h. + + *Ben Laurie (CHATS)* + + * Fix off-by-one error in EGD path. + + *Ben Laurie (CHATS)* + + * If RANDFILE path is too long, ignore instead of truncating. + + *Ben Laurie (CHATS)* + + * Eliminate unused and incorrectly sized X.509 structure + CBCParameter. + + *Ben Laurie (CHATS)* + + * Eliminate unused and dangerous function knumber(). + + *Ben Laurie (CHATS)* + + * Eliminate unused and dangerous structure, KSSL_ERR. + + *Ben Laurie (CHATS)* + + * Protect against overlong session ID context length in an encoded + session object. Since these are local, this does not appear to be + exploitable. + + *Ben Laurie (CHATS)* + + * Change from security patch (see 0.9.6e below) that did not affect + the 0.9.6 release series: + + Remote buffer overflow in SSL3 protocol - an attacker could + supply an oversized master key in Kerberos-enabled versions. + ([CVE-2002-0657]) + + *Ben Laurie (CHATS)* + + * Change the SSL kerb5 codes to match RFC 2712. + + *Richard Levitte* + + * Make -nameopt work fully for req and add -reqopt switch. + + *Michael Bell , Steve Henson* + + * The "block size" for block ciphers in CFB and OFB mode should be 1. + + *Steve Henson, reported by Yngve Nysaeter Pettersen * + + * Make sure tests can be performed even if the corresponding algorithms + have been removed entirely. This was also the last step to make + OpenSSL compilable with DJGPP under all reasonable conditions. + + *Richard Levitte, Doug Kaufman * + + * Add cipher selection rules COMPLEMENTOFALL and COMPLEMENTOFDEFAULT + to allow version independent disabling of normally unselected ciphers, + which may be activated as a side-effect of selecting a single cipher. + + (E.g., cipher list string "RSA" enables ciphersuites that are left + out of "ALL" because they do not provide symmetric encryption. + "RSA:!COMPLEMEMENTOFALL" avoids these unsafe ciphersuites.) + + *Lutz Jaenicke, Bodo Moeller* + + * Add appropriate support for separate platform-dependent build + directories. The recommended way to make a platform-dependent + build directory is the following (tested on Linux), maybe with + some local tweaks: + + # Place yourself outside of the OpenSSL source tree. In + # this example, the environment variable OPENSSL_SOURCE + # is assumed to contain the absolute OpenSSL source directory. + mkdir -p objtree/"`uname -s`-`uname -r`-`uname -m`" + cd objtree/"`uname -s`-`uname -r`-`uname -m`" + (cd $OPENSSL_SOURCE; find . -type f) | while read F; do + mkdir -p `dirname $F` + ln -s $OPENSSL_SOURCE/$F $F + done + + To be absolutely sure not to disturb the source tree, a "make clean" + is a good thing. If it isn't successful, don't worry about it, + it probably means the source directory is very clean. + + *Richard Levitte* + + * Make sure any ENGINE control commands make local copies of string + pointers passed to them whenever necessary. Otherwise it is possible + the caller may have overwritten (or deallocated) the original string + data when a later ENGINE operation tries to use the stored values. + + *Götz Babin-Ebell * + + * Improve diagnostics in file reading and command-line digests. + + *Ben Laurie aided and abetted by Solar Designer * + + * Add AES modes CFB and OFB to the object database. Correct an + error in AES-CFB decryption. + + *Richard Levitte* + + * Remove most calls to EVP_CIPHER_CTX_cleanup() in evp_enc.c, this + allows existing EVP_CIPHER_CTX structures to be reused after + calling `EVP_*Final()`. This behaviour is used by encryption + BIOs and some applications. This has the side effect that + applications must explicitly clean up cipher contexts with + EVP_CIPHER_CTX_cleanup() or they will leak memory. + + *Steve Henson* + + * Check the values of dna and dnb in bn_mul_recursive before calling + bn_mul_comba (a non zero value means the a or b arrays do not contain + n2 elements) and fallback to bn_mul_normal if either is not zero. + + *Steve Henson* + + * Fix escaping of non-ASCII characters when using the -subj option + of the "openssl req" command line tool. (Robert Joop ) + + *Lutz Jaenicke* + + * Make object definitions compliant to LDAP (RFC2256): SN is the short + form for "surname", serialNumber has no short form. + Use "mail" as the short name for "rfc822Mailbox" according to RFC2798; + therefore remove "mail" short name for "internet 7". + The OID for unique identifiers in X509 certificates is + x500UniqueIdentifier, not uniqueIdentifier. + Some more OID additions. (Michael Bell ) + + *Lutz Jaenicke* + + * Add an "init" command to the ENGINE config module and auto initialize + ENGINEs. Without any "init" command the ENGINE will be initialized + after all ctrl commands have been executed on it. If init=1 the + ENGINE is initialized at that point (ctrls before that point are run + on the uninitialized ENGINE and after on the initialized one). If + init=0 then the ENGINE will not be initialized at all. + + *Steve Henson* + + * Fix the 'app_verify_callback' interface so that the user-defined + argument is actually passed to the callback: In the + SSL_CTX_set_cert_verify_callback() prototype, the callback + declaration has been changed from + int (*cb)() + into + int (*cb)(X509_STORE_CTX *,void *); + in ssl_verify_cert_chain (ssl/ssl_cert.c), the call + i=s->ctx->app_verify_callback(&ctx) + has been changed into + i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg). + + To update applications using SSL_CTX_set_cert_verify_callback(), + a dummy argument can be added to their callback functions. + + *D. K. Smetters * + + * Added the '4758cca' ENGINE to support IBM 4758 cards. + + *Maurice Gittens , touchups by Geoff Thorpe* + + * Add and OPENSSL_LOAD_CONF define which will cause + OpenSSL_add_all_algorithms() to load the openssl.cnf config file. + This allows older applications to transparently support certain + OpenSSL features: such as crypto acceleration and dynamic ENGINE loading. + Two new functions OPENSSL_add_all_algorithms_noconf() which will never + load the config file and OPENSSL_add_all_algorithms_conf() which will + always load it have also been added. + + *Steve Henson* + + * Add the OFB, CFB and CTR (all with 128 bit feedback) to AES. + Adjust NIDs and EVP layer. + + *Stephen Sprunk and Richard Levitte* + + * Config modules support in openssl utility. + + Most commands now load modules from the config file, + though in a few (such as version) this isn't done + because it couldn't be used for anything. + + In the case of ca and req the config file used is + the same as the utility itself: that is the -config + command line option can be used to specify an + alternative file. + + *Steve Henson* + + * Move default behaviour from OPENSSL_config(). If appname is NULL + use "openssl_conf" if filename is NULL use default openssl config file. + + *Steve Henson* + + * Add an argument to OPENSSL_config() to allow the use of an alternative + config section name. Add a new flag to tolerate a missing config file + and move code to CONF_modules_load_file(). + + *Steve Henson* + + * Support for crypto accelerator cards from Accelerated Encryption + Processing, www.aep.ie. (Use engine 'aep') + The support was copied from 0.9.6c [engine] and adapted/corrected + to work with the new engine framework. + + *AEP Inc. and Richard Levitte* + + * Support for SureWare crypto accelerator cards from Baltimore + Technologies. (Use engine 'sureware') + The support was copied from 0.9.6c [engine] and adapted + to work with the new engine framework. + + *Richard Levitte* + + * Have the CHIL engine fork-safe (as defined by nCipher) and actually + make the newer ENGINE framework commands for the CHIL engine work. + + *Toomas Kiisk and Richard Levitte* + + * Make it possible to produce shared libraries on ReliantUNIX. + + *Robert Dahlem via Richard Levitte* + + * Add the configuration target debug-linux-ppro. + Make 'openssl rsa' use the general key loading routines + implemented in `apps.c`, and make those routines able to + handle the key format FORMAT_NETSCAPE and the variant + FORMAT_IISSGC. + + *Toomas Kiisk via Richard Levitte* + + * Fix a crashbug and a logic bug in hwcrhk_load_pubkey(). + + *Toomas Kiisk via Richard Levitte* + + * Add -keyform to rsautl, and document -engine. + + *Richard Levitte, inspired by Toomas Kiisk * + + * Change BIO_new_file (crypto/bio/bss_file.c) to use new + BIO_R_NO_SUCH_FILE error code rather than the generic + ERR_R_SYS_LIB error code if fopen() fails with ENOENT. + + *Ben Laurie* + + * Add new functions + ERR_peek_last_error + ERR_peek_last_error_line + ERR_peek_last_error_line_data. + These are similar to + ERR_peek_error + ERR_peek_error_line + ERR_peek_error_line_data, + but report on the latest error recorded rather than the first one + still in the error queue. + + *Ben Laurie, Bodo Moeller* + + * default_algorithms option in ENGINE config module. This allows things + like: + default_algorithms = ALL + default_algorithms = RSA, DSA, RAND, CIPHERS, DIGESTS + + *Steve Henson* + + * Preliminary ENGINE config module. + + *Steve Henson* + + * New experimental application configuration code. + + *Steve Henson* + + * Change the AES code to follow the same name structure as all other + symmetric ciphers, and behave the same way. Move everything to + the directory crypto/aes, thereby obsoleting crypto/rijndael. + + *Stephen Sprunk and Richard Levitte* + + * SECURITY: remove unsafe setjmp/signal interaction from ui_openssl.c. + + *Ben Laurie and Theo de Raadt* + + * Add option to output public keys in req command. + + *Massimiliano Pala madwolf@openca.org* + + * Use wNAFs in EC_POINTs_mul() for improved efficiency + (up to about 10% better than before for P-192 and P-224). + + *Bodo Moeller* + + * New functions/macros + + SSL_CTX_set_msg_callback(ctx, cb) + SSL_CTX_set_msg_callback_arg(ctx, arg) + SSL_set_msg_callback(ssl, cb) + SSL_set_msg_callback_arg(ssl, arg) + + to request calling a callback function + + void cb(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg) + + whenever a protocol message has been completely received + (write_p == 0) or sent (write_p == 1). Here 'version' is the + protocol version according to which the SSL library interprets + the current protocol message (SSL2_VERSION, SSL3_VERSION, or + TLS1_VERSION). 'content_type' is 0 in the case of SSL 2.0, or + the content type as defined in the SSL 3.0/TLS 1.0 protocol + specification (change_cipher_spec(20), alert(21), handshake(22)). + 'buf' and 'len' point to the actual message, 'ssl' to the + SSL object, and 'arg' is the application-defined value set by + SSL[_CTX]_set_msg_callback_arg(). + + 'openssl s_client' and 'openssl s_server' have new '-msg' options + to enable a callback that displays all protocol messages. + + *Bodo Moeller* + + * Change the shared library support so shared libraries are built as + soon as the corresponding static library is finished, and thereby get + openssl and the test programs linked against the shared library. + This still only happens when the keyword "shard" has been given to + the configuration scripts. + + NOTE: shared library support is still an experimental thing, and + backward binary compatibility is still not guaranteed. + + *"Maciej W. Rozycki" and Richard Levitte* + + * Add support for Subject Information Access extension. + + *Peter Sylvester * + + * Make BUF_MEM_grow() behaviour more consistent: Initialise to zero + additional bytes when new memory had to be allocated, not just + when reusing an existing buffer. + + *Bodo Moeller* + + * New command line and configuration option 'utf8' for the req command. + This allows field values to be specified as UTF8 strings. + + *Steve Henson* + + * Add -multi and -mr options to "openssl speed" - giving multiple parallel + runs for the former and machine-readable output for the latter. + + *Ben Laurie* + + * Add '-noemailDN' option to 'openssl ca'. This prevents inclusion + of the e-mail address in the DN (i.e., it will go into a certificate + extension only). The new configuration file option 'email_in_dn = no' + has the same effect. + + *Massimiliano Pala madwolf@openca.org* + + * Change all functions with names starting with `des_` to be starting + with `DES_` instead. Add wrappers that are compatible with libdes, + but are named `_ossl_old_des_*`. Finally, add macros that map the + `des_*` symbols to the corresponding `_ossl_old_des_*` if libdes + compatibility is desired. If OpenSSL 0.9.6c compatibility is + desired, the `des_*` symbols will be mapped to `DES_*`, with one + exception. + + Since we provide two compatibility mappings, the user needs to + define the macro OPENSSL_DES_LIBDES_COMPATIBILITY if libdes + compatibility is desired. The default (i.e., when that macro + isn't defined) is OpenSSL 0.9.6c compatibility. + + There are also macros that enable and disable the support of old + des functions altogether. Those are OPENSSL_ENABLE_OLD_DES_SUPPORT + and OPENSSL_DISABLE_OLD_DES_SUPPORT. If none or both of those + are defined, the default will apply: to support the old des routines. + + In either case, one must include openssl/des.h to get the correct + definitions. Do not try to just include openssl/des_old.h, that + won't work. + + NOTE: This is a major break of an old API into a new one. Software + authors are encouraged to switch to the `DES_` style functions. Some + time in the future, des_old.h and the libdes compatibility functions + will be disable (i.e. OPENSSL_DISABLE_OLD_DES_SUPPORT will be the + default), and then completely removed. + + *Richard Levitte* + + * Test for certificates which contain unsupported critical extensions. + If such a certificate is found during a verify operation it is + rejected by default: this behaviour can be overridden by either + handling the new error X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION or + by setting the verify flag X509_V_FLAG_IGNORE_CRITICAL. A new function + X509_supported_extension() has also been added which returns 1 if a + particular extension is supported. + + *Steve Henson* + + * Modify the behaviour of EVP cipher functions in similar way to digests + to retain compatibility with existing code. + + *Steve Henson* + + * Modify the behaviour of EVP_DigestInit() and EVP_DigestFinal() to retain + compatibility with existing code. In particular the 'ctx' parameter does + not have to be to be initialized before the call to EVP_DigestInit() and + it is tidied up after a call to EVP_DigestFinal(). New function + EVP_DigestFinal_ex() which does not tidy up the ctx. Similarly function + EVP_MD_CTX_copy() changed to not require the destination to be + initialized valid and new function EVP_MD_CTX_copy_ex() added which + requires the destination to be valid. + + Modify all the OpenSSL digest calls to use EVP_DigestInit_ex(), + EVP_DigestFinal_ex() and EVP_MD_CTX_copy_ex(). + + *Steve Henson* + + * Change ssl3_get_message (ssl/s3_both.c) and the functions using it + so that complete 'Handshake' protocol structures are kept in memory + instead of overwriting 'msg_type' and 'length' with 'body' data. + + *Bodo Moeller* + + * Add an implementation of SSL_add_dir_cert_subjects_to_stack for Win32. + + *Massimo Santin via Richard Levitte* + + * Major restructuring to the underlying ENGINE code. This includes + reduction of linker bloat, separation of pure "ENGINE" manipulation + (initialisation, etc) from functionality dealing with implementations + of specific crypto interfaces. This change also introduces integrated + support for symmetric ciphers and digest implementations - so ENGINEs + can now accelerate these by providing EVP_CIPHER and EVP_MD + implementations of their own. This is detailed in + [crypto/engine/README.md](crypto/engine/README.md) + as it couldn't be adequately described here. However, there are a few + API changes worth noting - some RSA, DSA, DH, and RAND functions that + were changed in the original introduction of ENGINE code have now + reverted back - the hooking from this code to ENGINE is now a good + deal more passive and at run-time, operations deal directly with + RSA_METHODs, DSA_METHODs (etc) as they did before, rather than + dereferencing through an ENGINE pointer any more. Also, the ENGINE + functions dealing with `BN_MOD_EXP[_CRT]` handlers have been removed - + they were not being used by the framework as there is no concept of a + BIGNUM_METHOD and they could not be generalised to the new + 'ENGINE_TABLE' mechanism that underlies the new code. Similarly, + ENGINE_cpy() has been removed as it cannot be consistently defined in + the new code. + + *Geoff Thorpe* + + * Change ASN1_GENERALIZEDTIME_check() to allow fractional seconds. + + *Steve Henson* + + * Change mkdef.pl to sort symbols that get the same entry number, + and make sure the automatically generated functions `ERR_load_*` + become part of libeay.num as well. + + *Richard Levitte* + + * New function SSL_renegotiate_pending(). This returns true once + renegotiation has been requested (either SSL_renegotiate() call + or HelloRequest/ClientHello received from the peer) and becomes + false once a handshake has been completed. + (For servers, SSL_renegotiate() followed by SSL_do_handshake() + sends a HelloRequest, but does not ensure that a handshake takes + place. SSL_renegotiate_pending() is useful for checking if the + client has followed the request.) + + *Bodo Moeller* + + * New SSL option SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION. + By default, clients may request session resumption even during + renegotiation (if session ID contexts permit); with this option, + session resumption is possible only in the first handshake. + + SSL_OP_ALL is now 0x00000FFFL instead of 0x000FFFFFL. This makes + more bits available for options that should not be part of + SSL_OP_ALL (such as SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION). + + *Bodo Moeller* + + * Add some demos for certificate and certificate request creation. + + *Steve Henson* + + * Make maximum certificate chain size accepted from the peer application + settable (`SSL*_get/set_max_cert_list()`), as proposed by + "Douglas E. Engert" . + + *Lutz Jaenicke* + + * Add support for shared libraries for Unixware-7 + (Boyd Lynn Gerber ). + + *Lutz Jaenicke* + + * Add a "destroy" handler to ENGINEs that allows structural cleanup to + be done prior to destruction. Use this to unload error strings from + ENGINEs that load their own error strings. NB: This adds two new API + functions to "get" and "set" this destroy handler in an ENGINE. + + *Geoff Thorpe* + + * Alter all existing ENGINE implementations (except "openssl" and + "openbsd") to dynamically instantiate their own error strings. This + makes them more flexible to be built both as statically-linked ENGINEs + and self-contained shared-libraries loadable via the "dynamic" ENGINE. + Also, add stub code to each that makes building them as self-contained + shared-libraries easier (see [README-Engine.md](README-Engine.md)). + + *Geoff Thorpe* + + * Add a "dynamic" ENGINE that provides a mechanism for binding ENGINE + implementations into applications that are completely implemented in + self-contained shared-libraries. The "dynamic" ENGINE exposes control + commands that can be used to configure what shared-library to load and + to control aspects of the way it is handled. Also, made an update to + the [README-Engine.md](README-Engine.md) file + that brings its information up-to-date and + provides some information and instructions on the "dynamic" ENGINE + (ie. how to use it, how to build "dynamic"-loadable ENGINEs, etc). + + *Geoff Thorpe* + + * Make it possible to unload ranges of ERR strings with a new + "ERR_unload_strings" function. + + *Geoff Thorpe* + + * Add a copy() function to EVP_MD. + + *Ben Laurie* + + * Make EVP_MD routines take a context pointer instead of just the + md_data void pointer. + + *Ben Laurie* + + * Add flags to EVP_MD and EVP_MD_CTX. EVP_MD_FLAG_ONESHOT indicates + that the digest can only process a single chunk of data + (typically because it is provided by a piece of + hardware). EVP_MD_CTX_FLAG_ONESHOT indicates that the application + is only going to provide a single chunk of data, and hence the + framework needn't accumulate the data for oneshot drivers. + + *Ben Laurie* + + * As with "ERR", make it possible to replace the underlying "ex_data" + functions. This change also alters the storage and management of global + ex_data state - it's now all inside ex_data.c and all "class" code (eg. + RSA, BIO, SSL_CTX, etc) no longer stores its own STACKS and per-class + index counters. The API functions that use this state have been changed + to take a "class_index" rather than pointers to the class's local STACK + and counter, and there is now an API function to dynamically create new + classes. This centralisation allows us to (a) plug a lot of the + thread-safety problems that existed, and (b) makes it possible to clean + up all allocated state using "CRYPTO_cleanup_all_ex_data()". W.r.t. (b) + such data would previously have always leaked in application code and + workarounds were in place to make the memory debugging turn a blind eye + to it. Application code that doesn't use this new function will still + leak as before, but their memory debugging output will announce it now + rather than letting it slide. + + Besides the addition of CRYPTO_cleanup_all_ex_data(), another API change + induced by the "ex_data" overhaul is that X509_STORE_CTX_init() now + has a return value to indicate success or failure. + + *Geoff Thorpe* + + * Make it possible to replace the underlying "ERR" functions such that the + global state (2 LHASH tables and 2 locks) is only used by the "default" + implementation. This change also adds two functions to "get" and "set" + the implementation prior to it being automatically set the first time + any other ERR function takes place. Ie. an application can call "get", + pass the return value to a module it has just loaded, and that module + can call its own "set" function using that value. This means the + module's "ERR" operations will use (and modify) the error state in the + application and not in its own statically linked copy of OpenSSL code. + + *Geoff Thorpe* + + * Give DH, DSA, and RSA types their own `*_up_ref()` function to increment + reference counts. This performs normal REF_PRINT/REF_CHECK macros on + the operation, and provides a more encapsulated way for external code + (crypto/evp/ and ssl/) to do this. Also changed the evp and ssl code + to use these functions rather than manually incrementing the counts. + + Also rename "DSO_up()" function to more descriptive "DSO_up_ref()". + + *Geoff Thorpe* + + * Add EVP test program. + + *Ben Laurie* + + * Add symmetric cipher support to ENGINE. Expect the API to change! + + *Ben Laurie* + + * New CRL functions: X509_CRL_set_version(), X509_CRL_set_issuer_name() + X509_CRL_set_lastUpdate(), X509_CRL_set_nextUpdate(), X509_CRL_sort(), + X509_REVOKED_set_serialNumber(), and X509_REVOKED_set_revocationDate(). + These allow a CRL to be built without having to access X509_CRL fields + directly. Modify 'ca' application to use new functions. + + *Steve Henson* + + * Move SSL_OP_TLS_ROLLBACK_BUG out of the SSL_OP_ALL list of recommended + bug workarounds. Rollback attack detection is a security feature. + The problem will only arise on OpenSSL servers when TLSv1 is not + available (sslv3_server_method() or SSL_OP_NO_TLSv1). + Software authors not wanting to support TLSv1 will have special reasons + for their choice and can explicitly enable this option. + + *Bodo Moeller, Lutz Jaenicke* + + * Rationalise EVP so it can be extended: don't include a union of + cipher/digest structures, add init/cleanup functions for EVP_MD_CTX + (similar to those existing for EVP_CIPHER_CTX). + Usage example: + + EVP_MD_CTX md; + + EVP_MD_CTX_init(&md); /* new function call */ + EVP_DigestInit(&md, EVP_sha1()); + EVP_DigestUpdate(&md, in, len); + EVP_DigestFinal(&md, out, NULL); + EVP_MD_CTX_cleanup(&md); /* new function call */ + + *Ben Laurie* + + * Make DES key schedule conform to the usual scheme, as well as + correcting its structure. This means that calls to DES functions + now have to pass a pointer to a des_key_schedule instead of a + plain des_key_schedule (which was actually always a pointer + anyway): E.g., + + des_key_schedule ks; + + des_set_key_checked(..., &ks); + des_ncbc_encrypt(..., &ks, ...); + + (Note that a later change renames 'des_...' into 'DES_...'.) + + *Ben Laurie* + + * Initial reduction of linker bloat: the use of some functions, such as + PEM causes large amounts of unused functions to be linked in due to + poor organisation. For example pem_all.c contains every PEM function + which has a knock on effect of linking in large amounts of (unused) + ASN1 code. Grouping together similar functions and splitting unrelated + functions prevents this. + + *Steve Henson* + + * Cleanup of EVP macros. + + *Ben Laurie* + + * Change historical references to `{NID,SN,LN}_des_ede` and ede3 to add the + correct `_ecb suffix`. + + *Ben Laurie* + + * Add initial OCSP responder support to ocsp application. The + revocation information is handled using the text based index + use by the ca application. The responder can either handle + requests generated internally, supplied in files (for example + via a CGI script) or using an internal minimal server. + + *Steve Henson* + + * Add configuration choices to get zlib compression for TLS. + + *Richard Levitte* + + * Changes to Kerberos SSL for RFC 2712 compliance: + 1. Implemented real KerberosWrapper, instead of just using + KRB5 AP_REQ message. [Thanks to Simon Wilkinson ] + 2. Implemented optional authenticator field of KerberosWrapper. + + Added openssl-style ASN.1 macros for Kerberos ticket, ap_req, + and authenticator structs; see crypto/krb5/. + + Generalized Kerberos calls to support multiple Kerberos libraries. + *Vern Staats , Jeffrey Altman + via Richard Levitte* + + * Cause 'openssl speed' to use fully hard-coded DSA keys as it + already does with RSA. testdsa.h now has 'priv_key/pub_key' + values for each of the key sizes rather than having just + parameters (and 'speed' generating keys each time). + + *Geoff Thorpe* + + * Speed up EVP routines. + Before: +crypt +pe 8 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes +s-cbc 4408.85k 5560.51k 5778.46k 5862.20k 5825.16k +s-cbc 4389.55k 5571.17k 5792.23k 5846.91k 5832.11k +s-cbc 4394.32k 5575.92k 5807.44k 5848.37k 5841.30k +crypt +s-cbc 3482.66k 5069.49k 5496.39k 5614.16k 5639.28k +s-cbc 3480.74k 5068.76k 5510.34k 5609.87k 5635.52k +s-cbc 3483.72k 5067.62k 5504.60k 5708.01k 5724.80k + After: +crypt +s-cbc 4660.16k 5650.19k 5807.19k 5827.13k 5783.32k +crypt +s-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k + + *Ben Laurie* + + * Added the OS2-EMX target. + + *"Brian Havard" and Richard Levitte* + + * Rewrite commands to use `NCONF` routines instead of the old `CONF`. + New functions to support `NCONF` routines in extension code. + New function `CONF_set_nconf()` + to allow functions which take an `NCONF` to also handle the old `LHASH` + structure: this means that the old `CONF` compatible routines can be + retained (in particular w.rt. extensions) without having to duplicate the + code. New function `X509V3_add_ext_nconf_sk()` to add extensions to a stack. + + *Steve Henson* + + * Enhance the general user interface with mechanisms for inner control + and with possibilities to have yes/no kind of prompts. + + *Richard Levitte* + + * Change all calls to low-level digest routines in the library and + applications to use EVP. Add missing calls to HMAC_cleanup() and + don't assume HMAC_CTX can be copied using memcpy(). + + *Verdon Walker , Steve Henson* + + * Add the possibility to control engines through control names but with + arbitrary arguments instead of just a string. + Change the key loaders to take a UI_METHOD instead of a callback + function pointer. NOTE: this breaks binary compatibility with earlier + versions of OpenSSL [engine]. + Adapt the nCipher code for these new conditions and add a card insertion + callback. + + *Richard Levitte* + + * Enhance the general user interface with mechanisms to better support + dialog box interfaces, application-defined prompts, the possibility + to use defaults (for example default passwords from somewhere else) + and interrupts/cancellations. + + *Richard Levitte* + + * Tidy up PKCS#12 attribute handling. Add support for the CSP name + attribute in PKCS#12 files, add new -CSP option to pkcs12 utility. + + *Steve Henson* + + * Fix a memory leak in 'sk_dup()' in the case reallocation fails. (Also + tidy up some unnecessarily weird code in 'sk_new()'). + + *Geoff, reported by Diego Tartara * + + * Change the key loading routines for ENGINEs to use the same kind + callback (pem_password_cb) as all other routines that need this + kind of callback. + + *Richard Levitte* + + * Increase ENTROPY_NEEDED to 32 bytes, as Rijndael can operate with + 256 bit (=32 byte) keys. Of course seeding with more entropy bytes + than this minimum value is recommended. + + *Lutz Jaenicke* + + * New random seeder for OpenVMS, using the system process statistics + that are easily reachable. + + *Richard Levitte* + + * Windows apparently can't transparently handle global + variables defined in DLLs. Initialisations such as: + + const ASN1_ITEM *it = &ASN1_INTEGER_it; + + won't compile. This is used by the any applications that need to + declare their own ASN1 modules. This was fixed by adding the option + EXPORT_VAR_AS_FN to all Win32 platforms, although this isn't strictly + needed for static libraries under Win32. + + *Steve Henson* + + * New functions X509_PURPOSE_set() and X509_TRUST_set() to handle + setting of purpose and trust fields. New X509_STORE trust and + purpose functions and tidy up setting in other SSL functions. + + *Steve Henson* + + * Add copies of X509_STORE_CTX fields and callbacks to X509_STORE + structure. These are inherited by X509_STORE_CTX when it is + initialised. This allows various defaults to be set in the + X509_STORE structure (such as flags for CRL checking and custom + purpose or trust settings) for functions which only use X509_STORE_CTX + internally such as S/MIME. + + Modify X509_STORE_CTX_purpose_inherit() so it only sets purposes and + trust settings if they are not set in X509_STORE. This allows X509_STORE + purposes and trust (in S/MIME for example) to override any set by default. + + Add command line options for CRL checking to smime, s_client and s_server + applications. + + *Steve Henson* + + * Initial CRL based revocation checking. If the CRL checking flag(s) + are set then the CRL is looked up in the X509_STORE structure and + its validity and signature checked, then if the certificate is found + in the CRL the verify fails with a revoked error. + + Various new CRL related callbacks added to X509_STORE_CTX structure. + + Command line options added to 'verify' application to support this. + + This needs some additional work, such as being able to handle multiple + CRLs with different times, extension based lookup (rather than just + by subject name) and ultimately more complete V2 CRL extension + handling. + + *Steve Henson* + + * Add a general user interface API (crypto/ui/). This is designed + to replace things like des_read_password and friends (backward + compatibility functions using this new API are provided). + The purpose is to remove prompting functions from the DES code + section as well as provide for prompting through dialog boxes in + a window system and the like. + + *Richard Levitte* + + * Add "ex_data" support to ENGINE so implementations can add state at a + per-structure level rather than having to store it globally. + + *Geoff* + + * Make it possible for ENGINE structures to be copied when retrieved by + ENGINE_by_id() if the ENGINE specifies a new flag: ENGINE_FLAGS_BY_ID_COPY. + This causes the "original" ENGINE structure to act like a template, + analogous to the RSA vs. RSA_METHOD type of separation. Because of this + operational state can be localised to each ENGINE structure, despite the + fact they all share the same "methods". New ENGINE structures returned in + this case have no functional references and the return value is the single + structural reference. This matches the single structural reference returned + by ENGINE_by_id() normally, when it is incremented on the pre-existing + ENGINE structure. + + *Geoff* + + * Fix ASN1 decoder when decoding type ANY and V_ASN1_OTHER: since this + needs to match any other type at all we need to manually clear the + tag cache. + + *Steve Henson* + + * Changes to the "openssl engine" utility to include; + - verbosity levels ('-v', '-vv', and '-vvv') that provide information + about an ENGINE's available control commands. + - executing control commands from command line arguments using the + '-pre' and '-post' switches. '-post' is only used if '-t' is + specified and the ENGINE is successfully initialised. The syntax for + the individual commands are colon-separated, for example; + openssl engine chil -pre FORK_CHECK:0 -pre SO_PATH:/lib/test.so + + *Geoff* + + * New dynamic control command support for ENGINEs. ENGINEs can now + declare their own commands (numbers), names (strings), descriptions, + and input types for run-time discovery by calling applications. A + subset of these commands are implicitly classed as "executable" + depending on their input type, and only these can be invoked through + the new string-based API function ENGINE_ctrl_cmd_string(). (Eg. this + can be based on user input, config files, etc). The distinction is + that "executable" commands cannot return anything other than a boolean + result and can only support numeric or string input, whereas some + discoverable commands may only be for direct use through + ENGINE_ctrl(), eg. supporting the exchange of binary data, function + pointers, or other custom uses. The "executable" commands are to + support parameterisations of ENGINE behaviour that can be + unambiguously defined by ENGINEs and used consistently across any + OpenSSL-based application. Commands have been added to all the + existing hardware-supporting ENGINEs, noticeably "SO_PATH" to allow + control over shared-library paths without source code alterations. + + *Geoff* + + * Changed all ENGINE implementations to dynamically allocate their + ENGINEs rather than declaring them statically. Apart from this being + necessary with the removal of the ENGINE_FLAGS_MALLOCED distinction, + this also allows the implementations to compile without using the + internal engine_int.h header. + + *Geoff* + + * Minor adjustment to "rand" code. RAND_get_rand_method() now returns a + 'const' value. Any code that should be able to modify a RAND_METHOD + should already have non-const pointers to it (ie. they should only + modify their own ones). + + *Geoff* + + * Made a variety of little tweaks to the ENGINE code. + - "atalla" and "ubsec" string definitions were moved from header files + to C code. "nuron" string definitions were placed in variables + rather than hard-coded - allowing parameterisation of these values + later on via ctrl() commands. + - Removed unused "#if 0"'d code. + - Fixed engine list iteration code so it uses ENGINE_free() to release + structural references. + - Constified the RAND_METHOD element of ENGINE structures. + - Constified various get/set functions as appropriate and added + missing functions (including a catch-all ENGINE_cpy that duplicates + all ENGINE values onto a new ENGINE except reference counts/state). + - Removed NULL parameter checks in get/set functions. Setting a method + or function to NULL is a way of cancelling out a previously set + value. Passing a NULL ENGINE parameter is just plain stupid anyway + and doesn't justify the extra error symbols and code. + - Deprecate the ENGINE_FLAGS_MALLOCED define and move the area for + flags from engine_int.h to engine.h. + - Changed prototypes for ENGINE handler functions (init(), finish(), + ctrl(), key-load functions, etc) to take an (ENGINE*) parameter. + + *Geoff* + + * Implement binary inversion algorithm for BN_mod_inverse in addition + to the algorithm using long division. The binary algorithm can be + used only if the modulus is odd. On 32-bit systems, it is faster + only for relatively small moduli (roughly 20-30% for 128-bit moduli, + roughly 5-15% for 256-bit moduli), so we use it only for moduli + up to 450 bits. In 64-bit environments, the binary algorithm + appears to be advantageous for much longer moduli; here we use it + for moduli up to 2048 bits. + + *Bodo Moeller* + + * Rewrite CHOICE field setting in ASN1_item_ex_d2i(). The old code + could not support the combine flag in choice fields. + + *Steve Henson* + + * Add a 'copy_extensions' option to the 'ca' utility. This copies + extensions from a certificate request to the certificate. + + *Steve Henson* + + * Allow multiple 'certopt' and 'nameopt' options to be separated + by commas. Add 'namopt' and 'certopt' options to the 'ca' config + file: this allows the display of the certificate about to be + signed to be customised, to allow certain fields to be included + or excluded and extension details. The old system didn't display + multicharacter strings properly, omitted fields not in the policy + and couldn't display additional details such as extensions. + + *Steve Henson* + + * Function EC_POINTs_mul for multiple scalar multiplication + of an arbitrary number of elliptic curve points + \sum scalars[i]*points[i], + optionally including the generator defined for the EC_GROUP: + scalar*generator + \sum scalars[i]*points[i]. + + EC_POINT_mul is a simple wrapper function for the typical case + that the point list has just one item (besides the optional + generator). + + *Bodo Moeller* + + * First EC_METHODs for curves over GF(p): + + EC_GFp_simple_method() uses the basic BN_mod_mul and BN_mod_sqr + operations and provides various method functions that can also + operate with faster implementations of modular arithmetic. + + EC_GFp_mont_method() reuses most functions that are part of + EC_GFp_simple_method, but uses Montgomery arithmetic. + + *Bodo Moeller; point addition and point doubling + implementation directly derived from source code provided by + Lenka Fibikova * + + * Framework for elliptic curves (crypto/ec/ec.h, crypto/ec/ec_lcl.h, + crypto/ec/ec_lib.c): + + Curves are EC_GROUP objects (with an optional group generator) + based on EC_METHODs that are built into the library. + + Points are EC_POINT objects based on EC_GROUP objects. + + Most of the framework would be able to handle curves over arbitrary + finite fields, but as there are no obvious types for fields other + than GF(p), some functions are limited to that for now. + + *Bodo Moeller* + + * Add the -HTTP option to s_server. It is similar to -WWW, but requires + that the file contains a complete HTTP response. + + *Richard Levitte* + + * Add the ec directory to mkdef.pl and mkfiles.pl. In mkdef.pl + change the def and num file printf format specifier from "%-40sXXX" + to "%-39s XXX". The latter will always guarantee a space after the + field while the former will cause them to run together if the field + is 40 of more characters long. + + *Steve Henson* + + * Constify the cipher and digest 'method' functions and structures + and modify related functions to take constant EVP_MD and EVP_CIPHER + pointers. + + *Steve Henson* + + * Hide BN_CTX structure details in bn_lcl.h instead of publishing them + in . Also further increase BN_CTX_NUM to 32. + + *Bodo Moeller* + + * Modify `EVP_Digest*()` routines so they now return values. Although the + internal software routines can never fail additional hardware versions + might. + + *Steve Henson* + + * Clean up crypto/err/err.h and change some error codes to avoid conflicts: + + Previously ERR_R_FATAL was too small and coincided with ERR_LIB_PKCS7 + (= ERR_R_PKCS7_LIB); it is now 64 instead of 32. + + ASN1 error codes + ERR_R_NESTED_ASN1_ERROR + ... + ERR_R_MISSING_ASN1_EOS + were 4 .. 9, conflicting with + ERR_LIB_RSA (= ERR_R_RSA_LIB) + ... + ERR_LIB_PEM (= ERR_R_PEM_LIB). + They are now 58 .. 63 (i.e., just below ERR_R_FATAL). + + Add new error code 'ERR_R_INTERNAL_ERROR'. + + *Bodo Moeller* + + * Don't overuse locks in crypto/err/err.c: For data retrieval, CRYPTO_r_lock + suffices. + + *Bodo Moeller* + + * New option '-subj arg' for 'openssl req' and 'openssl ca'. This + sets the subject name for a new request or supersedes the + subject name in a given request. Formats that can be parsed are + 'CN=Some Name, OU=myOU, C=IT' + and + 'CN=Some Name/OU=myOU/C=IT'. + + Add options '-batch' and '-verbose' to 'openssl req'. + + *Massimiliano Pala * + + * Introduce the possibility to access global variables through + functions on platform were that's the best way to handle exporting + global variables in shared libraries. To enable this functionality, + one must configure with "EXPORT_VAR_AS_FN" or defined the C macro + "OPENSSL_EXPORT_VAR_AS_FUNCTION" in crypto/opensslconf.h (the latter + is normally done by Configure or something similar). + + To implement a global variable, use the macro OPENSSL_IMPLEMENT_GLOBAL + in the source file (foo.c) like this: + + OPENSSL_IMPLEMENT_GLOBAL(int,foo)=1; + OPENSSL_IMPLEMENT_GLOBAL(double,bar); + + To declare a global variable, use the macros OPENSSL_DECLARE_GLOBAL + and OPENSSL_GLOBAL_REF in the header file (foo.h) like this: + + OPENSSL_DECLARE_GLOBAL(int,foo); + #define foo OPENSSL_GLOBAL_REF(foo) + OPENSSL_DECLARE_GLOBAL(double,bar); + #define bar OPENSSL_GLOBAL_REF(bar) + + The #defines are very important, and therefore so is including the + header file everywhere where the defined globals are used. + + The macro OPENSSL_EXPORT_VAR_AS_FUNCTION also affects the definition + of ASN.1 items, but that structure is a bit different. + + The largest change is in util/mkdef.pl which has been enhanced with + better and easier to understand logic to choose which symbols should + go into the Windows .def files as well as a number of fixes and code + cleanup (among others, algorithm keywords are now sorted + lexicographically to avoid constant rewrites). + + *Richard Levitte* + + * In BN_div() keep a copy of the sign of 'num' before writing the + result to 'rm' because if rm==num the value will be overwritten + and produce the wrong result if 'num' is negative: this caused + problems with BN_mod() and BN_nnmod(). + + *Steve Henson* + + * Function OCSP_request_verify(). This checks the signature on an + OCSP request and verifies the signer certificate. The signer + certificate is just checked for a generic purpose and OCSP request + trust settings. + + *Steve Henson* + + * Add OCSP_check_validity() function to check the validity of OCSP + responses. OCSP responses are prepared in real time and may only + be a few seconds old. Simply checking that the current time lies + between thisUpdate and nextUpdate max reject otherwise valid responses + caused by either OCSP responder or client clock inaccuracy. Instead + we allow thisUpdate and nextUpdate to fall within a certain period of + the current time. The age of the response can also optionally be + checked. Two new options -validity_period and -status_age added to + ocsp utility. + + *Steve Henson* + + * If signature or public key algorithm is unrecognized print out its + OID rather that just UNKNOWN. + + *Steve Henson* + + * Change OCSP_cert_to_id() to tolerate a NULL subject certificate and + OCSP_cert_id_new() a NULL serialNumber. This allows a partial certificate + ID to be generated from the issuer certificate alone which can then be + passed to OCSP_id_issuer_cmp(). + + *Steve Henson* + + * New compilation option ASN1_ITEM_FUNCTIONS. This causes the new + ASN1 modules to export functions returning ASN1_ITEM pointers + instead of the ASN1_ITEM structures themselves. This adds several + new macros which allow the underlying ASN1 function/structure to + be accessed transparently. As a result code should not use ASN1_ITEM + references directly (such as &X509_it) but instead use the relevant + macros (such as ASN1_ITEM_rptr(X509)). This option is to allow + use of the new ASN1 code on platforms where exporting structures + is problematical (for example in shared libraries) but exporting + functions returning pointers to structures is not. + + *Steve Henson* + + * Add support for overriding the generation of SSL/TLS session IDs. + These callbacks can be registered either in an SSL_CTX or per SSL. + The purpose of this is to allow applications to control, if they wish, + the arbitrary values chosen for use as session IDs, particularly as it + can be useful for session caching in multiple-server environments. A + command-line switch for testing this (and any client code that wishes + to use such a feature) has been added to "s_server". + + *Geoff Thorpe, Lutz Jaenicke* + + * Modify mkdef.pl to recognise and parse preprocessor conditionals + of the form `#if defined(...) || defined(...) || ...` and + `#if !defined(...) && !defined(...) && ...`. This also avoids + the growing number of special cases it was previously handling. + + *Richard Levitte* + + * Make all configuration macros available for application by making + sure they are available in opensslconf.h, by giving them names starting + with `OPENSSL_` to avoid conflicts with other packages and by making + sure e_os2.h will cover all platform-specific cases together with + opensslconf.h. + Additionally, it is now possible to define configuration/platform- + specific names (called "system identities"). In the C code, these + are prefixed with `OPENSSL_SYSNAME_`. e_os2.h will create another + macro with the name beginning with `OPENSSL_SYS_`, which is determined + from `OPENSSL_SYSNAME_*` or compiler-specific macros depending on + what is available. + + *Richard Levitte* + + * New option -set_serial to 'req' and 'x509' this allows the serial + number to use to be specified on the command line. Previously self + signed certificates were hard coded with serial number 0 and the + CA options of 'x509' had to use a serial number in a file which was + auto incremented. + + *Steve Henson* + + * New options to 'ca' utility to support V2 CRL entry extensions. + Currently CRL reason, invalidity date and hold instruction are + supported. Add new CRL extensions to V3 code and some new objects. + + *Steve Henson* + + * New function EVP_CIPHER_CTX_set_padding() this is used to + disable standard block padding (aka PKCS#5 padding) in the EVP + API, which was previously mandatory. This means that the data is + not padded in any way and so the total length much be a multiple + of the block size, otherwise an error occurs. + + *Steve Henson* + + * Initial (incomplete) OCSP SSL support. + + *Steve Henson* + + * New function OCSP_parse_url(). This splits up a URL into its host, + port and path components: primarily to parse OCSP URLs. New -url + option to ocsp utility. + + *Steve Henson* + + * New nonce behavior. The return value of OCSP_check_nonce() now + reflects the various checks performed. Applications can decide + whether to tolerate certain situations such as an absent nonce + in a response when one was present in a request: the ocsp application + just prints out a warning. New function OCSP_add1_basic_nonce() + this is to allow responders to include a nonce in a response even if + the request is nonce-less. + + *Steve Henson* + + * Disable stdin buffering in `load_cert()` (`apps/apps.c`) so that no certs are + skipped when using openssl x509 multiple times on a single input file, + e.g. `(openssl x509 -out cert1; openssl x509 -out cert2) * + + * New OCSP verify flag OCSP_TRUSTOTHER. When set the "other" certificates + passed by the function are trusted implicitly. If any of them signed the + response then it is assumed to be valid and is not verified. + + *Steve Henson* + + * In PKCS7_set_type() initialise content_type in PKCS7_ENC_CONTENT + to data. This was previously part of the PKCS7 ASN1 code. This + was causing problems with OpenSSL created PKCS#12 and PKCS#7 structures. + *Steve Henson, reported by Kenneth R. Robinette + * + + * Add CRYPTO_push_info() and CRYPTO_pop_info() calls to new ASN1 + routines: without these tracing memory leaks is very painful. + Fix leaks in PKCS12 and PKCS7 routines. + + *Steve Henson* + + * Make X509_time_adj() cope with the new behaviour of ASN1_TIME_new(). + Previously it initialised the 'type' argument to V_ASN1_UTCTIME which + effectively meant GeneralizedTime would never be used. Now it + is initialised to -1 but X509_time_adj() now has to check the value + and use ASN1_TIME_set() if the value is not V_ASN1_UTCTIME or + V_ASN1_GENERALIZEDTIME, without this it always uses GeneralizedTime. + *Steve Henson, reported by Kenneth R. Robinette + * + + * Fixes to BN_to_ASN1_INTEGER when bn is zero. This would previously + result in a zero length in the ASN1_INTEGER structure which was + not consistent with the structure when d2i_ASN1_INTEGER() was used + and would cause ASN1_INTEGER_cmp() to fail. Enhance s2i_ASN1_INTEGER() + to cope with hex and negative integers. Fix bug in i2a_ASN1_INTEGER() + where it did not print out a minus for negative ASN1_INTEGER. + + *Steve Henson* + + * Add summary printout to ocsp utility. The various functions which + convert status values to strings have been renamed to: + OCSP_response_status_str(), OCSP_cert_status_str() and + OCSP_crl_reason_str() and are no longer static. New options + to verify nonce values and to disable verification. OCSP response + printout format cleaned up. + + *Steve Henson* + + * Add additional OCSP certificate checks. These are those specified + in RFC2560. This consists of two separate checks: the CA of the + certificate being checked must either be the OCSP signer certificate + or the issuer of the OCSP signer certificate. In the latter case the + OCSP signer certificate must contain the OCSP signing extended key + usage. This check is performed by attempting to match the OCSP + signer or the OCSP signer CA to the issuerNameHash and issuerKeyHash + in the OCSP_CERTID structures of the response. + + *Steve Henson* + + * Initial OCSP certificate verification added to OCSP_basic_verify() + and related routines. This uses the standard OpenSSL certificate + verify routines to perform initial checks (just CA validity) and + to obtain the certificate chain. Then additional checks will be + performed on the chain. Currently the root CA is checked to see + if it is explicitly trusted for OCSP signing. This is used to set + a root CA as a global signing root: that is any certificate that + chains to that CA is an acceptable OCSP signing certificate. + + *Steve Henson* + + * New '-extfile ...' option to 'openssl ca' for reading X.509v3 + extensions from a separate configuration file. + As when reading extensions from the main configuration file, + the '-extensions ...' option may be used for specifying the + section to use. + + *Massimiliano Pala * + + * New OCSP utility. Allows OCSP requests to be generated or + read. The request can be sent to a responder and the output + parsed, outputted or printed in text form. Not complete yet: + still needs to check the OCSP response validity. + + *Steve Henson* + + * New subcommands for 'openssl ca': + `openssl ca -status ` prints the status of the cert with + the given serial number (according to the index file). + `openssl ca -updatedb` updates the expiry status of certificates + in the index file. + + *Massimiliano Pala * + + * New '-newreq-nodes' command option to CA.pl. This is like + '-newreq', but calls 'openssl req' with the '-nodes' option + so that the resulting key is not encrypted. + + *Damien Miller * + + * New configuration for the GNU Hurd. + + *Jonathan Bartlett via Richard Levitte* + + * Initial code to implement OCSP basic response verify. This + is currently incomplete. Currently just finds the signer's + certificate and verifies the signature on the response. + + *Steve Henson* + + * New SSLeay_version code SSLEAY_DIR to determine the compiled-in + value of OPENSSLDIR. This is available via the new '-d' option + to 'openssl version', and is also included in 'openssl version -a'. + + *Bodo Moeller* + + * Allowing defining memory allocation callbacks that will be given + file name and line number information in additional arguments + (a `const char*` and an int). The basic functionality remains, as + well as the original possibility to just replace malloc(), + realloc() and free() by functions that do not know about these + additional arguments. To register and find out the current + settings for extended allocation functions, the following + functions are provided: + + CRYPTO_set_mem_ex_functions + CRYPTO_set_locked_mem_ex_functions + CRYPTO_get_mem_ex_functions + CRYPTO_get_locked_mem_ex_functions + + These work the same way as CRYPTO_set_mem_functions and friends. + `CRYPTO_get_[locked_]mem_functions` now writes 0 where such an + extended allocation function is enabled. + Similarly, `CRYPTO_get_[locked_]mem_ex_functions` writes 0 where + a conventional allocation function is enabled. + + *Richard Levitte, Bodo Moeller* + + * Finish off removing the remaining LHASH function pointer casts. + There should no longer be any prototype-casting required when using + the LHASH abstraction, and any casts that remain are "bugs". See + the callback types and macros at the head of lhash.h for details + (and "OBJ_cleanup" in crypto/objects/obj_dat.c as an example). + + *Geoff Thorpe* + + * Add automatic query of EGD sockets in RAND_poll() for the unix variant. + If /dev/[u]random devices are not available or do not return enough + entropy, EGD style sockets (served by EGD or PRNGD) will automatically + be queried. + The locations /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool, and + /etc/entropy will be queried once each in this sequence, querying stops + when enough entropy was collected without querying more sockets. + + *Lutz Jaenicke* + + * Change the Unix RAND_poll() variant to be able to poll several + random devices, as specified by DEVRANDOM, until a sufficient amount + of data has been collected. We spend at most 10 ms on each file + (select timeout) and read in non-blocking mode. DEVRANDOM now + defaults to the list "/dev/urandom", "/dev/random", "/dev/srandom" + (previously it was just the string "/dev/urandom"), so on typical + platforms the 10 ms delay will never occur. + Also separate out the Unix variant to its own file, rand_unix.c. + For VMS, there's a currently-empty rand_vms.c. + + *Richard Levitte* + + * Move OCSP client related routines to ocsp_cl.c. These + provide utility functions which an application needing + to issue a request to an OCSP responder and analyse the + response will typically need: as opposed to those which an + OCSP responder itself would need which will be added later. + + OCSP_request_sign() signs an OCSP request with an API similar + to PKCS7_sign(). OCSP_response_status() returns status of OCSP + response. OCSP_response_get1_basic() extracts basic response + from response. OCSP_resp_find_status(): finds and extracts status + information from an OCSP_CERTID structure (which will be created + when the request structure is built). These are built from lower + level functions which work on OCSP_SINGLERESP structures but + won't normally be used unless the application wishes to examine + extensions in the OCSP response for example. + + Replace nonce routines with a pair of functions. + OCSP_request_add1_nonce() adds a nonce value and optionally + generates a random value. OCSP_check_nonce() checks the + validity of the nonce in an OCSP response. + + *Steve Henson* + + * Change function OCSP_request_add() to OCSP_request_add0_id(). + This doesn't copy the supplied OCSP_CERTID and avoids the + need to free up the newly created id. Change return type + to OCSP_ONEREQ to return the internal OCSP_ONEREQ structure. + This can then be used to add extensions to the request. + Deleted OCSP_request_new(), since most of its functionality + is now in OCSP_REQUEST_new() (and the case insensitive name + clash) apart from the ability to set the request name which + will be added elsewhere. + + *Steve Henson* + + * Update OCSP API. Remove obsolete extensions argument from + various functions. Extensions are now handled using the new + OCSP extension code. New simple OCSP HTTP function which + can be used to send requests and parse the response. + + *Steve Henson* + + * Fix the PKCS#7 (S/MIME) code to work with new ASN1. Two new + ASN1_ITEM structures help with sign and verify. PKCS7_ATTR_SIGN + uses the special reorder version of SET OF to sort the attributes + and reorder them to match the encoded order. This resolves a long + standing problem: a verify on a PKCS7 structure just after signing + it used to fail because the attribute order did not match the + encoded order. PKCS7_ATTR_VERIFY does not reorder the attributes: + it uses the received order. This is necessary to tolerate some broken + software that does not order SET OF. This is handled by encoding + as a SEQUENCE OF but using implicit tagging (with UNIVERSAL class) + to produce the required SET OF. + + *Steve Henson* + + * Have mk1mf.pl generate the macros OPENSSL_BUILD_SHLIBCRYPTO and + OPENSSL_BUILD_SHLIBSSL and use them appropriately in the header + files to get correct declarations of the ASN.1 item variables. + + *Richard Levitte* + + * Rewrite of PKCS#12 code to use new ASN1 functionality. Replace many + PKCS#12 macros with real functions. Fix two unrelated ASN1 bugs: + asn1_check_tlen() would sometimes attempt to use 'ctx' when it was + NULL and ASN1_TYPE was not dereferenced properly in asn1_ex_c2i(). + New ASN1 macro: DECLARE_ASN1_ITEM() which just declares the relevant + ASN1_ITEM and no wrapper functions. + + *Steve Henson* + + * New functions or ASN1_item_d2i_fp() and ASN1_item_d2i_bio(). These + replace the old function pointer based I/O routines. Change most of + the `*_d2i_bio()` and `*_d2i_fp()` functions to use these. + + *Steve Henson* + + * Enhance mkdef.pl to be more accepting about spacing in C preprocessor + lines, recognize more "algorithms" that can be deselected, and make + it complain about algorithm deselection that isn't recognised. + + *Richard Levitte* + + * New ASN1 functions to handle dup, sign, verify, digest, pack and + unpack operations in terms of ASN1_ITEM. Modify existing wrappers + to use new functions. Add NO_ASN1_OLD which can be set to remove + some old style ASN1 functions: this can be used to determine if old + code will still work when these eventually go away. + + *Steve Henson* + + * New extension functions for OCSP structures, these follow the + same conventions as certificates and CRLs. + + *Steve Henson* + + * New function X509V3_add1_i2d(). This automatically encodes and + adds an extension. Its behaviour can be customised with various + flags to append, replace or delete. Various wrappers added for + certificates and CRLs. + + *Steve Henson* + + * Fix to avoid calling the underlying ASN1 print routine when + an extension cannot be parsed. Correct a typo in the + OCSP_SERVICELOC extension. Tidy up print OCSP format. + + *Steve Henson* + + * Make mkdef.pl parse some of the ASN1 macros and add appropriate + entries for variables. + + *Steve Henson* + + * Add functionality to `apps/openssl.c` for detecting locking + problems: As the program is single-threaded, all we have + to do is register a locking callback using an array for + storing which locks are currently held by the program. + + *Bodo Moeller* + + * Use a lock around the call to CRYPTO_get_ex_new_index() in + SSL_get_ex_data_X509_STORE_idx(), which is used in + ssl_verify_cert_chain() and thus can be called at any time + during TLS/SSL handshakes so that thread-safety is essential. + Unfortunately, the ex_data design is not at all suited + for multi-threaded use, so it probably should be abolished. + + *Bodo Moeller* + + * Added Broadcom "ubsec" ENGINE to OpenSSL. + + *Broadcom, tweaked and integrated by Geoff Thorpe* + + * Move common extension printing code to new function + X509V3_print_extensions(). Reorganise OCSP print routines and + implement some needed OCSP ASN1 functions. Add OCSP extensions. + + *Steve Henson* + + * New function X509_signature_print() to remove duplication in some + print routines. + + *Steve Henson* + + * Add a special meaning when SET OF and SEQUENCE OF flags are both + set (this was treated exactly the same as SET OF previously). This + is used to reorder the STACK representing the structure to match the + encoding. This will be used to get round a problem where a PKCS7 + structure which was signed could not be verified because the STACK + order did not reflect the encoded order. + + *Steve Henson* + + * Reimplement the OCSP ASN1 module using the new code. + + *Steve Henson* + + * Update the X509V3 code to permit the use of an ASN1_ITEM structure + for its ASN1 operations. The old style function pointers still exist + for now but they will eventually go away. + + *Steve Henson* + + * Merge in replacement ASN1 code from the ASN1 branch. This almost + completely replaces the old ASN1 functionality with a table driven + encoder and decoder which interprets an ASN1_ITEM structure describing + the ASN1 module. Compatibility with the existing ASN1 API (i2d,d2i) is + largely maintained. Almost all of the old asn1_mac.h macro based ASN1 + has also been converted to the new form. + + *Steve Henson* + + * Change BN_mod_exp_recp so that negative moduli are tolerated + (the sign is ignored). Similarly, ignore the sign in BN_MONT_CTX_set + so that BN_mod_exp_mont and BN_mod_exp_mont_word work + for negative moduli. + + *Bodo Moeller* + + * Fix BN_uadd and BN_usub: Always return non-negative results instead + of not touching the result's sign bit. + + *Bodo Moeller* + + * BN_div bugfix: If the result is 0, the sign (res->neg) must not be + set. + + *Bodo Moeller* + + * Changed the LHASH code to use prototypes for callbacks, and created + macros to declare and implement thin (optionally static) functions + that provide type-safety and avoid function pointer casting for the + type-specific callbacks. + + *Geoff Thorpe* + + * Added Kerberos Cipher Suites to be used with TLS, as written in + RFC 2712. + *Veers Staats , + Jeffrey Altman , via Richard Levitte* + + * Reformat the FAQ so the different questions and answers can be divided + in sections depending on the subject. + + *Richard Levitte* + + * Have the zlib compression code load ZLIB.DLL dynamically under + Windows. + + *Richard Levitte* + + * New function BN_mod_sqrt for computing square roots modulo a prime + (using the probabilistic Tonelli-Shanks algorithm unless + p == 3 (mod 4) or p == 5 (mod 8), which are cases that can + be handled deterministically). + + *Lenka Fibikova , Bodo Moeller* + + * Make BN_mod_inverse faster by explicitly handling small quotients + in the Euclid loop. (Speed gain about 20% for small moduli [256 or + 512 bits], about 30% for larger ones [1024 or 2048 bits].) + + *Bodo Moeller* + + * New function BN_kronecker. + + *Bodo Moeller* + + * Fix BN_gcd so that it works on negative inputs; the result is + positive unless both parameters are zero. + Previously something reasonably close to an infinite loop was + possible because numbers could be growing instead of shrinking + in the implementation of Euclid's algorithm. + + *Bodo Moeller* + + * Fix BN_is_word() and BN_is_one() macros to take into account the + sign of the number in question. + + Fix BN_is_word(a,w) to work correctly for w == 0. + + The old BN_is_word(a,w) macro is now called BN_abs_is_word(a,w) + because its test if the absolute value of 'a' equals 'w'. + Note that BN_abs_is_word does *not* handle w == 0 reliably; + it exists mostly for use in the implementations of BN_is_zero(), + BN_is_one(), and BN_is_word(). + + *Bodo Moeller* + + * New function BN_swap. + + *Bodo Moeller* + + * Use BN_nnmod instead of BN_mod in crypto/bn/bn_exp.c so that + the exponentiation functions are more likely to produce reasonable + results on negative inputs. + + *Bodo Moeller* + + * Change BN_mod_mul so that the result is always non-negative. + Previously, it could be negative if one of the factors was negative; + I don't think anyone really wanted that behaviour. + + *Bodo Moeller* + + * Move `BN_mod_...` functions into new file `crypto/bn/bn_mod.c` + (except for exponentiation, which stays in `crypto/bn/bn_exp.c`, + and `BN_mod_mul_reciprocal`, which stays in `crypto/bn/bn_recp.c`) + and add new functions: + + BN_nnmod + BN_mod_sqr + BN_mod_add + BN_mod_add_quick + BN_mod_sub + BN_mod_sub_quick + BN_mod_lshift1 + BN_mod_lshift1_quick + BN_mod_lshift + BN_mod_lshift_quick + + These functions always generate non-negative results. + + `BN_nnmod` otherwise is `like BN_mod` (if `BN_mod` computes a remainder `r` + such that `|m| < r < 0`, `BN_nnmod` will output `rem + |m|` instead). + + `BN_mod_XXX_quick(r, a, [b,] m)` generates the same result as + `BN_mod_XXX(r, a, [b,] m, ctx)`, but requires that `a` [and `b`] + be reduced modulo `m`. + + *Lenka Fibikova , Bodo Moeller* + + + + * In 'openssl passwd', verify passwords read from the terminal + unless the '-salt' option is used (which usually means that + verification would just waste user's time since the resulting + hash is going to be compared with some given password hash) + or the new '-noverify' option is used. + + This is an incompatible change, but it does not affect + non-interactive use of 'openssl passwd' (passwords on the command + line, '-stdin' option, '-in ...' option) and thus should not + cause any problems. + + *Bodo Moeller* + + * Remove all references to RSAref, since there's no more need for it. + + *Richard Levitte* + + * Make DSO load along a path given through an environment variable + (SHLIB_PATH) with shl_load(). + + *Richard Levitte* + + * Constify the ENGINE code as a result of BIGNUM constification. + Also constify the RSA code and most things related to it. In a + few places, most notable in the depth of the ASN.1 code, ugly + casts back to non-const were required (to be solved at a later + time) + + *Richard Levitte* + + * Make it so the openssl application has all engines loaded by default. + + *Richard Levitte* + + * Constify the BIGNUM routines a little more. + + *Richard Levitte* + + * Add the following functions: + + ENGINE_load_cswift() + ENGINE_load_chil() + ENGINE_load_atalla() + ENGINE_load_nuron() + ENGINE_load_builtin_engines() + + That way, an application can itself choose if external engines that + are built-in in OpenSSL shall ever be used or not. The benefit is + that applications won't have to be linked with libdl or other dso + libraries unless it's really needed. + + Changed 'openssl engine' to load all engines on demand. + Changed the engine header files to avoid the duplication of some + declarations (they differed!). + + *Richard Levitte* + + * 'openssl engine' can now list capabilities. + + *Richard Levitte* + + * Better error reporting in 'openssl engine'. + + *Richard Levitte* + + * Never call load_dh_param(NULL) in s_server. + + *Bodo Moeller* + + * Add engine application. It can currently list engines by name and + identity, and test if they are actually available. + + *Richard Levitte* + + * Improve RPM specification file by forcing symbolic linking and making + sure the installed documentation is also owned by root.root. + + *Damien Miller * + + * Give the OpenSSL applications more possibilities to make use of + keys (public as well as private) handled by engines. + + *Richard Levitte* + + * Add OCSP code that comes from CertCo. + + *Richard Levitte* + + * Add VMS support for the Rijndael code. + + *Richard Levitte* + + * Added untested support for Nuron crypto accelerator. + + *Ben Laurie* + + * Add support for external cryptographic devices. This code was + previously distributed separately as the "engine" branch. + + *Geoff Thorpe, Richard Levitte* + + * Rework the filename-translation in the DSO code. It is now possible to + have far greater control over how a "name" is turned into a filename + depending on the operating environment and any oddities about the + different shared library filenames on each system. + + *Geoff Thorpe* + + * Support threads on FreeBSD-elf in Configure. + + *Richard Levitte* + + * Fix for SHA1 assembly problem with MASM: it produces + warnings about corrupt line number information when assembling + with debugging information. This is caused by the overlapping + of two sections. + + *Bernd Matthes , Steve Henson* + + * NCONF changes. + NCONF_get_number() has no error checking at all. As a replacement, + NCONF_get_number_e() is defined (`_e` for "error checking") and is + promoted strongly. The old NCONF_get_number is kept around for + binary backward compatibility. + Make it possible for methods to load from something other than a BIO, + by providing a function pointer that is given a name instead of a BIO. + For example, this could be used to load configuration data from an + LDAP server. + + *Richard Levitte* + + * Fix for non blocking accept BIOs. Added new I/O special reason + BIO_RR_ACCEPT to cover this case. Previously use of accept BIOs + with non blocking I/O was not possible because no retry code was + implemented. Also added new SSL code SSL_WANT_ACCEPT to cover + this case. + + *Steve Henson* + + * Added the beginnings of Rijndael support. + + *Ben Laurie* + + * Fix for bug in DirectoryString mask setting. Add support for + X509_NAME_print_ex() in 'req' and X509_print_ex() function + to allow certificate printing to more controllable, additional + 'certopt' option to 'x509' to allow new printing options to be + set. + + *Steve Henson* + + * Clean old EAY MD5 hack from e_os.h. + + *Richard Levitte* + +### Changes between 0.9.6l and 0.9.6m [17 Mar 2004] + + * Fix null-pointer assignment in do_change_cipher_spec() revealed + by using the Codenomicon TLS Test Tool ([CVE-2004-0079]) + + *Joe Orton, Steve Henson* + +### Changes between 0.9.6k and 0.9.6l [04 Nov 2003] + + * Fix additional bug revealed by the NISCC test suite: + + Stop bug triggering large recursion when presented with + certain ASN.1 tags ([CVE-2003-0851]) + + *Steve Henson* + +### Changes between 0.9.6j and 0.9.6k [30 Sep 2003] + + * Fix various bugs revealed by running the NISCC test suite: + + Stop out of bounds reads in the ASN1 code when presented with + invalid tags (CVE-2003-0543 and CVE-2003-0544). + + If verify callback ignores invalid public key errors don't try to check + certificate signature with the NULL public key. + + *Steve Henson* + + * In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate + if the server requested one: as stated in TLS 1.0 and SSL 3.0 + specifications. + + *Steve Henson* + + * In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional + extra data after the compression methods not only for TLS 1.0 + but also for SSL 3.0 (as required by the specification). + + *Bodo Moeller; problem pointed out by Matthias Loepfe* + + * Change X509_certificate_type() to mark the key as exported/exportable + when it's 512 *bits* long, not 512 bytes. + + *Richard Levitte* + +### Changes between 0.9.6i and 0.9.6j [10 Apr 2003] + + * Countermeasure against the Klima-Pokorny-Rosa extension of + Bleichbacher's attack on PKCS #1 v1.5 padding: treat + a protocol version number mismatch like a decryption error + in ssl3_get_client_key_exchange (ssl/s3_srvr.c). + + *Bodo Moeller* + + * Turn on RSA blinding by default in the default implementation + to avoid a timing attack. Applications that don't want it can call + RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING. + They would be ill-advised to do so in most cases. + + *Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller* + + * Change RSA blinding code so that it works when the PRNG is not + seeded (in this case, the secret RSA exponent is abused as + an unpredictable seed -- if it is not unpredictable, there + is no point in blinding anyway). Make RSA blinding thread-safe + by remembering the creator's thread ID in rsa->blinding and + having all other threads use local one-time blinding factors + (this requires more computation than sharing rsa->blinding, but + avoids excessive locking; and if an RSA object is not shared + between threads, blinding will still be very fast). + + *Bodo Moeller* + +### Changes between 0.9.6h and 0.9.6i [19 Feb 2003] + + * In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked + via timing by performing a MAC computation even if incorrect + block cipher padding has been found. This is a countermeasure + against active attacks where the attacker has to distinguish + between bad padding and a MAC verification error. ([CVE-2003-0078]) + + *Bodo Moeller; problem pointed out by Brice Canvel (EPFL), + Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and + Martin Vuagnoux (EPFL, Ilion)* + +### 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 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 + be read through on certain media, for example a swap space on disk. + + *Geoff Thorpe* + + * Bugfix: client side session caching did not work with external caching, + because the session->cipher setting was not restored when reloading + from the external cache. This problem was masked, when + SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG (part of SSL_OP_ALL) was set. + (Found by Steve Haslam .) + + *Lutz Jaenicke* + + * Fix client_certificate (ssl/s2_clnt.c): The permissible total + length of the REQUEST-CERTIFICATE message is 18 .. 34, not 17 .. 33. + + *Zeev Lieber * + + * Undo an undocumented change introduced in 0.9.6e which caused + repeated calls to OpenSSL_add_all_ciphers() and + OpenSSL_add_all_digests() to be ignored, even after calling + EVP_cleanup(). + + *Richard Levitte* + + * Change the default configuration reader to deal with last line not + being properly terminated. + + *Richard Levitte* + + * Change X509_NAME_cmp() so it applies the special rules on handling + DN values that are of type PrintableString, as well as RDNs of type + emailAddress where the value has the type ia5String. + + *stefank@valicert.com via Richard Levitte* + + * Add a SSL_SESS_CACHE_NO_INTERNAL_STORE flag to take over half + the job SSL_SESS_CACHE_NO_INTERNAL_LOOKUP was inconsistently + doing, define a new flag (SSL_SESS_CACHE_NO_INTERNAL) to be + the bitwise-OR of the two for use by the majority of applications + wanting this behaviour, and update the docs. The documented + behaviour and actual behaviour were inconsistent and had been + changing anyway, so this is more a bug-fix than a behavioural + change. + + *Geoff Thorpe, diagnosed by Nadav Har'El* + + * Don't impose a 16-byte length minimum on session IDs in ssl/s3_clnt.c + (the SSL 3.0 and TLS 1.0 specifications allow any length up to 32 bytes). + + *Bodo Moeller* + + * Fix initialization code race conditions in + SSLv23_method(), SSLv23_client_method(), SSLv23_server_method(), + SSLv2_method(), SSLv2_client_method(), SSLv2_server_method(), + SSLv3_method(), SSLv3_client_method(), SSLv3_server_method(), + TLSv1_method(), TLSv1_client_method(), TLSv1_server_method(), + ssl2_get_cipher_by_char(), + ssl3_get_cipher_by_char(). + + *Patrick McCormick , Bodo Moeller* + + * Reorder cleanup sequence in SSL_CTX_free(): only remove the ex_data after + the cached sessions are flushed, as the remove_cb() might use ex_data + contents. Bug found by Sam Varshavchik + (see [openssl.org #212]). + + *Geoff Thorpe, Lutz Jaenicke* + + * Fix typo in OBJ_txt2obj which incorrectly passed the content + length, instead of the encoding length to d2i_ASN1_OBJECT. + + *Steve Henson* + +### Changes between 0.9.6f and 0.9.6g [9 Aug 2002] + + * [In 0.9.6g-engine release:] + Fix crypto/engine/vendor_defns/cswift.h for WIN32 (use `_stdcall`). + + *Lynn Gazis * + +### Changes between 0.9.6e and 0.9.6f [8 Aug 2002] + + * Fix ASN1 checks. Check for overflow by comparing with LONG_MAX + and get fix the header length calculation. + *Florian Weimer , + Alon Kantor (and others), Steve Henson* + + * Use proper error handling instead of 'assertions' in buffer + overflow checks added in 0.9.6e. This prevents DoS (the + assertions could call abort()). + + *Arne Ansper , Bodo Moeller* + +### Changes between 0.9.6d and 0.9.6e [30 Jul 2002] + + * Add various sanity checks to asn1_get_length() to reject + the ASN1 length bytes if they exceed sizeof(long), will appear + negative or the content length exceeds the length of the + supplied buffer. + + *Steve Henson, Adi Stav , James Yonan * + + * Fix cipher selection routines: ciphers without encryption had no flags + for the cipher strength set and where therefore not handled correctly + by the selection routines (PR #130). + + *Lutz Jaenicke* + + * Fix EVP_dsa_sha macro. + + *Nils Larsch* + + * New option + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS + for disabling the SSL 3.0/TLS 1.0 CBC vulnerability countermeasure + that was added in OpenSSL 0.9.6d. + + As the countermeasure turned out to be incompatible with some + broken SSL implementations, the new option is part of SSL_OP_ALL. + SSL_OP_ALL is usually employed when compatibility with weird SSL + implementations is desired (e.g. '-bugs' option to 's_client' and + 's_server'), so the new option is automatically set in many + applications. + + *Bodo Moeller* + + * Changes in security patch: + + Changes marked "(CHATS)" were sponsored by the Defense Advanced + Research Projects Agency (DARPA) and Air Force Research Laboratory, + Air Force Materiel Command, USAF, under agreement number + F30602-01-2-0537. + + * Add various sanity checks to asn1_get_length() to reject + the ASN1 length bytes if they exceed sizeof(long), will appear + negative or the content length exceeds the length of the + supplied buffer. ([CVE-2002-0659]) + + *Steve Henson, Adi Stav , James Yonan * + + * Assertions for various potential buffer overflows, not known to + happen in practice. + + *Ben Laurie (CHATS)* + + * Various temporary buffers to hold ASCII versions of integers were + too small for 64 bit platforms. ([CVE-2002-0655]) + *Matthew Byng-Maddick and Ben Laurie (CHATS)>* + + * Remote buffer overflow in SSL3 protocol - an attacker could + supply an oversized session ID to a client. ([CVE-2002-0656]) + + *Ben Laurie (CHATS)* + + * Remote buffer overflow in SSL2 protocol - an attacker could + supply an oversized client master key. ([CVE-2002-0656]) + + *Ben Laurie (CHATS)* + +### Changes between 0.9.6c and 0.9.6d [9 May 2002] + + * Fix crypto/asn1/a_sign.c so that 'parameters' is omitted (not + encoded as NULL) with id-dsa-with-sha1. + + *Nils Larsch ; problem pointed out by Bodo Moeller* + + * Check various `X509_...()` return values in `apps/req.c`. + + *Nils Larsch * + + * Fix BASE64 decode (EVP_DecodeUpdate) for data with CR/LF ended lines: + an end-of-file condition would erroneously be flagged, when the CRLF + was just at the end of a processed block. The bug was discovered when + processing data through a buffering memory BIO handing the data to a + BASE64-decoding BIO. Bug fund and patch submitted by Pavel Tsekov + and Nedelcho Stanev. + + *Lutz Jaenicke* + + * Implement a countermeasure against a vulnerability recently found + in CBC ciphersuites in SSL 3.0/TLS 1.0: Send an empty fragment + before application data chunks to avoid the use of known IVs + with data potentially chosen by the attacker. + + *Bodo Moeller* + + * Fix length checks in ssl3_get_client_hello(). + + *Bodo Moeller* + + * TLS/SSL library bugfix: use s->s3->in_read_app_data differently + to prevent ssl3_read_internal() from incorrectly assuming that + ssl3_read_bytes() found application data while handshake + processing was enabled when in fact s->s3->in_read_app_data was + merely automatically cleared during the initial handshake. + + *Bodo Moeller; problem pointed out by Arne Ansper * + + * Fix object definitions for Private and Enterprise: they were not + recognized in their shortname (=lowercase) representation. Extend + obj_dat.pl to issue an error when using undefined keywords instead + of silently ignoring the problem (Svenning Sorensen + ). + + *Lutz Jaenicke* + + * Fix DH_generate_parameters() so that it works for 'non-standard' + generators, i.e. generators other than 2 and 5. (Previously, the + code did not properly initialise the 'add' and 'rem' values to + BN_generate_prime().) + + In the new general case, we do not insist that 'generator' is + actually a primitive root: This requirement is rather pointless; + a generator of the order-q subgroup is just as good, if not + better. + + *Bodo Moeller* + + * Map new X509 verification errors to alerts. Discovered and submitted by + Tom Wu . + + *Lutz Jaenicke* + + * Fix ssl3_pending() (ssl/s3_lib.c) to prevent SSL_pending() from + returning non-zero before the data has been completely received + when using non-blocking I/O. + + *Bodo Moeller; problem pointed out by John Hughes* + + * Some of the ciphers missed the strength entry (SSL_LOW etc). + + *Ben Laurie, Lutz Jaenicke* + + * Fix bug in SSL_clear(): bad sessions were not removed (found by + Yoram Zahavi ). + + *Lutz Jaenicke* + + * Add information about CygWin 1.3 and on, and preserve proper + configuration for the versions before that. + + *Corinna Vinschen and Richard Levitte* + + * Make removal from session cache (SSL_CTX_remove_session()) more robust: + check whether we deal with a copy of a session and do not delete from + the cache in this case. Problem reported by "Izhar Shoshani Levi" + . + + *Lutz Jaenicke* + + * Do not store session data into the internal session cache, if it + is never intended to be looked up (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP + flag is set). Proposed by Aslam . + + *Lutz Jaenicke* + + * Have ASN1_BIT_STRING_set_bit() really clear a bit when the requested + value is 0. + + *Richard Levitte* + + * [In 0.9.6d-engine release:] + Fix a crashbug and a logic bug in hwcrhk_load_pubkey(). + + *Toomas Kiisk via Richard Levitte* + + * Add the configuration target linux-s390x. + + *Neale Ferguson via Richard Levitte* + + * The earlier bugfix for the SSL3_ST_SW_HELLO_REQ_C case of + ssl3_accept (ssl/s3_srvr.c) incorrectly used a local flag + variable as an indication that a ClientHello message has been + received. As the flag value will be lost between multiple + invocations of ssl3_accept when using non-blocking I/O, the + function may not be aware that a handshake has actually taken + place, thus preventing a new session from being added to the + session cache. + + To avoid this problem, we now set s->new_session to 2 instead of + using a local variable. + + *Lutz Jaenicke, Bodo Moeller* + + * Bugfix: Return -1 from ssl3_get_server_done (ssl3/s3_clnt.c) + if the SSL_R_LENGTH_MISMATCH error is detected. + + *Geoff Thorpe, Bodo Moeller* + + * New 'shared_ldflag' column in Configure platform table. + + *Richard Levitte* + + * Fix EVP_CIPHER_mode macro. + + *"Dan S. Camper" * + + * Fix ssl3_read_bytes (ssl/s3_pkt.c): To ignore messages of unknown + type, we must throw them away by setting rr->length to 0. + + *D P Chang * + +### Changes between 0.9.6b and 0.9.6c [21 dec 2001] + + * Fix BN_rand_range bug pointed out by Dominikus Scherkl + . (The previous implementation + worked incorrectly for those cases where range = `10..._2` and + `3*range` is two bits longer than range.) + + *Bodo Moeller* + + * Only add signing time to PKCS7 structures if it is not already + present. + + *Steve Henson* + + * Fix crypto/objects/objects.h: "ld-ce" should be "id-ce", + OBJ_ld_ce should be OBJ_id_ce. + Also some ip-pda OIDs in crypto/objects/objects.txt were + incorrect (cf. RFC 3039). + + *Matt Cooper, Frederic Giudicelli, Bodo Moeller* + + * Release CRYPTO_LOCK_DYNLOCK when CRYPTO_destroy_dynlockid() + returns early because it has nothing to do. + + *Andy Schneider * + + * [In 0.9.6c-engine release:] + Fix mutex callback return values in crypto/engine/hw_ncipher.c. + + *Andy Schneider * + + * [In 0.9.6c-engine release:] + Add support for Cryptographic Appliance's keyserver technology. + (Use engine 'keyclient') + + *Cryptographic Appliances and Geoff Thorpe* + + * Add a configuration entry for OS/390 Unix. The C compiler 'c89' + is called via tools/c89.sh because arguments have to be + rearranged (all '-L' options must appear before the first object + modules). + + *Richard Shapiro * + + * [In 0.9.6c-engine release:] + Add support for Broadcom crypto accelerator cards, backported + from 0.9.7. + + *Broadcom, Nalin Dahyabhai , Mark Cox* + + * [In 0.9.6c-engine release:] + Add support for SureWare crypto accelerator cards from + Baltimore Technologies. (Use engine 'sureware') + + *Baltimore Technologies and Mark Cox* + + * [In 0.9.6c-engine release:] + Add support for crypto accelerator cards from Accelerated + Encryption Processing, www.aep.ie. (Use engine 'aep') + + *AEP Inc. and Mark Cox* + + * Add a configuration entry for gcc on UnixWare. + + *Gary Benson * + + * Change ssl/s2_clnt.c and ssl/s2_srvr.c so that received handshake + messages are stored in a single piece (fixed-length part and + variable-length part combined) and fix various bugs found on the way. + + *Bodo Moeller* + + * Disable caching in BIO_gethostbyname(), directly use gethostbyname() + instead. BIO_gethostbyname() does not know what timeouts are + appropriate, so entries would stay in cache even when they have + become invalid. + *Bodo Moeller; problem pointed out by Rich Salz * + + * Change ssl23_get_client_hello (ssl/s23_srvr.c) behaviour when + faced with a pathologically small ClientHello fragment that does + not contain client_version: Instead of aborting with an error, + simply choose the highest available protocol version (i.e., + TLS 1.0 unless it is disabled). In practice, ClientHello + messages are never sent like this, but this change gives us + strictly correct behaviour at least for TLS. + + *Bodo Moeller* + + * Fix SSL handshake functions and SSL_clear() such that SSL_clear() + never resets s->method to s->ctx->method when called from within + one of the SSL handshake functions. + + *Bodo Moeller; problem pointed out by Niko Baric* + + * In ssl3_get_client_hello (ssl/s3_srvr.c), generate a fatal alert + (sent using the client's version number) if client_version is + smaller than the protocol version in use. Also change + ssl23_get_client_hello (ssl/s23_srvr.c) to select TLS 1.0 if + the client demanded SSL 3.0 but only TLS 1.0 is enabled; then + the client will at least see that alert. + + *Bodo Moeller* + + * Fix ssl3_get_message (ssl/s3_both.c) to handle message fragmentation + correctly. + + *Bodo Moeller* + + * Avoid infinite loop in ssl3_get_message (ssl/s3_both.c) if a + client receives HelloRequest while in a handshake. + + *Bodo Moeller; bug noticed by Andy Schneider * + + * Bugfix in ssl3_accept (ssl/s3_srvr.c): Case SSL3_ST_SW_HELLO_REQ_C + should end in 'break', not 'goto end' which circumvents various + cleanups done in state SSL_ST_OK. But session related stuff + must be disabled for SSL_ST_OK in the case that we just sent a + HelloRequest. + + Also avoid some overhead by not calling ssl_init_wbio_buffer() + before just sending a HelloRequest. + + *Bodo Moeller, Eric Rescorla * + + * Fix ssl/s3_enc.c, ssl/t1_enc.c and ssl/s3_pkt.c so that we don't + reveal whether illegal block cipher padding was found or a MAC + verification error occurred. (Neither SSLerr() codes nor alerts + are directly visible to potential attackers, but the information + may leak via logfiles.) + + Similar changes are not required for the SSL 2.0 implementation + because the number of padding bytes is sent in clear for SSL 2.0, + and the extra bytes are just ignored. However ssl/s2_pkt.c + failed to verify that the purported number of padding bytes is in + the legal range. + + *Bodo Moeller* + + * Add OpenUNIX-8 support including shared libraries + (Boyd Lynn Gerber ). + + *Lutz Jaenicke* + + * Improve RSA_padding_check_PKCS1_OAEP() check again to avoid + 'wristwatch attack' using huge encoding parameters (cf. + James H. Manger's CRYPTO 2001 paper). Note that the + RSA_PKCS1_OAEP_PADDING case of RSA_private_decrypt() does not use + encoding parameters and hence was not vulnerable. + + *Bodo Moeller* + + * BN_sqr() bug fix. + + *Ulf Möller, reported by Jim Ellis * + + * Rabin-Miller test analyses assume uniformly distributed witnesses, + so use BN_pseudo_rand_range() instead of using BN_pseudo_rand() + followed by modular reduction. + + *Bodo Moeller; pointed out by Adam Young * + + * Add BN_pseudo_rand_range() with obvious functionality: BN_rand_range() + equivalent based on BN_pseudo_rand() instead of BN_rand(). + + *Bodo Moeller* + + * s3_srvr.c: allow sending of large client certificate lists (> 16 kB). + This function was broken, as the check for a new client hello message + to handle SGC did not allow these large messages. + (Tracked down by "Douglas E. Engert" .) + + *Lutz Jaenicke* + + * Add alert descriptions for TLSv1 to `SSL_alert_desc_string[_long]()`. + + *Lutz Jaenicke* + + * Fix buggy behaviour of BIO_get_num_renegotiates() and BIO_ctrl() + for BIO_C_GET_WRITE_BUF_SIZE ("Stephen Hinton" ). + + *Lutz Jaenicke* + + * Rework the configuration and shared library support for Tru64 Unix. + The configuration part makes use of modern compiler features and + still retains old compiler behavior for those that run older versions + of the OS. The shared library support part includes a variant that + uses the RPATH feature, and is available through the special + configuration target "alpha-cc-rpath", which will never be selected + automatically. + + *Tim Mooney via Richard Levitte* + + * In ssl3_get_key_exchange (ssl/s3_clnt.c), call ssl3_get_message() + with the same message size as in ssl3_get_certificate_request(). + Otherwise, if no ServerKeyExchange message occurs, CertificateRequest + messages might inadvertently be reject as too long. + + *Petr Lampa * + + * Enhanced support for IA-64 Unix platforms (well, Linux and HP-UX). + + *Andy Polyakov* + + * Modified SSL library such that the verify_callback that has been set + specifically for an SSL object with SSL_set_verify() is actually being + used. Before the change, a verify_callback set with this function was + ignored and the verify_callback() set in the SSL_CTX at the time of + the call was used. New function X509_STORE_CTX_set_verify_cb() introduced + to allow the necessary settings. + + *Lutz Jaenicke* + + * Initialize static variable in crypto/dsa/dsa_lib.c and crypto/dh/dh_lib.c + explicitly to NULL, as at least on Solaris 8 this seems not always to be + done automatically (in contradiction to the requirements of the C + standard). This made problems when used from OpenSSH. + + *Lutz Jaenicke* + + * In OpenSSL 0.9.6a and 0.9.6b, crypto/dh/dh_key.c ignored + dh->length and always used + + BN_rand_range(priv_key, dh->p). + + BN_rand_range() is not necessary for Diffie-Hellman, and this + specific range makes Diffie-Hellman unnecessarily inefficient if + dh->length (recommended exponent length) is much smaller than the + length of dh->p. We could use BN_rand_range() if the order of + the subgroup was stored in the DH structure, but we only have + dh->length. + + So switch back to + + BN_rand(priv_key, l, ...) + + where 'l' is dh->length if this is defined, or BN_num_bits(dh->p)-1 + otherwise. + + *Bodo Moeller* + + * In + + RSA_eay_public_encrypt + RSA_eay_private_decrypt + RSA_eay_private_encrypt (signing) + RSA_eay_public_decrypt (signature verification) + + (default implementations for RSA_public_encrypt, + RSA_private_decrypt, RSA_private_encrypt, RSA_public_decrypt), + always reject numbers >= n. + + *Bodo Moeller* + + * In crypto/rand/md_rand.c, use a new short-time lock CRYPTO_LOCK_RAND2 + to synchronize access to 'locking_thread'. This is necessary on + systems where access to 'locking_thread' (an 'unsigned long' + variable) is not atomic. + + *Bodo Moeller* + + * In crypto/rand/md_rand.c, set 'locking_thread' to current thread's ID + *before* setting the 'crypto_lock_rand' flag. The previous code had + a race condition if 0 is a valid thread ID. + + *Travis Vitek * + + * Add support for shared libraries under Irix. + + *Albert Chin-A-Young * + + * Add configuration option to build on Linux on both big-endian and + little-endian MIPS. + + *Ralf Baechle * + + * Add the possibility to create shared libraries on HP-UX. + + *Richard Levitte* + +### Changes between 0.9.6a and 0.9.6b [9 Jul 2001] + + * Change ssleay_rand_bytes (crypto/rand/md_rand.c) + to avoid a SSLeay/OpenSSL PRNG weakness pointed out by + Markku-Juhani O. Saarinen : + PRNG state recovery was possible based on the output of + one PRNG request appropriately sized to gain knowledge on + 'md' followed by enough consecutive 1-byte PRNG requests + to traverse all of 'state'. + + 1. When updating 'md_local' (the current thread's copy of 'md') + during PRNG output generation, hash all of the previous + 'md_local' value, not just the half used for PRNG output. + + 2. Make the number of bytes from 'state' included into the hash + independent from the number of PRNG bytes requested. + + The first measure alone would be sufficient to avoid + Markku-Juhani's attack. (Actually it had never occurred + to me that the half of 'md_local' used for chaining was the + half from which PRNG output bytes were taken -- I had always + assumed that the secret half would be used.) The second + measure makes sure that additional data from 'state' is never + mixed into 'md_local' in small portions; this heuristically + further strengthens the PRNG. + + *Bodo Moeller* + + * Fix crypto/bn/asm/mips3.s. + + *Andy Polyakov* + + * When only the key is given to "enc", the IV is undefined. Print out + an error message in this case. + + *Lutz Jaenicke* + + * Handle special case when X509_NAME is empty in X509 printing routines. + + *Steve Henson* + + * In dsa_do_verify (crypto/dsa/dsa_ossl.c), verify that r and s are + positive and less than q. + + *Bodo Moeller* + + * Don't change `*pointer` in CRYPTO_add_lock() is add_lock_callback is + used: it isn't thread safe and the add_lock_callback should handle + that itself. + + *Paul Rose * + + * Verify that incoming data obeys the block size in + ssl3_enc (ssl/s3_enc.c) and tls1_enc (ssl/t1_enc.c). + + *Bodo Moeller* + + * Fix OAEP check. + + *Ulf Möller, Bodo Möller* + + * The countermeasure against Bleichbacher's attack on PKCS #1 v1.5 + RSA encryption was accidentally removed in s3_srvr.c in OpenSSL 0.9.5 + when fixing the server behaviour for backwards-compatible 'client + hello' messages. (Note that the attack is impractical against + SSL 3.0 and TLS 1.0 anyway because length and version checking + means that the probability of guessing a valid ciphertext is + around 2^-40; see section 5 in Bleichenbacher's CRYPTO '98 + paper.) + + Before 0.9.5, the countermeasure (hide the error by generating a + random 'decryption result') did not work properly because + ERR_clear_error() was missing, meaning that SSL_get_error() would + detect the supposedly ignored error. + + Both problems are now fixed. + + *Bodo Moeller* + + * In crypto/bio/bf_buff.c, increase DEFAULT_BUFFER_SIZE to 4096 + (previously it was 1024). + + *Bodo Moeller* + + * Fix for compatibility mode trust settings: ignore trust settings + unless some valid trust or reject settings are present. + + *Steve Henson* + + * Fix for blowfish EVP: its a variable length cipher. + + *Steve Henson* + + * Fix various bugs related to DSA S/MIME verification. Handle missing + parameters in DSA public key structures and return an error in the + DSA routines if parameters are absent. + + *Steve Henson* + + * In versions up to 0.9.6, RAND_file_name() resorted to file ".rnd" + in the current directory if neither $RANDFILE nor $HOME was set. + RAND_file_name() in 0.9.6a returned NULL in this case. This has + caused some confusion to Windows users who haven't defined $HOME. + Thus RAND_file_name() is changed again: e_os.h can define a + DEFAULT_HOME, which will be used if $HOME is not set. + For Windows, we use "C:"; on other platforms, we still require + environment variables. + + * Move 'if (!initialized) RAND_poll()' into regions protected by + CRYPTO_LOCK_RAND. This is not strictly necessary, but avoids + having multiple threads call RAND_poll() concurrently. + + *Bodo Moeller* + + * In crypto/rand/md_rand.c, replace 'add_do_not_lock' flag by a + combination of a flag and a thread ID variable. + Otherwise while one thread is in ssleay_rand_bytes (which sets the + flag), *other* threads can enter ssleay_add_bytes without obeying + the CRYPTO_LOCK_RAND lock (and may even illegally release the lock + that they do not hold after the first thread unsets add_do_not_lock). + + *Bodo Moeller* + + * Change bctest again: '-x' expressions are not available in all + versions of 'test'. + + *Bodo Moeller* + +### Changes between 0.9.6 and 0.9.6a [5 Apr 2001] + + * Fix a couple of memory leaks in PKCS7_dataDecode() + + *Steve Henson, reported by Heyun Zheng * + + * Change Configure and Makefiles to provide EXE_EXT, which will contain + the default extension for executables, if any. Also, make the perl + scripts that use symlink() to test if it really exists and use "cp" + if it doesn't. All this made OpenSSL compilable and installable in + CygWin. + + *Richard Levitte* + + * Fix for asn1_GetSequence() for indefinite length constructed data. + If SEQUENCE is length is indefinite just set c->slen to the total + amount of data available. + + *Steve Henson, reported by shige@FreeBSD.org* + + *This change does not apply to 0.9.7.* + + * Change bctest to avoid here-documents inside command substitution + (workaround for FreeBSD /bin/sh bug). + For compatibility with Ultrix, avoid shell functions (introduced + in the bctest version that searches along $PATH). + + *Bodo Moeller* + + * Rename 'des_encrypt' to 'des_encrypt1'. This avoids the clashes + with des_encrypt() defined on some operating systems, like Solaris + and UnixWare. + + *Richard Levitte* + + * Check the result of RSA-CRT (see D. Boneh, R. DeMillo, R. Lipton: + On the Importance of Eliminating Errors in Cryptographic + Computations, J. Cryptology 14 (2001) 2, 101-119, + ). + + *Ulf Moeller* + + * MIPS assembler BIGNUM division bug fix. + + *Andy Polyakov* + + * Disabled incorrect Alpha assembler code. + + *Richard Levitte* + + * Fix PKCS#7 decode routines so they correctly update the length + after reading an EOC for the EXPLICIT tag. + + *Steve Henson* + + *This change does not apply to 0.9.7.* + + * Fix bug in PKCS#12 key generation routines. This was triggered + if a 3DES key was generated with a 0 initial byte. Include + PKCS12_BROKEN_KEYGEN compilation option to retain the old + (but broken) behaviour. + + *Steve Henson* + + * Enhance bctest to search for a working bc along $PATH and print + it when found. + + *Tim Rice via Richard Levitte* + + * Fix memory leaks in err.c: free err_data string if necessary; + don't write to the wrong index in ERR_set_error_data. + + *Bodo Moeller* + + * Implement ssl23_peek (analogous to ssl23_read), which previously + did not exist. + + *Bodo Moeller* + + * Replace rdtsc with `_emit` statements for VC++ version 5. + + *Jeremy Cooper * + + * Make it possible to reuse SSLv2 sessions. + + *Richard Levitte* + + * In copy_email() check for >= 0 as a return value for + X509_NAME_get_index_by_NID() since 0 is a valid index. + + *Steve Henson reported by Massimiliano Pala * + + * Avoid coredump with unsupported or invalid public keys by checking if + X509_get_pubkey() fails in PKCS7_verify(). Fix memory leak when + PKCS7_verify() fails with non detached data. + + *Steve Henson* + + * Don't use getenv in library functions when run as setuid/setgid. + New function OPENSSL_issetugid(). + + *Ulf Moeller* + + * Avoid false positives in memory leak detection code (crypto/mem_dbg.c) + due to incorrect handling of multi-threading: + + 1. Fix timing glitch in the MemCheck_off() portion of CRYPTO_mem_ctrl(). + + 2. Fix logical glitch in is_MemCheck_on() aka CRYPTO_is_mem_check_on(). + + 3. Count how many times MemCheck_off() has been called so that + nested use can be treated correctly. This also avoids + inband-signalling in the previous code (which relied on the + assumption that thread ID 0 is impossible). + + *Bodo Moeller* + + * Add "-rand" option also to s_client and s_server. + + *Lutz Jaenicke* + + * Fix CPU detection on Irix 6.x. + *Kurt Hockenbury and + "Bruce W. Forsberg" * + + * Fix X509_NAME bug which produced incorrect encoding if X509_NAME + was empty. + + *Steve Henson* + + *This change does not apply to 0.9.7.* + + * Use the cached encoding of an X509_NAME structure rather than + copying it. This is apparently the reason for the libsafe "errors" + but the code is actually correct. + + *Steve Henson* + + * Add new function BN_rand_range(), and fix DSA_sign_setup() to prevent + Bleichenbacher's DSA attack. + Extend BN_[pseudo_]rand: As before, top=1 forces the highest two bits + to be set and top=0 forces the highest bit to be set; top=-1 is new + and leaves the highest bit random. + + *Ulf Moeller, Bodo Moeller* + + * In the `NCONF_...`-based implementations for `CONF_...` queries + (crypto/conf/conf_lib.c), if the input LHASH is NULL, avoid using + a temporary CONF structure with the data component set to NULL + (which gives segmentation faults in lh_retrieve). + Instead, use NULL for the CONF pointer in CONF_get_string and + CONF_get_number (which may use environment variables) and directly + return NULL from CONF_get_section. + + *Bodo Moeller* + + * Fix potential buffer overrun for EBCDIC. + + *Ulf Moeller* + + * Tolerate nonRepudiation as being valid for S/MIME signing and certSign + keyUsage if basicConstraints absent for a CA. + + *Steve Henson* + + * Make SMIME_write_PKCS7() write mail header values with a format that + is more generally accepted (no spaces before the semicolon), since + some programs can't parse those values properly otherwise. Also make + sure BIO's that break lines after each write do not create invalid + headers. + + *Richard Levitte* + + * Make the CRL encoding routines work with empty SEQUENCE OF. The + macros previously used would not encode an empty SEQUENCE OF + and break the signature. + + *Steve Henson* + + *This change does not apply to 0.9.7.* + + * Zero the premaster secret after deriving the master secret in + DH ciphersuites. + + *Steve Henson* + + * Add some EVP_add_digest_alias registrations (as found in + OpenSSL_add_all_digests()) to SSL_library_init() + aka OpenSSL_add_ssl_algorithms(). This provides improved + compatibility with peers using X.509 certificates + with unconventional AlgorithmIdentifier OIDs. + + *Bodo Moeller* + + * Fix for Irix with NO_ASM. + + *"Bruce W. Forsberg" * + + * ./config script fixes. + + *Ulf Moeller, Richard Levitte* + + * Fix 'openssl passwd -1'. + + *Bodo Moeller* + + * Change PKCS12_key_gen_asc() so it can cope with non null + terminated strings whose length is passed in the passlen + parameter, for example from PEM callbacks. This was done + by adding an extra length parameter to asc2uni(). + + *Steve Henson, reported by * + + * Fix C code generated by 'openssl dsaparam -C': If a BN_bin2bn + call failed, free the DSA structure. + + *Bodo Moeller* + + * Fix to uni2asc() to cope with zero length Unicode strings. + These are present in some PKCS#12 files. + + *Steve Henson* + + * Increase s2->wbuf allocation by one byte in ssl2_new (ssl/s2_lib.c). + Otherwise do_ssl_write (ssl/s2_pkt.c) will write beyond buffer limits + when writing a 32767 byte record. + + *Bodo Moeller; problem reported by Eric Day * + + * In `RSA_eay_public_{en,ed}crypt` and RSA_eay_mod_exp (rsa_eay.c), + obtain lock CRYPTO_LOCK_RSA before setting `rsa->_method_mod_{n,p,q}`. + + (RSA objects have a reference count access to which is protected + by CRYPTO_LOCK_RSA [see rsa_lib.c, s3_srvr.c, ssl_cert.c, ssl_rsa.c], + so they are meant to be shared between threads.) + *Bodo Moeller, Geoff Thorpe; original patch submitted by + "Reddie, Steven" * + + * Fix a deadlock in CRYPTO_mem_leaks(). + + *Bodo Moeller* + + * Use better test patterns in bntest. + + *Ulf Möller* + + * rand_win.c fix for Borland C. + + *Ulf Möller* + + * BN_rshift bugfix for n == 0. + + *Bodo Moeller* + + * Add a 'bctest' script that checks for some known 'bc' bugs + so that 'make test' does not abort just because 'bc' is broken. + + *Bodo Moeller* + + * Store verify_result within SSL_SESSION also for client side to + avoid potential security hole. (Re-used sessions on the client side + always resulted in verify_result==X509_V_OK, not using the original + result of the server certificate verification.) + + *Lutz Jaenicke* + + * Fix ssl3_pending: If the record in s->s3->rrec is not of type + SSL3_RT_APPLICATION_DATA, return 0. + Similarly, change ssl2_pending to return 0 if SSL_in_init(s) is true. + + *Bodo Moeller* + + * Fix SSL_peek: + Both ssl2_peek and ssl3_peek, which were totally broken in earlier + releases, have been re-implemented by renaming the previous + implementations of ssl2_read and ssl3_read to ssl2_read_internal + and ssl3_read_internal, respectively, and adding 'peek' parameters + to them. The new ssl[23]_{read,peek} functions are calls to + ssl[23]_read_internal with the 'peek' flag set appropriately. + A 'peek' parameter has also been added to ssl3_read_bytes, which + does the actual work for ssl3_read_internal. + + *Bodo Moeller* + + * Initialise "ex_data" member of RSA/DSA/DH structures prior to calling + the method-specific "init()" handler. Also clean up ex_data after + calling the method-specific "finish()" handler. Previously, this was + happening the other way round. + + *Geoff Thorpe* + + * Increase BN_CTX_NUM (the number of BIGNUMs in a BN_CTX) to 16. + The previous value, 12, was not always sufficient for BN_mod_exp(). + + *Bodo Moeller* + + * Make sure that shared libraries get the internal name engine with + the full version number and not just 0. This should mark the + shared libraries as not backward compatible. Of course, this should + be changed again when we can guarantee backward binary compatibility. + + *Richard Levitte* + + * Fix typo in get_cert_by_subject() in by_dir.c + + *Jean-Marc Desperrier * + + * Rework the system to generate shared libraries: + + - Make note of the expected extension for the shared libraries and + if there is a need for symbolic links from for example libcrypto.so.0 + to libcrypto.so.0.9.7. There is extended info in Configure for + that. + + - Make as few rebuilds of the shared libraries as possible. + + - Still avoid linking the OpenSSL programs with the shared libraries. + + - When installing, install the shared libraries separately from the + static ones. + + *Richard Levitte* + + * Fix SSL_CTX_set_read_ahead macro to actually use its argument. + + Copy SSL_CTX's read_ahead flag to SSL object directly in SSL_new + and not in SSL_clear because the latter is also used by the + accept/connect functions; previously, the settings made by + SSL_set_read_ahead would be lost during the handshake. + + *Bodo Moeller; problems reported by Anders Gertz * + + * Correct util/mkdef.pl to be selective about disabled algorithms. + Previously, it would create entries for disabled algorithms no + matter what. + + *Richard Levitte* + + * Added several new manual pages for SSL_* function. + + *Lutz Jaenicke* + +### Changes between 0.9.5a and 0.9.6 [24 Sep 2000] + + * In ssl23_get_client_hello, generate an error message when faced + with an initial SSL 3.0/TLS record that is too small to contain the + first two bytes of the ClientHello message, i.e. client_version. + (Note that this is a pathologic case that probably has never happened + in real life.) The previous approach was to use the version number + from the record header as a substitute; but our protocol choice + should not depend on that one because it is not authenticated + by the Finished messages. + + *Bodo Moeller* + + * More robust randomness gathering functions for Windows. + + *Jeffrey Altman * + + * For compatibility reasons if the flag X509_V_FLAG_ISSUER_CHECK is + not set then we don't setup the error code for issuer check errors + to avoid possibly overwriting other errors which the callback does + handle. If an application does set the flag then we assume it knows + what it is doing and can handle the new informational codes + appropriately. + + *Steve Henson* + + * Fix for a nasty bug in ASN1_TYPE handling. ASN1_TYPE is used for + a general "ANY" type, as such it should be able to decode anything + including tagged types. However it didn't check the class so it would + wrongly interpret tagged types in the same way as their universal + counterpart and unknown types were just rejected. Changed so that the + tagged and unknown types are handled in the same way as a SEQUENCE: + that is the encoding is stored intact. There is also a new type + "V_ASN1_OTHER" which is used when the class is not universal, in this + case we have no idea what the actual type is so we just lump them all + together. + + *Steve Henson* + + * On VMS, stdout may very well lead to a file that is written to + in a record-oriented fashion. That means that every write() will + write a separate record, which will be read separately by the + programs trying to read from it. This can be very confusing. + + The solution is to put a BIO filter in the way that will buffer + text until a linefeed is reached, and then write everything a + line at a time, so every record written will be an actual line, + not chunks of lines and not (usually doesn't happen, but I've + seen it once) several lines in one record. BIO_f_linebuffer() is + the answer. + + Currently, it's a VMS-only method, because that's where it has + been tested well enough. + + *Richard Levitte* + + * Remove 'optimized' squaring variant in BN_mod_mul_montgomery, + it can return incorrect results. + (Note: The buggy variant was not enabled in OpenSSL 0.9.5a, + but it was in 0.9.6-beta[12].) + + *Bodo Moeller* + + * Disable the check for content being present when verifying detached + signatures in pk7_smime.c. Some versions of Netscape (wrongly) + include zero length content when signing messages. + + *Steve Henson* + + * New BIO_shutdown_wr macro, which invokes the BIO_C_SHUTDOWN_WR + BIO_ctrl (for BIO pairs). + + *Bodo Möller* + + * Add DSO method for VMS. + + *Richard Levitte* + + * Bug fix: Montgomery multiplication could produce results with the + wrong sign. + + *Ulf Möller* + + * Add RPM specification openssl.spec and modify it to build three + packages. The default package contains applications, application + documentation and run-time libraries. The devel package contains + include files, static libraries and function documentation. The + doc package contains the contents of the doc directory. The original + openssl.spec was provided by Damien Miller . + + *Richard Levitte* + + * Add a large number of documentation files for many SSL routines. + + *Lutz Jaenicke * + + * Add a configuration entry for Sony News 4. + + *NAKAJI Hiroyuki * + + * Don't set the two most significant bits to one when generating a + random number < q in the DSA library. + + *Ulf Möller* + + * New SSL API mode 'SSL_MODE_AUTO_RETRY'. This disables the default + behaviour that SSL_read may result in SSL_ERROR_WANT_READ (even if + the underlying transport is blocking) if a handshake took place. + (The default behaviour is needed by applications such as s_client + and s_server that use select() to determine when to use SSL_read; + but for applications that know in advance when to expect data, it + just makes things more complicated.) + + *Bodo Moeller* + + * Add RAND_egd_bytes(), which gives control over the number of bytes read + from EGD. + + *Ben Laurie* + + * Add a few more EBCDIC conditionals that make `req` and `x509` + work better on such systems. + + *Martin Kraemer * + + * Add two demo programs for PKCS12_parse() and PKCS12_create(). + Update PKCS12_parse() so it copies the friendlyName and the + keyid to the certificates aux info. + + *Steve Henson* + + * Fix bug in PKCS7_verify() which caused an infinite loop + if there was more than one signature. + + *Sven Uszpelkat * + + * Major change in util/mkdef.pl to include extra information + about each symbol, as well as presenting variables as well + as functions. This change means that there's n more need + to rebuild the .num files when some algorithms are excluded. + + *Richard Levitte* + + * Allow the verify time to be set by an application, + rather than always using the current time. + + *Steve Henson* + + * Phase 2 verify code reorganisation. The certificate + verify code now looks up an issuer certificate by a + number of criteria: subject name, authority key id + and key usage. It also verifies self signed certificates + by the same criteria. The main comparison function is + X509_check_issued() which performs these checks. + + Lot of changes were necessary in order to support this + without completely rewriting the lookup code. + + Authority and subject key identifier are now cached. + + The LHASH 'certs' is X509_STORE has now been replaced + by a STACK_OF(X509_OBJECT). This is mainly because an + LHASH can't store or retrieve multiple objects with + the same hash value. + + As a result various functions (which were all internal + use only) have changed to handle the new X509_STORE + structure. This will break anything that messed round + with X509_STORE internally. + + The functions X509_STORE_add_cert() now checks for an + exact match, rather than just subject name. + + The X509_STORE API doesn't directly support the retrieval + of multiple certificates matching a given criteria, however + this can be worked round by performing a lookup first + (which will fill the cache with candidate certificates) + and then examining the cache for matches. This is probably + the best we can do without throwing out X509_LOOKUP + entirely (maybe later...). + + The X509_VERIFY_CTX structure has been enhanced considerably. + + All certificate lookup operations now go via a get_issuer() + callback. Although this currently uses an X509_STORE it + can be replaced by custom lookups. This is a simple way + to bypass the X509_STORE hackery necessary to make this + work and makes it possible to use more efficient techniques + in future. A very simple version which uses a simple + STACK for its trusted certificate store is also provided + using X509_STORE_CTX_trusted_stack(). + + The verify_cb() and verify() callbacks now have equivalents + in the X509_STORE_CTX structure. + + X509_STORE_CTX also has a 'flags' field which can be used + to customise the verify behaviour. + + *Steve Henson* + + * Add new PKCS#7 signing option PKCS7_NOSMIMECAP which + excludes S/MIME capabilities. + + *Steve Henson* + + * When a certificate request is read in keep a copy of the + original encoding of the signed data and use it when outputting + again. Signatures then use the original encoding rather than + a decoded, encoded version which may cause problems if the + request is improperly encoded. + + *Steve Henson* + + * For consistency with other BIO_puts implementations, call + buffer_write(b, ...) directly in buffer_puts instead of calling + BIO_write(b, ...). + + In BIO_puts, increment b->num_write as in BIO_write. + + *Peter.Sylvester@EdelWeb.fr* + + * Fix BN_mul_word for the case where the word is 0. (We have to use + BN_zero, we may not return a BIGNUM with an array consisting of + words set to zero.) + + *Bodo Moeller* + + * Avoid calling abort() from within the library when problems are + detected, except if preprocessor symbols have been defined + (such as REF_CHECK, BN_DEBUG etc.). + + *Bodo Moeller* + + * New openssl application 'rsautl'. This utility can be + used for low-level RSA operations. DER public key + BIO/fp routines also added. + + *Steve Henson* + + * New Configure entry and patches for compiling on QNX 4. + + *Andreas Schneider * + + * A demo state-machine implementation was sponsored by + Nuron () and is now available in + demos/state_machine. + + *Ben Laurie* + + * New options added to the 'dgst' utility for signature + generation and verification. + + *Steve Henson* + + * Unrecognized PKCS#7 content types are now handled via a + catch all ASN1_TYPE structure. This allows unsupported + types to be stored as a "blob" and an application can + encode and decode it manually. + + *Steve Henson* + + * Fix various signed/unsigned issues to make a_strex.c + compile under VC++. + + *Oscar Jacobsson * + + * ASN1 fixes. i2d_ASN1_OBJECT was not returning the correct + length if passed a buffer. ASN1_INTEGER_to_BN failed + if passed a NULL BN and its argument was negative. + + *Steve Henson, pointed out by Sven Heiberg * + + * Modification to PKCS#7 encoding routines to output definite + length encoding. Since currently the whole structures are in + memory there's not real point in using indefinite length + constructed encoding. However if OpenSSL is compiled with + the flag PKCS7_INDEFINITE_ENCODING the old form is used. + + *Steve Henson* + + * Added BIO_vprintf() and BIO_vsnprintf(). + + *Richard Levitte* + + * Added more prefixes to parse for in the strings written + through a logging bio, to cover all the levels that are available + through syslog. The prefixes are now: + + PANIC, EMERG, EMR => LOG_EMERG + ALERT, ALR => LOG_ALERT + CRIT, CRI => LOG_CRIT + ERROR, ERR => LOG_ERR + WARNING, WARN, WAR => LOG_WARNING + NOTICE, NOTE, NOT => LOG_NOTICE + INFO, INF => LOG_INFO + DEBUG, DBG => LOG_DEBUG + + and as before, if none of those prefixes are present at the + beginning of the string, LOG_ERR is chosen. + + On Win32, the `LOG_*` levels are mapped according to this: + + LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR => EVENTLOG_ERROR_TYPE + LOG_WARNING => EVENTLOG_WARNING_TYPE + LOG_NOTICE, LOG_INFO, LOG_DEBUG => EVENTLOG_INFORMATION_TYPE + + *Richard Levitte* + + * Made it possible to reconfigure with just the configuration + argument "reconf" or "reconfigure". The command line arguments + are stored in Makefile.ssl in the variable CONFIGURE_ARGS, + and are retrieved from there when reconfiguring. + + *Richard Levitte* + + * MD4 implemented. + + *Assar Westerlund , Richard Levitte* + + * Add the arguments -CAfile and -CApath to the pkcs12 utility. + + *Richard Levitte* + + * The obj_dat.pl script was messing up the sorting of object + names. The reason was that it compared the quoted version + of strings as a result "OCSP" > "OCSP Signing" because + " > SPACE. Changed script to store unquoted versions of + names and add quotes on output. It was also omitting some + names from the lookup table if they were given a default + value (that is if SN is missing it is given the same + value as LN and vice versa), these are now added on the + grounds that if an object has a name we should be able to + look it up. Finally added warning output when duplicate + short or long names are found. + + *Steve Henson* + + * Changes needed for Tandem NSK. + + *Scott Uroff * + + * Fix SSL 2.0 rollback checking: Due to an off-by-one error in + RSA_padding_check_SSLv23(), special padding was never detected + and thus the SSL 3.0/TLS 1.0 countermeasure against protocol + version rollback attacks was not effective. + + In s23_clnt.c, don't use special rollback-attack detection padding + (RSA_SSLV23_PADDING) if SSL 2.0 is the only protocol enabled in the + client; similarly, in s23_srvr.c, don't do the rollback check if + SSL 2.0 is the only protocol enabled in the server. + + *Bodo Moeller* + + * Make it possible to get hexdumps of unprintable data with 'openssl + asn1parse'. By implication, the functions ASN1_parse_dump() and + BIO_dump_indent() are added. + + *Richard Levitte* + + * New functions ASN1_STRING_print_ex() and X509_NAME_print_ex() + these print out strings and name structures based on various + flags including RFC2253 support and proper handling of + multibyte characters. Added options to the 'x509' utility + to allow the various flags to be set. + + *Steve Henson* + + * Various fixes to use ASN1_TIME instead of ASN1_UTCTIME. + Also change the functions X509_cmp_current_time() and + X509_gmtime_adj() work with an ASN1_TIME structure, + this will enable certificates using GeneralizedTime in validity + dates to be checked. + + *Steve Henson* + + * Make the NEG_PUBKEY_BUG code (which tolerates invalid + negative public key encodings) on by default, + NO_NEG_PUBKEY_BUG can be set to disable it. + + *Steve Henson* + + * New function c2i_ASN1_OBJECT() which acts on ASN1_OBJECT + content octets. An i2c_ASN1_OBJECT is unnecessary because + the encoding can be trivially obtained from the structure. + + *Steve Henson* + + * crypto/err.c locking bugfix: Use write locks (`CRYPTO_w_[un]lock`), + not read locks (`CRYPTO_r_[un]lock`). + + *Bodo Moeller* + + * A first attempt at creating official support for shared + libraries through configuration. I've kept it so the + default is static libraries only, and the OpenSSL programs + are always statically linked for now, but there are + preparations for dynamic linking in place. + This has been tested on Linux and Tru64. + + *Richard Levitte* + + * Randomness polling function for Win9x, as described in: + Peter Gutmann, Software Generation of Practically Strong + Random Numbers. + + *Ulf Möller* + + * Fix so PRNG is seeded in req if using an already existing + DSA key. + + *Steve Henson* + + * New options to smime application. -inform and -outform + allow alternative formats for the S/MIME message including + PEM and DER. The -content option allows the content to be + specified separately. This should allow things like Netscape + form signing output easier to verify. + + *Steve Henson* + + * Fix the ASN1 encoding of tags using the 'long form'. + + *Steve Henson* + + * New ASN1 functions, `i2c_*` and `c2i_*` for INTEGER and BIT + STRING types. These convert content octets to and from the + underlying type. The actual tag and length octets are + already assumed to have been read in and checked. These + are needed because all other string types have virtually + identical handling apart from the tag. By having versions + of the ASN1 functions that just operate on content octets + IMPLICIT tagging can be handled properly. It also allows + the ASN1_ENUMERATED code to be cut down because ASN1_ENUMERATED + and ASN1_INTEGER are identical apart from the tag. + + *Steve Henson* + + * Change the handling of OID objects as follows: + + - New object identifiers are inserted in objects.txt, following + the syntax given in [crypto/objects/README.md](crypto/objects/README.md). + - objects.pl is used to process obj_mac.num and create a new + obj_mac.h. + - obj_dat.pl is used to create a new obj_dat.h, using the data in + obj_mac.h. + + This is currently kind of a hack, and the perl code in objects.pl + isn't very elegant, but it works as I intended. The simplest way + to check that it worked correctly is to look in obj_dat.h and + check the array nid_objs and make sure the objects haven't moved + around (this is important!). Additions are OK, as well as + consistent name changes. + + *Richard Levitte* + + * Add BSD-style MD5-based passwords to 'openssl passwd' (option '-1'). + + *Bodo Moeller* + + * Addition of the command line parameter '-rand file' to 'openssl req'. + The given file adds to whatever has already been seeded into the + random pool through the RANDFILE configuration file option or + environment variable, or the default random state file. + + *Richard Levitte* + + * mkstack.pl now sorts each macro group into lexical order. + Previously the output order depended on the order the files + appeared in the directory, resulting in needless rewriting + of safestack.h . + + *Steve Henson* + + * Patches to make OpenSSL compile under Win32 again. Mostly + work arounds for the VC++ problem that it treats func() as + func(void). Also stripped out the parts of mkdef.pl that + added extra typesafe functions: these no longer exist. + + *Steve Henson* + + * Reorganisation of the stack code. The macros are now all + collected in safestack.h . Each macro is defined in terms of + a "stack macro" of the form `SKM_(type, a, b)`. The + DEBUG_SAFESTACK is now handled in terms of function casts, + this has the advantage of retaining type safety without the + use of additional functions. If DEBUG_SAFESTACK is not defined + then the non typesafe macros are used instead. Also modified the + mkstack.pl script to handle the new form. Needs testing to see + if which (if any) compilers it chokes and maybe make DEBUG_SAFESTACK + the default if no major problems. Similar behaviour for ASN1_SET_OF + and PKCS12_STACK_OF. + + *Steve Henson* + + * When some versions of IIS use the 'NET' form of private key the + key derivation algorithm is different. Normally MD5(password) is + used as a 128 bit RC4 key. In the modified case + MD5(MD5(password) + "SGCKEYSALT") is used instead. Added some + new functions i2d_RSA_NET(), d2i_RSA_NET() etc which are the same + as the old Netscape_RSA functions except they have an additional + 'sgckey' parameter which uses the modified algorithm. Also added + an -sgckey command line option to the rsa utility. Thanks to + Adrian Peck for posting details of the modified + algorithm to openssl-dev. + + *Steve Henson* + + * The evp_local.h macros were using 'c.##kname' which resulted in + invalid expansion on some systems (SCO 5.0.5 for example). + Corrected to 'c.kname'. + + *Phillip Porch * + + * New X509_get1_email() and X509_REQ_get1_email() functions that return + a STACK of email addresses from a certificate or request, these look + in the subject name and the subject alternative name extensions and + omit any duplicate addresses. + + *Steve Henson* + + * Re-implement BN_mod_exp2_mont using independent (and larger) windows. + This makes DSA verification about 2 % faster. + + *Bodo Moeller* + + * Increase maximum window size in `BN_mod_exp_...` to 6 bits instead of 5 + (meaning that now 2^5 values will be precomputed, which is only 4 KB + plus overhead for 1024 bit moduli). + This makes exponentiations about 0.5 % faster for 1024 bit + exponents (as measured by "openssl speed rsa2048"). + + *Bodo Moeller* + + * Rename memory handling macros to avoid conflicts with other + software: + Malloc => OPENSSL_malloc + Malloc_locked => OPENSSL_malloc_locked + Realloc => OPENSSL_realloc + Free => OPENSSL_free + + *Richard Levitte* + + * New function BN_mod_exp_mont_word for small bases (roughly 15% + faster than BN_mod_exp_mont, i.e. 7% for a full DH exchange). + + *Bodo Moeller* + + * CygWin32 support. + + *John Jarvie * + + * The type-safe stack code has been rejigged. It is now only compiled + in when OpenSSL is configured with the DEBUG_SAFESTACK option and + by default all type-specific stack functions are "#define"d back to + standard stack functions. This results in more streamlined output + but retains the type-safety checking possibilities of the original + approach. + + *Geoff Thorpe* + + * The STACK code has been cleaned up, and certain type declarations + that didn't make a lot of sense have been brought in line. This has + also involved a cleanup of sorts in safestack.h to more correctly + map type-safe stack functions onto their plain stack counterparts. + This work has also resulted in a variety of "const"ifications of + lots of the code, especially `_cmp` operations which should normally + be prototyped with "const" parameters anyway. + + *Geoff Thorpe* + + * When generating bytes for the first time in md_rand.c, 'stir the pool' + by seeding with STATE_SIZE dummy bytes (with zero entropy count). + (The PRNG state consists of two parts, the large pool 'state' and 'md', + where all of 'md' is used each time the PRNG is used, but 'state' + is used only indexed by a cyclic counter. As entropy may not be + well distributed from the beginning, 'md' is important as a + chaining variable. However, the output function chains only half + of 'md', i.e. 80 bits. ssleay_rand_add, on the other hand, chains + all of 'md', and seeding with STATE_SIZE dummy bytes will result + in all of 'state' being rewritten, with the new values depending + on virtually all of 'md'. This overcomes the 80 bit limitation.) + + *Bodo Moeller* + + * In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when + the handshake is continued after ssl_verify_cert_chain(); + otherwise, if SSL_VERIFY_NONE is set, remaining error codes + can lead to 'unexplainable' connection aborts later. + + *Bodo Moeller; problem tracked down by Lutz Jaenicke* + + * Major EVP API cipher revision. + Add hooks for extra EVP features. This allows various cipher + parameters to be set in the EVP interface. Support added for variable + key length ciphers via the EVP_CIPHER_CTX_set_key_length() function and + setting of RC2 and RC5 parameters. + + Modify EVP_OpenInit() and EVP_SealInit() to cope with variable key length + ciphers. + + Remove lots of duplicated code from the EVP library. For example *every* + cipher init() function handles the 'iv' in the same way according to the + cipher mode. They also all do nothing if the 'key' parameter is NULL and + for CFB and OFB modes they zero ctx->num. + + New functionality allows removal of S/MIME code RC2 hack. + + Most of the routines have the same form and so can be declared in terms + of macros. + + By shifting this to the top level EVP_CipherInit() it can be removed from + all individual ciphers. If the cipher wants to handle IVs or keys + differently it can set the EVP_CIPH_CUSTOM_IV or EVP_CIPH_ALWAYS_CALL_INIT + flags. + + Change lots of functions like EVP_EncryptUpdate() to now return a + value: although software versions of the algorithms cannot fail + any installed hardware versions can. + + *Steve Henson* + + * Implement SSL_OP_TLS_ROLLBACK_BUG: In ssl3_get_client_key_exchange, if + this option is set, tolerate broken clients that send the negotiated + protocol version number instead of the requested protocol version + number. + + *Bodo Moeller* + + * Call dh_tmp_cb (set by `..._TMP_DH_CB`) with correct 'is_export' flag; + i.e. non-zero for export ciphersuites, zero otherwise. + Previous versions had this flag inverted, inconsistent with + rsa_tmp_cb (..._TMP_RSA_CB). + + *Bodo Moeller; problem reported by Amit Chopra* + + * Add missing DSA library text string. Work around for some IIS + key files with invalid SEQUENCE encoding. + + *Steve Henson* + + * Add a document (doc/standards.txt) that list all kinds of standards + and so on that are implemented in OpenSSL. + + *Richard Levitte* + + * Enhance c_rehash script. Old version would mishandle certificates + with the same subject name hash and wouldn't handle CRLs at all. + Added -fingerprint option to crl utility, to support new c_rehash + features. + + *Steve Henson* + + * Eliminate non-ANSI declarations in crypto.h and stack.h. + + *Ulf Möller* + + * Fix for SSL server purpose checking. Server checking was + rejecting certificates which had extended key usage present + but no ssl client purpose. + + *Steve Henson, reported by Rene Grosser * + + * Make PKCS#12 code work with no password. The PKCS#12 spec + is a little unclear about how a blank password is handled. + Since the password in encoded as a BMPString with terminating + double NULL a zero length password would end up as just the + double NULL. However no password at all is different and is + handled differently in the PKCS#12 key generation code. NS + treats a blank password as zero length. MSIE treats it as no + password on export: but it will try both on import. We now do + the same: PKCS12_parse() tries zero length and no password if + the password is set to "" or NULL (NULL is now a valid password: + it wasn't before) as does the pkcs12 application. + + *Steve Henson* + + * Bugfixes in `apps/x509.c`: Avoid a memory leak; and don't use + perror when PEM_read_bio_X509_REQ fails, the error message must + be obtained from the error queue. + + *Bodo Moeller* + + * Avoid 'thread_hash' memory leak in crypto/err/err.c by freeing + it in ERR_remove_state if appropriate, and change ERR_get_state + accordingly to avoid race conditions (this is necessary because + thread_hash is no longer constant once set). + + *Bodo Moeller* + + * Bugfix for linux-elf makefile.one. + + *Ulf Möller* + + * RSA_get_default_method() will now cause a default + RSA_METHOD to be chosen if one doesn't exist already. + Previously this was only set during a call to RSA_new() + or RSA_new_method(NULL) meaning it was possible for + RSA_get_default_method() to return NULL. + + *Geoff Thorpe* + + * Added native name translation to the existing DSO code + that will convert (if the flag to do so is set) filenames + that are sufficiently small and have no path information + into a canonical native form. Eg. "blah" converted to + "libblah.so" or "blah.dll" etc. + + *Geoff Thorpe* + + * New function ERR_error_string_n(e, buf, len) which is like + ERR_error_string(e, buf), but writes at most 'len' bytes + including the 0 terminator. For ERR_error_string_n, 'buf' + may not be NULL. + + *Damien Miller , Bodo Moeller* + + * CONF library reworked to become more general. A new CONF + configuration file reader "class" is implemented as well as a + new functions (`NCONF_*`, for "New CONF") to handle it. The now + old `CONF_*` functions are still there, but are reimplemented to + work in terms of the new functions. Also, a set of functions + to handle the internal storage of the configuration data is + provided to make it easier to write new configuration file + reader "classes" (I can definitely see something reading a + configuration file in XML format, for example), called `_CONF_*`, + or "the configuration storage API"... + + The new configuration file reading functions are: + + NCONF_new, NCONF_free, NCONF_load, NCONF_load_fp, NCONF_load_bio, + NCONF_get_section, NCONF_get_string, NCONF_get_numbre + + NCONF_default, NCONF_WIN32 + + NCONF_dump_fp, NCONF_dump_bio + + NCONF_default and NCONF_WIN32 are method (or "class") choosers, + NCONF_new creates a new CONF object. This works in the same way + as other interfaces in OpenSSL, like the BIO interface. + `NCONF_dump_*` dump the internal storage of the configuration file, + which is useful for debugging. All other functions take the same + arguments as the old `CONF_*` functions with the exception of the + first that must be a `CONF *` instead of a `LHASH *`. + + To make it easier to use the new classes with the old `CONF_*` functions, + the function CONF_set_default_method is provided. + + *Richard Levitte* + + * Add '-tls1' option to 'openssl ciphers', which was already + mentioned in the documentation but had not been implemented. + (This option is not yet really useful because even the additional + experimental TLS 1.0 ciphers are currently treated as SSL 3.0 ciphers.) + + *Bodo Moeller* + + * Initial DSO code added into libcrypto for letting OpenSSL (and + OpenSSL-based applications) load shared libraries and bind to + them in a portable way. + + *Geoff Thorpe, with contributions from Richard Levitte* + +### Changes between 0.9.5 and 0.9.5a [1 Apr 2000] + + * Make sure _lrotl and _lrotr are only used with MSVC. + + * Use lock CRYPTO_LOCK_RAND correctly in ssleay_rand_status + (the default implementation of RAND_status). + + * Rename openssl x509 option '-crlext', which was added in 0.9.5, + to '-clrext' (= clear extensions), as intended and documented. + *Bodo Moeller; inconsistency pointed out by Michael Attili + * + + * Fix for HMAC. It wasn't zeroing the rest of the block if the key length + was larger than the MD block size. + + *Steve Henson, pointed out by Yost William * + + * Modernise PKCS12_parse() so it uses STACK_OF(X509) for its ca argument + fix a leak when the ca argument was passed as NULL. Stop X509_PUBKEY_set() + using the passed key: if the passed key was a private key the result + of X509_print(), for example, would be to print out all the private key + components. + + *Steve Henson* + + * des_quad_cksum() byte order bug fix. + *Ulf Möller, using the problem description in krb4-0.9.7, where + the solution is attributed to Derrick J Brashear * + + * Fix so V_ASN1_APP_CHOOSE works again: however its use is strongly + discouraged. + + *Steve Henson, pointed out by Brian Korver * + + * For easily testing in shell scripts whether some command + 'openssl XXX' exists, the new pseudo-command 'openssl no-XXX' + returns with exit code 0 iff no command of the given name is available. + 'no-XXX' is printed in this case, 'XXX' otherwise. In both cases, + the output goes to stdout and nothing is printed to stderr. + Additional arguments are always ignored. + + Since for each cipher there is a command of the same name, + the 'no-cipher' compilation switches can be tested this way. + + ('openssl no-XXX' is not able to detect pseudo-commands such + as 'quit', 'list-XXX-commands', or 'no-XXX' itself.) + + *Bodo Moeller* + + * Update test suite so that 'make test' succeeds in 'no-rsa' configuration. + + *Bodo Moeller* + + * For SSL_[CTX_]set_tmp_dh, don't create a DH key if SSL_OP_SINGLE_DH_USE + is set; it will be thrown away anyway because each handshake creates + its own key. + ssl_cert_dup, which is used by SSL_new, now copies DH keys in addition + to parameters -- in previous versions (since OpenSSL 0.9.3) the + 'default key' from SSL_CTX_set_tmp_dh would always be lost, meaning + you effectively got SSL_OP_SINGLE_DH_USE when using this macro. + + *Bodo Moeller* + + * New s_client option -ign_eof: EOF at stdin is ignored, and + 'Q' and 'R' lose their special meanings (quit/renegotiate). + This is part of what -quiet does; unlike -quiet, -ign_eof + does not suppress any output. + + *Richard Levitte* + + * Add compatibility options to the purpose and trust code. The + purpose X509_PURPOSE_ANY is "any purpose" which automatically + accepts a certificate or CA, this was the previous behaviour, + with all the associated security issues. + + X509_TRUST_COMPAT is the old trust behaviour: only and + automatically trust self signed roots in certificate store. A + new trust setting X509_TRUST_DEFAULT is used to specify that + a purpose has no associated trust setting and it should instead + use the value in the default purpose. + + *Steve Henson* + + * Fix the PKCS#8 DSA private key code so it decodes keys again + and fix a memory leak. + + *Steve Henson* + + * In util/mkerr.pl (which implements 'make errors'), preserve + reason strings from the previous version of the .c file, as + the default to have only downcase letters (and digits) in + automatically generated reasons codes is not always appropriate. + + *Bodo Moeller* + + * In ERR_load_ERR_strings(), build an ERR_LIB_SYS error reason table + using strerror. Previously, ERR_reason_error_string() returned + library names as reason strings for SYSerr; but SYSerr is a special + case where small numbers are errno values, not library numbers. + + *Bodo Moeller* + + * Add '-dsaparam' option to 'openssl dhparam' application. This + converts DSA parameters into DH parameters. (When creating parameters, + DSA_generate_parameters is used.) + + *Bodo Moeller* + + * Include 'length' (recommended exponent length) in C code generated + by 'openssl dhparam -C'. + + *Bodo Moeller* + + * The second argument to set_label in perlasm was already being used + so couldn't be used as a "file scope" flag. Moved to third argument + which was free. + + *Steve Henson* + + * In PEM_ASN1_write_bio and some other functions, use RAND_pseudo_bytes + instead of RAND_bytes for encryption IVs and salts. + + *Bodo Moeller* + + * Include RAND_status() into RAND_METHOD instead of implementing + it only for md_rand.c Otherwise replacing the PRNG by calling + RAND_set_rand_method would be impossible. + + *Bodo Moeller* + + * Don't let DSA_generate_key() enter an infinite loop if the random + number generation fails. + + *Bodo Moeller* + + * New 'rand' application for creating pseudo-random output. + + *Bodo Moeller* + + * Added configuration support for Linux/IA64 + + *Rolf Haberrecker * + + * Assembler module support for Mingw32. + + *Ulf Möller* + + * Shared library support for HPUX (in shlib/). + + *Lutz Jaenicke and Anonymous* + + * Shared library support for Solaris gcc. + + *Lutz Behnke * + +### Changes between 0.9.4 and 0.9.5 [28 Feb 2000] + + * PKCS7_encrypt() was adding text MIME headers twice because they + were added manually and by SMIME_crlf_copy(). + + *Steve Henson* + + * In bntest.c don't call BN_rand with zero bits argument. + + *Steve Henson, pointed out by Andrew W. Gray * + + * BN_mul bugfix: In bn_mul_part_recursion() only the a>a[n] && b>b[n] + case was implemented. This caused BN_div_recp() to fail occasionally. + + *Ulf Möller* + + * Add an optional second argument to the set_label() in the perl + assembly language builder. If this argument exists and is set + to 1 it signals that the assembler should use a symbol whose + scope is the entire file, not just the current function. This + is needed with MASM which uses the format label:: for this scope. + + *Steve Henson, pointed out by Peter Runestig * + + * Change the ASN1 types so they are typedefs by default. Before + almost all types were #define'd to ASN1_STRING which was causing + STACK_OF() problems: you couldn't declare STACK_OF(ASN1_UTF8STRING) + for example. + + *Steve Henson* + + * Change names of new functions to the new get1/get0 naming + convention: After 'get1', the caller owns a reference count + and has to call `..._free`; 'get0' returns a pointer to some + data structure without incrementing reference counters. + (Some of the existing 'get' functions increment a reference + counter, some don't.) + Similarly, 'set1' and 'add1' functions increase reference + counters or duplicate objects. + + *Steve Henson* + + * Allow for the possibility of temp RSA key generation failure: + the code used to assume it always worked and crashed on failure. + + *Steve Henson* + + * Fix potential buffer overrun problem in BIO_printf(). + *Ulf Möller, using public domain code by Patrick Powell; problem + pointed out by David Sacerdote * + + * Support EGD . New functions + RAND_egd() and RAND_status(). In the command line application, + the EGD socket can be specified like a seed file using RANDFILE + or -rand. + + *Ulf Möller* + + * Allow the string CERTIFICATE to be tolerated in PKCS#7 structures. + Some CAs (e.g. Verisign) distribute certificates in this form. + + *Steve Henson* + + * Remove the SSL_ALLOW_ADH compile option and set the default cipher + list to exclude them. This means that no special compilation option + is needed to use anonymous DH: it just needs to be included in the + cipher list. + + *Steve Henson* + + * Change the EVP_MD_CTX_type macro so its meaning consistent with + EVP_MD_type. The old functionality is available in a new macro called + EVP_MD_md(). Change code that uses it and update docs. + + *Steve Henson* + + * `..._ctrl` functions now have corresponding `..._callback_ctrl` functions + where the `void *` argument is replaced by a function pointer argument. + Previously `void *` was abused to point to functions, which works on + many platforms, but is not correct. As these functions are usually + called by macros defined in OpenSSL header files, most source code + should work without changes. + + *Richard Levitte* + + * `` (which is created by Configure) now contains + sections with information on -D... compiler switches used for + compiling the library so that applications can see them. To enable + one of these sections, a pre-processor symbol `OPENSSL_..._DEFINES` + must be defined. E.g., + #define OPENSSL_ALGORITHM_DEFINES + #include + defines all pertinent `NO_` symbols, such as NO_IDEA, NO_RSA, etc. + + *Richard Levitte, Ulf and Bodo Möller* + + * Bugfix: Tolerate fragmentation and interleaving in the SSL 3/TLS + record layer. + + *Bodo Moeller* + + * Change the 'other' type in certificate aux info to a STACK_OF + X509_ALGOR. Although not an AlgorithmIdentifier as such it has + the required ASN1 format: arbitrary types determined by an OID. + + *Steve Henson* + + * Add some PEM_write_X509_REQ_NEW() functions and a command line + argument to 'req'. This is not because the function is newer or + better than others it just uses the work 'NEW' in the certificate + request header lines. Some software needs this. + + *Steve Henson* + + * Reorganise password command line arguments: now passwords can be + obtained from various sources. Delete the PEM_cb function and make + it the default behaviour: i.e. if the callback is NULL and the + usrdata argument is not NULL interpret it as a null terminated pass + phrase. If usrdata and the callback are NULL then the pass phrase + is prompted for as usual. + + *Steve Henson* + + * Add support for the Compaq Atalla crypto accelerator. If it is installed, + the support is automatically enabled. The resulting binaries will + autodetect the card and use it if present. + + *Ben Laurie and Compaq Inc.* + + * Work around for Netscape hang bug. This sends certificate request + and server done in one record. Since this is perfectly legal in the + SSL/TLS protocol it isn't a "bug" option and is on by default. See + the bugs/SSLv3 entry for more info. + + *Steve Henson* + + * HP-UX tune-up: new unified configs, HP C compiler bug workaround. + + *Andy Polyakov* + + * Add -rand argument to smime and pkcs12 applications and read/write + of seed file. + + *Steve Henson* + + * New 'passwd' tool for crypt(3) and apr1 password hashes. + + *Bodo Moeller* + + * Add command line password options to the remaining applications. + + *Steve Henson* + + * Bug fix for BN_div_recp() for numerators with an even number of + bits. + + *Ulf Möller* + + * More tests in bntest.c, and changed test_bn output. + + *Ulf Möller* + + * ./config recognizes MacOS X now. + + *Andy Polyakov* + + * Bug fix for BN_div() when the first words of num and divisor are + equal (it gave wrong results if `(rem=(n1-q*d0)&BN_MASK2) < d0)`. + + *Ulf Möller* + + * Add support for various broken PKCS#8 formats, and command line + options to produce them. + + *Steve Henson* + + * New functions BN_CTX_start(), BN_CTX_get() and BT_CTX_end() to + get temporary BIGNUMs from a BN_CTX. + + *Ulf Möller* + + * Correct return values in BN_mod_exp_mont() and BN_mod_exp2_mont() + for p == 0. + + *Ulf Möller* + + * Change the `SSLeay_add_all_*()` functions to `OpenSSL_add_all_*()` and + include a #define from the old name to the new. The original intent + was that statically linked binaries could for example just call + SSLeay_add_all_ciphers() to just add ciphers to the table and not + link with digests. This never worked because SSLeay_add_all_digests() + and SSLeay_add_all_ciphers() were in the same source file so calling + one would link with the other. They are now in separate source files. + + *Steve Henson* + + * Add a new -notext option to 'ca' and a -pubkey option to 'spkac'. + + *Steve Henson* + + * Use a less unusual form of the Miller-Rabin primality test (it used + a binary algorithm for exponentiation integrated into the Miller-Rabin + loop, our standard modexp algorithms are faster). + + *Bodo Moeller* + + * Support for the EBCDIC character set completed. + + *Martin Kraemer * + + * Source code cleanups: use const where appropriate, eliminate casts, + use `void *` instead of `char *` in lhash. + + *Ulf Möller* + + * Bugfix: ssl3_send_server_key_exchange was not restartable + (the state was not changed to SSL3_ST_SW_KEY_EXCH_B, and because of + this the server could overwrite ephemeral keys that the client + has already seen). + + *Bodo Moeller* + + * Turn DSA_is_prime into a macro that calls BN_is_prime, + using 50 iterations of the Rabin-Miller test. + + DSA_generate_parameters now uses BN_is_prime_fasttest (with 50 + iterations of the Rabin-Miller test as required by the appendix + to FIPS PUB 186[-1]) instead of DSA_is_prime. + As BN_is_prime_fasttest includes trial division, DSA parameter + generation becomes much faster. + + This implies a change for the callback functions in DSA_is_prime + and DSA_generate_parameters: The callback function is called once + for each positive witness in the Rabin-Miller test, not just + occasionally in the inner loop; and the parameters to the + callback function now provide an iteration count for the outer + loop rather than for the current invocation of the inner loop. + DSA_generate_parameters additionally can call the callback + function with an 'iteration count' of -1, meaning that a + candidate has passed the trial division test (when q is generated + from an application-provided seed, trial division is skipped). + + *Bodo Moeller* + + * New function BN_is_prime_fasttest that optionally does trial + division before starting the Rabin-Miller test and has + an additional BN_CTX * argument (whereas BN_is_prime always + has to allocate at least one BN_CTX). + 'callback(1, -1, cb_arg)' is called when a number has passed the + trial division stage. + + *Bodo Moeller* + + * Fix for bug in CRL encoding. The validity dates weren't being handled + as ASN1_TIME. + + *Steve Henson* + + * New -pkcs12 option to CA.pl script to write out a PKCS#12 file. + + *Steve Henson* + + * New function BN_pseudo_rand(). + + *Ulf Möller* + + * Clean up BN_mod_mul_montgomery(): replace the broken (and unreadable) + bignum version of BN_from_montgomery() with the working code from + SSLeay 0.9.0 (the word based version is faster anyway), and clean up + the comments. + + *Ulf Möller* + + * Avoid a race condition in s2_clnt.c (function get_server_hello) that + made it impossible to use the same SSL_SESSION data structure in + SSL2 clients in multiple threads. + + *Bodo Moeller* + + * The return value of RAND_load_file() no longer counts bytes obtained + by stat(). RAND_load_file(..., -1) is new and uses the complete file + to seed the PRNG (previously an explicit byte count was required). + + *Ulf Möller, Bodo Möller* + + * Clean up CRYPTO_EX_DATA functions, some of these didn't have prototypes + used `char *` instead of `void *` and had casts all over the place. + + *Steve Henson* + + * Make BN_generate_prime() return NULL on error if ret!=NULL. + + *Ulf Möller* + + * Retain source code compatibility for BN_prime_checks macro: + BN_is_prime(..., BN_prime_checks, ...) now uses + BN_prime_checks_for_size to determine the appropriate number of + Rabin-Miller iterations. + + *Ulf Möller* + + * Diffie-Hellman uses "safe" primes: DH_check() return code renamed to + DH_CHECK_P_NOT_SAFE_PRIME. + (Check if this is true? OpenPGP calls them "strong".) + + *Ulf Möller* + + * Merge the functionality of "dh" and "gendh" programs into a new program + "dhparam". The old programs are retained for now but will handle DH keys + (instead of parameters) in future. + + *Steve Henson* + + * Make the ciphers, s_server and s_client programs check the return values + when a new cipher list is set. + + *Steve Henson* + + * Enhance the SSL/TLS cipher mechanism to correctly handle the TLS 56bit + ciphers. Before when the 56bit ciphers were enabled the sorting was + wrong. + + The syntax for the cipher sorting has been extended to support sorting by + cipher-strength (using the strength_bits hard coded in the tables). + The new command is `@STRENGTH` (see also `doc/apps/ciphers.pod`). + + Fix a bug in the cipher-command parser: when supplying a cipher command + string with an "undefined" symbol (neither command nor alphanumeric + *A-Za-z0-9*, ssl_set_cipher_list used to hang in an endless loop. Now + an error is flagged. + + Due to the strength-sorting extension, the code of the + ssl_create_cipher_list() function was completely rearranged. I hope that + the readability was also increased :-) + + *Lutz Jaenicke * + + * Minor change to 'x509' utility. The -CAcreateserial option now uses 1 + for the first serial number and places 2 in the serial number file. This + avoids problems when the root CA is created with serial number zero and + the first user certificate has the same issuer name and serial number + as the root CA. + + *Steve Henson* + + * Fixes to X509_ATTRIBUTE utilities, change the 'req' program so it uses + the new code. Add documentation for this stuff. + + *Steve Henson* + + * Changes to X509_ATTRIBUTE utilities. These have been renamed from + `X509_*()` to `X509at_*()` on the grounds that they don't handle X509 + structures and behave in an analogous way to the X509v3 functions: + they shouldn't be called directly but wrapper functions should be used + instead. + + So we also now have some wrapper functions that call the X509at functions + when passed certificate requests. (TO DO: similar things can be done with + PKCS#7 signed and unsigned attributes, PKCS#12 attributes and a few other + things. Some of these need some d2i or i2d and print functionality + because they handle more complex structures.) + + *Steve Henson* + + * Add missing #ifndefs that caused missing symbols when building libssl + as a shared library without RSA. Use #ifndef NO_SSL2 instead of + NO_RSA in `ssl/s2*.c`. + + *Kris Kennaway , modified by Ulf Möller* + + * Precautions against using the PRNG uninitialized: RAND_bytes() now + has a return value which indicates the quality of the random data + (1 = ok, 0 = not seeded). Also an error is recorded on the thread's + error queue. New function RAND_pseudo_bytes() generates output that is + guaranteed to be unique but not unpredictable. RAND_add is like + RAND_seed, but takes an extra argument for an entropy estimate + (RAND_seed always assumes full entropy). + + *Ulf Möller* + + * Do more iterations of Rabin-Miller probable prime test (specifically, + 3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes + instead of only 2 for all lengths; see BN_prime_checks_for_size definition + in crypto/bn/bn_prime.c for the complete table). This guarantees a + false-positive rate of at most 2^-80 for random input. + + *Bodo Moeller* + + * Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs. + + *Bodo Moeller* + + * New function X509_CTX_rget_chain() (renamed to X509_CTX_get1_chain + in the 0.9.5 release), this returns the chain + from an X509_CTX structure with a dup of the stack and all + the X509 reference counts upped: so the stack will exist + after X509_CTX_cleanup() has been called. Modify pkcs12.c + to use this. + + Also make SSL_SESSION_print() print out the verify return + code. + + *Steve Henson* + + * Add manpage for the pkcs12 command. Also change the default + behaviour so MAC iteration counts are used unless the new + -nomaciter option is used. This improves file security and + only older versions of MSIE (4.0 for example) need it. + + *Steve Henson* + + * Honor the no-xxx Configure options when creating .DEF files. + + *Ulf Möller* + + * Add PKCS#10 attributes to field table: challengePassword, + unstructuredName and unstructuredAddress. These are taken from + draft PKCS#9 v2.0 but are compatible with v1.2 provided no + international characters are used. + + More changes to X509_ATTRIBUTE code: allow the setting of types + based on strings. Remove the 'loc' parameter when adding + attributes because these will be a SET OF encoding which is sorted + in ASN1 order. + + *Steve Henson* + + * Initial changes to the 'req' utility to allow request generation + automation. This will allow an application to just generate a template + file containing all the field values and have req construct the + request. + + Initial support for X509_ATTRIBUTE handling. Stacks of these are + used all over the place including certificate requests and PKCS#7 + structures. They are currently handled manually where necessary with + some primitive wrappers for PKCS#7. The new functions behave in a + manner analogous to the X509 extension functions: they allow + attributes to be looked up by NID and added. + + Later something similar to the X509V3 code would be desirable to + automatically handle the encoding, decoding and printing of the + more complex types. The string types like challengePassword can + be handled by the string table functions. + + Also modified the multi byte string table handling. Now there is + a 'global mask' which masks out certain types. The table itself + can use the flag STABLE_NO_MASK to ignore the mask setting: this + is useful when for example there is only one permissible type + (as in countryName) and using the mask might result in no valid + types at all. + + *Steve Henson* + + * Clean up 'Finished' handling, and add functions SSL_get_finished and + SSL_get_peer_finished to allow applications to obtain the latest + Finished messages sent to the peer or expected from the peer, + respectively. (SSL_get_peer_finished is usually the Finished message + actually received from the peer, otherwise the protocol will be aborted.) + + As the Finished message are message digests of the complete handshake + (with a total of 192 bits for TLS 1.0 and more for SSL 3.0), they can + be used for external authentication procedures when the authentication + provided by SSL/TLS is not desired or is not enough. + + *Bodo Moeller* + + * Enhanced support for Alpha Linux is added. Now ./config checks if + the host supports BWX extension and if Compaq C is present on the + $PATH. Just exploiting of the BWX extension results in 20-30% + performance kick for some algorithms, e.g. DES and RC4 to mention + a couple. Compaq C in turn generates ~20% faster code for MD5 and + SHA1. + + *Andy Polyakov* + + * Add support for MS "fast SGC". This is arguably a violation of the + SSL3/TLS protocol. Netscape SGC does two handshakes: the first with + weak crypto and after checking the certificate is SGC a second one + with strong crypto. MS SGC stops the first handshake after receiving + the server certificate message and sends a second client hello. Since + a server will typically do all the time consuming operations before + expecting any further messages from the client (server key exchange + is the most expensive) there is little difference between the two. + + To get OpenSSL to support MS SGC we have to permit a second client + hello message after we have sent server done. In addition we have to + reset the MAC if we do get this second client hello. + + *Steve Henson* + + * Add a function 'd2i_AutoPrivateKey()' this will automatically decide + if a DER encoded private key is RSA or DSA traditional format. Changed + d2i_PrivateKey_bio() to use it. This is only needed for the "traditional" + format DER encoded private key. Newer code should use PKCS#8 format which + has the key type encoded in the ASN1 structure. Added DER private key + support to pkcs8 application. + + *Steve Henson* + + * SSL 3/TLS 1 servers now don't request certificates when an anonymous + ciphersuites has been selected (as required by the SSL 3/TLS 1 + specifications). Exception: When SSL_VERIFY_FAIL_IF_NO_PEER_CERT + is set, we interpret this as a request to violate the specification + (the worst that can happen is a handshake failure, and 'correct' + behaviour would result in a handshake failure anyway). + + *Bodo Moeller* + + * In SSL_CTX_add_session, take into account that there might be multiple + SSL_SESSION structures with the same session ID (e.g. when two threads + concurrently obtain them from an external cache). + The internal cache can handle only one SSL_SESSION with a given ID, + so if there's a conflict, we now throw out the old one to achieve + consistency. + + *Bodo Moeller* + + * Add OIDs for idea and blowfish in CBC mode. This will allow both + to be used in PKCS#5 v2.0 and S/MIME. Also add checking to + some routines that use cipher OIDs: some ciphers do not have OIDs + defined and so they cannot be used for S/MIME and PKCS#5 v2.0 for + example. + + *Steve Henson* + + * Simplify the trust setting structure and code. Now we just have + two sequences of OIDs for trusted and rejected settings. These will + typically have values the same as the extended key usage extension + and any application specific purposes. + + The trust checking code now has a default behaviour: it will just + check for an object with the same NID as the passed id. Functions can + be provided to override either the default behaviour or the behaviour + for a given id. SSL client, server and email already have functions + in place for compatibility: they check the NID and also return "trusted" + if the certificate is self signed. + + *Steve Henson* + + * Add d2i,i2d bio/fp functions for PrivateKey: these convert the + traditional format into an EVP_PKEY structure. + + *Steve Henson* + + * Add a password callback function PEM_cb() which either prompts for + a password if usr_data is NULL or otherwise assumes it is a null + terminated password. Allow passwords to be passed on command line + environment or config files in a few more utilities. + + *Steve Henson* + + * Add a bunch of DER and PEM functions to handle PKCS#8 format private + keys. Add some short names for PKCS#8 PBE algorithms and allow them + to be specified on the command line for the pkcs8 and pkcs12 utilities. + Update documentation. + + *Steve Henson* + + * Support for ASN1 "NULL" type. This could be handled before by using + ASN1_TYPE but there wasn't any function that would try to read a NULL + and produce an error if it couldn't. For compatibility we also have + ASN1_NULL_new() and ASN1_NULL_free() functions but these are faked and + don't allocate anything because they don't need to. + + *Steve Henson* + + * Initial support for MacOS is now provided. Examine INSTALL.MacOS + for details. + + *Andy Polyakov, Roy Woods * + + * Rebuild of the memory allocation routines used by OpenSSL code and + possibly others as well. The purpose is to make an interface that + provide hooks so anyone can build a separate set of allocation and + deallocation routines to be used by OpenSSL, for example memory + pool implementations, or something else, which was previously hard + since Malloc(), Realloc() and Free() were defined as macros having + the values malloc, realloc and free, respectively (except for Win32 + compilations). The same is provided for memory debugging code. + OpenSSL already comes with functionality to find memory leaks, but + this gives people a chance to debug other memory problems. + + With these changes, a new set of functions and macros have appeared: + + CRYPTO_set_mem_debug_functions() [F] + CRYPTO_get_mem_debug_functions() [F] + CRYPTO_dbg_set_options() [F] + CRYPTO_dbg_get_options() [F] + CRYPTO_malloc_debug_init() [M] + + The memory debug functions are NULL by default, unless the library + is compiled with CRYPTO_MDEBUG or friends is defined. If someone + wants to debug memory anyway, CRYPTO_malloc_debug_init() (which + gives the standard debugging functions that come with OpenSSL) or + CRYPTO_set_mem_debug_functions() (tells OpenSSL to use functions + provided by the library user) must be used. When the standard + debugging functions are used, CRYPTO_dbg_set_options can be used to + request additional information: + CRYPTO_dbg_set_options(V_CYRPTO_MDEBUG_xxx) corresponds to setting + the CRYPTO_MDEBUG_xxx macro when compiling the library. + + Also, things like CRYPTO_set_mem_functions will always give the + expected result (the new set of functions is used for allocation + and deallocation) at all times, regardless of platform and compiler + options. + + To finish it up, some functions that were never use in any other + way than through macros have a new API and new semantic: + + CRYPTO_dbg_malloc() + CRYPTO_dbg_realloc() + CRYPTO_dbg_free() + + All macros of value have retained their old syntax. + + *Richard Levitte and Bodo Moeller* + + * Some S/MIME fixes. The OID for SMIMECapabilities was wrong, the + ordering of SMIMECapabilities wasn't in "strength order" and there + was a missing NULL in the AlgorithmIdentifier for the SHA1 signature + algorithm. + + *Steve Henson* + + * Some ASN1 types with illegal zero length encoding (INTEGER, + ENUMERATED and OBJECT IDENTIFIER) choked the ASN1 routines. + + *Frans Heymans , modified by Steve Henson* + + * Merge in my S/MIME library for OpenSSL. This provides a simple + S/MIME API on top of the PKCS#7 code, a MIME parser (with enough + functionality to handle multipart/signed properly) and a utility + called 'smime' to call all this stuff. This is based on code I + originally wrote for Celo who have kindly allowed it to be + included in OpenSSL. + + *Steve Henson* + + * Add variants des_set_key_checked and des_set_key_unchecked of + des_set_key (aka des_key_sched). Global variable des_check_key + decides which of these is called by des_set_key; this way + des_check_key behaves as it always did, but applications and + the library itself, which was buggy for des_check_key == 1, + have a cleaner way to pick the version they need. + + *Bodo Moeller* + + * New function PKCS12_newpass() which changes the password of a + PKCS12 structure. + + *Steve Henson* + + * Modify X509_TRUST and X509_PURPOSE so it also uses a static and + dynamic mix. In both cases the ids can be used as an index into the + table. Also modified the X509_TRUST_add() and X509_PURPOSE_add() + functions so they accept a list of the field values and the + application doesn't need to directly manipulate the X509_TRUST + structure. + + *Steve Henson* + + * Modify the ASN1_STRING_TABLE stuff so it also uses bsearch and doesn't + need initialising. + + *Steve Henson* + + * Modify the way the V3 extension code looks up extensions. This now + works in a similar way to the object code: we have some "standard" + extensions in a static table which is searched with OBJ_bsearch() + and the application can add dynamic ones if needed. The file + crypto/x509v3/ext_dat.h now has the info: this file needs to be + updated whenever a new extension is added to the core code and kept + in ext_nid order. There is a simple program 'tabtest.c' which checks + this. New extensions are not added too often so this file can readily + be maintained manually. + + There are two big advantages in doing things this way. The extensions + can be looked up immediately and no longer need to be "added" using + X509V3_add_standard_extensions(): this function now does nothing. + Side note: I get *lots* of email saying the extension code doesn't + work because people forget to call this function. + Also no dynamic allocation is done unless new extensions are added: + so if we don't add custom extensions there is no need to call + X509V3_EXT_cleanup(). + + *Steve Henson* + + * Modify enc utility's salting as follows: make salting the default. Add a + magic header, so unsalted files fail gracefully instead of just decrypting + to garbage. This is because not salting is a big security hole, so people + should be discouraged from doing it. + + *Ben Laurie* + + * Fixes and enhancements to the 'x509' utility. It allowed a message + digest to be passed on the command line but it only used this + parameter when signing a certificate. Modified so all relevant + operations are affected by the digest parameter including the + -fingerprint and -x509toreq options. Also -x509toreq choked if a + DSA key was used because it didn't fix the digest. + + *Steve Henson* + + * Initial certificate chain verify code. Currently tests the untrusted + certificates for consistency with the verify purpose (which is set + when the X509_STORE_CTX structure is set up) and checks the pathlength. + + There is a NO_CHAIN_VERIFY compilation option to keep the old behaviour: + this is because it will reject chains with invalid extensions whereas + every previous version of OpenSSL and SSLeay made no checks at all. + + Trust code: checks the root CA for the relevant trust settings. Trust + settings have an initial value consistent with the verify purpose: e.g. + if the verify purpose is for SSL client use it expects the CA to be + trusted for SSL client use. However the default value can be changed to + permit custom trust settings: one example of this would be to only trust + certificates from a specific "secure" set of CAs. + + Also added X509_STORE_CTX_new() and X509_STORE_CTX_free() functions + which should be used for version portability: especially since the + verify structure is likely to change more often now. + + SSL integration. Add purpose and trust to SSL_CTX and SSL and functions + to set them. If not set then assume SSL clients will verify SSL servers + and vice versa. + + Two new options to the verify program: -untrusted allows a set of + untrusted certificates to be passed in and -purpose which sets the + intended purpose of the certificate. If a purpose is set then the + new chain verify code is used to check extension consistency. + + *Steve Henson* + + * Support for the authority information access extension. + + *Steve Henson* + + * Modify RSA and DSA PEM read routines to transparently handle + PKCS#8 format private keys. New *_PUBKEY_* functions that handle + public keys in a format compatible with certificate + SubjectPublicKeyInfo structures. Unfortunately there were already + functions called *_PublicKey_* which used various odd formats so + these are retained for compatibility: however the DSA variants were + never in a public release so they have been deleted. Changed dsa/rsa + utilities to handle the new format: note no releases ever handled public + keys so we should be OK. + + The primary motivation for this change is to avoid the same fiasco + that dogs private keys: there are several incompatible private key + formats some of which are standard and some OpenSSL specific and + require various evil hacks to allow partial transparent handling and + even then it doesn't work with DER formats. Given the option anything + other than PKCS#8 should be dumped: but the other formats have to + stay in the name of compatibility. + + With public keys and the benefit of hindsight one standard format + is used which works with EVP_PKEY, RSA or DSA structures: though + it clearly returns an error if you try to read the wrong kind of key. + + Added a -pubkey option to the 'x509' utility to output the public key. + Also rename the `EVP_PKEY_get_*()` to `EVP_PKEY_rget_*()` + (renamed to `EVP_PKEY_get1_*()` in the OpenSSL 0.9.5 release) and add + `EVP_PKEY_rset_*()` functions (renamed to `EVP_PKEY_set1_*()`) + that do the same as the `EVP_PKEY_assign_*()` except they up the + reference count of the added key (they don't "swallow" the + supplied key). + + *Steve Henson* + + * Fixes to crypto/x509/by_file.c the code to read in certificates and + CRLs would fail if the file contained no certificates or no CRLs: + added a new function to read in both types and return the number + read: this means that if none are read it will be an error. The + DER versions of the certificate and CRL reader would always fail + because it isn't possible to mix certificates and CRLs in DER format + without choking one or the other routine. Changed this to just read + a certificate: this is the best we can do. Also modified the code + in `apps/verify.c` to take notice of return codes: it was previously + attempting to read in certificates from NULL pointers and ignoring + any errors: this is one reason why the cert and CRL reader seemed + to work. It doesn't check return codes from the default certificate + routines: these may well fail if the certificates aren't installed. + + *Steve Henson* + + * Code to support otherName option in GeneralName. + + *Steve Henson* + + * First update to verify code. Change the verify utility + so it warns if it is passed a self signed certificate: + for consistency with the normal behaviour. X509_verify + has been modified to it will now verify a self signed + certificate if *exactly* the same certificate appears + in the store: it was previously impossible to trust a + single self signed certificate. This means that: + openssl verify ss.pem + now gives a warning about a self signed certificate but + openssl verify -CAfile ss.pem ss.pem + is OK. + + *Steve Henson* + + * For servers, store verify_result in SSL_SESSION data structure + (and add it to external session representation). + This is needed when client certificate verifications fails, + but an application-provided verification callback (set by + SSL_CTX_set_cert_verify_callback) allows accepting the session + anyway (i.e. leaves x509_store_ctx->error != X509_V_OK + but returns 1): When the session is reused, we have to set + ssl->verify_result to the appropriate error code to avoid + security holes. + + *Bodo Moeller, problem pointed out by Lutz Jaenicke* + + * Fix a bug in the new PKCS#7 code: it didn't consider the + case in PKCS7_dataInit() where the signed PKCS7 structure + didn't contain any existing data because it was being created. + + *Po-Cheng Chen , slightly modified by Steve Henson* + + * Add a salt to the key derivation routines in enc.c. This + forms the first 8 bytes of the encrypted file. Also add a + -S option to allow a salt to be input on the command line. + + *Steve Henson* + + * New function X509_cmp(). Oddly enough there wasn't a function + to compare two certificates. We do this by working out the SHA1 + hash and comparing that. X509_cmp() will be needed by the trust + code. + + *Steve Henson* + + * SSL_get1_session() is like SSL_get_session(), but increments + the reference count in the SSL_SESSION returned. + + *Geoff Thorpe * + + * Fix for 'req': it was adding a null to request attributes. + Also change the X509_LOOKUP and X509_INFO code to handle + certificate auxiliary information. + + *Steve Henson* + + * Add support for 40 and 64 bit RC2 and RC4 algorithms: document + the 'enc' command. + + *Steve Henson* + + * Add the possibility to add extra information to the memory leak + detecting output, to form tracebacks, showing from where each + allocation was originated: CRYPTO_push_info("constant string") adds + the string plus current file name and line number to a per-thread + stack, CRYPTO_pop_info() does the obvious, CRYPTO_remove_all_info() + is like calling CYRPTO_pop_info() until the stack is empty. + Also updated memory leak detection code to be multi-thread-safe. + + *Richard Levitte* + + * Add options -text and -noout to pkcs7 utility and delete the + encryption options which never did anything. Update docs. + + *Steve Henson* + + * Add options to some of the utilities to allow the pass phrase + to be included on either the command line (not recommended on + OSes like Unix) or read from the environment. Update the + manpages and fix a few bugs. + + *Steve Henson* + + * Add a few manpages for some of the openssl commands. + + *Steve Henson* + + * Fix the -revoke option in ca. It was freeing up memory twice, + leaking and not finding already revoked certificates. + + *Steve Henson* + + * Extensive changes to support certificate auxiliary information. + This involves the use of X509_CERT_AUX structure and X509_AUX + functions. An X509_AUX function such as PEM_read_X509_AUX() + can still read in a certificate file in the usual way but it + will also read in any additional "auxiliary information". By + doing things this way a fair degree of compatibility can be + retained: existing certificates can have this information added + using the new 'x509' options. + + Current auxiliary information includes an "alias" and some trust + settings. The trust settings will ultimately be used in enhanced + certificate chain verification routines: currently a certificate + can only be trusted if it is self signed and then it is trusted + for all purposes. + + *Steve Henson* + + * Fix assembler for Alpha (tested only on DEC OSF not Linux or `*BSD`). + The problem was that one of the replacement routines had not been working + since SSLeay releases. For now the offending routine has been replaced + with non-optimised assembler. Even so, this now gives around 95% + performance improvement for 1024 bit RSA signs. + + *Mark Cox* + + * Hack to fix PKCS#7 decryption when used with some unorthodox RC2 + handling. Most clients have the effective key size in bits equal to + the key length in bits: so a 40 bit RC2 key uses a 40 bit (5 byte) key. + A few however don't do this and instead use the size of the decrypted key + to determine the RC2 key length and the AlgorithmIdentifier to determine + the effective key length. In this case the effective key length can still + be 40 bits but the key length can be 168 bits for example. This is fixed + by manually forcing an RC2 key into the EVP_PKEY structure because the + EVP code can't currently handle unusual RC2 key sizes: it always assumes + the key length and effective key length are equal. + + *Steve Henson* + + * Add a bunch of functions that should simplify the creation of + X509_NAME structures. Now you should be able to do: + X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, "Steve", -1, -1, 0); + and have it automatically work out the correct field type and fill in + the structures. The more adventurous can try: + X509_NAME_add_entry_by_txt(nm, field, MBSTRING_UTF8, str, -1, -1, 0); + and it will (hopefully) work out the correct multibyte encoding. + + *Steve Henson* + + * Change the 'req' utility to use the new field handling and multibyte + copy routines. Before the DN field creation was handled in an ad hoc + way in req, ca, and x509 which was rather broken and didn't support + BMPStrings or UTF8Strings. Since some software doesn't implement + BMPStrings or UTF8Strings yet, they can be enabled using the config file + using the dirstring_type option. See the new comment in the default + openssl.cnf for more info. + + *Steve Henson* + + * Make crypto/rand/md_rand.c more robust: + - Assure unique random numbers after fork(). + - Make sure that concurrent threads access the global counter and + md serializably so that we never lose entropy in them + or use exactly the same state in multiple threads. + Access to the large state is not always serializable because + the additional locking could be a performance killer, and + md should be large enough anyway. + + *Bodo Moeller* + + * New file `apps/app_rand.c` with commonly needed functionality + for handling the random seed file. + + Use the random seed file in some applications that previously did not: + ca, + dsaparam -genkey (which also ignored its '-rand' option), + s_client, + s_server, + x509 (when signing). + Except on systems with /dev/urandom, it is crucial to have a random + seed file at least for key creation, DSA signing, and for DH exchanges; + for RSA signatures we could do without one. + + gendh and gendsa (unlike genrsa) used to read only the first byte + of each file listed in the '-rand' option. The function as previously + found in genrsa is now in app_rand.c and is used by all programs + that support '-rand'. + + *Bodo Moeller* + + * In RAND_write_file, use mode 0600 for creating files; + don't just chmod when it may be too late. + + *Bodo Moeller* + + * Report an error from X509_STORE_load_locations + when X509_LOOKUP_load_file or X509_LOOKUP_add_dir failed. + + *Bill Perry* + + * New function ASN1_mbstring_copy() this copies a string in either + ASCII, Unicode, Universal (4 bytes per character) or UTF8 format + into an ASN1_STRING type. A mask of permissible types is passed + and it chooses the "minimal" type to use or an error if not type + is suitable. + + *Steve Henson* + + * Add function equivalents to the various macros in asn1.h. The old + macros are retained with an `M_` prefix. Code inside the library can + use the `M_` macros. External code (including the openssl utility) + should *NOT* in order to be "shared library friendly". + + *Steve Henson* + + * Add various functions that can check a certificate's extensions + to see if it usable for various purposes such as SSL client, + server or S/MIME and CAs of these types. This is currently + VERY EXPERIMENTAL but will ultimately be used for certificate chain + verification. Also added a -purpose flag to x509 utility to + print out all the purposes. + + *Steve Henson* + + * Add a CRYPTO_EX_DATA to X509 certificate structure and associated + functions. + + *Steve Henson* + + * New `X509V3_{X509,CRL,REVOKED}_get_d2i()` functions. These will search + for, obtain and decode and extension and obtain its critical flag. + This allows all the necessary extension code to be handled in a + single function call. + + *Steve Henson* + + * RC4 tune-up featuring 30-40% performance improvement on most RISC + platforms. See crypto/rc4/rc4_enc.c for further details. + + *Andy Polyakov* + + * New -noout option to asn1parse. This causes no output to be produced + its main use is when combined with -strparse and -out to extract data + from a file (which may not be in ASN.1 format). + + *Steve Henson* + + * Fix for pkcs12 program. It was hashing an invalid certificate pointer + when producing the local key id. + + *Richard Levitte * + + * New option -dhparam in s_server. This allows a DH parameter file to be + stated explicitly. If it is not stated then it tries the first server + certificate file. The previous behaviour hard coded the filename + "server.pem". + + *Steve Henson* + + * Add -pubin and -pubout options to the rsa and dsa commands. These allow + a public key to be input or output. For example: + openssl rsa -in key.pem -pubout -out pubkey.pem + Also added necessary DSA public key functions to handle this. + + *Steve Henson* + + * Fix so PKCS7_dataVerify() doesn't crash if no certificates are contained + in the message. This was handled by allowing + X509_find_by_issuer_and_serial() to tolerate a NULL passed to it. + + *Steve Henson, reported by Sampo Kellomaki * + + * Fix for bug in d2i_ASN1_bytes(): other ASN1 functions add an extra null + to the end of the strings whereas this didn't. This would cause problems + if strings read with d2i_ASN1_bytes() were later modified. + + *Steve Henson, reported by Arne Ansper * + + * Fix for base64 decode bug. When a base64 bio reads only one line of + data and it contains EOF it will end up returning an error. This is + caused by input 46 bytes long. The cause is due to the way base64 + BIOs find the start of base64 encoded data. They do this by trying a + trial decode on each line until they find one that works. When they + do a flag is set and it starts again knowing it can pass all the + data directly through the decoder. Unfortunately it doesn't reset + the context it uses. This means that if EOF is reached an attempt + is made to pass two EOFs through the context and this causes the + resulting error. This can also cause other problems as well. As is + usual with these problems it takes *ages* to find and the fix is + trivial: move one line. + + *Steve Henson, reported by ian@uns.ns.ac.yu (Ivan Nejgebauer)* + + * Ugly workaround to get s_client and s_server working under Windows. The + old code wouldn't work because it needed to select() on sockets and the + tty (for keypresses and to see if data could be written). Win32 only + supports select() on sockets so we select() with a 1s timeout on the + sockets and then see if any characters are waiting to be read, if none + are present then we retry, we also assume we can always write data to + the tty. This isn't nice because the code then blocks until we've + received a complete line of data and it is effectively polling the + keyboard at 1s intervals: however it's quite a bit better than not + working at all :-) A dedicated Windows application might handle this + with an event loop for example. + + *Steve Henson* + + * Enhance RSA_METHOD structure. Now there are two extra methods, rsa_sign + and rsa_verify. When the RSA_FLAGS_SIGN_VER option is set these functions + will be called when RSA_sign() and RSA_verify() are used. This is useful + if rsa_pub_dec() and rsa_priv_enc() equivalents are not available. + For this to work properly RSA_public_decrypt() and RSA_private_encrypt() + should *not* be used: RSA_sign() and RSA_verify() must be used instead. + This necessitated the support of an extra signature type NID_md5_sha1 + for SSL signatures and modifications to the SSL library to use it instead + of calling RSA_public_decrypt() and RSA_private_encrypt(). + + *Steve Henson* + + * Add new -verify -CAfile and -CApath options to the crl program, these + will lookup a CRL issuers certificate and verify the signature in a + similar way to the verify program. Tidy up the crl program so it + no longer accesses structures directly. Make the ASN1 CRL parsing a bit + less strict. It will now permit CRL extensions even if it is not + a V2 CRL: this will allow it to tolerate some broken CRLs. + + *Steve Henson* + + * Initialize all non-automatic variables each time one of the openssl + sub-programs is started (this is necessary as they may be started + multiple times from the "OpenSSL>" prompt). + + *Lennart Bang, Bodo Moeller* + + * Preliminary compilation option RSA_NULL which disables RSA crypto without + removing all other RSA functionality (this is what NO_RSA does). This + is so (for example) those in the US can disable those operations covered + by the RSA patent while allowing storage and parsing of RSA keys and RSA + key generation. + + *Steve Henson* + + * Non-copying interface to BIO pairs. + (still largely untested) + + *Bodo Moeller* + + * New function ASN1_tag2str() to convert an ASN1 tag to a descriptive + ASCII string. This was handled independently in various places before. + + *Steve Henson* + + * New functions UTF8_getc() and UTF8_putc() that parse and generate + UTF8 strings a character at a time. + + *Steve Henson* + + * Use client_version from client hello to select the protocol + (s23_srvr.c) and for RSA client key exchange verification + (s3_srvr.c), as required by the SSL 3.0/TLS 1.0 specifications. + + *Bodo Moeller* + + * Add various utility functions to handle SPKACs, these were previously + handled by poking round in the structure internals. Added new function + NETSCAPE_SPKI_print() to print out SPKAC and a new utility 'spkac' to + print, verify and generate SPKACs. Based on an original idea from + Massimiliano Pala but extensively modified. + + *Steve Henson* + + * RIPEMD160 is operational on all platforms and is back in 'make test'. + + *Andy Polyakov* + + * Allow the config file extension section to be overwritten on the + command line. Based on an original idea from Massimiliano Pala + . The new option is called -extensions + and can be applied to ca, req and x509. Also -reqexts to override + the request extensions in req and -crlexts to override the crl extensions + in ca. + + *Steve Henson* + + * Add new feature to the SPKAC handling in ca. Now you can include + the same field multiple times by preceding it by "XXXX." for example: + 1.OU="Unit name 1" + 2.OU="Unit name 2" + this is the same syntax as used in the req config file. + + *Steve Henson* + + * Allow certificate extensions to be added to certificate requests. These + are specified in a 'req_extensions' option of the req section of the + config file. They can be printed out with the -text option to req but + are otherwise ignored at present. + + *Steve Henson* + + * Fix a horrible bug in enc_read() in crypto/evp/bio_enc.c: if the first + data read consists of only the final block it would not decrypted because + EVP_CipherUpdate() would correctly report zero bytes had been decrypted. + A misplaced 'break' also meant the decrypted final block might not be + copied until the next read. + + *Steve Henson* + + * Initial support for DH_METHOD. Again based on RSA_METHOD. Also added + a few extra parameters to the DH structure: these will be useful if + for example we want the value of 'q' or implement X9.42 DH. + + *Steve Henson* + + * Initial support for DSA_METHOD. This is based on the RSA_METHOD and + provides hooks that allow the default DSA functions or functions on a + "per key" basis to be replaced. This allows hardware acceleration and + hardware key storage to be handled without major modification to the + library. Also added low-level modexp hooks and CRYPTO_EX structure and + associated functions. + + *Steve Henson* + + * Add a new flag to memory BIOs, BIO_FLAG_MEM_RDONLY. This marks the BIO + as "read only": it can't be written to and the buffer it points to will + not be freed. Reading from a read only BIO is much more efficient than + a normal memory BIO. This was added because there are several times when + an area of memory needs to be read from a BIO. The previous method was + to create a memory BIO and write the data to it, this results in two + copies of the data and an O(n^2) reading algorithm. There is a new + function BIO_new_mem_buf() which creates a read only memory BIO from + an area of memory. Also modified the PKCS#7 routines to use read only + memory BIOs. + + *Steve Henson* + + * Bugfix: ssl23_get_client_hello did not work properly when called in + state SSL23_ST_SR_CLNT_HELLO_B, i.e. when the first 7 bytes of + a SSLv2-compatible client hello for SSLv3 or TLSv1 could be read, + but a retry condition occurred while trying to read the rest. + + *Bodo Moeller* + + * The PKCS7_ENC_CONTENT_new() function was setting the content type as + NID_pkcs7_encrypted by default: this was wrong since this should almost + always be NID_pkcs7_data. Also modified the PKCS7_set_type() to handle + the encrypted data type: this is a more sensible place to put it and it + allows the PKCS#12 code to be tidied up that duplicated this + functionality. + + *Steve Henson* + + * Changed obj_dat.pl script so it takes its input and output files on + the command line. This should avoid shell escape redirection problems + under Win32. + + *Steve Henson* + + * Initial support for certificate extension requests, these are included + in things like Xenroll certificate requests. Included functions to allow + extensions to be obtained and added. + + *Steve Henson* + + * -crlf option to s_client and s_server for sending newlines as + CRLF (as required by many protocols). + + *Bodo Moeller* + +### Changes between 0.9.3a and 0.9.4 [09 Aug 1999] + + * Install libRSAglue.a when OpenSSL is built with RSAref. + + *Ralf S. Engelschall* + + * A few more `#ifndef NO_FP_API / #endif` pairs for consistency. + + *Andrija Antonijevic * + + * Fix -startdate and -enddate (which was missing) arguments to 'ca' + program. + + *Steve Henson* + + * New function DSA_dup_DH, which duplicates DSA parameters/keys as + DH parameters/keys (q is lost during that conversion, but the resulting + DH parameters contain its length). + + For 1024-bit p, DSA_generate_parameters followed by DSA_dup_DH is + much faster than DH_generate_parameters (which creates parameters + where `p = 2*q + 1`), and also the smaller q makes DH computations + much more efficient (160-bit exponentiation instead of 1024-bit + exponentiation); so this provides a convenient way to support DHE + ciphersuites in SSL/TLS servers (see ssl/ssltest.c). It is of + utter importance to use + SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); + or + SSL_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); + when such DH parameters are used, because otherwise small subgroup + attacks may become possible! + + *Bodo Moeller* + + * Avoid memory leak in i2d_DHparams. + + *Bodo Moeller* + + * Allow the -k option to be used more than once in the enc program: + this allows the same encrypted message to be read by multiple recipients. + + *Steve Henson* + + * New function OBJ_obj2txt(buf, buf_len, a, no_name), this converts + an ASN1_OBJECT to a text string. If the "no_name" parameter is set then + it will always use the numerical form of the OID, even if it has a short + or long name. + + *Steve Henson* + + * Added an extra RSA flag: RSA_FLAG_EXT_PKEY. Previously the rsa_mod_exp + method only got called if p,q,dmp1,dmq1,iqmp components were present, + otherwise bn_mod_exp was called. In the case of hardware keys for example + no private key components need be present and it might store extra data + in the RSA structure, which cannot be accessed from bn_mod_exp. + By setting RSA_FLAG_EXT_PKEY rsa_mod_exp will always be called for + private key operations. + + *Steve Henson* + + * Added support for SPARC Linux. + + *Andy Polyakov* + + * pem_password_cb function type incompatibly changed from + typedef int pem_password_cb(char *buf, int size, int rwflag); + to + ....(char *buf, int size, int rwflag, void *userdata); + so that applications can pass data to their callbacks: + The `PEM[_ASN1]_{read,write}...` functions and macros now take an + additional void * argument, which is just handed through whenever + the password callback is called. + + *Damien Miller ; tiny changes by Bodo Moeller* + + New function SSL_CTX_set_default_passwd_cb_userdata. + + Compatibility note: As many C implementations push function arguments + onto the stack in reverse order, the new library version is likely to + interoperate with programs that have been compiled with the old + pem_password_cb definition (PEM_whatever takes some data that + happens to be on the stack as its last argument, and the callback + just ignores this garbage); but there is no guarantee whatsoever that + this will work. + + * The -DPLATFORM="\"$(PLATFORM)\"" definition and the similar -DCFLAGS=... + (both in crypto/Makefile.ssl for use by crypto/cversion.c) caused + problems not only on Windows, but also on some Unix platforms. + To avoid problematic command lines, these definitions are now in an + auto-generated file crypto/buildinf.h (created by crypto/Makefile.ssl + for standard "make" builds, by util/mk1mf.pl for "mk1mf" builds). + + *Bodo Moeller* + + * MIPS III/IV assembler module is reimplemented. + + *Andy Polyakov* + + * More DES library cleanups: remove references to srand/rand and + delete an unused file. + + *Ulf Möller* + + * Add support for the free Netwide assembler (NASM) under Win32, + since not many people have MASM (ml) and it can be hard to obtain. + This is currently experimental but it seems to work OK and pass all + the tests. Check out INSTALL.W32 for info. + + *Steve Henson* + + * Fix memory leaks in s3_clnt.c: All non-anonymous SSL3/TLS1 connections + without temporary keys kept an extra copy of the server key, + and connections with temporary keys did not free everything in case + of an error. + + *Bodo Moeller* + + * New function RSA_check_key and new openssl rsa option -check + for verifying the consistency of RSA keys. + + *Ulf Moeller, Bodo Moeller* + + * Various changes to make Win32 compile work: + 1. Casts to avoid "loss of data" warnings in p5_crpt2.c + 2. Change unsigned int to int in b_dump.c to avoid "signed/unsigned + comparison" warnings. + 3. Add `sk__sort` to DEF file generator and do make update. + + *Steve Henson* + + * Add a debugging option to PKCS#5 v2 key generation function: when + you #define DEBUG_PKCS5V2 passwords, salts, iteration counts and + derived keys are printed to stderr. + + *Steve Henson* + + * Copy the flags in ASN1_STRING_dup(). + + *Roman E. Pavlov * + + * The x509 application mishandled signing requests containing DSA + keys when the signing key was also DSA and the parameters didn't match. + + It was supposed to omit the parameters when they matched the signing key: + the verifying software was then supposed to automatically use the CA's + parameters if they were absent from the end user certificate. + + Omitting parameters is no longer recommended. The test was also + the wrong way round! This was probably due to unusual behaviour in + EVP_cmp_parameters() which returns 1 if the parameters match. + This meant that parameters were omitted when they *didn't* match and + the certificate was useless. Certificates signed with 'ca' didn't have + this bug. + + *Steve Henson, reported by Doug Erickson * + + * Memory leak checking (-DCRYPTO_MDEBUG) had some problems. + The interface is as follows: + Applications can use + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) aka MemCheck_start(), + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) aka MemCheck_stop(); + "off" is now the default. + The library internally uses + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) aka MemCheck_off(), + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) aka MemCheck_on() + to disable memory-checking temporarily. + + Some inconsistent states that previously were possible (and were + even the default) are now avoided. + + -DCRYPTO_MDEBUG_TIME is new and additionally stores the current time + with each memory chunk allocated; this is occasionally more helpful + than just having a counter. + + -DCRYPTO_MDEBUG_THREAD is also new and adds the thread ID. + + -DCRYPTO_MDEBUG_ALL enables all of the above, plus any future + extensions. + + *Bodo Moeller* + + * Introduce "mode" for SSL structures (with defaults in SSL_CTX), + which largely parallels "options", but is for changing API behaviour, + whereas "options" are about protocol behaviour. + Initial "mode" flags are: + + SSL_MODE_ENABLE_PARTIAL_WRITE Allow SSL_write to report success when + a single record has been written. + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER Don't insist that SSL_write + retries use the same buffer location. + (But all of the contents must be + copied!) + + *Bodo Moeller* + + * Bugfix: SSL_set_options ignored its parameter, only SSL_CTX_set_options + worked. + + * Fix problems with no-hmac etc. + + *Ulf Möller, pointed out by Brian Wellington * + + * New functions RSA_get_default_method(), RSA_set_method() and + RSA_get_method(). These allows replacement of RSA_METHODs without having + to mess around with the internals of an RSA structure. + + *Steve Henson* + + * Fix memory leaks in DSA_do_sign and DSA_is_prime. + Also really enable memory leak checks in openssl.c and in some + test programs. + + *Chad C. Mulligan, Bodo Moeller* + + * Fix a bug in d2i_ASN1_INTEGER() and i2d_ASN1_INTEGER() which can mess + up the length of negative integers. This has now been simplified to just + store the length when it is first determined and use it later, rather + than trying to keep track of where data is copied and updating it to + point to the end. + *Steve Henson, reported by Brien Wheeler * + + * Add a new function PKCS7_signatureVerify. This allows the verification + of a PKCS#7 signature but with the signing certificate passed to the + function itself. This contrasts with PKCS7_dataVerify which assumes the + certificate is present in the PKCS#7 structure. This isn't always the + case: certificates can be omitted from a PKCS#7 structure and be + distributed by "out of band" means (such as a certificate database). + + *Steve Henson* + + * Complete the `PEM_*` macros with DECLARE_PEM versions to replace the + function prototypes in pem.h, also change util/mkdef.pl to add the + necessary function names. + + *Steve Henson* + + * mk1mf.pl (used by Windows builds) did not properly read the + options set by Configure in the top level Makefile, and Configure + was not even able to write more than one option correctly. + Fixed, now "no-idea no-rc5 -DCRYPTO_MDEBUG" etc. works as intended. + + *Bodo Moeller* + + * New functions CONF_load_bio() and CONF_load_fp() to allow a config + file to be loaded from a BIO or FILE pointer. The BIO version will + for example allow memory BIOs to contain config info. + + *Steve Henson* + + * New function "CRYPTO_num_locks" that returns CRYPTO_NUM_LOCKS. + Whoever hopes to achieve shared-library compatibility across versions + must use this, not the compile-time macro. + (Exercise 0.9.4: Which is the minimum library version required by + such programs?) + Note: All this applies only to multi-threaded programs, others don't + need locks. + + *Bodo Moeller* + + * Add missing case to s3_clnt.c state machine -- one of the new SSL tests + through a BIO pair triggered the default case, i.e. + SSLerr(...,SSL_R_UNKNOWN_STATE). + + *Bodo Moeller* + + * New "BIO pair" concept (crypto/bio/bss_bio.c) so that applications + can use the SSL library even if none of the specific BIOs is + appropriate. + + *Bodo Moeller* + + * Fix a bug in i2d_DSAPublicKey() which meant it returned the wrong value + for the encoded length. + + *Jeon KyoungHo * + + * Add initial documentation of the X509V3 functions. + + *Steve Henson* + + * Add a new pair of functions PEM_write_PKCS8PrivateKey() and + PEM_write_bio_PKCS8PrivateKey() that are equivalent to + PEM_write_PrivateKey() and PEM_write_bio_PrivateKey() but use the more + secure PKCS#8 private key format with a high iteration count. + + *Steve Henson* + + * Fix determination of Perl interpreter: A perl or perl5 + *directory* in $PATH was also accepted as the interpreter. + + *Ralf S. Engelschall* + + * Fix demos/sign/sign.c: well there wasn't anything strictly speaking + wrong with it but it was very old and did things like calling + PEM_ASN1_read() directly and used MD5 for the hash not to mention some + unusual formatting. + + *Steve Henson* + + * Fix demos/selfsign.c: it used obsolete and deleted functions, changed + to use the new extension code. + + *Steve Henson* + + * Implement the PEM_read/PEM_write functions in crypto/pem/pem_all.c + with macros. This should make it easier to change their form, add extra + arguments etc. Fix a few PEM prototypes which didn't have cipher as a + constant. + + *Steve Henson* + + * Add to configuration table a new entry that can specify an alternative + name for unistd.h (for pre-POSIX systems); we need this for NeXTstep, + according to Mark Crispin . + + *Bodo Moeller* + + * DES CBC did not update the IV. Weird. + + *Ben Laurie* +lse + des_cbc_encrypt does not update the IV, but des_ncbc_encrypt does. + Changing the behaviour of the former might break existing programs -- + where IV updating is needed, des_ncbc_encrypt can be used. +ndif + + * When bntest is run from "make test" it drives bc to check its + calculations, as well as internally checking them. If an internal check + fails, it needs to cause bc to give a non-zero result or make test carries + on without noticing the failure. Fixed. + + *Ben Laurie* + + * DES library cleanups. + + *Ulf Möller* + + * Add support for PKCS#5 v2.0 PBE algorithms. This will permit PKCS#8 to be + used with any cipher unlike PKCS#5 v1.5 which can at most handle 64 bit + ciphers. NOTE: although the key derivation function has been verified + against some published test vectors it has not been extensively tested + yet. Added a -v2 "cipher" option to pkcs8 application to allow the use + of v2.0. + + *Steve Henson* + + * Instead of "mkdir -p", which is not fully portable, use new + Perl script "util/mkdir-p.pl". + + *Bodo Moeller* + + * Rewrite the way password based encryption (PBE) is handled. It used to + assume that the ASN1 AlgorithmIdentifier parameter was a PBEParameter + structure. This was true for the PKCS#5 v1.5 and PKCS#12 PBE algorithms + but doesn't apply to PKCS#5 v2.0 where it can be something else. Now + the 'parameter' field of the AlgorithmIdentifier is passed to the + underlying key generation function so it must do its own ASN1 parsing. + This has also changed the EVP_PBE_CipherInit() function which now has a + 'parameter' argument instead of literal salt and iteration count values + and the function EVP_PBE_ALGOR_CipherInit() has been deleted. + + *Steve Henson* + + * Support for PKCS#5 v1.5 compatible password based encryption algorithms + and PKCS#8 functionality. New 'pkcs8' application linked to openssl. + Needed to change the PEM_STRING_EVP_PKEY value which was just "PRIVATE + KEY" because this clashed with PKCS#8 unencrypted string. Since this + value was just used as a "magic string" and not used directly its + value doesn't matter. + + *Steve Henson* + + * Introduce some semblance of const correctness to BN. Shame C doesn't + support mutable. + + *Ben Laurie* + + * "linux-sparc64" configuration (ultrapenguin). + + *Ray Miller * + "linux-sparc" configuration. + + *Christian Forster * + + * config now generates no-xxx options for missing ciphers. + + *Ulf Möller* + + * Support the EBCDIC character set (work in progress). + File ebcdic.c not yet included because it has a different license. + + *Martin Kraemer * + + * Support BS2000/OSD-POSIX. + + *Martin Kraemer * + + * Make callbacks for key generation use `void *` instead of `char *`. + + *Ben Laurie* + + * Make S/MIME samples compile (not yet tested). + + *Ben Laurie* + + * Additional typesafe stacks. + + *Ben Laurie* + + * New configuration variants "bsdi-elf-gcc" (BSD/OS 4.x). + + *Bodo Moeller* + +### Changes between 0.9.3 and 0.9.3a [29 May 1999] + + * New configuration variant "sco5-gcc". + + * Updated some demos. + + *Sean O Riordain, Wade Scholine* + + * Add missing BIO_free at exit of pkcs12 application. + + *Wu Zhigang* + + * Fix memory leak in conf.c. + + *Steve Henson* + + * Updates for Win32 to assembler version of MD5. + + *Steve Henson* + + * Set #! path to perl in `apps/der_chop` to where we found it + instead of using a fixed path. + + *Bodo Moeller* + + * SHA library changes for irix64-mips4-cc. + + *Andy Polyakov* + + * Improvements for VMS support. + + *Richard Levitte* + +### Changes between 0.9.2b and 0.9.3 [24 May 1999] + + * Bignum library bug fix. IRIX 6 passes "make test" now! + This also avoids the problems with SC4.2 and unpatched SC5. + + *Andy Polyakov * + + * New functions sk_num, sk_value and sk_set to replace the previous macros. + These are required because of the typesafe stack would otherwise break + existing code. If old code used a structure member which used to be STACK + and is now STACK_OF (for example cert in a PKCS7_SIGNED structure) with + sk_num or sk_value it would produce an error because the num, data members + are not present in STACK_OF. Now it just produces a warning. sk_set + replaces the old method of assigning a value to sk_value + (e.g. sk_value(x, i) = y) which the library used in a few cases. Any code + that does this will no longer work (and should use sk_set instead) but + this could be regarded as a "questionable" behaviour anyway. + + *Steve Henson* + + * Fix most of the other PKCS#7 bugs. The "experimental" code can now + correctly handle encrypted S/MIME data. + + *Steve Henson* + + * Change type of various DES function arguments from des_cblock + (which means, in function argument declarations, pointer to char) + to des_cblock * (meaning pointer to array with 8 char elements), + which allows the compiler to do more typechecking; it was like + that back in SSLeay, but with lots of ugly casts. + + Introduce new type const_des_cblock. + + *Bodo Moeller* + + * Reorganise the PKCS#7 library and get rid of some of the more obvious + problems: find RecipientInfo structure that matches recipient certificate + and initialise the ASN1 structures properly based on passed cipher. + + *Steve Henson* + + * Belatedly make the BN tests actually check the results. + + *Ben Laurie* + + * Fix the encoding and decoding of negative ASN1 INTEGERS and conversion + to and from BNs: it was completely broken. New compilation option + NEG_PUBKEY_BUG to allow for some broken certificates that encode public + key elements as negative integers. + + *Steve Henson* + + * Reorganize and speed up MD5. + + *Andy Polyakov * + + * VMS support. + + *Richard Levitte * + + * New option -out to asn1parse to allow the parsed structure to be + output to a file. This is most useful when combined with the -strparse + option to examine the output of things like OCTET STRINGS. + + *Steve Henson* + + * Make SSL library a little more fool-proof by not requiring any longer + that `SSL_set_{accept,connect}_state` be called before + `SSL_{accept,connect}` may be used (`SSL_set_..._state` is omitted + in many applications because usually everything *appeared* to work as + intended anyway -- now it really works as intended). + + *Bodo Moeller* + + * Move openssl.cnf out of lib/. + + *Ulf Möller* + + * Fix various things to let OpenSSL even pass "egcc -pipe -O2 -Wall + -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes + -Wmissing-declarations -Wnested-externs -Winline" with EGCS 1.1.2+ + + *Ralf S. Engelschall* + + * Various fixes to the EVP and PKCS#7 code. It may now be able to + handle PKCS#7 enveloped data properly. + + *Sebastian Akerman , modified by Steve* + + * Create a duplicate of the SSL_CTX's CERT in SSL_new instead of + copying pointers. The cert_st handling is changed by this in + various ways (and thus what used to be known as ctx->default_cert + is now called ctx->cert, since we don't resort to `s->ctx->[default_]cert` + any longer when s->cert does not give us what we need). + ssl_cert_instantiate becomes obsolete by this change. + As soon as we've got the new code right (possibly it already is?), + we have solved a couple of bugs of the earlier code where s->cert + was used as if it could not have been shared with other SSL structures. + + Note that using the SSL API in certain dirty ways now will result + in different behaviour than observed with earlier library versions: + Changing settings for an `SSL_CTX *ctx` after having done s = SSL_new(ctx) + does not influence s as it used to. + + In order to clean up things more thoroughly, inside SSL_SESSION + we don't use CERT any longer, but a new structure SESS_CERT + that holds per-session data (if available); currently, this is + the peer's certificate chain and, for clients, the server's certificate + and temporary key. CERT holds only those values that can have + meaningful defaults in an SSL_CTX. + + *Bodo Moeller* + + * New function X509V3_EXT_i2d() to create an X509_EXTENSION structure + from the internal representation. Various PKCS#7 fixes: remove some + evil casts and set the enc_dig_alg field properly based on the signing + key type. + + *Steve Henson* + + * Allow PKCS#12 password to be set from the command line or the + environment. Let 'ca' get its config file name from the environment + variables "OPENSSL_CONF" or "SSLEAY_CONF" (for consistency with 'req' + and 'x509'). + + *Steve Henson* + + * Allow certificate policies extension to use an IA5STRING for the + organization field. This is contrary to the PKIX definition but + VeriSign uses it and IE5 only recognises this form. Document 'x509' + extension option. + + *Steve Henson* + + * Add PEDANTIC compiler flag to allow compilation with gcc -pedantic, + without disallowing inline assembler and the like for non-pedantic builds. + + *Ben Laurie* + + * Support Borland C++ builder. + + *Janez Jere , modified by Ulf Möller* + + * Support Mingw32. + + *Ulf Möller* + + * SHA-1 cleanups and performance enhancements. + + *Andy Polyakov * + + * Sparc v8plus assembler for the bignum library. + + *Andy Polyakov * + + * Accept any -xxx and +xxx compiler options in Configure. + + *Ulf Möller* + + * Update HPUX configuration. + + *Anonymous* + + * Add missing `sk__unshift()` function to safestack.h + + *Ralf S. Engelschall* + + * New function SSL_CTX_use_certificate_chain_file that sets the + "extra_cert"s in addition to the certificate. (This makes sense + only for "PEM" format files, as chains as a whole are not + DER-encoded.) + + *Bodo Moeller* + + * Support verify_depth from the SSL API. + x509_vfy.c had what can be considered an off-by-one-error: + Its depth (which was not part of the external interface) + was actually counting the number of certificates in a chain; + now it really counts the depth. + + *Bodo Moeller* + + * Bugfix in crypto/x509/x509_cmp.c: The SSLerr macro was used + instead of X509err, which often resulted in confusing error + messages since the error codes are not globally unique + (e.g. an alleged error in ssl3_accept when a certificate + didn't match the private key). + + * New function SSL_CTX_set_session_id_context that allows to set a default + value (so that you don't need SSL_set_session_id_context for each + connection using the SSL_CTX). + + *Bodo Moeller* + + * OAEP decoding bug fix. + + *Ulf Möller* + + * Support INSTALL_PREFIX for package builders, as proposed by + David Harris. + + *Bodo Moeller* + + * New Configure options "threads" and "no-threads". For systems + where the proper compiler options are known (currently Solaris + and Linux), "threads" is the default. + + *Bodo Moeller* + + * New script util/mklink.pl as a faster substitute for util/mklink.sh. + + *Bodo Moeller* + + * Install various scripts to $(OPENSSLDIR)/misc, not to + $(INSTALLTOP)/bin -- they shouldn't clutter directories + such as /usr/local/bin. + + *Bodo Moeller* + + * "make linux-shared" to build shared libraries. + + *Niels Poppe * + + * New Configure option `no-` (rsa, idea, rc5, ...). + + *Ulf Möller* + + * Add the PKCS#12 API documentation to openssl.txt. Preliminary support for + extension adding in x509 utility. + + *Steve Henson* + + * Remove NOPROTO sections and error code comments. + + *Ulf Möller* + + * Partial rewrite of the DEF file generator to now parse the ANSI + prototypes. + + *Steve Henson* + + * New Configure options --prefix=DIR and --openssldir=DIR. + + *Ulf Möller* + + * Complete rewrite of the error code script(s). It is all now handled + by one script at the top level which handles error code gathering, + header rewriting and C source file generation. It should be much better + than the old method: it now uses a modified version of Ulf's parser to + read the ANSI prototypes in all header files (thus the old K&R definitions + aren't needed for error creation any more) and do a better job of + translating function codes into names. The old 'ASN1 error code embedded + in a comment' is no longer necessary and it doesn't use .err files which + have now been deleted. Also the error code call doesn't have to appear all + on one line (which resulted in some large lines...). + + *Steve Henson* + + * Change #include filenames from `` to ``. + + *Bodo Moeller* + + * Change behaviour of ssl2_read when facing length-0 packets: Don't return + 0 (which usually indicates a closed connection), but continue reading. + + *Bodo Moeller* + + * Fix some race conditions. + + *Bodo Moeller* + + * Add support for CRL distribution points extension. Add Certificate + Policies and CRL distribution points documentation. + + *Steve Henson* + + * Move the autogenerated header file parts to crypto/opensslconf.h. + + *Ulf Möller* + + * Fix new 56-bit DES export ciphersuites: they were using 7 bytes instead of + 8 of keying material. Merlin has also confirmed interop with this fix + between OpenSSL and Baltimore C/SSL 2.0 and J/SSL 2.0. + + *Merlin Hughes * + + * Fix lots of warnings. + + *Richard Levitte * + + * In add_cert_dir() in crypto/x509/by_dir.c, break out of the loop if + the directory spec didn't end with a LIST_SEPARATOR_CHAR. + + *Richard Levitte * + + * Fix problems with sizeof(long) == 8. + + *Andy Polyakov * + + * Change functions to ANSI C. + + *Ulf Möller* + + * Fix typos in error codes. + + *Martin Kraemer , Ulf Möller* + + * Remove defunct assembler files from Configure. + + *Ulf Möller* + + * SPARC v8 assembler BIGNUM implementation. + + *Andy Polyakov * + + * Support for Certificate Policies extension: both print and set. + Various additions to support the r2i method this uses. + + *Steve Henson* + + * A lot of constification, and fix a bug in X509_NAME_oneline() that could + return a const string when you are expecting an allocated buffer. + + *Ben Laurie* + + * Add support for ASN1 types UTF8String and VISIBLESTRING, also the CHOICE + types DirectoryString and DisplayText. + + *Steve Henson* + + * Add code to allow r2i extensions to access the configuration database, + add an LHASH database driver and add several ctx helper functions. + + *Steve Henson* + + * Fix an evil bug in bn_expand2() which caused various BN functions to + fail when they extended the size of a BIGNUM. + + *Steve Henson* + + * Various utility functions to handle SXNet extension. Modify mkdef.pl to + support typesafe stack. + + *Steve Henson* + + * Fix typo in SSL_[gs]et_options(). + + *Nils Frostberg * + + * Delete various functions and files that belonged to the (now obsolete) + old X509V3 handling code. + + *Steve Henson* + + * New Configure option "rsaref". + + *Ulf Möller* + + * Don't auto-generate pem.h. + + *Bodo Moeller* + + * Introduce type-safe ASN.1 SETs. + + *Ben Laurie* + + * Convert various additional casted stacks to type-safe STACK_OF() variants. + + *Ben Laurie, Ralf S. Engelschall, Steve Henson* + + * Introduce type-safe STACKs. This will almost certainly break lots of code + that links with OpenSSL (well at least cause lots of warnings), but fear + not: the conversion is trivial, and it eliminates loads of evil casts. A + few STACKed things have been converted already. Feel free to convert more. + In the fullness of time, I'll do away with the STACK type altogether. + + *Ben Laurie* + + * Add `openssl ca -revoke ` facility which revokes a certificate + specified in `` by updating the entry in the index.txt file. + This way one no longer has to edit the index.txt file manually for + revoking a certificate. The -revoke option does the gory details now. + + *Massimiliano Pala , Ralf S. Engelschall* + + * Fix `openssl crl -noout -text` combination where `-noout` killed the + `-text` option at all and this way the `-noout -text` combination was + inconsistent in `openssl crl` with the friends in `openssl x509|rsa|dsa`. + + *Ralf S. Engelschall* + + * Make sure a corresponding plain text error message exists for the + X509_V_ERR_CERT_REVOKED/23 error number which can occur when a + verify callback function determined that a certificate was revoked. + + *Ralf S. Engelschall* + + * Bugfix: In test/testenc, don't test `openssl ` for + ciphers that were excluded, e.g. by -DNO_IDEA. Also, test + all available ciphers including rc5, which was forgotten until now. + In order to let the testing shell script know which algorithms + are available, a new (up to now undocumented) command + `openssl list-cipher-commands` is used. + + *Bodo Moeller* + + * Bugfix: s_client occasionally would sleep in select() when + it should have checked SSL_pending() first. + + *Bodo Moeller* + + * New functions DSA_do_sign and DSA_do_verify to provide access to + the raw DSA values prior to ASN.1 encoding. + + *Ulf Möller* + + * Tweaks to Configure + + *Niels Poppe * + + * Add support for PKCS#5 v2.0 ASN1 PBES2 structures. No other support, + yet... + + *Steve Henson* + + * New variables $(RANLIB) and $(PERL) in the Makefiles. + + *Ulf Möller* + + * New config option to avoid instructions that are illegal on the 80386. + The default code is faster, but requires at least a 486. + + *Ulf Möller* + + * Got rid of old SSL2_CLIENT_VERSION (inconsistently used) and + SSL2_SERVER_VERSION (not used at all) macros, which are now the + same as SSL2_VERSION anyway. + + *Bodo Moeller* + + * New "-showcerts" option for s_client. + + *Bodo Moeller* + + * Still more PKCS#12 integration. Add pkcs12 application to openssl + application. Various cleanups and fixes. + + *Steve Henson* + + * More PKCS#12 integration. Add new pkcs12 directory with Makefile.ssl and + modify error routines to work internally. Add error codes and PBE init + to library startup routines. + + *Steve Henson* + + * Further PKCS#12 integration. Added password based encryption, PKCS#8 and + packing functions to asn1 and evp. Changed function names and error + codes along the way. + + *Steve Henson* + + * PKCS12 integration: and so it begins... First of several patches to + slowly integrate PKCS#12 functionality into OpenSSL. Add PKCS#12 + objects to objects.h + + *Steve Henson* + + * Add a new 'indent' option to some X509V3 extension code. Initial ASN1 + and display support for Thawte strong extranet extension. + + *Steve Henson* + + * Add LinuxPPC support. + + *Jeff Dubrule * + + * Get rid of redundant BN file bn_mulw.c, and rename bn_div64 to + bn_div_words in alpha.s. + + *Hannes Reinecke and Ben Laurie* + + * Make sure the RSA OAEP test is skipped under -DRSAref because + OAEP isn't supported when OpenSSL is built with RSAref. + + *Ulf Moeller * + + * Move definitions of IS_SET/IS_SEQUENCE inside crypto/asn1/asn1.h + so they no longer are missing under -DNOPROTO. + + *Soren S. Jorvang * + +### Changes between 0.9.1c and 0.9.2b [22 Mar 1999] + + * Make SSL_get_peer_cert_chain() work in servers. Unfortunately, it still + doesn't work when the session is reused. Coming soon! + + *Ben Laurie* + + * Fix a security hole, that allows sessions to be reused in the wrong + context thus bypassing client cert protection! All software that uses + client certs and session caches in multiple contexts NEEDS PATCHING to + allow session reuse! A fuller solution is in the works. + + *Ben Laurie, problem pointed out by Holger Reif, Bodo Moeller (and ???)* + + * Some more source tree cleanups (removed obsolete files + crypto/bf/asm/bf586.pl, test/test.txt and crypto/sha/asm/f.s; changed + permission on "config" script to be executable) and a fix for the INSTALL + document. + + *Ulf Moeller * + + * Remove some legacy and erroneous uses of malloc, free instead of + Malloc, Free. + + *Lennart Bang , with minor changes by Steve* + + * Make rsa_oaep_test return non-zero on error. + + *Ulf Moeller * + + * Add support for native Solaris shared libraries. Configure + solaris-sparc-sc4-pic, make, then run shlib/solaris-sc4.sh. It'd be nice + if someone would make that last step automatic. + + *Matthias Loepfe * + + * ctx_size was not built with the right compiler during "make links". Fixed. + + *Ben Laurie* + + * Change the meaning of 'ALL' in the cipher list. It now means "everything + except NULL ciphers". This means the default cipher list will no longer + enable NULL ciphers. They need to be specifically enabled e.g. with + the string "DEFAULT:eNULL". + + *Steve Henson* + + * Fix to RSA private encryption routines: if p < q then it would + occasionally produce an invalid result. This will only happen with + externally generated keys because OpenSSL (and SSLeay) ensure p > q. + + *Steve Henson* + + * Be less restrictive and allow also `perl util/perlpath.pl + /path/to/bin/perl` in addition to `perl util/perlpath.pl /path/to/bin`, + because this way one can also use an interpreter named `perl5` (which is + usually the name of Perl 5.xxx on platforms where an Perl 4.x is still + installed as `perl`). + + *Matthias Loepfe * + + * Let util/clean-depend.pl work also with older Perl 5.00x versions. + + *Matthias Loepfe * + + * Fix Makefile.org so CC,CFLAG etc are passed to 'make links' add + advapi32.lib to Win32 build and change the pem test comparison + to fc.exe (thanks to Ulrich Kroener for the + suggestion). Fix misplaced ASNI prototypes and declarations in evp.h + and crypto/des/ede_cbcm_enc.c. + + *Steve Henson* + + * DES quad checksum was broken on big-endian architectures. Fixed. + + *Ben Laurie* + + * Comment out two functions in bio.h that aren't implemented. Fix up the + Win32 test batch file so it (might) work again. The Win32 test batch file + is horrible: I feel ill.... + + *Steve Henson* + + * Move various #ifdefs around so NO_SYSLOG, NO_DIRENT etc are now selected + in e_os.h. Audit of header files to check ANSI and non ANSI + sections: 10 functions were absent from non ANSI section and not exported + from Windows DLLs. Fixed up libeay.num for new functions. + + *Steve Henson* + + * Make `openssl version` output lines consistent. + + *Ralf S. Engelschall* + + * Fix Win32 symbol export lists for BIO functions: Added + BIO_get_ex_new_index, BIO_get_ex_num, BIO_get_ex_data and BIO_set_ex_data + to ms/libeay{16,32}.def. + + *Ralf S. Engelschall* + + * Second round of fixing the OpenSSL perl/ stuff. It now at least compiled + fine under Unix and passes some trivial tests I've now added. But the + whole stuff is horribly incomplete, so a README.1ST with a disclaimer was + added to make sure no one expects that this stuff really works in the + OpenSSL 0.9.2 release. Additionally I've started to clean the XS sources + up and fixed a few little bugs and inconsistencies in OpenSSL.{pm,xs} and + openssl_bio.xs. + + *Ralf S. Engelschall* + + * Fix the generation of two part addresses in perl. + + *Kenji Miyake , integrated by Ben Laurie* + + * Add config entry for Linux on MIPS. + + *John Tobey * + + * Make links whenever Configure is run, unless we are on Windoze. + + *Ben Laurie* + + * Permit extensions to be added to CRLs using crl_section in openssl.cnf. + Currently only issuerAltName and AuthorityKeyIdentifier make any sense + in CRLs. + + *Steve Henson* + + * Add a useful kludge to allow package maintainers to specify compiler and + other platforms details on the command line without having to patch the + Configure script every time: One now can use + `perl Configure :
`, + i.e. platform ids are allowed to have details appended + to them (separated by colons). This is treated as there would be a static + pre-configured entry in Configure's %table under key `` with value + `
` and `perl Configure ` is called. So, when you want to + perform a quick test-compile under FreeBSD 3.1 with pgcc and without + assembler stuff you can use `perl Configure "FreeBSD-elf:pgcc:-O6:::"` + now, which overrides the FreeBSD-elf entry on-the-fly. + + *Ralf S. Engelschall* + + * Disable new TLS1 ciphersuites by default: they aren't official yet. + + *Ben Laurie* + + * Allow DSO flags like -fpic, -fPIC, -KPIC etc. to be specified + on the `perl Configure ...` command line. This way one can compile + OpenSSL libraries with Position Independent Code (PIC) which is needed + for linking it into DSOs. + + *Ralf S. Engelschall* + + * Remarkably, export ciphers were totally broken and no-one had noticed! + Fixed. + + *Ben Laurie* + + * Cleaned up the LICENSE document: The official contact for any license + questions now is the OpenSSL core team under openssl-core@openssl.org. + And add a paragraph about the dual-license situation to make sure people + recognize that _BOTH_ the OpenSSL license _AND_ the SSLeay license apply + to the OpenSSL toolkit. + + *Ralf S. Engelschall* + + * General source tree makefile cleanups: Made `making xxx in yyy...` + display consistent in the source tree and replaced `/bin/rm` by `rm`. + Additionally cleaned up the `make links` target: Remove unnecessary + semicolons, subsequent redundant removes, inline point.sh into mklink.sh + to speed processing and no longer clutter the display with confusing + stuff. Instead only the actually done links are displayed. + + *Ralf S. Engelschall* + + * Permit null encryption ciphersuites, used for authentication only. It used + to be necessary to set the preprocessor define SSL_ALLOW_ENULL to do this. + It is now necessary to set SSL_FORBID_ENULL to prevent the use of null + encryption. + + *Ben Laurie* + + * Add a bunch of fixes to the PKCS#7 stuff. It used to sometimes reorder + signed attributes when verifying signatures (this would break them), + the detached data encoding was wrong and public keys obtained using + X509_get_pubkey() weren't freed. + + *Steve Henson* + + * Add text documentation for the BUFFER functions. Also added a work around + to a Win95 console bug. This was triggered by the password read stuff: the + last character typed gets carried over to the next fread(). If you were + generating a new cert request using 'req' for example then the last + character of the passphrase would be CR which would then enter the first + field as blank. + + *Steve Henson* + + * Added the new 'Includes OpenSSL Cryptography Software' button as + doc/openssl_button.{gif,html} which is similar in style to the old SSLeay + button and can be used by applications based on OpenSSL to show the + relationship to the OpenSSL project. + + *Ralf S. Engelschall* + + * Remove confusing variables in function signatures in files + ssl/ssl_lib.c and ssl/ssl.h. + + *Lennart Bong * + + * Don't install bss_file.c under PREFIX/include/ + + *Lennart Bong * + + * Get the Win32 compile working again. Modify mkdef.pl so it can handle + functions that return function pointers and has support for NT specific + stuff. Fix mk1mf.pl and VC-32.pl to support NT differences also. Various + #ifdef WIN32 and WINNTs sprinkled about the place and some changes from + unsigned to signed types: this was killing the Win32 compile. + + *Steve Henson* + + * Add new certificate file to stack functions, + SSL_add_dir_cert_subjects_to_stack() and + SSL_add_file_cert_subjects_to_stack(). These largely supplant + SSL_load_client_CA_file(), and can be used to add multiple certs easily + to a stack (usually this is then handed to SSL_CTX_set_client_CA_list()). + This means that Apache-SSL and similar packages don't have to mess around + to add as many CAs as they want to the preferred list. + + *Ben Laurie* + + * Experiment with doxygen documentation. Currently only partially applied to + ssl/ssl_lib.c. + See , and run doxygen with + openssl.doxy as the configuration file. + + *Ben Laurie* + + * Get rid of remaining C++-style comments which strict C compilers hate. + + *Ralf S. Engelschall, pointed out by Carlos Amengual* + + * Changed BN_RECURSION in bn_mont.c to BN_RECURSION_MONT so it is not + compiled in by default: it has problems with large keys. + + *Steve Henson* + + * Add a bunch of SSL_xxx() functions for configuring the temporary RSA and + DH private keys and/or callback functions which directly correspond to + their SSL_CTX_xxx() counterparts but work on a per-connection basis. This + is needed for applications which have to configure certificates on a + per-connection basis (e.g. Apache+mod_ssl) instead of a per-context basis + (e.g. s_server). + For the RSA certificate situation is makes no difference, but + for the DSA certificate situation this fixes the "no shared cipher" + problem where the OpenSSL cipher selection procedure failed because the + temporary keys were not overtaken from the context and the API provided + no way to reconfigure them. + The new functions now let applications reconfigure the stuff and they + are in detail: SSL_need_tmp_RSA, SSL_set_tmp_rsa, SSL_set_tmp_dh, + SSL_set_tmp_rsa_callback and SSL_set_tmp_dh_callback. Additionally a new + non-public-API function ssl_cert_instantiate() is used as a helper + function and also to reduce code redundancy inside ssl_rsa.c. + + *Ralf S. Engelschall* + + * Move s_server -dcert and -dkey options out of the undocumented feature + area because they are useful for the DSA situation and should be + recognized by the users. + + *Ralf S. Engelschall* + + * Fix the cipher decision scheme for export ciphers: the export bits are + *not* within SSL_MKEY_MASK or SSL_AUTH_MASK, they are within + SSL_EXP_MASK. So, the original variable has to be used instead of the + already masked variable. + + *Richard Levitte * + + * Fix `port` variable from `int` to `unsigned int` in crypto/bio/b_sock.c + + *Richard Levitte * + + * Change type of another md_len variable in pk7_doit.c:PKCS7_dataFinal() + from `int` to `unsigned int` because it is a length and initialized by + EVP_DigestFinal() which expects an `unsigned int *`. + + *Richard Levitte * + + * Don't hard-code path to Perl interpreter on shebang line of Configure + script. Instead use the usual Shell->Perl transition trick. + + *Ralf S. Engelschall* + + * Make `openssl x509 -noout -modulus`' functional also for DSA certificates + (in addition to RSA certificates) to match the behaviour of `openssl dsa + -noout -modulus` as it's already the case for `openssl rsa -noout + -modulus`. For RSA the -modulus is the real "modulus" while for DSA + currently the public key is printed (a decision which was already done by + `openssl dsa -modulus` in the past) which serves a similar purpose. + Additionally the NO_RSA no longer completely removes the whole -modulus + option; it now only avoids using the RSA stuff. Same applies to NO_DSA + now, too. + + *Ralf S. Engelschall* + + * Add Arne Ansper's reliable BIO - this is an encrypted, block-digested + BIO. See the source (crypto/evp/bio_ok.c) for more info. + + *Arne Ansper * + + * Dump the old yucky req code that tried (and failed) to allow raw OIDs + to be added. Now both 'req' and 'ca' can use new objects defined in the + config file. + + *Steve Henson* + + * Add cool BIO that does syslog (or event log on NT). + + *Arne Ansper , integrated by Ben Laurie* + + * Add support for new TLS ciphersuites, TLS_RSA_EXPORT56_WITH_RC4_56_MD5, + TLS_RSA_EXPORT56_WITH_RC2_CBC_56_MD5 and + TLS_RSA_EXPORT56_WITH_DES_CBC_SHA, as specified in "56-bit Export Cipher + Suites For TLS", draft-ietf-tls-56-bit-ciphersuites-00.txt. + + *Ben Laurie* + + * Add preliminary config info for new extension code. + + *Steve Henson* + + * Make RSA_NO_PADDING really use no padding. + + *Ulf Moeller * + + * Generate errors when private/public key check is done. + + *Ben Laurie* + + * Overhaul for 'crl' utility. New function X509_CRL_print. Partial support + for some CRL extensions and new objects added. + + *Steve Henson* + + * Really fix the ASN1 IMPLICIT bug this time... Partial support for private + key usage extension and fuller support for authority key id. + + *Steve Henson* + + * Add OAEP encryption for the OpenSSL crypto library. OAEP is the improved + padding method for RSA, which is recommended for new applications in PKCS + #1 v2.0 (RFC 2437, October 1998). + OAEP (Optimal Asymmetric Encryption Padding) has better theoretical + foundations than the ad-hoc padding used in PKCS #1 v1.5. It is secure + against Bleichbacher's attack on RSA. + *Ulf Moeller , reformatted, corrected and integrated by + Ben Laurie* + + * Updates to the new SSL compression code + + *Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)* + + * Fix so that the version number in the master secret, when passed + via RSA, checks that if TLS was proposed, but we roll back to SSLv3 + (because the server will not accept higher), that the version number + is 0x03,0x01, not 0x03,0x00 + + *Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)* + + * Run extensive memory leak checks on SSL commands. Fixed *lots* of memory + leaks in `ssl/` relating to new `X509_get_pubkey()` behaviour. Also fixes + in `apps/` and an unrelated leak in `crypto/dsa/dsa_vrf.c`. + + *Steve Henson* + + * Support for RAW extensions where an arbitrary extension can be + created by including its DER encoding. See `apps/openssl.cnf` for + an example. + + *Steve Henson* + + * Make sure latest Perl versions don't interpret some generated C array + code as Perl array code in the crypto/err/err_genc.pl script. + + *Lars Weber <3weber@informatik.uni-hamburg.de>* + + * Modify ms/do_ms.bat to not generate assembly language makefiles since + not many people have the assembler. Various Win32 compilation fixes and + update to the INSTALL.W32 file with (hopefully) more accurate Win32 + build instructions. + + *Steve Henson* + + * Modify configure script 'Configure' to automatically create crypto/date.h + file under Win32 and also build pem.h from pem.org. New script + util/mkfiles.pl to create the MINFO file on environments that can't do a + 'make files': perl util/mkfiles.pl >MINFO should work. + + *Steve Henson* + + * Major rework of DES function declarations, in the pursuit of correctness + and purity. As a result, many evil casts evaporated, and some weirdness, + too. You may find this causes warnings in your code. Zapping your evil + casts will probably fix them. Mostly. + + *Ben Laurie* + + * Fix for a typo in asn1.h. Bug fix to object creation script + obj_dat.pl. It considered a zero in an object definition to mean + "end of object": none of the objects in objects.h have any zeros + so it wasn't spotted. + + *Steve Henson, reported by Erwann ABALEA * + + * Add support for Triple DES Cipher Block Chaining with Output Feedback + Masking (CBCM). In the absence of test vectors, the best I have been able + to do is check that the decrypt undoes the encrypt, so far. Send me test + vectors if you have them. + + *Ben Laurie* + + * Correct calculation of key length for export ciphers (too much space was + allocated for null ciphers). This has not been tested! + + *Ben Laurie* + + * Modifications to the mkdef.pl for Win32 DEF file creation. The usage + message is now correct (it understands "crypto" and "ssl" on its + command line). There is also now an "update" option. This will update + the util/ssleay.num and util/libeay.num files with any new functions. + If you do a: + perl util/mkdef.pl crypto ssl update + it will update them. + + *Steve Henson* + + * Overhauled the Perl interface: + - ported BN stuff to OpenSSL's different BN library + - made the perl/ source tree CVS-aware + - renamed the package from SSLeay to OpenSSL (the files still contain + their history because I've copied them in the repository) + - removed obsolete files (the test scripts will be replaced + by better Test::Harness variants in the future) + + *Ralf S. Engelschall* + + * First cut for a very conservative source tree cleanup: + 1. merge various obsolete readme texts into doc/ssleay.txt + where we collect the old documents and readme texts. + 2. remove the first part of files where I'm already sure that we no + longer need them because of three reasons: either they are just temporary + files which were left by Eric or they are preserved original files where + I've verified that the diff is also available in the CVS via "cvs diff + -rSSLeay_0_8_1b" or they were renamed (as it was definitely the case for + the crypto/md/ stuff). + + *Ralf S. Engelschall* + + * More extension code. Incomplete support for subject and issuer alt + name, issuer and authority key id. Change the i2v function parameters + and add an extra 'crl' parameter in the X509V3_CTX structure: guess + what that's for :-) Fix to ASN1 macro which messed up + IMPLICIT tag and add f_enum.c which adds a2i, i2a for ENUMERATED. + + *Steve Henson* + + * Preliminary support for ENUMERATED type. This is largely copied from the + INTEGER code. + + *Steve Henson* + + * Add new function, EVP_MD_CTX_copy() to replace frequent use of memcpy. + + *Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)* + + * Make sure `make rehash` target really finds the `openssl` program. + + *Ralf S. Engelschall, Matthias Loepfe * + + * Squeeze another 7% of speed out of MD5 assembler, at least on a P2. I'd + like to hear about it if this slows down other processors. + + *Ben Laurie* + + * Add CygWin32 platform information to Configure script. + + *Alan Batie * + + * Fixed ms/32all.bat script: `no_asm` -> `no-asm` + + *Rainer W. Gerling * + + * New program nseq to manipulate netscape certificate sequences + + *Steve Henson* + + * Modify crl2pkcs7 so it supports multiple -certfile arguments. Fix a + few typos. + + *Steve Henson* + + * Fixes to BN code. Previously the default was to define BN_RECURSION + but the BN code had some problems that would cause failures when + doing certificate verification and some other functions. + + *Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)* + + * Add ASN1 and PEM code to support netscape certificate sequences. + + *Steve Henson* + + * Add ASN1 and PEM code to support netscape certificate sequences. + + *Steve Henson* + + * Add several PKIX and private extended key usage OIDs. + + *Steve Henson* + + * Modify the 'ca' program to handle the new extension code. Modify + openssl.cnf for new extension format, add comments. + + *Steve Henson* + + * More X509 V3 changes. Fix typo in v3_bitstr.c. Add support to 'req' + and add a sample to openssl.cnf so req -x509 now adds appropriate + CA extensions. + + *Steve Henson* + + * Continued X509 V3 changes. Add to other makefiles, integrate with the + error code, add initial support to X509_print() and x509 application. + + *Steve Henson* + + * Takes a deep breath and start adding X509 V3 extension support code. Add + files in crypto/x509v3. Move original stuff to crypto/x509v3/old. All this + stuff is currently isolated and isn't even compiled yet. + + *Steve Henson* + + * Continuing patches for GeneralizedTime. Fix up certificate and CRL + ASN1 to use ASN1_TIME and modify print routines to use ASN1_TIME_print. + Removed the versions check from X509 routines when loading extensions: + this allows certain broken certificates that don't set the version + properly to be processed. + + *Steve Henson* + + * Deal with irritating shit to do with dependencies, in YAAHW (Yet Another + Ad Hoc Way) - Makefile.ssls now all contain local dependencies, which + can still be regenerated with "make depend". + + *Ben Laurie* + + * Spelling mistake in C version of CAST-128. + + *Ben Laurie, reported by Jeremy Hylton * + + * Changes to the error generation code. The perl script err-code.pl + now reads in the old error codes and retains the old numbers, only + adding new ones if necessary. It also only changes the .err files if new + codes are added. The makefiles have been modified to only insert errors + when needed (to avoid needlessly modifying header files). This is done + by only inserting errors if the .err file is newer than the auto generated + C file. To rebuild all the error codes from scratch (the old behaviour) + either modify crypto/Makefile.ssl to pass the -regen flag to err_code.pl + or delete all the .err files. + + *Steve Henson* + + * CAST-128 was incorrectly implemented for short keys. The C version has + been fixed, but is untested. The assembler versions are also fixed, but + new assembler HAS NOT BEEN GENERATED FOR WIN32 - the Makefile needs fixing + to regenerate it if needed. + *Ben Laurie, reported (with fix for C version) by Jun-ichiro itojun + Hagino * + + * File was opened incorrectly in randfile.c. + + *Ulf Möller * + + * Beginning of support for GeneralizedTime. d2i, i2d, check and print + functions. Also ASN1_TIME suite which is a CHOICE of UTCTime or + GeneralizedTime. ASN1_TIME is the proper type used in certificates et + al: it's just almost always a UTCTime. Note this patch adds new error + codes so do a "make errors" if there are problems. + + *Steve Henson* + + * Correct Linux 1 recognition in config. + + *Ulf Möller * + + * Remove pointless MD5 hash when using DSA keys in ca. + + *Anonymous * + + * Generate an error if given an empty string as a cert directory. Also + generate an error if handed NULL (previously returned 0 to indicate an + error, but didn't set one). + + *Ben Laurie, reported by Anonymous * + + * Add prototypes to SSL methods. Make SSL_write's buffer const, at last. + + *Ben Laurie* + + * Fix the dummy function BN_ref_mod_exp() in rsaref.c to have the correct + parameters. This was causing a warning which killed off the Win32 compile. + + *Steve Henson* + + * Remove C++ style comments from crypto/bn/bn_local.h. + + *Neil Costigan * + + * The function OBJ_txt2nid was broken. It was supposed to return a nid + based on a text string, looking up short and long names and finally + "dot" format. The "dot" format stuff didn't work. Added new function + OBJ_txt2obj to do the same but return an ASN1_OBJECT and rewrote + OBJ_txt2nid to use it. OBJ_txt2obj can also return objects even if the + OID is not part of the table. + + *Steve Henson* + + * Add prototypes to X509 lookup/verify methods, fixing a bug in + X509_LOOKUP_by_alias(). + + *Ben Laurie* + + * Sort openssl functions by name. + + *Ben Laurie* + + * Get the `gendsa` command working and add it to the `list` command. Remove + encryption from sample DSA keys (in case anyone is interested the password + was "1234"). + + *Steve Henson* + + * Make *all* `*_free` functions accept a NULL pointer. + + *Frans Heymans * + + * If a DH key is generated in s3_srvr.c, don't blow it by trying to use + NULL pointers. + + *Anonymous * + + * s_server should send the CAfile as acceptable CAs, not its own cert. + + *Bodo Moeller <3moeller@informatik.uni-hamburg.de>* + + * Don't blow it for numeric `-newkey` arguments to `apps/req`. + + *Bodo Moeller <3moeller@informatik.uni-hamburg.de>* + + * Temp key "for export" tests were wrong in s3_srvr.c. + + *Anonymous * + + * Add prototype for temp key callback functions + SSL_CTX_set_tmp_{rsa,dh}_callback(). + + *Ben Laurie* + + * Make DH_free() tolerate being passed a NULL pointer (like RSA_free() and + DSA_free()). Make X509_PUBKEY_set() check for errors in d2i_PublicKey(). + + *Steve Henson* + + * X509_name_add_entry() freed the wrong thing after an error. + + *Arne Ansper * + + * rsa_eay.c would attempt to free a NULL context. + + *Arne Ansper * + + * BIO_s_socket() had a broken should_retry() on Windoze. + + *Arne Ansper * + + * BIO_f_buffer() didn't pass on BIO_CTRL_FLUSH. + + *Arne Ansper * + + * Make sure the already existing X509_STORE->depth variable is initialized + in X509_STORE_new(), but document the fact that this variable is still + unused in the certificate verification process. + + *Ralf S. Engelschall* + + * Fix the various library and `apps/` files to free up pkeys obtained from + X509_PUBKEY_get() et al. Also allow x509.c to handle netscape extensions. + + *Steve Henson* + + * Fix reference counting in X509_PUBKEY_get(). This makes + demos/maurice/example2.c work, amongst others, probably. + + *Steve Henson and Ben Laurie* + + * First cut of a cleanup for `apps/`. First the `ssleay` program is now named + `openssl` and second, the shortcut symlinks for the `openssl ` + are no longer created. This way we have a single and consistent command + line interface `openssl `, similar to `cvs `. + + *Ralf S. Engelschall, Paul Sutton and Ben Laurie* + + * ca.c: move test for DSA keys inside #ifndef NO_DSA. Make pubkey + BIT STRING wrapper always have zero unused bits. + + *Steve Henson* + + * Add CA.pl, perl version of CA.sh, add extended key usage OID. + + *Steve Henson* + + * Make the top-level INSTALL documentation easier to understand. + + *Paul Sutton* + + * Makefiles updated to exit if an error occurs in a sub-directory + make (including if user presses ^C) [Paul Sutton] + + * Make Montgomery context stuff explicit in RSA data structure. + + *Ben Laurie* + + * Fix build order of pem and err to allow for generated pem.h. + + *Ben Laurie* + + * Fix renumbering bug in X509_NAME_delete_entry(). + + *Ben Laurie* + + * Enhanced the err-ins.pl script so it makes the error library number + global and can add a library name. This is needed for external ASN1 and + other error libraries. + + *Steve Henson* + + * Fixed sk_insert which never worked properly. + + *Steve Henson* + + * Fix ASN1 macros so they can handle indefinite length constructed + EXPLICIT tags. Some non standard certificates use these: they can now + be read in. + + *Steve Henson* + + * Merged the various old/obsolete SSLeay documentation files (doc/xxx.doc) + into a single doc/ssleay.txt bundle. This way the information is still + preserved but no longer messes up this directory. Now it's new room for + the new set of documentation files. + + *Ralf S. Engelschall* + + * SETs were incorrectly DER encoded. This was a major pain, because they + shared code with SEQUENCEs, which aren't coded the same. This means that + almost everything to do with SETs or SEQUENCEs has either changed name or + number of arguments. + + *Ben Laurie, based on a partial fix by GP Jayan * + + * Fix test data to work with the above. + + *Ben Laurie* + + * Fix the RSA header declarations that hid a bug I fixed in 0.9.0b but + was already fixed by Eric for 0.9.1 it seems. + + *Ben Laurie - pointed out by Ulf Möller * + + * Autodetect FreeBSD3. + + *Ben Laurie* + + * Fix various bugs in Configure. This affects the following platforms: + nextstep + ncr-scde + unixware-2.0 + unixware-2.0-pentium + sco5-cc. + + *Ben Laurie* + + * Eliminate generated files from CVS. Reorder tests to regenerate files + before they are needed. + + *Ben Laurie* + + * Generate Makefile.ssl from Makefile.org (to keep CVS happy). + + *Ben Laurie* + +### Changes between 0.9.1b and 0.9.1c [23-Dec-1998] + + * Added OPENSSL_VERSION_NUMBER to crypto/crypto.h and + changed SSLeay to OpenSSL in version strings. + + *Ralf S. Engelschall* + + * Some fixups to the top-level documents. + + *Paul Sutton* + + * Fixed the nasty bug where rsaref.h was not found under compile-time + because the symlink to include/ was missing. + + *Ralf S. Engelschall* + + * Incorporated the popular no-RSA/DSA-only patches + which allow to compile an RSA-free SSLeay. + + *Andrew Cooke / Interrader Ldt., Ralf S. Engelschall* + + * Fixed nasty rehash problem under `make -f Makefile.ssl links` + when "ssleay" is still not found. + + *Ralf S. Engelschall* + + * Added more platforms to Configure: Cray T3E, HPUX 11, + + *Ralf S. Engelschall, Beckmann * + + * Updated the README file. + + *Ralf S. Engelschall* + + * Added various .cvsignore files in the CVS repository subdirs + to make a "cvs update" really silent. + + *Ralf S. Engelschall* + + * Recompiled the error-definition header files and added + missing symbols to the Win32 linker tables. + + *Ralf S. Engelschall* + + * Cleaned up the top-level documents; + o new files: CHANGES and LICENSE + o merged VERSION, HISTORY* and README* files a CHANGES.SSLeay + o merged COPYRIGHT into LICENSE + o removed obsolete TODO file + o renamed MICROSOFT to INSTALL.W32 + + *Ralf S. Engelschall* + + * Removed dummy files from the 0.9.1b source tree: + crypto/asn1/x crypto/bio/cd crypto/bio/fg crypto/bio/grep crypto/bio/vi + crypto/bn/asm/......add.c crypto/bn/asm/a.out crypto/dsa/f crypto/md5/f + crypto/pem/gmon.out crypto/perlasm/f crypto/pkcs7/build crypto/rsa/f + crypto/sha/asm/f crypto/threads/f ms/zzz ssl/f ssl/f.mak test/f + util/f.mak util/pl/f util/pl/f.mak crypto/bf/bf_locl.old apps/f + + *Ralf S. Engelschall* + + * Added various platform portability fixes. + + *Mark J. Cox* + + * The Genesis of the OpenSSL rpject: + We start with the latest (unreleased) SSLeay version 0.9.1b which Eric A. + Young and Tim J. Hudson created while they were working for C2Net until + summer 1998. + + *The OpenSSL Project* + +### Changes between 0.9.0b and 0.9.1b [not released] + + * Updated a few CA certificates under certs/ + + *Eric A. Young* + + * Changed some BIGNUM api stuff. + + *Eric A. Young* + + * Various platform ports: OpenBSD, Ultrix, IRIX 64bit, NetBSD, + DGUX x86, Linux Alpha, etc. + + *Eric A. Young* + + * New COMP library [crypto/comp/] for SSL Record Layer Compression: + RLE (dummy implemented) and ZLIB (really implemented when ZLIB is + available). + + *Eric A. Young* + + * Add -strparse option to asn1pars program which parses nested + binary structures + + *Dr Stephen Henson * + + * Added "oid_file" to ssleay.cnf for "ca" and "req" programs. + + *Eric A. Young* + + * DSA fix for "ca" program. + + *Eric A. Young* + + * Added "-genkey" option to "dsaparam" program. + + *Eric A. Young* + + * Added RIPE MD160 (rmd160) message digest. + + *Eric A. Young* + + * Added -a (all) option to "ssleay version" command. + + *Eric A. Young* + + * Added PLATFORM define which is the id given to Configure. + + *Eric A. Young* + + * Added MemCheck_XXXX functions to crypto/mem.c for memory checking. + + *Eric A. Young* + + * Extended the ASN.1 parser routines. + + *Eric A. Young* + + * Extended BIO routines to support REUSEADDR, seek, tell, etc. + + *Eric A. Young* + + * Added a BN_CTX to the BN library. + + *Eric A. Young* + + * Fixed the weak key values in DES library + + *Eric A. Young* + + * Changed API in EVP library for cipher aliases. + + *Eric A. Young* + + * Added support for RC2/64bit cipher. + + *Eric A. Young* + + * Converted the lhash library to the crypto/mem.c functions. + + *Eric A. Young* + + * Added more recognized ASN.1 object ids. + + *Eric A. Young* + + * Added more RSA padding checks for SSL/TLS. + + *Eric A. Young* + + * Added BIO proxy/filter functionality. + + *Eric A. Young* + + * Added extra_certs to SSL_CTX which can be used + send extra CA certificates to the client in the CA cert chain sending + process. It can be configured with SSL_CTX_add_extra_chain_cert(). + + *Eric A. Young* + + * Now Fortezza is denied in the authentication phase because + this is key exchange mechanism is not supported by SSLeay at all. + + *Eric A. Young* + + * Additional PKCS1 checks. + + *Eric A. Young* + + * Support the string "TLSv1" for all TLS v1 ciphers. + + *Eric A. Young* + + * Added function SSL_get_ex_data_X509_STORE_CTX_idx() which gives the + ex_data index of the SSL context in the X509_STORE_CTX ex_data. + + *Eric A. Young* + + * Fixed a few memory leaks. + + *Eric A. Young* + + * Fixed various code and comment typos. + + *Eric A. Young* + + * A minor bug in ssl/s3_clnt.c where there would always be 4 0 + bytes sent in the client random. + + *Edward Bishop * + + + +[CVE-2023-0401]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0401 +[CVE-2023-0286]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0286 +[CVE-2023-0217]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0217 +[CVE-2023-0216]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0216 +[CVE-2023-0215]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0215 +[CVE-2022-4450]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4450 +[CVE-2022-4304]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4304 +[CVE-2022-4203]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4203 +[CVE-2022-3996]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-3996 +[CVE-2022-2274]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-2274 +[CVE-2022-2097]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-2274 +[CVE-2020-1971]: https://www.openssl.org/news/vulnerabilities.html#CVE-2020-1971 +[CVE-2020-1967]: https://www.openssl.org/news/vulnerabilities.html#CVE-2020-1967 +[CVE-2019-1563]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1563 +[CVE-2019-1559]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1559 +[CVE-2019-1552]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1552 +[CVE-2019-1551]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1551 +[CVE-2019-1549]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1549 +[CVE-2019-1547]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1547 +[CVE-2019-1543]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1543 +[CVE-2018-5407]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-5407 +[CVE-2018-0739]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0739 +[CVE-2018-0737]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0737 +[CVE-2018-0735]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0735 +[CVE-2018-0734]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0734 +[CVE-2018-0733]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0733 +[CVE-2018-0732]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0732 +[CVE-2017-3738]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3738 +[CVE-2017-3737]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3737 +[CVE-2017-3736]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3736 +[CVE-2017-3735]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3735 +[CVE-2017-3733]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3733 +[CVE-2017-3732]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3732 +[CVE-2017-3731]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3731 +[CVE-2017-3730]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3730 +[CVE-2016-7055]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7055 +[CVE-2016-7054]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7054 +[CVE-2016-7053]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7053 +[CVE-2016-7052]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7052 +[CVE-2016-6309]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6309 +[CVE-2016-6308]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6308 +[CVE-2016-6307]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6307 +[CVE-2016-6306]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6306 +[CVE-2016-6305]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6305 +[CVE-2016-6304]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6304 +[CVE-2016-6303]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6303 +[CVE-2016-6302]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6302 +[CVE-2016-2183]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2183 +[CVE-2016-2182]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2182 +[CVE-2016-2181]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2181 +[CVE-2016-2180]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2180 +[CVE-2016-2179]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2179 +[CVE-2016-2178]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2178 +[CVE-2016-2177]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2177 +[CVE-2016-2176]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2176 +[CVE-2016-2109]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2109 +[CVE-2016-2107]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2107 +[CVE-2016-2106]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2106 +[CVE-2016-2105]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2105 +[CVE-2016-0800]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0800 +[CVE-2016-0799]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0799 +[CVE-2016-0798]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0798 +[CVE-2016-0797]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0797 +[CVE-2016-0705]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0705 +[CVE-2016-0702]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0702 +[CVE-2016-0701]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0701 +[CVE-2015-3197]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3197 +[CVE-2015-3196]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3196 +[CVE-2015-3195]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3195 +[CVE-2015-3194]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3194 +[CVE-2015-3193]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3193 +[CVE-2015-1793]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1793 +[CVE-2015-1792]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1792 +[CVE-2015-1791]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1791 +[CVE-2015-1790]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1790 +[CVE-2015-1789]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1789 +[CVE-2015-1788]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1788 +[CVE-2015-1787]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1787 +[CVE-2015-0293]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0293 +[CVE-2015-0291]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0291 +[CVE-2015-0290]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0290 +[CVE-2015-0289]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0289 +[CVE-2015-0288]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0288 +[CVE-2015-0287]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0287 +[CVE-2015-0286]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0286 +[CVE-2015-0285]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0285 +[CVE-2015-0209]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0209 +[CVE-2015-0208]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0208 +[CVE-2015-0207]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0207 +[CVE-2015-0206]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0206 +[CVE-2015-0205]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0205 +[CVE-2015-0204]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0204 +[CVE-2014-8275]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-8275 +[CVE-2014-5139]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-5139 +[CVE-2014-3572]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3572 +[CVE-2014-3571]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3571 +[CVE-2014-3570]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3570 +[CVE-2014-3569]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3569 +[CVE-2014-3568]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3568 +[CVE-2014-3567]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3567 +[CVE-2014-3566]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3566 +[CVE-2014-3513]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3513 +[CVE-2014-3512]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3512 +[CVE-2014-3511]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3511 +[CVE-2014-3510]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3510 +[CVE-2014-3509]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3509 +[CVE-2014-3508]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3508 +[CVE-2014-3507]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3507 +[CVE-2014-3506]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3506 +[CVE-2014-3505]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3505 +[CVE-2014-3470]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3470 +[CVE-2014-0224]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0224 +[CVE-2014-0221]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0221 +[CVE-2014-0195]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0195 +[CVE-2014-0160]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0160 +[CVE-2014-0076]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0076 +[CVE-2013-6450]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-6450 +[CVE-2013-4353]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-4353 +[CVE-2013-0169]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-0169 +[CVE-2013-0166]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-0166 +[CVE-2012-2686]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2686 +[CVE-2012-2333]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2333 +[CVE-2012-2110]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2110 +[CVE-2012-0884]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0884 +[CVE-2012-0050]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0050 +[CVE-2012-0027]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0027 +[CVE-2011-4619]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4619 +[CVE-2011-4577]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4577 +[CVE-2011-4576]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4576 +[CVE-2011-4109]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4109 +[CVE-2011-4108]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4108 +[CVE-2011-3210]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-3210 +[CVE-2011-3207]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-3207 +[CVE-2011-0014]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-0014 +[CVE-2010-4252]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-4252 +[CVE-2010-4180]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-4180 +[CVE-2010-3864]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-3864 +[CVE-2010-1633]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-1633 +[CVE-2010-0740]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-0740 +[CVE-2010-0433]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-0433 +[CVE-2009-4355]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-4355 +[CVE-2009-3555]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-3555 +[CVE-2009-3245]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-3245 +[CVE-2009-1386]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-1386 +[CVE-2009-1379]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-1379 +[CVE-2009-1378]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-1378 +[CVE-2009-1377]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-1377 +[CVE-2009-0789]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0789 +[CVE-2009-0591]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0591 +[CVE-2009-0590]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0590 +[CVE-2008-5077]: https://www.openssl.org/news/vulnerabilities.html#CVE-2008-5077 +[CVE-2008-1678]: https://www.openssl.org/news/vulnerabilities.html#CVE-2008-1678 +[CVE-2008-1672]: https://www.openssl.org/news/vulnerabilities.html#CVE-2008-1672 +[CVE-2008-0891]: https://www.openssl.org/news/vulnerabilities.html#CVE-2008-0891 +[CVE-2007-5135]: https://www.openssl.org/news/vulnerabilities.html#CVE-2007-5135 +[CVE-2007-4995]: https://www.openssl.org/news/vulnerabilities.html#CVE-2007-4995 +[CVE-2006-4343]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-4343 +[CVE-2006-4339]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-4339 +[CVE-2006-3738]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-3738 +[CVE-2006-2940]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2940 +[CVE-2006-2937]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2937 +[CVE-2005-2969]: https://www.openssl.org/news/vulnerabilities.html#CVE-2005-2969 +[CVE-2004-0112]: https://www.openssl.org/news/vulnerabilities.html#CVE-2004-0112 +[CVE-2004-0079]: https://www.openssl.org/news/vulnerabilities.html#CVE-2004-0079 +[CVE-2003-0851]: https://www.openssl.org/news/vulnerabilities.html#CVE-2003-0851 +[CVE-2003-0545]: https://www.openssl.org/news/vulnerabilities.html#CVE-2003-0545 +[CVE-2003-0544]: https://www.openssl.org/news/vulnerabilities.html#CVE-2003-0544 +[CVE-2003-0543]: https://www.openssl.org/news/vulnerabilities.html#CVE-2003-0543 +[CVE-2003-0078]: https://www.openssl.org/news/vulnerabilities.html#CVE-2003-0078 +[CVE-2002-0659]: https://www.openssl.org/news/vulnerabilities.html#CVE-2002-0659 +[CVE-2002-0657]: https://www.openssl.org/news/vulnerabilities.html#CVE-2002-0657 +[CVE-2002-0656]: https://www.openssl.org/news/vulnerabilities.html#CVE-2002-0656 +[CVE-2002-0655]: https://www.openssl.org/news/vulnerabilities.html#CVE-2002-0655 diff --git a/crypto/openssl/CONTRIBUTING b/crypto/openssl/CONTRIBUTING deleted file mode 100644 index 83c0dde12819..000000000000 --- a/crypto/openssl/CONTRIBUTING +++ /dev/null @@ -1,72 +0,0 @@ -HOW TO CONTRIBUTE TO OpenSSL ----------------------------- - -(Please visit https://www.openssl.org/community/getting-started.html for -other ideas about how to contribute.) - -Development is done on GitHub, https://github.com/openssl/openssl. - -To request new features or report bugs, please open an issue on GitHub - -To submit a patch, please open a pull request on GitHub. If you are thinking -of making a large contribution, open an issue for it before starting work, -to get comments from the community. Someone may be already working on -the same thing or there may be reasons why that feature isn't implemented. - -To make it easier to review and accept your pull request, please follow these -guidelines: - - 1. Anything other than a trivial contribution requires a Contributor - License Agreement (CLA), giving us permission to use your code. See - https://www.openssl.org/policies/cla.html for details. If your - contribution is too small to require a CLA, put "CLA: trivial" on a - line by itself in your commit message body. - - 2. All source files should start with the following text (with - appropriate comment characters at the start of each line and the - year(s) updated): - - Copyright 20xx-20yy 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 - - 3. Patches should be as current as possible; expect to have to rebase - often. We do not accept merge commits, you will have to remove them - (usually by rebasing) before it will be acceptable. - - 4. Patches should follow our coding style (see - https://www.openssl.org/policies/codingstyle.html) and compile - without warnings. Where gcc or clang is available you should use the - --strict-warnings Configure option. OpenSSL compiles on many varied - platforms: try to ensure you only use portable features. Clean builds via - GitHub Actions and AppVeyor are required, and they are started automatically - whenever a PR is created or updated. - - 5. When at all possible, patches should include tests. These can - either be added to an existing test, or completely new. Please see - test/README for information on the test framework. - - 6. New features or changed functionality must include - documentation. Please look at the "pod" files in doc/man[1357] for - examples of our style. Run "make doc-nits" to make sure that your - documentation changes are clean. - - 7. For user visible changes (API changes, behaviour changes, ...), - consider adding a note in CHANGES. This could be a summarising - description of the change, and could explain the grander details. - Have a look through existing entries for inspiration. - Please note that this is NOT simply a copy of git-log one-liners. - Also note that security fixes get an entry in CHANGES. - This file helps users get more in depth information of what comes - with a specific release without having to sift through the higher - noise ratio in git-log. - - 8. For larger or more important user visible changes, as well as - security fixes, please add a line in NEWS. On exception, it might be - worth adding a multi-line entry (such as the entry that announces all - the types that became opaque with OpenSSL 1.1.0). - This file helps users get a very quick summary of what comes with a - specific release, to see if an upgrade is worth the effort. diff --git a/crypto/openssl/CONTRIBUTING.md b/crypto/openssl/CONTRIBUTING.md new file mode 100644 index 000000000000..efb4be871695 --- /dev/null +++ b/crypto/openssl/CONTRIBUTING.md @@ -0,0 +1,94 @@ +HOW TO CONTRIBUTE TO OpenSSL +============================ + +Please visit our [Getting Started] page for other ideas about how to contribute. + + [Getting Started]: + +Development is done on GitHub in the [openssl/openssl] repository. + + [openssl/openssl]: + +To request new features or report bugs, please open an issue on GitHub + +To submit a patch, please open a pull request on GitHub. If you are thinking +of making a large contribution, open an issue for it before starting work, +to get comments from the community. Someone may be already working on +the same thing or there may be reasons why that feature isn't implemented. + +To make it easier to review and accept your pull request, please follow these +guidelines: + + 1. Anything other than a trivial contribution requires a [Contributor + License Agreement] (CLA), giving us permission to use your code. + If your contribution is too small to require a CLA (e.g. fixing a spelling + mistake), place the text "`CLA: trivial`" on a line by itself separated by + an empty line from the rest of the commit message. It is not sufficient to + only place the text in the GitHub pull request description. + + [Contributor License Agreement]: + + To amend a missing "`CLA: trivial`" line after submission, do the following: + + ``` + git commit --amend + [add the line, save and quit the editor] + git push -f + ``` + + 2. All source files should start with the following text (with + appropriate comment characters at the start of each line and the + year(s) updated): + + ``` + Copyright 20xx-20yy 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 + ``` + + 3. Patches should be as current as possible; expect to have to rebase + often. We do not accept merge commits, you will have to remove them + (usually by rebasing) before it will be acceptable. + + 4. Patches should follow our [coding style] and compile without warnings. + Where `gcc` or `clang` is available you should use the + `--strict-warnings` `Configure` option. OpenSSL compiles on many varied + platforms: try to ensure you only use portable features. Clean builds via + GitHub Actions and AppVeyor are required, and they are started automatically + whenever a PR is created or updated. + + [coding style]: https://www.openssl.org/policies/technical/coding-style.html + + 5. When at all possible, patches should include tests. These can + either be added to an existing test, or completely new. Please see + [test/README.md](test/README.md) for information on the test framework. + + 6. New features or changed functionality must include + documentation. Please look at the "pod" files in doc/man[1357] for + examples of our style. Run "make doc-nits" to make sure that your + documentation changes are clean. + + 7. For user visible changes (API changes, behaviour changes, ...), + consider adding a note in [CHANGES.md](CHANGES.md). + This could be a summarising description of the change, and could + explain the grander details. + Have a look through existing entries for inspiration. + Please note that this is NOT simply a copy of git-log one-liners. + Also note that security fixes get an entry in [CHANGES.md](CHANGES.md). + This file helps users get more in depth information of what comes + with a specific release without having to sift through the higher + noise ratio in git-log. + + 8. For larger or more important user visible changes, as well as + security fixes, please add a line in [NEWS.md](NEWS.md). + On exception, it might be worth adding a multi-line entry (such as + the entry that announces all the types that became opaque with + OpenSSL 1.1.0). + This file helps users get a very quick summary of what comes with a + specific release, to see if an upgrade is worth the effort. + + 9. Guidelines how to integrate error output of new crypto library modules + can be found in [crypto/err/README.md](crypto/err/README.md). diff --git a/crypto/openssl/Configure b/crypto/openssl/Configure index 37a99d14715c..5ac4b5222e4f 100755 --- a/crypto/openssl/Configure +++ b/crypto/openssl/Configure @@ -2,7 +2,7 @@ # -*- mode: perl; -*- # Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -15,17 +15,38 @@ use Config; use FindBin; use lib "$FindBin::Bin/util/perl"; use File::Basename; -use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/; +use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs splitdir/; use File::Path qw/mkpath/; +use OpenSSL::fallback "$FindBin::Bin/external/perl/MODULES.txt"; use OpenSSL::Glob; +use OpenSSL::Template; +use OpenSSL::config; -# see INSTALL for instructions. +# see INSTALL.md for instructions. my $orig_death_handler = $SIG{__DIE__}; $SIG{__DIE__} = \&death_handler; my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n"; +my $banner = <<"EOF"; + +********************************************************************** +*** *** +*** OpenSSL has been successfully configured *** +*** *** +*** If you encounter a problem while building, please open an *** +*** issue on GitHub *** +*** and include the output from the following command: *** +*** *** +*** perl configdata.pm --dump *** +*** *** +*** (If you are new to OpenSSL, you might want to consult the *** +*** 'Troubleshooting' section in the INSTALL.md file first) *** +*** *** +********************************************************************** +EOF + # Options: # # --config add the given configuration file, which will be read after @@ -40,11 +61,17 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # given with --prefix. # This becomes the value of OPENSSLDIR in Makefile and in C. # (Default: PREFIX/ssl) +# --banner=".." Output specified text instead of default completion banner +# +# -w Don't wait after showing a Configure warning # # --cross-compile-prefix Add specified prefix to binutils components. # -# --api One of 0.9.8, 1.0.0 or 1.1.0. Do not compile support for -# interfaces deprecated as of the specified OpenSSL version. +# --api One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0 +# Define the public APIs as they were for that version +# including patch releases. If 'no-deprecated' is also +# given, do not compile support for interfaces deprecated +# up to and including the specified OpenSSL version. # # no-hw-xxx do not compile support for specific crypto hardware. # Generic OpenSSL-style methods relating to this support @@ -63,12 +90,13 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # zlib-dynamic Like "zlib", but the zlib library is expected to be a shared # library and will be loaded in run-time by the OpenSSL library. # sctp include SCTP support +# no-uplink Don't build support for UPLINK interface. # enable-weak-ssl-ciphers # Enable weak ciphers that are disabled by default. # 386 generate 80386 code in assembly modules # no-sse2 disables IA-32 SSE2 code in assembly modules, the above # mentioned '386' option implies this one -# no- build without specified algorithm (rsa, idea, rc5, ...) +# no- build without specified algorithm (dsa, idea, rc5, ...) # - + All options which are unknown to the 'Configure' script are # / passed through to the compiler. Unix-style options beginning # with a '-' or '+' are recognized, as well as Windows-style @@ -110,7 +138,6 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # get past these. Note that we only use these with C compilers, not with # C++ compilers. -# DEBUG_UNUSED enables __owur (warn unused result) checks. # -DPEDANTIC complements -pedantic and is meant to mask code that # is not strictly standard-compliant and/or implementation-specific, # e.g. inline assembly, disregards to alignment requirements, such @@ -124,9 +151,9 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # but 'long long' type. my @gcc_devteam_warn = qw( - -DDEBUG_UNUSED - -DPEDANTIC -pedantic -Wno-long-long + -DPEDANTIC -pedantic -Wno-long-long -DUNUSEDRESULT_DEBUG -Wall + -Wmissing-declarations -Wextra -Wno-unused-parameter -Wno-missing-field-initializers @@ -164,10 +191,6 @@ my @cl_devteam_warn = qw( /WX ); -# This adds backtrace information to the memory leak info. Is only used -# when crypto-mdebug-backtrace is enabled. -my $memleak_devteam_backtrace = "-rdynamic"; - my $strict_warnings = 0; # As for $BSDthreads. Idea is to maintain "collective" set of flags, @@ -182,13 +205,31 @@ our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT"; # # API compatibility name to version number mapping. # -my $maxapi = "1.1.0"; # API for "no-deprecated" builds my $apitable = { - "1.1.0" => "0x10100000L", - "1.0.0" => "0x10000000L", - "0.9.8" => "0x00908000L", + # This table expresses when API additions or changes can occur. + # The numbering used changes from 3.0 and on because we updated + # (solidified) our version numbering scheme at that point. + + # From 3.0 and on, we internalise the given version number in decimal + # as MAJOR * 10000 + MINOR * 100 + 0 + "3.0.0" => 30000, + "3.0" => 30000, + + # Note that before 3.0, we didn't have the same version number scheme. + # Still, the numbering we use here covers what we need. + "1.1.1" => 10101, + "1.1.0" => 10100, + "1.0.2" => 10002, + "1.0.1" => 10001, + "1.0.0" => 10000, + "0.9.8" => 908, }; +# For OpenSSL::config::get_platform +my %guess_opts = (); + +my $dryrun = 0; + our %table = (); our %config = (); our %withargs = (); @@ -233,6 +274,9 @@ my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR'; $config{sourcedir} = abs2rel($srcdir, $blddir); $config{builddir} = abs2rel($blddir, $blddir); +# echo -n 'holy hand grenade of antioch' | openssl sha256 +$config{FIPSKEY} = + 'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813'; # Collect reconfiguration information if needed my @argvcopy=@ARGV; @@ -260,29 +304,58 @@ if (grep /^reconf(igure)?$/, @argvcopy) { $config{perlargv} = [ @argvcopy ]; +# Historical: if known directories in crypto/ have been removed, it means +# that those sub-systems are disabled. +# (the other option would be to removed them from the SUBDIRS statement in +# crypto/build.info) +# We reverse the input list for cosmetic purely reasons, to compensate that +# 'unshift' adds at the front of the list (i.e. in reverse input order). +foreach ( reverse sort( 'aes', 'aria', 'bf', 'camellia', 'cast', 'des', 'dh', + 'dsa', 'ec', 'hmac', 'idea', 'md2', 'md5', 'mdc2', + 'rc2', 'rc4', 'rc5', 'ripemd', 'seed', 'sha', + 'sm2', 'sm3', 'sm4') ) { + unshift @argvcopy, "no-$_" if ! -d catdir($srcdir, 'crypto', $_); +} + # Collect version numbers -$config{version} = "unknown"; -$config{version_num} = "unknown"; -$config{shlib_version_number} = "unknown"; -$config{shlib_version_history} = "unknown"; +my %version = (); collect_information( - collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')), - qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; }, - qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/ => sub { $config{version_num}=$1 }, - qr/SHLIB_VERSION_NUMBER *"([^"]+)"/ => sub { $config{shlib_version_number}=$1 }, - qr/SHLIB_VERSION_HISTORY *"([^"]*)"/ => sub { $config{shlib_version_history}=$1 } + collect_from_file(catfile($srcdir,'VERSION.dat')), + qr/\s*(\w+)\s*=\s*(.*?)\s*$/ => + sub { + # Only define it if there is a value at all + if ($2 ne '') { + my $k = $1; + my $v = $2; + # Some values are quoted. Trim the quotes + $v = $1 if $v =~ /^"(.*)"$/; + $version{uc $k} = $v; + } + }, + "OTHERWISE" => + sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION.dat" }, ); -if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; } -($config{major}, $config{minor}) - = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/); -($config{shlib_major}, $config{shlib_minor}) - = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/); -die "erroneous version information in opensslv.h: ", - "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n" - if ($config{major} eq "" || $config{minor} eq "" - || $config{shlib_major} eq "" || $config{shlib_minor} eq ""); +$config{major} = $version{MAJOR} // 'unknown'; +$config{minor} = $version{MINOR} // 'unknown'; +$config{patch} = $version{PATCH} // 'unknown'; +$config{prerelease} = + defined $version{PRE_RELEASE_TAG} ? "-$version{PRE_RELEASE_TAG}" : ''; +$config{build_metadata} = + defined $version{BUILD_METADATA} ? "+$version{BUILD_METADATA}" : ''; +$config{shlib_version} = $version{SHLIB_VERSION} // 'unknown'; +$config{release_date} = $version{RELEASE_DATE} // 'xx XXX xxxx'; + +$config{version} = "$config{major}.$config{minor}.$config{patch}"; +$config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}"; + +die "erroneous version information in VERSION.dat: ", + "$config{version}, $config{shlib_version}\n" + unless (defined $version{MAJOR} + && defined $version{MINOR} + && defined $version{PATCH} + && defined $version{SHLIB_VERSION}); # Collect target configurations @@ -317,21 +390,6 @@ $config{libdir}=""; my $auto_threads=1; # enable threads automatically? true by default my $default_ranlib; -# Top level directories to build -$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ]; -# crypto/ subdirectories to build -$config{sdirs} = [ - "objects", - "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash", "sm3", - "des", "aes", "rc2", "rc4", "rc5", "idea", "aria", "bf", "cast", "camellia", "seed", "sm4", "chacha", "modes", - "bn", "ec", "rsa", "dsa", "dh", "sm2", "dso", "engine", - "buffer", "bio", "stack", "lhash", "rand", "err", - "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui", - "cms", "ts", "srp", "cmac", "ct", "async", "kdf", "store" - ]; -# test/ subdirectories to build -$config{tdirs} = [ "ossl_shim" ]; - # Known TLS and DTLS protocols my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3); my @dtls = qw(dtls1 dtls1_2); @@ -341,6 +399,7 @@ my @dtls = qw(dtls1 dtls1_2); # For developers: keep it sorted alphabetically my @disablables = ( + "acvp-tests", "afalgeng", "aria", "asan", @@ -351,16 +410,18 @@ my @disablables = ( "autoload-config", "bf", "blake2", - "buildtest-c\\+\\+", + "buildtest-c++", + "bulk", + "cached-fetch", "camellia", "capieng", "cast", "chacha", "cmac", + "cmp", "cms", "comp", "crypto-mdebug", - "crypto-mdebug-backtrace", "ct", "deprecated", "des", @@ -373,32 +434,36 @@ my @disablables = ( "dynamic-engine", "ec", "ec2m", + "ec_nistp_64_gcc_128", "ecdh", "ecdsa", - "ec_nistp_64_gcc_128", "egd", "engine", "err", "external-tests", "filenames", - "fuzz-libfuzzer", + "fips", + "fips-securitychecks", "fuzz-afl", + "fuzz-libfuzzer", "gost", - "heartbeats", - "hw(-.+)?", "idea", "ktls", + "legacy", + "loadereng", "makedepend", "md2", "md4", "mdc2", + "module", "msan", "multiblock", "nextprotoneg", - "pinshared", "ocb", "ocsp", + "padlockeng", "pic", + "pinshared", "poly1305", "posix-io", "psk", @@ -410,9 +475,11 @@ my @disablables = ( "rmd160", "scrypt", "sctp", + "secure-memory", "seed", "shared", "siphash", + "siv", "sm2", "sm3", "sm4", @@ -427,12 +494,14 @@ my @disablables = ( "tests", "threads", "tls", + "trace", "ts", "ubsan", "ui-console", "unit-test", - "whirlpool", + "uplink", "weak-ssl-ciphers", + "whirlpool", "zlib", "zlib-dynamic", ); @@ -442,16 +511,29 @@ foreach my $proto ((@tls, @dtls)) push(@disablables, "$proto-method") unless $proto eq "tls1_3"; } +# Internal disablables, for aliasing purposes. They serve no special +# purpose here, but allow scripts to get to know them through configdata.pm, +# where these are merged with @disablables. +# The actual aliasing mechanism is done via %disable_cascades +my @disablables_int = qw( + crmf + ); + my %deprecated_disablables = ( "ssl2" => undef, "buf-freelists" => undef, + "crypto-mdebug-backtrace" => undef, + "hw" => "hw", # causes cascade, but no macro + "hw-padlock" => "padlockeng", "ripemd" => "rmd160", "ui" => "ui-console", + "heartbeats" => undef, ); # All of the following are disabled by default: our %disabled = ( # "what" => "comment" + "fips" => "default", "asan" => "default", "buildtest-c++" => "default", "crypto-mdebug" => "default", @@ -460,35 +542,49 @@ our %disabled = ( # "what" => "comment" "ec_nistp_64_gcc_128" => "default", "egd" => "default", "external-tests" => "default", - "fuzz-libfuzzer" => "default", "fuzz-afl" => "default", - "heartbeats" => "default", + "fuzz-libfuzzer" => "default", + "ktls" => "default", "md2" => "default", "msan" => "default", "rc5" => "default", "sctp" => "default", - "ssl-trace" => "default", "ssl3" => "default", "ssl3-method" => "default", + "trace" => "default", "ubsan" => "default", "unit-test" => "default", "weak-ssl-ciphers" => "default", "zlib" => "default", "zlib-dynamic" => "default", - "ktls" => "default", ); # Note: => pair form used for aesthetics, not to truly make a hash table my @disable_cascades = ( # "what" => [ "cascade", ... ] + "bulk" => [ "shared", "dso", + "aria", "async", "autoload-config", + "blake2", "bf", "camellia", "cast", "chacha", + "cmac", "cms", "cmp", "comp", "ct", + "des", "dgram", "dh", "dsa", + "ec", "engine", + "filenames", + "idea", "ktls", + "md4", "multiblock", "nextprotoneg", + "ocsp", "ocb", "poly1305", "psk", + "rc2", "rc4", "rmd160", + "seed", "siphash", "siv", + "sm3", "sm4", "srp", + "srtp", "ssl3-method", "ssl-trace", + "ts", "ui-console", "whirlpool", + "fips-securitychecks" ], sub { $config{processor} eq "386" } => [ "sse2" ], "ssl" => [ "ssl3" ], "ssl3-method" => [ "ssl3" ], "zlib" => [ "zlib-dynamic" ], "des" => [ "mdc2" ], - "ec" => [ "ecdsa", "ecdh" ], - + "ec" => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost" ], "dgram" => [ "dtls", "sctp" ], "sock" => [ "dgram" ], "dtls" => [ @dtls ], @@ -501,24 +597,51 @@ my @disable_cascades = ( "crypto-mdebug" => [ "crypto-mdebug-backtrace" ], - # Without position independent code, there can be no shared libraries or DSOs - "pic" => [ "shared" ], - "shared" => [ "dynamic-engine" ], - "dso" => [ "dynamic-engine" ], - "engine" => [ "afalgeng", "devcryptoeng" ], + # If no modules, then no dynamic engines either + "module" => [ "dynamic-engine" ], + + # Without shared libraries, dynamic engines aren't possible. + # This is due to them having to link with libcrypto and register features + # using the ENGINE functionality, and since that relies on global tables, + # those *have* to be exacty the same as the ones accessed from the app, + # which cannot be guaranteed if shared libraries aren't present. + # (note that even with shared libraries, both the app and dynamic engines + # must be linked with the same library) + "shared" => [ "dynamic-engine", "uplink" ], + "dso" => [ "dynamic-engine", "module" ], + # Other modules don't necessarily have to link with libcrypto, so shared + # libraries do not have to be a condition to produce those. + + # Without position independent code, there can be no shared libraries + # or modules. + "pic" => [ "shared", "module" ], + + "module" => [ "fips", "dso" ], + + "engine" => [ "dynamic-engine", grep(/eng$/, @disablables) ], + "dynamic-engine" => [ "loadereng" ], + "hw" => [ "padlockeng" ], # no-autoalginit is only useful when building non-shared - "autoalginit" => [ "shared", "apps" ], + "autoalginit" => [ "shared", "apps", "fips" ], "stdio" => [ "apps", "capieng", "egd" ], "apps" => [ "tests" ], "tests" => [ "external-tests" ], "comp" => [ "zlib" ], - "ec" => [ "tls1_3", "sm2" ], "sm3" => [ "sm2" ], sub { !$disabled{"unit-test"} } => [ "heartbeats" ], sub { !$disabled{"msan"} } => [ "asm" ], + + "cmac" => [ "siv" ], + "legacy" => [ "md2" ], + + "cmp" => [ "crmf" ], + + "fips" => [ "fips-securitychecks", "acvp-tests" ], + + "deprecated-3.0" => [ "engine", "srp" ] ); # Avoid protocol support holes. Also disable all versions below N, if version @@ -543,8 +666,6 @@ while ((my $first, my $second) = (shift @list, shift @list)) { # To remove something from %disabled, use "enable-foo". # For symmetry, "disable-foo" is a synonym for "no-foo". -&usage if ($#ARGV < 0); - # For the "make variables" CPPINCLUDES and CPPDEFINES, we support lists with # platform specific list separators. Users from those platforms should # recognise those separators from how you set up the PATH to find executables. @@ -629,10 +750,8 @@ $config{lflags} = [ env('__CNF_LDFLAGS') || () ]; $config{ex_libs} = [ env('__CNF_LDLIBS') || () ]; $config{openssl_api_defines}=[]; -$config{openssl_algorithm_defines}=[]; -$config{openssl_thread_defines}=[]; $config{openssl_sys_defines}=[]; -$config{openssl_other_defines}=[]; +$config{openssl_feature_defines}=[]; $config{options}=""; $config{build_type} = "release"; my $target=""; @@ -681,12 +800,14 @@ while (@argvcopy) s /^threads$/enable-threads/; s /^zlib$/enable-zlib/; s /^zlib-dynamic$/enable-zlib-dynamic/; + s /^fips$/enable-fips/; if (/^(no|disable|enable)-(.+)$/) { my $word = $2; - if (!exists $deprecated_disablables{$word} - && !grep { $word =~ /^${_}$/ } @disablables) + if ($word !~ m|hw(?:-.+)| # special treatment for hw regexp opt + && !exists $deprecated_disablables{$word} + && !grep { $word eq $_ } @disablables) { $unsupported_options{$_} = 1; next; @@ -734,15 +855,16 @@ while (@argvcopy) } elsif (exists $deprecated_disablables{$1}) { - if ($deprecated_disablables{$1} ne "") + $deprecated_options{$_} = 1; + if (defined $deprecated_disablables{$1}) { - $deprecated_options{$_} = 1; - if (defined $deprecated_disablables{$1}) - { - $disabled{$deprecated_disablables{$1}} = "option"; - } + $disabled{$deprecated_disablables{$1}} = "option"; } } + elsif ($1 =~ m|hw(?:-.+)|) # deprecate hw options in regexp form + { + $deprecated_options{$_} = 1; + } else { $disabled{$1} = "option"; @@ -770,6 +892,22 @@ while (@argvcopy) # No longer an automatic choice $auto_threads = 0 if ($1 eq "threads"); } + elsif (/^-d$/) # From older 'config' + { + $config{build_type} = "debug"; + } + elsif (/^-v$/) # From older 'config' + { + $guess_opts{verbose} = 1; + } + elsif (/^-w$/) + { + $guess_opts{nowait} = 1; + } + elsif (/^-t$/) # From older 'config' + { + $dryrun = 1; + } elsif (/^--strict-warnings$/) { # Pretend that our strict flags is a C flag, and replace it @@ -787,20 +925,12 @@ while (@argvcopy) } elsif (/^386$/) { $config{processor}=386; } - elsif (/^fips$/) - { - die "FIPS mode not supported\n"; - } elsif (/^rsaref$/) { # No RSAref support any more since it's not needed. # The check for the option is there so scripts aren't # broken } - elsif (/^nofipscanistercheck$/) - { - die "FIPS mode not supported\n"; - } elsif (m|^[-+/]|) { if (/^--prefix=(.*)$/) @@ -811,7 +941,10 @@ while (@argvcopy) } elsif (/^--api=(.*)$/) { - $config{api}=$1; + my $api = $1; + die "Unknown API compatibility level $api" + unless defined $apitable->{$api}; + $config{api}=$apitable->{$api}; } elsif (/^--libdir=(.*)$/) { @@ -846,6 +979,20 @@ while (@argvcopy) push @seed_sources, $x; } } + elsif (/^--fips-key=(.*)$/) + { + $user{FIPSKEY}=lc($1); + die "Non-hex character in FIPS key\n" + if $user{FIPSKEY} =~ /[^a-f0-9]/; + die "FIPS key must have even number of characters\n" + if length $1 & 1; + die "FIPS key too long (64 bytes max)\n" + if length $1 > 64; + } + elsif (/^--banner=(.*)$/) + { + $banner = $1 . "\n"; + } elsif (/^--cross-compile-prefix=(.*)$/) { $user{CROSS_COMPILE}=$1; @@ -928,10 +1075,6 @@ while (@argvcopy) } } -if (defined($config{api}) && !exists $apitable->{$config{api}}) { - die "***** Unsupported api compatibility level: $config{api}\n", -} - if (keys %deprecated_options) { warn "***** Deprecated options: ", @@ -1004,6 +1147,23 @@ if (grep { /-rpath\b/ } ($user{LDFLAGS} ? @{$user{LDFLAGS}} : ()) "***** any of asan, msan or ubsan\n"; } +# If no target was given, try guessing. +unless ($target) { + my %system_config = OpenSSL::config::get_platform(%guess_opts, %user); + + # The $system_config{disable} is used to populate %disabled with + # entries that aren't already there. + foreach ( @{$system_config{disable} // []} ) { + $disabled{$_} = 'system' unless defined $disabled{$_}; + } + delete $system_config{disable}; + + # Override config entries with stuff from the guesser. + # It's assumed that this really is nothing new. + %config = ( %config, %system_config ); + $target = $system_config{target}; +} + sub disable { my $disable_type = shift; @@ -1054,8 +1214,8 @@ if ($target eq "HASH") { exit 0; } -print "Configuring OpenSSL version $config{version} ($config{version_num}) "; -print "for $target\n"; +print "Configuring OpenSSL version $config{full_version} "; +print "for target $target\n"; if (scalar(@seed_sources) == 0) { print "Using os-specific seed configuration\n"; @@ -1076,12 +1236,13 @@ will not work unless the random generator is seeded manually by the application. Please read the 'Note on random number generation' section in the -INSTALL instructions and the RAND_DRBG(7) manual page for more details. +INSTALL.md instructions and the RAND_DRBG(7) manual page for more +details. ============================== WARNING =============================== _____ } -push @{$config{openssl_other_defines}}, +push @{$config{openssl_feature_defines}}, map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" } @seed_sources; @@ -1101,7 +1262,26 @@ if ($d) { } } -&usage if !$table{$target} || $table{$target}->{template}; +if ($target) { + # It's possible that we have different config targets for specific + # toolchains, so we try to detect them, and go for the plain config + # target if not. + my $found; + foreach ( ( "$target-$user{CC}", "$target", undef ) ) { + $found=$_ if $table{$_} && !$table{$_}->{template}; + last if $found; + } + $target = $found; +} else { + # If we don't have a config target now, we try the C compiler as we + # fallback + my $cc = $user{CC} // 'cc'; + $target = $cc if $table{$cc} && !$table{$cc}->{template}; +} + +&usage unless $target; + +exit 0 if $dryrun; # From older 'config' $config{target} = $target; my %target = resolve_config($target); @@ -1137,22 +1317,19 @@ foreach my $feature (@{$target{enable}}) { delete $disabled{$feature}; } } + +# If uplink_arch isn't defined, disable uplink +$disabled{uplink} = 'no uplink_arch' unless (defined $target{uplink_arch}); +# If asm_arch isn't defined, disable asm +$disabled{asm} = 'no asm_arch' unless (defined $target{asm_arch}); + disable(); # Run a cascade now $target{CXXFLAGS}//=$target{CFLAGS} if $target{CXX}; $target{cxxflags}//=$target{cflags} if $target{CXX}; -$target{exe_extension}=""; -$target{exe_extension}=".exe" if ($config{target} eq "DJGPP" - || $config{target} =~ /^(?:Cygwin|mingw)/); +$target{exe_extension}=".exe" if ($config{target} eq "DJGPP"); $target{exe_extension}=".pm" if ($config{target} =~ /vos/); -($target{shared_extension_simple}=$target{shared_extension}) - =~ s|\.\$\(SHLIB_VERSION_NUMBER\)|| - unless defined($target{shared_extension_simple}); -$target{dso_extension}//=$target{shared_extension_simple}; -($target{shared_import_extension}=$target{shared_extension_simple}.".a") - if ($config{target} =~ /^(?:Cygwin|mingw)/); - # Fill %config with values from %user, and in case those are undefined or # empty, use values from %target (acting as a default). foreach (keys %user) { @@ -1203,7 +1380,7 @@ foreach (keys %useradd) { # At this point, we can forget everything about %user and %useradd, # because it's now all been merged into the corresponding $config entry -if (grep { $_ eq '-static' } @{$config{LDFLAGS}}) { +if (grep { $_ =~ /(?:^|\s)-static(?:\s|$)/ } @{$config{LDFLAGS}}) { disable('static', 'pic', 'threads'); } @@ -1279,19 +1456,35 @@ unless ($disabled{threads}) { } } +# Find out if clang's sanitizers have been enabled with -fsanitize +# flags and ensure that the corresponding %disabled elements area +# removed to reflect that the sanitizers are indeed enabled. +my %detected_sanitizers = (); +foreach (grep /^-fsanitize=/, @{$config{CFLAGS} || []}) { + (my $checks = $_) =~ s/^-fsanitize=//; + foreach (split /,/, $checks) { + my $d = { address => 'asan', + undefined => 'ubsan', + memory => 'msan' } -> {$_}; + next unless defined $d; + + $detected_sanitizers{$d} = 1; + if (defined $disabled{$d}) { + die "***** Conflict between disabling $d and enabling $_ sanitizer" + if $disabled{$d} ne "default"; + delete $disabled{$d}; + } + } +} + # If threads still aren't disabled, add a C macro to ensure the source # code knows about it. Any other flag is taken care of by the configs. unless($disabled{threads}) { - push @{$config{openssl_thread_defines}}, "OPENSSL_THREADS"; -} - -# With "deprecated" disable all deprecated features. -if (defined($disabled{"deprecated"})) { - $config{api} = $maxapi; + push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS"; } my $no_shared_warn=0; -if ($target{shared_target} eq "") +if (($target{shared_target} // '') eq "") { $no_shared_warn = 1 if (!$disabled{shared} || !$disabled{"dynamic-engine"}); @@ -1304,21 +1497,16 @@ if ($disabled{"dynamic-engine"}) { $config{dynamic_engines} = 1; } -unless ($disabled{asan}) { +unless ($disabled{asan} || defined $detected_sanitizers{asan}) { push @{$config{cflags}}, "-fsanitize=address"; - push @{$config{cxxflags}}, "-fsanitize=address" if $config{CXX}; } -unless ($disabled{ubsan}) { - # -DPEDANTIC or -fnosanitize=alignment may also be required on some - # platforms. - push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all"; - push @{$config{cxxflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all" if $config{CXX}; +unless ($disabled{ubsan} || defined $detected_sanitizers{ubsan}) { + push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all", "-DPEDANTIC"; } -unless ($disabled{msan}) { +unless ($disabled{msan} || defined $detected_sanitizers{msan}) { push @{$config{cflags}}, "-fsanitize=memory"; - push @{$config{cxxflags}}, "-fsanitize=memory" if $config{CXX}; } unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"} @@ -1352,98 +1540,46 @@ if ($target{sys_id} ne "") push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}"; } -unless ($disabled{asm}) { - $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386"); - push @{$config{lib_defines}}, "OPENSSL_CPUID_OBJ" if ($target{cpuid_asm_src} ne "mem_clr.c"); - - $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m})); - - # bn-586 is the only one implementing bn_*_part_words - push @{$config{lib_defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/); - push @{$config{lib_defines}}, "OPENSSL_IA32_SSE2" if (!$disabled{sse2} && $target{bn_asm_src} =~ /86/); - - push @{$config{lib_defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/); - push @{$config{lib_defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/); - push @{$config{lib_defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/); - push @{$config{lib_defines}}, "BN_DIV3W" if ($target{bn_asm_src} =~ /-div3w/); - - if ($target{sha1_asm_src}) { - push @{$config{lib_defines}}, "SHA1_ASM" if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/); - push @{$config{lib_defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/); - push @{$config{lib_defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/); - } - if ($target{keccak1600_asm_src} ne $table{DEFAULTS}->{keccak1600_asm_src}) { - push @{$config{lib_defines}}, "KECCAK1600_ASM"; - } - if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) { - push @{$config{lib_defines}}, "RC4_ASM"; - } - if ($target{md5_asm_src}) { - push @{$config{lib_defines}}, "MD5_ASM"; - } - $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC - if ($target{rmd160_asm_src}) { - push @{$config{lib_defines}}, "RMD160_ASM"; - } - if ($target{aes_asm_src}) { - push @{$config{lib_defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);; - push @{$config{lib_defines}}, "AESNI_ASM" if ($target{aes_asm_src} =~ m/\baesni-/);; - # aes-ctr.fake is not a real file, only indication that assembler - # module implements AES_ctr32_encrypt... - push @{$config{lib_defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//); - # aes-xts.fake indicates presence of AES_xts_[en|de]crypt... - push @{$config{lib_defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//); - $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($disabled{sse2}); - push @{$config{lib_defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/); - push @{$config{lib_defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/); - } - if ($target{wp_asm_src} =~ /mmx/) { - if ($config{processor} eq "386") { - $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src}; - } elsif (!$disabled{"whirlpool"}) { - push @{$config{lib_defines}}, "WHIRLPOOL_ASM"; - } - } - if ($target{modes_asm_src} =~ /ghash-/) { - push @{$config{lib_defines}}, "GHASH_ASM"; - } - if ($target{ec_asm_src} =~ /ecp_nistz256/) { - push @{$config{lib_defines}}, "ECP_NISTZ256_ASM"; - } - if ($target{ec_asm_src} =~ /x25519/) { - push @{$config{lib_defines}}, "X25519_ASM"; - } - if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) { - push @{$config{dso_defines}}, "PADLOCK_ASM"; - } - if ($target{poly1305_asm_src} ne "") { - push @{$config{lib_defines}}, "POLY1305_ASM"; - } -} - my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC}); my %predefined_CXX = $config{CXX} ? compiler_predefined($config{CROSS_COMPILE}.$config{CXX}) : (); +unless ($disabled{asm}) { + # big endian systems can use ELFv2 ABI + if ($target eq "linux-ppc64") { + $target{perlasm_scheme} = "linux64v2" if ($predefined_C{_CALL_ELF} == 2); + } +} + # Check for makedepend capabilities. if (!$disabled{makedepend}) { - if ($config{target} =~ /^(VC|vms)-/) { - # For VC- and vms- targets, there's nothing more to do here. The - # functionality is hard coded in the corresponding build files for - # cl (Windows) and CC/DECC (VMS). + # If the attribute makedep_scheme is defined, then we assume that the + # config target and its associated build file are programmed to deal + # with it. + # If makedep_scheme is undefined, we go looking for GCC compatible + # dependency making, and if that's not available, we try to fall back + # on 'makedepend'. + if ($target{makedep_scheme}) { + $config{makedep_scheme} = $target{makedep_scheme}; + # If the makedepcmd attribute is defined, copy it. If not, the + # build files will have to fend for themselves. + $config{makedepcmd} = $target{makedepcmd} if $target{makedepcmd}; } elsif (($predefined_C{__GNUC__} // -1) >= 3 && !($predefined_C{__APPLE_CC__} && !$predefined_C{__clang__})) { # We know that GNU C version 3 and up as well as all clang # versions support dependency generation, but Xcode did not # handle $cc -M before clang support (but claims __GNUC__ = 3) - $config{makedepprog} = "\$(CROSS_COMPILE)$config{CC}"; + $config{makedep_scheme} = 'gcc'; } else { - # In all other cases, we look for 'makedepend', and disable the - # capability if not found. - $config{makedepprog} = which('makedepend'); - disable('unavailable', 'makedepend') unless $config{makedepprog}; + # In all other cases, we look for 'makedepend', and set the + # makedep_scheme value if we found it. + $config{makedepcmd} = which('makedepend'); + $config{makedep_scheme} = 'makedepend' if $config{makedepcmd}; } + + # If no depend scheme is set, we disable makedepend + disable('unavailable', 'makedepend') unless $config{makedep_scheme}; } if (!$disabled{asm} && !$predefined_C{__MACH__} && $^O ne 'VMS') { @@ -1471,7 +1607,6 @@ if (!$disabled{asm} && !$predefined_C{__MACH__} && $^O ne 'VMS') { # Deal with bn_ops ################################################### $config{bn_ll} =0; -$config{export_var_as_fn} =0; my $def_int="unsigned int"; $config{rc4_int} =$def_int; ($config{b64l},$config{b64},$config{b32})=(0,0,1); @@ -1479,7 +1614,6 @@ $config{rc4_int} =$def_int; my $count = 0; foreach (sort split(/\s+/,$target{bn_ops})) { $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/; - $config{export_var_as_fn}=1 if $_ eq 'EXPORT_VAR_AS_FN'; $config{bn_ll}=1 if $_ eq 'BN_LLONG'; $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR'; ($config{b64l},$config{b64},$config{b32}) @@ -1492,6 +1626,14 @@ foreach (sort split(/\s+/,$target{bn_ops})) { die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n" if $count > 1; +$config{api} = $config{major} * 10000 + $config{minor} * 100 + unless $config{api}; +foreach (keys %$apitable) { + $disabled{"deprecated-$_"} = "deprecation" + if $disabled{deprecated} && $config{api} >= $apitable->{$_}; +} + +disable(); # Run a cascade now # Hack cflags for better warnings (dev option) ####################### @@ -1502,11 +1644,9 @@ $config{cflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x } $config{cxxflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x } @{$config{cxxflags}} ] if $config{CXX}; -if (defined($config{api})) { - $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ]; - my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}}); - push @{$config{defines}}, $apiflag; -} +$config{openssl_api_defines} = [ + "OPENSSL_CONFIGURED_API=".$config{api}, +]; my @strict_warnings_collection=(); if ($strict_warnings) @@ -1535,19 +1675,6 @@ $config{CFLAGS} = [ map { $_ eq '--ossl-strict-warnings' : ( $_ ) } @{$config{CFLAGS}} ]; -unless ($disabled{"crypto-mdebug-backtrace"}) - { - foreach my $wopt (split /\s+/, $memleak_devteam_backtrace) - { - push @{$config{cflags}}, $wopt - unless grep { $_ eq $wopt } @{$config{cflags}}; - } - if ($target =~ /^BSD-/) - { - push @{$config{ex_libs}}, "-lexecinfo"; - } - } - unless ($disabled{afalgeng}) { $config{afalgeng}=""; if (grep { $_ eq 'afalgeng' } @{$target{enable}}) { @@ -1587,20 +1714,13 @@ unless ($disabled{devcryptoeng}) { unless ($disabled{ktls}) { $config{ktls}=""; + my $cc = $config{CROSS_COMPILE}.$config{CC}; if ($target =~ m/^linux/) { - my $usr = "/usr/$config{cross_compile_prefix}"; - chop($usr); - if ($config{cross_compile_prefix} eq "") { - $usr = "/usr"; - } - my $minver = (4 << 16) + (13 << 8) + 0; - my @verstr = split(" ",`cat $usr/include/linux/version.h | grep LINUX_VERSION_CODE`); - - if ($verstr[2] < $minver) { + system("printf '#include \n#include ' | $cc -E - >/dev/null 2>&1"); + if ($? != 0) { disable('too-old-kernel', 'ktls'); } } elsif ($target =~ m/^BSD/) { - my $cc = $config{CROSS_COMPILE}.$config{CC}; system("printf '#include \n#include ' | $cc -E - >/dev/null 2>&1"); if ($? != 0) { disable('too-old-freebsd', 'ktls'); @@ -1655,47 +1775,53 @@ $target{module_ldflags} = $target{shared_ldflag} unless defined $target{module_l # ALL MODIFICATIONS TO %disabled, %config and %target MUST BE DONE FROM HERE ON +###################################################################### +# Build up information for skipping certain directories depending on disabled +# features, as well as setting up macros for disabled features. + +# This is a tentative database of directories to skip. Some entries may not +# correspond to anything real, but that's ok, they will simply be ignored. +# The actual processing of these entries is done in the build.info lookup +# loop further down. +# +# The key is a Unix formatted path in the source tree, the value is an index +# into %disabled_info, so any existing path gets added to a corresponding +# 'skipped' entry in there with the list of skipped directories. +my %skipdir = (); my %disabled_info = (); # For configdata.pm foreach my $what (sort keys %disabled) { + # There are deprecated disablables that translate to themselves. + # They cause disabling cascades, but should otherwise not regiter. + next if $deprecated_disablables{$what}; + # The generated $disabled{"deprecated-x.y"} entries are special + # and treated properly elsewhere + next if $what =~ m|^deprecated-|; + $config{options} .= " no-$what"; - if (!grep { $what eq $_ } ( 'buildtest-c++', 'threads', 'shared', 'pic', - 'dynamic-engine', 'makedepend', - 'zlib-dynamic', 'zlib', 'sse2' )) { + if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared', + 'module', 'pic', 'dynamic-engine', 'makedepend', + 'zlib-dynamic', 'zlib', 'sse2', 'legacy' )) { (my $WHAT = uc $what) =~ s|-|_|g; - - # Fix up C macro end names - $WHAT = "RMD160" if $what eq "ripemd"; + my $skipdir = $what; # fix-up crypto/directory name(s) - $what = "ripemd" if $what eq "rmd160"; - $what = "whrlpool" if $what eq "whirlpool"; + $skipdir = "ripemd" if $what eq "rmd160"; + $skipdir = "whrlpool" if $what eq "whirlpool"; my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT"; + push @{$config{openssl_feature_defines}}, $macro; - if ((grep { $what eq $_ } @{$config{sdirs}}) - && $what ne 'async' && $what ne 'err' && $what ne 'dso') { - @{$config{sdirs}} = grep { $what ne $_} @{$config{sdirs}}; - $disabled_info{$what}->{skipped} = [ catdir('crypto', $what) ]; - - if ($what ne 'engine') { - push @{$config{openssl_algorithm_defines}}, $macro; - } else { - @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}}; - push @{$disabled_info{engine}->{skipped}}, catdir('engines'); - push @{$config{openssl_other_defines}}, $macro; - } - } else { - push @{$config{openssl_other_defines}}, $macro; - } - + $skipdir{engines} = $what if $what eq 'engine'; + $skipdir{"crypto/$skipdir"} = $what + unless $what eq 'async' || $what eq 'err' || $what eq 'dso'; } } if ($disabled{"dynamic-engine"}) { - push @{$config{openssl_other_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE"; + push @{$config{openssl_feature_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE"; } else { - push @{$config{openssl_other_defines}}, "OPENSSL_NO_STATIC_ENGINE"; + push @{$config{openssl_feature_defines}}, "OPENSSL_NO_STATIC_ENGINE"; } # If we use the unified build, collect information from build.info files @@ -1703,7 +1829,7 @@ my %unified_info = (); my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO}); if ($builder eq "unified") { - use with_fallback qw(Text::Template); + use Text::Template 1.46; sub cleandir { my $base = shift; @@ -1777,64 +1903,174 @@ if ($builder eq "unified") { $config{build_file_templates} = [ cleanfile($srcdir, catfile("Configurations", "common0.tmpl"), $blddir), - $build_file_template, - cleanfile($srcdir, catfile("Configurations", "common.tmpl"), - $blddir) ]; + $build_file_template ]; - my @build_infos = ( [ ".", "build.info" ] ); - foreach (@{$config{dirs}}) { - push @build_infos, [ $_, "build.info" ] - if (-f catfile($srcdir, $_, "build.info")); - } - foreach (@{$config{sdirs}}) { - push @build_infos, [ catdir("crypto", $_), "build.info" ] - if (-f catfile($srcdir, "crypto", $_, "build.info")); - } - foreach (@{$config{engdirs}}) { - push @build_infos, [ catdir("engines", $_), "build.info" ] - if (-f catfile($srcdir, "engines", $_, "build.info")); - } - foreach (@{$config{tdirs}}) { - push @build_infos, [ catdir("test", $_), "build.info" ] - if (-f catfile($srcdir, "test", $_, "build.info")); - } + my @build_dirs = ( [ ] ); # current directory $config{build_infos} = [ ]; + # We want to detect configdata.pm in the source tree, so we + # don't use it if the build tree is different. + my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir); + + # Any source file that we recognise is placed in this hash table, with + # the list of its intended destinations as value. When everything has + # been collected, there's a routine that checks that these source files + # exist, or if they are generated, that the generator exists. + my %check_exist = (); + my %check_generate = (); + my %ordinals = (); - foreach (@build_infos) { - my $sourced = catdir($srcdir, $_->[0]); - my $buildd = catdir($blddir, $_->[0]); + while (@build_dirs) { + my @curd = @{shift @build_dirs}; + my $sourced = catdir($srcdir, @curd); + my $buildd = catdir($blddir, @curd); + + my $unixdir = join('/', @curd); + if (exists $skipdir{$unixdir}) { + my $what = $skipdir{$unixdir}; + push @{$disabled_info{$what}->{skipped}}, catdir(@curd); + next; + } mkpath($buildd); - my $f = $_->[1]; + my $f = 'build.info'; # The basic things we're trying to build my @programs = (); - my @programs_install = (); my @libraries = (); - my @libraries_install = (); - my @engines = (); - my @engines_install = (); + my @modules = (); my @scripts = (); - my @scripts_install = (); - my @extra = (); - my @overrides = (); - my @intermediates = (); - my @rawlines = (); my %sources = (); my %shared_sources = (); my %includes = (); + my %defines = (); my %depends = (); - my %renames = (); - my %sharednames = (); my %generate = (); + my %imagedocs = (); + my %htmldocs = (); + my %mandocs = (); + + # Support for $variablename in build.info files. + # Embedded perl code is the ultimate master, still. If its output + # contains a dollar sign, it had better be escaped, or it will be + # taken for a variable name prefix. + my %variables = (); + # Variable name syntax + my $variable_name_re = qr/(?P[[:alpha:]][[:alnum:]_]*)/; + # Value modifier syntaxes + my $variable_subst_re = qr/\/(?P(?:\\\/|.)*?)\/(?P.*?)/; + # Variable reference + my $variable_simple_re = qr/(?(?:\\\/|.)*?)\}/; + # Tie it all together + my $variable_re = qr/${variable_simple_re}|${variable_w_mod_re}/; + + my $expand_variables = sub { + my $value = ''; + my $value_rest = shift; + + if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) { + print STDERR + "DEBUG[\$expand_variables] Parsed '$value_rest' ...\n" + } + + while ($value_rest =~ /${variable_re}/) { + # We must save important regexp values, because the next + # regexp clears them + my $mod = $+{MOD}; + my $variable_value = $variables{$+{VARIABLE}}; + + $value_rest = $'; + $value .= $`; - # We want to detect configdata.pm in the source tree, so we - # don't use it if the build tree is different. - my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir); + # Process modifier expressions, if present + if (defined $mod) { + if ($mod =~ /^${variable_subst_re}$/) { + my $re = $+{RE}; + my $subst = $+{SUBST}; + $variable_value =~ s/\Q$re\E/$subst/g; + + if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) { + print STDERR + "DEBUG[\$expand_variables] ... and substituted ", + "'$re' with '$subst'\n"; + } + } + } + + $value .= $variable_value; + } + if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) { + print STDERR + "DEBUG[\$expand_variables] ... into: '$value$value_rest'\n"; + } + return $value . $value_rest; + }; + + # Support for attributes in build.info files + my %attributes = (); + my $handle_attributes = sub { + my $attr_str = shift; + my $ref = shift; + my @goals = @_; + + return unless defined $attr_str; + + my @a = tokenize($attr_str, qr|\s*,\s*|); + foreach my $a (@a) { + my $ac = 1; + my $ak = $a; + my $av = 1; + if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|x) { + $ac = ! $1; + $ak = $2; + $av = $3; + } + foreach my $g (@goals) { + if ($ac) { + $$ref->{$g}->{$ak} = $av; + } else { + delete $$ref->{$g}->{$ak}; + } + } + } + }; + + # Support for pushing values on multiple indexes of a given hash + # array. + my $push_to = sub { + my $valueref = shift; + my $index_str = shift; # May be undef or empty + my $attrref = shift; # May be undef + my $attr_str = shift; + my @values = @_; + + if (defined $index_str) { + my @indexes = ( '' ); + if ($index_str !~ m|^\s*$|) { + @indexes = tokenize($index_str); + } + foreach (@indexes) { + push @{$valueref->{$_}}, @values; + if (defined $attrref) { + $handle_attributes->($attr_str, \$$attrref->{$_}, + @values); + } + } + } else { + push @$valueref, @values; + $handle_attributes->($attr_str, $attrref, @values) + if defined $attrref; + } + }; + + if ($buildinfo_debug) { + print STDERR "DEBUG: Reading ",catfile($sourced, $f),"\n"; + } push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f); my $template = Text::Template->new(TYPE => 'FILE', @@ -1860,117 +2096,118 @@ if ($builder eq "unified") { # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF) # 2 positive ELSE (following ELSIF should fail) my @skip = (); + + # A few useful generic regexps + my $index_re = qr/\[\s*(?P(?:\\.|.)*?)\s*\]/; + my $cond_re = qr/\[\s*(?P(?:\\.|.)*?)\s*\]/; + my $attribs_re = qr/(?:\{\s*(?P(?:\\.|.)*?)\s*\})?/; + my $value_re = qr/(?P.*?)/; collect_information( collect_from_array([ @text ], qr/\\$/ => sub { my $l1 = shift; my $l2 = shift; $l1 =~ s/\\$//; $l1.$l2 }), # Info we're looking for - qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/ + qr/^\s* IF ${cond_re} \s*$/x => sub { if (! @skip || $skip[$#skip] > 0) { - push @skip, !! $1; + push @skip, !! $expand_variables->($+{COND}); } else { push @skip, -1; } }, - qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/ + qr/^\s* ELSIF ${cond_re} \s*$/x => sub { die "ELSIF out of scope" if ! @skip; die "ELSIF following ELSE" if abs($skip[$#skip]) == 2; $skip[$#skip] = -1 if $skip[$#skip] != 0; - $skip[$#skip] = !! $1 + $skip[$#skip] = !! $expand_variables->($+{COND}) if $skip[$#skip] == 0; }, - qr/^\s*ELSE\s*$/ + qr/^\s* ELSE \s*$/x => sub { die "ELSE out of scope" if ! @skip; $skip[$#skip] = -2 if $skip[$#skip] != 0; $skip[$#skip] = 2 if $skip[$#skip] == 0; }, - qr/^\s*ENDIF\s*$/ + qr/^\s* ENDIF \s*$/x => sub { die "ENDIF out of scope" if ! @skip; pop @skip; }, - qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/ + qr/^\s* ${variable_re} \s* = \s* ${value_re} \s* $/x => sub { if (!@skip || $skip[$#skip] > 0) { - my $install = $1; - my @x = tokenize($2); - push @programs, @x; - push @programs_install, @x unless $install; + $variables{$+{VARIABLE}} = $expand_variables->($+{VALUE}); } }, - qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/ + qr/^\s* SUBDIRS \s* = \s* ${value_re} \s* $/x => sub { if (!@skip || $skip[$#skip] > 0) { - my $install = $1; - my @x = tokenize($2); - push @libraries, @x; - push @libraries_install, @x unless $install; - } - }, - qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/ - => sub { - if (!@skip || $skip[$#skip] > 0) { - my $install = $1; - my @x = tokenize($2); - push @engines, @x; - push @engines_install, @x unless $install; - } - }, - qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/ - => sub { - if (!@skip || $skip[$#skip] > 0) { - my $install = $1; - my @x = tokenize($2); - push @scripts, @x; - push @scripts_install, @x unless $install; - } - }, - qr/^\s*EXTRA\s*=\s*(.*)\s*$/ - => sub { push @extra, tokenize($1) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/ - => sub { push @overrides, tokenize($1) - if !@skip || $skip[$#skip] > 0 }, - - qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/, - => sub { push @{$ordinals{$1}}, tokenize($2) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$sources{$1}}, tokenize($2) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$shared_sources{$1}}, tokenize($2) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$includes{$1}}, tokenize($2) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/ - => sub { push @{$depends{$1}}, tokenize($2) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$generate{$1}}, $2 - if !@skip || $skip[$#skip] > 0 }, - qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$renames{$1}}, tokenize($2) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ - => sub { push @{$sharednames{$1}}, tokenize($2) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/ - => sub { - my $lineiterator = shift; - my $target_kind = $1; - while (defined $lineiterator->()) { - s|\R$||; - if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) { - die "ENDRAW doesn't match BEGINRAW" - if $1 ne $target_kind; - last; + foreach (tokenize($expand_variables->($+{VALUE}))) { + push @build_dirs, [ @curd, splitdir($_, 1) ]; } - next if @skip && $skip[$#skip] <= 0; - push @rawlines, $_ - if ($target_kind eq $config{build_file} - || $target_kind eq $config{build_file}."(".$builder_platform.")"); } }, - qr/^\s*(?:#.*)?$/ => sub { }, + qr/^\s* PROGRAMS ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\@programs, undef, + \$attributes{programs}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* LIBS ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\@libraries, undef, + \$attributes{libraries}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* MODULES ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\@modules, undef, + \$attributes{modules}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* SCRIPTS ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\@scripts, undef, + \$attributes{scripts}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* IMAGEDOCS ${index_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%imagedocs, $expand_variables->($+{INDEX}), + undef, undef, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* HTMLDOCS ${index_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%htmldocs, $expand_variables->($+{INDEX}), + undef, undef, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* MANDOCS ${index_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%mandocs, $expand_variables->($+{INDEX}), + undef, undef, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%sources, $expand_variables->($+{INDEX}), + \$attributes{sources}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* SHARED_SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%shared_sources, $expand_variables->($+{INDEX}), + \$attributes{sources}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* INCLUDE ${index_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%includes, $expand_variables->($+{INDEX}), + undef, undef, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* DEFINE ${index_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%defines, $expand_variables->($+{INDEX}), + undef, undef, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* DEPEND ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%depends, $expand_variables->($+{INDEX}), + \$attributes{depends}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* GENERATE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%generate, $expand_variables->($+{INDEX}), + \$attributes{generate}, $+{ATTRIBS}, + $expand_variables->($+{VALUE})) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* (?:\#.*)? $/x => sub { }, "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }, "BEFORE" => sub { if ($buildinfo_debug) { @@ -1986,269 +2223,200 @@ if ($builder eq "unified") { ); die "runaway IF?" if (@skip); - foreach (keys %renames) { - die "$_ renamed to more than one thing: " - ,join(" ", @{$renames{$_}}),"\n" - if scalar @{$renames{$_}} > 1; - my $dest = cleanfile($buildd, $_, $blddir); - my $to = cleanfile($buildd, $renames{$_}->[0], $blddir); - die "$dest renamed to more than one thing: " - ,$unified_info{rename}->{$dest}, $to - unless !defined($unified_info{rename}->{$dest}) - or $unified_info{rename}->{$dest} eq $to; - $unified_info{rename}->{$dest} = $to; - } - - foreach (@programs) { - my $program = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$program}) { - $program = $unified_info{rename}->{$program}; - } - $unified_info{programs}->{$program} = 1; - } - - foreach (@programs_install) { - my $program = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$program}) { - $program = $unified_info{rename}->{$program}; - } - $unified_info{install}->{programs}->{$program} = 1; - } - - foreach (@libraries) { - my $library = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$library}) { - $library = $unified_info{rename}->{$library}; - } - $unified_info{libraries}->{$library} = 1; - } - - foreach (@libraries_install) { - my $library = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$library}) { - $library = $unified_info{rename}->{$library}; - } - $unified_info{install}->{libraries}->{$library} = 1; - } - - die <<"EOF" if scalar @engines and !$config{dynamic_engines}; + if (grep { defined $attributes{modules}->{$_}->{engine} } keys %attributes + and !$config{dynamic_engines}) { + die <<"EOF" ENGINES can only be used if configured with 'dynamic-engine'. This is usually a fault in a build.info file. EOF - foreach (@engines) { - my $library = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$library}) { - $library = $unified_info{rename}->{$library}; - } - $unified_info{engines}->{$library} = 1; - } - - foreach (@engines_install) { - my $library = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$library}) { - $library = $unified_info{rename}->{$library}; - } - $unified_info{install}->{engines}->{$library} = 1; - } - - foreach (@scripts) { - my $script = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$script}) { - $script = $unified_info{rename}->{$script}; - } - $unified_info{scripts}->{$script} = 1; - } - - foreach (@scripts_install) { - my $script = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$script}) { - $script = $unified_info{rename}->{$script}; - } - $unified_info{install}->{scripts}->{$script} = 1; } - foreach (@extra) { - my $extra = cleanfile($buildd, $_, $blddir); - $unified_info{extra}->{$extra} = 1; - } - - foreach (@overrides) { - my $override = cleanfile($buildd, $_, $blddir); - $unified_info{overrides}->{$override} = 1; - } - - push @{$unified_info{rawlines}}, @rawlines; - - unless ($disabled{shared}) { - # Check sharednames. - foreach (keys %sharednames) { - my $dest = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$dest}) { - $dest = $unified_info{rename}->{$dest}; - } - die "shared_name for $dest with multiple values: " - ,join(" ", @{$sharednames{$_}}),"\n" - if scalar @{$sharednames{$_}} > 1; - my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir); - die "shared_name found for a library $dest that isn't defined\n" - unless $unified_info{libraries}->{$dest}; - die "shared_name for $dest with multiple values: " - ,$unified_info{sharednames}->{$dest}, ", ", $to - unless !defined($unified_info{sharednames}->{$dest}) - or $unified_info{sharednames}->{$dest} eq $to; - $unified_info{sharednames}->{$dest} = $to; - } - - # Additionally, we set up sharednames for libraries that don't - # have any, as themselves. Only for libraries that aren't - # explicitly static. - foreach (grep !/\.a$/, keys %{$unified_info{libraries}}) { - if (!defined $unified_info{sharednames}->{$_}) { - $unified_info{sharednames}->{$_} = $_ + { + my %infos = ( programs => [ @programs ], + libraries => [ @libraries ], + modules => [ @modules ], + scripts => [ @scripts ] ); + foreach my $k (keys %infos) { + foreach (@{$infos{$k}}) { + my $item = cleanfile($buildd, $_, $blddir); + $unified_info{$k}->{$item} = 1; + + # Fix up associated attributes + $unified_info{attributes}->{$k}->{$item} = + $attributes{$k}->{$_} + if defined $attributes{$k}->{$_}; } } + } - # Check that we haven't defined any library as both shared and - # explicitly static. That is forbidden. - my @doubles = (); - foreach (grep /\.a$/, keys %{$unified_info{libraries}}) { - (my $l = $_) =~ s/\.a$//; - push @doubles, $l if defined $unified_info{sharednames}->{$l}; - } - die "these libraries are both explicitly static and shared:\n ", - join(" ", @doubles), "\n" - if @doubles; + # Check that we haven't defined any library as both shared and + # explicitly static. That is forbidden. + my @doubles = (); + foreach (grep /\.a$/, keys %{$unified_info{libraries}}) { + (my $l = $_) =~ s/\.a$//; + push @doubles, $l if defined $unified_info{libraries}->{$l}; } + die "these libraries are both explicitly static and shared:\n ", + join(" ", @doubles), "\n" + if @doubles; foreach (keys %sources) { my $dest = $_; my $ddest = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$ddest}) { - $ddest = $unified_info{rename}->{$ddest}; - } foreach (@{$sources{$dest}}) { my $s = cleanfile($sourced, $_, $blddir); - # If it isn't in the source tree, we assume it's generated - # in the build tree - if ($s eq $src_configdata || ! -f $s || $generate{$_}) { + # If it's generated or we simply don't find it in the source + # tree, we assume it's in the build tree. + if ($s eq $src_configdata || $generate{$_} || ! -f $s) { $s = cleanfile($buildd, $_, $blddir); } + my $o = $_; # We recognise C++, C and asm files if ($s =~ /\.(cc|cpp|c|s|S)$/) { - my $o = $_; + push @{$check_exist{$s}}, $ddest; $o =~ s/\.[csS]$/.o/; # C and assembler $o =~ s/\.(cc|cpp)$/_cc.o/; # C++ $o = cleanfile($buildd, $o, $blddir); - $unified_info{sources}->{$ddest}->{$o} = 1; - $unified_info{sources}->{$o}->{$s} = 1; + $unified_info{sources}->{$ddest}->{$o} = -1; + $unified_info{sources}->{$o}->{$s} = -1; } elsif ($s =~ /\.rc$/) { # We also recognise resource files - my $o = $_; + push @{$check_exist{$s}}, $ddest; $o =~ s/\.rc$/.res/; # Resource configuration - my $o = cleanfile($buildd, $o, $blddir); - $unified_info{sources}->{$ddest}->{$o} = 1; - $unified_info{sources}->{$o}->{$s} = 1; + $o = cleanfile($buildd, $o, $blddir); + $unified_info{sources}->{$ddest}->{$o} = -1; + $unified_info{sources}->{$o}->{$s} = -1; } else { + push @{$check_exist{$s}}, $ddest; $unified_info{sources}->{$ddest}->{$s} = 1; } + # Fix up associated attributes + if ($o ne $_) { + $unified_info{attributes}->{sources}->{$ddest}->{$o} = + $unified_info{attributes}->{sources}->{$o}->{$s} = + $attributes{sources}->{$dest}->{$_} + if defined $attributes{sources}->{$dest}->{$_}; + } else { + $unified_info{attributes}->{sources}->{$ddest}->{$s} = + $attributes{sources}->{$dest}->{$_} + if defined $attributes{sources}->{$dest}->{$_}; + } } } foreach (keys %shared_sources) { my $dest = $_; my $ddest = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$ddest}) { - $ddest = $unified_info{rename}->{$ddest}; - } foreach (@{$shared_sources{$dest}}) { my $s = cleanfile($sourced, $_, $blddir); - # If it isn't in the source tree, we assume it's generated - # in the build tree - if ($s eq $src_configdata || ! -f $s || $generate{$_}) { + # If it's generated or we simply don't find it in the source + # tree, we assume it's in the build tree. + if ($s eq $src_configdata || $generate{$_} || ! -f $s) { $s = cleanfile($buildd, $_, $blddir); } + my $o = $_; if ($s =~ /\.(cc|cpp|c|s|S)$/) { # We recognise C++, C and asm files - my $o = $_; + push @{$check_exist{$s}}, $ddest; $o =~ s/\.[csS]$/.o/; # C and assembler $o =~ s/\.(cc|cpp)$/_cc.o/; # C++ $o = cleanfile($buildd, $o, $blddir); - $unified_info{shared_sources}->{$ddest}->{$o} = 1; - $unified_info{sources}->{$o}->{$s} = 1; + $unified_info{shared_sources}->{$ddest}->{$o} = -1; + $unified_info{sources}->{$o}->{$s} = -1; } elsif ($s =~ /\.rc$/) { # We also recognise resource files - my $o = $_; + push @{$check_exist{$s}}, $ddest; $o =~ s/\.rc$/.res/; # Resource configuration - my $o = cleanfile($buildd, $o, $blddir); - $unified_info{shared_sources}->{$ddest}->{$o} = 1; - $unified_info{sources}->{$o}->{$s} = 1; - } elsif ($s =~ /\.(def|map|opt)$/) { - # We also recognise .def / .map / .opt files + $o = cleanfile($buildd, $o, $blddir); + $unified_info{shared_sources}->{$ddest}->{$o} = -1; + $unified_info{sources}->{$o}->{$s} = -1; + } elsif ($s =~ /\.ld$/) { + # We also recognise linker scripts (or corresponding) # We know they are generated files - my $def = cleanfile($buildd, $s, $blddir); - $unified_info{shared_sources}->{$ddest}->{$def} = 1; + push @{$check_exist{$s}}, $ddest; + $o = cleanfile($buildd, $_, $blddir); + $unified_info{shared_sources}->{$ddest}->{$o} = 1; } else { die "unrecognised source file type for shared library: $s\n"; } + # Fix up associated attributes + if ($o ne $_) { + $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} = + $unified_info{attributes}->{sources}->{$o}->{$s} = + $attributes{sources}->{$dest}->{$_} + if defined $attributes{sources}->{$dest}->{$_}; + } else { + $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} = + $attributes{sources}->{$dest}->{$_} + if defined $attributes{sources}->{$dest}->{$_}; + } } } foreach (keys %generate) { my $dest = $_; my $ddest = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$ddest}) { - $ddest = $unified_info{rename}->{$ddest}; - } die "more than one generator for $dest: " - ,join(" ", @{$generate{$_}}),"\n" - if scalar @{$generate{$_}} > 1; + ,join(" ", @{$generate{$_}}),"\n" + if scalar @{$generate{$_}} > 1; my @generator = split /\s+/, $generate{$dest}->[0]; - $generator[0] = cleanfile($sourced, $generator[0], $blddir), + my $gen = $generator[0]; + $generator[0] = cleanfile($sourced, $gen, $blddir); + + # If the generator is itself generated, it's in the build tree + if ($generate{$gen} || ! -f $generator[0]) { + $generator[0] = cleanfile($buildd, $gen, $blddir); + } + $check_generate{$ddest}->{$generator[0]}++; + $unified_info{generate}->{$ddest} = [ @generator ]; + # Fix up associated attributes + $unified_info{attributes}->{generate}->{$ddest} = + $attributes{generate}->{$dest}->{$gen} + if defined $attributes{generate}->{$dest}->{$gen}; } foreach (keys %depends) { my $dest = $_; - my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir); + my $ddest = $dest; + + if ($dest =~ /^\|(.*)\|$/) { + # Collect the raw target + $unified_info{targets}->{$1} = 1; + $ddest = $1; + } elsif ($dest eq '') { + $ddest = ''; + } else { + $ddest = cleanfile($sourced, $_, $blddir); - # If the destination doesn't exist in source, it can only be - # a generated file in the build tree. - if ($ddest ne "" && ($ddest eq $src_configdata || ! -f $ddest)) { - $ddest = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$ddest}) { - $ddest = $unified_info{rename}->{$ddest}; + # If the destination doesn't exist in source, it can only be + # a generated file in the build tree. + if ($ddest eq $src_configdata || ! -f $ddest) { + $ddest = cleanfile($buildd, $_, $blddir); } } foreach (@{$depends{$dest}}) { my $d = cleanfile($sourced, $_, $blddir); + my $d2 = cleanfile($buildd, $_, $blddir); # If we know it's generated, or assume it is because we can't # find it in the source tree, we set file we depend on to be - # in the build tree rather than the source tree, and assume - # and that there are lines to build it in a BEGINRAW..ENDRAW - # section or in the Makefile template. + # in the build tree rather than the source tree. if ($d eq $src_configdata - || ! -f $d - || (grep { $d eq $_ } - map { cleanfile($srcdir, $_, $blddir) } - grep { /\.h$/ } keys %{$unified_info{generate}})) { - $d = cleanfile($buildd, $_, $blddir); - } - # Take note if the file to depend on is being renamed - # Take extra care with files ending with .a, they should - # be treated without that extension, and the extension - # should be added back after treatment. - $d =~ /(\.a)?$/; - my $e = $1 // ""; - $d = $`; - if ($unified_info{rename}->{$d}) { - $d = $unified_info{rename}->{$d}; + || (grep { $d2 eq $_ } + keys %{$unified_info{generate}}) + || ! -f $d) { + $d = $d2; } - $d .= $e; $unified_info{depends}->{$ddest}->{$d} = 1; + + # Fix up associated attributes + $unified_info{attributes}->{depends}->{$ddest}->{$d} = + $attributes{depends}->{$dest}->{$_} + if defined $attributes{depends}->{$dest}->{$_}; } } @@ -2260,9 +2428,6 @@ EOF # a generated file in the build tree. if ($ddest eq $src_configdata || ! -f $ddest) { $ddest = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$ddest}) { - $ddest = $unified_info{rename}->{$ddest}; - } } foreach (@{$includes{$dest}}) { my $is = cleandir($sourced, $_, $blddir); @@ -2273,6 +2438,54 @@ EOF unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}}; } } + + foreach my $dest (keys %defines) { + my $ddest; + + if ($dest ne "") { + $ddest = cleanfile($sourced, $dest, $blddir); + + # If the destination doesn't exist in source, it can only + # be a generated file in the build tree. + if (! -f $ddest) { + $ddest = cleanfile($buildd, $dest, $blddir); + } + } + foreach my $v (@{$defines{$dest}}) { + $v =~ m|^([^=]*)(=.*)?$|; + die "0 length macro name not permitted\n" if $1 eq ""; + if ($dest ne "") { + die "$1 defined more than once\n" + if defined $unified_info{defines}->{$ddest}->{$1}; + $unified_info{defines}->{$ddest}->{$1} = $2; + } else { + die "$1 defined more than once\n" + if grep { $v eq $_ } @{$config{defines}}; + push @{$config{defines}}, $v; + } + } + } + + foreach my $section (keys %imagedocs) { + foreach (@{$imagedocs{$section}}) { + my $imagedocs = cleanfile($buildd, $_, $blddir); + $unified_info{imagedocs}->{$section}->{$imagedocs} = 1; + } + } + + foreach my $section (keys %htmldocs) { + foreach (@{$htmldocs{$section}}) { + my $htmldocs = cleanfile($buildd, $_, $blddir); + $unified_info{htmldocs}->{$section}->{$htmldocs} = 1; + } + } + + foreach my $section (keys %mandocs) { + foreach (@{$mandocs{$section}}) { + my $mandocs = cleanfile($buildd, $_, $blddir); + $unified_info{mandocs}->{$section}->{$mandocs} = 1; + } + } } my $ordinals_text = join(', ', sort keys %ordinals); @@ -2283,18 +2496,90 @@ They are ignored and should be replaced with a combination of GENERATE, DEPEND and SHARED_SOURCE. EOF - # Massage the result + # Check that each generated file is only generated once + my $ambiguous_generation = 0; + foreach (sort keys %check_generate) { + my @generators = sort keys %{$check_generate{$_}}; + my $generators_txt = join(', ', @generators); + if (scalar @generators > 1) { + warn "$_ is GENERATEd by more than one generator ($generators_txt)\n"; + $ambiguous_generation++; + } + if ($check_generate{$_}->{$generators[0]} > 1) { + warn "INFO: $_ has more than one GENERATE declaration (same generator)\n" + } + } + die "There are ambiguous source file generations\n" + if $ambiguous_generation > 0; + + # All given source files should exist, or if generated, their + # generator should exist. This loop ensures this is true. + my $missing = 0; + foreach my $orig (sort keys %check_exist) { + foreach my $dest (@{$check_exist{$orig}}) { + if ($orig ne $src_configdata) { + if ($orig =~ /\.a$/) { + # Static library names may be used as sources, so we + # need to detect those and give them special treatment. + unless (grep { $_ eq $orig } + keys %{$unified_info{libraries}}) { + warn "$orig is given as source for $dest, but no such library is built\n"; + $missing++; + } + } else { + # A source may be generated, and its generator may be + # generated as well. We therefore loop to dig out the + # first generator. + my $gen = $orig; - # If the user configured no-shared, we allow no shared sources - if ($disabled{shared}) { - foreach (keys %{$unified_info{shared_sources}}) { - foreach (keys %{$unified_info{shared_sources}->{$_}}) { - delete $unified_info{sources}->{$_}; + while (my @next = keys %{$check_generate{$gen}}) { + $gen = $next[0]; + } + + if (! -f $gen) { + if ($gen ne $orig) { + $missing++; + warn "$orig is given as source for $dest, but its generator (leading to $gen) is missing\n"; + } else { + $missing++; + warn "$orig is given as source for $dest, but is missing\n"; + } + } + } + } + } + } + die "There are files missing\n" if $missing > 0; + + # Go through the sources of all libraries and check that the same basename + # doesn't appear more than once. Some static library archivers depend on + # them being unique. + { + my $err = 0; + foreach my $prod (keys %{$unified_info{libraries}}) { + my @prod_sources = + map { keys %{$unified_info{sources}->{$_}} } + keys %{$unified_info{sources}->{$prod}}; + my %srccnt = (); + + # Count how many times a given each source basename + # appears for each product. + foreach my $src (@prod_sources) { + $srccnt{basename $src}++; + } + + foreach my $src (keys %srccnt) { + if ((my $cnt = $srccnt{$src}) > 1) { + print STDERR "$src appears $cnt times for the product $prod\n"; + $err++ + } } } - $unified_info{shared_sources} = {}; + die if $err > 0; } + # Massage the result + # If we depend on a header file or a perl module, add an inclusion of # its directory to allow smoothe inclusion foreach my $dest (keys %{$unified_info{depends}}) { @@ -2310,38 +2595,144 @@ EOF } } - # Trickle down includes placed on libraries, engines and programs to - # their sources (i.e. object files) - foreach my $dest (keys %{$unified_info{engines}}, - keys %{$unified_info{libraries}}, - keys %{$unified_info{programs}}) { - foreach my $k (("source", "build")) { - next unless defined($unified_info{includes}->{$dest}->{$k}); - my @incs = reverse @{$unified_info{includes}->{$dest}->{$k}}; - foreach my $obj (grep /\.o$/, - (keys %{$unified_info{sources}->{$dest} // {}}, - keys %{$unified_info{shared_sources}->{$dest} // {}})) { - foreach my $inc (@incs) { - unshift @{$unified_info{includes}->{$obj}->{$k}}, $inc - unless grep { $_ eq $inc } @{$unified_info{includes}->{$obj}->{$k}}; + # Go through all intermediary files and change their names to something that + # reflects what they will be built for. Note that for some source files, + # this leads to duplicate object files because they are used multiple times. + # the goal is to rename all object files according to this scheme: + # {productname}-{midfix}-{origobjname}.[o|res] + # the {midfix} is a keyword indicating the type of product, which is mostly + # valuable for libraries since they come in two forms. + # + # This also reorganises the {sources} and {shared_sources} so that the + # former only contains ALL object files that are supposed to end up in + # static libraries and programs, while the latter contains ALL object files + # that are supposed to end up in shared libraries and DSOs. + # The main reason for having two different source structures is to allow + # the same name to be used for the static and the shared variants of a + # library. + { + # Take copies so we don't get interference from added stuff + my %unified_copy = (); + foreach (('sources', 'shared_sources')) { + $unified_copy{$_} = { %{$unified_info{$_}} } + if defined($unified_info{$_}); + delete $unified_info{$_}; + } + foreach my $prodtype (('programs', 'libraries', 'modules', 'scripts')) { + # $intent serves multi purposes: + # - give a prefix for the new object files names + # - in the case of libraries, rearrange the object files so static + # libraries use the 'sources' structure exclusively, while shared + # libraries use the 'shared_sources' structure exclusively. + my $intent = { + programs => { bin => { src => [ 'sources' ], + dst => 'sources' } }, + libraries => { lib => { src => [ 'sources' ], + dst => 'sources' }, + shlib => { prodselect => + sub { grep !/\.a$/, @_ }, + src => [ 'sources', + 'shared_sources' ], + dst => 'shared_sources' } }, + modules => { dso => { src => [ 'sources' ], + dst => 'sources' } }, + scripts => { script => { src => [ 'sources' ], + dst => 'sources' } } + } -> {$prodtype}; + foreach my $kind (keys %$intent) { + next if ($intent->{$kind}->{dst} eq 'shared_sources' + && $disabled{shared}); + + my @src = @{$intent->{$kind}->{src}}; + my $dst = $intent->{$kind}->{dst}; + my $prodselect = $intent->{$kind}->{prodselect} // sub { @_ }; + foreach my $prod ($prodselect->(keys %{$unified_info{$prodtype}})) { + # %prod_sources has all applicable objects as keys, and + # their corresponding sources as values + my %prod_sources = + map { $_ => [ keys %{$unified_copy{sources}->{$_}} ] } + map { keys %{$unified_copy{$_}->{$prod}} } + @src; + foreach (keys %prod_sources) { + # Only affect object files and resource files, + # the others simply get a new value + # (+1 instead of -1) + if ($_ =~ /\.(o|res)$/) { + (my $prodname = $prod) =~ s|\.a$||; + my $newobj = + catfile(dirname($_), + basename($prodname) + . '-' . $kind + . '-' . basename($_)); + $unified_info{$dst}->{$prod}->{$newobj} = 1; + foreach my $src (@{$prod_sources{$_}}) { + $unified_info{sources}->{$newobj}->{$src} = 1; + # Adjust source attributes + my $attrs = $unified_info{attributes}->{sources}; + if (defined $attrs->{$prod} + && defined $attrs->{$prod}->{$_}) { + $attrs->{$prod}->{$newobj} = + $attrs->{$prod}->{$_}; + delete $attrs->{$prod}->{$_}; + } + foreach my $objsrc (keys %{$attrs->{$_} // {}}) { + $attrs->{$newobj}->{$objsrc} = + $attrs->{$_}->{$objsrc}; + delete $attrs->{$_}->{$objsrc}; + } + } + # Adjust dependencies + foreach my $deps (keys %{$unified_info{depends}->{$_}}) { + $unified_info{depends}->{$_}->{$deps} = -1; + $unified_info{depends}->{$newobj}->{$deps} = 1; + } + # Adjust includes + foreach my $k (('source', 'build')) { + next unless + defined($unified_info{includes}->{$_}->{$k}); + my @incs = @{$unified_info{includes}->{$_}->{$k}}; + $unified_info{includes}->{$newobj}->{$k} = [ @incs ]; + } + } else { + $unified_info{$dst}->{$prod}->{$_} = 1; + } + } } } } - delete $unified_info{includes}->{$dest}; } + # At this point, we have a number of sources with the value -1. They + # aren't part of the local build and are probably meant for a different + # platform, and can therefore be cleaned away. That happens when making + # %unified_info more efficient below. + ### Make unified_info a bit more efficient # One level structures - foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) { + foreach (("programs", "libraries", "modules", "scripts", "targets")) { $unified_info{$_} = [ sort keys %{$unified_info{$_}} ]; } # Two level structures - foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) { + foreach my $l1 (("sources", "shared_sources", "ldadd", "depends", + "imagedocs", "htmldocs", "mandocs")) { foreach my $l2 (sort keys %{$unified_info{$l1}}) { - $unified_info{$l1}->{$l2} = - [ sort keys %{$unified_info{$l1}->{$l2}} ]; + my @items = + sort + grep { $unified_info{$l1}->{$l2}->{$_} > 0 } + keys %{$unified_info{$l1}->{$l2}}; + if (@items) { + $unified_info{$l1}->{$l2} = [ @items ]; + } else { + delete $unified_info{$l1}->{$l2}; + } } } + # Defines + foreach my $dest (sort keys %{$unified_info{defines}}) { + $unified_info{defines}->{$dest} + = [ map { $_.$unified_info{defines}->{$dest}->{$_} } + sort keys %{$unified_info{defines}->{$dest}} ]; + } # Includes foreach my $dest (sort keys %{$unified_info{includes}}) { if (defined($unified_info{includes}->{$dest}->{build})) { @@ -2354,9 +2745,11 @@ EOF push @{$unified_info{includes}->{$dest}}, $inc unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}}; } - } else { + } elsif (defined($unified_info{includes}->{$dest}->{source})) { $unified_info{includes}->{$dest} = [ @{$unified_info{includes}->{$dest}->{source}} ]; + } else { + delete $unified_info{includes}->{$dest}; } } @@ -2365,10 +2758,16 @@ EOF # they end up in where applicable. Then, add build rules for those # directories my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ], - "dso" => [ @{$unified_info{engines}} ], + "dso" => [ @{$unified_info{modules}} ], "bin" => [ @{$unified_info{programs}} ], - "script" => [ @{$unified_info{scripts}} ] ); - foreach my $type (keys %loopinfo) { + "script" => [ @{$unified_info{scripts}} ], + "docs" => [ (map { @{$unified_info{imagedocs}->{$_} // []} } + keys %{$unified_info{imagedocs} // {}}), + (map { @{$unified_info{htmldocs}->{$_} // []} } + keys %{$unified_info{htmldocs} // {}}), + (map { @{$unified_info{mandocs}->{$_} // []} } + keys %{$unified_info{mandocs} // {}}) ] ); + foreach my $type (sort keys %loopinfo) { foreach my $product (@{$loopinfo{$type}}) { my %dirs = (); my $pd = dirname($product); @@ -2389,7 +2788,7 @@ EOF push @{$unified_info{dirinfo}->{$d}->{deps}}, $_ if $d ne $pd; } - foreach (keys %dirs) { + foreach (sort keys %dirs) { push @{$unified_info{dirinfo}->{$_}->{products}->{$type}}, $product; } @@ -2409,446 +2808,51 @@ foreach (grep /_(asm|aux)_src$/, keys %target) { # Write down our configuration where it fits ######################### -print "Creating configdata.pm\n"; -open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n"; -print OUT <<"EOF"; -#! $config{HASHBANGPERL} - -package configdata; - -use strict; -use warnings; - -use Exporter; -#use vars qw(\@ISA \@EXPORT); -our \@ISA = qw(Exporter); -our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables); - -EOF -print OUT "our %config = (\n"; -foreach (sort keys %config) { - if (ref($config{$_}) eq "ARRAY") { - print OUT " ", $_, " => [ ", join(", ", - map { quotify("perl", $_) } - @{$config{$_}}), " ],\n"; - } elsif (ref($config{$_}) eq "HASH") { - print OUT " ", $_, " => {"; - if (scalar keys %{$config{$_}} > 0) { - print OUT "\n"; - foreach my $key (sort keys %{$config{$_}}) { - print OUT " ", - join(" => ", - quotify("perl", $key), - defined $config{$_}->{$key} - ? quotify("perl", $config{$_}->{$key}) - : "undef"); - print OUT ",\n"; - } - print OUT " "; - } - print OUT "},\n"; - } else { - print OUT " ", $_, " => ", quotify("perl", $config{$_}), ",\n" - } -} -print OUT <<"EOF"; -); - -EOF -print OUT "our %target = (\n"; -foreach (sort keys %target) { - if (ref($target{$_}) eq "ARRAY") { - print OUT " ", $_, " => [ ", join(", ", - map { quotify("perl", $_) } - @{$target{$_}}), " ],\n"; - } else { - print OUT " ", $_, " => ", quotify("perl", $target{$_}), ",\n" - } -} -print OUT <<"EOF"; -); - -EOF -print OUT "our \%available_protocols = (\n"; -print OUT " tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n"; -print OUT " dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n"; -print OUT <<"EOF"; -); - -EOF -print OUT "our \@disablables = (\n"; -foreach (@disablables) { - print OUT " ", quotify("perl", $_), ",\n"; -} -print OUT <<"EOF"; -); - -EOF -print OUT "our \%disabled = (\n"; -foreach (sort keys %disabled) { - print OUT " ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n"; -} -print OUT <<"EOF"; -); - -EOF -print OUT "our %withargs = (\n"; -foreach (sort keys %withargs) { - if (ref($withargs{$_}) eq "ARRAY") { - print OUT " ", $_, " => [ ", join(", ", - map { quotify("perl", $_) } - @{$withargs{$_}}), " ],\n"; - } else { - print OUT " ", $_, " => ", quotify("perl", $withargs{$_}), ",\n" - } -} -print OUT <<"EOF"; -); - -EOF -if ($builder eq "unified") { - my $recurse; - $recurse = sub { - my $indent = shift; - foreach (@_) { - if (ref $_ eq "ARRAY") { - print OUT " "x$indent, "[\n"; - foreach (@$_) { - $recurse->($indent + 4, $_); - } - print OUT " "x$indent, "],\n"; - } elsif (ref $_ eq "HASH") { - my %h = %$_; - print OUT " "x$indent, "{\n"; - foreach (sort keys %h) { - if (ref $h{$_} eq "") { - print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n"; - } else { - print OUT " "x($indent + 4), quotify("perl", $_), " =>\n"; - $recurse->($indent + 8, $h{$_}); - } - } - print OUT " "x$indent, "},\n"; - } else { - print OUT " "x$indent, quotify("perl", $_), ",\n"; - } - } - }; - print OUT "our %unified_info = (\n"; - foreach (sort keys %unified_info) { - if (ref $unified_info{$_} eq "") { - print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n"; - } else { - print OUT " "x4, quotify("perl", $_), " =>\n"; - $recurse->(8, $unified_info{$_}); - } - } - print OUT <<"EOF"; +my %template_vars = ( + config => \%config, + target => \%target, + disablables => \@disablables, + disablables_int => \@disablables_int, + disabled => \%disabled, + withargs => \%withargs, + unified_info => \%unified_info, + tls => \@tls, + dtls => \@dtls, + makevars => [ sort keys %user ], + disabled_info => \%disabled_info, + user_crossable => \@user_crossable, ); - -EOF -} -print OUT - "# The following data is only used when this files is use as a script\n"; -print OUT "my \@makevars = (\n"; -foreach (sort keys %user) { - print OUT " '",$_,"',\n"; -} -print OUT ");\n"; -print OUT "my \%disabled_info = (\n"; -foreach my $what (sort keys %disabled_info) { - print OUT " '$what' => {\n"; - foreach my $info (sort keys %{$disabled_info{$what}}) { - if (ref $disabled_info{$what}->{$info} eq 'ARRAY') { - print OUT " $info => [ ", - join(', ', map { "'$_'" } @{$disabled_info{$what}->{$info}}), - " ],\n"; - } else { - print OUT " $info => '", $disabled_info{$what}->{$info}, - "',\n"; - } - } - print OUT " },\n"; -} -print OUT ");\n"; -print OUT 'my @user_crossable = qw( ', join (' ', @user_crossable), " );\n"; -print OUT << 'EOF'; -# If run directly, we can give some answers, and even reconfigure -unless (caller) { - use Getopt::Long; - use File::Spec::Functions; - use File::Basename; - use Pod::Usage; - - my $here = dirname($0); - - my $dump = undef; - my $cmdline = undef; - my $options = undef; - my $target = undef; - my $envvars = undef; - my $makevars = undef; - my $buildparams = undef; - my $reconf = undef; - my $verbose = undef; - my $help = undef; - my $man = undef; - GetOptions('dump|d' => \$dump, - 'command-line|c' => \$cmdline, - 'options|o' => \$options, - 'target|t' => \$target, - 'environment|e' => \$envvars, - 'make-variables|m' => \$makevars, - 'build-parameters|b' => \$buildparams, - 'reconfigure|reconf|r' => \$reconf, - 'verbose|v' => \$verbose, - 'help' => \$help, - 'man' => \$man) - or die "Errors in command line arguments\n"; - - unless ($dump || $cmdline || $options || $target || $envvars || $makevars - || $buildparams || $reconf || $verbose || $help || $man) { - print STDERR <<"_____"; -You must give at least one option. -For more information, do '$0 --help' -_____ - exit(2); - } - - if ($help) { - pod2usage(-exitval => 0, - -verbose => 1); - } - if ($man) { - pod2usage(-exitval => 0, - -verbose => 2); - } - if ($dump || $cmdline) { - print "\nCommand line (with current working directory = $here):\n\n"; - print ' ',join(' ', - $config{PERL}, - catfile($config{sourcedir}, 'Configure'), - @{$config{perlargv}}), "\n"; - print "\nPerl information:\n\n"; - print ' ',$config{perl_cmd},"\n"; - print ' ',$config{perl_version},' for ',$config{perl_archname},"\n"; - } - if ($dump || $options) { - my $longest = 0; - my $longest2 = 0; - foreach my $what (@disablables) { - $longest = length($what) if $longest < length($what); - $longest2 = length($disabled{$what}) - if $disabled{$what} && $longest2 < length($disabled{$what}); - } - print "\nEnabled features:\n\n"; - foreach my $what (@disablables) { - print " $what\n" - unless grep { $_ =~ /^${what}$/ } keys %disabled; - } - print "\nDisabled features:\n\n"; - foreach my $what (@disablables) { - my @what2 = grep { $_ =~ /^${what}$/ } keys %disabled; - my $what3 = $what2[0]; - if ($what3) { - print " $what3", ' ' x ($longest - length($what3) + 1), - "[$disabled{$what3}]", ' ' x ($longest2 - length($disabled{$what3}) + 1); - print $disabled_info{$what3}->{macro} - if $disabled_info{$what3}->{macro}; - print ' (skip ', - join(', ', @{$disabled_info{$what3}->{skipped}}), - ')' - if $disabled_info{$what3}->{skipped}; - print "\n"; - } - } - } - if ($dump || $target) { - print "\nConfig target attributes:\n\n"; - foreach (sort keys %target) { - next if $_ =~ m|^_| || $_ eq 'template'; - my $quotify = sub { - map { (my $x = $_) =~ s|([\\\$\@"])|\\$1|g; "\"$x\""} @_; - }; - print ' ', $_, ' => '; - if (ref($target{$_}) eq "ARRAY") { - print '[ ', join(', ', $quotify->(@{$target{$_}})), " ],\n"; - } else { - print $quotify->($target{$_}), ",\n" - } - } - } - if ($dump || $envvars) { - print "\nRecorded environment:\n\n"; - foreach (sort keys %{$config{perlenv}}) { - print ' ',$_,' = ',($config{perlenv}->{$_} || ''),"\n"; - } - } - if ($dump || $makevars) { - print "\nMakevars:\n\n"; - foreach my $var (@makevars) { - my $prefix = ''; - $prefix = $config{CROSS_COMPILE} - if grep { $var eq $_ } @user_crossable; - $prefix //= ''; - print ' ',$var,' ' x (16 - length $var),'= ', - (ref $config{$var} eq 'ARRAY' - ? join(' ', @{$config{$var}}) - : $prefix.$config{$var}), - "\n" - if defined $config{$var}; - } - - my @buildfile = ($config{builddir}, $config{build_file}); - unshift @buildfile, $here - unless file_name_is_absolute($config{builddir}); - my $buildfile = canonpath(catdir(@buildfile)); - print <<"_____"; - -NOTE: These variables only represent the configuration view. The build file -template may have processed these variables further, please have a look at the -build file for more exact data: - $buildfile -_____ - } - if ($dump || $buildparams) { - my @buildfile = ($config{builddir}, $config{build_file}); - unshift @buildfile, $here - unless file_name_is_absolute($config{builddir}); - print "\nbuild file:\n\n"; - print " ", canonpath(catfile(@buildfile)),"\n"; - - print "\nbuild file templates:\n\n"; - foreach (@{$config{build_file_templates}}) { - my @tmpl = ($_); - unshift @tmpl, $here - unless file_name_is_absolute($config{sourcedir}); - print ' ',canonpath(catfile(@tmpl)),"\n"; - } - } - if ($reconf) { - if ($verbose) { - print 'Reconfiguring with: ', join(' ',@{$config{perlargv}}), "\n"; - foreach (sort keys %{$config{perlenv}}) { - print ' ',$_,' = ',($config{perlenv}->{$_} || ""),"\n"; - } - } - - chdir $here; - exec $^X,catfile($config{sourcedir}, 'Configure'),'reconf'; - } -} - -1; - -__END__ - -=head1 NAME - -configdata.pm - configuration data for OpenSSL builds - -=head1 SYNOPSIS - -Interactive: - - perl configdata.pm [options] - -As data bank module: - - use configdata; - -=head1 DESCRIPTION - -This module can be used in two modes, interactively and as a module containing -all the data recorded by OpenSSL's Configure script. - -When used interactively, simply run it as any perl script, with at least one -option, and you will get the information you ask for. See L below. - -When loaded as a module, you get a few databanks with useful information to -perform build related tasks. The databanks are: - - %config Configured things. - %target The OpenSSL config target with all inheritances - resolved. - %disabled The features that are disabled. - @disablables The list of features that can be disabled. - %withargs All data given through --with-THING options. - %unified_info All information that was computed from the build.info - files. - -=head1 OPTIONS - -=over 4 - -=item B<--help> - -Print a brief help message and exit. - -=item B<--man> - -Print the manual page and exit. - -=item B<--dump> | B<-d> - -Print all relevant configuration data. This is equivalent to B<--command-line> -B<--options> B<--target> B<--environment> B<--make-variables> -B<--build-parameters>. - -=item B<--command-line> | B<-c> - -Print the current configuration command line. - -=item B<--options> | B<-o> - -Print the features, both enabled and disabled, and display defined macro and -skipped directories where applicable. - -=item B<--target> | B<-t> - -Print the config attributes for this config target. - -=item B<--environment> | B<-e> - -Print the environment variables and their values at the time of configuration. - -=item B<--make-variables> | B<-m> - -Print the main make variables generated in the current configuration - -=item B<--build-parameters> | B<-b> - -Print the build parameters, i.e. build file and build file templates. - -=item B<--reconfigure> | B<--reconf> | B<-r> - -Redo the configuration. - -=item B<--verbose> | B<-v> - -Verbose output. - -=back - -=cut - -EOF -close(OUT); +my $configdata_outname = 'configdata.pm'; +open CONFIGDATA, ">$configdata_outname.new" + or die "Trying to create $configdata_outname.new: $!"; +my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir); +my $configdata_tmpl = + OpenSSL::Template->new(TYPE => 'FILE', SOURCE => $configdata_tmplname); +$configdata_tmpl->fill_in( + FILENAME => $configdata_tmplname, + OUTPUT => \*CONFIGDATA, + HASH => { %template_vars, + autowarntext => [ + 'WARNING: do not edit!', + "Generated by Configure from $configdata_tmplname", + ] } +) or die $Text::Template::ERROR; +close CONFIGDATA; + +rename "$configdata_outname.new", $configdata_outname; if ($builder_platform eq 'unix') { my $mode = (0755 & ~umask); chmod $mode, 'configdata.pm' or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!); } +print "Created $configdata_outname\n"; -my %builders = ( - unified => sub { - print 'Creating ',$config{build_file},"\n"; - run_dofile(catfile($blddir, $config{build_file}), - @{$config{build_file_templates}}); - }, - ); - -$builders{$builder}->($builder_platform, @builder_opts); +print "Running $configdata_outname\n"; +my $perlcmd = (quotify("maybeshell", $config{PERL}))[0]; +my $cmd = "$perlcmd $configdata_outname"; +#print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n"; +system($cmd); +exit 1 if $? != 0; $SIG{__DIE__} = $orig_death_handler; @@ -2856,7 +2860,7 @@ print <<"EOF" if ($disabled{threads} eq "unavailable"); The library could not be configured for supporting multi-threaded applications as the compiler options required on this system are not known. -See file INSTALL for details if you need multi-threading. +See file INSTALL.md for details if you need multi-threading. EOF print <<"EOF" if ($no_shared_warn); @@ -2868,23 +2872,7 @@ or position independent code, please let us know (but please first make sure you have tried with a current version of OpenSSL). EOF -print <<"EOF"; - -********************************************************************** -*** *** -*** OpenSSL has been successfully configured *** -*** *** -*** If you encounter a problem while building, please open an *** -*** issue on GitHub *** -*** and include the output from the following command: *** -*** *** -*** perl configdata.pm --dump *** -*** *** -*** (If you are new to OpenSSL, you might want to consult the *** -*** 'Troubleshooting' section in the INSTALL file first) *** -*** *** -********************************************************************** -EOF +print $banner; exit(0); @@ -2901,8 +2889,8 @@ sub death_handler { my @message = ( <<"_____", @_ ); Failure! $build_file wasn't produced. -Please read INSTALL and associated NOTES files. You may also have to look over -your available compiler tool chain or change your configuration. +Please read INSTALL.md and associated NOTES-* files. You may also have to +look over your available compiler tool chain or change your configuration. _____ @@ -2918,18 +2906,6 @@ _____ # Thus, whenever there's mention of a returned value, it's about that # intended value. -# Helper function to implement conditional inheritance depending on the -# value of $disabled{asm}. Used in inherit_from values as follows: -# -# inherit_from => [ "template", asm("asm_tmpl") ] -# -sub asm { - my @x = @_; - sub { - $disabled{asm} ? () : @x; - } -} - # Helper function to implement conditional value variants, with a default # plus additional values based on the value of $config{build_type}. # Arguments are given in hash table form: @@ -3247,28 +3223,9 @@ sub usage } print STDERR $i . " "; } - print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n"; exit(1); } -sub run_dofile -{ - my $out = shift; - my @templates = @_; - - unlink $out || warn "Can't remove $out, $!" - if -f $out; - foreach (@templates) { - die "Can't open $_, $!" unless -f $_; - } - my $perlcmd = (quotify("maybeshell", $config{PERL}))[0]; - my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\""; - #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n"; - system($cmd); - exit 1 if $? != 0; - rename("$out.new", $out) || die "Can't rename $out.new, $!"; -} - sub compiler_predefined { state %predefined; my $cc = shift; @@ -3350,31 +3307,13 @@ sub print_table_entry "includes", "cc", "cflags", - "unistd", "ld", "lflags", "loutflag", "ex_libs", "bn_ops", - "apps_aux_src", - "cpuid_asm_src", - "uplink_aux_src", - "bn_asm_src", - "ec_asm_src", - "des_asm_src", - "aes_asm_src", - "bf_asm_src", - "md5_asm_src", - "cast_asm_src", - "sha1_asm_src", - "rc4_asm_src", - "rmd160_asm_src", - "rc5_asm_src", - "wp_asm_src", - "cmll_asm_src", - "modes_asm_src", - "padlock_asm_src", - "chacha_asm_src", + "enable", + "disable", "poly1035_asm_src", "thread_scheme", "perlasm_scheme", @@ -3606,32 +3545,43 @@ sub collect_information { } # tokenize($line) +# tokenize($line,$separator) # $line is a line of text to split up into tokens -# returns a list of tokens +# $separator [optional] is a regular expression that separates the tokens, +# the default being spaces. Do not use quotes of any kind as separators, +# that will give undefined results. +# Returns a list of tokens. # -# Tokens are divided by spaces. If the tokens include spaces, they -# have to be quoted with single or double quotes. Double quotes -# inside a double quoted token must be escaped. Escaping is done +# Tokens are divided by separator (spaces by default). If the tokens include +# the separators, they have to be quoted with single or double quotes. +# Double quotes inside a double quoted token must be escaped. Escaping is done # with backslash. # Basically, the same quoting rules apply for " and ' as in any # Unix shell. sub tokenize { my $line = my $debug_line = shift; + my $separator = shift // qr|\s+|; my @result = (); - while ($line =~ s|^\s+||, $line ne "") { + if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) { + print STDERR "DEBUG[tokenize]: \$separator = $separator\n"; + } + + while ($line =~ s|^${separator}||, $line ne "") { my $token = ""; - while ($line ne "" && $line !~ m|^\s|) { - if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) { - $token .= $1; - $line = $'; - } elsif ($line =~ m/^'([^']*)'/) { - $token .= $1; - $line = $'; - } elsif ($line =~ m/^(\S+)/) { - $token .= $1; - $line = $'; - } + again: + $line =~ m/^(.*?)(${separator}|"|'|$)/; + $token .= $1; + $line = $2.$'; + + if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) { + $token .= $1; + $line = $'; + goto again; + } elsif ($line =~ m/^'([^']*)'/) { + $token .= $1; + $line = $'; + goto again; } push @result, $token; } diff --git a/crypto/openssl/FAQ b/crypto/openssl/FAQ deleted file mode 100644 index 22c5cf7dc2f3..000000000000 --- a/crypto/openssl/FAQ +++ /dev/null @@ -1,2 +0,0 @@ -The FAQ is now maintained on the web: - https://www.openssl.org/docs/faq.html diff --git a/crypto/openssl/FAQ.md b/crypto/openssl/FAQ.md new file mode 100644 index 000000000000..30f5010ce3a4 --- /dev/null +++ b/crypto/openssl/FAQ.md @@ -0,0 +1,6 @@ +Frequently Asked Questions (FAQ) +================================ + +The [Frequently Asked Questions][FAQ] are now maintained on the OpenSSL homepage. + + [FAQ]: https://www.openssl.org/docs/faq.html diff --git a/crypto/openssl/HACKING.md b/crypto/openssl/HACKING.md new file mode 100644 index 000000000000..6375450c2413 --- /dev/null +++ b/crypto/openssl/HACKING.md @@ -0,0 +1,33 @@ +MODIFYING OPENSSL SOURCE +======================== + +This document describes the way to add custom modifications to OpenSSL sources. + + If you are adding new public functions to the custom library build, you need to + either add a prototype in one of the existing OpenSSL header files; + or provide a new header file and edit + [Configurations/unix-Makefile.tmpl](Configurations/unix-Makefile.tmpl) + to pick up that file. + + After that perform the following steps: + + ./Configure -Werror --strict-warnings [your-options] + make update + make + make test + + `make update` ensures that your functions declarations are added to + `util/libcrypto.num` or `util/libssl.num`. + If you plan to submit the changes you made to OpenSSL + (see [CONTRIBUTING.md](CONTRIBUTING.md)), it's worth running: + + make doc-nits + + after running `make update` to ensure that documentation has correct format. + + `make update` also generates files related to OIDs (in the `crypto/objects/` + folder) and errors. + If a merge error occurs in one of these generated files then the + generated files need to be removed and regenerated using `make update`. + To aid in this process the generated files can be committed separately + so they can be removed easily. diff --git a/crypto/openssl/INSTALL b/crypto/openssl/INSTALL deleted file mode 100644 index f6f754fd5e26..000000000000 --- a/crypto/openssl/INSTALL +++ /dev/null @@ -1,1298 +0,0 @@ - OPENSSL INSTALLATION - -------------------- - - This document describes installation on all supported operating - systems (the Unix/Linux family (which includes Mac OS/X), OpenVMS, - and Windows). - - To install OpenSSL, you will need: - - * A make implementation - * Perl 5 with core modules (please read NOTES.PERL) - * The perl module Text::Template (please read NOTES.PERL) - * an ANSI C compiler - * a development environment in the form of development libraries and C - header files - * a supported operating system - - For additional platform specific requirements, solutions to specific - issues and other details, please read one of these: - - * NOTES.UNIX (any supported Unix like system) - * NOTES.VMS (OpenVMS) - * NOTES.WIN (any supported Windows) - * NOTES.DJGPP (DOS platform with DJGPP) - * NOTES.ANDROID (obviously Android [NDK]) - - Notational conventions in this document - --------------------------------------- - - Throughout this document, we use the following conventions in command - examples: - - $ command Any line starting with a dollar sign - ($) is a command line. - - { word1 | word2 | word3 } This denotes a mandatory choice, to be - replaced with one of the given words. - A simple example would be this: - - $ echo { FOO | BAR | COOKIE } - - which is to be understood as one of - these: - - $ echo FOO - - or - - $ echo BAR - - or - - $ echo COOKIE - - [ word1 | word2 | word3 ] Similar to { word1 | word2 | word3 } - except it's optional to give any of - those. In addition to the examples - above, this would also be valid: - - $ echo - - {{ target }} This denotes a mandatory word or - sequence of words of some sort. A - simple example would be this: - - $ type {{ filename }} - - which is to be understood to use the - command 'type' on some file name - determined by the user. - - [[ options ]] Similar to {{ target }}, but is - optional. - - Note that the notation assumes spaces around {, }, [, ], {{, }} and - [[, ]]. This is to differentiate from OpenVMS directory - specifications, which also use [ and ], but without spaces. - - Quick Start - ----------- - - If you want to just get on with it, do: - - on Unix (again, this includes Mac OS/X): - - $ ./config - $ make - $ make test - $ make install - - on OpenVMS: - - $ @config - $ mms - $ mms test - $ mms install - - on Windows (only pick one of the targets for configuration): - - $ perl Configure { VC-WIN32 | VC-WIN64A | VC-WIN64I | VC-CE } - $ nmake - $ 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: - - Unix: normal installation directories under /usr/local - OpenVMS: SYS$COMMON:[OPENSSL] - 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 (the options - --prefix and --openssldir are explained further down, and the values shown - here are mere examples): - - On Unix: - - $ ./config --prefix=/opt/openssl --openssldir=/usr/local/ssl - - On OpenVMS: - - $ @config --prefix=PROGRAM:[INSTALLS] --openssldir=SYS$MANAGER:[OPENSSL] - - (Note: if you do add options to the configuration command, please make sure - you've read more than just this Quick Start, such as relevant NOTES.* files, - the options outline below, as configuration options may change the outcome - in otherwise unexpected ways) - - - Configuration Options - --------------------- - - There are several options to ./config (or ./Configure) to customize - the build (note that for Windows, the defaults for --prefix and - --openssldir depend in what configuration is used and what Windows - implementation OpenSSL is built on. More notes on this in NOTES.WIN): - - --api=x.y.z - 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. 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 - toolchain. It's likely to have to end with dash, e.g. - a-b-c- would invoke GNU compiler as a-b-c-gcc, etc. - Unfortunately cross-compiling is too case-specific to - put together one-size-fits-all instructions. You might - have to pass more flags or set up environment variables - to actually make it work. Android and iOS cases are - discussed in corresponding Configurations/15-*.conf - files. But there are cases when this option alone is - sufficient. For example to build the mingw64 target on - Linux "--cross-compile-prefix=x86_64-w64-mingw32-" - works. Naturally provided that mingw packages are - installed. Today Debian and Ubuntu users have option to - install a number of prepackaged cross-compilers along - with corresponding run-time and development packages for - "alien" hardware. To give another example - "--cross-compile-prefix=mipsel-linux-gnu-" suffices - in such case. Needless to mention that you have to - invoke ./Configure, not ./config, and pass your target - name explicitly. Also, note that --openssldir refers - to target's file system, not one you are building on. - - --debug - Build OpenSSL with debugging symbols and zero optimization - level. - - --libdir=DIR - The name of the directory under the top of the installation - directory tree (see the --prefix option) where libraries will - be installed. By default this is "lib". Note that on Windows - only ".lib" files will be stored in this location. dll files - will always be installed to the "bin" directory. - - --openssldir=DIR - Directory for OpenSSL configuration files, and also the - default certificate and key store. Defaults are: - - Unix: /usr/local/ssl - Windows: C:\Program Files\Common Files\SSL - or C:\Program Files (x86)\Common Files\SSL - OpenVMS: SYS$COMMON:[OPENSSL-COMMON] - - --prefix=DIR - The top of the installation directory tree. Defaults are: - - Unix: /usr/local - Windows: C:\Program Files\OpenSSL - or C:\Program Files (x86)\OpenSSL - OpenVMS: SYS$COMMON:[OPENSSL] - - --release - Build OpenSSL without debugging symbols. This is the default. - - --strict-warnings - This is a developer flag that switches on various compiler - options recommended for OpenSSL development. It only works - when using gcc or clang as the compiler. If you are - developing a patch for OpenSSL then it is recommended that - you use this option where possible. - - --with-zlib-include=DIR - The directory for the location of the zlib include file. This - option is only necessary if enable-zlib (see below) is used - and the include file is not already on the system include - path. - - --with-zlib-lib=LIB - On Unix: this is the directory containing the zlib library. - If not provided the system library path will be used. - On Windows: this is the filename of the zlib library (with or - without a path). This flag must be provided if the - zlib-dynamic option is not also used. If zlib-dynamic is used - then this flag is optional and a default value ("ZLIB1") is - used if not provided. - On VMS: this is the filename of the zlib library (with or - without a path). This flag is optional and if not provided - then "GNV$LIBZSHR", "GNV$LIBZSHR32" or "GNV$LIBZSHR64" is - used by default depending on the pointer size chosen. - - - --with-rand-seed=seed1[,seed2,...] - A comma separated list of seeding methods which will be tried - by OpenSSL in order to obtain random input (a.k.a "entropy") - for seeding its cryptographically secure random number - generator (CSPRNG). The current seeding methods are: - - os: Use a trusted operating system entropy source. - This is the default method if such an entropy - source exists. - getrandom: Use the L or equivalent system - call. - 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 - most unix-ish operating systems. - egd: Check for an entropy generating daemon. - rdcpu: Use the RDSEED or RDRAND command if provided by - the CPU. - librandom: Use librandom (not implemented yet). - none: Disable automatic seeding. This is the default - on some operating systems where no suitable - entropy source exists, or no support for it is - implemented yet. - - For more information, see the section 'Note on random number - generation' at the end of this document. - - no-afalgeng - Don't build the AFALG engine. This option will be forced if - on a platform that does not support AFALG. - - enable-ktls - Build with Kernel TLS support. This option will enable the - use of the Kernel TLS data-path, which can improve - performance and allow for the use of sendfile and splice - system calls on TLS sockets. The Kernel may use TLS - accelerators if any are available on the system. - This option will be forced off on systems that do not support - the Kernel TLS data-path. - - enable-asan - Build with the Address sanitiser. This is a developer option - only. It may not work on all platforms and should never be - used in production environments. It will only work when used - with gcc or clang and should be used in conjunction with the - no-shared option. - - no-asm - Do not use assembler code. This should be viewed as - debugging/trouble-shooting option rather than production. - On some platforms a small amount of assembler code may - still be used even with this option. - - no-async - Do not build support for async operations. - - no-autoalginit - Don't automatically load all supported ciphers and digests. - Typically OpenSSL will make available all of its supported - ciphers and digests. For a statically linked application this - may be undesirable if small executable size is an objective. - This only affects libcrypto. Ciphers and digests will have to - be loaded manually using EVP_add_cipher() and - EVP_add_digest() if this option is used. This option will - force a non-shared build. - - no-autoerrinit - Don't automatically load all libcrypto/libssl error strings. - Typically OpenSSL will automatically load human readable - error strings. For a statically linked application this may - be undesirable if small executable size is an objective. - - no-autoload-config - Don't automatically load the default openssl.cnf file. - Typically OpenSSL will automatically load a system config - file which configures default ssl options. - - enable-buildtest-c++ - While testing, generate C++ buildtest files that - simply check that the public OpenSSL header files - are usable standalone with C++. - - Enabling this option demands extra care. For any - compiler flag given directly as configuration - option, you must ensure that it's valid for both - the C and the C++ compiler. If not, the C++ build - test will most likely break. As an alternative, - you can use the language specific variables, CFLAGS - and CXXFLAGS. - - no-capieng - Don't build the CAPI engine. This option will be forced if - on a platform that does not support CAPI. - - no-cms - Don't build support for CMS features - - no-comp - Don't build support for SSL/TLS compression. If this option - is left enabled (the default), then compression will only - work if the zlib or zlib-dynamic options are also chosen. - - enable-crypto-mdebug - Build support for debugging memory allocated via - OPENSSL_malloc() or OPENSSL_zalloc(). - - enable-crypto-mdebug-backtrace - As for crypto-mdebug, but additionally provide backtrace - information for allocated memory. - TO BE USED WITH CARE: this uses GNU C functionality, and - is therefore not usable for non-GNU config targets. If - your build complains about the use of '-rdynamic' or the - lack of header file execinfo.h, this option is not for you. - ALSO NOTE that even though execinfo.h is available on your - system (through Gnulib), the functions might just be stubs - that do nothing. - - no-ct - Don't build support for Certificate Transparency. - - no-deprecated - Don't build with support for any deprecated APIs. This is the - same as using "--api" and supplying the latest version - number. - - no-dgram - Don't build support for datagram based BIOs. Selecting this - option will also force the disabling of DTLS. - - no-dso - Don't build support for loading Dynamic Shared Objects. - - enable-devcryptoeng - Build the /dev/crypto engine. It is automatically selected - on BSD implementations, in which case it can be disabled with - no-devcryptoeng. - - no-dynamic-engine - Don't build the dynamically loaded engines. This only has an - effect in a "shared" build - - no-ec - Don't build support for Elliptic Curves. - - no-ec2m - Don't build support for binary Elliptic Curves - - enable-ec_nistp_64_gcc_128 - Enable support for optimised implementations of some commonly - used NIST elliptic curves. - This is only supported on platforms: - - with little-endian storage of non-byte types - - that tolerate misaligned memory references - - where the compiler: - - supports the non-standard type __uint128_t - - defines the built-in macro __SIZEOF_INT128__ - - enable-egd - Build support for gathering entropy from EGD (Entropy - Gathering Daemon). - - no-engine - Don't build support for loading engines. - - no-err - Don't compile in any error strings. - - enable-external-tests - Enable building of integration with external test suites. - This is a developer option and may not work on all platforms. - The only supported external test suite at the current time is - the BoringSSL test suite. See the file test/README.external - for further details. - - no-filenames - Don't compile in filename and line number information (e.g. - for errors and memory allocation). - - enable-fuzz-libfuzzer, enable-fuzz-afl - Build with support for fuzzing using either libfuzzer or AFL. - These are developer options only. They may not work on all - platforms and should never be used in production environments. - See the file fuzz/README.md for further details. - - no-gost - Don't build support for GOST based ciphersuites. Note that - if this feature is enabled then GOST ciphersuites are only - available if the GOST algorithms are also available through - loading an externally supplied engine. - - no-hw-padlock - Don't build the padlock engine. - - no-makedepend - Don't generate dependencies. - - no-multiblock - Don't build support for writing multiple records in one - go in libssl (Note: this is a different capability to the - pipelining functionality). - - no-nextprotoneg - Don't build support for the NPN TLS extension. - - no-ocsp - Don't build support for OCSP. - - no-pic - Don't build with support for Position Independent Code. - - no-pinshared By default OpenSSL will attempt to stay in memory until the - process exits. This is so that libcrypto and libssl can be - properly cleaned up automatically via an "atexit()" handler. - The handler is registered by libcrypto and cleans up both - libraries. On some platforms the atexit() handler will run on - unload of libcrypto (if it has been dynamically loaded) - rather than at process exit. This option can be used to stop - OpenSSL from attempting to stay in memory until the process - exits. This could lead to crashes if either libcrypto or - libssl have already been unloaded at the point - that the atexit handler is invoked, e.g. on a platform which - calls atexit() on unload of the library, and libssl is - unloaded before libcrypto then a crash is likely to happen. - Applications can suppress running of the atexit() handler at - run time by using the OPENSSL_INIT_NO_ATEXIT option to - OPENSSL_init_crypto(). See the man page for it for further - details. - - no-posix-io - Don't use POSIX IO capabilities. - - no-psk - Don't build support for Pre-Shared Key based ciphersuites. - - no-rdrand - Don't use hardware RDRAND capabilities. - - no-rfc3779 - Don't build support for RFC3779 ("X.509 Extensions for IP - Addresses and AS Identifiers") - - sctp - Build support for SCTP - - no-shared - Do not create shared libraries, only static ones. See "Note - on shared libraries" below. - - no-sock - Don't build support for socket BIOs - - no-srp - Don't build support for SRP or SRP based ciphersuites. - - no-srtp - Don't build SRTP support - - no-sse2 - Exclude SSE2 code paths from 32-bit x86 assembly modules. - Normally SSE2 extension is detected at run-time, but the - decision whether or not the machine code will be executed - is taken solely on CPU capability vector. This means that - if you happen to run OS kernel which does not support SSE2 - extension on Intel P4 processor, then your application - might be exposed to "illegal instruction" exception. - There might be a way to enable support in kernel, e.g. - FreeBSD kernel can be compiled with CPU_ENABLE_SSE, and - there is a way to disengage SSE2 code paths upon application - start-up, but if you aim for wider "audience" running - such kernel, consider no-sse2. Both the 386 and - no-asm options imply no-sse2. - - enable-ssl-trace - Build with the SSL Trace capabilities (adds the "-trace" - option to s_client and s_server). - - no-static-engine - Don't build the statically linked engines. This only - has an impact when not built "shared". - - no-stdio - Don't use anything from the C header file "stdio.h" that - makes use of the "FILE" type. Only libcrypto and libssl can - be built in this way. Using this option will suppress - building the command line applications. Additionally since - the OpenSSL tests also use the command line applications the - tests will also be skipped. - - no-tests - Don't build test programs or run any test. - - no-threads - Don't try to build with support for multi-threaded - applications. - - threads - Build with support for multi-threaded applications. Most - platforms will enable this by default. However if on a - platform where this is not the case then this will usually - require additional system-dependent options! See "Note on - multi-threading" below. - - no-ts - Don't build Time Stamping Authority support. - - enable-ubsan - Build with the Undefined Behaviour sanitiser. This is a - developer option only. It may not work on all platforms and - should never be used in production environments. It will only - work when used with gcc or clang and should be used in - conjunction with the "-DPEDANTIC" option (or the - --strict-warnings option). - - no-ui-console - Don't build with the "UI" console method (i.e. the "UI" - method that enables text based console prompts). - - enable-unit-test - Enable additional unit test APIs. This should not typically - be used in production deployments. - - enable-weak-ssl-ciphers - Build support for SSL/TLS ciphers that are considered "weak" - (e.g. RC4 based ciphersuites). - - zlib - Build with support for zlib compression/decompression. - - zlib-dynamic - Like "zlib", but has OpenSSL load the zlib library - dynamically when needed. This is only supported on systems - where loading of shared libraries is supported. - - 386 - In 32-bit x86 builds, when generating assembly modules, - use the 80386 instruction set only (the default x86 code - is more efficient, but requires at least a 486). Note: - This doesn't affect code generated by compiler, you're - likely to complement configuration command line with - suitable compiler-specific option. - - no- - Don't build support for negotiating the specified SSL/TLS - protocol (one of ssl, ssl3, tls, tls1, tls1_1, tls1_2, - tls1_3, dtls, dtls1 or dtls1_2). If "no-tls" is selected then - all of tls1, tls1_1, tls1_2 and tls1_3 are disabled. - Similarly "no-dtls" will disable dtls1 and dtls1_2. The - "no-ssl" option is synonymous with "no-ssl3". Note this only - affects version negotiation. OpenSSL will still provide the - methods for applications to explicitly select the individual - protocol versions. - - no--method - As for no- but in addition do not build the methods for - applications to explicitly select individual protocol - versions. Note that there is no "no-tls1_3-method" option - because there is no application method for TLSv1.3. Using - individual protocol methods directly is deprecated. - Applications should use TLS_method() instead. - - enable- - Build with support for the specified algorithm, where - is one of: md2 or rc5. - - no- - Build without support for the specified algorithm, where - is one of: aria, bf, blake2, camellia, cast, chacha, - cmac, des, dh, dsa, ecdh, ecdsa, idea, md4, mdc2, ocb, - poly1305, rc2, rc4, rmd160, scrypt, seed, siphash, sm2, sm3, - sm4 or whirlpool. The "ripemd" algorithm is deprecated and - if used is synonymous with rmd160. - - -Dxxx, -Ixxx, -Wp, -lxxx, -Lxxx, -Wl, -rpath, -R, -framework, -static - These system specific options will be recognised and - passed through to the compiler to allow you to define - preprocessor symbols, specify additional libraries, library - directories or other compiler options. It might be worth - noting that some compilers generate code specifically for - processor the compiler currently executes on. This is not - necessarily what you might have in mind, since it might be - unsuitable for execution on other, typically older, - processor. Consult your compiler documentation. - - Take note of the VAR=value documentation below and how - these flags interact with those variables. - - -xxx, +xxx, /xxx - Additional options that are not otherwise recognised are - passed through as they are to the compiler as well. - Unix-style options beginning with a '-' or '+' and - Windows-style options beginning with a '/' are recognized. - Again, consult your compiler documentation. - - If the option contains arguments separated by spaces, - then the URL-style notation %20 can be used for the space - character in order to avoid having to quote the option. - For example, -opt%20arg gets expanded to -opt arg. - In fact, any ASCII character can be encoded as %xx using its - hexadecimal encoding. - - Take note of the VAR=value documentation below and how - these flags interact with those variables. - - VAR=value - Assignment of environment variable for Configure. These - work just like normal environment variable assignments, - but are supported on all platforms and are confined to - the configuration scripts only. These assignments override - the corresponding value in the inherited environment, if - there is one. - - The following variables are used as "make variables" and - can be used as an alternative to giving preprocessor, - compiler and linker options directly as configuration. - The following variables are supported: - - AR The static library archiver. - ARFLAGS Flags for the static library archiver. - AS The assembler compiler. - ASFLAGS Flags for the assembler compiler. - CC The C compiler. - CFLAGS Flags for the C compiler. - CXX The C++ compiler. - CXXFLAGS Flags for the C++ compiler. - CPP The C/C++ preprocessor. - CPPFLAGS Flags for the C/C++ preprocessor. - CPPDEFINES List of CPP macro definitions, separated - by a platform specific character (':' or - space for Unix, ';' for Windows, ',' for - VMS). This can be used instead of using - -D (or what corresponds to that on your - compiler) in CPPFLAGS. - CPPINCLUDES List of CPP inclusion directories, separated - the same way as for CPPDEFINES. This can - be used instead of -I (or what corresponds - to that on your compiler) in CPPFLAGS. - HASHBANGPERL Perl invocation to be inserted after '#!' - in public perl scripts (only relevant on - Unix). - LD The program linker (not used on Unix, $(CC) - is used there). - LDFLAGS Flags for the shared library, DSO and - program linker. - LDLIBS Extra libraries to use when linking. - Takes the form of a space separated list - of library specifications on Unix and - Windows, and as a comma separated list of - libraries on VMS. - RANLIB The library archive indexer. - RC The Windows resource compiler. - RCFLAGS Flags for the Windows resource compiler. - RM The command to remove files and directories. - - These cannot be mixed with compiling / linking flags given - on the command line. In other words, something like this - isn't permitted. - - ./config -DFOO CPPFLAGS=-DBAR -DCOOKIE - - Backward compatibility note: - - To be compatible with older configuration scripts, the - environment variables are ignored if compiling / linking - flags are given on the command line, except for these: - - AR, CC, CXX, CROSS_COMPILE, HASHBANGPERL, PERL, RANLIB, RC - and WINDRES - - For example, the following command will not see -DBAR: - - CPPFLAGS=-DBAR ./config -DCOOKIE - - However, the following will see both set variables: - - CC=gcc CROSS_COMPILE=x86_64-w64-mingw32- \ - ./config -DCOOKIE - - If CC is set, it is advisable to also set CXX to ensure - both C and C++ compilers are in the same "family". This - becomes relevant with 'enable-external-tests' and - 'enable-buildtest-c++'. - - reconf - reconfigure - Reconfigure from earlier data. This fetches the previous - command line options and environment from data saved in - "configdata.pm", and runs the configuration process again, - using these options and environment. - Note: NO other option is permitted together with "reconf". - This means that you also MUST use "./Configure" (or - what corresponds to that on non-Unix platforms) directly - to invoke this option. - Note: The original configuration saves away values for ALL - environment variables that were used, and if they weren't - defined, they are still saved away with information that - they weren't originally defined. This information takes - precedence over environment variables that are defined - when reconfiguring. - - Displaying configuration data - ----------------------------- - - The configuration script itself will say very little, and finishes by - creating "configdata.pm". This perl module can be loaded by other scripts - to find all the configuration data, and it can also be used as a script to - display all sorts of configuration data in a human readable form. - - For more information, please do: - - $ ./configdata.pm --help # Unix - - or - - $ perl configdata.pm --help # Windows and VMS - - Installation in Detail - ---------------------- - - 1a. Configure OpenSSL for your operation system automatically: - - NOTE: This is not available on Windows. - - $ ./config [[ options ]] # Unix - - or - - $ @config [[ options ]] ! OpenVMS - - For the remainder of this text, the Unix form will be used in all - examples, please use the appropriate form for your platform. - - This guesses at your operating system (and compiler, if necessary) and - configures OpenSSL based on this guess. Run ./config -t to see - if it guessed correctly. If you want to use a different compiler, you - are cross-compiling for another platform, or the ./config guess was - wrong for other reasons, go to step 1b. Otherwise go to step 2. - - On some systems, you can include debugging information as follows: - - $ ./config -d [[ options ]] - - 1b. Configure OpenSSL for your operating system manually - - OpenSSL knows about a range of different operating system, hardware and - compiler combinations. To see the ones it knows about, run - - $ ./Configure # Unix - - or - - $ perl Configure # All other platforms - - For the remainder of this text, the Unix form will be used in all - examples, please use the appropriate form for your platform. - - Pick a suitable name from the list that matches your system. For most - operating systems there is a choice between using "cc" or "gcc". When - you have identified your system (and if necessary compiler) use this name - as the argument to Configure. For example, a "linux-elf" user would - run: - - $ ./Configure linux-elf [[ options ]] - - If your system isn't listed, you will have to create a configuration - file named Configurations/{{ something }}.conf and add the correct - configuration for your system. See the available configs as examples - and read Configurations/README and Configurations/README.design for - more information. - - The generic configurations "cc" or "gcc" should usually work on 32 bit - Unix-like systems. - - Configure creates a build file ("Makefile" on Unix, "makefile" on Windows - and "descrip.mms" on OpenVMS) from a suitable template in Configurations, - and defines various macros in include/openssl/opensslconf.h (generated from - include/openssl/opensslconf.h.in). - - 1c. Configure OpenSSL for building outside of the source tree. - - OpenSSL can be configured to build in a build directory separate from - the directory with the source code. It's done by placing yourself in - some other directory and invoking the configuration commands from - there. - - Unix example: - - $ mkdir /var/tmp/openssl-build - $ cd /var/tmp/openssl-build - $ /PATH/TO/OPENSSL/SOURCE/config [[ options ]] - - or - - $ /PATH/TO/OPENSSL/SOURCE/Configure {{ target }} [[ options ]] - - OpenVMS example: - - $ set default sys$login: - $ create/dir [.tmp.openssl-build] - $ set default [.tmp.openssl-build] - $ @[PATH.TO.OPENSSL.SOURCE]config [[ options ]] - - or - - $ @[PATH.TO.OPENSSL.SOURCE]Configure {{ target }} [[ options ]] - - Windows example: - - $ C: - $ mkdir \temp-openssl - $ cd \temp-openssl - $ perl d:\PATH\TO\OPENSSL\SOURCE\Configure {{ target }} [[ options ]] - - Paths can be relative just as well as absolute. Configure will - do its best to translate them to relative paths whenever possible. - - 2. Build OpenSSL by running: - - $ make # Unix - $ mms ! (or mmk) OpenVMS - $ nmake # Windows - - This will build the OpenSSL libraries (libcrypto.a and libssl.a on - Unix, corresponding on other platforms) and the OpenSSL binary - ("openssl"). The libraries will be built in the top-level directory, - and the binary will be in the "apps" subdirectory. - - Troubleshooting: - - If the build fails, look at the output. There may be reasons - for the failure that aren't problems in OpenSSL itself (like - missing standard headers). - - If the build succeeded previously, but fails after a source or - configuration change, it might be helpful to clean the build tree - before attempting another build. Use this command: - - $ make clean # Unix - $ mms clean ! (or mmk) OpenVMS - $ nmake clean # Windows - - Assembler error messages can sometimes be sidestepped by using the - "no-asm" configuration option. - - Compiling parts of OpenSSL with gcc and others with the system - compiler will result in unresolved symbols on some systems. - - If you are still having problems you can get help by sending an email - to the openssl-users email list (see - https://www.openssl.org/community/mailinglists.html for details). If - it is a bug with OpenSSL itself, please open an issue on GitHub, at - https://github.com/openssl/openssl/issues. Please review the existing - ones first; maybe the bug was already reported or has already been - fixed. - - 3. After a successful build, the libraries should be tested. Run: - - $ make test # Unix - $ mms test ! OpenVMS - $ nmake test # Windows - - NOTE: you MUST run the tests from an unprivileged account (or - disable your privileges temporarily if your platform allows it). - - If some tests fail, look at the output. There may be reasons for - the failure that isn't a problem in OpenSSL itself (like a - malfunction with Perl). You may want increased verbosity, that - can be accomplished like this: - - $ make VERBOSE=1 test # Unix - - $ mms /macro=(VERBOSE=1) test ! OpenVMS - - $ nmake VERBOSE=1 test # Windows - - If you want to run just one or a few specific tests, you can use - the make variable TESTS to specify them, like this: - - $ make TESTS='test_rsa test_dsa' test # Unix - $ mms/macro="TESTS=test_rsa test_dsa" test ! OpenVMS - $ nmake TESTS='test_rsa test_dsa' test # Windows - - And of course, you can combine (Unix example shown): - - $ make VERBOSE=1 TESTS='test_rsa test_dsa' test - - You can find the list of available tests like this: - - $ make list-tests # Unix - $ mms list-tests ! OpenVMS - $ nmake list-tests # Windows - - Have a look at the manual for the perl module Test::Harness to - see what other HARNESS_* variables there are. - - If you find a problem with OpenSSL itself, try removing any - compiler optimization flags from the CFLAGS line in Makefile and - run "make clean; make" or corresponding. - - To report a bug please open an issue on GitHub, at - https://github.com/openssl/openssl/issues. - - For more details on how the make variables TESTS can be used, - see section TESTS in Detail below. - - 4. If everything tests ok, install OpenSSL with - - $ make install # Unix - $ mms install ! OpenVMS - $ nmake install # Windows - - 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: - - bin/ Contains the openssl binary and a few other - utility scripts. - include/openssl - Contains the header files needed if you want - to build your own programs that use libcrypto - or libssl. - lib Contains the OpenSSL library files. - lib/engines Contains the OpenSSL dynamically loadable engines. - - share/man/man1 Contains the OpenSSL command line man-pages. - share/man/man3 Contains the OpenSSL library calls man-pages. - share/man/man5 Contains the OpenSSL configuration format man-pages. - share/man/man7 Contains the OpenSSL other misc man-pages. - - share/doc/openssl/html/man1 - share/doc/openssl/html/man3 - share/doc/openssl/html/man5 - share/doc/openssl/html/man7 - Contains the HTML rendition of the man-pages. - - OpenVMS ('arch' is replaced with the architecture name, "ALPHA" - or "IA64", 'sover' is replaced with the shared library version - (0101 for 1.1.x), and 'pz' is replaced with the pointer size - OpenSSL was built with): - - [.EXE.'arch'] Contains the openssl binary. - [.EXE] Contains a few utility scripts. - [.include.openssl] - Contains the header files needed if you want - to build your own programs that use libcrypto - or libssl. - [.LIB.'arch'] Contains the OpenSSL library files. - [.ENGINES'sover''pz'.'arch'] - Contains the OpenSSL dynamically loadable engines. - [.SYS$STARTUP] Contains startup, login and shutdown scripts. - These define appropriate logical names and - command symbols. - [.SYSTEST] Contains the installation verification procedure. - [.HTML] Contains the HTML rendition of the manual pages. - - - Additionally, install will add the following directories under - OPENSSLDIR (the directory given with --openssldir or its default) - for you convenience: - - certs Initially empty, this is the default location - for certificate files. - private Initially empty, this is the default location - 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 - - $ make DESTDIR=/tmp/package-root install # Unix - $ mms/macro="DESTDIR=TMP:[PACKAGE-ROOT]" install ! OpenVMS - - The specified destination directory will be prepended to all - installation target paths. - - Compatibility issues with previous OpenSSL versions: - - * COMPILING existing applications - - Starting with version 1.1.0, OpenSSL hides a number of structures - that were previously open. This includes all internal libssl - structures and a number of EVP types. Accessor functions have - been added to allow controlled access to the structures' data. - - This means that some software needs to be rewritten to adapt to - the new ways of doing things. This often amounts to allocating - an instance of a structure explicitly where you could previously - allocate them on the stack as automatic variables, and using the - provided accessor functions where you would previously access a - structure's field directly. - - Some APIs have changed as well. However, older APIs have been - preserved when possible. - - Environment Variables - --------------------- - - A number of environment variables can be used to provide additional control - over the build process. Typically these should be defined prior to running - config or Configure. Not all environment variables are relevant to all - platforms. - - AR - The name of the ar executable to use. - - BUILDFILE - Use a different build file name than the platform default - ("Makefile" on Unix-like platforms, "makefile" on native Windows, - "descrip.mms" on OpenVMS). This requires that there is a - corresponding build file template. See Configurations/README - for further information. - - CC - The compiler to use. Configure will attempt to pick a default - compiler for your platform but this choice can be overridden - using this variable. Set it to the compiler executable you wish - to use, e.g. "gcc" or "clang". - - CROSS_COMPILE - This environment variable has the same meaning as for the - "--cross-compile-prefix" Configure flag described above. If both - are set then the Configure flag takes precedence. - - NM - The name of the nm executable to use. - - OPENSSL_LOCAL_CONFIG_DIR - OpenSSL comes with a database of information about how it - should be built on different platforms as well as build file - templates for those platforms. The database is comprised of - ".conf" files in the Configurations directory. The build - file templates reside there as well as ".tmpl" files. See the - file Configurations/README for further information about the - format of ".conf" files as well as information on the ".tmpl" - files. - In addition to the standard ".conf" and ".tmpl" files, it is - possible to create your own ".conf" and ".tmpl" files and store - them locally, outside the OpenSSL source tree. This environment - variable can be set to the directory where these files are held - and will be considered by Configure before it looks in the - standard directories. - - PERL - The name of the Perl executable to use when building OpenSSL. - This variable is used in config script only. Configure on the - other hand imposes the interpreter by which it itself was - executed on the whole build procedure. - - HASHBANGPERL - The command string for the Perl executable to insert in the - #! line of perl scripts that will be publicly installed. - Default: /usr/bin/env perl - Note: the value of this variable is added to the same scripts - on all platforms, but it's only relevant on Unix-like platforms. - - RC - The name of the rc executable to use. The default will be as - defined for the target platform in the ".conf" file. If not - defined then "windres" will be used. The WINDRES environment - variable is synonymous to this. If both are defined then RC - takes precedence. - - RANLIB - The name of the ranlib executable to use. - - WINDRES - See RC. - - Makefile targets - ---------------- - - The Configure script generates a Makefile in a format relevant to the specific - platform. The Makefiles provide a number of targets that can be used. Not all - targets may be available on all platforms. Only the most common targets are - described here. Examine the Makefiles themselves for the full list. - - all - The default target to build all the software components. - - clean - Remove all build artefacts and return the directory to a "clean" - state. - - depend - Rebuild the dependencies in the Makefiles. This is a legacy - option that no longer needs to be used since OpenSSL 1.1.0. - - install - Install all OpenSSL components. - - install_sw - Only install the OpenSSL software components. - - install_docs - Only install the OpenSSL documentation components. - - install_man_docs - Only install the OpenSSL man pages (Unix only). - - install_html_docs - Only install the OpenSSL html documentation. - - list-tests - Prints a list of all the self test names. - - test - Build and run the OpenSSL self tests. - - uninstall - Uninstall all OpenSSL components. - - reconfigure - reconf - Re-run the configuration process, as exactly as the last time - as possible. - - update - This is a developer option. If you are developing a patch for - OpenSSL you may need to use this if you want to update - automatically generated files; add new error codes or add new - (or change the visibility of) public API functions. (Unix only). - - TESTS in Detail - --------------- - - The make variable TESTS supports a versatile set of space separated tokens - with which you can specify a set of tests to be performed. With a "current - set of tests" in mind, initially being empty, here are the possible tokens: - - alltests The current set of tests becomes the whole set of available - tests (as listed when you do 'make list-tests' or similar). - xxx Adds the test 'xxx' to the current set of tests. - -xxx Removes 'xxx' from the current set of tests. If this is the - first token in the list, the current set of tests is first - assigned the whole set of available tests, effectively making - this token equivalent to TESTS="alltests -xxx". - nn Adds the test group 'nn' (which is a number) to the current - set of tests. - -nn Removes the test group 'nn' from the current set of tests. - If this is the first token in the list, the current set of - tests is first assigned the whole set of available tests, - effectively making this token equivalent to - TESTS="alltests -xxx". - - Also, all tokens except for "alltests" may have wildcards, such as *. - (on Unix and Windows, BSD style wildcards are supported, while on VMS, - it's VMS style wildcards) - - Example: All tests except for the fuzz tests: - - $ make TESTS=-test_fuzz test - - or (if you want to be explicit) - - $ make TESTS='alltests -test_fuzz' test - - Example: All tests that have a name starting with "test_ssl" but not those - starting with "test_ssl_": - - $ make TESTS='test_ssl* -test_ssl_*' test - - Example: Only test group 10: - - $ make TESTS='10' - - Example: All tests except the slow group (group 99): - - $ make TESTS='-99' - - Example: All tests in test groups 80 to 99 except for tests in group 90: - - $ make TESTS='[89]? -90' - - Note on multi-threading - ----------------------- - - For some systems, the OpenSSL Configure script knows what compiler options - are needed to generate a library that is suitable for multi-threaded - applications. On these systems, support for multi-threading is enabled - by default; use the "no-threads" option to disable (this should never be - necessary). - - On other systems, to enable support for multi-threading, you will have - to specify at least two options: "threads", and a system-dependent option. - (The latter is "-D_REENTRANT" on various systems.) The default in this - case, obviously, is not to include support for multi-threading (but - you can still use "no-threads" to suppress an annoying warning message - from the Configure script.) - - OpenSSL provides built-in support for two threading models: pthreads (found on - most UNIX/Linux systems), and Windows threads. No other threading models are - supported. If your platform does not provide pthreads or Windows threads then - you should Configure with the "no-threads" option. - - Notes on shared libraries - ------------------------- - - For most systems the OpenSSL Configure script knows what is needed to - build shared libraries for libcrypto and libssl. On these systems - the shared libraries will be created by default. This can be suppressed and - only static libraries created by using the "no-shared" option. On systems - where OpenSSL does not know how to build shared libraries the "no-shared" - option will be forced and only static libraries will be created. - - Shared libraries are named a little differently on different platforms. - One way or another, they all have the major OpenSSL version number as - part of the file name, i.e. for OpenSSL 1.1.x, 1.1 is somehow part of - the name. - - On most POSIX platforms, shared libraries are named libcrypto.so.1.1 - and libssl.so.1.1. - - on Cygwin, shared libraries are named cygcrypto-1.1.dll and cygssl-1.1.dll - with import libraries libcrypto.dll.a and libssl.dll.a. - - On Windows build with MSVC or using MingW, shared libraries are named - libcrypto-1_1.dll and libssl-1_1.dll for 32-bit Windows, libcrypto-1_1-x64.dll - and libssl-1_1-x64.dll for 64-bit x86_64 Windows, and libcrypto-1_1-ia64.dll - and libssl-1_1-ia64.dll for IA64 Windows. With MSVC, the import libraries - are named libcrypto.lib and libssl.lib, while with MingW, they are named - libcrypto.dll.a and libssl.dll.a. - - On VMS, shareable images (VMS speak for shared libraries) are named - ossl$libcrypto0101_shr.exe and ossl$libssl0101_shr.exe. However, when - OpenSSL is specifically built for 32-bit pointers, the shareable images - are named ossl$libcrypto0101_shr32.exe and ossl$libssl0101_shr32.exe - instead, and when built for 64-bit pointers, they are named - ossl$libcrypto0101_shr64.exe and ossl$libssl0101_shr64.exe. - - Note on random number generation - -------------------------------- - - Availability of cryptographically secure random numbers is required for - secret key generation. OpenSSL provides several options to seed the - internal CSPRNG. If not properly seeded, the internal CSPRNG will refuse - to deliver random bytes and a "PRNG not seeded error" will occur. - - The seeding method can be configured using the --with-rand-seed option, - which can be used to specify a comma separated list of seed methods. - However in most cases OpenSSL will choose a suitable default method, - so it is not necessary to explicitly provide this option. Note also - that not all methods are available on all platforms. - - I) On operating systems which provide a suitable randomness source (in - form of a system call or system device), OpenSSL will use the optimal - available method to seed the CSPRNG from the operating system's - randomness sources. This corresponds to the option --with-rand-seed=os. - - II) On systems without such a suitable randomness source, automatic seeding - and reseeding is disabled (--with-rand-seed=none) and it may be necessary - to install additional support software to obtain a random seed and reseed - the CSPRNG manually. Please check out the manual pages for RAND_add(), - RAND_bytes(), RAND_egd(), and the FAQ for more information. diff --git a/crypto/openssl/INSTALL.md b/crypto/openssl/INSTALL.md new file mode 100644 index 000000000000..84e8a7d542a5 --- /dev/null +++ b/crypto/openssl/INSTALL.md @@ -0,0 +1,1817 @@ +Build and Install +================= + +This document describes installation on all supported operating +systems (the Unix/Linux family, including macOS), OpenVMS, +and Windows). + +Table of Contents +================= + + - [Prerequisites](#prerequisites) + - [Notational Conventions](#notational-conventions) + - [Quick Installation Guide](#quick-installation-guide) + - [Building OpenSSL](#building-openssl) + - [Installing OpenSSL](#installing-openssl) + - [Configuration Options](#configuration-options) + - [API Level](#api-level) + - [Cross Compile Prefix](#cross-compile-prefix) + - [Build Type](#build-type) + - [Directories](#directories) + - [Compiler Warnings](#compiler-warnings) + - [ZLib Flags](#zlib-flags) + - [Seeding the Random Generator](#seeding-the-random-generator) + - [Setting the FIPS HMAC key](#setting-the-FIPS-HMAC-key) + - [Enable and Disable Features](#enable-and-disable-features) + - [Displaying configuration data](#displaying-configuration-data) + - [Installation Steps in Detail](#installation-steps-in-detail) + - [Configure](#configure-openssl) + - [Build](#build-openssl) + - [Test](#test-openssl) + - [Install](#install-openssl) + - [Advanced Build Options](#advanced-build-options) + - [Environment Variables](#environment-variables) + - [Makefile Targets](#makefile-targets) + - [Running Selected Tests](#running-selected-tests) + - [Troubleshooting](#troubleshooting) + - [Configuration Problems](#configuration-problems) + - [Build Failures](#build-failures) + - [Test Failures](#test-failures) + - [Notes](#notes) + - [Notes on multi-threading](#notes-on-multi-threading) + - [Notes on shared libraries](#notes-on-shared-libraries) + - [Notes on random number generation](#notes-on-random-number-generation) + - [Notes on assembler modules compilation](#notes-on-assembler-modules-compilation) + +Prerequisites +============= + +To install OpenSSL, you will need: + + * A "make" implementation + * Perl 5 with core modules (please read [NOTES-PERL.md](NOTES-PERL.md)) + * The Perl module `Text::Template` (please read [NOTES-PERL.md](NOTES-PERL.md)) + * an ANSI C compiler + * a development environment in the form of development libraries and C + header files + * a supported operating system + +For additional platform specific requirements, solutions to specific +issues and other details, please read one of these: + + * [Notes for UNIX-like platforms](NOTES-UNIX.md) + * [Notes for Android platforms](NOTES-ANDROID.md) + * [Notes for Windows platforms](NOTES-WINDOWS.md) + * [Notes for the DOS platform with DJGPP](NOTES-DJGPP.md) + * [Notes for the OpenVMS platform](NOTES-VMS.md) + * [Notes on Perl](NOTES-PERL.md) + * [Notes on Valgrind](NOTES-VALGRIND.md) + +Notational conventions +====================== + +Throughout this document, we use the following conventions. + +Commands +-------- + +Any line starting with a dollar sign is a command line. + + $ command + +The dollar sign indicates the shell prompt and is not to be entered as +part of the command. + +Choices +------- + +Several words in curly braces separated by pipe characters indicate a +**mandatory choice**, to be replaced with one of the given words. +For example, the line + + $ echo { WORD1 | WORD2 | WORD3 } + +represents one of the following three commands + + $ echo WORD1 + - or - + $ echo WORD2 + - or - + $ echo WORD3 + +One or several words in square brackets separated by pipe characters +denote an **optional choice**. It is similar to the mandatory choice, +but it can also be omitted entirely. + +So the line + + $ echo [ WORD1 | WORD2 | WORD3 ] + +represents one of the four commands + + $ echo WORD1 + - or - + $ echo WORD2 + - or - + $ echo WORD3 + - or - + $ echo + +Arguments +--------- + +**Mandatory arguments** are enclosed in double curly braces. +A simple example would be + + $ type {{ filename }} + +which is to be understood to use the command `type` on some file name +determined by the user. + +**Optional Arguments** are enclosed in double square brackets. + + [[ options ]] + +Note that the notation assumes spaces around `{`, `}`, `[`, `]`, `{{`, `}}` and +`[[`, `]]`. This is to differentiate from OpenVMS directory +specifications, which also use [ and ], but without spaces. + +Quick Installation Guide +======================== + +If you just want to get OpenSSL installed without bothering too much +about the details, here is the short version of how to build and install +OpenSSL. If any of the following steps fails, please consult the +[Installation in Detail](#installation-steps-in-detail) section below. + +Building OpenSSL +---------------- + +Use the following commands to configure, build and test OpenSSL. +The testing is optional, but recommended if you intend to install +OpenSSL for production use. + +### Unix / Linux / macOS + + $ ./Configure + $ make + $ make test + +### OpenVMS + +Use the following commands to build OpenSSL: + + $ perl Configure + $ mms + $ mms test + +### Windows + +If you are using Visual Studio, open a Developer Command Prompt and +issue the following commands to build OpenSSL. + + $ perl Configure + $ nmake + $ nmake test + +As mentioned in the [Choices](#choices) section, you need to pick one +of the four Configure targets in the first command. + +Most likely you will be using the `VC-WIN64A` target for 64bit Windows +binaries (AMD64) or `VC-WIN32` for 32bit Windows binaries (X86). +The other two options are `VC-WIN64I` (Intel IA64, Itanium) and +`VC-CE` (Windows CE) are rather uncommon nowadays. + +Installing OpenSSL +------------------ + +The following commands will install OpenSSL to a default system location. + +**Danger Zone:** even if you are impatient, please read the following two +paragraphs carefully before you install OpenSSL. + +For security reasons the default system location is by default not writable +for unprivileged users. So for the final installation step administrative +privileges are required. The default system location and the procedure to +obtain administrative privileges depends on the operating system. +It is recommended to compile and test OpenSSL with normal user privileges +and use administrative privileges only for the final installation step. + +On some platforms OpenSSL is preinstalled as part of the Operating System. +In this case it is highly recommended not to overwrite the system versions, +because other applications or libraries might depend on it. +To avoid breaking other applications, install your copy of OpenSSL to a +[different location](#installing-to-a-different-location) which is not in +the global search path for system libraries. + +Finally, if you plan on using the FIPS module, you need to read the +[Post-installation Notes](#post-installation-notes) further down. + +### Unix / Linux / macOS + +Depending on your distribution, you need to run the following command as +root user or prepend `sudo` to the command: + + $ make install + +By default, OpenSSL will be installed to + + /usr/local + +More precisely, the files will be installed into the subdirectories + + /usr/local/bin + /usr/local/lib + /usr/local/include + ... + +depending on the file type, as it is custom on Unix-like operating systems. + +### OpenVMS + +Use the following command to install OpenSSL. + + $ mms install + +By default, OpenSSL will be installed to + + SYS$COMMON:[OPENSSL] + +### Windows + +If you are using Visual Studio, open the Developer Command Prompt _elevated_ +and issue the following command. + + $ nmake install + +The easiest way to elevate the Command Prompt is to press and hold down both +the `` and `` keys while clicking the menu item in the task menu. + +The default installation location is + + C:\Program Files\OpenSSL + +for native binaries, or + + C:\Program Files (x86)\OpenSSL + +for 32bit binaries on 64bit Windows (WOW64). + +#### Installing to a different location + +To install OpenSSL to a different location (for example into your home +directory for testing purposes) run `Configure` as shown in the following +examples. + +The options `--prefix` and `--openssldir` are explained in further detail in +[Directories](#directories) below, and the values used here are mere examples. + +On Unix: + + $ ./Configure --prefix=/opt/openssl --openssldir=/usr/local/ssl + +On OpenVMS: + + $ perl Configure --prefix=PROGRAM:[INSTALLS] --openssldir=SYS$MANAGER:[OPENSSL] + +Note: if you do add options to the configuration command, please make sure +you've read more than just this Quick Start, such as relevant `NOTES-*` files, +the options outline below, as configuration options may change the outcome +in otherwise unexpected ways. + +Configuration Options +===================== + +There are several options to `./Configure` to customize the build (note that +for Windows, the defaults for `--prefix` and `--openssldir` depend on what +configuration is used and what Windows implementation OpenSSL is built on. +For more information, see the [Notes for Windows platforms](NOTES-WINDOWS.md). + +API Level +--------- + + --api=x.y[.z] + +Build the OpenSSL libraries to support the API for the specified version. +If [no-deprecated](#no-deprecated) is also given, don't build with support +for deprecated APIs in or below the specified version number. For example, +adding + + --api=1.1.0 no-deprecated + +will remove support for all APIs that were deprecated in OpenSSL version +1.1.0 or below. This is a rather specialized option for developers. +If you just intend to remove all deprecated APIs up to the current version +entirely, just specify [no-deprecated](#no-deprecated). +If `--api` isn't given, it defaults to the current (minor) OpenSSL version. + +Cross Compile Prefix +-------------------- + + --cross-compile-prefix= + +The `` to include in front of commands for your toolchain. + +It is likely to have to end with dash, e.g. `a-b-c-` would invoke GNU compiler +as `a-b-c-gcc`, etc. Unfortunately cross-compiling is too case-specific to put +together one-size-fits-all instructions. You might have to pass more flags or +set up environment variables to actually make it work. Android and iOS cases +are discussed in corresponding `Configurations/15-*.conf` files. But there are +cases when this option alone is sufficient. For example to build the mingw64 +target on Linux `--cross-compile-prefix=x86_64-w64-mingw32-` works. Naturally +provided that mingw packages are installed. Today Debian and Ubuntu users +have option to install a number of prepackaged cross-compilers along with +corresponding run-time and development packages for "alien" hardware. To give +another example `--cross-compile-prefix=mipsel-linux-gnu-` suffices in such +case. + +For cross compilation, you must [configure manually](#manual-configuration). +Also, note that `--openssldir` refers to target's file system, not one you are +building on. + +Build Type +---------- + + --debug + +Build OpenSSL with debugging symbols and zero optimization level. + + --release + +Build OpenSSL without debugging symbols. This is the default. + +Directories +----------- + +### libdir + + --libdir=DIR + +The name of the directory under the top of the installation directory tree +(see the `--prefix` option) where libraries will be installed. By default +this is `lib`. Note that on Windows only static libraries (`*.lib`) will +be stored in this location. Shared libraries (`*.dll`) will always be +installed to the `bin` directory. + +Some build targets have a multilib postfix set in the build configuration. +For these targets the default libdir is `lib`. Please use +`--libdir=lib` to override the libdir if adding the postfix is undesirable. + +### openssldir + + --openssldir=DIR + +Directory for OpenSSL configuration files, and also the default certificate +and key store. Defaults are: + + Unix: /usr/local/ssl + Windows: C:\Program Files\Common Files\SSL + OpenVMS: SYS$COMMON:[OPENSSL-COMMON] + +For 32bit Windows applications on Windows 64bit (WOW64), always replace +`C:\Program Files` by `C:\Program Files (x86)`. + +### prefix + + --prefix=DIR + +The top of the installation directory tree. Defaults are: + + Unix: /usr/local + Windows: C:\Program Files\OpenSSL + OpenVMS: SYS$COMMON:[OPENSSL] + +Compiler Warnings +----------------- + + --strict-warnings + +This is a developer flag that switches on various compiler options recommended +for OpenSSL development. It only works when using gcc or clang as the compiler. +If you are developing a patch for OpenSSL then it is recommended that you use +this option where possible. + +ZLib Flags +---------- + +### with-zlib-include + + --with-zlib-include=DIR + +The directory for the location of the zlib include file. This option is only +necessary if [zlib](#zlib) is used and the include file is not +already on the system include path. + +### with-zlib-lib + + --with-zlib-lib=LIB + +**On Unix**: this is the directory containing the zlib library. +If not provided the system library path will be used. + +**On Windows:** this is the filename of the zlib library (with or +without a path). This flag must be provided if the +[zlib-dynamic](#zlib-dynamic) option is not also used. If `zlib-dynamic` is used +then this flag is optional and defaults to `ZLIB1` if not provided. + +**On VMS:** this is the filename of the zlib library (with or without a path). +This flag is optional and if not provided then `GNV$LIBZSHR`, `GNV$LIBZSHR32` +or `GNV$LIBZSHR64` is used by default depending on the pointer size chosen. + +Seeding the Random Generator +---------------------------- + + --with-rand-seed=seed1[,seed2,...] + +A comma separated list of seeding methods which will be tried by OpenSSL +in order to obtain random input (a.k.a "entropy") for seeding its +cryptographically secure random number generator (CSPRNG). +The current seeding methods are: + +### os + +Use a trusted operating system entropy source. +This is the default method if such an entropy source exists. + +### getrandom + +Use the [getrandom(2)][man-getrandom] or equivalent system call. + +[man-getrandom]: http://man7.org/linux/man-pages/man2/getrandom.2.html + +### 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 most unix-ish operating systems. + +### egd + +Check for an entropy generating daemon. +This source is ignored by the FIPS provider. + +### rdcpu + +Use the `RDSEED` or `RDRAND` command if provided by the CPU. + +### librandom + +Use librandom (not implemented yet). +This source is ignored by the FIPS provider. + +### none + +Disable automatic seeding. This is the default on some operating systems where +no suitable entropy source exists, or no support for it is implemented yet. +This option is ignored by the FIPS provider. + +For more information, see the section [Notes on random number generation][rng] +at the end of this document. + +[rng]: #notes-on-random-number-generation + +Setting the FIPS HMAC key +------------------------- + + --fips-key=value + +As part of its self-test validation, the FIPS module must verify itself +by performing a SHA-256 HMAC computation on itself. The default key is +the SHA256 value of "the holy handgrenade of antioch" and is sufficient +for meeting the FIPS requirements. + +To change the key to a different value, use this flag. The value should +be a hex string no more than 64 characters. + +Enable and Disable Features +--------------------------- + +Feature options always come in pairs, an option to enable feature +`xxxx`, and an option to disable it: + + [ enable-xxxx | no-xxxx ] + +Whether a feature is enabled or disabled by default, depends on the feature. +In the following list, always the non-default variant is documented: if +feature `xxxx` is disabled by default then `enable-xxxx` is documented and +if feature `xxxx` is enabled by default then `no-xxxx` is documented. + +### no-afalgeng + +Don't build the AFALG engine. + +This option will be forced on a platform that does not support AFALG. + +### enable-ktls + +Build with Kernel TLS support. + +This option will enable the use of the Kernel TLS data-path, which can improve +performance and allow for the use of sendfile and splice system calls on +TLS sockets. The Kernel may use TLS accelerators if any are available on the +system. This option will be forced off on systems that do not support the +Kernel TLS data-path. + +### enable-asan + +Build with the Address sanitiser. + +This is a developer option only. It may not work on all platforms and should +never be used in production environments. It will only work when used with +gcc or clang and should be used in conjunction with the [no-shared](#no-shared) +option. + +### enable-acvp-tests + +Build support for Automated Cryptographic Validation Protocol (ACVP) +tests. + +This is required for FIPS validation purposes. Certain ACVP tests require +access to algorithm internals that are not normally accessible. +Additional information related to ACVP can be found at +. + +### no-asm + +Do not use assembler code. + +This should be viewed as debugging/troubleshooting option rather than for +production use. On some platforms a small amount of assembler code may still +be used even with this option. + +### no-async + +Do not build support for async operations. + +### no-autoalginit + +Don't automatically load all supported ciphers and digests. + +Typically OpenSSL will make available all of its supported ciphers and digests. +For a statically linked application this may be undesirable if small executable +size is an objective. This only affects libcrypto. Ciphers and digests will +have to be loaded manually using `EVP_add_cipher()` and `EVP_add_digest()` +if this option is used. This option will force a non-shared build. + +### no-autoerrinit + +Don't automatically load all libcrypto/libssl error strings. + +Typically OpenSSL will automatically load human readable error strings. For a +statically linked application this may be undesirable if small executable size +is an objective. + +### no-autoload-config + +Don't automatically load the default `openssl.cnf` file. + +Typically OpenSSL will automatically load a system config file which configures +default SSL options. + +### enable-buildtest-c++ + +While testing, generate C++ buildtest files that simply check that the public +OpenSSL header files are usable standalone with C++. + +Enabling this option demands extra care. For any compiler flag given directly +as configuration option, you must ensure that it's valid for both the C and +the C++ compiler. If not, the C++ build test will most likely break. As an +alternative, you can use the language specific variables, `CFLAGS` and `CXXFLAGS`. + +### --banner=text + +Use the specified text instead of the default banner at the end of +configuration. + +### --w + +On platforms where the choice of 32-bit or 64-bit architecture +is not explicitly specified, `Configure` will print a warning +message and wait for a few seconds to let you interrupt the +configuration. Using this flag skips the wait. + +### no-bulk + +Build only some minimal set of features. +This is a developer option used internally for CI build tests of the project. + +### no-cached-fetch + +Never cache algorithms when they are fetched from a provider. Normally, a +provider indicates if the algorithms it supplies can be cached or not. Using +this option will reduce run-time memory usage but it also introduces a +significant performance penalty. This option is primarily designed to help +with detecting incorrect reference counting. + +### no-capieng + +Don't build the CAPI engine. + +This option will be forced if on a platform that does not support CAPI. + +### no-cmp + +Don't build support for Certificate Management Protocol (CMP) +and Certificate Request Message Format (CRMF). + +### no-cms + +Don't build support for Cryptographic Message Syntax (CMS). + +### no-comp + +Don't build support for SSL/TLS compression. + +If this option is enabled (the default), then compression will only work if +the zlib or `zlib-dynamic` options are also chosen. + +### enable-crypto-mdebug + +This now only enables the `failed-malloc` feature. + +### enable-crypto-mdebug-backtrace + +This is a no-op; the project uses the compiler's address/leak sanitizer instead. + +### no-ct + +Don't build support for Certificate Transparency (CT). + +### no-deprecated + +Don't build with support for deprecated APIs up until and including the version +given with `--api` (or the current version, if `--api` wasn't specified). + +### no-dgram + +Don't build support for datagram based BIOs. + +Selecting this option will also force the disabling of DTLS. + +### no-dso + +Don't build support for loading Dynamic Shared Objects (DSO) + +### enable-devcryptoeng + +Build the `/dev/crypto` engine. + +This option is automatically selected on the BSD platform, in which case it can +be disabled with `no-devcryptoeng`. + +### no-dynamic-engine + +Don't build the dynamically loaded engines. + +This only has an effect in a shared build. + +### no-ec + +Don't build support for Elliptic Curves. + +### no-ec2m + +Don't build support for binary Elliptic Curves + +### enable-ec_nistp_64_gcc_128 + +Enable support for optimised implementations of some commonly used NIST +elliptic curves. + +This option is only supported on platforms: + + - with little-endian storage of non-byte types + - that tolerate misaligned memory references + - where the compiler: + - supports the non-standard type `__uint128_t` + - defines the built-in macro `__SIZEOF_INT128__` + +### enable-egd + +Build support for gathering entropy from the Entropy Gathering Daemon (EGD). + +### no-engine + +Don't build support for loading engines. + +### no-err + +Don't compile in any error strings. + +### enable-external-tests + +Enable building of integration with external test suites. + +This is a developer option and may not work on all platforms. The following +external test suites are currently supported: + + - GOST engine test suite + - Python PYCA/Cryptography test suite + - krb5 test suite + +See the file [test/README-external.md](test/README-external.md) +for further details. + +### no-filenames + +Don't compile in filename and line number information (e.g. for errors and +memory allocation). + +### enable-fips + +Build (and install) the FIPS provider + +### no-fips-securitychecks + +Don't perform FIPS module run-time checks related to enforcement of security +parameters such as minimum security strength of keys. + +### enable-fuzz-libfuzzer, enable-fuzz-afl + +Build with support for fuzzing using either libfuzzer or AFL. + +These are developer options only. They may not work on all platforms and +should never be used in production environments. + +See the file [fuzz/README.md](fuzz/README.md) for further details. + +### no-gost + +Don't build support for GOST based ciphersuites. + +Note that if this feature is enabled then GOST ciphersuites are only available +if the GOST algorithms are also available through loading an externally supplied +engine. + +### no-legacy + +Don't build the legacy provider. + +Disabling this also disables the legacy algorithms: MD2 (already disabled by default). + +### no-makedepend + +Don't generate dependencies. + +### no-module + +Don't build any dynamically loadable engines. + +This also implies `no-dynamic-engine`. + +### no-multiblock + +Don't build support for writing multiple records in one go in libssl + +Note: this is a different capability to the pipelining functionality. + +### no-nextprotoneg + +Don't build support for the Next Protocol Negotiation (NPN) TLS extension. + +### no-ocsp + +Don't build support for Online Certificate Status Protocol (OCSP). + +### no-padlockeng + +Don't build the padlock engine. + +### no-hw-padlock + +As synonym for `no-padlockeng`. Deprecated and should not be used. + +### no-pic + +Don't build with support for Position Independent Code. + +### no-pinshared + +Don't pin the shared libraries. + +By default OpenSSL will attempt to stay in memory until the process exits. +This is so that libcrypto and libssl can be properly cleaned up automatically +via an `atexit()` handler. The handler is registered by libcrypto and cleans +up both libraries. On some platforms the `atexit()` handler will run on unload of +libcrypto (if it has been dynamically loaded) rather than at process exit. This +option can be used to stop OpenSSL from attempting to stay in memory until the +process exits. This could lead to crashes if either libcrypto or libssl have +already been unloaded at the point that the atexit handler is invoked, e.g. on a +platform which calls `atexit()` on unload of the library, and libssl is unloaded +before libcrypto then a crash is likely to happen. Applications can suppress +running of the `atexit()` handler at run time by using the +`OPENSSL_INIT_NO_ATEXIT` option to `OPENSSL_init_crypto()`. +See the man page for it for further details. + +### no-posix-io + +Don't use POSIX IO capabilities. + +### no-psk + +Don't build support for Pre-Shared Key based ciphersuites. + +### no-rdrand + +Don't use hardware RDRAND capabilities. + +### no-rfc3779 + +Don't build support for RFC3779, "X.509 Extensions for IP Addresses and +AS Identifiers". + +### sctp + +Build support for Stream Control Transmission Protocol (SCTP). + +### no-shared + +Do not create shared libraries, only static ones. + +See [Notes on shared libraries](#notes-on-shared-libraries) below. + +### no-sock + +Don't build support for socket BIOs. + +### no-srp + +Don't build support for Secure Remote Password (SRP) protocol or +SRP based ciphersuites. + +### no-srtp + +Don't build Secure Real-Time Transport Protocol (SRTP) support. + +### no-sse2 + +Exclude SSE2 code paths from 32-bit x86 assembly modules. + +Normally SSE2 extension is detected at run-time, but the decision whether or not +the machine code will be executed is taken solely on CPU capability vector. This +means that if you happen to run OS kernel which does not support SSE2 extension +on Intel P4 processor, then your application might be exposed to "illegal +instruction" exception. There might be a way to enable support in kernel, e.g. +FreeBSD kernel can be compiled with `CPU_ENABLE_SSE`, and there is a way to +disengage SSE2 code paths upon application start-up, but if you aim for wider +"audience" running such kernel, consider `no-sse2`. Both the `386` and `no-asm` +options imply `no-sse2`. + +### no-ssl-trace + +Don't build with SSL Trace capabilities. + +This removes the `-trace` option from `s_client` and `s_server`, and omits the +`SSL_trace()` function from libssl. + +Disabling `ssl-trace` may provide a small reduction in libssl binary size. + +### no-static-engine + +Don't build the statically linked engines. + +This only has an impact when not built "shared". + +### no-stdio + +Don't use anything from the C header file `stdio.h` that makes use of the `FILE` +type. Only libcrypto and libssl can be built in this way. Using this option will +suppress building the command line applications. Additionally, since the OpenSSL +tests also use the command line applications, the tests will also be skipped. + +### no-tests + +Don't build test programs or run any tests. + +### no-threads + +Don't build with support for multi-threaded applications. + +### threads + +Build with support for multi-threaded applications. Most platforms will enable +this by default. However, if on a platform where this is not the case then this +will usually require additional system-dependent options! + +See [Notes on multi-threading](#notes-on-multi-threading) below. + +### enable-trace + +Build with support for the integrated tracing api. + +See manual pages OSSL_trace_set_channel(3) and OSSL_trace_enabled(3) for details. + +### no-ts + +Don't build Time Stamping (TS) Authority support. + +### enable-ubsan + +Build with the Undefined Behaviour sanitiser (UBSAN). + +This is a developer option only. It may not work on all platforms and should +never be used in production environments. It will only work when used with +gcc or clang and should be used in conjunction with the `-DPEDANTIC` option +(or the `--strict-warnings` option). + +### no-ui-console + +Don't build with the User Interface (UI) console method + +The User Interface console method enables text based console prompts. + +### enable-unit-test + +Enable additional unit test APIs. + +This should not typically be used in production deployments. + +### no-uplink + +Don't build support for UPLINK interface. + +### enable-weak-ssl-ciphers + +Build support for SSL/TLS ciphers that are considered "weak" + +Enabling this includes for example the RC4 based ciphersuites. + +### zlib + +Build with support for zlib compression/decompression. + +### zlib-dynamic + +Like the zlib option, but has OpenSSL load the zlib library dynamically +when needed. + +This is only supported on systems where loading of shared libraries is supported. + +### 386 + +In 32-bit x86 builds, use the 80386 instruction set only in assembly modules + +The default x86 code is more efficient, but requires at least an 486 processor. +Note: This doesn't affect compiler generated code, so this option needs to be +accompanied by a corresponding compiler-specific option. + +### no-{protocol} + + no-{ssl|ssl3|tls|tls1|tls1_1|tls1_2|tls1_3|dtls|dtls1|dtls1_2} + +Don't build support for negotiating the specified SSL/TLS protocol. + +If `no-tls` is selected then all of `tls1`, `tls1_1`, `tls1_2` and `tls1_3` +are disabled. +Similarly `no-dtls` will disable `dtls1` and `dtls1_2`. The `no-ssl` option is +synonymous with `no-ssl3`. Note this only affects version negotiation. +OpenSSL will still provide the methods for applications to explicitly select +the individual protocol versions. + +### no-{protocol}-method + + no-{ssl3|tls1|tls1_1|tls1_2|dtls1|dtls1_2}-method + +Analogous to `no-{protocol}` but in addition do not build the methods for +applications to explicitly select individual protocol versions. Note that there +is no `no-tls1_3-method` option because there is no application method for +TLSv1.3. + +Using individual protocol methods directly is deprecated. Applications should +use `TLS_method()` instead. + +### enable-{algorithm} + + enable-{md2|rc5} + +Build with support for the specified algorithm. + +### no-{algorithm} + + no-{aria|bf|blake2|camellia|cast|chacha|cmac| + des|dh|dsa|ecdh|ecdsa|idea|md4|mdc2|ocb| + poly1305|rc2|rc4|rmd160|scrypt|seed| + siphash|siv|sm2|sm3|sm4|whirlpool} + +Build without support for the specified algorithm. + +The `ripemd` algorithm is deprecated and if used is synonymous with `rmd160`. + +### Compiler-specific options + + -Dxxx, -Ixxx, -Wp, -lxxx, -Lxxx, -Wl, -rpath, -R, -framework, -static + +These system specific options will be recognised and passed through to the +compiler to allow you to define preprocessor symbols, specify additional +libraries, library directories or other compiler options. It might be worth +noting that some compilers generate code specifically for processor the +compiler currently executes on. This is not necessarily what you might have +in mind, since it might be unsuitable for execution on other, typically older, +processor. Consult your compiler documentation. + +Take note of the [Environment Variables](#environment-variables) documentation +below and how these flags interact with those variables. + + -xxx, +xxx, /xxx + +Additional options that are not otherwise recognised are passed through as +they are to the compiler as well. Unix-style options beginning with a +`-` or `+` and Windows-style options beginning with a `/` are recognized. +Again, consult your compiler documentation. + +If the option contains arguments separated by spaces, then the URL-style +notation `%20` can be used for the space character in order to avoid having +to quote the option. For example, `-opt%20arg` gets expanded to `-opt arg`. +In fact, any ASCII character can be encoded as %xx using its hexadecimal +encoding. + +Take note of the [Environment Variables](#environment-variables) documentation +below and how these flags interact with those variables. + +### Environment Variables + + VAR=value + +Assign the given value to the environment variable `VAR` for `Configure`. + +These work just like normal environment variable assignments, but are supported +on all platforms and are confined to the configuration scripts only. +These assignments override the corresponding value in the inherited environment, +if there is one. + +The following variables are used as "`make` variables" and can be used as an +alternative to giving preprocessor, compiler and linker options directly as +configuration. The following variables are supported: + + AR The static library archiver. + ARFLAGS Flags for the static library archiver. + AS The assembler compiler. + ASFLAGS Flags for the assembler compiler. + CC The C compiler. + CFLAGS Flags for the C compiler. + CXX The C++ compiler. + CXXFLAGS Flags for the C++ compiler. + CPP The C/C++ preprocessor. + CPPFLAGS Flags for the C/C++ preprocessor. + CPPDEFINES List of CPP macro definitions, separated + by a platform specific character (':' or + space for Unix, ';' for Windows, ',' for + VMS). This can be used instead of using + -D (or what corresponds to that on your + compiler) in CPPFLAGS. + CPPINCLUDES List of CPP inclusion directories, separated + the same way as for CPPDEFINES. This can + be used instead of -I (or what corresponds + to that on your compiler) in CPPFLAGS. + HASHBANGPERL Perl invocation to be inserted after '#!' + in public perl scripts (only relevant on + Unix). + LD The program linker (not used on Unix, $(CC) + is used there). + LDFLAGS Flags for the shared library, DSO and + program linker. + LDLIBS Extra libraries to use when linking. + Takes the form of a space separated list + of library specifications on Unix and + Windows, and as a comma separated list of + libraries on VMS. + RANLIB The library archive indexer. + RC The Windows resource compiler. + RCFLAGS Flags for the Windows resource compiler. + RM The command to remove files and directories. + +These cannot be mixed with compiling/linking flags given on the command line. +In other words, something like this isn't permitted. + + $ ./Configure -DFOO CPPFLAGS=-DBAR -DCOOKIE + +Backward compatibility note: + +To be compatible with older configuration scripts, the environment variables +are ignored if compiling/linking flags are given on the command line, except +for the following: + + AR, CC, CXX, CROSS_COMPILE, HASHBANGPERL, PERL, RANLIB, RC, and WINDRES + +For example, the following command will not see `-DBAR`: + + $ CPPFLAGS=-DBAR ./Configure -DCOOKIE + +However, the following will see both set variables: + + $ CC=gcc CROSS_COMPILE=x86_64-w64-mingw32- ./Configure -DCOOKIE + +If `CC` is set, it is advisable to also set `CXX` to ensure both the C and C++ +compiler are in the same "family". This becomes relevant with +`enable-external-tests` and `enable-buildtest-c++`. + +### Reconfigure + + reconf + reconfigure + +Reconfigure from earlier data. + +This fetches the previous command line options and environment from data +saved in `configdata.pm` and runs the configuration process again, using +these options and environment. Note: NO other option is permitted together +with `reconf`. Note: The original configuration saves away values for ALL +environment variables that were used, and if they weren't defined, they are +still saved away with information that they weren't originally defined. +This information takes precedence over environment variables that are +defined when reconfiguring. + +Displaying configuration data +----------------------------- + +The configuration script itself will say very little, and finishes by +creating `configdata.pm`. This perl module can be loaded by other scripts +to find all the configuration data, and it can also be used as a script to +display all sorts of configuration data in a human readable form. + +For more information, please do: + + $ ./configdata.pm --help # Unix + +or + + $ perl configdata.pm --help # Windows and VMS + +Installation Steps in Detail +============================ + +Configure OpenSSL +----------------- + +### Automatic Configuration + +In previous version, the `config` script determined the platform type and +compiler and then called `Configure`. Starting with this release, they are +the same. + +#### Unix / Linux / macOS + + $ ./Configure [[ options ]] + +#### OpenVMS + + $ perl Configure [[ options ]] + +#### Windows + + $ perl Configure [[ options ]] + +### Manual Configuration + +OpenSSL knows about a range of different operating system, hardware and +compiler combinations. To see the ones it knows about, run + + $ ./Configure LIST # Unix + +or + + $ perl Configure LIST # All other platforms + +For the remainder of this text, the Unix form will be used in all examples. +Please use the appropriate form for your platform. + +Pick a suitable name from the list that matches your system. For most +operating systems there is a choice between using cc or gcc. +When you have identified your system (and if necessary compiler) use this +name as the argument to `Configure`. For example, a `linux-elf` user would +run: + + $ ./Configure linux-elf [[ options ]] + +### Creating your own Configuration + +If your system isn't listed, you will have to create a configuration +file named `Configurations/{{ something }}.conf` and add the correct +configuration for your system. See the available configs as examples +and read [Configurations/README.md](Configurations/README.md) and +[Configurations/README-design.md](Configurations/README-design.md) +for more information. + +The generic configurations `cc` or `gcc` should usually work on 32 bit +Unix-like systems. + +`Configure` creates a build file (`Makefile` on Unix, `makefile` on Windows +and `descrip.mms` on OpenVMS) from a suitable template in `Configurations/`, +and defines various macros in `include/openssl/configuration.h` (generated +from `include/openssl/configuration.h.in`. + +If none of the generated build files suit your purpose, it's possible to +write your own build file template and give its name through the environment +variable `BUILDFILE`. For example, Ninja build files could be supported by +writing `Configurations/build.ninja.tmpl` and then configure with `BUILDFILE` +set like this (Unix syntax shown, you'll have to adapt for other platforms): + + $ BUILDFILE=build.ninja perl Configure [options...] + +### Out of Tree Builds + +OpenSSL can be configured to build in a build directory separate from the +source code directory. It's done by placing yourself in some other +directory and invoking the configuration commands from there. + +#### Unix example + + $ mkdir /var/tmp/openssl-build + $ cd /var/tmp/openssl-build + $ /PATH/TO/OPENSSL/SOURCE/Configure [[ options ]] + +#### OpenVMS example + + $ set default sys$login: + $ create/dir [.tmp.openssl-build] + $ set default [.tmp.openssl-build] + $ perl D:[PATH.TO.OPENSSL.SOURCE]Configure [[ options ]] + +#### Windows example + + $ C: + $ mkdir \temp-openssl + $ cd \temp-openssl + $ perl d:\PATH\TO\OPENSSL\SOURCE\Configure [[ options ]] + +Paths can be relative just as well as absolute. `Configure` will do its best +to translate them to relative paths whenever possible. + +Build OpenSSL +------------- + +Build OpenSSL by running: + + $ make # Unix + $ mms ! (or mmk) OpenVMS + $ nmake # Windows + +This will build the OpenSSL libraries (`libcrypto.a` and `libssl.a` on +Unix, corresponding on other platforms) and the OpenSSL binary +(`openssl`). The libraries will be built in the top-level directory, +and the binary will be in the `apps/` subdirectory. + +If the build fails, take a look at the [Build Failures](#build-failures) +subsection of the [Troubleshooting](#troubleshooting) section. + +Test OpenSSL +------------ + +After a successful build, and before installing, the libraries should +be tested. Run: + + $ make test # Unix + $ mms test ! OpenVMS + $ nmake test # Windows + +**Warning:** you MUST run the tests from an unprivileged account (or disable +your privileges temporarily if your platform allows it). + +See [test/README.md](test/README.md) for further details how run tests. + +See [test/README-dev.md](test/README-dev.md) for guidelines on adding tests. + +Install OpenSSL +--------------- + +If everything tests ok, install OpenSSL with + + $ make install # Unix + $ mms install ! OpenVMS + $ nmake install # Windows + +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 `` (the directory given with `--prefix` or +its default): + +### Unix / Linux / macOS + + bin/ Contains the openssl binary and a few other + utility scripts. + include/openssl + Contains the header files needed if you want + to build your own programs that use libcrypto + or libssl. + lib Contains the OpenSSL library files. + lib/engines Contains the OpenSSL dynamically loadable engines. + + share/man/man1 Contains the OpenSSL command line man-pages. + share/man/man3 Contains the OpenSSL library calls man-pages. + share/man/man5 Contains the OpenSSL configuration format man-pages. + share/man/man7 Contains the OpenSSL other misc man-pages. + + share/doc/openssl/html/man1 + share/doc/openssl/html/man3 + share/doc/openssl/html/man5 + share/doc/openssl/html/man7 + Contains the HTML rendition of the man-pages. + +### OpenVMS + +'arch' is replaced with the architecture name, `ALPHA` or `IA64`, +'sover' is replaced with the shared library version (`0101` for 1.1), and +'pz' is replaced with the pointer size OpenSSL was built with: + + [.EXE.'arch'] Contains the openssl binary. + [.EXE] Contains a few utility scripts. + [.include.openssl] + Contains the header files needed if you want + to build your own programs that use libcrypto + or libssl. + [.LIB.'arch'] Contains the OpenSSL library files. + [.ENGINES'sover''pz'.'arch'] + Contains the OpenSSL dynamically loadable engines. + [.SYS$STARTUP] Contains startup, login and shutdown scripts. + These define appropriate logical names and + command symbols. + [.SYSTEST] Contains the installation verification procedure. + [.HTML] Contains the HTML rendition of the manual pages. + +### Additional Directories + +Additionally, install will add the following directories under +OPENSSLDIR (the directory given with `--openssldir` or its default) +for you convenience: + + certs Initially empty, this is the default location + for certificate files. + private Initially empty, this is the default location + 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 + + $ make DESTDIR=/tmp/package-root install # Unix + $ mms/macro="DESTDIR=TMP:[PACKAGE-ROOT]" install ! OpenVMS + +The specified destination directory will be prepended to all installation +target paths. + +Compatibility issues with previous OpenSSL versions +--------------------------------------------------- + +### COMPILING existing applications + +Starting with version 1.1.0, OpenSSL hides a number of structures that were +previously open. This includes all internal libssl structures and a number +of EVP types. Accessor functions have been added to allow controlled access +to the structures' data. + +This means that some software needs to be rewritten to adapt to the new ways +of doing things. This often amounts to allocating an instance of a structure +explicitly where you could previously allocate them on the stack as automatic +variables, and using the provided accessor functions where you would previously +access a structure's field directly. + +Some APIs have changed as well. However, older APIs have been preserved when +possible. + +Post-installation Notes +----------------------- + +With the default OpenSSL installation comes a FIPS provider module, which +needs some post-installation attention, without which it will not be usable. +This involves using the following command: + + $ openssl fipsinstall + +See the openssl-fipsinstall(1) manual for details and examples. + +Advanced Build Options +====================== + +Environment Variables +--------------------- + +A number of environment variables can be used to provide additional control +over the build process. Typically these should be defined prior to running +`Configure`. Not all environment variables are relevant to all platforms. + + AR + The name of the ar executable to use. + + BUILDFILE + Use a different build file name than the platform default + ("Makefile" on Unix-like platforms, "makefile" on native Windows, + "descrip.mms" on OpenVMS). This requires that there is a + corresponding build file template. + See [Configurations/README.md](Configurations/README.md) + for further information. + + CC + The compiler to use. Configure will attempt to pick a default + compiler for your platform but this choice can be overridden + using this variable. Set it to the compiler executable you wish + to use, e.g. gcc or clang. + + CROSS_COMPILE + This environment variable has the same meaning as for the + "--cross-compile-prefix" Configure flag described above. If both + are set then the Configure flag takes precedence. + + HASHBANGPERL + The command string for the Perl executable to insert in the + #! line of perl scripts that will be publicly installed. + Default: /usr/bin/env perl + Note: the value of this variable is added to the same scripts + on all platforms, but it's only relevant on Unix-like platforms. + + KERNEL_BITS + This can be the value `32` or `64` to specify the architecture + when it is not "obvious" to the configuration. It should generally + not be necessary to specify this environment variable. + + NM + The name of the nm executable to use. + + OPENSSL_LOCAL_CONFIG_DIR + OpenSSL comes with a database of information about how it + should be built on different platforms as well as build file + templates for those platforms. The database is comprised of + ".conf" files in the Configurations directory. The build + file templates reside there as well as ".tmpl" files. See the + file [Configurations/README.md](Configurations/README.md) + for further information about the format of ".conf" files + as well as information on the ".tmpl" files. + In addition to the standard ".conf" and ".tmpl" files, it is + possible to create your own ".conf" and ".tmpl" files and + store them locally, outside the OpenSSL source tree. + This environment variable can be set to the directory where + these files are held and will be considered by Configure + before it looks in the standard directories. + + PERL + The name of the Perl executable to use when building OpenSSL. + Only needed if builing should use a different Perl executable + than what is used to run the Configure script. + + RANLIB + The name of the ranlib executable to use. + + RC + The name of the rc executable to use. The default will be as + defined for the target platform in the ".conf" file. If not + defined then "windres" will be used. The WINDRES environment + variable is synonymous to this. If both are defined then RC + takes precedence. + + WINDRES + See RC. + +Makefile Targets +---------------- + +The `Configure` script generates a Makefile in a format relevant to the specific +platform. The Makefiles provide a number of targets that can be used. Not all +targets may be available on all platforms. Only the most common targets are +described here. Examine the Makefiles themselves for the full list. + + all + The target to build all the software components and + documentation. + + build_sw + Build all the software components. + THIS IS THE DEFAULT TARGET. + + build_docs + Build all documentation components. + + clean + Remove all build artefacts and return the directory to a "clean" + state. + + depend + Rebuild the dependencies in the Makefiles. This is a legacy + option that no longer needs to be used since OpenSSL 1.1.0. + + install + Install all OpenSSL components. + + install_sw + Only install the OpenSSL software components. + + install_docs + Only install the OpenSSL documentation components. + + install_man_docs + Only install the OpenSSL man pages (Unix only). + + install_html_docs + Only install the OpenSSL HTML documentation. + + install_fips + Install the FIPS provider module configuration file. + + list-tests + Prints a list of all the self test names. + + test + Build and run the OpenSSL self tests. + + uninstall + Uninstall all OpenSSL components. + + reconfigure + reconf + Re-run the configuration process, as exactly as the last time + as possible. + + update + This is a developer option. If you are developing a patch for + OpenSSL you may need to use this if you want to update + automatically generated files; add new error codes or add new + (or change the visibility of) public API functions. (Unix only). + +Running Selected Tests +---------------------- + +You can specify a set of tests to be performed +using the `make` variable `TESTS`. + +See the section [Running Selected Tests of +test/README.md](test/README.md#running-selected-tests). + +Troubleshooting +=============== + +Configuration Problems +---------------------- + +### Selecting the correct target + +The `./Configure` script tries hard to guess your operating system, but in some +cases it does not succeed. You will see a message like the following: + + $ ./Configure + Operating system: x86-whatever-minix + This system (minix) is not supported. See file INSTALL.md for details. + +Even if the automatic target selection by the `./Configure` script fails, +chances are that you still might find a suitable target in the `Configurations` +directory, which you can supply to the `./Configure` command, +possibly after some adjustment. + +The `Configurations/` directory contains a lot of examples of such targets. +The main configuration file is [10-main.conf], which contains all targets that +are officially supported by the OpenSSL team. Other configuration files contain +targets contributed by other OpenSSL users. The list of targets can be found in +a Perl list `my %targets = ( ... )`. + + my %targets = ( + ... + "target-name" => { + inherit_from => [ "base-target" ], + CC => "...", + cflags => add("..."), + asm_arch => '...', + perlasm_scheme => "...", + }, + ... + ) + +If you call `./Configure` without arguments, it will give you a list of all +known targets. Using `grep`, you can lookup the target definition in the +`Configurations/` directory. For example the `android-x86_64` can be found in +[Configurations/15-android.conf](Configurations/15-android.conf). + +The directory contains two README files, which explain the general syntax and +design of the configuration files. + + - [Configurations/README.md](Configurations/README.md) + - [Configurations/README-design.md](Configurations/README-design.md) + +If you need further help, try to search the [openssl-users] mailing list +or the [GitHub Issues] for existing solutions. If you don't find anything, +you can [raise an issue] to ask a question yourself. + +More about our support resources can be found in the [SUPPORT] file. + +### Configuration Errors + +If the `./Configure` or `./Configure` command fails with an error message, +read the error message carefully and try to figure out whether you made +a mistake (e.g., by providing a wrong option), or whether the script is +working incorrectly. If you think you encountered a bug, please +[raise an issue] on GitHub to file a bug report. + +Along with a short description of the bug, please provide the complete +configure command line and the relevant output including the error message. + +Note: To make the output readable, pleace add a 'code fence' (three backquotes +` ``` ` on a separate line) before and after your output: + + ``` + ./Configure [your arguments...] + + [output...] + + ``` + +Build Failures +-------------- + +If the build fails, look carefully at the output. Try to locate and understand +the error message. It might be that the compiler is already telling you +exactly what you need to do to fix your problem. + +There may be reasons for the failure that aren't problems in OpenSSL itself, +for example if the compiler reports missing standard or third party headers. + +If the build succeeded previously, but fails after a source or configuration +change, it might be helpful to clean the build tree before attempting another +build. Use this command: + + $ make clean # Unix + $ mms clean ! (or mmk) OpenVMS + $ nmake clean # Windows + +Assembler error messages can sometimes be sidestepped by using the `no-asm` +configuration option. See also [notes](#notes-on-assembler-modules-compilation). + +Compiling parts of OpenSSL with gcc and others with the system compiler will +result in unresolved symbols on some systems. + +If you are still having problems, try to search the [openssl-users] mailing +list or the [GitHub Issues] for existing solutions. If you think you +encountered an OpenSSL bug, please [raise an issue] to file a bug report. +Please take the time to review the existing issues first; maybe the bug was +already reported or has already been fixed. + +Test Failures +------------- + +If some tests fail, look at the output. There may be reasons for the failure +that isn't a problem in OpenSSL itself (like an OS malfunction or a Perl issue). + +You may want increased verbosity, that can be accomplished as described in +section [Test Failures of test/README.md](test/README.md#test-failures). + +You may also want to selectively specify which test(s) to perform. This can be +done using the `make` variable `TESTS` as described in section [Running +Selected Tests of test/README.md](test/README.md#running-selected-tests). + +If you find a problem with OpenSSL itself, try removing any +compiler optimization flags from the `CFLAGS` line in the Makefile and +run `make clean; make` or corresponding. + +To report a bug please open an issue on GitHub, at +. + +Notes +===== + +Notes on multi-threading +------------------------ + +For some systems, the OpenSSL `Configure` script knows what compiler options +are needed to generate a library that is suitable for multi-threaded +applications. On these systems, support for multi-threading is enabled +by default; use the `no-threads` option to disable (this should never be +necessary). + +On other systems, to enable support for multi-threading, you will have +to specify at least two options: `threads`, and a system-dependent option. +(The latter is `-D_REENTRANT` on various systems.) The default in this +case, obviously, is not to include support for multi-threading (but +you can still use `no-threads` to suppress an annoying warning message +from the `Configure` script.) + +OpenSSL provides built-in support for two threading models: pthreads (found on +most UNIX/Linux systems), and Windows threads. No other threading models are +supported. If your platform does not provide pthreads or Windows threads then +you should use `Configure` with the `no-threads` option. + +For pthreads, all locks are non-recursive. In addition, in a debug build, +the mutex attribute `PTHREAD_MUTEX_ERRORCHECK` is used. If this is not +available on your platform, you might have to add +`-DOPENSSL_NO_MUTEX_ERRORCHECK` to your `Configure` invocation. +(On Linux `PTHREAD_MUTEX_ERRORCHECK` is an enum value, so a built-in +ifdef test cannot be used.) + +Notes on shared libraries +------------------------- + +For most systems the OpenSSL `Configure` script knows what is needed to +build shared libraries for libcrypto and libssl. On these systems +the shared libraries will be created by default. This can be suppressed and +only static libraries created by using the `no-shared` option. On systems +where OpenSSL does not know how to build shared libraries the `no-shared` +option will be forced and only static libraries will be created. + +Shared libraries are named a little differently on different platforms. +One way or another, they all have the major OpenSSL version number as +part of the file name, i.e. for OpenSSL 1.1.x, `1.1` is somehow part of +the name. + +On most POSIX platforms, shared libraries are named `libcrypto.so.1.1` +and `libssl.so.1.1`. + +on Cygwin, shared libraries are named `cygcrypto-1.1.dll` and `cygssl-1.1.dll` +with import libraries `libcrypto.dll.a` and `libssl.dll.a`. + +On Windows build with MSVC or using MingW, shared libraries are named +`libcrypto-1_1.dll` and `libssl-1_1.dll` for 32-bit Windows, +`libcrypto-1_1-x64.dll` and `libssl-1_1-x64.dll` for 64-bit x86_64 Windows, +and `libcrypto-1_1-ia64.dll` and `libssl-1_1-ia64.dll` for IA64 Windows. +With MSVC, the import libraries are named `libcrypto.lib` and `libssl.lib`, +while with MingW, they are named `libcrypto.dll.a` and `libssl.dll.a`. + +On VMS, shareable images (VMS speak for shared libraries) are named +`ossl$libcrypto0101_shr.exe` and `ossl$libssl0101_shr.exe`. However, when +OpenSSL is specifically built for 32-bit pointers, the shareable images +are named `ossl$libcrypto0101_shr32.exe` and `ossl$libssl0101_shr32.exe` +instead, and when built for 64-bit pointers, they are named +`ossl$libcrypto0101_shr64.exe` and `ossl$libssl0101_shr64.exe`. + +Notes on random number generation +--------------------------------- + +Availability of cryptographically secure random numbers is required for +secret key generation. OpenSSL provides several options to seed the +internal CSPRNG. If not properly seeded, the internal CSPRNG will refuse +to deliver random bytes and a "PRNG not seeded error" will occur. + +The seeding method can be configured using the `--with-rand-seed` option, +which can be used to specify a comma separated list of seed methods. +However, in most cases OpenSSL will choose a suitable default method, +so it is not necessary to explicitly provide this option. Note also +that not all methods are available on all platforms. The FIPS provider will +silently ignore seed sources that were not validated. + +I) On operating systems which provide a suitable randomness source (in +form of a system call or system device), OpenSSL will use the optimal +available method to seed the CSPRNG from the operating system's +randomness sources. This corresponds to the option `--with-rand-seed=os`. + +II) On systems without such a suitable randomness source, automatic seeding +and reseeding is disabled (`--with-rand-seed=none`) and it may be necessary +to install additional support software to obtain a random seed and reseed +the CSPRNG manually. Please check out the manual pages for `RAND_add()`, +`RAND_bytes()`, `RAND_egd()`, and the FAQ for more information. + +Notes on assembler modules compilation +-------------------------------------- + +Compilation of some code paths in assembler modules might depend on whether the +current assembler version supports certain ISA extensions or not. Code paths +that use the AES-NI, PCLMULQDQ, SSSE3, and SHA extensions are always assembled. +Apart from that, the minimum requirements for the assembler versions are shown +in the table below: + +| ISA extension | GNU as | nasm | llvm | +|---------------|--------|--------|---------| +| AVX | 2.19 | 2.09 | 3.0 | +| AVX2 | 2.22 | 2.10 | 3.1 | +| ADCX/ADOX | 2.23 | 2.10 | 3.3 | +| AVX512 | 2.25 | 2.11.8 | 3.6 (*) | +| AVX512IFMA | 2.26 | 2.11.8 | 6.0 (*) | +| VAES | 2.30 | 2.13.3 | 6.0 (*) | + +--- + +(*) Even though AVX512 support was implemented in llvm 3.6, prior to version 7.0 +an explicit -march flag was apparently required to compile assembly modules. But +then the compiler generates processor-specific code, which in turn contradicts +the idea of performing dispatch at run-time, which is facilitated by the special +variable `OPENSSL_ia32cap`. For versions older than 7.0, it is possible to work +around the problem by forcing the build procedure to use the following script: + + #!/bin/sh + exec clang -no-integrated-as "$@" + +instead of the real clang. In which case it doesn't matter what clang version +is used, as it is the version of the GNU assembler that will be checked. + +--- + + + +[openssl-users]: + + +[SUPPORT]: + ./SUPPORT.md + +[GitHub Issues]: + + +[raise an issue]: + + +[10-main.conf]: + Configurations/10-main.conf diff --git a/crypto/openssl/LICENSE b/crypto/openssl/LICENSE deleted file mode 100644 index 9601ab43575f..000000000000 --- a/crypto/openssl/LICENSE +++ /dev/null @@ -1,125 +0,0 @@ - - LICENSE ISSUES - ============== - - The OpenSSL toolkit stays under a double license, i.e. both the conditions of - the OpenSSL License and the original SSLeay license apply to the toolkit. - See below for the actual license texts. - - OpenSSL License - --------------- - -/* ==================================================================== - * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - - Original SSLeay License - ----------------------- - -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - diff --git a/crypto/openssl/LICENSE.txt b/crypto/openssl/LICENSE.txt new file mode 100644 index 000000000000..49cc83d2ee29 --- /dev/null +++ b/crypto/openssl/LICENSE.txt @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/crypto/openssl/NEWS b/crypto/openssl/NEWS deleted file mode 100644 index 2724fc4d85ba..000000000000 --- a/crypto/openssl/NEWS +++ /dev/null @@ -1,1045 +0,0 @@ - - NEWS - ==== - - 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.1s and OpenSSL 1.1.1t [7 Feb 2023] - - o Fixed X.400 address type confusion in X.509 GeneralName (CVE-2023-0286) - o Fixed Use-after-free following BIO_new_NDEF (CVE-2023-0215) - o Fixed Double free after calling PEM_read_bio_ex (CVE-2022-4450) - o Fixed Timing Oracle in RSA Decryption (CVE-2022-4304) - - Major changes between OpenSSL 1.1.1r and OpenSSL 1.1.1s [1 Nov 2022] - - o Fixed a regression introduced in OpenSSL 1.1.1r not refreshing the - certificate data to be signed before signing the certificate. - - Major changes between OpenSSL 1.1.1q and OpenSSL 1.1.1r [11 Oct 2022] - - o Added a missing header for memcmp that caused compilation failure on - some platforms - - Major changes between OpenSSL 1.1.1p and OpenSSL 1.1.1q [5 Jul 2022] - - o Fixed AES OCB failure to encrypt some bytes on 32-bit x86 platforms - (CVE-2022-2097) - - Major changes between OpenSSL 1.1.1o and OpenSSL 1.1.1p [21 Jun 2022] - - o Fixed additional bugs in the c_rehash script which was not properly - sanitising shell metacharacters to prevent command injection - (CVE-2022-2068) - - Major changes between OpenSSL 1.1.1n and OpenSSL 1.1.1o [3 May 2022] - - o Fixed a bug in the c_rehash script which was not properly sanitising - shell metacharacters to prevent command injection (CVE-2022-1292) - - Major changes between OpenSSL 1.1.1m and OpenSSL 1.1.1n [15 Mar 2022] - - o Fixed a bug in the BN_mod_sqrt() function that can cause it to loop - forever for non-prime moduli (CVE-2022-0778) - - Major changes between OpenSSL 1.1.1l and OpenSSL 1.1.1m [14 Dec 2021] - - o None - - Major changes between OpenSSL 1.1.1k and OpenSSL 1.1.1l [24 Aug 2021] - - o Fixed an SM2 Decryption Buffer Overflow (CVE-2021-3711) - o Fixed various read buffer overruns processing ASN.1 strings (CVE-2021-3712) - - Major changes between OpenSSL 1.1.1j and OpenSSL 1.1.1k [25 Mar 2021] - - o Fixed a problem with verifying a certificate chain when using the - X509_V_FLAG_X509_STRICT flag (CVE-2021-3450) - o Fixed an issue where an OpenSSL TLS server may crash if sent a - maliciously crafted renegotiation ClientHello message from a client - (CVE-2021-3449) - - Major changes between OpenSSL 1.1.1i and OpenSSL 1.1.1j [16 Feb 2021] - - o Fixed a NULL pointer deref in the X509_issuer_and_serial_hash() - function (CVE-2021-23841) - o Fixed the RSA_padding_check_SSLv23() function and the RSA_SSLV23_PADDING - padding mode to correctly check for rollback attacks - o Fixed an overflow in the EVP_CipherUpdate, EVP_EncryptUpdate and - EVP_DecryptUpdate functions (CVE-2021-23840) - o Fixed SRP_Calc_client_key so that it runs in constant time - - Major changes between OpenSSL 1.1.1h and OpenSSL 1.1.1i [8 Dec 2020] - - o Fixed NULL pointer deref in GENERAL_NAME_cmp (CVE-2020-1971) - - Major changes between OpenSSL 1.1.1g and OpenSSL 1.1.1h [22 Sep 2020] - - o Disallow explicit curve parameters in verifications chains when - X509_V_FLAG_X509_STRICT is used - o Enable 'MinProtocol' and 'MaxProtocol' to configure both TLS and DTLS - contexts - o Oracle Developer Studio will start reporting deprecation warnings - - Major changes between OpenSSL 1.1.1f and OpenSSL 1.1.1g [21 Apr 2020] - - o Fixed segmentation fault in SSL_check_chain() (CVE-2020-1967) - - Major changes between OpenSSL 1.1.1e and OpenSSL 1.1.1f [31 Mar 2020] - - o Revert the unexpected EOF reporting via SSL_ERROR_SSL - - Major changes between OpenSSL 1.1.1d and OpenSSL 1.1.1e [17 Mar 2020] - - o Fixed an overflow bug in the x64_64 Montgomery squaring procedure - used in exponentiation with 512-bit moduli (CVE-2019-1551) - o Properly detect unexpected EOF while reading in libssl and report - it via SSL_ERROR_SSL - - 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 1.1.1a and OpenSSL 1.1.1b [26 Feb 2019] - - o Change the info callback signals for the start and end of a post-handshake - message exchange in TLSv1.3. - o Fix a bug in DTLS over SCTP. This breaks interoperability with older versions - of OpenSSL like OpenSSL 1.1.0 and OpenSSL 1.0.2. - - Major changes between OpenSSL 1.1.1 and OpenSSL 1.1.1a [20 Nov 2018] - - o Timing vulnerability in DSA signature generation (CVE-2018-0734) - o Timing vulnerability in ECDSA signature generation (CVE-2018-0735) - - Major changes between OpenSSL 1.1.0i and OpenSSL 1.1.1 [11 Sep 2018] - - o Support for TLSv1.3 added (see https://wiki.openssl.org/index.php/TLS1.3 - for further important information). The TLSv1.3 implementation includes: - o Fully compliant implementation of RFC8446 (TLSv1.3) on by default - o Early data (0-RTT) - o Post-handshake authentication and key update - o Middlebox Compatibility Mode - o TLSv1.3 PSKs - o Support for all five RFC8446 ciphersuites - o RSA-PSS signature algorithms (backported to TLSv1.2) - o Configurable session ticket support - o Stateless server support - o Rewrite of the packet construction code for "safer" packet handling - o Rewrite of the extension handling code - o Complete rewrite of the OpenSSL random number generator to introduce the - following capabilities - o The default RAND method now utilizes an AES-CTR DRBG according to - NIST standard SP 800-90Ar1. - o Support for multiple DRBG instances with seed chaining. - o There is a public and private DRBG instance. - o The DRBG instances are fork-safe. - o Keep all global DRBG instances on the secure heap if it is enabled. - o The public and private DRBG instance are per thread for lock free - operation - o Support for various new cryptographic algorithms including: - o SHA3 - o SHA512/224 and SHA512/256 - o EdDSA (both Ed25519 and Ed448) including X509 and TLS support - o X448 (adding to the existing X25519 support in 1.1.0) - o Multi-prime RSA - o SM2 - o SM3 - o SM4 - o SipHash - o ARIA (including TLS support) - o Significant Side-Channel attack security improvements - o Add a new ClientHello callback to provide the ability to adjust the SSL - object at an early stage. - o Add 'Maximum Fragment Length' TLS extension negotiation and support - o A new STORE module, which implements a uniform and URI based reader of - stores that can contain keys, certificates, CRLs and numerous other - objects. - o Move the display of configuration data to configdata.pm. - o Allow GNU style "make variables" to be used with Configure. - o Claim the namespaces OSSL and OPENSSL, represented as symbol prefixes - o Rewrite of devcrypto engine - - Major changes between OpenSSL 1.1.0h and OpenSSL 1.1.0i [under development] - - o Client DoS due to large DH parameter (CVE-2018-0732) - o Cache timing vulnerability in RSA Key Generation (CVE-2018-0737) - - Major changes between OpenSSL 1.1.0g and OpenSSL 1.1.0h [under development] - - o Constructed ASN.1 types with a recursive definition could exceed the - stack (CVE-2018-0739) - o Incorrect CRYPTO_memcmp on HP-UX PA-RISC (CVE-2018-0733) - o rsaz_1024_mul_avx2 overflow bug on x86_64 (CVE-2017-3738) - - Major changes between OpenSSL 1.1.0f and OpenSSL 1.1.0g [2 Nov 2017] - - o bn_sqrx8x_internal carry bug on x86_64 (CVE-2017-3736) - o Malformed X.509 IPAddressFamily could cause OOB read (CVE-2017-3735) - - Major changes between OpenSSL 1.1.0e and OpenSSL 1.1.0f [25 May 2017] - - o config now recognises 64-bit mingw and chooses mingw64 instead of mingw - - Major changes between OpenSSL 1.1.0d and OpenSSL 1.1.0e [16 Feb 2017] - - o Encrypt-Then-Mac renegotiation crash (CVE-2017-3733) - - Major changes between OpenSSL 1.1.0c and OpenSSL 1.1.0d [26 Jan 2017] - - o Truncated packet could crash via OOB read (CVE-2017-3731) - o Bad (EC)DHE parameters cause a client crash (CVE-2017-3730) - o BN_mod_exp may produce incorrect results on x86_64 (CVE-2017-3732) - - Major changes between OpenSSL 1.1.0b and OpenSSL 1.1.0c [10 Nov 2016] - - o ChaCha20/Poly1305 heap-buffer-overflow (CVE-2016-7054) - o CMS Null dereference (CVE-2016-7053) - o Montgomery multiplication may produce incorrect results (CVE-2016-7055) - - Major changes between OpenSSL 1.1.0a and OpenSSL 1.1.0b [26 Sep 2016] - - o Fix Use After Free for large message sizes (CVE-2016-6309) - - Major changes between OpenSSL 1.1.0 and OpenSSL 1.1.0a [22 Sep 2016] - - o OCSP Status Request extension unbounded memory growth (CVE-2016-6304) - o SSL_peek() hang on empty record (CVE-2016-6305) - o Excessive allocation of memory in tls_get_message_header() - (CVE-2016-6307) - o Excessive allocation of memory in dtls1_preprocess_fragment() - (CVE-2016-6308) - - Major changes between OpenSSL 1.0.2h and OpenSSL 1.1.0 [25 Aug 2016] - - o Copyright text was shrunk to a boilerplate that points to the license - o "shared" builds are now the default when possible - o Added support for "pipelining" - o Added the AFALG engine - o New threading API implemented - o Support for ChaCha20 and Poly1305 added to libcrypto and libssl - o Support for extended master secret - o CCM ciphersuites - o Reworked test suite, now based on perl, Test::Harness and Test::More - o *Most* libcrypto and libssl public structures were made opaque, - including: - BIGNUM and associated types, EC_KEY and EC_KEY_METHOD, - DH and DH_METHOD, DSA and DSA_METHOD, RSA and RSA_METHOD, - BIO and BIO_METHOD, EVP_MD_CTX, EVP_MD, EVP_CIPHER_CTX, - EVP_CIPHER, EVP_PKEY and associated types, HMAC_CTX, - X509, X509_CRL, X509_OBJECT, X509_STORE_CTX, X509_STORE, - X509_LOOKUP, X509_LOOKUP_METHOD - o libssl internal structures made opaque - o SSLv2 support removed - o Kerberos ciphersuite support removed - o RC4 removed from DEFAULT ciphersuites in libssl - o 40 and 56 bit cipher support removed from libssl - o All public header files moved to include/openssl, no more symlinking - o SSL/TLS state machine, version negotiation and record layer rewritten - o EC revision: now operations use new EC_KEY_METHOD. - o Support for OCB mode added to libcrypto - o Support for asynchronous crypto operations added to libcrypto and libssl - o Deprecated interfaces can now be disabled at build time either - relative to the latest release via the "no-deprecated" Configure - argument, or via the "--api=1.1.0|1.0.0|0.9.8" option. - o Application software can be compiled with -DOPENSSL_API_COMPAT=version - to ensure that features deprecated in that version are not exposed. - o Support for RFC6698/RFC7671 DANE TLSA peer authentication - o Change of Configure to use --prefix as the main installation - directory location rather than --openssldir. The latter becomes - the directory for certs, private key and openssl.cnf exclusively. - o Reworked BIO networking library, with full support for IPv6. - o New "unified" build system - o New security levels - o Support for scrypt algorithm - o Support for X25519 - o Extended SSL_CONF support using configuration files - o KDF algorithm support. Implement TLS PRF as a KDF. - o Support for Certificate Transparency - o HKDF support. - - Major changes between OpenSSL 1.0.2g and OpenSSL 1.0.2h [3 May 2016] - - o Prevent padding oracle in AES-NI CBC MAC check (CVE-2016-2107) - o Fix EVP_EncodeUpdate overflow (CVE-2016-2105) - o Fix EVP_EncryptUpdate overflow (CVE-2016-2106) - o Prevent ASN.1 BIO excessive memory allocation (CVE-2016-2109) - o EBCDIC overread (CVE-2016-2176) - o Modify behavior of ALPN to invoke callback after SNI/servername - callback, such that updates to the SSL_CTX affect ALPN. - o Remove LOW from the DEFAULT cipher list. This removes singles DES from - the default. - o Only remove the SSLv2 methods with the no-ssl2-method option. - - Major changes between OpenSSL 1.0.2f and OpenSSL 1.0.2g [1 Mar 2016] - - o Disable weak ciphers in SSLv3 and up in default builds of OpenSSL. - o Disable SSLv2 default build, default negotiation and weak ciphers - (CVE-2016-0800) - o Fix a double-free in DSA code (CVE-2016-0705) - o Disable SRP fake user seed to address a server memory leak - (CVE-2016-0798) - o Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption - (CVE-2016-0797) - o Fix memory issues in BIO_*printf functions (CVE-2016-0799) - o Fix side channel attack on modular exponentiation (CVE-2016-0702) - - Major changes between OpenSSL 1.0.2e and OpenSSL 1.0.2f [28 Jan 2016] - - o DH small subgroups (CVE-2016-0701) - o SSLv2 doesn't block disabled ciphers (CVE-2015-3197) - - Major changes between OpenSSL 1.0.2d and OpenSSL 1.0.2e [3 Dec 2015] - - o BN_mod_exp may produce incorrect results on x86_64 (CVE-2015-3193) - o Certificate verify crash with missing PSS parameter (CVE-2015-3194) - o X509_ATTRIBUTE memory leak (CVE-2015-3195) - o Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs - o In DSA_generate_parameters_ex, if the provided seed is too short, - return an error - - Major changes between OpenSSL 1.0.2c and OpenSSL 1.0.2d [9 Jul 2015] - - o Alternate chains certificate forgery (CVE-2015-1793) - o Race condition handling PSK identify hint (CVE-2015-3196) - - Major changes between OpenSSL 1.0.2b and OpenSSL 1.0.2c [12 Jun 2015] - - o Fix HMAC ABI incompatibility - - Major changes between OpenSSL 1.0.2a and OpenSSL 1.0.2b [11 Jun 2015] - - o Malformed ECParameters causes infinite loop (CVE-2015-1788) - o Exploitable out-of-bounds read in X509_cmp_time (CVE-2015-1789) - o PKCS7 crash with missing EnvelopedContent (CVE-2015-1790) - o CMS verify infinite loop with unknown hash function (CVE-2015-1792) - o Race condition handling NewSessionTicket (CVE-2015-1791) - - Major changes between OpenSSL 1.0.2 and OpenSSL 1.0.2a [19 Mar 2015] - - o OpenSSL 1.0.2 ClientHello sigalgs DoS fix (CVE-2015-0291) - o Multiblock corrupted pointer fix (CVE-2015-0290) - o Segmentation fault in DTLSv1_listen fix (CVE-2015-0207) - o Segmentation fault in ASN1_TYPE_cmp fix (CVE-2015-0286) - o Segmentation fault for invalid PSS parameters fix (CVE-2015-0208) - o ASN.1 structure reuse memory corruption fix (CVE-2015-0287) - o PKCS7 NULL pointer dereferences fix (CVE-2015-0289) - o DoS via reachable assert in SSLv2 servers fix (CVE-2015-0293) - o Empty CKE with client auth and DHE fix (CVE-2015-1787) - o Handshake with unseeded PRNG fix (CVE-2015-0285) - o Use After Free following d2i_ECPrivatekey error fix (CVE-2015-0209) - o X509_to_X509_REQ NULL pointer deref fix (CVE-2015-0288) - o Removed the export ciphers from the DEFAULT ciphers - - Major changes between OpenSSL 1.0.1l and OpenSSL 1.0.2 [22 Jan 2015]: - - o Suite B support for TLS 1.2 and DTLS 1.2 - o Support for DTLS 1.2 - o TLS automatic EC curve selection. - o API to set TLS supported signature algorithms and curves - o SSL_CONF configuration API. - o TLS Brainpool support. - o ALPN support. - o CMS support for RSA-PSS, RSA-OAEP, ECDH and X9.42 DH. - - Major changes between OpenSSL 1.0.1k and OpenSSL 1.0.1l [15 Jan 2015] - - o Build fixes for the Windows and OpenVMS platforms - - Major changes between OpenSSL 1.0.1j and OpenSSL 1.0.1k [8 Jan 2015] - - o Fix for CVE-2014-3571 - o Fix for CVE-2015-0206 - o Fix for CVE-2014-3569 - o Fix for CVE-2014-3572 - o Fix for CVE-2015-0204 - o Fix for CVE-2015-0205 - o Fix for CVE-2014-8275 - o Fix for CVE-2014-3570 - - Major changes between OpenSSL 1.0.1i and OpenSSL 1.0.1j [15 Oct 2014] - - o Fix for CVE-2014-3513 - o Fix for CVE-2014-3567 - o Mitigation for CVE-2014-3566 (SSL protocol vulnerability) - o Fix for CVE-2014-3568 - - Major changes between OpenSSL 1.0.1h and OpenSSL 1.0.1i [6 Aug 2014] - - o Fix for CVE-2014-3512 - o Fix for CVE-2014-3511 - o Fix for CVE-2014-3510 - o Fix for CVE-2014-3507 - o Fix for CVE-2014-3506 - o Fix for CVE-2014-3505 - o Fix for CVE-2014-3509 - o Fix for CVE-2014-5139 - o Fix for CVE-2014-3508 - - Major changes between OpenSSL 1.0.1g and OpenSSL 1.0.1h [5 Jun 2014] - - o Fix for CVE-2014-0224 - o Fix for CVE-2014-0221 - o Fix for CVE-2014-0198 - o Fix for CVE-2014-0195 - o Fix for CVE-2014-3470 - o Fix for CVE-2010-5298 - - Major changes between OpenSSL 1.0.1f and OpenSSL 1.0.1g [7 Apr 2014] - - o Fix for CVE-2014-0160 - o Add TLS padding extension workaround for broken servers. - o Fix for CVE-2014-0076 - - Major changes between OpenSSL 1.0.1e and OpenSSL 1.0.1f [6 Jan 2014] - - o Don't include gmt_unix_time in TLS server and client random values - o Fix for TLS record tampering bug CVE-2013-4353 - o Fix for TLS version checking bug CVE-2013-6449 - o Fix for DTLS retransmission bug CVE-2013-6450 - - Major changes between OpenSSL 1.0.1d and OpenSSL 1.0.1e [11 Feb 2013]: - - o Corrected fix for CVE-2013-0169 - - Major changes between OpenSSL 1.0.1c and OpenSSL 1.0.1d [4 Feb 2013]: - - o Fix renegotiation in TLS 1.1, 1.2 by using the correct TLS version. - o Include the fips configuration module. - o Fix OCSP bad key DoS attack CVE-2013-0166 - o Fix for SSL/TLS/DTLS CBC plaintext recovery attack CVE-2013-0169 - o Fix for TLS AESNI record handling flaw CVE-2012-2686 - - Major changes between OpenSSL 1.0.1b and OpenSSL 1.0.1c [10 May 2012]: - - o Fix TLS/DTLS record length checking bug CVE-2012-2333 - o Don't attempt to use non-FIPS composite ciphers in FIPS mode. - - Major changes between OpenSSL 1.0.1a and OpenSSL 1.0.1b [26 Apr 2012]: - - o Fix compilation error on non-x86 platforms. - o Make FIPS capable OpenSSL ciphers work in non-FIPS mode. - o Fix SSL_OP_NO_TLSv1_1 clash with SSL_OP_ALL in OpenSSL 1.0.0 - - Major changes between OpenSSL 1.0.1 and OpenSSL 1.0.1a [19 Apr 2012]: - - o Fix for ASN1 overflow bug CVE-2012-2110 - o Workarounds for some servers that hang on long client hellos. - o Fix SEGV in AES code. - - Major changes between OpenSSL 1.0.0h and OpenSSL 1.0.1 [14 Mar 2012]: - - o TLS/DTLS heartbeat support. - o SCTP support. - o RFC 5705 TLS key material exporter. - o RFC 5764 DTLS-SRTP negotiation. - o Next Protocol Negotiation. - o PSS signatures in certificates, requests and CRLs. - o Support for password based recipient info for CMS. - o Support TLS v1.2 and TLS v1.1. - o Preliminary FIPS capability for unvalidated 2.0 FIPS module. - o SRP support. - - Major changes between OpenSSL 1.0.0g and OpenSSL 1.0.0h [12 Mar 2012]: - - o Fix for CMS/PKCS#7 MMA CVE-2012-0884 - o Corrected fix for CVE-2011-4619 - o Various DTLS fixes. - - Major changes between OpenSSL 1.0.0f and OpenSSL 1.0.0g [18 Jan 2012]: - - o Fix for DTLS DoS issue CVE-2012-0050 - - Major changes between OpenSSL 1.0.0e and OpenSSL 1.0.0f [4 Jan 2012]: - - o Fix for DTLS plaintext recovery attack CVE-2011-4108 - o Clear block padding bytes of SSL 3.0 records CVE-2011-4576 - o Only allow one SGC handshake restart for SSL/TLS CVE-2011-4619 - o Check parameters are not NULL in GOST ENGINE CVE-2012-0027 - o Check for malformed RFC3779 data CVE-2011-4577 - - Major changes between OpenSSL 1.0.0d and OpenSSL 1.0.0e [6 Sep 2011]: - - o Fix for CRL vulnerability issue CVE-2011-3207 - o Fix for ECDH crashes CVE-2011-3210 - o Protection against EC timing attacks. - o Support ECDH ciphersuites for certificates using SHA2 algorithms. - o Various DTLS fixes. - - Major changes between OpenSSL 1.0.0c and OpenSSL 1.0.0d [8 Feb 2011]: - - o Fix for security issue CVE-2011-0014 - - Major changes between OpenSSL 1.0.0b and OpenSSL 1.0.0c [2 Dec 2010]: - - o Fix for security issue CVE-2010-4180 - o Fix for CVE-2010-4252 - o Fix mishandling of absent EC point format extension. - o Fix various platform compilation issues. - o Corrected fix for security issue CVE-2010-3864. - - Major changes between OpenSSL 1.0.0a and OpenSSL 1.0.0b [16 Nov 2010]: - - o Fix for security issue CVE-2010-3864. - o Fix for CVE-2010-2939 - o Fix WIN32 build system for GOST ENGINE. - - Major changes between OpenSSL 1.0.0 and OpenSSL 1.0.0a [1 Jun 2010]: - - o Fix for security issue CVE-2010-1633. - o GOST MAC and CFB fixes. - - Major changes between OpenSSL 0.9.8n and OpenSSL 1.0.0 [29 Mar 2010]: - - o RFC3280 path validation: sufficient to process PKITS tests. - o Integrated support for PVK files and keyblobs. - o Change default private key format to PKCS#8. - o CMS support: able to process all examples in RFC4134 - o Streaming ASN1 encode support for PKCS#7 and CMS. - o Multiple signer and signer add support for PKCS#7 and CMS. - o ASN1 printing support. - o Whirlpool hash algorithm added. - o RFC3161 time stamp support. - o New generalised public key API supporting ENGINE based algorithms. - o New generalised public key API utilities. - o New ENGINE supporting GOST algorithms. - o SSL/TLS GOST ciphersuite support. - o PKCS#7 and CMS GOST support. - o RFC4279 PSK ciphersuite support. - o Supported points format extension for ECC ciphersuites. - o ecdsa-with-SHA224/256/384/512 signature types. - o dsa-with-SHA224 and dsa-with-SHA256 signature types. - o Opaque PRF Input TLS extension support. - o Updated time routines to avoid OS limitations. - - Major changes between OpenSSL 0.9.8m and OpenSSL 0.9.8n [24 Mar 2010]: - - o CFB cipher definition fixes. - o Fix security issues CVE-2010-0740 and CVE-2010-0433. - - Major changes between OpenSSL 0.9.8l and OpenSSL 0.9.8m [25 Feb 2010]: - - o Cipher definition fixes. - o Workaround for slow RAND_poll() on some WIN32 versions. - o Remove MD2 from algorithm tables. - o SPKAC handling fixes. - o Support for RFC5746 TLS renegotiation extension. - o Compression memory leak fixed. - o Compression session resumption fixed. - o Ticket and SNI coexistence fixes. - o Many fixes to DTLS handling. - - Major changes between OpenSSL 0.9.8k and OpenSSL 0.9.8l [5 Nov 2009]: - - o Temporary work around for CVE-2009-3555: disable renegotiation. - - Major changes between OpenSSL 0.9.8j and OpenSSL 0.9.8k [25 Mar 2009]: - - o Fix various build issues. - o Fix security issues (CVE-2009-0590, CVE-2009-0591, CVE-2009-0789) - - Major changes between OpenSSL 0.9.8i and OpenSSL 0.9.8j [7 Jan 2009]: - - o Fix security issue (CVE-2008-5077) - o Merge FIPS 140-2 branch code. - - Major changes between OpenSSL 0.9.8g and OpenSSL 0.9.8h [28 May 2008]: - - o CryptoAPI ENGINE support. - o Various precautionary measures. - o Fix for bugs affecting certificate request creation. - o Support for local machine keyset attribute in PKCS#12 files. - - Major changes between OpenSSL 0.9.8f and OpenSSL 0.9.8g [19 Oct 2007]: - - o Backport of CMS functionality to 0.9.8. - o Fixes for bugs introduced with 0.9.8f. - - Major changes between OpenSSL 0.9.8e and OpenSSL 0.9.8f [11 Oct 2007]: - - o Add gcc 4.2 support. - o Add support for AES and SSE2 assembly language optimization - for VC++ build. - o Support for RFC4507bis and server name extensions if explicitly - selected at compile time. - o DTLS improvements. - o RFC4507bis support. - o TLS Extensions support. - - Major changes between OpenSSL 0.9.8d and OpenSSL 0.9.8e [23 Feb 2007]: - - o Various ciphersuite selection fixes. - o RFC3779 support. - - Major changes between OpenSSL 0.9.8c and OpenSSL 0.9.8d [28 Sep 2006]: - - o Introduce limits to prevent malicious key DoS (CVE-2006-2940) - o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343) - o Changes to ciphersuite selection algorithm - - Major changes between OpenSSL 0.9.8b and OpenSSL 0.9.8c [5 Sep 2006]: - - o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339 - o New cipher Camellia - - Major changes between OpenSSL 0.9.8a and OpenSSL 0.9.8b [4 May 2006]: - - o Cipher string fixes. - o Fixes for VC++ 2005. - o Updated ECC cipher suite support. - o New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free(). - o Zlib compression usage fixes. - o Built in dynamic engine compilation support on Win32. - o Fixes auto dynamic engine loading in Win32. - - Major changes between OpenSSL 0.9.8 and OpenSSL 0.9.8a [11 Oct 2005]: - - o Fix potential SSL 2.0 rollback, CVE-2005-2969 - o Extended Windows CE support - - Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.8 [5 Jul 2005]: - - o Major work on the BIGNUM library for higher efficiency and to - make operations more streamlined and less contradictory. This - is the result of a major audit of the BIGNUM library. - o Addition of BIGNUM functions for fields GF(2^m) and NIST - curves, to support the Elliptic Crypto functions. - o Major work on Elliptic Crypto; ECDH and ECDSA added, including - the use through EVP, X509 and ENGINE. - o New ASN.1 mini-compiler that's usable through the OpenSSL - configuration file. - o Added support for ASN.1 indefinite length constructed encoding. - o New PKCS#12 'medium level' API to manipulate PKCS#12 files. - o Complete rework of shared library construction and linking - programs with shared or static libraries, through a separate - Makefile.shared. - o Rework of the passing of parameters from one Makefile to another. - o Changed ENGINE framework to load dynamic engine modules - automatically from specifically given directories. - o New structure and ASN.1 functions for CertificatePair. - o Changed the ZLIB compression method to be stateful. - o Changed the key-generation and primality testing "progress" - mechanism to take a structure that contains the ticker - function and an argument. - o New engine module: GMP (performs private key exponentiation). - o New engine module: VIA PadLOck ACE extension in VIA C3 - Nehemiah processors. - o Added support for IPv6 addresses in certificate extensions. - See RFC 1884, section 2.2. - o Added support for certificate policy mappings, policy - constraints and name constraints. - o Added support for multi-valued AVAs in the OpenSSL - configuration file. - o Added support for multiple certificates with the same subject - in the 'openssl ca' index file. - o Make it possible to create self-signed certificates using - 'openssl ca -selfsign'. - o Make it possible to generate a serial number file with - 'openssl ca -create_serial'. - o New binary search functions with extended functionality. - o New BUF functions. - o New STORE structure and library to provide an interface to all - sorts of data repositories. Supports storage of public and - private keys, certificates, CRLs, numbers and arbitrary blobs. - This library is unfortunately unfinished and unused within - OpenSSL. - o New control functions for the error stack. - o Changed the PKCS#7 library to support one-pass S/MIME - processing. - o Added the possibility to compile without old deprecated - functionality with the OPENSSL_NO_DEPRECATED macro or the - 'no-deprecated' argument to the config and Configure scripts. - o Constification of all ASN.1 conversion functions, and other - affected functions. - o Improved platform support for PowerPC. - o New FIPS 180-2 algorithms (SHA-224, -256, -384 and -512). - o New X509_VERIFY_PARAM structure to support parameterisation - of X.509 path validation. - o Major overhaul of RC4 performance on Intel P4, IA-64 and - AMD64. - o Changed the Configure script to have some algorithms disabled - by default. Those can be explicitly enabled with the new - argument form 'enable-xxx'. - o Change the default digest in 'openssl' commands from MD5 to - SHA-1. - o Added support for DTLS. - o New BIGNUM blinding. - o Added support for the RSA-PSS encryption scheme - o Added support for the RSA X.931 padding. - o Added support for BSD sockets on NetWare. - o Added support for files larger than 2GB. - o Added initial support for Win64. - o Added alternate pkg-config files. - - Major changes between OpenSSL 0.9.7l and OpenSSL 0.9.7m [23 Feb 2007]: - - o FIPS 1.1.1 module linking. - o Various ciphersuite selection fixes. - - Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l [28 Sep 2006]: - - o Introduce limits to prevent malicious key DoS (CVE-2006-2940) - o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343) - - Major changes between OpenSSL 0.9.7j and OpenSSL 0.9.7k [5 Sep 2006]: - - o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339 - - Major changes between OpenSSL 0.9.7i and OpenSSL 0.9.7j [4 May 2006]: - - o Visual C++ 2005 fixes. - o Update Windows build system for FIPS. - - Major changes between OpenSSL 0.9.7h and OpenSSL 0.9.7i [14 Oct 2005]: - - 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]: - - o Fix SSL 2.0 Rollback, CVE-2005-2969 - o Allow use of fixed-length exponent on DSA signing - o Default fixed-window RSA, DSA, DH private-key operations - - Major changes between OpenSSL 0.9.7f and OpenSSL 0.9.7g [11 Apr 2005]: - - o More compilation issues fixed. - o Adaptation to more modern Kerberos API. - o Enhanced or corrected configuration for Solaris64, Mingw and Cygwin. - o Enhanced x86_64 assembler BIGNUM module. - o More constification. - o Added processing of proxy certificates (RFC 3820). - - Major changes between OpenSSL 0.9.7e and OpenSSL 0.9.7f [22 Mar 2005]: - - o Several compilation issues fixed. - o Many memory allocation failure checks added. - o Improved comparison of X509 Name type. - o Mandatory basic checks on certificates. - o Performance improvements. - - Major changes between OpenSSL 0.9.7d and OpenSSL 0.9.7e [25 Oct 2004]: - - o Fix race condition in CRL checking code. - o Fixes to PKCS#7 (S/MIME) code. - - Major changes between OpenSSL 0.9.7c and OpenSSL 0.9.7d [17 Mar 2004]: - - o Security: Fix Kerberos ciphersuite SSL/TLS handshaking bug - o Security: Fix null-pointer assignment in do_change_cipher_spec() - o Allow multiple active certificates with same subject in CA index - o Multiple X509 verification fixes - o Speed up HMAC and other operations - - Major changes between OpenSSL 0.9.7b and OpenSSL 0.9.7c [30 Sep 2003]: - - o Security: fix various ASN1 parsing bugs. - o New -ignore_err option to OCSP utility. - o Various interop and bug fixes in S/MIME code. - o SSL/TLS protocol fix for unrequested client certificates. - - Major changes between OpenSSL 0.9.7a and OpenSSL 0.9.7b [10 Apr 2003]: - - o Security: counter the Klima-Pokorny-Rosa extension of - Bleichbacher's attack - o Security: make RSA blinding default. - o Configuration: Irix fixes, AIX fixes, better mingw support. - o Support for new platforms: linux-ia64-ecc. - o Build: shared library support fixes. - o ASN.1: treat domainComponent correctly. - o Documentation: fixes and additions. - - Major changes between OpenSSL 0.9.7 and OpenSSL 0.9.7a [19 Feb 2003]: - - o Security: Important security related bugfixes. - o Enhanced compatibility with MIT Kerberos. - o Can be built without the ENGINE framework. - o IA32 assembler enhancements. - o Support for new platforms: FreeBSD/IA64 and FreeBSD/Sparc64. - o Configuration: the no-err option now works properly. - o SSL/TLS: now handles manual certificate chain building. - o SSL/TLS: certain session ID malfunctions corrected. - - Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.7 [30 Dec 2002]: - - o New library section OCSP. - o Complete rewrite of ASN1 code. - o CRL checking in verify code and openssl utility. - o Extension copying in 'ca' utility. - o Flexible display options in 'ca' utility. - o Provisional support for international characters with UTF8. - o Support for external crypto devices ('engine') is no longer - a separate distribution. - o New elliptic curve library section. - o New AES (Rijndael) library section. - o Support for new platforms: Windows CE, Tandem OSS, A/UX, AIX 64-bit, - Linux x86_64, Linux 64-bit on Sparc v9 - o Extended support for some platforms: VxWorks - o Enhanced support for shared libraries. - o Now only builds PIC code when shared library support is requested. - o Support for pkg-config. - o Lots of new manuals. - o Makes symbolic links to or copies of manuals to cover all described - functions. - o Change DES API to clean up the namespace (some applications link also - against libdes providing similar functions having the same name). - Provide macros for backward compatibility (will be removed in the - future). - o Unify handling of cryptographic algorithms (software and engine) - to be available via EVP routines for asymmetric and symmetric ciphers. - o NCONF: new configuration handling routines. - o Change API to use more 'const' modifiers to improve error checking - and help optimizers. - o Finally remove references to RSAref. - o Reworked parts of the BIGNUM code. - o Support for new engines: Broadcom ubsec, Accelerated Encryption - Processing, IBM 4758. - o A few new engines added in the demos area. - o Extended and corrected OID (object identifier) table. - o PRNG: query at more locations for a random device, automatic query for - EGD style random sources at several locations. - o SSL/TLS: allow optional cipher choice according to server's preference. - o SSL/TLS: allow server to explicitly set new session ids. - o SSL/TLS: support Kerberos cipher suites (RFC2712). - Only supports MIT Kerberos for now. - o SSL/TLS: allow more precise control of renegotiations and sessions. - o SSL/TLS: add callback to retrieve SSL/TLS messages. - o SSL/TLS: support AES cipher suites (RFC3268). - - Major changes between OpenSSL 0.9.6j and OpenSSL 0.9.6k [30 Sep 2003]: - - o Security: fix various ASN1 parsing bugs. - o SSL/TLS protocol fix for unrequested client certificates. - - Major changes between OpenSSL 0.9.6i and OpenSSL 0.9.6j [10 Apr 2003]: - - o Security: counter the Klima-Pokorny-Rosa extension of - Bleichbacher's attack - o Security: make RSA blinding default. - o Build: shared library support fixes. - - Major changes between OpenSSL 0.9.6h and OpenSSL 0.9.6i [19 Feb 2003]: - - o Important security related bugfixes. - - Major changes between OpenSSL 0.9.6g and OpenSSL 0.9.6h [5 Dec 2002]: - - o New configuration targets for Tandem OSS and A/UX. - o New OIDs for Microsoft attributes. - o Better handling of SSL session caching. - o Better comparison of distinguished names. - o Better handling of shared libraries in a mixed GNU/non-GNU environment. - o Support assembler code with Borland C. - o Fixes for length problems. - o Fixes for uninitialised variables. - o Fixes for memory leaks, some unusual crashes and some race conditions. - o Fixes for smaller building problems. - o Updates of manuals, FAQ and other instructive documents. - - Major changes between OpenSSL 0.9.6f and OpenSSL 0.9.6g [9 Aug 2002]: - - o Important building fixes on Unix. - - Major changes between OpenSSL 0.9.6e and OpenSSL 0.9.6f [8 Aug 2002]: - - o Various important bugfixes. - - Major changes between OpenSSL 0.9.6d and OpenSSL 0.9.6e [30 Jul 2002]: - - o Important security related bugfixes. - o Various SSL/TLS library bugfixes. - - Major changes between OpenSSL 0.9.6c and OpenSSL 0.9.6d [9 May 2002]: - - o Various SSL/TLS library bugfixes. - o Fix DH parameter generation for 'non-standard' generators. - - Major changes between OpenSSL 0.9.6b and OpenSSL 0.9.6c [21 Dec 2001]: - - o Various SSL/TLS library bugfixes. - o BIGNUM library fixes. - o RSA OAEP and random number generation fixes. - o Object identifiers corrected and added. - o Add assembler BN routines for IA64. - o Add support for OS/390 Unix, UnixWare with gcc, OpenUNIX 8, - MIPS Linux; shared library support for Irix, HP-UX. - o Add crypto accelerator support for AEP, Baltimore SureWare, - Broadcom and Cryptographic Appliance's keyserver - [in 0.9.6c-engine release]. - - Major changes between OpenSSL 0.9.6a and OpenSSL 0.9.6b [9 Jul 2001]: - - o Security fix: PRNG improvements. - o Security fix: RSA OAEP check. - o Security fix: Reinsert and fix countermeasure to Bleichbacher's - attack. - o MIPS bug fix in BIGNUM. - o Bug fix in "openssl enc". - o Bug fix in X.509 printing routine. - o Bug fix in DSA verification routine and DSA S/MIME verification. - o Bug fix to make PRNG thread-safe. - o Bug fix in RAND_file_name(). - o Bug fix in compatibility mode trust settings. - o Bug fix in blowfish EVP. - o Increase default size for BIO buffering filter. - o Compatibility fixes in some scripts. - - Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.6a [5 Apr 2001]: - - o Security fix: change behavior of OpenSSL to avoid using - environment variables when running as root. - o Security fix: check the result of RSA-CRT to reduce the - possibility of deducing the private key from an incorrectly - calculated signature. - o Security fix: prevent Bleichenbacher's DSA attack. - o Security fix: Zero the premaster secret after deriving the - master secret in DH ciphersuites. - o Reimplement SSL_peek(), which had various problems. - o Compatibility fix: the function des_encrypt() renamed to - des_encrypt1() to avoid clashes with some Unixen libc. - o Bug fixes for Win32, HP/UX and Irix. - o Bug fixes in BIGNUM, SSL, PKCS#7, PKCS#12, X.509, CONF and - memory checking routines. - o Bug fixes for RSA operations in threaded environments. - o Bug fixes in misc. openssl applications. - o Remove a few potential memory leaks. - o Add tighter checks of BIGNUM routines. - o Shared library support has been reworked for generality. - o More documentation. - o New function BN_rand_range(). - o Add "-rand" option to openssl s_client and s_server. - - Major changes between OpenSSL 0.9.5a and OpenSSL 0.9.6 [10 Oct 2000]: - - o Some documentation for BIO and SSL libraries. - o Enhanced chain verification using key identifiers. - o New sign and verify options to 'dgst' application. - o Support for DER and PEM encoded messages in 'smime' application. - o New 'rsautl' application, low level RSA utility. - o MD4 now included. - o Bugfix for SSL rollback padding check. - o Support for external crypto devices [1]. - o Enhanced EVP interface. - - [1] The support for external crypto devices is currently a separate - distribution. See the file README.ENGINE. - - Major changes between OpenSSL 0.9.5 and OpenSSL 0.9.5a [1 Apr 2000]: - - o Bug fixes for Win32, SuSE Linux, NeXTSTEP and FreeBSD 2.2.8 - o Shared library support for HPUX and Solaris-gcc - o Support of Linux/IA64 - o Assembler support for Mingw32 - o New 'rand' application - o New way to check for existence of algorithms from scripts - - Major changes between OpenSSL 0.9.4 and OpenSSL 0.9.5 [25 May 2000]: - - o S/MIME support in new 'smime' command - o Documentation for the OpenSSL command line application - o Automation of 'req' application - o Fixes to make s_client, s_server work under Windows - o Support for multiple fieldnames in SPKACs - o New SPKAC command line utility and associated library functions - o Options to allow passwords to be obtained from various sources - o New public key PEM format and options to handle it - o Many other fixes and enhancements to command line utilities - o Usable certificate chain verification - o Certificate purpose checking - o Certificate trust settings - o Support of authority information access extension - o Extensions in certificate requests - o Simplified X509 name and attribute routines - o Initial (incomplete) support for international character sets - o New DH_METHOD, DSA_METHOD and enhanced RSA_METHOD - o Read only memory BIOs and simplified creation function - o TLS/SSL protocol bugfixes: Accept TLS 'client hello' in SSL 3.0 - record; allow fragmentation and interleaving of handshake and other - data - o TLS/SSL code now "tolerates" MS SGC - o Work around for Netscape client certificate hang bug - o RSA_NULL option that removes RSA patent code but keeps other - RSA functionality - o Memory leak detection now allows applications to add extra information - via a per-thread stack - o PRNG robustness improved - o EGD support - o BIGNUM library bug fixes - o Faster DSA parameter generation - o Enhanced support for Alpha Linux - o Experimental MacOS support - - Major changes between OpenSSL 0.9.3 and OpenSSL 0.9.4 [9 Aug 1999]: - - o Transparent support for PKCS#8 format private keys: these are used - by several software packages and are more secure than the standard - form - o PKCS#5 v2.0 implementation - o Password callbacks have a new void * argument for application data - o Avoid various memory leaks - o New pipe-like BIO that allows using the SSL library when actual I/O - must be handled by the application (BIO pair) - - Major changes between OpenSSL 0.9.2b and OpenSSL 0.9.3 [24 May 1999]: - o Lots of enhancements and cleanups to the Configuration mechanism - o RSA OEAP related fixes - o Added `openssl ca -revoke' option for revoking a certificate - o Source cleanups: const correctness, type-safe stacks and ASN.1 SETs - o Source tree cleanups: removed lots of obsolete files - o Thawte SXNet, certificate policies and CRL distribution points - extension support - o Preliminary (experimental) S/MIME support - o Support for ASN.1 UTF8String and VisibleString - o Full integration of PKCS#12 code - o Sparc assembler bignum implementation, optimized hash functions - o Option to disable selected ciphers - - Major changes between OpenSSL 0.9.1c and OpenSSL 0.9.2b [22 Mar 1999]: - o Fixed a security hole related to session resumption - o Fixed RSA encryption routines for the p < q case - o "ALL" in cipher lists now means "everything except NULL ciphers" - o Support for Triple-DES CBCM cipher - o Support of Optimal Asymmetric Encryption Padding (OAEP) for RSA - o First support for new TLSv1 ciphers - o Added a few new BIOs (syslog BIO, reliable BIO) - o Extended support for DSA certificate/keys. - o Extended support for Certificate Signing Requests (CSR) - o Initial support for X.509v3 extensions - o Extended support for compression inside the SSL record layer - o Overhauled Win32 builds - o Cleanups and fixes to the Big Number (BN) library - o Support for ASN.1 GeneralizedTime - o Splitted ASN.1 SETs from SEQUENCEs - o ASN1 and PEM support for Netscape Certificate Sequences - o Overhauled Perl interface - o Lots of source tree cleanups. - o Lots of memory leak fixes. - o Lots of bug fixes. - - Major changes between SSLeay 0.9.0b and OpenSSL 0.9.1c [23 Dec 1998]: - o Integration of the popular NO_RSA/NO_DSA patches - o Initial support for compression inside the SSL record layer - o Added BIO proxy and filtering functionality - o Extended Big Number (BN) library - o Added RIPE MD160 message digest - o Added support for RC2/64bit cipher - o Extended ASN.1 parser routines - o Adjustments of the source tree for CVS - o Support for various new platforms diff --git a/crypto/openssl/NEWS.md b/crypto/openssl/NEWS.md new file mode 100644 index 000000000000..36dbfa72f6d5 --- /dev/null +++ b/crypto/openssl/NEWS.md @@ -0,0 +1,1586 @@ +NEWS +==== + +This file gives a brief overview of the major changes between each OpenSSL +release. For more details please read the CHANGES file. + +OpenSSL Releases +---------------- + + - [OpenSSL 3.0](#openssl-30) + - [OpenSSL 1.1.1](#openssl-111) + - [OpenSSL 1.1.0](#openssl-110) + - [OpenSSL 1.0.2](#openssl-102) + - [OpenSSL 1.0.1](#openssl-101) + - [OpenSSL 1.0.0](#openssl-100) + - [OpenSSL 0.9.x](#openssl-09x) + +OpenSSL 3.0 +----------- + +### Major changes between OpenSSL 3.0.7 and OpenSSL 3.0.8 [7 Feb 2023] + + * Fixed NULL dereference during PKCS7 data verification ([CVE-2023-0401]) + * Fixed X.400 address type confusion in X.509 GeneralName ([CVE-2023-0286]) + * Fixed NULL dereference validating DSA public key ([CVE-2023-0217]) + * Fixed Invalid pointer dereference in d2i_PKCS7 functions ([CVE-2023-0216]) + * Fixed Use-after-free following BIO_new_NDEF ([CVE-2023-0215]) + * Fixed Double free after calling PEM_read_bio_ex ([CVE-2022-4450]) + * Fixed Timing Oracle in RSA Decryption ([CVE-2022-4304]) + * Fixed X.509 Name Constraints Read Buffer Overflow ([CVE-2022-4203]) + * Fixed X.509 Policy Constraints Double Locking ([CVE-2022-3996]) + +### Major changes between OpenSSL 3.0.6 and OpenSSL 3.0.7 [1 Nov 2022] + + * Added RIPEMD160 to the default provider. + * Fixed regressions introduced in 3.0.6 version. + * Fixed two buffer overflows in punycode decoding functions. + ([CVE-2022-3786]) and ([CVE-2022-3602]) + +### Major changes between OpenSSL 3.0.5 and OpenSSL 3.0.6 [11 Oct 2022] + + * Fix for custom ciphers to prevent accidental use of NULL encryption + ([CVE-2022-3358]) + +### Major changes between OpenSSL 3.0.4 and OpenSSL 3.0.5 [5 Jul 2022] + + * Fixed heap memory corruption with RSA private key operation + ([CVE-2022-2274]) + * Fixed AES OCB failure to encrypt some bytes on 32-bit x86 platforms + ([CVE-2022-2097]) + +### Major changes between OpenSSL 3.0.3 and OpenSSL 3.0.4 [21 Jun 2022] + + * Fixed additional bugs in the c_rehash script which was not properly + sanitising shell metacharacters to prevent command injection + ([CVE-2022-2068]) + +### Major changes between OpenSSL 3.0.2 and OpenSSL 3.0.3 [3 May 2022] + + * Fixed a bug in the c_rehash script which was not properly sanitising shell + metacharacters to prevent command injection ([CVE-2022-1292]) + * Fixed a bug in the function `OCSP_basic_verify` that verifies the signer + certificate on an OCSP response ([CVE-2022-1343]) + * Fixed a bug where the RC4-MD5 ciphersuite incorrectly used the + AAD data as the MAC key ([CVE-2022-1434]) + * Fix a bug in the OPENSSL_LH_flush() function that breaks reuse of the memory + occuppied by the removed hash table entries ([CVE-2022-1473]) + +### Major changes between OpenSSL 3.0.1 and OpenSSL 3.0.2 [15 Mar 2022] + + * Fixed a bug in the BN_mod_sqrt() function that can cause it to loop forever + for non-prime moduli ([CVE-2022-0778]) + +### Major changes between OpenSSL 3.0.0 and OpenSSL 3.0.1 [14 Dec 2021] + + * Fixed invalid handling of X509_verify_cert() internal errors in libssl + ([CVE-2021-4044]) + * Allow fetching an operation from the provider that owns an unexportable key + as a fallback if that is still allowed by the property query. + +### Major changes between OpenSSL 1.1.1 and OpenSSL 3.0.0 [7 sep 2021] + + * Enhanced 'openssl list' with many new options. + * Added migration guide to man7. + * Implemented support for fully "pluggable" TLSv1.3 groups. + * Added suport for Kernel TLS (KTLS). + * Changed the license to the Apache License v2.0. + * Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, + RC4, RC5, and DES to the legacy provider. + * Moved the EVP digests MD2, MD4, MDC2, WHIRLPOOL and RIPEMD-160 to the legacy + provider. + * Added convenience functions for generating asymmetric key pairs. + * Deprecated the `OCSP_REQ_CTX` type and functions. + * Deprecated the `EC_KEY` and `EC_KEY_METHOD` types and functions. + * Deprecated the `RSA` and `RSA_METHOD` types and functions. + * Deprecated the `DSA` and `DSA_METHOD` types and functions. + * Deprecated the `DH` and `DH_METHOD` types and functions. + * Deprecated the `ERR_load_` functions. + * Remove the `RAND_DRBG` API. + * Deprecated the `ENGINE` API. + * Added `OSSL_LIB_CTX`, a libcrypto library context. + * Added various `_ex` functions to the OpenSSL API that support using + a non-default `OSSL_LIB_CTX`. + * Interactive mode is removed from the 'openssl' program. + * The X25519, X448, Ed25519, Ed448, SHAKE128 and SHAKE256 algorithms are + included in the FIPS provider. + * X509 certificates signed using SHA1 are no longer allowed at security + level 1 or higher. The default security level for TLS is 1, so + certificates signed using SHA1 are by default no longer trusted to + authenticate servers or clients. + * enable-crypto-mdebug and enable-crypto-mdebug-backtrace were mostly + disabled; the project uses address sanitize/leak-detect instead. + * Added a Certificate Management Protocol (CMP, RFC 4210) implementation + also covering CRMF (RFC 4211) and HTTP transfer (RFC 6712). + It is part of the crypto lib and adds a 'cmp' app with a demo configuration. + All widely used CMP features are supported for both clients and servers. + * Added a proper HTTP client supporting GET with optional redirection, POST, + arbitrary request and response content types, TLS, persistent connections, + connections via HTTP(s) proxies, connections and exchange via user-defined + BIOs (allowing implicit connections), and timeout checks. + * Added util/check-format.pl for checking adherence to the coding guidelines. + * Added OSSL_ENCODER, a generic encoder API. + * Added OSSL_DECODER, a generic decoder API. + * Added OSSL_PARAM_BLD, an easier to use API to OSSL_PARAM. + * Added error raising macros, ERR_raise() and ERR_raise_data(). + * Deprecated ERR_put_error(), ERR_get_error_line(), ERR_get_error_line_data(), + ERR_peek_error_line_data(), ERR_peek_last_error_line_data() and + ERR_func_error_string(). + * Added OSSL_PROVIDER_available(), to check provider availibility. + * Added 'openssl mac' that uses the EVP_MAC API. + * Added 'openssl kdf' that uses the EVP_KDF API. + * Add OPENSSL_info() and 'openssl info' to get built-in data. + * Add support for enabling instrumentation through trace and debug + output. + * Changed our version number scheme and set the next major release to + 3.0.0 + * Added EVP_MAC, an EVP layer MAC API, and a generic EVP_PKEY to EVP_MAC + bridge. Supported MACs are: BLAKE2, CMAC, GMAC, HMAC, KMAC, POLY1305 + and SIPHASH. + * Removed the heartbeat message in DTLS feature. + * Added EVP_KDF, an EVP layer KDF and PRF API, and a generic EVP_PKEY to + EVP_KDF bridge. Supported KDFs are: HKDF, KBKDF, KRB5 KDF, PBKDF2, + PKCS12 KDF, SCRYPT, SSH KDF, SSKDF, TLS1 PRF, X9.42 KDF and X9.63 KDF. + * All of the low-level MD2, MD4, MD5, MDC2, RIPEMD160, SHA1, SHA224, + SHA256, SHA384, SHA512 and Whirlpool digest functions have been + deprecated. + * All of the low-level AES, Blowfish, Camellia, CAST, DES, IDEA, RC2, + RC4, RC5 and SEED cipher functions have been deprecated. + * All of the low-level DH, DSA, ECDH, ECDSA and RSA public key functions + have been deprecated. + * SSL 3, TLS 1.0, TLS 1.1, and DTLS 1.0 only work at security level 0, + except when RSA key exchange without SHA1 is used. + * Added providers, a new pluggability concept that will replace the + ENGINE API and ENGINE implementations. + +OpenSSL 1.1.1 +------------- + +### Major changes between OpenSSL 1.1.1k and OpenSSL 1.1.1l [24 Aug 2021] + + * Fixed an SM2 Decryption Buffer Overflow ([CVE-2021-3711]) + * Fixed various read buffer overruns processing ASN.1 strings ([CVE-2021-3712]) + +### Major changes between OpenSSL 1.1.1j and OpenSSL 1.1.1k [25 Mar 2021] + + * Fixed a problem with verifying a certificate chain when using the + X509_V_FLAG_X509_STRICT flag ([CVE-2021-3450]) + * Fixed an issue where an OpenSSL TLS server may crash if sent a maliciously + crafted renegotiation ClientHello message from a client ([CVE-2021-3449]) + +### Major changes between OpenSSL 1.1.1i and OpenSSL 1.1.1j [16 Feb 2021] + + * Fixed a NULL pointer deref in the X509_issuer_and_serial_hash() + function ([CVE-2021-23841]) + * Fixed the RSA_padding_check_SSLv23() function and the RSA_SSLV23_PADDING + padding mode to correctly check for rollback attacks + * Fixed an overflow in the EVP_CipherUpdate, EVP_EncryptUpdate and + EVP_DecryptUpdate functions ([CVE-2021-23840]) + * Fixed SRP_Calc_client_key so that it runs in constant time + +### Major changes between OpenSSL 1.1.1h and OpenSSL 1.1.1i [8 Dec 2020] + + * Fixed NULL pointer deref in GENERAL_NAME_cmp ([CVE-2020-1971]) + +### Major changes between OpenSSL 1.1.1g and OpenSSL 1.1.1h [22 Sep 2020] + + * Disallow explicit curve parameters in verifications chains when + X509_V_FLAG_X509_STRICT is used + * Enable 'MinProtocol' and 'MaxProtocol' to configure both TLS and DTLS + contexts + * Oracle Developer Studio will start reporting deprecation warnings + +### Major changes between OpenSSL 1.1.1f and OpenSSL 1.1.1g [21 Apr 2020] + + * Fixed segmentation fault in SSL_check_chain() ([CVE-2020-1967]) + +### Major changes between OpenSSL 1.1.1e and OpenSSL 1.1.1f [31 Mar 2020] + + * Revert the unexpected EOF reporting via SSL_ERROR_SSL + +### Major changes between OpenSSL 1.1.1d and OpenSSL 1.1.1e [17 Mar 2020] + + * Fixed an overflow bug in the x64_64 Montgomery squaring procedure + used in exponentiation with 512-bit moduli ([CVE-2019-1551]) + +### Major changes between OpenSSL 1.1.1c and OpenSSL 1.1.1d [10 Sep 2019] + + * Fixed a fork protection issue ([CVE-2019-1549]) + * Fixed a padding oracle in PKCS7_dataDecode and CMS_decrypt_set1_pkey + ([CVE-2019-1563]) + * For built-in EC curves, ensure an EC_GROUP built from the curve name is + used even when parsing explicit parameters + * Compute ECC cofactors if not provided during EC_GROUP construction + ([CVE-2019-1547]) + * Early start up entropy quality from the DEVRANDOM seed source has been + improved for older Linux systems + * Correct the extended master secret constant on EBCDIC systems + * Use Windows installation paths in the mingw builds ([CVE-2019-1552]) + * Changed DH_check to accept parameters with order q and 2q subgroups + * Significantly reduce secure memory usage by the randomness pools + * Revert the DEVRANDOM_WAIT feature for Linux systems + +### Major changes between OpenSSL 1.1.1b and OpenSSL 1.1.1c [28 May 2019] + + * Prevent over long nonces in ChaCha20-Poly1305 ([CVE-2019-1543]) + +### Major changes between OpenSSL 1.1.1a and OpenSSL 1.1.1b [26 Feb 2019] + + * Change the info callback signals for the start and end of a post-handshake + message exchange in TLSv1.3. + * Fix a bug in DTLS over SCTP. This breaks interoperability with older + versions of OpenSSL like OpenSSL 1.1.0 and OpenSSL 1.0.2. + +### Major changes between OpenSSL 1.1.1 and OpenSSL 1.1.1a [20 Nov 2018] + + * Timing vulnerability in DSA signature generation ([CVE-2018-0734]) + * Timing vulnerability in ECDSA signature generation ([CVE-2018-0735]) + +### Major changes between OpenSSL 1.1.0i and OpenSSL 1.1.1 [11 Sep 2018] + + * Support for TLSv1.3 added. The TLSv1.3 implementation includes: + * Fully compliant implementation of RFC8446 (TLSv1.3) on by default + * Early data (0-RTT) + * Post-handshake authentication and key update + * Middlebox Compatibility Mode + * TLSv1.3 PSKs + * Support for all five RFC8446 ciphersuites + * RSA-PSS signature algorithms (backported to TLSv1.2) + * Configurable session ticket support + * Stateless server support + * Rewrite of the packet construction code for "safer" packet handling + * Rewrite of the extension handling code + For further important information, see the [TLS1.3 page]( + https://wiki.openssl.org/index.php/TLS1.3) in the OpenSSL Wiki. + + * Complete rewrite of the OpenSSL random number generator to introduce the + following capabilities + * The default RAND method now utilizes an AES-CTR DRBG according to + NIST standard SP 800-90Ar1. + * Support for multiple DRBG instances with seed chaining. + * There is a public and private DRBG instance. + * The DRBG instances are fork-safe. + * Keep all global DRBG instances on the secure heap if it is enabled. + * The public and private DRBG instance are per thread for lock free + operation + * Support for various new cryptographic algorithms including: + * SHA3 + * SHA512/224 and SHA512/256 + * EdDSA (both Ed25519 and Ed448) including X509 and TLS support + * X448 (adding to the existing X25519 support in 1.1.0) + * Multi-prime RSA + * SM2 + * SM3 + * SM4 + * SipHash + * ARIA (including TLS support) + * Significant Side-Channel attack security improvements + * Add a new ClientHello callback to provide the ability to adjust the SSL + object at an early stage. + * Add 'Maximum Fragment Length' TLS extension negotiation and support + * A new STORE module, which implements a uniform and URI based reader of + stores that can contain keys, certificates, CRLs and numerous other + objects. + * Move the display of configuration data to configdata.pm. + * Allow GNU style "make variables" to be used with Configure. + * Claim the namespaces OSSL and OPENSSL, represented as symbol prefixes + * Rewrite of devcrypto engine + +OpenSSL 1.1.0 +------------- + +### Major changes between OpenSSL 1.1.0k and OpenSSL 1.1.0l [10 Sep 2019] + + * Fixed a padding oracle in PKCS7_dataDecode and CMS_decrypt_set1_pkey + ([CVE-2019-1563]) + * For built-in EC curves, ensure an EC_GROUP built from the curve name is + used even when parsing explicit parameters + * Compute ECC cofactors if not provided during EC_GROUP construction + ([CVE-2019-1547]) + * Use Windows installation paths in the mingw builds ([CVE-2019-1552]) + +### Major changes between OpenSSL 1.1.0j and OpenSSL 1.1.0k [28 May 2019] + + * Prevent over long nonces in ChaCha20-Poly1305 ([CVE-2019-1543]) + +### Major changes between OpenSSL 1.1.0i and OpenSSL 1.1.0j [20 Nov 2018] + + * Timing vulnerability in DSA signature generation ([CVE-2018-0734]) + * Timing vulnerability in ECDSA signature generation ([CVE-2018-0735]) + +### Major changes between OpenSSL 1.1.0h and OpenSSL 1.1.0i [14 Aug 2018] + + * Client DoS due to large DH parameter ([CVE-2018-0732]) + * Cache timing vulnerability in RSA Key Generation ([CVE-2018-0737]) + +### Major changes between OpenSSL 1.1.0g and OpenSSL 1.1.0h [27 Mar 2018] + + * Constructed ASN.1 types with a recursive definition could exceed the + stack ([CVE-2018-0739]) + * Incorrect CRYPTO_memcmp on HP-UX PA-RISC ([CVE-2018-0733]) + * rsaz_1024_mul_avx2 overflow bug on x86_64 ([CVE-2017-3738]) + +### Major changes between OpenSSL 1.1.0f and OpenSSL 1.1.0g [2 Nov 2017] + + * bn_sqrx8x_internal carry bug on x86_64 ([CVE-2017-3736]) + * Malformed X.509 IPAddressFamily could cause OOB read ([CVE-2017-3735]) + +### Major changes between OpenSSL 1.1.0e and OpenSSL 1.1.0f [25 May 2017] + + * config now recognises 64-bit mingw and chooses mingw64 instead of mingw + +### Major changes between OpenSSL 1.1.0d and OpenSSL 1.1.0e [16 Feb 2017] + + * Encrypt-Then-Mac renegotiation crash ([CVE-2017-3733]) + +### Major changes between OpenSSL 1.1.0c and OpenSSL 1.1.0d [26 Jan 2017] + + * Truncated packet could crash via OOB read ([CVE-2017-3731]) + * Bad (EC)DHE parameters cause a client crash ([CVE-2017-3730]) + * BN_mod_exp may produce incorrect results on x86_64 ([CVE-2017-3732]) + +### Major changes between OpenSSL 1.1.0b and OpenSSL 1.1.0c [10 Nov 2016] + + * ChaCha20/Poly1305 heap-buffer-overflow ([CVE-2016-7054]) + * CMS Null dereference ([CVE-2016-7053]) + * Montgomery multiplication may produce incorrect results ([CVE-2016-7055]) + +### Major changes between OpenSSL 1.1.0a and OpenSSL 1.1.0b [26 Sep 2016] + + * Fix Use After Free for large message sizes ([CVE-2016-6309]) + +### Major changes between OpenSSL 1.1.0 and OpenSSL 1.1.0a [22 Sep 2016] + + * OCSP Status Request extension unbounded memory growth ([CVE-2016-6304]) + * SSL_peek() hang on empty record ([CVE-2016-6305]) + * Excessive allocation of memory in tls_get_message_header() + ([CVE-2016-6307]) + * Excessive allocation of memory in dtls1_preprocess_fragment() + ([CVE-2016-6308]) + +### Major changes between OpenSSL 1.0.2h and OpenSSL 1.1.0 [25 Aug 2016] + + * Copyright text was shrunk to a boilerplate that points to the license + * "shared" builds are now the default when possible + * Added support for "pipelining" + * Added the AFALG engine + * New threading API implemented + * Support for ChaCha20 and Poly1305 added to libcrypto and libssl + * Support for extended master secret + * CCM ciphersuites + * Reworked test suite, now based on perl, Test::Harness and Test::More + * *Most* libcrypto and libssl public structures were made opaque, + including: + BIGNUM and associated types, EC_KEY and EC_KEY_METHOD, + DH and DH_METHOD, DSA and DSA_METHOD, RSA and RSA_METHOD, + BIO and BIO_METHOD, EVP_MD_CTX, EVP_MD, EVP_CIPHER_CTX, + EVP_CIPHER, EVP_PKEY and associated types, HMAC_CTX, + X509, X509_CRL, X509_OBJECT, X509_STORE_CTX, X509_STORE, + X509_LOOKUP, X509_LOOKUP_METHOD + * libssl internal structures made opaque + * SSLv2 support removed + * Kerberos ciphersuite support removed + * RC4 removed from DEFAULT ciphersuites in libssl + * 40 and 56 bit cipher support removed from libssl + * All public header files moved to include/openssl, no more symlinking + * SSL/TLS state machine, version negotiation and record layer rewritten + * EC revision: now operations use new EC_KEY_METHOD. + * Support for OCB mode added to libcrypto + * Support for asynchronous crypto operations added to libcrypto and libssl + * Deprecated interfaces can now be disabled at build time either + relative to the latest release via the "no-deprecated" Configure + argument, or via the "--api=1.1.0|1.0.0|0.9.8" option. + * Application software can be compiled with -DOPENSSL_API_COMPAT=version + to ensure that features deprecated in that version are not exposed. + * Support for RFC6698/RFC7671 DANE TLSA peer authentication + * Change of Configure to use --prefix as the main installation + directory location rather than --openssldir. The latter becomes + the directory for certs, private key and openssl.cnf exclusively. + * Reworked BIO networking library, with full support for IPv6. + * New "unified" build system + * New security levels + * Support for scrypt algorithm + * Support for X25519 + * Extended SSL_CONF support using configuration files + * KDF algorithm support. Implement TLS PRF as a KDF. + * Support for Certificate Transparency + * HKDF support. + +OpenSSL 1.0.2 +------------- + +### Major changes between OpenSSL 1.0.2s and OpenSSL 1.0.2t [10 Sep 2019] + + * Fixed a padding oracle in PKCS7_dataDecode and CMS_decrypt_set1_pkey + ([CVE-2019-1563]) + * For built-in EC curves, ensure an EC_GROUP built from the curve name is + used even when parsing explicit parameters + * Compute ECC cofactors if not provided during EC_GROUP construction + ([CVE-2019-1547]) + * Document issue with installation paths in diverse Windows builds + ([CVE-2019-1552]) + +### Major changes between OpenSSL 1.0.2r and OpenSSL 1.0.2s [28 May 2019] + + * None + +### Major changes between OpenSSL 1.0.2q and OpenSSL 1.0.2r [26 Feb 2019] + + * 0-byte record padding oracle ([CVE-2019-1559]) + +### Major changes between OpenSSL 1.0.2p and OpenSSL 1.0.2q [20 Nov 2018] + + * Microarchitecture timing vulnerability in ECC scalar multiplication ([CVE-2018-5407]) + * Timing vulnerability in DSA signature generation ([CVE-2018-0734]) + +### Major changes between OpenSSL 1.0.2o and OpenSSL 1.0.2p [14 Aug 2018] + + * Client DoS due to large DH parameter ([CVE-2018-0732]) + * Cache timing vulnerability in RSA Key Generation ([CVE-2018-0737]) + +### Major changes between OpenSSL 1.0.2n and OpenSSL 1.0.2o [27 Mar 2018] + + * Constructed ASN.1 types with a recursive definition could exceed the + stack ([CVE-2018-0739]) + +### Major changes between OpenSSL 1.0.2m and OpenSSL 1.0.2n [7 Dec 2017] + + * Read/write after SSL object in error state ([CVE-2017-3737]) + * rsaz_1024_mul_avx2 overflow bug on x86_64 ([CVE-2017-3738]) + +### Major changes between OpenSSL 1.0.2l and OpenSSL 1.0.2m [2 Nov 2017] + + * bn_sqrx8x_internal carry bug on x86_64 ([CVE-2017-3736]) + * Malformed X.509 IPAddressFamily could cause OOB read ([CVE-2017-3735]) + +### Major changes between OpenSSL 1.0.2k and OpenSSL 1.0.2l [25 May 2017] + + * config now recognises 64-bit mingw and chooses mingw64 instead of mingw + +### Major changes between OpenSSL 1.0.2j and OpenSSL 1.0.2k [26 Jan 2017] + + * Truncated packet could crash via OOB read ([CVE-2017-3731]) + * BN_mod_exp may produce incorrect results on x86_64 ([CVE-2017-3732]) + * Montgomery multiplication may produce incorrect results ([CVE-2016-7055]) + +### Major changes between OpenSSL 1.0.2i and OpenSSL 1.0.2j [26 Sep 2016] + + * Missing CRL sanity check ([CVE-2016-7052]) + +### Major changes between OpenSSL 1.0.2h and OpenSSL 1.0.2i [22 Sep 2016] + + * OCSP Status Request extension unbounded memory growth ([CVE-2016-6304]) + * SWEET32 Mitigation ([CVE-2016-2183]) + * OOB write in MDC2_Update() ([CVE-2016-6303]) + * Malformed SHA512 ticket DoS ([CVE-2016-6302]) + * OOB write in BN_bn2dec() ([CVE-2016-2182]) + * OOB read in TS_OBJ_print_bio() ([CVE-2016-2180]) + * Pointer arithmetic undefined behaviour ([CVE-2016-2177]) + * Constant time flag not preserved in DSA signing ([CVE-2016-2178]) + * DTLS buffered message DoS ([CVE-2016-2179]) + * DTLS replay protection DoS ([CVE-2016-2181]) + * Certificate message OOB reads ([CVE-2016-6306]) + +### Major changes between OpenSSL 1.0.2g and OpenSSL 1.0.2h [3 May 2016] + + * Prevent padding oracle in AES-NI CBC MAC check ([CVE-2016-2107]) + * Fix EVP_EncodeUpdate overflow ([CVE-2016-2105]) + * Fix EVP_EncryptUpdate overflow ([CVE-2016-2106]) + * Prevent ASN.1 BIO excessive memory allocation ([CVE-2016-2109]) + * EBCDIC overread ([CVE-2016-2176]) + * Modify behavior of ALPN to invoke callback after SNI/servername + callback, such that updates to the SSL_CTX affect ALPN. + * Remove LOW from the DEFAULT cipher list. This removes singles DES from + the default. + * Only remove the SSLv2 methods with the no-ssl2-method option. + +### Major changes between OpenSSL 1.0.2f and OpenSSL 1.0.2g [1 Mar 2016] + + * Disable weak ciphers in SSLv3 and up in default builds of OpenSSL. + * Disable SSLv2 default build, default negotiation and weak ciphers + ([CVE-2016-0800]) + * Fix a double-free in DSA code ([CVE-2016-0705]) + * Disable SRP fake user seed to address a server memory leak + ([CVE-2016-0798]) + * Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption + ([CVE-2016-0797]) + * Fix memory issues in BIO_*printf functions ([CVE-2016-0799]) + * Fix side channel attack on modular exponentiation ([CVE-2016-0702]) + +### Major changes between OpenSSL 1.0.2e and OpenSSL 1.0.2f [28 Jan 2016] + + * DH small subgroups ([CVE-2016-0701]) + * SSLv2 doesn't block disabled ciphers ([CVE-2015-3197]) + +### Major changes between OpenSSL 1.0.2d and OpenSSL 1.0.2e [3 Dec 2015] + + * BN_mod_exp may produce incorrect results on x86_64 ([CVE-2015-3193]) + * Certificate verify crash with missing PSS parameter ([CVE-2015-3194]) + * X509_ATTRIBUTE memory leak ([CVE-2015-3195]) + * Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs + * In DSA_generate_parameters_ex, if the provided seed is too short, + return an error + +### Major changes between OpenSSL 1.0.2c and OpenSSL 1.0.2d [9 Jul 2015] + + * Alternate chains certificate forgery ([CVE-2015-1793]) + * Race condition handling PSK identify hint ([CVE-2015-3196]) + +### Major changes between OpenSSL 1.0.2b and OpenSSL 1.0.2c [12 Jun 2015] + + * Fix HMAC ABI incompatibility + +### Major changes between OpenSSL 1.0.2a and OpenSSL 1.0.2b [11 Jun 2015] + + * Malformed ECParameters causes infinite loop ([CVE-2015-1788]) + * Exploitable out-of-bounds read in X509_cmp_time ([CVE-2015-1789]) + * PKCS7 crash with missing EnvelopedContent ([CVE-2015-1790]) + * CMS verify infinite loop with unknown hash function ([CVE-2015-1792]) + * Race condition handling NewSessionTicket ([CVE-2015-1791]) + +### Major changes between OpenSSL 1.0.2 and OpenSSL 1.0.2a [19 Mar 2015] + + * OpenSSL 1.0.2 ClientHello sigalgs DoS fix ([CVE-2015-0291]) + * Multiblock corrupted pointer fix ([CVE-2015-0290]) + * Segmentation fault in DTLSv1_listen fix ([CVE-2015-0207]) + * Segmentation fault in ASN1_TYPE_cmp fix ([CVE-2015-0286]) + * Segmentation fault for invalid PSS parameters fix ([CVE-2015-0208]) + * ASN.1 structure reuse memory corruption fix ([CVE-2015-0287]) + * PKCS7 NULL pointer dereferences fix ([CVE-2015-0289]) + * DoS via reachable assert in SSLv2 servers fix ([CVE-2015-0293]) + * Empty CKE with client auth and DHE fix ([CVE-2015-1787]) + * Handshake with unseeded PRNG fix ([CVE-2015-0285]) + * Use After Free following d2i_ECPrivatekey error fix ([CVE-2015-0209]) + * X509_to_X509_REQ NULL pointer deref fix ([CVE-2015-0288]) + * Removed the export ciphers from the DEFAULT ciphers + +### Major changes between OpenSSL 1.0.1l and OpenSSL 1.0.2 [22 Jan 2015] + + * Suite B support for TLS 1.2 and DTLS 1.2 + * Support for DTLS 1.2 + * TLS automatic EC curve selection. + * API to set TLS supported signature algorithms and curves + * SSL_CONF configuration API. + * TLS Brainpool support. + * ALPN support. + * CMS support for RSA-PSS, RSA-OAEP, ECDH and X9.42 DH. + +OpenSSL 1.0.1 +------------- + +### Major changes between OpenSSL 1.0.1t and OpenSSL 1.0.1u [22 Sep 2016] + + * OCSP Status Request extension unbounded memory growth ([CVE-2016-6304]) + * SWEET32 Mitigation ([CVE-2016-2183]) + * OOB write in MDC2_Update() ([CVE-2016-6303]) + * Malformed SHA512 ticket DoS ([CVE-2016-6302]) + * OOB write in BN_bn2dec() ([CVE-2016-2182]) + * OOB read in TS_OBJ_print_bio() ([CVE-2016-2180]) + * Pointer arithmetic undefined behaviour ([CVE-2016-2177]) + * Constant time flag not preserved in DSA signing ([CVE-2016-2178]) + * DTLS buffered message DoS ([CVE-2016-2179]) + * DTLS replay protection DoS ([CVE-2016-2181]) + * Certificate message OOB reads ([CVE-2016-6306]) + +### Major changes between OpenSSL 1.0.1s and OpenSSL 1.0.1t [3 May 2016] + + * Prevent padding oracle in AES-NI CBC MAC check ([CVE-2016-2107]) + * Fix EVP_EncodeUpdate overflow ([CVE-2016-2105]) + * Fix EVP_EncryptUpdate overflow ([CVE-2016-2106]) + * Prevent ASN.1 BIO excessive memory allocation ([CVE-2016-2109]) + * EBCDIC overread ([CVE-2016-2176]) + * Modify behavior of ALPN to invoke callback after SNI/servername + callback, such that updates to the SSL_CTX affect ALPN. + * Remove LOW from the DEFAULT cipher list. This removes singles DES from + the default. + * Only remove the SSLv2 methods with the no-ssl2-method option. + +### Major changes between OpenSSL 1.0.1r and OpenSSL 1.0.1s [1 Mar 2016] + + * Disable weak ciphers in SSLv3 and up in default builds of OpenSSL. + * Disable SSLv2 default build, default negotiation and weak ciphers + ([CVE-2016-0800]) + * Fix a double-free in DSA code ([CVE-2016-0705]) + * Disable SRP fake user seed to address a server memory leak + ([CVE-2016-0798]) + * Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption + ([CVE-2016-0797]) + * Fix memory issues in BIO_*printf functions ([CVE-2016-0799]) + * Fix side channel attack on modular exponentiation ([CVE-2016-0702]) + +### Major changes between OpenSSL 1.0.1q and OpenSSL 1.0.1r [28 Jan 2016] + + * Protection for DH small subgroup attacks + * SSLv2 doesn't block disabled ciphers ([CVE-2015-3197]) + +### Major changes between OpenSSL 1.0.1p and OpenSSL 1.0.1q [3 Dec 2015] + + * Certificate verify crash with missing PSS parameter ([CVE-2015-3194]) + * X509_ATTRIBUTE memory leak ([CVE-2015-3195]) + * Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs + * In DSA_generate_parameters_ex, if the provided seed is too short, + return an error + +### Major changes between OpenSSL 1.0.1o and OpenSSL 1.0.1p [9 Jul 2015] + + * Alternate chains certificate forgery ([CVE-2015-1793]) + * Race condition handling PSK identify hint ([CVE-2015-3196]) + +### Major changes between OpenSSL 1.0.1n and OpenSSL 1.0.1o [12 Jun 2015] + + * Fix HMAC ABI incompatibility + +### Major changes between OpenSSL 1.0.1m and OpenSSL 1.0.1n [11 Jun 2015] + + * Malformed ECParameters causes infinite loop ([CVE-2015-1788]) + * Exploitable out-of-bounds read in X509_cmp_time ([CVE-2015-1789]) + * PKCS7 crash with missing EnvelopedContent ([CVE-2015-1790]) + * CMS verify infinite loop with unknown hash function ([CVE-2015-1792]) + * Race condition handling NewSessionTicket ([CVE-2015-1791]) + +### Major changes between OpenSSL 1.0.1l and OpenSSL 1.0.1m [19 Mar 2015] + + * Segmentation fault in ASN1_TYPE_cmp fix ([CVE-2015-0286]) + * ASN.1 structure reuse memory corruption fix ([CVE-2015-0287]) + * PKCS7 NULL pointer dereferences fix ([CVE-2015-0289]) + * DoS via reachable assert in SSLv2 servers fix ([CVE-2015-0293]) + * Use After Free following d2i_ECPrivatekey error fix ([CVE-2015-0209]) + * X509_to_X509_REQ NULL pointer deref fix ([CVE-2015-0288]) + * Removed the export ciphers from the DEFAULT ciphers + +### Major changes between OpenSSL 1.0.1k and OpenSSL 1.0.1l [15 Jan 2015] + + * Build fixes for the Windows and OpenVMS platforms + +### Major changes between OpenSSL 1.0.1j and OpenSSL 1.0.1k [8 Jan 2015] + + * Fix for [CVE-2014-3571] + * Fix for [CVE-2015-0206] + * Fix for [CVE-2014-3569] + * Fix for [CVE-2014-3572] + * Fix for [CVE-2015-0204] + * Fix for [CVE-2015-0205] + * Fix for [CVE-2014-8275] + * Fix for [CVE-2014-3570] + +### Major changes between OpenSSL 1.0.1i and OpenSSL 1.0.1j [15 Oct 2014] + + * Fix for [CVE-2014-3513] + * Fix for [CVE-2014-3567] + * Mitigation for [CVE-2014-3566] (SSL protocol vulnerability) + * Fix for [CVE-2014-3568] + +### Major changes between OpenSSL 1.0.1h and OpenSSL 1.0.1i [6 Aug 2014] + + * Fix for [CVE-2014-3512] + * Fix for [CVE-2014-3511] + * Fix for [CVE-2014-3510] + * Fix for [CVE-2014-3507] + * Fix for [CVE-2014-3506] + * Fix for [CVE-2014-3505] + * Fix for [CVE-2014-3509] + * Fix for [CVE-2014-5139] + * Fix for [CVE-2014-3508] + +### Major changes between OpenSSL 1.0.1g and OpenSSL 1.0.1h [5 Jun 2014] + + * Fix for [CVE-2014-0224] + * Fix for [CVE-2014-0221] + * Fix for [CVE-2014-0198] + * Fix for [CVE-2014-0195] + * Fix for [CVE-2014-3470] + * Fix for [CVE-2010-5298] + +### Major changes between OpenSSL 1.0.1f and OpenSSL 1.0.1g [7 Apr 2014] + + * Fix for [CVE-2014-0160] + * Add TLS padding extension workaround for broken servers. + * Fix for [CVE-2014-0076] + +### Major changes between OpenSSL 1.0.1e and OpenSSL 1.0.1f [6 Jan 2014] + + * Don't include gmt_unix_time in TLS server and client random values + * Fix for TLS record tampering bug ([CVE-2013-4353]) + * Fix for TLS version checking bug ([CVE-2013-6449]) + * Fix for DTLS retransmission bug ([CVE-2013-6450]) + +### Major changes between OpenSSL 1.0.1d and OpenSSL 1.0.1e [11 Feb 2013] + + * Corrected fix for ([CVE-2013-0169]) + +### Major changes between OpenSSL 1.0.1c and OpenSSL 1.0.1d [4 Feb 2013] + + * Fix renegotiation in TLS 1.1, 1.2 by using the correct TLS version. + * Include the fips configuration module. + * Fix OCSP bad key DoS attack ([CVE-2013-0166]) + * Fix for SSL/TLS/DTLS CBC plaintext recovery attack ([CVE-2013-0169]) + * Fix for TLS AESNI record handling flaw ([CVE-2012-2686]) + +### Major changes between OpenSSL 1.0.1b and OpenSSL 1.0.1c [10 May 2012] + + * Fix TLS/DTLS record length checking bug ([CVE-2012-2333]) + * Don't attempt to use non-FIPS composite ciphers in FIPS mode. + +### Major changes between OpenSSL 1.0.1a and OpenSSL 1.0.1b [26 Apr 2012] + + * Fix compilation error on non-x86 platforms. + * Make FIPS capable OpenSSL ciphers work in non-FIPS mode. + * Fix SSL_OP_NO_TLSv1_1 clash with SSL_OP_ALL in OpenSSL 1.0.0 + +### Major changes between OpenSSL 1.0.1 and OpenSSL 1.0.1a [19 Apr 2012] + + * Fix for ASN1 overflow bug ([CVE-2012-2110]) + * Workarounds for some servers that hang on long client hellos. + * Fix SEGV in AES code. + +### Major changes between OpenSSL 1.0.0h and OpenSSL 1.0.1 [14 Mar 2012] + + * TLS/DTLS heartbeat support. + * SCTP support. + * RFC 5705 TLS key material exporter. + * RFC 5764 DTLS-SRTP negotiation. + * Next Protocol Negotiation. + * PSS signatures in certificates, requests and CRLs. + * Support for password based recipient info for CMS. + * Support TLS v1.2 and TLS v1.1. + * Preliminary FIPS capability for unvalidated 2.0 FIPS module. + * SRP support. + +OpenSSL 1.0.0 +------------- + +### Major changes between OpenSSL 1.0.0s and OpenSSL 1.0.0t [3 Dec 2015] + + * X509_ATTRIBUTE memory leak (([CVE-2015-3195])) + * Race condition handling PSK identify hint ([CVE-2015-3196]) + +### Major changes between OpenSSL 1.0.0r and OpenSSL 1.0.0s [11 Jun 2015] + + * Malformed ECParameters causes infinite loop ([CVE-2015-1788]) + * Exploitable out-of-bounds read in X509_cmp_time ([CVE-2015-1789]) + * PKCS7 crash with missing EnvelopedContent ([CVE-2015-1790]) + * CMS verify infinite loop with unknown hash function ([CVE-2015-1792]) + * Race condition handling NewSessionTicket ([CVE-2015-1791]) + +### Major changes between OpenSSL 1.0.0q and OpenSSL 1.0.0r [19 Mar 2015] + + * Segmentation fault in ASN1_TYPE_cmp fix ([CVE-2015-0286]) + * ASN.1 structure reuse memory corruption fix ([CVE-2015-0287]) + * PKCS7 NULL pointer dereferences fix ([CVE-2015-0289]) + * DoS via reachable assert in SSLv2 servers fix ([CVE-2015-0293]) + * Use After Free following d2i_ECPrivatekey error fix ([CVE-2015-0209]) + * X509_to_X509_REQ NULL pointer deref fix ([CVE-2015-0288]) + * Removed the export ciphers from the DEFAULT ciphers + +### Major changes between OpenSSL 1.0.0p and OpenSSL 1.0.0q [15 Jan 2015] + + * Build fixes for the Windows and OpenVMS platforms + +### Major changes between OpenSSL 1.0.0o and OpenSSL 1.0.0p [8 Jan 2015] + + * Fix for [CVE-2014-3571] + * Fix for [CVE-2015-0206] + * Fix for [CVE-2014-3569] + * Fix for [CVE-2014-3572] + * Fix for [CVE-2015-0204] + * Fix for [CVE-2015-0205] + * Fix for [CVE-2014-8275] + * Fix for [CVE-2014-3570] + +### Major changes between OpenSSL 1.0.0n and OpenSSL 1.0.0o [15 Oct 2014] + + * Fix for [CVE-2014-3513] + * Fix for [CVE-2014-3567] + * Mitigation for [CVE-2014-3566] (SSL protocol vulnerability) + * Fix for [CVE-2014-3568] + +### Major changes between OpenSSL 1.0.0m and OpenSSL 1.0.0n [6 Aug 2014] + + * Fix for [CVE-2014-3510] + * Fix for [CVE-2014-3507] + * Fix for [CVE-2014-3506] + * Fix for [CVE-2014-3505] + * Fix for [CVE-2014-3509] + * Fix for [CVE-2014-3508] + + Known issues in OpenSSL 1.0.0m: + + * EAP-FAST and other applications using tls_session_secret_cb + won't resume sessions. Fixed in 1.0.0n-dev + * Compilation failure of s3_pkt.c on some platforms due to missing + `` include. Fixed in 1.0.0n-dev + +### Major changes between OpenSSL 1.0.0l and OpenSSL 1.0.0m [5 Jun 2014] + + * Fix for [CVE-2014-0224] + * Fix for [CVE-2014-0221] + * Fix for [CVE-2014-0198] + * Fix for [CVE-2014-0195] + * Fix for [CVE-2014-3470] + * Fix for [CVE-2014-0076] + * Fix for [CVE-2010-5298] + +### Major changes between OpenSSL 1.0.0k and OpenSSL 1.0.0l [6 Jan 2014] + + * Fix for DTLS retransmission bug ([CVE-2013-6450]) + +### Major changes between OpenSSL 1.0.0j and OpenSSL 1.0.0k [5 Feb 2013] + + * Fix for SSL/TLS/DTLS CBC plaintext recovery attack ([CVE-2013-0169]) + * Fix OCSP bad key DoS attack ([CVE-2013-0166]) + +### Major changes between OpenSSL 1.0.0i and OpenSSL 1.0.0j [10 May 2012] + + * Fix DTLS record length checking bug ([CVE-2012-2333]) + +### Major changes between OpenSSL 1.0.0h and OpenSSL 1.0.0i [19 Apr 2012] + + * Fix for ASN1 overflow bug ([CVE-2012-2110]) + +### Major changes between OpenSSL 1.0.0g and OpenSSL 1.0.0h [12 Mar 2012] + + * Fix for CMS/PKCS#7 MMA ([CVE-2012-0884]) + * Corrected fix for ([CVE-2011-4619]) + * Various DTLS fixes. + +### Major changes between OpenSSL 1.0.0f and OpenSSL 1.0.0g [18 Jan 2012] + + * Fix for DTLS DoS issue ([CVE-2012-0050]) + +### Major changes between OpenSSL 1.0.0e and OpenSSL 1.0.0f [4 Jan 2012] + + * Fix for DTLS plaintext recovery attack ([CVE-2011-4108]) + * Clear block padding bytes of SSL 3.0 records ([CVE-2011-4576]) + * Only allow one SGC handshake restart for SSL/TLS ([CVE-2011-4619]) + * Check parameters are not NULL in GOST ENGINE ([CVE-2012-0027]) + * Check for malformed RFC3779 data ([CVE-2011-4577]) + +### Major changes between OpenSSL 1.0.0d and OpenSSL 1.0.0e [6 Sep 2011] + + * Fix for CRL vulnerability issue ([CVE-2011-3207]) + * Fix for ECDH crashes ([CVE-2011-3210]) + * Protection against EC timing attacks. + * Support ECDH ciphersuites for certificates using SHA2 algorithms. + * Various DTLS fixes. + +### Major changes between OpenSSL 1.0.0c and OpenSSL 1.0.0d [8 Feb 2011] + + * Fix for security issue ([CVE-2011-0014]) + +### Major changes between OpenSSL 1.0.0b and OpenSSL 1.0.0c [2 Dec 2010] + + * Fix for security issue ([CVE-2010-4180]) + * Fix for ([CVE-2010-4252]) + * Fix mishandling of absent EC point format extension. + * Fix various platform compilation issues. + * Corrected fix for security issue ([CVE-2010-3864]). + +### Major changes between OpenSSL 1.0.0a and OpenSSL 1.0.0b [16 Nov 2010] + + * Fix for security issue ([CVE-2010-3864]). + * Fix for ([CVE-2010-2939]) + * Fix WIN32 build system for GOST ENGINE. + +### Major changes between OpenSSL 1.0.0 and OpenSSL 1.0.0a [1 Jun 2010] + + * Fix for security issue ([CVE-2010-1633]). + * GOST MAC and CFB fixes. + +### Major changes between OpenSSL 0.9.8n and OpenSSL 1.0.0 [29 Mar 2010] + + * RFC3280 path validation: sufficient to process PKITS tests. + * Integrated support for PVK files and keyblobs. + * Change default private key format to PKCS#8. + * CMS support: able to process all examples in RFC4134 + * Streaming ASN1 encode support for PKCS#7 and CMS. + * Multiple signer and signer add support for PKCS#7 and CMS. + * ASN1 printing support. + * Whirlpool hash algorithm added. + * RFC3161 time stamp support. + * New generalised public key API supporting ENGINE based algorithms. + * New generalised public key API utilities. + * New ENGINE supporting GOST algorithms. + * SSL/TLS GOST ciphersuite support. + * PKCS#7 and CMS GOST support. + * RFC4279 PSK ciphersuite support. + * Supported points format extension for ECC ciphersuites. + * ecdsa-with-SHA224/256/384/512 signature types. + * dsa-with-SHA224 and dsa-with-SHA256 signature types. + * Opaque PRF Input TLS extension support. + * Updated time routines to avoid OS limitations. + +OpenSSL 0.9.x +------------- + +### Major changes between OpenSSL 0.9.8m and OpenSSL 0.9.8n [24 Mar 2010] + + * CFB cipher definition fixes. + * Fix security issues [CVE-2010-0740] and [CVE-2010-0433]. + +### Major changes between OpenSSL 0.9.8l and OpenSSL 0.9.8m [25 Feb 2010] + + * Cipher definition fixes. + * Workaround for slow RAND_poll() on some WIN32 versions. + * Remove MD2 from algorithm tables. + * SPKAC handling fixes. + * Support for RFC5746 TLS renegotiation extension. + * Compression memory leak fixed. + * Compression session resumption fixed. + * Ticket and SNI coexistence fixes. + * Many fixes to DTLS handling. + +### Major changes between OpenSSL 0.9.8k and OpenSSL 0.9.8l [5 Nov 2009] + + * Temporary work around for [CVE-2009-3555]: disable renegotiation. + +### Major changes between OpenSSL 0.9.8j and OpenSSL 0.9.8k [25 Mar 2009] + + * Fix various build issues. + * Fix security issues [CVE-2009-0590], [CVE-2009-0591], [CVE-2009-0789] + +### Major changes between OpenSSL 0.9.8i and OpenSSL 0.9.8j [7 Jan 2009] + + * Fix security issue ([CVE-2008-5077]) + * Merge FIPS 140-2 branch code. + +### Major changes between OpenSSL 0.9.8g and OpenSSL 0.9.8h [28 May 2008] + + * CryptoAPI ENGINE support. + * Various precautionary measures. + * Fix for bugs affecting certificate request creation. + * Support for local machine keyset attribute in PKCS#12 files. + +### Major changes between OpenSSL 0.9.8f and OpenSSL 0.9.8g [19 Oct 2007] + + * Backport of CMS functionality to 0.9.8. + * Fixes for bugs introduced with 0.9.8f. + +### Major changes between OpenSSL 0.9.8e and OpenSSL 0.9.8f [11 Oct 2007] + + * Add gcc 4.2 support. + * Add support for AES and SSE2 assembly language optimization + for VC++ build. + * Support for RFC4507bis and server name extensions if explicitly + selected at compile time. + * DTLS improvements. + * RFC4507bis support. + * TLS Extensions support. + +### Major changes between OpenSSL 0.9.8d and OpenSSL 0.9.8e [23 Feb 2007] + + * Various ciphersuite selection fixes. + * RFC3779 support. + +### Major changes between OpenSSL 0.9.8c and OpenSSL 0.9.8d [28 Sep 2006] + + * Introduce limits to prevent malicious key DoS ([CVE-2006-2940]) + * Fix security issues [CVE-2006-2937], [CVE-2006-3737], [CVE-2006-4343] + * Changes to ciphersuite selection algorithm + +### Major changes between OpenSSL 0.9.8b and OpenSSL 0.9.8c [5 Sep 2006] + + * Fix Daniel Bleichenbacher forged signature attack, [CVE-2006-4339] + * New cipher Camellia + +### Major changes between OpenSSL 0.9.8a and OpenSSL 0.9.8b [4 May 2006] + + * Cipher string fixes. + * Fixes for VC++ 2005. + * Updated ECC cipher suite support. + * New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free(). + * Zlib compression usage fixes. + * Built in dynamic engine compilation support on Win32. + * Fixes auto dynamic engine loading in Win32. + +### Major changes between OpenSSL 0.9.8 and OpenSSL 0.9.8a [11 Oct 2005] + + * Fix potential SSL 2.0 rollback ([CVE-2005-2969]) + * Extended Windows CE support + +### Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.8 [5 Jul 2005] + + * Major work on the BIGNUM library for higher efficiency and to + make operations more streamlined and less contradictory. This + is the result of a major audit of the BIGNUM library. + * Addition of BIGNUM functions for fields GF(2^m) and NIST + curves, to support the Elliptic Crypto functions. + * Major work on Elliptic Crypto; ECDH and ECDSA added, including + the use through EVP, X509 and ENGINE. + * New ASN.1 mini-compiler that's usable through the OpenSSL + configuration file. + * Added support for ASN.1 indefinite length constructed encoding. + * New PKCS#12 'medium level' API to manipulate PKCS#12 files. + * Complete rework of shared library construction and linking + programs with shared or static libraries, through a separate + Makefile.shared. + * Rework of the passing of parameters from one Makefile to another. + * Changed ENGINE framework to load dynamic engine modules + automatically from specifically given directories. + * New structure and ASN.1 functions for CertificatePair. + * Changed the ZLIB compression method to be stateful. + * Changed the key-generation and primality testing "progress" + mechanism to take a structure that contains the ticker + function and an argument. + * New engine module: GMP (performs private key exponentiation). + * New engine module: VIA PadLOck ACE extension in VIA C3 + Nehemiah processors. + * Added support for IPv6 addresses in certificate extensions. + See RFC 1884, section 2.2. + * Added support for certificate policy mappings, policy + constraints and name constraints. + * Added support for multi-valued AVAs in the OpenSSL + configuration file. + * Added support for multiple certificates with the same subject + in the 'openssl ca' index file. + * Make it possible to create self-signed certificates using + 'openssl ca -selfsign'. + * Make it possible to generate a serial number file with + 'openssl ca -create_serial'. + * New binary search functions with extended functionality. + * New BUF functions. + * New STORE structure and library to provide an interface to all + sorts of data repositories. Supports storage of public and + private keys, certificates, CRLs, numbers and arbitrary blobs. + This library is unfortunately unfinished and unused within + OpenSSL. + * New control functions for the error stack. + * Changed the PKCS#7 library to support one-pass S/MIME + processing. + * Added the possibility to compile without old deprecated + functionality with the OPENSSL_NO_DEPRECATED macro or the + 'no-deprecated' argument to the config and Configure scripts. + * Constification of all ASN.1 conversion functions, and other + affected functions. + * Improved platform support for PowerPC. + * New FIPS 180-2 algorithms (SHA-224, -256, -384 and -512). + * New X509_VERIFY_PARAM structure to support parameterisation + of X.509 path validation. + * Major overhaul of RC4 performance on Intel P4, IA-64 and + AMD64. + * Changed the Configure script to have some algorithms disabled + by default. Those can be explicitly enabled with the new + argument form 'enable-xxx'. + * Change the default digest in 'openssl' commands from MD5 to + SHA-1. + * Added support for DTLS. + * New BIGNUM blinding. + * Added support for the RSA-PSS encryption scheme + * Added support for the RSA X.931 padding. + * Added support for BSD sockets on NetWare. + * Added support for files larger than 2GB. + * Added initial support for Win64. + * Added alternate pkg-config files. + +### Major changes between OpenSSL 0.9.7l and OpenSSL 0.9.7m [23 Feb 2007] + + * FIPS 1.1.1 module linking. + * Various ciphersuite selection fixes. + +### Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l [28 Sep 2006] + + * Introduce limits to prevent malicious key DoS ([CVE-2006-2940]) + * Fix security issues [CVE-2006-2937], [CVE-2006-3737], [CVE-2006-4343] + +### Major changes between OpenSSL 0.9.7j and OpenSSL 0.9.7k [5 Sep 2006] + + * Fix Daniel Bleichenbacher forged signature attack, [CVE-2006-4339] + +### Major changes between OpenSSL 0.9.7i and OpenSSL 0.9.7j [4 May 2006] + + * Visual C++ 2005 fixes. + * Update Windows build system for FIPS. + +### Major changes between OpenSSL 0.9.7h and OpenSSL 0.9.7i [14 Oct 2005] + + * 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] + + * Fix SSL 2.0 Rollback ([CVE-2005-2969]) + * Allow use of fixed-length exponent on DSA signing + * Default fixed-window RSA, DSA, DH private-key operations + +### Major changes between OpenSSL 0.9.7f and OpenSSL 0.9.7g [11 Apr 2005] + + * More compilation issues fixed. + * Adaptation to more modern Kerberos API. + * Enhanced or corrected configuration for Solaris64, Mingw and Cygwin. + * Enhanced x86_64 assembler BIGNUM module. + * More constification. + * Added processing of proxy certificates (RFC 3820). + +### Major changes between OpenSSL 0.9.7e and OpenSSL 0.9.7f [22 Mar 2005] + + * Several compilation issues fixed. + * Many memory allocation failure checks added. + * Improved comparison of X509 Name type. + * Mandatory basic checks on certificates. + * Performance improvements. + +### Major changes between OpenSSL 0.9.7d and OpenSSL 0.9.7e [25 Oct 2004] + + * Fix race condition in CRL checking code. + * Fixes to PKCS#7 (S/MIME) code. + +### Major changes between OpenSSL 0.9.7c and OpenSSL 0.9.7d [17 Mar 2004] + + * Security: Fix Kerberos ciphersuite SSL/TLS handshaking bug + * Security: Fix null-pointer assignment in do_change_cipher_spec() + * Allow multiple active certificates with same subject in CA index + * Multiple X509 verification fixes + * Speed up HMAC and other operations + +### Major changes between OpenSSL 0.9.7b and OpenSSL 0.9.7c [30 Sep 2003] + + * Security: fix various ASN1 parsing bugs. + * New -ignore_err option to OCSP utility. + * Various interop and bug fixes in S/MIME code. + * SSL/TLS protocol fix for unrequested client certificates. + +### Major changes between OpenSSL 0.9.7a and OpenSSL 0.9.7b [10 Apr 2003] + + * Security: counter the Klima-Pokorny-Rosa extension of + Bleichbacher's attack + * Security: make RSA blinding default. + * Configuration: Irix fixes, AIX fixes, better mingw support. + * Support for new platforms: linux-ia64-ecc. + * Build: shared library support fixes. + * ASN.1: treat domainComponent correctly. + * Documentation: fixes and additions. + +### Major changes between OpenSSL 0.9.7 and OpenSSL 0.9.7a [19 Feb 2003] + + * Security: Important security related bugfixes. + * Enhanced compatibility with MIT Kerberos. + * Can be built without the ENGINE framework. + * IA32 assembler enhancements. + * Support for new platforms: FreeBSD/IA64 and FreeBSD/Sparc64. + * Configuration: the no-err option now works properly. + * SSL/TLS: now handles manual certificate chain building. + * SSL/TLS: certain session ID malfunctions corrected. + +### Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.7 [30 Dec 2002] + + * New library section OCSP. + * Complete rewrite of ASN1 code. + * CRL checking in verify code and openssl utility. + * Extension copying in 'ca' utility. + * Flexible display options in 'ca' utility. + * Provisional support for international characters with UTF8. + * Support for external crypto devices ('engine') is no longer + a separate distribution. + * New elliptic curve library section. + * New AES (Rijndael) library section. + * Support for new platforms: Windows CE, Tandem OSS, A/UX, AIX 64-bit, + Linux x86_64, Linux 64-bit on Sparc v9 + * Extended support for some platforms: VxWorks + * Enhanced support for shared libraries. + * Now only builds PIC code when shared library support is requested. + * Support for pkg-config. + * Lots of new manuals. + * Makes symbolic links to or copies of manuals to cover all described + functions. + * Change DES API to clean up the namespace (some applications link also + against libdes providing similar functions having the same name). + Provide macros for backward compatibility (will be removed in the + future). + * Unify handling of cryptographic algorithms (software and engine) + to be available via EVP routines for asymmetric and symmetric ciphers. + * NCONF: new configuration handling routines. + * Change API to use more 'const' modifiers to improve error checking + and help optimizers. + * Finally remove references to RSAref. + * Reworked parts of the BIGNUM code. + * Support for new engines: Broadcom ubsec, Accelerated Encryption + Processing, IBM 4758. + * A few new engines added in the demos area. + * Extended and corrected OID (object identifier) table. + * PRNG: query at more locations for a random device, automatic query for + EGD style random sources at several locations. + * SSL/TLS: allow optional cipher choice according to server's preference. + * SSL/TLS: allow server to explicitly set new session ids. + * SSL/TLS: support Kerberos cipher suites (RFC2712). + Only supports MIT Kerberos for now. + * SSL/TLS: allow more precise control of renegotiations and sessions. + * SSL/TLS: add callback to retrieve SSL/TLS messages. + * SSL/TLS: support AES cipher suites (RFC3268). + +### Major changes between OpenSSL 0.9.6j and OpenSSL 0.9.6k [30 Sep 2003] + + * Security: fix various ASN1 parsing bugs. + * SSL/TLS protocol fix for unrequested client certificates. + +### Major changes between OpenSSL 0.9.6i and OpenSSL 0.9.6j [10 Apr 2003] + + * Security: counter the Klima-Pokorny-Rosa extension of + Bleichbacher's attack + * Security: make RSA blinding default. + * Build: shared library support fixes. + +### Major changes between OpenSSL 0.9.6h and OpenSSL 0.9.6i [19 Feb 2003] + + * Important security related bugfixes. + +### Major changes between OpenSSL 0.9.6g and OpenSSL 0.9.6h [5 Dec 2002] + + * New configuration targets for Tandem OSS and A/UX. + * New OIDs for Microsoft attributes. + * Better handling of SSL session caching. + * Better comparison of distinguished names. + * Better handling of shared libraries in a mixed GNU/non-GNU environment. + * Support assembler code with Borland C. + * Fixes for length problems. + * Fixes for uninitialised variables. + * Fixes for memory leaks, some unusual crashes and some race conditions. + * Fixes for smaller building problems. + * Updates of manuals, FAQ and other instructive documents. + +### Major changes between OpenSSL 0.9.6f and OpenSSL 0.9.6g [9 Aug 2002] + + * Important building fixes on Unix. + +### Major changes between OpenSSL 0.9.6e and OpenSSL 0.9.6f [8 Aug 2002] + + * Various important bugfixes. + +### Major changes between OpenSSL 0.9.6d and OpenSSL 0.9.6e [30 Jul 2002] + + * Important security related bugfixes. + * Various SSL/TLS library bugfixes. + +### Major changes between OpenSSL 0.9.6c and OpenSSL 0.9.6d [9 May 2002] + + * Various SSL/TLS library bugfixes. + * Fix DH parameter generation for 'non-standard' generators. + +### Major changes between OpenSSL 0.9.6b and OpenSSL 0.9.6c [21 Dec 2001] + + * Various SSL/TLS library bugfixes. + * BIGNUM library fixes. + * RSA OAEP and random number generation fixes. + * Object identifiers corrected and added. + * Add assembler BN routines for IA64. + * Add support for OS/390 Unix, UnixWare with gcc, OpenUNIX 8, + MIPS Linux; shared library support for Irix, HP-UX. + * Add crypto accelerator support for AEP, Baltimore SureWare, + Broadcom and Cryptographic Appliance's keyserver + [in 0.9.6c-engine release]. + +### Major changes between OpenSSL 0.9.6a and OpenSSL 0.9.6b [9 Jul 2001] + + * Security fix: PRNG improvements. + * Security fix: RSA OAEP check. + * Security fix: Reinsert and fix countermeasure to Bleichbacher's + attack. + * MIPS bug fix in BIGNUM. + * Bug fix in "openssl enc". + * Bug fix in X.509 printing routine. + * Bug fix in DSA verification routine and DSA S/MIME verification. + * Bug fix to make PRNG thread-safe. + * Bug fix in RAND_file_name(). + * Bug fix in compatibility mode trust settings. + * Bug fix in blowfish EVP. + * Increase default size for BIO buffering filter. + * Compatibility fixes in some scripts. + +### Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.6a [5 Apr 2001] + + * Security fix: change behavior of OpenSSL to avoid using + environment variables when running as root. + * Security fix: check the result of RSA-CRT to reduce the + possibility of deducing the private key from an incorrectly + calculated signature. + * Security fix: prevent Bleichenbacher's DSA attack. + * Security fix: Zero the premaster secret after deriving the + master secret in DH ciphersuites. + * Reimplement SSL_peek(), which had various problems. + * Compatibility fix: the function des_encrypt() renamed to + des_encrypt1() to avoid clashes with some Unixen libc. + * Bug fixes for Win32, HP/UX and Irix. + * Bug fixes in BIGNUM, SSL, PKCS#7, PKCS#12, X.509, CONF and + memory checking routines. + * Bug fixes for RSA operations in threaded environments. + * Bug fixes in misc. openssl applications. + * Remove a few potential memory leaks. + * Add tighter checks of BIGNUM routines. + * Shared library support has been reworked for generality. + * More documentation. + * New function BN_rand_range(). + * Add "-rand" option to openssl s_client and s_server. + +### Major changes between OpenSSL 0.9.5a and OpenSSL 0.9.6 [10 Oct 2000] + + * Some documentation for BIO and SSL libraries. + * Enhanced chain verification using key identifiers. + * New sign and verify options to 'dgst' application. + * Support for DER and PEM encoded messages in 'smime' application. + * New 'rsautl' application, low-level RSA utility. + * MD4 now included. + * Bugfix for SSL rollback padding check. + * Support for external crypto devices [1]. + * Enhanced EVP interface. + + [1] The support for external crypto devices is currently a separate + distribution. See the file README-Engine.md. + +### Major changes between OpenSSL 0.9.5 and OpenSSL 0.9.5a [1 Apr 2000] + + * Bug fixes for Win32, SuSE Linux, NeXTSTEP and FreeBSD 2.2.8 + * Shared library support for HPUX and Solaris-gcc + * Support of Linux/IA64 + * Assembler support for Mingw32 + * New 'rand' application + * New way to check for existence of algorithms from scripts + +### Major changes between OpenSSL 0.9.4 and OpenSSL 0.9.5 [25 May 2000] + + * S/MIME support in new 'smime' command + * Documentation for the OpenSSL command line application + * Automation of 'req' application + * Fixes to make s_client, s_server work under Windows + * Support for multiple fieldnames in SPKACs + * New SPKAC command line utility and associated library functions + * Options to allow passwords to be obtained from various sources + * New public key PEM format and options to handle it + * Many other fixes and enhancements to command line utilities + * Usable certificate chain verification + * Certificate purpose checking + * Certificate trust settings + * Support of authority information access extension + * Extensions in certificate requests + * Simplified X509 name and attribute routines + * Initial (incomplete) support for international character sets + * New DH_METHOD, DSA_METHOD and enhanced RSA_METHOD + * Read only memory BIOs and simplified creation function + * TLS/SSL protocol bugfixes: Accept TLS 'client hello' in SSL 3.0 + record; allow fragmentation and interleaving of handshake and other + data + * TLS/SSL code now "tolerates" MS SGC + * Work around for Netscape client certificate hang bug + * RSA_NULL option that removes RSA patent code but keeps other + RSA functionality + * Memory leak detection now allows applications to add extra information + via a per-thread stack + * PRNG robustness improved + * EGD support + * BIGNUM library bug fixes + * Faster DSA parameter generation + * Enhanced support for Alpha Linux + * Experimental macOS support + +### Major changes between OpenSSL 0.9.3 and OpenSSL 0.9.4 [9 Aug 1999] + + * Transparent support for PKCS#8 format private keys: these are used + by several software packages and are more secure than the standard + form + * PKCS#5 v2.0 implementation + * Password callbacks have a new void * argument for application data + * Avoid various memory leaks + * New pipe-like BIO that allows using the SSL library when actual I/O + must be handled by the application (BIO pair) + +### Major changes between OpenSSL 0.9.2b and OpenSSL 0.9.3 [24 May 1999] + + * Lots of enhancements and cleanups to the Configuration mechanism + * RSA OEAP related fixes + * Added "openssl ca -revoke" option for revoking a certificate + * Source cleanups: const correctness, type-safe stacks and ASN.1 SETs + * Source tree cleanups: removed lots of obsolete files + * Thawte SXNet, certificate policies and CRL distribution points + extension support + * Preliminary (experimental) S/MIME support + * Support for ASN.1 UTF8String and VisibleString + * Full integration of PKCS#12 code + * Sparc assembler bignum implementation, optimized hash functions + * Option to disable selected ciphers + +### Major changes between OpenSSL 0.9.1c and OpenSSL 0.9.2b [22 Mar 1999] + + * Fixed a security hole related to session resumption + * Fixed RSA encryption routines for the p < q case + * "ALL" in cipher lists now means "everything except NULL ciphers" + * Support for Triple-DES CBCM cipher + * Support of Optimal Asymmetric Encryption Padding (OAEP) for RSA + * First support for new TLSv1 ciphers + * Added a few new BIOs (syslog BIO, reliable BIO) + * Extended support for DSA certificate/keys. + * Extended support for Certificate Signing Requests (CSR) + * Initial support for X.509v3 extensions + * Extended support for compression inside the SSL record layer + * Overhauled Win32 builds + * Cleanups and fixes to the Big Number (BN) library + * Support for ASN.1 GeneralizedTime + * Splitted ASN.1 SETs from SEQUENCEs + * ASN1 and PEM support for Netscape Certificate Sequences + * Overhauled Perl interface + * Lots of source tree cleanups. + * Lots of memory leak fixes. + * Lots of bug fixes. + +### Major changes between SSLeay 0.9.0b and OpenSSL 0.9.1c [23 Dec 1998] + + * Integration of the popular NO_RSA/NO_DSA patches + * Initial support for compression inside the SSL record layer + * Added BIO proxy and filtering functionality + * Extended Big Number (BN) library + * Added RIPE MD160 message digest + * Added support for RC2/64bit cipher + * Extended ASN.1 parser routines + * Adjustments of the source tree for CVS + * Support for various new platforms + + +[CVE-2023-0401]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0401 +[CVE-2023-0286]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0286 +[CVE-2023-0217]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0217 +[CVE-2023-0216]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0216 +[CVE-2023-0215]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0215 +[CVE-2022-4450]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4450 +[CVE-2022-4304]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4304 +[CVE-2022-4203]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4203 +[CVE-2022-3996]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-3996 +[CVE-2022-2274]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-2274 +[CVE-2022-2097]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-2274 +[CVE-2020-1971]: https://www.openssl.org/news/vulnerabilities.html#CVE-2020-1971 +[CVE-2020-1967]: https://www.openssl.org/news/vulnerabilities.html#CVE-2020-1967 +[CVE-2019-1563]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1563 +[CVE-2019-1559]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1559 +[CVE-2019-1552]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1552 +[CVE-2019-1551]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1551 +[CVE-2019-1549]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1549 +[CVE-2019-1547]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1547 +[CVE-2019-1543]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1543 +[CVE-2018-5407]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-5407 +[CVE-2018-0739]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0739 +[CVE-2018-0737]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0737 +[CVE-2018-0735]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0735 +[CVE-2018-0734]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0734 +[CVE-2018-0733]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0733 +[CVE-2018-0732]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0732 +[CVE-2017-3738]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3738 +[CVE-2017-3737]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3737 +[CVE-2017-3736]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3736 +[CVE-2017-3735]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3735 +[CVE-2017-3733]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3733 +[CVE-2017-3732]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3732 +[CVE-2017-3731]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3731 +[CVE-2017-3730]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3730 +[CVE-2016-7055]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7055 +[CVE-2016-7054]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7054 +[CVE-2016-7053]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7053 +[CVE-2016-7052]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7052 +[CVE-2016-6309]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6309 +[CVE-2016-6308]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6308 +[CVE-2016-6307]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6307 +[CVE-2016-6306]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6306 +[CVE-2016-6305]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6305 +[CVE-2016-6304]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6304 +[CVE-2016-6303]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6303 +[CVE-2016-6302]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6302 +[CVE-2016-2183]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2183 +[CVE-2016-2182]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2182 +[CVE-2016-2181]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2181 +[CVE-2016-2180]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2180 +[CVE-2016-2179]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2179 +[CVE-2016-2178]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2178 +[CVE-2016-2177]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2177 +[CVE-2016-2176]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2176 +[CVE-2016-2109]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2109 +[CVE-2016-2107]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2107 +[CVE-2016-2106]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2106 +[CVE-2016-2105]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2105 +[CVE-2016-0800]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0800 +[CVE-2016-0799]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0799 +[CVE-2016-0798]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0798 +[CVE-2016-0797]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0797 +[CVE-2016-0705]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0705 +[CVE-2016-0702]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0702 +[CVE-2016-0701]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0701 +[CVE-2015-3197]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3197 +[CVE-2015-3196]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3196 +[CVE-2015-3195]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3195 +[CVE-2015-3194]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3194 +[CVE-2015-3193]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3193 +[CVE-2015-1793]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1793 +[CVE-2015-1792]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1792 +[CVE-2015-1791]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1791 +[CVE-2015-1790]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1790 +[CVE-2015-1789]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1789 +[CVE-2015-1788]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1788 +[CVE-2015-1787]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1787 +[CVE-2015-0293]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0293 +[CVE-2015-0291]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0291 +[CVE-2015-0290]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0290 +[CVE-2015-0289]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0289 +[CVE-2015-0288]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0288 +[CVE-2015-0287]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0287 +[CVE-2015-0286]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0286 +[CVE-2015-0285]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0285 +[CVE-2015-0209]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0209 +[CVE-2015-0208]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0208 +[CVE-2015-0207]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0207 +[CVE-2015-0206]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0206 +[CVE-2015-0205]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0205 +[CVE-2015-0204]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0204 +[CVE-2014-8275]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-8275 +[CVE-2014-5139]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-5139 +[CVE-2014-3572]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3572 +[CVE-2014-3571]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3571 +[CVE-2014-3570]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3570 +[CVE-2014-3569]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3569 +[CVE-2014-3568]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3568 +[CVE-2014-3567]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3567 +[CVE-2014-3566]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3566 +[CVE-2014-3513]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3513 +[CVE-2014-3512]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3512 +[CVE-2014-3511]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3511 +[CVE-2014-3510]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3510 +[CVE-2014-3509]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3509 +[CVE-2014-3508]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3508 +[CVE-2014-3507]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3507 +[CVE-2014-3506]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3506 +[CVE-2014-3505]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3505 +[CVE-2014-3470]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3470 +[CVE-2014-0224]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0224 +[CVE-2014-0221]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0221 +[CVE-2014-0198]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0198 +[CVE-2014-0195]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0195 +[CVE-2014-0160]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0160 +[CVE-2014-0076]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0076 +[CVE-2013-6450]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-6450 +[CVE-2013-6449]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-6449 +[CVE-2013-4353]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-4353 +[CVE-2013-0169]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-0169 +[CVE-2013-0166]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-0166 +[CVE-2012-2686]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2686 +[CVE-2012-2333]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2333 +[CVE-2012-2110]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2110 +[CVE-2012-0884]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0884 +[CVE-2012-0050]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0050 +[CVE-2012-0027]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0027 +[CVE-2011-4619]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4619 +[CVE-2011-4577]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4577 +[CVE-2011-4576]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4576 +[CVE-2011-4108]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4108 +[CVE-2011-3210]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-3210 +[CVE-2011-3207]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-3207 +[CVE-2011-0014]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-0014 +[CVE-2010-5298]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-5298 +[CVE-2010-4252]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-4252 +[CVE-2010-4180]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-4180 +[CVE-2010-3864]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-3864 +[CVE-2010-2939]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-2939 +[CVE-2010-1633]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-1633 +[CVE-2010-0740]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-0740 +[CVE-2010-0433]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-0433 +[CVE-2009-3555]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-3555 +[CVE-2009-0789]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0789 +[CVE-2009-0591]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0591 +[CVE-2009-0590]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0590 +[CVE-2008-5077]: https://www.openssl.org/news/vulnerabilities.html#CVE-2008-5077 +[CVE-2006-4343]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-4343 +[CVE-2006-4339]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-4339 +[CVE-2006-3737]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-3737 +[CVE-2006-2940]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2940 +[CVE-2006-2937]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2937 +[CVE-2005-2969]: https://www.openssl.org/news/vulnerabilities.html#CVE-2005-2969 diff --git a/crypto/openssl/NOTES-ANDROID.md b/crypto/openssl/NOTES-ANDROID.md new file mode 100644 index 000000000000..eebf03a4c496 --- /dev/null +++ b/crypto/openssl/NOTES-ANDROID.md @@ -0,0 +1,90 @@ +Notes for Android platforms +=========================== + + Requirement details + ------------------- + + Beside basic tools like perl and make you'll need to download the Android + NDK. It's available for Linux, macOS and Windows, but only Linux + version was actually tested. There is no reason to believe that macOS + wouldn't work. And as for Windows, it's unclear which "shell" would be + suitable, MSYS2 might have best chances. NDK version should play lesser + role, the goal is to support a range of most recent versions. + + Configuration + ------------- + + Android is a cross-compiled target and you can't rely on `./Configure` + to find out the configuration target for you. You have to name your + target explicitly; there are `android-arm`, `android-arm64`, `android-mips`, + `android-mip64`, `android-x86` and `android-x86_64` (`*MIPS` targets are no + longer supported with NDK R20+). + + Do not pass --cross-compile-prefix (as you might be tempted), as it + will be "calculated" automatically based on chosen platform. However, + you still need to know the prefix to extend your PATH, in order to + invoke `$(CROSS_COMPILE)clang` [`*gcc` on NDK 19 and lower] and company. + (`./Configure` will fail and give you a hint if you get it wrong.) + + Apart from `PATH` adjustment you need to set `ANDROID_NDK_ROOT` environment + to point at the `NDK` directory. If you're using a side-by-side NDK the path + will look something like `/some/where/android-sdk/ndk/`, and for a + standalone NDK the path will be something like `/some/where/android-ndk-`. + Both variables are significant at both configuration and compilation times. + The NDK customarily supports multiple Android API levels, e.g. `android-14`, + `android-21`, etc. By default latest API level is chosen. If you need to target + an older platform pass the argument `-D__ANDROID_API__=N` to `Configure`, + with `N` being the numerical value of the target platform version. For example, + to compile for Android 10 arm64 with a side-by-side NDK r20.0.5594570 + + export ANDROID_NDK_ROOT=/home/whoever/Android/android-sdk/ndk/20.0.5594570 + PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH + ./Configure android-arm64 -D__ANDROID_API__=29 + make + + Older versions of the NDK have GCC under their common prebuilt tools + directory, so the bin path will be slightly different. EG: to compile + for ICS on ARM with NDK 10d: + + export ANDROID_NDK_ROOT=/some/where/android-ndk-10d + PATH=$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin:$PATH + ./Configure android-arm -D__ANDROID_API__=14 + make + + Caveat lector! Earlier OpenSSL versions relied on additional `CROSS_SYSROOT` + variable set to `$ANDROID_NDK_ROOT/platforms/android-/arch-` to + appoint headers-n-libraries' location. It's still recognized in order + to facilitate migration from older projects. However, since API level + appears in `CROSS_SYSROOT` value, passing `-D__ANDROID_API__=N` can be in + conflict, and mixing the two is therefore not supported. Migration to + `CROSS_SYSROOT`-less setup is recommended. + + One can engage clang by adjusting PATH to cover same NDK's clang. Just + keep in mind that if you miss it, Configure will try to use gcc... + Also, PATH would need even further adjustment to cover unprefixed, yet + target-specific, ar and ranlib. It's possible that you don't need to + bother, if binutils-multiarch is installed on your Linux system. + + Another option is to create so called "standalone toolchain" tailored + for single specific platform including Android API level, and assign its + location to `ANDROID_NDK_ROOT`. In such case you have to pass matching + target name to Configure and shouldn't use `-D__ANDROID_API__=N`. `PATH` + adjustment becomes simpler, `$ANDROID_NDK_ROOT/bin:$PATH` suffices. + + Running tests (on Linux) + ------------------------ + + This is not actually supported. Notes are meant rather as inspiration. + + Even though build output targets alien system, it's possible to execute + test suite on Linux system by employing qemu-user. The trick is static + linking. Pass -static to Configure, then edit generated Makefile and + remove occurrences of -ldl and -pie flags. You would also need to pick + API version that comes with usable static libraries, 42/2=21 used to + work. Once built, you should be able to + + env EXE_SHELL=qemu- make test + + If you need to pass additional flag to qemu, quotes are your friend, e.g. + + env EXE_SHELL="qemu-mips64el -cpu MIPS64R6-generic" make test diff --git a/crypto/openssl/NOTES-DJGPP.md b/crypto/openssl/NOTES-DJGPP.md new file mode 100644 index 000000000000..0b23c48370b3 --- /dev/null +++ b/crypto/openssl/NOTES-DJGPP.md @@ -0,0 +1,46 @@ +Notes for the DOS platform with DJGPP +===================================== + + OpenSSL has been ported to DJGPP, a Unix look-alike 32-bit run-time + environment for 16-bit DOS, but only with long filename support. + If you wish to compile on native DOS with 8+3 filenames, you will + have to tweak the installation yourself, including renaming files + with illegal or duplicate names. + + You should have a full DJGPP environment installed, including the + latest versions of DJGPP, GCC, BINUTILS, BASH, etc. This package + requires that PERL and the PERL module `Text::Template` also be + installed (see [NOTES-PERL.md](NOTES-PERL.md)). + + All of these can be obtained from the usual DJGPP mirror sites or + directly at . For help on which + files to download, see the DJGPP "ZIP PICKER" page at + . You also need to have + the WATT-32 networking package installed before you try to compile + OpenSSL. This can be obtained from . + The Makefile assumes that the WATT-32 code is in the directory + specified by the environment variable WATT_ROOT. If you have watt-32 + in directory `watt32` under your main DJGPP directory, specify + `WATT_ROOT="/dev/env/DJDIR/watt32"`. + + To compile OpenSSL, start your BASH shell, then configure for DJGPP by + running `./Configure` with appropriate arguments: + + ./Configure no-threads --prefix=/dev/env/DJDIR DJGPP + + And finally fire up `make`. You may run out of DPMI selectors when + running in a DOS box under Windows. If so, just close the BASH + shell, go back to Windows, and restart BASH. Then run `make` again. + + RUN-TIME CAVEAT LECTOR + -------------- + + Quoting FAQ: + + "Cryptographic software needs a source of unpredictable data to work + correctly. Many open source operating systems provide a "randomness + device" (`/dev/urandom` or `/dev/random`) that serves this purpose." + + As of version 0.9.7f DJGPP port checks upon `/dev/urandom$` for a 3rd + party "randomness" DOS driver. One such driver, `NOISE.SYS`, can be + obtained from . diff --git a/crypto/openssl/NOTES-NONSTOP.md b/crypto/openssl/NOTES-NONSTOP.md new file mode 100644 index 000000000000..627843babf32 --- /dev/null +++ b/crypto/openssl/NOTES-NONSTOP.md @@ -0,0 +1,245 @@ +NOTES FOR THE HPE NONSTOP PLATFORM +============================== + +Requirement details +------------------- + +In addition to the requirements and instructions listed +in [INSTALL.md](INSTALL.md), the following are required as well: + + * The TNS/X platform supports hardware randomization. + Specify the `--with-rand-seed=rdcpu` option to the `./Configure` script. + This is recommended but not required. `egd` is supported at 3.0 but cannot + be used if FIPS is selected. + * The TNS/E platform does not support hardware randomization, so + specify the `--with-rand-seed=egd` option to the `./Configure` script. + +About c99 compiler +------------------ + +The c99 compiler is required for building OpenSSL from source. While c11 +may work, it has not been broadly tested. c99 is the only compiler +prerequisite needed to build OpenSSL 3.0 on this platform. You should also +have the FLOSS package installed on your system. The ITUGLIB FLOSS package +is the only FLOSS variant that has been broadly tested. + +Threading Models +---------------- + +OpenSSL can be built using unthreaded, POSIX User Threads (PUT), or Standard +POSIX Threads (SPT). Select the following build configuration for each on +the TNS/X (L-Series) platform: + + * `nonstop-nsx` or default will select an unthreaded build. + * `nonstop-nsx_put` selects the PUT build. + * `nonstop-nsx_64_put` selects the 64 bit file length PUT build. + * `nonstop-nsx_spt_floss` selects the SPT build with FLOSS. FLOSS is + required for SPT builds because of a known hang when using SPT on its own. + +### TNS/E Considerations + +The TNS/E platform is build using the same set of builds specifying `nse` +instead of `nsx` in the set above. + +You cannot build for TNS/E for FIPS, so you must specify the `no-fips` +option to `./Configure`. + +About Prefix and OpenSSLDir +--------------------------- + +Because there are many potential builds that must co-exist on any given +NonStop node, managing the location of your build distribution is crucial. +Keep each destination separate and distinct. Mixing any mode described in +this document can cause application instability. The recommended approach +is to specify the OpenSSL version and threading model in your configuration +options, and keeping your memory and float options consistent, for example: + + * For 1.1 `--prefix=/usr/local-ssl1.1 --openssldir=/usr/local-ssl1.1/ssl` + * For 1.1 PUT `--prefix=/usr/local-ssl1.1_put --openssldir=/usr/local-ssl1.1_put/ssl` + +As of 3.0, the NonStop configurations use the multilib attribute to distinguish +between different models: + + * For 3.0 `--prefix=/usr/local-ssl3.0 --openssldir=/usr/local-ssl3.0/ssl` + +The PUT model is placed in `${prefix}/lib-put` for 32-bit models and +`${prefix}/lib64-put` for 64-bit models. + +Use the `_RLD_LIB_PATH` environment variable in OSS to select the appropriate +directory containing `libcrypto.so` and `libssl.so`. In GUARDIAN, use the +`=_RLD_LIB_PATH` search define to locate the GUARDIAN subvolume where OpenSSL +is installed. + +Float Considerations +-------------------- + +OpenSSL is built using IEEE Float mode by default. If you need a different +IEEE mode, create a new configuration specifying `tfloat-x86-64` (for Tandem +Float) or `nfloat-x86-64` (for Neutral Float). + +Memory Models +------------- + +The current OpenSSL default memory model uses the default platform address +model. If you need a different address model, you must specify the appropriate +c99 options for compile (`CFLAGS`) and linkers (`LDFLAGS`). + +Cross Compiling on Windows +-------------------------- + +To configure and compile OpenSSL, you will need to set up a Cygwin environment. +The Cygwin tools should include bash, make, and any other normal tools required +for building programs. + +Your `PATH` must include the bin directory for the c99 cross-compiler, as in: + + export PATH=/cygdrive/c/Program\ Files\ \(x86\)/HPE\ NonStop/L16.05/usr/bin:$PATH + +This should be set before Configure is run. For the c99 cross-compiler to work +correctly, you also need the `COMP_ROOT` set, as in: + + export COMP_ROOT="C:\Program Files (x86)\HPE NonStop\L16.05" + +`COMP_ROOT` needs to be in Windows form. + +`Configure` must specify the `no-makedepend` option otherwise errors will +result when running the build because the c99 cross-compiler does not support +the `gcc -MT` option. An example of a `Configure` command to be run from the +OpenSSL directory is: + + ./Configure nonstop-nsx_64 no-makedepend --with-rand-seed=rdcpu + +Do not forget to include any OpenSSL cross-compiling prefix and certificate +options when creating your libraries. + +The OpenSSL test suite will not run on your workstation. In order to verify the +build, you will need to perform the build and test steps in OSS in your NonStop +server. You can also build under gcc and run the test suite for Windows but that +is not equivalent. + +**Note:** In the event that you are attempting a FIPS-compliant cross-compile, +be aware that signatures may not match between builds done under OSS and under +cross-compiles as the compilers do not necessarily generate identical objects. +Anything and everything to do with FIPS is outside the scope of this document. +Refer to the FIPS security policy for more information. + +The following build configurations have been successfully attempted at one +point or another. If you are successful in your cross-compile efforts, please +update this list: + +- nonstop-nsx_64 +- nonstop-nsx_64_put + +**Note:** Cross-compile builds for TNS/E have not been attempted, but should +follow the same considerations as for TNS/X above. SPT builds generally require +FLOSS, which is not available for workstation builds. As a result, SPT builds +of OpenSSL cannot be cross-compiled. + +Also see the NSDEE discussion below for more historical information. + +Cross Compiling with NSDEE +-------------------------- + +**Note:** None of these builds have been tested by the platform maintainer and +are supplied for historical value. Please submit a Pull Request to OpenSSL +should these need to be adjusted. + +If you are attempting to build OpenSSL with NSDEE, you will need to specify +the following variables. The following set of compiler defines are required: + + # COMP_ROOT must be a full path for the build system (e.g. windows) + COMP_ROOT=$(cygpath -w /path/to/comp_root) + # CC must be executable by your shell + CC=/path/to/c99 + +### Optional Build Variables + + DBGFLAG="--debug" + CIPHENABLES="enable-ssl3 enable-ssl3-method enable-weak-ssl-ciphers enable-rc4" + +### Internal Known TNS/X to TNS/E Cross Compile Variables + +The following definition is required if you are building on TNS/X for TNS/E +and have access to a TNS/E machine on your EXPAND network - with an example +node named `\CS3`: + + SYSTEMLIBS="-L/E/cs3/usr/local/lib" + +Version Procedure (VPROC) Considerations +---------------------------------------- + +If you require a VPROC entry for platform version identification, use the +following variables: + +### For Itanium + + OPENSSL_VPROC_PREFIX=T0085H06 + +### For x86 + + OPENSSL_VPROC_PREFIX=T0085L01 + +### Common Definition + + export OPENSSL_VPROC=${OPENSSL_VPROC_PREFIX}_$( + . VERSION.dat + if [ -n "$PRE_RELEASE_TAG" ]; then + PRE_RELEASE_TAG="-$PRE_RELEASE_TAG" + fi + if [ -n "$BUILD_METADATA" ]; then + BUILD_METADATA="+$BUILD_METADATA" + fi + echo "$MAJOR.$MINOR.$PATCH$PRE_RELEASE_TAG$BUILD_METADATA" |\ + sed -e 's/[-.+]/_/g' + ) + +Example Configure Targets +------------------------- + +For OSS targets, the main DLL names will be `libssl.so` and `libcrypto.so`. +For GUARDIAN targets, DLL names will be `ssl` and `crypto`. The following +assumes that your PWD is set according to your installation standards. + + ./Configure nonstop-nsx --prefix=${PWD} \ + --openssldir=${PWD}/ssl no-threads \ + --with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nsx_g --prefix=${PWD} \ + --openssldir=${PWD}/ssl no-threads \ + --with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nsx_put --prefix=${PWD} \ + --openssldir=${PWD}/ssl threads "-D_REENTRANT" \ + --with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nsx_spt_floss --prefix=${PWD} \ + --openssldir=${PWD}/ssl threads "-D_REENTRANT" \ + --with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nsx_64 --prefix=${PWD} \ + --openssldir=${PWD}/ssl no-threads \ + --with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nsx_64_put --prefix=${PWD} \ + --openssldir=${PWD}/ssl threads "-D_REENTRANT" \ + --with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nsx_g_tandem --prefix=${PWD} \ + --openssldir=${PWD}/ssl no-threads \ + --with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + + ./Configure nonstop-nse --prefix=${PWD} \ + --openssldir=${PWD}/ssl no-threads \ + --with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nse_g --prefix=${PWD} \ + --openssldir=${PWD}/ssl no-threads \ + --with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nse_put --prefix=${PWD} \ + --openssldir=${PWD}/ssl threads "-D_REENTRANT" \ + --with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nse_spt_floss --prefix=${PWD} \ + --openssldir=${PWD}/ssl threads "-D_REENTRANT" \ + --with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nse_64 --prefix=${PWD} \ + --openssldir=${PWD}/ssl no-threads \ + --with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nse_64_put --prefix=${PWD} \ + --openssldir=${PWD}/ssl threads "-D_REENTRANT" + --with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} + ./Configure nonstop-nse_g_tandem --prefix=${PWD} \ + --openssldir=${PWD}/ssl no-threads \ + --with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS} diff --git a/crypto/openssl/NOTES-PERL.md b/crypto/openssl/NOTES-PERL.md new file mode 100644 index 000000000000..b7fc83fc7d75 --- /dev/null +++ b/crypto/openssl/NOTES-PERL.md @@ -0,0 +1,127 @@ +Notes on Perl +============= + + - [General Notes](#general-notes) + - [Perl on Windows](#perl-on-windows) + - [Perl on VMS](#perl-on-vms) + - [Perl on NonStop](#perl-on-nonstop) + - [Required Perl modules](#required-perl-modules) + - [Notes on installing a Perl module](#notes-on-installing-a-perl-module]) + +General Notes +------------- + +For our scripts, we rely quite a bit on Perl, and increasingly on +some core Perl modules. These Perl modules are part of the Perl +source, so if you build Perl on your own, you should be set. + +However, if you install Perl as binary packages, the outcome might +differ, and you may have to check that you do get the core modules +installed properly. We do not claim to know them all, but experience +has told us the following: + + - on Linux distributions based on Debian, the package `perl` will + install the core Perl modules as well, so you will be fine. + - on Linux distributions based on RPMs, you will need to install + `perl-core` rather than just `perl`. + +You MUST have at least Perl version 5.10.0 installed. This minimum +requirement is due to our use of regexp backslash sequence \R among +other features that didn't exist in core Perl before that version. + +Perl on Windows +--------------- + +There are a number of build targets that can be viewed as "Windows". +Indeed, there are `VC-*` configs targeting VisualStudio C, as well as +MinGW and Cygwin. The key recommendation is to use a Perl installation +that matches the build environment. For example, if you will build +on Cygwin be sure to use the Cygwin package manager to install Perl. +For MSYS builds use the MSYS provided Perl. +For VC-* builds we recommend Strawberry Perl, from . +An alternative is ActiveState Perl, from +for which you may need to explicitly select the Perl module Win32/Console.pm +available via . + +Perl on VMS +----------- + +You will need to install Perl separately. One way to do so is to +download the source from , unpacking it, reading +`README-VMS.md` and follow the instructions. Another way is to download a +`.PCSI` file from and install it using the +POLYCENTER install tool. + +Perl on NonStop +--------------- + +Perl is installed on HPE NonStop platforms as part of the Scripting Languages +package T1203PAX file. The package is shipped as part of a NonStop RVU +(Release Version Updates) package. Individual SPRs (Software Product Release) +representing fixes can be obtained from the Scout website at +. Follow the appropriate set of installation +instructions for your operating system release as described in the +Script Language User Guide available from the NonStop Technical Library. + +Required Perl modules +--------------------- + +We do our best to limit ourselves to core Perl modules to keep the +requirements down. There are just a few exceptions. + + * Text::Template this is required *for building* + + To avoid unnecessary initial hurdles, we include a copy of this module + in the source. It will work as a fallback if the module isn't already + installed. + + * `Test::More` this is required *for testing* + + We require the minimum version to be 0.96, which appeared in Perl 5.13.4, + because that version was the first to have all the features we're using. + This module is required for testing only! If you don't plan on running + the tests, you don't need to bother with this one. + +Notes on installing a Perl module +--------------------------------- + +There are a number of ways to install a perl module. In all +descriptions below, `Text::Template` will serve as an example. + +1. for Linux users, the easiest is to install with the use of your + favorite package manager. Usually, all you need to do is search + for the module name and to install the package that comes up. + + On Debian based Linux distributions, it would go like this: + + $ apt-cache search Text::Template + ... + libtext-template-perl - perl module to process text templates + $ sudo apt-get install libtext-template-perl + + Perl modules in Debian based distributions use package names like + the name of the module in question, with "lib" prepended and + "-perl" appended. + +2. Install using CPAN. This is very easy, but usually requires root + access: + + $ cpan -i Text::Template + + Note that this runs all the tests that the module to be installed + comes with. This is usually a smooth operation, but there are + platforms where a failure is indicated even though the actual tests + were successful. Should that happen, you can force an + installation regardless (that should be safe since you've already + seen the tests succeed!): + + $ cpan -f -i Text::Template + + Note: on VMS, you must quote any argument that contains upper case + characters, so the lines above would be: + + $ cpan -i "Text::Template" + + and: + + $ cpan -f -i "Text::Template" diff --git a/crypto/openssl/NOTES.UNIX b/crypto/openssl/NOTES-UNIX.md similarity index 66% rename from crypto/openssl/NOTES.UNIX rename to crypto/openssl/NOTES-UNIX.md index 6c291cbab6fd..293793b60559 100644 --- a/crypto/openssl/NOTES.UNIX +++ b/crypto/openssl/NOTES-UNIX.md @@ -1,9 +1,8 @@ +Notes for UNIX-like platforms +============================= - NOTES FOR UNIX LIKE PLATFORMS - ============================= - - For Unix/POSIX runtime systems on Windows, please see NOTES.WIN. - + For Unix/POSIX runtime systems on Windows, + please see the [Notes for Windows platforms](NOTES-WINDOWS.md). OpenSSL uses the compiler to link programs and shared libraries --------------------------------------------------------------- @@ -13,21 +12,20 @@ objects. Because of this, any linking option that's given to the configuration scripts MUST be in a form that the compiler can accept. This varies between systems, where some have compilers that accept - linker flags directly, while others take them in '-Wl,' form. You need + linker flags directly, while others take them in `-Wl,` form. You need to read your compiler documentation to figure out what is acceptable, - and ld(1) to figure out what linker options are available. - + and `ld(1)` to figure out what linker options are available. Shared libraries and installation in non-default locations ---------------------------------------------------------- Every Unix system has its own set of default locations for shared - libraries, such as /lib, /usr/lib or possibly /usr/local/lib. If + libraries, such as `/lib`, `/usr/lib` or possibly `/usr/local/lib`. If libraries are installed in non-default locations, dynamically linked binaries will not find them and therefore fail to run, unless they get a bit of help from a defined runtime shared library search path. - For OpenSSL's application (the 'openssl' command), our configuration + For OpenSSL's application (the `openssl` command), our configuration scripts do NOT generally set the runtime shared library search path for you. It's therefore advisable to set it explicitly when configuring, unless the libraries are to be installed in directories that you know @@ -42,15 +40,16 @@ Possible options to set the runtime shared library search path include the following: - -Wl,-rpath,/whatever/path # Linux, *BSD, etc. - -R /whatever/path # Solaris - -Wl,-R,/whatever/path # AIX (-bsvr4 is passed internally) - -Wl,+b,/whatever/path # HP-UX - -rpath /whatever/path # Tru64, IRIX + -Wl,-rpath,/whatever/path # Linux, *BSD, etc. + -R /whatever/path # Solaris + -Wl,-R,/whatever/path # AIX (-bsvr4 is passed internally) + -Wl,+b,/whatever/path # HP-UX + -rpath /whatever/path # Tru64, IRIX OpenSSL's configuration scripts recognise all these options and pass them to the Makefile that they build. (In fact, all arguments starting - with '-Wl,' are recognised as linker options.) + with `-Wl,` are recognised as linker options.) + Please note that 'l' in '-Wl' is lowercase L and not 1. Please do not use verbatim directories in your runtime shared library search path! Some OpenSSL config targets add an extra directory level @@ -59,41 +58,40 @@ used with the runtime shared library search path options, as shown in this example: - $ ./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl \ + $ ./Configure --prefix=/usr/local/ssl --openssldir=/usr/local/ssl \ '-Wl,-rpath,$(LIBRPATH)' On modern ELF based systems, there are two runtime search paths tags to - consider, DT_RPATH and DT_RUNPATH. Shared objects are searched for in + consider, `DT_RPATH` and `DT_RUNPATH`. Shared objects are searched for in this order: - 1. Using directories specified in DT_RPATH, unless DT_RUNPATH is - also set. - 2. Using the environment variable LD_LIBRARY_PATH - 3. Using directories specified in DT_RUNPATH. - 4. Using system shared object caches and default directories. + 1. Using directories specified in DT_RPATH, unless DT_RUNPATH is also set. + 2. Using the environment variable LD_LIBRARY_PATH + 3. Using directories specified in DT_RUNPATH. + 4. Using system shared object caches and default directories. - This means that the values in the environment variable LD_LIBRARY_PATH - won't matter if the library is found in the paths given by DT_RPATH - (and DT_RUNPATH isn't set). + This means that the values in the environment variable `LD_LIBRARY_PATH` + won't matter if the library is found in the paths given by `DT_RPATH` + (and `DT_RUNPATH` isn't set). - Exactly which of DT_RPATH or DT_RUNPATH is set by default appears to + Exactly which of `DT_RPATH` or `DT_RUNPATH` is set by default appears to depend on the system. For example, according to documentation, - DT_RPATH appears to be deprecated on Solaris in favor of DT_RUNPATH, - while on Debian GNU/Linux, either can be set, and DT_RPATH is the + `DT_RPATH` appears to be deprecated on Solaris in favor of `DT_RUNPATH`, + while on Debian GNU/Linux, either can be set, and `DT_RPATH` is the default at the time of writing. How to choose which runtime search path tag is to be set depends on your system, please refer to ld(1) for the exact information on your - system. As an example, the way to ensure the DT_RUNPATH is set on + system. As an example, the way to ensure the `DT_RUNPATH` is set on Debian GNU/Linux systems rather than DT_RPATH is to tell the linker to set new dtags, like this: - $ ./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl \ + $ ./Configure --prefix=/usr/local/ssl --openssldir=/usr/local/ssl \ '-Wl,--enable-new-dtags,-rpath,$(LIBRPATH)' It might be worth noting that some/most ELF systems implement support for runtime search path relative to the directory containing current - executable, by interpreting $ORIGIN along with some other internal + executable, by interpreting `$ORIGIN` along with some other internal variables. Consult your system documentation. Linking your application @@ -104,7 +102,7 @@ The OpenSSL config options mentioned above might or might not have bearing on linking of the target application. "Might" means that under some circumstances it would be sufficient to link with OpenSSL shared library - "naturally", i.e. with -L/whatever/path -lssl -lcrypto. But there are + "naturally", i.e. with `-L/whatever/path -lssl -lcrypto`. But there are also cases when you'd have to explicitly specify runtime search path when linking your application. Consult your system documentation and use above section as inspiration... @@ -114,4 +112,4 @@ for shared libraries first and tend to remain "blind" to static OpenSSL libraries. Referring to system documentation would suffice, if not for a corner case. On AIX static libraries (in shared build) are named - differently, add _a suffix to link with them, e.g. -lcrypto_a. + differently, add `_a` suffix to link with them, e.g. `-lcrypto_a`. diff --git a/crypto/openssl/NOTES-VALGRIND.md b/crypto/openssl/NOTES-VALGRIND.md new file mode 100644 index 000000000000..2700324efa36 --- /dev/null +++ b/crypto/openssl/NOTES-VALGRIND.md @@ -0,0 +1,72 @@ +Notes on Valgrind +================= + +Valgrind is a test harness that includes many tools such as memcheck, +which is commonly used to check for memory leaks, etc. The default tool +run by Valgrind is memcheck. There are other tools available, but this +will focus on memcheck. + +Valgrind runs programs in a virtual machine, this means OpenSSL unit +tests run under Valgrind will take longer than normal. + +Requirements +------------ + +1. Platform supported by Valgrind + See +2. Valgrind installed on the platform + See +3. OpenSSL compiled + See [INSTALL.md](INSTALL.md) + +Running Tests +------------- + +Test behavior can be modified by adjusting environment variables. + +`EXE_SHELL` + +This variable is used to specify the shell used to execute OpenSSL test +programs. The default wrapper (`util/wrap.pl`) initializes the environment +to allow programs to find shared libraries. The variable can be modified +to specify a different executable environment. + + EXE_SHELL=\ + "`/bin/pwd`/util/wrap.pl valgrind --error-exitcode=1 --leak-check=full -q" + +This will start up Valgrind with the default checker (`memcheck`). +The `--error-exitcode=1` option specifies that Valgrind should exit with an +error code of 1 when memory leaks occur. +The `--leak-check=full` option specifies extensive memory checking. +The `-q` option prints only error messages. +Additional Valgrind options may be added to the `EXE_SHELL` variable. + +`OPENSSL_ia32cap` + +This variable controls the processor-specific code on Intel processors. +By default, OpenSSL will attempt to figure out the capabilities of a +processor, and use it to its fullest capability. This variable can be +used to control what capabilities OpenSSL uses. + +As of valgrind-3.15.0 on Linux/x86_64, instructions up to AVX2 are +supported. Setting the following disables instructions beyond AVX2: + +`OPENSSL_ia32cap=":0"` + +This variable may need to be set to something different based on the +processor and Valgrind version you are running tests on. More information +may be found in [doc/man3/OPENSSL_ia32cap.pod](doc/man3/OPENSSL_ia32cap.pod). + +Additional variables (such as `VERBOSE` and `TESTS`) are described in the +file [test/README.md](test/README.md). + +Example command line: + + $ make test EXE_SHELL="`/bin/pwd`/util/wrap.pl valgrind --error-exitcode=1 \ + --leak-check=full -q" OPENSSL_ia32cap=":0" + +If an error occurs, you can then run the specific test via the `TESTS` variable +with the `VERBOSE` or `VF` or `VFP` options to gather additional information. + + $ make test VERBOSE=1 TESTS=test_test EXE_SHELL="`/bin/pwd`/util/wrap.pl \ + valgrind --error-exitcode=1 --leak-check=full -q" OPENSSL_ia32cap=":0" diff --git a/crypto/openssl/NOTES-VMS.md b/crypto/openssl/NOTES-VMS.md new file mode 100644 index 000000000000..e27f3d682a2a --- /dev/null +++ b/crypto/openssl/NOTES-VMS.md @@ -0,0 +1,115 @@ +Notes for the OpenVMS platform +============================== + + - [Requirement details](#requirement-details) + - [About ANSI C compiler](#about-ansi-c-compiler) + - [About ODS-5 directory names and Perl](#about-ods-5-directory-names-and-perl) + - [About MMS and DCL](#about-mms-and-dcl) + - [About debugging](#about-debugging) + - [Checking the distribution](#checking-the-distribution) + +Requirement details +------------------- + +In addition to the requirements and instructions listed +in [INSTALL.md](INSTALL.md), this are required as well: + + * At least ODS-5 disk organization for source and build. + Installation can be done on any existing disk organization. + +About ANSI C compiler +--------------------- + +An ANSI C compiled is needed among other things. This means that +VAX C is not and will not be supported. + +We have only tested with DEC C (aka HP VMS C / VSI C) and require +version 7.1 or later. Compiling with a different ANSI C compiler may +require some work. + +Please avoid using C RTL feature logical names `DECC$*` when building +and testing OpenSSL. Most of all, they can be disruptive when +running the tests, as they affect the Perl interpreter. + +About ODS-5 directory names and Perl +------------------------------------ + +It seems that the perl function canonpath() in the `File::Spec` module +doesn't treat file specifications where the last directory name +contains periods very well. Unfortunately, some versions of VMS tar +will keep the periods in the OpenSSL source directory instead of +converting them to underscore, thereby leaving your source in +something like `[.openssl-1^.1^.0]`. This will lead to issues when +configuring and building OpenSSL. + +We have no replacement for Perl's canonpath(), so the best workaround +for now is to rename the OpenSSL source directory, as follows (please +adjust for the actual source directory name you have): + + $ rename openssl-1^.1^.0.DIR openssl-1_1_0.DIR + +About MMS and DCL +----------------- + +MMS has certain limitations when it comes to line length, and DCL has +certain limitations when it comes to total command length. We do +what we can to mitigate, but there is the possibility that it's not +enough. Should you run into issues, a very simple solution is to set +yourself up a few logical names for the directory trees you're going +to use. + +About debugging +--------------- + +If you build for debugging, the default on VMS is that image +activation starts the debugger automatically, giving you a debug +prompt. Unfortunately, this disrupts all other uses, such as running +test programs in the test framework. + +Generally speaking, if you build for debugging, only use the programs +directly for debugging. Do not try to use them from a script, such +as running the test suite. + +### The following is not available on Alpha + +As a compromise, we're turning off the flag that makes the debugger +start automatically. If there is a program that you need to debug, +you need to turn that flag back on first, for example: + + $ set image /flag=call_debug [.test]evp_test.exe + +Then just run it and you will find yourself in a debugging session. +When done, we recommend that you turn that flag back off: + + $ set image /flag=nocall_debug [.test]evp_test.exe + +Checking the distribution +------------------------- + +There have been reports of places where the distribution didn't quite +get through, for example if you've copied the tree from a NFS-mounted +Unix mount point. + +The easiest way to check if everything got through as it should is to +check that this file exists: + + [.include.openssl]configuration^.h.in + +The best way to get a correct distribution is to download the gzipped +tar file from ftp://ftp.openssl.org/source/, use `GZIP -d` to uncompress +it and `VMSTAR` to unpack the resulting tar file. + +Gzip and VMSTAR are available here: + + + +Should you need it, you can find UnZip for VMS here: + + + + How the value of 'arch' is determined + ------------------------------------- + + 'arch' is mentioned in INSTALL. It's value is determined like this: + + arch = f$edit( f$getsyi( "arch_name"), "upcase") diff --git a/crypto/openssl/NOTES-WINDOWS.md b/crypto/openssl/NOTES-WINDOWS.md new file mode 100644 index 000000000000..b1d6c4fe13bb --- /dev/null +++ b/crypto/openssl/NOTES-WINDOWS.md @@ -0,0 +1,265 @@ +Notes for Windows platforms +=========================== + + - [Native builds using Visual C++](#native-builds-using-visual-c++) + - [Native builds using Embarcadero C++Builder]( + #native-builds-using-embarcadero-c++-builder) + - [Native builds using MinGW](#native-builds-using-mingw) + - [Linking native applications](#linking-native-applications) + - [Hosted builds using Cygwin](#hosted-builds-using-cygwin) + +There are various options to build and run OpenSSL on the Windows platforms. + +"Native" OpenSSL uses the Windows APIs directly at run time. +To build a native OpenSSL you can either use: + + Microsoft Visual C++ (MSVC) C compiler on the command line +or + Embarcadero C++Builder +or + MinGW cross compiler + run on the GNU-like development environment MSYS2 + or run on Linux or Cygwin + +"Hosted" OpenSSL relies on an external POSIX compatibility layer +for building (using GNU/Unix shell, compiler, and tools) and at run time. +For this option you can use Cygwin. + +Native builds using Visual C++ +============================== + +The native builds using Visual C++ have a `VC-*` prefix. + +Requirement details +------------------- + +In addition to the requirements and instructions listed in `INSTALL.md`, +these are required as well: + +### Perl + +We recommend Strawberry Perl, available from +Please read NOTES.PERL for more information, including the use of CPAN. +An alternative is ActiveState Perl, +for which you may need to explicitly build the Perl module Win32/Console.pm +via and then download it. + +### Microsoft Visual C compiler. + +Since these are proprietary and ever-changing we cannot test them all. +Older versions may not work. Use a recent version wherever possible. + +### Netwide Assembler (NASM) + +NASM is the only supported assembler. It is available from . + +Quick start +----------- + + 1. Install Perl + + 2. Install NASM + + 3. Make sure both Perl and NASM are on your %PATH% + + 4. Use Visual Studio Developer Command Prompt with administrative privileges, + choosing one of its variants depending on the intended architecture. + Or run `cmd` and execute `vcvarsall.bat` with one of the options `x86`, + `x86_amd64`, `x86_arm`, `x86_arm64`, `amd64`, `amd64_x86`, `amd64_arm`, + or `amd64_arm64`. + This sets up the environment variables needed for `nmake.exe`, `cl.exe`, + etc. + See also + + + 5. From the root of the OpenSSL source directory enter + - `perl Configure VC-WIN32` if you want 32-bit OpenSSL or + - `perl Configure VC-WIN64A` if you want 64-bit OpenSSL or + - `perl Configure VC-WIN64-ARM` if you want Windows on Arm (win-arm64) + OpenSSL or + - `perl Configure` to let Configure figure out the platform + + 6. `nmake` + + 7. `nmake test` + + 8. `nmake install` + +For the full installation instructions, or if anything goes wrong at any stage, +check the INSTALL.md file. + +Installation directories +------------------------ + +The default installation directories are derived from environment +variables. + +For VC-WIN32, the following defaults are use: + + PREFIX: %ProgramFiles(x86)%\OpenSSL + OPENSSLDIR: %CommonProgramFiles(x86)%\SSL + +For VC-WIN64, the following defaults are use: + + PREFIX: %ProgramW6432%\OpenSSL + OPENSSLDIR: %CommonProgramW6432%\SSL + +Should those environment variables not exist (on a pure Win32 +installation for examples), these fallbacks are used: + + PREFIX: %ProgramFiles%\OpenSSL + OPENSSLDIR: %CommonProgramFiles%\SSL + +ALSO NOTE that those directories are usually write protected, even if +your account is in the Administrators group. To work around that, +start the command prompt by right-clicking on it and choosing "Run as +Administrator" before running `nmake install`. The other solution +is, of course, to choose a different set of directories by using +`--prefix` and `--openssldir` when configuring. + +Special notes for Universal Windows Platform builds, aka `VC-*-UWP` +------------------------------------------------------------------- + + - UWP targets only support building the static and dynamic libraries. + + - You should define the platform type to `uwp` and the target arch via + `vcvarsall.bat` before you compile. For example, if you want to build + `arm64` builds, you should run `vcvarsall.bat x86_arm64 uwp`. + +Native builds using Embarcadero C++Builder +========================================= + +This toolchain (a descendant of Turbo/Borland C++) is an alternative to MSVC. +OpenSSL currently includes an experimental 32-bit configuration targeting the +Clang-based compiler (`bcc32c.exe`) in v10.3.3 Community Edition. + + + 1. Install Perl. + + 2. Open the RAD Studio Command Prompt. + + 3. Go to the root of the OpenSSL source directory and run: + `perl Configure BC-32 --prefix=%CD%` + + 4. `make -N` + + 5. `make -N test` + + 6. Build your program against this OpenSSL: + * Set your include search path to the "include" subdirectory of OpenSSL. + * Set your library search path to the OpenSSL source directory. + +Note that this is very experimental. Support for 64-bit and other Configure +options is still pending. + +Native builds using MinGW +========================= + +MinGW offers an alternative way to build native OpenSSL, by cross compilation. + + * Usually the build is done on Windows in a GNU-like environment called MSYS2. + + MSYS2 provides GNU tools, a Unix-like command prompt, + and a UNIX compatibility layer for applications. + However, in this context it is only used for building OpenSSL. + The resulting OpenSSL does not rely on MSYS2 to run and is fully native. + + Requirement details + + - MSYS2 shell, from + + - Perl, at least version 5.10.0, which usually comes pre-installed with MSYS2 + + - make, installed using `pacman -S make` into the MSYS2 environment + + - MinGW[64] compiler: `mingw-w64-i686-gcc` and/or `mingw-w64-x86_64-gcc`. + These compilers must be on your MSYS2 $PATH. + A common error is to not have these on your $PATH. + The MSYS2 version of gcc will not work correctly here. + + In the MSYS2 shell do the configuration depending on the target architecture: + + ./Configure mingw ... + + or + + ./Configure mingw64 ... + + or + + ./Configure ... + + for the default architecture. + + Apart from that, follow the Unix / Linux instructions in `INSTALL.md`. + + * It is also possible to build mingw[64] on Linux or Cygwin. + + In this case configure with the corresponding `--cross-compile-prefix=` + option. For example + + ./Configure mingw --cross-compile-prefix=i686-w64-mingw32- ... + + or + + ./Configure mingw64 --cross-compile-prefix=x86_64-w64-mingw32- ... + + This requires that you've installed the necessary add-on packages for + mingw[64] cross compilation. + +Linking native applications +=========================== + +This section applies to all native builds. + +If you link with static OpenSSL libraries then you're expected to +additionally link your application with `WS2_32.LIB`, `GDI32.LIB`, +`ADVAPI32.LIB`, `CRYPT32.LIB` and `USER32.LIB`. Those developing +non-interactive service applications might feel concerned about +linking with `GDI32.LIB` and `USER32.LIB`, as they are justly associated +with interactive desktop, which is not available to service +processes. The toolkit is designed to detect in which context it's +currently executed, GUI, console app or service, and act accordingly, +namely whether or not to actually make GUI calls. Additionally those +who wish to `/DELAYLOAD:GDI32.DLL` and `/DELAYLOAD:USER32.DLL` and +actually keep them off service process should consider implementing +and exporting from .exe image in question own `_OPENSSL_isservice` not +relying on `USER32.DLL`. E.g., on Windows Vista and later you could: + + __declspec(dllexport) __cdecl BOOL _OPENSSL_isservice(void) + { + DWORD sess; + + if (ProcessIdToSessionId(GetCurrentProcessId(), &sess)) + return sess == 0; + return FALSE; + } + +If you link with OpenSSL .DLLs, then you're expected to include into +your application code a small "shim" snippet, which provides +the glue between the OpenSSL BIO layer and your compiler run-time. +See also the OPENSSL_Applink manual page. + +Hosted builds using Cygwin +========================== + +Cygwin implements a POSIX/Unix runtime system (`cygwin1.dll`) on top of the +Windows subsystem and provides a Bash shell and GNU tools environment. +Consequently, a build of OpenSSL with Cygwin is virtually identical to the +Unix procedure. + +To build OpenSSL using Cygwin, you need to: + + * Install Cygwin, see + + * Install Cygwin Perl, at least version 5.10.0 + and ensure it is in the $PATH + + * Run the Cygwin Bash shell + +Apart from that, follow the Unix / Linux instructions in INSTALL.md. + +NOTE: `make test` and normal file operations may fail in directories +mounted as text (i.e. `mount -t c:\somewhere /home`) due to Cygwin +stripping of carriage returns. To avoid this ensure that a binary +mount is used, e.g. `mount -b c:\somewhere /home`. diff --git a/crypto/openssl/NOTES.PERL b/crypto/openssl/NOTES.PERL deleted file mode 100644 index 201b14386729..000000000000 --- a/crypto/openssl/NOTES.PERL +++ /dev/null @@ -1,119 +0,0 @@ - TOC - === - - - Notes on Perl - - Notes on Perl on Windows - - Notes on Perl modules we use - - Notes on installing a perl module - - Notes on Perl - ------------- - - For our scripts, we rely quite a bit on Perl, and increasingly on - some core Perl modules. These Perl modules are part of the Perl - source, so if you build Perl on your own, you should be set. - - However, if you install Perl as binary packages, the outcome might - differ, and you may have to check that you do get the core modules - installed properly. We do not claim to know them all, but experience - has told us the following: - - - on Linux distributions based on Debian, the package 'perl' will - install the core Perl modules as well, so you will be fine. - - on Linux distributions based on RPMs, you will need to install - 'perl-core' rather than just 'perl'. - - You MUST have at least Perl version 5.10.0 installed. This minimum - requirement is due to our use of regexp backslash sequence \R among - other features that didn't exist in core Perl before that version. - - Notes on Perl on Windows - ------------------------ - - There are a number of build targets that can be viewed as "Windows". - Indeed, there are VC-* configs targeting VisualStudio C, as well as - MinGW and Cygwin. The key recommendation is to use "matching" Perl, - one that matches build environment. For example, if you will build - on Cygwin be sure to use the Cygwin package manager to install Perl. - For MSYS builds use the MSYS provided Perl. For VC-* builds we - recommend ActiveState Perl, available from - http://www.activestate.com/ActivePerl. - - Notes on Perl on VMS - -------------------- - - You will need to install Perl separately. One way to do so is to - download the source from http://perl.org/, unpacking it, reading - README.vms and follow the instructions. Another way is to download a - .PCSI file from http://www.vmsperl.com/ and install it using the - POLYCENTER install tool. - - Notes on Perl modules we use - ---------------------------- - - We make increasing use of Perl modules, and do our best to limit - ourselves to core Perl modules to keep the requirements down. There - are just a few exceptions: - - Test::More We require the minimum version to be 0.96, which - appeared in Perl 5.13.4, because that version was - the first to have all the features we're using. - This module is required for testing only! If you - don't plan on running the tests, you don't need to - bother with this one. - - Text::Template This module is not part of the core Perl modules. - As a matter of fact, the core Perl modules do not - include any templating module to date. - This module is absolutely needed, configuration - depends on it. - - To avoid unnecessary initial hurdles, we have bundled a copy of the - following modules in our source. They will work as fallbacks if - these modules aren't already installed on the system. - - Text::Template - - Notes on installing a perl module - --------------------------------- - - There are a number of ways to install a perl module. In all - descriptions below, Text::Template will serve as an example. - - 1. for Linux users, the easiest is to install with the use of your - favorite package manager. Usually, all you need to do is search - for the module name and to install the package that comes up. - - On Debian based Linux distributions, it would go like this: - - $ apt-cache search Text::Template - ... - libtext-template-perl - perl module to process text templates - $ sudo apt-get install libtext-template-perl - - Perl modules in Debian based distributions use package names like - the name of the module in question, with "lib" prepended and - "-perl" appended. - - 2. Install using CPAN. This is very easy, but usually requires root - access: - - $ cpan -i Text::Template - - Note that this runs all the tests that the module to be installed - comes with. This is usually a smooth operation, but there are - platforms where a failure is indicated even though the actual tests - were successful. Should that happen, you can force an - installation regardless (that should be safe since you've already - seen the tests succeed!): - - $ cpan -f -i Text::Template - - Note: on VMS, you must quote any argument that contains uppercase - characters, so the lines above would be: - - $ cpan -i "Text::Template" - - and: - - $ cpan -f -i "Text::Template" diff --git a/crypto/openssl/README b/crypto/openssl/README deleted file mode 100644 index b2f806be3a44..000000000000 --- a/crypto/openssl/README +++ /dev/null @@ -1,93 +0,0 @@ - - OpenSSL 1.1.1t 7 Feb 2023 - - Copyright (c) 1998-2022 The OpenSSL Project - Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson - All rights reserved. - - DESCRIPTION - ----------- - - The OpenSSL Project is a collaborative effort to develop a robust, - commercial-grade, fully featured, and Open Source toolkit implementing the - Transport Layer Security (TLS) protocols (including SSLv3) as well as a - full-strength general purpose cryptographic library. - - OpenSSL is descended from the SSLeay library developed by Eric A. Young - and Tim J. Hudson. The OpenSSL toolkit is licensed under a dual-license (the - OpenSSL license plus the SSLeay license), which means that you are free to - get and use it for commercial and non-commercial purposes as long as you - fulfill the conditions of both licenses. - - OVERVIEW - -------- - - The OpenSSL toolkit includes: - - libssl (with platform specific naming): - Provides the client and server-side implementations for SSLv3 and TLS. - - libcrypto (with platform specific naming): - Provides general cryptographic and X.509 support needed by SSL/TLS but - not logically part of it. - - openssl: - A command line tool that can be used for: - Creation of key parameters - Creation of X.509 certificates, CSRs and CRLs - Calculation of message digests - Encryption and decryption - SSL/TLS client and server tests - Handling of S/MIME signed or encrypted mail - And more... - - INSTALLATION - ------------ - - See the appropriate file: - INSTALL Linux, Unix, Windows, OpenVMS, ... - NOTES.* INSTALL addendums for different platforms - - SUPPORT - ------- - - See the OpenSSL website www.openssl.org for details on how to obtain - commercial technical support. Free community support is available through the - openssl-users email list (see - https://www.openssl.org/community/mailinglists.html for further details). - - If you have any problems with OpenSSL then please take the following steps - first: - - - Download the latest version from the repository - to see if the problem has already been addressed - - Configure with no-asm - - Remove compiler optimization flags - - If you wish to report a bug then please include the following information - and create an issue on GitHub: - - - OpenSSL version: output of 'openssl version -a' - - Configuration data: output of 'perl configdata.pm --dump' - - OS Name, Version, Hardware platform - - Compiler Details (name, version) - - Application Details (name, version) - - Problem Description (steps that will reproduce the problem, if known) - - Stack Traceback (if the application dumps core) - - Just because something doesn't work the way you expect does not mean it - is necessarily a bug in OpenSSL. Use the openssl-users email list for this type - of query. - - HOW TO CONTRIBUTE TO OpenSSL - ---------------------------- - - See CONTRIBUTING - - LEGALITIES - ---------- - - A number of nations restrict the use or export of cryptography. If you - are potentially subject to such restrictions you should seek competent - professional legal advice before attempting to develop or distribute - cryptographic code. diff --git a/crypto/openssl/README-ENGINES.md b/crypto/openssl/README-ENGINES.md new file mode 100644 index 000000000000..9874276f1320 --- /dev/null +++ b/crypto/openssl/README-ENGINES.md @@ -0,0 +1,316 @@ +Engines +======= + +Deprecation Note +---------------- + +The ENGINE API was introduced in OpenSSL version 0.9.6 as a low level +interface for adding alternative implementations of cryptographic +primitives, most notably for integrating hardware crypto devices. + +The ENGINE interface has its limitations and it has been superseeded +by the [PROVIDER API](README-PROVIDERS.md), it is deprecated in OpenSSL +version 3.0. The following documentation is retained as an aid for +users who need to maintain or support existing ENGINE implementations. +Support for new hardware devices or new algorithms should be added +via providers, and existing engines should be converted to providers +as soon as possible. + +Built-in ENGINE implementations +------------------------------- + +There are currently built-in ENGINE implementations for the following +crypto devices: + + * Microsoft CryptoAPI + * VIA Padlock + * nCipher CHIL + +In addition, dynamic binding to external ENGINE implementations is now +provided by a special ENGINE called "dynamic". See the "DYNAMIC ENGINE" +section below for details. + +At this stage, a number of things are still needed and are being worked on: + + 1. Integration of EVP support. + 2. Configuration support. + 3. Documentation! + +Integration of EVP support +-------------------------- + +With respect to EVP, this relates to support for ciphers and digests in +the ENGINE model so that alternative implementations of existing +algorithms/modes (or previously unimplemented ones) can be provided by +ENGINE implementations. + +Configuration support +--------------------- + +Configuration support currently exists in the ENGINE API itself, in the +form of "control commands". These allow an application to expose to the +user/admin the set of commands and parameter types a given ENGINE +implementation supports, and for an application to directly feed string +based input to those ENGINEs, in the form of name-value pairs. This is an +extensible way for ENGINEs to define their own "configuration" mechanisms +that are specific to a given ENGINE (eg. for a particular hardware +device) but that should be consistent across *all* OpenSSL-based +applications when they use that ENGINE. Work is in progress (or at least +in planning) for supporting these control commands from the CONF (or +NCONF) code so that applications using OpenSSL's existing configuration +file format can have ENGINE settings specified in much the same way. +Presently however, applications must use the ENGINE API itself to provide +such functionality. To see first hand the types of commands available +with the various compiled-in ENGINEs (see further down for dynamic +ENGINEs), use the "engine" openssl utility with full verbosity, i.e.: + + openssl engine -vvvv + +Documentation +------------- + +Documentation? Volunteers welcome! The source code is reasonably well +self-documenting, but some summaries and usage instructions are needed - +moreover, they are needed in the same POD format the existing OpenSSL +documentation is provided in. Any complete or incomplete contributions +would help make this happen. + +STABILITY & BUG-REPORTS +======================= + +What already exists is fairly stable as far as it has been tested, but +the test base has been a bit small most of the time. For the most part, +the vendors of the devices these ENGINEs support have contributed to the +development and/or testing of the implementations, and *usually* (with no +guarantees) have experience in using the ENGINE support to drive their +devices from common OpenSSL-based applications. Bugs and/or inexplicable +behaviour in using a specific ENGINE implementation should be sent to the +author of that implementation (if it is mentioned in the corresponding C +file), and in the case of implementations for commercial hardware +devices, also through whatever vendor support channels are available. If +none of this is possible, or the problem seems to be something about the +ENGINE API itself (ie. not necessarily specific to a particular ENGINE +implementation) then you should mail complete details to the relevant +OpenSSL mailing list. For a definition of "complete details", refer to +the OpenSSL "README" file. As for which list to send it to: + + * openssl-users: if you are *using* the ENGINE abstraction, either in an + pre-compiled application or in your own application code. + + * openssl-dev: if you are discussing problems with OpenSSL source code. + +USAGE +===== + +The default "openssl" ENGINE is always chosen when performing crypto +operations unless you specify otherwise. You must actively tell the +openssl utility commands to use anything else through a new command line +switch called "-engine". Also, if you want to use the ENGINE support in +your own code to do something similar, you must likewise explicitly +select the ENGINE implementation you want. + +Depending on the type of hardware, system, and configuration, "settings" +may need to be applied to an ENGINE for it to function as expected/hoped. +The recommended way of doing this is for the application to support +ENGINE "control commands" so that each ENGINE implementation can provide +whatever configuration primitives it might require and the application +can allow the user/admin (and thus the hardware vendor's support desk +also) to provide any such input directly to the ENGINE implementation. +This way, applications do not need to know anything specific to any +device, they only need to provide the means to carry such user/admin +input through to the ENGINE in question. Ie. this connects *you* (and +your helpdesk) to the specific ENGINE implementation (and device), and +allows application authors to not get buried in hassle supporting +arbitrary devices they know (and care) nothing about. + +A new "openssl" utility, "openssl engine", has been added in that allows +for testing and examination of ENGINE implementations. Basic usage +instructions are available by specifying the "-?" command line switch. + +DYNAMIC ENGINES +=============== + +The new "dynamic" ENGINE provides a low-overhead way to support ENGINE +implementations that aren't pre-compiled and linked into OpenSSL-based +applications. This could be because existing compiled-in implementations +have known problems and you wish to use a newer version with an existing +application. It could equally be because the application (or OpenSSL +library) you are using simply doesn't have support for the ENGINE you +wish to use, and the ENGINE provider (eg. hardware vendor) is providing +you with a self-contained implementation in the form of a shared-library. +The other use-case for "dynamic" is with applications that wish to +maintain the smallest foot-print possible and so do not link in various +ENGINE implementations from OpenSSL, but instead leaves you to provide +them, if you want them, in the form of "dynamic"-loadable +shared-libraries. It should be possible for hardware vendors to provide +their own shared-libraries to support arbitrary hardware to work with +applications based on OpenSSL 0.9.7 or later. If you're using an +application based on 0.9.7 (or later) and the support you desire is only +announced for versions later than the one you need, ask the vendor to +backport their ENGINE to the version you need. + +How does "dynamic" work? +------------------------ + +The dynamic ENGINE has a special flag in its implementation such that +every time application code asks for the 'dynamic' ENGINE, it in fact +gets its own copy of it. As such, multi-threaded code (or code that +multiplexes multiple uses of 'dynamic' in a single application in any +way at all) does not get confused by 'dynamic' being used to do many +independent things. Other ENGINEs typically don't do this so there is +only ever 1 ENGINE structure of its type (and reference counts are used +to keep order). The dynamic ENGINE itself provides absolutely no +cryptographic functionality, and any attempt to "initialise" the ENGINE +automatically fails. All it does provide are a few "control commands" +that can be used to control how it will load an external ENGINE +implementation from a shared-library. To see these control commands, +use the command-line; + + openssl engine -vvvv dynamic + +The "SO_PATH" control command should be used to identify the +shared-library that contains the ENGINE implementation, and "NO_VCHECK" +might possibly be useful if there is a minor version conflict and you +(or a vendor helpdesk) is convinced you can safely ignore it. +"ID" is probably only needed if a shared-library implements +multiple ENGINEs, but if you know the engine id you expect to be using, +it doesn't hurt to specify it (and this provides a sanity check if +nothing else). "LIST_ADD" is only required if you actually wish the +loaded ENGINE to be discoverable by application code later on using the +ENGINE's "id". For most applications, this isn't necessary - but some +application authors may have nifty reasons for using it. The "LOAD" +command is the only one that takes no parameters and is the command +that uses the settings from any previous commands to actually *load* +the shared-library ENGINE implementation. If this command succeeds, the +(copy of the) 'dynamic' ENGINE will magically morph into the ENGINE +that has been loaded from the shared-library. As such, any control +commands supported by the loaded ENGINE could then be executed as per +normal. Eg. if ENGINE "foo" is implemented in the shared-library +"libfoo.so" and it supports some special control command "CMD_FOO", the +following code would load and use it (NB: obviously this code has no +error checking); + + ENGINE *e = ENGINE_by_id("dynamic"); + ENGINE_ctrl_cmd_string(e, "SO_PATH", "/lib/libfoo.so", 0); + ENGINE_ctrl_cmd_string(e, "ID", "foo", 0); + ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0); + ENGINE_ctrl_cmd_string(e, "CMD_FOO", "some input data", 0); + +For testing, the "openssl engine" utility can be useful for this sort +of thing. For example the above code excerpt would achieve much the +same result as; + + openssl engine dynamic \ + -pre SO_PATH:/lib/libfoo.so \ + -pre ID:foo \ + -pre LOAD \ + -pre "CMD_FOO:some input data" + +Or to simply see the list of commands supported by the "foo" ENGINE; + + openssl engine -vvvv dynamic \ + -pre SO_PATH:/lib/libfoo.so \ + -pre ID:foo \ + -pre LOAD + +Applications that support the ENGINE API and more specifically, the +"control commands" mechanism, will provide some way for you to pass +such commands through to ENGINEs. As such, you would select "dynamic" +as the ENGINE to use, and the parameters/commands you pass would +control the *actual* ENGINE used. Each command is actually a name-value +pair and the value can sometimes be omitted (eg. the "LOAD" command). +Whilst the syntax demonstrated in "openssl engine" uses a colon to +separate the command name from the value, applications may provide +their own syntax for making that separation (eg. a win32 registry +key-value pair may be used by some applications). The reason for the +"-pre" syntax in the "openssl engine" utility is that some commands +might be issued to an ENGINE *after* it has been initialised for use. +Eg. if an ENGINE implementation requires a smart-card to be inserted +during initialisation (or a PIN to be typed, or whatever), there may be +a control command you can issue afterwards to "forget" the smart-card +so that additional initialisation is no longer possible. In +applications such as web-servers, where potentially volatile code may +run on the same host system, this may provide some arguable security +value. In such a case, the command would be passed to the ENGINE after +it has been initialised for use, and so the "-post" switch would be +used instead. Applications may provide a different syntax for +supporting this distinction, and some may simply not provide it at all +("-pre" is almost always what you're after, in reality). + +How do I build a "dynamic" ENGINE? +---------------------------------- + +This question is trickier - currently OpenSSL bundles various ENGINE +implementations that are statically built in, and any application that +calls the "ENGINE_load_builtin_engines()" function will automatically +have all such ENGINEs available (and occupying memory). Applications +that don't call that function have no ENGINEs available like that and +would have to use "dynamic" to load any such ENGINE - but on the other +hand such applications would only have the memory footprint of any +ENGINEs explicitly loaded using user/admin provided control commands. +The main advantage of not statically linking ENGINEs and only using +"dynamic" for hardware support is that any installation using no +"external" ENGINE suffers no unnecessary memory footprint from unused +ENGINEs. Likewise, installations that do require an ENGINE incur the +overheads from only *that* ENGINE once it has been loaded. + +Sounds good? Maybe, but currently building an ENGINE implementation as +a shared-library that can be loaded by "dynamic" isn't automated in +OpenSSL's build process. It can be done manually quite easily however. +Such a shared-library can either be built with any OpenSSL code it +needs statically linked in, or it can link dynamically against OpenSSL +if OpenSSL itself is built as a shared library. The instructions are +the same in each case, but in the former (statically linked any +dependencies on OpenSSL) you must ensure OpenSSL is built with +position-independent code ("PIC"). The default OpenSSL compilation may +already specify the relevant flags to do this, but you should consult +with your compiler documentation if you are in any doubt. + +This example will show building the "atalla" ENGINE in the +crypto/engine/ directory as a shared-library for use via the "dynamic" +ENGINE. + + 1. "cd" to the crypto/engine/ directory of a pre-compiled OpenSSL + source tree. + + 2. Recompile at least one source file so you can see all the compiler + flags (and syntax) being used to build normally. Eg; + + touch hw_atalla.c ; make + + will rebuild "hw_atalla.o" using all such flags. + + 3. Manually enter the same compilation line to compile the + "hw_atalla.c" file but with the following two changes; + * add "-DENGINE_DYNAMIC_SUPPORT" to the command line switches, + * change the output file from "hw_atalla.o" to something new, + eg. "tmp_atalla.o" + + 4. Link "tmp_atalla.o" into a shared-library using the top-level + OpenSSL libraries to resolve any dependencies. The syntax for doing + this depends heavily on your system/compiler and is a nightmare + known well to anyone who has worked with shared-library portability + before. 'gcc' on Linux, for example, would use the following syntax; + + gcc -shared -o dyn_atalla.so tmp_atalla.o -L../.. -lcrypto + + 5. Test your shared library using "openssl engine" as explained in the + previous section. Eg. from the top-level directory, you might try + + apps/openssl engine -vvvv dynamic \ + -pre SO_PATH:./crypto/engine/dyn_atalla.so -pre LOAD + +If the shared-library loads successfully, you will see both "-pre" +commands marked as "SUCCESS" and the list of control commands +displayed (because of "-vvvv") will be the control commands for the +*atalla* ENGINE (ie. *not* the 'dynamic' ENGINE). You can also add +the "-t" switch to the utility if you want it to try and initialise +the atalla ENGINE for use to test any possible hardware/driver issues. + +PROBLEMS +======== + +It seems like the ENGINE part doesn't work too well with CryptoSwift on Win32. +A quick test done right before the release showed that trying "openssl speed +-engine cswift" generated errors. If the DSO gets enabled, an attempt is made +to write at memory address 0x00000002. diff --git a/crypto/openssl/README-FIPS.md b/crypto/openssl/README-FIPS.md new file mode 100644 index 000000000000..ba88ff2c4e98 --- /dev/null +++ b/crypto/openssl/README-FIPS.md @@ -0,0 +1,86 @@ +OpenSSL FIPS support +==================== + +This release of OpenSSL includes a cryptographic module that can be +FIPS 140-2 validated. The module is implemented as an OpenSSL provider. +A provider is essentially a dynamically loadable module which implements +cryptographic algorithms, see the [README-PROVIDERS](README-PROVIDERS.md) file +for further details. + +A cryptographic module is only FIPS validated after it has gone through the complex +FIPS 140 validation process. As this process takes a very long time, it is not +possible to validate every minor release of OpenSSL. +If you need a FIPS validated module then you must ONLY generate a FIPS provider +using OpenSSL versions that have valid FIPS certificates. A FIPS certificate +contains a link to a Security Policy, and you MUST follow the instructions +in the Security Policy in order to be FIPS compliant. +See for information related to OpenSSL +FIPS certificates and Security Policies. + +Newer OpenSSL Releases that include security or bug fixes can be used to build +all other components (such as the core API's, TLS and the default, base and +legacy providers) without any restrictions, but the FIPS provider must be built +as specified in the Security Policy (normally with a different version of the +source code). + +The OpenSSL FIPS provider is a shared library called `fips.so` (on Unix), or +resp. `fips.dll` (on Windows). The FIPS provider does not get built and +installed automatically. To enable it, you need to configure OpenSSL using +the `enable-fips` option. + +Installing the FIPS module +========================== + +The following is only a guide. +Please read the Security Policy for up to date installation instructions. + +If the FIPS provider is enabled, it gets installed automatically during the +normal installation process. Simply follow the normal procedure (configure, +make, make test, make install) as described in the [INSTALL](INSTALL.md) file. + +For example, on Unix the final command + + $ make install + +effectively executes the following install targets + + $ make install_sw + $ make install_ssldirs + $ make install_docs + $ make install_fips # for `enable-fips` only + +The `install_fips` make target can also be invoked explicitly to install +the FIPS provider independently, without installing the rest of OpenSSL. + +The Installation of the FIPS provider consists of two steps. In the first step, +the shared library is copied to its installed location, which by default is + + /usr/local/lib/ossl-modules/fips.so on Unix, and + C:\Program Files\OpenSSL\lib\ossl-modules\fips.dll on Windows. + +In the second step, the `openssl fipsinstall` command is executed, which completes +the installation by doing the following two things: + +- Runs the FIPS module self tests +- Generates the so-called FIPS module configuration file containing information + about the module such as the self test status, and the module checksum. + +The FIPS module must have the self tests run, and the FIPS module config file +output generated on every machine that it is to be used on. You must not copy +the FIPS module config file output data from one machine to another. + +On Unix the `openssl fipsinstall` command will be invoked as follows by default: + + $ openssl fipsinstall -out /usr/local/ssl/fipsmodule.cnf -module /usr/local/lib/ossl-modules/fips.so + +If you configured OpenSSL to be installed to a different location, the paths will +vary accordingly. In the rare case that you need to install the fipsmodule.cnf +to non-standard location, you can execute the `openssl fipsinstall` command manually. + +Using the FIPS Module in applications +===================================== + +Documentation about using the FIPS module is available on the [fips_module(7)] +manual page. + + [fips_module(7)]: https://www.openssl.org/docs/man3.0/man7/fips_module.html diff --git a/crypto/openssl/README-PROVIDERS.md b/crypto/openssl/README-PROVIDERS.md new file mode 100644 index 000000000000..25e49c8618f7 --- /dev/null +++ b/crypto/openssl/README-PROVIDERS.md @@ -0,0 +1,145 @@ +Providers +========= + + - [Standard Providers](#standard-providers) + - [The Default Provider](#the-default-provider) + - [The Legacy Provider](#the-legacy-provider) + - [The FIPS Provider](#the-fips-provider) + - [The Base Provider](#the-base-provider) + - [The Null Provider](#the-null-provider) + - [Loading Providers](#loading-providers) + +Standard Providers +================== + +Providers are containers for algorithm implementations. Whenever a cryptographic +algorithm is used via the high level APIs a provider is selected. It is that +provider implementation that actually does the required work. There are five +providers distributed with OpenSSL. In the future we expect third parties to +distribute their own providers which can be added to OpenSSL dynamically. +Documentation about writing providers is available on the [provider(7)] +manual page. + + [provider(7)]: https://www.openssl.org/docs/man3.0/man7/provider.html + +The Default Provider +-------------------- + +The default provider collects together all of the standard built-in OpenSSL +algorithm implementations. If an application doesn't specify anything else +explicitly (e.g. in the application or via config), then this is the provider +that will be used. It is loaded automatically the first time that we try to +get an algorithm from a provider if no other provider has been loaded yet. +If another provider has already been loaded then it won't be loaded +automatically. Therefore if you want to use it in conjunction with other +providers then you must load it explicitly. + +This is a "built-in" provider which means that it is compiled and linked +into the libcrypto library and does not exist as a separate standalone module. + +The Legacy Provider +------------------- + +The legacy provider is a collection of legacy algorithms that are either no +longer in common use or considered insecure and strongly discouraged from use. +However, some applications may need to use these algorithms for backwards +compatibility reasons. This provider is **not** loaded by default. +This may mean that some applications upgrading from earlier versions of OpenSSL +may find that some algorithms are no longer available unless they load the +legacy provider explicitly. + +Algorithms in the legacy provider include MD2, MD4, MDC2, RMD160, CAST5, +BF (Blowfish), IDEA, SEED, RC2, RC4, RC5 and DES (but not 3DES). + +The FIPS Provider +----------------- + +The FIPS provider contains a sub-set of the algorithm implementations available +from the default provider, consisting of algorithms conforming to FIPS standards. +It is intended that this provider will be FIPS140-2 validated. + +In some cases there may be minor behavioural differences between algorithm +implementations in this provider compared to the equivalent algorithm in the +default provider. This is typically in order to conform to FIPS standards. + +The Base Provider +----------------- + +The base provider contains a small sub-set of non-cryptographic algorithms +available in the default provider. For example, it contains algorithms to +serialize and deserialize keys to files. If you do not load the default +provider then you should always load this one instead (in particular, if +you are using the FIPS provider). + +The Null Provider +----------------- + +The null provider is "built-in" to libcrypto and contains no algorithm +implementations. In order to guarantee that the default provider is not +automatically loaded, the null provider can be loaded instead. + +This can be useful if you are using non-default library contexts and want +to ensure that the default library context is never used unintentionally. + +Loading Providers +================= + +Providers to be loaded can be specified in the OpenSSL config file. +See the [config(5)] manual page for information about how to configure +providers via the config file, and how to automatically activate them. + + [config(5)]: https://www.openssl.org/docs/man3.0/man5/config.html + +The following is a minimal config file example to load and activate both +the legacy and the default provider in the default library context. + + openssl_conf = openssl_init + + [openssl_init] + providers = provider_sect + + [provider_sect] + default = default_sect + legacy = legacy_sect + + [default_sect] + activate = 1 + + [legacy_sect] + activate = 1 + +It is also possible to load providers programmatically. For example you can +load the legacy provider into the default library context as shown below. +Note that once you have explicitly loaded a provider into the library context +the default provider will no longer be automatically loaded. Therefore you will +often also want to explicitly load the default provider, as is done here: + + #include + #include + + #include + + int main(void) + { + OSSL_PROVIDER *legacy; + OSSL_PROVIDER *deflt; + + /* Load Multiple providers into the default (NULL) library context */ + legacy = OSSL_PROVIDER_load(NULL, "legacy"); + if (legacy == NULL) { + printf("Failed to load Legacy provider\n"); + exit(EXIT_FAILURE); + } + deflt = OSSL_PROVIDER_load(NULL, "default"); + if (deflt == NULL) { + printf("Failed to load Default provider\n"); + OSSL_PROVIDER_unload(legacy); + exit(EXIT_FAILURE); + } + + /* Rest of application */ + + OSSL_PROVIDER_unload(legacy); + OSSL_PROVIDER_unload(deflt); + exit(EXIT_SUCCESS); + } diff --git a/crypto/openssl/README.ENGINE b/crypto/openssl/README.ENGINE deleted file mode 100644 index 230dc82a87ba..000000000000 --- a/crypto/openssl/README.ENGINE +++ /dev/null @@ -1,287 +0,0 @@ - ENGINE - ====== - - With OpenSSL 0.9.6, a new component was added to support alternative - cryptography implementations, most commonly for interfacing with external - crypto devices (eg. accelerator cards). This component is called ENGINE, - and its presence in OpenSSL 0.9.6 (and subsequent bug-fix releases) - caused a little confusion as 0.9.6** releases were rolled in two - versions, a "standard" and an "engine" version. In development for 0.9.7, - the ENGINE code has been merged into the main branch and will be present - in the standard releases from 0.9.7 forwards. - - There are currently built-in ENGINE implementations for the following - crypto devices: - - o Microsoft CryptoAPI - o VIA Padlock - o nCipher CHIL - - In addition, dynamic binding to external ENGINE implementations is now - provided by a special ENGINE called "dynamic". See the "DYNAMIC ENGINE" - section below for details. - - At this stage, a number of things are still needed and are being worked on: - - 1 Integration of EVP support. - 2 Configuration support. - 3 Documentation! - -1 With respect to EVP, this relates to support for ciphers and digests in - the ENGINE model so that alternative implementations of existing - algorithms/modes (or previously unimplemented ones) can be provided by - ENGINE implementations. - -2 Configuration support currently exists in the ENGINE API itself, in the - form of "control commands". These allow an application to expose to the - user/admin the set of commands and parameter types a given ENGINE - implementation supports, and for an application to directly feed string - based input to those ENGINEs, in the form of name-value pairs. This is an - extensible way for ENGINEs to define their own "configuration" mechanisms - that are specific to a given ENGINE (eg. for a particular hardware - device) but that should be consistent across *all* OpenSSL-based - applications when they use that ENGINE. Work is in progress (or at least - in planning) for supporting these control commands from the CONF (or - NCONF) code so that applications using OpenSSL's existing configuration - file format can have ENGINE settings specified in much the same way. - Presently however, applications must use the ENGINE API itself to provide - such functionality. To see first hand the types of commands available - with the various compiled-in ENGINEs (see further down for dynamic - ENGINEs), use the "engine" openssl utility with full verbosity, ie; - openssl engine -vvvv - -3 Documentation? Volunteers welcome! The source code is reasonably well - self-documenting, but some summaries and usage instructions are needed - - moreover, they are needed in the same POD format the existing OpenSSL - documentation is provided in. Any complete or incomplete contributions - would help make this happen. - - STABILITY & BUG-REPORTS - ======================= - - What already exists is fairly stable as far as it has been tested, but - the test base has been a bit small most of the time. For the most part, - the vendors of the devices these ENGINEs support have contributed to the - development and/or testing of the implementations, and *usually* (with no - guarantees) have experience in using the ENGINE support to drive their - devices from common OpenSSL-based applications. Bugs and/or inexplicable - behaviour in using a specific ENGINE implementation should be sent to the - author of that implementation (if it is mentioned in the corresponding C - file), and in the case of implementations for commercial hardware - devices, also through whatever vendor support channels are available. If - none of this is possible, or the problem seems to be something about the - ENGINE API itself (ie. not necessarily specific to a particular ENGINE - implementation) then you should mail complete details to the relevant - OpenSSL mailing list. For a definition of "complete details", refer to - the OpenSSL "README" file. As for which list to send it to; - - openssl-users: if you are *using* the ENGINE abstraction, either in an - pre-compiled application or in your own application code. - - openssl-dev: if you are discussing problems with OpenSSL source code. - - USAGE - ===== - - The default "openssl" ENGINE is always chosen when performing crypto - operations unless you specify otherwise. You must actively tell the - openssl utility commands to use anything else through a new command line - switch called "-engine". Also, if you want to use the ENGINE support in - your own code to do something similar, you must likewise explicitly - select the ENGINE implementation you want. - - Depending on the type of hardware, system, and configuration, "settings" - may need to be applied to an ENGINE for it to function as expected/hoped. - The recommended way of doing this is for the application to support - ENGINE "control commands" so that each ENGINE implementation can provide - whatever configuration primitives it might require and the application - can allow the user/admin (and thus the hardware vendor's support desk - also) to provide any such input directly to the ENGINE implementation. - This way, applications do not need to know anything specific to any - device, they only need to provide the means to carry such user/admin - input through to the ENGINE in question. Ie. this connects *you* (and - your helpdesk) to the specific ENGINE implementation (and device), and - allows application authors to not get buried in hassle supporting - arbitrary devices they know (and care) nothing about. - - A new "openssl" utility, "openssl engine", has been added in that allows - for testing and examination of ENGINE implementations. Basic usage - instructions are available by specifying the "-?" command line switch. - - DYNAMIC ENGINES - =============== - - The new "dynamic" ENGINE provides a low-overhead way to support ENGINE - implementations that aren't pre-compiled and linked into OpenSSL-based - applications. This could be because existing compiled-in implementations - have known problems and you wish to use a newer version with an existing - application. It could equally be because the application (or OpenSSL - library) you are using simply doesn't have support for the ENGINE you - wish to use, and the ENGINE provider (eg. hardware vendor) is providing - you with a self-contained implementation in the form of a shared-library. - The other use-case for "dynamic" is with applications that wish to - maintain the smallest foot-print possible and so do not link in various - ENGINE implementations from OpenSSL, but instead leaves you to provide - them, if you want them, in the form of "dynamic"-loadable - shared-libraries. It should be possible for hardware vendors to provide - their own shared-libraries to support arbitrary hardware to work with - applications based on OpenSSL 0.9.7 or later. If you're using an - application based on 0.9.7 (or later) and the support you desire is only - announced for versions later than the one you need, ask the vendor to - backport their ENGINE to the version you need. - - How does "dynamic" work? - ------------------------ - The dynamic ENGINE has a special flag in its implementation such that - every time application code asks for the 'dynamic' ENGINE, it in fact - gets its own copy of it. As such, multi-threaded code (or code that - multiplexes multiple uses of 'dynamic' in a single application in any - way at all) does not get confused by 'dynamic' being used to do many - independent things. Other ENGINEs typically don't do this so there is - only ever 1 ENGINE structure of its type (and reference counts are used - to keep order). The dynamic ENGINE itself provides absolutely no - cryptographic functionality, and any attempt to "initialise" the ENGINE - automatically fails. All it does provide are a few "control commands" - that can be used to control how it will load an external ENGINE - implementation from a shared-library. To see these control commands, - use the command-line; - - openssl engine -vvvv dynamic - - The "SO_PATH" control command should be used to identify the - shared-library that contains the ENGINE implementation, and "NO_VCHECK" - might possibly be useful if there is a minor version conflict and you - (or a vendor helpdesk) is convinced you can safely ignore it. - "ID" is probably only needed if a shared-library implements - multiple ENGINEs, but if you know the engine id you expect to be using, - it doesn't hurt to specify it (and this provides a sanity check if - nothing else). "LIST_ADD" is only required if you actually wish the - loaded ENGINE to be discoverable by application code later on using the - ENGINE's "id". For most applications, this isn't necessary - but some - application authors may have nifty reasons for using it. The "LOAD" - command is the only one that takes no parameters and is the command - that uses the settings from any previous commands to actually *load* - the shared-library ENGINE implementation. If this command succeeds, the - (copy of the) 'dynamic' ENGINE will magically morph into the ENGINE - that has been loaded from the shared-library. As such, any control - commands supported by the loaded ENGINE could then be executed as per - normal. Eg. if ENGINE "foo" is implemented in the shared-library - "libfoo.so" and it supports some special control command "CMD_FOO", the - following code would load and use it (NB: obviously this code has no - error checking); - - ENGINE *e = ENGINE_by_id("dynamic"); - ENGINE_ctrl_cmd_string(e, "SO_PATH", "/lib/libfoo.so", 0); - ENGINE_ctrl_cmd_string(e, "ID", "foo", 0); - ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0); - ENGINE_ctrl_cmd_string(e, "CMD_FOO", "some input data", 0); - - For testing, the "openssl engine" utility can be useful for this sort - of thing. For example the above code excerpt would achieve much the - same result as; - - openssl engine dynamic \ - -pre SO_PATH:/lib/libfoo.so \ - -pre ID:foo \ - -pre LOAD \ - -pre "CMD_FOO:some input data" - - Or to simply see the list of commands supported by the "foo" ENGINE; - - openssl engine -vvvv dynamic \ - -pre SO_PATH:/lib/libfoo.so \ - -pre ID:foo \ - -pre LOAD - - Applications that support the ENGINE API and more specifically, the - "control commands" mechanism, will provide some way for you to pass - such commands through to ENGINEs. As such, you would select "dynamic" - as the ENGINE to use, and the parameters/commands you pass would - control the *actual* ENGINE used. Each command is actually a name-value - pair and the value can sometimes be omitted (eg. the "LOAD" command). - Whilst the syntax demonstrated in "openssl engine" uses a colon to - separate the command name from the value, applications may provide - their own syntax for making that separation (eg. a win32 registry - key-value pair may be used by some applications). The reason for the - "-pre" syntax in the "openssl engine" utility is that some commands - might be issued to an ENGINE *after* it has been initialised for use. - Eg. if an ENGINE implementation requires a smart-card to be inserted - during initialisation (or a PIN to be typed, or whatever), there may be - a control command you can issue afterwards to "forget" the smart-card - so that additional initialisation is no longer possible. In - applications such as web-servers, where potentially volatile code may - run on the same host system, this may provide some arguable security - value. In such a case, the command would be passed to the ENGINE after - it has been initialised for use, and so the "-post" switch would be - used instead. Applications may provide a different syntax for - supporting this distinction, and some may simply not provide it at all - ("-pre" is almost always what you're after, in reality). - - How do I build a "dynamic" ENGINE? - ---------------------------------- - This question is trickier - currently OpenSSL bundles various ENGINE - implementations that are statically built in, and any application that - calls the "ENGINE_load_builtin_engines()" function will automatically - have all such ENGINEs available (and occupying memory). Applications - that don't call that function have no ENGINEs available like that and - would have to use "dynamic" to load any such ENGINE - but on the other - hand such applications would only have the memory footprint of any - ENGINEs explicitly loaded using user/admin provided control commands. - The main advantage of not statically linking ENGINEs and only using - "dynamic" for hardware support is that any installation using no - "external" ENGINE suffers no unnecessary memory footprint from unused - ENGINEs. Likewise, installations that do require an ENGINE incur the - overheads from only *that* ENGINE once it has been loaded. - - Sounds good? Maybe, but currently building an ENGINE implementation as - a shared-library that can be loaded by "dynamic" isn't automated in - OpenSSL's build process. It can be done manually quite easily however. - Such a shared-library can either be built with any OpenSSL code it - needs statically linked in, or it can link dynamically against OpenSSL - if OpenSSL itself is built as a shared library. The instructions are - the same in each case, but in the former (statically linked any - dependencies on OpenSSL) you must ensure OpenSSL is built with - position-independent code ("PIC"). The default OpenSSL compilation may - already specify the relevant flags to do this, but you should consult - with your compiler documentation if you are in any doubt. - - This example will show building the "atalla" ENGINE in the - crypto/engine/ directory as a shared-library for use via the "dynamic" - ENGINE. - 1) "cd" to the crypto/engine/ directory of a pre-compiled OpenSSL - source tree. - 2) Recompile at least one source file so you can see all the compiler - flags (and syntax) being used to build normally. Eg; - touch hw_atalla.c ; make - will rebuild "hw_atalla.o" using all such flags. - 3) Manually enter the same compilation line to compile the - "hw_atalla.c" file but with the following two changes; - (a) add "-DENGINE_DYNAMIC_SUPPORT" to the command line switches, - (b) change the output file from "hw_atalla.o" to something new, - eg. "tmp_atalla.o" - 4) Link "tmp_atalla.o" into a shared-library using the top-level - OpenSSL libraries to resolve any dependencies. The syntax for doing - this depends heavily on your system/compiler and is a nightmare - known well to anyone who has worked with shared-library portability - before. 'gcc' on Linux, for example, would use the following syntax; - gcc -shared -o dyn_atalla.so tmp_atalla.o -L../.. -lcrypto - 5) Test your shared library using "openssl engine" as explained in the - previous section. Eg. from the top-level directory, you might try; - apps/openssl engine -vvvv dynamic \ - -pre SO_PATH:./crypto/engine/dyn_atalla.so -pre LOAD - If the shared-library loads successfully, you will see both "-pre" - commands marked as "SUCCESS" and the list of control commands - displayed (because of "-vvvv") will be the control commands for the - *atalla* ENGINE (ie. *not* the 'dynamic' ENGINE). You can also add - the "-t" switch to the utility if you want it to try and initialise - the atalla ENGINE for use to test any possible hardware/driver - issues. - - PROBLEMS - ======== - - It seems like the ENGINE part doesn't work too well with CryptoSwift on Win32. - A quick test done right before the release showed that trying "openssl speed - -engine cswift" generated errors. If the DSO gets enabled, an attempt is made - to write at memory address 0x00000002. - diff --git a/crypto/openssl/README.FIPS b/crypto/openssl/README.FIPS deleted file mode 100644 index 859348664ef6..000000000000 --- a/crypto/openssl/README.FIPS +++ /dev/null @@ -1 +0,0 @@ -This release does not support a FIPS 140-2 validated module. diff --git a/crypto/openssl/README.md b/crypto/openssl/README.md new file mode 100644 index 000000000000..f2f4fd39ad05 --- /dev/null +++ b/crypto/openssl/README.md @@ -0,0 +1,224 @@ +Welcome to the OpenSSL Project +============================== + +[![openssl logo]][www.openssl.org] + +[![github actions ci badge]][github actions ci] +[![appveyor badge]][appveyor jobs] + +OpenSSL is a robust, commercial-grade, full-featured Open Source Toolkit +for the Transport Layer Security (TLS) protocol formerly known as the +Secure Sockets Layer (SSL) protocol. The protocol implementation is based +on a full-strength general purpose cryptographic library, which can also +be used stand-alone. + +OpenSSL is descended from the SSLeay library developed by Eric A. Young +and Tim J. Hudson. + +The official Home Page of the OpenSSL Project is [www.openssl.org]. + +Table of Contents +================= + + - [Overview](#overview) + - [Download](#download) + - [Build and Install](#build-and-install) + - [Documentation](#documentation) + - [License](#license) + - [Support](#support) + - [Contributing](#contributing) + - [Legalities](#legalities) + +Overview +======== + +The OpenSSL toolkit includes: + +- **libssl** + an implementation of all TLS protocol versions up to TLSv1.3 ([RFC 8446]). + +- **libcrypto** + a full-strength general purpose cryptographic library. It constitutes the + basis of the TLS implementation, but can also be used independently. + +- **openssl** + the OpenSSL command line tool, a swiss army knife for cryptographic tasks, + testing and analyzing. It can be used for + - creation of key parameters + - creation of X.509 certificates, CSRs and CRLs + - calculation of message digests + - encryption and decryption + - SSL/TLS client and server tests + - handling of S/MIME signed or encrypted mail + - and more... + +Download +======== + +For Production Use +------------------ + +Source code tarballs of the official releases can be downloaded from +[www.openssl.org/source](https://www.openssl.org/source). +The OpenSSL project does not distribute the toolkit in binary form. + +However, for a large variety of operating systems precompiled versions +of the OpenSSL toolkit are available. In particular on Linux and other +Unix operating systems it is normally recommended to link against the +precompiled shared libraries provided by the distributor or vendor. + +For Testing and Development +--------------------------- + +Although testing and development could in theory also be done using +the source tarballs, having a local copy of the git repository with +the entire project history gives you much more insight into the +code base. + +The official OpenSSL Git Repository is located at [git.openssl.org]. +There is a GitHub mirror of the repository at [github.com/openssl/openssl], +which is updated automatically from the former on every commit. + +A local copy of the Git Repository can be obtained by cloning it from +the original OpenSSL repository using + + git clone git://git.openssl.org/openssl.git + +or from the GitHub mirror using + + git clone https://github.com/openssl/openssl.git + +If you intend to contribute to OpenSSL, either to fix bugs or contribute +new features, you need to fork the OpenSSL repository openssl/openssl on +GitHub and clone your public fork instead. + + git clone https://github.com/yourname/openssl.git + +This is necessary, because all development of OpenSSL nowadays is done via +GitHub pull requests. For more details, see [Contributing](#contributing). + +Build and Install +================= + +After obtaining the Source, have a look at the [INSTALL](INSTALL.md) file for +detailed instructions about building and installing OpenSSL. For some +platforms, the installation instructions are amended by a platform specific +document. + + * [Notes for UNIX-like platforms](NOTES-UNIX.md) + * [Notes for Android platforms](NOTES-ANDROID.md) + * [Notes for Windows platforms](NOTES-WINDOWS.md) + * [Notes for the DOS platform with DJGPP](NOTES-DJGPP.md) + * [Notes for the OpenVMS platform](NOTES-VMS.md) + * [Notes on Perl](NOTES-PERL.md) + * [Notes on Valgrind](NOTES-VALGRIND.md) + +Specific notes on upgrading to OpenSSL 3.0 from previous versions can be found +in the [migration_guide(7ossl)] manual page. + +Documentation +============= + +Manual Pages +------------ + +The manual pages for the master branch and all current stable releases are +available online. + +- [OpenSSL master](https://www.openssl.org/docs/manmaster) +- [OpenSSL 3.0](https://www.openssl.org/docs/man3.0) +- [OpenSSL 1.1.1](https://www.openssl.org/docs/man1.1.1) + +Wiki +---- + +There is a Wiki at [wiki.openssl.org] which is currently not very active. +It contains a lot of useful information, not all of which is up to date. + +License +======= + +OpenSSL is licensed under the Apache License 2.0, which means that +you are free to get and use it for commercial and non-commercial +purposes as long as you fulfill its conditions. + +See the [LICENSE.txt](LICENSE.txt) file for more details. + +Support +======= + +There are various ways to get in touch. The correct channel depends on +your requirement. see the [SUPPORT](SUPPORT.md) file for more details. + +Contributing +============ + +If you are interested and willing to contribute to the OpenSSL project, +please take a look at the [CONTRIBUTING](CONTRIBUTING.md) file. + +Legalities +========== + +A number of nations restrict the use or export of cryptography. If you are +potentially subject to such restrictions you should seek legal advice before +attempting to develop or distribute cryptographic code. + +Copyright +========= + +Copyright (c) 1998-2022 The OpenSSL Project + +Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson + +All rights reserved. + + + +[www.openssl.org]: + + "OpenSSL Homepage" + +[git.openssl.org]: + + "OpenSSL Git Repository" + +[git.openssl.org]: + + "OpenSSL Git Repository" + +[github.com/openssl/openssl]: + + "OpenSSL GitHub Mirror" + +[wiki.openssl.org]: + + "OpenSSL Wiki" + +[migration_guide(7ossl)]: + + "OpenSSL Migration Guide" + +[RFC 8446]: + + + + +[openssl logo]: + doc/images/openssl.svg + "OpenSSL Logo" + +[github actions ci badge]: + + "GitHub Actions CI Status" + +[github actions ci]: + + "GitHub Actions CI" + +[appveyor badge]: + + "AppVeyor Build Status" + +[appveyor jobs]: + + "AppVeyor Jobs" diff --git a/crypto/openssl/SUPPORT.md b/crypto/openssl/SUPPORT.md new file mode 100644 index 000000000000..c0b6babe89ad --- /dev/null +++ b/crypto/openssl/SUPPORT.md @@ -0,0 +1,93 @@ +OpenSSL User Support resources +============================== + +See the for details on how to +obtain commercial technical support. + +If you have general questions about using OpenSSL +------------------------------------------------- + +In this case the [openssl-users] mailing list is the right place for you. +The list is not only watched by the OpenSSL team members, but also by many +other OpenSSL users. Here you will most likely get the answer to your questions. +An overview over the [mailing lists](#mailing-lists) can be found below. + +If you think you found a Bug +---------------------------- + +*NOTE: this section assumes that you want to report it or figure it out and +fix it. What's written here is not to be taken as a recipe for how to get a +working production installation* + +If you have any problems with OpenSSL then please take the following steps +first: + +- Search the mailing lists and/or the GitHub issues to find out whether + the problem has already been reported. +- Download the latest version from the repository to see if the problem + has already been addressed. +- Configure without assembler support (`no-asm`) and check whether the + problem persists. +- Remove compiler optimization flags. + +Please keep in mind: Just because something doesn't work the way you expect +does not mean it is necessarily a bug in OpenSSL. If you are not sure, +consider searching the mail archives and posting a question to the +[openssl-users] mailing list first. + +### Open an Issue + +If you wish to report a bug, please open an [issue][github-issues] on GitHub +and include the following information: + +- OpenSSL version: output of `openssl version -a` +- Configuration data: output of `perl configdata.pm --dump` +- OS Name, Version, Hardware platform +- Compiler Details (name, version) +- Application Details (name, version) +- Problem Description (steps that will reproduce the problem, if known) +- Stack Traceback (if the application dumps core) + +Not only errors in the software, also errors in the documentation, in +particular the manual pages, can be reported as issues. + +### Submit a Pull Request + +The fastest way to get a bug fixed is to fix it yourself ;-). If you are +experienced in programming and know how to fix the bug, you can open a +pull request. The details are covered in the [Contributing][contributing] section. + +Don't hesitate to open a pull request, even if it's only a small change +like a grammatical or typographical error in the documentation. + +Mailing Lists +============= + +The OpenSSL maintains a number of [mailing lists] for various purposes. +The most important lists are: + +- [openssl-users] for general questions about using the OpenSSL software + and discussions between OpenSSL users. + +- [openssl-announce] for official announcements to the OpenSSL community. + +- [openssl-project] for discussion about the development roadmap + and governance. + +Only subscribers can post to [openssl-users] or [openssl-project]. The +archives are made public, however. For more information, see the [mailing +lists] page. + +There was an [openssl-dev] list that has been discontinued since development +is now taking place in the form of GitHub pull requests. Although not active +anymore, the searchable archive may still contain useful information. + + + +[mailing lists]: https://www.openssl.org/community/mailinglists.html +[openssl-users]: https://mta.openssl.org/mailman/listinfo/openssl-users +[openssl-announce]: https://mta.openssl.org/mailman/listinfo/openssl-announce +[openssl-project]: https://mta.openssl.org/mailman/listinfo/openssl-project +[openssl-dev]: https://mta.openssl.org/mailman/listinfo/openssl-dev +[github-issues]: https://github.com/openssl/openssl/issues/new/choose +[contributing]: https://github.com/openssl/openssl/blob/master/CONTRIBUTING.md diff --git a/crypto/openssl/VERSION.dat b/crypto/openssl/VERSION.dat new file mode 100644 index 000000000000..375a0de7e128 --- /dev/null +++ b/crypto/openssl/VERSION.dat @@ -0,0 +1,7 @@ +MAJOR=3 +MINOR=0 +PATCH=8 +PRE_RELEASE_TAG= +BUILD_METADATA= +RELEASE_DATE="7 Feb 2023" +SHLIB_VERSION=3 diff --git a/crypto/openssl/apps/CA.pl.in b/crypto/openssl/apps/CA.pl.in index db3cc383189e..f029470005d9 100644 --- a/crypto/openssl/apps/CA.pl.in +++ b/crypto/openssl/apps/CA.pl.in @@ -1,7 +1,7 @@ #!{- $config{HASHBANGPERL} -} -# Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -14,57 +14,63 @@ use strict; use warnings; -my $openssl = "openssl"; -if(defined $ENV{'OPENSSL'}) { - $openssl = $ENV{'OPENSSL'}; -} else { - $ENV{'OPENSSL'} = $openssl; -} - my $verbose = 1; +my @OPENSSL_CMDS = ("req", "ca", "pkcs12", "x509", "verify"); -my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} || ""; -my $DAYS = "-days 365"; -my $CADAYS = "-days 1095"; # 3 years +my $openssl = $ENV{'OPENSSL'} // "openssl"; +$ENV{'OPENSSL'} = $openssl; +my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} // ""; + +# Command invocations. my $REQ = "$openssl req $OPENSSL_CONFIG"; my $CA = "$openssl ca $OPENSSL_CONFIG"; my $VERIFY = "$openssl verify"; my $X509 = "$openssl x509"; my $PKCS12 = "$openssl pkcs12"; -# default openssl.cnf file has setup as per the following +# Default values for various configuration settings. my $CATOP = "./demoCA"; my $CAKEY = "cakey.pem"; my $CAREQ = "careq.pem"; my $CACERT = "cacert.pem"; my $CACRL = "crl.pem"; -my $DIRMODE = 0777; - +my $DAYS = "-days 365"; +my $CADAYS = "-days 1095"; # 3 years my $NEWKEY = "newkey.pem"; my $NEWREQ = "newreq.pem"; my $NEWCERT = "newcert.pem"; my $NEWP12 = "newcert.p12"; -my $RET = 0; + +# Commandline parsing +my %EXTRA; my $WHAT = shift @ARGV || ""; -my @OPENSSL_CMDS = ("req", "ca", "pkcs12", "x509", "verify"); -my %EXTRA = extra_args(\@ARGV, "-extra-"); -my $FILE; - -sub extra_args { - my ($args_ref, $arg_prefix) = @_; - my %eargs = map { - if ($_ < $#$args_ref) { - my ($arg, $value) = splice(@$args_ref, $_, 2); - $arg =~ s/$arg_prefix//; - ($arg, $value); - } else { - (); - } - } reverse grep($$args_ref[$_] =~ /$arg_prefix/, 0..$#$args_ref); - my %empty = map { ($_, "") } @OPENSSL_CMDS; - return (%empty, %eargs); +@ARGV = parse_extra(@ARGV); +my $RET = 0; + +# Split out "-extra-CMD value", and return new |@ARGV|. Fill in +# |EXTRA{CMD}| with list of values. +sub parse_extra +{ + foreach ( @OPENSSL_CMDS ) { + $EXTRA{$_} = ''; + } + + my @result; + while ( scalar(@_) > 0 ) { + my $arg = shift; + if ( $arg !~ m/-extra-([a-z0-9]+)/ ) { + push @result, $arg; + next; + } + $arg =~ s/-extra-//; + die("Unknown \"-${arg}-extra\" option, exiting") + unless scalar grep { $arg eq $_ } @OPENSSL_CMDS; + $EXTRA{$arg} .= " " . shift; + } + return @result; } + # See if reason for a CRL entry is valid; exit if not. sub crl_reason_ok { @@ -113,19 +119,25 @@ sub run if ( $WHAT =~ /^(-\?|-h|-help)$/ ) { - print STDERR "usage: CA.pl -newcert | -newreq | -newreq-nodes | -xsign | -sign | -signCA | -signcert | -crl | -newca [-extra-cmd extra-params]\n"; - print STDERR " CA.pl -pkcs12 [-extra-pkcs12 extra-params] [certname]\n"; - print STDERR " CA.pl -verify [-extra-verify extra-params] certfile ...\n"; - print STDERR " CA.pl -revoke [-extra-ca extra-params] certfile [reason]\n"; + print STDERR <${CATOP}/index.txt"; close OUT; open OUT, ">${CATOP}/crlnumber"; @@ -145,6 +166,7 @@ if ($WHAT eq '-newcert' ) { close OUT; # ask user for existing CA certificate print "CA certificate filename (or enter to create)\n"; + my $FILE; $FILE = "" unless defined($FILE = ); $FILE =~ s{\R$}{}; if ($FILE ne "") { @@ -152,43 +174,43 @@ if ($WHAT eq '-newcert' ) { copy_pemfile($FILE,"${CATOP}/$CACERT", "CERTIFICATE"); } else { print "Making CA certificate ...\n"; - $RET = run("$REQ -new -keyout" - . " ${CATOP}/private/$CAKEY" + $RET = run("$REQ -new -keyout ${CATOP}/private/$CAKEY" . " -out ${CATOP}/$CAREQ $EXTRA{req}"); $RET = run("$CA -create_serial" . " -out ${CATOP}/$CACERT $CADAYS -batch" . " -keyfile ${CATOP}/private/$CAKEY -selfsign" - . " -extensions v3_ca $EXTRA{ca}" - . " -infiles ${CATOP}/$CAREQ") if $RET == 0; + . " -extensions v3_ca" + . " -infiles ${CATOP}/$CAREQ $EXTRA{ca}") if $RET == 0; print "CA certificate is in ${CATOP}/$CACERT\n" if $RET == 0; } } elsif ($WHAT eq '-pkcs12' ) { my $cname = $ARGV[0]; $cname = "My Certificate" unless defined $cname; $RET = run("$PKCS12 -in $NEWCERT -inkey $NEWKEY" - . " -certfile ${CATOP}/$CACERT" - . " -out $NEWP12" + . " -certfile ${CATOP}/$CACERT -out $NEWP12" . " -export -name \"$cname\" $EXTRA{pkcs12}"); print "PKCS #12 file is in $NEWP12\n" if $RET == 0; } elsif ($WHAT eq '-xsign' ) { - $RET = run("$CA -policy policy_anything $EXTRA{ca} -infiles $NEWREQ"); + $RET = run("$CA -policy policy_anything -infiles $NEWREQ $EXTRA{ca}"); } elsif ($WHAT eq '-sign' ) { - $RET = run("$CA -policy policy_anything -out $NEWCERT $EXTRA{ca} -infiles $NEWREQ"); + $RET = run("$CA -policy policy_anything -out $NEWCERT" + . " -infiles $NEWREQ $EXTRA{ca}"); print "Signed certificate is in $NEWCERT\n" if $RET == 0; } elsif ($WHAT eq '-signCA' ) { $RET = run("$CA -policy policy_anything -out $NEWCERT" - . " -extensions v3_ca $EXTRA{ca} -infiles $NEWREQ"); + . " -extensions v3_ca -infiles $NEWREQ $EXTRA{ca}"); print "Signed CA certificate is in $NEWCERT\n" if $RET == 0; } elsif ($WHAT eq '-signcert' ) { $RET = run("$X509 -x509toreq -in $NEWREQ -signkey $NEWREQ" . " -out tmp.pem $EXTRA{x509}"); $RET = run("$CA -policy policy_anything -out $NEWCERT" - . "$EXTRA{ca} -infiles tmp.pem") if $RET == 0; + . "-infiles tmp.pem $EXTRA{ca}") if $RET == 0; print "Signed certificate is in $NEWCERT\n" if $RET == 0; } elsif ($WHAT eq '-verify' ) { my @files = @ARGV ? @ARGV : ( $NEWCERT ); - my $file; - foreach $file (@files) { + foreach my $file (@files) { + # -CAfile quoted for VMS, since the C RTL downcases all unquoted + # arguments to C programs my $status = run("$VERIFY \"-CAfile\" ${CATOP}/$CACERT $file $EXTRA{verify}"); $RET = $status if $status != 0; } diff --git a/crypto/openssl/apps/asn1pars.c b/crypto/openssl/apps/asn1parse.c similarity index 97% rename from crypto/openssl/apps/asn1pars.c rename to crypto/openssl/apps/asn1parse.c index 6c44df7de490..f0bfd1d45fc4 100644 --- a/crypto/openssl/apps/asn1pars.c +++ b/crypto/openssl/apps/asn1parse.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,7 +19,7 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_IN, OPT_OUT, OPT_INDENT, OPT_NOOUT, OPT_OID, OPT_OFFSET, OPT_LENGTH, OPT_DUMP, OPT_DLIMIT, OPT_STRPARSE, OPT_GENSTR, OPT_GENCONF, OPT_STRICTPEM, @@ -27,27 +27,32 @@ typedef enum OPTION_choice { } OPTION_CHOICE; const OPTIONS asn1parse_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"oid", OPT_OID, '<', "file of extra oid definitions"}, + + OPT_SECTION("I/O"), {"inform", OPT_INFORM, 'F', "input format - one of DER PEM"}, {"in", OPT_IN, '<', "input file"}, {"out", OPT_OUT, '>', "output file (output format is always DER)"}, - {"i", OPT_INDENT, 0, "indents the output"}, {"noout", OPT_NOOUT, 0, "do not produce any output"}, {"offset", OPT_OFFSET, 'p', "offset into file"}, {"length", OPT_LENGTH, 'p', "length of section in file"}, - {"oid", OPT_OID, '<', "file of extra oid definitions"}, - {"dump", OPT_DUMP, 0, "unknown data in hex form"}, - {"dlimit", OPT_DLIMIT, 'p', - "dump the first arg bytes of unknown data in hex form"}, {"strparse", OPT_STRPARSE, 'p', "offset; a series of these can be used to 'dig'"}, - {OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"}, {"genstr", OPT_GENSTR, 's', "string to generate ASN1 structure from"}, + {OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"}, {"genconf", OPT_GENCONF, 's', "file to generate ASN1 structure from"}, - {OPT_MORE_STR, 0, 0, "(-inform will be ignored)"}, {"strictpem", OPT_STRICTPEM, 0, "do not attempt base64 decode outside PEM markers"}, {"item", OPT_ITEM, 's', "item to parse and print"}, + {OPT_MORE_STR, 0, 0, "(-inform will be ignored)"}, + + OPT_SECTION("Formatting"), + {"i", OPT_INDENT, 0, "indents the output"}, + {"dump", OPT_DUMP, 0, "unknown data in hex form"}, + {"dlimit", OPT_DLIMIT, 'p', + "dump the first arg bytes of unknown data in hex form"}, {NULL} }; @@ -152,6 +157,8 @@ int asn1parse_main(int argc, char **argv) break; } } + + /* No extra args. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; diff --git a/crypto/openssl/apps/build.info b/crypto/openssl/apps/build.info index 01537361820e..020d129f8cac 100644 --- a/crypto/openssl/apps/build.info +++ b/crypto/openssl/apps/build.info @@ -1,79 +1,90 @@ -{- our @apps_openssl_src = - qw(openssl.c - asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c - enc.c errstr.c - genpkey.c nseq.c passwd.c pkcs7.c pkcs8.c - pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c - s_client.c s_server.c s_time.c sess_id.c smime.c speed.c spkac.c - verify.c version.c x509.c rehash.c storeutl.c); - our @apps_lib_src = - ( qw(apps.c opt.c s_cb.c s_socket.c app_rand.c bf_prefix.c), - split(/\s+/, $target{apps_aux_src}) ); - our @apps_init_src = split(/\s+/, $target{apps_init_src}); - "" -} +SUBDIRS=lib -IF[{- !$disabled{apps} -}] - LIBS_NO_INST=libapps.a - SOURCE[libapps.a]={- join(" ", @apps_lib_src) -} - INCLUDE[libapps.a]=.. ../include +# Program init source, that don't have direct linkage with the rest of the +# source, and can therefore not be part of a library. +IF[{- !$disabled{uplink} -}] + $INITSRC=../ms/applink.c +ENDIF +IF[{- $config{target} =~ /^vms-/ -}] + $INITSRC=vms_decc_init.c +ENDIF - PROGRAMS=openssl - SOURCE[openssl]={- join(" ", @apps_init_src) -} - SOURCE[openssl]={- join(" ", @apps_openssl_src) -} - INCLUDE[openssl]=.. ../include - DEPEND[openssl]=libapps.a ../libssl - IF[{- !$disabled{'des'} -}] - SOURCE[openssl]=pkcs12.c - DEPEND[pkcs12.o]=progs.h - ENDIF - IF[{- !$disabled{'ec'} -}] - SOURCE[openssl]=ec.c ecparam.c - DEPEND[ec.o]=progs.h - DEPEND[ecparam.o]=progs.h - ENDIF - IF[{- !$disabled{'ocsp'} -}] - SOURCE[openssl]=ocsp.c - DEPEND[ocsp.o]=progs.h - ENDIF - IF[{- !$disabled{'srp'} -}] - SOURCE[openssl]=srp.c - DEPEND[srp.o]=progs.h - ENDIF - IF[{- !$disabled{'ts'} -}] - SOURCE[openssl]=ts.c - DEPEND[ts.o]=progs.h - ENDIF - IF[{- !$disabled{'dh'} -}] - SOURCE[openssl]=dhparam.c - DEPEND[dhparam.o]=progs.h - ENDIF - IF[{- !$disabled{'dsa'} -}] - SOURCE[openssl]=dsa.c dsaparam.c gendsa.c - DEPEND[dsa.o]=progs.h - DEPEND[dsaparam.o]=progs.h - DEPEND[gendsa.o]=progs.h - ENDIF - IF[{- !$disabled{'engine'} -}] - SOURCE[openssl]=engine.c - DEPEND[engine.o]=progs.h - ENDIF +# Source for the 'openssl' program +$OPENSSLSRC=\ + openssl.c \ + asn1parse.c ca.c ciphers.c crl.c crl2pkcs7.c dgst.c \ + enc.c errstr.c \ + genpkey.c kdf.c mac.c nseq.c passwd.c pkcs7.c \ + pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c \ + s_client.c s_server.c s_time.c sess_id.c smime.c speed.c \ + spkac.c verify.c version.c x509.c rehash.c storeutl.c \ + list.c info.c fipsinstall.c pkcs12.c +IF[{- !$disabled{'ec'} -}] + $OPENSSLSRC=$OPENSSLSRC ec.c ecparam.c +ENDIF +IF[{- !$disabled{'ocsp'} -}] + $OPENSSLSRC=$OPENSSLSRC ocsp.c +ENDIF +IF[{- !$disabled{'srp'} -}] + $OPENSSLSRC=$OPENSSLSRC srp.c +ENDIF +IF[{- !$disabled{'ts'} -}] + $OPENSSLSRC=$OPENSSLSRC ts.c +ENDIF +IF[{- !$disabled{'dh'} -}] +$OPENSSLSRC=$OPENSSLSRC dhparam.c +ENDIF +IF[{- !$disabled{'dsa'} -}] +$OPENSSLSRC=$OPENSSLSRC dsa.c dsaparam.c gendsa.c +ENDIF +IF[{- !$disabled{'engine'} -}] +$OPENSSLSRC=$OPENSSLSRC engine.c +ENDIF +IF[{- !$disabled{'rsa'} -}] +$OPENSSLSRC=$OPENSSLSRC rsa.c genrsa.c +ENDIF +IF[{- !$disabled{'deprecated-3.0'} -}] IF[{- !$disabled{'rsa'} -}] - SOURCE[openssl]=rsa.c rsautl.c genrsa.c - DEPEND[rsa.o]=progs.h - DEPEND[rsautl.o]=progs.h - DEPEND[genrsa.o]=progs.h + $OPENSSLSRC=$OPENSSLSRC rsautl.c ENDIF - IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-)/ -}] +ENDIF +IF[{- !$disabled{'cms'} -}] + $OPENSSLSRC=$OPENSSLSRC cms.c +ENDIF +IF[{- !$disabled{'cmp'} -}] + $OPENSSLSRC=$OPENSSLSRC cmp.c lib/cmp_mock_srv.c +ENDIF + +IF[{- !$disabled{apps} -}] + PROGRAMS=openssl + SOURCE[openssl]=$INITSRC $OPENSSLSRC + INCLUDE[openssl]=.. ../include include + DEPEND[openssl]=libapps.a ../libssl + + # The nocheck attribute is picked up by progs.pl as a signal not to look + # at that file; some systems may have locked it as the output file, and + # therefore don't allow it to be read at the same time, making progs.pl + # fail. + SOURCE[openssl]{nocheck}=progs.c + DEPEND[${OPENSSLSRC/.c/.o} progs.o]=progs.h + GENERATE[progs.c]=progs.pl "-C" $(APPS_OPENSSL) + GENERATE[progs.h]=progs.pl "-H" $(APPS_OPENSSL) + # progs.pl tries to read all 'openssl' sources, including progs.c, so we make + # sure things are generated in the correct order. + DEPEND[progs.h]=progs.c + # Because the files to look through may change (depends on $OPENSSLSRC), + # always depend on a changed configuration. + DEPEND[progs.c]=../configdata.pm + + IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-|BC-)/ -}] GENERATE[openssl.rc]=../util/mkrc.pl openssl SOURCE[openssl]=openssl.rc ENDIF - {- join("\n ", map { (my $x = $_) =~ s|\.c$|.o|; "DEPEND[$x]=progs.h" } - @apps_openssl_src) -} - GENERATE[progs.h]=progs.pl $(APPS_OPENSSL) - DEPEND[progs.h]=../configdata.pm - - SCRIPTS=CA.pl tsget.pl + SCRIPTS{misc}=CA.pl SOURCE[CA.pl]=CA.pl.in + # linkname tells build files that a symbolic link or copy of this script + # without extension must be installed as well. Unix or Unix lookalike only. + SCRIPTS{misc,linkname=tsget}=tsget.pl SOURCE[tsget.pl]=tsget.in ENDIF diff --git a/crypto/openssl/apps/ca.c b/crypto/openssl/apps/ca.c index ea375ca0b1d3..e14a5cff7802 100644 --- a/crypto/openssl/apps/ca.c +++ b/crypto/openssl/apps/ca.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -26,7 +26,7 @@ #ifndef W_OK # ifdef OPENSSL_SYS_VMS # include -# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) +# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_TANDEM) # include # endif #endif @@ -88,40 +88,46 @@ typedef enum { static char *lookup_conf(const CONF *conf, const char *group, const char *tag); -static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, +static int certify(X509 **xret, const char *infile, int informat, + EVP_PKEY *pkey, X509 *x509, + const char *dgst, + STACK_OF(OPENSSL_STRING) *sigopts, + STACK_OF(OPENSSL_STRING) *vfyopts, STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, const char *subj, unsigned long chtype, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, int batch, const char *ext_sect, CONF *conf, int verbose, unsigned long certopt, unsigned long nameopt, - int default_op, int ext_copy, int selfsign); -static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, + int default_op, int ext_copy, int selfsign, unsigned long dateopt); +static int certify_cert(X509 **xret, const char *infile, int certformat, + const char *passin, EVP_PKEY *pkey, X509 *x509, + const char *dgst, + STACK_OF(OPENSSL_STRING) *sigopts, + STACK_OF(OPENSSL_STRING) *vfyopts, STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, const char *subj, unsigned long chtype, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, int batch, const char *ext_sect, CONF *conf, int verbose, unsigned long certopt, - unsigned long nameopt, int default_op, int ext_copy); + unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt); static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, - X509 *x509, const EVP_MD *dgst, + X509 *x509, const char *dgst, STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, const char *subj, unsigned long chtype, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, const char *ext_sect, CONF *conf, int verbose, unsigned long certopt, - unsigned long nameopt, int default_op, int ext_copy); + unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt); static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, + const char *dgst, STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, const char *subj, unsigned long chtype, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, int batch, int verbose, X509_REQ *req, const char *ext_sect, CONF *conf, unsigned long certopt, unsigned long nameopt, - int default_op, int ext_copy, int selfsign); + int default_op, int ext_copy, int selfsign, unsigned long dateopt); static int get_certificate_status(const char *ser_status, CA_DB *db); static int do_updatedb(CA_DB *db); static int check_time_format(const char *str); @@ -132,77 +138,97 @@ static int make_revoked(X509_REVOKED *rev, const char *str); static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str); static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext); -static CONF *extconf = NULL; +static CONF *extfile_conf = NULL; static int preserve = 0; static int msie_hack = 0; typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_ENGINE, OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SUBJ, OPT_UTF8, OPT_CREATE_SERIAL, OPT_MULTIVALUE_RDN, OPT_STARTDATE, OPT_ENDDATE, OPT_DAYS, OPT_MD, OPT_POLICY, OPT_KEYFILE, OPT_KEYFORM, OPT_PASSIN, - OPT_KEY, OPT_CERT, OPT_SELFSIGN, OPT_IN, OPT_OUT, OPT_OUTDIR, + OPT_KEY, OPT_CERT, OPT_CERTFORM, OPT_SELFSIGN, + OPT_IN, OPT_INFORM, OPT_OUT, OPT_DATEOPT, OPT_OUTDIR, OPT_VFYOPT, OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN, - OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC, + OPT_GENCRL, OPT_MSIE_HACK, OPT_CRL_LASTUPDATE, OPT_CRL_NEXTUPDATE, + OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC, OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID, OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS, OPT_RAND_SERIAL, - OPT_R_ENUM, + OPT_R_ENUM, OPT_PROV_ENUM, /* Do not change the order here; see related case statements below */ OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE } OPTION_CHOICE; const OPTIONS ca_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [certreq...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"verbose", OPT_VERBOSE, '-', "Verbose output during processing"}, + {"outdir", OPT_OUTDIR, '/', "Where to put output cert"}, + {"in", OPT_IN, '<', "The input cert request(s)"}, + {"inform", OPT_INFORM, 'F', "CSR input format (DER or PEM); default PEM"}, + {"infiles", OPT_INFILES, '-', "The last argument, requests to process"}, + {"out", OPT_OUT, '>', "Where to put the output file(s)"}, + {"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."}, + {"notext", OPT_NOTEXT, '-', "Do not print the generated certificate"}, + {"batch", OPT_BATCH, '-', "Don't ask questions"}, + {"msie_hack", OPT_MSIE_HACK, '-', + "msie modifications to handle all Universal Strings"}, + {"ss_cert", OPT_SS_CERT, '<', "File contains a self signed cert to sign"}, + {"spkac", OPT_SPKAC, '<', + "File contains DN and signed public key and challenge"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Configuration"), {"config", OPT_CONFIG, 's', "A config file"}, {"name", OPT_NAME, 's', "The particular CA definition to use"}, + {"section", OPT_NAME, 's', "An alias for -name"}, + {"policy", OPT_POLICY, 's', "The CA 'policy' to support"}, + + OPT_SECTION("Certificate"), {"subj", OPT_SUBJ, 's', "Use arg instead of request's subject"}, - {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"}, + {"utf8", OPT_UTF8, '-', "Input characters are UTF8; default ASCII"}, {"create_serial", OPT_CREATE_SERIAL, '-', "If reading serial fails, create a new random serial"}, {"rand_serial", OPT_RAND_SERIAL, '-', "Always create a random serial; do not store it"}, {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-', - "Enable support for multivalued RDNs"}, + "Deprecated; multi-valued RDNs support is always on."}, {"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"}, {"enddate", OPT_ENDDATE, 's', "YYMMDDHHMMSSZ cert notAfter (overrides -days)"}, {"days", OPT_DAYS, 'p', "Number of days to certify the cert for"}, - {"md", OPT_MD, 's', "md to use; one of md2, md5, sha or sha1"}, - {"policy", OPT_POLICY, 's', "The CA 'policy' to support"}, - {"keyfile", OPT_KEYFILE, 's', "Private key"}, - {"keyform", OPT_KEYFORM, 'f', "Private key file format (PEM or ENGINE)"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"key", OPT_KEY, 's', "Key to decode the private key if it is encrypted"}, + {"extensions", OPT_EXTENSIONS, 's', + "Extension section (override value in config file)"}, + {"extfile", OPT_EXTFILE, '<', + "Configuration file with X509v3 extensions to add"}, + {"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"}, + {"noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN"}, + + OPT_SECTION("Signing"), + {"md", OPT_MD, 's', "Digest to use, such as sha256"}, + {"keyfile", OPT_KEYFILE, 's', "The CA private key"}, + {"keyform", OPT_KEYFORM, 'f', + "Private key file format (ENGINE, other values ignored)"}, + {"passin", OPT_PASSIN, 's', "Key and cert input file pass phrase source"}, + {"key", OPT_KEY, 's', + "Key to decrypt the private key or cert files if encrypted. Better use -passin"}, {"cert", OPT_CERT, '<', "The CA cert"}, + {"certform", OPT_CERTFORM, 'F', + "Certificate input format (DER/PEM/P12); has no effect"}, {"selfsign", OPT_SELFSIGN, '-', "Sign a cert with the key associated with it"}, - {"in", OPT_IN, '<', "The input PEM encoded cert request(s)"}, - {"out", OPT_OUT, '>', "Where to put the output file(s)"}, - {"outdir", OPT_OUTDIR, '/', "Where to put output cert"}, {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, - {"notext", OPT_NOTEXT, '-', "Do not print the generated certificate"}, - {"batch", OPT_BATCH, '-', "Don't ask questions"}, - {"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"}, - {"noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN"}, + {"vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form"}, + + OPT_SECTION("Revocation"), {"gencrl", OPT_GENCRL, '-', "Generate a new CRL"}, - {"msie_hack", OPT_MSIE_HACK, '-', - "msie modifications to handle all those universal strings"}, - {"crldays", OPT_CRLDAYS, 'p', "Days until the next CRL is due"}, - {"crlhours", OPT_CRLHOURS, 'p', "Hours until the next CRL is due"}, - {"crlsec", OPT_CRLSEC, 'p', "Seconds until the next CRL is due"}, - {"infiles", OPT_INFILES, '-', "The last argument, requests to process"}, - {"ss_cert", OPT_SS_CERT, '<', "File contains a self signed cert to sign"}, - {"spkac", OPT_SPKAC, '<', - "File contains DN and signed public key and challenge"}, - {"revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)"}, {"valid", OPT_VALID, 's', "Add a Valid(not-revoked) DB entry about a cert (given in file)"}, - {"extensions", OPT_EXTENSIONS, 's', - "Extension section (override value in config file)"}, - {"extfile", OPT_EXTFILE, '<', - "Configuration file with X509v3 extensions to add"}, {"status", OPT_STATUS, 's', "Shows cert status given the serial number"}, {"updatedb", OPT_UPDATEDB, '-', "Updates db for expired cert"}, {"crlexts", OPT_CRLEXTS, 's', @@ -214,10 +240,20 @@ const OPTIONS ca_options[] = { "sets compromise time to val and the revocation reason to keyCompromise"}, {"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's', "sets compromise time to val and the revocation reason to CACompromise"}, + {"crl_lastupdate", OPT_CRL_LASTUPDATE, 's', + "Sets the CRL lastUpdate time to val (YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ)"}, + {"crl_nextupdate", OPT_CRL_NEXTUPDATE, 's', + "Sets the CRL nextUpdate time to val (YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ)"}, + {"crldays", OPT_CRLDAYS, 'p', "Days until the next CRL is due"}, + {"crlhours", OPT_CRLHOURS, 'p', "Hours until the next CRL is due"}, + {"crlsec", OPT_CRLSEC, 'p', "Seconds until the next CRL is due"}, + {"revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)"}, + OPT_R_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"certreq", 0, 0, "Certificate requests to be signed (optional)"}, {NULL} }; @@ -229,19 +265,21 @@ int ca_main(int argc, char **argv) EVP_PKEY *pkey = NULL; BIO *in = NULL, *out = NULL, *Sout = NULL; ASN1_INTEGER *tmpser; - ASN1_TIME *tmptm; CA_DB *db = NULL; DB_ATTR db_attr; STACK_OF(CONF_VALUE) *attribs = NULL; - STACK_OF(OPENSSL_STRING) *sigopts = NULL; + STACK_OF(OPENSSL_STRING) *sigopts = NULL, *vfyopts = NULL; STACK_OF(X509) *cert_sk = NULL; X509_CRL *crl = NULL; - const EVP_MD *dgst = NULL; char *configfile = default_config_file, *section = NULL; - char *md = NULL, *policy = NULL, *keyfile = NULL; - char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL, *key = NULL; + char def_dgst[80] = ""; + char *dgst = NULL, *policy = NULL, *keyfile = NULL; + char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL; + int certformat = FORMAT_UNDEF, informat = FORMAT_UNDEF; + unsigned long dateopt = ASN1_DTFLGS_RFC822; const char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL; const char *extensions = NULL, *extfile = NULL, *passinarg = NULL; + char *passin = NULL; char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL; const char *serialfile = NULL, *subj = NULL; char *prog, *startdate = NULL, *enddate = NULL; @@ -251,11 +289,12 @@ int ca_main(int argc, char **argv) char *const *pp; const char *p; size_t outdirlen = 0; - int create_ser = 0, free_key = 0, total = 0, total_done = 0; + int create_ser = 0, free_passin = 0, total = 0, total_done = 0; int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE; - int keyformat = FORMAT_PEM, multirdn = 0, notext = 0, output_der = 0; + int keyformat = FORMAT_UNDEF, multirdn = 1, notext = 0, output_der = 0; int ret = 1, email_dn = 1, req = 0, verbose = 0, gencrl = 0, dorevoke = 0; - int rand_ser = 0, i, j, selfsign = 0, def_nid, def_ret; + int rand_ser = 0, i, j, selfsign = 0, def_ret; + char *crl_lastupdate = NULL, *crl_nextupdate = NULL; long crldays = 0, crlhours = 0, crlsec = 0, days = 0; unsigned long chtype = MBSTRING_ASC, certopt = 0; X509 *x509 = NULL, *x509p = NULL, *x = NULL; @@ -279,9 +318,17 @@ int ca_main(int argc, char **argv) req = 1; infile = opt_arg(); break; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; case OPT_OUT: outfile = opt_arg(); break; + case OPT_DATEOPT: + if (!set_dateopt(&dateopt, opt_arg())) + goto opthelp; + break; case OPT_VERBOSE: verbose = 1; break; @@ -305,7 +352,7 @@ int ca_main(int argc, char **argv) create_ser = 1; break; case OPT_MULTIVALUE_RDN: - multirdn = 1; + /* obsolete */ break; case OPT_STARTDATE: startdate = opt_arg(); @@ -317,7 +364,7 @@ int ca_main(int argc, char **argv) days = atoi(opt_arg()); break; case OPT_MD: - md = opt_arg(); + dgst = opt_arg(); break; case OPT_POLICY: policy = opt_arg(); @@ -336,12 +383,20 @@ int ca_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_KEY: - key = opt_arg(); + passin = opt_arg(); break; case OPT_CERT: certfile = opt_arg(); break; + case OPT_CERTFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &certformat)) + goto opthelp; + break; case OPT_SELFSIGN: selfsign = 1; break; @@ -354,6 +409,12 @@ int ca_main(int argc, char **argv) if (sigopts == NULL || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) goto end; break; + case OPT_VFYOPT: + if (vfyopts == NULL) + vfyopts = sk_OPENSSL_STRING_new_null(); + if (vfyopts == NULL || !sk_OPENSSL_STRING_push(vfyopts, opt_arg())) + goto end; + break; case OPT_NOTEXT: notext = 1; break; @@ -372,6 +433,12 @@ int ca_main(int argc, char **argv) case OPT_MSIE_HACK: msie_hack = 1; break; + case OPT_CRL_LASTUPDATE: + crl_lastupdate = opt_arg(); + break; + case OPT_CRL_NEXTUPDATE: + crl_nextupdate = opt_arg(); + break; case OPT_CRLDAYS: crldays = atol(opt_arg()); break; @@ -427,13 +494,13 @@ int ca_main(int argc, char **argv) break; } } + end_of_options: + /* Remaining args are files to certify. */ argc = opt_num_rest(); argv = opt_rest(); - BIO_printf(bio_err, "Using configuration from %s\n", configfile); - - if ((conf = app_load_config(configfile)) == NULL) + if ((conf = app_load_config_verbose(configfile, 1)) == NULL) goto end; if (configfile != default_config_file && !app_load_modules(conf)) goto end; @@ -456,12 +523,12 @@ int ca_main(int argc, char **argv) BIO_free(oid_bio); } } - if (!add_oid_section(conf)) { - ERR_print_errors(bio_err); + if (!add_oid_section(conf)) goto end; - } app_RAND_load_conf(conf, BASE_SECTION); + if (!app_RAND_load()) + goto end; f = NCONF_get_string(conf, section, STRING_MASK); if (f == NULL) @@ -495,8 +562,10 @@ int ca_main(int argc, char **argv) goto end; db = load_index(dbfile, &db_attr); - if (db == NULL) + if (db == NULL) { + BIO_printf(bio_err, "Problem with index file: %s (could not load/parse file)\n", dbfile); goto end; + } if (index_index(db) <= 0) goto end; @@ -513,16 +582,15 @@ int ca_main(int argc, char **argv) && (keyfile = lookup_conf(conf, section, ENV_PRIVATE_KEY)) == NULL) goto end; - if (key == NULL) { - free_key = 1; - if (!app_passwd(passinarg, NULL, &key, NULL)) { + if (passin == NULL) { + free_passin = 1; + if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } } - pkey = load_key(keyfile, keyformat, 0, key, e, "CA private key"); - if (key != NULL) - OPENSSL_cleanse(key, strlen(key)); + pkey = load_key(keyfile, keyformat, 0, passin, e, "CA private key"); + cleanse(passin); if (pkey == NULL) /* load_key() has already printed an appropriate message */ goto end; @@ -534,7 +602,7 @@ int ca_main(int argc, char **argv) && (certfile = lookup_conf(conf, section, ENV_CERTIFICATE)) == NULL) goto end; - x509 = load_cert(certfile, FORMAT_PEM, "CA certificate"); + x509 = load_cert_pass(certfile, certformat, 1, passin, "CA certificate"); if (x509 == NULL) goto end; @@ -624,8 +692,10 @@ int ca_main(int argc, char **argv) goto end; db = load_index(dbfile, &db_attr); - if (db == NULL) + if (db == NULL) { + BIO_printf(bio_err, "Problem with index file: %s (could not load/parse file)\n", dbfile); goto end; + } /* Lets check some fields */ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { @@ -703,7 +773,7 @@ int ca_main(int argc, char **argv) /*****************************************************************/ /* Read extensions config file */ if (extfile) { - if ((extconf = app_load_config(extfile)) == NULL) { + if ((extfile_conf = app_load_config(extfile)) == NULL) { ret = 1; goto end; } @@ -714,7 +784,7 @@ int ca_main(int argc, char **argv) /* We can have sections in the ext file */ if (extensions == NULL) { - extensions = NCONF_get_string(extconf, "default", "extensions"); + extensions = NCONF_get_string(extfile_conf, "default", "extensions"); if (extensions == NULL) extensions = "default"; } @@ -728,28 +798,25 @@ int ca_main(int argc, char **argv) } } - def_ret = EVP_PKEY_get_default_digest_nid(pkey, &def_nid); + def_ret = EVP_PKEY_get_default_digest_name(pkey, def_dgst, sizeof(def_dgst)); /* - * EVP_PKEY_get_default_digest_nid() returns 2 if the digest is + * EVP_PKEY_get_default_digest_name() returns 2 if the digest is * mandatory for this algorithm. */ - if (def_ret == 2 && def_nid == NID_undef) { + if (def_ret == 2 && strcmp(def_dgst, "UNDEF") == 0) { /* The signing algorithm requires there to be no digest */ - dgst = EVP_md_null(); - } else if (md == NULL - && (md = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL) { + dgst = NULL; + } else if (dgst == NULL + && (dgst = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL) { goto end; } else { - if (strcmp(md, "default") == 0) { + if (strcmp(dgst, "default") == 0) { if (def_ret <= 0) { BIO_puts(bio_err, "no default digest\n"); goto end; } - md = (char *)OBJ_nid2sn(def_nid); + dgst = def_dgst; } - - if (!opt_md(md, &dgst)) - goto end; } if (req) { @@ -761,8 +828,7 @@ int ca_main(int argc, char **argv) email_dn = 0; } if (verbose) - BIO_printf(bio_err, "message digest is %s\n", - OBJ_nid2ln(EVP_MD_type(dgst))); + BIO_printf(bio_err, "message digest is %s\n", dgst); if (policy == NULL && (policy = lookup_conf(conf, section, ENV_POLICY)) == NULL) goto end; @@ -778,7 +844,20 @@ int ca_main(int argc, char **argv) goto end; } - if (extconf == NULL) { + if (extfile_conf != NULL) { + /* Check syntax of extfile */ + X509V3_CTX ctx; + + X509V3_set_ctx_test(&ctx); + X509V3_set_nconf(&ctx, extfile_conf); + if (!X509V3_EXT_add_nconf(extfile_conf, &ctx, extensions, NULL)) { + BIO_printf(bio_err, + "Error checking certificate extensions from extfile section %s\n", + extensions); + ret = 1; + goto end; + } + } else { /* * no '-extfile' option, so we look for extensions in the main * configuration file @@ -789,13 +868,14 @@ int ca_main(int argc, char **argv) ERR_clear_error(); } if (extensions != NULL) { - /* Check syntax of file */ + /* Check syntax of config file section */ X509V3_CTX ctx; + X509V3_set_ctx_test(&ctx); X509V3_set_nconf(&ctx, conf); if (!X509V3_EXT_add_nconf(conf, &ctx, extensions, NULL)) { BIO_printf(bio_err, - "Error Loading extension section %s\n", + "Error checking certificate extension config section %s\n", extensions); ret = 1; goto end; @@ -874,7 +954,7 @@ int ca_main(int argc, char **argv) attribs, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, extensions, conf, verbose, certopt, get_nameopt(), default_op, - ext_copy); + ext_copy, dateopt); if (j < 0) goto end; if (j > 0) { @@ -890,12 +970,12 @@ int ca_main(int argc, char **argv) } if (ss_cert_file != NULL) { total++; - j = certify_cert(&x, ss_cert_file, pkey, x509, dgst, sigopts, - attribs, + j = certify_cert(&x, ss_cert_file, certformat, passin, pkey, + x509, dgst, sigopts, vfyopts, attribs, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, extensions, conf, verbose, certopt, get_nameopt(), default_op, - ext_copy); + ext_copy, dateopt); if (j < 0) goto end; if (j > 0) { @@ -911,10 +991,11 @@ int ca_main(int argc, char **argv) } if (infile != NULL) { total++; - j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db, + j = certify(&x, infile, informat, pkey, x509p, dgst, + sigopts, vfyopts, attribs, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, extensions, conf, verbose, - certopt, get_nameopt(), default_op, ext_copy, selfsign); + certopt, get_nameopt(), default_op, ext_copy, selfsign, dateopt); if (j < 0) goto end; if (j > 0) { @@ -930,10 +1011,12 @@ int ca_main(int argc, char **argv) } for (i = 0; i < argc; i++) { total++; - j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db, + j = certify(&x, argv[i], informat, pkey, x509p, dgst, + sigopts, vfyopts, + attribs, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, extensions, conf, verbose, - certopt, get_nameopt(), default_op, ext_copy, selfsign); + certopt, get_nameopt(), default_op, ext_copy, selfsign, dateopt); if (j < 0) goto end; if (j > 0) { @@ -996,7 +1079,7 @@ int ca_main(int argc, char **argv) for (i = 0; i < sk_X509_num(cert_sk); i++) { BIO *Cout = NULL; X509 *xi = sk_X509_value(cert_sk, i); - ASN1_INTEGER *serialNumber = X509_get_serialNumber(xi); + const ASN1_INTEGER *serialNumber = X509_get0_serialNumber(xi); const unsigned char *psn = ASN1_STRING_get0_data(serialNumber); const int snl = ASN1_STRING_length(serialNumber); const int filen_len = 2 * (snl > 0 ? snl : 1) + sizeof(".pem"); @@ -1067,11 +1150,12 @@ int ca_main(int argc, char **argv) if (crl_ext != NULL) { /* Check syntax of file */ X509V3_CTX ctx; + X509V3_set_ctx_test(&ctx); X509V3_set_nconf(&ctx, conf); if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) { BIO_printf(bio_err, - "Error Loading CRL extension section %s\n", crl_ext); + "Error checking CRL extension section %s\n", crl_ext); ret = 1; goto end; } @@ -1094,7 +1178,8 @@ int ca_main(int argc, char **argv) crlhours = 0; ERR_clear_error(); } - if ((crldays == 0) && (crlhours == 0) && (crlsec == 0)) { + if ((crl_nextupdate == NULL) && + (crldays == 0) && (crlhours == 0) && (crlsec == 0)) { BIO_printf(bio_err, "cannot lookup how long until the next CRL is issued\n"); goto end; @@ -1102,24 +1187,23 @@ int ca_main(int argc, char **argv) if (verbose) BIO_printf(bio_err, "making CRL\n"); - if ((crl = X509_CRL_new()) == NULL) + if ((crl = X509_CRL_new_ex(app_get0_libctx(), app_get0_propq())) == NULL) goto end; if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto end; - tmptm = ASN1_TIME_new(); - if (tmptm == NULL - || X509_gmtime_adj(tmptm, 0) == NULL - || !X509_CRL_set1_lastUpdate(crl, tmptm) - || X509_time_adj_ex(tmptm, crldays, crlhours * 60 * 60 + crlsec, - NULL) == NULL) { - BIO_puts(bio_err, "error setting CRL nextUpdate\n"); - ASN1_TIME_free(tmptm); + if (!set_crl_lastupdate(crl, crl_lastupdate)) { + BIO_puts(bio_err, "error setting CRL lastUpdate\n"); + ret = 1; goto end; } - X509_CRL_set1_nextUpdate(crl, tmptm); - ASN1_TIME_free(tmptm); + if (!set_crl_nextupdate(crl, crl_nextupdate, + crldays, crlhours, crlsec)) { + BIO_puts(bio_err, "error setting CRL nextUpdate\n"); + ret = 1; + goto end; + } for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { pp = sk_OPENSSL_PSTRING_value(db->db->data, i); @@ -1157,12 +1241,16 @@ int ca_main(int argc, char **argv) if (crl_ext != NULL || crlnumberfile != NULL) { X509V3_CTX crlctx; + X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0); X509V3_set_nconf(&crlctx, conf); if (crl_ext != NULL) - if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl)) + if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl)) { + BIO_printf(bio_err, + "Error adding CRL extensions from section %s\n", crl_ext); goto end; + } if (crlnumberfile != NULL) { tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL); if (!tmpser) @@ -1175,8 +1263,8 @@ int ca_main(int argc, char **argv) } } if (crl_ext != NULL || crl_v2) { - if (!X509_CRL_set_version(crl, 1)) - goto end; /* version 2 CRL */ + if (!X509_CRL_set_version(crl, X509_CRL_VERSION_2)) + goto end; } /* we have a CRL number that need updating */ @@ -1210,7 +1298,9 @@ int ca_main(int argc, char **argv) goto end; } else { X509 *revcert; - revcert = load_cert(infile, FORMAT_PEM, infile); + + revcert = load_cert_pass(infile, informat, 1, passin, + "certificate to be revoked"); if (revcert == NULL) goto end; if (dorevoke == 2) @@ -1239,17 +1329,19 @@ int ca_main(int argc, char **argv) BIO_free_all(in); sk_X509_pop_free(cert_sk, X509_free); - if (free_key) - OPENSSL_free(key); + cleanse(passin); + if (free_passin) + OPENSSL_free(passin); BN_free(serial); BN_free(crlnumber); free_index(db); sk_OPENSSL_STRING_free(sigopts); + sk_OPENSSL_STRING_free(vfyopts); EVP_PKEY_free(pkey); X509_free(x509); X509_CRL_free(crl); NCONF_free(conf); - NCONF_free(extconf); + NCONF_free(extfile_conf); release_engine(e); return ret; } @@ -1262,101 +1354,94 @@ static char *lookup_conf(const CONF *conf, const char *section, const char *tag) return entry; } -static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, +static int certify(X509 **xret, const char *infile, int informat, + EVP_PKEY *pkey, X509 *x509, + const char *dgst, + STACK_OF(OPENSSL_STRING) *sigopts, + STACK_OF(OPENSSL_STRING) *vfyopts, STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, const char *subj, unsigned long chtype, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, int batch, const char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, unsigned long nameopt, - int default_op, int ext_copy, int selfsign) + int default_op, int ext_copy, int selfsign, unsigned long dateopt) { X509_REQ *req = NULL; - BIO *in = NULL; EVP_PKEY *pktmp = NULL; int ok = -1, i; - in = BIO_new_file(infile, "r"); - if (in == NULL) { - ERR_print_errors(bio_err); + req = load_csr(infile, informat, "certificate request"); + if (req == NULL) goto end; - } - if ((req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL)) == NULL) { - BIO_printf(bio_err, "Error reading certificate request in %s\n", - infile); + if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) { + BIO_printf(bio_err, "Error unpacking public key\n"); goto end; } if (verbose) X509_REQ_print_ex(bio_err, req, nameopt, X509_FLAG_COMPAT); BIO_printf(bio_err, "Check that the request matches the signature\n"); + ok = 0; if (selfsign && !X509_REQ_check_private_key(req, pkey)) { BIO_printf(bio_err, "Certificate request and CA private key do not match\n"); - ok = 0; - goto end; - } - if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) { - BIO_printf(bio_err, "error unpacking public key\n"); goto end; } - i = X509_REQ_verify(req, pktmp); - pktmp = NULL; + i = do_X509_REQ_verify(req, pktmp, vfyopts); if (i < 0) { - ok = 0; - BIO_printf(bio_err, "Signature verification problems....\n"); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Signature verification problems...\n"); goto end; } if (i == 0) { - ok = 0; BIO_printf(bio_err, "Signature did not match the certificate request\n"); - ERR_print_errors(bio_err); goto end; - } else { - BIO_printf(bio_err, "Signature ok\n"); } + BIO_printf(bio_err, "Signature ok\n"); ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, verbose, req, ext_sect, lconf, certopt, nameopt, default_op, - ext_copy, selfsign); + ext_copy, selfsign, dateopt); end: + ERR_print_errors(bio_err); X509_REQ_free(req); - BIO_free(in); return ok; } -static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, +static int certify_cert(X509 **xret, const char *infile, int certformat, + const char *passin, EVP_PKEY *pkey, X509 *x509, + const char *dgst, + STACK_OF(OPENSSL_STRING) *sigopts, + STACK_OF(OPENSSL_STRING) *vfyopts, STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, const char *subj, unsigned long chtype, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, int batch, const char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, - unsigned long nameopt, int default_op, int ext_copy) + unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt) { - X509 *req = NULL; + X509 *template_cert = NULL; X509_REQ *rreq = NULL; EVP_PKEY *pktmp = NULL; int ok = -1, i; - if ((req = load_cert(infile, FORMAT_PEM, infile)) == NULL) + if ((template_cert = load_cert_pass(infile, certformat, 1, passin, + "template certificate")) == NULL) goto end; if (verbose) - X509_print(bio_err, req); + X509_print(bio_err, template_cert); BIO_printf(bio_err, "Check that the request matches the signature\n"); - if ((pktmp = X509_get0_pubkey(req)) == NULL) { + if ((pktmp = X509_get0_pubkey(template_cert)) == NULL) { BIO_printf(bio_err, "error unpacking public key\n"); goto end; } - i = X509_verify(req, pktmp); + i = do_X509_verify(template_cert, pktmp, vfyopts); if (i < 0) { ok = 0; BIO_printf(bio_err, "Signature verification problems....\n"); @@ -1370,30 +1455,31 @@ static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x BIO_printf(bio_err, "Signature ok\n"); } - if ((rreq = X509_to_X509_REQ(req, NULL, NULL)) == NULL) + if ((rreq = X509_to_X509_REQ(template_cert, NULL, NULL)) == NULL) goto end; ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op, - ext_copy, 0); + ext_copy, 0, dateopt); end: X509_REQ_free(rreq); - X509_free(req); + X509_free(template_cert); return ok; } static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, + const char *dgst, STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, const char *subj, unsigned long chtype, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, int batch, int verbose, X509_REQ *req, const char *ext_sect, CONF *lconf, unsigned long certopt, unsigned long nameopt, - int default_op, int ext_copy, int selfsign) + int default_op, int ext_copy, int selfsign, unsigned long dateopt) { - X509_NAME *name = NULL, *CAname = NULL, *subject = NULL; + const X509_NAME *name = NULL; + X509_NAME *CAname = NULL, *subject = NULL; const ASN1_TIME *tm; ASN1_STRING *str, *str2; ASN1_OBJECT *obj; @@ -1407,17 +1493,16 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, OPENSSL_STRING *irow = NULL; OPENSSL_STRING *rrow = NULL; char buf[25]; + X509V3_CTX ext_ctx; for (i = 0; i < DB_NUMBER; i++) row[i] = NULL; if (subj) { - X509_NAME *n = parse_name(subj, chtype, multirdn); + X509_NAME *n = parse_name(subj, chtype, multirdn, "subject"); - if (!n) { - ERR_print_errors(bio_err); + if (!n) goto end; - } X509_REQ_set_subject_name(req, n); X509_NAME_free(n); } @@ -1592,15 +1677,9 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, BIO_printf(bio_err, "Everything appears to be ok, creating and signing the certificate\n"); - if ((ret = X509_new()) == NULL) + if ((ret = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL) goto end; -#ifdef X509_V3 - /* Make it an X509 v3 certificate. */ - if (!X509_set_version(ret, 2)) - goto end; -#endif - if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL) goto end; if (selfsign) { @@ -1630,32 +1709,24 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, if (!i) goto end; + /* Initialize the context structure */ + X509V3_set_ctx(&ext_ctx, selfsign ? ret : x509, + ret, req, NULL, X509V3_CTX_REPLACE); + /* Lets add the extensions, if there are any */ if (ext_sect) { - X509V3_CTX ctx; - - /* Initialize the context structure */ - if (selfsign) - X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0); - else - X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0); - - if (extconf != NULL) { + if (extfile_conf != NULL) { if (verbose) BIO_printf(bio_err, "Extra configuration file found\n"); - /* Use the extconf configuration db LHASH */ - X509V3_set_nconf(&ctx, extconf); - - /* Test the structure (needed?) */ - /* X509V3_set_ctx_test(&ctx); */ + /* Use the extfile_conf configuration db LHASH */ + X509V3_set_nconf(&ext_ctx, extfile_conf); /* Adds exts contained in the configuration file */ - if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect, ret)) { + if (!X509V3_EXT_add_nconf(extfile_conf, &ext_ctx, ext_sect, ret)) { BIO_printf(bio_err, - "ERROR: adding extensions in section %s\n", + "Error adding certificate extensions from extfile section %s\n", ext_sect); - ERR_print_errors(bio_err); goto end; } if (verbose) @@ -1663,13 +1734,12 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, "Successfully added extensions from file.\n"); } else if (ext_sect) { /* We found extensions to be set from config file */ - X509V3_set_nconf(&ctx, lconf); + X509V3_set_nconf(&ext_ctx, lconf); - if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) { + if (!X509V3_EXT_add_nconf(lconf, &ext_ctx, ext_sect, ret)) { BIO_printf(bio_err, - "ERROR: adding extensions in section %s\n", + "Error adding certificate extensions from config section %s\n", ext_sect); - ERR_print_errors(bio_err); goto end; } @@ -1683,19 +1753,9 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, if (!copy_extensions(ret, req, ext_copy)) { BIO_printf(bio_err, "ERROR: adding extensions from request\n"); - ERR_print_errors(bio_err); goto end; } - { - const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(ret); - - if (exts != NULL && sk_X509_EXTENSION_num(exts) > 0) - /* Make it an X509 v3 certificate. */ - if (!X509_set_version(ret, 2)) - goto end; - } - if (verbose) BIO_printf(bio_err, "The subject name appears to be ok, checking data base for clashes\n"); @@ -1825,7 +1885,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, } BIO_printf(bio_err, "Certificate is to be certified until "); - ASN1_TIME_print(bio_err, X509_get0_notAfter(ret)); + ASN1_TIME_print_ex(bio_err, X509_get0_notAfter(ret), dateopt); if (days) BIO_printf(bio_err, " (%ld days)", days); BIO_printf(bio_err, "\n"); @@ -1853,7 +1913,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, !EVP_PKEY_missing_parameters(pkey)) EVP_PKEY_copy_parameters(pktmp, pkey); - if (!do_X509_sign(ret, pkey, dgst, sigopts)) + if (!do_X509_sign(ret, pkey, dgst, sigopts, &ext_ctx)) goto end; /* We now just add it to the database as DB_TYPE_VAL('V') */ @@ -1911,14 +1971,14 @@ static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext) } static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, - X509 *x509, const EVP_MD *dgst, + X509 *x509, const char *dgst, STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, const char *subj, unsigned long chtype, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, const char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, - unsigned long nameopt, int default_op, int ext_copy) + unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt) { STACK_OF(CONF_VALUE) *sk = NULL; LHASH_OF(CONF_VALUE) *parms = NULL; @@ -1941,7 +2001,6 @@ static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, parms = CONF_load(NULL, infile, &errline); if (parms == NULL) { BIO_printf(bio_err, "error on line %ld of %s\n", errline, infile); - ERR_print_errors(bio_err); goto end; } @@ -1959,10 +2018,8 @@ static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, * and we can use the same code as if you had a real X509 request. */ req = X509_REQ_new(); - if (req == NULL) { - ERR_print_errors(bio_err); + if (req == NULL) goto end; - } /* * Build up the subject name set. @@ -1993,7 +2050,6 @@ static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, if (spki == NULL) { BIO_printf(bio_err, "unable to load Netscape SPKAC structure\n"); - ERR_print_errors(bio_err); goto end; } } @@ -2035,7 +2091,7 @@ static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, 1, verbose, req, ext_sect, lconf, certopt, nameopt, default_op, - ext_copy, 0); + ext_copy, 0, dateopt); end: X509_REQ_free(req); CONF_free(parms); @@ -2062,7 +2118,7 @@ static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type, for (i = 0; i < DB_NUMBER; i++) row[i] = NULL; row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x509), NULL, 0); - bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509), NULL); + bn = ASN1_INTEGER_to_BN(X509_get0_serialNumber(x509), NULL); if (!bn) goto end; if (BN_is_zero(bn)) @@ -2313,7 +2369,7 @@ static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg) case REV_CRL_REASON: for (i = 0; i < 8; i++) { - if (strcasecmp(rev_arg, crl_reasons[i]) == 0) { + if (OPENSSL_strcasecmp(rev_arg, crl_reasons[i]) == 0) { reason = crl_reasons[i]; break; } @@ -2413,18 +2469,18 @@ static int make_revoked(X509_REVOKED *rev, const char *str) rtmp = ASN1_ENUMERATED_new(); if (rtmp == NULL || !ASN1_ENUMERATED_set(rtmp, reason_code)) goto end; - if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0)) + if (X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0) <= 0) goto end; } if (rev && comp_time) { - if (!X509_REVOKED_add1_ext_i2d - (rev, NID_invalidity_date, comp_time, 0, 0)) + if (X509_REVOKED_add1_ext_i2d + (rev, NID_invalidity_date, comp_time, 0, 0) <= 0) goto end; } if (rev && hold) { - if (!X509_REVOKED_add1_ext_i2d - (rev, NID_hold_instruction_code, hold, 0, 0)) + if (X509_REVOKED_add1_ext_i2d + (rev, NID_hold_instruction_code, hold, 0, 0) <= 0) goto end; } @@ -2530,7 +2586,7 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, } if (reason_str) { for (i = 0; i < NUM_REASONS; i++) { - if (strcasecmp(reason_str, crl_reasons[i]) == 0) { + if (OPENSSL_strcasecmp(reason_str, crl_reasons[i]) == 0) { reason_code = i; break; } diff --git a/crypto/openssl/apps/ciphers.c b/crypto/openssl/apps/ciphers.c index aade3fbf5671..42a0bb79f651 100644 --- a/crypto/openssl/apps/ciphers.c +++ b/crypto/openssl/apps/ciphers.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,9 +14,10 @@ #include "progs.h" #include #include +#include "s_apps.h" typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_STDNAME, OPT_CONVERT, OPT_SSL3, @@ -27,39 +28,50 @@ typedef enum OPTION_choice { OPT_PSK, OPT_SRP, OPT_CIPHERSUITES, - OPT_V, OPT_UPPER_V, OPT_S + OPT_V, OPT_UPPER_V, OPT_S, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS ciphers_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cipher]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Output"), {"v", OPT_V, '-', "Verbose listing of the SSL/TLS ciphers"}, {"V", OPT_UPPER_V, '-', "Even more verbose"}, + {"stdname", OPT_STDNAME, '-', "Show standard cipher names"}, + {"convert", OPT_CONVERT, 's', "Convert standard name into OpenSSL name"}, + + OPT_SECTION("Cipher specification"), {"s", OPT_S, '-', "Only supported ciphers"}, #ifndef OPENSSL_NO_SSL3 - {"ssl3", OPT_SSL3, '-', "SSL3 mode"}, + {"ssl3", OPT_SSL3, '-', "Ciphers compatible with SSL3"}, #endif #ifndef OPENSSL_NO_TLS1 - {"tls1", OPT_TLS1, '-', "TLS1 mode"}, + {"tls1", OPT_TLS1, '-', "Ciphers compatible with TLS1"}, #endif #ifndef OPENSSL_NO_TLS1_1 - {"tls1_1", OPT_TLS1_1, '-', "TLS1.1 mode"}, + {"tls1_1", OPT_TLS1_1, '-', "Ciphers compatible with TLS1.1"}, #endif #ifndef OPENSSL_NO_TLS1_2 - {"tls1_2", OPT_TLS1_2, '-', "TLS1.2 mode"}, + {"tls1_2", OPT_TLS1_2, '-', "Ciphers compatible with TLS1.2"}, #endif #ifndef OPENSSL_NO_TLS1_3 - {"tls1_3", OPT_TLS1_3, '-', "TLS1.3 mode"}, + {"tls1_3", OPT_TLS1_3, '-', "Ciphers compatible with TLS1.3"}, #endif - {"stdname", OPT_STDNAME, '-', "Show standard cipher names"}, #ifndef OPENSSL_NO_PSK - {"psk", OPT_PSK, '-', "include ciphersuites requiring PSK"}, + {"psk", OPT_PSK, '-', "Include ciphersuites requiring PSK"}, #endif #ifndef OPENSSL_NO_SRP - {"srp", OPT_SRP, '-', "include ciphersuites requiring SRP"}, + {"srp", OPT_SRP, '-', "(deprecated) Include ciphersuites requiring SRP"}, #endif - {"convert", OPT_CONVERT, 's', "Convert standard name into OpenSSL name"}, {"ciphersuites", OPT_CIPHERSUITES, 's', "Configure the TLSv1.3 ciphersuites to use"}, + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"cipher", 0, 0, "Cipher string to decode (optional)"}, {NULL} }; @@ -72,12 +84,6 @@ static unsigned int dummy_psk(SSL *ssl, const char *hint, char *identity, return 0; } #endif -#ifndef OPENSSL_NO_SRP -static char *dummy_srp(SSL *ssl, void *arg) -{ - return ""; -} -#endif int ciphers_main(int argc, char **argv) { @@ -159,13 +165,18 @@ int ciphers_main(int argc, char **argv) case OPT_CIPHERSUITES: ciphersuites = opt_arg(); break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* Optional arg is cipher name. */ argv = opt_rest(); argc = opt_num_rest(); - if (argc == 1) - ciphers = *argv; + ciphers = argv[0]; else if (argc != 0) goto opthelp; @@ -176,7 +187,7 @@ int ciphers_main(int argc, char **argv) goto end; } - ctx = SSL_CTX_new(meth); + ctx = SSL_CTX_new_ex(app_get0_libctx(), app_get0_propq(), meth); if (ctx == NULL) goto err; if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0) @@ -190,7 +201,7 @@ int ciphers_main(int argc, char **argv) #endif #ifndef OPENSSL_NO_SRP if (srp) - SSL_CTX_set_srp_client_pwd_callback(ctx, dummy_srp); + set_up_dummy_srp(ctx); #endif if (ciphersuites != NULL && !SSL_CTX_set_ciphersuites(ctx, ciphersuites)) { @@ -216,6 +227,10 @@ int ciphers_main(int argc, char **argv) if (!verbose) { for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i); + + if (!ossl_assert(c != NULL)) + continue; + p = SSL_CIPHER_get_name(c); if (p == NULL) break; @@ -231,6 +246,9 @@ int ciphers_main(int argc, char **argv) c = sk_SSL_CIPHER_value(sk, i); + if (!ossl_assert(c != NULL)) + continue; + if (Verbose) { unsigned long id = SSL_CIPHER_get_id(c); int id0 = (int)(id >> 24); @@ -248,7 +266,7 @@ int ciphers_main(int argc, char **argv) const char *nm = SSL_CIPHER_standard_name(c); if (nm == NULL) nm = "UNKNOWN"; - BIO_printf(bio_out, "%s - ", nm); + BIO_printf(bio_out, "%-45s - ", nm); } BIO_puts(bio_out, SSL_CIPHER_description(c, buf, sizeof(buf))); } diff --git a/crypto/openssl/apps/cmp.c b/crypto/openssl/apps/cmp.c new file mode 100644 index 000000000000..9b9e405bb248 --- /dev/null +++ b/crypto/openssl/apps/cmp.c @@ -0,0 +1,3023 @@ +/* + * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* This app is disabled when OPENSSL_NO_CMP is defined. */ + +#include +#include + +#include "apps.h" +#include "http_server.h" +#include "s_apps.h" +#include "progs.h" + +#include "cmp_mock_srv.h" + +/* tweaks needed due to missing unistd.h on Windows */ +#if defined(_WIN32) && !defined(__BORLANDC__) +# define access _access +#endif +#ifndef F_OK +# define F_OK 0 +#endif + +#include +#include +#include + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *prog; +static char *opt_config = NULL; +#define CMP_SECTION "cmp" +#define SECTION_NAME_MAX 40 /* max length of section name */ +#define DEFAULT_SECTION "default" +static char *opt_section = CMP_SECTION; +static int opt_verbosity = OSSL_CMP_LOG_INFO; + +static int read_config(void); + +static CONF *conf = NULL; /* OpenSSL config file context structure */ +static OSSL_CMP_CTX *cmp_ctx = NULL; /* the client-side CMP context */ + +/* the type of cmp command we want to send */ +typedef enum { + CMP_IR, + CMP_KUR, + CMP_CR, + CMP_P10CR, + CMP_RR, + CMP_GENM +} cmp_cmd_t; + +/* message transfer */ +#ifndef OPENSSL_NO_SOCK +static char *opt_server = NULL; +static char *opt_proxy = NULL; +static char *opt_no_proxy = NULL; +#endif +static char *opt_recipient = NULL; +static char *opt_path = NULL; +static int opt_keep_alive = 1; +static int opt_msg_timeout = -1; +static int opt_total_timeout = -1; + +/* server authentication */ +static char *opt_trusted = NULL; +static char *opt_untrusted = NULL; +static char *opt_srvcert = NULL; +static char *opt_expect_sender = NULL; +static int opt_ignore_keyusage = 0; +static int opt_unprotected_errors = 0; +static char *opt_extracertsout = NULL; +static char *opt_cacertsout = NULL; + +/* client authentication */ +static char *opt_ref = NULL; +static char *opt_secret = NULL; +static char *opt_cert = NULL; +static char *opt_own_trusted = NULL; +static char *opt_key = NULL; +static char *opt_keypass = NULL; +static char *opt_digest = NULL; +static char *opt_mac = NULL; +static char *opt_extracerts = NULL; +static int opt_unprotected_requests = 0; + +/* generic message */ +static char *opt_cmd_s = NULL; +static int opt_cmd = -1; +static char *opt_geninfo = NULL; +static char *opt_infotype_s = NULL; +static int opt_infotype = NID_undef; + +/* certificate enrollment */ +static char *opt_newkey = NULL; +static char *opt_newkeypass = NULL; +static char *opt_subject = NULL; +static char *opt_issuer = NULL; +static int opt_days = 0; +static char *opt_reqexts = NULL; +static char *opt_sans = NULL; +static int opt_san_nodefault = 0; +static char *opt_policies = NULL; +static char *opt_policy_oids = NULL; +static int opt_policy_oids_critical = 0; +static int opt_popo = OSSL_CRMF_POPO_NONE - 1; +static char *opt_csr = NULL; +static char *opt_out_trusted = NULL; +static int opt_implicit_confirm = 0; +static int opt_disable_confirm = 0; +static char *opt_certout = NULL; +static char *opt_chainout = NULL; + +/* certificate enrollment and revocation */ +static char *opt_oldcert = NULL; +static int opt_revreason = CRL_REASON_NONE; + +/* credentials format */ +static char *opt_certform_s = "PEM"; +static int opt_certform = FORMAT_PEM; +static char *opt_keyform_s = NULL; +static int opt_keyform = FORMAT_UNDEF; +static char *opt_otherpass = NULL; +static char *opt_engine = NULL; + +#ifndef OPENSSL_NO_SOCK +/* TLS connection */ +static int opt_tls_used = 0; +static char *opt_tls_cert = NULL; +static char *opt_tls_key = NULL; +static char *opt_tls_keypass = NULL; +static char *opt_tls_extra = NULL; +static char *opt_tls_trusted = NULL; +static char *opt_tls_host = NULL; +#endif + +/* client-side debugging */ +static int opt_batch = 0; +static int opt_repeat = 1; +static char *opt_reqin = NULL; +static int opt_reqin_new_tid = 0; +static char *opt_reqout = NULL; +static char *opt_rspin = NULL; +static char *opt_rspout = NULL; +static int opt_use_mock_srv = 0; + +/* mock server */ +#ifndef OPENSSL_NO_SOCK +static char *opt_port = NULL; +static int opt_max_msgs = 0; +#endif +static char *opt_srv_ref = NULL; +static char *opt_srv_secret = NULL; +static char *opt_srv_cert = NULL; +static char *opt_srv_key = NULL; +static char *opt_srv_keypass = NULL; + +static char *opt_srv_trusted = NULL; +static char *opt_srv_untrusted = NULL; +static char *opt_rsp_cert = NULL; +static char *opt_rsp_extracerts = NULL; +static char *opt_rsp_capubs = NULL; +static int opt_poll_count = 0; +static int opt_check_after = 1; +static int opt_grant_implicitconf = 0; + +static int opt_pkistatus = OSSL_CMP_PKISTATUS_accepted; +static int opt_failure = INT_MIN; +static int opt_failurebits = 0; +static char *opt_statusstring = NULL; +static int opt_send_error = 0; +static int opt_send_unprotected = 0; +static int opt_send_unprot_err = 0; +static int opt_accept_unprotected = 0; +static int opt_accept_unprot_err = 0; +static int opt_accept_raverified = 0; + +static X509_VERIFY_PARAM *vpm = NULL; + +typedef enum OPTION_choice { + OPT_COMMON, + OPT_CONFIG, OPT_SECTION, OPT_VERBOSITY, + + OPT_CMD, OPT_INFOTYPE, OPT_GENINFO, + + OPT_NEWKEY, OPT_NEWKEYPASS, OPT_SUBJECT, OPT_ISSUER, + OPT_DAYS, OPT_REQEXTS, + OPT_SANS, OPT_SAN_NODEFAULT, + OPT_POLICIES, OPT_POLICY_OIDS, OPT_POLICY_OIDS_CRITICAL, + OPT_POPO, OPT_CSR, + OPT_OUT_TRUSTED, OPT_IMPLICIT_CONFIRM, OPT_DISABLE_CONFIRM, + OPT_CERTOUT, OPT_CHAINOUT, + + OPT_OLDCERT, OPT_REVREASON, + +#ifndef OPENSSL_NO_SOCK + OPT_SERVER, OPT_PROXY, OPT_NO_PROXY, +#endif + OPT_RECIPIENT, OPT_PATH, + OPT_KEEP_ALIVE, OPT_MSG_TIMEOUT, OPT_TOTAL_TIMEOUT, + + OPT_TRUSTED, OPT_UNTRUSTED, OPT_SRVCERT, + OPT_EXPECT_SENDER, + OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS, + OPT_EXTRACERTSOUT, OPT_CACERTSOUT, + + OPT_REF, OPT_SECRET, OPT_CERT, OPT_OWN_TRUSTED, OPT_KEY, OPT_KEYPASS, + OPT_DIGEST, OPT_MAC, OPT_EXTRACERTS, + OPT_UNPROTECTED_REQUESTS, + + OPT_CERTFORM, OPT_KEYFORM, + OPT_OTHERPASS, +#ifndef OPENSSL_NO_ENGINE + OPT_ENGINE, +#endif + OPT_PROV_ENUM, + OPT_R_ENUM, + +#ifndef OPENSSL_NO_SOCK + OPT_TLS_USED, OPT_TLS_CERT, OPT_TLS_KEY, + OPT_TLS_KEYPASS, + OPT_TLS_EXTRA, OPT_TLS_TRUSTED, OPT_TLS_HOST, +#endif + + OPT_BATCH, OPT_REPEAT, + OPT_REQIN, OPT_REQIN_NEW_TID, OPT_REQOUT, OPT_RSPIN, OPT_RSPOUT, + OPT_USE_MOCK_SRV, + +#ifndef OPENSSL_NO_SOCK + OPT_PORT, OPT_MAX_MSGS, +#endif + OPT_SRV_REF, OPT_SRV_SECRET, + OPT_SRV_CERT, OPT_SRV_KEY, OPT_SRV_KEYPASS, + OPT_SRV_TRUSTED, OPT_SRV_UNTRUSTED, + OPT_RSP_CERT, OPT_RSP_EXTRACERTS, OPT_RSP_CAPUBS, + OPT_POLL_COUNT, OPT_CHECK_AFTER, + OPT_GRANT_IMPLICITCONF, + OPT_PKISTATUS, OPT_FAILURE, + OPT_FAILUREBITS, OPT_STATUSSTRING, + OPT_SEND_ERROR, OPT_SEND_UNPROTECTED, + OPT_SEND_UNPROT_ERR, OPT_ACCEPT_UNPROTECTED, + OPT_ACCEPT_UNPROT_ERR, OPT_ACCEPT_RAVERIFIED, + + OPT_V_ENUM +} OPTION_CHOICE; + +const OPTIONS cmp_options[] = { + /* entries must be in the same order as enumerated above!! */ + {"help", OPT_HELP, '-', "Display this summary"}, + {"config", OPT_CONFIG, 's', + "Configuration file to use. \"\" = none. Default from env variable OPENSSL_CONF"}, + {"section", OPT_SECTION, 's', + "Section(s) in config file to get options from. \"\" = 'default'. Default 'cmp'"}, + {"verbosity", OPT_VERBOSITY, 'N', + "Log level; 3=ERR, 4=WARN, 6=INFO, 7=DEBUG, 8=TRACE. Default 6 = INFO"}, + + OPT_SECTION("Generic message"), + {"cmd", OPT_CMD, 's', "CMP request to send: ir/cr/kur/p10cr/rr/genm"}, + {"infotype", OPT_INFOTYPE, 's', + "InfoType name for requesting specific info in genm, e.g. 'signKeyPairTypes'"}, + {"geninfo", OPT_GENINFO, 's', + "generalInfo integer values to place in request PKIHeader with given OID"}, + {OPT_MORE_STR, 0, 0, + "specified in the form :int:, e.g. \"1.2.3.4:int:56789\""}, + + OPT_SECTION("Certificate enrollment"), + {"newkey", OPT_NEWKEY, 's', + "Private or public key for the requested cert. Default: CSR key or client key"}, + {"newkeypass", OPT_NEWKEYPASS, 's', "New private key pass phrase source"}, + {"subject", OPT_SUBJECT, 's', + "Distinguished Name (DN) of subject to use in the requested cert template"}, + {OPT_MORE_STR, 0, 0, + "For kur, default is subject of -csr arg or reference cert (see -oldcert)"}, + {OPT_MORE_STR, 0, 0, + "this default is used for ir and cr only if no Subject Alt Names are set"}, + {"issuer", OPT_ISSUER, 's', + "DN of the issuer to place in the requested certificate template"}, + {OPT_MORE_STR, 0, 0, + "also used as recipient if neither -recipient nor -srvcert are given"}, + {"days", OPT_DAYS, 'N', + "Requested validity time of the new certificate in number of days"}, + {"reqexts", OPT_REQEXTS, 's', + "Name of config file section defining certificate request extensions."}, + {OPT_MORE_STR, 0, 0, + "Augments or replaces any extensions contained CSR given with -csr"}, + {"sans", OPT_SANS, 's', + "Subject Alt Names (IPADDR/DNS/URI) to add as (critical) cert req extension"}, + {"san_nodefault", OPT_SAN_NODEFAULT, '-', + "Do not take default SANs from reference certificate (see -oldcert)"}, + {"policies", OPT_POLICIES, 's', + "Name of config file section defining policies certificate request extension"}, + {"policy_oids", OPT_POLICY_OIDS, 's', + "Policy OID(s) to add as policies certificate request extension"}, + {"policy_oids_critical", OPT_POLICY_OIDS_CRITICAL, '-', + "Flag the policy OID(s) given with -policy_oids as critical"}, + {"popo", OPT_POPO, 'n', + "Proof-of-Possession (POPO) method to use for ir/cr/kur where"}, + {OPT_MORE_STR, 0, 0, + "-1 = NONE, 0 = RAVERIFIED, 1 = SIGNATURE (default), 2 = KEYENC"}, + {"csr", OPT_CSR, 's', + "PKCS#10 CSR file in PEM or DER format to convert or to use in p10cr"}, + {"out_trusted", OPT_OUT_TRUSTED, 's', + "Certificates to trust when verifying newly enrolled certificates"}, + {"implicit_confirm", OPT_IMPLICIT_CONFIRM, '-', + "Request implicit confirmation of newly enrolled certificates"}, + {"disable_confirm", OPT_DISABLE_CONFIRM, '-', + "Do not confirm newly enrolled certificate w/o requesting implicit"}, + {OPT_MORE_STR, 0, 0, + "confirmation. WARNING: This leads to behavior violating RFC 4210"}, + {"certout", OPT_CERTOUT, 's', + "File to save newly enrolled certificate"}, + {"chainout", OPT_CHAINOUT, 's', + "File to save the chain of newly enrolled certificate"}, + + OPT_SECTION("Certificate enrollment and revocation"), + + {"oldcert", OPT_OLDCERT, 's', + "Certificate to be updated (defaulting to -cert) or to be revoked in rr;"}, + {OPT_MORE_STR, 0, 0, + "also used as reference (defaulting to -cert) for subject DN and SANs."}, + {OPT_MORE_STR, 0, 0, + "Issuer is used as recipient unless -recipient, -srvcert, or -issuer given"}, + {"revreason", OPT_REVREASON, 'n', + "Reason code to include in revocation request (rr); possible values:"}, + {OPT_MORE_STR, 0, 0, + "0..6, 8..10 (see RFC5280, 5.3.1) or -1. Default -1 = none included"}, + + OPT_SECTION("Message transfer"), +#ifdef OPENSSL_NO_SOCK + {OPT_MORE_STR, 0, 0, + "NOTE: -server, -proxy, and -no_proxy not supported due to no-sock build"}, +#else + {"server", OPT_SERVER, 's', + "[http[s]://]address[:port][/path] of CMP server. Default port 80 or 443."}, + {OPT_MORE_STR, 0, 0, + "address may be a DNS name or an IP address; path can be overridden by -path"}, + {"proxy", OPT_PROXY, 's', + "[http[s]://]address[:port][/path] of HTTP(S) proxy to use; path is ignored"}, + {"no_proxy", OPT_NO_PROXY, 's', + "List of addresses of servers not to use HTTP(S) proxy for"}, + {OPT_MORE_STR, 0, 0, + "Default from environment variable 'no_proxy', else 'NO_PROXY', else none"}, +#endif + {"recipient", OPT_RECIPIENT, 's', + "DN of CA. Default: subject of -srvcert, -issuer, issuer of -oldcert or -cert"}, + {"path", OPT_PATH, 's', + "HTTP path (aka CMP alias) at the CMP server. Default from -server, else \"/\""}, + {"keep_alive", OPT_KEEP_ALIVE, 'N', + "Persistent HTTP connections. 0: no, 1 (the default): request, 2: require"}, + {"msg_timeout", OPT_MSG_TIMEOUT, 'N', + "Number of seconds allowed per CMP message round trip, or 0 for infinite"}, + {"total_timeout", OPT_TOTAL_TIMEOUT, 'N', + "Overall time an enrollment incl. polling may take. Default 0 = infinite"}, + + OPT_SECTION("Server authentication"), + {"trusted", OPT_TRUSTED, 's', + "Certificates to trust as chain roots when verifying signed CMP responses"}, + {OPT_MORE_STR, 0, 0, "unless -srvcert is given"}, + {"untrusted", OPT_UNTRUSTED, 's', + "Intermediate CA certs for chain construction for CMP/TLS/enrolled certs"}, + {"srvcert", OPT_SRVCERT, 's', + "Server cert to pin and trust directly when verifying signed CMP responses"}, + {"expect_sender", OPT_EXPECT_SENDER, 's', + "DN of expected sender of responses. Defaults to subject of -srvcert, if any"}, + {"ignore_keyusage", OPT_IGNORE_KEYUSAGE, '-', + "Ignore CMP signer cert key usage, else 'digitalSignature' must be allowed"}, + {"unprotected_errors", OPT_UNPROTECTED_ERRORS, '-', + "Accept missing or invalid protection of regular error messages and negative"}, + {OPT_MORE_STR, 0, 0, + "certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf"}, + {OPT_MORE_STR, 0, 0, + "WARNING: This setting leads to behavior allowing violation of RFC 4210"}, + {"extracertsout", OPT_EXTRACERTSOUT, 's', + "File to save extra certificates received in the extraCerts field"}, + {"cacertsout", OPT_CACERTSOUT, 's', + "File to save CA certificates received in the caPubs field of 'ip' messages"}, + + OPT_SECTION("Client authentication"), + {"ref", OPT_REF, 's', + "Reference value to use as senderKID in case no -cert is given"}, + {"secret", OPT_SECRET, 's', + "Prefer PBM (over signatures) for protecting msgs with given password source"}, + {"cert", OPT_CERT, 's', + "Client's CMP signer certificate; its public key must match the -key argument"}, + {OPT_MORE_STR, 0, 0, + "This also used as default reference for subject DN and SANs."}, + {OPT_MORE_STR, 0, 0, + "Any further certs included are appended to the untrusted certs"}, + {"own_trusted", OPT_OWN_TRUSTED, 's', + "Optional certs to verify chain building for own CMP signer cert"}, + {"key", OPT_KEY, 's', "CMP signer private key, not used when -secret given"}, + {"keypass", OPT_KEYPASS, 's', + "Client private key (and cert and old cert) pass phrase source"}, + {"digest", OPT_DIGEST, 's', + "Digest to use in message protection and POPO signatures. Default \"sha256\""}, + {"mac", OPT_MAC, 's', + "MAC algorithm to use in PBM-based message protection. Default \"hmac-sha1\""}, + {"extracerts", OPT_EXTRACERTS, 's', + "Certificates to append in extraCerts field of outgoing messages."}, + {OPT_MORE_STR, 0, 0, + "This can be used as the default CMP signer cert chain to include"}, + {"unprotected_requests", OPT_UNPROTECTED_REQUESTS, '-', + "Send messages without CMP-level protection"}, + + OPT_SECTION("Credentials format"), + {"certform", OPT_CERTFORM, 's', + "Format (PEM or DER) to use when saving a certificate to a file. Default PEM"}, + {"keyform", OPT_KEYFORM, 's', + "Format of the key input (ENGINE, other values ignored)"}, + {"otherpass", OPT_OTHERPASS, 's', + "Pass phrase source potentially needed for loading certificates of others"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', + "Use crypto engine with given identifier, possibly a hardware device."}, + {OPT_MORE_STR, 0, 0, + "Engines may also be defined in OpenSSL config file engine section."}, +#endif + OPT_PROV_OPTIONS, + OPT_R_OPTIONS, + + OPT_SECTION("TLS connection"), +#ifdef OPENSSL_NO_SOCK + {OPT_MORE_STR, 0, 0, + "NOTE: -tls_used and all other TLS options not supported due to no-sock build"}, +#else + {"tls_used", OPT_TLS_USED, '-', + "Enable using TLS (also when other TLS options are not set)"}, + {"tls_cert", OPT_TLS_CERT, 's', + "Client's TLS certificate. May include chain to be provided to TLS server"}, + {"tls_key", OPT_TLS_KEY, 's', + "Private key for the client's TLS certificate"}, + {"tls_keypass", OPT_TLS_KEYPASS, 's', + "Pass phrase source for the client's private TLS key (and TLS cert)"}, + {"tls_extra", OPT_TLS_EXTRA, 's', + "Extra certificates to provide to TLS server during TLS handshake"}, + {"tls_trusted", OPT_TLS_TRUSTED, 's', + "Trusted certificates to use for verifying the TLS server certificate;"}, + {OPT_MORE_STR, 0, 0, "this implies host name validation"}, + {"tls_host", OPT_TLS_HOST, 's', + "Address to be checked (rather than -server) during TLS host name validation"}, +#endif + + OPT_SECTION("Client-side debugging"), + {"batch", OPT_BATCH, '-', + "Do not interactively prompt for input when a password is required etc."}, + {"repeat", OPT_REPEAT, 'p', + "Invoke the transaction the given positive number of times. Default 1"}, + {"reqin", OPT_REQIN, 's', "Take sequence of CMP requests from file(s)"}, + {"reqin_new_tid", OPT_REQIN_NEW_TID, '-', + "Use fresh transactionID for CMP requests read from -reqin"}, + {"reqout", OPT_REQOUT, 's', "Save sequence of CMP requests to file(s)"}, + {"rspin", OPT_RSPIN, 's', + "Process sequence of CMP responses provided in file(s), skipping server"}, + {"rspout", OPT_RSPOUT, 's', "Save sequence of CMP responses to file(s)"}, + + {"use_mock_srv", OPT_USE_MOCK_SRV, '-', + "Use internal mock server at API level, bypassing socket-based HTTP"}, + + OPT_SECTION("Mock server"), +#ifdef OPENSSL_NO_SOCK + {OPT_MORE_STR, 0, 0, + "NOTE: -port and -max_msgs not supported due to no-sock build"}, +#else + {"port", OPT_PORT, 's', + "Act as HTTP-based mock server listening on given port"}, + {"max_msgs", OPT_MAX_MSGS, 'N', + "max number of messages handled by HTTP mock server. Default: 0 = unlimited"}, +#endif + + {"srv_ref", OPT_SRV_REF, 's', + "Reference value to use as senderKID of server in case no -srv_cert is given"}, + {"srv_secret", OPT_SRV_SECRET, 's', + "Password source for server authentication with a pre-shared key (secret)"}, + {"srv_cert", OPT_SRV_CERT, 's', "Certificate of the server"}, + {"srv_key", OPT_SRV_KEY, 's', + "Private key used by the server for signing messages"}, + {"srv_keypass", OPT_SRV_KEYPASS, 's', + "Server private key (and cert) pass phrase source"}, + + {"srv_trusted", OPT_SRV_TRUSTED, 's', + "Trusted certificates for client authentication"}, + {"srv_untrusted", OPT_SRV_UNTRUSTED, 's', + "Intermediate certs that may be useful for verifying CMP protection"}, + {"rsp_cert", OPT_RSP_CERT, 's', + "Certificate to be returned as mock enrollment result"}, + {"rsp_extracerts", OPT_RSP_EXTRACERTS, 's', + "Extra certificates to be included in mock certification responses"}, + {"rsp_capubs", OPT_RSP_CAPUBS, 's', + "CA certificates to be included in mock ip response"}, + {"poll_count", OPT_POLL_COUNT, 'N', + "Number of times the client must poll before receiving a certificate"}, + {"check_after", OPT_CHECK_AFTER, 'N', + "The check_after value (time to wait) to include in poll response"}, + {"grant_implicitconf", OPT_GRANT_IMPLICITCONF, '-', + "Grant implicit confirmation of newly enrolled certificate"}, + + {"pkistatus", OPT_PKISTATUS, 'N', + "PKIStatus to be included in server response. Possible values: 0..6"}, + {"failure", OPT_FAILURE, 'N', + "A single failure info bit number to include in server response, 0..26"}, + {"failurebits", OPT_FAILUREBITS, 'N', + "Number representing failure bits to include in server response, 0..2^27 - 1"}, + {"statusstring", OPT_STATUSSTRING, 's', + "Status string to be included in server response"}, + {"send_error", OPT_SEND_ERROR, '-', + "Force server to reply with error message"}, + {"send_unprotected", OPT_SEND_UNPROTECTED, '-', + "Send response messages without CMP-level protection"}, + {"send_unprot_err", OPT_SEND_UNPROT_ERR, '-', + "In case of negative responses, server shall send unprotected error messages,"}, + {OPT_MORE_STR, 0, 0, + "certificate responses (ip/cp/kup), and revocation responses (rp)."}, + {OPT_MORE_STR, 0, 0, + "WARNING: This setting leads to behavior violating RFC 4210"}, + {"accept_unprotected", OPT_ACCEPT_UNPROTECTED, '-', + "Accept missing or invalid protection of requests"}, + {"accept_unprot_err", OPT_ACCEPT_UNPROT_ERR, '-', + "Accept unprotected error messages from client"}, + {"accept_raverified", OPT_ACCEPT_RAVERIFIED, '-', + "Accept RAVERIFIED as proof-of-possession (POPO)"}, + + OPT_V_OPTIONS, + {NULL} +}; + +typedef union { + char **txt; + int *num; + long *num_long; +} varref; +static varref cmp_vars[] = { /* must be in same order as enumerated above! */ + {&opt_config}, {&opt_section}, {(char **)&opt_verbosity}, + + {&opt_cmd_s}, {&opt_infotype_s}, {&opt_geninfo}, + + {&opt_newkey}, {&opt_newkeypass}, {&opt_subject}, {&opt_issuer}, + {(char **)&opt_days}, {&opt_reqexts}, + {&opt_sans}, {(char **)&opt_san_nodefault}, + {&opt_policies}, {&opt_policy_oids}, {(char **)&opt_policy_oids_critical}, + {(char **)&opt_popo}, {&opt_csr}, + {&opt_out_trusted}, + {(char **)&opt_implicit_confirm}, {(char **)&opt_disable_confirm}, + {&opt_certout}, {&opt_chainout}, + + {&opt_oldcert}, {(char **)&opt_revreason}, + +#ifndef OPENSSL_NO_SOCK + {&opt_server}, {&opt_proxy}, {&opt_no_proxy}, +#endif + {&opt_recipient}, {&opt_path}, {(char **)&opt_keep_alive}, + {(char **)&opt_msg_timeout}, {(char **)&opt_total_timeout}, + + {&opt_trusted}, {&opt_untrusted}, {&opt_srvcert}, + {&opt_expect_sender}, + {(char **)&opt_ignore_keyusage}, {(char **)&opt_unprotected_errors}, + {&opt_extracertsout}, {&opt_cacertsout}, + + {&opt_ref}, {&opt_secret}, + {&opt_cert}, {&opt_own_trusted}, {&opt_key}, {&opt_keypass}, + {&opt_digest}, {&opt_mac}, {&opt_extracerts}, + {(char **)&opt_unprotected_requests}, + + {&opt_certform_s}, {&opt_keyform_s}, + {&opt_otherpass}, +#ifndef OPENSSL_NO_ENGINE + {&opt_engine}, +#endif + +#ifndef OPENSSL_NO_SOCK + {(char **)&opt_tls_used}, {&opt_tls_cert}, {&opt_tls_key}, + {&opt_tls_keypass}, + {&opt_tls_extra}, {&opt_tls_trusted}, {&opt_tls_host}, +#endif + + {(char **)&opt_batch}, {(char **)&opt_repeat}, + {&opt_reqin}, {(char **)&opt_reqin_new_tid}, + {&opt_reqout}, {&opt_rspin}, {&opt_rspout}, + + {(char **)&opt_use_mock_srv}, +#ifndef OPENSSL_NO_SOCK + {&opt_port}, {(char **)&opt_max_msgs}, +#endif + {&opt_srv_ref}, {&opt_srv_secret}, + {&opt_srv_cert}, {&opt_srv_key}, {&opt_srv_keypass}, + {&opt_srv_trusted}, {&opt_srv_untrusted}, + {&opt_rsp_cert}, {&opt_rsp_extracerts}, {&opt_rsp_capubs}, + {(char **)&opt_poll_count}, {(char **)&opt_check_after}, + {(char **)&opt_grant_implicitconf}, + {(char **)&opt_pkistatus}, {(char **)&opt_failure}, + {(char **)&opt_failurebits}, {&opt_statusstring}, + {(char **)&opt_send_error}, {(char **)&opt_send_unprotected}, + {(char **)&opt_send_unprot_err}, {(char **)&opt_accept_unprotected}, + {(char **)&opt_accept_unprot_err}, {(char **)&opt_accept_raverified}, + + {NULL} +}; + +#define FUNC (strcmp(OPENSSL_FUNC, "(unknown function)") == 0 \ + ? "CMP" : OPENSSL_FUNC) +#define CMP_print(bio, level, prefix, msg, a1, a2, a3) \ + ((void)(level > opt_verbosity ? 0 : \ + (BIO_printf(bio, "%s:%s:%d:CMP %s: " msg "\n", \ + FUNC, OPENSSL_FILE, OPENSSL_LINE, prefix, a1, a2, a3)))) +#define CMP_DEBUG(m, a1, a2, a3) \ + CMP_print(bio_out, OSSL_CMP_LOG_DEBUG, "debug", m, a1, a2, a3) +#define CMP_debug(msg) CMP_DEBUG(msg"%s%s%s", "", "", "") +#define CMP_debug1(msg, a1) CMP_DEBUG(msg"%s%s", a1, "", "") +#define CMP_debug2(msg, a1, a2) CMP_DEBUG(msg"%s", a1, a2, "") +#define CMP_debug3(msg, a1, a2, a3) CMP_DEBUG(msg, a1, a2, a3) +#define CMP_INFO(msg, a1, a2, a3) \ + CMP_print(bio_out, OSSL_CMP_LOG_INFO, "info", msg, a1, a2, a3) +#define CMP_info(msg) CMP_INFO(msg"%s%s%s", "", "", "") +#define CMP_info1(msg, a1) CMP_INFO(msg"%s%s", a1, "", "") +#define CMP_info2(msg, a1, a2) CMP_INFO(msg"%s", a1, a2, "") +#define CMP_info3(msg, a1, a2, a3) CMP_INFO(msg, a1, a2, a3) +#define CMP_WARN(m, a1, a2, a3) \ + CMP_print(bio_out, OSSL_CMP_LOG_WARNING, "warning", m, a1, a2, a3) +#define CMP_warn(msg) CMP_WARN(msg"%s%s%s", "", "", "") +#define CMP_warn1(msg, a1) CMP_WARN(msg"%s%s", a1, "", "") +#define CMP_warn2(msg, a1, a2) CMP_WARN(msg"%s", a1, a2, "") +#define CMP_warn3(msg, a1, a2, a3) CMP_WARN(msg, a1, a2, a3) +#define CMP_ERR(msg, a1, a2, a3) \ + CMP_print(bio_err, OSSL_CMP_LOG_ERR, "error", msg, a1, a2, a3) +#define CMP_err(msg) CMP_ERR(msg"%s%s%s", "", "", "") +#define CMP_err1(msg, a1) CMP_ERR(msg"%s%s", a1, "", "") +#define CMP_err2(msg, a1, a2) CMP_ERR(msg"%s", a1, a2, "") +#define CMP_err3(msg, a1, a2, a3) CMP_ERR(msg, a1, a2, a3) + +static int print_to_bio_out(const char *func, const char *file, int line, + OSSL_CMP_severity level, const char *msg) +{ + return OSSL_CMP_print_to_bio(bio_out, func, file, line, level, msg); +} + +static int print_to_bio_err(const char *func, const char *file, int line, + OSSL_CMP_severity level, const char *msg) +{ + return OSSL_CMP_print_to_bio(bio_err, func, file, line, level, msg); +} + +static int set_verbosity(int level) +{ + if (level < OSSL_CMP_LOG_EMERG || level > OSSL_CMP_LOG_MAX) { + CMP_err1("Logging verbosity level %d out of range (0 .. 8)", level); + return 0; + } + opt_verbosity = level; + return 1; +} + +static EVP_PKEY *load_key_pwd(const char *uri, int format, + const char *pass, ENGINE *eng, const char *desc) +{ + char *pass_string = get_passwd(pass, desc); + EVP_PKEY *pkey = load_key(uri, format, 0, pass_string, eng, desc); + + clear_free(pass_string); + return pkey; +} + +static X509 *load_cert_pwd(const char *uri, const char *pass, const char *desc) +{ + X509 *cert; + char *pass_string = get_passwd(pass, desc); + + cert = load_cert_pass(uri, FORMAT_UNDEF, 0, pass_string, desc); + clear_free(pass_string); + return cert; +} + +static X509_REQ *load_csr_autofmt(const char *infile, const char *desc) +{ + X509_REQ *csr; + BIO *bio_bak = bio_err; + + bio_err = NULL; /* do not show errors on more than one try */ + csr = load_csr(infile, FORMAT_PEM, desc); + bio_err = bio_bak; + if (csr == NULL) { + ERR_clear_error(); + csr = load_csr(infile, FORMAT_ASN1, desc); + } + if (csr == NULL) { + ERR_print_errors(bio_err); + BIO_printf(bio_err, "error: unable to load %s from file '%s'\n", desc, + infile); + } else { + EVP_PKEY *pkey = X509_REQ_get0_pubkey(csr); + int ret = do_X509_REQ_verify(csr, pkey, NULL /* vfyopts */); + + if (pkey == NULL || ret < 0) + CMP_warn("error while verifying CSR self-signature"); + else if (ret == 0) + CMP_warn("CSR self-signature does not match the contents"); + } + return csr; +} + +/* set expected host name/IP addr and clears the email addr in the given ts */ +static int truststore_set_host_etc(X509_STORE *ts, const char *host) +{ + X509_VERIFY_PARAM *ts_vpm = X509_STORE_get0_param(ts); + + /* first clear any host names, IP, and email addresses */ + if (!X509_VERIFY_PARAM_set1_host(ts_vpm, NULL, 0) + || !X509_VERIFY_PARAM_set1_ip(ts_vpm, NULL, 0) + || !X509_VERIFY_PARAM_set1_email(ts_vpm, NULL, 0)) + return 0; + X509_VERIFY_PARAM_set_hostflags(ts_vpm, + X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT | + X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); + return (host != NULL && X509_VERIFY_PARAM_set1_ip_asc(ts_vpm, host)) + || X509_VERIFY_PARAM_set1_host(ts_vpm, host, 0); +} + +/* write OSSL_CMP_MSG DER-encoded to the specified file name item */ +static int write_PKIMESSAGE(const OSSL_CMP_MSG *msg, char **filenames) +{ + char *file; + + if (msg == NULL || filenames == NULL) { + CMP_err("NULL arg to write_PKIMESSAGE"); + return 0; + } + if (*filenames == NULL) { + CMP_err("not enough file names provided for writing PKIMessage"); + return 0; + } + + file = *filenames; + *filenames = next_item(file); + if (OSSL_CMP_MSG_write(file, msg) < 0) { + CMP_err1("cannot write PKIMessage to file '%s'", file); + return 0; + } + return 1; +} + +/* read DER-encoded OSSL_CMP_MSG from the specified file name item */ +static OSSL_CMP_MSG *read_PKIMESSAGE(char **filenames) +{ + char *file; + OSSL_CMP_MSG *ret; + + if (filenames == NULL) { + CMP_err("NULL arg to read_PKIMESSAGE"); + return NULL; + } + if (*filenames == NULL) { + CMP_err("not enough file names provided for reading PKIMessage"); + return NULL; + } + + file = *filenames; + *filenames = next_item(file); + + ret = OSSL_CMP_MSG_read(file, app_get0_libctx(), app_get0_propq()); + if (ret == NULL) + CMP_err1("cannot read PKIMessage from file '%s'", file); + return ret; +} + +/*- + * Sends the PKIMessage req and on success place the response in *res + * basically like OSSL_CMP_MSG_http_perform(), but in addition allows + * to dump the sequence of requests and responses to files and/or + * to take the sequence of requests and responses from files. + */ +static OSSL_CMP_MSG *read_write_req_resp(OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *req) +{ + OSSL_CMP_MSG *req_new = NULL; + OSSL_CMP_MSG *res = NULL; + OSSL_CMP_PKIHEADER *hdr; + const char *prev_opt_rspin = opt_rspin; + + if (req != NULL && opt_reqout != NULL + && !write_PKIMESSAGE(req, &opt_reqout)) + goto err; + if (opt_reqin != NULL && opt_rspin == NULL) { + if ((req_new = read_PKIMESSAGE(&opt_reqin)) == NULL) + goto err; + /*- + * The transaction ID in req_new read from opt_reqin may not be fresh. + * In this case the server may complain "Transaction id already in use." + * The following workaround unfortunately requires re-protection. + */ + if (opt_reqin_new_tid + && !OSSL_CMP_MSG_update_transactionID(ctx, req_new)) + goto err; + } + + if (opt_rspin != NULL) { + res = read_PKIMESSAGE(&opt_rspin); + } else { + const OSSL_CMP_MSG *actual_req = opt_reqin != NULL ? req_new : req; + + res = opt_use_mock_srv + ? OSSL_CMP_CTX_server_perform(ctx, actual_req) + : OSSL_CMP_MSG_http_perform(ctx, actual_req); + } + if (res == NULL) + goto err; + + if (opt_reqin != NULL || prev_opt_rspin != NULL) { + /* need to satisfy nonce and transactionID checks */ + ASN1_OCTET_STRING *nonce; + ASN1_OCTET_STRING *tid; + + hdr = OSSL_CMP_MSG_get0_header(res); + nonce = OSSL_CMP_HDR_get0_recipNonce(hdr); + tid = OSSL_CMP_HDR_get0_transactionID(hdr); + if (!OSSL_CMP_CTX_set1_senderNonce(ctx, nonce) + || !OSSL_CMP_CTX_set1_transactionID(ctx, tid)) { + OSSL_CMP_MSG_free(res); + res = NULL; + goto err; + } + } + + if (opt_rspout != NULL && !write_PKIMESSAGE(res, &opt_rspout)) { + OSSL_CMP_MSG_free(res); + res = NULL; + } + + err: + OSSL_CMP_MSG_free(req_new); + return res; +} + +static int set_name(const char *str, + int (*set_fn) (OSSL_CMP_CTX *ctx, const X509_NAME *name), + OSSL_CMP_CTX *ctx, const char *desc) +{ + if (str != NULL) { + X509_NAME *n = parse_name(str, MBSTRING_ASC, 1, desc); + + if (n == NULL) + return 0; + if (!(*set_fn) (ctx, n)) { + X509_NAME_free(n); + CMP_err("out of memory"); + return 0; + } + X509_NAME_free(n); + } + return 1; +} + +static int set_gennames(OSSL_CMP_CTX *ctx, char *names, const char *desc) +{ + char *next; + + for (; names != NULL; names = next) { + GENERAL_NAME *n; + + next = next_item(names); + if (strcmp(names, "critical") == 0) { + (void)OSSL_CMP_CTX_set_option(ctx, + OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL, + 1); + continue; + } + + /* try IP address first, then URI or domain name */ + (void)ERR_set_mark(); + n = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_IPADD, names, 0); + if (n == NULL) + n = a2i_GENERAL_NAME(NULL, NULL, NULL, + strchr(names, ':') != NULL ? GEN_URI : GEN_DNS, + names, 0); + (void)ERR_pop_to_mark(); + + if (n == NULL) { + CMP_err2("bad syntax of %s '%s'", desc, names); + return 0; + } + if (!OSSL_CMP_CTX_push1_subjectAltName(ctx, n)) { + GENERAL_NAME_free(n); + CMP_err("out of memory"); + return 0; + } + GENERAL_NAME_free(n); + } + return 1; +} + +static X509_STORE *load_trusted(char *input, int for_new_cert, const char *desc) +{ + X509_STORE *ts = load_certstore(input, opt_otherpass, desc, vpm); + + if (ts == NULL) + return NULL; + X509_STORE_set_verify_cb(ts, X509_STORE_CTX_print_verify_cb); + + /* copy vpm to store */ + if (X509_STORE_set1_param(ts, vpm /* may be NULL */) + && (for_new_cert || truststore_set_host_etc(ts, NULL))) + return ts; + BIO_printf(bio_err, "error setting verification parameters for %s\n", desc); + OSSL_CMP_CTX_print_errors(cmp_ctx); + X509_STORE_free(ts); + return NULL; +} + +typedef int (*add_X509_stack_fn_t)(void *ctx, const STACK_OF(X509) *certs); + +static int setup_certs(char *files, const char *desc, void *ctx, + add_X509_stack_fn_t set1_fn) +{ + STACK_OF(X509) *certs; + int ok; + + if (files == NULL) + return 1; + if ((certs = load_certs_multifile(files, opt_otherpass, desc, vpm)) == NULL) + return 0; + ok = (*set1_fn)(ctx, certs); + sk_X509_pop_free(certs, X509_free); + return ok; +} + + +/* + * parse and transform some options, checking their syntax. + * Returns 1 on success, 0 on error + */ +static int transform_opts(void) +{ + if (opt_cmd_s != NULL) { + if (!strcmp(opt_cmd_s, "ir")) { + opt_cmd = CMP_IR; + } else if (!strcmp(opt_cmd_s, "kur")) { + opt_cmd = CMP_KUR; + } else if (!strcmp(opt_cmd_s, "cr")) { + opt_cmd = CMP_CR; + } else if (!strcmp(opt_cmd_s, "p10cr")) { + opt_cmd = CMP_P10CR; + } else if (!strcmp(opt_cmd_s, "rr")) { + opt_cmd = CMP_RR; + } else if (!strcmp(opt_cmd_s, "genm")) { + opt_cmd = CMP_GENM; + } else { + CMP_err1("unknown cmp command '%s'", opt_cmd_s); + return 0; + } + } else { + CMP_err("no cmp command to execute"); + return 0; + } + +#ifndef OPENSSL_NO_ENGINE +# define FORMAT_OPTIONS (OPT_FMT_PEMDER | OPT_FMT_PKCS12 | OPT_FMT_ENGINE) +#else +# define FORMAT_OPTIONS (OPT_FMT_PEMDER | OPT_FMT_PKCS12) +#endif + + if (opt_keyform_s != NULL + && !opt_format(opt_keyform_s, FORMAT_OPTIONS, &opt_keyform)) { + CMP_err("unknown option given for key loading format"); + return 0; + } + +#undef FORMAT_OPTIONS + + if (opt_certform_s != NULL + && !opt_format(opt_certform_s, OPT_FMT_PEMDER, &opt_certform)) { + CMP_err("unknown option given for certificate storing format"); + return 0; + } + + return 1; +} + +static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) +{ + OSSL_CMP_CTX *ctx; /* extra CMP (client) ctx partly used by server */ + OSSL_CMP_SRV_CTX *srv_ctx = ossl_cmp_mock_srv_new(app_get0_libctx(), + app_get0_propq()); + + if (srv_ctx == NULL) + return NULL; + ctx = OSSL_CMP_SRV_CTX_get0_cmp_ctx(srv_ctx); + + if (opt_srv_ref == NULL) { + if (opt_srv_cert == NULL) { + /* opt_srv_cert should determine the sender */ + CMP_err("must give -srv_ref for mock server if no -srv_cert given"); + goto err; + } + } else { + if (!OSSL_CMP_CTX_set1_referenceValue(ctx, (unsigned char *)opt_srv_ref, + strlen(opt_srv_ref))) + goto err; + } + + if (opt_srv_secret != NULL) { + int res; + char *pass_str = get_passwd(opt_srv_secret, "PBMAC secret of mock server"); + + if (pass_str != NULL) { + cleanse(opt_srv_secret); + res = OSSL_CMP_CTX_set1_secretValue(ctx, (unsigned char *)pass_str, + strlen(pass_str)); + clear_free(pass_str); + if (res == 0) + goto err; + } + } else if (opt_srv_cert == NULL) { + CMP_err("mock server credentials must be given if -use_mock_srv or -port is used"); + goto err; + } else { + CMP_warn("mock server will not be able to handle PBM-protected requests since -srv_secret is not given"); + } + + if (opt_srv_secret == NULL + && ((opt_srv_cert == NULL) != (opt_srv_key == NULL))) { + CMP_err("must give both -srv_cert and -srv_key options or neither"); + goto err; + } + if (opt_srv_cert != NULL) { + X509 *srv_cert = load_cert_pwd(opt_srv_cert, opt_srv_keypass, + "certificate of the mock server"); + + if (srv_cert == NULL || !OSSL_CMP_CTX_set1_cert(ctx, srv_cert)) { + X509_free(srv_cert); + goto err; + } + X509_free(srv_cert); + } + if (opt_srv_key != NULL) { + EVP_PKEY *pkey = load_key_pwd(opt_srv_key, opt_keyform, + opt_srv_keypass, + engine, "private key for mock server cert"); + + if (pkey == NULL || !OSSL_CMP_CTX_set1_pkey(ctx, pkey)) { + EVP_PKEY_free(pkey); + goto err; + } + EVP_PKEY_free(pkey); + } + cleanse(opt_srv_keypass); + + if (opt_srv_trusted != NULL) { + X509_STORE *ts = + load_trusted(opt_srv_trusted, 0, "certs trusted by mock server"); + + if (ts == NULL || !OSSL_CMP_CTX_set0_trustedStore(ctx, ts)) { + X509_STORE_free(ts); + goto err; + } + } else { + CMP_warn("mock server will not be able to handle signature-protected requests since -srv_trusted is not given"); + } + if (!setup_certs(opt_srv_untrusted, + "untrusted certificates for mock server", ctx, + (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_untrusted)) + goto err; + + if (opt_rsp_cert == NULL) { + CMP_warn("no -rsp_cert given for mock server"); + } else { + X509 *cert = load_cert_pwd(opt_rsp_cert, opt_keypass, + "cert to be returned by the mock server"); + + if (cert == NULL) + goto err; + /* from server perspective the server is the client */ + if (!ossl_cmp_mock_srv_set1_certOut(srv_ctx, cert)) { + X509_free(cert); + goto err; + } + X509_free(cert); + } + if (!setup_certs(opt_rsp_extracerts, + "CMP extra certificates for mock server", srv_ctx, + (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_chainOut)) + goto err; + if (!setup_certs(opt_rsp_capubs, "caPubs for mock server", srv_ctx, + (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_caPubsOut)) + goto err; + (void)ossl_cmp_mock_srv_set_pollCount(srv_ctx, opt_poll_count); + (void)ossl_cmp_mock_srv_set_checkAfterTime(srv_ctx, opt_check_after); + if (opt_grant_implicitconf) + (void)OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(srv_ctx, 1); + + if (opt_failure != INT_MIN) { /* option has been set explicity */ + if (opt_failure < 0 || OSSL_CMP_PKIFAILUREINFO_MAX < opt_failure) { + CMP_err1("-failure out of range, should be >= 0 and <= %d", + OSSL_CMP_PKIFAILUREINFO_MAX); + goto err; + } + if (opt_failurebits != 0) + CMP_warn("-failurebits overrides -failure"); + else + opt_failurebits = 1 << opt_failure; + } + if ((unsigned)opt_failurebits > OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN) { + CMP_err("-failurebits out of range"); + goto err; + } + if (!ossl_cmp_mock_srv_set_statusInfo(srv_ctx, opt_pkistatus, + opt_failurebits, opt_statusstring)) + goto err; + + if (opt_send_error) + (void)ossl_cmp_mock_srv_set_send_error(srv_ctx, 1); + + if (opt_send_unprotected) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_SEND, 1); + if (opt_send_unprot_err) + (void)OSSL_CMP_SRV_CTX_set_send_unprotected_errors(srv_ctx, 1); + if (opt_accept_unprotected) + (void)OSSL_CMP_SRV_CTX_set_accept_unprotected(srv_ctx, 1); + if (opt_accept_unprot_err) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, 1); + if (opt_accept_raverified) + (void)OSSL_CMP_SRV_CTX_set_accept_raverified(srv_ctx, 1); + + return srv_ctx; + + err: + ossl_cmp_mock_srv_free(srv_ctx); + return NULL; +} + +/* + * set up verification aspects of OSSL_CMP_CTX w.r.t. opts from config file/CLI. + * Returns pointer on success, NULL on error + */ +static int setup_verification_ctx(OSSL_CMP_CTX *ctx) +{ + if (!setup_certs(opt_untrusted, "untrusted certificates", ctx, + (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_untrusted)) + return 0; + + if (opt_srvcert != NULL || opt_trusted != NULL) { + X509 *srvcert; + X509_STORE *ts; + int ok; + + if (opt_srvcert != NULL) { + if (opt_trusted != NULL) { + CMP_warn("-trusted option is ignored since -srvcert option is present"); + opt_trusted = NULL; + } + if (opt_recipient != NULL) { + CMP_warn("-recipient option is ignored since -srvcert option is present"); + opt_recipient = NULL; + } + srvcert = load_cert_pwd(opt_srvcert, opt_otherpass, + "directly trusted CMP server certificate"); + ok = srvcert != NULL && OSSL_CMP_CTX_set1_srvCert(ctx, srvcert); + X509_free(srvcert); + if (!ok) + return 0; + } + if (opt_trusted != NULL) { + /* + * the 0 arg below clears any expected host/ip/email address; + * opt_expect_sender is used instead + */ + ts = load_trusted(opt_trusted, 0, "certs trusted by client"); + + if (ts == NULL || !OSSL_CMP_CTX_set0_trustedStore(ctx, ts)) { + X509_STORE_free(ts); + return 0; + } + } + } + + if (opt_ignore_keyusage) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_IGNORE_KEYUSAGE, 1); + + if (opt_unprotected_errors) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, 1); + + if (opt_out_trusted != NULL) { /* for use in OSSL_CMP_certConf_cb() */ + X509_VERIFY_PARAM *out_vpm = NULL; + X509_STORE *out_trusted = + load_trusted(opt_out_trusted, 1, + "trusted certs for verifying newly enrolled cert"); + + if (out_trusted == NULL) + return 0; + /* ignore any -attime here, new certs are current anyway */ + out_vpm = X509_STORE_get0_param(out_trusted); + X509_VERIFY_PARAM_clear_flags(out_vpm, X509_V_FLAG_USE_CHECK_TIME); + + (void)OSSL_CMP_CTX_set_certConf_cb_arg(ctx, out_trusted); + } + + if (opt_disable_confirm) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_DISABLE_CONFIRM, 1); + + if (opt_implicit_confirm) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM, 1); + + return 1; +} + +#ifndef OPENSSL_NO_SOCK +/* + * set up ssl_ctx for the OSSL_CMP_CTX based on options from config file/CLI. + * Returns pointer on success, NULL on error + */ +static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, const char *host, + ENGINE *engine) +{ + STACK_OF(X509) *untrusted = OSSL_CMP_CTX_get0_untrusted(ctx); + EVP_PKEY *pkey = NULL; + X509_STORE *trust_store = NULL; + SSL_CTX *ssl_ctx; + int i; + + ssl_ctx = SSL_CTX_new(TLS_client_method()); + if (ssl_ctx == NULL) + return NULL; + + if (opt_tls_trusted != NULL) { + trust_store = load_trusted(opt_tls_trusted, 0, "trusted TLS certs"); + if (trust_store == NULL) + goto err; + SSL_CTX_set_cert_store(ssl_ctx, trust_store); + } + + if (opt_tls_cert != NULL && opt_tls_key != NULL) { + X509 *cert; + STACK_OF(X509) *certs = NULL; + int ok; + + if (!load_cert_certs(opt_tls_cert, &cert, &certs, 0, opt_tls_keypass, + "TLS client certificate (optionally with chain)", + vpm)) + /* need opt_tls_keypass if opt_tls_cert is encrypted PKCS#12 file */ + goto err; + + ok = SSL_CTX_use_certificate(ssl_ctx, cert) > 0; + X509_free(cert); + + /* + * Any further certs and any untrusted certs are used for constructing + * the chain to be provided with the TLS client cert to the TLS server. + */ + if (!ok || !SSL_CTX_set0_chain(ssl_ctx, certs)) { + CMP_err1("unable to use client TLS certificate file '%s'", + opt_tls_cert); + sk_X509_pop_free(certs, X509_free); + goto err; + } + for (i = 0; i < sk_X509_num(untrusted); i++) { + cert = sk_X509_value(untrusted, i); + if (!SSL_CTX_add1_chain_cert(ssl_ctx, cert)) { + CMP_err("could not add untrusted cert to TLS client cert chain"); + goto err; + } + } + + { + X509_VERIFY_PARAM *tls_vpm = NULL; + unsigned long bak_flags = 0; /* compiler warns without init */ + + if (trust_store != NULL) { + tls_vpm = X509_STORE_get0_param(trust_store); + bak_flags = X509_VERIFY_PARAM_get_flags(tls_vpm); + /* disable any cert status/revocation checking etc. */ + X509_VERIFY_PARAM_clear_flags(tls_vpm, + ~(X509_V_FLAG_USE_CHECK_TIME + | X509_V_FLAG_NO_CHECK_TIME)); + } + CMP_debug("trying to build cert chain for own TLS cert"); + if (SSL_CTX_build_cert_chain(ssl_ctx, + SSL_BUILD_CHAIN_FLAG_UNTRUSTED | + SSL_BUILD_CHAIN_FLAG_NO_ROOT)) { + CMP_debug("success building cert chain for own TLS cert"); + } else { + OSSL_CMP_CTX_print_errors(ctx); + CMP_warn("could not build cert chain for own TLS cert"); + } + if (trust_store != NULL) + X509_VERIFY_PARAM_set_flags(tls_vpm, bak_flags); + } + + /* If present we append to the list also the certs from opt_tls_extra */ + if (opt_tls_extra != NULL) { + STACK_OF(X509) *tls_extra = load_certs_multifile(opt_tls_extra, + opt_otherpass, + "extra certificates for TLS", + vpm); + int res = 1; + + if (tls_extra == NULL) + goto err; + for (i = 0; i < sk_X509_num(tls_extra); i++) { + cert = sk_X509_value(tls_extra, i); + if (res != 0) + res = SSL_CTX_add_extra_chain_cert(ssl_ctx, cert); + if (res == 0) + X509_free(cert); + } + sk_X509_free(tls_extra); + if (res == 0) { + BIO_printf(bio_err, "error: unable to add TLS extra certs\n"); + goto err; + } + } + + pkey = load_key_pwd(opt_tls_key, opt_keyform, opt_tls_keypass, + engine, "TLS client private key"); + cleanse(opt_tls_keypass); + if (pkey == NULL) + goto err; + /* + * verify the key matches the cert, + * not using SSL_CTX_check_private_key(ssl_ctx) + * because it gives poor and sometimes misleading diagnostics + */ + if (!X509_check_private_key(SSL_CTX_get0_certificate(ssl_ctx), + pkey)) { + CMP_err2("TLS private key '%s' does not match the TLS certificate '%s'\n", + opt_tls_key, opt_tls_cert); + EVP_PKEY_free(pkey); + pkey = NULL; /* otherwise, for some reason double free! */ + goto err; + } + if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) <= 0) { + CMP_err1("unable to use TLS client private key '%s'", opt_tls_key); + EVP_PKEY_free(pkey); + pkey = NULL; /* otherwise, for some reason double free! */ + goto err; + } + EVP_PKEY_free(pkey); /* we do not need the handle any more */ + } + if (opt_tls_trusted != NULL) { + /* enable and parameterize server hostname/IP address check */ + if (!truststore_set_host_etc(trust_store, + opt_tls_host != NULL ? opt_tls_host : host)) + goto err; + SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); + } + return ssl_ctx; + err: + SSL_CTX_free(ssl_ctx); + return NULL; +} +#endif /* OPENSSL_NO_SOCK */ + +/* + * set up protection aspects of OSSL_CMP_CTX based on options from config + * file/CLI while parsing options and checking their consistency. + * Returns 1 on success, 0 on error + */ +static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) +{ + if (!opt_unprotected_requests && opt_secret == NULL && opt_key == NULL) { + CMP_err("must give -key or -secret unless -unprotected_requests is used"); + return 0; + } + + if (opt_ref == NULL && opt_cert == NULL && opt_subject == NULL) { + /* cert or subject should determine the sender */ + CMP_err("must give -ref if no -cert and no -subject given"); + return 0; + } + if (!opt_secret && ((opt_cert == NULL) != (opt_key == NULL))) { + CMP_err("must give both -cert and -key options or neither"); + return 0; + } + if (opt_secret != NULL) { + char *pass_string = get_passwd(opt_secret, "PBMAC"); + int res; + + if (pass_string != NULL) { + cleanse(opt_secret); + res = OSSL_CMP_CTX_set1_secretValue(ctx, + (unsigned char *)pass_string, + strlen(pass_string)); + clear_free(pass_string); + if (res == 0) + return 0; + } + if (opt_cert != NULL || opt_key != NULL) + CMP_warn("-cert and -key not used for protection since -secret is given"); + } + if (opt_ref != NULL + && !OSSL_CMP_CTX_set1_referenceValue(ctx, (unsigned char *)opt_ref, + strlen(opt_ref))) + return 0; + + if (opt_key != NULL) { + EVP_PKEY *pkey = load_key_pwd(opt_key, opt_keyform, opt_keypass, engine, + "private key for CMP client certificate"); + + if (pkey == NULL || !OSSL_CMP_CTX_set1_pkey(ctx, pkey)) { + EVP_PKEY_free(pkey); + return 0; + } + EVP_PKEY_free(pkey); + } + if (opt_secret == NULL && opt_srvcert == NULL && opt_trusted == NULL) + CMP_warn("will not authenticate server due to missing -secret, -trusted, or -srvcert"); + + if (opt_cert != NULL) { + X509 *cert; + STACK_OF(X509) *certs = NULL; + X509_STORE *own_trusted = NULL; + int ok; + + if (!load_cert_certs(opt_cert, &cert, &certs, 0, opt_keypass, + "CMP client certificate (optionally with chain)", + vpm)) + /* opt_keypass is needed if opt_cert is an encrypted PKCS#12 file */ + return 0; + ok = OSSL_CMP_CTX_set1_cert(ctx, cert); + X509_free(cert); + if (!ok) { + CMP_err("out of memory"); + } else { + if (opt_own_trusted != NULL) { + own_trusted = load_trusted(opt_own_trusted, 0, + "trusted certs for verifying own CMP signer cert"); + ok = own_trusted != NULL; + } + ok = ok && OSSL_CMP_CTX_build_cert_chain(ctx, own_trusted, certs); + } + X509_STORE_free(own_trusted); + sk_X509_pop_free(certs, X509_free); + if (!ok) + return 0; + } else if (opt_own_trusted != NULL) { + CMP_warn("-own_trusted option is ignored without -cert"); + } + + if (!setup_certs(opt_extracerts, "extra certificates for CMP", ctx, + (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_extraCertsOut)) + return 0; + cleanse(opt_otherpass); + + if (opt_unprotected_requests) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_SEND, 1); + + if (opt_digest != NULL) { + int digest = OBJ_ln2nid(opt_digest); + + if (digest == NID_undef) { + CMP_err1("digest algorithm name not recognized: '%s'", opt_digest); + return 0; + } + if (!OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_DIGEST_ALGNID, digest) + || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_OWF_ALGNID, digest)) { + CMP_err1("digest algorithm name not supported: '%s'", opt_digest); + return 0; + } + } + + if (opt_mac != NULL) { + int mac = OBJ_ln2nid(opt_mac); + if (mac == NID_undef) { + CMP_err1("MAC algorithm name not recognized: '%s'", opt_mac); + return 0; + } + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_MAC_ALGNID, mac); + } + return 1; +} + +/* + * set up IR/CR/KUR/CertConf/RR specific parts of the OSSL_CMP_CTX + * based on options from config file/CLI. + * Returns pointer on success, NULL on error + */ +static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) +{ + X509_REQ *csr = NULL; + X509_EXTENSIONS *exts = NULL; + X509V3_CTX ext_ctx; + + if (opt_subject == NULL + && opt_csr == NULL && opt_oldcert == NULL && opt_cert == NULL + && opt_cmd != CMP_RR && opt_cmd != CMP_GENM) + CMP_warn("no -subject given; no -csr or -oldcert or -cert available for fallback"); + + if (opt_cmd == CMP_IR || opt_cmd == CMP_CR || opt_cmd == CMP_KUR) { + if (opt_newkey == NULL && opt_key == NULL && opt_csr == NULL) { + CMP_err("missing -newkey (or -key) to be certified and no -csr given"); + return 0; + } + if (opt_certout == NULL) { + CMP_err("-certout not given, nowhere to save newly enrolled certificate"); + return 0; + } + if (!set_name(opt_subject, OSSL_CMP_CTX_set1_subjectName, ctx, "subject") + || !set_name(opt_issuer, OSSL_CMP_CTX_set1_issuer, ctx, "issuer")) + return 0; + } else { + const char *msg = "option is ignored for commands other than 'ir', 'cr', and 'kur'"; + + if (opt_subject != NULL) { + if (opt_ref == NULL && opt_cert == NULL) { + /* use subject as default sender unless oldcert subject is used */ + if (!set_name(opt_subject, OSSL_CMP_CTX_set1_subjectName, ctx, "subject")) + return 0; + } else { + CMP_warn1("-subject %s since -ref or -cert is given", msg); + } + } + if (opt_issuer != NULL) + CMP_warn1("-issuer %s", msg); + if (opt_reqexts != NULL) + CMP_warn1("-reqexts %s", msg); + if (opt_san_nodefault) + CMP_warn1("-san_nodefault %s", msg); + if (opt_sans != NULL) + CMP_warn1("-sans %s", msg); + if (opt_policies != NULL) + CMP_warn1("-policies %s", msg); + if (opt_policy_oids != NULL) + CMP_warn1("-policy_oids %s", msg); + } + if (opt_cmd == CMP_KUR) { + char *ref_cert = opt_oldcert != NULL ? opt_oldcert : opt_cert; + + if (ref_cert == NULL && opt_csr == NULL) { + CMP_err("missing -oldcert for certificate to be updated and no -csr given"); + return 0; + } + if (opt_subject != NULL) + CMP_warn2("given -subject '%s' overrides the subject of '%s' for KUR", + opt_subject, ref_cert != NULL ? ref_cert : opt_csr); + } + if (opt_cmd == CMP_RR) { + if (opt_oldcert == NULL && opt_csr == NULL) { + CMP_err("missing -oldcert for certificate to be revoked and no -csr given"); + return 0; + } + if (opt_oldcert != NULL && opt_csr != NULL) + CMP_warn("ignoring -csr since certificate to be revoked is given"); + } + if (opt_cmd == CMP_P10CR && opt_csr == NULL) { + CMP_err("missing PKCS#10 CSR for p10cr"); + return 0; + } + + if (opt_recipient == NULL && opt_srvcert == NULL && opt_issuer == NULL + && opt_oldcert == NULL && opt_cert == NULL) + CMP_warn("missing -recipient, -srvcert, -issuer, -oldcert or -cert; recipient will be set to \"NULL-DN\""); + + if (opt_cmd == CMP_P10CR || opt_cmd == CMP_RR) { + const char *msg = "option is ignored for 'p10cr' and 'rr' commands"; + + if (opt_newkeypass != NULL) + CMP_warn1("-newkeytype %s", msg); + if (opt_newkey != NULL) + CMP_warn1("-newkey %s", msg); + if (opt_days != 0) + CMP_warn1("-days %s", msg); + if (opt_popo != OSSL_CRMF_POPO_NONE - 1) + CMP_warn1("-popo %s", msg); + } else if (opt_newkey != NULL) { + const char *file = opt_newkey; + const int format = opt_keyform; + const char *pass = opt_newkeypass; + const char *desc = "new private key for cert to be enrolled"; + EVP_PKEY *pkey; + int priv = 1; + BIO *bio_bak = bio_err; + + bio_err = NULL; /* suppress diagnostics on first try loading key */ + pkey = load_key_pwd(file, format, pass, engine, desc); + bio_err = bio_bak; + if (pkey == NULL) { + ERR_clear_error(); + desc = opt_csr == NULL + ? "fallback public key for cert to be enrolled" + : "public key for checking cert resulting from p10cr"; + pkey = load_pubkey(file, format, 0, pass, engine, desc); + priv = 0; + } + cleanse(opt_newkeypass); + if (pkey == NULL || !OSSL_CMP_CTX_set0_newPkey(ctx, priv, pkey)) { + EVP_PKEY_free(pkey); + return 0; + } + } + + if (opt_days > 0 + && !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_VALIDITY_DAYS, + opt_days)) { + CMP_err("could not set requested cert validity period"); + return 0; + } + + if (opt_policies != NULL && opt_policy_oids != NULL) { + CMP_err("cannot have policies both via -policies and via -policy_oids"); + return 0; + } + + if (opt_csr != NULL) { + if (opt_cmd == CMP_GENM) { + CMP_warn("-csr option is ignored for command 'genm'"); + } else { + if ((csr = load_csr_autofmt(opt_csr, "PKCS#10 CSR")) == NULL) + return 0; + if (!OSSL_CMP_CTX_set1_p10CSR(ctx, csr)) + goto oom; + } + } + if (opt_reqexts != NULL || opt_policies != NULL) { + if ((exts = sk_X509_EXTENSION_new_null()) == NULL) + goto oom; + X509V3_set_ctx(&ext_ctx, NULL, NULL, csr, NULL, X509V3_CTX_REPLACE); + X509V3_set_nconf(&ext_ctx, conf); + if (opt_reqexts != NULL + && !X509V3_EXT_add_nconf_sk(conf, &ext_ctx, opt_reqexts, &exts)) { + CMP_err1("cannot load certificate request extension section '%s'", + opt_reqexts); + goto exts_err; + } + if (opt_policies != NULL + && !X509V3_EXT_add_nconf_sk(conf, &ext_ctx, opt_policies, &exts)) { + CMP_err1("cannot load policy cert request extension section '%s'", + opt_policies); + goto exts_err; + } + OSSL_CMP_CTX_set0_reqExtensions(ctx, exts); + } + X509_REQ_free(csr); + /* After here, must not goto oom/exts_err */ + + if (OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) && opt_sans != NULL) { + CMP_err("cannot have Subject Alternative Names both via -reqexts and via -sans"); + return 0; + } + if (!set_gennames(ctx, opt_sans, "Subject Alternative Name")) + return 0; + + if (opt_san_nodefault) { + if (opt_sans != NULL) + CMP_warn("-opt_san_nodefault has no effect when -sans is used"); + (void)OSSL_CMP_CTX_set_option(ctx, + OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT, 1); + } + + if (opt_policy_oids_critical) { + if (opt_policy_oids == NULL) + CMP_warn("-opt_policy_oids_critical has no effect unless -policy_oids is given"); + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_POLICIES_CRITICAL, 1); + } + + while (opt_policy_oids != NULL) { + ASN1_OBJECT *policy; + POLICYINFO *pinfo; + char *next = next_item(opt_policy_oids); + + if ((policy = OBJ_txt2obj(opt_policy_oids, 1)) == 0) { + CMP_err1("unknown policy OID '%s'", opt_policy_oids); + return 0; + } + + if ((pinfo = POLICYINFO_new()) == NULL) { + ASN1_OBJECT_free(policy); + return 0; + } + pinfo->policyid = policy; + + if (!OSSL_CMP_CTX_push0_policy(ctx, pinfo)) { + CMP_err1("cannot add policy with OID '%s'", opt_policy_oids); + POLICYINFO_free(pinfo); + return 0; + } + opt_policy_oids = next; + } + + if (opt_popo >= OSSL_CRMF_POPO_NONE) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_POPO_METHOD, opt_popo); + + if (opt_oldcert != NULL) { + if (opt_cmd == CMP_GENM) { + CMP_warn("-oldcert option is ignored for command 'genm'"); + } else { + X509 *oldcert = load_cert_pwd(opt_oldcert, opt_keypass, + opt_cmd == CMP_KUR ? + "certificate to be updated" : + opt_cmd == CMP_RR ? + "certificate to be revoked" : + "reference certificate (oldcert)"); + /* opt_keypass needed if opt_oldcert is an encrypted PKCS#12 file */ + + if (oldcert == NULL) + return 0; + if (!OSSL_CMP_CTX_set1_oldCert(ctx, oldcert)) { + X509_free(oldcert); + CMP_err("out of memory"); + return 0; + } + X509_free(oldcert); + } + } + cleanse(opt_keypass); + if (opt_revreason > CRL_REASON_NONE) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_REVOCATION_REASON, + opt_revreason); + + return 1; + + oom: + CMP_err("out of memory"); + exts_err: + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + X509_REQ_free(csr); + return 0; +} + +static int handle_opt_geninfo(OSSL_CMP_CTX *ctx) +{ + long value; + ASN1_OBJECT *type; + ASN1_INTEGER *aint; + ASN1_TYPE *val; + OSSL_CMP_ITAV *itav; + char *endstr; + char *valptr = strchr(opt_geninfo, ':'); + + if (valptr == NULL) { + CMP_err("missing ':' in -geninfo option"); + return 0; + } + valptr[0] = '\0'; + valptr++; + + if (OPENSSL_strncasecmp(valptr, "int:", 4) != 0) { + CMP_err("missing 'int:' in -geninfo option"); + return 0; + } + valptr += 4; + + value = strtol(valptr, &endstr, 10); + if (endstr == valptr || *endstr != '\0') { + CMP_err("cannot parse int in -geninfo option"); + return 0; + } + + type = OBJ_txt2obj(opt_geninfo, 1); + if (type == NULL) { + CMP_err("cannot parse OID in -geninfo option"); + return 0; + } + + if ((aint = ASN1_INTEGER_new()) == NULL) + goto oom; + + val = ASN1_TYPE_new(); + if (!ASN1_INTEGER_set(aint, value) || val == NULL) { + ASN1_INTEGER_free(aint); + goto oom; + } + ASN1_TYPE_set(val, V_ASN1_INTEGER, aint); + itav = OSSL_CMP_ITAV_create(type, val); + if (itav == NULL) { + ASN1_TYPE_free(val); + goto oom; + } + + if (!OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav)) { + OSSL_CMP_ITAV_free(itav); + return 0; + } + return 1; + + oom: + ASN1_OBJECT_free(type); + CMP_err("out of memory"); + return 0; +} + + +/* + * set up the client-side OSSL_CMP_CTX based on options from config file/CLI + * while parsing options and checking their consistency. + * Prints reason for error to bio_err. + * Returns 1 on success, 0 on error + */ +static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) +{ + int ret = 0; + char *host = NULL, *port = NULL, *path = NULL, *used_path = opt_path; +#ifndef OPENSSL_NO_SOCK + int portnum, ssl; + static char server_port[32] = { '\0' }; + const char *proxy_host = NULL; +#endif + char server_buf[200] = "mock server"; + char proxy_buf[200] = ""; + + if (!opt_use_mock_srv && opt_rspin == NULL) { /* note: -port is not given */ +#ifndef OPENSSL_NO_SOCK + if (opt_server == NULL) { + CMP_err("missing -server or -use_mock_srv or -rspin option"); + goto err; + } +#else + CMP_err("missing -use_mock_srv or -rspin option; -server option is not supported due to no-sock build"); + goto err; +#endif + } +#ifndef OPENSSL_NO_SOCK + if (opt_server == NULL) { + if (opt_proxy != NULL) + CMP_warn("ignoring -proxy option since -server is not given"); + if (opt_no_proxy != NULL) + CMP_warn("ignoring -no_proxy option since -server is not given"); + if (opt_tls_used) { + CMP_warn("ignoring -tls_used option since -server is not given"); + opt_tls_used = 0; + } + goto set_path; + } + if (!OSSL_HTTP_parse_url(opt_server, &ssl, NULL /* user */, &host, &port, + &portnum, &path, NULL /* q */, NULL /* frag */)) { + CMP_err1("cannot parse -server URL: %s", opt_server); + goto err; + } + if (ssl && !opt_tls_used) { + CMP_err("missing -tls_used option since -server URL indicates https"); + goto err; + } + + BIO_snprintf(server_port, sizeof(server_port), "%s", port); + if (opt_path == NULL) + used_path = path; + if (!OSSL_CMP_CTX_set1_server(ctx, host) + || !OSSL_CMP_CTX_set_serverPort(ctx, portnum)) + goto oom; + if (opt_proxy != NULL && !OSSL_CMP_CTX_set1_proxy(ctx, opt_proxy)) + goto oom; + if (opt_no_proxy != NULL && !OSSL_CMP_CTX_set1_no_proxy(ctx, opt_no_proxy)) + goto oom; + (void)BIO_snprintf(server_buf, sizeof(server_buf), "http%s://%s:%s/%s", + opt_tls_used ? "s" : "", host, port, + *used_path == '/' ? used_path + 1 : used_path); + + proxy_host = OSSL_HTTP_adapt_proxy(opt_proxy, opt_no_proxy, host, ssl); + if (proxy_host != NULL) + (void)BIO_snprintf(proxy_buf, sizeof(proxy_buf), " via %s", proxy_host); + + set_path: +#endif + + if (!OSSL_CMP_CTX_set1_serverPath(ctx, used_path)) + goto oom; + if (!transform_opts()) + goto err; + + if (opt_infotype_s != NULL) { + char id_buf[100] = "id-it-"; + + strncat(id_buf, opt_infotype_s, sizeof(id_buf) - strlen(id_buf) - 1); + if ((opt_infotype = OBJ_sn2nid(id_buf)) == NID_undef) { + CMP_err("unknown OID name in -infotype option"); + goto err; + } + } + + if (!setup_verification_ctx(ctx)) + goto err; + + if (opt_keep_alive != 1) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_KEEP_ALIVE, + opt_keep_alive); + if (opt_total_timeout > 0 && opt_msg_timeout > 0 + && opt_total_timeout < opt_msg_timeout) { + CMP_err2("-total_timeout argument = %d must not be < %d (-msg_timeout)", + opt_total_timeout, opt_msg_timeout); + goto err; + } + if (opt_msg_timeout >= 0) /* must do this before setup_ssl_ctx() */ + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_MSG_TIMEOUT, + opt_msg_timeout); + if (opt_total_timeout >= 0) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_TOTAL_TIMEOUT, + opt_total_timeout); + + if (opt_reqin != NULL && opt_rspin != NULL) + CMP_warn("-reqin is ignored since -rspin is present"); + if (opt_reqin_new_tid && opt_reqin == NULL) + CMP_warn("-reqin_new_tid is ignored since -reqin is not present"); + if (opt_reqin != NULL || opt_reqout != NULL + || opt_rspin != NULL || opt_rspout != NULL || opt_use_mock_srv) + (void)OSSL_CMP_CTX_set_transfer_cb(ctx, read_write_req_resp); + +#ifndef OPENSSL_NO_SOCK + if (opt_tls_used) { + APP_HTTP_TLS_INFO *info; + + if (opt_tls_cert != NULL + || opt_tls_key != NULL || opt_tls_keypass != NULL) { + if (opt_tls_key == NULL) { + CMP_err("missing -tls_key option"); + goto err; + } else if (opt_tls_cert == NULL) { + CMP_err("missing -tls_cert option"); + goto err; + } + } + + if ((info = OPENSSL_zalloc(sizeof(*info))) == NULL) + goto err; + (void)OSSL_CMP_CTX_set_http_cb_arg(ctx, info); + info->server = opt_server; + info->port = server_port; + /* workaround for callback design flaw, see #17088: */ + info->use_proxy = proxy_host != NULL; + info->timeout = OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_MSG_TIMEOUT); + info->ssl_ctx = setup_ssl_ctx(ctx, host, engine); + + if (info->ssl_ctx == NULL) + goto err; + (void)OSSL_CMP_CTX_set_http_cb(ctx, app_http_tls_cb); + } +#endif + + if (!setup_protection_ctx(ctx, engine)) + goto err; + + if (!setup_request_ctx(ctx, engine)) + goto err; + + if (!set_name(opt_recipient, OSSL_CMP_CTX_set1_recipient, ctx, "recipient") + || !set_name(opt_expect_sender, OSSL_CMP_CTX_set1_expected_sender, + ctx, "expected sender")) + goto err; + + if (opt_geninfo != NULL && !handle_opt_geninfo(ctx)) + goto err; + + /* not printing earlier, to minimize confusion in case setup fails before */ + if (opt_rspin != NULL) + CMP_info("will not contact any server since -rspin is given"); + else + CMP_info2("will contact %s%s", server_buf, proxy_buf); + + ret = 1; + + err: + OPENSSL_free(host); + OPENSSL_free(port); + OPENSSL_free(path); + return ret; + oom: + CMP_err("out of memory"); + goto err; +} + +/* + * write out the given certificate to the output specified by bio. + * Depending on options use either PEM or DER format. + * Returns 1 on success, 0 on error + */ +static int write_cert(BIO *bio, X509 *cert) +{ + if ((opt_certform == FORMAT_PEM && PEM_write_bio_X509(bio, cert)) + || (opt_certform == FORMAT_ASN1 && i2d_X509_bio(bio, cert))) + return 1; + if (opt_certform != FORMAT_PEM && opt_certform != FORMAT_ASN1) + BIO_printf(bio_err, + "error: unsupported type '%s' for writing certificates\n", + opt_certform_s); + return 0; +} + +/* + * If destFile != NULL writes out a stack of certs to the given file. + * In any case frees the certs. + * Depending on options use either PEM or DER format, + * where DER does not make much sense for writing more than one cert! + * Returns number of written certificates on success, -1 on error. + */ +static int save_free_certs(OSSL_CMP_CTX *ctx, + STACK_OF(X509) *certs, char *destFile, char *desc) +{ + BIO *bio = NULL; + int i; + int n = sk_X509_num(certs); + + if (destFile == NULL) + goto end; + CMP_info3("received %d %s certificate(s), saving to file '%s'", + n, desc, destFile); + if (n > 1 && opt_certform != FORMAT_PEM) + CMP_warn("saving more than one certificate in non-PEM format"); + + if (destFile == NULL || (bio = BIO_new(BIO_s_file())) == NULL + || !BIO_write_filename(bio, (char *)destFile)) { + CMP_err1("could not open file '%s' for writing", destFile); + n = -1; + goto end; + } + + for (i = 0; i < n; i++) { + if (!write_cert(bio, sk_X509_value(certs, i))) { + CMP_err1("cannot write certificate to file '%s'", destFile); + n = -1; + goto end; + } + } + + end: + BIO_free(bio); + sk_X509_pop_free(certs, X509_free); + return n; +} + +static void print_itavs(STACK_OF(OSSL_CMP_ITAV) *itavs) +{ + OSSL_CMP_ITAV *itav = NULL; + char buf[128]; + int i, r; + int n = sk_OSSL_CMP_ITAV_num(itavs); /* itavs == NULL leads to 0 */ + + if (n == 0) { + CMP_info("genp contains no ITAV"); + return; + } + + for (i = 0; i < n; i++) { + itav = sk_OSSL_CMP_ITAV_value(itavs, i); + r = OBJ_obj2txt(buf, 128, OSSL_CMP_ITAV_get0_type(itav), 0); + if (r < 0) + CMP_err("could not get ITAV details"); + else if (r == 0) + CMP_info("genp contains empty ITAV"); + else + CMP_info1("genp contains ITAV of type: %s", buf); + } +} + +static char opt_item[SECTION_NAME_MAX + 1]; +/* get previous name from a comma or space-separated list of names */ +static const char *prev_item(const char *opt, const char *end) +{ + const char *beg; + size_t len; + + if (end == opt) + return NULL; + beg = end; + while (beg > opt) { + --beg; + if (beg[0] == ',' || isspace(beg[0])) { + ++beg; + break; + } + } + len = end - beg; + if (len > SECTION_NAME_MAX) { + CMP_warn3("using only first %d characters of section name starting with \"%.*s\"", + SECTION_NAME_MAX, SECTION_NAME_MAX, beg); + len = SECTION_NAME_MAX; + } + memcpy(opt_item, beg, len); + opt_item[len] = '\0'; + while (beg > opt) { + --beg; + if (beg[0] != ',' && !isspace(beg[0])) { + ++beg; + break; + } + } + return beg; +} + +/* get str value for name from a comma-separated hierarchy of config sections */ +static char *conf_get_string(const CONF *src_conf, const char *groups, + const char *name) +{ + char *res = NULL; + const char *end = groups + strlen(groups); + + while ((end = prev_item(groups, end)) != NULL) { + if ((res = NCONF_get_string(src_conf, opt_item, name)) != NULL) + return res; + } + return res; +} + +/* get long val for name from a comma-separated hierarchy of config sections */ +static int conf_get_number_e(const CONF *conf_, const char *groups, + const char *name, long *result) +{ + char *str = conf_get_string(conf_, groups, name); + char *tailptr; + long res; + + if (str == NULL || *str == '\0') + return 0; + + res = strtol(str, &tailptr, 10); + if (res == LONG_MIN || res == LONG_MAX || *tailptr != '\0') + return 0; + + *result = res; + return 1; +} + +/* + * use the command line option table to read values from the CMP section + * of openssl.cnf. Defaults are taken from the config file, they can be + * overwritten on the command line. + */ +static int read_config(void) +{ + unsigned int i; + long num = 0; + char *txt = NULL; + const OPTIONS *opt; + int start_opt = OPT_VERBOSITY - OPT_HELP; + int start_idx = OPT_VERBOSITY - 2; + /* + * starting with offset OPT_VERBOSITY because OPT_CONFIG and OPT_SECTION + * would not make sense within the config file. + */ + int n_options = OSSL_NELEM(cmp_options) - 1; + + for (opt = &cmp_options[start_opt], i = start_idx; + opt->name != NULL; i++, opt++) + if (!strcmp(opt->name, OPT_SECTION_STR) + || !strcmp(opt->name, OPT_MORE_STR)) + n_options--; + OPENSSL_assert(OSSL_NELEM(cmp_vars) == n_options + + OPT_PROV__FIRST + 1 - OPT_PROV__LAST + + OPT_R__FIRST + 1 - OPT_R__LAST + + OPT_V__FIRST + 1 - OPT_V__LAST); + for (opt = &cmp_options[start_opt], i = start_idx; + opt->name != NULL; i++, opt++) { + int provider_option = (OPT_PROV__FIRST <= opt->retval + && opt->retval < OPT_PROV__LAST); + int rand_state_option = (OPT_R__FIRST <= opt->retval + && opt->retval < OPT_R__LAST); + int verification_option = (OPT_V__FIRST <= opt->retval + && opt->retval < OPT_V__LAST); + + if (strcmp(opt->name, OPT_SECTION_STR) == 0 + || strcmp(opt->name, OPT_MORE_STR) == 0) { + i--; + continue; + } + if (provider_option || rand_state_option || verification_option) + i--; + switch (opt->valtype) { + case '-': + case 'p': + case 'n': + case 'N': + case 'l': + if (!conf_get_number_e(conf, opt_section, opt->name, &num)) { + ERR_clear_error(); + continue; /* option not provided */ + } + if (opt->valtype == 'p' && num <= 0) { + opt_printf_stderr("Non-positive number \"%ld\" for config option -%s\n", + num, opt->name); + return -1; + } + if (opt->valtype == 'N' && num < 0) { + opt_printf_stderr("Negative number \"%ld\" for config option -%s\n", + num, opt->name); + return -1; + } + break; + case 's': + case '>': + case 'M': + txt = conf_get_string(conf, opt_section, opt->name); + if (txt == NULL) { + ERR_clear_error(); + continue; /* option not provided */ + } + break; + default: + CMP_err2("internal: unsupported type '%c' for option '%s'", + opt->valtype, opt->name); + return 0; + break; + } + if (provider_option || verification_option) { + int conf_argc = 1; + char *conf_argv[3]; + char arg1[82]; + + BIO_snprintf(arg1, 81, "-%s", (char *)opt->name); + conf_argv[0] = prog; + conf_argv[1] = arg1; + if (opt->valtype == '-') { + if (num != 0) + conf_argc = 2; + } else { + conf_argc = 3; + conf_argv[2] = conf_get_string(conf, opt_section, opt->name); + /* not NULL */ + } + if (conf_argc > 1) { + (void)opt_init(conf_argc, conf_argv, cmp_options); + + if (provider_option + ? !opt_provider(opt_next()) + : !opt_verify(opt_next(), vpm)) { + CMP_err2("for option '%s' in config file section '%s'", + opt->name, opt_section); + return 0; + } + } + } else { + switch (opt->valtype) { + case '-': + case 'p': + case 'n': + case 'N': + if (num < INT_MIN || INT_MAX < num) { + BIO_printf(bio_err, + "integer value out of range for option '%s'\n", + opt->name); + return 0; + } + *cmp_vars[i].num = (int)num; + break; + case 'l': + *cmp_vars[i].num_long = num; + break; + default: + if (txt != NULL && txt[0] == '\0') + txt = NULL; /* reset option on empty string input */ + *cmp_vars[i].txt = txt; + break; + } + } + } + + return 1; +} + +static char *opt_str(void) +{ + char *arg = opt_arg(); + + if (arg[0] == '\0') { + CMP_warn1("%s option argument is empty string, resetting option", + opt_flag()); + arg = NULL; + } else if (arg[0] == '-') { + CMP_warn1("%s option argument starts with hyphen", opt_flag()); + } + return arg; +} + +/* returns 1 on success, 0 on error, -1 on -help (i.e., stop with success) */ +static int get_opts(int argc, char **argv) +{ + OPTION_CHOICE o; + + prog = opt_init(argc, argv, cmp_options); + + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + return 0; + case OPT_HELP: + opt_help(cmp_options); + return -1; + case OPT_CONFIG: /* has already been handled */ + case OPT_SECTION: /* has already been handled */ + break; + case OPT_VERBOSITY: + if (!set_verbosity(opt_int_arg())) + goto opthelp; + break; +#ifndef OPENSSL_NO_SOCK + case OPT_SERVER: + opt_server = opt_str(); + break; + case OPT_PROXY: + opt_proxy = opt_str(); + break; + case OPT_NO_PROXY: + opt_no_proxy = opt_str(); + break; +#endif + case OPT_RECIPIENT: + opt_recipient = opt_str(); + break; + case OPT_PATH: + opt_path = opt_str(); + break; + case OPT_KEEP_ALIVE: + opt_keep_alive = opt_int_arg(); + if (opt_keep_alive > 2) { + CMP_err("-keep_alive argument must be 0, 1, or 2"); + goto opthelp; + } + break; + case OPT_MSG_TIMEOUT: + opt_msg_timeout = opt_int_arg(); + break; + case OPT_TOTAL_TIMEOUT: + opt_total_timeout = opt_int_arg(); + break; +#ifndef OPENSSL_NO_SOCK + case OPT_TLS_USED: + opt_tls_used = 1; + break; + case OPT_TLS_CERT: + opt_tls_cert = opt_str(); + break; + case OPT_TLS_KEY: + opt_tls_key = opt_str(); + break; + case OPT_TLS_KEYPASS: + opt_tls_keypass = opt_str(); + break; + case OPT_TLS_EXTRA: + opt_tls_extra = opt_str(); + break; + case OPT_TLS_TRUSTED: + opt_tls_trusted = opt_str(); + break; + case OPT_TLS_HOST: + opt_tls_host = opt_str(); + break; +#endif + + case OPT_REF: + opt_ref = opt_str(); + break; + case OPT_SECRET: + opt_secret = opt_str(); + break; + case OPT_CERT: + opt_cert = opt_str(); + break; + case OPT_OWN_TRUSTED: + opt_own_trusted = opt_str(); + break; + case OPT_KEY: + opt_key = opt_str(); + break; + case OPT_KEYPASS: + opt_keypass = opt_str(); + break; + case OPT_DIGEST: + opt_digest = opt_str(); + break; + case OPT_MAC: + opt_mac = opt_str(); + break; + case OPT_EXTRACERTS: + opt_extracerts = opt_str(); + break; + case OPT_UNPROTECTED_REQUESTS: + opt_unprotected_requests = 1; + break; + + case OPT_TRUSTED: + opt_trusted = opt_str(); + break; + case OPT_UNTRUSTED: + opt_untrusted = opt_str(); + break; + case OPT_SRVCERT: + opt_srvcert = opt_str(); + break; + case OPT_EXPECT_SENDER: + opt_expect_sender = opt_str(); + break; + case OPT_IGNORE_KEYUSAGE: + opt_ignore_keyusage = 1; + break; + case OPT_UNPROTECTED_ERRORS: + opt_unprotected_errors = 1; + break; + case OPT_EXTRACERTSOUT: + opt_extracertsout = opt_str(); + break; + case OPT_CACERTSOUT: + opt_cacertsout = opt_str(); + break; + + case OPT_V_CASES: + if (!opt_verify(o, vpm)) + goto opthelp; + break; + case OPT_CMD: + opt_cmd_s = opt_str(); + break; + case OPT_INFOTYPE: + opt_infotype_s = opt_str(); + break; + case OPT_GENINFO: + opt_geninfo = opt_str(); + break; + + case OPT_NEWKEY: + opt_newkey = opt_str(); + break; + case OPT_NEWKEYPASS: + opt_newkeypass = opt_str(); + break; + case OPT_SUBJECT: + opt_subject = opt_str(); + break; + case OPT_ISSUER: + opt_issuer = opt_str(); + break; + case OPT_DAYS: + opt_days = opt_int_arg(); + break; + case OPT_REQEXTS: + opt_reqexts = opt_str(); + break; + case OPT_SANS: + opt_sans = opt_str(); + break; + case OPT_SAN_NODEFAULT: + opt_san_nodefault = 1; + break; + case OPT_POLICIES: + opt_policies = opt_str(); + break; + case OPT_POLICY_OIDS: + opt_policy_oids = opt_str(); + break; + case OPT_POLICY_OIDS_CRITICAL: + opt_policy_oids_critical = 1; + break; + case OPT_POPO: + opt_popo = opt_int_arg(); + if (opt_popo < OSSL_CRMF_POPO_NONE + || opt_popo > OSSL_CRMF_POPO_KEYENC) { + CMP_err("invalid popo spec. Valid values are -1 .. 2"); + goto opthelp; + } + break; + case OPT_CSR: + opt_csr = opt_arg(); + break; + case OPT_OUT_TRUSTED: + opt_out_trusted = opt_str(); + break; + case OPT_IMPLICIT_CONFIRM: + opt_implicit_confirm = 1; + break; + case OPT_DISABLE_CONFIRM: + opt_disable_confirm = 1; + break; + case OPT_CERTOUT: + opt_certout = opt_str(); + break; + case OPT_CHAINOUT: + opt_chainout = opt_str(); + break; + case OPT_OLDCERT: + opt_oldcert = opt_str(); + break; + case OPT_REVREASON: + opt_revreason = opt_int_arg(); + if (opt_revreason < CRL_REASON_NONE + || opt_revreason > CRL_REASON_AA_COMPROMISE + || opt_revreason == 7) { + CMP_err("invalid revreason. Valid values are -1 .. 6, 8 .. 10"); + goto opthelp; + } + break; + case OPT_CERTFORM: + opt_certform_s = opt_str(); + break; + case OPT_KEYFORM: + opt_keyform_s = opt_str(); + break; + case OPT_OTHERPASS: + opt_otherpass = opt_str(); + break; +#ifndef OPENSSL_NO_ENGINE + case OPT_ENGINE: + opt_engine = opt_str(); + break; +#endif + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto opthelp; + break; + case OPT_R_CASES: + if (!opt_rand(o)) + goto opthelp; + break; + + case OPT_BATCH: + opt_batch = 1; + break; + case OPT_REPEAT: + opt_repeat = opt_int_arg(); + break; + case OPT_REQIN: + opt_reqin = opt_str(); + break; + case OPT_REQIN_NEW_TID: + opt_reqin_new_tid = 1; + break; + case OPT_REQOUT: + opt_reqout = opt_str(); + break; + case OPT_RSPIN: + opt_rspin = opt_str(); + break; + case OPT_RSPOUT: + opt_rspout = opt_str(); + break; + case OPT_USE_MOCK_SRV: + opt_use_mock_srv = 1; + break; + +#ifndef OPENSSL_NO_SOCK + case OPT_PORT: + opt_port = opt_str(); + break; + case OPT_MAX_MSGS: + opt_max_msgs = opt_int_arg(); + break; +#endif + case OPT_SRV_REF: + opt_srv_ref = opt_str(); + break; + case OPT_SRV_SECRET: + opt_srv_secret = opt_str(); + break; + case OPT_SRV_CERT: + opt_srv_cert = opt_str(); + break; + case OPT_SRV_KEY: + opt_srv_key = opt_str(); + break; + case OPT_SRV_KEYPASS: + opt_srv_keypass = opt_str(); + break; + case OPT_SRV_TRUSTED: + opt_srv_trusted = opt_str(); + break; + case OPT_SRV_UNTRUSTED: + opt_srv_untrusted = opt_str(); + break; + case OPT_RSP_CERT: + opt_rsp_cert = opt_str(); + break; + case OPT_RSP_EXTRACERTS: + opt_rsp_extracerts = opt_str(); + break; + case OPT_RSP_CAPUBS: + opt_rsp_capubs = opt_str(); + break; + case OPT_POLL_COUNT: + opt_poll_count = opt_int_arg(); + break; + case OPT_CHECK_AFTER: + opt_check_after = opt_int_arg(); + break; + case OPT_GRANT_IMPLICITCONF: + opt_grant_implicitconf = 1; + break; + case OPT_PKISTATUS: + opt_pkistatus = opt_int_arg(); + break; + case OPT_FAILURE: + opt_failure = opt_int_arg(); + break; + case OPT_FAILUREBITS: + opt_failurebits = opt_int_arg(); + break; + case OPT_STATUSSTRING: + opt_statusstring = opt_str(); + break; + case OPT_SEND_ERROR: + opt_send_error = 1; + break; + case OPT_SEND_UNPROTECTED: + opt_send_unprotected = 1; + break; + case OPT_SEND_UNPROT_ERR: + opt_send_unprot_err = 1; + break; + case OPT_ACCEPT_UNPROTECTED: + opt_accept_unprotected = 1; + break; + case OPT_ACCEPT_UNPROT_ERR: + opt_accept_unprot_err = 1; + break; + case OPT_ACCEPT_RAVERIFIED: + opt_accept_raverified = 1; + break; + } + } + + /* No extra args. */ + argc = opt_num_rest(); + argv = opt_rest(); + if (argc != 0) + goto opthelp; + return 1; +} + +#ifndef OPENSSL_NO_SOCK +static int cmp_server(OSSL_CMP_CTX *srv_cmp_ctx) { + BIO *acbio; + BIO *cbio = NULL; + int keep_alive = 0; + int msgs = 0; + int retry = 1; + int ret = 1; + + if ((acbio = http_server_init_bio(prog, opt_port)) == NULL) + return 0; + while (opt_max_msgs <= 0 || msgs < opt_max_msgs) { + char *path = NULL; + OSSL_CMP_MSG *req = NULL; + OSSL_CMP_MSG *resp = NULL; + + ret = http_server_get_asn1_req(ASN1_ITEM_rptr(OSSL_CMP_MSG), + (ASN1_VALUE **)&req, &path, + &cbio, acbio, &keep_alive, + prog, opt_port, 0, 0); + if (ret == 0) { /* no request yet */ + if (retry) { + ossl_sleep(1000); + retry = 0; + continue; + } + ret = 0; + goto next; + } + if (ret++ == -1) /* fatal error */ + break; + + ret = 0; + msgs++; + if (req != NULL) { + if (strcmp(path, "") != 0 && strcmp(path, "pkix/") != 0) { + (void)http_server_send_status(cbio, 404, "Not Found"); + CMP_err1("expecting empty path or 'pkix/' but got '%s'", + path); + OPENSSL_free(path); + OSSL_CMP_MSG_free(req); + goto next; + } + OPENSSL_free(path); + resp = OSSL_CMP_CTX_server_perform(cmp_ctx, req); + OSSL_CMP_MSG_free(req); + if (resp == NULL) { + (void)http_server_send_status(cbio, + 500, "Internal Server Error"); + break; /* treated as fatal error */ + } + ret = http_server_send_asn1_resp(cbio, keep_alive, + "application/pkixcmp", + ASN1_ITEM_rptr(OSSL_CMP_MSG), + (const ASN1_VALUE *)resp); + OSSL_CMP_MSG_free(resp); + if (!ret) + break; /* treated as fatal error */ + } + next: + if (!ret) { /* on transmission error, cancel CMP transaction */ + (void)OSSL_CMP_CTX_set1_transactionID(srv_cmp_ctx, NULL); + (void)OSSL_CMP_CTX_set1_senderNonce(srv_cmp_ctx, NULL); + } + if (!ret || !keep_alive + || OSSL_CMP_CTX_get_status(srv_cmp_ctx) != OSSL_CMP_PKISTATUS_trans + /* transaction closed by OSSL_CMP_CTX_server_perform() */) { + BIO_free_all(cbio); + cbio = NULL; + } + } + + BIO_free_all(cbio); + BIO_free_all(acbio); + return ret; +} +#endif + +static void print_status(void) +{ + /* print PKIStatusInfo */ + int status = OSSL_CMP_CTX_get_status(cmp_ctx); + char *buf = app_malloc(OSSL_CMP_PKISI_BUFLEN, "PKIStatusInfo buf"); + const char *string = + OSSL_CMP_CTX_snprint_PKIStatus(cmp_ctx, buf, OSSL_CMP_PKISI_BUFLEN); + const char *from = "", *server = ""; + +#ifndef OPENSSL_NO_SOCK + if (opt_server != NULL) { + from = " from "; + server = opt_server; + } +#endif + CMP_print(bio_err, + status == OSSL_CMP_PKISTATUS_accepted + ? OSSL_CMP_LOG_INFO : + status == OSSL_CMP_PKISTATUS_rejection + || status == OSSL_CMP_PKISTATUS_waiting + ? OSSL_CMP_LOG_ERR : OSSL_CMP_LOG_WARNING, + status == OSSL_CMP_PKISTATUS_accepted ? "info" : + status == OSSL_CMP_PKISTATUS_rejection ? "server error" : + status == OSSL_CMP_PKISTATUS_waiting ? "internal error" + : "warning", "received%s%s %s", from, server, + string != NULL ? string : ""); + OPENSSL_free(buf); +} + +int cmp_main(int argc, char **argv) +{ + char *configfile = NULL; + int i; + X509 *newcert = NULL; + ENGINE *engine = NULL; + OSSL_CMP_CTX *srv_cmp_ctx = NULL; + int ret = 0; /* default: failure */ + + prog = opt_appname(argv[0]); + if (argc <= 1) { + opt_help(cmp_options); + goto err; + } + + /* + * handle options -config, -section, and -verbosity upfront + * to take effect for other options + */ + for (i = 1; i < argc - 1; i++) { + if (*argv[i] == '-') { + if (!strcmp(argv[i] + 1, cmp_options[OPT_CONFIG - OPT_HELP].name)) + opt_config = argv[++i]; + else if (!strcmp(argv[i] + 1, + cmp_options[OPT_SECTION - OPT_HELP].name)) + opt_section = argv[++i]; + else if (strcmp(argv[i] + 1, + cmp_options[OPT_VERBOSITY - OPT_HELP].name) == 0 + && !set_verbosity(atoi(argv[++i]))) + goto err; + } + } + if (opt_section[0] == '\0') /* empty string */ + opt_section = DEFAULT_SECTION; + + vpm = X509_VERIFY_PARAM_new(); + if (vpm == NULL) { + CMP_err("out of memory"); + goto err; + } + + /* read default values for options from config file */ + configfile = opt_config != NULL ? opt_config : default_config_file; + if (configfile != NULL && configfile[0] != '\0' /* non-empty string */ + && (configfile != default_config_file || access(configfile, F_OK) != -1)) { + CMP_info2("using section(s) '%s' of OpenSSL configuration file '%s'", + opt_section, configfile); + conf = app_load_config(configfile); + if (conf == NULL) { + goto err; + } else { + if (strcmp(opt_section, CMP_SECTION) == 0) { /* default */ + if (!NCONF_get_section(conf, opt_section)) + CMP_info2("no [%s] section found in config file '%s';" + " will thus use just [default] and unnamed section if present", + opt_section, configfile); + } else { + const char *end = opt_section + strlen(opt_section); + while ((end = prev_item(opt_section, end)) != NULL) { + if (!NCONF_get_section(conf, opt_item)) { + CMP_err2("no [%s] section found in config file '%s'", + opt_item, configfile); + goto err; + } + } + } + ret = read_config(); + if (!set_verbosity(opt_verbosity)) /* just for checking range */ + ret = -1; + if (ret <= 0) { + if (ret == -1) + BIO_printf(bio_err, "Use -help for summary.\n"); + goto err; + } + } + } + (void)BIO_flush(bio_err); /* prevent interference with opt_help() */ + + ret = get_opts(argc, argv); + if (ret <= 0) + goto err; + ret = 0; + if (!app_RAND_load()) + goto err; + + if (opt_batch) + set_base_ui_method(UI_null()); + + if (opt_engine != NULL) { + engine = setup_engine_methods(opt_engine, 0 /* not: ENGINE_METHOD_ALL */, 0); + if (engine == NULL) { + CMP_err1("cannot load engine %s", opt_engine); + goto err; + } + } + + cmp_ctx = OSSL_CMP_CTX_new(app_get0_libctx(), app_get0_propq()); + if (cmp_ctx == NULL) + goto err; + OSSL_CMP_CTX_set_log_verbosity(cmp_ctx, opt_verbosity); + if (!OSSL_CMP_CTX_set_log_cb(cmp_ctx, print_to_bio_out)) { + CMP_err1("cannot set up error reporting and logging for %s", prog); + goto err; + } + +#ifndef OPENSSL_NO_SOCK + if ((opt_tls_cert != NULL || opt_tls_key != NULL + || opt_tls_keypass != NULL || opt_tls_extra != NULL + || opt_tls_trusted != NULL || opt_tls_host != NULL) + && !opt_tls_used) + CMP_warn("Ingnoring TLS options(s) since -tls_used is not given"); + if (opt_port != NULL) { + if (opt_tls_used) { + CMP_err("-tls_used option not supported with -port option"); + goto err; + } + if (opt_use_mock_srv || opt_server != NULL || opt_rspin != NULL) { + CMP_err("cannot use -port with -use_mock_srv, -server, or -rspin options"); + goto err; + } + } + if (opt_server != NULL && opt_use_mock_srv) { + CMP_err("cannot use both -server and -use_mock_srv options"); + goto err; + } +#endif + if (opt_rspin != NULL && opt_use_mock_srv) { + CMP_err("cannot use both -rspin and -use_mock_srv options"); + goto err; + } + + if (opt_use_mock_srv +#ifndef OPENSSL_NO_SOCK + || opt_port != NULL +#endif + ) { + OSSL_CMP_SRV_CTX *srv_ctx; + + if ((srv_ctx = setup_srv_ctx(engine)) == NULL) + goto err; + srv_cmp_ctx = OSSL_CMP_SRV_CTX_get0_cmp_ctx(srv_ctx); + OSSL_CMP_CTX_set_transfer_cb_arg(cmp_ctx, srv_ctx); + if (!OSSL_CMP_CTX_set_log_cb(srv_cmp_ctx, print_to_bio_err)) { + CMP_err1("cannot set up error reporting and logging for %s", prog); + goto err; + } + OSSL_CMP_CTX_set_log_verbosity(srv_cmp_ctx, opt_verbosity); + } + +#ifndef OPENSSL_NO_SOCK + if (opt_tls_used && (opt_use_mock_srv || opt_rspin != NULL)) { + CMP_warn("ignoring -tls_used option since -use_mock_srv or -rspin is given"); + opt_tls_used = 0; + } + + if (opt_port != NULL) { /* act as very basic CMP HTTP server */ + ret = cmp_server(srv_cmp_ctx); + goto err; + } + + /* act as CMP client, possibly using internal mock server */ + + if (opt_server != NULL) { + if (opt_rspin != NULL) { + CMP_warn("ignoring -server option since -rspin is given"); + opt_server = NULL; + } + } +#endif + + if (!setup_client_ctx(cmp_ctx, engine)) { + CMP_err("cannot set up CMP context"); + goto err; + } + for (i = 0; i < opt_repeat; i++) { + /* everything is ready, now connect and perform the command! */ + switch (opt_cmd) { + case CMP_IR: + newcert = OSSL_CMP_exec_IR_ses(cmp_ctx); + if (newcert != NULL) + ret = 1; + break; + case CMP_KUR: + newcert = OSSL_CMP_exec_KUR_ses(cmp_ctx); + if (newcert != NULL) + ret = 1; + break; + case CMP_CR: + newcert = OSSL_CMP_exec_CR_ses(cmp_ctx); + if (newcert != NULL) + ret = 1; + break; + case CMP_P10CR: + newcert = OSSL_CMP_exec_P10CR_ses(cmp_ctx); + if (newcert != NULL) + ret = 1; + break; + case CMP_RR: + ret = OSSL_CMP_exec_RR_ses(cmp_ctx); + break; + case CMP_GENM: + { + STACK_OF(OSSL_CMP_ITAV) *itavs; + + if (opt_infotype != NID_undef) { + OSSL_CMP_ITAV *itav = + OSSL_CMP_ITAV_create(OBJ_nid2obj(opt_infotype), NULL); + if (itav == NULL) + goto err; + OSSL_CMP_CTX_push0_genm_ITAV(cmp_ctx, itav); + } + + if ((itavs = OSSL_CMP_exec_GENM_ses(cmp_ctx)) != NULL) { + print_itavs(itavs); + sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free); + ret = 1; + } + break; + } + default: + break; + } + if (OSSL_CMP_CTX_get_status(cmp_ctx) < OSSL_CMP_PKISTATUS_accepted) + goto err; /* we got no response, maybe even did not send request */ + + print_status(); + if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_extraCertsIn(cmp_ctx), + opt_extracertsout, "extra") < 0) + ret = 0; + if (!ret) + goto err; + ret = 0; + if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_caPubs(cmp_ctx), + opt_cacertsout, "CA") < 0) + goto err; + if (newcert != NULL) { + STACK_OF(X509) *certs = sk_X509_new_null(); + + if (!X509_add_cert(certs, newcert, X509_ADD_FLAG_UP_REF)) { + sk_X509_free(certs); + goto err; + } + if (save_free_certs(cmp_ctx, certs, opt_certout, "enrolled") < 0) + goto err; + } + if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_newChain(cmp_ctx), + opt_chainout, "chain") < 0) + goto err; + + if (!OSSL_CMP_CTX_reinit(cmp_ctx)) + goto err; + } + ret = 1; + + err: + /* in case we ended up here on error without proper cleaning */ + cleanse(opt_keypass); + cleanse(opt_newkeypass); + cleanse(opt_otherpass); +#ifndef OPENSSL_NO_SOCK + cleanse(opt_tls_keypass); +#endif + cleanse(opt_secret); + cleanse(opt_srv_keypass); + cleanse(opt_srv_secret); + + if (ret != 1) + OSSL_CMP_CTX_print_errors(cmp_ctx); + + if (cmp_ctx != NULL) { +#ifndef OPENSSL_NO_SOCK + APP_HTTP_TLS_INFO *info = OSSL_CMP_CTX_get_http_cb_arg(cmp_ctx); + +#endif + ossl_cmp_mock_srv_free(OSSL_CMP_CTX_get_transfer_cb_arg(cmp_ctx)); + X509_STORE_free(OSSL_CMP_CTX_get_certConf_cb_arg(cmp_ctx)); + /* cannot free info already here, as it may be used indirectly by: */ + OSSL_CMP_CTX_free(cmp_ctx); +#ifndef OPENSSL_NO_SOCK + APP_HTTP_TLS_INFO_free(info); +#endif + } + X509_VERIFY_PARAM_free(vpm); + release_engine(engine); + + NCONF_free(conf); /* must not do as long as opt_... variables are used */ + OSSL_CMP_log_close(); + + return ret == 0 ? EXIT_FAILURE : EXIT_SUCCESS; /* ret == -1 for -help */ +} diff --git a/crypto/openssl/apps/cms.c b/crypto/openssl/apps/cms.c index 71554037d0b7..76c789671937 100644 --- a/crypto/openssl/apps/cms.c +++ b/crypto/openssl/apps/cms.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,43 +14,41 @@ #include "apps.h" #include "progs.h" -#ifndef OPENSSL_NO_CMS - -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include +#include static int save_certs(char *signerfile, STACK_OF(X509) *signers); static int cms_cb(int ok, X509_STORE_CTX *ctx); static void receipt_request_print(CMS_ContentInfo *cms); -static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) - *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING) - *rr_from); +static CMS_ReceiptRequest +*make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst, + STACK_OF(OPENSSL_STRING) *rr_from); static int cms_set_pkey_param(EVP_PKEY_CTX *pctx, STACK_OF(OPENSSL_STRING) *param); -# define SMIME_OP 0x10 -# define SMIME_IP 0x20 -# define SMIME_SIGNERS 0x40 -# define SMIME_ENCRYPT (1 | SMIME_OP) -# define SMIME_DECRYPT (2 | SMIME_IP) -# define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS) -# define SMIME_VERIFY (4 | SMIME_IP) -# define SMIME_CMSOUT (5 | SMIME_IP | SMIME_OP) -# define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) -# define SMIME_DATAOUT (7 | SMIME_IP) -# define SMIME_DATA_CREATE (8 | SMIME_OP) -# define SMIME_DIGEST_VERIFY (9 | SMIME_IP) -# define SMIME_DIGEST_CREATE (10 | SMIME_OP) -# define SMIME_UNCOMPRESS (11 | SMIME_IP) -# define SMIME_COMPRESS (12 | SMIME_OP) -# define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP) -# define SMIME_ENCRYPTED_ENCRYPT (14 | SMIME_OP) -# define SMIME_SIGN_RECEIPT (15 | SMIME_IP | SMIME_OP) -# define SMIME_VERIFY_RECEIPT (16 | SMIME_IP) +#define SMIME_OP 0x100 +#define SMIME_IP 0x200 +#define SMIME_SIGNERS 0x400 +#define SMIME_ENCRYPT (1 | SMIME_OP) +#define SMIME_DECRYPT (2 | SMIME_IP) +#define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS) +#define SMIME_VERIFY (4 | SMIME_IP) +#define SMIME_RESIGN (5 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) +#define SMIME_SIGN_RECEIPT (6 | SMIME_IP | SMIME_OP) +#define SMIME_VERIFY_RECEIPT (7 | SMIME_IP) +#define SMIME_DIGEST_CREATE (8 | SMIME_OP) +#define SMIME_DIGEST_VERIFY (9 | SMIME_IP) +#define SMIME_COMPRESS (10 | SMIME_OP) +#define SMIME_UNCOMPRESS (11 | SMIME_IP) +#define SMIME_ENCRYPTED_ENCRYPT (12 | SMIME_OP) +#define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP) +#define SMIME_DATA_CREATE (14 | SMIME_OP) +#define SMIME_DATA_OUT (15 | SMIME_IP) +#define SMIME_CMSOUT (16 | SMIME_IP | SMIME_OP) static int verify_err = 0; @@ -63,9 +61,9 @@ struct cms_key_param_st { }; typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENCRYPT, - OPT_DECRYPT, OPT_SIGN, OPT_SIGN_RECEIPT, OPT_RESIGN, + OPT_DECRYPT, OPT_SIGN, OPT_CADES, OPT_SIGN_RECEIPT, OPT_RESIGN, OPT_VERIFY, OPT_VERIFY_RETCODE, OPT_VERIFY_RECEIPT, OPT_CMSOUT, OPT_DATA_OUT, OPT_DATA_CREATE, OPT_DIGEST_VERIFY, OPT_DIGEST_CREATE, OPT_COMPRESS, OPT_UNCOMPRESS, @@ -75,151 +73,246 @@ typedef enum OPTION_choice { OPT_NOSIGS, OPT_NO_CONTENT_VERIFY, OPT_NO_ATTR_VERIFY, OPT_INDEF, OPT_NOINDEF, OPT_CRLFEOL, OPT_NOOUT, OPT_RR_PRINT, OPT_RR_ALL, OPT_RR_FIRST, OPT_RCTFORM, OPT_CERTFILE, OPT_CAFILE, - OPT_CAPATH, OPT_NOCAPATH, OPT_NOCAFILE,OPT_CONTENT, OPT_PRINT, + OPT_CAPATH, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, + OPT_CONTENT, OPT_PRINT, OPT_NAMEOPT, OPT_SECRETKEY, OPT_SECRETKEYID, OPT_PWRI_PASSWORD, OPT_ECONTENT_TYPE, OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_CERTSOUT, OPT_MD, OPT_INKEY, OPT_KEYFORM, OPT_KEYOPT, OPT_RR_FROM, OPT_RR_TO, OPT_AES128_WRAP, OPT_AES192_WRAP, OPT_AES256_WRAP, - OPT_3DES_WRAP, OPT_ENGINE, + OPT_3DES_WRAP, OPT_WRAP, OPT_ENGINE, OPT_R_ENUM, + OPT_PROV_ENUM, OPT_CONFIG, OPT_V_ENUM, - OPT_CIPHER + OPT_CIPHER, + OPT_ORIGINATOR } OPTION_CHOICE; const OPTIONS cms_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"}, - {OPT_HELP_STR, 1, '-', - " cert.pem... recipient certs for encryption\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert...]\n"}, {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER"}, - {"outform", OPT_OUTFORM, 'c', - "Output format SMIME (default), PEM or DER"}, + + OPT_SECTION("General"), {"in", OPT_IN, '<', "Input file"}, {"out", OPT_OUT, '>', "Output file"}, + OPT_CONFIG_OPTION, + + OPT_SECTION("Operation"), {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"}, {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"}, {"sign", OPT_SIGN, '-', "Sign message"}, - {"sign_receipt", OPT_SIGN_RECEIPT, '-', "Generate a signed receipt for the message"}, - {"resign", OPT_RESIGN, '-', "Resign a signed message"}, {"verify", OPT_VERIFY, '-', "Verify signed message"}, - {"verify_retcode", OPT_VERIFY_RETCODE, '-'}, - {"verify_receipt", OPT_VERIFY_RECEIPT, '<'}, + {"resign", OPT_RESIGN, '-', "Resign a signed message"}, + {"sign_receipt", OPT_SIGN_RECEIPT, '-', + "Generate a signed receipt for a message"}, + {"verify_receipt", OPT_VERIFY_RECEIPT, '<', + "Verify receipts; exit if receipt signatures do not verify"}, + {"digest_create", OPT_DIGEST_CREATE, '-', + "Create a CMS \"DigestedData\" object"}, + {"digest_verify", OPT_DIGEST_VERIFY, '-', + "Verify a CMS \"DigestedData\" object and output it"}, + {"compress", OPT_COMPRESS, '-', "Create a CMS \"CompressedData\" object"}, + {"uncompress", OPT_UNCOMPRESS, '-', + "Uncompress a CMS \"CompressedData\" object"}, + {"EncryptedData_encrypt", OPT_ED_ENCRYPT, '-', + "Create CMS \"EncryptedData\" object using symmetric key"}, + {"EncryptedData_decrypt", OPT_ED_DECRYPT, '-', + "Decrypt CMS \"EncryptedData\" object using symmetric key"}, + {"data_create", OPT_DATA_CREATE, '-', "Create a CMS \"Data\" object"}, + {"data_out", OPT_DATA_OUT, '-', "Copy CMS \"Data\" object to output"}, {"cmsout", OPT_CMSOUT, '-', "Output CMS structure"}, - {"data_out", OPT_DATA_OUT, '-'}, - {"data_create", OPT_DATA_CREATE, '-'}, - {"digest_verify", OPT_DIGEST_VERIFY, '-'}, - {"digest_create", OPT_DIGEST_CREATE, '-'}, - {"compress", OPT_COMPRESS, '-'}, - {"uncompress", OPT_UNCOMPRESS, '-'}, - {"EncryptedData_decrypt", OPT_ED_DECRYPT, '-'}, - {"EncryptedData_encrypt", OPT_ED_ENCRYPT, '-'}, - {"debug_decrypt", OPT_DEBUG_DECRYPT, '-'}, - {"text", OPT_TEXT, '-', "Include or delete text MIME headers"}, - {"asciicrlf", OPT_ASCIICRLF, '-'}, - {"nointern", OPT_NOINTERN, '-', - "Don't search certificates in message for signer"}, - {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"}, - {"nocerts", OPT_NOCERTS, '-', - "Don't include signers certificate when signing"}, - {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"}, - {"nodetach", OPT_NODETACH, '-', "Use opaque signing"}, - {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"}, - {"binary", OPT_BINARY, '-', "Don't translate message to text"}, - {"keyid", OPT_KEYID, '-', "Use subject key identifier"}, - {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"}, - {"no_content_verify", OPT_NO_CONTENT_VERIFY, '-'}, - {"no_attr_verify", OPT_NO_ATTR_VERIFY, '-'}, + + OPT_SECTION("File format"), + {"inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER"}, + {"outform", OPT_OUTFORM, 'c', + "Output format SMIME (default), PEM or DER"}, + {"rctform", OPT_RCTFORM, 'F', "Receipt file format"}, {"stream", OPT_INDEF, '-', "Enable CMS streaming"}, {"indef", OPT_INDEF, '-', "Same as -stream"}, {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"}, - {"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only" }, - {"noout", OPT_NOOUT, '-', "For the -cmsout operation do not output the parsed CMS structure"}, - {"receipt_request_print", OPT_RR_PRINT, '-', "Print CMS Receipt Request" }, - {"receipt_request_all", OPT_RR_ALL, '-'}, - {"receipt_request_first", OPT_RR_FIRST, '-'}, - {"rctform", OPT_RCTFORM, 'F', "Receipt file format"}, + {"binary", OPT_BINARY, '-', + "Treat input as binary: do not translate to canonical form"}, + {"crlfeol", OPT_CRLFEOL, '-', + "Use CRLF as EOL termination instead of CR only" }, + {"asciicrlf", OPT_ASCIICRLF, '-', + "Perform CRLF canonicalisation when signing"}, + + OPT_SECTION("Keys and passwords"), + {"pwri_password", OPT_PWRI_PASSWORD, 's', + "Specific password for recipient"}, + {"secretkey", OPT_SECRETKEY, 's', + "Use specified hex-encoded key to decrypt/encrypt recipients or content"}, + {"secretkeyid", OPT_SECRETKEYID, 's', + "Identity of the -secretkey for CMS \"KEKRecipientInfo\" object"}, + {"inkey", OPT_INKEY, 's', + "Input private key (if not signer or recipient)"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"keyopt", OPT_KEYOPT, 's', "Set public key parameters as n:v pairs"}, + {"keyform", OPT_KEYFORM, 'f', + "Input private key format (ENGINE, other values ignored)"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, +#endif + OPT_PROV_OPTIONS, + OPT_R_OPTIONS, + + OPT_SECTION("Encryption and decryption"), + {"originator", OPT_ORIGINATOR, 's', "Originator certificate file"}, + {"recip", OPT_RECIP, '<', "Recipient cert file"}, + {"cert...", OPT_PARAM, '.', + "Recipient certs (optional; used only when encrypting)"}, + {"", OPT_CIPHER, '-', + "The encryption algorithm to use (any supported cipher)"}, + {"wrap", OPT_WRAP, 's', + "Key wrap algorithm to use when encrypting with key agreement"}, + {"aes128-wrap", OPT_AES128_WRAP, '-', "Use AES128 to wrap key"}, + {"aes192-wrap", OPT_AES192_WRAP, '-', "Use AES192 to wrap key"}, + {"aes256-wrap", OPT_AES256_WRAP, '-', "Use AES256 to wrap key"}, + {"des3-wrap", OPT_3DES_WRAP, '-', "Use 3DES-EDE to wrap key"}, + {"debug_decrypt", OPT_DEBUG_DECRYPT, '-', + "Disable MMA protection, return error if no recipient found (see doc)"}, + + OPT_SECTION("Signing"), + {"md", OPT_MD, 's', "Digest algorithm to use"}, + {"signer", OPT_SIGNER, 's', "Signer certificate input file"}, {"certfile", OPT_CERTFILE, '<', "Other certificates file"}, + {"cades", OPT_CADES, '-', + "Include signingCertificate attribute (CAdES-BES)"}, + {"nodetach", OPT_NODETACH, '-', "Use opaque signing"}, + {"nocerts", OPT_NOCERTS, '-', + "Don't include signer's certificate when signing"}, + {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"}, + {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"}, + {"receipt_request_all", OPT_RR_ALL, '-', + "When signing, create a receipt request for all recipients"}, + {"receipt_request_first", OPT_RR_FIRST, '-', + "When signing, create a receipt request for first recipient"}, + {"receipt_request_from", OPT_RR_FROM, 's', + "Create signed receipt request with specified email address"}, + {"receipt_request_to", OPT_RR_TO, 's', + "Create signed receipt targeted to specified address"}, + + OPT_SECTION("Verification"), + {"signer", OPT_DUP, 's', "Signer certificate(s) output file"}, + {"content", OPT_CONTENT, '<', + "Supply or override content for detached signature"}, + {"no_content_verify", OPT_NO_CONTENT_VERIFY, '-', + "Do not verify signed content signatures"}, + {"no_attr_verify", OPT_NO_ATTR_VERIFY, '-', + "Do not verify signed attribute signatures"}, + {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"}, + {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"}, + {"nointern", OPT_NOINTERN, '-', + "Don't search certificates in message for signer"}, + {"cades", OPT_DUP, '-', "Check signingCertificate (CAdES-BES)"}, + {"verify_retcode", OPT_VERIFY_RETCODE, '-', + "Exit non-zero on verification failure"}, {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, - {"CApath", OPT_CAPATH, '/', "trusted certificates directory"}, + {"CApath", OPT_CAPATH, '/', "Trusted certificates directory"}, + {"CAstore", OPT_CASTORE, ':', "Trusted certificates store URI"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, - {"content", OPT_CONTENT, '<', - "Supply or override content for detached signature"}, - {"print", OPT_PRINT, '-', - "For the -cmsout operation print out all fields of the CMS structure"}, - {"secretkey", OPT_SECRETKEY, 's'}, - {"secretkeyid", OPT_SECRETKEYID, 's'}, - {"pwri_password", OPT_PWRI_PASSWORD, 's'}, - {"econtent_type", OPT_ECONTENT_TYPE, 's'}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store"}, + + OPT_SECTION("Output"), + {"keyid", OPT_KEYID, '-', "Use subject key identifier"}, + {"econtent_type", OPT_ECONTENT_TYPE, 's', "OID for external content"}, + {"text", OPT_TEXT, '-', "Include or delete text MIME headers"}, + {"certsout", OPT_CERTSOUT, '>', "Certificate output file"}, {"to", OPT_TO, 's', "To address"}, {"from", OPT_FROM, 's', "From address"}, {"subject", OPT_SUBJECT, 's', "Subject"}, - {"signer", OPT_SIGNER, 's', "Signer certificate file"}, - {"recip", OPT_RECIP, '<', "Recipient cert file for decryption"}, - {"certsout", OPT_CERTSOUT, '>', "Certificate output file"}, - {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"}, - {"inkey", OPT_INKEY, 's', - "Input private key (if not signer or recipient)"}, - {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"}, - {"keyopt", OPT_KEYOPT, 's', "Set public key parameters as n:v pairs"}, - {"receipt_request_from", OPT_RR_FROM, 's'}, - {"receipt_request_to", OPT_RR_TO, 's'}, - {"", OPT_CIPHER, '-', "Any supported cipher"}, - OPT_R_OPTIONS, + + OPT_SECTION("Printing"), + {"noout", OPT_NOOUT, '-', + "For the -cmsout operation do not output the parsed CMS structure"}, + {"print", OPT_PRINT, '-', + "For the -cmsout operation print out all fields of the CMS structure"}, + {"nameopt", OPT_NAMEOPT, 's', + "For the -print option specifies various strings printing options"}, + {"receipt_request_print", OPT_RR_PRINT, '-', "Print CMS Receipt Request" }, + OPT_V_OPTIONS, - {"aes128-wrap", OPT_AES128_WRAP, '-', "Use AES128 to wrap key"}, - {"aes192-wrap", OPT_AES192_WRAP, '-', "Use AES192 to wrap key"}, - {"aes256-wrap", OPT_AES256_WRAP, '-', "Use AES256 to wrap key"}, -# ifndef OPENSSL_NO_DES - {"des3-wrap", OPT_3DES_WRAP, '-', "Use 3DES-EDE to wrap key"}, -# endif -# ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, -# endif {NULL} }; +static CMS_ContentInfo *load_content_info(int informat, BIO *in, int flags, + BIO **indata, const char *name) +{ + CMS_ContentInfo *ret, *ci; + + ret = CMS_ContentInfo_new_ex(app_get0_libctx(), app_get0_propq()); + if (ret == NULL) { + BIO_printf(bio_err, "Error allocating CMS_contentinfo\n"); + return NULL; + } + switch (informat) { + case FORMAT_SMIME: + ci = SMIME_read_CMS_ex(in, flags, indata, &ret); + break; + case FORMAT_PEM: + ci = PEM_read_bio_CMS(in, &ret, NULL, NULL); + break; + case FORMAT_ASN1: + ci = d2i_CMS_bio(in, &ret); + break; + default: + BIO_printf(bio_err, "Bad input format for %s\n", name); + goto err; + } + if (ci == NULL) { + BIO_printf(bio_err, "Error reading %s Content Info\n", name); + goto err; + } + return ret; + err: + CMS_ContentInfo_free(ret); + return NULL; +} + int cms_main(int argc, char **argv) { + CONF *conf = NULL; ASN1_OBJECT *econtent_type = NULL; BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; CMS_ContentInfo *cms = NULL, *rcms = NULL; CMS_ReceiptRequest *rr = NULL; ENGINE *e = NULL; EVP_PKEY *key = NULL; - const EVP_CIPHER *cipher = NULL, *wrap_cipher = NULL; - const EVP_MD *sign_md = NULL; + EVP_CIPHER *cipher = NULL, *wrap_cipher = NULL; + EVP_MD *sign_md = NULL; STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; - STACK_OF(X509) *encerts = NULL, *other = NULL; - X509 *cert = NULL, *recip = NULL, *signer = NULL; + STACK_OF(X509) *encerts = sk_X509_new_null(), *other = NULL; + X509 *cert = NULL, *recip = NULL, *signer = NULL, *originator = NULL; X509_STORE *store = NULL; - X509_VERIFY_PARAM *vpm = NULL; + X509_VERIFY_PARAM *vpm = X509_VERIFY_PARAM_new(); char *certfile = NULL, *keyfile = NULL, *contfile = NULL; - const char *CAfile = NULL, *CApath = NULL; - char *certsoutfile = NULL; - int noCAfile = 0, noCApath = 0; + const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL; + char *certsoutfile = NULL, *digestname = NULL, *wrapname = NULL; + int noCAfile = 0, noCApath = 0, noCAstore = 0; char *infile = NULL, *outfile = NULL, *rctfile = NULL; - char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile = NULL; + char *passinarg = NULL, *passin = NULL, *signerfile = NULL; + char *originatorfile = NULL, *recipfile = NULL, *ciphername = NULL; char *to = NULL, *from = NULL, *subject = NULL, *prog; cms_key_param *key_first = NULL, *key_param = NULL; - int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched = 0; + int flags = CMS_DETACHED, binary_files = 0; + int noout = 0, print = 0, keyidx = -1, vpmtouched = 0; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; int operation = 0, ret = 1, rr_print = 0, rr_allorfirst = -1; - int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_PEM; + int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_UNDEF; size_t secret_keylen = 0, secret_keyidlen = 0; unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; unsigned char *secret_key = NULL, *secret_keyid = NULL; long ltmp; const char *mime_eol = "\n"; OPTION_CHOICE o; + OSSL_LIB_CTX *libctx = app_get0_libctx(); - if ((vpm = X509_VERIFY_PARAM_new()) == NULL) - return 1; + if (encerts == NULL || vpm == NULL) + goto end; prog = opt_init(argc, argv, cms_options); while ((o = opt_next()) != OPT_EOF) { @@ -244,6 +337,7 @@ int cms_main(int argc, char **argv) case OPT_OUT: outfile = opt_arg(); break; + case OPT_ENCRYPT: operation = SMIME_ENCRYPT; break; @@ -253,49 +347,50 @@ int cms_main(int argc, char **argv) case OPT_SIGN: operation = SMIME_SIGN; break; - case OPT_SIGN_RECEIPT: - operation = SMIME_SIGN_RECEIPT; + case OPT_VERIFY: + operation = SMIME_VERIFY; break; case OPT_RESIGN: operation = SMIME_RESIGN; break; - case OPT_VERIFY: - operation = SMIME_VERIFY; - break; - case OPT_VERIFY_RETCODE: - verify_retcode = 1; + case OPT_SIGN_RECEIPT: + operation = SMIME_SIGN_RECEIPT; break; case OPT_VERIFY_RECEIPT: operation = SMIME_VERIFY_RECEIPT; rctfile = opt_arg(); break; - case OPT_CMSOUT: - operation = SMIME_CMSOUT; - break; - case OPT_DATA_OUT: - operation = SMIME_DATAOUT; + case OPT_VERIFY_RETCODE: + verify_retcode = 1; break; - case OPT_DATA_CREATE: - operation = SMIME_DATA_CREATE; + case OPT_DIGEST_CREATE: + operation = SMIME_DIGEST_CREATE; break; case OPT_DIGEST_VERIFY: operation = SMIME_DIGEST_VERIFY; break; - case OPT_DIGEST_CREATE: - operation = SMIME_DIGEST_CREATE; - break; case OPT_COMPRESS: operation = SMIME_COMPRESS; break; case OPT_UNCOMPRESS: operation = SMIME_UNCOMPRESS; break; + case OPT_ED_ENCRYPT: + operation = SMIME_ENCRYPTED_ENCRYPT; + break; case OPT_ED_DECRYPT: operation = SMIME_ENCRYPTED_DECRYPT; break; - case OPT_ED_ENCRYPT: - operation = SMIME_ENCRYPTED_ENCRYPT; + case OPT_DATA_CREATE: + operation = SMIME_DATA_CREATE; + break; + case OPT_DATA_OUT: + operation = SMIME_DATA_OUT; break; + case OPT_CMSOUT: + operation = SMIME_CMSOUT; + break; + case OPT_DEBUG_DECRYPT: flags |= CMS_DEBUG_DECRYPT; break; @@ -326,6 +421,9 @@ int cms_main(int argc, char **argv) case OPT_BINARY: flags |= CMS_BINARY; break; + case OPT_CADES: + flags |= CMS_CADES; + break; case OPT_KEYID: flags |= CMS_USE_KEYID; break; @@ -361,14 +459,9 @@ int cms_main(int argc, char **argv) rr_allorfirst = 1; break; case OPT_RCTFORM: - if (rctformat == FORMAT_SMIME) - rcms = SMIME_read_CMS(rctin, NULL); - else if (rctformat == FORMAT_PEM) - rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); - else if (rctformat == FORMAT_ASN1) - if (!opt_format(opt_arg(), - OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat)) - goto opthelp; + if (!opt_format(opt_arg(), + OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat)) + goto opthelp; break; case OPT_CERTFILE: certfile = opt_arg(); @@ -379,12 +472,18 @@ int cms_main(int argc, char **argv) case OPT_CAPATH: CApath = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_NOCAFILE: noCAfile = 1; break; case OPT_NOCAPATH: noCApath = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_IN: infile = opt_arg(); break; @@ -406,6 +505,10 @@ int cms_main(int argc, char **argv) case OPT_PRINT: noout = print = 1; break; + case OPT_NAMEOPT: + if (!set_nameopt(opt_arg())) + goto opthelp; + break; case OPT_SECRETKEY: if (secret_key != NULL) { BIO_printf(bio_err, "Invalid key (supplied twice) %s\n", @@ -466,8 +569,7 @@ int cms_main(int argc, char **argv) certsoutfile = opt_arg(); break; case OPT_MD: - if (!opt_md(opt_arg(), &sign_md)) - goto end; + digestname = opt_arg(); break; case OPT_SIGNER: /* If previous -signer argument add signer to list */ @@ -486,6 +588,9 @@ int cms_main(int argc, char **argv) } signerfile = opt_arg(); break; + case OPT_ORIGINATOR: + originatorfile = opt_arg(); + break; case OPT_INKEY: /* If previous -inkey argument add signer to list */ if (keyfile != NULL) { @@ -511,9 +616,7 @@ int cms_main(int argc, char **argv) break; case OPT_RECIP: if (operation == SMIME_ENCRYPT) { - if (encerts == NULL && (encerts = sk_X509_new_null()) == NULL) - goto end; - cert = load_cert(opt_arg(), FORMAT_PEM, + cert = load_cert(opt_arg(), FORMAT_UNDEF, "recipient certificate file"); if (cert == NULL) goto end; @@ -524,13 +627,12 @@ int cms_main(int argc, char **argv) } break; case OPT_CIPHER: - if (!opt_cipher(opt_unknown(), &cipher)) - goto end; + ciphername = opt_unknown(); break; case OPT_KEYOPT: keyidx = -1; if (operation == SMIME_ENCRYPT) { - if (encerts != NULL) + if (sk_X509_num(encerts) > 0) keyidx += sk_X509_num(encerts); } else { if (keyfile != NULL || signerfile != NULL) @@ -568,22 +670,43 @@ int cms_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; - case OPT_3DES_WRAP: -# ifndef OPENSSL_NO_DES - wrap_cipher = EVP_des_ede3_wrap(); -# endif + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; break; - case OPT_AES128_WRAP: - wrap_cipher = EVP_aes_128_wrap(); + case OPT_CONFIG: + conf = app_load_config_modules(opt_arg()); + if (conf == NULL) + goto end; break; - case OPT_AES192_WRAP: - wrap_cipher = EVP_aes_192_wrap(); + case OPT_WRAP: + wrapname = opt_arg(); break; + case OPT_AES128_WRAP: + case OPT_AES192_WRAP: case OPT_AES256_WRAP: - wrap_cipher = EVP_aes_256_wrap(); + case OPT_3DES_WRAP: + wrapname = opt_flag() + 1; break; } } + if (!app_RAND_load()) + goto end; + + if (digestname != NULL) { + if (!opt_md(digestname, &sign_md)) + goto end; + } + if (ciphername != NULL) { + if (!opt_cipher_any(ciphername, &cipher)) + goto end; + } + if (wrapname != NULL) { + if (!opt_cipher_any(wrapname, &wrap_cipher)) + goto end; + } + + /* Remaining args are files to process. */ argc = opt_num_rest(); argv = opt_rest(); @@ -601,6 +724,20 @@ int cms_main(int argc, char **argv) goto opthelp; } + if ((flags & CMS_CADES) != 0) { + if ((flags & CMS_NOATTR) != 0) { + BIO_puts(bio_err, "Incompatible options: " + "CAdES requires signed attributes\n"); + goto opthelp; + } + if (operation == SMIME_VERIFY + && (flags & (CMS_NO_SIGNER_CERT_VERIFY | CMS_NO_ATTR_VERIFY)) != 0) { + BIO_puts(bio_err, "Incompatible options: CAdES validation requires" + " certs and signed attributes validations\n"); + goto opthelp; + } + } + if (operation & SMIME_SIGNERS) { if (keyfile != NULL && signerfile == NULL) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); @@ -633,7 +770,7 @@ int cms_main(int argc, char **argv) } } else if (operation == SMIME_ENCRYPT) { if (*argv == NULL && secret_key == NULL - && pwri_pass == NULL && encerts == NULL) { + && pwri_pass == NULL && sk_X509_num(encerts) <= 0) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); goto opthelp; } @@ -649,25 +786,36 @@ int cms_main(int argc, char **argv) ret = 2; - if (!(operation & SMIME_SIGNERS)) + if ((operation & SMIME_SIGNERS) == 0) { + if ((flags & CMS_DETACHED) == 0) + BIO_printf(bio_err, + "Warning: -nodetach option is ignored for non-signing operation\n"); + flags &= ~CMS_DETACHED; + } + if ((operation & SMIME_IP) == 0 && contfile != NULL) + BIO_printf(bio_err, + "Warning: -contfile option is ignored for the given operation\n"); - if (!(operation & SMIME_OP)) - if (flags & CMS_BINARY) + if ((flags & CMS_BINARY) != 0) { + if (!(operation & SMIME_OP)) outformat = FORMAT_BINARY; - - if (!(operation & SMIME_IP)) - if (flags & CMS_BINARY) + if (!(operation & SMIME_IP)) informat = FORMAT_BINARY; + if ((operation & SMIME_SIGNERS) != 0 && (flags & CMS_DETACHED) != 0) + binary_files = 1; + if ((operation & SMIME_IP) != 0 && contfile == NULL) + binary_files = 1; + } if (operation == SMIME_ENCRYPT) { if (!cipher) { -# ifndef OPENSSL_NO_DES - cipher = EVP_des_ede3_cbc(); -# else +#ifndef OPENSSL_NO_DES + cipher = (EVP_CIPHER *)EVP_des_ede3_cbc(); +#else BIO_printf(bio_err, "No cipher selected\n"); goto end; -# endif +#endif } if (secret_key && !secret_keyid) { @@ -675,44 +823,54 @@ int cms_main(int argc, char **argv) goto end; } - if (*argv && encerts == NULL) - if ((encerts = sk_X509_new_null()) == NULL) - goto end; - while (*argv) { - if ((cert = load_cert(*argv, FORMAT_PEM, - "recipient certificate file")) == NULL) - goto end; - sk_X509_push(encerts, cert); - cert = NULL; - argv++; + if (*argv != NULL) { + if (operation == SMIME_ENCRYPT) { + for (; *argv != NULL; argv++) { + cert = load_cert(*argv, FORMAT_UNDEF, + "recipient certificate file"); + if (cert == NULL) + goto end; + sk_X509_push(encerts, cert); + cert = NULL; + } + } else { + BIO_printf(bio_err, "Warning: recipient certificate file parameters ignored for operation other than -encrypt\n"); + } } } if (certfile != NULL) { - if (!load_certs(certfile, &other, FORMAT_PEM, NULL, - "certificate file")) { + if (!load_certs(certfile, 0, &other, NULL, "certificate file")) { ERR_print_errors(bio_err); goto end; } } if (recipfile != NULL && (operation == SMIME_DECRYPT)) { - if ((recip = load_cert(recipfile, FORMAT_PEM, + if ((recip = load_cert(recipfile, FORMAT_UNDEF, "recipient certificate file")) == NULL) { ERR_print_errors(bio_err); goto end; } } + if (originatorfile != NULL) { + if ((originator = load_cert(originatorfile, FORMAT_UNDEF, + "originator certificate file")) == NULL) { + ERR_print_errors(bio_err); + goto end; + } + } + if (operation == SMIME_SIGN_RECEIPT) { - if ((signer = load_cert(signerfile, FORMAT_PEM, + if ((signer = load_cert(signerfile, FORMAT_UNDEF, "receipt signer certificate file")) == NULL) { ERR_print_errors(bio_err); goto end; } } - if (operation == SMIME_DECRYPT) { + if ((operation == SMIME_DECRYPT) || (operation == SMIME_ENCRYPT)) { if (keyfile == NULL) keyfile = recipfile; } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) { @@ -723,31 +881,20 @@ int cms_main(int argc, char **argv) } if (keyfile != NULL) { - key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key"); if (key == NULL) goto end; } - in = bio_open_default(infile, 'r', informat); + in = bio_open_default(infile, 'r', + binary_files ? FORMAT_BINARY : informat); if (in == NULL) goto end; if (operation & SMIME_IP) { - if (informat == FORMAT_SMIME) { - cms = SMIME_read_CMS(in, &indata); - } else if (informat == FORMAT_PEM) { - cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); - } else if (informat == FORMAT_ASN1) { - cms = d2i_CMS_bio(in, NULL); - } else { - BIO_printf(bio_err, "Bad input format for CMS file\n"); - goto end; - } - - if (cms == NULL) { - BIO_printf(bio_err, "Error reading S/MIME message\n"); + cms = load_content_info(informat, in, flags, &indata, "SMIME"); + if (cms == NULL) goto end; - } if (contfile != NULL) { BIO_free(indata); if ((indata = BIO_new_file(contfile, "rb")) == NULL) { @@ -770,34 +917,25 @@ int cms_main(int argc, char **argv) if (rctfile != NULL) { char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r"; + if ((rctin = BIO_new_file(rctfile, rctmode)) == NULL) { BIO_printf(bio_err, "Can't open receipt file %s\n", rctfile); goto end; } - if (rctformat == FORMAT_SMIME) { - rcms = SMIME_read_CMS(rctin, NULL); - } else if (rctformat == FORMAT_PEM) { - rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); - } else if (rctformat == FORMAT_ASN1) { - rcms = d2i_CMS_bio(rctin, NULL); - } else { - BIO_printf(bio_err, "Bad input format for receipt\n"); - goto end; - } - - if (rcms == NULL) { - BIO_printf(bio_err, "Error reading receipt\n"); + rcms = load_content_info(rctformat, rctin, 0, NULL, "receipt"); + if (rcms == NULL) goto end; - } } - out = bio_open_default(outfile, 'w', outformat); + out = bio_open_default(outfile, 'w', + binary_files ? FORMAT_BINARY : outformat); if (out == NULL) goto end; if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) { - if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) + if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) == NULL) goto end; X509_STORE_set_verify_cb(store, cms_cb); if (vpmtouched) @@ -807,39 +945,49 @@ int cms_main(int argc, char **argv) ret = 3; if (operation == SMIME_DATA_CREATE) { - cms = CMS_data_create(in, flags); + cms = CMS_data_create_ex(in, flags, libctx, app_get0_propq()); } else if (operation == SMIME_DIGEST_CREATE) { - cms = CMS_digest_create(in, sign_md, flags); + cms = CMS_digest_create_ex(in, sign_md, flags, libctx, app_get0_propq()); } else if (operation == SMIME_COMPRESS) { cms = CMS_compress(in, -1, flags); } else if (operation == SMIME_ENCRYPT) { int i; flags |= CMS_PARTIAL; - cms = CMS_encrypt(NULL, in, cipher, flags); + cms = CMS_encrypt_ex(NULL, in, cipher, flags, libctx, app_get0_propq()); if (cms == NULL) goto end; for (i = 0; i < sk_X509_num(encerts); i++) { CMS_RecipientInfo *ri; cms_key_param *kparam; - int tflags = flags; + int tflags = flags | CMS_KEY_PARAM; + /* This flag enforces allocating the EVP_PKEY_CTX for the recipient here */ + EVP_PKEY_CTX *pctx; X509 *x = sk_X509_value(encerts, i); + int res; + for (kparam = key_first; kparam; kparam = kparam->next) { if (kparam->idx == i) { - tflags |= CMS_KEY_PARAM; break; } } - ri = CMS_add1_recipient_cert(cms, x, tflags); + ri = CMS_add1_recipient(cms, x, key, originator, tflags); if (ri == NULL) goto end; + + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (kparam != NULL) { - EVP_PKEY_CTX *pctx; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (!cms_set_pkey_param(pctx, kparam->param)) goto end; } + + res = EVP_PKEY_CTX_ctrl(pctx, -1, -1, + EVP_PKEY_CTRL_CIPHER, + EVP_CIPHER_get_nid(cipher), NULL); + if (res <= 0 && res != -2) + goto end; + if (CMS_RecipientInfo_type(ri) == CMS_RECIPINFO_AGREE - && wrap_cipher) { + && wrap_cipher != NULL) { EVP_CIPHER_CTX *wctx; wctx = CMS_RecipientInfo_kari_get0_ctx(ri); EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL); @@ -871,8 +1019,8 @@ int cms_main(int argc, char **argv) goto end; } } else if (operation == SMIME_ENCRYPTED_ENCRYPT) { - cms = CMS_EncryptedData_encrypt(in, cipher, - secret_key, secret_keylen, flags); + cms = CMS_EncryptedData_encrypt_ex(in, cipher, secret_key, + secret_keylen, flags, libctx, app_get0_propq()); } else if (operation == SMIME_SIGN_RECEIPT) { CMS_ContentInfo *srcms = NULL; @@ -900,19 +1048,17 @@ int cms_main(int argc, char **argv) flags |= CMS_STREAM; } flags |= CMS_PARTIAL; - cms = CMS_sign(NULL, NULL, other, in, flags); + cms = CMS_sign_ex(NULL, NULL, other, in, flags, libctx, app_get0_propq()); if (cms == NULL) goto end; if (econtent_type != NULL) CMS_set1_eContentType(cms, econtent_type); - if (rr_to != NULL) { - rr = make_receipt_request(rr_to, rr_allorfirst, rr_from); - if (rr == NULL) { - BIO_puts(bio_err, - "Signed Receipt Request Creation Error\n"); - goto end; - } + if (rr_to != NULL + && ((rr = make_receipt_request(rr_to, rr_allorfirst, rr_from)) + == NULL)) { + BIO_puts(bio_err, "Signed Receipt Request Creation Error\n"); + goto end; } } else { flags |= CMS_REUSE_DIGEST; @@ -924,16 +1070,17 @@ int cms_main(int argc, char **argv) signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); - signer = load_cert(signerfile, FORMAT_PEM, "signer certificate"); + signer = load_cert(signerfile, FORMAT_UNDEF, "signer certificate"); if (signer == NULL) { ret = 2; goto end; } - key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key"); if (key == NULL) { ret = 2; goto end; } + for (kparam = key_first; kparam; kparam = kparam->next) { if (kparam->idx == i) { tflags |= CMS_KEY_PARAM; @@ -983,7 +1130,7 @@ int cms_main(int argc, char **argv) } if (key != NULL) { - if (!CMS_decrypt_set1_pkey(cms, key, recip)) { + if (!CMS_decrypt_set1_pkey_and_peer(cms, key, recip, originator)) { BIO_puts(bio_err, "Error decrypting CMS using private key\n"); goto end; } @@ -1000,7 +1147,7 @@ int cms_main(int argc, char **argv) BIO_printf(bio_err, "Error decrypting CMS structure\n"); goto end; } - } else if (operation == SMIME_DATAOUT) { + } else if (operation == SMIME_DATA_OUT) { if (!CMS_data(cms, out, flags)) goto end; } else if (operation == SMIME_UNCOMPRESS) { @@ -1019,16 +1166,18 @@ int cms_main(int argc, char **argv) goto end; } else if (operation == SMIME_VERIFY) { if (CMS_verify(cms, other, store, indata, out, flags) > 0) { - BIO_printf(bio_err, "Verification successful\n"); + BIO_printf(bio_err, "%s Verification successful\n", + (flags & CMS_CADES) != 0 ? "CAdES" : "CMS"); } else { - BIO_printf(bio_err, "Verification failure\n"); + BIO_printf(bio_err, "%s Verification failure\n", + (flags & CMS_CADES) != 0 ? "CAdES" : "CMS"); if (verify_retcode) ret = verify_err + 32; goto end; } if (signerfile != NULL) { - STACK_OF(X509) *signers; - signers = CMS_get0_signers(cms); + STACK_OF(X509) *signers = CMS_get0_signers(cms); + if (!save_certs(signerfile, signers)) { BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); @@ -1049,8 +1198,19 @@ int cms_main(int argc, char **argv) } } else { if (noout) { - if (print) - CMS_ContentInfo_print_ctx(out, cms, 0, NULL); + if (print) { + ASN1_PCTX *pctx = NULL; + if (get_nameopt() != XN_FLAG_ONELINE) { + pctx = ASN1_PCTX_new(); + if (pctx != NULL) { /* Print anyway if malloc failed */ + ASN1_PCTX_set_flags(pctx, ASN1_PCTX_FLAGS_SHOW_ABSENT); + ASN1_PCTX_set_str_flags(pctx, get_nameopt()); + ASN1_PCTX_set_nm_flags(pctx, get_nameopt()); + } + } + CMS_ContentInfo_print_ctx(out, cms, 0, pctx); + ASN1_PCTX_free(pctx); + } } else if (outformat == FORMAT_SMIME) { if (to) BIO_printf(out, "To: %s%s", to, mime_eol); @@ -1103,6 +1263,9 @@ int cms_main(int argc, char **argv) X509_free(recip); X509_free(signer); EVP_PKEY_free(key); + EVP_CIPHER_free(cipher); + EVP_CIPHER_free(wrap_cipher); + EVP_MD_free(sign_md); CMS_ContentInfo_free(cms); CMS_ContentInfo_free(rcms); release_engine(e); @@ -1111,6 +1274,7 @@ int cms_main(int argc, char **argv) BIO_free(indata); BIO_free_all(out); OPENSSL_free(passin); + NCONF_free(conf); return ret; } @@ -1247,12 +1411,12 @@ static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns) return NULL; } -static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) - *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING) - *rr_from) +static CMS_ReceiptRequest +*make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst, + STACK_OF(OPENSSL_STRING) *rr_from) { STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL; - CMS_ReceiptRequest *rr; + rct_to = make_names_stack(rr_to); if (rct_to == NULL) goto err; @@ -1263,9 +1427,8 @@ static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) } else { rct_from = NULL; } - rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from, - rct_to); - return rr; + return CMS_ReceiptRequest_create0_ex(NULL, -1, rr_allorfirst, rct_from, + rct_to, app_get0_libctx()); err: sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free); return NULL; @@ -1288,5 +1451,3 @@ static int cms_set_pkey_param(EVP_PKEY_CTX *pctx, } return 1; } - -#endif diff --git a/crypto/openssl/apps/crl.c b/crypto/openssl/apps/crl.c index 031fada14c84..2158a107e551 100644 --- a/crypto/openssl/apps/crl.c +++ b/crypto/openssl/apps/crl.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,22 +19,38 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_IN, OPT_OUTFORM, OPT_OUT, OPT_KEYFORM, OPT_KEY, OPT_ISSUER, OPT_LASTUPDATE, OPT_NEXTUPDATE, OPT_FINGERPRINT, - OPT_CRLNUMBER, OPT_BADSIG, OPT_GENDELTA, OPT_CAPATH, OPT_CAFILE, - OPT_NOCAPATH, OPT_NOCAFILE, OPT_VERIFY, OPT_TEXT, OPT_HASH, OPT_HASH_OLD, - OPT_NOOUT, OPT_NAMEOPT, OPT_MD + OPT_CRLNUMBER, OPT_BADSIG, OPT_GENDELTA, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, + OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_VERIFY, OPT_DATEOPT, OPT_TEXT, OPT_HASH, + OPT_HASH_OLD, OPT_NOOUT, OPT_NAMEOPT, OPT_MD, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS crl_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format; default PEM"}, + {"verify", OPT_VERIFY, '-', "Verify CRL signature"}, + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file - default stdin"}, - {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, - {"out", OPT_OUT, '>', "output file - default stdout"}, - {"keyform", OPT_KEYFORM, 'F', "Private key file format (PEM or ENGINE)"}, + {"inform", OPT_INFORM, 'F', "CRL input format (DER or PEM); has no effect"}, {"key", OPT_KEY, '<', "CRL signing Private key to use"}, + {"keyform", OPT_KEYFORM, 'F', "Private key file format (DER/PEM/P12); has no effect"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "output file - default stdout"}, + {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, + {"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."}, + {"text", OPT_TEXT, '-', "Print out a text format version"}, + {"hash", OPT_HASH, '-', "Print hash value"}, +#ifndef OPENSSL_NO_MD5 + {"hash_old", OPT_HASH_OLD, '-', "Print old-style (MD5) hash value"}, +#endif + {"nameopt", OPT_NAMEOPT, 's', "Certificate subject/issuer name printing options"}, + {"", OPT_MD, '-', "Any supported digest"}, + + OPT_SECTION("CRL"), {"issuer", OPT_ISSUER, '-', "Print issuer DN"}, {"lastupdate", OPT_LASTUPDATE, '-', "Set lastUpdate field"}, {"nextupdate", OPT_NEXTUPDATE, '-', "Set nextUpdate field"}, @@ -43,20 +59,18 @@ const OPTIONS crl_options[] = { {"crlnumber", OPT_CRLNUMBER, '-', "Print CRL number"}, {"badsig", OPT_BADSIG, '-', "Corrupt last byte of loaded CRL signature (for test)" }, {"gendelta", OPT_GENDELTA, '<', "Other CRL to compare/diff to the Input one"}, + + OPT_SECTION("Certificate"), {"CApath", OPT_CAPATH, '/', "Verify CRL using certificates in dir"}, {"CAfile", OPT_CAFILE, '<', "Verify CRL using certificates in file name"}, + {"CAstore", OPT_CASTORE, ':', "Verify CRL using certificates in store URI"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, - {"verify", OPT_VERIFY, '-', "Verify CRL signature"}, - {"text", OPT_TEXT, '-', "Print out a text format version"}, - {"hash", OPT_HASH, '-', "Print hash value"}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, - {"", OPT_MD, '-', "Any supported digest"}, -#ifndef OPENSSL_NO_MD5 - {"hash_old", OPT_HASH_OLD, '-', "Print old-style (MD5) hash value"}, -#endif + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store"}, + OPT_PROV_OPTIONS, {NULL} }; @@ -69,14 +83,16 @@ int crl_main(int argc, char **argv) X509_LOOKUP *lookup = NULL; X509_OBJECT *xobj = NULL; EVP_PKEY *pkey; - const EVP_MD *digest = EVP_sha1(); + EVP_MD *digest = (EVP_MD *)EVP_sha1(); char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL; - const char *CAfile = NULL, *CApath = NULL, *prog; + char *digestname = NULL; + const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL, *prog; OPTION_CHOICE o; int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = 0; - int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; + int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, keyformat = FORMAT_UNDEF; int ret = 1, num = 0, badsig = 0, fingerprint = 0, crlnumber = 0; - int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0; + int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0, noCAstore = 0; + unsigned long dateopt = ASN1_DTFLGS_RFC822; int i; #ifndef OPENSSL_NO_MD5 int hash_old = 0; @@ -109,7 +125,7 @@ int crl_main(int argc, char **argv) outfile = opt_arg(); break; case OPT_KEYFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat)) goto opthelp; break; case OPT_KEY: @@ -126,12 +142,19 @@ int crl_main(int argc, char **argv) CAfile = opt_arg(); do_ver = 1; break; + case OPT_CASTORE: + CAstore = opt_arg(); + do_ver = 1; + break; case OPT_NOCAPATH: noCApath = 1; break; case OPT_NOCAFILE: noCAfile = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_HASH_OLD: #ifndef OPENSSL_NO_MD5 hash_old = ++num; @@ -140,6 +163,10 @@ int crl_main(int argc, char **argv) case OPT_VERIFY: do_ver = 1; break; + case OPT_DATEOPT: + if (!set_dateopt(&dateopt, opt_arg())) + goto opthelp; + break; case OPT_TEXT: text = 1; break; @@ -156,7 +183,7 @@ int crl_main(int argc, char **argv) nextupdate = ++num; break; case OPT_NOOUT: - noout = ++num; + noout = 1; break; case OPT_FINGERPRINT: fingerprint = ++num; @@ -172,20 +199,31 @@ int crl_main(int argc, char **argv) goto opthelp; break; case OPT_MD: - if (!opt_md(opt_unknown(), &digest)) - goto opthelp; + digestname = opt_unknown(); + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No remaining args. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; - x = load_crl(infile, informat); + if (digestname != NULL) { + if (!opt_md(digestname, &digest)) + goto opthelp; + } + x = load_crl(infile, informat, 1, "CRL"); if (x == NULL) goto end; if (do_ver) { - if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) + if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) == NULL) goto end; lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) @@ -204,7 +242,7 @@ int crl_main(int argc, char **argv) } pkey = X509_get_pubkey(X509_OBJECT_get0_X509(xobj)); X509_OBJECT_free(xobj); - if (!pkey) { + if (pkey == NULL) { BIO_printf(bio_err, "Error getting CRL issuer public key\n"); goto end; } @@ -218,17 +256,17 @@ int crl_main(int argc, char **argv) BIO_printf(bio_err, "verify OK\n"); } - if (crldiff) { + if (crldiff != NULL) { X509_CRL *newcrl, *delta; if (!keyfile) { BIO_puts(bio_err, "Missing CRL signing key\n"); goto end; } - newcrl = load_crl(crldiff, informat); + newcrl = load_crl(crldiff, informat, 0, "other CRL"); if (!newcrl) goto end; pkey = load_key(keyfile, keyformat, 0, NULL, NULL, "CRL signing key"); - if (!pkey) { + if (pkey == NULL) { X509_CRL_free(newcrl); goto end; } @@ -254,39 +292,54 @@ int crl_main(int argc, char **argv) if (num) { for (i = 1; i <= num; i++) { if (issuer == i) { - print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), - get_nameopt()); + print_name(bio_out, "issuer=", X509_CRL_get_issuer(x)); } if (crlnumber == i) { ASN1_INTEGER *crlnum; + crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, NULL, NULL); BIO_printf(bio_out, "crlNumber="); if (crlnum) { + BIO_puts(bio_out, "0x"); i2a_ASN1_INTEGER(bio_out, crlnum); ASN1_INTEGER_free(crlnum); - } else + } else { BIO_puts(bio_out, ""); + } BIO_printf(bio_out, "\n"); } if (hash == i) { - BIO_printf(bio_out, "%08lx\n", - X509_NAME_hash(X509_CRL_get_issuer(x))); + int ok; + unsigned long hash_value = + X509_NAME_hash_ex(X509_CRL_get_issuer(x), app_get0_libctx(), + app_get0_propq(), &ok); + + if (num > 1) + BIO_printf(bio_out, "issuer name hash="); + if (ok) { + BIO_printf(bio_out, "%08lx\n", hash_value); + } else { + BIO_puts(bio_out, ""); + goto end; + } } #ifndef OPENSSL_NO_MD5 if (hash_old == i) { + if (num > 1) + BIO_printf(bio_out, "issuer name old hash="); BIO_printf(bio_out, "%08lx\n", X509_NAME_hash_old(X509_CRL_get_issuer(x))); } #endif if (lastupdate == i) { BIO_printf(bio_out, "lastUpdate="); - ASN1_TIME_print(bio_out, X509_CRL_get0_lastUpdate(x)); + ASN1_TIME_print_ex(bio_out, X509_CRL_get0_lastUpdate(x), dateopt); BIO_printf(bio_out, "\n"); } if (nextupdate == i) { BIO_printf(bio_out, "nextUpdate="); if (X509_CRL_get0_nextUpdate(x)) - ASN1_TIME_print(bio_out, X509_CRL_get0_nextUpdate(x)); + ASN1_TIME_print_ex(bio_out, X509_CRL_get0_nextUpdate(x), dateopt); else BIO_printf(bio_out, "NONE"); BIO_printf(bio_out, "\n"); @@ -301,7 +354,7 @@ int crl_main(int argc, char **argv) goto end; } BIO_printf(bio_out, "%s Fingerprint=", - OBJ_nid2sn(EVP_MD_type(digest))); + EVP_MD_get0_name(digest)); for (j = 0; j < (int)n; j++) { BIO_printf(bio_out, "%02X%c", md[j], (j + 1 == (int)n) ? '\n' : ':'); @@ -335,6 +388,7 @@ int crl_main(int argc, char **argv) if (ret != 0) ERR_print_errors(bio_err); BIO_free_all(out); + EVP_MD_free(digest); X509_CRL_free(x); X509_STORE_CTX_free(ctx); X509_STORE_free(store); diff --git a/crypto/openssl/apps/crl2p7.c b/crypto/openssl/apps/crl2pkcs7.c similarity index 94% rename from crypto/openssl/apps/crl2p7.c rename to crypto/openssl/apps/crl2pkcs7.c index 3f619bf5278e..fe59e654270d 100644 --- a/crypto/openssl/apps/crl2p7.c +++ b/crypto/openssl/apps/crl2pkcs7.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -22,19 +22,27 @@ static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile); typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOCRL, OPT_CERTFILE + OPT_COMMON, + OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOCRL, OPT_CERTFILE, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS crl2pkcs7_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, - {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, {"nocrl", OPT_NOCRL, '-', "No crl to load, just certs from '-certfile'"}, {"certfile", OPT_CERTFILE, '<', "File of chain of certs to a trusted CA; can be repeated"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + + OPT_PROV_OPTIONS, {NULL} }; @@ -88,8 +96,14 @@ int crl2pkcs7_main(int argc, char **argv) if (!sk_OPENSSL_STRING_push(certflst, opt_arg())) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No remaining args. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; diff --git a/crypto/openssl/apps/dgst.c b/crypto/openssl/apps/dgst.c index f9b184be4cc1..1042d940f49c 100644 --- a/crypto/openssl/apps/dgst.c +++ b/crypto/openssl/apps/dgst.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -24,7 +24,7 @@ #undef BUFSIZE #define BUFSIZE 1024*8 -int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, +int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *sig_name, const char *md_name, const char *file); @@ -36,49 +36,58 @@ struct doall_dgst_digests { }; typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_LIST, + OPT_COMMON, + OPT_LIST, OPT_C, OPT_R, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY, OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL, OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT, - OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT, + OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT, OPT_XOFLEN, OPT_DIGEST, - OPT_R_ENUM + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS dgst_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] [file...]\n"}, - {OPT_HELP_STR, 1, '-', - " file... files to digest (default is stdin)\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"list", OPT_LIST, '-', "List digests"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, + {"engine_impl", OPT_ENGINE_IMPL, '-', + "Also use engine given by -engine for digest operations"}, +#endif + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + + OPT_SECTION("Output"), {"c", OPT_C, '-', "Print the digest with separating colons"}, {"r", OPT_R, '-', "Print the digest in coreutils format"}, {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"sign", OPT_SIGN, 's', "Sign digest using private key"}, - {"verify", OPT_VERIFY, 's', - "Verify a signature using public key"}, - {"prverify", OPT_PRVERIFY, 's', - "Verify a signature using private key"}, - {"signature", OPT_SIGNATURE, '<', "File with signature to verify"}, - {"keyform", OPT_KEYFORM, 'f', "Key file format (PEM or ENGINE)"}, + {"keyform", OPT_KEYFORM, 'f', "Key file format (ENGINE, other values ignored)"}, {"hex", OPT_HEX, '-', "Print as hex dump"}, {"binary", OPT_BINARY, '-', "Print in binary form"}, + {"xoflen", OPT_XOFLEN, 'p', "Output length for XOF algorithms. To obtain the maximum security strength set this to 32 (or greater) for SHAKE128, and 64 (or greater) for SHAKE256"}, {"d", OPT_DEBUG, '-', "Print debug info"}, {"debug", OPT_DEBUG, '-', "Print debug info"}, - {"fips-fingerprint", OPT_FIPS_FINGERPRINT, '-', - "Compute HMAC with the key used in OpenSSL-FIPS fingerprint"}, + + OPT_SECTION("Signing"), + {"sign", OPT_SIGN, 's', "Sign digest using private key"}, + {"verify", OPT_VERIFY, 's', "Verify a signature using public key"}, + {"prverify", OPT_PRVERIFY, 's', "Verify a signature using private key"}, + {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, + {"signature", OPT_SIGNATURE, '<', "File with signature to verify"}, {"hmac", OPT_HMAC, 's', "Create hashed MAC with key"}, {"mac", OPT_MAC, 's', "Create MAC (not necessarily HMAC)"}, - {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"}, {"", OPT_DIGEST, '-', "Any supported digest"}, + {"fips-fingerprint", OPT_FIPS_FINGERPRINT, '-', + "Compute HMAC with the key used in OpenSSL-FIPS fingerprint"}, + OPT_R_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, - {"engine_impl", OPT_ENGINE_IMPL, '-', - "Also use engine given by -engine for digest operations"}, -#endif + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"file", 0, 0, "Files to digest (optional; default is stdin)"}, {NULL} }; @@ -89,21 +98,24 @@ int dgst_main(int argc, char **argv) EVP_PKEY *sigkey = NULL; STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; char *hmac_key = NULL; - char *mac_name = NULL; + char *mac_name = NULL, *digestname = NULL; char *passinarg = NULL, *passin = NULL; - const EVP_MD *md = NULL, *m; + EVP_MD *md = NULL; const char *outfile = NULL, *keyfile = NULL, *prog = NULL; const char *sigfile = NULL; + const char *md_name = NULL; OPTION_CHOICE o; - int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0; - int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0; + int separator = 0, debug = 0, keyform = FORMAT_UNDEF, siglen = 0; + int i, ret = EXIT_FAILURE, out_bin = -1, want_pub = 0, do_verify = 0; + int xoflen = 0; unsigned char *buf = NULL, *sigbuf = NULL; int engine_impl = 0; struct doall_dgst_digests dec; - prog = opt_progname(argv[0]); buf = app_malloc(BUFSIZE, "I/O buffer"); - md = EVP_get_digestbyname(prog); + md = (EVP_MD *)EVP_get_digestbyname(argv[0]); + if (md != NULL) + digestname = argv[0]; prog = opt_init(argc, argv, dgst_options); while ((o = opt_next()) != OPT_EOF) { @@ -115,7 +127,7 @@ int dgst_main(int argc, char **argv) goto end; case OPT_HELP: opt_help(dgst_options); - ret = 0; + ret = EXIT_SUCCESS; goto end; case OPT_LIST: BIO_printf(bio_out, "Supported digests:\n"); @@ -124,7 +136,7 @@ int dgst_main(int argc, char **argv) OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, show_digests, &dec); BIO_printf(bio_out, "\n"); - ret = 0; + ret = EXIT_SUCCESS; goto end; case OPT_C: separator = 1; @@ -172,6 +184,9 @@ int dgst_main(int argc, char **argv) case OPT_BINARY: out_bin = 1; break; + case OPT_XOFLEN: + xoflen = atoi(opt_arg()); + break; case OPT_DEBUG: debug = 1; break; @@ -197,18 +212,29 @@ int dgst_main(int argc, char **argv) goto opthelp; break; case OPT_DIGEST: - if (!opt_md(opt_unknown(), &m)) - goto opthelp; - md = m; + digestname = opt_unknown(); + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; break; } } + + /* Remaining args are files to digest. */ argc = opt_num_rest(); argv = opt_rest(); if (keyfile != NULL && argc > 1) { BIO_printf(bio_err, "%s: Can only sign or verify one file.\n", prog); goto end; } + if (!app_RAND_load()) + goto end; + + if (digestname != NULL) { + if (!opt_md(digestname, &md)) + goto opthelp; + } if (do_verify && sigfile == NULL) { BIO_printf(bio_err, @@ -220,13 +246,11 @@ int dgst_main(int argc, char **argv) in = BIO_new(BIO_s_file()); bmd = BIO_new(BIO_f_md()); - if ((in == NULL) || (bmd == NULL)) { - ERR_print_errors(bio_err); + if (in == NULL || bmd == NULL) goto end; - } if (debug) { - BIO_set_callback(in, BIO_debug_callback); + BIO_set_callback_ex(in, BIO_debug_callback_ex); /* needed for windows 3.1 */ BIO_set_callback_arg(in, (char *)bio_err); } @@ -248,7 +272,7 @@ int dgst_main(int argc, char **argv) goto end; if ((!(mac_name == NULL) + !(keyfile == NULL) + !(hmac_key == NULL)) > 1) { - BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); + BIO_printf(bio_err, "MAC and signing key cannot both be specified\n"); goto end; } @@ -256,16 +280,16 @@ int dgst_main(int argc, char **argv) int type; if (want_pub) - sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file"); + sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "public key"); else - sigkey = load_key(keyfile, keyform, 0, passin, e, "key file"); + sigkey = load_key(keyfile, keyform, 0, passin, e, "private key"); if (sigkey == NULL) { /* * load_[pub]key() has already printed an appropriate message */ goto end; } - type = EVP_PKEY_id(sigkey); + type = EVP_PKEY_get_id(sigkey); if (type == EVP_PKEY_ED25519 || type == EVP_PKEY_ED448) { /* * We implement PureEdDSA for these which doesn't have a separate @@ -278,36 +302,34 @@ int dgst_main(int argc, char **argv) if (mac_name != NULL) { EVP_PKEY_CTX *mac_ctx = NULL; - int r = 0; - if (!init_gen_str(&mac_ctx, mac_name, impl, 0)) - goto mac_end; + + if (!init_gen_str(&mac_ctx, mac_name, impl, 0, NULL, NULL)) + goto end; if (macopts != NULL) { - char *macopt; for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { - macopt = sk_OPENSSL_STRING_value(macopts, i); + char *macopt = sk_OPENSSL_STRING_value(macopts, i); + if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { - BIO_printf(bio_err, - "MAC parameter error \"%s\"\n", macopt); - ERR_print_errors(bio_err); - goto mac_end; + EVP_PKEY_CTX_free(mac_ctx); + BIO_printf(bio_err, "MAC parameter error \"%s\"\n", macopt); + goto end; } } } - if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) { - BIO_puts(bio_err, "Error generating key\n"); - ERR_print_errors(bio_err); - goto mac_end; - } - r = 1; - mac_end: + + sigkey = app_keygen(mac_ctx, mac_name, 0, 0 /* not verbose */); + /* Verbose output would make external-tests gost-engine fail */ EVP_PKEY_CTX_free(mac_ctx); - if (r == 0) - goto end; } if (hmac_key != NULL) { + if (md == NULL) { + md = (EVP_MD *)EVP_sha256(); + digestname = SN_sha256; + } sigkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, impl, - (unsigned char *)hmac_key, -1); + (unsigned char *)hmac_key, + strlen(hmac_key)); if (sigkey == NULL) goto end; } @@ -315,28 +337,37 @@ int dgst_main(int argc, char **argv) if (sigkey != NULL) { EVP_MD_CTX *mctx = NULL; EVP_PKEY_CTX *pctx = NULL; - int r; + int res; + if (BIO_get_md_ctx(bmd, &mctx) <= 0) { BIO_printf(bio_err, "Error getting context\n"); - ERR_print_errors(bio_err); goto end; } if (do_verify) - r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey); + if (impl == NULL) + res = EVP_DigestVerifyInit_ex(mctx, &pctx, digestname, + app_get0_libctx(), + app_get0_propq(), sigkey, NULL); + else + res = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey); else - r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey); - if (!r) { + if (impl == NULL) + res = EVP_DigestSignInit_ex(mctx, &pctx, digestname, + app_get0_libctx(), + app_get0_propq(), sigkey, NULL); + else + res = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey); + if (res == 0) { BIO_printf(bio_err, "Error setting context\n"); - ERR_print_errors(bio_err); goto end; } if (sigopts != NULL) { - char *sigopt; for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { - sigopt = sk_OPENSSL_STRING_value(sigopts, i); + char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); + if (pkey_ctrl_string(pctx, sigopt) <= 0) { - BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Signature parameter error \"%s\"\n", + sigopt); goto end; } } @@ -347,32 +378,29 @@ int dgst_main(int argc, char **argv) EVP_MD_CTX *mctx = NULL; if (BIO_get_md_ctx(bmd, &mctx) <= 0) { BIO_printf(bio_err, "Error getting context\n"); - ERR_print_errors(bio_err); goto end; } if (md == NULL) - md = EVP_sha256(); + md = (EVP_MD *)EVP_sha256(); if (!EVP_DigestInit_ex(mctx, md, impl)) { BIO_printf(bio_err, "Error setting digest\n"); - ERR_print_errors(bio_err); goto end; } } if (sigfile != NULL && sigkey != NULL) { BIO *sigbio = BIO_new_file(sigfile, "rb"); + if (sigbio == NULL) { BIO_printf(bio_err, "Error opening signature file %s\n", sigfile); - ERR_print_errors(bio_err); goto end; } - siglen = EVP_PKEY_size(sigkey); + siglen = EVP_PKEY_get_size(sigkey); sigbuf = app_malloc(siglen, "signature buffer"); siglen = BIO_read(sigbio, sigbuf, siglen); BIO_free(sigbio); if (siglen <= 0) { BIO_printf(bio_err, "Error reading signature file %s\n", sigfile); - ERR_print_errors(bio_err); goto end; } } @@ -380,48 +408,62 @@ int dgst_main(int argc, char **argv) if (md == NULL) { EVP_MD_CTX *tctx; + BIO_get_md_ctx(bmd, &tctx); - md = EVP_MD_CTX_md(tctx); + md = EVP_MD_CTX_get1_md(tctx); + } + if (md != NULL) + md_name = EVP_MD_get0_name(md); + + if (xoflen > 0) { + if (!(EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF)) { + BIO_printf(bio_err, "Length can only be specified for XOF\n"); + goto end; + } + /* + * Signing using XOF is not supported by any algorithms currently since + * each algorithm only calls EVP_DigestFinal_ex() in their sign_final + * and verify_final methods. + */ + if (sigkey != NULL) { + BIO_printf(bio_err, "Signing key cannot be specified for XOF\n"); + goto end; + } } if (argc == 0) { BIO_set_fp(in, stdin, BIO_NOCLOSE); - ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, - siglen, NULL, NULL, "stdin"); + ret = do_fp(out, buf, inp, separator, out_bin, xoflen, sigkey, sigbuf, + siglen, NULL, md_name, "stdin"); } else { - const char *md_name = NULL, *sig_name = NULL; - if (!out_bin) { - if (sigkey != NULL) { - const EVP_PKEY_ASN1_METHOD *ameth; - ameth = EVP_PKEY_get0_asn1(sigkey); - if (ameth) - EVP_PKEY_asn1_get0_info(NULL, NULL, - NULL, NULL, &sig_name, ameth); - } - if (md != NULL) - md_name = EVP_MD_name(md); + const char *sig_name = NULL; + + if (out_bin == 0) { + if (sigkey != NULL) + sig_name = EVP_PKEY_get0_type_name(sigkey); } - ret = 0; + ret = EXIT_SUCCESS; for (i = 0; i < argc; i++) { - int r; if (BIO_read_filename(in, argv[i]) <= 0) { perror(argv[i]); - ret++; + ret = EXIT_FAILURE; continue; } else { - r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, - siglen, sig_name, md_name, argv[i]); + if (do_fp(out, buf, inp, separator, out_bin, xoflen, + sigkey, sigbuf, siglen, sig_name, md_name, argv[i])) + ret = EXIT_FAILURE; } - if (r) - ret = r; (void)BIO_reset(bmd); } } end: + if (ret != EXIT_SUCCESS) + ERR_print_errors(bio_err); OPENSSL_clear_free(buf, BUFSIZE); BIO_free(in); OPENSSL_free(passin); BIO_free_all(out); + EVP_MD_free(md); EVP_PKEY_free(sigkey); sk_OPENSSL_STRING_free(sigopts); sk_OPENSSL_STRING_free(macopts); @@ -444,7 +486,7 @@ static void show_digests(const OBJ_NAME *name, void *arg) return; /* Filter out message digests that we cannot use */ - md = EVP_get_digestbyname(name->name); + md = EVP_MD_fetch(app_get0_libctx(), name->name, app_get0_propq()); if (md == NULL) return; @@ -496,20 +538,19 @@ static const char *newline_escape_filename(const char *file, int * backslash) } -int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, +int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *sig_name, const char *md_name, const char *file) { size_t len = BUFSIZE; - int i, backslash = 0, ret = 1; - unsigned char *sigbuf = NULL; + int i, backslash = 0, ret = EXIT_FAILURE; + unsigned char *allocated_buf = NULL; 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); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Read error in %s\n", file); goto end; } if (i == 0) @@ -522,37 +563,52 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, if (i > 0) { BIO_printf(out, "Verified OK\n"); } else if (i == 0) { - BIO_printf(out, "Verification Failure\n"); + BIO_printf(out, "Verification failure\n"); goto end; } else { - BIO_printf(bio_err, "Error Verifying Data\n"); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Error verifying data\n"); goto end; } - ret = 0; + ret = EXIT_SUCCESS; goto end; } if (key != NULL) { EVP_MD_CTX *ctx; - int pkey_len; + size_t tmplen; + BIO_get_md_ctx(bp, &ctx); - pkey_len = EVP_PKEY_size(key); - if (pkey_len > BUFSIZE) { - len = pkey_len; - sigbuf = app_malloc(len, "Signature buffer"); - buf = sigbuf; + if (!EVP_DigestSignFinal(ctx, NULL, &tmplen)) { + BIO_printf(bio_err, "Error getting maximum length of signed data\n"); + goto end; + } + if (tmplen > BUFSIZE) { + len = tmplen; + allocated_buf = app_malloc(len, "Signature buffer"); + buf = allocated_buf; } if (!EVP_DigestSignFinal(ctx, buf, &len)) { - BIO_printf(bio_err, "Error Signing Data\n"); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Error signing data\n"); + goto end; + } + } else if (xoflen > 0) { + EVP_MD_CTX *ctx; + + len = xoflen; + if (len > BUFSIZE) { + allocated_buf = app_malloc(len, "Digest buffer"); + buf = allocated_buf; + } + + BIO_get_md_ctx(bp, &ctx); + + if (!EVP_DigestFinalXOF(ctx, buf, len)) { + BIO_printf(bio_err, "Error Digesting Data\n"); goto end; } } else { len = BIO_gets(bp, (char *)buf, BUFSIZE); - if ((int)len < 0) { - ERR_print_errors(bio_err); + if ((int)len < 0) goto end; - } } if (binout) { @@ -587,10 +643,10 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, BIO_printf(out, "\n"); } - ret = 0; + ret = EXIT_SUCCESS; end: - if (sigbuf != NULL) - OPENSSL_clear_free(sigbuf, len); + if (allocated_buf != NULL) + OPENSSL_clear_free(allocated_buf, len); return ret; } diff --git a/crypto/openssl/apps/dh1024.pem b/crypto/openssl/apps/dh1024.pem deleted file mode 100644 index 813e8a4a4822..000000000000 --- a/crypto/openssl/apps/dh1024.pem +++ /dev/null @@ -1,10 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR -Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL -/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC ------END DH PARAMETERS----- - -These are the 1024-bit DH parameters from "Internet Key Exchange -Protocol Version 2 (IKEv2)": https://tools.ietf.org/html/rfc5996 - -See https://tools.ietf.org/html/rfc2412 for how they were generated. diff --git a/crypto/openssl/apps/dh2048.pem b/crypto/openssl/apps/dh2048.pem deleted file mode 100644 index 288a20997e5a..000000000000 --- a/crypto/openssl/apps/dh2048.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb -IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft -awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT -mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh -fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq -5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg== ------END DH PARAMETERS----- - -These are the 2048-bit DH parameters from "More Modular Exponential -(MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)": -https://tools.ietf.org/html/rfc3526 - -See https://tools.ietf.org/html/rfc2412 for how they were generated. diff --git a/crypto/openssl/apps/dh4096.pem b/crypto/openssl/apps/dh4096.pem deleted file mode 100644 index 08560e1284e2..000000000000 --- a/crypto/openssl/apps/dh4096.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIICCAKCAgEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb -IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft -awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT -mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh -fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq -5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM -fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq -ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI -ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O -+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI -HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0BjGZ//////////8CAQI= ------END DH PARAMETERS----- - -These are the 4096-bit DH parameters from "More Modular Exponential -(MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)": -https://tools.ietf.org/html/rfc3526 - -See https://tools.ietf.org/html/rfc2412 for how they were generated. diff --git a/crypto/openssl/apps/dhparam.c b/crypto/openssl/apps/dhparam.c index 98c73214b53e..43906cea5649 100644 --- a/crypto/openssl/apps/dhparam.c +++ b/crypto/openssl/apps/dhparam.c @@ -1,13 +1,14 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include + #include #include #include @@ -17,61 +18,73 @@ #include #include #include +#include #include #include #include - -#ifndef OPENSSL_NO_DSA -# include -#endif +#include +#include +#include +#include +#include #define DEFBITS 2048 -static int dh_cb(int p, int n, BN_GENCB *cb); +static EVP_PKEY *dsa_to_dh(EVP_PKEY *dh); +static int gendh_cb(EVP_PKEY_CTX *ctx); typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT, - OPT_DSAPARAM, OPT_C, OPT_2, OPT_5, - OPT_R_ENUM + OPT_DSAPARAM, OPT_2, OPT_3, OPT_5, + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS dhparam_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [flags] [numbits]\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [numbits]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"in", OPT_IN, '<', "Input file"}, - {"inform", OPT_INFORM, 'F', "Input format, DER or PEM"}, - {"outform", OPT_OUTFORM, 'F', "Output format, DER or PEM"}, - {"out", OPT_OUT, '>', "Output file"}, {"check", OPT_CHECK, '-', "Check the DH parameters"}, - {"text", OPT_TEXT, '-', "Print a text form of the DH parameters"}, - {"noout", OPT_NOOUT, '-', "Don't output any DH parameters"}, - OPT_R_OPTIONS, - {"C", OPT_C, '-', "Print C code"}, - {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"}, - {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"}, -#ifndef OPENSSL_NO_DSA +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_DEPRECATED_3_0) {"dsaparam", OPT_DSAPARAM, '-', "Read or generate DSA parameters, convert to DH"}, #endif #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, #endif + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file"}, + {"inform", OPT_INFORM, 'F', "Input format, DER or PEM"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format, DER or PEM"}, + {"text", OPT_TEXT, '-', "Print a text form of the DH parameters"}, + {"noout", OPT_NOOUT, '-', "Don't output any DH parameters"}, + {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"}, + {"3", OPT_3, '-', "Generate parameters using 3 as the generator value"}, + {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"}, + + OPT_R_OPTIONS, + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"numbits", 0, 0, "Number of bits if generating parameters (optional)"}, {NULL} }; int dhparam_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; - DH *dh = NULL; + EVP_PKEY *pkey = NULL, *tmppkey = NULL; + EVP_PKEY_CTX *ctx = NULL; char *infile = NULL, *outfile = NULL, *prog; ENGINE *e = NULL; -#ifndef OPENSSL_NO_DSA int dsaparam = 0; -#endif - int i, text = 0, C = 0, ret = 1, num = 0, g = 0; + int text = 0, ret = 1, num = 0, g = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, check = 0, noout = 0; OPTION_CHOICE o; @@ -111,16 +124,14 @@ int dhparam_main(int argc, char **argv) text = 1; break; case OPT_DSAPARAM: -#ifndef OPENSSL_NO_DSA dsaparam = 1; -#endif - break; - case OPT_C: - C = 1; break; case OPT_2: g = 2; break; + case OPT_3: + g = 3; + break; case OPT_5: g = 5; break; @@ -131,24 +142,33 @@ int dhparam_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* One optional argument, bitsize to generate. */ argc = opt_num_rest(); argv = opt_rest(); - - if (argv[0] != NULL && (!opt_int(argv[0], &num) || num <= 0)) + if (argc == 1) { + if (!opt_int(argv[0], &num) || num <= 0) + goto opthelp; + } else if (argc != 0) { + goto opthelp; + } + if (!app_RAND_load()) goto end; if (g && !num) num = DEFBITS; -#ifndef OPENSSL_NO_DSA if (dsaparam && g) { BIO_printf(bio_err, - "generator may not be chosen for DSA parameters\n"); + "Error, generator may not be chosen for DSA parameters\n"); goto end; } -#endif out = bio_open_default(outfile, 'w', outformat); if (out == NULL) @@ -159,216 +179,238 @@ int dhparam_main(int argc, char **argv) g = 2; if (num) { + const char *alg = dsaparam ? "DSA" : "DH"; + + if (infile != NULL) { + BIO_printf(bio_err, "Warning, input file %s ignored\n", infile); + } - BN_GENCB *cb; - cb = BN_GENCB_new(); - if (cb == NULL) { - ERR_print_errors(bio_err); + ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), alg, app_get0_propq()); + if (ctx == NULL) { + BIO_printf(bio_err, + "Error, %s param generation context allocation failed\n", + alg); goto end; } + EVP_PKEY_CTX_set_cb(ctx, gendh_cb); + EVP_PKEY_CTX_set_app_data(ctx, bio_err); + BIO_printf(bio_err, + "Generating %s parameters, %d bit long %sprime\n", + alg, num, dsaparam ? "" : "safe "); - BN_GENCB_set(cb, dh_cb, bio_err); + if (EVP_PKEY_paramgen_init(ctx) <= 0) { + BIO_printf(bio_err, + "Error, unable to initialise %s parameters\n", + alg); + goto end; + } -#ifndef OPENSSL_NO_DSA if (dsaparam) { - DSA *dsa = DSA_new(); - - BIO_printf(bio_err, - "Generating DSA parameters, %d bit long prime\n", num); - if (dsa == NULL - || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, - cb)) { - DSA_free(dsa); - BN_GENCB_free(cb); - ERR_print_errors(bio_err); + if (EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, num) <= 0) { + BIO_printf(bio_err, "Error, unable to set DSA prime length\n"); goto end; } - - dh = DSA_dup_DH(dsa); - DSA_free(dsa); - if (dh == NULL) { - BN_GENCB_free(cb); - ERR_print_errors(bio_err); + } else { + if (EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, num) <= 0) { + BIO_printf(bio_err, "Error, unable to set DH prime length\n"); goto end; } - } else -#endif - { - dh = DH_new(); - BIO_printf(bio_err, - "Generating DH parameters, %d bit long safe prime, generator %d\n", - num, g); - BIO_printf(bio_err, "This is going to take a long time\n"); - if (dh == NULL || !DH_generate_parameters_ex(dh, num, g, cb)) { - BN_GENCB_free(cb); - ERR_print_errors(bio_err); + if (EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, g) <= 0) { + BIO_printf(bio_err, "Error, unable to set generator\n"); goto end; } } - BN_GENCB_free(cb); + tmppkey = app_paramgen(ctx, alg); + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + if (dsaparam) { + pkey = dsa_to_dh(tmppkey); + if (pkey == NULL) + goto end; + EVP_PKEY_free(tmppkey); + } else { + pkey = tmppkey; + } + tmppkey = NULL; } else { + OSSL_DECODER_CTX *decoderctx = NULL; + const char *keytype = "DH"; + int done; in = bio_open_default(infile, 'r', informat); if (in == NULL) goto end; -#ifndef OPENSSL_NO_DSA - if (dsaparam) { - DSA *dsa; - - if (informat == FORMAT_ASN1) - dsa = d2i_DSAparams_bio(in, NULL); - else /* informat == FORMAT_PEM */ - dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); - - if (dsa == NULL) { - BIO_printf(bio_err, "unable to load DSA parameters\n"); - ERR_print_errors(bio_err); - goto end; - } - - dh = DSA_dup_DH(dsa); - DSA_free(dsa); - if (dh == NULL) { - ERR_print_errors(bio_err); - goto end; - } - } else -#endif - { - if (informat == FORMAT_ASN1) { + do { + /* + * We assume we're done unless we explicitly want to retry and set + * this to 0 below. + */ + done = 1; + /* + * We set NULL for the keytype to allow any key type. We don't know + * if we're going to get DH or DHX (or DSA in the event of dsaparam). + * We check that we got one of those key types afterwards. + */ + decoderctx + = OSSL_DECODER_CTX_new_for_pkey(&tmppkey, + (informat == FORMAT_ASN1) + ? "DER" : "PEM", + NULL, + (informat == FORMAT_ASN1) + ? keytype : NULL, + OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, + NULL, NULL); + + if (decoderctx != NULL + && !OSSL_DECODER_from_bio(decoderctx, in) + && informat == FORMAT_ASN1 + && strcmp(keytype, "DH") == 0) { + /* + * When reading DER we explicitly state the expected keytype + * because, unlike PEM, there is no header to declare what + * the contents of the DER file are. The decoders just try + * and guess. Unfortunately with DHX key types they may guess + * wrong and think we have a DSA keytype. Therefore we try + * both DH and DHX sequentially. + */ + keytype = "DHX"; /* - * We have no PEM header to determine what type of DH params it - * is. We'll just try both. + * BIO_reset() returns 0 for success for file BIOs only!!! + * This won't work for stdin (and never has done) */ - dh = d2i_DHparams_bio(in, NULL); - /* BIO_reset() returns 0 for success for file BIOs only!!! */ - if (dh == NULL && BIO_reset(in) == 0) - dh = d2i_DHxparams_bio(in, NULL); - } else { - /* informat == FORMAT_PEM */ - dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); + if (BIO_reset(in) == 0) + done = 0; } + OSSL_DECODER_CTX_free(decoderctx); + } while (!done); + if (tmppkey == NULL) { + BIO_printf(bio_err, "Error, unable to load parameters\n"); + goto end; + } - if (dh == NULL) { - BIO_printf(bio_err, "unable to load DH parameters\n"); - ERR_print_errors(bio_err); + if (dsaparam) { + if (!EVP_PKEY_is_a(tmppkey, "DSA")) { + BIO_printf(bio_err, "Error, unable to load DSA parameters\n"); goto end; } + pkey = dsa_to_dh(tmppkey); + if (pkey == NULL) + goto end; + } else { + if (!EVP_PKEY_is_a(tmppkey, "DH") + && !EVP_PKEY_is_a(tmppkey, "DHX")) { + BIO_printf(bio_err, "Error, unable to load DH parameters\n"); + goto end; + } + pkey = tmppkey; + tmppkey = NULL; } - - /* dh != NULL */ } - if (text) { - DHparams_print(out, dh); - } + if (text) + EVP_PKEY_print_params(out, pkey, 4, NULL); if (check) { - if (!DH_check(dh, &i)) { - ERR_print_errors(bio_err); + ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), pkey, app_get0_propq()); + if (ctx == NULL) { + BIO_printf(bio_err, "Error, failed to check DH parameters\n"); goto end; } - if (i & DH_CHECK_P_NOT_PRIME) - BIO_printf(bio_err, "WARNING: p value is not prime\n"); - if (i & DH_CHECK_P_NOT_SAFE_PRIME) - BIO_printf(bio_err, "WARNING: p value is not a safe prime\n"); - if (i & DH_CHECK_Q_NOT_PRIME) - BIO_printf(bio_err, "WARNING: q value is not a prime\n"); - if (i & DH_CHECK_INVALID_Q_VALUE) - BIO_printf(bio_err, "WARNING: q value is invalid\n"); - if (i & DH_CHECK_INVALID_J_VALUE) - BIO_printf(bio_err, "WARNING: j value is invalid\n"); - if (i & DH_UNABLE_TO_CHECK_GENERATOR) - BIO_printf(bio_err, - "WARNING: unable to check the generator value\n"); - if (i & DH_NOT_SUITABLE_GENERATOR) - BIO_printf(bio_err, "WARNING: the g value is not a generator\n"); - if (i == 0) - BIO_printf(bio_err, "DH parameters appear to be ok.\n"); - if (num != 0 && i != 0) { - /* - * We have generated parameters but DH_check() indicates they are - * invalid! This should never happen! - */ - BIO_printf(bio_err, "ERROR: Invalid parameters generated\n"); + if (EVP_PKEY_param_check(ctx) <= 0) { + BIO_printf(bio_err, "Error, invalid parameters generated\n"); goto end; } - } - if (C) { - unsigned char *data; - int len, bits; - const BIGNUM *pbn, *gbn; - - len = DH_size(dh); - bits = DH_bits(dh); - DH_get0_pqg(dh, &pbn, NULL, &gbn); - data = app_malloc(len, "print a BN"); - - BIO_printf(out, "static DH *get_dh%d(void)\n{\n", bits); - print_bignum_var(out, pbn, "dhp", bits, data); - print_bignum_var(out, gbn, "dhg", bits, data); - BIO_printf(out, " DH *dh = DH_new();\n" - " BIGNUM *p, *g;\n" - "\n" - " if (dh == NULL)\n" - " return NULL;\n"); - BIO_printf(out, " p = BN_bin2bn(dhp_%d, sizeof(dhp_%d), NULL);\n", - bits, bits); - BIO_printf(out, " g = BN_bin2bn(dhg_%d, sizeof(dhg_%d), NULL);\n", - bits, bits); - BIO_printf(out, " if (p == NULL || g == NULL\n" - " || !DH_set0_pqg(dh, p, NULL, g)) {\n" - " DH_free(dh);\n" - " BN_free(p);\n" - " BN_free(g);\n" - " return NULL;\n" - " }\n"); - if (DH_get_length(dh) > 0) - BIO_printf(out, - " if (!DH_set_length(dh, %ld)) {\n" - " DH_free(dh);\n" - " return NULL;\n" - " }\n", DH_get_length(dh)); - BIO_printf(out, " return dh;\n}\n"); - OPENSSL_free(data); + BIO_printf(bio_err, "DH parameters appear to be ok.\n"); } if (!noout) { - const BIGNUM *q; - DH_get0_pqg(dh, NULL, &q, NULL); - if (outformat == FORMAT_ASN1) { - if (q != NULL) - i = i2d_DHxparams_bio(out, dh); - else - i = i2d_DHparams_bio(out, dh); - } else if (q != NULL) { - i = PEM_write_bio_DHxparams(out, dh); - } else { - i = PEM_write_bio_DHparams(out, dh); - } - if (!i) { - BIO_printf(bio_err, "unable to write DH parameters\n"); - ERR_print_errors(bio_err); + OSSL_ENCODER_CTX *ectx = + OSSL_ENCODER_CTX_new_for_pkey(pkey, + OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, + outformat == FORMAT_ASN1 + ? "DER" : "PEM", + NULL, NULL); + + if (ectx == NULL || !OSSL_ENCODER_to_bio(ectx, out)) { + OSSL_ENCODER_CTX_free(ectx); + BIO_printf(bio_err, "Error, unable to write DH parameters\n"); goto end; } + OSSL_ENCODER_CTX_free(ectx); } ret = 0; end: + if (ret != 0) + ERR_print_errors(bio_err); BIO_free(in); BIO_free_all(out); - DH_free(dh); + EVP_PKEY_free(pkey); + EVP_PKEY_free(tmppkey); + EVP_PKEY_CTX_free(ctx); release_engine(e); return ret; } -static int dh_cb(int p, int n, BN_GENCB *cb) +/* + * Historically we had the low level call DSA_dup_DH() to do this. + * That is now deprecated with no replacement. Since we still need to do this + * for backwards compatibility reasons, we do it "manually". + */ +static EVP_PKEY *dsa_to_dh(EVP_PKEY *dh) +{ + OSSL_PARAM_BLD *tmpl = NULL; + OSSL_PARAM *params = NULL; + BIGNUM *bn_p = NULL, *bn_q = NULL, *bn_g = NULL; + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; + + if (!EVP_PKEY_get_bn_param(dh, OSSL_PKEY_PARAM_FFC_P, &bn_p) + || !EVP_PKEY_get_bn_param(dh, OSSL_PKEY_PARAM_FFC_Q, &bn_q) + || !EVP_PKEY_get_bn_param(dh, OSSL_PKEY_PARAM_FFC_G, &bn_g)) { + BIO_printf(bio_err, "Error, failed to set DH parameters\n"); + goto err; + } + + if ((tmpl = OSSL_PARAM_BLD_new()) == NULL + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, + bn_p) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, + bn_q) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, + bn_g) + || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) { + BIO_printf(bio_err, "Error, failed to set DH parameters\n"); + goto err; + } + + ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), "DHX", app_get0_propq()); + if (ctx == NULL + || EVP_PKEY_fromdata_init(ctx) <= 0 + || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEY_PARAMETERS, params) <= 0) { + BIO_printf(bio_err, "Error, failed to set DH parameters\n"); + goto err; + } + + err: + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + OSSL_PARAM_BLD_free(tmpl); + BN_free(bn_p); + BN_free(bn_q); + BN_free(bn_g); + return pkey; +} + +static int gendh_cb(EVP_PKEY_CTX *ctx) { + int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); + BIO *b = EVP_PKEY_CTX_get_app_data(ctx); static const char symbols[] = ".+*\n"; char c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?'; - BIO_write(BN_GENCB_get_arg(cb), &c, 1); - (void)BIO_flush(BN_GENCB_get_arg(cb)); + BIO_write(b, &c, 1); + (void)BIO_flush(b); return 1; } diff --git a/crypto/openssl/apps/dsa.c b/crypto/openssl/apps/dsa.c index c7884df166b7..51c02843539f 100644 --- a/crypto/openssl/apps/dsa.c +++ b/crypto/openssl/apps/dsa.c @@ -1,13 +1,14 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include + #include #include #include @@ -21,29 +22,29 @@ #include #include #include +#include +#include +#include + +#ifndef OPENSSL_NO_RC4 +# define DEFAULT_PVK_ENCR_STRENGTH 2 +#else +# define DEFAULT_PVK_ENCR_STRENGTH 0 +#endif typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENGINE, /* Do not change the order here; see case statements below */ OPT_PVK_NONE, OPT_PVK_WEAK, OPT_PVK_STRONG, OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_PUBIN, - OPT_PUBOUT, OPT_CIPHER, OPT_PASSIN, OPT_PASSOUT + OPT_PUBOUT, OPT_CIPHER, OPT_PASSIN, OPT_PASSOUT, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS dsa_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'f', "Input format, DER PEM PVK"}, - {"outform", OPT_OUTFORM, 'f', "Output format, DER PEM PVK"}, - {"in", OPT_IN, 's', "Input key"}, - {"out", OPT_OUT, '>', "Output file"}, - {"noout", OPT_NOOUT, '-', "Don't print key out"}, - {"text", OPT_TEXT, '-', "Print the key in text"}, - {"modulus", OPT_MODULUS, '-', "Print the DSA public value"}, - {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, - {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"", OPT_CIPHER, '-', "Any supported cipher"}, #ifndef OPENSSL_NO_RC4 {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"}, @@ -53,24 +54,43 @@ const OPTIONS dsa_options[] = { #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, #endif + + OPT_SECTION("Input"), + {"in", OPT_IN, 's', "Input key"}, + {"inform", OPT_INFORM, 'f', "Input format (DER/PEM/PVK); has no effect"}, + {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'f', "Output format, DER PEM PVK"}, + {"noout", OPT_NOOUT, '-', "Don't print key out"}, + {"text", OPT_TEXT, '-', "Print the key in text"}, + {"modulus", OPT_MODULUS, '-', "Print the DSA public value"}, + {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + + OPT_PROV_OPTIONS, {NULL} }; int dsa_main(int argc, char **argv) { BIO *out = NULL; - DSA *dsa = NULL; ENGINE *e = NULL; - const EVP_CIPHER *enc = NULL; + EVP_PKEY *pkey = NULL; + EVP_CIPHER *enc = NULL; char *infile = NULL, *outfile = NULL, *prog; char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL; OPTION_CHOICE o; - int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0; - int i, modulus = 0, pubin = 0, pubout = 0, ret = 1; -#ifndef OPENSSL_NO_RC4 - int pvk_encr = 2; -#endif + int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, text = 0, noout = 0; + int modulus = 0, pubin = 0, pubout = 0, ret = 1; + int pvk_encr = DEFAULT_PVK_ENCR_STRENGTH; int private = 0; + const char *output_type = NULL, *ciphername = NULL; + const char *output_structure = NULL; + int selection = 0; + OSSL_ENCODER_CTX *ectx = NULL; prog = opt_init(argc, argv, dsa_options); while ((o = opt_next()) != OPT_EOF) { @@ -131,15 +151,24 @@ int dsa_main(int argc, char **argv) pubout = 1; break; case OPT_CIPHER: - if (!opt_cipher(opt_unknown(), &enc)) + ciphername = opt_unknown(); + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) goto end; break; } } + + /* No extra args. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; + if (ciphername != NULL) { + if (!opt_cipher(ciphername, &enc)) + goto end; + } private = pubin || pubout ? 0 : 1; if (text && !pubin) private = 1; @@ -150,24 +179,20 @@ int dsa_main(int argc, char **argv) } BIO_printf(bio_err, "read DSA key\n"); - { - EVP_PKEY *pkey; - - if (pubin) - pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key"); - else - pkey = load_key(infile, informat, 1, passin, e, "Private Key"); + if (pubin) + pkey = load_pubkey(infile, informat, 1, passin, e, "public key"); + else + pkey = load_key(infile, informat, 1, passin, e, "private key"); - if (pkey != NULL) { - dsa = EVP_PKEY_get1_DSA(pkey); - EVP_PKEY_free(pkey); - } - } - if (dsa == NULL) { + if (pkey == NULL) { BIO_printf(bio_err, "unable to load Key\n"); ERR_print_errors(bio_err); goto end; } + if (!EVP_PKEY_is_a(pkey, "DSA")) { + BIO_printf(bio_err, "Not a DSA key\n"); + goto end; + } out = bio_open_owner(outfile, outformat, private); if (out == NULL) @@ -175,7 +200,8 @@ int dsa_main(int argc, char **argv) if (text) { assert(pubin || private); - if (!DSA_print(out, dsa, 0)) { + if ((pubin && EVP_PKEY_print_public(out, pkey, 0, NULL) <= 0) + || (!pubin && EVP_PKEY_print_private(out, pkey, 0, NULL) <= 0)) { perror(outfile); ERR_print_errors(bio_err); goto end; @@ -183,11 +209,16 @@ int dsa_main(int argc, char **argv) } if (modulus) { - const BIGNUM *pub_key = NULL; - DSA_get0_key(dsa, &pub_key, NULL); + BIGNUM *pub_key = NULL; + + if (!EVP_PKEY_get_bn_param(pkey, "pub", &pub_key)) { + ERR_print_errors(bio_err); + goto end; + } BIO_printf(out, "Public Key="); BN_print(out, pub_key); BIO_printf(out, "\n"); + BN_free(pub_key); } if (noout) { @@ -196,63 +227,83 @@ int dsa_main(int argc, char **argv) } BIO_printf(bio_err, "writing DSA key\n"); if (outformat == FORMAT_ASN1) { - if (pubin || pubout) { - i = i2d_DSA_PUBKEY_bio(out, dsa); - } else { - assert(private); - i = i2d_DSAPrivateKey_bio(out, dsa); - } + output_type = "DER"; } else if (outformat == FORMAT_PEM) { - if (pubin || pubout) { - i = PEM_write_bio_DSA_PUBKEY(out, dsa); - } else { - assert(private); - i = PEM_write_bio_DSAPrivateKey(out, dsa, enc, - NULL, 0, NULL, passout); - } -#ifndef OPENSSL_NO_RSA - } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { - EVP_PKEY *pk; - pk = EVP_PKEY_new(); - if (pk == NULL) - goto end; - - EVP_PKEY_set1_DSA(pk, dsa); - if (outformat == FORMAT_PVK) { - if (pubin) { - BIO_printf(bio_err, "PVK form impossible with public key input\n"); - EVP_PKEY_free(pk); - goto end; - } - assert(private); -# ifdef OPENSSL_NO_RC4 - BIO_printf(bio_err, "PVK format not supported\n"); - EVP_PKEY_free(pk); + output_type = "PEM"; + } else if (outformat == FORMAT_MSBLOB) { + output_type = "MSBLOB"; + } else if (outformat == FORMAT_PVK) { + if (pubin) { + BIO_printf(bio_err, "PVK form impossible with public key input\n"); goto end; -# else - i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); -# endif - } else if (pubin || pubout) { - i = i2b_PublicKey_bio(out, pk); - } else { - assert(private); - i = i2b_PrivateKey_bio(out, pk); } - EVP_PKEY_free(pk); -#endif + output_type = "PVK"; } else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } - if (i <= 0) { - BIO_printf(bio_err, "unable to write private key\n"); - ERR_print_errors(bio_err); + + if (outformat == FORMAT_ASN1 || outformat == FORMAT_PEM) { + if (pubout || pubin) + output_structure = "SubjectPublicKeyInfo"; + else + output_structure = "type-specific"; + } + + /* Select what you want in the output */ + if (pubout || pubin) { + selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + } else { + assert(private); + selection = (OSSL_KEYMGMT_SELECT_KEYPAIR + | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS); + } + + /* Perform the encoding */ + ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, output_type, + output_structure, NULL); + if (OSSL_ENCODER_CTX_get_num_encoders(ectx) == 0) { + BIO_printf(bio_err, "%s format not supported\n", output_type); + goto end; + } + + /* Passphrase setup */ + if (enc != NULL) + OSSL_ENCODER_CTX_set_cipher(ectx, EVP_CIPHER_get0_name(enc), NULL); + + /* Default passphrase prompter */ + if (enc != NULL || outformat == FORMAT_PVK) { + OSSL_ENCODER_CTX_set_passphrase_ui(ectx, get_ui_method(), NULL); + if (passout != NULL) + /* When passout given, override the passphrase prompter */ + OSSL_ENCODER_CTX_set_passphrase(ectx, + (const unsigned char *)passout, + strlen(passout)); + } + + /* PVK requires a bit more */ + if (outformat == FORMAT_PVK) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_int("encrypt-level", &pvk_encr); + if (!OSSL_ENCODER_CTX_set_params(ectx, params)) { + BIO_printf(bio_err, "invalid PVK encryption level\n"); + goto end; + } + } + + if (!OSSL_ENCODER_to_bio(ectx, out)) { + BIO_printf(bio_err, "unable to write key\n"); goto end; } ret = 0; end: + if (ret != 0) + ERR_print_errors(bio_err); + OSSL_ENCODER_CTX_free(ectx); BIO_free_all(out); - DSA_free(dsa); + EVP_PKEY_free(pkey); + EVP_CIPHER_free(enc); release_engine(e); OPENSSL_free(passin); OPENSSL_free(passout); diff --git a/crypto/openssl/apps/dsaparam.c b/crypto/openssl/apps/dsaparam.c index 75589ac6bc4e..b5555282be6e 100644 --- a/crypto/openssl/apps/dsaparam.c +++ b/crypto/openssl/apps/dsaparam.c @@ -1,15 +1,17 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include + #include #include +#include "apps.h" #include #include #include "apps.h" @@ -21,39 +23,54 @@ #include #include -static int dsa_cb(int p, int n, BN_GENCB *cb); +static int verbose = 0; + +static int gendsa_cb(EVP_PKEY_CTX *ctx); typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C, - OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_R_ENUM + OPT_COMMON, + OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, + OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_VERBOSE, + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS dsaparam_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [numbits]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, +#endif + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file"}, - {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + + OPT_SECTION("Output"), {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, {"text", OPT_TEXT, '-', "Print as text"}, - {"C", OPT_C, '-', "Output C code"}, {"noout", OPT_NOOUT, '-', "No output"}, + {"verbose", OPT_VERBOSE, '-', "Verbose output"}, {"genkey", OPT_GENKEY, '-', "Generate a DSA key"}, + OPT_R_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, -#endif + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"numbits", 0, 0, "Number of bits if generating parameters (optional)"}, {NULL} }; int dsaparam_main(int argc, char **argv) { ENGINE *e = NULL; - DSA *dsa = NULL; - BIO *in = NULL, *out = NULL; - BN_GENCB *cb = NULL; + BIO *out = NULL; + EVP_PKEY *params = NULL, *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; int numbits = -1, num = 0, genkey = 0; - int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0; + int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, noout = 0; int ret = 1, i, text = 0, private = 0; char *infile = NULL, *outfile = NULL, *prog; OPTION_CHOICE o; @@ -90,9 +107,6 @@ int dsaparam_main(int argc, char **argv) case OPT_TEXT: text = 1; break; - case OPT_C: - C = 1; - break; case OPT_GENKEY: genkey = 1; break; @@ -100,29 +114,45 @@ int dsaparam_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_NOOUT: noout = 1; break; + case OPT_VERBOSE: + verbose = 1; + break; } } + + /* Optional arg is bitsize. */ argc = opt_num_rest(); argv = opt_rest(); - if (argc == 1) { if (!opt_int(argv[0], &num) || num < 0) - goto end; - /* generate a key */ - numbits = num; + goto opthelp; + } else if (argc != 0) { + goto opthelp; } + if (!app_RAND_load()) + goto end; + + /* generate a key */ + numbits = num; private = genkey ? 1 : 0; - in = bio_open_default(infile, 'r', informat); - if (in == NULL) - goto end; out = bio_open_owner(outfile, outformat, private); if (out == NULL) goto end; + ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), "DSA", app_get0_propq()); + if (ctx == NULL) { + BIO_printf(bio_err, + "Error, DSA parameter generation context allocation failed\n"); + goto end; + } if (numbits > 0) { if (numbits > OPENSSL_DSA_MAX_MODULUS_BITS) BIO_printf(bio_err, @@ -130,74 +160,34 @@ int dsaparam_main(int argc, char **argv) " Your key size is %d! Larger key size may behave not as expected.\n", OPENSSL_DSA_MAX_MODULUS_BITS, numbits); - cb = BN_GENCB_new(); - if (cb == NULL) { - BIO_printf(bio_err, "Error allocating BN_GENCB object\n"); - goto end; + EVP_PKEY_CTX_set_cb(ctx, gendsa_cb); + EVP_PKEY_CTX_set_app_data(ctx, bio_err); + if (verbose) { + BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", + num); + BIO_printf(bio_err, "This could take some time\n"); } - BN_GENCB_set(cb, dsa_cb, bio_err); - dsa = DSA_new(); - if (dsa == NULL) { - BIO_printf(bio_err, "Error allocating DSA object\n"); + if (EVP_PKEY_paramgen_init(ctx) <= 0) { + BIO_printf(bio_err, + "Error, DSA key generation paramgen init failed\n"); goto end; } - BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", - num); - BIO_printf(bio_err, "This could take some time\n"); - if (!DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, cb)) { - ERR_print_errors(bio_err); - BIO_printf(bio_err, "Error, DSA key generation failed\n"); + if (EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, num) <= 0) { + BIO_printf(bio_err, + "Error, DSA key generation setting bit length failed\n"); goto end; } - } else if (informat == FORMAT_ASN1) { - dsa = d2i_DSAparams_bio(in, NULL); + params = app_paramgen(ctx, "DSA"); } else { - dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); + params = load_keyparams(infile, informat, 1, "DSA", "DSA parameters"); } - if (dsa == NULL) { - BIO_printf(bio_err, "unable to load DSA parameters\n"); - ERR_print_errors(bio_err); + if (params == NULL) { + /* Error message should already have been displayed */ goto end; } if (text) { - DSAparams_print(out, dsa); - } - - if (C) { - const BIGNUM *p = NULL, *q = NULL, *g = NULL; - unsigned char *data; - int len, bits_p; - - DSA_get0_pqg(dsa, &p, &q, &g); - len = BN_num_bytes(p); - bits_p = BN_num_bits(p); - - data = app_malloc(len + 20, "BN space"); - - BIO_printf(bio_out, "static DSA *get_dsa%d(void)\n{\n", bits_p); - print_bignum_var(bio_out, p, "dsap", bits_p, data); - print_bignum_var(bio_out, q, "dsaq", bits_p, data); - print_bignum_var(bio_out, g, "dsag", bits_p, data); - BIO_printf(bio_out, " DSA *dsa = DSA_new();\n" - " BIGNUM *p, *q, *g;\n" - "\n"); - BIO_printf(bio_out, " if (dsa == NULL)\n" - " return NULL;\n"); - BIO_printf(bio_out, " if (!DSA_set0_pqg(dsa, p = BN_bin2bn(dsap_%d, sizeof(dsap_%d), NULL),\n", - bits_p, bits_p); - BIO_printf(bio_out, " q = BN_bin2bn(dsaq_%d, sizeof(dsaq_%d), NULL),\n", - bits_p, bits_p); - BIO_printf(bio_out, " g = BN_bin2bn(dsag_%d, sizeof(dsag_%d), NULL))) {\n", - bits_p, bits_p); - BIO_printf(bio_out, " DSA_free(dsa);\n" - " BN_free(p);\n" - " BN_free(q);\n" - " BN_free(g);\n" - " return NULL;\n" - " }\n" - " return dsa;\n}\n"); - OPENSSL_free(data); + EVP_PKEY_print_params(out, params, 0, NULL); } if (outformat == FORMAT_ASN1 && genkey) @@ -205,49 +195,62 @@ int dsaparam_main(int argc, char **argv) if (!noout) { if (outformat == FORMAT_ASN1) - i = i2d_DSAparams_bio(out, dsa); + i = i2d_KeyParams_bio(out, params); else - i = PEM_write_bio_DSAparams(out, dsa); + i = PEM_write_bio_Parameters(out, params); if (!i) { - BIO_printf(bio_err, "unable to write DSA parameters\n"); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Error, unable to write DSA parameters\n"); goto end; } } if (genkey) { - DSA *dsakey; - - if ((dsakey = DSAparams_dup(dsa)) == NULL) + EVP_PKEY_CTX_free(ctx); + ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), params, + app_get0_propq()); + if (ctx == NULL) { + BIO_printf(bio_err, + "Error, DSA key generation context allocation failed\n"); goto end; - if (!DSA_generate_key(dsakey)) { - ERR_print_errors(bio_err); - DSA_free(dsakey); + } + if (EVP_PKEY_keygen_init(ctx) <= 0) { + BIO_printf(bio_err, + "Error, unable to initialise for key generation\n"); goto end; } + pkey = app_keygen(ctx, "DSA", numbits, verbose); assert(private); if (outformat == FORMAT_ASN1) - i = i2d_DSAPrivateKey_bio(out, dsakey); + i = i2d_PrivateKey_bio(out, pkey); else - i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, - NULL); - DSA_free(dsakey); + i = PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, NULL); } ret = 0; end: - BN_GENCB_free(cb); - BIO_free(in); + if (ret != 0) + ERR_print_errors(bio_err); BIO_free_all(out); - DSA_free(dsa); + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + EVP_PKEY_free(params); release_engine(e); return ret; } -static int dsa_cb(int p, int n, BN_GENCB *cb) +static int gendsa_cb(EVP_PKEY_CTX *ctx) { static const char symbols[] = ".+*\n"; - char c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?'; + int p; + char c; + BIO *b; + + if (!verbose) + return 1; + + b = EVP_PKEY_CTX_get_app_data(ctx); + p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); + c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?'; - BIO_write(BN_GENCB_get_arg(cb), &c, 1); - (void)BIO_flush(BN_GENCB_get_arg(cb)); + BIO_write(b, &c, 1); + (void)BIO_flush(b); return 1; } diff --git a/crypto/openssl/apps/ec.c b/crypto/openssl/apps/ec.c index 0c8ed750cc17..e2dd6f2b48f3 100644 --- a/crypto/openssl/apps/ec.c +++ b/crypto/openssl/apps/ec.c @@ -1,84 +1,84 @@ /* - * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include -#include #include -#include "apps.h" -#include "progs.h" -#include -#include +#include #include -#include - -static OPT_PAIR conv_forms[] = { - {"compressed", POINT_CONVERSION_COMPRESSED}, - {"uncompressed", POINT_CONVERSION_UNCOMPRESSED}, - {"hybrid", POINT_CONVERSION_HYBRID}, - {NULL} -}; +#include +#include +#include +#include +#include +#include -static OPT_PAIR param_enc[] = { - {"named_curve", OPENSSL_EC_NAMED_CURVE}, - {"explicit", 0}, - {NULL} -}; +#include "apps.h" +#include "progs.h" +#include "ec_common.h" typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, OPT_NOOUT, OPT_TEXT, OPT_PARAM_OUT, OPT_PUBIN, OPT_PUBOUT, OPT_PASSIN, OPT_PASSOUT, OPT_PARAM_ENC, OPT_CONV_FORM, OPT_CIPHER, - OPT_NO_PUBLIC, OPT_CHECK + OPT_NO_PUBLIC, OPT_CHECK, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS ec_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Input"), {"in", OPT_IN, 's', "Input file"}, - {"inform", OPT_INFORM, 'f', "Input format - DER or PEM"}, + {"inform", OPT_INFORM, 'f', "Input format (DER/PEM/P12/ENGINE)"}, + {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"check", OPT_CHECK, '-', "check key consistency"}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, + {"param_enc", OPT_PARAM_ENC, 's', + "Specifies the way the ec parameters are encoded"}, + {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, + + OPT_SECTION("Output"), {"out", OPT_OUT, '>', "Output file"}, {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, {"noout", OPT_NOOUT, '-', "Don't print key out"}, {"text", OPT_TEXT, '-', "Print the key"}, {"param_out", OPT_PARAM_OUT, '-', "Print the elliptic curve parameters"}, - {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, {"no_public", OPT_NO_PUBLIC, '-', "exclude public key from private key"}, - {"check", OPT_CHECK, '-', "check key consistency"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - {"param_enc", OPT_PARAM_ENC, 's', - "Specifies the way the ec parameters are encoded"}, - {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, - {"", OPT_CIPHER, '-', "Any supported cipher"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + + OPT_PROV_OPTIONS, {NULL} }; int ec_main(int argc, char **argv) { - BIO *in = NULL, *out = NULL; + OSSL_ENCODER_CTX *ectx = NULL; + OSSL_DECODER_CTX *dctx = NULL; + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *eckey = NULL; + BIO *out = NULL; ENGINE *e = NULL; - EC_KEY *eckey = NULL; - const EC_GROUP *group; - const EVP_CIPHER *enc = NULL; - point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; - char *infile = NULL, *outfile = NULL, *prog; + EVP_CIPHER *enc = NULL; + char *infile = NULL, *outfile = NULL, *ciphername = NULL, *prog; char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL; OPTION_CHOICE o; - int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_form = 0, new_asn1_flag = 0; - int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0; - int pubin = 0, pubout = 0, param_out = 0, i, ret = 1, private = 0; - int no_public = 0, check = 0; + int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, text = 0, noout = 0; + int pubin = 0, pubout = 0, param_out = 0, ret = 1, private = 0; + int check = 0; + char *asn1_encoding = NULL; + char *point_format = NULL; + int no_public = 0; prog = opt_init(argc, argv, ec_options); while ((o = opt_next()) != OPT_EOF) { @@ -131,20 +131,17 @@ int ec_main(int argc, char **argv) e = setup_engine(opt_arg(), 0); break; case OPT_CIPHER: - if (!opt_cipher(opt_unknown(), &enc)) - goto opthelp; + ciphername = opt_unknown(); break; case OPT_CONV_FORM: - if (!opt_pair(opt_arg(), conv_forms, &i)) + point_format = opt_arg(); + if (!opt_string(point_format, point_format_options)) goto opthelp; - new_form = 1; - form = i; break; case OPT_PARAM_ENC: - if (!opt_pair(opt_arg(), param_enc, &i)) + asn1_encoding = opt_arg(); + if (!opt_string(asn1_encoding, asn1_encoding_options)) goto opthelp; - new_asn1_flag = 1; - asn1_flag = i; break; case OPT_NO_PUBLIC: no_public = 1; @@ -152,12 +149,22 @@ int ec_main(int argc, char **argv) case OPT_CHECK: check = 1; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; + if (ciphername != NULL) { + if (!opt_cipher(ciphername, &enc)) + goto opthelp; + } private = param_out || pubin || pubout ? 0 : 1; if (text && !pubin) private = 1; @@ -167,37 +174,15 @@ int ec_main(int argc, char **argv) goto end; } - if (informat != FORMAT_ENGINE) { - in = bio_open_default(infile, 'r', informat); - if (in == NULL) - goto end; - } - BIO_printf(bio_err, "read EC key\n"); - if (informat == FORMAT_ASN1) { - if (pubin) - eckey = d2i_EC_PUBKEY_bio(in, NULL); - else - eckey = d2i_ECPrivateKey_bio(in, NULL); - } else if (informat == FORMAT_ENGINE) { - EVP_PKEY *pkey; - if (pubin) - pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key"); - else - pkey = load_key(infile, informat, 1, passin, e, "Private Key"); - if (pkey != NULL) { - eckey = EVP_PKEY_get1_EC_KEY(pkey); - EVP_PKEY_free(pkey); - } - } else { - if (pubin) - eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL); - else - eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, passin); - } + + if (pubin) + eckey = load_pubkey(infile, informat, 1, passin, e, "public key"); + else + eckey = load_key(infile, informat, 1, passin, e, "private key"); + if (eckey == NULL) { BIO_printf(bio_err, "unable to load Key\n"); - ERR_print_errors(bio_err); goto end; } @@ -205,74 +190,105 @@ int ec_main(int argc, char **argv) if (out == NULL) goto end; - group = EC_KEY_get0_group(eckey); - - if (new_form) - EC_KEY_set_conv_form(eckey, form); + if (point_format + && !EVP_PKEY_set_utf8_string_param( + eckey, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, + point_format)) { + BIO_printf(bio_err, "unable to set point conversion format\n"); + goto end; + } - if (new_asn1_flag) - EC_KEY_set_asn1_flag(eckey, asn1_flag); + if (asn1_encoding != NULL + && !EVP_PKEY_set_utf8_string_param( + eckey, OSSL_PKEY_PARAM_EC_ENCODING, asn1_encoding)) { + BIO_printf(bio_err, "unable to set asn1 encoding format\n"); + goto end; + } - if (no_public) - EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY); + if (no_public) { + if (!EVP_PKEY_set_int_param(eckey, OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, 0)) { + BIO_printf(bio_err, "unable to disable public key encoding\n"); + goto end; + } + } else { + if (!EVP_PKEY_set_int_param(eckey, OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, 1)) { + BIO_printf(bio_err, "unable to enable public key encoding\n"); + goto end; + } + } if (text) { assert(pubin || private); - if (!EC_KEY_print(out, eckey, 0)) { - perror(outfile); - ERR_print_errors(bio_err); + if ((pubin && EVP_PKEY_print_public(out, eckey, 0, NULL) <= 0) + || (!pubin && EVP_PKEY_print_private(out, eckey, 0, NULL) <= 0)) { + BIO_printf(bio_err, "unable to print EC key\n"); goto end; } } if (check) { - if (EC_KEY_check_key(eckey) == 1) { - BIO_printf(bio_err, "EC Key valid.\n"); - } else { - BIO_printf(bio_err, "EC Key Invalid!\n"); - ERR_print_errors(bio_err); + pctx = EVP_PKEY_CTX_new_from_pkey(NULL, eckey, NULL); + if (pctx == NULL) { + BIO_printf(bio_err, "unable to check EC key\n"); + goto end; } + if (EVP_PKEY_check(pctx) <= 0) + BIO_printf(bio_err, "EC Key Invalid!\n"); + else + BIO_printf(bio_err, "EC Key valid.\n"); + ERR_print_errors(bio_err); } - if (noout) { - ret = 0; - goto end; - } + if (!noout) { + int selection; + const char *output_type = outformat == FORMAT_ASN1 ? "DER" : "PEM"; + const char *output_structure = "type-specific"; - BIO_printf(bio_err, "writing EC key\n"); - if (outformat == FORMAT_ASN1) { + BIO_printf(bio_err, "writing EC key\n"); if (param_out) { - i = i2d_ECPKParameters_bio(out, group); + selection = OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS; } else if (pubin || pubout) { - i = i2d_EC_PUBKEY_bio(out, eckey); + selection = OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS + | OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + output_structure = "SubjectPublicKeyInfo"; } else { + selection = OSSL_KEYMGMT_SELECT_ALL; assert(private); - i = i2d_ECPrivateKey_bio(out, eckey); } - } else { - if (param_out) { - i = PEM_write_bio_ECPKParameters(out, group); - } else if (pubin || pubout) { - i = PEM_write_bio_EC_PUBKEY(out, eckey); - } else { - assert(private); - i = PEM_write_bio_ECPrivateKey(out, eckey, enc, - NULL, 0, NULL, passout); + + ectx = OSSL_ENCODER_CTX_new_for_pkey(eckey, selection, + output_type, output_structure, + NULL); + if (enc != NULL) { + OSSL_ENCODER_CTX_set_cipher(ectx, EVP_CIPHER_get0_name(enc), NULL); + /* Default passphrase prompter */ + OSSL_ENCODER_CTX_set_passphrase_ui(ectx, get_ui_method(), NULL); + if (passout != NULL) + /* When passout given, override the passphrase prompter */ + OSSL_ENCODER_CTX_set_passphrase(ectx, + (const unsigned char *)passout, + strlen(passout)); + } + if (!OSSL_ENCODER_to_bio(ectx, out)) { + BIO_printf(bio_err, "unable to write EC key\n"); + goto end; } } - if (!i) { - BIO_printf(bio_err, "unable to write private key\n"); + ret = 0; +end: + if (ret != 0) ERR_print_errors(bio_err); - } else { - ret = 0; - } - end: - BIO_free(in); BIO_free_all(out); - EC_KEY_free(eckey); + EVP_PKEY_free(eckey); + EVP_CIPHER_free(enc); + OSSL_ENCODER_CTX_free(ectx); + OSSL_DECODER_CTX_free(dctx); + EVP_PKEY_CTX_free(pctx); release_engine(e); - OPENSSL_free(passin); - OPENSSL_free(passout); + if (passin != NULL) + OPENSSL_clear_free(passin, strlen(passin)); + if (passout != NULL) + OPENSSL_clear_free(passout, strlen(passout)); return ret; } diff --git a/crypto/openssl/apps/ecparam.c b/crypto/openssl/apps/ecparam.c index 58fbeb95c9ce..9e9ad136837b 100644 --- a/crypto/openssl/apps/ecparam.c +++ b/crypto/openssl/apps/ecparam.c @@ -1,92 +1,115 @@ /* - * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2022 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 + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include "apps.h" #include "progs.h" -#include -#include -#include -#include -#include -#include +#include "ec_common.h" typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C, + OPT_COMMON, + OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_CHECK, OPT_LIST_CURVES, OPT_NO_SEED, OPT_NOOUT, OPT_NAME, - OPT_CONV_FORM, OPT_PARAM_ENC, OPT_GENKEY, OPT_ENGINE, - OPT_R_ENUM + OPT_CONV_FORM, OPT_PARAM_ENC, OPT_GENKEY, OPT_ENGINE, OPT_CHECK_NAMED, + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS ecparam_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"}, - {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, + {"list_curves", OPT_LIST_CURVES, '-', + "Prints a list of all curve 'short names'"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + {"genkey", OPT_GENKEY, '-', "Generate ec key"}, {"in", OPT_IN, '<', "Input file - default stdin"}, + {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"}, {"out", OPT_OUT, '>', "Output file - default stdout"}, + {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, + + OPT_SECTION("Output"), {"text", OPT_TEXT, '-', "Print the ec parameters in text form"}, - {"C", OPT_C, '-', "Print a 'C' function creating the parameters"}, + {"noout", OPT_NOOUT, '-', "Do not print the ec parameter"}, + {"param_enc", OPT_PARAM_ENC, 's', + "Specifies the way the ec parameters are encoded"}, + + OPT_SECTION("Parameter"), {"check", OPT_CHECK, '-', "Validate the ec parameters"}, - {"list_curves", OPT_LIST_CURVES, '-', - "Prints a list of all curve 'short names'"}, + {"check_named", OPT_CHECK_NAMED, '-', + "Check that named EC curve parameters have not been modified"}, {"no_seed", OPT_NO_SEED, '-', "If 'explicit' parameters are chosen do not use the seed"}, - {"noout", OPT_NOOUT, '-', "Do not print the ec parameter"}, {"name", OPT_NAME, 's', "Use the ec parameters with specified 'short name'"}, {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, - {"param_enc", OPT_PARAM_ENC, 's', - "Specifies the way the ec parameters are encoded"}, - {"genkey", OPT_GENKEY, '-', "Generate ec key"}, + OPT_R_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + OPT_PROV_OPTIONS, {NULL} }; -static OPT_PAIR forms[] = { - {"compressed", POINT_CONVERSION_COMPRESSED}, - {"uncompressed", POINT_CONVERSION_UNCOMPRESSED}, - {"hybrid", POINT_CONVERSION_HYBRID}, - {NULL} -}; +static int list_builtin_curves(BIO *out) +{ + int ret = 0; + EC_builtin_curve *curves = NULL; + size_t n, crv_len = EC_get_builtin_curves(NULL, 0); -static OPT_PAIR encodings[] = { - {"named_curve", OPENSSL_EC_NAMED_CURVE}, - {"explicit", 0}, - {NULL} -}; + curves = app_malloc((int)sizeof(*curves) * crv_len, "list curves"); + if (!EC_get_builtin_curves(curves, crv_len)) + goto end; + + for (n = 0; n < crv_len; n++) { + const char *comment = curves[n].comment; + const char *sname = OBJ_nid2sn(curves[n].nid); + + if (comment == NULL) + comment = "CURVE DESCRIPTION NOT AVAILABLE"; + if (sname == NULL) + sname = ""; + + BIO_printf(out, " %-10s: ", sname); + BIO_printf(out, "%s\n", comment); + } + ret = 1; +end: + OPENSSL_free(curves); + return ret; +} int ecparam_main(int argc, char **argv) { + EVP_PKEY_CTX *gctx_params = NULL, *gctx_key = NULL, *pctx = NULL; + EVP_PKEY *params_key = NULL, *key = NULL; + OSSL_ENCODER_CTX *ectx_key = NULL, *ectx_params = NULL; + OSSL_DECODER_CTX *dctx_params = NULL; ENGINE *e = NULL; - BIGNUM *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL; - BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL; - BIO *in = NULL, *out = NULL; - EC_GROUP *group = NULL; - point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; + BIO *out = NULL; char *curve_name = NULL; + char *asn1_encoding = NULL; + char *point_format = NULL; char *infile = NULL, *outfile = NULL, *prog; - unsigned char *buffer = NULL; OPTION_CHOICE o; - int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_asn1_flag = 0; - int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0; int ret = 1, private = 0; - int list_curves = 0, no_seed = 0, check = 0, new_form = 0; - int text = 0, i, genkey = 0; + int no_seed = 0, check = 0, check_named = 0, text = 0, genkey = 0; + int list_curves = 0; prog = opt_init(argc, argv, ecparam_options); while ((o = opt_next()) != OPT_EOF) { @@ -117,12 +140,12 @@ int ecparam_main(int argc, char **argv) case OPT_TEXT: text = 1; break; - case OPT_C: - C = 1; - break; case OPT_CHECK: check = 1; break; + case OPT_CHECK_NAMED: + check_named = 1; + break; case OPT_LIST_CURVES: list_curves = 1; break; @@ -136,15 +159,14 @@ int ecparam_main(int argc, char **argv) curve_name = opt_arg(); break; case OPT_CONV_FORM: - if (!opt_pair(opt_arg(), forms, &new_form)) + point_format = opt_arg(); + if (!opt_string(point_format, point_format_options)) goto opthelp; - form = new_form; - new_form = 1; break; case OPT_PARAM_ENC: - if (!opt_pair(opt_arg(), encodings, &asn1_flag)) + asn1_encoding = opt_arg(); + if (!opt_string(asn1_encoding, asn1_encoding_options)) goto opthelp; - new_asn1_flag = 1; break; case OPT_GENKEY: genkey = 1; @@ -153,292 +175,178 @@ int ecparam_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; } } + + /* No extra args. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; + if (!app_RAND_load()) + goto end; + private = genkey ? 1 : 0; - in = bio_open_default(infile, 'r', informat); - if (in == NULL) - goto end; out = bio_open_owner(outfile, outformat, private); if (out == NULL) goto end; if (list_curves) { - EC_builtin_curve *curves = NULL; - size_t crv_len = EC_get_builtin_curves(NULL, 0); - size_t n; - - curves = app_malloc((int)sizeof(*curves) * crv_len, "list curves"); - if (!EC_get_builtin_curves(curves, crv_len)) { - OPENSSL_free(curves); - goto end; - } - - for (n = 0; n < crv_len; n++) { - const char *comment; - const char *sname; - comment = curves[n].comment; - sname = OBJ_nid2sn(curves[n].nid); - if (comment == NULL) - comment = "CURVE DESCRIPTION NOT AVAILABLE"; - if (sname == NULL) - sname = ""; - - BIO_printf(out, " %-10s: ", sname); - BIO_printf(out, "%s\n", comment); - } - - OPENSSL_free(curves); - ret = 0; + if (list_builtin_curves(out)) + ret = 0; goto end; } if (curve_name != NULL) { - int nid; + OSSL_PARAM params[4]; + OSSL_PARAM *p = params; - /* - * workaround for the SECG curve names secp192r1 and secp256r1 (which - * are the same as the curves prime192v1 and prime256v1 defined in - * X9.62) - */ if (strcmp(curve_name, "secp192r1") == 0) { - BIO_printf(bio_err, "using curve name prime192v1 " - "instead of secp192r1\n"); - nid = NID_X9_62_prime192v1; + BIO_printf(bio_err, + "using curve name prime192v1 instead of secp192r1\n"); + curve_name = SN_X9_62_prime192v1; } else if (strcmp(curve_name, "secp256r1") == 0) { - BIO_printf(bio_err, "using curve name prime256v1 " - "instead of secp256r1\n"); - nid = NID_X9_62_prime256v1; - } else { - nid = OBJ_sn2nid(curve_name); + BIO_printf(bio_err, + "using curve name prime256v1 instead of secp256r1\n"); + curve_name = SN_X9_62_prime256v1; } - - if (nid == 0) - nid = EC_curve_nist2nid(curve_name); - - if (nid == 0) { - BIO_printf(bio_err, "unknown curve name (%s)\n", curve_name); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + curve_name, 0); + if (asn1_encoding != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, + asn1_encoding, 0); + if (point_format != NULL) + *p++ = OSSL_PARAM_construct_utf8_string( + OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, + point_format, 0); + *p = OSSL_PARAM_construct_end(); + + if (OPENSSL_strcasecmp(curve_name, "SM2") == 0) + gctx_params = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), "sm2", + app_get0_propq()); + else + gctx_params = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), "ec", + app_get0_propq()); + if (gctx_params == NULL + || EVP_PKEY_keygen_init(gctx_params) <= 0 + || EVP_PKEY_CTX_set_params(gctx_params, params) <= 0 + || EVP_PKEY_keygen(gctx_params, ¶ms_key) <= 0) { + BIO_printf(bio_err, "unable to generate key\n"); + goto end; + } + } else { + params_key = load_keyparams(infile, informat, 1, "EC", "EC parameters"); + if (params_key == NULL || !EVP_PKEY_is_a(params_key, "EC")) + goto end; + if (point_format + && !EVP_PKEY_set_utf8_string_param( + params_key, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, + point_format)) { + BIO_printf(bio_err, "unable to set point conversion format\n"); goto end; } - group = EC_GROUP_new_by_curve_name(nid); - if (group == NULL) { - BIO_printf(bio_err, "unable to create curve (%s)\n", curve_name); + if (asn1_encoding != NULL + && !EVP_PKEY_set_utf8_string_param( + params_key, OSSL_PKEY_PARAM_EC_ENCODING, asn1_encoding)) { + BIO_printf(bio_err, "unable to set asn1 encoding format\n"); goto end; } - EC_GROUP_set_asn1_flag(group, asn1_flag); - EC_GROUP_set_point_conversion_form(group, form); - } else if (informat == FORMAT_ASN1) { - group = d2i_ECPKParameters_bio(in, NULL); - } else { - group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); } - if (group == NULL) { - BIO_printf(bio_err, "unable to load elliptic curve parameters\n"); - ERR_print_errors(bio_err); - goto end; - } - - if (new_form) - EC_GROUP_set_point_conversion_form(group, form); - if (new_asn1_flag) - EC_GROUP_set_asn1_flag(group, asn1_flag); - - if (no_seed) { - EC_GROUP_set_seed(group, NULL, 0); + if (no_seed + && !EVP_PKEY_set_octet_string_param(params_key, OSSL_PKEY_PARAM_EC_SEED, + NULL, 0)) { + BIO_printf(bio_err, "unable to clear seed\n"); + goto end; } - if (text) { - if (!ECPKParameters_print(out, group, 0)) - goto end; + if (text + && !EVP_PKEY_print_params(out, params_key, 0, NULL)) { + BIO_printf(bio_err, "unable to print params\n"); + goto end; } - if (check) { + if (check || check_named) { BIO_printf(bio_err, "checking elliptic curve parameters: "); - if (!EC_GROUP_check(group, NULL)) { - BIO_printf(bio_err, "failed\n"); - ERR_print_errors(bio_err); - goto end; - } - BIO_printf(bio_err, "ok\n"); - - } - - if (C) { - size_t buf_len = 0, tmp_len = 0; - const EC_POINT *point; - int is_prime, len = 0; - const EC_METHOD *meth = EC_GROUP_method_of(group); - if ((ec_p = BN_new()) == NULL - || (ec_a = BN_new()) == NULL - || (ec_b = BN_new()) == NULL - || (ec_gen = BN_new()) == NULL - || (ec_order = BN_new()) == NULL - || (ec_cofactor = BN_new()) == NULL) { - perror("Can't allocate BN"); - goto end; + if (check_named + && !EVP_PKEY_set_utf8_string_param(params_key, + OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, + OSSL_PKEY_EC_GROUP_CHECK_NAMED)) { + BIO_printf(bio_err, "unable to set check_type\n"); + goto end; } - - is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field); - if (!is_prime) { - BIO_printf(bio_err, "Can only handle X9.62 prime fields\n"); + pctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), params_key, + app_get0_propq()); + if (pctx == NULL || EVP_PKEY_param_check(pctx) <= 0) { + BIO_printf(bio_err, "failed\n"); goto end; } - - if (!EC_GROUP_get_curve(group, ec_p, ec_a, ec_b, NULL)) - goto end; - - if ((point = EC_GROUP_get0_generator(group)) == NULL) - goto end; - if (!EC_POINT_point2bn(group, point, - EC_GROUP_get_point_conversion_form(group), - ec_gen, NULL)) - goto end; - if (!EC_GROUP_get_order(group, ec_order, NULL)) - goto end; - if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL)) - goto end; - - if (!ec_p || !ec_a || !ec_b || !ec_gen || !ec_order || !ec_cofactor) - goto end; - - len = BN_num_bits(ec_order); - - if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len) - buf_len = tmp_len; - if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len) - buf_len = tmp_len; - if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len) - buf_len = tmp_len; - if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len) - buf_len = tmp_len; - if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len) - buf_len = tmp_len; - if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len) - buf_len = tmp_len; - - buffer = app_malloc(buf_len, "BN buffer"); - - BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n{\n", len); - print_bignum_var(out, ec_p, "ec_p", len, buffer); - print_bignum_var(out, ec_a, "ec_a", len, buffer); - print_bignum_var(out, ec_b, "ec_b", len, buffer); - print_bignum_var(out, ec_gen, "ec_gen", len, buffer); - print_bignum_var(out, ec_order, "ec_order", len, buffer); - print_bignum_var(out, ec_cofactor, "ec_cofactor", len, buffer); - BIO_printf(out, " int ok = 0;\n" - " EC_GROUP *group = NULL;\n" - " EC_POINT *point = NULL;\n" - " BIGNUM *tmp_1 = NULL;\n" - " BIGNUM *tmp_2 = NULL;\n" - " BIGNUM *tmp_3 = NULL;\n" - "\n"); - - BIO_printf(out, " if ((tmp_1 = BN_bin2bn(ec_p_%d, sizeof(ec_p_%d), NULL)) == NULL)\n" - " goto err;\n", len, len); - BIO_printf(out, " if ((tmp_2 = BN_bin2bn(ec_a_%d, sizeof(ec_a_%d), NULL)) == NULL)\n" - " goto err;\n", len, len); - BIO_printf(out, " if ((tmp_3 = BN_bin2bn(ec_b_%d, sizeof(ec_b_%d), NULL)) == NULL)\n" - " goto err;\n", len, len); - BIO_printf(out, " if ((group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)\n" - " goto err;\n" - "\n"); - BIO_printf(out, " /* build generator */\n"); - BIO_printf(out, " if ((tmp_1 = BN_bin2bn(ec_gen_%d, sizeof(ec_gen_%d), tmp_1)) == NULL)\n" - " goto err;\n", len, len); - BIO_printf(out, " point = EC_POINT_bn2point(group, tmp_1, NULL, NULL);\n"); - BIO_printf(out, " if (point == NULL)\n" - " goto err;\n"); - BIO_printf(out, " if ((tmp_2 = BN_bin2bn(ec_order_%d, sizeof(ec_order_%d), tmp_2)) == NULL)\n" - " goto err;\n", len, len); - BIO_printf(out, " if ((tmp_3 = BN_bin2bn(ec_cofactor_%d, sizeof(ec_cofactor_%d), tmp_3)) == NULL)\n" - " goto err;\n", len, len); - BIO_printf(out, " if (!EC_GROUP_set_generator(group, point, tmp_2, tmp_3))\n" - " goto err;\n" - "ok = 1;" - "\n"); - BIO_printf(out, "err:\n" - " BN_free(tmp_1);\n" - " BN_free(tmp_2);\n" - " BN_free(tmp_3);\n" - " EC_POINT_free(point);\n" - " if (!ok) {\n" - " EC_GROUP_free(group);\n" - " return NULL;\n" - " }\n" - " return (group);\n" - "}\n"); + BIO_printf(bio_err, "ok\n"); } if (outformat == FORMAT_ASN1 && genkey) noout = 1; if (!noout) { - if (outformat == FORMAT_ASN1) - i = i2d_ECPKParameters_bio(out, group); - else - i = PEM_write_bio_ECPKParameters(out, group); - if (!i) { - BIO_printf(bio_err, "unable to write elliptic " - "curve parameters\n"); - ERR_print_errors(bio_err); + ectx_params = OSSL_ENCODER_CTX_new_for_pkey( + params_key, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, + outformat == FORMAT_ASN1 ? "DER" : "PEM", NULL, NULL); + if (!OSSL_ENCODER_to_bio(ectx_params, out)) { + BIO_printf(bio_err, "unable to write elliptic curve parameters\n"); goto end; } } if (genkey) { - EC_KEY *eckey = EC_KEY_new(); - - if (eckey == NULL) - goto end; - - if (EC_KEY_set_group(eckey, group) == 0) { - BIO_printf(bio_err, "unable to set group when generating key\n"); - EC_KEY_free(eckey); - ERR_print_errors(bio_err); - goto end; - } - - if (new_form) - EC_KEY_set_conv_form(eckey, form); - - if (!EC_KEY_generate_key(eckey)) { + /* + * NOTE: EC keygen does not normally need to pass in the param_key + * for named curves. This can be achieved using: + * gctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + * EVP_PKEY_keygen_init(gctx); + * EVP_PKEY_CTX_set_group_name(gctx, curvename); + * EVP_PKEY_keygen(gctx, &key) <= 0) + */ + gctx_key = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), params_key, + app_get0_propq()); + if (EVP_PKEY_keygen_init(gctx_key) <= 0 + || EVP_PKEY_keygen(gctx_key, &key) <= 0) { BIO_printf(bio_err, "unable to generate key\n"); - EC_KEY_free(eckey); - ERR_print_errors(bio_err); goto end; } assert(private); - if (outformat == FORMAT_ASN1) - i = i2d_ECPrivateKey_bio(out, eckey); - else - i = PEM_write_bio_ECPrivateKey(out, eckey, NULL, - NULL, 0, NULL, NULL); - EC_KEY_free(eckey); + ectx_key = OSSL_ENCODER_CTX_new_for_pkey( + key, OSSL_KEYMGMT_SELECT_ALL, + outformat == FORMAT_ASN1 ? "DER" : "PEM", NULL, NULL); + if (!OSSL_ENCODER_to_bio(ectx_key, out)) { + BIO_printf(bio_err, "unable to write elliptic " + "curve parameters\n"); + goto end; + } } ret = 0; - end: - BN_free(ec_p); - BN_free(ec_a); - BN_free(ec_b); - BN_free(ec_gen); - BN_free(ec_order); - BN_free(ec_cofactor); - OPENSSL_free(buffer); - EC_GROUP_free(group); +end: + if (ret != 0) + ERR_print_errors(bio_err); release_engine(e); - BIO_free(in); + EVP_PKEY_free(params_key); + EVP_PKEY_free(key); + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_CTX_free(gctx_params); + EVP_PKEY_CTX_free(gctx_key); + OSSL_DECODER_CTX_free(dctx_params); + OSSL_ENCODER_CTX_free(ectx_params); + OSSL_ENCODER_CTX_free(ectx_key); BIO_free_all(out); return ret; } diff --git a/crypto/openssl/apps/enc.c b/crypto/openssl/apps/enc.c index 65710771a089..3dd609856304 100644 --- a/crypto/openssl/apps/enc.c +++ b/crypto/openssl/apps/enc.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -39,38 +39,51 @@ struct doall_enc_ciphers { }; typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_LIST, OPT_E, OPT_IN, OPT_OUT, OPT_PASS, OPT_ENGINE, OPT_D, OPT_P, OPT_V, OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A, OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE, OPT_UPPER_S, OPT_IV, OPT_MD, OPT_ITER, OPT_PBKDF2, OPT_CIPHER, - OPT_R_ENUM + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS enc_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"list", OPT_LIST, '-', "List ciphers"}, +#ifndef OPENSSL_NO_DEPRECATED_3_0 {"ciphers", OPT_LIST, '-', "Alias for -list"}, - {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, - {"pass", OPT_PASS, 's', "Passphrase source"}, +#endif {"e", OPT_E, '-', "Encrypt"}, {"d", OPT_D, '-', "Decrypt"}, {"p", OPT_P, '-', "Print the iv/key"}, {"P", OPT_UPPER_P, '-', "Print the iv/key and exit"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file"}, + {"k", OPT_K, 's', "Passphrase"}, + {"kfile", OPT_KFILE, '<', "Read passphrase from file"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"pass", OPT_PASS, 's', "Passphrase source"}, {"v", OPT_V, '-', "Verbose output"}, - {"nopad", OPT_NOPAD, '-', "Disable standard block padding"}, - {"salt", OPT_SALT, '-', "Use salt in the KDF (default)"}, - {"nosalt", OPT_NOSALT, '-', "Do not use salt in the KDF"}, - {"debug", OPT_DEBUG, '-', "Print debug info"}, {"a", OPT_A, '-', "Base64 encode/decode, depending on encryption flag"}, {"base64", OPT_A, '-', "Same as option -a"}, {"A", OPT_UPPER_A, '-', "Used with -[base64|a] to specify base64 buffer as a single line"}, + + OPT_SECTION("Encryption"), + {"nopad", OPT_NOPAD, '-', "Disable standard block padding"}, + {"salt", OPT_SALT, '-', "Use salt in the KDF (default)"}, + {"nosalt", OPT_NOSALT, '-', "Do not use salt in the KDF"}, + {"debug", OPT_DEBUG, '-', "Print debug info"}, + {"bufsize", OPT_BUFSIZE, 's', "Buffer size"}, - {"k", OPT_K, 's', "Passphrase"}, - {"kfile", OPT_KFILE, '<', "Read passphrase from file"}, {"K", OPT_UPPER_K, 's', "Raw key, in hex"}, {"S", OPT_UPPER_S, 's', "Salt, in hex"}, {"iv", OPT_IV, 's', "IV in hex"}, @@ -78,14 +91,13 @@ const OPTIONS enc_options[] = { {"iter", OPT_ITER, 'p', "Specify the iteration count and force use of PBKDF2"}, {"pbkdf2", OPT_PBKDF2, '-', "Use password-based key derivation function 2"}, {"none", OPT_NONE, '-', "Don't encrypt"}, - {"", OPT_CIPHER, '-', "Any supported cipher"}, - OPT_R_OPTIONS, #ifdef ZLIB {"z", OPT_Z, '-', "Compress or decompress encrypted data using zlib"}, #endif -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + {"", OPT_CIPHER, '-', "Any supported cipher"}, + + OPT_R_OPTIONS, + OPT_PROV_OPTIONS, {NULL} }; @@ -97,11 +109,13 @@ int enc_main(int argc, char **argv) BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio = NULL, *wbio = NULL; EVP_CIPHER_CTX *ctx = NULL; - const EVP_CIPHER *cipher = NULL, *c; - const EVP_MD *dgst = NULL; + EVP_CIPHER *cipher = NULL; + EVP_MD *dgst = NULL; + const char *digestname = NULL; char *hkey = NULL, *hiv = NULL, *hsalt = NULL, *p; char *infile = NULL, *outfile = NULL, *prog; char *str = NULL, *passarg = NULL, *pass = NULL, *strbuf = NULL; + const char *ciphername = NULL; char mbuf[sizeof(magic) - 1]; OPTION_CHOICE o; int bsize = BSIZE, verbose = 0, debug = 0, olb64 = 0, nosalt = 0; @@ -119,21 +133,15 @@ int enc_main(int argc, char **argv) BIO *bzl = NULL; #endif - /* first check the program name */ - prog = opt_progname(argv[0]); - if (strcmp(prog, "base64") == 0) { + /* first check the command name */ + if (strcmp(argv[0], "base64") == 0) base64 = 1; #ifdef ZLIB - } else if (strcmp(prog, "zlib") == 0) { + else if (strcmp(argv[0], "zlib") == 0) do_zlib = 1; #endif - } else { - cipher = EVP_get_cipherbyname(prog); - if (cipher == NULL && strcmp(prog, "enc") != 0) { - BIO_printf(bio_err, "%s is not a known cipher\n", prog); - goto end; - } - } + else if (strcmp(argv[0], "enc") != 0) + ciphername = argv[0]; prog = opt_init(argc, argv, enc_options); while ((o = opt_next()) != OPT_EOF) { @@ -252,17 +260,13 @@ int enc_main(int argc, char **argv) hiv = opt_arg(); break; case OPT_MD: - if (!opt_md(opt_arg(), &dgst)) - goto opthelp; + digestname = opt_arg(); break; case OPT_CIPHER: - if (!opt_cipher(opt_unknown(), &c)) - goto opthelp; - cipher = c; + ciphername = opt_unknown(); break; case OPT_ITER: - if (!opt_int(opt_arg(), &iter)) - goto opthelp; + iter = opt_int_arg(); pbkdf2 = 1; break; case OPT_PBKDF2: @@ -277,25 +281,31 @@ int enc_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } - if (opt_num_rest() != 0) { - BIO_printf(bio_err, "Extra arguments given.\n"); - goto opthelp; - } - if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { - BIO_printf(bio_err, "%s: AEAD ciphers not supported\n", prog); + /* No extra arguments. */ + argc = opt_num_rest(); + if (argc != 0) + goto opthelp; + if (!app_RAND_load()) goto end; - } - if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)) { - BIO_printf(bio_err, "%s XTS ciphers not supported\n", prog); - goto end; + /* Get the cipher name, either from progname (if set) or flag. */ + if (ciphername != NULL) { + if (!opt_cipher(ciphername, &cipher)) + goto opthelp; + } + if (digestname != NULL) { + if (!opt_md(digestname, &dgst)) + goto opthelp; } - if (dgst == NULL) - dgst = EVP_sha256(); + dgst = (EVP_MD *)EVP_sha256(); if (iter == 0) iter = 1; @@ -342,7 +352,7 @@ int enc_main(int argc, char **argv) char prompt[200]; BIO_snprintf(prompt, sizeof(prompt), "enter %s %s password:", - OBJ_nid2ln(EVP_CIPHER_nid(cipher)), + EVP_CIPHER_get0_name(cipher), (enc) ? "encryption" : "decryption"); strbuf[0] = '\0'; i = EVP_read_pw_string((char *)strbuf, SIZE, prompt, enc); @@ -371,8 +381,8 @@ int enc_main(int argc, char **argv) goto end; if (debug) { - BIO_set_callback(in, BIO_debug_callback); - BIO_set_callback(out, BIO_debug_callback); + BIO_set_callback_ex(in, BIO_debug_callback_ex); + BIO_set_callback_ex(out, BIO_debug_callback_ex); BIO_set_callback_arg(in, (char *)bio_err); BIO_set_callback_arg(out, (char *)bio_err); } @@ -385,7 +395,7 @@ int enc_main(int argc, char **argv) if ((bzl = BIO_new(BIO_f_zlib())) == NULL) goto end; if (debug) { - BIO_set_callback(bzl, BIO_debug_callback); + BIO_set_callback_ex(bzl, BIO_debug_callback_ex); BIO_set_callback_arg(bzl, (char *)bio_err); } if (enc) @@ -399,7 +409,7 @@ int enc_main(int argc, char **argv) if ((b64 = BIO_new(BIO_f_base64())) == NULL) goto end; if (debug) { - BIO_set_callback(b64, BIO_debug_callback); + BIO_set_callback_ex(b64, BIO_debug_callback_ex); BIO_set_callback_arg(b64, (char *)bio_err); } if (olb64) @@ -411,14 +421,11 @@ int enc_main(int argc, char **argv) } if (cipher != NULL) { - /* - * Note that str is NULL if a key was passed on the command line, so - * we get no salt in that case. Is this a bug? - */ - if (str != NULL) { + if (str != NULL) { /* a passphrase is available */ /* - * Salt handling: if encrypting generate a salt and write to - * output BIO. If decrypting read salt from input BIO. + * Salt handling: if encrypting generate a salt if not supplied, + * and write to output BIO. If decrypting use salt from input BIO + * if not given with args */ unsigned char *sptr; size_t str_len = strlen(str); @@ -426,36 +433,47 @@ int enc_main(int argc, char **argv) if (nosalt) { sptr = NULL; } else { - if (enc) { - if (hsalt) { - if (!set_hex(hsalt, salt, sizeof(salt))) { - BIO_printf(bio_err, "invalid hex salt value\n"); + if (hsalt != NULL && !set_hex(hsalt, salt, sizeof(salt))) { + BIO_printf(bio_err, "invalid hex salt value\n"); + goto end; + } + if (enc) { /* encryption */ + if (hsalt == NULL) { + if (RAND_bytes(salt, sizeof(salt)) <= 0) { + BIO_printf(bio_err, "RAND_bytes failed\n"); + goto end; + } + /* + * If -P option then don't bother writing. + * If salt is given, shouldn't either ? + */ + if ((printkey != 2) + && (BIO_write(wbio, magic, + sizeof(magic) - 1) != sizeof(magic) - 1 + || BIO_write(wbio, + (char *)salt, + sizeof(salt)) != sizeof(salt))) { + BIO_printf(bio_err, "error writing output file\n"); goto end; } - } else if (RAND_bytes(salt, sizeof(salt)) <= 0) { - goto end; } - /* - * If -P option then don't bother writing - */ - if ((printkey != 2) - && (BIO_write(wbio, magic, - sizeof(magic) - 1) != sizeof(magic) - 1 - || BIO_write(wbio, - (char *)salt, - sizeof(salt)) != sizeof(salt))) { - BIO_printf(bio_err, "error writing output file\n"); - goto end; + } else { /* decryption */ + if (hsalt == NULL) { + if (BIO_read(rbio, mbuf, sizeof(mbuf)) != sizeof(mbuf)) { + BIO_printf(bio_err, "error reading input file\n"); + goto end; + } + if (memcmp(mbuf, magic, sizeof(mbuf)) == 0) { /* file IS salted */ + if (BIO_read(rbio, salt, + sizeof(salt)) != sizeof(salt)) { + BIO_printf(bio_err, "error reading input file\n"); + goto end; + } + } else { /* file is NOT salted, NO salt available */ + BIO_printf(bio_err, "bad magic number\n"); + goto end; + } } - } else if (BIO_read(rbio, mbuf, sizeof(mbuf)) != sizeof(mbuf) - || BIO_read(rbio, - (unsigned char *)salt, - sizeof(salt)) != sizeof(salt)) { - BIO_printf(bio_err, "error reading input file\n"); - goto end; - } else if (memcmp(mbuf, magic, sizeof(magic) - 1)) { - BIO_printf(bio_err, "bad magic number\n"); - goto end; } sptr = salt; } @@ -466,8 +484,8 @@ int enc_main(int argc, char **argv) * concatenated into a temporary buffer */ unsigned char tmpkeyiv[EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH]; - int iklen = EVP_CIPHER_key_length(cipher); - int ivlen = EVP_CIPHER_iv_length(cipher); + int iklen = EVP_CIPHER_get_key_length(cipher); + int ivlen = EVP_CIPHER_get_iv_length(cipher); /* not needed if HASH_UPDATE() is fixed : */ int islen = (sptr != NULL ? sizeof(salt) : 0); if (!PKCS5_PBKDF2_HMAC(str, str_len, sptr, islen, @@ -499,7 +517,7 @@ int enc_main(int argc, char **argv) OPENSSL_cleanse(str, str_len); } if (hiv != NULL) { - int siz = EVP_CIPHER_iv_length(cipher); + int siz = EVP_CIPHER_get_iv_length(cipher); if (siz == 0) { BIO_printf(bio_err, "warning: iv not used by this cipher\n"); } else if (!set_hex(hiv, iv, siz)) { @@ -508,7 +526,7 @@ int enc_main(int argc, char **argv) } } if ((hiv == NULL) && (str == NULL) - && EVP_CIPHER_iv_length(cipher) != 0) { + && EVP_CIPHER_get_iv_length(cipher) != 0) { /* * No IV was explicitly set and no IV was generated. * Hence the IV is undefined, making correct decryption impossible. @@ -517,12 +535,12 @@ int enc_main(int argc, char **argv) goto end; } if (hkey != NULL) { - if (!set_hex(hkey, key, EVP_CIPHER_key_length(cipher))) { + if (!set_hex(hkey, key, EVP_CIPHER_get_key_length(cipher))) { BIO_printf(bio_err, "invalid hex key value\n"); goto end; } /* wiping secret data as we no longer need it */ - OPENSSL_cleanse(hkey, strlen(hkey)); + cleanse(hkey); } if ((benc = BIO_new(BIO_f_cipher())) == NULL) @@ -535,9 +553,9 @@ int enc_main(int argc, char **argv) BIO_get_cipher_ctx(benc, &ctx); - if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) { + if (!EVP_CipherInit_ex(ctx, cipher, e, NULL, NULL, enc)) { BIO_printf(bio_err, "Error setting cipher %s\n", - EVP_CIPHER_name(cipher)); + EVP_CIPHER_get0_name(cipher)); ERR_print_errors(bio_err); goto end; } @@ -547,13 +565,13 @@ int enc_main(int argc, char **argv) if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) { BIO_printf(bio_err, "Error setting cipher %s\n", - EVP_CIPHER_name(cipher)); + EVP_CIPHER_get0_name(cipher)); ERR_print_errors(bio_err); goto end; } if (debug) { - BIO_set_callback(benc, BIO_debug_callback); + BIO_set_callback_ex(benc, BIO_debug_callback_ex); BIO_set_callback_arg(benc, (char *)bio_err); } @@ -564,15 +582,15 @@ int enc_main(int argc, char **argv) printf("%02X", salt[i]); printf("\n"); } - if (EVP_CIPHER_key_length(cipher) > 0) { + if (EVP_CIPHER_get_key_length(cipher) > 0) { printf("key="); - for (i = 0; i < EVP_CIPHER_key_length(cipher); i++) + for (i = 0; i < EVP_CIPHER_get_key_length(cipher); i++) printf("%02X", key[i]); printf("\n"); } - if (EVP_CIPHER_iv_length(cipher) > 0) { + if (EVP_CIPHER_get_iv_length(cipher) > 0) { printf("iv ="); - for (i = 0; i < EVP_CIPHER_iv_length(cipher); i++) + for (i = 0; i < EVP_CIPHER_get_iv_length(cipher); i++) printf("%02X", iv[i]); printf("\n"); } @@ -614,6 +632,8 @@ int enc_main(int argc, char **argv) BIO_free_all(out); BIO_free(benc); BIO_free(b64); + EVP_MD_free(dgst); + EVP_CIPHER_free(cipher); #ifdef ZLIB BIO_free(bzl); #endif @@ -632,9 +652,9 @@ static void show_ciphers(const OBJ_NAME *name, void *arg) /* Filter out ciphers that we cannot use */ cipher = EVP_get_cipherbyname(name->name); - if (cipher == NULL || - (EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0 || - EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE) + if (cipher == NULL + || (EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0 + || EVP_CIPHER_get_mode(cipher) == EVP_CIPH_XTS_MODE) return; BIO_printf(dec->bio, "-%-25s", name->name); diff --git a/crypto/openssl/apps/engine.c b/crypto/openssl/apps/engine.c index 746cace354b2..1b0f64309c6f 100644 --- a/crypto/openssl/apps/engine.c +++ b/crypto/openssl/apps/engine.c @@ -1,13 +1,17 @@ /* - * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include + #include "apps.h" #include "progs.h" #include @@ -19,27 +23,32 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_C, OPT_T, OPT_TT, OPT_PRE, OPT_POST, OPT_V = 100, OPT_VV, OPT_VVV, OPT_VVVV } OPTION_CHOICE; const OPTIONS engine_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] engine...\n"}, - {OPT_HELP_STR, 1, '-', - " engine... Engines to load\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"t", OPT_T, '-', "Check that specified engine is available"}, + {"pre", OPT_PRE, 's', "Run command against the ENGINE before loading it"}, + {"post", OPT_POST, 's', "Run command against the ENGINE after loading it"}, + + OPT_SECTION("Output"), {"v", OPT_V, '-', "List 'control commands' For each specified engine"}, {"vv", OPT_VV, '-', "Also display each command's description"}, {"vvv", OPT_VVV, '-', "Also add the input flags for each command"}, {"vvvv", OPT_VVVV, '-', "Also show internal input flags"}, {"c", OPT_C, '-', "List the capabilities of specified engine"}, - {"t", OPT_T, '-', "Check that specified engine is available"}, {"tt", OPT_TT, '-', "Display error trace for unavailable engines"}, - {"pre", OPT_PRE, 's', "Run command against the ENGINE before loading it"}, - {"post", OPT_POST, 's', "Run command against the ENGINE after loading it"}, {OPT_MORE_STR, OPT_EOF, 1, "Commands are like \"SO_PATH:/lib/libdriver.so\""}, + + OPT_PARAMETERS(), + {"engine", 0, 0, "ID of engine(s) to load"}, {NULL} }; @@ -351,7 +360,7 @@ int engine_main(int argc, char **argv) } } - /* Allow any trailing parameters as engine names. */ + /* Any remaining arguments are engine names. */ argc = opt_num_rest(); argv = opt_rest(); for ( ; *argv; argv++) { diff --git a/crypto/openssl/apps/errstr.c b/crypto/openssl/apps/errstr.c index 3ef01f076a8c..782705a78a33 100644 --- a/crypto/openssl/apps/errstr.c +++ b/crypto/openssl/apps/errstr.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -22,8 +22,12 @@ typedef enum OPTION_choice { const OPTIONS errstr_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] errnum...\n"}, - {OPT_HELP_STR, 1, '-', " errnum Error number\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_PARAMETERS(), + {"errnum", 0, 0, "Error number(s) to decode"}, {NULL} }; @@ -48,16 +52,19 @@ int errstr_main(int argc, char **argv) } } + /* + * We're not really an SSL application so this won't auto-init, but + * we're still interested in SSL error strings + */ + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS + | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); + + /* All remaining arg are error code. */ ret = 0; - for (argv = opt_rest(); *argv; argv++) { + for (argv = opt_rest(); *argv != NULL; argv++) { if (sscanf(*argv, "%lx", &l) == 0) { ret++; } else { - /* We're not really an SSL application so this won't auto-init, but - * we're still interested in SSL error strings - */ - OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS - | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); ERR_error_string_n(l, buf, sizeof(buf)); BIO_printf(bio_out, "%s\n", buf); } diff --git a/crypto/openssl/apps/fipsinstall.c b/crypto/openssl/apps/fipsinstall.c new file mode 100644 index 000000000000..d0efdf7643bd --- /dev/null +++ b/crypto/openssl/apps/fipsinstall.c @@ -0,0 +1,590 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "apps.h" +#include "progs.h" + +#define BUFSIZE 4096 + +/* Configuration file values */ +#define VERSION_KEY "version" +#define VERSION_VAL "1" +#define INSTALL_STATUS_VAL "INSTALL_SELF_TEST_KATS_RUN" + +static OSSL_CALLBACK self_test_events; +static char *self_test_corrupt_desc = NULL; +static char *self_test_corrupt_type = NULL; +static int self_test_log = 1; +static int quiet = 0; + +typedef enum OPTION_choice { + OPT_COMMON, + OPT_IN, OPT_OUT, OPT_MODULE, + OPT_PROV_NAME, OPT_SECTION_NAME, OPT_MAC_NAME, OPT_MACOPT, OPT_VERIFY, + OPT_NO_LOG, OPT_CORRUPT_DESC, OPT_CORRUPT_TYPE, OPT_QUIET, OPT_CONFIG, + OPT_NO_CONDITIONAL_ERRORS, + OPT_NO_SECURITY_CHECKS, + OPT_SELF_TEST_ONLOAD +} OPTION_CHOICE; + +const OPTIONS fipsinstall_options[] = { + OPT_SECTION("General"), + {"help", OPT_HELP, '-', "Display this summary"}, + {"verify", OPT_VERIFY, '-', + "Verify a config file instead of generating one"}, + {"module", OPT_MODULE, '<', "File name of the provider module"}, + {"provider_name", OPT_PROV_NAME, 's', "FIPS provider name"}, + {"section_name", OPT_SECTION_NAME, 's', + "FIPS Provider config section name (optional)"}, + {"no_conditional_errors", OPT_NO_CONDITIONAL_ERRORS, '-', + "Disable the ability of the fips module to enter an error state if" + " any conditional self tests fail"}, + {"no_security_checks", OPT_NO_SECURITY_CHECKS, '-', + "Disable the run-time FIPS security checks in the module"}, + {"self_test_onload", OPT_SELF_TEST_ONLOAD, '-', + "Forces self tests to always run on module load"}, + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input config file, used when verifying"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output config file, used when generating"}, + {"mac_name", OPT_MAC_NAME, 's', "MAC name"}, + {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form. " + "See 'PARAMETER NAMES' in the EVP_MAC_ docs"}, + {"noout", OPT_NO_LOG, '-', "Disable logging of self test events"}, + {"corrupt_desc", OPT_CORRUPT_DESC, 's', "Corrupt a self test by description"}, + {"corrupt_type", OPT_CORRUPT_TYPE, 's', "Corrupt a self test by type"}, + {"config", OPT_CONFIG, '<', "The parent config to verify"}, + {"quiet", OPT_QUIET, '-', "No messages, just exit status"}, + {NULL} +}; + +static int do_mac(EVP_MAC_CTX *ctx, unsigned char *tmp, BIO *in, + unsigned char *out, size_t *out_len) +{ + int ret = 0; + int i; + size_t outsz = *out_len; + + if (!EVP_MAC_init(ctx, NULL, 0, NULL)) + goto err; + if (EVP_MAC_CTX_get_mac_size(ctx) > outsz) + goto end; + while ((i = BIO_read(in, (char *)tmp, BUFSIZE)) != 0) { + if (i < 0 || !EVP_MAC_update(ctx, tmp, i)) + goto err; + } +end: + if (!EVP_MAC_final(ctx, out, out_len, outsz)) + goto err; + ret = 1; +err: + return ret; +} + +static int load_fips_prov_and_run_self_test(const char *prov_name) +{ + int ret = 0; + OSSL_PROVIDER *prov = NULL; + + prov = OSSL_PROVIDER_load(NULL, prov_name); + if (prov == NULL) { + BIO_printf(bio_err, "Failed to load FIPS module\n"); + goto end; + } + ret = 1; +end: + OSSL_PROVIDER_unload(prov); + return ret; +} + +static int print_mac(BIO *bio, const char *label, const unsigned char *mac, + size_t len) +{ + int ret; + char *hexstr = NULL; + + hexstr = OPENSSL_buf2hexstr(mac, (long)len); + if (hexstr == NULL) + return 0; + ret = BIO_printf(bio, "%s = %s\n", label, hexstr); + OPENSSL_free(hexstr); + return ret; +} + +static int write_config_header(BIO *out, const char *prov_name, + const char *section) +{ + return BIO_printf(out, "openssl_conf = openssl_init\n\n") + && BIO_printf(out, "[openssl_init]\n") + && BIO_printf(out, "providers = provider_section\n\n") + && BIO_printf(out, "[provider_section]\n") + && BIO_printf(out, "%s = %s\n\n", prov_name, section); +} + +/* + * Outputs a fips related config file that contains entries for the fips + * module checksum, installation indicator checksum and the options + * conditional_errors and security_checks. + * + * Returns 1 if the config file is written otherwise it returns 0 on error. + */ +static int write_config_fips_section(BIO *out, const char *section, + unsigned char *module_mac, + size_t module_mac_len, + int conditional_errors, + int security_checks, + unsigned char *install_mac, + size_t install_mac_len) +{ + int ret = 0; + + if (BIO_printf(out, "[%s]\n", section) <= 0 + || BIO_printf(out, "activate = 1\n") <= 0 + || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_VERSION, + VERSION_VAL) <= 0 + || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS, + conditional_errors ? "1" : "0") <= 0 + || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS, + security_checks ? "1" : "0") <= 0 + || !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac, + module_mac_len)) + goto end; + + if (install_mac != NULL && install_mac_len > 0) { + if (!print_mac(out, OSSL_PROV_FIPS_PARAM_INSTALL_MAC, install_mac, + install_mac_len) + || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_STATUS, + INSTALL_STATUS_VAL) <= 0) + goto end; + } + ret = 1; +end: + return ret; +} + +static CONF *generate_config_and_load(const char *prov_name, + const char *section, + unsigned char *module_mac, + size_t module_mac_len, + int conditional_errors, + int security_checks) +{ + BIO *mem_bio = NULL; + CONF *conf = NULL; + + mem_bio = BIO_new(BIO_s_mem()); + if (mem_bio == NULL) + return 0; + if (!write_config_header(mem_bio, prov_name, section) + || !write_config_fips_section(mem_bio, section, + module_mac, module_mac_len, + conditional_errors, + security_checks, + NULL, 0)) + goto end; + + conf = app_load_config_bio(mem_bio, NULL); + if (conf == NULL) + goto end; + + if (CONF_modules_load(conf, NULL, 0) <= 0) + goto end; + BIO_free(mem_bio); + return conf; +end: + NCONF_free(conf); + BIO_free(mem_bio); + return NULL; +} + +static void free_config_and_unload(CONF *conf) +{ + if (conf != NULL) { + NCONF_free(conf); + CONF_modules_unload(1); + } +} + +static int verify_module_load(const char *parent_config_file) +{ + return OSSL_LIB_CTX_load_config(NULL, parent_config_file); +} + +/* + * Returns 1 if the config file entries match the passed in module_mac and + * install_mac values, otherwise it returns 0. + */ +static int verify_config(const char *infile, const char *section, + unsigned char *module_mac, size_t module_mac_len, + unsigned char *install_mac, size_t install_mac_len) +{ + int ret = 0; + char *s = NULL; + unsigned char *buf1 = NULL, *buf2 = NULL; + long len; + CONF *conf = NULL; + + /* read in the existing values and check they match the saved values */ + conf = app_load_config(infile); + if (conf == NULL) + goto end; + + s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_VERSION); + if (s == NULL || strcmp(s, VERSION_VAL) != 0) { + BIO_printf(bio_err, "version not found\n"); + goto end; + } + s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_MODULE_MAC); + if (s == NULL) { + BIO_printf(bio_err, "Module integrity MAC not found\n"); + goto end; + } + buf1 = OPENSSL_hexstr2buf(s, &len); + if (buf1 == NULL + || (size_t)len != module_mac_len + || memcmp(module_mac, buf1, module_mac_len) != 0) { + BIO_printf(bio_err, "Module integrity mismatch\n"); + goto end; + } + if (install_mac != NULL && install_mac_len > 0) { + s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_STATUS); + if (s == NULL || strcmp(s, INSTALL_STATUS_VAL) != 0) { + BIO_printf(bio_err, "install status not found\n"); + goto end; + } + s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_MAC); + if (s == NULL) { + BIO_printf(bio_err, "Install indicator MAC not found\n"); + goto end; + } + buf2 = OPENSSL_hexstr2buf(s, &len); + if (buf2 == NULL + || (size_t)len != install_mac_len + || memcmp(install_mac, buf2, install_mac_len) != 0) { + BIO_printf(bio_err, "Install indicator status mismatch\n"); + goto end; + } + } + ret = 1; +end: + OPENSSL_free(buf1); + OPENSSL_free(buf2); + NCONF_free(conf); + return ret; +} + +int fipsinstall_main(int argc, char **argv) +{ + int ret = 1, verify = 0, gotkey = 0, gotdigest = 0, self_test_onload = 0; + int enable_conditional_errors = 1, enable_security_checks = 1; + const char *section_name = "fips_sect"; + const char *mac_name = "HMAC"; + const char *prov_name = "fips"; + BIO *module_bio = NULL, *mem_bio = NULL, *fout = NULL; + char *in_fname = NULL, *out_fname = NULL, *prog; + char *module_fname = NULL, *parent_config = NULL, *module_path = NULL; + const char *tail; + EVP_MAC_CTX *ctx = NULL, *ctx2 = NULL; + STACK_OF(OPENSSL_STRING) *opts = NULL; + OPTION_CHOICE o; + unsigned char *read_buffer = NULL; + unsigned char module_mac[EVP_MAX_MD_SIZE]; + size_t module_mac_len = EVP_MAX_MD_SIZE; + unsigned char install_mac[EVP_MAX_MD_SIZE]; + size_t install_mac_len = EVP_MAX_MD_SIZE; + EVP_MAC *mac = NULL; + CONF *conf = NULL; + + if ((opts = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; + + prog = opt_init(argc, argv, fipsinstall_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: +opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto cleanup; + case OPT_HELP: + opt_help(fipsinstall_options); + ret = 0; + goto end; + case OPT_IN: + in_fname = opt_arg(); + break; + case OPT_OUT: + out_fname = opt_arg(); + break; + case OPT_NO_CONDITIONAL_ERRORS: + enable_conditional_errors = 0; + break; + case OPT_NO_SECURITY_CHECKS: + enable_security_checks = 0; + break; + case OPT_QUIET: + quiet = 1; + /* FALLTHROUGH */ + case OPT_NO_LOG: + self_test_log = 0; + break; + case OPT_CORRUPT_DESC: + self_test_corrupt_desc = opt_arg(); + break; + case OPT_CORRUPT_TYPE: + self_test_corrupt_type = opt_arg(); + break; + case OPT_PROV_NAME: + prov_name = opt_arg(); + break; + case OPT_MODULE: + module_fname = opt_arg(); + break; + case OPT_SECTION_NAME: + section_name = opt_arg(); + break; + case OPT_MAC_NAME: + mac_name = opt_arg(); + break; + case OPT_CONFIG: + parent_config = opt_arg(); + break; + case OPT_MACOPT: + if (!sk_OPENSSL_STRING_push(opts, opt_arg())) + goto opthelp; + if (strncmp(opt_arg(), "hexkey:", 7) == 0) + gotkey = 1; + else if (strncmp(opt_arg(), "digest:", 7) == 0) + gotdigest = 1; + break; + case OPT_VERIFY: + verify = 1; + break; + case OPT_SELF_TEST_ONLOAD: + self_test_onload = 1; + break; + } + } + + /* No extra arguments. */ + argc = opt_num_rest(); + if (argc != 0 || (verify && in_fname == NULL)) + goto opthelp; + + if (parent_config != NULL) { + /* Test that a parent config can load the module */ + if (verify_module_load(parent_config)) { + ret = OSSL_PROVIDER_available(NULL, prov_name) ? 0 : 1; + if (!quiet) + BIO_printf(bio_err, "FIPS provider is %s\n", + ret == 0 ? "available" : " not available"); + } + goto end; + } + if (module_fname == NULL) + goto opthelp; + + tail = opt_path_end(module_fname); + if (tail != NULL) { + module_path = OPENSSL_strdup(module_fname); + if (module_path == NULL) + goto end; + module_path[tail - module_fname] = '\0'; + if (!OSSL_PROVIDER_set_default_search_path(NULL, module_path)) + goto end; + } + + if (self_test_log + || self_test_corrupt_desc != NULL + || self_test_corrupt_type != NULL) + OSSL_SELF_TEST_set_callback(NULL, self_test_events, NULL); + + /* Use the default FIPS HMAC digest and key if not specified. */ + if (!gotdigest && !sk_OPENSSL_STRING_push(opts, "digest:SHA256")) + goto end; + if (!gotkey && !sk_OPENSSL_STRING_push(opts, "hexkey:" FIPS_KEY_STRING)) + goto end; + + module_bio = bio_open_default(module_fname, 'r', FORMAT_BINARY); + if (module_bio == NULL) { + BIO_printf(bio_err, "Failed to open module file\n"); + goto end; + } + + read_buffer = app_malloc(BUFSIZE, "I/O buffer"); + if (read_buffer == NULL) + goto end; + + mac = EVP_MAC_fetch(app_get0_libctx(), mac_name, app_get0_propq()); + if (mac == NULL) { + BIO_printf(bio_err, "Unable to get MAC of type %s\n", mac_name); + goto end; + } + + ctx = EVP_MAC_CTX_new(mac); + if (ctx == NULL) { + BIO_printf(bio_err, "Unable to create MAC CTX for module check\n"); + goto end; + } + + if (opts != NULL) { + int ok = 1; + OSSL_PARAM *params = + app_params_new_from_opts(opts, EVP_MAC_settable_ctx_params(mac)); + + if (params == NULL) + goto end; + + if (!EVP_MAC_CTX_set_params(ctx, params)) { + BIO_printf(bio_err, "MAC parameter error\n"); + ERR_print_errors(bio_err); + ok = 0; + } + app_params_free(params); + if (!ok) + goto end; + } + + ctx2 = EVP_MAC_CTX_dup(ctx); + if (ctx2 == NULL) { + BIO_printf(bio_err, "Unable to create MAC CTX for install indicator\n"); + goto end; + } + + if (!do_mac(ctx, read_buffer, module_bio, module_mac, &module_mac_len)) + goto end; + + if (self_test_onload == 0) { + mem_bio = BIO_new_mem_buf((const void *)INSTALL_STATUS_VAL, + strlen(INSTALL_STATUS_VAL)); + if (mem_bio == NULL) { + BIO_printf(bio_err, "Unable to create memory BIO\n"); + goto end; + } + if (!do_mac(ctx2, read_buffer, mem_bio, install_mac, &install_mac_len)) + goto end; + } else { + install_mac_len = 0; + } + + if (verify) { + if (!verify_config(in_fname, section_name, module_mac, module_mac_len, + install_mac, install_mac_len)) + goto end; + if (!quiet) + BIO_printf(bio_err, "VERIFY PASSED\n"); + } else { + + conf = generate_config_and_load(prov_name, section_name, module_mac, + module_mac_len, + enable_conditional_errors, + enable_security_checks); + if (conf == NULL) + goto end; + if (!load_fips_prov_and_run_self_test(prov_name)) + goto end; + + fout = + out_fname == NULL ? dup_bio_out(FORMAT_TEXT) + : bio_open_default(out_fname, 'w', FORMAT_TEXT); + if (fout == NULL) { + BIO_printf(bio_err, "Failed to open file\n"); + goto end; + } + if (!write_config_fips_section(fout, section_name, + module_mac, module_mac_len, + enable_conditional_errors, + enable_security_checks, + install_mac, install_mac_len)) + goto end; + if (!quiet) + BIO_printf(bio_err, "INSTALL PASSED\n"); + } + + ret = 0; +end: + if (ret == 1) { + if (!quiet) + BIO_printf(bio_err, "%s FAILED\n", verify ? "VERIFY" : "INSTALL"); + ERR_print_errors(bio_err); + } + +cleanup: + OPENSSL_free(module_path); + BIO_free(fout); + BIO_free(mem_bio); + BIO_free(module_bio); + sk_OPENSSL_STRING_free(opts); + EVP_MAC_free(mac); + EVP_MAC_CTX_free(ctx2); + EVP_MAC_CTX_free(ctx); + OPENSSL_free(read_buffer); + free_config_and_unload(conf); + return ret; +} + +static int self_test_events(const OSSL_PARAM params[], void *arg) +{ + const OSSL_PARAM *p = NULL; + const char *phase = NULL, *type = NULL, *desc = NULL; + int ret = 0; + + p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_PHASE); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) + goto err; + phase = (const char *)p->data; + + p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_DESC); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) + goto err; + desc = (const char *)p->data; + + p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_TYPE); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) + goto err; + type = (const char *)p->data; + + if (self_test_log) { + if (strcmp(phase, OSSL_SELF_TEST_PHASE_START) == 0) + BIO_printf(bio_err, "%s : (%s) : ", desc, type); + else if (strcmp(phase, OSSL_SELF_TEST_PHASE_PASS) == 0 + || strcmp(phase, OSSL_SELF_TEST_PHASE_FAIL) == 0) + BIO_printf(bio_err, "%s\n", phase); + } + /* + * The self test code will internally corrupt the KAT test result if an + * error is returned during the corrupt phase. + */ + if (strcmp(phase, OSSL_SELF_TEST_PHASE_CORRUPT) == 0 + && (self_test_corrupt_desc != NULL + || self_test_corrupt_type != NULL)) { + if (self_test_corrupt_desc != NULL + && strcmp(self_test_corrupt_desc, desc) != 0) + goto end; + if (self_test_corrupt_type != NULL + && strcmp(self_test_corrupt_type, type) != 0) + goto end; + BIO_printf(bio_err, "%s ", phase); + goto err; + } +end: + ret = 1; +err: + return ret; +} diff --git a/crypto/openssl/apps/gendsa.c b/crypto/openssl/apps/gendsa.c index ec57c92a9492..27feb793fed2 100644 --- a/crypto/openssl/apps/gendsa.c +++ b/crypto/openssl/apps/gendsa.c @@ -1,13 +1,14 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include + #include #include #include @@ -22,22 +23,30 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER, - OPT_R_ENUM + OPT_COMMON, + OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER, OPT_VERBOSE, + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS gendsa_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [args] dsaparam-file\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] dsaparam-file\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Output"), {"out", OPT_OUT, '>', "Output the key to the specified file"}, {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, OPT_R_OPTIONS, + OPT_PROV_OPTIONS, {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + + OPT_PARAMETERS(), + {"dsaparam-file", 0, 0, "File containing DSA parameters"}, {NULL} }; @@ -45,13 +54,13 @@ int gendsa_main(int argc, char **argv) { ENGINE *e = NULL; BIO *out = NULL, *in = NULL; - DSA *dsa = NULL; - const EVP_CIPHER *enc = NULL; - char *dsaparams = NULL; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + EVP_CIPHER *enc = NULL; + char *dsaparams = NULL, *ciphername = NULL; char *outfile = NULL, *passoutarg = NULL, *passout = NULL, *prog; OPTION_CHOICE o; - int ret = 1, private = 0; - const BIGNUM *p = NULL; + int ret = 1, private = 0, verbose = 0, nbits; prog = opt_init(argc, argv, gendsa_options); while ((o = opt_next()) != OPT_EOF) { @@ -78,55 +87,71 @@ int gendsa_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; - case OPT_CIPHER: - if (!opt_cipher(opt_unknown(), &enc)) + case OPT_PROV_CASES: + if (!opt_provider(o)) goto end; break; + case OPT_CIPHER: + ciphername = opt_unknown(); + break; + case OPT_VERBOSE: + verbose = 1; + break; } } + + /* One argument, the params file. */ argc = opt_num_rest(); argv = opt_rest(); - private = 1; - if (argc != 1) goto opthelp; - dsaparams = *argv; + dsaparams = argv[0]; - if (!app_passwd(NULL, passoutarg, NULL, &passout)) { - BIO_printf(bio_err, "Error getting password\n"); + if (!app_RAND_load()) goto end; - } - in = bio_open_default(dsaparams, 'r', FORMAT_PEM); - if (in == NULL) - goto end2; + if (ciphername != NULL) { + if (!opt_cipher(ciphername, &enc)) + goto end; + } + private = 1; - if ((dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) { - BIO_printf(bio_err, "unable to load DSA parameter file\n"); + if (!app_passwd(NULL, passoutarg, NULL, &passout)) { + BIO_printf(bio_err, "Error getting password\n"); goto end; } - BIO_free(in); - in = NULL; + + pkey = load_keyparams(dsaparams, FORMAT_UNDEF, 1, "DSA", "DSA parameters"); out = bio_open_owner(outfile, FORMAT_PEM, private); if (out == NULL) goto end2; - DSA_get0_pqg(dsa, &p, NULL, NULL); - - if (BN_num_bits(p) > OPENSSL_DSA_MAX_MODULUS_BITS) + nbits = EVP_PKEY_get_bits(pkey); + if (nbits > OPENSSL_DSA_MAX_MODULUS_BITS) BIO_printf(bio_err, "Warning: It is not recommended to use more than %d bit for DSA keys.\n" " Your key size is %d! Larger key size may behave not as expected.\n", - OPENSSL_DSA_MAX_MODULUS_BITS, BN_num_bits(p)); + OPENSSL_DSA_MAX_MODULUS_BITS, EVP_PKEY_get_bits(pkey)); - BIO_printf(bio_err, "Generating DSA key, %d bits\n", BN_num_bits(p)); - if (!DSA_generate_key(dsa)) + ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), pkey, app_get0_propq()); + if (ctx == NULL) { + BIO_printf(bio_err, "unable to create PKEY context\n"); goto end; + } + EVP_PKEY_free(pkey); + pkey = NULL; + if (EVP_PKEY_keygen_init(ctx) <= 0) { + BIO_printf(bio_err, "unable to set up for key generation\n"); + goto end; + } + pkey = app_keygen(ctx, "DSA", nbits, verbose); assert(private); - if (!PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout)) + if (!PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, passout)) { + BIO_printf(bio_err, "unable to output generated key\n"); goto end; + } ret = 0; end: if (ret != 0) @@ -134,7 +159,9 @@ int gendsa_main(int argc, char **argv) end2: BIO_free(in); BIO_free_all(out); - DSA_free(dsa); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + EVP_CIPHER_free(enc); release_engine(e); OPENSSL_free(passout); return ret; diff --git a/crypto/openssl/apps/genpkey.c b/crypto/openssl/apps/genpkey.c index 3fe87e853c57..d00754eeaca0 100644 --- a/crypto/openssl/apps/genpkey.c +++ b/crypto/openssl/apps/genpkey.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,34 +14,44 @@ #include #include #include -#ifndef OPENSSL_NO_ENGINE -# include -#endif -static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e); +static int quiet; + +static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e, + OSSL_LIB_CTX *libctx, const char *propq); static int genpkey_cb(EVP_PKEY_CTX *ctx); typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE, - OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER + OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER, + OPT_QUIET, OPT_CONFIG, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS genpkey_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"out", OPT_OUT, '>', "Output file"}, - {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"}, - {"pass", OPT_PASS, 's', "Output file pass phrase source"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif {"paramfile", OPT_PARAMFILE, '<', "Parameters file"}, {"algorithm", OPT_ALGORITHM, 's', "The public key algorithm"}, + {"quiet", OPT_QUIET, '-', "Do not output status while generating keys"}, {"pkeyopt", OPT_PKEYOPT, 's', "Set the public key algorithm option as opt:value"}, + OPT_CONFIG_OPTION, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"}, + {"pass", OPT_PASS, 's', "Output file pass phrase source"}, {"genparam", OPT_GENPARAM, '-', "Generate parameters, not key"}, {"text", OPT_TEXT, '-', "Print the in text"}, {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + + OPT_PROV_OPTIONS, + /* This is deliberately last. */ {OPT_HELP_STR, 1, 1, "Order of options may be important! See the documentation.\n"}, @@ -50,17 +60,24 @@ const OPTIONS genpkey_options[] = { int genpkey_main(int argc, char **argv) { + CONF *conf = NULL; BIO *in = NULL, *out = NULL; ENGINE *e = NULL; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; - char *outfile = NULL, *passarg = NULL, *pass = NULL, *prog; - const EVP_CIPHER *cipher = NULL; + char *outfile = NULL, *passarg = NULL, *pass = NULL, *prog, *p; + const char *ciphername = NULL, *paramfile = NULL, *algname = NULL; + EVP_CIPHER *cipher = NULL; OPTION_CHOICE o; int outformat = FORMAT_PEM, text = 0, ret = 1, rv, do_param = 0; - int private = 0; + int private = 0, i; + OSSL_LIB_CTX *libctx = app_get0_libctx(); + STACK_OF(OPENSSL_STRING) *keyopt = NULL; prog = opt_init(argc, argv, genpkey_options); + keyopt = sk_OPENSSL_STRING_new_null(); + if (keyopt == NULL) + goto end; while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: @@ -88,56 +105,70 @@ int genpkey_main(int argc, char **argv) case OPT_PARAMFILE: if (do_param == 1) goto opthelp; - if (!init_keygen_file(&ctx, opt_arg(), e)) - goto end; + paramfile = opt_arg(); break; case OPT_ALGORITHM: - if (!init_gen_str(&ctx, opt_arg(), e, do_param)) - goto end; + algname = opt_arg(); break; case OPT_PKEYOPT: - if (ctx == NULL) { - BIO_printf(bio_err, "%s: No keytype specified.\n", prog); - goto opthelp; - } - if (pkey_ctrl_string(ctx, opt_arg()) <= 0) { - BIO_printf(bio_err, - "%s: Error setting %s parameter:\n", - prog, opt_arg()); - ERR_print_errors(bio_err); + if (!sk_OPENSSL_STRING_push(keyopt, opt_arg())) goto end; - } + break; + case OPT_QUIET: + quiet = 1; break; case OPT_GENPARAM: - if (ctx != NULL) - goto opthelp; do_param = 1; break; case OPT_TEXT: text = 1; break; case OPT_CIPHER: - if (!opt_cipher(opt_unknown(), &cipher) - || do_param == 1) - goto opthelp; - if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE || - EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE || - EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE || - EVP_CIPHER_mode(cipher) == EVP_CIPH_OCB_MODE) { - BIO_printf(bio_err, "%s: cipher mode not supported\n", prog); + ciphername = opt_unknown(); + break; + case OPT_CONFIG: + conf = app_load_config_modules(opt_arg()); + if (conf == NULL) goto end; - } + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; - private = do_param ? 0 : 1; - + /* Fetch cipher, etc. */ + if (paramfile != NULL) { + if (!init_keygen_file(&ctx, paramfile, e, libctx, app_get0_propq())) + goto end; + } + if (algname != NULL) { + if (!init_gen_str(&ctx, algname, e, do_param, libctx, app_get0_propq())) + goto end; + } if (ctx == NULL) goto opthelp; + for (i = 0; i < sk_OPENSSL_STRING_num(keyopt); i++) { + p = sk_OPENSSL_STRING_value(keyopt, i); + if (pkey_ctrl_string(ctx, p) <= 0) { + BIO_printf(bio_err, "%s: Error setting %s parameter:\n", prog, p); + ERR_print_errors(bio_err); + goto end; + } + } + if (ciphername != NULL) + if (!opt_cipher(ciphername, &cipher) || do_param == 1) + goto opthelp; + + private = do_param ? 0 : 1; + if (!app_passwd(passarg, NULL, &pass, NULL)) { BIO_puts(bio_err, "Error getting password\n"); goto end; @@ -150,19 +181,8 @@ int genpkey_main(int argc, char **argv) EVP_PKEY_CTX_set_cb(ctx, genpkey_cb); EVP_PKEY_CTX_set_app_data(ctx, bio_err); - if (do_param) { - if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) { - BIO_puts(bio_err, "Error generating parameters\n"); - ERR_print_errors(bio_err); - goto end; - } - } else { - if (EVP_PKEY_keygen(ctx, &pkey) <= 0) { - BIO_puts(bio_err, "Error generating key\n"); - ERR_print_errors(bio_err); - goto end; - } - } + pkey = do_param ? app_paramgen(ctx, algname) + : app_keygen(ctx, algname, 0, 0 /* not verbose */); if (do_param) { rv = PEM_write_bio_Parameters(out, pkey); @@ -181,7 +201,6 @@ int genpkey_main(int argc, char **argv) if (rv <= 0) { BIO_puts(bio_err, "Error writing key\n"); - ERR_print_errors(bio_err); ret = 1; } @@ -193,22 +212,27 @@ int genpkey_main(int argc, char **argv) if (rv <= 0) { BIO_puts(bio_err, "Error printing key\n"); - ERR_print_errors(bio_err); ret = 1; } } end: + sk_OPENSSL_STRING_free(keyopt); + if (ret != 0) + ERR_print_errors(bio_err); EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(ctx); + EVP_CIPHER_free(cipher); BIO_free_all(out); BIO_free(in); release_engine(e); OPENSSL_free(pass); + NCONF_free(conf); return ret; } -static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e) +static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e, + OSSL_LIB_CTX *libctx, const char *propq) { BIO *pbio; EVP_PKEY *pkey = NULL; @@ -219,20 +243,23 @@ static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e) } pbio = BIO_new_file(file, "r"); - if (!pbio) { + if (pbio == NULL) { BIO_printf(bio_err, "Can't open parameter file %s\n", file); return 0; } - pkey = PEM_read_bio_Parameters(pbio, NULL); + pkey = PEM_read_bio_Parameters_ex(pbio, NULL, libctx, propq); BIO_free(pbio); - if (!pkey) { + if (pkey == NULL) { BIO_printf(bio_err, "Error reading parameter file %s\n", file); return 0; } - ctx = EVP_PKEY_CTX_new(pkey, e); + if (e != NULL) + ctx = EVP_PKEY_CTX_new(pkey, e); + else + ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); if (ctx == NULL) goto err; if (EVP_PKEY_keygen_init(ctx) <= 0) @@ -251,11 +278,10 @@ static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e) } int init_gen_str(EVP_PKEY_CTX **pctx, - const char *algname, ENGINE *e, int do_param) + const char *algname, ENGINE *e, int do_param, + OSSL_LIB_CTX *libctx, const char *propq) { EVP_PKEY_CTX *ctx = NULL; - const EVP_PKEY_ASN1_METHOD *ameth; - ENGINE *tmpeng = NULL; int pkey_id; if (*pctx) { @@ -263,27 +289,13 @@ int init_gen_str(EVP_PKEY_CTX **pctx, return 0; } - ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1); - -#ifndef OPENSSL_NO_ENGINE - if (!ameth && e) - ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1); -#endif - - if (!ameth) { - BIO_printf(bio_err, "Algorithm %s not found\n", algname); - return 0; - } - - ERR_clear_error(); + pkey_id = get_legacy_pkey_id(libctx, algname, e); + if (pkey_id != NID_undef) + ctx = EVP_PKEY_CTX_new_id(pkey_id, e); + else + ctx = EVP_PKEY_CTX_new_from_name(libctx, algname, propq); - EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(tmpeng); -#endif - ctx = EVP_PKEY_CTX_new_id(pkey_id, e); - - if (!ctx) + if (ctx == NULL) goto err; if (do_param) { if (EVP_PKEY_paramgen_init(ctx) <= 0) @@ -308,16 +320,22 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx) { char c = '*'; BIO *b = EVP_PKEY_CTX_get_app_data(ctx); - int p; - p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); - if (p == 0) + + if (quiet) + return 1; + + switch (EVP_PKEY_CTX_get_keygen_info(ctx, 0)) { + case 0: c = '.'; - if (p == 1) + break; + case 1: c = '+'; - if (p == 2) - c = '*'; - if (p == 3) + break; + case 3: c = '\n'; + break; + } + BIO_write(b, &c, 1); (void)BIO_flush(b); return 1; diff --git a/crypto/openssl/apps/genrsa.c b/crypto/openssl/apps/genrsa.c index e34a2f7ab9e8..4436b7fa1745 100644 --- a/crypto/openssl/apps/genrsa.c +++ b/crypto/openssl/apps/genrsa.c @@ -1,13 +1,14 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include + #include #include #include @@ -26,52 +27,72 @@ #define DEFBITS 2048 #define DEFPRIMES 2 -static int genrsa_cb(int p, int n, BN_GENCB *cb); +static int verbose = 0; + +static int genrsa_cb(EVP_PKEY_CTX *ctx); typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_3, OPT_F4, OPT_ENGINE, - OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, - OPT_R_ENUM + OPT_COMMON, +#ifndef OPENSSL_NO_DEPRECATED_3_0 + OPT_3, +#endif + OPT_F4, OPT_ENGINE, + OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, OPT_VERBOSE, + OPT_R_ENUM, OPT_PROV_ENUM, OPT_TRADITIONAL } OPTION_CHOICE; const OPTIONS genrsa_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] numbits\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"3", OPT_3, '-', "Use 3 for the E value"}, - {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, - {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, - {"out", OPT_OUT, '>', "Output the key to specified file"}, - OPT_R_OPTIONS, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + + OPT_SECTION("Input"), +#ifndef OPENSSL_NO_DEPRECATED_3_0 + {"3", OPT_3, '-', "(deprecated) Use 3 for the E value"}, +#endif + {"F4", OPT_F4, '-', "Use the Fermat number F4 (0x10001) for the E value"}, + {"f4", OPT_F4, '-', "Use the Fermat number F4 (0x10001) for the E value"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output the key to specified file"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"primes", OPT_PRIMES, 'p', "Specify number of primes"}, + {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"traditional", OPT_TRADITIONAL, '-', + "Use traditional format for private keys"}, + {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, + + OPT_R_OPTIONS, + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"numbits", 0, 0, "Size of key in bits"}, {NULL} }; int genrsa_main(int argc, char **argv) { BN_GENCB *cb = BN_GENCB_new(); - PW_CB_DATA cb_data; ENGINE *eng = NULL; BIGNUM *bn = BN_new(); BIO *out = NULL; - const BIGNUM *e; - RSA *rsa = NULL; - const EVP_CIPHER *enc = NULL; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + EVP_CIPHER *enc = NULL; int ret = 1, num = DEFBITS, private = 0, primes = DEFPRIMES; unsigned long f4 = RSA_F4; char *outfile = NULL, *passoutarg = NULL, *passout = NULL; - char *prog, *hexe, *dece; + char *prog, *hexe, *dece, *ciphername = NULL; OPTION_CHOICE o; + int traditional = 0; if (bn == NULL || cb == NULL) goto end; - BN_GENCB_set(cb, genrsa_cb, bio_err); - prog = opt_init(argc, argv, genrsa_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -84,9 +105,11 @@ int genrsa_main(int argc, char **argv) ret = 0; opt_help(genrsa_options); goto end; +#ifndef OPENSSL_NO_DEPRECATED_3_0 case OPT_3: - f4 = 3; + f4 = RSA_3; break; +#endif case OPT_F4: f4 = RSA_F4; break; @@ -100,19 +123,29 @@ int genrsa_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_PASSOUT: passoutarg = opt_arg(); break; case OPT_CIPHER: - if (!opt_cipher(opt_unknown(), &enc)) - goto end; + ciphername = opt_unknown(); break; case OPT_PRIMES: - if (!opt_int(opt_arg(), &primes)) - goto end; + primes = opt_int_arg(); + break; + case OPT_VERBOSE: + verbose = 1; + break; + case OPT_TRADITIONAL: + traditional = 1; break; } } + + /* One optional argument, the bitsize. */ argc = opt_num_rest(); argv = opt_rest(); @@ -129,7 +162,14 @@ int genrsa_main(int argc, char **argv) goto opthelp; } + if (!app_RAND_load()) + goto end; + private = 1; + if (ciphername != NULL) { + if (!opt_cipher(ciphername, &enc)) + goto end; + } if (!app_passwd(NULL, passoutarg, NULL, &passout)) { BIO_printf(bio_err, "Error getting password\n"); goto end; @@ -139,37 +179,65 @@ int genrsa_main(int argc, char **argv) if (out == NULL) goto end; - BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus (%d primes)\n", - num, primes); - rsa = eng ? RSA_new_method(eng) : RSA_new(); - if (rsa == NULL) + if (!init_gen_str(&ctx, "RSA", eng, 0, app_get0_libctx(), + app_get0_propq())) goto end; - if (!BN_set_word(bn, f4) - || !RSA_generate_multi_prime_key(rsa, num, primes, bn, cb)) - goto end; + EVP_PKEY_CTX_set_cb(ctx, genrsa_cb); + EVP_PKEY_CTX_set_app_data(ctx, bio_err); - RSA_get0_key(rsa, NULL, &e, NULL); - hexe = BN_bn2hex(e); - dece = BN_bn2dec(e); - if (hexe && dece) { - BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe); + if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, num) <= 0) { + BIO_printf(bio_err, "Error setting RSA length\n"); + goto end; + } + if (!BN_set_word(bn, f4)) { + BIO_printf(bio_err, "Error allocating RSA public exponent\n"); + goto end; + } + if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, bn) <= 0) { + BIO_printf(bio_err, "Error setting RSA public exponent\n"); + goto end; } - OPENSSL_free(hexe); - OPENSSL_free(dece); - cb_data.password = passout; - cb_data.prompt_info = outfile; - assert(private); - if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, - (pem_password_cb *)password_callback, - &cb_data)) + if (EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, primes) <= 0) { + BIO_printf(bio_err, "Error setting number of primes\n"); goto end; + } + pkey = app_keygen(ctx, "RSA", num, verbose); + + if (verbose) { + BIGNUM *e = NULL; + + /* Every RSA key has an 'e' */ + EVP_PKEY_get_bn_param(pkey, "e", &e); + if (e == NULL) { + BIO_printf(bio_err, "Error cannot access RSA e\n"); + goto end; + } + hexe = BN_bn2hex(e); + dece = BN_bn2dec(e); + if (hexe && dece) { + BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe); + } + OPENSSL_free(hexe); + OPENSSL_free(dece); + BN_free(e); + } + if (traditional) { + if (!PEM_write_bio_PrivateKey_traditional(out, pkey, enc, NULL, 0, + NULL, passout)) + goto end; + } else { + if (!PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, passout)) + goto end; + } ret = 0; end: BN_free(bn); BN_GENCB_free(cb); - RSA_free(rsa); + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + EVP_CIPHER_free(enc); BIO_free_all(out); release_engine(eng); OPENSSL_free(passout); @@ -178,9 +246,14 @@ int genrsa_main(int argc, char **argv) return ret; } -static int genrsa_cb(int p, int n, BN_GENCB *cb) +static int genrsa_cb(EVP_PKEY_CTX *ctx) { char c = '*'; + BIO *b = EVP_PKEY_CTX_get_app_data(ctx); + int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); + + if (!verbose) + return 1; if (p == 0) c = '.'; @@ -190,7 +263,7 @@ static int genrsa_cb(int p, int n, BN_GENCB *cb) c = '*'; if (p == 3) c = '\n'; - BIO_write(BN_GENCB_get_arg(cb), &c, 1); - (void)BIO_flush(BN_GENCB_get_arg(cb)); + BIO_write(b, &c, 1); + (void)BIO_flush(b); return 1; } diff --git a/crypto/openssl/apps/include/__DECC_INCLUDE_EPILOGUE.H b/crypto/openssl/apps/include/__DECC_INCLUDE_EPILOGUE.H new file mode 100644 index 000000000000..2ab493330675 --- /dev/null +++ b/crypto/openssl/apps/include/__DECC_INCLUDE_EPILOGUE.H @@ -0,0 +1,22 @@ +/* + * Copyright 2016-2021 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 + */ + +/* + * This file is only used by HP C/C++ on VMS, and is included automatically + * after each header file from this directory + */ + +/* + * The C++ compiler doesn't understand these pragmas, even though it + * understands the corresponding command line qualifier. + */ +#ifndef __cplusplus +/* restore state. Must correspond to the save in __decc_include_prologue.h */ +# pragma names restore +#endif diff --git a/crypto/openssl/apps/include/__DECC_INCLUDE_PROLOGUE.H b/crypto/openssl/apps/include/__DECC_INCLUDE_PROLOGUE.H new file mode 100644 index 000000000000..8e95fa975488 --- /dev/null +++ b/crypto/openssl/apps/include/__DECC_INCLUDE_PROLOGUE.H @@ -0,0 +1,26 @@ +/* + * Copyright 2016-2021 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 + */ + +/* + * This file is only used by HP C/C++ on VMS, and is included automatically + * after each header file from this directory + */ + +/* + * The C++ compiler doesn't understand these pragmas, even though it + * understands the corresponding command line qualifier. + */ +#ifndef __cplusplus +/* save state */ +# pragma names save +/* have the compiler shorten symbols larger than 31 chars to 23 chars + * followed by a 8 hex char CRC + */ +# pragma names as_is,shortened +#endif diff --git a/crypto/openssl/apps/include/app_libctx.h b/crypto/openssl/apps/include/app_libctx.h new file mode 100644 index 000000000000..17c0afc713d2 --- /dev/null +++ b/crypto/openssl/apps/include/app_libctx.h @@ -0,0 +1,20 @@ +/* + * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_APPS_LIBCTX_H +# define OSSL_APPS_LIBCTX_H + +# include + +OSSL_LIB_CTX *app_create_libctx(void); +OSSL_LIB_CTX *app_get0_libctx(void); +int app_set_propq(const char *arg); +const char *app_get0_propq(void); + +#endif diff --git a/crypto/openssl/apps/include/app_params.h b/crypto/openssl/apps/include/app_params.h new file mode 100644 index 000000000000..79f8f58b3122 --- /dev/null +++ b/crypto/openssl/apps/include/app_params.h @@ -0,0 +1,14 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +int print_param_types(const char *thing, const OSSL_PARAM *pdefs, int indent); +void print_param_value(const OSSL_PARAM *p, int indent); + diff --git a/crypto/openssl/apps/include/apps.h b/crypto/openssl/apps/include/apps.h new file mode 100644 index 000000000000..baacd0025d68 --- /dev/null +++ b/crypto/openssl/apps/include/apps.h @@ -0,0 +1,348 @@ +/* + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_APPS_H +# define OSSL_APPS_H + +# include "e_os.h" /* struct timeval for DTLS */ +# include "internal/nelem.h" +# include "internal/sockets.h" /* for openssl_fdset() */ +# include "internal/cryptlib.h" /* ossl_assert() */ +# include + +# include +# include +# ifndef OPENSSL_NO_POSIX_IO +# include +# include +# endif + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include "apps_ui.h" +# include "opt.h" +# include "fmt.h" +# include "platform.h" +# include "engine_loader.h" +# include "app_libctx.h" + +/* + * quick macro when you need to pass an unsigned char instead of a char. + * this is true for some implementations of the is*() functions, for + * example. + */ +# define _UC(c) ((unsigned char)(c)) + +void app_RAND_load_conf(CONF *c, const char *section); +int app_RAND_write(void); +int app_RAND_load(void); + +extern char *default_config_file; /* may be "" */ +extern BIO *bio_in; +extern BIO *bio_out; +extern BIO *bio_err; +extern const unsigned char tls13_aes128gcmsha256_id[]; +extern const unsigned char tls13_aes256gcmsha384_id[]; +extern BIO_ADDR *ourpeer; + +BIO *dup_bio_in(int format); +BIO *dup_bio_out(int format); +BIO *dup_bio_err(int format); +BIO *bio_open_owner(const char *filename, int format, int private); +BIO *bio_open_default(const char *filename, char mode, int format); +BIO *bio_open_default_quiet(const char *filename, char mode, int format); +CONF *app_load_config_bio(BIO *in, const char *filename); +#define app_load_config(filename) app_load_config_internal(filename, 0) +#define app_load_config_quiet(filename) app_load_config_internal(filename, 1) +CONF *app_load_config_internal(const char *filename, int quiet); +CONF *app_load_config_verbose(const char *filename, int verbose); +int app_load_modules(const CONF *config); +CONF *app_load_config_modules(const char *configfile); +void unbuffer(FILE *fp); +void wait_for_async(SSL *s); +# if defined(OPENSSL_SYS_MSDOS) +int has_stdin_waiting(void); +# endif + +void corrupt_signature(const ASN1_STRING *signature); +int set_cert_times(X509 *x, const char *startdate, const char *enddate, + int days); +int set_crl_lastupdate(X509_CRL *crl, const char *lastupdate); +int set_crl_nextupdate(X509_CRL *crl, const char *nextupdate, + long days, long hours, long secs); + +typedef struct args_st { + int size; + int argc; + char **argv; +} ARGS; + +/* We need both wrap and the "real" function because libcrypto uses both. */ +int wrap_password_callback(char *buf, int bufsiz, int verify, void *cb_data); + +int chopup_args(ARGS *arg, char *buf); +void dump_cert_text(BIO *out, X509 *x); +void print_name(BIO *out, const char *title, const X509_NAME *nm); +void print_bignum_var(BIO *, const BIGNUM *, const char*, + int, unsigned char *); +void print_array(BIO *, const char *, int, const unsigned char *); +int set_nameopt(const char *arg); +unsigned long get_nameopt(void); +int set_dateopt(unsigned long *dateopt, const char *arg); +int set_cert_ex(unsigned long *flags, const char *arg); +int set_name_ex(unsigned long *flags, const char *arg); +int set_ext_copy(int *copy_type, const char *arg); +int copy_extensions(X509 *x, X509_REQ *req, int copy_type); +char *get_passwd(const char *pass, const char *desc); +int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2); +int add_oid_section(CONF *conf); +X509_REQ *load_csr(const char *file, int format, const char *desc); +X509 *load_cert_pass(const char *uri, int format, int maybe_stdin, + const char *pass, const char *desc); +#define load_cert(uri, format, desc) load_cert_pass(uri, format, 1, NULL, desc) +X509_CRL *load_crl(const char *uri, int format, int maybe_stdin, + const char *desc); +void cleanse(char *str); +void clear_free(char *str); +EVP_PKEY *load_key(const char *uri, int format, int maybe_stdin, + const char *pass, ENGINE *e, const char *desc); +EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin, + const char *pass, ENGINE *e, const char *desc); +EVP_PKEY *load_keyparams(const char *uri, int format, int maybe_stdin, + const char *keytype, const char *desc); +EVP_PKEY *load_keyparams_suppress(const char *uri, int format, int maybe_stdin, + const char *keytype, const char *desc, + int suppress_decode_errors); +char *next_item(char *opt); /* in list separated by comma and/or space */ +int load_cert_certs(const char *uri, + X509 **pcert, STACK_OF(X509) **pcerts, + int exclude_http, const char *pass, const char *desc, + X509_VERIFY_PARAM *vpm); +STACK_OF(X509) *load_certs_multifile(char *files, const char *pass, + const char *desc, X509_VERIFY_PARAM *vpm); +X509_STORE *load_certstore(char *input, const char *pass, const char *desc, + X509_VERIFY_PARAM *vpm); +int load_certs(const char *uri, int maybe_stdin, STACK_OF(X509) **certs, + const char *pass, const char *desc); +int load_crls(const char *uri, STACK_OF(X509_CRL) **crls, + const char *pass, const char *desc); +int load_key_certs_crls(const char *uri, int format, int maybe_stdin, + const char *pass, const char *desc, + EVP_PKEY **ppkey, EVP_PKEY **ppubkey, + EVP_PKEY **pparams, + X509 **pcert, STACK_OF(X509) **pcerts, + X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls); +int load_key_cert_crl(const char *uri, int format, int maybe_stdin, + const char *pass, const char *desc, + EVP_PKEY **ppkey, EVP_PKEY **ppubkey, + X509 **pcert, X509_CRL **pcrl); +X509_STORE *setup_verify(const char *CAfile, int noCAfile, + const char *CApath, int noCApath, + const char *CAstore, int noCAstore); +__owur int ctx_set_verify_locations(SSL_CTX *ctx, + const char *CAfile, int noCAfile, + const char *CApath, int noCApath, + const char *CAstore, int noCAstore); + +# ifndef OPENSSL_NO_CT + +/* + * Sets the file to load the Certificate Transparency log list from. + * If path is NULL, loads from the default file path. + * Returns 1 on success, 0 otherwise. + */ +__owur int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path); + +# endif + +ENGINE *setup_engine_methods(const char *id, unsigned int methods, int debug); +# define setup_engine(e, debug) setup_engine_methods(e, (unsigned int)-1, debug) +void release_engine(ENGINE *e); +int init_engine(ENGINE *e); +int finish_engine(ENGINE *e); +char *make_engine_uri(ENGINE *e, const char *key_id, const char *desc); + +int get_legacy_pkey_id(OSSL_LIB_CTX *libctx, const char *algname, ENGINE *e); +const EVP_MD *get_digest_from_engine(const char *name); +const EVP_CIPHER *get_cipher_from_engine(const char *name); + +# ifndef OPENSSL_NO_OCSP +OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, const char *host, + const char *port, const char *path, + const char *proxy, const char *no_proxy, + int use_ssl, STACK_OF(CONF_VALUE) *headers, + int req_timeout); +# endif + +/* Functions defined in ca.c and also used in ocsp.c */ +int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, + ASN1_GENERALIZEDTIME **pinvtm, const char *str); + +# define DB_type 0 +# define DB_exp_date 1 +# define DB_rev_date 2 +# define DB_serial 3 /* index - unique */ +# define DB_file 4 +# define DB_name 5 /* index - unique when active and not + * disabled */ +# define DB_NUMBER 6 + +# define DB_TYPE_REV 'R' /* Revoked */ +# define DB_TYPE_EXP 'E' /* Expired */ +# define DB_TYPE_VAL 'V' /* Valid ; inserted with: ca ... -valid */ +# define DB_TYPE_SUSP 'S' /* Suspended */ + +typedef struct db_attr_st { + int unique_subject; +} DB_ATTR; +typedef struct ca_db_st { + DB_ATTR attributes; + TXT_DB *db; + char *dbfname; +# ifndef OPENSSL_NO_POSIX_IO + struct stat dbst; +# endif +} CA_DB; + +void app_bail_out(char *fmt, ...); +void *app_malloc(size_t sz, const char *what); + +/* load_serial, save_serial, and rotate_serial are also used for CRL numbers */ +BIGNUM *load_serial(const char *serialfile, int *exists, int create, + ASN1_INTEGER **retai); +int save_serial(const char *serialfile, const char *suffix, + const BIGNUM *serial, ASN1_INTEGER **retai); +int rotate_serial(const char *serialfile, const char *new_suffix, + const char *old_suffix); +int rand_serial(BIGNUM *b, ASN1_INTEGER *ai); + +CA_DB *load_index(const char *dbfile, DB_ATTR *dbattr); +int index_index(CA_DB *db); +int save_index(const char *dbfile, const char *suffix, CA_DB *db); +int rotate_index(const char *dbfile, const char *new_suffix, + const char *old_suffix); +void free_index(CA_DB *db); +# define index_name_cmp_noconst(a, b) \ + index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \ + (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b)) +int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b); +int parse_yesno(const char *str, int def); + +X509_NAME *parse_name(const char *str, int chtype, int multirdn, + const char *desc); +void policies_print(X509_STORE_CTX *ctx); +int bio_to_mem(unsigned char **out, int maxlen, BIO *in); +int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value); +int x509_ctrl_string(X509 *x, const char *value); +int x509_req_ctrl_string(X509_REQ *x, const char *value); +int init_gen_str(EVP_PKEY_CTX **pctx, + const char *algname, ENGINE *e, int do_param, + OSSL_LIB_CTX *libctx, const char *propq); +int do_X509_sign(X509 *x, EVP_PKEY *pkey, const char *md, + STACK_OF(OPENSSL_STRING) *sigopts, X509V3_CTX *ext_ctx); +int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts); +int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const char *md, + STACK_OF(OPENSSL_STRING) *sigopts); +int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey, + STACK_OF(OPENSSL_STRING) *vfyopts); +int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const char *md, + STACK_OF(OPENSSL_STRING) *sigopts); + +extern char *psk_key; + + +unsigned char *next_protos_parse(size_t *outlen, const char *in); + +void print_cert_checks(BIO *bio, X509 *x, + const char *checkhost, + const char *checkemail, const char *checkip); + +void store_setup_crl_download(X509_STORE *st); + +typedef struct app_http_tls_info_st { + const char *server; + const char *port; + int use_proxy; + long timeout; + SSL_CTX *ssl_ctx; +} APP_HTTP_TLS_INFO; +BIO *app_http_tls_cb(BIO *hbio, /* APP_HTTP_TLS_INFO */ void *arg, + int connect, int detail); +void APP_HTTP_TLS_INFO_free(APP_HTTP_TLS_INFO *info); +# ifndef OPENSSL_NO_SOCK +ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy, + const char *no_proxy, SSL_CTX *ssl_ctx, + const STACK_OF(CONF_VALUE) *headers, + long timeout, const char *expected_content_type, + const ASN1_ITEM *it); +ASN1_VALUE *app_http_post_asn1(const char *host, const char *port, + const char *path, const char *proxy, + const char *no_proxy, SSL_CTX *ctx, + const STACK_OF(CONF_VALUE) *headers, + const char *content_type, + ASN1_VALUE *req, const ASN1_ITEM *req_it, + const char *expected_content_type, + long timeout, const ASN1_ITEM *rsp_it); +# endif + +# define EXT_COPY_NONE 0 +# define EXT_COPY_ADD 1 +# define EXT_COPY_ALL 2 + +# define NETSCAPE_CERT_HDR "certificate" + +# define APP_PASS_LEN 1024 + +/* + * IETF RFC 5280 says serial number must be <= 20 bytes. Use 159 bits + * so that the first bit will never be one, so that the DER encoding + * rules won't force a leading octet. + */ +# define SERIAL_RAND_BITS 159 + +int app_isdir(const char *); +int app_access(const char *, int flag); +int fileno_stdin(void); +int fileno_stdout(void); +int raw_read_stdin(void *, int); +int raw_write_stdout(const void *, int); + +# define TM_START 0 +# define TM_STOP 1 +double app_tminterval(int stop, int usertime); + +void make_uppercase(char *string); + +typedef struct verify_options_st { + int depth; + int quiet; + int error; + int return_error; +} VERIFY_CB_ARGS; + +extern VERIFY_CB_ARGS verify_args; + +OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts, + const OSSL_PARAM *paramdefs); +void app_params_free(OSSL_PARAM *params); +int app_provider_load(OSSL_LIB_CTX *libctx, const char *provider_name); +void app_providers_cleanup(void); + +EVP_PKEY *app_keygen(EVP_PKEY_CTX *ctx, const char *alg, int bits, int verbose); +EVP_PKEY *app_paramgen(EVP_PKEY_CTX *ctx, const char *alg); + +#endif diff --git a/crypto/openssl/apps/include/apps_ui.h b/crypto/openssl/apps/include/apps_ui.h new file mode 100644 index 000000000000..6875b7c372d9 --- /dev/null +++ b/crypto/openssl/apps/include/apps_ui.h @@ -0,0 +1,29 @@ +/* + * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_APPS_UI_H +# define OSSL_APPS_UI_H + + +# define PW_MIN_LENGTH 4 +typedef struct pw_cb_data { + const void *password; + const char *prompt_info; +} PW_CB_DATA; + +int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data); + +int setup_ui_method(void); +void destroy_ui_method(void); +int set_base_ui_method(const UI_METHOD *ui_method); +const UI_METHOD *get_ui_method(void); + +extern BIO *bio_err; + +#endif diff --git a/crypto/openssl/apps/include/cmp_mock_srv.h b/crypto/openssl/apps/include/cmp_mock_srv.h new file mode 100644 index 000000000000..6beba1473590 --- /dev/null +++ b/crypto/openssl/apps/include/cmp_mock_srv.h @@ -0,0 +1,35 @@ +/* + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Siemens AG 2018-2020 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_APPS_CMP_MOCK_SRV_H +# define OSSL_APPS_CMP_MOCK_SRV_H + +# include +# ifndef OPENSSL_NO_CMP + +# include + +OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, + const char *propq); +void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx); + +int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); +int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx, + STACK_OF(X509) *chain); +int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx, + STACK_OF(X509) *caPubs); +int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status, + int fail_info, const char *text); +int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val); +int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count); +int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec); + +# endif /* !defined(OPENSSL_NO_CMP) */ +#endif /* !defined(OSSL_APPS_CMP_MOCK_SRV_H) */ diff --git a/crypto/openssl/apps/include/ec_common.h b/crypto/openssl/apps/include/ec_common.h new file mode 100644 index 000000000000..f5711657a299 --- /dev/null +++ b/crypto/openssl/apps/include/ec_common.h @@ -0,0 +1,23 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_NO_EC +static const char *point_format_options[] = { + "uncompressed", + "compressed", + "hybrid", + NULL +}; + +static const char *asn1_encoding_options[] = { + "named_curve", + "explicit", + NULL +}; +#endif diff --git a/crypto/openssl/apps/include/engine_loader.h b/crypto/openssl/apps/include/engine_loader.h new file mode 100644 index 000000000000..fa80fc96567c --- /dev/null +++ b/crypto/openssl/apps/include/engine_loader.h @@ -0,0 +1,21 @@ +/* + * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#ifndef HEADER_ENGINE_LOADER_H +# define HEADER_ENGINE_LOADER_H + +# include + +/* this is a private URI scheme */ +# define ENGINE_SCHEME "org.openssl.engine" +# define ENGINE_SCHEME_COLON (ENGINE_SCHEME ":") + +int setup_engine_loader(void); +void destroy_engine_loader(void); + +#endif diff --git a/crypto/openssl/apps/include/fmt.h b/crypto/openssl/apps/include/fmt.h new file mode 100644 index 000000000000..98dfed7dc0a2 --- /dev/null +++ b/crypto/openssl/apps/include/fmt.h @@ -0,0 +1,45 @@ +/* + * Copyright 2018-2021 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 + */ + +/* + * Options are shared by apps (see apps.h) and the test system + * (see test/testutil.h'). + * In order to remove the dependency between apps and options, the following + * shared fields have been moved into this file. + */ + +#ifndef OSSL_APPS_FMT_H +#define OSSL_APPS_FMT_H + +/* + * On some platforms, it's important to distinguish between text and binary + * files. On some, there might even be specific file formats for different + * contents. The FORMAT_xxx macros are meant to express an intent with the + * file being read or created. + */ +# define B_FORMAT_TEXT 0x8000 +# define FORMAT_UNDEF 0 +# define FORMAT_TEXT (1 | B_FORMAT_TEXT) /* Generic text */ +# define FORMAT_BINARY 2 /* Generic binary */ +# define FORMAT_BASE64 (3 | B_FORMAT_TEXT) /* Base64 */ +# define FORMAT_ASN1 4 /* ASN.1/DER */ +# define FORMAT_PEM (5 | B_FORMAT_TEXT) +# define FORMAT_PKCS12 6 +# define FORMAT_SMIME (7 | B_FORMAT_TEXT) +# define FORMAT_ENGINE 8 /* Not really a file format */ +# define FORMAT_PEMRSA (9 | B_FORMAT_TEXT) /* PEM RSAPublicKey format */ +# define FORMAT_ASN1RSA 10 /* DER RSAPublicKey format */ +# define FORMAT_MSBLOB 11 /* MS Key blob format */ +# define FORMAT_PVK 12 /* MS PVK file format */ +# define FORMAT_HTTP 13 /* Download using HTTP */ +# define FORMAT_NSS 14 /* NSS keylog format */ + +int FMT_istext(int format); + +#endif /* OSSL_APPS_FMT_H_ */ diff --git a/crypto/openssl/apps/include/function.h b/crypto/openssl/apps/include/function.h new file mode 100644 index 000000000000..14e8dd388670 --- /dev/null +++ b/crypto/openssl/apps/include/function.h @@ -0,0 +1,44 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_APPS_FUNCTION_H +# define OSSL_APPS_FUNCTION_H + +# include +# include "opt.h" + +#define DEPRECATED_NO_ALTERNATIVE "unknown" + +typedef enum FUNC_TYPE { + FT_none, FT_general, FT_md, FT_cipher, FT_pkey, + FT_md_alg, FT_cipher_alg +} FUNC_TYPE; + +typedef struct function_st { + FUNC_TYPE type; + const char *name; + int (*func)(int argc, char *argv[]); + const OPTIONS *help; + const char *deprecated_alternative; + const char *deprecated_version; +} FUNCTION; + +DEFINE_LHASH_OF(FUNCTION); + +/* Structure to hold the number of columns to be displayed and the + * field width used to display them. + */ +typedef struct { + int columns; + int width; +} DISPLAY_COLUMNS; + +void calculate_columns(FUNCTION *functions, DISPLAY_COLUMNS *dc); + +#endif diff --git a/crypto/openssl/apps/include/http_server.h b/crypto/openssl/apps/include/http_server.h new file mode 100644 index 000000000000..8c339660a65e --- /dev/null +++ b/crypto/openssl/apps/include/http_server.h @@ -0,0 +1,125 @@ +/* + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_HTTP_SERVER_H +# define OSSL_HTTP_SERVER_H + +# include "apps.h" + +# ifndef HAVE_FORK +# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) +# define HAVE_FORK 0 +# else +# define HAVE_FORK 1 +# endif +# endif + +# if HAVE_FORK +# undef NO_FORK +# else +# define NO_FORK +# endif + +# if !defined(NO_FORK) && !defined(OPENSSL_NO_SOCK) \ + && !defined(OPENSSL_NO_POSIX_IO) +# define HTTP_DAEMON +# include +# include +# include +# include +# define MAXERRLEN 1000 /* limit error text sent to syslog to 1000 bytes */ +# else +# undef LOG_DEBUG +# undef LOG_INFO +# undef LOG_WARNING +# undef LOG_ERR +# define LOG_DEBUG 7 +# define LOG_INFO 6 +# define LOG_WARNING 4 +# define LOG_ERR 3 +# endif + +/*- + * Log a message to syslog if multi-threaded HTTP_DAEMON, else to bio_err + * prog: the name of the current app + * level: the severity of the message, e.g., LOG_ERR + * fmt: message with potential extra parameters like with printf() + * returns nothing + */ +void log_message(const char *prog, int level, const char *fmt, ...); + +# ifndef OPENSSL_NO_SOCK +/*- + * Initialize an HTTP server by setting up its listening BIO + * prog: the name of the current app + * port: the port to listen on + * returns a BIO for accepting requests, NULL on error + */ +BIO *http_server_init_bio(const char *prog, const char *port); + +/*- + * Accept an ASN.1-formatted HTTP request + * it: the expected request ASN.1 type + * preq: pointer to variable where to place the parsed request + * ppath: pointer to variable where to place the request path, or NULL + * pcbio: pointer to variable where to place the BIO for sending the response to + * acbio: the listening bio (typically as returned by http_server_init_bio()) + * found_keep_alive: for returning flag if client requests persistent connection + * prog: the name of the current app, for diagnostics only + * port: the local port listening to, for diagnostics only + * accept_get: whether to accept GET requests (in addition to POST requests) + * timeout: connection timeout (in seconds), or 0 for none/infinite + * returns 0 in case caller should retry, then *preq == *ppath == *pcbio == NULL + * returns -1 on fatal error; also then holds *preq == *ppath == *pcbio == NULL + * returns 1 otherwise. In this case it is guaranteed that *pcbio != NULL while + * *ppath == NULL and *preq == NULL if and only if the request is invalid, + * On return value 1 the caller is responsible for sending an HTTP response, + * using http_server_send_asn1_resp() or http_server_send_status(). + * The caller must free any non-NULL *preq, *ppath, and *pcbio pointers. + */ +int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, + char **ppath, BIO **pcbio, BIO *acbio, + int *found_keep_alive, + const char *prog, const char *port, + int accept_get, int timeout); + +/*- + * Send an ASN.1-formatted HTTP response + * cbio: destination BIO (typically as returned by http_server_get_asn1_req()) + * note: cbio should not do an encoding that changes the output length + * keep_alive: grant persistent connnection + * content_type: string identifying the type of the response + * it: the response ASN.1 type + * resp: the response to send + * returns 1 on success, 0 on failure + */ +int http_server_send_asn1_resp(BIO *cbio, int keep_alive, + const char *content_type, + const ASN1_ITEM *it, const ASN1_VALUE *resp); + +/*- + * Send a trivial HTTP response, typically to report an error or OK + * cbio: destination BIO (typically as returned by http_server_get_asn1_req()) + * status: the status code to send + * reason: the corresponding human-readable string + * returns 1 on success, 0 on failure + */ +int http_server_send_status(BIO *cbio, int status, const char *reason); + +# endif + +# ifdef HTTP_DAEMON +extern int multi; +extern int acfd; + +void socket_timeout(int signum); +void spawn_loop(const char *prog); +# endif + +#endif diff --git a/crypto/openssl/apps/include/names.h b/crypto/openssl/apps/include/names.h new file mode 100644 index 000000000000..f4d6f6a9a333 --- /dev/null +++ b/crypto/openssl/apps/include/names.h @@ -0,0 +1,17 @@ +/* + * 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 + +/* Standard comparing function for names */ +int name_cmp(const char * const *a, const char * const *b); +/* collect_names is meant to be used with EVP_{type}_doall_names */ +void collect_names(const char *name, void *vdata); +/* Sorts and prints a stack of names to |out| */ +void print_names(BIO *out, STACK_OF(OPENSSL_CSTRING) *names); diff --git a/crypto/openssl/apps/apps.h b/crypto/openssl/apps/include/opt.h similarity index 53% rename from crypto/openssl/apps/apps.h rename to crypto/openssl/apps/include/opt.h index 3e8f50fda87b..4f83a0ed53c9 100644 --- a/crypto/openssl/apps/apps.h +++ b/crypto/openssl/apps/include/opt.h @@ -1,92 +1,20 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#ifndef OSSL_APPS_OPT_H +#define OSSL_APPS_OPT_H -#ifndef OSSL_APPS_H -# define OSSL_APPS_H - -# include "e_os.h" /* struct timeval for DTLS */ -# include "internal/nelem.h" -# include - -# include -# ifndef OPENSSL_NO_POSIX_IO -# include -# include -# endif - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINCE) -# define openssl_fdset(a,b) FD_SET((unsigned int)a, b) -# else -# define openssl_fdset(a,b) FD_SET(a, b) -# endif +#include +#include +#include +#include -/* - * quick macro when you need to pass an unsigned char instead of a char. - * this is true for some implementations of the is*() functions, for - * example. - */ -#define _UC(c) ((unsigned char)(c)) - -void app_RAND_load_conf(CONF *c, const char *section); -void app_RAND_write(void); - -extern char *default_config_file; -extern BIO *bio_in; -extern BIO *bio_out; -extern BIO *bio_err; -extern const unsigned char tls13_aes128gcmsha256_id[]; -extern const unsigned char tls13_aes256gcmsha384_id[]; -extern BIO_ADDR *ourpeer; - -BIO_METHOD *apps_bf_prefix(void); -/* - * The control used to set the prefix with BIO_ctrl() - * We make it high enough so the chance of ever clashing with the BIO library - * remains unlikely for the foreseeable future and beyond. - */ -#define PREFIX_CTRL_SET_PREFIX (1 << 15) -/* - * apps_bf_prefix() returns a dynamically created BIO_METHOD, which we - * need to destroy at some point. When created internally, it's stored - * in an internal pointer which can be freed with the following function - */ -void destroy_prefix_method(void); - -BIO *dup_bio_in(int format); -BIO *dup_bio_out(int format); -BIO *dup_bio_err(int format); -BIO *bio_open_owner(const char *filename, int format, int private); -BIO *bio_open_default(const char *filename, char mode, int format); -BIO *bio_open_default_quiet(const char *filename, char mode, int format); -CONF *app_load_config_bio(BIO *in, const char *filename); -CONF *app_load_config(const char *filename); -CONF *app_load_config_quiet(const char *filename); -int app_load_modules(const CONF *config); -void unbuffer(FILE *fp); -void wait_for_async(SSL *s); -# if defined(OPENSSL_SYS_MSDOS) -int has_stdin_waiting(void); -# endif - -void corrupt_signature(const ASN1_STRING *signature); -int set_cert_times(X509 *x, const char *startdate, const char *enddate, - int days); +#define OPT_COMMON OPT_ERR = -1, OPT_EOF = 0, OPT_HELP /* * Common verification options. @@ -106,6 +34,7 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate, OPT_V__LAST # define OPT_V_OPTIONS \ + OPT_SECTION("Validation"), \ { "policy", OPT_V_POLICY, 's', "adds policy to the acceptable policy set"}, \ { "purpose", OPT_V_PURPOSE, 's', \ "certificate chain purpose"}, \ @@ -198,15 +127,16 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate, OPT_X__LAST # define OPT_X_OPTIONS \ + OPT_SECTION("Extended certificate"), \ { "xkey", OPT_X_KEY, '<', "key for Extended certificates"}, \ { "xcert", OPT_X_CERT, '<', "cert for Extended certificates"}, \ { "xchain", OPT_X_CHAIN, '<', "chain for Extended certificates"}, \ { "xchain_build", OPT_X_CHAIN_BUILD, '-', \ "build certificate chain for the extended certificates"}, \ { "xcertform", OPT_X_CERTFORM, 'F', \ - "format of Extended certificate (PEM or DER) PEM default " }, \ + "format of Extended certificate (PEM/DER/P12); has no effect" }, \ { "xkeyform", OPT_X_KEYFORM, 'F', \ - "format of Extended certificate's key (PEM or DER) PEM default"} + "format of Extended certificate's key (DER/PEM/P12); has no effect"} # define OPT_X_CASES \ OPT_X__FIRST: case OPT_X__LAST: break; \ @@ -225,16 +155,18 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate, OPT_S__FIRST=3000, \ OPT_S_NOSSL3, OPT_S_NOTLS1, OPT_S_NOTLS1_1, OPT_S_NOTLS1_2, \ OPT_S_NOTLS1_3, OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \ - OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_LEGACYCONN, \ + OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_CLIENTRENEG, \ + OPT_S_LEGACYCONN, \ OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_ALLOW_NO_DHE_KEX, \ OPT_S_PRIORITIZE_CHACHA, \ OPT_S_STRICT, OPT_S_SIGALGS, OPT_S_CLIENTSIGALGS, OPT_S_GROUPS, \ OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, OPT_S_CIPHERSUITES, \ OPT_S_RECORD_PADDING, OPT_S_DEBUGBROKE, OPT_S_COMP, \ OPT_S_MINPROTO, OPT_S_MAXPROTO, \ - OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S__LAST + OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S_NO_ETM, OPT_S__LAST # define OPT_S_OPTIONS \ + OPT_SECTION("TLS/SSL"), \ {"no_ssl3", OPT_S_NOSSL3, '-',"Just disable SSLv3" }, \ {"no_tls1", OPT_S_NOTLS1, '-', "Just disable TLSv1"}, \ {"no_tls1_1", OPT_S_NOTLS1_1, '-', "Just disable TLSv1.1" }, \ @@ -248,6 +180,8 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate, {"serverpref", OPT_S_SERVERPREF, '-', "Use server's cipher preferences"}, \ {"legacy_renegotiation", OPT_S_LEGACYRENEG, '-', \ "Enable use of legacy renegotiation (dangerous)"}, \ + {"client_renegotiation", OPT_S_CLIENTRENEG, '-', \ + "Allow client-initiated renegotiation" }, \ {"no_renegotiation", OPT_S_NO_RENEGOTIATION, '-', \ "Disable all renegotiation."}, \ {"legacy_server_connect", OPT_S_LEGACYCONN, '-', \ @@ -282,7 +216,9 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate, {"debug_broken_protocol", OPT_S_DEBUGBROKE, '-', \ "Perform all sorts of protocol violations for testing purposes"}, \ {"no_middlebox", OPT_S_NO_MIDDLEBOX, '-', \ - "Disable TLSv1.3 middlebox compat mode" } + "Disable TLSv1.3 middlebox compat mode" }, \ + {"no_etm", OPT_S_NO_ETM, '-', \ + "Disable Encrypt-then-Mac extension"} # define OPT_S_CASES \ OPT_S__FIRST: case OPT_S__LAST: break; \ @@ -297,6 +233,7 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate, case OPT_S_NOTICKET: \ case OPT_S_SERVERPREF: \ case OPT_S_LEGACYRENEG: \ + case OPT_S_CLIENTRENEG: \ case OPT_S_LEGACYCONN: \ case OPT_S_ONRESUMP: \ case OPT_S_NOLEGACYCONN: \ @@ -315,7 +252,8 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate, case OPT_S_MINPROTO: \ case OPT_S_MAXPROTO: \ case OPT_S_DEBUGBROKE: \ - case OPT_S_NO_MIDDLEBOX + case OPT_S_NO_MIDDLEBOX: \ + case OPT_S_NO_ETM #define IS_NO_PROT_FLAG(o) \ (o == OPT_S_NOSSL3 || o == OPT_S_NOTLS1 || o == OPT_S_NOTLS1_1 \ @@ -328,18 +266,45 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate, OPT_R__FIRST=1500, OPT_R_RAND, OPT_R_WRITERAND, OPT_R__LAST # define OPT_R_OPTIONS \ - {"rand", OPT_R_RAND, 's', "Load the file(s) into the random number generator"}, \ + OPT_SECTION("Random state"), \ + {"rand", OPT_R_RAND, 's', "Load the given file(s) into the random number generator"}, \ {"writerand", OPT_R_WRITERAND, '>', "Write random data to the specified file"} # define OPT_R_CASES \ OPT_R__FIRST: case OPT_R__LAST: break; \ case OPT_R_RAND: case OPT_R_WRITERAND +/* + * Provider options. + */ +# define OPT_PROV_ENUM \ + OPT_PROV__FIRST=1600, \ + OPT_PROV_PROVIDER, OPT_PROV_PROVIDER_PATH, OPT_PROV_PROPQUERY, \ + OPT_PROV__LAST + +# define OPT_CONFIG_OPTION \ + { "config", OPT_CONFIG, '<', "Load a configuration file (this may load modules)" } + +# define OPT_PROV_OPTIONS \ + OPT_SECTION("Provider"), \ + { "provider-path", OPT_PROV_PROVIDER_PATH, 's', "Provider load path (must be before 'provider' argument if required)" }, \ + { "provider", OPT_PROV_PROVIDER, 's', "Provider to load (can be specified multiple times)" }, \ + { "propquery", OPT_PROV_PROPQUERY, 's', "Property query used when fetching algorithms" } + +# define OPT_PROV_CASES \ + OPT_PROV__FIRST: case OPT_PROV__LAST: break; \ + case OPT_PROV_PROVIDER: \ + case OPT_PROV_PROVIDER_PATH: \ + case OPT_PROV_PROPQUERY + /* * Option parsing. */ extern const char OPT_HELP_STR[]; extern const char OPT_MORE_STR[]; +extern const char OPT_SECTION_STR[]; +extern const char OPT_PARAM_STR[]; + typedef struct options_st { const char *name; int retval; @@ -352,6 +317,9 @@ typedef struct options_st { int valtype; const char *helpstr; } OPTIONS; +/* Special retval values: */ +#define OPT_PARAM 0 /* same as OPT_EOF usually defined in apps */ +#define OPT_DUP -2 /* marks duplicate occurrence of option in help output */ /* * A string/int pairing; widely use for option value lookup, hence the @@ -381,255 +349,52 @@ typedef struct string_int_pair_st { OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NSS | \ OPT_FMT_TEXT | OPT_FMT_HTTP | OPT_FMT_PVK) +/* Divide options into sections when displaying usage */ +#define OPT_SECTION(sec) { OPT_SECTION_STR, 1, '-', sec " options:\n" } +#define OPT_PARAMETERS() { OPT_PARAM_STR, 1, '-', "Parameters:\n" } + +const char *opt_path_end(const char *filename); +char *opt_init(int ac, char **av, const OPTIONS * o); char *opt_progname(const char *argv0); +char *opt_appname(const char *argv0); char *opt_getprog(void); -char *opt_init(int ac, char **av, const OPTIONS * o); +void opt_help(const OPTIONS * list); + +void opt_begin(void); int opt_next(void); -int opt_format(const char *s, unsigned long flags, int *result); -int opt_int(const char *arg, int *result); -int opt_ulong(const char *arg, unsigned long *result); -int opt_long(const char *arg, long *result); -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \ - defined(INTMAX_MAX) && defined(UINTMAX_MAX) -int opt_imax(const char *arg, intmax_t *result); -int opt_umax(const char *arg, uintmax_t *result); -#else -# define opt_imax opt_long -# define opt_umax opt_ulong -# define intmax_t long -# define uintmax_t unsigned long -#endif -int opt_pair(const char *arg, const OPT_PAIR * pairs, int *result); -int opt_cipher(const char *name, const EVP_CIPHER **cipherp); -int opt_md(const char *name, const EVP_MD **mdp); -char *opt_arg(void); char *opt_flag(void); +char *opt_arg(void); char *opt_unknown(void); -char **opt_rest(void); -int opt_num_rest(void); -int opt_verify(int i, X509_VERIFY_PARAM *vpm); -int opt_rand(int i); -void opt_help(const OPTIONS * list); -int opt_format_error(const char *s, unsigned long flags); +int opt_cipher(const char *name, EVP_CIPHER **cipherp); +int opt_cipher_any(const char *name, EVP_CIPHER **cipherp); +int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp); +int opt_md(const char *name, EVP_MD **mdp); +int opt_md_silent(const char *name, EVP_MD **mdp); -typedef struct args_st { - int size; - int argc; - char **argv; -} ARGS; - -/* - * VMS C only for now, implemented in vms_decc_init.c - * If other C compilers forget to terminate argv with NULL, this function - * can be re-used. - */ -char **copy_argv(int *argc, char *argv[]); -/* - * Win32-specific argv initialization that splits OS-supplied UNICODE - * command line string to array of UTF8-encoded strings. - */ -void win32_utf8argv(int *argc, char **argv[]); - - -# define PW_MIN_LENGTH 4 -typedef struct pw_cb_data { - const void *password; - const char *prompt_info; -} PW_CB_DATA; - -int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data); - -int setup_ui_method(void); -void destroy_ui_method(void); -const UI_METHOD *get_ui_method(void); - -int chopup_args(ARGS *arg, char *buf); -int dump_cert_text(BIO *out, X509 *x); -void print_name(BIO *out, const char *title, X509_NAME *nm, - unsigned long lflags); -void print_bignum_var(BIO *, const BIGNUM *, const char*, - int, unsigned char *); -void print_array(BIO *, const char *, int, const unsigned char *); -int set_nameopt(const char *arg); -unsigned long get_nameopt(void); -int set_cert_ex(unsigned long *flags, const char *arg); -int set_name_ex(unsigned long *flags, const char *arg); -int set_ext_copy(int *copy_type, const char *arg); -int copy_extensions(X509 *x, X509_REQ *req, int copy_type); -int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2); -int add_oid_section(CONF *conf); -X509 *load_cert(const char *file, int format, const char *cert_descrip); -X509_CRL *load_crl(const char *infile, int format); -EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, - const char *pass, ENGINE *e, const char *key_descrip); -EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, - const char *pass, ENGINE *e, const char *key_descrip); -int load_certs(const char *file, STACK_OF(X509) **certs, int format, - const char *pass, const char *cert_descrip); -int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format, - const char *pass, const char *cert_descrip); -X509_STORE *setup_verify(const char *CAfile, const char *CApath, - int noCAfile, int noCApath); -__owur int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile, - const char *CApath, int noCAfile, - int noCApath); - -#ifndef OPENSSL_NO_CT - -/* - * Sets the file to load the Certificate Transparency log list from. - * If path is NULL, loads from the default file path. - * Returns 1 on success, 0 otherwise. - */ -__owur int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path); - -#endif - -ENGINE *setup_engine(const char *engine, int debug); -void release_engine(ENGINE *e); - -# ifndef OPENSSL_NO_OCSP -OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, - const char *host, const char *path, - const char *port, int use_ssl, - STACK_OF(CONF_VALUE) *headers, - int req_timeout); -# endif - -/* Functions defined in ca.c and also used in ocsp.c */ -int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, - ASN1_GENERALIZEDTIME **pinvtm, const char *str); - -# define DB_type 0 -# define DB_exp_date 1 -# define DB_rev_date 2 -# define DB_serial 3 /* index - unique */ -# define DB_file 4 -# define DB_name 5 /* index - unique when active and not - * disabled */ -# define DB_NUMBER 6 - -# define DB_TYPE_REV 'R' /* Revoked */ -# define DB_TYPE_EXP 'E' /* Expired */ -# define DB_TYPE_VAL 'V' /* Valid ; inserted with: ca ... -valid */ -# define DB_TYPE_SUSP 'S' /* Suspended */ - -typedef struct db_attr_st { - int unique_subject; -} DB_ATTR; -typedef struct ca_db_st { - DB_ATTR attributes; - TXT_DB *db; - char *dbfname; -# ifndef OPENSSL_NO_POSIX_IO - struct stat dbst; -# endif -} CA_DB; - -void* app_malloc(int sz, const char *what); - -/* load_serial, save_serial, and rotate_serial are also used for CRL numbers */ -BIGNUM *load_serial(const char *serialfile, int *exists, int create, - ASN1_INTEGER **retai); -int save_serial(const char *serialfile, const char *suffix, - const BIGNUM *serial, ASN1_INTEGER **retai); -int rotate_serial(const char *serialfile, const char *new_suffix, - const char *old_suffix); -int rand_serial(BIGNUM *b, ASN1_INTEGER *ai); -CA_DB *load_index(const char *dbfile, DB_ATTR *dbattr); -int index_index(CA_DB *db); -int save_index(const char *dbfile, const char *suffix, CA_DB *db); -int rotate_index(const char *dbfile, const char *new_suffix, - const char *old_suffix); -void free_index(CA_DB *db); -# define index_name_cmp_noconst(a, b) \ - index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \ - (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b)) -int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b); -int parse_yesno(const char *str, int def); - -X509_NAME *parse_name(const char *str, long chtype, int multirdn); -void policies_print(X509_STORE_CTX *ctx); -int bio_to_mem(unsigned char **out, int maxlen, BIO *in); -int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value); -int init_gen_str(EVP_PKEY_CTX **pctx, - const char *algname, ENGINE *e, int do_param); -int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md, - STACK_OF(OPENSSL_STRING) *sigopts); -int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, - STACK_OF(OPENSSL_STRING) *sigopts); -int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, - STACK_OF(OPENSSL_STRING) *sigopts); - -extern char *psk_key; - - -unsigned char *next_protos_parse(size_t *outlen, const char *in); - -void print_cert_checks(BIO *bio, X509 *x, - const char *checkhost, - const char *checkemail, const char *checkip); - -void store_setup_crl_download(X509_STORE *st); - -/* See OPT_FMT_xxx, above. */ -/* On some platforms, it's important to distinguish between text and binary - * files. On some, there might even be specific file formats for different - * contents. The FORMAT_xxx macros are meant to express an intent with the - * file being read or created. - */ -# define B_FORMAT_TEXT 0x8000 -# define FORMAT_UNDEF 0 -# define FORMAT_TEXT (1 | B_FORMAT_TEXT) /* Generic text */ -# define FORMAT_BINARY 2 /* Generic binary */ -# define FORMAT_BASE64 (3 | B_FORMAT_TEXT) /* Base64 */ -# define FORMAT_ASN1 4 /* ASN.1/DER */ -# define FORMAT_PEM (5 | B_FORMAT_TEXT) -# define FORMAT_PKCS12 6 -# define FORMAT_SMIME (7 | B_FORMAT_TEXT) -# define FORMAT_ENGINE 8 /* Not really a file format */ -# define FORMAT_PEMRSA (9 | B_FORMAT_TEXT) /* PEM RSAPubicKey format */ -# define FORMAT_ASN1RSA 10 /* DER RSAPubicKey format */ -# define FORMAT_MSBLOB 11 /* MS Key blob format */ -# define FORMAT_PVK 12 /* MS PVK file format */ -# define FORMAT_HTTP 13 /* Download using HTTP */ -# define FORMAT_NSS 14 /* NSS keylog format */ - -# define EXT_COPY_NONE 0 -# define EXT_COPY_ADD 1 -# define EXT_COPY_ALL 2 - -# define NETSCAPE_CERT_HDR "certificate" - -# define APP_PASS_LEN 1024 - -/* - * IETF RFC 5280 says serial number must be <= 20 bytes. Use 159 bits - * so that the first bit will never be one, so that the DER encoding - * rules won't force a leading octet. - */ -# define SERIAL_RAND_BITS 159 +int opt_int(const char *arg, int *result); +int opt_int_arg(void); +int opt_long(const char *arg, long *result); +int opt_ulong(const char *arg, unsigned long *result); +int opt_intmax(const char *arg, ossl_intmax_t *result); +int opt_uintmax(const char *arg, ossl_uintmax_t *result); -int app_isdir(const char *); -int app_access(const char *, int flag); -int fileno_stdin(void); -int fileno_stdout(void); -int raw_read_stdin(void *, int); -int raw_write_stdout(const void *, int); +int opt_isdir(const char *name); +int opt_format(const char *s, unsigned long flags, int *result); +void print_format_error(int format, unsigned long flags); +int opt_printf_stderr(const char *fmt, ...); +int opt_string(const char *name, const char **options); +int opt_pair(const char *arg, const OPT_PAIR * pairs, int *result); -# define TM_START 0 -# define TM_STOP 1 -double app_tminterval(int stop, int usertime); +int opt_verify(int i, X509_VERIFY_PARAM *vpm); +int opt_rand(int i); +int opt_provider(int i); +int opt_provider_option_given(void); -void make_uppercase(char *string); +char **opt_rest(void); +int opt_num_rest(void); -typedef struct verify_options_st { - int depth; - int quiet; - int error; - int return_error; -} VERIFY_CB_ARGS; +/* Returns non-zero if legacy paths are still available */ +int opt_legacy_okay(void); -extern VERIFY_CB_ARGS verify_args; -#endif +#endif /* OSSL_APPS_OPT_H */ diff --git a/crypto/openssl/apps/include/platform.h b/crypto/openssl/apps/include/platform.h new file mode 100644 index 000000000000..491559df3152 --- /dev/null +++ b/crypto/openssl/apps/include/platform.h @@ -0,0 +1,32 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_APPS_PLATFORM_H +# define OSSL_APPS_PLATFORM_H + +# include + +# if defined(OPENSSL_SYS_VMS) && defined(__DECC) +/* + * VMS C only for now, implemented in vms_decc_init.c + * If other C compilers forget to terminate argv with NULL, this function + * can be re-used. + */ +char **copy_argv(int *argc, char *argv[]); +# endif + +# ifdef _WIN32 +/* + * Win32-specific argv initialization that splits OS-supplied UNICODE + * command line string to array of UTF8-encoded strings. + */ +void win32_utf8argv(int *argc, char **argv[]); +# endif + +#endif diff --git a/crypto/openssl/apps/s_apps.h b/crypto/openssl/apps/include/s_apps.h similarity index 65% rename from crypto/openssl/apps/s_apps.h rename to crypto/openssl/apps/include/s_apps.h index f94e659e71e3..d610df40be3f 100644 --- a/crypto/openssl/apps/s_apps.h +++ b/crypto/openssl/apps/include/s_apps.h @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,11 +10,13 @@ #include #include +#include #define PORT "4433" #define PROTOCOL "tcp" typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context); +int report_server_accept(BIO *out, int asock, int with_address, int with_pid); 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); @@ -32,9 +34,10 @@ int init_client(int *sock, const char *host, const char *port, const char *bindhost, const char *bindport, int family, int type, int protocol); int should_retry(int i); +void do_ssl_shutdown(SSL *ssl); -long bio_dump_callback(BIO *bio, int cmd, const char *argp, - int argi, long argl, long ret); +long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len, + int argi, long argl, int ret, size_t *processed); 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, @@ -69,9 +72,37 @@ 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); int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath, - const char *vfyCAfile, const char *chCApath, - const char *chCAfile, STACK_OF(X509_CRL) *crls, + const char *vfyCAfile, const char *vfyCAstore, + const char *chCApath, const char *chCAfile, + const char *chCAstore, STACK_OF(X509_CRL) *crls, int crl_download); 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); + +#ifndef OPENSSL_NO_SRP +/* The client side SRP context that we pass to all SRP related callbacks */ +typedef struct srp_arg_st { + char *srppassin; + char *srplogin; + int msg; /* copy from c_msg */ + int debug; /* copy from c_debug */ + int amp; /* allow more groups */ + int strength; /* minimal size for N */ +} SRP_ARG; + +int set_up_srp_arg(SSL_CTX *ctx, SRP_ARG *srp_arg, int srp_lateuser, int c_msg, + int c_debug); +void set_up_dummy_srp(SSL_CTX *ctx); + +/* The server side SRP context that we pass to all SRP related callbacks */ +typedef struct srpsrvparm_st { + char *login; + SRP_VBASE *vb; + SRP_user_pwd *user; +} srpsrvparm; + +int set_up_srp_verifier_file(SSL_CTX *ctx, srpsrvparm *srp_callback_parm, + char *srpuserseed, char *srp_verifier_file); +void lookup_srp_user(srpsrvparm *srp_callback_parm, BIO *bio_s_out); +#endif /* OPENSSL_NO_SRP */ diff --git a/crypto/openssl/apps/include/vms_term_sock.h b/crypto/openssl/apps/include/vms_term_sock.h new file mode 100644 index 000000000000..eae37b1af931 --- /dev/null +++ b/crypto/openssl/apps/include/vms_term_sock.h @@ -0,0 +1,31 @@ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016 VMS Software, Inc. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_APPS_VMS_TERM_SOCK_H +# define OSSL_APPS_VMS_TERM_SOCK_H + +/* +** Terminal Socket Function Codes +*/ +# define TERM_SOCK_CREATE 1 +# define TERM_SOCK_DELETE 2 + +/* +** Terminal Socket Status Codes +*/ +# define TERM_SOCK_FAILURE 0 +# define TERM_SOCK_SUCCESS 1 + +/* +** Terminal Socket Prototype +*/ +int TerminalSocket (int FunctionCode, int *ReturnSocket); + +#endif diff --git a/crypto/openssl/apps/info.c b/crypto/openssl/apps/info.c new file mode 100644 index 000000000000..c68603652f21 --- /dev/null +++ b/crypto/openssl/apps/info.c @@ -0,0 +1,104 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "apps.h" +#include "progs.h" + +typedef enum OPTION_choice { + OPT_COMMON, + OPT_CONFIGDIR, OPT_ENGINESDIR, OPT_MODULESDIR, OPT_DSOEXT, OPT_DIRNAMESEP, + OPT_LISTSEP, OPT_SEEDS, OPT_CPUSETTINGS +} OPTION_CHOICE; + +const OPTIONS info_options[] = { + + OPT_SECTION("General"), + {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Output"), + {"configdir", OPT_CONFIGDIR, '-', "Default configuration file directory"}, + {"enginesdir", OPT_ENGINESDIR, '-', "Default engine module directory"}, + {"modulesdir", OPT_MODULESDIR, '-', + "Default module directory (other than engine modules)"}, + {"dsoext", OPT_DSOEXT, '-', "Configured extension for modules"}, + {"dirnamesep", OPT_DIRNAMESEP, '-', "Directory-filename separator"}, + {"listsep", OPT_LISTSEP, '-', "List separator character"}, + {"seeds", OPT_SEEDS, '-', "Seed sources"}, + {"cpusettings", OPT_CPUSETTINGS, '-', "CPU settings info"}, + {NULL} +}; + +int info_main(int argc, char **argv) +{ + int ret = 1, dirty = 0, type = 0; + char *prog; + OPTION_CHOICE o; + + prog = opt_init(argc, argv, info_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + default: +opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(info_options); + ret = 0; + goto end; + case OPT_CONFIGDIR: + type = OPENSSL_INFO_CONFIG_DIR; + dirty++; + break; + case OPT_ENGINESDIR: + type = OPENSSL_INFO_ENGINES_DIR; + dirty++; + break; + case OPT_MODULESDIR: + type = OPENSSL_INFO_MODULES_DIR; + dirty++; + break; + case OPT_DSOEXT: + type = OPENSSL_INFO_DSO_EXTENSION; + dirty++; + break; + case OPT_DIRNAMESEP: + type = OPENSSL_INFO_DIR_FILENAME_SEPARATOR; + dirty++; + break; + case OPT_LISTSEP: + type = OPENSSL_INFO_LIST_SEPARATOR; + dirty++; + break; + case OPT_SEEDS: + type = OPENSSL_INFO_SEED_SOURCE; + dirty++; + break; + case OPT_CPUSETTINGS: + type = OPENSSL_INFO_CPU_SETTINGS; + dirty++; + break; + } + } + if (opt_num_rest() != 0) + goto opthelp; + if (dirty > 1) { + BIO_printf(bio_err, "%s: Only one item allowed\n", prog); + goto opthelp; + } + if (dirty == 0) { + BIO_printf(bio_err, "%s: No items chosen\n", prog); + goto opthelp; + } + + BIO_printf(bio_out, "%s\n", OPENSSL_info(type)); + ret = 0; + end: + return ret; +} diff --git a/crypto/openssl/apps/insta.ca.crt b/crypto/openssl/apps/insta.ca.crt new file mode 100644 index 000000000000..6aea6d4f9794 Binary files /dev/null and b/crypto/openssl/apps/insta.ca.crt differ diff --git a/crypto/openssl/apps/kdf.c b/crypto/openssl/apps/kdf.c new file mode 100644 index 000000000000..89ee1f69c766 --- /dev/null +++ b/crypto/openssl/apps/kdf.c @@ -0,0 +1,211 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include + +typedef enum OPTION_choice { + OPT_COMMON, + OPT_KDFOPT, OPT_BIN, OPT_KEYLEN, OPT_OUT, + OPT_CIPHER, OPT_DIGEST, OPT_MAC, + OPT_PROV_ENUM +} OPTION_CHOICE; + +const OPTIONS kdf_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] kdf_name\n"}, + + OPT_SECTION("General"), + {"help", OPT_HELP, '-', "Display this summary"}, + {"kdfopt", OPT_KDFOPT, 's', "KDF algorithm control parameters in n:v form"}, + {"cipher", OPT_CIPHER, 's', "Cipher"}, + {"digest", OPT_DIGEST, 's', "Digest"}, + {"mac", OPT_MAC, 's', "MAC"}, + {OPT_MORE_STR, 1, '-', "See 'Supported Controls' in the EVP_KDF_ docs\n"}, + {"keylen", OPT_KEYLEN, 's', "The size of the output derived key"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, + {"binary", OPT_BIN, '-', + "Output in binary format (default is hexadecimal)"}, + + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"kdf_name", 0, 0, "Name of the KDF algorithm"}, + {NULL} +}; + +static char *alloc_kdf_algorithm_name(STACK_OF(OPENSSL_STRING) **optp, + const char *name, const char *arg) +{ + size_t len = strlen(name) + strlen(arg) + 2; + char *res; + + if (*optp == NULL) + *optp = sk_OPENSSL_STRING_new_null(); + if (*optp == NULL) + return NULL; + + res = app_malloc(len, "algorithm name"); + BIO_snprintf(res, len, "%s:%s", name, arg); + if (sk_OPENSSL_STRING_push(*optp, res)) + return res; + OPENSSL_free(res); + return NULL; +} + +int kdf_main(int argc, char **argv) +{ + int ret = 1, out_bin = 0; + OPTION_CHOICE o; + STACK_OF(OPENSSL_STRING) *opts = NULL; + char *prog, *hexout = NULL; + const char *outfile = NULL; + unsigned char *dkm_bytes = NULL; + size_t dkm_len = 0; + BIO *out = NULL; + EVP_KDF *kdf = NULL; + EVP_KDF_CTX *ctx = NULL; + char *digest = NULL, *cipher = NULL, *mac = NULL; + + prog = opt_init(argc, argv, kdf_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + default: +opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto err; + case OPT_HELP: + opt_help(kdf_options); + ret = 0; + goto err; + case OPT_BIN: + out_bin = 1; + break; + case OPT_KEYLEN: + dkm_len = (size_t)atoi(opt_arg()); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_KDFOPT: + if (opts == NULL) + opts = sk_OPENSSL_STRING_new_null(); + if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg())) + goto opthelp; + break; + case OPT_CIPHER: + OPENSSL_free(cipher); + cipher = alloc_kdf_algorithm_name(&opts, "cipher", opt_arg()); + if (cipher == NULL) + goto opthelp; + break; + case OPT_DIGEST: + OPENSSL_free(digest); + digest = alloc_kdf_algorithm_name(&opts, "digest", opt_arg()); + if (digest == NULL) + goto opthelp; + break; + case OPT_MAC: + OPENSSL_free(mac); + mac = alloc_kdf_algorithm_name(&opts, "mac", opt_arg()); + if (mac == NULL) + goto opthelp; + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto err; + break; + } + } + + /* One argument, the KDF name. */ + argc = opt_num_rest(); + argv = opt_rest(); + if (argc != 1) + goto opthelp; + + if ((kdf = EVP_KDF_fetch(app_get0_libctx(), argv[0], + app_get0_propq())) == NULL) { + BIO_printf(bio_err, "Invalid KDF name %s\n", argv[0]); + goto opthelp; + } + + ctx = EVP_KDF_CTX_new(kdf); + if (ctx == NULL) + goto err; + + if (opts != NULL) { + int ok = 1; + OSSL_PARAM *params = + app_params_new_from_opts(opts, EVP_KDF_settable_ctx_params(kdf)); + + if (params == NULL) + goto err; + + if (!EVP_KDF_CTX_set_params(ctx, params)) { + BIO_printf(bio_err, "KDF parameter error\n"); + ERR_print_errors(bio_err); + ok = 0; + } + app_params_free(params); + if (!ok) + goto err; + } + + out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); + if (out == NULL) + goto err; + + if (dkm_len <= 0) { + BIO_printf(bio_err, "Invalid derived key length.\n"); + goto err; + } + dkm_bytes = app_malloc(dkm_len, "out buffer"); + if (dkm_bytes == NULL) + goto err; + + if (!EVP_KDF_derive(ctx, dkm_bytes, dkm_len, NULL)) { + BIO_printf(bio_err, "EVP_KDF_derive failed\n"); + goto err; + } + + if (out_bin) { + BIO_write(out, dkm_bytes, dkm_len); + } else { + hexout = OPENSSL_buf2hexstr(dkm_bytes, dkm_len); + if (hexout == NULL) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + BIO_printf(out, "%s\n\n", hexout); + } + + ret = 0; +err: + if (ret != 0) + ERR_print_errors(bio_err); + OPENSSL_clear_free(dkm_bytes, dkm_len); + sk_OPENSSL_STRING_free(opts); + EVP_KDF_free(kdf); + EVP_KDF_CTX_free(ctx); + BIO_free(out); + OPENSSL_free(hexout); + OPENSSL_free(cipher); + OPENSSL_free(digest); + OPENSSL_free(mac); + return ret; +} diff --git a/crypto/openssl/apps/lib/app_libctx.c b/crypto/openssl/apps/lib/app_libctx.c new file mode 100644 index 000000000000..4b9ec40e8527 --- /dev/null +++ b/crypto/openssl/apps/lib/app_libctx.c @@ -0,0 +1,48 @@ +/* + * Copyright 1995-2021 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 "app_libctx.h" +#include "apps.h" + +static OSSL_LIB_CTX *app_libctx = NULL; +static const char *app_propq = NULL; + +int app_set_propq(const char *arg) +{ + app_propq = arg; + return 1; +} + +const char *app_get0_propq(void) +{ + return app_propq; +} + +OSSL_LIB_CTX *app_get0_libctx(void) +{ + return app_libctx; +} + +OSSL_LIB_CTX *app_create_libctx(void) +{ + /* + * Load the NULL provider into the default library context and create a + * library context which will then be used for any OPT_PROV options. + */ + if (app_libctx == NULL) { + if (!app_provider_load(NULL, "null")) { + opt_printf_stderr( "Failed to create null provider\n"); + return NULL; + } + app_libctx = OSSL_LIB_CTX_new(); + } + if (app_libctx == NULL) + opt_printf_stderr("Failed to create library context\n"); + return app_libctx; +} + diff --git a/crypto/openssl/apps/lib/app_params.c b/crypto/openssl/apps/lib/app_params.c new file mode 100644 index 000000000000..95e1298ee926 --- /dev/null +++ b/crypto/openssl/apps/lib/app_params.c @@ -0,0 +1,132 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "apps.h" +#include "app_params.h" + +static int describe_param_type(char *buf, size_t bufsz, const OSSL_PARAM *param) +{ + const char *type_mod = ""; + const char *type = NULL; + int show_type_number = 0; + int printed_len; + + switch (param->data_type) { + case OSSL_PARAM_UNSIGNED_INTEGER: + type_mod = "unsigned "; + /* FALLTHRU */ + case OSSL_PARAM_INTEGER: + type = "integer"; + break; + case OSSL_PARAM_UTF8_PTR: + type_mod = "pointer to a "; + /* FALLTHRU */ + case OSSL_PARAM_UTF8_STRING: + type = "UTF8 encoded string"; + break; + case OSSL_PARAM_OCTET_PTR: + type_mod = "pointer to an "; + /* FALLTHRU */ + case OSSL_PARAM_OCTET_STRING: + type = "octet string"; + break; + default: + type = "unknown type"; + show_type_number = 1; + break; + } + + printed_len = BIO_snprintf(buf, bufsz, "%s: ", param->key); + if (printed_len > 0) { + buf += printed_len; + bufsz -= printed_len; + } + printed_len = BIO_snprintf(buf, bufsz, "%s%s", type_mod, type); + if (printed_len > 0) { + buf += printed_len; + bufsz -= printed_len; + } + if (show_type_number) { + printed_len = BIO_snprintf(buf, bufsz, " [%d]", param->data_type); + if (printed_len > 0) { + buf += printed_len; + bufsz -= printed_len; + } + } + if (param->data_size == 0) + printed_len = BIO_snprintf(buf, bufsz, " (arbitrary size)"); + else + printed_len = BIO_snprintf(buf, bufsz, " (max %zu bytes large)", + param->data_size); + if (printed_len > 0) { + buf += printed_len; + bufsz -= printed_len; + } + *buf = '\0'; + return 1; +} + +int print_param_types(const char *thing, const OSSL_PARAM *pdefs, int indent) +{ + if (pdefs == NULL) { + return 1; + } else if (pdefs->key == NULL) { + /* + * An empty list? This shouldn't happen, but let's just make sure to + * say something if there's a badly written provider... + */ + BIO_printf(bio_out, "%*sEmpty list of %s (!!!)\n", indent, "", thing); + } else { + BIO_printf(bio_out, "%*s%s:\n", indent, "", thing); + for (; pdefs->key != NULL; pdefs++) { + char buf[200]; /* This should be ample space */ + + describe_param_type(buf, sizeof(buf), pdefs); + BIO_printf(bio_out, "%*s %s\n", indent, "", buf); + } + } + return 1; +} + +void print_param_value(const OSSL_PARAM *p, int indent) +{ + int64_t i; + uint64_t u; + + printf("%*s%s: ", indent, "", p->key); + switch (p->data_type) { + case OSSL_PARAM_UNSIGNED_INTEGER: + if (OSSL_PARAM_get_uint64(p, &u)) + BIO_printf(bio_out, "%llu\n", (unsigned long long int)u); + else + BIO_printf(bio_out, "error getting value\n"); + break; + case OSSL_PARAM_INTEGER: + if (OSSL_PARAM_get_int64(p, &i)) + BIO_printf(bio_out, "%lld\n", (long long int)i); + else + BIO_printf(bio_out, "error getting value\n"); + break; + case OSSL_PARAM_UTF8_PTR: + BIO_printf(bio_out, "'%s'\n", *(char **)(p->data)); + break; + case OSSL_PARAM_UTF8_STRING: + BIO_printf(bio_out, "'%s'\n", (char *)p->data); + break; + case OSSL_PARAM_OCTET_PTR: + case OSSL_PARAM_OCTET_STRING: + BIO_printf(bio_out, "<%zu bytes>\n", p->data_size); + break; + default: + BIO_printf(bio_out, "unknown type (%u) of %zu bytes\n", + p->data_type, p->data_size); + break; + } +} + diff --git a/crypto/openssl/apps/lib/app_provider.c b/crypto/openssl/apps/lib/app_provider.c new file mode 100644 index 000000000000..63f78ae07d80 --- /dev/null +++ b/crypto/openssl/apps/lib/app_provider.c @@ -0,0 +1,92 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "apps.h" +#include +#include +#include +#include + +/* Non-zero if any of the provider options have been seen */ +static int provider_option_given = 0; + +DEFINE_STACK_OF(OSSL_PROVIDER) + +/* + * See comments in opt_verify for explanation of this. + */ +enum prov_range { OPT_PROV_ENUM }; + +static STACK_OF(OSSL_PROVIDER) *app_providers = NULL; + +static void provider_free(OSSL_PROVIDER *prov) +{ + OSSL_PROVIDER_unload(prov); +} + +int app_provider_load(OSSL_LIB_CTX *libctx, const char *provider_name) +{ + OSSL_PROVIDER *prov; + + prov = OSSL_PROVIDER_load(libctx, provider_name); + if (prov == NULL) { + opt_printf_stderr("%s: unable to load provider %s\n" + "Hint: use -provider-path option or OPENSSL_MODULES environment variable.\n", + opt_getprog(), provider_name); + ERR_print_errors(bio_err); + return 0; + } + if (app_providers == NULL) + app_providers = sk_OSSL_PROVIDER_new_null(); + if (app_providers == NULL + || !sk_OSSL_PROVIDER_push(app_providers, prov)) { + app_providers_cleanup(); + return 0; + } + return 1; +} + +void app_providers_cleanup(void) +{ + sk_OSSL_PROVIDER_pop_free(app_providers, provider_free); + app_providers = NULL; +} + +static int opt_provider_path(const char *path) +{ + if (path != NULL && *path == '\0') + path = NULL; + return OSSL_PROVIDER_set_default_search_path(app_get0_libctx(), path); +} + +int opt_provider(int opt) +{ + const int given = provider_option_given; + + provider_option_given = 1; + switch ((enum prov_range)opt) { + case OPT_PROV__FIRST: + case OPT_PROV__LAST: + return 1; + case OPT_PROV_PROVIDER: + return app_provider_load(app_get0_libctx(), opt_arg()); + case OPT_PROV_PROVIDER_PATH: + return opt_provider_path(opt_arg()); + case OPT_PROV_PROPQUERY: + return app_set_propq(opt_arg()); + } + /* Should never get here but if we do, undo what we did earlier */ + provider_option_given = given; + return 0; +} + +int opt_provider_option_given(void) +{ + return provider_option_given; +} diff --git a/crypto/openssl/apps/app_rand.c b/crypto/openssl/apps/lib/app_rand.c similarity index 64% rename from crypto/openssl/apps/app_rand.c rename to crypto/openssl/apps/lib/app_rand.c index 2b0bbde03423..713792ead40a 100644 --- a/crypto/openssl/apps/app_rand.c +++ b/crypto/openssl/apps/lib/app_rand.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,6 +14,7 @@ #include static char *save_rand_file; +static STACK_OF(OPENSSL_STRING) *randfiles; void app_RAND_load_conf(CONF *c, const char *section) { @@ -27,8 +28,14 @@ void app_RAND_load_conf(CONF *c, const char *section) BIO_printf(bio_err, "Can't load %s into RNG\n", randfile); ERR_print_errors(bio_err); } - if (save_rand_file == NULL) + if (save_rand_file == NULL) { save_rand_file = OPENSSL_strdup(randfile); + /* If some internal memory errors have occurred */ + if (save_rand_file == NULL) { + BIO_printf(bio_err, "Can't duplicate %s\n", randfile); + ERR_print_errors(bio_err); + } + } } static int loadfiles(char *name) @@ -57,16 +64,34 @@ static int loadfiles(char *name) return ret; } -void app_RAND_write(void) +int app_RAND_load(void) { + char *p; + int i, ret = 1; + + for (i = 0; i < sk_OPENSSL_STRING_num(randfiles); i++) { + p = sk_OPENSSL_STRING_value(randfiles, i); + if (!loadfiles(p)) + ret = 0; + } + sk_OPENSSL_STRING_free(randfiles); + return ret; +} + +int app_RAND_write(void) +{ + int ret = 1; + if (save_rand_file == NULL) - return; + return 1; if (RAND_write_file(save_rand_file) == -1) { BIO_printf(bio_err, "Cannot write random bytes:\n"); ERR_print_errors(bio_err); + ret = 0; } OPENSSL_free(save_rand_file); save_rand_file = NULL; + return ret; } @@ -82,11 +107,17 @@ int opt_rand(int opt) case OPT_R__LAST: break; case OPT_R_RAND: - return loadfiles(opt_arg()); + if (randfiles == NULL + && (randfiles = sk_OPENSSL_STRING_new_null()) == NULL) + return 0; + if (!sk_OPENSSL_STRING_push(randfiles, opt_arg())) + return 0; break; case OPT_R_WRITERAND: OPENSSL_free(save_rand_file); save_rand_file = OPENSSL_strdup(opt_arg()); + if (save_rand_file == NULL) + return 0; break; } return 1; diff --git a/crypto/openssl/apps/lib/app_x509.c b/crypto/openssl/apps/lib/app_x509.c new file mode 100644 index 000000000000..f2c22948f201 --- /dev/null +++ b/crypto/openssl/apps/lib/app_x509.c @@ -0,0 +1,137 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "apps.h" + +/* + * X509_ctrl_str() is sorely lacking in libcrypto, but is still needed to + * allow the application to process verification options in a manner similar + * to signature or other options that pass through EVP_PKEY_CTX_ctrl_str(), + * for uniformity. + * + * As soon as more stuff is added, the code will need serious rework. For + * the moment, it only handles the FIPS 196 / SM2 distinguishing ID. + */ +#ifdef EVP_PKEY_CTRL_SET1_ID +static ASN1_OCTET_STRING *mk_octet_string(void *value, size_t value_n) +{ + ASN1_OCTET_STRING *v = ASN1_OCTET_STRING_new(); + + if (v == NULL) { + BIO_printf(bio_err, "error: allocation failed\n"); + } else if (!ASN1_OCTET_STRING_set(v, value, (int)value_n)) { + ASN1_OCTET_STRING_free(v); + v = NULL; + } + return v; +} +#endif + +static int x509_ctrl(void *object, int cmd, void *value, size_t value_n) +{ + switch (cmd) { +#ifdef EVP_PKEY_CTRL_SET1_ID + case EVP_PKEY_CTRL_SET1_ID: + { + ASN1_OCTET_STRING *v = mk_octet_string(value, value_n); + + if (v == NULL) { + BIO_printf(bio_err, + "error: setting distinguishing ID in certificate failed\n"); + return 0; + } + + X509_set0_distinguishing_id(object, v); + return 1; + } +#endif + default: + break; + } + return -2; /* typical EVP_PKEY return for "unsupported" */ +} + +static int x509_req_ctrl(void *object, int cmd, void *value, size_t value_n) +{ + switch (cmd) { +#ifdef EVP_PKEY_CTRL_SET1_ID + case EVP_PKEY_CTRL_SET1_ID: + { + ASN1_OCTET_STRING *v = mk_octet_string(value, value_n); + + if (v == NULL) { + BIO_printf(bio_err, + "error: setting distinguishing ID in certificate signing request failed\n"); + return 0; + } + + X509_REQ_set0_distinguishing_id(object, v); + return 1; + } +#endif + default: + break; + } + return -2; /* typical EVP_PKEY return for "unsupported" */ +} + +static int do_x509_ctrl_string(int (*ctrl)(void *object, int cmd, + void *value, size_t value_n), + void *object, const char *value) +{ + int rv = 0; + char *stmp, *vtmp = NULL; + size_t vtmp_len = 0; + int cmd = 0; /* Will get command values that make sense somehow */ + + stmp = OPENSSL_strdup(value); + if (stmp == NULL) + return -1; + vtmp = strchr(stmp, ':'); + if (vtmp != NULL) { + *vtmp = 0; + vtmp++; + vtmp_len = strlen(vtmp); + } + + if (strcmp(stmp, "distid") == 0) { +#ifdef EVP_PKEY_CTRL_SET1_ID + cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */ +#endif + } else if (strcmp(stmp, "hexdistid") == 0) { + if (vtmp != NULL) { + void *hexid; + long hexid_len = 0; + + hexid = OPENSSL_hexstr2buf((const char *)vtmp, &hexid_len); + OPENSSL_free(stmp); + stmp = vtmp = hexid; + vtmp_len = (size_t)hexid_len; + } +#ifdef EVP_PKEY_CTRL_SET1_ID + cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */ +#endif + } + + rv = ctrl(object, cmd, vtmp, vtmp_len); + + OPENSSL_free(stmp); + return rv; +} + +int x509_ctrl_string(X509 *x, const char *value) +{ + return do_x509_ctrl_string(x509_ctrl, x, value); +} + +int x509_req_ctrl_string(X509_REQ *x, const char *value) +{ + return do_x509_ctrl_string(x509_req_ctrl, x, value); +} diff --git a/crypto/openssl/apps/apps.c b/crypto/openssl/apps/lib/apps.c similarity index 51% rename from crypto/openssl/apps/apps.c rename to crypto/openssl/apps/lib/apps.c index f2447fb0bef8..0d7a20b52afc 100644 --- a/crypto/openssl/apps/apps.c +++ b/crypto/openssl/apps/lib/apps.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,6 +15,12 @@ # define _POSIX_C_SOURCE 2 #endif +#ifndef OPENSSL_NO_ENGINE +/* We need to use some deprecated APIs */ +# define OPENSSL_SUPPRESS_DEPRECATED +# include +#endif + #include #include #include @@ -28,18 +34,19 @@ #include #include #include +#include #include +#include #include #include #include -#ifndef OPENSSL_NO_ENGINE -# include -#endif -#ifndef OPENSSL_NO_RSA -# include -#endif +#include +#include #include #include +#include +#include +#include "s_apps.h" #include "apps.h" #ifdef _WIN32 @@ -51,23 +58,35 @@ static int WIN32_rename(const char *from, const char *to); # include #endif -#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32) +#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32) || defined(__BORLANDC__) # define _kbhit kbhit #endif +static BIO *bio_open_default_(const char *filename, char mode, int format, + int quiet); + +#define PASS_SOURCE_SIZE_MAX 4 + +DEFINE_STACK_OF(CONF) + typedef struct { const char *name; unsigned long flag; unsigned long mask; } NAME_EX_TBL; -static UI_METHOD *ui_method = NULL; -static const UI_METHOD *ui_fallback_method = NULL; - static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL * in_tbl); static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL * in_tbl); +static +int load_key_certs_crls_suppress(const char *uri, int format, int maybe_stdin, + const char *pass, const char *desc, + EVP_PKEY **ppkey, EVP_PKEY **ppubkey, + EVP_PKEY **pparams, + X509 **pcert, STACK_OF(X509) **pcerts, + X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls, + int suppress_decode_errors); int app_init(long mesgwin); @@ -86,7 +105,7 @@ int chopup_args(ARGS *arg, char *buf) /* Skip whitespace. */ while (*p && isspace(_UC(*p))) p++; - if (!*p) + if (*p == '\0') break; /* The start of something good :-) */ @@ -126,18 +145,29 @@ int app_init(long mesgwin) } #endif -int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile, - const char *CApath, int noCAfile, int noCApath) +int ctx_set_verify_locations(SSL_CTX *ctx, + const char *CAfile, int noCAfile, + const char *CApath, int noCApath, + const char *CAstore, int noCAstore) { - if (CAfile == NULL && CApath == NULL) { + if (CAfile == NULL && CApath == NULL && CAstore == NULL) { if (!noCAfile && SSL_CTX_set_default_verify_file(ctx) <= 0) return 0; if (!noCApath && SSL_CTX_set_default_verify_dir(ctx) <= 0) return 0; + if (!noCAstore && SSL_CTX_set_default_verify_store(ctx) <= 0) + return 0; return 1; } - return SSL_CTX_load_verify_locations(ctx, CAfile, CApath); + + if (CAfile != NULL && !SSL_CTX_load_verify_file(ctx, CAfile)) + return 0; + if (CApath != NULL && !SSL_CTX_load_verify_dir(ctx, CApath)) + return 0; + if (CAstore != NULL && !SSL_CTX_load_verify_store(ctx, CAstore)) + return 0; + return 1; } #ifndef OPENSSL_NO_CT @@ -170,201 +200,42 @@ unsigned long get_nameopt(void) return (nmflag_set) ? nmflag : XN_FLAG_ONELINE; } -int dump_cert_text(BIO *out, X509 *x) -{ - print_name(out, "subject=", X509_get_subject_name(x), get_nameopt()); - BIO_puts(out, "\n"); - print_name(out, "issuer=", X509_get_issuer_name(x), get_nameopt()); - BIO_puts(out, "\n"); - - return 0; -} - -static int ui_open(UI *ui) +void dump_cert_text(BIO *out, X509 *x) { - int (*opener)(UI *ui) = UI_method_get_opener(ui_fallback_method); - - if (opener) - return opener(ui); - return 1; + print_name(out, "subject=", X509_get_subject_name(x)); + print_name(out, "issuer=", X509_get_issuer_name(x)); } -static int ui_read(UI *ui, UI_STRING *uis) +int wrap_password_callback(char *buf, int bufsiz, int verify, void *userdata) { - int (*reader)(UI *ui, UI_STRING *uis) = NULL; - - if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD - && UI_get0_user_data(ui)) { - switch (UI_get_string_type(uis)) { - case UIT_PROMPT: - case UIT_VERIFY: - { - const char *password = - ((PW_CB_DATA *)UI_get0_user_data(ui))->password; - if (password && password[0] != '\0') { - UI_set_result(ui, uis, password); - return 1; - } - } - break; - case UIT_NONE: - case UIT_BOOLEAN: - case UIT_INFO: - case UIT_ERROR: - break; - } - } - - reader = UI_method_get_reader(ui_fallback_method); - if (reader) - return reader(ui, uis); - return 1; + return password_callback(buf, bufsiz, verify, (PW_CB_DATA *)userdata); } -static int ui_write(UI *ui, UI_STRING *uis) -{ - int (*writer)(UI *ui, UI_STRING *uis) = NULL; - if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD - && UI_get0_user_data(ui)) { - switch (UI_get_string_type(uis)) { - case UIT_PROMPT: - case UIT_VERIFY: - { - const char *password = - ((PW_CB_DATA *)UI_get0_user_data(ui))->password; - if (password && password[0] != '\0') - return 1; - } - break; - case UIT_NONE: - case UIT_BOOLEAN: - case UIT_INFO: - case UIT_ERROR: - break; - } - } - - writer = UI_method_get_writer(ui_fallback_method); - if (writer) - return writer(ui, uis); - return 1; -} - -static int ui_close(UI *ui) -{ - int (*closer)(UI *ui) = UI_method_get_closer(ui_fallback_method); - - if (closer) - return closer(ui); - return 1; -} - -int setup_ui_method(void) -{ - ui_fallback_method = UI_null(); -#ifndef OPENSSL_NO_UI_CONSOLE - ui_fallback_method = UI_OpenSSL(); -#endif - ui_method = UI_create_method("OpenSSL application user interface"); - UI_method_set_opener(ui_method, ui_open); - UI_method_set_reader(ui_method, ui_read); - UI_method_set_writer(ui_method, ui_write); - UI_method_set_closer(ui_method, ui_close); - return 0; -} - -void destroy_ui_method(void) -{ - if (ui_method) { - UI_destroy_method(ui_method); - ui_method = NULL; - } -} - -const UI_METHOD *get_ui_method(void) -{ - return ui_method; -} +static char *app_get_pass(const char *arg, int keepbio); -int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp) +char *get_passwd(const char *pass, const char *desc) { - int res = 0; - UI *ui = NULL; - PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp; - - ui = UI_new_method(ui_method); - if (ui) { - int ok = 0; - char *buff = NULL; - int ui_flags = 0; - const char *prompt_info = NULL; - char *prompt; - int pw_min_len = PW_MIN_LENGTH; - - if (cb_data != NULL && cb_data->prompt_info != NULL) - prompt_info = cb_data->prompt_info; - if (cb_data != NULL && cb_data->password != NULL - && *(const char*)cb_data->password != '\0') - pw_min_len = 1; - else if (!verify) - pw_min_len = 0; - prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); - if (!prompt) { - BIO_printf(bio_err, "Out of memory\n"); - UI_free(ui); - return 0; - } - - ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; - UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); - - /* We know that there is no previous user data to return to us */ - (void)UI_add_user_data(ui, cb_data); + char *result = NULL; - ok = UI_add_input_string(ui, prompt, ui_flags, buf, - pw_min_len, bufsiz - 1); - - if (ok >= 0 && verify) { - buff = app_malloc(bufsiz, "password buffer"); - ok = UI_add_verify_string(ui, prompt, ui_flags, buff, - pw_min_len, bufsiz - 1, buf); - } - if (ok >= 0) - do { - ok = UI_process(ui); - } while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); - - OPENSSL_clear_free(buff, (unsigned int)bufsiz); - - if (ok >= 0) - res = strlen(buf); - if (ok == -1) { - BIO_printf(bio_err, "User interface error\n"); - ERR_print_errors(bio_err); - OPENSSL_cleanse(buf, (unsigned int)bufsiz); - res = 0; - } - if (ok == -2) { - BIO_printf(bio_err, "aborted!\n"); - OPENSSL_cleanse(buf, (unsigned int)bufsiz); - res = 0; - } - UI_free(ui); - OPENSSL_free(prompt); + if (desc == NULL) + desc = ""; + if (!app_passwd(pass, NULL, &result, NULL)) + BIO_printf(bio_err, "Error getting password for %s\n", desc); + if (pass != NULL && result == NULL) { + BIO_printf(bio_err, + "Trying plain input string (better precede with 'pass:')\n"); + result = OPENSSL_strdup(pass); + if (result == NULL) + BIO_printf(bio_err, "Out of memory getting password for %s\n", desc); } - return res; + return result; } -static char *app_get_pass(const char *arg, int keepbio); - int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2) { - int same; - if (arg2 == NULL || arg1 == NULL || strcmp(arg1, arg2)) - same = 0; - else - same = 1; + int same = arg1 != NULL && arg2 != NULL && strcmp(arg1, arg2) == 0; + if (arg1 != NULL) { *pass1 = app_get_pass(arg1, same); if (*pass1 == NULL) @@ -384,16 +255,17 @@ int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2) static char *app_get_pass(const char *arg, int keepbio) { - char *tmp, tpass[APP_PASS_LEN]; static BIO *pwdbio = NULL; + char *tmp, tpass[APP_PASS_LEN]; int i; + /* PASS_SOURCE_SIZE_MAX = max number of chars before ':' in below strings */ if (strncmp(arg, "pass:", 5) == 0) return OPENSSL_strdup(arg + 5); if (strncmp(arg, "env:", 4) == 0) { tmp = getenv(arg + 4); if (tmp == NULL) { - BIO_printf(bio_err, "Can't read environment variable %s\n", arg + 4); + BIO_printf(bio_err, "No environment variable %s\n", arg + 4); return NULL; } return OPENSSL_strdup(tmp); @@ -419,7 +291,7 @@ static char *app_get_pass(const char *arg, int keepbio) i = atoi(arg + 3); if (i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE); - if ((i < 0) || !pwdbio) { + if ((i < 0) || pwdbio == NULL) { BIO_printf(bio_err, "Can't access file descriptor %s\n", arg + 3); return NULL; } @@ -427,16 +299,32 @@ static char *app_get_pass(const char *arg, int keepbio) * Can't do BIO_gets on an fd BIO so add a buffering BIO */ btmp = BIO_new(BIO_f_buffer()); + if (btmp == NULL) { + BIO_free_all(pwdbio); + pwdbio = NULL; + BIO_printf(bio_err, "Out of memory\n"); + return NULL; + } pwdbio = BIO_push(btmp, pwdbio); #endif } else if (strcmp(arg, "stdin") == 0) { + unbuffer(stdin); pwdbio = dup_bio_in(FORMAT_TEXT); - if (!pwdbio) { + if (pwdbio == NULL) { BIO_printf(bio_err, "Can't open BIO for stdin\n"); return NULL; } } else { - BIO_printf(bio_err, "Invalid password argument \"%s\"\n", arg); + /* argument syntax error; do not reveal too much about arg */ + tmp = strchr(arg, ':'); + if (tmp == NULL || tmp - arg > PASS_SOURCE_SIZE_MAX) + BIO_printf(bio_err, + "Invalid password argument, missing ':' within the first %d chars\n", + PASS_SOURCE_SIZE_MAX + 1); + else + BIO_printf(bio_err, + "Invalid password argument, starting with \"%.*s\"\n", + (int)(tmp - arg + 1), arg); return NULL; } } @@ -461,7 +349,7 @@ CONF *app_load_config_bio(BIO *in, const char *filename) CONF *conf; int i; - conf = NCONF_new(NULL); + conf = NCONF_new_ex(app_get0_libctx(), NULL); i = NCONF_load_bio(conf, in, &errorline); if (i > 0) return conf; @@ -481,31 +369,31 @@ CONF *app_load_config_bio(BIO *in, const char *filename) return NULL; } -CONF *app_load_config(const char *filename) +CONF *app_load_config_verbose(const char *filename, int verbose) { - BIO *in; - CONF *conf; - - in = bio_open_default(filename, 'r', FORMAT_TEXT); - if (in == NULL) - return NULL; - - conf = app_load_config_bio(in, filename); - BIO_free(in); - return conf; + if (verbose) { + if (*filename == '\0') + BIO_printf(bio_err, "No configuration used\n"); + else + BIO_printf(bio_err, "Using configuration from %s\n", filename); + } + return app_load_config_internal(filename, 0); } -CONF *app_load_config_quiet(const char *filename) +CONF *app_load_config_internal(const char *filename, int quiet) { BIO *in; CONF *conf; - in = bio_open_default_quiet(filename, 'r', FORMAT_TEXT); - if (in == NULL) - return NULL; - - conf = app_load_config_bio(in, filename); - BIO_free(in); + if (filename == NULL || *filename != '\0') { + if ((in = bio_open_default_(filename, 'r', FORMAT_TEXT, quiet)) == NULL) + return NULL; + conf = app_load_config_bio(in, filename); + BIO_free(in); + } else { + /* Return empty config if filename is empty string. */ + conf = NCONF_new_ex(app_get0_libctx(), NULL); + } return conf; } @@ -554,439 +442,663 @@ int add_oid_section(CONF *conf) return 1; } -static int load_pkcs12(BIO *in, const char *desc, - pem_password_cb *pem_cb, void *cb_data, - EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) +CONF *app_load_config_modules(const char *configfile) { - const char *pass; - char tpass[PEM_BUFSIZE]; - int len, ret = 0; - PKCS12 *p12; - p12 = d2i_PKCS12_bio(in, NULL); - if (p12 == NULL) { - BIO_printf(bio_err, "Error loading PKCS12 file for %s\n", desc); - goto die; - } - /* See if an empty password will do */ - if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) { - pass = ""; - } else { - if (!pem_cb) - pem_cb = (pem_password_cb *)password_callback; - len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data); - if (len < 0) { - BIO_printf(bio_err, "Passphrase callback error for %s\n", desc); - goto die; - } - if (len < PEM_BUFSIZE) - tpass[len] = 0; - if (!PKCS12_verify_mac(p12, tpass, len)) { - BIO_printf(bio_err, - "Mac verify error (wrong password?) in PKCS12 file for %s\n", - desc); - goto die; + CONF *conf = NULL; + + if (configfile != NULL) { + if ((conf = app_load_config_verbose(configfile, 1)) == NULL) + return NULL; + if (configfile != default_config_file && !app_load_modules(conf)) { + NCONF_free(conf); + conf = NULL; } - pass = tpass; } - ret = PKCS12_parse(p12, pass, pkey, cert, ca); - die: - PKCS12_free(p12); - return ret; + return conf; } -#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK) -static int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl) +#define IS_HTTP(uri) ((uri) != NULL \ + && strncmp(uri, OSSL_HTTP_PREFIX, strlen(OSSL_HTTP_PREFIX)) == 0) +#define IS_HTTPS(uri) ((uri) != NULL \ + && strncmp(uri, OSSL_HTTPS_PREFIX, strlen(OSSL_HTTPS_PREFIX)) == 0) + +X509 *load_cert_pass(const char *uri, int format, int maybe_stdin, + const char *pass, const char *desc) { - char *host = NULL, *port = NULL, *path = NULL; - BIO *bio = NULL; - OCSP_REQ_CTX *rctx = NULL; - int use_ssl, rv = 0; - if (!OCSP_parse_url(url, &host, &port, &path, &use_ssl)) - goto err; - if (use_ssl) { - BIO_puts(bio_err, "https not supported\n"); - goto err; - } - bio = BIO_new_connect(host); - if (!bio || !BIO_set_conn_port(bio, port)) - goto err; - rctx = OCSP_REQ_CTX_new(bio, 1024); - if (rctx == NULL) - goto err; - if (!OCSP_REQ_CTX_http(rctx, "GET", path)) - goto err; - if (!OCSP_REQ_CTX_add1_header(rctx, "Host", host)) - goto err; - if (pcert) { - do { - rv = X509_http_nbio(rctx, pcert); - } while (rv == -1); - } else { - do { - rv = X509_CRL_http_nbio(rctx, pcrl); - } while (rv == -1); - } + X509 *cert = NULL; - err: - OPENSSL_free(host); - OPENSSL_free(path); - OPENSSL_free(port); - BIO_free_all(bio); - OCSP_REQ_CTX_free(rctx); - if (rv != 1) { - BIO_printf(bio_err, "Error loading %s from %s\n", - pcert ? "certificate" : "CRL", url); + if (desc == NULL) + desc = "certificate"; + if (IS_HTTPS(uri)) + BIO_printf(bio_err, "Loading %s over HTTPS is unsupported\n", desc); + else if (IS_HTTP(uri)) + cert = X509_load_http(uri, NULL, NULL, 0 /* timeout */); + else + (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, + NULL, NULL, NULL, &cert, NULL, NULL, NULL); + if (cert == NULL) { + BIO_printf(bio_err, "Unable to load %s\n", desc); ERR_print_errors(bio_err); } - return rv; + return cert; } -#endif -X509 *load_cert(const char *file, int format, const char *cert_descrip) +X509_CRL *load_crl(const char *uri, int format, int maybe_stdin, + const char *desc) { - X509 *x = NULL; - BIO *cert; + X509_CRL *crl = NULL; - if (format == FORMAT_HTTP) { -#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK) - load_cert_crl_http(file, &x, NULL); -#endif - return x; + if (desc == NULL) + desc = "CRL"; + if (IS_HTTPS(uri)) + BIO_printf(bio_err, "Loading %s over HTTPS is unsupported\n", desc); + else if (IS_HTTP(uri)) + crl = X509_CRL_load_http(uri, NULL, NULL, 0 /* timeout */); + else + (void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc, + NULL, NULL, NULL, NULL, NULL, &crl, NULL); + if (crl == NULL) { + BIO_printf(bio_err, "Unable to load %s\n", desc); + ERR_print_errors(bio_err); } + return crl; +} - if (file == NULL) { - unbuffer(stdin); - cert = dup_bio_in(format); - } else { - cert = bio_open_default(file, 'r', format); - } - if (cert == NULL) - goto end; +X509_REQ *load_csr(const char *file, int format, const char *desc) +{ + X509_REQ *req = NULL; + BIO *in; - if (format == FORMAT_ASN1) { - x = d2i_X509_bio(cert, NULL); - } else if (format == FORMAT_PEM) { - x = PEM_read_bio_X509_AUX(cert, NULL, - (pem_password_cb *)password_callback, NULL); - } else if (format == FORMAT_PKCS12) { - if (!load_pkcs12(cert, cert_descrip, NULL, NULL, NULL, &x, NULL)) - goto end; - } else { - BIO_printf(bio_err, "bad input format specified for %s\n", cert_descrip); + if (format == FORMAT_UNDEF) + format = FORMAT_PEM; + if (desc == NULL) + desc = "CSR"; + in = bio_open_default(file, 'r', format); + if (in == NULL) goto end; - } + + if (format == FORMAT_ASN1) + req = d2i_X509_REQ_bio(in, NULL); + else if (format == FORMAT_PEM) + req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); + else + print_format_error(format, OPT_FMT_PEMDER); + end: - if (x == NULL) { - BIO_printf(bio_err, "unable to load certificate\n"); + if (req == NULL) { + BIO_printf(bio_err, "Unable to load %s\n", desc); ERR_print_errors(bio_err); } - BIO_free(cert); - return x; + BIO_free(in); + return req; } -X509_CRL *load_crl(const char *infile, int format) +void cleanse(char *str) { - X509_CRL *x = NULL; - BIO *in = NULL; + if (str != NULL) + OPENSSL_cleanse(str, strlen(str)); +} - if (format == FORMAT_HTTP) { -#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK) - load_cert_crl_http(infile, NULL, &x); -#endif - return x; - } +void clear_free(char *str) +{ + if (str != NULL) + OPENSSL_clear_free(str, strlen(str)); +} - in = bio_open_default(infile, 'r', format); - if (in == NULL) - goto end; - if (format == FORMAT_ASN1) { - x = d2i_X509_CRL_bio(in, NULL); - } else if (format == FORMAT_PEM) { - x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); - } else { - BIO_printf(bio_err, "bad input format specified for input crl\n"); - goto end; - } - if (x == NULL) { - BIO_printf(bio_err, "unable to load CRL\n"); - ERR_print_errors(bio_err); - goto end; +EVP_PKEY *load_key(const char *uri, int format, int may_stdin, + const char *pass, ENGINE *e, const char *desc) +{ + EVP_PKEY *pkey = NULL; + char *allocated_uri = NULL; + + if (desc == NULL) + desc = "private key"; + + if (format == FORMAT_ENGINE) { + uri = allocated_uri = make_engine_uri(e, uri, desc); } + (void)load_key_certs_crls(uri, format, may_stdin, pass, desc, + &pkey, NULL, NULL, NULL, NULL, NULL, NULL); - end: - BIO_free(in); - return x; + OPENSSL_free(allocated_uri); + return pkey; } -EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, - const char *pass, ENGINE *e, const char *key_descrip) +EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin, + const char *pass, ENGINE *e, const char *desc) { - BIO *key = NULL; EVP_PKEY *pkey = NULL; - PW_CB_DATA cb_data; + char *allocated_uri = NULL; - cb_data.password = pass; - cb_data.prompt_info = file; + if (desc == NULL) + desc = "public key"; - if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) { - BIO_printf(bio_err, "no keyfile specified\n"); - goto end; - } if (format == FORMAT_ENGINE) { - if (e == NULL) { - BIO_printf(bio_err, "no engine specified\n"); - } else { -#ifndef OPENSSL_NO_ENGINE - if (ENGINE_init(e)) { - pkey = ENGINE_load_private_key(e, file, ui_method, &cb_data); - ENGINE_finish(e); - } - if (pkey == NULL) { - BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip); - ERR_print_errors(bio_err); - } -#else - BIO_printf(bio_err, "engines not supported\n"); -#endif + uri = allocated_uri = make_engine_uri(e, uri, desc); + } + (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, + NULL, &pkey, NULL, NULL, NULL, NULL, NULL); + + OPENSSL_free(allocated_uri); + return pkey; +} + +EVP_PKEY *load_keyparams_suppress(const char *uri, int format, int maybe_stdin, + const char *keytype, const char *desc, + int suppress_decode_errors) +{ + EVP_PKEY *params = NULL; + + if (desc == NULL) + desc = "key parameters"; + + (void)load_key_certs_crls_suppress(uri, format, maybe_stdin, NULL, desc, + NULL, NULL, ¶ms, NULL, NULL, NULL, + NULL, suppress_decode_errors); + if (params != NULL && keytype != NULL && !EVP_PKEY_is_a(params, keytype)) { + if (!suppress_decode_errors) { + BIO_printf(bio_err, + "Unable to load %s from %s (unexpected parameters type)\n", + desc, uri); + ERR_print_errors(bio_err); } - goto end; + EVP_PKEY_free(params); + params = NULL; } - if (file == NULL && maybe_stdin) { - unbuffer(stdin); - key = dup_bio_in(format); - } else { - key = bio_open_default(file, 'r', format); + return params; +} + +EVP_PKEY *load_keyparams(const char *uri, int format, int maybe_stdin, + const char *keytype, const char *desc) +{ + return load_keyparams_suppress(uri, format, maybe_stdin, keytype, desc, 0); +} + +void app_bail_out(char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + BIO_vprintf(bio_err, fmt, args); + va_end(args); + ERR_print_errors(bio_err); + exit(EXIT_FAILURE); +} + +void *app_malloc(size_t sz, const char *what) +{ + void *vp = OPENSSL_malloc(sz); + + if (vp == NULL) + app_bail_out("%s: Could not allocate %zu bytes for %s\n", + opt_getprog(), sz, what); + return vp; +} + +char *next_item(char *opt) /* in list separated by comma and/or space */ +{ + /* advance to separator (comma or whitespace), if any */ + while (*opt != ',' && !isspace(*opt) && *opt != '\0') + opt++; + if (*opt != '\0') { + /* terminate current item */ + *opt++ = '\0'; + /* skip over any whitespace after separator */ + while (isspace(*opt)) + opt++; } - if (key == NULL) - goto end; - if (format == FORMAT_ASN1) { - pkey = d2i_PrivateKey_bio(key, NULL); - } else if (format == FORMAT_PEM) { - pkey = PEM_read_bio_PrivateKey(key, NULL, - (pem_password_cb *)password_callback, - &cb_data); - } else if (format == FORMAT_PKCS12) { - if (!load_pkcs12(key, key_descrip, - (pem_password_cb *)password_callback, &cb_data, - &pkey, NULL, NULL)) - goto end; -#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4) - } else if (format == FORMAT_MSBLOB) { - pkey = b2i_PrivateKey_bio(key); - } else if (format == FORMAT_PVK) { - pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback, - &cb_data); -#endif + return *opt == '\0' ? NULL : opt; /* NULL indicates end of input */ +} + +static void warn_cert_msg(const char *uri, X509 *cert, const char *msg) +{ + char *subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); + + BIO_printf(bio_err, "Warning: certificate from '%s' with subject '%s' %s\n", + uri, subj, msg); + OPENSSL_free(subj); +} + +static void warn_cert(const char *uri, X509 *cert, int warn_EE, + X509_VERIFY_PARAM *vpm) +{ + uint32_t ex_flags = X509_get_extension_flags(cert); + int res = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert), + X509_get0_notAfter(cert)); + + if (res != 0) + warn_cert_msg(uri, cert, res > 0 ? "has expired" : "not yet valid"); + if (warn_EE && (ex_flags & EXFLAG_V1) == 0 && (ex_flags & EXFLAG_CA) == 0) + warn_cert_msg(uri, cert, "is not a CA cert"); +} + +static void warn_certs(const char *uri, STACK_OF(X509) *certs, int warn_EE, + X509_VERIFY_PARAM *vpm) +{ + int i; + + for (i = 0; i < sk_X509_num(certs); i++) + warn_cert(uri, sk_X509_value(certs, i), warn_EE, vpm); +} + +int load_cert_certs(const char *uri, + X509 **pcert, STACK_OF(X509) **pcerts, + int exclude_http, const char *pass, const char *desc, + X509_VERIFY_PARAM *vpm) +{ + int ret = 0; + char *pass_string; + + if (exclude_http && (OPENSSL_strncasecmp(uri, "http://", 7) == 0 + || OPENSSL_strncasecmp(uri, "https://", 8) == 0)) { + BIO_printf(bio_err, "error: HTTP retrieval not allowed for %s\n", desc); + return ret; + } + pass_string = get_passwd(pass, desc); + ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass_string, desc, + NULL, NULL, NULL, + pcert, pcerts, NULL, NULL); + clear_free(pass_string); + + if (ret) { + if (pcert != NULL) + warn_cert(uri, *pcert, 0, vpm); + if (pcerts != NULL) + warn_certs(uri, *pcerts, 1, vpm); } else { - BIO_printf(bio_err, "bad input format specified for key file\n"); - goto end; - } - end: - BIO_free(key); - if (pkey == NULL) { - BIO_printf(bio_err, "unable to load %s\n", key_descrip); - ERR_print_errors(bio_err); + if (pcerts != NULL) { + sk_X509_pop_free(*pcerts, X509_free); + *pcerts = NULL; + } } - return pkey; + return ret; } -EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, - const char *pass, ENGINE *e, const char *key_descrip) +STACK_OF(X509) *load_certs_multifile(char *files, const char *pass, + const char *desc, X509_VERIFY_PARAM *vpm) { - BIO *key = NULL; - EVP_PKEY *pkey = NULL; - PW_CB_DATA cb_data; + STACK_OF(X509) *certs = NULL; + STACK_OF(X509) *result = sk_X509_new_null(); + + if (files == NULL) + goto err; + if (result == NULL) + goto oom; - cb_data.password = pass; - cb_data.prompt_info = file; + while (files != NULL) { + char *next = next_item(files); - if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) { - BIO_printf(bio_err, "no keyfile specified\n"); - goto end; + if (!load_cert_certs(files, NULL, &certs, 0, pass, desc, vpm)) + goto err; + if (!X509_add_certs(result, certs, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) + goto oom; + sk_X509_pop_free(certs, X509_free); + certs = NULL; + files = next; } - if (format == FORMAT_ENGINE) { - if (e == NULL) { - BIO_printf(bio_err, "no engine specified\n"); - } else { -#ifndef OPENSSL_NO_ENGINE - pkey = ENGINE_load_public_key(e, file, ui_method, &cb_data); - if (pkey == NULL) { - BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip); - ERR_print_errors(bio_err); - } -#else - BIO_printf(bio_err, "engines not supported\n"); -#endif + return result; + + oom: + BIO_printf(bio_err, "out of memory\n"); + err: + sk_X509_pop_free(certs, X509_free); + sk_X509_pop_free(result, X509_free); + return NULL; +} + +static X509_STORE *sk_X509_to_store(X509_STORE *store /* may be NULL */, + const STACK_OF(X509) *certs /* may NULL */) +{ + int i; + + if (store == NULL) + store = X509_STORE_new(); + if (store == NULL) + return NULL; + for (i = 0; i < sk_X509_num(certs); i++) { + if (!X509_STORE_add_cert(store, sk_X509_value(certs, i))) { + X509_STORE_free(store); + return NULL; } - goto end; } - if (file == NULL && maybe_stdin) { - unbuffer(stdin); - key = dup_bio_in(format); - } else { - key = bio_open_default(file, 'r', format); + return store; +} + +/* + * Create cert store structure with certificates read from given file(s). + * Returns pointer to created X509_STORE on success, NULL on error. + */ +X509_STORE *load_certstore(char *input, const char *pass, const char *desc, + X509_VERIFY_PARAM *vpm) +{ + X509_STORE *store = NULL; + STACK_OF(X509) *certs = NULL; + + while (input != NULL) { + char *next = next_item(input); + int ok; + + if (!load_cert_certs(input, NULL, &certs, 1, pass, desc, vpm)) { + X509_STORE_free(store); + return NULL; + } + ok = (store = sk_X509_to_store(store, certs)) != NULL; + sk_X509_pop_free(certs, X509_free); + certs = NULL; + if (!ok) + return NULL; + input = next; } - if (key == NULL) - goto end; - if (format == FORMAT_ASN1) { - pkey = d2i_PUBKEY_bio(key, NULL); - } else if (format == FORMAT_ASN1RSA) { -#ifndef OPENSSL_NO_RSA - RSA *rsa; - rsa = d2i_RSAPublicKey_bio(key, NULL); - if (rsa) { - pkey = EVP_PKEY_new(); - if (pkey != NULL) - EVP_PKEY_set1_RSA(pkey, rsa); - RSA_free(rsa); - } else -#else - BIO_printf(bio_err, "RSA keys not supported\n"); -#endif - pkey = NULL; - } else if (format == FORMAT_PEMRSA) { -#ifndef OPENSSL_NO_RSA - RSA *rsa; - rsa = PEM_read_bio_RSAPublicKey(key, NULL, - (pem_password_cb *)password_callback, - &cb_data); - if (rsa != NULL) { - pkey = EVP_PKEY_new(); - if (pkey != NULL) - EVP_PKEY_set1_RSA(pkey, rsa); - RSA_free(rsa); - } else -#else - BIO_printf(bio_err, "RSA keys not supported\n"); -#endif - pkey = NULL; - } else if (format == FORMAT_PEM) { - pkey = PEM_read_bio_PUBKEY(key, NULL, - (pem_password_cb *)password_callback, - &cb_data); -#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) - } else if (format == FORMAT_MSBLOB) { - pkey = b2i_PublicKey_bio(key); -#endif + return store; +} + +/* + * Initialize or extend, if *certs != NULL, a certificate stack. + * The caller is responsible for freeing *certs if its value is left not NULL. + */ +int load_certs(const char *uri, int maybe_stdin, STACK_OF(X509) **certs, + const char *pass, const char *desc) +{ + int was_NULL = *certs == NULL; + int ret = load_key_certs_crls(uri, FORMAT_UNDEF, maybe_stdin, + pass, desc, NULL, NULL, + NULL, NULL, certs, NULL, NULL); + + if (!ret && was_NULL) { + sk_X509_pop_free(*certs, X509_free); + *certs = NULL; } - end: - BIO_free(key); - if (pkey == NULL) - BIO_printf(bio_err, "unable to load %s\n", key_descrip); - return pkey; + return ret; } -static int load_certs_crls(const char *file, int format, - const char *pass, const char *desc, - STACK_OF(X509) **pcerts, - STACK_OF(X509_CRL) **pcrls) +/* + * Initialize or extend, if *crls != NULL, a certificate stack. + * The caller is responsible for freeing *crls if its value is left not NULL. + */ +int load_crls(const char *uri, STACK_OF(X509_CRL) **crls, + const char *pass, const char *desc) { - int i; - BIO *bio; - STACK_OF(X509_INFO) *xis = NULL; - X509_INFO *xi; - PW_CB_DATA cb_data; - int rv = 0; + int was_NULL = *crls == NULL; + int ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass, desc, + NULL, NULL, NULL, + NULL, NULL, NULL, crls); - cb_data.password = pass; - cb_data.prompt_info = file; + if (!ret && was_NULL) { + sk_X509_CRL_pop_free(*crls, X509_CRL_free); + *crls = NULL; + } + return ret; +} - if (format != FORMAT_PEM) { - BIO_printf(bio_err, "bad input format specified for %s\n", desc); +static const char *format2string(int format) +{ + switch(format) { + case FORMAT_PEM: + return "PEM"; + case FORMAT_ASN1: + return "DER"; + } + return NULL; +} + +/* Set type expectation, but clear it if objects of different types expected. */ +#define SET_EXPECT(expect, val) ((expect) = (expect) < 0 ? (val) : ((expect) == (val) ? (val) : 0)) +/* + * Load those types of credentials for which the result pointer is not NULL. + * Reads from stdio if uri is NULL and maybe_stdin is nonzero. + * For non-NULL ppkey, pcert, and pcrl the first suitable value found is loaded. + * If pcerts is non-NULL and *pcerts == NULL then a new cert list is allocated. + * If pcerts is non-NULL then all available certificates are appended to *pcerts + * except any certificate assigned to *pcert. + * If pcrls is non-NULL and *pcrls == NULL then a new list of CRLs is allocated. + * If pcrls is non-NULL then all available CRLs are appended to *pcerts + * except any CRL assigned to *pcrl. + * In any case (also on error) the caller is responsible for freeing all members + * of *pcerts and *pcrls (as far as they are not NULL). + */ +static +int load_key_certs_crls_suppress(const char *uri, int format, int maybe_stdin, + const char *pass, const char *desc, + EVP_PKEY **ppkey, EVP_PKEY **ppubkey, + EVP_PKEY **pparams, + X509 **pcert, STACK_OF(X509) **pcerts, + X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls, + int suppress_decode_errors) +{ + PW_CB_DATA uidata; + OSSL_STORE_CTX *ctx = NULL; + OSSL_LIB_CTX *libctx = app_get0_libctx(); + const char *propq = app_get0_propq(); + int ncerts = 0; + int ncrls = 0; + const char *failed = + ppkey != NULL ? "key" : ppubkey != NULL ? "public key" : + pparams != NULL ? "params" : pcert != NULL ? "cert" : + pcrl != NULL ? "CRL" : pcerts != NULL ? "certs" : + pcrls != NULL ? "CRLs" : NULL; + int cnt_expectations = 0; + int expect = -1; + const char *input_type; + OSSL_PARAM itp[2]; + const OSSL_PARAM *params = NULL; + + if (ppkey != NULL) { + *ppkey = NULL; + cnt_expectations++; + SET_EXPECT(expect, OSSL_STORE_INFO_PKEY); + } + if (ppubkey != NULL) { + *ppubkey = NULL; + cnt_expectations++; + SET_EXPECT(expect, OSSL_STORE_INFO_PUBKEY); + } + if (pparams != NULL) { + *pparams = NULL; + cnt_expectations++; + SET_EXPECT(expect, OSSL_STORE_INFO_PARAMS); + } + if (pcert != NULL) { + *pcert = NULL; + cnt_expectations++; + SET_EXPECT(expect, OSSL_STORE_INFO_CERT); + } + if (pcerts != NULL) { + if (*pcerts == NULL && (*pcerts = sk_X509_new_null()) == NULL) { + BIO_printf(bio_err, "Out of memory loading"); + goto end; + } + cnt_expectations++; + SET_EXPECT(expect, OSSL_STORE_INFO_CERT); + } + if (pcrl != NULL) { + *pcrl = NULL; + cnt_expectations++; + SET_EXPECT(expect, OSSL_STORE_INFO_CRL); + } + if (pcrls != NULL) { + if (*pcrls == NULL && (*pcrls = sk_X509_CRL_new_null()) == NULL) { + BIO_printf(bio_err, "Out of memory loading"); + goto end; + } + cnt_expectations++; + SET_EXPECT(expect, OSSL_STORE_INFO_CRL); + } + if (cnt_expectations == 0) { + BIO_printf(bio_err, "Internal error: nothing to load from %s\n", + uri != NULL ? uri : ""); return 0; } - bio = bio_open_default(file, 'r', FORMAT_PEM); - if (bio == NULL) - return 0; + uidata.password = pass; + uidata.prompt_info = uri; - xis = PEM_X509_INFO_read_bio(bio, NULL, - (pem_password_cb *)password_callback, - &cb_data); + if ((input_type = format2string(format)) != NULL) { + itp[0] = OSSL_PARAM_construct_utf8_string(OSSL_STORE_PARAM_INPUT_TYPE, + (char *)input_type, 0); + itp[1] = OSSL_PARAM_construct_end(); + params = itp; + } - BIO_free(bio); + if (uri == NULL) { + BIO *bio; - if (pcerts != NULL && *pcerts == NULL) { - *pcerts = sk_X509_new_null(); - if (*pcerts == NULL) + if (!maybe_stdin) { + BIO_printf(bio_err, "No filename or uri specified for loading"); goto end; + } + uri = ""; + unbuffer(stdin); + bio = BIO_new_fp(stdin, 0); + if (bio != NULL) { + ctx = OSSL_STORE_attach(bio, "file", libctx, propq, + get_ui_method(), &uidata, params, + NULL, NULL); + BIO_free(bio); + } + } else { + ctx = OSSL_STORE_open_ex(uri, libctx, propq, get_ui_method(), &uidata, + params, NULL, NULL); } - - if (pcrls != NULL && *pcrls == NULL) { - *pcrls = sk_X509_CRL_new_null(); - if (*pcrls == NULL) - goto end; + if (ctx == NULL) { + BIO_printf(bio_err, "Could not open file or uri for loading"); + goto end; } + if (expect > 0 && !OSSL_STORE_expect(ctx, expect)) + goto end; - for (i = 0; i < sk_X509_INFO_num(xis); i++) { - xi = sk_X509_INFO_value(xis, i); - if (xi->x509 != NULL && pcerts != NULL) { - if (!sk_X509_push(*pcerts, xi->x509)) - goto end; - xi->x509 = NULL; + failed = NULL; + while (cnt_expectations > 0 && !OSSL_STORE_eof(ctx)) { + OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); + int type, ok = 1; + + /* + * This can happen (for example) if we attempt to load a file with + * multiple different types of things in it - but the thing we just + * tried to load wasn't one of the ones we wanted, e.g. if we're trying + * to load a certificate but the file has both the private key and the + * certificate in it. We just retry until eof. + */ + if (info == NULL) { + continue; } - if (xi->crl != NULL && pcrls != NULL) { - if (!sk_X509_CRL_push(*pcrls, xi->crl)) - goto end; - xi->crl = NULL; + + type = OSSL_STORE_INFO_get_type(info); + switch (type) { + case OSSL_STORE_INFO_PKEY: + if (ppkey != NULL && *ppkey == NULL) { + ok = (*ppkey = OSSL_STORE_INFO_get1_PKEY(info)) != NULL; + cnt_expectations -= ok; + } + /* + * An EVP_PKEY with private parts also holds the public parts, + * so if the caller asked for a public key, and we got a private + * key, we can still pass it back. + */ + if (ok && ppubkey != NULL && *ppubkey == NULL) { + ok = ((*ppubkey = OSSL_STORE_INFO_get1_PKEY(info)) != NULL); + cnt_expectations -= ok; + } + break; + case OSSL_STORE_INFO_PUBKEY: + if (ppubkey != NULL && *ppubkey == NULL) { + ok = ((*ppubkey = OSSL_STORE_INFO_get1_PUBKEY(info)) != NULL); + cnt_expectations -= ok; + } + break; + case OSSL_STORE_INFO_PARAMS: + if (pparams != NULL && *pparams == NULL) { + ok = ((*pparams = OSSL_STORE_INFO_get1_PARAMS(info)) != NULL); + cnt_expectations -= ok; + } + break; + case OSSL_STORE_INFO_CERT: + if (pcert != NULL && *pcert == NULL) { + ok = (*pcert = OSSL_STORE_INFO_get1_CERT(info)) != NULL; + cnt_expectations -= ok; + } + else if (pcerts != NULL) + ok = X509_add_cert(*pcerts, + OSSL_STORE_INFO_get1_CERT(info), + X509_ADD_FLAG_DEFAULT); + ncerts += ok; + break; + case OSSL_STORE_INFO_CRL: + if (pcrl != NULL && *pcrl == NULL) { + ok = (*pcrl = OSSL_STORE_INFO_get1_CRL(info)) != NULL; + cnt_expectations -= ok; + } + else if (pcrls != NULL) + ok = sk_X509_CRL_push(*pcrls, OSSL_STORE_INFO_get1_CRL(info)); + ncrls += ok; + break; + default: + /* skip any other type */ + break; + } + OSSL_STORE_INFO_free(info); + if (!ok) { + failed = info == NULL ? NULL : OSSL_STORE_INFO_type_string(type); + BIO_printf(bio_err, "Error reading"); + break; } } - if (pcerts != NULL && sk_X509_num(*pcerts) > 0) - rv = 1; - - if (pcrls != NULL && sk_X509_CRL_num(*pcrls) > 0) - rv = 1; - end: - - sk_X509_INFO_pop_free(xis, X509_INFO_free); - - if (rv == 0) { - if (pcerts != NULL) { - sk_X509_pop_free(*pcerts, X509_free); - *pcerts = NULL; + OSSL_STORE_close(ctx); + if (failed == NULL) { + int any = 0; + + if ((ppkey != NULL && *ppkey == NULL) + || (ppubkey != NULL && *ppubkey == NULL)) { + failed = "key"; + } else if (pparams != NULL && *pparams == NULL) { + failed = "params"; + } else if ((pcert != NULL || pcerts != NULL) && ncerts == 0) { + if (pcert == NULL) + any = 1; + failed = "cert"; + } else if ((pcrl != NULL || pcrls != NULL) && ncrls == 0) { + if (pcrl == NULL) + any = 1; + failed = "CRL"; } - if (pcrls != NULL) { - sk_X509_CRL_pop_free(*pcrls, X509_CRL_free); - *pcrls = NULL; + if (!suppress_decode_errors) { + if (failed != NULL) + BIO_printf(bio_err, "Could not read"); + if (any) + BIO_printf(bio_err, " any"); } - BIO_printf(bio_err, "unable to load %s\n", - pcerts ? "certificates" : "CRLs"); - ERR_print_errors(bio_err); } - return rv; -} - -void* app_malloc(int sz, const char *what) -{ - void *vp = OPENSSL_malloc(sz); - - if (vp == NULL) { - BIO_printf(bio_err, "%s: Could not allocate %d bytes for %s\n", - opt_getprog(), sz, what); + if (!suppress_decode_errors && failed != NULL) { + if (desc != NULL && strstr(desc, failed) != NULL) { + BIO_printf(bio_err, " %s", desc); + } else { + BIO_printf(bio_err, " %s", failed); + if (desc != NULL) + BIO_printf(bio_err, " of %s", desc); + } + if (uri != NULL) + BIO_printf(bio_err, " from %s", uri); + BIO_printf(bio_err, "\n"); ERR_print_errors(bio_err); - exit(1); } - return vp; -} - -/* - * Initialize or extend, if *certs != NULL, a certificate stack. - */ -int load_certs(const char *file, STACK_OF(X509) **certs, int format, - const char *pass, const char *desc) -{ - return load_certs_crls(file, format, pass, desc, certs, NULL); + if (suppress_decode_errors || failed == NULL) + /* clear any spurious errors */ + ERR_clear_error(); + return failed == NULL; } -/* - * Initialize or extend, if *crls != NULL, a certificate stack. - */ -int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format, - const char *pass, const char *desc) +int load_key_certs_crls(const char *uri, int format, int maybe_stdin, + const char *pass, const char *desc, + EVP_PKEY **ppkey, EVP_PKEY **ppubkey, + EVP_PKEY **pparams, + X509 **pcert, STACK_OF(X509) **pcerts, + X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls) { - return load_certs_crls(file, format, pass, desc, NULL, crls); + return load_key_certs_crls_suppress(uri, format, maybe_stdin, pass, desc, + ppkey, ppubkey, pparams, pcert, pcerts, + pcrl, pcrls, 0); } #define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) @@ -1069,13 +1181,24 @@ int set_name_ex(unsigned long *flags, const char *arg) return 1; } +int set_dateopt(unsigned long *dateopt, const char *arg) +{ + if (OPENSSL_strcasecmp(arg, "rfc_822") == 0) + *dateopt = ASN1_DTFLGS_RFC822; + else if (OPENSSL_strcasecmp(arg, "iso_8601") == 0) + *dateopt = ASN1_DTFLGS_ISO8601; + else + return 0; + return 1; +} + int set_ext_copy(int *copy_type, const char *arg) { - if (strcasecmp(arg, "none") == 0) + if (OPENSSL_strcasecmp(arg, "none") == 0) *copy_type = EXT_COPY_NONE; - else if (strcasecmp(arg, "copy") == 0) + else if (OPENSSL_strcasecmp(arg, "copy") == 0) *copy_type = EXT_COPY_ADD; - else if (strcasecmp(arg, "copyall") == 0) + else if (OPENSSL_strcasecmp(arg, "copyall") == 0) *copy_type = EXT_COPY_ALL; else return 0; @@ -1084,41 +1207,38 @@ int set_ext_copy(int *copy_type, const char *arg) int copy_extensions(X509 *x, X509_REQ *req, int copy_type) { - STACK_OF(X509_EXTENSION) *exts = NULL; - X509_EXTENSION *ext, *tmpext; - ASN1_OBJECT *obj; - int i, idx, ret = 0; - if (!x || !req || (copy_type == EXT_COPY_NONE)) + STACK_OF(X509_EXTENSION) *exts; + int i, ret = 0; + + if (x == NULL || req == NULL) + return 0; + if (copy_type == EXT_COPY_NONE) return 1; exts = X509_REQ_get_extensions(req); for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { - ext = sk_X509_EXTENSION_value(exts, i); - obj = X509_EXTENSION_get_object(ext); - idx = X509_get_ext_by_OBJ(x, obj, -1); - /* Does extension exist? */ + X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); + ASN1_OBJECT *obj = X509_EXTENSION_get_object(ext); + int idx = X509_get_ext_by_OBJ(x, obj, -1); + + /* Does extension exist in target? */ if (idx != -1) { /* If normal copy don't override existing extension */ if (copy_type == EXT_COPY_ADD) continue; /* Delete all extensions of same type */ do { - tmpext = X509_get_ext(x, idx); - X509_delete_ext(x, idx); - X509_EXTENSION_free(tmpext); + X509_EXTENSION_free(X509_delete_ext(x, idx)); idx = X509_get_ext_by_OBJ(x, obj, -1); } while (idx != -1); } if (!X509_add_ext(x, ext, -1)) goto end; } - ret = 1; end: - sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); - return ret; } @@ -1158,7 +1278,7 @@ static int set_table_opts(unsigned long *flags, const char *arg, } for (ptbl = in_tbl; ptbl->name; ptbl++) { - if (strcasecmp(arg, ptbl->name) == 0) { + if (OPENSSL_strcasecmp(arg, ptbl->name) == 0) { *flags &= ~ptbl->mask; if (c) *flags |= ptbl->flag; @@ -1170,14 +1290,16 @@ static int set_table_opts(unsigned long *flags, const char *arg, return 0; } -void print_name(BIO *out, const char *title, X509_NAME *nm, - unsigned long lflags) +void print_name(BIO *out, const char *title, const X509_NAME *nm) { char *buf; char mline = 0; int indent = 0; + unsigned long lflags = get_nameopt(); - if (title) + if (out == NULL) + return; + if (title != NULL) BIO_puts(out, title); if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { mline = 1; @@ -1233,10 +1355,14 @@ void print_array(BIO *out, const char* title, int len, const unsigned char* d) BIO_printf(out, "\n};\n"); } -X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, int noCApath) +X509_STORE *setup_verify(const char *CAfile, int noCAfile, + const char *CApath, int noCApath, + const char *CAstore, int noCAstore) { X509_STORE *store = X509_STORE_new(); X509_LOOKUP *lookup; + OSSL_LIB_CTX *libctx = app_get0_libctx(); + const char *propq = app_get0_propq(); if (store == NULL) goto end; @@ -1245,13 +1371,15 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) goto end; - if (CAfile) { - if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) { + if (CAfile != NULL) { + if (X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_PEM, + libctx, propq) <= 0) { BIO_printf(bio_err, "Error loading file %s\n", CAfile); goto end; } } else { - X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT, + libctx, propq); } } @@ -1259,8 +1387,8 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); if (lookup == NULL) goto end; - if (CApath) { - if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) { + if (CApath != NULL) { + if (X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM) <= 0) { BIO_printf(bio_err, "Error loading directory %s\n", CApath); goto end; } @@ -1269,72 +1397,25 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i } } + if (CAstore != NULL || !noCAstore) { + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_store()); + if (lookup == NULL) + goto end; + if (!X509_LOOKUP_add_store_ex(lookup, CAstore, libctx, propq)) { + if (CAstore != NULL) + BIO_printf(bio_err, "Error loading store URI %s\n", CAstore); + goto end; + } + } + ERR_clear_error(); return store; end: + ERR_print_errors(bio_err); X509_STORE_free(store); return NULL; } -#ifndef OPENSSL_NO_ENGINE -/* Try to load an engine in a shareable library */ -static ENGINE *try_load_engine(const char *engine) -{ - ENGINE *e = ENGINE_by_id("dynamic"); - if (e) { - if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) - || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) { - ENGINE_free(e); - e = NULL; - } - } - return e; -} -#endif - -ENGINE *setup_engine(const char *engine, int debug) -{ - ENGINE *e = NULL; - -#ifndef OPENSSL_NO_ENGINE - if (engine != NULL) { - if (strcmp(engine, "auto") == 0) { - BIO_printf(bio_err, "enabling auto ENGINE support\n"); - ENGINE_register_all_complete(); - return NULL; - } - if ((e = ENGINE_by_id(engine)) == NULL - && (e = try_load_engine(engine)) == NULL) { - BIO_printf(bio_err, "invalid engine \"%s\"\n", engine); - ERR_print_errors(bio_err); - return NULL; - } - if (debug) { - ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0); - } - ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1); - if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { - BIO_printf(bio_err, "can't use that engine\n"); - ERR_print_errors(bio_err); - ENGINE_free(e); - return NULL; - } - - BIO_printf(bio_err, "engine \"%s\" set.\n", ENGINE_get_id(e)); - } -#endif - return e; -} - -void release_engine(ENGINE *e) -{ -#ifndef OPENSSL_NO_ENGINE - if (e != NULL) - /* Free our "structural" reference. */ - ENGINE_free(e); -#endif -} - static unsigned long index_serial_hash(const OPENSSL_CSTRING *a) { const char *n; @@ -1408,19 +1489,18 @@ BIGNUM *load_serial(const char *serialfile, int *exists, int create, } } else { if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) { - BIO_printf(bio_err, "unable to load number from %s\n", + BIO_printf(bio_err, "Unable to load number from %s\n", serialfile); goto err; } ret = ASN1_INTEGER_to_BN(ai, NULL); if (ret == NULL) { - BIO_printf(bio_err, - "error converting number from bin to BIGNUM\n"); + BIO_printf(bio_err, "Error converting number from bin to BIGNUM\n"); goto err; } } - if (ret && retai) { + if (ret != NULL && retai != NULL) { *retai = ai; ai = NULL; } @@ -1446,7 +1526,7 @@ int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial else j = strlen(serialfile) + strlen(suffix) + 1; if (j >= BSIZE) { - BIO_printf(bio_err, "file name too long\n"); + BIO_printf(bio_err, "File name too long\n"); goto err; } @@ -1461,7 +1541,6 @@ int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial } out = BIO_new_file(buf[0], "w"); if (out == NULL) { - ERR_print_errors(bio_err); goto err; } @@ -1477,6 +1556,8 @@ int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial ai = NULL; } err: + if (!ret) + ERR_print_errors(bio_err); BIO_free_all(out); ASN1_INTEGER_free(ai); return ret; @@ -1493,7 +1574,7 @@ int rotate_serial(const char *serialfile, const char *new_suffix, if (i > j) j = i; if (j + 1 >= BSIZE) { - BIO_printf(bio_err, "file name too long\n"); + BIO_printf(bio_err, "File name too long\n"); goto err; } #ifndef OPENSSL_SYS_VMS @@ -1509,19 +1590,20 @@ int rotate_serial(const char *serialfile, const char *new_suffix, #endif ) { BIO_printf(bio_err, - "unable to rename %s to %s\n", serialfile, buf[1]); + "Unable to rename %s to %s\n", serialfile, buf[1]); perror("reason"); goto err; } if (rename(buf[0], serialfile) < 0) { BIO_printf(bio_err, - "unable to rename %s to %s\n", buf[0], serialfile); + "Unable to rename %s to %s\n", buf[0], serialfile); perror("reason"); rename(buf[1], serialfile); goto err; } return 1; err: + ERR_print_errors(bio_err); return 0; } @@ -1562,17 +1644,14 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr) #endif in = BIO_new_file(dbfile, "r"); - if (in == NULL) { - ERR_print_errors(bio_err); + if (in == NULL) goto err; - } #ifndef OPENSSL_NO_POSIX_IO BIO_get_fp(in, &dbfp); if (fstat(fileno(dbfp), &dbst) == -1) { - SYSerr(SYS_F_FSTAT, errno); - ERR_add_error_data(3, "fstat('", dbfile, "')"); - ERR_print_errors(bio_err); + ERR_raise_data(ERR_LIB_SYS, errno, + "calling fstat(%s)", dbfile); goto err; } #endif @@ -1609,6 +1688,7 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr) #endif err: + ERR_print_errors(bio_err); NCONF_free(dbattr_conf); TXT_DB_free(tmpdb); BIO_free_all(in); @@ -1624,20 +1704,23 @@ int index_index(CA_DB *db) LHASH_HASH_FN(index_serial), LHASH_COMP_FN(index_serial))) { BIO_printf(bio_err, - "error creating serial number index:(%ld,%ld,%ld)\n", + "Error creating serial number index:(%ld,%ld,%ld)\n", db->db->error, db->db->arg1, db->db->arg2); - return 0; + goto err; } if (db->attributes.unique_subject && !TXT_DB_create_index(db->db, DB_name, index_name_qual, LHASH_HASH_FN(index_name), LHASH_COMP_FN(index_name))) { - BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n", + BIO_printf(bio_err, "Error creating name index:(%ld,%ld,%ld)\n", db->db->error, db->db->arg1, db->db->arg2); - return 0; + goto err; } return 1; + err: + ERR_print_errors(bio_err); + return 0; } int save_index(const char *dbfile, const char *suffix, CA_DB *db) @@ -1648,7 +1731,7 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db) j = strlen(dbfile) + strlen(suffix); if (j + 6 >= BSIZE) { - BIO_printf(bio_err, "file name too long\n"); + BIO_printf(bio_err, "File name too long\n"); goto err; } #ifndef OPENSSL_SYS_VMS @@ -1663,7 +1746,7 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db) out = BIO_new_file(buf[0], "w"); if (out == NULL) { perror(dbfile); - BIO_printf(bio_err, "unable to open '%s'\n", dbfile); + BIO_printf(bio_err, "Unable to open '%s'\n", dbfile); goto err; } j = TXT_DB_write(out, db->db); @@ -1674,7 +1757,7 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db) out = BIO_new_file(buf[1], "w"); if (out == NULL) { perror(buf[2]); - BIO_printf(bio_err, "unable to open '%s'\n", buf[2]); + BIO_printf(bio_err, "Unable to open '%s'\n", buf[2]); goto err; } BIO_printf(out, "unique_subject = %s\n", @@ -1683,6 +1766,7 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db) return 1; err: + ERR_print_errors(bio_err); return 0; } @@ -1697,7 +1781,7 @@ int rotate_index(const char *dbfile, const char *new_suffix, if (i > j) j = i; if (j + 6 >= BSIZE) { - BIO_printf(bio_err, "file name too long\n"); + BIO_printf(bio_err, "File name too long\n"); goto err; } #ifndef OPENSSL_SYS_VMS @@ -1718,12 +1802,12 @@ int rotate_index(const char *dbfile, const char *new_suffix, && errno != ENOTDIR #endif ) { - BIO_printf(bio_err, "unable to rename %s to %s\n", dbfile, buf[1]); + BIO_printf(bio_err, "Unable to rename %s to %s\n", dbfile, buf[1]); perror("reason"); goto err; } if (rename(buf[0], dbfile) < 0) { - BIO_printf(bio_err, "unable to rename %s to %s\n", buf[0], dbfile); + BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[0], dbfile); perror("reason"); rename(buf[1], dbfile); goto err; @@ -1733,14 +1817,14 @@ int rotate_index(const char *dbfile, const char *new_suffix, && errno != ENOTDIR #endif ) { - BIO_printf(bio_err, "unable to rename %s to %s\n", buf[4], buf[3]); + BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[4], buf[3]); perror("reason"); rename(dbfile, buf[0]); rename(buf[1], dbfile); goto err; } if (rename(buf[2], buf[4]) < 0) { - BIO_printf(bio_err, "unable to rename %s to %s\n", buf[2], buf[4]); + BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[2], buf[4]); perror("reason"); rename(buf[3], buf[4]); rename(dbfile, buf[0]); @@ -1749,6 +1833,7 @@ int rotate_index(const char *dbfile, const char *new_suffix, } return 1; err: + ERR_print_errors(bio_err); return 0; } @@ -1784,9 +1869,11 @@ int parse_yesno(const char *str, int def) /* * name is expected to be in the format /type0=value0/type1=value1/type2=... - * where characters may be escaped by \ + * where + can be used instead of / to form multi-valued RDNs if canmulti + * and characters may be escaped by \ */ -X509_NAME *parse_name(const char *cp, long chtype, int canmulti) +X509_NAME *parse_name(const char *cp, int chtype, int canmulti, + const char *desc) { int nextismulti = 0; char *work; @@ -1794,21 +1881,26 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) if (*cp++ != '/') { BIO_printf(bio_err, - "name is expected to be in the format " + "%s: %s name is expected to be in the format " "/type0=value0/type1=value1/type2=... where characters may " "be escaped by \\. This name is not in that format: '%s'\n", - --cp); + opt_getprog(), desc, --cp); return NULL; } n = X509_NAME_new(); - if (n == NULL) + if (n == NULL) { + BIO_printf(bio_err, "%s: Out of memory\n", opt_getprog()); return NULL; + } work = OPENSSL_strdup(cp); - if (work == NULL) + if (work == NULL) { + BIO_printf(bio_err, "%s: Error copying %s name input\n", + opt_getprog(), desc); goto err; + } - while (*cp) { + while (*cp != '\0') { char *bp = work; char *typestr = bp; unsigned char *valstr; @@ -1817,54 +1909,64 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) nextismulti = 0; /* Collect the type */ - while (*cp && *cp != '=') + while (*cp != '\0' && *cp != '=') *bp++ = *cp++; + *bp++ = '\0'; if (*cp == '\0') { BIO_printf(bio_err, - "%s: Hit end of string before finding the equals.\n", - opt_getprog()); + "%s: Missing '=' after RDN type string '%s' in %s name string\n", + opt_getprog(), typestr, desc); goto err; } - *bp++ = '\0'; ++cp; /* Collect the value. */ valstr = (unsigned char *)bp; - for (; *cp && *cp != '/'; *bp++ = *cp++) { + for (; *cp != '\0' && *cp != '/'; *bp++ = *cp++) { + /* unescaped '+' symbol string signals further member of multiRDN */ if (canmulti && *cp == '+') { nextismulti = 1; break; } if (*cp == '\\' && *++cp == '\0') { BIO_printf(bio_err, - "%s: escape character at end of string\n", - opt_getprog()); + "%s: Escape character at end of %s name string\n", + opt_getprog(), desc); goto err; } } *bp++ = '\0'; /* If not at EOS (must be + or /), move forward. */ - if (*cp) + if (*cp != '\0') ++cp; /* Parse */ nid = OBJ_txt2nid(typestr); if (nid == NID_undef) { - BIO_printf(bio_err, "%s: Skipping unknown attribute \"%s\"\n", - opt_getprog(), typestr); + BIO_printf(bio_err, + "%s: Skipping unknown %s name attribute \"%s\"\n", + opt_getprog(), desc, typestr); + if (ismulti) + BIO_printf(bio_err, + "Hint: a '+' in a value string needs be escaped using '\\' else a new member of a multi-valued RDN is expected\n"); continue; } if (*valstr == '\0') { BIO_printf(bio_err, - "%s: No value provided for Subject Attribute %s, skipped\n", - opt_getprog(), typestr); + "%s: No value provided for %s name attribute \"%s\", skipped\n", + opt_getprog(), desc, typestr); continue; } if (!X509_NAME_add_entry_by_NID(n, nid, chtype, valstr, strlen((char *)valstr), - -1, ismulti ? -1 : 0)) + -1, ismulti ? -1 : 0)) { + ERR_print_errors(bio_err); + BIO_printf(bio_err, + "%s: Error adding %s name attribute \"/%s=%s\"\n", + opt_getprog(), desc, typestr ,valstr); goto err; + } } OPENSSL_free(work); @@ -1919,17 +2021,21 @@ int bio_to_mem(unsigned char **out, int maxlen, BIO *in) int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value) { - int rv; + int rv = 0; char *stmp, *vtmp = NULL; + stmp = OPENSSL_strdup(value); - if (!stmp) + if (stmp == NULL) return -1; vtmp = strchr(stmp, ':'); - if (vtmp) { - *vtmp = 0; - vtmp++; - } + if (vtmp == NULL) + goto err; + + *vtmp = 0; + vtmp++; rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp); + + err: OPENSSL_free(stmp); return rv; } @@ -2013,38 +2119,241 @@ unsigned char *next_protos_parse(size_t *outlen, const char *in) } } - if (len <= skipped) { - OPENSSL_free(out); - return NULL; - } + if (len <= skipped) { + OPENSSL_free(out); + return NULL; + } + + *outlen = len + 1 - skipped; + return out; +} + +void print_cert_checks(BIO *bio, X509 *x, + const char *checkhost, + const char *checkemail, const char *checkip) +{ + if (x == NULL) + return; + if (checkhost) { + BIO_printf(bio, "Hostname %s does%s match certificate\n", + checkhost, + X509_check_host(x, checkhost, 0, 0, NULL) == 1 + ? "" : " NOT"); + } + + if (checkemail) { + BIO_printf(bio, "Email %s does%s match certificate\n", + checkemail, X509_check_email(x, checkemail, 0, 0) + ? "" : " NOT"); + } + + if (checkip) { + BIO_printf(bio, "IP %s does%s match certificate\n", + checkip, X509_check_ip_asc(x, checkip, 0) ? "" : " NOT"); + } +} + +static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, STACK_OF(OPENSSL_STRING) *opts) +{ + int i; + + if (opts == NULL) + return 1; + + for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { + char *opt = sk_OPENSSL_STRING_value(opts, i); + if (pkey_ctrl_string(pkctx, opt) <= 0) { + BIO_printf(bio_err, "parameter error \"%s\"\n", opt); + ERR_print_errors(bio_err); + return 0; + } + } + + return 1; +} + +static int do_x509_init(X509 *x, STACK_OF(OPENSSL_STRING) *opts) +{ + int i; + + if (opts == NULL) + return 1; + + for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { + char *opt = sk_OPENSSL_STRING_value(opts, i); + if (x509_ctrl_string(x, opt) <= 0) { + BIO_printf(bio_err, "parameter error \"%s\"\n", opt); + ERR_print_errors(bio_err); + return 0; + } + } + + return 1; +} + +static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts) +{ + int i; + + if (opts == NULL) + return 1; + + for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { + char *opt = sk_OPENSSL_STRING_value(opts, i); + if (x509_req_ctrl_string(x, opt) <= 0) { + BIO_printf(bio_err, "parameter error \"%s\"\n", opt); + ERR_print_errors(bio_err); + return 0; + } + } + + return 1; +} + +static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey, + const char *md, STACK_OF(OPENSSL_STRING) *sigopts) +{ + EVP_PKEY_CTX *pkctx = NULL; + char def_md[80]; + + if (ctx == NULL) + return 0; + /* + * EVP_PKEY_get_default_digest_name() returns 2 if the digest is mandatory + * for this algorithm. + */ + if (EVP_PKEY_get_default_digest_name(pkey, def_md, sizeof(def_md)) == 2 + && strcmp(def_md, "UNDEF") == 0) { + /* The signing algorithm requires there to be no digest */ + md = NULL; + } + + return EVP_DigestSignInit_ex(ctx, &pkctx, md, app_get0_libctx(), + app_get0_propq(), pkey, NULL) + && do_pkey_ctx_init(pkctx, sigopts); +} + +static int adapt_keyid_ext(X509 *cert, X509V3_CTX *ext_ctx, + const char *name, const char *value, int add_default) +{ + const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(cert); + X509_EXTENSION *new_ext = X509V3_EXT_nconf(NULL, ext_ctx, name, value); + int idx, rv = 0; + + if (new_ext == NULL) + return rv; + + idx = X509v3_get_ext_by_OBJ(exts, X509_EXTENSION_get_object(new_ext), -1); + if (idx >= 0) { + X509_EXTENSION *found_ext = X509v3_get_ext(exts, idx); + ASN1_OCTET_STRING *data = X509_EXTENSION_get_data(found_ext); + int disabled = ASN1_STRING_length(data) <= 2; /* config said "none" */ + + if (disabled) { + X509_delete_ext(cert, idx); + X509_EXTENSION_free(found_ext); + } /* else keep existing key identifier, which might be outdated */ + rv = 1; + } else { + rv = !add_default || X509_add_ext(cert, new_ext, -1); + } + X509_EXTENSION_free(new_ext); + return rv; +} + +/* Ensure RFC 5280 compliance, adapt keyIDs as needed, and sign the cert info */ +int do_X509_sign(X509 *cert, EVP_PKEY *pkey, const char *md, + STACK_OF(OPENSSL_STRING) *sigopts, X509V3_CTX *ext_ctx) +{ + const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(cert); + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + int self_sign; + int rv = 0; + + if (sk_X509_EXTENSION_num(exts /* may be NULL */) > 0) { + /* Prevent X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 */ + if (!X509_set_version(cert, X509_VERSION_3)) + goto end; + + /* + * Add default SKID before such that default AKID can make use of it + * in case the certificate is self-signed + */ + /* Prevent X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER */ + if (!adapt_keyid_ext(cert, ext_ctx, "subjectKeyIdentifier", "hash", 1)) + goto end; + /* Prevent X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER */ + ERR_set_mark(); + self_sign = X509_check_private_key(cert, pkey); + ERR_pop_to_mark(); + if (!adapt_keyid_ext(cert, ext_ctx, "authorityKeyIdentifier", + "keyid, issuer", !self_sign)) + goto end; + } + + if (mctx != NULL && do_sign_init(mctx, pkey, md, sigopts) > 0) + rv = (X509_sign_ctx(cert, mctx) > 0); + end: + EVP_MD_CTX_free(mctx); + return rv; +} + +/* Sign the certificate request info */ +int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const char *md, + STACK_OF(OPENSSL_STRING) *sigopts) +{ + int rv = 0; + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + + if (do_sign_init(mctx, pkey, md, sigopts) > 0) + rv = (X509_REQ_sign_ctx(x, mctx) > 0); + EVP_MD_CTX_free(mctx); + return rv; +} + +/* Sign the CRL info */ +int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const char *md, + STACK_OF(OPENSSL_STRING) *sigopts) +{ + int rv = 0; + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - *outlen = len + 1 - skipped; - return out; + if (do_sign_init(mctx, pkey, md, sigopts) > 0) + rv = (X509_CRL_sign_ctx(x, mctx) > 0); + EVP_MD_CTX_free(mctx); + return rv; } -void print_cert_checks(BIO *bio, X509 *x, - const char *checkhost, - const char *checkemail, const char *checkip) +/* + * do_X509_verify returns 1 if the signature is valid, + * 0 if the signature check fails, or -1 if error occurs. + */ +int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts) { - if (x == NULL) - return; - if (checkhost) { - BIO_printf(bio, "Hostname %s does%s match certificate\n", - checkhost, - X509_check_host(x, checkhost, 0, 0, NULL) == 1 - ? "" : " NOT"); - } + int rv = 0; - if (checkemail) { - BIO_printf(bio, "Email %s does%s match certificate\n", - checkemail, X509_check_email(x, checkemail, 0, 0) - ? "" : " NOT"); - } + if (do_x509_init(x, vfyopts) > 0) + rv = X509_verify(x, pkey); + else + rv = -1; + return rv; +} - if (checkip) { - BIO_printf(bio, "IP %s does%s match certificate\n", - checkip, X509_check_ip_asc(x, checkip, 0) ? "" : " NOT"); - } +/* + * do_X509_REQ_verify returns 1 if the signature is valid, + * 0 if the signature check fails, or -1 if error occurs. + */ +int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey, + STACK_OF(OPENSSL_STRING) *vfyopts) +{ + int rv = 0; + + if (do_x509_req_init(x, vfyopts) > 0) + rv = X509_REQ_verify_ex(x, pkey, + app_get0_libctx(), app_get0_propq()); + else + rv = -1; + return rv; } /* Get first http URL from a DIST_POINT structure */ @@ -2063,7 +2372,8 @@ static const char *get_dp_url(DIST_POINT *dp) uri = GENERAL_NAME_get0_value(gen, >ype); if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) { const char *uptr = (const char *)ASN1_STRING_get0_data(uri); - if (strncmp(uptr, "http://", 7) == 0) + + if (IS_HTTP(uptr)) /* can/should not use HTTPS here */ return uptr; } } @@ -2082,19 +2392,19 @@ static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp) for (i = 0; i < sk_DIST_POINT_num(crldp); i++) { DIST_POINT *dp = sk_DIST_POINT_value(crldp, i); urlptr = get_dp_url(dp); - if (urlptr) - return load_crl(urlptr, FORMAT_HTTP); + if (urlptr != NULL) + return load_crl(urlptr, FORMAT_UNDEF, 0, "CRL via CDP"); } return NULL; } /* - * Example of downloading CRLs from CRLDP: not usable for real world as it - * always downloads, doesn't support non-blocking I/O and doesn't cache - * anything. + * Example of downloading CRLs from CRLDP: + * not usable for real world as it always downloads and doesn't cache anything. */ -static STACK_OF(X509_CRL) *crls_http_cb(X509_STORE_CTX *ctx, X509_NAME *nm) +static STACK_OF(X509_CRL) *crls_http_cb(const X509_STORE_CTX *ctx, + const X509_NAME *nm) { X509 *x; STACK_OF(X509_CRL) *crls = NULL; @@ -2127,6 +2437,184 @@ void store_setup_crl_download(X509_STORE *st) X509_STORE_set_lookup_crls_cb(st, crls_http_cb); } +#ifndef OPENSSL_NO_SOCK +static const char *tls_error_hint(void) +{ + unsigned long err = ERR_peek_error(); + + if (ERR_GET_LIB(err) != ERR_LIB_SSL) + err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) != ERR_LIB_SSL) + return NULL; + + switch (ERR_GET_REASON(err)) { + case SSL_R_WRONG_VERSION_NUMBER: + return "The server does not support (a suitable version of) TLS"; + case SSL_R_UNKNOWN_PROTOCOL: + return "The server does not support HTTPS"; + case SSL_R_CERTIFICATE_VERIFY_FAILED: + return "Cannot authenticate server via its TLS certificate, likely due to mismatch with our trusted TLS certs or missing revocation status"; + case SSL_AD_REASON_OFFSET + TLS1_AD_UNKNOWN_CA: + return "Server did not accept our TLS certificate, likely due to mismatch with server's trust anchor or missing revocation status"; + case SSL_AD_REASON_OFFSET + SSL3_AD_HANDSHAKE_FAILURE: + return "TLS handshake failure. Possibly the server requires our TLS certificate but did not receive it"; + default: /* no error or no hint available for error */ + return NULL; + } +} + +/* HTTP callback function that supports TLS connection also via HTTPS proxy */ +BIO *app_http_tls_cb(BIO *bio, void *arg, int connect, int detail) +{ + APP_HTTP_TLS_INFO *info = (APP_HTTP_TLS_INFO *)arg; + SSL_CTX *ssl_ctx = info->ssl_ctx; + + if (ssl_ctx == NULL) /* not using TLS */ + return bio; + if (connect) { + SSL *ssl; + BIO *sbio = NULL; + + /* adapt after fixing callback design flaw, see #17088 */ + if ((info->use_proxy + && !OSSL_HTTP_proxy_connect(bio, info->server, info->port, + NULL, NULL, /* no proxy credentials */ + info->timeout, bio_err, opt_getprog())) + || (sbio = BIO_new(BIO_f_ssl())) == NULL) { + return NULL; + } + if (ssl_ctx == NULL || (ssl = SSL_new(ssl_ctx)) == NULL) { + BIO_free(sbio); + return NULL; + } + + /* adapt after fixing callback design flaw, see #17088 */ + SSL_set_tlsext_host_name(ssl, info->server); /* not critical to do */ + + SSL_set_connect_state(ssl); + BIO_set_ssl(sbio, ssl, BIO_CLOSE); + + bio = BIO_push(sbio, bio); + } + if (!connect) { + const char *hint; + BIO *cbio; + + if (!detail) { /* disconnecting after error */ + hint = tls_error_hint(); + if (hint != NULL) + ERR_add_error_data(2, " : ", hint); + } + if (ssl_ctx != NULL) { + (void)ERR_set_mark(); + BIO_ssl_shutdown(bio); + cbio = BIO_pop(bio); /* connect+HTTP BIO */ + BIO_free(bio); /* SSL BIO */ + (void)ERR_pop_to_mark(); /* hide SSL_R_READ_BIO_NOT_SET etc. */ + bio = cbio; + } + } + return bio; +} + +void APP_HTTP_TLS_INFO_free(APP_HTTP_TLS_INFO *info) +{ + if (info != NULL) { + SSL_CTX_free(info->ssl_ctx); + OPENSSL_free(info); + } +} + +ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy, + const char *no_proxy, SSL_CTX *ssl_ctx, + const STACK_OF(CONF_VALUE) *headers, + long timeout, const char *expected_content_type, + const ASN1_ITEM *it) +{ + APP_HTTP_TLS_INFO info; + char *server; + char *port; + int use_ssl; + BIO *mem; + ASN1_VALUE *resp = NULL; + + if (url == NULL || it == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if (!OSSL_HTTP_parse_url(url, &use_ssl, NULL /* userinfo */, &server, &port, + NULL /* port_num, */, NULL, NULL, NULL)) + return NULL; + if (use_ssl && ssl_ctx == NULL) { + ERR_raise_data(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER, + "missing SSL_CTX"); + goto end; + } + if (!use_ssl && ssl_ctx != NULL) { + ERR_raise_data(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT, + "SSL_CTX given but use_ssl == 0"); + goto end; + } + + info.server = server; + info.port = port; + info.use_proxy = /* workaround for callback design flaw, see #17088 */ + OSSL_HTTP_adapt_proxy(proxy, no_proxy, server, use_ssl) != NULL; + info.timeout = timeout; + info.ssl_ctx = ssl_ctx; + mem = OSSL_HTTP_get(url, proxy, no_proxy, NULL /* bio */, NULL /* rbio */, + app_http_tls_cb, &info, 0 /* buf_size */, headers, + expected_content_type, 1 /* expect_asn1 */, + OSSL_HTTP_DEFAULT_MAX_RESP_LEN, timeout); + resp = ASN1_item_d2i_bio(it, mem, NULL); + BIO_free(mem); + + end: + OPENSSL_free(server); + OPENSSL_free(port); + return resp; + +} + +ASN1_VALUE *app_http_post_asn1(const char *host, const char *port, + const char *path, const char *proxy, + const char *no_proxy, SSL_CTX *ssl_ctx, + const STACK_OF(CONF_VALUE) *headers, + const char *content_type, + ASN1_VALUE *req, const ASN1_ITEM *req_it, + const char *expected_content_type, + long timeout, const ASN1_ITEM *rsp_it) +{ + int use_ssl = ssl_ctx != NULL; + APP_HTTP_TLS_INFO info; + BIO *rsp, *req_mem = ASN1_item_i2d_mem_bio(req_it, req); + ASN1_VALUE *res; + + if (req_mem == NULL) + return NULL; + + info.server = host; + info.port = port; + info.use_proxy = /* workaround for callback design flaw, see #17088 */ + OSSL_HTTP_adapt_proxy(proxy, no_proxy, host, use_ssl) != NULL; + info.timeout = timeout; + info.ssl_ctx = ssl_ctx; + rsp = OSSL_HTTP_transfer(NULL, host, port, path, use_ssl, + proxy, no_proxy, NULL /* bio */, NULL /* rbio */, + app_http_tls_cb, &info, + 0 /* buf_size */, headers, content_type, req_mem, + expected_content_type, 1 /* expect_asn1 */, + OSSL_HTTP_DEFAULT_MAX_RESP_LEN, timeout, + 0 /* keep_alive */); + BIO_free(req_mem); + res = ASN1_item_d2i_bio(rsp_it, rsp, NULL); + BIO_free(rsp); + return res; +} + +#endif + /* * Platform-specific sections */ @@ -2277,40 +2765,6 @@ double app_tminterval(int stop, int usertime) return ret; } -#elif defined(OPENSSL_SYSTEM_VMS) -# include -# include - -double app_tminterval(int stop, int usertime) -{ - static clock_t tmstart; - double ret = 0; - clock_t now; -# ifdef __TMS - struct tms rus; - - now = times(&rus); - if (usertime) - now = rus.tms_utime; -# else - if (usertime) - now = clock(); /* sum of user and kernel times */ - else { - struct timeval tv; - gettimeofday(&tv, NULL); - now = (clock_t)((unsigned long long)tv.tv_sec * CLK_TCK + - (unsigned long long)tv.tv_usec * (1000000 / CLK_TCK) - ); - } -# endif - if (stop == TM_START) - tmstart = now; - else - ret = (now - tmstart) / (double)(CLK_TCK); - - return ret; -} - #elif defined(_SC_CLK_TCK) /* by means of unistd.h */ # include @@ -2369,56 +2823,10 @@ int app_access(const char* name, int flag) #endif } -/* app_isdir section */ -#ifdef _WIN32 -int app_isdir(const char *name) -{ - DWORD attr; -# if defined(UNICODE) || defined(_UNICODE) - size_t i, len_0 = strlen(name) + 1; - WCHAR tempname[MAX_PATH]; - - if (len_0 > MAX_PATH) - return -1; - -# if !defined(_WIN32_WCE) || _WIN32_WCE>=101 - if (!MultiByteToWideChar(CP_ACP, 0, name, len_0, tempname, MAX_PATH)) -# endif - for (i = 0; i < len_0; i++) - tempname[i] = (WCHAR)name[i]; - - attr = GetFileAttributes(tempname); -# else - attr = GetFileAttributes(name); -# endif - if (attr == INVALID_FILE_ATTRIBUTES) - return -1; - return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0); -} -#else -# include -# ifndef S_ISDIR -# if defined(_S_IFMT) && defined(_S_IFDIR) -# define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR) -# else -# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) -# endif -# endif - int app_isdir(const char *name) { -# if defined(S_ISDIR) - struct stat st; - - if (stat(name, &st) == 0) - return S_ISDIR(st.st_mode); - else - return -1; -# else - return -1; -# endif + return opt_isdir(name); } -#endif /* raw_read|write section */ #if defined(__VMS) @@ -2468,6 +2876,11 @@ int raw_read_stdin(void *buf, int siz) return recv(fileno_stdin(), buf, siz, 0); } #else +# if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +# endif int raw_read_stdin(void *buf, int siz) { return read(fileno_stdin(), buf, siz); @@ -2483,7 +2896,22 @@ int raw_write_stdout(const void *buf, int siz) else return -1; } +#elif defined(OPENSSL_SYS_TANDEM) && defined(OPENSSL_THREADS) && defined(_SPT_MODEL_) +# if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +# endif +int raw_write_stdout(const void *buf,int siz) +{ + return write(fileno(stdout),(void*)buf,siz); +} #else +# if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +# endif int raw_write_stdout(const void *buf, int siz) { return write(fileno_stdout(), buf, siz); @@ -2491,41 +2919,36 @@ int raw_write_stdout(const void *buf, int siz) #endif /* - * Centralized handling if input and output files with format specification + * Centralized handling of input and output files with format specification * The format is meant to show what the input and output is supposed to be, * and is therefore a show of intent more than anything else. However, it - * does impact behavior on some platform, such as differentiating between + * does impact behavior on some platforms, such as differentiating between * text and binary input/output on non-Unix platforms */ -static int istext(int format) -{ - return (format & B_FORMAT_TEXT) == B_FORMAT_TEXT; -} - BIO *dup_bio_in(int format) { return BIO_new_fp(stdin, - BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0)); + BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0)); } -static BIO_METHOD *prefix_method = NULL; - BIO *dup_bio_out(int format) { BIO *b = BIO_new_fp(stdout, - BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0)); + BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0)); void *prefix = NULL; + if (b == NULL) + return NULL; + #ifdef OPENSSL_SYS_VMS - if (istext(format)) + if (FMT_istext(format)) b = BIO_push(BIO_new(BIO_f_linebuffer()), b); #endif - if (istext(format) && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) { - if (prefix_method == NULL) - prefix_method = apps_bf_prefix(); - b = BIO_push(BIO_new(prefix_method), b); - BIO_ctrl(b, PREFIX_CTRL_SET_PREFIX, 0, prefix); + if (FMT_istext(format) + && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) { + b = BIO_push(BIO_new(BIO_f_prefix()), b); + BIO_set_prefix(b, prefix); } return b; @@ -2534,20 +2957,14 @@ BIO *dup_bio_out(int format) BIO *dup_bio_err(int format) { BIO *b = BIO_new_fp(stderr, - BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0)); + BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0)); #ifdef OPENSSL_SYS_VMS - if (istext(format)) + if (b != NULL && FMT_istext(format)) b = BIO_push(BIO_new(BIO_f_linebuffer()), b); #endif return b; } -void destroy_prefix_method(void) -{ - BIO_meth_free(prefix_method); - prefix_method = NULL; -} - void unbuffer(FILE *fp) { /* @@ -2573,11 +2990,11 @@ static const char *modestr(char mode, int format) switch (mode) { case 'a': - return istext(format) ? "a" : "ab"; + return FMT_istext(format) ? "a" : "ab"; case 'r': - return istext(format) ? "r" : "rb"; + return FMT_istext(format) ? "r" : "rb"; case 'w': - return istext(format) ? "w" : "wb"; + return FMT_istext(format) ? "w" : "wb"; } /* The assert above should make sure we never reach this point */ return NULL; @@ -2603,28 +3020,32 @@ BIO *bio_open_owner(const char *filename, int format, int private) { FILE *fp = NULL; BIO *b = NULL; - int fd = -1, bflags, mode, textmode; + int textmode, bflags; +#ifndef OPENSSL_NO_POSIX_IO + int fd = -1, mode; +#endif if (!private || filename == NULL || strcmp(filename, "-") == 0) return bio_open_default(filename, 'w', format); + textmode = FMT_istext(format); +#ifndef OPENSSL_NO_POSIX_IO mode = O_WRONLY; -#ifdef O_CREAT +# ifdef O_CREAT mode |= O_CREAT; -#endif -#ifdef O_TRUNC +# endif +# ifdef O_TRUNC mode |= O_TRUNC; -#endif - textmode = istext(format); +# endif if (!textmode) { -#ifdef O_BINARY +# ifdef O_BINARY mode |= O_BINARY; -#elif defined(_O_BINARY) +# elif defined(_O_BINARY) mode |= _O_BINARY; -#endif +# endif } -#ifdef OPENSSL_SYS_VMS +# ifdef OPENSSL_SYS_VMS /* VMS doesn't have O_BINARY, it just doesn't make sense. But, * it still needs to know that we're going binary, or fdopen() * will fail with "invalid argument"... so we tell VMS what the @@ -2633,18 +3054,22 @@ BIO *bio_open_owner(const char *filename, int format, int private) if (!textmode) fd = open(filename, mode, 0600, "ctx=bin"); else -#endif +# endif fd = open(filename, mode, 0600); if (fd < 0) goto err; fp = fdopen(fd, modestr('w', format)); +#else /* OPENSSL_NO_POSIX_IO */ + /* Have stdio but not Posix IO, do the best we can */ + fp = fopen(filename, modestr('w', format)); +#endif /* OPENSSL_NO_POSIX_IO */ if (fp == NULL) goto err; bflags = BIO_CLOSE; if (textmode) bflags |= BIO_FP_TEXT; b = BIO_new_fp(fp, bflags); - if (b) + if (b != NULL) return b; err: @@ -2652,10 +3077,12 @@ BIO *bio_open_owner(const char *filename, int format, int private) opt_getprog(), filename, strerror(errno)); ERR_print_errors(bio_err); /* If we have fp, then fdopen took over fd, so don't close both. */ - if (fp) + if (fp != NULL) fclose(fp); +#ifndef OPENSSL_NO_POSIX_IO else if (fd >= 0) close(fd); +#endif return NULL; } @@ -2684,7 +3111,7 @@ static BIO *bio_open_default_(const char *filename, char mode, int format, if (ret != NULL) return ret; BIO_printf(bio_err, - "Can't open %s for %s, %s\n", + "Can't open \"%s\" for %s, %s\n", filename, modeverb(mode), strerror(errno)); } ERR_print_errors(bio_err); @@ -2787,6 +3214,57 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate, return 1; } +int set_crl_lastupdate(X509_CRL *crl, const char *lastupdate) +{ + int ret = 0; + ASN1_TIME *tm = ASN1_TIME_new(); + + if (tm == NULL) + goto end; + + if (lastupdate == NULL) { + if (X509_gmtime_adj(tm, 0) == NULL) + goto end; + } else { + if (!ASN1_TIME_set_string_X509(tm, lastupdate)) + goto end; + } + + if (!X509_CRL_set1_lastUpdate(crl, tm)) + goto end; + + ret = 1; +end: + ASN1_TIME_free(tm); + return ret; +} + +int set_crl_nextupdate(X509_CRL *crl, const char *nextupdate, + long days, long hours, long secs) +{ + int ret = 0; + ASN1_TIME *tm = ASN1_TIME_new(); + + if (tm == NULL) + goto end; + + if (nextupdate == NULL) { + if (X509_time_adj_ex(tm, days, hours * 60 * 60 + secs, NULL) == NULL) + goto end; + } else { + if (!ASN1_TIME_set_string_X509(tm, nextupdate)) + goto end; + } + + if (!X509_CRL_set1_nextUpdate(crl, tm)) + goto end; + + ret = 1; +end: + ASN1_TIME_free(tm); + return ret; +} + void make_uppercase(char *string) { int i; @@ -2794,3 +3272,118 @@ void make_uppercase(char *string) for (i = 0; string[i] != '\0'; i++) string[i] = toupper((unsigned char)string[i]); } + +/* This function is defined here due to visibility of bio_err */ +int opt_printf_stderr(const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = BIO_vprintf(bio_err, fmt, ap); + va_end(ap); + return ret; +} + +OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts, + const OSSL_PARAM *paramdefs) +{ + OSSL_PARAM *params = NULL; + size_t sz = (size_t)sk_OPENSSL_STRING_num(opts); + size_t params_n; + char *opt = "", *stmp, *vtmp = NULL; + int found = 1; + + if (opts == NULL) + return NULL; + + params = OPENSSL_zalloc(sizeof(OSSL_PARAM) * (sz + 1)); + if (params == NULL) + return NULL; + + for (params_n = 0; params_n < sz; params_n++) { + opt = sk_OPENSSL_STRING_value(opts, (int)params_n); + if ((stmp = OPENSSL_strdup(opt)) == NULL + || (vtmp = strchr(stmp, ':')) == NULL) + goto err; + /* Replace ':' with 0 to terminate the string pointed to by stmp */ + *vtmp = 0; + /* Skip over the separator so that vmtp points to the value */ + vtmp++; + if (!OSSL_PARAM_allocate_from_text(¶ms[params_n], paramdefs, + stmp, vtmp, strlen(vtmp), &found)) + goto err; + OPENSSL_free(stmp); + } + params[params_n] = OSSL_PARAM_construct_end(); + return params; +err: + OPENSSL_free(stmp); + BIO_printf(bio_err, "Parameter %s '%s'\n", found ? "error" : "unknown", + opt); + ERR_print_errors(bio_err); + app_params_free(params); + return NULL; +} + +void app_params_free(OSSL_PARAM *params) +{ + int i; + + if (params != NULL) { + for (i = 0; params[i].key != NULL; ++i) + OPENSSL_free(params[i].data); + OPENSSL_free(params); + } +} + +EVP_PKEY *app_keygen(EVP_PKEY_CTX *ctx, const char *alg, int bits, int verbose) +{ + EVP_PKEY *res = NULL; + + if (verbose && alg != NULL) { + BIO_printf(bio_err, "Generating %s key", alg); + if (bits > 0) + BIO_printf(bio_err, " with %d bits\n", bits); + else + BIO_printf(bio_err, "\n"); + } + if (!RAND_status()) + BIO_printf(bio_err, "Warning: generating random key material may take a long time\n" + "if the system has a poor entropy source\n"); + if (EVP_PKEY_keygen(ctx, &res) <= 0) + app_bail_out("%s: Error generating %s key\n", opt_getprog(), + alg != NULL ? alg : "asymmetric"); + return res; +} + +EVP_PKEY *app_paramgen(EVP_PKEY_CTX *ctx, const char *alg) +{ + EVP_PKEY *res = NULL; + + if (!RAND_status()) + BIO_printf(bio_err, "Warning: generating random key parameters may take a long time\n" + "if the system has a poor entropy source\n"); + if (EVP_PKEY_paramgen(ctx, &res) <= 0) + app_bail_out("%s: Generating %s key parameters failed\n", + opt_getprog(), alg != NULL ? alg : "asymmetric"); + return res; +} + +/* + * Return non-zero if the legacy path is still an option. + * This decision is based on the global command line operations and the + * behaviour thus far. + */ +int opt_legacy_okay(void) +{ + int provider_options = opt_provider_option_given(); + int libctx = app_get0_libctx() != NULL || app_get0_propq() != NULL; + /* + * Having a provider option specified or a custom library context or + * property query, is a sure sign we're not using legacy. + */ + if (provider_options || libctx) + return 0; + return 1; +} diff --git a/crypto/openssl/apps/lib/apps_ui.c b/crypto/openssl/apps/lib/apps_ui.c new file mode 100644 index 000000000000..00e0ba5d9996 --- /dev/null +++ b/crypto/openssl/apps/lib/apps_ui.c @@ -0,0 +1,223 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "apps_ui.h" + +static UI_METHOD *ui_method = NULL; +static const UI_METHOD *ui_base_method = NULL; + +static int ui_open(UI *ui) +{ + int (*opener)(UI *ui) = UI_method_get_opener(ui_base_method); + + if (opener != NULL) + return opener(ui); + return 1; +} + +static int ui_read(UI *ui, UI_STRING *uis) +{ + int (*reader)(UI *ui, UI_STRING *uis) = NULL; + + if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD + && UI_get0_user_data(ui)) { + switch (UI_get_string_type(uis)) { + case UIT_PROMPT: + case UIT_VERIFY: + { + const char *password = + ((PW_CB_DATA *)UI_get0_user_data(ui))->password; + + if (password != NULL) { + UI_set_result(ui, uis, password); + return 1; + } + } + break; + case UIT_NONE: + case UIT_BOOLEAN: + case UIT_INFO: + case UIT_ERROR: + break; + } + } + + reader = UI_method_get_reader(ui_base_method); + if (reader != NULL) + return reader(ui, uis); + /* Default to the empty password if we've got nothing better */ + UI_set_result(ui, uis, ""); + return 1; +} + +static int ui_write(UI *ui, UI_STRING *uis) +{ + int (*writer)(UI *ui, UI_STRING *uis) = NULL; + + if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD + && UI_get0_user_data(ui)) { + switch (UI_get_string_type(uis)) { + case UIT_PROMPT: + case UIT_VERIFY: + { + const char *password = + ((PW_CB_DATA *)UI_get0_user_data(ui))->password; + + if (password != NULL) + return 1; + } + break; + case UIT_NONE: + case UIT_BOOLEAN: + case UIT_INFO: + case UIT_ERROR: + break; + } + } + + writer = UI_method_get_writer(ui_base_method); + if (writer != NULL) + return writer(ui, uis); + return 1; +} + +static int ui_close(UI *ui) +{ + int (*closer)(UI *ui) = UI_method_get_closer(ui_base_method); + + if (closer != NULL) + return closer(ui); + return 1; +} + +/* object_name defaults to prompt_info from ui user data if present */ +static char *ui_prompt_construct(UI *ui, const char *phrase_desc, + const char *object_name) +{ + PW_CB_DATA *cb_data = (PW_CB_DATA *)UI_get0_user_data(ui); + + if (phrase_desc == NULL) + phrase_desc = "pass phrase"; + if (object_name == NULL && cb_data != NULL) + object_name = cb_data->prompt_info; + return UI_construct_prompt(NULL, phrase_desc, object_name); +} + +int set_base_ui_method(const UI_METHOD *ui_meth) +{ + if (ui_meth == NULL) + ui_meth = UI_null(); + ui_base_method = ui_meth; + return 1; +} + +int setup_ui_method(void) +{ + ui_base_method = UI_null(); +#ifndef OPENSSL_NO_UI_CONSOLE + ui_base_method = UI_OpenSSL(); +#endif + ui_method = UI_create_method("OpenSSL application user interface"); + return ui_method != NULL + && 0 == UI_method_set_opener(ui_method, ui_open) + && 0 == UI_method_set_reader(ui_method, ui_read) + && 0 == UI_method_set_writer(ui_method, ui_write) + && 0 == UI_method_set_closer(ui_method, ui_close) + && 0 == UI_method_set_prompt_constructor(ui_method, + ui_prompt_construct); +} + +void destroy_ui_method(void) +{ + if (ui_method != NULL) { + UI_destroy_method(ui_method); + ui_method = NULL; + } +} + +const UI_METHOD *get_ui_method(void) +{ + return ui_method; +} + +static void *ui_malloc(int sz, const char *what) +{ + void *vp = OPENSSL_malloc(sz); + + if (vp == NULL) { + BIO_printf(bio_err, "Could not allocate %d bytes for %s\n", sz, what); + ERR_print_errors(bio_err); + exit(1); + } + return vp; +} + +int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data) +{ + int res = 0; + UI *ui; + int ok = 0; + char *buff = NULL; + int ui_flags = 0; + const char *prompt_info = NULL; + char *prompt; + + if ((ui = UI_new_method(ui_method)) == NULL) + return 0; + + if (cb_data != NULL && cb_data->prompt_info != NULL) + prompt_info = cb_data->prompt_info; + prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); + if (prompt == NULL) { + BIO_printf(bio_err, "Out of memory\n"); + UI_free(ui); + return 0; + } + + ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; + UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); + + /* We know that there is no previous user data to return to us */ + (void)UI_add_user_data(ui, cb_data); + + ok = UI_add_input_string(ui, prompt, ui_flags, buf, + PW_MIN_LENGTH, bufsiz - 1); + + if (ok >= 0 && verify) { + buff = ui_malloc(bufsiz, "password buffer"); + ok = UI_add_verify_string(ui, prompt, ui_flags, buff, + PW_MIN_LENGTH, bufsiz - 1, buf); + } + if (ok >= 0) + do { + ok = UI_process(ui); + } while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); + + OPENSSL_clear_free(buff, (unsigned int)bufsiz); + + if (ok >= 0) + res = strlen(buf); + if (ok == -1) { + BIO_printf(bio_err, "User interface error\n"); + ERR_print_errors(bio_err); + OPENSSL_cleanse(buf, (unsigned int)bufsiz); + res = 0; + } + if (ok == -2) { + BIO_printf(bio_err, "aborted!\n"); + OPENSSL_cleanse(buf, (unsigned int)bufsiz); + res = 0; + } + UI_free(ui); + OPENSSL_free(prompt); + return res; +} diff --git a/crypto/openssl/apps/lib/build.info b/crypto/openssl/apps/lib/build.info new file mode 100644 index 000000000000..923ef5d92b83 --- /dev/null +++ b/crypto/openssl/apps/lib/build.info @@ -0,0 +1,23 @@ +# Auxiliary program source +IF[{- $config{target} =~ /^(?:VC-|mingw|BC-)/ -}] + # It's called 'init', but doesn't have much 'init' in it... + $AUXLIBAPPSSRC=win32_init.c +ENDIF +IF[{- $config{target} =~ /^vms-/ -}] + $AUXLIBAPPSSRC=vms_term_sock.c vms_decc_argv.c +ENDIF + +# Source for libapps +$LIBAPPSSRC=apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c \ + columns.c app_params.c names.c app_provider.c app_x509.c http_server.c \ + engine.c engine_loader.c app_libctx.c + +IF[{- !$disabled{apps} -}] + LIBS{noinst}=../libapps.a + SOURCE[../libapps.a]=$LIBAPPSSRC $AUXLIBAPPSSRC + INCLUDE[../libapps.a]=../.. ../../include ../include +ENDIF + +IF[{- !$disabled{srp} -}] + SOURCE[../libapps.a]=tlssrp_depr.c +ENDIF diff --git a/crypto/openssl/apps/lib/cmp_mock_srv.c b/crypto/openssl/apps/lib/cmp_mock_srv.c new file mode 100644 index 000000000000..b37f3dd3d89c --- /dev/null +++ b/crypto/openssl/apps/lib/cmp_mock_srv.c @@ -0,0 +1,450 @@ +/* + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Siemens AG 2018-2020 + * + * 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 atf + * https://www.openssl.org/source/license.html + */ + +#include "apps.h" +#include "cmp_mock_srv.h" + +#include +#include +#include + +/* the context for the CMP mock server */ +typedef struct +{ + X509 *certOut; /* certificate to be returned in cp/ip/kup msg */ + STACK_OF(X509) *chainOut; /* chain of certOut to add to extraCerts field */ + STACK_OF(X509) *caPubsOut; /* certs to return in caPubs field of ip msg */ + OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */ + int sendError; /* send error response also on valid requests */ + OSSL_CMP_MSG *certReq; /* ir/cr/p10cr/kur remembered while polling */ + int certReqId; /* id of last ir/cr/kur, used for polling */ + int pollCount; /* number of polls before actual cert response */ + int curr_pollCount; /* number of polls so far for current request */ + int checkAfterTime; /* time the client should wait between polling */ +} mock_srv_ctx; + + +static void mock_srv_ctx_free(mock_srv_ctx *ctx) +{ + if (ctx == NULL) + return; + + OSSL_CMP_PKISI_free(ctx->statusOut); + X509_free(ctx->certOut); + sk_X509_pop_free(ctx->chainOut, X509_free); + sk_X509_pop_free(ctx->caPubsOut, X509_free); + OSSL_CMP_MSG_free(ctx->certReq); + OPENSSL_free(ctx); +} + +static mock_srv_ctx *mock_srv_ctx_new(void) +{ + mock_srv_ctx *ctx = OPENSSL_zalloc(sizeof(mock_srv_ctx)); + + if (ctx == NULL) + goto err; + + if ((ctx->statusOut = OSSL_CMP_PKISI_new()) == NULL) + goto err; + + ctx->certReqId = -1; + + /* all other elements are initialized to 0 or NULL, respectively */ + return ctx; + err: + mock_srv_ctx_free(ctx); + return NULL; +} + +int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (cert == NULL || X509_up_ref(cert)) { + X509_free(ctx->certOut); + ctx->certOut = cert; + return 1; + } + return 0; +} + +int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx, + STACK_OF(X509) *chain) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + STACK_OF(X509) *chain_copy = NULL; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (chain != NULL && (chain_copy = X509_chain_up_ref(chain)) == NULL) + return 0; + sk_X509_pop_free(ctx->chainOut, X509_free); + ctx->chainOut = chain_copy; + return 1; +} + +int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx, + STACK_OF(X509) *caPubs) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + STACK_OF(X509) *caPubs_copy = NULL; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (caPubs != NULL && (caPubs_copy = X509_chain_up_ref(caPubs)) == NULL) + return 0; + sk_X509_pop_free(ctx->caPubsOut, X509_free); + ctx->caPubsOut = caPubs_copy; + return 1; +} + +int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status, + int fail_info, const char *text) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + OSSL_CMP_PKISI *si; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if ((si = OSSL_CMP_STATUSINFO_new(status, fail_info, text)) == NULL) + return 0; + OSSL_CMP_PKISI_free(ctx->statusOut); + ctx->statusOut = si; + return 1; +} + +int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx->sendError = val != 0; + return 1; +} + +int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (count < 0) { + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); + return 0; + } + ctx->pollCount = count; + return 1; +} + +int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx->checkAfterTime = sec; + return 1; +} + +static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *cert_req, + int certReqId, + const OSSL_CRMF_MSG *crm, + const X509_REQ *p10cr, + X509 **certOut, + STACK_OF(X509) **chainOut, + STACK_OF(X509) **caPubs) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + OSSL_CMP_PKISI *si = NULL; + + if (ctx == NULL || cert_req == NULL + || certOut == NULL || chainOut == NULL || caPubs == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + if (ctx->sendError) { + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); + return NULL; + } + + *certOut = NULL; + *chainOut = NULL; + *caPubs = NULL; + ctx->certReqId = certReqId; + + if (ctx->pollCount > 0 && ctx->curr_pollCount == 0) { + /* start polling */ + if (ctx->certReq != NULL) { + /* already in polling mode */ + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + return NULL; + } + if ((ctx->certReq = OSSL_CMP_MSG_dup(cert_req)) == NULL) + return NULL; + return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL); + } + if (ctx->curr_pollCount >= ctx->pollCount) + /* give final response after polling */ + ctx->curr_pollCount = 0; + + if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_KUR + && crm != NULL && ctx->certOut != NULL) { + const OSSL_CRMF_CERTID *cid = OSSL_CRMF_MSG_get0_regCtrl_oldCertID(crm); + const X509_NAME *issuer = X509_get_issuer_name(ctx->certOut); + const ASN1_INTEGER *serial = X509_get0_serialNumber(ctx->certOut); + + if (cid == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_CERTID); + return NULL; + } + if (issuer != NULL + && X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) { + ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID); + return NULL; + } + if (serial != NULL + && ASN1_INTEGER_cmp(serial, + OSSL_CRMF_CERTID_get0_serialNumber(cid)) != 0) { + ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID); + return NULL; + } + } + + if (ctx->certOut != NULL + && (*certOut = X509_dup(ctx->certOut)) == NULL) + goto err; + if (ctx->chainOut != NULL + && (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL) + goto err; + if (ctx->caPubsOut != NULL + && (*caPubs = X509_chain_up_ref(ctx->caPubsOut)) == NULL) + goto err; + if (ctx->statusOut != NULL + && (si = OSSL_CMP_PKISI_dup(ctx->statusOut)) == NULL) + goto err; + return si; + + err: + X509_free(*certOut); + *certOut = NULL; + sk_X509_pop_free(*chainOut, X509_free); + *chainOut = NULL; + sk_X509_pop_free(*caPubs, X509_free); + *caPubs = NULL; + return NULL; +} + +static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *rr, + const X509_NAME *issuer, + const ASN1_INTEGER *serial) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + + if (ctx == NULL || rr == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + if (ctx->sendError || ctx->certOut == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); + return NULL; + } + + /* Allow any RR derived from CSR, which may include subject and serial */ + if (issuer == NULL || serial == NULL) + return OSSL_CMP_PKISI_dup(ctx->statusOut); + + /* accept revocation only for the certificate we sent in ir/cr/kur */ + if (X509_NAME_cmp(issuer, X509_get_issuer_name(ctx->certOut)) != 0 + || ASN1_INTEGER_cmp(serial, + X509_get0_serialNumber(ctx->certOut)) != 0) { + ERR_raise_data(ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED, + "wrong certificate to revoke"); + return NULL; + } + return OSSL_CMP_PKISI_dup(ctx->statusOut); +} + +static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *genm, + const STACK_OF(OSSL_CMP_ITAV) *in, + STACK_OF(OSSL_CMP_ITAV) **out) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + + if (ctx == NULL || genm == NULL || in == NULL || out == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (sk_OSSL_CMP_ITAV_num(in) > 1 || ctx->sendError) { + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); + return 0; + } + + *out = sk_OSSL_CMP_ITAV_deep_copy(in, OSSL_CMP_ITAV_dup, + OSSL_CMP_ITAV_free); + return *out != NULL; +} + +static void process_error(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *error, + const OSSL_CMP_PKISI *statusInfo, + const ASN1_INTEGER *errorCode, + const OSSL_CMP_PKIFREETEXT *errorDetails) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + char buf[OSSL_CMP_PKISI_BUFLEN]; + char *sibuf; + int i; + + if (ctx == NULL || error == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return; + } + + BIO_printf(bio_err, "mock server received error:\n"); + + if (statusInfo == NULL) { + BIO_printf(bio_err, "pkiStatusInfo absent\n"); + } else { + sibuf = OSSL_CMP_snprint_PKIStatusInfo(statusInfo, buf, sizeof(buf)); + BIO_printf(bio_err, "pkiStatusInfo: %s\n", + sibuf != NULL ? sibuf: ""); + } + + if (errorCode == NULL) + BIO_printf(bio_err, "errorCode absent\n"); + else + BIO_printf(bio_err, "errorCode: %ld\n", ASN1_INTEGER_get(errorCode)); + + if (sk_ASN1_UTF8STRING_num(errorDetails) <= 0) { + BIO_printf(bio_err, "errorDetails absent\n"); + } else { + BIO_printf(bio_err, "errorDetails: "); + for (i = 0; i < sk_ASN1_UTF8STRING_num(errorDetails); i++) { + if (i > 0) + BIO_printf(bio_err, ", "); + BIO_printf(bio_err, "\""); + ASN1_STRING_print(bio_err, + sk_ASN1_UTF8STRING_value(errorDetails, i)); + BIO_printf(bio_err, "\""); + } + BIO_printf(bio_err, "\n"); + } +} + +static int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *certConf, int certReqId, + const ASN1_OCTET_STRING *certHash, + const OSSL_CMP_PKISI *si) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + ASN1_OCTET_STRING *digest; + + if (ctx == NULL || certConf == NULL || certHash == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (ctx->sendError || ctx->certOut == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); + return 0; + } + + if (certReqId != ctx->certReqId) { + /* in case of error, invalid reqId -1 */ + ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); + return 0; + } + + if ((digest = X509_digest_sig(ctx->certOut, NULL, NULL)) == NULL) + return 0; + if (ASN1_OCTET_STRING_cmp(certHash, digest) != 0) { + ASN1_OCTET_STRING_free(digest); + ERR_raise(ERR_LIB_CMP, CMP_R_CERTHASH_UNMATCHED); + return 0; + } + ASN1_OCTET_STRING_free(digest); + return 1; +} + +static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *pollReq, int certReqId, + OSSL_CMP_MSG **certReq, int64_t *check_after) +{ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + + if (ctx == NULL || pollReq == NULL + || certReq == NULL || check_after == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (ctx->sendError) { + *certReq = NULL; + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); + return 0; + } + if (ctx->certReq == NULL) { + /* not currently in polling mode */ + *certReq = NULL; + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + return 0; + } + + if (++ctx->curr_pollCount >= ctx->pollCount) { + /* end polling */ + *certReq = ctx->certReq; + ctx->certReq = NULL; + *check_after = 0; + } else { + *certReq = NULL; + *check_after = ctx->checkAfterTime; + } + return 1; +} + +OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq) +{ + OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new(libctx, propq); + mock_srv_ctx *ctx = mock_srv_ctx_new(); + + if (srv_ctx != NULL && ctx != NULL + && OSSL_CMP_SRV_CTX_init(srv_ctx, ctx, process_cert_request, + process_rr, process_genm, process_error, + process_certConf, process_pollReq)) + return srv_ctx; + + mock_srv_ctx_free(ctx); + OSSL_CMP_SRV_CTX_free(srv_ctx); + return NULL; +} + +void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx) +{ + if (srv_ctx != NULL) + mock_srv_ctx_free(OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx)); + OSSL_CMP_SRV_CTX_free(srv_ctx); +} diff --git a/crypto/openssl/apps/lib/columns.c b/crypto/openssl/apps/lib/columns.c new file mode 100644 index 000000000000..aa58fe1781f5 --- /dev/null +++ b/crypto/openssl/apps/lib/columns.c @@ -0,0 +1,27 @@ +/* + * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "apps.h" +#include "function.h" + +void calculate_columns(FUNCTION *functions, DISPLAY_COLUMNS *dc) +{ + FUNCTION *f; + int len, maxlen = 0; + + for (f = functions; f->name != NULL; ++f) + if (f->type == FT_general || f->type == FT_md || f->type == FT_cipher) + if ((len = strlen(f->name)) > maxlen) + maxlen = len; + + dc->width = maxlen + 2; + dc->columns = (80 - 1) / dc->width; +} + diff --git a/crypto/openssl/apps/lib/engine.c b/crypto/openssl/apps/lib/engine.c new file mode 100644 index 000000000000..209c4b6b03c2 --- /dev/null +++ b/crypto/openssl/apps/lib/engine.c @@ -0,0 +1,193 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Here is a set of wrappers for the ENGINE API, which are no-ops when the + * ENGINE API is disabled / removed. + * We need to suppress deprecation warnings to make this work. + */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include /* strcmp */ + +#include /* Ensure we have the ENGINE type, regardless */ +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include "apps.h" + +#ifndef OPENSSL_NO_ENGINE +/* Try to load an engine in a shareable library */ +static ENGINE *try_load_engine(const char *engine) +{ + ENGINE *e = NULL; + + if ((e = ENGINE_by_id("dynamic")) != NULL) { + if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) + || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) { + ENGINE_free(e); + e = NULL; + } + } + return e; +} +#endif + +ENGINE *setup_engine_methods(const char *id, unsigned int methods, int debug) +{ + ENGINE *e = NULL; + +#ifndef OPENSSL_NO_ENGINE + if (id != NULL) { + if (strcmp(id, "auto") == 0) { + BIO_printf(bio_err, "Enabling auto ENGINE support\n"); + ENGINE_register_all_complete(); + return NULL; + } + if ((e = ENGINE_by_id(id)) == NULL + && (e = try_load_engine(id)) == NULL) { + BIO_printf(bio_err, "Invalid engine \"%s\"\n", id); + ERR_print_errors(bio_err); + return NULL; + } + if (debug) + (void)ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0); + if (!ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, + (void *)get_ui_method(), 0, 1) + || !ENGINE_set_default(e, methods)) { + BIO_printf(bio_err, "Cannot use engine \"%s\"\n", ENGINE_get_id(e)); + ERR_print_errors(bio_err); + ENGINE_free(e); + return NULL; + } + + BIO_printf(bio_err, "Engine \"%s\" set.\n", ENGINE_get_id(e)); + } +#endif + return e; +} + +void release_engine(ENGINE *e) +{ +#ifndef OPENSSL_NO_ENGINE + /* Free our "structural" reference. */ + ENGINE_free(e); +#endif +} + +int init_engine(ENGINE *e) +{ + int rv = 1; + +#ifndef OPENSSL_NO_ENGINE + rv = ENGINE_init(e); +#endif + return rv; +} + +int finish_engine(ENGINE *e) +{ + int rv = 1; + +#ifndef OPENSSL_NO_ENGINE + rv = ENGINE_finish(e); +#endif + return rv; +} + +char *make_engine_uri(ENGINE *e, const char *key_id, const char *desc) +{ + char *new_uri = NULL; + +#ifndef OPENSSL_NO_ENGINE + if (e == NULL) { + BIO_printf(bio_err, "No engine specified for loading %s\n", desc); + } else if (key_id == NULL) { + BIO_printf(bio_err, "No engine key id specified for loading %s\n", desc); + } else { + const char *engineid = ENGINE_get_id(e); + size_t uri_sz = + sizeof(ENGINE_SCHEME_COLON) - 1 + + strlen(engineid) + + 1 /* : */ + + strlen(key_id) + + 1 /* \0 */ + ; + + new_uri = OPENSSL_malloc(uri_sz); + if (new_uri != NULL) { + OPENSSL_strlcpy(new_uri, ENGINE_SCHEME_COLON, uri_sz); + OPENSSL_strlcat(new_uri, engineid, uri_sz); + OPENSSL_strlcat(new_uri, ":", uri_sz); + OPENSSL_strlcat(new_uri, key_id, uri_sz); + } + } +#else + BIO_printf(bio_err, "Engines not supported for loading %s\n", desc); +#endif + return new_uri; +} + +int get_legacy_pkey_id(OSSL_LIB_CTX *libctx, const char *algname, ENGINE *e) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *tmpeng = NULL; + int pkey_id = NID_undef; + + ERR_set_mark(); + ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1); + +#if !defined(OPENSSL_NO_ENGINE) + ENGINE_finish(tmpeng); + + if (ameth == NULL && e != NULL) + ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1); + else +#endif + /* We're only interested if it comes from an ENGINE */ + if (tmpeng == NULL) + ameth = NULL; + + ERR_pop_to_mark(); + if (ameth == NULL) + return NID_undef; + + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); + + return pkey_id; +} + +const EVP_MD *get_digest_from_engine(const char *name) +{ +#ifndef OPENSSL_NO_ENGINE + ENGINE *eng; + + eng = ENGINE_get_digest_engine(OBJ_sn2nid(name)); + if (eng != NULL) { + ENGINE_finish(eng); + return EVP_get_digestbyname(name); + } +#endif + return NULL; +} + +const EVP_CIPHER *get_cipher_from_engine(const char *name) +{ +#ifndef OPENSSL_NO_ENGINE + ENGINE *eng; + + eng = ENGINE_get_cipher_engine(OBJ_sn2nid(name)); + if (eng != NULL) { + ENGINE_finish(eng); + return EVP_get_cipherbyname(name); + } +#endif + return NULL; +} diff --git a/crypto/openssl/apps/lib/engine_loader.c b/crypto/openssl/apps/lib/engine_loader.c new file mode 100644 index 000000000000..42775a89f361 --- /dev/null +++ b/crypto/openssl/apps/lib/engine_loader.c @@ -0,0 +1,203 @@ +/* + * Copyright 2018-2022 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 + */ + +/* + * Here is an STORE loader for ENGINE backed keys. It relies on deprecated + * functions, and therefore need to have deprecation warnings suppressed. + * This file is not compiled at all in a '--api=3 no-deprecated' configuration. + */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include "apps.h" + +#ifndef OPENSSL_NO_ENGINE + +# include +# include +# include +# include + +/* + * Support for legacy private engine keys via the 'org.openssl.engine:' scheme + * + * org.openssl.engine:{engineid}:{keyid} + * + * Note: we ONLY support ENGINE_load_private_key() and ENGINE_load_public_key() + * Note 2: This scheme has a precedent in code in PKIX-SSH. for exactly + * this sort of purpose. + */ + +/* Local definition of OSSL_STORE_LOADER_CTX */ +struct ossl_store_loader_ctx_st { + ENGINE *e; /* Structural reference */ + char *keyid; + int expected; + int loaded; /* 0 = key not loaded yet, 1 = key loaded */ +}; + +static OSSL_STORE_LOADER_CTX *OSSL_STORE_LOADER_CTX_new(ENGINE *e, char *keyid) +{ + OSSL_STORE_LOADER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx != NULL) { + ctx->e = e; + ctx->keyid = keyid; + } + return ctx; +} + +static void OSSL_STORE_LOADER_CTX_free(OSSL_STORE_LOADER_CTX *ctx) +{ + if (ctx != NULL) { + ENGINE_free(ctx->e); + OPENSSL_free(ctx->keyid); + OPENSSL_free(ctx); + } +} + +static OSSL_STORE_LOADER_CTX *engine_open(const OSSL_STORE_LOADER *loader, + const char *uri, + const UI_METHOD *ui_method, + void *ui_data) +{ + const char *p = uri, *q; + ENGINE *e = NULL; + char *keyid = NULL; + OSSL_STORE_LOADER_CTX *ctx = NULL; + + if (OPENSSL_strncasecmp(p, ENGINE_SCHEME_COLON, sizeof(ENGINE_SCHEME_COLON) - 1) + != 0) + return NULL; + p += sizeof(ENGINE_SCHEME_COLON) - 1; + + /* Look for engine ID */ + q = strchr(p, ':'); + if (q != NULL /* There is both an engine ID and a key ID */ + && p[0] != ':' /* The engine ID is at least one character */ + && q[1] != '\0') { /* The key ID is at least one character */ + char engineid[256]; + size_t engineid_l = q - p; + + strncpy(engineid, p, engineid_l); + engineid[engineid_l] = '\0'; + e = ENGINE_by_id(engineid); + + keyid = OPENSSL_strdup(q + 1); + } + + if (e != NULL && keyid != NULL) + ctx = OSSL_STORE_LOADER_CTX_new(e, keyid); + + if (ctx == NULL) { + OPENSSL_free(keyid); + ENGINE_free(e); + } + + return ctx; +} + +static int engine_expect(OSSL_STORE_LOADER_CTX *ctx, int expected) +{ + if (expected == 0 + || expected == OSSL_STORE_INFO_PUBKEY + || expected == OSSL_STORE_INFO_PKEY) { + ctx->expected = expected; + return 1; + } + return 0; +} + +static OSSL_STORE_INFO *engine_load(OSSL_STORE_LOADER_CTX *ctx, + const UI_METHOD *ui_method, void *ui_data) +{ + EVP_PKEY *pkey = NULL, *pubkey = NULL; + OSSL_STORE_INFO *info = NULL; + + if (ctx->loaded == 0) { + if (ENGINE_init(ctx->e)) { + if (ctx->expected == 0 + || ctx->expected == OSSL_STORE_INFO_PKEY) + pkey = + ENGINE_load_private_key(ctx->e, ctx->keyid, + (UI_METHOD *)ui_method, ui_data); + if ((pkey == NULL && ctx->expected == 0) + || ctx->expected == OSSL_STORE_INFO_PUBKEY) + pubkey = + ENGINE_load_public_key(ctx->e, ctx->keyid, + (UI_METHOD *)ui_method, ui_data); + ENGINE_finish(ctx->e); + } + } + + ctx->loaded = 1; + + if (pubkey != NULL) + info = OSSL_STORE_INFO_new_PUBKEY(pubkey); + else if (pkey != NULL) + info = OSSL_STORE_INFO_new_PKEY(pkey); + if (info == NULL) { + EVP_PKEY_free(pkey); + EVP_PKEY_free(pubkey); + } + return info; +} + +static int engine_eof(OSSL_STORE_LOADER_CTX *ctx) +{ + return ctx->loaded != 0; +} + +static int engine_error(OSSL_STORE_LOADER_CTX *ctx) +{ + return 0; +} + +static int engine_close(OSSL_STORE_LOADER_CTX *ctx) +{ + OSSL_STORE_LOADER_CTX_free(ctx); + return 1; +} + +int setup_engine_loader(void) +{ + OSSL_STORE_LOADER *loader = NULL; + + if ((loader = OSSL_STORE_LOADER_new(NULL, ENGINE_SCHEME)) == NULL + || !OSSL_STORE_LOADER_set_open(loader, engine_open) + || !OSSL_STORE_LOADER_set_expect(loader, engine_expect) + || !OSSL_STORE_LOADER_set_load(loader, engine_load) + || !OSSL_STORE_LOADER_set_eof(loader, engine_eof) + || !OSSL_STORE_LOADER_set_error(loader, engine_error) + || !OSSL_STORE_LOADER_set_close(loader, engine_close) + || !OSSL_STORE_register_loader(loader)) { + OSSL_STORE_LOADER_free(loader); + loader = NULL; + } + + return loader != NULL; +} + +void destroy_engine_loader(void) +{ + OSSL_STORE_LOADER *loader = OSSL_STORE_unregister_loader(ENGINE_SCHEME); + OSSL_STORE_LOADER_free(loader); +} + +#else /* !OPENSSL_NO_ENGINE */ + +int setup_engine_loader(void) +{ + return 0; +} + +void destroy_engine_loader(void) +{ +} + +#endif diff --git a/crypto/openssl/apps/lib/fmt.c b/crypto/openssl/apps/lib/fmt.c new file mode 100644 index 000000000000..af0e63b85b14 --- /dev/null +++ b/crypto/openssl/apps/lib/fmt.c @@ -0,0 +1,15 @@ +/* + * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "fmt.h" + +int FMT_istext(int format) +{ + return (format & B_FORMAT_TEXT) == B_FORMAT_TEXT; +} diff --git a/crypto/openssl/apps/lib/http_server.c b/crypto/openssl/apps/lib/http_server.c new file mode 100644 index 000000000000..a7fe5e1a58b0 --- /dev/null +++ b/crypto/openssl/apps/lib/http_server.c @@ -0,0 +1,533 @@ +/* + * Copyright 1995-2022 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 + */ + +/* Very basic HTTP server */ + +#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS) +/* + * On VMS, you need to define this to get the declaration of fileno(). The + * value 2 is to make sure no function defined in POSIX-2 is left undefined. + */ +# define _POSIX_C_SOURCE 2 +#endif + +#include +#include +#include "http_server.h" +#include "internal/sockets.h" +#include +#include +#include "s_apps.h" + +#if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +#endif + +static int verbosity = LOG_INFO; + +#define HTTP_PREFIX "HTTP/" +#define HTTP_VERSION_PATT "1." /* allow 1.x */ +#define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT +#define HTTP_1_0 HTTP_PREFIX_VERSION"0" /* "HTTP/1.0" */ + +#ifdef HTTP_DAEMON + +int multi = 0; /* run multiple responder processes */ +int acfd = (int) INVALID_SOCKET; + +static int print_syslog(const char *str, size_t len, void *levPtr) +{ + int level = *(int *)levPtr; + int ilen = len > MAXERRLEN ? MAXERRLEN : len; + + syslog(level, "%.*s", ilen, str); + + return ilen; +} +#endif + +void log_message(const char *prog, int level, const char *fmt, ...) +{ + va_list ap; + + if (verbosity < level) + return; + + va_start(ap, fmt); +#ifdef HTTP_DAEMON + if (multi) { + char buf[1024]; + + if (vsnprintf(buf, sizeof(buf), fmt, ap) > 0) + syslog(level, "%s", buf); + if (level <= LOG_ERR) + ERR_print_errors_cb(print_syslog, &level); + } else +#endif + { + BIO_printf(bio_err, "%s: ", prog); + BIO_vprintf(bio_err, fmt, ap); + BIO_printf(bio_err, "\n"); + (void)BIO_flush(bio_err); + } + va_end(ap); +} + +#ifdef HTTP_DAEMON +void socket_timeout(int signum) +{ + if (acfd != (int)INVALID_SOCKET) + (void)shutdown(acfd, SHUT_RD); +} + +static void killall(int ret, pid_t *kidpids) +{ + int i; + + for (i = 0; i < multi; ++i) + if (kidpids[i] != 0) + (void)kill(kidpids[i], SIGTERM); + OPENSSL_free(kidpids); + ossl_sleep(1000); + exit(ret); +} + +static int termsig = 0; + +static void noteterm(int sig) +{ + termsig = sig; +} + +/* + * Loop spawning up to `multi` child processes, only child processes return + * from this function. The parent process loops until receiving a termination + * signal, kills extant children and exits without returning. + */ +void spawn_loop(const char *prog) +{ + pid_t *kidpids = NULL; + int status; + int procs = 0; + int i; + + openlog(prog, LOG_PID, LOG_DAEMON); + + if (setpgid(0, 0)) { + syslog(LOG_ERR, "fatal: error detaching from parent process group: %s", + strerror(errno)); + exit(1); + } + kidpids = app_malloc(multi * sizeof(*kidpids), "child PID array"); + for (i = 0; i < multi; ++i) + kidpids[i] = 0; + + signal(SIGINT, noteterm); + signal(SIGTERM, noteterm); + + while (termsig == 0) { + pid_t fpid; + + /* + * Wait for a child to replace when we're at the limit. + * Slow down if a child exited abnormally or waitpid() < 0 + */ + while (termsig == 0 && procs >= multi) { + if ((fpid = waitpid(-1, &status, 0)) > 0) { + for (i = 0; i < procs; ++i) { + if (kidpids[i] == fpid) { + kidpids[i] = 0; + --procs; + break; + } + } + if (i >= multi) { + syslog(LOG_ERR, "fatal: internal error: " + "no matching child slot for pid: %ld", + (long) fpid); + killall(1, kidpids); + } + if (status != 0) { + if (WIFEXITED(status)) + syslog(LOG_WARNING, "child process: %ld, exit status: %d", + (long)fpid, WEXITSTATUS(status)); + else if (WIFSIGNALED(status)) + syslog(LOG_WARNING, "child process: %ld, term signal %d%s", + (long)fpid, WTERMSIG(status), +# ifdef WCOREDUMP + WCOREDUMP(status) ? " (core dumped)" : +# endif + ""); + ossl_sleep(1000); + } + break; + } else if (errno != EINTR) { + syslog(LOG_ERR, "fatal: waitpid(): %s", strerror(errno)); + killall(1, kidpids); + } + } + if (termsig) + break; + + switch (fpid = fork()) { + case -1: /* error */ + /* System critically low on memory, pause and try again later */ + ossl_sleep(30000); + break; + case 0: /* child */ + OPENSSL_free(kidpids); + signal(SIGINT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + if (termsig) + _exit(0); + if (RAND_poll() <= 0) { + syslog(LOG_ERR, "fatal: RAND_poll() failed"); + _exit(1); + } + return; + default: /* parent */ + for (i = 0; i < multi; ++i) { + if (kidpids[i] == 0) { + kidpids[i] = fpid; + procs++; + break; + } + } + if (i >= multi) { + syslog(LOG_ERR, "fatal: internal error: no free child slots"); + killall(1, kidpids); + } + break; + } + } + + /* The loop above can only break on termsig */ + syslog(LOG_INFO, "terminating on signal: %d", termsig); + killall(0, kidpids); +} +#endif + +#ifndef OPENSSL_NO_SOCK +BIO *http_server_init_bio(const char *prog, const char *port) +{ + BIO *acbio = NULL, *bufbio; + int asock; + + bufbio = BIO_new(BIO_f_buffer()); + if (bufbio == NULL) + goto err; + acbio = BIO_new(BIO_s_accept()); + if (acbio == NULL + || BIO_set_bind_mode(acbio, BIO_BIND_REUSEADDR) < 0 + || BIO_set_accept_port(acbio, port) < 0) { + log_message(prog, LOG_ERR, "Error setting up accept BIO"); + goto err; + } + + BIO_set_accept_bios(acbio, bufbio); + bufbio = NULL; + if (BIO_do_accept(acbio) <= 0) { + log_message(prog, LOG_ERR, "Error starting accept"); + goto err; + } + + /* Report back what address and port are used */ + BIO_get_fd(acbio, &asock); + if (!report_server_accept(bio_out, asock, 1, 1)) { + log_message(prog, LOG_ERR, "Error printing ACCEPT string"); + goto err; + } + + return acbio; + + err: + BIO_free_all(acbio); + BIO_free(bufbio); + return NULL; +} + +/* + * Decode %xx URL-decoding in-place. Ignores malformed sequences. + */ +static int urldecode(char *p) +{ + unsigned char *out = (unsigned char *)p; + unsigned char *save = out; + + for (; *p; p++) { + if (*p != '%') { + *out++ = *p; + } else if (isxdigit(_UC(p[1])) && isxdigit(_UC(p[2]))) { + /* Don't check, can't fail because of ixdigit() call. */ + *out++ = (OPENSSL_hexchar2int(p[1]) << 4) + | OPENSSL_hexchar2int(p[2]); + p += 2; + } else { + return -1; + } + } + *out = '\0'; + return (int)(out - save); +} + +/* if *pcbio != NULL, continue given connected session, else accept new */ +/* if found_keep_alive != NULL, return this way connection persistence state */ +int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, + char **ppath, BIO **pcbio, BIO *acbio, + int *found_keep_alive, + const char *prog, const char *port, + int accept_get, int timeout) +{ + BIO *cbio = *pcbio, *getbio = NULL, *b64 = NULL; + int len; + char reqbuf[2048], inbuf[2048]; + char *meth, *url, *end; + ASN1_VALUE *req; + int ret = 0; + + *preq = NULL; + if (ppath != NULL) + *ppath = NULL; + + if (cbio == NULL) { + log_message(prog, LOG_DEBUG, + "Awaiting new connection on port %s...", port); + if (BIO_do_accept(acbio) <= 0) + /* Connection loss before accept() is routine, ignore silently */ + return ret; + + *pcbio = cbio = BIO_pop(acbio); + } else { + log_message(prog, LOG_DEBUG, "Awaiting next request..."); + } + if (cbio == NULL) { + /* Cannot call http_server_send_status(cbio, ...) */ + ret = -1; + goto out; + } + +# ifdef HTTP_DAEMON + if (timeout > 0) { + (void)BIO_get_fd(cbio, &acfd); + alarm(timeout); + } +# endif + + /* Read the request line. */ + len = BIO_gets(cbio, reqbuf, sizeof(reqbuf)); + if (len == 0) + return ret; + ret = 1; + if (len < 0) { + log_message(prog, LOG_WARNING, "Request line read error"); + (void)http_server_send_status(cbio, 400, "Bad Request"); + goto out; + } + if ((end = strchr(reqbuf, '\r')) != NULL + || (end = strchr(reqbuf, '\n')) != NULL) + *end = '\0'; + log_message(prog, LOG_INFO, "Received request, 1st line: %s", reqbuf); + + meth = reqbuf; + url = meth + 3; + if ((accept_get && strncmp(meth, "GET ", 4) == 0) + || (url++, strncmp(meth, "POST ", 5) == 0)) { + static const char http_version_str[] = " "HTTP_PREFIX_VERSION; + static const size_t http_version_str_len = sizeof(http_version_str) - 1; + + /* Expecting (GET|POST) {sp} /URL {sp} HTTP/1.x */ + *(url++) = '\0'; + while (*url == ' ') + url++; + if (*url != '/') { + log_message(prog, LOG_WARNING, + "Invalid %s -- URL does not begin with '/': %s", + meth, url); + (void)http_server_send_status(cbio, 400, "Bad Request"); + goto out; + } + url++; + + /* Splice off the HTTP version identifier. */ + for (end = url; *end != '\0'; end++) + if (*end == ' ') + break; + if (strncmp(end, http_version_str, http_version_str_len) != 0) { + log_message(prog, LOG_WARNING, + "Invalid %s -- bad HTTP/version string: %s", + meth, end + 1); + (void)http_server_send_status(cbio, 400, "Bad Request"); + goto out; + } + *end = '\0'; + /* above HTTP 1.0, connection persistence is the default */ + if (found_keep_alive != NULL) + *found_keep_alive = end[http_version_str_len] > '0'; + + /*- + * Skip "GET / HTTP..." requests often used by load-balancers. + * 'url' was incremented above to point to the first byte *after* + * the leading slash, so in case 'GET / ' it is now an empty string. + */ + if (strlen(meth) == 3 && url[0] == '\0') { + (void)http_server_send_status(cbio, 200, "OK"); + goto out; + } + + len = urldecode(url); + if (len < 0) { + log_message(prog, LOG_WARNING, + "Invalid %s request -- bad URL encoding: %s", + meth, url); + (void)http_server_send_status(cbio, 400, "Bad Request"); + goto out; + } + if (strlen(meth) == 3) { /* GET */ + if ((getbio = BIO_new_mem_buf(url, len)) == NULL + || (b64 = BIO_new(BIO_f_base64())) == NULL) { + log_message(prog, LOG_ERR, + "Could not allocate base64 bio with size = %d", + len); + goto fatal; + } + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + getbio = BIO_push(b64, getbio); + } + } else { + log_message(prog, LOG_WARNING, + "HTTP request does not begin with %sPOST: %s", + accept_get ? "GET or " : "", reqbuf); + (void)http_server_send_status(cbio, 400, "Bad Request"); + goto out; + } + + /* chop any further/duplicate leading or trailing '/' */ + while (*url == '/') + url++; + while (end >= url + 2 && end[-2] == '/' && end[-1] == '/') + end--; + *end = '\0'; + + /* Read and skip past the headers. */ + for (;;) { + char *key, *value, *line_end = NULL; + + len = BIO_gets(cbio, inbuf, sizeof(inbuf)); + if (len <= 0) { + log_message(prog, LOG_WARNING, "Error reading HTTP header"); + (void)http_server_send_status(cbio, 400, "Bad Request"); + goto out; + } + + if (inbuf[0] == '\r' || inbuf[0] == '\n') + break; + + key = inbuf; + value = strchr(key, ':'); + if (value == NULL) { + log_message(prog, LOG_WARNING, + "Error parsing HTTP header: missing ':'"); + (void)http_server_send_status(cbio, 400, "Bad Request"); + goto out; + } + *(value++) = '\0'; + while (*value == ' ') + value++; + line_end = strchr(value, '\r'); + if (line_end == NULL) { + line_end = strchr(value, '\n'); + if (line_end == NULL) { + log_message(prog, LOG_WARNING, + "Error parsing HTTP header: missing end of line"); + (void)http_server_send_status(cbio, 400, "Bad Request"); + goto out; + } + } + *line_end = '\0'; + /* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */ + if (found_keep_alive != NULL + && OPENSSL_strcasecmp(key, "Connection") == 0) { + if (OPENSSL_strcasecmp(value, "keep-alive") == 0) + *found_keep_alive = 1; + else if (OPENSSL_strcasecmp(value, "close") == 0) + *found_keep_alive = 0; + } + } + +# ifdef HTTP_DAEMON + /* Clear alarm before we close the client socket */ + alarm(0); + timeout = 0; +# endif + + /* Try to read and parse request */ + req = ASN1_item_d2i_bio(it, getbio != NULL ? getbio : cbio, NULL); + if (req == NULL) { + log_message(prog, LOG_WARNING, + "Error parsing DER-encoded request content"); + (void)http_server_send_status(cbio, 400, "Bad Request"); + } else if (ppath != NULL && (*ppath = OPENSSL_strdup(url)) == NULL) { + log_message(prog, LOG_ERR, + "Out of memory allocating %zu bytes", strlen(url) + 1); + ASN1_item_free(req, it); + goto fatal; + } + + *preq = req; + + out: + BIO_free_all(getbio); +# ifdef HTTP_DAEMON + if (timeout > 0) + alarm(0); + acfd = (int)INVALID_SOCKET; +# endif + return ret; + + fatal: + (void)http_server_send_status(cbio, 500, "Internal Server Error"); + if (ppath != NULL) { + OPENSSL_free(*ppath); + *ppath = NULL; + } + BIO_free_all(cbio); + *pcbio = NULL; + ret = -1; + goto out; +} + +/* assumes that cbio does not do an encoding that changes the output length */ +int http_server_send_asn1_resp(BIO *cbio, int keep_alive, + const char *content_type, + const ASN1_ITEM *it, const ASN1_VALUE *resp) +{ + int ret = BIO_printf(cbio, HTTP_1_0" 200 OK\r\n%s" + "Content-type: %s\r\n" + "Content-Length: %d\r\n\r\n", + keep_alive ? "Connection: keep-alive\r\n" : "", + content_type, + ASN1_item_i2d(resp, NULL, it)) > 0 + && ASN1_item_i2d_bio(it, cbio, resp) > 0; + + (void)BIO_flush(cbio); + return ret; +} + +int http_server_send_status(BIO *cbio, int status, const char *reason) +{ + int ret = BIO_printf(cbio, HTTP_1_0" %d %s\r\n\r\n", + /* This implicitly cancels keep-alive */ + status, reason) > 0; + + (void)BIO_flush(cbio); + return ret; +} +#endif diff --git a/crypto/openssl/apps/lib/names.c b/crypto/openssl/apps/lib/names.c new file mode 100644 index 000000000000..4788ae84b915 --- /dev/null +++ b/crypto/openssl/apps/lib/names.c @@ -0,0 +1,45 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "names.h" +#include "openssl/crypto.h" + +int name_cmp(const char * const *a, const char * const *b) +{ + return OPENSSL_strcasecmp(*a, *b); +} + +void collect_names(const char *name, void *vdata) +{ + STACK_OF(OPENSSL_CSTRING) *names = vdata; + + sk_OPENSSL_CSTRING_push(names, name); +} + +void print_names(BIO *out, STACK_OF(OPENSSL_CSTRING) *names) +{ + int i = sk_OPENSSL_CSTRING_num(names); + int j; + + sk_OPENSSL_CSTRING_sort(names); + if (i > 1) + BIO_printf(out, "{ "); + for (j = 0; j < i; j++) { + const char *name = sk_OPENSSL_CSTRING_value(names, j); + + if (j > 0) + BIO_printf(out, ", "); + BIO_printf(out, "%s", name); + } + if (i > 1) + BIO_printf(out, " }"); +} diff --git a/crypto/openssl/apps/opt.c b/crypto/openssl/apps/lib/opt.c similarity index 59% rename from crypto/openssl/apps/opt.c rename to crypto/openssl/apps/lib/opt.c index 666856535d5e..157367982d2f 100644 --- a/crypto/openssl/apps/opt.c +++ b/crypto/openssl/apps/lib/opt.c @@ -1,27 +1,38 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include "apps.h" + +/* + * This file is also used by the test suite. Do not #include "apps.h". + */ +#include "opt.h" +#include "fmt.h" +#include "app_libctx.h" +#include "internal/nelem.h" +#include "internal/numbers.h" #include #if !defined(OPENSSL_SYS_MSDOS) -# include OPENSSL_UNISTD +# include #endif #include #include #include #include +#include #include #include #define MAX_OPT_HELP_WIDTH 30 -const char OPT_HELP_STR[] = "--"; -const char OPT_MORE_STR[] = "---"; +const char OPT_HELP_STR[] = "-H"; +const char OPT_MORE_STR[] = "-M"; +const char OPT_SECTION_STR[] = "-S"; +const char OPT_PARAM_STR[] = "-P"; /* Our state */ static char **argv; @@ -38,18 +49,27 @@ static char prog[40]; * Return the simple name of the program; removing various platform gunk. */ #if defined(OPENSSL_SYS_WIN32) -char *opt_progname(const char *argv0) + +const char *opt_path_end(const char *filename) { - size_t i, n; const char *p; - char *q; /* find the last '/', '\' or ':' */ - for (p = argv0 + strlen(argv0); --p > argv0;) + for (p = filename + strlen(filename); --p > filename; ) if (*p == '/' || *p == '\\' || *p == ':') { p++; break; } + return p; +} + +char *opt_progname(const char *argv0) +{ + size_t i, n; + const char *p; + char *q; + + p = opt_path_end(argv0); /* Strip off trailing nonsense. */ n = strlen(p); @@ -68,19 +88,28 @@ char *opt_progname(const char *argv0) #elif defined(OPENSSL_SYS_VMS) -char *opt_progname(const char *argv0) +const char *opt_path_end(const char *filename) { - const char *p, *q; + const char *p; /* Find last special character sys:[foo.bar]openssl */ - for (p = argv0 + strlen(argv0); --p > argv0;) + for (p = filename + strlen(filename); --p > filename;) if (*p == ':' || *p == ']' || *p == '>') { p++; break; } + return p; +} +char *opt_progname(const char *argv0) +{ + const char *p, *q; + + /* Find last special character sys:[foo.bar]openssl */ + p = opt_path_end(argv0); q = strrchr(p, '.'); - strncpy(prog, p, sizeof(prog) - 1); + if (prog != p) + strncpy(prog, p, sizeof(prog) - 1); prog[sizeof(prog) - 1] = '\0'; if (q != NULL && q - p < sizeof(prog)) prog[q - p] = '\0'; @@ -89,22 +118,40 @@ char *opt_progname(const char *argv0) #else -char *opt_progname(const char *argv0) +const char *opt_path_end(const char *filename) { const char *p; /* Could use strchr, but this is like the ones above. */ - for (p = argv0 + strlen(argv0); --p > argv0;) + for (p = filename + strlen(filename); --p > filename;) if (*p == '/') { p++; break; } - strncpy(prog, p, sizeof(prog) - 1); + return p; +} + +char *opt_progname(const char *argv0) +{ + const char *p; + + p = opt_path_end(argv0); + if (prog != p) + strncpy(prog, p, sizeof(prog) - 1); prog[sizeof(prog) - 1] = '\0'; return prog; } #endif +char *opt_appname(const char *argv0) +{ + size_t len = strlen(prog); + + if (argv0 != NULL) + BIO_snprintf(prog + len, sizeof(prog) - len - 1, " %s", argv0); + return prog; +} + char *opt_getprog(void) { return prog; @@ -116,32 +163,41 @@ char *opt_init(int ac, char **av, const OPTIONS *o) /* Store state. */ argc = ac; argv = av; - opt_index = 1; + opt_begin(); opts = o; - opt_progname(av[0]); unknown = NULL; - for (; o->name; ++o) { + /* Make sure prog name is set for usage output */ + (void)opt_progname(argv[0]); + + /* Check all options up until the PARAM marker (if present) */ + for (; o->name != NULL && o->name != OPT_PARAM_STR; ++o) { #ifndef NDEBUG const OPTIONS *next; int duplicated, i; #endif - if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR) + if (o->name == OPT_HELP_STR + || o->name == OPT_MORE_STR + || o->name == OPT_SECTION_STR) continue; #ifndef NDEBUG i = o->valtype; /* Make sure options are legit. */ - assert(o->name[0] != '-'); - assert(o->retval > 0); + OPENSSL_assert(o->name[0] != '-'); + if (o->valtype == '.') + OPENSSL_assert(o->retval == OPT_PARAM); + else + OPENSSL_assert(o->retval == OPT_DUP || o->retval > OPT_PARAM); switch (i) { - case 0: case '-': case '/': case '<': case '>': case 'E': case 'F': + case 0: case '-': case '.': + case '/': case '<': case '>': case 'E': case 'F': case 'M': case 'U': case 'f': case 'l': case 'n': case 'p': case 's': - case 'u': case 'c': + case 'u': case 'c': case ':': case 'N': break; default: - assert(0); + OPENSSL_assert(0); } /* Make sure there are no duplicates. */ @@ -149,14 +205,19 @@ char *opt_init(int ac, char **av, const OPTIONS *o) /* * Some compilers inline strcmp and the assert string is too long. */ - duplicated = strcmp(o->name, next->name) == 0; - assert(!duplicated); + duplicated = next->retval != OPT_DUP + && strcmp(o->name, next->name) == 0; + if (duplicated) { + opt_printf_stderr("%s: Internal error: duplicate option %s\n", + prog, o->name); + OPENSSL_assert(!duplicated); + } } #endif if (o->name[0] == '\0') { - assert(unknown == NULL); + OPENSSL_assert(unknown == NULL); unknown = o; - assert(unknown->valtype == 0 || unknown->valtype == '-'); + OPENSSL_assert(unknown->valtype == 0 || unknown->valtype == '-'); } } return prog; @@ -176,19 +237,19 @@ static OPT_PAIR formats[] = { }; /* Print an error message about a failed format parse. */ -int opt_format_error(const char *s, unsigned long flags) +static int opt_format_error(const char *s, unsigned long flags) { OPT_PAIR *ap; if (flags == OPT_FMT_PEMDER) { - BIO_printf(bio_err, "%s: Bad format \"%s\"; must be pem or der\n", - prog, s); + opt_printf_stderr("%s: Bad format \"%s\"; must be pem or der\n", + prog, s); } else { - BIO_printf(bio_err, "%s: Bad format \"%s\"; must be one of:\n", - prog, s); + opt_printf_stderr("%s: Bad format \"%s\"; must be one of:\n", + prog, s); for (ap = formats; ap->name; ap++) if (flags & ap->retval) - BIO_printf(bio_err, " %s\n", ap->name); + opt_printf_stderr(" %s\n", ap->name); } return 0; } @@ -198,6 +259,7 @@ int opt_format(const char *s, unsigned long flags, int *result) { switch (*s) { default: + opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s); return 0; case 'D': case 'd': @@ -264,6 +326,7 @@ int opt_format(const char *s, unsigned long flags, int *result) return opt_format_error(s, flags); *result = FORMAT_PKCS12; } else { + opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s); return 0; } break; @@ -271,28 +334,132 @@ int opt_format(const char *s, unsigned long flags, int *result) return 1; } -/* Parse a cipher name, put it in *EVP_CIPHER; return 0 on failure, else 1. */ -int opt_cipher(const char *name, const EVP_CIPHER **cipherp) +/* Return string representing the given format. */ +static const char *format2str(int format) +{ + switch (format) { + default: + return "(undefined)"; + case FORMAT_PEM: + return "PEM"; + case FORMAT_ASN1: + return "DER"; + case FORMAT_TEXT: + return "TEXT"; + case FORMAT_NSS: + return "NSS"; + case FORMAT_SMIME: + return "SMIME"; + case FORMAT_MSBLOB: + return "MSBLOB"; + case FORMAT_ENGINE: + return "ENGINE"; + case FORMAT_HTTP: + return "HTTP"; + case FORMAT_PKCS12: + return "P12"; + case FORMAT_PVK: + return "PVK"; + } +} + +/* Print an error message about unsuitable/unsupported format requested. */ +void print_format_error(int format, unsigned long flags) { - *cipherp = EVP_get_cipherbyname(name); - if (*cipherp != NULL) + (void)opt_format_error(format2str(format), flags); +} + +/* + * Parse a cipher name, put it in *cipherp after freeing what was there, if + * cipherp is not NULL. Return 0 on failure, else 1. + */ +int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp) +{ + EVP_CIPHER *c; + + ERR_set_mark(); + if ((c = EVP_CIPHER_fetch(app_get0_libctx(), name, + app_get0_propq())) != NULL + || (opt_legacy_okay() + && (c = (EVP_CIPHER *)EVP_get_cipherbyname(name)) != NULL)) { + ERR_pop_to_mark(); + if (cipherp != NULL) { + EVP_CIPHER_free(*cipherp); + *cipherp = c; + } else { + EVP_CIPHER_free(c); + } return 1; - BIO_printf(bio_err, "%s: Unrecognized flag %s\n", prog, name); + } + ERR_clear_last_mark(); return 0; } +int opt_cipher_any(const char *name, EVP_CIPHER **cipherp) +{ + int ret; + + if ((ret = opt_cipher_silent(name, cipherp)) == 0) + opt_printf_stderr("%s: Unknown cipher: %s\n", prog, name); + return ret; +} + +int opt_cipher(const char *name, EVP_CIPHER **cipherp) +{ + int mode, ret = 0; + unsigned long int flags; + EVP_CIPHER *c = NULL; + + if (opt_cipher_any(name, &c)) { + mode = EVP_CIPHER_get_mode(c); + flags = EVP_CIPHER_get_flags(c); + if (mode == EVP_CIPH_XTS_MODE) { + opt_printf_stderr("%s XTS ciphers not supported\n", prog); + } else if ((flags & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) { + opt_printf_stderr("%s: AEAD ciphers not supported\n", prog); + } else { + ret = 1; + if (cipherp != NULL) + *cipherp = c; + } + } + return ret; +} + /* * Parse message digest name, put it in *EVP_MD; return 0 on failure, else 1. */ -int opt_md(const char *name, const EVP_MD **mdp) +int opt_md_silent(const char *name, EVP_MD **mdp) { - *mdp = EVP_get_digestbyname(name); - if (*mdp != NULL) + EVP_MD *md; + + ERR_set_mark(); + if ((md = EVP_MD_fetch(app_get0_libctx(), name, app_get0_propq())) != NULL + || (opt_legacy_okay() + && (md = (EVP_MD *)EVP_get_digestbyname(name)) != NULL)) { + ERR_pop_to_mark(); + if (mdp != NULL) { + EVP_MD_free(*mdp); + *mdp = md; + } else { + EVP_MD_free(md); + } return 1; - BIO_printf(bio_err, "%s: Unrecognized flag %s\n", prog, name); + } + ERR_clear_last_mark(); return 0; } +int opt_md(const char *name, EVP_MD **mdp) +{ + int ret; + + if ((ret = opt_md_silent(name, mdp)) == 0) + opt_printf_stderr("%s: Unknown option or message digest: %s\n", prog, + name != NULL ? name : "\"\""); + return ret; +} + /* Look through a list of name/value pairs. */ int opt_pair(const char *name, const OPT_PAIR* pairs, int *result) { @@ -303,9 +470,23 @@ int opt_pair(const char *name, const OPT_PAIR* pairs, int *result) *result = pp->retval; return 1; } - BIO_printf(bio_err, "%s: Value must be one of:\n", prog); + opt_printf_stderr("%s: Value must be one of:\n", prog); for (pp = pairs; pp->name; pp++) - BIO_printf(bio_err, "\t%s\n", pp->name); + opt_printf_stderr("\t%s\n", pp->name); + return 0; +} + +/* Look through a list of valid names */ +int opt_string(const char *name, const char **options) +{ + const char **p; + + for (p = options; *p != NULL; p++) + if (strcmp(*p, name) == 0) + return 1; + opt_printf_stderr("%s: Value must be one of:\n", prog); + for (p = options; *p != NULL; p++) + opt_printf_stderr("\t%s\n", *p); return 0; } @@ -318,13 +499,22 @@ int opt_int(const char *value, int *result) return 0; *result = (int)l; if (*result != l) { - BIO_printf(bio_err, "%s: Value \"%s\" outside integer range\n", - prog, value); + opt_printf_stderr("%s: Value \"%s\" outside integer range\n", + prog, value); return 0; } return 1; } +/* Parse and return an integer, assuming range has been checked before. */ +int opt_int_arg(void) +{ + int result = -1; + + (void)opt_int(arg, &result); + return result; +} + static void opt_number_error(const char *v) { size_t i = 0; @@ -339,13 +529,12 @@ static void opt_number_error(const char *v) for (i = 0; i < OSSL_NELEM(b); i++) { if (strncmp(v, b[i].prefix, strlen(b[i].prefix)) == 0) { - BIO_printf(bio_err, - "%s: Can't parse \"%s\" as %s number\n", - prog, v, b[i].name); + opt_printf_stderr("%s: Can't parse \"%s\" as %s number\n", + prog, v, b[i].name); return; } } - BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n", prog, v); + opt_printf_stderr("%s: Can't parse \"%s\" as a number\n", prog, v); return; } @@ -372,10 +561,11 @@ int opt_long(const char *value, long *result) } #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \ - defined(INTMAX_MAX) && defined(UINTMAX_MAX) + defined(INTMAX_MAX) && defined(UINTMAX_MAX) && \ + !defined(OPENSSL_NO_INTTYPES_H) /* Parse an intmax_t, put it into *result; return 0 on failure, else 1. */ -int opt_imax(const char *value, intmax_t *result) +int opt_intmax(const char *value, ossl_intmax_t *result) { int oerrno = errno; intmax_t m; @@ -385,19 +575,26 @@ int opt_imax(const char *value, intmax_t *result) m = strtoimax(value, &endp, 0); if (*endp || endp == value - || ((m == INTMAX_MAX || m == INTMAX_MIN) && errno == ERANGE) + || ((m == INTMAX_MAX || m == INTMAX_MIN) + && errno == ERANGE) || (m == 0 && errno != 0)) { opt_number_error(value); errno = oerrno; return 0; } - *result = m; + /* Ensure that the value in |m| is never too big for |*result| */ + if (sizeof(m) > sizeof(*result) + && (m < OSSL_INTMAX_MIN || m > OSSL_INTMAX_MAX)) { + opt_number_error(value); + return 0; + } + *result = (ossl_intmax_t)m; errno = oerrno; return 1; } /* Parse a uintmax_t, put it into *result; return 0 on failure, else 1. */ -int opt_umax(const char *value, uintmax_t *result) +int opt_uintmax(const char *value, ossl_uintmax_t *result) { int oerrno = errno; uintmax_t m; @@ -413,10 +610,37 @@ int opt_umax(const char *value, uintmax_t *result) errno = oerrno; return 0; } - *result = m; + /* Ensure that the value in |m| is never too big for |*result| */ + if (sizeof(m) > sizeof(*result) + && m > OSSL_UINTMAX_MAX) { + opt_number_error(value); + return 0; + } + *result = (ossl_intmax_t)m; errno = oerrno; return 1; } +#else +/* Fallback implementations based on long */ +int opt_intmax(const char *value, ossl_intmax_t *result) +{ + long m; + int ret; + + if ((ret = opt_long(value, &m))) + *result = m; + return ret; +} + +int opt_uintmax(const char *value, ossl_uintmax_t *result) +{ + unsigned long m; + int ret; + + if ((ret = opt_ulong(value, &m))) + *result = m; + return ret; +} #endif /* @@ -458,9 +682,9 @@ int opt_verify(int opt, X509_VERIFY_PARAM *vpm) X509_PURPOSE *xptmp; const X509_VERIFY_PARAM *vtmp; - assert(vpm != NULL); - assert(opt > OPT_V__FIRST); - assert(opt < OPT_V__LAST); + OPENSSL_assert(vpm != NULL); + OPENSSL_assert(opt > OPT_V__FIRST); + OPENSSL_assert(opt < OPT_V__LAST); switch ((enum range)opt) { case OPT_V__FIRST: @@ -469,7 +693,7 @@ int opt_verify(int opt, X509_VERIFY_PARAM *vpm) case OPT_V_POLICY: otmp = OBJ_txt2obj(opt_arg(), 0); if (otmp == NULL) { - BIO_printf(bio_err, "%s: Invalid Policy %s\n", prog, opt_arg()); + opt_printf_stderr("%s: Invalid Policy %s\n", prog, opt_arg()); return 0; } X509_VERIFY_PARAM_add0_policy(vpm, otmp); @@ -478,7 +702,7 @@ int opt_verify(int opt, X509_VERIFY_PARAM *vpm) /* purpose name -> purpose index */ i = X509_PURPOSE_get_by_sname(opt_arg()); if (i < 0) { - BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg()); + opt_printf_stderr("%s: Invalid purpose %s\n", prog, opt_arg()); return 0; } @@ -489,17 +713,16 @@ int opt_verify(int opt, X509_VERIFY_PARAM *vpm) i = X509_PURPOSE_get_id(xptmp); if (!X509_VERIFY_PARAM_set_purpose(vpm, i)) { - BIO_printf(bio_err, - "%s: Internal error setting purpose %s\n", - prog, opt_arg()); + opt_printf_stderr("%s: Internal error setting purpose %s\n", + prog, opt_arg()); return 0; } break; case OPT_V_VERIFY_NAME: vtmp = X509_VERIFY_PARAM_lookup(opt_arg()); if (vtmp == NULL) { - BIO_printf(bio_err, "%s: Invalid verify name %s\n", - prog, opt_arg()); + opt_printf_stderr("%s: Invalid verify name %s\n", + prog, opt_arg()); return 0; } X509_VERIFY_PARAM_set1(vpm, vtmp); @@ -515,11 +738,11 @@ int opt_verify(int opt, X509_VERIFY_PARAM *vpm) X509_VERIFY_PARAM_set_auth_level(vpm, i); break; case OPT_V_ATTIME: - if (!opt_imax(opt_arg(), &t)) + if (!opt_intmax(opt_arg(), &t)) return 0; if (t != (time_t)t) { - BIO_printf(bio_err, "%s: epoch time out of range %s\n", - prog, opt_arg()); + opt_printf_stderr("%s: epoch time out of range %s\n", + prog, opt_arg()); return 0; } X509_VERIFY_PARAM_set_time(vpm, (time_t)t); @@ -606,6 +829,13 @@ int opt_verify(int opt, X509_VERIFY_PARAM *vpm) } +void opt_begin(void) +{ + opt_index = 1; + arg = NULL; + flag = NULL; +} + /* * Parse the next flag (and value if specified), return 0 if done, -1 on * error, otherwise the flag's retval. @@ -645,14 +875,15 @@ int opt_next(void) *arg++ = '\0'; for (o = opts; o->name; ++o) { /* If not this option, move on to the next one. */ - if (strcmp(p, o->name) != 0) + if (!(strcmp(p, "h") == 0 && strcmp(o->name, "help") == 0) + && strcmp(p, o->name) != 0) continue; /* If it doesn't take a value, make sure none was given. */ if (o->valtype == 0 || o->valtype == '-') { if (arg) { - BIO_printf(bio_err, - "%s: Option -%s does not take a value\n", prog, p); + opt_printf_stderr("%s: Option -%s does not take a value\n", + prog, p); return -1; } return o->retval; @@ -661,8 +892,8 @@ int opt_next(void) /* Want a value; get the next param if =foo not used. */ if (arg == NULL) { if (argv[opt_index] == NULL) { - BIO_printf(bio_err, - "%s: Option -%s needs a value\n", prog, o->name); + opt_printf_stderr("%s: Option -%s needs a value\n", + prog, o->name); return -1; } arg = argv[opt_index++]; @@ -672,12 +903,16 @@ int opt_next(void) switch (o->valtype) { default: case 's': + case ':': /* Just a string. */ break; + case '.': + /* Parameters */ + break; case '/': - if (app_isdir(arg) > 0) + if (opt_isdir(arg) > 0) break; - BIO_printf(bio_err, "%s: Not a directory: %s\n", prog, arg); + opt_printf_stderr("%s: Not a directory: %s\n", prog, arg); return -1; case '<': /* Input file. */ @@ -687,45 +922,35 @@ int opt_next(void) break; case 'p': case 'n': - if (!opt_int(arg, &ival) - || (o->valtype == 'p' && ival <= 0)) { - BIO_printf(bio_err, - "%s: Non-positive number \"%s\" for -%s\n", - prog, arg, o->name); + case 'N': + if (!opt_int(arg, &ival)) + return -1; + if (o->valtype == 'p' && ival <= 0) { + opt_printf_stderr("%s: Non-positive number \"%s\" for option -%s\n", + prog, arg, o->name); + return -1; + } + if (o->valtype == 'N' && ival < 0) { + opt_printf_stderr("%s: Negative number \"%s\" for option -%s\n", + prog, arg, o->name); return -1; } break; case 'M': - if (!opt_imax(arg, &imval)) { - BIO_printf(bio_err, - "%s: Invalid number \"%s\" for -%s\n", - prog, arg, o->name); + if (!opt_intmax(arg, &imval)) return -1; - } break; case 'U': - if (!opt_umax(arg, &umval)) { - BIO_printf(bio_err, - "%s: Invalid number \"%s\" for -%s\n", - prog, arg, o->name); + if (!opt_uintmax(arg, &umval)) return -1; - } break; case 'l': - if (!opt_long(arg, &lval)) { - BIO_printf(bio_err, - "%s: Invalid number \"%s\" for -%s\n", - prog, arg, o->name); + if (!opt_long(arg, &lval)) return -1; - } break; case 'u': - if (!opt_ulong(arg, &ulval)) { - BIO_printf(bio_err, - "%s: Invalid number \"%s\" for -%s\n", - prog, arg, o->name); + if (!opt_ulong(arg, &ulval)) return -1; - } break; case 'c': case 'E': @@ -737,9 +962,8 @@ int opt_next(void) o->valtype == 'F' ? OPT_FMT_PEMDER : OPT_FMT_ANY, &ival)) break; - BIO_printf(bio_err, - "%s: Invalid format \"%s\" for -%s\n", - prog, arg, o->name); + opt_printf_stderr("%s: Invalid format \"%s\" for option -%s\n", + prog, arg, o->name); return -1; } @@ -750,7 +974,7 @@ int opt_next(void) dunno = p; return unknown->retval; } - BIO_printf(bio_err, "%s: Option unknown option -%s\n", prog, p); + opt_printf_stderr("%s: Unknown option: -%s\n", prog, p); return -1; } @@ -760,7 +984,7 @@ char *opt_arg(void) return arg; } -/* Return the most recent flag. */ +/* Return the most recent flag (option name including the preceding '-'). */ char *opt_flag(void) { return flag; @@ -796,6 +1020,8 @@ static const char *valtype2param(const OPTIONS *o) case 0: case '-': return ""; + case ':': + return "uri"; case 's': return "val"; case '/': @@ -820,47 +1046,33 @@ static const char *valtype2param(const OPTIONS *o) return "format"; case 'M': return "intmax"; + case 'N': + return "nonneg"; case 'U': return "uintmax"; } return "parm"; } -void opt_help(const OPTIONS *list) +static void opt_print(const OPTIONS *o, int doingparams, int width) { - const OPTIONS *o; - int i; - int standard_prolog; - int width = 5; + const char* help; char start[80 + 1]; char *p; - const char *help; - /* Starts with its own help message? */ - standard_prolog = list[0].name != OPT_HELP_STR; - - /* Find the widest help. */ - for (o = list; o->name; o++) { - if (o->name == OPT_MORE_STR) - continue; - i = 2 + (int)strlen(o->name); - if (o->valtype != '-') - i += 1 + strlen(valtype2param(o)); - if (i < MAX_OPT_HELP_WIDTH && i > width) - width = i; - assert(i < (int)sizeof(start)); - } - - if (standard_prolog) - BIO_printf(bio_err, "Usage: %s [options]\nValid options are:\n", - prog); - - /* Now let's print. */ - for (o = list; o->name; o++) { help = o->helpstr ? o->helpstr : "(No additional info)"; if (o->name == OPT_HELP_STR) { - BIO_printf(bio_err, help, prog); - continue; + opt_printf_stderr(help, prog); + return; + } + if (o->name == OPT_SECTION_STR) { + opt_printf_stderr("\n"); + opt_printf_stderr(help, prog); + return; + } + if (o->name == OPT_PARAM_STR) { + opt_printf_stderr("\nParameters:\n"); + return; } /* Pad out prefix */ @@ -870,14 +1082,15 @@ void opt_help(const OPTIONS *list) if (o->name == OPT_MORE_STR) { /* Continuation of previous line; pad and print. */ start[width] = '\0'; - BIO_printf(bio_err, "%s %s\n", start, help); - continue; + opt_printf_stderr("%s %s\n", start, help); + return; } /* Build up the "-flag [param]" part. */ p = start; *p++ = ' '; - *p++ = '-'; + if (!doingparams) + *p++ = '-'; if (o->name[0]) p += strlen(strcpy(p, o->name)); else @@ -889,10 +1102,97 @@ void opt_help(const OPTIONS *list) *p = ' '; if ((int)(p - start) >= MAX_OPT_HELP_WIDTH) { *p = '\0'; - BIO_printf(bio_err, "%s\n", start); + opt_printf_stderr("%s\n", start); memset(start, ' ', sizeof(start)); } start[width] = '\0'; - BIO_printf(bio_err, "%s %s\n", start, help); + opt_printf_stderr("%s %s\n", start, help); +} + +void opt_help(const OPTIONS *list) +{ + const OPTIONS *o; + int i, sawparams = 0, width = 5; + int standard_prolog; + char start[80 + 1]; + + /* Starts with its own help message? */ + standard_prolog = list[0].name != OPT_HELP_STR; + + /* Find the widest help. */ + for (o = list; o->name; o++) { + if (o->name == OPT_MORE_STR) + continue; + i = 2 + (int)strlen(o->name); + if (o->valtype != '-') + i += 1 + strlen(valtype2param(o)); + if (i < MAX_OPT_HELP_WIDTH && i > width) + width = i; + OPENSSL_assert(i < (int)sizeof(start)); + } + + if (standard_prolog) { + opt_printf_stderr("Usage: %s [options]\n", prog); + if (list[0].name != OPT_SECTION_STR) + opt_printf_stderr("Valid options are:\n", prog); } + + /* Now let's print. */ + for (o = list; o->name; o++) { + if (o->name == OPT_PARAM_STR) + sawparams = 1; + opt_print(o, sawparams, width); + } +} + +/* opt_isdir section */ +#ifdef _WIN32 +# include +int opt_isdir(const char *name) +{ + DWORD attr; +# if defined(UNICODE) || defined(_UNICODE) + size_t i, len_0 = strlen(name) + 1; + WCHAR tempname[MAX_PATH]; + + if (len_0 > MAX_PATH) + return -1; + +# if !defined(_WIN32_WCE) || _WIN32_WCE>=101 + if (!MultiByteToWideChar(CP_ACP, 0, name, len_0, tempname, MAX_PATH)) +# endif + for (i = 0; i < len_0; i++) + tempname[i] = (WCHAR)name[i]; + + attr = GetFileAttributes(tempname); +# else + attr = GetFileAttributes(name); +# endif + if (attr == INVALID_FILE_ATTRIBUTES) + return -1; + return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0); } +#else +# include +# ifndef S_ISDIR +# if defined(_S_IFMT) && defined(_S_IFDIR) +# define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR) +# else +# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) +# endif +# endif + +int opt_isdir(const char *name) +{ +# if defined(S_ISDIR) + struct stat st; + + if (stat(name, &st) == 0) + return S_ISDIR(st.st_mode); + else + return -1; +# else + return -1; +# endif +} +#endif diff --git a/crypto/openssl/apps/s_cb.c b/crypto/openssl/apps/lib/s_cb.c similarity index 88% rename from crypto/openssl/apps/s_cb.c rename to crypto/openssl/apps/lib/s_cb.c index 2f94c13393a5..f2ddd94c3de4 100644 --- a/crypto/openssl/apps/s_cb.c +++ b/crypto/openssl/apps/lib/s_cb.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,6 +12,8 @@ #include #include /* for memcpy() and strcmp() */ #include "apps.h" +#include +#include #include #include #include @@ -150,6 +152,7 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key, STACK_OF(X509) *chain, int build_chain) { int chflags = chain ? SSL_BUILD_CHAIN_FLAG_CHECK : 0; + if (cert == NULL) return 1; if (SSL_CTX_use_certificate(ctx, cert) <= 0) { @@ -194,7 +197,7 @@ static STRINT_PAIR cert_type_list[] = { {"RSA fixed ECDH", TLS_CT_RSA_FIXED_ECDH}, {"ECDSA fixed ECDH", TLS_CT_ECDSA_FIXED_ECDH}, {"GOST01 Sign", TLS_CT_GOST01_SIGN}, - {"GOST12 Sign", TLS_CT_GOST12_SIGN}, + {"GOST12 Sign", TLS_CT_GOST12_IANA_SIGN}, {NULL} }; @@ -203,6 +206,7 @@ static void ssl_print_client_cert_types(BIO *bio, SSL *s) const unsigned char *p; int i; int cert_type_num = SSL_get0_certificate_types(s, &p); + if (!cert_type_num) return; BIO_puts(bio, "Client Certificate Types: "); @@ -232,22 +236,22 @@ static const char *get_sigtype(int nid) case EVP_PKEY_DSA: return "DSA"; - case EVP_PKEY_EC: + case EVP_PKEY_EC: return "ECDSA"; - case NID_ED25519: + case NID_ED25519: return "Ed25519"; - case NID_ED448: + case NID_ED448: return "Ed448"; - case NID_id_GostR3410_2001: + case NID_id_GostR3410_2001: return "gost2001"; - case NID_id_GostR3410_2012_256: + case NID_id_GostR3410_2012_256: return "gost2012_256"; - case NID_id_GostR3410_2012_512: + case NID_id_GostR3410_2012_512: return "gost2012_512"; default: @@ -258,6 +262,7 @@ static const char *get_sigtype(int nid) static int do_print_sigalgs(BIO *out, SSL *s, int shared) { int i, nsig, client; + client = SSL_is_server(s) ? 0 : 1; if (shared) nsig = SSL_get_shared_sigalgs(s, 0, NULL, NULL, NULL, NULL, NULL); @@ -300,6 +305,7 @@ static int do_print_sigalgs(BIO *out, SSL *s, int shared) int ssl_print_sigalgs(BIO *out, SSL *s) { int nid; + if (!SSL_is_server(s)) ssl_print_client_cert_types(out, s); do_print_sigalgs(out, s, 0); @@ -316,6 +322,7 @@ int ssl_print_point_formats(BIO *out, SSL *s) { int i, nformats; const char *pformats; + nformats = SSL_get0_ec_point_formats(s, &pformats); if (nformats <= 0) return 1; @@ -349,7 +356,6 @@ int ssl_print_point_formats(BIO *out, SSL *s) int ssl_print_groups(BIO *out, SSL *s, int noshared) { int i, ngroups, *groups, nid; - const char *gname; ngroups = SSL_get1_groups(s, NULL); if (ngroups <= 0) @@ -357,39 +363,25 @@ int ssl_print_groups(BIO *out, SSL *s, int noshared) groups = app_malloc(ngroups * sizeof(int), "groups to print"); SSL_get1_groups(s, groups); - BIO_puts(out, "Supported Elliptic Groups: "); + BIO_puts(out, "Supported groups: "); for (i = 0; i < ngroups; i++) { if (i) BIO_puts(out, ":"); nid = groups[i]; - /* If unrecognised print out hex version */ - if (nid & TLSEXT_nid_unknown) { - BIO_printf(out, "0x%04X", nid & 0xFFFF); - } else { - /* TODO(TLS1.3): Get group name here */ - /* Use NIST name for curve if it exists */ - gname = EC_curve_nid2nist(nid); - if (gname == NULL) - gname = OBJ_nid2sn(nid); - BIO_printf(out, "%s", gname); - } + BIO_printf(out, "%s", SSL_group_to_name(s, nid)); } OPENSSL_free(groups); if (noshared) { BIO_puts(out, "\n"); return 1; } - BIO_puts(out, "\nShared Elliptic groups: "); + BIO_puts(out, "\nShared groups: "); ngroups = SSL_get_shared_group(s, -1); for (i = 0; i < ngroups; i++) { if (i) BIO_puts(out, ":"); nid = SSL_get_shared_group(s, i); - /* TODO(TLS1.3): Convert for DH groups */ - gname = EC_curve_nid2nist(nid); - if (gname == NULL) - gname = OBJ_nid2sn(nid); - BIO_printf(out, "%s", gname); + BIO_printf(out, "%s", SSL_group_to_name(s, nid)); } if (ngroups == 0) BIO_puts(out, "NONE"); @@ -405,39 +397,37 @@ int ssl_print_tmp_key(BIO *out, SSL *s) if (!SSL_get_peer_tmp_key(s, &key)) return 1; BIO_puts(out, "Server Temp Key: "); - switch (EVP_PKEY_id(key)) { + switch (EVP_PKEY_get_id(key)) { case EVP_PKEY_RSA: - BIO_printf(out, "RSA, %d bits\n", EVP_PKEY_bits(key)); + BIO_printf(out, "RSA, %d bits\n", EVP_PKEY_get_bits(key)); break; case EVP_PKEY_DH: - BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(key)); + BIO_printf(out, "DH, %d bits\n", EVP_PKEY_get_bits(key)); break; #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: { - EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key); - int nid; - const char *cname; - nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); - EC_KEY_free(ec); - cname = EC_curve_nid2nist(nid); - if (cname == NULL) - cname = OBJ_nid2sn(nid); - BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(key)); + char name[80]; + size_t name_len; + + if (!EVP_PKEY_get_utf8_string_param(key, OSSL_PKEY_PARAM_GROUP_NAME, + name, sizeof(name), &name_len)) + strcpy(name, "?"); + BIO_printf(out, "ECDH, %s, %d bits\n", name, EVP_PKEY_get_bits(key)); } break; #endif default: - BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_id(key)), - EVP_PKEY_bits(key)); + BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_get_id(key)), + EVP_PKEY_get_bits(key)); } EVP_PKEY_free(key); return 1; } -long bio_dump_callback(BIO *bio, int cmd, const char *argp, - int argi, long argl, long ret) +long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len, + int argi, long argl, int ret, size_t *processed) { BIO *out; @@ -446,14 +436,23 @@ long bio_dump_callback(BIO *bio, int cmd, const char *argp, return ret; if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) { - BIO_printf(out, "read from %p [%p] (%lu bytes => %ld (0x%lX))\n", - (void *)bio, (void *)argp, (unsigned long)argi, ret, ret); - BIO_dump(out, argp, (int)ret); - return ret; + if (ret > 0 && processed != NULL) { + BIO_printf(out, "read from %p [%p] (%zu bytes => %zu (0x%zX))\n", + (void *)bio, (void *)argp, len, *processed, *processed); + BIO_dump(out, argp, (int)*processed); + } else { + BIO_printf(out, "read from %p [%p] (%zu bytes => %d)\n", + (void *)bio, (void *)argp, len, ret); + } } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) { - BIO_printf(out, "write to %p [%p] (%lu bytes => %ld (0x%lX))\n", - (void *)bio, (void *)argp, (unsigned long)argi, ret, ret); - BIO_dump(out, argp, (int)ret); + if (ret > 0 && processed != NULL) { + BIO_printf(out, "write to %p [%p] (%zu bytes => %zu (0x%zX))\n", + (void *)bio, (void *)argp, len, *processed, *processed); + BIO_dump(out, argp, (int)*processed); + } else { + BIO_printf(out, "write to %p [%p] (%zu bytes => %d)\n", + (void *)bio, (void *)argp, len, ret); + } } return ret; } @@ -569,8 +568,8 @@ void msg_cb(int write_p, int version, int content_type, const void *buf, { BIO *bio = arg; const char *str_write_p = write_p ? ">>>" : "<<<"; - const char *str_version = lookup(version, ssl_versions, "???"); - const char *str_content_type = "", *str_details1 = "", *str_details2 = ""; + char tmpbuf[128]; + const char *str_version, *str_content_type = "", *str_details1 = "", *str_details2 = ""; const unsigned char* bp = buf; if (version == SSL3_VERSION || @@ -579,11 +578,14 @@ void msg_cb(int write_p, int version, int content_type, const void *buf, version == TLS1_2_VERSION || version == TLS1_3_VERSION || version == DTLS1_VERSION || version == DTLS1_BAD_VER) { + str_version = lookup(version, ssl_versions, "???"); switch (content_type) { - case 20: + case SSL3_RT_CHANGE_CIPHER_SPEC: + /* type 20 */ str_content_type = ", ChangeCipherSpec"; break; - case 21: + case SSL3_RT_ALERT: + /* type 21 */ str_content_type = ", Alert"; str_details1 = ", ???"; if (len == 2) { @@ -598,32 +600,32 @@ void msg_cb(int write_p, int version, int content_type, const void *buf, str_details2 = lookup((int)bp[1], alert_types, " ???"); } break; - case 22: + case SSL3_RT_HANDSHAKE: + /* type 22 */ str_content_type = ", Handshake"; str_details1 = "???"; if (len > 0) str_details1 = lookup((int)bp[0], handshakes, "???"); break; - case 23: + case SSL3_RT_APPLICATION_DATA: + /* type 23 */ str_content_type = ", ApplicationData"; break; -#ifndef OPENSSL_NO_HEARTBEATS - case 24: - str_details1 = ", Heartbeat"; - - if (len > 0) { - switch (bp[0]) { - case 1: - str_details1 = ", HeartbeatRequest"; - break; - case 2: - str_details1 = ", HeartbeatResponse"; - break; - } - } + case SSL3_RT_HEADER: + /* type 256 */ + str_content_type = ", RecordHeader"; break; -#endif + case SSL3_RT_INNER_CONTENT_TYPE: + /* type 257 */ + str_content_type = ", InnerContent"; + break; + default: + BIO_snprintf(tmpbuf, sizeof(tmpbuf)-1, ", Unknown (content_type=%d)", content_type); + str_content_type = tmpbuf; } + } else { + BIO_snprintf(tmpbuf, sizeof(tmpbuf)-1, "Not TLS data or unknown version (version=%d, content_type=%d)", version, content_type); + str_version = tmpbuf; } BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version, @@ -663,7 +665,6 @@ static STRINT_PAIR tlsext_types[] = { {"SRP", TLSEXT_TYPE_srp}, {"signature algorithms", TLSEXT_TYPE_signature_algorithms}, {"use SRTP", TLSEXT_TYPE_use_srtp}, - {"heartbeat", TLSEXT_TYPE_heartbeat}, {"session ticket", TLSEXT_TYPE_session_ticket}, {"renegotiation info", TLSEXT_TYPE_renegotiate}, {"signed certificate timestamps", TLSEXT_TYPE_signed_certificate_timestamp}, @@ -750,13 +751,14 @@ void tlsext_cb(SSL *s, int client_server, int type, } #ifndef OPENSSL_NO_SOCK -int generate_cookie_callback(SSL *ssl, unsigned char *cookie, - unsigned int *cookie_len) +int generate_stateless_cookie_callback(SSL *ssl, unsigned char *cookie, + size_t *cookie_len) { - unsigned char *buffer; + unsigned char *buffer = NULL; size_t length = 0; unsigned short port; BIO_ADDR *lpeer = NULL, *peer = NULL; + int res = 0; /* Initialize a random secret */ if (!cookie_initialized) { @@ -783,6 +785,7 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie, /* Create buffer with peer's address and port */ if (!BIO_ADDR_rawaddress(peer, NULL, &length)) { BIO_printf(bio_err, "Failed getting peer address\n"); + BIO_ADDR_free(lpeer); return 0; } OPENSSL_assert(length != 0); @@ -793,26 +796,31 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie, memcpy(buffer, &port, sizeof(port)); BIO_ADDR_rawaddress(peer, buffer + sizeof(port), NULL); - /* Calculate HMAC of buffer using the secret */ - HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, - buffer, length, cookie, cookie_len); - + if (EVP_Q_mac(NULL, "HMAC", NULL, "SHA1", NULL, + cookie_secret, COOKIE_SECRET_LENGTH, buffer, length, + cookie, DTLS1_COOKIE_LENGTH, cookie_len) == NULL) { + BIO_printf(bio_err, + "Error calculating HMAC-SHA1 of buffer with secret\n"); + goto end; + } + res = 1; +end: OPENSSL_free(buffer); BIO_ADDR_free(lpeer); - return 1; + return res; } -int verify_cookie_callback(SSL *ssl, const unsigned char *cookie, - unsigned int cookie_len) +int verify_stateless_cookie_callback(SSL *ssl, const unsigned char *cookie, + size_t cookie_len) { unsigned char result[EVP_MAX_MD_SIZE]; - unsigned int resultlength; + size_t resultlength; /* Note: we check cookie_initialized because if it's not, * it cannot be valid */ if (cookie_initialized - && generate_cookie_callback(ssl, result, &resultlength) + && generate_stateless_cookie_callback(ssl, result, &resultlength) && cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0) return 1; @@ -820,21 +828,21 @@ int verify_cookie_callback(SSL *ssl, const unsigned char *cookie, return 0; } -int generate_stateless_cookie_callback(SSL *ssl, unsigned char *cookie, - size_t *cookie_len) +int generate_cookie_callback(SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len) { - unsigned int temp; - int res = generate_cookie_callback(ssl, cookie, &temp); + size_t temp = 0; + int res = generate_stateless_cookie_callback(ssl, cookie, &temp); if (res != 0) - *cookie_len = temp; + *cookie_len = (unsigned int)temp; return res; } -int verify_stateless_cookie_callback(SSL *ssl, const unsigned char *cookie, - size_t cookie_len) +int verify_cookie_callback(SSL *ssl, const unsigned char *cookie, + unsigned int cookie_len) { - return verify_cookie_callback(ssl, cookie, cookie_len); + return verify_stateless_cookie_callback(ssl, cookie, cookie_len); } #endif @@ -898,6 +906,7 @@ static int set_cert_cb(SSL *ssl, void *arg) SSL_EXCERT *exc = arg; #ifdef CERT_CB_TEST_RETRY static int retry_cnt; + if (retry_cnt < 5) { retry_cnt++; BIO_printf(bio_err, @@ -996,6 +1005,7 @@ void ssl_excert_free(SSL_EXCERT *exc) int load_excert(SSL_EXCERT **pexc) { SSL_EXCERT *exc = *pexc; + if (exc == NULL) return 1; /* If nothing in list, free and set to NULL */ @@ -1015,16 +1025,15 @@ int load_excert(SSL_EXCERT **pexc) return 0; if (exc->keyfile != NULL) { exc->key = load_key(exc->keyfile, exc->keyform, - 0, NULL, NULL, "Server Key"); + 0, NULL, NULL, "server key"); } else { exc->key = load_key(exc->certfile, exc->certform, - 0, NULL, NULL, "Server Key"); + 0, NULL, NULL, "server key"); } if (exc->key == NULL) return 0; if (exc->chainfile != NULL) { - if (!load_certs(exc->chainfile, &exc->chain, FORMAT_PEM, NULL, - "Server Chain")) + if (!load_certs(exc->chainfile, 0, &exc->chain, NULL, "server chain")) return 0; } } @@ -1080,11 +1089,11 @@ int args_excert(int opt, SSL_EXCERT **pexc) exc->build_chain = 1; break; case OPT_X_CERTFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &exc->certform)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &exc->certform)) return 0; break; case OPT_X_KEYFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &exc->keyform)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &exc->keyform)) return 0; break; } @@ -1102,6 +1111,7 @@ static void print_raw_cipherlist(SSL *s) const unsigned char *rlist; static const unsigned char scsv_id[] = { 0, 0xFF }; size_t i, rlistlen, num; + if (!SSL_is_server(s)) return; num = SSL_get0_raw_cipherlist(s, NULL); @@ -1210,7 +1220,7 @@ void print_ssl_summary(SSL *s) c = SSL_get_current_cipher(s); BIO_printf(bio_err, "Ciphersuite: %s\n", SSL_CIPHER_get_name(c)); do_print_sigalgs(bio_err, s, 0); - peer = SSL_get_peer_certificate(s); + peer = SSL_get0_peer_certificate(s); if (peer != NULL) { int nid; @@ -1226,7 +1236,6 @@ void print_ssl_summary(SSL *s) } else { BIO_puts(bio_err, "No peer certificate\n"); } - X509_free(peer); #ifndef OPENSSL_NO_EC ssl_print_point_formats(bio_err, s); if (SSL_is_server(s)) @@ -1248,12 +1257,10 @@ int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, for (i = 0; i < sk_OPENSSL_STRING_num(str); i += 2) { const char *flag = sk_OPENSSL_STRING_value(str, i); const char *arg = sk_OPENSSL_STRING_value(str, i + 1); + if (SSL_CONF_cmd(cctx, flag, arg) <= 0) { - if (arg != NULL) - BIO_printf(bio_err, "Error with command: \"%s %s\"\n", - flag, arg); - else - BIO_printf(bio_err, "Error with command: \"%s\"\n", flag); + BIO_printf(bio_err, "Call to SSL_CONF_cmd(%s, %s) failed\n", + flag, arg == NULL ? "" : arg); ERR_print_errors(bio_err); return 0; } @@ -1269,17 +1276,20 @@ int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, static int add_crls_store(X509_STORE *st, STACK_OF(X509_CRL) *crls) { X509_CRL *crl; - int i; + int i, ret = 1; + for (i = 0; i < sk_X509_CRL_num(crls); i++) { crl = sk_X509_CRL_value(crls, i); - X509_STORE_add_crl(st, crl); + if (!X509_STORE_add_crl(st, crl)) + ret = 0; } - return 1; + return ret; } int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download) { X509_STORE *st; + st = SSL_CTX_get_cert_store(ctx); add_crls_store(st, crls); if (crl_download) @@ -1289,27 +1299,38 @@ int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download) int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath, const char *vfyCAfile, + const char *vfyCAstore, const char *chCApath, const char *chCAfile, + const char *chCAstore, STACK_OF(X509_CRL) *crls, int crl_download) { X509_STORE *vfy = NULL, *ch = NULL; int rv = 0; - if (vfyCApath != NULL || vfyCAfile != NULL) { + + if (vfyCApath != NULL || vfyCAfile != NULL || vfyCAstore != NULL) { vfy = X509_STORE_new(); if (vfy == NULL) goto err; - if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath)) + if (vfyCAfile != NULL && !X509_STORE_load_file(vfy, vfyCAfile)) + goto err; + if (vfyCApath != NULL && !X509_STORE_load_path(vfy, vfyCApath)) + goto err; + if (vfyCAstore != NULL && !X509_STORE_load_store(vfy, vfyCAstore)) goto err; add_crls_store(vfy, crls); SSL_CTX_set1_verify_cert_store(ctx, vfy); if (crl_download) store_setup_crl_download(vfy); } - if (chCApath != NULL || chCAfile != NULL) { + if (chCApath != NULL || chCAfile != NULL || chCAstore != NULL) { ch = X509_STORE_new(); if (ch == NULL) goto err; - if (!X509_STORE_load_locations(ch, chCAfile, chCApath)) + if (chCAfile != NULL && !X509_STORE_load_file(ch, chCAfile)) + goto err; + if (chCApath != NULL && !X509_STORE_load_path(ch, chCApath)) + goto err; + if (chCAstore != NULL && !X509_STORE_load_store(ch, chCAstore)) goto err; SSL_CTX_set1_chain_cert_store(ctx, ch); } @@ -1362,6 +1383,7 @@ static int security_callback_debug(const SSL *s, const SSL_CTX *ctx, int rv, show_bits = 1, cert_md = 0; const char *nm; int show_nm; + rv = sdb->old_cb(s, ctx, op, bits, nid, other, ex); if (rv == 1 && sdb->verbose < 2) return 1; @@ -1410,27 +1432,26 @@ static int security_callback_debug(const SSL *s, const SSL_CTX *ctx, BIO_puts(sdb->out, cname); } break; -#endif -#ifndef OPENSSL_NO_DH - case SSL_SECOP_OTHER_DH: - { - DH *dh = other; - BIO_printf(sdb->out, "%d", DH_bits(dh)); - break; - } #endif case SSL_SECOP_OTHER_CERT: { if (cert_md) { int sig_nid = X509_get_signature_nid(other); + BIO_puts(sdb->out, OBJ_nid2sn(sig_nid)); } else { EVP_PKEY *pkey = X509_get0_pubkey(other); - const char *algname = ""; - EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, - &algname, EVP_PKEY_get0_asn1(pkey)); - BIO_printf(sdb->out, "%s, bits=%d", - algname, EVP_PKEY_bits(pkey)); + + if (pkey == NULL) { + BIO_printf(sdb->out, "Public key missing"); + } else { + const char *algname = ""; + + EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, + &algname, EVP_PKEY_get0_asn1(pkey)); + BIO_printf(sdb->out, "%s, bits=%d", + algname, EVP_PKEY_get_bits(pkey)); + } } break; } diff --git a/crypto/openssl/apps/s_socket.c b/crypto/openssl/apps/lib/s_socket.c similarity index 88% rename from crypto/openssl/apps/s_socket.c rename to crypto/openssl/apps/lib/s_socket.c index 96f16d2931cd..059afe47b904 100644 --- a/crypto/openssl/apps/s_socket.c +++ b/crypto/openssl/apps/lib/s_socket.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -26,12 +26,27 @@ typedef unsigned int u_int; #endif +#ifdef _WIN32 +# include + +/* MSVC renamed some POSIX functions to have an underscore prefix. */ +# ifdef _MSC_VER +# define getpid _getpid +# endif +#endif + #ifndef OPENSSL_NO_SOCK # include "apps.h" # include "s_apps.h" # include "internal/sockets.h" +# if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +# endif + # include # include @@ -160,7 +175,9 @@ int init_client(int *sock, const char *host, const char *port, if (*sock == INVALID_SOCKET) { if (bindaddr != NULL && !found) { BIO_printf(bio_err, "Can't bind %saddress for %s%s%s\n", +#ifdef AF_INET6 BIO_ADDRINFO_family(res) == AF_INET6 ? "IPv6 " : +#endif BIO_ADDRINFO_family(res) == AF_INET ? "IPv4 " : BIO_ADDRINFO_family(res) == AF_UNIX ? "unix " : "", bindhost != NULL ? bindhost : "", @@ -183,6 +200,42 @@ int init_client(int *sock, const char *host, const char *port, return ret; } +int report_server_accept(BIO *out, int asock, int with_address, int with_pid) +{ + int success = 1; + + if (BIO_printf(out, "ACCEPT") <= 0) + return 0; + if (with_address) { + union BIO_sock_info_u info; + char *hostname = NULL; + char *service = NULL; + + if ((info.addr = BIO_ADDR_new()) != NULL + && BIO_sock_info(asock, BIO_SOCK_INFO_ADDRESS, &info) + && (hostname = BIO_ADDR_hostname_string(info.addr, 1)) != NULL + && (service = BIO_ADDR_service_string(info.addr, 1)) != NULL) { + success = BIO_printf(out, + strchr(hostname, ':') == NULL + ? /* IPv4 */ " %s:%s" + : /* IPv6 */ " [%s]:%s", + hostname, service) > 0; + } else { + (void)BIO_printf(out, "unknown:error\n"); + success = 0; + } + OPENSSL_free(hostname); + OPENSSL_free(service); + BIO_ADDR_free(info.addr); + } + if (with_pid) + success = success && BIO_printf(out, " PID=%d", getpid()) > 0; + success = success && BIO_printf(out, "\n") > 0; + (void)BIO_flush(out); + + return success; +} + /* * do_server - helper routine to perform a server operation * @accept_sock: pointer to storage of resulting socket. @@ -239,6 +292,7 @@ int do_server(int *accept_sock, const char *host, const char *port, sock_protocol = BIO_ADDRINFO_protocol(res); sock_address = BIO_ADDRINFO_address(res); next = BIO_ADDRINFO_next(res); +#ifdef AF_INET6 if (sock_family == AF_INET6) sock_options |= BIO_SOCK_V6_ONLY; if (next != NULL @@ -257,6 +311,7 @@ int do_server(int *accept_sock, const char *host, const char *port, sock_options &= ~BIO_SOCK_V6_ONLY; } } +#endif asock = BIO_socket(sock_family, sock_type, sock_protocol, 0); if (asock == INVALID_SOCKET && sock_family_fallback != AF_UNSPEC) { @@ -296,36 +351,10 @@ int do_server(int *accept_sock, const char *host, const char *port, BIO_ADDRINFO_free(res); res = NULL; - if (sock_port == 0) { - /* dynamically allocated port, report which one */ - union BIO_sock_info_u info; - char *hostname = NULL; - char *service = NULL; - int success = 0; - - if ((info.addr = BIO_ADDR_new()) != NULL - && BIO_sock_info(asock, BIO_SOCK_INFO_ADDRESS, &info) - && (hostname = BIO_ADDR_hostname_string(info.addr, 1)) != NULL - && (service = BIO_ADDR_service_string(info.addr, 1)) != NULL - && BIO_printf(bio_s_out, - strchr(hostname, ':') == NULL - ? /* IPv4 */ "ACCEPT %s:%s\n" - : /* IPv6 */ "ACCEPT [%s]:%s\n", - hostname, service) > 0) - success = 1; - - (void)BIO_flush(bio_s_out); - OPENSSL_free(hostname); - OPENSSL_free(service); - BIO_ADDR_free(info.addr); - if (!success) { - BIO_closesocket(asock); - ERR_print_errors(bio_err); - goto end; - } - } else { - (void)BIO_printf(bio_s_out, "ACCEPT\n"); - (void)BIO_flush(bio_s_out); + if (!report_server_accept(bio_s_out, asock, sock_port == 0, 0)) { + BIO_closesocket(asock); + ERR_print_errors(bio_err); + goto end; } if (accept_sock != NULL) @@ -402,4 +431,25 @@ int do_server(int *accept_sock, const char *host, const char *port, return ret; } +void do_ssl_shutdown(SSL *ssl) +{ + int ret; + + do { + /* We only do unidirectional shutdown */ + ret = SSL_shutdown(ssl); + if (ret < 0) { + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_ASYNC: + case SSL_ERROR_WANT_ASYNC_JOB: + /* We just do busy waiting. Nothing clever */ + continue; + } + ret = 0; + } + } while (ret < 0); +} + #endif /* OPENSSL_NO_SOCK */ diff --git a/crypto/openssl/apps/lib/tlssrp_depr.c b/crypto/openssl/apps/lib/tlssrp_depr.c new file mode 100644 index 000000000000..91c19b096e9a --- /dev/null +++ b/crypto/openssl/apps/lib/tlssrp_depr.c @@ -0,0 +1,231 @@ +/* + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005 Nokia. 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 + */ + +/* + * This file is to enable backwards compatibility for the SRP features of + * s_client, s_server and ciphers. All of those features are deprecated and will + * eventually disappear. In the meantime, to continue to support them, we + * need to access deprecated SRP APIs. + */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include +#include +#include +#include +#include "apps_ui.h" +#include "apps.h" +#include "s_apps.h" + +static int srp_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g) +{ + BN_CTX *bn_ctx = BN_CTX_new(); + BIGNUM *p = BN_new(); + BIGNUM *r = BN_new(); + int ret = + g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) && + BN_check_prime(N, bn_ctx, NULL) == 1 && + p != NULL && BN_rshift1(p, N) && + /* p = (N-1)/2 */ + BN_check_prime(p, bn_ctx, NULL) == 1 && + r != NULL && + /* verify g^((N-1)/2) == -1 (mod N) */ + BN_mod_exp(r, g, p, N, bn_ctx) && + BN_add_word(r, 1) && BN_cmp(r, N) == 0; + + BN_free(r); + BN_free(p); + BN_CTX_free(bn_ctx); + return ret; +} + +/*- + * This callback is used here for two purposes: + * - extended debugging + * - making some primality tests for unknown groups + * The callback is only called for a non default group. + * + * An application does not need the call back at all if + * only the standard groups are used. In real life situations, + * client and server already share well known groups, + * thus there is no need to verify them. + * Furthermore, in case that a server actually proposes a group that + * is not one of those defined in RFC 5054, it is more appropriate + * to add the group to a static list and then compare since + * primality tests are rather cpu consuming. + */ + +static int ssl_srp_verify_param_cb(SSL *s, void *arg) +{ + SRP_ARG *srp_arg = (SRP_ARG *)arg; + BIGNUM *N = NULL, *g = NULL; + + if (((N = SSL_get_srp_N(s)) == NULL) || ((g = SSL_get_srp_g(s)) == NULL)) + return 0; + if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) { + BIO_printf(bio_err, "SRP parameters:\n"); + BIO_printf(bio_err, "\tN="); + BN_print(bio_err, N); + BIO_printf(bio_err, "\n\tg="); + BN_print(bio_err, g); + BIO_printf(bio_err, "\n"); + } + + if (SRP_check_known_gN_param(g, N)) + return 1; + + if (srp_arg->amp == 1) { + if (srp_arg->debug) + BIO_printf(bio_err, + "SRP param N and g are not known params, going to check deeper.\n"); + + /* + * The srp_moregroups is a real debugging feature. Implementors + * should rather add the value to the known ones. The minimal size + * has already been tested. + */ + if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g)) + return 1; + } + BIO_printf(bio_err, "SRP param N and g rejected.\n"); + return 0; +} + +#define PWD_STRLEN 1024 + +static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg) +{ + SRP_ARG *srp_arg = (SRP_ARG *)arg; + char *pass = app_malloc(PWD_STRLEN + 1, "SRP password buffer"); + PW_CB_DATA cb_tmp; + int l; + + cb_tmp.password = (char *)srp_arg->srppassin; + cb_tmp.prompt_info = "SRP user"; + if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp)) < 0) { + BIO_printf(bio_err, "Can't read Password\n"); + OPENSSL_free(pass); + return NULL; + } + *(pass + l) = '\0'; + + return pass; +} + +int set_up_srp_arg(SSL_CTX *ctx, SRP_ARG *srp_arg, int srp_lateuser, int c_msg, + int c_debug) +{ + if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg->srplogin)) { + BIO_printf(bio_err, "Unable to set SRP username\n"); + return 0; + } + srp_arg->msg = c_msg; + srp_arg->debug = c_debug; + SSL_CTX_set_srp_cb_arg(ctx, &srp_arg); + SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb); + SSL_CTX_set_srp_strength(ctx, srp_arg->strength); + if (c_msg || c_debug || srp_arg->amp == 0) + SSL_CTX_set_srp_verify_param_callback(ctx, ssl_srp_verify_param_cb); + + return 1; +} + +static char *dummy_srp(SSL *ssl, void *arg) +{ + return ""; +} + +void set_up_dummy_srp(SSL_CTX *ctx) +{ + SSL_CTX_set_srp_client_pwd_callback(ctx, dummy_srp); +} + +/* + * This callback pretends to require some asynchronous logic in order to + * obtain a verifier. When the callback is called for a new connection we + * return with a negative value. This will provoke the accept etc to return + * with an LOOKUP_X509. The main logic of the reinvokes the suspended call + * (which would normally occur after a worker has finished) and we set the + * user parameters. + */ +static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) +{ + srpsrvparm *p = (srpsrvparm *) arg; + int ret = SSL3_AL_FATAL; + + if (p->login == NULL && p->user == NULL) { + p->login = SSL_get_srp_username(s); + BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login); + return -1; + } + + if (p->user == NULL) { + BIO_printf(bio_err, "User %s doesn't exist\n", p->login); + goto err; + } + + if (SSL_set_srp_server_param + (s, p->user->N, p->user->g, p->user->s, p->user->v, + p->user->info) < 0) { + *ad = SSL_AD_INTERNAL_ERROR; + goto err; + } + BIO_printf(bio_err, + "SRP parameters set: username = \"%s\" info=\"%s\" \n", + p->login, p->user->info); + ret = SSL_ERROR_NONE; + + err: + SRP_user_pwd_free(p->user); + p->user = NULL; + p->login = NULL; + return ret; +} + +int set_up_srp_verifier_file(SSL_CTX *ctx, srpsrvparm *srp_callback_parm, + char *srpuserseed, char *srp_verifier_file) +{ + int ret; + + srp_callback_parm->vb = SRP_VBASE_new(srpuserseed); + srp_callback_parm->user = NULL; + srp_callback_parm->login = NULL; + + if (srp_callback_parm->vb == NULL) { + BIO_printf(bio_err, "Failed to initialize SRP verifier file \n"); + return 0; + } + if ((ret = + SRP_VBASE_init(srp_callback_parm->vb, + srp_verifier_file)) != SRP_NO_ERROR) { + BIO_printf(bio_err, + "Cannot initialize SRP verifier file \"%s\":ret=%d\n", + srp_verifier_file, ret); + return 0; + } + SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback); + SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm); + SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb); + + return 1; +} + +void lookup_srp_user(srpsrvparm *srp_callback_parm, BIO *bio_s_out) +{ + SRP_user_pwd_free(srp_callback_parm->user); + srp_callback_parm->user = SRP_VBASE_get1_by_user(srp_callback_parm->vb, + srp_callback_parm->login); + + if (srp_callback_parm->user != NULL) + BIO_printf(bio_s_out, "LOOKUP done %s\n", + srp_callback_parm->user->info); + else + BIO_printf(bio_s_out, "LOOKUP not successful\n"); +} diff --git a/crypto/openssl/apps/lib/vms_decc_argv.c b/crypto/openssl/apps/lib/vms_decc_argv.c new file mode 100644 index 000000000000..031e5afdeca0 --- /dev/null +++ b/crypto/openssl/apps/lib/vms_decc_argv.c @@ -0,0 +1,72 @@ +/* + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "platform.h" /* for copy_argv() */ + +char **newargv = NULL; + +static void cleanup_argv(void) +{ + OPENSSL_free(newargv); + newargv = NULL; +} + +char **copy_argv(int *argc, char *argv[]) +{ + /*- + * The note below is for historical purpose. On VMS now we always + * copy argv "safely." + * + * 2011-03-22 SMS. + * If we have 32-bit pointers everywhere, then we're safe, and + * we bypass this mess, as on non-VMS systems. + * Problem 1: Compaq/HP C before V7.3 always used 32-bit + * pointers for argv[]. + * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers + * everywhere else, we always allocate and use a 64-bit + * duplicate of argv[]. + * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed + * to NULL-terminate a 64-bit argv[]. (As this was written, the + * compiler ECO was available only on IA64.) + * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a + * 64-bit argv[argc] for NULL, and, if necessary, use a + * (properly) NULL-terminated (64-bit) duplicate of argv[]. + * The same code is used in either case to duplicate argv[]. + * Some of these decisions could be handled in preprocessing, + * but the code tends to get even uglier, and the penalty for + * deciding at compile- or run-time is tiny. + */ + + int i, count = *argc; + char **p = newargv; + + cleanup_argv(); + + /* + * We purposefully use OPENSSL_malloc() rather than app_malloc() here, + * to avoid symbol name clashes in test programs that would otherwise + * get them when linking with all of libapps.a. + * See comment in test/build.info. + */ + newargv = OPENSSL_malloc(sizeof(*newargv) * (count + 1)); + if (newargv == NULL) + return NULL; + + /* Register automatic cleanup on first use */ + if (p == NULL) + OPENSSL_atexit(cleanup_argv); + + for (i = 0; i < count; i++) + newargv[i] = argv[i]; + newargv[i] = NULL; + *argc = i; + return newargv; +} diff --git a/crypto/openssl/apps/lib/vms_term_sock.c b/crypto/openssl/apps/lib/vms_term_sock.c new file mode 100644 index 000000000000..97fb3943265c --- /dev/null +++ b/crypto/openssl/apps/lib/vms_term_sock.c @@ -0,0 +1,591 @@ +/* + * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016 VMS Software, Inc. 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 + */ + +#ifdef __VMS +# define OPENSSL_SYS_VMS +# pragma message disable DOLLARID + + +# include + +# if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS) +/* + * On VMS, you need to define this to get the declaration of fileno(). The + * value 2 is to make sure no function defined in POSIX-2 is left undefined. + */ +# define _POSIX_C_SOURCE 2 +# endif + +# include + +# undef _POSIX_C_SOURCE + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# ifdef __alpha +# include +# else +typedef struct _iosb { /* Copied from IOSBDEF.H for Alpha */ +# pragma __nomember_alignment + __union { + __struct { + unsigned short int iosb$w_status; /* Final I/O status */ + __union { + __struct { /* 16-bit byte count variant */ + unsigned short int iosb$w_bcnt; /* 16-bit byte count */ + __union { + unsigned int iosb$l_dev_depend; /* 32-bit device dependent info */ + unsigned int iosb$l_pid; /* 32-bit pid */ + } iosb$r_l; + } iosb$r_bcnt_16; + __struct { /* 32-bit byte count variant */ + unsigned int iosb$l_bcnt; /* 32-bit byte count (unaligned) */ + unsigned short int iosb$w_dev_depend_high; /* 16-bit device dependent info */ + } iosb$r_bcnt_32; + } iosb$r_devdepend; + } iosb$r_io_64; + __struct { + __union { + unsigned int iosb$l_getxxi_status; /* Final GETxxI status */ + unsigned int iosb$l_reg_status; /* Final $Registry status */ + } iosb$r_l_status; + unsigned int iosb$l_reserved; /* Reserved field */ + } iosb$r_get_64; + } iosb$r_io_get; +} IOSB; + +# if !defined(__VAXC) +# define iosb$w_status iosb$r_io_get.iosb$r_io_64.iosb$w_status +# define iosb$w_bcnt iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_16.iosb$w_bcnt +# define iosb$r_l iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_16.iosb$r_l +# define iosb$l_dev_depend iosb$r_l.iosb$l_dev_depend +# define iosb$l_pid iosb$r_l.iosb$l_pid +# define iosb$l_bcnt iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_32.iosb$l_bcnt +# define iosb$w_dev_depend_high iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_32.iosb$w_dev_depend_high +# define iosb$l_getxxi_status iosb$r_io_get.iosb$r_get_64.iosb$r_l_status.iosb$l_getxxi_status +# define iosb$l_reg_status iosb$r_io_get.iosb$r_get_64.iosb$r_l_status.iosb$l_reg_status +# endif /* #if !defined(__VAXC) */ + +# endif /* End of IOSBDEF */ + +# include +# include +# include +# include +# include +# include + +# include "vms_term_sock.h" + +# ifdef __alpha +static struct _iosb TerminalDeviceIosb; +# else +IOSB TerminalDeviceIosb; +# endif + +static char TerminalDeviceBuff[255 + 2]; +static int TerminalSocketPair[2] = {0, 0}; +static unsigned short TerminalDeviceChan = 0; + +static int CreateSocketPair (int, int, int, int *); +static void SocketPairTimeoutAst (int); +static int TerminalDeviceAst (int); +static void LogMessage (char *, ...); + +/* +** Socket Pair Timeout Value (must be 0-59 seconds) +*/ +# define SOCKET_PAIR_TIMEOUT_VALUE 20 + +/* +** Socket Pair Timeout Block which is passed to timeout AST +*/ +typedef struct _SocketPairTimeoutBlock { + unsigned short SockChan1; + unsigned short SockChan2; +} SPTB; + +# ifdef TERM_SOCK_TEST + +/*----------------------------------------------------------------------------*/ +/* */ +/*----------------------------------------------------------------------------*/ +int main (int argc, char *argv[], char *envp[]) +{ + char TermBuff[80]; + int TermSock, + status, + len; + + LogMessage ("Enter 'q' or 'Q' to quit ..."); + while (OPENSSL_strcasecmp (TermBuff, "Q")) { + /* + ** Create the terminal socket + */ + status = TerminalSocket (TERM_SOCK_CREATE, &TermSock); + if (status != TERM_SOCK_SUCCESS) + exit (1); + + /* + ** Process the terminal input + */ + LogMessage ("Waiting on terminal I/O ...\n"); + len = recv (TermSock, TermBuff, sizeof(TermBuff), 0) ; + TermBuff[len] = '\0'; + LogMessage ("Received terminal I/O [%s]", TermBuff); + + /* + ** Delete the terminal socket + */ + status = TerminalSocket (TERM_SOCK_DELETE, &TermSock); + if (status != TERM_SOCK_SUCCESS) + exit (1); + } + + return 1; + +} +# endif + +/*----------------------------------------------------------------------------*/ +/* */ +/*----------------------------------------------------------------------------*/ +int TerminalSocket (int FunctionCode, int *ReturnSocket) +{ + int status; + $DESCRIPTOR (TerminalDeviceDesc, "SYS$COMMAND"); + + /* + ** Process the requested function code + */ + switch (FunctionCode) { + case TERM_SOCK_CREATE: + /* + ** Create a socket pair + */ + status = CreateSocketPair (AF_INET, SOCK_STREAM, 0, TerminalSocketPair); + if (status == -1) { + LogMessage ("TerminalSocket: CreateSocketPair () - %08X", status); + if (TerminalSocketPair[0]) + close (TerminalSocketPair[0]); + if (TerminalSocketPair[1]) + close (TerminalSocketPair[1]); + return TERM_SOCK_FAILURE; + } + + /* + ** Assign a channel to the terminal device + */ + status = sys$assign (&TerminalDeviceDesc, + &TerminalDeviceChan, + 0, 0, 0); + if (! (status & 1)) { + LogMessage ("TerminalSocket: SYS$ASSIGN () - %08X", status); + close (TerminalSocketPair[0]); + close (TerminalSocketPair[1]); + return TERM_SOCK_FAILURE; + } + + /* + ** Queue an async IO to the terminal device + */ + status = sys$qio (EFN$C_ENF, + TerminalDeviceChan, + IO$_READVBLK, + &TerminalDeviceIosb, + TerminalDeviceAst, + 0, + TerminalDeviceBuff, + sizeof(TerminalDeviceBuff) - 2, + 0, 0, 0, 0); + if (! (status & 1)) { + LogMessage ("TerminalSocket: SYS$QIO () - %08X", status); + close (TerminalSocketPair[0]); + close (TerminalSocketPair[1]); + return TERM_SOCK_FAILURE; + } + + /* + ** Return the input side of the socket pair + */ + *ReturnSocket = TerminalSocketPair[1]; + break; + + case TERM_SOCK_DELETE: + /* + ** Cancel any pending IO on the terminal channel + */ + status = sys$cancel (TerminalDeviceChan); + if (! (status & 1)) { + LogMessage ("TerminalSocket: SYS$CANCEL () - %08X", status); + close (TerminalSocketPair[0]); + close (TerminalSocketPair[1]); + return TERM_SOCK_FAILURE; + } + + /* + ** Deassign the terminal channel + */ + status = sys$dassgn (TerminalDeviceChan); + if (! (status & 1)) { + LogMessage ("TerminalSocket: SYS$DASSGN () - %08X", status); + close (TerminalSocketPair[0]); + close (TerminalSocketPair[1]); + return TERM_SOCK_FAILURE; + } + + /* + ** Close the terminal socket pair + */ + close (TerminalSocketPair[0]); + close (TerminalSocketPair[1]); + + /* + ** Return the initialized socket + */ + *ReturnSocket = 0; + break; + + default: + /* + ** Invalid function code + */ + LogMessage ("TerminalSocket: Invalid Function Code - %d", FunctionCode); + return TERM_SOCK_FAILURE; + break; + } + + /* + ** Return success + */ + return TERM_SOCK_SUCCESS; + +} + +/*----------------------------------------------------------------------------*/ +/* */ +/*----------------------------------------------------------------------------*/ +static int CreateSocketPair (int SocketFamily, + int SocketType, + int SocketProtocol, + int *SocketPair) +{ + struct dsc$descriptor AscTimeDesc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL}; + static const char* LocalHostAddr = {"127.0.0.1"}; + unsigned short TcpAcceptChan = 0, + TcpDeviceChan = 0; + unsigned long BinTimeBuff[2]; + struct sockaddr_in sin; + char AscTimeBuff[32]; + short LocalHostPort; + int status; + unsigned int slen; + +# ifdef __alpha + struct _iosb iosb; +# else + IOSB iosb; +# endif + + int SockDesc1 = 0, + SockDesc2 = 0; + SPTB sptb; + $DESCRIPTOR (TcpDeviceDesc, "TCPIP$DEVICE"); + + /* + ** Create a socket + */ + SockDesc1 = socket (SocketFamily, SocketType, 0); + if (SockDesc1 < 0) { + LogMessage ("CreateSocketPair: socket () - %d", errno); + return -1; + } + + /* + ** Initialize the socket information + */ + slen = sizeof(sin); + memset ((char *) &sin, 0, slen); + sin.sin_family = SocketFamily; + sin.sin_addr.s_addr = inet_addr (LocalHostAddr); + sin.sin_port = 0; + + /* + ** Bind the socket to the local IP + */ + status = bind (SockDesc1, (struct sockaddr *) &sin, slen); + if (status < 0) { + LogMessage ("CreateSocketPair: bind () - %d", errno); + close (SockDesc1); + return -1; + } + + /* + ** Get the socket name so we can save the port number + */ + status = getsockname (SockDesc1, (struct sockaddr *) &sin, &slen); + if (status < 0) { + LogMessage ("CreateSocketPair: getsockname () - %d", errno); + close (SockDesc1); + return -1; + } else + LocalHostPort = sin.sin_port; + + /* + ** Setup a listen for the socket + */ + listen (SockDesc1, 5); + + /* + ** Get the binary (64-bit) time of the specified timeout value + */ + sprintf (AscTimeBuff, "0 0:0:%02d.00", SOCKET_PAIR_TIMEOUT_VALUE); + AscTimeDesc.dsc$w_length = strlen (AscTimeBuff); + AscTimeDesc.dsc$a_pointer = AscTimeBuff; + status = sys$bintim (&AscTimeDesc, BinTimeBuff); + if (! (status & 1)) { + LogMessage ("CreateSocketPair: SYS$BINTIM () - %08X", status); + close (SockDesc1); + return -1; + } + + /* + ** Assign another channel to the TCP/IP device for the accept. + ** This is the channel that ends up being connected to. + */ + status = sys$assign (&TcpDeviceDesc, &TcpDeviceChan, 0, 0, 0); + if (! (status & 1)) { + LogMessage ("CreateSocketPair: SYS$ASSIGN () - %08X", status); + close (SockDesc1); + return -1; + } + + /* + ** Get the channel of the first socket for the accept + */ + TcpAcceptChan = decc$get_sdc (SockDesc1); + + /* + ** Perform the accept using $QIO so we can do this asynchronously + */ + status = sys$qio (EFN$C_ENF, + TcpAcceptChan, + IO$_ACCESS | IO$M_ACCEPT, + &iosb, + 0, 0, 0, 0, 0, + &TcpDeviceChan, + 0, 0); + if (! (status & 1)) { + LogMessage ("CreateSocketPair: SYS$QIO () - %08X", status); + close (SockDesc1); + sys$dassgn (TcpDeviceChan); + return -1; + } + + /* + ** Create the second socket to do the connect + */ + SockDesc2 = socket (SocketFamily, SocketType, 0); + if (SockDesc2 < 0) { + LogMessage ("CreateSocketPair: socket () - %d", errno); + sys$cancel (TcpAcceptChan); + close (SockDesc1); + sys$dassgn (TcpDeviceChan); + return (-1) ; + } + + /* + ** Setup the Socket Pair Timeout Block + */ + sptb.SockChan1 = TcpAcceptChan; + sptb.SockChan2 = decc$get_sdc (SockDesc2); + + /* + ** Before we block on the connect, set a timer that can cancel I/O on our + ** two sockets if it never connects. + */ + status = sys$setimr (EFN$C_ENF, + BinTimeBuff, + SocketPairTimeoutAst, + &sptb, + 0); + if (! (status & 1)) { + LogMessage ("CreateSocketPair: SYS$SETIMR () - %08X", status); + sys$cancel (TcpAcceptChan); + close (SockDesc1); + close (SockDesc2); + sys$dassgn (TcpDeviceChan); + return -1; + } + + /* + ** Now issue the connect + */ + memset ((char *) &sin, 0, sizeof(sin)) ; + sin.sin_family = SocketFamily; + sin.sin_addr.s_addr = inet_addr (LocalHostAddr) ; + sin.sin_port = LocalHostPort ; + + status = connect (SockDesc2, (struct sockaddr *) &sin, sizeof(sin)); + if (status < 0 ) { + LogMessage ("CreateSocketPair: connect () - %d", errno); + sys$cantim (&sptb, 0); + sys$cancel (TcpAcceptChan); + close (SockDesc1); + close (SockDesc2); + sys$dassgn (TcpDeviceChan); + return -1; + } + + /* + ** Wait for the asynch $QIO to finish. Note that if the I/O was aborted + ** (SS$_ABORT), then we probably canceled it from the AST routine - so log + ** a timeout. + */ + status = sys$synch (EFN$C_ENF, &iosb); + if (! (iosb.iosb$w_status & 1)) { + if (iosb.iosb$w_status == SS$_ABORT) + LogMessage ("CreateSocketPair: SYS$QIO(iosb) timeout"); + else { + LogMessage ("CreateSocketPair: SYS$QIO(iosb) - %d", + iosb.iosb$w_status); + sys$cantim (&sptb, 0); + } + close (SockDesc1); + close (SockDesc2); + sys$dassgn (TcpDeviceChan); + return -1; + } + + /* + ** Here we're successfully connected, so cancel the timer, convert the + ** I/O channel to a socket fd, close the listener socket and return the + ** connected pair. + */ + sys$cantim (&sptb, 0); + + close (SockDesc1) ; + SocketPair[0] = SockDesc2 ; + SocketPair[1] = socket_fd (TcpDeviceChan); + + return (0) ; + +} + +/*----------------------------------------------------------------------------*/ +/* */ +/*----------------------------------------------------------------------------*/ +static void SocketPairTimeoutAst (int astparm) +{ + SPTB *sptb = (SPTB *) astparm; + + sys$cancel (sptb->SockChan2); /* Cancel the connect() */ + sys$cancel (sptb->SockChan1); /* Cancel the accept() */ + + return; + +} + +/*----------------------------------------------------------------------------*/ +/* */ +/*----------------------------------------------------------------------------*/ +static int TerminalDeviceAst (int astparm) +{ + int status; + + /* + ** Terminate the terminal buffer + */ + TerminalDeviceBuff[TerminalDeviceIosb.iosb$w_bcnt] = '\0'; + strcat (TerminalDeviceBuff, "\n"); + + /* + ** Send the data read from the terminal device through the socket pair + */ + send (TerminalSocketPair[0], TerminalDeviceBuff, + TerminalDeviceIosb.iosb$w_bcnt + 1, 0); + + /* + ** Queue another async IO to the terminal device + */ + status = sys$qio (EFN$C_ENF, + TerminalDeviceChan, + IO$_READVBLK, + &TerminalDeviceIosb, + TerminalDeviceAst, + 0, + TerminalDeviceBuff, + sizeof(TerminalDeviceBuff) - 1, + 0, 0, 0, 0); + + /* + ** Return status + */ + return status; + +} + +/*----------------------------------------------------------------------------*/ +/* */ +/*----------------------------------------------------------------------------*/ +static void LogMessage (char *msg, ...) +{ + char *Month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + static unsigned int pid = 0; + va_list args; + time_t CurTime; + struct tm *LocTime; + char MsgBuff[256]; + + /* + ** Get the process pid + */ + if (pid == 0) + pid = getpid (); + + /* + ** Convert the current time into local time + */ + CurTime = time (NULL); + LocTime = localtime (&CurTime); + + /* + ** Format the message buffer + */ + sprintf (MsgBuff, "%02d-%s-%04d %02d:%02d:%02d [%08X] %s\n", + LocTime->tm_mday, Month[LocTime->tm_mon], + (LocTime->tm_year + 1900), LocTime->tm_hour, LocTime->tm_min, + LocTime->tm_sec, pid, msg); + + /* + ** Get any variable arguments and add them to the print of the message + ** buffer + */ + va_start (args, msg); + vfprintf (stderr, MsgBuff, args); + va_end (args); + + /* + ** Flush standard error output + */ + fsync (fileno (stderr)); + + return; + +} +#endif diff --git a/crypto/openssl/apps/lib/win32_init.c b/crypto/openssl/apps/lib/win32_init.c new file mode 100644 index 000000000000..6d2be0c62942 --- /dev/null +++ b/crypto/openssl/apps/lib/win32_init.c @@ -0,0 +1,307 @@ +/* + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include + +#if defined(CP_UTF8) + +static UINT saved_cp; +static int newargc; +static char **newargv; + +static void cleanup(void) +{ + int i; + + SetConsoleOutputCP(saved_cp); + + for (i = 0; i < newargc; i++) + free(newargv[i]); + + free(newargv); +} + +/* + * Incrementally [re]allocate newargv and keep it NULL-terminated. + */ +static int validate_argv(int argc) +{ + static int size = 0; + + if (argc >= size) { + char **ptr; + + while (argc >= size) + size += 64; + + ptr = realloc(newargv, size * sizeof(newargv[0])); + if (ptr == NULL) + return 0; + + (newargv = ptr)[argc] = NULL; + } else { + newargv[argc] = NULL; + } + + return 1; +} + +static int process_glob(WCHAR *wstr, int wlen) +{ + int i, slash, udlen; + WCHAR saved_char; + WIN32_FIND_DATAW data; + HANDLE h; + + /* + * Note that we support wildcard characters only in filename part + * of the path, and not in directories. Windows users are used to + * this, that's why recursive glob processing is not implemented. + */ + /* + * Start by looking for last slash or backslash, ... + */ + for (slash = 0, i = 0; i < wlen; i++) + if (wstr[i] == L'/' || wstr[i] == L'\\') + slash = i + 1; + /* + * ... then look for asterisk or question mark in the file name. + */ + for (i = slash; i < wlen; i++) + if (wstr[i] == L'*' || wstr[i] == L'?') + break; + + if (i == wlen) + return 0; /* definitely not a glob */ + + saved_char = wstr[wlen]; + wstr[wlen] = L'\0'; + h = FindFirstFileW(wstr, &data); + wstr[wlen] = saved_char; + if (h == INVALID_HANDLE_VALUE) + return 0; /* not a valid glob, just pass... */ + + if (slash) + udlen = WideCharToMultiByte(CP_UTF8, 0, wstr, slash, + NULL, 0, NULL, NULL); + else + udlen = 0; + + do { + int uflen; + char *arg; + + /* + * skip over . and .. + */ + if (data.cFileName[0] == L'.') { + if ((data.cFileName[1] == L'\0') || + (data.cFileName[1] == L'.' && data.cFileName[2] == L'\0')) + continue; + } + + if (!validate_argv(newargc + 1)) + break; + + /* + * -1 below means "scan for trailing '\0' *and* count it", + * so that |uflen| covers even trailing '\0'. + */ + uflen = WideCharToMultiByte(CP_UTF8, 0, data.cFileName, -1, + NULL, 0, NULL, NULL); + + arg = malloc(udlen + uflen); + if (arg == NULL) + break; + + if (udlen) + WideCharToMultiByte(CP_UTF8, 0, wstr, slash, + arg, udlen, NULL, NULL); + + WideCharToMultiByte(CP_UTF8, 0, data.cFileName, -1, + arg + udlen, uflen, NULL, NULL); + + newargv[newargc++] = arg; + } while (FindNextFileW(h, &data)); + + CloseHandle(h); + + return 1; +} + +void win32_utf8argv(int *argc, char **argv[]) +{ + const WCHAR *wcmdline; + WCHAR *warg, *wend, *p; + int wlen, ulen, valid = 1; + char *arg; + + if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) == 0) + return; + + newargc = 0; + newargv = NULL; + if (!validate_argv(newargc)) + return; + + wcmdline = GetCommandLineW(); + if (wcmdline == NULL) return; + + /* + * make a copy of the command line, since we might have to modify it... + */ + wlen = wcslen(wcmdline); + p = _alloca((wlen + 1) * sizeof(WCHAR)); + wcscpy(p, wcmdline); + + while (*p != L'\0') { + int in_quote = 0; + + if (*p == L' ' || *p == L'\t') { + p++; /* skip over whitespace */ + continue; + } + + /* + * Note: because we may need to fiddle with the number of backslashes, + * the argument string is copied into itself. This is safe because + * the number of characters will never expand. + */ + warg = wend = p; + while (*p != L'\0' + && (in_quote || (*p != L' ' && *p != L'\t'))) { + switch (*p) { + case L'\\': + /* + * Microsoft documentation on how backslashes are treated + * is: + * + * + Backslashes are interpreted literally, unless they + * immediately precede a double quotation mark. + * + If an even number of backslashes is followed by a double + * quotation mark, one backslash is placed in the argv array + * for every pair of backslashes, and the double quotation + * mark is interpreted as a string delimiter. + * + If an odd number of backslashes is followed by a double + * quotation mark, one backslash is placed in the argv array + * for every pair of backslashes, and the double quotation + * mark is "escaped" by the remaining backslash, causing a + * literal double quotation mark (") to be placed in argv. + * + * Ref: https://msdn.microsoft.com/en-us/library/17w5ykft.aspx + * + * Though referred page doesn't mention it, multiple qouble + * quotes are also special. Pair of double quotes in quoted + * string is counted as single double quote. + */ + { + const WCHAR *q = p; + int i; + + while (*p == L'\\') + p++; + + if (*p == L'"') { + int i; + + for (i = (p - q) / 2; i > 0; i--) + *wend++ = L'\\'; + + /* + * if odd amount of backslashes before the quote, + * said quote is part of the argument, not a delimiter + */ + if ((p - q) % 2 == 1) + *wend++ = *p++; + } else { + for (i = p - q; i > 0; i--) + *wend++ = L'\\'; + } + } + break; + case L'"': + /* + * Without the preceding backslash (or when preceded with an + * even number of backslashes), the double quote is a simple + * string delimiter and just slightly change the parsing state + */ + if (in_quote && p[1] == L'"') + *wend++ = *p++; + else + in_quote = !in_quote; + p++; + break; + default: + /* + * Any other non-delimiter character is just taken verbatim + */ + *wend++ = *p++; + } + } + + wlen = wend - warg; + + if (wlen == 0 || !process_glob(warg, wlen)) { + if (!validate_argv(newargc + 1)) { + valid = 0; + break; + } + + ulen = 0; + if (wlen > 0) { + ulen = WideCharToMultiByte(CP_UTF8, 0, warg, wlen, + NULL, 0, NULL, NULL); + if (ulen <= 0) + continue; + } + + arg = malloc(ulen + 1); + if (arg == NULL) { + valid = 0; + break; + } + + if (wlen > 0) + WideCharToMultiByte(CP_UTF8, 0, warg, wlen, + arg, ulen, NULL, NULL); + arg[ulen] = '\0'; + + newargv[newargc++] = arg; + } + } + + if (valid) { + saved_cp = GetConsoleOutputCP(); + SetConsoleOutputCP(CP_UTF8); + + *argc = newargc; + *argv = newargv; + + atexit(cleanup); + } else if (newargv != NULL) { + int i; + + for (i = 0; i < newargc; i++) + free(newargv[i]); + + free(newargv); + + newargc = 0; + newargv = NULL; + } + + return; +} +#else +void win32_utf8argv(int *argc, char **argv[]) +{ return; } +#endif diff --git a/crypto/openssl/apps/list.c b/crypto/openssl/apps/list.c new file mode 100644 index 000000000000..514abacfc835 --- /dev/null +++ b/crypto/openssl/apps/list.c @@ -0,0 +1,1706 @@ +/* + * Copyright 1995-2022 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 + */ + +/* We need to use some deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "apps.h" +#include "app_params.h" +#include "progs.h" +#include "opt.h" +#include "names.h" + +static int verbose = 0; +static const char *select_name = NULL; + +/* Checks to see if algorithms are fetchable */ +#define IS_FETCHABLE(type, TYPE) \ + static int is_ ## type ## _fetchable(const TYPE *alg) \ + { \ + TYPE *impl; \ + const char *propq = app_get0_propq(); \ + OSSL_LIB_CTX *libctx = app_get0_libctx(); \ + const char *name = TYPE ## _get0_name(alg); \ + \ + ERR_set_mark(); \ + impl = TYPE ## _fetch(libctx, name, propq); \ + ERR_pop_to_mark(); \ + if (impl == NULL) \ + return 0; \ + TYPE ## _free(impl); \ + return 1; \ + } +IS_FETCHABLE(cipher, EVP_CIPHER) +IS_FETCHABLE(digest, EVP_MD) +IS_FETCHABLE(mac, EVP_MAC) +IS_FETCHABLE(kdf, EVP_KDF) +IS_FETCHABLE(rand, EVP_RAND) +IS_FETCHABLE(keymgmt, EVP_KEYMGMT) +IS_FETCHABLE(signature, EVP_SIGNATURE) +IS_FETCHABLE(kem, EVP_KEM) +IS_FETCHABLE(asym_cipher, EVP_ASYM_CIPHER) +IS_FETCHABLE(keyexch, EVP_KEYEXCH) +IS_FETCHABLE(decoder, OSSL_DECODER) +IS_FETCHABLE(encoder, OSSL_ENCODER) + +#ifndef OPENSSL_NO_DEPRECATED_3_0 +static int include_legacy(void) +{ + return app_get0_propq() == NULL; +} + +static void legacy_cipher_fn(const EVP_CIPHER *c, + const char *from, const char *to, void *arg) +{ + if (select_name != NULL + && (c == NULL + || OPENSSL_strcasecmp(select_name, EVP_CIPHER_get0_name(c)) != 0)) + return; + if (c != NULL) { + BIO_printf(arg, " %s\n", EVP_CIPHER_get0_name(c)); + } else { + if (from == NULL) + from = ""; + if (to == NULL) + to = ""; + BIO_printf(arg, " %s => %s\n", from, to); + } +} +#endif + +DEFINE_STACK_OF(EVP_CIPHER) +static int cipher_cmp(const EVP_CIPHER * const *a, + const EVP_CIPHER * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(EVP_CIPHER_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_CIPHER_get0_provider(*b))); +} + +static void collect_ciphers(EVP_CIPHER *cipher, void *stack) +{ + STACK_OF(EVP_CIPHER) *cipher_stack = stack; + + if (is_cipher_fetchable(cipher) + && sk_EVP_CIPHER_push(cipher_stack, cipher) > 0) + EVP_CIPHER_up_ref(cipher); +} + +static void list_ciphers(void) +{ + STACK_OF(EVP_CIPHER) *ciphers = sk_EVP_CIPHER_new(cipher_cmp); + int i; + + if (ciphers == NULL) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + return; + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (include_legacy()) { + BIO_printf(bio_out, "Legacy:\n"); + EVP_CIPHER_do_all_sorted(legacy_cipher_fn, bio_out); + } +#endif + + BIO_printf(bio_out, "Provided:\n"); + EVP_CIPHER_do_all_provided(app_get0_libctx(), collect_ciphers, ciphers); + sk_EVP_CIPHER_sort(ciphers); + for (i = 0; i < sk_EVP_CIPHER_num(ciphers); i++) { + const EVP_CIPHER *c = sk_EVP_CIPHER_value(ciphers, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_CIPHER_is_a(c, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL && EVP_CIPHER_names_do_all(c, collect_names, names)) { + BIO_printf(bio_out, " "); + print_names(bio_out, names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(EVP_CIPHER_get0_provider(c))); + + if (verbose) { + const char *desc = EVP_CIPHER_get0_description(c); + + if (desc != NULL) + BIO_printf(bio_out, " description: %s\n", desc); + print_param_types("retrievable algorithm parameters", + EVP_CIPHER_gettable_params(c), 4); + print_param_types("retrievable operation parameters", + EVP_CIPHER_gettable_ctx_params(c), 4); + print_param_types("settable operation parameters", + EVP_CIPHER_settable_ctx_params(c), 4); + } + } + sk_OPENSSL_CSTRING_free(names); + } + sk_EVP_CIPHER_pop_free(ciphers, EVP_CIPHER_free); +} + +#ifndef OPENSSL_NO_DEPRECATED_3_0 +static void legacy_md_fn(const EVP_MD *m, + const char *from, const char *to, void *arg) +{ + if (m != NULL) { + BIO_printf(arg, " %s\n", EVP_MD_get0_name(m)); + } else { + if (from == NULL) + from = ""; + if (to == NULL) + to = ""; + BIO_printf((BIO *)arg, " %s => %s\n", from, to); + } +} +#endif + +DEFINE_STACK_OF(EVP_MD) +static int md_cmp(const EVP_MD * const *a, const EVP_MD * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(EVP_MD_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_MD_get0_provider(*b))); +} + +static void collect_digests(EVP_MD *digest, void *stack) +{ + STACK_OF(EVP_MD) *digest_stack = stack; + + if (is_digest_fetchable(digest) + && sk_EVP_MD_push(digest_stack, digest) > 0) + EVP_MD_up_ref(digest); +} + +static void list_digests(void) +{ + STACK_OF(EVP_MD) *digests = sk_EVP_MD_new(md_cmp); + int i; + + if (digests == NULL) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + return; + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (include_legacy()) { + BIO_printf(bio_out, "Legacy:\n"); + EVP_MD_do_all_sorted(legacy_md_fn, bio_out); + } +#endif + + BIO_printf(bio_out, "Provided:\n"); + EVP_MD_do_all_provided(app_get0_libctx(), collect_digests, digests); + sk_EVP_MD_sort(digests); + for (i = 0; i < sk_EVP_MD_num(digests); i++) { + const EVP_MD *m = sk_EVP_MD_value(digests, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_MD_is_a(m, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL && EVP_MD_names_do_all(m, collect_names, names)) { + BIO_printf(bio_out, " "); + print_names(bio_out, names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(EVP_MD_get0_provider(m))); + + if (verbose) { + const char *desc = EVP_MD_get0_description(m); + + if (desc != NULL) + BIO_printf(bio_out, " description: %s\n", desc); + print_param_types("retrievable algorithm parameters", + EVP_MD_gettable_params(m), 4); + print_param_types("retrievable operation parameters", + EVP_MD_gettable_ctx_params(m), 4); + print_param_types("settable operation parameters", + EVP_MD_settable_ctx_params(m), 4); + } + } + sk_OPENSSL_CSTRING_free(names); + } + sk_EVP_MD_pop_free(digests, EVP_MD_free); +} + +DEFINE_STACK_OF(EVP_MAC) +static int mac_cmp(const EVP_MAC * const *a, const EVP_MAC * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(EVP_MAC_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_MAC_get0_provider(*b))); +} + +static void collect_macs(EVP_MAC *mac, void *stack) +{ + STACK_OF(EVP_MAC) *mac_stack = stack; + + if (is_mac_fetchable(mac) + && sk_EVP_MAC_push(mac_stack, mac) > 0) + EVP_MAC_up_ref(mac); +} + +static void list_macs(void) +{ + STACK_OF(EVP_MAC) *macs = sk_EVP_MAC_new(mac_cmp); + int i; + + if (macs == NULL) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + return; + } + BIO_printf(bio_out, "Provided MACs:\n"); + EVP_MAC_do_all_provided(app_get0_libctx(), collect_macs, macs); + sk_EVP_MAC_sort(macs); + for (i = 0; i < sk_EVP_MAC_num(macs); i++) { + const EVP_MAC *m = sk_EVP_MAC_value(macs, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_MAC_is_a(m, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL && EVP_MAC_names_do_all(m, collect_names, names)) { + BIO_printf(bio_out, " "); + print_names(bio_out, names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(EVP_MAC_get0_provider(m))); + + if (verbose) { + const char *desc = EVP_MAC_get0_description(m); + + if (desc != NULL) + BIO_printf(bio_out, " description: %s\n", desc); + print_param_types("retrievable algorithm parameters", + EVP_MAC_gettable_params(m), 4); + print_param_types("retrievable operation parameters", + EVP_MAC_gettable_ctx_params(m), 4); + print_param_types("settable operation parameters", + EVP_MAC_settable_ctx_params(m), 4); + } + } + sk_OPENSSL_CSTRING_free(names); + } + sk_EVP_MAC_pop_free(macs, EVP_MAC_free); +} + +/* + * KDFs and PRFs + */ +DEFINE_STACK_OF(EVP_KDF) +static int kdf_cmp(const EVP_KDF * const *a, const EVP_KDF * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(EVP_KDF_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_KDF_get0_provider(*b))); +} + +static void collect_kdfs(EVP_KDF *kdf, void *stack) +{ + STACK_OF(EVP_KDF) *kdf_stack = stack; + + if (is_kdf_fetchable(kdf) + && sk_EVP_KDF_push(kdf_stack, kdf) > 0) + EVP_KDF_up_ref(kdf); +} + +static void list_kdfs(void) +{ + STACK_OF(EVP_KDF) *kdfs = sk_EVP_KDF_new(kdf_cmp); + int i; + + if (kdfs == NULL) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + return; + } + BIO_printf(bio_out, "Provided KDFs and PDFs:\n"); + EVP_KDF_do_all_provided(app_get0_libctx(), collect_kdfs, kdfs); + sk_EVP_KDF_sort(kdfs); + for (i = 0; i < sk_EVP_KDF_num(kdfs); i++) { + const EVP_KDF *k = sk_EVP_KDF_value(kdfs, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_KDF_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL && EVP_KDF_names_do_all(k, collect_names, names)) { + BIO_printf(bio_out, " "); + print_names(bio_out, names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(EVP_KDF_get0_provider(k))); + + if (verbose) { + const char *desc = EVP_KDF_get0_description(k); + + if (desc != NULL) + BIO_printf(bio_out, " description: %s\n", desc); + print_param_types("retrievable algorithm parameters", + EVP_KDF_gettable_params(k), 4); + print_param_types("retrievable operation parameters", + EVP_KDF_gettable_ctx_params(k), 4); + print_param_types("settable operation parameters", + EVP_KDF_settable_ctx_params(k), 4); + } + } + sk_OPENSSL_CSTRING_free(names); + } + sk_EVP_KDF_pop_free(kdfs, EVP_KDF_free); +} + +/* + * RANDs + */ +DEFINE_STACK_OF(EVP_RAND) + +static int rand_cmp(const EVP_RAND * const *a, const EVP_RAND * const *b) +{ + int ret = OPENSSL_strcasecmp(EVP_RAND_get0_name(*a), EVP_RAND_get0_name(*b)); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_get0_name(EVP_RAND_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_RAND_get0_provider(*b))); + + return ret; +} + +static void collect_rands(EVP_RAND *rand, void *stack) +{ + STACK_OF(EVP_RAND) *rand_stack = stack; + + if (is_rand_fetchable(rand) + && sk_EVP_RAND_push(rand_stack, rand) > 0) + EVP_RAND_up_ref(rand); +} + +static void list_random_generators(void) +{ + STACK_OF(EVP_RAND) *rands = sk_EVP_RAND_new(rand_cmp); + int i; + + if (rands == NULL) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + return; + } + BIO_printf(bio_out, "Provided RNGs and seed sources:\n"); + EVP_RAND_do_all_provided(app_get0_libctx(), collect_rands, rands); + sk_EVP_RAND_sort(rands); + for (i = 0; i < sk_EVP_RAND_num(rands); i++) { + const EVP_RAND *m = sk_EVP_RAND_value(rands, i); + + if (select_name != NULL + && OPENSSL_strcasecmp(EVP_RAND_get0_name(m), select_name) != 0) + continue; + BIO_printf(bio_out, " %s", EVP_RAND_get0_name(m)); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(EVP_RAND_get0_provider(m))); + + if (verbose) { + const char *desc = EVP_RAND_get0_description(m); + + if (desc != NULL) + BIO_printf(bio_out, " description: %s\n", desc); + print_param_types("retrievable algorithm parameters", + EVP_RAND_gettable_params(m), 4); + print_param_types("retrievable operation parameters", + EVP_RAND_gettable_ctx_params(m), 4); + print_param_types("settable operation parameters", + EVP_RAND_settable_ctx_params(m), 4); + } + } + sk_EVP_RAND_pop_free(rands, EVP_RAND_free); +} + +static void display_random(const char *name, EVP_RAND_CTX *drbg) +{ + EVP_RAND *rand; + uint64_t u; + const char *p; + const OSSL_PARAM *gettables; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + unsigned char buf[1000]; + + BIO_printf(bio_out, "%s:\n", name); + if (drbg != NULL) { + rand = EVP_RAND_CTX_get0_rand(drbg); + + BIO_printf(bio_out, " %s", EVP_RAND_get0_name(rand)); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(EVP_RAND_get0_provider(rand))); + + switch (EVP_RAND_get_state(drbg)) { + case EVP_RAND_STATE_UNINITIALISED: + p = "uninitialised"; + break; + case EVP_RAND_STATE_READY: + p = "ready"; + break; + case EVP_RAND_STATE_ERROR: + p = "error"; + break; + default: + p = "unknown"; + break; + } + BIO_printf(bio_out, " state = %s\n", p); + + gettables = EVP_RAND_gettable_ctx_params(rand); + if (gettables != NULL) + for (; gettables->key != NULL; gettables++) { + /* State has been dealt with already, so ignore */ + if (OPENSSL_strcasecmp(gettables->key, OSSL_RAND_PARAM_STATE) == 0) + continue; + /* Outside of verbose mode, we skip non-string values */ + if (gettables->data_type != OSSL_PARAM_UTF8_STRING + && gettables->data_type != OSSL_PARAM_UTF8_PTR + && !verbose) + continue; + params->key = gettables->key; + params->data_type = gettables->data_type; + if (gettables->data_type == OSSL_PARAM_UNSIGNED_INTEGER + || gettables->data_type == OSSL_PARAM_INTEGER) { + params->data = &u; + params->data_size = sizeof(u); + } else { + params->data = buf; + params->data_size = sizeof(buf); + } + params->return_size = 0; + if (EVP_RAND_CTX_get_params(drbg, params)) + print_param_value(params, 2); + } + } +} + +static void list_random_instances(void) +{ + display_random("primary", RAND_get0_primary(NULL)); + display_random("public", RAND_get0_public(NULL)); + display_random("private", RAND_get0_private(NULL)); +} + +/* + * Encoders + */ +DEFINE_STACK_OF(OSSL_ENCODER) +static int encoder_cmp(const OSSL_ENCODER * const *a, + const OSSL_ENCODER * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(OSSL_ENCODER_get0_provider(*a)), + OSSL_PROVIDER_get0_name(OSSL_ENCODER_get0_provider(*b))); +} + +static void collect_encoders(OSSL_ENCODER *encoder, void *stack) +{ + STACK_OF(OSSL_ENCODER) *encoder_stack = stack; + + if (is_encoder_fetchable(encoder) + && sk_OSSL_ENCODER_push(encoder_stack, encoder) > 0) + OSSL_ENCODER_up_ref(encoder); +} + +static void list_encoders(void) +{ + STACK_OF(OSSL_ENCODER) *encoders; + int i; + + encoders = sk_OSSL_ENCODER_new(encoder_cmp); + if (encoders == NULL) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + return; + } + BIO_printf(bio_out, "Provided ENCODERs:\n"); + OSSL_ENCODER_do_all_provided(app_get0_libctx(), collect_encoders, + encoders); + sk_OSSL_ENCODER_sort(encoders); + + for (i = 0; i < sk_OSSL_ENCODER_num(encoders); i++) { + OSSL_ENCODER *k = sk_OSSL_ENCODER_value(encoders, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !OSSL_ENCODER_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL && OSSL_ENCODER_names_do_all(k, collect_names, names)) { + BIO_printf(bio_out, " "); + print_names(bio_out, names); + + BIO_printf(bio_out, " @ %s (%s)\n", + OSSL_PROVIDER_get0_name(OSSL_ENCODER_get0_provider(k)), + OSSL_ENCODER_get0_properties(k)); + + if (verbose) { + const char *desc = OSSL_ENCODER_get0_description(k); + + if (desc != NULL) + BIO_printf(bio_out, " description: %s\n", desc); + print_param_types("settable operation parameters", + OSSL_ENCODER_settable_ctx_params(k), 4); + } + } + sk_OPENSSL_CSTRING_free(names); + } + sk_OSSL_ENCODER_pop_free(encoders, OSSL_ENCODER_free); +} + +/* + * Decoders + */ +DEFINE_STACK_OF(OSSL_DECODER) +static int decoder_cmp(const OSSL_DECODER * const *a, + const OSSL_DECODER * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(OSSL_DECODER_get0_provider(*a)), + OSSL_PROVIDER_get0_name(OSSL_DECODER_get0_provider(*b))); +} + +static void collect_decoders(OSSL_DECODER *decoder, void *stack) +{ + STACK_OF(OSSL_DECODER) *decoder_stack = stack; + + if (is_decoder_fetchable(decoder) + && sk_OSSL_DECODER_push(decoder_stack, decoder) > 0) + OSSL_DECODER_up_ref(decoder); +} + +static void list_decoders(void) +{ + STACK_OF(OSSL_DECODER) *decoders; + int i; + + decoders = sk_OSSL_DECODER_new(decoder_cmp); + if (decoders == NULL) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + return; + } + BIO_printf(bio_out, "Provided DECODERs:\n"); + OSSL_DECODER_do_all_provided(app_get0_libctx(), collect_decoders, + decoders); + sk_OSSL_DECODER_sort(decoders); + + for (i = 0; i < sk_OSSL_DECODER_num(decoders); i++) { + OSSL_DECODER *k = sk_OSSL_DECODER_value(decoders, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !OSSL_DECODER_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL && OSSL_DECODER_names_do_all(k, collect_names, names)) { + BIO_printf(bio_out, " "); + print_names(bio_out, names); + + BIO_printf(bio_out, " @ %s (%s)\n", + OSSL_PROVIDER_get0_name(OSSL_DECODER_get0_provider(k)), + OSSL_DECODER_get0_properties(k)); + + if (verbose) { + const char *desc = OSSL_DECODER_get0_description(k); + + if (desc != NULL) + BIO_printf(bio_out, " description: %s\n", desc); + print_param_types("settable operation parameters", + OSSL_DECODER_settable_ctx_params(k), 4); + } + } + sk_OPENSSL_CSTRING_free(names); + } + sk_OSSL_DECODER_pop_free(decoders, OSSL_DECODER_free); +} + +DEFINE_STACK_OF(EVP_KEYMGMT) +static int keymanager_cmp(const EVP_KEYMGMT * const *a, + const EVP_KEYMGMT * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(EVP_KEYMGMT_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_KEYMGMT_get0_provider(*b))); +} + +static void collect_keymanagers(EVP_KEYMGMT *km, void *stack) +{ + STACK_OF(EVP_KEYMGMT) *km_stack = stack; + + if (is_keymgmt_fetchable(km) + && sk_EVP_KEYMGMT_push(km_stack, km) > 0) + EVP_KEYMGMT_up_ref(km); +} + +static void list_keymanagers(void) +{ + int i; + STACK_OF(EVP_KEYMGMT) *km_stack = sk_EVP_KEYMGMT_new(keymanager_cmp); + + EVP_KEYMGMT_do_all_provided(app_get0_libctx(), collect_keymanagers, + km_stack); + sk_EVP_KEYMGMT_sort(km_stack); + + for (i = 0; i < sk_EVP_KEYMGMT_num(km_stack); i++) { + EVP_KEYMGMT *k = sk_EVP_KEYMGMT_value(km_stack, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_KEYMGMT_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL && EVP_KEYMGMT_names_do_all(k, collect_names, names)) { + const char *desc = EVP_KEYMGMT_get0_description(k); + + BIO_printf(bio_out, " Name: "); + if (desc != NULL) + BIO_printf(bio_out, "%s", desc); + else + BIO_printf(bio_out, "%s", sk_OPENSSL_CSTRING_value(names, 0)); + BIO_printf(bio_out, "\n"); + BIO_printf(bio_out, " Type: Provider Algorithm\n"); + BIO_printf(bio_out, " IDs: "); + print_names(bio_out, names); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(EVP_KEYMGMT_get0_provider(k))); + + if (verbose) { + print_param_types("settable key generation parameters", + EVP_KEYMGMT_gen_settable_params(k), 4); + print_param_types("settable operation parameters", + EVP_KEYMGMT_settable_params(k), 4); + print_param_types("retrievable operation parameters", + EVP_KEYMGMT_gettable_params(k), 4); + } + } + sk_OPENSSL_CSTRING_free(names); + } + sk_EVP_KEYMGMT_pop_free(km_stack, EVP_KEYMGMT_free); +} + +DEFINE_STACK_OF(EVP_SIGNATURE) +static int signature_cmp(const EVP_SIGNATURE * const *a, + const EVP_SIGNATURE * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*b))); +} + +static void collect_signatures(EVP_SIGNATURE *sig, void *stack) +{ + STACK_OF(EVP_SIGNATURE) *sig_stack = stack; + + if (is_signature_fetchable(sig) + && sk_EVP_SIGNATURE_push(sig_stack, sig) > 0) + EVP_SIGNATURE_up_ref(sig); +} + +static void list_signatures(void) +{ + int i, count = 0; + STACK_OF(EVP_SIGNATURE) *sig_stack = sk_EVP_SIGNATURE_new(signature_cmp); + + EVP_SIGNATURE_do_all_provided(app_get0_libctx(), collect_signatures, + sig_stack); + sk_EVP_SIGNATURE_sort(sig_stack); + + for (i = 0; i < sk_EVP_SIGNATURE_num(sig_stack); i++) { + EVP_SIGNATURE *k = sk_EVP_SIGNATURE_value(sig_stack, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_SIGNATURE_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL && EVP_SIGNATURE_names_do_all(k, collect_names, names)) { + count++; + BIO_printf(bio_out, " "); + print_names(bio_out, names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(k))); + + if (verbose) { + const char *desc = EVP_SIGNATURE_get0_description(k); + + if (desc != NULL) + BIO_printf(bio_out, " description: %s\n", desc); + print_param_types("settable operation parameters", + EVP_SIGNATURE_settable_ctx_params(k), 4); + print_param_types("retrievable operation parameters", + EVP_SIGNATURE_gettable_ctx_params(k), 4); + } + } + sk_OPENSSL_CSTRING_free(names); + } + sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free); + if (count == 0) + BIO_printf(bio_out, " -\n"); +} + +DEFINE_STACK_OF(EVP_KEM) +static int kem_cmp(const EVP_KEM * const *a, + const EVP_KEM * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*b))); +} + +static void collect_kem(EVP_KEM *kem, void *stack) +{ + STACK_OF(EVP_KEM) *kem_stack = stack; + + if (is_kem_fetchable(kem) + && sk_EVP_KEM_push(kem_stack, kem) > 0) + EVP_KEM_up_ref(kem); +} + +static void list_kems(void) +{ + int i, count = 0; + STACK_OF(EVP_KEM) *kem_stack = sk_EVP_KEM_new(kem_cmp); + + EVP_KEM_do_all_provided(app_get0_libctx(), collect_kem, kem_stack); + sk_EVP_KEM_sort(kem_stack); + + for (i = 0; i < sk_EVP_KEM_num(kem_stack); i++) { + EVP_KEM *k = sk_EVP_KEM_value(kem_stack, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_KEM_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL && EVP_KEM_names_do_all(k, collect_names, names)) { + count++; + BIO_printf(bio_out, " "); + print_names(bio_out, names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(k))); + + if (verbose) { + const char *desc = EVP_KEM_get0_description(k); + + if (desc != NULL) + BIO_printf(bio_out, " description: %s\n", desc); + print_param_types("settable operation parameters", + EVP_KEM_settable_ctx_params(k), 4); + print_param_types("retrievable operation parameters", + EVP_KEM_gettable_ctx_params(k), 4); + } + } + sk_OPENSSL_CSTRING_free(names); + } + sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free); + if (count == 0) + BIO_printf(bio_out, " -\n"); +} + +DEFINE_STACK_OF(EVP_ASYM_CIPHER) +static int asymcipher_cmp(const EVP_ASYM_CIPHER * const *a, + const EVP_ASYM_CIPHER * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(EVP_ASYM_CIPHER_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_ASYM_CIPHER_get0_provider(*b))); +} + +static void collect_asymciph(EVP_ASYM_CIPHER *asym_cipher, void *stack) +{ + STACK_OF(EVP_ASYM_CIPHER) *asym_cipher_stack = stack; + + if (is_asym_cipher_fetchable(asym_cipher) + && sk_EVP_ASYM_CIPHER_push(asym_cipher_stack, asym_cipher) > 0) + EVP_ASYM_CIPHER_up_ref(asym_cipher); +} + +static void list_asymciphers(void) +{ + int i, count = 0; + STACK_OF(EVP_ASYM_CIPHER) *asymciph_stack = + sk_EVP_ASYM_CIPHER_new(asymcipher_cmp); + + EVP_ASYM_CIPHER_do_all_provided(app_get0_libctx(), collect_asymciph, + asymciph_stack); + sk_EVP_ASYM_CIPHER_sort(asymciph_stack); + + for (i = 0; i < sk_EVP_ASYM_CIPHER_num(asymciph_stack); i++) { + EVP_ASYM_CIPHER *k = sk_EVP_ASYM_CIPHER_value(asymciph_stack, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_ASYM_CIPHER_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL + && EVP_ASYM_CIPHER_names_do_all(k, collect_names, names)) { + count++; + BIO_printf(bio_out, " "); + print_names(bio_out, names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(EVP_ASYM_CIPHER_get0_provider(k))); + + if (verbose) { + const char *desc = EVP_ASYM_CIPHER_get0_description(k); + + if (desc != NULL) + BIO_printf(bio_out, " description: %s\n", desc); + print_param_types("settable operation parameters", + EVP_ASYM_CIPHER_settable_ctx_params(k), 4); + print_param_types("retrievable operation parameters", + EVP_ASYM_CIPHER_gettable_ctx_params(k), 4); + } + } + sk_OPENSSL_CSTRING_free(names); + } + sk_EVP_ASYM_CIPHER_pop_free(asymciph_stack, EVP_ASYM_CIPHER_free); + if (count == 0) + BIO_printf(bio_out, " -\n"); +} + +DEFINE_STACK_OF(EVP_KEYEXCH) +static int kex_cmp(const EVP_KEYEXCH * const *a, + const EVP_KEYEXCH * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(EVP_KEYEXCH_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_KEYEXCH_get0_provider(*b))); +} + +static void collect_kex(EVP_KEYEXCH *kex, void *stack) +{ + STACK_OF(EVP_KEYEXCH) *kex_stack = stack; + + if (is_keyexch_fetchable(kex) + && sk_EVP_KEYEXCH_push(kex_stack, kex) > 0) + EVP_KEYEXCH_up_ref(kex); +} + +static void list_keyexchanges(void) +{ + int i, count = 0; + STACK_OF(EVP_KEYEXCH) *kex_stack = sk_EVP_KEYEXCH_new(kex_cmp); + + EVP_KEYEXCH_do_all_provided(app_get0_libctx(), collect_kex, kex_stack); + sk_EVP_KEYEXCH_sort(kex_stack); + + for (i = 0; i < sk_EVP_KEYEXCH_num(kex_stack); i++) { + EVP_KEYEXCH *k = sk_EVP_KEYEXCH_value(kex_stack, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_KEYEXCH_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL && EVP_KEYEXCH_names_do_all(k, collect_names, names)) { + count++; + BIO_printf(bio_out, " "); + print_names(bio_out, names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(EVP_KEYEXCH_get0_provider(k))); + + if (verbose) { + const char *desc = EVP_KEYEXCH_get0_description(k); + + if (desc != NULL) + BIO_printf(bio_out, " description: %s\n", desc); + print_param_types("settable operation parameters", + EVP_KEYEXCH_settable_ctx_params(k), 4); + print_param_types("retrievable operation parameters", + EVP_KEYEXCH_gettable_ctx_params(k), 4); + } + } + sk_OPENSSL_CSTRING_free(names); + } + sk_EVP_KEYEXCH_pop_free(kex_stack, EVP_KEYEXCH_free); + if (count == 0) + BIO_printf(bio_out, " -\n"); +} + +static void list_objects(void) +{ + int max_nid = OBJ_new_nid(0); + int i; + char *oid_buf = NULL; + int oid_size = 0; + + /* Skip 0, since that's NID_undef */ + for (i = 1; i < max_nid; i++) { + const ASN1_OBJECT *obj = OBJ_nid2obj(i); + const char *sn = OBJ_nid2sn(i); + const char *ln = OBJ_nid2ln(i); + int n = 0; + + /* + * If one of the retrieved objects somehow generated an error, + * we ignore it. The check for NID_undef below will detect the + * error and simply skip to the next NID. + */ + ERR_clear_error(); + + if (OBJ_obj2nid(obj) == NID_undef) + continue; + + if ((n = OBJ_obj2txt(NULL, 0, obj, 1)) == 0) { + BIO_printf(bio_out, "# None-OID object: %s, %s\n", sn, ln); + continue; + } + if (n < 0) + break; /* Error */ + + if (n > oid_size) { + oid_buf = OPENSSL_realloc(oid_buf, n + 1); + if (oid_buf == NULL) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + break; /* Error */ + } + oid_size = n + 1; + } + if (OBJ_obj2txt(oid_buf, oid_size, obj, 1) < 0) + break; /* Error */ + if (ln == NULL || strcmp(sn, ln) == 0) + BIO_printf(bio_out, "%s = %s\n", sn, oid_buf); + else + BIO_printf(bio_out, "%s = %s, %s\n", sn, ln, oid_buf); + } + + OPENSSL_free(oid_buf); +} + +static void list_options_for_command(const char *command) +{ + const FUNCTION *fp; + const OPTIONS *o; + + for (fp = functions; fp->name != NULL; fp++) + if (strcmp(fp->name, command) == 0) + break; + if (fp->name == NULL) { + BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", + command); + return; + } + + if ((o = fp->help) == NULL) + return; + + for ( ; o->name != NULL; o++) { + char c = o->valtype; + + if (o->name == OPT_PARAM_STR) + break; + + if (o->name == OPT_HELP_STR + || o->name == OPT_MORE_STR + || o->name == OPT_SECTION_STR + || o->name[0] == '\0') + continue; + BIO_printf(bio_out, "%s %c\n", o->name, c == '\0' ? '-' : c); + } + /* Always output the -- marker since it is sometimes documented. */ + BIO_printf(bio_out, "- -\n"); +} + +static int is_md_available(const char *name) +{ + EVP_MD *md; + const char *propq = app_get0_propq(); + + /* Look through providers' digests */ + ERR_set_mark(); + md = EVP_MD_fetch(app_get0_libctx(), name, propq); + ERR_pop_to_mark(); + if (md != NULL) { + EVP_MD_free(md); + return 1; + } + + return propq != NULL || get_digest_from_engine(name) == NULL ? 0 : 1; +} + +static int is_cipher_available(const char *name) +{ + EVP_CIPHER *cipher; + const char *propq = app_get0_propq(); + + /* Look through providers' ciphers */ + ERR_set_mark(); + cipher = EVP_CIPHER_fetch(app_get0_libctx(), name, propq); + ERR_pop_to_mark(); + if (cipher != NULL) { + EVP_CIPHER_free(cipher); + return 1; + } + + return propq != NULL || get_cipher_from_engine(name) == NULL ? 0 : 1; +} + +static void list_type(FUNC_TYPE ft, int one) +{ + FUNCTION *fp; + int i = 0; + DISPLAY_COLUMNS dc; + + memset(&dc, 0, sizeof(dc)); + if (!one) + calculate_columns(functions, &dc); + + for (fp = functions; fp->name != NULL; fp++) { + if (fp->type != ft) + continue; + switch (ft) { + case FT_cipher: + if (!is_cipher_available(fp->name)) + continue; + break; + case FT_md: + if (!is_md_available(fp->name)) + continue; + break; + default: + break; + } + if (one) { + BIO_printf(bio_out, "%s\n", fp->name); + } else { + if (i % dc.columns == 0 && i > 0) + BIO_printf(bio_out, "\n"); + BIO_printf(bio_out, "%-*s", dc.width, fp->name); + i++; + } + } + if (!one) + BIO_printf(bio_out, "\n\n"); +} + +static void list_pkey(void) +{ +#ifndef OPENSSL_NO_DEPRECATED_3_0 + int i; + + if (select_name == NULL && include_legacy()) { + BIO_printf(bio_out, "Legacy:\n"); + for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id, pkey_base_id, pkey_flags; + const char *pinfo, *pem_str; + ameth = EVP_PKEY_asn1_get0(i); + EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags, + &pinfo, &pem_str, ameth); + if (pkey_flags & ASN1_PKEY_ALIAS) { + BIO_printf(bio_out, " Name: %s\n", OBJ_nid2ln(pkey_id)); + BIO_printf(bio_out, "\tAlias for: %s\n", + OBJ_nid2ln(pkey_base_id)); + } else { + BIO_printf(bio_out, " Name: %s\n", pinfo); + BIO_printf(bio_out, "\tType: %s Algorithm\n", + pkey_flags & ASN1_PKEY_DYNAMIC ? + "External" : "Builtin"); + BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); + if (pem_str == NULL) + pem_str = "(none)"; + BIO_printf(bio_out, "\tPEM string: %s\n", pem_str); + } + } + } +#endif + BIO_printf(bio_out, "Provided:\n"); + BIO_printf(bio_out, " Key Managers:\n"); + list_keymanagers(); +} + +static void list_pkey_meth(void) +{ +#ifndef OPENSSL_NO_DEPRECATED_3_0 + size_t i; + size_t meth_count = EVP_PKEY_meth_get_count(); + + if (select_name == NULL && include_legacy()) { + BIO_printf(bio_out, "Legacy:\n"); + for (i = 0; i < meth_count; i++) { + const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i); + int pkey_id, pkey_flags; + + EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth); + BIO_printf(bio_out, " %s\n", OBJ_nid2ln(pkey_id)); + BIO_printf(bio_out, "\tType: %s Algorithm\n", + pkey_flags & ASN1_PKEY_DYNAMIC ? "External" : "Builtin"); + } + } +#endif + BIO_printf(bio_out, "Provided:\n"); + BIO_printf(bio_out, " Encryption:\n"); + list_asymciphers(); + BIO_printf(bio_out, " Key Exchange:\n"); + list_keyexchanges(); + BIO_printf(bio_out, " Signatures:\n"); + list_signatures(); + BIO_printf(bio_out, " Key encapsulation:\n"); + list_kems(); +} + +DEFINE_STACK_OF(OSSL_STORE_LOADER) +static int store_cmp(const OSSL_STORE_LOADER * const *a, + const OSSL_STORE_LOADER * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(OSSL_STORE_LOADER_get0_provider(*a)), + OSSL_PROVIDER_get0_name(OSSL_STORE_LOADER_get0_provider(*b))); +} + +static void collect_store_loaders(OSSL_STORE_LOADER *store, void *stack) +{ + STACK_OF(OSSL_STORE_LOADER) *store_stack = stack; + + if (sk_OSSL_STORE_LOADER_push(store_stack, store) > 0) + OSSL_STORE_LOADER_up_ref(store); +} + +static void list_store_loaders(void) +{ + STACK_OF(OSSL_STORE_LOADER) *stores = sk_OSSL_STORE_LOADER_new(store_cmp); + int i; + + if (stores == NULL) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + return; + } + BIO_printf(bio_out, "Provided STORE LOADERs:\n"); + OSSL_STORE_LOADER_do_all_provided(app_get0_libctx(), collect_store_loaders, + stores); + sk_OSSL_STORE_LOADER_sort(stores); + for (i = 0; i < sk_OSSL_STORE_LOADER_num(stores); i++) { + const OSSL_STORE_LOADER *m = sk_OSSL_STORE_LOADER_value(stores, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !OSSL_STORE_LOADER_is_a(m, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + if (names != NULL && OSSL_STORE_LOADER_names_do_all(m, collect_names, + names)) { + BIO_printf(bio_out, " "); + print_names(bio_out, names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_get0_name(OSSL_STORE_LOADER_get0_provider(m))); + } + sk_OPENSSL_CSTRING_free(names); + } + sk_OSSL_STORE_LOADER_pop_free(stores, OSSL_STORE_LOADER_free); +} + +DEFINE_STACK_OF(OSSL_PROVIDER) +static int provider_cmp(const OSSL_PROVIDER * const *a, + const OSSL_PROVIDER * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(*a), OSSL_PROVIDER_get0_name(*b)); +} + +static int collect_providers(OSSL_PROVIDER *provider, void *stack) +{ + STACK_OF(OSSL_PROVIDER) *provider_stack = stack; + + sk_OSSL_PROVIDER_push(provider_stack, provider); + return 1; +} + +static void list_provider_info(void) +{ + STACK_OF(OSSL_PROVIDER) *providers = sk_OSSL_PROVIDER_new(provider_cmp); + OSSL_PARAM params[5]; + char *name, *version, *buildinfo; + int status; + int i; + + if (providers == NULL) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + return; + } + BIO_printf(bio_out, "Providers:\n"); + OSSL_PROVIDER_do_all(NULL, &collect_providers, providers); + sk_OSSL_PROVIDER_sort(providers); + for (i = 0; i < sk_OSSL_PROVIDER_num(providers); i++) { + const OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(providers, i); + + /* Query the "known" information parameters, the order matches below */ + params[0] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_NAME, + &name, 0); + params[1] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION, + &version, 0); + params[2] = OSSL_PARAM_construct_int(OSSL_PROV_PARAM_STATUS, &status); + params[3] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_BUILDINFO, + &buildinfo, 0); + params[4] = OSSL_PARAM_construct_end(); + OSSL_PARAM_set_all_unmodified(params); + if (!OSSL_PROVIDER_get_params(prov, params)) { + BIO_printf(bio_err, "ERROR: Unable to query provider parameters\n"); + return; + } + + /* Print out the provider information, the params order matches above */ + BIO_printf(bio_out, " %s\n", OSSL_PROVIDER_get0_name(prov)); + if (OSSL_PARAM_modified(params)) + BIO_printf(bio_out, " name: %s\n", name); + if (OSSL_PARAM_modified(params + 1)) + BIO_printf(bio_out, " version: %s\n", version); + if (OSSL_PARAM_modified(params + 2)) + BIO_printf(bio_out, " status: %sactive\n", status ? "" : "in"); + if (verbose) { + if (OSSL_PARAM_modified(params + 3)) + BIO_printf(bio_out, " build info: %s\n", buildinfo); + print_param_types("gettable provider parameters", + OSSL_PROVIDER_gettable_params(prov), 4); + } + } + sk_OSSL_PROVIDER_free(providers); +} + +#ifndef OPENSSL_NO_DEPRECATED_3_0 +static void list_engines(void) +{ +# ifndef OPENSSL_NO_ENGINE + ENGINE *e; + + BIO_puts(bio_out, "Engines:\n"); + e = ENGINE_get_first(); + while (e) { + BIO_printf(bio_out, "%s\n", ENGINE_get_id(e)); + e = ENGINE_get_next(e); + } +# else + BIO_puts(bio_out, "Engine support is disabled.\n"); +# endif +} +#endif + +static void list_disabled(void) +{ + BIO_puts(bio_out, "Disabled algorithms:\n"); +#ifdef OPENSSL_NO_ARIA + BIO_puts(bio_out, "ARIA\n"); +#endif +#ifdef OPENSSL_NO_BF + BIO_puts(bio_out, "BF\n"); +#endif +#ifdef OPENSSL_NO_BLAKE2 + BIO_puts(bio_out, "BLAKE2\n"); +#endif +#ifdef OPENSSL_NO_CAMELLIA + BIO_puts(bio_out, "CAMELLIA\n"); +#endif +#ifdef OPENSSL_NO_CAST + BIO_puts(bio_out, "CAST\n"); +#endif +#ifdef OPENSSL_NO_CMAC + BIO_puts(bio_out, "CMAC\n"); +#endif +#ifdef OPENSSL_NO_CMS + BIO_puts(bio_out, "CMS\n"); +#endif +#ifdef OPENSSL_NO_COMP + BIO_puts(bio_out, "COMP\n"); +#endif +#ifdef OPENSSL_NO_DES + BIO_puts(bio_out, "DES\n"); +#endif +#ifdef OPENSSL_NO_DGRAM + BIO_puts(bio_out, "DGRAM\n"); +#endif +#ifdef OPENSSL_NO_DH + BIO_puts(bio_out, "DH\n"); +#endif +#ifdef OPENSSL_NO_DSA + BIO_puts(bio_out, "DSA\n"); +#endif +#if defined(OPENSSL_NO_DTLS) + BIO_puts(bio_out, "DTLS\n"); +#endif +#if defined(OPENSSL_NO_DTLS1) + BIO_puts(bio_out, "DTLS1\n"); +#endif +#if defined(OPENSSL_NO_DTLS1_2) + BIO_puts(bio_out, "DTLS1_2\n"); +#endif +#ifdef OPENSSL_NO_EC + BIO_puts(bio_out, "EC\n"); +#endif +#ifdef OPENSSL_NO_EC2M + BIO_puts(bio_out, "EC2M\n"); +#endif +#if defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0) + BIO_puts(bio_out, "ENGINE\n"); +#endif +#ifdef OPENSSL_NO_GOST + BIO_puts(bio_out, "GOST\n"); +#endif +#ifdef OPENSSL_NO_IDEA + BIO_puts(bio_out, "IDEA\n"); +#endif +#ifdef OPENSSL_NO_MD2 + BIO_puts(bio_out, "MD2\n"); +#endif +#ifdef OPENSSL_NO_MD4 + BIO_puts(bio_out, "MD4\n"); +#endif +#ifdef OPENSSL_NO_MD5 + BIO_puts(bio_out, "MD5\n"); +#endif +#ifdef OPENSSL_NO_MDC2 + BIO_puts(bio_out, "MDC2\n"); +#endif +#ifdef OPENSSL_NO_OCB + BIO_puts(bio_out, "OCB\n"); +#endif +#ifdef OPENSSL_NO_OCSP + BIO_puts(bio_out, "OCSP\n"); +#endif +#ifdef OPENSSL_NO_PSK + BIO_puts(bio_out, "PSK\n"); +#endif +#ifdef OPENSSL_NO_RC2 + BIO_puts(bio_out, "RC2\n"); +#endif +#ifdef OPENSSL_NO_RC4 + BIO_puts(bio_out, "RC4\n"); +#endif +#ifdef OPENSSL_NO_RC5 + BIO_puts(bio_out, "RC5\n"); +#endif +#ifdef OPENSSL_NO_RMD160 + BIO_puts(bio_out, "RMD160\n"); +#endif +#ifdef OPENSSL_NO_SCRYPT + BIO_puts(bio_out, "SCRYPT\n"); +#endif +#ifdef OPENSSL_NO_SCTP + BIO_puts(bio_out, "SCTP\n"); +#endif +#ifdef OPENSSL_NO_SEED + BIO_puts(bio_out, "SEED\n"); +#endif +#ifdef OPENSSL_NO_SM2 + BIO_puts(bio_out, "SM2\n"); +#endif +#ifdef OPENSSL_NO_SM3 + BIO_puts(bio_out, "SM3\n"); +#endif +#ifdef OPENSSL_NO_SM4 + BIO_puts(bio_out, "SM4\n"); +#endif +#ifdef OPENSSL_NO_SOCK + BIO_puts(bio_out, "SOCK\n"); +#endif +#ifdef OPENSSL_NO_SRP + BIO_puts(bio_out, "SRP\n"); +#endif +#ifdef OPENSSL_NO_SRTP + BIO_puts(bio_out, "SRTP\n"); +#endif +#ifdef OPENSSL_NO_SSL3 + BIO_puts(bio_out, "SSL3\n"); +#endif +#ifdef OPENSSL_NO_TLS1 + BIO_puts(bio_out, "TLS1\n"); +#endif +#ifdef OPENSSL_NO_TLS1_1 + BIO_puts(bio_out, "TLS1_1\n"); +#endif +#ifdef OPENSSL_NO_TLS1_2 + BIO_puts(bio_out, "TLS1_2\n"); +#endif +#ifdef OPENSSL_NO_WHIRLPOOL + BIO_puts(bio_out, "WHIRLPOOL\n"); +#endif +#ifndef ZLIB + BIO_puts(bio_out, "ZLIB\n"); +#endif +} + +/* Unified enum for help and list commands. */ +typedef enum HELPLIST_CHOICE { + OPT_COMMON, + OPT_ONE, OPT_VERBOSE, + OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS, + OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS, + OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED, + OPT_KDF_ALGORITHMS, OPT_RANDOM_INSTANCES, OPT_RANDOM_GENERATORS, + OPT_ENCODERS, OPT_DECODERS, OPT_KEYMANAGERS, OPT_KEYEXCHANGE_ALGORITHMS, + OPT_KEM_ALGORITHMS, OPT_SIGNATURE_ALGORITHMS, OPT_ASYM_CIPHER_ALGORITHMS, + OPT_STORE_LOADERS, OPT_PROVIDER_INFO, + OPT_OBJECTS, OPT_SELECT_NAME, +#ifndef OPENSSL_NO_DEPRECATED_3_0 + OPT_ENGINES, +#endif + OPT_PROV_ENUM +} HELPLIST_CHOICE; + +const OPTIONS list_options[] = { + + OPT_SECTION("General"), + {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Output"), + {"1", OPT_ONE, '-', "List in one column"}, + {"verbose", OPT_VERBOSE, '-', "Verbose listing"}, + {"select", OPT_SELECT_NAME, 's', "Select a single algorithm"}, + {"commands", OPT_COMMANDS, '-', "List of standard commands"}, + {"standard-commands", OPT_COMMANDS, '-', "List of standard commands"}, +#ifndef OPENSSL_NO_DEPRECATED_3_0 + {"digest-commands", OPT_DIGEST_COMMANDS, '-', + "List of message digest commands (deprecated)"}, +#endif + {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-', + "List of message digest algorithms"}, + {"kdf-algorithms", OPT_KDF_ALGORITHMS, '-', + "List of key derivation and pseudo random function algorithms"}, + {"random-instances", OPT_RANDOM_INSTANCES, '-', + "List the primary, public and private random number generator details"}, + {"random-generators", OPT_RANDOM_GENERATORS, '-', + "List of random number generators"}, + {"mac-algorithms", OPT_MAC_ALGORITHMS, '-', + "List of message authentication code algorithms"}, +#ifndef OPENSSL_NO_DEPRECATED_3_0 + {"cipher-commands", OPT_CIPHER_COMMANDS, '-', + "List of cipher commands (deprecated)"}, +#endif + {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-', + "List of symmetric cipher algorithms"}, + {"encoders", OPT_ENCODERS, '-', "List of encoding methods" }, + {"decoders", OPT_DECODERS, '-', "List of decoding methods" }, + {"key-managers", OPT_KEYMANAGERS, '-', "List of key managers" }, + {"key-exchange-algorithms", OPT_KEYEXCHANGE_ALGORITHMS, '-', + "List of key exchange algorithms" }, + {"kem-algorithms", OPT_KEM_ALGORITHMS, '-', + "List of key encapsulation mechanism algorithms" }, + {"signature-algorithms", OPT_SIGNATURE_ALGORITHMS, '-', + "List of signature algorithms" }, + {"asymcipher-algorithms", OPT_ASYM_CIPHER_ALGORITHMS, '-', + "List of asymmetric cipher algorithms" }, + {"public-key-algorithms", OPT_PK_ALGORITHMS, '-', + "List of public key algorithms"}, + {"public-key-methods", OPT_PK_METHOD, '-', + "List of public key methods"}, + {"store-loaders", OPT_STORE_LOADERS, '-', + "List of store loaders"}, + {"providers", OPT_PROVIDER_INFO, '-', + "List of provider information"}, +#ifndef OPENSSL_NO_DEPRECATED_3_0 + {"engines", OPT_ENGINES, '-', + "List of loaded engines"}, +#endif + {"disabled", OPT_DISABLED, '-', "List of disabled features"}, + {"options", OPT_OPTIONS, 's', + "List options for specified command"}, + {"objects", OPT_OBJECTS, '-', + "List built in objects (OID<->name mappings)"}, + + OPT_PROV_OPTIONS, + {NULL} +}; + +int list_main(int argc, char **argv) +{ + char *prog; + HELPLIST_CHOICE o; + int one = 0, done = 0; + struct { + unsigned int commands:1; + unsigned int random_instances:1; + unsigned int random_generators:1; + unsigned int digest_commands:1; + unsigned int digest_algorithms:1; + unsigned int kdf_algorithms:1; + unsigned int mac_algorithms:1; + unsigned int cipher_commands:1; + unsigned int cipher_algorithms:1; + unsigned int encoder_algorithms:1; + unsigned int decoder_algorithms:1; + unsigned int keymanager_algorithms:1; + unsigned int signature_algorithms:1; + unsigned int keyexchange_algorithms:1; + unsigned int kem_algorithms:1; + unsigned int asym_cipher_algorithms:1; + unsigned int pk_algorithms:1; + unsigned int pk_method:1; + unsigned int store_loaders:1; + unsigned int provider_info:1; +#ifndef OPENSSL_NO_DEPRECATED_3_0 + unsigned int engines:1; +#endif + unsigned int disabled:1; + unsigned int objects:1; + unsigned int options:1; + } todo = { 0, }; + + verbose = 0; /* Clear a possible previous call */ + + prog = opt_init(argc, argv, list_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: /* Never hit, but suppresses warning */ + case OPT_ERR: +opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + return 1; + case OPT_HELP: + opt_help(list_options); + return 0; + case OPT_ONE: + one = 1; + break; + case OPT_COMMANDS: + todo.commands = 1; + break; + case OPT_DIGEST_COMMANDS: + todo.digest_commands = 1; + break; + case OPT_DIGEST_ALGORITHMS: + todo.digest_algorithms = 1; + break; + case OPT_KDF_ALGORITHMS: + todo.kdf_algorithms = 1; + break; + case OPT_RANDOM_INSTANCES: + todo.random_instances = 1; + break; + case OPT_RANDOM_GENERATORS: + todo.random_generators = 1; + break; + case OPT_MAC_ALGORITHMS: + todo.mac_algorithms = 1; + break; + case OPT_CIPHER_COMMANDS: + todo.cipher_commands = 1; + break; + case OPT_CIPHER_ALGORITHMS: + todo.cipher_algorithms = 1; + break; + case OPT_ENCODERS: + todo.encoder_algorithms = 1; + break; + case OPT_DECODERS: + todo.decoder_algorithms = 1; + break; + case OPT_KEYMANAGERS: + todo.keymanager_algorithms = 1; + break; + case OPT_SIGNATURE_ALGORITHMS: + todo.signature_algorithms = 1; + break; + case OPT_KEYEXCHANGE_ALGORITHMS: + todo.keyexchange_algorithms = 1; + break; + case OPT_KEM_ALGORITHMS: + todo.kem_algorithms = 1; + break; + case OPT_ASYM_CIPHER_ALGORITHMS: + todo.asym_cipher_algorithms = 1; + break; + case OPT_PK_ALGORITHMS: + todo.pk_algorithms = 1; + break; + case OPT_PK_METHOD: + todo.pk_method = 1; + break; + case OPT_STORE_LOADERS: + todo.store_loaders = 1; + break; + case OPT_PROVIDER_INFO: + todo.provider_info = 1; + break; +#ifndef OPENSSL_NO_DEPRECATED_3_0 + case OPT_ENGINES: + todo.engines = 1; + break; +#endif + case OPT_DISABLED: + todo.disabled = 1; + break; + case OPT_OBJECTS: + todo.objects = 1; + break; + case OPT_OPTIONS: + list_options_for_command(opt_arg()); + break; + case OPT_VERBOSE: + verbose = 1; + break; + case OPT_SELECT_NAME: + select_name = opt_arg(); + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + return 1; + break; + } + done = 1; + } + + /* No extra arguments. */ + if (opt_num_rest() != 0) + goto opthelp; + + if (todo.commands) + list_type(FT_general, one); + if (todo.random_instances) + list_random_instances(); + if (todo.random_generators) + list_random_generators(); + if (todo.digest_commands) + list_type(FT_md, one); + if (todo.digest_algorithms) + list_digests(); + if (todo.kdf_algorithms) + list_kdfs(); + if (todo.mac_algorithms) + list_macs(); + if (todo.cipher_commands) + list_type(FT_cipher, one); + if (todo.cipher_algorithms) + list_ciphers(); + if (todo.encoder_algorithms) + list_encoders(); + if (todo.decoder_algorithms) + list_decoders(); + if (todo.keymanager_algorithms) + list_keymanagers(); + if (todo.signature_algorithms) + list_signatures(); + if (todo.asym_cipher_algorithms) + list_asymciphers(); + if (todo.keyexchange_algorithms) + list_keyexchanges(); + if (todo.kem_algorithms) + list_kems(); + if (todo.pk_algorithms) + list_pkey(); + if (todo.pk_method) + list_pkey_meth(); + if (todo.store_loaders) + list_store_loaders(); + if (todo.provider_info) + list_provider_info(); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (todo.engines) + list_engines(); +#endif + if (todo.disabled) + list_disabled(); + if (todo.objects) + list_objects(); + + if (!done) + goto opthelp; + + return 0; +} diff --git a/crypto/openssl/apps/mac.c b/crypto/openssl/apps/mac.c new file mode 100644 index 000000000000..a9b6a265f49a --- /dev/null +++ b/crypto/openssl/apps/mac.c @@ -0,0 +1,237 @@ +/* + * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include + +#undef BUFSIZE +#define BUFSIZE 1024*8 + +typedef enum OPTION_choice { + OPT_COMMON, + OPT_MACOPT, OPT_BIN, OPT_IN, OPT_OUT, + OPT_CIPHER, OPT_DIGEST, + OPT_PROV_ENUM +} OPTION_CHOICE; + +const OPTIONS mac_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] mac_name\n"}, + + OPT_SECTION("General"), + {"help", OPT_HELP, '-', "Display this summary"}, + {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form"}, + {"cipher", OPT_CIPHER, 's', "Cipher"}, + {"digest", OPT_DIGEST, 's', "Digest"}, + {OPT_MORE_STR, 1, '-', "See 'PARAMETER NAMES' in the EVP_MAC_ docs"}, + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file to MAC (default is stdin)"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, + {"binary", OPT_BIN, '-', + "Output in binary format (default is hexadecimal)"}, + + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"mac_name", 0, 0, "MAC algorithm"}, + {NULL} +}; + +static char *alloc_mac_algorithm_name(STACK_OF(OPENSSL_STRING) **optp, + const char *name, const char *arg) +{ + size_t len = strlen(name) + strlen(arg) + 2; + char *res; + + if (*optp == NULL) + *optp = sk_OPENSSL_STRING_new_null(); + if (*optp == NULL) + return NULL; + + res = app_malloc(len, "algorithm name"); + BIO_snprintf(res, len, "%s:%s", name, arg); + if (sk_OPENSSL_STRING_push(*optp, res)) + return res; + OPENSSL_free(res); + return NULL; +} + +int mac_main(int argc, char **argv) +{ + int ret = 1; + char *prog; + EVP_MAC *mac = NULL; + OPTION_CHOICE o; + EVP_MAC_CTX *ctx = NULL; + STACK_OF(OPENSSL_STRING) *opts = NULL; + unsigned char *buf = NULL; + size_t len; + int i; + BIO *in = NULL, *out = NULL; + const char *outfile = NULL; + const char *infile = NULL; + int out_bin = 0; + int inform = FORMAT_BINARY; + char *digest = NULL, *cipher = NULL; + OSSL_PARAM *params = NULL; + + prog = opt_init(argc, argv, mac_options); + buf = app_malloc(BUFSIZE, "I/O buffer"); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + default: +opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto err; + case OPT_HELP: + opt_help(mac_options); + ret = 0; + goto err; + case OPT_BIN: + out_bin = 1; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_MACOPT: + if (opts == NULL) + opts = sk_OPENSSL_STRING_new_null(); + if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg())) + goto opthelp; + break; + case OPT_CIPHER: + OPENSSL_free(cipher); + cipher = alloc_mac_algorithm_name(&opts, "cipher", opt_arg()); + if (cipher == NULL) + goto opthelp; + break; + case OPT_DIGEST: + OPENSSL_free(digest); + digest = alloc_mac_algorithm_name(&opts, "digest", opt_arg()); + if (digest == NULL) + goto opthelp; + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto err; + break; + } + } + + /* One argument, the MAC name. */ + argc = opt_num_rest(); + argv = opt_rest(); + if (argc != 1) + goto opthelp; + + mac = EVP_MAC_fetch(app_get0_libctx(), argv[0], app_get0_propq()); + if (mac == NULL) { + BIO_printf(bio_err, "Invalid MAC name %s\n", argv[0]); + goto opthelp; + } + + ctx = EVP_MAC_CTX_new(mac); + if (ctx == NULL) + goto err; + + if (opts != NULL) { + int ok = 1; + + params = app_params_new_from_opts(opts, + EVP_MAC_settable_ctx_params(mac)); + if (params == NULL) + goto err; + + if (!EVP_MAC_CTX_set_params(ctx, params)) { + BIO_printf(bio_err, "MAC parameter error\n"); + ERR_print_errors(bio_err); + ok = 0; + } + app_params_free(params); + if (!ok) + goto err; + } + + in = bio_open_default(infile, 'r', inform); + if (in == NULL) + goto err; + + out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); + if (out == NULL) + goto err; + + if (!EVP_MAC_init(ctx, NULL, 0, NULL)) { + BIO_printf(bio_err, "EVP_MAC_Init failed\n"); + goto err; + } + + while (BIO_pending(in) || !BIO_eof(in)) { + i = BIO_read(in, (char *)buf, BUFSIZE); + if (i < 0) { + BIO_printf(bio_err, "Read Error in '%s'\n", infile); + ERR_print_errors(bio_err); + goto err; + } + if (i == 0) + break; + if (!EVP_MAC_update(ctx, buf, i)) { + BIO_printf(bio_err, "EVP_MAC_update failed\n"); + goto err; + } + } + + if (!EVP_MAC_final(ctx, NULL, &len, 0)) { + BIO_printf(bio_err, "EVP_MAC_final failed\n"); + goto err; + } + if (len > BUFSIZE) { + BIO_printf(bio_err, "output len is too large\n"); + goto err; + } + + if (!EVP_MAC_final(ctx, buf, &len, BUFSIZE)) { + BIO_printf(bio_err, "EVP_MAC_final failed\n"); + goto err; + } + + if (out_bin) { + BIO_write(out, buf, len); + } else { + for (i = 0; i < (int)len; ++i) + BIO_printf(out, "%02X", buf[i]); + if (outfile == NULL) + BIO_printf(out,"\n"); + } + + ret = 0; +err: + if (ret != 0) + ERR_print_errors(bio_err); + OPENSSL_clear_free(buf, BUFSIZE); + OPENSSL_free(cipher); + OPENSSL_free(digest); + sk_OPENSSL_STRING_free(opts); + BIO_free(in); + BIO_free(out); + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + return ret; +} diff --git a/crypto/openssl/apps/nseq.c b/crypto/openssl/apps/nseq.c index a067c915926f..d5524370f26c 100644 --- a/crypto/openssl/apps/nseq.c +++ b/crypto/openssl/apps/nseq.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,15 +15,23 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_TOSEQ, OPT_IN, OPT_OUT + OPT_COMMON, + OPT_TOSEQ, OPT_IN, OPT_OUT, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS nseq_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"toseq", OPT_TOSEQ, '-', "Output NS Sequence file"}, + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file"}, + + OPT_SECTION("Output"), + {"toseq", OPT_TOSEQ, '-', "Output NS Sequence file"}, {"out", OPT_OUT, '>', "Output file"}, + + OPT_PROV_OPTIONS, {NULL} }; @@ -57,8 +65,14 @@ int nseq_main(int argc, char **argv) case OPT_OUT: outfile = opt_arg(); break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; @@ -77,8 +91,10 @@ int nseq_main(int argc, char **argv) seq->certs = sk_X509_new_null(); if (seq->certs == NULL) goto end; - while ((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) - sk_X509_push(seq->certs, x509); + while ((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) { + if (!sk_X509_push(seq->certs, x509)) + goto end; + } if (!sk_X509_num(seq->certs)) { BIO_printf(bio_err, "%s: Error reading certs file %s\n", diff --git a/crypto/openssl/apps/ocsp.c b/crypto/openssl/apps/ocsp.c index 8f20864cea51..821e224c6ce4 100644 --- a/crypto/openssl/apps/ocsp.c +++ b/crypto/openssl/apps/ocsp.c @@ -1,7 +1,7 @@ /* * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,8 +10,8 @@ #include #ifdef OPENSSL_SYS_VMS -# define _XOPEN_SOURCE_EXTENDED/* So fd_set and friends get properly defined - * on OpenVMS */ + /* So fd_set and friends get properly defined on OpenVMS */ +# define _XOPEN_SOURCE_EXTENDED #endif #include @@ -22,6 +22,7 @@ /* Needs to be included before the openssl headers */ #include "apps.h" +#include "http_server.h" #include "progs.h" #include "internal/sockets.h" #include @@ -31,37 +32,11 @@ #include #include #include -#include -#ifndef HAVE_FORK -#if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) -# define HAVE_FORK 0 -#else -# define HAVE_FORK 1 -#endif -#endif - -#if HAVE_FORK -#undef NO_FORK -#else -#define NO_FORK -#endif - -#if !defined(NO_FORK) && !defined(OPENSSL_NO_SOCK) \ - && !defined(OPENSSL_NO_POSIX_IO) -# define OCSP_DAEMON -# include -# include -# include -# include -# define MAXERRLEN 1000 /* limit error text sent to syslog to 1000 bytes */ -#else -# undef LOG_INFO -# undef LOG_WARNING -# undef LOG_ERR -# define LOG_INFO 0 -# define LOG_WARNING 1 -# define LOG_ERR 2 +#if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif #endif #if defined(OPENSSL_SYS_VXWORKS) @@ -87,7 +62,7 @@ static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD *cert_id_md, X509 *issuer, STACK_OF(OCSP_CERTID) *ids); -static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, +static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, STACK_OF(OPENSSL_STRING) *names, STACK_OF(OCSP_CERTID) *ids, long nsec, long maxage); @@ -96,76 +71,118 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req EVP_PKEY *rkey, const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(X509) *rother, unsigned long flags, - int nmin, int ndays, int badsig); + int nmin, int ndays, int badsig, + const EVP_MD *resp_md); static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser); -static BIO *init_responder(const char *port); -static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, int timeout); -static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp); -static void log_message(int level, const char *fmt, ...); +static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, + const char *port, int timeout); +static int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp); static char *prog; -static int multi = 0; -#ifdef OCSP_DAEMON -static int acfd = (int) INVALID_SOCKET; +#ifdef HTTP_DAEMON static int index_changed(CA_DB *); -static void spawn_loop(void); -static int print_syslog(const char *str, size_t len, void *levPtr); -static void socket_timeout(int signum); -#endif - -#ifndef OPENSSL_NO_SOCK -static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, - const char *path, - const STACK_OF(CONF_VALUE) *headers, - OCSP_REQUEST *req, int req_timeout); #endif typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_OUTFILE, OPT_TIMEOUT, OPT_URL, OPT_HOST, OPT_PORT, +#ifndef OPENSSL_NO_SOCK + OPT_PROXY, OPT_NO_PROXY, +#endif OPT_IGNORE_ERR, OPT_NOVERIFY, OPT_NONCE, OPT_NO_NONCE, OPT_RESP_NO_CERTS, OPT_RESP_KEY_ID, OPT_NO_CERTS, OPT_NO_SIGNATURE_VERIFY, OPT_NO_CERT_VERIFY, OPT_NO_CHAIN, OPT_NO_CERT_CHECKS, OPT_NO_EXPLICIT, OPT_TRUST_OTHER, OPT_NO_INTERN, OPT_BADSIG, OPT_TEXT, OPT_REQ_TEXT, OPT_RESP_TEXT, OPT_REQIN, OPT_RESPIN, OPT_SIGNER, OPT_VAFILE, OPT_SIGN_OTHER, - OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH, + OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, OPT_CASTORE, OPT_NOCAFILE, + OPT_NOCAPATH, OPT_NOCASTORE, OPT_VALIDITY_PERIOD, OPT_STATUS_AGE, OPT_SIGNKEY, OPT_REQOUT, OPT_RESPOUT, OPT_PATH, OPT_ISSUER, OPT_CERT, OPT_SERIAL, OPT_INDEX, OPT_CA, OPT_NMIN, OPT_REQUEST, OPT_NDAYS, OPT_RSIGNER, OPT_RKEY, OPT_ROTHER, OPT_RMD, OPT_RSIGOPT, OPT_HEADER, + OPT_PASSIN, + OPT_RCID, OPT_V_ENUM, OPT_MD, - OPT_MULTI + OPT_MULTI, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS ocsp_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"out", OPT_OUTFILE, '>', "Output filename"}, - {"timeout", OPT_TIMEOUT, 'p', - "Connection timeout (in seconds) to the OCSP responder"}, - {"url", OPT_URL, 's', "Responder URL"}, - {"host", OPT_HOST, 's', "TCP/IP hostname:port to connect to"}, - {"port", OPT_PORT, 'p', "Port to run responder on"}, {"ignore_err", OPT_IGNORE_ERR, '-', "Ignore error on OCSP request or response and continue running"}, - {"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"}, - {"nonce", OPT_NONCE, '-', "Add OCSP nonce to request"}, - {"no_nonce", OPT_NO_NONCE, '-', "Don't add OCSP nonce to request"}, + {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, + {"CApath", OPT_CAPATH, '<', "Trusted certificates directory"}, + {"CAstore", OPT_CASTORE, ':', "Trusted certificates store URI"}, + {"no-CAfile", OPT_NOCAFILE, '-', + "Do not load the default certificates file"}, + {"no-CApath", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates directory"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store"}, + + OPT_SECTION("Responder"), + {"timeout", OPT_TIMEOUT, 'p', + "Connection timeout (in seconds) to the OCSP responder"}, {"resp_no_certs", OPT_RESP_NO_CERTS, '-', "Don't include any certificates in response"}, - {"resp_key_id", OPT_RESP_KEY_ID, '-', - "Identify response by signing certificate key ID"}, -#ifdef OCSP_DAEMON +#ifdef HTTP_DAEMON {"multi", OPT_MULTI, 'p', "run multiple responder processes"}, #endif {"no_certs", OPT_NO_CERTS, '-', "Don't include any certificates in signed request"}, + {"badsig", OPT_BADSIG, '-', + "Corrupt last byte of loaded OCSP response signature (for test)"}, + {"CA", OPT_CA, '<', "CA certificate"}, + {"nmin", OPT_NMIN, 'p', "Number of minutes before next update"}, + {"nrequest", OPT_REQUEST, 'p', + "Number of requests to accept (default unlimited)"}, + {"reqin", OPT_REQIN, 's', "File with the DER-encoded request"}, + {"signer", OPT_SIGNER, '<', "Certificate to sign OCSP request with"}, + {"sign_other", OPT_SIGN_OTHER, '<', + "Additional certificates to include in signed request"}, + {"index", OPT_INDEX, '<', "Certificate status index file"}, + {"ndays", OPT_NDAYS, 'p', "Number of days before next update"}, + {"rsigner", OPT_RSIGNER, '<', + "Responder certificate to sign responses with"}, + {"rkey", OPT_RKEY, '<', "Responder key to sign responses with"}, + {"passin", OPT_PASSIN, 's', "Responder key pass phrase source"}, + {"rother", OPT_ROTHER, '<', "Other certificates to include in response"}, + {"rmd", OPT_RMD, 's', "Digest Algorithm to use in signature of OCSP response"}, + {"rsigopt", OPT_RSIGOPT, 's', "OCSP response signature parameter in n:v form"}, + {"header", OPT_HEADER, 's', "key=value header to add"}, + {"rcid", OPT_RCID, 's', "Use specified algorithm for cert id in response"}, + {"", OPT_MD, '-', "Any supported digest algorithm (sha1,sha256, ... )"}, + + OPT_SECTION("Client"), + {"url", OPT_URL, 's', "Responder URL"}, + {"host", OPT_HOST, 's', "TCP/IP hostname:port to connect to"}, + {"port", OPT_PORT, 'N', "Port to run responder on"}, + {"path", OPT_PATH, 's', "Path to use in OCSP request"}, +#ifndef OPENSSL_NO_SOCK + {"proxy", OPT_PROXY, 's', + "[http[s]://]host[:port][/path] of HTTP(S) proxy to use; path is ignored"}, + {"no_proxy", OPT_NO_PROXY, 's', + "List of addresses of servers not to use HTTP(S) proxy for"}, + {OPT_MORE_STR, 0, 0, + "Default from environment variable 'no_proxy', else 'NO_PROXY', else none"}, +#endif + {"out", OPT_OUTFILE, '>', "Output filename"}, + {"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"}, + {"nonce", OPT_NONCE, '-', "Add OCSP nonce to request"}, + {"no_nonce", OPT_NO_NONCE, '-', "Don't add OCSP nonce to request"}, {"no_signature_verify", OPT_NO_SIGNATURE_VERIFY, '-', "Don't check signature on response"}, + {"resp_key_id", OPT_RESP_KEY_ID, '-', + "Identify response by signing certificate key ID"}, {"no_cert_verify", OPT_NO_CERT_VERIFY, '-', "Don't check signing certificate"}, + {"text", OPT_TEXT, '-', "Print text form of request and response"}, + {"req_text", OPT_REQ_TEXT, '-', "Print text form of request"}, + {"resp_text", OPT_RESP_TEXT, '-', "Print text form of response"}, {"no_chain", OPT_NO_CHAIN, '-', "Don't chain verify response"}, {"no_cert_checks", OPT_NO_CERT_CHECKS, '-', "Don't do additional checks on signing certificate"}, @@ -175,57 +192,29 @@ const OPTIONS ocsp_options[] = { "Don't verify additional certificates"}, {"no_intern", OPT_NO_INTERN, '-', "Don't search certificates contained in response for signer"}, - {"badsig", OPT_BADSIG, '-', - "Corrupt last byte of loaded OCSP response signature (for test)"}, - {"text", OPT_TEXT, '-', "Print text form of request and response"}, - {"req_text", OPT_REQ_TEXT, '-', "Print text form of request"}, - {"resp_text", OPT_RESP_TEXT, '-', "Print text form of response"}, - {"reqin", OPT_REQIN, 's', "File with the DER-encoded request"}, {"respin", OPT_RESPIN, 's', "File with the DER-encoded response"}, - {"signer", OPT_SIGNER, '<', "Certificate to sign OCSP request with"}, {"VAfile", OPT_VAFILE, '<', "Validator certificates file"}, - {"sign_other", OPT_SIGN_OTHER, '<', - "Additional certificates to include in signed request"}, {"verify_other", OPT_VERIFY_OTHER, '<', "Additional certificates to search for signer"}, - {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, - {"CApath", OPT_CAPATH, '<', "Trusted certificates directory"}, - {"no-CAfile", OPT_NOCAFILE, '-', - "Do not load the default certificates file"}, - {"no-CApath", OPT_NOCAPATH, '-', - "Do not load certificates from the default certificates directory"}, + {"cert", OPT_CERT, '<', "Certificate to check"}, + {"serial", OPT_SERIAL, 's', "Serial number to check"}, {"validity_period", OPT_VALIDITY_PERIOD, 'u', "Maximum validity discrepancy in seconds"}, - {"status_age", OPT_STATUS_AGE, 'p', "Maximum status age in seconds"}, {"signkey", OPT_SIGNKEY, 's', "Private key to sign OCSP request with"}, {"reqout", OPT_REQOUT, 's', "Output file for the DER-encoded request"}, {"respout", OPT_RESPOUT, 's', "Output file for the DER-encoded response"}, - {"path", OPT_PATH, 's', "Path to use in OCSP request"}, {"issuer", OPT_ISSUER, '<', "Issuer certificate"}, - {"cert", OPT_CERT, '<', "Certificate to check"}, - {"serial", OPT_SERIAL, 's', "Serial number to check"}, - {"index", OPT_INDEX, '<', "Certificate status index file"}, - {"CA", OPT_CA, '<', "CA certificate"}, - {"nmin", OPT_NMIN, 'p', "Number of minutes before next update"}, - {"nrequest", OPT_REQUEST, 'p', - "Number of requests to accept (default unlimited)"}, - {"ndays", OPT_NDAYS, 'p', "Number of days before next update"}, - {"rsigner", OPT_RSIGNER, '<', - "Responder certificate to sign responses with"}, - {"rkey", OPT_RKEY, '<', "Responder key to sign responses with"}, - {"rother", OPT_ROTHER, '<', "Other certificates to include in response"}, - {"rmd", OPT_RMD, 's', "Digest Algorithm to use in signature of OCSP response"}, - {"rsigopt", OPT_RSIGOPT, 's', "OCSP response signature parameter in n:v form"}, - {"header", OPT_HEADER, 's', "key=value header to add"}, - {"", OPT_MD, '-', "Any supported digest algorithm (sha1,sha256, ... )"}, + {"status_age", OPT_STATUS_AGE, 'p', "Maximum status age in seconds"}, + OPT_V_OPTIONS, + OPT_PROV_OPTIONS, {NULL} }; int ocsp_main(int argc, char **argv) { BIO *acbio = NULL, *cbio = NULL, *derbio = NULL, *out = NULL; - const EVP_MD *cert_id_md = NULL, *rsign_md = NULL; + EVP_MD *cert_id_md = NULL, *rsign_md = NULL; STACK_OF(OPENSSL_STRING) *rsign_sigopts = NULL; int trailing_md = 0; CA_DB *rdb = NULL; @@ -240,35 +229,37 @@ int ocsp_main(int argc, char **argv) STACK_OF(X509) *issuers = NULL; X509 *issuer = NULL, *cert = NULL; STACK_OF(X509) *rca_cert = NULL; + EVP_MD *resp_certid_md = NULL; X509 *signer = NULL, *rsigner = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; - const char *CAfile = NULL, *CApath = NULL; - char *header, *value; + const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL; + char *header, *value, *respdigname = NULL; char *host = NULL, *port = NULL, *path = "/", *outfile = NULL; +#ifndef OPENSSL_NO_SOCK + char *opt_proxy = NULL; + char *opt_no_proxy = NULL; +#endif char *rca_filename = NULL, *reqin = NULL, *respin = NULL; char *reqout = NULL, *respout = NULL, *ridx_filename = NULL; char *rsignfile = NULL, *rkeyfile = NULL; + char *passinarg = NULL, *passin = NULL; char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; char *signfile = NULL, *keyfile = NULL; char *thost = NULL, *tport = NULL, *tpath = NULL; - int noCAfile = 0, noCApath = 0; + int noCAfile = 0, noCApath = 0, noCAstore = 0; int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1; int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1; - int req_text = 0, resp_text = 0, ret = 1; + int req_text = 0, resp_text = 0, res, ret = 1; int req_timeout = -1; long nsec = MAX_VALIDITY_PERIOD, maxage = -1; unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; OPTION_CHOICE o; - reqnames = sk_OPENSSL_STRING_new_null(); - if (reqnames == NULL) - goto end; - ids = sk_OCSP_CERTID_new_null(); - if (ids == NULL) + if ((reqnames = sk_OPENSSL_STRING_new_null()) == NULL + || (ids = sk_OCSP_CERTID_new_null()) == NULL + || (vpm = X509_VERIFY_PARAM_new()) == NULL) goto end; - if ((vpm = X509_VERIFY_PARAM_new()) == NULL) - return 1; prog = opt_init(argc, argv, ocsp_options); while ((o = opt_next()) != OPT_EOF) { @@ -295,8 +286,10 @@ int ocsp_main(int argc, char **argv) OPENSSL_free(tport); OPENSSL_free(tpath); thost = tport = tpath = NULL; - if (!OCSP_parse_url(opt_arg(), &host, &port, &path, &use_ssl)) { - BIO_printf(bio_err, "%s Error parsing URL\n", prog); + if (!OSSL_HTTP_parse_url(opt_arg(), &use_ssl, NULL /* userinfo */, + &host, &port, NULL /* port_num */, + &path, NULL /* qry */, NULL /* frag */)) { + BIO_printf(bio_err, "%s Error parsing -url argument\n", prog); goto end; } thost = host; @@ -309,6 +302,17 @@ int ocsp_main(int argc, char **argv) case OPT_PORT: port = opt_arg(); break; + case OPT_PATH: + path = opt_arg(); + break; +#ifndef OPENSSL_NO_SOCK + case OPT_PROXY: + opt_proxy = opt_arg(); + break; + case OPT_NO_PROXY: + opt_no_proxy = opt_arg(); + break; +#endif case OPT_IGNORE_ERR: ignore_err = 1; break; @@ -388,12 +392,18 @@ int ocsp_main(int argc, char **argv) case OPT_CAPATH: CApath = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_NOCAFILE: noCAfile = 1; break; case OPT_NOCAPATH: noCApath = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_V_CASES: if (!opt_verify(o, vpm)) goto end; @@ -414,26 +424,24 @@ int ocsp_main(int argc, char **argv) case OPT_RESPOUT: respout = opt_arg(); break; - case OPT_PATH: - path = opt_arg(); - break; case OPT_ISSUER: - issuer = load_cert(opt_arg(), FORMAT_PEM, "issuer certificate"); + issuer = load_cert(opt_arg(), FORMAT_UNDEF, "issuer certificate"); if (issuer == NULL) goto end; if (issuers == NULL) { if ((issuers = sk_X509_new_null()) == NULL) goto end; } - sk_X509_push(issuers, issuer); + if (!sk_X509_push(issuers, issuer)) + goto end; break; case OPT_CERT: X509_free(cert); - cert = load_cert(opt_arg(), FORMAT_PEM, "certificate"); + cert = load_cert(opt_arg(), FORMAT_UNDEF, "certificate"); if (cert == NULL) goto end; if (cert_id_md == NULL) - cert_id_md = EVP_sha1(); + cert_id_md = (EVP_MD *)EVP_sha1(); if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids)) goto end; if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) @@ -442,7 +450,7 @@ int ocsp_main(int argc, char **argv) break; case OPT_SERIAL: if (cert_id_md == NULL) - cert_id_md = EVP_sha1(); + cert_id_md = (EVP_MD *)EVP_sha1(); if (!add_ocsp_serial(&req, opt_arg(), cert_id_md, issuer, ids)) goto end; if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) @@ -456,12 +464,12 @@ int ocsp_main(int argc, char **argv) rca_filename = opt_arg(); break; case OPT_NMIN: - opt_int(opt_arg(), &nmin); + nmin = opt_int_arg(); if (ndays == -1) ndays = 0; break; case OPT_REQUEST: - opt_int(opt_arg(), &accept_count); + accept_count = opt_int_arg(); break; case OPT_NDAYS: ndays = atoi(opt_arg()); @@ -472,17 +480,20 @@ int ocsp_main(int argc, char **argv) case OPT_RKEY: rkeyfile = opt_arg(); break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; case OPT_ROTHER: rcertfile = opt_arg(); break; case OPT_RMD: /* Response MessageDigest */ - if (!opt_md(opt_arg(), &rsign_md)) - goto end; + respdigname = opt_arg(); break; case OPT_RSIGOPT: if (rsign_sigopts == NULL) rsign_sigopts = sk_OPENSSL_STRING_new_null(); - if (rsign_sigopts == NULL || !sk_OPENSSL_STRING_push(rsign_sigopts, opt_arg())) + if (rsign_sigopts == NULL + || !sk_OPENSSL_STRING_push(rsign_sigopts, opt_arg())) goto end; break; case OPT_HEADER: @@ -496,6 +507,10 @@ int ocsp_main(int argc, char **argv) if (!X509V3_add_value(header, value, &headers)) goto end; break; + case OPT_RCID: + if (!opt_md(opt_arg(), &resp_certid_md)) + goto opthelp; + break; case OPT_MD: if (trailing_md) { BIO_printf(bio_err, @@ -508,20 +523,32 @@ int ocsp_main(int argc, char **argv) trailing_md = 1; break; case OPT_MULTI: -#ifdef OCSP_DAEMON +#ifdef HTTP_DAEMON multi = atoi(opt_arg()); #endif break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No extra arguments. */ + argc = opt_num_rest(); + if (argc != 0) + goto opthelp; + if (trailing_md) { BIO_printf(bio_err, "%s: Digest must be before -cert or -serial\n", prog); goto opthelp; } - argc = opt_num_rest(); - if (argc != 0) - goto opthelp; + + if (respdigname != NULL) { + if (!opt_md(respdigname, &rsign_md)) + goto end; + } /* Have we anything to do? */ if (req == NULL && reqin == NULL @@ -548,28 +575,36 @@ int ocsp_main(int argc, char **argv) } if (req == NULL && port != NULL) { - acbio = init_responder(port); +#ifndef OPENSSL_NO_SOCK + acbio = http_server_init_bio(prog, port); if (acbio == NULL) goto end; +#else + BIO_printf(bio_err, "Cannot act as server - sockets not supported\n"); + goto end; +#endif } if (rsignfile != NULL) { if (rkeyfile == NULL) rkeyfile = rsignfile; - rsigner = load_cert(rsignfile, FORMAT_PEM, "responder certificate"); + rsigner = load_cert(rsignfile, FORMAT_UNDEF, "responder certificate"); if (rsigner == NULL) { BIO_printf(bio_err, "Error loading responder certificate\n"); goto end; } - if (!load_certs(rca_filename, &rca_cert, FORMAT_PEM, - NULL, "CA certificate")) + if (!load_certs(rca_filename, 0, &rca_cert, NULL, "CA certificates")) goto end; if (rcertfile != NULL) { - if (!load_certs(rcertfile, &rother, FORMAT_PEM, NULL, + if (!load_certs(rcertfile, 0, &rother, NULL, "responder other certificates")) goto end; } - rkey = load_key(rkeyfile, FORMAT_PEM, 0, NULL, NULL, + if (!app_passwd(passinarg, NULL, &passin, NULL)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + rkey = load_key(rkeyfile, FORMAT_UNDEF, 0, passin, NULL, "responder private key"); if (rkey == NULL) goto end; @@ -585,25 +620,28 @@ int ocsp_main(int argc, char **argv) if (ridx_filename != NULL) { rdb = load_index(ridx_filename, NULL); if (rdb == NULL || index_index(rdb) <= 0) { + BIO_printf(bio_err, + "Problem with index file: %s (could not load/parse file)\n", + ridx_filename); ret = 1; goto end; } } -#ifdef OCSP_DAEMON +#ifdef HTTP_DAEMON if (multi && acbio != NULL) - spawn_loop(); + spawn_loop(prog); if (acbio != NULL && req_timeout > 0) signal(SIGALRM, socket_timeout); #endif if (acbio != NULL) - log_message(LOG_INFO, "waiting for OCSP client connections..."); + log_message(prog, LOG_INFO, "waiting for OCSP client connections..."); redo_accept: if (acbio != NULL) { -#ifdef OCSP_DAEMON +#ifdef HTTP_DAEMON if (index_changed(rdb)) { CA_DB *newrdb = load_index(ridx_filename, NULL); @@ -612,21 +650,24 @@ int ocsp_main(int argc, char **argv) rdb = newrdb; } else { free_index(newrdb); - log_message(LOG_ERR, "error reloading updated index: %s", + log_message(prog, LOG_ERR, "error reloading updated index: %s", ridx_filename); } } #endif req = NULL; - if (!do_responder(&req, &cbio, acbio, req_timeout)) + res = do_responder(&req, &cbio, acbio, port, req_timeout); + if (res == 0) goto redo_accept; if (req == NULL) { - resp = - OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, - NULL); - send_ocsp_response(cbio, resp); + if (res == 1) { + resp = + OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, + NULL); + send_ocsp_response(cbio, resp); + } goto done_resp; } } @@ -646,23 +687,23 @@ int ocsp_main(int argc, char **argv) if (signfile != NULL) { if (keyfile == NULL) keyfile = signfile; - signer = load_cert(signfile, FORMAT_PEM, "signer certificate"); + signer = load_cert(signfile, FORMAT_UNDEF, "signer certificate"); if (signer == NULL) { BIO_printf(bio_err, "Error loading signer certificate\n"); goto end; } if (sign_certfile != NULL) { - if (!load_certs(sign_certfile, &sign_other, FORMAT_PEM, NULL, + if (!load_certs(sign_certfile, 0, &sign_other, NULL, "signer certificates")) goto end; } - key = load_key(keyfile, FORMAT_PEM, 0, NULL, NULL, + key = load_key(keyfile, FORMAT_UNDEF, 0, NULL, NULL, "signer private key"); if (key == NULL) goto end; - if (!OCSP_request_sign - (req, signer, key, NULL, sign_other, sign_flags)) { + if (!OCSP_request_sign(req, signer, key, NULL, + sign_other, sign_flags)) { BIO_printf(bio_err, "Error signing OCSP request\n"); goto end; } @@ -681,18 +722,21 @@ int ocsp_main(int argc, char **argv) if (rdb != NULL) { make_ocsp_response(bio_err, &resp, req, rdb, rca_cert, rsigner, rkey, - rsign_md, rsign_sigopts, rother, rflags, nmin, ndays, badsig); + rsign_md, rsign_sigopts, rother, rflags, nmin, ndays, + badsig, resp_certid_md); + if (resp == NULL) + goto end; if (cbio != NULL) send_ocsp_response(cbio, resp); } else if (host != NULL) { #ifndef OPENSSL_NO_SOCK - resp = process_responder(req, host, path, - port, use_ssl, headers, req_timeout); + resp = process_responder(req, host, port, path, opt_proxy, opt_no_proxy, + use_ssl, headers, req_timeout); if (resp == NULL) goto end; #else BIO_printf(bio_err, - "Error creating connect BIO - sockets not supported.\n"); + "Error creating connect BIO - sockets not supported\n"); goto end; #endif } else if (respin != NULL) { @@ -752,15 +796,16 @@ int ocsp_main(int argc, char **argv) } if (store == NULL) { - store = setup_verify(CAfile, CApath, noCAfile, noCApath); + store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore); if (!store) goto end; } if (vpmtouched) X509_STORE_set1_param(store, vpm); if (verify_certfile != NULL) { - if (!load_certs(verify_certfile, &verify_other, FORMAT_PEM, NULL, - "validator certificate")) + if (!load_certs(verify_certfile, 0, &verify_other, NULL, + "validator certificates")) goto end; } @@ -798,7 +843,8 @@ int ocsp_main(int argc, char **argv) } } - print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage); + if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) + ret = 1; end: ERR_print_errors(bio_err); @@ -808,6 +854,9 @@ int ocsp_main(int argc, char **argv) sk_OPENSSL_STRING_free(rsign_sigopts); EVP_PKEY_free(key); EVP_PKEY_free(rkey); + EVP_MD_free(cert_id_md); + EVP_MD_free(rsign_md); + EVP_MD_free(resp_certid_md); X509_free(cert); sk_X509_pop_free(issuers, X509_free); X509_free(rsigner); @@ -831,41 +880,7 @@ int ocsp_main(int argc, char **argv) return ret; } -static void -log_message(int level, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); -#ifdef OCSP_DAEMON - if (multi) { - char buf[1024]; - if (vsnprintf(buf, sizeof(buf), fmt, ap) > 0) { - syslog(level, "%s", buf); - } - if (level >= LOG_ERR) - ERR_print_errors_cb(print_syslog, &level); - } -#endif - if (!multi) { - BIO_printf(bio_err, "%s: ", prog); - BIO_vprintf(bio_err, fmt, ap); - BIO_printf(bio_err, "\n"); - } - va_end(ap); -} - -#ifdef OCSP_DAEMON - -static int print_syslog(const char *str, size_t len, void *levPtr) -{ - int level = *(int *)levPtr; - int ilen = (len > MAXERRLEN) ? MAXERRLEN : len; - - syslog(level, "%.*s", ilen, str); - - return ilen; -} +#ifdef HTTP_DAEMON static int index_changed(CA_DB *rdb) { @@ -883,131 +898,6 @@ static int index_changed(CA_DB *rdb) return 0; } -static void killall(int ret, pid_t *kidpids) -{ - int i; - - for (i = 0; i < multi; ++i) - if (kidpids[i] != 0) - (void)kill(kidpids[i], SIGTERM); - OPENSSL_free(kidpids); - sleep(1); - exit(ret); -} - -static int termsig = 0; - -static void noteterm (int sig) -{ - termsig = sig; -} - -/* - * Loop spawning up to `multi` child processes, only child processes return - * from this function. The parent process loops until receiving a termination - * signal, kills extant children and exits without returning. - */ -static void spawn_loop(void) -{ - pid_t *kidpids = NULL; - int status; - int procs = 0; - int i; - - openlog(prog, LOG_PID, LOG_DAEMON); - - if (setpgid(0, 0)) { - syslog(LOG_ERR, "fatal: error detaching from parent process group: %s", - strerror(errno)); - exit(1); - } - kidpids = app_malloc(multi * sizeof(*kidpids), "child PID array"); - for (i = 0; i < multi; ++i) - kidpids[i] = 0; - - signal(SIGINT, noteterm); - signal(SIGTERM, noteterm); - - while (termsig == 0) { - pid_t fpid; - - /* - * Wait for a child to replace when we're at the limit. - * Slow down if a child exited abnormally or waitpid() < 0 - */ - while (termsig == 0 && procs >= multi) { - if ((fpid = waitpid(-1, &status, 0)) > 0) { - for (i = 0; i < procs; ++i) { - if (kidpids[i] == fpid) { - kidpids[i] = 0; - --procs; - break; - } - } - if (i >= multi) { - syslog(LOG_ERR, "fatal: internal error: " - "no matching child slot for pid: %ld", - (long) fpid); - killall(1, kidpids); - } - if (status != 0) { - if (WIFEXITED(status)) - syslog(LOG_WARNING, "child process: %ld, exit status: %d", - (long)fpid, WEXITSTATUS(status)); - else if (WIFSIGNALED(status)) - syslog(LOG_WARNING, "child process: %ld, term signal %d%s", - (long)fpid, WTERMSIG(status), -#ifdef WCOREDUMP - WCOREDUMP(status) ? " (core dumped)" : -#endif - ""); - sleep(1); - } - break; - } else if (errno != EINTR) { - syslog(LOG_ERR, "fatal: waitpid(): %s", strerror(errno)); - killall(1, kidpids); - } - } - if (termsig) - break; - - switch(fpid = fork()) { - case -1: /* error */ - /* System critically low on memory, pause and try again later */ - sleep(30); - break; - case 0: /* child */ - OPENSSL_free(kidpids); - signal(SIGINT, SIG_DFL); - signal(SIGTERM, SIG_DFL); - if (termsig) - _exit(0); - if (RAND_poll() <= 0) { - syslog(LOG_ERR, "fatal: RAND_poll() failed"); - _exit(1); - } - return; - default: /* parent */ - for (i = 0; i < multi; ++i) { - if (kidpids[i] == 0) { - kidpids[i] = fpid; - procs++; - break; - } - } - if (i >= multi) { - syslog(LOG_ERR, "fatal: internal error: no free child slots"); - killall(1, kidpids); - } - break; - } - } - - /* The loop above can only break on termsig */ - syslog(LOG_INFO, "terminating on signal: %d", termsig); - killall(0, kidpids); -} #endif static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, @@ -1041,7 +931,7 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, STACK_OF(OCSP_CERTID) *ids) { OCSP_CERTID *id; - X509_NAME *iname; + const X509_NAME *iname; ASN1_BIT_STRING *ikey; ASN1_INTEGER *sno; @@ -1073,7 +963,7 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, return 0; } -static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, +static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, STACK_OF(OPENSSL_STRING) *names, STACK_OF(OCSP_CERTID) *ids, long nsec, long maxage) @@ -1082,10 +972,13 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, const char *name; int i, status, reason; ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; + int ret = 1; - if (bs == NULL || req == NULL || !sk_OPENSSL_STRING_num(names) - || !sk_OCSP_CERTID_num(ids)) - return; + if (req == NULL || !sk_OPENSSL_STRING_num(names)) + return 1; + + if (bs == NULL || !sk_OCSP_CERTID_num(ids)) + return 0; for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) { id = sk_OCSP_CERTID_value(ids, i); @@ -1095,6 +988,7 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, if (!OCSP_resp_find_status(bs, id, &status, &reason, &rev, &thisupd, &nextupd)) { BIO_puts(out, "ERROR: No Status found.\n"); + ret = 0; continue; } @@ -1128,6 +1022,7 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, ASN1_GENERALIZEDTIME_print(out, rev); BIO_puts(out, "\n"); } + return ret; } static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req, @@ -1135,7 +1030,8 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req EVP_PKEY *rkey, const EVP_MD *rmd, STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(X509) *rother, unsigned long flags, - int nmin, int ndays, int badsig) + int nmin, int ndays, int badsig, + const EVP_MD *resp_md) { ASN1_TIME *thisupd = NULL, *nextupd = NULL; OCSP_CERTID *cid; @@ -1166,6 +1062,8 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req int found = 0; ASN1_OBJECT *cert_id_md_oid; const EVP_MD *cert_id_md; + OCSP_CERTID *cid_resp_md = NULL; + one = OCSP_request_onereq_get0(req, i); cid = OCSP_onereq_get0_id(one); @@ -1181,11 +1079,18 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req X509 *ca_cert = sk_X509_value(ca, jj); OCSP_CERTID *ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca_cert); - if (OCSP_id_issuer_cmp(ca_id, cid) == 0) + if (OCSP_id_issuer_cmp(ca_id, cid) == 0) { found = 1; - + if (resp_md != NULL) + cid_resp_md = OCSP_cert_to_id(resp_md, NULL, ca_cert); + } OCSP_CERTID_free(ca_id); } + OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid); + inf = lookup_serial(db, serial); + + /* at this point, we can have cid be an alias of cid_resp_md */ + cid = (cid_resp_md != NULL) ? cid_resp_md : cid; if (!found) { OCSP_basic_add1_status(bs, cid, @@ -1193,8 +1098,6 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req 0, NULL, thisupd, nextupd); continue; } - OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid); - inf = lookup_serial(db, serial); if (inf == NULL) { OCSP_basic_add1_status(bs, cid, V_OCSP_CERTSTATUS_UNKNOWN, @@ -1209,10 +1112,16 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req ASN1_GENERALIZEDTIME *invtm = NULL; OCSP_SINGLERESP *single; int reason = -1; + unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]); single = OCSP_basic_add1_status(bs, cid, V_OCSP_CERTSTATUS_REVOKED, reason, revtm, thisupd, nextupd); + if (single == NULL) { + *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, + NULL); + goto end; + } if (invtm != NULL) OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0); @@ -1224,6 +1133,7 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req ASN1_TIME_free(revtm); ASN1_GENERALIZEDTIME_free(invtm); } + OCSP_CERTID_free(cid_resp_md); } OCSP_copy_nonce(bs, req); @@ -1273,10 +1183,12 @@ static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) bn = ASN1_INTEGER_to_BN(ser, NULL); OPENSSL_assert(bn); /* FIXME: should report an error at this * point and abort */ - if (BN_is_zero(bn)) + if (BN_is_zero(bn)) { itmp = OPENSSL_strdup("00"); - else + OPENSSL_assert(itmp); + } else { itmp = BN_bn2hex(bn); + } row[DB_serial] = itmp; BN_free(bn); rrow = TXT_DB_get_by_index(db->db, DB_serial, row); @@ -1284,339 +1196,66 @@ static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) return rrow; } -/* Quick and dirty OCSP server: read in and parse input request */ - -static BIO *init_responder(const char *port) -{ -#ifdef OPENSSL_NO_SOCK - BIO_printf(bio_err, - "Error setting up accept BIO - sockets not supported.\n"); - return NULL; -#else - BIO *acbio = NULL, *bufbio = NULL; - - bufbio = BIO_new(BIO_f_buffer()); - if (bufbio == NULL) - goto err; - acbio = BIO_new(BIO_s_accept()); - if (acbio == NULL - || BIO_set_bind_mode(acbio, BIO_BIND_REUSEADDR) < 0 - || BIO_set_accept_port(acbio, port) < 0) { - log_message(LOG_ERR, "Error setting up accept BIO"); - goto err; - } - - BIO_set_accept_bios(acbio, bufbio); - bufbio = NULL; - if (BIO_do_accept(acbio) <= 0) { - log_message(LOG_ERR, "Error starting accept"); - goto err; - } - - return acbio; - - err: - BIO_free_all(acbio); - BIO_free(bufbio); - return NULL; -#endif -} - -#ifndef OPENSSL_NO_SOCK -/* - * Decode %xx URL-decoding in-place. Ignores mal-formed sequences. - */ -static int urldecode(char *p) -{ - unsigned char *out = (unsigned char *)p; - unsigned char *save = out; - - for (; *p; p++) { - if (*p != '%') - *out++ = *p; - else if (isxdigit(_UC(p[1])) && isxdigit(_UC(p[2]))) { - /* Don't check, can't fail because of ixdigit() call. */ - *out++ = (OPENSSL_hexchar2int(p[1]) << 4) - | OPENSSL_hexchar2int(p[2]); - p += 2; - } - else - return -1; - } - *out = '\0'; - return (int)(out - save); -} -#endif - -#ifdef OCSP_DAEMON -static void socket_timeout(int signum) -{ - if (acfd != (int)INVALID_SOCKET) - (void)shutdown(acfd, SHUT_RD); -} -#endif - static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, - int timeout) + const char *port, int timeout) { -#ifdef OPENSSL_NO_SOCK - return 0; +#ifndef OPENSSL_NO_SOCK + return http_server_get_asn1_req(ASN1_ITEM_rptr(OCSP_REQUEST), + (ASN1_VALUE **)preq, NULL, pcbio, acbio, + NULL /* found_keep_alive */, + prog, port, 1 /* accept_get */, timeout); #else - int len; - OCSP_REQUEST *req = NULL; - char inbuf[2048], reqbuf[2048]; - char *p, *q; - BIO *cbio = NULL, *getbio = NULL, *b64 = NULL; - const char *client; - + BIO_printf(bio_err, + "Error getting OCSP request - sockets not supported\n"); *preq = NULL; - - /* Connection loss before accept() is routine, ignore silently */ - if (BIO_do_accept(acbio) <= 0) - return 0; - - cbio = BIO_pop(acbio); - *pcbio = cbio; - client = BIO_get_peer_name(cbio); - -# ifdef OCSP_DAEMON - if (timeout > 0) { - (void) BIO_get_fd(cbio, &acfd); - alarm(timeout); - } -# endif - - /* Read the request line. */ - len = BIO_gets(cbio, reqbuf, sizeof(reqbuf)); - if (len <= 0) - goto out; - - if (strncmp(reqbuf, "GET ", 4) == 0) { - /* Expecting GET {sp} /URL {sp} HTTP/1.x */ - for (p = reqbuf + 4; *p == ' '; ++p) - continue; - if (*p != '/') { - log_message(LOG_INFO, "Invalid request -- bad URL: %s", client); - goto out; - } - p++; - - /* Splice off the HTTP version identifier. */ - for (q = p; *q; q++) - if (*q == ' ') - break; - if (strncmp(q, " HTTP/1.", 8) != 0) { - log_message(LOG_INFO, - "Invalid request -- bad HTTP version: %s", client); - goto out; - } - *q = '\0'; - - /* - * 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[0] == '\0') - goto out; - - len = urldecode(p); - if (len <= 0) { - log_message(LOG_INFO, - "Invalid request -- bad URL encoding: %s", client); - goto out; - } - if ((getbio = BIO_new_mem_buf(p, len)) == NULL - || (b64 = BIO_new(BIO_f_base64())) == NULL) { - log_message(LOG_ERR, "Could not allocate base64 bio: %s", client); - goto out; - } - BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); - getbio = BIO_push(b64, getbio); - } else if (strncmp(reqbuf, "POST ", 5) != 0) { - log_message(LOG_INFO, "Invalid request -- bad HTTP verb: %s", client); - goto out; - } - - /* Read and skip past the headers. */ - for (;;) { - len = BIO_gets(cbio, inbuf, sizeof(inbuf)); - if (len <= 0) - goto out; - if ((inbuf[0] == '\r') || (inbuf[0] == '\n')) - break; - } - -# ifdef OCSP_DAEMON - /* Clear alarm before we close the client socket */ - alarm(0); - timeout = 0; -# endif - - /* Try to read OCSP request */ - if (getbio != NULL) { - req = d2i_OCSP_REQUEST_bio(getbio, NULL); - BIO_free_all(getbio); - } else { - req = d2i_OCSP_REQUEST_bio(cbio, NULL); - } - - if (req == NULL) - log_message(LOG_ERR, "Error parsing OCSP request"); - - *preq = req; - -out: -# ifdef OCSP_DAEMON - if (timeout > 0) - alarm(0); - acfd = (int)INVALID_SOCKET; -# endif - return 1; + return 0; #endif } -static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) +static int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp) { - char http_resp[] = - "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n" - "Content-Length: %d\r\n\r\n"; - if (cbio == NULL) - return 0; - BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL)); - i2d_OCSP_RESPONSE_bio(cbio, resp); - (void)BIO_flush(cbio); - return 1; -} - #ifndef OPENSSL_NO_SOCK -static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, - const char *path, - const STACK_OF(CONF_VALUE) *headers, - OCSP_REQUEST *req, int req_timeout) -{ - int fd; - int rv; - int i; - int add_host = 1; - OCSP_REQ_CTX *ctx = NULL; - OCSP_RESPONSE *rsp = NULL; - fd_set confds; - struct timeval tv; - - if (req_timeout != -1) - BIO_set_nbio(cbio, 1); - - rv = BIO_do_connect(cbio); - - if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) { - BIO_puts(bio_err, "Error connecting BIO\n"); - return NULL; - } - - if (BIO_get_fd(cbio, &fd) < 0) { - BIO_puts(bio_err, "Can't get connection fd\n"); - goto err; - } - - if (req_timeout != -1 && rv <= 0) { - FD_ZERO(&confds); - openssl_fdset(fd, &confds); - tv.tv_usec = 0; - tv.tv_sec = req_timeout; - rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); - if (rv == 0) { - BIO_puts(bio_err, "Timeout on connect\n"); - return NULL; - } - } - - ctx = OCSP_sendreq_new(cbio, path, NULL, -1); - if (ctx == NULL) - return NULL; - - for (i = 0; i < sk_CONF_VALUE_num(headers); i++) { - CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i); - if (add_host == 1 && strcasecmp("host", hdr->name) == 0) - add_host = 0; - if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value)) - goto err; - } - - if (add_host == 1 && OCSP_REQ_CTX_add1_header(ctx, "Host", host) == 0) - goto err; - - if (!OCSP_REQ_CTX_set1_req(ctx, req)) - goto err; - - for (;;) { - rv = OCSP_sendreq_nbio(&rsp, ctx); - if (rv != -1) - break; - if (req_timeout == -1) - continue; - FD_ZERO(&confds); - openssl_fdset(fd, &confds); - tv.tv_usec = 0; - tv.tv_sec = req_timeout; - if (BIO_should_read(cbio)) { - rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv); - } else if (BIO_should_write(cbio)) { - rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); - } else { - BIO_puts(bio_err, "Unexpected retry condition\n"); - goto err; - } - if (rv == 0) { - BIO_puts(bio_err, "Timeout on request\n"); - break; - } - if (rv == -1) { - BIO_puts(bio_err, "Select error\n"); - break; - } - - } - err: - OCSP_REQ_CTX_free(ctx); - - return rsp; + return http_server_send_asn1_resp(cbio, + 0 /* no keep-alive */, + "application/ocsp-response", + ASN1_ITEM_rptr(OCSP_RESPONSE), + (const ASN1_VALUE *)resp); +#else + BIO_printf(bio_err, + "Error sending OCSP response - sockets not supported\n"); + return 0; +#endif } -OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, - const char *host, const char *path, - const char *port, int use_ssl, - STACK_OF(CONF_VALUE) *headers, +#ifndef OPENSSL_NO_SOCK +OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, const char *host, + const char *port, const char *path, + const char *proxy, const char *no_proxy, + int use_ssl, STACK_OF(CONF_VALUE) *headers, int req_timeout) { - BIO *cbio = NULL; SSL_CTX *ctx = NULL; OCSP_RESPONSE *resp = NULL; - cbio = BIO_new_connect(host); - if (cbio == NULL) { - BIO_printf(bio_err, "Error creating connect BIO\n"); - goto end; - } - if (port != NULL) - BIO_set_conn_port(cbio, port); if (use_ssl == 1) { - BIO *sbio; ctx = SSL_CTX_new(TLS_client_method()); if (ctx == NULL) { BIO_printf(bio_err, "Error creating SSL context.\n"); goto end; } - SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); - sbio = BIO_new_ssl(ctx, 1); - cbio = BIO_push(sbio, cbio); } - resp = query_responder(cbio, host, path, headers, req, req_timeout); + resp = (OCSP_RESPONSE *) + app_http_post_asn1(host, port, path, proxy, no_proxy, + ctx, headers, "application/ocsp-request", + (ASN1_VALUE *)req, ASN1_ITEM_rptr(OCSP_REQUEST), + "application/ocsp-response", + req_timeout, ASN1_ITEM_rptr(OCSP_RESPONSE)); + if (resp == NULL) BIO_printf(bio_err, "Error querying OCSP responder\n"); + end: - BIO_free_all(cbio); SSL_CTX_free(ctx); return resp; } diff --git a/crypto/openssl/apps/openssl.c b/crypto/openssl/apps/openssl.c index f35d57f2648c..a3056c799f85 100644 --- a/crypto/openssl/apps/openssl.c +++ b/crypto/openssl/apps/openssl.c @@ -1,18 +1,18 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include #include #include #include #include #include +#include #include #include #include @@ -27,20 +27,8 @@ # include #endif #include "apps.h" -#define INCLUDE_FUNCTION_TABLE #include "progs.h" -/* Structure to hold the number of columns to be displayed and the - * field width used to display them. - */ -typedef struct { - int columns; - int width; -} DISPLAY_COLUMNS; - -/* Special sentinel to exit the program. */ -#define EXIT_THE_PROGRAM (-1) - /* * The LHASH callbacks ("hash" & "cmp") have been replaced by functions with * the base prototypes (we cast each variable inside the function to the @@ -49,32 +37,27 @@ typedef struct { */ static LHASH_OF(FUNCTION) *prog_init(void); static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]); -static void list_pkey(void); -static void list_pkey_meth(void); -static void list_type(FUNC_TYPE ft, int one); -static void list_disabled(void); char *default_config_file = NULL; BIO *bio_in = NULL; BIO *bio_out = NULL; BIO *bio_err = NULL; -static void calculate_columns(DISPLAY_COLUMNS *dc) +static void warn_deprecated(const FUNCTION *fp) { - FUNCTION *f; - int len, maxlen = 0; - - for (f = functions; f->name != NULL; ++f) - if (f->type == FT_general || f->type == FT_md || f->type == FT_cipher) - if ((len = strlen(f->name)) > maxlen) - maxlen = len; - - dc->width = maxlen + 2; - dc->columns = (80 - 1) / dc->width; + if (fp->deprecated_version != NULL) + BIO_printf(bio_err, "The command %s was deprecated in version %s.", + fp->name, fp->deprecated_version); + else + BIO_printf(bio_err, "The command %s is deprecated.", fp->name); + if (strcmp(fp->deprecated_alternative, DEPRECATED_NO_ALTERNATIVE) != 0) + BIO_printf(bio_err, " Use '%s' instead.", fp->deprecated_alternative); + BIO_printf(bio_err, "\n"); } static int apps_startup(void) { + const char *use_libctx = NULL; #ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); #endif @@ -84,53 +67,186 @@ static int apps_startup(void) | OPENSSL_INIT_LOAD_CONFIG, NULL)) return 0; - setup_ui_method(); + (void)setup_ui_method(); + (void)setup_engine_loader(); + + /* + * NOTE: This is an undocumented feature required for testing only. + * There are no guarantees that it will exist in future builds. + */ + use_libctx = getenv("OPENSSL_TEST_LIBCTX"); + if (use_libctx != NULL) { + /* Set this to "1" to create a global libctx */ + if (strcmp(use_libctx, "1") == 0) { + if (app_create_libctx() == NULL) + return 0; + } + } return 1; } static void apps_shutdown(void) { + app_providers_cleanup(); + OSSL_LIB_CTX_free(app_get0_libctx()); + destroy_engine_loader(); destroy_ui_method(); - destroy_prefix_method(); } -static char *make_config_name(void) + +#ifndef OPENSSL_NO_TRACE +typedef struct tracedata_st { + BIO *bio; + unsigned int ingroup:1; +} tracedata; + +static size_t internal_trace_cb(const char *buf, size_t cnt, + int category, int cmd, void *vdata) { - const char *t; - size_t len; - char *p; - - if ((t = getenv("OPENSSL_CONF")) != NULL) - return OPENSSL_strdup(t); - - t = X509_get_default_cert_area(); - len = strlen(t) + 1 + strlen(OPENSSL_CONF) + 1; - p = app_malloc(len, "config filename buffer"); - strcpy(p, t); -#ifndef OPENSSL_SYS_VMS - strcat(p, "/"); -#endif - strcat(p, OPENSSL_CONF); + int ret = 0; + tracedata *trace_data = vdata; + char buffer[256], *hex; + CRYPTO_THREAD_ID tid; + + switch (cmd) { + case OSSL_TRACE_CTRL_BEGIN: + if (trace_data->ingroup) { + BIO_printf(bio_err, "ERROR: tracing already started\n"); + return 0; + } + trace_data->ingroup = 1; + + tid = CRYPTO_THREAD_get_current_id(); + hex = OPENSSL_buf2hexstr((const unsigned char *)&tid, sizeof(tid)); + BIO_snprintf(buffer, sizeof(buffer), "TRACE[%s]:%s: ", + hex == NULL ? "" : hex, + OSSL_trace_get_category_name(category)); + OPENSSL_free(hex); + BIO_set_prefix(trace_data->bio, buffer); + break; + case OSSL_TRACE_CTRL_WRITE: + if (!trace_data->ingroup) { + BIO_printf(bio_err, "ERROR: writing when tracing not started\n"); + return 0; + } + + ret = BIO_write(trace_data->bio, buf, cnt); + break; + case OSSL_TRACE_CTRL_END: + if (!trace_data->ingroup) { + BIO_printf(bio_err, "ERROR: finishing when tracing not started\n"); + return 0; + } + trace_data->ingroup = 0; + + BIO_set_prefix(trace_data->bio, NULL); + + break; + } + + return ret < 0 ? 0 : ret; +} + +DEFINE_STACK_OF(tracedata) +static STACK_OF(tracedata) *trace_data_stack; - return p; +static void tracedata_free(tracedata *data) +{ + BIO_free_all(data->bio); + OPENSSL_free(data); } +static STACK_OF(tracedata) *trace_data_stack; + +static void cleanup_trace(void) +{ + sk_tracedata_pop_free(trace_data_stack, tracedata_free); +} + +static void setup_trace_category(int category) +{ + BIO *channel; + tracedata *trace_data; + BIO *bio = NULL; + + if (OSSL_trace_enabled(category)) + return; + + bio = BIO_new(BIO_f_prefix()); + channel = BIO_push(bio, dup_bio_err(FORMAT_TEXT)); + trace_data = OPENSSL_zalloc(sizeof(*trace_data)); + + if (trace_data == NULL + || bio == NULL + || (trace_data->bio = channel) == NULL + || OSSL_trace_set_callback(category, internal_trace_cb, + trace_data) == 0 + || sk_tracedata_push(trace_data_stack, trace_data) == 0) { + + fprintf(stderr, + "warning: unable to setup trace callback for category '%s'.\n", + OSSL_trace_get_category_name(category)); + + OSSL_trace_set_callback(category, NULL, NULL); + BIO_free_all(channel); + } +} + +static void setup_trace(const char *str) +{ + char *val; + + /* + * We add this handler as early as possible to ensure it's executed + * as late as possible, i.e. after the TRACE code has done its cleanup + * (which happens last in OPENSSL_cleanup). + */ + atexit(cleanup_trace); + + trace_data_stack = sk_tracedata_new_null(); + val = OPENSSL_strdup(str); + + if (val != NULL) { + char *valp = val; + char *item; + + for (valp = val; (item = strtok(valp, ",")) != NULL; valp = NULL) { + int category = OSSL_trace_get_category_num(item); + + if (category == OSSL_TRACE_CATEGORY_ALL) { + while (++category < OSSL_TRACE_CATEGORY_NUM) + setup_trace_category(category); + break; + } else if (category > 0) { + setup_trace_category(category); + } else { + fprintf(stderr, + "warning: unknown trace category: '%s'.\n", item); + } + } + } + + OPENSSL_free(val); +} +#endif /* OPENSSL_NO_TRACE */ + +static char *help_argv[] = { "help", NULL }; + int main(int argc, char *argv[]) { FUNCTION f, *fp; LHASH_OF(FUNCTION) *prog = NULL; - char *p, *pname; - char buf[1024]; - const char *prompt; + char *pname; + const char *fname; ARGS arg; - int first, n, i, ret = 0; + int global_help = 0; + int ret = 0; arg.argv = NULL; arg.size = 0; /* Set up some of the environment. */ - default_config_file = make_config_name(); bio_in = dup_bio_in(FORMAT_TEXT); bio_out = dup_bio_out(FORMAT_TEXT); bio_err = dup_bio_err(FORMAT_TEXT); @@ -138,319 +254,75 @@ int main(int argc, char *argv[]) #if defined(OPENSSL_SYS_VMS) && defined(__DECC) argv = copy_argv(&argc, argv); #elif defined(_WIN32) - /* - * Replace argv[] with UTF-8 encoded strings. - */ + /* Replace argv[] with UTF-8 encoded strings. */ win32_utf8argv(&argc, &argv); #endif - p = getenv("OPENSSL_DEBUG_MEMORY"); - if (p != NULL && strcmp(p, "on") == 0) - CRYPTO_set_mem_debug(1); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); - - if (getenv("OPENSSL_FIPS")) { - BIO_printf(bio_err, "FIPS mode not supported.\n"); - return 1; - } - - if (!apps_startup()) { - BIO_printf(bio_err, - "FATAL: Startup failure (dev note: apps_startup() failed)\n"); - ERR_print_errors(bio_err); - ret = 1; - goto end; - } +#ifndef OPENSSL_NO_TRACE + setup_trace(getenv("OPENSSL_TRACE")); +#endif - prog = prog_init(); - if (prog == NULL) { + if ((fname = "apps_startup", !apps_startup()) + || (fname = "prog_init", (prog = prog_init()) == NULL)) { BIO_printf(bio_err, - "FATAL: Startup failure (dev note: prog_init() failed)\n"); + "FATAL: Startup failure (dev note: %s()) for %s\n", + fname, argv[0]); ERR_print_errors(bio_err); ret = 1; goto end; } pname = opt_progname(argv[0]); + default_config_file = CONF_get1_default_config_file(); + if (default_config_file == NULL) + app_bail_out("%s: could not get default config file\n", pname); + /* first check the program name */ f.name = pname; fp = lh_FUNCTION_retrieve(prog, &f); - if (fp != NULL) { - argv[0] = pname; - ret = fp->func(argc, argv); - goto end; - } - - /* If there is stuff on the command line, run with that. */ - if (argc != 1) { + if (fp == NULL) { + /* We assume we've been called as 'openssl ...' */ + global_help = argc > 1 + && (strcmp(argv[1], "-help") == 0 || strcmp(argv[1], "--help") == 0 + || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--h") == 0); argc--; argv++; - ret = do_cmd(prog, argc, argv); - if (ret < 0) - ret = 0; - goto end; + opt_appname(argc == 1 || global_help ? "help" : argv[0]); + } else { + argv[0] = pname; } - /* ok, lets enter interactive mode */ - for (;;) { - ret = 0; - /* Read a line, continue reading if line ends with \ */ - for (p = buf, n = sizeof(buf), i = 0, first = 1; n > 0; first = 0) { - prompt = first ? "OpenSSL> " : "> "; - p[0] = '\0'; -#ifndef READLINE - fputs(prompt, stdout); - fflush(stdout); - if (!fgets(p, n, stdin)) - goto end; - if (p[0] == '\0') - goto end; - i = strlen(p); - if (i <= 1) - break; - if (p[i - 2] != '\\') - break; - i -= 2; - p += i; - n -= i; -#else - { - extern char *readline(const char *); - extern void add_history(const char *cp); - char *text; - - text = readline(prompt); - if (text == NULL) - goto end; - i = strlen(text); - if (i == 0 || i > n) - break; - if (text[i - 1] != '\\') { - p += strlen(strcpy(p, text)); - free(text); - add_history(buf); - break; - } - - text[i - 1] = '\0'; - p += strlen(strcpy(p, text)); - free(text); - n -= i; - } -#endif - } + /* If there's a command, run with that, otherwise "help". */ + ret = argc == 0 || global_help + ? do_cmd(prog, 1, help_argv) + : do_cmd(prog, argc, argv); - if (!chopup_args(&arg, buf)) { - BIO_printf(bio_err, "Can't parse (no memory?)\n"); - break; - } - - ret = do_cmd(prog, arg.argc, arg.argv); - if (ret == EXIT_THE_PROGRAM) { - ret = 0; - goto end; - } - if (ret != 0) - BIO_printf(bio_err, "error in %s\n", arg.argv[0]); - (void)BIO_flush(bio_out); - (void)BIO_flush(bio_err); - } - ret = 1; end: OPENSSL_free(default_config_file); lh_FUNCTION_free(prog); OPENSSL_free(arg.argv); - app_RAND_write(); + if (!app_RAND_write()) + ret = EXIT_FAILURE; BIO_free(bio_in); BIO_free_all(bio_out); apps_shutdown(); -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - if (CRYPTO_mem_leaks(bio_err) <= 0) - ret = 1; -#endif - BIO_free(bio_err); + BIO_free_all(bio_err); EXIT(ret); } -static void list_cipher_fn(const EVP_CIPHER *c, - const char *from, const char *to, void *arg) -{ - if (c != NULL) { - BIO_printf(arg, "%s\n", EVP_CIPHER_name(c)); - } else { - if (from == NULL) - from = ""; - if (to == NULL) - to = ""; - BIO_printf(arg, "%s => %s\n", from, to); - } -} - -static void list_md_fn(const EVP_MD *m, - const char *from, const char *to, void *arg) -{ - if (m != NULL) { - BIO_printf(arg, "%s\n", EVP_MD_name(m)); - } else { - if (from == NULL) - from = ""; - if (to == NULL) - to = ""; - BIO_printf((BIO *)arg, "%s => %s\n", from, to); - } -} - -static void list_missing_help(void) -{ - const FUNCTION *fp; - const OPTIONS *o; - - for (fp = functions; fp->name != NULL; fp++) { - if ((o = fp->help) != NULL) { - /* If there is help, list what flags are not documented. */ - for ( ; o->name != NULL; o++) { - if (o->helpstr == NULL) - BIO_printf(bio_out, "%s %s\n", fp->name, o->name); - } - } else if (fp->func != dgst_main) { - /* If not aliased to the dgst command, */ - BIO_printf(bio_out, "%s *\n", fp->name); - } - } -} - -static void list_options_for_command(const char *command) -{ - const FUNCTION *fp; - const OPTIONS *o; - - for (fp = functions; fp->name != NULL; fp++) - if (strcmp(fp->name, command) == 0) - break; - if (fp->name == NULL) { - BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", - command); - return; - } - - if ((o = fp->help) == NULL) - return; - - for ( ; o->name != NULL; o++) { - if (o->name == OPT_HELP_STR - || o->name == OPT_MORE_STR - || o->name[0] == '\0') - continue; - BIO_printf(bio_out, "%s %c\n", o->name, o->valtype); - } -} - - -/* Unified enum for help and list commands. */ -typedef enum HELPLIST_CHOICE { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ONE, - OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_OPTIONS, - OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS, - OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED, OPT_MISSING_HELP -} HELPLIST_CHOICE; - -const OPTIONS list_options[] = { - {"help", OPT_HELP, '-', "Display this summary"}, - {"1", OPT_ONE, '-', "List in one column"}, - {"commands", OPT_COMMANDS, '-', "List of standard commands"}, - {"digest-commands", OPT_DIGEST_COMMANDS, '-', - "List of message digest commands"}, - {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-', - "List of message digest algorithms"}, - {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"}, - {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-', - "List of cipher algorithms"}, - {"public-key-algorithms", OPT_PK_ALGORITHMS, '-', - "List of public key algorithms"}, - {"public-key-methods", OPT_PK_METHOD, '-', - "List of public key methods"}, - {"disabled", OPT_DISABLED, '-', - "List of disabled features"}, - {"missing-help", OPT_MISSING_HELP, '-', - "List missing detailed help strings"}, - {"options", OPT_OPTIONS, 's', - "List options for specified command"}, - {NULL} -}; - -int list_main(int argc, char **argv) -{ - char *prog; - HELPLIST_CHOICE o; - int one = 0, done = 0; - - prog = opt_init(argc, argv, list_options); - while ((o = opt_next()) != OPT_EOF) { - switch (o) { - case OPT_EOF: /* Never hit, but suppresses warning */ - case OPT_ERR: -opthelp: - BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); - return 1; - case OPT_HELP: - opt_help(list_options); - break; - case OPT_ONE: - one = 1; - break; - case OPT_COMMANDS: - list_type(FT_general, one); - break; - case OPT_DIGEST_COMMANDS: - list_type(FT_md, one); - break; - case OPT_DIGEST_ALGORITHMS: - EVP_MD_do_all_sorted(list_md_fn, bio_out); - break; - case OPT_CIPHER_COMMANDS: - list_type(FT_cipher, one); - break; - case OPT_CIPHER_ALGORITHMS: - EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out); - break; - case OPT_PK_ALGORITHMS: - list_pkey(); - break; - case OPT_PK_METHOD: - list_pkey_meth(); - break; - case OPT_DISABLED: - list_disabled(); - break; - case OPT_MISSING_HELP: - list_missing_help(); - break; - case OPT_OPTIONS: - list_options_for_command(opt_arg()); - break; - } - done = 1; - } - if (opt_num_rest() != 0) { - BIO_printf(bio_err, "Extra arguments given.\n"); - goto opthelp; - } - - if (!done) - goto opthelp; - - return 0; -} - typedef enum HELP_CHOICE { OPT_hERR = -1, OPT_hEOF = 0, OPT_hHELP } HELP_CHOICE; const OPTIONS help_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: help [options]\n"}, - {OPT_HELP_STR, 1, '-', " help [command]\n"}, + {OPT_HELP_STR, 1, '-', "Usage: help [options] [command]\n"}, + + OPT_SECTION("General"), {"help", OPT_hHELP, '-', "Display this summary"}, + + OPT_PARAMETERS(), + {"command", 0, 0, "Name of command to display help (optional)"}, {NULL} }; @@ -463,6 +335,7 @@ int help_main(int argc, char **argv) char *prog; HELP_CHOICE o; DISPLAY_COLUMNS dc; + char *new_argv[3]; prog = opt_init(argc, argv, help_options); while ((o = opt_next()) != OPT_hEOF) { @@ -477,9 +350,8 @@ int help_main(int argc, char **argv) } } + /* One optional argument, the command to get help for. */ if (opt_num_rest() == 1) { - char *new_argv[3]; - new_argv[0] = opt_rest()[0]; new_argv[1] = "--help"; new_argv[2] = NULL; @@ -490,8 +362,8 @@ int help_main(int argc, char **argv) return 1; } - calculate_columns(&dc); - BIO_printf(bio_err, "Standard commands"); + calculate_columns(functions, &dc); + BIO_printf(bio_err, "%s:\n\nStandard commands", prog); i = 0; tp = FT_none; for (fp = functions; fp->name != NULL; fp++) { @@ -520,37 +392,13 @@ int help_main(int argc, char **argv) return 0; } -static void list_type(FUNC_TYPE ft, int one) -{ - FUNCTION *fp; - int i = 0; - DISPLAY_COLUMNS dc = {0}; - - if (!one) - calculate_columns(&dc); - - for (fp = functions; fp->name != NULL; fp++) { - if (fp->type != ft) - continue; - if (one) { - BIO_printf(bio_out, "%s\n", fp->name); - } else { - if (i % dc.columns == 0 && i > 0) - BIO_printf(bio_out, "\n"); - BIO_printf(bio_out, "%-*s", dc.width, fp->name); - i++; - } - } - if (!one) - BIO_printf(bio_out, "\n\n"); -} - static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) { FUNCTION f, *fp; if (argc <= 0 || argv[0] == NULL) return 0; + memset(&f, 0, sizeof(f)); f.name = argv[0]; fp = lh_FUNCTION_retrieve(prog, &f); if (fp == NULL) { @@ -565,6 +413,8 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) } } if (fp != NULL) { + if (fp->deprecated_alternative != NULL) + warn_deprecated(fp); return fp->func(argc, argv); } if ((strncmp(argv[0], "no-", 3)) == 0) { @@ -580,61 +430,12 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) BIO_printf(bio_out, "%s\n", argv[0] + 3); return 1; } - if (strcmp(argv[0], "quit") == 0 || strcmp(argv[0], "q") == 0 || - strcmp(argv[0], "exit") == 0 || strcmp(argv[0], "bye") == 0) - /* Special value to mean "exit the program. */ - return EXIT_THE_PROGRAM; BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", argv[0]); return 1; } -static void list_pkey(void) -{ - int i; - - for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { - const EVP_PKEY_ASN1_METHOD *ameth; - int pkey_id, pkey_base_id, pkey_flags; - const char *pinfo, *pem_str; - ameth = EVP_PKEY_asn1_get0(i); - EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags, - &pinfo, &pem_str, ameth); - if (pkey_flags & ASN1_PKEY_ALIAS) { - BIO_printf(bio_out, "Name: %s\n", OBJ_nid2ln(pkey_id)); - BIO_printf(bio_out, "\tAlias for: %s\n", - OBJ_nid2ln(pkey_base_id)); - } else { - BIO_printf(bio_out, "Name: %s\n", pinfo); - BIO_printf(bio_out, "\tType: %s Algorithm\n", - pkey_flags & ASN1_PKEY_DYNAMIC ? - "External" : "Builtin"); - BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); - if (pem_str == NULL) - pem_str = "(none)"; - BIO_printf(bio_out, "\tPEM string: %s\n", pem_str); - } - - } -} - -static void list_pkey_meth(void) -{ - size_t i; - size_t meth_count = EVP_PKEY_meth_get_count(); - - for (i = 0; i < meth_count; i++) { - const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i); - int pkey_id, pkey_flags; - - EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth); - BIO_printf(bio_out, "%s\n", OBJ_nid2ln(pkey_id)); - BIO_printf(bio_out, "\tType: %s Algorithm\n", - pkey_flags & ASN1_PKEY_DYNAMIC ? "External" : "Builtin"); - } -} - static int function_cmp(const FUNCTION * a, const FUNCTION * b) { return strncmp(a->name, b->name, 8); @@ -655,155 +456,6 @@ static int SortFnByName(const void *_f1, const void *_f2) return strcmp(f1->name, f2->name); } -static void list_disabled(void) -{ - BIO_puts(bio_out, "Disabled algorithms:\n"); -#ifdef OPENSSL_NO_ARIA - BIO_puts(bio_out, "ARIA\n"); -#endif -#ifdef OPENSSL_NO_BF - BIO_puts(bio_out, "BF\n"); -#endif -#ifdef OPENSSL_NO_BLAKE2 - BIO_puts(bio_out, "BLAKE2\n"); -#endif -#ifdef OPENSSL_NO_CAMELLIA - BIO_puts(bio_out, "CAMELLIA\n"); -#endif -#ifdef OPENSSL_NO_CAST - BIO_puts(bio_out, "CAST\n"); -#endif -#ifdef OPENSSL_NO_CMAC - BIO_puts(bio_out, "CMAC\n"); -#endif -#ifdef OPENSSL_NO_CMS - BIO_puts(bio_out, "CMS\n"); -#endif -#ifdef OPENSSL_NO_COMP - BIO_puts(bio_out, "COMP\n"); -#endif -#ifdef OPENSSL_NO_DES - BIO_puts(bio_out, "DES\n"); -#endif -#ifdef OPENSSL_NO_DGRAM - BIO_puts(bio_out, "DGRAM\n"); -#endif -#ifdef OPENSSL_NO_DH - BIO_puts(bio_out, "DH\n"); -#endif -#ifdef OPENSSL_NO_DSA - BIO_puts(bio_out, "DSA\n"); -#endif -#if defined(OPENSSL_NO_DTLS) - BIO_puts(bio_out, "DTLS\n"); -#endif -#if defined(OPENSSL_NO_DTLS1) - BIO_puts(bio_out, "DTLS1\n"); -#endif -#if defined(OPENSSL_NO_DTLS1_2) - BIO_puts(bio_out, "DTLS1_2\n"); -#endif -#ifdef OPENSSL_NO_EC - BIO_puts(bio_out, "EC\n"); -#endif -#ifdef OPENSSL_NO_EC2M - BIO_puts(bio_out, "EC2M\n"); -#endif -#ifdef OPENSSL_NO_ENGINE - BIO_puts(bio_out, "ENGINE\n"); -#endif -#ifdef OPENSSL_NO_GOST - BIO_puts(bio_out, "GOST\n"); -#endif -#ifdef OPENSSL_NO_HEARTBEATS - BIO_puts(bio_out, "HEARTBEATS\n"); -#endif -#ifdef OPENSSL_NO_IDEA - BIO_puts(bio_out, "IDEA\n"); -#endif -#ifdef OPENSSL_NO_MD2 - BIO_puts(bio_out, "MD2\n"); -#endif -#ifdef OPENSSL_NO_MD4 - BIO_puts(bio_out, "MD4\n"); -#endif -#ifdef OPENSSL_NO_MD5 - BIO_puts(bio_out, "MD5\n"); -#endif -#ifdef OPENSSL_NO_MDC2 - BIO_puts(bio_out, "MDC2\n"); -#endif -#ifdef OPENSSL_NO_OCB - BIO_puts(bio_out, "OCB\n"); -#endif -#ifdef OPENSSL_NO_OCSP - BIO_puts(bio_out, "OCSP\n"); -#endif -#ifdef OPENSSL_NO_PSK - BIO_puts(bio_out, "PSK\n"); -#endif -#ifdef OPENSSL_NO_RC2 - BIO_puts(bio_out, "RC2\n"); -#endif -#ifdef OPENSSL_NO_RC4 - BIO_puts(bio_out, "RC4\n"); -#endif -#ifdef OPENSSL_NO_RC5 - BIO_puts(bio_out, "RC5\n"); -#endif -#ifdef OPENSSL_NO_RMD160 - BIO_puts(bio_out, "RMD160\n"); -#endif -#ifdef OPENSSL_NO_RSA - BIO_puts(bio_out, "RSA\n"); -#endif -#ifdef OPENSSL_NO_SCRYPT - BIO_puts(bio_out, "SCRYPT\n"); -#endif -#ifdef OPENSSL_NO_SCTP - BIO_puts(bio_out, "SCTP\n"); -#endif -#ifdef OPENSSL_NO_SEED - BIO_puts(bio_out, "SEED\n"); -#endif -#ifdef OPENSSL_NO_SM2 - BIO_puts(bio_out, "SM2\n"); -#endif -#ifdef OPENSSL_NO_SM3 - BIO_puts(bio_out, "SM3\n"); -#endif -#ifdef OPENSSL_NO_SM4 - BIO_puts(bio_out, "SM4\n"); -#endif -#ifdef OPENSSL_NO_SOCK - BIO_puts(bio_out, "SOCK\n"); -#endif -#ifdef OPENSSL_NO_SRP - BIO_puts(bio_out, "SRP\n"); -#endif -#ifdef OPENSSL_NO_SRTP - BIO_puts(bio_out, "SRTP\n"); -#endif -#ifdef OPENSSL_NO_SSL3 - BIO_puts(bio_out, "SSL3\n"); -#endif -#ifdef OPENSSL_NO_TLS1 - BIO_puts(bio_out, "TLS1\n"); -#endif -#ifdef OPENSSL_NO_TLS1_1 - BIO_puts(bio_out, "TLS1_1\n"); -#endif -#ifdef OPENSSL_NO_TLS1_2 - BIO_puts(bio_out, "TLS1_2\n"); -#endif -#ifdef OPENSSL_NO_WHIRLPOOL - BIO_puts(bio_out, "WHIRLPOOL\n"); -#endif -#ifndef ZLIB - BIO_puts(bio_out, "ZLIB\n"); -#endif -} - static LHASH_OF(FUNCTION) *prog_init(void) { static LHASH_OF(FUNCTION) *ret = NULL; diff --git a/crypto/openssl/apps/openssl.cnf b/crypto/openssl/apps/openssl.cnf index d67a4241af78..b2d7d9a1308f 100644 --- a/crypto/openssl/apps/openssl.cnf +++ b/crypto/openssl/apps/openssl.cnf @@ -1,8 +1,10 @@ # $FreeBSD$ # # OpenSSL example configuration file. -# This is mostly being used for generation of certificate requests. +# See doc/man5/config.pod for more info. # +# This is mostly being used for generation of certificate requests, +# but may be used for auto loading of providers # Note that you can include other files from the main configuration # file using the .include directive. @@ -12,9 +14,15 @@ # defined. HOME = . + # Use this in order to automatically load providers. +openssl_conf = openssl_init + +# Comment out the next line to ignore configuration errors +config_diagnostics = 1 + # Extra OBJECT IDENTIFIER info: -#oid_file = $ENV::HOME/.oid -oid_section = new_oids +# oid_file = $ENV::HOME/.oid +oid_section = new_oids # To use this configuration file with the "-extfile" option of the # "openssl x509" utility, name here the section containing the @@ -24,7 +32,6 @@ oid_section = new_oids # X.509v3 extensions in its main [= default] section.) [ new_oids ] - # We can add new OIDs in here for use by 'ca', 'req' and 'ts'. # Add a simple OID like this: # testoid1=1.2.3.4 @@ -36,6 +43,36 @@ tsa_policy1 = 1.2.3.4.1 tsa_policy2 = 1.2.3.4.5.6 tsa_policy3 = 1.2.3.4.5.7 +# For FIPS +# Optionally include a file that is generated by the OpenSSL fipsinstall +# application. This file contains configuration data required by the OpenSSL +# fips provider. It contains a named section e.g. [fips_sect] which is +# referenced from the [provider_sect] below. +# Refer to the OpenSSL security policy for more information. +# .include fipsmodule.cnf + +[openssl_init] +providers = provider_sect + +# List of providers to load +[provider_sect] +default = default_sect +# The fips section name should match the section name inside the +# included fipsmodule.cnf. +# fips = fips_sect + +# If no providers are activated explicitly, the default one is activated implicitly. +# See man 7 OSSL_PROVIDER-default for more details. +# +# If you add a section explicitly activating any other provider(s), you most +# probably need to explicitly activate the default provider, otherwise it +# becomes unavailable in openssl. As a consequence applications depending on +# OpenSSL may not work correctly which could lead to significant system +# problems including inability to remotely access the system. +[default_sect] +# activate = 1 + + #################################################################### [ ca ] default_ca = CA_default # The default ca section @@ -172,27 +209,9 @@ unstructuredName = An optional company name basicConstraints=CA:FALSE -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer @@ -207,13 +226,6 @@ authorityKeyIdentifier=keyid,issuer # Copy subject details # issuerAltName=issuer:copy -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - # This is required for TSA certificates. # extendedKeyUsage = critical,timeStamping @@ -243,9 +255,6 @@ basicConstraints = critical,CA:true # left out by default. # keyUsage = cRLSign, keyCertSign -# Some might want this also -# nsCertType = sslCA, emailCA - # Include email address in subject alt name: another PKIX recommendation # subjectAltName=email:copy # Copy issuer details @@ -273,27 +282,9 @@ authorityKeyIdentifier=keyid:always basicConstraints=CA:FALSE -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer @@ -308,13 +299,6 @@ authorityKeyIdentifier=keyid,issuer # Copy subject details # issuerAltName=issuer:copy -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - # This really needs to be in place for it to be a proxy certificate. proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo @@ -349,3 +333,59 @@ ess_cert_id_chain = no # Must the ESS cert id chain be included? # (optional, default: no) ess_cert_id_alg = sha1 # algorithm to compute certificate # identifier (optional, default: sha1) + +[insta] # CMP using Insta Demo CA +# Message transfer +server = pki.certificate.fi:8700 +# proxy = # set this as far as needed, e.g., http://192.168.1.1:8080 +# tls_use = 0 +path = pkix/ + +# Server authentication +recipient = "/C=FI/O=Insta Demo/CN=Insta Demo CA" # or set srvcert or issuer +ignore_keyusage = 1 # potentially needed quirk +unprotected_errors = 1 # potentially needed quirk +extracertsout = insta.extracerts.pem + +# Client authentication +ref = 3078 # user identification +secret = pass:insta # can be used for both client and server side + +# Generic message options +cmd = ir # default operation, can be overridden on cmd line with, e.g., kur + +# Certificate enrollment +subject = "/CN=openssl-cmp-test" +newkey = insta.priv.pem +out_trusted = insta.ca.crt +certout = insta.cert.pem + +[pbm] # Password-based protection for Insta CA +# Server and client authentication +ref = $insta::ref # 3078 +secret = $insta::secret # pass:insta + +[signature] # Signature-based protection for Insta CA +# Server authentication +trusted = insta.ca.crt # does not include keyUsage digitalSignature + +# Client authentication +secret = # disable PBM +key = $insta::newkey # insta.priv.pem +cert = $insta::certout # insta.cert.pem + +[ir] +cmd = ir + +[cr] +cmd = cr + +[kur] +# Certificate update +cmd = kur +oldcert = $insta::certout # insta.cert.pem + +[rr] +# Certificate revocation +cmd = rr +oldcert = $insta::certout # insta.cert.pem diff --git a/crypto/openssl/apps/passwd.c b/crypto/openssl/apps/passwd.c index af08ccd4ac0f..64b2e76c147a 100644 --- a/crypto/openssl/apps/passwd.c +++ b/crypto/openssl/apps/passwd.c @@ -1,7 +1,7 @@ /* * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -16,13 +16,13 @@ #include #include #include -#ifndef OPENSSL_NO_DES +#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_DEPRECATED_3_0) # include #endif #include #include -static unsigned const char cov_2char[64] = { +static const unsigned char cov_2char[64] = { /* from crypto/des/fcrypt.c */ 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, @@ -38,7 +38,6 @@ static const char ascii_dollar[] = { 0x24, 0x00 }; typedef enum { passwd_unset = 0, - passwd_crypt, passwd_md5, passwd_apr1, passwd_sha256, @@ -51,32 +50,43 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, int reverse, size_t pw_maxlen, passwd_modes mode); typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_IN, OPT_NOVERIFY, OPT_QUIET, OPT_TABLE, OPT_REVERSE, OPT_APR1, - OPT_1, OPT_5, OPT_6, OPT_CRYPT, OPT_AIXMD5, OPT_SALT, OPT_STDIN, - OPT_R_ENUM + OPT_1, OPT_5, OPT_6, OPT_AIXMD5, OPT_SALT, OPT_STDIN, + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS passwd_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [password]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Read passwords from file"}, {"noverify", OPT_NOVERIFY, '-', "Never verify when reading password from terminal"}, + {"stdin", OPT_STDIN, '-', "Read passwords from stdin"}, + + OPT_SECTION("Output"), {"quiet", OPT_QUIET, '-', "No warnings"}, {"table", OPT_TABLE, '-', "Format output as table"}, {"reverse", OPT_REVERSE, '-', "Switch table columns"}, + + OPT_SECTION("Cryptographic"), {"salt", OPT_SALT, 's', "Use provided salt"}, - {"stdin", OPT_STDIN, '-', "Read passwords from stdin"}, {"6", OPT_6, '-', "SHA512-based password algorithm"}, {"5", OPT_5, '-', "SHA256-based password algorithm"}, {"apr1", OPT_APR1, '-', "MD5-based password algorithm, Apache variant"}, {"1", OPT_1, '-', "MD5-based password algorithm"}, {"aixmd5", OPT_AIXMD5, '-', "AIX MD5-based password algorithm"}, -#ifndef OPENSSL_NO_DES - {"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"}, -#endif + OPT_R_OPTIONS, + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"password", 0, 0, "Password text to digest (optional)"}, {NULL} }; @@ -154,13 +164,6 @@ int passwd_main(int argc, char **argv) goto opthelp; mode = passwd_aixmd5; break; - case OPT_CRYPT: -#ifndef OPENSSL_NO_DES - if (mode != passwd_unset) - goto opthelp; - mode = passwd_crypt; -#endif - break; case OPT_SALT: passed_salt = 1; salt = opt_arg(); @@ -175,11 +178,16 @@ int passwd_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* All remaining arguments are the password text */ argc = opt_num_rest(); argv = opt_rest(); - if (*argv != NULL) { if (pw_source_defined) goto opthelp; @@ -187,16 +195,14 @@ int passwd_main(int argc, char **argv) passwds = argv; } + if (!app_RAND_load()) + goto end; + if (mode == passwd_unset) { /* use default */ - mode = passwd_crypt; + mode = passwd_md5; } -#ifdef OPENSSL_NO_DES - if (mode == passwd_crypt) - goto opthelp; -#endif - if (infile != NULL && in_stdin) { BIO_printf(bio_err, "%s: Can't combine -in and -stdin\n", prog); goto end; @@ -212,9 +218,6 @@ int passwd_main(int argc, char **argv) goto end; } - if (mode == passwd_crypt) - pw_maxlen = 8; - if (passwds == NULL) { /* no passwords on the command line */ @@ -413,7 +416,7 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt) if (!EVP_DigestInit_ex(md2, EVP_md5(), NULL)) goto err; if (!EVP_DigestUpdate(md2, - (i & 1) ? (unsigned const char *)passwd : buf, + (i & 1) ? (const unsigned char *)passwd : buf, (i & 1) ? passwd_len : sizeof(buf))) goto err; if (i % 3) { @@ -425,7 +428,7 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt) goto err; } if (!EVP_DigestUpdate(md2, - (i & 1) ? buf : (unsigned const char *)passwd, + (i & 1) ? buf : (const unsigned char *)passwd, (i & 1) ? sizeof(buf) : passwd_len)) goto err; if (!EVP_DigestFinal_ex(md2, buf, NULL)) @@ -515,7 +518,7 @@ static char *shacrypt(const char *passwd, const char *magic, const char *salt) EVP_MD_CTX *md = NULL, *md2 = NULL; const EVP_MD *sha = NULL; size_t passwd_len, salt_len, magic_len; - unsigned int rounds = 5000; /* Default */ + unsigned int rounds = ROUNDS_DEFAULT; /* Default */ char rounds_custom = 0; char *p_bytes = NULL; char *s_bytes = NULL; @@ -627,7 +630,7 @@ static char *shacrypt(const char *passwd, const char *magic, const char *salt) n = passwd_len; while (n) { if (!EVP_DigestUpdate(md, - (n & 1) ? buf : (unsigned const char *)passwd, + (n & 1) ? buf : (const unsigned char *)passwd, (n & 1) ? buf_size : passwd_len)) goto err; n >>= 1; @@ -673,7 +676,7 @@ static char *shacrypt(const char *passwd, const char *magic, const char *salt) if (!EVP_DigestInit_ex(md2, sha, NULL)) goto err; if (!EVP_DigestUpdate(md2, - (n & 1) ? (unsigned const char *)p_bytes : buf, + (n & 1) ? (const unsigned char *)p_bytes : buf, (n & 1) ? passwd_len : buf_size)) goto err; if (n % 3) { @@ -685,7 +688,7 @@ static char *shacrypt(const char *passwd, const char *magic, const char *salt) goto err; } if (!EVP_DigestUpdate(md2, - (n & 1) ? buf : (unsigned const char *)p_bytes, + (n & 1) ? buf : (const unsigned char *)p_bytes, (n & 1) ? buf_size : passwd_len)) goto err; if (!EVP_DigestFinal_ex(md2, buf, NULL)) @@ -785,11 +788,6 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, size_t saltlen = 0; size_t i; -#ifndef OPENSSL_NO_DES - if (mode == passwd_crypt) - saltlen = 2; -#endif /* !OPENSSL_NO_DES */ - if (mode == passwd_md5 || mode == passwd_apr1 || mode == passwd_aixmd5) saltlen = 8; @@ -828,10 +826,6 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, assert(strlen(passwd) <= pw_maxlen); /* now compute password hash */ -#ifndef OPENSSL_NO_DES - if (mode == passwd_crypt) - hash = DES_crypt(passwd, *salt_p); -#endif if (mode == passwd_md5 || mode == passwd_apr1) hash = md5crypt(passwd, (mode == passwd_md5 ? "1" : "apr1"), *salt_p); if (mode == passwd_aixmd5) diff --git a/crypto/openssl/apps/pkcs12.c b/crypto/openssl/apps/pkcs12.c index 8c5d963b8c65..b442d358f8b7 100644 --- a/crypto/openssl/apps/pkcs12.c +++ b/crypto/openssl/apps/pkcs12.c @@ -1,13 +1,14 @@ /* - * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include + #include #include #include @@ -17,6 +18,8 @@ #include #include #include +#include +#include #define NOKEYS 0x1 #define NOCERTS 0x2 @@ -26,7 +29,13 @@ #define PASSWD_BUF_SIZE 2048 +#define WARN_EXPORT(opt) \ + BIO_printf(bio_err, "Warning: -%s option ignored with -export\n", opt); +#define WARN_NO_EXPORT(opt) \ + BIO_printf(bio_err, "Warning: -%s option ignored without -export\n", opt); + static int get_cert_chain(X509 *cert, X509_STORE *store, + STACK_OF(X509) *untrusted_certs, STACK_OF(X509) **chain); int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass, int passlen, int options, @@ -46,100 +55,131 @@ int cert_load(BIO *in, STACK_OF(X509) *sk); static int set_pbe(int *ppbe, const char *str); typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_CIPHER, OPT_NOKEYS, OPT_KEYEX, OPT_KEYSIG, OPT_NOCERTS, OPT_CLCERTS, OPT_CACERTS, OPT_NOOUT, OPT_INFO, OPT_CHAIN, OPT_TWOPASS, OPT_NOMACVER, - OPT_DESCERT, OPT_EXPORT, OPT_NOITER, OPT_MACITER, OPT_NOMACITER, - OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE, - OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME, +#ifndef OPENSSL_NO_DES + OPT_DESCERT, +#endif + OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER, + OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_NOENC, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE, + OPT_INKEY, OPT_CERTFILE, OPT_UNTRUSTED, OPT_PASSCERTS, + OPT_NAME, OPT_CSP, OPT_CANAME, OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH, - OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE, - OPT_R_ENUM + OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE, + OPT_R_ENUM, OPT_PROV_ENUM, +#ifndef OPENSSL_NO_DES + OPT_LEGACY_ALG +#endif } OPTION_CHOICE; const OPTIONS pkcs12_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"password", OPT_PASSWORD, 's', "Set PKCS#12 import/export password source"}, + {"twopass", OPT_TWOPASS, '-', "Separate MAC, encryption passwords"}, {"nokeys", OPT_NOKEYS, '-', "Don't output private keys"}, - {"keyex", OPT_KEYEX, '-', "Set MS key exchange type"}, - {"keysig", OPT_KEYSIG, '-', "Set MS key signature type"}, {"nocerts", OPT_NOCERTS, '-', "Don't output certificates"}, - {"clcerts", OPT_CLCERTS, '-', "Only output client certificates"}, - {"cacerts", OPT_CACERTS, '-', "Only output CA certificates"}, - {"noout", OPT_NOOUT, '-', "Don't output anything, just verify"}, - {"info", OPT_INFO, '-', "Print info about PKCS#12 structure"}, - {"chain", OPT_CHAIN, '-', "Add certificate chain"}, - {"twopass", OPT_TWOPASS, '-', "Separate MAC, encryption passwords"}, - {"nomacver", OPT_NOMACVER, '-', "Don't verify MAC"}, -#ifndef OPENSSL_NO_RC2 - {"descert", OPT_DESCERT, '-', - "Encrypt output with 3DES (default RC2-40)"}, - {"certpbe", OPT_CERTPBE, 's', - "Certificate PBE algorithm (default RC2-40)"}, -#else - {"descert", OPT_DESCERT, '-', "Encrypt output with 3DES (the default)"}, - {"certpbe", OPT_CERTPBE, 's', "Certificate PBE algorithm (default 3DES)"}, + {"noout", OPT_NOOUT, '-', "Don't output anything, just verify PKCS#12 input"}, +#ifndef OPENSSL_NO_DES + {"legacy", OPT_LEGACY_ALG, '-', +# ifdef OPENSSL_NO_RC2 + "Use legacy encryption algorithm 3DES_CBC for keys and certs" +# else + "Use legacy encryption: 3DES_CBC for keys, RC2_CBC for certs" +# endif + }, #endif - {"export", OPT_EXPORT, '-', "Output PKCS12 file"}, - {"noiter", OPT_NOITER, '-', "Don't use encryption iteration"}, - {"maciter", OPT_MACITER, '-', "Use MAC iteration"}, - {"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration"}, - {"nomac", OPT_NOMAC, '-', "Don't generate MAC"}, - {"LMK", OPT_LMK, '-', - "Add local machine keyset attribute to private key"}, - {"nodes", OPT_NODES, '-', "Don't encrypt private keys"}, - {"macalg", OPT_MACALG, 's', - "Digest algorithm used in MAC (default SHA1)"}, - {"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default 3DES)"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + OPT_PROV_OPTIONS, OPT_R_OPTIONS, - {"inkey", OPT_INKEY, 's', "Private key if not infile"}, - {"certfile", OPT_CERTFILE, '<', "Load certs from file"}, - {"name", OPT_NAME, 's', "Use name as friendly name"}, - {"CSP", OPT_CSP, 's', "Microsoft CSP name"}, - {"caname", OPT_CANAME, 's', - "Use name as CA friendly name (can be repeated)"}, - {"in", OPT_IN, '<', "Input filename"}, - {"out", OPT_OUT, '>', "Output filename"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - {"password", OPT_PASSWORD, 's', "Set import/export password source"}, - {"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"}, + + OPT_SECTION("PKCS#12 import (parsing PKCS#12)"), + {"info", OPT_INFO, '-', "Print info about PKCS#12 structure"}, + {"nomacver", OPT_NOMACVER, '-', "Don't verify integrity MAC"}, + {"clcerts", OPT_CLCERTS, '-', "Only output client certificates"}, + {"cacerts", OPT_CACERTS, '-', "Only output CA certificates"}, + {"", OPT_CIPHER, '-', "Any supported cipher for output encryption"}, + {"noenc", OPT_NOENC, '-', "Don't encrypt private keys"}, + {"nodes", OPT_NODES, '-', "Don't encrypt private keys; deprecated"}, + + OPT_SECTION("PKCS#12 output (export)"), + {"export", OPT_EXPORT, '-', "Create PKCS12 file"}, + {"inkey", OPT_INKEY, 's', "Private key, else read from -in input file"}, + {"certfile", OPT_CERTFILE, '<', "Extra certificates for PKCS12 output"}, + {"passcerts", OPT_PASSCERTS, 's', "Certificate file pass phrase source"}, + {"chain", OPT_CHAIN, '-', "Build and add certificate chain for EE cert,"}, + {OPT_MORE_STR, 0, 0, + "which is the 1st cert from -in matching the private key (if given)"}, + {"untrusted", OPT_UNTRUSTED, '<', "Untrusted certificates for chain building"}, {"CAfile", OPT_CAFILE, '<', "PEM-format file of CA's"}, + {"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"}, + {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, - {"", OPT_CIPHER, '-', "Any supported cipher"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store"}, + {"name", OPT_NAME, 's', "Use name as friendly name"}, + {"caname", OPT_CANAME, 's', + "Use name as CA friendly name (can be repeated)"}, + {"CSP", OPT_CSP, 's', "Microsoft CSP name"}, + {"LMK", OPT_LMK, '-', + "Add local machine keyset attribute to private key"}, + {"keyex", OPT_KEYEX, '-', "Set key type to MS key exchange"}, + {"keysig", OPT_KEYSIG, '-', "Set key type to MS key signature"}, + {"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default AES-256 CBC)"}, + {"certpbe", OPT_CERTPBE, 's', + "Certificate PBE algorithm (default PBES2 with PBKDF2 and AES-256 CBC)"}, +#ifndef OPENSSL_NO_DES + {"descert", OPT_DESCERT, '-', + "Encrypt output with 3DES (default PBES2 with PBKDF2 and AES-256 CBC)"}, #endif + {"macalg", OPT_MACALG, 's', + "Digest algorithm to use in MAC (default SHA256)"}, + {"iter", OPT_ITER, 'p', "Specify the iteration count for encryption and MAC"}, + {"noiter", OPT_NOITER, '-', "Don't use encryption iteration"}, + {"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration)"}, + {"maciter", OPT_MACITER, '-', "Unused, kept for backwards compatibility"}, + {"nomac", OPT_NOMAC, '-', "Don't generate MAC"}, {NULL} }; int pkcs12_main(int argc, char **argv) { char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL; + char *untrusted = NULL, *ciphername = NULL, *enc_flag = NULL; + char *passcertsarg = NULL, *passcerts = NULL; char *name = NULL, *csp_name = NULL; char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = ""; - int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0; - int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER; -#ifndef OPENSSL_NO_RC2 - int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; -#else - int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + int export_pkcs12 = 0, options = 0, chain = 0, twopass = 0, keytype = 0; +#ifndef OPENSSL_NO_DES + int use_legacy = 0; #endif - int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + /* use library defaults for the iter, maciter, cert, and key PBE */ + int iter = 0, maciter = 0; + int cert_pbe = NID_undef; + int key_pbe = NID_undef; int ret = 1, macver = 1, add_lmk = 0, private = 0; int noprompt = 0; char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL; char *passin = NULL, *passout = NULL, *macalg = NULL; char *cpass = NULL, *mpass = NULL, *badpass = NULL; - const char *CApath = NULL, *CAfile = NULL, *prog; - int noCApath = 0, noCAfile = 0; + const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL, *prog; + int noCApath = 0, noCAfile = 0, noCAstore = 0; ENGINE *e = NULL; BIO *in = NULL, *out = NULL; PKCS12 *p12 = NULL; STACK_OF(OPENSSL_STRING) *canames = NULL; - const EVP_CIPHER *enc = EVP_des_ede3_cbc(); + EVP_CIPHER *default_enc = (EVP_CIPHER *)EVP_aes_256_cbc(); + EVP_CIPHER *enc = (EVP_CIPHER *)default_enc; OPTION_CHOICE o; prog = opt_init(argc, argv, pkcs12_options); @@ -187,34 +227,47 @@ int pkcs12_main(int argc, char **argv) case OPT_NOMACVER: macver = 0; break; +#ifndef OPENSSL_NO_DES case OPT_DESCERT: cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; break; +#endif case OPT_EXPORT: - export_cert = 1; + export_pkcs12 = 1; + break; + case OPT_NODES: + case OPT_NOENC: + /* + * |enc_flag| stores the name of the option used so it + * can be printed if an error message is output. + */ + enc_flag = opt_flag() + 1; + enc = NULL; + ciphername = NULL; break; case OPT_CIPHER: - if (!opt_cipher(opt_unknown(), &enc)) - goto opthelp; + ciphername = opt_unknown(); + enc_flag = opt_unknown(); + break; + case OPT_ITER: + maciter = iter = opt_int_arg(); break; case OPT_NOITER: iter = 1; break; case OPT_MACITER: - maciter = PKCS12_DEFAULT_ITER; + /* no-op */ break; case OPT_NOMACITER: maciter = 1; break; case OPT_NOMAC: + cert_pbe = -1; maciter = -1; break; case OPT_MACALG: macalg = opt_arg(); break; - case OPT_NODES: - enc = NULL; - break; case OPT_CERTPBE: if (!set_pbe(&cert_pbe, opt_arg())) goto opthelp; @@ -233,6 +286,12 @@ int pkcs12_main(int argc, char **argv) case OPT_CERTFILE: certfile = opt_arg(); break; + case OPT_UNTRUSTED: + untrusted = opt_arg(); + break; + case OPT_PASSCERTS: + passcertsarg = opt_arg(); + break; case OPT_NAME: name = opt_arg(); break; @@ -266,28 +325,145 @@ int pkcs12_main(int argc, char **argv) case OPT_CAPATH: CApath = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_CAFILE: CAfile = opt_arg(); break; case OPT_NOCAPATH: noCApath = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_NOCAFILE: noCAfile = 1; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; +#ifndef OPENSSL_NO_DES + case OPT_LEGACY_ALG: + use_legacy = 1; + break; +#endif + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; + if (!app_RAND_load()) + goto end; + + if (ciphername != NULL) { + if (!opt_cipher_any(ciphername, &enc)) + goto opthelp; + } + if (export_pkcs12) { + if ((options & INFO) != 0) + WARN_EXPORT("info"); + if (macver == 0) + WARN_EXPORT("nomacver"); + if ((options & CLCERTS) != 0) + WARN_EXPORT("clcerts"); + if ((options & CACERTS) != 0) + WARN_EXPORT("cacerts"); + if (enc != default_enc) + BIO_printf(bio_err, + "Warning: output encryption option -%s ignored with -export\n", enc_flag); + } else { + if (keyname != NULL) + WARN_NO_EXPORT("inkey"); + if (certfile != NULL) + WARN_NO_EXPORT("certfile"); + if (passcertsarg != NULL) + WARN_NO_EXPORT("passcerts"); + if (chain) + WARN_NO_EXPORT("chain"); + if (untrusted != NULL) + WARN_NO_EXPORT("untrusted"); + if (CAfile != NULL) + WARN_NO_EXPORT("CAfile"); + if (CApath != NULL) + WARN_NO_EXPORT("CApath"); + if (CAstore != NULL) + WARN_NO_EXPORT("CAstore"); + if (noCAfile) + WARN_NO_EXPORT("no-CAfile"); + if (noCApath) + WARN_NO_EXPORT("no-CApath"); + if (noCAstore) + WARN_NO_EXPORT("no-CAstore"); + if (name != NULL) + WARN_NO_EXPORT("name"); + if (canames != NULL) + WARN_NO_EXPORT("caname"); + if (csp_name != NULL) + WARN_NO_EXPORT("CSP"); + if (add_lmk) + WARN_NO_EXPORT("LMK"); + if (keytype == KEY_EX) + WARN_NO_EXPORT("keyex"); + if (keytype == KEY_SIG) + WARN_NO_EXPORT("keysig"); + if (key_pbe != NID_undef) + WARN_NO_EXPORT("keypbe"); + if (cert_pbe != NID_undef && cert_pbe != -1) + WARN_NO_EXPORT("certpbe and -descert"); + if (macalg != NULL) + WARN_NO_EXPORT("macalg"); + if (iter != 0) + WARN_NO_EXPORT("iter and -noiter"); + if (maciter == 1) + WARN_NO_EXPORT("nomaciter"); + if (cert_pbe == -1 && maciter == -1) + WARN_NO_EXPORT("nomac"); + } +#ifndef OPENSSL_NO_DES + if (use_legacy) { + /* load the legacy provider if not loaded already*/ + if (!OSSL_PROVIDER_available(app_get0_libctx(), "legacy")) { + if (!app_provider_load(app_get0_libctx(), "legacy")) + goto end; + /* load the default provider explicitly */ + if (!app_provider_load(app_get0_libctx(), "default")) + goto end; + } + if (cert_pbe == NID_undef) { + /* Adapt default algorithm */ +# ifndef OPENSSL_NO_RC2 + cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; +# else + cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; +# endif + } + + if (key_pbe == NID_undef) + key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + if (enc == default_enc) + enc = (EVP_CIPHER *)EVP_des_ede3_cbc(); + if (macalg == NULL) + macalg = "sha1"; + } +#endif + private = 1; + if (!app_passwd(passcertsarg, NULL, &passcerts, NULL)) { + BIO_printf(bio_err, "Error getting certificate file password\n"); + goto end; + } + if (passarg != NULL) { - if (export_cert) + if (export_pkcs12) passoutarg = passarg; else passinarg = passarg; @@ -299,7 +475,7 @@ int pkcs12_main(int argc, char **argv) } if (cpass == NULL) { - if (export_cert) + if (export_pkcs12) cpass = passout; else cpass = passin; @@ -309,7 +485,7 @@ int pkcs12_main(int argc, char **argv) mpass = cpass; noprompt = 1; if (twopass) { - if (export_cert) + if (export_pkcs12) BIO_printf(bio_err, "Option -twopass cannot be used with -passout or -password\n"); else BIO_printf(bio_err, "Option -twopass cannot be used with -passin or -password\n"); @@ -325,7 +501,7 @@ int pkcs12_main(int argc, char **argv) if (1) { #ifndef OPENSSL_NO_UI_CONSOLE if (EVP_read_pw_string( - macpass, sizeof(macpass), "Enter MAC Password:", export_cert)) { + macpass, sizeof(macpass), "Enter MAC Password:", export_pkcs12)) { BIO_printf(bio_err, "Can't read Password\n"); goto end; } @@ -336,96 +512,126 @@ int pkcs12_main(int argc, char **argv) } } - if (export_cert) { + if (export_pkcs12) { EVP_PKEY *key = NULL; - X509 *ucert = NULL, *x = NULL; + X509 *ee_cert = NULL, *x = NULL; STACK_OF(X509) *certs = NULL; - const EVP_MD *macmd = NULL; + STACK_OF(X509) *untrusted_certs = NULL; + EVP_MD *macmd = NULL; unsigned char *catmp = NULL; int i; if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) { - BIO_printf(bio_err, "Nothing to do!\n"); + BIO_printf(bio_err, "Nothing to export due to -noout or -nocerts and -nokeys\n"); goto export_end; } - if (options & NOCERTS) + if ((options & NOCERTS) != 0) { chain = 0; + BIO_printf(bio_err, "Warning: -chain option ignored with -nocerts\n"); + } if (!(options & NOKEYS)) { key = load_key(keyname ? keyname : infile, - FORMAT_PEM, 1, passin, e, "private key"); + FORMAT_PEM, 1, passin, e, + keyname ? + "private key from -inkey file" : + "private key from -in file"); if (key == NULL) goto export_end; } - /* Load in all certs in input file */ + /* Load all certs in input file */ if (!(options & NOCERTS)) { - if (!load_certs(infile, &certs, FORMAT_PEM, NULL, - "certificates")) + if (!load_certs(infile, 1, &certs, passin, + "certificates from -in file")) goto export_end; + if (sk_X509_num(certs) < 1) { + BIO_printf(bio_err, "No certificate in -in file %s\n", infile); + goto export_end; + } if (key != NULL) { /* Look for matching private key */ for (i = 0; i < sk_X509_num(certs); i++) { x = sk_X509_value(certs, i); if (X509_check_private_key(x, key)) { - ucert = x; + ee_cert = x; /* Zero keyid and alias */ - X509_keyid_set1(ucert, NULL, 0); - X509_alias_set1(ucert, NULL, 0); + X509_keyid_set1(ee_cert, NULL, 0); + X509_alias_set1(ee_cert, NULL, 0); /* Remove from list */ (void)sk_X509_delete(certs, i); break; } } - if (ucert == NULL) { + if (ee_cert == NULL) { BIO_printf(bio_err, - "No certificate matches private key\n"); + "No cert in -in file '%s' matches private key\n", + infile); goto export_end; } } - } - /* Add any more certificates asked for */ - if (certfile != NULL) { - if (!load_certs(certfile, &certs, FORMAT_PEM, NULL, - "certificates from certfile")) + /* Load any untrusted certificates for chain building */ + if (untrusted != NULL) { + if (!load_certs(untrusted, 0, &untrusted_certs, passcerts, + "untrusted certificates")) goto export_end; } - /* If chaining get chain from user cert */ + /* If chaining get chain from end entity cert */ if (chain) { int vret; STACK_OF(X509) *chain2; X509_STORE *store; - if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) + X509 *ee_cert_tmp = ee_cert; + + /* Assume the first cert if we haven't got anything else */ + if (ee_cert_tmp == NULL && certs != NULL) + ee_cert_tmp = sk_X509_value(certs, 0); + + if (ee_cert_tmp == NULL) { + BIO_printf(bio_err, + "No end entity certificate to check with -chain\n"); + goto export_end; + } + + if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) == NULL) goto export_end; - vret = get_cert_chain(ucert, store, &chain2); + vret = get_cert_chain(ee_cert_tmp, store, untrusted_certs, &chain2); X509_STORE_free(store); if (vret == X509_V_OK) { - /* Exclude verified certificate */ - for (i = 1; i < sk_X509_num(chain2); i++) - sk_X509_push(certs, sk_X509_value(chain2, i)); - /* Free first certificate */ - X509_free(sk_X509_value(chain2, 0)); - sk_X509_free(chain2); + int add_certs; + /* Remove from chain2 the first (end entity) certificate */ + X509_free(sk_X509_shift(chain2)); + /* Add the remaining certs (except for duplicates) */ + add_certs = X509_add_certs(certs, chain2, X509_ADD_FLAG_UP_REF + | X509_ADD_FLAG_NO_DUP); + sk_X509_pop_free(chain2, X509_free); + if (!add_certs) + goto export_end; } else { if (vret != X509_V_ERR_UNSPECIFIED) - BIO_printf(bio_err, "Error %s getting chain.\n", + BIO_printf(bio_err, "Error getting chain: %s\n", X509_verify_cert_error_string(vret)); - else - ERR_print_errors(bio_err); goto export_end; } } - /* Add any CA names */ + /* Add any extra certificates asked for */ + if (certfile != NULL) { + if (!load_certs(certfile, 0, &certs, passcerts, + "extra certificates from -certfile")) + goto export_end; + } + /* Add any CA names */ for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) { catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i); X509_alias_set1(sk_X509_value(certs, i), catmp, -1); @@ -439,7 +645,7 @@ int pkcs12_main(int argc, char **argv) if (add_lmk && key != NULL) EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1); - if (!noprompt) { + if (!noprompt && !(enc == NULL && maciter == -1)) { /* To avoid bit rot */ if (1) { #ifndef OPENSSL_NO_UI_CONSOLE @@ -458,21 +664,27 @@ int pkcs12_main(int argc, char **argv) if (!twopass) OPENSSL_strlcpy(macpass, pass, sizeof(macpass)); - p12 = PKCS12_create(cpass, name, key, ucert, certs, - key_pbe, cert_pbe, iter, -1, keytype); + p12 = PKCS12_create_ex(cpass, name, key, ee_cert, certs, + key_pbe, cert_pbe, iter, -1, keytype, + app_get0_libctx(), app_get0_propq()); - if (!p12) { - ERR_print_errors(bio_err); + if (p12 == NULL) { + BIO_printf(bio_err, "Error creating PKCS12 structure for %s\n", + outfile); goto export_end; } - if (macalg) { + if (macalg != NULL) { if (!opt_md(macalg, &macmd)) goto opthelp; } if (maciter != -1) - PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd); + if (!PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd)) { + BIO_printf(bio_err, "Error creating PKCS12 MAC; no PKCS12KDF support?\n"); + BIO_printf(bio_err, "Use -nomac if MAC not required and PKCS12KDF support not available.\n"); + goto export_end; + } assert(private); @@ -487,9 +699,12 @@ int pkcs12_main(int argc, char **argv) export_end: EVP_PKEY_free(key); + EVP_MD_free(macmd); sk_X509_pop_free(certs, X509_free); - X509_free(ucert); + sk_X509_pop_free(untrusted_certs, X509_free); + X509_free(ee_cert); + ERR_print_errors(bio_err); goto end; } @@ -501,7 +716,12 @@ int pkcs12_main(int argc, char **argv) if (out == NULL) goto end; - if ((p12 = d2i_PKCS12_bio(in, NULL)) == NULL) { + p12 = PKCS12_init_ex(NID_pkcs7_data, app_get0_libctx(), app_get0_propq()); + if (p12 == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if ((p12 = d2i_PKCS12_bio(in, &p12)) == NULL) { ERR_print_errors(bio_err); goto end; } @@ -544,6 +764,16 @@ int pkcs12_main(int argc, char **argv) tsalt != NULL ? ASN1_STRING_length(tsalt) : 0L); } if (macver) { + EVP_KDF *pkcs12kdf; + + pkcs12kdf = EVP_KDF_fetch(app_get0_libctx(), "PKCS12KDF", + app_get0_propq()); + if (pkcs12kdf == NULL) { + BIO_printf(bio_err, "Error verifying PKCS12 MAC; no PKCS12KDF support.\n"); + BIO_printf(bio_err, "Use -nomacver if MAC verification is not required.\n"); + goto end; + } + EVP_KDF_free(pkcs12kdf); /* If we enter empty password try no password first */ if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { /* If mac and crypto pass the same set it to NULL too */ @@ -557,6 +787,14 @@ int pkcs12_main(int argc, char **argv) */ unsigned char *utmp; int utmplen; + unsigned long err = ERR_peek_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 + && ERR_GET_REASON(err) == PKCS12_R_MAC_ABSENT) { + BIO_printf(bio_err, "Warning: MAC is absent!\n"); + goto dump; + } + utmp = OPENSSL_asc2uni(mpass, -1, NULL, &utmplen); if (utmp == NULL) goto end; @@ -574,6 +812,7 @@ int pkcs12_main(int argc, char **argv) } } + dump: assert(private); if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout, enc)) { BIO_printf(bio_err, "Error outputting keys and certificates\n"); @@ -588,6 +827,7 @@ int pkcs12_main(int argc, char **argv) BIO_free_all(out); sk_OPENSSL_STRING_free(canames); OPENSSL_free(badpass); + OPENSSL_free(passcerts); OPENSSL_free(passin); OPENSSL_free(passout); return ret; @@ -725,6 +965,16 @@ int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bag, X509_free(x509); break; + case NID_secretBag: + if (options & INFO) + BIO_printf(bio_err, "Secret bag\n"); + print_attribs(out, attrs, "Bag Attributes"); + BIO_printf(bio_err, "Bag Type: "); + i2a_ASN1_OBJECT(bio_err, PKCS12_SAFEBAG_get0_bag_type(bag)); + BIO_printf(bio_err, "\nBag Value: "); + print_attribute(out, PKCS12_SAFEBAG_get0_bag_obj(bag)); + return 1; + case NID_safeContentsBag: if (options & INFO) BIO_printf(bio_err, "Safe Contents bag\n"); @@ -744,18 +994,19 @@ int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bag, /* Given a single certificate return a verified chain or NULL if error */ static int get_cert_chain(X509 *cert, X509_STORE *store, + STACK_OF(X509) *untrusted_certs, STACK_OF(X509) **chain) { X509_STORE_CTX *store_ctx = NULL; STACK_OF(X509) *chn = NULL; int i = 0; - store_ctx = X509_STORE_CTX_new(); + store_ctx = X509_STORE_CTX_new_ex(app_get0_libctx(), app_get0_propq()); if (store_ctx == NULL) { i = X509_V_ERR_UNSPECIFIED; goto end; } - if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL)) { + if (!X509_STORE_CTX_init(store_ctx, store, cert, untrusted_certs)) { i = X509_V_ERR_UNSPECIFIED; goto end; } @@ -863,12 +1114,13 @@ static int alg_print(const X509_ALGOR *alg) int cert_load(BIO *in, STACK_OF(X509) *sk) { - int ret; + int ret = 0; X509 *cert; - ret = 0; + while ((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) { ret = 1; - sk_X509_push(sk, cert); + if (!sk_X509_push(sk, cert)) + return 0; } if (ret) ERR_clear_error(); @@ -889,6 +1141,11 @@ void print_attribute(BIO *out, const ASN1_TYPE *av) OPENSSL_free(value); break; + case V_ASN1_UTF8STRING: + BIO_printf(out, "%.*s\n", av->value.utf8string->length, + av->value.utf8string->data); + break; + case V_ASN1_OCTET_STRING: hex_prin(out, av->value.octet_string->data, av->value.octet_string->length); diff --git a/crypto/openssl/apps/pkcs7.c b/crypto/openssl/apps/pkcs7.c index c3e9f5c69260..ba11e8151ae9 100644 --- a/crypto/openssl/apps/pkcs7.c +++ b/crypto/openssl/apps/pkcs7.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -21,15 +21,24 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOOUT, - OPT_TEXT, OPT_PRINT, OPT_PRINT_CERTS, OPT_ENGINE + OPT_TEXT, OPT_PRINT, OPT_PRINT_CERTS, OPT_ENGINE, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS pkcs7_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + + OPT_SECTION("Output"), {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, {"out", OPT_OUT, '>', "Output file"}, {"noout", OPT_NOOUT, '-', "Don't output encoded data"}, @@ -37,21 +46,21 @@ const OPTIONS pkcs7_options[] = { {"print", OPT_PRINT, '-', "Print out all fields of the PKCS7 structure"}, {"print_certs", OPT_PRINT_CERTS, '-', "Print_certs print any certs or crl in the input"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + + OPT_PROV_OPTIONS, {NULL} }; int pkcs7_main(int argc, char **argv) { ENGINE *e = NULL; - PKCS7 *p7 = NULL; + PKCS7 *p7 = NULL, *p7i; BIO *in = NULL, *out = NULL; int informat = FORMAT_PEM, outformat = FORMAT_PEM; char *infile = NULL, *outfile = NULL, *prog; int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, ret = 1; OPTION_CHOICE o; + OSSL_LIB_CTX *libctx = app_get0_libctx(); prog = opt_init(argc, argv, pkcs7_options); while ((o = opt_next()) != OPT_EOF) { @@ -94,8 +103,14 @@ int pkcs7_main(int argc, char **argv) case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; @@ -104,11 +119,18 @@ int pkcs7_main(int argc, char **argv) if (in == NULL) goto end; + p7 = PKCS7_new_ex(libctx, app_get0_propq()); + if (p7 == NULL) { + BIO_printf(bio_err, "unable to allocate PKCS7 object\n"); + ERR_print_errors(bio_err); + goto end; + } + if (informat == FORMAT_ASN1) - p7 = d2i_PKCS7_bio(in, NULL); + p7i = d2i_PKCS7_bio(in, &p7); else - p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); - if (p7 == NULL) { + p7i = PEM_read_bio_PKCS7(in, &p7, NULL, NULL); + if (p7i == NULL) { BIO_printf(bio_err, "unable to load PKCS7 object\n"); ERR_print_errors(bio_err); goto end; diff --git a/crypto/openssl/apps/pkcs8.c b/crypto/openssl/apps/pkcs8.c index 205536560ac1..6b09b909eb7a 100644 --- a/crypto/openssl/apps/pkcs8.c +++ b/crypto/openssl/apps/pkcs8.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -18,7 +18,7 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, OPT_TOPK8, OPT_NOITER, OPT_NOCRYPT, #ifndef OPENSSL_NO_SCRYPT @@ -26,35 +26,44 @@ typedef enum OPTION_choice { #endif OPT_V2, OPT_V1, OPT_V2PRF, OPT_ITER, OPT_PASSIN, OPT_PASSOUT, OPT_TRADITIONAL, - OPT_R_ENUM + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS pkcs8_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format (DER or PEM)"}, - {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, - {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, - {"topk8", OPT_TOPK8, '-', "Output PKCS8 file"}, - {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"}, - {"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"}, - OPT_R_OPTIONS, - {"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif {"v1", OPT_V1, 's', "Use PKCS#5 v1.5 and cipher"}, + {"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"}, {"v2prf", OPT_V2PRF, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"}, - {"iter", OPT_ITER, 'p', "Specify the iteration count"}, + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file"}, + {"inform", OPT_INFORM, 'F', "Input format (DER or PEM)"}, {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, + {"topk8", OPT_TOPK8, '-', "Output PKCS8 file"}, {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"traditional", OPT_TRADITIONAL, '-', "use traditional format private key"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + {"iter", OPT_ITER, 'p', "Specify the iteration count"}, + {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"}, + #ifndef OPENSSL_NO_SCRYPT + OPT_SECTION("Scrypt"), {"scrypt", OPT_SCRYPT, '-', "Use scrypt algorithm"}, {"scrypt_N", OPT_SCRYPT_N, 's', "Set scrypt N parameter"}, {"scrypt_r", OPT_SCRYPT_R, 's', "Set scrypt r parameter"}, {"scrypt_p", OPT_SCRYPT_P, 's', "Set scrypt p parameter"}, #endif + + OPT_R_OPTIONS, + OPT_PROV_OPTIONS, {NULL} }; @@ -65,8 +74,8 @@ int pkcs8_main(int argc, char **argv) EVP_PKEY *pkey = NULL; PKCS8_PRIV_KEY_INFO *p8inf = NULL; X509_SIG *p8 = NULL; - const EVP_CIPHER *cipher = NULL; - char *infile = NULL, *outfile = NULL; + EVP_CIPHER *cipher = NULL; + char *infile = NULL, *outfile = NULL, *ciphername = NULL; char *passinarg = NULL, *passoutarg = NULL, *prog; #ifndef OPENSSL_NO_UI_CONSOLE char pass[APP_PASS_LEN]; @@ -74,7 +83,7 @@ int pkcs8_main(int argc, char **argv) char *passin = NULL, *passout = NULL, *p8pass = NULL; OPTION_CHOICE o; int nocrypt = 0, ret = 1, iter = PKCS12_DEFAULT_ITER; - int informat = FORMAT_PEM, outformat = FORMAT_PEM, topk8 = 0, pbe_nid = -1; + int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, topk8 = 0, pbe_nid = -1; int private = 0, traditional = 0; #ifndef OPENSSL_NO_SCRYPT long scrypt_N = 0, scrypt_r = 0, scrypt_p = 0; @@ -119,12 +128,15 @@ int pkcs8_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_TRADITIONAL: traditional = 1; break; case OPT_V2: - if (!opt_cipher(opt_arg(), &cipher)) - goto opthelp; + ciphername = opt_arg(); break; case OPT_V1: pbe_nid = OBJ_txt2nid(opt_arg()); @@ -142,11 +154,10 @@ int pkcs8_main(int argc, char **argv) goto opthelp; } if (cipher == NULL) - cipher = EVP_aes_256_cbc(); + cipher = (EVP_CIPHER *)EVP_aes_256_cbc(); break; case OPT_ITER: - if (!opt_int(opt_arg(), &iter)) - goto opthelp; + iter = opt_int_arg(); break; case OPT_PASSIN: passinarg = opt_arg(); @@ -163,7 +174,7 @@ int pkcs8_main(int argc, char **argv) scrypt_r = 8; scrypt_p = 1; if (cipher == NULL) - cipher = EVP_aes_256_cbc(); + cipher = (EVP_CIPHER *)EVP_aes_256_cbc(); break; case OPT_SCRYPT_N: if (!opt_long(opt_arg(), &scrypt_N) || scrypt_N <= 0) @@ -180,11 +191,20 @@ int pkcs8_main(int argc, char **argv) #endif } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; private = 1; + if (!app_RAND_load()) + goto end; + + if (ciphername != NULL) { + if (!opt_cipher(ciphername, &cipher)) + goto opthelp; + } if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); @@ -192,9 +212,10 @@ int pkcs8_main(int argc, char **argv) } if ((pbe_nid == -1) && cipher == NULL) - cipher = EVP_aes_256_cbc(); + cipher = (EVP_CIPHER *)EVP_aes_256_cbc(); - in = bio_open_default(infile, 'r', informat); + in = bio_open_default(infile, 'r', + informat == FORMAT_UNDEF ? FORMAT_PEM : informat); if (in == NULL) goto end; out = bio_open_owner(outfile, outformat, private); @@ -278,7 +299,7 @@ int pkcs8_main(int argc, char **argv) } if (nocrypt) { - if (informat == FORMAT_PEM) { + if (informat == FORMAT_PEM || informat == FORMAT_UNDEF) { p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL, NULL, NULL); } else if (informat == FORMAT_ASN1) { p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL); @@ -287,7 +308,7 @@ int pkcs8_main(int argc, char **argv) goto end; } } else { - if (informat == FORMAT_PEM) { + if (informat == FORMAT_PEM || informat == FORMAT_UNDEF) { p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL); } else if (informat == FORMAT_ASN1) { p8 = d2i_PKCS8_bio(in, NULL); @@ -349,6 +370,7 @@ int pkcs8_main(int argc, char **argv) X509_SIG_free(p8); PKCS8_PRIV_KEY_INFO_free(p8inf); EVP_PKEY_free(pkey); + EVP_CIPHER_free(cipher); release_engine(e); BIO_free_all(out); BIO_free(in); diff --git a/crypto/openssl/apps/pkey.c b/crypto/openssl/apps/pkey.c index 0dd5590bdc0b..196678533c1d 100644 --- a/crypto/openssl/apps/pkey.c +++ b/crypto/openssl/apps/pkey.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,54 +11,77 @@ #include #include "apps.h" #include "progs.h" +#include "ec_common.h" #include #include #include +#include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE, OPT_IN, OPT_OUT, OPT_PUBIN, OPT_PUBOUT, OPT_TEXT_PUB, - OPT_TEXT, OPT_NOOUT, OPT_MD, OPT_TRADITIONAL, OPT_CHECK, OPT_PUB_CHECK + OPT_TEXT, OPT_NOOUT, OPT_CIPHER, OPT_TRADITIONAL, OPT_CHECK, OPT_PUB_CHECK, + OPT_EC_PARAM_ENC, OPT_EC_CONV_FORM, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS pkey_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'f', "Input format (DER or PEM)"}, - {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - {"in", OPT_IN, 's', "Input key"}, - {"out", OPT_OUT, '>', "Output file"}, - {"pubin", OPT_PUBIN, '-', - "Read public key from input (default is private key)"}, - {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, - {"text_pub", OPT_TEXT_PUB, '-', "Only output public key components"}, - {"text", OPT_TEXT, '-', "Output in plaintext as well"}, - {"noout", OPT_NOOUT, '-', "Don't output the key"}, - {"", OPT_MD, '-', "Any supported cipher"}, - {"traditional", OPT_TRADITIONAL, '-', - "Use traditional format for private keys"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + OPT_PROV_OPTIONS, + {"check", OPT_CHECK, '-', "Check key consistency"}, {"pubcheck", OPT_PUB_CHECK, '-', "Check public key consistency"}, + + OPT_SECTION("Input"), + {"in", OPT_IN, 's', "Input key"}, + {"inform", OPT_INFORM, 'f', + "Key input format (ENGINE, other values ignored)"}, + {"passin", OPT_PASSIN, 's', "Key input pass phrase source"}, + {"pubin", OPT_PUBIN, '-', + "Read only public components from key input"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file for encoded and/or text output"}, + {"outform", OPT_OUTFORM, 'F', "Output encoding format (DER or PEM)"}, + {"", OPT_CIPHER, '-', "Any supported cipher to be used for encryption"}, + {"passout", OPT_PASSOUT, 's', "Output PEM file pass phrase source"}, + {"traditional", OPT_TRADITIONAL, '-', + "Use traditional format for private key PEM output"}, + {"pubout", OPT_PUBOUT, '-', "Restrict encoded output to public components"}, + {"noout", OPT_NOOUT, '-', "Do not output the key in encoded form"}, + {"text", OPT_TEXT, '-', "Output key components in plaintext"}, + {"text_pub", OPT_TEXT_PUB, '-', + "Output only public key components in text form"}, + {"ec_conv_form", OPT_EC_CONV_FORM, 's', + "Specifies the EC point conversion form in the encoding"}, + {"ec_param_enc", OPT_EC_PARAM_ENC, 's', + "Specifies the way the EC parameters are encoded"}, + {NULL} }; int pkey_main(int argc, char **argv) { - BIO *in = NULL, *out = NULL; + BIO *out = NULL; ENGINE *e = NULL; EVP_PKEY *pkey = NULL; - const EVP_CIPHER *cipher = NULL; + EVP_PKEY_CTX *ctx = NULL; + EVP_CIPHER *cipher = NULL; char *infile = NULL, *outfile = NULL, *passin = NULL, *passout = NULL; - char *passinarg = NULL, *passoutarg = NULL, *prog; + char *passinarg = NULL, *passoutarg = NULL, *ciphername = NULL, *prog; OPTION_CHOICE o; - int informat = FORMAT_PEM, outformat = FORMAT_PEM; - int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0, ret = 1; + int informat = FORMAT_UNDEF, outformat = FORMAT_PEM; + int pubin = 0, pubout = 0, text_pub = 0, text = 0, noout = 0, ret = 1; int private = 0, traditional = 0, check = 0, pub_check = 0; +#ifndef OPENSSL_NO_EC + char *asn1_encoding = NULL; + char *point_format = NULL; +#endif prog = opt_init(argc, argv, pkey_options); while ((o = opt_next()) != OPT_EOF) { @@ -96,13 +119,13 @@ int pkey_main(int argc, char **argv) outfile = opt_arg(); break; case OPT_PUBIN: - pubin = pubout = pubtext = 1; + pubin = pubout = 1; break; case OPT_PUBOUT: pubout = 1; break; case OPT_TEXT_PUB: - pubtext = text = 1; + text_pub = 1; break; case OPT_TEXT: text = 1; @@ -119,19 +142,69 @@ int pkey_main(int argc, char **argv) case OPT_PUB_CHECK: pub_check = 1; break; - case OPT_MD: - if (!opt_cipher(opt_unknown(), &cipher)) + case OPT_CIPHER: + ciphername = opt_unknown(); + break; + case OPT_EC_CONV_FORM: +#ifdef OPENSSL_NO_EC + goto opthelp; +#else + point_format = opt_arg(); + if (!opt_string(point_format, point_format_options)) goto opthelp; + break; +#endif + case OPT_EC_PARAM_ENC: +#ifdef OPENSSL_NO_EC + goto opthelp; +#else + asn1_encoding = opt_arg(); + if (!opt_string(asn1_encoding, asn1_encoding_options)) + goto opthelp; + break; +#endif + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; - private = !noout && !pubout ? 1 : 0; - if (text && !pubtext) - private = 1; + if (text && text_pub) + BIO_printf(bio_err, + "Warning: The -text option is ignored with -text_pub\n"); + if (traditional && (noout || outformat != FORMAT_PEM)) + BIO_printf(bio_err, + "Warning: The -traditional is ignored since there is no PEM output\n"); + + /* -pubout and -text is the same as -text_pub */ + if (!text_pub && pubout && text) { + text = 0; + text_pub = 1; + } + + private = (!noout && !pubout) || (text && !text_pub); + if (ciphername != NULL) { + if (!opt_cipher(ciphername, &cipher)) + goto opthelp; + } + if (cipher == NULL) { + if (passoutarg != NULL) + BIO_printf(bio_err, + "Warning: The -passout option is ignored without a cipher option\n"); + } else { + if (noout || outformat != FORMAT_PEM) { + BIO_printf(bio_err, + "Error: Cipher options are supported only for PEM output\n"); + goto end; + } + } if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; @@ -148,9 +221,28 @@ int pkey_main(int argc, char **argv) if (pkey == NULL) goto end; +#ifndef OPENSSL_NO_EC + if (asn1_encoding != NULL || point_format != NULL) { + OSSL_PARAM params[3], *p = params; + + if (!EVP_PKEY_is_a(pkey, "EC")) + goto end; + + if (asn1_encoding != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, + asn1_encoding, 0); + if (point_format != NULL) + *p++ = OSSL_PARAM_construct_utf8_string( + OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, + point_format, 0); + *p = OSSL_PARAM_construct_end(); + if (EVP_PKEY_set_params(pkey, params) <= 0) + goto end; + } +#endif + if (check || pub_check) { int r; - EVP_PKEY_CTX *ctx; ctx = EVP_PKEY_CTX_new(pkey, e); if (ctx == NULL) { @@ -158,7 +250,7 @@ int pkey_main(int argc, char **argv) goto end; } - if (check) + if (check && !pubin) r = EVP_PKEY_check(ctx); else r = EVP_PKEY_public_check(ctx); @@ -170,17 +262,10 @@ int pkey_main(int argc, char **argv) * Note: at least for RSA keys if this function returns * -1, there will be no error reasons. */ - unsigned long err; - - BIO_printf(out, "Key is invalid\n"); - - while ((err = ERR_peek_error()) != 0) { - BIO_printf(out, "Detailed error: %s\n", - ERR_reason_error_string(err)); - ERR_get_error(); /* remove err from error stack */ - } + BIO_printf(bio_err, "Key is invalid\n"); + ERR_print_errors(bio_err); + goto end; } - EVP_PKEY_CTX_free(ctx); } if (!noout) { @@ -202,6 +287,11 @@ int pkey_main(int argc, char **argv) } } } else if (outformat == FORMAT_ASN1) { + if (text || text_pub) { + BIO_printf(bio_err, + "Error: Text output cannot be combined with DER output\n"); + goto end; + } if (pubout) { if (!i2d_PUBKEY_bio(out, pkey)) goto end; @@ -216,15 +306,13 @@ int pkey_main(int argc, char **argv) } } - if (text) { - if (pubtext) { - if (EVP_PKEY_print_public(out, pkey, 0, NULL) <= 0) - goto end; - } else { - assert(private); - if (EVP_PKEY_print_private(out, pkey, 0, NULL) <= 0) - goto end; - } + if (text_pub) { + if (EVP_PKEY_print_public(out, pkey, 0, NULL) <= 0) + goto end; + } else if (text) { + assert(private); + if (EVP_PKEY_print_private(out, pkey, 0, NULL) <= 0) + goto end; } ret = 0; @@ -232,10 +320,11 @@ int pkey_main(int argc, char **argv) end: if (ret != 0) ERR_print_errors(bio_err); + EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); + EVP_CIPHER_free(cipher); release_engine(e); BIO_free_all(out); - BIO_free(in); OPENSSL_free(passin); OPENSSL_free(passout); diff --git a/crypto/openssl/apps/pkeyparam.c b/crypto/openssl/apps/pkeyparam.c index 41c3f532b345..b02882ccc296 100644 --- a/crypto/openssl/apps/pkeyparam.c +++ b/crypto/openssl/apps/pkeyparam.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,6 +9,7 @@ #include #include +#include #include "apps.h" #include "progs.h" #include @@ -16,21 +17,29 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_IN, OPT_OUT, OPT_TEXT, OPT_NOOUT, - OPT_ENGINE, OPT_CHECK + OPT_ENGINE, OPT_CHECK, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS pkeyparam_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, - {"text", OPT_TEXT, '-', "Print parameters as text"}, - {"noout", OPT_NOOUT, '-', "Don't output encoded parameters"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif {"check", OPT_CHECK, '-', "Check key param consistency"}, + + OPT_SECTION("Input"), + {"in", OPT_IN, '<', "Input file"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"text", OPT_TEXT, '-', "Print parameters as text"}, + {"noout", OPT_NOOUT, '-', "Don't output encoded parameters"}, + + OPT_PROV_OPTIONS, {NULL} }; @@ -39,7 +48,8 @@ int pkeyparam_main(int argc, char **argv) ENGINE *e = NULL; BIO *in = NULL, *out = NULL; EVP_PKEY *pkey = NULL; - int text = 0, noout = 0, ret = 1, check = 0; + EVP_PKEY_CTX *ctx = NULL; + int text = 0, noout = 0, ret = EXIT_FAILURE, check = 0, r; OPTION_CHOICE o; char *infile = NULL, *outfile = NULL, *prog; @@ -73,8 +83,14 @@ int pkeyparam_main(int argc, char **argv) case OPT_CHECK: check = 1; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; @@ -85,7 +101,8 @@ int pkeyparam_main(int argc, char **argv) out = bio_open_default(outfile, 'w', FORMAT_PEM); if (out == NULL) goto end; - pkey = PEM_read_bio_Parameters(in, NULL); + pkey = PEM_read_bio_Parameters_ex(in, NULL, app_get0_libctx(), + app_get0_propq()); if (pkey == NULL) { BIO_printf(bio_err, "Error reading parameters\n"); ERR_print_errors(bio_err); @@ -93,10 +110,11 @@ int pkeyparam_main(int argc, char **argv) } if (check) { - int r; - EVP_PKEY_CTX *ctx; - - ctx = EVP_PKEY_CTX_new(pkey, e); + if (e == NULL) + ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), pkey, + app_get0_propq()); + else + ctx = EVP_PKEY_CTX_new(pkey, e); if (ctx == NULL) { ERR_print_errors(bio_err); goto end; @@ -111,17 +129,10 @@ int pkeyparam_main(int argc, char **argv) * Note: at least for RSA keys if this function returns * -1, there will be no error reasons. */ - unsigned long err; - - BIO_printf(out, "Parameters are invalid\n"); - - while ((err = ERR_peek_error()) != 0) { - BIO_printf(out, "Detailed error: %s\n", - ERR_reason_error_string(err)); - ERR_get_error(); /* remove err from error stack */ - } + BIO_printf(bio_err, "Parameters are invalid\n"); + ERR_print_errors(bio_err); + goto end; } - EVP_PKEY_CTX_free(ctx); } if (!noout) @@ -130,9 +141,10 @@ int pkeyparam_main(int argc, char **argv) if (text) EVP_PKEY_print_params(out, pkey, 0, NULL); - ret = 0; + ret = EXIT_SUCCESS; end: + EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); release_engine(e); BIO_free_all(out); diff --git a/crypto/openssl/apps/pkeyutl.c b/crypto/openssl/apps/pkeyutl.c index 831e14dab4b3..518a74166153 100644 --- a/crypto/openssl/apps/pkeyutl.c +++ b/crypto/openssl/apps/pkeyutl.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,6 +13,7 @@ #include #include #include +#include #define KEY_NONE 0 #define KEY_PRIVKEY 1 @@ -22,7 +23,9 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, const char *keyfile, int keyform, int key_type, char *passinarg, int pkey_op, ENGINE *e, - const int impl); + const int impl, int rawin, EVP_PKEY **ppkey, + EVP_MD_CTX *mctx, const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq); static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, ENGINE *e); @@ -31,69 +34,100 @@ static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, unsigned char *out, size_t *poutlen, const unsigned char *in, size_t inlen); +static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx, + EVP_PKEY *pkey, BIO *in, + int filesize, unsigned char *sig, int siglen, + unsigned char **out, size_t *poutlen); + typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_ENGINE, OPT_ENGINE_IMPL, OPT_IN, OPT_OUT, OPT_PUBIN, OPT_CERTIN, OPT_ASN1PARSE, OPT_HEXDUMP, OPT_SIGN, OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT, OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN, - OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_KDF, OPT_KDFLEN, - OPT_R_ENUM + OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_PKEYOPT_PASSIN, OPT_KDF, + OPT_KDFLEN, OPT_R_ENUM, OPT_PROV_ENUM, + OPT_CONFIG, + OPT_RAWIN, OPT_DIGEST } OPTION_CHOICE; const OPTIONS pkeyutl_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, + {"engine_impl", OPT_ENGINE_IMPL, '-', + "Also use engine given by -engine for crypto operations"}, +#endif + {"sign", OPT_SIGN, '-', "Sign input data with private key"}, + {"verify", OPT_VERIFY, '-', "Verify with public key"}, + {"encrypt", OPT_ENCRYPT, '-', "Encrypt input data with public key"}, + {"decrypt", OPT_DECRYPT, '-', "Decrypt input data with private key"}, + {"derive", OPT_DERIVE, '-', "Derive shared secret"}, + OPT_CONFIG_OPTION, + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file - default stdin"}, - {"out", OPT_OUT, '>', "Output file - default stdout"}, + {"rawin", OPT_RAWIN, '-', "Indicate the input data is in raw form"}, {"pubin", OPT_PUBIN, '-', "Input is a public key"}, + {"inkey", OPT_INKEY, 's', "Input private key file"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"}, + {"peerform", OPT_PEERFORM, 'E', "Peer key format (DER/PEM/P12/ENGINE)"}, {"certin", OPT_CERTIN, '-', "Input is a cert with a public key"}, + {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, + {"sigfile", OPT_SIGFILE, '<', "Signature file (verify operation only)"}, + {"keyform", OPT_KEYFORM, 'E', "Private key format (ENGINE, other values ignored)"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file - default stdout"}, {"asn1parse", OPT_ASN1PARSE, '-', "asn1parse the output data"}, {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, - {"sign", OPT_SIGN, '-', "Sign input data with private key"}, - {"verify", OPT_VERIFY, '-', "Verify with public key"}, {"verifyrecover", OPT_VERIFYRECOVER, '-', "Verify with public key, recover original data"}, - {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, - {"encrypt", OPT_ENCRYPT, '-', "Encrypt input data with public key"}, - {"decrypt", OPT_DECRYPT, '-', "Decrypt input data with private key"}, - {"derive", OPT_DERIVE, '-', "Derive shared secret"}, + + OPT_SECTION("Signing/Derivation"), + {"digest", OPT_DIGEST, 's', + "Specify the digest algorithm when signing the raw input data"}, + {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, + {"pkeyopt_passin", OPT_PKEYOPT_PASSIN, 's', + "Public key option that is read as a passphrase argument opt:passphrase"}, {"kdf", OPT_KDF, 's', "Use KDF algorithm"}, {"kdflen", OPT_KDFLEN, 'p', "KDF algorithm output length"}, - {"sigfile", OPT_SIGFILE, '<', "Signature file (verify operation only)"}, - {"inkey", OPT_INKEY, 's', "Input private key file"}, - {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"peerform", OPT_PEERFORM, 'E', "Peer key format - default PEM"}, - {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"}, - {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, + OPT_R_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, - {"engine_impl", OPT_ENGINE_IMPL, '-', - "Also use engine given by -engine for crypto operations"}, -#endif + OPT_PROV_OPTIONS, {NULL} }; int pkeyutl_main(int argc, char **argv) { + CONF *conf = NULL; BIO *in = NULL, *out = NULL; ENGINE *e = NULL; EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL; char hexdump = 0, asn1parse = 0, rev = 0, *prog; unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; OPTION_CHOICE o; - int buf_inlen = 0, siglen = -1, keyform = FORMAT_PEM, peerform = FORMAT_PEM; + int buf_inlen = 0, siglen = -1; + int keyform = FORMAT_UNDEF, peerform = FORMAT_UNDEF; int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; int engine_impl = 0; int ret = 1, rv = -1; size_t buf_outlen; const char *inkey = NULL; const char *peerkey = NULL; - const char *kdfalg = NULL; + const char *kdfalg = NULL, *digestname = NULL; int kdflen = 0; STACK_OF(OPENSSL_STRING) *pkeyopts = NULL; + STACK_OF(OPENSSL_STRING) *pkeyopts_passin = NULL; + int rawin = 0; + EVP_MD_CTX *mctx = NULL; + EVP_MD *md = NULL; + int filesize = -1; + OSSL_LIB_CTX *libctx = app_get0_libctx(); prog = opt_init(argc, argv, pkeyutl_options); while ((o = opt_next()) != OPT_EOF) { @@ -129,17 +163,26 @@ int pkeyutl_main(int argc, char **argv) passinarg = opt_arg(); break; case OPT_PEERFORM: - if (!opt_format(opt_arg(), OPT_FMT_PDE, &peerform)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &peerform)) goto opthelp; break; case OPT_KEYFORM: - if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyform)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) goto opthelp; break; case OPT_R_CASES: if (!opt_rand(o)) goto end; break; + case OPT_CONFIG: + conf = app_load_config_modules(opt_arg()); + if (conf == NULL) + goto end; + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; @@ -192,12 +235,51 @@ int pkeyutl_main(int argc, char **argv) goto end; } break; + case OPT_PKEYOPT_PASSIN: + if ((pkeyopts_passin == NULL && + (pkeyopts_passin = sk_OPENSSL_STRING_new_null()) == NULL) || + sk_OPENSSL_STRING_push(pkeyopts_passin, opt_arg()) == 0) { + BIO_puts(bio_err, "out of memory\n"); + goto end; + } + break; + case OPT_RAWIN: + rawin = 1; + break; + case OPT_DIGEST: + digestname = opt_arg(); + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; + if (!app_RAND_load()) + goto end; + + if (rawin && pkey_op != EVP_PKEY_OP_SIGN && pkey_op != EVP_PKEY_OP_VERIFY) { + BIO_printf(bio_err, + "%s: -rawin can only be used with -sign or -verify\n", + prog); + goto opthelp; + } + + if (digestname != NULL && !rawin) { + BIO_printf(bio_err, + "%s: -digest can only be used with -rawin\n", + prog); + goto opthelp; + } + + if (rawin && rev) { + BIO_printf(bio_err, "%s: -rev cannot be used with raw input\n", + prog); + goto opthelp; + } + if (kdfalg != NULL) { if (kdflen == 0) { BIO_printf(bio_err, @@ -213,16 +295,22 @@ int pkeyutl_main(int argc, char **argv) "%s: no peer key given (-peerkey parameter).\n", prog); goto opthelp; } + + if (rawin) { + if ((mctx = EVP_MD_CTX_new()) == NULL) { + BIO_printf(bio_err, "Error: out of memory\n"); + goto end; + } + } ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type, - passinarg, pkey_op, e, engine_impl); + passinarg, pkey_op, e, engine_impl, rawin, &pkey, + mctx, digestname, libctx, app_get0_propq()); if (ctx == NULL) { BIO_printf(bio_err, "%s: Error initializing context\n", prog); - ERR_print_errors(bio_err); goto end; } if (peerkey != NULL && !setup_peer(ctx, peerform, peerkey, e)) { BIO_printf(bio_err, "%s: Error setting up peer key\n", prog); - ERR_print_errors(bio_err); goto end; } if (pkeyopts != NULL) { @@ -235,11 +323,58 @@ int pkeyutl_main(int argc, char **argv) if (pkey_ctrl_string(ctx, opt) <= 0) { BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n", prog, opt); - ERR_print_errors(bio_err); goto end; } } } + if (pkeyopts_passin != NULL) { + int num = sk_OPENSSL_STRING_num(pkeyopts_passin); + int i; + + for (i = 0; i < num; i++) { + char *opt = sk_OPENSSL_STRING_value(pkeyopts_passin, i); + char *passin = strchr(opt, ':'); + char *passwd; + + if (passin == NULL) { + /* Get password interactively */ + char passwd_buf[4096]; + int r; + + BIO_snprintf(passwd_buf, sizeof(passwd_buf), "Enter %s: ", opt); + r = EVP_read_pw_string(passwd_buf, sizeof(passwd_buf) - 1, + passwd_buf, 0); + if (r < 0) { + if (r == -2) + BIO_puts(bio_err, "user abort\n"); + else + BIO_puts(bio_err, "entry failed\n"); + goto end; + } + passwd = OPENSSL_strdup(passwd_buf); + if (passwd == NULL) { + BIO_puts(bio_err, "out of memory\n"); + goto end; + } + } else { + /* Get password as a passin argument: First split option name + * and passphrase argument into two strings */ + *passin = 0; + passin++; + if (app_passwd(passin, NULL, &passwd, NULL) == 0) { + BIO_printf(bio_err, "failed to get '%s'\n", opt); + goto end; + } + } + + if (EVP_PKEY_CTX_ctrl_str(ctx, opt, passwd) <= 0) { + BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n", + prog, opt); + goto end; + } + OPENSSL_free(passwd); + } + } if (sigfile != NULL && (pkey_op != EVP_PKEY_OP_VERIFY)) { BIO_printf(bio_err, @@ -255,6 +390,12 @@ int pkeyutl_main(int argc, char **argv) if (pkey_op != EVP_PKEY_OP_DERIVE) { in = bio_open_default(infile, 'r', FORMAT_BINARY); + if (infile != NULL) { + struct stat st; + + if (stat(infile, &st) == 0 && st.st_size <= INT_MAX) + filesize = (int)st.st_size; + } if (in == NULL) goto end; } @@ -277,7 +418,8 @@ int pkeyutl_main(int argc, char **argv) } } - if (in != NULL) { + /* Raw input data is handled elsewhere */ + if (in != NULL && !rawin) { /* Read the input data */ buf_inlen = bio_to_mem(&buf_in, keysize * 10, in); if (buf_inlen < 0) { @@ -296,8 +438,9 @@ int pkeyutl_main(int argc, char **argv) } } - /* Sanity check the input */ - if (buf_inlen > EVP_MAX_MD_SIZE + /* Sanity check the input if the input is not raw */ + if (!rawin + && buf_inlen > EVP_MAX_MD_SIZE && (pkey_op == EVP_PKEY_OP_SIGN || pkey_op == EVP_PKEY_OP_VERIFY)) { BIO_printf(bio_err, @@ -306,8 +449,13 @@ int pkeyutl_main(int argc, char **argv) } if (pkey_op == EVP_PKEY_OP_VERIFY) { - rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, - buf_in, (size_t)buf_inlen); + if (rawin) { + rv = do_raw_keyop(pkey_op, mctx, pkey, in, filesize, sig, siglen, + NULL, 0); + } else { + rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, + buf_in, (size_t)buf_inlen); + } if (rv == 1) { BIO_puts(out, "Signature Verified Successfully\n"); ret = 0; @@ -316,18 +464,24 @@ int pkeyutl_main(int argc, char **argv) } goto end; } - if (kdflen != 0) { - buf_outlen = kdflen; - rv = 1; + if (rawin) { + /* rawin allocates the buffer in do_raw_keyop() */ + rv = do_raw_keyop(pkey_op, mctx, pkey, in, filesize, NULL, 0, + &buf_out, (size_t *)&buf_outlen); } else { - rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, - buf_in, (size_t)buf_inlen); - } - if (rv > 0 && buf_outlen != 0) { - buf_out = app_malloc(buf_outlen, "buffer output"); - rv = do_keyop(ctx, pkey_op, - buf_out, (size_t *)&buf_outlen, - buf_in, (size_t)buf_inlen); + if (kdflen != 0) { + buf_outlen = kdflen; + rv = 1; + } else { + rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, + buf_in, (size_t)buf_inlen); + } + if (rv > 0 && buf_outlen != 0) { + buf_out = app_malloc(buf_outlen, "buffer output"); + rv = do_keyop(ctx, pkey_op, + buf_out, (size_t *)&buf_outlen, + buf_in, (size_t)buf_inlen); + } } if (rv <= 0) { if (pkey_op != EVP_PKEY_OP_DERIVE) { @@ -335,14 +489,13 @@ int pkeyutl_main(int argc, char **argv) } else { BIO_puts(bio_err, "Key derivation failed\n"); } - ERR_print_errors(bio_err); goto end; } ret = 0; if (asn1parse) { if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) - ERR_print_errors(bio_err); + ERR_print_errors(bio_err); /* but still return success */ } else if (hexdump) { BIO_dump(out, (char *)buf_out, buf_outlen); } else { @@ -350,7 +503,11 @@ int pkeyutl_main(int argc, char **argv) } end: + if (ret != 0) + ERR_print_errors(bio_err); + EVP_MD_CTX_free(mctx); EVP_PKEY_CTX_free(ctx); + EVP_MD_free(md); release_engine(e); BIO_free(in); BIO_free_all(out); @@ -358,13 +515,17 @@ int pkeyutl_main(int argc, char **argv) OPENSSL_free(buf_out); OPENSSL_free(sig); sk_OPENSSL_STRING_free(pkeyopts); + sk_OPENSSL_STRING_free(pkeyopts_passin); + NCONF_free(conf); return ret; } static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, const char *keyfile, int keyform, int key_type, char *passinarg, int pkey_op, ENGINE *e, - const int engine_impl) + const int engine_impl, int rawin, + EVP_PKEY **ppkey, EVP_MD_CTX *mctx, const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq) { EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; @@ -372,6 +533,7 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, char *passin = NULL; int rv = -1; X509 *x; + if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) || (pkey_op == EVP_PKEY_OP_DERIVE)) && (key_type != KEY_PRIVKEY && kdfalg == NULL)) { @@ -384,11 +546,11 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, } switch (key_type) { case KEY_PRIVKEY: - pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key"); + pkey = load_key(keyfile, keyform, 0, passin, e, "private key"); break; case KEY_PUBKEY: - pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "Public Key"); + pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "public key"); break; case KEY_CERT: @@ -420,42 +582,68 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, goto end; } } - ctx = EVP_PKEY_CTX_new_id(kdfnid, impl); + if (impl != NULL) + ctx = EVP_PKEY_CTX_new_id(kdfnid, impl); + else + ctx = EVP_PKEY_CTX_new_from_name(libctx, kdfalg, propq); } else { if (pkey == NULL) goto end; - *pkeysize = EVP_PKEY_size(pkey); - ctx = EVP_PKEY_CTX_new(pkey, impl); + + *pkeysize = EVP_PKEY_get_size(pkey); + if (impl != NULL) + ctx = EVP_PKEY_CTX_new(pkey, impl); + else + ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); + if (ppkey != NULL) + *ppkey = pkey; EVP_PKEY_free(pkey); } if (ctx == NULL) goto end; - switch (pkey_op) { - case EVP_PKEY_OP_SIGN: - rv = EVP_PKEY_sign_init(ctx); - break; + if (rawin) { + EVP_MD_CTX_set_pkey_ctx(mctx, ctx); - case EVP_PKEY_OP_VERIFY: - rv = EVP_PKEY_verify_init(ctx); - break; + switch (pkey_op) { + case EVP_PKEY_OP_SIGN: + rv = EVP_DigestSignInit_ex(mctx, NULL, digestname, libctx, propq, + pkey, NULL); + break; - case EVP_PKEY_OP_VERIFYRECOVER: - rv = EVP_PKEY_verify_recover_init(ctx); - break; + case EVP_PKEY_OP_VERIFY: + rv = EVP_DigestVerifyInit_ex(mctx, NULL, digestname, libctx, propq, + pkey, NULL); + break; + } - case EVP_PKEY_OP_ENCRYPT: - rv = EVP_PKEY_encrypt_init(ctx); - break; + } else { + switch (pkey_op) { + case EVP_PKEY_OP_SIGN: + rv = EVP_PKEY_sign_init(ctx); + break; - case EVP_PKEY_OP_DECRYPT: - rv = EVP_PKEY_decrypt_init(ctx); - break; + case EVP_PKEY_OP_VERIFY: + rv = EVP_PKEY_verify_init(ctx); + break; - case EVP_PKEY_OP_DERIVE: - rv = EVP_PKEY_derive_init(ctx); - break; + case EVP_PKEY_OP_VERIFYRECOVER: + rv = EVP_PKEY_verify_recover_init(ctx); + break; + + case EVP_PKEY_OP_ENCRYPT: + rv = EVP_PKEY_encrypt_init(ctx); + break; + + case EVP_PKEY_OP_DECRYPT: + rv = EVP_PKEY_decrypt_init(ctx); + break; + + case EVP_PKEY_OP_DERIVE: + rv = EVP_PKEY_derive_init(ctx); + break; + } } if (rv <= 0) { @@ -478,18 +666,15 @@ static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, if (peerform == FORMAT_ENGINE) engine = e; - peer = load_pubkey(file, peerform, 0, NULL, engine, "Peer Key"); + peer = load_pubkey(file, peerform, 0, NULL, engine, "peer key"); if (peer == NULL) { BIO_printf(bio_err, "Error reading peer key %s\n", file); - ERR_print_errors(bio_err); return 0; } - ret = EVP_PKEY_derive_set_peer(ctx, peer); + ret = EVP_PKEY_derive_set_peer(ctx, peer) > 0; EVP_PKEY_free(peer); - if (ret <= 0) - ERR_print_errors(bio_err); return ret; } @@ -522,3 +707,95 @@ static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, } return rv; } + +#define TBUF_MAXSIZE 2048 + +static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx, + EVP_PKEY *pkey, BIO *in, + int filesize, unsigned char *sig, int siglen, + unsigned char **out, size_t *poutlen) +{ + int rv = 0; + unsigned char tbuf[TBUF_MAXSIZE]; + unsigned char *mbuf = NULL; + int buf_len = 0; + + /* Some algorithms only support oneshot digests */ + if (EVP_PKEY_get_id(pkey) == EVP_PKEY_ED25519 + || EVP_PKEY_get_id(pkey) == EVP_PKEY_ED448) { + if (filesize < 0) { + BIO_printf(bio_err, + "Error: unable to determine file size for oneshot operation\n"); + goto end; + } + mbuf = app_malloc(filesize, "oneshot sign/verify buffer"); + switch(pkey_op) { + case EVP_PKEY_OP_VERIFY: + buf_len = BIO_read(in, mbuf, filesize); + if (buf_len != filesize) { + BIO_printf(bio_err, "Error reading raw input data\n"); + goto end; + } + rv = EVP_DigestVerify(mctx, sig, (size_t)siglen, mbuf, buf_len); + break; + case EVP_PKEY_OP_SIGN: + buf_len = BIO_read(in, mbuf, filesize); + if (buf_len != filesize) { + BIO_printf(bio_err, "Error reading raw input data\n"); + goto end; + } + rv = EVP_DigestSign(mctx, NULL, poutlen, mbuf, buf_len); + if (rv == 1 && out != NULL) { + *out = app_malloc(*poutlen, "buffer output"); + rv = EVP_DigestSign(mctx, *out, poutlen, mbuf, buf_len); + } + break; + } + goto end; + } + + switch(pkey_op) { + case EVP_PKEY_OP_VERIFY: + for (;;) { + buf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); + if (buf_len == 0) + break; + if (buf_len < 0) { + BIO_printf(bio_err, "Error reading raw input data\n"); + goto end; + } + rv = EVP_DigestVerifyUpdate(mctx, tbuf, (size_t)buf_len); + if (rv != 1) { + BIO_printf(bio_err, "Error verifying raw input data\n"); + goto end; + } + } + rv = EVP_DigestVerifyFinal(mctx, sig, (size_t)siglen); + break; + case EVP_PKEY_OP_SIGN: + for (;;) { + buf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); + if (buf_len == 0) + break; + if (buf_len < 0) { + BIO_printf(bio_err, "Error reading raw input data\n"); + goto end; + } + rv = EVP_DigestSignUpdate(mctx, tbuf, (size_t)buf_len); + if (rv != 1) { + BIO_printf(bio_err, "Error signing raw input data\n"); + goto end; + } + } + rv = EVP_DigestSignFinal(mctx, NULL, poutlen); + if (rv == 1 && out != NULL) { + *out = app_malloc(*poutlen, "buffer output"); + rv = EVP_DigestSignFinal(mctx, *out, poutlen); + } + break; + } + + end: + OPENSSL_free(mbuf); + return rv; +} diff --git a/crypto/openssl/apps/prime.c b/crypto/openssl/apps/prime.c index 694479764696..e269493d5cd7 100644 --- a/crypto/openssl/apps/prime.c +++ b/crypto/openssl/apps/prime.c @@ -1,7 +1,7 @@ /* - * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,28 +14,36 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_HEX, OPT_GENERATE, OPT_BITS, OPT_SAFE, OPT_CHECKS + OPT_COMMON, + OPT_HEX, OPT_GENERATE, OPT_BITS, OPT_SAFE, OPT_CHECKS, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS prime_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"}, - {OPT_HELP_STR, 1, '-', - " number Number to check for primality\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"bits", OPT_BITS, 'p', "Size of number in bits"}, + {"checks", OPT_CHECKS, 'p', "Number of checks"}, + + OPT_SECTION("Output"), {"hex", OPT_HEX, '-', "Hex output"}, {"generate", OPT_GENERATE, '-', "Generate a prime"}, - {"bits", OPT_BITS, 'p', "Size of number in bits"}, {"safe", OPT_SAFE, '-', "When used with -generate, generate a safe prime"}, - {"checks", OPT_CHECKS, 'p', "Number of checks"}, + + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"number", 0, 0, "Number(s) to check for primality if not generating"}, {NULL} }; int prime_main(int argc, char **argv) { BIGNUM *bn = NULL; - int hex = 0, checks = 20, generate = 0, bits = 0, safe = 0, ret = 1; + int hex = 0, generate = 0, bits = 0, safe = 0, ret = 1; char *prog; OPTION_CHOICE o; @@ -64,20 +72,23 @@ int prime_main(int argc, char **argv) safe = 1; break; case OPT_CHECKS: - checks = atoi(opt_arg()); + /* ignore parameter and argument */ + opt_arg(); + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; break; } } + + /* Optional arguments are numbers to check. */ argc = opt_num_rest(); argv = opt_rest(); - if (generate) { - if (argc != 0) { - BIO_printf(bio_err, "Extra arguments given.\n"); + if (argc != 0) goto opthelp; - } } else if (argc == 0) { - BIO_printf(bio_err, "%s: No prime specified\n", prog); goto opthelp; } @@ -121,7 +132,7 @@ int prime_main(int argc, char **argv) BN_print(bio_out, bn); BIO_printf(bio_out, " (%s) %s prime\n", argv[0], - BN_is_prime_ex(bn, checks, NULL, NULL) + BN_check_prime(bn, NULL, NULL) ? "is" : "is not"); } } diff --git a/crypto/openssl/apps/progs.c b/crypto/openssl/apps/progs.c new file mode 100644 index 000000000000..2646a1a35bf3 --- /dev/null +++ b/crypto/openssl/apps/progs.c @@ -0,0 +1,397 @@ +/* + * WARNING: do not edit! + * Generated by apps/progs.pl + * + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "progs.h" + +FUNCTION functions[] = { + {FT_general, "asn1parse", asn1parse_main, asn1parse_options, NULL, NULL}, + {FT_general, "ca", ca_main, ca_options, NULL, NULL}, +#ifndef OPENSSL_NO_SOCK + {FT_general, "ciphers", ciphers_main, ciphers_options, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_CMP + {FT_general, "cmp", cmp_main, cmp_options, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_CMS + {FT_general, "cms", cms_main, cms_options, NULL, NULL}, +#endif + {FT_general, "crl", crl_main, crl_options, NULL, NULL}, + {FT_general, "crl2pkcs7", crl2pkcs7_main, crl2pkcs7_options, NULL, NULL}, + {FT_general, "dgst", dgst_main, dgst_options, NULL, NULL}, +#ifndef OPENSSL_NO_DH + {FT_general, "dhparam", dhparam_main, dhparam_options, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_DSA + {FT_general, "dsa", dsa_main, dsa_options, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_DSA + {FT_general, "dsaparam", dsaparam_main, dsaparam_options, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_EC + {FT_general, "ec", ec_main, ec_options, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_EC + {FT_general, "ecparam", ecparam_main, ecparam_options, NULL, NULL}, +#endif + {FT_general, "enc", enc_main, enc_options, NULL, NULL}, +#ifndef OPENSSL_NO_ENGINE + {FT_general, "engine", engine_main, engine_options, NULL, NULL}, +#endif + {FT_general, "errstr", errstr_main, errstr_options, NULL, NULL}, + {FT_general, "fipsinstall", fipsinstall_main, fipsinstall_options, NULL, NULL}, +#ifndef OPENSSL_NO_DSA + {FT_general, "gendsa", gendsa_main, gendsa_options, NULL, NULL}, +#endif + {FT_general, "genpkey", genpkey_main, genpkey_options, NULL, NULL}, +#ifndef OPENSSL_NO_RSA + {FT_general, "genrsa", genrsa_main, genrsa_options, NULL, NULL}, +#endif + {FT_general, "help", help_main, help_options, NULL, NULL}, + {FT_general, "info", info_main, info_options, NULL, NULL}, + {FT_general, "kdf", kdf_main, kdf_options, NULL, NULL}, + {FT_general, "list", list_main, list_options, NULL, NULL}, + {FT_general, "mac", mac_main, mac_options, NULL, NULL}, + {FT_general, "nseq", nseq_main, nseq_options, NULL, NULL}, +#ifndef OPENSSL_NO_OCSP + {FT_general, "ocsp", ocsp_main, ocsp_options, NULL, NULL}, +#endif + {FT_general, "passwd", passwd_main, passwd_options, NULL, NULL}, + {FT_general, "pkcs12", pkcs12_main, pkcs12_options, NULL, NULL}, + {FT_general, "pkcs7", pkcs7_main, pkcs7_options, NULL, NULL}, + {FT_general, "pkcs8", pkcs8_main, pkcs8_options, NULL, NULL}, + {FT_general, "pkey", pkey_main, pkey_options, NULL, NULL}, + {FT_general, "pkeyparam", pkeyparam_main, pkeyparam_options, NULL, NULL}, + {FT_general, "pkeyutl", pkeyutl_main, pkeyutl_options, NULL, NULL}, + {FT_general, "prime", prime_main, prime_options, NULL, NULL}, + {FT_general, "rand", rand_main, rand_options, NULL, NULL}, + {FT_general, "rehash", rehash_main, rehash_options, NULL, NULL}, + {FT_general, "req", req_main, req_options, NULL, NULL}, + {FT_general, "rsa", rsa_main, rsa_options, NULL, NULL}, +#if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(OPENSSL_NO_RSA) + {FT_general, "rsautl", rsautl_main, rsautl_options, "pkeyutl", "3.0"}, +#endif +#ifndef OPENSSL_NO_SOCK + {FT_general, "s_client", s_client_main, s_client_options, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_SOCK + {FT_general, "s_server", s_server_main, s_server_options, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_SOCK + {FT_general, "s_time", s_time_main, s_time_options, NULL, NULL}, +#endif + {FT_general, "sess_id", sess_id_main, sess_id_options, NULL, NULL}, + {FT_general, "smime", smime_main, smime_options, NULL, NULL}, + {FT_general, "speed", speed_main, speed_options, NULL, NULL}, + {FT_general, "spkac", spkac_main, spkac_options, NULL, NULL}, +#ifndef OPENSSL_NO_SRP + {FT_general, "srp", srp_main, srp_options, NULL, NULL}, +#endif + {FT_general, "storeutl", storeutl_main, storeutl_options, NULL, NULL}, +#ifndef OPENSSL_NO_TS + {FT_general, "ts", ts_main, ts_options, NULL, NULL}, +#endif + {FT_general, "verify", verify_main, verify_options, NULL, NULL}, + {FT_general, "version", version_main, version_options, NULL, NULL}, + {FT_general, "x509", x509_main, x509_options, NULL, NULL}, +#ifndef OPENSSL_NO_MD2 + {FT_md, "md2", dgst_main, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_MD4 + {FT_md, "md4", dgst_main, NULL, NULL}, +#endif + {FT_md, "md5", dgst_main, NULL, NULL}, + {FT_md, "sha1", dgst_main, NULL, NULL}, + {FT_md, "sha224", dgst_main, NULL, NULL}, + {FT_md, "sha256", dgst_main, NULL, NULL}, + {FT_md, "sha384", dgst_main, NULL, NULL}, + {FT_md, "sha512", dgst_main, NULL, NULL}, + {FT_md, "sha512-224", dgst_main, NULL, NULL}, + {FT_md, "sha512-256", dgst_main, NULL, NULL}, + {FT_md, "sha3-224", dgst_main, NULL, NULL}, + {FT_md, "sha3-256", dgst_main, NULL, NULL}, + {FT_md, "sha3-384", dgst_main, NULL, NULL}, + {FT_md, "sha3-512", dgst_main, NULL, NULL}, + {FT_md, "shake128", dgst_main, NULL, NULL}, + {FT_md, "shake256", dgst_main, NULL, NULL}, +#ifndef OPENSSL_NO_MDC2 + {FT_md, "mdc2", dgst_main, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_RMD160 + {FT_md, "rmd160", dgst_main, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_BLAKE2 + {FT_md, "blake2b512", dgst_main, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_BLAKE2 + {FT_md, "blake2s256", dgst_main, NULL, NULL}, +#endif +#ifndef OPENSSL_NO_SM3 + {FT_md, "sm3", dgst_main, NULL, NULL}, +#endif + {FT_cipher, "aes-128-cbc", enc_main, enc_options, NULL}, + {FT_cipher, "aes-128-ecb", enc_main, enc_options, NULL}, + {FT_cipher, "aes-192-cbc", enc_main, enc_options, NULL}, + {FT_cipher, "aes-192-ecb", enc_main, enc_options, NULL}, + {FT_cipher, "aes-256-cbc", enc_main, enc_options, NULL}, + {FT_cipher, "aes-256-ecb", enc_main, enc_options, NULL}, +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-ctr", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-cfb1", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-128-cfb8", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-ctr", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-cfb1", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-192-cfb8", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-ctr", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-cfb1", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_ARIA + {FT_cipher, "aria-256-cfb8", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-128-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-128-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-192-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-192-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-256-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAMELLIA + {FT_cipher, "camellia-256-ecb", enc_main, enc_options, NULL}, +#endif + {FT_cipher, "base64", enc_main, enc_options, NULL}, +#ifdef ZLIB + {FT_cipher, "zlib", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des3", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "desx", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_IDEA + {FT_cipher, "idea", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_SEED + {FT_cipher, "seed", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC4 + {FT_cipher, "rc4", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC4 + {FT_cipher, "rc4-40", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_BF + {FT_cipher, "bf", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC5 + {FT_cipher, "rc5", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede3", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede3-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede3-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_DES + {FT_cipher, "des-ede3-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_IDEA + {FT_cipher, "idea-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_IDEA + {FT_cipher, "idea-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_IDEA + {FT_cipher, "idea-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_IDEA + {FT_cipher, "idea-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_SEED + {FT_cipher, "seed-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_SEED + {FT_cipher, "seed-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_SEED + {FT_cipher, "seed-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_SEED + {FT_cipher, "seed-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-64-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC2 + {FT_cipher, "rc2-40-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_BF + {FT_cipher, "bf-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_BF + {FT_cipher, "bf-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_BF + {FT_cipher, "bf-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_BF + {FT_cipher, "bf-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast5-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast5-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast5-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast5-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_CAST + {FT_cipher, "cast-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC5 + {FT_cipher, "rc5-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC5 + {FT_cipher, "rc5-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC5 + {FT_cipher, "rc5-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_RC5 + {FT_cipher, "rc5-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_SM4 + {FT_cipher, "sm4-cbc", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_SM4 + {FT_cipher, "sm4-ecb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_SM4 + {FT_cipher, "sm4-cfb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_SM4 + {FT_cipher, "sm4-ofb", enc_main, enc_options, NULL}, +#endif +#ifndef OPENSSL_NO_SM4 + {FT_cipher, "sm4-ctr", enc_main, enc_options, NULL}, +#endif + {0, NULL, NULL, NULL, NULL} +}; diff --git a/crypto/openssl/apps/progs.h b/crypto/openssl/apps/progs.h index 0733d2735b3e..83c829a721bf 100644 --- a/crypto/openssl/apps/progs.h +++ b/crypto/openssl/apps/progs.h @@ -1,33 +1,21 @@ -/* $FreeBSD$ */ /* * WARNING: do not edit! * Generated by apps/progs.pl * - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ -typedef enum FUNC_TYPE { - FT_none, FT_general, FT_md, FT_cipher, FT_pkey, - FT_md_alg, FT_cipher_alg -} FUNC_TYPE; - -typedef struct function_st { - FUNC_TYPE type; - const char *name; - int (*func)(int argc, char *argv[]); - const OPTIONS *help; -} FUNCTION; - -DEFINE_LHASH_OF(FUNCTION); +#include "function.h" extern int asn1parse_main(int argc, char *argv[]); extern int ca_main(int argc, char *argv[]); extern int ciphers_main(int argc, char *argv[]); +extern int cmp_main(int argc, char *argv[]); extern int cms_main(int argc, char *argv[]); extern int crl_main(int argc, char *argv[]); extern int crl2pkcs7_main(int argc, char *argv[]); @@ -40,11 +28,15 @@ extern int ecparam_main(int argc, char *argv[]); extern int enc_main(int argc, char *argv[]); extern int engine_main(int argc, char *argv[]); extern int errstr_main(int argc, char *argv[]); +extern int fipsinstall_main(int argc, char *argv[]); extern int gendsa_main(int argc, char *argv[]); extern int genpkey_main(int argc, char *argv[]); extern int genrsa_main(int argc, char *argv[]); extern int help_main(int argc, char *argv[]); +extern int info_main(int argc, char *argv[]); +extern int kdf_main(int argc, char *argv[]); extern int list_main(int argc, char *argv[]); +extern int mac_main(int argc, char *argv[]); extern int nseq_main(int argc, char *argv[]); extern int ocsp_main(int argc, char *argv[]); extern int passwd_main(int argc, char *argv[]); @@ -77,6 +69,7 @@ extern int x509_main(int argc, char *argv[]); extern const OPTIONS asn1parse_options[]; extern const OPTIONS ca_options[]; extern const OPTIONS ciphers_options[]; +extern const OPTIONS cmp_options[]; extern const OPTIONS cms_options[]; extern const OPTIONS crl_options[]; extern const OPTIONS crl2pkcs7_options[]; @@ -89,11 +82,15 @@ extern const OPTIONS ecparam_options[]; extern const OPTIONS enc_options[]; extern const OPTIONS engine_options[]; extern const OPTIONS errstr_options[]; +extern const OPTIONS fipsinstall_options[]; extern const OPTIONS gendsa_options[]; extern const OPTIONS genpkey_options[]; extern const OPTIONS genrsa_options[]; extern const OPTIONS help_options[]; +extern const OPTIONS info_options[]; +extern const OPTIONS kdf_options[]; extern const OPTIONS list_options[]; +extern const OPTIONS mac_options[]; extern const OPTIONS nseq_options[]; extern const OPTIONS ocsp_options[]; extern const OPTIONS passwd_options[]; @@ -123,386 +120,4 @@ extern const OPTIONS verify_options[]; extern const OPTIONS version_options[]; extern const OPTIONS x509_options[]; -#ifdef INCLUDE_FUNCTION_TABLE -static FUNCTION functions[] = { - {FT_general, "asn1parse", asn1parse_main, asn1parse_options}, - {FT_general, "ca", ca_main, ca_options}, -#ifndef OPENSSL_NO_SOCK - {FT_general, "ciphers", ciphers_main, ciphers_options}, -#endif -#ifndef OPENSSL_NO_CMS - {FT_general, "cms", cms_main, cms_options}, -#endif - {FT_general, "crl", crl_main, crl_options}, - {FT_general, "crl2pkcs7", crl2pkcs7_main, crl2pkcs7_options}, - {FT_general, "dgst", dgst_main, dgst_options}, -#ifndef OPENSSL_NO_DH - {FT_general, "dhparam", dhparam_main, dhparam_options}, -#endif -#ifndef OPENSSL_NO_DSA - {FT_general, "dsa", dsa_main, dsa_options}, -#endif -#ifndef OPENSSL_NO_DSA - {FT_general, "dsaparam", dsaparam_main, dsaparam_options}, -#endif -#ifndef OPENSSL_NO_EC - {FT_general, "ec", ec_main, ec_options}, -#endif -#ifndef OPENSSL_NO_EC - {FT_general, "ecparam", ecparam_main, ecparam_options}, -#endif - {FT_general, "enc", enc_main, enc_options}, -#ifndef OPENSSL_NO_ENGINE - {FT_general, "engine", engine_main, engine_options}, -#endif - {FT_general, "errstr", errstr_main, errstr_options}, -#ifndef OPENSSL_NO_DSA - {FT_general, "gendsa", gendsa_main, gendsa_options}, -#endif - {FT_general, "genpkey", genpkey_main, genpkey_options}, -#ifndef OPENSSL_NO_RSA - {FT_general, "genrsa", genrsa_main, genrsa_options}, -#endif - {FT_general, "help", help_main, help_options}, - {FT_general, "list", list_main, list_options}, - {FT_general, "nseq", nseq_main, nseq_options}, -#ifndef OPENSSL_NO_OCSP - {FT_general, "ocsp", ocsp_main, ocsp_options}, -#endif - {FT_general, "passwd", passwd_main, passwd_options}, -#ifndef OPENSSL_NO_DES - {FT_general, "pkcs12", pkcs12_main, pkcs12_options}, -#endif - {FT_general, "pkcs7", pkcs7_main, pkcs7_options}, - {FT_general, "pkcs8", pkcs8_main, pkcs8_options}, - {FT_general, "pkey", pkey_main, pkey_options}, - {FT_general, "pkeyparam", pkeyparam_main, pkeyparam_options}, - {FT_general, "pkeyutl", pkeyutl_main, pkeyutl_options}, - {FT_general, "prime", prime_main, prime_options}, - {FT_general, "rand", rand_main, rand_options}, - {FT_general, "rehash", rehash_main, rehash_options}, - {FT_general, "req", req_main, req_options}, - {FT_general, "rsa", rsa_main, rsa_options}, -#ifndef OPENSSL_NO_RSA - {FT_general, "rsautl", rsautl_main, rsautl_options}, -#endif -#ifndef OPENSSL_NO_SOCK - {FT_general, "s_client", s_client_main, s_client_options}, -#endif -#ifndef OPENSSL_NO_SOCK - {FT_general, "s_server", s_server_main, s_server_options}, -#endif -#ifndef OPENSSL_NO_SOCK - {FT_general, "s_time", s_time_main, s_time_options}, -#endif - {FT_general, "sess_id", sess_id_main, sess_id_options}, - {FT_general, "smime", smime_main, smime_options}, - {FT_general, "speed", speed_main, speed_options}, - {FT_general, "spkac", spkac_main, spkac_options}, -#ifndef OPENSSL_NO_SRP - {FT_general, "srp", srp_main, srp_options}, -#endif - {FT_general, "storeutl", storeutl_main, storeutl_options}, -#ifndef OPENSSL_NO_TS - {FT_general, "ts", ts_main, ts_options}, -#endif - {FT_general, "verify", verify_main, verify_options}, - {FT_general, "version", version_main, version_options}, - {FT_general, "x509", x509_main, x509_options}, -#ifndef OPENSSL_NO_MD2 - {FT_md, "md2", dgst_main}, -#endif -#ifndef OPENSSL_NO_MD4 - {FT_md, "md4", dgst_main}, -#endif - {FT_md, "md5", dgst_main}, -#ifndef OPENSSL_NO_GOST - {FT_md, "gost", dgst_main}, -#endif - {FT_md, "sha1", dgst_main}, - {FT_md, "sha224", dgst_main}, - {FT_md, "sha256", dgst_main}, - {FT_md, "sha384", dgst_main}, - {FT_md, "sha512", dgst_main}, - {FT_md, "sha512-224", dgst_main}, - {FT_md, "sha512-256", dgst_main}, - {FT_md, "sha3-224", dgst_main}, - {FT_md, "sha3-256", dgst_main}, - {FT_md, "sha3-384", dgst_main}, - {FT_md, "sha3-512", dgst_main}, - {FT_md, "shake128", dgst_main}, - {FT_md, "shake256", dgst_main}, -#ifndef OPENSSL_NO_MDC2 - {FT_md, "mdc2", dgst_main}, -#endif -#ifndef OPENSSL_NO_RMD160 - {FT_md, "rmd160", dgst_main}, -#endif -#ifndef OPENSSL_NO_BLAKE2 - {FT_md, "blake2b512", dgst_main}, -#endif -#ifndef OPENSSL_NO_BLAKE2 - {FT_md, "blake2s256", dgst_main}, -#endif -#ifndef OPENSSL_NO_SM3 - {FT_md, "sm3", dgst_main}, -#endif - {FT_cipher, "aes-128-cbc", enc_main, enc_options}, - {FT_cipher, "aes-128-ecb", enc_main, enc_options}, - {FT_cipher, "aes-192-cbc", enc_main, enc_options}, - {FT_cipher, "aes-192-ecb", enc_main, enc_options}, - {FT_cipher, "aes-256-cbc", enc_main, enc_options}, - {FT_cipher, "aes-256-ecb", enc_main, enc_options}, -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-128-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-128-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-128-ctr", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-128-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-128-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-128-cfb1", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-128-cfb8", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-192-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-192-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-192-ctr", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-192-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-192-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-192-cfb1", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-192-cfb8", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-256-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-256-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-256-ctr", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-256-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-256-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-256-cfb1", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_ARIA - {FT_cipher, "aria-256-cfb8", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAMELLIA - {FT_cipher, "camellia-128-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAMELLIA - {FT_cipher, "camellia-128-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAMELLIA - {FT_cipher, "camellia-192-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAMELLIA - {FT_cipher, "camellia-192-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAMELLIA - {FT_cipher, "camellia-256-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAMELLIA - {FT_cipher, "camellia-256-ecb", enc_main, enc_options}, -#endif - {FT_cipher, "base64", enc_main, enc_options}, -#ifdef ZLIB - {FT_cipher, "zlib", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des3", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "desx", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_IDEA - {FT_cipher, "idea", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_SEED - {FT_cipher, "seed", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC4 - {FT_cipher, "rc4", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC4 - {FT_cipher, "rc4-40", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC2 - {FT_cipher, "rc2", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_BF - {FT_cipher, "bf", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAST - {FT_cipher, "cast", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC5 - {FT_cipher, "rc5", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-ede", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-ede3", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-ede-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-ede3-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-ede-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-ede3-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-ede-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_DES - {FT_cipher, "des-ede3-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_IDEA - {FT_cipher, "idea-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_IDEA - {FT_cipher, "idea-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_IDEA - {FT_cipher, "idea-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_IDEA - {FT_cipher, "idea-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_SEED - {FT_cipher, "seed-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_SEED - {FT_cipher, "seed-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_SEED - {FT_cipher, "seed-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_SEED - {FT_cipher, "seed-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC2 - {FT_cipher, "rc2-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC2 - {FT_cipher, "rc2-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC2 - {FT_cipher, "rc2-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC2 - {FT_cipher, "rc2-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC2 - {FT_cipher, "rc2-64-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC2 - {FT_cipher, "rc2-40-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_BF - {FT_cipher, "bf-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_BF - {FT_cipher, "bf-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_BF - {FT_cipher, "bf-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_BF - {FT_cipher, "bf-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAST - {FT_cipher, "cast5-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAST - {FT_cipher, "cast5-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAST - {FT_cipher, "cast5-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAST - {FT_cipher, "cast5-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_CAST - {FT_cipher, "cast-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC5 - {FT_cipher, "rc5-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC5 - {FT_cipher, "rc5-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC5 - {FT_cipher, "rc5-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_RC5 - {FT_cipher, "rc5-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_SM4 - {FT_cipher, "sm4-cbc", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_SM4 - {FT_cipher, "sm4-ecb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_SM4 - {FT_cipher, "sm4-cfb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_SM4 - {FT_cipher, "sm4-ofb", enc_main, enc_options}, -#endif -#ifndef OPENSSL_NO_SM4 - {FT_cipher, "sm4-ctr", enc_main, enc_options}, -#endif - {0, NULL, NULL} -}; -#endif +extern FUNCTION functions[]; diff --git a/crypto/openssl/apps/progs.pl b/crypto/openssl/apps/progs.pl index 57671405dda0..29f9be13ca08 100755 --- a/crypto/openssl/apps/progs.pl +++ b/crypto/openssl/apps/progs.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -14,17 +14,22 @@ use warnings; use lib '.'; use configdata qw/@disablables %unified_info/; +my $opt = shift @ARGV; +die "Unrecognised option, must be -C or -H\n" + unless ($opt eq '-H' || $opt eq '-C'); + my %commands = (); my $cmdre = qr/^\s*int\s+([a-z_][a-z0-9_]*)_main\(\s*int\s+argc\s*,/; my $apps_openssl = shift @ARGV; -my $YEAR = [localtime()]->[5] + 1900; +my $YEAR = [gmtime($ENV{SOURCE_DATE_EPOCH} || time())]->[5] + 1900; # because the program apps/openssl has object files as sources, and # they then have the corresponding C files as source, we need to chain # the lookups in %unified_info my @openssl_source = map { @{$unified_info{sources}->{$_}} } - grep { /\.o$/ } + grep { /\.o$/ + && !$unified_info{attributes}->{sources}->{$apps_openssl}->{$_}->{nocheck} } @{$unified_info{sources}->{$apps_openssl}}; foreach my $filename (@openssl_source) { @@ -38,144 +43,178 @@ foreach my $filename (@openssl_source) { @ARGV = sort keys %commands; -print <<"EOF"; +if ($opt eq '-H') { + print <<"EOF"; /* * WARNING: do not edit! * Generated by apps/progs.pl * * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ -typedef enum FUNC_TYPE { - FT_none, FT_general, FT_md, FT_cipher, FT_pkey, - FT_md_alg, FT_cipher_alg -} FUNC_TYPE; - -typedef struct function_st { - FUNC_TYPE type; - const char *name; - int (*func)(int argc, char *argv[]); - const OPTIONS *help; -} FUNCTION; - -DEFINE_LHASH_OF(FUNCTION); +#include "function.h" EOF -foreach (@ARGV) { - printf "extern int %s_main(int argc, char *argv[]);\n", $_; -} -print "\n"; + foreach (@ARGV) { + printf "extern int %s_main(int argc, char *argv[]);\n", $_; + } + print "\n"; -foreach (@ARGV) { - printf "extern const OPTIONS %s_options[];\n", $_; -} -print "\n"; - -my %cmd_disabler = ( - ciphers => "sock", - genrsa => "rsa", - rsautl => "rsa", - gendsa => "dsa", - dsaparam => "dsa", - gendh => "dh", - dhparam => "dh", - ecparam => "ec", - pkcs12 => "des", -); - -print "#ifdef INCLUDE_FUNCTION_TABLE\n"; -print "static FUNCTION functions[] = {\n"; -foreach my $cmd ( @ARGV ) { - my $str = " {FT_general, \"$cmd\", ${cmd}_main, ${cmd}_options},\n"; - if ($cmd =~ /^s_/) { - print "#ifndef OPENSSL_NO_SOCK\n${str}#endif\n"; - } elsif (grep { $cmd eq $_ } @disablables) { - print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n"; - } elsif (my $disabler = $cmd_disabler{$cmd}) { - print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; - } else { - print $str; + foreach (@ARGV) { + printf "extern const OPTIONS %s_options[];\n", $_; } + print "\n"; + print "extern FUNCTION functions[];\n"; } -my %md_disabler = ( - blake2b512 => "blake2", - blake2s256 => "blake2", -); -foreach my $cmd ( - "md2", "md4", "md5", - "gost", - "sha1", "sha224", "sha256", "sha384", - "sha512", "sha512-224", "sha512-256", - "sha3-224", "sha3-256", "sha3-384", "sha3-512", - "shake128", "shake256", - "mdc2", "rmd160", "blake2b512", "blake2s256", - "sm3" -) { - my $str = " {FT_md, \"$cmd\", dgst_main},\n"; - if (grep { $cmd eq $_ } @disablables) { - print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n"; - } elsif (my $disabler = $md_disabler{$cmd}) { - print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; - } else { - print $str; +if ($opt eq '-C') { + print <<"EOF"; +/* + * WARNING: do not edit! + * Generated by apps/progs.pl + * + * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "progs.h" + +EOF + + my %cmd_disabler = ( + ciphers => "sock", + genrsa => "rsa", + gendsa => "dsa", + dsaparam => "dsa", + gendh => "dh", + dhparam => "dh", + ecparam => "ec", + ); + my %cmd_deprecated = ( +# The format of this table is: +# [0] = alternative command to use instead +# [1] = deprecented in this version +# [2] = preprocessor conditional for exclusing irrespective of deprecation +# rsa => [ "pkey", "3_0", "rsa" ], +# genrsa => [ "genpkey", "3_0", "rsa" ], + rsautl => [ "pkeyutl", "3_0", "rsa" ], +# dhparam => [ "pkeyparam", "3_0", "dh" ], +# dsaparam => [ "pkeyparam", "3_0", "dsa" ], +# dsa => [ "pkey", "3_0", "dsa" ], +# gendsa => [ "genpkey", "3_0", "dsa" ], +# ec => [ "pkey", "3_0", "ec" ], +# ecparam => [ "pkeyparam", "3_0", "ec" ], + ); + + print "FUNCTION functions[] = {\n"; + foreach my $cmd ( @ARGV ) { + my $str = + " {FT_general, \"$cmd\", ${cmd}_main, ${cmd}_options, NULL, NULL},\n"; + if ($cmd =~ /^s_/) { + print "#ifndef OPENSSL_NO_SOCK\n${str}#endif\n"; + } elsif (my $deprecated = $cmd_deprecated{$cmd}) { + my @dep = @{$deprecated}; + my $daltprg = $dep[0]; + my $dver = $dep[1]; + my $dsys = $dep[2]; + print "#if !defined(OPENSSL_NO_DEPRECATED_" . $dver . ")"; + if ($dsys) { + print " && !defined(OPENSSL_NO_" . uc($dsys) . ")"; + } + $dver =~ s/_/./g; + my $dalt = "\"" . $daltprg . "\", \"" . $dver . "\""; + $str =~ s/NULL, NULL/$dalt/; + print "\n${str}#endif\n"; + } elsif (grep { $cmd eq $_ } @disablables) { + print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n"; + } elsif (my $disabler = $cmd_disabler{$cmd}) { + print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; + } else { + print $str; + } } -} -my %cipher_disabler = ( - des3 => "des", - desx => "des", - cast5 => "cast", -); -foreach my $cmd ( - "aes-128-cbc", "aes-128-ecb", - "aes-192-cbc", "aes-192-ecb", - "aes-256-cbc", "aes-256-ecb", - "aria-128-cbc", "aria-128-cfb", - "aria-128-ctr", "aria-128-ecb", "aria-128-ofb", - "aria-128-cfb1", "aria-128-cfb8", - "aria-192-cbc", "aria-192-cfb", - "aria-192-ctr", "aria-192-ecb", "aria-192-ofb", - "aria-192-cfb1", "aria-192-cfb8", - "aria-256-cbc", "aria-256-cfb", - "aria-256-ctr", "aria-256-ecb", "aria-256-ofb", - "aria-256-cfb1", "aria-256-cfb8", - "camellia-128-cbc", "camellia-128-ecb", - "camellia-192-cbc", "camellia-192-ecb", - "camellia-256-cbc", "camellia-256-ecb", - "base64", "zlib", - "des", "des3", "desx", "idea", "seed", "rc4", "rc4-40", - "rc2", "bf", "cast", "rc5", - "des-ecb", "des-ede", "des-ede3", - "des-cbc", "des-ede-cbc","des-ede3-cbc", - "des-cfb", "des-ede-cfb","des-ede3-cfb", - "des-ofb", "des-ede-ofb","des-ede3-ofb", - "idea-cbc","idea-ecb", "idea-cfb", "idea-ofb", - "seed-cbc","seed-ecb", "seed-cfb", "seed-ofb", - "rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc", - "bf-cbc", "bf-ecb", "bf-cfb", "bf-ofb", - "cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb", - "cast-cbc", "rc5-cbc", "rc5-ecb", "rc5-cfb", "rc5-ofb", - "sm4-cbc", "sm4-ecb", "sm4-cfb", "sm4-ofb", "sm4-ctr" -) { - my $str = " {FT_cipher, \"$cmd\", enc_main, enc_options},\n"; - (my $algo = $cmd) =~ s/-.*//g; - if ($cmd eq "zlib") { - print "#ifdef ZLIB\n${str}#endif\n"; - } elsif (grep { $algo eq $_ } @disablables) { - print "#ifndef OPENSSL_NO_" . uc($algo) . "\n${str}#endif\n"; - } elsif (my $disabler = $cipher_disabler{$algo}) { - print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; - } else { - print $str; + my %md_disabler = ( + blake2b512 => "blake2", + blake2s256 => "blake2", + ); + foreach my $cmd ( + "md2", "md4", "md5", + "sha1", "sha224", "sha256", "sha384", + "sha512", "sha512-224", "sha512-256", + "sha3-224", "sha3-256", "sha3-384", "sha3-512", + "shake128", "shake256", + "mdc2", "rmd160", "blake2b512", "blake2s256", + "sm3" + ) { + my $str = " {FT_md, \"$cmd\", dgst_main, NULL, NULL},\n"; + if (grep { $cmd eq $_ } @disablables) { + print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n"; + } elsif (my $disabler = $md_disabler{$cmd}) { + print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; + } else { + print $str; + } } -} -print " {0, NULL, NULL}\n};\n"; -print "#endif\n"; + my %cipher_disabler = ( + des3 => "des", + desx => "des", + cast5 => "cast", + ); + foreach my $cmd ( + "aes-128-cbc", "aes-128-ecb", + "aes-192-cbc", "aes-192-ecb", + "aes-256-cbc", "aes-256-ecb", + "aria-128-cbc", "aria-128-cfb", + "aria-128-ctr", "aria-128-ecb", "aria-128-ofb", + "aria-128-cfb1", "aria-128-cfb8", + "aria-192-cbc", "aria-192-cfb", + "aria-192-ctr", "aria-192-ecb", "aria-192-ofb", + "aria-192-cfb1", "aria-192-cfb8", + "aria-256-cbc", "aria-256-cfb", + "aria-256-ctr", "aria-256-ecb", "aria-256-ofb", + "aria-256-cfb1", "aria-256-cfb8", + "camellia-128-cbc", "camellia-128-ecb", + "camellia-192-cbc", "camellia-192-ecb", + "camellia-256-cbc", "camellia-256-ecb", + "base64", "zlib", + "des", "des3", "desx", "idea", "seed", "rc4", "rc4-40", + "rc2", "bf", "cast", "rc5", + "des-ecb", "des-ede", "des-ede3", + "des-cbc", "des-ede-cbc","des-ede3-cbc", + "des-cfb", "des-ede-cfb","des-ede3-cfb", + "des-ofb", "des-ede-ofb","des-ede3-ofb", + "idea-cbc","idea-ecb", "idea-cfb", "idea-ofb", + "seed-cbc","seed-ecb", "seed-cfb", "seed-ofb", + "rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc", + "bf-cbc", "bf-ecb", "bf-cfb", "bf-ofb", + "cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb", + "cast-cbc", "rc5-cbc", "rc5-ecb", "rc5-cfb", "rc5-ofb", + "sm4-cbc", "sm4-ecb", "sm4-cfb", "sm4-ofb", "sm4-ctr" + ) { + my $str = " {FT_cipher, \"$cmd\", enc_main, enc_options, NULL},\n"; + (my $algo = $cmd) =~ s/-.*//g; + if ($cmd eq "zlib") { + print "#ifdef ZLIB\n${str}#endif\n"; + } elsif (grep { $algo eq $_ } @disablables) { + print "#ifndef OPENSSL_NO_" . uc($algo) . "\n${str}#endif\n"; + } elsif (my $disabler = $cipher_disabler{$algo}) { + print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; + } else { + print $str; + } + } + + print " {0, NULL, NULL, NULL, NULL}\n};\n"; +} diff --git a/crypto/openssl/apps/rand.c b/crypto/openssl/apps/rand.c index 4c6181507bd5..cbf495d5bc53 100644 --- a/crypto/openssl/apps/rand.c +++ b/crypto/openssl/apps/rand.c @@ -1,7 +1,7 @@ /* - * Copyright 1998-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,22 +19,30 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_OUT, OPT_ENGINE, OPT_BASE64, OPT_HEX, - OPT_R_ENUM + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS rand_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [flags] num\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] num\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"out", OPT_OUT, '>', "Output file"}, - OPT_R_OPTIONS, - {"base64", OPT_BASE64, '-', "Base64 encode output"}, - {"hex", OPT_HEX, '-', "Hex encode output"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"base64", OPT_BASE64, '-', "Base64 encode output"}, + {"hex", OPT_HEX, '-', "Hex encode output"}, + + OPT_R_OPTIONS, + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"num", 0, 0, "Number of bytes to generate"}, {NULL} }; @@ -74,18 +82,26 @@ int rand_main(int argc, char **argv) case OPT_HEX: format = FORMAT_TEXT; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* Optional argument is number of bytes to generate. */ argc = opt_num_rest(); argv = opt_rest(); if (argc == 1) { if (!opt_int(argv[0], &num) || num <= 0) - goto end; - } else if (argc > 0) { - BIO_printf(bio_err, "Extra arguments given.\n"); + goto opthelp; + } else if (argc != 0) { goto opthelp; } + if (!app_RAND_load()) + goto end; + out = bio_open_default(outfile, 'w', format); if (out == NULL) goto end; diff --git a/crypto/openssl/apps/rehash.c b/crypto/openssl/apps/rehash.c index fc1dffe97497..e4a4e14fd497 100644 --- a/crypto/openssl/apps/rehash.c +++ b/crypto/openssl/apps/rehash.c @@ -1,8 +1,8 @@ /* - * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2013-2014 Timo Teräs * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -42,7 +42,6 @@ # include # include - # ifndef PATH_MAX # define PATH_MAX 4096 # endif @@ -169,6 +168,12 @@ static int add_entry(enum Type type, unsigned int hash, const char *filename, *ep = nilhentry; ep->old_id = ~0; ep->filename = OPENSSL_strdup(filename); + if (ep->filename == NULL) { + OPENSSL_free(ep); + ep = NULL; + BIO_printf(bio_err, "out of memory\n"); + return 1; + } if (bp->last_entry) bp->last_entry->next = ep; if (bp->first_entry == NULL) @@ -209,7 +214,7 @@ static int handle_symlink(const char *filename, const char *fullpath) return -1; for (type = OSSL_NELEM(suffixes) - 1; type > 0; type--) { const char *suffix = suffixes[type]; - if (strncasecmp(suffix, &filename[i], strlen(suffix)) == 0) + if (OPENSSL_strncasecmp(suffix, &filename[i], strlen(suffix)) == 0) break; } i += strlen(suffixes[type]); @@ -233,7 +238,7 @@ static int do_file(const char *filename, const char *fullpath, enum Hash h) { STACK_OF (X509_INFO) *inf = NULL; X509_INFO *x; - X509_NAME *name = NULL; + const X509_NAME *name = NULL; BIO *b; const char *ext; unsigned char digest[EVP_MAX_MD_SIZE]; @@ -244,7 +249,7 @@ static int do_file(const char *filename, const char *fullpath, enum Hash h) if ((ext = strrchr(filename, '.')) == NULL) goto end; for (i = 0; i < OSSL_NELEM(extensions); i++) { - if (strcasecmp(extensions[i], ext + 1) == 0) + if (OPENSSL_strcasecmp(extensions[i], ext + 1) == 0) break; } if (i >= OSSL_NELEM(extensions)) @@ -292,10 +297,23 @@ static int do_file(const char *filename, const char *fullpath, enum Hash h) goto end; } if (name != NULL) { - if ((h == HASH_NEW) || (h == HASH_BOTH)) - errs += add_entry(type, X509_NAME_hash(name), filename, digest, 1, ~0); + if (h == HASH_NEW || h == HASH_BOTH) { + int ok; + unsigned long hash_value = + X509_NAME_hash_ex(name, + app_get0_libctx(), app_get0_propq(), &ok); + + if (ok) { + errs += add_entry(type, hash_value, filename, digest, 1, ~0); + } else { + BIO_printf(bio_err, "%s: error calculating SHA1 hash value\n", + opt_getprog()); + errs++; + } + } if ((h == HASH_OLD) || (h == HASH_BOTH)) - errs += add_entry(type, X509_NAME_hash_old(name), filename, digest, 1, ~0); + errs += add_entry(type, X509_NAME_hash_old(name), + filename, digest, 1, ~0); } end: @@ -454,19 +472,28 @@ static int do_dir(const char *dirname, enum Hash h) } typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_COMPAT, OPT_OLD, OPT_N, OPT_VERBOSE + OPT_COMMON, + OPT_COMPAT, OPT_OLD, OPT_N, OPT_VERBOSE, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS rehash_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert-directory...]\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [directory...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"h", OPT_HELP, '-', "Display this summary"}, {"compat", OPT_COMPAT, '-', "Create both new- and old-style hash links"}, {"old", OPT_OLD, '-', "Use old-style hash to generate links"}, {"n", OPT_N, '-', "Do not remove existing links"}, + + OPT_SECTION("Output"), {"v", OPT_VERBOSE, '-', "Verbose output"}, + + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"directory", 0, 0, "One or more directories to process (optional)"}, {NULL} }; @@ -501,13 +528,19 @@ int rehash_main(int argc, char **argv) case OPT_VERBOSE: verbose = 1; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* Optional arguments are directories to scan. */ argc = opt_num_rest(); argv = opt_rest(); evpmd = EVP_sha1(); - evpmdsize = EVP_MD_size(evpmd); + evpmdsize = EVP_MD_get_size(evpmd); if (*argv != NULL) { while (*argv != NULL) diff --git a/crypto/openssl/apps/req.c b/crypto/openssl/apps/req.c index a603907cd5af..23757044ab7f 100644 --- a/crypto/openssl/apps/req.c +++ b/crypto/openssl/apps/req.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,6 +14,7 @@ #include #include "apps.h" #include "progs.h" +#include #include #include #include @@ -25,32 +26,29 @@ #include #include #include -#ifndef OPENSSL_NO_RSA -# include -#endif +#include #ifndef OPENSSL_NO_DSA # include #endif -#define SECTION "req" - -#define BITS "default_bits" -#define KEYFILE "default_keyfile" -#define PROMPT "prompt" -#define DISTINGUISHED_NAME "distinguished_name" -#define ATTRIBUTES "attributes" -#define V3_EXTENSIONS "x509_extensions" -#define REQ_EXTENSIONS "req_extensions" -#define STRING_MASK "string_mask" -#define UTF8_IN "utf8" - -#define DEFAULT_KEY_LENGTH 2048 -#define MIN_KEY_LENGTH 512 - -static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *dn, int mutlirdn, - int attribs, unsigned long chtype); -static int build_subject(X509_REQ *req, const char *subj, unsigned long chtype, - int multirdn); +#define BITS "default_bits" +#define KEYFILE "default_keyfile" +#define PROMPT "prompt" +#define DISTINGUISHED_NAME "distinguished_name" +#define ATTRIBUTES "attributes" +#define V3_EXTENSIONS "x509_extensions" +#define REQ_EXTENSIONS "req_extensions" +#define STRING_MASK "string_mask" +#define UTF8_IN "utf8" + +#define DEFAULT_KEY_LENGTH 2048 +#define MIN_KEY_LENGTH 512 +#define DEFAULT_DAYS 30 /* default cert validity period in days */ +#define UNSET_DAYS -2 /* -1 may be used for testing expiration checks */ +#define EXT_COPY_UNSET -1 + +static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, X509_NAME *fsubj, + int mutlirdn, int attribs, unsigned long chtype); static int prompt_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, const char *dn_sect, STACK_OF(CONF_VALUE) *attr_sk, const char *attr_sect, @@ -65,91 +63,113 @@ static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value, int nid, int n_min, int n_max, unsigned long chtype, int mval); static int genpkey_cb(EVP_PKEY_CTX *ctx); -static int build_data(char *text, const char *def, - char *value, int n_min, int n_max, - char *buf, const int buf_size, - const char *desc1, const char *desc2 - ); +static int build_data(char *text, const char *def, char *value, + int n_min, int n_max, char *buf, const int buf_size, + const char *desc1, const char *desc2); static int req_check_len(int len, int n_min, int n_max); static int check_end(const char *str, const char *end); static int join(char buf[], size_t buf_size, const char *name, const char *tail, const char *desc); static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr, - int *pkey_type, long *pkeylen, - char **palgnam, ENGINE *keygen_engine); + char **pkeytype, long *pkeylen, + ENGINE *keygen_engine); + +static const char *section = "req"; static CONF *req_conf = NULL; static CONF *addext_conf = NULL; static int batch = 0; typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_KEYGEN_ENGINE, OPT_KEY, OPT_PUBKEY, OPT_NEW, OPT_CONFIG, OPT_KEYFORM, OPT_IN, OPT_OUT, OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_NEWKEY, - OPT_PKEYOPT, OPT_SIGOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS, - OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8, + OPT_PKEYOPT, OPT_SIGOPT, OPT_VFYOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS, + OPT_VERIFY, OPT_NOENC, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8, OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509, - OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_ADDEXT, OPT_EXTENSIONS, + OPT_CA, OPT_CAKEY, + OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, + OPT_COPY_EXTENSIONS, OPT_ADDEXT, OPT_EXTENSIONS, OPT_REQEXTS, OPT_PRECERT, OPT_MD, - OPT_R_ENUM + OPT_SECTION, + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS req_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, + {"keygen_engine", OPT_KEYGEN_ENGINE, 's', + "Specify engine to be used for key generation operations"}, +#endif + {"in", OPT_IN, '<', "X.509 request input file (default stdin)"}, {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, - {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, - {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, - {"key", OPT_KEY, 's', "Private key to use"}, - {"keyform", OPT_KEYFORM, 'f', "Key file format"}, - {"pubkey", OPT_PUBKEY, '-', "Output public key"}, + {"verify", OPT_VERIFY, '-', "Verify self-signature on the request"}, + + OPT_SECTION("Certificate"), {"new", OPT_NEW, '-', "New request"}, {"config", OPT_CONFIG, '<', "Request template file"}, - {"keyout", OPT_KEYOUT, '>', "File to send the key to"}, - {"passin", OPT_PASSIN, 's', "Private key password source"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - OPT_R_OPTIONS, - {"newkey", OPT_NEWKEY, 's', "Specify as type:bits"}, - {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, - {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, - {"batch", OPT_BATCH, '-', - "Do not ask anything during request generation"}, - {"newhdr", OPT_NEWHDR, '-', "Output \"NEW\" in the header lines"}, - {"modulus", OPT_MODULUS, '-', "RSA modulus"}, - {"verify", OPT_VERIFY, '-', "Verify signature on REQ"}, - {"nodes", OPT_NODES, '-', "Don't encrypt the output key"}, - {"noout", OPT_NOOUT, '-', "Do not output REQ"}, - {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"section", OPT_SECTION, 's', "Config section to use (default \"req\")"}, {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, + {"nameopt", OPT_NAMEOPT, 's', "Certificate subject/issuer name printing options"}, {"reqopt", OPT_REQOPT, 's', "Various request text options"}, {"text", OPT_TEXT, '-', "Text form of request"}, {"x509", OPT_X509, '-', - "Output a x509 structure instead of a cert request"}, + "Output an X.509 certificate structure instead of a cert request"}, + {"CA", OPT_CA, '<', "Issuer cert to use for signing a cert, implies -x509"}, + {"CAkey", OPT_CAKEY, 's', + "Issuer private key to use with -CA; default is -CA arg"}, {OPT_MORE_STR, 1, 1, "(Required by some CA's)"}, - {"subj", OPT_SUBJ, 's', "Set or modify request subject"}, - {"subject", OPT_SUBJECT, '-', "Output the request's subject"}, + {"subj", OPT_SUBJ, 's', "Set or modify subject of request or cert"}, + {"subject", OPT_SUBJECT, '-', + "Print the subject of the output request or cert"}, {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-', - "Enable support for multivalued RDNs"}, + "Deprecated; multi-valued RDNs support is always on."}, {"days", OPT_DAYS, 'p', "Number of days cert is valid for"}, {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"}, + {"copy_extensions", OPT_COPY_EXTENSIONS, 's', + "copy extensions from request when using -x509"}, {"addext", OPT_ADDEXT, 's', "Additional cert extension key=value pair (may be given more than once)"}, {"extensions", OPT_EXTENSIONS, 's', "Cert extension section (override value in config file)"}, {"reqexts", OPT_REQEXTS, 's', "Request extension section (override value in config file)"}, - {"precert", OPT_PRECERT, '-', "Add a poison extension (implies -new)"}, + {"precert", OPT_PRECERT, '-', + "Add a poison extension to the generated cert (implies -new)"}, + + OPT_SECTION("Keys and Signing"), + {"key", OPT_KEY, 's', "Key for signing, and to include unless -in given"}, + {"keyform", OPT_KEYFORM, 'f', "Key file format (ENGINE, other values ignored)"}, + {"pubkey", OPT_PUBKEY, '-', "Output public key"}, + {"keyout", OPT_KEYOUT, '>', "File to write private key to"}, + {"passin", OPT_PASSIN, 's', "Private key and certificate password source"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"newkey", OPT_NEWKEY, 's', + "Generate new key with [:] or [:] or param:"}, + {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, + {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, + {"vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form"}, {"", OPT_MD, '-', "Any supported digest"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, - {"keygen_engine", OPT_KEYGEN_ENGINE, 's', - "Specify engine to be used for key generation operations"}, -#endif + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + {"batch", OPT_BATCH, '-', + "Do not ask anything during request generation"}, + {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"noenc", OPT_NOENC, '-', "Don't encrypt private keys"}, + {"nodes", OPT_NODES, '-', "Don't encrypt private keys; deprecated"}, + {"noout", OPT_NOOUT, '-', "Do not output REQ"}, + {"newhdr", OPT_NEWHDR, '-', "Output \"NEW\" in the header lines"}, + {"modulus", OPT_MODULUS, '-', "RSA modulus"}, + + OPT_R_OPTIONS, + OPT_PROV_OPTIONS, {NULL} }; - /* * An LHASH of strings, where each string is an extension name. */ @@ -169,9 +189,8 @@ static void exts_cleanup(OPENSSL_STRING *x) } /* - * Is the |kv| key already duplicated? This is remarkably tricky to get - * right. Return 0 if unique, -1 on runtime error; 1 if found or a syntax - * error. + * Is the |kv| key already duplicated? This is remarkably tricky to get right. + * Return 0 if unique, -1 on runtime error; 1 if found or a syntax error. */ static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv) { @@ -200,7 +219,7 @@ static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv) *p = '\0'; /* Finally have a clean "key"; see if it's there [by attempt to add it]. */ - p = (char *)lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING*)kv); + p = (char *)lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING *)kv); if (p != NULL) { OPENSSL_free(p); return 1; @@ -215,36 +234,39 @@ static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv) int req_main(int argc, char **argv) { ASN1_INTEGER *serial = NULL; - BIO *in = NULL, *out = NULL; + BIO *out = NULL; ENGINE *e = NULL, *gen_eng = NULL; - EVP_PKEY *pkey = NULL; + EVP_PKEY *pkey = NULL, *CAkey = NULL; EVP_PKEY_CTX *genctx = NULL; - STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL; + STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL, *vfyopts = NULL; LHASH_OF(OPENSSL_STRING) *addexts = NULL; - X509 *x509ss = NULL; + X509 *new_x509 = NULL, *CAcert = NULL; X509_REQ *req = NULL; - const EVP_CIPHER *cipher = NULL; - const EVP_MD *md_alg = NULL, *digest = NULL; + EVP_CIPHER *cipher = NULL; + EVP_MD *md = NULL; + int ext_copy = EXT_COPY_UNSET; BIO *addext_bio = NULL; - char *extensions = NULL, *infile = NULL; - char *outfile = NULL, *keyfile = NULL; + char *extensions = NULL; + const char *infile = NULL, *CAfile = NULL, *CAkeyfile = NULL; + char *outfile = NULL, *keyfile = NULL, *digest = NULL; char *keyalgstr = NULL, *p, *prog, *passargin = NULL, *passargout = NULL; char *passin = NULL, *passout = NULL; char *nofree_passin = NULL, *nofree_passout = NULL; char *req_exts = NULL, *subj = NULL; + X509_NAME *fsubj = NULL; char *template = default_config_file, *keyout = NULL; const char *keyalg = NULL; OPTION_CHOICE o; - int ret = 1, x509 = 0, days = 0, i = 0, newreq = 0, verbose = 0; - int pkey_type = -1, private = 0; - int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyform = FORMAT_PEM; - int modulus = 0, multirdn = 0, verify = 0, noout = 0, text = 0; - int nodes = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0; - long newkey = -1; + int days = UNSET_DAYS; + int ret = 1, gen_x509 = 0, i = 0, newreq = 0, verbose = 0; + int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, keyform = FORMAT_UNDEF; + int modulus = 0, multirdn = 1, verify = 0, noout = 0, text = 0; + int noenc = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0; + long newkey_len = -1; unsigned long chtype = MBSTRING_ASC, reqflag = 0; #ifndef OPENSSL_NO_DES - cipher = EVP_des_ede3_cbc(); + cipher = (EVP_CIPHER *)EVP_des_ede3_cbc(); #endif prog = opt_init(argc, argv, req_options); @@ -272,7 +294,7 @@ int req_main(int argc, char **argv) break; case OPT_KEYGEN_ENGINE: #ifndef OPENSSL_NO_ENGINE - gen_eng = ENGINE_by_id(opt_arg()); + gen_eng = setup_engine(opt_arg(), 0); if (gen_eng == NULL) { BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv); goto opthelp; @@ -291,6 +313,9 @@ int req_main(int argc, char **argv) case OPT_CONFIG: template = opt_arg(); break; + case OPT_SECTION: + section = opt_arg(); + break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) goto opthelp; @@ -314,14 +339,19 @@ int req_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_NEWKEY: keyalg = opt_arg(); newreq = 1; break; case OPT_PKEYOPT: - if (!pkeyopts) + if (pkeyopts == NULL) pkeyopts = sk_OPENSSL_STRING_new_null(); - if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, opt_arg())) + if (pkeyopts == NULL + || !sk_OPENSSL_STRING_push(pkeyopts, opt_arg())) goto opthelp; break; case OPT_SIGOPT: @@ -330,6 +360,12 @@ int req_main(int argc, char **argv) if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) goto opthelp; break; + case OPT_VFYOPT: + if (!vfyopts) + vfyopts = sk_OPENSSL_STRING_new_null(); + if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg())) + goto opthelp; + break; case OPT_BATCH: batch = 1; break; @@ -343,7 +379,8 @@ int req_main(int argc, char **argv) verify = 1; break; case OPT_NODES: - nodes = 1; + case OPT_NOENC: + noenc = 1; break; case OPT_NOOUT: noout = 1; @@ -366,10 +403,22 @@ int req_main(int argc, char **argv) text = 1; break; case OPT_X509: - x509 = 1; + gen_x509 = 1; + break; + case OPT_CA: + CAfile = opt_arg(); + gen_x509 = 1; + break; + case OPT_CAKEY: + CAkeyfile = opt_arg(); break; case OPT_DAYS: days = atoi(opt_arg()); + if (days < -1) { + BIO_printf(bio_err, "%s: -days parameter arg must be >= -1\n", + prog); + goto end; + } break; case OPT_SET_SERIAL: if (serial != NULL) { @@ -387,7 +436,14 @@ int req_main(int argc, char **argv) subj = opt_arg(); break; case OPT_MULTIVALUE_RDN: - multirdn = 1; + /* obsolete */ + break; + case OPT_COPY_EXTENSIONS: + if (!set_ext_copy(&ext_copy, opt_arg())) { + BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", + opt_arg()); + goto end; + } break; case OPT_ADDEXT: p = opt_arg(); @@ -398,9 +454,11 @@ int req_main(int argc, char **argv) goto end; } i = duplicated(addexts, p); - if (i == 1) + if (i == 1) { + BIO_printf(bio_err, "Duplicate extension: %s\n", p); goto opthelp; - if (i < 0 || BIO_printf(addext_bio, "%s\n", opt_arg()) < 0) + } + if (i < 0 || BIO_printf(addext_bio, "%s\n", p) < 0) goto end; break; case OPT_EXTENSIONS: @@ -413,37 +471,39 @@ int req_main(int argc, char **argv) newreq = precert = 1; break; case OPT_MD: - if (!opt_md(opt_unknown(), &md_alg)) - goto opthelp; - digest = md_alg; + digest = opt_unknown(); break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; - if (days && !x509) - BIO_printf(bio_err, "Ignoring -days; not generating a certificate\n"); - if (x509 && infile == NULL) - newreq = 1; + if (!app_RAND_load()) + goto end; - /* TODO: simplify this as pkey is still always NULL here */ - private = newreq && (pkey == NULL) ? 1 : 0; + if (!gen_x509) { + if (days != UNSET_DAYS) + BIO_printf(bio_err, "Ignoring -days without -x509; not generating a certificate\n"); + if (ext_copy == EXT_COPY_NONE) + BIO_printf(bio_err, "Ignoring -copy_extensions 'none' when -x509 is not given\n"); + } + if (gen_x509 && infile == NULL) + newreq = 1; if (!app_passwd(passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } - if (verbose) - BIO_printf(bio_err, "Using configuration from %s\n", template); - if ((req_conf = app_load_config(template)) == NULL) + if ((req_conf = app_load_config_verbose(template, verbose)) == NULL) goto end; - if (addext_bio) { + if (addext_bio != NULL) { if (verbose) BIO_printf(bio_err, - "Using additional configuration from command line\n"); + "Using additional configuration from -addext options\n"); if ((addext_conf = app_load_config_bio(addext_bio, NULL)) == NULL) goto end; } @@ -455,14 +515,12 @@ int req_main(int argc, char **argv) if (p == NULL) ERR_clear_error(); if (p != NULL) { - BIO *oid_bio; + BIO *oid_bio = BIO_new_file(p, "r"); - oid_bio = BIO_new_file(p, "r"); if (oid_bio == NULL) { - /*- - BIO_printf(bio_err,"problems opening %s for extra oid's\n",p); - ERR_print_errors(bio_err); - */ + if (verbose) + BIO_printf(bio_err, + "Problems opening '%s' for extra OIDs\n", p); } else { OBJ_create_objects(oid_bio); BIO_free(oid_bio); @@ -472,59 +530,67 @@ int req_main(int argc, char **argv) if (!add_oid_section(req_conf)) goto end; - if (md_alg == NULL) { - p = NCONF_get_string(req_conf, SECTION, "default_md"); - if (p == NULL) { + /* Check that any specified digest is fetchable */ + if (digest != NULL) { + if (!opt_md(digest, &md)) { ERR_clear_error(); - } else { - if (!opt_md(p, &md_alg)) - goto opthelp; - digest = md_alg; + goto opthelp; } + EVP_MD_free(md); + } else { + /* No digest specified, default to configuration */ + p = NCONF_get_string(req_conf, section, "default_md"); + if (p == NULL) + ERR_clear_error(); + else + digest = p; } if (extensions == NULL) { - extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS); + extensions = NCONF_get_string(req_conf, section, V3_EXTENSIONS); if (extensions == NULL) ERR_clear_error(); } if (extensions != NULL) { /* Check syntax of file */ X509V3_CTX ctx; + X509V3_set_ctx_test(&ctx); X509V3_set_nconf(&ctx, req_conf); if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) { BIO_printf(bio_err, - "Error Loading extension section %s\n", extensions); + "Error checking x509 extension section %s\n", + extensions); goto end; } } if (addext_conf != NULL) { /* Check syntax of command line extensions */ X509V3_CTX ctx; + X509V3_set_ctx_test(&ctx); X509V3_set_nconf(&ctx, addext_conf); if (!X509V3_EXT_add_nconf(addext_conf, &ctx, "default", NULL)) { - BIO_printf(bio_err, "Error Loading command line extensions\n"); + BIO_printf(bio_err, "Error checking extensions defined using -addext\n"); goto end; } } if (passin == NULL) { passin = nofree_passin = - NCONF_get_string(req_conf, SECTION, "input_password"); + NCONF_get_string(req_conf, section, "input_password"); if (passin == NULL) ERR_clear_error(); } if (passout == NULL) { passout = nofree_passout = - NCONF_get_string(req_conf, SECTION, "output_password"); + NCONF_get_string(req_conf, section, "output_password"); if (passout == NULL) ERR_clear_error(); } - p = NCONF_get_string(req_conf, SECTION, STRING_MASK); + p = NCONF_get_string(req_conf, section, STRING_MASK); if (p == NULL) ERR_clear_error(); @@ -534,7 +600,7 @@ int req_main(int argc, char **argv) } if (chtype != MBSTRING_UTF8) { - p = NCONF_get_string(req_conf, SECTION, UTF8_IN); + p = NCONF_get_string(req_conf, section, UTF8_IN); if (p == NULL) ERR_clear_error(); else if (strcmp(p, "yes") == 0) @@ -542,134 +608,117 @@ int req_main(int argc, char **argv) } if (req_exts == NULL) { - req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS); + req_exts = NCONF_get_string(req_conf, section, REQ_EXTENSIONS); if (req_exts == NULL) ERR_clear_error(); } if (req_exts != NULL) { /* Check syntax of file */ X509V3_CTX ctx; + X509V3_set_ctx_test(&ctx); X509V3_set_nconf(&ctx, req_conf); if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) { BIO_printf(bio_err, - "Error Loading request extension section %s\n", + "Error checking request extension section %s\n", req_exts); goto end; } } if (keyfile != NULL) { - pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key"); - if (pkey == NULL) { - /* load_key() has already printed an appropriate message */ + pkey = load_key(keyfile, keyform, 0, passin, e, "private key"); + if (pkey == NULL) goto end; - } else { - app_RAND_load_conf(req_conf, SECTION); - } + app_RAND_load_conf(req_conf, section); } + if (newreq && pkey == NULL) { + app_RAND_load_conf(req_conf, section); - if (newreq && (pkey == NULL)) { - app_RAND_load_conf(req_conf, SECTION); + if (!NCONF_get_number(req_conf, section, BITS, &newkey_len)) + newkey_len = DEFAULT_KEY_LENGTH; - if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) { - newkey = DEFAULT_KEY_LENGTH; - } - - if (keyalg != NULL) { - genctx = set_keygen_ctx(keyalg, &pkey_type, &newkey, - &keyalgstr, gen_eng); - if (genctx == NULL) - goto end; - } + genctx = set_keygen_ctx(keyalg, &keyalgstr, &newkey_len, gen_eng); + if (genctx == NULL) + goto end; - if (newkey < MIN_KEY_LENGTH - && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) { - BIO_printf(bio_err, "private key length is too short,\n"); - BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n", - MIN_KEY_LENGTH, newkey); + if (newkey_len < MIN_KEY_LENGTH + && (EVP_PKEY_CTX_is_a(genctx, "RSA") + || EVP_PKEY_CTX_is_a(genctx, "RSA-PSS") + || EVP_PKEY_CTX_is_a(genctx, "DSA"))) { + BIO_printf(bio_err, "Private key length too short, needs to be at least %d bits, not %ld.\n", + MIN_KEY_LENGTH, newkey_len); goto end; } - if (pkey_type == EVP_PKEY_RSA && newkey > OPENSSL_RSA_MAX_MODULUS_BITS) + if (newkey_len > OPENSSL_RSA_MAX_MODULUS_BITS + && (EVP_PKEY_CTX_is_a(genctx, "RSA") + || EVP_PKEY_CTX_is_a(genctx, "RSA-PSS"))) BIO_printf(bio_err, "Warning: It is not recommended to use more than %d bit for RSA keys.\n" " Your key size is %ld! Larger key size may behave not as expected.\n", - OPENSSL_RSA_MAX_MODULUS_BITS, newkey); + OPENSSL_RSA_MAX_MODULUS_BITS, newkey_len); #ifndef OPENSSL_NO_DSA - if (pkey_type == EVP_PKEY_DSA && newkey > OPENSSL_DSA_MAX_MODULUS_BITS) + if (EVP_PKEY_CTX_is_a(genctx, "DSA") + && newkey_len > OPENSSL_DSA_MAX_MODULUS_BITS) BIO_printf(bio_err, "Warning: It is not recommended to use more than %d bit for DSA keys.\n" " Your key size is %ld! Larger key size may behave not as expected.\n", - OPENSSL_DSA_MAX_MODULUS_BITS, newkey); + OPENSSL_DSA_MAX_MODULUS_BITS, newkey_len); #endif - if (genctx == NULL) { - genctx = set_keygen_ctx(NULL, &pkey_type, &newkey, - &keyalgstr, gen_eng); - if (!genctx) - goto end; - } - if (pkeyopts != NULL) { char *genopt; for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) { genopt = sk_OPENSSL_STRING_value(pkeyopts, i); if (pkey_ctrl_string(genctx, genopt) <= 0) { - BIO_printf(bio_err, "parameter error \"%s\"\n", genopt); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Key parameter error \"%s\"\n", genopt); goto end; } } } - if (pkey_type == EVP_PKEY_EC) { - BIO_printf(bio_err, "Generating an EC private key\n"); - } else { - BIO_printf(bio_err, "Generating a %s private key\n", keyalgstr); - } - EVP_PKEY_CTX_set_cb(genctx, genpkey_cb); EVP_PKEY_CTX_set_app_data(genctx, bio_err); - if (EVP_PKEY_keygen(genctx, &pkey) <= 0) { - BIO_puts(bio_err, "Error Generating Key\n"); - goto end; - } + pkey = app_keygen(genctx, keyalgstr, newkey_len, verbose); EVP_PKEY_CTX_free(genctx); genctx = NULL; + } + if (keyout == NULL && keyfile == NULL) { + keyout = NCONF_get_string(req_conf, section, KEYFILE); + if (keyout == NULL) + ERR_clear_error(); + } - if (keyout == NULL) { - keyout = NCONF_get_string(req_conf, SECTION, KEYFILE); + if (pkey != NULL && (keyfile == NULL || keyout != NULL)) { + if (verbose) { + BIO_printf(bio_err, "Writing private key to "); if (keyout == NULL) - ERR_clear_error(); + BIO_printf(bio_err, "stdout\n"); + else + BIO_printf(bio_err, "'%s'\n", keyout); } - - if (keyout == NULL) - BIO_printf(bio_err, "writing new private key to stdout\n"); - else - BIO_printf(bio_err, "writing new private key to '%s'\n", keyout); - out = bio_open_owner(keyout, outformat, private); + out = bio_open_owner(keyout, outformat, newreq); if (out == NULL) goto end; - p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key"); + p = NCONF_get_string(req_conf, section, "encrypt_rsa_key"); if (p == NULL) { ERR_clear_error(); - p = NCONF_get_string(req_conf, SECTION, "encrypt_key"); + p = NCONF_get_string(req_conf, section, "encrypt_key"); if (p == NULL) ERR_clear_error(); } if ((p != NULL) && (strcmp(p, "no") == 0)) cipher = NULL; - if (nodes) + if (noenc) cipher = NULL; i = 0; loop: - assert(private); if (!PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, passout)) { if ((ERR_GET_REASON(ERR_peek_error()) == @@ -685,112 +734,151 @@ int req_main(int argc, char **argv) BIO_printf(bio_err, "-----\n"); } + /* + * subj is expected to be in the format /type0=value0/type1=value1/type2=... + * where characters may be escaped by \ + */ + if (subj != NULL + && (fsubj = parse_name(subj, chtype, multirdn, "subject")) == NULL) + goto end; + if (!newreq) { - in = bio_open_default(infile, 'r', informat); - if (in == NULL) + req = load_csr(infile /* if NULL, reads from stdin */, + informat, "X509 request"); + if (req == NULL) goto end; + } - if (informat == FORMAT_ASN1) - req = d2i_X509_REQ_bio(in, NULL); - else - req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); - if (req == NULL) { - BIO_printf(bio_err, "unable to load X509 request\n"); + if (CAkeyfile == NULL) + CAkeyfile = CAfile; + if (CAkeyfile != NULL) { + if (CAfile == NULL) { + BIO_printf(bio_err, + "Warning: Ignoring -CAkey option since no -CA option is given\n"); + } else { + if ((CAkey = load_key(CAkeyfile, FORMAT_UNDEF, + 0, passin, e, + CAkeyfile != CAfile + ? "issuer private key from -CAkey arg" + : "issuer private key from -CA arg")) == NULL) + goto end; + } + } + if (CAfile != NULL) { + if ((CAcert = load_cert_pass(CAfile, FORMAT_UNDEF, 1, passin, + "issuer cert from -CA arg")) == NULL) + goto end; + if (!X509_check_private_key(CAcert, CAkey)) { + BIO_printf(bio_err, + "Issuer CA certificate and key do not match\n"); goto end; } } - - if (newreq || x509) { - if (pkey == NULL) { - BIO_printf(bio_err, "you need to specify a private key\n"); + if (newreq || gen_x509) { + if (CAcert == NULL && pkey == NULL) { + BIO_printf(bio_err, "Must provide a signature key using -key or" + " provide -CA / -CAkey\n"); goto end; } if (req == NULL) { - req = X509_REQ_new(); + req = X509_REQ_new_ex(app_get0_libctx(), app_get0_propq()); if (req == NULL) { goto end; } - i = make_REQ(req, pkey, subj, multirdn, !x509, chtype); - subj = NULL; /* done processing '-subj' option */ - if (!i) { - BIO_printf(bio_err, "problems making Certificate Request\n"); + if (!make_REQ(req, pkey, fsubj, multirdn, !gen_x509, chtype)){ + BIO_printf(bio_err, "Error making certificate request\n"); goto end; } + /* Note that -x509 can take over -key and -subj option values. */ } - if (x509) { - EVP_PKEY *tmppkey; + if (gen_x509) { + EVP_PKEY *pub_key = X509_REQ_get0_pubkey(req); + EVP_PKEY *issuer_key = CAcert != NULL ? CAkey : pkey; X509V3_CTX ext_ctx; - if ((x509ss = X509_new()) == NULL) - goto end; + X509_NAME *issuer = CAcert != NULL ? X509_get_subject_name(CAcert) : + X509_REQ_get_subject_name(req); + X509_NAME *n_subj = fsubj != NULL ? fsubj : + X509_REQ_get_subject_name(req); - /* Set version to V3 */ - if ((extensions != NULL || addext_conf != NULL) - && !X509_set_version(x509ss, 2)) + if ((new_x509 = X509_new_ex(app_get0_libctx(), + app_get0_propq())) == NULL) goto end; + if (serial != NULL) { - if (!X509_set_serialNumber(x509ss, serial)) + if (!X509_set_serialNumber(new_x509, serial)) goto end; } else { - if (!rand_serial(NULL, X509_get_serialNumber(x509ss))) + if (!rand_serial(NULL, X509_get_serialNumber(new_x509))) goto end; } - if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) + if (!X509_set_issuer_name(new_x509, issuer)) goto end; - if (days == 0) { - /* set default days if it's not specified */ - days = 30; + if (days == UNSET_DAYS) { + days = DEFAULT_DAYS; } - if (!set_cert_times(x509ss, NULL, NULL, days)) + if (!set_cert_times(new_x509, NULL, NULL, days)) + goto end; + if (!X509_set_subject_name(new_x509, n_subj)) goto end; - if (!X509_set_subject_name - (x509ss, X509_REQ_get_subject_name(req))) + if (!pub_key || !X509_set_pubkey(new_x509, pub_key)) goto end; - tmppkey = X509_REQ_get0_pubkey(req); - if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey)) + if (ext_copy == EXT_COPY_UNSET) { + if (infile != NULL) + BIO_printf(bio_err, "Warning: No -copy_extensions given; ignoring any extensions in the request\n"); + } else if (!copy_extensions(new_x509, req, ext_copy)) { + BIO_printf(bio_err, "Error copying extensions from request\n"); goto end; + } /* Set up V3 context struct */ - - X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0); + X509V3_set_ctx(&ext_ctx, CAcert != NULL ? CAcert : new_x509, + new_x509, NULL, NULL, X509V3_CTX_REPLACE); + /* prepare fallback for AKID, but only if issuer cert == new_x509 */ + if (CAcert == NULL) { + if (!X509V3_set_issuer_pkey(&ext_ctx, issuer_key)) + goto end; + ERR_set_mark(); + if (!X509_check_private_key(new_x509, issuer_key)) + BIO_printf(bio_err, + "Warning: Signature key and public key of cert do not match\n"); + ERR_pop_to_mark(); + } X509V3_set_nconf(&ext_ctx, req_conf); /* Add extensions */ - if (extensions != NULL && !X509V3_EXT_add_nconf(req_conf, - &ext_ctx, extensions, - x509ss)) { - BIO_printf(bio_err, "Error Loading extension section %s\n", + if (extensions != NULL + && !X509V3_EXT_add_nconf(req_conf, &ext_ctx, extensions, + new_x509)) { + BIO_printf(bio_err, "Error adding x509 extensions from section %s\n", extensions); goto end; } if (addext_conf != NULL && !X509V3_EXT_add_nconf(addext_conf, &ext_ctx, "default", - x509ss)) { - BIO_printf(bio_err, "Error Loading command line extensions\n"); + new_x509)) { + BIO_printf(bio_err, "Error adding extensions defined via -addext\n"); goto end; } /* If a pre-cert was requested, we need to add a poison extension */ if (precert) { - if (X509_add1_ext_i2d(x509ss, NID_ct_precert_poison, NULL, 1, 0) - != 1) { + if (X509_add1_ext_i2d(new_x509, NID_ct_precert_poison, + NULL, 1, 0) != 1) { BIO_printf(bio_err, "Error adding poison extension\n"); goto end; } } - i = do_X509_sign(x509ss, pkey, digest, sigopts); - if (!i) { - ERR_print_errors(bio_err); + i = do_X509_sign(new_x509, issuer_key, digest, sigopts, &ext_ctx); + if (!i) goto end; - } } else { X509V3_CTX ext_ctx; /* Set up V3 context struct */ - X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0); X509V3_set_nconf(&ext_ctx, req_conf); @@ -798,49 +886,39 @@ int req_main(int argc, char **argv) if (req_exts != NULL && !X509V3_EXT_REQ_add_nconf(req_conf, &ext_ctx, req_exts, req)) { - BIO_printf(bio_err, "Error Loading extension section %s\n", + BIO_printf(bio_err, "Error adding request extensions from section %s\n", req_exts); goto end; } if (addext_conf != NULL && !X509V3_EXT_REQ_add_nconf(addext_conf, &ext_ctx, "default", req)) { - BIO_printf(bio_err, "Error Loading command line extensions\n"); + BIO_printf(bio_err, "Error adding extensions defined via -addext\n"); goto end; } i = do_X509_REQ_sign(req, pkey, digest, sigopts); - if (!i) { - ERR_print_errors(bio_err); + if (!i) goto end; - } } } - if (subj && x509) { - BIO_printf(bio_err, "Cannot modify certificate subject\n"); - goto end; - } - - if (subj && !x509) { + if (subj != NULL && !newreq && !gen_x509) { if (verbose) { - BIO_printf(bio_err, "Modifying Request's Subject\n"); - print_name(bio_err, "old subject=", - X509_REQ_get_subject_name(req), get_nameopt()); + BIO_printf(out, "Modifying subject of certificate request\n"); + print_name(out, "Old subject=", X509_REQ_get_subject_name(req)); } - if (build_subject(req, subj, chtype, multirdn) == 0) { - BIO_printf(bio_err, "ERROR: cannot modify subject\n"); - ret = 1; + if (!X509_REQ_set_subject_name(req, fsubj)) { + BIO_printf(bio_err, "Error modifying subject of certificate request\n"); goto end; } if (verbose) { - print_name(bio_err, "new subject=", - X509_REQ_get_subject_name(req), get_nameopt()); + print_name(out, "New subject=", X509_REQ_get_subject_name(req)); } } - if (verify && !x509) { + if (verify) { EVP_PKEY *tpubkey = pkey; if (tpubkey == NULL) { @@ -849,16 +927,14 @@ int req_main(int argc, char **argv) goto end; } - i = X509_REQ_verify(req, tpubkey); + i = do_X509_REQ_verify(req, tpubkey, vfyopts); - if (i < 0) { + if (i < 0) goto end; - } else if (i == 0) { - BIO_printf(bio_err, "verify failure\n"); - ERR_print_errors(bio_err); - } else { /* if (i > 0) */ - BIO_printf(bio_err, "verify OK\n"); - } + if (i == 0) + BIO_printf(bio_err, "Certificate request self-signature verify failure\n"); + else /* i > 0 */ + BIO_printf(bio_err, "Certificate request self-signature verify OK\n"); } if (noout && !text && !modulus && !subject && !pubkey) { @@ -878,62 +954,58 @@ int req_main(int argc, char **argv) if (tpubkey == NULL) { BIO_printf(bio_err, "Error getting public key\n"); - ERR_print_errors(bio_err); goto end; } PEM_write_bio_PUBKEY(out, tpubkey); } if (text) { - if (x509) - ret = X509_print_ex(out, x509ss, get_nameopt(), reqflag); + if (gen_x509) + ret = X509_print_ex(out, new_x509, get_nameopt(), reqflag); else ret = X509_REQ_print_ex(out, req, get_nameopt(), reqflag); if (ret == 0) { - if (x509) - BIO_printf(bio_err, "Error printing certificate\n"); + if (gen_x509) + BIO_printf(bio_err, "Error printing certificate\n"); else - BIO_printf(bio_err, "Error printing certificate request\n"); - - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Error printing certificate request\n"); goto end; } } if (subject) { - if (x509) - print_name(out, "subject=", X509_get_subject_name(x509ss), - get_nameopt()); - else - print_name(out, "subject=", X509_REQ_get_subject_name(req), - get_nameopt()); + print_name(out, "subject=", gen_x509 + ? X509_get_subject_name(new_x509) + : X509_REQ_get_subject_name(req)); } if (modulus) { EVP_PKEY *tpubkey; - if (x509) - tpubkey = X509_get0_pubkey(x509ss); + if (gen_x509) + tpubkey = X509_get0_pubkey(new_x509); else tpubkey = X509_REQ_get0_pubkey(req); if (tpubkey == NULL) { - fprintf(stdout, "Modulus=unavailable\n"); + fprintf(stdout, "Modulus is unavailable\n"); goto end; } fprintf(stdout, "Modulus="); -#ifndef OPENSSL_NO_RSA - if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA) { - const BIGNUM *n; - RSA_get0_key(EVP_PKEY_get0_RSA(tpubkey), &n, NULL, NULL); + if (EVP_PKEY_is_a(tpubkey, "RSA") || EVP_PKEY_is_a(tpubkey, "RSA-PSS")) { + BIGNUM *n = NULL; + + if (!EVP_PKEY_get_bn_param(tpubkey, "n", &n)) + goto end; BN_print(out, n); - } else -#endif + BN_free(n); + } else { fprintf(stdout, "Wrong Algorithm type"); + } fprintf(stdout, "\n"); } - if (!noout && !x509) { + if (!noout && !gen_x509) { if (outformat == FORMAT_ASN1) i = i2d_X509_REQ_bio(out, req); else if (newhdr) @@ -941,17 +1013,17 @@ int req_main(int argc, char **argv) else i = PEM_write_bio_X509_REQ(out, req); if (!i) { - BIO_printf(bio_err, "unable to write X509 request\n"); + BIO_printf(bio_err, "Unable to write certificate request\n"); goto end; } } - if (!noout && x509 && (x509ss != NULL)) { + if (!noout && gen_x509 && new_x509 != NULL) { if (outformat == FORMAT_ASN1) - i = i2d_X509_bio(out, x509ss); + i = i2d_X509_bio(out, new_x509); else - i = PEM_write_bio_X509(out, x509ss); + i = PEM_write_bio_X509(out, new_x509); if (!i) { - BIO_printf(bio_err, "unable to write X509 certificate\n"); + BIO_printf(bio_err, "Unable to write X509 certificate\n"); goto end; } } @@ -963,20 +1035,23 @@ int req_main(int argc, char **argv) NCONF_free(req_conf); NCONF_free(addext_conf); BIO_free(addext_bio); - BIO_free(in); BIO_free_all(out); EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(genctx); sk_OPENSSL_STRING_free(pkeyopts); sk_OPENSSL_STRING_free(sigopts); + sk_OPENSSL_STRING_free(vfyopts); lh_OPENSSL_STRING_doall(addexts, exts_cleanup); lh_OPENSSL_STRING_free(addexts); #ifndef OPENSSL_NO_ENGINE - ENGINE_free(gen_eng); + release_engine(gen_eng); #endif OPENSSL_free(keyalgstr); X509_REQ_free(req); - X509_free(x509ss); + X509_NAME_free(fsubj); + X509_free(new_x509); + X509_free(CAcert); + EVP_PKEY_free(CAkey); ASN1_INTEGER_free(serial); release_engine(e); if (passin != nofree_passin) @@ -986,50 +1061,48 @@ int req_main(int argc, char **argv) return ret; } -static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn, - int attribs, unsigned long chtype) +static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, X509_NAME *fsubj, + int multirdn, int attribs, unsigned long chtype) { int ret = 0, i; char no_prompt = 0; - STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL; + STACK_OF(CONF_VALUE) *dn_sk = NULL, *attr_sk = NULL; char *tmp, *dn_sect, *attr_sect; - tmp = NCONF_get_string(req_conf, SECTION, PROMPT); + tmp = NCONF_get_string(req_conf, section, PROMPT); if (tmp == NULL) ERR_clear_error(); if ((tmp != NULL) && strcmp(tmp, "no") == 0) no_prompt = 1; - dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME); + dn_sect = NCONF_get_string(req_conf, section, DISTINGUISHED_NAME); if (dn_sect == NULL) { - BIO_printf(bio_err, "unable to find '%s' in config\n", - DISTINGUISHED_NAME); - goto err; - } - dn_sk = NCONF_get_section(req_conf, dn_sect); - if (dn_sk == NULL) { - BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect); - goto err; + ERR_clear_error(); + } else { + dn_sk = NCONF_get_section(req_conf, dn_sect); + if (dn_sk == NULL) { + BIO_printf(bio_err, "Unable to get '%s' section\n", dn_sect); + goto err; + } } - attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES); + attr_sect = NCONF_get_string(req_conf, section, ATTRIBUTES); if (attr_sect == NULL) { ERR_clear_error(); - attr_sk = NULL; } else { attr_sk = NCONF_get_section(req_conf, attr_sect); if (attr_sk == NULL) { - BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect); + BIO_printf(bio_err, "Unable to get '%s' section\n", attr_sect); goto err; } } - /* setup version number */ - if (!X509_REQ_set_version(req, 0L)) - goto err; /* version 1 */ + /* so far there is only version 1 */ + if (!X509_REQ_set_version(req, X509_REQ_VERSION_1)) + goto err; - if (subj) - i = build_subject(req, subj, chtype, multirdn); + if (fsubj != NULL) + i = X509_REQ_set_subject_name(req, fsubj); else if (no_prompt) i = auto_info(req, dn_sk, attr_sk, attribs, chtype); else @@ -1046,26 +1119,6 @@ static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn, return ret; } -/* - * subject is expected to be in the format /type0=value0/type1=value1/type2=... - * where characters may be escaped by \ - */ -static int build_subject(X509_REQ *req, const char *subject, unsigned long chtype, - int multirdn) -{ - X509_NAME *n; - - if ((n = parse_name(subject, chtype, multirdn)) == NULL) - return 0; - - if (!X509_REQ_set_subject_name(req, n)) { - X509_NAME_free(n); - return 0; - } - X509_NAME_free(n); - return 1; -} - static int prompt_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, const char *dn_sect, STACK_OF(CONF_VALUE) *attr_sk, const char *attr_sect, @@ -1079,8 +1132,7 @@ static int prompt_info(X509_REQ *req, char *type, *value; const char *def; CONF_VALUE *v; - X509_NAME *subj; - subj = X509_REQ_get_subject_name(req); + X509_NAME *subj = X509_REQ_get_subject_name(req); if (!batch) { BIO_printf(bio_err, @@ -1100,7 +1152,7 @@ static int prompt_info(X509_REQ *req, if (sk_CONF_VALUE_num(dn_sk)) { i = -1; start: - for ( ; ; ) { + for (;;) { i++; if (sk_CONF_VALUE_num(dn_sk) <= i) break; @@ -1152,7 +1204,6 @@ static int prompt_info(X509_REQ *req, n_min = -1; } - if (!join(buf, sizeof(buf), v->name, "_max", "Name")) return 0; if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) { @@ -1165,8 +1216,7 @@ static int prompt_info(X509_REQ *req, return 0; } if (X509_NAME_entry_count(subj) == 0) { - BIO_printf(bio_err, - "error, no objects specified in config file\n"); + BIO_printf(bio_err, "Error: No objects specified in config file\n"); return 0; } @@ -1181,7 +1231,7 @@ static int prompt_info(X509_REQ *req, i = -1; start2: - for ( ; ; ) { + for (;;) { i++; if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i)) break; @@ -1207,7 +1257,7 @@ static int prompt_info(X509_REQ *req, value = NULL; } - if (!join(buf, sizeof(buf), type,"_min", "Name")) + if (!join(buf, sizeof(buf), type, "_min", "Name")) return 0; if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) { ERR_clear_error(); @@ -1258,10 +1308,10 @@ static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, */ for (p = v->name; *p; p++) { #ifndef CHARSET_EBCDIC - spec_char = ((*p == ':') || (*p == ',') || (*p == '.')); + spec_char = (*p == ':' || *p == ',' || *p == '.'); #else - spec_char = ((*p == os_toascii[':']) || (*p == os_toascii[',']) - || (*p == os_toascii['.'])); + spec_char = (*p == os_toascii[':'] || *p == os_toascii[','] + || *p == os_toascii['.']); #endif if (spec_char) { p++; @@ -1289,7 +1339,7 @@ static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, } if (!X509_NAME_entry_count(subj)) { - BIO_printf(bio_err, "error, no objects specified in config file\n"); + BIO_printf(bio_err, "Error: No objects specified in config file\n"); return 0; } if (attribs) { @@ -1339,19 +1389,15 @@ static int add_attribute_object(X509_REQ *req, char *text, const char *def, if (!X509_REQ_add1_attr_by_NID(req, nid, chtype, (unsigned char *)buf, -1)) { BIO_printf(bio_err, "Error adding attribute\n"); - ERR_print_errors(bio_err); ret = 0; } return ret; } - -static int build_data(char *text, const char *def, - char *value, int n_min, int n_max, - char *buf, const int buf_size, - const char *desc1, const char *desc2 - ) +static int build_data(char *text, const char *def, char *value, + int n_min, int n_max, char *buf, const int buf_size, + const char *desc1, const char *desc2) { int i; start: @@ -1386,7 +1432,7 @@ static int build_data(char *text, const char *def, i = strlen(buf); if (buf[i - 1] != '\n') { - BIO_printf(bio_err, "weird input :-(\n"); + BIO_printf(bio_err, "Missing newline at end of input\n"); return 0; } buf[--i] = '\0'; @@ -1403,16 +1449,14 @@ static int build_data(char *text, const char *def, static int req_check_len(int len, int n_min, int n_max) { - if ((n_min > 0) && (len < n_min)) { + if (n_min > 0 && len < n_min) { BIO_printf(bio_err, - "string is too short, it needs to be at least %d bytes long\n", - n_min); + "String too short, must be at least %d bytes long\n", n_min); return 0; } - if ((n_max >= 0) && (len > n_max)) { + if (n_max >= 0 && len > n_max) { BIO_printf(bio_err, - "string is too long, it needs to be no more than %d bytes long\n", - n_max); + "String too long, must be at most %d bytes long\n", n_max); return 0; } return 1; @@ -1451,66 +1495,71 @@ static int join(char buf[], size_t buf_size, const char *name, } static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr, - int *pkey_type, long *pkeylen, - char **palgnam, ENGINE *keygen_engine) + char **pkeytype, long *pkeylen, + ENGINE *keygen_engine) { EVP_PKEY_CTX *gctx = NULL; EVP_PKEY *param = NULL; long keylen = -1; BIO *pbio = NULL; + const char *keytype = NULL; + size_t keytypelen = 0; + int expect_paramfile = 0; const char *paramfile = NULL; + /* Treat the first part of gstr, and only that */ if (gstr == NULL) { - *pkey_type = EVP_PKEY_RSA; + /* + * Special case: when no string given, default to RSA and the + * key length given by |*pkeylen|. + */ + keytype = "RSA"; keylen = *pkeylen; } else if (gstr[0] >= '0' && gstr[0] <= '9') { - *pkey_type = EVP_PKEY_RSA; - keylen = atol(gstr); - *pkeylen = keylen; - } else if (strncmp(gstr, "param:", 6) == 0) { - paramfile = gstr + 6; + /* Special case: only keylength given from string, so default to RSA */ + keytype = "RSA"; + /* The second part treatment will do the rest */ } else { const char *p = strchr(gstr, ':'); int len; - ENGINE *tmpeng; - const EVP_PKEY_ASN1_METHOD *ameth; if (p != NULL) len = p - gstr; else len = strlen(gstr); - /* - * The lookup of a the string will cover all engines so keep a note - * of the implementation. - */ - ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len); - - if (ameth == NULL) { - BIO_printf(bio_err, "Unknown algorithm %.*s\n", len, gstr); - return NULL; - } - - EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, ameth); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(tmpeng); -#endif - if (*pkey_type == EVP_PKEY_RSA) { - if (p != NULL) { - keylen = atol(p + 1); - *pkeylen = keylen; - } else { - keylen = *pkeylen; + if (strncmp(gstr, "param", len) == 0) { + expect_paramfile = 1; + if (p == NULL) { + BIO_printf(bio_err, + "Parameter file requested but no path given: %s\n", + gstr); + return NULL; } - } else if (p != NULL) { - paramfile = p + 1; + } else { + keytype = gstr; + keytypelen = len; } + + if (p != NULL) + gstr = gstr + len + 1; + else + gstr = NULL; + } + + /* Treat the second part of gstr, if there is one */ + if (gstr != NULL) { + /* If the second part starts with a digit, we assume it's a size */ + if (!expect_paramfile && gstr[0] >= '0' && gstr[0] <= '9') + keylen = atol(gstr); + else + paramfile = gstr; } if (paramfile != NULL) { pbio = BIO_new_file(paramfile, "r"); if (pbio == NULL) { - BIO_printf(bio_err, "Can't open parameter file %s\n", paramfile); + BIO_printf(bio_err, "Cannot open parameter file %s\n", paramfile); return NULL; } param = PEM_read_bio_Parameters(pbio, NULL); @@ -1532,62 +1581,83 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr, BIO_printf(bio_err, "Error reading parameter file %s\n", paramfile); return NULL; } - if (*pkey_type == -1) { - *pkey_type = EVP_PKEY_id(param); - } else if (*pkey_type != EVP_PKEY_base_id(param)) { - BIO_printf(bio_err, "Key Type does not match parameters\n"); - EVP_PKEY_free(param); - return NULL; + if (keytype == NULL) { + keytype = EVP_PKEY_get0_type_name(param); + if (keytype == NULL) { + EVP_PKEY_free(param); + BIO_puts(bio_err, "Unable to determine key type\n"); + return NULL; + } } } - if (palgnam != NULL) { - const EVP_PKEY_ASN1_METHOD *ameth; - ENGINE *tmpeng; - const char *anam; + if (keytypelen > 0) + *pkeytype = OPENSSL_strndup(keytype, keytypelen); + else + *pkeytype = OPENSSL_strdup(keytype); - ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type); - if (ameth == NULL) { - BIO_puts(bio_err, "Internal error: can't find key algorithm\n"); - return NULL; - } - EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth); - *palgnam = OPENSSL_strdup(anam); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(tmpeng); -#endif + if (*pkeytype == NULL) { + BIO_printf(bio_err, "Out of memory\n"); + EVP_PKEY_free(param); + return NULL; } + if (keylen >= 0) + *pkeylen = keylen; + if (param != NULL) { - gctx = EVP_PKEY_CTX_new(param, keygen_engine); - *pkeylen = EVP_PKEY_bits(param); + if (!EVP_PKEY_is_a(param, *pkeytype)) { + BIO_printf(bio_err, "Key type does not match parameters\n"); + EVP_PKEY_free(param); + return NULL; + } + + if (keygen_engine != NULL) + gctx = EVP_PKEY_CTX_new(param, keygen_engine); + else + gctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), + param, app_get0_propq()); + *pkeylen = EVP_PKEY_get_bits(param); EVP_PKEY_free(param); } else { - gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine); + if (keygen_engine != NULL) { + int pkey_id = get_legacy_pkey_id(app_get0_libctx(), *pkeytype, + keygen_engine); + + if (pkey_id != NID_undef) + gctx = EVP_PKEY_CTX_new_id(pkey_id, keygen_engine); + } else { + gctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), + *pkeytype, app_get0_propq()); + } } if (gctx == NULL) { BIO_puts(bio_err, "Error allocating keygen context\n"); - ERR_print_errors(bio_err); return NULL; } if (EVP_PKEY_keygen_init(gctx) <= 0) { BIO_puts(bio_err, "Error initializing keygen context\n"); - ERR_print_errors(bio_err); EVP_PKEY_CTX_free(gctx); return NULL; } -#ifndef OPENSSL_NO_RSA - if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) { - if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) { - BIO_puts(bio_err, "Error setting RSA keysize\n"); - ERR_print_errors(bio_err); + if (keylen == -1 && (EVP_PKEY_CTX_is_a(gctx, "RSA") + || EVP_PKEY_CTX_is_a(gctx, "RSA-PSS"))) + keylen = *pkeylen; + + if (keylen != -1) { + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t bits = keylen; + + params[0] = + OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_BITS, &bits); + if (EVP_PKEY_CTX_set_params(gctx, params) <= 0) { + BIO_puts(bio_err, "Error setting keysize\n"); EVP_PKEY_CTX_free(gctx); return NULL; } } -#endif return gctx; } @@ -1610,70 +1680,3 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx) (void)BIO_flush(b); return 1; } - -static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey, - const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts) -{ - EVP_PKEY_CTX *pkctx = NULL; - int i, def_nid; - - if (ctx == NULL) - return 0; - /* - * EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory - * for this algorithm. - */ - if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) == 2 - && def_nid == NID_undef) { - /* The signing algorithm requires there to be no digest */ - md = NULL; - } - if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)) - return 0; - for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { - char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); - if (pkey_ctrl_string(pkctx, sigopt) <= 0) { - BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); - ERR_print_errors(bio_err); - return 0; - } - } - return 1; -} - -int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md, - STACK_OF(OPENSSL_STRING) *sigopts) -{ - int rv; - EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - - rv = do_sign_init(mctx, pkey, md, sigopts); - if (rv > 0) - rv = X509_sign_ctx(x, mctx); - EVP_MD_CTX_free(mctx); - return rv > 0 ? 1 : 0; -} - -int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, - STACK_OF(OPENSSL_STRING) *sigopts) -{ - int rv; - EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - rv = do_sign_init(mctx, pkey, md, sigopts); - if (rv > 0) - rv = X509_REQ_sign_ctx(x, mctx); - EVP_MD_CTX_free(mctx); - return rv > 0 ? 1 : 0; -} - -int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, - STACK_OF(OPENSSL_STRING) *sigopts) -{ - int rv; - EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - rv = do_sign_init(mctx, pkey, md, sigopts); - if (rv > 0) - rv = X509_CRL_sign_ctx(x, mctx); - EVP_MD_CTX_free(mctx); - return rv > 0 ? 1 : 0; -} diff --git a/crypto/openssl/apps/rsa.c b/crypto/openssl/apps/rsa.c index aeda917cc768..0da342c38f2c 100644 --- a/crypto/openssl/apps/rsa.c +++ b/crypto/openssl/apps/rsa.c @@ -1,13 +1,17 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* Necessary for legacy RSA public key export */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include + #include #include #include @@ -21,60 +25,119 @@ #include #include #include +#include + +/* + * This include is to get OSSL_KEYMGMT_SELECT_*, which feels a bit + * much just for those macros... they might serve better as EVP macros. + */ +#include + +#ifndef OPENSSL_NO_RC4 +# define DEFAULT_PVK_ENCR_STRENGTH 2 +#else +# define DEFAULT_PVK_ENCR_STRENGTH 0 +#endif typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, OPT_PUBIN, OPT_PUBOUT, OPT_PASSOUT, OPT_PASSIN, OPT_RSAPUBKEY_IN, OPT_RSAPUBKEY_OUT, /* Do not change the order here; see case statements below */ OPT_PVK_NONE, OPT_PVK_WEAK, OPT_PVK_STRONG, - OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_CHECK, OPT_CIPHER + OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_CHECK, OPT_CIPHER, + OPT_PROV_ENUM, OPT_TRADITIONAL } OPTION_CHOICE; const OPTIONS rsa_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'f', "Input format, one of DER PEM"}, - {"outform", OPT_OUTFORM, 'f', "Output format, one of DER PEM PVK"}, + {"check", OPT_CHECK, '-', "Verify key consistency"}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Input"), {"in", OPT_IN, 's', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, + {"inform", OPT_INFORM, 'f', "Input format (DER/PEM/P12/ENGINE)"}, {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, - {"pubout", OPT_PUBOUT, '-', "Output a public key"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"RSAPublicKey_in", OPT_RSAPUBKEY_IN, '-', "Input is an RSAPublicKey"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'f', "Output format, one of DER PEM PVK"}, + {"pubout", OPT_PUBOUT, '-', "Output a public key"}, {"RSAPublicKey_out", OPT_RSAPUBKEY_OUT, '-', "Output is an RSAPublicKey"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"noout", OPT_NOOUT, '-', "Don't print key out"}, {"text", OPT_TEXT, '-', "Print the key in text"}, {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"}, - {"check", OPT_CHECK, '-', "Verify key consistency"}, - {"", OPT_CIPHER, '-', "Any supported cipher"}, -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) + {"traditional", OPT_TRADITIONAL, '-', + "Use traditional format for private keys"}, + +#ifndef OPENSSL_NO_RC4 + OPT_SECTION("PVK"), {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"}, {"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"}, {"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"}, #endif -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + + OPT_PROV_OPTIONS, {NULL} }; +static int try_legacy_encoding(EVP_PKEY *pkey, int outformat, int pubout, + BIO *out) +{ + int ret = 0; +#ifndef OPENSSL_NO_DEPRECATED_3_0 + const RSA *rsa = EVP_PKEY_get0_RSA(pkey); + + if (rsa == NULL) + return 0; + + if (outformat == FORMAT_ASN1) { + if (pubout == 2) + ret = i2d_RSAPublicKey_bio(out, rsa) > 0; + else + ret = i2d_RSA_PUBKEY_bio(out, rsa) > 0; + } else if (outformat == FORMAT_PEM) { + if (pubout == 2) + ret = PEM_write_bio_RSAPublicKey(out, rsa) > 0; + else + ret = PEM_write_bio_RSA_PUBKEY(out, rsa) > 0; +# ifndef OPENSSL_NO_DSA + } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { + ret = i2b_PublicKey_bio(out, pkey) > 0; +# endif + } +#endif + + return ret; +} + int rsa_main(int argc, char **argv) { ENGINE *e = NULL; BIO *out = NULL; - RSA *rsa = NULL; - const EVP_CIPHER *enc = NULL; - char *infile = NULL, *outfile = NULL, *prog; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pctx; + EVP_CIPHER *enc = NULL; + char *infile = NULL, *outfile = NULL, *ciphername = NULL, *prog; char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL; - int i, private = 0; - int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, check = 0; + int private = 0; + int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, text = 0, check = 0; int noout = 0, modulus = 0, pubin = 0, pubout = 0, ret = 1; -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) - int pvk_encr = 2; -#endif + int pvk_encr = DEFAULT_PVK_ENCR_STRENGTH; OPTION_CHOICE o; + int traditional = 0; + const char *output_type = NULL; + const char *output_structure = NULL; + int selection = 0; + OSSL_ENCODER_CTX *ectx = NULL; prog = opt_init(argc, argv, rsa_options); while ((o = opt_next()) != OPT_EOF) { @@ -126,9 +189,7 @@ int rsa_main(int argc, char **argv) case OPT_PVK_STRONG: /* pvk_encr:= 2 */ case OPT_PVK_WEAK: /* pvk_encr:= 1 */ case OPT_PVK_NONE: /* pvk_encr:= 0 */ -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) pvk_encr = (o - OPT_PVK_NONE); -#endif break; case OPT_NOOUT: noout = 1; @@ -143,15 +204,27 @@ int rsa_main(int argc, char **argv) check = 1; break; case OPT_CIPHER: - if (!opt_cipher(opt_unknown(), &enc)) - goto opthelp; + ciphername = opt_unknown(); + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; + case OPT_TRADITIONAL: + traditional = 1; break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; + if (ciphername != NULL) { + if (!opt_cipher(ciphername, &enc)) + goto opthelp; + } private = (text && !pubin) || (!pubout && !noout) ? 1 : 0; if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { @@ -163,34 +236,31 @@ int rsa_main(int argc, char **argv) goto end; } - { - EVP_PKEY *pkey; + if (pubin) { + int tmpformat = FORMAT_UNDEF; - if (pubin) { - int tmpformat = -1; - if (pubin == 2) { - if (informat == FORMAT_PEM) - tmpformat = FORMAT_PEMRSA; - else if (informat == FORMAT_ASN1) - tmpformat = FORMAT_ASN1RSA; - } else { - tmpformat = informat; - } - - pkey = load_pubkey(infile, tmpformat, 1, passin, e, "Public Key"); + if (pubin == 2) { + if (informat == FORMAT_PEM) + tmpformat = FORMAT_PEMRSA; + else if (informat == FORMAT_ASN1) + tmpformat = FORMAT_ASN1RSA; } else { - pkey = load_key(infile, informat, 1, passin, e, "Private Key"); + tmpformat = informat; } - if (pkey != NULL) - rsa = EVP_PKEY_get1_RSA(pkey); - EVP_PKEY_free(pkey); + pkey = load_pubkey(infile, tmpformat, 1, passin, e, "public key"); + } else { + pkey = load_key(infile, informat, 1, passin, e, "private key"); } - if (rsa == NULL) { + if (pkey == NULL) { ERR_print_errors(bio_err); goto end; } + if (!EVP_PKEY_is_a(pkey, "RSA") && !EVP_PKEY_is_a(pkey, "RSA-PSS")) { + BIO_printf(bio_err, "Not an RSA key\n"); + goto end; + } out = bio_open_owner(outfile, outformat, private); if (out == NULL) @@ -198,7 +268,8 @@ int rsa_main(int argc, char **argv) if (text) { assert(pubin || private); - if (!RSA_print(out, rsa, 0)) { + if ((pubin && EVP_PKEY_print_public(out, pkey, 0, NULL) <= 0) + || (!pubin && EVP_PKEY_print_private(out, pkey, 0, NULL) <= 0)) { perror(outfile); ERR_print_errors(bio_err); goto end; @@ -206,30 +277,34 @@ int rsa_main(int argc, char **argv) } if (modulus) { - const BIGNUM *n; - RSA_get0_key(rsa, &n, NULL, NULL); + BIGNUM *n = NULL; + + /* Every RSA key has an 'n' */ + EVP_PKEY_get_bn_param(pkey, "n", &n); BIO_printf(out, "Modulus="); BN_print(out, n); BIO_printf(out, "\n"); + BN_free(n); } if (check) { - int r = RSA_check_key_ex(rsa, NULL); + int r; + + pctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); + if (pctx == NULL) { + BIO_printf(bio_err, "RSA unable to create PKEY context\n"); + ERR_print_errors(bio_err); + goto end; + } + r = EVP_PKEY_check(pctx); + EVP_PKEY_CTX_free(pctx); if (r == 1) { BIO_printf(out, "RSA key ok\n"); } else if (r == 0) { - unsigned long err; - - while ((err = ERR_peek_error()) != 0 && - ERR_GET_LIB(err) == ERR_LIB_RSA && - ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY_EX && - ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) { - BIO_printf(out, "RSA key error: %s\n", - ERR_reason_error_string(err)); - ERR_get_error(); /* remove err from error stack */ - } - } else if (r == -1) { + BIO_printf(bio_err, "RSA key not ok\n"); + ERR_print_errors(bio_err); + } else if (r < 0) { ERR_print_errors(bio_err); goto end; } @@ -240,71 +315,100 @@ int rsa_main(int argc, char **argv) goto end; } BIO_printf(bio_err, "writing RSA key\n"); + + /* Choose output type for the format */ if (outformat == FORMAT_ASN1) { - if (pubout || pubin) { - if (pubout == 2) - i = i2d_RSAPublicKey_bio(out, rsa); - else - i = i2d_RSA_PUBKEY_bio(out, rsa); - } else { - assert(private); - i = i2d_RSAPrivateKey_bio(out, rsa); - } + output_type = "DER"; } else if (outformat == FORMAT_PEM) { + output_type = "PEM"; + } else if (outformat == FORMAT_MSBLOB) { + output_type = "MSBLOB"; + } else if (outformat == FORMAT_PVK) { + if (pubin) { + BIO_printf(bio_err, "PVK form impossible with public key input\n"); + goto end; + } + output_type = "PVK"; + } else { + BIO_printf(bio_err, "bad output format specified for outfile\n"); + goto end; + } + + /* Select what you want in the output */ + if (pubout || pubin) { + selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + } else { + assert(private); + selection = (OSSL_KEYMGMT_SELECT_KEYPAIR + | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS); + } + + /* For DER based output, select the desired output structure */ + if (outformat == FORMAT_ASN1 || outformat == FORMAT_PEM) { if (pubout || pubin) { if (pubout == 2) - i = PEM_write_bio_RSAPublicKey(out, rsa); + output_structure = "pkcs1"; /* "type-specific" would work too */ else - i = PEM_write_bio_RSA_PUBKEY(out, rsa); + output_structure = "SubjectPublicKeyInfo"; } else { assert(private); - i = PEM_write_bio_RSAPrivateKey(out, rsa, - enc, NULL, 0, NULL, passout); + if (traditional) + output_structure = "pkcs1"; /* "type-specific" would work too */ + else + output_structure = "PrivateKeyInfo"; } -#ifndef OPENSSL_NO_DSA - } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { - EVP_PKEY *pk; - pk = EVP_PKEY_new(); - if (pk == NULL) - goto end; + } - EVP_PKEY_set1_RSA(pk, rsa); - if (outformat == FORMAT_PVK) { - if (pubin) { - BIO_printf(bio_err, "PVK form impossible with public key input\n"); - EVP_PKEY_free(pk); - goto end; - } - assert(private); -# ifdef OPENSSL_NO_RC4 - BIO_printf(bio_err, "PVK format not supported\n"); - EVP_PKEY_free(pk); + /* Now, perform the encoding */ + ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, + output_type, output_structure, + NULL); + if (OSSL_ENCODER_CTX_get_num_encoders(ectx) == 0) { + if ((!pubout && !pubin) + || !try_legacy_encoding(pkey, outformat, pubout, out)) + BIO_printf(bio_err, "%s format not supported\n", output_type); + else + ret = 0; + goto end; + } + + /* Passphrase setup */ + if (enc != NULL) + OSSL_ENCODER_CTX_set_cipher(ectx, EVP_CIPHER_get0_name(enc), NULL); + + /* Default passphrase prompter */ + if (enc != NULL || outformat == FORMAT_PVK) { + OSSL_ENCODER_CTX_set_passphrase_ui(ectx, get_ui_method(), NULL); + if (passout != NULL) + /* When passout given, override the passphrase prompter */ + OSSL_ENCODER_CTX_set_passphrase(ectx, + (const unsigned char *)passout, + strlen(passout)); + } + + /* PVK is a bit special... */ + if (outformat == FORMAT_PVK) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_int("encrypt-level", &pvk_encr); + if (!OSSL_ENCODER_CTX_set_params(ectx, params)) { + BIO_printf(bio_err, "invalid PVK encryption level\n"); goto end; -# else - i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); -# endif - } else if (pubin || pubout) { - i = i2b_PublicKey_bio(out, pk); - } else { - assert(private); - i = i2b_PrivateKey_bio(out, pk); } - EVP_PKEY_free(pk); -#endif - } else { - BIO_printf(bio_err, "bad output format specified for outfile\n"); - goto end; } - if (i <= 0) { + + if (!OSSL_ENCODER_to_bio(ectx, out)) { BIO_printf(bio_err, "unable to write key\n"); ERR_print_errors(bio_err); - } else { - ret = 0; + goto end; } + ret = 0; end: + OSSL_ENCODER_CTX_free(ectx); release_engine(e); BIO_free_all(out); - RSA_free(rsa); + EVP_PKEY_free(pkey); + EVP_CIPHER_free(enc); OPENSSL_free(passin); OPENSSL_free(passout); return ret; diff --git a/crypto/openssl/apps/rsautl.c b/crypto/openssl/apps/rsautl.c index 0c0fa8eba30a..df29069bc1f4 100644 --- a/crypto/openssl/apps/rsautl.c +++ b/crypto/openssl/apps/rsautl.c @@ -1,13 +1,14 @@ /* - * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include + #include "apps.h" #include "progs.h" #include @@ -25,40 +26,46 @@ #define KEY_CERT 3 typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_ENGINE, OPT_IN, OPT_OUT, OPT_ASN1PARSE, OPT_HEXDUMP, - OPT_RAW, OPT_OAEP, OPT_SSL, OPT_PKCS, OPT_X931, + OPT_RSA_RAW, OPT_OAEP, OPT_PKCS, OPT_X931, OPT_SIGN, OPT_VERIFY, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT, OPT_PUBIN, OPT_CERTIN, OPT_INKEY, OPT_PASSIN, OPT_KEYFORM, - OPT_R_ENUM + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS rsautl_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"sign", OPT_SIGN, '-', "Sign with private key"}, + {"verify", OPT_VERIFY, '-', "Verify with public key"}, + {"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"}, + {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, {"inkey", OPT_INKEY, 's', "Input key"}, - {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"}, + {"keyform", OPT_KEYFORM, 'E', "Private key format (ENGINE, other values ignored)"}, {"pubin", OPT_PUBIN, '-', "Input is an RSA public"}, {"certin", OPT_CERTIN, '-', "Input is a cert carrying an RSA public key"}, - {"ssl", OPT_SSL, '-', "Use SSL v2 padding"}, - {"raw", OPT_RAW, '-', "Use no padding"}, + {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"raw", OPT_RSA_RAW, '-', "Use no padding"}, {"pkcs", OPT_PKCS, '-', "Use PKCS#1 v1.5 padding (default)"}, + {"x931", OPT_X931, '-', "Use ANSI X9.31 padding"}, {"oaep", OPT_OAEP, '-', "Use PKCS#1 OAEP"}, - {"sign", OPT_SIGN, '-', "Sign with private key"}, - {"verify", OPT_VERIFY, '-', "Verify with public key"}, {"asn1parse", OPT_ASN1PARSE, '-', "Run output through asn1parse; useful with -verify"}, {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, - {"x931", OPT_X931, '-', "Use ANSI X9.31 padding"}, - {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, - {"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"}, - {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + OPT_R_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + OPT_PROV_OPTIONS, {NULL} }; @@ -67,14 +74,15 @@ int rsautl_main(int argc, char **argv) BIO *in = NULL, *out = NULL; ENGINE *e = NULL; EVP_PKEY *pkey = NULL; - RSA *rsa = NULL; + EVP_PKEY_CTX *ctx = NULL; X509 *x; char *infile = NULL, *outfile = NULL, *keyfile = NULL; char *passinarg = NULL, *passin = NULL, *prog; char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; unsigned char *rsa_in = NULL, *rsa_out = NULL, pad = RSA_PKCS1_PADDING; - int rsa_inlen, keyformat = FORMAT_PEM, keysize, ret = 1; - int rsa_outlen = 0, hexdump = 0, asn1parse = 0, need_priv = 0, rev = 0; + size_t rsa_inlen, rsa_outlen = 0; + int keyformat = FORMAT_UNDEF, keysize, ret = 1, rv; + int hexdump = 0, asn1parse = 0, need_priv = 0, rev = 0; OPTION_CHOICE o; prog = opt_init(argc, argv, rsautl_options); @@ -90,7 +98,7 @@ int rsautl_main(int argc, char **argv) ret = 0; goto end; case OPT_KEYFORM: - if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyformat)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat)) goto opthelp; break; case OPT_IN: @@ -108,15 +116,12 @@ int rsautl_main(int argc, char **argv) case OPT_HEXDUMP: hexdump = 1; break; - case OPT_RAW: + case OPT_RSA_RAW: pad = RSA_NO_PADDING; break; case OPT_OAEP: pad = RSA_PKCS1_OAEP_PADDING; break; - case OPT_SSL: - pad = RSA_SSLV23_PADDING; - break; case OPT_PKCS: pad = RSA_PKCS1_PADDING; break; @@ -156,12 +161,21 @@ int rsautl_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; + if (!app_RAND_load()) + goto end; + if (need_priv && (key_type != KEY_PRIVKEY)) { BIO_printf(bio_err, "A private key is needed for this operation\n"); goto end; @@ -174,15 +188,15 @@ int rsautl_main(int argc, char **argv) switch (key_type) { case KEY_PRIVKEY: - pkey = load_key(keyfile, keyformat, 0, passin, e, "Private Key"); + pkey = load_key(keyfile, keyformat, 0, passin, e, "private key"); break; case KEY_PUBKEY: - pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "Public Key"); + pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "public key"); break; case KEY_CERT: - x = load_cert(keyfile, keyformat, "Certificate"); + x = load_cert(keyfile, FORMAT_UNDEF, "Certificate"); if (x) { pkey = X509_get_pubkey(x); X509_free(x); @@ -193,15 +207,6 @@ int rsautl_main(int argc, char **argv) if (pkey == NULL) return 1; - rsa = EVP_PKEY_get1_RSA(pkey); - EVP_PKEY_free(pkey); - - if (rsa == NULL) { - BIO_printf(bio_err, "Error getting RSA key\n"); - ERR_print_errors(bio_err); - goto end; - } - in = bio_open_default(infile, 'r', FORMAT_BINARY); if (in == NULL) goto end; @@ -209,48 +214,58 @@ int rsautl_main(int argc, char **argv) if (out == NULL) goto end; - keysize = RSA_size(rsa); + keysize = EVP_PKEY_get_size(pkey); rsa_in = app_malloc(keysize * 2, "hold rsa key"); rsa_out = app_malloc(keysize, "output rsa key"); + rsa_outlen = keysize; /* Read the input data */ - rsa_inlen = BIO_read(in, rsa_in, keysize * 2); - if (rsa_inlen < 0) { + rv = BIO_read(in, rsa_in, keysize * 2); + if (rv < 0) { BIO_printf(bio_err, "Error reading input Data\n"); goto end; } + rsa_inlen = rv; if (rev) { - int i; + size_t i; unsigned char ctmp; + for (i = 0; i < rsa_inlen / 2; i++) { ctmp = rsa_in[i]; rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; rsa_in[rsa_inlen - 1 - i] = ctmp; } } - switch (rsa_mode) { + if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL) + goto end; + + switch (rsa_mode) { case RSA_VERIFY: - rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + rv = EVP_PKEY_verify_recover_init(ctx) > 0 + && EVP_PKEY_CTX_set_rsa_padding(ctx, pad) > 0 + && EVP_PKEY_verify_recover(ctx, rsa_out, &rsa_outlen, + rsa_in, rsa_inlen) > 0; break; - case RSA_SIGN: - rsa_outlen = - RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + rv = EVP_PKEY_sign_init(ctx) > 0 + && EVP_PKEY_CTX_set_rsa_padding(ctx, pad) > 0 + && EVP_PKEY_sign(ctx, rsa_out, &rsa_outlen, rsa_in, rsa_inlen) > 0; break; - case RSA_ENCRYPT: - rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + rv = EVP_PKEY_encrypt_init(ctx) > 0 + && EVP_PKEY_CTX_set_rsa_padding(ctx, pad) > 0 + && EVP_PKEY_encrypt(ctx, rsa_out, &rsa_outlen, rsa_in, rsa_inlen) > 0; break; - case RSA_DECRYPT: - rsa_outlen = - RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + rv = EVP_PKEY_decrypt_init(ctx) > 0 + && EVP_PKEY_CTX_set_rsa_padding(ctx, pad) > 0 + && EVP_PKEY_decrypt(ctx, rsa_out, &rsa_outlen, rsa_in, rsa_inlen) > 0; break; } - if (rsa_outlen < 0) { + if (!rv) { BIO_printf(bio_err, "RSA operation error\n"); ERR_print_errors(bio_err); goto end; @@ -266,7 +281,8 @@ int rsautl_main(int argc, char **argv) BIO_write(out, rsa_out, rsa_outlen); } end: - RSA_free(rsa); + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); release_engine(e); BIO_free(in); BIO_free_all(out); diff --git a/crypto/openssl/apps/s_client.c b/crypto/openssl/apps/s_client.c index 5664e7e04ec6..a9142386428d 100644 --- a/crypto/openssl/apps/s_client.c +++ b/crypto/openssl/apps/s_client.c @@ -1,8 +1,8 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2005 Nokia. All rights reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -38,10 +38,8 @@ typedef unsigned int u_int; #include #include #include +#include #include -#ifndef OPENSSL_NO_SRP -# include -#endif #ifndef OPENSSL_NO_CT # include #endif @@ -91,27 +89,6 @@ static int restore_errno(void) return ret; } -static void do_ssl_shutdown(SSL *ssl) -{ - int ret; - - do { - /* We only do unidirectional shutdown */ - ret = SSL_shutdown(ssl); - if (ret < 0) { - switch (SSL_get_error(ssl, ret)) { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_ASYNC: - case SSL_ERROR_WANT_ASYNC_JOB: - /* We just do busy waiting. Nothing clever */ - continue; - } - ret = 0; - } - } while (ret < 0); -} - /* Default PSK identity and key */ static char *psk_identity = "Client_identity"; @@ -258,117 +235,6 @@ static int ssl_servername_cb(SSL *s, int *ad, void *arg) return SSL_TLSEXT_ERR_OK; } -#ifndef OPENSSL_NO_SRP - -/* This is a context that we pass to all callbacks */ -typedef struct srp_arg_st { - char *srppassin; - char *srplogin; - int msg; /* copy from c_msg */ - int debug; /* copy from c_debug */ - int amp; /* allow more groups */ - int strength; /* minimal size for N */ -} SRP_ARG; - -# define SRP_NUMBER_ITERATIONS_FOR_PRIME 64 - -static int srp_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g) -{ - BN_CTX *bn_ctx = BN_CTX_new(); - BIGNUM *p = BN_new(); - BIGNUM *r = BN_new(); - int ret = - g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) && - BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) == 1 && - p != NULL && BN_rshift1(p, N) && - /* p = (N-1)/2 */ - BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) == 1 && - r != NULL && - /* verify g^((N-1)/2) == -1 (mod N) */ - BN_mod_exp(r, g, p, N, bn_ctx) && - BN_add_word(r, 1) && BN_cmp(r, N) == 0; - - BN_free(r); - BN_free(p); - BN_CTX_free(bn_ctx); - return ret; -} - -/*- - * This callback is used here for two purposes: - * - extended debugging - * - making some primality tests for unknown groups - * The callback is only called for a non default group. - * - * An application does not need the call back at all if - * only the standard groups are used. In real life situations, - * client and server already share well known groups, - * thus there is no need to verify them. - * Furthermore, in case that a server actually proposes a group that - * is not one of those defined in RFC 5054, it is more appropriate - * to add the group to a static list and then compare since - * primality tests are rather cpu consuming. - */ - -static int ssl_srp_verify_param_cb(SSL *s, void *arg) -{ - SRP_ARG *srp_arg = (SRP_ARG *)arg; - BIGNUM *N = NULL, *g = NULL; - - if (((N = SSL_get_srp_N(s)) == NULL) || ((g = SSL_get_srp_g(s)) == NULL)) - return 0; - if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) { - BIO_printf(bio_err, "SRP parameters:\n"); - BIO_printf(bio_err, "\tN="); - BN_print(bio_err, N); - BIO_printf(bio_err, "\n\tg="); - BN_print(bio_err, g); - BIO_printf(bio_err, "\n"); - } - - if (SRP_check_known_gN_param(g, N)) - return 1; - - if (srp_arg->amp == 1) { - if (srp_arg->debug) - BIO_printf(bio_err, - "SRP param N and g are not known params, going to check deeper.\n"); - - /* - * The srp_moregroups is a real debugging feature. Implementors - * should rather add the value to the known ones. The minimal size - * has already been tested. - */ - if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g)) - return 1; - } - BIO_printf(bio_err, "SRP param N and g rejected.\n"); - return 0; -} - -# define PWD_STRLEN 1024 - -static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg) -{ - SRP_ARG *srp_arg = (SRP_ARG *)arg; - char *pass = app_malloc(PWD_STRLEN + 1, "SRP password buffer"); - PW_CB_DATA cb_tmp; - int l; - - cb_tmp.password = (char *)srp_arg->srppassin; - cb_tmp.prompt_info = "SRP user"; - if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp)) < 0) { - BIO_printf(bio_err, "Can't read Password\n"); - OPENSSL_free(pass); - return NULL; - } - *(pass + l) = '\0'; - - return pass; -} - -#endif - #ifndef OPENSSL_NO_NEXTPROTONEG /* This the context that we pass to next_proto_cb */ typedef struct tlsextnextprotoctx_st { @@ -563,7 +429,7 @@ static int tlsa_import_rrset(SSL *con, STACK_OF(OPENSSL_STRING) *rrset) } typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_4, OPT_6, OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_BIND, OPT_UNIX, OPT_XMPPHOST, OPT_VERIFY, OPT_NAMEOPT, OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN, @@ -581,35 +447,56 @@ typedef enum OPTION_choice { OPT_SSL3, OPT_SSL_CONFIG, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS, - OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, - OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, - OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_NEXTPROTONEG, OPT_ALPN, + OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, + OPT_NEXTPROTONEG, OPT_ALPN, + OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, + OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, OPT_VERIFYCAFILE, + OPT_CASTORE, OPT_NOCASTORE, OPT_CHAINCASTORE, OPT_VERIFYCASTORE, OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME, OPT_NOSERVERNAME, OPT_ASYNC, OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_PROTOHOST, OPT_MAXFRAGLEN, OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF, OPT_KEYLOG_FILE, OPT_EARLY_DATA, OPT_REQCAFILE, OPT_V_ENUM, OPT_X_ENUM, - OPT_S_ENUM, - OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY, OPT_DANE_TLSA_DOMAIN, + OPT_S_ENUM, OPT_IGNORE_UNEXPECTED_EOF, + OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY, OPT_PROXY_USER, OPT_PROXY_PASS, + OPT_DANE_TLSA_DOMAIN, #ifndef OPENSSL_NO_CT OPT_CT, OPT_NOCT, OPT_CTLOG_FILE, #endif OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME, OPT_ENABLE_PHA, OPT_SCTP_LABEL_BUG, - OPT_R_ENUM + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS s_client_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [host:port]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, + {"ssl_client_engine", OPT_SSL_CLIENT_ENGINE, 's', + "Specify engine to be used for client certificate operations"}, +#endif + {"ssl_config", OPT_SSL_CONFIG, 's', "Use specified section for SSL_CTX configuration"}, +#ifndef OPENSSL_NO_CT + {"ct", OPT_CT, '-', "Request and parse SCTs (also enables OCSP stapling)"}, + {"noct", OPT_NOCT, '-', "Do not request or parse SCTs (default)"}, + {"ctlogfile", OPT_CTLOG_FILE, '<', "CT log list CONF file"}, +#endif + + OPT_SECTION("Network"), {"host", OPT_HOST, 's', "Use -connect instead"}, {"port", OPT_PORT, 'p', "Use -connect instead"}, {"connect", OPT_CONNECT, 's', - "TCP/IP where to connect (default is :" PORT ")"}, + "TCP/IP where to connect; default: " PORT ")"}, {"bind", OPT_BIND, 's', "bind local address for connection"}, {"proxy", OPT_PROXY, 's', "Connect to via specified proxy to the real server"}, + {"proxy_user", OPT_PROXY_USER, 's', "UserID for proxy authentication"}, + {"proxy_pass", OPT_PROXY_PASS, 's', "Proxy authentication password source"}, #ifdef AF_UNIX {"unix", OPT_UNIX, 's', "Connect over the specified Unix-domain socket"}, #endif @@ -617,20 +504,38 @@ const OPTIONS s_client_options[] = { #ifdef AF_INET6 {"6", OPT_6, '-', "Use IPv6 only"}, #endif - {"verify", OPT_VERIFY, 'p', "Turn on peer certificate verification"}, - {"cert", OPT_CERT, '<', "Certificate file to use, PEM format assumed"}, + {"maxfraglen", OPT_MAXFRAGLEN, 'p', + "Enable Maximum Fragment Length Negotiation (len values: 512, 1024, 2048 and 4096)"}, + {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, + {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', + "Size used to split data for encrypt pipelines"}, + {"max_pipelines", OPT_MAX_PIPELINES, 'p', + "Maximum number of encrypt/decrypt pipelines to be used"}, + {"read_buf", OPT_READ_BUF, 'p', + "Default read buffer size to be used for connections"}, + {"fallback_scsv", OPT_FALLBACKSCSV, '-', "Send the fallback SCSV"}, + + OPT_SECTION("Identity"), + {"cert", OPT_CERT, '<', "Client certificate file to use"}, {"certform", OPT_CERTFORM, 'F', - "Certificate format (PEM or DER) PEM default"}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, - {"key", OPT_KEY, 's', "Private key file to use, if not in -cert file"}, - {"keyform", OPT_KEYFORM, 'E', "Key format (PEM, DER or engine) PEM default"}, - {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, + "Client certificate file format (PEM/DER/P12); has no effect"}, + {"cert_chain", OPT_CERT_CHAIN, '<', + "Client certificate chain file (in PEM format)"}, + {"build_chain", OPT_BUILD_CHAIN, '-', "Build client certificate chain"}, + {"key", OPT_KEY, 's', "Private key file to use; default: -cert file"}, + {"keyform", OPT_KEYFORM, 'E', "Key format (ENGINE, other values ignored)"}, + {"pass", OPT_PASS, 's', "Private key and cert file pass phrase source"}, + {"verify", OPT_VERIFY, 'p', "Turn on peer certificate verification"}, + {"nameopt", OPT_NAMEOPT, 's', "Certificate subject/issuer name printing options"}, {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store"}, {"requestCAfile", OPT_REQCAFILE, '<', "PEM format file of CA names to send to the server"}, {"dane_tlsa_domain", OPT_DANE_TLSA_DOMAIN, 's', "DANE TLSA base domain"}, @@ -638,16 +543,19 @@ const OPTIONS s_client_options[] = { "DANE TLSA rrdata presentation form"}, {"dane_ee_no_namechecks", OPT_DANE_EE_NO_NAME, '-', "Disable name checks when matching DANE-EE(3) TLSA records"}, + {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity"}, + {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, + {"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"}, + {"name", OPT_PROTOHOST, 's', + "Hostname to use for \"-starttls lmtp\", \"-starttls smtp\" or \"-starttls xmpp[-server]\""}, + + OPT_SECTION("Session"), {"reconnect", OPT_RECONNECT, '-', "Drop and re-make the connection with the same Session-ID"}, - {"showcerts", OPT_SHOWCERTS, '-', - "Show all certificates sent by the server"}, - {"debug", OPT_DEBUG, '-', "Extra output"}, - {"msg", OPT_MSG, '-', "Show protocol messages"}, - {"msgfile", OPT_MSGFILE, '>', - "File to send output of -msg or -trace, instead of stdout"}, - {"nbio_test", OPT_NBIO_TEST, '-', "More ssl protocol testing"}, - {"state", OPT_STATE, '-', "Print the ssl states"}, + {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"}, + {"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"}, + + OPT_SECTION("Input/Output"), {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, {"quiet", OPT_QUIET, '-', "No s_client output"}, {"ign_eof", OPT_IGN_EOF, '-', "Ignore input eof (default when -quiet)"}, @@ -656,47 +564,35 @@ const OPTIONS s_client_options[] = { "Use the appropriate STARTTLS command before starting TLS"}, {"xmpphost", OPT_XMPPHOST, 's', "Alias of -name option for \"-starttls xmpp[-server]\""}, - OPT_R_OPTIONS, - {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"}, - {"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"}, -#ifndef OPENSSL_NO_SRTP - {"use_srtp", OPT_USE_SRTP, 's', - "Offer SRTP key management with a colon-separated profile list"}, -#endif - {"keymatexport", OPT_KEYMATEXPORT, 's', - "Export keying material using label"}, - {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', - "Export len bytes of keying material (default 20)"}, - {"maxfraglen", OPT_MAXFRAGLEN, 'p', - "Enable Maximum Fragment Length Negotiation (len values: 512, 1024, 2048 and 4096)"}, - {"fallback_scsv", OPT_FALLBACKSCSV, '-', "Send the fallback SCSV"}, - {"name", OPT_PROTOHOST, 's', - "Hostname to use for \"-starttls lmtp\", \"-starttls smtp\" or \"-starttls xmpp[-server]\""}, - {"CRL", OPT_CRL, '<', "CRL file to use"}, - {"crl_download", OPT_CRL_DOWNLOAD, '-', "Download CRL from distribution points"}, - {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"}, - {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', - "Close connection on verification error"}, - {"verify_quiet", OPT_VERIFY_QUIET, '-', "Restrict verify output to errors"}, {"brief", OPT_BRIEF, '-', "Restrict output to brief summary of connection parameters"}, {"prexit", OPT_PREXIT, '-', "Print session information when the program exits"}, + + OPT_SECTION("Debug"), + {"showcerts", OPT_SHOWCERTS, '-', + "Show all certificates sent by the server"}, + {"debug", OPT_DEBUG, '-', "Extra output"}, + {"msg", OPT_MSG, '-', "Show protocol messages"}, + {"msgfile", OPT_MSGFILE, '>', + "File to send output of -msg or -trace, instead of stdout"}, + {"nbio_test", OPT_NBIO_TEST, '-', "More ssl protocol testing"}, + {"state", OPT_STATE, '-', "Print the ssl states"}, + {"keymatexport", OPT_KEYMATEXPORT, 's', + "Export keying material using label"}, + {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', + "Export len bytes of keying material; default 20"}, {"security_debug", OPT_SECURITY_DEBUG, '-', "Enable security debug messages"}, {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-', "Output more security debug output"}, - {"cert_chain", OPT_CERT_CHAIN, '<', - "Certificate chain file (in PEM format)"}, - {"chainCApath", OPT_CHAINCAPATH, '/', - "Use dir as certificate store path to build CA certificate chain"}, - {"verifyCApath", OPT_VERIFYCAPATH, '/', - "Use dir as certificate store path to verify CA certificate"}, - {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"}, - {"chainCAfile", OPT_CHAINCAFILE, '<', - "CA file for certificate chain (PEM format)"}, - {"verifyCAfile", OPT_VERIFYCAFILE, '<', - "CA file for certificate verification (PEM format)"}, +#ifndef OPENSSL_NO_SSL_TRACE + {"trace", OPT_TRACE, '-', "Show trace output of protocol messages"}, +#endif +#ifdef WATT32 + {"wdebug", OPT_WDEBUG, '-', "WATT-32 tcp debugging"}, +#endif + {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, {"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"}, {"servername", OPT_SERVERNAME, 's', "Set TLS extension servername (SNI) in ClientHello (default)"}, @@ -704,6 +600,8 @@ const OPTIONS s_client_options[] = { "Do not send the server name (SNI) extension in the ClientHello"}, {"tlsextdebug", OPT_TLSEXTDEBUG, '-', "Hex dump of all TLS extensions received"}, + {"ignore_unexpected_eof", OPT_IGNORE_UNEXPECTED_EOF, '-', + "Do not treat lack of close_notify from a peer as an error"}, #ifndef OPENSSL_NO_OCSP {"status", OPT_STATUS, '-', "Request certificate status from server"}, #endif @@ -712,17 +610,9 @@ const OPTIONS s_client_options[] = { {"alpn", OPT_ALPN, 's', "Enable ALPN extension, considering named protocols supported (comma-separated list)"}, {"async", OPT_ASYNC, '-', "Support asynchronous operation"}, - {"ssl_config", OPT_SSL_CONFIG, 's', "Use specified configuration file"}, - {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, - {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', - "Size used to split data for encrypt pipelines"}, - {"max_pipelines", OPT_MAX_PIPELINES, 'p', - "Maximum number of encrypt/decrypt pipelines to be used"}, - {"read_buf", OPT_READ_BUF, 'p', - "Default read buffer size to be used for connections"}, - OPT_S_OPTIONS, - OPT_V_OPTIONS, - OPT_X_OPTIONS, + {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, + + OPT_SECTION("Protocol and version"), #ifndef OPENSSL_NO_SSL3 {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, #endif @@ -754,43 +644,54 @@ const OPTIONS s_client_options[] = { {"sctp", OPT_SCTP, '-', "Use SCTP"}, {"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"}, #endif -#ifndef OPENSSL_NO_SSL_TRACE - {"trace", OPT_TRACE, '-', "Show trace output of protocol messages"}, -#endif -#ifdef WATT32 - {"wdebug", OPT_WDEBUG, '-', "WATT-32 tcp debugging"}, -#endif - {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, - {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity"}, - {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, - {"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"}, -#ifndef OPENSSL_NO_SRP - {"srpuser", OPT_SRPUSER, 's', "SRP authentication for 'user'"}, - {"srppass", OPT_SRPPASS, 's', "Password for 'user'"}, - {"srp_lateuser", OPT_SRP_LATEUSER, '-', - "SRP username into second ClientHello message"}, - {"srp_moregroups", OPT_SRP_MOREGROUPS, '-', - "Tolerate other than the known g N values."}, - {"srp_strength", OPT_SRP_STRENGTH, 'p', "Minimal length in bits for N"}, -#endif #ifndef OPENSSL_NO_NEXTPROTONEG {"nextprotoneg", OPT_NEXTPROTONEG, 's', "Enable NPN extension, considering named protocols supported (comma-separated list)"}, #endif -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, - {"ssl_client_engine", OPT_SSL_CLIENT_ENGINE, 's', - "Specify engine to be used for client certificate operations"}, -#endif -#ifndef OPENSSL_NO_CT - {"ct", OPT_CT, '-', "Request and parse SCTs (also enables OCSP stapling)"}, - {"noct", OPT_NOCT, '-', "Do not request or parse SCTs (default)"}, - {"ctlogfile", OPT_CTLOG_FILE, '<', "CT log list CONF file"}, -#endif - {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, {"early_data", OPT_EARLY_DATA, '<', "File to send as early data"}, {"enable_pha", OPT_ENABLE_PHA, '-', "Enable post-handshake-authentication"}, - {NULL, OPT_EOF, 0x00, NULL} +#ifndef OPENSSL_NO_SRTP + {"use_srtp", OPT_USE_SRTP, 's', + "Offer SRTP key management with a colon-separated profile list"}, +#endif +#ifndef OPENSSL_NO_SRP + {"srpuser", OPT_SRPUSER, 's', "(deprecated) SRP authentication for 'user'"}, + {"srppass", OPT_SRPPASS, 's', "(deprecated) Password for 'user'"}, + {"srp_lateuser", OPT_SRP_LATEUSER, '-', + "(deprecated) SRP username into second ClientHello message"}, + {"srp_moregroups", OPT_SRP_MOREGROUPS, '-', + "(deprecated) Tolerate other than the known g N values."}, + {"srp_strength", OPT_SRP_STRENGTH, 'p', + "(deprecated) Minimal length in bits for N"}, +#endif + + OPT_R_OPTIONS, + OPT_S_OPTIONS, + OPT_V_OPTIONS, + {"CRL", OPT_CRL, '<', "CRL file to use"}, + {"crl_download", OPT_CRL_DOWNLOAD, '-', "Download CRL from distribution points"}, + {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER); default PEM"}, + {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', + "Close connection on verification error"}, + {"verify_quiet", OPT_VERIFY_QUIET, '-', "Restrict verify output to errors"}, + {"chainCAfile", OPT_CHAINCAFILE, '<', + "CA file for certificate chain (PEM format)"}, + {"chainCApath", OPT_CHAINCAPATH, '/', + "Use dir as certificate store path to build CA certificate chain"}, + {"chainCAstore", OPT_CHAINCASTORE, ':', + "CA store URI for certificate chain"}, + {"verifyCAfile", OPT_VERIFYCAFILE, '<', + "CA file for certificate verification (PEM format)"}, + {"verifyCApath", OPT_VERIFYCAPATH, '/', + "Use dir as certificate store path to verify CA certificate"}, + {"verifyCAstore", OPT_VERIFYCASTORE, ':', + "CA store URI for certificate verification"}, + OPT_X_OPTIONS, + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"host:port", 0, 0, "Where to connect; same as -connect option"}, + {NULL} }; typedef enum PROTOCOL_choice { @@ -802,7 +703,6 @@ typedef enum PROTOCOL_choice { PROTO_TELNET, PROTO_XMPP, PROTO_XMPP_SERVER, - PROTO_CONNECT, PROTO_IRC, PROTO_MYSQL, PROTO_POSTGRES, @@ -896,29 +796,33 @@ int s_client_main(int argc, char **argv) int dane_ee_no_name = 0; STACK_OF(X509_CRL) *crls = NULL; const SSL_METHOD *meth = TLS_client_method(); - const char *CApath = NULL, *CAfile = NULL; - char *cbuf = NULL, *sbuf = NULL; - char *mbuf = NULL, *proxystr = NULL, *connectstr = NULL, *bindstr = NULL; + const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL; + char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL; + char *proxystr = NULL, *proxyuser = NULL; + char *proxypassarg = NULL, *proxypass = NULL; + char *connectstr = NULL, *bindstr = NULL; char *cert_file = NULL, *key_file = NULL, *chain_file = NULL; - char *chCApath = NULL, *chCAfile = NULL, *host = NULL; - char *port = OPENSSL_strdup(PORT); + char *chCApath = NULL, *chCAfile = NULL, *chCAstore = NULL, *host = NULL; + char *thost = NULL, *tport = NULL; + char *port = NULL; char *bindhost = NULL, *bindport = NULL; - char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; + char *passarg = NULL, *pass = NULL; + char *vfyCApath = NULL, *vfyCAfile = NULL, *vfyCAstore = NULL; char *ReqCAfile = NULL; char *sess_in = NULL, *crl_file = NULL, *p; const char *protohost = NULL; struct timeval timeout, *timeoutp; fd_set readfds, writefds; - int noCApath = 0, noCAfile = 0; - int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_PEM; - int key_format = FORMAT_PEM, crlf = 0, full_log = 1, mbuf_len = 0; + int noCApath = 0, noCAfile = 0, noCAstore = 0; + int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_UNDEF; + int key_format = FORMAT_UNDEF, crlf = 0, full_log = 1, mbuf_len = 0; int prexit = 0; int sdebug = 0; int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0; - int ret = 1, in_init = 1, i, nbio_test = 0, s = -1, k, width, state = 0; + int ret = 1, in_init = 1, i, nbio_test = 0, sock = -1, k, width, state = 0; int sbuf_len, sbuf_off, cmdletters = 1; int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0; - int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0; + int starttls_proto = PROTO_OFF, crl_format = FORMAT_UNDEF, crl_download = 0; int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending; #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) int at_eof = 0; @@ -983,6 +887,7 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_SCTP int sctp_label_bug = 0; #endif + int ignore_unexpected_eof = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); @@ -994,16 +899,16 @@ int s_client_main(int argc, char **argv) # endif #endif - prog = opt_progname(argv[0]); c_quiet = 0; c_debug = 0; c_showcerts = 0; c_nbio = 0; + port = OPENSSL_strdup(PORT); vpm = X509_VERIFY_PARAM_new(); cctx = SSL_CONF_CTX_new(); - if (vpm == NULL || cctx == NULL) { - BIO_printf(bio_err, "%s: out of memory\n", prog); + if (port == NULL || vpm == NULL || cctx == NULL) { + BIO_printf(bio_err, "%s: out of memory\n", opt_getprog()); goto end; } @@ -1080,7 +985,12 @@ int s_client_main(int argc, char **argv) break; case OPT_PROXY: proxystr = opt_arg(); - starttls_proto = PROTO_CONNECT; + break; + case OPT_PROXY_USER: + proxyuser = opt_arg(); + break; + case OPT_PROXY_PASS: + proxypassarg = opt_arg(); break; #ifdef AF_UNIX case OPT_UNIX: @@ -1120,7 +1030,7 @@ int s_client_main(int argc, char **argv) sess_in = opt_arg(); break; case OPT_CERTFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &cert_format)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &cert_format)) goto opthelp; break; case OPT_CRLFORM: @@ -1156,6 +1066,9 @@ int s_client_main(int argc, char **argv) if (!args_excert(o, &exc)) goto end; break; + case OPT_IGNORE_UNEXPECTED_EOF: + ignore_unexpected_eof = 1; + break; case OPT_PREXIT: prexit = 1; break; @@ -1176,7 +1089,7 @@ int s_client_main(int argc, char **argv) break; case OPT_SSL_CLIENT_ENGINE: #ifndef OPENSSL_NO_ENGINE - ssl_client_engine = ENGINE_by_id(opt_arg()); + ssl_client_engine = setup_engine(opt_arg(), 0); if (ssl_client_engine == NULL) { BIO_printf(bio_err, "Error getting client auth engine\n"); goto opthelp; @@ -1187,6 +1100,10 @@ int s_client_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_IGN_EOF: c_ign_eof = 1; break; @@ -1214,6 +1131,10 @@ int s_client_main(int argc, char **argv) break; case OPT_MSGFILE: bio_c_msg = BIO_new_file(opt_arg(), "w"); + if (bio_c_msg == NULL) { + BIO_printf(bio_err, "Error writing file %s\n", opt_arg()); + goto end; + } break; case OPT_TRACE: #ifndef OPENSSL_NO_SSL_TRACE @@ -1370,7 +1291,7 @@ int s_client_main(int argc, char **argv) fallback_scsv = 1; break; case OPT_KEYFORM: - if (!opt_format(opt_arg(), OPT_FMT_PDE, &key_format)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &key_format)) goto opthelp; break; case OPT_PASS: @@ -1426,6 +1347,18 @@ int s_client_main(int argc, char **argv) case OPT_VERIFYCAFILE: vfyCAfile = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; + case OPT_NOCASTORE: + noCAstore = 1; + break; + case OPT_CHAINCASTORE: + chCAstore = opt_arg(); + break; + case OPT_VERIFYCASTORE: + vfyCAstore = opt_arg(); + break; case OPT_DANE_TLSA_DOMAIN: dane_tlsa_domain = opt_arg(); break; @@ -1530,6 +1463,25 @@ int s_client_main(int argc, char **argv) break; } } + + /* Optional argument is connect string if -connect not used. */ + argc = opt_num_rest(); + if (argc == 1) { + /* Don't allow -connect and a separate argument. */ + if (connectstr != NULL) { + BIO_printf(bio_err, + "%s: cannot provide both -connect option and target parameter\n", + prog); + goto opthelp; + } + connect_type = use_inet; + freeandcopy(&connectstr, *opt_rest()); + } else if (argc != 0) { + goto opthelp; + } + if (!app_RAND_load()) + goto end; + if (count4or6 >= 2) { BIO_printf(bio_err, "%s: Can't use both -4 and -6\n", prog); goto opthelp; @@ -1548,23 +1500,6 @@ int s_client_main(int argc, char **argv) goto opthelp; } } - argc = opt_num_rest(); - if (argc == 1) { - /* If there's a positional argument, it's the equivalent of - * OPT_CONNECT. - * Don't allow -connect and a separate argument. - */ - if (connectstr != NULL) { - BIO_printf(bio_err, - "%s: must not provide both -connect option and target parameter\n", - prog); - goto opthelp; - } - connect_type = use_inet; - freeandcopy(&connectstr, *opt_rest()); - } else if (argc != 0) { - goto opthelp; - } #ifndef OPENSSL_NO_NEXTPROTONEG if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) { @@ -1572,46 +1507,57 @@ int s_client_main(int argc, char **argv) goto opthelp; } #endif - if (proxystr != NULL) { + + if (connectstr != NULL) { int res; char *tmp_host = host, *tmp_port = port; - if (connectstr == NULL) { - BIO_printf(bio_err, "%s: -proxy requires use of -connect or target parameter\n", prog); - goto opthelp; - } - res = BIO_parse_hostserv(proxystr, &host, &port, BIO_PARSE_PRIO_HOST); + + res = BIO_parse_hostserv(connectstr, &host, &port, BIO_PARSE_PRIO_HOST); if (tmp_host != host) OPENSSL_free(tmp_host); if (tmp_port != port) OPENSSL_free(tmp_port); if (!res) { BIO_printf(bio_err, - "%s: -proxy argument malformed or ambiguous\n", prog); + "%s: -connect argument or target parameter malformed or ambiguous\n", + prog); goto end; } + } + + if (proxystr != NULL) { + int res; + char *tmp_host = host, *tmp_port = port; + + if (host == NULL || port == NULL) { + BIO_printf(bio_err, "%s: -proxy requires use of -connect or target parameter\n", prog); + goto opthelp; + } + if (servername == NULL && !noservername) { - res = BIO_parse_hostserv(connectstr, &sname_alloc, NULL, BIO_PARSE_PRIO_HOST); - if (!res) { - BIO_printf(bio_err, - "%s: -connect argument malformed or ambiguous\n", prog); + servername = sname_alloc = OPENSSL_strdup(host); + if (sname_alloc == NULL) { + BIO_printf(bio_err, "%s: out of memory\n", prog); goto end; } - servername = sname_alloc; } - } else { - int res = 1; - char *tmp_host = host, *tmp_port = port; - if (connectstr != NULL) - res = BIO_parse_hostserv(connectstr, &host, &port, - BIO_PARSE_PRIO_HOST); + + /* Retain the original target host:port for use in the HTTP proxy connect string */ + thost = OPENSSL_strdup(host); + tport = OPENSSL_strdup(port); + if (thost == NULL || tport == NULL) { + BIO_printf(bio_err, "%s: out of memory\n", prog); + goto end; + } + + res = BIO_parse_hostserv(proxystr, &host, &port, BIO_PARSE_PRIO_HOST); if (tmp_host != host) OPENSSL_free(tmp_host); if (tmp_port != port) OPENSSL_free(tmp_port); if (!res) { BIO_printf(bio_err, - "%s: -connect argument or target parameter malformed or ambiguous\n", - prog); + "%s: -proxy argument malformed or ambiguous\n", prog); goto end; } } @@ -1661,7 +1607,17 @@ int s_client_main(int argc, char **argv) #endif if (!app_passwd(passarg, NULL, &pass, NULL)) { - BIO_printf(bio_err, "Error getting password\n"); + BIO_printf(bio_err, "Error getting private key password\n"); + goto end; + } + + if (!app_passwd(proxypassarg, NULL, &proxypass, NULL)) { + BIO_printf(bio_err, "Error getting proxy password\n"); + goto end; + } + + if (proxypass != NULL && proxyuser == NULL) { + BIO_printf(bio_err, "Error: Must specify proxy_user with proxy_pass\n"); goto end; } @@ -1670,35 +1626,28 @@ int s_client_main(int argc, char **argv) if (key_file != NULL) { key = load_key(key_file, key_format, 0, pass, e, - "client certificate private key file"); - if (key == NULL) { - ERR_print_errors(bio_err); + "client certificate private key"); + if (key == NULL) goto end; - } } if (cert_file != NULL) { - cert = load_cert(cert_file, cert_format, "client certificate file"); - if (cert == NULL) { - ERR_print_errors(bio_err); + cert = load_cert_pass(cert_file, cert_format, 1, pass, + "client certificate"); + if (cert == NULL) goto end; - } } if (chain_file != NULL) { - if (!load_certs(chain_file, &chain, FORMAT_PEM, NULL, - "client certificate chain")) + if (!load_certs(chain_file, 0, &chain, pass, "client certificate chain")) goto end; } if (crl_file != NULL) { X509_CRL *crl; - crl = load_crl(crl_file, crl_format); - if (crl == NULL) { - BIO_puts(bio_err, "Error loading CRL\n"); - ERR_print_errors(bio_err); + crl = load_crl(crl_file, crl_format, 0, "CRL"); + if (crl == NULL) goto end; - } crls = sk_X509_CRL_new_null(); if (crls == NULL || !sk_X509_CRL_push(crls, crl)) { BIO_puts(bio_err, "Error adding CRL\n"); @@ -1714,10 +1663,21 @@ int s_client_main(int argc, char **argv) if (bio_c_out == NULL) { if (c_quiet && !c_debug) { bio_c_out = BIO_new(BIO_s_null()); - if (c_msg && bio_c_msg == NULL) + if (c_msg && bio_c_msg == NULL) { bio_c_msg = dup_bio_out(FORMAT_TEXT); - } else if (bio_c_out == NULL) + if (bio_c_msg == NULL) { + BIO_printf(bio_err, "Out of memory\n"); + goto end; + } + } + } else { bio_c_out = dup_bio_out(FORMAT_TEXT); + } + + if (bio_c_out == NULL) { + BIO_printf(bio_err, "Unable to create BIO\n"); + goto end; + } } #ifndef OPENSSL_NO_SRP if (!app_passwd(srppass, NULL, &srp_arg.srppassin, NULL)) { @@ -1726,7 +1686,7 @@ int s_client_main(int argc, char **argv) } #endif - ctx = SSL_CTX_new(meth); + ctx = SSL_CTX_new_ex(app_get0_libctx(), app_get0_propq(), meth); if (ctx == NULL) { ERR_print_errors(bio_err); goto end; @@ -1761,6 +1721,9 @@ int s_client_main(int argc, char **argv) && SSL_CTX_set_max_proto_version(ctx, max_version) == 0) goto end; + if (ignore_unexpected_eof) + SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF); + if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) { BIO_printf(bio_err, "Error setting verify params\n"); ERR_print_errors(bio_err); @@ -1804,7 +1767,9 @@ int s_client_main(int argc, char **argv) goto end; } - if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, + if (!ssl_load_stores(ctx, + vfyCApath, vfyCAfile, vfyCAstore, + chCApath, chCAfile, chCAstore, crls, crl_download)) { BIO_printf(bio_err, "Error loading store locations\n"); ERR_print_errors(bio_err); @@ -1826,10 +1791,10 @@ int s_client_main(int argc, char **argv) if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine)) { BIO_puts(bio_err, "Error setting client auth engine\n"); ERR_print_errors(bio_err); - ENGINE_free(ssl_client_engine); + release_engine(ssl_client_engine); goto end; } - ENGINE_free(ssl_client_engine); + release_engine(ssl_client_engine); } #endif @@ -1933,7 +1898,8 @@ int s_client_main(int argc, char **argv) SSL_CTX_set_verify(ctx, verify, verify_callback); - if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { + if (!ctx_set_verify_locations(ctx, CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) { ERR_print_errors(bio_err); goto end; } @@ -1948,21 +1914,10 @@ int s_client_main(int argc, char **argv) SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); } -# ifndef OPENSSL_NO_SRP - if (srp_arg.srplogin) { - if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin)) { - BIO_printf(bio_err, "Unable to set SRP username\n"); - goto end; - } - srp_arg.msg = c_msg; - srp_arg.debug = c_debug; - SSL_CTX_set_srp_cb_arg(ctx, &srp_arg); - SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb); - SSL_CTX_set_srp_strength(ctx, srp_arg.strength); - if (c_msg || c_debug || srp_arg.amp == 0) - SSL_CTX_set_srp_verify_param_callback(ctx, - ssl_srp_verify_param_cb); - } +#ifndef OPENSSL_NO_SRP + if (srp_arg.srplogin != NULL + && !set_up_srp_arg(ctx, &srp_arg, srp_lateuser, c_msg, c_debug)) + goto end; # endif if (dane_tlsa_domain != NULL) { @@ -2023,7 +1978,7 @@ int s_client_main(int argc, char **argv) if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) { if (servername == NULL) { - if(host == NULL || is_dNS_name(host)) + if(host == NULL || is_dNS_name(host)) servername = (host == NULL) ? "localhost" : host; } if (servername != NULL && !SSL_set_tlsext_host_name(con, servername)) { @@ -2059,16 +2014,16 @@ int s_client_main(int argc, char **argv) } re_start: - if (init_client(&s, host, port, bindhost, bindport, socket_family, + if (init_client(&sock, host, port, bindhost, bindport, socket_family, socket_type, protocol) == 0) { BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error()); - BIO_closesocket(s); + BIO_closesocket(sock); goto end; } - BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s); + BIO_printf(bio_c_out, "CONNECTED(%08X)\n", sock); if (c_nbio) { - if (!BIO_socket_nbio(s, 1)) { + if (!BIO_socket_nbio(sock, 1)) { ERR_print_errors(bio_err); goto end; } @@ -2080,21 +2035,23 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_SCTP if (protocol == IPPROTO_SCTP) - sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE); + sbio = BIO_new_dgram_sctp(sock, BIO_NOCLOSE); else #endif - sbio = BIO_new_dgram(s, BIO_NOCLOSE); + sbio = BIO_new_dgram(sock, BIO_NOCLOSE); - if ((peer_info.addr = BIO_ADDR_new()) == NULL) { + if (sbio == NULL || (peer_info.addr = BIO_ADDR_new()) == NULL) { BIO_printf(bio_err, "memory allocation failure\n"); - BIO_closesocket(s); + BIO_free(sbio); + BIO_closesocket(sock); goto end; } - if (!BIO_sock_info(s, BIO_SOCK_INFO_ADDRESS, &peer_info)) { + if (!BIO_sock_info(sock, BIO_SOCK_INFO_ADDRESS, &peer_info)) { BIO_printf(bio_err, "getsockname:errno=%d\n", get_last_socket_error()); + BIO_free(sbio); BIO_ADDR_free(peer_info.addr); - BIO_closesocket(s); + BIO_closesocket(sock); goto end; } @@ -2131,17 +2088,29 @@ int s_client_main(int argc, char **argv) } } else #endif /* OPENSSL_NO_DTLS */ - sbio = BIO_new_socket(s, BIO_NOCLOSE); + sbio = BIO_new_socket(sock, BIO_NOCLOSE); + + if (sbio == NULL) { + BIO_printf(bio_err, "Unable to create BIO\n"); + ERR_print_errors(bio_err); + BIO_closesocket(sock); + goto end; + } if (nbio_test) { BIO *test; test = BIO_new(BIO_f_nbio_test()); + if (test == NULL) { + BIO_printf(bio_err, "Unable to create BIO\n"); + BIO_free(sbio); + goto shut; + } sbio = BIO_push(test, sbio); } if (c_debug) { - BIO_set_callback(sbio, bio_dump_callback); + BIO_set_callback_ex(sbio, bio_dump_callback); BIO_set_callback_arg(sbio, (char *)bio_c_out); } if (c_msg) { @@ -2186,6 +2155,13 @@ int s_client_main(int argc, char **argv) sbuf_len = 0; sbuf_off = 0; + if (proxystr != NULL) { + /* Here we must use the connect string target host & port */ + if (!OSSL_HTTP_proxy_connect(sbio, thost, tport, proxyuser, proxypass, + 0 /* no timeout */, bio_err, prog)) + goto shut; + } + switch ((PROTOCOL_CHOICE) starttls_proto) { case PROTO_OFF: break; @@ -2203,6 +2179,10 @@ int s_client_main(int argc, char **argv) int foundit = 0; BIO *fbio = BIO_new(BIO_f_buffer()); + if (fbio == NULL) { + BIO_printf(bio_err, "Unable to create BIO\n"); + goto shut; + } BIO_push(fbio, sbio); /* Wait for multi-line response to end from LMTP or SMTP */ do { @@ -2251,6 +2231,10 @@ int s_client_main(int argc, char **argv) int foundit = 0; BIO *fbio = BIO_new(BIO_f_buffer()); + if (fbio == NULL) { + BIO_printf(bio_err, "Unable to create BIO\n"); + goto shut; + } BIO_push(fbio, sbio); BIO_gets(fbio, mbuf, BUFSIZZ); /* STARTTLS command requires CAPABILITY... */ @@ -2278,6 +2262,10 @@ int s_client_main(int argc, char **argv) { BIO *fbio = BIO_new(BIO_f_buffer()); + if (fbio == NULL) { + BIO_printf(bio_err, "Unable to create BIO\n"); + goto shut; + } BIO_push(fbio, sbio); /* wait for multi-line response to end from FTP */ do { @@ -2361,64 +2349,15 @@ int s_client_main(int argc, char **argv) goto shut; } break; - case PROTO_CONNECT: - { - enum { - error_proto, /* Wrong protocol, not even HTTP */ - error_connect, /* CONNECT failed */ - success - } foundit = error_connect; - BIO *fbio = BIO_new(BIO_f_buffer()); - - BIO_push(fbio, sbio); - BIO_printf(fbio, "CONNECT %s HTTP/1.0\r\n\r\n", connectstr); - (void)BIO_flush(fbio); - /* - * The first line is the HTTP response. According to RFC 7230, - * it's formatted exactly like this: - * - * HTTP/d.d ddd Reason text\r\n - */ - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); - if (mbuf_len < (int)strlen("HTTP/1.0 200")) { - BIO_printf(bio_err, - "%s: HTTP CONNECT failed, insufficient response " - "from proxy (got %d octets)\n", prog, mbuf_len); - (void)BIO_flush(fbio); - BIO_pop(fbio); - BIO_free(fbio); - goto shut; - } - if (mbuf[8] != ' ') { - BIO_printf(bio_err, - "%s: HTTP CONNECT failed, incorrect response " - "from proxy\n", prog); - foundit = error_proto; - } else if (mbuf[9] != '2') { - BIO_printf(bio_err, "%s: HTTP CONNECT failed: %s ", prog, - &mbuf[9]); - } else { - foundit = success; - } - if (foundit != error_proto) { - /* Read past all following headers */ - do { - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); - } while (mbuf_len > 2); - } - (void)BIO_flush(fbio); - BIO_pop(fbio); - BIO_free(fbio); - if (foundit != success) { - goto shut; - } - } - break; case PROTO_IRC: { int numeric; BIO *fbio = BIO_new(BIO_f_buffer()); + if (fbio == NULL) { + BIO_printf(bio_err, "Unable to create BIO\n"); + goto end; + } BIO_push(fbio, sbio); BIO_printf(fbio, "STARTTLS\r\n"); (void)BIO_flush(fbio); @@ -2579,17 +2518,25 @@ int s_client_main(int argc, char **argv) int foundit = 0; BIO *fbio = BIO_new(BIO_f_buffer()); + if (fbio == NULL) { + BIO_printf(bio_err, "Unable to create BIO\n"); + goto end; + } BIO_push(fbio, sbio); BIO_gets(fbio, mbuf, BUFSIZZ); /* STARTTLS command requires CAPABILITIES... */ BIO_printf(fbio, "CAPABILITIES\r\n"); (void)BIO_flush(fbio); - /* wait for multi-line CAPABILITIES response */ - do { - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); - if (strstr(mbuf, "STARTTLS")) - foundit = 1; - } while (mbuf_len > 1 && mbuf[0] != '.'); + BIO_gets(fbio, mbuf, BUFSIZZ); + /* no point in trying to parse the CAPABILITIES response if there is none */ + if (strstr(mbuf, "101") != NULL) { + /* wait for multi-line CAPABILITIES response */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + if (strstr(mbuf, "STARTTLS")) + foundit = 1; + } while (mbuf_len > 1 && mbuf[0] != '.'); + } (void)BIO_flush(fbio); BIO_pop(fbio); BIO_free(fbio); @@ -2615,6 +2562,10 @@ int s_client_main(int argc, char **argv) int foundit = 0; BIO *fbio = BIO_new(BIO_f_buffer()); + if (fbio == NULL) { + BIO_printf(bio_err, "Unable to create BIO\n"); + goto end; + } BIO_push(fbio, sbio); /* wait for multi-line response to end from Sieve */ do { @@ -2674,8 +2625,9 @@ int s_client_main(int argc, char **argv) BIO *ldapbio = BIO_new(BIO_s_mem()); CONF *cnf = NCONF_new(NULL); - if (cnf == NULL) { + if (ldapbio == NULL || cnf == NULL) { BIO_free(ldapbio); + NCONF_free(cnf); goto end; } BIO_puts(ldapbio, ldap_tls_genconf); @@ -2784,7 +2736,6 @@ int s_client_main(int argc, char **argv) tty_on = 1; if (in_init) { in_init = 0; - if (c_brief) { BIO_puts(bio_err, "CONNECTION ESTABLISHED\n"); print_ssl_summary(con); @@ -3080,22 +3031,14 @@ int s_client_main(int argc, char **argv) BIO_printf(bio_err, "RENEGOTIATING\n"); SSL_renegotiate(con); cbuf_len = 0; - } else if (!c_ign_eof && (cbuf[0] == 'K' || cbuf[0] == 'k' ) + } else if (!c_ign_eof && (cbuf[0] == 'K' || cbuf[0] == 'k' ) && cmdletters) { BIO_printf(bio_err, "KEYUPDATE\n"); SSL_key_update(con, cbuf[0] == 'K' ? SSL_KEY_UPDATE_REQUESTED : SSL_KEY_UPDATE_NOT_REQUESTED); cbuf_len = 0; - } -#ifndef OPENSSL_NO_HEARTBEATS - else if ((!c_ign_eof) && (cbuf[0] == 'B' && cmdletters)) { - BIO_printf(bio_err, "HEARTBEATING\n"); - SSL_heartbeat(con); - cbuf_len = 0; - } -#endif - else { + } else { cbuf_len = i; cbuf_off = 0; #ifdef CHARSET_EBCDIC @@ -3108,7 +3051,6 @@ int s_client_main(int argc, char **argv) } } - ret = 0; shut: if (in_init) print_stuff(bio_c_out, con, full_log); @@ -3134,8 +3076,8 @@ int s_client_main(int argc, char **argv) timeout.tv_usec = 500000; /* some extreme round-trip */ do { FD_ZERO(&readfds); - openssl_fdset(s, &readfds); - } while (select(s + 1, &readfds, NULL, NULL, &timeout) > 0 + openssl_fdset(sock, &readfds); + } while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0 && BIO_read(sbio, sbuf, BUFSIZZ) > 0); BIO_closesocket(SSL_get_fd(con)); @@ -3166,6 +3108,8 @@ int s_client_main(int argc, char **argv) OPENSSL_free(bindport); OPENSSL_free(host); OPENSSL_free(port); + OPENSSL_free(thost); + OPENSSL_free(tport); X509_VERIFY_PARAM_free(vpm); ssl_excert_free(exc); sk_OPENSSL_STRING_free(ssl_args); @@ -3174,6 +3118,7 @@ int s_client_main(int argc, char **argv) OPENSSL_clear_free(cbuf, BUFSIZZ); OPENSSL_clear_free(sbuf, BUFSIZZ); OPENSSL_clear_free(mbuf, BUFSIZZ); + clear_free(proxypass); release_engine(e); BIO_free(bio_c_out); bio_c_out = NULL; @@ -3187,6 +3132,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) X509 *peer = NULL; STACK_OF(X509) *sk; const SSL_CIPHER *c; + EVP_PKEY *public_key; int i, istls13 = (SSL_version(s) == TLS1_3_VERSION); long verify_result; #ifndef OPENSSL_NO_COMP @@ -3212,13 +3158,26 @@ static void print_stuff(BIO *bio, SSL *s, int full) BIO_printf(bio, " i:"); X509_NAME_print_ex(bio, X509_get_issuer_name(sk_X509_value(sk, i)), 0, get_nameopt()); BIO_puts(bio, "\n"); + public_key = X509_get_pubkey(sk_X509_value(sk, i)); + if (public_key != NULL) { + BIO_printf(bio, " a:PKEY: %s, %d (bit); sigalg: %s\n", + OBJ_nid2sn(EVP_PKEY_get_base_id(public_key)), + EVP_PKEY_get_bits(public_key), + OBJ_nid2sn(X509_get_signature_nid(sk_X509_value(sk, i)))); + EVP_PKEY_free(public_key); + } + BIO_printf(bio, " v:NotBefore: "); + ASN1_TIME_print(bio, X509_get0_notBefore(sk_X509_value(sk, i))); + BIO_printf(bio, "; NotAfter: "); + ASN1_TIME_print(bio, X509_get0_notAfter(sk_X509_value(sk, i))); + BIO_puts(bio, "\n"); if (c_showcerts) PEM_write_bio_X509(bio, sk_X509_value(sk, i)); } } BIO_printf(bio, "---\n"); - peer = SSL_get_peer_certificate(s); + peer = SSL_get0_peer_certificate(s); if (peer != NULL) { BIO_printf(bio, "Server certificate\n"); @@ -3283,7 +3242,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) pktmp = X509_get0_pubkey(peer); BIO_printf(bio, "Server public key is %d bit\n", - EVP_PKEY_bits(pktmp)); + EVP_PKEY_get_bits(pktmp)); } BIO_printf(bio, "Secure Renegotiation IS%s supported\n", SSL_get_secure_renegotiation_support(s) ? "" : " NOT"); @@ -3302,8 +3261,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) BIO_printf(bio_err, "Using Kernel TLS for receiving\n"); #endif -#ifdef SSL_DEBUG - { + if (OSSL_TRACE_ENABLED(TLS)) { /* Print out local port of connection: useful for debugging */ int sock; union BIO_sock_info_u info; @@ -3316,7 +3274,6 @@ static void print_stuff(BIO *bio, SSL *s, int full) } BIO_ADDR_free(info.addr); } -#endif #if !defined(OPENSSL_NO_NEXTPROTONEG) if (next_proto.status != -1) { @@ -3385,11 +3342,11 @@ static void print_stuff(BIO *bio, SSL *s, int full) BIO_printf(bio, " Label: '%s'\n", keymatexportlabel); BIO_printf(bio, " Length: %i bytes\n", keymatexportlen); exportedkeymat = app_malloc(keymatexportlen, "export key"); - if (!SSL_export_keying_material(s, exportedkeymat, + if (SSL_export_keying_material(s, exportedkeymat, keymatexportlen, keymatexportlabel, strlen(keymatexportlabel), - NULL, 0, 0)) { + NULL, 0, 0) <= 0) { BIO_printf(bio, " Error\n"); } else { BIO_printf(bio, " Keying material: "); @@ -3400,7 +3357,6 @@ static void print_stuff(BIO *bio, SSL *s, int full) OPENSSL_free(exportedkeymat); } BIO_printf(bio, "---\n"); - X509_free(peer); /* flush, or debugging output gets mixed with http response */ (void)BIO_flush(bio); } @@ -3516,7 +3472,7 @@ static int ldap_ExtendedResponse_parse(const char *buf, long rem) } /* - * Host dNS Name verifier: used for checking that the hostname is in dNS format + * Host dNS Name verifier: used for checking that the hostname is in dNS format * before setting it as SNI */ static int is_dNS_name(const char *host) diff --git a/crypto/openssl/apps/s_server.c b/crypto/openssl/apps/s_server.c index aa41a79cc959..2b0b6ba381fb 100644 --- a/crypto/openssl/apps/s_server.c +++ b/crypto/openssl/apps/s_server.c @@ -3,7 +3,7 @@ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -21,6 +21,7 @@ #include #include #include +#include #ifndef OPENSSL_NO_SOCK @@ -47,12 +48,7 @@ typedef unsigned int u_int; #ifndef OPENSSL_NO_DH # include #endif -#ifndef OPENSSL_NO_RSA -# include -#endif -#ifndef OPENSSL_NO_SRP -# include -#endif +#include #include "s_apps.h" #include "timeouts.h" #ifdef CHARSET_EBCDIC @@ -71,9 +67,6 @@ static int generate_session_id(SSL *ssl, unsigned char *id, unsigned int *id_len); static void init_session_cache_ctx(SSL_CTX *sctx); static void free_sessions(void); -#ifndef OPENSSL_NO_DH -static DH *load_dh_param(const char *dhfile); -#endif static void print_connection_info(SSL *con); static const int bufsize = 16 * 1024; @@ -103,6 +96,8 @@ static int keymatexportlen = 20; static int async = 0; +static int use_sendfile = 0; + static const char *session_id_prefix = NULL; #ifndef OPENSSL_NO_DTLS @@ -123,6 +118,8 @@ static SSL_SESSION *psksess = NULL; static char *psk_identity = "Client_identity"; char *psk_key = NULL; /* by default PSK is not used */ +static char http_server_binmode = 0; /* for now: 0/1 = default/binary */ + #ifndef OPENSSL_NO_PSK static unsigned int psk_server_cb(SSL *ssl, const char *identity, unsigned char *psk, @@ -241,56 +238,7 @@ static int psk_find_session_cb(SSL *ssl, const unsigned char *identity, } #ifndef OPENSSL_NO_SRP -/* This is a context that we pass to callbacks */ -typedef struct srpsrvparm_st { - char *login; - SRP_VBASE *vb; - SRP_user_pwd *user; -} srpsrvparm; static srpsrvparm srp_callback_parm; - -/* - * This callback pretends to require some asynchronous logic in order to - * obtain a verifier. When the callback is called for a new connection we - * return with a negative value. This will provoke the accept etc to return - * with an LOOKUP_X509. The main logic of the reinvokes the suspended call - * (which would normally occur after a worker has finished) and we set the - * user parameters. - */ -static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) -{ - srpsrvparm *p = (srpsrvparm *) arg; - int ret = SSL3_AL_FATAL; - - if (p->login == NULL && p->user == NULL) { - p->login = SSL_get_srp_username(s); - BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login); - return -1; - } - - if (p->user == NULL) { - BIO_printf(bio_err, "User %s doesn't exist\n", p->login); - goto err; - } - - if (SSL_set_srp_server_param - (s, p->user->N, p->user->g, p->user->s, p->user->v, - p->user->info) < 0) { - *ad = SSL_AD_INTERNAL_ERROR; - goto err; - } - BIO_printf(bio_err, - "SRP parameters set: username = \"%s\" info=\"%s\" \n", - p->login, p->user->info); - ret = SSL_ERROR_NONE; - - err: - SRP_user_pwd_free(p->user); - p->user = NULL; - p->login = NULL; - return ret; -} - #endif static int local_argc = 0; @@ -476,7 +424,7 @@ static int ssl_servername_cb(SSL *s, int *ad, void *arg) BIO_printf(p->biodebug, "Hostname in TLS extension: \""); while ((uc = *cp++) != 0) BIO_printf(p->biodebug, - isascii(uc) && isprint(uc) ? "%c" : "\\x%02x", uc); + (((uc) & ~127) == 0) && isprint(uc) ? "%c" : "\\x%02x", uc); BIO_printf(p->biodebug, "\"\n"); } @@ -484,7 +432,7 @@ static int ssl_servername_cb(SSL *s, int *ad, void *arg) return SSL_TLSEXT_ERR_NOACK; if (servername != NULL) { - if (strcasecmp(servername, p->servername)) + if (OPENSSL_strcasecmp(servername, p->servername)) return p->extension_error; if (ctx2 != NULL) { BIO_printf(p->biodebug, "Switching server context.\n"); @@ -501,6 +449,7 @@ typedef struct tlsextstatusctx_st { char *respin; /* Default responder to use */ char *host, *path, *port; + char *proxy, *no_proxy; int use_ssl; int verbose; } tlsextstatusctx; @@ -520,6 +469,7 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx, OCSP_RESPONSE **resp) { char *host = NULL, *port = NULL, *path = NULL; + char *proxy = NULL, *no_proxy = NULL; int use_ssl; STACK_OF(OPENSSL_STRING) *aia = NULL; X509 *x = NULL; @@ -535,8 +485,8 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx, x = SSL_get_certificate(s); aia = X509_get1_ocsp(x); if (aia != NULL) { - if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0), - &host, &port, &path, &use_ssl)) { + if (!OSSL_HTTP_parse_url(sk_OPENSSL_STRING_value(aia, 0), &use_ssl, + NULL, &host, &port, NULL, &path, NULL, NULL)) { BIO_puts(bio_err, "cert_status: can't parse AIA URL\n"); goto err; } @@ -554,6 +504,8 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx, port = srctx->port; use_ssl = srctx->use_ssl; } + proxy = srctx->proxy; + no_proxy = srctx->no_proxy; inctx = X509_STORE_CTX_new(); if (inctx == NULL) @@ -585,8 +537,8 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx, if (!OCSP_REQUEST_add_ext(req, ext, -1)) goto err; } - *resp = process_responder(req, host, path, port, use_ssl, NULL, - srctx->timeout); + *resp = process_responder(req, host, port, path, proxy, no_proxy, + use_ssl, NULL /* headers */, srctx->timeout); if (*resp == NULL) { BIO_puts(bio_err, "cert_status: error querying responder\n"); goto done; @@ -716,7 +668,7 @@ static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, if (SSL_select_next_proto ((unsigned char **)out, outlen, alpn_ctx->data, alpn_ctx->len, in, inlen) != OPENSSL_NPN_NEGOTIATED) { - return SSL_TLSEXT_ERR_NOACK; + return SSL_TLSEXT_ERR_ALERT_FATAL; } if (!s_quiet) { @@ -735,7 +687,8 @@ static int not_resumable_sess_cb(SSL *s, int is_forward_secure) } typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, + OPT_COMMON, + OPT_ENGINE, OPT_4, OPT_6, OPT_ACCEPT, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT, OPT_VERIFY, OPT_NAMEOPT, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM, @@ -744,9 +697,12 @@ typedef enum OPTION_choice { OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_NO_CACHE, OPT_EXT_CACHE, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, - OPT_VERIFYCAFILE, OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF, + OPT_VERIFYCAFILE, + OPT_CASTORE, OPT_NOCASTORE, OPT_CHAINCASTORE, OPT_VERIFYCASTORE, + OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF, OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE, - OPT_STATUS_TIMEOUT, OPT_STATUS_URL, OPT_STATUS_FILE, OPT_MSG, OPT_MSGFILE, + OPT_STATUS_TIMEOUT, OPT_PROXY, OPT_NO_PROXY, OPT_STATUS_URL, + OPT_STATUS_FILE, OPT_MSG, OPT_MSGFILE, OPT_TRACE, OPT_SECURITY_DEBUG, OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, OPT_CRLF, OPT_QUIET, OPT_BRIEF, OPT_NO_DHE, OPT_NO_RESUME_EPHEMERAL, OPT_PSK_IDENTITY, OPT_PSK_HINT, OPT_PSK, @@ -756,132 +712,154 @@ typedef enum OPTION_choice { OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN, OPT_STATELESS, OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL, - OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, + OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, OPT_SENDFILE, OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA, OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG, + OPT_HTTP_SERVER_BINMODE, OPT_NOCANAMES, OPT_IGNORE_UNEXPECTED_EOF, OPT_R_ENUM, OPT_S_ENUM, OPT_V_ENUM, - OPT_X_ENUM + OPT_X_ENUM, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS s_server_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"ssl_config", OPT_SSL_CONFIG, 's', + "Configure SSL_CTX using the given configuration value"}, +#ifndef OPENSSL_NO_SSL_TRACE + {"trace", OPT_TRACE, '-', "trace protocol messages"}, +#endif +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Network"), {"port", OPT_PORT, 'p', "TCP/IP port to listen on for connections (default is " PORT ")"}, {"accept", OPT_ACCEPT, 's', "TCP/IP optional host and port to listen on for connections (default is *:" PORT ")"}, #ifdef AF_UNIX {"unix", OPT_UNIX, 's', "Unix domain socket to accept on"}, + {"unlink", OPT_UNLINK, '-', "For -unix, unlink existing socket first"}, #endif {"4", OPT_4, '-', "Use IPv4 only"}, {"6", OPT_6, '-', "Use IPv6 only"}, -#ifdef AF_UNIX - {"unlink", OPT_UNLINK, '-', "For -unix, unlink existing socket first"}, -#endif + + OPT_SECTION("Identity"), {"context", OPT_CONTEXT, 's', "Set session ID context"}, + {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, + {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"}, + {"no-CAfile", OPT_NOCAFILE, '-', + "Do not load the default certificates file"}, + {"no-CApath", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates directory"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store URI"}, + {"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"}, {"verify", OPT_VERIFY, 'n', "Turn on peer certificate verification"}, {"Verify", OPT_UPPER_V_VERIFY, 'n', "Turn on peer certificate verification, must have a cert"}, - {"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, - {"naccept", OPT_NACCEPT, 'p', "Terminate after #num connections"}, + {"nameopt", OPT_NAMEOPT, 's', "Certificate subject/issuer name printing options"}, + {"cert", OPT_CERT, '<', "Server certificate file to use; default " TEST_CERT}, + {"cert2", OPT_CERT2, '<', + "Certificate file to use for servername; default " TEST_CERT2}, + {"certform", OPT_CERTFORM, 'F', + "Server certificate file format (PEM/DER/P12); has no effect"}, + {"cert_chain", OPT_CERT_CHAIN, '<', + "Server certificate chain file in PEM format"}, + {"build_chain", OPT_BUILD_CHAIN, '-', "Build server certificate chain"}, {"serverinfo", OPT_SERVERINFO, 's', "PEM serverinfo file for certificate"}, - {"certform", OPT_CERTFORM, 'F', - "Certificate format (PEM or DER) PEM default"}, {"key", OPT_KEY, 's', - "Private Key if not in -cert; default is " TEST_CERT}, - {"keyform", OPT_KEYFORM, 'f', - "Key format (PEM, DER or ENGINE) PEM default"}, - {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, + "Private key file to use; default is -cert file or else" TEST_CERT}, + {"key2", OPT_KEY2, '<', + "-Private Key file to use for servername if not in -cert2"}, + {"keyform", OPT_KEYFORM, 'f', "Key format (ENGINE, other values ignored)"}, + {"pass", OPT_PASS, 's', "Private key and cert file pass phrase source"}, {"dcert", OPT_DCERT, '<', - "Second certificate file to use (usually for DSA)"}, - {"dhparam", OPT_DHPARAM, '<', "DH parameters file to use"}, + "Second server certificate file to use (usually for DSA)"}, {"dcertform", OPT_DCERTFORM, 'F', - "Second certificate format (PEM or DER) PEM default"}, + "Second server certificate file format (PEM/DER/P12); has no effect"}, + {"dcert_chain", OPT_DCERT_CHAIN, '<', + "second server certificate chain file in PEM format"}, {"dkey", OPT_DKEY, '<', "Second private key file to use (usually for DSA)"}, {"dkeyform", OPT_DKEYFORM, 'F', - "Second key format (PEM, DER or ENGINE) PEM default"}, - {"dpass", OPT_DPASS, 's', "Second private key file pass phrase source"}, + "Second key file format (ENGINE, other values ignored)"}, + {"dpass", OPT_DPASS, 's', + "Second private key and cert file pass phrase source"}, + {"dhparam", OPT_DHPARAM, '<', "DH parameters file to use"}, + {"servername", OPT_SERVERNAME, 's', + "Servername for HostName TLS extension"}, + {"servername_fatal", OPT_SERVERNAME_FATAL, '-', + "On servername mismatch send fatal alert (default warning alert)"}, {"nbio_test", OPT_NBIO_TEST, '-', "Test with the non-blocking test bio"}, {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, - {"debug", OPT_DEBUG, '-', "Print more output"}, - {"msg", OPT_MSG, '-', "Show protocol messages"}, - {"msgfile", OPT_MSGFILE, '>', - "File to send output of -msg or -trace, instead of stdout"}, - {"state", OPT_STATE, '-', "Print the SSL states"}, - {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, - {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, - {"no-CAfile", OPT_NOCAFILE, '-', - "Do not load the default certificates file"}, - {"no-CApath", OPT_NOCAPATH, '-', - "Do not load certificates from the default certificates directory"}, - {"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"}, {"quiet", OPT_QUIET, '-', "No server output"}, {"no_resume_ephemeral", OPT_NO_RESUME_EPHEMERAL, '-', "Disable caching and tickets if ephemeral (EC)DH is used"}, {"www", OPT_WWW, '-', "Respond to a 'GET /' with a status page"}, {"WWW", OPT_UPPER_WWW, '-', "Respond to a 'GET with the file ./path"}, - {"servername", OPT_SERVERNAME, 's', - "Servername for HostName TLS extension"}, - {"servername_fatal", OPT_SERVERNAME_FATAL, '-', - "mismatch send fatal alert (default warning alert)"}, - {"cert2", OPT_CERT2, '<', - "Certificate file to use for servername; default is" TEST_CERT2}, - {"key2", OPT_KEY2, '<', - "-Private Key file to use for servername if not in -cert2"}, + {"ignore_unexpected_eof", OPT_IGNORE_UNEXPECTED_EOF, '-', + "Do not treat lack of close_notify from a peer as an error"}, {"tlsextdebug", OPT_TLSEXTDEBUG, '-', "Hex dump of all TLS extensions received"}, {"HTTP", OPT_HTTP, '-', "Like -WWW but ./path includes HTTP headers"}, {"id_prefix", OPT_ID_PREFIX, 's', "Generate SSL/TLS session IDs prefixed by arg"}, - OPT_R_OPTIONS, {"keymatexport", OPT_KEYMATEXPORT, 's', "Export keying material using label"}, {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', - "Export len bytes of keying material (default 20)"}, + "Export len bytes of keying material; default 20"}, {"CRL", OPT_CRL, '<', "CRL file to use"}, + {"CRLform", OPT_CRLFORM, 'F', "CRL file format (PEM or DER); default PEM"}, {"crl_download", OPT_CRL_DOWNLOAD, '-', - "Download CRL from distribution points"}, - {"cert_chain", OPT_CERT_CHAIN, '<', - "certificate chain file in PEM format"}, - {"dcert_chain", OPT_DCERT_CHAIN, '<', - "second certificate chain file in PEM format"}, + "Download CRLs from distribution points in certificate CDP entries"}, + {"chainCAfile", OPT_CHAINCAFILE, '<', + "CA file for certificate chain (PEM format)"}, {"chainCApath", OPT_CHAINCAPATH, '/', "use dir as certificate store path to build CA certificate chain"}, + {"chainCAstore", OPT_CHAINCASTORE, ':', + "use URI as certificate store to build CA certificate chain"}, + {"verifyCAfile", OPT_VERIFYCAFILE, '<', + "CA file for certificate verification (PEM format)"}, {"verifyCApath", OPT_VERIFYCAPATH, '/', "use dir as certificate store path to verify CA certificate"}, + {"verifyCAstore", OPT_VERIFYCASTORE, ':', + "use URI as certificate store to verify CA certificate"}, {"no_cache", OPT_NO_CACHE, '-', "Disable session cache"}, {"ext_cache", OPT_EXT_CACHE, '-', - "Disable internal cache, setup and use external cache"}, - {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"}, + "Disable internal cache, set up and use external cache"}, {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', "Close connection on verification error"}, {"verify_quiet", OPT_VERIFY_QUIET, '-', "No verify output except verify errors"}, - {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"}, - {"chainCAfile", OPT_CHAINCAFILE, '<', - "CA file for certificate chain (PEM format)"}, - {"verifyCAfile", OPT_VERIFYCAFILE, '<', - "CA file for certificate verification (PEM format)"}, - {"ign_eof", OPT_IGN_EOF, '-', "ignore input eof (default when -quiet)"}, - {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Do not ignore input eof"}, + {"ign_eof", OPT_IGN_EOF, '-', "Ignore input EOF (default when -quiet)"}, + {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Do not ignore input EOF"}, + #ifndef OPENSSL_NO_OCSP + OPT_SECTION("OCSP"), {"status", OPT_STATUS, '-', "Request certificate status from server"}, {"status_verbose", OPT_STATUS_VERBOSE, '-', "Print more output in certificate status callback"}, {"status_timeout", OPT_STATUS_TIMEOUT, 'n', "Status request responder timeout"}, {"status_url", OPT_STATUS_URL, 's', "Status request fallback URL"}, + {"proxy", OPT_PROXY, 's', + "[http[s]://]host[:port][/path] of HTTP(S) proxy to use; path is ignored"}, + {"no_proxy", OPT_NO_PROXY, 's', + "List of addresses of servers not to use HTTP(S) proxy for"}, + {OPT_MORE_STR, 0, 0, + "Default from environment variable 'no_proxy', else 'NO_PROXY', else none"}, {"status_file", OPT_STATUS_FILE, '<', "File containing DER encoded OCSP Response"}, #endif -#ifndef OPENSSL_NO_SSL_TRACE - {"trace", OPT_TRACE, '-', "trace protocol messages"}, -#endif + + OPT_SECTION("Debug"), {"security_debug", OPT_SECURITY_DEBUG, '-', "Print output from SSL/TLS security framework"}, {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-', @@ -889,21 +867,29 @@ const OPTIONS s_server_options[] = { {"brief", OPT_BRIEF, '-', "Restrict output to brief summary of connection parameters"}, {"rev", OPT_REV, '-', - "act as a simple test server which just sends back with the received text reversed"}, + "act as an echo server that sends back received text reversed"}, + {"debug", OPT_DEBUG, '-', "Print more output"}, + {"msg", OPT_MSG, '-', "Show protocol messages"}, + {"msgfile", OPT_MSGFILE, '>', + "File to send output of -msg or -trace, instead of stdout"}, + {"state", OPT_STATE, '-', "Print the SSL states"}, {"async", OPT_ASYNC, '-', "Operate in asynchronous mode"}, - {"ssl_config", OPT_SSL_CONFIG, 's', - "Configure SSL_CTX using the configuration 'val'"}, - {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, - {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', - "Size used to split data for encrypt pipelines"}, {"max_pipelines", OPT_MAX_PIPELINES, 'p', "Maximum number of encrypt/decrypt pipelines to be used"}, + {"naccept", OPT_NACCEPT, 'p', "Terminate after #num connections"}, + {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, + + OPT_SECTION("Network"), + {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, + {"timeout", OPT_TIMEOUT, '-', "Enable timeouts"}, + {"mtu", OPT_MTU, 'p', "Set link-layer MTU"}, {"read_buf", OPT_READ_BUF, 'p', "Default read buffer size to be used for connections"}, - OPT_S_OPTIONS, - OPT_V_OPTIONS, - OPT_X_OPTIONS, - {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, + {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', + "Size used to split data for encrypt pipelines"}, + {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, + + OPT_SECTION("Server identity"), {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity to expect"}, #ifndef OPENSSL_NO_PSK {"psk_hint", OPT_PSK_HINT, 's', "PSK identity hint to use"}, @@ -911,10 +897,25 @@ const OPTIONS s_server_options[] = { {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, {"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"}, #ifndef OPENSSL_NO_SRP - {"srpvfile", OPT_SRPVFILE, '<', "The verifier file for SRP"}, + {"srpvfile", OPT_SRPVFILE, '<', "(deprecated) The verifier file for SRP"}, {"srpuserseed", OPT_SRPUSERSEED, 's', - "A seed string for a default user salt"}, + "(deprecated) A seed string for a default user salt"}, #endif + + OPT_SECTION("Protocol and version"), + {"max_early_data", OPT_MAX_EARLY, 'n', + "The maximum number of bytes of early data as advertised in tickets"}, + {"recv_max_early_data", OPT_RECV_MAX_EARLY, 'n', + "The maximum number of bytes of early data (hard limit)"}, + {"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"}, + {"num_tickets", OPT_S_NUM_TICKETS, 'n', + "The number of TLSv1.3 session tickets that a server will automatically issue" }, + {"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"}, + {"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"}, + {"http_server_binmode", OPT_HTTP_SERVER_BINMODE, '-', "opening files in binary mode when acting as http server (-WWW and -HTTP)"}, + {"no_ca_names", OPT_NOCANAMES, '-', + "Disable TLS Extension CA Names"}, + {"stateless", OPT_STATELESS, '-', "Require TLSv1.3 cookies"}, #ifndef OPENSSL_NO_SSL3 {"ssl3", OPT_SSL3, '-', "Just talk SSLv3"}, #endif @@ -932,12 +933,9 @@ const OPTIONS s_server_options[] = { #endif #ifndef OPENSSL_NO_DTLS {"dtls", OPT_DTLS, '-', "Use any DTLS version"}, - {"timeout", OPT_TIMEOUT, '-', "Enable timeouts"}, - {"mtu", OPT_MTU, 'p', "Set link layer MTU"}, {"listen", OPT_LISTEN, '-', "Listen for a DTLS ClientHello with a cookie and then connect"}, #endif - {"stateless", OPT_STATELESS, '-', "Require TLSv1.3 cookies"}, #ifndef OPENSSL_NO_DTLS1 {"dtls1", OPT_DTLS1, '-', "Just talk DTLSv1"}, #endif @@ -948,33 +946,27 @@ const OPTIONS s_server_options[] = { {"sctp", OPT_SCTP, '-', "Use SCTP"}, {"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"}, #endif -#ifndef OPENSSL_NO_DH - {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"}, +#ifndef OPENSSL_NO_SRTP + {"use_srtp", OPT_SRTP_PROFILES, 's', + "Offer SRTP key management with a colon-separated profile list"}, #endif + {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"}, #ifndef OPENSSL_NO_NEXTPROTONEG {"nextprotoneg", OPT_NEXTPROTONEG, 's', "Set the advertised protocols for the NPN extension (comma-separated list)"}, -#endif -#ifndef OPENSSL_NO_SRTP - {"use_srtp", OPT_SRTP_PROFILES, 's', - "Offer SRTP key management with a colon-separated profile list"}, #endif {"alpn", OPT_ALPN, 's', "Set the advertised protocols for the ALPN extension (comma-separated list)"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#ifndef OPENSSL_NO_KTLS + {"sendfile", OPT_SENDFILE, '-', "Use sendfile to response file with -WWW"}, #endif - {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, - {"max_early_data", OPT_MAX_EARLY, 'n', - "The maximum number of bytes of early data as advertised in tickets"}, - {"recv_max_early_data", OPT_RECV_MAX_EARLY, 'n', - "The maximum number of bytes of early data (hard limit)"}, - {"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"}, - {"num_tickets", OPT_S_NUM_TICKETS, 'n', - "The number of TLSv1.3 session tickets that a server will automatically issue" }, - {"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"}, - {"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"}, - {NULL, OPT_EOF, 0, NULL} + + OPT_R_OPTIONS, + OPT_S_OPTIONS, + OPT_V_OPTIONS, + OPT_X_OPTIONS, + OPT_PROV_OPTIONS, + {NULL} }; #define IS_PROT_FLAG(o) \ @@ -993,28 +985,28 @@ int s_server_main(int argc, char *argv[]) STACK_OF(X509_CRL) *crls = NULL; X509 *s_cert = NULL, *s_dcert = NULL; X509_VERIFY_PARAM *vpm = NULL; - const char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL; + const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL; + const char *chCApath = NULL, *chCAfile = NULL, *chCAstore = NULL; char *dpassarg = NULL, *dpass = NULL; - char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; + char *passarg = NULL, *pass = NULL; + char *vfyCApath = NULL, *vfyCAfile = NULL, *vfyCAstore = NULL; char *crl_file = NULL, *prog; #ifdef AF_UNIX int unlink_unix_path = 0; #endif do_server_cb server_cb; int vpmtouched = 0, build_chain = 0, no_cache = 0, ext_cache = 0; -#ifndef OPENSSL_NO_DH char *dhfile = NULL; int no_dhe = 0; -#endif int nocert = 0, ret = 1; - int noCApath = 0, noCAfile = 0; - int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM; - int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM; + int noCApath = 0, noCAfile = 0, noCAstore = 0; + int s_cert_format = FORMAT_UNDEF, s_key_format = FORMAT_UNDEF; + int s_dcert_format = FORMAT_UNDEF, s_dkey_format = FORMAT_UNDEF; int rev = 0, naccept = -1, sdebug = 0; int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0; - int state = 0, crl_format = FORMAT_PEM, crl_download = 0; + int state = 0, crl_format = FORMAT_UNDEF, crl_download = 0; char *host = NULL; - char *port = BUF_strdup(PORT); + char *port = NULL; unsigned char *context = NULL; OPTION_CHOICE o; EVP_PKEY *s_key2 = NULL; @@ -1056,9 +1048,11 @@ int s_server_main(int argc, char *argv[]) const char *keylog_file = NULL; int max_early_data = -1, recv_max_early_data = -1; char *psksessf = NULL; + int no_ca_names = 0; #ifndef OPENSSL_NO_SCTP int sctp_label_bug = 0; #endif + int ignore_unexpected_eof = 0; /* Init of few remaining global variables */ local_argc = argc; @@ -1073,10 +1067,12 @@ int s_server_main(int argc, char *argv[]) s_quiet = 0; s_brief = 0; async = 0; + use_sendfile = 0; + port = OPENSSL_strdup(PORT); cctx = SSL_CONF_CTX_new(); vpm = X509_VERIFY_PARAM_new(); - if (cctx == NULL || vpm == NULL) + if (port == NULL || cctx == NULL || vpm == NULL) goto end; SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CMDLINE); @@ -1163,7 +1159,9 @@ int s_server_main(int argc, char *argv[]) #ifdef AF_UNIX case OPT_UNIX: socket_family = AF_UNIX; - OPENSSL_free(host); host = BUF_strdup(opt_arg()); + OPENSSL_free(host); host = OPENSSL_strdup(opt_arg()); + if (host == NULL) + goto end; OPENSSL_free(port); port = NULL; break; case OPT_UNLINK: @@ -1209,7 +1207,7 @@ int s_server_main(int argc, char *argv[]) s_serverinfo_file = opt_arg(); break; case OPT_CERTFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_cert_format)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &s_cert_format)) goto opthelp; break; case OPT_KEY: @@ -1226,19 +1224,17 @@ int s_server_main(int argc, char *argv[]) s_chain_file = opt_arg(); break; case OPT_DHPARAM: -#ifndef OPENSSL_NO_DH dhfile = opt_arg(); -#endif break; case OPT_DCERTFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dcert_format)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &s_dcert_format)) goto opthelp; break; case OPT_DCERT: s_dcert_file = opt_arg(); break; case OPT_DKEYFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dkey_format)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &s_dkey_format)) goto opthelp; break; case OPT_DPASS: @@ -1265,6 +1261,18 @@ int s_server_main(int argc, char *argv[]) case OPT_VERIFYCAPATH: vfyCApath = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; + case OPT_NOCASTORE: + noCAstore = 1; + break; + case OPT_CHAINCASTORE: + chCAstore = opt_arg(); + break; + case OPT_VERIFYCASTORE: + vfyCAstore = opt_arg(); + break; case OPT_NO_CACHE: no_cache = 1; break; @@ -1350,16 +1358,25 @@ int s_server_main(int argc, char *argv[]) #ifndef OPENSSL_NO_OCSP s_tlsextstatus = 1; tlscstatp.timeout = atoi(opt_arg()); +#endif + break; + case OPT_PROXY: +#ifndef OPENSSL_NO_OCSP + tlscstatp.proxy = opt_arg(); +#endif + break; + case OPT_NO_PROXY: +#ifndef OPENSSL_NO_OCSP + tlscstatp.no_proxy = opt_arg(); #endif break; case OPT_STATUS_URL: #ifndef OPENSSL_NO_OCSP s_tlsextstatus = 1; - if (!OCSP_parse_url(opt_arg(), - &tlscstatp.host, - &tlscstatp.port, - &tlscstatp.path, &tlscstatp.use_ssl)) { - BIO_printf(bio_err, "Error parsing URL\n"); + if (!OSSL_HTTP_parse_url(opt_arg(), &tlscstatp.use_ssl, NULL, + &tlscstatp.host, &tlscstatp.port, NULL, + &tlscstatp.path, NULL, NULL)) { + BIO_printf(bio_err, "Error parsing -status_url argument\n"); goto end; } #endif @@ -1375,6 +1392,10 @@ int s_server_main(int argc, char *argv[]) break; case OPT_MSGFILE: bio_s_msg = BIO_new_file(opt_arg(), "w"); + if (bio_s_msg == NULL) { + BIO_printf(bio_err, "Error writing file %s\n", opt_arg()); + goto end; + } break; case OPT_TRACE: #ifndef OPENSSL_NO_SSL_TRACE @@ -1400,9 +1421,7 @@ int s_server_main(int argc, char *argv[]) s_quiet = s_brief = verify_args.quiet = 1; break; case OPT_NO_DHE: -#ifndef OPENSSL_NO_DH no_dhe = 1; -#endif break; case OPT_NO_RESUME_EPHEMERAL: no_resume_ephemeral = 1; @@ -1529,12 +1548,18 @@ int s_server_main(int argc, char *argv[]) session_id_prefix = opt_arg(); break; case OPT_ENGINE: - engine = setup_engine(opt_arg(), 1); +#ifndef OPENSSL_NO_ENGINE + engine = setup_engine(opt_arg(), s_debug); +#endif break; case OPT_R_CASES: if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_SERVERNAME: tlsextcbp.servername = opt_arg(); break; @@ -1603,10 +1628,30 @@ int s_server_main(int argc, char *argv[]) if (max_early_data == -1) max_early_data = SSL3_RT_MAX_PLAIN_LENGTH; break; + case OPT_HTTP_SERVER_BINMODE: + http_server_binmode = 1; + break; + case OPT_NOCANAMES: + no_ca_names = 1; + break; + case OPT_SENDFILE: +#ifndef OPENSSL_NO_KTLS + use_sendfile = 1; +#endif + break; + case OPT_IGNORE_UNEXPECTED_EOF: + ignore_unexpected_eof = 1; + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); - argv = opt_rest(); + if (argc != 0) + goto opthelp; + + if (!app_RAND_load()) + goto end; #ifndef OPENSSL_NO_NEXTPROTONEG if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) { @@ -1655,6 +1700,13 @@ int s_server_main(int argc, char *argv[]) } #endif +#ifndef OPENSSL_NO_KTLS + if (use_sendfile && www <= 1) { + BIO_printf(bio_err, "Can't use -sendfile without -WWW or -HTTP\n"); + goto end; + } +#endif + if (!app_passwd(passarg, dpassarg, &pass, &dpass)) { BIO_printf(bio_err, "Error getting password\n"); goto end; @@ -1671,40 +1723,32 @@ int s_server_main(int argc, char *argv[]) if (nocert == 0) { s_key = load_key(s_key_file, s_key_format, 0, pass, engine, - "server certificate private key file"); - if (s_key == NULL) { - ERR_print_errors(bio_err); + "server certificate private key"); + if (s_key == NULL) goto end; - } - s_cert = load_cert(s_cert_file, s_cert_format, - "server certificate file"); + s_cert = load_cert_pass(s_cert_file, s_cert_format, 1, pass, + "server certificate"); - if (s_cert == NULL) { - ERR_print_errors(bio_err); + if (s_cert == NULL) goto end; - } if (s_chain_file != NULL) { - if (!load_certs(s_chain_file, &s_chain, FORMAT_PEM, NULL, + if (!load_certs(s_chain_file, 0, &s_chain, NULL, "server certificate chain")) goto end; } if (tlsextcbp.servername != NULL) { s_key2 = load_key(s_key_file2, s_key_format, 0, pass, engine, - "second server certificate private key file"); - if (s_key2 == NULL) { - ERR_print_errors(bio_err); + "second server certificate private key"); + if (s_key2 == NULL) goto end; - } - s_cert2 = load_cert(s_cert_file2, s_cert_format, - "second server certificate file"); + s_cert2 = load_cert_pass(s_cert_file2, s_cert_format, 1, pass, + "second server certificate"); - if (s_cert2 == NULL) { - ERR_print_errors(bio_err); + if (s_cert2 == NULL) goto end; - } } } #if !defined(OPENSSL_NO_NEXTPROTONEG) @@ -1723,12 +1767,9 @@ int s_server_main(int argc, char *argv[]) if (crl_file != NULL) { X509_CRL *crl; - crl = load_crl(crl_file, crl_format); - if (crl == NULL) { - BIO_puts(bio_err, "Error loading CRL\n"); - ERR_print_errors(bio_err); + crl = load_crl(crl_file, crl_format, 0, "CRL"); + if (crl == NULL) goto end; - } crls = sk_X509_CRL_new_null(); if (crls == NULL || !sk_X509_CRL_push(crls, crl)) { BIO_puts(bio_err, "Error adding CRL\n"); @@ -1744,21 +1785,19 @@ int s_server_main(int argc, char *argv[]) s_dkey_file = s_dcert_file; s_dkey = load_key(s_dkey_file, s_dkey_format, - 0, dpass, engine, "second certificate private key file"); - if (s_dkey == NULL) { - ERR_print_errors(bio_err); + 0, dpass, engine, "second certificate private key"); + if (s_dkey == NULL) goto end; - } - s_dcert = load_cert(s_dcert_file, s_dcert_format, - "second server certificate file"); + s_dcert = load_cert_pass(s_dcert_file, s_dcert_format, 1, dpass, + "second server certificate"); if (s_dcert == NULL) { ERR_print_errors(bio_err); goto end; } if (s_dchain_file != NULL) { - if (!load_certs(s_dchain_file, &s_dchain, FORMAT_PEM, NULL, + if (!load_certs(s_dchain_file, 0, &s_dchain, NULL, "second server certificate chain")) goto end; } @@ -1768,17 +1807,22 @@ int s_server_main(int argc, char *argv[]) if (bio_s_out == NULL) { if (s_quiet && !s_debug) { bio_s_out = BIO_new(BIO_s_null()); - if (s_msg && bio_s_msg == NULL) + if (s_msg && bio_s_msg == NULL) { bio_s_msg = dup_bio_out(FORMAT_TEXT); + if (bio_s_msg == NULL) { + BIO_printf(bio_err, "Out of memory\n"); + goto end; + } + } } else { - if (bio_s_out == NULL) - bio_s_out = dup_bio_out(FORMAT_TEXT); + bio_s_out = dup_bio_out(FORMAT_TEXT); } } -#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) - if (nocert) -#endif - { + + if (bio_s_out == NULL) + goto end; + + if (nocert) { s_cert_file = NULL; s_key_file = NULL; s_dcert_file = NULL; @@ -1787,7 +1831,7 @@ int s_server_main(int argc, char *argv[]) s_key_file2 = NULL; } - ctx = SSL_CTX_new(meth); + ctx = SSL_CTX_new_ex(app_get0_libctx(), app_get0_propq(), meth); if (ctx == NULL) { ERR_print_errors(bio_err); goto end; @@ -1809,7 +1853,6 @@ int s_server_main(int argc, char *argv[]) goto end; } } - #ifndef OPENSSL_NO_SCTP if (protocol == IPPROTO_SCTP && sctp_label_bug == 1) SSL_CTX_set_mode(ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG); @@ -1833,7 +1876,6 @@ int s_server_main(int argc, char *argv[]) } BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); } - SSL_CTX_set_quiet_shutdown(ctx, 1); if (exc != NULL) ssl_ctx_set_excert(ctx, exc); @@ -1850,6 +1892,13 @@ int s_server_main(int argc, char *argv[]) SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC); } + if (no_ca_names) { + SSL_CTX_set_options(ctx, SSL_OP_DISABLE_TLSEXT_CA_NAMES); + } + + if (ignore_unexpected_eof) + SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF); + if (max_send_fragment > 0 && !SSL_CTX_set_max_send_fragment(ctx, max_send_fragment)) { BIO_printf(bio_err, "%s: Max send fragment size %u is out of permitted range\n", @@ -1884,7 +1933,8 @@ int s_server_main(int argc, char *argv[]) } #endif - if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { + if (!ctx_set_verify_locations(ctx, CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) { ERR_print_errors(bio_err); goto end; } @@ -1896,7 +1946,9 @@ int s_server_main(int argc, char *argv[]) ssl_ctx_add_crls(ctx, crls, 0); - if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, + if (!ssl_load_stores(ctx, + vfyCApath, vfyCAfile, vfyCAstore, + chCApath, chCAfile, chCAstore, crls, crl_download)) { BIO_printf(bio_err, "Error loading store locations\n"); ERR_print_errors(bio_err); @@ -1904,7 +1956,7 @@ int s_server_main(int argc, char *argv[]) } if (s_cert2) { - ctx2 = SSL_CTX_new(meth); + ctx2 = SSL_CTX_new_ex(app_get0_libctx(), app_get0_propq(), meth); if (ctx2 == NULL) { ERR_print_errors(bio_err); goto end; @@ -1928,7 +1980,6 @@ int s_server_main(int argc, char *argv[]) } BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); } - SSL_CTX_set_quiet_shutdown(ctx2, 1); if (exc != NULL) ssl_ctx_set_excert(ctx2, exc); @@ -1945,8 +1996,8 @@ int s_server_main(int argc, char *argv[]) if (async) SSL_CTX_set_mode(ctx2, SSL_MODE_ASYNC); - if (!ctx_set_verify_locations(ctx2, CAfile, CApath, noCAfile, - noCApath)) { + if (!ctx_set_verify_locations(ctx2, CAfile, noCAfile, CApath, + noCApath, CAstore, noCAstore)) { ERR_print_errors(bio_err); goto end; } @@ -1968,54 +2019,70 @@ int s_server_main(int argc, char *argv[]) if (alpn_ctx.data) SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx); -#ifndef OPENSSL_NO_DH if (!no_dhe) { - DH *dh = NULL; + EVP_PKEY *dhpkey = NULL; if (dhfile != NULL) - dh = load_dh_param(dhfile); + dhpkey = load_keyparams(dhfile, FORMAT_UNDEF, 0, "DH", "DH parameters"); else if (s_cert_file != NULL) - dh = load_dh_param(s_cert_file); + dhpkey = load_keyparams_suppress(s_cert_file, FORMAT_UNDEF, 0, "DH", + "DH parameters", 1); - if (dh != NULL) { + if (dhpkey != NULL) { BIO_printf(bio_s_out, "Setting temp DH parameters\n"); } else { BIO_printf(bio_s_out, "Using default temp DH parameters\n"); } (void)BIO_flush(bio_s_out); - if (dh == NULL) { + if (dhpkey == NULL) { SSL_CTX_set_dh_auto(ctx, 1); - } else if (!SSL_CTX_set_tmp_dh(ctx, dh)) { - BIO_puts(bio_err, "Error setting temp DH parameters\n"); - ERR_print_errors(bio_err); - DH_free(dh); - goto end; + } else { + /* + * We need 2 references: one for use by ctx and one for use by + * ctx2 + */ + if (!EVP_PKEY_up_ref(dhpkey)) { + EVP_PKEY_free(dhpkey); + goto end; + } + if (!SSL_CTX_set0_tmp_dh_pkey(ctx, dhpkey)) { + BIO_puts(bio_err, "Error setting temp DH parameters\n"); + ERR_print_errors(bio_err); + /* Free 2 references */ + EVP_PKEY_free(dhpkey); + EVP_PKEY_free(dhpkey); + goto end; + } } if (ctx2 != NULL) { - if (!dhfile) { - DH *dh2 = load_dh_param(s_cert_file2); - if (dh2 != NULL) { + if (dhfile != NULL) { + EVP_PKEY *dhpkey2 = load_keyparams_suppress(s_cert_file2, + FORMAT_UNDEF, + 0, "DH", + "DH parameters", 1); + + if (dhpkey2 != NULL) { BIO_printf(bio_s_out, "Setting temp DH parameters\n"); (void)BIO_flush(bio_s_out); - DH_free(dh); - dh = dh2; + EVP_PKEY_free(dhpkey); + dhpkey = dhpkey2; } } - if (dh == NULL) { + if (dhpkey == NULL) { SSL_CTX_set_dh_auto(ctx2, 1); - } else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) { + } else if (!SSL_CTX_set0_tmp_dh_pkey(ctx2, dhpkey)) { BIO_puts(bio_err, "Error setting temp DH parameters\n"); ERR_print_errors(bio_err); - DH_free(dh); + EVP_PKEY_free(dhpkey); goto end; } + dhpkey = NULL; } - DH_free(dh); + EVP_PKEY_free(dhpkey); } -#endif if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain)) goto end; @@ -2050,10 +2117,16 @@ int s_server_main(int argc, char *argv[]) SSL_CTX_set_psk_server_callback(ctx, psk_server_cb); } - if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) { - BIO_printf(bio_err, "error setting PSK identity hint to context\n"); - ERR_print_errors(bio_err); - goto end; + if (psk_identity_hint != NULL) { + if (min_version == TLS1_3_VERSION) { + BIO_printf(bio_s_out, "PSK warning: there is NO identity hint in TLSv1.3\n"); + } else { + if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) { + BIO_printf(bio_err, "error setting PSK identity hint to context\n"); + ERR_print_errors(bio_err); + goto end; + } + } } #endif if (psksessf != NULL) { @@ -2112,20 +2185,9 @@ int s_server_main(int argc, char *argv[]) #ifndef OPENSSL_NO_SRP if (srp_verifier_file != NULL) { - srp_callback_parm.vb = SRP_VBASE_new(srpuserseed); - srp_callback_parm.user = NULL; - srp_callback_parm.login = NULL; - if ((ret = - SRP_VBASE_init(srp_callback_parm.vb, - srp_verifier_file)) != SRP_NO_ERROR) { - BIO_printf(bio_err, - "Cannot initialize SRP verifier file \"%s\":ret=%d\n", - srp_verifier_file, ret); + if (!set_up_srp_verifier_file(ctx, &srp_callback_parm, srpuserseed, + srp_verifier_file)) goto end; - } - SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback); - SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm); - SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb); } else #endif if (CAfile != NULL) { @@ -2236,8 +2298,8 @@ static void print_stats(BIO *bio, SSL_CTX *ssl_ctx) SSL_CTX_sess_get_cache_size(ssl_ctx)); } -static long int count_reads_callback(BIO *bio, int cmd, const char *argp, - int argi, long int argl, long int ret) +static long int count_reads_callback(BIO *bio, int cmd, const char *argp, size_t len, + int argi, long argl, int ret, size_t *processed) { unsigned int *p_counter = (unsigned int *)BIO_get_callback_arg(bio); @@ -2253,7 +2315,7 @@ static long int count_reads_callback(BIO *bio, int cmd, const char *argp, if (s_debug) { BIO_set_callback_arg(bio, (char *)bio_s_out); - ret = bio_dump_callback(bio, cmd, argp, argi, argl, ret); + ret = (int)bio_dump_callback(bio, cmd, argp, len, argi, argl, ret, processed); BIO_set_callback_arg(bio, (char *)p_counter); } @@ -2321,6 +2383,11 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) else # endif sbio = BIO_new_dgram(s, BIO_NOCLOSE); + if (sbio == NULL) { + BIO_printf(bio_err, "Unable to create BIO\n"); + ERR_print_errors(bio_err); + goto err; + } if (enable_timeouts) { timeout.tv_sec = 0; @@ -2370,6 +2437,13 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) BIO *test; test = BIO_new(BIO_f_nbio_test()); + if (test == NULL) { + BIO_printf(bio_err, "Unable to create BIO\n"); + ret = -1; + BIO_free(sbio); + goto err; + } + sbio = BIO_push(test, sbio); } @@ -2377,7 +2451,7 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) SSL_set_accept_state(con); /* SSL_set_fd(con,s); */ - BIO_set_callback(SSL_get_rbio(con), count_reads_callback); + BIO_set_callback_ex(SSL_get_rbio(con), count_reads_callback); if (s_msg) { #ifndef OPENSSL_NO_SSL_TRACE if (s_msg == 2) @@ -2536,14 +2610,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) */ goto err; } -#ifndef OPENSSL_NO_HEARTBEATS - if ((buf[0] == 'B') && ((buf[1] == '\n') || (buf[1] == '\r'))) { - BIO_printf(bio_err, "HEARTBEATING\n"); - SSL_heartbeat(con); - i = 0; - continue; - } -#endif if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) { SSL_renegotiate(con); i = SSL_do_handshake(con); @@ -2585,8 +2651,8 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) continue; } if (buf[0] == 'P') { - static const char *str = "Lets print some clear text\n"; - BIO_write(SSL_get_wbio(con), str, strlen(str)); + static const char str[] = "Lets print some clear text\n"; + BIO_write(SSL_get_wbio(con), str, sizeof(str) -1); } if (buf[0] == 'S') { print_stats(bio_s_out, SSL_get_SSL_CTX(con)); @@ -2609,15 +2675,9 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) #ifndef OPENSSL_NO_SRP while (SSL_get_error(con, k) == SSL_ERROR_WANT_X509_LOOKUP) { BIO_printf(bio_s_out, "LOOKUP renego during write\n"); - SRP_user_pwd_free(srp_callback_parm.user); - srp_callback_parm.user = - SRP_VBASE_get1_by_user(srp_callback_parm.vb, - srp_callback_parm.login); - if (srp_callback_parm.user) - BIO_printf(bio_s_out, "LOOKUP done %s\n", - srp_callback_parm.user->info); - else - BIO_printf(bio_s_out, "LOOKUP not successful\n"); + + lookup_srp_user(&srp_callback_parm, bio_s_out); + k = SSL_write(con, &(buf[l]), (unsigned int)i); } #endif @@ -2688,7 +2748,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) ret = -1; goto err; } - if (i < 0) { ret = 0; goto err; @@ -2702,15 +2761,9 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) #ifndef OPENSSL_NO_SRP while (SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) { BIO_printf(bio_s_out, "LOOKUP renego during read\n"); - SRP_user_pwd_free(srp_callback_parm.user); - srp_callback_parm.user = - SRP_VBASE_get1_by_user(srp_callback_parm.vb, - srp_callback_parm.login); - if (srp_callback_parm.user) - BIO_printf(bio_s_out, "LOOKUP done %s\n", - srp_callback_parm.user->info); - else - BIO_printf(bio_s_out, "LOOKUP not successful\n"); + + lookup_srp_user(&srp_callback_parm, bio_s_out); + i = SSL_read(con, (char *)buf, bufsize); } #endif @@ -2757,7 +2810,7 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) err: if (con != NULL) { BIO_printf(bio_s_out, "shutting down SSL\n"); - SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); + do_ssl_shutdown(con); SSL_free(con); } BIO_printf(bio_s_out, "CONNECTION CLOSED\n"); @@ -2852,15 +2905,9 @@ static int init_ssl_connection(SSL *con) && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) { BIO_printf(bio_s_out, "LOOKUP during accept %s\n", srp_callback_parm.login); - SRP_user_pwd_free(srp_callback_parm.user); - srp_callback_parm.user = - SRP_VBASE_get1_by_user(srp_callback_parm.vb, - srp_callback_parm.login); - if (srp_callback_parm.user) - BIO_printf(bio_s_out, "LOOKUP done %s\n", - srp_callback_parm.user->info); - else - BIO_printf(bio_s_out, "LOOKUP not successful\n"); + + lookup_srp_user(&srp_callback_parm, bio_s_out); + i = SSL_accept(con); if (i <= 0) retry = is_retryable(con, i); @@ -2909,12 +2956,11 @@ static void print_connection_info(SSL *con) PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con)); - peer = SSL_get_peer_certificate(con); + peer = SSL_get0_peer_certificate(con); if (peer != NULL) { BIO_printf(bio_s_out, "Client certificate\n"); PEM_write_bio_X509(bio_s_out, peer); dump_cert_text(bio_s_out, peer); - X509_free(peer); peer = NULL; } @@ -2959,11 +3005,11 @@ static void print_connection_info(SSL *con) BIO_printf(bio_s_out, " Label: '%s'\n", keymatexportlabel); BIO_printf(bio_s_out, " Length: %i bytes\n", keymatexportlen); exportedkeymat = app_malloc(keymatexportlen, "export key"); - if (!SSL_export_keying_material(con, exportedkeymat, + if (SSL_export_keying_material(con, exportedkeymat, keymatexportlen, keymatexportlabel, strlen(keymatexportlabel), - NULL, 0, 0)) { + NULL, 0, 0) <= 0) { BIO_printf(bio_s_out, " Error\n"); } else { BIO_printf(bio_s_out, " Keying material: "); @@ -2983,21 +3029,6 @@ static void print_connection_info(SSL *con) (void)BIO_flush(bio_s_out); } -#ifndef OPENSSL_NO_DH -static DH *load_dh_param(const char *dhfile) -{ - DH *ret = NULL; - BIO *bio; - - if ((bio = BIO_new_file(dhfile, "r")) == NULL) - goto err; - ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); - err: - BIO_free(bio); - return ret; -} -#endif - static int www_body(int s, int stype, int prot, unsigned char *context) { char *buf = NULL; @@ -3010,12 +3041,21 @@ static int www_body(int s, int stype, int prot, unsigned char *context) int total_bytes = 0; #endif int width; +#ifndef OPENSSL_NO_KTLS + int use_sendfile_for_req = use_sendfile; +#endif fd_set readfds; + const char *opmode; +#ifdef CHARSET_EBCDIC + BIO *filter; +#endif /* Set width for a select call if needed */ width = s + 1; - buf = app_malloc(bufsize, "server www buffer"); + /* as we use BIO_gets(), and it always null terminates data, we need + * to allocate 1 byte longer buffer to fit the full 2^14 byte record */ + buf = app_malloc(bufsize + 1, "server www buffer"); io = BIO_new(BIO_f_buffer()); ssl_bio = BIO_new(BIO_f_ssl()); if ((io == NULL) || (ssl_bio == NULL)) @@ -3029,7 +3069,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context) } /* lets make the output buffer a reasonable size */ - if (!BIO_set_write_buffer_size(io, bufsize)) + if (BIO_set_write_buffer_size(io, bufsize) <= 0) goto err; if ((con = SSL_new(ctx)) == NULL) @@ -3048,10 +3088,21 @@ static int www_body(int s, int stype, int prot, unsigned char *context) } sbio = BIO_new_socket(s, BIO_NOCLOSE); + if (sbio == NULL) { + SSL_free(con); + goto err; + } + if (s_nbio_test) { BIO *test; test = BIO_new(BIO_f_nbio_test()); + if (test == NULL) { + SSL_free(con); + BIO_free(sbio); + goto err; + } + sbio = BIO_push(test, sbio); } SSL_set_bio(con, sbio, sbio); @@ -3060,12 +3111,17 @@ static int www_body(int s, int stype, int prot, unsigned char *context) /* No need to free |con| after this. Done by BIO_free(ssl_bio) */ BIO_set_ssl(ssl_bio, con, BIO_CLOSE); BIO_push(io, ssl_bio); + ssl_bio = NULL; #ifdef CHARSET_EBCDIC - io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io); + filter = BIO_new(BIO_f_ebcdic_filter()); + if (filter == NULL) + goto err; + + io = BIO_push(filter, io); #endif if (s_debug) { - BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); + BIO_set_callback_ex(SSL_get_rbio(con), bio_dump_callback); BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out); } if (s_msg) { @@ -3079,7 +3135,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context) } for (;;) { - i = BIO_gets(io, buf, bufsize - 1); + i = BIO_gets(io, buf, bufsize + 1); if (i < 0) { /* error */ if (!BIO_should_retry(io) && !SSL_waiting_for_async(con)) { if (!s_quiet) @@ -3091,21 +3147,13 @@ static int www_body(int s, int stype, int prot, unsigned char *context) if (BIO_should_io_special(io) && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) { BIO_printf(bio_s_out, "LOOKUP renego during read\n"); - SRP_user_pwd_free(srp_callback_parm.user); - srp_callback_parm.user = - SRP_VBASE_get1_by_user(srp_callback_parm.vb, - srp_callback_parm.login); - if (srp_callback_parm.user) - BIO_printf(bio_s_out, "LOOKUP done %s\n", - srp_callback_parm.user->info); - else - BIO_printf(bio_s_out, "LOOKUP not successful\n"); + + lookup_srp_user(&srp_callback_parm, bio_s_out); + continue; } #endif -#if !defined(OPENSSL_SYS_MSDOS) - sleep(1); -#endif + ossl_sleep(1000); continue; } } else if (i == 0) { /* end of input */ @@ -3152,7 +3200,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context) * we're expecting to come from the client. If they haven't * sent one there's not much we can do. */ - BIO_gets(io, buf, bufsize - 1); + BIO_gets(io, buf, bufsize + 1); } BIO_puts(io, @@ -3234,12 +3282,11 @@ static int www_body(int s, int stype, int prot, unsigned char *context) BIO_printf(io, "---\n"); print_stats(io, SSL_get_SSL_CTX(con)); BIO_printf(io, "---\n"); - peer = SSL_get_peer_certificate(con); + peer = SSL_get0_peer_certificate(con); if (peer != NULL) { BIO_printf(io, "Client certificate\n"); X509_print(io, peer); PEM_write_bio_X509(io, peer); - X509_free(peer); peer = NULL; } else { BIO_puts(io, "no client certificate available\n"); @@ -3310,9 +3357,10 @@ static int www_body(int s, int stype, int prot, unsigned char *context) break; } - if ((file = BIO_new_file(p, "r")) == NULL) { + opmode = (http_server_binmode == 1) ? "rb" : "r"; + if ((file = BIO_new_file(p, opmode)) == NULL) { BIO_puts(io, text); - BIO_printf(io, "Error opening '%s'\r\n", p); + BIO_printf(io, "Error opening '%s' mode='%s'\r\n", p, opmode); ERR_print_errors(io); break; } @@ -3332,38 +3380,83 @@ static int www_body(int s, int stype, int prot, unsigned char *context) "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"); } /* send the file */ - for (;;) { - i = BIO_read(file, buf, bufsize); - if (i <= 0) - break; +#ifndef OPENSSL_NO_KTLS + if (use_sendfile_for_req && !BIO_get_ktls_send(SSL_get_wbio(con))) { + BIO_printf(bio_err, "Warning: sendfile requested but KTLS is not available\n"); + use_sendfile_for_req = 0; + } + if (use_sendfile_for_req) { + FILE *fp = NULL; + int fd; + struct stat st; + off_t offset = 0; + size_t filesize; + + BIO_get_fp(file, &fp); + fd = fileno(fp); + if (fstat(fd, &st) < 0) { + BIO_printf(io, "Error fstat '%s'\r\n", p); + ERR_print_errors(io); + goto write_error; + } -#ifdef RENEG - total_bytes += i; - BIO_printf(bio_err, "%d\n", i); - if (total_bytes > 3 * 1024) { - total_bytes = 0; - BIO_printf(bio_err, "RENEGOTIATE\n"); - SSL_renegotiate(con); + filesize = st.st_size; + if (((int)BIO_flush(io)) < 0) + goto write_error; + + for (;;) { + i = SSL_sendfile(con, fd, offset, filesize, 0); + if (i < 0) { + BIO_printf(io, "Error SSL_sendfile '%s'\r\n", p); + ERR_print_errors(io); + break; + } else { + offset += i; + filesize -= i; + } + + if (filesize <= 0) { + if (!s_quiet) + BIO_printf(bio_err, "KTLS SENDFILE '%s' OK\n", p); + + break; + } } + } else #endif + { + for (;;) { + i = BIO_read(file, buf, bufsize); + if (i <= 0) + break; - for (j = 0; j < i;) { #ifdef RENEG - static count = 0; - if (++count == 13) { + total_bytes += i; + BIO_printf(bio_err, "%d\n", i); + if (total_bytes > 3 * 1024) { + total_bytes = 0; + BIO_printf(bio_err, "RENEGOTIATE\n"); SSL_renegotiate(con); } #endif - k = BIO_write(io, &(buf[j]), i - j); - if (k <= 0) { - if (!BIO_should_retry(io) - && !SSL_waiting_for_async(con)) - goto write_error; - else { - BIO_printf(bio_s_out, "rwrite W BLOCK\n"); + + for (j = 0; j < i;) { +#ifdef RENEG + static count = 0; + if (++count == 13) + SSL_renegotiate(con); +#endif + k = BIO_write(io, &(buf[j]), i - j); + if (k <= 0) { + if (!BIO_should_retry(io) + && !SSL_waiting_for_async(con)) { + goto write_error; + } else { + BIO_printf(bio_s_out, "rwrite W BLOCK\n"); + } + } else { + j += k; } - } else { - j += k; } } } @@ -3383,10 +3476,11 @@ static int www_body(int s, int stype, int prot, unsigned char *context) } end: /* make sure we re-use sessions */ - SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); + do_ssl_shutdown(con); err: OPENSSL_free(buf); + BIO_free(ssl_bio); BIO_free_all(io); return ret; } @@ -3398,15 +3492,20 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) int ret = 1; SSL *con; BIO *io, *ssl_bio, *sbio; +#ifdef CHARSET_EBCDIC + BIO *filter; +#endif - buf = app_malloc(bufsize, "server rev buffer"); + /* as we use BIO_gets(), and it always null terminates data, we need + * to allocate 1 byte longer buffer to fit the full 2^14 byte record */ + buf = app_malloc(bufsize + 1, "server rev buffer"); io = BIO_new(BIO_f_buffer()); ssl_bio = BIO_new(BIO_f_ssl()); if ((io == NULL) || (ssl_bio == NULL)) goto err; /* lets make the output buffer a reasonable size */ - if (!BIO_set_write_buffer_size(io, bufsize)) + if (BIO_set_write_buffer_size(io, bufsize) <= 0) goto err; if ((con = SSL_new(ctx)) == NULL) @@ -3425,18 +3524,29 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) } sbio = BIO_new_socket(s, BIO_NOCLOSE); + if (sbio == NULL) { + SSL_free(con); + ERR_print_errors(bio_err); + goto err; + } + SSL_set_bio(con, sbio, sbio); SSL_set_accept_state(con); /* No need to free |con| after this. Done by BIO_free(ssl_bio) */ BIO_set_ssl(ssl_bio, con, BIO_CLOSE); BIO_push(io, ssl_bio); + ssl_bio = NULL; #ifdef CHARSET_EBCDIC - io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io); + filter = BIO_new(BIO_f_ebcdic_filter()); + if (filter == NULL) + goto err; + + io = BIO_push(filter, io); #endif if (s_debug) { - BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); + BIO_set_callback_ex(SSL_get_rbio(con), bio_dump_callback); BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out); } if (s_msg) { @@ -3462,15 +3572,9 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) if (BIO_should_io_special(io) && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) { BIO_printf(bio_s_out, "LOOKUP renego during accept\n"); - SRP_user_pwd_free(srp_callback_parm.user); - srp_callback_parm.user = - SRP_VBASE_get1_by_user(srp_callback_parm.vb, - srp_callback_parm.login); - if (srp_callback_parm.user) - BIO_printf(bio_s_out, "LOOKUP done %s\n", - srp_callback_parm.user->info); - else - BIO_printf(bio_s_out, "LOOKUP not successful\n"); + + lookup_srp_user(&srp_callback_parm, bio_s_out); + continue; } #endif @@ -3479,7 +3583,7 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) print_ssl_summary(con); for (;;) { - i = BIO_gets(io, buf, bufsize - 1); + i = BIO_gets(io, buf, bufsize + 1); if (i < 0) { /* error */ if (!BIO_should_retry(io)) { if (!s_quiet) @@ -3491,21 +3595,13 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) if (BIO_should_io_special(io) && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) { BIO_printf(bio_s_out, "LOOKUP renego during read\n"); - SRP_user_pwd_free(srp_callback_parm.user); - srp_callback_parm.user = - SRP_VBASE_get1_by_user(srp_callback_parm.vb, - srp_callback_parm.login); - if (srp_callback_parm.user) - BIO_printf(bio_s_out, "LOOKUP done %s\n", - srp_callback_parm.user->info); - else - BIO_printf(bio_s_out, "LOOKUP not successful\n"); + + lookup_srp_user(&srp_callback_parm, bio_s_out); + continue; } #endif -#if !defined(OPENSSL_SYS_MSDOS) - sleep(1); -#endif + ossl_sleep(1000); continue; } } else if (i == 0) { /* end of input */ @@ -3537,11 +3633,12 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) } end: /* make sure we re-use sessions */ - SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); + do_ssl_shutdown(con); err: OPENSSL_free(buf); + BIO_free(ssl_bio); BIO_free_all(io); return ret; } @@ -3551,6 +3648,8 @@ static int generate_session_id(SSL *ssl, unsigned char *id, unsigned int *id_len) { unsigned int count = 0; + unsigned int session_id_prefix_len = strlen(session_id_prefix); + do { if (RAND_bytes(id, *id_len) <= 0) return 0; @@ -3562,8 +3661,8 @@ static int generate_session_id(SSL *ssl, unsigned char *id, * conflicts. */ memcpy(id, session_id_prefix, - (strlen(session_id_prefix) < *id_len) ? - strlen(session_id_prefix) : *id_len); + (session_id_prefix_len < *id_len) ? + session_id_prefix_len : *id_len); } while (SSL_has_matching_session_id(ssl, id, *id_len) && (++count < MAX_SESSION_ID_ATTEMPTS)); @@ -3574,7 +3673,7 @@ static int generate_session_id(SSL *ssl, unsigned char *id, /* * By default s_server uses an in-memory cache which caches SSL_SESSION - * structures without any serialisation. This hides some bugs which only + * structures without any serialization. This hides some bugs which only * become apparent in deployed servers. By implementing a basic external * session cache some issues can be debugged using s_server. */ diff --git a/crypto/openssl/apps/s_time.c b/crypto/openssl/apps/s_time.c index 1235e545c20a..1a58e19de53f 100644 --- a/crypto/openssl/apps/s_time.c +++ b/crypto/openssl/apps/s_time.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -22,9 +22,9 @@ #include #include "s_apps.h" #include -#include +#include "internal/sockets.h" #if !defined(OPENSSL_SYS_MSDOS) -# include OPENSSL_UNISTD +# include #endif #define SSL_CONNECT_NAME "localhost:4433" @@ -43,40 +43,64 @@ static const char fmt_http_get_cmd[] = "GET %s HTTP/1.0\r\n\r\n"; static const size_t fmt_http_get_cmd_size = sizeof(fmt_http_get_cmd) - 2; typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_CONNECT, OPT_CIPHER, OPT_CIPHERSUITES, OPT_CERT, OPT_NAMEOPT, OPT_KEY, - OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NEW, OPT_REUSE, - OPT_BUGS, OPT_VERIFY, OPT_TIME, OPT_SSL3, - OPT_WWW + OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, + OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, + OPT_NEW, OPT_REUSE, OPT_BUGS, OPT_VERIFY, OPT_TIME, OPT_SSL3, + OPT_WWW, OPT_TLS1, OPT_TLS1_1, OPT_TLS1_2, OPT_TLS1_3, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS s_time_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Connection"), {"connect", OPT_CONNECT, 's', "Where to connect as post:port (default is " SSL_CONNECT_NAME ")"}, + {"new", OPT_NEW, '-', "Just time new connections"}, + {"reuse", OPT_REUSE, '-', "Just time connection reuse"}, + {"bugs", OPT_BUGS, '-', "Turn on SSL bug compatibility"}, {"cipher", OPT_CIPHER, 's', "TLSv1.2 and below cipher list to be used"}, {"ciphersuites", OPT_CIPHERSUITES, 's', "Specify TLSv1.3 ciphersuites to be used"}, +#ifndef OPENSSL_NO_SSL3 + {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, +#endif +#ifndef OPENSSL_NO_TLS1 + {"tls1", OPT_TLS1, '-', "Just use TLSv1.0"}, +#endif +#ifndef OPENSSL_NO_TLS1_1 + {"tls1_1", OPT_TLS1_1, '-', "Just use TLSv1.1"}, +#endif +#ifndef OPENSSL_NO_TLS1_2 + {"tls1_2", OPT_TLS1_2, '-', "Just use TLSv1.2"}, +#endif +#ifndef OPENSSL_NO_TLS1_3 + {"tls1_3", OPT_TLS1_3, '-', "Just use TLSv1.3"}, +#endif + {"verify", OPT_VERIFY, 'p', + "Turn on peer certificate verification, set depth"}, + {"time", OPT_TIME, 'p', "Seconds to collect data, default " SECONDSSTR}, + {"www", OPT_WWW, 's', "Fetch specified page from the site"}, + + OPT_SECTION("Certificate"), + {"nameopt", OPT_NAMEOPT, 's', "Certificate subject/issuer name printing options"}, {"cert", OPT_CERT, '<', "Cert file to use, PEM format assumed"}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, {"key", OPT_KEY, '<', "File with key, PEM; default is -cert file"}, - {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, {"cafile", OPT_CAFILE, '<', "PEM format file of CA's"}, {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, + {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, - {"new", OPT_NEW, '-', "Just time new connections"}, - {"reuse", OPT_REUSE, '-', "Just time connection reuse"}, - {"bugs", OPT_BUGS, '-', "Turn on SSL bug compatibility"}, - {"verify", OPT_VERIFY, 'p', - "Turn on peer certificate verification, set depth"}, - {"time", OPT_TIME, 'p', "Seconds to collect data, default " SECONDSSTR}, - {"www", OPT_WWW, 's', "Fetch specified page from the site"}, -#ifndef OPENSSL_NO_SSL3 - {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, -#endif + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store URI"}, + + OPT_PROV_OPTIONS, {NULL} }; @@ -94,15 +118,16 @@ int s_time_main(int argc, char **argv) SSL *scon = NULL; SSL_CTX *ctx = NULL; const SSL_METHOD *meth = NULL; - char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *ciphersuites = NULL; + char *CApath = NULL, *CAfile = NULL, *CAstore = NULL; + char *cipher = NULL, *ciphersuites = NULL; char *www_path = NULL; char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog; double totalTime = 0.0; - int noCApath = 0, noCAfile = 0; + int noCApath = 0, noCAfile = 0, noCAstore = 0; int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs = 0; long bytes_read = 0, finishtime = 0; OPTION_CHOICE o; - int max_version = 0, ver, buf_len; + int min_version = 0, max_version = 0, ver, buf_len, fd; size_t buf_size; meth = TLS_client_method(); @@ -129,8 +154,7 @@ int s_time_main(int argc, char **argv) perform = 1; break; case OPT_VERIFY: - if (!opt_int(opt_arg(), &verify_args.depth)) - goto opthelp; + verify_args.depth = opt_int_arg(); BIO_printf(bio_err, "%s: verify depth is %d\n", prog, verify_args.depth); break; @@ -156,6 +180,12 @@ int s_time_main(int argc, char **argv) case OPT_NOCAFILE: noCAfile = 1; break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_CIPHER: cipher = opt_arg(); break; @@ -166,8 +196,7 @@ int s_time_main(int argc, char **argv) st_bugs = 1; break; case OPT_TIME: - if (!opt_int(opt_arg(), &maxtime)) - goto opthelp; + maxtime = opt_int_arg(); break; case OPT_WWW: www_path = opt_arg(); @@ -178,10 +207,33 @@ int s_time_main(int argc, char **argv) } break; case OPT_SSL3: + min_version = SSL3_VERSION; max_version = SSL3_VERSION; break; + case OPT_TLS1: + min_version = TLS1_VERSION; + max_version = TLS1_VERSION; + break; + case OPT_TLS1_1: + min_version = TLS1_1_VERSION; + max_version = TLS1_1_VERSION; + break; + case OPT_TLS1_2: + min_version = TLS1_2_VERSION; + max_version = TLS1_2_VERSION; + break; + case OPT_TLS1_3: + min_version = TLS1_3_VERSION; + max_version = TLS1_3_VERSION; + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; @@ -192,8 +244,9 @@ int s_time_main(int argc, char **argv) if ((ctx = SSL_CTX_new(meth)) == NULL) goto end; - SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_quiet_shutdown(ctx, 1); + if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0) + goto end; if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0) goto end; @@ -206,7 +259,8 @@ int s_time_main(int argc, char **argv) if (!set_cert_stuff(ctx, certfile, keyfile)) goto end; - if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { + if (!ctx_set_verify_locations(ctx, CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) { ERR_print_errors(bio_err); goto end; } @@ -289,7 +343,8 @@ int s_time_main(int argc, char **argv) continue; } SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); - BIO_closesocket(SSL_get_fd(scon)); + if ((fd = SSL_get_fd(scon)) >= 0) + BIO_closesocket(fd); nConn = 0; totalTime = 0.0; @@ -316,7 +371,8 @@ int s_time_main(int argc, char **argv) bytes_read += i; } SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); - BIO_closesocket(SSL_get_fd(scon)); + if ((fd = SSL_get_fd(scon)) >= 0) + BIO_closesocket(fd); nConn += 1; if (SSL_session_reused(scon)) { @@ -338,10 +394,13 @@ int s_time_main(int argc, char **argv) printf ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn / totalTime), bytes_read); - printf - ("%d connections in %ld real seconds, %ld bytes read per connection\n", - nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn); - + if (nConn > 0) + printf + ("%d connections in %ld real seconds, %ld bytes read per connection\n", + nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn); + else + printf("0 connections in %ld real seconds\n", + (long)time(NULL) - finishtime + maxtime); ret = 0; end: @@ -362,12 +421,19 @@ static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx) if ((conn = BIO_new(BIO_s_connect())) == NULL) return NULL; - BIO_set_conn_hostname(conn, host); - BIO_set_conn_mode(conn, BIO_SOCK_NODELAY); + if (BIO_set_conn_hostname(conn, host) <= 0 + || BIO_set_conn_mode(conn, BIO_SOCK_NODELAY) <= 0) { + BIO_free(conn); + return NULL; + } - if (scon == NULL) + if (scon == NULL) { serverCon = SSL_new(ctx); - else { + if (serverCon == NULL) { + BIO_free(conn); + return NULL; + } + } else { serverCon = scon; SSL_set_connect_state(serverCon); } diff --git a/crypto/openssl/apps/sess_id.c b/crypto/openssl/apps/sess_id.c index 8fd584f3b131..714c0f77877e 100644 --- a/crypto/openssl/apps/sess_id.c +++ b/crypto/openssl/apps/sess_id.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,22 +19,27 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_CERT, OPT_NOOUT, OPT_CONTEXT } OPTION_CHOICE; const OPTIONS sess_id_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"context", OPT_CONTEXT, 's', "Set the session ID context"}, + + OPT_SECTION("Input"), + {"in", OPT_IN, 's', "Input file - default stdin"}, {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file - default stdout"}, {"outform", OPT_OUTFORM, 'f', "Output format - default PEM (PEM, DER or NSS)"}, - {"in", OPT_IN, 's', "Input file - default stdin"}, - {"out", OPT_OUT, '>', "Output file - default stdout"}, {"text", OPT_TEXT, '-', "Print ssl session id details"}, {"cert", OPT_CERT, '-', "Output certificate "}, {"noout", OPT_NOOUT, '-', "Don't output the encoded session info"}, - {"context", OPT_CONTEXT, 's', "Set the session ID context"}, {NULL} }; @@ -91,6 +96,8 @@ int sess_id_main(int argc, char **argv) break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; diff --git a/crypto/openssl/apps/smime.c b/crypto/openssl/apps/smime.c index 6fd473775f45..a2ff0b5be75c 100644 --- a/crypto/openssl/apps/smime.c +++ b/crypto/openssl/apps/smime.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -33,7 +33,7 @@ static int smime_cb(int ok, X509_STORE_CTX *ctx); #define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_ENCRYPT, OPT_DECRYPT, OPT_SIGN, OPT_RESIGN, OPT_VERIFY, OPT_PK7OUT, OPT_TEXT, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCHAIN, OPT_NOCERTS, OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP, @@ -41,76 +41,97 @@ typedef enum OPTION_choice { OPT_CRLFEOL, OPT_ENGINE, OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_MD, OPT_CIPHER, OPT_INKEY, OPT_KEYFORM, OPT_CERTFILE, OPT_CAFILE, - OPT_R_ENUM, + OPT_CAPATH, OPT_CASTORE, OPT_NOCAFILE, OPT_NOCAPATH, OPT_NOCASTORE, + OPT_R_ENUM, OPT_PROV_ENUM, OPT_CONFIG, OPT_V_ENUM, - OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH, OPT_IN, OPT_INFORM, OPT_OUT, + OPT_IN, OPT_INFORM, OPT_OUT, OPT_OUTFORM, OPT_CONTENT } OPTION_CHOICE; const OPTIONS smime_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"}, - {OPT_HELP_STR, 1, '-', - " cert.pem... recipient certs for encryption\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Input file"}, + {"inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER"}, + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'c', + "Output format SMIME (default), PEM or DER"}, + {"inkey", OPT_INKEY, 's', + "Input private key (if not signer or recipient)"}, + {"keyform", OPT_KEYFORM, 'f', "Input private key format (ENGINE, other values ignored)"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {"stream", OPT_STREAM, '-', "Enable CMS streaming" }, + {"indef", OPT_INDEF, '-', "Same as -stream" }, + {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"}, + OPT_CONFIG_OPTION, + + OPT_SECTION("Action"), {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"}, {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"}, {"sign", OPT_SIGN, '-', "Sign message"}, + {"resign", OPT_RESIGN, '-', "Resign a signed message"}, {"verify", OPT_VERIFY, '-', "Verify signed message"}, + + OPT_SECTION("Signing/Encryption"), + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, {"pk7out", OPT_PK7OUT, '-', "Output PKCS#7 structure"}, {"nointern", OPT_NOINTERN, '-', "Don't search certificates in message for signer"}, - {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"}, - {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"}, - {"nocerts", OPT_NOCERTS, '-', - "Don't include signers certificate when signing"}, {"nodetach", OPT_NODETACH, '-', "Use opaque signing"}, {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"}, {"binary", OPT_BINARY, '-', "Don't translate message to text"}, - {"certfile", OPT_CERTFILE, '<', "Other certificates file"}, {"signer", OPT_SIGNER, 's', "Signer certificate file"}, - {"recip", OPT_RECIP, '<', "Recipient certificate file for decryption"}, - {"in", OPT_IN, '<', "Input file"}, - {"inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER"}, - {"inkey", OPT_INKEY, 's', - "Input private key (if not signer or recipient)"}, - {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"}, - {"out", OPT_OUT, '>', "Output file"}, - {"outform", OPT_OUTFORM, 'c', - "Output format SMIME (default), PEM or DER"}, {"content", OPT_CONTENT, '<', "Supply or override content for detached signature"}, + {"nocerts", OPT_NOCERTS, '-', + "Don't include signers certificate when signing"}, + + OPT_SECTION("Verification/Decryption"), + {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"}, + {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"}, + + {"certfile", OPT_CERTFILE, '<', "Other certificates file"}, + {"recip", OPT_RECIP, '<', "Recipient certificate file for decryption"}, + + OPT_SECTION("Email"), {"to", OPT_TO, 's', "To address"}, {"from", OPT_FROM, 's', "From address"}, {"subject", OPT_SUBJECT, 's', "Subject"}, {"text", OPT_TEXT, '-', "Include or delete text MIME headers"}, + {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"}, + + OPT_SECTION("Certificate chain"), {"CApath", OPT_CAPATH, '/', "Trusted certificates directory"}, {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, + {"CAstore", OPT_CASTORE, ':', "Trusted certificates store URI"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, - {"resign", OPT_RESIGN, '-', "Resign a signed message"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store"}, {"nochain", OPT_NOCHAIN, '-', "set PKCS7_NOCHAIN so certificates contained in the message are not used as untrusted CAs" }, - {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"}, - {"stream", OPT_STREAM, '-', "Enable CMS streaming" }, - {"indef", OPT_INDEF, '-', "Same as -stream" }, - {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"}, {"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only"}, + OPT_R_OPTIONS, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"}, - {"", OPT_CIPHER, '-', "Any supported cipher"}, OPT_V_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"cert", 0, 0, "Recipient certs, used when encrypting"}, {NULL} }; int smime_main(int argc, char **argv) { + CONF *conf = NULL; BIO *in = NULL, *out = NULL, *indata = NULL; EVP_PKEY *key = NULL; PKCS7 *p7 = NULL; @@ -119,20 +140,22 @@ int smime_main(int argc, char **argv) X509 *cert = NULL, *recip = NULL, *signer = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; - const EVP_CIPHER *cipher = NULL; - const EVP_MD *sign_md = NULL; - const char *CAfile = NULL, *CApath = NULL, *prog = NULL; + EVP_CIPHER *cipher = NULL; + EVP_MD *sign_md = NULL; + const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL, *prog = NULL; char *certfile = NULL, *keyfile = NULL, *contfile = NULL; char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile = NULL; - char *passinarg = NULL, *passin = NULL, *to = NULL, *from = NULL, *subject = NULL; + char *passinarg = NULL, *passin = NULL, *to = NULL, *from = NULL; + char *subject = NULL, *digestname = NULL, *ciphername = NULL; OPTION_CHOICE o; - int noCApath = 0, noCAfile = 0; + int noCApath = 0, noCAfile = 0, noCAstore = 0; int flags = PKCS7_DETACHED, operation = 0, ret = 0, indef = 0; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME, keyform = - FORMAT_PEM; + FORMAT_UNDEF; int vpmtouched = 0, rv = 0; ENGINE *e = NULL; const char *mime_eol = "\n"; + OSSL_LIB_CTX *libctx = app_get0_libctx(); if ((vpm = X509_VERIFY_PARAM_new()) == NULL) return 1; @@ -226,6 +249,15 @@ int smime_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; + case OPT_CONFIG: + conf = app_load_config_modules(opt_arg()); + if (conf == NULL) + goto end; + break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; @@ -262,12 +294,10 @@ int smime_main(int argc, char **argv) recipfile = opt_arg(); break; case OPT_MD: - if (!opt_md(opt_arg(), &sign_md)) - goto opthelp; + digestname = opt_arg(); break; case OPT_CIPHER: - if (!opt_cipher(opt_unknown(), &cipher)) - goto opthelp; + ciphername = opt_unknown(); break; case OPT_INKEY: /* If previous -inkey argument add signer to list */ @@ -302,12 +332,18 @@ int smime_main(int argc, char **argv) case OPT_CAPATH: CApath = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_NOCAFILE: noCAfile = 1; break; case OPT_NOCAPATH: noCApath = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_CONTENT: contfile = opt_arg(); break; @@ -318,13 +354,31 @@ int smime_main(int argc, char **argv) break; } } + + /* Extra arguments are files with recipient keys. */ argc = opt_num_rest(); argv = opt_rest(); + if (!app_RAND_load()) + goto end; + + if (digestname != NULL) { + if (!opt_md(digestname, &sign_md)) + goto opthelp; + } + if (ciphername != NULL) { + if (!opt_cipher_any(ciphername, &cipher)) + goto opthelp; + } if (!(operation & SMIME_SIGNERS) && (skkeys != NULL || sksigners != NULL)) { BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); goto opthelp; } + if (!operation) { + BIO_puts(bio_err, + "No operation (-encrypt|-sign|...) specified\n"); + goto opthelp; + } if (operation & SMIME_SIGNERS) { /* Check to see if any final signer needs to be appended */ @@ -360,8 +414,6 @@ int smime_main(int argc, char **argv) BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); goto opthelp; } - } else if (!operation) { - goto opthelp; } if (!app_passwd(passinarg, NULL, &passin, NULL)) { @@ -387,7 +439,7 @@ int smime_main(int argc, char **argv) if (operation == SMIME_ENCRYPT) { if (cipher == NULL) { #ifndef OPENSSL_NO_DES - cipher = EVP_des_ede3_cbc(); + cipher = (EVP_CIPHER *)EVP_des_ede3_cbc(); #else BIO_printf(bio_err, "No cipher selected\n"); goto end; @@ -397,7 +449,7 @@ int smime_main(int argc, char **argv) if (encerts == NULL) goto end; while (*argv != NULL) { - cert = load_cert(*argv, FORMAT_PEM, + cert = load_cert(*argv, FORMAT_UNDEF, "recipient certificate file"); if (cert == NULL) goto end; @@ -408,15 +460,14 @@ int smime_main(int argc, char **argv) } if (certfile != NULL) { - if (!load_certs(certfile, &other, FORMAT_PEM, NULL, - "certificate file")) { + if (!load_certs(certfile, 0, &other, NULL, "certificates")) { ERR_print_errors(bio_err); goto end; } } if (recipfile != NULL && (operation == SMIME_DECRYPT)) { - if ((recip = load_cert(recipfile, FORMAT_PEM, + if ((recip = load_cert(recipfile, FORMAT_UNDEF, "recipient certificate file")) == NULL) { ERR_print_errors(bio_err); goto end; @@ -434,7 +485,7 @@ int smime_main(int argc, char **argv) } if (keyfile != NULL) { - key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key"); if (key == NULL) goto end; } @@ -444,18 +495,25 @@ int smime_main(int argc, char **argv) goto end; if (operation & SMIME_IP) { + PKCS7 *p7_in = NULL; + + p7 = PKCS7_new_ex(libctx, app_get0_propq()); + if (p7 == NULL) { + BIO_printf(bio_err, "Error allocating PKCS7 object\n"); + goto end; + } if (informat == FORMAT_SMIME) { - p7 = SMIME_read_PKCS7(in, &indata); + p7_in = SMIME_read_PKCS7_ex(in, &indata, &p7); } else if (informat == FORMAT_PEM) { - p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); + p7_in = PEM_read_bio_PKCS7(in, &p7, NULL, NULL); } else if (informat == FORMAT_ASN1) { - p7 = d2i_PKCS7_bio(in, NULL); + p7_in = d2i_PKCS7_bio(in, &p7); } else { BIO_printf(bio_err, "Bad input format for PKCS#7 file\n"); goto end; } - if (p7 == NULL) { + if (p7_in == NULL) { BIO_printf(bio_err, "Error reading S/MIME message\n"); goto end; } @@ -473,7 +531,8 @@ int smime_main(int argc, char **argv) goto end; if (operation == SMIME_VERIFY) { - if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) + if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) == NULL) goto end; X509_STORE_set_verify_cb(store, smime_cb); if (vpmtouched) @@ -485,7 +544,7 @@ int smime_main(int argc, char **argv) if (operation == SMIME_ENCRYPT) { if (indef) flags |= PKCS7_STREAM; - p7 = PKCS7_encrypt(encerts, in, cipher, flags); + p7 = PKCS7_encrypt_ex(encerts, in, cipher, flags, libctx, app_get0_propq()); } else if (operation & SMIME_SIGNERS) { int i; /* @@ -500,7 +559,7 @@ int smime_main(int argc, char **argv) flags |= PKCS7_STREAM; } flags |= PKCS7_PARTIAL; - p7 = PKCS7_sign(NULL, NULL, other, in, flags); + p7 = PKCS7_sign_ex(NULL, NULL, other, in, flags, libctx, app_get0_propq()); if (p7 == NULL) goto end; if (flags & PKCS7_NOCERTS) { @@ -515,13 +574,13 @@ int smime_main(int argc, char **argv) for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); - signer = load_cert(signerfile, FORMAT_PEM, - "signer certificate"); + signer = load_cert(signerfile, FORMAT_UNDEF, "signer certificate"); if (signer == NULL) goto end; - key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key"); if (key == NULL) goto end; + if (!PKCS7_sign_add_signer(p7, signer, key, sign_md, flags)) goto end; X509_free(signer); @@ -604,12 +663,15 @@ int smime_main(int argc, char **argv) X509_free(recip); X509_free(signer); EVP_PKEY_free(key); + EVP_MD_free(sign_md); + EVP_CIPHER_free(cipher); PKCS7_free(p7); release_engine(e); BIO_free(in); BIO_free(indata); BIO_free_all(out); OPENSSL_free(passin); + NCONF_free(conf); return ret; } diff --git a/crypto/openssl/apps/speed.c b/crypto/openssl/apps/speed.c index 89bf18480fa1..addf7e32137f 100644 --- a/crypto/openssl/apps/speed.c +++ b/crypto/openssl/apps/speed.c @@ -1,20 +1,27 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 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 + * 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 */ #undef SECONDS -#define SECONDS 3 -#define RSA_SECONDS 10 -#define DSA_SECONDS 10 -#define ECDSA_SECONDS 10 -#define ECDH_SECONDS 10 -#define EdDSA_SECONDS 10 +#define SECONDS 3 +#define PKEY_SECONDS 10 + +#define RSA_SECONDS PKEY_SECONDS +#define DSA_SECONDS PKEY_SECONDS +#define ECDSA_SECONDS PKEY_SECONDS +#define ECDH_SECONDS PKEY_SECONDS +#define EdDSA_SECONDS PKEY_SECONDS +#define SM2_SECONDS PKEY_SECONDS +#define FFDH_SECONDS PKEY_SECONDS + +/* We need to use some deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED #include #include @@ -22,14 +29,22 @@ #include #include "apps.h" #include "progs.h" +#include "internal/numbers.h" #include #include #include #include #include +#include #include #if !defined(OPENSSL_SYS_MSDOS) -# include OPENSSL_UNISTD +# include +#endif + +#if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif #endif #if defined(_WIN32) @@ -37,66 +52,14 @@ #endif #include -#ifndef OPENSSL_NO_DES -# include -#endif -#include -#ifndef OPENSSL_NO_CAMELLIA -# include -#endif -#ifndef OPENSSL_NO_MD2 -# include -#endif -#ifndef OPENSSL_NO_MDC2 -# include -#endif -#ifndef OPENSSL_NO_MD4 -# include -#endif -#ifndef OPENSSL_NO_MD5 -# include -#endif -#include -#include -#ifndef OPENSSL_NO_RMD160 -# include -#endif -#ifndef OPENSSL_NO_WHIRLPOOL -# include -#endif -#ifndef OPENSSL_NO_RC4 -# include -#endif -#ifndef OPENSSL_NO_RC5 -# include -#endif -#ifndef OPENSSL_NO_RC2 -# include -#endif -#ifndef OPENSSL_NO_IDEA -# include -#endif -#ifndef OPENSSL_NO_SEED -# include -#endif -#ifndef OPENSSL_NO_BF -# include -#endif -#ifndef OPENSSL_NO_CAST -# include -#endif -#ifndef OPENSSL_NO_RSA -# include -# include "./testrsa.h" +#include +#include "./testrsa.h" +#ifndef OPENSSL_NO_DH +# include #endif #include -#ifndef OPENSSL_NO_DSA -# include -# include "./testdsa.h" -#endif -#ifndef OPENSSL_NO_EC -# include -#endif +#include +#include "./testdsa.h" #include #ifndef HAVE_FORK @@ -104,6 +67,7 @@ # define HAVE_FORK 0 # else # define HAVE_FORK 1 +# include # endif #endif @@ -116,6 +80,11 @@ #define MAX_MISALIGNMENT 63 #define MAX_ECDH_SIZE 256 #define MISALIGN 64 +#define MAX_FFDH_SIZE 1024 + +#ifndef RSA_DEFAULT_PRIME_NUM +# define RSA_DEFAULT_PRIME_NUM 2 +#endif typedef struct openssl_speed_sec_st { int sym; @@ -124,70 +93,15 @@ typedef struct openssl_speed_sec_st { int ecdsa; int ecdh; int eddsa; + int sm2; + int ffdh; } openssl_speed_sec_t; static volatile int run = 0; -static int mr = 0; +static int mr = 0; /* machine-readeable output format to merge fork results */ static int usertime = 1; -#ifndef OPENSSL_NO_MD2 -static int EVP_Digest_MD2_loop(void *args); -#endif - -#ifndef OPENSSL_NO_MDC2 -static int EVP_Digest_MDC2_loop(void *args); -#endif -#ifndef OPENSSL_NO_MD4 -static int EVP_Digest_MD4_loop(void *args); -#endif -#ifndef OPENSSL_NO_MD5 -static int MD5_loop(void *args); -static int HMAC_loop(void *args); -#endif -static int SHA1_loop(void *args); -static int SHA256_loop(void *args); -static int SHA512_loop(void *args); -#ifndef OPENSSL_NO_WHIRLPOOL -static int WHIRLPOOL_loop(void *args); -#endif -#ifndef OPENSSL_NO_RMD160 -static int EVP_Digest_RMD160_loop(void *args); -#endif -#ifndef OPENSSL_NO_RC4 -static int RC4_loop(void *args); -#endif -#ifndef OPENSSL_NO_DES -static int DES_ncbc_encrypt_loop(void *args); -static int DES_ede3_cbc_encrypt_loop(void *args); -#endif -static int AES_cbc_128_encrypt_loop(void *args); -static int AES_cbc_192_encrypt_loop(void *args); -static int AES_ige_128_encrypt_loop(void *args); -static int AES_cbc_256_encrypt_loop(void *args); -static int AES_ige_192_encrypt_loop(void *args); -static int AES_ige_256_encrypt_loop(void *args); -static int CRYPTO_gcm128_aad_loop(void *args); -static int RAND_bytes_loop(void *args); -static int EVP_Update_loop(void *args); -static int EVP_Update_loop_ccm(void *args); -static int EVP_Update_loop_aead(void *args); -static int EVP_Digest_loop(void *args); -#ifndef OPENSSL_NO_RSA -static int RSA_sign_loop(void *args); -static int RSA_verify_loop(void *args); -#endif -#ifndef OPENSSL_NO_DSA -static int DSA_sign_loop(void *args); -static int DSA_verify_loop(void *args); -#endif -#ifndef OPENSSL_NO_EC -static int ECDSA_sign_loop(void *args); -static int ECDSA_verify_loop(void *args); -static int EdDSA_sign_loop(void *args); -static int EdDSA_verify_loop(void *args); -#endif - static double Time_F(int s); static void print_message(const char *s, long num, int length, int tm); static void pkey_print_message(const char *str, const char *str2, @@ -200,6 +114,7 @@ static int do_multi(int multi, int size_num); static const int lengths_list[] = { 16, 64, 256, 1024, 8 * 1024, 16 * 1024 }; +#define SIZE_NUM OSSL_NELEM(lengths_list) static const int *lengths = lengths_list; static const int aead_lengths_list[] = { @@ -272,17 +187,12 @@ static double Time_F(int s) return ret; } #else -static double Time_F(int s) -{ - return app_tminterval(s, usertime); -} +# error "SIGALRM not defined and the platform is not Windows" #endif static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, const openssl_speed_sec_t *seconds); -#define found(value, pairs, result)\ - opt_found(value, result, pairs, OSSL_NELEM(pairs)) static int opt_found(const char *name, unsigned int *result, const OPT_PAIR pairs[], unsigned int nbelem) { @@ -295,23 +205,21 @@ static int opt_found(const char *name, unsigned int *result, } return 0; } +#define opt_found(value, pairs, result)\ + opt_found(value, result, pairs, OSSL_NELEM(pairs)) typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_ELAPSED, OPT_EVP, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI, - OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, - OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD + OPT_COMMON, + OPT_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI, + OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, OPT_PROV_ENUM, + OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC } OPTION_CHOICE; const OPTIONS speed_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] ciphers...\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [algorithm...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"}, - {"decrypt", OPT_DECRYPT, '-', - "Time decryption instead of encryption (only EVP)"}, - {"aead", OPT_AEAD, '-', - "Benchmark EVP-named AEAD cipher in TLS-like sequence"}, {"mb", OPT_MB, '-', "Enable (tls1>=1) multi-block mode on EVP-named cipher"}, {"mr", OPT_MR, '-', "Produce machine readable output"}, @@ -322,160 +230,114 @@ const OPTIONS speed_options[] = { {"async_jobs", OPT_ASYNCJOBS, 'p', "Enable async mode and start specified number of jobs"}, #endif - OPT_R_OPTIONS, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"}, + + OPT_SECTION("Selection"), + {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"}, + {"hmac", OPT_HMAC, 's', "HMAC using EVP-named digest"}, + {"cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher"}, + {"decrypt", OPT_DECRYPT, '-', + "Time decryption instead of encryption (only EVP)"}, + {"aead", OPT_AEAD, '-', + "Benchmark EVP-named AEAD cipher in TLS-like sequence"}, + + OPT_SECTION("Timing"), {"elapsed", OPT_ELAPSED, '-', "Use wall-clock time instead of CPU user time as divisor"}, - {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"}, {"seconds", OPT_SECONDS, 'p', "Run benchmarks for specified amount of seconds"}, {"bytes", OPT_BYTES, 'p', "Run [non-PKI] benchmarks on custom-sized buffer"}, {"misalign", OPT_MISALIGN, 'p', "Use specified offset to mis-align buffers"}, + + OPT_R_OPTIONS, + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"}, {NULL} }; -#define D_MD2 0 -#define D_MDC2 1 -#define D_MD4 2 -#define D_MD5 3 -#define D_HMAC 4 -#define D_SHA1 5 -#define D_RMD160 6 -#define D_RC4 7 -#define D_CBC_DES 8 -#define D_EDE3_DES 9 -#define D_CBC_IDEA 10 -#define D_CBC_SEED 11 -#define D_CBC_RC2 12 -#define D_CBC_RC5 13 -#define D_CBC_BF 14 -#define D_CBC_CAST 15 -#define D_CBC_128_AES 16 -#define D_CBC_192_AES 17 -#define D_CBC_256_AES 18 -#define D_CBC_128_CML 19 -#define D_CBC_192_CML 20 -#define D_CBC_256_CML 21 -#define D_EVP 22 -#define D_SHA256 23 -#define D_SHA512 24 -#define D_WHIRLPOOL 25 -#define D_IGE_128_AES 26 -#define D_IGE_192_AES 27 -#define D_IGE_256_AES 28 -#define D_GHASH 29 -#define D_RAND 30 -/* name of algorithms to test */ -static const char *names[] = { - "md2", "mdc2", "md4", "md5", "hmac(md5)", "sha1", "rmd160", "rc4", - "des cbc", "des ede3", "idea cbc", "seed cbc", - "rc2 cbc", "rc5-32/12 cbc", "blowfish cbc", "cast cbc", - "aes-128 cbc", "aes-192 cbc", "aes-256 cbc", - "camellia-128 cbc", "camellia-192 cbc", "camellia-256 cbc", - "evp", "sha256", "sha512", "whirlpool", - "aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash", - "rand" +enum { + D_MD2, D_MDC2, D_MD4, D_MD5, D_SHA1, D_RMD160, + D_SHA256, D_SHA512, D_WHIRLPOOL, D_HMAC, + D_CBC_DES, D_EDE3_DES, D_RC4, D_CBC_IDEA, D_CBC_SEED, + D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST, + D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES, + D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML, + D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, ALGOR_NUM +}; +/* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */ +static const char *names[ALGOR_NUM] = { + "md2", "mdc2", "md4", "md5", "sha1", "rmd160", + "sha256", "sha512", "whirlpool", "hmac(md5)", + "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc", + "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc", + "aes-128-cbc", "aes-192-cbc", "aes-256-cbc", + "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc", + "evp", "ghash", "rand", "cmac" }; -#define ALGOR_NUM OSSL_NELEM(names) -/* list of configured algorithm (remaining) */ +/* list of configured algorithm (remaining), with some few alias */ static const OPT_PAIR doit_choices[] = { -#ifndef OPENSSL_NO_MD2 {"md2", D_MD2}, -#endif -#ifndef OPENSSL_NO_MDC2 {"mdc2", D_MDC2}, -#endif -#ifndef OPENSSL_NO_MD4 {"md4", D_MD4}, -#endif -#ifndef OPENSSL_NO_MD5 {"md5", D_MD5}, {"hmac", D_HMAC}, -#endif {"sha1", D_SHA1}, {"sha256", D_SHA256}, {"sha512", D_SHA512}, -#ifndef OPENSSL_NO_WHIRLPOOL {"whirlpool", D_WHIRLPOOL}, -#endif -#ifndef OPENSSL_NO_RMD160 {"ripemd", D_RMD160}, {"rmd160", D_RMD160}, {"ripemd160", D_RMD160}, -#endif -#ifndef OPENSSL_NO_RC4 {"rc4", D_RC4}, -#endif -#ifndef OPENSSL_NO_DES {"des-cbc", D_CBC_DES}, {"des-ede3", D_EDE3_DES}, -#endif {"aes-128-cbc", D_CBC_128_AES}, {"aes-192-cbc", D_CBC_192_AES}, {"aes-256-cbc", D_CBC_256_AES}, - {"aes-128-ige", D_IGE_128_AES}, - {"aes-192-ige", D_IGE_192_AES}, - {"aes-256-ige", D_IGE_256_AES}, -#ifndef OPENSSL_NO_RC2 + {"camellia-128-cbc", D_CBC_128_CML}, + {"camellia-192-cbc", D_CBC_192_CML}, + {"camellia-256-cbc", D_CBC_256_CML}, {"rc2-cbc", D_CBC_RC2}, {"rc2", D_CBC_RC2}, -#endif -#ifndef OPENSSL_NO_RC5 {"rc5-cbc", D_CBC_RC5}, {"rc5", D_CBC_RC5}, -#endif -#ifndef OPENSSL_NO_IDEA {"idea-cbc", D_CBC_IDEA}, {"idea", D_CBC_IDEA}, -#endif -#ifndef OPENSSL_NO_SEED {"seed-cbc", D_CBC_SEED}, {"seed", D_CBC_SEED}, -#endif -#ifndef OPENSSL_NO_BF {"bf-cbc", D_CBC_BF}, {"blowfish", D_CBC_BF}, {"bf", D_CBC_BF}, -#endif -#ifndef OPENSSL_NO_CAST {"cast-cbc", D_CBC_CAST}, {"cast", D_CBC_CAST}, {"cast5", D_CBC_CAST}, -#endif {"ghash", D_GHASH}, {"rand", D_RAND} }; -static double results[ALGOR_NUM][OSSL_NELEM(lengths_list)]; +static double results[ALGOR_NUM][SIZE_NUM]; -#ifndef OPENSSL_NO_DSA -# define R_DSA_512 0 -# define R_DSA_1024 1 -# define R_DSA_2048 2 -static const OPT_PAIR dsa_choices[] = { +enum { R_DSA_512, R_DSA_1024, R_DSA_2048, DSA_NUM }; +static const OPT_PAIR dsa_choices[DSA_NUM] = { {"dsa512", R_DSA_512}, {"dsa1024", R_DSA_1024}, {"dsa2048", R_DSA_2048} }; -# define DSA_NUM OSSL_NELEM(dsa_choices) - static double dsa_results[DSA_NUM][2]; /* 2 ops: sign then verify */ -#endif /* OPENSSL_NO_DSA */ - -#define R_RSA_512 0 -#define R_RSA_1024 1 -#define R_RSA_2048 2 -#define R_RSA_3072 3 -#define R_RSA_4096 4 -#define R_RSA_7680 5 -#define R_RSA_15360 6 -#ifndef OPENSSL_NO_RSA -static const OPT_PAIR rsa_choices[] = { + +enum { + R_RSA_512, R_RSA_1024, R_RSA_2048, R_RSA_3072, R_RSA_4096, R_RSA_7680, + R_RSA_15360, RSA_NUM +}; +static const OPT_PAIR rsa_choices[RSA_NUM] = { {"rsa512", R_RSA_512}, {"rsa1024", R_RSA_1024}, {"rsa2048", R_RSA_2048}, @@ -484,49 +346,43 @@ static const OPT_PAIR rsa_choices[] = { {"rsa7680", R_RSA_7680}, {"rsa15360", R_RSA_15360} }; -# define RSA_NUM OSSL_NELEM(rsa_choices) static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */ -#endif /* OPENSSL_NO_RSA */ -enum { - R_EC_P160, - R_EC_P192, - R_EC_P224, - R_EC_P256, - R_EC_P384, - R_EC_P521, +#ifndef OPENSSL_NO_DH +enum ff_params_t { + R_FFDH_2048, R_FFDH_3072, R_FFDH_4096, R_FFDH_6144, R_FFDH_8192, FFDH_NUM +}; + +static const OPT_PAIR ffdh_choices[FFDH_NUM] = { + {"ffdh2048", R_FFDH_2048}, + {"ffdh3072", R_FFDH_3072}, + {"ffdh4096", R_FFDH_4096}, + {"ffdh6144", R_FFDH_6144}, + {"ffdh8192", R_FFDH_8192}, +}; + +static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */ +#endif /* OPENSSL_NO_DH */ + +enum ec_curves_t { + R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521, #ifndef OPENSSL_NO_EC2M - R_EC_K163, - R_EC_K233, - R_EC_K283, - R_EC_K409, - R_EC_K571, - R_EC_B163, - R_EC_B233, - R_EC_B283, - R_EC_B409, - R_EC_B571, + R_EC_K163, R_EC_K233, R_EC_K283, R_EC_K409, R_EC_K571, + R_EC_B163, R_EC_B233, R_EC_B283, R_EC_B409, R_EC_B571, #endif - R_EC_BRP256R1, - R_EC_BRP256T1, - R_EC_BRP384R1, - R_EC_BRP384T1, - R_EC_BRP512R1, - R_EC_BRP512T1, - R_EC_X25519, - R_EC_X448 + R_EC_BRP256R1, R_EC_BRP256T1, R_EC_BRP384R1, R_EC_BRP384T1, + R_EC_BRP512R1, R_EC_BRP512T1, ECDSA_NUM }; - -#ifndef OPENSSL_NO_EC -static OPT_PAIR ecdsa_choices[] = { +/* list of ecdsa curves */ +static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = { {"ecdsap160", R_EC_P160}, {"ecdsap192", R_EC_P192}, {"ecdsap224", R_EC_P224}, {"ecdsap256", R_EC_P256}, {"ecdsap384", R_EC_P384}, {"ecdsap521", R_EC_P521}, -# ifndef OPENSSL_NO_EC2M +#ifndef OPENSSL_NO_EC2M {"ecdsak163", R_EC_K163}, {"ecdsak233", R_EC_K233}, {"ecdsak283", R_EC_K283}, @@ -537,7 +393,7 @@ static OPT_PAIR ecdsa_choices[] = { {"ecdsab283", R_EC_B283}, {"ecdsab409", R_EC_B409}, {"ecdsab571", R_EC_B571}, -# endif +#endif {"ecdsabrp256r1", R_EC_BRP256R1}, {"ecdsabrp256t1", R_EC_BRP256T1}, {"ecdsabrp384r1", R_EC_BRP384R1}, @@ -545,18 +401,16 @@ static OPT_PAIR ecdsa_choices[] = { {"ecdsabrp512r1", R_EC_BRP512R1}, {"ecdsabrp512t1", R_EC_BRP512T1} }; -# define ECDSA_NUM OSSL_NELEM(ecdsa_choices) - -static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */ - -static const OPT_PAIR ecdh_choices[] = { +enum { R_EC_X25519 = ECDSA_NUM, R_EC_X448, EC_NUM }; +/* list of ecdh curves, extension of |ecdsa_choices| list above */ +static const OPT_PAIR ecdh_choices[EC_NUM] = { {"ecdhp160", R_EC_P160}, {"ecdhp192", R_EC_P192}, {"ecdhp224", R_EC_P224}, {"ecdhp256", R_EC_P256}, {"ecdhp384", R_EC_P384}, {"ecdhp521", R_EC_P521}, -# ifndef OPENSSL_NO_EC2M +#ifndef OPENSSL_NO_EC2M {"ecdhk163", R_EC_K163}, {"ecdhk233", R_EC_K233}, {"ecdhk283", R_EC_K283}, @@ -567,7 +421,7 @@ static const OPT_PAIR ecdh_choices[] = { {"ecdhb283", R_EC_B283}, {"ecdhb409", R_EC_B409}, {"ecdhb571", R_EC_B571}, -# endif +#endif {"ecdhbrp256r1", R_EC_BRP256R1}, {"ecdhbrp256t1", R_EC_BRP256T1}, {"ecdhbrp384r1", R_EC_BRP384R1}, @@ -577,28 +431,30 @@ static const OPT_PAIR ecdh_choices[] = { {"ecdhx25519", R_EC_X25519}, {"ecdhx448", R_EC_X448} }; -# define EC_NUM OSSL_NELEM(ecdh_choices) -static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */ +static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */ +static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */ -#define R_EC_Ed25519 0 -#define R_EC_Ed448 1 -static OPT_PAIR eddsa_choices[] = { +enum { R_EC_Ed25519, R_EC_Ed448, EdDSA_NUM }; +static const OPT_PAIR eddsa_choices[EdDSA_NUM] = { {"ed25519", R_EC_Ed25519}, {"ed448", R_EC_Ed448} -}; -# define EdDSA_NUM OSSL_NELEM(eddsa_choices) +}; static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */ -#endif /* OPENSSL_NO_EC */ -#ifndef SIGALRM -# define COND(d) (count < (d)) -# define COUNT(d) (d) -#else -# define COND(unused_cond) (run && count<0x7fffffff) -# define COUNT(d) (count) -#endif /* SIGALRM */ +#ifndef OPENSSL_NO_SM2 +enum { R_EC_CURVESM2, SM2_NUM }; +static const OPT_PAIR sm2_choices[SM2_NUM] = { + {"curveSM2", R_EC_CURVESM2} +}; +# define SM2_ID "TLSv1.3+GM+Cipher+Suite" +# define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1 +static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */ +#endif /* OPENSSL_NO_SM2 */ + +#define COND(unused_cond) (run && count < INT_MAX) +#define COUNT(d) (count) typedef struct loopargs_st { ASYNC_JOB *inprogress_job; @@ -608,25 +464,32 @@ typedef struct loopargs_st { unsigned char *buf_malloc; unsigned char *buf2_malloc; unsigned char *key; - unsigned int siglen; + size_t buflen; size_t sigsize; -#ifndef OPENSSL_NO_RSA - RSA *rsa_key[RSA_NUM]; -#endif -#ifndef OPENSSL_NO_DSA - DSA *dsa_key[DSA_NUM]; -#endif -#ifndef OPENSSL_NO_EC - EC_KEY *ecdsa[ECDSA_NUM]; + EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM]; + EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM]; + EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM]; + EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM]; + EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM]; + EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM]; EVP_PKEY_CTX *ecdh_ctx[EC_NUM]; EVP_MD_CTX *eddsa_ctx[EdDSA_NUM]; + EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM]; +#ifndef OPENSSL_NO_SM2 + EVP_MD_CTX *sm2_ctx[SM2_NUM]; + EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM]; + EVP_PKEY *sm2_pkey[SM2_NUM]; +#endif unsigned char *secret_a; unsigned char *secret_b; size_t outlen[EC_NUM]; +#ifndef OPENSSL_NO_DH + EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM]; + unsigned char *secret_ff_a; + unsigned char *secret_ff_b; #endif EVP_CIPHER_CTX *ctx; - HMAC_CTX *hctx; - GCM128_CONTEXT *gcm_ctx; + EVP_MAC_CTX *mctx; } loopargs_t; static int run_benchmark(int async_jobs, int (*loop_function) (void *), loopargs_t * loopargs); @@ -634,273 +497,216 @@ static int run_benchmark(int async_jobs, int (*loop_function) (void *), static unsigned int testnum; /* Nb of iterations to do per algorithm and key-size */ -static long c[ALGOR_NUM][OSSL_NELEM(lengths_list)]; +static long c[ALGOR_NUM][SIZE_NUM]; -#ifndef OPENSSL_NO_MD2 -static int EVP_Digest_MD2_loop(void *args) +static char *evp_mac_mdname = "md5"; +static char *evp_hmac_name = NULL; +static const char *evp_md_name = NULL; +static char *evp_mac_ciphername = "aes-128-cbc"; +static char *evp_cmac_name = NULL; + +static int have_md(const char *name) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char md2[MD2_DIGEST_LENGTH]; - int count; + int ret = 0; + EVP_MD *md = NULL; - for (count = 0; COND(c[D_MD2][testnum]); count++) { - if (!EVP_Digest(buf, (size_t)lengths[testnum], md2, NULL, EVP_md2(), - NULL)) - return -1; + if (opt_md_silent(name, &md)) { + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + + if (ctx != NULL && EVP_DigestInit(ctx, md) > 0) + ret = 1; + EVP_MD_CTX_free(ctx); + EVP_MD_free(md); } - return count; + return ret; } -#endif -#ifndef OPENSSL_NO_MDC2 -static int EVP_Digest_MDC2_loop(void *args) +static int have_cipher(const char *name) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char mdc2[MDC2_DIGEST_LENGTH]; - int count; + int ret = 0; + EVP_CIPHER *cipher = NULL; - for (count = 0; COND(c[D_MDC2][testnum]); count++) { - if (!EVP_Digest(buf, (size_t)lengths[testnum], mdc2, NULL, EVP_mdc2(), - NULL)) - return -1; + if (opt_cipher_silent(name, &cipher)) { + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + + if (ctx != NULL + && EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) > 0) + ret = 1; + EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_free(cipher); } - return count; + return ret; } -#endif -#ifndef OPENSSL_NO_MD4 -static int EVP_Digest_MD4_loop(void *args) +static int EVP_Digest_loop(const char *mdname, int algindex, void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; - unsigned char md4[MD4_DIGEST_LENGTH]; + unsigned char digest[EVP_MAX_MD_SIZE]; int count; + EVP_MD *md = NULL; - for (count = 0; COND(c[D_MD4][testnum]); count++) { - if (!EVP_Digest(buf, (size_t)lengths[testnum], md4, NULL, EVP_md4(), - NULL)) - return -1; + if (!opt_md_silent(mdname, &md)) + return -1; + for (count = 0; COND(c[algindex][testnum]); count++) { + if (!EVP_Digest(buf, (size_t)lengths[testnum], digest, NULL, md, + NULL)) { + count = -1; + break; + } } + EVP_MD_free(md); return count; } -#endif -#ifndef OPENSSL_NO_MD5 -static int MD5_loop(void *args) +static int EVP_Digest_md_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char md5[MD5_DIGEST_LENGTH]; - int count; - for (count = 0; COND(c[D_MD5][testnum]); count++) - MD5(buf, lengths[testnum], md5); - return count; + return EVP_Digest_loop(evp_md_name, D_EVP, args); } -static int HMAC_loop(void *args) +static int EVP_Digest_MD2_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - HMAC_CTX *hctx = tempargs->hctx; - unsigned char hmac[MD5_DIGEST_LENGTH]; - int count; - - for (count = 0; COND(c[D_HMAC][testnum]); count++) { - HMAC_Init_ex(hctx, NULL, 0, NULL, NULL); - HMAC_Update(hctx, buf, lengths[testnum]); - HMAC_Final(hctx, hmac, NULL); - } - return count; + return EVP_Digest_loop("md2", D_MD2, args); } -#endif -static int SHA1_loop(void *args) +static int EVP_Digest_MDC2_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char sha[SHA_DIGEST_LENGTH]; - int count; - for (count = 0; COND(c[D_SHA1][testnum]); count++) - SHA1(buf, lengths[testnum], sha); - return count; + return EVP_Digest_loop("mdc2", D_MDC2, args); } -static int SHA256_loop(void *args) +static int EVP_Digest_MD4_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char sha256[SHA256_DIGEST_LENGTH]; - int count; - for (count = 0; COND(c[D_SHA256][testnum]); count++) - SHA256(buf, lengths[testnum], sha256); - return count; + return EVP_Digest_loop("md4", D_MD4, args); } -static int SHA512_loop(void *args) +static int MD5_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char sha512[SHA512_DIGEST_LENGTH]; - int count; - for (count = 0; COND(c[D_SHA512][testnum]); count++) - SHA512(buf, lengths[testnum], sha512); - return count; + return EVP_Digest_loop("md5", D_MD5, args); } -#ifndef OPENSSL_NO_WHIRLPOOL -static int WHIRLPOOL_loop(void *args) +static int EVP_MAC_loop(int algindex, void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; - unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH]; + EVP_MAC_CTX *mctx = tempargs->mctx; + unsigned char mac[EVP_MAX_MD_SIZE]; int count; - for (count = 0; COND(c[D_WHIRLPOOL][testnum]); count++) - WHIRLPOOL(buf, lengths[testnum], whirlpool); - return count; -} -#endif -#ifndef OPENSSL_NO_RMD160 -static int EVP_Digest_RMD160_loop(void *args) -{ - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char rmd160[RIPEMD160_DIGEST_LENGTH]; - int count; - for (count = 0; COND(c[D_RMD160][testnum]); count++) { - if (!EVP_Digest(buf, (size_t)lengths[testnum], &(rmd160[0]), - NULL, EVP_ripemd160(), NULL)) + for (count = 0; COND(c[algindex][testnum]); count++) { + size_t outl; + + if (!EVP_MAC_init(mctx, NULL, 0, NULL) + || !EVP_MAC_update(mctx, buf, lengths[testnum]) + || !EVP_MAC_final(mctx, mac, &outl, sizeof(mac))) return -1; } return count; } -#endif -#ifndef OPENSSL_NO_RC4 -static RC4_KEY rc4_ks; -static int RC4_loop(void *args) +static int HMAC_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - int count; - for (count = 0; COND(c[D_RC4][testnum]); count++) - RC4(&rc4_ks, (size_t)lengths[testnum], buf, buf); - return count; + return EVP_MAC_loop(D_HMAC, args); } -#endif -#ifndef OPENSSL_NO_DES -static unsigned char DES_iv[8]; -static DES_key_schedule sch; -static DES_key_schedule sch2; -static DES_key_schedule sch3; -static int DES_ncbc_encrypt_loop(void *args) +static int CMAC_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - int count; - for (count = 0; COND(c[D_CBC_DES][testnum]); count++) - DES_ncbc_encrypt(buf, buf, lengths[testnum], &sch, - &DES_iv, DES_ENCRYPT); - return count; + return EVP_MAC_loop(D_EVP_CMAC, args); } -static int DES_ede3_cbc_encrypt_loop(void *args) +static int SHA1_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - int count; - for (count = 0; COND(c[D_EDE3_DES][testnum]); count++) - DES_ede3_cbc_encrypt(buf, buf, lengths[testnum], - &sch, &sch2, &sch3, &DES_iv, DES_ENCRYPT); - return count; + return EVP_Digest_loop("sha1", D_SHA1, args); } -#endif -#define MAX_BLOCK_SIZE 128 - -static unsigned char iv[2 * MAX_BLOCK_SIZE / 8]; -static AES_KEY aes_ks1, aes_ks2, aes_ks3; -static int AES_cbc_128_encrypt_loop(void *args) +static int SHA256_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - int count; - for (count = 0; COND(c[D_CBC_128_AES][testnum]); count++) - AES_cbc_encrypt(buf, buf, - (size_t)lengths[testnum], &aes_ks1, iv, AES_ENCRYPT); - return count; + return EVP_Digest_loop("sha256", D_SHA256, args); } -static int AES_cbc_192_encrypt_loop(void *args) +static int SHA512_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - int count; - for (count = 0; COND(c[D_CBC_192_AES][testnum]); count++) - AES_cbc_encrypt(buf, buf, - (size_t)lengths[testnum], &aes_ks2, iv, AES_ENCRYPT); - return count; + return EVP_Digest_loop("sha512", D_SHA512, args); } -static int AES_cbc_256_encrypt_loop(void *args) +static int WHIRLPOOL_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - int count; - for (count = 0; COND(c[D_CBC_256_AES][testnum]); count++) - AES_cbc_encrypt(buf, buf, - (size_t)lengths[testnum], &aes_ks3, iv, AES_ENCRYPT); - return count; + return EVP_Digest_loop("whirlpool", D_WHIRLPOOL, args); } -static int AES_ige_128_encrypt_loop(void *args) +static int EVP_Digest_RMD160_loop(void *args) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char *buf2 = tempargs->buf2; - int count; - for (count = 0; COND(c[D_IGE_128_AES][testnum]); count++) - AES_ige_encrypt(buf, buf2, - (size_t)lengths[testnum], &aes_ks1, iv, AES_ENCRYPT); - return count; + return EVP_Digest_loop("ripemd160", D_RMD160, args); } -static int AES_ige_192_encrypt_loop(void *args) +static int algindex; + +static int EVP_Cipher_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; - unsigned char *buf2 = tempargs->buf2; int count; - for (count = 0; COND(c[D_IGE_192_AES][testnum]); count++) - AES_ige_encrypt(buf, buf2, - (size_t)lengths[testnum], &aes_ks2, iv, AES_ENCRYPT); + + if (tempargs->ctx == NULL) + return -1; + for (count = 0; COND(c[algindex][testnum]); count++) + if (EVP_Cipher(tempargs->ctx, buf, buf, (size_t)lengths[testnum]) <= 0) + return -1; return count; } -static int AES_ige_256_encrypt_loop(void *args) +static int GHASH_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; - unsigned char *buf2 = tempargs->buf2; + EVP_MAC_CTX *mctx = tempargs->mctx; int count; - for (count = 0; COND(c[D_IGE_256_AES][testnum]); count++) - AES_ige_encrypt(buf, buf2, - (size_t)lengths[testnum], &aes_ks3, iv, AES_ENCRYPT); + + /* just do the update in the loop to be comparable with 1.1.1 */ + for (count = 0; COND(c[D_GHASH][testnum]); count++) { + if (!EVP_MAC_update(mctx, buf, lengths[testnum])) + return -1; + } return count; } -static int CRYPTO_gcm128_aad_loop(void *args) +#define MAX_BLOCK_SIZE 128 + +static unsigned char iv[2 * MAX_BLOCK_SIZE / 8]; + +static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername, + const unsigned char *key, + int keylen) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - GCM128_CONTEXT *gcm_ctx = tempargs->gcm_ctx; - int count; - for (count = 0; COND(c[D_GHASH][testnum]); count++) - CRYPTO_gcm128_aad(gcm_ctx, buf, lengths[testnum]); - return count; + EVP_CIPHER_CTX *ctx = NULL; + EVP_CIPHER *cipher = NULL; + + if (!opt_cipher_silent(ciphername, &cipher)) + return NULL; + + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) + goto end; + + if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1)) { + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + goto end; + } + + if (EVP_CIPHER_CTX_set_key_length(ctx, keylen) <= 0) { + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + goto end; + } + + if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1)) { + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + goto end; + } + +end: + EVP_CIPHER_free(cipher); + return ctx; } static int RAND_bytes_loop(void *args) @@ -914,7 +720,6 @@ static int RAND_bytes_loop(void *args) return count; } -static long save_count = 0; static int decrypt = 0; static int EVP_Update_loop(void *args) { @@ -922,11 +727,9 @@ static int EVP_Update_loop(void *args) unsigned char *buf = tempargs->buf; EVP_CIPHER_CTX *ctx = tempargs->ctx; int outl, count, rc; -#ifndef SIGALRM - int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; -#endif + if (decrypt) { - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP][testnum]); count++) { rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); if (rc != 1) { /* reset iv in case of counter overflow */ @@ -934,7 +737,7 @@ static int EVP_Update_loop(void *args) } } } else { - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP][testnum]); count++) { rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); if (rc != 1) { /* reset iv in case of counter overflow */ @@ -961,29 +764,28 @@ static int EVP_Update_loop_ccm(void *args) EVP_CIPHER_CTX *ctx = tempargs->ctx; int outl, count; unsigned char tag[12]; -#ifndef SIGALRM - int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; -#endif + if (decrypt) { - for (count = 0; COND(nb_iter); count++) { - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag), tag); + for (count = 0; COND(c[D_EVP][testnum]); count++) { + (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag), + tag); /* reset iv */ - EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); + (void)EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); /* counter is reset on every update */ - EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + (void)EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); } } else { - for (count = 0; COND(nb_iter); count++) { + for (count = 0; COND(c[D_EVP][testnum]); count++) { /* restore iv length field */ - EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]); + (void)EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]); /* counter is reset on every update */ - EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + (void)EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); } } if (decrypt) - EVP_DecryptFinal_ex(ctx, buf, &outl); + (void)EVP_DecryptFinal_ex(ctx, buf, &outl); else - EVP_EncryptFinal_ex(ctx, buf, &outl); + (void)EVP_EncryptFinal_ex(ctx, buf, &outl); return count; } @@ -1000,61 +802,42 @@ static int EVP_Update_loop_aead(void *args) int outl, count; unsigned char aad[13] = { 0xcc }; unsigned char faketag[16] = { 0xcc }; -#ifndef SIGALRM - int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; -#endif + if (decrypt) { - for (count = 0; COND(nb_iter); count++) { - EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, - sizeof(faketag), faketag); - EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)); - EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); - EVP_DecryptFinal_ex(ctx, buf + outl, &outl); + for (count = 0; COND(c[D_EVP][testnum]); count++) { + (void)EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); + (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + sizeof(faketag), faketag); + (void)EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)); + (void)EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + (void)EVP_DecryptFinal_ex(ctx, buf + outl, &outl); } } else { - for (count = 0; COND(nb_iter); count++) { - EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); - EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)); - EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); - EVP_EncryptFinal_ex(ctx, buf + outl, &outl); + for (count = 0; COND(c[D_EVP][testnum]); count++) { + (void)EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); + (void)EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)); + (void)EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + (void)EVP_EncryptFinal_ex(ctx, buf + outl, &outl); } } return count; } -static const EVP_MD *evp_md = NULL; -static int EVP_Digest_loop(void *args) -{ - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char md[EVP_MAX_MD_SIZE]; - int count; -#ifndef SIGALRM - int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; -#endif - - for (count = 0; COND(nb_iter); count++) { - if (!EVP_Digest(buf, lengths[testnum], md, NULL, evp_md, NULL)) - return -1; - } - return count; -} - -#ifndef OPENSSL_NO_RSA -static long rsa_c[RSA_NUM][2]; /* # RSA iteration test */ - -static int RSA_sign_loop(void *args) +static long rsa_c[RSA_NUM][2]; /* # RSA iteration test */ + +static int RSA_sign_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; unsigned char *buf2 = tempargs->buf2; - unsigned int *rsa_num = &tempargs->siglen; - RSA **rsa_key = tempargs->rsa_key; + size_t *rsa_num = &tempargs->sigsize; + EVP_PKEY_CTX **rsa_sign_ctx = tempargs->rsa_sign_ctx; int ret, count; + for (count = 0; COND(rsa_c[testnum][0]); count++) { - ret = RSA_sign(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[testnum]); - if (ret == 0) { + *rsa_num = tempargs->buflen; + ret = EVP_PKEY_sign(rsa_sign_ctx[testnum], buf2, rsa_num, buf, 36); + if (ret <= 0) { BIO_printf(bio_err, "RSA sign failure\n"); ERR_print_errors(bio_err); count = -1; @@ -1069,12 +852,12 @@ static int RSA_verify_loop(void *args) loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; unsigned char *buf2 = tempargs->buf2; - unsigned int rsa_num = tempargs->siglen; - RSA **rsa_key = tempargs->rsa_key; + size_t rsa_num = tempargs->sigsize; + EVP_PKEY_CTX **rsa_verify_ctx = tempargs->rsa_verify_ctx; int ret, count; + for (count = 0; COND(rsa_c[testnum][1]); count++) { - ret = - RSA_verify(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[testnum]); + ret = EVP_PKEY_verify(rsa_verify_ctx[testnum], buf2, rsa_num, buf, 36); if (ret <= 0) { BIO_printf(bio_err, "RSA verify failure\n"); ERR_print_errors(bio_err); @@ -1084,21 +867,41 @@ static int RSA_verify_loop(void *args) } return count; } -#endif -#ifndef OPENSSL_NO_DSA +#ifndef OPENSSL_NO_DH +static long ffdh_c[FFDH_NUM][1]; + +static int FFDH_derive_key_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum]; + unsigned char *derived_secret = tempargs->secret_ff_a; + int count; + + for (count = 0; COND(ffdh_c[testnum][0]); count++) { + /* outlen can be overwritten with a too small value (no padding used) */ + size_t outlen = MAX_FFDH_SIZE; + + EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen); + } + return count; +} +#endif /* OPENSSL_NO_DH */ + static long dsa_c[DSA_NUM][2]; static int DSA_sign_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; unsigned char *buf2 = tempargs->buf2; - DSA **dsa_key = tempargs->dsa_key; - unsigned int *siglen = &tempargs->siglen; + size_t *dsa_num = &tempargs->sigsize; + EVP_PKEY_CTX **dsa_sign_ctx = tempargs->dsa_sign_ctx; int ret, count; + for (count = 0; COND(dsa_c[testnum][0]); count++) { - ret = DSA_sign(0, buf, 20, buf2, siglen, dsa_key[testnum]); - if (ret == 0) { + *dsa_num = tempargs->buflen; + ret = EVP_PKEY_sign(dsa_sign_ctx[testnum], buf2, dsa_num, buf, 20); + if (ret <= 0) { BIO_printf(bio_err, "DSA sign failure\n"); ERR_print_errors(bio_err); count = -1; @@ -1113,11 +916,12 @@ static int DSA_verify_loop(void *args) loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; unsigned char *buf2 = tempargs->buf2; - DSA **dsa_key = tempargs->dsa_key; - unsigned int siglen = tempargs->siglen; + size_t dsa_num = tempargs->sigsize; + EVP_PKEY_CTX **dsa_verify_ctx = tempargs->dsa_verify_ctx; int ret, count; + for (count = 0; COND(dsa_c[testnum][1]); count++) { - ret = DSA_verify(0, buf, 20, buf2, siglen, dsa_key[testnum]); + ret = EVP_PKEY_verify(dsa_verify_ctx[testnum], buf2, dsa_num, buf, 20); if (ret <= 0) { BIO_printf(bio_err, "DSA verify failure\n"); ERR_print_errors(bio_err); @@ -1127,21 +931,21 @@ static int DSA_verify_loop(void *args) } return count; } -#endif -#ifndef OPENSSL_NO_EC static long ecdsa_c[ECDSA_NUM][2]; static int ECDSA_sign_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; - EC_KEY **ecdsa = tempargs->ecdsa; - unsigned char *ecdsasig = tempargs->buf2; - unsigned int *ecdsasiglen = &tempargs->siglen; + unsigned char *buf2 = tempargs->buf2; + size_t *ecdsa_num = &tempargs->sigsize; + EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx; int ret, count; + for (count = 0; COND(ecdsa_c[testnum][0]); count++) { - ret = ECDSA_sign(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[testnum]); - if (ret == 0) { + *ecdsa_num = tempargs->buflen; + ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20); + if (ret <= 0) { BIO_printf(bio_err, "ECDSA sign failure\n"); ERR_print_errors(bio_err); count = -1; @@ -1155,13 +959,15 @@ static int ECDSA_verify_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; - EC_KEY **ecdsa = tempargs->ecdsa; - unsigned char *ecdsasig = tempargs->buf2; - unsigned int ecdsasiglen = tempargs->siglen; + unsigned char *buf2 = tempargs->buf2; + size_t ecdsa_num = tempargs->sigsize; + EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx; int ret, count; + for (count = 0; COND(ecdsa_c[testnum][1]); count++) { - ret = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[testnum]); - if (ret != 1) { + ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num, + buf, 20); + if (ret <= 0) { BIO_printf(bio_err, "ECDSA verify failure\n"); ERR_print_errors(bio_err); count = -1; @@ -1214,7 +1020,7 @@ static int EdDSA_verify_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; - EVP_MD_CTX **edctx = tempargs->eddsa_ctx; + EVP_MD_CTX **edctx = tempargs->eddsa_ctx2; unsigned char *eddsasig = tempargs->buf2; size_t eddsasigsize = tempargs->sigsize; int ret, count; @@ -1230,7 +1036,75 @@ static int EdDSA_verify_loop(void *args) } return count; } -#endif /* OPENSSL_NO_EC */ + +#ifndef OPENSSL_NO_SM2 +static long sm2_c[SM2_NUM][2]; +static int SM2_sign_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + unsigned char *buf = tempargs->buf; + EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx; + unsigned char *sm2sig = tempargs->buf2; + size_t sm2sigsize; + int ret, count; + EVP_PKEY **sm2_pkey = tempargs->sm2_pkey; + const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]); + + for (count = 0; COND(sm2_c[testnum][0]); count++) { + sm2sigsize = max_size; + + if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(), + NULL, sm2_pkey[testnum])) { + BIO_printf(bio_err, "SM2 init sign failure\n"); + ERR_print_errors(bio_err); + count = -1; + break; + } + ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize, + buf, 20); + if (ret == 0) { + BIO_printf(bio_err, "SM2 sign failure\n"); + ERR_print_errors(bio_err); + count = -1; + break; + } + /* update the latest returned size and always use the fixed buffer size */ + tempargs->sigsize = sm2sigsize; + } + + return count; +} + +static int SM2_verify_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + unsigned char *buf = tempargs->buf; + EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx; + unsigned char *sm2sig = tempargs->buf2; + size_t sm2sigsize = tempargs->sigsize; + int ret, count; + EVP_PKEY **sm2_pkey = tempargs->sm2_pkey; + + for (count = 0; COND(sm2_c[testnum][1]); count++) { + if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(), + NULL, sm2_pkey[testnum])) { + BIO_printf(bio_err, "SM2 verify init failure\n"); + ERR_print_errors(bio_err); + count = -1; + break; + } + ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize, + buf, 20); + if (ret != 1) { + BIO_printf(bio_err, "SM2 verify failure\n"); + ERR_print_errors(bio_err); + count = -1; + break; + } + } + return count; +} +#endif /* OPENSSL_NO_SM2 */ static int run_benchmark(int async_jobs, int (*loop_function) (void *), loopargs_t * loopargs) @@ -1383,124 +1257,170 @@ static int run_benchmark(int async_jobs, return error ? -1 : total_op_count; } +typedef struct ec_curve_st { + const char *name; + unsigned int nid; + unsigned int bits; + size_t sigsize; /* only used for EdDSA curves */ +} EC_CURVE; + +static EVP_PKEY *get_ecdsa(const EC_CURVE *curve) +{ + EVP_PKEY_CTX *kctx = NULL; + EVP_PKEY *key = NULL; + + /* Ensure that the error queue is empty */ + if (ERR_peek_error()) { + BIO_printf(bio_err, + "WARNING: the error queue contains previous unhandled errors.\n"); + ERR_print_errors(bio_err); + } + + /* + * Let's try to create a ctx directly from the NID: this works for + * curves like Curve25519 that are not implemented through the low + * level EC interface. + * If this fails we try creating a EVP_PKEY_EC generic param ctx, + * then we set the curve by NID before deriving the actual keygen + * ctx for that specific curve. + */ + kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL); + if (kctx == NULL) { + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *params = NULL; + /* + * If we reach this code EVP_PKEY_CTX_new_id() failed and a + * "int_ctx_new:unsupported algorithm" error was added to the + * error queue. + * We remove it from the error queue as we are handling it. + */ + unsigned long error = ERR_peek_error(); + + if (error == ERR_peek_last_error() /* oldest and latest errors match */ + /* check that the error origin matches */ + && ERR_GET_LIB(error) == ERR_LIB_EVP + && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM + || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED)) + ERR_get_error(); /* pop error from queue */ + if (ERR_peek_error()) { + BIO_printf(bio_err, + "Unhandled error in the error queue during EC key setup.\n"); + ERR_print_errors(bio_err); + return NULL; + } + + /* Create the context for parameter generation */ + if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL + || EVP_PKEY_paramgen_init(pctx) <= 0 + || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, + curve->nid) <= 0 + || EVP_PKEY_paramgen(pctx, ¶ms) <= 0) { + BIO_printf(bio_err, "EC params init failure.\n"); + ERR_print_errors(bio_err); + EVP_PKEY_CTX_free(pctx); + return NULL; + } + EVP_PKEY_CTX_free(pctx); + + /* Create the context for the key generation */ + kctx = EVP_PKEY_CTX_new(params, NULL); + EVP_PKEY_free(params); + } + if (kctx == NULL + || EVP_PKEY_keygen_init(kctx) <= 0 + || EVP_PKEY_keygen(kctx, &key) <= 0) { + BIO_printf(bio_err, "EC key generation failure.\n"); + ERR_print_errors(bio_err); + key = NULL; + } + EVP_PKEY_CTX_free(kctx); + return key; +} + +#define stop_it(do_it, test_num)\ + memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num); + int speed_main(int argc, char **argv) { ENGINE *e = NULL; loopargs_t *loopargs = NULL; const char *prog; const char *engine_id = NULL; - const EVP_CIPHER *evp_cipher = NULL; + EVP_CIPHER *evp_cipher = NULL; + EVP_MAC *mac = NULL; double d = 0.0; OPTION_CHOICE o; int async_init = 0, multiblock = 0, pr_header = 0; - int doit[ALGOR_NUM] = { 0 }; + uint8_t doit[ALGOR_NUM] = { 0 }; int ret = 1, misalign = 0, lengths_single = 0, aead = 0; long count = 0; - unsigned int size_num = OSSL_NELEM(lengths_list); - unsigned int i, k, loop, loopargs_len = 0, async_jobs = 0; + unsigned int size_num = SIZE_NUM; + unsigned int i, k, loopargs_len = 0, async_jobs = 0; int keylen; int buflen; + BIGNUM *bn = NULL; + EVP_PKEY_CTX *genctx = NULL; #ifndef NO_FORK int multi = 0; #endif -#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) \ - || !defined(OPENSSL_NO_EC) - long rsa_count = 1; -#endif + long op_count = 1; openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS, ECDSA_SECONDS, ECDH_SECONDS, - EdDSA_SECONDS }; + EdDSA_SECONDS, SM2_SECONDS, + FFDH_SECONDS }; - /* What follows are the buffers and key material. */ -#ifndef OPENSSL_NO_RC5 - RC5_32_KEY rc5_ks; -#endif -#ifndef OPENSSL_NO_RC2 - RC2_KEY rc2_ks; -#endif -#ifndef OPENSSL_NO_IDEA - IDEA_KEY_SCHEDULE idea_ks; -#endif -#ifndef OPENSSL_NO_SEED - SEED_KEY_SCHEDULE seed_ks; -#endif -#ifndef OPENSSL_NO_BF - BF_KEY bf_ks; -#endif -#ifndef OPENSSL_NO_CAST - CAST_KEY cast_ks; -#endif - static const unsigned char key16[16] = { - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, - 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 - }; - static const unsigned char key24[24] = { - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, - 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, - 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 - }; static const unsigned char key32[32] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56 }; -#ifndef OPENSSL_NO_CAMELLIA - static const unsigned char ckey24[24] = { - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, - 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, - 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 - }; - static const unsigned char ckey32[32] = { - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, - 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, - 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, - 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56 - }; - CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3; -#endif -#ifndef OPENSSL_NO_DES - static DES_cblock key = { - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 - }; - static DES_cblock key2 = { - 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 + static const unsigned char deskey[] = { + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */ + 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */ + 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */ }; - static DES_cblock key3 = { - 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 - }; -#endif -#ifndef OPENSSL_NO_RSA - static const unsigned int rsa_bits[RSA_NUM] = { - 512, 1024, 2048, 3072, 4096, 7680, 15360 - }; - static const unsigned char *rsa_data[RSA_NUM] = { - test512, test1024, test2048, test3072, test4096, test7680, test15360 - }; - static const int rsa_data_length[RSA_NUM] = { - sizeof(test512), sizeof(test1024), - sizeof(test2048), sizeof(test3072), - sizeof(test4096), sizeof(test7680), - sizeof(test15360) + static const struct { + const unsigned char *data; + unsigned int length; + unsigned int bits; + } rsa_keys[] = { + { test512, sizeof(test512), 512 }, + { test1024, sizeof(test1024), 1024 }, + { test2048, sizeof(test2048), 2048 }, + { test3072, sizeof(test3072), 3072 }, + { test4096, sizeof(test4096), 4096 }, + { test7680, sizeof(test7680), 7680 }, + { test15360, sizeof(test15360), 15360 } }; - int rsa_doit[RSA_NUM] = { 0 }; + uint8_t rsa_doit[RSA_NUM] = { 0 }; int primes = RSA_DEFAULT_PRIME_NUM; -#endif -#ifndef OPENSSL_NO_DSA +#ifndef OPENSSL_NO_DH + typedef struct ffdh_params_st { + const char *name; + unsigned int nid; + unsigned int bits; + } FFDH_PARAMS; + + static const FFDH_PARAMS ffdh_params[FFDH_NUM] = { + {"ffdh2048", NID_ffdhe2048, 2048}, + {"ffdh3072", NID_ffdhe3072, 3072}, + {"ffdh4096", NID_ffdhe4096, 4096}, + {"ffdh6144", NID_ffdhe6144, 6144}, + {"ffdh8192", NID_ffdhe8192, 8192} + }; + uint8_t ffdh_doit[FFDH_NUM] = { 0 }; + +#endif /* OPENSSL_NO_DH */ static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 }; - int dsa_doit[DSA_NUM] = { 0 }; -#endif -#ifndef OPENSSL_NO_EC + uint8_t dsa_doit[DSA_NUM] = { 0 }; /* * We only test over the following curves as they are representative, To * add tests over more curves, simply add the curve NID and curve name to - * the following arrays and increase the |ecdh_choices| list accordingly. + * the following arrays and increase the |ecdh_choices| and |ecdsa_choices| + * lists accordingly. */ - static const struct { - const char *name; - unsigned int nid; - unsigned int bits; - } test_curves[] = { + static const EC_CURVE ec_curves[EC_NUM] = { /* Prime Curves */ {"secp160r1", NID_secp160r1, 160}, {"nistp192", NID_X9_62_prime192v1, 192}, @@ -1508,7 +1428,7 @@ int speed_main(int argc, char **argv) {"nistp256", NID_X9_62_prime256v1, 256}, {"nistp384", NID_secp384r1, 384}, {"nistp521", NID_secp521r1, 521}, -# ifndef OPENSSL_NO_EC2M +#ifndef OPENSSL_NO_EC2M /* Binary Curves */ {"nistk163", NID_sect163k1, 163}, {"nistk233", NID_sect233k1, 233}, @@ -1520,7 +1440,7 @@ int speed_main(int argc, char **argv) {"nistb283", NID_sect283r1, 283}, {"nistb409", NID_sect409r1, 409}, {"nistb571", NID_sect571r1, 571}, -# endif +#endif {"brainpoolP256r1", NID_brainpoolP256r1, 256}, {"brainpoolP256t1", NID_brainpoolP256t1, 256}, {"brainpoolP384r1", NID_brainpoolP384r1, 384}, @@ -1531,22 +1451,36 @@ int speed_main(int argc, char **argv) {"X25519", NID_X25519, 253}, {"X448", NID_X448, 448} }; - static const struct { - const char *name; - unsigned int nid; - unsigned int bits; - size_t sigsize; - } test_ed_curves[] = { + static const EC_CURVE ed_curves[EdDSA_NUM] = { /* EdDSA */ {"Ed25519", NID_ED25519, 253, 64}, {"Ed448", NID_ED448, 456, 114} }; - int ecdsa_doit[ECDSA_NUM] = { 0 }; - int ecdh_doit[EC_NUM] = { 0 }; - int eddsa_doit[EdDSA_NUM] = { 0 }; - OPENSSL_assert(OSSL_NELEM(test_curves) >= EC_NUM); - OPENSSL_assert(OSSL_NELEM(test_ed_curves) >= EdDSA_NUM); -#endif /* ndef OPENSSL_NO_EC */ +#ifndef OPENSSL_NO_SM2 + static const EC_CURVE sm2_curves[SM2_NUM] = { + /* SM2 */ + {"CurveSM2", NID_sm2, 256} + }; + uint8_t sm2_doit[SM2_NUM] = { 0 }; +#endif + uint8_t ecdsa_doit[ECDSA_NUM] = { 0 }; + uint8_t ecdh_doit[EC_NUM] = { 0 }; + uint8_t eddsa_doit[EdDSA_NUM] = { 0 }; + + /* checks declarated curves against choices list. */ + OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448); + OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0); + + OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448); + OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0); + + OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1); + OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0); + +#ifndef OPENSSL_NO_SM2 + OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2); + OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0); +#endif prog = opt_init(argc, argv, speed_options); while ((o = opt_next()) != OPT_EOF) { @@ -1564,18 +1498,43 @@ int speed_main(int argc, char **argv) usertime = 0; break; case OPT_EVP: - evp_md = NULL; - evp_cipher = EVP_get_cipherbyname(opt_arg()); - if (evp_cipher == NULL) - evp_md = EVP_get_digestbyname(opt_arg()); - if (evp_cipher == NULL && evp_md == NULL) { + if (doit[D_EVP]) { + BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog); + goto opterr; + } + ERR_set_mark(); + if (!opt_cipher_silent(opt_arg(), &evp_cipher)) { + if (have_md(opt_arg())) + evp_md_name = opt_arg(); + } + if (evp_cipher == NULL && evp_md_name == NULL) { + ERR_clear_last_mark(); BIO_printf(bio_err, "%s: %s is an unknown cipher or digest\n", prog, opt_arg()); goto end; } + ERR_pop_to_mark(); doit[D_EVP] = 1; break; + case OPT_HMAC: + if (!have_md(opt_arg())) { + BIO_printf(bio_err, "%s: %s is an unknown digest\n", + prog, opt_arg()); + goto end; + } + evp_mac_mdname = opt_arg(); + doit[D_HMAC] = 1; + break; + case OPT_CMAC: + if (!have_cipher(opt_arg())) { + BIO_printf(bio_err, "%s: %s is an unknown cipher\n", + prog, opt_arg()); + goto end; + } + evp_mac_ciphername = opt_arg(); + doit[D_EVP_CMAC] = 1; + break; case OPT_DECRYPT: decrypt = 1; break; @@ -1590,7 +1549,7 @@ int speed_main(int argc, char **argv) case OPT_MULTI: #ifndef NO_FORK multi = atoi(opt_arg()); - if (multi >= INT_MAX / (int)sizeof(int)) { + if ((size_t)multi >= SIZE_MAX / sizeof(int)) { BIO_printf(bio_err, "%s: multi argument too large\n", prog); return 0; } @@ -1612,8 +1571,7 @@ int speed_main(int argc, char **argv) #endif break; case OPT_MISALIGN: - if (!opt_int(opt_arg(), &misalign)) - goto end; + misalign = opt_int_arg(); if (misalign > MISALIGN) { BIO_printf(bio_err, "%s: Maximum offset is %d\n", prog, MISALIGN); @@ -1636,13 +1594,17 @@ int speed_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; - case OPT_PRIMES: - if (!opt_int(opt_arg(), &primes)) + case OPT_PROV_CASES: + if (!opt_provider(o)) goto end; break; + case OPT_PRIMES: + primes = opt_int_arg(); + break; case OPT_SECONDS: seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa - = seconds.ecdh = seconds.eddsa = atoi(opt_arg()); + = seconds.ecdh = seconds.eddsa + = seconds.sm2 = seconds.ffdh = atoi(opt_arg()); break; case OPT_BYTES: lengths_single = atoi(opt_arg()); @@ -1654,89 +1616,112 @@ int speed_main(int argc, char **argv) break; } } + + /* Remaining arguments are algorithms. */ argc = opt_num_rest(); argv = opt_rest(); - /* Remaining arguments are algorithms. */ + if (!app_RAND_load()) + goto end; + for (; *argv; argv++) { - if (found(*argv, doit_choices, &i)) { + const char *algo = *argv; + + if (opt_found(algo, doit_choices, &i)) { doit[i] = 1; continue; } -#ifndef OPENSSL_NO_DES - if (strcmp(*argv, "des") == 0) { + if (strcmp(algo, "des") == 0) { doit[D_CBC_DES] = doit[D_EDE3_DES] = 1; continue; } -#endif - if (strcmp(*argv, "sha") == 0) { + if (strcmp(algo, "sha") == 0) { doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1; continue; } -#ifndef OPENSSL_NO_RSA - if (strcmp(*argv, "openssl") == 0) - continue; - if (strcmp(*argv, "rsa") == 0) { - for (loop = 0; loop < OSSL_NELEM(rsa_doit); loop++) - rsa_doit[loop] = 1; - continue; - } - if (found(*argv, rsa_choices, &i)) { - rsa_doit[i] = 1; +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (strcmp(algo, "openssl") == 0) /* just for compatibility */ continue; - } #endif -#ifndef OPENSSL_NO_DSA - if (strcmp(*argv, "dsa") == 0) { - dsa_doit[R_DSA_512] = dsa_doit[R_DSA_1024] = - dsa_doit[R_DSA_2048] = 1; - continue; + if (strncmp(algo, "rsa", 3) == 0) { + if (algo[3] == '\0') { + memset(rsa_doit, 1, sizeof(rsa_doit)); + continue; + } + if (opt_found(algo, rsa_choices, &i)) { + rsa_doit[i] = 1; + continue; + } } - if (found(*argv, dsa_choices, &i)) { - dsa_doit[i] = 2; - continue; +#ifndef OPENSSL_NO_DH + if (strncmp(algo, "ffdh", 4) == 0) { + if (algo[4] == '\0') { + memset(ffdh_doit, 1, sizeof(ffdh_doit)); + continue; + } + if (opt_found(algo, ffdh_choices, &i)) { + ffdh_doit[i] = 2; + continue; + } } #endif - if (strcmp(*argv, "aes") == 0) { + if (strncmp(algo, "dsa", 3) == 0) { + if (algo[3] == '\0') { + memset(dsa_doit, 1, sizeof(dsa_doit)); + continue; + } + if (opt_found(algo, dsa_choices, &i)) { + dsa_doit[i] = 2; + continue; + } + } + if (strcmp(algo, "aes") == 0) { doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1; continue; } -#ifndef OPENSSL_NO_CAMELLIA - if (strcmp(*argv, "camellia") == 0) { + if (strcmp(algo, "camellia") == 0) { doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1; continue; } -#endif -#ifndef OPENSSL_NO_EC - if (strcmp(*argv, "ecdsa") == 0) { - for (loop = 0; loop < OSSL_NELEM(ecdsa_doit); loop++) - ecdsa_doit[loop] = 1; - continue; + if (strncmp(algo, "ecdsa", 5) == 0) { + if (algo[5] == '\0') { + memset(ecdsa_doit, 1, sizeof(ecdsa_doit)); + continue; + } + if (opt_found(algo, ecdsa_choices, &i)) { + ecdsa_doit[i] = 2; + continue; + } } - if (found(*argv, ecdsa_choices, &i)) { - ecdsa_doit[i] = 2; - continue; + if (strncmp(algo, "ecdh", 4) == 0) { + if (algo[4] == '\0') { + memset(ecdh_doit, 1, sizeof(ecdh_doit)); + continue; + } + if (opt_found(algo, ecdh_choices, &i)) { + ecdh_doit[i] = 2; + continue; + } } - if (strcmp(*argv, "ecdh") == 0) { - for (loop = 0; loop < OSSL_NELEM(ecdh_doit); loop++) - ecdh_doit[loop] = 1; + if (strcmp(algo, "eddsa") == 0) { + memset(eddsa_doit, 1, sizeof(eddsa_doit)); continue; } - if (found(*argv, ecdh_choices, &i)) { - ecdh_doit[i] = 2; + if (opt_found(algo, eddsa_choices, &i)) { + eddsa_doit[i] = 2; continue; } - if (strcmp(*argv, "eddsa") == 0) { - for (loop = 0; loop < OSSL_NELEM(eddsa_doit); loop++) - eddsa_doit[loop] = 1; +#ifndef OPENSSL_NO_SM2 + if (strcmp(algo, "sm2") == 0) { + memset(sm2_doit, 1, sizeof(sm2_doit)); continue; } - if (found(*argv, eddsa_choices, &i)) { - eddsa_doit[i] = 2; + if (opt_found(algo, sm2_choices, &i)) { + sm2_doit[i] = 2; continue; } #endif - BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, *argv); + BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo); goto end; } @@ -1745,22 +1730,22 @@ int speed_main(int argc, char **argv) if (evp_cipher == NULL) { BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n"); goto end; - } else if (!(EVP_CIPHER_flags(evp_cipher) & + } else if (!(EVP_CIPHER_get_flags(evp_cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { BIO_printf(bio_err, "%s is not an AEAD cipher\n", - OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher))); + EVP_CIPHER_get0_name(evp_cipher)); goto end; } } if (multiblock) { if (evp_cipher == NULL) { - BIO_printf(bio_err,"-mb can be used only with a multi-block" - " capable cipher\n"); + BIO_printf(bio_err, "-mb can be used only with a multi-block" + " capable cipher\n"); goto end; - } else if (!(EVP_CIPHER_flags(evp_cipher) & + } else if (!(EVP_CIPHER_get_flags(evp_cipher) & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) { BIO_printf(bio_err, "%s is not a multi-block capable\n", - OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher))); + EVP_CIPHER_get0_name(evp_cipher)); goto end; } else if (async_jobs > 0) { BIO_printf(bio_err, "Async mode is not supported with -mb"); @@ -1794,6 +1779,10 @@ int speed_main(int argc, char **argv) buflen = lengths[size_num - 1]; if (buflen < 36) /* size of random vector in RSA benchmark */ buflen = 36; + if (INT_MAX - (MAX_MISALIGNMENT + 1) < buflen) { + BIO_printf(bio_err, "Error: buffer size too large\n"); + goto end; + } buflen += MAX_MISALIGNMENT + 1; loopargs[i].buf_malloc = app_malloc(buflen, "input buffer"); loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer"); @@ -1803,9 +1792,13 @@ int speed_main(int argc, char **argv) /* Align the start of buffers on a 64 byte boundary */ loopargs[i].buf = loopargs[i].buf_malloc + misalign; loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign; -#ifndef OPENSSL_NO_EC + loopargs[i].buflen = buflen - misalign; + loopargs[i].sigsize = buflen - misalign; loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a"); loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b"); +#ifndef OPENSSL_NO_DH + loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a"); + loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b"); #endif } @@ -1818,25 +1811,43 @@ int speed_main(int argc, char **argv) e = setup_engine(engine_id, 0); /* No parameters; turn on everything. */ - if ((argc == 0) && !doit[D_EVP]) { - for (i = 0; i < ALGOR_NUM; i++) - if (i != D_EVP) - doit[i] = 1; -#ifndef OPENSSL_NO_RSA - for (i = 0; i < RSA_NUM; i++) - rsa_doit[i] = 1; -#endif -#ifndef OPENSSL_NO_DSA - for (i = 0; i < DSA_NUM; i++) - dsa_doit[i] = 1; + if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC]) { + memset(doit, 1, sizeof(doit)); + doit[D_EVP] = doit[D_EVP_CMAC] = 0; + ERR_set_mark(); + for (i = D_MD2; i <= D_WHIRLPOOL; i++) { + if (!have_md(names[i])) + doit[i] = 0; + } + for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) { + if (!have_cipher(names[i])) + doit[i] = 0; + } + if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC", + app_get0_propq())) != NULL) { + EVP_MAC_free(mac); + mac = NULL; + } else { + doit[D_GHASH] = 0; + } + if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", + app_get0_propq())) != NULL) { + EVP_MAC_free(mac); + mac = NULL; + } else { + doit[D_HMAC] = 0; + } + ERR_pop_to_mark(); + memset(rsa_doit, 1, sizeof(rsa_doit)); +#ifndef OPENSSL_NO_DH + memset(ffdh_doit, 1, sizeof(ffdh_doit)); #endif -#ifndef OPENSSL_NO_EC - for (loop = 0; loop < OSSL_NELEM(ecdsa_doit); loop++) - ecdsa_doit[loop] = 1; - for (loop = 0; loop < OSSL_NELEM(ecdh_doit); loop++) - ecdh_doit[loop] = 1; - for (loop = 0; loop < OSSL_NELEM(eddsa_doit); loop++) - eddsa_doit[loop] = 1; + memset(dsa_doit, 1, sizeof(dsa_doit)); + memset(ecdsa_doit, 1, sizeof(ecdsa_doit)); + memset(ecdh_doit, 1, sizeof(ecdh_doit)); + memset(eddsa_doit, 1, sizeof(eddsa_doit)); +#ifndef OPENSSL_NO_SM2 + memset(sm2_doit, 1, sizeof(sm2_doit)); #endif } for (i = 0; i < ALGOR_NUM; i++) @@ -1848,308 +1859,10 @@ int speed_main(int argc, char **argv) "You have chosen to measure elapsed time " "instead of user CPU time.\n"); -#ifndef OPENSSL_NO_RSA - for (i = 0; i < loopargs_len; i++) { - if (primes > RSA_DEFAULT_PRIME_NUM) { - /* for multi-prime RSA, skip this */ - break; - } - for (k = 0; k < RSA_NUM; k++) { - const unsigned char *p; - - p = rsa_data[k]; - loopargs[i].rsa_key[k] = - d2i_RSAPrivateKey(NULL, &p, rsa_data_length[k]); - if (loopargs[i].rsa_key[k] == NULL) { - BIO_printf(bio_err, - "internal error loading RSA key number %d\n", k); - goto end; - } - } - } -#endif -#ifndef OPENSSL_NO_DSA - for (i = 0; i < loopargs_len; i++) { - loopargs[i].dsa_key[0] = get_dsa(512); - loopargs[i].dsa_key[1] = get_dsa(1024); - loopargs[i].dsa_key[2] = get_dsa(2048); - } -#endif -#ifndef OPENSSL_NO_DES - DES_set_key_unchecked(&key, &sch); - DES_set_key_unchecked(&key2, &sch2); - DES_set_key_unchecked(&key3, &sch3); -#endif - AES_set_encrypt_key(key16, 128, &aes_ks1); - AES_set_encrypt_key(key24, 192, &aes_ks2); - AES_set_encrypt_key(key32, 256, &aes_ks3); -#ifndef OPENSSL_NO_CAMELLIA - Camellia_set_key(key16, 128, &camellia_ks1); - Camellia_set_key(ckey24, 192, &camellia_ks2); - Camellia_set_key(ckey32, 256, &camellia_ks3); -#endif -#ifndef OPENSSL_NO_IDEA - IDEA_set_encrypt_key(key16, &idea_ks); -#endif -#ifndef OPENSSL_NO_SEED - SEED_set_key(key16, &seed_ks); -#endif -#ifndef OPENSSL_NO_RC4 - RC4_set_key(&rc4_ks, 16, key16); -#endif -#ifndef OPENSSL_NO_RC2 - RC2_set_key(&rc2_ks, 16, key16, 128); -#endif -#ifndef OPENSSL_NO_RC5 - RC5_32_set_key(&rc5_ks, 16, key16, 12); -#endif -#ifndef OPENSSL_NO_BF - BF_set_key(&bf_ks, 16, key16); -#endif -#ifndef OPENSSL_NO_CAST - CAST_set_key(&cast_ks, 16, key16); -#endif -#ifndef SIGALRM -# ifndef OPENSSL_NO_DES - BIO_printf(bio_err, "First we calculate the approximate speed ...\n"); - count = 10; - do { - long it; - count *= 2; - Time_F(START); - for (it = count; it; it--) - DES_ecb_encrypt((DES_cblock *)loopargs[0].buf, - (DES_cblock *)loopargs[0].buf, &sch, DES_ENCRYPT); - d = Time_F(STOP); - } while (d < 3); - save_count = count; - c[D_MD2][0] = count / 10; - c[D_MDC2][0] = count / 10; - c[D_MD4][0] = count; - c[D_MD5][0] = count; - c[D_HMAC][0] = count; - c[D_SHA1][0] = count; - c[D_RMD160][0] = count; - c[D_RC4][0] = count * 5; - c[D_CBC_DES][0] = count; - c[D_EDE3_DES][0] = count / 3; - c[D_CBC_IDEA][0] = count; - c[D_CBC_SEED][0] = count; - c[D_CBC_RC2][0] = count; - c[D_CBC_RC5][0] = count; - c[D_CBC_BF][0] = count; - c[D_CBC_CAST][0] = count; - c[D_CBC_128_AES][0] = count; - c[D_CBC_192_AES][0] = count; - c[D_CBC_256_AES][0] = count; - c[D_CBC_128_CML][0] = count; - c[D_CBC_192_CML][0] = count; - c[D_CBC_256_CML][0] = count; - c[D_SHA256][0] = count; - c[D_SHA512][0] = count; - c[D_WHIRLPOOL][0] = count; - c[D_IGE_128_AES][0] = count; - c[D_IGE_192_AES][0] = count; - c[D_IGE_256_AES][0] = count; - c[D_GHASH][0] = count; - c[D_RAND][0] = count; - - for (i = 1; i < size_num; i++) { - long l0, l1; - - l0 = (long)lengths[0]; - l1 = (long)lengths[i]; - - c[D_MD2][i] = c[D_MD2][0] * 4 * l0 / l1; - c[D_MDC2][i] = c[D_MDC2][0] * 4 * l0 / l1; - c[D_MD4][i] = c[D_MD4][0] * 4 * l0 / l1; - c[D_MD5][i] = c[D_MD5][0] * 4 * l0 / l1; - c[D_HMAC][i] = c[D_HMAC][0] * 4 * l0 / l1; - c[D_SHA1][i] = c[D_SHA1][0] * 4 * l0 / l1; - c[D_RMD160][i] = c[D_RMD160][0] * 4 * l0 / l1; - c[D_SHA256][i] = c[D_SHA256][0] * 4 * l0 / l1; - c[D_SHA512][i] = c[D_SHA512][0] * 4 * l0 / l1; - c[D_WHIRLPOOL][i] = c[D_WHIRLPOOL][0] * 4 * l0 / l1; - c[D_GHASH][i] = c[D_GHASH][0] * 4 * l0 / l1; - c[D_RAND][i] = c[D_RAND][0] * 4 * l0 / l1; - - l0 = (long)lengths[i - 1]; - - c[D_RC4][i] = c[D_RC4][i - 1] * l0 / l1; - c[D_CBC_DES][i] = c[D_CBC_DES][i - 1] * l0 / l1; - c[D_EDE3_DES][i] = c[D_EDE3_DES][i - 1] * l0 / l1; - c[D_CBC_IDEA][i] = c[D_CBC_IDEA][i - 1] * l0 / l1; - c[D_CBC_SEED][i] = c[D_CBC_SEED][i - 1] * l0 / l1; - c[D_CBC_RC2][i] = c[D_CBC_RC2][i - 1] * l0 / l1; - c[D_CBC_RC5][i] = c[D_CBC_RC5][i - 1] * l0 / l1; - c[D_CBC_BF][i] = c[D_CBC_BF][i - 1] * l0 / l1; - c[D_CBC_CAST][i] = c[D_CBC_CAST][i - 1] * l0 / l1; - c[D_CBC_128_AES][i] = c[D_CBC_128_AES][i - 1] * l0 / l1; - c[D_CBC_192_AES][i] = c[D_CBC_192_AES][i - 1] * l0 / l1; - c[D_CBC_256_AES][i] = c[D_CBC_256_AES][i - 1] * l0 / l1; - c[D_CBC_128_CML][i] = c[D_CBC_128_CML][i - 1] * l0 / l1; - c[D_CBC_192_CML][i] = c[D_CBC_192_CML][i - 1] * l0 / l1; - c[D_CBC_256_CML][i] = c[D_CBC_256_CML][i - 1] * l0 / l1; - c[D_IGE_128_AES][i] = c[D_IGE_128_AES][i - 1] * l0 / l1; - c[D_IGE_192_AES][i] = c[D_IGE_192_AES][i - 1] * l0 / l1; - c[D_IGE_256_AES][i] = c[D_IGE_256_AES][i - 1] * l0 / l1; - } - -# ifndef OPENSSL_NO_RSA - rsa_c[R_RSA_512][0] = count / 2000; - rsa_c[R_RSA_512][1] = count / 400; - for (i = 1; i < RSA_NUM; i++) { - rsa_c[i][0] = rsa_c[i - 1][0] / 8; - rsa_c[i][1] = rsa_c[i - 1][1] / 4; - if (rsa_doit[i] <= 1 && rsa_c[i][0] == 0) - rsa_doit[i] = 0; - else { - if (rsa_c[i][0] == 0) { - rsa_c[i][0] = 1; /* Set minimum iteration Nb to 1. */ - rsa_c[i][1] = 20; - } - } - } -# endif - -# ifndef OPENSSL_NO_DSA - dsa_c[R_DSA_512][0] = count / 1000; - dsa_c[R_DSA_512][1] = count / 1000 / 2; - for (i = 1; i < DSA_NUM; i++) { - dsa_c[i][0] = dsa_c[i - 1][0] / 4; - dsa_c[i][1] = dsa_c[i - 1][1] / 4; - if (dsa_doit[i] <= 1 && dsa_c[i][0] == 0) - dsa_doit[i] = 0; - else { - if (dsa_c[i][0] == 0) { - dsa_c[i][0] = 1; /* Set minimum iteration Nb to 1. */ - dsa_c[i][1] = 1; - } - } - } -# endif - -# ifndef OPENSSL_NO_EC - ecdsa_c[R_EC_P160][0] = count / 1000; - ecdsa_c[R_EC_P160][1] = count / 1000 / 2; - for (i = R_EC_P192; i <= R_EC_P521; i++) { - ecdsa_c[i][0] = ecdsa_c[i - 1][0] / 2; - ecdsa_c[i][1] = ecdsa_c[i - 1][1] / 2; - if (ecdsa_doit[i] <= 1 && ecdsa_c[i][0] == 0) - ecdsa_doit[i] = 0; - else { - if (ecdsa_c[i][0] == 0) { - ecdsa_c[i][0] = 1; - ecdsa_c[i][1] = 1; - } - } - } -# ifndef OPENSSL_NO_EC2M - ecdsa_c[R_EC_K163][0] = count / 1000; - ecdsa_c[R_EC_K163][1] = count / 1000 / 2; - for (i = R_EC_K233; i <= R_EC_K571; i++) { - ecdsa_c[i][0] = ecdsa_c[i - 1][0] / 2; - ecdsa_c[i][1] = ecdsa_c[i - 1][1] / 2; - if (ecdsa_doit[i] <= 1 && ecdsa_c[i][0] == 0) - ecdsa_doit[i] = 0; - else { - if (ecdsa_c[i][0] == 0) { - ecdsa_c[i][0] = 1; - ecdsa_c[i][1] = 1; - } - } - } - ecdsa_c[R_EC_B163][0] = count / 1000; - ecdsa_c[R_EC_B163][1] = count / 1000 / 2; - for (i = R_EC_B233; i <= R_EC_B571; i++) { - ecdsa_c[i][0] = ecdsa_c[i - 1][0] / 2; - ecdsa_c[i][1] = ecdsa_c[i - 1][1] / 2; - if (ecdsa_doit[i] <= 1 && ecdsa_c[i][0] == 0) - ecdsa_doit[i] = 0; - else { - if (ecdsa_c[i][0] == 0) { - ecdsa_c[i][0] = 1; - ecdsa_c[i][1] = 1; - } - } - } -# endif - - ecdh_c[R_EC_P160][0] = count / 1000; - for (i = R_EC_P192; i <= R_EC_P521; i++) { - ecdh_c[i][0] = ecdh_c[i - 1][0] / 2; - if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0) - ecdh_doit[i] = 0; - else { - if (ecdh_c[i][0] == 0) { - ecdh_c[i][0] = 1; - } - } - } -# ifndef OPENSSL_NO_EC2M - ecdh_c[R_EC_K163][0] = count / 1000; - for (i = R_EC_K233; i <= R_EC_K571; i++) { - ecdh_c[i][0] = ecdh_c[i - 1][0] / 2; - if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0) - ecdh_doit[i] = 0; - else { - if (ecdh_c[i][0] == 0) { - ecdh_c[i][0] = 1; - } - } - } - ecdh_c[R_EC_B163][0] = count / 1000; - for (i = R_EC_B233; i <= R_EC_B571; i++) { - ecdh_c[i][0] = ecdh_c[i - 1][0] / 2; - if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0) - ecdh_doit[i] = 0; - else { - if (ecdh_c[i][0] == 0) { - ecdh_c[i][0] = 1; - } - } - } -# endif - /* repeated code good to factorize */ - ecdh_c[R_EC_BRP256R1][0] = count / 1000; - for (i = R_EC_BRP384R1; i <= R_EC_BRP512R1; i += 2) { - ecdh_c[i][0] = ecdh_c[i - 2][0] / 2; - if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0) - ecdh_doit[i] = 0; - else { - if (ecdh_c[i][0] == 0) { - ecdh_c[i][0] = 1; - } - } - } - ecdh_c[R_EC_BRP256T1][0] = count / 1000; - for (i = R_EC_BRP384T1; i <= R_EC_BRP512T1; i += 2) { - ecdh_c[i][0] = ecdh_c[i - 2][0] / 2; - if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0) - ecdh_doit[i] = 0; - else { - if (ecdh_c[i][0] == 0) { - ecdh_c[i][0] = 1; - } - } - } - /* default iteration count for the last two EC Curves */ - ecdh_c[R_EC_X25519][0] = count / 1800; - ecdh_c[R_EC_X448][0] = count / 7200; - - eddsa_c[R_EC_Ed25519][0] = count / 1800; - eddsa_c[R_EC_Ed448][0] = count / 7200; -# endif - -# else -/* not worth fixing */ -# error "You cannot disable DES on systems without SIGALRM." -# endif /* OPENSSL_NO_DES */ -#elif SIGALRM > 0 +#if SIGALRM > 0 signal(SIGALRM, alarmed); -#endif /* SIGALRM */ +#endif -#ifndef OPENSSL_NO_MD2 if (doit[D_MD2]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum], @@ -2158,10 +1871,11 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs); d = Time_F(STOP); print_result(D_MD2, testnum, count, d); + if (count < 0) + break; } } -#endif -#ifndef OPENSSL_NO_MDC2 + if (doit[D_MDC2]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum], @@ -2170,11 +1884,11 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs); d = Time_F(STOP); print_result(D_MDC2, testnum, count, d); + if (count < 0) + break; } } -#endif -#ifndef OPENSSL_NO_MD4 if (doit[D_MD4]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum], @@ -2183,11 +1897,11 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs); d = Time_F(STOP); print_result(D_MD4, testnum, count, d); + if (count < 0) + break; } } -#endif -#ifndef OPENSSL_NO_MD5 if (doit[D_MD5]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum], @@ -2196,35 +1910,11 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, MD5_loop, loopargs); d = Time_F(STOP); print_result(D_MD5, testnum, count, d); + if (count < 0) + break; } } - if (doit[D_HMAC]) { - static const char hmac_key[] = "This is a key..."; - int len = strlen(hmac_key); - - for (i = 0; i < loopargs_len; i++) { - loopargs[i].hctx = HMAC_CTX_new(); - if (loopargs[i].hctx == NULL) { - BIO_printf(bio_err, "HMAC malloc failure, exiting..."); - exit(1); - } - - HMAC_Init_ex(loopargs[i].hctx, hmac_key, len, EVP_md5(), NULL); - } - for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum], - seconds.sym); - Time_F(START); - count = run_benchmark(async_jobs, HMAC_loop, loopargs); - d = Time_F(STOP); - print_result(D_HMAC, testnum, count, d); - } - for (i = 0; i < loopargs_len; i++) { - HMAC_CTX_free(loopargs[i].hctx); - } - } -#endif if (doit[D_SHA1]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum], @@ -2233,8 +1923,11 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, SHA1_loop, loopargs); d = Time_F(STOP); print_result(D_SHA1, testnum, count, d); + if (count < 0) + break; } } + if (doit[D_SHA256]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_SHA256], c[D_SHA256][testnum], @@ -2243,8 +1936,11 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, SHA256_loop, loopargs); d = Time_F(STOP); print_result(D_SHA256, testnum, count, d); + if (count < 0) + break; } } + if (doit[D_SHA512]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_SHA512], c[D_SHA512][testnum], @@ -2253,9 +1949,11 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, SHA512_loop, loopargs); d = Time_F(STOP); print_result(D_SHA512, testnum, count, d); + if (count < 0) + break; } } -#ifndef OPENSSL_NO_WHIRLPOOL + if (doit[D_WHIRLPOOL]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum], @@ -2264,11 +1962,11 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs); d = Time_F(STOP); print_result(D_WHIRLPOOL, testnum, count, d); + if (count < 0) + break; } } -#endif -#ifndef OPENSSL_NO_RMD160 if (doit[D_RMD160]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_RMD160], c[D_RMD160][testnum], @@ -2277,319 +1975,215 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs); d = Time_F(STOP); print_result(D_RMD160, testnum, count, d); + if (count < 0) + break; } } -#endif -#ifndef OPENSSL_NO_RC4 - if (doit[D_RC4]) { + + if (doit[D_HMAC]) { + static const char hmac_key[] = "This is a key..."; + int len = strlen(hmac_key); + OSSL_PARAM params[3]; + + mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq()); + if (mac == NULL || evp_mac_mdname == NULL) + goto end; + + evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname), + "HMAC name"); + sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname); + names[D_HMAC] = evp_hmac_name; + + params[0] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + evp_mac_mdname, 0); + params[1] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (char *)hmac_key, len); + params[2] = OSSL_PARAM_construct_end(); + + for (i = 0; i < loopargs_len; i++) { + loopargs[i].mctx = EVP_MAC_CTX_new(mac); + if (loopargs[i].mctx == NULL) + goto end; + + if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params)) + goto skip_hmac; /* Digest not found */ + } for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_RC4], c[D_RC4][testnum], lengths[testnum], + print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum], seconds.sym); Time_F(START); - count = run_benchmark(async_jobs, RC4_loop, loopargs); + count = run_benchmark(async_jobs, HMAC_loop, loopargs); d = Time_F(STOP); - print_result(D_RC4, testnum, count, d); + print_result(D_HMAC, testnum, count, d); + if (count < 0) + break; } + for (i = 0; i < loopargs_len; i++) + EVP_MAC_CTX_free(loopargs[i].mctx); + EVP_MAC_free(mac); + mac = NULL; } -#endif -#ifndef OPENSSL_NO_DES +skip_hmac: if (doit[D_CBC_DES]) { - for (testnum = 0; testnum < size_num; testnum++) { + int st = 1; + + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].ctx = init_evp_cipher_ctx("des-cbc", deskey, + sizeof(deskey) / 3); + st = loopargs[i].ctx != NULL; + } + algindex = D_CBC_DES; + for (testnum = 0; st && testnum < size_num; testnum++) { print_message(names[D_CBC_DES], c[D_CBC_DES][testnum], lengths[testnum], seconds.sym); Time_F(START); - count = run_benchmark(async_jobs, DES_ncbc_encrypt_loop, loopargs); + count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); d = Time_F(STOP); print_result(D_CBC_DES, testnum, count, d); } + for (i = 0; i < loopargs_len; i++) + EVP_CIPHER_CTX_free(loopargs[i].ctx); } if (doit[D_EDE3_DES]) { - for (testnum = 0; testnum < size_num; testnum++) { + int st = 1; + + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].ctx = init_evp_cipher_ctx("des-ede3-cbc", deskey, + sizeof(deskey)); + st = loopargs[i].ctx != NULL; + } + algindex = D_EDE3_DES; + for (testnum = 0; st && testnum < size_num; testnum++) { print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum], lengths[testnum], seconds.sym); Time_F(START); count = - run_benchmark(async_jobs, DES_ede3_cbc_encrypt_loop, loopargs); + run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); d = Time_F(STOP); print_result(D_EDE3_DES, testnum, count, d); } + for (i = 0; i < loopargs_len; i++) + EVP_CIPHER_CTX_free(loopargs[i].ctx); } -#endif - if (doit[D_CBC_128_AES]) { - for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_CBC_128_AES], c[D_CBC_128_AES][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - count = - run_benchmark(async_jobs, AES_cbc_128_encrypt_loop, loopargs); - d = Time_F(STOP); - print_result(D_CBC_128_AES, testnum, count, d); - } - } - if (doit[D_CBC_192_AES]) { - for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_CBC_192_AES], c[D_CBC_192_AES][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - count = - run_benchmark(async_jobs, AES_cbc_192_encrypt_loop, loopargs); - d = Time_F(STOP); - print_result(D_CBC_192_AES, testnum, count, d); - } - } - if (doit[D_CBC_256_AES]) { - for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_CBC_256_AES], c[D_CBC_256_AES][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - count = - run_benchmark(async_jobs, AES_cbc_256_encrypt_loop, loopargs); - d = Time_F(STOP); - print_result(D_CBC_256_AES, testnum, count, d); - } - } + for (k = 0; k < 3; k++) { + algindex = D_CBC_128_AES + k; + if (doit[algindex]) { + int st = 1; - if (doit[D_IGE_128_AES]) { - for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_IGE_128_AES], c[D_IGE_128_AES][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - count = - run_benchmark(async_jobs, AES_ige_128_encrypt_loop, loopargs); - d = Time_F(STOP); - print_result(D_IGE_128_AES, testnum, count, d); + keylen = 16 + k * 8; + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].ctx = init_evp_cipher_ctx(names[algindex], + key32, keylen); + st = loopargs[i].ctx != NULL; + } + + for (testnum = 0; st && testnum < size_num; testnum++) { + print_message(names[algindex], c[algindex][testnum], + lengths[testnum], seconds.sym); + Time_F(START); + count = + run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); + d = Time_F(STOP); + print_result(algindex, testnum, count, d); + } + for (i = 0; i < loopargs_len; i++) + EVP_CIPHER_CTX_free(loopargs[i].ctx); } } - if (doit[D_IGE_192_AES]) { - for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_IGE_192_AES], c[D_IGE_192_AES][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - count = - run_benchmark(async_jobs, AES_ige_192_encrypt_loop, loopargs); - d = Time_F(STOP); - print_result(D_IGE_192_AES, testnum, count, d); + + for (k = 0; k < 3; k++) { + algindex = D_CBC_128_CML + k; + if (doit[algindex]) { + int st = 1; + + keylen = 16 + k * 8; + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].ctx = init_evp_cipher_ctx(names[algindex], + key32, keylen); + st = loopargs[i].ctx != NULL; + } + + for (testnum = 0; st && testnum < size_num; testnum++) { + print_message(names[algindex], c[algindex][testnum], + lengths[testnum], seconds.sym); + Time_F(START); + count = + run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); + d = Time_F(STOP); + print_result(algindex, testnum, count, d); + } + for (i = 0; i < loopargs_len; i++) + EVP_CIPHER_CTX_free(loopargs[i].ctx); } } - if (doit[D_IGE_256_AES]) { - for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_IGE_256_AES], c[D_IGE_256_AES][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - count = - run_benchmark(async_jobs, AES_ige_256_encrypt_loop, loopargs); - d = Time_F(STOP); - print_result(D_IGE_256_AES, testnum, count, d); + + for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) { + if (doit[algindex]) { + int st = 1; + + keylen = 16; + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].ctx = init_evp_cipher_ctx(names[algindex], + key32, keylen); + st = loopargs[i].ctx != NULL; + } + + for (testnum = 0; st && testnum < size_num; testnum++) { + print_message(names[algindex], c[algindex][testnum], + lengths[testnum], seconds.sym); + Time_F(START); + count = + run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); + d = Time_F(STOP); + print_result(algindex, testnum, count, d); + } + for (i = 0; i < loopargs_len; i++) + EVP_CIPHER_CTX_free(loopargs[i].ctx); } } if (doit[D_GHASH]) { + static const char gmac_iv[] = "0123456789ab"; + OSSL_PARAM params[3]; + + mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq()); + if (mac == NULL) + goto end; + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER, + "aes-128-gcm", 0); + params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV, + (char *)gmac_iv, + sizeof(gmac_iv) - 1); + params[2] = OSSL_PARAM_construct_end(); + for (i = 0; i < loopargs_len; i++) { - loopargs[i].gcm_ctx = - CRYPTO_gcm128_new(&aes_ks1, (block128_f) AES_encrypt); - CRYPTO_gcm128_setiv(loopargs[i].gcm_ctx, - (unsigned char *)"0123456789ab", 12); - } + loopargs[i].mctx = EVP_MAC_CTX_new(mac); + if (loopargs[i].mctx == NULL) + goto end; + if (!EVP_MAC_init(loopargs[i].mctx, key32, 16, params)) + goto end; + } for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_GHASH], c[D_GHASH][testnum], - lengths[testnum], seconds.sym); + print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum], + seconds.sym); Time_F(START); - count = run_benchmark(async_jobs, CRYPTO_gcm128_aad_loop, loopargs); + count = run_benchmark(async_jobs, GHASH_loop, loopargs); d = Time_F(STOP); print_result(D_GHASH, testnum, count, d); + if (count < 0) + break; } for (i = 0; i < loopargs_len; i++) - CRYPTO_gcm128_release(loopargs[i].gcm_ctx); - } -#ifndef OPENSSL_NO_CAMELLIA - if (doit[D_CBC_128_CML]) { - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported with %s\n", - names[D_CBC_128_CML]); - doit[D_CBC_128_CML] = 0; - } - for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { - print_message(names[D_CBC_128_CML], c[D_CBC_128_CML][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - for (count = 0; COND(c[D_CBC_128_CML][testnum]); count++) - Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &camellia_ks1, - iv, CAMELLIA_ENCRYPT); - d = Time_F(STOP); - print_result(D_CBC_128_CML, testnum, count, d); - } - } - if (doit[D_CBC_192_CML]) { - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported with %s\n", - names[D_CBC_192_CML]); - doit[D_CBC_192_CML] = 0; - } - for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { - print_message(names[D_CBC_192_CML], c[D_CBC_192_CML][testnum], - lengths[testnum], seconds.sym); - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported, exiting..."); - exit(1); - } - Time_F(START); - for (count = 0; COND(c[D_CBC_192_CML][testnum]); count++) - Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &camellia_ks2, - iv, CAMELLIA_ENCRYPT); - d = Time_F(STOP); - print_result(D_CBC_192_CML, testnum, count, d); - } - } - if (doit[D_CBC_256_CML]) { - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported with %s\n", - names[D_CBC_256_CML]); - doit[D_CBC_256_CML] = 0; - } - for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { - print_message(names[D_CBC_256_CML], c[D_CBC_256_CML][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - for (count = 0; COND(c[D_CBC_256_CML][testnum]); count++) - Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &camellia_ks3, - iv, CAMELLIA_ENCRYPT); - d = Time_F(STOP); - print_result(D_CBC_256_CML, testnum, count, d); - } - } -#endif -#ifndef OPENSSL_NO_IDEA - if (doit[D_CBC_IDEA]) { - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported with %s\n", - names[D_CBC_IDEA]); - doit[D_CBC_IDEA] = 0; - } - for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { - print_message(names[D_CBC_IDEA], c[D_CBC_IDEA][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - for (count = 0; COND(c[D_CBC_IDEA][testnum]); count++) - IDEA_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &idea_ks, - iv, IDEA_ENCRYPT); - d = Time_F(STOP); - print_result(D_CBC_IDEA, testnum, count, d); - } - } -#endif -#ifndef OPENSSL_NO_SEED - if (doit[D_CBC_SEED]) { - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported with %s\n", - names[D_CBC_SEED]); - doit[D_CBC_SEED] = 0; - } - for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { - print_message(names[D_CBC_SEED], c[D_CBC_SEED][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - for (count = 0; COND(c[D_CBC_SEED][testnum]); count++) - SEED_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &seed_ks, iv, 1); - d = Time_F(STOP); - print_result(D_CBC_SEED, testnum, count, d); - } - } -#endif -#ifndef OPENSSL_NO_RC2 - if (doit[D_CBC_RC2]) { - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported with %s\n", - names[D_CBC_RC2]); - doit[D_CBC_RC2] = 0; - } - for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { - print_message(names[D_CBC_RC2], c[D_CBC_RC2][testnum], - lengths[testnum], seconds.sym); - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported, exiting..."); - exit(1); - } - Time_F(START); - for (count = 0; COND(c[D_CBC_RC2][testnum]); count++) - RC2_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &rc2_ks, - iv, RC2_ENCRYPT); - d = Time_F(STOP); - print_result(D_CBC_RC2, testnum, count, d); - } - } -#endif -#ifndef OPENSSL_NO_RC5 - if (doit[D_CBC_RC5]) { - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported with %s\n", - names[D_CBC_RC5]); - doit[D_CBC_RC5] = 0; - } - for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { - print_message(names[D_CBC_RC5], c[D_CBC_RC5][testnum], - lengths[testnum], seconds.sym); - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported, exiting..."); - exit(1); - } - Time_F(START); - for (count = 0; COND(c[D_CBC_RC5][testnum]); count++) - RC5_32_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &rc5_ks, - iv, RC5_ENCRYPT); - d = Time_F(STOP); - print_result(D_CBC_RC5, testnum, count, d); - } + EVP_MAC_CTX_free(loopargs[i].mctx); + EVP_MAC_free(mac); + mac = NULL; } -#endif -#ifndef OPENSSL_NO_BF - if (doit[D_CBC_BF]) { - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported with %s\n", - names[D_CBC_BF]); - doit[D_CBC_BF] = 0; - } - for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { - print_message(names[D_CBC_BF], c[D_CBC_BF][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - for (count = 0; COND(c[D_CBC_BF][testnum]); count++) - BF_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &bf_ks, - iv, BF_ENCRYPT); - d = Time_F(STOP); - print_result(D_CBC_BF, testnum, count, d); - } - } -#endif -#ifndef OPENSSL_NO_CAST - if (doit[D_CBC_CAST]) { - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported with %s\n", - names[D_CBC_CAST]); - doit[D_CBC_CAST] = 0; - } - for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { - print_message(names[D_CBC_CAST], c[D_CBC_CAST][testnum], - lengths[testnum], seconds.sym); - Time_F(START); - for (count = 0; COND(c[D_CBC_CAST][testnum]); count++) - CAST_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, - (size_t)lengths[testnum], &cast_ks, - iv, CAST_ENCRYPT); - d = Time_F(STOP); - print_result(D_CBC_CAST, testnum, count, d); - } - } -#endif + if (doit[D_RAND]) { for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_RAND], c[D_RAND][testnum], lengths[testnum], @@ -2603,20 +2197,20 @@ int speed_main(int argc, char **argv) if (doit[D_EVP]) { if (evp_cipher != NULL) { - int (*loopfunc)(void *args) = EVP_Update_loop; + int (*loopfunc) (void *) = EVP_Update_loop; - if (multiblock && (EVP_CIPHER_flags(evp_cipher) & + if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) { multiblock_speed(evp_cipher, lengths_single, &seconds); ret = 0; goto end; } - names[D_EVP] = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher)); + names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher); - if (EVP_CIPHER_mode(evp_cipher) == EVP_CIPH_CCM_MODE) { + if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) { loopfunc = EVP_Update_loop_ccm; - } else if (aead && (EVP_CIPHER_flags(evp_cipher) & + } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { loopfunc = EVP_Update_loop_aead; if (lengths == lengths_list) { @@ -2626,7 +2220,7 @@ int speed_main(int argc, char **argv) } for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_EVP], save_count, lengths[testnum], + print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum], seconds.sym); for (k = 0; k < loopargs_len; k++) { @@ -2644,7 +2238,7 @@ int speed_main(int argc, char **argv) EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0); - keylen = EVP_CIPHER_CTX_key_length(loopargs[k].ctx); + keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx); loopargs[k].key = app_malloc(keylen, "evp_cipher key"); EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key); if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL, @@ -2654,81 +2248,139 @@ int speed_main(int argc, char **argv) exit(1); } OPENSSL_clear_free(loopargs[k].key, keylen); + + /* SIV mode only allows for a single Update operation */ + if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE) + (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx, + EVP_CTRL_SET_SPEED, 1, NULL); } Time_F(START); count = run_benchmark(async_jobs, loopfunc, loopargs); d = Time_F(STOP); - for (k = 0; k < loopargs_len; k++) { + for (k = 0; k < loopargs_len; k++) EVP_CIPHER_CTX_free(loopargs[k].ctx); - } print_result(D_EVP, testnum, count, d); } - } else if (evp_md != NULL) { - names[D_EVP] = OBJ_nid2ln(EVP_MD_type(evp_md)); + } else if (evp_md_name != NULL) { + names[D_EVP] = evp_md_name; for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_EVP], save_count, lengths[testnum], + print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum], seconds.sym); Time_F(START); - count = run_benchmark(async_jobs, EVP_Digest_loop, loopargs); + count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs); d = Time_F(STOP); print_result(D_EVP, testnum, count, d); + if (count < 0) + break; } } } + if (doit[D_EVP_CMAC]) { + OSSL_PARAM params[3]; + EVP_CIPHER *cipher = NULL; + + mac = EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq()); + if (mac == NULL || evp_mac_ciphername == NULL) + goto end; + if (!opt_cipher(evp_mac_ciphername, &cipher)) + goto end; + + keylen = EVP_CIPHER_get_key_length(cipher); + EVP_CIPHER_free(cipher); + if (keylen <= 0 || keylen > (int)sizeof(key32)) { + BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n"); + goto end; + } + evp_cmac_name = app_malloc(sizeof("cmac()") + + strlen(evp_mac_ciphername), "CMAC name"); + sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername); + names[D_EVP_CMAC] = evp_cmac_name; + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER, + evp_mac_ciphername, 0); + params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (char *)key32, keylen); + params[2] = OSSL_PARAM_construct_end(); + + for (i = 0; i < loopargs_len; i++) { + loopargs[i].mctx = EVP_MAC_CTX_new(mac); + if (loopargs[i].mctx == NULL) + goto end; + + if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params)) + goto end; + } + + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_EVP_CMAC], c[D_EVP_CMAC][testnum], + lengths[testnum], seconds.sym); + Time_F(START); + count = run_benchmark(async_jobs, CMAC_loop, loopargs); + d = Time_F(STOP); + print_result(D_EVP_CMAC, testnum, count, d); + if (count < 0) + break; + } + for (i = 0; i < loopargs_len; i++) + EVP_MAC_CTX_free(loopargs[i].mctx); + EVP_MAC_free(mac); + mac = NULL; + } + for (i = 0; i < loopargs_len; i++) if (RAND_bytes(loopargs[i].buf, 36) <= 0) goto end; -#ifndef OPENSSL_NO_RSA for (testnum = 0; testnum < RSA_NUM; testnum++) { + EVP_PKEY *rsa_key = NULL; int st = 0; + if (!rsa_doit[testnum]) continue; - for (i = 0; i < loopargs_len; i++) { - if (primes > 2) { - /* we haven't set keys yet, generate multi-prime RSA keys */ - BIGNUM *bn = BN_new(); - - if (bn == NULL) - goto end; - if (!BN_set_word(bn, RSA_F4)) { - BN_free(bn); - goto end; - } - BIO_printf(bio_err, "Generate multi-prime RSA key for %s\n", - rsa_choices[testnum].name); + if (primes > RSA_DEFAULT_PRIME_NUM) { + /* we haven't set keys yet, generate multi-prime RSA keys */ + bn = BN_new(); + st = bn != NULL + && BN_set_word(bn, RSA_F4) + && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL) + && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0 + && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0 + && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0 + && EVP_PKEY_keygen(genctx, &rsa_key); + BN_free(bn); + bn = NULL; + EVP_PKEY_CTX_free(genctx); + genctx = NULL; + } else { + const unsigned char *p = rsa_keys[testnum].data; - loopargs[i].rsa_key[testnum] = RSA_new(); - if (loopargs[i].rsa_key[testnum] == NULL) { - BN_free(bn); - goto end; - } + st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p, + rsa_keys[testnum].length)) != NULL; + } - if (!RSA_generate_multi_prime_key(loopargs[i].rsa_key[testnum], - rsa_bits[testnum], - primes, bn, NULL)) { - BN_free(bn); - goto end; - } - BN_free(bn); - } - st = RSA_sign(NID_md5_sha1, loopargs[i].buf, 36, loopargs[i].buf2, - &loopargs[i].siglen, loopargs[i].rsa_key[testnum]); - if (st == 0) - break; + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL); + loopargs[i].sigsize = loopargs[i].buflen; + if (loopargs[i].rsa_sign_ctx[testnum] == NULL + || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0 + || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum], + loopargs[i].buf2, + &loopargs[i].sigsize, + loopargs[i].buf, 36) <= 0) + st = 0; } - if (st == 0) { + if (!st) { BIO_printf(bio_err, - "RSA sign failure. No RSA sign will be done.\n"); + "RSA sign setup failure. No RSA sign will be done.\n"); ERR_print_errors(bio_err); - rsa_count = 1; + op_count = 1; } else { pkey_print_message("private", "rsa", - rsa_c[testnum][0], rsa_bits[testnum], + rsa_c[testnum][0], rsa_keys[testnum].bits, seconds.rsa); /* RSA_blinding_on(rsa_key[testnum],NULL); */ Time_F(START); @@ -2737,25 +2389,30 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, mr ? "+R1:%ld:%d:%.2f\n" : "%ld %u bits private RSA's in %.2fs\n", - count, rsa_bits[testnum], d); + count, rsa_keys[testnum].bits, d); rsa_results[testnum][0] = (double)count / d; - rsa_count = count; - } - - for (i = 0; i < loopargs_len; i++) { - st = RSA_verify(NID_md5_sha1, loopargs[i].buf, 36, loopargs[i].buf2, - loopargs[i].siglen, loopargs[i].rsa_key[testnum]); - if (st <= 0) - break; + op_count = count; + } + + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, + NULL); + if (loopargs[i].rsa_verify_ctx[testnum] == NULL + || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0 + || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum], + loopargs[i].buf2, + loopargs[i].sigsize, + loopargs[i].buf, 36) <= 0) + st = 0; } - if (st <= 0) { + if (!st) { BIO_printf(bio_err, - "RSA verify failure. No RSA verify will be done.\n"); + "RSA verify setup failure. No RSA verify will be done.\n"); ERR_print_errors(bio_err); rsa_doit[testnum] = 0; } else { pkey_print_message("public", "rsa", - rsa_c[testnum][1], rsa_bits[testnum], + rsa_c[testnum][1], rsa_keys[testnum].bits, seconds.rsa); Time_F(START); count = run_benchmark(async_jobs, RSA_verify_loop, loopargs); @@ -2763,41 +2420,44 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, mr ? "+R2:%ld:%d:%.2f\n" : "%ld %u bits public RSA's in %.2fs\n", - count, rsa_bits[testnum], d); + count, rsa_keys[testnum].bits, d); rsa_results[testnum][1] = (double)count / d; } - if (rsa_count <= 1) { + if (op_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < RSA_NUM; testnum++) - rsa_doit[testnum] = 0; + stop_it(rsa_doit, testnum); } + EVP_PKEY_free(rsa_key); } -#endif /* OPENSSL_NO_RSA */ - - for (i = 0; i < loopargs_len; i++) - if (RAND_bytes(loopargs[i].buf, 36) <= 0) - goto end; -#ifndef OPENSSL_NO_DSA for (testnum = 0; testnum < DSA_NUM; testnum++) { - int st = 0; + EVP_PKEY *dsa_key = NULL; + int st; + if (!dsa_doit[testnum]) continue; - /* DSA_generate_key(dsa_key[testnum]); */ - /* DSA_sign_setup(dsa_key[testnum],NULL); */ - for (i = 0; i < loopargs_len; i++) { - st = DSA_sign(0, loopargs[i].buf, 20, loopargs[i].buf2, - &loopargs[i].siglen, loopargs[i].dsa_key[testnum]); - if (st == 0) - break; + st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL; + + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key, + NULL); + loopargs[i].sigsize = loopargs[i].buflen; + if (loopargs[i].dsa_sign_ctx[testnum] == NULL + || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0 + + || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum], + loopargs[i].buf2, + &loopargs[i].sigsize, + loopargs[i].buf, 20) <= 0) + st = 0; } - if (st == 0) { + if (!st) { BIO_printf(bio_err, - "DSA sign failure. No DSA sign will be done.\n"); + "DSA sign setup failure. No DSA sign will be done.\n"); ERR_print_errors(bio_err); - rsa_count = 1; + op_count = 1; } else { pkey_print_message("sign", "dsa", dsa_c[testnum][0], dsa_bits[testnum], @@ -2810,18 +2470,23 @@ int speed_main(int argc, char **argv) : "%ld %u bits DSA signs in %.2fs\n", count, dsa_bits[testnum], d); dsa_results[testnum][0] = (double)count / d; - rsa_count = count; - } - - for (i = 0; i < loopargs_len; i++) { - st = DSA_verify(0, loopargs[i].buf, 20, loopargs[i].buf2, - loopargs[i].siglen, loopargs[i].dsa_key[testnum]); - if (st <= 0) - break; + op_count = count; + } + + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key, + NULL); + if (loopargs[i].dsa_verify_ctx[testnum] == NULL + || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0 + || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum], + loopargs[i].buf2, + loopargs[i].sigsize, + loopargs[i].buf, 36) <= 0) + st = 0; } - if (st <= 0) { + if (!st) { BIO_printf(bio_err, - "DSA verify failure. No DSA verify will be done.\n"); + "DSA verify setup failure. No DSA verify will be done.\n"); ERR_print_errors(bio_err); dsa_doit[testnum] = 0; } else { @@ -2838,214 +2503,137 @@ int speed_main(int argc, char **argv) dsa_results[testnum][1] = (double)count / d; } - if (rsa_count <= 1) { + if (op_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < DSA_NUM; testnum++) - dsa_doit[testnum] = 0; + stop_it(dsa_doit, testnum); } + EVP_PKEY_free(dsa_key); } -#endif /* OPENSSL_NO_DSA */ -#ifndef OPENSSL_NO_EC for (testnum = 0; testnum < ECDSA_NUM; testnum++) { - int st = 1; + EVP_PKEY *ecdsa_key = NULL; + int st; if (!ecdsa_doit[testnum]) - continue; /* Ignore Curve */ - for (i = 0; i < loopargs_len; i++) { - loopargs[i].ecdsa[testnum] = - EC_KEY_new_by_curve_name(test_curves[testnum].nid); - if (loopargs[i].ecdsa[testnum] == NULL) { + continue; + + st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL; + + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key, + NULL); + loopargs[i].sigsize = loopargs[i].buflen; + if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL + || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0 + + || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum], + loopargs[i].buf2, + &loopargs[i].sigsize, + loopargs[i].buf, 20) <= 0) st = 0; - break; - } } - if (st == 0) { - BIO_printf(bio_err, "ECDSA failure.\n"); + if (!st) { + BIO_printf(bio_err, + "ECDSA sign setup failure. No ECDSA sign will be done.\n"); ERR_print_errors(bio_err); - rsa_count = 1; + op_count = 1; } else { - for (i = 0; i < loopargs_len; i++) { - EC_KEY_precompute_mult(loopargs[i].ecdsa[testnum], NULL); - /* Perform ECDSA signature test */ - EC_KEY_generate_key(loopargs[i].ecdsa[testnum]); - st = ECDSA_sign(0, loopargs[i].buf, 20, loopargs[i].buf2, - &loopargs[i].siglen, - loopargs[i].ecdsa[testnum]); - if (st == 0) - break; - } - if (st == 0) { - BIO_printf(bio_err, - "ECDSA sign failure. No ECDSA sign will be done.\n"); - ERR_print_errors(bio_err); - rsa_count = 1; - } else { - pkey_print_message("sign", "ecdsa", - ecdsa_c[testnum][0], - test_curves[testnum].bits, seconds.ecdsa); - Time_F(START); - count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs); - d = Time_F(STOP); - - BIO_printf(bio_err, - mr ? "+R5:%ld:%u:%.2f\n" : - "%ld %u bits ECDSA signs in %.2fs \n", - count, test_curves[testnum].bits, d); - ecdsa_results[testnum][0] = (double)count / d; - rsa_count = count; - } - - /* Perform ECDSA verification test */ - for (i = 0; i < loopargs_len; i++) { - st = ECDSA_verify(0, loopargs[i].buf, 20, loopargs[i].buf2, - loopargs[i].siglen, - loopargs[i].ecdsa[testnum]); - if (st != 1) - break; - } - if (st != 1) { - BIO_printf(bio_err, - "ECDSA verify failure. No ECDSA verify will be done.\n"); - ERR_print_errors(bio_err); - ecdsa_doit[testnum] = 0; - } else { - pkey_print_message("verify", "ecdsa", - ecdsa_c[testnum][1], - test_curves[testnum].bits, seconds.ecdsa); - Time_F(START); - count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs); - d = Time_F(STOP); - BIO_printf(bio_err, - mr ? "+R6:%ld:%u:%.2f\n" - : "%ld %u bits ECDSA verify in %.2fs\n", - count, test_curves[testnum].bits, d); - ecdsa_results[testnum][1] = (double)count / d; - } + pkey_print_message("sign", "ecdsa", + ecdsa_c[testnum][0], ec_curves[testnum].bits, + seconds.ecdsa); + Time_F(START); + count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R5:%ld:%u:%.2f\n" + : "%ld %u bits ECDSA signs in %.2fs\n", + count, ec_curves[testnum].bits, d); + ecdsa_results[testnum][0] = (double)count / d; + op_count = count; + } + + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key, + NULL); + if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL + || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0 + || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum], + loopargs[i].buf2, + loopargs[i].sigsize, + loopargs[i].buf, 20) <= 0) + st = 0; + } + if (!st) { + BIO_printf(bio_err, + "ECDSA verify setup failure. No ECDSA verify will be done.\n"); + ERR_print_errors(bio_err); + ecdsa_doit[testnum] = 0; + } else { + pkey_print_message("verify", "ecdsa", + ecdsa_c[testnum][1], ec_curves[testnum].bits, + seconds.ecdsa); + Time_F(START); + count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R6:%ld:%u:%.2f\n" + : "%ld %u bits ECDSA verify in %.2fs\n", + count, ec_curves[testnum].bits, d); + ecdsa_results[testnum][1] = (double)count / d; + } - if (rsa_count <= 1) { - /* if longer than 10s, don't do any more */ - for (testnum++; testnum < ECDSA_NUM; testnum++) - ecdsa_doit[testnum] = 0; - } + if (op_count <= 1) { + /* if longer than 10s, don't do any more */ + stop_it(ecdsa_doit, testnum); } } for (testnum = 0; testnum < EC_NUM; testnum++) { - int ecdh_checks = 1; - - if (!ecdh_doit[testnum]) - continue; - - for (i = 0; i < loopargs_len; i++) { - EVP_PKEY_CTX *kctx = NULL; - EVP_PKEY_CTX *test_ctx = NULL; - EVP_PKEY_CTX *ctx = NULL; - EVP_PKEY *key_A = NULL; - EVP_PKEY *key_B = NULL; - size_t outlen; - size_t test_outlen; - - /* Ensure that the error queue is empty */ - if (ERR_peek_error()) { - BIO_printf(bio_err, - "WARNING: the error queue contains previous unhandled errors.\n"); - ERR_print_errors(bio_err); - } - - /* Let's try to create a ctx directly from the NID: this works for - * curves like Curve25519 that are not implemented through the low - * level EC interface. - * If this fails we try creating a EVP_PKEY_EC generic param ctx, - * then we set the curve by NID before deriving the actual keygen - * ctx for that specific curve. */ - kctx = EVP_PKEY_CTX_new_id(test_curves[testnum].nid, NULL); /* keygen ctx from NID */ - if (!kctx) { - EVP_PKEY_CTX *pctx = NULL; - EVP_PKEY *params = NULL; - - /* If we reach this code EVP_PKEY_CTX_new_id() failed and a - * "int_ctx_new:unsupported algorithm" error was added to the - * error queue. - * We remove it from the error queue as we are handling it. */ - unsigned long error = ERR_peek_error(); /* peek the latest error in the queue */ - if (error == ERR_peek_last_error() && /* oldest and latest errors match */ - /* check that the error origin matches */ - ERR_GET_LIB(error) == ERR_LIB_EVP && - ERR_GET_FUNC(error) == EVP_F_INT_CTX_NEW && - ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM) - ERR_get_error(); /* pop error from queue */ - if (ERR_peek_error()) { - BIO_printf(bio_err, - "Unhandled error in the error queue during ECDH init.\n"); - ERR_print_errors(bio_err); - rsa_count = 1; - break; - } + int ecdh_checks = 1; - if ( /* Create the context for parameter generation */ - !(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) || - /* Initialise the parameter generation */ - !EVP_PKEY_paramgen_init(pctx) || - /* Set the curve by NID */ - !EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, - test_curves - [testnum].nid) || - /* Create the parameter object params */ - !EVP_PKEY_paramgen(pctx, ¶ms)) { - ecdh_checks = 0; - BIO_printf(bio_err, "ECDH EC params init failure.\n"); - ERR_print_errors(bio_err); - rsa_count = 1; - break; - } - /* Create the context for the key generation */ - kctx = EVP_PKEY_CTX_new(params, NULL); + if (!ecdh_doit[testnum]) + continue; - EVP_PKEY_free(params); - params = NULL; - EVP_PKEY_CTX_free(pctx); - pctx = NULL; - } - if (kctx == NULL || /* keygen ctx is not null */ - EVP_PKEY_keygen_init(kctx) <= 0/* init keygen ctx */ ) { - ecdh_checks = 0; - BIO_printf(bio_err, "ECDH keygen failure.\n"); - ERR_print_errors(bio_err); - rsa_count = 1; - break; - } + for (i = 0; i < loopargs_len; i++) { + EVP_PKEY_CTX *test_ctx = NULL; + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *key_A = NULL; + EVP_PKEY *key_B = NULL; + size_t outlen; + size_t test_outlen; - if (EVP_PKEY_keygen(kctx, &key_A) <= 0 || /* generate secret key A */ - EVP_PKEY_keygen(kctx, &key_B) <= 0 || /* generate secret key B */ - !(ctx = EVP_PKEY_CTX_new(key_A, NULL)) || /* derivation ctx from skeyA */ - EVP_PKEY_derive_init(ctx) <= 0 || /* init derivation ctx */ - EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 || /* set peer pubkey in ctx */ - EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 || /* determine max length */ - outlen == 0 || /* ensure outlen is a valid size */ - outlen > MAX_ECDH_SIZE /* avoid buffer overflow */ ) { + if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */ + || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */ + || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */ + || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */ + || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */ + || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */ + || outlen == 0 /* ensure outlen is a valid size */ + || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) { ecdh_checks = 0; BIO_printf(bio_err, "ECDH key generation failure.\n"); ERR_print_errors(bio_err); - rsa_count = 1; + op_count = 1; break; } - /* Here we perform a test run, comparing the output of a*B and b*A; + /* + * Here we perform a test run, comparing the output of a*B and b*A; * we try this here and assume that further EVP_PKEY_derive calls * never fail, so we can skip checks in the actually benchmarked - * code, for maximum performance. */ - if (!(test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) || /* test ctx from skeyB */ - !EVP_PKEY_derive_init(test_ctx) || /* init derivation test_ctx */ - !EVP_PKEY_derive_set_peer(test_ctx, key_A) || /* set peer pubkey in test_ctx */ - !EVP_PKEY_derive(test_ctx, NULL, &test_outlen) || /* determine max length */ - !EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) || /* compute a*B */ - !EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) || /* compute b*A */ - test_outlen != outlen /* compare output length */ ) { + * code, for maximum performance. + */ + if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */ + || EVP_PKEY_derive_init(test_ctx) <= 0 /* init derivation test_ctx */ + || EVP_PKEY_derive_set_peer(test_ctx, key_A) <= 0 /* set peer pubkey in test_ctx */ + || EVP_PKEY_derive(test_ctx, NULL, &test_outlen) <= 0 /* determine max length */ + || EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) <= 0 /* compute a*B */ + || EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) <= 0 /* compute b*A */ + || test_outlen != outlen /* compare output length */) { ecdh_checks = 0; BIO_printf(bio_err, "ECDH computation failure.\n"); ERR_print_errors(bio_err); - rsa_count = 1; + op_count = 1; break; } @@ -3055,7 +2643,7 @@ int speed_main(int argc, char **argv) ecdh_checks = 0; BIO_printf(bio_err, "ECDH computations don't match.\n"); ERR_print_errors(bio_err); - rsa_count = 1; + op_count = 1; break; } @@ -3064,15 +2652,13 @@ int speed_main(int argc, char **argv) EVP_PKEY_free(key_A); EVP_PKEY_free(key_B); - EVP_PKEY_CTX_free(kctx); - kctx = NULL; EVP_PKEY_CTX_free(test_ctx); test_ctx = NULL; } if (ecdh_checks != 0) { pkey_print_message("", "ecdh", ecdh_c[testnum][0], - test_curves[testnum].bits, seconds.ecdh); + ec_curves[testnum].bits, seconds.ecdh); Time_F(START); count = run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs); @@ -3080,15 +2666,14 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, mr ? "+R7:%ld:%d:%.2f\n" : "%ld %u-bits ECDH ops in %.2fs\n", count, - test_curves[testnum].bits, d); + ec_curves[testnum].bits, d); ecdh_results[testnum][0] = (double)count / d; - rsa_count = count; + op_count = count; } - if (rsa_count <= 1) { + if (op_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < OSSL_NELEM(ecdh_doit); testnum++) - ecdh_doit[testnum] = 0; + stop_it(ecdh_doit, testnum); } } @@ -3105,9 +2690,14 @@ int speed_main(int argc, char **argv) st = 0; break; } + loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new(); + if (loopargs[i].eddsa_ctx2[testnum] == NULL) { + st = 0; + break; + } - if ((ed_pctx = EVP_PKEY_CTX_new_id(test_ed_curves[testnum].nid, NULL)) - == NULL + if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid, + NULL)) == NULL || EVP_PKEY_keygen_init(ed_pctx) <= 0 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) { st = 0; @@ -3122,16 +2712,24 @@ int speed_main(int argc, char **argv) EVP_PKEY_free(ed_pkey); break; } + if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL, + NULL, NULL, ed_pkey)) { + st = 0; + EVP_PKEY_free(ed_pkey); + break; + } + EVP_PKEY_free(ed_pkey); + ed_pkey = NULL; } if (st == 0) { BIO_printf(bio_err, "EdDSA failure.\n"); ERR_print_errors(bio_err); - rsa_count = 1; + op_count = 1; } else { for (i = 0; i < loopargs_len; i++) { /* Perform EdDSA signature test */ - loopargs[i].sigsize = test_ed_curves[testnum].sigsize; + loopargs[i].sigsize = ed_curves[testnum].sigsize; st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum], loopargs[i].buf2, &loopargs[i].sigsize, loopargs[i].buf, 20); @@ -3142,11 +2740,11 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, "EdDSA sign failure. No EdDSA sign will be done.\n"); ERR_print_errors(bio_err); - rsa_count = 1; + op_count = 1; } else { - pkey_print_message("sign", test_ed_curves[testnum].name, + pkey_print_message("sign", ed_curves[testnum].name, eddsa_c[testnum][0], - test_ed_curves[testnum].bits, seconds.eddsa); + ed_curves[testnum].bits, seconds.eddsa); Time_F(START); count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs); d = Time_F(STOP); @@ -3154,15 +2752,14 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, mr ? "+R8:%ld:%u:%s:%.2f\n" : "%ld %u bits %s signs in %.2fs \n", - count, test_ed_curves[testnum].bits, - test_ed_curves[testnum].name, d); + count, ed_curves[testnum].bits, + ed_curves[testnum].name, d); eddsa_results[testnum][0] = (double)count / d; - rsa_count = count; + op_count = count; } - /* Perform EdDSA verification test */ for (i = 0; i < loopargs_len; i++) { - st = EVP_DigestVerify(loopargs[i].eddsa_ctx[testnum], + st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum], loopargs[i].buf2, loopargs[i].sigsize, loopargs[i].buf, 20); if (st != 1) @@ -3174,62 +2771,360 @@ int speed_main(int argc, char **argv) ERR_print_errors(bio_err); eddsa_doit[testnum] = 0; } else { - pkey_print_message("verify", test_ed_curves[testnum].name, + pkey_print_message("verify", ed_curves[testnum].name, eddsa_c[testnum][1], - test_ed_curves[testnum].bits, seconds.eddsa); + ed_curves[testnum].bits, seconds.eddsa); Time_F(START); count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, mr ? "+R9:%ld:%u:%s:%.2f\n" : "%ld %u bits %s verify in %.2fs\n", - count, test_ed_curves[testnum].bits, - test_ed_curves[testnum].name, d); + count, ed_curves[testnum].bits, + ed_curves[testnum].name, d); eddsa_results[testnum][1] = (double)count / d; } - if (rsa_count <= 1) { + if (op_count <= 1) { + /* if longer than 10s, don't do any more */ + stop_it(eddsa_doit, testnum); + } + } + } + +#ifndef OPENSSL_NO_SM2 + for (testnum = 0; testnum < SM2_NUM; testnum++) { + int st = 1; + EVP_PKEY *sm2_pkey = NULL; + + if (!sm2_doit[testnum]) + continue; /* Ignore Curve */ + /* Init signing and verification */ + for (i = 0; i < loopargs_len; i++) { + EVP_PKEY_CTX *sm2_pctx = NULL; + EVP_PKEY_CTX *sm2_vfy_pctx = NULL; + EVP_PKEY_CTX *pctx = NULL; + st = 0; + + loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new(); + loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new(); + if (loopargs[i].sm2_ctx[testnum] == NULL + || loopargs[i].sm2_vfy_ctx[testnum] == NULL) + break; + + sm2_pkey = NULL; + + st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL + || EVP_PKEY_keygen_init(pctx) <= 0 + || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, + sm2_curves[testnum].nid) <= 0 + || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0); + EVP_PKEY_CTX_free(pctx); + if (st == 0) + break; + + st = 0; /* set back to zero */ + /* attach it sooner to rely on main final cleanup */ + loopargs[i].sm2_pkey[testnum] = sm2_pkey; + loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey); + + sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL); + sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL); + if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) { + EVP_PKEY_CTX_free(sm2_vfy_pctx); + break; + } + + /* attach them directly to respective ctx */ + EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx); + EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx); + + /* + * No need to allow user to set an explicit ID here, just use + * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D. + */ + if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1 + || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1) + break; + + if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL, + EVP_sm3(), NULL, sm2_pkey)) + break; + if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL, + EVP_sm3(), NULL, sm2_pkey)) + break; + st = 1; /* mark loop as succeeded */ + } + if (st == 0) { + BIO_printf(bio_err, "SM2 init failure.\n"); + ERR_print_errors(bio_err); + op_count = 1; + } else { + for (i = 0; i < loopargs_len; i++) { + /* Perform SM2 signature test */ + st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum], + loopargs[i].buf2, &loopargs[i].sigsize, + loopargs[i].buf, 20); + if (st == 0) + break; + } + if (st == 0) { + BIO_printf(bio_err, + "SM2 sign failure. No SM2 sign will be done.\n"); + ERR_print_errors(bio_err); + op_count = 1; + } else { + pkey_print_message("sign", sm2_curves[testnum].name, + sm2_c[testnum][0], + sm2_curves[testnum].bits, seconds.sm2); + Time_F(START); + count = run_benchmark(async_jobs, SM2_sign_loop, loopargs); + d = Time_F(STOP); + + BIO_printf(bio_err, + mr ? "+R10:%ld:%u:%s:%.2f\n" : + "%ld %u bits %s signs in %.2fs \n", + count, sm2_curves[testnum].bits, + sm2_curves[testnum].name, d); + sm2_results[testnum][0] = (double)count / d; + op_count = count; + } + + /* Perform SM2 verification test */ + for (i = 0; i < loopargs_len; i++) { + st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum], + loopargs[i].buf2, loopargs[i].sigsize, + loopargs[i].buf, 20); + if (st != 1) + break; + } + if (st != 1) { + BIO_printf(bio_err, + "SM2 verify failure. No SM2 verify will be done.\n"); + ERR_print_errors(bio_err); + sm2_doit[testnum] = 0; + } else { + pkey_print_message("verify", sm2_curves[testnum].name, + sm2_c[testnum][1], + sm2_curves[testnum].bits, seconds.sm2); + Time_F(START); + count = run_benchmark(async_jobs, SM2_verify_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R11:%ld:%u:%s:%.2f\n" + : "%ld %u bits %s verify in %.2fs\n", + count, sm2_curves[testnum].bits, + sm2_curves[testnum].name, d); + sm2_results[testnum][1] = (double)count / d; + } + + if (op_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < EdDSA_NUM; testnum++) - eddsa_doit[testnum] = 0; + for (testnum++; testnum < SM2_NUM; testnum++) + sm2_doit[testnum] = 0; } } } +#endif /* OPENSSL_NO_SM2 */ + +#ifndef OPENSSL_NO_DH + for (testnum = 0; testnum < FFDH_NUM; testnum++) { + int ffdh_checks = 1; + + if (!ffdh_doit[testnum]) + continue; + + for (i = 0; i < loopargs_len; i++) { + EVP_PKEY *pkey_A = NULL; + EVP_PKEY *pkey_B = NULL; + EVP_PKEY_CTX *ffdh_ctx = NULL; + EVP_PKEY_CTX *test_ctx = NULL; + size_t secret_size; + size_t test_out; + + /* Ensure that the error queue is empty */ + if (ERR_peek_error()) { + BIO_printf(bio_err, + "WARNING: the error queue contains previous unhandled errors.\n"); + ERR_print_errors(bio_err); + } + + pkey_A = EVP_PKEY_new(); + if (!pkey_A) { + BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + pkey_B = EVP_PKEY_new(); + if (!pkey_B) { + BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + + ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL); + if (!ffdh_ctx) { + BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + + if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) { + BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) { + BIO_printf(bio_err, "Error setting DH key size for keygen.\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + + if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 || + EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) { + BIO_printf(bio_err, "FFDH key generation failure.\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + + EVP_PKEY_CTX_free(ffdh_ctx); -#endif /* OPENSSL_NO_EC */ + /* + * check if the derivation works correctly both ways so that + * we know if future derive calls will fail, and we can skip + * error checking in benchmarked code + */ + ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL); + if (ffdh_ctx == NULL) { + BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) { + BIO_printf(bio_err, "FFDH derivation context init failure.\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) { + BIO_printf(bio_err, "Assigning peer key for derivation failed.\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) { + BIO_printf(bio_err, "Checking size of shared secret failed.\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + if (secret_size > MAX_FFDH_SIZE) { + BIO_printf(bio_err, "Assertion failure: shared secret too large.\n"); + op_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive(ffdh_ctx, + loopargs[i].secret_ff_a, + &secret_size) <= 0) { + BIO_printf(bio_err, "Shared secret derive failure.\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + /* Now check from side B */ + test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL); + if (!test_ctx) { + BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive_init(test_ctx) <= 0 || + EVP_PKEY_derive_set_peer(test_ctx, pkey_A) <= 0 || + EVP_PKEY_derive(test_ctx, NULL, &test_out) <= 0 || + EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) <= 0 || + test_out != secret_size) { + BIO_printf(bio_err, "FFDH computation failure.\n"); + op_count = 1; + ffdh_checks = 0; + break; + } + + /* compare the computed secrets */ + if (CRYPTO_memcmp(loopargs[i].secret_ff_a, + loopargs[i].secret_ff_b, secret_size)) { + BIO_printf(bio_err, "FFDH computations don't match.\n"); + ERR_print_errors(bio_err); + op_count = 1; + ffdh_checks = 0; + break; + } + + loopargs[i].ffdh_ctx[testnum] = ffdh_ctx; + + EVP_PKEY_free(pkey_A); + pkey_A = NULL; + EVP_PKEY_free(pkey_B); + pkey_B = NULL; + EVP_PKEY_CTX_free(test_ctx); + test_ctx = NULL; + } + if (ffdh_checks != 0) { + pkey_print_message("", "ffdh", ffdh_c[testnum][0], + ffdh_params[testnum].bits, seconds.ffdh); + Time_F(START); + count = + run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R12:%ld:%d:%.2f\n" : + "%ld %u-bits FFDH ops in %.2fs\n", count, + ffdh_params[testnum].bits, d); + ffdh_results[testnum][0] = (double)count / d; + op_count = count; + } + if (op_count <= 1) { + /* if longer than 10s, don't do any more */ + stop_it(ffdh_doit, testnum); + } + } +#endif /* OPENSSL_NO_DH */ #ifndef NO_FORK show_res: #endif if (!mr) { - printf("%s\n", OpenSSL_version(OPENSSL_VERSION)); + printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING)); printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON)); - printf("options:"); - printf("%s ", BN_options()); -#ifndef OPENSSL_NO_MD2 - printf("%s ", MD2_options()); -#endif -#ifndef OPENSSL_NO_RC4 - printf("%s ", RC4_options()); -#endif -#ifndef OPENSSL_NO_DES - printf("%s ", DES_options()); -#endif - printf("%s ", AES_options()); -#ifndef OPENSSL_NO_IDEA - printf("%s ", IDEA_options()); -#endif -#ifndef OPENSSL_NO_BF - printf("%s ", BF_options()); -#endif - printf("\n%s\n", OpenSSL_version(OPENSSL_CFLAGS)); + printf("options: %s\n", BN_options()); + printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS)); + printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO)); } if (pr_header) { - if (mr) + if (mr) { printf("+H"); - else { - printf - ("The 'numbers' are in 1000s of bytes per second processed.\n"); + } else { + printf("The 'numbers' are in 1000s of bytes per second processed.\n"); printf("type "); } for (testnum = 0; testnum < size_num; testnum++) @@ -3252,7 +3147,6 @@ int speed_main(int argc, char **argv) } printf("\n"); } -#ifndef OPENSSL_NO_RSA testnum = 1; for (k = 0; k < RSA_NUM; k++) { if (!rsa_doit[k]) @@ -3263,14 +3157,12 @@ int speed_main(int argc, char **argv) } if (mr) printf("+F2:%u:%u:%f:%f\n", - k, rsa_bits[k], rsa_results[k][0], rsa_results[k][1]); + k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1]); else printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n", - rsa_bits[k], 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1], + rsa_keys[k].bits, 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1], rsa_results[k][0], rsa_results[k][1]); } -#endif -#ifndef OPENSSL_NO_DSA testnum = 1; for (k = 0; k < DSA_NUM; k++) { if (!dsa_doit[k]) @@ -3287,8 +3179,6 @@ int speed_main(int argc, char **argv) dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1], dsa_results[k][0], dsa_results[k][1]); } -#endif -#ifndef OPENSSL_NO_EC testnum = 1; for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) { if (!ecdsa_doit[k]) @@ -3300,11 +3190,11 @@ int speed_main(int argc, char **argv) if (mr) printf("+F4:%u:%u:%f:%f\n", - k, test_curves[k].bits, + k, ec_curves[k].bits, ecdsa_results[k][0], ecdsa_results[k][1]); else printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n", - test_curves[k].bits, test_curves[k].name, + ec_curves[k].bits, ec_curves[k].name, 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1], ecdsa_results[k][0], ecdsa_results[k][1]); } @@ -3319,12 +3209,12 @@ int speed_main(int argc, char **argv) } if (mr) printf("+F5:%u:%u:%f:%f\n", - k, test_curves[k].bits, + k, ec_curves[k].bits, ecdh_results[k][0], 1.0 / ecdh_results[k][0]); else printf("%4u bits ecdh (%s) %8.4fs %8.1f\n", - test_curves[k].bits, test_curves[k].name, + ec_curves[k].bits, ec_curves[k].name, 1.0 / ecdh_results[k][0], ecdh_results[k][0]); } @@ -3339,15 +3229,56 @@ int speed_main(int argc, char **argv) if (mr) printf("+F6:%u:%u:%s:%f:%f\n", - k, test_ed_curves[k].bits, test_ed_curves[k].name, + k, ed_curves[k].bits, ed_curves[k].name, eddsa_results[k][0], eddsa_results[k][1]); else printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n", - test_ed_curves[k].bits, test_ed_curves[k].name, + ed_curves[k].bits, ed_curves[k].name, 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1], eddsa_results[k][0], eddsa_results[k][1]); } + +#ifndef OPENSSL_NO_SM2 + testnum = 1; + for (k = 0; k < OSSL_NELEM(sm2_doit); k++) { + if (!sm2_doit[k]) + continue; + if (testnum && !mr) { + printf("%30ssign verify sign/s verify/s\n", " "); + testnum = 0; + } + + if (mr) + printf("+F7:%u:%u:%s:%f:%f\n", + k, sm2_curves[k].bits, sm2_curves[k].name, + sm2_results[k][0], sm2_results[k][1]); + else + printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n", + sm2_curves[k].bits, sm2_curves[k].name, + 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1], + sm2_results[k][0], sm2_results[k][1]); + } #endif +#ifndef OPENSSL_NO_DH + testnum = 1; + for (k = 0; k < FFDH_NUM; k++) { + if (!ffdh_doit[k]) + continue; + if (testnum && !mr) { + printf("%23sop op/s\n", " "); + testnum = 0; + } + if (mr) + printf("+F8:%u:%u:%f:%f\n", + k, ffdh_params[k].bits, + ffdh_results[k][0], 1.0 / ffdh_results[k][0]); + + else + printf("%4u bits ffdh %8.4fs %8.1f\n", + ffdh_params[k].bits, + 1.0 / ffdh_results[k][0], ffdh_results[k][0]); + } +#endif /* OPENSSL_NO_DH */ ret = 0; @@ -3357,25 +3288,55 @@ int speed_main(int argc, char **argv) OPENSSL_free(loopargs[i].buf_malloc); OPENSSL_free(loopargs[i].buf2_malloc); -#ifndef OPENSSL_NO_RSA - for (k = 0; k < RSA_NUM; k++) - RSA_free(loopargs[i].rsa_key[k]); -#endif -#ifndef OPENSSL_NO_DSA - for (k = 0; k < DSA_NUM; k++) - DSA_free(loopargs[i].dsa_key[k]); + BN_free(bn); + EVP_PKEY_CTX_free(genctx); + for (k = 0; k < RSA_NUM; k++) { + EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]); + EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]); + } +#ifndef OPENSSL_NO_DH + OPENSSL_free(loopargs[i].secret_ff_a); + OPENSSL_free(loopargs[i].secret_ff_b); + for (k = 0; k < FFDH_NUM; k++) + EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]); #endif -#ifndef OPENSSL_NO_EC - for (k = 0; k < ECDSA_NUM; k++) - EC_KEY_free(loopargs[i].ecdsa[k]); + for (k = 0; k < DSA_NUM; k++) { + EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]); + EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]); + } + for (k = 0; k < ECDSA_NUM; k++) { + EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]); + EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]); + } for (k = 0; k < EC_NUM; k++) EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]); - for (k = 0; k < EdDSA_NUM; k++) + for (k = 0; k < EdDSA_NUM; k++) { EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]); + EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]); + } +#ifndef OPENSSL_NO_SM2 + for (k = 0; k < SM2_NUM; k++) { + EVP_PKEY_CTX *pctx = NULL; + + /* free signing ctx */ + if (loopargs[i].sm2_ctx[k] != NULL + && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL) + EVP_PKEY_CTX_free(pctx); + EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]); + /* free verification ctx */ + if (loopargs[i].sm2_vfy_ctx[k] != NULL + && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL) + EVP_PKEY_CTX_free(pctx); + EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]); + /* free pkey */ + EVP_PKEY_free(loopargs[i].sm2_pkey[k]); + } +#endif OPENSSL_free(loopargs[i].secret_a); OPENSSL_free(loopargs[i].secret_b); -#endif } + OPENSSL_free(evp_hmac_name); + OPENSSL_free(evp_cmac_name); if (async_jobs > 0) { for (i = 0; i < loopargs_len; i++) @@ -3387,49 +3348,38 @@ int speed_main(int argc, char **argv) } OPENSSL_free(loopargs); release_engine(e); + EVP_CIPHER_free(evp_cipher); + EVP_MAC_free(mac); return ret; } static void print_message(const char *s, long num, int length, int tm) { -#ifdef SIGALRM BIO_printf(bio_err, mr ? "+DT:%s:%d:%d\n" : "Doing %s for %ds on %d size blocks: ", s, tm, length); (void)BIO_flush(bio_err); run = 1; alarm(tm); -#else - BIO_printf(bio_err, - mr ? "+DN:%s:%ld:%d\n" - : "Doing %s %ld times on %d size blocks: ", s, num, length); - (void)BIO_flush(bio_err); -#endif } static void pkey_print_message(const char *str, const char *str2, long num, unsigned int bits, int tm) { -#ifdef SIGALRM BIO_printf(bio_err, mr ? "+DTP:%d:%s:%s:%d\n" : "Doing %u bits %s %s's for %ds: ", bits, str, str2, tm); (void)BIO_flush(bio_err); run = 1; alarm(tm); -#else - BIO_printf(bio_err, - mr ? "+DNP:%ld:%d:%s:%s\n" - : "Doing %ld %u bits %s %s's: ", num, bits, str, str2); - (void)BIO_flush(bio_err); -#endif } static void print_result(int alg, int run_no, int count, double time_used) { if (count == -1) { - BIO_puts(bio_err, "EVP error!\n"); - exit(1); + BIO_printf(bio_err, "%s error!\n", names[alg]); + ERR_print_errors(bio_err); + return; } BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n" @@ -3454,9 +3404,8 @@ static char *sstrsep(char **string, const char *delim) delim++; } - while (!isdelim[(unsigned char)(**string)]) { + while (!isdelim[(unsigned char)(**string)]) (*string)++; - } if (**string) { **string = 0; @@ -3471,6 +3420,7 @@ static int do_multi(int multi, int size_num) int n; int fd[2]; int *fds; + int status; static char sep[] = ":"; fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi"); @@ -3506,7 +3456,12 @@ static int do_multi(int multi, int size_num) char buf[1024]; char *p; - f = fdopen(fds[n], "r"); + if ((f = fdopen(fds[n], "r")) == NULL) { + BIO_printf(bio_err, "fdopen failure with 0x%x\n", + errno); + OPENSSL_free(fds); + return 1; + } while (fgets(buf, sizeof(buf), f)) { p = strchr(buf, '\n'); if (p) @@ -3540,9 +3495,7 @@ static int do_multi(int multi, int size_num) d = atof(sstrsep(&p, sep)); rsa_results[k][1] += d; - } -# ifndef OPENSSL_NO_DSA - else if (strncmp(buf, "+F3:", 4) == 0) { + } else if (strncmp(buf, "+F3:", 4) == 0) { int k; double d; @@ -3555,10 +3508,7 @@ static int do_multi(int multi, int size_num) d = atof(sstrsep(&p, sep)); dsa_results[k][1] += d; - } -# endif -# ifndef OPENSSL_NO_EC - else if (strncmp(buf, "+F4:", 4) == 0) { + } else if (strncmp(buf, "+F4:", 4) == 0) { int k; double d; @@ -3595,19 +3545,59 @@ static int do_multi(int multi, int size_num) d = atof(sstrsep(&p, sep)); eddsa_results[k][1] += d; - } -# endif +# ifndef OPENSSL_NO_SM2 + } else if (strncmp(buf, "+F7:", 4) == 0) { + int k; + double d; + + p = buf + 4; + k = atoi(sstrsep(&p, sep)); + sstrsep(&p, sep); + sstrsep(&p, sep); + + d = atof(sstrsep(&p, sep)); + sm2_results[k][0] += d; + + d = atof(sstrsep(&p, sep)); + sm2_results[k][1] += d; +# endif /* OPENSSL_NO_SM2 */ +# ifndef OPENSSL_NO_DH + } else if (strncmp(buf, "+F8:", 4) == 0) { + int k; + double d; + + p = buf + 4; + k = atoi(sstrsep(&p, sep)); + sstrsep(&p, sep); - else if (strncmp(buf, "+H:", 3) == 0) { + d = atof(sstrsep(&p, sep)); + ffdh_results[k][0] += d; +# endif /* OPENSSL_NO_DH */ + } else if (strncmp(buf, "+H:", 3) == 0) { ; - } else + } else { BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf, n); + } } fclose(f); } OPENSSL_free(fds); + for (n = 0; n < multi; ++n) { + while (wait(&status) == -1) + if (errno != EINTR) { + BIO_printf(bio_err, "Waitng for child failed with 0x%x\n", + errno); + return 1; + } + if (WIFEXITED(status) && WEXITSTATUS(status)) { + BIO_printf(bio_err, "Child exited with %d\n", WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + BIO_printf(bio_err, "Child terminated by signal %d\n", + WTERMSIG(status)); + } + } return 1; } #endif @@ -3620,8 +3610,8 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, const int *mblengths = mblengths_list; int j, count, keylen, num = OSSL_NELEM(mblengths_list); const char *alg_name; - unsigned char *inp, *out, *key, no_key[32], no_iv[16]; - EVP_CIPHER_CTX *ctx; + unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16]; + EVP_CIPHER_CTX *ctx = NULL; double d = 0.0; if (lengths_single) { @@ -3631,22 +3621,32 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, inp = app_malloc(mblengths[num - 1], "multiblock input buffer"); out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer"); - ctx = EVP_CIPHER_CTX_new(); - EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv); + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) + app_bail_out("failed to allocate cipher context\n"); + if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv)) + app_bail_out("failed to initialise cipher context\n"); - keylen = EVP_CIPHER_CTX_key_length(ctx); + if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) { + BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen); + goto err; + } key = app_malloc(keylen, "evp_cipher key"); - EVP_CIPHER_CTX_rand_key(ctx, key); - EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); + if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) + app_bail_out("failed to generate random cipher key\n"); + if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL)) + app_bail_out("failed to set cipher key\n"); OPENSSL_clear_free(key, keylen); - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY, sizeof(no_key), no_key); - alg_name = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher)); + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY, + sizeof(no_key), no_key) <= 0) + app_bail_out("failed to set AEAD key\n"); + if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL) + app_bail_out("failed to get cipher name\n"); for (j = 0; j < num; j++) { print_message(alg_name, 0, mblengths[j], seconds->sym); Time_F(START); - for (count = 0; run && count < 0x7fffffff; count++) { + for (count = 0; run && count < INT_MAX; count++) { unsigned char aad[EVP_AEAD_TLS1_AAD_LEN]; EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param; size_t len = mblengths[j]; @@ -3670,8 +3670,9 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, mb_param.out = out; mb_param.inp = inp; mb_param.len = len; - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT, - sizeof(mb_param), &mb_param); + (void)EVP_CIPHER_CTX_ctrl(ctx, + EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT, + sizeof(mb_param), &mb_param); } else { int pad; @@ -3717,6 +3718,7 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, fprintf(stdout, "\n"); } + err: OPENSSL_free(inp); OPENSSL_free(out); EVP_CIPHER_CTX_free(ctx); diff --git a/crypto/openssl/apps/spkac.c b/crypto/openssl/apps/spkac.c index f384af6eb60b..d92be7d6450e 100644 --- a/crypto/openssl/apps/spkac.c +++ b/crypto/openssl/apps/spkac.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -21,29 +21,38 @@ #include typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_NOOUT, OPT_PUBKEY, OPT_VERIFY, OPT_IN, OPT_OUT, OPT_ENGINE, OPT_KEY, OPT_CHALLENGE, OPT_PASSIN, OPT_SPKAC, - OPT_SPKSECT, OPT_KEYFORM + OPT_SPKSECT, OPT_KEYFORM, OPT_DIGEST, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS spkac_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"spksect", OPT_SPKSECT, 's', + "Specify the name of an SPKAC-dedicated section of configuration"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file"}, - {"out", OPT_OUT, '>', "Output file"}, {"key", OPT_KEY, '<', "Create SPKAC using private key"}, - {"keyform", OPT_KEYFORM, 'f', "Private key file format - default PEM (PEM, DER, or ENGINE)"}, + {"keyform", OPT_KEYFORM, 'f', "Private key file format (ENGINE, other values ignored)"}, {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"challenge", OPT_CHALLENGE, 's', "Challenge string"}, {"spkac", OPT_SPKAC, 's', "Alternative SPKAC name"}, + + OPT_SECTION("Output"), + {"digest", OPT_DIGEST, 's', "Sign new SPKAC with the specified digest (default: MD5)" }, + {"out", OPT_OUT, '>', "Output file"}, {"noout", OPT_NOOUT, '-', "Don't print SPKAC"}, {"pubkey", OPT_PUBKEY, '-', "Output public key"}, {"verify", OPT_VERIFY, '-', "Verify SPKAC signature"}, - {"spksect", OPT_SPKSECT, 's', - "Specify the name of an SPKAC-dedicated section of configuration"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + + OPT_PROV_OPTIONS, {NULL} }; @@ -58,8 +67,10 @@ int spkac_main(int argc, char **argv) char *infile = NULL, *outfile = NULL, *passinarg = NULL, *passin = NULL; char *spkstr = NULL, *prog; const char *spkac = "SPKAC", *spksect = "default"; + const char *digest = "MD5"; + EVP_MD *md = NULL; int i, ret = 1, verify = 0, noout = 0, pubkey = 0; - int keyformat = FORMAT_PEM; + int keyformat = FORMAT_UNDEF; OPTION_CHOICE o; prog = opt_init(argc, argv, spkac_options); @@ -108,11 +119,20 @@ int spkac_main(int argc, char **argv) case OPT_SPKSECT: spksect = opt_arg(); break; + case OPT_DIGEST: + digest = opt_arg(); + break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); if (argc != 0) goto opthelp; @@ -123,6 +143,9 @@ int spkac_main(int argc, char **argv) } if (keyfile != NULL) { + if (!opt_md(digest, &md)) + goto end; + pkey = load_key(strcmp(keyfile, "-") ? keyfile : NULL, keyformat, 1, passin, e, "private key"); if (pkey == NULL) @@ -133,8 +156,15 @@ int spkac_main(int argc, char **argv) if (challenge != NULL) ASN1_STRING_set(spki->spkac->challenge, challenge, (int)strlen(challenge)); - NETSCAPE_SPKI_set_pubkey(spki, pkey); - NETSCAPE_SPKI_sign(spki, pkey, EVP_md5()); + if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) { + BIO_printf(bio_err, "Error setting public key\n"); + goto end; + } + i = NETSCAPE_SPKI_sign(spki, pkey, md); + if (i <= 0) { + BIO_printf(bio_err, "Error signing SPKAC\n"); + goto end; + } spkstr = NETSCAPE_SPKI_b64_encode(spki); if (spkstr == NULL) goto end; @@ -192,6 +222,7 @@ int spkac_main(int argc, char **argv) ret = 0; end: + EVP_MD_free(md); NCONF_free(conf); NETSCAPE_SPKI_free(spki); BIO_free_all(out); diff --git a/crypto/openssl/apps/srp.c b/crypto/openssl/apps/srp.c index 6c5817387973..a9466f830289 100644 --- a/crypto/openssl/apps/srp.c +++ b/crypto/openssl/apps/srp.c @@ -1,8 +1,8 @@ /* - * Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2004, EdelKey Project. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,7 +11,11 @@ * for the EdelKey project. */ +/* SRP is deprecated, so we're going to have to use some deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include + #include #include #include @@ -186,31 +190,42 @@ static char *srp_create_user(char *user, char **srp_verifier, } typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SRPVFILE, OPT_ADD, OPT_DELETE, OPT_MODIFY, OPT_LIST, OPT_GN, OPT_USERINFO, - OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE, OPT_R_ENUM + OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS srp_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [user...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"verbose", OPT_VERBOSE, '-', "Talk a lot while doing things"}, {"config", OPT_CONFIG, '<', "A config file"}, {"name", OPT_NAME, 's', "The particular srp definition to use"}, - {"srpvfile", OPT_SRPVFILE, '<', "The srp verifier file name"}, - {"add", OPT_ADD, '-', "Add a user and srp verifier"}, - {"modify", OPT_MODIFY, '-', - "Modify the srp verifier of an existing user"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Action"), + {"add", OPT_ADD, '-', "Add a user and SRP verifier"}, + {"modify", OPT_MODIFY, '-', "Modify the SRP verifier of an existing user"}, {"delete", OPT_DELETE, '-', "Delete user from verifier file"}, {"list", OPT_LIST, '-', "List users"}, + + OPT_SECTION("Configuration"), + {"srpvfile", OPT_SRPVFILE, '<', "The srp verifier file name"}, {"gn", OPT_GN, 's', "Set g and N values to be used for new verifier"}, {"userinfo", OPT_USERINFO, 's', "Additional info to be set for user"}, {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + OPT_R_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"user", 0, 0, "Username(s) to process (optional)"}, {NULL} }; @@ -283,11 +298,20 @@ int srp_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* Optional parameters are usernames. */ argc = opt_num_rest(); argv = opt_rest(); + if (!app_RAND_load()) + goto end; + if (srpvfile != NULL && configfile != NULL) { BIO_printf(bio_err, "-srpvfile and -configfile cannot be specified together.\n"); @@ -320,10 +344,7 @@ int srp_main(int argc, char **argv) if (configfile == NULL) configfile = default_config_file; - if (verbose) - BIO_printf(bio_err, "Using configuration from %s\n", - configfile); - conf = app_load_config(configfile); + conf = app_load_config_verbose(configfile, verbose); if (conf == NULL) goto end; if (configfile != default_config_file && !app_load_modules(conf)) @@ -358,8 +379,10 @@ int srp_main(int argc, char **argv) srpvfile); db = load_index(srpvfile, NULL); - if (db == NULL) + if (db == NULL) { + BIO_printf(bio_err, "Problem with index file: %s (could not load/parse file)\n", srpvfile); goto end; + } /* Lets check some fields */ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { diff --git a/crypto/openssl/apps/storeutl.c b/crypto/openssl/apps/storeutl.c index 644fe28499d6..30c9915de3e8 100644 --- a/crypto/openssl/apps/storeutl.c +++ b/crypto/openssl/apps/storeutl.c @@ -1,7 +1,7 @@ /* - * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,24 +19,29 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, int expected, int criterion, OSSL_STORE_SEARCH *search, int text, int noout, int recursive, int indent, BIO *out, - const char *prog); + const char *prog, OSSL_LIB_CTX *libctx); typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, OPT_OUT, OPT_PASSIN, + OPT_COMMON, + OPT_ENGINE, OPT_OUT, OPT_PASSIN, OPT_NOOUT, OPT_TEXT, OPT_RECURSIVE, OPT_SEARCHFOR_CERTS, OPT_SEARCHFOR_KEYS, OPT_SEARCHFOR_CRLS, OPT_CRITERION_SUBJECT, OPT_CRITERION_ISSUER, OPT_CRITERION_SERIAL, OPT_CRITERION_FINGERPRINT, OPT_CRITERION_ALIAS, - OPT_MD + OPT_MD, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS storeutl_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] uri\nValid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] uri\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, - {"out", OPT_OUT, '>', "Output file - default stdout"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"text", OPT_TEXT, '-', "Print a text form of the objects"}, - {"noout", OPT_NOOUT, '-', "No PEM output, just status"}, + {"", OPT_MD, '-', "Any supported digest"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + + OPT_SECTION("Search"), {"certs", OPT_SEARCHFOR_CERTS, '-', "Search for certificates only"}, {"keys", OPT_SEARCHFOR_KEYS, '-', "Search for keys only"}, {"crls", OPT_SEARCHFOR_CRLS, '-', "Search for CRLs only"}, @@ -45,11 +50,20 @@ const OPTIONS storeutl_options[] = { {"serial", OPT_CRITERION_SERIAL, 's', "Search by issuer and serial, serial number"}, {"fingerprint", OPT_CRITERION_FINGERPRINT, 's', "Search by public key fingerprint, given in hex"}, {"alias", OPT_CRITERION_ALIAS, 's', "Search by alias"}, - {"", OPT_MD, '-', "Any supported digest"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif {"r", OPT_RECURSIVE, '-', "Recurse through names"}, + + OPT_SECTION("Input"), + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file - default stdout"}, + {"text", OPT_TEXT, '-', "Print a text form of the objects"}, + {"noout", OPT_NOOUT, '-', "No PEM output, just status"}, + + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"uri", 0, 0, "URI of the store object"}, {NULL} }; @@ -68,9 +82,10 @@ int storeutl_main(int argc, char *argv[]) ASN1_INTEGER *serial = NULL; unsigned char *fingerprint = NULL; size_t fingerprintlen = 0; - char *alias = NULL; + char *alias = NULL, *digestname = NULL; OSSL_STORE_SEARCH *search = NULL; - const EVP_MD *digest = NULL; + EVP_MD *digest = NULL; + OSSL_LIB_CTX *libctx = app_get0_libctx(); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -142,16 +157,13 @@ int storeutl_main(int argc, char *argv[]) prog); goto end; } - if ((subject = parse_name(opt_arg(), MBSTRING_UTF8, 1)) == NULL) { - BIO_printf(bio_err, "%s: can't parse subject argument.\n", - prog); + subject = parse_name(opt_arg(), MBSTRING_UTF8, 1, "subject"); + if (subject == NULL) goto end; - } break; case OPT_CRITERION_ISSUER: if (criterion != 0 - || (criterion == OSSL_STORE_SEARCH_BY_ISSUER_SERIAL - && issuer != NULL)) { + && criterion != OSSL_STORE_SEARCH_BY_ISSUER_SERIAL) { BIO_printf(bio_err, "%s: criterion already given.\n", prog); goto end; @@ -162,16 +174,13 @@ int storeutl_main(int argc, char *argv[]) prog); goto end; } - if ((issuer = parse_name(opt_arg(), MBSTRING_UTF8, 1)) == NULL) { - BIO_printf(bio_err, "%s: can't parse issuer argument.\n", - prog); + issuer = parse_name(opt_arg(), MBSTRING_UTF8, 1, "issuer"); + if (issuer == NULL) goto end; - } break; case OPT_CRITERION_SERIAL: if (criterion != 0 - || (criterion == OSSL_STORE_SEARCH_BY_ISSUER_SERIAL - && serial != NULL)) { + && criterion != OSSL_STORE_SEARCH_BY_ISSUER_SERIAL) { BIO_printf(bio_err, "%s: criterion already given.\n", prog); goto end; @@ -237,20 +246,24 @@ int storeutl_main(int argc, char *argv[]) e = setup_engine(opt_arg(), 0); break; case OPT_MD: - if (!opt_md(opt_unknown(), &digest)) - goto opthelp; + digestname = opt_unknown(); + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* One argument, the URI */ argc = opt_num_rest(); argv = opt_rest(); - - if (argc == 0) { - BIO_printf(bio_err, "%s: No URI given, nothing to do...\n", prog); - goto opthelp; - } - if (argc > 1) { - BIO_printf(bio_err, "%s: Unknown extra parameters after URI\n", prog); + if (argc != 1) goto opthelp; + + if (digestname != NULL) { + if (!opt_md(digestname, &digest)) + goto opthelp; } if (criterion != 0) { @@ -305,9 +318,10 @@ int storeutl_main(int argc, char *argv[]) ret = process(argv[0], get_ui_method(), &pw_cb_data, expected, criterion, search, - text, noout, recursive, 0, out, prog); + text, noout, recursive, 0, out, prog, libctx); end: + EVP_MD_free(digest); OPENSSL_free(fingerprint); OPENSSL_free(alias); ASN1_INTEGER_free(serial); @@ -336,12 +350,13 @@ static int indent_printf(int indent, BIO *bio, const char *format, ...) static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, int expected, int criterion, OSSL_STORE_SEARCH *search, int text, int noout, int recursive, int indent, BIO *out, - const char *prog) + const char *prog, OSSL_LIB_CTX *libctx) { OSSL_STORE_CTX *store_ctx = NULL; int ret = 1, items = 0; - if ((store_ctx = OSSL_STORE_open(uri, uimeth, uidata, NULL, NULL)) + if ((store_ctx = OSSL_STORE_open_ex(uri, libctx, app_get0_propq(), uimeth, uidata, + NULL, NULL, NULL)) == NULL) { BIO_printf(bio_err, "Couldn't open file or uri %s\n", uri); ERR_print_errors(bio_err); @@ -379,18 +394,20 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, info == NULL ? NULL : OSSL_STORE_INFO_type_string(type); if (info == NULL) { - if (OSSL_STORE_eof(store_ctx)) - break; - if (OSSL_STORE_error(store_ctx)) { if (recursive) ERR_clear_error(); else ERR_print_errors(bio_err); + if (OSSL_STORE_eof(store_ctx)) + break; ret++; continue; } + if (OSSL_STORE_eof(store_ctx)) + break; + BIO_printf(bio_err, "ERROR: OSSL_STORE_load() returned NULL without " "eof or error indications\n"); @@ -422,7 +439,8 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, const char *suburi = OSSL_STORE_INFO_get0_NAME(info); ret += process(suburi, uimeth, uidata, expected, criterion, search, - text, noout, recursive, indent + 2, out, prog); + text, noout, recursive, indent + 2, out, prog, + libctx); } break; case OSSL_STORE_INFO_PARAMS: @@ -433,6 +451,13 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, PEM_write_bio_Parameters(out, OSSL_STORE_INFO_get0_PARAMS(info)); break; + case OSSL_STORE_INFO_PUBKEY: + if (text) + EVP_PKEY_print_public(out, OSSL_STORE_INFO_get0_PUBKEY(info), + 0, NULL); + if (!noout) + PEM_write_bio_PUBKEY(out, OSSL_STORE_INFO_get0_PUBKEY(info)); + break; case OSSL_STORE_INFO_PKEY: if (text) EVP_PKEY_print_private(out, OSSL_STORE_INFO_get0_PKEY(info), diff --git a/crypto/openssl/apps/testdsa.h b/crypto/openssl/apps/testdsa.h index 3c4b459db117..d80d2cf7f2d2 100644 --- a/crypto/openssl/apps/testdsa.h +++ b/crypto/openssl/apps/testdsa.h @@ -1,14 +1,16 @@ /* - * Copyright 1998-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 + /* used by speed.c */ -DSA *get_dsa(int); +EVP_PKEY *get_dsa(int); static unsigned char dsa512_priv[] = { 0x65, 0xe5, 0xc7, 0x38, 0x60, 0x24, 0xb5, 0x89, 0xd4, 0x9c, 0xeb, 0x4c, @@ -211,11 +213,14 @@ typedef struct testdsa_st { st.q_l = sizeof(dsa##bits##_q); \ } while (0) -DSA *get_dsa(int dsa_bits) +EVP_PKEY *get_dsa(int dsa_bits) { - DSA *dsa; + EVP_PKEY *pkey = NULL; BIGNUM *priv_key, *pub_key, *p, *q, *g; + EVP_PKEY_CTX *pctx; testdsa dsa_t; + OSSL_PARAM_BLD *tmpl = NULL; + OSSL_PARAM *params = NULL; switch (dsa_bits) { case 512: @@ -231,30 +236,44 @@ DSA *get_dsa(int dsa_bits) return NULL; } - if ((dsa = DSA_new()) == NULL) + if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)) == NULL) return NULL; + priv_key = BN_bin2bn(dsa_t.priv, dsa_t.priv_l, NULL); pub_key = BN_bin2bn(dsa_t.pub, dsa_t.pub_l, NULL); p = BN_bin2bn(dsa_t.p, dsa_t.p_l, NULL); q = BN_bin2bn(dsa_t.q, dsa_t.q_l, NULL); g = BN_bin2bn(dsa_t.g, dsa_t.g_l, NULL); - if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL) - || (g == NULL)) { + if (priv_key == NULL || pub_key == NULL || p == NULL || q == NULL + || g == NULL) { goto err; } - if (!DSA_set0_pqg(dsa, p, q, g)) - goto err; - - if (!DSA_set0_key(dsa, pub_key, priv_key)) + if ((tmpl = OSSL_PARAM_BLD_new()) == NULL + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, + p) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, + q) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, + g) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, + priv_key) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, + pub_key) + || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) goto err; - return dsa; - err: - DSA_free(dsa); + if (EVP_PKEY_fromdata_init(pctx) <= 0 + || EVP_PKEY_fromdata(pctx, &pkey, EVP_PKEY_KEYPAIR, + params) <= 0) + pkey = NULL; +err: + OSSL_PARAM_free(params); + OSSL_PARAM_BLD_free(tmpl); BN_free(priv_key); BN_free(pub_key); BN_free(p); BN_free(q); BN_free(g); - return NULL; + EVP_PKEY_CTX_free(pctx); + return pkey; } diff --git a/crypto/openssl/apps/testrsa.h b/crypto/openssl/apps/testrsa.h index 1350ce54e3fb..8c3a967414c6 100644 --- a/crypto/openssl/apps/testrsa.h +++ b/crypto/openssl/apps/testrsa.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/apps/timeouts.h b/crypto/openssl/apps/timeouts.h index 7e606cba0b20..002852724763 100644 --- a/crypto/openssl/apps/timeouts.h +++ b/crypto/openssl/apps/timeouts.h @@ -1,7 +1,7 @@ /* * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/apps/ts.c b/crypto/openssl/apps/ts.c index 66a0c810e0c3..57292e187cd2 100644 --- a/crypto/openssl/apps/ts.c +++ b/crypto/openssl/apps/ts.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -63,60 +63,68 @@ static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial); /* Verify related functions. */ static int verify_command(const char *data, const char *digest, const char *queryfile, const char *in, int token_in, - const char *CApath, const char *CAfile, const char *untrusted, - X509_VERIFY_PARAM *vpm); + const char *CApath, const char *CAfile, + const char *CAstore, + char *untrusted, X509_VERIFY_PARAM *vpm); static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest, const char *queryfile, const char *CApath, const char *CAfile, - const char *untrusted, + const char *CAstore, + char *untrusted, X509_VERIFY_PARAM *vpm); static X509_STORE *create_cert_store(const char *CApath, const char *CAfile, - X509_VERIFY_PARAM *vpm); + const char *CAstore, X509_VERIFY_PARAM *vpm); static int verify_cb(int ok, X509_STORE_CTX *ctx); typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_ENGINE, OPT_CONFIG, OPT_SECTION, OPT_QUERY, OPT_DATA, OPT_DIGEST, OPT_TSPOLICY, OPT_NO_NONCE, OPT_CERT, OPT_IN, OPT_TOKEN_IN, OPT_OUT, OPT_TOKEN_OUT, OPT_TEXT, OPT_REPLY, OPT_QUERYFILE, OPT_PASSIN, OPT_INKEY, OPT_SIGNER, - OPT_CHAIN, OPT_VERIFY, OPT_CAPATH, OPT_CAFILE, OPT_UNTRUSTED, - OPT_MD, OPT_V_ENUM, OPT_R_ENUM + OPT_CHAIN, OPT_VERIFY, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, OPT_UNTRUSTED, + OPT_MD, OPT_V_ENUM, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS ts_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"config", OPT_CONFIG, '<', "Configuration file"}, {"section", OPT_SECTION, 's', "Section to use within config file"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {"inkey", OPT_INKEY, 's', "File with private key for reply"}, + {"signer", OPT_SIGNER, 's', "Signer certificate file"}, + {"chain", OPT_CHAIN, '<', "File with signer CA chain"}, + {"CAfile", OPT_CAFILE, '<', "File with trusted CA certs"}, + {"CApath", OPT_CAPATH, '/', "Path to trusted CA files"}, + {"CAstore", OPT_CASTORE, ':', "URI to trusted CA store"}, + {"untrusted", OPT_UNTRUSTED, '<', "Extra untrusted certs"}, + {"token_in", OPT_TOKEN_IN, '-', "Input is a PKCS#7 file"}, + {"token_out", OPT_TOKEN_OUT, '-', "Output is a PKCS#7 file"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"", OPT_MD, '-', "Any supported digest"}, + + OPT_SECTION("Query"), {"query", OPT_QUERY, '-', "Generate a TS query"}, {"data", OPT_DATA, '<', "File to hash"}, {"digest", OPT_DIGEST, 's', "Digest (as a hex string)"}, - OPT_R_OPTIONS, - {"tspolicy", OPT_TSPOLICY, 's', "Policy OID to use"}, - {"no_nonce", OPT_NO_NONCE, '-', "Do not include a nonce"}, + {"queryfile", OPT_QUERYFILE, '<', "File containing a TS query"}, {"cert", OPT_CERT, '-', "Put cert request into query"}, {"in", OPT_IN, '<', "Input file"}, - {"token_in", OPT_TOKEN_IN, '-', "Input is a PKCS#7 file"}, + + OPT_SECTION("Verify"), + {"verify", OPT_VERIFY, '-', "Verify a TS response"}, + {"reply", OPT_REPLY, '-', "Generate a TS reply"}, + {"tspolicy", OPT_TSPOLICY, 's', "Policy OID to use"}, + {"no_nonce", OPT_NO_NONCE, '-', "Do not include a nonce"}, {"out", OPT_OUT, '>', "Output file"}, - {"token_out", OPT_TOKEN_OUT, '-', "Output is a PKCS#7 file"}, {"text", OPT_TEXT, '-', "Output text (not DER)"}, - {"reply", OPT_REPLY, '-', "Generate a TS reply"}, - {"queryfile", OPT_QUERYFILE, '<', "File containing a TS query"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"inkey", OPT_INKEY, 's', "File with private key for reply"}, - {"signer", OPT_SIGNER, 's', "Signer certificate file"}, - {"chain", OPT_CHAIN, '<', "File with signer CA chain"}, - {"verify", OPT_VERIFY, '-', "Verify a TS response"}, - {"CApath", OPT_CAPATH, '/', "Path to trusted CA files"}, - {"CAfile", OPT_CAFILE, '<', "File with trusted CA certs"}, - {"untrusted", OPT_UNTRUSTED, '<', "File with untrusted certs"}, - {"", OPT_MD, '-', "Any supported digest"}, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif - {OPT_HELP_STR, 1, '-', "\nOptions specific to 'ts -verify': \n"}, + + OPT_R_OPTIONS, OPT_V_OPTIONS, - {OPT_HELP_STR, 1, '-', "\n"}, + OPT_PROV_OPTIONS, {NULL} }; @@ -124,41 +132,43 @@ const OPTIONS ts_options[] = { * This command is so complex, special help is needed. */ static char* opt_helplist[] = { + "", "Typical uses:", - "ts -query [-rand file...] [-config file] [-data file]", - " [-digest hexstring] [-tspolicy oid] [-no_nonce] [-cert]", - " [-in file] [-out file] [-text]", - " or", - "ts -reply [-config file] [-section tsa_section]", - " [-queryfile file] [-passin password]", - " [-signer tsa_cert.pem] [-inkey private_key.pem]", - " [-chain certs_file.pem] [-tspolicy oid]", - " [-in file] [-token_in] [-out file] [-token_out]", + " openssl ts -query [-rand file...] [-config file] [-data file]", + " [-digest hexstring] [-tspolicy oid] [-no_nonce] [-cert]", + " [-in file] [-out file] [-text]", + "", + " openssl ts -reply [-config file] [-section tsa_section]", + " [-queryfile file] [-passin password]", + " [-signer tsa_cert.pem] [-inkey private_key.pem]", + " [-chain certs_file.pem] [-tspolicy oid]", + " [-in file] [-token_in] [-out file] [-token_out]", #ifndef OPENSSL_NO_ENGINE - " [-text] [-engine id]", + " [-text] [-engine id]", #else - " [-text]", + " [-text]", #endif - " or", - "ts -verify -CApath dir -CAfile file.pem -untrusted file.pem", - " [-data file] [-digest hexstring]", - " [-queryfile file] -in file [-token_in]", - " [[options specific to 'ts -verify']]", + "", + " openssl ts -verify -CApath dir -CAfile root-cert.pem -CAstore uri", + " -untrusted extra-certs.pem [-data file] [-digest hexstring]", + " [-queryfile request.tsq] -in response.tsr [-token_in] ...", NULL, }; int ts_main(int argc, char **argv) { CONF *conf = NULL; - const char *CAfile = NULL, *untrusted = NULL, *prog; + const char *CAfile = NULL, *prog; + char *untrusted = NULL; const char *configfile = default_config_file, *engine = NULL; - const char *section = NULL; + const char *section = NULL, *digestname = NULL; char **helpp; char *password = NULL; char *data = NULL, *digest = NULL, *policy = NULL; char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL; char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL; - const EVP_MD *md = NULL; + char *CAstore = NULL; + EVP_MD *md = NULL; OPTION_CHOICE o, mode = OPT_ERR; int ret = 1, no_nonce = 0, cert = 0, text = 0; int vpmtouched = 0; @@ -208,6 +218,10 @@ int ts_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_TSPOLICY: policy = opt_arg(); break; @@ -253,6 +267,9 @@ int ts_main(int argc, char **argv) case OPT_CAFILE: CAfile = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_UNTRUSTED: untrusted = opt_arg(); break; @@ -260,8 +277,7 @@ int ts_main(int argc, char **argv) engine = opt_arg(); break; case OPT_MD: - if (!opt_md(opt_unknown(), &md)) - goto opthelp; + digestname = opt_unknown(); break; case OPT_V_CASES: if (!opt_verify(o, vpm)) @@ -270,9 +286,19 @@ int ts_main(int argc, char **argv) break; } } - if (mode == OPT_ERR || opt_num_rest() != 0) + + /* No extra arguments. */ + argc = opt_num_rest(); + if (argc != 0 || mode == OPT_ERR) goto opthelp; + if (!app_RAND_load()) + goto end; + + if (digestname != NULL) { + if (!opt_md(digestname, &md)) + goto opthelp; + } if (mode == OPT_REPLY && passin && !app_passwd(passin, NULL, &password, NULL)) { BIO_printf(bio_err, "Error getting password.\n"); @@ -309,7 +335,7 @@ int ts_main(int argc, char **argv) if ((in == NULL) || !EXACTLY_ONE(queryfile, data, digest)) goto opthelp; ret = !verify_command(data, digest, queryfile, in, token_in, - CApath, CAfile, untrusted, + CApath, CAfile, CAstore, untrusted, vpmtouched ? vpm : NULL); } else { goto opthelp; @@ -317,6 +343,7 @@ int ts_main(int argc, char **argv) end: X509_VERIFY_PARAM_free(vpm); + EVP_MD_free(md); NCONF_free(conf); OPENSSL_free(password); return ret; @@ -423,7 +450,7 @@ static TS_REQ *create_query(BIO *data_bio, const char *digest, const EVP_MD *md, ASN1_OBJECT *policy_obj = NULL; ASN1_INTEGER *nonce_asn1 = NULL; - if (md == NULL && (md = EVP_get_digestbyname("sha1")) == NULL) + if (md == NULL && (md = EVP_get_digestbyname("sha256")) == NULL) goto err; if ((ts_req = TS_REQ_new()) == NULL) goto err; @@ -433,7 +460,7 @@ static TS_REQ *create_query(BIO *data_bio, const char *digest, const EVP_MD *md, goto err; if ((algo = X509_ALGOR_new()) == NULL) goto err; - if ((algo->algorithm = OBJ_nid2obj(EVP_MD_type(md))) == NULL) + if ((algo->algorithm = OBJ_nid2obj(EVP_MD_get_type(md))) == NULL) goto err; if ((algo->parameter = ASN1_TYPE_new()) == NULL) goto err; @@ -482,7 +509,7 @@ static int create_digest(BIO *input, const char *digest, const EVP_MD *md, int rv = 0; EVP_MD_CTX *md_ctx = NULL; - md_value_len = EVP_MD_size(md); + md_value_len = EVP_MD_get_size(md); if (md_value_len < 0) return 0; @@ -502,11 +529,12 @@ static int create_digest(BIO *input, const char *digest, const EVP_MD *md, } if (!EVP_DigestFinal(md_ctx, *md_value, NULL)) goto err; - md_value_len = EVP_MD_size(md); + md_value_len = EVP_MD_get_size(md); } else { long digest_len; + *md_value = OPENSSL_hexstr2buf(digest, &digest_len); - if (!*md_value || md_value_len != digest_len) { + if (*md_value == NULL || md_value_len != digest_len) { OPENSSL_free(*md_value); *md_value = NULL; BIO_printf(bio_err, "bad digest, %d bytes " @@ -817,7 +845,8 @@ static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial) static int verify_command(const char *data, const char *digest, const char *queryfile, const char *in, int token_in, - const char *CApath, const char *CAfile, const char *untrusted, + const char *CApath, const char *CAfile, + const char *CAstore, char *untrusted, X509_VERIFY_PARAM *vpm) { BIO *in_bio = NULL; @@ -837,7 +866,7 @@ static int verify_command(const char *data, const char *digest, const char *quer } if ((verify_ctx = create_verify_ctx(data, digest, queryfile, - CApath, CAfile, untrusted, + CApath, CAfile, CAstore, untrusted, vpm)) == NULL) goto end; @@ -864,10 +893,12 @@ static int verify_command(const char *data, const char *digest, const char *quer static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest, const char *queryfile, const char *CApath, const char *CAfile, - const char *untrusted, + const char *CAstore, + char *untrusted, X509_VERIFY_PARAM *vpm) { TS_VERIFY_CTX *ctx = NULL; + STACK_OF(X509) *certs; BIO *input = NULL; TS_REQ *request = NULL; int ret = 0; @@ -912,14 +943,18 @@ static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest, TS_VERIFY_CTX_add_flags(ctx, f | TS_VFY_SIGNATURE); /* Initialising the X509_STORE object. */ - if (TS_VERIFY_CTX_set_store(ctx, create_cert_store(CApath, CAfile, vpm)) + if (TS_VERIFY_CTX_set_store(ctx, + create_cert_store(CApath, CAfile, CAstore, vpm)) == NULL) goto err; - /* Loading untrusted certificates. */ - if (untrusted - && TS_VERIFY_CTS_set_certs(ctx, TS_CONF_load_certs(untrusted)) == NULL) - goto err; + /* Loading any extra untrusted certificates. */ + if (untrusted != NULL) { + certs = load_certs_multifile(untrusted, NULL, "extra untrusted certs", + vpm); + if (certs == NULL || TS_VERIFY_CTX_set_certs(ctx, certs) == NULL) + goto err; + } ret = 1; err: @@ -933,13 +968,18 @@ static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest, } static X509_STORE *create_cert_store(const char *CApath, const char *CAfile, - X509_VERIFY_PARAM *vpm) + const char *CAstore, X509_VERIFY_PARAM *vpm) { X509_STORE *cert_ctx = NULL; X509_LOOKUP *lookup = NULL; - int i; + OSSL_LIB_CTX *libctx = app_get0_libctx(); + const char *propq = app_get0_propq(); cert_ctx = X509_STORE_new(); + if (cert_ctx == NULL) { + BIO_printf(bio_err, "memory allocation failure\n"); + return NULL; + } X509_STORE_set_verify_cb(cert_ctx, verify_cb); if (CApath != NULL) { lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir()); @@ -947,8 +987,7 @@ static X509_STORE *create_cert_store(const char *CApath, const char *CAfile, BIO_printf(bio_err, "memory allocation failure\n"); goto err; } - i = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM); - if (!i) { + if (X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM) <= 0) { BIO_printf(bio_err, "Error loading directory %s\n", CApath); goto err; } @@ -960,13 +999,25 @@ static X509_STORE *create_cert_store(const char *CApath, const char *CAfile, BIO_printf(bio_err, "memory allocation failure\n"); goto err; } - i = X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM); - if (!i) { + if (X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_PEM, libctx, + propq) <= 0) { BIO_printf(bio_err, "Error loading file %s\n", CAfile); goto err; } } + if (CAstore != NULL) { + lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_store()); + if (lookup == NULL) { + BIO_printf(bio_err, "memory allocation failure\n"); + goto err; + } + if (X509_LOOKUP_load_store_ex(lookup, CAstore, libctx, propq) <= 0) { + BIO_printf(bio_err, "Error loading store URI %s\n", CAstore); + goto err; + } + } + if (vpm != NULL) X509_STORE_set1_param(cert_ctx, vpm); diff --git a/crypto/openssl/apps/tsget.in b/crypto/openssl/apps/tsget.in index bec365e28ce5..3b5f83cf9b57 100644 --- a/crypto/openssl/apps/tsget.in +++ b/crypto/openssl/apps/tsget.in @@ -1,8 +1,8 @@ #!{- $config{HASHBANGPERL} -} -# Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2002 The OpenTSA Project. All rights reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -21,10 +21,10 @@ sub read_body { my $return_data = ""; my $data_len = length ${$state->{data}}; if ($state->{bytes} < $data_len) { - $data_len = $data_len - $state->{bytes}; - $data_len = $maxlength if $data_len > $maxlength; - $return_data = substr ${$state->{data}}, $state->{bytes}, $data_len; - $state->{bytes} += $data_len; + $data_len = $data_len - $state->{bytes}; + $data_len = $maxlength if $data_len > $maxlength; + $return_data = substr ${$state->{data}}, $state->{bytes}, $data_len; + $state->{bytes} += $data_len; } return $return_data; } @@ -47,14 +47,14 @@ sub create_curl { $curl->setopt(CURLOPT_VERBOSE, 1) if $options{d}; $curl->setopt(CURLOPT_FAILONERROR, 1); $curl->setopt(CURLOPT_USERAGENT, - "OpenTSA tsget.pl/openssl-{- $config{version} -}"); + "OpenTSA tsget.pl/openssl-{- $config{full_version} -}"); # Options for POST method. $curl->setopt(CURLOPT_UPLOAD, 1); $curl->setopt(CURLOPT_CUSTOMREQUEST, "POST"); $curl->setopt(CURLOPT_HTTPHEADER, - ["Content-Type: application/timestamp-query", - "Accept: application/timestamp-reply,application/timestamp-response"]); + ["Content-Type: application/timestamp-query", + "Accept: application/timestamp-reply,application/timestamp-response"]); $curl->setopt(CURLOPT_READFUNCTION, \&read_body); $curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length($_[0]); }); @@ -63,8 +63,8 @@ sub create_curl { # SSL related options. $curl->setopt(CURLOPT_SSLKEYTYPE, "PEM"); - $curl->setopt(CURLOPT_SSL_VERIFYPEER, 1); # Verify server's certificate. - $curl->setopt(CURLOPT_SSL_VERIFYHOST, 2); # Check server's CN. + $curl->setopt(CURLOPT_SSL_VERIFYPEER, 1); # Verify server's certificate. + $curl->setopt(CURLOPT_SSL_VERIFYHOST, 2); # Check server's CN. $curl->setopt(CURLOPT_SSLKEY, $options{k}) if defined($options{k}); $curl->setopt(CURLOPT_SSLKEYPASSWD, $options{p}) if defined($options{p}); $curl->setopt(CURLOPT_SSLCERT, $options{c}) if defined($options{c}); @@ -101,15 +101,15 @@ sub get_timestamp { my $error_string; if ($error_code != 0) { my $http_code = $curl->getinfo(CURLINFO_HTTP_CODE); - $error_string = "could not get timestamp"; - $error_string .= ", http code: $http_code" unless $http_code == 0; - $error_string .= ", curl code: $error_code"; - $error_string .= " ($::error_buf)" if defined($::error_buf); + $error_string = "could not get timestamp"; + $error_string .= ", http code: $http_code" unless $http_code == 0; + $error_string .= ", curl code: $error_code"; + $error_string .= " ($::error_buf)" if defined($::error_buf); } else { my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE); - if (lc($ct) ne "application/timestamp-reply" - && lc($ct) ne "application/timestamp-response") { - $error_string = "unexpected content type returned: $ct"; + if (lc($ct) ne "application/timestamp-reply" + && lc($ct) ne "application/timestamp-response") { + $error_string = "unexpected content type returned: $ct"; } } return ($ts_body, $error_string); @@ -163,15 +163,15 @@ REQUEST: foreach (@ARGV) { # Read request. my $body; if ($input eq "-") { - # Read the request from STDIN; - $body = ; + # Read the request from STDIN; + $body = ; } else { - # Read the request from file. + # Read the request from file. open INPUT, "<" . $input - or warn("$input: could not open input file: $!\n"), next REQUEST; + or warn("$input: could not open input file: $!\n"), next REQUEST; $body = ; close INPUT - or warn("$input: could not close input file: $!\n"), next REQUEST; + or warn("$input: could not close input file: $!\n"), next REQUEST; } # Send request. @@ -179,21 +179,21 @@ REQUEST: foreach (@ARGV) { my ($ts_body, $error) = get_timestamp $curl, \$body; if (defined($error)) { - die "$input: fatal error: $error\n"; + die "$input: fatal error: $error\n"; } STDERR->printflush(", reply received") if $options{v}; # Write response. if ($output eq "-") { - # Write to STDOUT. + # Write to STDOUT. print $ts_body; } else { - # Write to file. + # Write to file. open OUTPUT, ">", $output - or warn("$output: could not open output file: $!\n"), next REQUEST; + or warn("$output: could not open output file: $!\n"), next REQUEST; print OUTPUT $ts_body; close OUTPUT - or warn("$output: could not close output file: $!\n"), next REQUEST; + or warn("$output: could not close output file: $!\n"), next REQUEST; } STDERR->printflush(", $output written.\n") if $options{v}; } diff --git a/crypto/openssl/apps/verify.c b/crypto/openssl/apps/verify.c index 1f9385606046..3aae931f69df 100644 --- a/crypto/openssl/apps/verify.c +++ b/crypto/openssl/apps/verify.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -21,42 +21,58 @@ static int cb(int ok, X509_STORE_CTX *ctx); static int check(X509_STORE *ctx, const char *file, STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, - STACK_OF(X509_CRL) *crls, int show_chain); + STACK_OF(X509_CRL) *crls, int show_chain, + STACK_OF(OPENSSL_STRING) *opts); static int v_verbose = 0, vflags = 0; typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, + OPT_COMMON, + OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, + OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN, - OPT_V_ENUM, OPT_NAMEOPT, - OPT_VERBOSE + OPT_V_ENUM, OPT_NAMEOPT, OPT_VFYOPT, + OPT_VERBOSE, + OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS verify_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"}, - {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert...]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif {"verbose", OPT_VERBOSE, '-', "Print extra information about the operations being performed."}, - {"CApath", OPT_CAPATH, '/', "A directory of trusted certificates"}, + {"nameopt", OPT_NAMEOPT, 's', "Certificate subject/issuer name printing options"}, + + OPT_SECTION("Certificate chain"), + {"trusted", OPT_TRUSTED, '<', "A file of trusted certificates"}, {"CAfile", OPT_CAFILE, '<', "A file of trusted certificates"}, + {"CApath", OPT_CAPATH, '/', "A directory of files with trusted certificates"}, + {"CAstore", OPT_CASTORE, ':', "URI to a store of trusted certificates"}, {"no-CAfile", OPT_NOCAFILE, '-', - "Do not load the default certificates file"}, + "Do not load the default trusted certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', - "Do not load certificates from the default certificates directory"}, + "Do not load trusted certificates from the default directory"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load trusted certificates from the default certificates store"}, {"untrusted", OPT_UNTRUSTED, '<', "A file of untrusted certificates"}, - {"trusted", OPT_TRUSTED, '<', "A file of trusted certificates"}, {"CRLfile", OPT_CRLFILE, '<', "File containing one or more CRL's (in PEM format) to load"}, {"crl_download", OPT_CRL_DOWNLOAD, '-', - "Attempt to download CRL information for this certificate"}, + "Try downloading CRL information for certificates via their CDP entries"}, {"show_chain", OPT_SHOW_CHAIN, '-', "Display information about the certificate chain"}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, + OPT_V_OPTIONS, -#ifndef OPENSSL_NO_ENGINE - {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif + {"vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form"}, + + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"cert", 0, 0, "Certificate(s) to verify (optional; stdin used otherwise)"}, {NULL} }; @@ -65,10 +81,11 @@ int verify_main(int argc, char **argv) ENGINE *e = NULL; STACK_OF(X509) *untrusted = NULL, *trusted = NULL; STACK_OF(X509_CRL) *crls = NULL; + STACK_OF(OPENSSL_STRING) *vfyopts = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; - const char *prog, *CApath = NULL, *CAfile = NULL; - int noCApath = 0, noCAfile = 0; + const char *prog, *CApath = NULL, *CAfile = NULL, *CAstore = NULL; + int noCApath = 0, noCAfile = 0, noCAstore = 0; int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1; OPTION_CHOICE o; @@ -80,24 +97,25 @@ int verify_main(int argc, char **argv) switch (o) { case OPT_EOF: case OPT_ERR: + opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(verify_options); - BIO_printf(bio_err, "Recognized usages:\n"); + BIO_printf(bio_err, "\nRecognized certificate chain purposes:\n"); for (i = 0; i < X509_PURPOSE_get_count(); i++) { - X509_PURPOSE *ptmp; - ptmp = X509_PURPOSE_get0(i); - BIO_printf(bio_err, "\t%-10s\t%s\n", + X509_PURPOSE *ptmp = X509_PURPOSE_get0(i); + + BIO_printf(bio_err, " %-15s %s\n", X509_PURPOSE_get0_sname(ptmp), X509_PURPOSE_get0_name(ptmp)); } - BIO_printf(bio_err, "Recognized verify names:\n"); + BIO_printf(bio_err, "Recognized certificate policy names:\n"); for (i = 0; i < X509_VERIFY_PARAM_get_count(); i++) { - const X509_VERIFY_PARAM *vptmp; - vptmp = X509_VERIFY_PARAM_get0(i); - BIO_printf(bio_err, "\t%-10s\n", + const X509_VERIFY_PARAM *vptmp = X509_VERIFY_PARAM_get0(i); + + BIO_printf(bio_err, " %s\n", X509_VERIFY_PARAM_get0_name(vptmp)); } ret = 0; @@ -113,15 +131,21 @@ int verify_main(int argc, char **argv) case OPT_CAFILE: CAfile = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; case OPT_NOCAPATH: noCApath = 1; break; case OPT_NOCAFILE: noCAfile = 1; break; + case OPT_NOCASTORE: + noCAstore = 1; + break; case OPT_UNTRUSTED: /* Zero or more times */ - if (!load_certs(opt_arg(), &untrusted, FORMAT_PEM, NULL, + if (!load_certs(opt_arg(), 0, &untrusted, NULL, "untrusted certificates")) goto end; break; @@ -129,14 +153,13 @@ int verify_main(int argc, char **argv) /* Zero or more times */ noCAfile = 1; noCApath = 1; - if (!load_certs(opt_arg(), &trusted, FORMAT_PEM, NULL, - "trusted certificates")) + noCAstore = 1; + if (!load_certs(opt_arg(), 0, &trusted, NULL, "trusted certificates")) goto end; break; case OPT_CRLFILE: /* Zero or more times */ - if (!load_crls(opt_arg(), &crls, FORMAT_PEM, NULL, - "other CRLs")) + if (!load_crls(opt_arg(), &crls, NULL, "other CRLs")) goto end; break; case OPT_CRL_DOWNLOAD: @@ -155,21 +178,36 @@ int verify_main(int argc, char **argv) if (!set_nameopt(opt_arg())) goto end; break; + case OPT_VFYOPT: + if (!vfyopts) + vfyopts = sk_OPENSSL_STRING_new_null(); + if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg())) + goto opthelp; + break; case OPT_VERBOSE: v_verbose = 1; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; } } + + /* Extra arguments are certificates to verify. */ argc = opt_num_rest(); argv = opt_rest(); - if (trusted != NULL && (CAfile || CApath)) { + + if (trusted != NULL + && (CAfile != NULL || CApath != NULL || CAstore != NULL)) { BIO_printf(bio_err, - "%s: Cannot use -trusted with -CAfile or -CApath\n", + "%s: Cannot use -trusted with -CAfile, -CApath or -CAstore\n", prog); goto end; } - if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) + if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) == NULL) goto end; X509_STORE_set_verify_cb(store, cb); @@ -183,12 +221,13 @@ int verify_main(int argc, char **argv) ret = 0; if (argc < 1) { - if (check(store, NULL, untrusted, trusted, crls, show_chain) != 1) + if (check(store, NULL, untrusted, trusted, crls, show_chain, + vfyopts) != 1) ret = -1; } else { for (i = 0; i < argc; i++) - if (check(store, argv[i], untrusted, trusted, crls, - show_chain) != 1) + if (check(store, argv[i], untrusted, trusted, crls, show_chain, + vfyopts) != 1) ret = -1; } @@ -198,13 +237,15 @@ int verify_main(int argc, char **argv) sk_X509_pop_free(untrusted, X509_free); sk_X509_pop_free(trusted, X509_free); sk_X509_CRL_pop_free(crls, X509_CRL_free); + sk_OPENSSL_STRING_free(vfyopts); release_engine(e); return (ret < 0 ? 2 : ret); } static int check(X509_STORE *ctx, const char *file, STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, - STACK_OF(X509_CRL) *crls, int show_chain) + STACK_OF(X509_CRL) *crls, int show_chain, + STACK_OF(OPENSSL_STRING) *opts) { X509 *x = NULL; int i = 0, ret = 0; @@ -212,22 +253,35 @@ static int check(X509_STORE *ctx, const char *file, STACK_OF(X509) *chain = NULL; int num_untrusted; - x = load_cert(file, FORMAT_PEM, "certificate file"); + x = load_cert(file, FORMAT_UNDEF, "certificate file"); if (x == NULL) goto end; + if (opts != NULL) { + for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { + char *opt = sk_OPENSSL_STRING_value(opts, i); + if (x509_ctrl_string(x, opt) <= 0) { + BIO_printf(bio_err, "parameter error \"%s\"\n", opt); + ERR_print_errors(bio_err); + X509_free(x); + return 0; + } + } + } + csc = X509_STORE_CTX_new(); if (csc == NULL) { - printf("error %s: X.509 store context allocation failed\n", - (file == NULL) ? "stdin" : file); + BIO_printf(bio_err, "error %s: X.509 store context allocation failed\n", + (file == NULL) ? "stdin" : file); goto end; } X509_STORE_set_flags(ctx, vflags); if (!X509_STORE_CTX_init(csc, ctx, x, uchain)) { X509_STORE_CTX_free(csc); - printf("error %s: X.509 store context initialization failed\n", - (file == NULL) ? "stdin" : file); + BIO_printf(bio_err, + "error %s: X.509 store context initialization failed\n", + (file == NULL) ? "stdin" : file); goto end; } if (tchain != NULL) @@ -236,28 +290,30 @@ static int check(X509_STORE *ctx, const char *file, X509_STORE_CTX_set0_crls(csc, crls); i = X509_verify_cert(csc); if (i > 0 && X509_STORE_CTX_get_error(csc) == X509_V_OK) { - printf("%s: OK\n", (file == NULL) ? "stdin" : file); + BIO_printf(bio_out, "%s: OK\n", (file == NULL) ? "stdin" : file); ret = 1; if (show_chain) { int j; chain = X509_STORE_CTX_get1_chain(csc); num_untrusted = X509_STORE_CTX_get_num_untrusted(csc); - printf("Chain:\n"); + BIO_printf(bio_out, "Chain:\n"); for (j = 0; j < sk_X509_num(chain); j++) { X509 *cert = sk_X509_value(chain, j); - printf("depth=%d: ", j); + BIO_printf(bio_out, "depth=%d: ", j); X509_NAME_print_ex_fp(stdout, X509_get_subject_name(cert), 0, get_nameopt()); if (j < num_untrusted) - printf(" (untrusted)"); - printf("\n"); + BIO_printf(bio_out, " (untrusted)"); + BIO_printf(bio_out, "\n"); } sk_X509_pop_free(chain, X509_free); } } else { - printf("error %s: verification failed\n", (file == NULL) ? "stdin" : file); + BIO_printf(bio_err, + "error %s: verification failed\n", + (file == NULL) ? "stdin" : file); } X509_STORE_CTX_free(csc); @@ -298,19 +354,34 @@ static int cb(int ok, X509_STORE_CTX *ctx) policies_print(ctx); /* fall thru */ case X509_V_ERR_CERT_HAS_EXPIRED: - /* Continue even if the leaf is a self signed cert */ + /* Continue even if the leaf is a self-signed cert */ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: /* Continue after extension errors too */ case X509_V_ERR_INVALID_CA: case X509_V_ERR_INVALID_NON_CA: case X509_V_ERR_PATH_LENGTH_EXCEEDED: - case X509_V_ERR_INVALID_PURPOSE: case X509_V_ERR_CRL_HAS_EXPIRED: case X509_V_ERR_CRL_NOT_YET_VALID: case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: + /* errors due to strict conformance checking (-x509_strict) */ + case X509_V_ERR_INVALID_PURPOSE: + case X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA: + case X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN: + case X509_V_ERR_CA_BCONS_NOT_CRITICAL: + case X509_V_ERR_CA_CERT_MISSING_KEY_USAGE: + case X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA: + case X509_V_ERR_ISSUER_NAME_EMPTY: + case X509_V_ERR_SUBJECT_NAME_EMPTY: + case X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL: + case X509_V_ERR_EMPTY_SUBJECT_ALT_NAME: + case X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY: + case X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL: + case X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL: + case X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER: + case X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER: + case X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3: ok = 1; } - return ok; } diff --git a/crypto/openssl/apps/version.c b/crypto/openssl/apps/version.c index 2aca1636152b..cab17a46bf18 100644 --- a/crypto/openssl/apps/version.c +++ b/crypto/openssl/apps/version.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,56 +15,36 @@ #include #include #include -#ifndef OPENSSL_NO_MD2 -# include -#endif -#ifndef OPENSSL_NO_RC4 -# include -#endif -#ifndef OPENSSL_NO_DES -# include -#endif -#ifndef OPENSSL_NO_IDEA -# include -#endif -#ifndef OPENSSL_NO_BF -# include -#endif typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_B, OPT_D, OPT_E, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A, OPT_R + OPT_COMMON, + OPT_B, OPT_D, OPT_E, OPT_M, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A, OPT_R, OPT_C } OPTION_CHOICE; const OPTIONS version_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + OPT_SECTION("Output"), {"a", OPT_A, '-', "Show all data"}, {"b", OPT_B, '-', "Show build date"}, {"d", OPT_D, '-', "Show configuration directory"}, {"e", OPT_E, '-', "Show engines directory"}, + {"m", OPT_M, '-', "Show modules directory"}, {"f", OPT_F, '-', "Show compiler flags used"}, {"o", OPT_O, '-', "Show some internal datatype options"}, {"p", OPT_P, '-', "Show target build platform"}, {"r", OPT_R, '-', "Show random seeding options"}, {"v", OPT_V, '-', "Show library version"}, + {"c", OPT_C, '-', "Show CPU settings info"}, {NULL} }; -#if defined(OPENSSL_RAND_SEED_DEVRANDOM) || defined(OPENSSL_RAND_SEED_EGD) -static void printlist(const char *prefix, const char **dev) -{ - printf("%s (", prefix); - for ( ; *dev != NULL; dev++) - printf(" \"%s\"", *dev); - printf(" )"); -} -#endif - int version_main(int argc, char **argv) { int ret = 1, dirty = 0, seed = 0; int cflags = 0, version = 0, date = 0, options = 0, platform = 0, dir = 0; - int engdir = 0; + int engdir = 0, moddir = 0, cpuinfo = 0; char *prog; OPTION_CHOICE o; @@ -89,6 +69,9 @@ int version_main(int argc, char **argv) case OPT_E: dirty = engdir = 1; break; + case OPT_M: + dirty = moddir = 1; + break; case OPT_F: dirty = cflags = 1; break; @@ -104,48 +87,35 @@ int version_main(int argc, char **argv) case OPT_V: dirty = version = 1; break; + case OPT_C: + dirty = cpuinfo = 1; + break; case OPT_A: - seed = options = cflags = version = date = platform = dir = engdir + seed = options = cflags = version = date = platform + = dir = engdir = moddir = cpuinfo = 1; break; } } - if (opt_num_rest() != 0) { - BIO_printf(bio_err, "Extra parameters given.\n"); + + /* No extra arguments. */ + argc = opt_num_rest(); + if (argc != 0) goto opthelp; - } + if (!dirty) version = 1; - if (version) { - if (OpenSSL_version_num() == OPENSSL_VERSION_NUMBER) - printf("%s\n", OpenSSL_version(OPENSSL_VERSION)); - else - printf("%s (Library: %s)\n", - OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION)); - } + if (version) + printf("%s (Library: %s)\n", + OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION)); if (date) printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON)); if (platform) printf("%s\n", OpenSSL_version(OPENSSL_PLATFORM)); if (options) { - printf("options: "); - printf("%s ", BN_options()); -#ifndef OPENSSL_NO_MD2 - printf("%s ", MD2_options()); -#endif -#ifndef OPENSSL_NO_RC4 - printf("%s ", RC4_options()); -#endif -#ifndef OPENSSL_NO_DES - printf("%s ", DES_options()); -#endif -#ifndef OPENSSL_NO_IDEA - printf("%s ", IDEA_options()); -#endif -#ifndef OPENSSL_NO_BF - printf("%s ", BF_options()); -#endif + printf("options: "); + printf(" %s", BN_options()); printf("\n"); } if (cflags) @@ -154,41 +124,28 @@ int version_main(int argc, char **argv) printf("%s\n", OpenSSL_version(OPENSSL_DIR)); if (engdir) printf("%s\n", OpenSSL_version(OPENSSL_ENGINES_DIR)); + if (moddir) + printf("%s\n", OpenSSL_version(OPENSSL_MODULES_DIR)); if (seed) { - printf("Seeding source:"); -#ifdef OPENSSL_RAND_SEED_RTDSC - printf(" rtdsc"); -#endif -#ifdef OPENSSL_RAND_SEED_RDCPU - printf(" rdrand ( rdseed rdrand )"); -#endif -#ifdef OPENSSL_RAND_SEED_LIBRANDOM - printf(" C-library-random"); -#endif -#ifdef OPENSSL_RAND_SEED_GETRANDOM - printf(" getrandom-syscall"); -#endif -#ifdef OPENSSL_RAND_SEED_DEVRANDOM - { - static const char *dev[] = { DEVRANDOM, NULL }; - printlist(" random-device", dev); - } -#endif -#ifdef OPENSSL_RAND_SEED_EGD - { - static const char *dev[] = { DEVRANDOM_EGD, NULL }; - printlist(" EGD", dev); - } -#endif -#ifdef OPENSSL_RAND_SEED_NONE - printf(" none"); -#endif -#ifdef OPENSSL_RAND_SEED_OS - printf(" os-specific"); -#endif - printf("\n"); + const char *src = OPENSSL_info(OPENSSL_INFO_SEED_SOURCE); + printf("Seeding source: %s\n", src ? src : "N/A"); } + if (cpuinfo) + printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO)); ret = 0; end: return ret; } + + +#if defined(__TANDEM) && defined(OPENSSL_VPROC) +/* + * Define a VPROC function for the openssl program. + * This is used by platform version identification tools. + * Do not inline this procedure or make it static. + */ +# define OPENSSL_VPROC_STRING_(x) x##_OPENSSL +# define OPENSSL_VPROC_STRING(x) OPENSSL_VPROC_STRING_(x) +# define OPENSSL_VPROC_FUNC OPENSSL_VPROC_STRING(OPENSSL_VPROC) +void OPENSSL_VPROC_FUNC(void) {} +#endif diff --git a/crypto/openssl/apps/x509.c b/crypto/openssl/apps/x509.c index 8d4bf71a03ee..a919d787457c 100644 --- a/crypto/openssl/apps/x509.c +++ b/crypto/openssl/apps/x509.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -21,162 +21,271 @@ #include #include #include -#ifndef OPENSSL_NO_RSA -# include -#endif +#include #ifndef OPENSSL_NO_DSA # include #endif #undef POSTFIX #define POSTFIX ".srl" -#define DEF_DAYS 30 +#define DEFAULT_DAYS 30 /* default cert validity period in days */ +#define UNSET_DAYS -2 /* -1 is used for testing expiration checks */ +#define EXT_COPY_UNSET -1 static int callb(int ok, X509_STORE_CTX *ctx); -static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, - const EVP_MD *digest, CONF *conf, const char *section, - int preserve_dates); -static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest, - X509 *x, X509 *xca, EVP_PKEY *pkey, - STACK_OF(OPENSSL_STRING) *sigopts, const char *serialfile, - int create, int days, int clrext, CONF *conf, - const char *section, ASN1_INTEGER *sno, int reqfile, - int preserve_dates); +static ASN1_INTEGER *x509_load_serial(const char *CAfile, + const char *serialfile, int create); static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt); -static int print_x509v3_exts(BIO *bio, X509 *x, const char *exts); +static int print_x509v3_exts(BIO *bio, X509 *x, const char *ext_names); typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM, - OPT_CAKEYFORM, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE, - OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_SIGNKEY, OPT_CA, - OPT_CAKEY, OPT_CASERIAL, OPT_SET_SERIAL, OPT_FORCE_PUBKEY, - OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_NAMEOPT, - OPT_C, OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL, + OPT_CAKEYFORM, OPT_VFYOPT, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE, + OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_KEY, OPT_SIGNKEY, OPT_CA, OPT_CAKEY, + OPT_CASERIAL, OPT_SET_SERIAL, OPT_NEW, OPT_FORCE_PUBKEY, OPT_SUBJ, + OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_DATEOPT, OPT_NAMEOPT, + OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL, OPT_MODULUS, OPT_PUBKEY, OPT_X509TOREQ, OPT_TEXT, OPT_HASH, OPT_ISSUER_HASH, OPT_SUBJECT, OPT_ISSUER, OPT_FINGERPRINT, OPT_DATES, OPT_PURPOSE, OPT_STARTDATE, OPT_ENDDATE, OPT_CHECKEND, OPT_CHECKHOST, OPT_CHECKEMAIL, OPT_CHECKIP, OPT_NOOUT, OPT_TRUSTOUT, OPT_CLRTRUST, OPT_CLRREJECT, OPT_ALIAS, OPT_CACREATESERIAL, OPT_CLREXT, OPT_OCSPID, - OPT_SUBJECT_HASH_OLD, - OPT_ISSUER_HASH_OLD, + OPT_SUBJECT_HASH_OLD, OPT_ISSUER_HASH_OLD, OPT_COPY_EXTENSIONS, OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT, OPT_PRESERVE_DATES, - OPT_R_ENUM, OPT_EXT + OPT_R_ENUM, OPT_PROV_ENUM, OPT_EXT } OPTION_CHOICE; const OPTIONS x509_options[] = { + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + + {"in", OPT_IN, '<', + "Certificate input, or CSR input file with -req (default stdin)"}, + {"passin", OPT_PASSIN, 's', "Private key and cert file pass-phrase source"}, + {"new", OPT_NEW, '-', "Generate a certificate from scratch"}, + {"x509toreq", OPT_X509TOREQ, '-', + "Output a certification request (rather than a certificate)"}, + {"req", OPT_REQ, '-', "Input is a CSR file (rather than a certificate)"}, + {"copy_extensions", OPT_COPY_EXTENSIONS, 's', + "copy extensions when converting from CSR to x509 or vice versa"}, {"inform", OPT_INFORM, 'f', - "Input format - default PEM (one of DER or PEM)"}, - {"in", OPT_IN, '<', "Input file - default stdin"}, - {"outform", OPT_OUTFORM, 'f', - "Output format - default PEM (one of DER or PEM)"}, + "CSR input file format (DER or PEM) - default PEM"}, + {"vfyopt", OPT_VFYOPT, 's', "CSR verification parameter in n:v form"}, + {"key", OPT_KEY, 's', + "Key for signing, and to include unless using -force_pubkey"}, + {"signkey", OPT_SIGNKEY, 's', + "Same as -key"}, + {"keyform", OPT_KEYFORM, 'E', + "Key input format (ENGINE, other values ignored)"}, {"out", OPT_OUT, '>', "Output file - default stdout"}, - {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"}, - {"passin", OPT_PASSIN, 's', "Private key password/pass-phrase source"}, + {"outform", OPT_OUTFORM, 'f', + "Output format (DER or PEM) - default PEM"}, + {"nocert", OPT_NOCERT, '-', + "No cert output (except for requested printing)"}, + {"noout", OPT_NOOUT, '-', "No output (except for requested printing)"}, + + OPT_SECTION("Certificate printing"), + {"text", OPT_TEXT, '-', "Print the certificate in text form"}, + {"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."}, + {"certopt", OPT_CERTOPT, 's', "Various certificate text printing options"}, + {"fingerprint", OPT_FINGERPRINT, '-', "Print the certificate fingerprint"}, + {"alias", OPT_ALIAS, '-', "Print certificate alias"}, {"serial", OPT_SERIAL, '-', "Print serial number value"}, - {"subject_hash", OPT_HASH, '-', "Print subject hash value"}, - {"issuer_hash", OPT_ISSUER_HASH, '-', "Print issuer hash value"}, - {"hash", OPT_HASH, '-', "Synonym for -subject_hash"}, + {"startdate", OPT_STARTDATE, '-', "Print the notBefore field"}, + {"enddate", OPT_ENDDATE, '-', "Print the notAfter field"}, + {"dates", OPT_DATES, '-', "Print both notBefore and notAfter fields"}, {"subject", OPT_SUBJECT, '-', "Print subject DN"}, {"issuer", OPT_ISSUER, '-', "Print issuer DN"}, + {"nameopt", OPT_NAMEOPT, 's', + "Certificate subject/issuer name printing options"}, {"email", OPT_EMAIL, '-', "Print email address(es)"}, - {"startdate", OPT_STARTDATE, '-', "Set notBefore field"}, - {"enddate", OPT_ENDDATE, '-', "Set notAfter field"}, - {"purpose", OPT_PURPOSE, '-', "Print out certificate purposes"}, - {"dates", OPT_DATES, '-', "Both Before and After dates"}, - {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"}, - {"pubkey", OPT_PUBKEY, '-', "Output the public key"}, - {"fingerprint", OPT_FINGERPRINT, '-', - "Print the certificate fingerprint"}, - {"alias", OPT_ALIAS, '-', "Output certificate alias"}, - {"noout", OPT_NOOUT, '-', "No output, just status"}, - {"nocert", OPT_NOCERT, '-', "No certificate output"}, + {"hash", OPT_HASH, '-', "Synonym for -subject_hash (for backward compat)"}, + {"subject_hash", OPT_HASH, '-', "Print subject hash value"}, +#ifndef OPENSSL_NO_MD5 + {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-', + "Print old-style (MD5) subject hash value"}, +#endif + {"issuer_hash", OPT_ISSUER_HASH, '-', "Print issuer hash value"}, +#ifndef OPENSSL_NO_MD5 + {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-', + "Print old-style (MD5) issuer hash value"}, +#endif + {"ext", OPT_EXT, 's', + "Restrict which X.509 extensions to print and/or copy"}, {"ocspid", OPT_OCSPID, '-', "Print OCSP hash values for the subject name and public key"}, {"ocsp_uri", OPT_OCSP_URI, '-', "Print OCSP Responder URL(s)"}, - {"trustout", OPT_TRUSTOUT, '-', "Output a trusted certificate"}, - {"clrtrust", OPT_CLRTRUST, '-', "Clear all trusted purposes"}, - {"clrext", OPT_CLREXT, '-', "Clear all certificate extensions"}, - {"addtrust", OPT_ADDTRUST, 's', "Trust certificate for a given purpose"}, - {"addreject", OPT_ADDREJECT, 's', - "Reject certificate for a given purpose"}, - {"setalias", OPT_SETALIAS, 's', "Set certificate alias"}, - {"days", OPT_DAYS, 'n', - "How long till expiry of a signed certificate - def 30 days"}, + {"purpose", OPT_PURPOSE, '-', "Print out certificate purposes"}, + {"pubkey", OPT_PUBKEY, '-', "Print the public key in PEM format"}, + {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"}, + + OPT_SECTION("Certificate checking"), {"checkend", OPT_CHECKEND, 'M', - "Check whether the cert expires in the next arg seconds"}, - {OPT_MORE_STR, 1, 1, "Exit 1 if so, 0 if not"}, - {"signkey", OPT_SIGNKEY, 's', "Self sign cert with arg"}, - {"x509toreq", OPT_X509TOREQ, '-', - "Output a certification request object"}, - {"req", OPT_REQ, '-', "Input is a certificate request, sign and output"}, - {"CA", OPT_CA, '<', "Set the CA certificate, must be PEM format"}, - {"CAkey", OPT_CAKEY, 's', - "The CA key, must be PEM format; if not in CAfile"}, - {"CAcreateserial", OPT_CACREATESERIAL, '-', - "Create serial number file if it does not exist"}, - {"CAserial", OPT_CASERIAL, 's', "Serial file"}, - {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"}, - {"text", OPT_TEXT, '-', "Print the certificate in text form"}, - {"ext", OPT_EXT, 's', "Print various X509V3 extensions"}, - {"C", OPT_C, '-', "Print out C code forms"}, - {"extfile", OPT_EXTFILE, '<', "File with X509V3 extensions to add"}, - OPT_R_OPTIONS, - {"extensions", OPT_EXTENSIONS, 's', "Section from config file to use"}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, - {"certopt", OPT_CERTOPT, 's', "Various certificate text options"}, + "Check whether cert expires in the next arg seconds"}, + {OPT_MORE_STR, 1, 1, "Exit 1 (failure) if so, 0 if not"}, {"checkhost", OPT_CHECKHOST, 's', "Check certificate matches host"}, {"checkemail", OPT_CHECKEMAIL, 's', "Check certificate matches email"}, {"checkip", OPT_CHECKIP, 's', "Check certificate matches ipaddr"}, - {"CAform", OPT_CAFORM, 'F', "CA format - default PEM"}, - {"CAkeyform", OPT_CAKEYFORM, 'E', "CA key format - default PEM"}, - {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, - {"force_pubkey", OPT_FORCE_PUBKEY, '<', "Force the Key to put inside certificate"}, - {"next_serial", OPT_NEXT_SERIAL, '-', "Increment current certificate serial number"}, + + OPT_SECTION("Certificate output"), + {"set_serial", OPT_SET_SERIAL, 's', + "Serial number to use, overrides -CAserial"}, + {"next_serial", OPT_NEXT_SERIAL, '-', + "Increment current certificate serial number"}, + {"days", OPT_DAYS, 'n', + "Number of days until newly generated certificate expires - default 30"}, + {"preserve_dates", OPT_PRESERVE_DATES, '-', + "Preserve existing validity dates"}, + {"subj", OPT_SUBJ, 's', "Set or override certificate subject (and issuer)"}, + {"force_pubkey", OPT_FORCE_PUBKEY, '<', + "Place the given key in new certificate"}, + {"clrext", OPT_CLREXT, '-', + "Do not take over any extensions from the source certificate or request"}, + {"extfile", OPT_EXTFILE, '<', "Config file with X509V3 extensions to add"}, + {"extensions", OPT_EXTENSIONS, 's', + "Section of extfile to use - default: unnamed section"}, + {"sigopt", OPT_SIGOPT, 's', "Signature parameter, in n:v form"}, + {"badsig", OPT_BADSIG, '-', + "Corrupt last byte of certificate signature (for test)"}, + {"", OPT_MD, '-', "Any supported digest, used for signing and printing"}, + + OPT_SECTION("Micro-CA"), + {"CA", OPT_CA, '<', + "Use the given CA certificate, conflicts with -key"}, + {"CAform", OPT_CAFORM, 'F', "CA cert format (PEM/DER/P12); has no effect"}, + {"CAkey", OPT_CAKEY, 's', "The corresponding CA key; default is -CA arg"}, + {"CAkeyform", OPT_CAKEYFORM, 'E', + "CA key format (ENGINE, other values ignored)"}, + {"CAserial", OPT_CASERIAL, 's', + "File that keeps track of CA-generated serial number"}, + {"CAcreateserial", OPT_CACREATESERIAL, '-', + "Create CA serial number file if it does not exist"}, + + OPT_SECTION("Certificate trust output"), + {"trustout", OPT_TRUSTOUT, '-', "Mark certificate PEM output as trusted"}, + {"setalias", OPT_SETALIAS, 's', "Set certificate alias (nickname)"}, + {"clrtrust", OPT_CLRTRUST, '-', "Clear all trusted purposes"}, + {"addtrust", OPT_ADDTRUST, 's', "Trust certificate for a given purpose"}, {"clrreject", OPT_CLRREJECT, '-', "Clears all the prohibited or rejected uses of the certificate"}, - {"badsig", OPT_BADSIG, '-', "Corrupt last byte of certificate signature (for test)"}, - {"", OPT_MD, '-', "Any supported digest"}, -#ifndef OPENSSL_NO_MD5 - {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-', - "Print old-style (MD5) subject hash value"}, - {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-', - "Print old-style (MD5) issuer hash value"}, -#endif + {"addreject", OPT_ADDREJECT, 's', + "Reject certificate for a given purpose"}, + + OPT_R_OPTIONS, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif - {"preserve_dates", OPT_PRESERVE_DATES, '-', "preserve existing dates when signing"}, + OPT_PROV_OPTIONS, {NULL} }; +static void warn_copying(ASN1_OBJECT *excluded, const char *names) +{ + const char *sn = OBJ_nid2sn(OBJ_obj2nid(excluded)); + + if (names != NULL && strstr(names, sn) != NULL) + BIO_printf(bio_err, + "Warning: -ext should not specify copying %s extension to CSR; ignoring this\n", + sn); +} + +static X509_REQ *x509_to_req(X509 *cert, int ext_copy, const char *names) +{ + const STACK_OF(X509_EXTENSION) *cert_exts = X509_get0_extensions(cert); + int i, n = sk_X509_EXTENSION_num(cert_exts /* may be NULL */); + ASN1_OBJECT *skid = OBJ_nid2obj(NID_subject_key_identifier); + ASN1_OBJECT *akid = OBJ_nid2obj(NID_authority_key_identifier); + STACK_OF(X509_EXTENSION) *exts; + X509_REQ *req = X509_to_X509_REQ(cert, NULL, NULL); + + if (req == NULL) + return NULL; + + /* + * Filter out SKID and AKID extensions, which make no sense in a CSR. + * If names is not NULL, copy only those extensions listed there. + */ + warn_copying(skid, names); + warn_copying(akid, names); + if ((exts = sk_X509_EXTENSION_new_reserve(NULL, n)) == NULL) + goto err; + for (i = 0; i < n; i++) { + X509_EXTENSION *ex = sk_X509_EXTENSION_value(cert_exts, i); + ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex); + + if (OBJ_cmp(obj, skid) != 0 && OBJ_cmp(obj, akid) != 0 + && !sk_X509_EXTENSION_push(exts, ex)) + goto err; + } + + if (sk_X509_EXTENSION_num(exts) > 0) { + if (ext_copy != EXT_COPY_UNSET && ext_copy != EXT_COPY_NONE + && !X509_REQ_add_extensions(req, exts)) { + BIO_printf(bio_err, "Error copying extensions from certificate\n"); + goto err; + } + } + sk_X509_EXTENSION_free(exts); + return req; + + err: + sk_X509_EXTENSION_free(exts); + X509_REQ_free(req); + return NULL; +} + +static int self_signed(X509_STORE *ctx, X509 *cert) +{ + X509_STORE_CTX *xsc = X509_STORE_CTX_new(); + int ret = 0; + + if (xsc == NULL || !X509_STORE_CTX_init(xsc, ctx, cert, NULL)) { + BIO_printf(bio_err, "Error initialising X509 store\n"); + } else { + X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE); + ret = X509_verify_cert(xsc) > 0; + } + X509_STORE_CTX_free(xsc); + return ret; +} + int x509_main(int argc, char **argv) { ASN1_INTEGER *sno = NULL; ASN1_OBJECT *objtmp = NULL; BIO *out = NULL; CONF *extconf = NULL; - EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL; + int ext_copy = EXT_COPY_UNSET; + X509V3_CTX ext_ctx; + EVP_PKEY *privkey = NULL, *CAkey = NULL, *pubkey = NULL; + EVP_PKEY *pkey; + int newcert = 0; + char *subj = NULL, *digest = NULL; + X509_NAME *fsubj = NULL; + const unsigned long chtype = MBSTRING_ASC; + const int multirdn = 1; STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; - STACK_OF(OPENSSL_STRING) *sigopts = NULL; - X509 *x = NULL, *xca = NULL; + STACK_OF(OPENSSL_STRING) *sigopts = NULL, *vfyopts = NULL; + X509 *x = NULL, *xca = NULL, *issuer_cert; X509_REQ *req = NULL, *rq = NULL; X509_STORE *ctx = NULL; - const EVP_MD *digest = NULL; - char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL; - char *checkhost = NULL, *checkemail = NULL, *checkip = NULL, *exts = NULL; + char *CAkeyfile = NULL, *CAserial = NULL, *pubkeyfile = NULL, *alias = NULL; + char *checkhost = NULL, *checkemail = NULL, *checkip = NULL; + char *ext_names = NULL; char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL; - char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL; + char *infile = NULL, *outfile = NULL, *privkeyfile = NULL, *CAfile = NULL; char *prog; - int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = 0; - int C = 0, CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM; + int days = UNSET_DAYS; /* not explicitly set */ + int x509toreq = 0, modulus = 0, print_pubkey = 0, pprint = 0; + int CAformat = FORMAT_UNDEF, CAkeyformat = FORMAT_UNDEF; + unsigned long dateopt = ASN1_DTFLGS_RFC822; int fingerprint = 0, reqfile = 0, checkend = 0; - int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; + int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, keyformat = FORMAT_UNDEF; int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0; - int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0; + int noout = 0, CA_createserial = 0, email = 0; int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0; - int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0; + int ret = 1, i, j, num = 0, badsig = 0, clrext = 0, nocert = 0; int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0, ext = 0; int enddate = 0; time_t checkoffset = 0; @@ -206,7 +315,7 @@ int x509_main(int argc, char **argv) ret = 0; goto end; case OPT_INFORM: - if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_IN: @@ -217,15 +326,15 @@ int x509_main(int argc, char **argv) goto opthelp; break; case OPT_KEYFORM: - if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyformat)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat)) goto opthelp; break; case OPT_CAFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAformat)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &CAformat)) goto opthelp; break; case OPT_CAKEYFORM: - if (!opt_format(opt_arg(), OPT_FMT_PDE, &CAkeyformat)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &CAkeyformat)) goto opthelp; break; case OPT_OUT: @@ -235,16 +344,40 @@ int x509_main(int argc, char **argv) reqfile = 1; break; + case OPT_DATEOPT: + if (!set_dateopt(&dateopt, opt_arg())) { + BIO_printf(bio_err, + "Invalid date format: %s\n", opt_arg()); + goto end; + } + break; + case OPT_COPY_EXTENSIONS: + if (!set_ext_copy(&ext_copy, opt_arg())) { + BIO_printf(bio_err, + "Invalid extension copy option: %s\n", opt_arg()); + goto end; + } + break; + case OPT_SIGOPT: if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) goto opthelp; break; - case OPT_DAYS: - if (preserve_dates) + case OPT_VFYOPT: + if (!vfyopts) + vfyopts = sk_OPENSSL_STRING_new_null(); + if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg())) goto opthelp; + break; + case OPT_DAYS: days = atoi(opt_arg()); + if (days < -1) { + BIO_printf(bio_err, "%s: -days parameter arg must be >= -1\n", + prog); + goto end; + } break; case OPT_PASSIN: passinarg = opt_arg(); @@ -256,16 +389,19 @@ int x509_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_EXTENSIONS: extsect = opt_arg(); break; + case OPT_KEY: case OPT_SIGNKEY: - keyfile = opt_arg(); - sign_flag = ++num; + privkeyfile = opt_arg(); break; case OPT_CA: CAfile = opt_arg(); - CA_flag = ++num; break; case OPT_CAKEY: CAkeyfile = opt_arg(); @@ -281,34 +417,35 @@ int x509_main(int argc, char **argv) if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL) goto opthelp; break; + case OPT_NEW: + newcert = 1; + break; case OPT_FORCE_PUBKEY: - fkeyfile = opt_arg(); + pubkeyfile = opt_arg(); + break; + case OPT_SUBJ: + subj = opt_arg(); break; case OPT_ADDTRUST: + if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL) + goto end; if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { - BIO_printf(bio_err, - "%s: Invalid trust object value %s\n", + BIO_printf(bio_err, "%s: Invalid trust object value %s\n", prog, opt_arg()); goto opthelp; } - if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL) - goto end; sk_ASN1_OBJECT_push(trust, objtmp); - objtmp = NULL; trustout = 1; break; case OPT_ADDREJECT: + if (reject == NULL && (reject = sk_ASN1_OBJECT_new_null()) == NULL) + goto end; if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { - BIO_printf(bio_err, - "%s: Invalid reject object value %s\n", + BIO_printf(bio_err, "%s: Invalid reject object value %s\n", prog, opt_arg()); goto opthelp; } - if (reject == NULL - && (reject = sk_ASN1_OBJECT_new_null()) == NULL) - goto end; sk_ASN1_OBJECT_push(reject, objtmp); - objtmp = NULL; trustout = 1; break; case OPT_SETALIAS: @@ -326,9 +463,6 @@ int x509_main(int argc, char **argv) case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; - case OPT_C: - C = ++num; - break; case OPT_EMAIL: email = ++num; break; @@ -345,10 +479,10 @@ int x509_main(int argc, char **argv) modulus = ++num; break; case OPT_PUBKEY: - pubkey = ++num; + print_pubkey = ++num; break; case OPT_X509TOREQ: - x509req = ++num; + x509toreq = 1; break; case OPT_TEXT: text = ++num; @@ -382,7 +516,7 @@ int x509_main(int argc, char **argv) break; case OPT_EXT: ext = ++num; - exts = opt_arg(); + ext_names = opt_arg(); break; case OPT_NOCERT: nocert = 1; @@ -430,12 +564,12 @@ int x509_main(int argc, char **argv) case OPT_CHECKEND: checkend = 1; { - intmax_t temp = 0; - if (!opt_imax(opt_arg(), &temp)) + ossl_intmax_t temp = 0; + if (!opt_intmax(opt_arg(), &temp)) goto opthelp; checkoffset = (time_t)temp; - if ((intmax_t)checkoffset != temp) { - BIO_printf(bio_err, "%s: checkend time out of range %s\n", + if ((ossl_intmax_t)checkoffset != temp) { + BIO_printf(bio_err, "%s: Checkend time out of range %s\n", prog, opt_arg()); goto opthelp; } @@ -451,48 +585,103 @@ int x509_main(int argc, char **argv) checkip = opt_arg(); break; case OPT_PRESERVE_DATES: - if (days != DEF_DAYS) - goto opthelp; preserve_dates = 1; break; case OPT_MD: - if (!opt_md(opt_unknown(), &digest)) - goto opthelp; + digest = opt_unknown(); + break; } } + + /* No extra arguments. */ argc = opt_num_rest(); - argv = opt_rest(); - if (argc != 0) { - BIO_printf(bio_err, "%s: Unknown parameter %s\n", prog, argv[0]); + if (argc != 0) goto opthelp; + + if (!app_RAND_load()) + goto end; + + if (preserve_dates && days != UNSET_DAYS) { + BIO_printf(bio_err, "Cannot use -preserve_dates with -days option\n"); + goto end; } + if (days == UNSET_DAYS) + days = DEFAULT_DAYS; if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } - if (!X509_STORE_set_default_paths(ctx)) { - ERR_print_errors(bio_err); + if (!X509_STORE_set_default_paths_ex(ctx, app_get0_libctx(), + app_get0_propq())) + goto end; + + if (newcert && infile != NULL) { + BIO_printf(bio_err, "The -in option cannot be used with -new\n"); + goto end; + } + if (newcert && reqfile) { + BIO_printf(bio_err, + "The -req option cannot be used with -new\n"); goto end; } + if (privkeyfile != NULL) { + privkey = load_key(privkeyfile, keyformat, 0, passin, e, "private key"); + if (privkey == NULL) + goto end; + } + if (pubkeyfile != NULL) { + if ((pubkey = load_pubkey(pubkeyfile, keyformat, 0, NULL, e, + "explicitly set public key")) == NULL) + goto end; + } - if (fkeyfile != NULL) { - fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key"); - if (fkey == NULL) + if (newcert) { + if (subj == NULL) { + BIO_printf(bio_err, + "The -new option requires a subject to be set using -subj\n"); goto end; + } + if (privkeyfile == NULL && pubkeyfile == NULL) { + BIO_printf(bio_err, + "The -new option requires using the -key or -force_pubkey option\n"); + goto end; + } } + if (subj != NULL + && (fsubj = parse_name(subj, chtype, multirdn, "subject")) == NULL) + goto end; - if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) { + if (CAkeyfile == NULL) CAkeyfile = CAfile; - } else if ((CA_flag) && (CAkeyfile == NULL)) { - BIO_printf(bio_err, - "need to specify a CAkey if using the CA command\n"); - goto end; + if (CAfile != NULL) { + if (privkeyfile != NULL) { + BIO_printf(bio_err, "Cannot use both -key/-signkey and -CA option\n"); + goto end; + } + } else { +#define WARN_NO_CA(opt) BIO_printf(bio_err, \ + "Warning: ignoring " opt " option since -CA option is not given\n"); + if (CAkeyfile != NULL) + WARN_NO_CA("-CAkey"); + if (CAkeyformat != FORMAT_UNDEF) + WARN_NO_CA("-CAkeyform"); + if (CAformat != FORMAT_UNDEF) + WARN_NO_CA("-CAform"); + if (CAserial != NULL) + WARN_NO_CA("-CAserial"); + if (CA_createserial) + WARN_NO_CA("-CAcreateserial"); } - if (extfile != NULL) { + if (extfile == NULL) { + if (extsect != NULL) + BIO_printf(bio_err, + "Warning: ignoring -extensions option without -extfile\n"); + } else { X509V3_CTX ctx2; + if ((extconf = app_load_config(extfile)) == NULL) goto end; if (extsect == NULL) { @@ -506,92 +695,79 @@ int x509_main(int argc, char **argv) X509V3_set_nconf(&ctx2, extconf); if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) { BIO_printf(bio_err, - "Error Loading extension section %s\n", extsect); - ERR_print_errors(bio_err); + "Error checking extension section %s\n", extsect); goto end; } } if (reqfile) { - EVP_PKEY *pkey; - BIO *in; - - if (!sign_flag && !CA_flag) { - BIO_printf(bio_err, "We need a private key to sign with\n"); + req = load_csr(infile, informat, "certificate request input"); + if (req == NULL) goto end; - } - in = bio_open_default(infile, 'r', informat); - if (in == NULL) - goto end; - req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); - BIO_free(in); - - if (req == NULL) { - ERR_print_errors(bio_err); - goto end; - } if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) { - BIO_printf(bio_err, "error unpacking public key\n"); + BIO_printf(bio_err, "Error unpacking public key from CSR\n"); goto end; } - i = X509_REQ_verify(req, pkey); - if (i < 0) { - BIO_printf(bio_err, "Signature verification error\n"); - ERR_print_errors(bio_err); + i = do_X509_REQ_verify(req, pkey, vfyopts); + if (i <= 0) { + BIO_printf(bio_err, i < 0 + ? "Error while verifying certificate request self-signature\n" + : "Certificate request self-signature did not match the contents\n"); goto end; } - if (i == 0) { + BIO_printf(bio_err, "Certificate request self-signature ok\n"); + + print_name(bio_err, "subject=", X509_REQ_get_subject_name(req)); + } else if (!x509toreq && ext_copy != EXT_COPY_UNSET) { + BIO_printf(bio_err, "Warning: ignoring -copy_extensions since neither -x509toreq nor -req is given\n"); + } + + if (reqfile || newcert) { + if (preserve_dates) BIO_printf(bio_err, - "Signature did not match the certificate request\n"); + "Warning: ignoring -preserve_dates option with -req or -new\n"); + preserve_dates = 0; + if (privkeyfile == NULL && CAkeyfile == NULL) { + BIO_printf(bio_err, + "We need a private key to sign with, use -key or -CAkey or -CA with private key\n"); goto end; - } else { - BIO_printf(bio_err, "Signature ok\n"); } - - print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), - get_nameopt()); - - if ((x = X509_new()) == NULL) + if ((x = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL) goto end; - - if (sno == NULL) { + if (CAfile == NULL && sno == NULL) { sno = ASN1_INTEGER_new(); if (sno == NULL || !rand_serial(NULL, sno)) goto end; - if (!X509_set_serialNumber(x, sno)) - goto end; - ASN1_INTEGER_free(sno); - sno = NULL; - } else if (!X509_set_serialNumber(x, sno)) { - goto end; } - - if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req))) - goto end; - if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req))) - goto end; - if (!set_cert_times(x, NULL, NULL, days)) - goto end; - - if (fkey != NULL) { - X509_set_pubkey(x, fkey); - } else { - pkey = X509_REQ_get0_pubkey(req); - X509_set_pubkey(x, pkey); + if (req != NULL && ext_copy != EXT_COPY_UNSET) { + if (clrext && ext_copy != EXT_COPY_NONE) { + BIO_printf(bio_err, "Must not use -clrext together with -copy_extensions\n"); + goto end; + } else if (!copy_extensions(x, req, ext_copy)) { + BIO_printf(bio_err, "Error copying extensions from request\n"); + goto end; + } } } else { - x = load_cert(infile, informat, "Certificate"); + x = load_cert_pass(infile, informat, 1, passin, "certificate"); + if (x == NULL) + goto end; } - - if (x == NULL) + if ((fsubj != NULL || req != NULL) + && !X509_set_subject_name(x, fsubj != NULL ? fsubj : + X509_REQ_get_subject_name(req))) goto end; - if (CA_flag) { - xca = load_cert(CAfile, CAformat, "CA Certificate"); + if ((pubkey != NULL || privkey != NULL || req != NULL) + && !X509_set_pubkey(x, pubkey != NULL ? pubkey : + privkey != NULL ? privkey : + X509_REQ_get0_pubkey(req))) + goto end; + + if (CAfile != NULL) { + xca = load_cert_pass(CAfile, CAformat, 1, passin, "CA certificate"); if (xca == NULL) goto end; - if (reqfile && !X509_set_issuer_name(x, X509_get_subject_name(xca))) - goto end; } out = bio_open_default(outfile, 'w', outformat); @@ -610,21 +786,120 @@ int x509_main(int argc, char **argv) X509_reject_clear(x); if (trust != NULL) { - for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) { - objtmp = sk_ASN1_OBJECT_value(trust, i); - X509_add1_trust_object(x, objtmp); - } - objtmp = NULL; + for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) + X509_add1_trust_object(x, sk_ASN1_OBJECT_value(trust, i)); } if (reject != NULL) { - for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) { - objtmp = sk_ASN1_OBJECT_value(reject, i); - X509_add1_reject_object(x, objtmp); + for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) + X509_add1_reject_object(x, sk_ASN1_OBJECT_value(reject, i)); + } + + if (clrext && ext_names != NULL) + BIO_printf(bio_err, "Warning: Ignoring -ext since -clrext is given\n"); + for (i = X509_get_ext_count(x) - 1; i >= 0; i--) { + X509_EXTENSION *ex = X509_get_ext(x, i); + const char *sn = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ex))); + + if (clrext || (ext_names != NULL && strstr(ext_names, sn) == NULL)) + X509_EXTENSION_free(X509_delete_ext(x, i)); + } + + issuer_cert = x; + if (CAfile != NULL) { + issuer_cert = xca; + if (sno == NULL) + sno = x509_load_serial(CAfile, CAserial, CA_createserial); + if (sno == NULL) + goto end; + if (!x509toreq && !reqfile && !newcert && !self_signed(ctx, x)) + goto end; + } + + if (sno != NULL && !X509_set_serialNumber(x, sno)) + goto end; + + if (reqfile || newcert || privkey != NULL || CAfile != NULL) { + if (!preserve_dates && !set_cert_times(x, NULL, NULL, days)) + goto end; + if (!X509_set_issuer_name(x, X509_get_subject_name(issuer_cert))) + goto end; + } + + X509V3_set_ctx(&ext_ctx, issuer_cert, x, NULL, NULL, X509V3_CTX_REPLACE); + /* prepare fallback for AKID, but only if issuer cert equals subject cert */ + if (CAfile == NULL) { + if (!X509V3_set_issuer_pkey(&ext_ctx, privkey)) + goto end; + } + if (extconf != NULL && !x509toreq) { + X509V3_set_nconf(&ext_ctx, extconf); + if (!X509V3_EXT_add_nconf(extconf, &ext_ctx, extsect, x)) { + BIO_printf(bio_err, + "Error adding extensions from section %s\n", extsect); + goto end; } - objtmp = NULL; } + /* At this point the contents of the certificate x have been finished. */ + + pkey = X509_get0_pubkey(x); + if ((print_pubkey != 0 || modulus != 0) && pkey == NULL) { + BIO_printf(bio_err, "Error getting public key\n"); + goto end; + } + + if (x509toreq) { /* also works in conjunction with -req */ + if (privkey == NULL) { + BIO_printf(bio_err, "Must specify request signing key using -key\n"); + goto end; + } + if (clrext && ext_copy != EXT_COPY_NONE) { + BIO_printf(bio_err, "Must not use -clrext together with -copy_extensions\n"); + goto end; + } + if ((rq = x509_to_req(x, ext_copy, ext_names)) == NULL) + goto end; + if (extconf != NULL) { + X509V3_set_nconf(&ext_ctx, extconf); + if (!X509V3_EXT_REQ_add_nconf(extconf, &ext_ctx, extsect, rq)) { + BIO_printf(bio_err, + "Error adding request extensions from section %s\n", extsect); + goto end; + } + } + if (!do_X509_REQ_sign(rq, privkey, digest, sigopts)) + goto end; + if (!noout) { + if (outformat == FORMAT_ASN1) { + X509_REQ_print_ex(out, rq, get_nameopt(), X509_FLAG_COMPAT); + i = i2d_X509_bio(out, x); + } else { + i = PEM_write_bio_X509_REQ(out, rq); + } + if (!i) { + BIO_printf(bio_err, + "Unable to write certificate request\n"); + goto end; + } + } + noout = 1; + } else if (privkey != NULL) { + if (!do_X509_sign(x, privkey, digest, sigopts, &ext_ctx)) + goto end; + } else if (CAfile != NULL) { + if ((CAkey = load_key(CAkeyfile, CAkeyformat, + 0, passin, e, "CA private key")) == NULL) + goto end; + if (!X509_check_private_key(xca, CAkey)) { + BIO_printf(bio_err, + "CA certificate and CA private key do not match\n"); + goto end; + } + + if (!do_X509_sign(x, CAkey, digest, sigopts, &ext_ctx)) + goto end; + } if (badsig) { const ASN1_BIT_STRING *signature; @@ -632,236 +907,133 @@ int x509_main(int argc, char **argv) corrupt_signature(signature); } - if (num) { - for (i = 1; i <= num; i++) { - if (issuer == i) { - print_name(out, "issuer=", X509_get_issuer_name(x), get_nameopt()); - } else if (subject == i) { - print_name(out, "subject=", - X509_get_subject_name(x), get_nameopt()); - } else if (serial == i) { - BIO_printf(out, "serial="); - i2a_ASN1_INTEGER(out, X509_get_serialNumber(x)); - BIO_printf(out, "\n"); - } else if (next_serial == i) { - ASN1_INTEGER *ser = X509_get_serialNumber(x); - BIGNUM *bnser = ASN1_INTEGER_to_BN(ser, NULL); - - if (!bnser) - goto end; - if (!BN_add_word(bnser, 1)) - goto end; - ser = BN_to_ASN1_INTEGER(bnser, NULL); - if (!ser) - goto end; + /* Process print options in the given order, as indicated by index i */ + for (i = 1; i <= num; i++) { + if (i == issuer) { + print_name(out, "issuer=", X509_get_issuer_name(x)); + } else if (i == subject) { + print_name(out, "subject=", X509_get_subject_name(x)); + } else if (i == serial) { + BIO_printf(out, "serial="); + i2a_ASN1_INTEGER(out, X509_get0_serialNumber(x)); + BIO_printf(out, "\n"); + } else if (i == next_serial) { + ASN1_INTEGER *ser; + BIGNUM *bnser = ASN1_INTEGER_to_BN(X509_get0_serialNumber(x), NULL); + + if (bnser == NULL) + goto end; + if (!BN_add_word(bnser, 1) + || (ser = BN_to_ASN1_INTEGER(bnser, NULL)) == NULL) { BN_free(bnser); - i2a_ASN1_INTEGER(out, ser); - ASN1_INTEGER_free(ser); - BIO_puts(out, "\n"); - } else if ((email == i) || (ocsp_uri == i)) { - int j; - STACK_OF(OPENSSL_STRING) *emlst; - if (email == i) - emlst = X509_get1_email(x); - else - emlst = X509_get1_ocsp(x); - for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) - BIO_printf(out, "%s\n", - sk_OPENSSL_STRING_value(emlst, j)); - X509_email_free(emlst); - } else if (aliasout == i) { - unsigned char *alstr; - alstr = X509_alias_get0(x, NULL); - if (alstr) - BIO_printf(out, "%s\n", alstr); - else - BIO_puts(out, "\n"); - } else if (subject_hash == i) { - BIO_printf(out, "%08lx\n", X509_subject_name_hash(x)); + goto end; } + BN_free(bnser); + i2a_ASN1_INTEGER(out, ser); + ASN1_INTEGER_free(ser); + BIO_puts(out, "\n"); + } else if (i == email || i == ocsp_uri) { + STACK_OF(OPENSSL_STRING) *emlst = + i == email ? X509_get1_email(x) : X509_get1_ocsp(x); + + for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) + BIO_printf(out, "%s\n", sk_OPENSSL_STRING_value(emlst, j)); + X509_email_free(emlst); + } else if (i == aliasout) { + unsigned char *alstr = X509_alias_get0(x, NULL); + + if (alstr) + BIO_printf(out, "%s\n", alstr); + else + BIO_puts(out, "\n"); + } else if (i == subject_hash) { + BIO_printf(out, "%08lx\n", X509_subject_name_hash(x)); #ifndef OPENSSL_NO_MD5 - else if (subject_hash_old == i) { - BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x)); - } + } else if (i == subject_hash_old) { + BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x)); #endif - else if (issuer_hash == i) { - BIO_printf(out, "%08lx\n", X509_issuer_name_hash(x)); - } + } else if (i == issuer_hash) { + BIO_printf(out, "%08lx\n", X509_issuer_name_hash(x)); #ifndef OPENSSL_NO_MD5 - else if (issuer_hash_old == i) { - BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x)); - } + } else if (i == issuer_hash_old) { + BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x)); #endif - else if (pprint == i) { - X509_PURPOSE *ptmp; - int j; - BIO_printf(out, "Certificate purposes:\n"); - for (j = 0; j < X509_PURPOSE_get_count(); j++) { - ptmp = X509_PURPOSE_get0(j); - purpose_print(out, x, ptmp); - } - } else if (modulus == i) { - EVP_PKEY *pkey; - - pkey = X509_get0_pubkey(x); - if (pkey == NULL) { - BIO_printf(bio_err, "Modulus=unavailable\n"); - ERR_print_errors(bio_err); - goto end; - } - BIO_printf(out, "Modulus="); -#ifndef OPENSSL_NO_RSA - if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { - const BIGNUM *n; - RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, NULL, NULL); - BN_print(out, n); - } else -#endif -#ifndef OPENSSL_NO_DSA - if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA) { - const BIGNUM *dsapub = NULL; - DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &dsapub, NULL); - BN_print(out, dsapub); - } else -#endif - { - BIO_printf(out, "Wrong Algorithm type"); - } - BIO_printf(out, "\n"); - } else if (pubkey == i) { - EVP_PKEY *pkey; - - pkey = X509_get0_pubkey(x); - if (pkey == NULL) { - BIO_printf(bio_err, "Error getting public key\n"); - ERR_print_errors(bio_err); - goto end; - } - PEM_write_bio_PUBKEY(out, pkey); - } else if (C == i) { - unsigned char *d; - char *m; - int len; - - print_name(out, "/*\n" - " * Subject: ", X509_get_subject_name(x), get_nameopt()); - print_name(out, " * Issuer: ", X509_get_issuer_name(x), get_nameopt()); - BIO_puts(out, " */\n"); - - len = i2d_X509(x, NULL); - m = app_malloc(len, "x509 name buffer"); - d = (unsigned char *)m; - len = i2d_X509_NAME(X509_get_subject_name(x), &d); - print_array(out, "the_subject_name", len, (unsigned char *)m); - d = (unsigned char *)m; - len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d); - print_array(out, "the_public_key", len, (unsigned char *)m); - d = (unsigned char *)m; - len = i2d_X509(x, &d); - print_array(out, "the_certificate", len, (unsigned char *)m); - OPENSSL_free(m); - } else if (text == i) { - X509_print_ex(out, x, get_nameopt(), certflag); - } else if (startdate == i) { - BIO_puts(out, "notBefore="); - ASN1_TIME_print(out, X509_get0_notBefore(x)); - BIO_puts(out, "\n"); - } else if (enddate == i) { - BIO_puts(out, "notAfter="); - ASN1_TIME_print(out, X509_get0_notAfter(x)); - BIO_puts(out, "\n"); - } else if (fingerprint == i) { - int j; - unsigned int n; - unsigned char md[EVP_MAX_MD_SIZE]; - const EVP_MD *fdig = digest; - - if (fdig == NULL) - fdig = EVP_sha1(); - - if (!X509_digest(x, fdig, md, &n)) { - BIO_printf(bio_err, "out of memory\n"); - goto end; - } - BIO_printf(out, "%s Fingerprint=", - OBJ_nid2sn(EVP_MD_type(fdig))); - for (j = 0; j < (int)n; j++) { - BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n) - ? '\n' : ':'); - } + } else if (i == pprint) { + BIO_printf(out, "Certificate purposes:\n"); + for (j = 0; j < X509_PURPOSE_get_count(); j++) + purpose_print(out, x, X509_PURPOSE_get0(j)); + } else if (i == modulus) { + BIO_printf(out, "Modulus="); + if (EVP_PKEY_is_a(pkey, "RSA") || EVP_PKEY_is_a(pkey, "RSA-PSS")) { + BIGNUM *n = NULL; + + /* Every RSA key has an 'n' */ + EVP_PKEY_get_bn_param(pkey, "n", &n); + BN_print(out, n); + BN_free(n); + } else if (EVP_PKEY_is_a(pkey, "DSA")) { + BIGNUM *dsapub = NULL; + + /* Every DSA key has a 'pub' */ + EVP_PKEY_get_bn_param(pkey, "pub", &dsapub); + BN_print(out, dsapub); + BN_free(dsapub); + } else { + BIO_printf(out, "No modulus for this public key type"); } - - /* should be in the library */ - else if ((sign_flag == i) && (x509req == 0)) { - BIO_printf(bio_err, "Getting Private key\n"); - if (Upkey == NULL) { - Upkey = load_key(keyfile, keyformat, 0, - passin, e, "Private key"); - if (Upkey == NULL) - goto end; - } - - if (!sign(x, Upkey, days, clrext, digest, extconf, extsect, preserve_dates)) - goto end; - } else if (CA_flag == i) { - BIO_printf(bio_err, "Getting CA Private Key\n"); - if (CAkeyfile != NULL) { - CApkey = load_key(CAkeyfile, CAkeyformat, - 0, passin, e, "CA Private Key"); - if (CApkey == NULL) - goto end; - } - - if (!x509_certify(ctx, CAfile, digest, x, xca, - CApkey, sigopts, - CAserial, CA_createserial, days, clrext, - extconf, extsect, sno, reqfile, preserve_dates)) - goto end; - } else if (x509req == i) { - EVP_PKEY *pk; - - BIO_printf(bio_err, "Getting request Private Key\n"); - if (keyfile == NULL) { - BIO_printf(bio_err, "no request key file specified\n"); - goto end; - } else { - pk = load_key(keyfile, keyformat, 0, - passin, e, "request key"); - if (pk == NULL) - goto end; - } - - BIO_printf(bio_err, "Generating certificate request\n"); - - rq = X509_to_X509_REQ(x, pk, digest); - EVP_PKEY_free(pk); - if (rq == NULL) { - ERR_print_errors(bio_err); - goto end; - } - if (!noout) { - X509_REQ_print_ex(out, rq, get_nameopt(), X509_FLAG_COMPAT); - PEM_write_bio_X509_REQ(out, rq); - } - noout = 1; - } else if (ocspid == i) { - X509_ocspid_print(out, x); - } else if (ext == i) { - print_x509v3_exts(out, x, exts); + BIO_printf(out, "\n"); + } else if (i == print_pubkey) { + PEM_write_bio_PUBKEY(out, pkey); + } else if (i == text) { + X509_print_ex(out, x, get_nameopt(), certflag); + } else if (i == startdate) { + BIO_puts(out, "notBefore="); + ASN1_TIME_print_ex(out, X509_get0_notBefore(x), dateopt); + BIO_puts(out, "\n"); + } else if (i == enddate) { + BIO_puts(out, "notAfter="); + ASN1_TIME_print_ex(out, X509_get0_notAfter(x), dateopt); + BIO_puts(out, "\n"); + } else if (i == fingerprint) { + unsigned int n; + unsigned char md[EVP_MAX_MD_SIZE]; + const char *fdigname = digest; + EVP_MD *fdig; + int digres; + + if (fdigname == NULL) + fdigname = "SHA1"; + + if ((fdig = EVP_MD_fetch(app_get0_libctx(), fdigname, + app_get0_propq())) == NULL) { + BIO_printf(bio_err, "Unknown digest\n"); + goto end; + } + digres = X509_digest(x, fdig, md, &n); + EVP_MD_free(fdig); + if (!digres) { + BIO_printf(bio_err, "Out of memory\n"); + goto end; } + + BIO_printf(out, "%s Fingerprint=", fdigname); + for (j = 0; j < (int)n; j++) + BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n) ? '\n' : ':'); + } else if (i == ocspid) { + X509_ocspid_print(out, x); + } else if (i == ext) { + print_x509v3_exts(out, x, ext_names); } } if (checkend) { time_t tcheck = time(NULL) + checkoffset; - if (X509_cmp_time(X509_get0_notAfter(x), &tcheck) < 0) { + ret = X509_cmp_time(X509_get0_notAfter(x), &tcheck) < 0; + if (ret) BIO_printf(out, "Certificate will expire\n"); - ret = 1; - } else { + else BIO_printf(out, "Certificate will not expire\n"); - ret = 0; - } goto end; } @@ -880,33 +1052,36 @@ int x509_main(int argc, char **argv) else i = PEM_write_bio_X509(out, x); } else { - BIO_printf(bio_err, "bad output format specified for outfile\n"); + BIO_printf(bio_err, "Bad output format specified for outfile\n"); goto end; } if (!i) { - BIO_printf(bio_err, "unable to write certificate\n"); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Unable to write certificate\n"); goto end; } ret = 0; + end: + if (ret != 0) + ERR_print_errors(bio_err); NCONF_free(extconf); BIO_free_all(out); X509_STORE_free(ctx); + X509_NAME_free(fsubj); X509_REQ_free(req); X509_free(x); X509_free(xca); - EVP_PKEY_free(Upkey); - EVP_PKEY_free(CApkey); - EVP_PKEY_free(fkey); + EVP_PKEY_free(privkey); + EVP_PKEY_free(CAkey); + EVP_PKEY_free(pubkey); sk_OPENSSL_STRING_free(sigopts); + sk_OPENSSL_STRING_free(vfyopts); X509_REQ_free(rq); ASN1_INTEGER_free(sno); sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); - ASN1_OBJECT_free(objtmp); release_engine(e); - OPENSSL_free(passin); + clear_free(passin); return ret; } @@ -934,7 +1109,7 @@ static ASN1_INTEGER *x509_load_serial(const char *CAfile, goto end; if (!BN_add_word(serial, 1)) { - BIO_printf(bio_err, "add_word failure\n"); + BIO_printf(bio_err, "Serial number increment failure\n"); goto end; } @@ -949,92 +1124,14 @@ static ASN1_INTEGER *x509_load_serial(const char *CAfile, return bs; } -static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest, - X509 *x, X509 *xca, EVP_PKEY *pkey, - STACK_OF(OPENSSL_STRING) *sigopts, - const char *serialfile, int create, - int days, int clrext, CONF *conf, const char *section, - ASN1_INTEGER *sno, int reqfile, int preserve_dates) -{ - int ret = 0; - ASN1_INTEGER *bs = NULL; - X509_STORE_CTX *xsc = NULL; - EVP_PKEY *upkey; - - upkey = X509_get0_pubkey(xca); - if (upkey == NULL) { - BIO_printf(bio_err, "Error obtaining CA X509 public key\n"); - goto end; - } - EVP_PKEY_copy_parameters(upkey, pkey); - - xsc = X509_STORE_CTX_new(); - if (xsc == NULL || !X509_STORE_CTX_init(xsc, ctx, x, NULL)) { - BIO_printf(bio_err, "Error initialising X509 store\n"); - goto end; - } - if (sno) - bs = sno; - else if ((bs = x509_load_serial(CAfile, serialfile, create)) == NULL) - goto end; - - /* - * NOTE: this certificate can/should be self signed, unless it was a - * certificate request in which case it is not. - */ - X509_STORE_CTX_set_cert(xsc, x); - X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE); - if (!reqfile && X509_verify_cert(xsc) <= 0) - goto end; - - if (!X509_check_private_key(xca, pkey)) { - BIO_printf(bio_err, - "CA certificate and CA private key do not match\n"); - goto end; - } - - if (!X509_set_issuer_name(x, X509_get_subject_name(xca))) - goto end; - if (!X509_set_serialNumber(x, bs)) - goto end; - - if (!preserve_dates && !set_cert_times(x, NULL, NULL, days)) - goto end; - - if (clrext) { - while (X509_get_ext_count(x) > 0) - X509_delete_ext(x, 0); - } - - if (conf != NULL) { - X509V3_CTX ctx2; - X509_set_version(x, 2); /* version 3 certificate */ - X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0); - X509V3_set_nconf(&ctx2, conf); - if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) - goto end; - } - - if (!do_X509_sign(x, pkey, digest, sigopts)) - goto end; - ret = 1; - end: - X509_STORE_CTX_free(xsc); - if (!ret) - ERR_print_errors(bio_err); - if (!sno) - ASN1_INTEGER_free(bs); - return ret; -} - static int callb(int ok, X509_STORE_CTX *ctx) { int err; X509 *err_cert; /* - * it is ok to use a self signed certificate This case will catch both - * the initial ok == 0 and the final ok == 1 calls to this function + * It is ok to use a self-signed certificate. This case will catch both + * the initial ok == 0 and the final ok == 1 calls to this function. */ err = X509_STORE_CTX_get_error(ctx); if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) @@ -1047,51 +1144,19 @@ static int callb(int ok, X509_STORE_CTX *ctx) */ if (ok) { BIO_printf(bio_err, - "error with certificate to be certified - should be self signed\n"); + "Error with certificate to be certified - should be self-signed\n"); return 0; } else { err_cert = X509_STORE_CTX_get_current_cert(ctx); - print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0); + print_name(bio_err, "subject=", X509_get_subject_name(err_cert)); BIO_printf(bio_err, - "error with certificate - error %d at depth %d\n%s\n", err, + "Error with certificate - error %d at depth %d\n%s\n", err, X509_STORE_CTX_get_error_depth(ctx), X509_verify_cert_error_string(err)); return 1; } } -/* self sign */ -static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, - const EVP_MD *digest, CONF *conf, const char *section, - int preserve_dates) -{ - - if (!X509_set_issuer_name(x, X509_get_subject_name(x))) - goto err; - if (!preserve_dates && !set_cert_times(x, NULL, NULL, days)) - goto err; - if (!X509_set_pubkey(x, pkey)) - goto err; - if (clrext) { - while (X509_get_ext_count(x) > 0) - X509_delete_ext(x, 0); - } - if (conf != NULL) { - X509V3_CTX ctx; - X509_set_version(x, 2); /* version 3 certificate */ - X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0); - X509V3_set_nconf(&ctx, conf); - if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) - goto err; - } - if (!X509_sign(x, pkey, digest)) - goto err; - return 1; - err: - ERR_print_errors(bio_err); - return 0; -} - static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt) { int id, i, idret; @@ -1150,7 +1215,7 @@ static int print_x509v3_exts(BIO *bio, X509 *x, const char *ext_names) exts = X509_get0_extensions(x); if ((num = sk_X509_EXTENSION_num(exts)) <= 0) { - BIO_printf(bio, "No extensions in certificate\n"); + BIO_printf(bio_err, "No extensions in certificate\n"); ret = 1; goto end; } diff --git a/crypto/openssl/appveyor.yml b/crypto/openssl/appveyor.yml index 6210391f204a..9bb6f04e0a44 100644 --- a/crypto/openssl/appveyor.yml +++ b/crypto/openssl/appveyor.yml @@ -1,5 +1,5 @@ image: - - Visual Studio 2017 + - Visual Studio 2017 platform: - x64 @@ -12,16 +12,23 @@ environment: configuration: - shared - - plain - minimal +for: + - + branches: + only: + - master + configuration: + - shared + - plain + - minimal + before_build: - ps: >- Install-Module VSSetup -Scope CurrentUser - ps: >- Get-VSSetupInstance -All - - ps: >- - gci env:* | sort-object name - ps: >- If ($env:Platform -Match "x86") { $env:VCVARS_PLATFORM="x86" @@ -32,47 +39,44 @@ before_build: } - ps: >- If ($env:Configuration -Match "shared") { - $env:SHARED="no-makedepend" + $env:CONFIG_OPTS="enable-fips" } ElseIf ($env:Configuration -Match "minimal") { - $env:SHARED="no-shared no-dso no-makedepend no-aria no-async no-autoload-config no-blake2 no-bf no-camellia no-cast no-chacha no-cmac no-cms no-comp no-ct no-des no-dgram no-dh no-dsa no-dtls no-ec2m no-engine no-filenames no-gost no-idea no-mdc2 no-md4 no-multiblock no-nextprotoneg no-ocsp no-ocb no-poly1305 no-psk no-rc2 no-rc4 no-rmd160 no-seed no-siphash no-sm2 no-sm3 no-sm4 no-srp no-srtp no-ssl3 no-ssl3-method no-ts no-ui-console no-whirlpool no-asm -DOPENSSL_SMALL_FOOTPRINT" + $env:CONFIG_OPTS="no-bulk no-asm -DOPENSSL_SMALL_FOOTPRINT" } Else { - $env:SHARED="no-shared no-makedepend" + $env:CONFIG_OPTS="no-fips no-shared" } - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" %VCVARS_PLATFORM% - mkdir _build - cd _build - - perl ..\Configure %TARGET% %SHARED% + - perl ..\Configure %TARGET% no-makedepend %CONFIG_OPTS% - perl configdata.pm --dump - cd .. - ps: >- - if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER` - -or (&git log -1 $env:APPVEYOR_PULL_REQUEST_HEAD_COMMIT | - Select-String "\[extended tests\]") ) { - $env:EXTENDED_TESTS="yes" + If ($env:BUILDONLY -or $env:MAKEVERBOSE) { + $env:NMAKE="nmake" + } Else { + $env:NMAKE="nmake /S" } + - ps: >- + gci env:* | sort-object name build_script: - cd _build - - ps: >- - If ($env:Configuration -Match "shared" -or $env:EXTENDED_TESTS) { - cmd /c "nmake build_all_generated 2>&1" - cmd /c "nmake PERL=no-perl 2>&1" - } + - "%NMAKE% build_all_generated" + - "%NMAKE% PERL=no-perl" - cd .. test_script: - cd _build - ps: >- - If ($env:Configuration -Match "shared" -or $env:EXTENDED_TESTS) { - if ($env:EXTENDED_TESTS) { - cmd /c "nmake test V=1 2>&1" - } Else { - cmd /c "nmake test V=1 TESTS=-test_fuzz 2>&1" - } + if ($env:Configuration -Match "plain") { + cmd /c "%NMAKE% test VERBOSE_FAILURE=yes 2>&1" + } Else { + cmd /c "%NMAKE% test VERBOSE_FAILURE=yes TESTS=-test_fuzz 2>&1" } - ps: >- - if ($env:EXTENDED_TESTS) { + if ($env:Configuration -Match "shared") { mkdir ..\_install - cmd /c "nmake install DESTDIR=..\_install 2>&1" + cmd /c "%NMAKE% install DESTDIR=..\_install 2>&1" } - cd .. diff --git a/crypto/openssl/build.info b/crypto/openssl/build.info index 05c9bdd19c56..5a8421623b97 100644 --- a/crypto/openssl/build.info +++ b/crypto/openssl/build.info @@ -1,13 +1,14 @@ -{- - our $sover = $config{shlib_version_number}; - our $sover_filename = $sover; - $sover_filename =~ s|\.|_|g - if $config{target} =~ /^mingw/ || $config{target} =~ /^VC-/; - $sover_filename = - sprintf "%02d%02d", split m|\.|, $config{shlib_version_number} - if $config{target} =~ /^vms/; - ""; --} +# Note that some of these directories are filtered in Configure. Look for +# %skipdir there for further explanations. + +SUBDIRS=crypto ssl apps util tools fuzz providers doc +IF[{- !$disabled{tests} -}] + SUBDIRS=test +ENDIF +IF[{- !$disabled{'deprecated-3.0'} -}] + SUBDIRS=engines +ENDIF + LIBS=libcrypto libssl INCLUDE[libcrypto]=. include INCLUDE[libssl]=. include @@ -15,89 +16,77 @@ DEPEND[libssl]=libcrypto # Empty DEPEND "indices" means the dependencies are expected to be built # unconditionally before anything else. -DEPEND[]=include/openssl/opensslconf.h include/crypto/bn_conf.h \ - include/crypto/dso_conf.h -DEPEND[include/openssl/opensslconf.h]=configdata.pm -GENERATE[include/openssl/opensslconf.h]=include/openssl/opensslconf.h.in -DEPEND[include/crypto/bn_conf.h]=configdata.pm +DEPEND[]=include/openssl/asn1.h \ + include/openssl/asn1t.h \ + include/openssl/bio.h \ + include/openssl/cmp.h \ + include/openssl/cms.h \ + include/openssl/conf.h \ + include/openssl/crmf.h \ + include/openssl/crypto.h \ + include/openssl/ct.h \ + include/openssl/err.h \ + include/openssl/ess.h \ + include/openssl/fipskey.h \ + include/openssl/lhash.h \ + include/openssl/opensslv.h \ + include/openssl/ocsp.h \ + include/openssl/pkcs12.h \ + include/openssl/pkcs7.h \ + include/openssl/safestack.h \ + include/openssl/srp.h \ + include/openssl/ssl.h \ + include/openssl/ui.h \ + include/openssl/x509.h \ + include/openssl/x509v3.h \ + include/openssl/x509_vfy.h \ + include/crypto/bn_conf.h include/crypto/dso_conf.h + +GENERATE[include/openssl/asn1.h]=include/openssl/asn1.h.in +GENERATE[include/openssl/asn1t.h]=include/openssl/asn1t.h.in +GENERATE[include/openssl/bio.h]=include/openssl/bio.h.in +GENERATE[include/openssl/cmp.h]=include/openssl/cmp.h.in +GENERATE[include/openssl/cms.h]=include/openssl/cms.h.in +GENERATE[include/openssl/conf.h]=include/openssl/conf.h.in +# include/openssl/configuration.h is generated by configdata.pm +# We still need this information for the FIPS module checksum, but the attribute +# 'skip' ensures that nothing is actually done with it. +GENERATE[include/openssl/configuration.h]{skip}=include/openssl/configuration.h.in +GENERATE[include/openssl/crmf.h]=include/openssl/crmf.h.in +GENERATE[include/openssl/crypto.h]=include/openssl/crypto.h.in +GENERATE[include/openssl/ct.h]=include/openssl/ct.h.in +GENERATE[include/openssl/err.h]=include/openssl/err.h.in +GENERATE[include/openssl/ess.h]=include/openssl/ess.h.in +GENERATE[include/openssl/fipskey.h]=include/openssl/fipskey.h.in +GENERATE[include/openssl/lhash.h]=include/openssl/lhash.h.in +GENERATE[include/openssl/ocsp.h]=include/openssl/ocsp.h.in +GENERATE[include/openssl/opensslv.h]=include/openssl/opensslv.h.in +GENERATE[include/openssl/pkcs12.h]=include/openssl/pkcs12.h.in +GENERATE[include/openssl/pkcs7.h]=include/openssl/pkcs7.h.in +GENERATE[include/openssl/safestack.h]=include/openssl/safestack.h.in +GENERATE[include/openssl/srp.h]=include/openssl/srp.h.in +GENERATE[include/openssl/ssl.h]=include/openssl/ssl.h.in +GENERATE[include/openssl/ui.h]=include/openssl/ui.h.in +GENERATE[include/openssl/x509.h]=include/openssl/x509.h.in +GENERATE[include/openssl/x509v3.h]=include/openssl/x509v3.h.in +GENERATE[include/openssl/x509_vfy.h]=include/openssl/x509_vfy.h.in GENERATE[include/crypto/bn_conf.h]=include/crypto/bn_conf.h.in -DEPEND[include/crypto/dso_conf.h]=configdata.pm GENERATE[include/crypto/dso_conf.h]=include/crypto/dso_conf.h.in IF[{- defined $target{shared_defflag} -}] - IF[{- $config{target} =~ /^mingw/ -}] - GENERATE[libcrypto.def]=util/mkdef.pl crypto 32 - DEPEND[libcrypto.def]=util/libcrypto.num - GENERATE[libssl.def]=util/mkdef.pl ssl 32 - DEPEND[libssl.def]=util/libssl.num - - SHARED_SOURCE[libcrypto]=libcrypto.def - SHARED_SOURCE[libssl]=libssl.def - ELSIF[{- $config{target} =~ /^aix/ -}] - GENERATE[libcrypto.map]=util/mkdef.pl crypto aix - DEPEND[libcrypto.map]=util/libcrypto.num - GENERATE[libssl.map]=util/mkdef.pl ssl aix - DEPEND[libssl.map]=util/libssl.num - - SHARED_SOURCE[libcrypto]=libcrypto.map - SHARED_SOURCE[libssl]=libssl.map - ELSE - GENERATE[libcrypto.map]=util/mkdef.pl crypto linux - DEPEND[libcrypto.map]=util/libcrypto.num - GENERATE[libssl.map]=util/mkdef.pl ssl linux - DEPEND[libssl.map]=util/libssl.num + SHARED_SOURCE[libcrypto]=libcrypto.ld + SHARED_SOURCE[libssl]=libssl.ld - SHARED_SOURCE[libcrypto]=libcrypto.map - SHARED_SOURCE[libssl]=libssl.map - ENDIF + GENERATE[libcrypto.ld]=util/libcrypto.num libcrypto + GENERATE[libssl.ld]=util/libssl.num libssl + DEPEND[libcrypto.ld libssl.ld]=configdata.pm util/perl/OpenSSL/Ordinals.pm ENDIF -# VMS and VC don't have parametrised .def / .symvec generation, so they get -# special treatment, since we know they do use these files -IF[{- $config{target} =~ /^VC-/ -}] - GENERATE[libcrypto.def]=util/mkdef.pl crypto 32 - DEPEND[libcrypto.def]=util/libcrypto.num - GENERATE[libssl.def]=util/mkdef.pl ssl 32 - DEPEND[libssl.def]=util/libssl.num - SHARED_SOURCE[libcrypto]=libcrypto.def - SHARED_SOURCE[libssl]=libssl.def -ELSIF[{- $config{target} =~ /^vms/ -}] - GENERATE[libcrypto.opt]=util/mkdef.pl crypto "VMS" - DEPEND[libcrypto.opt]=util/libcrypto.num - GENERATE[libssl.opt]=util/mkdef.pl ssl "VMS" - DEPEND[libssl.opt]=util/libssl.num - - SHARED_SOURCE[libcrypto]=libcrypto.opt - SHARED_SOURCE[libssl]=libssl.opt -ENDIF - -IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-)/ -}] +IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-|BC-)/ -}] GENERATE[libcrypto.rc]=util/mkrc.pl libcrypto GENERATE[libssl.rc]=util/mkrc.pl libssl + DEPEND[libcrypto.rc libssl.rc]=configdata.pm SHARED_SOURCE[libcrypto]=libcrypto.rc SHARED_SOURCE[libssl]=libssl.rc ENDIF - -IF[{- $config{target} =~ /^Cygwin/ -}] - SHARED_NAME[libcrypto]=cygcrypto-{- $sover_filename -} - SHARED_NAME[libssl]=cygssl-{- $sover_filename -} -ELSIF[{- $config{target} =~ /^mingw/ -}] - SHARED_NAME[libcrypto]=libcrypto-{- $sover_filename -}{- $config{target} eq "mingw64" ? "-x64" : "" -} - SHARED_NAME[libssl]=libssl-{- $sover_filename -}{- $config{target} eq "mingw64" ? "-x64" : "" -} -ELSIF[{- $config{target} =~ /^VC-/ -}] - SHARED_NAME[libcrypto]=libcrypto-{- $sover_filename -}{- $target{multilib} -} - SHARED_NAME[libssl]=libssl-{- $sover_filename -}{- $target{multilib} -} -ENDIF - -# VMS has a cultural standard where all libraries are prefixed. -# For OpenSSL, the choice is 'ossl$' (this prefix was claimed in a -# conversation with VSI, Tuesday January 26 2016) -# Also, it seems it's usual to have the pointer size the libraries -# were built for as part of the name. -IF[{- $config{target} =~ /^vms/ -}] - RENAME[libcrypto]=ossl$libcrypto{- $target{pointer_size} -} - RENAME[libssl]=ossl$libssl{- $target{pointer_size} -} - SHARED_NAME[libcrypto]=ossl$libcrypto{- $sover_filename -}_shr{- $target{pointer_size} -} - SHARED_NAME[libssl]=ossl$libssl{- $sover_filename -}_shr{- $target{pointer_size} -} -ENDIF diff --git a/crypto/openssl/config b/crypto/openssl/config index c7b035a0c57c..e194d4bde4f6 100755 --- a/crypto/openssl/config +++ b/crypto/openssl/config @@ -1,946 +1,10 @@ -#!/bin/sh -# Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. +#! /bin/sh +# Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 -# OpenSSL config: determine the operating system and run ./Configure -# Derived from minarch and GuessOS from Apache. -# -# Do "config -h" for usage information. -SUFFIX="" -DRYRUN="false" -VERBOSE="false" -EXE="" THERE=`dirname $0` - -# pick up any command line args to config -for i -do -case "$i" in --d*) options=$options" --debug";; --t*) DRYRUN="true" VERBOSE="true";; --v*) VERBOSE="true";; --h*) DRYRUN="true"; cat </dev/null` || MACHINE="unknown" -[ "$RELEASE" ] || RELEASE=`(uname -r) 2>/dev/null` || RELEASE="unknown" -[ "$SYSTEM" ] || SYSTEM=`(uname -s) 2>/dev/null` || SYSTEM="unknown" -[ "$BUILD" ] || VERSION=`(uname -v) 2>/dev/null` || VERSION="unknown" - - -# Now test for ISC and SCO, since it is has a braindamaged uname. -# -# We need to work around FreeBSD 1.1.5.1 -( -XREL=`uname -X 2>/dev/null | grep "^Release" | awk '{print $3}'` -if [ "x$XREL" != "x" ]; then - if [ -f /etc/kconfig ]; then - case "$XREL" in - 4.0|4.1) - echo "${MACHINE}-whatever-isc4"; exit 0 - ;; - esac - else - case "$XREL" in - 3.2v4.2) - echo "whatever-whatever-sco3"; exit 0 - ;; - 3.2v5.0*) - echo "whatever-whatever-sco5"; exit 0 - ;; - 4.2MP) - case "x${VERSION}" in - x2.0*) echo "whatever-whatever-unixware20"; exit 0 ;; - x2.1*) echo "whatever-whatever-unixware21"; exit 0 ;; - x2*) echo "whatever-whatever-unixware2"; exit 0 ;; - esac - ;; - 4.2) - echo "whatever-whatever-unixware1"; exit 0 - ;; - 5*) - case "x${VERSION}" in - # We hardcode i586 in place of ${MACHINE} for the - # following reason. The catch is that even though Pentium - # is minimum requirement for platforms in question, - # ${MACHINE} gets always assigned to i386. Now, problem - # with i386 is that it makes ./config pass 386 to - # ./Configure, which in turn makes make generate - # inefficient SHA-1 (for this moment) code. - x[678]*) echo "i586-sco-unixware7"; exit 0 ;; - esac - ;; - esac - fi -fi -# Now we simply scan though... In most cases, the SYSTEM info is enough -# -case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in - A/UX:*) - echo "m68k-apple-aux3"; exit 0 - ;; - - AIX:[3-9]:4:*) - echo "${MACHINE}-ibm-aix"; exit 0 - ;; - - AIX:*:[5-9]:*) - echo "${MACHINE}-ibm-aix"; exit 0 - ;; - - AIX:*) - echo "${MACHINE}-ibm-aix3"; exit 0 - ;; - - HI-UX:*) - echo "${MACHINE}-hi-hiux"; exit 0 - ;; - - HP-UX:*) - HPUXVER=`echo ${RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "$HPUXVER" in - 1[0-9].*) # HPUX 10 and 11 targets are unified - echo "${MACHINE}-hp-hpux1x"; exit 0 - ;; - *) - echo "${MACHINE}-hp-hpux"; exit 0 - ;; - esac - ;; - - IRIX:6.*) - echo "mips3-sgi-irix"; exit 0 - ;; - - IRIX64:*) - echo "mips4-sgi-irix64"; exit 0 - ;; - - Linux:[2-9].*) - echo "${MACHINE}-whatever-linux2"; exit 0 - ;; - - Linux:1.*) - echo "${MACHINE}-whatever-linux1"; exit 0 - ;; - - GNU*) - echo "hurd-x86"; exit 0; - ;; - - LynxOS:*) - echo "${MACHINE}-lynx-lynxos"; exit 0 - ;; - - BSD/OS:4.*) # BSD/OS always says 386 - echo "i486-whatever-bsdi4"; exit 0 - ;; - - BSD/386:*:*:*486*|BSD/OS:*:*:*:*486*) - case `/sbin/sysctl -n hw.model` in - Pentium*) - echo "i586-whatever-bsdi"; exit 0 - ;; - *) - echo "i386-whatever-bsdi"; exit 0 - ;; - esac; - ;; - - BSD/386:*|BSD/OS:*) - echo "${MACHINE}-whatever-bsdi"; exit 0 - ;; - - FreeBSD:*:*:*386*) - VERS=`echo ${RELEASE} | sed -e 's/[-(].*//'` - MACH=`sysctl -n hw.model` - ARCH='whatever' - case ${MACH} in - *386* ) MACH="i386" ;; - *486* ) MACH="i486" ;; - Pentium\ II*) MACH="i686" ;; - Pentium* ) MACH="i586" ;; - * ) MACH="$MACHINE" ;; - esac - case ${MACH} in - i[0-9]86 ) ARCH="pc" ;; - esac - echo "${MACH}-${ARCH}-freebsd${VERS}"; exit 0 - ;; - - DragonFly:*) - echo "${MACHINE}-whatever-dragonfly"; exit 0 - ;; - - FreeBSD:*) - echo "${MACHINE}-whatever-freebsd"; exit 0 - ;; - - Haiku:*) - echo "${MACHINE}-whatever-haiku"; exit 0 - ;; - - NetBSD:*:*:*386*) - echo "`(/usr/sbin/sysctl -n hw.model || /sbin/sysctl -n hw.model) | sed 's,.*\(.\)86-class.*,i\186,'`-whatever-netbsd"; exit 0 - ;; - - NetBSD:*) - echo "${MACHINE}-whatever-netbsd"; exit 0 - ;; - - OpenBSD:*) - echo "${MACHINE}-whatever-openbsd"; exit 0 - ;; - - OpenUNIX:*) - echo "${MACHINE}-unknown-OpenUNIX${VERSION}"; exit 0 - ;; - - OSF1:*:*:*alpha*) - OSFMAJOR=`echo ${RELEASE}| sed -e 's/^V\([0-9]*\)\..*$/\1/'` - case "$OSFMAJOR" in - 4|5) - echo "${MACHINE}-dec-tru64"; exit 0 - ;; - 1|2|3) - echo "${MACHINE}-dec-osf"; exit 0 - ;; - *) - echo "${MACHINE}-dec-osf"; exit 0 - ;; - esac - ;; - - Paragon*:*:*:*) - echo "i860-intel-osf1"; exit 0 - ;; - - Rhapsody:*) - echo "ppc-apple-rhapsody"; exit 0 - ;; - - Darwin:*) - case "$MACHINE" in - Power*) - echo "ppc-apple-darwin${VERSION}" - ;; - *) - echo "${MACHINE}-apple-darwin${VERSION}" - ;; - esac - exit 0 - ;; - - SunOS:5.*) - echo "${MACHINE}-whatever-solaris2"; exit 0 - ;; - - SunOS:*) - echo "${MACHINE}-sun-sunos4"; exit 0 - ;; - - UNIX_System_V:4.*:*) - echo "${MACHINE}-whatever-sysv4"; exit 0 - ;; - - VOS:*:*:i786) - echo "i386-stratus-vos"; exit 0 - ;; - - VOS:*:*:*) - echo "hppa1.1-stratus-vos"; exit 0 - ;; - - *:4*:R4*:m88k) - echo "${MACHINE}-whatever-sysv4"; exit 0 - ;; - - DYNIX/ptx:4*:*) - echo "${MACHINE}-whatever-sysv4"; exit 0 - ;; - - *:4.0:3.0:3[34]?? | *:4.0:3.0:3[34]??,*) - echo "i486-ncr-sysv4"; exit 0 - ;; - - ULTRIX:*) - echo "${MACHINE}-unknown-ultrix"; exit 0 - ;; - - POSIX-BC*) - echo "${MACHINE}-siemens-sysv4"; exit 0 # Here, $MACHINE == "BS2000" - ;; - - machten:*) - echo "${MACHINE}-tenon-${SYSTEM}"; exit 0; - ;; - - library:*) - echo "${MACHINE}-ncr-sysv4"; exit 0 - ;; - - ConvexOS:*:11.0:*) - echo "${MACHINE}-v11-${SYSTEM}"; exit 0; - ;; - - # The following combinations are supported - # MINGW64* on x86_64 => mingw64 - # MINGW32* on x86_64 => mingw - # MINGW32* on i?86 => mingw - # - # MINGW64* on i?86 isn't expected to work... - MINGW64*:*:*:x86_64) - echo "${MACHINE}-whatever-mingw64"; exit 0; - ;; - MINGW*) - echo "${MACHINE}-whatever-mingw"; exit 0; - ;; - CYGWIN*) - echo "${MACHINE}-pc-cygwin"; exit 0 - ;; - - vxworks*) - echo "${MACHINE}-whatever-vxworks"; exit 0; - ;; -esac - -# -# Ugg. These are all we can determine by what we know about -# the output of uname. Be more creative: -# - -# Do the Apollo stuff first. Here, we just simply assume -# that the existence of the /usr/apollo directory is proof -# enough -if [ -d /usr/apollo ]; then - echo "whatever-apollo-whatever" - exit 0 -fi - -# Now NeXT -ISNEXT=`hostinfo 2>/dev/null` -case "$ISNEXT" in - *'NeXT Mach 3.3'*) - echo "whatever-next-nextstep3.3"; exit 0 - ;; - *NeXT*) - echo "whatever-next-nextstep"; exit 0 - ;; -esac - -# At this point we gone through all the one's -# we know of: Punt - -echo "${MACHINE}-whatever-${SYSTEM}" -exit 0 -) 2>/dev/null | ( - -# --------------------------------------------------------------------------- -# this is where the translation occurs into SSLeay terms -# --------------------------------------------------------------------------- - -# Only set CC if not supplied already -if [ -z "$CROSS_COMPILE$CC" ]; then - GCCVER=`sh -c "gcc -dumpversion" 2>/dev/null` - if [ "$GCCVER" != "" ]; then - # then strip off whatever prefix egcs prepends the number with... - # Hopefully, this will work for any future prefixes as well. - GCCVER=`echo $GCCVER | LC_ALL=C sed 's/^[a-zA-Z]*\-//'` - # Since gcc 3.1 gcc --version behaviour has changed. gcc -dumpversion - # does give us what we want though, so we use that. We just just the - # major and minor version numbers. - # peak single digit before and after first dot, e.g. 2.95.1 gives 29 - GCCVER=`echo $GCCVER | sed 's/\([0-9]\)\.\([0-9]\).*/\1\2/'` - CC=gcc - else - CC=cc - fi -fi -GCCVER=${GCCVER:-0} -if [ "$SYSTEM" = "HP-UX" ];then - # By default gcc is a ILP32 compiler (with long long == 64). - GCC_BITS="32" - if [ $GCCVER -ge 30 ]; then - # PA64 support only came in with gcc 3.0.x. - # We check if the preprocessor symbol __LP64__ is defined... - if echo "__LP64__" | gcc -v -E -x c - 2>/dev/null | grep "^__LP64__" 2>&1 > /dev/null; then - : # __LP64__ has slipped through, it therefore is not defined - else - GCC_BITS="64" - fi - fi -fi -if [ "$SYSTEM" = "SunOS" ]; then - if [ $GCCVER -ge 30 ]; then - # 64-bit ABI isn't officially supported in gcc 3.0, but it appears - # to be working, at the very least 'make test' passes... - if gcc -v -E -x c /dev/null 2>&1 | grep __arch64__ > /dev/null; then - GCC_ARCH="-m64" - else - GCC_ARCH="-m32" - fi - fi - # check for WorkShop C, expected output is "cc: blah-blah C x.x" - CCVER=`(cc -V 2>&1) 2>/dev/null | \ - egrep -e '^cc: .* C [0-9]\.[0-9]' | \ - sed 's/.* C \([0-9]\)\.\([0-9]\).*/\1\2/'` - CCVER=${CCVER:-0} - if [ $MACHINE != i86pc -a $CCVER -gt 40 ]; then - CC=cc # overrides gcc!!! - if [ $CCVER -eq 50 ]; then - echo "WARNING! Detected WorkShop C 5.0. Do make sure you have" - echo " patch #107357-01 or later applied." - sleep 5 - fi - fi -fi - -if [ "${SYSTEM}" = "AIX" ]; then # favor vendor cc over gcc - (cc) 2>&1 | grep -iv "not found" > /dev/null && CC=cc -fi - -CCVER=${CCVER:-0} - -# read the output of the embedded GuessOS -read GUESSOS - -echo Operating system: $GUESSOS - -# now map the output into SSLeay terms ... really should hack into the -# script above so we end up with values in vars but that would take -# more time that I want to waste at the moment -case "$GUESSOS" in - uClinux*64*) - OUT=uClinux-dist64 - ;; - uClinux*) - OUT=uClinux-dist - ;; - mips3-sgi-irix) - OUT="irix-mips3-$CC" - ;; - mips4-sgi-irix64) - echo "WARNING! If you wish to build 64-bit library, then you have to" - echo " invoke '$THERE/Configure irix64-mips4-$CC' *manually*." - if [ "$DRYRUN" = "false" -a -t 1 ]; then - echo " You have about 5 seconds to press Ctrl-C to abort." - (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1 - fi - OUT="irix-mips3-$CC" - ;; - ppc-apple-rhapsody) OUT="rhapsody-ppc-cc" ;; - ppc-apple-darwin*) - ISA64=`(sysctl -n hw.optional.64bitops) 2>/dev/null` - if [ "$ISA64" = "1" -a -z "$KERNEL_BITS" ]; then - echo "WARNING! If you wish to build 64-bit library, then you have to" - echo " invoke '$THERE/Configure darwin64-ppc-cc' *manually*." - if [ "$DRYRUN" = "false" -a -t 1 ]; then - echo " You have about 5 seconds to press Ctrl-C to abort." - (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1 - fi - fi - if [ "$ISA64" = "1" -a "$KERNEL_BITS" = "64" ]; then - OUT="darwin64-ppc-cc" - else - OUT="darwin-ppc-cc" - fi ;; - i?86-apple-darwin*) - ISA64=`(sysctl -n hw.optional.x86_64) 2>/dev/null` - if [ "$ISA64" = "1" -a -z "$KERNEL_BITS" ]; then - echo "WARNING! If you wish to build 64-bit library, then you have to" - echo " invoke 'KERNEL_BITS=64 $THERE/config $options'." - if [ "$DRYRUN" = "false" -a -t 1 ]; then - echo " You have about 5 seconds to press Ctrl-C to abort." - (trap "stty `stty -g`; exit 1" 2; stty -icanon min 0 time 50; read waste; exit 0) <&1 || exit - fi - fi - if [ "$ISA64" = "1" -a "$KERNEL_BITS" = "64" ]; then - OUT="darwin64-x86_64-cc" - else - OUT="darwin-i386-cc" - fi ;; - x86_64-apple-darwin*) - if [ "$KERNEL_BITS" = "32" ]; then - OUT="darwin-i386-cc" - else - OUT="darwin64-x86_64-cc" - fi ;; - $MACHINE-apple-darwin*) - OUT="darwin64-$MACHINE-cc" - ;; - armv6+7-*-iphoneos) - __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 ${MACHINE}" - __CNF_CXXFLAGS="$__CNF_CXXFLAGS -arch ${MACHINE}" - OUT="iphoneos-cross" ;; - arm64-*-iphoneos|*-*-ios64) - OUT="ios64-cross" ;; - alpha-*-linux2) - ISA=`awk '/cpu model/{print$4;exit(0);}' /proc/cpuinfo` - OUT="linux-alpha-$CC" - if [ "$CC" = "gcc" ]; then - case ${ISA:-generic} in - EV5|EV45) __CNF_CFLAGS="$__CNF_CFLAGS -mcpu=ev5" - __CNF_CXXFLAGS="$__CNF_CFLAGS -mcpu=ev5";; - EV56|PCA56) __CNF_CFLAGS="$__CNF_CFLAGS -mcpu=ev56" - __CNF_CXXFLAGS="$__CNF_CXXFLAGS -mcpu=ev56";; - *) __CNF_CFLAGS="$__CNF_CFLAGS -mcpu=ev6" - __CNF_CXXFLAGS="$__CNF_CXXFLAGS -mcpu=ev6";; - esac - fi - ;; - ppc64-*-linux2) - if [ -z "$KERNEL_BITS" ]; then - echo "WARNING! If you wish to build 64-bit library, then you have to" - echo " invoke '$THERE/Configure linux-ppc64' *manually*." - if [ "$DRYRUN" = "false" -a -t 1 ]; then - echo " You have about 5 seconds to press Ctrl-C to abort." - (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1 - fi - fi - if [ "$KERNEL_BITS" = "64" ]; then - OUT="linux-ppc64" - else - OUT="linux-ppc" - if (echo "__LP64__" | gcc -E -x c - 2>/dev/null | grep "^__LP64__" 2>&1 > /dev/null); then - :; - else - __CNF_CFLAGS="$__CNF_CFLAGS -m32" - __CNF_CXXFLAGS="$__CNF_CXXFLAGS -m32" - fi - fi - ;; - ppc64le-*-linux2) OUT="linux-ppc64le" ;; - ppc-*-linux2) OUT="linux-ppc" ;; - mips64*-*-linux2) - echo "WARNING! If you wish to build 64-bit library, then you have to" - echo " invoke '$THERE/Configure linux64-mips64' *manually*." - if [ "$DRYRUN" = "false" -a -t 1 ]; then - echo " You have about 5 seconds to press Ctrl-C to abort." - (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1 - fi - OUT="linux-mips64" - ;; - mips*-*-linux2) OUT="linux-mips32" ;; - ppc60x-*-vxworks*) OUT="vxworks-ppc60x" ;; - ppcgen-*-vxworks*) OUT="vxworks-ppcgen" ;; - pentium-*-vxworks*) OUT="vxworks-pentium" ;; - simlinux-*-vxworks*) OUT="vxworks-simlinux" ;; - mips-*-vxworks*) OUT="vxworks-mips";; - ia64-*-linux?) OUT="linux-ia64" ;; - sparc64-*-linux2) - echo "WARNING! If you *know* that your GNU C supports 64-bit/V9 ABI" - echo " and wish to build 64-bit library, then you have to" - echo " invoke '$THERE/Configure linux64-sparcv9' *manually*." - if [ "$DRYRUN" = "false" -a -t 1 ]; then - echo " You have about 5 seconds to press Ctrl-C to abort." - (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1 - fi - OUT="linux-sparcv9" ;; - sparc-*-linux2) - KARCH=`awk '/^type/{print$3;exit(0);}' /proc/cpuinfo` - case ${KARCH:-sun4} in - sun4u*) OUT="linux-sparcv9" ;; - sun4m) OUT="linux-sparcv8" ;; - sun4d) OUT="linux-sparcv8" ;; - *) OUT="linux-generic32"; - __CNF_CPPFLAGS="$__CNF_CPPFLAGS -DB_ENDIAN" ;; - esac ;; - parisc*-*-linux2) - # 64-bit builds under parisc64 linux are not supported and - # compiler is expected to generate 32-bit objects... - CPUARCH=`awk '/cpu family/{print substr($5,1,3); exit(0);}' /proc/cpuinfo` - CPUSCHEDULE=`awk '/^cpu.[ ]*: PA/{print substr($3,3); exit(0);}' /proc/cpuinfo` - - # ??TODO ?? Model transformations - # 0. CPU Architecture for the 1.1 processor has letter suffixes. We strip that off - # assuming no further arch. identification will ever be used by GCC. - # 1. I'm most concerned about whether is a 7300LC is closer to a 7100 versus a 7100LC. - # 2. The variant 64-bit processors cause concern should GCC support explicit schedulers - # for these chips in the future. - # PA7300LC -> 7100LC (1.1) - # PA8200 -> 8000 (2.0) - # PA8500 -> 8000 (2.0) - # PA8600 -> 8000 (2.0) - - CPUSCHEDULE=`echo $CPUSCHEDULE|sed -e 's/7300LC/7100LC/' -e 's/8.00/8000/'` - # Finish Model transformations - - __CNF_CPPFLAGS="$__CNF_CPPFLAGS -DB_ENDIAN" - __CNF_CFLAGS="$__CNF_CFLAGS -mschedule=$CPUSCHEDULE -march=$CPUARCH" - __CNF_CXXFLAGS="$__CNF_CXXFLAGS -mschedule=$CPUSCHEDULE -march=$CPUARCH" - OUT="linux-generic32" ;; - armv[1-3]*-*-linux2) OUT="linux-generic32" ;; - armv[7-9]*-*-linux2) OUT="linux-armv4" - __CNF_CFLAGS="$__CNF_CFLAGS -march=armv7-a" - __CNF_CXXFLAGS="$__CNF_CXXFLAGS -march=armv7-a" - ;; - arm*-*-linux2) OUT="linux-armv4" ;; - aarch64-*-linux2) OUT="linux-aarch64" ;; - sh*b-*-linux2) OUT="linux-generic32"; - __CNF_CPPFLAGS="$__CNF_CPPFLAGS -DB_ENDIAN" ;; - sh*-*-linux2) OUT="linux-generic32"; - __CNF_CPPFLAGS="$__CNF_CPPFLAGS -DL_ENDIAN" ;; - m68k*-*-linux2) OUT="linux-generic32"; - __CNF_CPPFLAGS="$__CNF_CPPFLAGS -DB_ENDIAN" ;; - s390-*-linux2) OUT="linux-generic32"; - __CNF_CPPFLAGS="$__CNF_CPPFLAGS -DB_ENDIAN" ;; - s390x-*-linux2) - # To be uncommented when glibc bug is fixed, see Configure... - #if egrep -e '^features.* highgprs' /proc/cpuinfo >/dev/null ; then - # echo "WARNING! If you wish to build \"highgprs\" 32-bit library, then you" - # echo " have to invoke './Configure linux32-s390x' *manually*." - # if [ "$DRYRUN" = "false" -a -t -1 ]; then - # echo " You have about 5 seconds to press Ctrl-C to abort." - # (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1 - # fi - #fi - OUT="linux64-s390x" - ;; - x86_64-*-linux?) - if $CC -dM -E -x c /dev/null 2>&1 | grep -q ILP32 > /dev/null; then - OUT="linux-x32" - else - OUT="linux-x86_64" - fi ;; - *86-*-linux2) - # On machines where the compiler understands -m32, prefer a - # config target that uses it - if $CC -m32 -E -x c /dev/null > /dev/null 2>&1; then - OUT="linux-x86" - else - OUT="linux-elf" - fi ;; - *86-*-linux1) OUT="linux-aout" ;; - *-*-linux?) OUT="linux-generic32" ;; - sun4[uv]*-*-solaris2) - OUT="solaris-sparcv9-$CC" - ISA64=`(isainfo) 2>/dev/null | grep sparcv9` - if [ "$ISA64" != "" -a "$KERNEL_BITS" = "" ]; then - if [ "$CC" = "cc" -a $CCVER -ge 50 ]; then - echo "WARNING! If you wish to build 64-bit library, then you have to" - echo " invoke '$THERE/Configure solaris64-sparcv9-cc' *manually*." - if [ "$DRYRUN" = "false" -a -t 1 ]; then - echo " You have about 5 seconds to press Ctrl-C to abort." - (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1 - fi - elif [ "$CC" = "gcc" -a "$GCC_ARCH" = "-m64" ]; then - # $GCC_ARCH denotes default ABI chosen by compiler driver - # (first one found on the $PATH). I assume that user - # expects certain consistency with the rest of his builds - # and therefore switch over to 64-bit. - OUT="solaris64-sparcv9-gcc" - echo "WARNING! If you wish to build 32-bit library, then you have to" - echo " invoke '$THERE/Configure solaris-sparcv9-gcc' *manually*." - if [ "$DRYRUN" = "false" -a -t 1 ]; then - echo " You have about 5 seconds to press Ctrl-C to abort." - (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1 - fi - elif [ "$GCC_ARCH" = "-m32" ]; then - echo "NOTICE! If you *know* that your GNU C supports 64-bit/V9 ABI" - echo " and wish to build 64-bit library, then you have to" - echo " invoke '$THERE/Configure solaris64-sparcv9-gcc' *manually*." - if [ "$DRYRUN" = "false" -a -t 1 ]; then - echo " You have about 5 seconds to press Ctrl-C to abort." - (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1 - fi - fi - fi - if [ "$ISA64" != "" -a "$KERNEL_BITS" = "64" ]; then - OUT="solaris64-sparcv9-$CC" - fi - ;; - sun4m-*-solaris2) OUT="solaris-sparcv8-$CC" ;; - sun4d-*-solaris2) OUT="solaris-sparcv8-$CC" ;; - sun4*-*-solaris2) OUT="solaris-sparcv7-$CC" ;; - *86*-*-solaris2) - ISA64=`(isainfo) 2>/dev/null | grep amd64` - if [ "$ISA64" != "" -a ${KERNEL_BITS:-64} -eq 64 ]; then - OUT="solaris64-x86_64-$CC" - else - OUT="solaris-x86-$CC" - if [ `uname -r | sed -e 's/5\.//'` -lt 10 ]; then - options="$options no-sse2" - fi - fi - ;; - *-*-sunos4) OUT="sunos-$CC" ;; - - *86*-*-bsdi4) OUT="BSD-x86-elf"; options="$options no-sse2"; - __CNF_LDFLAGS="$__CNF_LDFLAGS -ldl" ;; - alpha*-*-*bsd*) OUT="BSD-generic64"; - __CNF_CPPFLAGS="$__CNF_CPPFLAGS -DL_ENDIAN" ;; - powerpc64-*-*bsd*) OUT="BSD-generic64"; - __CNF_CPPFLAGS="$__CNF_CPPFLAGS -DB_ENDIAN" ;; - riscv64-*-*bsd*) OUT="BSD-riscv64" ;; - sparc64-*-*bsd*) OUT="BSD-sparc64" ;; - ia64-*-*bsd*) OUT="BSD-ia64" ;; - x86_64-*-dragonfly*) OUT="BSD-x86_64" ;; - amd64-*-*bsd*) OUT="BSD-x86_64" ;; - arm64-*-*bsd*) OUT="BSD-aarch64" ;; - *86*-*-*bsd*) # mimic ld behaviour when it's looking for libc... - if [ -L /usr/lib/libc.so ]; then # [Free|Net]BSD - libc=/usr/lib/libc.so - else # OpenBSD - # ld searches for highest libc.so.* and so do we - libc=`(ls /usr/lib/libc.so.* /lib/libc.so.* | tail -1) 2>/dev/null` - fi - case "`(file -L $libc) 2>/dev/null`" in - *ELF*) OUT="BSD-x86-elf" ;; - *) OUT="BSD-x86"; options="$options no-sse2" ;; - esac ;; - *-*-*bsd*) OUT="BSD-generic32" ;; - - x86_64-*-haiku) OUT="haiku-x86_64" ;; - *-*-haiku) OUT="haiku-x86" ;; - - *-*-osf) OUT="osf1-alpha-cc" ;; - *-*-tru64) OUT="tru64-alpha-cc" ;; - *-*-[Uu]nix[Ww]are7) - if [ "$CC" = "gcc" ]; then - OUT="unixware-7-gcc" ; options="$options no-sse2" - else - OUT="unixware-7" ; options="$options no-sse2" - __CNF_CPPFLAGS="$__CNF_CPPFLAGS -D__i386__" - fi - ;; - *-*-[Uu]nix[Ww]are20*) OUT="unixware-2.0"; options="$options no-sse2 no-sha512" ;; - *-*-[Uu]nix[Ww]are21*) OUT="unixware-2.1"; options="$options no-sse2 no-sha512" ;; - *-*-vos) - options="$options no-threads no-shared no-asm no-dso" - EXE=".pm" - OUT="vos-$CC" ;; - BS2000-siemens-sysv4) OUT="BS2000-OSD" ;; - *-hpux1*) - if [ $CC = "gcc" -a $GCC_BITS = "64" ]; then - OUT="hpux64-parisc2-gcc" - fi - [ "$KERNEL_BITS" ] || KERNEL_BITS=`(getconf KERNEL_BITS) 2>/dev/null` - KERNEL_BITS=${KERNEL_BITS:-32} - CPU_VERSION=`(getconf CPU_VERSION) 2>/dev/null` - CPU_VERSION=${CPU_VERSION:-0} - # See for further info on CPU_VERSION. - if [ $CPU_VERSION -ge 768 ]; then # IA-64 CPU - if [ $KERNEL_BITS -eq 64 -a "$CC" = "cc" ]; then - OUT="hpux64-ia64-cc" - else - OUT="hpux-ia64-cc" - fi - elif [ $CPU_VERSION -ge 532 ]; then # PA-RISC 2.x CPU - # PA-RISC 2.0 is no longer supported as separate 32-bit - # target. This is compensated for by run-time detection - # in most critical assembly modules and taking advantage - # of 2.0 architecture in PA-RISC 1.1 build. - OUT=${OUT:-"hpux-parisc1_1-${CC}"} - if [ $KERNEL_BITS -eq 64 -a "$CC" = "cc" ]; then - echo "WARNING! If you wish to build 64-bit library then you have to" - echo " invoke '$THERE/Configure hpux64-parisc2-cc' *manually*." - if [ "$DRYRUN" = "false" -a -t 1 ]; then - echo " You have about 5 seconds to press Ctrl-C to abort." - (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1 - fi - fi - elif [ $CPU_VERSION -ge 528 ]; then # PA-RISC 1.1+ CPU - OUT="hpux-parisc1_1-${CC}" - elif [ $CPU_VERSION -ge 523 ]; then # PA-RISC 1.0 CPU - OUT="hpux-parisc-${CC}" - else # Motorola(?) CPU - OUT="hpux-$CC" - fi - __CNF_CPPFLAGS="$__CNF_CPPFLAGS -D_REENTRANT" ;; - *-hpux) OUT="hpux-parisc-$CC" ;; - *-aix) - [ "$KERNEL_BITS" ] || KERNEL_BITS=`(getconf KERNEL_BITMODE) 2>/dev/null` - KERNEL_BITS=${KERNEL_BITS:-32} - OBJECT_MODE=${OBJECT_MODE:-32} - if [ "$CC" = "gcc" ]; then - OUT="aix-gcc" - if [ $OBJECT_MODE -eq 64 ]; then - echo 'Your $OBJECT_MODE was found to be set to 64' - OUT="aix64-gcc" - fi - elif [ $OBJECT_MODE -eq 64 ]; then - echo 'Your $OBJECT_MODE was found to be set to 64' - OUT="aix64-cc" - else - OUT="aix-cc" - if [ $KERNEL_BITS -eq 64 ]; then - echo "WARNING! If you wish to build 64-bit kit, then you have to" - echo " invoke '$THERE/Configure aix64-cc' *manually*." - if [ "$DRYRUN" = "false" -a -t 1 ]; then - echo " You have ~5 seconds to press Ctrl-C to abort." - (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1 - fi - fi - fi - if (lsattr -E -O -l `lsdev -c processor|awk '{print$1;exit}'` | grep -i powerpc) >/dev/null 2>&1; then - : # this applies even to Power3 and later, as they return PowerPC_POWER[345] - else - options="$options no-asm" - fi - ;; - # these are all covered by the catchall below - i[3456]86-*-cygwin) OUT="Cygwin-x86" ;; - *-*-cygwin) OUT="Cygwin-${MACHINE}" ;; - x86-*-android|i?86-*-android) OUT="android-x86" ;; - armv[7-9]*-*-android) - OUT="android-armeabi" - __CNF_CFLAGS="$__CNF_CFLAGS -march=armv7-a" - __CNF_CXXFLAGS="$__CNF_CXXFLAGS -march=armv7-a";; - arm*-*-android) OUT="android-armeabi" ;; - *) OUT=`echo $GUESSOS | awk -F- '{print $3}'`;; -esac - -# NB: This atalla support has been superseded by the ENGINE support -# That contains its own header and definitions anyway. Support can -# be enabled or disabled on any supported platform without external -# headers, eg. by adding the "hw-atalla" switch to ./config or -# perl Configure -# -# See whether we can compile Atalla support -#if [ -f /usr/include/atasi.h ] -#then -# __CNF_CPPFLAGS="$__CNF_CPPFLAGS -DATALLA" -#fi - -if [ -n "$CONFIG_OPTIONS" ]; then - options="$options $CONFIG_OPTIONS" -fi - -# gcc < 2.8 does not support -march=ultrasparc -if [ "$OUT" = solaris-sparcv9-gcc -a $GCCVER -lt 28 ] -then - echo "WARNING! Falling down to 'solaris-sparcv8-gcc'." - echo " Upgrade to gcc-2.8 or later." - sleep 5 - OUT=solaris-sparcv8-gcc -fi -if [ "$OUT" = "linux-sparcv9" -a $GCCVER -lt 28 ] -then - echo "WARNING! Falling down to 'linux-sparcv8'." - echo " Upgrade to gcc-2.8 or later." - sleep 5 - OUT=linux-sparcv8 -fi - -case "$GUESSOS" in - i386-*) options="$options 386" ;; -esac - -for i in aes aria bf camellia cast des dh dsa ec hmac idea md2 md5 mdc2 rc2 rc4 rc5 ripemd rsa seed sha sm2 sm3 sm4 -do - if [ ! -d $THERE/crypto/$i ] - then - options="$options no-$i" - fi -done - -if [ -z "$OUT" ]; then - OUT="$CC" -fi - -if [ ".$PERL" = . ] ; then - for i in . `echo $PATH | sed 's/:/ /g'`; do - if [ -f "$i/perl5$EXE" ] ; then - PERL="$i/perl5$EXE" - break; - fi; - done -fi - -if [ ".$PERL" = . ] ; then - for i in . `echo $PATH | sed 's/:/ /g'`; do - if [ -f "$i/perl$EXE" ] ; then - if "$i/perl$EXE" -e 'exit($]<5.0)'; then - PERL="$i/perl$EXE" - break; - fi; - fi; - done -fi - -if [ ".$PERL" = . ] ; then - echo "You need Perl 5." - exit 1 -fi - -# run Configure to check to see if we need to specify the -# compiler for the platform ... in which case we add it on -# the end ... otherwise we leave it off - -$PERL $THERE/Configure LIST | grep "$OUT-$CC" > /dev/null -if [ $? = "0" ]; then - OUT="$OUT-$CC" -fi - -OUT="$OUT" - -if [ "$OUT" = "darwin64-x86_64-cc" ]; then - echo "WARNING! If you wish to build 32-bit libraries, then you have to" - echo " invoke 'KERNEL_BITS=32 $THERE/config $options'." -fi - -if $PERL $THERE/Configure LIST | grep "$OUT" > /dev/null; then - if [ "$VERBOSE" = "true" ]; then - echo /usr/bin/env \ - __CNF_CPPDEFINES="'$__CNF_CPPDEFINES'" \ - __CNF_CPPINCLUDES="'$__CNF_CPPINCLUDES'" \ - __CNF_CPPFLAGS="'$__CNF_CPPFLAGS'" \ - __CNF_CFLAGS="'$__CNF_CFLAGS'" \ - __CNF_CXXFLAGS="'$__CNF_CXXFLAGS'" \ - __CNF_LDFLAGS="'$__CNF_LDFLAGS'" \ - __CNF_LDLIBS="'$__CNF_LDLIBS'" \ - $PERL $THERE/Configure $OUT $options - fi - if [ "$DRYRUN" = "false" ]; then - # eval to make sure quoted options, possibly with spaces inside, - # are treated right - eval /usr/bin/env \ - __CNF_CPPDEFINES="'$__CNF_CPPDEFINES'" \ - __CNF_CPPINCLUDES="'$__CNF_CPPINCLUDES'" \ - __CNF_CPPFLAGS="'$__CNF_CPPFLAGS'" \ - __CNF_CFLAGS="'$__CNF_CFLAGS'" \ - __CNF_CXXFLAGS="'$__CNF_CXXFLAGS'" \ - __CNF_LDFLAGS="'$__CNF_LDFLAGS'" \ - __CNF_LDLIBS="'$__CNF_LDLIBS'" \ - $PERL $THERE/Configure $OUT $options - fi -else - echo "This system ($OUT) is not supported. See file INSTALL for details." - exit 1 -fi - -# Do not add anothing from here on, so we don't lose the Configure exit code -) +exec "$THERE/Configure" "$@" diff --git a/crypto/openssl/configdata.pm.in b/crypto/openssl/configdata.pm.in new file mode 100644 index 000000000000..04b901144f47 --- /dev/null +++ b/crypto/openssl/configdata.pm.in @@ -0,0 +1,487 @@ +#! {- $config{HASHBANGPERL} -} +# -*- mode: perl -*- +{- + # We must make sourcedir() return an absolute path, because configdata.pm + # may be loaded as a module from any script in any directory, making + # relative paths untrustable. Because the result is used with 'use lib', + # we must ensure that it returns a Unix style path. Mixing File::Spec + # and File::Spec::Unix does just that. + use File::Spec::Unix; + use File::Spec; + use Cwd qw(abs_path); + sub _fixup_path { + my $path = shift; + + # Make the path absolute at all times + $path = abs_path($path); + + if ($^O eq 'VMS') { + # Convert any path of the VMS form VOLUME:[DIR1.DIR2]FILE to the + # Unix form /VOLUME/DIR1/DIR2/FILE, which is what VMS perl supports + # for 'use lib'. + + # Start with spliting the native path + (my $vol, my $dirs, my $file) = File::Spec->splitpath($path); + my @dirs = File::Spec->splitdir($dirs); + + # Reassemble it as a Unix path + $vol =~ s|:$||; + $dirs = File::Spec::Unix->catdir('', $vol, @dirs); + $path = File::Spec::Unix->catpath('', $dirs, $file); + } + + return $path; + } + sub sourcedir { + return _fixup_path(File::Spec->catdir($config{sourcedir}, @_)) + } + sub sourcefile { + return _fixup_path(File::Spec->catfile($config{sourcedir}, @_)) + } + use lib sourcedir('util', 'perl'); + use OpenSSL::Util; +-} +package configdata; + +use strict; +use warnings; + +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw( + %config %target %disabled %withargs %unified_info + @disablables @disablables_int +); + +our %config = ({- dump_data(\%config, indent => 0); -}); +our %target = ({- dump_data(\%target, indent => 0); -}); +our @disablables = ({- dump_data(\@disablables, indent => 0) -}); +our @disablables_int = ({- dump_data(\@disablables_int, indent => 0) -}); +our %disabled = ({- dump_data(\%disabled, indent => 0); -}); +our %withargs = ({- dump_data(\%withargs, indent => 0); -}); +our %unified_info = ({- dump_data(\%unified_info, indent => 0); -}); + +# Unexported, only used by OpenSSL::Test::Utils::available_protocols() +our %available_protocols = ( + tls => [{- dump_data(\@tls, indent => 0) -}], + dtls => [{- dump_data(\@dtls, indent => 0) -}], +); + +# The following data is only used when this files is use as a script +my @makevars = ({- dump_data(\@makevars, indent => 0); -}); +my %disabled_info = ({- dump_data(\%disabled_info, indent => 0); -}); +my @user_crossable = qw( {- join (' ', @user_crossable) -} ); + +# If run directly, we can give some answers, and even reconfigure +unless (caller) { + use Getopt::Long; + use File::Spec::Functions; + use File::Basename; + use File::Compare qw(compare_text); + use File::Copy; + use Pod::Usage; + + use lib '{- sourcedir('util', 'perl') -}'; + use OpenSSL::fallback '{- sourcefile('external', 'perl', 'MODULES.txt') -}'; + + my $here = dirname($0); + + if (scalar @ARGV == 0) { + # With no arguments, re-create the build file + # We do that in two steps, where the first step emits perl + # snipets. + + my $buildfile = $config{build_file}; + my $buildfile_template = "$buildfile.in"; + my @autowarntext = ( + 'WARNING: do not edit!', + "Generated by configdata.pm from " + .join(", ", @{$config{build_file_templates}}), + "via $buildfile_template" + ); + my %gendata = ( + config => \%config, + target => \%target, + disabled => \%disabled, + withargs => \%withargs, + unified_info => \%unified_info, + autowarntext => \@autowarntext, + ); + + use lib '.'; + use lib '{- sourcedir('Configurations') -}'; + use gentemplate; + + open my $buildfile_template_fh, ">$buildfile_template" + or die "Trying to create $buildfile_template: $!"; + foreach (@{$config{build_file_templates}}) { + copy($_, $buildfile_template_fh) + or die "Trying to copy $_ into $buildfile_template: $!"; + } + gentemplate(output => $buildfile_template_fh, %gendata); + close $buildfile_template_fh; + print 'Created ',$buildfile_template,"\n"; + + use OpenSSL::Template; + + my $prepend = <<'_____'; +use File::Spec::Functions; +use lib '{- sourcedir('util', 'perl') -}'; +use lib '{- sourcedir('Configurations') -}'; +use lib '{- $config{builddir} -}'; +use platform; +_____ + + my $tmpl; + open BUILDFILE, ">$buildfile.new" + or die "Trying to create $buildfile.new: $!"; + $tmpl = OpenSSL::Template->new(TYPE => 'FILE', + SOURCE => $buildfile_template); + $tmpl->fill_in(FILENAME => $_, + OUTPUT => \*BUILDFILE, + HASH => \%gendata, + PREPEND => $prepend, + # To ensure that global variables and functions + # defined in one template stick around for the + # next, making them combinable + PACKAGE => 'OpenSSL::safe') + or die $Text::Template::ERROR; + close BUILDFILE; + rename("$buildfile.new", $buildfile) + or die "Trying to rename $buildfile.new to $buildfile: $!"; + print 'Created ',$buildfile,"\n"; + + my $configuration_h = + catfile('include', 'openssl', 'configuration.h'); + my $configuration_h_in = + catfile($config{sourcedir}, 'include', 'openssl', 'configuration.h.in'); + open CONFIGURATION_H, ">${configuration_h}.new" + or die "Trying to create ${configuration_h}.new: $!"; + $tmpl = OpenSSL::Template->new(TYPE => 'FILE', + SOURCE => $configuration_h_in); + $tmpl->fill_in(FILENAME => $_, + OUTPUT => \*CONFIGURATION_H, + HASH => \%gendata, + PREPEND => $prepend, + # To ensure that global variables and functions + # defined in one template stick around for the + # next, making them combinable + PACKAGE => 'OpenSSL::safe') + or die $Text::Template::ERROR; + close CONFIGURATION_H; + + # When using stat() on Windows, we can get it to perform better by + # avoid some data. This doesn't affect the mtime field, so we're not + # losing anything... + ${^WIN32_SLOPPY_STAT} = 1; + + my $update_configuration_h = 0; + if (-f $configuration_h) { + my $configuration_h_mtime = (stat($configuration_h))[9]; + my $configuration_h_in_mtime = (stat($configuration_h_in))[9]; + + # If configuration.h.in was updated after the last configuration.h, + # or if configuration.h.new differs configuration.h, we update + # configuration.h + if ($configuration_h_mtime < $configuration_h_in_mtime + || compare_text("${configuration_h}.new", $configuration_h) != 0) { + $update_configuration_h = 1; + } else { + # If nothing has changed, let's just drop the new one and + # pretend like nothing happened + unlink "${configuration_h}.new" + } + } else { + $update_configuration_h = 1; + } + + if ($update_configuration_h) { + rename("${configuration_h}.new", $configuration_h) + or die "Trying to rename ${configuration_h}.new to $configuration_h: $!"; + print 'Created ',$configuration_h,"\n"; + } + + exit(0); + } + + my $dump = undef; + my $cmdline = undef; + my $options = undef; + my $target = undef; + my $envvars = undef; + my $makevars = undef; + my $buildparams = undef; + my $reconf = undef; + my $verbose = undef; + my $query = undef; + my $help = undef; + my $man = undef; + GetOptions('dump|d' => \$dump, + 'command-line|c' => \$cmdline, + 'options|o' => \$options, + 'target|t' => \$target, + 'environment|e' => \$envvars, + 'make-variables|m' => \$makevars, + 'build-parameters|b' => \$buildparams, + 'reconfigure|reconf|r' => \$reconf, + 'verbose|v' => \$verbose, + 'query|q=s' => \$query, + 'help' => \$help, + 'man' => \$man) + or die "Errors in command line arguments\n"; + + # We allow extra arguments with --query. That allows constructs like + # this: + # ./configdata.pm --query 'get_sources(@ARGV)' file1 file2 file3 + if (!$query && scalar @ARGV > 0) { + print STDERR <<"_____"; +Unrecognised arguments. +For more information, do '$0 --help' +_____ + exit(2); + } + + if ($help) { + pod2usage(-exitval => 0, + -verbose => 1); + } + if ($man) { + pod2usage(-exitval => 0, + -verbose => 2); + } + if ($dump || $cmdline) { + print "\nCommand line (with current working directory = $here):\n\n"; + print ' ',join(' ', + $config{PERL}, + catfile($config{sourcedir}, 'Configure'), + @{$config{perlargv}}), "\n"; + print "\nPerl information:\n\n"; + print ' ',$config{perl_cmd},"\n"; + print ' ',$config{perl_version},' for ',$config{perl_archname},"\n"; + } + if ($dump || $options) { + my $longest = 0; + my $longest2 = 0; + foreach my $what (@disablables) { + $longest = length($what) if $longest < length($what); + $longest2 = length($disabled{$what}) + if $disabled{$what} && $longest2 < length($disabled{$what}); + } + print "\nEnabled features:\n\n"; + foreach my $what (@disablables) { + print " $what\n" unless $disabled{$what}; + } + print "\nDisabled features:\n\n"; + foreach my $what (@disablables) { + if ($disabled{$what}) { + print " $what", ' ' x ($longest - length($what) + 1), + "[$disabled{$what}]", ' ' x ($longest2 - length($disabled{$what}) + 1); + print $disabled_info{$what}->{macro} + if $disabled_info{$what}->{macro}; + print ' (skip ', + join(', ', @{$disabled_info{$what}->{skipped}}), + ')' + if $disabled_info{$what}->{skipped}; + print "\n"; + } + } + } + if ($dump || $target) { + print "\nConfig target attributes:\n\n"; + foreach (sort keys %target) { + next if $_ =~ m|^_| || $_ eq 'template'; + my $quotify = sub { + map { + if (defined $_) { + (my $x = $_) =~ s|([\\\$\@"])|\\$1|g; "\"$x\"" + } else { + "undef"; + } + } @_; + }; + print ' ', $_, ' => '; + if (ref($target{$_}) eq "ARRAY") { + print '[ ', join(', ', $quotify->(@{$target{$_}})), " ],\n"; + } else { + print $quotify->($target{$_}), ",\n" + } + } + } + if ($dump || $envvars) { + print "\nRecorded environment:\n\n"; + foreach (sort keys %{$config{perlenv}}) { + print ' ',$_,' = ',($config{perlenv}->{$_} || ''),"\n"; + } + } + if ($dump || $makevars) { + print "\nMakevars:\n\n"; + foreach my $var (@makevars) { + my $prefix = ''; + $prefix = $config{CROSS_COMPILE} + if grep { $var eq $_ } @user_crossable; + $prefix //= ''; + print ' ',$var,' ' x (16 - length $var),'= ', + (ref $config{$var} eq 'ARRAY' + ? join(' ', @{$config{$var}}) + : $prefix.$config{$var}), + "\n" + if defined $config{$var}; + } + + my @buildfile = ($config{builddir}, $config{build_file}); + unshift @buildfile, $here + unless file_name_is_absolute($config{builddir}); + my $buildfile = canonpath(catdir(@buildfile)); + print <<"_____"; + +NOTE: These variables only represent the configuration view. The build file +template may have processed these variables further, please have a look at the +build file for more exact data: + $buildfile +_____ + } + if ($dump || $buildparams) { + my @buildfile = ($config{builddir}, $config{build_file}); + unshift @buildfile, $here + unless file_name_is_absolute($config{builddir}); + print "\nbuild file:\n\n"; + print " ", canonpath(catfile(@buildfile)),"\n"; + + print "\nbuild file templates:\n\n"; + foreach (@{$config{build_file_templates}}) { + my @tmpl = ($_); + unshift @tmpl, $here + unless file_name_is_absolute($config{sourcedir}); + print ' ',canonpath(catfile(@tmpl)),"\n"; + } + } + if ($reconf) { + if ($verbose) { + print 'Reconfiguring with: ', join(' ',@{$config{perlargv}}), "\n"; + foreach (sort keys %{$config{perlenv}}) { + print ' ',$_,' = ',($config{perlenv}->{$_} || ""),"\n"; + } + } + + chdir $here; + exec $^X,catfile($config{sourcedir}, 'Configure'),'reconf'; + } + if ($query) { + use OpenSSL::Config::Query; + + my $confquery = OpenSSL::Config::Query->new(info => \%unified_info, + config => \%config); + my $result = eval "\$confquery->$query"; + + # We may need a result class with a printing function at some point. + # Until then, we assume that we get a scalar, or a list or a hash table + # with scalar values and simply print them in some orderly fashion. + if (ref $result eq 'ARRAY') { + print "$_\n" foreach @$result; + } elsif (ref $result eq 'HASH') { + print "$_ : \\\n ", join(" \\\n ", @{$result->{$_}}), "\n" + foreach sort keys %$result; + } elsif (ref $result eq 'SCALAR') { + print "$$result\n"; + } + } +} + +1; + +__END__ + +=head1 NAME + +configdata.pm - configuration data for OpenSSL builds + +=head1 SYNOPSIS + +Interactive: + + perl configdata.pm [options] + +As data bank module: + + use configdata; + +=head1 DESCRIPTION + +This module can be used in two modes, interactively and as a module containing +all the data recorded by OpenSSL's Configure script. + +When used interactively, simply run it as any perl script. +If run with no arguments, it will rebuild the build file (Makefile or +corresponding). +With at least one option, it will instead get the information you ask for, or +re-run the configuration process. +See L below for more information. + +When loaded as a module, you get a few databanks with useful information to +perform build related tasks. The databanks are: + + %config Configured things. + %target The OpenSSL config target with all inheritances + resolved. + %disabled The features that are disabled. + @disablables The list of features that can be disabled. + %withargs All data given through --with-THING options. + %unified_info All information that was computed from the build.info + files. + +=head1 OPTIONS + +=over 4 + +=item B<--help> + +Print a brief help message and exit. + +=item B<--man> + +Print the manual page and exit. + +=item B<--dump> | B<-d> + +Print all relevant configuration data. This is equivalent to B<--command-line> +B<--options> B<--target> B<--environment> B<--make-variables> +B<--build-parameters>. + +=item B<--command-line> | B<-c> + +Print the current configuration command line. + +=item B<--options> | B<-o> + +Print the features, both enabled and disabled, and display defined macro and +skipped directories where applicable. + +=item B<--target> | B<-t> + +Print the config attributes for this config target. + +=item B<--environment> | B<-e> + +Print the environment variables and their values at the time of configuration. + +=item B<--make-variables> | B<-m> + +Print the main make variables generated in the current configuration + +=item B<--build-parameters> | B<-b> + +Print the build parameters, i.e. build file and build file templates. + +=item B<--reconfigure> | B<--reconf> | B<-r> + +Re-run the configuration process. + +=item B<--verbose> | B<-v> + +Verbose output. + +=back + +=cut + +EOF diff --git a/crypto/openssl/crypto/LPdir_unix.c b/crypto/openssl/crypto/LPdir_unix.c index bbbec0aee138..bc0e924e46a7 100644 --- a/crypto/openssl/crypto/LPdir_unix.c +++ b/crypto/openssl/crypto/LPdir_unix.c @@ -1,7 +1,7 @@ /* - * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -141,7 +141,8 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) p--; if (p > (*ctx)->entry_name && p[-1] == ';') p[-1] = '\0'; - if (strcasecmp((*ctx)->entry_name, (*ctx)->previous_entry_name) == 0) + if (OPENSSL_strcasecmp((*ctx)->entry_name, + (*ctx)->previous_entry_name) == 0) goto again; } #endif diff --git a/crypto/openssl/crypto/README-sparse_array.md b/crypto/openssl/crypto/README-sparse_array.md new file mode 100644 index 000000000000..bc2ff0cb8aee --- /dev/null +++ b/crypto/openssl/crypto/README-sparse_array.md @@ -0,0 +1,156 @@ +Sparse Arrays +============= + +The `sparse_array.c` file contains an implementation of a sparse array that +attempts to be both space and time efficient. + +The sparse array is represented using a tree structure. Each node in the +tree contains a block of pointers to either the user supplied leaf values or +to another node. + +There are a number of parameters used to define the block size: + + OPENSSL_SA_BLOCK_BITS Specifies the number of bits covered by each block + SA_BLOCK_MAX Specifies the number of pointers in each block + SA_BLOCK_MASK Specifies a bit mask to perform modulo block size + SA_BLOCK_MAX_LEVELS Indicates the maximum possible height of the tree + +These constants are inter-related: + + SA_BLOCK_MAX = 2 ^ OPENSSL_SA_BLOCK_BITS + SA_BLOCK_MASK = SA_BLOCK_MAX - 1 + SA_BLOCK_MAX_LEVELS = number of bits in size_t divided by + OPENSSL_SA_BLOCK_BITS rounded up to the next multiple + of OPENSSL_SA_BLOCK_BITS + +`OPENSSL_SA_BLOCK_BITS` can be defined at compile time and this overrides the +built in setting. + +As a space and performance optimisation, the height of the tree is usually +less than the maximum possible height. Only sufficient height is allocated to +accommodate the largest index added to the data structure. + +The largest index used to add a value to the array determines the tree height: + + +----------------------+---------------------+ + | Largest Added Index | Height of Tree | + +----------------------+---------------------+ + | SA_BLOCK_MAX - 1 | 1 | + | SA_BLOCK_MAX ^ 2 - 1 | 2 | + | SA_BLOCK_MAX ^ 3 - 1 | 3 | + | ... | ... | + | size_t max | SA_BLOCK_MAX_LEVELS | + +----------------------+---------------------+ + +The tree height is dynamically increased as needed based on additions. + +An empty tree is represented by a NULL root pointer. Inserting a value at +index 0 results in the allocation of a top level node full of null pointers +except for the single pointer to the user's data (N = SA_BLOCK_MAX for +brevity): + + +----+ + |Root| + |Node| + +-+--+ + | + | + | + v + +-+-+---+---+---+---+ + | 0 | 1 | 2 |...|N-1| + | |nil|nil|...|nil| + +-+-+---+---+---+---+ + | + | + | + v + +-+--+ + |User| + |Data| + +----+ + Index 0 + +Inserting at element 2N+1 creates a new root node and pushes down the old root +node. It then creates a second second level node to hold the pointer to the +user's new data: + + +----+ + |Root| + |Node| + +-+--+ + | + | + | + v + +-+-+---+---+---+---+ + | 0 | 1 | 2 |...|N-1| + | |nil| |...|nil| + +-+-+---+-+-+---+---+ + | | + | +------------------+ + | | + v v + +-+-+---+---+---+---+ +-+-+---+---+---+---+ + | 0 | 1 | 2 |...|N-1| | 0 | 1 | 2 |...|N-1| + |nil| |nil|...|nil| |nil| |nil|...|nil| + +-+-+---+---+---+---+ +---+-+-+---+---+---+ + | | + | | + | | + v v + +-+--+ +-+--+ + |User| |User| + |Data| |Data| + +----+ +----+ + Index 0 Index 2N+1 + +The nodes themselves are allocated in a sparse manner. Only nodes which exist +along a path from the root of the tree to an added leaf will be allocated. +The complexity is hidden and nodes are allocated on an as needed basis. +Because the data is expected to be sparse this doesn't result in a large waste +of space. + +Values can be removed from the sparse array by setting their index position to +NULL. The data structure does not attempt to reclaim nodes or reduce the +height of the tree on removal. For example, now setting index 0 to NULL would +result in: + + +----+ + |Root| + |Node| + +-+--+ + | + | + | + v + +-+-+---+---+---+---+ + | 0 | 1 | 2 |...|N-1| + | |nil| |...|nil| + +-+-+---+-+-+---+---+ + | | + | +------------------+ + | | + v v + +-+-+---+---+---+---+ +-+-+---+---+---+---+ + | 0 | 1 | 2 |...|N-1| | 0 | 1 | 2 |...|N-1| + |nil|nil|nil|...|nil| |nil| |nil|...|nil| + +---+---+---+---+---+ +---+-+-+---+---+---+ + | + | + | + v + +-+--+ + |User| + |Data| + +----+ + Index 2N+1 + +Accesses to elements in the sparse array take O(log n) time where n is the +largest element. The base of the logarithm is `SA_BLOCK_MAX`, so for moderately +small indices (e.g. NIDs), single level (constant time) access is achievable. +Space usage is O(minimum(m, n log(n)) where m is the number of elements in the +array. + +Note: sparse arrays only include pointers to types. +Thus, `SPARSE_ARRAY_OF(char)` can be used to store a string. diff --git a/crypto/openssl/crypto/aes/aes-586.S b/crypto/openssl/crypto/aes/aes-586.S new file mode 100644 index 000000000000..9ee3fc9a57e8 --- /dev/null +++ b/crypto/openssl/crypto/aes/aes-586.S @@ -0,0 +1,3320 @@ +.text +.type _x86_AES_encrypt_compact,@function +.align 16 +_x86_AES_encrypt_compact: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl %edi,20(%esp) + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + movl 240(%edi),%esi + leal -2(%esi,%esi,1),%esi + leal (%edi,%esi,8),%esi + movl %esi,24(%esp) + movl -128(%ebp),%edi + movl -96(%ebp),%esi + movl -64(%ebp),%edi + movl -32(%ebp),%esi + movl (%ebp),%edi + movl 32(%ebp),%esi + movl 64(%ebp),%edi + movl 96(%ebp),%esi +.align 16 +.L000loop: + movl %eax,%esi + andl $255,%esi + movzbl -128(%ebp,%esi,1),%esi + movzbl %bh,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %ecx,%edi + shrl $16,%edi + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $24,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl %esi,4(%esp) + + movl %ebx,%esi + andl $255,%esi + shrl $16,%ebx + movzbl -128(%ebp,%esi,1),%esi + movzbl %ch,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $16,%edi + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %eax,%edi + shrl $24,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl %esi,8(%esp) + + movl %ecx,%esi + andl $255,%esi + shrl $24,%ecx + movzbl -128(%ebp,%esi,1),%esi + movzbl %dh,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %eax,%edi + shrl $16,%edi + andl $255,%edx + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movzbl %bh,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + + andl $255,%edx + movzbl -128(%ebp,%edx,1),%edx + movzbl %ah,%eax + movzbl -128(%ebp,%eax,1),%eax + shll $8,%eax + xorl %eax,%edx + movl 4(%esp),%eax + andl $255,%ebx + movzbl -128(%ebp,%ebx,1),%ebx + shll $16,%ebx + xorl %ebx,%edx + movl 8(%esp),%ebx + movzbl -128(%ebp,%ecx,1),%ecx + shll $24,%ecx + xorl %ecx,%edx + movl %esi,%ecx + + movl $2155905152,%ebp + andl %ecx,%ebp + leal (%ecx,%ecx,1),%edi + movl %ebp,%esi + shrl $7,%ebp + andl $4278124286,%edi + subl %ebp,%esi + movl %ecx,%ebp + andl $454761243,%esi + rorl $16,%ebp + xorl %edi,%esi + movl %ecx,%edi + xorl %esi,%ecx + rorl $24,%edi + xorl %ebp,%esi + roll $24,%ecx + xorl %edi,%esi + movl $2155905152,%ebp + xorl %esi,%ecx + andl %edx,%ebp + leal (%edx,%edx,1),%edi + movl %ebp,%esi + shrl $7,%ebp + andl $4278124286,%edi + subl %ebp,%esi + movl %edx,%ebp + andl $454761243,%esi + rorl $16,%ebp + xorl %edi,%esi + movl %edx,%edi + xorl %esi,%edx + rorl $24,%edi + xorl %ebp,%esi + roll $24,%edx + xorl %edi,%esi + movl $2155905152,%ebp + xorl %esi,%edx + andl %eax,%ebp + leal (%eax,%eax,1),%edi + movl %ebp,%esi + shrl $7,%ebp + andl $4278124286,%edi + subl %ebp,%esi + movl %eax,%ebp + andl $454761243,%esi + rorl $16,%ebp + xorl %edi,%esi + movl %eax,%edi + xorl %esi,%eax + rorl $24,%edi + xorl %ebp,%esi + roll $24,%eax + xorl %edi,%esi + movl $2155905152,%ebp + xorl %esi,%eax + andl %ebx,%ebp + leal (%ebx,%ebx,1),%edi + movl %ebp,%esi + shrl $7,%ebp + andl $4278124286,%edi + subl %ebp,%esi + movl %ebx,%ebp + andl $454761243,%esi + rorl $16,%ebp + xorl %edi,%esi + movl %ebx,%edi + xorl %esi,%ebx + rorl $24,%edi + xorl %ebp,%esi + roll $24,%ebx + xorl %edi,%esi + xorl %esi,%ebx + movl 20(%esp),%edi + movl 28(%esp),%ebp + addl $16,%edi + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + cmpl 24(%esp),%edi + movl %edi,20(%esp) + jb .L000loop + movl %eax,%esi + andl $255,%esi + movzbl -128(%ebp,%esi,1),%esi + movzbl %bh,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %ecx,%edi + shrl $16,%edi + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $24,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl %esi,4(%esp) + + movl %ebx,%esi + andl $255,%esi + shrl $16,%ebx + movzbl -128(%ebp,%esi,1),%esi + movzbl %ch,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $16,%edi + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %eax,%edi + shrl $24,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl %esi,8(%esp) + + movl %ecx,%esi + andl $255,%esi + shrl $24,%ecx + movzbl -128(%ebp,%esi,1),%esi + movzbl %dh,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %eax,%edi + shrl $16,%edi + andl $255,%edx + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movzbl %bh,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + + movl 20(%esp),%edi + andl $255,%edx + movzbl -128(%ebp,%edx,1),%edx + movzbl %ah,%eax + movzbl -128(%ebp,%eax,1),%eax + shll $8,%eax + xorl %eax,%edx + movl 4(%esp),%eax + andl $255,%ebx + movzbl -128(%ebp,%ebx,1),%ebx + shll $16,%ebx + xorl %ebx,%edx + movl 8(%esp),%ebx + movzbl -128(%ebp,%ecx,1),%ecx + shll $24,%ecx + xorl %ecx,%edx + movl %esi,%ecx + + xorl 16(%edi),%eax + xorl 20(%edi),%ebx + xorl 24(%edi),%ecx + xorl 28(%edi),%edx + ret +.size _x86_AES_encrypt_compact,.-_x86_AES_encrypt_compact +.type _sse_AES_encrypt_compact,@function +.align 16 +_sse_AES_encrypt_compact: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pxor (%edi),%mm0 + pxor 8(%edi),%mm4 + movl 240(%edi),%esi + leal -2(%esi,%esi,1),%esi + leal (%edi,%esi,8),%esi + movl %esi,24(%esp) + movl $454761243,%eax + movl %eax,8(%esp) + movl %eax,12(%esp) + movl -128(%ebp),%eax + movl -96(%ebp),%ebx + movl -64(%ebp),%ecx + movl -32(%ebp),%edx + movl (%ebp),%eax + movl 32(%ebp),%ebx + movl 64(%ebp),%ecx + movl 96(%ebp),%edx +.align 16 +.L001loop: + pshufw $8,%mm0,%mm1 + pshufw $13,%mm4,%mm5 + movd %mm1,%eax + movd %mm5,%ebx + movl %edi,20(%esp) + movzbl %al,%esi + movzbl %ah,%edx + pshufw $13,%mm0,%mm2 + movzbl -128(%ebp,%esi,1),%ecx + movzbl %bl,%edi + movzbl -128(%ebp,%edx,1),%edx + shrl $16,%eax + shll $8,%edx + movzbl -128(%ebp,%edi,1),%esi + movzbl %bh,%edi + shll $16,%esi + pshufw $8,%mm4,%mm6 + orl %esi,%ecx + movzbl -128(%ebp,%edi,1),%esi + movzbl %ah,%edi + shll $24,%esi + shrl $16,%ebx + orl %esi,%edx + movzbl -128(%ebp,%edi,1),%esi + movzbl %bh,%edi + shll $8,%esi + orl %esi,%ecx + movzbl -128(%ebp,%edi,1),%esi + movzbl %al,%edi + shll $24,%esi + orl %esi,%ecx + movzbl -128(%ebp,%edi,1),%esi + movzbl %bl,%edi + movd %mm2,%eax + movd %ecx,%mm0 + movzbl -128(%ebp,%edi,1),%ecx + movzbl %ah,%edi + shll $16,%ecx + movd %mm6,%ebx + orl %esi,%ecx + movzbl -128(%ebp,%edi,1),%esi + movzbl %bh,%edi + shll $24,%esi + orl %esi,%ecx + movzbl -128(%ebp,%edi,1),%esi + movzbl %bl,%edi + shll $8,%esi + shrl $16,%ebx + orl %esi,%ecx + movzbl -128(%ebp,%edi,1),%esi + movzbl %al,%edi + shrl $16,%eax + movd %ecx,%mm1 + movzbl -128(%ebp,%edi,1),%ecx + movzbl %ah,%edi + shll $16,%ecx + andl $255,%eax + orl %esi,%ecx + punpckldq %mm1,%mm0 + movzbl -128(%ebp,%edi,1),%esi + movzbl %bh,%edi + shll $24,%esi + andl $255,%ebx + movzbl -128(%ebp,%eax,1),%eax + orl %esi,%ecx + shll $16,%eax + movzbl -128(%ebp,%edi,1),%esi + orl %eax,%edx + shll $8,%esi + movzbl -128(%ebp,%ebx,1),%ebx + orl %esi,%ecx + orl %ebx,%edx + movl 20(%esp),%edi + movd %ecx,%mm4 + movd %edx,%mm5 + punpckldq %mm5,%mm4 + addl $16,%edi + cmpl 24(%esp),%edi + ja .L002out + movq 8(%esp),%mm2 + pxor %mm3,%mm3 + pxor %mm7,%mm7 + movq %mm0,%mm1 + movq %mm4,%mm5 + pcmpgtb %mm0,%mm3 + pcmpgtb %mm4,%mm7 + pand %mm2,%mm3 + pand %mm2,%mm7 + pshufw $177,%mm0,%mm2 + pshufw $177,%mm4,%mm6 + paddb %mm0,%mm0 + paddb %mm4,%mm4 + pxor %mm3,%mm0 + pxor %mm7,%mm4 + pshufw $177,%mm2,%mm3 + pshufw $177,%mm6,%mm7 + pxor %mm0,%mm1 + pxor %mm4,%mm5 + pxor %mm2,%mm0 + pxor %mm6,%mm4 + movq %mm3,%mm2 + movq %mm7,%mm6 + pslld $8,%mm3 + pslld $8,%mm7 + psrld $24,%mm2 + psrld $24,%mm6 + pxor %mm3,%mm0 + pxor %mm7,%mm4 + pxor %mm2,%mm0 + pxor %mm6,%mm4 + movq %mm1,%mm3 + movq %mm5,%mm7 + movq (%edi),%mm2 + movq 8(%edi),%mm6 + psrld $8,%mm1 + psrld $8,%mm5 + movl -128(%ebp),%eax + pslld $24,%mm3 + pslld $24,%mm7 + movl -64(%ebp),%ebx + pxor %mm1,%mm0 + pxor %mm5,%mm4 + movl (%ebp),%ecx + pxor %mm3,%mm0 + pxor %mm7,%mm4 + movl 64(%ebp),%edx + pxor %mm2,%mm0 + pxor %mm6,%mm4 + jmp .L001loop +.align 16 +.L002out: + pxor (%edi),%mm0 + pxor 8(%edi),%mm4 + ret +.size _sse_AES_encrypt_compact,.-_sse_AES_encrypt_compact +.type _x86_AES_encrypt,@function +.align 16 +_x86_AES_encrypt: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl %edi,20(%esp) + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + movl 240(%edi),%esi + leal -2(%esi,%esi,1),%esi + leal (%edi,%esi,8),%esi + movl %esi,24(%esp) +.align 16 +.L003loop: + movl %eax,%esi + andl $255,%esi + movl (%ebp,%esi,8),%esi + movzbl %bh,%edi + xorl 3(%ebp,%edi,8),%esi + movl %ecx,%edi + shrl $16,%edi + andl $255,%edi + xorl 2(%ebp,%edi,8),%esi + movl %edx,%edi + shrl $24,%edi + xorl 1(%ebp,%edi,8),%esi + movl %esi,4(%esp) + + movl %ebx,%esi + andl $255,%esi + shrl $16,%ebx + movl (%ebp,%esi,8),%esi + movzbl %ch,%edi + xorl 3(%ebp,%edi,8),%esi + movl %edx,%edi + shrl $16,%edi + andl $255,%edi + xorl 2(%ebp,%edi,8),%esi + movl %eax,%edi + shrl $24,%edi + xorl 1(%ebp,%edi,8),%esi + movl %esi,8(%esp) + + movl %ecx,%esi + andl $255,%esi + shrl $24,%ecx + movl (%ebp,%esi,8),%esi + movzbl %dh,%edi + xorl 3(%ebp,%edi,8),%esi + movl %eax,%edi + shrl $16,%edi + andl $255,%edx + andl $255,%edi + xorl 2(%ebp,%edi,8),%esi + movzbl %bh,%edi + xorl 1(%ebp,%edi,8),%esi + + movl 20(%esp),%edi + movl (%ebp,%edx,8),%edx + movzbl %ah,%eax + xorl 3(%ebp,%eax,8),%edx + movl 4(%esp),%eax + andl $255,%ebx + xorl 2(%ebp,%ebx,8),%edx + movl 8(%esp),%ebx + xorl 1(%ebp,%ecx,8),%edx + movl %esi,%ecx + + addl $16,%edi + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + cmpl 24(%esp),%edi + movl %edi,20(%esp) + jb .L003loop + movl %eax,%esi + andl $255,%esi + movl 2(%ebp,%esi,8),%esi + andl $255,%esi + movzbl %bh,%edi + movl (%ebp,%edi,8),%edi + andl $65280,%edi + xorl %edi,%esi + movl %ecx,%edi + shrl $16,%edi + andl $255,%edi + movl (%ebp,%edi,8),%edi + andl $16711680,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $24,%edi + movl 2(%ebp,%edi,8),%edi + andl $4278190080,%edi + xorl %edi,%esi + movl %esi,4(%esp) + movl %ebx,%esi + andl $255,%esi + shrl $16,%ebx + movl 2(%ebp,%esi,8),%esi + andl $255,%esi + movzbl %ch,%edi + movl (%ebp,%edi,8),%edi + andl $65280,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $16,%edi + andl $255,%edi + movl (%ebp,%edi,8),%edi + andl $16711680,%edi + xorl %edi,%esi + movl %eax,%edi + shrl $24,%edi + movl 2(%ebp,%edi,8),%edi + andl $4278190080,%edi + xorl %edi,%esi + movl %esi,8(%esp) + movl %ecx,%esi + andl $255,%esi + shrl $24,%ecx + movl 2(%ebp,%esi,8),%esi + andl $255,%esi + movzbl %dh,%edi + movl (%ebp,%edi,8),%edi + andl $65280,%edi + xorl %edi,%esi + movl %eax,%edi + shrl $16,%edi + andl $255,%edx + andl $255,%edi + movl (%ebp,%edi,8),%edi + andl $16711680,%edi + xorl %edi,%esi + movzbl %bh,%edi + movl 2(%ebp,%edi,8),%edi + andl $4278190080,%edi + xorl %edi,%esi + movl 20(%esp),%edi + andl $255,%edx + movl 2(%ebp,%edx,8),%edx + andl $255,%edx + movzbl %ah,%eax + movl (%ebp,%eax,8),%eax + andl $65280,%eax + xorl %eax,%edx + movl 4(%esp),%eax + andl $255,%ebx + movl (%ebp,%ebx,8),%ebx + andl $16711680,%ebx + xorl %ebx,%edx + movl 8(%esp),%ebx + movl 2(%ebp,%ecx,8),%ecx + andl $4278190080,%ecx + xorl %ecx,%edx + movl %esi,%ecx + addl $16,%edi + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + ret +.align 64 +.LAES_Te: +.long 2774754246,2774754246 +.long 2222750968,2222750968 +.long 2574743534,2574743534 +.long 2373680118,2373680118 +.long 234025727,234025727 +.long 3177933782,3177933782 +.long 2976870366,2976870366 +.long 1422247313,1422247313 +.long 1345335392,1345335392 +.long 50397442,50397442 +.long 2842126286,2842126286 +.long 2099981142,2099981142 +.long 436141799,436141799 +.long 1658312629,1658312629 +.long 3870010189,3870010189 +.long 2591454956,2591454956 +.long 1170918031,1170918031 +.long 2642575903,2642575903 +.long 1086966153,1086966153 +.long 2273148410,2273148410 +.long 368769775,368769775 +.long 3948501426,3948501426 +.long 3376891790,3376891790 +.long 200339707,200339707 +.long 3970805057,3970805057 +.long 1742001331,1742001331 +.long 4255294047,4255294047 +.long 3937382213,3937382213 +.long 3214711843,3214711843 +.long 4154762323,4154762323 +.long 2524082916,2524082916 +.long 1539358875,1539358875 +.long 3266819957,3266819957 +.long 486407649,486407649 +.long 2928907069,2928907069 +.long 1780885068,1780885068 +.long 1513502316,1513502316 +.long 1094664062,1094664062 +.long 49805301,49805301 +.long 1338821763,1338821763 +.long 1546925160,1546925160 +.long 4104496465,4104496465 +.long 887481809,887481809 +.long 150073849,150073849 +.long 2473685474,2473685474 +.long 1943591083,1943591083 +.long 1395732834,1395732834 +.long 1058346282,1058346282 +.long 201589768,201589768 +.long 1388824469,1388824469 +.long 1696801606,1696801606 +.long 1589887901,1589887901 +.long 672667696,672667696 +.long 2711000631,2711000631 +.long 251987210,251987210 +.long 3046808111,3046808111 +.long 151455502,151455502 +.long 907153956,907153956 +.long 2608889883,2608889883 +.long 1038279391,1038279391 +.long 652995533,652995533 +.long 1764173646,1764173646 +.long 3451040383,3451040383 +.long 2675275242,2675275242 +.long 453576978,453576978 +.long 2659418909,2659418909 +.long 1949051992,1949051992 +.long 773462580,773462580 +.long 756751158,756751158 +.long 2993581788,2993581788 +.long 3998898868,3998898868 +.long 4221608027,4221608027 +.long 4132590244,4132590244 +.long 1295727478,1295727478 +.long 1641469623,1641469623 +.long 3467883389,3467883389 +.long 2066295122,2066295122 +.long 1055122397,1055122397 +.long 1898917726,1898917726 +.long 2542044179,2542044179 +.long 4115878822,4115878822 +.long 1758581177,1758581177 +.long 0,0 +.long 753790401,753790401 +.long 1612718144,1612718144 +.long 536673507,536673507 +.long 3367088505,3367088505 +.long 3982187446,3982187446 +.long 3194645204,3194645204 +.long 1187761037,1187761037 +.long 3653156455,3653156455 +.long 1262041458,1262041458 +.long 3729410708,3729410708 +.long 3561770136,3561770136 +.long 3898103984,3898103984 +.long 1255133061,1255133061 +.long 1808847035,1808847035 +.long 720367557,720367557 +.long 3853167183,3853167183 +.long 385612781,385612781 +.long 3309519750,3309519750 +.long 3612167578,3612167578 +.long 1429418854,1429418854 +.long 2491778321,2491778321 +.long 3477423498,3477423498 +.long 284817897,284817897 +.long 100794884,100794884 +.long 2172616702,2172616702 +.long 4031795360,4031795360 +.long 1144798328,1144798328 +.long 3131023141,3131023141 +.long 3819481163,3819481163 +.long 4082192802,4082192802 +.long 4272137053,4272137053 +.long 3225436288,3225436288 +.long 2324664069,2324664069 +.long 2912064063,2912064063 +.long 3164445985,3164445985 +.long 1211644016,1211644016 +.long 83228145,83228145 +.long 3753688163,3753688163 +.long 3249976951,3249976951 +.long 1977277103,1977277103 +.long 1663115586,1663115586 +.long 806359072,806359072 +.long 452984805,452984805 +.long 250868733,250868733 +.long 1842533055,1842533055 +.long 1288555905,1288555905 +.long 336333848,336333848 +.long 890442534,890442534 +.long 804056259,804056259 +.long 3781124030,3781124030 +.long 2727843637,2727843637 +.long 3427026056,3427026056 +.long 957814574,957814574 +.long 1472513171,1472513171 +.long 4071073621,4071073621 +.long 2189328124,2189328124 +.long 1195195770,1195195770 +.long 2892260552,2892260552 +.long 3881655738,3881655738 +.long 723065138,723065138 +.long 2507371494,2507371494 +.long 2690670784,2690670784 +.long 2558624025,2558624025 +.long 3511635870,3511635870 +.long 2145180835,2145180835 +.long 1713513028,1713513028 +.long 2116692564,2116692564 +.long 2878378043,2878378043 +.long 2206763019,2206763019 +.long 3393603212,3393603212 +.long 703524551,703524551 +.long 3552098411,3552098411 +.long 1007948840,1007948840 +.long 2044649127,2044649127 +.long 3797835452,3797835452 +.long 487262998,487262998 +.long 1994120109,1994120109 +.long 1004593371,1004593371 +.long 1446130276,1446130276 +.long 1312438900,1312438900 +.long 503974420,503974420 +.long 3679013266,3679013266 +.long 168166924,168166924 +.long 1814307912,1814307912 +.long 3831258296,3831258296 +.long 1573044895,1573044895 +.long 1859376061,1859376061 +.long 4021070915,4021070915 +.long 2791465668,2791465668 +.long 2828112185,2828112185 +.long 2761266481,2761266481 +.long 937747667,937747667 +.long 2339994098,2339994098 +.long 854058965,854058965 +.long 1137232011,1137232011 +.long 1496790894,1496790894 +.long 3077402074,3077402074 +.long 2358086913,2358086913 +.long 1691735473,1691735473 +.long 3528347292,3528347292 +.long 3769215305,3769215305 +.long 3027004632,3027004632 +.long 4199962284,4199962284 +.long 133494003,133494003 +.long 636152527,636152527 +.long 2942657994,2942657994 +.long 2390391540,2390391540 +.long 3920539207,3920539207 +.long 403179536,403179536 +.long 3585784431,3585784431 +.long 2289596656,2289596656 +.long 1864705354,1864705354 +.long 1915629148,1915629148 +.long 605822008,605822008 +.long 4054230615,4054230615 +.long 3350508659,3350508659 +.long 1371981463,1371981463 +.long 602466507,602466507 +.long 2094914977,2094914977 +.long 2624877800,2624877800 +.long 555687742,555687742 +.long 3712699286,3712699286 +.long 3703422305,3703422305 +.long 2257292045,2257292045 +.long 2240449039,2240449039 +.long 2423288032,2423288032 +.long 1111375484,1111375484 +.long 3300242801,3300242801 +.long 2858837708,2858837708 +.long 3628615824,3628615824 +.long 84083462,84083462 +.long 32962295,32962295 +.long 302911004,302911004 +.long 2741068226,2741068226 +.long 1597322602,1597322602 +.long 4183250862,4183250862 +.long 3501832553,3501832553 +.long 2441512471,2441512471 +.long 1489093017,1489093017 +.long 656219450,656219450 +.long 3114180135,3114180135 +.long 954327513,954327513 +.long 335083755,335083755 +.long 3013122091,3013122091 +.long 856756514,856756514 +.long 3144247762,3144247762 +.long 1893325225,1893325225 +.long 2307821063,2307821063 +.long 2811532339,2811532339 +.long 3063651117,3063651117 +.long 572399164,572399164 +.long 2458355477,2458355477 +.long 552200649,552200649 +.long 1238290055,1238290055 +.long 4283782570,4283782570 +.long 2015897680,2015897680 +.long 2061492133,2061492133 +.long 2408352771,2408352771 +.long 4171342169,4171342169 +.long 2156497161,2156497161 +.long 386731290,386731290 +.long 3669999461,3669999461 +.long 837215959,837215959 +.long 3326231172,3326231172 +.long 3093850320,3093850320 +.long 3275833730,3275833730 +.long 2962856233,2962856233 +.long 1999449434,1999449434 +.long 286199582,286199582 +.long 3417354363,3417354363 +.long 4233385128,4233385128 +.long 3602627437,3602627437 +.long 974525996,974525996 +.byte 99,124,119,123,242,107,111,197 +.byte 48,1,103,43,254,215,171,118 +.byte 202,130,201,125,250,89,71,240 +.byte 173,212,162,175,156,164,114,192 +.byte 183,253,147,38,54,63,247,204 +.byte 52,165,229,241,113,216,49,21 +.byte 4,199,35,195,24,150,5,154 +.byte 7,18,128,226,235,39,178,117 +.byte 9,131,44,26,27,110,90,160 +.byte 82,59,214,179,41,227,47,132 +.byte 83,209,0,237,32,252,177,91 +.byte 106,203,190,57,74,76,88,207 +.byte 208,239,170,251,67,77,51,133 +.byte 69,249,2,127,80,60,159,168 +.byte 81,163,64,143,146,157,56,245 +.byte 188,182,218,33,16,255,243,210 +.byte 205,12,19,236,95,151,68,23 +.byte 196,167,126,61,100,93,25,115 +.byte 96,129,79,220,34,42,144,136 +.byte 70,238,184,20,222,94,11,219 +.byte 224,50,58,10,73,6,36,92 +.byte 194,211,172,98,145,149,228,121 +.byte 231,200,55,109,141,213,78,169 +.byte 108,86,244,234,101,122,174,8 +.byte 186,120,37,46,28,166,180,198 +.byte 232,221,116,31,75,189,139,138 +.byte 112,62,181,102,72,3,246,14 +.byte 97,53,87,185,134,193,29,158 +.byte 225,248,152,17,105,217,142,148 +.byte 155,30,135,233,206,85,40,223 +.byte 140,161,137,13,191,230,66,104 +.byte 65,153,45,15,176,84,187,22 +.byte 99,124,119,123,242,107,111,197 +.byte 48,1,103,43,254,215,171,118 +.byte 202,130,201,125,250,89,71,240 +.byte 173,212,162,175,156,164,114,192 +.byte 183,253,147,38,54,63,247,204 +.byte 52,165,229,241,113,216,49,21 +.byte 4,199,35,195,24,150,5,154 +.byte 7,18,128,226,235,39,178,117 +.byte 9,131,44,26,27,110,90,160 +.byte 82,59,214,179,41,227,47,132 +.byte 83,209,0,237,32,252,177,91 +.byte 106,203,190,57,74,76,88,207 +.byte 208,239,170,251,67,77,51,133 +.byte 69,249,2,127,80,60,159,168 +.byte 81,163,64,143,146,157,56,245 +.byte 188,182,218,33,16,255,243,210 +.byte 205,12,19,236,95,151,68,23 +.byte 196,167,126,61,100,93,25,115 +.byte 96,129,79,220,34,42,144,136 +.byte 70,238,184,20,222,94,11,219 +.byte 224,50,58,10,73,6,36,92 +.byte 194,211,172,98,145,149,228,121 +.byte 231,200,55,109,141,213,78,169 +.byte 108,86,244,234,101,122,174,8 +.byte 186,120,37,46,28,166,180,198 +.byte 232,221,116,31,75,189,139,138 +.byte 112,62,181,102,72,3,246,14 +.byte 97,53,87,185,134,193,29,158 +.byte 225,248,152,17,105,217,142,148 +.byte 155,30,135,233,206,85,40,223 +.byte 140,161,137,13,191,230,66,104 +.byte 65,153,45,15,176,84,187,22 +.byte 99,124,119,123,242,107,111,197 +.byte 48,1,103,43,254,215,171,118 +.byte 202,130,201,125,250,89,71,240 +.byte 173,212,162,175,156,164,114,192 +.byte 183,253,147,38,54,63,247,204 +.byte 52,165,229,241,113,216,49,21 +.byte 4,199,35,195,24,150,5,154 +.byte 7,18,128,226,235,39,178,117 +.byte 9,131,44,26,27,110,90,160 +.byte 82,59,214,179,41,227,47,132 +.byte 83,209,0,237,32,252,177,91 +.byte 106,203,190,57,74,76,88,207 +.byte 208,239,170,251,67,77,51,133 +.byte 69,249,2,127,80,60,159,168 +.byte 81,163,64,143,146,157,56,245 +.byte 188,182,218,33,16,255,243,210 +.byte 205,12,19,236,95,151,68,23 +.byte 196,167,126,61,100,93,25,115 +.byte 96,129,79,220,34,42,144,136 +.byte 70,238,184,20,222,94,11,219 +.byte 224,50,58,10,73,6,36,92 +.byte 194,211,172,98,145,149,228,121 +.byte 231,200,55,109,141,213,78,169 +.byte 108,86,244,234,101,122,174,8 +.byte 186,120,37,46,28,166,180,198 +.byte 232,221,116,31,75,189,139,138 +.byte 112,62,181,102,72,3,246,14 +.byte 97,53,87,185,134,193,29,158 +.byte 225,248,152,17,105,217,142,148 +.byte 155,30,135,233,206,85,40,223 +.byte 140,161,137,13,191,230,66,104 +.byte 65,153,45,15,176,84,187,22 +.byte 99,124,119,123,242,107,111,197 +.byte 48,1,103,43,254,215,171,118 +.byte 202,130,201,125,250,89,71,240 +.byte 173,212,162,175,156,164,114,192 +.byte 183,253,147,38,54,63,247,204 +.byte 52,165,229,241,113,216,49,21 +.byte 4,199,35,195,24,150,5,154 +.byte 7,18,128,226,235,39,178,117 +.byte 9,131,44,26,27,110,90,160 +.byte 82,59,214,179,41,227,47,132 +.byte 83,209,0,237,32,252,177,91 +.byte 106,203,190,57,74,76,88,207 +.byte 208,239,170,251,67,77,51,133 +.byte 69,249,2,127,80,60,159,168 +.byte 81,163,64,143,146,157,56,245 +.byte 188,182,218,33,16,255,243,210 +.byte 205,12,19,236,95,151,68,23 +.byte 196,167,126,61,100,93,25,115 +.byte 96,129,79,220,34,42,144,136 +.byte 70,238,184,20,222,94,11,219 +.byte 224,50,58,10,73,6,36,92 +.byte 194,211,172,98,145,149,228,121 +.byte 231,200,55,109,141,213,78,169 +.byte 108,86,244,234,101,122,174,8 +.byte 186,120,37,46,28,166,180,198 +.byte 232,221,116,31,75,189,139,138 +.byte 112,62,181,102,72,3,246,14 +.byte 97,53,87,185,134,193,29,158 +.byte 225,248,152,17,105,217,142,148 +.byte 155,30,135,233,206,85,40,223 +.byte 140,161,137,13,191,230,66,104 +.byte 65,153,45,15,176,84,187,22 +.long 1,2,4,8 +.long 16,32,64,128 +.long 27,54,0,0 +.long 0,0,0,0 +.size _x86_AES_encrypt,.-_x86_AES_encrypt +.globl AES_encrypt +.type AES_encrypt,@function +.align 16 +AES_encrypt: +.L_AES_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 28(%esp),%edi + movl %esp,%eax + subl $36,%esp + andl $-64,%esp + leal -127(%edi),%ebx + subl %esp,%ebx + negl %ebx + andl $960,%ebx + subl %ebx,%esp + addl $4,%esp + movl %eax,28(%esp) + call .L004pic_point +.L004pic_point: + popl %ebp + leal OPENSSL_ia32cap_P-.L004pic_point(%ebp),%eax + leal .LAES_Te-.L004pic_point(%ebp),%ebp + leal 764(%esp),%ebx + subl %ebp,%ebx + andl $768,%ebx + leal 2176(%ebp,%ebx,1),%ebp + btl $25,(%eax) + jnc .L005x86 + movq (%esi),%mm0 + movq 8(%esi),%mm4 + call _sse_AES_encrypt_compact + movl 28(%esp),%esp + movl 24(%esp),%esi + movq %mm0,(%esi) + movq %mm4,8(%esi) + emms + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 16 +.L005x86: + movl %ebp,24(%esp) + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + call _x86_AES_encrypt_compact + movl 28(%esp),%esp + movl 24(%esp),%esi + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size AES_encrypt,.-.L_AES_encrypt_begin +.type _x86_AES_decrypt_compact,@function +.align 16 +_x86_AES_decrypt_compact: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl %edi,20(%esp) + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + movl 240(%edi),%esi + leal -2(%esi,%esi,1),%esi + leal (%edi,%esi,8),%esi + movl %esi,24(%esp) + movl -128(%ebp),%edi + movl -96(%ebp),%esi + movl -64(%ebp),%edi + movl -32(%ebp),%esi + movl (%ebp),%edi + movl 32(%ebp),%esi + movl 64(%ebp),%edi + movl 96(%ebp),%esi +.align 16 +.L006loop: + movl %eax,%esi + andl $255,%esi + movzbl -128(%ebp,%esi,1),%esi + movzbl %dh,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %ecx,%edi + shrl $16,%edi + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %ebx,%edi + shrl $24,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl %esi,4(%esp) + movl %ebx,%esi + andl $255,%esi + movzbl -128(%ebp,%esi,1),%esi + movzbl %ah,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $16,%edi + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %ecx,%edi + shrl $24,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl %esi,8(%esp) + movl %ecx,%esi + andl $255,%esi + movzbl -128(%ebp,%esi,1),%esi + movzbl %bh,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %eax,%edi + shrl $16,%edi + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $24,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + andl $255,%edx + movzbl -128(%ebp,%edx,1),%edx + movzbl %ch,%ecx + movzbl -128(%ebp,%ecx,1),%ecx + shll $8,%ecx + xorl %ecx,%edx + movl %esi,%ecx + shrl $16,%ebx + andl $255,%ebx + movzbl -128(%ebp,%ebx,1),%ebx + shll $16,%ebx + xorl %ebx,%edx + shrl $24,%eax + movzbl -128(%ebp,%eax,1),%eax + shll $24,%eax + xorl %eax,%edx + movl $2155905152,%edi + andl %ecx,%edi + movl %edi,%esi + shrl $7,%edi + leal (%ecx,%ecx,1),%eax + subl %edi,%esi + andl $4278124286,%eax + andl $454761243,%esi + xorl %esi,%eax + movl $2155905152,%edi + andl %eax,%edi + movl %edi,%esi + shrl $7,%edi + leal (%eax,%eax,1),%ebx + subl %edi,%esi + andl $4278124286,%ebx + andl $454761243,%esi + xorl %ecx,%eax + xorl %esi,%ebx + movl $2155905152,%edi + andl %ebx,%edi + movl %edi,%esi + shrl $7,%edi + leal (%ebx,%ebx,1),%ebp + subl %edi,%esi + andl $4278124286,%ebp + andl $454761243,%esi + xorl %ecx,%ebx + roll $8,%ecx + xorl %esi,%ebp + xorl %eax,%ecx + xorl %ebp,%eax + xorl %ebx,%ecx + xorl %ebp,%ebx + roll $24,%eax + xorl %ebp,%ecx + roll $16,%ebx + xorl %eax,%ecx + roll $8,%ebp + xorl %ebx,%ecx + movl 4(%esp),%eax + xorl %ebp,%ecx + movl %ecx,12(%esp) + movl $2155905152,%edi + andl %edx,%edi + movl %edi,%esi + shrl $7,%edi + leal (%edx,%edx,1),%ebx + subl %edi,%esi + andl $4278124286,%ebx + andl $454761243,%esi + xorl %esi,%ebx + movl $2155905152,%edi + andl %ebx,%edi + movl %edi,%esi + shrl $7,%edi + leal (%ebx,%ebx,1),%ecx + subl %edi,%esi + andl $4278124286,%ecx + andl $454761243,%esi + xorl %edx,%ebx + xorl %esi,%ecx + movl $2155905152,%edi + andl %ecx,%edi + movl %edi,%esi + shrl $7,%edi + leal (%ecx,%ecx,1),%ebp + subl %edi,%esi + andl $4278124286,%ebp + andl $454761243,%esi + xorl %edx,%ecx + roll $8,%edx + xorl %esi,%ebp + xorl %ebx,%edx + xorl %ebp,%ebx + xorl %ecx,%edx + xorl %ebp,%ecx + roll $24,%ebx + xorl %ebp,%edx + roll $16,%ecx + xorl %ebx,%edx + roll $8,%ebp + xorl %ecx,%edx + movl 8(%esp),%ebx + xorl %ebp,%edx + movl %edx,16(%esp) + movl $2155905152,%edi + andl %eax,%edi + movl %edi,%esi + shrl $7,%edi + leal (%eax,%eax,1),%ecx + subl %edi,%esi + andl $4278124286,%ecx + andl $454761243,%esi + xorl %esi,%ecx + movl $2155905152,%edi + andl %ecx,%edi + movl %edi,%esi + shrl $7,%edi + leal (%ecx,%ecx,1),%edx + subl %edi,%esi + andl $4278124286,%edx + andl $454761243,%esi + xorl %eax,%ecx + xorl %esi,%edx + movl $2155905152,%edi + andl %edx,%edi + movl %edi,%esi + shrl $7,%edi + leal (%edx,%edx,1),%ebp + subl %edi,%esi + andl $4278124286,%ebp + andl $454761243,%esi + xorl %eax,%edx + roll $8,%eax + xorl %esi,%ebp + xorl %ecx,%eax + xorl %ebp,%ecx + xorl %edx,%eax + xorl %ebp,%edx + roll $24,%ecx + xorl %ebp,%eax + roll $16,%edx + xorl %ecx,%eax + roll $8,%ebp + xorl %edx,%eax + xorl %ebp,%eax + movl $2155905152,%edi + andl %ebx,%edi + movl %edi,%esi + shrl $7,%edi + leal (%ebx,%ebx,1),%ecx + subl %edi,%esi + andl $4278124286,%ecx + andl $454761243,%esi + xorl %esi,%ecx + movl $2155905152,%edi + andl %ecx,%edi + movl %edi,%esi + shrl $7,%edi + leal (%ecx,%ecx,1),%edx + subl %edi,%esi + andl $4278124286,%edx + andl $454761243,%esi + xorl %ebx,%ecx + xorl %esi,%edx + movl $2155905152,%edi + andl %edx,%edi + movl %edi,%esi + shrl $7,%edi + leal (%edx,%edx,1),%ebp + subl %edi,%esi + andl $4278124286,%ebp + andl $454761243,%esi + xorl %ebx,%edx + roll $8,%ebx + xorl %esi,%ebp + xorl %ecx,%ebx + xorl %ebp,%ecx + xorl %edx,%ebx + xorl %ebp,%edx + roll $24,%ecx + xorl %ebp,%ebx + roll $16,%edx + xorl %ecx,%ebx + roll $8,%ebp + xorl %edx,%ebx + movl 12(%esp),%ecx + xorl %ebp,%ebx + movl 16(%esp),%edx + movl 20(%esp),%edi + movl 28(%esp),%ebp + addl $16,%edi + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + cmpl 24(%esp),%edi + movl %edi,20(%esp) + jb .L006loop + movl %eax,%esi + andl $255,%esi + movzbl -128(%ebp,%esi,1),%esi + movzbl %dh,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %ecx,%edi + shrl $16,%edi + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %ebx,%edi + shrl $24,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl %esi,4(%esp) + movl %ebx,%esi + andl $255,%esi + movzbl -128(%ebp,%esi,1),%esi + movzbl %ah,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $16,%edi + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %ecx,%edi + shrl $24,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl %esi,8(%esp) + movl %ecx,%esi + andl $255,%esi + movzbl -128(%ebp,%esi,1),%esi + movzbl %bh,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %eax,%edi + shrl $16,%edi + andl $255,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $24,%edi + movzbl -128(%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl 20(%esp),%edi + andl $255,%edx + movzbl -128(%ebp,%edx,1),%edx + movzbl %ch,%ecx + movzbl -128(%ebp,%ecx,1),%ecx + shll $8,%ecx + xorl %ecx,%edx + movl %esi,%ecx + shrl $16,%ebx + andl $255,%ebx + movzbl -128(%ebp,%ebx,1),%ebx + shll $16,%ebx + xorl %ebx,%edx + movl 8(%esp),%ebx + shrl $24,%eax + movzbl -128(%ebp,%eax,1),%eax + shll $24,%eax + xorl %eax,%edx + movl 4(%esp),%eax + xorl 16(%edi),%eax + xorl 20(%edi),%ebx + xorl 24(%edi),%ecx + xorl 28(%edi),%edx + ret +.size _x86_AES_decrypt_compact,.-_x86_AES_decrypt_compact +.type _sse_AES_decrypt_compact,@function +.align 16 +_sse_AES_decrypt_compact: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pxor (%edi),%mm0 + pxor 8(%edi),%mm4 + movl 240(%edi),%esi + leal -2(%esi,%esi,1),%esi + leal (%edi,%esi,8),%esi + movl %esi,24(%esp) + movl $454761243,%eax + movl %eax,8(%esp) + movl %eax,12(%esp) + movl -128(%ebp),%eax + movl -96(%ebp),%ebx + movl -64(%ebp),%ecx + movl -32(%ebp),%edx + movl (%ebp),%eax + movl 32(%ebp),%ebx + movl 64(%ebp),%ecx + movl 96(%ebp),%edx +.align 16 +.L007loop: + pshufw $12,%mm0,%mm1 + pshufw $9,%mm4,%mm5 + movd %mm1,%eax + movd %mm5,%ebx + movl %edi,20(%esp) + movzbl %al,%esi + movzbl %ah,%edx + pshufw $6,%mm0,%mm2 + movzbl -128(%ebp,%esi,1),%ecx + movzbl %bl,%edi + movzbl -128(%ebp,%edx,1),%edx + shrl $16,%eax + shll $8,%edx + movzbl -128(%ebp,%edi,1),%esi + movzbl %bh,%edi + shll $16,%esi + pshufw $3,%mm4,%mm6 + orl %esi,%ecx + movzbl -128(%ebp,%edi,1),%esi + movzbl %ah,%edi + shll $24,%esi + shrl $16,%ebx + orl %esi,%edx + movzbl -128(%ebp,%edi,1),%esi + movzbl %bh,%edi + shll $24,%esi + orl %esi,%ecx + movzbl -128(%ebp,%edi,1),%esi + movzbl %al,%edi + shll $8,%esi + movd %mm2,%eax + orl %esi,%ecx + movzbl -128(%ebp,%edi,1),%esi + movzbl %bl,%edi + shll $16,%esi + movd %mm6,%ebx + movd %ecx,%mm0 + movzbl -128(%ebp,%edi,1),%ecx + movzbl %al,%edi + orl %esi,%ecx + movzbl -128(%ebp,%edi,1),%esi + movzbl %bl,%edi + orl %esi,%edx + movzbl -128(%ebp,%edi,1),%esi + movzbl %ah,%edi + shll $16,%esi + shrl $16,%eax + orl %esi,%edx + movzbl -128(%ebp,%edi,1),%esi + movzbl %bh,%edi + shrl $16,%ebx + shll $8,%esi + movd %edx,%mm1 + movzbl -128(%ebp,%edi,1),%edx + movzbl %bh,%edi + shll $24,%edx + andl $255,%ebx + orl %esi,%edx + punpckldq %mm1,%mm0 + movzbl -128(%ebp,%edi,1),%esi + movzbl %al,%edi + shll $8,%esi + movzbl %ah,%eax + movzbl -128(%ebp,%ebx,1),%ebx + orl %esi,%ecx + movzbl -128(%ebp,%edi,1),%esi + orl %ebx,%edx + shll $16,%esi + movzbl -128(%ebp,%eax,1),%eax + orl %esi,%edx + shll $24,%eax + orl %eax,%ecx + movl 20(%esp),%edi + movd %edx,%mm4 + movd %ecx,%mm5 + punpckldq %mm5,%mm4 + addl $16,%edi + cmpl 24(%esp),%edi + ja .L008out + movq %mm0,%mm3 + movq %mm4,%mm7 + pshufw $228,%mm0,%mm2 + pshufw $228,%mm4,%mm6 + movq %mm0,%mm1 + movq %mm4,%mm5 + pshufw $177,%mm0,%mm0 + pshufw $177,%mm4,%mm4 + pslld $8,%mm2 + pslld $8,%mm6 + psrld $8,%mm3 + psrld $8,%mm7 + pxor %mm2,%mm0 + pxor %mm6,%mm4 + pxor %mm3,%mm0 + pxor %mm7,%mm4 + pslld $16,%mm2 + pslld $16,%mm6 + psrld $16,%mm3 + psrld $16,%mm7 + pxor %mm2,%mm0 + pxor %mm6,%mm4 + pxor %mm3,%mm0 + pxor %mm7,%mm4 + movq 8(%esp),%mm3 + pxor %mm2,%mm2 + pxor %mm6,%mm6 + pcmpgtb %mm1,%mm2 + pcmpgtb %mm5,%mm6 + pand %mm3,%mm2 + pand %mm3,%mm6 + paddb %mm1,%mm1 + paddb %mm5,%mm5 + pxor %mm2,%mm1 + pxor %mm6,%mm5 + movq %mm1,%mm3 + movq %mm5,%mm7 + movq %mm1,%mm2 + movq %mm5,%mm6 + pxor %mm1,%mm0 + pxor %mm5,%mm4 + pslld $24,%mm3 + pslld $24,%mm7 + psrld $8,%mm2 + psrld $8,%mm6 + pxor %mm3,%mm0 + pxor %mm7,%mm4 + pxor %mm2,%mm0 + pxor %mm6,%mm4 + movq 8(%esp),%mm2 + pxor %mm3,%mm3 + pxor %mm7,%mm7 + pcmpgtb %mm1,%mm3 + pcmpgtb %mm5,%mm7 + pand %mm2,%mm3 + pand %mm2,%mm7 + paddb %mm1,%mm1 + paddb %mm5,%mm5 + pxor %mm3,%mm1 + pxor %mm7,%mm5 + pshufw $177,%mm1,%mm3 + pshufw $177,%mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm5,%mm4 + pxor %mm3,%mm0 + pxor %mm7,%mm4 + pxor %mm3,%mm3 + pxor %mm7,%mm7 + pcmpgtb %mm1,%mm3 + pcmpgtb %mm5,%mm7 + pand %mm2,%mm3 + pand %mm2,%mm7 + paddb %mm1,%mm1 + paddb %mm5,%mm5 + pxor %mm3,%mm1 + pxor %mm7,%mm5 + pxor %mm1,%mm0 + pxor %mm5,%mm4 + movq %mm1,%mm3 + movq %mm5,%mm7 + pshufw $177,%mm1,%mm2 + pshufw $177,%mm5,%mm6 + pxor %mm2,%mm0 + pxor %mm6,%mm4 + pslld $8,%mm1 + pslld $8,%mm5 + psrld $8,%mm3 + psrld $8,%mm7 + movq (%edi),%mm2 + movq 8(%edi),%mm6 + pxor %mm1,%mm0 + pxor %mm5,%mm4 + pxor %mm3,%mm0 + pxor %mm7,%mm4 + movl -128(%ebp),%eax + pslld $16,%mm1 + pslld $16,%mm5 + movl -64(%ebp),%ebx + psrld $16,%mm3 + psrld $16,%mm7 + movl (%ebp),%ecx + pxor %mm1,%mm0 + pxor %mm5,%mm4 + movl 64(%ebp),%edx + pxor %mm3,%mm0 + pxor %mm7,%mm4 + pxor %mm2,%mm0 + pxor %mm6,%mm4 + jmp .L007loop +.align 16 +.L008out: + pxor (%edi),%mm0 + pxor 8(%edi),%mm4 + ret +.size _sse_AES_decrypt_compact,.-_sse_AES_decrypt_compact +.type _x86_AES_decrypt,@function +.align 16 +_x86_AES_decrypt: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl %edi,20(%esp) + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + movl 240(%edi),%esi + leal -2(%esi,%esi,1),%esi + leal (%edi,%esi,8),%esi + movl %esi,24(%esp) +.align 16 +.L009loop: + movl %eax,%esi + andl $255,%esi + movl (%ebp,%esi,8),%esi + movzbl %dh,%edi + xorl 3(%ebp,%edi,8),%esi + movl %ecx,%edi + shrl $16,%edi + andl $255,%edi + xorl 2(%ebp,%edi,8),%esi + movl %ebx,%edi + shrl $24,%edi + xorl 1(%ebp,%edi,8),%esi + movl %esi,4(%esp) + + movl %ebx,%esi + andl $255,%esi + movl (%ebp,%esi,8),%esi + movzbl %ah,%edi + xorl 3(%ebp,%edi,8),%esi + movl %edx,%edi + shrl $16,%edi + andl $255,%edi + xorl 2(%ebp,%edi,8),%esi + movl %ecx,%edi + shrl $24,%edi + xorl 1(%ebp,%edi,8),%esi + movl %esi,8(%esp) + + movl %ecx,%esi + andl $255,%esi + movl (%ebp,%esi,8),%esi + movzbl %bh,%edi + xorl 3(%ebp,%edi,8),%esi + movl %eax,%edi + shrl $16,%edi + andl $255,%edi + xorl 2(%ebp,%edi,8),%esi + movl %edx,%edi + shrl $24,%edi + xorl 1(%ebp,%edi,8),%esi + + movl 20(%esp),%edi + andl $255,%edx + movl (%ebp,%edx,8),%edx + movzbl %ch,%ecx + xorl 3(%ebp,%ecx,8),%edx + movl %esi,%ecx + shrl $16,%ebx + andl $255,%ebx + xorl 2(%ebp,%ebx,8),%edx + movl 8(%esp),%ebx + shrl $24,%eax + xorl 1(%ebp,%eax,8),%edx + movl 4(%esp),%eax + + addl $16,%edi + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + cmpl 24(%esp),%edi + movl %edi,20(%esp) + jb .L009loop + leal 2176(%ebp),%ebp + movl -128(%ebp),%edi + movl -96(%ebp),%esi + movl -64(%ebp),%edi + movl -32(%ebp),%esi + movl (%ebp),%edi + movl 32(%ebp),%esi + movl 64(%ebp),%edi + movl 96(%ebp),%esi + leal -128(%ebp),%ebp + movl %eax,%esi + andl $255,%esi + movzbl (%ebp,%esi,1),%esi + movzbl %dh,%edi + movzbl (%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %ecx,%edi + shrl $16,%edi + andl $255,%edi + movzbl (%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %ebx,%edi + shrl $24,%edi + movzbl (%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl %esi,4(%esp) + movl %ebx,%esi + andl $255,%esi + movzbl (%ebp,%esi,1),%esi + movzbl %ah,%edi + movzbl (%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $16,%edi + andl $255,%edi + movzbl (%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %ecx,%edi + shrl $24,%edi + movzbl (%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl %esi,8(%esp) + movl %ecx,%esi + andl $255,%esi + movzbl (%ebp,%esi,1),%esi + movzbl %bh,%edi + movzbl (%ebp,%edi,1),%edi + shll $8,%edi + xorl %edi,%esi + movl %eax,%edi + shrl $16,%edi + andl $255,%edi + movzbl (%ebp,%edi,1),%edi + shll $16,%edi + xorl %edi,%esi + movl %edx,%edi + shrl $24,%edi + movzbl (%ebp,%edi,1),%edi + shll $24,%edi + xorl %edi,%esi + movl 20(%esp),%edi + andl $255,%edx + movzbl (%ebp,%edx,1),%edx + movzbl %ch,%ecx + movzbl (%ebp,%ecx,1),%ecx + shll $8,%ecx + xorl %ecx,%edx + movl %esi,%ecx + shrl $16,%ebx + andl $255,%ebx + movzbl (%ebp,%ebx,1),%ebx + shll $16,%ebx + xorl %ebx,%edx + movl 8(%esp),%ebx + shrl $24,%eax + movzbl (%ebp,%eax,1),%eax + shll $24,%eax + xorl %eax,%edx + movl 4(%esp),%eax + leal -2048(%ebp),%ebp + addl $16,%edi + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + ret +.align 64 +.LAES_Td: +.long 1353184337,1353184337 +.long 1399144830,1399144830 +.long 3282310938,3282310938 +.long 2522752826,2522752826 +.long 3412831035,3412831035 +.long 4047871263,4047871263 +.long 2874735276,2874735276 +.long 2466505547,2466505547 +.long 1442459680,1442459680 +.long 4134368941,4134368941 +.long 2440481928,2440481928 +.long 625738485,625738485 +.long 4242007375,4242007375 +.long 3620416197,3620416197 +.long 2151953702,2151953702 +.long 2409849525,2409849525 +.long 1230680542,1230680542 +.long 1729870373,1729870373 +.long 2551114309,2551114309 +.long 3787521629,3787521629 +.long 41234371,41234371 +.long 317738113,317738113 +.long 2744600205,2744600205 +.long 3338261355,3338261355 +.long 3881799427,3881799427 +.long 2510066197,2510066197 +.long 3950669247,3950669247 +.long 3663286933,3663286933 +.long 763608788,763608788 +.long 3542185048,3542185048 +.long 694804553,694804553 +.long 1154009486,1154009486 +.long 1787413109,1787413109 +.long 2021232372,2021232372 +.long 1799248025,1799248025 +.long 3715217703,3715217703 +.long 3058688446,3058688446 +.long 397248752,397248752 +.long 1722556617,1722556617 +.long 3023752829,3023752829 +.long 407560035,407560035 +.long 2184256229,2184256229 +.long 1613975959,1613975959 +.long 1165972322,1165972322 +.long 3765920945,3765920945 +.long 2226023355,2226023355 +.long 480281086,480281086 +.long 2485848313,2485848313 +.long 1483229296,1483229296 +.long 436028815,436028815 +.long 2272059028,2272059028 +.long 3086515026,3086515026 +.long 601060267,601060267 +.long 3791801202,3791801202 +.long 1468997603,1468997603 +.long 715871590,715871590 +.long 120122290,120122290 +.long 63092015,63092015 +.long 2591802758,2591802758 +.long 2768779219,2768779219 +.long 4068943920,4068943920 +.long 2997206819,2997206819 +.long 3127509762,3127509762 +.long 1552029421,1552029421 +.long 723308426,723308426 +.long 2461301159,2461301159 +.long 4042393587,4042393587 +.long 2715969870,2715969870 +.long 3455375973,3455375973 +.long 3586000134,3586000134 +.long 526529745,526529745 +.long 2331944644,2331944644 +.long 2639474228,2639474228 +.long 2689987490,2689987490 +.long 853641733,853641733 +.long 1978398372,1978398372 +.long 971801355,971801355 +.long 2867814464,2867814464 +.long 111112542,111112542 +.long 1360031421,1360031421 +.long 4186579262,4186579262 +.long 1023860118,1023860118 +.long 2919579357,2919579357 +.long 1186850381,1186850381 +.long 3045938321,3045938321 +.long 90031217,90031217 +.long 1876166148,1876166148 +.long 4279586912,4279586912 +.long 620468249,620468249 +.long 2548678102,2548678102 +.long 3426959497,3426959497 +.long 2006899047,2006899047 +.long 3175278768,3175278768 +.long 2290845959,2290845959 +.long 945494503,945494503 +.long 3689859193,3689859193 +.long 1191869601,1191869601 +.long 3910091388,3910091388 +.long 3374220536,3374220536 +.long 0,0 +.long 2206629897,2206629897 +.long 1223502642,1223502642 +.long 2893025566,2893025566 +.long 1316117100,1316117100 +.long 4227796733,4227796733 +.long 1446544655,1446544655 +.long 517320253,517320253 +.long 658058550,658058550 +.long 1691946762,1691946762 +.long 564550760,564550760 +.long 3511966619,3511966619 +.long 976107044,976107044 +.long 2976320012,2976320012 +.long 266819475,266819475 +.long 3533106868,3533106868 +.long 2660342555,2660342555 +.long 1338359936,1338359936 +.long 2720062561,2720062561 +.long 1766553434,1766553434 +.long 370807324,370807324 +.long 179999714,179999714 +.long 3844776128,3844776128 +.long 1138762300,1138762300 +.long 488053522,488053522 +.long 185403662,185403662 +.long 2915535858,2915535858 +.long 3114841645,3114841645 +.long 3366526484,3366526484 +.long 2233069911,2233069911 +.long 1275557295,1275557295 +.long 3151862254,3151862254 +.long 4250959779,4250959779 +.long 2670068215,2670068215 +.long 3170202204,3170202204 +.long 3309004356,3309004356 +.long 880737115,880737115 +.long 1982415755,1982415755 +.long 3703972811,3703972811 +.long 1761406390,1761406390 +.long 1676797112,1676797112 +.long 3403428311,3403428311 +.long 277177154,277177154 +.long 1076008723,1076008723 +.long 538035844,538035844 +.long 2099530373,2099530373 +.long 4164795346,4164795346 +.long 288553390,288553390 +.long 1839278535,1839278535 +.long 1261411869,1261411869 +.long 4080055004,4080055004 +.long 3964831245,3964831245 +.long 3504587127,3504587127 +.long 1813426987,1813426987 +.long 2579067049,2579067049 +.long 4199060497,4199060497 +.long 577038663,577038663 +.long 3297574056,3297574056 +.long 440397984,440397984 +.long 3626794326,3626794326 +.long 4019204898,4019204898 +.long 3343796615,3343796615 +.long 3251714265,3251714265 +.long 4272081548,4272081548 +.long 906744984,906744984 +.long 3481400742,3481400742 +.long 685669029,685669029 +.long 646887386,646887386 +.long 2764025151,2764025151 +.long 3835509292,3835509292 +.long 227702864,227702864 +.long 2613862250,2613862250 +.long 1648787028,1648787028 +.long 3256061430,3256061430 +.long 3904428176,3904428176 +.long 1593260334,1593260334 +.long 4121936770,4121936770 +.long 3196083615,3196083615 +.long 2090061929,2090061929 +.long 2838353263,2838353263 +.long 3004310991,3004310991 +.long 999926984,999926984 +.long 2809993232,2809993232 +.long 1852021992,1852021992 +.long 2075868123,2075868123 +.long 158869197,158869197 +.long 4095236462,4095236462 +.long 28809964,28809964 +.long 2828685187,2828685187 +.long 1701746150,1701746150 +.long 2129067946,2129067946 +.long 147831841,147831841 +.long 3873969647,3873969647 +.long 3650873274,3650873274 +.long 3459673930,3459673930 +.long 3557400554,3557400554 +.long 3598495785,3598495785 +.long 2947720241,2947720241 +.long 824393514,824393514 +.long 815048134,815048134 +.long 3227951669,3227951669 +.long 935087732,935087732 +.long 2798289660,2798289660 +.long 2966458592,2966458592 +.long 366520115,366520115 +.long 1251476721,1251476721 +.long 4158319681,4158319681 +.long 240176511,240176511 +.long 804688151,804688151 +.long 2379631990,2379631990 +.long 1303441219,1303441219 +.long 1414376140,1414376140 +.long 3741619940,3741619940 +.long 3820343710,3820343710 +.long 461924940,461924940 +.long 3089050817,3089050817 +.long 2136040774,2136040774 +.long 82468509,82468509 +.long 1563790337,1563790337 +.long 1937016826,1937016826 +.long 776014843,776014843 +.long 1511876531,1511876531 +.long 1389550482,1389550482 +.long 861278441,861278441 +.long 323475053,323475053 +.long 2355222426,2355222426 +.long 2047648055,2047648055 +.long 2383738969,2383738969 +.long 2302415851,2302415851 +.long 3995576782,3995576782 +.long 902390199,902390199 +.long 3991215329,3991215329 +.long 1018251130,1018251130 +.long 1507840668,1507840668 +.long 1064563285,1064563285 +.long 2043548696,2043548696 +.long 3208103795,3208103795 +.long 3939366739,3939366739 +.long 1537932639,1537932639 +.long 342834655,342834655 +.long 2262516856,2262516856 +.long 2180231114,2180231114 +.long 1053059257,1053059257 +.long 741614648,741614648 +.long 1598071746,1598071746 +.long 1925389590,1925389590 +.long 203809468,203809468 +.long 2336832552,2336832552 +.long 1100287487,1100287487 +.long 1895934009,1895934009 +.long 3736275976,3736275976 +.long 2632234200,2632234200 +.long 2428589668,2428589668 +.long 1636092795,1636092795 +.long 1890988757,1890988757 +.long 1952214088,1952214088 +.long 1113045200,1113045200 +.byte 82,9,106,213,48,54,165,56 +.byte 191,64,163,158,129,243,215,251 +.byte 124,227,57,130,155,47,255,135 +.byte 52,142,67,68,196,222,233,203 +.byte 84,123,148,50,166,194,35,61 +.byte 238,76,149,11,66,250,195,78 +.byte 8,46,161,102,40,217,36,178 +.byte 118,91,162,73,109,139,209,37 +.byte 114,248,246,100,134,104,152,22 +.byte 212,164,92,204,93,101,182,146 +.byte 108,112,72,80,253,237,185,218 +.byte 94,21,70,87,167,141,157,132 +.byte 144,216,171,0,140,188,211,10 +.byte 247,228,88,5,184,179,69,6 +.byte 208,44,30,143,202,63,15,2 +.byte 193,175,189,3,1,19,138,107 +.byte 58,145,17,65,79,103,220,234 +.byte 151,242,207,206,240,180,230,115 +.byte 150,172,116,34,231,173,53,133 +.byte 226,249,55,232,28,117,223,110 +.byte 71,241,26,113,29,41,197,137 +.byte 111,183,98,14,170,24,190,27 +.byte 252,86,62,75,198,210,121,32 +.byte 154,219,192,254,120,205,90,244 +.byte 31,221,168,51,136,7,199,49 +.byte 177,18,16,89,39,128,236,95 +.byte 96,81,127,169,25,181,74,13 +.byte 45,229,122,159,147,201,156,239 +.byte 160,224,59,77,174,42,245,176 +.byte 200,235,187,60,131,83,153,97 +.byte 23,43,4,126,186,119,214,38 +.byte 225,105,20,99,85,33,12,125 +.byte 82,9,106,213,48,54,165,56 +.byte 191,64,163,158,129,243,215,251 +.byte 124,227,57,130,155,47,255,135 +.byte 52,142,67,68,196,222,233,203 +.byte 84,123,148,50,166,194,35,61 +.byte 238,76,149,11,66,250,195,78 +.byte 8,46,161,102,40,217,36,178 +.byte 118,91,162,73,109,139,209,37 +.byte 114,248,246,100,134,104,152,22 +.byte 212,164,92,204,93,101,182,146 +.byte 108,112,72,80,253,237,185,218 +.byte 94,21,70,87,167,141,157,132 +.byte 144,216,171,0,140,188,211,10 +.byte 247,228,88,5,184,179,69,6 +.byte 208,44,30,143,202,63,15,2 +.byte 193,175,189,3,1,19,138,107 +.byte 58,145,17,65,79,103,220,234 +.byte 151,242,207,206,240,180,230,115 +.byte 150,172,116,34,231,173,53,133 +.byte 226,249,55,232,28,117,223,110 +.byte 71,241,26,113,29,41,197,137 +.byte 111,183,98,14,170,24,190,27 +.byte 252,86,62,75,198,210,121,32 +.byte 154,219,192,254,120,205,90,244 +.byte 31,221,168,51,136,7,199,49 +.byte 177,18,16,89,39,128,236,95 +.byte 96,81,127,169,25,181,74,13 +.byte 45,229,122,159,147,201,156,239 +.byte 160,224,59,77,174,42,245,176 +.byte 200,235,187,60,131,83,153,97 +.byte 23,43,4,126,186,119,214,38 +.byte 225,105,20,99,85,33,12,125 +.byte 82,9,106,213,48,54,165,56 +.byte 191,64,163,158,129,243,215,251 +.byte 124,227,57,130,155,47,255,135 +.byte 52,142,67,68,196,222,233,203 +.byte 84,123,148,50,166,194,35,61 +.byte 238,76,149,11,66,250,195,78 +.byte 8,46,161,102,40,217,36,178 +.byte 118,91,162,73,109,139,209,37 +.byte 114,248,246,100,134,104,152,22 +.byte 212,164,92,204,93,101,182,146 +.byte 108,112,72,80,253,237,185,218 +.byte 94,21,70,87,167,141,157,132 +.byte 144,216,171,0,140,188,211,10 +.byte 247,228,88,5,184,179,69,6 +.byte 208,44,30,143,202,63,15,2 +.byte 193,175,189,3,1,19,138,107 +.byte 58,145,17,65,79,103,220,234 +.byte 151,242,207,206,240,180,230,115 +.byte 150,172,116,34,231,173,53,133 +.byte 226,249,55,232,28,117,223,110 +.byte 71,241,26,113,29,41,197,137 +.byte 111,183,98,14,170,24,190,27 +.byte 252,86,62,75,198,210,121,32 +.byte 154,219,192,254,120,205,90,244 +.byte 31,221,168,51,136,7,199,49 +.byte 177,18,16,89,39,128,236,95 +.byte 96,81,127,169,25,181,74,13 +.byte 45,229,122,159,147,201,156,239 +.byte 160,224,59,77,174,42,245,176 +.byte 200,235,187,60,131,83,153,97 +.byte 23,43,4,126,186,119,214,38 +.byte 225,105,20,99,85,33,12,125 +.byte 82,9,106,213,48,54,165,56 +.byte 191,64,163,158,129,243,215,251 +.byte 124,227,57,130,155,47,255,135 +.byte 52,142,67,68,196,222,233,203 +.byte 84,123,148,50,166,194,35,61 +.byte 238,76,149,11,66,250,195,78 +.byte 8,46,161,102,40,217,36,178 +.byte 118,91,162,73,109,139,209,37 +.byte 114,248,246,100,134,104,152,22 +.byte 212,164,92,204,93,101,182,146 +.byte 108,112,72,80,253,237,185,218 +.byte 94,21,70,87,167,141,157,132 +.byte 144,216,171,0,140,188,211,10 +.byte 247,228,88,5,184,179,69,6 +.byte 208,44,30,143,202,63,15,2 +.byte 193,175,189,3,1,19,138,107 +.byte 58,145,17,65,79,103,220,234 +.byte 151,242,207,206,240,180,230,115 +.byte 150,172,116,34,231,173,53,133 +.byte 226,249,55,232,28,117,223,110 +.byte 71,241,26,113,29,41,197,137 +.byte 111,183,98,14,170,24,190,27 +.byte 252,86,62,75,198,210,121,32 +.byte 154,219,192,254,120,205,90,244 +.byte 31,221,168,51,136,7,199,49 +.byte 177,18,16,89,39,128,236,95 +.byte 96,81,127,169,25,181,74,13 +.byte 45,229,122,159,147,201,156,239 +.byte 160,224,59,77,174,42,245,176 +.byte 200,235,187,60,131,83,153,97 +.byte 23,43,4,126,186,119,214,38 +.byte 225,105,20,99,85,33,12,125 +.size _x86_AES_decrypt,.-_x86_AES_decrypt +.globl AES_decrypt +.type AES_decrypt,@function +.align 16 +AES_decrypt: +.L_AES_decrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 28(%esp),%edi + movl %esp,%eax + subl $36,%esp + andl $-64,%esp + leal -127(%edi),%ebx + subl %esp,%ebx + negl %ebx + andl $960,%ebx + subl %ebx,%esp + addl $4,%esp + movl %eax,28(%esp) + call .L010pic_point +.L010pic_point: + popl %ebp + leal OPENSSL_ia32cap_P-.L010pic_point(%ebp),%eax + leal .LAES_Td-.L010pic_point(%ebp),%ebp + leal 764(%esp),%ebx + subl %ebp,%ebx + andl $768,%ebx + leal 2176(%ebp,%ebx,1),%ebp + btl $25,(%eax) + jnc .L011x86 + movq (%esi),%mm0 + movq 8(%esi),%mm4 + call _sse_AES_decrypt_compact + movl 28(%esp),%esp + movl 24(%esp),%esi + movq %mm0,(%esi) + movq %mm4,8(%esi) + emms + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 16 +.L011x86: + movl %ebp,24(%esp) + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + call _x86_AES_decrypt_compact + movl 28(%esp),%esp + movl 24(%esp),%esi + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size AES_decrypt,.-.L_AES_decrypt_begin +.globl AES_cbc_encrypt +.type AES_cbc_encrypt,@function +.align 16 +AES_cbc_encrypt: +.L_AES_cbc_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 28(%esp),%ecx + cmpl $0,%ecx + je .L012drop_out + call .L013pic_point +.L013pic_point: + popl %ebp + leal OPENSSL_ia32cap_P-.L013pic_point(%ebp),%eax + cmpl $0,40(%esp) + leal .LAES_Te-.L013pic_point(%ebp),%ebp + jne .L014picked_te + leal .LAES_Td-.LAES_Te(%ebp),%ebp +.L014picked_te: + pushfl + cld + cmpl $512,%ecx + jb .L015slow_way + testl $15,%ecx + jnz .L015slow_way + btl $28,(%eax) + jc .L015slow_way + leal -324(%esp),%esi + andl $-64,%esi + movl %ebp,%eax + leal 2304(%ebp),%ebx + movl %esi,%edx + andl $4095,%eax + andl $4095,%ebx + andl $4095,%edx + cmpl %ebx,%edx + jb .L016tbl_break_out + subl %ebx,%edx + subl %edx,%esi + jmp .L017tbl_ok +.align 4 +.L016tbl_break_out: + subl %eax,%edx + andl $4095,%edx + addl $384,%edx + subl %edx,%esi +.align 4 +.L017tbl_ok: + leal 24(%esp),%edx + xchgl %esi,%esp + addl $4,%esp + movl %ebp,24(%esp) + movl %esi,28(%esp) + movl (%edx),%eax + movl 4(%edx),%ebx + movl 12(%edx),%edi + movl 16(%edx),%esi + movl 20(%edx),%edx + movl %eax,32(%esp) + movl %ebx,36(%esp) + movl %ecx,40(%esp) + movl %edi,44(%esp) + movl %esi,48(%esp) + movl $0,316(%esp) + movl %edi,%ebx + movl $61,%ecx + subl %ebp,%ebx + movl %edi,%esi + andl $4095,%ebx + leal 76(%esp),%edi + cmpl $2304,%ebx + jb .L018do_copy + cmpl $3852,%ebx + jb .L019skip_copy +.align 4 +.L018do_copy: + movl %edi,44(%esp) +.long 2784229001 +.L019skip_copy: + movl $16,%edi +.align 4 +.L020prefetch_tbl: + movl (%ebp),%eax + movl 32(%ebp),%ebx + movl 64(%ebp),%ecx + movl 96(%ebp),%esi + leal 128(%ebp),%ebp + subl $1,%edi + jnz .L020prefetch_tbl + subl $2048,%ebp + movl 32(%esp),%esi + movl 48(%esp),%edi + cmpl $0,%edx + je .L021fast_decrypt + movl (%edi),%eax + movl 4(%edi),%ebx +.align 16 +.L022fast_enc_loop: + movl 8(%edi),%ecx + movl 12(%edi),%edx + xorl (%esi),%eax + xorl 4(%esi),%ebx + xorl 8(%esi),%ecx + xorl 12(%esi),%edx + movl 44(%esp),%edi + call _x86_AES_encrypt + movl 32(%esp),%esi + movl 36(%esp),%edi + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + leal 16(%esi),%esi + movl 40(%esp),%ecx + movl %esi,32(%esp) + leal 16(%edi),%edx + movl %edx,36(%esp) + subl $16,%ecx + movl %ecx,40(%esp) + jnz .L022fast_enc_loop + movl 48(%esp),%esi + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + cmpl $0,316(%esp) + movl 44(%esp),%edi + je .L023skip_ezero + movl $60,%ecx + xorl %eax,%eax +.align 4 +.long 2884892297 +.L023skip_ezero: + movl 28(%esp),%esp + popfl +.L012drop_out: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + pushfl +.align 16 +.L021fast_decrypt: + cmpl 36(%esp),%esi + je .L024fast_dec_in_place + movl %edi,52(%esp) +.align 4 +.align 16 +.L025fast_dec_loop: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl 44(%esp),%edi + call _x86_AES_decrypt + movl 52(%esp),%edi + movl 40(%esp),%esi + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + movl 36(%esp),%edi + movl 32(%esp),%esi + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 40(%esp),%ecx + movl %esi,52(%esp) + leal 16(%esi),%esi + movl %esi,32(%esp) + leal 16(%edi),%edi + movl %edi,36(%esp) + subl $16,%ecx + movl %ecx,40(%esp) + jnz .L025fast_dec_loop + movl 52(%esp),%edi + movl 48(%esp),%esi + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + jmp .L026fast_dec_out +.align 16 +.L024fast_dec_in_place: +.L027fast_dec_in_place_loop: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + leal 60(%esp),%edi + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 44(%esp),%edi + call _x86_AES_decrypt + movl 48(%esp),%edi + movl 36(%esp),%esi + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + leal 16(%esi),%esi + movl %esi,36(%esp) + leal 60(%esp),%esi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 32(%esp),%esi + movl 40(%esp),%ecx + leal 16(%esi),%esi + movl %esi,32(%esp) + subl $16,%ecx + movl %ecx,40(%esp) + jnz .L027fast_dec_in_place_loop +.align 4 +.L026fast_dec_out: + cmpl $0,316(%esp) + movl 44(%esp),%edi + je .L028skip_dzero + movl $60,%ecx + xorl %eax,%eax +.align 4 +.long 2884892297 +.L028skip_dzero: + movl 28(%esp),%esp + popfl + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + pushfl +.align 16 +.L015slow_way: + movl (%eax),%eax + movl 36(%esp),%edi + leal -80(%esp),%esi + andl $-64,%esi + leal -143(%edi),%ebx + subl %esi,%ebx + negl %ebx + andl $960,%ebx + subl %ebx,%esi + leal 768(%esi),%ebx + subl %ebp,%ebx + andl $768,%ebx + leal 2176(%ebp,%ebx,1),%ebp + leal 24(%esp),%edx + xchgl %esi,%esp + addl $4,%esp + movl %ebp,24(%esp) + movl %esi,28(%esp) + movl %eax,52(%esp) + movl (%edx),%eax + movl 4(%edx),%ebx + movl 16(%edx),%esi + movl 20(%edx),%edx + movl %eax,32(%esp) + movl %ebx,36(%esp) + movl %ecx,40(%esp) + movl %edi,44(%esp) + movl %esi,48(%esp) + movl %esi,%edi + movl %eax,%esi + cmpl $0,%edx + je .L029slow_decrypt + cmpl $16,%ecx + movl %ebx,%edx + jb .L030slow_enc_tail + btl $25,52(%esp) + jnc .L031slow_enc_x86 + movq (%edi),%mm0 + movq 8(%edi),%mm4 +.align 16 +.L032slow_enc_loop_sse: + pxor (%esi),%mm0 + pxor 8(%esi),%mm4 + movl 44(%esp),%edi + call _sse_AES_encrypt_compact + movl 32(%esp),%esi + movl 36(%esp),%edi + movl 40(%esp),%ecx + movq %mm0,(%edi) + movq %mm4,8(%edi) + leal 16(%esi),%esi + movl %esi,32(%esp) + leal 16(%edi),%edx + movl %edx,36(%esp) + subl $16,%ecx + cmpl $16,%ecx + movl %ecx,40(%esp) + jae .L032slow_enc_loop_sse + testl $15,%ecx + jnz .L030slow_enc_tail + movl 48(%esp),%esi + movq %mm0,(%esi) + movq %mm4,8(%esi) + emms + movl 28(%esp),%esp + popfl + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + pushfl +.align 16 +.L031slow_enc_x86: + movl (%edi),%eax + movl 4(%edi),%ebx +.align 4 +.L033slow_enc_loop_x86: + movl 8(%edi),%ecx + movl 12(%edi),%edx + xorl (%esi),%eax + xorl 4(%esi),%ebx + xorl 8(%esi),%ecx + xorl 12(%esi),%edx + movl 44(%esp),%edi + call _x86_AES_encrypt_compact + movl 32(%esp),%esi + movl 36(%esp),%edi + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 40(%esp),%ecx + leal 16(%esi),%esi + movl %esi,32(%esp) + leal 16(%edi),%edx + movl %edx,36(%esp) + subl $16,%ecx + cmpl $16,%ecx + movl %ecx,40(%esp) + jae .L033slow_enc_loop_x86 + testl $15,%ecx + jnz .L030slow_enc_tail + movl 48(%esp),%esi + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + movl 28(%esp),%esp + popfl + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + pushfl +.align 16 +.L030slow_enc_tail: + emms + movl %edx,%edi + movl $16,%ebx + subl %ecx,%ebx + cmpl %esi,%edi + je .L034enc_in_place +.align 4 +.long 2767451785 + jmp .L035enc_skip_in_place +.L034enc_in_place: + leal (%edi,%ecx,1),%edi +.L035enc_skip_in_place: + movl %ebx,%ecx + xorl %eax,%eax +.align 4 +.long 2868115081 + movl 48(%esp),%edi + movl %edx,%esi + movl (%edi),%eax + movl 4(%edi),%ebx + movl $16,40(%esp) + jmp .L033slow_enc_loop_x86 +.align 16 +.L029slow_decrypt: + btl $25,52(%esp) + jnc .L036slow_dec_loop_x86 +.align 4 +.L037slow_dec_loop_sse: + movq (%esi),%mm0 + movq 8(%esi),%mm4 + movl 44(%esp),%edi + call _sse_AES_decrypt_compact + movl 32(%esp),%esi + leal 60(%esp),%eax + movl 36(%esp),%ebx + movl 40(%esp),%ecx + movl 48(%esp),%edi + movq (%esi),%mm1 + movq 8(%esi),%mm5 + pxor (%edi),%mm0 + pxor 8(%edi),%mm4 + movq %mm1,(%edi) + movq %mm5,8(%edi) + subl $16,%ecx + jc .L038slow_dec_partial_sse + movq %mm0,(%ebx) + movq %mm4,8(%ebx) + leal 16(%ebx),%ebx + movl %ebx,36(%esp) + leal 16(%esi),%esi + movl %esi,32(%esp) + movl %ecx,40(%esp) + jnz .L037slow_dec_loop_sse + emms + movl 28(%esp),%esp + popfl + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + pushfl +.align 16 +.L038slow_dec_partial_sse: + movq %mm0,(%eax) + movq %mm4,8(%eax) + emms + addl $16,%ecx + movl %ebx,%edi + movl %eax,%esi +.align 4 +.long 2767451785 + movl 28(%esp),%esp + popfl + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + pushfl +.align 16 +.L036slow_dec_loop_x86: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + leal 60(%esp),%edi + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 44(%esp),%edi + call _x86_AES_decrypt_compact + movl 48(%esp),%edi + movl 40(%esp),%esi + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + subl $16,%esi + jc .L039slow_dec_partial_x86 + movl %esi,40(%esp) + movl 36(%esp),%esi + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + leal 16(%esi),%esi + movl %esi,36(%esp) + leal 60(%esp),%esi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 32(%esp),%esi + leal 16(%esi),%esi + movl %esi,32(%esp) + jnz .L036slow_dec_loop_x86 + movl 28(%esp),%esp + popfl + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + pushfl +.align 16 +.L039slow_dec_partial_x86: + leal 60(%esp),%esi + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + movl 32(%esp),%esi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 40(%esp),%ecx + movl 36(%esp),%edi + leal 60(%esp),%esi +.align 4 +.long 2767451785 + movl 28(%esp),%esp + popfl + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size AES_cbc_encrypt,.-.L_AES_cbc_encrypt_begin +.type _x86_AES_set_encrypt_key,@function +.align 16 +_x86_AES_set_encrypt_key: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + movl 32(%esp),%edi + testl $-1,%esi + jz .L040badpointer + testl $-1,%edi + jz .L040badpointer + call .L041pic_point +.L041pic_point: + popl %ebp + leal .LAES_Te-.L041pic_point(%ebp),%ebp + leal 2176(%ebp),%ebp + movl -128(%ebp),%eax + movl -96(%ebp),%ebx + movl -64(%ebp),%ecx + movl -32(%ebp),%edx + movl (%ebp),%eax + movl 32(%ebp),%ebx + movl 64(%ebp),%ecx + movl 96(%ebp),%edx + movl 28(%esp),%ecx + cmpl $128,%ecx + je .L04210rounds + cmpl $192,%ecx + je .L04312rounds + cmpl $256,%ecx + je .L04414rounds + movl $-2,%eax + jmp .L045exit +.L04210rounds: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + xorl %ecx,%ecx + jmp .L04610shortcut +.align 4 +.L04710loop: + movl (%edi),%eax + movl 12(%edi),%edx +.L04610shortcut: + movzbl %dl,%esi + movzbl -128(%ebp,%esi,1),%ebx + movzbl %dh,%esi + shll $24,%ebx + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + shrl $16,%edx + movzbl %dl,%esi + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + movzbl %dh,%esi + shll $8,%ebx + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + shll $16,%ebx + xorl %ebx,%eax + xorl 896(%ebp,%ecx,4),%eax + movl %eax,16(%edi) + xorl 4(%edi),%eax + movl %eax,20(%edi) + xorl 8(%edi),%eax + movl %eax,24(%edi) + xorl 12(%edi),%eax + movl %eax,28(%edi) + incl %ecx + addl $16,%edi + cmpl $10,%ecx + jl .L04710loop + movl $10,80(%edi) + xorl %eax,%eax + jmp .L045exit +.L04312rounds: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 16(%esi),%ecx + movl 20(%esi),%edx + movl %ecx,16(%edi) + movl %edx,20(%edi) + xorl %ecx,%ecx + jmp .L04812shortcut +.align 4 +.L04912loop: + movl (%edi),%eax + movl 20(%edi),%edx +.L04812shortcut: + movzbl %dl,%esi + movzbl -128(%ebp,%esi,1),%ebx + movzbl %dh,%esi + shll $24,%ebx + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + shrl $16,%edx + movzbl %dl,%esi + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + movzbl %dh,%esi + shll $8,%ebx + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + shll $16,%ebx + xorl %ebx,%eax + xorl 896(%ebp,%ecx,4),%eax + movl %eax,24(%edi) + xorl 4(%edi),%eax + movl %eax,28(%edi) + xorl 8(%edi),%eax + movl %eax,32(%edi) + xorl 12(%edi),%eax + movl %eax,36(%edi) + cmpl $7,%ecx + je .L05012break + incl %ecx + xorl 16(%edi),%eax + movl %eax,40(%edi) + xorl 20(%edi),%eax + movl %eax,44(%edi) + addl $24,%edi + jmp .L04912loop +.L05012break: + movl $12,72(%edi) + xorl %eax,%eax + jmp .L045exit +.L04414rounds: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + movl %eax,16(%edi) + movl %ebx,20(%edi) + movl %ecx,24(%edi) + movl %edx,28(%edi) + xorl %ecx,%ecx + jmp .L05114shortcut +.align 4 +.L05214loop: + movl 28(%edi),%edx +.L05114shortcut: + movl (%edi),%eax + movzbl %dl,%esi + movzbl -128(%ebp,%esi,1),%ebx + movzbl %dh,%esi + shll $24,%ebx + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + shrl $16,%edx + movzbl %dl,%esi + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + movzbl %dh,%esi + shll $8,%ebx + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + shll $16,%ebx + xorl %ebx,%eax + xorl 896(%ebp,%ecx,4),%eax + movl %eax,32(%edi) + xorl 4(%edi),%eax + movl %eax,36(%edi) + xorl 8(%edi),%eax + movl %eax,40(%edi) + xorl 12(%edi),%eax + movl %eax,44(%edi) + cmpl $6,%ecx + je .L05314break + incl %ecx + movl %eax,%edx + movl 16(%edi),%eax + movzbl %dl,%esi + movzbl -128(%ebp,%esi,1),%ebx + movzbl %dh,%esi + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + shrl $16,%edx + shll $8,%ebx + movzbl %dl,%esi + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + movzbl %dh,%esi + shll $16,%ebx + xorl %ebx,%eax + movzbl -128(%ebp,%esi,1),%ebx + shll $24,%ebx + xorl %ebx,%eax + movl %eax,48(%edi) + xorl 20(%edi),%eax + movl %eax,52(%edi) + xorl 24(%edi),%eax + movl %eax,56(%edi) + xorl 28(%edi),%eax + movl %eax,60(%edi) + addl $32,%edi + jmp .L05214loop +.L05314break: + movl $14,48(%edi) + xorl %eax,%eax + jmp .L045exit +.L040badpointer: + movl $-1,%eax +.L045exit: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size _x86_AES_set_encrypt_key,.-_x86_AES_set_encrypt_key +.globl AES_set_encrypt_key +.type AES_set_encrypt_key,@function +.align 16 +AES_set_encrypt_key: +.L_AES_set_encrypt_key_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + call _x86_AES_set_encrypt_key + ret +.size AES_set_encrypt_key,.-.L_AES_set_encrypt_key_begin +.globl AES_set_decrypt_key +.type AES_set_decrypt_key,@function +.align 16 +AES_set_decrypt_key: +.L_AES_set_decrypt_key_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + call _x86_AES_set_encrypt_key + cmpl $0,%eax + je .L054proceed + ret +.L054proceed: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 28(%esp),%esi + movl 240(%esi),%ecx + leal (,%ecx,4),%ecx + leal (%esi,%ecx,4),%edi +.align 4 +.L055invert: + movl (%esi),%eax + movl 4(%esi),%ebx + movl (%edi),%ecx + movl 4(%edi),%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,(%esi) + movl %edx,4(%esi) + movl 8(%esi),%eax + movl 12(%esi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl %eax,8(%edi) + movl %ebx,12(%edi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + addl $16,%esi + subl $16,%edi + cmpl %edi,%esi + jne .L055invert + movl 28(%esp),%edi + movl 240(%edi),%esi + leal -2(%esi,%esi,1),%esi + leal (%edi,%esi,8),%esi + movl %esi,28(%esp) + movl 16(%edi),%eax +.align 4 +.L056permute: + addl $16,%edi + movl $2155905152,%ebp + andl %eax,%ebp + leal (%eax,%eax,1),%ebx + movl %ebp,%esi + shrl $7,%ebp + subl %ebp,%esi + andl $4278124286,%ebx + andl $454761243,%esi + xorl %esi,%ebx + movl $2155905152,%ebp + andl %ebx,%ebp + leal (%ebx,%ebx,1),%ecx + movl %ebp,%esi + shrl $7,%ebp + subl %ebp,%esi + andl $4278124286,%ecx + andl $454761243,%esi + xorl %eax,%ebx + xorl %esi,%ecx + movl $2155905152,%ebp + andl %ecx,%ebp + leal (%ecx,%ecx,1),%edx + movl %ebp,%esi + shrl $7,%ebp + xorl %eax,%ecx + subl %ebp,%esi + andl $4278124286,%edx + andl $454761243,%esi + roll $8,%eax + xorl %esi,%edx + movl 4(%edi),%ebp + xorl %ebx,%eax + xorl %edx,%ebx + xorl %ecx,%eax + roll $24,%ebx + xorl %edx,%ecx + xorl %edx,%eax + roll $16,%ecx + xorl %ebx,%eax + roll $8,%edx + xorl %ecx,%eax + movl %ebp,%ebx + xorl %edx,%eax + movl %eax,(%edi) + movl $2155905152,%ebp + andl %ebx,%ebp + leal (%ebx,%ebx,1),%ecx + movl %ebp,%esi + shrl $7,%ebp + subl %ebp,%esi + andl $4278124286,%ecx + andl $454761243,%esi + xorl %esi,%ecx + movl $2155905152,%ebp + andl %ecx,%ebp + leal (%ecx,%ecx,1),%edx + movl %ebp,%esi + shrl $7,%ebp + subl %ebp,%esi + andl $4278124286,%edx + andl $454761243,%esi + xorl %ebx,%ecx + xorl %esi,%edx + movl $2155905152,%ebp + andl %edx,%ebp + leal (%edx,%edx,1),%eax + movl %ebp,%esi + shrl $7,%ebp + xorl %ebx,%edx + subl %ebp,%esi + andl $4278124286,%eax + andl $454761243,%esi + roll $8,%ebx + xorl %esi,%eax + movl 8(%edi),%ebp + xorl %ecx,%ebx + xorl %eax,%ecx + xorl %edx,%ebx + roll $24,%ecx + xorl %eax,%edx + xorl %eax,%ebx + roll $16,%edx + xorl %ecx,%ebx + roll $8,%eax + xorl %edx,%ebx + movl %ebp,%ecx + xorl %eax,%ebx + movl %ebx,4(%edi) + movl $2155905152,%ebp + andl %ecx,%ebp + leal (%ecx,%ecx,1),%edx + movl %ebp,%esi + shrl $7,%ebp + subl %ebp,%esi + andl $4278124286,%edx + andl $454761243,%esi + xorl %esi,%edx + movl $2155905152,%ebp + andl %edx,%ebp + leal (%edx,%edx,1),%eax + movl %ebp,%esi + shrl $7,%ebp + subl %ebp,%esi + andl $4278124286,%eax + andl $454761243,%esi + xorl %ecx,%edx + xorl %esi,%eax + movl $2155905152,%ebp + andl %eax,%ebp + leal (%eax,%eax,1),%ebx + movl %ebp,%esi + shrl $7,%ebp + xorl %ecx,%eax + subl %ebp,%esi + andl $4278124286,%ebx + andl $454761243,%esi + roll $8,%ecx + xorl %esi,%ebx + movl 12(%edi),%ebp + xorl %edx,%ecx + xorl %ebx,%edx + xorl %eax,%ecx + roll $24,%edx + xorl %ebx,%eax + xorl %ebx,%ecx + roll $16,%eax + xorl %edx,%ecx + roll $8,%ebx + xorl %eax,%ecx + movl %ebp,%edx + xorl %ebx,%ecx + movl %ecx,8(%edi) + movl $2155905152,%ebp + andl %edx,%ebp + leal (%edx,%edx,1),%eax + movl %ebp,%esi + shrl $7,%ebp + subl %ebp,%esi + andl $4278124286,%eax + andl $454761243,%esi + xorl %esi,%eax + movl $2155905152,%ebp + andl %eax,%ebp + leal (%eax,%eax,1),%ebx + movl %ebp,%esi + shrl $7,%ebp + subl %ebp,%esi + andl $4278124286,%ebx + andl $454761243,%esi + xorl %edx,%eax + xorl %esi,%ebx + movl $2155905152,%ebp + andl %ebx,%ebp + leal (%ebx,%ebx,1),%ecx + movl %ebp,%esi + shrl $7,%ebp + xorl %edx,%ebx + subl %ebp,%esi + andl $4278124286,%ecx + andl $454761243,%esi + roll $8,%edx + xorl %esi,%ecx + movl 16(%edi),%ebp + xorl %eax,%edx + xorl %ecx,%eax + xorl %ebx,%edx + roll $24,%eax + xorl %ecx,%ebx + xorl %ecx,%edx + roll $16,%ebx + xorl %eax,%edx + roll $8,%ecx + xorl %ebx,%edx + movl %ebp,%eax + xorl %ecx,%edx + movl %edx,12(%edi) + cmpl 28(%esp),%edi + jb .L056permute + xorl %eax,%eax + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size AES_set_decrypt_key,.-.L_AES_set_decrypt_key_begin +.byte 65,69,83,32,102,111,114,32,120,56,54,44,32,67,82,89 +.byte 80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114 +.byte 111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/aes/aes-x86_64.S b/crypto/openssl/crypto/aes/aes-x86_64.S new file mode 100644 index 000000000000..1e85beafbe40 --- /dev/null +++ b/crypto/openssl/crypto/aes/aes-x86_64.S @@ -0,0 +1,2679 @@ +.text +.type _x86_64_AES_encrypt,@function +.align 16 +_x86_64_AES_encrypt: +.cfi_startproc + xorl 0(%r15),%eax + xorl 4(%r15),%ebx + xorl 8(%r15),%ecx + xorl 12(%r15),%edx + + movl 240(%r15),%r13d + subl $1,%r13d + jmp .Lenc_loop +.align 16 +.Lenc_loop: + + movzbl %al,%esi + movzbl %bl,%edi + movzbl %cl,%ebp + movl 0(%r14,%rsi,8),%r10d + movl 0(%r14,%rdi,8),%r11d + movl 0(%r14,%rbp,8),%r12d + + movzbl %bh,%esi + movzbl %ch,%edi + movzbl %dl,%ebp + xorl 3(%r14,%rsi,8),%r10d + xorl 3(%r14,%rdi,8),%r11d + movl 0(%r14,%rbp,8),%r8d + + movzbl %dh,%esi + shrl $16,%ecx + movzbl %ah,%ebp + xorl 3(%r14,%rsi,8),%r12d + shrl $16,%edx + xorl 3(%r14,%rbp,8),%r8d + + shrl $16,%ebx + leaq 16(%r15),%r15 + shrl $16,%eax + + movzbl %cl,%esi + movzbl %dl,%edi + movzbl %al,%ebp + xorl 2(%r14,%rsi,8),%r10d + xorl 2(%r14,%rdi,8),%r11d + xorl 2(%r14,%rbp,8),%r12d + + movzbl %dh,%esi + movzbl %ah,%edi + movzbl %bl,%ebp + xorl 1(%r14,%rsi,8),%r10d + xorl 1(%r14,%rdi,8),%r11d + xorl 2(%r14,%rbp,8),%r8d + + movl 12(%r15),%edx + movzbl %bh,%edi + movzbl %ch,%ebp + movl 0(%r15),%eax + xorl 1(%r14,%rdi,8),%r12d + xorl 1(%r14,%rbp,8),%r8d + + movl 4(%r15),%ebx + movl 8(%r15),%ecx + xorl %r10d,%eax + xorl %r11d,%ebx + xorl %r12d,%ecx + xorl %r8d,%edx + subl $1,%r13d + jnz .Lenc_loop + movzbl %al,%esi + movzbl %bl,%edi + movzbl %cl,%ebp + movzbl 2(%r14,%rsi,8),%r10d + movzbl 2(%r14,%rdi,8),%r11d + movzbl 2(%r14,%rbp,8),%r12d + + movzbl %dl,%esi + movzbl %bh,%edi + movzbl %ch,%ebp + movzbl 2(%r14,%rsi,8),%r8d + movl 0(%r14,%rdi,8),%edi + movl 0(%r14,%rbp,8),%ebp + + andl $0x0000ff00,%edi + andl $0x0000ff00,%ebp + + xorl %edi,%r10d + xorl %ebp,%r11d + shrl $16,%ecx + + movzbl %dh,%esi + movzbl %ah,%edi + shrl $16,%edx + movl 0(%r14,%rsi,8),%esi + movl 0(%r14,%rdi,8),%edi + + andl $0x0000ff00,%esi + andl $0x0000ff00,%edi + shrl $16,%ebx + xorl %esi,%r12d + xorl %edi,%r8d + shrl $16,%eax + + movzbl %cl,%esi + movzbl %dl,%edi + movzbl %al,%ebp + movl 0(%r14,%rsi,8),%esi + movl 0(%r14,%rdi,8),%edi + movl 0(%r14,%rbp,8),%ebp + + andl $0x00ff0000,%esi + andl $0x00ff0000,%edi + andl $0x00ff0000,%ebp + + xorl %esi,%r10d + xorl %edi,%r11d + xorl %ebp,%r12d + + movzbl %bl,%esi + movzbl %dh,%edi + movzbl %ah,%ebp + movl 0(%r14,%rsi,8),%esi + movl 2(%r14,%rdi,8),%edi + movl 2(%r14,%rbp,8),%ebp + + andl $0x00ff0000,%esi + andl $0xff000000,%edi + andl $0xff000000,%ebp + + xorl %esi,%r8d + xorl %edi,%r10d + xorl %ebp,%r11d + + movzbl %bh,%esi + movzbl %ch,%edi + movl 16+12(%r15),%edx + movl 2(%r14,%rsi,8),%esi + movl 2(%r14,%rdi,8),%edi + movl 16+0(%r15),%eax + + andl $0xff000000,%esi + andl $0xff000000,%edi + + xorl %esi,%r12d + xorl %edi,%r8d + + movl 16+4(%r15),%ebx + movl 16+8(%r15),%ecx + xorl %r10d,%eax + xorl %r11d,%ebx + xorl %r12d,%ecx + xorl %r8d,%edx +.byte 0xf3,0xc3 +.cfi_endproc +.size _x86_64_AES_encrypt,.-_x86_64_AES_encrypt +.type _x86_64_AES_encrypt_compact,@function +.align 16 +_x86_64_AES_encrypt_compact: +.cfi_startproc + leaq 128(%r14),%r8 + movl 0-128(%r8),%edi + movl 32-128(%r8),%ebp + movl 64-128(%r8),%r10d + movl 96-128(%r8),%r11d + movl 128-128(%r8),%edi + movl 160-128(%r8),%ebp + movl 192-128(%r8),%r10d + movl 224-128(%r8),%r11d + jmp .Lenc_loop_compact +.align 16 +.Lenc_loop_compact: + xorl 0(%r15),%eax + xorl 4(%r15),%ebx + xorl 8(%r15),%ecx + xorl 12(%r15),%edx + leaq 16(%r15),%r15 + movzbl %al,%r10d + movzbl %bl,%r11d + movzbl %cl,%r12d + movzbl %dl,%r8d + movzbl %bh,%esi + movzbl %ch,%edi + shrl $16,%ecx + movzbl %dh,%ebp + movzbl (%r14,%r10,1),%r10d + movzbl (%r14,%r11,1),%r11d + movzbl (%r14,%r12,1),%r12d + movzbl (%r14,%r8,1),%r8d + + movzbl (%r14,%rsi,1),%r9d + movzbl %ah,%esi + movzbl (%r14,%rdi,1),%r13d + movzbl %cl,%edi + movzbl (%r14,%rbp,1),%ebp + movzbl (%r14,%rsi,1),%esi + + shll $8,%r9d + shrl $16,%edx + shll $8,%r13d + xorl %r9d,%r10d + shrl $16,%eax + movzbl %dl,%r9d + shrl $16,%ebx + xorl %r13d,%r11d + shll $8,%ebp + movzbl %al,%r13d + movzbl (%r14,%rdi,1),%edi + xorl %ebp,%r12d + + shll $8,%esi + movzbl %bl,%ebp + shll $16,%edi + xorl %esi,%r8d + movzbl (%r14,%r9,1),%r9d + movzbl %dh,%esi + movzbl (%r14,%r13,1),%r13d + xorl %edi,%r10d + + shrl $8,%ecx + movzbl %ah,%edi + shll $16,%r9d + shrl $8,%ebx + shll $16,%r13d + xorl %r9d,%r11d + movzbl (%r14,%rbp,1),%ebp + movzbl (%r14,%rsi,1),%esi + movzbl (%r14,%rdi,1),%edi + movzbl (%r14,%rcx,1),%edx + movzbl (%r14,%rbx,1),%ecx + + shll $16,%ebp + xorl %r13d,%r12d + shll $24,%esi + xorl %ebp,%r8d + shll $24,%edi + xorl %esi,%r10d + shll $24,%edx + xorl %edi,%r11d + shll $24,%ecx + movl %r10d,%eax + movl %r11d,%ebx + xorl %r12d,%ecx + xorl %r8d,%edx + cmpq 16(%rsp),%r15 + je .Lenc_compact_done + movl $0x80808080,%r10d + movl $0x80808080,%r11d + andl %eax,%r10d + andl %ebx,%r11d + movl %r10d,%esi + movl %r11d,%edi + shrl $7,%r10d + leal (%rax,%rax,1),%r8d + shrl $7,%r11d + leal (%rbx,%rbx,1),%r9d + subl %r10d,%esi + subl %r11d,%edi + andl $0xfefefefe,%r8d + andl $0xfefefefe,%r9d + andl $0x1b1b1b1b,%esi + andl $0x1b1b1b1b,%edi + movl %eax,%r10d + movl %ebx,%r11d + xorl %esi,%r8d + xorl %edi,%r9d + + xorl %r8d,%eax + xorl %r9d,%ebx + movl $0x80808080,%r12d + roll $24,%eax + movl $0x80808080,%ebp + roll $24,%ebx + andl %ecx,%r12d + andl %edx,%ebp + xorl %r8d,%eax + xorl %r9d,%ebx + movl %r12d,%esi + rorl $16,%r10d + movl %ebp,%edi + rorl $16,%r11d + leal (%rcx,%rcx,1),%r8d + shrl $7,%r12d + xorl %r10d,%eax + shrl $7,%ebp + xorl %r11d,%ebx + rorl $8,%r10d + leal (%rdx,%rdx,1),%r9d + rorl $8,%r11d + subl %r12d,%esi + subl %ebp,%edi + xorl %r10d,%eax + xorl %r11d,%ebx + + andl $0xfefefefe,%r8d + andl $0xfefefefe,%r9d + andl $0x1b1b1b1b,%esi + andl $0x1b1b1b1b,%edi + movl %ecx,%r12d + movl %edx,%ebp + xorl %esi,%r8d + xorl %edi,%r9d + + rorl $16,%r12d + xorl %r8d,%ecx + rorl $16,%ebp + xorl %r9d,%edx + roll $24,%ecx + movl 0(%r14),%esi + roll $24,%edx + xorl %r8d,%ecx + movl 64(%r14),%edi + xorl %r9d,%edx + movl 128(%r14),%r8d + xorl %r12d,%ecx + rorl $8,%r12d + xorl %ebp,%edx + rorl $8,%ebp + xorl %r12d,%ecx + movl 192(%r14),%r9d + xorl %ebp,%edx + jmp .Lenc_loop_compact +.align 16 +.Lenc_compact_done: + xorl 0(%r15),%eax + xorl 4(%r15),%ebx + xorl 8(%r15),%ecx + xorl 12(%r15),%edx +.byte 0xf3,0xc3 +.cfi_endproc +.size _x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact +.globl AES_encrypt +.type AES_encrypt,@function +.align 16 +.globl asm_AES_encrypt +.hidden asm_AES_encrypt +asm_AES_encrypt: +AES_encrypt: +.cfi_startproc +.byte 243,15,30,250 + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + + leaq -63(%rdx),%rcx + andq $-64,%rsp + subq %rsp,%rcx + negq %rcx + andq $0x3c0,%rcx + subq %rcx,%rsp + subq $32,%rsp + + movq %rsi,16(%rsp) + movq %rax,24(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x18,0x06,0x23,0x08 +.Lenc_prologue: + + movq %rdx,%r15 + movl 240(%r15),%r13d + + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + + shll $4,%r13d + leaq (%r15,%r13,1),%rbp + movq %r15,(%rsp) + movq %rbp,8(%rsp) + + + leaq .LAES_Te+2048(%rip),%r14 + leaq 768(%rsp),%rbp + subq %r14,%rbp + andq $0x300,%rbp + leaq (%r14,%rbp,1),%r14 + + call _x86_64_AES_encrypt_compact + + movq 16(%rsp),%r9 + movq 24(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movl %eax,0(%r9) + movl %ebx,4(%r9) + movl %ecx,8(%r9) + movl %edx,12(%r9) + + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lenc_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size AES_encrypt,.-AES_encrypt +.type _x86_64_AES_decrypt,@function +.align 16 +_x86_64_AES_decrypt: +.cfi_startproc + xorl 0(%r15),%eax + xorl 4(%r15),%ebx + xorl 8(%r15),%ecx + xorl 12(%r15),%edx + + movl 240(%r15),%r13d + subl $1,%r13d + jmp .Ldec_loop +.align 16 +.Ldec_loop: + + movzbl %al,%esi + movzbl %bl,%edi + movzbl %cl,%ebp + movl 0(%r14,%rsi,8),%r10d + movl 0(%r14,%rdi,8),%r11d + movl 0(%r14,%rbp,8),%r12d + + movzbl %dh,%esi + movzbl %ah,%edi + movzbl %dl,%ebp + xorl 3(%r14,%rsi,8),%r10d + xorl 3(%r14,%rdi,8),%r11d + movl 0(%r14,%rbp,8),%r8d + + movzbl %bh,%esi + shrl $16,%eax + movzbl %ch,%ebp + xorl 3(%r14,%rsi,8),%r12d + shrl $16,%edx + xorl 3(%r14,%rbp,8),%r8d + + shrl $16,%ebx + leaq 16(%r15),%r15 + shrl $16,%ecx + + movzbl %cl,%esi + movzbl %dl,%edi + movzbl %al,%ebp + xorl 2(%r14,%rsi,8),%r10d + xorl 2(%r14,%rdi,8),%r11d + xorl 2(%r14,%rbp,8),%r12d + + movzbl %bh,%esi + movzbl %ch,%edi + movzbl %bl,%ebp + xorl 1(%r14,%rsi,8),%r10d + xorl 1(%r14,%rdi,8),%r11d + xorl 2(%r14,%rbp,8),%r8d + + movzbl %dh,%esi + movl 12(%r15),%edx + movzbl %ah,%ebp + xorl 1(%r14,%rsi,8),%r12d + movl 0(%r15),%eax + xorl 1(%r14,%rbp,8),%r8d + + xorl %r10d,%eax + movl 4(%r15),%ebx + movl 8(%r15),%ecx + xorl %r12d,%ecx + xorl %r11d,%ebx + xorl %r8d,%edx + subl $1,%r13d + jnz .Ldec_loop + leaq 2048(%r14),%r14 + movzbl %al,%esi + movzbl %bl,%edi + movzbl %cl,%ebp + movzbl (%r14,%rsi,1),%r10d + movzbl (%r14,%rdi,1),%r11d + movzbl (%r14,%rbp,1),%r12d + + movzbl %dl,%esi + movzbl %dh,%edi + movzbl %ah,%ebp + movzbl (%r14,%rsi,1),%r8d + movzbl (%r14,%rdi,1),%edi + movzbl (%r14,%rbp,1),%ebp + + shll $8,%edi + shll $8,%ebp + + xorl %edi,%r10d + xorl %ebp,%r11d + shrl $16,%edx + + movzbl %bh,%esi + movzbl %ch,%edi + shrl $16,%eax + movzbl (%r14,%rsi,1),%esi + movzbl (%r14,%rdi,1),%edi + + shll $8,%esi + shll $8,%edi + shrl $16,%ebx + xorl %esi,%r12d + xorl %edi,%r8d + shrl $16,%ecx + + movzbl %cl,%esi + movzbl %dl,%edi + movzbl %al,%ebp + movzbl (%r14,%rsi,1),%esi + movzbl (%r14,%rdi,1),%edi + movzbl (%r14,%rbp,1),%ebp + + shll $16,%esi + shll $16,%edi + shll $16,%ebp + + xorl %esi,%r10d + xorl %edi,%r11d + xorl %ebp,%r12d + + movzbl %bl,%esi + movzbl %bh,%edi + movzbl %ch,%ebp + movzbl (%r14,%rsi,1),%esi + movzbl (%r14,%rdi,1),%edi + movzbl (%r14,%rbp,1),%ebp + + shll $16,%esi + shll $24,%edi + shll $24,%ebp + + xorl %esi,%r8d + xorl %edi,%r10d + xorl %ebp,%r11d + + movzbl %dh,%esi + movzbl %ah,%edi + movl 16+12(%r15),%edx + movzbl (%r14,%rsi,1),%esi + movzbl (%r14,%rdi,1),%edi + movl 16+0(%r15),%eax + + shll $24,%esi + shll $24,%edi + + xorl %esi,%r12d + xorl %edi,%r8d + + movl 16+4(%r15),%ebx + movl 16+8(%r15),%ecx + leaq -2048(%r14),%r14 + xorl %r10d,%eax + xorl %r11d,%ebx + xorl %r12d,%ecx + xorl %r8d,%edx +.byte 0xf3,0xc3 +.cfi_endproc +.size _x86_64_AES_decrypt,.-_x86_64_AES_decrypt +.type _x86_64_AES_decrypt_compact,@function +.align 16 +_x86_64_AES_decrypt_compact: +.cfi_startproc + leaq 128(%r14),%r8 + movl 0-128(%r8),%edi + movl 32-128(%r8),%ebp + movl 64-128(%r8),%r10d + movl 96-128(%r8),%r11d + movl 128-128(%r8),%edi + movl 160-128(%r8),%ebp + movl 192-128(%r8),%r10d + movl 224-128(%r8),%r11d + jmp .Ldec_loop_compact + +.align 16 +.Ldec_loop_compact: + xorl 0(%r15),%eax + xorl 4(%r15),%ebx + xorl 8(%r15),%ecx + xorl 12(%r15),%edx + leaq 16(%r15),%r15 + movzbl %al,%r10d + movzbl %bl,%r11d + movzbl %cl,%r12d + movzbl %dl,%r8d + movzbl %dh,%esi + movzbl %ah,%edi + shrl $16,%edx + movzbl %bh,%ebp + movzbl (%r14,%r10,1),%r10d + movzbl (%r14,%r11,1),%r11d + movzbl (%r14,%r12,1),%r12d + movzbl (%r14,%r8,1),%r8d + + movzbl (%r14,%rsi,1),%r9d + movzbl %ch,%esi + movzbl (%r14,%rdi,1),%r13d + movzbl (%r14,%rbp,1),%ebp + movzbl (%r14,%rsi,1),%esi + + shrl $16,%ecx + shll $8,%r13d + shll $8,%r9d + movzbl %cl,%edi + shrl $16,%eax + xorl %r9d,%r10d + shrl $16,%ebx + movzbl %dl,%r9d + + shll $8,%ebp + xorl %r13d,%r11d + shll $8,%esi + movzbl %al,%r13d + movzbl (%r14,%rdi,1),%edi + xorl %ebp,%r12d + movzbl %bl,%ebp + + shll $16,%edi + xorl %esi,%r8d + movzbl (%r14,%r9,1),%r9d + movzbl %bh,%esi + movzbl (%r14,%rbp,1),%ebp + xorl %edi,%r10d + movzbl (%r14,%r13,1),%r13d + movzbl %ch,%edi + + shll $16,%ebp + shll $16,%r9d + shll $16,%r13d + xorl %ebp,%r8d + movzbl %dh,%ebp + xorl %r9d,%r11d + shrl $8,%eax + xorl %r13d,%r12d + + movzbl (%r14,%rsi,1),%esi + movzbl (%r14,%rdi,1),%ebx + movzbl (%r14,%rbp,1),%ecx + movzbl (%r14,%rax,1),%edx + + movl %r10d,%eax + shll $24,%esi + shll $24,%ebx + shll $24,%ecx + xorl %esi,%eax + shll $24,%edx + xorl %r11d,%ebx + xorl %r12d,%ecx + xorl %r8d,%edx + cmpq 16(%rsp),%r15 + je .Ldec_compact_done + + movq 256+0(%r14),%rsi + shlq $32,%rbx + shlq $32,%rdx + movq 256+8(%r14),%rdi + orq %rbx,%rax + orq %rdx,%rcx + movq 256+16(%r14),%rbp + movq %rsi,%r9 + movq %rsi,%r12 + andq %rax,%r9 + andq %rcx,%r12 + movq %r9,%rbx + movq %r12,%rdx + shrq $7,%r9 + leaq (%rax,%rax,1),%r8 + shrq $7,%r12 + leaq (%rcx,%rcx,1),%r11 + subq %r9,%rbx + subq %r12,%rdx + andq %rdi,%r8 + andq %rdi,%r11 + andq %rbp,%rbx + andq %rbp,%rdx + xorq %rbx,%r8 + xorq %rdx,%r11 + movq %rsi,%r10 + movq %rsi,%r13 + + andq %r8,%r10 + andq %r11,%r13 + movq %r10,%rbx + movq %r13,%rdx + shrq $7,%r10 + leaq (%r8,%r8,1),%r9 + shrq $7,%r13 + leaq (%r11,%r11,1),%r12 + subq %r10,%rbx + subq %r13,%rdx + andq %rdi,%r9 + andq %rdi,%r12 + andq %rbp,%rbx + andq %rbp,%rdx + xorq %rbx,%r9 + xorq %rdx,%r12 + movq %rsi,%r10 + movq %rsi,%r13 + + andq %r9,%r10 + andq %r12,%r13 + movq %r10,%rbx + movq %r13,%rdx + shrq $7,%r10 + xorq %rax,%r8 + shrq $7,%r13 + xorq %rcx,%r11 + subq %r10,%rbx + subq %r13,%rdx + leaq (%r9,%r9,1),%r10 + leaq (%r12,%r12,1),%r13 + xorq %rax,%r9 + xorq %rcx,%r12 + andq %rdi,%r10 + andq %rdi,%r13 + andq %rbp,%rbx + andq %rbp,%rdx + xorq %rbx,%r10 + xorq %rdx,%r13 + + xorq %r10,%rax + xorq %r13,%rcx + xorq %r10,%r8 + xorq %r13,%r11 + movq %rax,%rbx + movq %rcx,%rdx + xorq %r10,%r9 + shrq $32,%rbx + xorq %r13,%r12 + shrq $32,%rdx + xorq %r8,%r10 + roll $8,%eax + xorq %r11,%r13 + roll $8,%ecx + xorq %r9,%r10 + roll $8,%ebx + xorq %r12,%r13 + + roll $8,%edx + xorl %r10d,%eax + shrq $32,%r10 + xorl %r13d,%ecx + shrq $32,%r13 + xorl %r10d,%ebx + xorl %r13d,%edx + + movq %r8,%r10 + roll $24,%r8d + movq %r11,%r13 + roll $24,%r11d + shrq $32,%r10 + xorl %r8d,%eax + shrq $32,%r13 + xorl %r11d,%ecx + roll $24,%r10d + movq %r9,%r8 + roll $24,%r13d + movq %r12,%r11 + shrq $32,%r8 + xorl %r10d,%ebx + shrq $32,%r11 + xorl %r13d,%edx + + movq 0(%r14),%rsi + roll $16,%r9d + movq 64(%r14),%rdi + roll $16,%r12d + movq 128(%r14),%rbp + roll $16,%r8d + movq 192(%r14),%r10 + xorl %r9d,%eax + roll $16,%r11d + xorl %r12d,%ecx + movq 256(%r14),%r13 + xorl %r8d,%ebx + xorl %r11d,%edx + jmp .Ldec_loop_compact +.align 16 +.Ldec_compact_done: + xorl 0(%r15),%eax + xorl 4(%r15),%ebx + xorl 8(%r15),%ecx + xorl 12(%r15),%edx +.byte 0xf3,0xc3 +.cfi_endproc +.size _x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact +.globl AES_decrypt +.type AES_decrypt,@function +.align 16 +.globl asm_AES_decrypt +.hidden asm_AES_decrypt +asm_AES_decrypt: +AES_decrypt: +.cfi_startproc +.byte 243,15,30,250 + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + + leaq -63(%rdx),%rcx + andq $-64,%rsp + subq %rsp,%rcx + negq %rcx + andq $0x3c0,%rcx + subq %rcx,%rsp + subq $32,%rsp + + movq %rsi,16(%rsp) + movq %rax,24(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x18,0x06,0x23,0x08 +.Ldec_prologue: + + movq %rdx,%r15 + movl 240(%r15),%r13d + + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + + shll $4,%r13d + leaq (%r15,%r13,1),%rbp + movq %r15,(%rsp) + movq %rbp,8(%rsp) + + + leaq .LAES_Td+2048(%rip),%r14 + leaq 768(%rsp),%rbp + subq %r14,%rbp + andq $0x300,%rbp + leaq (%r14,%rbp,1),%r14 + shrq $3,%rbp + addq %rbp,%r14 + + call _x86_64_AES_decrypt_compact + + movq 16(%rsp),%r9 + movq 24(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movl %eax,0(%r9) + movl %ebx,4(%r9) + movl %ecx,8(%r9) + movl %edx,12(%r9) + + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Ldec_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size AES_decrypt,.-AES_decrypt +.globl AES_set_encrypt_key +.type AES_set_encrypt_key,@function +.align 16 +AES_set_encrypt_key: +.cfi_startproc +.byte 243,15,30,250 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $8,%rsp +.cfi_adjust_cfa_offset 8 +.Lenc_key_prologue: + + call _x86_64_AES_set_encrypt_key + + movq 40(%rsp),%rbp +.cfi_restore %rbp + movq 48(%rsp),%rbx +.cfi_restore %rbx + addq $56,%rsp +.cfi_adjust_cfa_offset -56 +.Lenc_key_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size AES_set_encrypt_key,.-AES_set_encrypt_key + +.type _x86_64_AES_set_encrypt_key,@function +.align 16 +_x86_64_AES_set_encrypt_key: +.cfi_startproc + movl %esi,%ecx + movq %rdi,%rsi + movq %rdx,%rdi + + testq $-1,%rsi + jz .Lbadpointer + testq $-1,%rdi + jz .Lbadpointer + + leaq .LAES_Te(%rip),%rbp + leaq 2048+128(%rbp),%rbp + + + movl 0-128(%rbp),%eax + movl 32-128(%rbp),%ebx + movl 64-128(%rbp),%r8d + movl 96-128(%rbp),%edx + movl 128-128(%rbp),%eax + movl 160-128(%rbp),%ebx + movl 192-128(%rbp),%r8d + movl 224-128(%rbp),%edx + + cmpl $128,%ecx + je .L10rounds + cmpl $192,%ecx + je .L12rounds + cmpl $256,%ecx + je .L14rounds + movq $-2,%rax + jmp .Lexit + +.L10rounds: + movq 0(%rsi),%rax + movq 8(%rsi),%rdx + movq %rax,0(%rdi) + movq %rdx,8(%rdi) + + shrq $32,%rdx + xorl %ecx,%ecx + jmp .L10shortcut +.align 4 +.L10loop: + movl 0(%rdi),%eax + movl 12(%rdi),%edx +.L10shortcut: + movzbl %dl,%esi + movzbl -128(%rbp,%rsi,1),%ebx + movzbl %dh,%esi + shll $24,%ebx + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + shrl $16,%edx + movzbl %dl,%esi + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + movzbl %dh,%esi + shll $8,%ebx + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + shll $16,%ebx + xorl %ebx,%eax + + xorl 1024-128(%rbp,%rcx,4),%eax + movl %eax,16(%rdi) + xorl 4(%rdi),%eax + movl %eax,20(%rdi) + xorl 8(%rdi),%eax + movl %eax,24(%rdi) + xorl 12(%rdi),%eax + movl %eax,28(%rdi) + addl $1,%ecx + leaq 16(%rdi),%rdi + cmpl $10,%ecx + jl .L10loop + + movl $10,80(%rdi) + xorq %rax,%rax + jmp .Lexit + +.L12rounds: + movq 0(%rsi),%rax + movq 8(%rsi),%rbx + movq 16(%rsi),%rdx + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rdx,16(%rdi) + + shrq $32,%rdx + xorl %ecx,%ecx + jmp .L12shortcut +.align 4 +.L12loop: + movl 0(%rdi),%eax + movl 20(%rdi),%edx +.L12shortcut: + movzbl %dl,%esi + movzbl -128(%rbp,%rsi,1),%ebx + movzbl %dh,%esi + shll $24,%ebx + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + shrl $16,%edx + movzbl %dl,%esi + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + movzbl %dh,%esi + shll $8,%ebx + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + shll $16,%ebx + xorl %ebx,%eax + + xorl 1024-128(%rbp,%rcx,4),%eax + movl %eax,24(%rdi) + xorl 4(%rdi),%eax + movl %eax,28(%rdi) + xorl 8(%rdi),%eax + movl %eax,32(%rdi) + xorl 12(%rdi),%eax + movl %eax,36(%rdi) + + cmpl $7,%ecx + je .L12break + addl $1,%ecx + + xorl 16(%rdi),%eax + movl %eax,40(%rdi) + xorl 20(%rdi),%eax + movl %eax,44(%rdi) + + leaq 24(%rdi),%rdi + jmp .L12loop +.L12break: + movl $12,72(%rdi) + xorq %rax,%rax + jmp .Lexit + +.L14rounds: + movq 0(%rsi),%rax + movq 8(%rsi),%rbx + movq 16(%rsi),%rcx + movq 24(%rsi),%rdx + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + + shrq $32,%rdx + xorl %ecx,%ecx + jmp .L14shortcut +.align 4 +.L14loop: + movl 0(%rdi),%eax + movl 28(%rdi),%edx +.L14shortcut: + movzbl %dl,%esi + movzbl -128(%rbp,%rsi,1),%ebx + movzbl %dh,%esi + shll $24,%ebx + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + shrl $16,%edx + movzbl %dl,%esi + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + movzbl %dh,%esi + shll $8,%ebx + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + shll $16,%ebx + xorl %ebx,%eax + + xorl 1024-128(%rbp,%rcx,4),%eax + movl %eax,32(%rdi) + xorl 4(%rdi),%eax + movl %eax,36(%rdi) + xorl 8(%rdi),%eax + movl %eax,40(%rdi) + xorl 12(%rdi),%eax + movl %eax,44(%rdi) + + cmpl $6,%ecx + je .L14break + addl $1,%ecx + + movl %eax,%edx + movl 16(%rdi),%eax + movzbl %dl,%esi + movzbl -128(%rbp,%rsi,1),%ebx + movzbl %dh,%esi + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + shrl $16,%edx + shll $8,%ebx + movzbl %dl,%esi + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + movzbl %dh,%esi + shll $16,%ebx + xorl %ebx,%eax + + movzbl -128(%rbp,%rsi,1),%ebx + shll $24,%ebx + xorl %ebx,%eax + + movl %eax,48(%rdi) + xorl 20(%rdi),%eax + movl %eax,52(%rdi) + xorl 24(%rdi),%eax + movl %eax,56(%rdi) + xorl 28(%rdi),%eax + movl %eax,60(%rdi) + + leaq 32(%rdi),%rdi + jmp .L14loop +.L14break: + movl $14,48(%rdi) + xorq %rax,%rax + jmp .Lexit + +.Lbadpointer: + movq $-1,%rax +.Lexit: +.byte 0xf3,0xc3 +.cfi_endproc +.size _x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key +.globl AES_set_decrypt_key +.type AES_set_decrypt_key,@function +.align 16 +AES_set_decrypt_key: +.cfi_startproc +.byte 243,15,30,250 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + pushq %rdx +.cfi_adjust_cfa_offset 8 +.Ldec_key_prologue: + + call _x86_64_AES_set_encrypt_key + movq (%rsp),%r8 + cmpl $0,%eax + jne .Labort + + movl 240(%r8),%r14d + xorq %rdi,%rdi + leaq (%rdi,%r14,4),%rcx + movq %r8,%rsi + leaq (%r8,%rcx,4),%rdi +.align 4 +.Linvert: + movq 0(%rsi),%rax + movq 8(%rsi),%rbx + movq 0(%rdi),%rcx + movq 8(%rdi),%rdx + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,0(%rsi) + movq %rdx,8(%rsi) + leaq 16(%rsi),%rsi + leaq -16(%rdi),%rdi + cmpq %rsi,%rdi + jne .Linvert + + leaq .LAES_Te+2048+1024(%rip),%rax + + movq 40(%rax),%rsi + movq 48(%rax),%rdi + movq 56(%rax),%rbp + + movq %r8,%r15 + subl $1,%r14d +.align 4 +.Lpermute: + leaq 16(%r15),%r15 + movq 0(%r15),%rax + movq 8(%r15),%rcx + movq %rsi,%r9 + movq %rsi,%r12 + andq %rax,%r9 + andq %rcx,%r12 + movq %r9,%rbx + movq %r12,%rdx + shrq $7,%r9 + leaq (%rax,%rax,1),%r8 + shrq $7,%r12 + leaq (%rcx,%rcx,1),%r11 + subq %r9,%rbx + subq %r12,%rdx + andq %rdi,%r8 + andq %rdi,%r11 + andq %rbp,%rbx + andq %rbp,%rdx + xorq %rbx,%r8 + xorq %rdx,%r11 + movq %rsi,%r10 + movq %rsi,%r13 + + andq %r8,%r10 + andq %r11,%r13 + movq %r10,%rbx + movq %r13,%rdx + shrq $7,%r10 + leaq (%r8,%r8,1),%r9 + shrq $7,%r13 + leaq (%r11,%r11,1),%r12 + subq %r10,%rbx + subq %r13,%rdx + andq %rdi,%r9 + andq %rdi,%r12 + andq %rbp,%rbx + andq %rbp,%rdx + xorq %rbx,%r9 + xorq %rdx,%r12 + movq %rsi,%r10 + movq %rsi,%r13 + + andq %r9,%r10 + andq %r12,%r13 + movq %r10,%rbx + movq %r13,%rdx + shrq $7,%r10 + xorq %rax,%r8 + shrq $7,%r13 + xorq %rcx,%r11 + subq %r10,%rbx + subq %r13,%rdx + leaq (%r9,%r9,1),%r10 + leaq (%r12,%r12,1),%r13 + xorq %rax,%r9 + xorq %rcx,%r12 + andq %rdi,%r10 + andq %rdi,%r13 + andq %rbp,%rbx + andq %rbp,%rdx + xorq %rbx,%r10 + xorq %rdx,%r13 + + xorq %r10,%rax + xorq %r13,%rcx + xorq %r10,%r8 + xorq %r13,%r11 + movq %rax,%rbx + movq %rcx,%rdx + xorq %r10,%r9 + shrq $32,%rbx + xorq %r13,%r12 + shrq $32,%rdx + xorq %r8,%r10 + roll $8,%eax + xorq %r11,%r13 + roll $8,%ecx + xorq %r9,%r10 + roll $8,%ebx + xorq %r12,%r13 + + roll $8,%edx + xorl %r10d,%eax + shrq $32,%r10 + xorl %r13d,%ecx + shrq $32,%r13 + xorl %r10d,%ebx + xorl %r13d,%edx + + movq %r8,%r10 + roll $24,%r8d + movq %r11,%r13 + roll $24,%r11d + shrq $32,%r10 + xorl %r8d,%eax + shrq $32,%r13 + xorl %r11d,%ecx + roll $24,%r10d + movq %r9,%r8 + roll $24,%r13d + movq %r12,%r11 + shrq $32,%r8 + xorl %r10d,%ebx + shrq $32,%r11 + xorl %r13d,%edx + + + roll $16,%r9d + + roll $16,%r12d + + roll $16,%r8d + + xorl %r9d,%eax + roll $16,%r11d + xorl %r12d,%ecx + + xorl %r8d,%ebx + xorl %r11d,%edx + movl %eax,0(%r15) + movl %ebx,4(%r15) + movl %ecx,8(%r15) + movl %edx,12(%r15) + subl $1,%r14d + jnz .Lpermute + + xorq %rax,%rax +.Labort: + movq 8(%rsp),%r15 +.cfi_restore %r15 + movq 16(%rsp),%r14 +.cfi_restore %r14 + movq 24(%rsp),%r13 +.cfi_restore %r13 + movq 32(%rsp),%r12 +.cfi_restore %r12 + movq 40(%rsp),%rbp +.cfi_restore %rbp + movq 48(%rsp),%rbx +.cfi_restore %rbx + addq $56,%rsp +.cfi_adjust_cfa_offset -56 +.Ldec_key_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size AES_set_decrypt_key,.-AES_set_decrypt_key +.globl AES_cbc_encrypt +.type AES_cbc_encrypt,@function +.align 16 + +.globl asm_AES_cbc_encrypt +.hidden asm_AES_cbc_encrypt +asm_AES_cbc_encrypt: +AES_cbc_encrypt: +.cfi_startproc +.byte 243,15,30,250 + cmpq $0,%rdx + je .Lcbc_epilogue + pushfq + + +.cfi_adjust_cfa_offset 8 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-32 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-40 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-48 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-56 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-64 +.Lcbc_prologue: + + cld + movl %r9d,%r9d + + leaq .LAES_Te(%rip),%r14 + leaq .LAES_Td(%rip),%r10 + cmpq $0,%r9 + cmoveq %r10,%r14 + +.cfi_remember_state + movl OPENSSL_ia32cap_P(%rip),%r10d + cmpq $512,%rdx + jb .Lcbc_slow_prologue + testq $15,%rdx + jnz .Lcbc_slow_prologue + btl $28,%r10d + jc .Lcbc_slow_prologue + + + leaq -88-248(%rsp),%r15 + andq $-64,%r15 + + + movq %r14,%r10 + leaq 2304(%r14),%r11 + movq %r15,%r12 + andq $0xFFF,%r10 + andq $0xFFF,%r11 + andq $0xFFF,%r12 + + cmpq %r11,%r12 + jb .Lcbc_te_break_out + subq %r11,%r12 + subq %r12,%r15 + jmp .Lcbc_te_ok +.Lcbc_te_break_out: + subq %r10,%r12 + andq $0xFFF,%r12 + addq $320,%r12 + subq %r12,%r15 +.align 4 +.Lcbc_te_ok: + + xchgq %rsp,%r15 +.cfi_def_cfa_register %r15 + + movq %r15,16(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x10,0x06,0x23,0x40 +.Lcbc_fast_body: + movq %rdi,24(%rsp) + movq %rsi,32(%rsp) + movq %rdx,40(%rsp) + movq %rcx,48(%rsp) + movq %r8,56(%rsp) + movl $0,80+240(%rsp) + movq %r8,%rbp + movq %r9,%rbx + movq %rsi,%r9 + movq %rdi,%r8 + movq %rcx,%r15 + + movl 240(%r15),%eax + + movq %r15,%r10 + subq %r14,%r10 + andq $0xfff,%r10 + cmpq $2304,%r10 + jb .Lcbc_do_ecopy + cmpq $4096-248,%r10 + jb .Lcbc_skip_ecopy +.align 4 +.Lcbc_do_ecopy: + movq %r15,%rsi + leaq 80(%rsp),%rdi + leaq 80(%rsp),%r15 + movl $30,%ecx +.long 0x90A548F3 + movl %eax,(%rdi) +.Lcbc_skip_ecopy: + movq %r15,0(%rsp) + + movl $18,%ecx +.align 4 +.Lcbc_prefetch_te: + movq 0(%r14),%r10 + movq 32(%r14),%r11 + movq 64(%r14),%r12 + movq 96(%r14),%r13 + leaq 128(%r14),%r14 + subl $1,%ecx + jnz .Lcbc_prefetch_te + leaq -2304(%r14),%r14 + + cmpq $0,%rbx + je .LFAST_DECRYPT + + + movl 0(%rbp),%eax + movl 4(%rbp),%ebx + movl 8(%rbp),%ecx + movl 12(%rbp),%edx + +.align 4 +.Lcbc_fast_enc_loop: + xorl 0(%r8),%eax + xorl 4(%r8),%ebx + xorl 8(%r8),%ecx + xorl 12(%r8),%edx + movq 0(%rsp),%r15 + movq %r8,24(%rsp) + + call _x86_64_AES_encrypt + + movq 24(%rsp),%r8 + movq 40(%rsp),%r10 + movl %eax,0(%r9) + movl %ebx,4(%r9) + movl %ecx,8(%r9) + movl %edx,12(%r9) + + leaq 16(%r8),%r8 + leaq 16(%r9),%r9 + subq $16,%r10 + testq $-16,%r10 + movq %r10,40(%rsp) + jnz .Lcbc_fast_enc_loop + movq 56(%rsp),%rbp + movl %eax,0(%rbp) + movl %ebx,4(%rbp) + movl %ecx,8(%rbp) + movl %edx,12(%rbp) + + jmp .Lcbc_fast_cleanup + + +.align 16 +.LFAST_DECRYPT: + cmpq %r8,%r9 + je .Lcbc_fast_dec_in_place + + movq %rbp,64(%rsp) +.align 4 +.Lcbc_fast_dec_loop: + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movq 0(%rsp),%r15 + movq %r8,24(%rsp) + + call _x86_64_AES_decrypt + + movq 64(%rsp),%rbp + movq 24(%rsp),%r8 + movq 40(%rsp),%r10 + xorl 0(%rbp),%eax + xorl 4(%rbp),%ebx + xorl 8(%rbp),%ecx + xorl 12(%rbp),%edx + movq %r8,%rbp + + subq $16,%r10 + movq %r10,40(%rsp) + movq %rbp,64(%rsp) + + movl %eax,0(%r9) + movl %ebx,4(%r9) + movl %ecx,8(%r9) + movl %edx,12(%r9) + + leaq 16(%r8),%r8 + leaq 16(%r9),%r9 + jnz .Lcbc_fast_dec_loop + movq 56(%rsp),%r12 + movq 0(%rbp),%r10 + movq 8(%rbp),%r11 + movq %r10,0(%r12) + movq %r11,8(%r12) + jmp .Lcbc_fast_cleanup + +.align 16 +.Lcbc_fast_dec_in_place: + movq 0(%rbp),%r10 + movq 8(%rbp),%r11 + movq %r10,0+64(%rsp) + movq %r11,8+64(%rsp) +.align 4 +.Lcbc_fast_dec_in_place_loop: + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movq 0(%rsp),%r15 + movq %r8,24(%rsp) + + call _x86_64_AES_decrypt + + movq 24(%rsp),%r8 + movq 40(%rsp),%r10 + xorl 0+64(%rsp),%eax + xorl 4+64(%rsp),%ebx + xorl 8+64(%rsp),%ecx + xorl 12+64(%rsp),%edx + + movq 0(%r8),%r11 + movq 8(%r8),%r12 + subq $16,%r10 + jz .Lcbc_fast_dec_in_place_done + + movq %r11,0+64(%rsp) + movq %r12,8+64(%rsp) + + movl %eax,0(%r9) + movl %ebx,4(%r9) + movl %ecx,8(%r9) + movl %edx,12(%r9) + + leaq 16(%r8),%r8 + leaq 16(%r9),%r9 + movq %r10,40(%rsp) + jmp .Lcbc_fast_dec_in_place_loop +.Lcbc_fast_dec_in_place_done: + movq 56(%rsp),%rdi + movq %r11,0(%rdi) + movq %r12,8(%rdi) + + movl %eax,0(%r9) + movl %ebx,4(%r9) + movl %ecx,8(%r9) + movl %edx,12(%r9) + +.align 4 +.Lcbc_fast_cleanup: + cmpl $0,80+240(%rsp) + leaq 80(%rsp),%rdi + je .Lcbc_exit + movl $30,%ecx + xorq %rax,%rax +.long 0x90AB48F3 + + jmp .Lcbc_exit + + +.align 16 +.Lcbc_slow_prologue: +.cfi_restore_state + + leaq -88(%rsp),%rbp + andq $-64,%rbp + + leaq -88-63(%rcx),%r10 + subq %rbp,%r10 + negq %r10 + andq $0x3c0,%r10 + subq %r10,%rbp + + xchgq %rsp,%rbp +.cfi_def_cfa_register %rbp + + movq %rbp,16(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x10,0x06,0x23,0x40 +.Lcbc_slow_body: + + + + + movq %r8,56(%rsp) + movq %r8,%rbp + movq %r9,%rbx + movq %rsi,%r9 + movq %rdi,%r8 + movq %rcx,%r15 + movq %rdx,%r10 + + movl 240(%r15),%eax + movq %r15,0(%rsp) + shll $4,%eax + leaq (%r15,%rax,1),%rax + movq %rax,8(%rsp) + + + leaq 2048(%r14),%r14 + leaq 768-8(%rsp),%rax + subq %r14,%rax + andq $0x300,%rax + leaq (%r14,%rax,1),%r14 + + cmpq $0,%rbx + je .LSLOW_DECRYPT + + + testq $-16,%r10 + movl 0(%rbp),%eax + movl 4(%rbp),%ebx + movl 8(%rbp),%ecx + movl 12(%rbp),%edx + jz .Lcbc_slow_enc_tail + +.align 4 +.Lcbc_slow_enc_loop: + xorl 0(%r8),%eax + xorl 4(%r8),%ebx + xorl 8(%r8),%ecx + xorl 12(%r8),%edx + movq 0(%rsp),%r15 + movq %r8,24(%rsp) + movq %r9,32(%rsp) + movq %r10,40(%rsp) + + call _x86_64_AES_encrypt_compact + + movq 24(%rsp),%r8 + movq 32(%rsp),%r9 + movq 40(%rsp),%r10 + movl %eax,0(%r9) + movl %ebx,4(%r9) + movl %ecx,8(%r9) + movl %edx,12(%r9) + + leaq 16(%r8),%r8 + leaq 16(%r9),%r9 + subq $16,%r10 + testq $-16,%r10 + jnz .Lcbc_slow_enc_loop + testq $15,%r10 + jnz .Lcbc_slow_enc_tail + movq 56(%rsp),%rbp + movl %eax,0(%rbp) + movl %ebx,4(%rbp) + movl %ecx,8(%rbp) + movl %edx,12(%rbp) + + jmp .Lcbc_exit + +.align 4 +.Lcbc_slow_enc_tail: + movq %rax,%r11 + movq %rcx,%r12 + movq %r10,%rcx + movq %r8,%rsi + movq %r9,%rdi +.long 0x9066A4F3 + movq $16,%rcx + subq %r10,%rcx + xorq %rax,%rax +.long 0x9066AAF3 + movq %r9,%r8 + movq $16,%r10 + movq %r11,%rax + movq %r12,%rcx + jmp .Lcbc_slow_enc_loop + +.align 16 +.LSLOW_DECRYPT: + shrq $3,%rax + addq %rax,%r14 + + movq 0(%rbp),%r11 + movq 8(%rbp),%r12 + movq %r11,0+64(%rsp) + movq %r12,8+64(%rsp) + +.align 4 +.Lcbc_slow_dec_loop: + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movq 0(%rsp),%r15 + movq %r8,24(%rsp) + movq %r9,32(%rsp) + movq %r10,40(%rsp) + + call _x86_64_AES_decrypt_compact + + movq 24(%rsp),%r8 + movq 32(%rsp),%r9 + movq 40(%rsp),%r10 + xorl 0+64(%rsp),%eax + xorl 4+64(%rsp),%ebx + xorl 8+64(%rsp),%ecx + xorl 12+64(%rsp),%edx + + movq 0(%r8),%r11 + movq 8(%r8),%r12 + subq $16,%r10 + jc .Lcbc_slow_dec_partial + jz .Lcbc_slow_dec_done + + movq %r11,0+64(%rsp) + movq %r12,8+64(%rsp) + + movl %eax,0(%r9) + movl %ebx,4(%r9) + movl %ecx,8(%r9) + movl %edx,12(%r9) + + leaq 16(%r8),%r8 + leaq 16(%r9),%r9 + jmp .Lcbc_slow_dec_loop +.Lcbc_slow_dec_done: + movq 56(%rsp),%rdi + movq %r11,0(%rdi) + movq %r12,8(%rdi) + + movl %eax,0(%r9) + movl %ebx,4(%r9) + movl %ecx,8(%r9) + movl %edx,12(%r9) + + jmp .Lcbc_exit + +.align 4 +.Lcbc_slow_dec_partial: + movq 56(%rsp),%rdi + movq %r11,0(%rdi) + movq %r12,8(%rdi) + + movl %eax,0+64(%rsp) + movl %ebx,4+64(%rsp) + movl %ecx,8+64(%rsp) + movl %edx,12+64(%rsp) + + movq %r9,%rdi + leaq 64(%rsp),%rsi + leaq 16(%r10),%rcx +.long 0x9066A4F3 + jmp .Lcbc_exit + +.align 16 +.Lcbc_exit: + movq 16(%rsp),%rsi +.cfi_def_cfa %rsi,64 + movq (%rsi),%r15 +.cfi_restore %r15 + movq 8(%rsi),%r14 +.cfi_restore %r14 + movq 16(%rsi),%r13 +.cfi_restore %r13 + movq 24(%rsi),%r12 +.cfi_restore %r12 + movq 32(%rsi),%rbp +.cfi_restore %rbp + movq 40(%rsi),%rbx +.cfi_restore %rbx + leaq 48(%rsi),%rsp +.cfi_def_cfa %rsp,16 +.Lcbc_popfq: + popfq + + +.cfi_adjust_cfa_offset -8 +.Lcbc_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size AES_cbc_encrypt,.-AES_cbc_encrypt +.align 64 +.LAES_Te: +.long 0xa56363c6,0xa56363c6 +.long 0x847c7cf8,0x847c7cf8 +.long 0x997777ee,0x997777ee +.long 0x8d7b7bf6,0x8d7b7bf6 +.long 0x0df2f2ff,0x0df2f2ff +.long 0xbd6b6bd6,0xbd6b6bd6 +.long 0xb16f6fde,0xb16f6fde +.long 0x54c5c591,0x54c5c591 +.long 0x50303060,0x50303060 +.long 0x03010102,0x03010102 +.long 0xa96767ce,0xa96767ce +.long 0x7d2b2b56,0x7d2b2b56 +.long 0x19fefee7,0x19fefee7 +.long 0x62d7d7b5,0x62d7d7b5 +.long 0xe6abab4d,0xe6abab4d +.long 0x9a7676ec,0x9a7676ec +.long 0x45caca8f,0x45caca8f +.long 0x9d82821f,0x9d82821f +.long 0x40c9c989,0x40c9c989 +.long 0x877d7dfa,0x877d7dfa +.long 0x15fafaef,0x15fafaef +.long 0xeb5959b2,0xeb5959b2 +.long 0xc947478e,0xc947478e +.long 0x0bf0f0fb,0x0bf0f0fb +.long 0xecadad41,0xecadad41 +.long 0x67d4d4b3,0x67d4d4b3 +.long 0xfda2a25f,0xfda2a25f +.long 0xeaafaf45,0xeaafaf45 +.long 0xbf9c9c23,0xbf9c9c23 +.long 0xf7a4a453,0xf7a4a453 +.long 0x967272e4,0x967272e4 +.long 0x5bc0c09b,0x5bc0c09b +.long 0xc2b7b775,0xc2b7b775 +.long 0x1cfdfde1,0x1cfdfde1 +.long 0xae93933d,0xae93933d +.long 0x6a26264c,0x6a26264c +.long 0x5a36366c,0x5a36366c +.long 0x413f3f7e,0x413f3f7e +.long 0x02f7f7f5,0x02f7f7f5 +.long 0x4fcccc83,0x4fcccc83 +.long 0x5c343468,0x5c343468 +.long 0xf4a5a551,0xf4a5a551 +.long 0x34e5e5d1,0x34e5e5d1 +.long 0x08f1f1f9,0x08f1f1f9 +.long 0x937171e2,0x937171e2 +.long 0x73d8d8ab,0x73d8d8ab +.long 0x53313162,0x53313162 +.long 0x3f15152a,0x3f15152a +.long 0x0c040408,0x0c040408 +.long 0x52c7c795,0x52c7c795 +.long 0x65232346,0x65232346 +.long 0x5ec3c39d,0x5ec3c39d +.long 0x28181830,0x28181830 +.long 0xa1969637,0xa1969637 +.long 0x0f05050a,0x0f05050a +.long 0xb59a9a2f,0xb59a9a2f +.long 0x0907070e,0x0907070e +.long 0x36121224,0x36121224 +.long 0x9b80801b,0x9b80801b +.long 0x3de2e2df,0x3de2e2df +.long 0x26ebebcd,0x26ebebcd +.long 0x6927274e,0x6927274e +.long 0xcdb2b27f,0xcdb2b27f +.long 0x9f7575ea,0x9f7575ea +.long 0x1b090912,0x1b090912 +.long 0x9e83831d,0x9e83831d +.long 0x742c2c58,0x742c2c58 +.long 0x2e1a1a34,0x2e1a1a34 +.long 0x2d1b1b36,0x2d1b1b36 +.long 0xb26e6edc,0xb26e6edc +.long 0xee5a5ab4,0xee5a5ab4 +.long 0xfba0a05b,0xfba0a05b +.long 0xf65252a4,0xf65252a4 +.long 0x4d3b3b76,0x4d3b3b76 +.long 0x61d6d6b7,0x61d6d6b7 +.long 0xceb3b37d,0xceb3b37d +.long 0x7b292952,0x7b292952 +.long 0x3ee3e3dd,0x3ee3e3dd +.long 0x712f2f5e,0x712f2f5e +.long 0x97848413,0x97848413 +.long 0xf55353a6,0xf55353a6 +.long 0x68d1d1b9,0x68d1d1b9 +.long 0x00000000,0x00000000 +.long 0x2cededc1,0x2cededc1 +.long 0x60202040,0x60202040 +.long 0x1ffcfce3,0x1ffcfce3 +.long 0xc8b1b179,0xc8b1b179 +.long 0xed5b5bb6,0xed5b5bb6 +.long 0xbe6a6ad4,0xbe6a6ad4 +.long 0x46cbcb8d,0x46cbcb8d +.long 0xd9bebe67,0xd9bebe67 +.long 0x4b393972,0x4b393972 +.long 0xde4a4a94,0xde4a4a94 +.long 0xd44c4c98,0xd44c4c98 +.long 0xe85858b0,0xe85858b0 +.long 0x4acfcf85,0x4acfcf85 +.long 0x6bd0d0bb,0x6bd0d0bb +.long 0x2aefefc5,0x2aefefc5 +.long 0xe5aaaa4f,0xe5aaaa4f +.long 0x16fbfbed,0x16fbfbed +.long 0xc5434386,0xc5434386 +.long 0xd74d4d9a,0xd74d4d9a +.long 0x55333366,0x55333366 +.long 0x94858511,0x94858511 +.long 0xcf45458a,0xcf45458a +.long 0x10f9f9e9,0x10f9f9e9 +.long 0x06020204,0x06020204 +.long 0x817f7ffe,0x817f7ffe +.long 0xf05050a0,0xf05050a0 +.long 0x443c3c78,0x443c3c78 +.long 0xba9f9f25,0xba9f9f25 +.long 0xe3a8a84b,0xe3a8a84b +.long 0xf35151a2,0xf35151a2 +.long 0xfea3a35d,0xfea3a35d +.long 0xc0404080,0xc0404080 +.long 0x8a8f8f05,0x8a8f8f05 +.long 0xad92923f,0xad92923f +.long 0xbc9d9d21,0xbc9d9d21 +.long 0x48383870,0x48383870 +.long 0x04f5f5f1,0x04f5f5f1 +.long 0xdfbcbc63,0xdfbcbc63 +.long 0xc1b6b677,0xc1b6b677 +.long 0x75dadaaf,0x75dadaaf +.long 0x63212142,0x63212142 +.long 0x30101020,0x30101020 +.long 0x1affffe5,0x1affffe5 +.long 0x0ef3f3fd,0x0ef3f3fd +.long 0x6dd2d2bf,0x6dd2d2bf +.long 0x4ccdcd81,0x4ccdcd81 +.long 0x140c0c18,0x140c0c18 +.long 0x35131326,0x35131326 +.long 0x2fececc3,0x2fececc3 +.long 0xe15f5fbe,0xe15f5fbe +.long 0xa2979735,0xa2979735 +.long 0xcc444488,0xcc444488 +.long 0x3917172e,0x3917172e +.long 0x57c4c493,0x57c4c493 +.long 0xf2a7a755,0xf2a7a755 +.long 0x827e7efc,0x827e7efc +.long 0x473d3d7a,0x473d3d7a +.long 0xac6464c8,0xac6464c8 +.long 0xe75d5dba,0xe75d5dba +.long 0x2b191932,0x2b191932 +.long 0x957373e6,0x957373e6 +.long 0xa06060c0,0xa06060c0 +.long 0x98818119,0x98818119 +.long 0xd14f4f9e,0xd14f4f9e +.long 0x7fdcdca3,0x7fdcdca3 +.long 0x66222244,0x66222244 +.long 0x7e2a2a54,0x7e2a2a54 +.long 0xab90903b,0xab90903b +.long 0x8388880b,0x8388880b +.long 0xca46468c,0xca46468c +.long 0x29eeeec7,0x29eeeec7 +.long 0xd3b8b86b,0xd3b8b86b +.long 0x3c141428,0x3c141428 +.long 0x79dedea7,0x79dedea7 +.long 0xe25e5ebc,0xe25e5ebc +.long 0x1d0b0b16,0x1d0b0b16 +.long 0x76dbdbad,0x76dbdbad +.long 0x3be0e0db,0x3be0e0db +.long 0x56323264,0x56323264 +.long 0x4e3a3a74,0x4e3a3a74 +.long 0x1e0a0a14,0x1e0a0a14 +.long 0xdb494992,0xdb494992 +.long 0x0a06060c,0x0a06060c +.long 0x6c242448,0x6c242448 +.long 0xe45c5cb8,0xe45c5cb8 +.long 0x5dc2c29f,0x5dc2c29f +.long 0x6ed3d3bd,0x6ed3d3bd +.long 0xefacac43,0xefacac43 +.long 0xa66262c4,0xa66262c4 +.long 0xa8919139,0xa8919139 +.long 0xa4959531,0xa4959531 +.long 0x37e4e4d3,0x37e4e4d3 +.long 0x8b7979f2,0x8b7979f2 +.long 0x32e7e7d5,0x32e7e7d5 +.long 0x43c8c88b,0x43c8c88b +.long 0x5937376e,0x5937376e +.long 0xb76d6dda,0xb76d6dda +.long 0x8c8d8d01,0x8c8d8d01 +.long 0x64d5d5b1,0x64d5d5b1 +.long 0xd24e4e9c,0xd24e4e9c +.long 0xe0a9a949,0xe0a9a949 +.long 0xb46c6cd8,0xb46c6cd8 +.long 0xfa5656ac,0xfa5656ac +.long 0x07f4f4f3,0x07f4f4f3 +.long 0x25eaeacf,0x25eaeacf +.long 0xaf6565ca,0xaf6565ca +.long 0x8e7a7af4,0x8e7a7af4 +.long 0xe9aeae47,0xe9aeae47 +.long 0x18080810,0x18080810 +.long 0xd5baba6f,0xd5baba6f +.long 0x887878f0,0x887878f0 +.long 0x6f25254a,0x6f25254a +.long 0x722e2e5c,0x722e2e5c +.long 0x241c1c38,0x241c1c38 +.long 0xf1a6a657,0xf1a6a657 +.long 0xc7b4b473,0xc7b4b473 +.long 0x51c6c697,0x51c6c697 +.long 0x23e8e8cb,0x23e8e8cb +.long 0x7cdddda1,0x7cdddda1 +.long 0x9c7474e8,0x9c7474e8 +.long 0x211f1f3e,0x211f1f3e +.long 0xdd4b4b96,0xdd4b4b96 +.long 0xdcbdbd61,0xdcbdbd61 +.long 0x868b8b0d,0x868b8b0d +.long 0x858a8a0f,0x858a8a0f +.long 0x907070e0,0x907070e0 +.long 0x423e3e7c,0x423e3e7c +.long 0xc4b5b571,0xc4b5b571 +.long 0xaa6666cc,0xaa6666cc +.long 0xd8484890,0xd8484890 +.long 0x05030306,0x05030306 +.long 0x01f6f6f7,0x01f6f6f7 +.long 0x120e0e1c,0x120e0e1c +.long 0xa36161c2,0xa36161c2 +.long 0x5f35356a,0x5f35356a +.long 0xf95757ae,0xf95757ae +.long 0xd0b9b969,0xd0b9b969 +.long 0x91868617,0x91868617 +.long 0x58c1c199,0x58c1c199 +.long 0x271d1d3a,0x271d1d3a +.long 0xb99e9e27,0xb99e9e27 +.long 0x38e1e1d9,0x38e1e1d9 +.long 0x13f8f8eb,0x13f8f8eb +.long 0xb398982b,0xb398982b +.long 0x33111122,0x33111122 +.long 0xbb6969d2,0xbb6969d2 +.long 0x70d9d9a9,0x70d9d9a9 +.long 0x898e8e07,0x898e8e07 +.long 0xa7949433,0xa7949433 +.long 0xb69b9b2d,0xb69b9b2d +.long 0x221e1e3c,0x221e1e3c +.long 0x92878715,0x92878715 +.long 0x20e9e9c9,0x20e9e9c9 +.long 0x49cece87,0x49cece87 +.long 0xff5555aa,0xff5555aa +.long 0x78282850,0x78282850 +.long 0x7adfdfa5,0x7adfdfa5 +.long 0x8f8c8c03,0x8f8c8c03 +.long 0xf8a1a159,0xf8a1a159 +.long 0x80898909,0x80898909 +.long 0x170d0d1a,0x170d0d1a +.long 0xdabfbf65,0xdabfbf65 +.long 0x31e6e6d7,0x31e6e6d7 +.long 0xc6424284,0xc6424284 +.long 0xb86868d0,0xb86868d0 +.long 0xc3414182,0xc3414182 +.long 0xb0999929,0xb0999929 +.long 0x772d2d5a,0x772d2d5a +.long 0x110f0f1e,0x110f0f1e +.long 0xcbb0b07b,0xcbb0b07b +.long 0xfc5454a8,0xfc5454a8 +.long 0xd6bbbb6d,0xd6bbbb6d +.long 0x3a16162c,0x3a16162c +.byte 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5 +.byte 0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76 +.byte 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0 +.byte 0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0 +.byte 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc +.byte 0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15 +.byte 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a +.byte 0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75 +.byte 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0 +.byte 0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84 +.byte 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b +.byte 0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf +.byte 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85 +.byte 0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8 +.byte 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5 +.byte 0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2 +.byte 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17 +.byte 0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73 +.byte 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88 +.byte 0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb +.byte 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c +.byte 0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79 +.byte 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9 +.byte 0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08 +.byte 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6 +.byte 0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a +.byte 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e +.byte 0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e +.byte 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94 +.byte 0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf +.byte 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68 +.byte 0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16 +.byte 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5 +.byte 0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76 +.byte 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0 +.byte 0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0 +.byte 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc +.byte 0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15 +.byte 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a +.byte 0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75 +.byte 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0 +.byte 0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84 +.byte 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b +.byte 0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf +.byte 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85 +.byte 0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8 +.byte 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5 +.byte 0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2 +.byte 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17 +.byte 0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73 +.byte 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88 +.byte 0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb +.byte 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c +.byte 0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79 +.byte 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9 +.byte 0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08 +.byte 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6 +.byte 0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a +.byte 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e +.byte 0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e +.byte 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94 +.byte 0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf +.byte 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68 +.byte 0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16 +.byte 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5 +.byte 0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76 +.byte 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0 +.byte 0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0 +.byte 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc +.byte 0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15 +.byte 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a +.byte 0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75 +.byte 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0 +.byte 0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84 +.byte 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b +.byte 0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf +.byte 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85 +.byte 0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8 +.byte 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5 +.byte 0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2 +.byte 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17 +.byte 0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73 +.byte 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88 +.byte 0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb +.byte 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c +.byte 0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79 +.byte 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9 +.byte 0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08 +.byte 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6 +.byte 0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a +.byte 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e +.byte 0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e +.byte 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94 +.byte 0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf +.byte 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68 +.byte 0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16 +.byte 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5 +.byte 0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76 +.byte 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0 +.byte 0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0 +.byte 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc +.byte 0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15 +.byte 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a +.byte 0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75 +.byte 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0 +.byte 0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84 +.byte 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b +.byte 0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf +.byte 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85 +.byte 0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8 +.byte 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5 +.byte 0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2 +.byte 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17 +.byte 0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73 +.byte 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88 +.byte 0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb +.byte 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c +.byte 0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79 +.byte 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9 +.byte 0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08 +.byte 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6 +.byte 0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a +.byte 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e +.byte 0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e +.byte 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94 +.byte 0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf +.byte 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68 +.byte 0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16 +.long 0x00000001, 0x00000002, 0x00000004, 0x00000008 +.long 0x00000010, 0x00000020, 0x00000040, 0x00000080 +.long 0x0000001b, 0x00000036, 0x80808080, 0x80808080 +.long 0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b +.align 64 +.LAES_Td: +.long 0x50a7f451,0x50a7f451 +.long 0x5365417e,0x5365417e +.long 0xc3a4171a,0xc3a4171a +.long 0x965e273a,0x965e273a +.long 0xcb6bab3b,0xcb6bab3b +.long 0xf1459d1f,0xf1459d1f +.long 0xab58faac,0xab58faac +.long 0x9303e34b,0x9303e34b +.long 0x55fa3020,0x55fa3020 +.long 0xf66d76ad,0xf66d76ad +.long 0x9176cc88,0x9176cc88 +.long 0x254c02f5,0x254c02f5 +.long 0xfcd7e54f,0xfcd7e54f +.long 0xd7cb2ac5,0xd7cb2ac5 +.long 0x80443526,0x80443526 +.long 0x8fa362b5,0x8fa362b5 +.long 0x495ab1de,0x495ab1de +.long 0x671bba25,0x671bba25 +.long 0x980eea45,0x980eea45 +.long 0xe1c0fe5d,0xe1c0fe5d +.long 0x02752fc3,0x02752fc3 +.long 0x12f04c81,0x12f04c81 +.long 0xa397468d,0xa397468d +.long 0xc6f9d36b,0xc6f9d36b +.long 0xe75f8f03,0xe75f8f03 +.long 0x959c9215,0x959c9215 +.long 0xeb7a6dbf,0xeb7a6dbf +.long 0xda595295,0xda595295 +.long 0x2d83bed4,0x2d83bed4 +.long 0xd3217458,0xd3217458 +.long 0x2969e049,0x2969e049 +.long 0x44c8c98e,0x44c8c98e +.long 0x6a89c275,0x6a89c275 +.long 0x78798ef4,0x78798ef4 +.long 0x6b3e5899,0x6b3e5899 +.long 0xdd71b927,0xdd71b927 +.long 0xb64fe1be,0xb64fe1be +.long 0x17ad88f0,0x17ad88f0 +.long 0x66ac20c9,0x66ac20c9 +.long 0xb43ace7d,0xb43ace7d +.long 0x184adf63,0x184adf63 +.long 0x82311ae5,0x82311ae5 +.long 0x60335197,0x60335197 +.long 0x457f5362,0x457f5362 +.long 0xe07764b1,0xe07764b1 +.long 0x84ae6bbb,0x84ae6bbb +.long 0x1ca081fe,0x1ca081fe +.long 0x942b08f9,0x942b08f9 +.long 0x58684870,0x58684870 +.long 0x19fd458f,0x19fd458f +.long 0x876cde94,0x876cde94 +.long 0xb7f87b52,0xb7f87b52 +.long 0x23d373ab,0x23d373ab +.long 0xe2024b72,0xe2024b72 +.long 0x578f1fe3,0x578f1fe3 +.long 0x2aab5566,0x2aab5566 +.long 0x0728ebb2,0x0728ebb2 +.long 0x03c2b52f,0x03c2b52f +.long 0x9a7bc586,0x9a7bc586 +.long 0xa50837d3,0xa50837d3 +.long 0xf2872830,0xf2872830 +.long 0xb2a5bf23,0xb2a5bf23 +.long 0xba6a0302,0xba6a0302 +.long 0x5c8216ed,0x5c8216ed +.long 0x2b1ccf8a,0x2b1ccf8a +.long 0x92b479a7,0x92b479a7 +.long 0xf0f207f3,0xf0f207f3 +.long 0xa1e2694e,0xa1e2694e +.long 0xcdf4da65,0xcdf4da65 +.long 0xd5be0506,0xd5be0506 +.long 0x1f6234d1,0x1f6234d1 +.long 0x8afea6c4,0x8afea6c4 +.long 0x9d532e34,0x9d532e34 +.long 0xa055f3a2,0xa055f3a2 +.long 0x32e18a05,0x32e18a05 +.long 0x75ebf6a4,0x75ebf6a4 +.long 0x39ec830b,0x39ec830b +.long 0xaaef6040,0xaaef6040 +.long 0x069f715e,0x069f715e +.long 0x51106ebd,0x51106ebd +.long 0xf98a213e,0xf98a213e +.long 0x3d06dd96,0x3d06dd96 +.long 0xae053edd,0xae053edd +.long 0x46bde64d,0x46bde64d +.long 0xb58d5491,0xb58d5491 +.long 0x055dc471,0x055dc471 +.long 0x6fd40604,0x6fd40604 +.long 0xff155060,0xff155060 +.long 0x24fb9819,0x24fb9819 +.long 0x97e9bdd6,0x97e9bdd6 +.long 0xcc434089,0xcc434089 +.long 0x779ed967,0x779ed967 +.long 0xbd42e8b0,0xbd42e8b0 +.long 0x888b8907,0x888b8907 +.long 0x385b19e7,0x385b19e7 +.long 0xdbeec879,0xdbeec879 +.long 0x470a7ca1,0x470a7ca1 +.long 0xe90f427c,0xe90f427c +.long 0xc91e84f8,0xc91e84f8 +.long 0x00000000,0x00000000 +.long 0x83868009,0x83868009 +.long 0x48ed2b32,0x48ed2b32 +.long 0xac70111e,0xac70111e +.long 0x4e725a6c,0x4e725a6c +.long 0xfbff0efd,0xfbff0efd +.long 0x5638850f,0x5638850f +.long 0x1ed5ae3d,0x1ed5ae3d +.long 0x27392d36,0x27392d36 +.long 0x64d90f0a,0x64d90f0a +.long 0x21a65c68,0x21a65c68 +.long 0xd1545b9b,0xd1545b9b +.long 0x3a2e3624,0x3a2e3624 +.long 0xb1670a0c,0xb1670a0c +.long 0x0fe75793,0x0fe75793 +.long 0xd296eeb4,0xd296eeb4 +.long 0x9e919b1b,0x9e919b1b +.long 0x4fc5c080,0x4fc5c080 +.long 0xa220dc61,0xa220dc61 +.long 0x694b775a,0x694b775a +.long 0x161a121c,0x161a121c +.long 0x0aba93e2,0x0aba93e2 +.long 0xe52aa0c0,0xe52aa0c0 +.long 0x43e0223c,0x43e0223c +.long 0x1d171b12,0x1d171b12 +.long 0x0b0d090e,0x0b0d090e +.long 0xadc78bf2,0xadc78bf2 +.long 0xb9a8b62d,0xb9a8b62d +.long 0xc8a91e14,0xc8a91e14 +.long 0x8519f157,0x8519f157 +.long 0x4c0775af,0x4c0775af +.long 0xbbdd99ee,0xbbdd99ee +.long 0xfd607fa3,0xfd607fa3 +.long 0x9f2601f7,0x9f2601f7 +.long 0xbcf5725c,0xbcf5725c +.long 0xc53b6644,0xc53b6644 +.long 0x347efb5b,0x347efb5b +.long 0x7629438b,0x7629438b +.long 0xdcc623cb,0xdcc623cb +.long 0x68fcedb6,0x68fcedb6 +.long 0x63f1e4b8,0x63f1e4b8 +.long 0xcadc31d7,0xcadc31d7 +.long 0x10856342,0x10856342 +.long 0x40229713,0x40229713 +.long 0x2011c684,0x2011c684 +.long 0x7d244a85,0x7d244a85 +.long 0xf83dbbd2,0xf83dbbd2 +.long 0x1132f9ae,0x1132f9ae +.long 0x6da129c7,0x6da129c7 +.long 0x4b2f9e1d,0x4b2f9e1d +.long 0xf330b2dc,0xf330b2dc +.long 0xec52860d,0xec52860d +.long 0xd0e3c177,0xd0e3c177 +.long 0x6c16b32b,0x6c16b32b +.long 0x99b970a9,0x99b970a9 +.long 0xfa489411,0xfa489411 +.long 0x2264e947,0x2264e947 +.long 0xc48cfca8,0xc48cfca8 +.long 0x1a3ff0a0,0x1a3ff0a0 +.long 0xd82c7d56,0xd82c7d56 +.long 0xef903322,0xef903322 +.long 0xc74e4987,0xc74e4987 +.long 0xc1d138d9,0xc1d138d9 +.long 0xfea2ca8c,0xfea2ca8c +.long 0x360bd498,0x360bd498 +.long 0xcf81f5a6,0xcf81f5a6 +.long 0x28de7aa5,0x28de7aa5 +.long 0x268eb7da,0x268eb7da +.long 0xa4bfad3f,0xa4bfad3f +.long 0xe49d3a2c,0xe49d3a2c +.long 0x0d927850,0x0d927850 +.long 0x9bcc5f6a,0x9bcc5f6a +.long 0x62467e54,0x62467e54 +.long 0xc2138df6,0xc2138df6 +.long 0xe8b8d890,0xe8b8d890 +.long 0x5ef7392e,0x5ef7392e +.long 0xf5afc382,0xf5afc382 +.long 0xbe805d9f,0xbe805d9f +.long 0x7c93d069,0x7c93d069 +.long 0xa92dd56f,0xa92dd56f +.long 0xb31225cf,0xb31225cf +.long 0x3b99acc8,0x3b99acc8 +.long 0xa77d1810,0xa77d1810 +.long 0x6e639ce8,0x6e639ce8 +.long 0x7bbb3bdb,0x7bbb3bdb +.long 0x097826cd,0x097826cd +.long 0xf418596e,0xf418596e +.long 0x01b79aec,0x01b79aec +.long 0xa89a4f83,0xa89a4f83 +.long 0x656e95e6,0x656e95e6 +.long 0x7ee6ffaa,0x7ee6ffaa +.long 0x08cfbc21,0x08cfbc21 +.long 0xe6e815ef,0xe6e815ef +.long 0xd99be7ba,0xd99be7ba +.long 0xce366f4a,0xce366f4a +.long 0xd4099fea,0xd4099fea +.long 0xd67cb029,0xd67cb029 +.long 0xafb2a431,0xafb2a431 +.long 0x31233f2a,0x31233f2a +.long 0x3094a5c6,0x3094a5c6 +.long 0xc066a235,0xc066a235 +.long 0x37bc4e74,0x37bc4e74 +.long 0xa6ca82fc,0xa6ca82fc +.long 0xb0d090e0,0xb0d090e0 +.long 0x15d8a733,0x15d8a733 +.long 0x4a9804f1,0x4a9804f1 +.long 0xf7daec41,0xf7daec41 +.long 0x0e50cd7f,0x0e50cd7f +.long 0x2ff69117,0x2ff69117 +.long 0x8dd64d76,0x8dd64d76 +.long 0x4db0ef43,0x4db0ef43 +.long 0x544daacc,0x544daacc +.long 0xdf0496e4,0xdf0496e4 +.long 0xe3b5d19e,0xe3b5d19e +.long 0x1b886a4c,0x1b886a4c +.long 0xb81f2cc1,0xb81f2cc1 +.long 0x7f516546,0x7f516546 +.long 0x04ea5e9d,0x04ea5e9d +.long 0x5d358c01,0x5d358c01 +.long 0x737487fa,0x737487fa +.long 0x2e410bfb,0x2e410bfb +.long 0x5a1d67b3,0x5a1d67b3 +.long 0x52d2db92,0x52d2db92 +.long 0x335610e9,0x335610e9 +.long 0x1347d66d,0x1347d66d +.long 0x8c61d79a,0x8c61d79a +.long 0x7a0ca137,0x7a0ca137 +.long 0x8e14f859,0x8e14f859 +.long 0x893c13eb,0x893c13eb +.long 0xee27a9ce,0xee27a9ce +.long 0x35c961b7,0x35c961b7 +.long 0xede51ce1,0xede51ce1 +.long 0x3cb1477a,0x3cb1477a +.long 0x59dfd29c,0x59dfd29c +.long 0x3f73f255,0x3f73f255 +.long 0x79ce1418,0x79ce1418 +.long 0xbf37c773,0xbf37c773 +.long 0xeacdf753,0xeacdf753 +.long 0x5baafd5f,0x5baafd5f +.long 0x146f3ddf,0x146f3ddf +.long 0x86db4478,0x86db4478 +.long 0x81f3afca,0x81f3afca +.long 0x3ec468b9,0x3ec468b9 +.long 0x2c342438,0x2c342438 +.long 0x5f40a3c2,0x5f40a3c2 +.long 0x72c31d16,0x72c31d16 +.long 0x0c25e2bc,0x0c25e2bc +.long 0x8b493c28,0x8b493c28 +.long 0x41950dff,0x41950dff +.long 0x7101a839,0x7101a839 +.long 0xdeb30c08,0xdeb30c08 +.long 0x9ce4b4d8,0x9ce4b4d8 +.long 0x90c15664,0x90c15664 +.long 0x6184cb7b,0x6184cb7b +.long 0x70b632d5,0x70b632d5 +.long 0x745c6c48,0x745c6c48 +.long 0x4257b8d0,0x4257b8d0 +.byte 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38 +.byte 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb +.byte 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87 +.byte 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb +.byte 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d +.byte 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e +.byte 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2 +.byte 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25 +.byte 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16 +.byte 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92 +.byte 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda +.byte 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84 +.byte 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a +.byte 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06 +.byte 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02 +.byte 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b +.byte 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea +.byte 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73 +.byte 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85 +.byte 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e +.byte 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89 +.byte 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b +.byte 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20 +.byte 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4 +.byte 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31 +.byte 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f +.byte 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d +.byte 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef +.byte 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0 +.byte 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61 +.byte 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26 +.byte 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d +.long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe +.long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 +.byte 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38 +.byte 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb +.byte 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87 +.byte 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb +.byte 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d +.byte 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e +.byte 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2 +.byte 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25 +.byte 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16 +.byte 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92 +.byte 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda +.byte 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84 +.byte 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a +.byte 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06 +.byte 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02 +.byte 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b +.byte 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea +.byte 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73 +.byte 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85 +.byte 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e +.byte 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89 +.byte 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b +.byte 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20 +.byte 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4 +.byte 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31 +.byte 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f +.byte 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d +.byte 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef +.byte 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0 +.byte 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61 +.byte 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26 +.byte 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d +.long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe +.long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 +.byte 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38 +.byte 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb +.byte 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87 +.byte 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb +.byte 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d +.byte 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e +.byte 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2 +.byte 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25 +.byte 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16 +.byte 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92 +.byte 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda +.byte 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84 +.byte 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a +.byte 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06 +.byte 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02 +.byte 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b +.byte 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea +.byte 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73 +.byte 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85 +.byte 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e +.byte 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89 +.byte 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b +.byte 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20 +.byte 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4 +.byte 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31 +.byte 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f +.byte 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d +.byte 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef +.byte 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0 +.byte 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61 +.byte 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26 +.byte 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d +.long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe +.long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 +.byte 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38 +.byte 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb +.byte 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87 +.byte 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb +.byte 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d +.byte 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e +.byte 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2 +.byte 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25 +.byte 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16 +.byte 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92 +.byte 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda +.byte 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84 +.byte 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a +.byte 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06 +.byte 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02 +.byte 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b +.byte 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea +.byte 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73 +.byte 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85 +.byte 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e +.byte 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89 +.byte 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b +.byte 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20 +.byte 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4 +.byte 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31 +.byte 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f +.byte 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d +.byte 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef +.byte 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0 +.byte 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61 +.byte 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26 +.byte 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d +.long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe +.long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 +.byte 65,69,83,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/aes/aes_cbc.c b/crypto/openssl/crypto/aes/aes_cbc.c index 342841fc4ff7..f2d5381b86d7 100644 --- a/crypto/openssl/crypto/aes/aes_cbc.c +++ b/crypto/openssl/crypto/aes/aes_cbc.c @@ -1,12 +1,19 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * AES low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/openssl/crypto/aes/aes_cfb.c b/crypto/openssl/crypto/aes/aes_cfb.c index f010e3c4ea9e..e5fcbb87f609 100644 --- a/crypto/openssl/crypto/aes/aes_cfb.c +++ b/crypto/openssl/crypto/aes/aes_cfb.c @@ -1,12 +1,18 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * AES_encrypt is deprecated - but we need to use it to implement these other + * deprecated APIs. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/openssl/crypto/aes/aes_core.c b/crypto/openssl/crypto/aes/aes_core.c index ad00c729e700..3413ce8f4378 100644 --- a/crypto/openssl/crypto/aes/aes_core.c +++ b/crypto/openssl/crypto/aes/aes_core.c @@ -1,7 +1,7 @@ /* - * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -36,6 +36,13 @@ /* Note: rewritten a little bit to provide error control and an OpenSSL- compatible API */ +/* + * AES low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include @@ -44,6 +51,15 @@ #include "aes_local.h" #if defined(OPENSSL_AES_CONST_TIME) && !defined(AES_ASM) + +# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define U64(C) C##UI64 +# elif defined(__arch64__) +# define U64(C) C##UL +# else +# define U64(C) C##ULL +# endif + typedef union { unsigned char b[8]; u32 w[2]; @@ -72,10 +88,10 @@ static void XtimeLong(u64 *w) u64 a, b; a = *w; - b = a & 0x8080808080808080uLL; + b = a & U64(0x8080808080808080); a ^= b; b -= b >> 7; - b &= 0x1B1B1B1B1B1B1B1BuLL; + b &= U64(0x1B1B1B1B1B1B1B1B); b ^= a << 1; *w = b; } @@ -222,89 +238,89 @@ static void SubLong(u64 *w) u64 x, y, a1, a2, a3, a4, a5, a6; x = *w; - y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7); - x &= 0xDDDDDDDDDDDDDDDDuLL; - x ^= y & 0x5757575757575757uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x1C1C1C1C1C1C1C1CuLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x4A4A4A4A4A4A4A4AuLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x4242424242424242uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x6464646464646464uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0xE0E0E0E0E0E0E0E0uLL; + y = ((x & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((x & U64(0x0101010101010101)) << 7); + x &= U64(0xDDDDDDDDDDDDDDDD); + x ^= y & U64(0x5757575757575757); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x1C1C1C1C1C1C1C1C); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x4A4A4A4A4A4A4A4A); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x4242424242424242); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x6464646464646464); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0xE0E0E0E0E0E0E0E0); a1 = x; - a1 ^= (x & 0xF0F0F0F0F0F0F0F0uLL) >> 4; - a2 = ((x & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((x & 0x3333333333333333uLL) << 2); + a1 ^= (x & U64(0xF0F0F0F0F0F0F0F0)) >> 4; + a2 = ((x & U64(0xCCCCCCCCCCCCCCCC)) >> 2) | ((x & U64(0x3333333333333333)) << 2); a3 = x & a1; - a3 ^= (a3 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; - a3 ^= (((x << 1) & a1) ^ ((a1 << 1) & x)) & 0xAAAAAAAAAAAAAAAAuLL; + a3 ^= (a3 & U64(0xAAAAAAAAAAAAAAAA)) >> 1; + a3 ^= (((x << 1) & a1) ^ ((a1 << 1) & x)) & U64(0xAAAAAAAAAAAAAAAA); a4 = a2 & a1; - a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; - a4 ^= (((a2 << 1) & a1) ^ ((a1 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL; - a5 = (a3 & 0xCCCCCCCCCCCCCCCCuLL) >> 2; - a3 ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL; - a4 = a5 & 0x2222222222222222uLL; + a4 ^= (a4 & U64(0xAAAAAAAAAAAAAAAA)) >> 1; + a4 ^= (((a2 << 1) & a1) ^ ((a1 << 1) & a2)) & U64(0xAAAAAAAAAAAAAAAA); + a5 = (a3 & U64(0xCCCCCCCCCCCCCCCC)) >> 2; + a3 ^= ((a4 << 2) ^ a4) & U64(0xCCCCCCCCCCCCCCCC); + a4 = a5 & U64(0x2222222222222222); a4 |= a4 >> 1; - a4 ^= (a5 << 1) & 0x2222222222222222uLL; + a4 ^= (a5 << 1) & U64(0x2222222222222222); a3 ^= a4; - a5 = a3 & 0xA0A0A0A0A0A0A0A0uLL; + a5 = a3 & U64(0xA0A0A0A0A0A0A0A0); a5 |= a5 >> 1; - a5 ^= (a3 << 1) & 0xA0A0A0A0A0A0A0A0uLL; - a4 = a5 & 0xC0C0C0C0C0C0C0C0uLL; + a5 ^= (a3 << 1) & U64(0xA0A0A0A0A0A0A0A0); + a4 = a5 & U64(0xC0C0C0C0C0C0C0C0); a6 = a4 >> 2; - a4 ^= (a5 << 2) & 0xC0C0C0C0C0C0C0C0uLL; - a5 = a6 & 0x2020202020202020uLL; + a4 ^= (a5 << 2) & U64(0xC0C0C0C0C0C0C0C0); + a5 = a6 & U64(0x2020202020202020); a5 |= a5 >> 1; - a5 ^= (a6 << 1) & 0x2020202020202020uLL; + a5 ^= (a6 << 1) & U64(0x2020202020202020); a4 |= a5; a3 ^= a4 >> 4; - a3 &= 0x0F0F0F0F0F0F0F0FuLL; + a3 &= U64(0x0F0F0F0F0F0F0F0F); a2 = a3; - a2 ^= (a3 & 0x0C0C0C0C0C0C0C0CuLL) >> 2; + a2 ^= (a3 & U64(0x0C0C0C0C0C0C0C0C)) >> 2; a4 = a3 & a2; - a4 ^= (a4 & 0x0A0A0A0A0A0A0A0AuLL) >> 1; - a4 ^= (((a3 << 1) & a2) ^ ((a2 << 1) & a3)) & 0x0A0A0A0A0A0A0A0AuLL; - a5 = a4 & 0x0808080808080808uLL; + a4 ^= (a4 & U64(0x0A0A0A0A0A0A0A0A)) >> 1; + a4 ^= (((a3 << 1) & a2) ^ ((a2 << 1) & a3)) & U64(0x0A0A0A0A0A0A0A0A); + a5 = a4 & U64(0x0808080808080808); a5 |= a5 >> 1; - a5 ^= (a4 << 1) & 0x0808080808080808uLL; + a5 ^= (a4 << 1) & U64(0x0808080808080808); a4 ^= a5 >> 2; - a4 &= 0x0303030303030303uLL; - a4 ^= (a4 & 0x0202020202020202uLL) >> 1; + a4 &= U64(0x0303030303030303); + a4 ^= (a4 & U64(0x0202020202020202)) >> 1; a4 |= a4 << 2; a3 = a2 & a4; - a3 ^= (a3 & 0x0A0A0A0A0A0A0A0AuLL) >> 1; - a3 ^= (((a2 << 1) & a4) ^ ((a4 << 1) & a2)) & 0x0A0A0A0A0A0A0A0AuLL; + a3 ^= (a3 & U64(0x0A0A0A0A0A0A0A0A)) >> 1; + a3 ^= (((a2 << 1) & a4) ^ ((a4 << 1) & a2)) & U64(0x0A0A0A0A0A0A0A0A); a3 |= a3 << 4; - a2 = ((a1 & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((a1 & 0x3333333333333333uLL) << 2); + a2 = ((a1 & U64(0xCCCCCCCCCCCCCCCC)) >> 2) | ((a1 & U64(0x3333333333333333)) << 2); x = a1 & a3; - x ^= (x & 0xAAAAAAAAAAAAAAAAuLL) >> 1; - x ^= (((a1 << 1) & a3) ^ ((a3 << 1) & a1)) & 0xAAAAAAAAAAAAAAAAuLL; + x ^= (x & U64(0xAAAAAAAAAAAAAAAA)) >> 1; + x ^= (((a1 << 1) & a3) ^ ((a3 << 1) & a1)) & U64(0xAAAAAAAAAAAAAAAA); a4 = a2 & a3; - a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; - a4 ^= (((a2 << 1) & a3) ^ ((a3 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL; - a5 = (x & 0xCCCCCCCCCCCCCCCCuLL) >> 2; - x ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL; - a4 = a5 & 0x2222222222222222uLL; + a4 ^= (a4 & U64(0xAAAAAAAAAAAAAAAA)) >> 1; + a4 ^= (((a2 << 1) & a3) ^ ((a3 << 1) & a2)) & U64(0xAAAAAAAAAAAAAAAA); + a5 = (x & U64(0xCCCCCCCCCCCCCCCC)) >> 2; + x ^= ((a4 << 2) ^ a4) & U64(0xCCCCCCCCCCCCCCCC); + a4 = a5 & U64(0x2222222222222222); a4 |= a4 >> 1; - a4 ^= (a5 << 1) & 0x2222222222222222uLL; + a4 ^= (a5 << 1) & U64(0x2222222222222222); x ^= a4; - y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7); - x &= 0x3939393939393939uLL; - x ^= y & 0x3F3F3F3F3F3F3F3FuLL; - y = ((y & 0xFCFCFCFCFCFCFCFCuLL) >> 2) | ((y & 0x0303030303030303uLL) << 6); - x ^= y & 0x9797979797979797uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x9B9B9B9B9B9B9B9BuLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x3C3C3C3C3C3C3C3CuLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0xDDDDDDDDDDDDDDDDuLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x7272727272727272uLL; - x ^= 0x6363636363636363uLL; + y = ((x & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((x & U64(0x0101010101010101)) << 7); + x &= U64(0x3939393939393939); + x ^= y & U64(0x3F3F3F3F3F3F3F3F); + y = ((y & U64(0xFCFCFCFCFCFCFCFC)) >> 2) | ((y & U64(0x0303030303030303)) << 6); + x ^= y & U64(0x9797979797979797); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x9B9B9B9B9B9B9B9B); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x3C3C3C3C3C3C3C3C); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0xDDDDDDDDDDDDDDDD); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x7272727272727272); + x ^= U64(0x6363636363636363); *w = x; } @@ -316,93 +332,93 @@ static void InvSubLong(u64 *w) u64 x, y, a1, a2, a3, a4, a5, a6; x = *w; - x ^= 0x6363636363636363uLL; - y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7); - x &= 0xFDFDFDFDFDFDFDFDuLL; - x ^= y & 0x5E5E5E5E5E5E5E5EuLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0xF3F3F3F3F3F3F3F3uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0xF5F5F5F5F5F5F5F5uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x7878787878787878uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x7777777777777777uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x1515151515151515uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0xA5A5A5A5A5A5A5A5uLL; + x ^= U64(0x6363636363636363); + y = ((x & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((x & U64(0x0101010101010101)) << 7); + x &= U64(0xFDFDFDFDFDFDFDFD); + x ^= y & U64(0x5E5E5E5E5E5E5E5E); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0xF3F3F3F3F3F3F3F3); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0xF5F5F5F5F5F5F5F5); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x7878787878787878); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x7777777777777777); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x1515151515151515); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0xA5A5A5A5A5A5A5A5); a1 = x; - a1 ^= (x & 0xF0F0F0F0F0F0F0F0uLL) >> 4; - a2 = ((x & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((x & 0x3333333333333333uLL) << 2); + a1 ^= (x & U64(0xF0F0F0F0F0F0F0F0)) >> 4; + a2 = ((x & U64(0xCCCCCCCCCCCCCCCC)) >> 2) | ((x & U64(0x3333333333333333)) << 2); a3 = x & a1; - a3 ^= (a3 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; - a3 ^= (((x << 1) & a1) ^ ((a1 << 1) & x)) & 0xAAAAAAAAAAAAAAAAuLL; + a3 ^= (a3 & U64(0xAAAAAAAAAAAAAAAA)) >> 1; + a3 ^= (((x << 1) & a1) ^ ((a1 << 1) & x)) & U64(0xAAAAAAAAAAAAAAAA); a4 = a2 & a1; - a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; - a4 ^= (((a2 << 1) & a1) ^ ((a1 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL; - a5 = (a3 & 0xCCCCCCCCCCCCCCCCuLL) >> 2; - a3 ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL; - a4 = a5 & 0x2222222222222222uLL; + a4 ^= (a4 & U64(0xAAAAAAAAAAAAAAAA)) >> 1; + a4 ^= (((a2 << 1) & a1) ^ ((a1 << 1) & a2)) & U64(0xAAAAAAAAAAAAAAAA); + a5 = (a3 & U64(0xCCCCCCCCCCCCCCCC)) >> 2; + a3 ^= ((a4 << 2) ^ a4) & U64(0xCCCCCCCCCCCCCCCC); + a4 = a5 & U64(0x2222222222222222); a4 |= a4 >> 1; - a4 ^= (a5 << 1) & 0x2222222222222222uLL; + a4 ^= (a5 << 1) & U64(0x2222222222222222); a3 ^= a4; - a5 = a3 & 0xA0A0A0A0A0A0A0A0uLL; + a5 = a3 & U64(0xA0A0A0A0A0A0A0A0); a5 |= a5 >> 1; - a5 ^= (a3 << 1) & 0xA0A0A0A0A0A0A0A0uLL; - a4 = a5 & 0xC0C0C0C0C0C0C0C0uLL; + a5 ^= (a3 << 1) & U64(0xA0A0A0A0A0A0A0A0); + a4 = a5 & U64(0xC0C0C0C0C0C0C0C0); a6 = a4 >> 2; - a4 ^= (a5 << 2) & 0xC0C0C0C0C0C0C0C0uLL; - a5 = a6 & 0x2020202020202020uLL; + a4 ^= (a5 << 2) & U64(0xC0C0C0C0C0C0C0C0); + a5 = a6 & U64(0x2020202020202020); a5 |= a5 >> 1; - a5 ^= (a6 << 1) & 0x2020202020202020uLL; + a5 ^= (a6 << 1) & U64(0x2020202020202020); a4 |= a5; a3 ^= a4 >> 4; - a3 &= 0x0F0F0F0F0F0F0F0FuLL; + a3 &= U64(0x0F0F0F0F0F0F0F0F); a2 = a3; - a2 ^= (a3 & 0x0C0C0C0C0C0C0C0CuLL) >> 2; + a2 ^= (a3 & U64(0x0C0C0C0C0C0C0C0C)) >> 2; a4 = a3 & a2; - a4 ^= (a4 & 0x0A0A0A0A0A0A0A0AuLL) >> 1; - a4 ^= (((a3 << 1) & a2) ^ ((a2 << 1) & a3)) & 0x0A0A0A0A0A0A0A0AuLL; - a5 = a4 & 0x0808080808080808uLL; + a4 ^= (a4 & U64(0x0A0A0A0A0A0A0A0A)) >> 1; + a4 ^= (((a3 << 1) & a2) ^ ((a2 << 1) & a3)) & U64(0x0A0A0A0A0A0A0A0A); + a5 = a4 & U64(0x0808080808080808); a5 |= a5 >> 1; - a5 ^= (a4 << 1) & 0x0808080808080808uLL; + a5 ^= (a4 << 1) & U64(0x0808080808080808); a4 ^= a5 >> 2; - a4 &= 0x0303030303030303uLL; - a4 ^= (a4 & 0x0202020202020202uLL) >> 1; + a4 &= U64(0x0303030303030303); + a4 ^= (a4 & U64(0x0202020202020202)) >> 1; a4 |= a4 << 2; a3 = a2 & a4; - a3 ^= (a3 & 0x0A0A0A0A0A0A0A0AuLL) >> 1; - a3 ^= (((a2 << 1) & a4) ^ ((a4 << 1) & a2)) & 0x0A0A0A0A0A0A0A0AuLL; + a3 ^= (a3 & U64(0x0A0A0A0A0A0A0A0A)) >> 1; + a3 ^= (((a2 << 1) & a4) ^ ((a4 << 1) & a2)) & U64(0x0A0A0A0A0A0A0A0A); a3 |= a3 << 4; - a2 = ((a1 & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((a1 & 0x3333333333333333uLL) << 2); + a2 = ((a1 & U64(0xCCCCCCCCCCCCCCCC)) >> 2) | ((a1 & U64(0x3333333333333333)) << 2); x = a1 & a3; - x ^= (x & 0xAAAAAAAAAAAAAAAAuLL) >> 1; - x ^= (((a1 << 1) & a3) ^ ((a3 << 1) & a1)) & 0xAAAAAAAAAAAAAAAAuLL; + x ^= (x & U64(0xAAAAAAAAAAAAAAAA)) >> 1; + x ^= (((a1 << 1) & a3) ^ ((a3 << 1) & a1)) & U64(0xAAAAAAAAAAAAAAAA); a4 = a2 & a3; - a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; - a4 ^= (((a2 << 1) & a3) ^ ((a3 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL; - a5 = (x & 0xCCCCCCCCCCCCCCCCuLL) >> 2; - x ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL; - a4 = a5 & 0x2222222222222222uLL; + a4 ^= (a4 & U64(0xAAAAAAAAAAAAAAAA)) >> 1; + a4 ^= (((a2 << 1) & a3) ^ ((a3 << 1) & a2)) & U64(0xAAAAAAAAAAAAAAAA); + a5 = (x & U64(0xCCCCCCCCCCCCCCCC)) >> 2; + x ^= ((a4 << 2) ^ a4) & U64(0xCCCCCCCCCCCCCCCC); + a4 = a5 & U64(0x2222222222222222); a4 |= a4 >> 1; - a4 ^= (a5 << 1) & 0x2222222222222222uLL; + a4 ^= (a5 << 1) & U64(0x2222222222222222); x ^= a4; - y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7); - x &= 0xB5B5B5B5B5B5B5B5uLL; - x ^= y & 0x4040404040404040uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x8080808080808080uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x1616161616161616uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0xEBEBEBEBEBEBEBEBuLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x9797979797979797uLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0xFBFBFBFBFBFBFBFBuLL; - y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); - x ^= y & 0x7D7D7D7D7D7D7D7DuLL; + y = ((x & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((x & U64(0x0101010101010101)) << 7); + x &= U64(0xB5B5B5B5B5B5B5B5); + x ^= y & U64(0x4040404040404040); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x8080808080808080); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x1616161616161616); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0xEBEBEBEBEBEBEBEB); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x9797979797979797); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0xFBFBFBFBFBFBFBFB); + y = ((y & U64(0xFEFEFEFEFEFEFEFE)) >> 1) | ((y & U64(0x0101010101010101)) << 7); + x ^= y & U64(0x7D7D7D7D7D7D7D7D); *w = x; } @@ -453,10 +469,10 @@ static void MixColumns(u64 *state) for (c = 0; c < 2; c++) { s1.d = state[c]; s.d = s1.d; - s.d ^= ((s.d & 0xFFFF0000FFFF0000uLL) >> 16) - | ((s.d & 0x0000FFFF0000FFFFuLL) << 16); - s.d ^= ((s.d & 0xFF00FF00FF00FF00uLL) >> 8) - | ((s.d & 0x00FF00FF00FF00FFuLL) << 8); + s.d ^= ((s.d & U64(0xFFFF0000FFFF0000)) >> 16) + | ((s.d & U64(0x0000FFFF0000FFFF)) << 16); + s.d ^= ((s.d & U64(0xFF00FF00FF00FF00)) >> 8) + | ((s.d & U64(0x00FF00FF00FF00FF)) << 8); s.d ^= s1.d; XtimeLong(&s1.d); s.d ^= s1.d; @@ -481,10 +497,10 @@ static void InvMixColumns(u64 *state) for (c = 0; c < 2; c++) { s1.d = state[c]; s.d = s1.d; - s.d ^= ((s.d & 0xFFFF0000FFFF0000uLL) >> 16) - | ((s.d & 0x0000FFFF0000FFFFuLL) << 16); - s.d ^= ((s.d & 0xFF00FF00FF00FF00uLL) >> 8) - | ((s.d & 0x00FF00FF00FF00FFuLL) << 8); + s.d ^= ((s.d & U64(0xFFFF0000FFFF0000)) >> 16) + | ((s.d & U64(0x0000FFFF0000FFFF)) << 16); + s.d ^= ((s.d & U64(0xFF00FF00FF00FF00)) >> 8) + | ((s.d & U64(0x00FF00FF00FF00FF)) << 8); s.d ^= s1.d; XtimeLong(&s1.d); s.d ^= s1.d; @@ -497,12 +513,12 @@ static void InvMixColumns(u64 *state) s.b[6] ^= s1.b[7]; s.b[7] ^= s1.b[4]; XtimeLong(&s1.d); - s1.d ^= ((s1.d & 0xFFFF0000FFFF0000uLL) >> 16) - | ((s1.d & 0x0000FFFF0000FFFFuLL) << 16); + s1.d ^= ((s1.d & U64(0xFFFF0000FFFF0000)) >> 16) + | ((s1.d & U64(0x0000FFFF0000FFFF)) << 16); s.d ^= s1.d; XtimeLong(&s1.d); - s1.d ^= ((s1.d & 0xFF00FF00FF00FF00uLL) >> 8) - | ((s1.d & 0x00FF00FF00FF00FFuLL) << 8); + s1.d ^= ((s1.d & U64(0xFF00FF00FF00FF00)) >> 8) + | ((s1.d & U64(0x00FF00FF00FF00FF)) << 8); s.d ^= s1.d; state[c] = s.d; } diff --git a/crypto/openssl/crypto/aes/aes_ecb.c b/crypto/openssl/crypto/aes/aes_ecb.c index 4fa360ca8b8d..e05afb0449cc 100644 --- a/crypto/openssl/crypto/aes/aes_ecb.c +++ b/crypto/openssl/crypto/aes/aes_ecb.c @@ -1,7 +1,7 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,6 +9,12 @@ #include +/* + * AES_encrypt/AES_decrypt are deprecated - but we need to use them to implement + * AES_ecb_encrypt + */ +#include "internal/deprecated.h" + #include #include "aes_local.h" diff --git a/crypto/openssl/crypto/aes/aes_ige.c b/crypto/openssl/crypto/aes/aes_ige.c index 804b3a723d1f..72fcba7a0cf1 100644 --- a/crypto/openssl/crypto/aes/aes_ige.c +++ b/crypto/openssl/crypto/aes/aes_ige.c @@ -1,12 +1,18 @@ /* * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * AES_encrypt/AES_decrypt are deprecated - but we need to use them to implement + * these functions + */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" #include @@ -38,12 +44,13 @@ typedef struct { /* N.B. The IV for this mode is _twice_ the block size */ +/* Use of this function is deprecated. */ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, const int enc) { size_t n; - size_t len = length; + size_t len = length / AES_BLOCK_SIZE; if (length == 0) return; @@ -52,8 +59,6 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); - len = length / AES_BLOCK_SIZE; - if (AES_ENCRYPT == enc) { if (in != out && (UNALIGNED_MEMOPS_ARE_FAST @@ -166,6 +171,14 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, /* * Note that its effectively impossible to do biIGE in anything other * than a single pass, so no provision is made for chaining. + * + * NB: The implementation of AES_bi_ige_encrypt has a bug. It is supposed to use + * 2 AES keys, but in fact only one is ever used. This bug has been present + * since this code was first implemented. It is believed to have minimal + * security impact in practice and has therefore not been fixed for backwards + * compatibility reasons. + * + * Use of this function is deprecated. */ /* N.B. The IV for this mode is _four times_ the block size */ diff --git a/crypto/openssl/crypto/aes/aes_local.h b/crypto/openssl/crypto/aes/aes_local.h index a9c0059e52cc..69d17d6cde7b 100644 --- a/crypto/openssl/crypto/aes/aes_local.h +++ b/crypto/openssl/crypto/aes/aes_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -24,7 +24,7 @@ # define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } # endif -typedef unsigned long long u64; +typedef uint64_t u64; # ifdef AES_LONG typedef unsigned long u32; # else diff --git a/crypto/openssl/crypto/aes/aes_misc.c b/crypto/openssl/crypto/aes/aes_misc.c index e0edc72ba71c..7f39bcf2b35f 100644 --- a/crypto/openssl/crypto/aes/aes_misc.c +++ b/crypto/openssl/crypto/aes/aes_misc.c @@ -1,7 +1,7 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,11 +11,13 @@ #include #include "aes_local.h" +#ifndef OPENSSL_NO_DEPRECATED_3_0 const char *AES_options(void) { -#ifdef FULL_UNROLL +# ifdef FULL_UNROLL return "aes(full)"; -#else +# else return "aes(partial)"; -#endif +# endif } +#endif diff --git a/crypto/openssl/crypto/aes/aes_ofb.c b/crypto/openssl/crypto/aes/aes_ofb.c index 215b53858eb6..58e47dc45e73 100644 --- a/crypto/openssl/crypto/aes/aes_ofb.c +++ b/crypto/openssl/crypto/aes/aes_ofb.c @@ -1,12 +1,18 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * AES_encrypt is deprecated - but we need to use it to implement + * AES_ofb128_encrypt + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/openssl/crypto/aes/aes_wrap.c b/crypto/openssl/crypto/aes/aes_wrap.c index cae0b212297a..2187883aff91 100644 --- a/crypto/openssl/crypto/aes/aes_wrap.c +++ b/crypto/openssl/crypto/aes/aes_wrap.c @@ -1,12 +1,18 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * AES_encrypt/AES_decrypt are deprecated - but we need to use them to implement + * these functions + */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" #include #include diff --git a/crypto/openssl/crypto/aes/aes_x86core.c b/crypto/openssl/crypto/aes/aes_x86core.c index 50b53abc1219..da525b6566c4 100644 --- a/crypto/openssl/crypto/aes/aes_x86core.c +++ b/crypto/openssl/crypto/aes/aes_x86core.c @@ -1,7 +1,7 @@ /* * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/aes/aesni-mb-x86_64.S b/crypto/openssl/crypto/aes/aesni-mb-x86_64.S new file mode 100644 index 000000000000..76b09bc7a57a --- /dev/null +++ b/crypto/openssl/crypto/aes/aesni-mb-x86_64.S @@ -0,0 +1,1609 @@ +.text + + + +.globl aesni_multi_cbc_encrypt +.type aesni_multi_cbc_encrypt,@function +.align 32 +aesni_multi_cbc_encrypt: +.cfi_startproc + cmpl $2,%edx + jb .Lenc_non_avx + movl OPENSSL_ia32cap_P+4(%rip),%ecx + testl $268435456,%ecx + jnz _avx_cbc_enc_shortcut + jmp .Lenc_non_avx +.align 16 +.Lenc_non_avx: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + + + + + + subq $48,%rsp + andq $-64,%rsp + movq %rax,16(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x10,0x06,0x23,0x08 + +.Lenc4x_body: + movdqu (%rsi),%xmm12 + leaq 120(%rsi),%rsi + leaq 80(%rdi),%rdi + +.Lenc4x_loop_grande: + movl %edx,24(%rsp) + xorl %edx,%edx + + movl -64(%rdi),%ecx + movq -80(%rdi),%r8 + cmpl %edx,%ecx + movq -72(%rdi),%r12 + cmovgl %ecx,%edx + testl %ecx,%ecx + + movdqu -56(%rdi),%xmm2 + movl %ecx,32(%rsp) + cmovleq %rsp,%r8 + + movl -24(%rdi),%ecx + movq -40(%rdi),%r9 + cmpl %edx,%ecx + movq -32(%rdi),%r13 + cmovgl %ecx,%edx + testl %ecx,%ecx + + movdqu -16(%rdi),%xmm3 + movl %ecx,36(%rsp) + cmovleq %rsp,%r9 + + movl 16(%rdi),%ecx + movq 0(%rdi),%r10 + cmpl %edx,%ecx + movq 8(%rdi),%r14 + cmovgl %ecx,%edx + testl %ecx,%ecx + + movdqu 24(%rdi),%xmm4 + movl %ecx,40(%rsp) + cmovleq %rsp,%r10 + + movl 56(%rdi),%ecx + movq 40(%rdi),%r11 + cmpl %edx,%ecx + movq 48(%rdi),%r15 + cmovgl %ecx,%edx + testl %ecx,%ecx + + movdqu 64(%rdi),%xmm5 + movl %ecx,44(%rsp) + cmovleq %rsp,%r11 + testl %edx,%edx + jz .Lenc4x_done + + movups 16-120(%rsi),%xmm1 + pxor %xmm12,%xmm2 + movups 32-120(%rsi),%xmm0 + pxor %xmm12,%xmm3 + movl 240-120(%rsi),%eax + pxor %xmm12,%xmm4 + movdqu (%r8),%xmm6 + pxor %xmm12,%xmm5 + movdqu (%r9),%xmm7 + pxor %xmm6,%xmm2 + movdqu (%r10),%xmm8 + pxor %xmm7,%xmm3 + movdqu (%r11),%xmm9 + pxor %xmm8,%xmm4 + pxor %xmm9,%xmm5 + movdqa 32(%rsp),%xmm10 + xorq %rbx,%rbx + jmp .Loop_enc4x + +.align 32 +.Loop_enc4x: + addq $16,%rbx + leaq 16(%rsp),%rbp + movl $1,%ecx + subq %rbx,%rbp + +.byte 102,15,56,220,209 + prefetcht0 31(%r8,%rbx,1) + prefetcht0 31(%r9,%rbx,1) +.byte 102,15,56,220,217 + prefetcht0 31(%r10,%rbx,1) + prefetcht0 31(%r10,%rbx,1) +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups 48-120(%rsi),%xmm1 + cmpl 32(%rsp),%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 + cmovgeq %rbp,%r8 + cmovgq %rbp,%r12 +.byte 102,15,56,220,232 + movups -56(%rsi),%xmm0 + cmpl 36(%rsp),%ecx +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 + cmovgeq %rbp,%r9 + cmovgq %rbp,%r13 +.byte 102,15,56,220,233 + movups -40(%rsi),%xmm1 + cmpl 40(%rsp),%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 + cmovgeq %rbp,%r10 + cmovgq %rbp,%r14 +.byte 102,15,56,220,232 + movups -24(%rsi),%xmm0 + cmpl 44(%rsp),%ecx +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 + cmovgeq %rbp,%r11 + cmovgq %rbp,%r15 +.byte 102,15,56,220,233 + movups -8(%rsi),%xmm1 + movdqa %xmm10,%xmm11 +.byte 102,15,56,220,208 + prefetcht0 15(%r12,%rbx,1) + prefetcht0 15(%r13,%rbx,1) +.byte 102,15,56,220,216 + prefetcht0 15(%r14,%rbx,1) + prefetcht0 15(%r15,%rbx,1) +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movups 128-120(%rsi),%xmm0 + pxor %xmm12,%xmm12 + +.byte 102,15,56,220,209 + pcmpgtd %xmm12,%xmm11 + movdqu -120(%rsi),%xmm12 +.byte 102,15,56,220,217 + paddd %xmm11,%xmm10 + movdqa %xmm10,32(%rsp) +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups 144-120(%rsi),%xmm1 + + cmpl $11,%eax + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movups 160-120(%rsi),%xmm0 + + jb .Lenc4x_tail + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups 176-120(%rsi),%xmm1 + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movups 192-120(%rsi),%xmm0 + + je .Lenc4x_tail + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups 208-120(%rsi),%xmm1 + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movups 224-120(%rsi),%xmm0 + jmp .Lenc4x_tail + +.align 32 +.Lenc4x_tail: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movdqu (%r8,%rbx,1),%xmm6 + movdqu 16-120(%rsi),%xmm1 + +.byte 102,15,56,221,208 + movdqu (%r9,%rbx,1),%xmm7 + pxor %xmm12,%xmm6 +.byte 102,15,56,221,216 + movdqu (%r10,%rbx,1),%xmm8 + pxor %xmm12,%xmm7 +.byte 102,15,56,221,224 + movdqu (%r11,%rbx,1),%xmm9 + pxor %xmm12,%xmm8 +.byte 102,15,56,221,232 + movdqu 32-120(%rsi),%xmm0 + pxor %xmm12,%xmm9 + + movups %xmm2,-16(%r12,%rbx,1) + pxor %xmm6,%xmm2 + movups %xmm3,-16(%r13,%rbx,1) + pxor %xmm7,%xmm3 + movups %xmm4,-16(%r14,%rbx,1) + pxor %xmm8,%xmm4 + movups %xmm5,-16(%r15,%rbx,1) + pxor %xmm9,%xmm5 + + decl %edx + jnz .Loop_enc4x + + movq 16(%rsp),%rax +.cfi_def_cfa %rax,8 + movl 24(%rsp),%edx + + + + + + + + + + + + leaq 160(%rdi),%rdi + decl %edx + jnz .Lenc4x_loop_grande + +.Lenc4x_done: + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lenc4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_multi_cbc_encrypt,.-aesni_multi_cbc_encrypt + +.globl aesni_multi_cbc_decrypt +.type aesni_multi_cbc_decrypt,@function +.align 32 +aesni_multi_cbc_decrypt: +.cfi_startproc + cmpl $2,%edx + jb .Ldec_non_avx + movl OPENSSL_ia32cap_P+4(%rip),%ecx + testl $268435456,%ecx + jnz _avx_cbc_dec_shortcut + jmp .Ldec_non_avx +.align 16 +.Ldec_non_avx: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + + + + + + subq $48,%rsp + andq $-64,%rsp + movq %rax,16(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x10,0x06,0x23,0x08 + +.Ldec4x_body: + movdqu (%rsi),%xmm12 + leaq 120(%rsi),%rsi + leaq 80(%rdi),%rdi + +.Ldec4x_loop_grande: + movl %edx,24(%rsp) + xorl %edx,%edx + + movl -64(%rdi),%ecx + movq -80(%rdi),%r8 + cmpl %edx,%ecx + movq -72(%rdi),%r12 + cmovgl %ecx,%edx + testl %ecx,%ecx + + movdqu -56(%rdi),%xmm6 + movl %ecx,32(%rsp) + cmovleq %rsp,%r8 + + movl -24(%rdi),%ecx + movq -40(%rdi),%r9 + cmpl %edx,%ecx + movq -32(%rdi),%r13 + cmovgl %ecx,%edx + testl %ecx,%ecx + + movdqu -16(%rdi),%xmm7 + movl %ecx,36(%rsp) + cmovleq %rsp,%r9 + + movl 16(%rdi),%ecx + movq 0(%rdi),%r10 + cmpl %edx,%ecx + movq 8(%rdi),%r14 + cmovgl %ecx,%edx + testl %ecx,%ecx + + movdqu 24(%rdi),%xmm8 + movl %ecx,40(%rsp) + cmovleq %rsp,%r10 + + movl 56(%rdi),%ecx + movq 40(%rdi),%r11 + cmpl %edx,%ecx + movq 48(%rdi),%r15 + cmovgl %ecx,%edx + testl %ecx,%ecx + + movdqu 64(%rdi),%xmm9 + movl %ecx,44(%rsp) + cmovleq %rsp,%r11 + testl %edx,%edx + jz .Ldec4x_done + + movups 16-120(%rsi),%xmm1 + movups 32-120(%rsi),%xmm0 + movl 240-120(%rsi),%eax + movdqu (%r8),%xmm2 + movdqu (%r9),%xmm3 + pxor %xmm12,%xmm2 + movdqu (%r10),%xmm4 + pxor %xmm12,%xmm3 + movdqu (%r11),%xmm5 + pxor %xmm12,%xmm4 + pxor %xmm12,%xmm5 + movdqa 32(%rsp),%xmm10 + xorq %rbx,%rbx + jmp .Loop_dec4x + +.align 32 +.Loop_dec4x: + addq $16,%rbx + leaq 16(%rsp),%rbp + movl $1,%ecx + subq %rbx,%rbp + +.byte 102,15,56,222,209 + prefetcht0 31(%r8,%rbx,1) + prefetcht0 31(%r9,%rbx,1) +.byte 102,15,56,222,217 + prefetcht0 31(%r10,%rbx,1) + prefetcht0 31(%r11,%rbx,1) +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups 48-120(%rsi),%xmm1 + cmpl 32(%rsp),%ecx +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 + cmovgeq %rbp,%r8 + cmovgq %rbp,%r12 +.byte 102,15,56,222,232 + movups -56(%rsi),%xmm0 + cmpl 36(%rsp),%ecx +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 + cmovgeq %rbp,%r9 + cmovgq %rbp,%r13 +.byte 102,15,56,222,233 + movups -40(%rsi),%xmm1 + cmpl 40(%rsp),%ecx +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 + cmovgeq %rbp,%r10 + cmovgq %rbp,%r14 +.byte 102,15,56,222,232 + movups -24(%rsi),%xmm0 + cmpl 44(%rsp),%ecx +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 + cmovgeq %rbp,%r11 + cmovgq %rbp,%r15 +.byte 102,15,56,222,233 + movups -8(%rsi),%xmm1 + movdqa %xmm10,%xmm11 +.byte 102,15,56,222,208 + prefetcht0 15(%r12,%rbx,1) + prefetcht0 15(%r13,%rbx,1) +.byte 102,15,56,222,216 + prefetcht0 15(%r14,%rbx,1) + prefetcht0 15(%r15,%rbx,1) +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + movups 128-120(%rsi),%xmm0 + pxor %xmm12,%xmm12 + +.byte 102,15,56,222,209 + pcmpgtd %xmm12,%xmm11 + movdqu -120(%rsi),%xmm12 +.byte 102,15,56,222,217 + paddd %xmm11,%xmm10 + movdqa %xmm10,32(%rsp) +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups 144-120(%rsi),%xmm1 + + cmpl $11,%eax + +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + movups 160-120(%rsi),%xmm0 + + jb .Ldec4x_tail + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups 176-120(%rsi),%xmm1 + +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + movups 192-120(%rsi),%xmm0 + + je .Ldec4x_tail + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups 208-120(%rsi),%xmm1 + +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + movups 224-120(%rsi),%xmm0 + jmp .Ldec4x_tail + +.align 32 +.Ldec4x_tail: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 + pxor %xmm0,%xmm6 + pxor %xmm0,%xmm7 +.byte 102,15,56,222,233 + movdqu 16-120(%rsi),%xmm1 + pxor %xmm0,%xmm8 + pxor %xmm0,%xmm9 + movdqu 32-120(%rsi),%xmm0 + +.byte 102,15,56,223,214 +.byte 102,15,56,223,223 + movdqu -16(%r8,%rbx,1),%xmm6 + movdqu -16(%r9,%rbx,1),%xmm7 +.byte 102,65,15,56,223,224 +.byte 102,65,15,56,223,233 + movdqu -16(%r10,%rbx,1),%xmm8 + movdqu -16(%r11,%rbx,1),%xmm9 + + movups %xmm2,-16(%r12,%rbx,1) + movdqu (%r8,%rbx,1),%xmm2 + movups %xmm3,-16(%r13,%rbx,1) + movdqu (%r9,%rbx,1),%xmm3 + pxor %xmm12,%xmm2 + movups %xmm4,-16(%r14,%rbx,1) + movdqu (%r10,%rbx,1),%xmm4 + pxor %xmm12,%xmm3 + movups %xmm5,-16(%r15,%rbx,1) + movdqu (%r11,%rbx,1),%xmm5 + pxor %xmm12,%xmm4 + pxor %xmm12,%xmm5 + + decl %edx + jnz .Loop_dec4x + + movq 16(%rsp),%rax +.cfi_def_cfa %rax,8 + movl 24(%rsp),%edx + + leaq 160(%rdi),%rdi + decl %edx + jnz .Ldec4x_loop_grande + +.Ldec4x_done: + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Ldec4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_multi_cbc_decrypt,.-aesni_multi_cbc_decrypt +.type aesni_multi_cbc_encrypt_avx,@function +.align 32 +aesni_multi_cbc_encrypt_avx: +.cfi_startproc +_avx_cbc_enc_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + + + + + + + + subq $192,%rsp + andq $-128,%rsp + movq %rax,16(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x10,0x06,0x23,0x08 + +.Lenc8x_body: + vzeroupper + vmovdqu (%rsi),%xmm15 + leaq 120(%rsi),%rsi + leaq 160(%rdi),%rdi + shrl $1,%edx + +.Lenc8x_loop_grande: + + xorl %edx,%edx + + movl -144(%rdi),%ecx + + movq -160(%rdi),%r8 + cmpl %edx,%ecx + + movq -152(%rdi),%rbx + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu -136(%rdi),%xmm2 + movl %ecx,32(%rsp) + cmovleq %rsp,%r8 + subq %r8,%rbx + movq %rbx,64(%rsp) + + movl -104(%rdi),%ecx + + movq -120(%rdi),%r9 + cmpl %edx,%ecx + + movq -112(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu -96(%rdi),%xmm3 + movl %ecx,36(%rsp) + cmovleq %rsp,%r9 + subq %r9,%rbp + movq %rbp,72(%rsp) + + movl -64(%rdi),%ecx + + movq -80(%rdi),%r10 + cmpl %edx,%ecx + + movq -72(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu -56(%rdi),%xmm4 + movl %ecx,40(%rsp) + cmovleq %rsp,%r10 + subq %r10,%rbp + movq %rbp,80(%rsp) + + movl -24(%rdi),%ecx + + movq -40(%rdi),%r11 + cmpl %edx,%ecx + + movq -32(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu -16(%rdi),%xmm5 + movl %ecx,44(%rsp) + cmovleq %rsp,%r11 + subq %r11,%rbp + movq %rbp,88(%rsp) + + movl 16(%rdi),%ecx + + movq 0(%rdi),%r12 + cmpl %edx,%ecx + + movq 8(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu 24(%rdi),%xmm6 + movl %ecx,48(%rsp) + cmovleq %rsp,%r12 + subq %r12,%rbp + movq %rbp,96(%rsp) + + movl 56(%rdi),%ecx + + movq 40(%rdi),%r13 + cmpl %edx,%ecx + + movq 48(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu 64(%rdi),%xmm7 + movl %ecx,52(%rsp) + cmovleq %rsp,%r13 + subq %r13,%rbp + movq %rbp,104(%rsp) + + movl 96(%rdi),%ecx + + movq 80(%rdi),%r14 + cmpl %edx,%ecx + + movq 88(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu 104(%rdi),%xmm8 + movl %ecx,56(%rsp) + cmovleq %rsp,%r14 + subq %r14,%rbp + movq %rbp,112(%rsp) + + movl 136(%rdi),%ecx + + movq 120(%rdi),%r15 + cmpl %edx,%ecx + + movq 128(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu 144(%rdi),%xmm9 + movl %ecx,60(%rsp) + cmovleq %rsp,%r15 + subq %r15,%rbp + movq %rbp,120(%rsp) + testl %edx,%edx + jz .Lenc8x_done + + vmovups 16-120(%rsi),%xmm1 + vmovups 32-120(%rsi),%xmm0 + movl 240-120(%rsi),%eax + + vpxor (%r8),%xmm15,%xmm10 + leaq 128(%rsp),%rbp + vpxor (%r9),%xmm15,%xmm11 + vpxor (%r10),%xmm15,%xmm12 + vpxor (%r11),%xmm15,%xmm13 + vpxor %xmm10,%xmm2,%xmm2 + vpxor (%r12),%xmm15,%xmm10 + vpxor %xmm11,%xmm3,%xmm3 + vpxor (%r13),%xmm15,%xmm11 + vpxor %xmm12,%xmm4,%xmm4 + vpxor (%r14),%xmm15,%xmm12 + vpxor %xmm13,%xmm5,%xmm5 + vpxor (%r15),%xmm15,%xmm13 + vpxor %xmm10,%xmm6,%xmm6 + movl $1,%ecx + vpxor %xmm11,%xmm7,%xmm7 + vpxor %xmm12,%xmm8,%xmm8 + vpxor %xmm13,%xmm9,%xmm9 + jmp .Loop_enc8x + +.align 32 +.Loop_enc8x: + vaesenc %xmm1,%xmm2,%xmm2 + cmpl 32+0(%rsp),%ecx + vaesenc %xmm1,%xmm3,%xmm3 + prefetcht0 31(%r8) + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm5,%xmm5 + leaq (%r8,%rbx,1),%rbx + cmovgeq %rsp,%r8 + vaesenc %xmm1,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesenc %xmm1,%xmm7,%xmm7 + subq %r8,%rbx + vaesenc %xmm1,%xmm8,%xmm8 + vpxor 16(%r8),%xmm15,%xmm10 + movq %rbx,64+0(%rsp) + vaesenc %xmm1,%xmm9,%xmm9 + vmovups -72(%rsi),%xmm1 + leaq 16(%r8,%rbx,1),%r8 + vmovdqu %xmm10,0(%rbp) + vaesenc %xmm0,%xmm2,%xmm2 + cmpl 32+4(%rsp),%ecx + movq 64+8(%rsp),%rbx + vaesenc %xmm0,%xmm3,%xmm3 + prefetcht0 31(%r9) + vaesenc %xmm0,%xmm4,%xmm4 + vaesenc %xmm0,%xmm5,%xmm5 + leaq (%r9,%rbx,1),%rbx + cmovgeq %rsp,%r9 + vaesenc %xmm0,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesenc %xmm0,%xmm7,%xmm7 + subq %r9,%rbx + vaesenc %xmm0,%xmm8,%xmm8 + vpxor 16(%r9),%xmm15,%xmm11 + movq %rbx,64+8(%rsp) + vaesenc %xmm0,%xmm9,%xmm9 + vmovups -56(%rsi),%xmm0 + leaq 16(%r9,%rbx,1),%r9 + vmovdqu %xmm11,16(%rbp) + vaesenc %xmm1,%xmm2,%xmm2 + cmpl 32+8(%rsp),%ecx + movq 64+16(%rsp),%rbx + vaesenc %xmm1,%xmm3,%xmm3 + prefetcht0 31(%r10) + vaesenc %xmm1,%xmm4,%xmm4 + prefetcht0 15(%r8) + vaesenc %xmm1,%xmm5,%xmm5 + leaq (%r10,%rbx,1),%rbx + cmovgeq %rsp,%r10 + vaesenc %xmm1,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesenc %xmm1,%xmm7,%xmm7 + subq %r10,%rbx + vaesenc %xmm1,%xmm8,%xmm8 + vpxor 16(%r10),%xmm15,%xmm12 + movq %rbx,64+16(%rsp) + vaesenc %xmm1,%xmm9,%xmm9 + vmovups -40(%rsi),%xmm1 + leaq 16(%r10,%rbx,1),%r10 + vmovdqu %xmm12,32(%rbp) + vaesenc %xmm0,%xmm2,%xmm2 + cmpl 32+12(%rsp),%ecx + movq 64+24(%rsp),%rbx + vaesenc %xmm0,%xmm3,%xmm3 + prefetcht0 31(%r11) + vaesenc %xmm0,%xmm4,%xmm4 + prefetcht0 15(%r9) + vaesenc %xmm0,%xmm5,%xmm5 + leaq (%r11,%rbx,1),%rbx + cmovgeq %rsp,%r11 + vaesenc %xmm0,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesenc %xmm0,%xmm7,%xmm7 + subq %r11,%rbx + vaesenc %xmm0,%xmm8,%xmm8 + vpxor 16(%r11),%xmm15,%xmm13 + movq %rbx,64+24(%rsp) + vaesenc %xmm0,%xmm9,%xmm9 + vmovups -24(%rsi),%xmm0 + leaq 16(%r11,%rbx,1),%r11 + vmovdqu %xmm13,48(%rbp) + vaesenc %xmm1,%xmm2,%xmm2 + cmpl 32+16(%rsp),%ecx + movq 64+32(%rsp),%rbx + vaesenc %xmm1,%xmm3,%xmm3 + prefetcht0 31(%r12) + vaesenc %xmm1,%xmm4,%xmm4 + prefetcht0 15(%r10) + vaesenc %xmm1,%xmm5,%xmm5 + leaq (%r12,%rbx,1),%rbx + cmovgeq %rsp,%r12 + vaesenc %xmm1,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesenc %xmm1,%xmm7,%xmm7 + subq %r12,%rbx + vaesenc %xmm1,%xmm8,%xmm8 + vpxor 16(%r12),%xmm15,%xmm10 + movq %rbx,64+32(%rsp) + vaesenc %xmm1,%xmm9,%xmm9 + vmovups -8(%rsi),%xmm1 + leaq 16(%r12,%rbx,1),%r12 + vaesenc %xmm0,%xmm2,%xmm2 + cmpl 32+20(%rsp),%ecx + movq 64+40(%rsp),%rbx + vaesenc %xmm0,%xmm3,%xmm3 + prefetcht0 31(%r13) + vaesenc %xmm0,%xmm4,%xmm4 + prefetcht0 15(%r11) + vaesenc %xmm0,%xmm5,%xmm5 + leaq (%rbx,%r13,1),%rbx + cmovgeq %rsp,%r13 + vaesenc %xmm0,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesenc %xmm0,%xmm7,%xmm7 + subq %r13,%rbx + vaesenc %xmm0,%xmm8,%xmm8 + vpxor 16(%r13),%xmm15,%xmm11 + movq %rbx,64+40(%rsp) + vaesenc %xmm0,%xmm9,%xmm9 + vmovups 8(%rsi),%xmm0 + leaq 16(%r13,%rbx,1),%r13 + vaesenc %xmm1,%xmm2,%xmm2 + cmpl 32+24(%rsp),%ecx + movq 64+48(%rsp),%rbx + vaesenc %xmm1,%xmm3,%xmm3 + prefetcht0 31(%r14) + vaesenc %xmm1,%xmm4,%xmm4 + prefetcht0 15(%r12) + vaesenc %xmm1,%xmm5,%xmm5 + leaq (%r14,%rbx,1),%rbx + cmovgeq %rsp,%r14 + vaesenc %xmm1,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesenc %xmm1,%xmm7,%xmm7 + subq %r14,%rbx + vaesenc %xmm1,%xmm8,%xmm8 + vpxor 16(%r14),%xmm15,%xmm12 + movq %rbx,64+48(%rsp) + vaesenc %xmm1,%xmm9,%xmm9 + vmovups 24(%rsi),%xmm1 + leaq 16(%r14,%rbx,1),%r14 + vaesenc %xmm0,%xmm2,%xmm2 + cmpl 32+28(%rsp),%ecx + movq 64+56(%rsp),%rbx + vaesenc %xmm0,%xmm3,%xmm3 + prefetcht0 31(%r15) + vaesenc %xmm0,%xmm4,%xmm4 + prefetcht0 15(%r13) + vaesenc %xmm0,%xmm5,%xmm5 + leaq (%r15,%rbx,1),%rbx + cmovgeq %rsp,%r15 + vaesenc %xmm0,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesenc %xmm0,%xmm7,%xmm7 + subq %r15,%rbx + vaesenc %xmm0,%xmm8,%xmm8 + vpxor 16(%r15),%xmm15,%xmm13 + movq %rbx,64+56(%rsp) + vaesenc %xmm0,%xmm9,%xmm9 + vmovups 40(%rsi),%xmm0 + leaq 16(%r15,%rbx,1),%r15 + vmovdqu 32(%rsp),%xmm14 + prefetcht0 15(%r14) + prefetcht0 15(%r15) + cmpl $11,%eax + jb .Lenc8x_tail + + vaesenc %xmm1,%xmm2,%xmm2 + vaesenc %xmm1,%xmm3,%xmm3 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm5,%xmm5 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm8,%xmm8 + vaesenc %xmm1,%xmm9,%xmm9 + vmovups 176-120(%rsi),%xmm1 + + vaesenc %xmm0,%xmm2,%xmm2 + vaesenc %xmm0,%xmm3,%xmm3 + vaesenc %xmm0,%xmm4,%xmm4 + vaesenc %xmm0,%xmm5,%xmm5 + vaesenc %xmm0,%xmm6,%xmm6 + vaesenc %xmm0,%xmm7,%xmm7 + vaesenc %xmm0,%xmm8,%xmm8 + vaesenc %xmm0,%xmm9,%xmm9 + vmovups 192-120(%rsi),%xmm0 + je .Lenc8x_tail + + vaesenc %xmm1,%xmm2,%xmm2 + vaesenc %xmm1,%xmm3,%xmm3 + vaesenc %xmm1,%xmm4,%xmm4 + vaesenc %xmm1,%xmm5,%xmm5 + vaesenc %xmm1,%xmm6,%xmm6 + vaesenc %xmm1,%xmm7,%xmm7 + vaesenc %xmm1,%xmm8,%xmm8 + vaesenc %xmm1,%xmm9,%xmm9 + vmovups 208-120(%rsi),%xmm1 + + vaesenc %xmm0,%xmm2,%xmm2 + vaesenc %xmm0,%xmm3,%xmm3 + vaesenc %xmm0,%xmm4,%xmm4 + vaesenc %xmm0,%xmm5,%xmm5 + vaesenc %xmm0,%xmm6,%xmm6 + vaesenc %xmm0,%xmm7,%xmm7 + vaesenc %xmm0,%xmm8,%xmm8 + vaesenc %xmm0,%xmm9,%xmm9 + vmovups 224-120(%rsi),%xmm0 + +.Lenc8x_tail: + vaesenc %xmm1,%xmm2,%xmm2 + vpxor %xmm15,%xmm15,%xmm15 + vaesenc %xmm1,%xmm3,%xmm3 + vaesenc %xmm1,%xmm4,%xmm4 + vpcmpgtd %xmm15,%xmm14,%xmm15 + vaesenc %xmm1,%xmm5,%xmm5 + vaesenc %xmm1,%xmm6,%xmm6 + vpaddd %xmm14,%xmm15,%xmm15 + vmovdqu 48(%rsp),%xmm14 + vaesenc %xmm1,%xmm7,%xmm7 + movq 64(%rsp),%rbx + vaesenc %xmm1,%xmm8,%xmm8 + vaesenc %xmm1,%xmm9,%xmm9 + vmovups 16-120(%rsi),%xmm1 + + vaesenclast %xmm0,%xmm2,%xmm2 + vmovdqa %xmm15,32(%rsp) + vpxor %xmm15,%xmm15,%xmm15 + vaesenclast %xmm0,%xmm3,%xmm3 + vaesenclast %xmm0,%xmm4,%xmm4 + vpcmpgtd %xmm15,%xmm14,%xmm15 + vaesenclast %xmm0,%xmm5,%xmm5 + vaesenclast %xmm0,%xmm6,%xmm6 + vpaddd %xmm15,%xmm14,%xmm14 + vmovdqu -120(%rsi),%xmm15 + vaesenclast %xmm0,%xmm7,%xmm7 + vaesenclast %xmm0,%xmm8,%xmm8 + vmovdqa %xmm14,48(%rsp) + vaesenclast %xmm0,%xmm9,%xmm9 + vmovups 32-120(%rsi),%xmm0 + + vmovups %xmm2,-16(%r8) + subq %rbx,%r8 + vpxor 0(%rbp),%xmm2,%xmm2 + vmovups %xmm3,-16(%r9) + subq 72(%rsp),%r9 + vpxor 16(%rbp),%xmm3,%xmm3 + vmovups %xmm4,-16(%r10) + subq 80(%rsp),%r10 + vpxor 32(%rbp),%xmm4,%xmm4 + vmovups %xmm5,-16(%r11) + subq 88(%rsp),%r11 + vpxor 48(%rbp),%xmm5,%xmm5 + vmovups %xmm6,-16(%r12) + subq 96(%rsp),%r12 + vpxor %xmm10,%xmm6,%xmm6 + vmovups %xmm7,-16(%r13) + subq 104(%rsp),%r13 + vpxor %xmm11,%xmm7,%xmm7 + vmovups %xmm8,-16(%r14) + subq 112(%rsp),%r14 + vpxor %xmm12,%xmm8,%xmm8 + vmovups %xmm9,-16(%r15) + subq 120(%rsp),%r15 + vpxor %xmm13,%xmm9,%xmm9 + + decl %edx + jnz .Loop_enc8x + + movq 16(%rsp),%rax +.cfi_def_cfa %rax,8 + + + + + +.Lenc8x_done: + vzeroupper + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lenc8x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_multi_cbc_encrypt_avx,.-aesni_multi_cbc_encrypt_avx + +.type aesni_multi_cbc_decrypt_avx,@function +.align 32 +aesni_multi_cbc_decrypt_avx: +.cfi_startproc +_avx_cbc_dec_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + + + + + + + + + subq $256,%rsp + andq $-256,%rsp + subq $192,%rsp + movq %rax,16(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x10,0x06,0x23,0x08 + +.Ldec8x_body: + vzeroupper + vmovdqu (%rsi),%xmm15 + leaq 120(%rsi),%rsi + leaq 160(%rdi),%rdi + shrl $1,%edx + +.Ldec8x_loop_grande: + + xorl %edx,%edx + + movl -144(%rdi),%ecx + + movq -160(%rdi),%r8 + cmpl %edx,%ecx + + movq -152(%rdi),%rbx + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu -136(%rdi),%xmm2 + movl %ecx,32(%rsp) + cmovleq %rsp,%r8 + subq %r8,%rbx + movq %rbx,64(%rsp) + vmovdqu %xmm2,192(%rsp) + + movl -104(%rdi),%ecx + + movq -120(%rdi),%r9 + cmpl %edx,%ecx + + movq -112(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu -96(%rdi),%xmm3 + movl %ecx,36(%rsp) + cmovleq %rsp,%r9 + subq %r9,%rbp + movq %rbp,72(%rsp) + vmovdqu %xmm3,208(%rsp) + + movl -64(%rdi),%ecx + + movq -80(%rdi),%r10 + cmpl %edx,%ecx + + movq -72(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu -56(%rdi),%xmm4 + movl %ecx,40(%rsp) + cmovleq %rsp,%r10 + subq %r10,%rbp + movq %rbp,80(%rsp) + vmovdqu %xmm4,224(%rsp) + + movl -24(%rdi),%ecx + + movq -40(%rdi),%r11 + cmpl %edx,%ecx + + movq -32(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu -16(%rdi),%xmm5 + movl %ecx,44(%rsp) + cmovleq %rsp,%r11 + subq %r11,%rbp + movq %rbp,88(%rsp) + vmovdqu %xmm5,240(%rsp) + + movl 16(%rdi),%ecx + + movq 0(%rdi),%r12 + cmpl %edx,%ecx + + movq 8(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu 24(%rdi),%xmm6 + movl %ecx,48(%rsp) + cmovleq %rsp,%r12 + subq %r12,%rbp + movq %rbp,96(%rsp) + vmovdqu %xmm6,256(%rsp) + + movl 56(%rdi),%ecx + + movq 40(%rdi),%r13 + cmpl %edx,%ecx + + movq 48(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu 64(%rdi),%xmm7 + movl %ecx,52(%rsp) + cmovleq %rsp,%r13 + subq %r13,%rbp + movq %rbp,104(%rsp) + vmovdqu %xmm7,272(%rsp) + + movl 96(%rdi),%ecx + + movq 80(%rdi),%r14 + cmpl %edx,%ecx + + movq 88(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu 104(%rdi),%xmm8 + movl %ecx,56(%rsp) + cmovleq %rsp,%r14 + subq %r14,%rbp + movq %rbp,112(%rsp) + vmovdqu %xmm8,288(%rsp) + + movl 136(%rdi),%ecx + + movq 120(%rdi),%r15 + cmpl %edx,%ecx + + movq 128(%rdi),%rbp + cmovgl %ecx,%edx + testl %ecx,%ecx + + vmovdqu 144(%rdi),%xmm9 + movl %ecx,60(%rsp) + cmovleq %rsp,%r15 + subq %r15,%rbp + movq %rbp,120(%rsp) + vmovdqu %xmm9,304(%rsp) + testl %edx,%edx + jz .Ldec8x_done + + vmovups 16-120(%rsi),%xmm1 + vmovups 32-120(%rsi),%xmm0 + movl 240-120(%rsi),%eax + leaq 192+128(%rsp),%rbp + + vmovdqu (%r8),%xmm2 + vmovdqu (%r9),%xmm3 + vmovdqu (%r10),%xmm4 + vmovdqu (%r11),%xmm5 + vmovdqu (%r12),%xmm6 + vmovdqu (%r13),%xmm7 + vmovdqu (%r14),%xmm8 + vmovdqu (%r15),%xmm9 + vmovdqu %xmm2,0(%rbp) + vpxor %xmm15,%xmm2,%xmm2 + vmovdqu %xmm3,16(%rbp) + vpxor %xmm15,%xmm3,%xmm3 + vmovdqu %xmm4,32(%rbp) + vpxor %xmm15,%xmm4,%xmm4 + vmovdqu %xmm5,48(%rbp) + vpxor %xmm15,%xmm5,%xmm5 + vmovdqu %xmm6,64(%rbp) + vpxor %xmm15,%xmm6,%xmm6 + vmovdqu %xmm7,80(%rbp) + vpxor %xmm15,%xmm7,%xmm7 + vmovdqu %xmm8,96(%rbp) + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu %xmm9,112(%rbp) + vpxor %xmm15,%xmm9,%xmm9 + xorq $0x80,%rbp + movl $1,%ecx + jmp .Loop_dec8x + +.align 32 +.Loop_dec8x: + vaesdec %xmm1,%xmm2,%xmm2 + cmpl 32+0(%rsp),%ecx + vaesdec %xmm1,%xmm3,%xmm3 + prefetcht0 31(%r8) + vaesdec %xmm1,%xmm4,%xmm4 + vaesdec %xmm1,%xmm5,%xmm5 + leaq (%r8,%rbx,1),%rbx + cmovgeq %rsp,%r8 + vaesdec %xmm1,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesdec %xmm1,%xmm7,%xmm7 + subq %r8,%rbx + vaesdec %xmm1,%xmm8,%xmm8 + vmovdqu 16(%r8),%xmm10 + movq %rbx,64+0(%rsp) + vaesdec %xmm1,%xmm9,%xmm9 + vmovups -72(%rsi),%xmm1 + leaq 16(%r8,%rbx,1),%r8 + vmovdqu %xmm10,128(%rsp) + vaesdec %xmm0,%xmm2,%xmm2 + cmpl 32+4(%rsp),%ecx + movq 64+8(%rsp),%rbx + vaesdec %xmm0,%xmm3,%xmm3 + prefetcht0 31(%r9) + vaesdec %xmm0,%xmm4,%xmm4 + vaesdec %xmm0,%xmm5,%xmm5 + leaq (%r9,%rbx,1),%rbx + cmovgeq %rsp,%r9 + vaesdec %xmm0,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesdec %xmm0,%xmm7,%xmm7 + subq %r9,%rbx + vaesdec %xmm0,%xmm8,%xmm8 + vmovdqu 16(%r9),%xmm11 + movq %rbx,64+8(%rsp) + vaesdec %xmm0,%xmm9,%xmm9 + vmovups -56(%rsi),%xmm0 + leaq 16(%r9,%rbx,1),%r9 + vmovdqu %xmm11,144(%rsp) + vaesdec %xmm1,%xmm2,%xmm2 + cmpl 32+8(%rsp),%ecx + movq 64+16(%rsp),%rbx + vaesdec %xmm1,%xmm3,%xmm3 + prefetcht0 31(%r10) + vaesdec %xmm1,%xmm4,%xmm4 + prefetcht0 15(%r8) + vaesdec %xmm1,%xmm5,%xmm5 + leaq (%r10,%rbx,1),%rbx + cmovgeq %rsp,%r10 + vaesdec %xmm1,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesdec %xmm1,%xmm7,%xmm7 + subq %r10,%rbx + vaesdec %xmm1,%xmm8,%xmm8 + vmovdqu 16(%r10),%xmm12 + movq %rbx,64+16(%rsp) + vaesdec %xmm1,%xmm9,%xmm9 + vmovups -40(%rsi),%xmm1 + leaq 16(%r10,%rbx,1),%r10 + vmovdqu %xmm12,160(%rsp) + vaesdec %xmm0,%xmm2,%xmm2 + cmpl 32+12(%rsp),%ecx + movq 64+24(%rsp),%rbx + vaesdec %xmm0,%xmm3,%xmm3 + prefetcht0 31(%r11) + vaesdec %xmm0,%xmm4,%xmm4 + prefetcht0 15(%r9) + vaesdec %xmm0,%xmm5,%xmm5 + leaq (%r11,%rbx,1),%rbx + cmovgeq %rsp,%r11 + vaesdec %xmm0,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesdec %xmm0,%xmm7,%xmm7 + subq %r11,%rbx + vaesdec %xmm0,%xmm8,%xmm8 + vmovdqu 16(%r11),%xmm13 + movq %rbx,64+24(%rsp) + vaesdec %xmm0,%xmm9,%xmm9 + vmovups -24(%rsi),%xmm0 + leaq 16(%r11,%rbx,1),%r11 + vmovdqu %xmm13,176(%rsp) + vaesdec %xmm1,%xmm2,%xmm2 + cmpl 32+16(%rsp),%ecx + movq 64+32(%rsp),%rbx + vaesdec %xmm1,%xmm3,%xmm3 + prefetcht0 31(%r12) + vaesdec %xmm1,%xmm4,%xmm4 + prefetcht0 15(%r10) + vaesdec %xmm1,%xmm5,%xmm5 + leaq (%r12,%rbx,1),%rbx + cmovgeq %rsp,%r12 + vaesdec %xmm1,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesdec %xmm1,%xmm7,%xmm7 + subq %r12,%rbx + vaesdec %xmm1,%xmm8,%xmm8 + vmovdqu 16(%r12),%xmm10 + movq %rbx,64+32(%rsp) + vaesdec %xmm1,%xmm9,%xmm9 + vmovups -8(%rsi),%xmm1 + leaq 16(%r12,%rbx,1),%r12 + vaesdec %xmm0,%xmm2,%xmm2 + cmpl 32+20(%rsp),%ecx + movq 64+40(%rsp),%rbx + vaesdec %xmm0,%xmm3,%xmm3 + prefetcht0 31(%r13) + vaesdec %xmm0,%xmm4,%xmm4 + prefetcht0 15(%r11) + vaesdec %xmm0,%xmm5,%xmm5 + leaq (%rbx,%r13,1),%rbx + cmovgeq %rsp,%r13 + vaesdec %xmm0,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesdec %xmm0,%xmm7,%xmm7 + subq %r13,%rbx + vaesdec %xmm0,%xmm8,%xmm8 + vmovdqu 16(%r13),%xmm11 + movq %rbx,64+40(%rsp) + vaesdec %xmm0,%xmm9,%xmm9 + vmovups 8(%rsi),%xmm0 + leaq 16(%r13,%rbx,1),%r13 + vaesdec %xmm1,%xmm2,%xmm2 + cmpl 32+24(%rsp),%ecx + movq 64+48(%rsp),%rbx + vaesdec %xmm1,%xmm3,%xmm3 + prefetcht0 31(%r14) + vaesdec %xmm1,%xmm4,%xmm4 + prefetcht0 15(%r12) + vaesdec %xmm1,%xmm5,%xmm5 + leaq (%r14,%rbx,1),%rbx + cmovgeq %rsp,%r14 + vaesdec %xmm1,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesdec %xmm1,%xmm7,%xmm7 + subq %r14,%rbx + vaesdec %xmm1,%xmm8,%xmm8 + vmovdqu 16(%r14),%xmm12 + movq %rbx,64+48(%rsp) + vaesdec %xmm1,%xmm9,%xmm9 + vmovups 24(%rsi),%xmm1 + leaq 16(%r14,%rbx,1),%r14 + vaesdec %xmm0,%xmm2,%xmm2 + cmpl 32+28(%rsp),%ecx + movq 64+56(%rsp),%rbx + vaesdec %xmm0,%xmm3,%xmm3 + prefetcht0 31(%r15) + vaesdec %xmm0,%xmm4,%xmm4 + prefetcht0 15(%r13) + vaesdec %xmm0,%xmm5,%xmm5 + leaq (%r15,%rbx,1),%rbx + cmovgeq %rsp,%r15 + vaesdec %xmm0,%xmm6,%xmm6 + cmovgq %rsp,%rbx + vaesdec %xmm0,%xmm7,%xmm7 + subq %r15,%rbx + vaesdec %xmm0,%xmm8,%xmm8 + vmovdqu 16(%r15),%xmm13 + movq %rbx,64+56(%rsp) + vaesdec %xmm0,%xmm9,%xmm9 + vmovups 40(%rsi),%xmm0 + leaq 16(%r15,%rbx,1),%r15 + vmovdqu 32(%rsp),%xmm14 + prefetcht0 15(%r14) + prefetcht0 15(%r15) + cmpl $11,%eax + jb .Ldec8x_tail + + vaesdec %xmm1,%xmm2,%xmm2 + vaesdec %xmm1,%xmm3,%xmm3 + vaesdec %xmm1,%xmm4,%xmm4 + vaesdec %xmm1,%xmm5,%xmm5 + vaesdec %xmm1,%xmm6,%xmm6 + vaesdec %xmm1,%xmm7,%xmm7 + vaesdec %xmm1,%xmm8,%xmm8 + vaesdec %xmm1,%xmm9,%xmm9 + vmovups 176-120(%rsi),%xmm1 + + vaesdec %xmm0,%xmm2,%xmm2 + vaesdec %xmm0,%xmm3,%xmm3 + vaesdec %xmm0,%xmm4,%xmm4 + vaesdec %xmm0,%xmm5,%xmm5 + vaesdec %xmm0,%xmm6,%xmm6 + vaesdec %xmm0,%xmm7,%xmm7 + vaesdec %xmm0,%xmm8,%xmm8 + vaesdec %xmm0,%xmm9,%xmm9 + vmovups 192-120(%rsi),%xmm0 + je .Ldec8x_tail + + vaesdec %xmm1,%xmm2,%xmm2 + vaesdec %xmm1,%xmm3,%xmm3 + vaesdec %xmm1,%xmm4,%xmm4 + vaesdec %xmm1,%xmm5,%xmm5 + vaesdec %xmm1,%xmm6,%xmm6 + vaesdec %xmm1,%xmm7,%xmm7 + vaesdec %xmm1,%xmm8,%xmm8 + vaesdec %xmm1,%xmm9,%xmm9 + vmovups 208-120(%rsi),%xmm1 + + vaesdec %xmm0,%xmm2,%xmm2 + vaesdec %xmm0,%xmm3,%xmm3 + vaesdec %xmm0,%xmm4,%xmm4 + vaesdec %xmm0,%xmm5,%xmm5 + vaesdec %xmm0,%xmm6,%xmm6 + vaesdec %xmm0,%xmm7,%xmm7 + vaesdec %xmm0,%xmm8,%xmm8 + vaesdec %xmm0,%xmm9,%xmm9 + vmovups 224-120(%rsi),%xmm0 + +.Ldec8x_tail: + vaesdec %xmm1,%xmm2,%xmm2 + vpxor %xmm15,%xmm15,%xmm15 + vaesdec %xmm1,%xmm3,%xmm3 + vaesdec %xmm1,%xmm4,%xmm4 + vpcmpgtd %xmm15,%xmm14,%xmm15 + vaesdec %xmm1,%xmm5,%xmm5 + vaesdec %xmm1,%xmm6,%xmm6 + vpaddd %xmm14,%xmm15,%xmm15 + vmovdqu 48(%rsp),%xmm14 + vaesdec %xmm1,%xmm7,%xmm7 + movq 64(%rsp),%rbx + vaesdec %xmm1,%xmm8,%xmm8 + vaesdec %xmm1,%xmm9,%xmm9 + vmovups 16-120(%rsi),%xmm1 + + vaesdeclast %xmm0,%xmm2,%xmm2 + vmovdqa %xmm15,32(%rsp) + vpxor %xmm15,%xmm15,%xmm15 + vaesdeclast %xmm0,%xmm3,%xmm3 + vpxor 0(%rbp),%xmm2,%xmm2 + vaesdeclast %xmm0,%xmm4,%xmm4 + vpxor 16(%rbp),%xmm3,%xmm3 + vpcmpgtd %xmm15,%xmm14,%xmm15 + vaesdeclast %xmm0,%xmm5,%xmm5 + vpxor 32(%rbp),%xmm4,%xmm4 + vaesdeclast %xmm0,%xmm6,%xmm6 + vpxor 48(%rbp),%xmm5,%xmm5 + vpaddd %xmm15,%xmm14,%xmm14 + vmovdqu -120(%rsi),%xmm15 + vaesdeclast %xmm0,%xmm7,%xmm7 + vpxor 64(%rbp),%xmm6,%xmm6 + vaesdeclast %xmm0,%xmm8,%xmm8 + vpxor 80(%rbp),%xmm7,%xmm7 + vmovdqa %xmm14,48(%rsp) + vaesdeclast %xmm0,%xmm9,%xmm9 + vpxor 96(%rbp),%xmm8,%xmm8 + vmovups 32-120(%rsi),%xmm0 + + vmovups %xmm2,-16(%r8) + subq %rbx,%r8 + vmovdqu 128+0(%rsp),%xmm2 + vpxor 112(%rbp),%xmm9,%xmm9 + vmovups %xmm3,-16(%r9) + subq 72(%rsp),%r9 + vmovdqu %xmm2,0(%rbp) + vpxor %xmm15,%xmm2,%xmm2 + vmovdqu 128+16(%rsp),%xmm3 + vmovups %xmm4,-16(%r10) + subq 80(%rsp),%r10 + vmovdqu %xmm3,16(%rbp) + vpxor %xmm15,%xmm3,%xmm3 + vmovdqu 128+32(%rsp),%xmm4 + vmovups %xmm5,-16(%r11) + subq 88(%rsp),%r11 + vmovdqu %xmm4,32(%rbp) + vpxor %xmm15,%xmm4,%xmm4 + vmovdqu 128+48(%rsp),%xmm5 + vmovups %xmm6,-16(%r12) + subq 96(%rsp),%r12 + vmovdqu %xmm5,48(%rbp) + vpxor %xmm15,%xmm5,%xmm5 + vmovdqu %xmm10,64(%rbp) + vpxor %xmm10,%xmm15,%xmm6 + vmovups %xmm7,-16(%r13) + subq 104(%rsp),%r13 + vmovdqu %xmm11,80(%rbp) + vpxor %xmm11,%xmm15,%xmm7 + vmovups %xmm8,-16(%r14) + subq 112(%rsp),%r14 + vmovdqu %xmm12,96(%rbp) + vpxor %xmm12,%xmm15,%xmm8 + vmovups %xmm9,-16(%r15) + subq 120(%rsp),%r15 + vmovdqu %xmm13,112(%rbp) + vpxor %xmm13,%xmm15,%xmm9 + + xorq $128,%rbp + decl %edx + jnz .Loop_dec8x + + movq 16(%rsp),%rax +.cfi_def_cfa %rax,8 + + + + + +.Ldec8x_done: + vzeroupper + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Ldec8x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_multi_cbc_decrypt_avx,.-aesni_multi_cbc_decrypt_avx + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/aes/aesni-sha1-x86_64.S b/crypto/openssl/crypto/aes/aesni-sha1-x86_64.S new file mode 100644 index 000000000000..2078fe2ab378 --- /dev/null +++ b/crypto/openssl/crypto/aes/aesni-sha1-x86_64.S @@ -0,0 +1,3056 @@ +.text + + +.globl aesni_cbc_sha1_enc +.type aesni_cbc_sha1_enc,@function +.align 32 +aesni_cbc_sha1_enc: +.cfi_startproc + + movl OPENSSL_ia32cap_P+0(%rip),%r10d + movq OPENSSL_ia32cap_P+4(%rip),%r11 + btq $61,%r11 + jc aesni_cbc_sha1_enc_shaext + andl $268435456,%r11d + andl $1073741824,%r10d + orl %r11d,%r10d + cmpl $1342177280,%r10d + je aesni_cbc_sha1_enc_avx + jmp aesni_cbc_sha1_enc_ssse3 + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_cbc_sha1_enc,.-aesni_cbc_sha1_enc +.type aesni_cbc_sha1_enc_ssse3,@function +.align 32 +aesni_cbc_sha1_enc_ssse3: +.cfi_startproc + movq 8(%rsp),%r10 + + + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + leaq -104(%rsp),%rsp +.cfi_adjust_cfa_offset 104 + + + movq %rdi,%r12 + movq %rsi,%r13 + movq %rdx,%r14 + leaq 112(%rcx),%r15 + movdqu (%r8),%xmm2 + movq %r8,88(%rsp) + shlq $6,%r14 + subq %r12,%r13 + movl 240-112(%r15),%r8d + addq %r10,%r14 + + leaq K_XX_XX(%rip),%r11 + movl 0(%r9),%eax + movl 4(%r9),%ebx + movl 8(%r9),%ecx + movl 12(%r9),%edx + movl %ebx,%esi + movl 16(%r9),%ebp + movl %ecx,%edi + xorl %edx,%edi + andl %edi,%esi + + movdqa 64(%r11),%xmm3 + movdqa 0(%r11),%xmm13 + movdqu 0(%r10),%xmm4 + movdqu 16(%r10),%xmm5 + movdqu 32(%r10),%xmm6 + movdqu 48(%r10),%xmm7 +.byte 102,15,56,0,227 +.byte 102,15,56,0,235 +.byte 102,15,56,0,243 + addq $64,%r10 + paddd %xmm13,%xmm4 +.byte 102,15,56,0,251 + paddd %xmm13,%xmm5 + paddd %xmm13,%xmm6 + movdqa %xmm4,0(%rsp) + psubd %xmm13,%xmm4 + movdqa %xmm5,16(%rsp) + psubd %xmm13,%xmm5 + movdqa %xmm6,32(%rsp) + psubd %xmm13,%xmm6 + movups -112(%r15),%xmm15 + movups 16-112(%r15),%xmm0 + jmp .Loop_ssse3 +.align 32 +.Loop_ssse3: + rorl $2,%ebx + movups 0(%r12),%xmm14 + xorps %xmm15,%xmm14 + xorps %xmm14,%xmm2 + movups -80(%r15),%xmm1 +.byte 102,15,56,220,208 + pshufd $238,%xmm4,%xmm8 + xorl %edx,%esi + movdqa %xmm7,%xmm12 + paddd %xmm7,%xmm13 + movl %eax,%edi + addl 0(%rsp),%ebp + punpcklqdq %xmm5,%xmm8 + xorl %ecx,%ebx + roll $5,%eax + addl %esi,%ebp + psrldq $4,%xmm12 + andl %ebx,%edi + xorl %ecx,%ebx + pxor %xmm4,%xmm8 + addl %eax,%ebp + rorl $7,%eax + pxor %xmm6,%xmm12 + xorl %ecx,%edi + movl %ebp,%esi + addl 4(%rsp),%edx + pxor %xmm12,%xmm8 + xorl %ebx,%eax + roll $5,%ebp + movdqa %xmm13,48(%rsp) + addl %edi,%edx + movups -64(%r15),%xmm0 +.byte 102,15,56,220,209 + andl %eax,%esi + movdqa %xmm8,%xmm3 + xorl %ebx,%eax + addl %ebp,%edx + rorl $7,%ebp + movdqa %xmm8,%xmm12 + xorl %ebx,%esi + pslldq $12,%xmm3 + paddd %xmm8,%xmm8 + movl %edx,%edi + addl 8(%rsp),%ecx + psrld $31,%xmm12 + xorl %eax,%ebp + roll $5,%edx + addl %esi,%ecx + movdqa %xmm3,%xmm13 + andl %ebp,%edi + xorl %eax,%ebp + psrld $30,%xmm3 + addl %edx,%ecx + rorl $7,%edx + por %xmm12,%xmm8 + xorl %eax,%edi + movl %ecx,%esi + addl 12(%rsp),%ebx + movups -48(%r15),%xmm1 +.byte 102,15,56,220,208 + pslld $2,%xmm13 + pxor %xmm3,%xmm8 + xorl %ebp,%edx + movdqa 0(%r11),%xmm3 + roll $5,%ecx + addl %edi,%ebx + andl %edx,%esi + pxor %xmm13,%xmm8 + xorl %ebp,%edx + addl %ecx,%ebx + rorl $7,%ecx + pshufd $238,%xmm5,%xmm9 + xorl %ebp,%esi + movdqa %xmm8,%xmm13 + paddd %xmm8,%xmm3 + movl %ebx,%edi + addl 16(%rsp),%eax + punpcklqdq %xmm6,%xmm9 + xorl %edx,%ecx + roll $5,%ebx + addl %esi,%eax + psrldq $4,%xmm13 + andl %ecx,%edi + xorl %edx,%ecx + pxor %xmm5,%xmm9 + addl %ebx,%eax + rorl $7,%ebx + movups -32(%r15),%xmm0 +.byte 102,15,56,220,209 + pxor %xmm7,%xmm13 + xorl %edx,%edi + movl %eax,%esi + addl 20(%rsp),%ebp + pxor %xmm13,%xmm9 + xorl %ecx,%ebx + roll $5,%eax + movdqa %xmm3,0(%rsp) + addl %edi,%ebp + andl %ebx,%esi + movdqa %xmm9,%xmm12 + xorl %ecx,%ebx + addl %eax,%ebp + rorl $7,%eax + movdqa %xmm9,%xmm13 + xorl %ecx,%esi + pslldq $12,%xmm12 + paddd %xmm9,%xmm9 + movl %ebp,%edi + addl 24(%rsp),%edx + psrld $31,%xmm13 + xorl %ebx,%eax + roll $5,%ebp + addl %esi,%edx + movups -16(%r15),%xmm1 +.byte 102,15,56,220,208 + movdqa %xmm12,%xmm3 + andl %eax,%edi + xorl %ebx,%eax + psrld $30,%xmm12 + addl %ebp,%edx + rorl $7,%ebp + por %xmm13,%xmm9 + xorl %ebx,%edi + movl %edx,%esi + addl 28(%rsp),%ecx + pslld $2,%xmm3 + pxor %xmm12,%xmm9 + xorl %eax,%ebp + movdqa 16(%r11),%xmm12 + roll $5,%edx + addl %edi,%ecx + andl %ebp,%esi + pxor %xmm3,%xmm9 + xorl %eax,%ebp + addl %edx,%ecx + rorl $7,%edx + pshufd $238,%xmm6,%xmm10 + xorl %eax,%esi + movdqa %xmm9,%xmm3 + paddd %xmm9,%xmm12 + movl %ecx,%edi + addl 32(%rsp),%ebx + movups 0(%r15),%xmm0 +.byte 102,15,56,220,209 + punpcklqdq %xmm7,%xmm10 + xorl %ebp,%edx + roll $5,%ecx + addl %esi,%ebx + psrldq $4,%xmm3 + andl %edx,%edi + xorl %ebp,%edx + pxor %xmm6,%xmm10 + addl %ecx,%ebx + rorl $7,%ecx + pxor %xmm8,%xmm3 + xorl %ebp,%edi + movl %ebx,%esi + addl 36(%rsp),%eax + pxor %xmm3,%xmm10 + xorl %edx,%ecx + roll $5,%ebx + movdqa %xmm12,16(%rsp) + addl %edi,%eax + andl %ecx,%esi + movdqa %xmm10,%xmm13 + xorl %edx,%ecx + addl %ebx,%eax + rorl $7,%ebx + movups 16(%r15),%xmm1 +.byte 102,15,56,220,208 + movdqa %xmm10,%xmm3 + xorl %edx,%esi + pslldq $12,%xmm13 + paddd %xmm10,%xmm10 + movl %eax,%edi + addl 40(%rsp),%ebp + psrld $31,%xmm3 + xorl %ecx,%ebx + roll $5,%eax + addl %esi,%ebp + movdqa %xmm13,%xmm12 + andl %ebx,%edi + xorl %ecx,%ebx + psrld $30,%xmm13 + addl %eax,%ebp + rorl $7,%eax + por %xmm3,%xmm10 + xorl %ecx,%edi + movl %ebp,%esi + addl 44(%rsp),%edx + pslld $2,%xmm12 + pxor %xmm13,%xmm10 + xorl %ebx,%eax + movdqa 16(%r11),%xmm13 + roll $5,%ebp + addl %edi,%edx + movups 32(%r15),%xmm0 +.byte 102,15,56,220,209 + andl %eax,%esi + pxor %xmm12,%xmm10 + xorl %ebx,%eax + addl %ebp,%edx + rorl $7,%ebp + pshufd $238,%xmm7,%xmm11 + xorl %ebx,%esi + movdqa %xmm10,%xmm12 + paddd %xmm10,%xmm13 + movl %edx,%edi + addl 48(%rsp),%ecx + punpcklqdq %xmm8,%xmm11 + xorl %eax,%ebp + roll $5,%edx + addl %esi,%ecx + psrldq $4,%xmm12 + andl %ebp,%edi + xorl %eax,%ebp + pxor %xmm7,%xmm11 + addl %edx,%ecx + rorl $7,%edx + pxor %xmm9,%xmm12 + xorl %eax,%edi + movl %ecx,%esi + addl 52(%rsp),%ebx + movups 48(%r15),%xmm1 +.byte 102,15,56,220,208 + pxor %xmm12,%xmm11 + xorl %ebp,%edx + roll $5,%ecx + movdqa %xmm13,32(%rsp) + addl %edi,%ebx + andl %edx,%esi + movdqa %xmm11,%xmm3 + xorl %ebp,%edx + addl %ecx,%ebx + rorl $7,%ecx + movdqa %xmm11,%xmm12 + xorl %ebp,%esi + pslldq $12,%xmm3 + paddd %xmm11,%xmm11 + movl %ebx,%edi + addl 56(%rsp),%eax + psrld $31,%xmm12 + xorl %edx,%ecx + roll $5,%ebx + addl %esi,%eax + movdqa %xmm3,%xmm13 + andl %ecx,%edi + xorl %edx,%ecx + psrld $30,%xmm3 + addl %ebx,%eax + rorl $7,%ebx + cmpl $11,%r8d + jb .Laesenclast1 + movups 64(%r15),%xmm0 +.byte 102,15,56,220,209 + movups 80(%r15),%xmm1 +.byte 102,15,56,220,208 + je .Laesenclast1 + movups 96(%r15),%xmm0 +.byte 102,15,56,220,209 + movups 112(%r15),%xmm1 +.byte 102,15,56,220,208 +.Laesenclast1: +.byte 102,15,56,221,209 + movups 16-112(%r15),%xmm0 + por %xmm12,%xmm11 + xorl %edx,%edi + movl %eax,%esi + addl 60(%rsp),%ebp + pslld $2,%xmm13 + pxor %xmm3,%xmm11 + xorl %ecx,%ebx + movdqa 16(%r11),%xmm3 + roll $5,%eax + addl %edi,%ebp + andl %ebx,%esi + pxor %xmm13,%xmm11 + pshufd $238,%xmm10,%xmm13 + xorl %ecx,%ebx + addl %eax,%ebp + rorl $7,%eax + pxor %xmm8,%xmm4 + xorl %ecx,%esi + movl %ebp,%edi + addl 0(%rsp),%edx + punpcklqdq %xmm11,%xmm13 + xorl %ebx,%eax + roll $5,%ebp + pxor %xmm5,%xmm4 + addl %esi,%edx + movups 16(%r12),%xmm14 + xorps %xmm15,%xmm14 + movups %xmm2,0(%r12,%r13,1) + xorps %xmm14,%xmm2 + movups -80(%r15),%xmm1 +.byte 102,15,56,220,208 + andl %eax,%edi + movdqa %xmm3,%xmm12 + xorl %ebx,%eax + paddd %xmm11,%xmm3 + addl %ebp,%edx + pxor %xmm13,%xmm4 + rorl $7,%ebp + xorl %ebx,%edi + movl %edx,%esi + addl 4(%rsp),%ecx + movdqa %xmm4,%xmm13 + xorl %eax,%ebp + roll $5,%edx + movdqa %xmm3,48(%rsp) + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + pslld $2,%xmm4 + addl %edx,%ecx + rorl $7,%edx + psrld $30,%xmm13 + xorl %eax,%esi + movl %ecx,%edi + addl 8(%rsp),%ebx + movups -64(%r15),%xmm0 +.byte 102,15,56,220,209 + por %xmm13,%xmm4 + xorl %ebp,%edx + roll $5,%ecx + pshufd $238,%xmm11,%xmm3 + addl %esi,%ebx + andl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + pxor %xmm9,%xmm5 + addl 16(%rsp),%ebp + movups -48(%r15),%xmm1 +.byte 102,15,56,220,208 + xorl %ecx,%esi + punpcklqdq %xmm4,%xmm3 + movl %eax,%edi + roll $5,%eax + pxor %xmm6,%xmm5 + addl %esi,%ebp + xorl %ecx,%edi + movdqa %xmm12,%xmm13 + rorl $7,%ebx + paddd %xmm4,%xmm12 + addl %eax,%ebp + pxor %xmm3,%xmm5 + addl 20(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm5,%xmm3 + addl %edi,%edx + xorl %ebx,%esi + movdqa %xmm12,0(%rsp) + rorl $7,%eax + addl %ebp,%edx + addl 24(%rsp),%ecx + pslld $2,%xmm5 + xorl %eax,%esi + movl %edx,%edi + psrld $30,%xmm3 + roll $5,%edx + addl %esi,%ecx + movups -32(%r15),%xmm0 +.byte 102,15,56,220,209 + xorl %eax,%edi + rorl $7,%ebp + por %xmm3,%xmm5 + addl %edx,%ecx + addl 28(%rsp),%ebx + pshufd $238,%xmm4,%xmm12 + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + pxor %xmm10,%xmm6 + addl 32(%rsp),%eax + xorl %edx,%esi + punpcklqdq %xmm5,%xmm12 + movl %ebx,%edi + roll $5,%ebx + pxor %xmm7,%xmm6 + addl %esi,%eax + xorl %edx,%edi + movdqa 32(%r11),%xmm3 + rorl $7,%ecx + paddd %xmm5,%xmm13 + addl %ebx,%eax + pxor %xmm12,%xmm6 + addl 36(%rsp),%ebp + movups -16(%r15),%xmm1 +.byte 102,15,56,220,208 + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + movdqa %xmm6,%xmm12 + addl %edi,%ebp + xorl %ecx,%esi + movdqa %xmm13,16(%rsp) + rorl $7,%ebx + addl %eax,%ebp + addl 40(%rsp),%edx + pslld $2,%xmm6 + xorl %ebx,%esi + movl %ebp,%edi + psrld $30,%xmm12 + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + por %xmm12,%xmm6 + addl %ebp,%edx + addl 44(%rsp),%ecx + pshufd $238,%xmm5,%xmm13 + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + movups 0(%r15),%xmm0 +.byte 102,15,56,220,209 + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + pxor %xmm11,%xmm7 + addl 48(%rsp),%ebx + xorl %ebp,%esi + punpcklqdq %xmm6,%xmm13 + movl %ecx,%edi + roll $5,%ecx + pxor %xmm8,%xmm7 + addl %esi,%ebx + xorl %ebp,%edi + movdqa %xmm3,%xmm12 + rorl $7,%edx + paddd %xmm6,%xmm3 + addl %ecx,%ebx + pxor %xmm13,%xmm7 + addl 52(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + movdqa %xmm7,%xmm13 + addl %edi,%eax + xorl %edx,%esi + movdqa %xmm3,32(%rsp) + rorl $7,%ecx + addl %ebx,%eax + addl 56(%rsp),%ebp + movups 16(%r15),%xmm1 +.byte 102,15,56,220,208 + pslld $2,%xmm7 + xorl %ecx,%esi + movl %eax,%edi + psrld $30,%xmm13 + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + por %xmm13,%xmm7 + addl %eax,%ebp + addl 60(%rsp),%edx + pshufd $238,%xmm6,%xmm3 + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + pxor %xmm4,%xmm8 + addl 0(%rsp),%ecx + xorl %eax,%esi + punpcklqdq %xmm7,%xmm3 + movl %edx,%edi + roll $5,%edx + pxor %xmm9,%xmm8 + addl %esi,%ecx + movups 32(%r15),%xmm0 +.byte 102,15,56,220,209 + xorl %eax,%edi + movdqa %xmm12,%xmm13 + rorl $7,%ebp + paddd %xmm7,%xmm12 + addl %edx,%ecx + pxor %xmm3,%xmm8 + addl 4(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + movdqa %xmm8,%xmm3 + addl %edi,%ebx + xorl %ebp,%esi + movdqa %xmm12,48(%rsp) + rorl $7,%edx + addl %ecx,%ebx + addl 8(%rsp),%eax + pslld $2,%xmm8 + xorl %edx,%esi + movl %ebx,%edi + psrld $30,%xmm3 + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + por %xmm3,%xmm8 + addl %ebx,%eax + addl 12(%rsp),%ebp + movups 48(%r15),%xmm1 +.byte 102,15,56,220,208 + pshufd $238,%xmm7,%xmm12 + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + pxor %xmm5,%xmm9 + addl 16(%rsp),%edx + xorl %ebx,%esi + punpcklqdq %xmm8,%xmm12 + movl %ebp,%edi + roll $5,%ebp + pxor %xmm10,%xmm9 + addl %esi,%edx + xorl %ebx,%edi + movdqa %xmm13,%xmm3 + rorl $7,%eax + paddd %xmm8,%xmm13 + addl %ebp,%edx + pxor %xmm12,%xmm9 + addl 20(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + movdqa %xmm9,%xmm12 + addl %edi,%ecx + cmpl $11,%r8d + jb .Laesenclast2 + movups 64(%r15),%xmm0 +.byte 102,15,56,220,209 + movups 80(%r15),%xmm1 +.byte 102,15,56,220,208 + je .Laesenclast2 + movups 96(%r15),%xmm0 +.byte 102,15,56,220,209 + movups 112(%r15),%xmm1 +.byte 102,15,56,220,208 +.Laesenclast2: +.byte 102,15,56,221,209 + movups 16-112(%r15),%xmm0 + xorl %eax,%esi + movdqa %xmm13,0(%rsp) + rorl $7,%ebp + addl %edx,%ecx + addl 24(%rsp),%ebx + pslld $2,%xmm9 + xorl %ebp,%esi + movl %ecx,%edi + psrld $30,%xmm12 + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + por %xmm12,%xmm9 + addl %ecx,%ebx + addl 28(%rsp),%eax + pshufd $238,%xmm8,%xmm13 + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%edi + roll $5,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + pxor %xmm6,%xmm10 + addl 32(%rsp),%ebp + movups 32(%r12),%xmm14 + xorps %xmm15,%xmm14 + movups %xmm2,16(%r13,%r12,1) + xorps %xmm14,%xmm2 + movups -80(%r15),%xmm1 +.byte 102,15,56,220,208 + andl %ecx,%esi + xorl %edx,%ecx + rorl $7,%ebx + punpcklqdq %xmm9,%xmm13 + movl %eax,%edi + xorl %ecx,%esi + pxor %xmm11,%xmm10 + roll $5,%eax + addl %esi,%ebp + movdqa %xmm3,%xmm12 + xorl %ebx,%edi + paddd %xmm9,%xmm3 + xorl %ecx,%ebx + pxor %xmm13,%xmm10 + addl %eax,%ebp + addl 36(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + rorl $7,%eax + movdqa %xmm10,%xmm13 + movl %ebp,%esi + xorl %ebx,%edi + movdqa %xmm3,16(%rsp) + roll $5,%ebp + addl %edi,%edx + movups -64(%r15),%xmm0 +.byte 102,15,56,220,209 + xorl %eax,%esi + pslld $2,%xmm10 + xorl %ebx,%eax + addl %ebp,%edx + psrld $30,%xmm13 + addl 40(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + por %xmm13,%xmm10 + rorl $7,%ebp + movl %edx,%edi + xorl %eax,%esi + roll $5,%edx + pshufd $238,%xmm9,%xmm3 + addl %esi,%ecx + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 44(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + rorl $7,%edx + movups -48(%r15),%xmm1 +.byte 102,15,56,220,208 + movl %ecx,%esi + xorl %ebp,%edi + roll $5,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + pxor %xmm7,%xmm11 + addl 48(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + rorl $7,%ecx + punpcklqdq %xmm10,%xmm3 + movl %ebx,%edi + xorl %edx,%esi + pxor %xmm4,%xmm11 + roll $5,%ebx + addl %esi,%eax + movdqa 48(%r11),%xmm13 + xorl %ecx,%edi + paddd %xmm10,%xmm12 + xorl %edx,%ecx + pxor %xmm3,%xmm11 + addl %ebx,%eax + addl 52(%rsp),%ebp + movups -32(%r15),%xmm0 +.byte 102,15,56,220,209 + andl %ecx,%edi + xorl %edx,%ecx + rorl $7,%ebx + movdqa %xmm11,%xmm3 + movl %eax,%esi + xorl %ecx,%edi + movdqa %xmm12,32(%rsp) + roll $5,%eax + addl %edi,%ebp + xorl %ebx,%esi + pslld $2,%xmm11 + xorl %ecx,%ebx + addl %eax,%ebp + psrld $30,%xmm3 + addl 56(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + por %xmm3,%xmm11 + rorl $7,%eax + movl %ebp,%edi + xorl %ebx,%esi + roll $5,%ebp + pshufd $238,%xmm10,%xmm12 + addl %esi,%edx + movups -16(%r15),%xmm1 +.byte 102,15,56,220,208 + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 60(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + rorl $7,%ebp + movl %edx,%esi + xorl %eax,%edi + roll $5,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + pxor %xmm8,%xmm4 + addl 0(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + rorl $7,%edx + movups 0(%r15),%xmm0 +.byte 102,15,56,220,209 + punpcklqdq %xmm11,%xmm12 + movl %ecx,%edi + xorl %ebp,%esi + pxor %xmm5,%xmm4 + roll $5,%ecx + addl %esi,%ebx + movdqa %xmm13,%xmm3 + xorl %edx,%edi + paddd %xmm11,%xmm13 + xorl %ebp,%edx + pxor %xmm12,%xmm4 + addl %ecx,%ebx + addl 4(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + rorl $7,%ecx + movdqa %xmm4,%xmm12 + movl %ebx,%esi + xorl %edx,%edi + movdqa %xmm13,48(%rsp) + roll $5,%ebx + addl %edi,%eax + xorl %ecx,%esi + pslld $2,%xmm4 + xorl %edx,%ecx + addl %ebx,%eax + psrld $30,%xmm12 + addl 8(%rsp),%ebp + movups 16(%r15),%xmm1 +.byte 102,15,56,220,208 + andl %ecx,%esi + xorl %edx,%ecx + por %xmm12,%xmm4 + rorl $7,%ebx + movl %eax,%edi + xorl %ecx,%esi + roll $5,%eax + pshufd $238,%xmm11,%xmm13 + addl %esi,%ebp + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 12(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + rorl $7,%eax + movl %ebp,%esi + xorl %ebx,%edi + roll $5,%ebp + addl %edi,%edx + movups 32(%r15),%xmm0 +.byte 102,15,56,220,209 + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + pxor %xmm9,%xmm5 + addl 16(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + rorl $7,%ebp + punpcklqdq %xmm4,%xmm13 + movl %edx,%edi + xorl %eax,%esi + pxor %xmm6,%xmm5 + roll $5,%edx + addl %esi,%ecx + movdqa %xmm3,%xmm12 + xorl %ebp,%edi + paddd %xmm4,%xmm3 + xorl %eax,%ebp + pxor %xmm13,%xmm5 + addl %edx,%ecx + addl 20(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + rorl $7,%edx + movups 48(%r15),%xmm1 +.byte 102,15,56,220,208 + movdqa %xmm5,%xmm13 + movl %ecx,%esi + xorl %ebp,%edi + movdqa %xmm3,0(%rsp) + roll $5,%ecx + addl %edi,%ebx + xorl %edx,%esi + pslld $2,%xmm5 + xorl %ebp,%edx + addl %ecx,%ebx + psrld $30,%xmm13 + addl 24(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + por %xmm13,%xmm5 + rorl $7,%ecx + movl %ebx,%edi + xorl %edx,%esi + roll $5,%ebx + pshufd $238,%xmm4,%xmm3 + addl %esi,%eax + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%rsp),%ebp + cmpl $11,%r8d + jb .Laesenclast3 + movups 64(%r15),%xmm0 +.byte 102,15,56,220,209 + movups 80(%r15),%xmm1 +.byte 102,15,56,220,208 + je .Laesenclast3 + movups 96(%r15),%xmm0 +.byte 102,15,56,220,209 + movups 112(%r15),%xmm1 +.byte 102,15,56,220,208 +.Laesenclast3: +.byte 102,15,56,221,209 + movups 16-112(%r15),%xmm0 + andl %ecx,%edi + xorl %edx,%ecx + rorl $7,%ebx + movl %eax,%esi + xorl %ecx,%edi + roll $5,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + pxor %xmm10,%xmm6 + addl 32(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + rorl $7,%eax + punpcklqdq %xmm5,%xmm3 + movl %ebp,%edi + xorl %ebx,%esi + pxor %xmm7,%xmm6 + roll $5,%ebp + addl %esi,%edx + movups 48(%r12),%xmm14 + xorps %xmm15,%xmm14 + movups %xmm2,32(%r13,%r12,1) + xorps %xmm14,%xmm2 + movups -80(%r15),%xmm1 +.byte 102,15,56,220,208 + movdqa %xmm12,%xmm13 + xorl %eax,%edi + paddd %xmm5,%xmm12 + xorl %ebx,%eax + pxor %xmm3,%xmm6 + addl %ebp,%edx + addl 36(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + rorl $7,%ebp + movdqa %xmm6,%xmm3 + movl %edx,%esi + xorl %eax,%edi + movdqa %xmm12,16(%rsp) + roll $5,%edx + addl %edi,%ecx + xorl %ebp,%esi + pslld $2,%xmm6 + xorl %eax,%ebp + addl %edx,%ecx + psrld $30,%xmm3 + addl 40(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + por %xmm3,%xmm6 + rorl $7,%edx + movups -64(%r15),%xmm0 +.byte 102,15,56,220,209 + movl %ecx,%edi + xorl %ebp,%esi + roll $5,%ecx + pshufd $238,%xmm5,%xmm12 + addl %esi,%ebx + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 44(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%edi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + addl %ebx,%eax + pxor %xmm11,%xmm7 + addl 48(%rsp),%ebp + movups -48(%r15),%xmm1 +.byte 102,15,56,220,208 + xorl %ecx,%esi + punpcklqdq %xmm6,%xmm12 + movl %eax,%edi + roll $5,%eax + pxor %xmm8,%xmm7 + addl %esi,%ebp + xorl %ecx,%edi + movdqa %xmm13,%xmm3 + rorl $7,%ebx + paddd %xmm6,%xmm13 + addl %eax,%ebp + pxor %xmm12,%xmm7 + addl 52(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm7,%xmm12 + addl %edi,%edx + xorl %ebx,%esi + movdqa %xmm13,32(%rsp) + rorl $7,%eax + addl %ebp,%edx + addl 56(%rsp),%ecx + pslld $2,%xmm7 + xorl %eax,%esi + movl %edx,%edi + psrld $30,%xmm12 + roll $5,%edx + addl %esi,%ecx + movups -32(%r15),%xmm0 +.byte 102,15,56,220,209 + xorl %eax,%edi + rorl $7,%ebp + por %xmm12,%xmm7 + addl %edx,%ecx + addl 60(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + addl 0(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + paddd %xmm7,%xmm3 + addl %esi,%eax + xorl %edx,%edi + movdqa %xmm3,48(%rsp) + rorl $7,%ecx + addl %ebx,%eax + addl 4(%rsp),%ebp + movups -16(%r15),%xmm1 +.byte 102,15,56,220,208 + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 8(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + addl %ebp,%edx + addl 12(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + movups 0(%r15),%xmm0 +.byte 102,15,56,220,209 + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + cmpq %r14,%r10 + je .Ldone_ssse3 + movdqa 64(%r11),%xmm3 + movdqa 0(%r11),%xmm13 + movdqu 0(%r10),%xmm4 + movdqu 16(%r10),%xmm5 + movdqu 32(%r10),%xmm6 + movdqu 48(%r10),%xmm7 +.byte 102,15,56,0,227 + addq $64,%r10 + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi +.byte 102,15,56,0,235 + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + paddd %xmm13,%xmm4 + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + movdqa %xmm4,0(%rsp) + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + psubd %xmm13,%xmm4 + addl %ebx,%eax + addl 24(%rsp),%ebp + movups 16(%r15),%xmm1 +.byte 102,15,56,220,208 + xorl %ecx,%esi + movl %eax,%edi + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi +.byte 102,15,56,0,243 + roll $5,%edx + addl %esi,%ecx + movups 32(%r15),%xmm0 +.byte 102,15,56,220,209 + xorl %eax,%edi + rorl $7,%ebp + paddd %xmm13,%xmm5 + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + movdqa %xmm5,16(%rsp) + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + psubd %xmm13,%xmm5 + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + movups 48(%r15),%xmm1 +.byte 102,15,56,220,208 + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi +.byte 102,15,56,0,251 + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + paddd %xmm13,%xmm6 + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + movdqa %xmm6,32(%rsp) + roll $5,%edx + addl %edi,%ecx + cmpl $11,%r8d + jb .Laesenclast4 + movups 64(%r15),%xmm0 +.byte 102,15,56,220,209 + movups 80(%r15),%xmm1 +.byte 102,15,56,220,208 + je .Laesenclast4 + movups 96(%r15),%xmm0 +.byte 102,15,56,220,209 + movups 112(%r15),%xmm1 +.byte 102,15,56,220,208 +.Laesenclast4: +.byte 102,15,56,221,209 + movups 16-112(%r15),%xmm0 + xorl %eax,%esi + rorl $7,%ebp + psubd %xmm13,%xmm6 + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + rorl $7,%ecx + addl %ebx,%eax + movups %xmm2,48(%r13,%r12,1) + leaq 64(%r12),%r12 + + addl 0(%r9),%eax + addl 4(%r9),%esi + addl 8(%r9),%ecx + addl 12(%r9),%edx + movl %eax,0(%r9) + addl 16(%r9),%ebp + movl %esi,4(%r9) + movl %esi,%ebx + movl %ecx,8(%r9) + movl %ecx,%edi + movl %edx,12(%r9) + xorl %edx,%edi + movl %ebp,16(%r9) + andl %edi,%esi + jmp .Loop_ssse3 + +.Ldone_ssse3: + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + movups 16(%r15),%xmm1 +.byte 102,15,56,220,208 + xorl %ecx,%esi + movl %eax,%edi + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + roll $5,%edx + addl %esi,%ecx + movups 32(%r15),%xmm0 +.byte 102,15,56,220,209 + xorl %eax,%edi + rorl $7,%ebp + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + movups 48(%r15),%xmm1 +.byte 102,15,56,220,208 + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + cmpl $11,%r8d + jb .Laesenclast5 + movups 64(%r15),%xmm0 +.byte 102,15,56,220,209 + movups 80(%r15),%xmm1 +.byte 102,15,56,220,208 + je .Laesenclast5 + movups 96(%r15),%xmm0 +.byte 102,15,56,220,209 + movups 112(%r15),%xmm1 +.byte 102,15,56,220,208 +.Laesenclast5: +.byte 102,15,56,221,209 + movups 16-112(%r15),%xmm0 + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + rorl $7,%ecx + addl %ebx,%eax + movups %xmm2,48(%r13,%r12,1) + movq 88(%rsp),%r8 + + addl 0(%r9),%eax + addl 4(%r9),%esi + addl 8(%r9),%ecx + movl %eax,0(%r9) + addl 12(%r9),%edx + movl %esi,4(%r9) + addl 16(%r9),%ebp + movl %ecx,8(%r9) + movl %edx,12(%r9) + movl %ebp,16(%r9) + movups %xmm2,(%r8) + leaq 104(%rsp),%rsi +.cfi_def_cfa %rsi,56 + movq 0(%rsi),%r15 +.cfi_restore %r15 + movq 8(%rsi),%r14 +.cfi_restore %r14 + movq 16(%rsi),%r13 +.cfi_restore %r13 + movq 24(%rsi),%r12 +.cfi_restore %r12 + movq 32(%rsi),%rbp +.cfi_restore %rbp + movq 40(%rsi),%rbx +.cfi_restore %rbx + leaq 48(%rsi),%rsp +.cfi_def_cfa %rsp,8 +.Lepilogue_ssse3: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_cbc_sha1_enc_ssse3,.-aesni_cbc_sha1_enc_ssse3 +.type aesni_cbc_sha1_enc_avx,@function +.align 32 +aesni_cbc_sha1_enc_avx: +.cfi_startproc + movq 8(%rsp),%r10 + + + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + leaq -104(%rsp),%rsp +.cfi_adjust_cfa_offset 104 + + + vzeroall + movq %rdi,%r12 + movq %rsi,%r13 + movq %rdx,%r14 + leaq 112(%rcx),%r15 + vmovdqu (%r8),%xmm12 + movq %r8,88(%rsp) + shlq $6,%r14 + subq %r12,%r13 + movl 240-112(%r15),%r8d + addq %r10,%r14 + + leaq K_XX_XX(%rip),%r11 + movl 0(%r9),%eax + movl 4(%r9),%ebx + movl 8(%r9),%ecx + movl 12(%r9),%edx + movl %ebx,%esi + movl 16(%r9),%ebp + movl %ecx,%edi + xorl %edx,%edi + andl %edi,%esi + + vmovdqa 64(%r11),%xmm6 + vmovdqa 0(%r11),%xmm10 + vmovdqu 0(%r10),%xmm0 + vmovdqu 16(%r10),%xmm1 + vmovdqu 32(%r10),%xmm2 + vmovdqu 48(%r10),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + addq $64,%r10 + vpshufb %xmm6,%xmm1,%xmm1 + vpshufb %xmm6,%xmm2,%xmm2 + vpshufb %xmm6,%xmm3,%xmm3 + vpaddd %xmm10,%xmm0,%xmm4 + vpaddd %xmm10,%xmm1,%xmm5 + vpaddd %xmm10,%xmm2,%xmm6 + vmovdqa %xmm4,0(%rsp) + vmovdqa %xmm5,16(%rsp) + vmovdqa %xmm6,32(%rsp) + vmovups -112(%r15),%xmm15 + vmovups 16-112(%r15),%xmm14 + jmp .Loop_avx +.align 32 +.Loop_avx: + shrdl $2,%ebx,%ebx + vmovdqu 0(%r12),%xmm13 + vpxor %xmm15,%xmm13,%xmm13 + vpxor %xmm13,%xmm12,%xmm12 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -80(%r15),%xmm15 + xorl %edx,%esi + vpalignr $8,%xmm0,%xmm1,%xmm4 + movl %eax,%edi + addl 0(%rsp),%ebp + vpaddd %xmm3,%xmm10,%xmm9 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrldq $4,%xmm3,%xmm8 + addl %esi,%ebp + andl %ebx,%edi + vpxor %xmm0,%xmm4,%xmm4 + xorl %ecx,%ebx + addl %eax,%ebp + vpxor %xmm2,%xmm8,%xmm8 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 4(%rsp),%edx + vpxor %xmm8,%xmm4,%xmm4 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vmovdqa %xmm9,48(%rsp) + addl %edi,%edx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups -64(%r15),%xmm14 + andl %eax,%esi + vpsrld $31,%xmm4,%xmm8 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpslldq $12,%xmm4,%xmm9 + vpaddd %xmm4,%xmm4,%xmm4 + movl %edx,%edi + addl 8(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpor %xmm8,%xmm4,%xmm4 + vpsrld $30,%xmm9,%xmm8 + addl %esi,%ecx + andl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + vpslld $2,%xmm9,%xmm9 + vpxor %xmm8,%xmm4,%xmm4 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 12(%rsp),%ebx + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -48(%r15),%xmm15 + vpxor %xmm9,%xmm4,%xmm4 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %edi,%ebx + andl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpalignr $8,%xmm1,%xmm2,%xmm5 + movl %ebx,%edi + addl 16(%rsp),%eax + vpaddd %xmm4,%xmm10,%xmm9 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrldq $4,%xmm4,%xmm8 + addl %esi,%eax + andl %ecx,%edi + vpxor %xmm1,%xmm5,%xmm5 + xorl %edx,%ecx + addl %ebx,%eax + vpxor %xmm3,%xmm8,%xmm8 + shrdl $7,%ebx,%ebx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups -32(%r15),%xmm14 + xorl %edx,%edi + movl %eax,%esi + addl 20(%rsp),%ebp + vpxor %xmm8,%xmm5,%xmm5 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vmovdqa %xmm9,0(%rsp) + addl %edi,%ebp + andl %ebx,%esi + vpsrld $31,%xmm5,%xmm8 + xorl %ecx,%ebx + addl %eax,%ebp + shrdl $7,%eax,%eax + xorl %ecx,%esi + vpslldq $12,%xmm5,%xmm9 + vpaddd %xmm5,%xmm5,%xmm5 + movl %ebp,%edi + addl 24(%rsp),%edx + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpor %xmm8,%xmm5,%xmm5 + vpsrld $30,%xmm9,%xmm8 + addl %esi,%edx + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -16(%r15),%xmm15 + andl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + vpslld $2,%xmm9,%xmm9 + vpxor %xmm8,%xmm5,%xmm5 + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + movl %edx,%esi + addl 28(%rsp),%ecx + vpxor %xmm9,%xmm5,%xmm5 + xorl %eax,%ebp + shldl $5,%edx,%edx + vmovdqa 16(%r11),%xmm10 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + vpalignr $8,%xmm2,%xmm3,%xmm6 + movl %ecx,%edi + addl 32(%rsp),%ebx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 0(%r15),%xmm14 + vpaddd %xmm5,%xmm10,%xmm9 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vpsrldq $4,%xmm5,%xmm8 + addl %esi,%ebx + andl %edx,%edi + vpxor %xmm2,%xmm6,%xmm6 + xorl %ebp,%edx + addl %ecx,%ebx + vpxor %xmm4,%xmm8,%xmm8 + shrdl $7,%ecx,%ecx + xorl %ebp,%edi + movl %ebx,%esi + addl 36(%rsp),%eax + vpxor %xmm8,%xmm6,%xmm6 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vmovdqa %xmm9,16(%rsp) + addl %edi,%eax + andl %ecx,%esi + vpsrld $31,%xmm6,%xmm8 + xorl %edx,%ecx + addl %ebx,%eax + shrdl $7,%ebx,%ebx + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 16(%r15),%xmm15 + xorl %edx,%esi + vpslldq $12,%xmm6,%xmm9 + vpaddd %xmm6,%xmm6,%xmm6 + movl %eax,%edi + addl 40(%rsp),%ebp + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpor %xmm8,%xmm6,%xmm6 + vpsrld $30,%xmm9,%xmm8 + addl %esi,%ebp + andl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + vpslld $2,%xmm9,%xmm9 + vpxor %xmm8,%xmm6,%xmm6 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 44(%rsp),%edx + vpxor %xmm9,%xmm6,%xmm6 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + addl %edi,%edx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 32(%r15),%xmm14 + andl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpalignr $8,%xmm3,%xmm4,%xmm7 + movl %edx,%edi + addl 48(%rsp),%ecx + vpaddd %xmm6,%xmm10,%xmm9 + xorl %eax,%ebp + shldl $5,%edx,%edx + vpsrldq $4,%xmm6,%xmm8 + addl %esi,%ecx + andl %ebp,%edi + vpxor %xmm3,%xmm7,%xmm7 + xorl %eax,%ebp + addl %edx,%ecx + vpxor %xmm5,%xmm8,%xmm8 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 52(%rsp),%ebx + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 48(%r15),%xmm15 + vpxor %xmm8,%xmm7,%xmm7 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vmovdqa %xmm9,32(%rsp) + addl %edi,%ebx + andl %edx,%esi + vpsrld $31,%xmm7,%xmm8 + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpslldq $12,%xmm7,%xmm9 + vpaddd %xmm7,%xmm7,%xmm7 + movl %ebx,%edi + addl 56(%rsp),%eax + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpor %xmm8,%xmm7,%xmm7 + vpsrld $30,%xmm9,%xmm8 + addl %esi,%eax + andl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + vpslld $2,%xmm9,%xmm9 + vpxor %xmm8,%xmm7,%xmm7 + shrdl $7,%ebx,%ebx + cmpl $11,%r8d + jb .Lvaesenclast6 + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 64(%r15),%xmm14 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 80(%r15),%xmm15 + je .Lvaesenclast6 + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 96(%r15),%xmm14 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 112(%r15),%xmm15 +.Lvaesenclast6: + vaesenclast %xmm15,%xmm12,%xmm12 + vmovups -112(%r15),%xmm15 + vmovups 16-112(%r15),%xmm14 + xorl %edx,%edi + movl %eax,%esi + addl 60(%rsp),%ebp + vpxor %xmm9,%xmm7,%xmm7 + xorl %ecx,%ebx + shldl $5,%eax,%eax + addl %edi,%ebp + andl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%esi + movl %ebp,%edi + addl 0(%rsp),%edx + vpxor %xmm1,%xmm0,%xmm0 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpaddd %xmm7,%xmm10,%xmm9 + addl %esi,%edx + vmovdqu 16(%r12),%xmm13 + vpxor %xmm15,%xmm13,%xmm13 + vmovups %xmm12,0(%r12,%r13,1) + vpxor %xmm13,%xmm12,%xmm12 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -80(%r15),%xmm15 + andl %eax,%edi + vpxor %xmm8,%xmm0,%xmm0 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + movl %edx,%esi + addl 4(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpslld $2,%xmm0,%xmm0 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + movl %ecx,%edi + addl 8(%rsp),%ebx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups -64(%r15),%xmm14 + vpor %xmm8,%xmm0,%xmm0 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %esi,%ebx + andl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ebp + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -48(%r15),%xmm15 + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm2,%xmm1,%xmm1 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm0,%xmm10,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm1,%xmm1 + addl 20(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm1,%xmm1 + addl 24(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups -32(%r15),%xmm14 + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm1,%xmm1 + addl 28(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + vpxor %xmm3,%xmm2,%xmm2 + addl %esi,%eax + xorl %edx,%edi + vpaddd %xmm1,%xmm10,%xmm9 + vmovdqa 32(%r11),%xmm10 + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpxor %xmm8,%xmm2,%xmm2 + addl 36(%rsp),%ebp + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -16(%r15),%xmm15 + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpslld $2,%xmm2,%xmm2 + addl 40(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpor %xmm8,%xmm2,%xmm2 + addl 44(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 0(%r15),%xmm14 + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebx + xorl %ebp,%edi + vpaddd %xmm2,%xmm10,%xmm9 + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ebp + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 16(%r15),%xmm15 + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpalignr $8,%xmm2,%xmm3,%xmm8 + vpxor %xmm0,%xmm4,%xmm4 + addl 0(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + vpxor %xmm5,%xmm4,%xmm4 + addl %esi,%ecx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 32(%r15),%xmm14 + xorl %eax,%edi + vpaddd %xmm3,%xmm10,%xmm9 + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpxor %xmm8,%xmm4,%xmm4 + addl 4(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + vpsrld $30,%xmm4,%xmm8 + vmovdqa %xmm9,48(%rsp) + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpslld $2,%xmm4,%xmm4 + addl 8(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpor %xmm8,%xmm4,%xmm4 + addl 12(%rsp),%ebp + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 48(%r15),%xmm15 + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm3,%xmm4,%xmm8 + vpxor %xmm1,%xmm5,%xmm5 + addl 16(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpxor %xmm6,%xmm5,%xmm5 + addl %esi,%edx + xorl %ebx,%edi + vpaddd %xmm4,%xmm10,%xmm9 + shrdl $7,%eax,%eax + addl %ebp,%edx + vpxor %xmm8,%xmm5,%xmm5 + addl 20(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + vpsrld $30,%xmm5,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%ecx + cmpl $11,%r8d + jb .Lvaesenclast7 + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 64(%r15),%xmm14 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 80(%r15),%xmm15 + je .Lvaesenclast7 + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 96(%r15),%xmm14 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 112(%r15),%xmm15 +.Lvaesenclast7: + vaesenclast %xmm15,%xmm12,%xmm12 + vmovups -112(%r15),%xmm15 + vmovups 16-112(%r15),%xmm14 + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpslld $2,%xmm5,%xmm5 + addl 24(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpor %xmm8,%xmm5,%xmm5 + addl 28(%rsp),%eax + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm4,%xmm5,%xmm8 + vpxor %xmm2,%xmm6,%xmm6 + addl 32(%rsp),%ebp + vmovdqu 32(%r12),%xmm13 + vpxor %xmm15,%xmm13,%xmm13 + vmovups %xmm12,16(%r13,%r12,1) + vpxor %xmm13,%xmm12,%xmm12 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -80(%r15),%xmm15 + andl %ecx,%esi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vpxor %xmm7,%xmm6,%xmm6 + movl %eax,%edi + xorl %ecx,%esi + vpaddd %xmm5,%xmm10,%xmm9 + shldl $5,%eax,%eax + addl %esi,%ebp + vpxor %xmm8,%xmm6,%xmm6 + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 36(%rsp),%edx + vpsrld $30,%xmm6,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + vpslld $2,%xmm6,%xmm6 + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups -64(%r15),%xmm14 + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + addl 40(%rsp),%ecx + andl %eax,%esi + vpor %xmm8,%xmm6,%xmm6 + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%edi + xorl %eax,%esi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 44(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -48(%r15),%xmm15 + movl %ecx,%esi + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + vpalignr $8,%xmm5,%xmm6,%xmm8 + vpxor %xmm3,%xmm7,%xmm7 + addl 48(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + vpxor %xmm0,%xmm7,%xmm7 + movl %ebx,%edi + xorl %edx,%esi + vpaddd %xmm6,%xmm10,%xmm9 + vmovdqa 48(%r11),%xmm10 + shldl $5,%ebx,%ebx + addl %esi,%eax + vpxor %xmm8,%xmm7,%xmm7 + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%rsp),%ebp + vaesenc %xmm15,%xmm12,%xmm12 + vmovups -32(%r15),%xmm14 + vpsrld $30,%xmm7,%xmm8 + vmovdqa %xmm9,32(%rsp) + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + vpslld $2,%xmm7,%xmm7 + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + addl 56(%rsp),%edx + andl %ebx,%esi + vpor %xmm8,%xmm7,%xmm7 + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%edi + xorl %ebx,%esi + shldl $5,%ebp,%ebp + addl %esi,%edx + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -16(%r15),%xmm15 + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 60(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + addl 0(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + shrdl $7,%edx,%edx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 0(%r15),%xmm14 + vpxor %xmm1,%xmm0,%xmm0 + movl %ecx,%edi + xorl %ebp,%esi + vpaddd %xmm7,%xmm10,%xmm9 + shldl $5,%ecx,%ecx + addl %esi,%ebx + vpxor %xmm8,%xmm0,%xmm0 + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 4(%rsp),%eax + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + vpslld $2,%xmm0,%xmm0 + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%rsp),%ebp + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 16(%r15),%xmm15 + andl %ecx,%esi + vpor %xmm8,%xmm0,%xmm0 + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%edi + xorl %ecx,%esi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 12(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 32(%r15),%xmm14 + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + vpxor %xmm2,%xmm1,%xmm1 + movl %edx,%edi + xorl %eax,%esi + vpaddd %xmm0,%xmm10,%xmm9 + shldl $5,%edx,%edx + addl %esi,%ecx + vpxor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 20(%rsp),%ebx + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 48(%r15),%xmm15 + movl %ecx,%esi + vpslld $2,%xmm1,%xmm1 + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + addl 24(%rsp),%eax + andl %edx,%esi + vpor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%edi + xorl %edx,%esi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%rsp),%ebp + cmpl $11,%r8d + jb .Lvaesenclast8 + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 64(%r15),%xmm14 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 80(%r15),%xmm15 + je .Lvaesenclast8 + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 96(%r15),%xmm14 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 112(%r15),%xmm15 +.Lvaesenclast8: + vaesenclast %xmm15,%xmm12,%xmm12 + vmovups -112(%r15),%xmm15 + vmovups 16-112(%r15),%xmm14 + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vpxor %xmm3,%xmm2,%xmm2 + movl %ebp,%edi + xorl %ebx,%esi + vpaddd %xmm1,%xmm10,%xmm9 + shldl $5,%ebp,%ebp + addl %esi,%edx + vmovdqu 48(%r12),%xmm13 + vpxor %xmm15,%xmm13,%xmm13 + vmovups %xmm12,32(%r13,%r12,1) + vpxor %xmm13,%xmm12,%xmm12 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -80(%r15),%xmm15 + vpxor %xmm8,%xmm2,%xmm2 + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 36(%rsp),%ecx + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + vpslld $2,%xmm2,%xmm2 + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + addl 40(%rsp),%ebx + andl %ebp,%esi + vpor %xmm8,%xmm2,%xmm2 + xorl %eax,%ebp + shrdl $7,%edx,%edx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups -64(%r15),%xmm14 + movl %ecx,%edi + xorl %ebp,%esi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 44(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + addl %ebx,%eax + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebp + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -48(%r15),%xmm15 + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm2,%xmm10,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups -32(%r15),%xmm14 + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 0(%rsp),%eax + vpaddd %xmm3,%xmm10,%xmm9 + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + vmovdqa %xmm9,48(%rsp) + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 4(%rsp),%ebp + vaesenc %xmm14,%xmm12,%xmm12 + vmovups -16(%r15),%xmm15 + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 8(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 12(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 0(%r15),%xmm14 + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + cmpq %r14,%r10 + je .Ldone_avx + vmovdqa 64(%r11),%xmm9 + vmovdqa 0(%r11),%xmm10 + vmovdqu 0(%r10),%xmm0 + vmovdqu 16(%r10),%xmm1 + vmovdqu 32(%r10),%xmm2 + vmovdqu 48(%r10),%xmm3 + vpshufb %xmm9,%xmm0,%xmm0 + addq $64,%r10 + addl 16(%rsp),%ebx + xorl %ebp,%esi + vpshufb %xmm9,%xmm1,%xmm1 + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpaddd %xmm10,%xmm0,%xmm8 + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vmovdqa %xmm8,0(%rsp) + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 16(%r15),%xmm15 + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + vpshufb %xmm9,%xmm2,%xmm2 + movl %edx,%edi + shldl $5,%edx,%edx + vpaddd %xmm10,%xmm1,%xmm8 + addl %esi,%ecx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 32(%r15),%xmm14 + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vmovdqa %xmm8,16(%rsp) + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 48(%r15),%xmm15 + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + vpshufb %xmm9,%xmm3,%xmm3 + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpaddd %xmm10,%xmm2,%xmm8 + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vmovdqa %xmm8,32(%rsp) + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + cmpl $11,%r8d + jb .Lvaesenclast9 + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 64(%r15),%xmm14 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 80(%r15),%xmm15 + je .Lvaesenclast9 + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 96(%r15),%xmm14 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 112(%r15),%xmm15 +.Lvaesenclast9: + vaesenclast %xmm15,%xmm12,%xmm12 + vmovups -112(%r15),%xmm15 + vmovups 16-112(%r15),%xmm14 + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vmovups %xmm12,48(%r13,%r12,1) + leaq 64(%r12),%r12 + + addl 0(%r9),%eax + addl 4(%r9),%esi + addl 8(%r9),%ecx + addl 12(%r9),%edx + movl %eax,0(%r9) + addl 16(%r9),%ebp + movl %esi,4(%r9) + movl %esi,%ebx + movl %ecx,8(%r9) + movl %ecx,%edi + movl %edx,12(%r9) + xorl %edx,%edi + movl %ebp,16(%r9) + andl %edi,%esi + jmp .Loop_avx + +.Ldone_avx: + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 16(%r15),%xmm15 + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 32(%r15),%xmm14 + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 48(%r15),%xmm15 + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + cmpl $11,%r8d + jb .Lvaesenclast10 + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 64(%r15),%xmm14 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 80(%r15),%xmm15 + je .Lvaesenclast10 + vaesenc %xmm15,%xmm12,%xmm12 + vmovups 96(%r15),%xmm14 + vaesenc %xmm14,%xmm12,%xmm12 + vmovups 112(%r15),%xmm15 +.Lvaesenclast10: + vaesenclast %xmm15,%xmm12,%xmm12 + vmovups -112(%r15),%xmm15 + vmovups 16-112(%r15),%xmm14 + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vmovups %xmm12,48(%r13,%r12,1) + movq 88(%rsp),%r8 + + addl 0(%r9),%eax + addl 4(%r9),%esi + addl 8(%r9),%ecx + movl %eax,0(%r9) + addl 12(%r9),%edx + movl %esi,4(%r9) + addl 16(%r9),%ebp + movl %ecx,8(%r9) + movl %edx,12(%r9) + movl %ebp,16(%r9) + vmovups %xmm12,(%r8) + vzeroall + leaq 104(%rsp),%rsi +.cfi_def_cfa %rsi,56 + movq 0(%rsi),%r15 +.cfi_restore %r15 + movq 8(%rsi),%r14 +.cfi_restore %r14 + movq 16(%rsi),%r13 +.cfi_restore %r13 + movq 24(%rsi),%r12 +.cfi_restore %r12 + movq 32(%rsi),%rbp +.cfi_restore %rbp + movq 40(%rsi),%rbx +.cfi_restore %rbx + leaq 48(%rsi),%rsp +.cfi_def_cfa %rsp,8 +.Lepilogue_avx: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_cbc_sha1_enc_avx,.-aesni_cbc_sha1_enc_avx +.align 64 +K_XX_XX: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.byte 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 + +.byte 65,69,83,78,73,45,67,66,67,43,83,72,65,49,32,115,116,105,116,99,104,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 +.type aesni_cbc_sha1_enc_shaext,@function +.align 32 +aesni_cbc_sha1_enc_shaext: +.cfi_startproc + movq 8(%rsp),%r10 + movdqu (%r9),%xmm8 + movd 16(%r9),%xmm9 + movdqa K_XX_XX+80(%rip),%xmm7 + + movl 240(%rcx),%r11d + subq %rdi,%rsi + movups (%rcx),%xmm15 + movups (%r8),%xmm2 + movups 16(%rcx),%xmm0 + leaq 112(%rcx),%rcx + + pshufd $27,%xmm8,%xmm8 + pshufd $27,%xmm9,%xmm9 + jmp .Loop_shaext + +.align 16 +.Loop_shaext: + movups 0(%rdi),%xmm14 + xorps %xmm15,%xmm14 + xorps %xmm14,%xmm2 + movups -80(%rcx),%xmm1 +.byte 102,15,56,220,208 + movdqu (%r10),%xmm3 + movdqa %xmm9,%xmm12 +.byte 102,15,56,0,223 + movdqu 16(%r10),%xmm4 + movdqa %xmm8,%xmm11 + movups -64(%rcx),%xmm0 +.byte 102,15,56,220,209 +.byte 102,15,56,0,231 + + paddd %xmm3,%xmm9 + movdqu 32(%r10),%xmm5 + leaq 64(%r10),%r10 + pxor %xmm12,%xmm3 + movups -48(%rcx),%xmm1 +.byte 102,15,56,220,208 + pxor %xmm12,%xmm3 + movdqa %xmm8,%xmm10 +.byte 102,15,56,0,239 +.byte 69,15,58,204,193,0 +.byte 68,15,56,200,212 + movups -32(%rcx),%xmm0 +.byte 102,15,56,220,209 +.byte 15,56,201,220 + movdqu -16(%r10),%xmm6 + movdqa %xmm8,%xmm9 +.byte 102,15,56,0,247 + movups -16(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 69,15,58,204,194,0 +.byte 68,15,56,200,205 + pxor %xmm5,%xmm3 +.byte 15,56,201,229 + movups 0(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm10 +.byte 69,15,58,204,193,0 +.byte 68,15,56,200,214 + movups 16(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,222 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 + movups 32(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm9 +.byte 69,15,58,204,194,0 +.byte 68,15,56,200,203 + movups 48(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,227 + pxor %xmm3,%xmm5 +.byte 15,56,201,243 + cmpl $11,%r11d + jb .Laesenclast11 + movups 64(%rcx),%xmm0 +.byte 102,15,56,220,209 + movups 80(%rcx),%xmm1 +.byte 102,15,56,220,208 + je .Laesenclast11 + movups 96(%rcx),%xmm0 +.byte 102,15,56,220,209 + movups 112(%rcx),%xmm1 +.byte 102,15,56,220,208 +.Laesenclast11: +.byte 102,15,56,221,209 + movups 16-112(%rcx),%xmm0 + movdqa %xmm8,%xmm10 +.byte 69,15,58,204,193,0 +.byte 68,15,56,200,212 + movups 16(%rdi),%xmm14 + xorps %xmm15,%xmm14 + movups %xmm2,0(%rsi,%rdi,1) + xorps %xmm14,%xmm2 + movups -80(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,236 + pxor %xmm4,%xmm6 +.byte 15,56,201,220 + movups -64(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm9 +.byte 69,15,58,204,194,1 +.byte 68,15,56,200,205 + movups -48(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,245 + pxor %xmm5,%xmm3 +.byte 15,56,201,229 + movups -32(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm10 +.byte 69,15,58,204,193,1 +.byte 68,15,56,200,214 + movups -16(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,222 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 + movups 0(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm9 +.byte 69,15,58,204,194,1 +.byte 68,15,56,200,203 + movups 16(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,227 + pxor %xmm3,%xmm5 +.byte 15,56,201,243 + movups 32(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm10 +.byte 69,15,58,204,193,1 +.byte 68,15,56,200,212 + movups 48(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,236 + pxor %xmm4,%xmm6 +.byte 15,56,201,220 + cmpl $11,%r11d + jb .Laesenclast12 + movups 64(%rcx),%xmm0 +.byte 102,15,56,220,209 + movups 80(%rcx),%xmm1 +.byte 102,15,56,220,208 + je .Laesenclast12 + movups 96(%rcx),%xmm0 +.byte 102,15,56,220,209 + movups 112(%rcx),%xmm1 +.byte 102,15,56,220,208 +.Laesenclast12: +.byte 102,15,56,221,209 + movups 16-112(%rcx),%xmm0 + movdqa %xmm8,%xmm9 +.byte 69,15,58,204,194,1 +.byte 68,15,56,200,205 + movups 32(%rdi),%xmm14 + xorps %xmm15,%xmm14 + movups %xmm2,16(%rsi,%rdi,1) + xorps %xmm14,%xmm2 + movups -80(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,245 + pxor %xmm5,%xmm3 +.byte 15,56,201,229 + movups -64(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm10 +.byte 69,15,58,204,193,2 +.byte 68,15,56,200,214 + movups -48(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,222 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 + movups -32(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm9 +.byte 69,15,58,204,194,2 +.byte 68,15,56,200,203 + movups -16(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,227 + pxor %xmm3,%xmm5 +.byte 15,56,201,243 + movups 0(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm10 +.byte 69,15,58,204,193,2 +.byte 68,15,56,200,212 + movups 16(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,236 + pxor %xmm4,%xmm6 +.byte 15,56,201,220 + movups 32(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm9 +.byte 69,15,58,204,194,2 +.byte 68,15,56,200,205 + movups 48(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,245 + pxor %xmm5,%xmm3 +.byte 15,56,201,229 + cmpl $11,%r11d + jb .Laesenclast13 + movups 64(%rcx),%xmm0 +.byte 102,15,56,220,209 + movups 80(%rcx),%xmm1 +.byte 102,15,56,220,208 + je .Laesenclast13 + movups 96(%rcx),%xmm0 +.byte 102,15,56,220,209 + movups 112(%rcx),%xmm1 +.byte 102,15,56,220,208 +.Laesenclast13: +.byte 102,15,56,221,209 + movups 16-112(%rcx),%xmm0 + movdqa %xmm8,%xmm10 +.byte 69,15,58,204,193,2 +.byte 68,15,56,200,214 + movups 48(%rdi),%xmm14 + xorps %xmm15,%xmm14 + movups %xmm2,32(%rsi,%rdi,1) + xorps %xmm14,%xmm2 + movups -80(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,222 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 + movups -64(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm9 +.byte 69,15,58,204,194,3 +.byte 68,15,56,200,203 + movups -48(%rcx),%xmm1 +.byte 102,15,56,220,208 +.byte 15,56,202,227 + pxor %xmm3,%xmm5 +.byte 15,56,201,243 + movups -32(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm8,%xmm10 +.byte 69,15,58,204,193,3 +.byte 68,15,56,200,212 +.byte 15,56,202,236 + pxor %xmm4,%xmm6 + movups -16(%rcx),%xmm1 +.byte 102,15,56,220,208 + movdqa %xmm8,%xmm9 +.byte 69,15,58,204,194,3 +.byte 68,15,56,200,205 +.byte 15,56,202,245 + movups 0(%rcx),%xmm0 +.byte 102,15,56,220,209 + movdqa %xmm12,%xmm5 + movdqa %xmm8,%xmm10 +.byte 69,15,58,204,193,3 +.byte 68,15,56,200,214 + movups 16(%rcx),%xmm1 +.byte 102,15,56,220,208 + movdqa %xmm8,%xmm9 +.byte 69,15,58,204,194,3 +.byte 68,15,56,200,205 + movups 32(%rcx),%xmm0 +.byte 102,15,56,220,209 + movups 48(%rcx),%xmm1 +.byte 102,15,56,220,208 + cmpl $11,%r11d + jb .Laesenclast14 + movups 64(%rcx),%xmm0 +.byte 102,15,56,220,209 + movups 80(%rcx),%xmm1 +.byte 102,15,56,220,208 + je .Laesenclast14 + movups 96(%rcx),%xmm0 +.byte 102,15,56,220,209 + movups 112(%rcx),%xmm1 +.byte 102,15,56,220,208 +.Laesenclast14: +.byte 102,15,56,221,209 + movups 16-112(%rcx),%xmm0 + decq %rdx + + paddd %xmm11,%xmm8 + movups %xmm2,48(%rsi,%rdi,1) + leaq 64(%rdi),%rdi + jnz .Loop_shaext + + pshufd $27,%xmm8,%xmm8 + pshufd $27,%xmm9,%xmm9 + movups %xmm2,(%r8) + movdqu %xmm8,(%r9) + movd %xmm9,16(%r9) + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_cbc_sha1_enc_shaext,.-aesni_cbc_sha1_enc_shaext + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/aes/aesni-sha256-x86_64.S b/crypto/openssl/crypto/aes/aesni-sha256-x86_64.S new file mode 100644 index 000000000000..c938e50b990b --- /dev/null +++ b/crypto/openssl/crypto/aes/aesni-sha256-x86_64.S @@ -0,0 +1,4456 @@ +.text + + +.globl aesni_cbc_sha256_enc +.type aesni_cbc_sha256_enc,@function +.align 16 +aesni_cbc_sha256_enc: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%r11 + movl $1,%eax + cmpq $0,%rdi + je .Lprobe + movl 0(%r11),%eax + movq 4(%r11),%r10 + btq $61,%r10 + jc aesni_cbc_sha256_enc_shaext + movq %r10,%r11 + shrq $32,%r11 + + testl $2048,%r10d + jnz aesni_cbc_sha256_enc_xop + andl $296,%r11d + cmpl $296,%r11d + je aesni_cbc_sha256_enc_avx2 + andl $268435456,%r10d + jnz aesni_cbc_sha256_enc_avx + ud2 + xorl %eax,%eax + cmpq $0,%rdi + je .Lprobe + ud2 +.Lprobe: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_cbc_sha256_enc,.-aesni_cbc_sha256_enc + +.align 64 +.type K256,@object +K256: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 + +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0,0,0,0, 0,0,0,0, -1,-1,-1,-1 +.long 0,0,0,0, 0,0,0,0 +.byte 65,69,83,78,73,45,67,66,67,43,83,72,65,50,53,54,32,115,116,105,116,99,104,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 +.type aesni_cbc_sha256_enc_xop,@function +.align 64 +aesni_cbc_sha256_enc_xop: +.cfi_startproc +.Lxop_shortcut: + movq 8(%rsp),%r10 + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + subq $128,%rsp + andq $-64,%rsp + + shlq $6,%rdx + subq %rdi,%rsi + subq %rdi,%r10 + addq %rdi,%rdx + + + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + + movq %r8,64+32(%rsp) + movq %r9,64+40(%rsp) + movq %r10,64+48(%rsp) + movq %rax,120(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xf8,0x00,0x06,0x23,0x08 +.Lprologue_xop: + vzeroall + + movq %rdi,%r12 + leaq 128(%rcx),%rdi + leaq K256+544(%rip),%r13 + movl 240-128(%rdi),%r14d + movq %r9,%r15 + movq %r10,%rsi + vmovdqu (%r8),%xmm8 + subq $9,%r14 + + movl 0(%r15),%eax + movl 4(%r15),%ebx + movl 8(%r15),%ecx + movl 12(%r15),%edx + movl 16(%r15),%r8d + movl 20(%r15),%r9d + movl 24(%r15),%r10d + movl 28(%r15),%r11d + + vmovdqa 0(%r13,%r14,8),%xmm14 + vmovdqa 16(%r13,%r14,8),%xmm13 + vmovdqa 32(%r13,%r14,8),%xmm12 + vmovdqu 0-128(%rdi),%xmm10 + jmp .Lloop_xop +.align 16 +.Lloop_xop: + vmovdqa K256+512(%rip),%xmm7 + vmovdqu 0(%rsi,%r12,1),%xmm0 + vmovdqu 16(%rsi,%r12,1),%xmm1 + vmovdqu 32(%rsi,%r12,1),%xmm2 + vmovdqu 48(%rsi,%r12,1),%xmm3 + vpshufb %xmm7,%xmm0,%xmm0 + leaq K256(%rip),%rbp + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd 0(%rbp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 32(%rbp),%xmm1,%xmm5 + vpaddd 64(%rbp),%xmm2,%xmm6 + vpaddd 96(%rbp),%xmm3,%xmm7 + vmovdqa %xmm4,0(%rsp) + movl %eax,%r14d + vmovdqa %xmm5,16(%rsp) + movl %ebx,%esi + vmovdqa %xmm6,32(%rsp) + xorl %ecx,%esi + vmovdqa %xmm7,48(%rsp) + movl %r8d,%r13d + jmp .Lxop_00_47 + +.align 16 +.Lxop_00_47: + subq $-32*4,%rbp + vmovdqu (%r12),%xmm9 + movq %r12,64+0(%rsp) + vpalignr $4,%xmm0,%xmm1,%xmm4 + rorl $14,%r13d + movl %r14d,%eax + vpalignr $4,%xmm2,%xmm3,%xmm7 + movl %r9d,%r12d + xorl %r8d,%r13d +.byte 143,232,120,194,236,14 + rorl $9,%r14d + xorl %r10d,%r12d + vpsrld $3,%xmm4,%xmm4 + rorl $5,%r13d + xorl %eax,%r14d + vpaddd %xmm7,%xmm0,%xmm0 + andl %r8d,%r12d + vpxor %xmm10,%xmm9,%xmm9 + vmovdqu 16-128(%rdi),%xmm10 + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d +.byte 143,232,120,194,245,11 + rorl $11,%r14d + xorl %r10d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + xorl %ebx,%r15d + rorl $6,%r13d + addl %r12d,%r11d + andl %r15d,%esi +.byte 143,232,120,194,251,13 + xorl %eax,%r14d + addl %r13d,%r11d + vpxor %xmm6,%xmm4,%xmm4 + xorl %ebx,%esi + addl %r11d,%edx + vpsrld $10,%xmm3,%xmm6 + rorl $2,%r14d + addl %esi,%r11d + vpaddd %xmm4,%xmm0,%xmm0 + movl %edx,%r13d + addl %r11d,%r14d +.byte 143,232,120,194,239,2 + rorl $14,%r13d + movl %r14d,%r11d + vpxor %xmm6,%xmm7,%xmm7 + movl %r8d,%r12d + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%r12d + vpxor %xmm5,%xmm7,%xmm7 + rorl $5,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + vpxor %xmm8,%xmm9,%xmm9 + xorl %edx,%r13d + vpsrldq $8,%xmm7,%xmm7 + addl 4(%rsp),%r10d + movl %r11d,%esi + rorl $11,%r14d + xorl %r9d,%r12d + vpaddd %xmm7,%xmm0,%xmm0 + xorl %eax,%esi + rorl $6,%r13d + addl %r12d,%r10d + andl %esi,%r15d +.byte 143,232,120,194,248,13 + xorl %r11d,%r14d + addl %r13d,%r10d + vpsrld $10,%xmm0,%xmm6 + xorl %eax,%r15d + addl %r10d,%ecx +.byte 143,232,120,194,239,2 + rorl $2,%r14d + addl %r15d,%r10d + vpxor %xmm6,%xmm7,%xmm7 + movl %ecx,%r13d + addl %r10d,%r14d + rorl $14,%r13d + movl %r14d,%r10d + vpxor %xmm5,%xmm7,%xmm7 + movl %edx,%r12d + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r12d + vpslldq $8,%xmm7,%xmm7 + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 32-128(%rdi),%xmm10 + xorl %ecx,%r13d + vpaddd %xmm7,%xmm0,%xmm0 + addl 8(%rsp),%r9d + movl %r10d,%r15d + rorl $11,%r14d + xorl %r8d,%r12d + vpaddd 0(%rbp),%xmm0,%xmm6 + xorl %r11d,%r15d + rorl $6,%r13d + addl %r12d,%r9d + andl %r15d,%esi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%esi + addl %r9d,%ebx + rorl $2,%r14d + addl %esi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + rorl $14,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 48-128(%rdi),%xmm10 + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%esi + rorl $11,%r14d + xorl %edx,%r12d + xorl %r10d,%esi + rorl $6,%r13d + addl %r12d,%r8d + andl %esi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + addl %r8d,%eax + rorl $2,%r14d + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,0(%rsp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + rorl $14,%r13d + movl %r14d,%r8d + vpalignr $4,%xmm3,%xmm0,%xmm7 + movl %ebx,%r12d + xorl %eax,%r13d +.byte 143,232,120,194,236,14 + rorl $9,%r14d + xorl %ecx,%r12d + vpsrld $3,%xmm4,%xmm4 + rorl $5,%r13d + xorl %r8d,%r14d + vpaddd %xmm7,%xmm1,%xmm1 + andl %eax,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 64-128(%rdi),%xmm10 + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d +.byte 143,232,120,194,245,11 + rorl $11,%r14d + xorl %ecx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + xorl %r9d,%r15d + rorl $6,%r13d + addl %r12d,%edx + andl %r15d,%esi +.byte 143,232,120,194,248,13 + xorl %r8d,%r14d + addl %r13d,%edx + vpxor %xmm6,%xmm4,%xmm4 + xorl %r9d,%esi + addl %edx,%r11d + vpsrld $10,%xmm0,%xmm6 + rorl $2,%r14d + addl %esi,%edx + vpaddd %xmm4,%xmm1,%xmm1 + movl %r11d,%r13d + addl %edx,%r14d +.byte 143,232,120,194,239,2 + rorl $14,%r13d + movl %r14d,%edx + vpxor %xmm6,%xmm7,%xmm7 + movl %eax,%r12d + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%r12d + vpxor %xmm5,%xmm7,%xmm7 + rorl $5,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 80-128(%rdi),%xmm10 + xorl %r11d,%r13d + vpsrldq $8,%xmm7,%xmm7 + addl 20(%rsp),%ecx + movl %edx,%esi + rorl $11,%r14d + xorl %ebx,%r12d + vpaddd %xmm7,%xmm1,%xmm1 + xorl %r8d,%esi + rorl $6,%r13d + addl %r12d,%ecx + andl %esi,%r15d +.byte 143,232,120,194,249,13 + xorl %edx,%r14d + addl %r13d,%ecx + vpsrld $10,%xmm1,%xmm6 + xorl %r8d,%r15d + addl %ecx,%r10d +.byte 143,232,120,194,239,2 + rorl $2,%r14d + addl %r15d,%ecx + vpxor %xmm6,%xmm7,%xmm7 + movl %r10d,%r13d + addl %ecx,%r14d + rorl $14,%r13d + movl %r14d,%ecx + vpxor %xmm5,%xmm7,%xmm7 + movl %r11d,%r12d + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r12d + vpslldq $8,%xmm7,%xmm7 + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 96-128(%rdi),%xmm10 + xorl %r10d,%r13d + vpaddd %xmm7,%xmm1,%xmm1 + addl 24(%rsp),%ebx + movl %ecx,%r15d + rorl $11,%r14d + xorl %eax,%r12d + vpaddd 32(%rbp),%xmm1,%xmm6 + xorl %edx,%r15d + rorl $6,%r13d + addl %r12d,%ebx + andl %r15d,%esi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%esi + addl %ebx,%r9d + rorl $2,%r14d + addl %esi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + rorl $14,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 112-128(%rdi),%xmm10 + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%esi + rorl $11,%r14d + xorl %r11d,%r12d + xorl %ecx,%esi + rorl $6,%r13d + addl %r12d,%eax + andl %esi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + addl %eax,%r8d + rorl $2,%r14d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,16(%rsp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + rorl $14,%r13d + movl %r14d,%eax + vpalignr $4,%xmm0,%xmm1,%xmm7 + movl %r9d,%r12d + xorl %r8d,%r13d +.byte 143,232,120,194,236,14 + rorl $9,%r14d + xorl %r10d,%r12d + vpsrld $3,%xmm4,%xmm4 + rorl $5,%r13d + xorl %eax,%r14d + vpaddd %xmm7,%xmm2,%xmm2 + andl %r8d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 128-128(%rdi),%xmm10 + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d +.byte 143,232,120,194,245,11 + rorl $11,%r14d + xorl %r10d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + xorl %ebx,%r15d + rorl $6,%r13d + addl %r12d,%r11d + andl %r15d,%esi +.byte 143,232,120,194,249,13 + xorl %eax,%r14d + addl %r13d,%r11d + vpxor %xmm6,%xmm4,%xmm4 + xorl %ebx,%esi + addl %r11d,%edx + vpsrld $10,%xmm1,%xmm6 + rorl $2,%r14d + addl %esi,%r11d + vpaddd %xmm4,%xmm2,%xmm2 + movl %edx,%r13d + addl %r11d,%r14d +.byte 143,232,120,194,239,2 + rorl $14,%r13d + movl %r14d,%r11d + vpxor %xmm6,%xmm7,%xmm7 + movl %r8d,%r12d + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%r12d + vpxor %xmm5,%xmm7,%xmm7 + rorl $5,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 144-128(%rdi),%xmm10 + xorl %edx,%r13d + vpsrldq $8,%xmm7,%xmm7 + addl 36(%rsp),%r10d + movl %r11d,%esi + rorl $11,%r14d + xorl %r9d,%r12d + vpaddd %xmm7,%xmm2,%xmm2 + xorl %eax,%esi + rorl $6,%r13d + addl %r12d,%r10d + andl %esi,%r15d +.byte 143,232,120,194,250,13 + xorl %r11d,%r14d + addl %r13d,%r10d + vpsrld $10,%xmm2,%xmm6 + xorl %eax,%r15d + addl %r10d,%ecx +.byte 143,232,120,194,239,2 + rorl $2,%r14d + addl %r15d,%r10d + vpxor %xmm6,%xmm7,%xmm7 + movl %ecx,%r13d + addl %r10d,%r14d + rorl $14,%r13d + movl %r14d,%r10d + vpxor %xmm5,%xmm7,%xmm7 + movl %edx,%r12d + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r12d + vpslldq $8,%xmm7,%xmm7 + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 160-128(%rdi),%xmm10 + xorl %ecx,%r13d + vpaddd %xmm7,%xmm2,%xmm2 + addl 40(%rsp),%r9d + movl %r10d,%r15d + rorl $11,%r14d + xorl %r8d,%r12d + vpaddd 64(%rbp),%xmm2,%xmm6 + xorl %r11d,%r15d + rorl $6,%r13d + addl %r12d,%r9d + andl %r15d,%esi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%esi + addl %r9d,%ebx + rorl $2,%r14d + addl %esi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + rorl $14,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 176-128(%rdi),%xmm10 + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%esi + rorl $11,%r14d + xorl %edx,%r12d + xorl %r10d,%esi + rorl $6,%r13d + addl %r12d,%r8d + andl %esi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + addl %r8d,%eax + rorl $2,%r14d + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,32(%rsp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + rorl $14,%r13d + movl %r14d,%r8d + vpalignr $4,%xmm1,%xmm2,%xmm7 + movl %ebx,%r12d + xorl %eax,%r13d +.byte 143,232,120,194,236,14 + rorl $9,%r14d + xorl %ecx,%r12d + vpsrld $3,%xmm4,%xmm4 + rorl $5,%r13d + xorl %r8d,%r14d + vpaddd %xmm7,%xmm3,%xmm3 + andl %eax,%r12d + vpand %xmm12,%xmm11,%xmm8 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 192-128(%rdi),%xmm10 + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d +.byte 143,232,120,194,245,11 + rorl $11,%r14d + xorl %ecx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + xorl %r9d,%r15d + rorl $6,%r13d + addl %r12d,%edx + andl %r15d,%esi +.byte 143,232,120,194,250,13 + xorl %r8d,%r14d + addl %r13d,%edx + vpxor %xmm6,%xmm4,%xmm4 + xorl %r9d,%esi + addl %edx,%r11d + vpsrld $10,%xmm2,%xmm6 + rorl $2,%r14d + addl %esi,%edx + vpaddd %xmm4,%xmm3,%xmm3 + movl %r11d,%r13d + addl %edx,%r14d +.byte 143,232,120,194,239,2 + rorl $14,%r13d + movl %r14d,%edx + vpxor %xmm6,%xmm7,%xmm7 + movl %eax,%r12d + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%r12d + vpxor %xmm5,%xmm7,%xmm7 + rorl $5,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 208-128(%rdi),%xmm10 + xorl %r11d,%r13d + vpsrldq $8,%xmm7,%xmm7 + addl 52(%rsp),%ecx + movl %edx,%esi + rorl $11,%r14d + xorl %ebx,%r12d + vpaddd %xmm7,%xmm3,%xmm3 + xorl %r8d,%esi + rorl $6,%r13d + addl %r12d,%ecx + andl %esi,%r15d +.byte 143,232,120,194,251,13 + xorl %edx,%r14d + addl %r13d,%ecx + vpsrld $10,%xmm3,%xmm6 + xorl %r8d,%r15d + addl %ecx,%r10d +.byte 143,232,120,194,239,2 + rorl $2,%r14d + addl %r15d,%ecx + vpxor %xmm6,%xmm7,%xmm7 + movl %r10d,%r13d + addl %ecx,%r14d + rorl $14,%r13d + movl %r14d,%ecx + vpxor %xmm5,%xmm7,%xmm7 + movl %r11d,%r12d + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r12d + vpslldq $8,%xmm7,%xmm7 + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + vpand %xmm13,%xmm11,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 224-128(%rdi),%xmm10 + xorl %r10d,%r13d + vpaddd %xmm7,%xmm3,%xmm3 + addl 56(%rsp),%ebx + movl %ecx,%r15d + rorl $11,%r14d + xorl %eax,%r12d + vpaddd 96(%rbp),%xmm3,%xmm6 + xorl %edx,%r15d + rorl $6,%r13d + addl %r12d,%ebx + andl %r15d,%esi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%esi + addl %ebx,%r9d + rorl $2,%r14d + addl %esi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + rorl $14,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpor %xmm11,%xmm8,%xmm8 + vaesenclast %xmm10,%xmm9,%xmm11 + vmovdqu 0-128(%rdi),%xmm10 + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%esi + rorl $11,%r14d + xorl %r11d,%r12d + xorl %ecx,%esi + rorl $6,%r13d + addl %r12d,%eax + andl %esi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + addl %eax,%r8d + rorl $2,%r14d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,48(%rsp) + movq 64+0(%rsp),%r12 + vpand %xmm14,%xmm11,%xmm11 + movq 64+8(%rsp),%r15 + vpor %xmm11,%xmm8,%xmm8 + vmovdqu %xmm8,(%r15,%r12,1) + leaq 16(%r12),%r12 + cmpb $0,131(%rbp) + jne .Lxop_00_47 + vmovdqu (%r12),%xmm9 + movq %r12,64+0(%rsp) + rorl $14,%r13d + movl %r14d,%eax + movl %r9d,%r12d + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpxor %xmm10,%xmm9,%xmm9 + vmovdqu 16-128(%rdi),%xmm10 + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + rorl $11,%r14d + xorl %r10d,%r12d + xorl %ebx,%r15d + rorl $6,%r13d + addl %r12d,%r11d + andl %r15d,%esi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%esi + addl %r11d,%edx + rorl $2,%r14d + addl %esi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + rorl $14,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%r12d + rorl $5,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + vpxor %xmm8,%xmm9,%xmm9 + xorl %edx,%r13d + addl 4(%rsp),%r10d + movl %r11d,%esi + rorl $11,%r14d + xorl %r9d,%r12d + xorl %eax,%esi + rorl $6,%r13d + addl %r12d,%r10d + andl %esi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + addl %r10d,%ecx + rorl $2,%r14d + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r12d + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 32-128(%rdi),%xmm10 + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + rorl $11,%r14d + xorl %r8d,%r12d + xorl %r11d,%r15d + rorl $6,%r13d + addl %r12d,%r9d + andl %r15d,%esi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%esi + addl %r9d,%ebx + rorl $2,%r14d + addl %esi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + rorl $14,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 48-128(%rdi),%xmm10 + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%esi + rorl $11,%r14d + xorl %edx,%r12d + xorl %r10d,%esi + rorl $6,%r13d + addl %r12d,%r8d + andl %esi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + addl %r8d,%eax + rorl $2,%r14d + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + rorl $14,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 64-128(%rdi),%xmm10 + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + rorl $11,%r14d + xorl %ecx,%r12d + xorl %r9d,%r15d + rorl $6,%r13d + addl %r12d,%edx + andl %r15d,%esi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%esi + addl %edx,%r11d + rorl $2,%r14d + addl %esi,%edx + movl %r11d,%r13d + addl %edx,%r14d + rorl $14,%r13d + movl %r14d,%edx + movl %eax,%r12d + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%r12d + rorl $5,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 80-128(%rdi),%xmm10 + xorl %r11d,%r13d + addl 20(%rsp),%ecx + movl %edx,%esi + rorl $11,%r14d + xorl %ebx,%r12d + xorl %r8d,%esi + rorl $6,%r13d + addl %r12d,%ecx + andl %esi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + addl %ecx,%r10d + rorl $2,%r14d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r12d + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 96-128(%rdi),%xmm10 + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + rorl $11,%r14d + xorl %eax,%r12d + xorl %edx,%r15d + rorl $6,%r13d + addl %r12d,%ebx + andl %r15d,%esi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%esi + addl %ebx,%r9d + rorl $2,%r14d + addl %esi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + rorl $14,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 112-128(%rdi),%xmm10 + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%esi + rorl $11,%r14d + xorl %r11d,%r12d + xorl %ecx,%esi + rorl $6,%r13d + addl %r12d,%eax + andl %esi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + addl %eax,%r8d + rorl $2,%r14d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + rorl $14,%r13d + movl %r14d,%eax + movl %r9d,%r12d + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 128-128(%rdi),%xmm10 + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + rorl $11,%r14d + xorl %r10d,%r12d + xorl %ebx,%r15d + rorl $6,%r13d + addl %r12d,%r11d + andl %r15d,%esi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%esi + addl %r11d,%edx + rorl $2,%r14d + addl %esi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + rorl $14,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%r12d + rorl $5,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 144-128(%rdi),%xmm10 + xorl %edx,%r13d + addl 36(%rsp),%r10d + movl %r11d,%esi + rorl $11,%r14d + xorl %r9d,%r12d + xorl %eax,%esi + rorl $6,%r13d + addl %r12d,%r10d + andl %esi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + addl %r10d,%ecx + rorl $2,%r14d + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r12d + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 160-128(%rdi),%xmm10 + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + rorl $11,%r14d + xorl %r8d,%r12d + xorl %r11d,%r15d + rorl $6,%r13d + addl %r12d,%r9d + andl %r15d,%esi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%esi + addl %r9d,%ebx + rorl $2,%r14d + addl %esi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + rorl $14,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 176-128(%rdi),%xmm10 + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%esi + rorl $11,%r14d + xorl %edx,%r12d + xorl %r10d,%esi + rorl $6,%r13d + addl %r12d,%r8d + andl %esi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + addl %r8d,%eax + rorl $2,%r14d + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + rorl $14,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpand %xmm12,%xmm11,%xmm8 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 192-128(%rdi),%xmm10 + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + rorl $11,%r14d + xorl %ecx,%r12d + xorl %r9d,%r15d + rorl $6,%r13d + addl %r12d,%edx + andl %r15d,%esi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%esi + addl %edx,%r11d + rorl $2,%r14d + addl %esi,%edx + movl %r11d,%r13d + addl %edx,%r14d + rorl $14,%r13d + movl %r14d,%edx + movl %eax,%r12d + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%r12d + rorl $5,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 208-128(%rdi),%xmm10 + xorl %r11d,%r13d + addl 52(%rsp),%ecx + movl %edx,%esi + rorl $11,%r14d + xorl %ebx,%r12d + xorl %r8d,%esi + rorl $6,%r13d + addl %r12d,%ecx + andl %esi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + addl %ecx,%r10d + rorl $2,%r14d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r12d + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + vpand %xmm13,%xmm11,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 224-128(%rdi),%xmm10 + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + rorl $11,%r14d + xorl %eax,%r12d + xorl %edx,%r15d + rorl $6,%r13d + addl %r12d,%ebx + andl %r15d,%esi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%esi + addl %ebx,%r9d + rorl $2,%r14d + addl %esi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + rorl $14,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpor %xmm11,%xmm8,%xmm8 + vaesenclast %xmm10,%xmm9,%xmm11 + vmovdqu 0-128(%rdi),%xmm10 + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%esi + rorl $11,%r14d + xorl %r11d,%r12d + xorl %ecx,%esi + rorl $6,%r13d + addl %r12d,%eax + andl %esi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + addl %eax,%r8d + rorl $2,%r14d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + movq 64+0(%rsp),%r12 + movq 64+8(%rsp),%r13 + movq 64+40(%rsp),%r15 + movq 64+48(%rsp),%rsi + + vpand %xmm14,%xmm11,%xmm11 + movl %r14d,%eax + vpor %xmm11,%xmm8,%xmm8 + vmovdqu %xmm8,(%r12,%r13,1) + leaq 16(%r12),%r12 + + addl 0(%r15),%eax + addl 4(%r15),%ebx + addl 8(%r15),%ecx + addl 12(%r15),%edx + addl 16(%r15),%r8d + addl 20(%r15),%r9d + addl 24(%r15),%r10d + addl 28(%r15),%r11d + + cmpq 64+16(%rsp),%r12 + + movl %eax,0(%r15) + movl %ebx,4(%r15) + movl %ecx,8(%r15) + movl %edx,12(%r15) + movl %r8d,16(%r15) + movl %r9d,20(%r15) + movl %r10d,24(%r15) + movl %r11d,28(%r15) + + jb .Lloop_xop + + movq 64+32(%rsp),%r8 + movq 120(%rsp),%rsi +.cfi_def_cfa %rsi,8 + vmovdqu %xmm8,(%r8) + vzeroall + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_xop: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_cbc_sha256_enc_xop,.-aesni_cbc_sha256_enc_xop +.type aesni_cbc_sha256_enc_avx,@function +.align 64 +aesni_cbc_sha256_enc_avx: +.cfi_startproc +.Lavx_shortcut: + movq 8(%rsp),%r10 + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + subq $128,%rsp + andq $-64,%rsp + + shlq $6,%rdx + subq %rdi,%rsi + subq %rdi,%r10 + addq %rdi,%rdx + + + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + + movq %r8,64+32(%rsp) + movq %r9,64+40(%rsp) + movq %r10,64+48(%rsp) + movq %rax,120(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xf8,0x00,0x06,0x23,0x08 +.Lprologue_avx: + vzeroall + + movq %rdi,%r12 + leaq 128(%rcx),%rdi + leaq K256+544(%rip),%r13 + movl 240-128(%rdi),%r14d + movq %r9,%r15 + movq %r10,%rsi + vmovdqu (%r8),%xmm8 + subq $9,%r14 + + movl 0(%r15),%eax + movl 4(%r15),%ebx + movl 8(%r15),%ecx + movl 12(%r15),%edx + movl 16(%r15),%r8d + movl 20(%r15),%r9d + movl 24(%r15),%r10d + movl 28(%r15),%r11d + + vmovdqa 0(%r13,%r14,8),%xmm14 + vmovdqa 16(%r13,%r14,8),%xmm13 + vmovdqa 32(%r13,%r14,8),%xmm12 + vmovdqu 0-128(%rdi),%xmm10 + jmp .Lloop_avx +.align 16 +.Lloop_avx: + vmovdqa K256+512(%rip),%xmm7 + vmovdqu 0(%rsi,%r12,1),%xmm0 + vmovdqu 16(%rsi,%r12,1),%xmm1 + vmovdqu 32(%rsi,%r12,1),%xmm2 + vmovdqu 48(%rsi,%r12,1),%xmm3 + vpshufb %xmm7,%xmm0,%xmm0 + leaq K256(%rip),%rbp + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd 0(%rbp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 32(%rbp),%xmm1,%xmm5 + vpaddd 64(%rbp),%xmm2,%xmm6 + vpaddd 96(%rbp),%xmm3,%xmm7 + vmovdqa %xmm4,0(%rsp) + movl %eax,%r14d + vmovdqa %xmm5,16(%rsp) + movl %ebx,%esi + vmovdqa %xmm6,32(%rsp) + xorl %ecx,%esi + vmovdqa %xmm7,48(%rsp) + movl %r8d,%r13d + jmp .Lavx_00_47 + +.align 16 +.Lavx_00_47: + subq $-32*4,%rbp + vmovdqu (%r12),%xmm9 + movq %r12,64+0(%rsp) + vpalignr $4,%xmm0,%xmm1,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm2,%xmm3,%xmm7 + xorl %r8d,%r13d + shrdl $9,%r14d,%r14d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm0,%xmm0 + vpxor %xmm10,%xmm9,%xmm9 + vmovdqu 16-128(%rdi),%xmm10 + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + shrdl $11,%r14d,%r14d + xorl %r10d,%r12d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + shrdl $6,%r13d,%r13d + addl %r12d,%r11d + andl %r15d,%esi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%esi + vpshufd $250,%xmm3,%xmm7 + addl %r11d,%edx + shrdl $2,%r14d,%r14d + addl %esi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + xorl %edx,%r13d + vpslld $11,%xmm5,%xmm5 + shrdl $9,%r14d,%r14d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + vpxor %xmm8,%xmm9,%xmm9 + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 4(%rsp),%r10d + movl %r11d,%esi + shrdl $11,%r14d,%r14d + vpxor %xmm5,%xmm4,%xmm4 + xorl %r9d,%r12d + xorl %eax,%esi + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + addl %r12d,%r10d + andl %esi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm0,%xmm0 + addl %r13d,%r10d + xorl %eax,%r15d + addl %r10d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $2,%r14d,%r14d + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + xorl %ecx,%r13d + shrdl $9,%r14d,%r14d + vpshufd $132,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpsrldq $8,%xmm6,%xmm6 + andl %ecx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 32-128(%rdi),%xmm10 + xorl %ecx,%r13d + addl 8(%rsp),%r9d + vpaddd %xmm6,%xmm0,%xmm0 + movl %r10d,%r15d + shrdl $11,%r14d,%r14d + xorl %r8d,%r12d + vpshufd $80,%xmm0,%xmm7 + xorl %r11d,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%r9d + vpsrld $10,%xmm7,%xmm6 + andl %r15d,%esi + xorl %r10d,%r14d + addl %r13d,%r9d + vpsrlq $17,%xmm7,%xmm7 + xorl %r11d,%esi + addl %r9d,%ebx + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %esi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpsrlq $2,%xmm7,%xmm7 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpxor %xmm7,%xmm6,%xmm6 + xorl %ebx,%r13d + shrdl $9,%r14d,%r14d + xorl %edx,%r12d + vpshufd $232,%xmm6,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpslldq $8,%xmm6,%xmm6 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 48-128(%rdi),%xmm10 + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%esi + vpaddd %xmm6,%xmm0,%xmm0 + shrdl $11,%r14d,%r14d + xorl %edx,%r12d + xorl %r10d,%esi + vpaddd 0(%rbp),%xmm0,%xmm6 + shrdl $6,%r13d,%r13d + addl %r12d,%r8d + andl %esi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + addl %r8d,%eax + shrdl $2,%r14d,%r14d + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,0(%rsp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm3,%xmm0,%xmm7 + xorl %eax,%r13d + shrdl $9,%r14d,%r14d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm1,%xmm1 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 64-128(%rdi),%xmm10 + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + shrdl $11,%r14d,%r14d + xorl %ecx,%r12d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + shrdl $6,%r13d,%r13d + addl %r12d,%edx + andl %r15d,%esi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%esi + vpshufd $250,%xmm0,%xmm7 + addl %edx,%r11d + shrdl $2,%r14d,%r14d + addl %esi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + xorl %r11d,%r13d + vpslld $11,%xmm5,%xmm5 + shrdl $9,%r14d,%r14d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 80-128(%rdi),%xmm10 + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 20(%rsp),%ecx + movl %edx,%esi + shrdl $11,%r14d,%r14d + vpxor %xmm5,%xmm4,%xmm4 + xorl %ebx,%r12d + xorl %r8d,%esi + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + addl %r12d,%ecx + andl %esi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm1,%xmm1 + addl %r13d,%ecx + xorl %r8d,%r15d + addl %ecx,%r10d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $2,%r14d,%r14d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + xorl %r10d,%r13d + shrdl $9,%r14d,%r14d + vpshufd $132,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpsrldq $8,%xmm6,%xmm6 + andl %r10d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 96-128(%rdi),%xmm10 + xorl %r10d,%r13d + addl 24(%rsp),%ebx + vpaddd %xmm6,%xmm1,%xmm1 + movl %ecx,%r15d + shrdl $11,%r14d,%r14d + xorl %eax,%r12d + vpshufd $80,%xmm1,%xmm7 + xorl %edx,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%ebx + vpsrld $10,%xmm7,%xmm6 + andl %r15d,%esi + xorl %ecx,%r14d + addl %r13d,%ebx + vpsrlq $17,%xmm7,%xmm7 + xorl %edx,%esi + addl %ebx,%r9d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %esi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpsrlq $2,%xmm7,%xmm7 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r9d,%r13d + shrdl $9,%r14d,%r14d + xorl %r11d,%r12d + vpshufd $232,%xmm6,%xmm6 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpslldq $8,%xmm6,%xmm6 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 112-128(%rdi),%xmm10 + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%esi + vpaddd %xmm6,%xmm1,%xmm1 + shrdl $11,%r14d,%r14d + xorl %r11d,%r12d + xorl %ecx,%esi + vpaddd 32(%rbp),%xmm1,%xmm6 + shrdl $6,%r13d,%r13d + addl %r12d,%eax + andl %esi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + addl %eax,%r8d + shrdl $2,%r14d,%r14d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,16(%rsp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm0,%xmm1,%xmm7 + xorl %r8d,%r13d + shrdl $9,%r14d,%r14d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm2,%xmm2 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 128-128(%rdi),%xmm10 + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + shrdl $11,%r14d,%r14d + xorl %r10d,%r12d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + shrdl $6,%r13d,%r13d + addl %r12d,%r11d + andl %r15d,%esi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%esi + vpshufd $250,%xmm1,%xmm7 + addl %r11d,%edx + shrdl $2,%r14d,%r14d + addl %esi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + xorl %edx,%r13d + vpslld $11,%xmm5,%xmm5 + shrdl $9,%r14d,%r14d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 144-128(%rdi),%xmm10 + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 36(%rsp),%r10d + movl %r11d,%esi + shrdl $11,%r14d,%r14d + vpxor %xmm5,%xmm4,%xmm4 + xorl %r9d,%r12d + xorl %eax,%esi + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + addl %r12d,%r10d + andl %esi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm2,%xmm2 + addl %r13d,%r10d + xorl %eax,%r15d + addl %r10d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $2,%r14d,%r14d + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + xorl %ecx,%r13d + shrdl $9,%r14d,%r14d + vpshufd $132,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpsrldq $8,%xmm6,%xmm6 + andl %ecx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 160-128(%rdi),%xmm10 + xorl %ecx,%r13d + addl 40(%rsp),%r9d + vpaddd %xmm6,%xmm2,%xmm2 + movl %r10d,%r15d + shrdl $11,%r14d,%r14d + xorl %r8d,%r12d + vpshufd $80,%xmm2,%xmm7 + xorl %r11d,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%r9d + vpsrld $10,%xmm7,%xmm6 + andl %r15d,%esi + xorl %r10d,%r14d + addl %r13d,%r9d + vpsrlq $17,%xmm7,%xmm7 + xorl %r11d,%esi + addl %r9d,%ebx + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %esi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpsrlq $2,%xmm7,%xmm7 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpxor %xmm7,%xmm6,%xmm6 + xorl %ebx,%r13d + shrdl $9,%r14d,%r14d + xorl %edx,%r12d + vpshufd $232,%xmm6,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpslldq $8,%xmm6,%xmm6 + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 176-128(%rdi),%xmm10 + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%esi + vpaddd %xmm6,%xmm2,%xmm2 + shrdl $11,%r14d,%r14d + xorl %edx,%r12d + xorl %r10d,%esi + vpaddd 64(%rbp),%xmm2,%xmm6 + shrdl $6,%r13d,%r13d + addl %r12d,%r8d + andl %esi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + addl %r8d,%eax + shrdl $2,%r14d,%r14d + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,32(%rsp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm1,%xmm2,%xmm7 + xorl %eax,%r13d + shrdl $9,%r14d,%r14d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm3,%xmm3 + vpand %xmm12,%xmm11,%xmm8 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 192-128(%rdi),%xmm10 + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + shrdl $11,%r14d,%r14d + xorl %ecx,%r12d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + shrdl $6,%r13d,%r13d + addl %r12d,%edx + andl %r15d,%esi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%esi + vpshufd $250,%xmm2,%xmm7 + addl %edx,%r11d + shrdl $2,%r14d,%r14d + addl %esi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + xorl %r11d,%r13d + vpslld $11,%xmm5,%xmm5 + shrdl $9,%r14d,%r14d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 208-128(%rdi),%xmm10 + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 52(%rsp),%ecx + movl %edx,%esi + shrdl $11,%r14d,%r14d + vpxor %xmm5,%xmm4,%xmm4 + xorl %ebx,%r12d + xorl %r8d,%esi + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + addl %r12d,%ecx + andl %esi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm3,%xmm3 + addl %r13d,%ecx + xorl %r8d,%r15d + addl %ecx,%r10d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $2,%r14d,%r14d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + xorl %r10d,%r13d + shrdl $9,%r14d,%r14d + vpshufd $132,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpsrldq $8,%xmm6,%xmm6 + andl %r10d,%r12d + vpand %xmm13,%xmm11,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 224-128(%rdi),%xmm10 + xorl %r10d,%r13d + addl 56(%rsp),%ebx + vpaddd %xmm6,%xmm3,%xmm3 + movl %ecx,%r15d + shrdl $11,%r14d,%r14d + xorl %eax,%r12d + vpshufd $80,%xmm3,%xmm7 + xorl %edx,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%ebx + vpsrld $10,%xmm7,%xmm6 + andl %r15d,%esi + xorl %ecx,%r14d + addl %r13d,%ebx + vpsrlq $17,%xmm7,%xmm7 + xorl %edx,%esi + addl %ebx,%r9d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %esi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpsrlq $2,%xmm7,%xmm7 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r9d,%r13d + shrdl $9,%r14d,%r14d + xorl %r11d,%r12d + vpshufd $232,%xmm6,%xmm6 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpslldq $8,%xmm6,%xmm6 + vpor %xmm11,%xmm8,%xmm8 + vaesenclast %xmm10,%xmm9,%xmm11 + vmovdqu 0-128(%rdi),%xmm10 + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%esi + vpaddd %xmm6,%xmm3,%xmm3 + shrdl $11,%r14d,%r14d + xorl %r11d,%r12d + xorl %ecx,%esi + vpaddd 96(%rbp),%xmm3,%xmm6 + shrdl $6,%r13d,%r13d + addl %r12d,%eax + andl %esi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + addl %eax,%r8d + shrdl $2,%r14d,%r14d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,48(%rsp) + movq 64+0(%rsp),%r12 + vpand %xmm14,%xmm11,%xmm11 + movq 64+8(%rsp),%r15 + vpor %xmm11,%xmm8,%xmm8 + vmovdqu %xmm8,(%r15,%r12,1) + leaq 16(%r12),%r12 + cmpb $0,131(%rbp) + jne .Lavx_00_47 + vmovdqu (%r12),%xmm9 + movq %r12,64+0(%rsp) + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + xorl %r8d,%r13d + shrdl $9,%r14d,%r14d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpxor %xmm10,%xmm9,%xmm9 + vmovdqu 16-128(%rdi),%xmm10 + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + shrdl $11,%r14d,%r14d + xorl %r10d,%r12d + xorl %ebx,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%r11d + andl %r15d,%esi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%esi + addl %r11d,%edx + shrdl $2,%r14d,%r14d + addl %esi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + xorl %edx,%r13d + shrdl $9,%r14d,%r14d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + vpxor %xmm8,%xmm9,%xmm9 + xorl %edx,%r13d + addl 4(%rsp),%r10d + movl %r11d,%esi + shrdl $11,%r14d,%r14d + xorl %r9d,%r12d + xorl %eax,%esi + shrdl $6,%r13d,%r13d + addl %r12d,%r10d + andl %esi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + addl %r10d,%ecx + shrdl $2,%r14d,%r14d + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + xorl %ecx,%r13d + shrdl $9,%r14d,%r14d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 32-128(%rdi),%xmm10 + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + shrdl $11,%r14d,%r14d + xorl %r8d,%r12d + xorl %r11d,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%r9d + andl %r15d,%esi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%esi + addl %r9d,%ebx + shrdl $2,%r14d,%r14d + addl %esi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + xorl %ebx,%r13d + shrdl $9,%r14d,%r14d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 48-128(%rdi),%xmm10 + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%esi + shrdl $11,%r14d,%r14d + xorl %edx,%r12d + xorl %r10d,%esi + shrdl $6,%r13d,%r13d + addl %r12d,%r8d + andl %esi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + addl %r8d,%eax + shrdl $2,%r14d,%r14d + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + xorl %eax,%r13d + shrdl $9,%r14d,%r14d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 64-128(%rdi),%xmm10 + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + shrdl $11,%r14d,%r14d + xorl %ecx,%r12d + xorl %r9d,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%edx + andl %r15d,%esi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%esi + addl %edx,%r11d + shrdl $2,%r14d,%r14d + addl %esi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + xorl %r11d,%r13d + shrdl $9,%r14d,%r14d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 80-128(%rdi),%xmm10 + xorl %r11d,%r13d + addl 20(%rsp),%ecx + movl %edx,%esi + shrdl $11,%r14d,%r14d + xorl %ebx,%r12d + xorl %r8d,%esi + shrdl $6,%r13d,%r13d + addl %r12d,%ecx + andl %esi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + addl %ecx,%r10d + shrdl $2,%r14d,%r14d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + xorl %r10d,%r13d + shrdl $9,%r14d,%r14d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 96-128(%rdi),%xmm10 + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + shrdl $11,%r14d,%r14d + xorl %eax,%r12d + xorl %edx,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%ebx + andl %r15d,%esi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%esi + addl %ebx,%r9d + shrdl $2,%r14d,%r14d + addl %esi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + xorl %r9d,%r13d + shrdl $9,%r14d,%r14d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 112-128(%rdi),%xmm10 + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%esi + shrdl $11,%r14d,%r14d + xorl %r11d,%r12d + xorl %ecx,%esi + shrdl $6,%r13d,%r13d + addl %r12d,%eax + andl %esi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + addl %eax,%r8d + shrdl $2,%r14d,%r14d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + xorl %r8d,%r13d + shrdl $9,%r14d,%r14d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 128-128(%rdi),%xmm10 + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + shrdl $11,%r14d,%r14d + xorl %r10d,%r12d + xorl %ebx,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%r11d + andl %r15d,%esi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%esi + addl %r11d,%edx + shrdl $2,%r14d,%r14d + addl %esi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + xorl %edx,%r13d + shrdl $9,%r14d,%r14d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 144-128(%rdi),%xmm10 + xorl %edx,%r13d + addl 36(%rsp),%r10d + movl %r11d,%esi + shrdl $11,%r14d,%r14d + xorl %r9d,%r12d + xorl %eax,%esi + shrdl $6,%r13d,%r13d + addl %r12d,%r10d + andl %esi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + addl %r10d,%ecx + shrdl $2,%r14d,%r14d + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + xorl %ecx,%r13d + shrdl $9,%r14d,%r14d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 160-128(%rdi),%xmm10 + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + shrdl $11,%r14d,%r14d + xorl %r8d,%r12d + xorl %r11d,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%r9d + andl %r15d,%esi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%esi + addl %r9d,%ebx + shrdl $2,%r14d,%r14d + addl %esi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + xorl %ebx,%r13d + shrdl $9,%r14d,%r14d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 176-128(%rdi),%xmm10 + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%esi + shrdl $11,%r14d,%r14d + xorl %edx,%r12d + xorl %r10d,%esi + shrdl $6,%r13d,%r13d + addl %r12d,%r8d + andl %esi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + addl %r8d,%eax + shrdl $2,%r14d,%r14d + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + xorl %eax,%r13d + shrdl $9,%r14d,%r14d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpand %xmm12,%xmm11,%xmm8 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 192-128(%rdi),%xmm10 + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + shrdl $11,%r14d,%r14d + xorl %ecx,%r12d + xorl %r9d,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%edx + andl %r15d,%esi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%esi + addl %edx,%r11d + shrdl $2,%r14d,%r14d + addl %esi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + xorl %r11d,%r13d + shrdl $9,%r14d,%r14d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 208-128(%rdi),%xmm10 + xorl %r11d,%r13d + addl 52(%rsp),%ecx + movl %edx,%esi + shrdl $11,%r14d,%r14d + xorl %ebx,%r12d + xorl %r8d,%esi + shrdl $6,%r13d,%r13d + addl %r12d,%ecx + andl %esi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + addl %ecx,%r10d + shrdl $2,%r14d,%r14d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + xorl %r10d,%r13d + shrdl $9,%r14d,%r14d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + vpand %xmm13,%xmm11,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 224-128(%rdi),%xmm10 + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + shrdl $11,%r14d,%r14d + xorl %eax,%r12d + xorl %edx,%r15d + shrdl $6,%r13d,%r13d + addl %r12d,%ebx + andl %r15d,%esi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%esi + addl %ebx,%r9d + shrdl $2,%r14d,%r14d + addl %esi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + xorl %r9d,%r13d + shrdl $9,%r14d,%r14d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpor %xmm11,%xmm8,%xmm8 + vaesenclast %xmm10,%xmm9,%xmm11 + vmovdqu 0-128(%rdi),%xmm10 + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%esi + shrdl $11,%r14d,%r14d + xorl %r11d,%r12d + xorl %ecx,%esi + shrdl $6,%r13d,%r13d + addl %r12d,%eax + andl %esi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + addl %eax,%r8d + shrdl $2,%r14d,%r14d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + movq 64+0(%rsp),%r12 + movq 64+8(%rsp),%r13 + movq 64+40(%rsp),%r15 + movq 64+48(%rsp),%rsi + + vpand %xmm14,%xmm11,%xmm11 + movl %r14d,%eax + vpor %xmm11,%xmm8,%xmm8 + vmovdqu %xmm8,(%r12,%r13,1) + leaq 16(%r12),%r12 + + addl 0(%r15),%eax + addl 4(%r15),%ebx + addl 8(%r15),%ecx + addl 12(%r15),%edx + addl 16(%r15),%r8d + addl 20(%r15),%r9d + addl 24(%r15),%r10d + addl 28(%r15),%r11d + + cmpq 64+16(%rsp),%r12 + + movl %eax,0(%r15) + movl %ebx,4(%r15) + movl %ecx,8(%r15) + movl %edx,12(%r15) + movl %r8d,16(%r15) + movl %r9d,20(%r15) + movl %r10d,24(%r15) + movl %r11d,28(%r15) + jb .Lloop_avx + + movq 64+32(%rsp),%r8 + movq 120(%rsp),%rsi +.cfi_def_cfa %rsi,8 + vmovdqu %xmm8,(%r8) + vzeroall + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_cbc_sha256_enc_avx,.-aesni_cbc_sha256_enc_avx +.type aesni_cbc_sha256_enc_avx2,@function +.align 64 +aesni_cbc_sha256_enc_avx2: +.cfi_startproc +.Lavx2_shortcut: + movq 8(%rsp),%r10 + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + subq $576,%rsp + andq $-1024,%rsp + addq $448,%rsp + + shlq $6,%rdx + subq %rdi,%rsi + subq %rdi,%r10 + addq %rdi,%rdx + + + + movq %rdx,64+16(%rsp) + + movq %r8,64+32(%rsp) + movq %r9,64+40(%rsp) + movq %r10,64+48(%rsp) + movq %rax,120(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xf8,0x00,0x06,0x23,0x08 +.Lprologue_avx2: + vzeroall + + movq %rdi,%r13 + vpinsrq $1,%rsi,%xmm15,%xmm15 + leaq 128(%rcx),%rdi + leaq K256+544(%rip),%r12 + movl 240-128(%rdi),%r14d + movq %r9,%r15 + movq %r10,%rsi + vmovdqu (%r8),%xmm8 + leaq -9(%r14),%r14 + + vmovdqa 0(%r12,%r14,8),%xmm14 + vmovdqa 16(%r12,%r14,8),%xmm13 + vmovdqa 32(%r12,%r14,8),%xmm12 + + subq $-64,%r13 + movl 0(%r15),%eax + leaq (%rsi,%r13,1),%r12 + movl 4(%r15),%ebx + cmpq %rdx,%r13 + movl 8(%r15),%ecx + cmoveq %rsp,%r12 + movl 12(%r15),%edx + movl 16(%r15),%r8d + movl 20(%r15),%r9d + movl 24(%r15),%r10d + movl 28(%r15),%r11d + vmovdqu 0-128(%rdi),%xmm10 + jmp .Loop_avx2 +.align 16 +.Loop_avx2: + vmovdqa K256+512(%rip),%ymm7 + vmovdqu -64+0(%rsi,%r13,1),%xmm0 + vmovdqu -64+16(%rsi,%r13,1),%xmm1 + vmovdqu -64+32(%rsi,%r13,1),%xmm2 + vmovdqu -64+48(%rsi,%r13,1),%xmm3 + + vinserti128 $1,(%r12),%ymm0,%ymm0 + vinserti128 $1,16(%r12),%ymm1,%ymm1 + vpshufb %ymm7,%ymm0,%ymm0 + vinserti128 $1,32(%r12),%ymm2,%ymm2 + vpshufb %ymm7,%ymm1,%ymm1 + vinserti128 $1,48(%r12),%ymm3,%ymm3 + + leaq K256(%rip),%rbp + vpshufb %ymm7,%ymm2,%ymm2 + leaq -64(%r13),%r13 + vpaddd 0(%rbp),%ymm0,%ymm4 + vpshufb %ymm7,%ymm3,%ymm3 + vpaddd 32(%rbp),%ymm1,%ymm5 + vpaddd 64(%rbp),%ymm2,%ymm6 + vpaddd 96(%rbp),%ymm3,%ymm7 + vmovdqa %ymm4,0(%rsp) + xorl %r14d,%r14d + vmovdqa %ymm5,32(%rsp) + + movq 120(%rsp),%rsi +.cfi_def_cfa %rsi,8 + leaq -64(%rsp),%rsp + + + + movq %rsi,-8(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x78,0x06,0x23,0x08 + movl %ebx,%esi + vmovdqa %ymm6,0(%rsp) + xorl %ecx,%esi + vmovdqa %ymm7,32(%rsp) + movl %r9d,%r12d + subq $-32*4,%rbp + jmp .Lavx2_00_47 + +.align 16 +.Lavx2_00_47: + vmovdqu (%r13),%xmm9 + vpinsrq $0,%r13,%xmm15,%xmm15 + leaq -64(%rsp),%rsp +.cfi_escape 0x0f,0x05,0x77,0x38,0x06,0x23,0x08 + + pushq 64-8(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x00,0x06,0x23,0x08 + leaq 8(%rsp),%rsp +.cfi_escape 0x0f,0x05,0x77,0x78,0x06,0x23,0x08 + vpalignr $4,%ymm0,%ymm1,%ymm4 + addl 0+128(%rsp),%r11d + andl %r8d,%r12d + rorxl $25,%r8d,%r13d + vpalignr $4,%ymm2,%ymm3,%ymm7 + rorxl $11,%r8d,%r15d + leal (%rax,%r14,1),%eax + leal (%r11,%r12,1),%r11d + vpsrld $7,%ymm4,%ymm6 + andnl %r10d,%r8d,%r12d + xorl %r15d,%r13d + rorxl $6,%r8d,%r14d + vpaddd %ymm7,%ymm0,%ymm0 + leal (%r11,%r12,1),%r11d + xorl %r14d,%r13d + movl %eax,%r15d + vpsrld $3,%ymm4,%ymm7 + rorxl $22,%eax,%r12d + leal (%r11,%r13,1),%r11d + xorl %ebx,%r15d + vpslld $14,%ymm4,%ymm5 + rorxl $13,%eax,%r14d + rorxl $2,%eax,%r13d + leal (%rdx,%r11,1),%edx + vpxor %ymm6,%ymm7,%ymm4 + andl %r15d,%esi + vpxor %xmm10,%xmm9,%xmm9 + vmovdqu 16-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ebx,%esi + vpshufd $250,%ymm3,%ymm7 + xorl %r13d,%r14d + leal (%r11,%rsi,1),%r11d + movl %r8d,%r12d + vpsrld $11,%ymm6,%ymm6 + addl 4+128(%rsp),%r10d + andl %edx,%r12d + rorxl $25,%edx,%r13d + vpxor %ymm5,%ymm4,%ymm4 + rorxl $11,%edx,%esi + leal (%r11,%r14,1),%r11d + leal (%r10,%r12,1),%r10d + vpslld $11,%ymm5,%ymm5 + andnl %r9d,%edx,%r12d + xorl %esi,%r13d + rorxl $6,%edx,%r14d + vpxor %ymm6,%ymm4,%ymm4 + leal (%r10,%r12,1),%r10d + xorl %r14d,%r13d + movl %r11d,%esi + vpsrld $10,%ymm7,%ymm6 + rorxl $22,%r11d,%r12d + leal (%r10,%r13,1),%r10d + xorl %eax,%esi + vpxor %ymm5,%ymm4,%ymm4 + rorxl $13,%r11d,%r14d + rorxl $2,%r11d,%r13d + leal (%rcx,%r10,1),%ecx + vpsrlq $17,%ymm7,%ymm7 + andl %esi,%r15d + vpxor %xmm8,%xmm9,%xmm9 + xorl %r12d,%r14d + xorl %eax,%r15d + vpaddd %ymm4,%ymm0,%ymm0 + xorl %r13d,%r14d + leal (%r10,%r15,1),%r10d + movl %edx,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 8+128(%rsp),%r9d + andl %ecx,%r12d + rorxl $25,%ecx,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%ecx,%r15d + leal (%r10,%r14,1),%r10d + leal (%r9,%r12,1),%r9d + vpxor %ymm7,%ymm6,%ymm6 + andnl %r8d,%ecx,%r12d + xorl %r15d,%r13d + rorxl $6,%ecx,%r14d + vpshufd $132,%ymm6,%ymm6 + leal (%r9,%r12,1),%r9d + xorl %r14d,%r13d + movl %r10d,%r15d + vpsrldq $8,%ymm6,%ymm6 + rorxl $22,%r10d,%r12d + leal (%r9,%r13,1),%r9d + xorl %r11d,%r15d + vpaddd %ymm6,%ymm0,%ymm0 + rorxl $13,%r10d,%r14d + rorxl $2,%r10d,%r13d + leal (%rbx,%r9,1),%ebx + vpshufd $80,%ymm0,%ymm7 + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 32-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r11d,%esi + vpsrld $10,%ymm7,%ymm6 + xorl %r13d,%r14d + leal (%r9,%rsi,1),%r9d + movl %ecx,%r12d + vpsrlq $17,%ymm7,%ymm7 + addl 12+128(%rsp),%r8d + andl %ebx,%r12d + rorxl $25,%ebx,%r13d + vpxor %ymm7,%ymm6,%ymm6 + rorxl $11,%ebx,%esi + leal (%r9,%r14,1),%r9d + leal (%r8,%r12,1),%r8d + vpsrlq $2,%ymm7,%ymm7 + andnl %edx,%ebx,%r12d + xorl %esi,%r13d + rorxl $6,%ebx,%r14d + vpxor %ymm7,%ymm6,%ymm6 + leal (%r8,%r12,1),%r8d + xorl %r14d,%r13d + movl %r9d,%esi + vpshufd $232,%ymm6,%ymm6 + rorxl $22,%r9d,%r12d + leal (%r8,%r13,1),%r8d + xorl %r10d,%esi + vpslldq $8,%ymm6,%ymm6 + rorxl $13,%r9d,%r14d + rorxl $2,%r9d,%r13d + leal (%rax,%r8,1),%eax + vpaddd %ymm6,%ymm0,%ymm0 + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 48-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r10d,%r15d + vpaddd 0(%rbp),%ymm0,%ymm6 + xorl %r13d,%r14d + leal (%r8,%r15,1),%r8d + movl %ebx,%r12d + vmovdqa %ymm6,0(%rsp) + vpalignr $4,%ymm1,%ymm2,%ymm4 + addl 32+128(%rsp),%edx + andl %eax,%r12d + rorxl $25,%eax,%r13d + vpalignr $4,%ymm3,%ymm0,%ymm7 + rorxl $11,%eax,%r15d + leal (%r8,%r14,1),%r8d + leal (%rdx,%r12,1),%edx + vpsrld $7,%ymm4,%ymm6 + andnl %ecx,%eax,%r12d + xorl %r15d,%r13d + rorxl $6,%eax,%r14d + vpaddd %ymm7,%ymm1,%ymm1 + leal (%rdx,%r12,1),%edx + xorl %r14d,%r13d + movl %r8d,%r15d + vpsrld $3,%ymm4,%ymm7 + rorxl $22,%r8d,%r12d + leal (%rdx,%r13,1),%edx + xorl %r9d,%r15d + vpslld $14,%ymm4,%ymm5 + rorxl $13,%r8d,%r14d + rorxl $2,%r8d,%r13d + leal (%r11,%rdx,1),%r11d + vpxor %ymm6,%ymm7,%ymm4 + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 64-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r9d,%esi + vpshufd $250,%ymm0,%ymm7 + xorl %r13d,%r14d + leal (%rdx,%rsi,1),%edx + movl %eax,%r12d + vpsrld $11,%ymm6,%ymm6 + addl 36+128(%rsp),%ecx + andl %r11d,%r12d + rorxl $25,%r11d,%r13d + vpxor %ymm5,%ymm4,%ymm4 + rorxl $11,%r11d,%esi + leal (%rdx,%r14,1),%edx + leal (%rcx,%r12,1),%ecx + vpslld $11,%ymm5,%ymm5 + andnl %ebx,%r11d,%r12d + xorl %esi,%r13d + rorxl $6,%r11d,%r14d + vpxor %ymm6,%ymm4,%ymm4 + leal (%rcx,%r12,1),%ecx + xorl %r14d,%r13d + movl %edx,%esi + vpsrld $10,%ymm7,%ymm6 + rorxl $22,%edx,%r12d + leal (%rcx,%r13,1),%ecx + xorl %r8d,%esi + vpxor %ymm5,%ymm4,%ymm4 + rorxl $13,%edx,%r14d + rorxl $2,%edx,%r13d + leal (%r10,%rcx,1),%r10d + vpsrlq $17,%ymm7,%ymm7 + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 80-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r8d,%r15d + vpaddd %ymm4,%ymm1,%ymm1 + xorl %r13d,%r14d + leal (%rcx,%r15,1),%ecx + movl %r11d,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 40+128(%rsp),%ebx + andl %r10d,%r12d + rorxl $25,%r10d,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%r10d,%r15d + leal (%rcx,%r14,1),%ecx + leal (%rbx,%r12,1),%ebx + vpxor %ymm7,%ymm6,%ymm6 + andnl %eax,%r10d,%r12d + xorl %r15d,%r13d + rorxl $6,%r10d,%r14d + vpshufd $132,%ymm6,%ymm6 + leal (%rbx,%r12,1),%ebx + xorl %r14d,%r13d + movl %ecx,%r15d + vpsrldq $8,%ymm6,%ymm6 + rorxl $22,%ecx,%r12d + leal (%rbx,%r13,1),%ebx + xorl %edx,%r15d + vpaddd %ymm6,%ymm1,%ymm1 + rorxl $13,%ecx,%r14d + rorxl $2,%ecx,%r13d + leal (%r9,%rbx,1),%r9d + vpshufd $80,%ymm1,%ymm7 + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 96-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %edx,%esi + vpsrld $10,%ymm7,%ymm6 + xorl %r13d,%r14d + leal (%rbx,%rsi,1),%ebx + movl %r10d,%r12d + vpsrlq $17,%ymm7,%ymm7 + addl 44+128(%rsp),%eax + andl %r9d,%r12d + rorxl $25,%r9d,%r13d + vpxor %ymm7,%ymm6,%ymm6 + rorxl $11,%r9d,%esi + leal (%rbx,%r14,1),%ebx + leal (%rax,%r12,1),%eax + vpsrlq $2,%ymm7,%ymm7 + andnl %r11d,%r9d,%r12d + xorl %esi,%r13d + rorxl $6,%r9d,%r14d + vpxor %ymm7,%ymm6,%ymm6 + leal (%rax,%r12,1),%eax + xorl %r14d,%r13d + movl %ebx,%esi + vpshufd $232,%ymm6,%ymm6 + rorxl $22,%ebx,%r12d + leal (%rax,%r13,1),%eax + xorl %ecx,%esi + vpslldq $8,%ymm6,%ymm6 + rorxl $13,%ebx,%r14d + rorxl $2,%ebx,%r13d + leal (%r8,%rax,1),%r8d + vpaddd %ymm6,%ymm1,%ymm1 + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 112-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ecx,%r15d + vpaddd 32(%rbp),%ymm1,%ymm6 + xorl %r13d,%r14d + leal (%rax,%r15,1),%eax + movl %r9d,%r12d + vmovdqa %ymm6,32(%rsp) + leaq -64(%rsp),%rsp +.cfi_escape 0x0f,0x05,0x77,0x38,0x06,0x23,0x08 + + pushq 64-8(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x00,0x06,0x23,0x08 + leaq 8(%rsp),%rsp +.cfi_escape 0x0f,0x05,0x77,0x78,0x06,0x23,0x08 + vpalignr $4,%ymm2,%ymm3,%ymm4 + addl 0+128(%rsp),%r11d + andl %r8d,%r12d + rorxl $25,%r8d,%r13d + vpalignr $4,%ymm0,%ymm1,%ymm7 + rorxl $11,%r8d,%r15d + leal (%rax,%r14,1),%eax + leal (%r11,%r12,1),%r11d + vpsrld $7,%ymm4,%ymm6 + andnl %r10d,%r8d,%r12d + xorl %r15d,%r13d + rorxl $6,%r8d,%r14d + vpaddd %ymm7,%ymm2,%ymm2 + leal (%r11,%r12,1),%r11d + xorl %r14d,%r13d + movl %eax,%r15d + vpsrld $3,%ymm4,%ymm7 + rorxl $22,%eax,%r12d + leal (%r11,%r13,1),%r11d + xorl %ebx,%r15d + vpslld $14,%ymm4,%ymm5 + rorxl $13,%eax,%r14d + rorxl $2,%eax,%r13d + leal (%rdx,%r11,1),%edx + vpxor %ymm6,%ymm7,%ymm4 + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 128-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ebx,%esi + vpshufd $250,%ymm1,%ymm7 + xorl %r13d,%r14d + leal (%r11,%rsi,1),%r11d + movl %r8d,%r12d + vpsrld $11,%ymm6,%ymm6 + addl 4+128(%rsp),%r10d + andl %edx,%r12d + rorxl $25,%edx,%r13d + vpxor %ymm5,%ymm4,%ymm4 + rorxl $11,%edx,%esi + leal (%r11,%r14,1),%r11d + leal (%r10,%r12,1),%r10d + vpslld $11,%ymm5,%ymm5 + andnl %r9d,%edx,%r12d + xorl %esi,%r13d + rorxl $6,%edx,%r14d + vpxor %ymm6,%ymm4,%ymm4 + leal (%r10,%r12,1),%r10d + xorl %r14d,%r13d + movl %r11d,%esi + vpsrld $10,%ymm7,%ymm6 + rorxl $22,%r11d,%r12d + leal (%r10,%r13,1),%r10d + xorl %eax,%esi + vpxor %ymm5,%ymm4,%ymm4 + rorxl $13,%r11d,%r14d + rorxl $2,%r11d,%r13d + leal (%rcx,%r10,1),%ecx + vpsrlq $17,%ymm7,%ymm7 + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 144-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %eax,%r15d + vpaddd %ymm4,%ymm2,%ymm2 + xorl %r13d,%r14d + leal (%r10,%r15,1),%r10d + movl %edx,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 8+128(%rsp),%r9d + andl %ecx,%r12d + rorxl $25,%ecx,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%ecx,%r15d + leal (%r10,%r14,1),%r10d + leal (%r9,%r12,1),%r9d + vpxor %ymm7,%ymm6,%ymm6 + andnl %r8d,%ecx,%r12d + xorl %r15d,%r13d + rorxl $6,%ecx,%r14d + vpshufd $132,%ymm6,%ymm6 + leal (%r9,%r12,1),%r9d + xorl %r14d,%r13d + movl %r10d,%r15d + vpsrldq $8,%ymm6,%ymm6 + rorxl $22,%r10d,%r12d + leal (%r9,%r13,1),%r9d + xorl %r11d,%r15d + vpaddd %ymm6,%ymm2,%ymm2 + rorxl $13,%r10d,%r14d + rorxl $2,%r10d,%r13d + leal (%rbx,%r9,1),%ebx + vpshufd $80,%ymm2,%ymm7 + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 160-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r11d,%esi + vpsrld $10,%ymm7,%ymm6 + xorl %r13d,%r14d + leal (%r9,%rsi,1),%r9d + movl %ecx,%r12d + vpsrlq $17,%ymm7,%ymm7 + addl 12+128(%rsp),%r8d + andl %ebx,%r12d + rorxl $25,%ebx,%r13d + vpxor %ymm7,%ymm6,%ymm6 + rorxl $11,%ebx,%esi + leal (%r9,%r14,1),%r9d + leal (%r8,%r12,1),%r8d + vpsrlq $2,%ymm7,%ymm7 + andnl %edx,%ebx,%r12d + xorl %esi,%r13d + rorxl $6,%ebx,%r14d + vpxor %ymm7,%ymm6,%ymm6 + leal (%r8,%r12,1),%r8d + xorl %r14d,%r13d + movl %r9d,%esi + vpshufd $232,%ymm6,%ymm6 + rorxl $22,%r9d,%r12d + leal (%r8,%r13,1),%r8d + xorl %r10d,%esi + vpslldq $8,%ymm6,%ymm6 + rorxl $13,%r9d,%r14d + rorxl $2,%r9d,%r13d + leal (%rax,%r8,1),%eax + vpaddd %ymm6,%ymm2,%ymm2 + andl %esi,%r15d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 176-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r10d,%r15d + vpaddd 64(%rbp),%ymm2,%ymm6 + xorl %r13d,%r14d + leal (%r8,%r15,1),%r8d + movl %ebx,%r12d + vmovdqa %ymm6,0(%rsp) + vpalignr $4,%ymm3,%ymm0,%ymm4 + addl 32+128(%rsp),%edx + andl %eax,%r12d + rorxl $25,%eax,%r13d + vpalignr $4,%ymm1,%ymm2,%ymm7 + rorxl $11,%eax,%r15d + leal (%r8,%r14,1),%r8d + leal (%rdx,%r12,1),%edx + vpsrld $7,%ymm4,%ymm6 + andnl %ecx,%eax,%r12d + xorl %r15d,%r13d + rorxl $6,%eax,%r14d + vpaddd %ymm7,%ymm3,%ymm3 + leal (%rdx,%r12,1),%edx + xorl %r14d,%r13d + movl %r8d,%r15d + vpsrld $3,%ymm4,%ymm7 + rorxl $22,%r8d,%r12d + leal (%rdx,%r13,1),%edx + xorl %r9d,%r15d + vpslld $14,%ymm4,%ymm5 + rorxl $13,%r8d,%r14d + rorxl $2,%r8d,%r13d + leal (%r11,%rdx,1),%r11d + vpxor %ymm6,%ymm7,%ymm4 + andl %r15d,%esi + vpand %xmm12,%xmm11,%xmm8 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 192-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r9d,%esi + vpshufd $250,%ymm2,%ymm7 + xorl %r13d,%r14d + leal (%rdx,%rsi,1),%edx + movl %eax,%r12d + vpsrld $11,%ymm6,%ymm6 + addl 36+128(%rsp),%ecx + andl %r11d,%r12d + rorxl $25,%r11d,%r13d + vpxor %ymm5,%ymm4,%ymm4 + rorxl $11,%r11d,%esi + leal (%rdx,%r14,1),%edx + leal (%rcx,%r12,1),%ecx + vpslld $11,%ymm5,%ymm5 + andnl %ebx,%r11d,%r12d + xorl %esi,%r13d + rorxl $6,%r11d,%r14d + vpxor %ymm6,%ymm4,%ymm4 + leal (%rcx,%r12,1),%ecx + xorl %r14d,%r13d + movl %edx,%esi + vpsrld $10,%ymm7,%ymm6 + rorxl $22,%edx,%r12d + leal (%rcx,%r13,1),%ecx + xorl %r8d,%esi + vpxor %ymm5,%ymm4,%ymm4 + rorxl $13,%edx,%r14d + rorxl $2,%edx,%r13d + leal (%r10,%rcx,1),%r10d + vpsrlq $17,%ymm7,%ymm7 + andl %esi,%r15d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 208-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r8d,%r15d + vpaddd %ymm4,%ymm3,%ymm3 + xorl %r13d,%r14d + leal (%rcx,%r15,1),%ecx + movl %r11d,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 40+128(%rsp),%ebx + andl %r10d,%r12d + rorxl $25,%r10d,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%r10d,%r15d + leal (%rcx,%r14,1),%ecx + leal (%rbx,%r12,1),%ebx + vpxor %ymm7,%ymm6,%ymm6 + andnl %eax,%r10d,%r12d + xorl %r15d,%r13d + rorxl $6,%r10d,%r14d + vpshufd $132,%ymm6,%ymm6 + leal (%rbx,%r12,1),%ebx + xorl %r14d,%r13d + movl %ecx,%r15d + vpsrldq $8,%ymm6,%ymm6 + rorxl $22,%ecx,%r12d + leal (%rbx,%r13,1),%ebx + xorl %edx,%r15d + vpaddd %ymm6,%ymm3,%ymm3 + rorxl $13,%ecx,%r14d + rorxl $2,%ecx,%r13d + leal (%r9,%rbx,1),%r9d + vpshufd $80,%ymm3,%ymm7 + andl %r15d,%esi + vpand %xmm13,%xmm11,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 224-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %edx,%esi + vpsrld $10,%ymm7,%ymm6 + xorl %r13d,%r14d + leal (%rbx,%rsi,1),%ebx + movl %r10d,%r12d + vpsrlq $17,%ymm7,%ymm7 + addl 44+128(%rsp),%eax + andl %r9d,%r12d + rorxl $25,%r9d,%r13d + vpxor %ymm7,%ymm6,%ymm6 + rorxl $11,%r9d,%esi + leal (%rbx,%r14,1),%ebx + leal (%rax,%r12,1),%eax + vpsrlq $2,%ymm7,%ymm7 + andnl %r11d,%r9d,%r12d + xorl %esi,%r13d + rorxl $6,%r9d,%r14d + vpxor %ymm7,%ymm6,%ymm6 + leal (%rax,%r12,1),%eax + xorl %r14d,%r13d + movl %ebx,%esi + vpshufd $232,%ymm6,%ymm6 + rorxl $22,%ebx,%r12d + leal (%rax,%r13,1),%eax + xorl %ecx,%esi + vpslldq $8,%ymm6,%ymm6 + rorxl $13,%ebx,%r14d + rorxl $2,%ebx,%r13d + leal (%r8,%rax,1),%r8d + vpaddd %ymm6,%ymm3,%ymm3 + andl %esi,%r15d + vpor %xmm11,%xmm8,%xmm8 + vaesenclast %xmm10,%xmm9,%xmm11 + vmovdqu 0-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ecx,%r15d + vpaddd 96(%rbp),%ymm3,%ymm6 + xorl %r13d,%r14d + leal (%rax,%r15,1),%eax + movl %r9d,%r12d + vmovdqa %ymm6,32(%rsp) + vmovq %xmm15,%r13 + vpextrq $1,%xmm15,%r15 + vpand %xmm14,%xmm11,%xmm11 + vpor %xmm11,%xmm8,%xmm8 + vmovdqu %xmm8,(%r15,%r13,1) + leaq 16(%r13),%r13 + leaq 128(%rbp),%rbp + cmpb $0,3(%rbp) + jne .Lavx2_00_47 + vmovdqu (%r13),%xmm9 + vpinsrq $0,%r13,%xmm15,%xmm15 + addl 0+64(%rsp),%r11d + andl %r8d,%r12d + rorxl $25,%r8d,%r13d + rorxl $11,%r8d,%r15d + leal (%rax,%r14,1),%eax + leal (%r11,%r12,1),%r11d + andnl %r10d,%r8d,%r12d + xorl %r15d,%r13d + rorxl $6,%r8d,%r14d + leal (%r11,%r12,1),%r11d + xorl %r14d,%r13d + movl %eax,%r15d + rorxl $22,%eax,%r12d + leal (%r11,%r13,1),%r11d + xorl %ebx,%r15d + rorxl $13,%eax,%r14d + rorxl $2,%eax,%r13d + leal (%rdx,%r11,1),%edx + andl %r15d,%esi + vpxor %xmm10,%xmm9,%xmm9 + vmovdqu 16-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ebx,%esi + xorl %r13d,%r14d + leal (%r11,%rsi,1),%r11d + movl %r8d,%r12d + addl 4+64(%rsp),%r10d + andl %edx,%r12d + rorxl $25,%edx,%r13d + rorxl $11,%edx,%esi + leal (%r11,%r14,1),%r11d + leal (%r10,%r12,1),%r10d + andnl %r9d,%edx,%r12d + xorl %esi,%r13d + rorxl $6,%edx,%r14d + leal (%r10,%r12,1),%r10d + xorl %r14d,%r13d + movl %r11d,%esi + rorxl $22,%r11d,%r12d + leal (%r10,%r13,1),%r10d + xorl %eax,%esi + rorxl $13,%r11d,%r14d + rorxl $2,%r11d,%r13d + leal (%rcx,%r10,1),%ecx + andl %esi,%r15d + vpxor %xmm8,%xmm9,%xmm9 + xorl %r12d,%r14d + xorl %eax,%r15d + xorl %r13d,%r14d + leal (%r10,%r15,1),%r10d + movl %edx,%r12d + addl 8+64(%rsp),%r9d + andl %ecx,%r12d + rorxl $25,%ecx,%r13d + rorxl $11,%ecx,%r15d + leal (%r10,%r14,1),%r10d + leal (%r9,%r12,1),%r9d + andnl %r8d,%ecx,%r12d + xorl %r15d,%r13d + rorxl $6,%ecx,%r14d + leal (%r9,%r12,1),%r9d + xorl %r14d,%r13d + movl %r10d,%r15d + rorxl $22,%r10d,%r12d + leal (%r9,%r13,1),%r9d + xorl %r11d,%r15d + rorxl $13,%r10d,%r14d + rorxl $2,%r10d,%r13d + leal (%rbx,%r9,1),%ebx + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 32-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r11d,%esi + xorl %r13d,%r14d + leal (%r9,%rsi,1),%r9d + movl %ecx,%r12d + addl 12+64(%rsp),%r8d + andl %ebx,%r12d + rorxl $25,%ebx,%r13d + rorxl $11,%ebx,%esi + leal (%r9,%r14,1),%r9d + leal (%r8,%r12,1),%r8d + andnl %edx,%ebx,%r12d + xorl %esi,%r13d + rorxl $6,%ebx,%r14d + leal (%r8,%r12,1),%r8d + xorl %r14d,%r13d + movl %r9d,%esi + rorxl $22,%r9d,%r12d + leal (%r8,%r13,1),%r8d + xorl %r10d,%esi + rorxl $13,%r9d,%r14d + rorxl $2,%r9d,%r13d + leal (%rax,%r8,1),%eax + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 48-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r10d,%r15d + xorl %r13d,%r14d + leal (%r8,%r15,1),%r8d + movl %ebx,%r12d + addl 32+64(%rsp),%edx + andl %eax,%r12d + rorxl $25,%eax,%r13d + rorxl $11,%eax,%r15d + leal (%r8,%r14,1),%r8d + leal (%rdx,%r12,1),%edx + andnl %ecx,%eax,%r12d + xorl %r15d,%r13d + rorxl $6,%eax,%r14d + leal (%rdx,%r12,1),%edx + xorl %r14d,%r13d + movl %r8d,%r15d + rorxl $22,%r8d,%r12d + leal (%rdx,%r13,1),%edx + xorl %r9d,%r15d + rorxl $13,%r8d,%r14d + rorxl $2,%r8d,%r13d + leal (%r11,%rdx,1),%r11d + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 64-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r9d,%esi + xorl %r13d,%r14d + leal (%rdx,%rsi,1),%edx + movl %eax,%r12d + addl 36+64(%rsp),%ecx + andl %r11d,%r12d + rorxl $25,%r11d,%r13d + rorxl $11,%r11d,%esi + leal (%rdx,%r14,1),%edx + leal (%rcx,%r12,1),%ecx + andnl %ebx,%r11d,%r12d + xorl %esi,%r13d + rorxl $6,%r11d,%r14d + leal (%rcx,%r12,1),%ecx + xorl %r14d,%r13d + movl %edx,%esi + rorxl $22,%edx,%r12d + leal (%rcx,%r13,1),%ecx + xorl %r8d,%esi + rorxl $13,%edx,%r14d + rorxl $2,%edx,%r13d + leal (%r10,%rcx,1),%r10d + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 80-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r8d,%r15d + xorl %r13d,%r14d + leal (%rcx,%r15,1),%ecx + movl %r11d,%r12d + addl 40+64(%rsp),%ebx + andl %r10d,%r12d + rorxl $25,%r10d,%r13d + rorxl $11,%r10d,%r15d + leal (%rcx,%r14,1),%ecx + leal (%rbx,%r12,1),%ebx + andnl %eax,%r10d,%r12d + xorl %r15d,%r13d + rorxl $6,%r10d,%r14d + leal (%rbx,%r12,1),%ebx + xorl %r14d,%r13d + movl %ecx,%r15d + rorxl $22,%ecx,%r12d + leal (%rbx,%r13,1),%ebx + xorl %edx,%r15d + rorxl $13,%ecx,%r14d + rorxl $2,%ecx,%r13d + leal (%r9,%rbx,1),%r9d + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 96-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %edx,%esi + xorl %r13d,%r14d + leal (%rbx,%rsi,1),%ebx + movl %r10d,%r12d + addl 44+64(%rsp),%eax + andl %r9d,%r12d + rorxl $25,%r9d,%r13d + rorxl $11,%r9d,%esi + leal (%rbx,%r14,1),%ebx + leal (%rax,%r12,1),%eax + andnl %r11d,%r9d,%r12d + xorl %esi,%r13d + rorxl $6,%r9d,%r14d + leal (%rax,%r12,1),%eax + xorl %r14d,%r13d + movl %ebx,%esi + rorxl $22,%ebx,%r12d + leal (%rax,%r13,1),%eax + xorl %ecx,%esi + rorxl $13,%ebx,%r14d + rorxl $2,%ebx,%r13d + leal (%r8,%rax,1),%r8d + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 112-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ecx,%r15d + xorl %r13d,%r14d + leal (%rax,%r15,1),%eax + movl %r9d,%r12d + addl 0(%rsp),%r11d + andl %r8d,%r12d + rorxl $25,%r8d,%r13d + rorxl $11,%r8d,%r15d + leal (%rax,%r14,1),%eax + leal (%r11,%r12,1),%r11d + andnl %r10d,%r8d,%r12d + xorl %r15d,%r13d + rorxl $6,%r8d,%r14d + leal (%r11,%r12,1),%r11d + xorl %r14d,%r13d + movl %eax,%r15d + rorxl $22,%eax,%r12d + leal (%r11,%r13,1),%r11d + xorl %ebx,%r15d + rorxl $13,%eax,%r14d + rorxl $2,%eax,%r13d + leal (%rdx,%r11,1),%edx + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 128-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ebx,%esi + xorl %r13d,%r14d + leal (%r11,%rsi,1),%r11d + movl %r8d,%r12d + addl 4(%rsp),%r10d + andl %edx,%r12d + rorxl $25,%edx,%r13d + rorxl $11,%edx,%esi + leal (%r11,%r14,1),%r11d + leal (%r10,%r12,1),%r10d + andnl %r9d,%edx,%r12d + xorl %esi,%r13d + rorxl $6,%edx,%r14d + leal (%r10,%r12,1),%r10d + xorl %r14d,%r13d + movl %r11d,%esi + rorxl $22,%r11d,%r12d + leal (%r10,%r13,1),%r10d + xorl %eax,%esi + rorxl $13,%r11d,%r14d + rorxl $2,%r11d,%r13d + leal (%rcx,%r10,1),%ecx + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 144-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %eax,%r15d + xorl %r13d,%r14d + leal (%r10,%r15,1),%r10d + movl %edx,%r12d + addl 8(%rsp),%r9d + andl %ecx,%r12d + rorxl $25,%ecx,%r13d + rorxl $11,%ecx,%r15d + leal (%r10,%r14,1),%r10d + leal (%r9,%r12,1),%r9d + andnl %r8d,%ecx,%r12d + xorl %r15d,%r13d + rorxl $6,%ecx,%r14d + leal (%r9,%r12,1),%r9d + xorl %r14d,%r13d + movl %r10d,%r15d + rorxl $22,%r10d,%r12d + leal (%r9,%r13,1),%r9d + xorl %r11d,%r15d + rorxl $13,%r10d,%r14d + rorxl $2,%r10d,%r13d + leal (%rbx,%r9,1),%ebx + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 160-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r11d,%esi + xorl %r13d,%r14d + leal (%r9,%rsi,1),%r9d + movl %ecx,%r12d + addl 12(%rsp),%r8d + andl %ebx,%r12d + rorxl $25,%ebx,%r13d + rorxl $11,%ebx,%esi + leal (%r9,%r14,1),%r9d + leal (%r8,%r12,1),%r8d + andnl %edx,%ebx,%r12d + xorl %esi,%r13d + rorxl $6,%ebx,%r14d + leal (%r8,%r12,1),%r8d + xorl %r14d,%r13d + movl %r9d,%esi + rorxl $22,%r9d,%r12d + leal (%r8,%r13,1),%r8d + xorl %r10d,%esi + rorxl $13,%r9d,%r14d + rorxl $2,%r9d,%r13d + leal (%rax,%r8,1),%eax + andl %esi,%r15d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 176-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r10d,%r15d + xorl %r13d,%r14d + leal (%r8,%r15,1),%r8d + movl %ebx,%r12d + addl 32(%rsp),%edx + andl %eax,%r12d + rorxl $25,%eax,%r13d + rorxl $11,%eax,%r15d + leal (%r8,%r14,1),%r8d + leal (%rdx,%r12,1),%edx + andnl %ecx,%eax,%r12d + xorl %r15d,%r13d + rorxl $6,%eax,%r14d + leal (%rdx,%r12,1),%edx + xorl %r14d,%r13d + movl %r8d,%r15d + rorxl $22,%r8d,%r12d + leal (%rdx,%r13,1),%edx + xorl %r9d,%r15d + rorxl $13,%r8d,%r14d + rorxl $2,%r8d,%r13d + leal (%r11,%rdx,1),%r11d + andl %r15d,%esi + vpand %xmm12,%xmm11,%xmm8 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 192-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r9d,%esi + xorl %r13d,%r14d + leal (%rdx,%rsi,1),%edx + movl %eax,%r12d + addl 36(%rsp),%ecx + andl %r11d,%r12d + rorxl $25,%r11d,%r13d + rorxl $11,%r11d,%esi + leal (%rdx,%r14,1),%edx + leal (%rcx,%r12,1),%ecx + andnl %ebx,%r11d,%r12d + xorl %esi,%r13d + rorxl $6,%r11d,%r14d + leal (%rcx,%r12,1),%ecx + xorl %r14d,%r13d + movl %edx,%esi + rorxl $22,%edx,%r12d + leal (%rcx,%r13,1),%ecx + xorl %r8d,%esi + rorxl $13,%edx,%r14d + rorxl $2,%edx,%r13d + leal (%r10,%rcx,1),%r10d + andl %esi,%r15d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 208-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r8d,%r15d + xorl %r13d,%r14d + leal (%rcx,%r15,1),%ecx + movl %r11d,%r12d + addl 40(%rsp),%ebx + andl %r10d,%r12d + rorxl $25,%r10d,%r13d + rorxl $11,%r10d,%r15d + leal (%rcx,%r14,1),%ecx + leal (%rbx,%r12,1),%ebx + andnl %eax,%r10d,%r12d + xorl %r15d,%r13d + rorxl $6,%r10d,%r14d + leal (%rbx,%r12,1),%ebx + xorl %r14d,%r13d + movl %ecx,%r15d + rorxl $22,%ecx,%r12d + leal (%rbx,%r13,1),%ebx + xorl %edx,%r15d + rorxl $13,%ecx,%r14d + rorxl $2,%ecx,%r13d + leal (%r9,%rbx,1),%r9d + andl %r15d,%esi + vpand %xmm13,%xmm11,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 224-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %edx,%esi + xorl %r13d,%r14d + leal (%rbx,%rsi,1),%ebx + movl %r10d,%r12d + addl 44(%rsp),%eax + andl %r9d,%r12d + rorxl $25,%r9d,%r13d + rorxl $11,%r9d,%esi + leal (%rbx,%r14,1),%ebx + leal (%rax,%r12,1),%eax + andnl %r11d,%r9d,%r12d + xorl %esi,%r13d + rorxl $6,%r9d,%r14d + leal (%rax,%r12,1),%eax + xorl %r14d,%r13d + movl %ebx,%esi + rorxl $22,%ebx,%r12d + leal (%rax,%r13,1),%eax + xorl %ecx,%esi + rorxl $13,%ebx,%r14d + rorxl $2,%ebx,%r13d + leal (%r8,%rax,1),%r8d + andl %esi,%r15d + vpor %xmm11,%xmm8,%xmm8 + vaesenclast %xmm10,%xmm9,%xmm11 + vmovdqu 0-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ecx,%r15d + xorl %r13d,%r14d + leal (%rax,%r15,1),%eax + movl %r9d,%r12d + vpextrq $1,%xmm15,%r12 + vmovq %xmm15,%r13 + movq 552(%rsp),%r15 + addl %r14d,%eax + leaq 448(%rsp),%rbp + + vpand %xmm14,%xmm11,%xmm11 + vpor %xmm11,%xmm8,%xmm8 + vmovdqu %xmm8,(%r12,%r13,1) + leaq 16(%r13),%r13 + + addl 0(%r15),%eax + addl 4(%r15),%ebx + addl 8(%r15),%ecx + addl 12(%r15),%edx + addl 16(%r15),%r8d + addl 20(%r15),%r9d + addl 24(%r15),%r10d + addl 28(%r15),%r11d + + movl %eax,0(%r15) + movl %ebx,4(%r15) + movl %ecx,8(%r15) + movl %edx,12(%r15) + movl %r8d,16(%r15) + movl %r9d,20(%r15) + movl %r10d,24(%r15) + movl %r11d,28(%r15) + + cmpq 80(%rbp),%r13 + je .Ldone_avx2 + + xorl %r14d,%r14d + movl %ebx,%esi + movl %r9d,%r12d + xorl %ecx,%esi + jmp .Lower_avx2 +.align 16 +.Lower_avx2: + vmovdqu (%r13),%xmm9 + vpinsrq $0,%r13,%xmm15,%xmm15 + addl 0+16(%rbp),%r11d + andl %r8d,%r12d + rorxl $25,%r8d,%r13d + rorxl $11,%r8d,%r15d + leal (%rax,%r14,1),%eax + leal (%r11,%r12,1),%r11d + andnl %r10d,%r8d,%r12d + xorl %r15d,%r13d + rorxl $6,%r8d,%r14d + leal (%r11,%r12,1),%r11d + xorl %r14d,%r13d + movl %eax,%r15d + rorxl $22,%eax,%r12d + leal (%r11,%r13,1),%r11d + xorl %ebx,%r15d + rorxl $13,%eax,%r14d + rorxl $2,%eax,%r13d + leal (%rdx,%r11,1),%edx + andl %r15d,%esi + vpxor %xmm10,%xmm9,%xmm9 + vmovdqu 16-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ebx,%esi + xorl %r13d,%r14d + leal (%r11,%rsi,1),%r11d + movl %r8d,%r12d + addl 4+16(%rbp),%r10d + andl %edx,%r12d + rorxl $25,%edx,%r13d + rorxl $11,%edx,%esi + leal (%r11,%r14,1),%r11d + leal (%r10,%r12,1),%r10d + andnl %r9d,%edx,%r12d + xorl %esi,%r13d + rorxl $6,%edx,%r14d + leal (%r10,%r12,1),%r10d + xorl %r14d,%r13d + movl %r11d,%esi + rorxl $22,%r11d,%r12d + leal (%r10,%r13,1),%r10d + xorl %eax,%esi + rorxl $13,%r11d,%r14d + rorxl $2,%r11d,%r13d + leal (%rcx,%r10,1),%ecx + andl %esi,%r15d + vpxor %xmm8,%xmm9,%xmm9 + xorl %r12d,%r14d + xorl %eax,%r15d + xorl %r13d,%r14d + leal (%r10,%r15,1),%r10d + movl %edx,%r12d + addl 8+16(%rbp),%r9d + andl %ecx,%r12d + rorxl $25,%ecx,%r13d + rorxl $11,%ecx,%r15d + leal (%r10,%r14,1),%r10d + leal (%r9,%r12,1),%r9d + andnl %r8d,%ecx,%r12d + xorl %r15d,%r13d + rorxl $6,%ecx,%r14d + leal (%r9,%r12,1),%r9d + xorl %r14d,%r13d + movl %r10d,%r15d + rorxl $22,%r10d,%r12d + leal (%r9,%r13,1),%r9d + xorl %r11d,%r15d + rorxl $13,%r10d,%r14d + rorxl $2,%r10d,%r13d + leal (%rbx,%r9,1),%ebx + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 32-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r11d,%esi + xorl %r13d,%r14d + leal (%r9,%rsi,1),%r9d + movl %ecx,%r12d + addl 12+16(%rbp),%r8d + andl %ebx,%r12d + rorxl $25,%ebx,%r13d + rorxl $11,%ebx,%esi + leal (%r9,%r14,1),%r9d + leal (%r8,%r12,1),%r8d + andnl %edx,%ebx,%r12d + xorl %esi,%r13d + rorxl $6,%ebx,%r14d + leal (%r8,%r12,1),%r8d + xorl %r14d,%r13d + movl %r9d,%esi + rorxl $22,%r9d,%r12d + leal (%r8,%r13,1),%r8d + xorl %r10d,%esi + rorxl $13,%r9d,%r14d + rorxl $2,%r9d,%r13d + leal (%rax,%r8,1),%eax + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 48-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r10d,%r15d + xorl %r13d,%r14d + leal (%r8,%r15,1),%r8d + movl %ebx,%r12d + addl 32+16(%rbp),%edx + andl %eax,%r12d + rorxl $25,%eax,%r13d + rorxl $11,%eax,%r15d + leal (%r8,%r14,1),%r8d + leal (%rdx,%r12,1),%edx + andnl %ecx,%eax,%r12d + xorl %r15d,%r13d + rorxl $6,%eax,%r14d + leal (%rdx,%r12,1),%edx + xorl %r14d,%r13d + movl %r8d,%r15d + rorxl $22,%r8d,%r12d + leal (%rdx,%r13,1),%edx + xorl %r9d,%r15d + rorxl $13,%r8d,%r14d + rorxl $2,%r8d,%r13d + leal (%r11,%rdx,1),%r11d + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 64-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r9d,%esi + xorl %r13d,%r14d + leal (%rdx,%rsi,1),%edx + movl %eax,%r12d + addl 36+16(%rbp),%ecx + andl %r11d,%r12d + rorxl $25,%r11d,%r13d + rorxl $11,%r11d,%esi + leal (%rdx,%r14,1),%edx + leal (%rcx,%r12,1),%ecx + andnl %ebx,%r11d,%r12d + xorl %esi,%r13d + rorxl $6,%r11d,%r14d + leal (%rcx,%r12,1),%ecx + xorl %r14d,%r13d + movl %edx,%esi + rorxl $22,%edx,%r12d + leal (%rcx,%r13,1),%ecx + xorl %r8d,%esi + rorxl $13,%edx,%r14d + rorxl $2,%edx,%r13d + leal (%r10,%rcx,1),%r10d + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 80-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r8d,%r15d + xorl %r13d,%r14d + leal (%rcx,%r15,1),%ecx + movl %r11d,%r12d + addl 40+16(%rbp),%ebx + andl %r10d,%r12d + rorxl $25,%r10d,%r13d + rorxl $11,%r10d,%r15d + leal (%rcx,%r14,1),%ecx + leal (%rbx,%r12,1),%ebx + andnl %eax,%r10d,%r12d + xorl %r15d,%r13d + rorxl $6,%r10d,%r14d + leal (%rbx,%r12,1),%ebx + xorl %r14d,%r13d + movl %ecx,%r15d + rorxl $22,%ecx,%r12d + leal (%rbx,%r13,1),%ebx + xorl %edx,%r15d + rorxl $13,%ecx,%r14d + rorxl $2,%ecx,%r13d + leal (%r9,%rbx,1),%r9d + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 96-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %edx,%esi + xorl %r13d,%r14d + leal (%rbx,%rsi,1),%ebx + movl %r10d,%r12d + addl 44+16(%rbp),%eax + andl %r9d,%r12d + rorxl $25,%r9d,%r13d + rorxl $11,%r9d,%esi + leal (%rbx,%r14,1),%ebx + leal (%rax,%r12,1),%eax + andnl %r11d,%r9d,%r12d + xorl %esi,%r13d + rorxl $6,%r9d,%r14d + leal (%rax,%r12,1),%eax + xorl %r14d,%r13d + movl %ebx,%esi + rorxl $22,%ebx,%r12d + leal (%rax,%r13,1),%eax + xorl %ecx,%esi + rorxl $13,%ebx,%r14d + rorxl $2,%ebx,%r13d + leal (%r8,%rax,1),%r8d + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 112-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ecx,%r15d + xorl %r13d,%r14d + leal (%rax,%r15,1),%eax + movl %r9d,%r12d + leaq -64(%rbp),%rbp + addl 0+16(%rbp),%r11d + andl %r8d,%r12d + rorxl $25,%r8d,%r13d + rorxl $11,%r8d,%r15d + leal (%rax,%r14,1),%eax + leal (%r11,%r12,1),%r11d + andnl %r10d,%r8d,%r12d + xorl %r15d,%r13d + rorxl $6,%r8d,%r14d + leal (%r11,%r12,1),%r11d + xorl %r14d,%r13d + movl %eax,%r15d + rorxl $22,%eax,%r12d + leal (%r11,%r13,1),%r11d + xorl %ebx,%r15d + rorxl $13,%eax,%r14d + rorxl $2,%eax,%r13d + leal (%rdx,%r11,1),%edx + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 128-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ebx,%esi + xorl %r13d,%r14d + leal (%r11,%rsi,1),%r11d + movl %r8d,%r12d + addl 4+16(%rbp),%r10d + andl %edx,%r12d + rorxl $25,%edx,%r13d + rorxl $11,%edx,%esi + leal (%r11,%r14,1),%r11d + leal (%r10,%r12,1),%r10d + andnl %r9d,%edx,%r12d + xorl %esi,%r13d + rorxl $6,%edx,%r14d + leal (%r10,%r12,1),%r10d + xorl %r14d,%r13d + movl %r11d,%esi + rorxl $22,%r11d,%r12d + leal (%r10,%r13,1),%r10d + xorl %eax,%esi + rorxl $13,%r11d,%r14d + rorxl $2,%r11d,%r13d + leal (%rcx,%r10,1),%ecx + andl %esi,%r15d + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 144-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %eax,%r15d + xorl %r13d,%r14d + leal (%r10,%r15,1),%r10d + movl %edx,%r12d + addl 8+16(%rbp),%r9d + andl %ecx,%r12d + rorxl $25,%ecx,%r13d + rorxl $11,%ecx,%r15d + leal (%r10,%r14,1),%r10d + leal (%r9,%r12,1),%r9d + andnl %r8d,%ecx,%r12d + xorl %r15d,%r13d + rorxl $6,%ecx,%r14d + leal (%r9,%r12,1),%r9d + xorl %r14d,%r13d + movl %r10d,%r15d + rorxl $22,%r10d,%r12d + leal (%r9,%r13,1),%r9d + xorl %r11d,%r15d + rorxl $13,%r10d,%r14d + rorxl $2,%r10d,%r13d + leal (%rbx,%r9,1),%ebx + andl %r15d,%esi + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 160-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r11d,%esi + xorl %r13d,%r14d + leal (%r9,%rsi,1),%r9d + movl %ecx,%r12d + addl 12+16(%rbp),%r8d + andl %ebx,%r12d + rorxl $25,%ebx,%r13d + rorxl $11,%ebx,%esi + leal (%r9,%r14,1),%r9d + leal (%r8,%r12,1),%r8d + andnl %edx,%ebx,%r12d + xorl %esi,%r13d + rorxl $6,%ebx,%r14d + leal (%r8,%r12,1),%r8d + xorl %r14d,%r13d + movl %r9d,%esi + rorxl $22,%r9d,%r12d + leal (%r8,%r13,1),%r8d + xorl %r10d,%esi + rorxl $13,%r9d,%r14d + rorxl $2,%r9d,%r13d + leal (%rax,%r8,1),%eax + andl %esi,%r15d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 176-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r10d,%r15d + xorl %r13d,%r14d + leal (%r8,%r15,1),%r8d + movl %ebx,%r12d + addl 32+16(%rbp),%edx + andl %eax,%r12d + rorxl $25,%eax,%r13d + rorxl $11,%eax,%r15d + leal (%r8,%r14,1),%r8d + leal (%rdx,%r12,1),%edx + andnl %ecx,%eax,%r12d + xorl %r15d,%r13d + rorxl $6,%eax,%r14d + leal (%rdx,%r12,1),%edx + xorl %r14d,%r13d + movl %r8d,%r15d + rorxl $22,%r8d,%r12d + leal (%rdx,%r13,1),%edx + xorl %r9d,%r15d + rorxl $13,%r8d,%r14d + rorxl $2,%r8d,%r13d + leal (%r11,%rdx,1),%r11d + andl %r15d,%esi + vpand %xmm12,%xmm11,%xmm8 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 192-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r9d,%esi + xorl %r13d,%r14d + leal (%rdx,%rsi,1),%edx + movl %eax,%r12d + addl 36+16(%rbp),%ecx + andl %r11d,%r12d + rorxl $25,%r11d,%r13d + rorxl $11,%r11d,%esi + leal (%rdx,%r14,1),%edx + leal (%rcx,%r12,1),%ecx + andnl %ebx,%r11d,%r12d + xorl %esi,%r13d + rorxl $6,%r11d,%r14d + leal (%rcx,%r12,1),%ecx + xorl %r14d,%r13d + movl %edx,%esi + rorxl $22,%edx,%r12d + leal (%rcx,%r13,1),%ecx + xorl %r8d,%esi + rorxl $13,%edx,%r14d + rorxl $2,%edx,%r13d + leal (%r10,%rcx,1),%r10d + andl %esi,%r15d + vaesenclast %xmm10,%xmm9,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 208-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %r8d,%r15d + xorl %r13d,%r14d + leal (%rcx,%r15,1),%ecx + movl %r11d,%r12d + addl 40+16(%rbp),%ebx + andl %r10d,%r12d + rorxl $25,%r10d,%r13d + rorxl $11,%r10d,%r15d + leal (%rcx,%r14,1),%ecx + leal (%rbx,%r12,1),%ebx + andnl %eax,%r10d,%r12d + xorl %r15d,%r13d + rorxl $6,%r10d,%r14d + leal (%rbx,%r12,1),%ebx + xorl %r14d,%r13d + movl %ecx,%r15d + rorxl $22,%ecx,%r12d + leal (%rbx,%r13,1),%ebx + xorl %edx,%r15d + rorxl $13,%ecx,%r14d + rorxl $2,%ecx,%r13d + leal (%r9,%rbx,1),%r9d + andl %r15d,%esi + vpand %xmm13,%xmm11,%xmm11 + vaesenc %xmm10,%xmm9,%xmm9 + vmovdqu 224-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %edx,%esi + xorl %r13d,%r14d + leal (%rbx,%rsi,1),%ebx + movl %r10d,%r12d + addl 44+16(%rbp),%eax + andl %r9d,%r12d + rorxl $25,%r9d,%r13d + rorxl $11,%r9d,%esi + leal (%rbx,%r14,1),%ebx + leal (%rax,%r12,1),%eax + andnl %r11d,%r9d,%r12d + xorl %esi,%r13d + rorxl $6,%r9d,%r14d + leal (%rax,%r12,1),%eax + xorl %r14d,%r13d + movl %ebx,%esi + rorxl $22,%ebx,%r12d + leal (%rax,%r13,1),%eax + xorl %ecx,%esi + rorxl $13,%ebx,%r14d + rorxl $2,%ebx,%r13d + leal (%r8,%rax,1),%r8d + andl %esi,%r15d + vpor %xmm11,%xmm8,%xmm8 + vaesenclast %xmm10,%xmm9,%xmm11 + vmovdqu 0-128(%rdi),%xmm10 + xorl %r12d,%r14d + xorl %ecx,%r15d + xorl %r13d,%r14d + leal (%rax,%r15,1),%eax + movl %r9d,%r12d + vmovq %xmm15,%r13 + vpextrq $1,%xmm15,%r15 + vpand %xmm14,%xmm11,%xmm11 + vpor %xmm11,%xmm8,%xmm8 + leaq -64(%rbp),%rbp + vmovdqu %xmm8,(%r15,%r13,1) + leaq 16(%r13),%r13 + cmpq %rsp,%rbp + jae .Lower_avx2 + + movq 552(%rsp),%r15 + leaq 64(%r13),%r13 + movq 560(%rsp),%rsi + addl %r14d,%eax + leaq 448(%rsp),%rsp + + addl 0(%r15),%eax + addl 4(%r15),%ebx + addl 8(%r15),%ecx + addl 12(%r15),%edx + addl 16(%r15),%r8d + addl 20(%r15),%r9d + addl 24(%r15),%r10d + leaq (%rsi,%r13,1),%r12 + addl 28(%r15),%r11d + + cmpq 64+16(%rsp),%r13 + + movl %eax,0(%r15) + cmoveq %rsp,%r12 + movl %ebx,4(%r15) + movl %ecx,8(%r15) + movl %edx,12(%r15) + movl %r8d,16(%r15) + movl %r9d,20(%r15) + movl %r10d,24(%r15) + movl %r11d,28(%r15) + + jbe .Loop_avx2 + leaq (%rsp),%rbp + + +.cfi_escape 0x0f,0x06,0x76,0xf8,0x00,0x06,0x23,0x08 + +.Ldone_avx2: + movq 64+32(%rbp),%r8 + movq 64+56(%rbp),%rsi +.cfi_def_cfa %rsi,8 + vmovdqu %xmm8,(%r8) + vzeroall + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx2: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_cbc_sha256_enc_avx2,.-aesni_cbc_sha256_enc_avx2 +.type aesni_cbc_sha256_enc_shaext,@function +.align 32 +aesni_cbc_sha256_enc_shaext: +.cfi_startproc + movq 8(%rsp),%r10 + leaq K256+128(%rip),%rax + movdqu (%r9),%xmm1 + movdqu 16(%r9),%xmm2 + movdqa 512-128(%rax),%xmm3 + + movl 240(%rcx),%r11d + subq %rdi,%rsi + movups (%rcx),%xmm15 + movups (%r8),%xmm6 + movups 16(%rcx),%xmm4 + leaq 112(%rcx),%rcx + + pshufd $0x1b,%xmm1,%xmm0 + pshufd $0xb1,%xmm1,%xmm1 + pshufd $0x1b,%xmm2,%xmm2 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,202,8 + punpcklqdq %xmm0,%xmm2 + + jmp .Loop_shaext + +.align 16 +.Loop_shaext: + movdqu (%r10),%xmm10 + movdqu 16(%r10),%xmm11 + movdqu 32(%r10),%xmm12 +.byte 102,68,15,56,0,211 + movdqu 48(%r10),%xmm13 + + movdqa 0-128(%rax),%xmm0 + paddd %xmm10,%xmm0 +.byte 102,68,15,56,0,219 + movdqa %xmm2,%xmm9 + movdqa %xmm1,%xmm8 + movups 0(%rdi),%xmm14 + xorps %xmm15,%xmm14 + xorps %xmm14,%xmm6 + movups -80(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movups -64(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,202 + + movdqa 32-128(%rax),%xmm0 + paddd %xmm11,%xmm0 +.byte 102,68,15,56,0,227 + leaq 64(%r10),%r10 + movups -48(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movups -32(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,202 + + movdqa 64-128(%rax),%xmm0 + paddd %xmm12,%xmm0 +.byte 102,68,15,56,0,235 +.byte 69,15,56,204,211 + movups -16(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm13,%xmm3 +.byte 102,65,15,58,15,220,4 + paddd %xmm3,%xmm10 + movups 0(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,202 + + movdqa 96-128(%rax),%xmm0 + paddd %xmm13,%xmm0 +.byte 69,15,56,205,213 +.byte 69,15,56,204,220 + movups 16(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movups 32(%rcx),%xmm4 + aesenc %xmm5,%xmm6 + movdqa %xmm10,%xmm3 +.byte 102,65,15,58,15,221,4 + paddd %xmm3,%xmm11 +.byte 15,56,203,202 + movdqa 128-128(%rax),%xmm0 + paddd %xmm10,%xmm0 +.byte 69,15,56,205,218 +.byte 69,15,56,204,229 + movups 48(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm11,%xmm3 +.byte 102,65,15,58,15,218,4 + paddd %xmm3,%xmm12 + cmpl $11,%r11d + jb .Laesenclast1 + movups 64(%rcx),%xmm4 + aesenc %xmm5,%xmm6 + movups 80(%rcx),%xmm5 + aesenc %xmm4,%xmm6 + je .Laesenclast1 + movups 96(%rcx),%xmm4 + aesenc %xmm5,%xmm6 + movups 112(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.Laesenclast1: + aesenclast %xmm5,%xmm6 + movups 16-112(%rcx),%xmm4 + nop +.byte 15,56,203,202 + movups 16(%rdi),%xmm14 + xorps %xmm15,%xmm14 + movups %xmm6,0(%rsi,%rdi,1) + xorps %xmm14,%xmm6 + movups -80(%rcx),%xmm5 + aesenc %xmm4,%xmm6 + movdqa 160-128(%rax),%xmm0 + paddd %xmm11,%xmm0 +.byte 69,15,56,205,227 +.byte 69,15,56,204,234 + movups -64(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm12,%xmm3 +.byte 102,65,15,58,15,219,4 + paddd %xmm3,%xmm13 + movups -48(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,202 + movdqa 192-128(%rax),%xmm0 + paddd %xmm12,%xmm0 +.byte 69,15,56,205,236 +.byte 69,15,56,204,211 + movups -32(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm13,%xmm3 +.byte 102,65,15,58,15,220,4 + paddd %xmm3,%xmm10 + movups -16(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,202 + movdqa 224-128(%rax),%xmm0 + paddd %xmm13,%xmm0 +.byte 69,15,56,205,213 +.byte 69,15,56,204,220 + movups 0(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm10,%xmm3 +.byte 102,65,15,58,15,221,4 + paddd %xmm3,%xmm11 + movups 16(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,202 + movdqa 256-128(%rax),%xmm0 + paddd %xmm10,%xmm0 +.byte 69,15,56,205,218 +.byte 69,15,56,204,229 + movups 32(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm11,%xmm3 +.byte 102,65,15,58,15,218,4 + paddd %xmm3,%xmm12 + movups 48(%rcx),%xmm5 + aesenc %xmm4,%xmm6 + cmpl $11,%r11d + jb .Laesenclast2 + movups 64(%rcx),%xmm4 + aesenc %xmm5,%xmm6 + movups 80(%rcx),%xmm5 + aesenc %xmm4,%xmm6 + je .Laesenclast2 + movups 96(%rcx),%xmm4 + aesenc %xmm5,%xmm6 + movups 112(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.Laesenclast2: + aesenclast %xmm5,%xmm6 + movups 16-112(%rcx),%xmm4 + nop +.byte 15,56,203,202 + movups 32(%rdi),%xmm14 + xorps %xmm15,%xmm14 + movups %xmm6,16(%rsi,%rdi,1) + xorps %xmm14,%xmm6 + movups -80(%rcx),%xmm5 + aesenc %xmm4,%xmm6 + movdqa 288-128(%rax),%xmm0 + paddd %xmm11,%xmm0 +.byte 69,15,56,205,227 +.byte 69,15,56,204,234 + movups -64(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm12,%xmm3 +.byte 102,65,15,58,15,219,4 + paddd %xmm3,%xmm13 + movups -48(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,202 + movdqa 320-128(%rax),%xmm0 + paddd %xmm12,%xmm0 +.byte 69,15,56,205,236 +.byte 69,15,56,204,211 + movups -32(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm13,%xmm3 +.byte 102,65,15,58,15,220,4 + paddd %xmm3,%xmm10 + movups -16(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,202 + movdqa 352-128(%rax),%xmm0 + paddd %xmm13,%xmm0 +.byte 69,15,56,205,213 +.byte 69,15,56,204,220 + movups 0(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm10,%xmm3 +.byte 102,65,15,58,15,221,4 + paddd %xmm3,%xmm11 + movups 16(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,202 + movdqa 384-128(%rax),%xmm0 + paddd %xmm10,%xmm0 +.byte 69,15,56,205,218 +.byte 69,15,56,204,229 + movups 32(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm11,%xmm3 +.byte 102,65,15,58,15,218,4 + paddd %xmm3,%xmm12 + movups 48(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,202 + movdqa 416-128(%rax),%xmm0 + paddd %xmm11,%xmm0 +.byte 69,15,56,205,227 +.byte 69,15,56,204,234 + cmpl $11,%r11d + jb .Laesenclast3 + movups 64(%rcx),%xmm4 + aesenc %xmm5,%xmm6 + movups 80(%rcx),%xmm5 + aesenc %xmm4,%xmm6 + je .Laesenclast3 + movups 96(%rcx),%xmm4 + aesenc %xmm5,%xmm6 + movups 112(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.Laesenclast3: + aesenclast %xmm5,%xmm6 + movups 16-112(%rcx),%xmm4 + nop +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm12,%xmm3 +.byte 102,65,15,58,15,219,4 + paddd %xmm3,%xmm13 + movups 48(%rdi),%xmm14 + xorps %xmm15,%xmm14 + movups %xmm6,32(%rsi,%rdi,1) + xorps %xmm14,%xmm6 + movups -80(%rcx),%xmm5 + aesenc %xmm4,%xmm6 + movups -64(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,202 + + movdqa 448-128(%rax),%xmm0 + paddd %xmm12,%xmm0 +.byte 69,15,56,205,236 + movdqa %xmm7,%xmm3 + movups -48(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movups -32(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,202 + + movdqa 480-128(%rax),%xmm0 + paddd %xmm13,%xmm0 + movups -16(%rcx),%xmm5 + aesenc %xmm4,%xmm6 + movups 0(%rcx),%xmm4 + aesenc %xmm5,%xmm6 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movups 16(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.byte 15,56,203,202 + + movups 32(%rcx),%xmm4 + aesenc %xmm5,%xmm6 + movups 48(%rcx),%xmm5 + aesenc %xmm4,%xmm6 + cmpl $11,%r11d + jb .Laesenclast4 + movups 64(%rcx),%xmm4 + aesenc %xmm5,%xmm6 + movups 80(%rcx),%xmm5 + aesenc %xmm4,%xmm6 + je .Laesenclast4 + movups 96(%rcx),%xmm4 + aesenc %xmm5,%xmm6 + movups 112(%rcx),%xmm5 + aesenc %xmm4,%xmm6 +.Laesenclast4: + aesenclast %xmm5,%xmm6 + movups 16-112(%rcx),%xmm4 + nop + + paddd %xmm9,%xmm2 + paddd %xmm8,%xmm1 + + decq %rdx + movups %xmm6,48(%rsi,%rdi,1) + leaq 64(%rdi),%rdi + jnz .Loop_shaext + + pshufd $0xb1,%xmm2,%xmm2 + pshufd $0x1b,%xmm1,%xmm3 + pshufd $0xb1,%xmm1,%xmm1 + punpckhqdq %xmm2,%xmm1 +.byte 102,15,58,15,211,8 + + movups %xmm6,(%r8) + movdqu %xmm1,(%r9) + movdqu %xmm2,16(%r9) + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_cbc_sha256_enc_shaext,.-aesni_cbc_sha256_enc_shaext + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/aes/aesni-x86.S b/crypto/openssl/crypto/aes/aesni-x86.S new file mode 100644 index 000000000000..eb2d01b16630 --- /dev/null +++ b/crypto/openssl/crypto/aes/aesni-x86.S @@ -0,0 +1,3364 @@ +.text +.globl aesni_encrypt +.type aesni_encrypt,@function +.align 16 +aesni_encrypt: +.L_aesni_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl 4(%esp),%eax + movl 12(%esp),%edx + movups (%eax),%xmm2 + movl 240(%edx),%ecx + movl 8(%esp),%eax + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L000enc1_loop_1: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L000enc1_loop_1 +.byte 102,15,56,221,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%eax) + pxor %xmm2,%xmm2 + ret +.size aesni_encrypt,.-.L_aesni_encrypt_begin +.globl aesni_decrypt +.type aesni_decrypt,@function +.align 16 +aesni_decrypt: +.L_aesni_decrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl 4(%esp),%eax + movl 12(%esp),%edx + movups (%eax),%xmm2 + movl 240(%edx),%ecx + movl 8(%esp),%eax + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L001dec1_loop_2: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L001dec1_loop_2 +.byte 102,15,56,223,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%eax) + pxor %xmm2,%xmm2 + ret +.size aesni_decrypt,.-.L_aesni_decrypt_begin +.type _aesni_encrypt2,@function +.align 16 +_aesni_encrypt2: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx + addl $16,%ecx +.L002enc2_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L002enc2_loop +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 + ret +.size _aesni_encrypt2,.-_aesni_encrypt2 +.type _aesni_decrypt2,@function +.align 16 +_aesni_decrypt2: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx + addl $16,%ecx +.L003dec2_loop: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L003dec2_loop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 + ret +.size _aesni_decrypt2,.-_aesni_decrypt2 +.type _aesni_encrypt3,@function +.align 16 +_aesni_encrypt3: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx + addl $16,%ecx +.L004enc3_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L004enc3_loop +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 + ret +.size _aesni_encrypt3,.-_aesni_encrypt3 +.type _aesni_decrypt3,@function +.align 16 +_aesni_decrypt3: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx + addl $16,%ecx +.L005dec3_loop: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L005dec3_loop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 + ret +.size _aesni_decrypt3,.-_aesni_decrypt3 +.type _aesni_encrypt4,@function +.align 16 +_aesni_encrypt4: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + shll $4,%ecx + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx +.byte 15,31,64,0 + addl $16,%ecx +.L006enc4_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L006enc4_loop +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 + ret +.size _aesni_encrypt4,.-_aesni_encrypt4 +.type _aesni_decrypt4,@function +.align 16 +_aesni_decrypt4: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + shll $4,%ecx + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + movups 32(%edx),%xmm0 + leal 32(%edx,%ecx,1),%edx + negl %ecx +.byte 15,31,64,0 + addl $16,%ecx +.L007dec4_loop: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L007dec4_loop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 + ret +.size _aesni_decrypt4,.-_aesni_decrypt4 +.type _aesni_encrypt6,@function +.align 16 +_aesni_encrypt6: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 +.byte 102,15,56,220,209 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 +.byte 102,15,56,220,217 + leal 32(%edx,%ecx,1),%edx + negl %ecx +.byte 102,15,56,220,225 + pxor %xmm0,%xmm7 + movups (%edx,%ecx,1),%xmm0 + addl $16,%ecx + jmp .L008_aesni_encrypt6_inner +.align 16 +.L009enc6_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.L008_aesni_encrypt6_inner: +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.L_aesni_encrypt6_enter: + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L009enc6_loop +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 +.byte 102,15,56,221,240 +.byte 102,15,56,221,248 + ret +.size _aesni_encrypt6,.-_aesni_encrypt6 +.type _aesni_decrypt6,@function +.align 16 +_aesni_decrypt6: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movups (%edx),%xmm0 + shll $4,%ecx + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 +.byte 102,15,56,222,209 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 +.byte 102,15,56,222,217 + leal 32(%edx,%ecx,1),%edx + negl %ecx +.byte 102,15,56,222,225 + pxor %xmm0,%xmm7 + movups (%edx,%ecx,1),%xmm0 + addl $16,%ecx + jmp .L010_aesni_decrypt6_inner +.align 16 +.L011dec6_loop: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.L010_aesni_decrypt6_inner: +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.L_aesni_decrypt6_enter: + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L011dec6_loop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 +.byte 102,15,56,223,240 +.byte 102,15,56,223,248 + ret +.size _aesni_decrypt6,.-_aesni_decrypt6 +.globl aesni_ecb_encrypt +.type aesni_ecb_encrypt,@function +.align 16 +aesni_ecb_encrypt: +.L_aesni_ecb_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl 36(%esp),%ebx + andl $-16,%eax + jz .L012ecb_ret + movl 240(%edx),%ecx + testl %ebx,%ebx + jz .L013ecb_decrypt + movl %edx,%ebp + movl %ecx,%ebx + cmpl $96,%eax + jb .L014ecb_enc_tail + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movdqu 64(%esi),%xmm6 + movdqu 80(%esi),%xmm7 + leal 96(%esi),%esi + subl $96,%eax + jmp .L015ecb_enc_loop6_enter +.align 16 +.L016ecb_enc_loop6: + movups %xmm2,(%edi) + movdqu (%esi),%xmm2 + movups %xmm3,16(%edi) + movdqu 16(%esi),%xmm3 + movups %xmm4,32(%edi) + movdqu 32(%esi),%xmm4 + movups %xmm5,48(%edi) + movdqu 48(%esi),%xmm5 + movups %xmm6,64(%edi) + movdqu 64(%esi),%xmm6 + movups %xmm7,80(%edi) + leal 96(%edi),%edi + movdqu 80(%esi),%xmm7 + leal 96(%esi),%esi +.L015ecb_enc_loop6_enter: + call _aesni_encrypt6 + movl %ebp,%edx + movl %ebx,%ecx + subl $96,%eax + jnc .L016ecb_enc_loop6 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + movups %xmm7,80(%edi) + leal 96(%edi),%edi + addl $96,%eax + jz .L012ecb_ret +.L014ecb_enc_tail: + movups (%esi),%xmm2 + cmpl $32,%eax + jb .L017ecb_enc_one + movups 16(%esi),%xmm3 + je .L018ecb_enc_two + movups 32(%esi),%xmm4 + cmpl $64,%eax + jb .L019ecb_enc_three + movups 48(%esi),%xmm5 + je .L020ecb_enc_four + movups 64(%esi),%xmm6 + xorps %xmm7,%xmm7 + call _aesni_encrypt6 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + jmp .L012ecb_ret +.align 16 +.L017ecb_enc_one: + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L021enc1_loop_3: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L021enc1_loop_3 +.byte 102,15,56,221,209 + movups %xmm2,(%edi) + jmp .L012ecb_ret +.align 16 +.L018ecb_enc_two: + call _aesni_encrypt2 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + jmp .L012ecb_ret +.align 16 +.L019ecb_enc_three: + call _aesni_encrypt3 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + jmp .L012ecb_ret +.align 16 +.L020ecb_enc_four: + call _aesni_encrypt4 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + jmp .L012ecb_ret +.align 16 +.L013ecb_decrypt: + movl %edx,%ebp + movl %ecx,%ebx + cmpl $96,%eax + jb .L022ecb_dec_tail + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movdqu 64(%esi),%xmm6 + movdqu 80(%esi),%xmm7 + leal 96(%esi),%esi + subl $96,%eax + jmp .L023ecb_dec_loop6_enter +.align 16 +.L024ecb_dec_loop6: + movups %xmm2,(%edi) + movdqu (%esi),%xmm2 + movups %xmm3,16(%edi) + movdqu 16(%esi),%xmm3 + movups %xmm4,32(%edi) + movdqu 32(%esi),%xmm4 + movups %xmm5,48(%edi) + movdqu 48(%esi),%xmm5 + movups %xmm6,64(%edi) + movdqu 64(%esi),%xmm6 + movups %xmm7,80(%edi) + leal 96(%edi),%edi + movdqu 80(%esi),%xmm7 + leal 96(%esi),%esi +.L023ecb_dec_loop6_enter: + call _aesni_decrypt6 + movl %ebp,%edx + movl %ebx,%ecx + subl $96,%eax + jnc .L024ecb_dec_loop6 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + movups %xmm7,80(%edi) + leal 96(%edi),%edi + addl $96,%eax + jz .L012ecb_ret +.L022ecb_dec_tail: + movups (%esi),%xmm2 + cmpl $32,%eax + jb .L025ecb_dec_one + movups 16(%esi),%xmm3 + je .L026ecb_dec_two + movups 32(%esi),%xmm4 + cmpl $64,%eax + jb .L027ecb_dec_three + movups 48(%esi),%xmm5 + je .L028ecb_dec_four + movups 64(%esi),%xmm6 + xorps %xmm7,%xmm7 + call _aesni_decrypt6 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + jmp .L012ecb_ret +.align 16 +.L025ecb_dec_one: + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L029dec1_loop_4: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L029dec1_loop_4 +.byte 102,15,56,223,209 + movups %xmm2,(%edi) + jmp .L012ecb_ret +.align 16 +.L026ecb_dec_two: + call _aesni_decrypt2 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + jmp .L012ecb_ret +.align 16 +.L027ecb_dec_three: + call _aesni_decrypt3 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + jmp .L012ecb_ret +.align 16 +.L028ecb_dec_four: + call _aesni_decrypt4 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) +.L012ecb_ret: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aesni_ecb_encrypt,.-.L_aesni_ecb_encrypt_begin +.globl aesni_ccm64_encrypt_blocks +.type aesni_ccm64_encrypt_blocks,@function +.align 16 +aesni_ccm64_encrypt_blocks: +.L_aesni_ccm64_encrypt_blocks_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl 36(%esp),%ebx + movl 40(%esp),%ecx + movl %esp,%ebp + subl $60,%esp + andl $-16,%esp + movl %ebp,48(%esp) + movdqu (%ebx),%xmm7 + movdqu (%ecx),%xmm3 + movl 240(%edx),%ecx + movl $202182159,(%esp) + movl $134810123,4(%esp) + movl $67438087,8(%esp) + movl $66051,12(%esp) + movl $1,%ebx + xorl %ebp,%ebp + movl %ebx,16(%esp) + movl %ebp,20(%esp) + movl %ebp,24(%esp) + movl %ebp,28(%esp) + shll $4,%ecx + movl $16,%ebx + leal (%edx),%ebp + movdqa (%esp),%xmm5 + movdqa %xmm7,%xmm2 + leal 32(%edx,%ecx,1),%edx + subl %ecx,%ebx +.byte 102,15,56,0,253 +.L030ccm64_enc_outer: + movups (%ebp),%xmm0 + movl %ebx,%ecx + movups (%esi),%xmm6 + xorps %xmm0,%xmm2 + movups 16(%ebp),%xmm1 + xorps %xmm6,%xmm0 + xorps %xmm0,%xmm3 + movups 32(%ebp),%xmm0 +.L031ccm64_enc2_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L031ccm64_enc2_loop +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + paddq 16(%esp),%xmm7 + decl %eax +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 + leal 16(%esi),%esi + xorps %xmm2,%xmm6 + movdqa %xmm7,%xmm2 + movups %xmm6,(%edi) +.byte 102,15,56,0,213 + leal 16(%edi),%edi + jnz .L030ccm64_enc_outer + movl 48(%esp),%esp + movl 40(%esp),%edi + movups %xmm3,(%edi) + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aesni_ccm64_encrypt_blocks,.-.L_aesni_ccm64_encrypt_blocks_begin +.globl aesni_ccm64_decrypt_blocks +.type aesni_ccm64_decrypt_blocks,@function +.align 16 +aesni_ccm64_decrypt_blocks: +.L_aesni_ccm64_decrypt_blocks_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl 36(%esp),%ebx + movl 40(%esp),%ecx + movl %esp,%ebp + subl $60,%esp + andl $-16,%esp + movl %ebp,48(%esp) + movdqu (%ebx),%xmm7 + movdqu (%ecx),%xmm3 + movl 240(%edx),%ecx + movl $202182159,(%esp) + movl $134810123,4(%esp) + movl $67438087,8(%esp) + movl $66051,12(%esp) + movl $1,%ebx + xorl %ebp,%ebp + movl %ebx,16(%esp) + movl %ebp,20(%esp) + movl %ebp,24(%esp) + movl %ebp,28(%esp) + movdqa (%esp),%xmm5 + movdqa %xmm7,%xmm2 + movl %edx,%ebp + movl %ecx,%ebx +.byte 102,15,56,0,253 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L032enc1_loop_5: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L032enc1_loop_5 +.byte 102,15,56,221,209 + shll $4,%ebx + movl $16,%ecx + movups (%esi),%xmm6 + paddq 16(%esp),%xmm7 + leal 16(%esi),%esi + subl %ebx,%ecx + leal 32(%ebp,%ebx,1),%edx + movl %ecx,%ebx + jmp .L033ccm64_dec_outer +.align 16 +.L033ccm64_dec_outer: + xorps %xmm2,%xmm6 + movdqa %xmm7,%xmm2 + movups %xmm6,(%edi) + leal 16(%edi),%edi +.byte 102,15,56,0,213 + subl $1,%eax + jz .L034ccm64_dec_break + movups (%ebp),%xmm0 + movl %ebx,%ecx + movups 16(%ebp),%xmm1 + xorps %xmm0,%xmm6 + xorps %xmm0,%xmm2 + xorps %xmm6,%xmm3 + movups 32(%ebp),%xmm0 +.L035ccm64_dec2_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + movups (%edx,%ecx,1),%xmm1 + addl $32,%ecx +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + movups -16(%edx,%ecx,1),%xmm0 + jnz .L035ccm64_dec2_loop + movups (%esi),%xmm6 + paddq 16(%esp),%xmm7 +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 + leal 16(%esi),%esi + jmp .L033ccm64_dec_outer +.align 16 +.L034ccm64_dec_break: + movl 240(%ebp),%ecx + movl %ebp,%edx + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm6 + leal 32(%edx),%edx + xorps %xmm6,%xmm3 +.L036enc1_loop_6: +.byte 102,15,56,220,217 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L036enc1_loop_6 +.byte 102,15,56,221,217 + movl 48(%esp),%esp + movl 40(%esp),%edi + movups %xmm3,(%edi) + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aesni_ccm64_decrypt_blocks,.-.L_aesni_ccm64_decrypt_blocks_begin +.globl aesni_ctr32_encrypt_blocks +.type aesni_ctr32_encrypt_blocks,@function +.align 16 +aesni_ctr32_encrypt_blocks: +.L_aesni_ctr32_encrypt_blocks_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl 36(%esp),%ebx + movl %esp,%ebp + subl $88,%esp + andl $-16,%esp + movl %ebp,80(%esp) + cmpl $1,%eax + je .L037ctr32_one_shortcut + movdqu (%ebx),%xmm7 + movl $202182159,(%esp) + movl $134810123,4(%esp) + movl $67438087,8(%esp) + movl $66051,12(%esp) + movl $6,%ecx + xorl %ebp,%ebp + movl %ecx,16(%esp) + movl %ecx,20(%esp) + movl %ecx,24(%esp) + movl %ebp,28(%esp) +.byte 102,15,58,22,251,3 +.byte 102,15,58,34,253,3 + movl 240(%edx),%ecx + bswap %ebx + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movdqa (%esp),%xmm2 +.byte 102,15,58,34,195,0 + leal 3(%ebx),%ebp +.byte 102,15,58,34,205,0 + incl %ebx +.byte 102,15,58,34,195,1 + incl %ebp +.byte 102,15,58,34,205,1 + incl %ebx +.byte 102,15,58,34,195,2 + incl %ebp +.byte 102,15,58,34,205,2 + movdqa %xmm0,48(%esp) +.byte 102,15,56,0,194 + movdqu (%edx),%xmm6 + movdqa %xmm1,64(%esp) +.byte 102,15,56,0,202 + pshufd $192,%xmm0,%xmm2 + pshufd $128,%xmm0,%xmm3 + cmpl $6,%eax + jb .L038ctr32_tail + pxor %xmm6,%xmm7 + shll $4,%ecx + movl $16,%ebx + movdqa %xmm7,32(%esp) + movl %edx,%ebp + subl %ecx,%ebx + leal 32(%edx,%ecx,1),%edx + subl $6,%eax + jmp .L039ctr32_loop6 +.align 16 +.L039ctr32_loop6: + pshufd $64,%xmm0,%xmm4 + movdqa 32(%esp),%xmm0 + pshufd $192,%xmm1,%xmm5 + pxor %xmm0,%xmm2 + pshufd $128,%xmm1,%xmm6 + pxor %xmm0,%xmm3 + pshufd $64,%xmm1,%xmm7 + movups 16(%ebp),%xmm1 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 +.byte 102,15,56,220,209 + pxor %xmm0,%xmm6 + pxor %xmm0,%xmm7 +.byte 102,15,56,220,217 + movups 32(%ebp),%xmm0 + movl %ebx,%ecx +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + call .L_aesni_encrypt6_enter + movups (%esi),%xmm1 + movups 16(%esi),%xmm0 + xorps %xmm1,%xmm2 + movups 32(%esi),%xmm1 + xorps %xmm0,%xmm3 + movups %xmm2,(%edi) + movdqa 16(%esp),%xmm0 + xorps %xmm1,%xmm4 + movdqa 64(%esp),%xmm1 + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + paddd %xmm0,%xmm1 + paddd 48(%esp),%xmm0 + movdqa (%esp),%xmm2 + movups 48(%esi),%xmm3 + movups 64(%esi),%xmm4 + xorps %xmm3,%xmm5 + movups 80(%esi),%xmm3 + leal 96(%esi),%esi + movdqa %xmm0,48(%esp) +.byte 102,15,56,0,194 + xorps %xmm4,%xmm6 + movups %xmm5,48(%edi) + xorps %xmm3,%xmm7 + movdqa %xmm1,64(%esp) +.byte 102,15,56,0,202 + movups %xmm6,64(%edi) + pshufd $192,%xmm0,%xmm2 + movups %xmm7,80(%edi) + leal 96(%edi),%edi + pshufd $128,%xmm0,%xmm3 + subl $6,%eax + jnc .L039ctr32_loop6 + addl $6,%eax + jz .L040ctr32_ret + movdqu (%ebp),%xmm7 + movl %ebp,%edx + pxor 32(%esp),%xmm7 + movl 240(%ebp),%ecx +.L038ctr32_tail: + por %xmm7,%xmm2 + cmpl $2,%eax + jb .L041ctr32_one + pshufd $64,%xmm0,%xmm4 + por %xmm7,%xmm3 + je .L042ctr32_two + pshufd $192,%xmm1,%xmm5 + por %xmm7,%xmm4 + cmpl $4,%eax + jb .L043ctr32_three + pshufd $128,%xmm1,%xmm6 + por %xmm7,%xmm5 + je .L044ctr32_four + por %xmm7,%xmm6 + call _aesni_encrypt6 + movups (%esi),%xmm1 + movups 16(%esi),%xmm0 + xorps %xmm1,%xmm2 + movups 32(%esi),%xmm1 + xorps %xmm0,%xmm3 + movups 48(%esi),%xmm0 + xorps %xmm1,%xmm4 + movups 64(%esi),%xmm1 + xorps %xmm0,%xmm5 + movups %xmm2,(%edi) + xorps %xmm1,%xmm6 + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + jmp .L040ctr32_ret +.align 16 +.L037ctr32_one_shortcut: + movups (%ebx),%xmm2 + movl 240(%edx),%ecx +.L041ctr32_one: + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L045enc1_loop_7: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L045enc1_loop_7 +.byte 102,15,56,221,209 + movups (%esi),%xmm6 + xorps %xmm2,%xmm6 + movups %xmm6,(%edi) + jmp .L040ctr32_ret +.align 16 +.L042ctr32_two: + call _aesni_encrypt2 + movups (%esi),%xmm5 + movups 16(%esi),%xmm6 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + jmp .L040ctr32_ret +.align 16 +.L043ctr32_three: + call _aesni_encrypt3 + movups (%esi),%xmm5 + movups 16(%esi),%xmm6 + xorps %xmm5,%xmm2 + movups 32(%esi),%xmm7 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + xorps %xmm7,%xmm4 + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + jmp .L040ctr32_ret +.align 16 +.L044ctr32_four: + call _aesni_encrypt4 + movups (%esi),%xmm6 + movups 16(%esi),%xmm7 + movups 32(%esi),%xmm1 + xorps %xmm6,%xmm2 + movups 48(%esi),%xmm0 + xorps %xmm7,%xmm3 + movups %xmm2,(%edi) + xorps %xmm1,%xmm4 + movups %xmm3,16(%edi) + xorps %xmm0,%xmm5 + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) +.L040ctr32_ret: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + movdqa %xmm0,32(%esp) + pxor %xmm5,%xmm5 + movdqa %xmm0,48(%esp) + pxor %xmm6,%xmm6 + movdqa %xmm0,64(%esp) + pxor %xmm7,%xmm7 + movl 80(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aesni_ctr32_encrypt_blocks,.-.L_aesni_ctr32_encrypt_blocks_begin +.globl aesni_xts_encrypt +.type aesni_xts_encrypt,@function +.align 16 +aesni_xts_encrypt: +.L_aesni_xts_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 36(%esp),%edx + movl 40(%esp),%esi + movl 240(%edx),%ecx + movups (%esi),%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L046enc1_loop_8: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L046enc1_loop_8 +.byte 102,15,56,221,209 + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl %esp,%ebp + subl $120,%esp + movl 240(%edx),%ecx + andl $-16,%esp + movl $135,96(%esp) + movl $0,100(%esp) + movl $1,104(%esp) + movl $0,108(%esp) + movl %eax,112(%esp) + movl %ebp,116(%esp) + movdqa %xmm2,%xmm1 + pxor %xmm0,%xmm0 + movdqa 96(%esp),%xmm3 + pcmpgtd %xmm1,%xmm0 + andl $-16,%eax + movl %edx,%ebp + movl %ecx,%ebx + subl $96,%eax + jc .L047xts_enc_short + shll $4,%ecx + movl $16,%ebx + subl %ecx,%ebx + leal 32(%edx,%ecx,1),%edx + jmp .L048xts_enc_loop6 +.align 16 +.L048xts_enc_loop6: + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,16(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,32(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,48(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm7 + movdqa %xmm1,64(%esp) + paddq %xmm1,%xmm1 + movups (%ebp),%xmm0 + pand %xmm3,%xmm7 + movups (%esi),%xmm2 + pxor %xmm1,%xmm7 + movl %ebx,%ecx + movdqu 16(%esi),%xmm3 + xorps %xmm0,%xmm2 + movdqu 32(%esi),%xmm4 + pxor %xmm0,%xmm3 + movdqu 48(%esi),%xmm5 + pxor %xmm0,%xmm4 + movdqu 64(%esi),%xmm6 + pxor %xmm0,%xmm5 + movdqu 80(%esi),%xmm1 + pxor %xmm0,%xmm6 + leal 96(%esi),%esi + pxor (%esp),%xmm2 + movdqa %xmm7,80(%esp) + pxor %xmm1,%xmm7 + movups 16(%ebp),%xmm1 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 +.byte 102,15,56,220,209 + pxor 48(%esp),%xmm5 + pxor 64(%esp),%xmm6 +.byte 102,15,56,220,217 + pxor %xmm0,%xmm7 + movups 32(%ebp),%xmm0 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + call .L_aesni_encrypt6_enter + movdqa 80(%esp),%xmm1 + pxor %xmm0,%xmm0 + xorps (%esp),%xmm2 + pcmpgtd %xmm1,%xmm0 + xorps 16(%esp),%xmm3 + movups %xmm2,(%edi) + xorps 32(%esp),%xmm4 + movups %xmm3,16(%edi) + xorps 48(%esp),%xmm5 + movups %xmm4,32(%edi) + xorps 64(%esp),%xmm6 + movups %xmm5,48(%edi) + xorps %xmm1,%xmm7 + movups %xmm6,64(%edi) + pshufd $19,%xmm0,%xmm2 + movups %xmm7,80(%edi) + leal 96(%edi),%edi + movdqa 96(%esp),%xmm3 + pxor %xmm0,%xmm0 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + subl $96,%eax + jnc .L048xts_enc_loop6 + movl 240(%ebp),%ecx + movl %ebp,%edx + movl %ecx,%ebx +.L047xts_enc_short: + addl $96,%eax + jz .L049xts_enc_done6x + movdqa %xmm1,%xmm5 + cmpl $32,%eax + jb .L050xts_enc_one + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + je .L051xts_enc_two + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,%xmm6 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + cmpl $64,%eax + jb .L052xts_enc_three + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,%xmm7 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + movdqa %xmm5,(%esp) + movdqa %xmm6,16(%esp) + je .L053xts_enc_four + movdqa %xmm7,32(%esp) + pshufd $19,%xmm0,%xmm7 + movdqa %xmm1,48(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm7 + pxor %xmm1,%xmm7 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + pxor (%esp),%xmm2 + movdqu 48(%esi),%xmm5 + pxor 16(%esp),%xmm3 + movdqu 64(%esi),%xmm6 + pxor 32(%esp),%xmm4 + leal 80(%esi),%esi + pxor 48(%esp),%xmm5 + movdqa %xmm7,64(%esp) + pxor %xmm7,%xmm6 + call _aesni_encrypt6 + movaps 64(%esp),%xmm1 + xorps (%esp),%xmm2 + xorps 16(%esp),%xmm3 + xorps 32(%esp),%xmm4 + movups %xmm2,(%edi) + xorps 48(%esp),%xmm5 + movups %xmm3,16(%edi) + xorps %xmm1,%xmm6 + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + leal 80(%edi),%edi + jmp .L054xts_enc_done +.align 16 +.L050xts_enc_one: + movups (%esi),%xmm2 + leal 16(%esi),%esi + xorps %xmm5,%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L055enc1_loop_9: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L055enc1_loop_9 +.byte 102,15,56,221,209 + xorps %xmm5,%xmm2 + movups %xmm2,(%edi) + leal 16(%edi),%edi + movdqa %xmm5,%xmm1 + jmp .L054xts_enc_done +.align 16 +.L051xts_enc_two: + movaps %xmm1,%xmm6 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + leal 32(%esi),%esi + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + call _aesni_encrypt2 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + leal 32(%edi),%edi + movdqa %xmm6,%xmm1 + jmp .L054xts_enc_done +.align 16 +.L052xts_enc_three: + movaps %xmm1,%xmm7 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + movups 32(%esi),%xmm4 + leal 48(%esi),%esi + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm7,%xmm4 + call _aesni_encrypt3 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm7,%xmm4 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + leal 48(%edi),%edi + movdqa %xmm7,%xmm1 + jmp .L054xts_enc_done +.align 16 +.L053xts_enc_four: + movaps %xmm1,%xmm6 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + movups 32(%esi),%xmm4 + xorps (%esp),%xmm2 + movups 48(%esi),%xmm5 + leal 64(%esi),%esi + xorps 16(%esp),%xmm3 + xorps %xmm7,%xmm4 + xorps %xmm6,%xmm5 + call _aesni_encrypt4 + xorps (%esp),%xmm2 + xorps 16(%esp),%xmm3 + xorps %xmm7,%xmm4 + movups %xmm2,(%edi) + xorps %xmm6,%xmm5 + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + leal 64(%edi),%edi + movdqa %xmm6,%xmm1 + jmp .L054xts_enc_done +.align 16 +.L049xts_enc_done6x: + movl 112(%esp),%eax + andl $15,%eax + jz .L056xts_enc_ret + movdqa %xmm1,%xmm5 + movl %eax,112(%esp) + jmp .L057xts_enc_steal +.align 16 +.L054xts_enc_done: + movl 112(%esp),%eax + pxor %xmm0,%xmm0 + andl $15,%eax + jz .L056xts_enc_ret + pcmpgtd %xmm1,%xmm0 + movl %eax,112(%esp) + pshufd $19,%xmm0,%xmm5 + paddq %xmm1,%xmm1 + pand 96(%esp),%xmm5 + pxor %xmm1,%xmm5 +.L057xts_enc_steal: + movzbl (%esi),%ecx + movzbl -16(%edi),%edx + leal 1(%esi),%esi + movb %cl,-16(%edi) + movb %dl,(%edi) + leal 1(%edi),%edi + subl $1,%eax + jnz .L057xts_enc_steal + subl 112(%esp),%edi + movl %ebp,%edx + movl %ebx,%ecx + movups -16(%edi),%xmm2 + xorps %xmm5,%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L058enc1_loop_10: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L058enc1_loop_10 +.byte 102,15,56,221,209 + xorps %xmm5,%xmm2 + movups %xmm2,-16(%edi) +.L056xts_enc_ret: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + movdqa %xmm0,(%esp) + pxor %xmm3,%xmm3 + movdqa %xmm0,16(%esp) + pxor %xmm4,%xmm4 + movdqa %xmm0,32(%esp) + pxor %xmm5,%xmm5 + movdqa %xmm0,48(%esp) + pxor %xmm6,%xmm6 + movdqa %xmm0,64(%esp) + pxor %xmm7,%xmm7 + movdqa %xmm0,80(%esp) + movl 116(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aesni_xts_encrypt,.-.L_aesni_xts_encrypt_begin +.globl aesni_xts_decrypt +.type aesni_xts_decrypt,@function +.align 16 +aesni_xts_decrypt: +.L_aesni_xts_decrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 36(%esp),%edx + movl 40(%esp),%esi + movl 240(%edx),%ecx + movups (%esi),%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L059enc1_loop_11: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L059enc1_loop_11 +.byte 102,15,56,221,209 + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movl %esp,%ebp + subl $120,%esp + andl $-16,%esp + xorl %ebx,%ebx + testl $15,%eax + setnz %bl + shll $4,%ebx + subl %ebx,%eax + movl $135,96(%esp) + movl $0,100(%esp) + movl $1,104(%esp) + movl $0,108(%esp) + movl %eax,112(%esp) + movl %ebp,116(%esp) + movl 240(%edx),%ecx + movl %edx,%ebp + movl %ecx,%ebx + movdqa %xmm2,%xmm1 + pxor %xmm0,%xmm0 + movdqa 96(%esp),%xmm3 + pcmpgtd %xmm1,%xmm0 + andl $-16,%eax + subl $96,%eax + jc .L060xts_dec_short + shll $4,%ecx + movl $16,%ebx + subl %ecx,%ebx + leal 32(%edx,%ecx,1),%edx + jmp .L061xts_dec_loop6 +.align 16 +.L061xts_dec_loop6: + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,16(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,32(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,48(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + pshufd $19,%xmm0,%xmm7 + movdqa %xmm1,64(%esp) + paddq %xmm1,%xmm1 + movups (%ebp),%xmm0 + pand %xmm3,%xmm7 + movups (%esi),%xmm2 + pxor %xmm1,%xmm7 + movl %ebx,%ecx + movdqu 16(%esi),%xmm3 + xorps %xmm0,%xmm2 + movdqu 32(%esi),%xmm4 + pxor %xmm0,%xmm3 + movdqu 48(%esi),%xmm5 + pxor %xmm0,%xmm4 + movdqu 64(%esi),%xmm6 + pxor %xmm0,%xmm5 + movdqu 80(%esi),%xmm1 + pxor %xmm0,%xmm6 + leal 96(%esi),%esi + pxor (%esp),%xmm2 + movdqa %xmm7,80(%esp) + pxor %xmm1,%xmm7 + movups 16(%ebp),%xmm1 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 +.byte 102,15,56,222,209 + pxor 48(%esp),%xmm5 + pxor 64(%esp),%xmm6 +.byte 102,15,56,222,217 + pxor %xmm0,%xmm7 + movups 32(%ebp),%xmm0 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + call .L_aesni_decrypt6_enter + movdqa 80(%esp),%xmm1 + pxor %xmm0,%xmm0 + xorps (%esp),%xmm2 + pcmpgtd %xmm1,%xmm0 + xorps 16(%esp),%xmm3 + movups %xmm2,(%edi) + xorps 32(%esp),%xmm4 + movups %xmm3,16(%edi) + xorps 48(%esp),%xmm5 + movups %xmm4,32(%edi) + xorps 64(%esp),%xmm6 + movups %xmm5,48(%edi) + xorps %xmm1,%xmm7 + movups %xmm6,64(%edi) + pshufd $19,%xmm0,%xmm2 + movups %xmm7,80(%edi) + leal 96(%edi),%edi + movdqa 96(%esp),%xmm3 + pxor %xmm0,%xmm0 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + subl $96,%eax + jnc .L061xts_dec_loop6 + movl 240(%ebp),%ecx + movl %ebp,%edx + movl %ecx,%ebx +.L060xts_dec_short: + addl $96,%eax + jz .L062xts_dec_done6x + movdqa %xmm1,%xmm5 + cmpl $32,%eax + jb .L063xts_dec_one + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + je .L064xts_dec_two + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,%xmm6 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + cmpl $64,%eax + jb .L065xts_dec_three + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa %xmm1,%xmm7 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 + movdqa %xmm5,(%esp) + movdqa %xmm6,16(%esp) + je .L066xts_dec_four + movdqa %xmm7,32(%esp) + pshufd $19,%xmm0,%xmm7 + movdqa %xmm1,48(%esp) + paddq %xmm1,%xmm1 + pand %xmm3,%xmm7 + pxor %xmm1,%xmm7 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + pxor (%esp),%xmm2 + movdqu 48(%esi),%xmm5 + pxor 16(%esp),%xmm3 + movdqu 64(%esi),%xmm6 + pxor 32(%esp),%xmm4 + leal 80(%esi),%esi + pxor 48(%esp),%xmm5 + movdqa %xmm7,64(%esp) + pxor %xmm7,%xmm6 + call _aesni_decrypt6 + movaps 64(%esp),%xmm1 + xorps (%esp),%xmm2 + xorps 16(%esp),%xmm3 + xorps 32(%esp),%xmm4 + movups %xmm2,(%edi) + xorps 48(%esp),%xmm5 + movups %xmm3,16(%edi) + xorps %xmm1,%xmm6 + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + movups %xmm6,64(%edi) + leal 80(%edi),%edi + jmp .L067xts_dec_done +.align 16 +.L063xts_dec_one: + movups (%esi),%xmm2 + leal 16(%esi),%esi + xorps %xmm5,%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L068dec1_loop_12: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L068dec1_loop_12 +.byte 102,15,56,223,209 + xorps %xmm5,%xmm2 + movups %xmm2,(%edi) + leal 16(%edi),%edi + movdqa %xmm5,%xmm1 + jmp .L067xts_dec_done +.align 16 +.L064xts_dec_two: + movaps %xmm1,%xmm6 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + leal 32(%esi),%esi + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + call _aesni_decrypt2 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + leal 32(%edi),%edi + movdqa %xmm6,%xmm1 + jmp .L067xts_dec_done +.align 16 +.L065xts_dec_three: + movaps %xmm1,%xmm7 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + movups 32(%esi),%xmm4 + leal 48(%esi),%esi + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm7,%xmm4 + call _aesni_decrypt3 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm7,%xmm4 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + leal 48(%edi),%edi + movdqa %xmm7,%xmm1 + jmp .L067xts_dec_done +.align 16 +.L066xts_dec_four: + movaps %xmm1,%xmm6 + movups (%esi),%xmm2 + movups 16(%esi),%xmm3 + movups 32(%esi),%xmm4 + xorps (%esp),%xmm2 + movups 48(%esi),%xmm5 + leal 64(%esi),%esi + xorps 16(%esp),%xmm3 + xorps %xmm7,%xmm4 + xorps %xmm6,%xmm5 + call _aesni_decrypt4 + xorps (%esp),%xmm2 + xorps 16(%esp),%xmm3 + xorps %xmm7,%xmm4 + movups %xmm2,(%edi) + xorps %xmm6,%xmm5 + movups %xmm3,16(%edi) + movups %xmm4,32(%edi) + movups %xmm5,48(%edi) + leal 64(%edi),%edi + movdqa %xmm6,%xmm1 + jmp .L067xts_dec_done +.align 16 +.L062xts_dec_done6x: + movl 112(%esp),%eax + andl $15,%eax + jz .L069xts_dec_ret + movl %eax,112(%esp) + jmp .L070xts_dec_only_one_more +.align 16 +.L067xts_dec_done: + movl 112(%esp),%eax + pxor %xmm0,%xmm0 + andl $15,%eax + jz .L069xts_dec_ret + pcmpgtd %xmm1,%xmm0 + movl %eax,112(%esp) + pshufd $19,%xmm0,%xmm2 + pxor %xmm0,%xmm0 + movdqa 96(%esp),%xmm3 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm2 + pcmpgtd %xmm1,%xmm0 + pxor %xmm2,%xmm1 +.L070xts_dec_only_one_more: + pshufd $19,%xmm0,%xmm5 + movdqa %xmm1,%xmm6 + paddq %xmm1,%xmm1 + pand %xmm3,%xmm5 + pxor %xmm1,%xmm5 + movl %ebp,%edx + movl %ebx,%ecx + movups (%esi),%xmm2 + xorps %xmm5,%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L071dec1_loop_13: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L071dec1_loop_13 +.byte 102,15,56,223,209 + xorps %xmm5,%xmm2 + movups %xmm2,(%edi) +.L072xts_dec_steal: + movzbl 16(%esi),%ecx + movzbl (%edi),%edx + leal 1(%esi),%esi + movb %cl,(%edi) + movb %dl,16(%edi) + leal 1(%edi),%edi + subl $1,%eax + jnz .L072xts_dec_steal + subl 112(%esp),%edi + movl %ebp,%edx + movl %ebx,%ecx + movups (%edi),%xmm2 + xorps %xmm6,%xmm2 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L073dec1_loop_14: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L073dec1_loop_14 +.byte 102,15,56,223,209 + xorps %xmm6,%xmm2 + movups %xmm2,(%edi) +.L069xts_dec_ret: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + movdqa %xmm0,(%esp) + pxor %xmm3,%xmm3 + movdqa %xmm0,16(%esp) + pxor %xmm4,%xmm4 + movdqa %xmm0,32(%esp) + pxor %xmm5,%xmm5 + movdqa %xmm0,48(%esp) + pxor %xmm6,%xmm6 + movdqa %xmm0,64(%esp) + pxor %xmm7,%xmm7 + movdqa %xmm0,80(%esp) + movl 116(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aesni_xts_decrypt,.-.L_aesni_xts_decrypt_begin +.globl aesni_ocb_encrypt +.type aesni_ocb_encrypt,@function +.align 16 +aesni_ocb_encrypt: +.L_aesni_ocb_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 40(%esp),%ecx + movl 48(%esp),%ebx + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movdqu (%ecx),%xmm0 + movl 36(%esp),%ebp + movdqu (%ebx),%xmm1 + movl 44(%esp),%ebx + movl %esp,%ecx + subl $132,%esp + andl $-16,%esp + subl %esi,%edi + shll $4,%eax + leal -96(%esi,%eax,1),%eax + movl %edi,120(%esp) + movl %eax,124(%esp) + movl %ecx,128(%esp) + movl 240(%edx),%ecx + testl $1,%ebp + jnz .L074odd + bsfl %ebp,%eax + addl $1,%ebp + shll $4,%eax + movdqu (%ebx,%eax,1),%xmm7 + movl %edx,%eax + movdqu (%esi),%xmm2 + leal 16(%esi),%esi + pxor %xmm0,%xmm7 + pxor %xmm2,%xmm1 + pxor %xmm7,%xmm2 + movdqa %xmm1,%xmm6 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L075enc1_loop_15: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L075enc1_loop_15 +.byte 102,15,56,221,209 + xorps %xmm7,%xmm2 + movdqa %xmm7,%xmm0 + movdqa %xmm6,%xmm1 + movups %xmm2,-16(%edi,%esi,1) + movl 240(%eax),%ecx + movl %eax,%edx + movl 124(%esp),%eax +.L074odd: + shll $4,%ecx + movl $16,%edi + subl %ecx,%edi + movl %edx,112(%esp) + leal 32(%edx,%ecx,1),%edx + movl %edi,116(%esp) + cmpl %eax,%esi + ja .L076short + jmp .L077grandloop +.align 32 +.L077grandloop: + leal 1(%ebp),%ecx + leal 3(%ebp),%eax + leal 5(%ebp),%edi + addl $6,%ebp + bsfl %ecx,%ecx + bsfl %eax,%eax + bsfl %edi,%edi + shll $4,%ecx + shll $4,%eax + shll $4,%edi + movdqu (%ebx),%xmm2 + movdqu (%ebx,%ecx,1),%xmm3 + movl 116(%esp),%ecx + movdqa %xmm2,%xmm4 + movdqu (%ebx,%eax,1),%xmm5 + movdqa %xmm2,%xmm6 + movdqu (%ebx,%edi,1),%xmm7 + pxor %xmm0,%xmm2 + pxor %xmm2,%xmm3 + movdqa %xmm2,(%esp) + pxor %xmm3,%xmm4 + movdqa %xmm3,16(%esp) + pxor %xmm4,%xmm5 + movdqa %xmm4,32(%esp) + pxor %xmm5,%xmm6 + movdqa %xmm5,48(%esp) + pxor %xmm6,%xmm7 + movdqa %xmm6,64(%esp) + movdqa %xmm7,80(%esp) + movups -48(%edx,%ecx,1),%xmm0 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movdqu 64(%esi),%xmm6 + movdqu 80(%esi),%xmm7 + leal 96(%esi),%esi + pxor %xmm2,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm3,%xmm1 + pxor %xmm0,%xmm3 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + pxor %xmm5,%xmm1 + pxor %xmm0,%xmm5 + pxor %xmm6,%xmm1 + pxor %xmm0,%xmm6 + pxor %xmm7,%xmm1 + pxor %xmm0,%xmm7 + movdqa %xmm1,96(%esp) + movups -32(%edx,%ecx,1),%xmm1 + pxor (%esp),%xmm2 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 + pxor 48(%esp),%xmm5 + pxor 64(%esp),%xmm6 + pxor 80(%esp),%xmm7 + movups -16(%edx,%ecx,1),%xmm0 +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + movl 120(%esp),%edi + movl 124(%esp),%eax + call .L_aesni_encrypt6_enter + movdqa 80(%esp),%xmm0 + pxor (%esp),%xmm2 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 + pxor 48(%esp),%xmm5 + pxor 64(%esp),%xmm6 + pxor %xmm0,%xmm7 + movdqa 96(%esp),%xmm1 + movdqu %xmm2,-96(%edi,%esi,1) + movdqu %xmm3,-80(%edi,%esi,1) + movdqu %xmm4,-64(%edi,%esi,1) + movdqu %xmm5,-48(%edi,%esi,1) + movdqu %xmm6,-32(%edi,%esi,1) + movdqu %xmm7,-16(%edi,%esi,1) + cmpl %eax,%esi + jbe .L077grandloop +.L076short: + addl $96,%eax + subl %esi,%eax + jz .L078done + cmpl $32,%eax + jb .L079one + je .L080two + cmpl $64,%eax + jb .L081three + je .L082four + leal 1(%ebp),%ecx + leal 3(%ebp),%eax + bsfl %ecx,%ecx + bsfl %eax,%eax + shll $4,%ecx + shll $4,%eax + movdqu (%ebx),%xmm2 + movdqu (%ebx,%ecx,1),%xmm3 + movl 116(%esp),%ecx + movdqa %xmm2,%xmm4 + movdqu (%ebx,%eax,1),%xmm5 + movdqa %xmm2,%xmm6 + pxor %xmm0,%xmm2 + pxor %xmm2,%xmm3 + movdqa %xmm2,(%esp) + pxor %xmm3,%xmm4 + movdqa %xmm3,16(%esp) + pxor %xmm4,%xmm5 + movdqa %xmm4,32(%esp) + pxor %xmm5,%xmm6 + movdqa %xmm5,48(%esp) + pxor %xmm6,%xmm7 + movdqa %xmm6,64(%esp) + movups -48(%edx,%ecx,1),%xmm0 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movdqu 64(%esi),%xmm6 + pxor %xmm7,%xmm7 + pxor %xmm2,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm3,%xmm1 + pxor %xmm0,%xmm3 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + pxor %xmm5,%xmm1 + pxor %xmm0,%xmm5 + pxor %xmm6,%xmm1 + pxor %xmm0,%xmm6 + movdqa %xmm1,96(%esp) + movups -32(%edx,%ecx,1),%xmm1 + pxor (%esp),%xmm2 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 + pxor 48(%esp),%xmm5 + pxor 64(%esp),%xmm6 + movups -16(%edx,%ecx,1),%xmm0 +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + movl 120(%esp),%edi + call .L_aesni_encrypt6_enter + movdqa 64(%esp),%xmm0 + pxor (%esp),%xmm2 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 + pxor 48(%esp),%xmm5 + pxor %xmm0,%xmm6 + movdqa 96(%esp),%xmm1 + movdqu %xmm2,(%edi,%esi,1) + movdqu %xmm3,16(%edi,%esi,1) + movdqu %xmm4,32(%edi,%esi,1) + movdqu %xmm5,48(%edi,%esi,1) + movdqu %xmm6,64(%edi,%esi,1) + jmp .L078done +.align 16 +.L079one: + movdqu (%ebx),%xmm7 + movl 112(%esp),%edx + movdqu (%esi),%xmm2 + movl 240(%edx),%ecx + pxor %xmm0,%xmm7 + pxor %xmm2,%xmm1 + pxor %xmm7,%xmm2 + movdqa %xmm1,%xmm6 + movl 120(%esp),%edi + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L083enc1_loop_16: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L083enc1_loop_16 +.byte 102,15,56,221,209 + xorps %xmm7,%xmm2 + movdqa %xmm7,%xmm0 + movdqa %xmm6,%xmm1 + movups %xmm2,(%edi,%esi,1) + jmp .L078done +.align 16 +.L080two: + leal 1(%ebp),%ecx + movl 112(%esp),%edx + bsfl %ecx,%ecx + shll $4,%ecx + movdqu (%ebx),%xmm6 + movdqu (%ebx,%ecx,1),%xmm7 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movl 240(%edx),%ecx + pxor %xmm0,%xmm6 + pxor %xmm6,%xmm7 + pxor %xmm2,%xmm1 + pxor %xmm6,%xmm2 + pxor %xmm3,%xmm1 + pxor %xmm7,%xmm3 + movdqa %xmm1,%xmm5 + movl 120(%esp),%edi + call _aesni_encrypt2 + xorps %xmm6,%xmm2 + xorps %xmm7,%xmm3 + movdqa %xmm7,%xmm0 + movdqa %xmm5,%xmm1 + movups %xmm2,(%edi,%esi,1) + movups %xmm3,16(%edi,%esi,1) + jmp .L078done +.align 16 +.L081three: + leal 1(%ebp),%ecx + movl 112(%esp),%edx + bsfl %ecx,%ecx + shll $4,%ecx + movdqu (%ebx),%xmm5 + movdqu (%ebx,%ecx,1),%xmm6 + movdqa %xmm5,%xmm7 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movl 240(%edx),%ecx + pxor %xmm0,%xmm5 + pxor %xmm5,%xmm6 + pxor %xmm6,%xmm7 + pxor %xmm2,%xmm1 + pxor %xmm5,%xmm2 + pxor %xmm3,%xmm1 + pxor %xmm6,%xmm3 + pxor %xmm4,%xmm1 + pxor %xmm7,%xmm4 + movdqa %xmm1,96(%esp) + movl 120(%esp),%edi + call _aesni_encrypt3 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm7,%xmm4 + movdqa %xmm7,%xmm0 + movdqa 96(%esp),%xmm1 + movups %xmm2,(%edi,%esi,1) + movups %xmm3,16(%edi,%esi,1) + movups %xmm4,32(%edi,%esi,1) + jmp .L078done +.align 16 +.L082four: + leal 1(%ebp),%ecx + leal 3(%ebp),%eax + bsfl %ecx,%ecx + bsfl %eax,%eax + movl 112(%esp),%edx + shll $4,%ecx + shll $4,%eax + movdqu (%ebx),%xmm4 + movdqu (%ebx,%ecx,1),%xmm5 + movdqa %xmm4,%xmm6 + movdqu (%ebx,%eax,1),%xmm7 + pxor %xmm0,%xmm4 + movdqu (%esi),%xmm2 + pxor %xmm4,%xmm5 + movdqu 16(%esi),%xmm3 + pxor %xmm5,%xmm6 + movdqa %xmm4,(%esp) + pxor %xmm6,%xmm7 + movdqa %xmm5,16(%esp) + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movl 240(%edx),%ecx + pxor %xmm2,%xmm1 + pxor (%esp),%xmm2 + pxor %xmm3,%xmm1 + pxor 16(%esp),%xmm3 + pxor %xmm4,%xmm1 + pxor %xmm6,%xmm4 + pxor %xmm5,%xmm1 + pxor %xmm7,%xmm5 + movdqa %xmm1,96(%esp) + movl 120(%esp),%edi + call _aesni_encrypt4 + xorps (%esp),%xmm2 + xorps 16(%esp),%xmm3 + xorps %xmm6,%xmm4 + movups %xmm2,(%edi,%esi,1) + xorps %xmm7,%xmm5 + movups %xmm3,16(%edi,%esi,1) + movdqa %xmm7,%xmm0 + movups %xmm4,32(%edi,%esi,1) + movdqa 96(%esp),%xmm1 + movups %xmm5,48(%edi,%esi,1) +.L078done: + movl 128(%esp),%edx + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + movdqa %xmm2,(%esp) + pxor %xmm4,%xmm4 + movdqa %xmm2,16(%esp) + pxor %xmm5,%xmm5 + movdqa %xmm2,32(%esp) + pxor %xmm6,%xmm6 + movdqa %xmm2,48(%esp) + pxor %xmm7,%xmm7 + movdqa %xmm2,64(%esp) + movdqa %xmm2,80(%esp) + movdqa %xmm2,96(%esp) + leal (%edx),%esp + movl 40(%esp),%ecx + movl 48(%esp),%ebx + movdqu %xmm0,(%ecx) + pxor %xmm0,%xmm0 + movdqu %xmm1,(%ebx) + pxor %xmm1,%xmm1 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aesni_ocb_encrypt,.-.L_aesni_ocb_encrypt_begin +.globl aesni_ocb_decrypt +.type aesni_ocb_decrypt,@function +.align 16 +aesni_ocb_decrypt: +.L_aesni_ocb_decrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 40(%esp),%ecx + movl 48(%esp),%ebx + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + movdqu (%ecx),%xmm0 + movl 36(%esp),%ebp + movdqu (%ebx),%xmm1 + movl 44(%esp),%ebx + movl %esp,%ecx + subl $132,%esp + andl $-16,%esp + subl %esi,%edi + shll $4,%eax + leal -96(%esi,%eax,1),%eax + movl %edi,120(%esp) + movl %eax,124(%esp) + movl %ecx,128(%esp) + movl 240(%edx),%ecx + testl $1,%ebp + jnz .L084odd + bsfl %ebp,%eax + addl $1,%ebp + shll $4,%eax + movdqu (%ebx,%eax,1),%xmm7 + movl %edx,%eax + movdqu (%esi),%xmm2 + leal 16(%esi),%esi + pxor %xmm0,%xmm7 + pxor %xmm7,%xmm2 + movdqa %xmm1,%xmm6 + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L085dec1_loop_17: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L085dec1_loop_17 +.byte 102,15,56,223,209 + xorps %xmm7,%xmm2 + movaps %xmm6,%xmm1 + movdqa %xmm7,%xmm0 + xorps %xmm2,%xmm1 + movups %xmm2,-16(%edi,%esi,1) + movl 240(%eax),%ecx + movl %eax,%edx + movl 124(%esp),%eax +.L084odd: + shll $4,%ecx + movl $16,%edi + subl %ecx,%edi + movl %edx,112(%esp) + leal 32(%edx,%ecx,1),%edx + movl %edi,116(%esp) + cmpl %eax,%esi + ja .L086short + jmp .L087grandloop +.align 32 +.L087grandloop: + leal 1(%ebp),%ecx + leal 3(%ebp),%eax + leal 5(%ebp),%edi + addl $6,%ebp + bsfl %ecx,%ecx + bsfl %eax,%eax + bsfl %edi,%edi + shll $4,%ecx + shll $4,%eax + shll $4,%edi + movdqu (%ebx),%xmm2 + movdqu (%ebx,%ecx,1),%xmm3 + movl 116(%esp),%ecx + movdqa %xmm2,%xmm4 + movdqu (%ebx,%eax,1),%xmm5 + movdqa %xmm2,%xmm6 + movdqu (%ebx,%edi,1),%xmm7 + pxor %xmm0,%xmm2 + pxor %xmm2,%xmm3 + movdqa %xmm2,(%esp) + pxor %xmm3,%xmm4 + movdqa %xmm3,16(%esp) + pxor %xmm4,%xmm5 + movdqa %xmm4,32(%esp) + pxor %xmm5,%xmm6 + movdqa %xmm5,48(%esp) + pxor %xmm6,%xmm7 + movdqa %xmm6,64(%esp) + movdqa %xmm7,80(%esp) + movups -48(%edx,%ecx,1),%xmm0 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movdqu 64(%esi),%xmm6 + movdqu 80(%esi),%xmm7 + leal 96(%esi),%esi + movdqa %xmm1,96(%esp) + pxor %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 + pxor %xmm0,%xmm7 + movups -32(%edx,%ecx,1),%xmm1 + pxor (%esp),%xmm2 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 + pxor 48(%esp),%xmm5 + pxor 64(%esp),%xmm6 + pxor 80(%esp),%xmm7 + movups -16(%edx,%ecx,1),%xmm0 +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + movl 120(%esp),%edi + movl 124(%esp),%eax + call .L_aesni_decrypt6_enter + movdqa 80(%esp),%xmm0 + pxor (%esp),%xmm2 + movdqa 96(%esp),%xmm1 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 + pxor 48(%esp),%xmm5 + pxor 64(%esp),%xmm6 + pxor %xmm0,%xmm7 + pxor %xmm2,%xmm1 + movdqu %xmm2,-96(%edi,%esi,1) + pxor %xmm3,%xmm1 + movdqu %xmm3,-80(%edi,%esi,1) + pxor %xmm4,%xmm1 + movdqu %xmm4,-64(%edi,%esi,1) + pxor %xmm5,%xmm1 + movdqu %xmm5,-48(%edi,%esi,1) + pxor %xmm6,%xmm1 + movdqu %xmm6,-32(%edi,%esi,1) + pxor %xmm7,%xmm1 + movdqu %xmm7,-16(%edi,%esi,1) + cmpl %eax,%esi + jbe .L087grandloop +.L086short: + addl $96,%eax + subl %esi,%eax + jz .L088done + cmpl $32,%eax + jb .L089one + je .L090two + cmpl $64,%eax + jb .L091three + je .L092four + leal 1(%ebp),%ecx + leal 3(%ebp),%eax + bsfl %ecx,%ecx + bsfl %eax,%eax + shll $4,%ecx + shll $4,%eax + movdqu (%ebx),%xmm2 + movdqu (%ebx,%ecx,1),%xmm3 + movl 116(%esp),%ecx + movdqa %xmm2,%xmm4 + movdqu (%ebx,%eax,1),%xmm5 + movdqa %xmm2,%xmm6 + pxor %xmm0,%xmm2 + pxor %xmm2,%xmm3 + movdqa %xmm2,(%esp) + pxor %xmm3,%xmm4 + movdqa %xmm3,16(%esp) + pxor %xmm4,%xmm5 + movdqa %xmm4,32(%esp) + pxor %xmm5,%xmm6 + movdqa %xmm5,48(%esp) + pxor %xmm6,%xmm7 + movdqa %xmm6,64(%esp) + movups -48(%edx,%ecx,1),%xmm0 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movdqu 64(%esi),%xmm6 + pxor %xmm7,%xmm7 + movdqa %xmm1,96(%esp) + pxor %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 + movups -32(%edx,%ecx,1),%xmm1 + pxor (%esp),%xmm2 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 + pxor 48(%esp),%xmm5 + pxor 64(%esp),%xmm6 + movups -16(%edx,%ecx,1),%xmm0 +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + movl 120(%esp),%edi + call .L_aesni_decrypt6_enter + movdqa 64(%esp),%xmm0 + pxor (%esp),%xmm2 + movdqa 96(%esp),%xmm1 + pxor 16(%esp),%xmm3 + pxor 32(%esp),%xmm4 + pxor 48(%esp),%xmm5 + pxor %xmm0,%xmm6 + pxor %xmm2,%xmm1 + movdqu %xmm2,(%edi,%esi,1) + pxor %xmm3,%xmm1 + movdqu %xmm3,16(%edi,%esi,1) + pxor %xmm4,%xmm1 + movdqu %xmm4,32(%edi,%esi,1) + pxor %xmm5,%xmm1 + movdqu %xmm5,48(%edi,%esi,1) + pxor %xmm6,%xmm1 + movdqu %xmm6,64(%edi,%esi,1) + jmp .L088done +.align 16 +.L089one: + movdqu (%ebx),%xmm7 + movl 112(%esp),%edx + movdqu (%esi),%xmm2 + movl 240(%edx),%ecx + pxor %xmm0,%xmm7 + pxor %xmm7,%xmm2 + movdqa %xmm1,%xmm6 + movl 120(%esp),%edi + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L093dec1_loop_18: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L093dec1_loop_18 +.byte 102,15,56,223,209 + xorps %xmm7,%xmm2 + movaps %xmm6,%xmm1 + movdqa %xmm7,%xmm0 + xorps %xmm2,%xmm1 + movups %xmm2,(%edi,%esi,1) + jmp .L088done +.align 16 +.L090two: + leal 1(%ebp),%ecx + movl 112(%esp),%edx + bsfl %ecx,%ecx + shll $4,%ecx + movdqu (%ebx),%xmm6 + movdqu (%ebx,%ecx,1),%xmm7 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movl 240(%edx),%ecx + movdqa %xmm1,%xmm5 + pxor %xmm0,%xmm6 + pxor %xmm6,%xmm7 + pxor %xmm6,%xmm2 + pxor %xmm7,%xmm3 + movl 120(%esp),%edi + call _aesni_decrypt2 + xorps %xmm6,%xmm2 + xorps %xmm7,%xmm3 + movdqa %xmm7,%xmm0 + xorps %xmm2,%xmm5 + movups %xmm2,(%edi,%esi,1) + xorps %xmm3,%xmm5 + movups %xmm3,16(%edi,%esi,1) + movaps %xmm5,%xmm1 + jmp .L088done +.align 16 +.L091three: + leal 1(%ebp),%ecx + movl 112(%esp),%edx + bsfl %ecx,%ecx + shll $4,%ecx + movdqu (%ebx),%xmm5 + movdqu (%ebx,%ecx,1),%xmm6 + movdqa %xmm5,%xmm7 + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movl 240(%edx),%ecx + movdqa %xmm1,96(%esp) + pxor %xmm0,%xmm5 + pxor %xmm5,%xmm6 + pxor %xmm6,%xmm7 + pxor %xmm5,%xmm2 + pxor %xmm6,%xmm3 + pxor %xmm7,%xmm4 + movl 120(%esp),%edi + call _aesni_decrypt3 + movdqa 96(%esp),%xmm1 + xorps %xmm5,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm7,%xmm4 + movups %xmm2,(%edi,%esi,1) + pxor %xmm2,%xmm1 + movdqa %xmm7,%xmm0 + movups %xmm3,16(%edi,%esi,1) + pxor %xmm3,%xmm1 + movups %xmm4,32(%edi,%esi,1) + pxor %xmm4,%xmm1 + jmp .L088done +.align 16 +.L092four: + leal 1(%ebp),%ecx + leal 3(%ebp),%eax + bsfl %ecx,%ecx + bsfl %eax,%eax + movl 112(%esp),%edx + shll $4,%ecx + shll $4,%eax + movdqu (%ebx),%xmm4 + movdqu (%ebx,%ecx,1),%xmm5 + movdqa %xmm4,%xmm6 + movdqu (%ebx,%eax,1),%xmm7 + pxor %xmm0,%xmm4 + movdqu (%esi),%xmm2 + pxor %xmm4,%xmm5 + movdqu 16(%esi),%xmm3 + pxor %xmm5,%xmm6 + movdqa %xmm4,(%esp) + pxor %xmm6,%xmm7 + movdqa %xmm5,16(%esp) + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movl 240(%edx),%ecx + movdqa %xmm1,96(%esp) + pxor (%esp),%xmm2 + pxor 16(%esp),%xmm3 + pxor %xmm6,%xmm4 + pxor %xmm7,%xmm5 + movl 120(%esp),%edi + call _aesni_decrypt4 + movdqa 96(%esp),%xmm1 + xorps (%esp),%xmm2 + xorps 16(%esp),%xmm3 + xorps %xmm6,%xmm4 + movups %xmm2,(%edi,%esi,1) + pxor %xmm2,%xmm1 + xorps %xmm7,%xmm5 + movups %xmm3,16(%edi,%esi,1) + pxor %xmm3,%xmm1 + movdqa %xmm7,%xmm0 + movups %xmm4,32(%edi,%esi,1) + pxor %xmm4,%xmm1 + movups %xmm5,48(%edi,%esi,1) + pxor %xmm5,%xmm1 +.L088done: + movl 128(%esp),%edx + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + movdqa %xmm2,(%esp) + pxor %xmm4,%xmm4 + movdqa %xmm2,16(%esp) + pxor %xmm5,%xmm5 + movdqa %xmm2,32(%esp) + pxor %xmm6,%xmm6 + movdqa %xmm2,48(%esp) + pxor %xmm7,%xmm7 + movdqa %xmm2,64(%esp) + movdqa %xmm2,80(%esp) + movdqa %xmm2,96(%esp) + leal (%edx),%esp + movl 40(%esp),%ecx + movl 48(%esp),%ebx + movdqu %xmm0,(%ecx) + pxor %xmm0,%xmm0 + movdqu %xmm1,(%ebx) + pxor %xmm1,%xmm1 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aesni_ocb_decrypt,.-.L_aesni_ocb_decrypt_begin +.globl aesni_cbc_encrypt +.type aesni_cbc_encrypt,@function +.align 16 +aesni_cbc_encrypt: +.L_aesni_cbc_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl %esp,%ebx + movl 24(%esp),%edi + subl $24,%ebx + movl 28(%esp),%eax + andl $-16,%ebx + movl 32(%esp),%edx + movl 36(%esp),%ebp + testl %eax,%eax + jz .L094cbc_abort + cmpl $0,40(%esp) + xchgl %esp,%ebx + movups (%ebp),%xmm7 + movl 240(%edx),%ecx + movl %edx,%ebp + movl %ebx,16(%esp) + movl %ecx,%ebx + je .L095cbc_decrypt + movaps %xmm7,%xmm2 + cmpl $16,%eax + jb .L096cbc_enc_tail + subl $16,%eax + jmp .L097cbc_enc_loop +.align 16 +.L097cbc_enc_loop: + movups (%esi),%xmm7 + leal 16(%esi),%esi + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + xorps %xmm0,%xmm7 + leal 32(%edx),%edx + xorps %xmm7,%xmm2 +.L098enc1_loop_19: +.byte 102,15,56,220,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L098enc1_loop_19 +.byte 102,15,56,221,209 + movl %ebx,%ecx + movl %ebp,%edx + movups %xmm2,(%edi) + leal 16(%edi),%edi + subl $16,%eax + jnc .L097cbc_enc_loop + addl $16,%eax + jnz .L096cbc_enc_tail + movaps %xmm2,%xmm7 + pxor %xmm2,%xmm2 + jmp .L099cbc_ret +.L096cbc_enc_tail: + movl %eax,%ecx +.long 2767451785 + movl $16,%ecx + subl %eax,%ecx + xorl %eax,%eax +.long 2868115081 + leal -16(%edi),%edi + movl %ebx,%ecx + movl %edi,%esi + movl %ebp,%edx + jmp .L097cbc_enc_loop +.align 16 +.L095cbc_decrypt: + cmpl $80,%eax + jbe .L100cbc_dec_tail + movaps %xmm7,(%esp) + subl $80,%eax + jmp .L101cbc_dec_loop6_enter +.align 16 +.L102cbc_dec_loop6: + movaps %xmm0,(%esp) + movups %xmm7,(%edi) + leal 16(%edi),%edi +.L101cbc_dec_loop6_enter: + movdqu (%esi),%xmm2 + movdqu 16(%esi),%xmm3 + movdqu 32(%esi),%xmm4 + movdqu 48(%esi),%xmm5 + movdqu 64(%esi),%xmm6 + movdqu 80(%esi),%xmm7 + call _aesni_decrypt6 + movups (%esi),%xmm1 + movups 16(%esi),%xmm0 + xorps (%esp),%xmm2 + xorps %xmm1,%xmm3 + movups 32(%esi),%xmm1 + xorps %xmm0,%xmm4 + movups 48(%esi),%xmm0 + xorps %xmm1,%xmm5 + movups 64(%esi),%xmm1 + xorps %xmm0,%xmm6 + movups 80(%esi),%xmm0 + xorps %xmm1,%xmm7 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + leal 96(%esi),%esi + movups %xmm4,32(%edi) + movl %ebx,%ecx + movups %xmm5,48(%edi) + movl %ebp,%edx + movups %xmm6,64(%edi) + leal 80(%edi),%edi + subl $96,%eax + ja .L102cbc_dec_loop6 + movaps %xmm7,%xmm2 + movaps %xmm0,%xmm7 + addl $80,%eax + jle .L103cbc_dec_clear_tail_collected + movups %xmm2,(%edi) + leal 16(%edi),%edi +.L100cbc_dec_tail: + movups (%esi),%xmm2 + movaps %xmm2,%xmm6 + cmpl $16,%eax + jbe .L104cbc_dec_one + movups 16(%esi),%xmm3 + movaps %xmm3,%xmm5 + cmpl $32,%eax + jbe .L105cbc_dec_two + movups 32(%esi),%xmm4 + cmpl $48,%eax + jbe .L106cbc_dec_three + movups 48(%esi),%xmm5 + cmpl $64,%eax + jbe .L107cbc_dec_four + movups 64(%esi),%xmm6 + movaps %xmm7,(%esp) + movups (%esi),%xmm2 + xorps %xmm7,%xmm7 + call _aesni_decrypt6 + movups (%esi),%xmm1 + movups 16(%esi),%xmm0 + xorps (%esp),%xmm2 + xorps %xmm1,%xmm3 + movups 32(%esi),%xmm1 + xorps %xmm0,%xmm4 + movups 48(%esi),%xmm0 + xorps %xmm1,%xmm5 + movups 64(%esi),%xmm7 + xorps %xmm0,%xmm6 + movups %xmm2,(%edi) + movups %xmm3,16(%edi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%edi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%edi) + pxor %xmm5,%xmm5 + leal 64(%edi),%edi + movaps %xmm6,%xmm2 + pxor %xmm6,%xmm6 + subl $80,%eax + jmp .L108cbc_dec_tail_collected +.align 16 +.L104cbc_dec_one: + movups (%edx),%xmm0 + movups 16(%edx),%xmm1 + leal 32(%edx),%edx + xorps %xmm0,%xmm2 +.L109dec1_loop_20: +.byte 102,15,56,222,209 + decl %ecx + movups (%edx),%xmm1 + leal 16(%edx),%edx + jnz .L109dec1_loop_20 +.byte 102,15,56,223,209 + xorps %xmm7,%xmm2 + movaps %xmm6,%xmm7 + subl $16,%eax + jmp .L108cbc_dec_tail_collected +.align 16 +.L105cbc_dec_two: + call _aesni_decrypt2 + xorps %xmm7,%xmm2 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + movaps %xmm3,%xmm2 + pxor %xmm3,%xmm3 + leal 16(%edi),%edi + movaps %xmm5,%xmm7 + subl $32,%eax + jmp .L108cbc_dec_tail_collected +.align 16 +.L106cbc_dec_three: + call _aesni_decrypt3 + xorps %xmm7,%xmm2 + xorps %xmm6,%xmm3 + xorps %xmm5,%xmm4 + movups %xmm2,(%edi) + movaps %xmm4,%xmm2 + pxor %xmm4,%xmm4 + movups %xmm3,16(%edi) + pxor %xmm3,%xmm3 + leal 32(%edi),%edi + movups 32(%esi),%xmm7 + subl $48,%eax + jmp .L108cbc_dec_tail_collected +.align 16 +.L107cbc_dec_four: + call _aesni_decrypt4 + movups 16(%esi),%xmm1 + movups 32(%esi),%xmm0 + xorps %xmm7,%xmm2 + movups 48(%esi),%xmm7 + xorps %xmm6,%xmm3 + movups %xmm2,(%edi) + xorps %xmm1,%xmm4 + movups %xmm3,16(%edi) + pxor %xmm3,%xmm3 + xorps %xmm0,%xmm5 + movups %xmm4,32(%edi) + pxor %xmm4,%xmm4 + leal 48(%edi),%edi + movaps %xmm5,%xmm2 + pxor %xmm5,%xmm5 + subl $64,%eax + jmp .L108cbc_dec_tail_collected +.align 16 +.L103cbc_dec_clear_tail_collected: + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 +.L108cbc_dec_tail_collected: + andl $15,%eax + jnz .L110cbc_dec_tail_partial + movups %xmm2,(%edi) + pxor %xmm0,%xmm0 + jmp .L099cbc_ret +.align 16 +.L110cbc_dec_tail_partial: + movaps %xmm2,(%esp) + pxor %xmm0,%xmm0 + movl $16,%ecx + movl %esp,%esi + subl %eax,%ecx +.long 2767451785 + movdqa %xmm2,(%esp) +.L099cbc_ret: + movl 16(%esp),%esp + movl 36(%esp),%ebp + pxor %xmm2,%xmm2 + pxor %xmm1,%xmm1 + movups %xmm7,(%ebp) + pxor %xmm7,%xmm7 +.L094cbc_abort: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size aesni_cbc_encrypt,.-.L_aesni_cbc_encrypt_begin +.type _aesni_set_encrypt_key,@function +.align 16 +_aesni_set_encrypt_key: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + testl %eax,%eax + jz .L111bad_pointer + testl %edx,%edx + jz .L111bad_pointer + call .L112pic +.L112pic: + popl %ebx + leal .Lkey_const-.L112pic(%ebx),%ebx + leal OPENSSL_ia32cap_P-.Lkey_const(%ebx),%ebp + movups (%eax),%xmm0 + xorps %xmm4,%xmm4 + movl 4(%ebp),%ebp + leal 16(%edx),%edx + andl $268437504,%ebp + cmpl $256,%ecx + je .L11314rounds + cmpl $192,%ecx + je .L11412rounds + cmpl $128,%ecx + jne .L115bad_keybits +.align 16 +.L11610rounds: + cmpl $268435456,%ebp + je .L11710rounds_alt + movl $9,%ecx + movups %xmm0,-16(%edx) +.byte 102,15,58,223,200,1 + call .L118key_128_cold +.byte 102,15,58,223,200,2 + call .L119key_128 +.byte 102,15,58,223,200,4 + call .L119key_128 +.byte 102,15,58,223,200,8 + call .L119key_128 +.byte 102,15,58,223,200,16 + call .L119key_128 +.byte 102,15,58,223,200,32 + call .L119key_128 +.byte 102,15,58,223,200,64 + call .L119key_128 +.byte 102,15,58,223,200,128 + call .L119key_128 +.byte 102,15,58,223,200,27 + call .L119key_128 +.byte 102,15,58,223,200,54 + call .L119key_128 + movups %xmm0,(%edx) + movl %ecx,80(%edx) + jmp .L120good_key +.align 16 +.L119key_128: + movups %xmm0,(%edx) + leal 16(%edx),%edx +.L118key_128_cold: + shufps $16,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $255,%xmm1,%xmm1 + xorps %xmm1,%xmm0 + ret +.align 16 +.L11710rounds_alt: + movdqa (%ebx),%xmm5 + movl $8,%ecx + movdqa 32(%ebx),%xmm4 + movdqa %xmm0,%xmm2 + movdqu %xmm0,-16(%edx) +.L121loop_key128: +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + pslld $1,%xmm4 + leal 16(%edx),%edx + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + pxor %xmm2,%xmm0 + movdqu %xmm0,-16(%edx) + movdqa %xmm0,%xmm2 + decl %ecx + jnz .L121loop_key128 + movdqa 48(%ebx),%xmm4 +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + pslld $1,%xmm4 + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + pxor %xmm2,%xmm0 + movdqu %xmm0,(%edx) + movdqa %xmm0,%xmm2 +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + pxor %xmm2,%xmm0 + movdqu %xmm0,16(%edx) + movl $9,%ecx + movl %ecx,96(%edx) + jmp .L120good_key +.align 16 +.L11412rounds: + movq 16(%eax),%xmm2 + cmpl $268435456,%ebp + je .L12212rounds_alt + movl $11,%ecx + movups %xmm0,-16(%edx) +.byte 102,15,58,223,202,1 + call .L123key_192a_cold +.byte 102,15,58,223,202,2 + call .L124key_192b +.byte 102,15,58,223,202,4 + call .L125key_192a +.byte 102,15,58,223,202,8 + call .L124key_192b +.byte 102,15,58,223,202,16 + call .L125key_192a +.byte 102,15,58,223,202,32 + call .L124key_192b +.byte 102,15,58,223,202,64 + call .L125key_192a +.byte 102,15,58,223,202,128 + call .L124key_192b + movups %xmm0,(%edx) + movl %ecx,48(%edx) + jmp .L120good_key +.align 16 +.L125key_192a: + movups %xmm0,(%edx) + leal 16(%edx),%edx +.align 16 +.L123key_192a_cold: + movaps %xmm2,%xmm5 +.L126key_192b_warm: + shufps $16,%xmm0,%xmm4 + movdqa %xmm2,%xmm3 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + pslldq $4,%xmm3 + xorps %xmm4,%xmm0 + pshufd $85,%xmm1,%xmm1 + pxor %xmm3,%xmm2 + pxor %xmm1,%xmm0 + pshufd $255,%xmm0,%xmm3 + pxor %xmm3,%xmm2 + ret +.align 16 +.L124key_192b: + movaps %xmm0,%xmm3 + shufps $68,%xmm0,%xmm5 + movups %xmm5,(%edx) + shufps $78,%xmm2,%xmm3 + movups %xmm3,16(%edx) + leal 32(%edx),%edx + jmp .L126key_192b_warm +.align 16 +.L12212rounds_alt: + movdqa 16(%ebx),%xmm5 + movdqa 32(%ebx),%xmm4 + movl $8,%ecx + movdqu %xmm0,-16(%edx) +.L127loop_key192: + movq %xmm2,(%edx) + movdqa %xmm2,%xmm1 +.byte 102,15,56,0,213 +.byte 102,15,56,221,212 + pslld $1,%xmm4 + leal 24(%edx),%edx + movdqa %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm3,%xmm0 + pshufd $255,%xmm0,%xmm3 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pxor %xmm2,%xmm0 + pxor %xmm3,%xmm2 + movdqu %xmm0,-16(%edx) + decl %ecx + jnz .L127loop_key192 + movl $11,%ecx + movl %ecx,32(%edx) + jmp .L120good_key +.align 16 +.L11314rounds: + movups 16(%eax),%xmm2 + leal 16(%edx),%edx + cmpl $268435456,%ebp + je .L12814rounds_alt + movl $13,%ecx + movups %xmm0,-32(%edx) + movups %xmm2,-16(%edx) +.byte 102,15,58,223,202,1 + call .L129key_256a_cold +.byte 102,15,58,223,200,1 + call .L130key_256b +.byte 102,15,58,223,202,2 + call .L131key_256a +.byte 102,15,58,223,200,2 + call .L130key_256b +.byte 102,15,58,223,202,4 + call .L131key_256a +.byte 102,15,58,223,200,4 + call .L130key_256b +.byte 102,15,58,223,202,8 + call .L131key_256a +.byte 102,15,58,223,200,8 + call .L130key_256b +.byte 102,15,58,223,202,16 + call .L131key_256a +.byte 102,15,58,223,200,16 + call .L130key_256b +.byte 102,15,58,223,202,32 + call .L131key_256a +.byte 102,15,58,223,200,32 + call .L130key_256b +.byte 102,15,58,223,202,64 + call .L131key_256a + movups %xmm0,(%edx) + movl %ecx,16(%edx) + xorl %eax,%eax + jmp .L120good_key +.align 16 +.L131key_256a: + movups %xmm2,(%edx) + leal 16(%edx),%edx +.L129key_256a_cold: + shufps $16,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $255,%xmm1,%xmm1 + xorps %xmm1,%xmm0 + ret +.align 16 +.L130key_256b: + movups %xmm0,(%edx) + leal 16(%edx),%edx + shufps $16,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps $140,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps $170,%xmm1,%xmm1 + xorps %xmm1,%xmm2 + ret +.align 16 +.L12814rounds_alt: + movdqa (%ebx),%xmm5 + movdqa 32(%ebx),%xmm4 + movl $7,%ecx + movdqu %xmm0,-32(%edx) + movdqa %xmm2,%xmm1 + movdqu %xmm2,-16(%edx) +.L132loop_key256: +.byte 102,15,56,0,213 +.byte 102,15,56,221,212 + movdqa %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm3,%xmm0 + pslld $1,%xmm4 + pxor %xmm2,%xmm0 + movdqu %xmm0,(%edx) + decl %ecx + jz .L133done_key256 + pshufd $255,%xmm0,%xmm2 + pxor %xmm3,%xmm3 +.byte 102,15,56,221,211 + movdqa %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm3,%xmm1 + pxor %xmm1,%xmm2 + movdqu %xmm2,16(%edx) + leal 32(%edx),%edx + movdqa %xmm2,%xmm1 + jmp .L132loop_key256 +.L133done_key256: + movl $13,%ecx + movl %ecx,16(%edx) +.L120good_key: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + xorl %eax,%eax + popl %ebx + popl %ebp + ret +.align 4 +.L111bad_pointer: + movl $-1,%eax + popl %ebx + popl %ebp + ret +.align 4 +.L115bad_keybits: + pxor %xmm0,%xmm0 + movl $-2,%eax + popl %ebx + popl %ebp + ret +.size _aesni_set_encrypt_key,.-_aesni_set_encrypt_key +.globl aesni_set_encrypt_key +.type aesni_set_encrypt_key,@function +.align 16 +aesni_set_encrypt_key: +.L_aesni_set_encrypt_key_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl 4(%esp),%eax + movl 8(%esp),%ecx + movl 12(%esp),%edx + call _aesni_set_encrypt_key + ret +.size aesni_set_encrypt_key,.-.L_aesni_set_encrypt_key_begin +.globl aesni_set_decrypt_key +.type aesni_set_decrypt_key,@function +.align 16 +aesni_set_decrypt_key: +.L_aesni_set_decrypt_key_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl 4(%esp),%eax + movl 8(%esp),%ecx + movl 12(%esp),%edx + call _aesni_set_encrypt_key + movl 12(%esp),%edx + shll $4,%ecx + testl %eax,%eax + jnz .L134dec_key_ret + leal 16(%edx,%ecx,1),%eax + movups (%edx),%xmm0 + movups (%eax),%xmm1 + movups %xmm0,(%eax) + movups %xmm1,(%edx) + leal 16(%edx),%edx + leal -16(%eax),%eax +.L135dec_key_inverse: + movups (%edx),%xmm0 + movups (%eax),%xmm1 +.byte 102,15,56,219,192 +.byte 102,15,56,219,201 + leal 16(%edx),%edx + leal -16(%eax),%eax + movups %xmm0,16(%eax) + movups %xmm1,-16(%edx) + cmpl %edx,%eax + ja .L135dec_key_inverse + movups (%edx),%xmm0 +.byte 102,15,56,219,192 + movups %xmm0,(%edx) + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + xorl %eax,%eax +.L134dec_key_ret: + ret +.size aesni_set_decrypt_key,.-.L_aesni_set_decrypt_key_begin +.align 64 +.Lkey_const: +.long 202313229,202313229,202313229,202313229 +.long 67569157,67569157,67569157,67569157 +.long 1,1,1,1 +.long 27,27,27,27 +.byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69 +.byte 83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83 +.byte 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115 +.byte 115,108,46,111,114,103,62,0 +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/aes/aesni-x86_64.S b/crypto/openssl/crypto/aes/aesni-x86_64.S new file mode 100644 index 000000000000..4e35b2b1d379 --- /dev/null +++ b/crypto/openssl/crypto/aes/aesni-x86_64.S @@ -0,0 +1,4506 @@ +.text + +.globl aesni_encrypt +.type aesni_encrypt,@function +.align 16 +aesni_encrypt: +.cfi_startproc +.byte 243,15,30,250 + movups (%rdi),%xmm2 + movl 240(%rdx),%eax + movups (%rdx),%xmm0 + movups 16(%rdx),%xmm1 + leaq 32(%rdx),%rdx + xorps %xmm0,%xmm2 +.Loop_enc1_1: +.byte 102,15,56,220,209 + decl %eax + movups (%rdx),%xmm1 + leaq 16(%rdx),%rdx + jnz .Loop_enc1_1 +.byte 102,15,56,221,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_encrypt,.-aesni_encrypt + +.globl aesni_decrypt +.type aesni_decrypt,@function +.align 16 +aesni_decrypt: +.cfi_startproc +.byte 243,15,30,250 + movups (%rdi),%xmm2 + movl 240(%rdx),%eax + movups (%rdx),%xmm0 + movups 16(%rdx),%xmm1 + leaq 32(%rdx),%rdx + xorps %xmm0,%xmm2 +.Loop_dec1_2: +.byte 102,15,56,222,209 + decl %eax + movups (%rdx),%xmm1 + leaq 16(%rdx),%rdx + jnz .Loop_dec1_2 +.byte 102,15,56,223,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_decrypt, .-aesni_decrypt +.type _aesni_encrypt2,@function +.align 16 +_aesni_encrypt2: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +.Lenc_loop2: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lenc_loop2 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_encrypt2,.-_aesni_encrypt2 +.type _aesni_decrypt2,@function +.align 16 +_aesni_decrypt2: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +.Ldec_loop2: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Ldec_loop2 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_decrypt2,.-_aesni_decrypt2 +.type _aesni_encrypt3,@function +.align 16 +_aesni_encrypt3: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +.Lenc_loop3: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lenc_loop3 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_encrypt3,.-_aesni_encrypt3 +.type _aesni_decrypt3,@function +.align 16 +_aesni_decrypt3: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax + addq $16,%rax + +.Ldec_loop3: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Ldec_loop3 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_decrypt3,.-_aesni_decrypt3 +.type _aesni_encrypt4,@function +.align 16 +_aesni_encrypt4: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + xorps %xmm0,%xmm5 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 0x0f,0x1f,0x00 + addq $16,%rax + +.Lenc_loop4: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lenc_loop4 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_encrypt4,.-_aesni_encrypt4 +.type _aesni_decrypt4,@function +.align 16 +_aesni_decrypt4: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + xorps %xmm0,%xmm4 + xorps %xmm0,%xmm5 + movups 32(%rcx),%xmm0 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 0x0f,0x1f,0x00 + addq $16,%rax + +.Ldec_loop4: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Ldec_loop4 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_decrypt4,.-_aesni_decrypt4 +.type _aesni_encrypt6,@function +.align 16 +_aesni_encrypt6: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 +.byte 102,15,56,220,209 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,220,217 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 +.byte 102,15,56,220,225 + pxor %xmm0,%xmm7 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp .Lenc_loop6_enter +.align 16 +.Lenc_loop6: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.Lenc_loop6_enter: +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lenc_loop6 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 +.byte 102,15,56,221,240 +.byte 102,15,56,221,248 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_encrypt6,.-_aesni_encrypt6 +.type _aesni_decrypt6,@function +.align 16 +_aesni_decrypt6: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + pxor %xmm0,%xmm3 + pxor %xmm0,%xmm4 +.byte 102,15,56,222,209 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,222,217 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 +.byte 102,15,56,222,225 + pxor %xmm0,%xmm7 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp .Ldec_loop6_enter +.align 16 +.Ldec_loop6: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.Ldec_loop6_enter: +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Ldec_loop6 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 +.byte 102,15,56,223,240 +.byte 102,15,56,223,248 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_decrypt6,.-_aesni_decrypt6 +.type _aesni_encrypt8,@function +.align 16 +_aesni_encrypt8: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,220,209 + pxor %xmm0,%xmm7 + pxor %xmm0,%xmm8 +.byte 102,15,56,220,217 + pxor %xmm0,%xmm9 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp .Lenc_loop8_inner +.align 16 +.Lenc_loop8: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.Lenc_loop8_inner: +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 +.Lenc_loop8_enter: + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lenc_loop8 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 +.byte 102,15,56,221,224 +.byte 102,15,56,221,232 +.byte 102,15,56,221,240 +.byte 102,15,56,221,248 +.byte 102,68,15,56,221,192 +.byte 102,68,15,56,221,200 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_encrypt8,.-_aesni_encrypt8 +.type _aesni_decrypt8,@function +.align 16 +_aesni_decrypt8: +.cfi_startproc + movups (%rcx),%xmm0 + shll $4,%eax + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm2 + xorps %xmm0,%xmm3 + pxor %xmm0,%xmm4 + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 + leaq 32(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,222,209 + pxor %xmm0,%xmm7 + pxor %xmm0,%xmm8 +.byte 102,15,56,222,217 + pxor %xmm0,%xmm9 + movups (%rcx,%rax,1),%xmm0 + addq $16,%rax + jmp .Ldec_loop8_inner +.align 16 +.Ldec_loop8: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.Ldec_loop8_inner: +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 +.Ldec_loop8_enter: + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Ldec_loop8 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 +.byte 102,15,56,223,208 +.byte 102,15,56,223,216 +.byte 102,15,56,223,224 +.byte 102,15,56,223,232 +.byte 102,15,56,223,240 +.byte 102,15,56,223,248 +.byte 102,68,15,56,223,192 +.byte 102,68,15,56,223,200 + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_decrypt8,.-_aesni_decrypt8 +.globl aesni_ecb_encrypt +.type aesni_ecb_encrypt,@function +.align 16 +aesni_ecb_encrypt: +.cfi_startproc +.byte 243,15,30,250 + andq $-16,%rdx + jz .Lecb_ret + + movl 240(%rcx),%eax + movups (%rcx),%xmm0 + movq %rcx,%r11 + movl %eax,%r10d + testl %r8d,%r8d + jz .Lecb_decrypt + + cmpq $0x80,%rdx + jb .Lecb_enc_tail + + movdqu (%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqu 32(%rdi),%xmm4 + movdqu 48(%rdi),%xmm5 + movdqu 64(%rdi),%xmm6 + movdqu 80(%rdi),%xmm7 + movdqu 96(%rdi),%xmm8 + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi + subq $0x80,%rdx + jmp .Lecb_enc_loop8_enter +.align 16 +.Lecb_enc_loop8: + movups %xmm2,(%rsi) + movq %r11,%rcx + movdqu (%rdi),%xmm2 + movl %r10d,%eax + movups %xmm3,16(%rsi) + movdqu 16(%rdi),%xmm3 + movups %xmm4,32(%rsi) + movdqu 32(%rdi),%xmm4 + movups %xmm5,48(%rsi) + movdqu 48(%rdi),%xmm5 + movups %xmm6,64(%rsi) + movdqu 64(%rdi),%xmm6 + movups %xmm7,80(%rsi) + movdqu 80(%rdi),%xmm7 + movups %xmm8,96(%rsi) + movdqu 96(%rdi),%xmm8 + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi +.Lecb_enc_loop8_enter: + + call _aesni_encrypt8 + + subq $0x80,%rdx + jnc .Lecb_enc_loop8 + + movups %xmm2,(%rsi) + movq %r11,%rcx + movups %xmm3,16(%rsi) + movl %r10d,%eax + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + movups %xmm7,80(%rsi) + movups %xmm8,96(%rsi) + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + addq $0x80,%rdx + jz .Lecb_ret + +.Lecb_enc_tail: + movups (%rdi),%xmm2 + cmpq $0x20,%rdx + jb .Lecb_enc_one + movups 16(%rdi),%xmm3 + je .Lecb_enc_two + movups 32(%rdi),%xmm4 + cmpq $0x40,%rdx + jb .Lecb_enc_three + movups 48(%rdi),%xmm5 + je .Lecb_enc_four + movups 64(%rdi),%xmm6 + cmpq $0x60,%rdx + jb .Lecb_enc_five + movups 80(%rdi),%xmm7 + je .Lecb_enc_six + movdqu 96(%rdi),%xmm8 + xorps %xmm9,%xmm9 + call _aesni_encrypt8 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + movups %xmm7,80(%rsi) + movups %xmm8,96(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_one: + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_enc1_3: +.byte 102,15,56,220,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_enc1_3 +.byte 102,15,56,221,209 + movups %xmm2,(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_two: + call _aesni_encrypt2 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_three: + call _aesni_encrypt3 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_four: + call _aesni_encrypt4 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_five: + xorps %xmm7,%xmm7 + call _aesni_encrypt6 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + jmp .Lecb_ret +.align 16 +.Lecb_enc_six: + call _aesni_encrypt6 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + movups %xmm7,80(%rsi) + jmp .Lecb_ret + +.align 16 +.Lecb_decrypt: + cmpq $0x80,%rdx + jb .Lecb_dec_tail + + movdqu (%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqu 32(%rdi),%xmm4 + movdqu 48(%rdi),%xmm5 + movdqu 64(%rdi),%xmm6 + movdqu 80(%rdi),%xmm7 + movdqu 96(%rdi),%xmm8 + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi + subq $0x80,%rdx + jmp .Lecb_dec_loop8_enter +.align 16 +.Lecb_dec_loop8: + movups %xmm2,(%rsi) + movq %r11,%rcx + movdqu (%rdi),%xmm2 + movl %r10d,%eax + movups %xmm3,16(%rsi) + movdqu 16(%rdi),%xmm3 + movups %xmm4,32(%rsi) + movdqu 32(%rdi),%xmm4 + movups %xmm5,48(%rsi) + movdqu 48(%rdi),%xmm5 + movups %xmm6,64(%rsi) + movdqu 64(%rdi),%xmm6 + movups %xmm7,80(%rsi) + movdqu 80(%rdi),%xmm7 + movups %xmm8,96(%rsi) + movdqu 96(%rdi),%xmm8 + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + movdqu 112(%rdi),%xmm9 + leaq 128(%rdi),%rdi +.Lecb_dec_loop8_enter: + + call _aesni_decrypt8 + + movups (%r11),%xmm0 + subq $0x80,%rdx + jnc .Lecb_dec_loop8 + + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movq %r11,%rcx + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movl %r10d,%eax + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + movups %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + movups %xmm8,96(%rsi) + pxor %xmm8,%xmm8 + movups %xmm9,112(%rsi) + pxor %xmm9,%xmm9 + leaq 128(%rsi),%rsi + addq $0x80,%rdx + jz .Lecb_ret + +.Lecb_dec_tail: + movups (%rdi),%xmm2 + cmpq $0x20,%rdx + jb .Lecb_dec_one + movups 16(%rdi),%xmm3 + je .Lecb_dec_two + movups 32(%rdi),%xmm4 + cmpq $0x40,%rdx + jb .Lecb_dec_three + movups 48(%rdi),%xmm5 + je .Lecb_dec_four + movups 64(%rdi),%xmm6 + cmpq $0x60,%rdx + jb .Lecb_dec_five + movups 80(%rdi),%xmm7 + je .Lecb_dec_six + movups 96(%rdi),%xmm8 + movups (%rcx),%xmm0 + xorps %xmm9,%xmm9 + call _aesni_decrypt8 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + movups %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + movups %xmm8,96(%rsi) + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 + jmp .Lecb_ret +.align 16 +.Lecb_dec_one: + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_dec1_4: +.byte 102,15,56,222,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_dec1_4 +.byte 102,15,56,223,209 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + jmp .Lecb_ret +.align 16 +.Lecb_dec_two: + call _aesni_decrypt2 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + jmp .Lecb_ret +.align 16 +.Lecb_dec_three: + call _aesni_decrypt3 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + jmp .Lecb_ret +.align 16 +.Lecb_dec_four: + call _aesni_decrypt4 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + jmp .Lecb_ret +.align 16 +.Lecb_dec_five: + xorps %xmm7,%xmm7 + call _aesni_decrypt6 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + jmp .Lecb_ret +.align 16 +.Lecb_dec_six: + call _aesni_decrypt6 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + movups %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + +.Lecb_ret: + xorps %xmm0,%xmm0 + pxor %xmm1,%xmm1 + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_ecb_encrypt,.-aesni_ecb_encrypt +.globl aesni_ccm64_encrypt_blocks +.type aesni_ccm64_encrypt_blocks,@function +.align 16 +aesni_ccm64_encrypt_blocks: +.cfi_startproc +.byte 243,15,30,250 + movl 240(%rcx),%eax + movdqu (%r8),%xmm6 + movdqa .Lincrement64(%rip),%xmm9 + movdqa .Lbswap_mask(%rip),%xmm7 + + shll $4,%eax + movl $16,%r10d + leaq 0(%rcx),%r11 + movdqu (%r9),%xmm3 + movdqa %xmm6,%xmm2 + leaq 32(%rcx,%rax,1),%rcx +.byte 102,15,56,0,247 + subq %rax,%r10 + jmp .Lccm64_enc_outer +.align 16 +.Lccm64_enc_outer: + movups (%r11),%xmm0 + movq %r10,%rax + movups (%rdi),%xmm8 + + xorps %xmm0,%xmm2 + movups 16(%r11),%xmm1 + xorps %xmm8,%xmm0 + xorps %xmm0,%xmm3 + movups 32(%r11),%xmm0 + +.Lccm64_enc2_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lccm64_enc2_loop +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + paddq %xmm9,%xmm6 + decq %rdx +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 + + leaq 16(%rdi),%rdi + xorps %xmm2,%xmm8 + movdqa %xmm6,%xmm2 + movups %xmm8,(%rsi) +.byte 102,15,56,0,215 + leaq 16(%rsi),%rsi + jnz .Lccm64_enc_outer + + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + movups %xmm3,(%r9) + pxor %xmm3,%xmm3 + pxor %xmm8,%xmm8 + pxor %xmm6,%xmm6 + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_ccm64_encrypt_blocks,.-aesni_ccm64_encrypt_blocks +.globl aesni_ccm64_decrypt_blocks +.type aesni_ccm64_decrypt_blocks,@function +.align 16 +aesni_ccm64_decrypt_blocks: +.cfi_startproc +.byte 243,15,30,250 + movl 240(%rcx),%eax + movups (%r8),%xmm6 + movdqu (%r9),%xmm3 + movdqa .Lincrement64(%rip),%xmm9 + movdqa .Lbswap_mask(%rip),%xmm7 + + movaps %xmm6,%xmm2 + movl %eax,%r10d + movq %rcx,%r11 +.byte 102,15,56,0,247 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_enc1_5: +.byte 102,15,56,220,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_enc1_5 +.byte 102,15,56,221,209 + shll $4,%r10d + movl $16,%eax + movups (%rdi),%xmm8 + paddq %xmm9,%xmm6 + leaq 16(%rdi),%rdi + subq %r10,%rax + leaq 32(%r11,%r10,1),%rcx + movq %rax,%r10 + jmp .Lccm64_dec_outer +.align 16 +.Lccm64_dec_outer: + xorps %xmm2,%xmm8 + movdqa %xmm6,%xmm2 + movups %xmm8,(%rsi) + leaq 16(%rsi),%rsi +.byte 102,15,56,0,215 + + subq $1,%rdx + jz .Lccm64_dec_break + + movups (%r11),%xmm0 + movq %r10,%rax + movups 16(%r11),%xmm1 + xorps %xmm0,%xmm8 + xorps %xmm0,%xmm2 + xorps %xmm8,%xmm3 + movups 32(%r11),%xmm0 + jmp .Lccm64_dec2_loop +.align 16 +.Lccm64_dec2_loop: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Lccm64_dec2_loop + movups (%rdi),%xmm8 + paddq %xmm9,%xmm6 +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,221,208 +.byte 102,15,56,221,216 + leaq 16(%rdi),%rdi + jmp .Lccm64_dec_outer + +.align 16 +.Lccm64_dec_break: + + movl 240(%r11),%eax + movups (%r11),%xmm0 + movups 16(%r11),%xmm1 + xorps %xmm0,%xmm8 + leaq 32(%r11),%r11 + xorps %xmm8,%xmm3 +.Loop_enc1_6: +.byte 102,15,56,220,217 + decl %eax + movups (%r11),%xmm1 + leaq 16(%r11),%r11 + jnz .Loop_enc1_6 +.byte 102,15,56,221,217 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + movups %xmm3,(%r9) + pxor %xmm3,%xmm3 + pxor %xmm8,%xmm8 + pxor %xmm6,%xmm6 + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_ccm64_decrypt_blocks,.-aesni_ccm64_decrypt_blocks +.globl aesni_ctr32_encrypt_blocks +.type aesni_ctr32_encrypt_blocks,@function +.align 16 +aesni_ctr32_encrypt_blocks: +.cfi_startproc +.byte 243,15,30,250 + cmpq $1,%rdx + jne .Lctr32_bulk + + + + movups (%r8),%xmm2 + movups (%rdi),%xmm3 + movl 240(%rcx),%edx + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_enc1_7: +.byte 102,15,56,220,209 + decl %edx + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_enc1_7 +.byte 102,15,56,221,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + xorps %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movups %xmm2,(%rsi) + xorps %xmm2,%xmm2 + jmp .Lctr32_epilogue + +.align 16 +.Lctr32_bulk: + leaq (%rsp),%r11 +.cfi_def_cfa_register %r11 + pushq %rbp +.cfi_offset %rbp,-16 + subq $128,%rsp + andq $-16,%rsp + + + + + movdqu (%r8),%xmm2 + movdqu (%rcx),%xmm0 + movl 12(%r8),%r8d + pxor %xmm0,%xmm2 + movl 12(%rcx),%ebp + movdqa %xmm2,0(%rsp) + bswapl %r8d + movdqa %xmm2,%xmm3 + movdqa %xmm2,%xmm4 + movdqa %xmm2,%xmm5 + movdqa %xmm2,64(%rsp) + movdqa %xmm2,80(%rsp) + movdqa %xmm2,96(%rsp) + movq %rdx,%r10 + movdqa %xmm2,112(%rsp) + + leaq 1(%r8),%rax + leaq 2(%r8),%rdx + bswapl %eax + bswapl %edx + xorl %ebp,%eax + xorl %ebp,%edx +.byte 102,15,58,34,216,3 + leaq 3(%r8),%rax + movdqa %xmm3,16(%rsp) +.byte 102,15,58,34,226,3 + bswapl %eax + movq %r10,%rdx + leaq 4(%r8),%r10 + movdqa %xmm4,32(%rsp) + xorl %ebp,%eax + bswapl %r10d +.byte 102,15,58,34,232,3 + xorl %ebp,%r10d + movdqa %xmm5,48(%rsp) + leaq 5(%r8),%r9 + movl %r10d,64+12(%rsp) + bswapl %r9d + leaq 6(%r8),%r10 + movl 240(%rcx),%eax + xorl %ebp,%r9d + bswapl %r10d + movl %r9d,80+12(%rsp) + xorl %ebp,%r10d + leaq 7(%r8),%r9 + movl %r10d,96+12(%rsp) + bswapl %r9d + movl OPENSSL_ia32cap_P+4(%rip),%r10d + xorl %ebp,%r9d + andl $71303168,%r10d + movl %r9d,112+12(%rsp) + + movups 16(%rcx),%xmm1 + + movdqa 64(%rsp),%xmm6 + movdqa 80(%rsp),%xmm7 + + cmpq $8,%rdx + jb .Lctr32_tail + + subq $6,%rdx + cmpl $4194304,%r10d + je .Lctr32_6x + + leaq 128(%rcx),%rcx + subq $2,%rdx + jmp .Lctr32_loop8 + +.align 16 +.Lctr32_6x: + shll $4,%eax + movl $48,%r10d + bswapl %ebp + leaq 32(%rcx,%rax,1),%rcx + subq %rax,%r10 + jmp .Lctr32_loop6 + +.align 16 +.Lctr32_loop6: + addl $6,%r8d + movups -48(%rcx,%r10,1),%xmm0 +.byte 102,15,56,220,209 + movl %r8d,%eax + xorl %ebp,%eax +.byte 102,15,56,220,217 +.byte 0x0f,0x38,0xf1,0x44,0x24,12 + leal 1(%r8),%eax +.byte 102,15,56,220,225 + xorl %ebp,%eax +.byte 0x0f,0x38,0xf1,0x44,0x24,28 +.byte 102,15,56,220,233 + leal 2(%r8),%eax + xorl %ebp,%eax +.byte 102,15,56,220,241 +.byte 0x0f,0x38,0xf1,0x44,0x24,44 + leal 3(%r8),%eax +.byte 102,15,56,220,249 + movups -32(%rcx,%r10,1),%xmm1 + xorl %ebp,%eax + +.byte 102,15,56,220,208 +.byte 0x0f,0x38,0xf1,0x44,0x24,60 + leal 4(%r8),%eax +.byte 102,15,56,220,216 + xorl %ebp,%eax +.byte 0x0f,0x38,0xf1,0x44,0x24,76 +.byte 102,15,56,220,224 + leal 5(%r8),%eax + xorl %ebp,%eax +.byte 102,15,56,220,232 +.byte 0x0f,0x38,0xf1,0x44,0x24,92 + movq %r10,%rax +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups -16(%rcx,%r10,1),%xmm0 + + call .Lenc_loop6 + + movdqu (%rdi),%xmm8 + movdqu 16(%rdi),%xmm9 + movdqu 32(%rdi),%xmm10 + movdqu 48(%rdi),%xmm11 + movdqu 64(%rdi),%xmm12 + movdqu 80(%rdi),%xmm13 + leaq 96(%rdi),%rdi + movups -64(%rcx,%r10,1),%xmm1 + pxor %xmm2,%xmm8 + movaps 0(%rsp),%xmm2 + pxor %xmm3,%xmm9 + movaps 16(%rsp),%xmm3 + pxor %xmm4,%xmm10 + movaps 32(%rsp),%xmm4 + pxor %xmm5,%xmm11 + movaps 48(%rsp),%xmm5 + pxor %xmm6,%xmm12 + movaps 64(%rsp),%xmm6 + pxor %xmm7,%xmm13 + movaps 80(%rsp),%xmm7 + movdqu %xmm8,(%rsi) + movdqu %xmm9,16(%rsi) + movdqu %xmm10,32(%rsi) + movdqu %xmm11,48(%rsi) + movdqu %xmm12,64(%rsi) + movdqu %xmm13,80(%rsi) + leaq 96(%rsi),%rsi + + subq $6,%rdx + jnc .Lctr32_loop6 + + addq $6,%rdx + jz .Lctr32_done + + leal -48(%r10),%eax + leaq -80(%rcx,%r10,1),%rcx + negl %eax + shrl $4,%eax + jmp .Lctr32_tail + +.align 32 +.Lctr32_loop8: + addl $8,%r8d + movdqa 96(%rsp),%xmm8 +.byte 102,15,56,220,209 + movl %r8d,%r9d + movdqa 112(%rsp),%xmm9 +.byte 102,15,56,220,217 + bswapl %r9d + movups 32-128(%rcx),%xmm0 +.byte 102,15,56,220,225 + xorl %ebp,%r9d + nop +.byte 102,15,56,220,233 + movl %r9d,0+12(%rsp) + leaq 1(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 48-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movl %r9d,16+12(%rsp) + leaq 2(%r8),%r9 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 64-128(%rcx),%xmm0 + bswapl %r9d +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movl %r9d,32+12(%rsp) + leaq 3(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 80-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movl %r9d,48+12(%rsp) + leaq 4(%r8),%r9 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 96-128(%rcx),%xmm0 + bswapl %r9d +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movl %r9d,64+12(%rsp) + leaq 5(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 112-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movl %r9d,80+12(%rsp) + leaq 6(%r8),%r9 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 128-128(%rcx),%xmm0 + bswapl %r9d +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + xorl %ebp,%r9d +.byte 0x66,0x90 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movl %r9d,96+12(%rsp) + leaq 7(%r8),%r9 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 144-128(%rcx),%xmm1 + bswapl %r9d +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 + xorl %ebp,%r9d + movdqu 0(%rdi),%xmm10 +.byte 102,15,56,220,232 + movl %r9d,112+12(%rsp) + cmpl $11,%eax +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 160-128(%rcx),%xmm0 + + jb .Lctr32_enc_done + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 176-128(%rcx),%xmm1 + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 192-128(%rcx),%xmm0 + je .Lctr32_enc_done + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movups 208-128(%rcx),%xmm1 + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 +.byte 102,68,15,56,220,192 +.byte 102,68,15,56,220,200 + movups 224-128(%rcx),%xmm0 + jmp .Lctr32_enc_done + +.align 16 +.Lctr32_enc_done: + movdqu 16(%rdi),%xmm11 + pxor %xmm0,%xmm10 + movdqu 32(%rdi),%xmm12 + pxor %xmm0,%xmm11 + movdqu 48(%rdi),%xmm13 + pxor %xmm0,%xmm12 + movdqu 64(%rdi),%xmm14 + pxor %xmm0,%xmm13 + movdqu 80(%rdi),%xmm15 + pxor %xmm0,%xmm14 + pxor %xmm0,%xmm15 +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 +.byte 102,68,15,56,220,201 + movdqu 96(%rdi),%xmm1 + leaq 128(%rdi),%rdi + +.byte 102,65,15,56,221,210 + pxor %xmm0,%xmm1 + movdqu 112-128(%rdi),%xmm10 +.byte 102,65,15,56,221,219 + pxor %xmm0,%xmm10 + movdqa 0(%rsp),%xmm11 +.byte 102,65,15,56,221,228 +.byte 102,65,15,56,221,237 + movdqa 16(%rsp),%xmm12 + movdqa 32(%rsp),%xmm13 +.byte 102,65,15,56,221,246 +.byte 102,65,15,56,221,255 + movdqa 48(%rsp),%xmm14 + movdqa 64(%rsp),%xmm15 +.byte 102,68,15,56,221,193 + movdqa 80(%rsp),%xmm0 + movups 16-128(%rcx),%xmm1 +.byte 102,69,15,56,221,202 + + movups %xmm2,(%rsi) + movdqa %xmm11,%xmm2 + movups %xmm3,16(%rsi) + movdqa %xmm12,%xmm3 + movups %xmm4,32(%rsi) + movdqa %xmm13,%xmm4 + movups %xmm5,48(%rsi) + movdqa %xmm14,%xmm5 + movups %xmm6,64(%rsi) + movdqa %xmm15,%xmm6 + movups %xmm7,80(%rsi) + movdqa %xmm0,%xmm7 + movups %xmm8,96(%rsi) + movups %xmm9,112(%rsi) + leaq 128(%rsi),%rsi + + subq $8,%rdx + jnc .Lctr32_loop8 + + addq $8,%rdx + jz .Lctr32_done + leaq -128(%rcx),%rcx + +.Lctr32_tail: + + + leaq 16(%rcx),%rcx + cmpq $4,%rdx + jb .Lctr32_loop3 + je .Lctr32_loop4 + + + shll $4,%eax + movdqa 96(%rsp),%xmm8 + pxor %xmm9,%xmm9 + + movups 16(%rcx),%xmm0 +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 + leaq 32-16(%rcx,%rax,1),%rcx + negq %rax +.byte 102,15,56,220,225 + addq $16,%rax + movups (%rdi),%xmm10 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 + movups 16(%rdi),%xmm11 + movups 32(%rdi),%xmm12 +.byte 102,15,56,220,249 +.byte 102,68,15,56,220,193 + + call .Lenc_loop8_enter + + movdqu 48(%rdi),%xmm13 + pxor %xmm10,%xmm2 + movdqu 64(%rdi),%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm10,%xmm6 + movdqu %xmm5,48(%rsi) + movdqu %xmm6,64(%rsi) + cmpq $6,%rdx + jb .Lctr32_done + + movups 80(%rdi),%xmm11 + xorps %xmm11,%xmm7 + movups %xmm7,80(%rsi) + je .Lctr32_done + + movups 96(%rdi),%xmm12 + xorps %xmm12,%xmm8 + movups %xmm8,96(%rsi) + jmp .Lctr32_done + +.align 32 +.Lctr32_loop4: +.byte 102,15,56,220,209 + leaq 16(%rcx),%rcx + decl %eax +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups (%rcx),%xmm1 + jnz .Lctr32_loop4 +.byte 102,15,56,221,209 +.byte 102,15,56,221,217 + movups (%rdi),%xmm10 + movups 16(%rdi),%xmm11 +.byte 102,15,56,221,225 +.byte 102,15,56,221,233 + movups 32(%rdi),%xmm12 + movups 48(%rdi),%xmm13 + + xorps %xmm10,%xmm2 + movups %xmm2,(%rsi) + xorps %xmm11,%xmm3 + movups %xmm3,16(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm4,32(%rsi) + pxor %xmm13,%xmm5 + movdqu %xmm5,48(%rsi) + jmp .Lctr32_done + +.align 32 +.Lctr32_loop3: +.byte 102,15,56,220,209 + leaq 16(%rcx),%rcx + decl %eax +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 + movups (%rcx),%xmm1 + jnz .Lctr32_loop3 +.byte 102,15,56,221,209 +.byte 102,15,56,221,217 +.byte 102,15,56,221,225 + + movups (%rdi),%xmm10 + xorps %xmm10,%xmm2 + movups %xmm2,(%rsi) + cmpq $2,%rdx + jb .Lctr32_done + + movups 16(%rdi),%xmm11 + xorps %xmm11,%xmm3 + movups %xmm3,16(%rsi) + je .Lctr32_done + + movups 32(%rdi),%xmm12 + xorps %xmm12,%xmm4 + movups %xmm4,32(%rsi) + +.Lctr32_done: + xorps %xmm0,%xmm0 + xorl %ebp,%ebp + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + movaps %xmm0,0(%rsp) + pxor %xmm8,%xmm8 + movaps %xmm0,16(%rsp) + pxor %xmm9,%xmm9 + movaps %xmm0,32(%rsp) + pxor %xmm10,%xmm10 + movaps %xmm0,48(%rsp) + pxor %xmm11,%xmm11 + movaps %xmm0,64(%rsp) + pxor %xmm12,%xmm12 + movaps %xmm0,80(%rsp) + pxor %xmm13,%xmm13 + movaps %xmm0,96(%rsp) + pxor %xmm14,%xmm14 + movaps %xmm0,112(%rsp) + pxor %xmm15,%xmm15 + movq -8(%r11),%rbp +.cfi_restore %rbp + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lctr32_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_ctr32_encrypt_blocks,.-aesni_ctr32_encrypt_blocks +.globl aesni_xts_encrypt +.type aesni_xts_encrypt,@function +.align 16 +aesni_xts_encrypt: +.cfi_startproc +.byte 243,15,30,250 + leaq (%rsp),%r11 +.cfi_def_cfa_register %r11 + pushq %rbp +.cfi_offset %rbp,-16 + subq $112,%rsp + andq $-16,%rsp + movups (%r9),%xmm2 + movl 240(%r8),%eax + movl 240(%rcx),%r10d + movups (%r8),%xmm0 + movups 16(%r8),%xmm1 + leaq 32(%r8),%r8 + xorps %xmm0,%xmm2 +.Loop_enc1_8: +.byte 102,15,56,220,209 + decl %eax + movups (%r8),%xmm1 + leaq 16(%r8),%r8 + jnz .Loop_enc1_8 +.byte 102,15,56,221,209 + movups (%rcx),%xmm0 + movq %rcx,%rbp + movl %r10d,%eax + shll $4,%r10d + movq %rdx,%r9 + andq $-16,%rdx + + movups 16(%rcx,%r10,1),%xmm1 + + movdqa .Lxts_magic(%rip),%xmm8 + movdqa %xmm2,%xmm15 + pshufd $0x5f,%xmm2,%xmm9 + pxor %xmm0,%xmm1 + movdqa %xmm9,%xmm14 + paddd %xmm9,%xmm9 + movdqa %xmm15,%xmm10 + psrad $31,%xmm14 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 + pxor %xmm0,%xmm10 + pxor %xmm14,%xmm15 + movdqa %xmm9,%xmm14 + paddd %xmm9,%xmm9 + movdqa %xmm15,%xmm11 + psrad $31,%xmm14 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 + pxor %xmm0,%xmm11 + pxor %xmm14,%xmm15 + movdqa %xmm9,%xmm14 + paddd %xmm9,%xmm9 + movdqa %xmm15,%xmm12 + psrad $31,%xmm14 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 + pxor %xmm0,%xmm12 + pxor %xmm14,%xmm15 + movdqa %xmm9,%xmm14 + paddd %xmm9,%xmm9 + movdqa %xmm15,%xmm13 + psrad $31,%xmm14 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 + pxor %xmm0,%xmm13 + pxor %xmm14,%xmm15 + movdqa %xmm15,%xmm14 + psrad $31,%xmm9 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm9 + pxor %xmm0,%xmm14 + pxor %xmm9,%xmm15 + movaps %xmm1,96(%rsp) + + subq $96,%rdx + jc .Lxts_enc_short + + movl $16+96,%eax + leaq 32(%rbp,%r10,1),%rcx + subq %r10,%rax + movups 16(%rbp),%xmm1 + movq %rax,%r10 + leaq .Lxts_magic(%rip),%r8 + jmp .Lxts_enc_grandloop + +.align 32 +.Lxts_enc_grandloop: + movdqu 0(%rdi),%xmm2 + movdqa %xmm0,%xmm8 + movdqu 16(%rdi),%xmm3 + pxor %xmm10,%xmm2 + movdqu 32(%rdi),%xmm4 + pxor %xmm11,%xmm3 +.byte 102,15,56,220,209 + movdqu 48(%rdi),%xmm5 + pxor %xmm12,%xmm4 +.byte 102,15,56,220,217 + movdqu 64(%rdi),%xmm6 + pxor %xmm13,%xmm5 +.byte 102,15,56,220,225 + movdqu 80(%rdi),%xmm7 + pxor %xmm15,%xmm8 + movdqa 96(%rsp),%xmm9 + pxor %xmm14,%xmm6 +.byte 102,15,56,220,233 + movups 32(%rbp),%xmm0 + leaq 96(%rdi),%rdi + pxor %xmm8,%xmm7 + + pxor %xmm9,%xmm10 +.byte 102,15,56,220,241 + pxor %xmm9,%xmm11 + movdqa %xmm10,0(%rsp) +.byte 102,15,56,220,249 + movups 48(%rbp),%xmm1 + pxor %xmm9,%xmm12 + +.byte 102,15,56,220,208 + pxor %xmm9,%xmm13 + movdqa %xmm11,16(%rsp) +.byte 102,15,56,220,216 + pxor %xmm9,%xmm14 + movdqa %xmm12,32(%rsp) +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + pxor %xmm9,%xmm8 + movdqa %xmm14,64(%rsp) +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups 64(%rbp),%xmm0 + movdqa %xmm8,80(%rsp) + pshufd $0x5f,%xmm15,%xmm9 + jmp .Lxts_enc_loop6 +.align 32 +.Lxts_enc_loop6: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + movups -64(%rcx,%rax,1),%xmm1 + addq $32,%rax + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups -80(%rcx,%rax,1),%xmm0 + jnz .Lxts_enc_loop6 + + movdqa (%r8),%xmm8 + movdqa %xmm9,%xmm14 + paddd %xmm9,%xmm9 +.byte 102,15,56,220,209 + paddq %xmm15,%xmm15 + psrad $31,%xmm14 +.byte 102,15,56,220,217 + pand %xmm8,%xmm14 + movups (%rbp),%xmm10 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 + pxor %xmm14,%xmm15 + movaps %xmm10,%xmm11 +.byte 102,15,56,220,249 + movups -64(%rcx),%xmm1 + + movdqa %xmm9,%xmm14 +.byte 102,15,56,220,208 + paddd %xmm9,%xmm9 + pxor %xmm15,%xmm10 +.byte 102,15,56,220,216 + psrad $31,%xmm14 + paddq %xmm15,%xmm15 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + pand %xmm8,%xmm14 + movaps %xmm11,%xmm12 +.byte 102,15,56,220,240 + pxor %xmm14,%xmm15 + movdqa %xmm9,%xmm14 +.byte 102,15,56,220,248 + movups -48(%rcx),%xmm0 + + paddd %xmm9,%xmm9 +.byte 102,15,56,220,209 + pxor %xmm15,%xmm11 + psrad $31,%xmm14 +.byte 102,15,56,220,217 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movdqa %xmm13,48(%rsp) + pxor %xmm14,%xmm15 +.byte 102,15,56,220,241 + movaps %xmm12,%xmm13 + movdqa %xmm9,%xmm14 +.byte 102,15,56,220,249 + movups -32(%rcx),%xmm1 + + paddd %xmm9,%xmm9 +.byte 102,15,56,220,208 + pxor %xmm15,%xmm12 + psrad $31,%xmm14 +.byte 102,15,56,220,216 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 + pxor %xmm14,%xmm15 + movaps %xmm13,%xmm14 +.byte 102,15,56,220,248 + + movdqa %xmm9,%xmm0 + paddd %xmm9,%xmm9 +.byte 102,15,56,220,209 + pxor %xmm15,%xmm13 + psrad $31,%xmm0 +.byte 102,15,56,220,217 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm0 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + pxor %xmm0,%xmm15 + movups (%rbp),%xmm0 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + movups 16(%rbp),%xmm1 + + pxor %xmm15,%xmm14 +.byte 102,15,56,221,84,36,0 + psrad $31,%xmm9 + paddq %xmm15,%xmm15 +.byte 102,15,56,221,92,36,16 +.byte 102,15,56,221,100,36,32 + pand %xmm8,%xmm9 + movq %r10,%rax +.byte 102,15,56,221,108,36,48 +.byte 102,15,56,221,116,36,64 +.byte 102,15,56,221,124,36,80 + pxor %xmm9,%xmm15 + + leaq 96(%rsi),%rsi + movups %xmm2,-96(%rsi) + movups %xmm3,-80(%rsi) + movups %xmm4,-64(%rsi) + movups %xmm5,-48(%rsi) + movups %xmm6,-32(%rsi) + movups %xmm7,-16(%rsi) + subq $96,%rdx + jnc .Lxts_enc_grandloop + + movl $16+96,%eax + subl %r10d,%eax + movq %rbp,%rcx + shrl $4,%eax + +.Lxts_enc_short: + + movl %eax,%r10d + pxor %xmm0,%xmm10 + addq $96,%rdx + jz .Lxts_enc_done + + pxor %xmm0,%xmm11 + cmpq $0x20,%rdx + jb .Lxts_enc_one + pxor %xmm0,%xmm12 + je .Lxts_enc_two + + pxor %xmm0,%xmm13 + cmpq $0x40,%rdx + jb .Lxts_enc_three + pxor %xmm0,%xmm14 + je .Lxts_enc_four + + movdqu (%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqu 32(%rdi),%xmm4 + pxor %xmm10,%xmm2 + movdqu 48(%rdi),%xmm5 + pxor %xmm11,%xmm3 + movdqu 64(%rdi),%xmm6 + leaq 80(%rdi),%rdi + pxor %xmm12,%xmm4 + pxor %xmm13,%xmm5 + pxor %xmm14,%xmm6 + pxor %xmm7,%xmm7 + + call _aesni_encrypt6 + + xorps %xmm10,%xmm2 + movdqa %xmm15,%xmm10 + xorps %xmm11,%xmm3 + xorps %xmm12,%xmm4 + movdqu %xmm2,(%rsi) + xorps %xmm13,%xmm5 + movdqu %xmm3,16(%rsi) + xorps %xmm14,%xmm6 + movdqu %xmm4,32(%rsi) + movdqu %xmm5,48(%rsi) + movdqu %xmm6,64(%rsi) + leaq 80(%rsi),%rsi + jmp .Lxts_enc_done + +.align 16 +.Lxts_enc_one: + movups (%rdi),%xmm2 + leaq 16(%rdi),%rdi + xorps %xmm10,%xmm2 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_enc1_9: +.byte 102,15,56,220,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_enc1_9 +.byte 102,15,56,221,209 + xorps %xmm10,%xmm2 + movdqa %xmm11,%xmm10 + movups %xmm2,(%rsi) + leaq 16(%rsi),%rsi + jmp .Lxts_enc_done + +.align 16 +.Lxts_enc_two: + movups (%rdi),%xmm2 + movups 16(%rdi),%xmm3 + leaq 32(%rdi),%rdi + xorps %xmm10,%xmm2 + xorps %xmm11,%xmm3 + + call _aesni_encrypt2 + + xorps %xmm10,%xmm2 + movdqa %xmm12,%xmm10 + xorps %xmm11,%xmm3 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + leaq 32(%rsi),%rsi + jmp .Lxts_enc_done + +.align 16 +.Lxts_enc_three: + movups (%rdi),%xmm2 + movups 16(%rdi),%xmm3 + movups 32(%rdi),%xmm4 + leaq 48(%rdi),%rdi + xorps %xmm10,%xmm2 + xorps %xmm11,%xmm3 + xorps %xmm12,%xmm4 + + call _aesni_encrypt3 + + xorps %xmm10,%xmm2 + movdqa %xmm13,%xmm10 + xorps %xmm11,%xmm3 + xorps %xmm12,%xmm4 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + leaq 48(%rsi),%rsi + jmp .Lxts_enc_done + +.align 16 +.Lxts_enc_four: + movups (%rdi),%xmm2 + movups 16(%rdi),%xmm3 + movups 32(%rdi),%xmm4 + xorps %xmm10,%xmm2 + movups 48(%rdi),%xmm5 + leaq 64(%rdi),%rdi + xorps %xmm11,%xmm3 + xorps %xmm12,%xmm4 + xorps %xmm13,%xmm5 + + call _aesni_encrypt4 + + pxor %xmm10,%xmm2 + movdqa %xmm14,%xmm10 + pxor %xmm11,%xmm3 + pxor %xmm12,%xmm4 + movdqu %xmm2,(%rsi) + pxor %xmm13,%xmm5 + movdqu %xmm3,16(%rsi) + movdqu %xmm4,32(%rsi) + movdqu %xmm5,48(%rsi) + leaq 64(%rsi),%rsi + jmp .Lxts_enc_done + +.align 16 +.Lxts_enc_done: + andq $15,%r9 + jz .Lxts_enc_ret + movq %r9,%rdx + +.Lxts_enc_steal: + movzbl (%rdi),%eax + movzbl -16(%rsi),%ecx + leaq 1(%rdi),%rdi + movb %al,-16(%rsi) + movb %cl,0(%rsi) + leaq 1(%rsi),%rsi + subq $1,%rdx + jnz .Lxts_enc_steal + + subq %r9,%rsi + movq %rbp,%rcx + movl %r10d,%eax + + movups -16(%rsi),%xmm2 + xorps %xmm10,%xmm2 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_enc1_10: +.byte 102,15,56,220,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_enc1_10 +.byte 102,15,56,221,209 + xorps %xmm10,%xmm2 + movups %xmm2,-16(%rsi) + +.Lxts_enc_ret: + xorps %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + movaps %xmm0,0(%rsp) + pxor %xmm8,%xmm8 + movaps %xmm0,16(%rsp) + pxor %xmm9,%xmm9 + movaps %xmm0,32(%rsp) + pxor %xmm10,%xmm10 + movaps %xmm0,48(%rsp) + pxor %xmm11,%xmm11 + movaps %xmm0,64(%rsp) + pxor %xmm12,%xmm12 + movaps %xmm0,80(%rsp) + pxor %xmm13,%xmm13 + movaps %xmm0,96(%rsp) + pxor %xmm14,%xmm14 + pxor %xmm15,%xmm15 + movq -8(%r11),%rbp +.cfi_restore %rbp + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lxts_enc_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_xts_encrypt,.-aesni_xts_encrypt +.globl aesni_xts_decrypt +.type aesni_xts_decrypt,@function +.align 16 +aesni_xts_decrypt: +.cfi_startproc +.byte 243,15,30,250 + leaq (%rsp),%r11 +.cfi_def_cfa_register %r11 + pushq %rbp +.cfi_offset %rbp,-16 + subq $112,%rsp + andq $-16,%rsp + movups (%r9),%xmm2 + movl 240(%r8),%eax + movl 240(%rcx),%r10d + movups (%r8),%xmm0 + movups 16(%r8),%xmm1 + leaq 32(%r8),%r8 + xorps %xmm0,%xmm2 +.Loop_enc1_11: +.byte 102,15,56,220,209 + decl %eax + movups (%r8),%xmm1 + leaq 16(%r8),%r8 + jnz .Loop_enc1_11 +.byte 102,15,56,221,209 + xorl %eax,%eax + testq $15,%rdx + setnz %al + shlq $4,%rax + subq %rax,%rdx + + movups (%rcx),%xmm0 + movq %rcx,%rbp + movl %r10d,%eax + shll $4,%r10d + movq %rdx,%r9 + andq $-16,%rdx + + movups 16(%rcx,%r10,1),%xmm1 + + movdqa .Lxts_magic(%rip),%xmm8 + movdqa %xmm2,%xmm15 + pshufd $0x5f,%xmm2,%xmm9 + pxor %xmm0,%xmm1 + movdqa %xmm9,%xmm14 + paddd %xmm9,%xmm9 + movdqa %xmm15,%xmm10 + psrad $31,%xmm14 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 + pxor %xmm0,%xmm10 + pxor %xmm14,%xmm15 + movdqa %xmm9,%xmm14 + paddd %xmm9,%xmm9 + movdqa %xmm15,%xmm11 + psrad $31,%xmm14 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 + pxor %xmm0,%xmm11 + pxor %xmm14,%xmm15 + movdqa %xmm9,%xmm14 + paddd %xmm9,%xmm9 + movdqa %xmm15,%xmm12 + psrad $31,%xmm14 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 + pxor %xmm0,%xmm12 + pxor %xmm14,%xmm15 + movdqa %xmm9,%xmm14 + paddd %xmm9,%xmm9 + movdqa %xmm15,%xmm13 + psrad $31,%xmm14 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 + pxor %xmm0,%xmm13 + pxor %xmm14,%xmm15 + movdqa %xmm15,%xmm14 + psrad $31,%xmm9 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm9 + pxor %xmm0,%xmm14 + pxor %xmm9,%xmm15 + movaps %xmm1,96(%rsp) + + subq $96,%rdx + jc .Lxts_dec_short + + movl $16+96,%eax + leaq 32(%rbp,%r10,1),%rcx + subq %r10,%rax + movups 16(%rbp),%xmm1 + movq %rax,%r10 + leaq .Lxts_magic(%rip),%r8 + jmp .Lxts_dec_grandloop + +.align 32 +.Lxts_dec_grandloop: + movdqu 0(%rdi),%xmm2 + movdqa %xmm0,%xmm8 + movdqu 16(%rdi),%xmm3 + pxor %xmm10,%xmm2 + movdqu 32(%rdi),%xmm4 + pxor %xmm11,%xmm3 +.byte 102,15,56,222,209 + movdqu 48(%rdi),%xmm5 + pxor %xmm12,%xmm4 +.byte 102,15,56,222,217 + movdqu 64(%rdi),%xmm6 + pxor %xmm13,%xmm5 +.byte 102,15,56,222,225 + movdqu 80(%rdi),%xmm7 + pxor %xmm15,%xmm8 + movdqa 96(%rsp),%xmm9 + pxor %xmm14,%xmm6 +.byte 102,15,56,222,233 + movups 32(%rbp),%xmm0 + leaq 96(%rdi),%rdi + pxor %xmm8,%xmm7 + + pxor %xmm9,%xmm10 +.byte 102,15,56,222,241 + pxor %xmm9,%xmm11 + movdqa %xmm10,0(%rsp) +.byte 102,15,56,222,249 + movups 48(%rbp),%xmm1 + pxor %xmm9,%xmm12 + +.byte 102,15,56,222,208 + pxor %xmm9,%xmm13 + movdqa %xmm11,16(%rsp) +.byte 102,15,56,222,216 + pxor %xmm9,%xmm14 + movdqa %xmm12,32(%rsp) +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + pxor %xmm9,%xmm8 + movdqa %xmm14,64(%rsp) +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 + movups 64(%rbp),%xmm0 + movdqa %xmm8,80(%rsp) + pshufd $0x5f,%xmm15,%xmm9 + jmp .Lxts_dec_loop6 +.align 32 +.Lxts_dec_loop6: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + movups -64(%rcx,%rax,1),%xmm1 + addq $32,%rax + +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 + movups -80(%rcx,%rax,1),%xmm0 + jnz .Lxts_dec_loop6 + + movdqa (%r8),%xmm8 + movdqa %xmm9,%xmm14 + paddd %xmm9,%xmm9 +.byte 102,15,56,222,209 + paddq %xmm15,%xmm15 + psrad $31,%xmm14 +.byte 102,15,56,222,217 + pand %xmm8,%xmm14 + movups (%rbp),%xmm10 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 + pxor %xmm14,%xmm15 + movaps %xmm10,%xmm11 +.byte 102,15,56,222,249 + movups -64(%rcx),%xmm1 + + movdqa %xmm9,%xmm14 +.byte 102,15,56,222,208 + paddd %xmm9,%xmm9 + pxor %xmm15,%xmm10 +.byte 102,15,56,222,216 + psrad $31,%xmm14 + paddq %xmm15,%xmm15 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + pand %xmm8,%xmm14 + movaps %xmm11,%xmm12 +.byte 102,15,56,222,240 + pxor %xmm14,%xmm15 + movdqa %xmm9,%xmm14 +.byte 102,15,56,222,248 + movups -48(%rcx),%xmm0 + + paddd %xmm9,%xmm9 +.byte 102,15,56,222,209 + pxor %xmm15,%xmm11 + psrad $31,%xmm14 +.byte 102,15,56,222,217 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movdqa %xmm13,48(%rsp) + pxor %xmm14,%xmm15 +.byte 102,15,56,222,241 + movaps %xmm12,%xmm13 + movdqa %xmm9,%xmm14 +.byte 102,15,56,222,249 + movups -32(%rcx),%xmm1 + + paddd %xmm9,%xmm9 +.byte 102,15,56,222,208 + pxor %xmm15,%xmm12 + psrad $31,%xmm14 +.byte 102,15,56,222,216 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm14 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 + pxor %xmm14,%xmm15 + movaps %xmm13,%xmm14 +.byte 102,15,56,222,248 + + movdqa %xmm9,%xmm0 + paddd %xmm9,%xmm9 +.byte 102,15,56,222,209 + pxor %xmm15,%xmm13 + psrad $31,%xmm0 +.byte 102,15,56,222,217 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm0 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + pxor %xmm0,%xmm15 + movups (%rbp),%xmm0 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + movups 16(%rbp),%xmm1 + + pxor %xmm15,%xmm14 +.byte 102,15,56,223,84,36,0 + psrad $31,%xmm9 + paddq %xmm15,%xmm15 +.byte 102,15,56,223,92,36,16 +.byte 102,15,56,223,100,36,32 + pand %xmm8,%xmm9 + movq %r10,%rax +.byte 102,15,56,223,108,36,48 +.byte 102,15,56,223,116,36,64 +.byte 102,15,56,223,124,36,80 + pxor %xmm9,%xmm15 + + leaq 96(%rsi),%rsi + movups %xmm2,-96(%rsi) + movups %xmm3,-80(%rsi) + movups %xmm4,-64(%rsi) + movups %xmm5,-48(%rsi) + movups %xmm6,-32(%rsi) + movups %xmm7,-16(%rsi) + subq $96,%rdx + jnc .Lxts_dec_grandloop + + movl $16+96,%eax + subl %r10d,%eax + movq %rbp,%rcx + shrl $4,%eax + +.Lxts_dec_short: + + movl %eax,%r10d + pxor %xmm0,%xmm10 + pxor %xmm0,%xmm11 + addq $96,%rdx + jz .Lxts_dec_done + + pxor %xmm0,%xmm12 + cmpq $0x20,%rdx + jb .Lxts_dec_one + pxor %xmm0,%xmm13 + je .Lxts_dec_two + + pxor %xmm0,%xmm14 + cmpq $0x40,%rdx + jb .Lxts_dec_three + je .Lxts_dec_four + + movdqu (%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqu 32(%rdi),%xmm4 + pxor %xmm10,%xmm2 + movdqu 48(%rdi),%xmm5 + pxor %xmm11,%xmm3 + movdqu 64(%rdi),%xmm6 + leaq 80(%rdi),%rdi + pxor %xmm12,%xmm4 + pxor %xmm13,%xmm5 + pxor %xmm14,%xmm6 + + call _aesni_decrypt6 + + xorps %xmm10,%xmm2 + xorps %xmm11,%xmm3 + xorps %xmm12,%xmm4 + movdqu %xmm2,(%rsi) + xorps %xmm13,%xmm5 + movdqu %xmm3,16(%rsi) + xorps %xmm14,%xmm6 + movdqu %xmm4,32(%rsi) + pxor %xmm14,%xmm14 + movdqu %xmm5,48(%rsi) + pcmpgtd %xmm15,%xmm14 + movdqu %xmm6,64(%rsi) + leaq 80(%rsi),%rsi + pshufd $0x13,%xmm14,%xmm11 + andq $15,%r9 + jz .Lxts_dec_ret + + movdqa %xmm15,%xmm10 + paddq %xmm15,%xmm15 + pand %xmm8,%xmm11 + pxor %xmm15,%xmm11 + jmp .Lxts_dec_done2 + +.align 16 +.Lxts_dec_one: + movups (%rdi),%xmm2 + leaq 16(%rdi),%rdi + xorps %xmm10,%xmm2 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_dec1_12: +.byte 102,15,56,222,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_dec1_12 +.byte 102,15,56,223,209 + xorps %xmm10,%xmm2 + movdqa %xmm11,%xmm10 + movups %xmm2,(%rsi) + movdqa %xmm12,%xmm11 + leaq 16(%rsi),%rsi + jmp .Lxts_dec_done + +.align 16 +.Lxts_dec_two: + movups (%rdi),%xmm2 + movups 16(%rdi),%xmm3 + leaq 32(%rdi),%rdi + xorps %xmm10,%xmm2 + xorps %xmm11,%xmm3 + + call _aesni_decrypt2 + + xorps %xmm10,%xmm2 + movdqa %xmm12,%xmm10 + xorps %xmm11,%xmm3 + movdqa %xmm13,%xmm11 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + leaq 32(%rsi),%rsi + jmp .Lxts_dec_done + +.align 16 +.Lxts_dec_three: + movups (%rdi),%xmm2 + movups 16(%rdi),%xmm3 + movups 32(%rdi),%xmm4 + leaq 48(%rdi),%rdi + xorps %xmm10,%xmm2 + xorps %xmm11,%xmm3 + xorps %xmm12,%xmm4 + + call _aesni_decrypt3 + + xorps %xmm10,%xmm2 + movdqa %xmm13,%xmm10 + xorps %xmm11,%xmm3 + movdqa %xmm14,%xmm11 + xorps %xmm12,%xmm4 + movups %xmm2,(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + leaq 48(%rsi),%rsi + jmp .Lxts_dec_done + +.align 16 +.Lxts_dec_four: + movups (%rdi),%xmm2 + movups 16(%rdi),%xmm3 + movups 32(%rdi),%xmm4 + xorps %xmm10,%xmm2 + movups 48(%rdi),%xmm5 + leaq 64(%rdi),%rdi + xorps %xmm11,%xmm3 + xorps %xmm12,%xmm4 + xorps %xmm13,%xmm5 + + call _aesni_decrypt4 + + pxor %xmm10,%xmm2 + movdqa %xmm14,%xmm10 + pxor %xmm11,%xmm3 + movdqa %xmm15,%xmm11 + pxor %xmm12,%xmm4 + movdqu %xmm2,(%rsi) + pxor %xmm13,%xmm5 + movdqu %xmm3,16(%rsi) + movdqu %xmm4,32(%rsi) + movdqu %xmm5,48(%rsi) + leaq 64(%rsi),%rsi + jmp .Lxts_dec_done + +.align 16 +.Lxts_dec_done: + andq $15,%r9 + jz .Lxts_dec_ret +.Lxts_dec_done2: + movq %r9,%rdx + movq %rbp,%rcx + movl %r10d,%eax + + movups (%rdi),%xmm2 + xorps %xmm11,%xmm2 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_dec1_13: +.byte 102,15,56,222,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_dec1_13 +.byte 102,15,56,223,209 + xorps %xmm11,%xmm2 + movups %xmm2,(%rsi) + +.Lxts_dec_steal: + movzbl 16(%rdi),%eax + movzbl (%rsi),%ecx + leaq 1(%rdi),%rdi + movb %al,(%rsi) + movb %cl,16(%rsi) + leaq 1(%rsi),%rsi + subq $1,%rdx + jnz .Lxts_dec_steal + + subq %r9,%rsi + movq %rbp,%rcx + movl %r10d,%eax + + movups (%rsi),%xmm2 + xorps %xmm10,%xmm2 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_dec1_14: +.byte 102,15,56,222,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_dec1_14 +.byte 102,15,56,223,209 + xorps %xmm10,%xmm2 + movups %xmm2,(%rsi) + +.Lxts_dec_ret: + xorps %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + movaps %xmm0,0(%rsp) + pxor %xmm8,%xmm8 + movaps %xmm0,16(%rsp) + pxor %xmm9,%xmm9 + movaps %xmm0,32(%rsp) + pxor %xmm10,%xmm10 + movaps %xmm0,48(%rsp) + pxor %xmm11,%xmm11 + movaps %xmm0,64(%rsp) + pxor %xmm12,%xmm12 + movaps %xmm0,80(%rsp) + pxor %xmm13,%xmm13 + movaps %xmm0,96(%rsp) + pxor %xmm14,%xmm14 + pxor %xmm15,%xmm15 + movq -8(%r11),%rbp +.cfi_restore %rbp + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lxts_dec_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_xts_decrypt,.-aesni_xts_decrypt +.globl aesni_ocb_encrypt +.type aesni_ocb_encrypt,@function +.align 32 +aesni_ocb_encrypt: +.cfi_startproc +.byte 243,15,30,250 + leaq (%rsp),%rax + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + movq 8(%rax),%rbx + movq 8+8(%rax),%rbp + + movl 240(%rcx),%r10d + movq %rcx,%r11 + shll $4,%r10d + movups (%rcx),%xmm9 + movups 16(%rcx,%r10,1),%xmm1 + + movdqu (%r9),%xmm15 + pxor %xmm1,%xmm9 + pxor %xmm1,%xmm15 + + movl $16+32,%eax + leaq 32(%r11,%r10,1),%rcx + movups 16(%r11),%xmm1 + subq %r10,%rax + movq %rax,%r10 + + movdqu (%rbx),%xmm10 + movdqu (%rbp),%xmm8 + + testq $1,%r8 + jnz .Locb_enc_odd + + bsfq %r8,%r12 + addq $1,%r8 + shlq $4,%r12 + movdqu (%rbx,%r12,1),%xmm7 + movdqu (%rdi),%xmm2 + leaq 16(%rdi),%rdi + + call __ocb_encrypt1 + + movdqa %xmm7,%xmm15 + movups %xmm2,(%rsi) + leaq 16(%rsi),%rsi + subq $1,%rdx + jz .Locb_enc_done + +.Locb_enc_odd: + leaq 1(%r8),%r12 + leaq 3(%r8),%r13 + leaq 5(%r8),%r14 + leaq 6(%r8),%r8 + bsfq %r12,%r12 + bsfq %r13,%r13 + bsfq %r14,%r14 + shlq $4,%r12 + shlq $4,%r13 + shlq $4,%r14 + + subq $6,%rdx + jc .Locb_enc_short + jmp .Locb_enc_grandloop + +.align 32 +.Locb_enc_grandloop: + movdqu 0(%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqu 32(%rdi),%xmm4 + movdqu 48(%rdi),%xmm5 + movdqu 64(%rdi),%xmm6 + movdqu 80(%rdi),%xmm7 + leaq 96(%rdi),%rdi + + call __ocb_encrypt6 + + movups %xmm2,0(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + movups %xmm7,80(%rsi) + leaq 96(%rsi),%rsi + subq $6,%rdx + jnc .Locb_enc_grandloop + +.Locb_enc_short: + addq $6,%rdx + jz .Locb_enc_done + + movdqu 0(%rdi),%xmm2 + cmpq $2,%rdx + jb .Locb_enc_one + movdqu 16(%rdi),%xmm3 + je .Locb_enc_two + + movdqu 32(%rdi),%xmm4 + cmpq $4,%rdx + jb .Locb_enc_three + movdqu 48(%rdi),%xmm5 + je .Locb_enc_four + + movdqu 64(%rdi),%xmm6 + pxor %xmm7,%xmm7 + + call __ocb_encrypt6 + + movdqa %xmm14,%xmm15 + movups %xmm2,0(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + movups %xmm6,64(%rsi) + + jmp .Locb_enc_done + +.align 16 +.Locb_enc_one: + movdqa %xmm10,%xmm7 + + call __ocb_encrypt1 + + movdqa %xmm7,%xmm15 + movups %xmm2,0(%rsi) + jmp .Locb_enc_done + +.align 16 +.Locb_enc_two: + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + + call __ocb_encrypt4 + + movdqa %xmm11,%xmm15 + movups %xmm2,0(%rsi) + movups %xmm3,16(%rsi) + + jmp .Locb_enc_done + +.align 16 +.Locb_enc_three: + pxor %xmm5,%xmm5 + + call __ocb_encrypt4 + + movdqa %xmm12,%xmm15 + movups %xmm2,0(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + + jmp .Locb_enc_done + +.align 16 +.Locb_enc_four: + call __ocb_encrypt4 + + movdqa %xmm13,%xmm15 + movups %xmm2,0(%rsi) + movups %xmm3,16(%rsi) + movups %xmm4,32(%rsi) + movups %xmm5,48(%rsi) + +.Locb_enc_done: + pxor %xmm0,%xmm15 + movdqu %xmm8,(%rbp) + movdqu %xmm15,(%r9) + + xorps %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 + pxor %xmm10,%xmm10 + pxor %xmm11,%xmm11 + pxor %xmm12,%xmm12 + pxor %xmm13,%xmm13 + pxor %xmm14,%xmm14 + pxor %xmm15,%xmm15 + leaq 40(%rsp),%rax +.cfi_def_cfa %rax,8 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Locb_enc_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_ocb_encrypt,.-aesni_ocb_encrypt + +.type __ocb_encrypt6,@function +.align 32 +__ocb_encrypt6: +.cfi_startproc + pxor %xmm9,%xmm15 + movdqu (%rbx,%r12,1),%xmm11 + movdqa %xmm10,%xmm12 + movdqu (%rbx,%r13,1),%xmm13 + movdqa %xmm10,%xmm14 + pxor %xmm15,%xmm10 + movdqu (%rbx,%r14,1),%xmm15 + pxor %xmm10,%xmm11 + pxor %xmm2,%xmm8 + pxor %xmm10,%xmm2 + pxor %xmm11,%xmm12 + pxor %xmm3,%xmm8 + pxor %xmm11,%xmm3 + pxor %xmm12,%xmm13 + pxor %xmm4,%xmm8 + pxor %xmm12,%xmm4 + pxor %xmm13,%xmm14 + pxor %xmm5,%xmm8 + pxor %xmm13,%xmm5 + pxor %xmm14,%xmm15 + pxor %xmm6,%xmm8 + pxor %xmm14,%xmm6 + pxor %xmm7,%xmm8 + pxor %xmm15,%xmm7 + movups 32(%r11),%xmm0 + + leaq 1(%r8),%r12 + leaq 3(%r8),%r13 + leaq 5(%r8),%r14 + addq $6,%r8 + pxor %xmm9,%xmm10 + bsfq %r12,%r12 + bsfq %r13,%r13 + bsfq %r14,%r14 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + pxor %xmm9,%xmm11 + pxor %xmm9,%xmm12 +.byte 102,15,56,220,241 + pxor %xmm9,%xmm13 + pxor %xmm9,%xmm14 +.byte 102,15,56,220,249 + movups 48(%r11),%xmm1 + pxor %xmm9,%xmm15 + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups 64(%r11),%xmm0 + shlq $4,%r12 + shlq $4,%r13 + jmp .Locb_enc_loop6 + +.align 32 +.Locb_enc_loop6: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 +.byte 102,15,56,220,240 +.byte 102,15,56,220,248 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Locb_enc_loop6 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 +.byte 102,15,56,220,241 +.byte 102,15,56,220,249 + movups 16(%r11),%xmm1 + shlq $4,%r14 + +.byte 102,65,15,56,221,210 + movdqu (%rbx),%xmm10 + movq %r10,%rax +.byte 102,65,15,56,221,219 +.byte 102,65,15,56,221,228 +.byte 102,65,15,56,221,237 +.byte 102,65,15,56,221,246 +.byte 102,65,15,56,221,255 + .byte 0xf3,0xc3 +.cfi_endproc +.size __ocb_encrypt6,.-__ocb_encrypt6 + +.type __ocb_encrypt4,@function +.align 32 +__ocb_encrypt4: +.cfi_startproc + pxor %xmm9,%xmm15 + movdqu (%rbx,%r12,1),%xmm11 + movdqa %xmm10,%xmm12 + movdqu (%rbx,%r13,1),%xmm13 + pxor %xmm15,%xmm10 + pxor %xmm10,%xmm11 + pxor %xmm2,%xmm8 + pxor %xmm10,%xmm2 + pxor %xmm11,%xmm12 + pxor %xmm3,%xmm8 + pxor %xmm11,%xmm3 + pxor %xmm12,%xmm13 + pxor %xmm4,%xmm8 + pxor %xmm12,%xmm4 + pxor %xmm5,%xmm8 + pxor %xmm13,%xmm5 + movups 32(%r11),%xmm0 + + pxor %xmm9,%xmm10 + pxor %xmm9,%xmm11 + pxor %xmm9,%xmm12 + pxor %xmm9,%xmm13 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups 48(%r11),%xmm1 + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movups 64(%r11),%xmm0 + jmp .Locb_enc_loop4 + +.align 32 +.Locb_enc_loop4: +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax + +.byte 102,15,56,220,208 +.byte 102,15,56,220,216 +.byte 102,15,56,220,224 +.byte 102,15,56,220,232 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Locb_enc_loop4 + +.byte 102,15,56,220,209 +.byte 102,15,56,220,217 +.byte 102,15,56,220,225 +.byte 102,15,56,220,233 + movups 16(%r11),%xmm1 + movq %r10,%rax + +.byte 102,65,15,56,221,210 +.byte 102,65,15,56,221,219 +.byte 102,65,15,56,221,228 +.byte 102,65,15,56,221,237 + .byte 0xf3,0xc3 +.cfi_endproc +.size __ocb_encrypt4,.-__ocb_encrypt4 + +.type __ocb_encrypt1,@function +.align 32 +__ocb_encrypt1: +.cfi_startproc + pxor %xmm15,%xmm7 + pxor %xmm9,%xmm7 + pxor %xmm2,%xmm8 + pxor %xmm7,%xmm2 + movups 32(%r11),%xmm0 + +.byte 102,15,56,220,209 + movups 48(%r11),%xmm1 + pxor %xmm9,%xmm7 + +.byte 102,15,56,220,208 + movups 64(%r11),%xmm0 + jmp .Locb_enc_loop1 + +.align 32 +.Locb_enc_loop1: +.byte 102,15,56,220,209 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax + +.byte 102,15,56,220,208 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Locb_enc_loop1 + +.byte 102,15,56,220,209 + movups 16(%r11),%xmm1 + movq %r10,%rax + +.byte 102,15,56,221,215 + .byte 0xf3,0xc3 +.cfi_endproc +.size __ocb_encrypt1,.-__ocb_encrypt1 + +.globl aesni_ocb_decrypt +.type aesni_ocb_decrypt,@function +.align 32 +aesni_ocb_decrypt: +.cfi_startproc +.byte 243,15,30,250 + leaq (%rsp),%rax + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + movq 8(%rax),%rbx + movq 8+8(%rax),%rbp + + movl 240(%rcx),%r10d + movq %rcx,%r11 + shll $4,%r10d + movups (%rcx),%xmm9 + movups 16(%rcx,%r10,1),%xmm1 + + movdqu (%r9),%xmm15 + pxor %xmm1,%xmm9 + pxor %xmm1,%xmm15 + + movl $16+32,%eax + leaq 32(%r11,%r10,1),%rcx + movups 16(%r11),%xmm1 + subq %r10,%rax + movq %rax,%r10 + + movdqu (%rbx),%xmm10 + movdqu (%rbp),%xmm8 + + testq $1,%r8 + jnz .Locb_dec_odd + + bsfq %r8,%r12 + addq $1,%r8 + shlq $4,%r12 + movdqu (%rbx,%r12,1),%xmm7 + movdqu (%rdi),%xmm2 + leaq 16(%rdi),%rdi + + call __ocb_decrypt1 + + movdqa %xmm7,%xmm15 + movups %xmm2,(%rsi) + xorps %xmm2,%xmm8 + leaq 16(%rsi),%rsi + subq $1,%rdx + jz .Locb_dec_done + +.Locb_dec_odd: + leaq 1(%r8),%r12 + leaq 3(%r8),%r13 + leaq 5(%r8),%r14 + leaq 6(%r8),%r8 + bsfq %r12,%r12 + bsfq %r13,%r13 + bsfq %r14,%r14 + shlq $4,%r12 + shlq $4,%r13 + shlq $4,%r14 + + subq $6,%rdx + jc .Locb_dec_short + jmp .Locb_dec_grandloop + +.align 32 +.Locb_dec_grandloop: + movdqu 0(%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqu 32(%rdi),%xmm4 + movdqu 48(%rdi),%xmm5 + movdqu 64(%rdi),%xmm6 + movdqu 80(%rdi),%xmm7 + leaq 96(%rdi),%rdi + + call __ocb_decrypt6 + + movups %xmm2,0(%rsi) + pxor %xmm2,%xmm8 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm8 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm8 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm8 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm8 + movups %xmm7,80(%rsi) + pxor %xmm7,%xmm8 + leaq 96(%rsi),%rsi + subq $6,%rdx + jnc .Locb_dec_grandloop + +.Locb_dec_short: + addq $6,%rdx + jz .Locb_dec_done + + movdqu 0(%rdi),%xmm2 + cmpq $2,%rdx + jb .Locb_dec_one + movdqu 16(%rdi),%xmm3 + je .Locb_dec_two + + movdqu 32(%rdi),%xmm4 + cmpq $4,%rdx + jb .Locb_dec_three + movdqu 48(%rdi),%xmm5 + je .Locb_dec_four + + movdqu 64(%rdi),%xmm6 + pxor %xmm7,%xmm7 + + call __ocb_decrypt6 + + movdqa %xmm14,%xmm15 + movups %xmm2,0(%rsi) + pxor %xmm2,%xmm8 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm8 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm8 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm8 + movups %xmm6,64(%rsi) + pxor %xmm6,%xmm8 + + jmp .Locb_dec_done + +.align 16 +.Locb_dec_one: + movdqa %xmm10,%xmm7 + + call __ocb_decrypt1 + + movdqa %xmm7,%xmm15 + movups %xmm2,0(%rsi) + xorps %xmm2,%xmm8 + jmp .Locb_dec_done + +.align 16 +.Locb_dec_two: + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + + call __ocb_decrypt4 + + movdqa %xmm11,%xmm15 + movups %xmm2,0(%rsi) + xorps %xmm2,%xmm8 + movups %xmm3,16(%rsi) + xorps %xmm3,%xmm8 + + jmp .Locb_dec_done + +.align 16 +.Locb_dec_three: + pxor %xmm5,%xmm5 + + call __ocb_decrypt4 + + movdqa %xmm12,%xmm15 + movups %xmm2,0(%rsi) + xorps %xmm2,%xmm8 + movups %xmm3,16(%rsi) + xorps %xmm3,%xmm8 + movups %xmm4,32(%rsi) + xorps %xmm4,%xmm8 + + jmp .Locb_dec_done + +.align 16 +.Locb_dec_four: + call __ocb_decrypt4 + + movdqa %xmm13,%xmm15 + movups %xmm2,0(%rsi) + pxor %xmm2,%xmm8 + movups %xmm3,16(%rsi) + pxor %xmm3,%xmm8 + movups %xmm4,32(%rsi) + pxor %xmm4,%xmm8 + movups %xmm5,48(%rsi) + pxor %xmm5,%xmm8 + +.Locb_dec_done: + pxor %xmm0,%xmm15 + movdqu %xmm8,(%rbp) + movdqu %xmm15,(%r9) + + xorps %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 + pxor %xmm10,%xmm10 + pxor %xmm11,%xmm11 + pxor %xmm12,%xmm12 + pxor %xmm13,%xmm13 + pxor %xmm14,%xmm14 + pxor %xmm15,%xmm15 + leaq 40(%rsp),%rax +.cfi_def_cfa %rax,8 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Locb_dec_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_ocb_decrypt,.-aesni_ocb_decrypt + +.type __ocb_decrypt6,@function +.align 32 +__ocb_decrypt6: +.cfi_startproc + pxor %xmm9,%xmm15 + movdqu (%rbx,%r12,1),%xmm11 + movdqa %xmm10,%xmm12 + movdqu (%rbx,%r13,1),%xmm13 + movdqa %xmm10,%xmm14 + pxor %xmm15,%xmm10 + movdqu (%rbx,%r14,1),%xmm15 + pxor %xmm10,%xmm11 + pxor %xmm10,%xmm2 + pxor %xmm11,%xmm12 + pxor %xmm11,%xmm3 + pxor %xmm12,%xmm13 + pxor %xmm12,%xmm4 + pxor %xmm13,%xmm14 + pxor %xmm13,%xmm5 + pxor %xmm14,%xmm15 + pxor %xmm14,%xmm6 + pxor %xmm15,%xmm7 + movups 32(%r11),%xmm0 + + leaq 1(%r8),%r12 + leaq 3(%r8),%r13 + leaq 5(%r8),%r14 + addq $6,%r8 + pxor %xmm9,%xmm10 + bsfq %r12,%r12 + bsfq %r13,%r13 + bsfq %r14,%r14 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + pxor %xmm9,%xmm11 + pxor %xmm9,%xmm12 +.byte 102,15,56,222,241 + pxor %xmm9,%xmm13 + pxor %xmm9,%xmm14 +.byte 102,15,56,222,249 + movups 48(%r11),%xmm1 + pxor %xmm9,%xmm15 + +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 + movups 64(%r11),%xmm0 + shlq $4,%r12 + shlq $4,%r13 + jmp .Locb_dec_loop6 + +.align 32 +.Locb_dec_loop6: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax + +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Locb_dec_loop6 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + movups 16(%r11),%xmm1 + shlq $4,%r14 + +.byte 102,65,15,56,223,210 + movdqu (%rbx),%xmm10 + movq %r10,%rax +.byte 102,65,15,56,223,219 +.byte 102,65,15,56,223,228 +.byte 102,65,15,56,223,237 +.byte 102,65,15,56,223,246 +.byte 102,65,15,56,223,255 + .byte 0xf3,0xc3 +.cfi_endproc +.size __ocb_decrypt6,.-__ocb_decrypt6 + +.type __ocb_decrypt4,@function +.align 32 +__ocb_decrypt4: +.cfi_startproc + pxor %xmm9,%xmm15 + movdqu (%rbx,%r12,1),%xmm11 + movdqa %xmm10,%xmm12 + movdqu (%rbx,%r13,1),%xmm13 + pxor %xmm15,%xmm10 + pxor %xmm10,%xmm11 + pxor %xmm10,%xmm2 + pxor %xmm11,%xmm12 + pxor %xmm11,%xmm3 + pxor %xmm12,%xmm13 + pxor %xmm12,%xmm4 + pxor %xmm13,%xmm5 + movups 32(%r11),%xmm0 + + pxor %xmm9,%xmm10 + pxor %xmm9,%xmm11 + pxor %xmm9,%xmm12 + pxor %xmm9,%xmm13 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups 48(%r11),%xmm1 + +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + movups 64(%r11),%xmm0 + jmp .Locb_dec_loop4 + +.align 32 +.Locb_dec_loop4: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax + +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Locb_dec_loop4 + +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + movups 16(%r11),%xmm1 + movq %r10,%rax + +.byte 102,65,15,56,223,210 +.byte 102,65,15,56,223,219 +.byte 102,65,15,56,223,228 +.byte 102,65,15,56,223,237 + .byte 0xf3,0xc3 +.cfi_endproc +.size __ocb_decrypt4,.-__ocb_decrypt4 + +.type __ocb_decrypt1,@function +.align 32 +__ocb_decrypt1: +.cfi_startproc + pxor %xmm15,%xmm7 + pxor %xmm9,%xmm7 + pxor %xmm7,%xmm2 + movups 32(%r11),%xmm0 + +.byte 102,15,56,222,209 + movups 48(%r11),%xmm1 + pxor %xmm9,%xmm7 + +.byte 102,15,56,222,208 + movups 64(%r11),%xmm0 + jmp .Locb_dec_loop1 + +.align 32 +.Locb_dec_loop1: +.byte 102,15,56,222,209 + movups (%rcx,%rax,1),%xmm1 + addq $32,%rax + +.byte 102,15,56,222,208 + movups -16(%rcx,%rax,1),%xmm0 + jnz .Locb_dec_loop1 + +.byte 102,15,56,222,209 + movups 16(%r11),%xmm1 + movq %r10,%rax + +.byte 102,15,56,223,215 + .byte 0xf3,0xc3 +.cfi_endproc +.size __ocb_decrypt1,.-__ocb_decrypt1 +.globl aesni_cbc_encrypt +.type aesni_cbc_encrypt,@function +.align 16 +aesni_cbc_encrypt: +.cfi_startproc +.byte 243,15,30,250 + testq %rdx,%rdx + jz .Lcbc_ret + + movl 240(%rcx),%r10d + movq %rcx,%r11 + testl %r9d,%r9d + jz .Lcbc_decrypt + + movups (%r8),%xmm2 + movl %r10d,%eax + cmpq $16,%rdx + jb .Lcbc_enc_tail + subq $16,%rdx + jmp .Lcbc_enc_loop +.align 16 +.Lcbc_enc_loop: + movups (%rdi),%xmm3 + leaq 16(%rdi),%rdi + + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + xorps %xmm0,%xmm3 + leaq 32(%rcx),%rcx + xorps %xmm3,%xmm2 +.Loop_enc1_15: +.byte 102,15,56,220,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_enc1_15 +.byte 102,15,56,221,209 + movl %r10d,%eax + movq %r11,%rcx + movups %xmm2,0(%rsi) + leaq 16(%rsi),%rsi + subq $16,%rdx + jnc .Lcbc_enc_loop + addq $16,%rdx + jnz .Lcbc_enc_tail + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movups %xmm2,(%r8) + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + jmp .Lcbc_ret + +.Lcbc_enc_tail: + movq %rdx,%rcx + xchgq %rdi,%rsi +.long 0x9066A4F3 + movl $16,%ecx + subq %rdx,%rcx + xorl %eax,%eax +.long 0x9066AAF3 + leaq -16(%rdi),%rdi + movl %r10d,%eax + movq %rdi,%rsi + movq %r11,%rcx + xorq %rdx,%rdx + jmp .Lcbc_enc_loop + +.align 16 +.Lcbc_decrypt: + cmpq $16,%rdx + jne .Lcbc_decrypt_bulk + + + + movdqu (%rdi),%xmm2 + movdqu (%r8),%xmm3 + movdqa %xmm2,%xmm4 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_dec1_16: +.byte 102,15,56,222,209 + decl %r10d + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_dec1_16 +.byte 102,15,56,223,209 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movdqu %xmm4,(%r8) + xorps %xmm3,%xmm2 + pxor %xmm3,%xmm3 + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + jmp .Lcbc_ret +.align 16 +.Lcbc_decrypt_bulk: + leaq (%rsp),%r11 +.cfi_def_cfa_register %r11 + pushq %rbp +.cfi_offset %rbp,-16 + subq $16,%rsp + andq $-16,%rsp + movq %rcx,%rbp + movups (%r8),%xmm10 + movl %r10d,%eax + cmpq $0x50,%rdx + jbe .Lcbc_dec_tail + + movups (%rcx),%xmm0 + movdqu 0(%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqa %xmm2,%xmm11 + movdqu 32(%rdi),%xmm4 + movdqa %xmm3,%xmm12 + movdqu 48(%rdi),%xmm5 + movdqa %xmm4,%xmm13 + movdqu 64(%rdi),%xmm6 + movdqa %xmm5,%xmm14 + movdqu 80(%rdi),%xmm7 + movdqa %xmm6,%xmm15 + movl OPENSSL_ia32cap_P+4(%rip),%r9d + cmpq $0x70,%rdx + jbe .Lcbc_dec_six_or_seven + + andl $71303168,%r9d + subq $0x50,%rdx + cmpl $4194304,%r9d + je .Lcbc_dec_loop6_enter + subq $0x20,%rdx + leaq 112(%rcx),%rcx + jmp .Lcbc_dec_loop8_enter +.align 16 +.Lcbc_dec_loop8: + movups %xmm9,(%rsi) + leaq 16(%rsi),%rsi +.Lcbc_dec_loop8_enter: + movdqu 96(%rdi),%xmm8 + pxor %xmm0,%xmm2 + movdqu 112(%rdi),%xmm9 + pxor %xmm0,%xmm3 + movups 16-112(%rcx),%xmm1 + pxor %xmm0,%xmm4 + movq $-1,%rbp + cmpq $0x70,%rdx + pxor %xmm0,%xmm5 + pxor %xmm0,%xmm6 + pxor %xmm0,%xmm7 + pxor %xmm0,%xmm8 + +.byte 102,15,56,222,209 + pxor %xmm0,%xmm9 + movups 32-112(%rcx),%xmm0 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 + adcq $0,%rbp + andq $128,%rbp +.byte 102,68,15,56,222,201 + addq %rdi,%rbp + movups 48-112(%rcx),%xmm1 +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 64-112(%rcx),%xmm0 + nop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 80-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 96-112(%rcx),%xmm0 + nop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 112-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 128-112(%rcx),%xmm0 + nop +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 144-112(%rcx),%xmm1 + cmpl $11,%eax +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 160-112(%rcx),%xmm0 + jb .Lcbc_dec_done +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 176-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 192-112(%rcx),%xmm0 + je .Lcbc_dec_done +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movups 208-112(%rcx),%xmm1 + nop +.byte 102,15,56,222,208 +.byte 102,15,56,222,216 +.byte 102,15,56,222,224 +.byte 102,15,56,222,232 +.byte 102,15,56,222,240 +.byte 102,15,56,222,248 +.byte 102,68,15,56,222,192 +.byte 102,68,15,56,222,200 + movups 224-112(%rcx),%xmm0 + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_done: +.byte 102,15,56,222,209 +.byte 102,15,56,222,217 + pxor %xmm0,%xmm10 + pxor %xmm0,%xmm11 +.byte 102,15,56,222,225 +.byte 102,15,56,222,233 + pxor %xmm0,%xmm12 + pxor %xmm0,%xmm13 +.byte 102,15,56,222,241 +.byte 102,15,56,222,249 + pxor %xmm0,%xmm14 + pxor %xmm0,%xmm15 +.byte 102,68,15,56,222,193 +.byte 102,68,15,56,222,201 + movdqu 80(%rdi),%xmm1 + +.byte 102,65,15,56,223,210 + movdqu 96(%rdi),%xmm10 + pxor %xmm0,%xmm1 +.byte 102,65,15,56,223,219 + pxor %xmm0,%xmm10 + movdqu 112(%rdi),%xmm0 +.byte 102,65,15,56,223,228 + leaq 128(%rdi),%rdi + movdqu 0(%rbp),%xmm11 +.byte 102,65,15,56,223,237 +.byte 102,65,15,56,223,246 + movdqu 16(%rbp),%xmm12 + movdqu 32(%rbp),%xmm13 +.byte 102,65,15,56,223,255 +.byte 102,68,15,56,223,193 + movdqu 48(%rbp),%xmm14 + movdqu 64(%rbp),%xmm15 +.byte 102,69,15,56,223,202 + movdqa %xmm0,%xmm10 + movdqu 80(%rbp),%xmm1 + movups -112(%rcx),%xmm0 + + movups %xmm2,(%rsi) + movdqa %xmm11,%xmm2 + movups %xmm3,16(%rsi) + movdqa %xmm12,%xmm3 + movups %xmm4,32(%rsi) + movdqa %xmm13,%xmm4 + movups %xmm5,48(%rsi) + movdqa %xmm14,%xmm5 + movups %xmm6,64(%rsi) + movdqa %xmm15,%xmm6 + movups %xmm7,80(%rsi) + movdqa %xmm1,%xmm7 + movups %xmm8,96(%rsi) + leaq 112(%rsi),%rsi + + subq $0x80,%rdx + ja .Lcbc_dec_loop8 + + movaps %xmm9,%xmm2 + leaq -112(%rcx),%rcx + addq $0x70,%rdx + jle .Lcbc_dec_clear_tail_collected + movups %xmm9,(%rsi) + leaq 16(%rsi),%rsi + cmpq $0x50,%rdx + jbe .Lcbc_dec_tail + + movaps %xmm11,%xmm2 +.Lcbc_dec_six_or_seven: + cmpq $0x60,%rdx + ja .Lcbc_dec_seven + + movaps %xmm7,%xmm8 + call _aesni_decrypt6 + pxor %xmm10,%xmm2 + movaps %xmm8,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + pxor %xmm14,%xmm6 + movdqu %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + pxor %xmm15,%xmm7 + movdqu %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + leaq 80(%rsi),%rsi + movdqa %xmm7,%xmm2 + pxor %xmm7,%xmm7 + jmp .Lcbc_dec_tail_collected + +.align 16 +.Lcbc_dec_seven: + movups 96(%rdi),%xmm8 + xorps %xmm9,%xmm9 + call _aesni_decrypt8 + movups 80(%rdi),%xmm9 + pxor %xmm10,%xmm2 + movups 96(%rdi),%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + pxor %xmm14,%xmm6 + movdqu %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + pxor %xmm15,%xmm7 + movdqu %xmm6,64(%rsi) + pxor %xmm6,%xmm6 + pxor %xmm9,%xmm8 + movdqu %xmm7,80(%rsi) + pxor %xmm7,%xmm7 + leaq 96(%rsi),%rsi + movdqa %xmm8,%xmm2 + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 + jmp .Lcbc_dec_tail_collected + +.align 16 +.Lcbc_dec_loop6: + movups %xmm7,(%rsi) + leaq 16(%rsi),%rsi + movdqu 0(%rdi),%xmm2 + movdqu 16(%rdi),%xmm3 + movdqa %xmm2,%xmm11 + movdqu 32(%rdi),%xmm4 + movdqa %xmm3,%xmm12 + movdqu 48(%rdi),%xmm5 + movdqa %xmm4,%xmm13 + movdqu 64(%rdi),%xmm6 + movdqa %xmm5,%xmm14 + movdqu 80(%rdi),%xmm7 + movdqa %xmm6,%xmm15 +.Lcbc_dec_loop6_enter: + leaq 96(%rdi),%rdi + movdqa %xmm7,%xmm8 + + call _aesni_decrypt6 + + pxor %xmm10,%xmm2 + movdqa %xmm8,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm14,%xmm6 + movq %rbp,%rcx + movdqu %xmm5,48(%rsi) + pxor %xmm15,%xmm7 + movl %r10d,%eax + movdqu %xmm6,64(%rsi) + leaq 80(%rsi),%rsi + subq $0x60,%rdx + ja .Lcbc_dec_loop6 + + movdqa %xmm7,%xmm2 + addq $0x50,%rdx + jle .Lcbc_dec_clear_tail_collected + movups %xmm7,(%rsi) + leaq 16(%rsi),%rsi + +.Lcbc_dec_tail: + movups (%rdi),%xmm2 + subq $0x10,%rdx + jbe .Lcbc_dec_one + + movups 16(%rdi),%xmm3 + movaps %xmm2,%xmm11 + subq $0x10,%rdx + jbe .Lcbc_dec_two + + movups 32(%rdi),%xmm4 + movaps %xmm3,%xmm12 + subq $0x10,%rdx + jbe .Lcbc_dec_three + + movups 48(%rdi),%xmm5 + movaps %xmm4,%xmm13 + subq $0x10,%rdx + jbe .Lcbc_dec_four + + movups 64(%rdi),%xmm6 + movaps %xmm5,%xmm14 + movaps %xmm6,%xmm15 + xorps %xmm7,%xmm7 + call _aesni_decrypt6 + pxor %xmm10,%xmm2 + movaps %xmm15,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + pxor %xmm14,%xmm6 + movdqu %xmm5,48(%rsi) + pxor %xmm5,%xmm5 + leaq 64(%rsi),%rsi + movdqa %xmm6,%xmm2 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + subq $0x10,%rdx + jmp .Lcbc_dec_tail_collected + +.align 16 +.Lcbc_dec_one: + movaps %xmm2,%xmm11 + movups (%rcx),%xmm0 + movups 16(%rcx),%xmm1 + leaq 32(%rcx),%rcx + xorps %xmm0,%xmm2 +.Loop_dec1_17: +.byte 102,15,56,222,209 + decl %eax + movups (%rcx),%xmm1 + leaq 16(%rcx),%rcx + jnz .Loop_dec1_17 +.byte 102,15,56,223,209 + xorps %xmm10,%xmm2 + movaps %xmm11,%xmm10 + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_two: + movaps %xmm3,%xmm12 + call _aesni_decrypt2 + pxor %xmm10,%xmm2 + movaps %xmm12,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + movdqa %xmm3,%xmm2 + pxor %xmm3,%xmm3 + leaq 16(%rsi),%rsi + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_three: + movaps %xmm4,%xmm13 + call _aesni_decrypt3 + pxor %xmm10,%xmm2 + movaps %xmm13,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + movdqa %xmm4,%xmm2 + pxor %xmm4,%xmm4 + leaq 32(%rsi),%rsi + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_four: + movaps %xmm5,%xmm14 + call _aesni_decrypt4 + pxor %xmm10,%xmm2 + movaps %xmm14,%xmm10 + pxor %xmm11,%xmm3 + movdqu %xmm2,(%rsi) + pxor %xmm12,%xmm4 + movdqu %xmm3,16(%rsi) + pxor %xmm3,%xmm3 + pxor %xmm13,%xmm5 + movdqu %xmm4,32(%rsi) + pxor %xmm4,%xmm4 + movdqa %xmm5,%xmm2 + pxor %xmm5,%xmm5 + leaq 48(%rsi),%rsi + jmp .Lcbc_dec_tail_collected + +.align 16 +.Lcbc_dec_clear_tail_collected: + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 +.Lcbc_dec_tail_collected: + movups %xmm10,(%r8) + andq $15,%rdx + jnz .Lcbc_dec_tail_partial + movups %xmm2,(%rsi) + pxor %xmm2,%xmm2 + jmp .Lcbc_dec_ret +.align 16 +.Lcbc_dec_tail_partial: + movaps %xmm2,(%rsp) + pxor %xmm2,%xmm2 + movq $16,%rcx + movq %rsi,%rdi + subq %rdx,%rcx + leaq (%rsp),%rsi +.long 0x9066A4F3 + movdqa %xmm2,(%rsp) + +.Lcbc_dec_ret: + xorps %xmm0,%xmm0 + pxor %xmm1,%xmm1 + movq -8(%r11),%rbp +.cfi_restore %rbp + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lcbc_ret: + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_cbc_encrypt,.-aesni_cbc_encrypt +.globl aesni_set_decrypt_key +.type aesni_set_decrypt_key,@function +.align 16 +aesni_set_decrypt_key: +.cfi_startproc +.byte 0x48,0x83,0xEC,0x08 +.cfi_adjust_cfa_offset 8 + call __aesni_set_encrypt_key + shll $4,%esi + testl %eax,%eax + jnz .Ldec_key_ret + leaq 16(%rdx,%rsi,1),%rdi + + movups (%rdx),%xmm0 + movups (%rdi),%xmm1 + movups %xmm0,(%rdi) + movups %xmm1,(%rdx) + leaq 16(%rdx),%rdx + leaq -16(%rdi),%rdi + +.Ldec_key_inverse: + movups (%rdx),%xmm0 + movups (%rdi),%xmm1 +.byte 102,15,56,219,192 +.byte 102,15,56,219,201 + leaq 16(%rdx),%rdx + leaq -16(%rdi),%rdi + movups %xmm0,16(%rdi) + movups %xmm1,-16(%rdx) + cmpq %rdx,%rdi + ja .Ldec_key_inverse + + movups (%rdx),%xmm0 +.byte 102,15,56,219,192 + pxor %xmm1,%xmm1 + movups %xmm0,(%rdi) + pxor %xmm0,%xmm0 +.Ldec_key_ret: + addq $8,%rsp +.cfi_adjust_cfa_offset -8 + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_set_decrypt_key: +.size aesni_set_decrypt_key,.-aesni_set_decrypt_key +.globl aesni_set_encrypt_key +.type aesni_set_encrypt_key,@function +.align 16 +aesni_set_encrypt_key: +__aesni_set_encrypt_key: +.cfi_startproc +.byte 0x48,0x83,0xEC,0x08 +.cfi_adjust_cfa_offset 8 + movq $-1,%rax + testq %rdi,%rdi + jz .Lenc_key_ret + testq %rdx,%rdx + jz .Lenc_key_ret + + movl $268437504,%r10d + movups (%rdi),%xmm0 + xorps %xmm4,%xmm4 + andl OPENSSL_ia32cap_P+4(%rip),%r10d + leaq 16(%rdx),%rax + cmpl $256,%esi + je .L14rounds + cmpl $192,%esi + je .L12rounds + cmpl $128,%esi + jne .Lbad_keybits + +.L10rounds: + movl $9,%esi + cmpl $268435456,%r10d + je .L10rounds_alt + + movups %xmm0,(%rdx) +.byte 102,15,58,223,200,1 + call .Lkey_expansion_128_cold +.byte 102,15,58,223,200,2 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,4 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,8 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,16 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,32 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,64 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,128 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,27 + call .Lkey_expansion_128 +.byte 102,15,58,223,200,54 + call .Lkey_expansion_128 + movups %xmm0,(%rax) + movl %esi,80(%rax) + xorl %eax,%eax + jmp .Lenc_key_ret + +.align 16 +.L10rounds_alt: + movdqa .Lkey_rotate(%rip),%xmm5 + movl $8,%r10d + movdqa .Lkey_rcon1(%rip),%xmm4 + movdqa %xmm0,%xmm2 + movdqu %xmm0,(%rdx) + jmp .Loop_key128 + +.align 16 +.Loop_key128: +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + pslld $1,%xmm4 + leaq 16(%rax),%rax + + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + + pxor %xmm2,%xmm0 + movdqu %xmm0,-16(%rax) + movdqa %xmm0,%xmm2 + + decl %r10d + jnz .Loop_key128 + + movdqa .Lkey_rcon1b(%rip),%xmm4 + +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + pslld $1,%xmm4 + + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + + pxor %xmm2,%xmm0 + movdqu %xmm0,(%rax) + + movdqa %xmm0,%xmm2 +.byte 102,15,56,0,197 +.byte 102,15,56,221,196 + + movdqa %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm2,%xmm3 + pslldq $4,%xmm2 + pxor %xmm3,%xmm2 + + pxor %xmm2,%xmm0 + movdqu %xmm0,16(%rax) + + movl %esi,96(%rax) + xorl %eax,%eax + jmp .Lenc_key_ret + +.align 16 +.L12rounds: + movq 16(%rdi),%xmm2 + movl $11,%esi + cmpl $268435456,%r10d + je .L12rounds_alt + + movups %xmm0,(%rdx) +.byte 102,15,58,223,202,1 + call .Lkey_expansion_192a_cold +.byte 102,15,58,223,202,2 + call .Lkey_expansion_192b +.byte 102,15,58,223,202,4 + call .Lkey_expansion_192a +.byte 102,15,58,223,202,8 + call .Lkey_expansion_192b +.byte 102,15,58,223,202,16 + call .Lkey_expansion_192a +.byte 102,15,58,223,202,32 + call .Lkey_expansion_192b +.byte 102,15,58,223,202,64 + call .Lkey_expansion_192a +.byte 102,15,58,223,202,128 + call .Lkey_expansion_192b + movups %xmm0,(%rax) + movl %esi,48(%rax) + xorq %rax,%rax + jmp .Lenc_key_ret + +.align 16 +.L12rounds_alt: + movdqa .Lkey_rotate192(%rip),%xmm5 + movdqa .Lkey_rcon1(%rip),%xmm4 + movl $8,%r10d + movdqu %xmm0,(%rdx) + jmp .Loop_key192 + +.align 16 +.Loop_key192: + movq %xmm2,0(%rax) + movdqa %xmm2,%xmm1 +.byte 102,15,56,0,213 +.byte 102,15,56,221,212 + pslld $1,%xmm4 + leaq 24(%rax),%rax + + movdqa %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm3,%xmm0 + + pshufd $0xff,%xmm0,%xmm3 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + + pxor %xmm2,%xmm0 + pxor %xmm3,%xmm2 + movdqu %xmm0,-16(%rax) + + decl %r10d + jnz .Loop_key192 + + movl %esi,32(%rax) + xorl %eax,%eax + jmp .Lenc_key_ret + +.align 16 +.L14rounds: + movups 16(%rdi),%xmm2 + movl $13,%esi + leaq 16(%rax),%rax + cmpl $268435456,%r10d + je .L14rounds_alt + + movups %xmm0,(%rdx) + movups %xmm2,16(%rdx) +.byte 102,15,58,223,202,1 + call .Lkey_expansion_256a_cold +.byte 102,15,58,223,200,1 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,2 + call .Lkey_expansion_256a +.byte 102,15,58,223,200,2 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,4 + call .Lkey_expansion_256a +.byte 102,15,58,223,200,4 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,8 + call .Lkey_expansion_256a +.byte 102,15,58,223,200,8 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,16 + call .Lkey_expansion_256a +.byte 102,15,58,223,200,16 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,32 + call .Lkey_expansion_256a +.byte 102,15,58,223,200,32 + call .Lkey_expansion_256b +.byte 102,15,58,223,202,64 + call .Lkey_expansion_256a + movups %xmm0,(%rax) + movl %esi,16(%rax) + xorq %rax,%rax + jmp .Lenc_key_ret + +.align 16 +.L14rounds_alt: + movdqa .Lkey_rotate(%rip),%xmm5 + movdqa .Lkey_rcon1(%rip),%xmm4 + movl $7,%r10d + movdqu %xmm0,0(%rdx) + movdqa %xmm2,%xmm1 + movdqu %xmm2,16(%rdx) + jmp .Loop_key256 + +.align 16 +.Loop_key256: +.byte 102,15,56,0,213 +.byte 102,15,56,221,212 + + movdqa %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm0,%xmm3 + pslldq $4,%xmm0 + pxor %xmm3,%xmm0 + pslld $1,%xmm4 + + pxor %xmm2,%xmm0 + movdqu %xmm0,(%rax) + + decl %r10d + jz .Ldone_key256 + + pshufd $0xff,%xmm0,%xmm2 + pxor %xmm3,%xmm3 +.byte 102,15,56,221,211 + + movdqa %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm1,%xmm3 + pslldq $4,%xmm1 + pxor %xmm3,%xmm1 + + pxor %xmm1,%xmm2 + movdqu %xmm2,16(%rax) + leaq 32(%rax),%rax + movdqa %xmm2,%xmm1 + + jmp .Loop_key256 + +.Ldone_key256: + movl %esi,16(%rax) + xorl %eax,%eax + jmp .Lenc_key_ret + +.align 16 +.Lbad_keybits: + movq $-2,%rax +.Lenc_key_ret: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + addq $8,%rsp +.cfi_adjust_cfa_offset -8 + .byte 0xf3,0xc3 +.LSEH_end_set_encrypt_key: + +.align 16 +.Lkey_expansion_128: + movups %xmm0,(%rax) + leaq 16(%rax),%rax +.Lkey_expansion_128_cold: + shufps $16,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $255,%xmm1,%xmm1 + xorps %xmm1,%xmm0 + .byte 0xf3,0xc3 + +.align 16 +.Lkey_expansion_192a: + movups %xmm0,(%rax) + leaq 16(%rax),%rax +.Lkey_expansion_192a_cold: + movaps %xmm2,%xmm5 +.Lkey_expansion_192b_warm: + shufps $16,%xmm0,%xmm4 + movdqa %xmm2,%xmm3 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + pslldq $4,%xmm3 + xorps %xmm4,%xmm0 + pshufd $85,%xmm1,%xmm1 + pxor %xmm3,%xmm2 + pxor %xmm1,%xmm0 + pshufd $255,%xmm0,%xmm3 + pxor %xmm3,%xmm2 + .byte 0xf3,0xc3 + +.align 16 +.Lkey_expansion_192b: + movaps %xmm0,%xmm3 + shufps $68,%xmm0,%xmm5 + movups %xmm5,(%rax) + shufps $78,%xmm2,%xmm3 + movups %xmm3,16(%rax) + leaq 32(%rax),%rax + jmp .Lkey_expansion_192b_warm + +.align 16 +.Lkey_expansion_256a: + movups %xmm2,(%rax) + leaq 16(%rax),%rax +.Lkey_expansion_256a_cold: + shufps $16,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $140,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps $255,%xmm1,%xmm1 + xorps %xmm1,%xmm0 + .byte 0xf3,0xc3 + +.align 16 +.Lkey_expansion_256b: + movups %xmm0,(%rax) + leaq 16(%rax),%rax + + shufps $16,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps $140,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps $170,%xmm1,%xmm1 + xorps %xmm1,%xmm2 + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_set_encrypt_key,.-aesni_set_encrypt_key +.size __aesni_set_encrypt_key,.-__aesni_set_encrypt_key +.align 64 +.Lbswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.Lincrement32: +.long 6,6,6,0 +.Lincrement64: +.long 1,0,0,0 +.Lxts_magic: +.long 0x87,0,1,0 +.Lincrement1: +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 +.Lkey_rotate: +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d +.Lkey_rotate192: +.long 0x04070605,0x04070605,0x04070605,0x04070605 +.Lkey_rcon1: +.long 1,1,1,1 +.Lkey_rcon1b: +.long 0x1b,0x1b,0x1b,0x1b + +.byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/aes/aesv8-armx.S b/crypto/openssl/crypto/aes/aesv8-armx.S new file mode 100644 index 000000000000..cd9cac97ca63 --- /dev/null +++ b/crypto/openssl/crypto/aes/aesv8-armx.S @@ -0,0 +1,3178 @@ +#include "arm_arch.h" + +#if __ARM_MAX_ARCH__>=7 +.arch armv8-a+crypto +.text +.align 5 +.Lrcon: +.long 0x01,0x01,0x01,0x01 +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat +.long 0x1b,0x1b,0x1b,0x1b + +.globl aes_v8_set_encrypt_key +.type aes_v8_set_encrypt_key,%function +.align 5 +aes_v8_set_encrypt_key: +.Lenc_key: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + mov x3,#-1 + cmp x0,#0 + b.eq .Lenc_key_abort + cmp x2,#0 + b.eq .Lenc_key_abort + mov x3,#-2 + cmp w1,#128 + b.lt .Lenc_key_abort + cmp w1,#256 + b.gt .Lenc_key_abort + tst w1,#0x3f + b.ne .Lenc_key_abort + + adr x3,.Lrcon + cmp w1,#192 + + eor v0.16b,v0.16b,v0.16b + ld1 {v3.16b},[x0],#16 + mov w1,#8 // reuse w1 + ld1 {v1.4s,v2.4s},[x3],#32 + + b.lt .Loop128 + b.eq .L192 + b .L256 + +.align 4 +.Loop128: + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + b.ne .Loop128 + + ld1 {v1.4s},[x3] + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2] + add x2,x2,#0x50 + + mov w12,#10 + b .Ldone + +.align 4 +.L192: + ld1 {v4.8b},[x0],#8 + movi v6.16b,#8 // borrow v6.16b + st1 {v3.4s},[x2],#16 + sub v2.16b,v2.16b,v6.16b // adjust the mask + +.Loop192: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 +#ifdef __ARMEB__ + st1 {v4.4s},[x2],#16 + sub x2,x2,#8 +#else + st1 {v4.8b},[x2],#8 +#endif + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + + dup v5.4s,v3.s[3] + eor v5.16b,v5.16b,v4.16b + eor v6.16b,v6.16b,v1.16b + ext v4.16b,v0.16b,v4.16b,#12 + shl v1.16b,v1.16b,#1 + eor v4.16b,v4.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + eor v4.16b,v4.16b,v6.16b + st1 {v3.4s},[x2],#16 + b.ne .Loop192 + + mov w12,#12 + add x2,x2,#0x20 + b .Ldone + +.align 4 +.L256: + ld1 {v4.16b},[x0] + mov w1,#7 + mov w12,#14 + st1 {v3.4s},[x2],#16 + +.Loop256: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v4.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2],#16 + b.eq .Ldone + + dup v6.4s,v3.s[3] // just splat + ext v5.16b,v0.16b,v4.16b,#12 + aese v6.16b,v0.16b + + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + + eor v4.16b,v4.16b,v6.16b + b .Loop256 + +.Ldone: + str w12,[x2] + mov x3,#0 + +.Lenc_key_abort: + mov x0,x3 // return value + ldr x29,[sp],#16 + ret +.size aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key + +.globl aes_v8_set_decrypt_key +.type aes_v8_set_decrypt_key,%function +.align 5 +aes_v8_set_decrypt_key: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + bl .Lenc_key + + cmp x0,#0 + b.ne .Ldec_key_abort + + sub x2,x2,#240 // restore original x2 + mov x4,#-16 + add x0,x2,x12,lsl#4 // end of key schedule + + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + +.Loop_imc: + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + aesimc v0.16b,v0.16b + aesimc v1.16b,v1.16b + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + cmp x0,x2 + b.hi .Loop_imc + + ld1 {v0.4s},[x2] + aesimc v0.16b,v0.16b + st1 {v0.4s},[x0] + + eor x0,x0,x0 // return value +.Ldec_key_abort: + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key +.globl aes_v8_encrypt +.type aes_v8_encrypt,%function +.align 5 +aes_v8_encrypt: + ldr w3,[x2,#240] + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +.Loop_enc: + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aese v2.16b,v1.16b + aesmc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt .Loop_enc + + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aese v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret +.size aes_v8_encrypt,.-aes_v8_encrypt +.globl aes_v8_decrypt +.type aes_v8_decrypt,%function +.align 5 +aes_v8_decrypt: + ldr w3,[x2,#240] + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +.Loop_dec: + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aesd v2.16b,v1.16b + aesimc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt .Loop_dec + + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aesd v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret +.size aes_v8_decrypt,.-aes_v8_decrypt +.globl aes_v8_ecb_encrypt +.type aes_v8_ecb_encrypt,%function +.align 5 +aes_v8_ecb_encrypt: + subs x2,x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne .Lecb_big_size + ld1 {v0.16b},[x0] + cmp w4,#0 // en- or decrypting? + ldr w5,[x3,#240] + ld1 {v5.4s,v6.4s},[x3],#32 // load key schedule... + + b.eq .Lecb_small_dec + aese v0.16b,v5.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aese v0.16b,v6.16b + aesmc v0.16b,v0.16b + subs w5,w5,#10 // if rounds==10, jump to aes-128-ecb processing + b.eq .Lecb_128_enc +.Lecb_round_loop: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w5,w5,#2 // bias + b.gt .Lecb_round_loop +.Lecb_128_enc: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + st1 {v0.16b},[x1] + b .Lecb_Final_abort +.Lecb_small_dec: + aesd v0.16b,v5.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aesd v0.16b,v6.16b + aesimc v0.16b,v0.16b + subs w5,w5,#10 // bias + b.eq .Lecb_128_dec +.Lecb_dec_round_loop: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w5,w5,#2 // bias + b.gt .Lecb_dec_round_loop +.Lecb_128_dec: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + st1 {v0.16b},[x1] + b .Lecb_Final_abort +.Lecb_big_size: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + mov x8,#16 + b.lo .Lecb_done + csel x8,xzr,x8,eq + + cmp w4,#0 // en- or decrypting? + ldr w5,[x3,#240] + and x2,x2,#-16 + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + b.eq .Lecb_dec + + ld1 {v1.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v1.16b,v1.16b + orr v24.16b,v1.16b,v1.16b + orr v1.16b,v0.16b,v0.16b + b.lo .Lecb_enc_tail + + orr v1.16b,v3.16b,v3.16b + ld1 {v24.16b},[x0],#16 + cmp x2,#32 + b.lo .Loop3x_ecb_enc + + ld1 {v25.16b},[x0],#16 + ld1 {v26.16b},[x0],#16 + sub x2,x2,#32 // bias + mov w6,w5 + +.Loop5x_ecb_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop5x_ecb_enc + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + cmp x2,#0x40 // because .Lecb_enc_tail4x + sub x2,x2,#0x50 + + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v1.16b,v18.16b + aesmc v1.16b,v1.16b + aese v24.16b,v18.16b + aesmc v24.16b,v24.16b + aese v25.16b,v18.16b + aesmc v25.16b,v25.16b + aese v26.16b,v18.16b + aesmc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because .Lecb_enc_tail4x + + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + aese v1.16b,v19.16b + aesmc v1.16b,v1.16b + aese v24.16b,v19.16b + aesmc v24.16b,v24.16b + aese v25.16b,v19.16b + aesmc v25.16b,v25.16b + aese v26.16b,v19.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + aese v25.16b,v20.16b + aesmc v25.16b,v25.16b + aese v26.16b,v20.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v25.16b,v21.16b + aesmc v25.16b,v25.16b + aese v26.16b,v21.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v25.16b,v22.16b + aesmc v25.16b,v25.16b + aese v26.16b,v22.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v23.16b + ld1 {v2.16b},[x0],#16 + aese v1.16b,v23.16b + ld1 {v3.16b},[x0],#16 + aese v24.16b,v23.16b + ld1 {v27.16b},[x0],#16 + aese v25.16b,v23.16b + ld1 {v28.16b},[x0],#16 + aese v26.16b,v23.16b + ld1 {v29.16b},[x0],#16 + cbz x6,.Lecb_enc_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v7.16b,v0.16b + orr v0.16b,v2.16b,v2.16b + eor v5.16b,v7.16b,v1.16b + orr v1.16b,v3.16b,v3.16b + eor v17.16b,v7.16b,v24.16b + orr v24.16b,v27.16b,v27.16b + eor v30.16b,v7.16b,v25.16b + orr v25.16b,v28.16b,v28.16b + eor v31.16b,v7.16b,v26.16b + st1 {v4.16b},[x1],#16 + orr v26.16b,v29.16b,v29.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs .Loop5x_ecb_enc + + add x2,x2,#0x50 + cbz x2,.Lecb_done + + add w6,w5,#2 + subs x2,x2,#0x30 + orr v0.16b,v27.16b,v27.16b + orr v1.16b,v28.16b,v28.16b + orr v24.16b,v29.16b,v29.16b + b.lo .Lecb_enc_tail + + b .Loop3x_ecb_enc + +.align 4 +.Lecb_enc_tail4x: + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + eor v30.16b,v7.16b,v25.16b + eor v31.16b,v7.16b,v26.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + + b .Lecb_done +.align 4 +.Loop3x_ecb_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_ecb_enc + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + subs x2,x2,#0x30 + csel x6,x2,x6,lo // x6, w6, is zero at this point + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v24.16b + // are loaded with last "words" + mov x7,x3 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + ld1 {v2.16b},[x0],#16 + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + ld1 {v3.16b},[x0],#16 + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aese v0.16b,v23.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v7.16b,v0.16b + eor v5.16b,v7.16b,v1.16b + eor v24.16b,v24.16b,v7.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v24.16b},[x1],#16 + orr v24.16b,v27.16b,v27.16b + b.hs .Loop3x_ecb_enc + + cmn x2,#0x30 + b.eq .Lecb_done + nop + +.Lecb_enc_tail: + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lecb_enc_tail + + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + cmn x2,#0x20 + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + b.eq .Lecb_enc_one + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b .Lecb_done + +.Lecb_enc_one: + eor v5.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + b .Lecb_done +.align 5 +.Lecb_dec: + ld1 {v1.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v1.16b,v1.16b + orr v24.16b,v1.16b,v1.16b + orr v1.16b,v0.16b,v0.16b + b.lo .Lecb_dec_tail + + orr v1.16b,v3.16b,v3.16b + ld1 {v24.16b},[x0],#16 + cmp x2,#32 + b.lo .Loop3x_ecb_dec + + ld1 {v25.16b},[x0],#16 + ld1 {v26.16b},[x0],#16 + sub x2,x2,#32 // bias + mov w6,w5 + +.Loop5x_ecb_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop5x_ecb_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + cmp x2,#0x40 // because .Lecb_tail4x + sub x2,x2,#0x50 + + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v18.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v18.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v18.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v18.16b + aesimc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because .Lecb_tail4x + + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v19.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v19.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v19.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v19.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v20.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v20.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v21.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v21.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v22.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v22.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v23.16b + ld1 {v2.16b},[x0],#16 + aesd v1.16b,v23.16b + ld1 {v3.16b},[x0],#16 + aesd v24.16b,v23.16b + ld1 {v27.16b},[x0],#16 + aesd v25.16b,v23.16b + ld1 {v28.16b},[x0],#16 + aesd v26.16b,v23.16b + ld1 {v29.16b},[x0],#16 + cbz x6,.Lecb_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v7.16b,v0.16b + orr v0.16b,v2.16b,v2.16b + eor v5.16b,v7.16b,v1.16b + orr v1.16b,v3.16b,v3.16b + eor v17.16b,v7.16b,v24.16b + orr v24.16b,v27.16b,v27.16b + eor v30.16b,v7.16b,v25.16b + orr v25.16b,v28.16b,v28.16b + eor v31.16b,v7.16b,v26.16b + st1 {v4.16b},[x1],#16 + orr v26.16b,v29.16b,v29.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs .Loop5x_ecb_dec + + add x2,x2,#0x50 + cbz x2,.Lecb_done + + add w6,w5,#2 + subs x2,x2,#0x30 + orr v0.16b,v27.16b,v27.16b + orr v1.16b,v28.16b,v28.16b + orr v24.16b,v29.16b,v29.16b + b.lo .Lecb_dec_tail + + b .Loop3x_ecb_dec + +.align 4 +.Lecb_tail4x: + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + eor v30.16b,v7.16b,v25.16b + eor v31.16b,v7.16b,v26.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + + b .Lecb_done +.align 4 +.Loop3x_ecb_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_ecb_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + subs x2,x2,#0x30 + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v24.16b + // are loaded with last "words" + mov x7,x3 + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + ld1 {v2.16b},[x0],#16 + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + ld1 {v3.16b},[x0],#16 + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v7.16b,v0.16b + eor v5.16b,v7.16b,v1.16b + eor v24.16b,v24.16b,v7.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v24.16b},[x1],#16 + orr v24.16b,v27.16b,v27.16b + b.hs .Loop3x_ecb_dec + + cmn x2,#0x30 + b.eq .Lecb_done + nop + +.Lecb_dec_tail: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lecb_dec_tail + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + b.eq .Lecb_dec_one + eor v5.16b,v7.16b,v1.16b + eor v17.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b .Lecb_done + +.Lecb_dec_one: + eor v5.16b,v7.16b,v24.16b + st1 {v5.16b},[x1],#16 + +.Lecb_done: + ldr x29,[sp],#16 +.Lecb_Final_abort: + ret +.size aes_v8_ecb_encrypt,.-aes_v8_ecb_encrypt +.globl aes_v8_cbc_encrypt +.type aes_v8_cbc_encrypt,%function +.align 5 +aes_v8_cbc_encrypt: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + subs x2,x2,#16 + mov x8,#16 + b.lo .Lcbc_abort + csel x8,xzr,x8,eq + + cmp w5,#0 // en- or decrypting? + ldr w5,[x3,#240] + and x2,x2,#-16 + ld1 {v6.16b},[x4] + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + b.eq .Lcbc_dec + + cmp w5,#2 + eor v0.16b,v0.16b,v6.16b + eor v5.16b,v16.16b,v7.16b + b.eq .Lcbc_enc128 + + ld1 {v2.4s,v3.4s},[x7] + add x7,x3,#16 + add x6,x3,#16*4 + add x12,x3,#16*5 + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + add x14,x3,#16*6 + add x3,x3,#16*7 + b .Lenter_cbc_enc + +.align 4 +.Loop_cbc_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +.Lenter_cbc_enc: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x6] + cmp w5,#4 + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x12] + b.eq .Lcbc_enc192 + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x14] + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3] + nop + +.Lcbc_enc192: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x7] // re-pre-load rndkey[1] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs .Loop_cbc_enc + + st1 {v6.16b},[x1],#16 + b .Lcbc_done + +.align 5 +.Lcbc_enc128: + ld1 {v2.4s,v3.4s},[x7] + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + b .Lenter_cbc_enc128 +.Loop_cbc_enc128: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +.Lenter_cbc_enc128: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs .Loop_cbc_enc128 + + st1 {v6.16b},[x1],#16 + b .Lcbc_done +.align 5 +.Lcbc_dec: + ld1 {v24.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v27.16b,v24.16b,v24.16b + b.lo .Lcbc_dec_tail + + orr v1.16b,v24.16b,v24.16b + ld1 {v24.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + orr v27.16b,v24.16b,v24.16b + cmp x2,#32 + b.lo .Loop3x_cbc_dec + + ld1 {v25.16b},[x0],#16 + ld1 {v26.16b},[x0],#16 + sub x2,x2,#32 // bias + mov w6,w5 + orr v28.16b,v25.16b,v25.16b + orr v29.16b,v26.16b,v26.16b + +.Loop5x_cbc_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop5x_cbc_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + cmp x2,#0x40 // because .Lcbc_tail4x + sub x2,x2,#0x50 + + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v18.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v18.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v18.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v18.16b + aesimc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because .Lcbc_tail4x + + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v19.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v19.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v19.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v19.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v20.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v20.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v21.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v21.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v22.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v22.16b + aesimc v26.16b,v26.16b + + eor v4.16b,v6.16b,v7.16b + aesd v0.16b,v23.16b + eor v5.16b,v2.16b,v7.16b + ld1 {v2.16b},[x0],#16 + aesd v1.16b,v23.16b + eor v17.16b,v3.16b,v7.16b + ld1 {v3.16b},[x0],#16 + aesd v24.16b,v23.16b + eor v30.16b,v27.16b,v7.16b + ld1 {v27.16b},[x0],#16 + aesd v25.16b,v23.16b + eor v31.16b,v28.16b,v7.16b + ld1 {v28.16b},[x0],#16 + aesd v26.16b,v23.16b + orr v6.16b,v29.16b,v29.16b + ld1 {v29.16b},[x0],#16 + cbz x6,.Lcbc_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + orr v0.16b,v2.16b,v2.16b + eor v5.16b,v5.16b,v1.16b + orr v1.16b,v3.16b,v3.16b + eor v17.16b,v17.16b,v24.16b + orr v24.16b,v27.16b,v27.16b + eor v30.16b,v30.16b,v25.16b + orr v25.16b,v28.16b,v28.16b + eor v31.16b,v31.16b,v26.16b + st1 {v4.16b},[x1],#16 + orr v26.16b,v29.16b,v29.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs .Loop5x_cbc_dec + + add x2,x2,#0x50 + cbz x2,.Lcbc_done + + add w6,w5,#2 + subs x2,x2,#0x30 + orr v0.16b,v27.16b,v27.16b + orr v2.16b,v27.16b,v27.16b + orr v1.16b,v28.16b,v28.16b + orr v3.16b,v28.16b,v28.16b + orr v24.16b,v29.16b,v29.16b + orr v27.16b,v29.16b,v29.16b + b.lo .Lcbc_dec_tail + + b .Loop3x_cbc_dec + +.align 4 +.Lcbc_tail4x: + eor v5.16b,v4.16b,v1.16b + eor v17.16b,v17.16b,v24.16b + eor v30.16b,v30.16b,v25.16b + eor v31.16b,v31.16b,v26.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + + b .Lcbc_done +.align 4 +.Loop3x_cbc_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_cbc_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + eor v5.16b,v2.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + eor v17.16b,v3.16b,v7.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v24.16b + // are loaded with last "words" + orr v6.16b,v27.16b,v27.16b + mov x7,x3 + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + ld1 {v2.16b},[x0],#16 + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + ld1 {v3.16b},[x0],#16 + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v24.16b,v24.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v24.16b},[x1],#16 + orr v24.16b,v27.16b,v27.16b + b.hs .Loop3x_cbc_dec + + cmn x2,#0x30 + b.eq .Lcbc_done + nop + +.Lcbc_dec_tail: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lcbc_dec_tail + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + eor v5.16b,v6.16b,v7.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + eor v17.16b,v3.16b,v7.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + b.eq .Lcbc_dec_one + eor v5.16b,v5.16b,v1.16b + eor v17.16b,v17.16b,v24.16b + orr v6.16b,v27.16b,v27.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b .Lcbc_done + +.Lcbc_dec_one: + eor v5.16b,v5.16b,v24.16b + orr v6.16b,v27.16b,v27.16b + st1 {v5.16b},[x1],#16 + +.Lcbc_done: + st1 {v6.16b},[x4] +.Lcbc_abort: + ldr x29,[sp],#16 + ret +.size aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt +.globl aes_v8_ctr32_encrypt_blocks +.type aes_v8_ctr32_encrypt_blocks,%function +.align 5 +aes_v8_ctr32_encrypt_blocks: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + ldr w5,[x3,#240] + + ldr w8, [x4, #12] +#ifdef __ARMEB__ + ld1 {v0.16b},[x4] +#else + ld1 {v0.4s},[x4] +#endif + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#4 + mov x12,#16 + cmp x2,#2 + add x7,x3,x5,lsl#4 // pointer to last 5 round keys + sub w5,w5,#2 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + add x7,x3,#32 + mov w6,w5 + csel x12,xzr,x12,lo +#ifndef __ARMEB__ + rev w8, w8 +#endif + orr v1.16b,v0.16b,v0.16b + add w10, w8, #1 + orr v18.16b,v0.16b,v0.16b + add w8, w8, #2 + orr v6.16b,v0.16b,v0.16b + rev w10, w10 + mov v1.s[3],w10 + b.ls .Lctr32_tail + rev w12, w8 + sub x2,x2,#3 // bias + mov v18.s[3],w12 + cmp x2,#32 + b.lo .Loop3x_ctr32 + + add w13,w8,#1 + add w14,w8,#2 + orr v24.16b,v0.16b,v0.16b + rev w13,w13 + orr v25.16b,v0.16b,v0.16b + rev w14,w14 + mov v24.s[3],w13 + sub x2,x2,#2 // bias + mov v25.s[3],w14 + add w8,w8,#2 + b .Loop5x_ctr32 + +.align 4 +.Loop5x_ctr32: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop5x_ctr32 + + mov x7,x3 + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + add w9,w8,#1 + add w10,w8,#2 + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + add w12,w8,#3 + add w13,w8,#4 + aese v18.16b,v20.16b + aesmc v18.16b,v18.16b + add w14,w8,#5 + rev w9,w9 + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + rev w10,w10 + rev w12,w12 + aese v25.16b,v20.16b + aesmc v25.16b,v25.16b + rev w13,w13 + rev w14,w14 + + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v18.16b,v21.16b + aesmc v18.16b,v18.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v25.16b,v21.16b + aesmc v25.16b,v25.16b + + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + ld1 {v2.16b},[x0],#16 + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + ld1 {v3.16b},[x0],#16 + aese v18.16b,v22.16b + aesmc v18.16b,v18.16b + ld1 {v19.16b},[x0],#16 + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + ld1 {v26.16b},[x0],#16 + aese v25.16b,v22.16b + aesmc v25.16b,v25.16b + ld1 {v27.16b},[x0],#16 + + aese v0.16b,v23.16b + eor v2.16b,v2.16b,v7.16b + aese v1.16b,v23.16b + eor v3.16b,v3.16b,v7.16b + aese v18.16b,v23.16b + eor v19.16b,v19.16b,v7.16b + aese v24.16b,v23.16b + eor v26.16b,v26.16b,v7.16b + aese v25.16b,v23.16b + eor v27.16b,v27.16b,v7.16b + + eor v2.16b,v2.16b,v0.16b + orr v0.16b,v6.16b,v6.16b + eor v3.16b,v3.16b,v1.16b + orr v1.16b,v6.16b,v6.16b + eor v19.16b,v19.16b,v18.16b + orr v18.16b,v6.16b,v6.16b + eor v26.16b,v26.16b,v24.16b + orr v24.16b,v6.16b,v6.16b + eor v27.16b,v27.16b,v25.16b + orr v25.16b,v6.16b,v6.16b + + st1 {v2.16b},[x1],#16 + mov v0.s[3],w9 + st1 {v3.16b},[x1],#16 + mov v1.s[3],w10 + st1 {v19.16b},[x1],#16 + mov v18.s[3],w12 + st1 {v26.16b},[x1],#16 + mov v24.s[3],w13 + st1 {v27.16b},[x1],#16 + mov v25.s[3],w14 + + mov w6,w5 + cbz x2,.Lctr32_done + + add w8,w8,#5 + subs x2,x2,#5 + b.hs .Loop5x_ctr32 + + add x2,x2,#5 + sub w8,w8,#5 + + cmp x2,#2 + mov x12,#16 + csel x12,xzr,x12,lo + b.ls .Lctr32_tail + + sub x2,x2,#3 // bias + add w8,w8,#3 + b .Loop3x_ctr32 + +.align 4 +.Loop3x_ctr32: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_ctr32 + + aese v0.16b,v16.16b + aesmc v4.16b,v0.16b + aese v1.16b,v16.16b + aesmc v5.16b,v1.16b + ld1 {v2.16b},[x0],#16 + orr v0.16b,v6.16b,v6.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v3.16b},[x0],#16 + orr v1.16b,v6.16b,v6.16b + aese v4.16b,v17.16b + aesmc v4.16b,v4.16b + aese v5.16b,v17.16b + aesmc v5.16b,v5.16b + ld1 {v19.16b},[x0],#16 + mov x7,x3 + aese v18.16b,v17.16b + aesmc v17.16b,v18.16b + orr v18.16b,v6.16b,v6.16b + add w9,w8,#1 + aese v4.16b,v20.16b + aesmc v4.16b,v4.16b + aese v5.16b,v20.16b + aesmc v5.16b,v5.16b + eor v2.16b,v2.16b,v7.16b + add w10,w8,#2 + aese v17.16b,v20.16b + aesmc v17.16b,v17.16b + eor v3.16b,v3.16b,v7.16b + add w8,w8,#3 + aese v4.16b,v21.16b + aesmc v4.16b,v4.16b + aese v5.16b,v21.16b + aesmc v5.16b,v5.16b + eor v19.16b,v19.16b,v7.16b + rev w9,w9 + aese v17.16b,v21.16b + aesmc v17.16b,v17.16b + mov v0.s[3], w9 + rev w10,w10 + aese v4.16b,v22.16b + aesmc v4.16b,v4.16b + aese v5.16b,v22.16b + aesmc v5.16b,v5.16b + mov v1.s[3], w10 + rev w12,w8 + aese v17.16b,v22.16b + aesmc v17.16b,v17.16b + mov v18.s[3], w12 + subs x2,x2,#3 + aese v4.16b,v23.16b + aese v5.16b,v23.16b + aese v17.16b,v23.16b + + eor v2.16b,v2.16b,v4.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + st1 {v2.16b},[x1],#16 + eor v3.16b,v3.16b,v5.16b + mov w6,w5 + st1 {v3.16b},[x1],#16 + eor v19.16b,v19.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v19.16b},[x1],#16 + b.hs .Loop3x_ctr32 + + adds x2,x2,#3 + b.eq .Lctr32_done + cmp x2,#1 + mov x12,#16 + csel x12,xzr,x12,eq + +.Lctr32_tail: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lctr32_tail + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v2.16b},[x0],x12 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + ld1 {v3.16b},[x0] + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + eor v2.16b,v2.16b,v7.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + eor v3.16b,v3.16b,v7.16b + aese v0.16b,v23.16b + aese v1.16b,v23.16b + + cmp x2,#1 + eor v2.16b,v2.16b,v0.16b + eor v3.16b,v3.16b,v1.16b + st1 {v2.16b},[x1],#16 + b.eq .Lctr32_done + st1 {v3.16b},[x1] + +.Lctr32_done: + ldr x29,[sp],#16 + ret +.size aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks +.globl aes_v8_xts_encrypt +.type aes_v8_xts_encrypt,%function +.align 5 +aes_v8_xts_encrypt: + cmp x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne .Lxts_enc_big_size + // Encrypt the iv with key2, as the first XEX iv. + ldr w6,[x4,#240] + ld1 {v0.16b},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.16b},[x4],#16 + +.Loop_enc_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt .Loop_enc_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + ld1 {v0.16b},[x0] + eor v0.16b,v6.16b,v0.16b + + ldr w6,[x3,#240] + ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... + + aese v0.16b,v28.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aese v0.16b,v29.16b + aesmc v0.16b,v0.16b + subs w6,w6,#10 // if rounds==10, jump to aes-128-xts processing + b.eq .Lxts_128_enc +.Lxts_enc_round_loop: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 // bias + b.gt .Lxts_enc_round_loop +.Lxts_128_enc: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + st1 {v0.16b},[x1] + b .Lxts_enc_final_abort + +.align 4 +.Lxts_enc_big_size: + stp x19,x20,[sp,#-64]! + stp x21,x22,[sp,#48] + stp d8,d9,[sp,#32] + stp d10,d11,[sp,#16] + + // tailcnt store the tail value of length%16. + and x21,x2,#0xf + and x2,x2,#-16 + subs x2,x2,#16 + mov x8,#16 + b.lo .Lxts_abort + csel x8,xzr,x8,eq + + // Firstly, encrypt the iv with key2, as the first iv of XEX. + ldr w6,[x4,#240] + ld1 {v0.4s},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.4s},[x4],#16 + +.Loop_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt .Loop_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + // The iv for second block + // x9- iv(low), x10 - iv(high) + // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d8,x9 + fmov v8.d[1],x10 + + ldr w5,[x3,#240] // next starting point + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + + // Encryption +.Lxts_enc: + ld1 {v24.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v28.16b,v0.16b,v0.16b + orr v27.16b,v24.16b,v24.16b + orr v29.16b,v24.16b,v24.16b + b.lo .Lxts_inner_enc_tail + eor v0.16b,v0.16b,v6.16b // before encryption, xor with iv + eor v24.16b,v24.16b,v8.16b + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d9,x9 + fmov v9.d[1],x10 + + + orr v1.16b,v24.16b,v24.16b + ld1 {v24.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + eor v27.16b,v24.16b,v9.16b // the third block + eor v24.16b,v24.16b,v9.16b + cmp x2,#32 + b.lo .Lxts_outer_enc_tail + + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d10,x9 + fmov v10.d[1],x10 + + ld1 {v25.16b},[x0],#16 + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v26.16b},[x0],#16 + eor v25.16b,v25.16b,v10.16b // the fourth block + eor v26.16b,v26.16b,v11.16b + sub x2,x2,#32 // bias + mov w6,w5 + b .Loop5x_xts_enc + +.align 4 +.Loop5x_xts_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop5x_xts_enc + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + subs x2,x2,#0x50 // because .Lxts_enc_tail4x + + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v1.16b,v18.16b + aesmc v1.16b,v1.16b + aese v24.16b,v18.16b + aesmc v24.16b,v24.16b + aese v25.16b,v18.16b + aesmc v25.16b,v25.16b + aese v26.16b,v18.16b + aesmc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because .Lxts_enc_tail4x + + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + aese v1.16b,v19.16b + aesmc v1.16b,v1.16b + aese v24.16b,v19.16b + aesmc v24.16b,v24.16b + aese v25.16b,v19.16b + aesmc v25.16b,v25.16b + aese v26.16b,v19.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + aese v25.16b,v20.16b + aesmc v25.16b,v25.16b + aese v26.16b,v20.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v25.16b,v21.16b + aesmc v25.16b,v25.16b + aese v26.16b,v21.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v25.16b,v22.16b + aesmc v25.16b,v25.16b + aese v26.16b,v22.16b + aesmc v26.16b,v26.16b + + eor v4.16b,v7.16b,v6.16b + aese v0.16b,v23.16b + // The iv for first block of one iteration + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v7.16b,v8.16b + ld1 {v2.16b},[x0],#16 + aese v1.16b,v23.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d8,x9 + fmov v8.d[1],x10 + eor v17.16b,v7.16b,v9.16b + ld1 {v3.16b},[x0],#16 + aese v24.16b,v23.16b + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d9,x9 + fmov v9.d[1],x10 + eor v30.16b,v7.16b,v10.16b + ld1 {v27.16b},[x0],#16 + aese v25.16b,v23.16b + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d10,x9 + fmov v10.d[1],x10 + eor v31.16b,v7.16b,v11.16b + ld1 {v28.16b},[x0],#16 + aese v26.16b,v23.16b + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v29.16b},[x0],#16 + cbz x6,.Lxts_enc_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v0.16b,v2.16b,v6.16b + eor v5.16b,v5.16b,v1.16b + eor v1.16b,v3.16b,v8.16b + eor v17.16b,v17.16b,v24.16b + eor v24.16b,v27.16b,v9.16b + eor v30.16b,v30.16b,v25.16b + eor v25.16b,v28.16b,v10.16b + eor v31.16b,v31.16b,v26.16b + st1 {v4.16b},[x1],#16 + eor v26.16b,v29.16b,v11.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs .Loop5x_xts_enc + + + // If left 4 blocks, borrow the five block's processing. + cmn x2,#0x10 + b.ne .Loop5x_enc_after + orr v11.16b,v10.16b,v10.16b + orr v10.16b,v9.16b,v9.16b + orr v9.16b,v8.16b,v8.16b + orr v8.16b,v6.16b,v6.16b + fmov x9,d11 + fmov x10,v11.d[1] + eor v0.16b,v6.16b,v2.16b + eor v1.16b,v8.16b,v3.16b + eor v24.16b,v27.16b,v9.16b + eor v25.16b,v28.16b,v10.16b + eor v26.16b,v29.16b,v11.16b + b.eq .Loop5x_xts_enc + +.Loop5x_enc_after: + add x2,x2,#0x50 + cbz x2,.Lxts_enc_done + + add w6,w5,#2 + subs x2,x2,#0x30 + b.lo .Lxts_inner_enc_tail + + eor v0.16b,v6.16b,v27.16b + eor v1.16b,v8.16b,v28.16b + eor v24.16b,v29.16b,v9.16b + b .Lxts_outer_enc_tail + +.align 4 +.Lxts_enc_tail4x: + add x0,x0,#16 + eor v5.16b,v1.16b,v5.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v24.16b,v17.16b + st1 {v17.16b},[x1],#16 + eor v30.16b,v25.16b,v30.16b + eor v31.16b,v26.16b,v31.16b + st1 {v30.16b,v31.16b},[x1],#32 + + b .Lxts_enc_done +.align 4 +.Lxts_outer_enc_tail: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lxts_outer_enc_tail + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + // The iv for first block + fmov x9,d9 + fmov x10,v9.d[1] + //mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v8.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + eor v17.16b,v9.16b,v7.16b + + add x6,x6,#0x20 + add x0,x0,x6 + mov x7,x3 + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v0.16b,v23.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + ld1 {v27.16b},[x0],#16 + add w6,w5,#2 + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v24.16b,v24.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + st1 {v5.16b},[x1],#16 + st1 {v24.16b},[x1],#16 + cmn x2,#0x30 + b.eq .Lxts_enc_done +.Lxts_encxor_one: + orr v28.16b,v3.16b,v3.16b + orr v29.16b,v27.16b,v27.16b + nop + +.Lxts_inner_enc_tail: + cmn x2,#0x10 + eor v1.16b,v28.16b,v6.16b + eor v24.16b,v29.16b,v8.16b + b.eq .Lxts_enc_tail_loop + eor v24.16b,v29.16b,v6.16b +.Lxts_enc_tail_loop: + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lxts_enc_tail_loop + + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + cmn x2,#0x20 + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + eor v5.16b,v6.16b,v7.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + eor v17.16b,v8.16b,v7.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + b.eq .Lxts_enc_one + eor v5.16b,v5.16b,v1.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v17.16b,v24.16b + orr v6.16b,v8.16b,v8.16b + st1 {v17.16b},[x1],#16 + fmov x9,d8 + fmov x10,v8.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + b .Lxts_enc_done + +.Lxts_enc_one: + eor v5.16b,v5.16b,v24.16b + orr v6.16b,v6.16b,v6.16b + st1 {v5.16b},[x1],#16 + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + b .Lxts_enc_done +.align 5 +.Lxts_enc_done: + // Process the tail block with cipher stealing. + tst x21,#0xf + b.eq .Lxts_abort + + mov x20,x0 + mov x13,x1 + sub x1,x1,#16 +.composite_enc_loop: + subs x21,x21,#1 + ldrb w15,[x1,x21] + ldrb w14,[x20,x21] + strb w15,[x13,x21] + strb w14,[x1,x21] + b.gt .composite_enc_loop +.Lxts_enc_load_done: + ld1 {v26.16b},[x1] + eor v26.16b,v26.16b,v6.16b + + // Encrypt the composite block to get the last second encrypted text block + ldr w6,[x3,#240] // load key schedule... + ld1 {v0.16b},[x3],#16 + sub w6,w6,#2 + ld1 {v1.16b},[x3],#16 // load key schedule... +.Loop_final_enc: + aese v26.16b,v0.16b + aesmc v26.16b,v26.16b + ld1 {v0.4s},[x3],#16 + subs w6,w6,#2 + aese v26.16b,v1.16b + aesmc v26.16b,v26.16b + ld1 {v1.4s},[x3],#16 + b.gt .Loop_final_enc + + aese v26.16b,v0.16b + aesmc v26.16b,v26.16b + ld1 {v0.4s},[x3] + aese v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v6.16b + st1 {v26.16b},[x1] + +.Lxts_abort: + ldp x21,x22,[sp,#48] + ldp d8,d9,[sp,#32] + ldp d10,d11,[sp,#16] + ldp x19,x20,[sp],#64 +.Lxts_enc_final_abort: + ret +.size aes_v8_xts_encrypt,.-aes_v8_xts_encrypt +.globl aes_v8_xts_decrypt +.type aes_v8_xts_decrypt,%function +.align 5 +aes_v8_xts_decrypt: + cmp x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne .Lxts_dec_big_size + // Encrypt the iv with key2, as the first XEX iv. + ldr w6,[x4,#240] + ld1 {v0.16b},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.16b},[x4],#16 + +.Loop_dec_small_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt .Loop_dec_small_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + ld1 {v0.16b},[x0] + eor v0.16b,v6.16b,v0.16b + + ldr w6,[x3,#240] + ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... + + aesd v0.16b,v28.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aesd v0.16b,v29.16b + aesimc v0.16b,v0.16b + subs w6,w6,#10 // bias + b.eq .Lxts_128_dec +.Lxts_dec_round_loop: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 // bias + b.gt .Lxts_dec_round_loop +.Lxts_128_dec: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v6.16b,v0.16b + st1 {v0.16b},[x1] + b .Lxts_dec_final_abort +.Lxts_dec_big_size: + stp x19,x20,[sp,#-64]! + stp x21,x22,[sp,#48] + stp d8,d9,[sp,#32] + stp d10,d11,[sp,#16] + + and x21,x2,#0xf + and x2,x2,#-16 + subs x2,x2,#16 + mov x8,#16 + b.lo .Lxts_dec_abort + + // Encrypt the iv with key2, as the first XEX iv + ldr w6,[x4,#240] + ld1 {v0.16b},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.16b},[x4],#16 + +.Loop_dec_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt .Loop_dec_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + // The iv for second block + // x9- iv(low), x10 - iv(high) + // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + + ldr w5,[x3,#240] // load rounds number + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 // load key schedule... + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d10,x9 + fmov v10.d[1],x10 + + add x7,x3,#32 + mov w6,w5 + b .Lxts_dec + + // Decryption +.align 5 +.Lxts_dec: + tst x21,#0xf + b.eq .Lxts_dec_begin + subs x2,x2,#16 + csel x8,xzr,x8,eq + ld1 {v0.16b},[x0],#16 + b.lo .Lxts_done + sub x0,x0,#16 +.Lxts_dec_begin: + ld1 {v0.16b},[x0],x8 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v28.16b,v0.16b,v0.16b + ld1 {v24.16b},[x0],#16 + orr v27.16b,v24.16b,v24.16b + orr v29.16b,v24.16b,v24.16b + b.lo .Lxts_inner_dec_tail + eor v0.16b,v0.16b,v6.16b // before decryt, xor with iv + eor v24.16b,v24.16b,v8.16b + + orr v1.16b,v24.16b,v24.16b + ld1 {v24.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + eor v27.16b,v24.16b,v9.16b // third block xox with third iv + eor v24.16b,v24.16b,v9.16b + cmp x2,#32 + b.lo .Lxts_outer_dec_tail + + ld1 {v25.16b},[x0],#16 + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v26.16b},[x0],#16 + eor v25.16b,v25.16b,v10.16b // the fourth block + eor v26.16b,v26.16b,v11.16b + sub x2,x2,#32 // bias + mov w6,w5 + b .Loop5x_xts_dec + +.align 4 +.Loop5x_xts_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 // load key schedule... + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 // load key schedule... + b.gt .Loop5x_xts_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + subs x2,x2,#0x50 // because .Lxts_dec_tail4x + + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v18.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v18.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v18.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v18.16b + aesimc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because .Lxts_dec_tail4x + + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v19.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v19.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v19.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v19.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v20.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v20.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v21.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v21.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v22.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v22.16b + aesimc v26.16b,v26.16b + + eor v4.16b,v7.16b,v6.16b + aesd v0.16b,v23.16b + // The iv for first block of next iteration. + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v7.16b,v8.16b + ld1 {v2.16b},[x0],#16 + aesd v1.16b,v23.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + eor v17.16b,v7.16b,v9.16b + ld1 {v3.16b},[x0],#16 + aesd v24.16b,v23.16b + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + eor v30.16b,v7.16b,v10.16b + ld1 {v27.16b},[x0],#16 + aesd v25.16b,v23.16b + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d10,x9 + fmov v10.d[1],x10 + eor v31.16b,v7.16b,v11.16b + ld1 {v28.16b},[x0],#16 + aesd v26.16b,v23.16b + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v29.16b},[x0],#16 + cbz x6,.Lxts_dec_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v0.16b,v2.16b,v6.16b + eor v5.16b,v5.16b,v1.16b + eor v1.16b,v3.16b,v8.16b + eor v17.16b,v17.16b,v24.16b + eor v24.16b,v27.16b,v9.16b + eor v30.16b,v30.16b,v25.16b + eor v25.16b,v28.16b,v10.16b + eor v31.16b,v31.16b,v26.16b + st1 {v4.16b},[x1],#16 + eor v26.16b,v29.16b,v11.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs .Loop5x_xts_dec + + cmn x2,#0x10 + b.ne .Loop5x_dec_after + // If x2(x2) equal to -0x10, the left blocks is 4. + // After specially processing, utilize the five blocks processing again. + // It will use the following IVs: v6.16b,v6.16b,v8.16b,v9.16b,v10.16b. + orr v11.16b,v10.16b,v10.16b + orr v10.16b,v9.16b,v9.16b + orr v9.16b,v8.16b,v8.16b + orr v8.16b,v6.16b,v6.16b + fmov x9,d11 + fmov x10,v11.d[1] + eor v0.16b,v6.16b,v2.16b + eor v1.16b,v8.16b,v3.16b + eor v24.16b,v27.16b,v9.16b + eor v25.16b,v28.16b,v10.16b + eor v26.16b,v29.16b,v11.16b + b.eq .Loop5x_xts_dec + +.Loop5x_dec_after: + add x2,x2,#0x50 + cbz x2,.Lxts_done + + add w6,w5,#2 + subs x2,x2,#0x30 + b.lo .Lxts_inner_dec_tail + + eor v0.16b,v6.16b,v27.16b + eor v1.16b,v8.16b,v28.16b + eor v24.16b,v29.16b,v9.16b + b .Lxts_outer_dec_tail + +.align 4 +.Lxts_dec_tail4x: + add x0,x0,#16 + ld1 {v0.4s},[x0],#16 + eor v5.16b,v1.16b,v4.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v24.16b,v17.16b + st1 {v17.16b},[x1],#16 + eor v30.16b,v25.16b,v30.16b + eor v31.16b,v26.16b,v31.16b + st1 {v30.16b,v31.16b},[x1],#32 + + b .Lxts_done +.align 4 +.Lxts_outer_dec_tail: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lxts_outer_dec_tail + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + // The iv for first block + fmov x9,d9 + fmov x10,v9.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v8.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + eor v17.16b,v9.16b,v7.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + + add x6,x6,#0x20 + add x0,x0,x6 // x0 is adjusted to the last data + + mov x7,x3 + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v24.16b,v24.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + st1 {v5.16b},[x1],#16 + st1 {v24.16b},[x1],#16 + + cmn x2,#0x30 + add x2,x2,#0x30 + b.eq .Lxts_done + sub x2,x2,#0x30 + orr v28.16b,v3.16b,v3.16b + orr v29.16b,v27.16b,v27.16b + nop + +.Lxts_inner_dec_tail: + // x2 == -0x10 means two blocks left. + cmn x2,#0x10 + eor v1.16b,v28.16b,v6.16b + eor v24.16b,v29.16b,v8.16b + b.eq .Lxts_dec_tail_loop + eor v24.16b,v29.16b,v6.16b +.Lxts_dec_tail_loop: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lxts_dec_tail_loop + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + eor v5.16b,v6.16b,v7.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + eor v17.16b,v8.16b,v7.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + b.eq .Lxts_dec_one + eor v5.16b,v5.16b,v1.16b + eor v17.16b,v17.16b,v24.16b + orr v6.16b,v9.16b,v9.16b + orr v8.16b,v10.16b,v10.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + add x2,x2,#16 + b .Lxts_done + +.Lxts_dec_one: + eor v5.16b,v5.16b,v24.16b + orr v6.16b,v8.16b,v8.16b + orr v8.16b,v9.16b,v9.16b + st1 {v5.16b},[x1],#16 + add x2,x2,#32 + +.Lxts_done: + tst x21,#0xf + b.eq .Lxts_dec_abort + // Processing the last two blocks with cipher stealing. + mov x7,x3 + cbnz x2,.Lxts_dec_1st_done + ld1 {v0.4s},[x0],#16 + + // Decrypt the last secod block to get the last plain text block +.Lxts_dec_1st_done: + eor v26.16b,v0.16b,v8.16b + ldr w6,[x3,#240] + ld1 {v0.4s},[x3],#16 + sub w6,w6,#2 + ld1 {v1.4s},[x3],#16 +.Loop_final_2nd_dec: + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 + aesd v26.16b,v1.16b + aesimc v26.16b,v26.16b + ld1 {v1.4s},[x3],#16 // load key schedule... + b.gt .Loop_final_2nd_dec + + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x3] + aesd v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v8.16b + st1 {v26.16b},[x1] + + mov x20,x0 + add x13,x1,#16 + + // Composite the tailcnt "16 byte not aligned block" into the last second plain blocks + // to get the last encrypted block. +.composite_dec_loop: + subs x21,x21,#1 + ldrb w15,[x1,x21] + ldrb w14,[x20,x21] + strb w15,[x13,x21] + strb w14,[x1,x21] + b.gt .composite_dec_loop +.Lxts_dec_load_done: + ld1 {v26.16b},[x1] + eor v26.16b,v26.16b,v6.16b + + // Decrypt the composite block to get the last second plain text block + ldr w6,[x7,#240] + ld1 {v0.16b},[x7],#16 + sub w6,w6,#2 + ld1 {v1.16b},[x7],#16 +.Loop_final_dec: + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x7],#16 // load key schedule... + subs w6,w6,#2 + aesd v26.16b,v1.16b + aesimc v26.16b,v26.16b + ld1 {v1.4s},[x7],#16 // load key schedule... + b.gt .Loop_final_dec + + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x7] + aesd v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v6.16b + st1 {v26.16b},[x1] + +.Lxts_dec_abort: + ldp x21,x22,[sp,#48] + ldp d8,d9,[sp,#32] + ldp d10,d11,[sp,#16] + ldp x19,x20,[sp],#64 + +.Lxts_dec_final_abort: + ret +.size aes_v8_xts_decrypt,.-aes_v8_xts_decrypt +#endif diff --git a/crypto/openssl/crypto/aes/asm/aes-586.pl b/crypto/openssl/crypto/aes/asm/aes-586.pl new file mode 100755 index 000000000000..7b4f9e1672f2 --- /dev/null +++ b/crypto/openssl/crypto/aes/asm/aes-586.pl @@ -0,0 +1,2998 @@ +#! /usr/bin/env perl +# Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# +# ==================================================================== +# Written by Andy Polyakov 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 and open STDOUT,">$output"; + +&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 "); + +&asm_finish(); + +close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/aes/asm/aes-armv4.pl b/crypto/openssl/crypto/aes/asm/aes-armv4.pl index 1112eef50c0b..fc9ff7d3e4ee 100755 --- a/crypto/openssl/crypto/aes/asm/aes-armv4.pl +++ b/crypto/openssl/crypto/aes/asm/aes-armv4.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -39,9 +39,10 @@ # Profiler-assisted and platform-specific optimization resulted in 16% # improvement on Cortex A8 core and ~21.5 cycles per byte. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -49,9 +50,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $s0="r0"; @@ -76,7 +78,6 @@ $code=<<___; # define __ARM_ARCH__ __LINUX_ARM_ARCH__ #endif -.text #if defined(__thumb2__) && !defined(__APPLE__) .syntax unified .thumb @@ -85,6 +86,8 @@ $code=<<___; #undef __thumb2__ #endif +.text + .type AES_Te,%object .align 5 AES_Te: diff --git a/crypto/openssl/crypto/aes/asm/aes-c64xplus.pl b/crypto/openssl/crypto/aes/asm/aes-c64xplus.pl index cad3fcd06e36..fa9a132d90fb 100755 --- a/crypto/openssl/crypto/aes/asm/aes-c64xplus.pl +++ b/crypto/openssl/crypto/aes/asm/aes-c64xplus.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -37,8 +37,7 @@ # cost of 8x increased pressure on L1D. 8x because you'd have # to interleave both Te and Td tables... -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; ($TEA,$TEB)=("A5","B5"); ($KPA,$KPB)=("A3","B1"); diff --git a/crypto/openssl/crypto/aes/asm/aes-ia64.S b/crypto/openssl/crypto/aes/asm/aes-ia64.S index 03f79b7ae3b7..ad9e466bbc18 100644 --- a/crypto/openssl/crypto/aes/asm/aes-ia64.S +++ b/crypto/openssl/crypto/aes/asm/aes-ia64.S @@ -1,6 +1,6 @@ // Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. // -// Licensed under the OpenSSL license (the "License"). You may not use +// 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 @@ -8,7 +8,7 @@ // ==================================================================== // Written by Andy Polyakov for the OpenSSL // project. Rights for redistribution and usage in source and binary -// forms are granted according to the OpenSSL license. +// forms are granted according to the License. // ==================================================================== // // What's wrong with compiler generated code? Compiler never uses diff --git a/crypto/openssl/crypto/aes/asm/aes-mips.pl b/crypto/openssl/crypto/aes/asm/aes-mips.pl index b5601e90ea3f..290621acc2cf 100755 --- a/crypto/openssl/crypto/aes/asm/aes-mips.pl +++ b/crypto/openssl/crypto/aes/asm/aes-mips.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -34,6 +34,11 @@ # instead, code path is chosen upon pre-process time, pass -mips32r2 # or/and -msmartmips. +# February 2019 +# +# Normalize MIPS32R2 AES table address calculation by always using EXT +# instruction. This reduces the standard codebase by another 10%. + ###################################################################### # There is a number of MIPS ABI in use, O32 and N32/64 are most # widely used. Then there is a new contender: NUBI. It appears that if @@ -60,8 +65,12 @@ # ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); # ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); # ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); -# -$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; +$flavour ||= "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 if ($flavour =~ /64|n32/i) { $PTR_LA="dla"; @@ -90,17 +99,13 @@ $pf = ($flavour =~ /nubi/i) ? $t0 : $t2; $big_endian=(`echo MIPSEB | $ENV{CC} -E -`=~/MIPSEB/)?0:1 if ($ENV{CC}); -for (@ARGV) { $output=$_ if (/\w[\w\-]*\.\w+$/); } -open STDOUT,">$output"; - if (!defined($big_endian)) { $big_endian=(unpack('L',pack('N',1))==1); } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; - my ($MSB,$LSB)=(0,3); # automatically converted to little-endian +$output and open STDOUT,">$output"; + $code.=<<___; #include "mips_arch.h" @@ -223,6 +228,33 @@ _mips_AES_encrypt: ext $i0,$s1,16,8 _xtr $i0,$s1,16-2 +#else +#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) + move $i0,$Tbl + move $i1,$Tbl + move $i2,$Tbl + move $i3,$Tbl + ext $t0,$s1,16,8 +.Loop_enc: + ext $t1,$s2,16,8 + ext $t2,$s3,16,8 + ext $t3,$s0,16,8 + $PTR_INS $i0,$t0,2,8 + $PTR_INS $i1,$t1,2,8 + $PTR_INS $i2,$t2,2,8 + $PTR_INS $i3,$t3,2,8 + lw $t0,0($i0) # Te1[s1>>16] + ext $t4,$s2,8,8 + lw $t1,0($i1) # Te1[s2>>16] + ext $t5,$s3,8,8 + lw $t2,0($i2) # Te1[s3>>16] + ext $t6,$s0,8,8 + lw $t3,0($i3) # Te1[s0>>16] + ext $t7,$s1,8,8 + $PTR_INS $i0,$t4,2,8 + $PTR_INS $i1,$t5,2,8 + $PTR_INS $i2,$t6,2,8 + $PTR_INS $i3,$t7,2,8 #else _xtr $i0,$s1,16-2 .Loop_enc: @@ -237,16 +269,6 @@ _mips_AES_encrypt: $PTR_ADD $i1,$Tbl $PTR_ADD $i2,$Tbl $PTR_ADD $i3,$Tbl -#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) - lw $t0,0($i0) # Te1[s1>>16] - _xtr $i0,$s2,8-2 - lw $t1,0($i1) # Te1[s2>>16] - _xtr $i1,$s3,8-2 - lw $t2,0($i2) # Te1[s3>>16] - _xtr $i2,$s0,8-2 - lw $t3,0($i3) # Te1[s0>>16] - _xtr $i3,$s1,8-2 -#else lwl $t0,3($i0) # Te1[s1>>16] lwl $t1,3($i1) # Te1[s2>>16] lwl $t2,3($i2) # Te1[s3>>16] @@ -259,7 +281,6 @@ _mips_AES_encrypt: _xtr $i2,$s0,8-2 lwr $t3,2($i3) # Te1[s0>>16] _xtr $i3,$s1,8-2 -#endif and $i0,0x3fc and $i1,0x3fc and $i2,0x3fc @@ -268,6 +289,7 @@ _mips_AES_encrypt: $PTR_ADD $i1,$Tbl $PTR_ADD $i2,$Tbl $PTR_ADD $i3,$Tbl +#endif #if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) rotr $t0,$t0,8 rotr $t1,$t1,8 @@ -275,22 +297,18 @@ _mips_AES_encrypt: rotr $t3,$t3,8 # if defined(_MIPSEL) lw $t4,0($i0) # Te2[s2>>8] - _xtr $i0,$s3,0-2 + ext $t8,$s3,0,8 lw $t5,0($i1) # Te2[s3>>8] - _xtr $i1,$s0,0-2 + ext $t9,$s0,0,8 lw $t6,0($i2) # Te2[s0>>8] - _xtr $i2,$s1,0-2 + ext $t10,$s1,0,8 lw $t7,0($i3) # Te2[s1>>8] - _xtr $i3,$s2,0-2 + ext $t11,$s2,0,8 + $PTR_INS $i0,$t8,2,8 + $PTR_INS $i1,$t9,2,8 + $PTR_INS $i2,$t10,2,8 + $PTR_INS $i3,$t11,2,8 - and $i0,0x3fc - and $i1,0x3fc - and $i2,0x3fc - and $i3,0x3fc - $PTR_ADD $i0,$Tbl - $PTR_ADD $i1,$Tbl - $PTR_ADD $i2,$Tbl - $PTR_ADD $i3,$Tbl lw $t8,0($i0) # Te3[s3] $PTR_INS $i0,$s0,2,8 lw $t9,0($i1) # Te3[s0] @@ -411,6 +429,9 @@ _mips_AES_encrypt: xor $s3,$t3 .set noreorder bnez $cnt,.Loop_enc +#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) + ext $t0,$s1,16,8 +#endif _xtr $i0,$s1,16-2 #endif @@ -811,6 +832,33 @@ _mips_AES_decrypt: ext $i0,$s3,16,8 _xtr $i0,$s3,16-2 +#else +#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) + move $i0,$Tbl + move $i1,$Tbl + move $i2,$Tbl + move $i3,$Tbl + ext $t0,$s3,16,8 +.Loop_dec: + ext $t1,$s0,16,8 + ext $t2,$s1,16,8 + ext $t3,$s2,16,8 + $PTR_INS $i0,$t0,2,8 + $PTR_INS $i1,$t1,2,8 + $PTR_INS $i2,$t2,2,8 + $PTR_INS $i3,$t3,2,8 + lw $t0,0($i0) # Td1[s3>>16] + ext $t4,$s2,8,8 + lw $t1,0($i1) # Td1[s0>>16] + ext $t5,$s3,8,8 + lw $t2,0($i2) # Td1[s1>>16] + ext $t6,$s0,8,8 + lw $t3,0($i3) # Td1[s2>>16] + ext $t7,$s1,8,8 + $PTR_INS $i0,$t4,2,8 + $PTR_INS $i1,$t5,2,8 + $PTR_INS $i2,$t6,2,8 + $PTR_INS $i3,$t7,2,8 #else _xtr $i0,$s3,16-2 .Loop_dec: @@ -825,16 +873,6 @@ _mips_AES_decrypt: $PTR_ADD $i1,$Tbl $PTR_ADD $i2,$Tbl $PTR_ADD $i3,$Tbl -#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) - lw $t0,0($i0) # Td1[s3>>16] - _xtr $i0,$s2,8-2 - lw $t1,0($i1) # Td1[s0>>16] - _xtr $i1,$s3,8-2 - lw $t2,0($i2) # Td1[s1>>16] - _xtr $i2,$s0,8-2 - lw $t3,0($i3) # Td1[s2>>16] - _xtr $i3,$s1,8-2 -#else lwl $t0,3($i0) # Td1[s3>>16] lwl $t1,3($i1) # Td1[s0>>16] lwl $t2,3($i2) # Td1[s1>>16] @@ -847,8 +885,6 @@ _mips_AES_decrypt: _xtr $i2,$s0,8-2 lwr $t3,2($i3) # Td1[s2>>16] _xtr $i3,$s1,8-2 -#endif - and $i0,0x3fc and $i1,0x3fc and $i2,0x3fc @@ -857,6 +893,7 @@ _mips_AES_decrypt: $PTR_ADD $i1,$Tbl $PTR_ADD $i2,$Tbl $PTR_ADD $i3,$Tbl +#endif #if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) rotr $t0,$t0,8 rotr $t1,$t1,8 @@ -864,22 +901,17 @@ _mips_AES_decrypt: rotr $t3,$t3,8 # if defined(_MIPSEL) lw $t4,0($i0) # Td2[s2>>8] - _xtr $i0,$s1,0-2 + ext $t8,$s1,0,8 lw $t5,0($i1) # Td2[s3>>8] - _xtr $i1,$s2,0-2 + ext $t9,$s2,0,8 lw $t6,0($i2) # Td2[s0>>8] - _xtr $i2,$s3,0-2 + ext $t10,$s3,0,8 lw $t7,0($i3) # Td2[s1>>8] - _xtr $i3,$s0,0-2 - - and $i0,0x3fc - and $i1,0x3fc - and $i2,0x3fc - and $i3,0x3fc - $PTR_ADD $i0,$Tbl - $PTR_ADD $i1,$Tbl - $PTR_ADD $i2,$Tbl - $PTR_ADD $i3,$Tbl + ext $t11,$s0,0,8 + $PTR_INS $i0,$t8,2,8 + $PTR_INS $i1,$t9,2,8 + $PTR_INS $i2,$t10,2,8 + $PTR_INS $i3,$t11,2,8 lw $t8,0($i0) # Td3[s1] $PTR_INS $i0,$s0,2,8 lw $t9,0($i1) # Td3[s2] @@ -1001,6 +1033,10 @@ _mips_AES_decrypt: xor $s3,$t3 .set noreorder bnez $cnt,.Loop_dec +#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2) + ext $t0,$s3,16,8 +#endif + _xtr $i0,$s3,16-2 #endif diff --git a/crypto/openssl/crypto/aes/asm/aes-parisc.pl b/crypto/openssl/crypto/aes/asm/aes-parisc.pl index 5b07fac3d004..3d55eec9bb37 100755 --- a/crypto/openssl/crypto/aes/asm/aes-parisc.pl +++ b/crypto/openssl/crypto/aes/asm/aes-parisc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -28,9 +28,12 @@ # # Special thanks to polarhome.com for providing HP-UX account. -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/openssl/crypto/aes/asm/aes-ppc.pl b/crypto/openssl/crypto/aes/asm/aes-ppc.pl index bb4ee84ae337..595182c89bf3 100755 --- a/crypto/openssl/crypto/aes/asm/aes-ppc.pl +++ b/crypto/openssl/crypto/aes/asm/aes-ppc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -36,7 +36,10 @@ # ppc_AES_encrypt_compact operates at 42 cycles per byte, while # ppc_AES_decrypt_compact - at 55 (in 64-bit build). -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -59,7 +62,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=32*$SIZE_T; diff --git a/crypto/openssl/crypto/aes/asm/aes-s390x.pl b/crypto/openssl/crypto/aes/asm/aes-s390x.pl index 4cb8f4331742..5d1283f57690 100755 --- a/crypto/openssl/crypto/aes/asm/aes-s390x.pl +++ b/crypto/openssl/crypto/aes/asm/aes-s390x.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -89,7 +89,10 @@ # instructions, which deliver ~70% improvement at 8KB block size over # vanilla km-based code, 37% - at most like 512-bytes block size. -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -99,8 +102,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $softonly=0; # allow hardware support diff --git a/crypto/openssl/crypto/aes/asm/aes-sparcv9.pl b/crypto/openssl/crypto/aes/asm/aes-sparcv9.pl index 1b37a9203c27..d15640e3d76b 100755 --- a/crypto/openssl/crypto/aes/asm/aes-sparcv9.pl +++ b/crypto/openssl/crypto/aes/asm/aes-sparcv9.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -10,7 +10,7 @@ # ==================================================================== # Written by Andy Polyakov for the OpenSSL # project. Rights for redistribution and usage in source and binary -# forms are granted according to the OpenSSL license. +# forms are granted according to the License. # ==================================================================== # # Version 1.1 @@ -37,8 +37,7 @@ # optimal decrypt procedure]. Compared to GNU C generated code both # procedures are more than 60% faster:-) -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $frame="STACK_FRAME"; $bias="STACK_BIAS"; @@ -83,7 +82,10 @@ sub _data_word() } $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #ifdef __arch64__ .register %g2,#scratch diff --git a/crypto/openssl/crypto/aes/asm/aes-x86_64.pl b/crypto/openssl/crypto/aes/asm/aes-x86_64.pl new file mode 100755 index 000000000000..25f7ded947ed --- /dev/null +++ b/crypto/openssl/crypto/aes/asm/aes-x86_64.pl @@ -0,0 +1,2927 @@ +#! /usr/bin/env perl +# Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# +# ==================================================================== +# Written by Andy Polyakov 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 + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; +*STDOUT=*OUT; + +$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: +.cfi_startproc + 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 +.cfi_endproc +.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 + endbranch + 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: +.cfi_startproc + 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 +.cfi_endproc +.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 + endbranch + 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 + endbranch + 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 + endbranch + 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 + endbranch + 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 " +.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->RipRsp + + 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->RipRsp + + 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 or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/aes/asm/aesfx-sparcv9.pl b/crypto/openssl/crypto/aes/asm/aesfx-sparcv9.pl index 1678c4f786f2..27233d03af7b 100755 --- a/crypto/openssl/crypto/aes/asm/aesfx-sparcv9.pl +++ b/crypto/openssl/crypto/aes/asm/aesfx-sparcv9.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -33,14 +33,16 @@ # instructions and improve single-block and short-input performance # with misaligned data. -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; { my ($inp,$out,$key,$rounds,$tmp,$mask) = map("%o$_",(0..5)); $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #define LOCALS (STACK_BIAS+STACK_FRAME) diff --git a/crypto/openssl/crypto/aes/asm/aesni-mb-x86_64.pl b/crypto/openssl/crypto/aes/asm/aesni-mb-x86_64.pl index a80cfdc13948..dde15b1ef7ee 100755 --- a/crypto/openssl/crypto/aes/asm/aesni-mb-x86_64.pl +++ b/crypto/openssl/crypto/aes/asm/aesni-mb-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -42,9 +42,10 @@ # (*) Sandy/Ivy Bridge are known to handle high interleave factors # suboptimally; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -53,6 +54,11 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86_64-support.pl"; + +$ptr_size=&pointer_size($flavour); + $avx=0; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` @@ -74,7 +80,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0 $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; # void aesni_multi_cbc_encrypt ( @@ -86,6 +93,8 @@ $inp="%rdi"; # 1st arg $key="%rsi"; # 2nd arg $num="%edx"; +$inp_elm_size=2*$ptr_size+8+16; + @inptr=map("%r$_",(8..11)); @outptr=map("%r$_",(12..15)); @@ -161,21 +170,25 @@ $code.=<<___; .Lenc4x_body: movdqu ($key),$zero # 0-round key lea 0x78($key),$key # size optimization - lea 40*2($inp),$inp + lea $inp_elm_size*2($inp),$inp .Lenc4x_loop_grande: mov $num,24(%rsp) # original $num xor $num,$num ___ for($i=0;$i<4;$i++) { + $inptr_reg=&pointer_register($flavour,@inptr[$i]); + $outptr_reg=&pointer_register($flavour,@outptr[$i]); $code.=<<___; - mov `40*$i+16-40*2`($inp),$one # borrow $one for number of blocks - mov `40*$i+0-40*2`($inp),@inptr[$i] + # borrow $one for number of blocks + mov `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*2`($inp),$one + mov `$inp_elm_size*$i+0-$inp_elm_size*2`($inp),$inptr_reg cmp $num,$one - mov `40*$i+8-40*2`($inp),@outptr[$i] + mov `$inp_elm_size*$i+$ptr_size-$inp_elm_size*2`($inp),$outptr_reg cmovg $one,$num # find maximum test $one,$one - movdqu `40*$i+24-40*2`($inp),@out[$i] # load IV + # load IV + movdqu `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*2`($inp),@out[$i] mov $one,`32+4*$i`(%rsp) # initialize counters cmovle %rsp,@inptr[$i] # cancel input ___ @@ -333,14 +346,15 @@ $code.=<<___; #pxor @inp[0],@out[0] #pxor @inp[1],@out[1] - #movdqu @out[0],`40*0+24-40*2`($inp) # output iv FIX ME! + # output iv FIX ME! + #movdqu @out[0],`$inp_elm_size*0+2*$ptr_size+8-$inp_elm_size*2`($inp) #pxor @inp[2],@out[2] - #movdqu @out[1],`40*1+24-40*2`($inp) + #movdqu @out[1],`$inp_elm_size*1+2*$ptr_size+8-$inp_elm_size*2`($inp) #pxor @inp[3],@out[3] - #movdqu @out[2],`40*2+24-40*2`($inp) # won't fix, let caller - #movdqu @out[3],`40*3+24-40*2`($inp) # figure this out... + #movdqu @out[2],`$inp_elm_size*2+2*$ptr_size+8-$inp_elm_size*2`($inp) # won't fix, let caller + #movdqu @out[3],`$inp_elm_size*3+2*$ptr_size+8-$inp_elm_size*2`($inp) # figure this out... - lea `40*4`($inp),$inp + lea `$inp_elm_size*4`($inp),$inp dec $num jnz .Lenc4x_loop_grande @@ -438,21 +452,25 @@ $code.=<<___; .Ldec4x_body: movdqu ($key),$zero # 0-round key lea 0x78($key),$key # size optimization - lea 40*2($inp),$inp + lea $inp_elm_size*2($inp),$inp .Ldec4x_loop_grande: mov $num,24(%rsp) # original $num xor $num,$num ___ for($i=0;$i<4;$i++) { + $inptr_reg=&pointer_register($flavour,@inptr[$i]); + $outptr_reg=&pointer_register($flavour,@outptr[$i]); $code.=<<___; - mov `40*$i+16-40*2`($inp),$one # borrow $one for number of blocks - mov `40*$i+0-40*2`($inp),@inptr[$i] + # borrow $one for number of blocks + mov `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*2`($inp),$one + mov `$inp_elm_size*$i+0-$inp_elm_size*2`($inp),$inptr_reg cmp $num,$one - mov `40*$i+8-40*2`($inp),@outptr[$i] + mov `$inp_elm_size*$i+$ptr_size-$inp_elm_size*2`($inp),$outptr_reg cmovg $one,$num # find maximum test $one,$one - movdqu `40*$i+24-40*2`($inp),@inp[$i] # load IV + # load IV + movdqu `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*2`($inp),@inp[$i] mov $one,`32+4*$i`(%rsp) # initialize counters cmovle %rsp,@inptr[$i] # cancel input ___ @@ -608,7 +626,7 @@ $code.=<<___; .cfi_def_cfa %rax,8 mov 24(%rsp),$num - lea `40*4`($inp),$inp + lea `$inp_elm_size*4`($inp),$inp dec $num jnz .Ldec4x_loop_grande @@ -707,7 +725,7 @@ $code.=<<___; vzeroupper vmovdqu ($key),$zero # 0-round key lea 0x78($key),$key # size optimization - lea 40*4($inp),$inp + lea `$inp_elm_size*4`($inp),$inp shr \$1,$num .Lenc8x_loop_grande: @@ -716,14 +734,20 @@ $code.=<<___; ___ for($i=0;$i<8;$i++) { my $temp = $i ? $offload : $offset; + $ptr_reg=&pointer_register($flavour,@ptr[$i]); + $temp_reg=&pointer_register($flavour,$temp); $code.=<<___; - mov `40*$i+16-40*4`($inp),$one # borrow $one for number of blocks - mov `40*$i+0-40*4`($inp),@ptr[$i] # input pointer + # borrow $one for number of blocks + mov `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*4`($inp),$one + # input pointer + mov `$inp_elm_size*$i+0-$inp_elm_size*4`($inp),$ptr_reg cmp $num,$one - mov `40*$i+8-40*4`($inp),$temp # output pointer + # output pointer + mov `$inp_elm_size*$i+$ptr_size-$inp_elm_size*4`($inp),$temp_reg cmovg $one,$num # find maximum test $one,$one - vmovdqu `40*$i+24-40*4`($inp),@out[$i] # load IV + # load IV + vmovdqu `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*4`($inp),@out[$i] mov $one,`32+4*$i`(%rsp) # initialize counters cmovle %rsp,@ptr[$i] # cancel input sub @ptr[$i],$temp # distance between input and output @@ -908,7 +932,7 @@ $code.=<<___; mov 16(%rsp),%rax # original %rsp .cfi_def_cfa %rax,8 #mov 24(%rsp),$num - #lea `40*8`($inp),$inp + #lea `$inp_elm_size*8`($inp),$inp #dec $num #jnz .Lenc8x_loop_grande @@ -1000,7 +1024,7 @@ $code.=<<___; vzeroupper vmovdqu ($key),$zero # 0-round key lea 0x78($key),$key # size optimization - lea 40*4($inp),$inp + lea `$inp_elm_size*4`($inp),$inp shr \$1,$num .Ldec8x_loop_grande: @@ -1009,14 +1033,20 @@ $code.=<<___; ___ for($i=0;$i<8;$i++) { my $temp = $i ? $offload : $offset; + $ptr_reg=&pointer_register($flavour,@ptr[$i]); + $temp_reg=&pointer_register($flavour,$temp); $code.=<<___; - mov `40*$i+16-40*4`($inp),$one # borrow $one for number of blocks - mov `40*$i+0-40*4`($inp),@ptr[$i] # input pointer + # borrow $one for number of blocks + mov `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*4`($inp),$one + # input pointer + mov `$inp_elm_size*$i+0-$inp_elm_size*4`($inp),$ptr_reg cmp $num,$one - mov `40*$i+8-40*4`($inp),$temp # output pointer + # output pointer + mov `$inp_elm_size*$i+$ptr_size-$inp_elm_size*4`($inp),$temp_reg cmovg $one,$num # find maximum test $one,$one - vmovdqu `40*$i+24-40*4`($inp),@out[$i] # load IV + # load IV + vmovdqu `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*4`($inp),@out[$i] mov $one,`32+4*$i`(%rsp) # initialize counters cmovle %rsp,@ptr[$i] # cancel input sub @ptr[$i],$temp # distance between input and output @@ -1232,7 +1262,7 @@ $code.=<<___; mov 16(%rsp),%rax # original %rsp .cfi_def_cfa %rax,8 #mov 24(%rsp),$num - #lea `40*8`($inp),$inp + #lea `$inp_elm_size*8`($inp),$inp #dec $num #jnz .Ldec8x_loop_grande diff --git a/crypto/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl b/crypto/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl index 04fd13be5e09..dbe33a3f1a02 100755 --- a/crypto/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl +++ b/crypto/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -88,9 +88,10 @@ # (**) Execution is fully dominated by integer code sequence and # SIMD still hardly shows [in single-process benchmark;-] -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -114,7 +115,8 @@ $shaext=1; ### set to zero if compiling for 1.0.1 $stitched_decrypt=0; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; # void aesni_cbc_sha1_enc(const void *inp, diff --git a/crypto/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl b/crypto/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl index ff9b18507da0..5521766a6a7d 100755 --- a/crypto/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl +++ b/crypto/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -44,9 +44,10 @@ # -evp aes-256-cbc-hmac-sha256' will vary by percent or two; # (***) these are SHAEXT results; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -77,7 +78,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0 $shaext=$avx; ### set to zero if compiling for 1.0.1 $avx=1 if (!$shaext && $avx); -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $func="aesni_cbc_sha256_enc"; diff --git a/crypto/openssl/crypto/aes/asm/aesni-x86.pl b/crypto/openssl/crypto/aes/asm/aesni-x86.pl index 3502940d5233..d8cc378b5f9b 100755 --- a/crypto/openssl/crypto/aes/asm/aesni-x86.pl +++ b/crypto/openssl/crypto/aes/asm/aesni-x86.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2009-2022 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -76,9 +76,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open OUT,">$output"; -*STDOUT=*OUT; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/openssl/crypto/aes/asm/aesni-x86_64.pl b/crypto/openssl/crypto/aes/asm/aesni-x86_64.pl index f8c2e2393438..09c8f78890ed 100755 --- a/crypto/openssl/crypto/aes/asm/aesni-x86_64.pl +++ b/crypto/openssl/crypto/aes/asm/aesni-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -192,9 +192,10 @@ $PREFIX="aesni"; # if $PREFIX is set to "AES", the script # generates drop-in replacement for # crypto/aes/asm/aes-x86_64.pl:-) -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -203,7 +204,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $movkey = $PREFIX eq "aesni" ? "movups" : "movups"; @@ -275,6 +277,7 @@ $code.=<<___; .align 16 ${PREFIX}_encrypt: .cfi_startproc + endbranch movups ($inp),$inout0 # load input mov 240($key),$rounds # key->rounds ___ @@ -293,6 +296,7 @@ $code.=<<___; .align 16 ${PREFIX}_decrypt: .cfi_startproc + endbranch movups ($inp),$inout0 # load input mov 240($key),$rounds # key->rounds ___ @@ -613,6 +617,7 @@ $code.=<<___; .align 16 aesni_ecb_encrypt: .cfi_startproc + endbranch ___ $code.=<<___ if ($win64); lea -0x58(%rsp),%rsp @@ -985,6 +990,7 @@ $code.=<<___; .align 16 aesni_ccm64_encrypt_blocks: .cfi_startproc + endbranch ___ $code.=<<___ if ($win64); lea -0x58(%rsp),%rsp @@ -1077,6 +1083,7 @@ $code.=<<___; .align 16 aesni_ccm64_decrypt_blocks: .cfi_startproc + endbranch ___ $code.=<<___ if ($win64); lea -0x58(%rsp),%rsp @@ -1203,6 +1210,7 @@ $code.=<<___; .align 16 aesni_ctr32_encrypt_blocks: .cfi_startproc + endbranch cmp \$1,$len jne .Lctr32_bulk @@ -1775,6 +1783,7 @@ $code.=<<___; .align 16 aesni_xts_encrypt: .cfi_startproc + endbranch lea (%rsp),%r11 # frame pointer .cfi_def_cfa_register %r11 push %rbp @@ -2258,6 +2267,7 @@ $code.=<<___; .align 16 aesni_xts_decrypt: .cfi_startproc + endbranch lea (%rsp),%r11 # frame pointer .cfi_def_cfa_register %r11 push %rbp @@ -2783,6 +2793,7 @@ $code.=<<___; .align 32 aesni_ocb_encrypt: .cfi_startproc + endbranch lea (%rsp),%rax push %rbx .cfi_push %rbx @@ -3249,6 +3260,7 @@ __ocb_encrypt1: .align 32 aesni_ocb_decrypt: .cfi_startproc + endbranch lea (%rsp),%rax push %rbx .cfi_push %rbx @@ -3737,6 +3749,7 @@ $code.=<<___; .align 16 ${PREFIX}_cbc_encrypt: .cfi_startproc + endbranch test $len,$len # check length jz .Lcbc_ret diff --git a/crypto/openssl/crypto/aes/asm/aesp8-ppc.pl b/crypto/openssl/crypto/aes/asm/aesp8-ppc.pl index 22a538f9e24f..60cf86f52aed 100755 --- a/crypto/openssl/crypto/aes/asm/aesp8-ppc.pl +++ b/crypto/openssl/crypto/aes/asm/aesp8-ppc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -43,7 +43,10 @@ # POWER9[le] 4.02/0.86 0.84 1.05 # POWER9[be] 3.99/0.78 0.79 0.97 -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -70,7 +73,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=8*$SIZE_T; $prefix="aes_p8"; diff --git a/crypto/openssl/crypto/aes/asm/aest4-sparcv9.pl b/crypto/openssl/crypto/aes/asm/aest4-sparcv9.pl index 478c97eb6feb..c04b5f3cdaf8 100755 --- a/crypto/openssl/crypto/aes/asm/aest4-sparcv9.pl +++ b/crypto/openssl/crypto/aes/asm/aest4-sparcv9.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -75,8 +75,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "sparcv9_modes.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $::evp=1; # if $evp is set to 0, script generates module with # AES_[en|de]crypt, AES_set_[en|de]crypt_key and AES_cbc_encrypt entry @@ -92,7 +91,10 @@ $::evp=1; # if $evp is set to 0, script generates module with my ($inp,$out,$key,$rounds,$tmp,$mask)=map("%o$_",(0..5)); $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #ifdef __arch64__ .register %g2,#scratch diff --git a/crypto/openssl/crypto/aes/asm/aesv8-armx.pl b/crypto/openssl/crypto/aes/asm/aesv8-armx.pl index ff5b742cf5ed..6a7bf05d1b35 100755 --- a/crypto/openssl/crypto/aes/asm/aesv8-armx.pl +++ b/crypto/openssl/crypto/aes/asm/aesv8-armx.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2014-2022 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -27,44 +27,72 @@ # CBC encrypt case. On Cortex-A57 parallelizable mode performance # seems to be limited by sheer amount of NEON instructions... # +# April 2019 +# +# Key to performance of parallelize-able modes is round instruction +# interleaving. But which factor to use? There is optimal one for +# each combination of instruction latency and issue rate, beyond +# which increasing interleave factor doesn't pay off. While on cons +# side we have code size increase and resource waste on platforms for +# which interleave factor is too high. In other words you want it to +# be just right. So far interleave factor of 3x was serving well all +# platforms. But for ThunderX2 optimal interleave factor was measured +# to be 5x... +# # Performance in cycles per byte processed with 128-bit key: # # CBC enc CBC dec CTR # Apple A7 2.39 1.20 1.20 -# Cortex-A53 1.32 1.29 1.46 -# Cortex-A57(*) 1.95 0.85 0.93 -# Denver 1.96 0.86 0.80 -# Mongoose 1.33 1.20 1.20 -# Kryo 1.26 0.94 1.00 +# Cortex-A53 1.32 1.17/1.29(**) 1.36/1.46 +# Cortex-A57(*) 1.95 0.82/0.85 0.89/0.93 +# Cortex-A72 1.33 0.85/0.88 0.92/0.96 +# Denver 1.96 0.65/0.86 0.76/0.80 +# Mongoose 1.33 1.23/1.20 1.30/1.20 +# Kryo 1.26 0.87/0.94 1.00/1.00 +# ThunderX2 5.95 1.25 1.30 # # (*) original 3.64/1.34/1.32 results were for r0p0 revision # and are still same even for updated module; +# (**) numbers after slash are for 32-bit code, which is 3x- +# interleaved; -$flavour = shift; -$output = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $prefix="aes_v8"; +$_byte = ($flavour =~ /win/ ? "DCB" : ".byte"); + $code=<<___; #include "arm_arch.h" #if __ARM_MAX_ARCH__>=7 -.text ___ -# $code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/); +$code.=".arch armv8-a+crypto\n.text\n" if ($flavour =~ /64/); $code.=<<___ if ($flavour !~ /64/); .arch armv7-a // don't confuse not-so-latest binutils with argv8 :-) .fpu neon +#ifdef __thumb2__ +.syntax unified +.thumb +# define INST(a,b,c,d) $_byte c,d|0xc,a,b +#else .code 32 -#undef __thumb2__ +# define INST(a,b,c,d) $_byte a,b,c,d +#endif + +.text ___ # Assembler mnemonics are an eclectic mix of 32- and 64-bit syntax, @@ -361,21 +389,148 @@ ___ &gen_block("en"); &gen_block("de"); }}} + +# Performance in cycles per byte. +# Processed with AES-ECB different key size. +# It shows the value before and after optimization as below: +# (before/after): +# +# AES-128-ECB AES-192-ECB AES-256-ECB +# Cortex-A57 1.85/0.82 2.16/0.96 2.47/1.10 +# Cortex-A72 1.64/0.85 1.82/0.99 2.13/1.14 + +# Optimization is implemented by loop unrolling and interleaving. +# Commonly, we choose the unrolling factor as 5, if the input +# data size smaller than 5 blocks, but not smaller than 3 blocks, +# choose 3 as the unrolling factor. +# If the input data size dsize >= 5*16 bytes, then take 5 blocks +# as one iteration, every loop the left size lsize -= 5*16. +# If 5*16 > lsize >= 3*16 bytes, take 3 blocks as one iteration, +# every loop lsize -=3*16. +# If lsize < 3*16 bytes, treat them as the tail, interleave the +# two blocks AES instructions. +# There is one special case, if the original input data size dsize +# = 16 bytes, we will treat it seperately to improve the +# performance: one independent code block without LR, FP load and +# store, just looks like what the original ECB implementation does. + {{{ -my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4)); my $enc="w5"; -my ($rounds,$cnt,$key_,$step,$step1)=($enc,"w6","x7","x8","x12"); -my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$ivec,$rndlast)=map("q$_",(0..7)); +my ($inp,$out,$len,$key)=map("x$_",(0..3)); +my ($enc,$rounds,$cnt,$key_,$step)=("w4","w5","w6","x7","x8"); +my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$tmp2,$rndlast)=map("q$_",(0..7)); my ($dat,$tmp,$rndzero_n_last)=($dat0,$tmp0,$tmp1); -my ($key4,$key5,$key6,$key7)=("x6","x12","x14",$key); -### q8-q15 preloaded key schedule +### q7 last round key +### q10-q15 q7 Last 7 round keys +### q8-q9 preloaded round keys except last 7 keys for big size +### q5, q6, q8-q9 preloaded round keys except last 7 keys for only 16 byte + +{ +my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9)); + +my ($dat3,$in3,$tmp3); # used only in 64-bit mode +my ($dat4,$in4,$tmp4); +if ($flavour =~ /64/) { + ($dat2,$dat3,$dat4,$in2,$in3,$in4,$tmp3,$tmp4)=map("q$_",(16..23)); +} $code.=<<___; -.globl ${prefix}_cbc_encrypt -.type ${prefix}_cbc_encrypt,%function +.globl ${prefix}_ecb_encrypt +.type ${prefix}_ecb_encrypt,%function .align 5 -${prefix}_cbc_encrypt: +${prefix}_ecb_encrypt: +___ +$code.=<<___ if ($flavour =~ /64/); + subs $len,$len,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne .Lecb_big_size + vld1.8 {$dat0},[$inp] + cmp $enc,#0 // en- or decrypting? + ldr $rounds,[$key,#240] + vld1.32 {q5-q6},[$key],#32 // load key schedule... + + b.eq .Lecb_small_dec + aese $dat0,q5 + aesmc $dat0,$dat0 + vld1.32 {q8-q9},[$key],#32 // load key schedule... + aese $dat0,q6 + aesmc $dat0,$dat0 + subs $rounds,$rounds,#10 // if rounds==10, jump to aes-128-ecb processing + b.eq .Lecb_128_enc +.Lecb_round_loop: + aese $dat0,q8 + aesmc $dat0,$dat0 + vld1.32 {q8},[$key],#16 // load key schedule... + aese $dat0,q9 + aesmc $dat0,$dat0 + vld1.32 {q9},[$key],#16 // load key schedule... + subs $rounds,$rounds,#2 // bias + b.gt .Lecb_round_loop +.Lecb_128_enc: + vld1.32 {q10-q11},[$key],#32 // load key schedule... + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat0,q9 + aesmc $dat0,$dat0 + vld1.32 {q12-q13},[$key],#32 // load key schedule... + aese $dat0,q10 + aesmc $dat0,$dat0 + aese $dat0,q11 + aesmc $dat0,$dat0 + vld1.32 {q14-q15},[$key],#32 // load key schedule... + aese $dat0,q12 + aesmc $dat0,$dat0 + aese $dat0,q13 + aesmc $dat0,$dat0 + vld1.32 {$rndlast},[$key] + aese $dat0,q14 + aesmc $dat0,$dat0 + aese $dat0,q15 + veor $dat0,$dat0,$rndlast + vst1.8 {$dat0},[$out] + b .Lecb_Final_abort +.Lecb_small_dec: + aesd $dat0,q5 + aesimc $dat0,$dat0 + vld1.32 {q8-q9},[$key],#32 // load key schedule... + aesd $dat0,q6 + aesimc $dat0,$dat0 + subs $rounds,$rounds,#10 // bias + b.eq .Lecb_128_dec +.Lecb_dec_round_loop: + aesd $dat0,q8 + aesimc $dat0,$dat0 + vld1.32 {q8},[$key],#16 // load key schedule... + aesd $dat0,q9 + aesimc $dat0,$dat0 + vld1.32 {q9},[$key],#16 // load key schedule... + subs $rounds,$rounds,#2 // bias + b.gt .Lecb_dec_round_loop +.Lecb_128_dec: + vld1.32 {q10-q11},[$key],#32 // load key schedule... + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat0,q9 + aesimc $dat0,$dat0 + vld1.32 {q12-q13},[$key],#32 // load key schedule... + aesd $dat0,q10 + aesimc $dat0,$dat0 + aesd $dat0,q11 + aesimc $dat0,$dat0 + vld1.32 {q14-q15},[$key],#32 // load key schedule... + aesd $dat0,q12 + aesimc $dat0,$dat0 + aesd $dat0,q13 + aesimc $dat0,$dat0 + vld1.32 {$rndlast},[$key] + aesd $dat0,q14 + aesimc $dat0,$dat0 + aesd $dat0,q15 + veor $dat0,$dat0,$rndlast + vst1.8 {$dat0},[$out] + b .Lecb_Final_abort +.Lecb_big_size: ___ $code.=<<___ if ($flavour =~ /64/); stp x29,x30,[sp,#-16]! @@ -384,24 +539,23 @@ ___ $code.=<<___ if ($flavour !~ /64/); mov ip,sp stmdb sp!,{r4-r8,lr} - vstmdb sp!,{d8-d15} @ ABI specification says so - ldmia ip,{r4-r5} @ load remaining args + vstmdb sp!,{d8-d15} @ ABI specification says so + ldmia ip,{r4-r5} @ load remaining args + subs $len,$len,#16 ___ $code.=<<___; - subs $len,$len,#16 mov $step,#16 - b.lo .Lcbc_abort + b.lo .Lecb_done cclr $step,eq - cmp $enc,#0 // en- or decrypting? + cmp $enc,#0 // en- or decrypting? ldr $rounds,[$key,#240] and $len,$len,#-16 - vld1.8 {$ivec},[$ivp] vld1.8 {$dat},[$inp],$step - vld1.32 {q8-q9},[$key] // load key schedule... + vld1.32 {q8-q9},[$key] // load key schedule... sub $rounds,$rounds,#6 - add $key_,$key,x5,lsl#4 // pointer to last 7 round keys + add $key_,$key,x5,lsl#4 // pointer to last 7 round keys sub $rounds,$rounds,#2 vld1.32 {q10-q11},[$key_],#32 vld1.32 {q12-q13},[$key_],#32 @@ -410,139 +564,359 @@ $code.=<<___; add $key_,$key,#32 mov $cnt,$rounds - b.eq .Lcbc_dec + b.eq .Lecb_dec - cmp $rounds,#2 - veor $dat,$dat,$ivec - veor $rndzero_n_last,q8,$rndlast - b.eq .Lcbc_enc128 + vld1.8 {$dat1},[$inp],#16 + subs $len,$len,#32 // bias + add $cnt,$rounds,#2 + vorr $in1,$dat1,$dat1 + vorr $dat2,$dat1,$dat1 + vorr $dat1,$dat,$dat + b.lo .Lecb_enc_tail - vld1.32 {$in0-$in1},[$key_] - add $key_,$key,#16 - add $key4,$key,#16*4 - add $key5,$key,#16*5 - aese $dat,q8 - aesmc $dat,$dat - add $key6,$key,#16*6 - add $key7,$key,#16*7 - b .Lenter_cbc_enc + vorr $dat1,$in1,$in1 + vld1.8 {$dat2},[$inp],#16 +___ +$code.=<<___ if ($flavour =~ /64/); + cmp $len,#32 + b.lo .Loop3x_ecb_enc -.align 4 -.Loop_cbc_enc: - aese $dat,q8 - aesmc $dat,$dat - vst1.8 {$ivec},[$out],#16 -.Lenter_cbc_enc: - aese $dat,q9 - aesmc $dat,$dat - aese $dat,$in0 - aesmc $dat,$dat - vld1.32 {q8},[$key4] - cmp $rounds,#4 - aese $dat,$in1 - aesmc $dat,$dat - vld1.32 {q9},[$key5] - b.eq .Lcbc_enc192 + vld1.8 {$dat3},[$inp],#16 + vld1.8 {$dat4},[$inp],#16 + sub $len,$len,#32 // bias + mov $cnt,$rounds - aese $dat,q8 - aesmc $dat,$dat - vld1.32 {q8},[$key6] - aese $dat,q9 - aesmc $dat,$dat - vld1.32 {q9},[$key7] - nop +.Loop5x_ecb_enc: + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + aese $dat3,q8 + aesmc $dat3,$dat3 + aese $dat4,q8 + aesmc $dat4,$dat4 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + aese $dat3,q9 + aesmc $dat3,$dat3 + aese $dat4,q9 + aesmc $dat4,$dat4 + vld1.32 {q9},[$key_],#16 + b.gt .Loop5x_ecb_enc + + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + aese $dat3,q8 + aesmc $dat3,$dat3 + aese $dat4,q8 + aesmc $dat4,$dat4 + cmp $len,#0x40 // because .Lecb_enc_tail4x + sub $len,$len,#0x50 + + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + aese $dat3,q9 + aesmc $dat3,$dat3 + aese $dat4,q9 + aesmc $dat4,$dat4 + csel x6,xzr,$len,gt // borrow x6, $cnt, "gt" is not typo + mov $key_,$key + + aese $dat0,q10 + aesmc $dat0,$dat0 + aese $dat1,q10 + aesmc $dat1,$dat1 + aese $dat2,q10 + aesmc $dat2,$dat2 + aese $dat3,q10 + aesmc $dat3,$dat3 + aese $dat4,q10 + aesmc $dat4,$dat4 + add $inp,$inp,x6 // $inp is adjusted in such way that + // at exit from the loop $dat1-$dat4 + // are loaded with last "words" + add x6,$len,#0x60 // because .Lecb_enc_tail4x + + aese $dat0,q11 + aesmc $dat0,$dat0 + aese $dat1,q11 + aesmc $dat1,$dat1 + aese $dat2,q11 + aesmc $dat2,$dat2 + aese $dat3,q11 + aesmc $dat3,$dat3 + aese $dat4,q11 + aesmc $dat4,$dat4 + + aese $dat0,q12 + aesmc $dat0,$dat0 + aese $dat1,q12 + aesmc $dat1,$dat1 + aese $dat2,q12 + aesmc $dat2,$dat2 + aese $dat3,q12 + aesmc $dat3,$dat3 + aese $dat4,q12 + aesmc $dat4,$dat4 + + aese $dat0,q13 + aesmc $dat0,$dat0 + aese $dat1,q13 + aesmc $dat1,$dat1 + aese $dat2,q13 + aesmc $dat2,$dat2 + aese $dat3,q13 + aesmc $dat3,$dat3 + aese $dat4,q13 + aesmc $dat4,$dat4 + + aese $dat0,q14 + aesmc $dat0,$dat0 + aese $dat1,q14 + aesmc $dat1,$dat1 + aese $dat2,q14 + aesmc $dat2,$dat2 + aese $dat3,q14 + aesmc $dat3,$dat3 + aese $dat4,q14 + aesmc $dat4,$dat4 + + aese $dat0,q15 + vld1.8 {$in0},[$inp],#16 + aese $dat1,q15 + vld1.8 {$in1},[$inp],#16 + aese $dat2,q15 + vld1.8 {$in2},[$inp],#16 + aese $dat3,q15 + vld1.8 {$in3},[$inp],#16 + aese $dat4,q15 + vld1.8 {$in4},[$inp],#16 + cbz x6,.Lecb_enc_tail4x + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + veor $tmp0,$rndlast,$dat0 + vorr $dat0,$in0,$in0 + veor $tmp1,$rndlast,$dat1 + vorr $dat1,$in1,$in1 + veor $tmp2,$rndlast,$dat2 + vorr $dat2,$in2,$in2 + veor $tmp3,$rndlast,$dat3 + vorr $dat3,$in3,$in3 + veor $tmp4,$rndlast,$dat4 + vst1.8 {$tmp0},[$out],#16 + vorr $dat4,$in4,$in4 + vst1.8 {$tmp1},[$out],#16 + mov $cnt,$rounds + vst1.8 {$tmp2},[$out],#16 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + b.hs .Loop5x_ecb_enc -.Lcbc_enc192: - aese $dat,q8 - aesmc $dat,$dat - subs $len,$len,#16 - aese $dat,q9 - aesmc $dat,$dat - cclr $step,eq - aese $dat,q10 - aesmc $dat,$dat - aese $dat,q11 - aesmc $dat,$dat - vld1.8 {q8},[$inp],$step - aese $dat,q12 - aesmc $dat,$dat - veor q8,q8,$rndzero_n_last - aese $dat,q13 - aesmc $dat,$dat - vld1.32 {q9},[$key_] // re-pre-load rndkey[1] - aese $dat,q14 - aesmc $dat,$dat - aese $dat,q15 - veor $ivec,$dat,$rndlast - b.hs .Loop_cbc_enc + add $len,$len,#0x50 + cbz $len,.Lecb_done - vst1.8 {$ivec},[$out],#16 - b .Lcbc_done + add $cnt,$rounds,#2 + subs $len,$len,#0x30 + vorr $dat0,$in2,$in2 + vorr $dat1,$in3,$in3 + vorr $dat2,$in4,$in4 + b.lo .Lecb_enc_tail -.align 5 -.Lcbc_enc128: - vld1.32 {$in0-$in1},[$key_] - aese $dat,q8 - aesmc $dat,$dat - b .Lenter_cbc_enc128 -.Loop_cbc_enc128: - aese $dat,q8 - aesmc $dat,$dat - vst1.8 {$ivec},[$out],#16 -.Lenter_cbc_enc128: - aese $dat,q9 - aesmc $dat,$dat - subs $len,$len,#16 - aese $dat,$in0 - aesmc $dat,$dat - cclr $step,eq - aese $dat,$in1 - aesmc $dat,$dat - aese $dat,q10 - aesmc $dat,$dat - aese $dat,q11 - aesmc $dat,$dat - vld1.8 {q8},[$inp],$step - aese $dat,q12 - aesmc $dat,$dat - aese $dat,q13 - aesmc $dat,$dat - aese $dat,q14 - aesmc $dat,$dat - veor q8,q8,$rndzero_n_last - aese $dat,q15 - veor $ivec,$dat,$rndlast - b.hs .Loop_cbc_enc128 + b .Loop3x_ecb_enc - vst1.8 {$ivec},[$out],#16 - b .Lcbc_done +.align 4 +.Lecb_enc_tail4x: + veor $tmp1,$rndlast,$dat1 + veor $tmp2,$rndlast,$dat2 + veor $tmp3,$rndlast,$dat3 + veor $tmp4,$rndlast,$dat4 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$tmp2},[$out],#16 + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + + b .Lecb_done +.align 4 ___ -{ -my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9)); +$code.=<<___; +.Loop3x_ecb_enc: + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Loop3x_ecb_enc + + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + subs $len,$len,#0x30 + mov.lo x6,$len // x6, $cnt, is zero at this point + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + add $inp,$inp,x6 // $inp is adjusted in such way that + // at exit from the loop $dat1-$dat2 + // are loaded with last "words" + mov $key_,$key + aese $dat0,q12 + aesmc $dat0,$dat0 + aese $dat1,q12 + aesmc $dat1,$dat1 + aese $dat2,q12 + aesmc $dat2,$dat2 + vld1.8 {$in0},[$inp],#16 + aese $dat0,q13 + aesmc $dat0,$dat0 + aese $dat1,q13 + aesmc $dat1,$dat1 + aese $dat2,q13 + aesmc $dat2,$dat2 + vld1.8 {$in1},[$inp],#16 + aese $dat0,q14 + aesmc $dat0,$dat0 + aese $dat1,q14 + aesmc $dat1,$dat1 + aese $dat2,q14 + aesmc $dat2,$dat2 + vld1.8 {$in2},[$inp],#16 + aese $dat0,q15 + aese $dat1,q15 + aese $dat2,q15 + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + add $cnt,$rounds,#2 + veor $tmp0,$rndlast,$dat0 + veor $tmp1,$rndlast,$dat1 + veor $dat2,$dat2,$rndlast + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp0},[$out],#16 + vorr $dat0,$in0,$in0 + vst1.8 {$tmp1},[$out],#16 + vorr $dat1,$in1,$in1 + vst1.8 {$dat2},[$out],#16 + vorr $dat2,$in2,$in2 + b.hs .Loop3x_ecb_enc + + cmn $len,#0x30 + b.eq .Lecb_done + nop + +.Lecb_enc_tail: + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Lecb_enc_tail + + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + aese $dat1,q12 + aesmc $dat1,$dat1 + aese $dat2,q12 + aesmc $dat2,$dat2 + cmn $len,#0x20 + aese $dat1,q13 + aesmc $dat1,$dat1 + aese $dat2,q13 + aesmc $dat2,$dat2 + aese $dat1,q14 + aesmc $dat1,$dat1 + aese $dat2,q14 + aesmc $dat2,$dat2 + aese $dat1,q15 + aese $dat2,q15 + b.eq .Lecb_enc_one + veor $tmp1,$rndlast,$dat1 + veor $tmp2,$rndlast,$dat2 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$tmp2},[$out],#16 + b .Lecb_done + +.Lecb_enc_one: + veor $tmp1,$rndlast,$dat2 + vst1.8 {$tmp1},[$out],#16 + b .Lecb_done +___ + $code.=<<___; .align 5 -.Lcbc_dec: - vld1.8 {$dat2},[$inp],#16 - subs $len,$len,#32 // bias +.Lecb_dec: + vld1.8 {$dat1},[$inp],#16 + subs $len,$len,#32 // bias add $cnt,$rounds,#2 - vorr $in1,$dat,$dat + vorr $in1,$dat1,$dat1 + vorr $dat2,$dat1,$dat1 vorr $dat1,$dat,$dat - vorr $in2,$dat2,$dat2 - b.lo .Lcbc_dec_tail + b.lo .Lecb_dec_tail - vorr $dat1,$dat2,$dat2 + vorr $dat1,$in1,$in1 vld1.8 {$dat2},[$inp],#16 - vorr $in0,$dat,$dat - vorr $in1,$dat1,$dat1 - vorr $in2,$dat2,$dat2 +___ +$code.=<<___ if ($flavour =~ /64/); + cmp $len,#32 + b.lo .Loop3x_ecb_dec -.Loop3x_cbc_dec: + vld1.8 {$dat3},[$inp],#16 + vld1.8 {$dat4},[$inp],#16 + sub $len,$len,#32 // bias + mov $cnt,$rounds + +.Loop5x_ecb_dec: aesd $dat0,q8 aesimc $dat0,$dat0 aesd $dat1,q8 aesimc $dat1,$dat1 aesd $dat2,q8 aesimc $dat2,$dat2 + aesd $dat3,q8 + aesimc $dat3,$dat3 + aesd $dat4,q8 + aesimc $dat4,$dat4 vld1.32 {q8},[$key_],#16 subs $cnt,$cnt,#2 aesd $dat0,q9 @@ -551,8 +925,12 @@ $code.=<<___; aesimc $dat1,$dat1 aesd $dat2,q9 aesimc $dat2,$dat2 + aesd $dat3,q9 + aesimc $dat3,$dat3 + aesd $dat4,q9 + aesimc $dat4,$dat4 vld1.32 {q9},[$key_],#16 - b.gt .Loop3x_cbc_dec + b.gt .Loop5x_ecb_dec aesd $dat0,q8 aesimc $dat0,$dat0 @@ -560,62 +938,738 @@ $code.=<<___; aesimc $dat1,$dat1 aesd $dat2,q8 aesimc $dat2,$dat2 - veor $tmp0,$ivec,$rndlast - subs $len,$len,#0x30 - veor $tmp1,$in0,$rndlast - mov.lo x6,$len // x6, $cnt, is zero at this point + aesd $dat3,q8 + aesimc $dat3,$dat3 + aesd $dat4,q8 + aesimc $dat4,$dat4 + cmp $len,#0x40 // because .Lecb_tail4x + sub $len,$len,#0x50 + aesd $dat0,q9 aesimc $dat0,$dat0 aesd $dat1,q9 aesimc $dat1,$dat1 aesd $dat2,q9 aesimc $dat2,$dat2 - veor $tmp2,$in1,$rndlast - add $inp,$inp,x6 // $inp is adjusted in such way that - // at exit from the loop $dat1-$dat2 - // are loaded with last "words" - vorr $ivec,$in2,$in2 - mov $key_,$key + aesd $dat3,q9 + aesimc $dat3,$dat3 + aesd $dat4,q9 + aesimc $dat4,$dat4 + csel x6,xzr,$len,gt // borrow x6, $cnt, "gt" is not typo + mov $key_,$key + + aesd $dat0,q10 + aesimc $dat0,$dat0 + aesd $dat1,q10 + aesimc $dat1,$dat1 + aesd $dat2,q10 + aesimc $dat2,$dat2 + aesd $dat3,q10 + aesimc $dat3,$dat3 + aesd $dat4,q10 + aesimc $dat4,$dat4 + add $inp,$inp,x6 // $inp is adjusted in such way that + // at exit from the loop $dat1-$dat4 + // are loaded with last "words" + add x6,$len,#0x60 // because .Lecb_tail4x + + aesd $dat0,q11 + aesimc $dat0,$dat0 + aesd $dat1,q11 + aesimc $dat1,$dat1 + aesd $dat2,q11 + aesimc $dat2,$dat2 + aesd $dat3,q11 + aesimc $dat3,$dat3 + aesd $dat4,q11 + aesimc $dat4,$dat4 + aesd $dat0,q12 aesimc $dat0,$dat0 aesd $dat1,q12 aesimc $dat1,$dat1 aesd $dat2,q12 aesimc $dat2,$dat2 - vld1.8 {$in0},[$inp],#16 + aesd $dat3,q12 + aesimc $dat3,$dat3 + aesd $dat4,q12 + aesimc $dat4,$dat4 + aesd $dat0,q13 aesimc $dat0,$dat0 aesd $dat1,q13 aesimc $dat1,$dat1 aesd $dat2,q13 aesimc $dat2,$dat2 - vld1.8 {$in1},[$inp],#16 + aesd $dat3,q13 + aesimc $dat3,$dat3 + aesd $dat4,q13 + aesimc $dat4,$dat4 + aesd $dat0,q14 aesimc $dat0,$dat0 aesd $dat1,q14 aesimc $dat1,$dat1 aesd $dat2,q14 aesimc $dat2,$dat2 - vld1.8 {$in2},[$inp],#16 + aesd $dat3,q14 + aesimc $dat3,$dat3 + aesd $dat4,q14 + aesimc $dat4,$dat4 + aesd $dat0,q15 + vld1.8 {$in0},[$inp],#16 aesd $dat1,q15 + vld1.8 {$in1},[$inp],#16 aesd $dat2,q15 - vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] - add $cnt,$rounds,#2 - veor $tmp0,$tmp0,$dat0 - veor $tmp1,$tmp1,$dat1 - veor $dat2,$dat2,$tmp2 - vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vld1.8 {$in2},[$inp],#16 + aesd $dat3,q15 + vld1.8 {$in3},[$inp],#16 + aesd $dat4,q15 + vld1.8 {$in4},[$inp],#16 + cbz x6,.Lecb_tail4x + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + veor $tmp0,$rndlast,$dat0 + vorr $dat0,$in0,$in0 + veor $tmp1,$rndlast,$dat1 + vorr $dat1,$in1,$in1 + veor $tmp2,$rndlast,$dat2 + vorr $dat2,$in2,$in2 + veor $tmp3,$rndlast,$dat3 + vorr $dat3,$in3,$in3 + veor $tmp4,$rndlast,$dat4 vst1.8 {$tmp0},[$out],#16 - vorr $dat0,$in0,$in0 + vorr $dat4,$in4,$in4 vst1.8 {$tmp1},[$out],#16 - vorr $dat1,$in1,$in1 - vst1.8 {$dat2},[$out],#16 - vorr $dat2,$in2,$in2 - b.hs .Loop3x_cbc_dec + mov $cnt,$rounds + vst1.8 {$tmp2},[$out],#16 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + b.hs .Loop5x_ecb_dec - cmn $len,#0x30 - b.eq .Lcbc_done + add $len,$len,#0x50 + cbz $len,.Lecb_done + + add $cnt,$rounds,#2 + subs $len,$len,#0x30 + vorr $dat0,$in2,$in2 + vorr $dat1,$in3,$in3 + vorr $dat2,$in4,$in4 + b.lo .Lecb_dec_tail + + b .Loop3x_ecb_dec + +.align 4 +.Lecb_tail4x: + veor $tmp1,$rndlast,$dat1 + veor $tmp2,$rndlast,$dat2 + veor $tmp3,$rndlast,$dat3 + veor $tmp4,$rndlast,$dat4 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$tmp2},[$out],#16 + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + + b .Lecb_done +.align 4 +___ +$code.=<<___; +.Loop3x_ecb_dec: + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Loop3x_ecb_dec + + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + subs $len,$len,#0x30 + mov.lo x6,$len // x6, $cnt, is zero at this point + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + add $inp,$inp,x6 // $inp is adjusted in such way that + // at exit from the loop $dat1-$dat2 + // are loaded with last "words" + mov $key_,$key + aesd $dat0,q12 + aesimc $dat0,$dat0 + aesd $dat1,q12 + aesimc $dat1,$dat1 + aesd $dat2,q12 + aesimc $dat2,$dat2 + vld1.8 {$in0},[$inp],#16 + aesd $dat0,q13 + aesimc $dat0,$dat0 + aesd $dat1,q13 + aesimc $dat1,$dat1 + aesd $dat2,q13 + aesimc $dat2,$dat2 + vld1.8 {$in1},[$inp],#16 + aesd $dat0,q14 + aesimc $dat0,$dat0 + aesd $dat1,q14 + aesimc $dat1,$dat1 + aesd $dat2,q14 + aesimc $dat2,$dat2 + vld1.8 {$in2},[$inp],#16 + aesd $dat0,q15 + aesd $dat1,q15 + aesd $dat2,q15 + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + add $cnt,$rounds,#2 + veor $tmp0,$rndlast,$dat0 + veor $tmp1,$rndlast,$dat1 + veor $dat2,$dat2,$rndlast + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp0},[$out],#16 + vorr $dat0,$in0,$in0 + vst1.8 {$tmp1},[$out],#16 + vorr $dat1,$in1,$in1 + vst1.8 {$dat2},[$out],#16 + vorr $dat2,$in2,$in2 + b.hs .Loop3x_ecb_dec + + cmn $len,#0x30 + b.eq .Lecb_done + nop + +.Lecb_dec_tail: + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Lecb_dec_tail + + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + aesd $dat1,q12 + aesimc $dat1,$dat1 + aesd $dat2,q12 + aesimc $dat2,$dat2 + cmn $len,#0x20 + aesd $dat1,q13 + aesimc $dat1,$dat1 + aesd $dat2,q13 + aesimc $dat2,$dat2 + aesd $dat1,q14 + aesimc $dat1,$dat1 + aesd $dat2,q14 + aesimc $dat2,$dat2 + aesd $dat1,q15 + aesd $dat2,q15 + b.eq .Lecb_dec_one + veor $tmp1,$rndlast,$dat1 + veor $tmp2,$rndlast,$dat2 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$tmp2},[$out],#16 + b .Lecb_done + +.Lecb_dec_one: + veor $tmp1,$rndlast,$dat2 + vst1.8 {$tmp1},[$out],#16 + +.Lecb_done: +___ +} +$code.=<<___ if ($flavour !~ /64/); + vldmia sp!,{d8-d15} + ldmia sp!,{r4-r8,pc} +___ +$code.=<<___ if ($flavour =~ /64/); + ldr x29,[sp],#16 +___ +$code.=<<___ if ($flavour =~ /64/); +.Lecb_Final_abort: + ret +___ +$code.=<<___; +.size ${prefix}_ecb_encrypt,.-${prefix}_ecb_encrypt +___ +}}} +{{{ +my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4)); my $enc="w5"; +my ($rounds,$cnt,$key_,$step,$step1)=($enc,"w6","x7","x8","x12"); +my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$ivec,$rndlast)=map("q$_",(0..7)); + +my ($dat,$tmp,$rndzero_n_last)=($dat0,$tmp0,$tmp1); +my ($key4,$key5,$key6,$key7)=("x6","x12","x14",$key); + +### q8-q15 preloaded key schedule + +$code.=<<___; +.globl ${prefix}_cbc_encrypt +.type ${prefix}_cbc_encrypt,%function +.align 5 +${prefix}_cbc_encrypt: +___ +$code.=<<___ if ($flavour =~ /64/); + stp x29,x30,[sp,#-16]! + add x29,sp,#0 +___ +$code.=<<___ if ($flavour !~ /64/); + mov ip,sp + stmdb sp!,{r4-r8,lr} + vstmdb sp!,{d8-d15} @ ABI specification says so + ldmia ip,{r4-r5} @ load remaining args +___ +$code.=<<___; + subs $len,$len,#16 + mov $step,#16 + b.lo .Lcbc_abort + cclr $step,eq + + cmp $enc,#0 // en- or decrypting? + ldr $rounds,[$key,#240] + and $len,$len,#-16 + vld1.8 {$ivec},[$ivp] + vld1.8 {$dat},[$inp],$step + + vld1.32 {q8-q9},[$key] // load key schedule... + sub $rounds,$rounds,#6 + add $key_,$key,x5,lsl#4 // pointer to last 7 round keys + sub $rounds,$rounds,#2 + vld1.32 {q10-q11},[$key_],#32 + vld1.32 {q12-q13},[$key_],#32 + vld1.32 {q14-q15},[$key_],#32 + vld1.32 {$rndlast},[$key_] + + add $key_,$key,#32 + mov $cnt,$rounds + b.eq .Lcbc_dec + + cmp $rounds,#2 + veor $dat,$dat,$ivec + veor $rndzero_n_last,q8,$rndlast + b.eq .Lcbc_enc128 + + vld1.32 {$in0-$in1},[$key_] + add $key_,$key,#16 + add $key4,$key,#16*4 + add $key5,$key,#16*5 + aese $dat,q8 + aesmc $dat,$dat + add $key6,$key,#16*6 + add $key7,$key,#16*7 + b .Lenter_cbc_enc + +.align 4 +.Loop_cbc_enc: + aese $dat,q8 + aesmc $dat,$dat + vst1.8 {$ivec},[$out],#16 +.Lenter_cbc_enc: + aese $dat,q9 + aesmc $dat,$dat + aese $dat,$in0 + aesmc $dat,$dat + vld1.32 {q8},[$key4] + cmp $rounds,#4 + aese $dat,$in1 + aesmc $dat,$dat + vld1.32 {q9},[$key5] + b.eq .Lcbc_enc192 + + aese $dat,q8 + aesmc $dat,$dat + vld1.32 {q8},[$key6] + aese $dat,q9 + aesmc $dat,$dat + vld1.32 {q9},[$key7] + nop + +.Lcbc_enc192: + aese $dat,q8 + aesmc $dat,$dat + subs $len,$len,#16 + aese $dat,q9 + aesmc $dat,$dat + cclr $step,eq + aese $dat,q10 + aesmc $dat,$dat + aese $dat,q11 + aesmc $dat,$dat + vld1.8 {q8},[$inp],$step + aese $dat,q12 + aesmc $dat,$dat + veor q8,q8,$rndzero_n_last + aese $dat,q13 + aesmc $dat,$dat + vld1.32 {q9},[$key_] // re-pre-load rndkey[1] + aese $dat,q14 + aesmc $dat,$dat + aese $dat,q15 + veor $ivec,$dat,$rndlast + b.hs .Loop_cbc_enc + + vst1.8 {$ivec},[$out],#16 + b .Lcbc_done + +.align 5 +.Lcbc_enc128: + vld1.32 {$in0-$in1},[$key_] + aese $dat,q8 + aesmc $dat,$dat + b .Lenter_cbc_enc128 +.Loop_cbc_enc128: + aese $dat,q8 + aesmc $dat,$dat + vst1.8 {$ivec},[$out],#16 +.Lenter_cbc_enc128: + aese $dat,q9 + aesmc $dat,$dat + subs $len,$len,#16 + aese $dat,$in0 + aesmc $dat,$dat + cclr $step,eq + aese $dat,$in1 + aesmc $dat,$dat + aese $dat,q10 + aesmc $dat,$dat + aese $dat,q11 + aesmc $dat,$dat + vld1.8 {q8},[$inp],$step + aese $dat,q12 + aesmc $dat,$dat + aese $dat,q13 + aesmc $dat,$dat + aese $dat,q14 + aesmc $dat,$dat + veor q8,q8,$rndzero_n_last + aese $dat,q15 + veor $ivec,$dat,$rndlast + b.hs .Loop_cbc_enc128 + + vst1.8 {$ivec},[$out],#16 + b .Lcbc_done +___ +{ +my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9)); + +my ($dat3,$in3,$tmp3); # used only in 64-bit mode +my ($dat4,$in4,$tmp4); +if ($flavour =~ /64/) { + ($dat2,$dat3,$dat4,$in2,$in3,$in4,$tmp3,$tmp4)=map("q$_",(16..23)); +} + +$code.=<<___; +.align 5 +.Lcbc_dec: + vld1.8 {$dat2},[$inp],#16 + subs $len,$len,#32 // bias + add $cnt,$rounds,#2 + vorr $in1,$dat,$dat + vorr $dat1,$dat,$dat + vorr $in2,$dat2,$dat2 + b.lo .Lcbc_dec_tail + + vorr $dat1,$dat2,$dat2 + vld1.8 {$dat2},[$inp],#16 + vorr $in0,$dat,$dat + vorr $in1,$dat1,$dat1 + vorr $in2,$dat2,$dat2 +___ +$code.=<<___ if ($flavour =~ /64/); + cmp $len,#32 + b.lo .Loop3x_cbc_dec + + vld1.8 {$dat3},[$inp],#16 + vld1.8 {$dat4},[$inp],#16 + sub $len,$len,#32 // bias + mov $cnt,$rounds + vorr $in3,$dat3,$dat3 + vorr $in4,$dat4,$dat4 + +.Loop5x_cbc_dec: + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + aesd $dat3,q8 + aesimc $dat3,$dat3 + aesd $dat4,q8 + aesimc $dat4,$dat4 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + aesd $dat3,q9 + aesimc $dat3,$dat3 + aesd $dat4,q9 + aesimc $dat4,$dat4 + vld1.32 {q9},[$key_],#16 + b.gt .Loop5x_cbc_dec + + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + aesd $dat3,q8 + aesimc $dat3,$dat3 + aesd $dat4,q8 + aesimc $dat4,$dat4 + cmp $len,#0x40 // because .Lcbc_tail4x + sub $len,$len,#0x50 + + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + aesd $dat3,q9 + aesimc $dat3,$dat3 + aesd $dat4,q9 + aesimc $dat4,$dat4 + csel x6,xzr,$len,gt // borrow x6, $cnt, "gt" is not typo + mov $key_,$key + + aesd $dat0,q10 + aesimc $dat0,$dat0 + aesd $dat1,q10 + aesimc $dat1,$dat1 + aesd $dat2,q10 + aesimc $dat2,$dat2 + aesd $dat3,q10 + aesimc $dat3,$dat3 + aesd $dat4,q10 + aesimc $dat4,$dat4 + add $inp,$inp,x6 // $inp is adjusted in such way that + // at exit from the loop $dat1-$dat4 + // are loaded with last "words" + add x6,$len,#0x60 // because .Lcbc_tail4x + + aesd $dat0,q11 + aesimc $dat0,$dat0 + aesd $dat1,q11 + aesimc $dat1,$dat1 + aesd $dat2,q11 + aesimc $dat2,$dat2 + aesd $dat3,q11 + aesimc $dat3,$dat3 + aesd $dat4,q11 + aesimc $dat4,$dat4 + + aesd $dat0,q12 + aesimc $dat0,$dat0 + aesd $dat1,q12 + aesimc $dat1,$dat1 + aesd $dat2,q12 + aesimc $dat2,$dat2 + aesd $dat3,q12 + aesimc $dat3,$dat3 + aesd $dat4,q12 + aesimc $dat4,$dat4 + + aesd $dat0,q13 + aesimc $dat0,$dat0 + aesd $dat1,q13 + aesimc $dat1,$dat1 + aesd $dat2,q13 + aesimc $dat2,$dat2 + aesd $dat3,q13 + aesimc $dat3,$dat3 + aesd $dat4,q13 + aesimc $dat4,$dat4 + + aesd $dat0,q14 + aesimc $dat0,$dat0 + aesd $dat1,q14 + aesimc $dat1,$dat1 + aesd $dat2,q14 + aesimc $dat2,$dat2 + aesd $dat3,q14 + aesimc $dat3,$dat3 + aesd $dat4,q14 + aesimc $dat4,$dat4 + + veor $tmp0,$ivec,$rndlast + aesd $dat0,q15 + veor $tmp1,$in0,$rndlast + vld1.8 {$in0},[$inp],#16 + aesd $dat1,q15 + veor $tmp2,$in1,$rndlast + vld1.8 {$in1},[$inp],#16 + aesd $dat2,q15 + veor $tmp3,$in2,$rndlast + vld1.8 {$in2},[$inp],#16 + aesd $dat3,q15 + veor $tmp4,$in3,$rndlast + vld1.8 {$in3},[$inp],#16 + aesd $dat4,q15 + vorr $ivec,$in4,$in4 + vld1.8 {$in4},[$inp],#16 + cbz x6,.Lcbc_tail4x + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + veor $tmp0,$tmp0,$dat0 + vorr $dat0,$in0,$in0 + veor $tmp1,$tmp1,$dat1 + vorr $dat1,$in1,$in1 + veor $tmp2,$tmp2,$dat2 + vorr $dat2,$in2,$in2 + veor $tmp3,$tmp3,$dat3 + vorr $dat3,$in3,$in3 + veor $tmp4,$tmp4,$dat4 + vst1.8 {$tmp0},[$out],#16 + vorr $dat4,$in4,$in4 + vst1.8 {$tmp1},[$out],#16 + mov $cnt,$rounds + vst1.8 {$tmp2},[$out],#16 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + b.hs .Loop5x_cbc_dec + + add $len,$len,#0x50 + cbz $len,.Lcbc_done + + add $cnt,$rounds,#2 + subs $len,$len,#0x30 + vorr $dat0,$in2,$in2 + vorr $in0,$in2,$in2 + vorr $dat1,$in3,$in3 + vorr $in1,$in3,$in3 + vorr $dat2,$in4,$in4 + vorr $in2,$in4,$in4 + b.lo .Lcbc_dec_tail + + b .Loop3x_cbc_dec + +.align 4 +.Lcbc_tail4x: + veor $tmp1,$tmp0,$dat1 + veor $tmp2,$tmp2,$dat2 + veor $tmp3,$tmp3,$dat3 + veor $tmp4,$tmp4,$dat4 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$tmp2},[$out],#16 + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + + b .Lcbc_done +.align 4 +___ +$code.=<<___; +.Loop3x_cbc_dec: + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Loop3x_cbc_dec + + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + veor $tmp0,$ivec,$rndlast + subs $len,$len,#0x30 + veor $tmp1,$in0,$rndlast + mov.lo x6,$len // x6, $cnt, is zero at this point + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + veor $tmp2,$in1,$rndlast + add $inp,$inp,x6 // $inp is adjusted in such way that + // at exit from the loop $dat1-$dat2 + // are loaded with last "words" + vorr $ivec,$in2,$in2 + mov $key_,$key + aesd $dat0,q12 + aesimc $dat0,$dat0 + aesd $dat1,q12 + aesimc $dat1,$dat1 + aesd $dat2,q12 + aesimc $dat2,$dat2 + vld1.8 {$in0},[$inp],#16 + aesd $dat0,q13 + aesimc $dat0,$dat0 + aesd $dat1,q13 + aesimc $dat1,$dat1 + aesd $dat2,q13 + aesimc $dat2,$dat2 + vld1.8 {$in1},[$inp],#16 + aesd $dat0,q14 + aesimc $dat0,$dat0 + aesd $dat1,q14 + aesimc $dat1,$dat1 + aesd $dat2,q14 + aesimc $dat2,$dat2 + vld1.8 {$in2},[$inp],#16 + aesd $dat0,q15 + aesd $dat1,q15 + aesd $dat2,q15 + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + add $cnt,$rounds,#2 + veor $tmp0,$tmp0,$dat0 + veor $tmp1,$tmp1,$dat1 + veor $dat2,$dat2,$tmp2 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp0},[$out],#16 + vorr $dat0,$in0,$in0 + vst1.8 {$tmp1},[$out],#16 + vorr $dat1,$in1,$in1 + vst1.8 {$dat2},[$out],#16 + vorr $dat2,$in2,$in2 + b.hs .Loop3x_cbc_dec + + cmn $len,#0x30 + b.eq .Lcbc_done nop .Lcbc_dec_tail: @@ -696,6 +1750,9 @@ my $step="x12"; # aliases with $tctr2 my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$ivec,$rndlast)=map("q$_",(0..7)); my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9)); +# used only in 64-bit mode... +my ($dat3,$dat4,$in3,$in4)=map("q$_",(16..23)); + my ($dat,$tmp)=($dat0,$tmp0); ### q8-q15 preloaded key schedule @@ -762,10 +1819,177 @@ $code.=<<___ if ($flavour !~ /64/); add $ctr, $ctr, #2 vorr $dat1,$ivec,$ivec b.ls .Lctr32_tail - rev $tctr2, $ctr - vmov.32 ${ivec}[3],$tctr2 + rev $tctr2, $ctr + vmov.32 ${ivec}[3],$tctr2 + sub $len,$len,#3 // bias + vorr $dat2,$ivec,$ivec +___ +$code.=<<___ if ($flavour =~ /64/); + cmp $len,#32 + b.lo .Loop3x_ctr32 + + add w13,$ctr,#1 + add w14,$ctr,#2 + vorr $dat3,$dat0,$dat0 + rev w13,w13 + vorr $dat4,$dat0,$dat0 + rev w14,w14 + vmov.32 ${dat3}[3],w13 + sub $len,$len,#2 // bias + vmov.32 ${dat4}[3],w14 + add $ctr,$ctr,#2 + b .Loop5x_ctr32 + +.align 4 +.Loop5x_ctr32: + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + aese $dat3,q8 + aesmc $dat3,$dat3 + aese $dat4,q8 + aesmc $dat4,$dat4 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + aese $dat3,q9 + aesmc $dat3,$dat3 + aese $dat4,q9 + aesmc $dat4,$dat4 + vld1.32 {q9},[$key_],#16 + b.gt .Loop5x_ctr32 + + mov $key_,$key + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + aese $dat3,q8 + aesmc $dat3,$dat3 + aese $dat4,q8 + aesmc $dat4,$dat4 + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + aese $dat3,q9 + aesmc $dat3,$dat3 + aese $dat4,q9 + aesmc $dat4,$dat4 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + + aese $dat0,q12 + aesmc $dat0,$dat0 + add $tctr0,$ctr,#1 + add $tctr1,$ctr,#2 + aese $dat1,q12 + aesmc $dat1,$dat1 + add $tctr2,$ctr,#3 + add w13,$ctr,#4 + aese $dat2,q12 + aesmc $dat2,$dat2 + add w14,$ctr,#5 + rev $tctr0,$tctr0 + aese $dat3,q12 + aesmc $dat3,$dat3 + rev $tctr1,$tctr1 + rev $tctr2,$tctr2 + aese $dat4,q12 + aesmc $dat4,$dat4 + rev w13,w13 + rev w14,w14 + + aese $dat0,q13 + aesmc $dat0,$dat0 + aese $dat1,q13 + aesmc $dat1,$dat1 + aese $dat2,q13 + aesmc $dat2,$dat2 + aese $dat3,q13 + aesmc $dat3,$dat3 + aese $dat4,q13 + aesmc $dat4,$dat4 + + aese $dat0,q14 + aesmc $dat0,$dat0 + vld1.8 {$in0},[$inp],#16 + aese $dat1,q14 + aesmc $dat1,$dat1 + vld1.8 {$in1},[$inp],#16 + aese $dat2,q14 + aesmc $dat2,$dat2 + vld1.8 {$in2},[$inp],#16 + aese $dat3,q14 + aesmc $dat3,$dat3 + vld1.8 {$in3},[$inp],#16 + aese $dat4,q14 + aesmc $dat4,$dat4 + vld1.8 {$in4},[$inp],#16 + + aese $dat0,q15 + veor $in0,$in0,$rndlast + aese $dat1,q15 + veor $in1,$in1,$rndlast + aese $dat2,q15 + veor $in2,$in2,$rndlast + aese $dat3,q15 + veor $in3,$in3,$rndlast + aese $dat4,q15 + veor $in4,$in4,$rndlast + + veor $in0,$in0,$dat0 + vorr $dat0,$ivec,$ivec + veor $in1,$in1,$dat1 + vorr $dat1,$ivec,$ivec + veor $in2,$in2,$dat2 + vorr $dat2,$ivec,$ivec + veor $in3,$in3,$dat3 + vorr $dat3,$ivec,$ivec + veor $in4,$in4,$dat4 + vorr $dat4,$ivec,$ivec + + vst1.8 {$in0},[$out],#16 + vmov.32 ${dat0}[3],$tctr0 + vst1.8 {$in1},[$out],#16 + vmov.32 ${dat1}[3],$tctr1 + vst1.8 {$in2},[$out],#16 + vmov.32 ${dat2}[3],$tctr2 + vst1.8 {$in3},[$out],#16 + vmov.32 ${dat3}[3],w13 + vst1.8 {$in4},[$out],#16 + vmov.32 ${dat4}[3],w14 + + mov $cnt,$rounds + cbz $len,.Lctr32_done + + add $ctr,$ctr,#5 + subs $len,$len,#5 + b.hs .Loop5x_ctr32 + + add $len,$len,#5 + sub $ctr,$ctr,#5 + + cmp $len,#2 + mov $step,#16 + cclr $step,lo + b.ls .Lctr32_tail + sub $len,$len,#3 // bias - vorr $dat2,$ivec,$ivec + add $ctr,$ctr,#3 ___ $code.=<<___; b .Loop3x_ctr32 @@ -888,84 +2112,1510 @@ $code.=<<___; aese $tmp1,q15 aese $tmp2,q15 - veor $in0,$in0,$tmp0 - vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] - vst1.8 {$in0},[$out],#16 - veor $in1,$in1,$tmp1 - mov $cnt,$rounds - vst1.8 {$in1},[$out],#16 - veor $in2,$in2,$tmp2 - vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] - vst1.8 {$in2},[$out],#16 - b.hs .Loop3x_ctr32 + veor $in0,$in0,$tmp0 + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + vst1.8 {$in0},[$out],#16 + veor $in1,$in1,$tmp1 + mov $cnt,$rounds + vst1.8 {$in1},[$out],#16 + veor $in2,$in2,$tmp2 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$in2},[$out],#16 + b.hs .Loop3x_ctr32 + + adds $len,$len,#3 + b.eq .Lctr32_done + cmp $len,#1 + mov $step,#16 + cclr $step,eq + +.Lctr32_tail: + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + vld1.32 {q8},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + vld1.32 {q9},[$key_],#16 + b.gt .Lctr32_tail + + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + vld1.8 {$in0},[$inp],$step + aese $dat0,q12 + aesmc $dat0,$dat0 + aese $dat1,q12 + aesmc $dat1,$dat1 + vld1.8 {$in1},[$inp] + aese $dat0,q13 + aesmc $dat0,$dat0 + aese $dat1,q13 + aesmc $dat1,$dat1 + veor $in0,$in0,$rndlast + aese $dat0,q14 + aesmc $dat0,$dat0 + aese $dat1,q14 + aesmc $dat1,$dat1 + veor $in1,$in1,$rndlast + aese $dat0,q15 + aese $dat1,q15 + + cmp $len,#1 + veor $in0,$in0,$dat0 + veor $in1,$in1,$dat1 + vst1.8 {$in0},[$out],#16 + b.eq .Lctr32_done + vst1.8 {$in1},[$out] + +.Lctr32_done: +___ +$code.=<<___ if ($flavour !~ /64/); + vldmia sp!,{d8-d15} + ldmia sp!,{r4-r10,pc} +___ +$code.=<<___ if ($flavour =~ /64/); + ldr x29,[sp],#16 + ret +___ +$code.=<<___; +.size ${prefix}_ctr32_encrypt_blocks,.-${prefix}_ctr32_encrypt_blocks +___ +}}} +# Performance in cycles per byte. +# Processed with AES-XTS different key size. +# It shows the value before and after optimization as below: +# (before/after): +# +# AES-128-XTS AES-256-XTS +# Cortex-A57 3.36/1.09 4.02/1.37 +# Cortex-A72 3.03/1.02 3.28/1.33 + +# Optimization is implemented by loop unrolling and interleaving. +# Commonly, we choose the unrolling factor as 5, if the input +# data size smaller than 5 blocks, but not smaller than 3 blocks, +# choose 3 as the unrolling factor. +# If the input data size dsize >= 5*16 bytes, then take 5 blocks +# as one iteration, every loop the left size lsize -= 5*16. +# If lsize < 5*16 bytes, treat them as the tail. Note: left 4*16 bytes +# will be processed specially, which be integrated into the 5*16 bytes +# loop to improve the efficiency. +# There is one special case, if the original input data size dsize +# = 16 bytes, we will treat it seperately to improve the +# performance: one independent code block without LR, FP load and +# store. +# Encryption will process the (length -tailcnt) bytes as mentioned +# previously, then encrypt the composite block as last second +# cipher block. +# Decryption will process the (length -tailcnt -1) bytes as mentioned +# previously, then decrypt the last second cipher block to get the +# last plain block(tail), decrypt the composite block as last second +# plain text block. + +{{{ +my ($inp,$out,$len,$key1,$key2,$ivp)=map("x$_",(0..5)); +my ($rounds0,$rounds,$key_,$step,$ivl,$ivh)=("w5","w6","x7","x8","x9","x10"); +my ($tmpoutp,$loutp,$l2outp,$tmpinp)=("x13","w14","w15","x20"); +my ($tailcnt,$midnum,$midnumx,$constnum,$constnumx)=("x21","w22","x22","w19","x19"); +my ($xoffset,$tmpmx,$tmpmw)=("x6","x11","w11"); +my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$tmp2,$rndlast)=map("q$_",(0..7)); +my ($iv0,$iv1,$iv2,$iv3,$iv4)=("v6.16b","v8.16b","v9.16b","v10.16b","v11.16b"); +my ($ivd00,$ivd01,$ivd20,$ivd21)=("d6","v6.d[1]","d9","v9.d[1]"); +my ($ivd10,$ivd11,$ivd30,$ivd31,$ivd40,$ivd41)=("d8","v8.d[1]","d10","v10.d[1]","d11","v11.d[1]"); + +my ($tmpin)=("v26.16b"); +my ($dat,$tmp,$rndzero_n_last)=($dat0,$tmp0,$tmp1); + +# q7 last round key +# q10-q15, q7 Last 7 round keys +# q8-q9 preloaded round keys except last 7 keys for big size +# q20, q21, q8-q9 preloaded round keys except last 7 keys for only 16 byte + + +my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9)); + +my ($dat3,$in3,$tmp3); # used only in 64-bit mode +my ($dat4,$in4,$tmp4); +if ($flavour =~ /64/) { + ($dat2,$dat3,$dat4,$in2,$in3,$in4,$tmp3,$tmp4)=map("q$_",(16..23)); +} + +$code.=<<___ if ($flavour =~ /64/); +.globl ${prefix}_xts_encrypt +.type ${prefix}_xts_encrypt,%function +.align 5 +${prefix}_xts_encrypt: +___ +$code.=<<___ if ($flavour =~ /64/); + cmp $len,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne .Lxts_enc_big_size + // Encrypt the iv with key2, as the first XEX iv. + ldr $rounds,[$key2,#240] + vld1.8 {$dat},[$key2],#16 + vld1.8 {$iv0},[$ivp] + sub $rounds,$rounds,#2 + vld1.8 {$dat1},[$key2],#16 + +.Loop_enc_iv_enc: + aese $iv0,$dat + aesmc $iv0,$iv0 + vld1.32 {$dat},[$key2],#16 + subs $rounds,$rounds,#2 + aese $iv0,$dat1 + aesmc $iv0,$iv0 + vld1.32 {$dat1},[$key2],#16 + b.gt .Loop_enc_iv_enc + + aese $iv0,$dat + aesmc $iv0,$iv0 + vld1.32 {$dat},[$key2] + aese $iv0,$dat1 + veor $iv0,$iv0,$dat + + vld1.8 {$dat0},[$inp] + veor $dat0,$iv0,$dat0 + + ldr $rounds,[$key1,#240] + vld1.32 {q20-q21},[$key1],#32 // load key schedule... + + aese $dat0,q20 + aesmc $dat0,$dat0 + vld1.32 {q8-q9},[$key1],#32 // load key schedule... + aese $dat0,q21 + aesmc $dat0,$dat0 + subs $rounds,$rounds,#10 // if rounds==10, jump to aes-128-xts processing + b.eq .Lxts_128_enc +.Lxts_enc_round_loop: + aese $dat0,q8 + aesmc $dat0,$dat0 + vld1.32 {q8},[$key1],#16 // load key schedule... + aese $dat0,q9 + aesmc $dat0,$dat0 + vld1.32 {q9},[$key1],#16 // load key schedule... + subs $rounds,$rounds,#2 // bias + b.gt .Lxts_enc_round_loop +.Lxts_128_enc: + vld1.32 {q10-q11},[$key1],#32 // load key schedule... + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat0,q9 + aesmc $dat0,$dat0 + vld1.32 {q12-q13},[$key1],#32 // load key schedule... + aese $dat0,q10 + aesmc $dat0,$dat0 + aese $dat0,q11 + aesmc $dat0,$dat0 + vld1.32 {q14-q15},[$key1],#32 // load key schedule... + aese $dat0,q12 + aesmc $dat0,$dat0 + aese $dat0,q13 + aesmc $dat0,$dat0 + vld1.32 {$rndlast},[$key1] + aese $dat0,q14 + aesmc $dat0,$dat0 + aese $dat0,q15 + veor $dat0,$dat0,$rndlast + veor $dat0,$dat0,$iv0 + vst1.8 {$dat0},[$out] + b .Lxts_enc_final_abort + +.align 4 +.Lxts_enc_big_size: +___ +$code.=<<___ if ($flavour =~ /64/); + stp $constnumx,$tmpinp,[sp,#-64]! + stp $tailcnt,$midnumx,[sp,#48] + stp $ivd10,$ivd20,[sp,#32] + stp $ivd30,$ivd40,[sp,#16] + + // tailcnt store the tail value of length%16. + and $tailcnt,$len,#0xf + and $len,$len,#-16 + subs $len,$len,#16 + mov $step,#16 + b.lo .Lxts_abort + csel $step,xzr,$step,eq + + // Firstly, encrypt the iv with key2, as the first iv of XEX. + ldr $rounds,[$key2,#240] + vld1.32 {$dat},[$key2],#16 + vld1.8 {$iv0},[$ivp] + sub $rounds,$rounds,#2 + vld1.32 {$dat1},[$key2],#16 + +.Loop_iv_enc: + aese $iv0,$dat + aesmc $iv0,$iv0 + vld1.32 {$dat},[$key2],#16 + subs $rounds,$rounds,#2 + aese $iv0,$dat1 + aesmc $iv0,$iv0 + vld1.32 {$dat1},[$key2],#16 + b.gt .Loop_iv_enc + + aese $iv0,$dat + aesmc $iv0,$iv0 + vld1.32 {$dat},[$key2] + aese $iv0,$dat1 + veor $iv0,$iv0,$dat + + // The iv for second block + // $ivl- iv(low), $ivh - iv(high) + // the five ivs stored into, $iv0,$iv1,$iv2,$iv3,$iv4 + fmov $ivl,$ivd00 + fmov $ivh,$ivd01 + mov $constnum,#0x87 + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr#31 + eor $ivl,$tmpmx,$ivl,lsl#1 + fmov $ivd10,$ivl + fmov $ivd11,$ivh + + ldr $rounds0,[$key1,#240] // next starting point + vld1.8 {$dat},[$inp],$step + + vld1.32 {q8-q9},[$key1] // load key schedule... + sub $rounds0,$rounds0,#6 + add $key_,$key1,$ivp,lsl#4 // pointer to last 7 round keys + sub $rounds0,$rounds0,#2 + vld1.32 {q10-q11},[$key_],#32 + vld1.32 {q12-q13},[$key_],#32 + vld1.32 {q14-q15},[$key_],#32 + vld1.32 {$rndlast},[$key_] + + add $key_,$key1,#32 + mov $rounds,$rounds0 + + // Encryption +.Lxts_enc: + vld1.8 {$dat2},[$inp],#16 + subs $len,$len,#32 // bias + add $rounds,$rounds0,#2 + vorr $in1,$dat,$dat + vorr $dat1,$dat,$dat + vorr $in3,$dat,$dat + vorr $in2,$dat2,$dat2 + vorr $in4,$dat2,$dat2 + b.lo .Lxts_inner_enc_tail + veor $dat,$dat,$iv0 // before encryption, xor with iv + veor $dat2,$dat2,$iv1 + + // The iv for third block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr#31 + eor $ivl,$tmpmx,$ivl,lsl#1 + fmov $ivd20,$ivl + fmov $ivd21,$ivh + + + vorr $dat1,$dat2,$dat2 + vld1.8 {$dat2},[$inp],#16 + vorr $in0,$dat,$dat + vorr $in1,$dat1,$dat1 + veor $in2,$dat2,$iv2 // the third block + veor $dat2,$dat2,$iv2 + cmp $len,#32 + b.lo .Lxts_outer_enc_tail + + // The iv for fourth block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr#31 + eor $ivl,$tmpmx,$ivl,lsl#1 + fmov $ivd30,$ivl + fmov $ivd31,$ivh + + vld1.8 {$dat3},[$inp],#16 + // The iv for fifth block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr#31 + eor $ivl,$tmpmx,$ivl,lsl#1 + fmov $ivd40,$ivl + fmov $ivd41,$ivh + + vld1.8 {$dat4},[$inp],#16 + veor $dat3,$dat3,$iv3 // the fourth block + veor $dat4,$dat4,$iv4 + sub $len,$len,#32 // bias + mov $rounds,$rounds0 + b .Loop5x_xts_enc + +.align 4 +.Loop5x_xts_enc: + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + aese $dat3,q8 + aesmc $dat3,$dat3 + aese $dat4,q8 + aesmc $dat4,$dat4 + vld1.32 {q8},[$key_],#16 + subs $rounds,$rounds,#2 + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + aese $dat3,q9 + aesmc $dat3,$dat3 + aese $dat4,q9 + aesmc $dat4,$dat4 + vld1.32 {q9},[$key_],#16 + b.gt .Loop5x_xts_enc + + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + aese $dat3,q8 + aesmc $dat3,$dat3 + aese $dat4,q8 + aesmc $dat4,$dat4 + subs $len,$len,#0x50 // because .Lxts_enc_tail4x + + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + aese $dat3,q9 + aesmc $dat3,$dat3 + aese $dat4,q9 + aesmc $dat4,$dat4 + csel $xoffset,xzr,$len,gt // borrow x6, w6, "gt" is not typo + mov $key_,$key1 + + aese $dat0,q10 + aesmc $dat0,$dat0 + aese $dat1,q10 + aesmc $dat1,$dat1 + aese $dat2,q10 + aesmc $dat2,$dat2 + aese $dat3,q10 + aesmc $dat3,$dat3 + aese $dat4,q10 + aesmc $dat4,$dat4 + add $inp,$inp,$xoffset // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add $xoffset,$len,#0x60 // because .Lxts_enc_tail4x + + aese $dat0,q11 + aesmc $dat0,$dat0 + aese $dat1,q11 + aesmc $dat1,$dat1 + aese $dat2,q11 + aesmc $dat2,$dat2 + aese $dat3,q11 + aesmc $dat3,$dat3 + aese $dat4,q11 + aesmc $dat4,$dat4 + + aese $dat0,q12 + aesmc $dat0,$dat0 + aese $dat1,q12 + aesmc $dat1,$dat1 + aese $dat2,q12 + aesmc $dat2,$dat2 + aese $dat3,q12 + aesmc $dat3,$dat3 + aese $dat4,q12 + aesmc $dat4,$dat4 + + aese $dat0,q13 + aesmc $dat0,$dat0 + aese $dat1,q13 + aesmc $dat1,$dat1 + aese $dat2,q13 + aesmc $dat2,$dat2 + aese $dat3,q13 + aesmc $dat3,$dat3 + aese $dat4,q13 + aesmc $dat4,$dat4 + + aese $dat0,q14 + aesmc $dat0,$dat0 + aese $dat1,q14 + aesmc $dat1,$dat1 + aese $dat2,q14 + aesmc $dat2,$dat2 + aese $dat3,q14 + aesmc $dat3,$dat3 + aese $dat4,q14 + aesmc $dat4,$dat4 + + veor $tmp0,$rndlast,$iv0 + aese $dat0,q15 + // The iv for first block of one iteration + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr#31 + eor $ivl,$tmpmx,$ivl,lsl#1 + fmov $ivd00,$ivl + fmov $ivd01,$ivh + veor $tmp1,$rndlast,$iv1 + vld1.8 {$in0},[$inp],#16 + aese $dat1,q15 + // The iv for second block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr#31 + eor $ivl,$tmpmx,$ivl,lsl#1 + fmov $ivd10,$ivl + fmov $ivd11,$ivh + veor $tmp2,$rndlast,$iv2 + vld1.8 {$in1},[$inp],#16 + aese $dat2,q15 + // The iv for third block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr#31 + eor $ivl,$tmpmx,$ivl,lsl#1 + fmov $ivd20,$ivl + fmov $ivd21,$ivh + veor $tmp3,$rndlast,$iv3 + vld1.8 {$in2},[$inp],#16 + aese $dat3,q15 + // The iv for fourth block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr#31 + eor $ivl,$tmpmx,$ivl,lsl#1 + fmov $ivd30,$ivl + fmov $ivd31,$ivh + veor $tmp4,$rndlast,$iv4 + vld1.8 {$in3},[$inp],#16 + aese $dat4,q15 + + // The iv for fifth block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd40,$ivl + fmov $ivd41,$ivh + + vld1.8 {$in4},[$inp],#16 + cbz $xoffset,.Lxts_enc_tail4x + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + veor $tmp0,$tmp0,$dat0 + veor $dat0,$in0,$iv0 + veor $tmp1,$tmp1,$dat1 + veor $dat1,$in1,$iv1 + veor $tmp2,$tmp2,$dat2 + veor $dat2,$in2,$iv2 + veor $tmp3,$tmp3,$dat3 + veor $dat3,$in3,$iv3 + veor $tmp4,$tmp4,$dat4 + vst1.8 {$tmp0},[$out],#16 + veor $dat4,$in4,$iv4 + vst1.8 {$tmp1},[$out],#16 + mov $rounds,$rounds0 + vst1.8 {$tmp2},[$out],#16 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + b.hs .Loop5x_xts_enc + + + // If left 4 blocks, borrow the five block's processing. + cmn $len,#0x10 + b.ne .Loop5x_enc_after + vorr $iv4,$iv3,$iv3 + vorr $iv3,$iv2,$iv2 + vorr $iv2,$iv1,$iv1 + vorr $iv1,$iv0,$iv0 + fmov $ivl,$ivd40 + fmov $ivh,$ivd41 + veor $dat0,$iv0,$in0 + veor $dat1,$iv1,$in1 + veor $dat2,$in2,$iv2 + veor $dat3,$in3,$iv3 + veor $dat4,$in4,$iv4 + b.eq .Loop5x_xts_enc + +.Loop5x_enc_after: + add $len,$len,#0x50 + cbz $len,.Lxts_enc_done + + add $rounds,$rounds0,#2 + subs $len,$len,#0x30 + b.lo .Lxts_inner_enc_tail + + veor $dat0,$iv0,$in2 + veor $dat1,$iv1,$in3 + veor $dat2,$in4,$iv2 + b .Lxts_outer_enc_tail + +.align 4 +.Lxts_enc_tail4x: + add $inp,$inp,#16 + veor $tmp1,$dat1,$tmp1 + vst1.8 {$tmp1},[$out],#16 + veor $tmp2,$dat2,$tmp2 + vst1.8 {$tmp2},[$out],#16 + veor $tmp3,$dat3,$tmp3 + veor $tmp4,$dat4,$tmp4 + vst1.8 {$tmp3-$tmp4},[$out],#32 + + b .Lxts_enc_done +.align 4 +.Lxts_outer_enc_tail: + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $rounds,$rounds,#2 + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Lxts_outer_enc_tail + + aese $dat0,q8 + aesmc $dat0,$dat0 + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + veor $tmp0,$iv0,$rndlast + subs $len,$len,#0x30 + // The iv for first block + fmov $ivl,$ivd20 + fmov $ivh,$ivd21 + //mov $constnum,#0x87 + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr#31 + eor $ivl,$tmpmx,$ivl,lsl#1 + fmov $ivd00,$ivl + fmov $ivd01,$ivh + veor $tmp1,$iv1,$rndlast + csel $xoffset,$len,$xoffset,lo // x6, w6, is zero at this point + aese $dat0,q9 + aesmc $dat0,$dat0 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + veor $tmp2,$iv2,$rndlast + + add $xoffset,$xoffset,#0x20 + add $inp,$inp,$xoffset + mov $key_,$key1 + + aese $dat0,q12 + aesmc $dat0,$dat0 + aese $dat1,q12 + aesmc $dat1,$dat1 + aese $dat2,q12 + aesmc $dat2,$dat2 + aese $dat0,q13 + aesmc $dat0,$dat0 + aese $dat1,q13 + aesmc $dat1,$dat1 + aese $dat2,q13 + aesmc $dat2,$dat2 + aese $dat0,q14 + aesmc $dat0,$dat0 + aese $dat1,q14 + aesmc $dat1,$dat1 + aese $dat2,q14 + aesmc $dat2,$dat2 + aese $dat0,q15 + aese $dat1,q15 + aese $dat2,q15 + vld1.8 {$in2},[$inp],#16 + add $rounds,$rounds0,#2 + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + veor $tmp0,$tmp0,$dat0 + veor $tmp1,$tmp1,$dat1 + veor $dat2,$dat2,$tmp2 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp0},[$out],#16 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$dat2},[$out],#16 + cmn $len,#0x30 + b.eq .Lxts_enc_done +.Lxts_encxor_one: + vorr $in3,$in1,$in1 + vorr $in4,$in2,$in2 + nop + +.Lxts_inner_enc_tail: + cmn $len,#0x10 + veor $dat1,$in3,$iv0 + veor $dat2,$in4,$iv1 + b.eq .Lxts_enc_tail_loop + veor $dat2,$in4,$iv0 +.Lxts_enc_tail_loop: + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $rounds,$rounds,#2 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Lxts_enc_tail_loop + + aese $dat1,q8 + aesmc $dat1,$dat1 + aese $dat2,q8 + aesmc $dat2,$dat2 + aese $dat1,q9 + aesmc $dat1,$dat1 + aese $dat2,q9 + aesmc $dat2,$dat2 + aese $dat1,q12 + aesmc $dat1,$dat1 + aese $dat2,q12 + aesmc $dat2,$dat2 + cmn $len,#0x20 + aese $dat1,q13 + aesmc $dat1,$dat1 + aese $dat2,q13 + aesmc $dat2,$dat2 + veor $tmp1,$iv0,$rndlast + aese $dat1,q14 + aesmc $dat1,$dat1 + aese $dat2,q14 + aesmc $dat2,$dat2 + veor $tmp2,$iv1,$rndlast + aese $dat1,q15 + aese $dat2,q15 + b.eq .Lxts_enc_one + veor $tmp1,$tmp1,$dat1 + vst1.8 {$tmp1},[$out],#16 + veor $tmp2,$tmp2,$dat2 + vorr $iv0,$iv1,$iv1 + vst1.8 {$tmp2},[$out],#16 + fmov $ivl,$ivd10 + fmov $ivh,$ivd11 + mov $constnum,#0x87 + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd00,$ivl + fmov $ivd01,$ivh + b .Lxts_enc_done + +.Lxts_enc_one: + veor $tmp1,$tmp1,$dat2 + vorr $iv0,$iv0,$iv0 + vst1.8 {$tmp1},[$out],#16 + fmov $ivl,$ivd00 + fmov $ivh,$ivd01 + mov $constnum,#0x87 + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd00,$ivl + fmov $ivd01,$ivh + b .Lxts_enc_done +.align 5 +.Lxts_enc_done: + // Process the tail block with cipher stealing. + tst $tailcnt,#0xf + b.eq .Lxts_abort + + mov $tmpinp,$inp + mov $tmpoutp,$out + sub $out,$out,#16 +.composite_enc_loop: + subs $tailcnt,$tailcnt,#1 + ldrb $l2outp,[$out,$tailcnt] + ldrb $loutp,[$tmpinp,$tailcnt] + strb $l2outp,[$tmpoutp,$tailcnt] + strb $loutp,[$out,$tailcnt] + b.gt .composite_enc_loop +.Lxts_enc_load_done: + vld1.8 {$tmpin},[$out] + veor $tmpin,$tmpin,$iv0 + + // Encrypt the composite block to get the last second encrypted text block + ldr $rounds,[$key1,#240] // load key schedule... + vld1.8 {$dat},[$key1],#16 + sub $rounds,$rounds,#2 + vld1.8 {$dat1},[$key1],#16 // load key schedule... +.Loop_final_enc: + aese $tmpin,$dat0 + aesmc $tmpin,$tmpin + vld1.32 {$dat0},[$key1],#16 + subs $rounds,$rounds,#2 + aese $tmpin,$dat1 + aesmc $tmpin,$tmpin + vld1.32 {$dat1},[$key1],#16 + b.gt .Loop_final_enc + + aese $tmpin,$dat0 + aesmc $tmpin,$tmpin + vld1.32 {$dat0},[$key1] + aese $tmpin,$dat1 + veor $tmpin,$tmpin,$dat0 + veor $tmpin,$tmpin,$iv0 + vst1.8 {$tmpin},[$out] + +.Lxts_abort: + ldp $tailcnt,$midnumx,[sp,#48] + ldp $ivd10,$ivd20,[sp,#32] + ldp $ivd30,$ivd40,[sp,#16] + ldp $constnumx,$tmpinp,[sp],#64 +.Lxts_enc_final_abort: + ret +.size ${prefix}_xts_encrypt,.-${prefix}_xts_encrypt +___ + +}}} +{{{ +my ($inp,$out,$len,$key1,$key2,$ivp)=map("x$_",(0..5)); +my ($rounds0,$rounds,$key_,$step,$ivl,$ivh)=("w5","w6","x7","x8","x9","x10"); +my ($tmpoutp,$loutp,$l2outp,$tmpinp)=("x13","w14","w15","x20"); +my ($tailcnt,$midnum,$midnumx,$constnum,$constnumx)=("x21","w22","x22","w19","x19"); +my ($xoffset,$tmpmx,$tmpmw)=("x6","x11","w11"); +my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$tmp2,$rndlast)=map("q$_",(0..7)); +my ($iv0,$iv1,$iv2,$iv3,$iv4,$tmpin)=("v6.16b","v8.16b","v9.16b","v10.16b","v11.16b","v26.16b"); +my ($ivd00,$ivd01,$ivd20,$ivd21)=("d6","v6.d[1]","d9","v9.d[1]"); +my ($ivd10,$ivd11,$ivd30,$ivd31,$ivd40,$ivd41)=("d8","v8.d[1]","d10","v10.d[1]","d11","v11.d[1]"); + +my ($dat,$tmp,$rndzero_n_last)=($dat0,$tmp0,$tmp1); + +# q7 last round key +# q10-q15, q7 Last 7 round keys +# q8-q9 preloaded round keys except last 7 keys for big size +# q20, q21, q8-q9 preloaded round keys except last 7 keys for only 16 byte + +{ +my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9)); + +my ($dat3,$in3,$tmp3); # used only in 64-bit mode +my ($dat4,$in4,$tmp4); +if ($flavour =~ /64/) { + ($dat2,$dat3,$dat4,$in2,$in3,$in4,$tmp3,$tmp4)=map("q$_",(16..23)); +} + +$code.=<<___ if ($flavour =~ /64/); +.globl ${prefix}_xts_decrypt +.type ${prefix}_xts_decrypt,%function +.align 5 +${prefix}_xts_decrypt: +___ +$code.=<<___ if ($flavour =~ /64/); + cmp $len,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne .Lxts_dec_big_size + // Encrypt the iv with key2, as the first XEX iv. + ldr $rounds,[$key2,#240] + vld1.8 {$dat},[$key2],#16 + vld1.8 {$iv0},[$ivp] + sub $rounds,$rounds,#2 + vld1.8 {$dat1},[$key2],#16 + +.Loop_dec_small_iv_enc: + aese $iv0,$dat + aesmc $iv0,$iv0 + vld1.32 {$dat},[$key2],#16 + subs $rounds,$rounds,#2 + aese $iv0,$dat1 + aesmc $iv0,$iv0 + vld1.32 {$dat1},[$key2],#16 + b.gt .Loop_dec_small_iv_enc + + aese $iv0,$dat + aesmc $iv0,$iv0 + vld1.32 {$dat},[$key2] + aese $iv0,$dat1 + veor $iv0,$iv0,$dat + + vld1.8 {$dat0},[$inp] + veor $dat0,$iv0,$dat0 + + ldr $rounds,[$key1,#240] + vld1.32 {q20-q21},[$key1],#32 // load key schedule... + + aesd $dat0,q20 + aesimc $dat0,$dat0 + vld1.32 {q8-q9},[$key1],#32 // load key schedule... + aesd $dat0,q21 + aesimc $dat0,$dat0 + subs $rounds,$rounds,#10 // bias + b.eq .Lxts_128_dec +.Lxts_dec_round_loop: + aesd $dat0,q8 + aesimc $dat0,$dat0 + vld1.32 {q8},[$key1],#16 // load key schedule... + aesd $dat0,q9 + aesimc $dat0,$dat0 + vld1.32 {q9},[$key1],#16 // load key schedule... + subs $rounds,$rounds,#2 // bias + b.gt .Lxts_dec_round_loop +.Lxts_128_dec: + vld1.32 {q10-q11},[$key1],#32 // load key schedule... + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat0,q9 + aesimc $dat0,$dat0 + vld1.32 {q12-q13},[$key1],#32 // load key schedule... + aesd $dat0,q10 + aesimc $dat0,$dat0 + aesd $dat0,q11 + aesimc $dat0,$dat0 + vld1.32 {q14-q15},[$key1],#32 // load key schedule... + aesd $dat0,q12 + aesimc $dat0,$dat0 + aesd $dat0,q13 + aesimc $dat0,$dat0 + vld1.32 {$rndlast},[$key1] + aesd $dat0,q14 + aesimc $dat0,$dat0 + aesd $dat0,q15 + veor $dat0,$dat0,$rndlast + veor $dat0,$iv0,$dat0 + vst1.8 {$dat0},[$out] + b .Lxts_dec_final_abort +.Lxts_dec_big_size: +___ +$code.=<<___ if ($flavour =~ /64/); + stp $constnumx,$tmpinp,[sp,#-64]! + stp $tailcnt,$midnumx,[sp,#48] + stp $ivd10,$ivd20,[sp,#32] + stp $ivd30,$ivd40,[sp,#16] + + and $tailcnt,$len,#0xf + and $len,$len,#-16 + subs $len,$len,#16 + mov $step,#16 + b.lo .Lxts_dec_abort + + // Encrypt the iv with key2, as the first XEX iv + ldr $rounds,[$key2,#240] + vld1.8 {$dat},[$key2],#16 + vld1.8 {$iv0},[$ivp] + sub $rounds,$rounds,#2 + vld1.8 {$dat1},[$key2],#16 + +.Loop_dec_iv_enc: + aese $iv0,$dat + aesmc $iv0,$iv0 + vld1.32 {$dat},[$key2],#16 + subs $rounds,$rounds,#2 + aese $iv0,$dat1 + aesmc $iv0,$iv0 + vld1.32 {$dat1},[$key2],#16 + b.gt .Loop_dec_iv_enc + + aese $iv0,$dat + aesmc $iv0,$iv0 + vld1.32 {$dat},[$key2] + aese $iv0,$dat1 + veor $iv0,$iv0,$dat + + // The iv for second block + // $ivl- iv(low), $ivh - iv(high) + // the five ivs stored into, $iv0,$iv1,$iv2,$iv3,$iv4 + fmov $ivl,$ivd00 + fmov $ivh,$ivd01 + mov $constnum,#0x87 + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd10,$ivl + fmov $ivd11,$ivh + + ldr $rounds0,[$key1,#240] // load rounds number + + // The iv for third block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd20,$ivl + fmov $ivd21,$ivh + + vld1.32 {q8-q9},[$key1] // load key schedule... + sub $rounds0,$rounds0,#6 + add $key_,$key1,$ivp,lsl#4 // pointer to last 7 round keys + sub $rounds0,$rounds0,#2 + vld1.32 {q10-q11},[$key_],#32 // load key schedule... + vld1.32 {q12-q13},[$key_],#32 + vld1.32 {q14-q15},[$key_],#32 + vld1.32 {$rndlast},[$key_] + + // The iv for fourth block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd30,$ivl + fmov $ivd31,$ivh + + add $key_,$key1,#32 + mov $rounds,$rounds0 + b .Lxts_dec + + // Decryption +.align 5 +.Lxts_dec: + tst $tailcnt,#0xf + b.eq .Lxts_dec_begin + subs $len,$len,#16 + csel $step,xzr,$step,eq + vld1.8 {$dat},[$inp],#16 + b.lo .Lxts_done + sub $inp,$inp,#16 +.Lxts_dec_begin: + vld1.8 {$dat},[$inp],$step + subs $len,$len,#32 // bias + add $rounds,$rounds0,#2 + vorr $in1,$dat,$dat + vorr $dat1,$dat,$dat + vorr $in3,$dat,$dat + vld1.8 {$dat2},[$inp],#16 + vorr $in2,$dat2,$dat2 + vorr $in4,$dat2,$dat2 + b.lo .Lxts_inner_dec_tail + veor $dat,$dat,$iv0 // before decryt, xor with iv + veor $dat2,$dat2,$iv1 + + vorr $dat1,$dat2,$dat2 + vld1.8 {$dat2},[$inp],#16 + vorr $in0,$dat,$dat + vorr $in1,$dat1,$dat1 + veor $in2,$dat2,$iv2 // third block xox with third iv + veor $dat2,$dat2,$iv2 + cmp $len,#32 + b.lo .Lxts_outer_dec_tail + + vld1.8 {$dat3},[$inp],#16 + + // The iv for fifth block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd40,$ivl + fmov $ivd41,$ivh + + vld1.8 {$dat4},[$inp],#16 + veor $dat3,$dat3,$iv3 // the fourth block + veor $dat4,$dat4,$iv4 + sub $len,$len,#32 // bias + mov $rounds,$rounds0 + b .Loop5x_xts_dec - adds $len,$len,#3 - b.eq .Lctr32_done - cmp $len,#1 - mov $step,#16 - cclr $step,eq +.align 4 +.Loop5x_xts_dec: + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + aesd $dat3,q8 + aesimc $dat3,$dat3 + aesd $dat4,q8 + aesimc $dat4,$dat4 + vld1.32 {q8},[$key_],#16 // load key schedule... + subs $rounds,$rounds,#2 + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + aesd $dat3,q9 + aesimc $dat3,$dat3 + aesd $dat4,q9 + aesimc $dat4,$dat4 + vld1.32 {q9},[$key_],#16 // load key schedule... + b.gt .Loop5x_xts_dec -.Lctr32_tail: - aese $dat0,q8 - aesmc $dat0,$dat0 - aese $dat1,q8 - aesmc $dat1,$dat1 - vld1.32 {q8},[$key_],#16 - subs $cnt,$cnt,#2 - aese $dat0,q9 - aesmc $dat0,$dat0 - aese $dat1,q9 - aesmc $dat1,$dat1 - vld1.32 {q9},[$key_],#16 - b.gt .Lctr32_tail + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + aesd $dat3,q8 + aesimc $dat3,$dat3 + aesd $dat4,q8 + aesimc $dat4,$dat4 + subs $len,$len,#0x50 // because .Lxts_dec_tail4x - aese $dat0,q8 - aesmc $dat0,$dat0 - aese $dat1,q8 - aesmc $dat1,$dat1 - aese $dat0,q9 - aesmc $dat0,$dat0 - aese $dat1,q9 - aesmc $dat1,$dat1 - vld1.8 {$in0},[$inp],$step - aese $dat0,q12 - aesmc $dat0,$dat0 - aese $dat1,q12 - aesmc $dat1,$dat1 - vld1.8 {$in1},[$inp] - aese $dat0,q13 - aesmc $dat0,$dat0 - aese $dat1,q13 - aesmc $dat1,$dat1 - veor $in0,$in0,$rndlast - aese $dat0,q14 - aesmc $dat0,$dat0 - aese $dat1,q14 - aesmc $dat1,$dat1 - veor $in1,$in1,$rndlast - aese $dat0,q15 - aese $dat1,q15 + aesd $dat0,q9 + aesimc $dat0,$dat + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + aesd $dat3,q9 + aesimc $dat3,$dat3 + aesd $dat4,q9 + aesimc $dat4,$dat4 + csel $xoffset,xzr,$len,gt // borrow x6, w6, "gt" is not typo + mov $key_,$key1 + + aesd $dat0,q10 + aesimc $dat0,$dat0 + aesd $dat1,q10 + aesimc $dat1,$dat1 + aesd $dat2,q10 + aesimc $dat2,$dat2 + aesd $dat3,q10 + aesimc $dat3,$dat3 + aesd $dat4,q10 + aesimc $dat4,$dat4 + add $inp,$inp,$xoffset // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add $xoffset,$len,#0x60 // because .Lxts_dec_tail4x + + aesd $dat0,q11 + aesimc $dat0,$dat0 + aesd $dat1,q11 + aesimc $dat1,$dat1 + aesd $dat2,q11 + aesimc $dat2,$dat2 + aesd $dat3,q11 + aesimc $dat3,$dat3 + aesd $dat4,q11 + aesimc $dat4,$dat4 - cmp $len,#1 - veor $in0,$in0,$dat0 - veor $in1,$in1,$dat1 - vst1.8 {$in0},[$out],#16 - b.eq .Lctr32_done - vst1.8 {$in1},[$out] + aesd $dat0,q12 + aesimc $dat0,$dat0 + aesd $dat1,q12 + aesimc $dat1,$dat1 + aesd $dat2,q12 + aesimc $dat2,$dat2 + aesd $dat3,q12 + aesimc $dat3,$dat3 + aesd $dat4,q12 + aesimc $dat4,$dat4 -.Lctr32_done: -___ -$code.=<<___ if ($flavour !~ /64/); - vldmia sp!,{d8-d15} - ldmia sp!,{r4-r10,pc} -___ -$code.=<<___ if ($flavour =~ /64/); - ldr x29,[sp],#16 + aesd $dat0,q13 + aesimc $dat0,$dat0 + aesd $dat1,q13 + aesimc $dat1,$dat1 + aesd $dat2,q13 + aesimc $dat2,$dat2 + aesd $dat3,q13 + aesimc $dat3,$dat3 + aesd $dat4,q13 + aesimc $dat4,$dat4 + + aesd $dat0,q14 + aesimc $dat0,$dat0 + aesd $dat1,q14 + aesimc $dat1,$dat1 + aesd $dat2,q14 + aesimc $dat2,$dat2 + aesd $dat3,q14 + aesimc $dat3,$dat3 + aesd $dat4,q14 + aesimc $dat4,$dat4 + + veor $tmp0,$rndlast,$iv0 + aesd $dat0,q15 + // The iv for first block of next iteration. + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd00,$ivl + fmov $ivd01,$ivh + veor $tmp1,$rndlast,$iv1 + vld1.8 {$in0},[$inp],#16 + aesd $dat1,q15 + // The iv for second block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd10,$ivl + fmov $ivd11,$ivh + veor $tmp2,$rndlast,$iv2 + vld1.8 {$in1},[$inp],#16 + aesd $dat2,q15 + // The iv for third block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd20,$ivl + fmov $ivd21,$ivh + veor $tmp3,$rndlast,$iv3 + vld1.8 {$in2},[$inp],#16 + aesd $dat3,q15 + // The iv for fourth block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd30,$ivl + fmov $ivd31,$ivh + veor $tmp4,$rndlast,$iv4 + vld1.8 {$in3},[$inp],#16 + aesd $dat4,q15 + + // The iv for fifth block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd40,$ivl + fmov $ivd41,$ivh + + vld1.8 {$in4},[$inp],#16 + cbz $xoffset,.Lxts_dec_tail4x + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + veor $tmp0,$tmp0,$dat0 + veor $dat0,$in0,$iv0 + veor $tmp1,$tmp1,$dat1 + veor $dat1,$in1,$iv1 + veor $tmp2,$tmp2,$dat2 + veor $dat2,$in2,$iv2 + veor $tmp3,$tmp3,$dat3 + veor $dat3,$in3,$iv3 + veor $tmp4,$tmp4,$dat4 + vst1.8 {$tmp0},[$out],#16 + veor $dat4,$in4,$iv4 + vst1.8 {$tmp1},[$out],#16 + mov $rounds,$rounds0 + vst1.8 {$tmp2},[$out],#16 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp3},[$out],#16 + vst1.8 {$tmp4},[$out],#16 + b.hs .Loop5x_xts_dec + + cmn $len,#0x10 + b.ne .Loop5x_dec_after + // If x2($len) equal to -0x10, the left blocks is 4. + // After specially processing, utilize the five blocks processing again. + // It will use the following IVs: $iv0,$iv0,$iv1,$iv2,$iv3. + vorr $iv4,$iv3,$iv3 + vorr $iv3,$iv2,$iv2 + vorr $iv2,$iv1,$iv1 + vorr $iv1,$iv0,$iv0 + fmov $ivl,$ivd40 + fmov $ivh,$ivd41 + veor $dat0,$iv0,$in0 + veor $dat1,$iv1,$in1 + veor $dat2,$in2,$iv2 + veor $dat3,$in3,$iv3 + veor $dat4,$in4,$iv4 + b.eq .Loop5x_xts_dec + +.Loop5x_dec_after: + add $len,$len,#0x50 + cbz $len,.Lxts_done + + add $rounds,$rounds0,#2 + subs $len,$len,#0x30 + b.lo .Lxts_inner_dec_tail + + veor $dat0,$iv0,$in2 + veor $dat1,$iv1,$in3 + veor $dat2,$in4,$iv2 + b .Lxts_outer_dec_tail + +.align 4 +.Lxts_dec_tail4x: + add $inp,$inp,#16 + vld1.32 {$dat0},[$inp],#16 + veor $tmp1,$dat1,$tmp0 + vst1.8 {$tmp1},[$out],#16 + veor $tmp2,$dat2,$tmp2 + vst1.8 {$tmp2},[$out],#16 + veor $tmp3,$dat3,$tmp3 + veor $tmp4,$dat4,$tmp4 + vst1.8 {$tmp3-$tmp4},[$out],#32 + + b .Lxts_done +.align 4 +.Lxts_outer_dec_tail: + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $rounds,$rounds,#2 + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Lxts_outer_dec_tail + + aesd $dat0,q8 + aesimc $dat0,$dat0 + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + veor $tmp0,$iv0,$rndlast + subs $len,$len,#0x30 + // The iv for first block + fmov $ivl,$ivd20 + fmov $ivh,$ivd21 + mov $constnum,#0x87 + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd00,$ivl + fmov $ivd01,$ivh + veor $tmp1,$iv1,$rndlast + csel $xoffset,$len,$xoffset,lo // x6, w6, is zero at this point + aesd $dat0,q9 + aesimc $dat0,$dat0 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + veor $tmp2,$iv2,$rndlast + // The iv for second block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd10,$ivl + fmov $ivd11,$ivh + + add $xoffset,$xoffset,#0x20 + add $inp,$inp,$xoffset // $inp is adjusted to the last data + + mov $key_,$key1 + + // The iv for third block + extr $midnumx,$ivh,$ivh,#32 + extr $ivh,$ivh,$ivl,#63 + and $tmpmw,$constnum,$midnum,asr #31 + eor $ivl,$tmpmx,$ivl,lsl #1 + fmov $ivd20,$ivl + fmov $ivd21,$ivh + + aesd $dat0,q12 + aesimc $dat0,$dat0 + aesd $dat1,q12 + aesimc $dat1,$dat1 + aesd $dat2,q12 + aesimc $dat2,$dat2 + aesd $dat0,q13 + aesimc $dat0,$dat0 + aesd $dat1,q13 + aesimc $dat1,$dat1 + aesd $dat2,q13 + aesimc $dat2,$dat2 + aesd $dat0,q14 + aesimc $dat0,$dat0 + aesd $dat1,q14 + aesimc $dat1,$dat1 + aesd $dat2,q14 + aesimc $dat2,$dat2 + vld1.8 {$in2},[$inp],#16 + aesd $dat0,q15 + aesd $dat1,q15 + aesd $dat2,q15 + vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0] + add $rounds,$rounds0,#2 + veor $tmp0,$tmp0,$dat0 + veor $tmp1,$tmp1,$dat1 + veor $dat2,$dat2,$tmp2 + vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$tmp0},[$out],#16 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$dat2},[$out],#16 + + cmn $len,#0x30 + add $len,$len,#0x30 + b.eq .Lxts_done + sub $len,$len,#0x30 + vorr $in3,$in1,$in1 + vorr $in4,$in2,$in2 + nop + +.Lxts_inner_dec_tail: + // $len == -0x10 means two blocks left. + cmn $len,#0x10 + veor $dat1,$in3,$iv0 + veor $dat2,$in4,$iv1 + b.eq .Lxts_dec_tail_loop + veor $dat2,$in4,$iv0 +.Lxts_dec_tail_loop: + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + vld1.32 {q8},[$key_],#16 + subs $rounds,$rounds,#2 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + vld1.32 {q9},[$key_],#16 + b.gt .Lxts_dec_tail_loop + + aesd $dat1,q8 + aesimc $dat1,$dat1 + aesd $dat2,q8 + aesimc $dat2,$dat2 + aesd $dat1,q9 + aesimc $dat1,$dat1 + aesd $dat2,q9 + aesimc $dat2,$dat2 + aesd $dat1,q12 + aesimc $dat1,$dat1 + aesd $dat2,q12 + aesimc $dat2,$dat2 + cmn $len,#0x20 + aesd $dat1,q13 + aesimc $dat1,$dat1 + aesd $dat2,q13 + aesimc $dat2,$dat2 + veor $tmp1,$iv0,$rndlast + aesd $dat1,q14 + aesimc $dat1,$dat1 + aesd $dat2,q14 + aesimc $dat2,$dat2 + veor $tmp2,$iv1,$rndlast + aesd $dat1,q15 + aesd $dat2,q15 + b.eq .Lxts_dec_one + veor $tmp1,$tmp1,$dat1 + veor $tmp2,$tmp2,$dat2 + vorr $iv0,$iv2,$iv2 + vorr $iv1,$iv3,$iv3 + vst1.8 {$tmp1},[$out],#16 + vst1.8 {$tmp2},[$out],#16 + add $len,$len,#16 + b .Lxts_done + +.Lxts_dec_one: + veor $tmp1,$tmp1,$dat2 + vorr $iv0,$iv1,$iv1 + vorr $iv1,$iv2,$iv2 + vst1.8 {$tmp1},[$out],#16 + add $len,$len,#32 + +.Lxts_done: + tst $tailcnt,#0xf + b.eq .Lxts_dec_abort + // Processing the last two blocks with cipher stealing. + mov x7,x3 + cbnz x2,.Lxts_dec_1st_done + vld1.32 {$dat0},[$inp],#16 + + // Decrypt the last secod block to get the last plain text block +.Lxts_dec_1st_done: + eor $tmpin,$dat0,$iv1 + ldr $rounds,[$key1,#240] + vld1.32 {$dat0},[$key1],#16 + sub $rounds,$rounds,#2 + vld1.32 {$dat1},[$key1],#16 +.Loop_final_2nd_dec: + aesd $tmpin,$dat0 + aesimc $tmpin,$tmpin + vld1.32 {$dat0},[$key1],#16 // load key schedule... + subs $rounds,$rounds,#2 + aesd $tmpin,$dat1 + aesimc $tmpin,$tmpin + vld1.32 {$dat1},[$key1],#16 // load key schedule... + b.gt .Loop_final_2nd_dec + + aesd $tmpin,$dat0 + aesimc $tmpin,$tmpin + vld1.32 {$dat0},[$key1] + aesd $tmpin,$dat1 + veor $tmpin,$tmpin,$dat0 + veor $tmpin,$tmpin,$iv1 + vst1.8 {$tmpin},[$out] + + mov $tmpinp,$inp + add $tmpoutp,$out,#16 + + // Composite the tailcnt "16 byte not aligned block" into the last second plain blocks + // to get the last encrypted block. +.composite_dec_loop: + subs $tailcnt,$tailcnt,#1 + ldrb $l2outp,[$out,$tailcnt] + ldrb $loutp,[$tmpinp,$tailcnt] + strb $l2outp,[$tmpoutp,$tailcnt] + strb $loutp,[$out,$tailcnt] + b.gt .composite_dec_loop +.Lxts_dec_load_done: + vld1.8 {$tmpin},[$out] + veor $tmpin,$tmpin,$iv0 + + // Decrypt the composite block to get the last second plain text block + ldr $rounds,[$key_,#240] + vld1.8 {$dat},[$key_],#16 + sub $rounds,$rounds,#2 + vld1.8 {$dat1},[$key_],#16 +.Loop_final_dec: + aesd $tmpin,$dat0 + aesimc $tmpin,$tmpin + vld1.32 {$dat0},[$key_],#16 // load key schedule... + subs $rounds,$rounds,#2 + aesd $tmpin,$dat1 + aesimc $tmpin,$tmpin + vld1.32 {$dat1},[$key_],#16 // load key schedule... + b.gt .Loop_final_dec + + aesd $tmpin,$dat0 + aesimc $tmpin,$tmpin + vld1.32 {$dat0},[$key_] + aesd $tmpin,$dat1 + veor $tmpin,$tmpin,$dat0 + veor $tmpin,$tmpin,$iv0 + vst1.8 {$tmpin},[$out] + +.Lxts_dec_abort: + ldp $tailcnt,$midnumx,[sp,#48] + ldp $ivd10,$ivd20,[sp,#32] + ldp $ivd30,$ivd40,[sp,#16] + ldp $constnumx,$tmpinp,[sp],#64 + +.Lxts_dec_final_abort: ret +.size ${prefix}_xts_decrypt,.-${prefix}_xts_decrypt ___ -$code.=<<___; -.size ${prefix}_ctr32_encrypt_blocks,.-${prefix}_ctr32_encrypt_blocks -___ +} }}} $code.=<<___; #endif @@ -1025,7 +3675,7 @@ if ($flavour =~ /64/) { ######## 64-bit code # since ARMv7 instructions are always encoded little-endian. # correct solution is to use .inst directive, but older # assemblers don't implement it:-( - sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s", + sprintf "INST(0x%02x,0x%02x,0x%02x,0x%02x)\t@ %s %s", $word&0xff,($word>>8)&0xff, ($word>>16)&0xff,($word>>24)&0xff, $mnemonic,$arg; @@ -1066,14 +3716,17 @@ if ($flavour =~ /64/) { ######## 64-bit code s/\],#[0-9]+/]!/o; s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo or - s/cclr\s+([^,]+),\s*([a-z]+)/mov$2 $1,#0/o or + s/cclr\s+([^,]+),\s*([a-z]+)/mov.$2 $1,#0/o or s/vtbl\.8\s+(.*)/unvtbl($1)/geo or s/vdup\.32\s+(.*)/unvdup32($1)/geo or s/vmov\.32\s+(.*)/unvmov32($1)/geo or s/^(\s+)b\./$1b/o or - s/^(\s+)mov\./$1mov/o or s/^(\s+)ret/$1bx\tlr/o; + if (s/^(\s+)mov\.([a-z]+)/$1mov$2/) { + print " it $2\n"; + } + print $_,"\n"; } } diff --git a/crypto/openssl/crypto/aes/asm/bsaes-armv7.pl b/crypto/openssl/crypto/aes/asm/bsaes-armv7.pl index e2a84b380940..9c5dd5839acb 100755 --- a/crypto/openssl/crypto/aes/asm/bsaes-armv7.pl +++ b/crypto/openssl/crypto/aes/asm/bsaes-armv7.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -50,9 +50,10 @@ # April-August 2013 # Add CBC, CTR and XTS subroutines and adapt for kernel use; courtesy of Ard. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -60,9 +61,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } my ($inp,$out,$len,$key)=("r0","r1","r2","r3"); @@ -728,7 +730,6 @@ $code.=<<___; .arch armv7-a .fpu neon -.text .syntax unified @ ARMv7-capable assembler is expected to handle this #if defined(__thumb2__) && !defined(__APPLE__) .thumb @@ -737,6 +738,8 @@ $code.=<<___; # undef __thumb2__ #endif +.text + .type _bsaes_decrypt8,%function .align 4 _bsaes_decrypt8: @@ -1116,18 +1119,18 @@ $code.=<<___; .extern AES_cbc_encrypt .extern AES_decrypt -.global bsaes_cbc_encrypt -.type bsaes_cbc_encrypt,%function +.global ossl_bsaes_cbc_encrypt +.type ossl_bsaes_cbc_encrypt,%function .align 5 -bsaes_cbc_encrypt: +ossl_bsaes_cbc_encrypt: #ifndef __KERNEL__ cmp $len, #128 #ifndef __thumb__ blo AES_cbc_encrypt #else - bhs 1f + bhs .Lcbc_do_bsaes b AES_cbc_encrypt -1: +.Lcbc_do_bsaes: #endif #endif @@ -1381,7 +1384,7 @@ bsaes_cbc_encrypt: vst1.8 {@XMM[15]}, [$ivp] @ return IV VFP_ABI_POP ldmia sp!, {r4-r10, pc} -.size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt +.size ossl_bsaes_cbc_encrypt,.-ossl_bsaes_cbc_encrypt ___ } { @@ -1391,10 +1394,10 @@ my $keysched = "sp"; $code.=<<___; .extern AES_encrypt -.global bsaes_ctr32_encrypt_blocks -.type bsaes_ctr32_encrypt_blocks,%function +.global ossl_bsaes_ctr32_encrypt_blocks +.type ossl_bsaes_ctr32_encrypt_blocks,%function .align 5 -bsaes_ctr32_encrypt_blocks: +ossl_bsaes_ctr32_encrypt_blocks: cmp $len, #8 @ use plain AES for blo .Lctr_enc_short @ small sizes @@ -1444,7 +1447,7 @@ bsaes_ctr32_encrypt_blocks: .align 2 0: add r12, $key, #248 vld1.8 {@XMM[0]}, [$ctr] @ load counter - add $ctr, $const, #.LREVM0SR-.LM0 @ borrow $ctr + adrl $ctr, .LREVM0SR @ borrow $ctr vldmia r12, {@XMM[4]} @ load round0 key sub sp, #0x10 @ place for adjusted round0 key #endif @@ -1617,7 +1620,7 @@ bsaes_ctr32_encrypt_blocks: vstmia sp!, {q0-q1} ldmia sp!, {r4-r8, pc} -.size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks +.size ossl_bsaes_ctr32_encrypt_blocks,.-ossl_bsaes_ctr32_encrypt_blocks ___ } { @@ -1632,10 +1635,10 @@ my $twmask=@XMM[5]; my @T=@XMM[6..7]; $code.=<<___; -.globl bsaes_xts_encrypt -.type bsaes_xts_encrypt,%function +.globl ossl_bsaes_xts_encrypt +.type ossl_bsaes_xts_encrypt,%function .align 4 -bsaes_xts_encrypt: +ossl_bsaes_xts_encrypt: mov ip, sp stmdb sp!, {r4-r10, lr} @ 0x20 VFP_ABI_PUSH @@ -2034,12 +2037,12 @@ $code.=<<___; VFP_ABI_POP ldmia sp!, {r4-r10, pc} @ return -.size bsaes_xts_encrypt,.-bsaes_xts_encrypt +.size ossl_bsaes_xts_encrypt,.-ossl_bsaes_xts_encrypt -.globl bsaes_xts_decrypt -.type bsaes_xts_decrypt,%function +.globl ossl_bsaes_xts_decrypt +.type ossl_bsaes_xts_decrypt,%function .align 4 -bsaes_xts_decrypt: +ossl_bsaes_xts_decrypt: mov ip, sp stmdb sp!, {r4-r10, lr} @ 0x20 VFP_ABI_PUSH @@ -2469,7 +2472,7 @@ $code.=<<___; VFP_ABI_POP ldmia sp!, {r4-r10, pc} @ return -.size bsaes_xts_decrypt,.-bsaes_xts_decrypt +.size ossl_bsaes_xts_decrypt,.-ossl_bsaes_xts_decrypt ___ } $code.=<<___; diff --git a/crypto/openssl/crypto/aes/asm/bsaes-x86_64.pl b/crypto/openssl/crypto/aes/asm/bsaes-x86_64.pl new file mode 100644 index 000000000000..6498cfe908c8 --- /dev/null +++ b/crypto/openssl/crypto/aes/asm/bsaes-x86_64.pl @@ -0,0 +1,3243 @@ +#! /usr/bin/env perl +# Copyright 2011-2021 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 + + +################################################################### +### 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 possible 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... +# +# + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; +*STDOUT=*OUT; + +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 ossl_bsaes_cbc_encrypt +.type ossl_bsaes_cbc_encrypt,\@abi-omnipotent +.align 16 +ossl_bsaes_cbc_encrypt: +.cfi_startproc + endbranch +___ +$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 ossl_bsaes_cbc_encrypt,.-ossl_bsaes_cbc_encrypt + +.globl ossl_bsaes_ctr32_encrypt_blocks +.type ossl_bsaes_ctr32_encrypt_blocks,\@abi-omnipotent +.align 16 +ossl_bsaes_ctr32_encrypt_blocks: +.cfi_startproc + endbranch + 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 ossl_bsaes_ctr32_encrypt_blocks,.-ossl_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 ossl_bsaes_xts_encrypt +.type ossl_bsaes_xts_encrypt,\@abi-omnipotent +.align 16 +ossl_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 ossl_bsaes_xts_encrypt,.-ossl_bsaes_xts_encrypt + +.globl ossl_bsaes_xts_decrypt +.type ossl_bsaes_xts_decrypt,\@abi-omnipotent +.align 16 +ossl_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 ossl_bsaes_xts_decrypt,.-ossl_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 or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/aes/asm/vpaes-armv8.pl b/crypto/openssl/crypto/aes/asm/vpaes-armv8.pl index 7a9ffbd7d94c..dcd5065e68c0 100755 --- a/crypto/openssl/crypto/aes/asm/vpaes-armv8.pl +++ b/crypto/openssl/crypto/aes/asm/vpaes-armv8.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -30,6 +30,7 @@ # Denver(***) 16.6(**) 15.1/17.8(**) [8.80/9.93 ] # Apple A7(***) 22.7(**) 10.9/14.3 [8.45/10.0 ] # Mongoose(***) 26.3(**) 21.0/25.0(**) [13.3/16.8 ] +# ThunderX2(***) 39.4(**) 33.8/48.6(**) # # (*) ECB denotes approximate result for parallelizable modes # such as CBC decrypt, CTR, etc.; @@ -37,15 +38,18 @@ # code, but it's constant-time and therefore preferred; # (***) presented for reference/comparison purposes; -$flavour = shift; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $code.=<<___; @@ -150,12 +154,12 @@ my ($sb1u,$sb1t,$sb2u,$sb2t) = map("v$_.16b",(24..27)); my ($sb9u,$sb9t,$sbdu,$sbdt,$sbbu,$sbbt,$sbeu,$sbet)=map("v$_.16b",(24..31)); $code.=<<___; -## -## _aes_preheat -## -## Fills register %r10 -> .aes_consts (so you can -fPIC) -## and %xmm9-%xmm15 as specified below. -## +// +// _aes_preheat +// +// Fills register %r10 -> .aes_consts (so you can -fPIC) +// and %xmm9-%xmm15 as specified below. +// .type _vpaes_encrypt_preheat,%function .align 4 _vpaes_encrypt_preheat: @@ -167,21 +171,21 @@ _vpaes_encrypt_preheat: ret .size _vpaes_encrypt_preheat,.-_vpaes_encrypt_preheat -## -## _aes_encrypt_core -## -## AES-encrypt %xmm0. -## -## Inputs: -## %xmm0 = input -## %xmm9-%xmm15 as in _vpaes_preheat -## (%rdx) = scheduled keys -## -## Output in %xmm0 -## Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax -## Preserves %xmm6 - %xmm8 so you get some local vectors -## -## +// +// _aes_encrypt_core +// +// AES-encrypt %xmm0. +// +// Inputs: +// %xmm0 = input +// %xmm9-%xmm15 as in _vpaes_preheat +// (%rdx) = scheduled keys +// +// Output in %xmm0 +// Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax +// Preserves %xmm6 - %xmm8 so you get some local vectors +// +// .type _vpaes_encrypt_core,%function .align 4 _vpaes_encrypt_core: @@ -387,11 +391,11 @@ _vpaes_decrypt_preheat: ret .size _vpaes_decrypt_preheat,.-_vpaes_decrypt_preheat -## -## Decryption core -## -## Same API as encryption core. -## +// +// Decryption core +// +// Same API as encryption core. +// .type _vpaes_decrypt_core,%function .align 4 _vpaes_decrypt_core: @@ -643,11 +647,11 @@ my ($inp,$bits,$out,$dir)=("x0","w1","x2","w3"); my ($invlo,$invhi,$iptlo,$ipthi,$rcon) = map("v$_.16b",(18..21,8)); $code.=<<___; -######################################################## -## ## -## AES key schedule ## -## ## -######################################################## +//////////////////////////////////////////////////////// +// // +// AES key schedule // +// // +//////////////////////////////////////////////////////// .type _vpaes_key_preheat,%function .align 4 _vpaes_key_preheat: @@ -703,14 +707,14 @@ _vpaes_schedule_core: b.eq .Lschedule_192 // 128: fall though -## -## .schedule_128 -## -## 128-bit specific part of key schedule. -## -## This schedule is really simple, because all its parts -## are accomplished by the subroutines. -## +// +// .schedule_128 +// +// 128-bit specific part of key schedule. +// +// This schedule is really simple, because all its parts +// are accomplished by the subroutines. +// .Lschedule_128: mov $inp, #10 // mov \$10, %esi @@ -721,21 +725,21 @@ _vpaes_schedule_core: bl _vpaes_schedule_mangle // write output b .Loop_schedule_128 -## -## .aes_schedule_192 -## -## 192-bit specific part of key schedule. -## -## The main body of this schedule is the same as the 128-bit -## schedule, but with more smearing. The long, high side is -## stored in %xmm7 as before, and the short, low side is in -## the high bits of %xmm6. -## -## This schedule is somewhat nastier, however, because each -## round produces 192 bits of key material, or 1.5 round keys. -## Therefore, on each cycle we do 2 rounds and produce 3 round -## keys. -## +// +// .aes_schedule_192 +// +// 192-bit specific part of key schedule. +// +// The main body of this schedule is the same as the 128-bit +// schedule, but with more smearing. The long, high side is +// stored in %xmm7 as before, and the short, low side is in +// the high bits of %xmm6. +// +// This schedule is somewhat nastier, however, because each +// round produces 192 bits of key material, or 1.5 round keys. +// Therefore, on each cycle we do 2 rounds and produce 3 round +// keys. +// .align 4 .Lschedule_192: sub $inp, $inp, #8 @@ -759,16 +763,16 @@ _vpaes_schedule_core: bl _vpaes_schedule_192_smear b .Loop_schedule_192 -## -## .aes_schedule_256 -## -## 256-bit specific part of key schedule. -## -## The structure here is very similar to the 128-bit -## schedule, but with an additional "low side" in -## %xmm6. The low side's rounds are the same as the -## high side's, except no rcon and no rotation. -## +// +// .aes_schedule_256 +// +// 256-bit specific part of key schedule. +// +// The structure here is very similar to the 128-bit +// schedule, but with an additional "low side" in +// %xmm6. The low side's rounds are the same as the +// high side's, except no rcon and no rotation. +// .align 4 .Lschedule_256: ld1 {v0.16b}, [$inp] // vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned) @@ -795,16 +799,16 @@ _vpaes_schedule_core: b .Loop_schedule_256 -## -## .aes_schedule_mangle_last -## -## Mangler for last round of key schedule -## Mangles %xmm0 -## when encrypting, outputs out(%xmm0) ^ 63 -## when decrypting, outputs unskew(%xmm0) -## -## Always called right before return... jumps to cleanup and exits -## +// +// .aes_schedule_mangle_last +// +// Mangler for last round of key schedule +// Mangles %xmm0 +// when encrypting, outputs out(%xmm0) ^ 63 +// when decrypting, outputs unskew(%xmm0) +// +// Always called right before return... jumps to cleanup and exits +// .align 4 .Lschedule_mangle_last: // schedule last round key from xmm0 @@ -838,20 +842,20 @@ _vpaes_schedule_core: ret .size _vpaes_schedule_core,.-_vpaes_schedule_core -## -## .aes_schedule_192_smear -## -## Smear the short, low side in the 192-bit key schedule. -## -## Inputs: -## %xmm7: high side, b a x y -## %xmm6: low side, d c 0 0 -## %xmm13: 0 -## -## Outputs: -## %xmm6: b+c+d b+c 0 0 -## %xmm0: b+c+d b+c b a -## +// +// .aes_schedule_192_smear +// +// Smear the short, low side in the 192-bit key schedule. +// +// Inputs: +// %xmm7: high side, b a x y +// %xmm6: low side, d c 0 0 +// %xmm13: 0 +// +// Outputs: +// %xmm6: b+c+d b+c 0 0 +// %xmm0: b+c+d b+c b a +// .type _vpaes_schedule_192_smear,%function .align 4 _vpaes_schedule_192_smear: @@ -867,24 +871,24 @@ _vpaes_schedule_192_smear: ret .size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear -## -## .aes_schedule_round -## -## Runs one main round of the key schedule on %xmm0, %xmm7 -## -## Specifically, runs subbytes on the high dword of %xmm0 -## then rotates it by one byte and xors into the low dword of -## %xmm7. -## -## Adds rcon from low byte of %xmm8, then rotates %xmm8 for -## next rcon. -## -## Smears the dwords of %xmm7 by xoring the low into the -## second low, result into third, result into highest. -## -## Returns results in %xmm7 = %xmm0. -## Clobbers %xmm1-%xmm4, %r11. -## +// +// .aes_schedule_round +// +// Runs one main round of the key schedule on %xmm0, %xmm7 +// +// Specifically, runs subbytes on the high dword of %xmm0 +// then rotates it by one byte and xors into the low dword of +// %xmm7. +// +// Adds rcon from low byte of %xmm8, then rotates %xmm8 for +// next rcon. +// +// Smears the dwords of %xmm7 by xoring the low into the +// second low, result into third, result into highest. +// +// Returns results in %xmm7 = %xmm0. +// Clobbers %xmm1-%xmm4, %r11. +// .type _vpaes_schedule_round,%function .align 4 _vpaes_schedule_round: @@ -932,15 +936,15 @@ _vpaes_schedule_low_round: ret .size _vpaes_schedule_round,.-_vpaes_schedule_round -## -## .aes_schedule_transform -## -## Linear-transform %xmm0 according to tables at (%r11) -## -## Requires that %xmm9 = 0x0F0F... as in preheat -## Output in %xmm0 -## Clobbers %xmm1, %xmm2 -## +// +// .aes_schedule_transform +// +// Linear-transform %xmm0 according to tables at (%r11) +// +// Requires that %xmm9 = 0x0F0F... as in preheat +// Output in %xmm0 +// Clobbers %xmm1, %xmm2 +// .type _vpaes_schedule_transform,%function .align 4 _vpaes_schedule_transform: @@ -954,29 +958,29 @@ _vpaes_schedule_transform: ret .size _vpaes_schedule_transform,.-_vpaes_schedule_transform -## -## .aes_schedule_mangle -## -## Mangle xmm0 from (basis-transformed) standard version -## to our version. -## -## On encrypt, -## xor with 0x63 -## multiply by circulant 0,1,1,1 -## apply shiftrows transform -## -## On decrypt, -## xor with 0x63 -## multiply by "inverse mixcolumns" circulant E,B,D,9 -## deskew -## apply shiftrows transform -## -## -## Writes out to (%rdx), and increments or decrements it -## Keeps track of round number mod 4 in %r8 -## Preserves xmm0 -## Clobbers xmm1-xmm5 -## +// +// .aes_schedule_mangle +// +// Mangle xmm0 from (basis-transformed) standard version +// to our version. +// +// On encrypt, +// xor with 0x63 +// multiply by circulant 0,1,1,1 +// apply shiftrows transform +// +// On decrypt, +// xor with 0x63 +// multiply by "inverse mixcolumns" circulant E,B,D,9 +// deskew +// apply shiftrows transform +// +// +// Writes out to (%rdx), and increments or decrements it +// Keeps track of round number mod 4 in %r8 +// Preserves xmm0 +// Clobbers xmm1-xmm5 +// .type _vpaes_schedule_mangle,%function .align 4 _vpaes_schedule_mangle: diff --git a/crypto/openssl/crypto/aes/asm/vpaes-ppc.pl b/crypto/openssl/crypto/aes/asm/vpaes-ppc.pl index 0260a5c9bff0..7af47c630e71 100755 --- a/crypto/openssl/crypto/aes/asm/vpaes-ppc.pl +++ b/crypto/openssl/crypto/aes/asm/vpaes-ppc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -35,7 +35,10 @@ # (**) Inadequate POWER6 performance is due to astronomic AltiVec # latency, 9 cycles per simple logical operation. -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -61,7 +64,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + || die "can't call $xlate: $!"; $code.=<<___; .machine "any" diff --git a/crypto/openssl/crypto/aes/asm/vpaes-x86.pl b/crypto/openssl/crypto/aes/asm/vpaes-x86.pl index fb02a413345a..b206e934b48b 100755 --- a/crypto/openssl/crypto/aes/asm/vpaes-x86.pl +++ b/crypto/openssl/crypto/aes/asm/vpaes-x86.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -58,9 +58,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open OUT,">$output"; -*STDOUT=*OUT; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$x86only = $ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/aes/asm/vpaes-x86_64.pl b/crypto/openssl/crypto/aes/asm/vpaes-x86_64.pl index 099a686a4d5d..845528f41ac2 100755 --- a/crypto/openssl/crypto/aes/asm/vpaes-x86_64.pl +++ b/crypto/openssl/crypto/aes/asm/vpaes-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -54,9 +54,10 @@ # # -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -65,7 +66,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $PREFIX="vpaes"; @@ -696,6 +698,7 @@ _vpaes_schedule_mangle: .align 16 ${PREFIX}_set_encrypt_key: .cfi_startproc + endbranch ___ $code.=<<___ if ($win64); lea -0xb8(%rsp),%rsp @@ -746,6 +749,7 @@ $code.=<<___; .align 16 ${PREFIX}_set_decrypt_key: .cfi_startproc + endbranch ___ $code.=<<___ if ($win64); lea -0xb8(%rsp),%rsp @@ -801,6 +805,7 @@ $code.=<<___; .align 16 ${PREFIX}_encrypt: .cfi_startproc + endbranch ___ $code.=<<___ if ($win64); lea -0xb8(%rsp),%rsp @@ -846,6 +851,7 @@ $code.=<<___; .align 16 ${PREFIX}_decrypt: .cfi_startproc + endbranch ___ $code.=<<___ if ($win64); lea -0xb8(%rsp),%rsp @@ -897,6 +903,7 @@ $code.=<<___; .align 16 ${PREFIX}_cbc_encrypt: .cfi_startproc + endbranch xchg $key,$len ___ ($len,$key)=($key,$len); diff --git a/crypto/openssl/crypto/aes/bsaes-x86_64.S b/crypto/openssl/crypto/aes/bsaes-x86_64.S new file mode 100644 index 000000000000..ff533b2df32c --- /dev/null +++ b/crypto/openssl/crypto/aes/bsaes-x86_64.S @@ -0,0 +1,2618 @@ +.text + + + + +.type _bsaes_encrypt8,@function +.align 64 +_bsaes_encrypt8: +.cfi_startproc + leaq .LBS0(%rip),%r11 + + movdqa (%rax),%xmm8 + leaq 16(%rax),%rax + movdqa 80(%r11),%xmm7 + pxor %xmm8,%xmm15 + pxor %xmm8,%xmm0 + pxor %xmm8,%xmm1 + pxor %xmm8,%xmm2 +.byte 102,68,15,56,0,255 +.byte 102,15,56,0,199 + pxor %xmm8,%xmm3 + pxor %xmm8,%xmm4 +.byte 102,15,56,0,207 +.byte 102,15,56,0,215 + pxor %xmm8,%xmm5 + pxor %xmm8,%xmm6 +.byte 102,15,56,0,223 +.byte 102,15,56,0,231 +.byte 102,15,56,0,239 +.byte 102,15,56,0,247 +_bsaes_encrypt8_bitslice: + movdqa 0(%r11),%xmm7 + movdqa 16(%r11),%xmm8 + movdqa %xmm5,%xmm9 + psrlq $1,%xmm5 + movdqa %xmm3,%xmm10 + psrlq $1,%xmm3 + pxor %xmm6,%xmm5 + pxor %xmm4,%xmm3 + pand %xmm7,%xmm5 + pand %xmm7,%xmm3 + pxor %xmm5,%xmm6 + psllq $1,%xmm5 + pxor %xmm3,%xmm4 + psllq $1,%xmm3 + pxor %xmm9,%xmm5 + pxor %xmm10,%xmm3 + movdqa %xmm1,%xmm9 + psrlq $1,%xmm1 + movdqa %xmm15,%xmm10 + psrlq $1,%xmm15 + pxor %xmm2,%xmm1 + pxor %xmm0,%xmm15 + pand %xmm7,%xmm1 + pand %xmm7,%xmm15 + pxor %xmm1,%xmm2 + psllq $1,%xmm1 + pxor %xmm15,%xmm0 + psllq $1,%xmm15 + pxor %xmm9,%xmm1 + pxor %xmm10,%xmm15 + movdqa 32(%r11),%xmm7 + movdqa %xmm4,%xmm9 + psrlq $2,%xmm4 + movdqa %xmm3,%xmm10 + psrlq $2,%xmm3 + pxor %xmm6,%xmm4 + pxor %xmm5,%xmm3 + pand %xmm8,%xmm4 + pand %xmm8,%xmm3 + pxor %xmm4,%xmm6 + psllq $2,%xmm4 + pxor %xmm3,%xmm5 + psllq $2,%xmm3 + pxor %xmm9,%xmm4 + pxor %xmm10,%xmm3 + movdqa %xmm0,%xmm9 + psrlq $2,%xmm0 + movdqa %xmm15,%xmm10 + psrlq $2,%xmm15 + pxor %xmm2,%xmm0 + pxor %xmm1,%xmm15 + pand %xmm8,%xmm0 + pand %xmm8,%xmm15 + pxor %xmm0,%xmm2 + psllq $2,%xmm0 + pxor %xmm15,%xmm1 + psllq $2,%xmm15 + pxor %xmm9,%xmm0 + pxor %xmm10,%xmm15 + movdqa %xmm2,%xmm9 + psrlq $4,%xmm2 + movdqa %xmm1,%xmm10 + psrlq $4,%xmm1 + pxor %xmm6,%xmm2 + pxor %xmm5,%xmm1 + pand %xmm7,%xmm2 + pand %xmm7,%xmm1 + pxor %xmm2,%xmm6 + psllq $4,%xmm2 + pxor %xmm1,%xmm5 + psllq $4,%xmm1 + pxor %xmm9,%xmm2 + pxor %xmm10,%xmm1 + movdqa %xmm0,%xmm9 + psrlq $4,%xmm0 + movdqa %xmm15,%xmm10 + psrlq $4,%xmm15 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pand %xmm7,%xmm0 + pand %xmm7,%xmm15 + pxor %xmm0,%xmm4 + psllq $4,%xmm0 + pxor %xmm15,%xmm3 + psllq $4,%xmm15 + pxor %xmm9,%xmm0 + pxor %xmm10,%xmm15 + decl %r10d + jmp .Lenc_sbox +.align 16 +.Lenc_loop: + pxor 0(%rax),%xmm15 + pxor 16(%rax),%xmm0 + pxor 32(%rax),%xmm1 + pxor 48(%rax),%xmm2 +.byte 102,68,15,56,0,255 +.byte 102,15,56,0,199 + pxor 64(%rax),%xmm3 + pxor 80(%rax),%xmm4 +.byte 102,15,56,0,207 +.byte 102,15,56,0,215 + pxor 96(%rax),%xmm5 + pxor 112(%rax),%xmm6 +.byte 102,15,56,0,223 +.byte 102,15,56,0,231 +.byte 102,15,56,0,239 +.byte 102,15,56,0,247 + leaq 128(%rax),%rax +.Lenc_sbox: + pxor %xmm5,%xmm4 + pxor %xmm0,%xmm1 + pxor %xmm15,%xmm2 + pxor %xmm1,%xmm5 + pxor %xmm15,%xmm4 + + pxor %xmm2,%xmm5 + pxor %xmm6,%xmm2 + pxor %xmm4,%xmm6 + pxor %xmm3,%xmm2 + pxor %xmm4,%xmm3 + pxor %xmm0,%xmm2 + + pxor %xmm6,%xmm1 + pxor %xmm4,%xmm0 + movdqa %xmm6,%xmm10 + movdqa %xmm0,%xmm9 + movdqa %xmm4,%xmm8 + movdqa %xmm1,%xmm12 + movdqa %xmm5,%xmm11 + + pxor %xmm3,%xmm10 + pxor %xmm1,%xmm9 + pxor %xmm2,%xmm8 + movdqa %xmm10,%xmm13 + pxor %xmm3,%xmm12 + movdqa %xmm9,%xmm7 + pxor %xmm15,%xmm11 + movdqa %xmm10,%xmm14 + + por %xmm8,%xmm9 + por %xmm11,%xmm10 + pxor %xmm7,%xmm14 + pand %xmm11,%xmm13 + pxor %xmm8,%xmm11 + pand %xmm8,%xmm7 + pand %xmm11,%xmm14 + movdqa %xmm2,%xmm11 + pxor %xmm15,%xmm11 + pand %xmm11,%xmm12 + pxor %xmm12,%xmm10 + pxor %xmm12,%xmm9 + movdqa %xmm6,%xmm12 + movdqa %xmm4,%xmm11 + pxor %xmm0,%xmm12 + pxor %xmm5,%xmm11 + movdqa %xmm12,%xmm8 + pand %xmm11,%xmm12 + por %xmm11,%xmm8 + pxor %xmm12,%xmm7 + pxor %xmm14,%xmm10 + pxor %xmm13,%xmm9 + pxor %xmm14,%xmm8 + movdqa %xmm1,%xmm11 + pxor %xmm13,%xmm7 + movdqa %xmm3,%xmm12 + pxor %xmm13,%xmm8 + movdqa %xmm0,%xmm13 + pand %xmm2,%xmm11 + movdqa %xmm6,%xmm14 + pand %xmm15,%xmm12 + pand %xmm4,%xmm13 + por %xmm5,%xmm14 + pxor %xmm11,%xmm10 + pxor %xmm12,%xmm9 + pxor %xmm13,%xmm8 + pxor %xmm14,%xmm7 + + + + + + movdqa %xmm10,%xmm11 + pand %xmm8,%xmm10 + pxor %xmm9,%xmm11 + + movdqa %xmm7,%xmm13 + movdqa %xmm11,%xmm14 + pxor %xmm10,%xmm13 + pand %xmm13,%xmm14 + + movdqa %xmm8,%xmm12 + pxor %xmm9,%xmm14 + pxor %xmm7,%xmm12 + + pxor %xmm9,%xmm10 + + pand %xmm10,%xmm12 + + movdqa %xmm13,%xmm9 + pxor %xmm7,%xmm12 + + pxor %xmm12,%xmm9 + pxor %xmm12,%xmm8 + + pand %xmm7,%xmm9 + + pxor %xmm9,%xmm13 + pxor %xmm9,%xmm8 + + pand %xmm14,%xmm13 + + pxor %xmm11,%xmm13 + movdqa %xmm5,%xmm11 + movdqa %xmm4,%xmm7 + movdqa %xmm14,%xmm9 + pxor %xmm13,%xmm9 + pand %xmm5,%xmm9 + pxor %xmm4,%xmm5 + pand %xmm14,%xmm4 + pand %xmm13,%xmm5 + pxor %xmm4,%xmm5 + pxor %xmm9,%xmm4 + pxor %xmm15,%xmm11 + pxor %xmm2,%xmm7 + pxor %xmm12,%xmm14 + pxor %xmm8,%xmm13 + movdqa %xmm14,%xmm10 + movdqa %xmm12,%xmm9 + pxor %xmm13,%xmm10 + pxor %xmm8,%xmm9 + pand %xmm11,%xmm10 + pand %xmm15,%xmm9 + pxor %xmm7,%xmm11 + pxor %xmm2,%xmm15 + pand %xmm14,%xmm7 + pand %xmm12,%xmm2 + pand %xmm13,%xmm11 + pand %xmm8,%xmm15 + pxor %xmm11,%xmm7 + pxor %xmm2,%xmm15 + pxor %xmm10,%xmm11 + pxor %xmm9,%xmm2 + pxor %xmm11,%xmm5 + pxor %xmm11,%xmm15 + pxor %xmm7,%xmm4 + pxor %xmm7,%xmm2 + + movdqa %xmm6,%xmm11 + movdqa %xmm0,%xmm7 + pxor %xmm3,%xmm11 + pxor %xmm1,%xmm7 + movdqa %xmm14,%xmm10 + movdqa %xmm12,%xmm9 + pxor %xmm13,%xmm10 + pxor %xmm8,%xmm9 + pand %xmm11,%xmm10 + pand %xmm3,%xmm9 + pxor %xmm7,%xmm11 + pxor %xmm1,%xmm3 + pand %xmm14,%xmm7 + pand %xmm12,%xmm1 + pand %xmm13,%xmm11 + pand %xmm8,%xmm3 + pxor %xmm11,%xmm7 + pxor %xmm1,%xmm3 + pxor %xmm10,%xmm11 + pxor %xmm9,%xmm1 + pxor %xmm12,%xmm14 + pxor %xmm8,%xmm13 + movdqa %xmm14,%xmm10 + pxor %xmm13,%xmm10 + pand %xmm6,%xmm10 + pxor %xmm0,%xmm6 + pand %xmm14,%xmm0 + pand %xmm13,%xmm6 + pxor %xmm0,%xmm6 + pxor %xmm10,%xmm0 + pxor %xmm11,%xmm6 + pxor %xmm11,%xmm3 + pxor %xmm7,%xmm0 + pxor %xmm7,%xmm1 + pxor %xmm15,%xmm6 + pxor %xmm5,%xmm0 + pxor %xmm6,%xmm3 + pxor %xmm15,%xmm5 + pxor %xmm0,%xmm15 + + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm4 + pxor %xmm2,%xmm1 + pxor %xmm4,%xmm2 + pxor %xmm4,%xmm3 + + pxor %xmm2,%xmm5 + decl %r10d + jl .Lenc_done + pshufd $0x93,%xmm15,%xmm7 + pshufd $0x93,%xmm0,%xmm8 + pxor %xmm7,%xmm15 + pshufd $0x93,%xmm3,%xmm9 + pxor %xmm8,%xmm0 + pshufd $0x93,%xmm5,%xmm10 + pxor %xmm9,%xmm3 + pshufd $0x93,%xmm2,%xmm11 + pxor %xmm10,%xmm5 + pshufd $0x93,%xmm6,%xmm12 + pxor %xmm11,%xmm2 + pshufd $0x93,%xmm1,%xmm13 + pxor %xmm12,%xmm6 + pshufd $0x93,%xmm4,%xmm14 + pxor %xmm13,%xmm1 + pxor %xmm14,%xmm4 + + pxor %xmm15,%xmm8 + pxor %xmm4,%xmm7 + pxor %xmm4,%xmm8 + pshufd $0x4E,%xmm15,%xmm15 + pxor %xmm0,%xmm9 + pshufd $0x4E,%xmm0,%xmm0 + pxor %xmm2,%xmm12 + pxor %xmm7,%xmm15 + pxor %xmm6,%xmm13 + pxor %xmm8,%xmm0 + pxor %xmm5,%xmm11 + pshufd $0x4E,%xmm2,%xmm7 + pxor %xmm1,%xmm14 + pshufd $0x4E,%xmm6,%xmm8 + pxor %xmm3,%xmm10 + pshufd $0x4E,%xmm5,%xmm2 + pxor %xmm4,%xmm10 + pshufd $0x4E,%xmm4,%xmm6 + pxor %xmm4,%xmm11 + pshufd $0x4E,%xmm1,%xmm5 + pxor %xmm11,%xmm7 + pshufd $0x4E,%xmm3,%xmm1 + pxor %xmm12,%xmm8 + pxor %xmm10,%xmm2 + pxor %xmm14,%xmm6 + pxor %xmm13,%xmm5 + movdqa %xmm7,%xmm3 + pxor %xmm9,%xmm1 + movdqa %xmm8,%xmm4 + movdqa 48(%r11),%xmm7 + jnz .Lenc_loop + movdqa 64(%r11),%xmm7 + jmp .Lenc_loop +.align 16 +.Lenc_done: + movdqa 0(%r11),%xmm7 + movdqa 16(%r11),%xmm8 + movdqa %xmm1,%xmm9 + psrlq $1,%xmm1 + movdqa %xmm2,%xmm10 + psrlq $1,%xmm2 + pxor %xmm4,%xmm1 + pxor %xmm6,%xmm2 + pand %xmm7,%xmm1 + pand %xmm7,%xmm2 + pxor %xmm1,%xmm4 + psllq $1,%xmm1 + pxor %xmm2,%xmm6 + psllq $1,%xmm2 + pxor %xmm9,%xmm1 + pxor %xmm10,%xmm2 + movdqa %xmm3,%xmm9 + psrlq $1,%xmm3 + movdqa %xmm15,%xmm10 + psrlq $1,%xmm15 + pxor %xmm5,%xmm3 + pxor %xmm0,%xmm15 + pand %xmm7,%xmm3 + pand %xmm7,%xmm15 + pxor %xmm3,%xmm5 + psllq $1,%xmm3 + pxor %xmm15,%xmm0 + psllq $1,%xmm15 + pxor %xmm9,%xmm3 + pxor %xmm10,%xmm15 + movdqa 32(%r11),%xmm7 + movdqa %xmm6,%xmm9 + psrlq $2,%xmm6 + movdqa %xmm2,%xmm10 + psrlq $2,%xmm2 + pxor %xmm4,%xmm6 + pxor %xmm1,%xmm2 + pand %xmm8,%xmm6 + pand %xmm8,%xmm2 + pxor %xmm6,%xmm4 + psllq $2,%xmm6 + pxor %xmm2,%xmm1 + psllq $2,%xmm2 + pxor %xmm9,%xmm6 + pxor %xmm10,%xmm2 + movdqa %xmm0,%xmm9 + psrlq $2,%xmm0 + movdqa %xmm15,%xmm10 + psrlq $2,%xmm15 + pxor %xmm5,%xmm0 + pxor %xmm3,%xmm15 + pand %xmm8,%xmm0 + pand %xmm8,%xmm15 + pxor %xmm0,%xmm5 + psllq $2,%xmm0 + pxor %xmm15,%xmm3 + psllq $2,%xmm15 + pxor %xmm9,%xmm0 + pxor %xmm10,%xmm15 + movdqa %xmm5,%xmm9 + psrlq $4,%xmm5 + movdqa %xmm3,%xmm10 + psrlq $4,%xmm3 + pxor %xmm4,%xmm5 + pxor %xmm1,%xmm3 + pand %xmm7,%xmm5 + pand %xmm7,%xmm3 + pxor %xmm5,%xmm4 + psllq $4,%xmm5 + pxor %xmm3,%xmm1 + psllq $4,%xmm3 + pxor %xmm9,%xmm5 + pxor %xmm10,%xmm3 + movdqa %xmm0,%xmm9 + psrlq $4,%xmm0 + movdqa %xmm15,%xmm10 + psrlq $4,%xmm15 + pxor %xmm6,%xmm0 + pxor %xmm2,%xmm15 + pand %xmm7,%xmm0 + pand %xmm7,%xmm15 + pxor %xmm0,%xmm6 + psllq $4,%xmm0 + pxor %xmm15,%xmm2 + psllq $4,%xmm15 + pxor %xmm9,%xmm0 + pxor %xmm10,%xmm15 + movdqa (%rax),%xmm7 + pxor %xmm7,%xmm3 + pxor %xmm7,%xmm5 + pxor %xmm7,%xmm2 + pxor %xmm7,%xmm6 + pxor %xmm7,%xmm1 + pxor %xmm7,%xmm4 + pxor %xmm7,%xmm15 + pxor %xmm7,%xmm0 + .byte 0xf3,0xc3 +.cfi_endproc +.size _bsaes_encrypt8,.-_bsaes_encrypt8 + +.type _bsaes_decrypt8,@function +.align 64 +_bsaes_decrypt8: +.cfi_startproc + leaq .LBS0(%rip),%r11 + + movdqa (%rax),%xmm8 + leaq 16(%rax),%rax + movdqa -48(%r11),%xmm7 + pxor %xmm8,%xmm15 + pxor %xmm8,%xmm0 + pxor %xmm8,%xmm1 + pxor %xmm8,%xmm2 +.byte 102,68,15,56,0,255 +.byte 102,15,56,0,199 + pxor %xmm8,%xmm3 + pxor %xmm8,%xmm4 +.byte 102,15,56,0,207 +.byte 102,15,56,0,215 + pxor %xmm8,%xmm5 + pxor %xmm8,%xmm6 +.byte 102,15,56,0,223 +.byte 102,15,56,0,231 +.byte 102,15,56,0,239 +.byte 102,15,56,0,247 + movdqa 0(%r11),%xmm7 + movdqa 16(%r11),%xmm8 + movdqa %xmm5,%xmm9 + psrlq $1,%xmm5 + movdqa %xmm3,%xmm10 + psrlq $1,%xmm3 + pxor %xmm6,%xmm5 + pxor %xmm4,%xmm3 + pand %xmm7,%xmm5 + pand %xmm7,%xmm3 + pxor %xmm5,%xmm6 + psllq $1,%xmm5 + pxor %xmm3,%xmm4 + psllq $1,%xmm3 + pxor %xmm9,%xmm5 + pxor %xmm10,%xmm3 + movdqa %xmm1,%xmm9 + psrlq $1,%xmm1 + movdqa %xmm15,%xmm10 + psrlq $1,%xmm15 + pxor %xmm2,%xmm1 + pxor %xmm0,%xmm15 + pand %xmm7,%xmm1 + pand %xmm7,%xmm15 + pxor %xmm1,%xmm2 + psllq $1,%xmm1 + pxor %xmm15,%xmm0 + psllq $1,%xmm15 + pxor %xmm9,%xmm1 + pxor %xmm10,%xmm15 + movdqa 32(%r11),%xmm7 + movdqa %xmm4,%xmm9 + psrlq $2,%xmm4 + movdqa %xmm3,%xmm10 + psrlq $2,%xmm3 + pxor %xmm6,%xmm4 + pxor %xmm5,%xmm3 + pand %xmm8,%xmm4 + pand %xmm8,%xmm3 + pxor %xmm4,%xmm6 + psllq $2,%xmm4 + pxor %xmm3,%xmm5 + psllq $2,%xmm3 + pxor %xmm9,%xmm4 + pxor %xmm10,%xmm3 + movdqa %xmm0,%xmm9 + psrlq $2,%xmm0 + movdqa %xmm15,%xmm10 + psrlq $2,%xmm15 + pxor %xmm2,%xmm0 + pxor %xmm1,%xmm15 + pand %xmm8,%xmm0 + pand %xmm8,%xmm15 + pxor %xmm0,%xmm2 + psllq $2,%xmm0 + pxor %xmm15,%xmm1 + psllq $2,%xmm15 + pxor %xmm9,%xmm0 + pxor %xmm10,%xmm15 + movdqa %xmm2,%xmm9 + psrlq $4,%xmm2 + movdqa %xmm1,%xmm10 + psrlq $4,%xmm1 + pxor %xmm6,%xmm2 + pxor %xmm5,%xmm1 + pand %xmm7,%xmm2 + pand %xmm7,%xmm1 + pxor %xmm2,%xmm6 + psllq $4,%xmm2 + pxor %xmm1,%xmm5 + psllq $4,%xmm1 + pxor %xmm9,%xmm2 + pxor %xmm10,%xmm1 + movdqa %xmm0,%xmm9 + psrlq $4,%xmm0 + movdqa %xmm15,%xmm10 + psrlq $4,%xmm15 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm15 + pand %xmm7,%xmm0 + pand %xmm7,%xmm15 + pxor %xmm0,%xmm4 + psllq $4,%xmm0 + pxor %xmm15,%xmm3 + psllq $4,%xmm15 + pxor %xmm9,%xmm0 + pxor %xmm10,%xmm15 + decl %r10d + jmp .Ldec_sbox +.align 16 +.Ldec_loop: + pxor 0(%rax),%xmm15 + pxor 16(%rax),%xmm0 + pxor 32(%rax),%xmm1 + pxor 48(%rax),%xmm2 +.byte 102,68,15,56,0,255 +.byte 102,15,56,0,199 + pxor 64(%rax),%xmm3 + pxor 80(%rax),%xmm4 +.byte 102,15,56,0,207 +.byte 102,15,56,0,215 + pxor 96(%rax),%xmm5 + pxor 112(%rax),%xmm6 +.byte 102,15,56,0,223 +.byte 102,15,56,0,231 +.byte 102,15,56,0,239 +.byte 102,15,56,0,247 + leaq 128(%rax),%rax +.Ldec_sbox: + pxor %xmm3,%xmm2 + + pxor %xmm6,%xmm3 + pxor %xmm6,%xmm1 + pxor %xmm3,%xmm5 + pxor %xmm5,%xmm6 + pxor %xmm6,%xmm0 + + pxor %xmm0,%xmm15 + pxor %xmm4,%xmm1 + pxor %xmm15,%xmm2 + pxor %xmm15,%xmm4 + pxor %xmm2,%xmm0 + movdqa %xmm2,%xmm10 + movdqa %xmm6,%xmm9 + movdqa %xmm0,%xmm8 + movdqa %xmm3,%xmm12 + movdqa %xmm4,%xmm11 + + pxor %xmm15,%xmm10 + pxor %xmm3,%xmm9 + pxor %xmm5,%xmm8 + movdqa %xmm10,%xmm13 + pxor %xmm15,%xmm12 + movdqa %xmm9,%xmm7 + pxor %xmm1,%xmm11 + movdqa %xmm10,%xmm14 + + por %xmm8,%xmm9 + por %xmm11,%xmm10 + pxor %xmm7,%xmm14 + pand %xmm11,%xmm13 + pxor %xmm8,%xmm11 + pand %xmm8,%xmm7 + pand %xmm11,%xmm14 + movdqa %xmm5,%xmm11 + pxor %xmm1,%xmm11 + pand %xmm11,%xmm12 + pxor %xmm12,%xmm10 + pxor %xmm12,%xmm9 + movdqa %xmm2,%xmm12 + movdqa %xmm0,%xmm11 + pxor %xmm6,%xmm12 + pxor %xmm4,%xmm11 + movdqa %xmm12,%xmm8 + pand %xmm11,%xmm12 + por %xmm11,%xmm8 + pxor %xmm12,%xmm7 + pxor %xmm14,%xmm10 + pxor %xmm13,%xmm9 + pxor %xmm14,%xmm8 + movdqa %xmm3,%xmm11 + pxor %xmm13,%xmm7 + movdqa %xmm15,%xmm12 + pxor %xmm13,%xmm8 + movdqa %xmm6,%xmm13 + pand %xmm5,%xmm11 + movdqa %xmm2,%xmm14 + pand %xmm1,%xmm12 + pand %xmm0,%xmm13 + por %xmm4,%xmm14 + pxor %xmm11,%xmm10 + pxor %xmm12,%xmm9 + pxor %xmm13,%xmm8 + pxor %xmm14,%xmm7 + + + + + + movdqa %xmm10,%xmm11 + pand %xmm8,%xmm10 + pxor %xmm9,%xmm11 + + movdqa %xmm7,%xmm13 + movdqa %xmm11,%xmm14 + pxor %xmm10,%xmm13 + pand %xmm13,%xmm14 + + movdqa %xmm8,%xmm12 + pxor %xmm9,%xmm14 + pxor %xmm7,%xmm12 + + pxor %xmm9,%xmm10 + + pand %xmm10,%xmm12 + + movdqa %xmm13,%xmm9 + pxor %xmm7,%xmm12 + + pxor %xmm12,%xmm9 + pxor %xmm12,%xmm8 + + pand %xmm7,%xmm9 + + pxor %xmm9,%xmm13 + pxor %xmm9,%xmm8 + + pand %xmm14,%xmm13 + + pxor %xmm11,%xmm13 + movdqa %xmm4,%xmm11 + movdqa %xmm0,%xmm7 + movdqa %xmm14,%xmm9 + pxor %xmm13,%xmm9 + pand %xmm4,%xmm9 + pxor %xmm0,%xmm4 + pand %xmm14,%xmm0 + pand %xmm13,%xmm4 + pxor %xmm0,%xmm4 + pxor %xmm9,%xmm0 + pxor %xmm1,%xmm11 + pxor %xmm5,%xmm7 + pxor %xmm12,%xmm14 + pxor %xmm8,%xmm13 + movdqa %xmm14,%xmm10 + movdqa %xmm12,%xmm9 + pxor %xmm13,%xmm10 + pxor %xmm8,%xmm9 + pand %xmm11,%xmm10 + pand %xmm1,%xmm9 + pxor %xmm7,%xmm11 + pxor %xmm5,%xmm1 + pand %xmm14,%xmm7 + pand %xmm12,%xmm5 + pand %xmm13,%xmm11 + pand %xmm8,%xmm1 + pxor %xmm11,%xmm7 + pxor %xmm5,%xmm1 + pxor %xmm10,%xmm11 + pxor %xmm9,%xmm5 + pxor %xmm11,%xmm4 + pxor %xmm11,%xmm1 + pxor %xmm7,%xmm0 + pxor %xmm7,%xmm5 + + movdqa %xmm2,%xmm11 + movdqa %xmm6,%xmm7 + pxor %xmm15,%xmm11 + pxor %xmm3,%xmm7 + movdqa %xmm14,%xmm10 + movdqa %xmm12,%xmm9 + pxor %xmm13,%xmm10 + pxor %xmm8,%xmm9 + pand %xmm11,%xmm10 + pand %xmm15,%xmm9 + pxor %xmm7,%xmm11 + pxor %xmm3,%xmm15 + pand %xmm14,%xmm7 + pand %xmm12,%xmm3 + pand %xmm13,%xmm11 + pand %xmm8,%xmm15 + pxor %xmm11,%xmm7 + pxor %xmm3,%xmm15 + pxor %xmm10,%xmm11 + pxor %xmm9,%xmm3 + pxor %xmm12,%xmm14 + pxor %xmm8,%xmm13 + movdqa %xmm14,%xmm10 + pxor %xmm13,%xmm10 + pand %xmm2,%xmm10 + pxor %xmm6,%xmm2 + pand %xmm14,%xmm6 + pand %xmm13,%xmm2 + pxor %xmm6,%xmm2 + pxor %xmm10,%xmm6 + pxor %xmm11,%xmm2 + pxor %xmm11,%xmm15 + pxor %xmm7,%xmm6 + pxor %xmm7,%xmm3 + pxor %xmm6,%xmm0 + pxor %xmm4,%xmm5 + + pxor %xmm0,%xmm3 + pxor %xmm6,%xmm1 + pxor %xmm6,%xmm4 + pxor %xmm1,%xmm3 + pxor %xmm15,%xmm6 + pxor %xmm4,%xmm3 + pxor %xmm5,%xmm2 + pxor %xmm0,%xmm5 + pxor %xmm3,%xmm2 + + pxor %xmm15,%xmm3 + pxor %xmm2,%xmm6 + decl %r10d + jl .Ldec_done + + pshufd $0x4E,%xmm15,%xmm7 + pshufd $0x4E,%xmm2,%xmm13 + pxor %xmm15,%xmm7 + pshufd $0x4E,%xmm4,%xmm14 + pxor %xmm2,%xmm13 + pshufd $0x4E,%xmm0,%xmm8 + pxor %xmm4,%xmm14 + pshufd $0x4E,%xmm5,%xmm9 + pxor %xmm0,%xmm8 + pshufd $0x4E,%xmm3,%xmm10 + pxor %xmm5,%xmm9 + pxor %xmm13,%xmm15 + pxor %xmm13,%xmm0 + pshufd $0x4E,%xmm1,%xmm11 + pxor %xmm3,%xmm10 + pxor %xmm7,%xmm5 + pxor %xmm8,%xmm3 + pshufd $0x4E,%xmm6,%xmm12 + pxor %xmm1,%xmm11 + pxor %xmm14,%xmm0 + pxor %xmm9,%xmm1 + pxor %xmm6,%xmm12 + + pxor %xmm14,%xmm5 + pxor %xmm13,%xmm3 + pxor %xmm13,%xmm1 + pxor %xmm10,%xmm6 + pxor %xmm11,%xmm2 + pxor %xmm14,%xmm1 + pxor %xmm14,%xmm6 + pxor %xmm12,%xmm4 + pshufd $0x93,%xmm15,%xmm7 + pshufd $0x93,%xmm0,%xmm8 + pxor %xmm7,%xmm15 + pshufd $0x93,%xmm5,%xmm9 + pxor %xmm8,%xmm0 + pshufd $0x93,%xmm3,%xmm10 + pxor %xmm9,%xmm5 + pshufd $0x93,%xmm1,%xmm11 + pxor %xmm10,%xmm3 + pshufd $0x93,%xmm6,%xmm12 + pxor %xmm11,%xmm1 + pshufd $0x93,%xmm2,%xmm13 + pxor %xmm12,%xmm6 + pshufd $0x93,%xmm4,%xmm14 + pxor %xmm13,%xmm2 + pxor %xmm14,%xmm4 + + pxor %xmm15,%xmm8 + pxor %xmm4,%xmm7 + pxor %xmm4,%xmm8 + pshufd $0x4E,%xmm15,%xmm15 + pxor %xmm0,%xmm9 + pshufd $0x4E,%xmm0,%xmm0 + pxor %xmm1,%xmm12 + pxor %xmm7,%xmm15 + pxor %xmm6,%xmm13 + pxor %xmm8,%xmm0 + pxor %xmm3,%xmm11 + pshufd $0x4E,%xmm1,%xmm7 + pxor %xmm2,%xmm14 + pshufd $0x4E,%xmm6,%xmm8 + pxor %xmm5,%xmm10 + pshufd $0x4E,%xmm3,%xmm1 + pxor %xmm4,%xmm10 + pshufd $0x4E,%xmm4,%xmm6 + pxor %xmm4,%xmm11 + pshufd $0x4E,%xmm2,%xmm3 + pxor %xmm11,%xmm7 + pshufd $0x4E,%xmm5,%xmm2 + pxor %xmm12,%xmm8 + pxor %xmm1,%xmm10 + pxor %xmm14,%xmm6 + pxor %xmm3,%xmm13 + movdqa %xmm7,%xmm3 + pxor %xmm9,%xmm2 + movdqa %xmm13,%xmm5 + movdqa %xmm8,%xmm4 + movdqa %xmm2,%xmm1 + movdqa %xmm10,%xmm2 + movdqa -16(%r11),%xmm7 + jnz .Ldec_loop + movdqa -32(%r11),%xmm7 + jmp .Ldec_loop +.align 16 +.Ldec_done: + movdqa 0(%r11),%xmm7 + movdqa 16(%r11),%xmm8 + movdqa %xmm2,%xmm9 + psrlq $1,%xmm2 + movdqa %xmm1,%xmm10 + psrlq $1,%xmm1 + pxor %xmm4,%xmm2 + pxor %xmm6,%xmm1 + pand %xmm7,%xmm2 + pand %xmm7,%xmm1 + pxor %xmm2,%xmm4 + psllq $1,%xmm2 + pxor %xmm1,%xmm6 + psllq $1,%xmm1 + pxor %xmm9,%xmm2 + pxor %xmm10,%xmm1 + movdqa %xmm5,%xmm9 + psrlq $1,%xmm5 + movdqa %xmm15,%xmm10 + psrlq $1,%xmm15 + pxor %xmm3,%xmm5 + pxor %xmm0,%xmm15 + pand %xmm7,%xmm5 + pand %xmm7,%xmm15 + pxor %xmm5,%xmm3 + psllq $1,%xmm5 + pxor %xmm15,%xmm0 + psllq $1,%xmm15 + pxor %xmm9,%xmm5 + pxor %xmm10,%xmm15 + movdqa 32(%r11),%xmm7 + movdqa %xmm6,%xmm9 + psrlq $2,%xmm6 + movdqa %xmm1,%xmm10 + psrlq $2,%xmm1 + pxor %xmm4,%xmm6 + pxor %xmm2,%xmm1 + pand %xmm8,%xmm6 + pand %xmm8,%xmm1 + pxor %xmm6,%xmm4 + psllq $2,%xmm6 + pxor %xmm1,%xmm2 + psllq $2,%xmm1 + pxor %xmm9,%xmm6 + pxor %xmm10,%xmm1 + movdqa %xmm0,%xmm9 + psrlq $2,%xmm0 + movdqa %xmm15,%xmm10 + psrlq $2,%xmm15 + pxor %xmm3,%xmm0 + pxor %xmm5,%xmm15 + pand %xmm8,%xmm0 + pand %xmm8,%xmm15 + pxor %xmm0,%xmm3 + psllq $2,%xmm0 + pxor %xmm15,%xmm5 + psllq $2,%xmm15 + pxor %xmm9,%xmm0 + pxor %xmm10,%xmm15 + movdqa %xmm3,%xmm9 + psrlq $4,%xmm3 + movdqa %xmm5,%xmm10 + psrlq $4,%xmm5 + pxor %xmm4,%xmm3 + pxor %xmm2,%xmm5 + pand %xmm7,%xmm3 + pand %xmm7,%xmm5 + pxor %xmm3,%xmm4 + psllq $4,%xmm3 + pxor %xmm5,%xmm2 + psllq $4,%xmm5 + pxor %xmm9,%xmm3 + pxor %xmm10,%xmm5 + movdqa %xmm0,%xmm9 + psrlq $4,%xmm0 + movdqa %xmm15,%xmm10 + psrlq $4,%xmm15 + pxor %xmm6,%xmm0 + pxor %xmm1,%xmm15 + pand %xmm7,%xmm0 + pand %xmm7,%xmm15 + pxor %xmm0,%xmm6 + psllq $4,%xmm0 + pxor %xmm15,%xmm1 + psllq $4,%xmm15 + pxor %xmm9,%xmm0 + pxor %xmm10,%xmm15 + movdqa (%rax),%xmm7 + pxor %xmm7,%xmm5 + pxor %xmm7,%xmm3 + pxor %xmm7,%xmm1 + pxor %xmm7,%xmm6 + pxor %xmm7,%xmm2 + pxor %xmm7,%xmm4 + pxor %xmm7,%xmm15 + pxor %xmm7,%xmm0 + .byte 0xf3,0xc3 +.cfi_endproc +.size _bsaes_decrypt8,.-_bsaes_decrypt8 +.type _bsaes_key_convert,@function +.align 16 +_bsaes_key_convert: +.cfi_startproc + leaq .Lmasks(%rip),%r11 + movdqu (%rcx),%xmm7 + leaq 16(%rcx),%rcx + movdqa 0(%r11),%xmm0 + movdqa 16(%r11),%xmm1 + movdqa 32(%r11),%xmm2 + movdqa 48(%r11),%xmm3 + movdqa 64(%r11),%xmm4 + pcmpeqd %xmm5,%xmm5 + + movdqu (%rcx),%xmm6 + movdqa %xmm7,(%rax) + leaq 16(%rax),%rax + decl %r10d + jmp .Lkey_loop +.align 16 +.Lkey_loop: +.byte 102,15,56,0,244 + + movdqa %xmm0,%xmm8 + movdqa %xmm1,%xmm9 + + pand %xmm6,%xmm8 + pand %xmm6,%xmm9 + movdqa %xmm2,%xmm10 + pcmpeqb %xmm0,%xmm8 + psllq $4,%xmm0 + movdqa %xmm3,%xmm11 + pcmpeqb %xmm1,%xmm9 + psllq $4,%xmm1 + + pand %xmm6,%xmm10 + pand %xmm6,%xmm11 + movdqa %xmm0,%xmm12 + pcmpeqb %xmm2,%xmm10 + psllq $4,%xmm2 + movdqa %xmm1,%xmm13 + pcmpeqb %xmm3,%xmm11 + psllq $4,%xmm3 + + movdqa %xmm2,%xmm14 + movdqa %xmm3,%xmm15 + pxor %xmm5,%xmm8 + pxor %xmm5,%xmm9 + + pand %xmm6,%xmm12 + pand %xmm6,%xmm13 + movdqa %xmm8,0(%rax) + pcmpeqb %xmm0,%xmm12 + psrlq $4,%xmm0 + movdqa %xmm9,16(%rax) + pcmpeqb %xmm1,%xmm13 + psrlq $4,%xmm1 + leaq 16(%rcx),%rcx + + pand %xmm6,%xmm14 + pand %xmm6,%xmm15 + movdqa %xmm10,32(%rax) + pcmpeqb %xmm2,%xmm14 + psrlq $4,%xmm2 + movdqa %xmm11,48(%rax) + pcmpeqb %xmm3,%xmm15 + psrlq $4,%xmm3 + movdqu (%rcx),%xmm6 + + pxor %xmm5,%xmm13 + pxor %xmm5,%xmm14 + movdqa %xmm12,64(%rax) + movdqa %xmm13,80(%rax) + movdqa %xmm14,96(%rax) + movdqa %xmm15,112(%rax) + leaq 128(%rax),%rax + decl %r10d + jnz .Lkey_loop + + movdqa 80(%r11),%xmm7 + + .byte 0xf3,0xc3 +.cfi_endproc +.size _bsaes_key_convert,.-_bsaes_key_convert + +.globl ossl_bsaes_cbc_encrypt +.type ossl_bsaes_cbc_encrypt,@function +.align 16 +ossl_bsaes_cbc_encrypt: +.cfi_startproc +.byte 243,15,30,250 + cmpl $0,%r9d + jne asm_AES_cbc_encrypt + cmpq $128,%rdx + jb asm_AES_cbc_encrypt + + movq %rsp,%rax +.Lcbc_dec_prologue: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + leaq -72(%rsp),%rsp +.cfi_adjust_cfa_offset 0x48 + movq %rsp,%rbp +.cfi_def_cfa_register %rbp + movl 240(%rcx),%eax + movq %rdi,%r12 + movq %rsi,%r13 + movq %rdx,%r14 + movq %rcx,%r15 + movq %r8,%rbx + shrq $4,%r14 + + movl %eax,%edx + shlq $7,%rax + subq $96,%rax + subq %rax,%rsp + + movq %rsp,%rax + movq %r15,%rcx + movl %edx,%r10d + call _bsaes_key_convert + pxor (%rsp),%xmm7 + movdqa %xmm6,(%rax) + movdqa %xmm7,(%rsp) + + movdqu (%rbx),%xmm14 + subq $8,%r14 +.Lcbc_dec_loop: + movdqu 0(%r12),%xmm15 + movdqu 16(%r12),%xmm0 + movdqu 32(%r12),%xmm1 + movdqu 48(%r12),%xmm2 + movdqu 64(%r12),%xmm3 + movdqu 80(%r12),%xmm4 + movq %rsp,%rax + movdqu 96(%r12),%xmm5 + movl %edx,%r10d + movdqu 112(%r12),%xmm6 + movdqa %xmm14,32(%rbp) + + call _bsaes_decrypt8 + + pxor 32(%rbp),%xmm15 + movdqu 0(%r12),%xmm7 + movdqu 16(%r12),%xmm8 + pxor %xmm7,%xmm0 + movdqu 32(%r12),%xmm9 + pxor %xmm8,%xmm5 + movdqu 48(%r12),%xmm10 + pxor %xmm9,%xmm3 + movdqu 64(%r12),%xmm11 + pxor %xmm10,%xmm1 + movdqu 80(%r12),%xmm12 + pxor %xmm11,%xmm6 + movdqu 96(%r12),%xmm13 + pxor %xmm12,%xmm2 + movdqu 112(%r12),%xmm14 + pxor %xmm13,%xmm4 + movdqu %xmm15,0(%r13) + leaq 128(%r12),%r12 + movdqu %xmm0,16(%r13) + movdqu %xmm5,32(%r13) + movdqu %xmm3,48(%r13) + movdqu %xmm1,64(%r13) + movdqu %xmm6,80(%r13) + movdqu %xmm2,96(%r13) + movdqu %xmm4,112(%r13) + leaq 128(%r13),%r13 + subq $8,%r14 + jnc .Lcbc_dec_loop + + addq $8,%r14 + jz .Lcbc_dec_done + + movdqu 0(%r12),%xmm15 + movq %rsp,%rax + movl %edx,%r10d + cmpq $2,%r14 + jb .Lcbc_dec_one + movdqu 16(%r12),%xmm0 + je .Lcbc_dec_two + movdqu 32(%r12),%xmm1 + cmpq $4,%r14 + jb .Lcbc_dec_three + movdqu 48(%r12),%xmm2 + je .Lcbc_dec_four + movdqu 64(%r12),%xmm3 + cmpq $6,%r14 + jb .Lcbc_dec_five + movdqu 80(%r12),%xmm4 + je .Lcbc_dec_six + movdqu 96(%r12),%xmm5 + movdqa %xmm14,32(%rbp) + call _bsaes_decrypt8 + pxor 32(%rbp),%xmm15 + movdqu 0(%r12),%xmm7 + movdqu 16(%r12),%xmm8 + pxor %xmm7,%xmm0 + movdqu 32(%r12),%xmm9 + pxor %xmm8,%xmm5 + movdqu 48(%r12),%xmm10 + pxor %xmm9,%xmm3 + movdqu 64(%r12),%xmm11 + pxor %xmm10,%xmm1 + movdqu 80(%r12),%xmm12 + pxor %xmm11,%xmm6 + movdqu 96(%r12),%xmm14 + pxor %xmm12,%xmm2 + movdqu %xmm15,0(%r13) + movdqu %xmm0,16(%r13) + movdqu %xmm5,32(%r13) + movdqu %xmm3,48(%r13) + movdqu %xmm1,64(%r13) + movdqu %xmm6,80(%r13) + movdqu %xmm2,96(%r13) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_six: + movdqa %xmm14,32(%rbp) + call _bsaes_decrypt8 + pxor 32(%rbp),%xmm15 + movdqu 0(%r12),%xmm7 + movdqu 16(%r12),%xmm8 + pxor %xmm7,%xmm0 + movdqu 32(%r12),%xmm9 + pxor %xmm8,%xmm5 + movdqu 48(%r12),%xmm10 + pxor %xmm9,%xmm3 + movdqu 64(%r12),%xmm11 + pxor %xmm10,%xmm1 + movdqu 80(%r12),%xmm14 + pxor %xmm11,%xmm6 + movdqu %xmm15,0(%r13) + movdqu %xmm0,16(%r13) + movdqu %xmm5,32(%r13) + movdqu %xmm3,48(%r13) + movdqu %xmm1,64(%r13) + movdqu %xmm6,80(%r13) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_five: + movdqa %xmm14,32(%rbp) + call _bsaes_decrypt8 + pxor 32(%rbp),%xmm15 + movdqu 0(%r12),%xmm7 + movdqu 16(%r12),%xmm8 + pxor %xmm7,%xmm0 + movdqu 32(%r12),%xmm9 + pxor %xmm8,%xmm5 + movdqu 48(%r12),%xmm10 + pxor %xmm9,%xmm3 + movdqu 64(%r12),%xmm14 + pxor %xmm10,%xmm1 + movdqu %xmm15,0(%r13) + movdqu %xmm0,16(%r13) + movdqu %xmm5,32(%r13) + movdqu %xmm3,48(%r13) + movdqu %xmm1,64(%r13) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_four: + movdqa %xmm14,32(%rbp) + call _bsaes_decrypt8 + pxor 32(%rbp),%xmm15 + movdqu 0(%r12),%xmm7 + movdqu 16(%r12),%xmm8 + pxor %xmm7,%xmm0 + movdqu 32(%r12),%xmm9 + pxor %xmm8,%xmm5 + movdqu 48(%r12),%xmm14 + pxor %xmm9,%xmm3 + movdqu %xmm15,0(%r13) + movdqu %xmm0,16(%r13) + movdqu %xmm5,32(%r13) + movdqu %xmm3,48(%r13) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_three: + movdqa %xmm14,32(%rbp) + call _bsaes_decrypt8 + pxor 32(%rbp),%xmm15 + movdqu 0(%r12),%xmm7 + movdqu 16(%r12),%xmm8 + pxor %xmm7,%xmm0 + movdqu 32(%r12),%xmm14 + pxor %xmm8,%xmm5 + movdqu %xmm15,0(%r13) + movdqu %xmm0,16(%r13) + movdqu %xmm5,32(%r13) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_two: + movdqa %xmm14,32(%rbp) + call _bsaes_decrypt8 + pxor 32(%rbp),%xmm15 + movdqu 0(%r12),%xmm7 + movdqu 16(%r12),%xmm14 + pxor %xmm7,%xmm0 + movdqu %xmm15,0(%r13) + movdqu %xmm0,16(%r13) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_one: + leaq (%r12),%rdi + leaq 32(%rbp),%rsi + leaq (%r15),%rdx + call asm_AES_decrypt + pxor 32(%rbp),%xmm14 + movdqu %xmm14,(%r13) + movdqa %xmm15,%xmm14 + +.Lcbc_dec_done: + movdqu %xmm14,(%rbx) + leaq (%rsp),%rax + pxor %xmm0,%xmm0 +.Lcbc_dec_bzero: + movdqa %xmm0,0(%rax) + movdqa %xmm0,16(%rax) + leaq 32(%rax),%rax + cmpq %rax,%rbp + ja .Lcbc_dec_bzero + + leaq 120(%rbp),%rax +.cfi_def_cfa %rax,8 + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbx +.cfi_restore %rbx + movq -8(%rax),%rbp +.cfi_restore %rbp + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lcbc_dec_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ossl_bsaes_cbc_encrypt,.-ossl_bsaes_cbc_encrypt + +.globl ossl_bsaes_ctr32_encrypt_blocks +.type ossl_bsaes_ctr32_encrypt_blocks,@function +.align 16 +ossl_bsaes_ctr32_encrypt_blocks: +.cfi_startproc +.byte 243,15,30,250 + movq %rsp,%rax +.Lctr_enc_prologue: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + leaq -72(%rsp),%rsp +.cfi_adjust_cfa_offset 0x48 + movq %rsp,%rbp +.cfi_def_cfa_register %rbp + movdqu (%r8),%xmm0 + movl 240(%rcx),%eax + movq %rdi,%r12 + movq %rsi,%r13 + movq %rdx,%r14 + movq %rcx,%r15 + movdqa %xmm0,32(%rbp) + cmpq $8,%rdx + jb .Lctr_enc_short + + movl %eax,%ebx + shlq $7,%rax + subq $96,%rax + subq %rax,%rsp + + movq %rsp,%rax + movq %r15,%rcx + movl %ebx,%r10d + call _bsaes_key_convert + pxor %xmm6,%xmm7 + movdqa %xmm7,(%rax) + + movdqa (%rsp),%xmm8 + leaq .LADD1(%rip),%r11 + movdqa 32(%rbp),%xmm15 + movdqa -32(%r11),%xmm7 +.byte 102,68,15,56,0,199 +.byte 102,68,15,56,0,255 + movdqa %xmm8,(%rsp) + jmp .Lctr_enc_loop +.align 16 +.Lctr_enc_loop: + movdqa %xmm15,32(%rbp) + movdqa %xmm15,%xmm0 + movdqa %xmm15,%xmm1 + paddd 0(%r11),%xmm0 + movdqa %xmm15,%xmm2 + paddd 16(%r11),%xmm1 + movdqa %xmm15,%xmm3 + paddd 32(%r11),%xmm2 + movdqa %xmm15,%xmm4 + paddd 48(%r11),%xmm3 + movdqa %xmm15,%xmm5 + paddd 64(%r11),%xmm4 + movdqa %xmm15,%xmm6 + paddd 80(%r11),%xmm5 + paddd 96(%r11),%xmm6 + + + + movdqa (%rsp),%xmm8 + leaq 16(%rsp),%rax + movdqa -16(%r11),%xmm7 + pxor %xmm8,%xmm15 + pxor %xmm8,%xmm0 + pxor %xmm8,%xmm1 + pxor %xmm8,%xmm2 +.byte 102,68,15,56,0,255 +.byte 102,15,56,0,199 + pxor %xmm8,%xmm3 + pxor %xmm8,%xmm4 +.byte 102,15,56,0,207 +.byte 102,15,56,0,215 + pxor %xmm8,%xmm5 + pxor %xmm8,%xmm6 +.byte 102,15,56,0,223 +.byte 102,15,56,0,231 +.byte 102,15,56,0,239 +.byte 102,15,56,0,247 + leaq .LBS0(%rip),%r11 + movl %ebx,%r10d + + call _bsaes_encrypt8_bitslice + + subq $8,%r14 + jc .Lctr_enc_loop_done + + movdqu 0(%r12),%xmm7 + movdqu 16(%r12),%xmm8 + movdqu 32(%r12),%xmm9 + movdqu 48(%r12),%xmm10 + movdqu 64(%r12),%xmm11 + movdqu 80(%r12),%xmm12 + movdqu 96(%r12),%xmm13 + movdqu 112(%r12),%xmm14 + leaq 128(%r12),%r12 + pxor %xmm15,%xmm7 + movdqa 32(%rbp),%xmm15 + pxor %xmm8,%xmm0 + movdqu %xmm7,0(%r13) + pxor %xmm9,%xmm3 + movdqu %xmm0,16(%r13) + pxor %xmm10,%xmm5 + movdqu %xmm3,32(%r13) + pxor %xmm11,%xmm2 + movdqu %xmm5,48(%r13) + pxor %xmm12,%xmm6 + movdqu %xmm2,64(%r13) + pxor %xmm13,%xmm1 + movdqu %xmm6,80(%r13) + pxor %xmm14,%xmm4 + movdqu %xmm1,96(%r13) + leaq .LADD1(%rip),%r11 + movdqu %xmm4,112(%r13) + leaq 128(%r13),%r13 + paddd 112(%r11),%xmm15 + jnz .Lctr_enc_loop + + jmp .Lctr_enc_done +.align 16 +.Lctr_enc_loop_done: + addq $8,%r14 + movdqu 0(%r12),%xmm7 + pxor %xmm7,%xmm15 + movdqu %xmm15,0(%r13) + cmpq $2,%r14 + jb .Lctr_enc_done + movdqu 16(%r12),%xmm8 + pxor %xmm8,%xmm0 + movdqu %xmm0,16(%r13) + je .Lctr_enc_done + movdqu 32(%r12),%xmm9 + pxor %xmm9,%xmm3 + movdqu %xmm3,32(%r13) + cmpq $4,%r14 + jb .Lctr_enc_done + movdqu 48(%r12),%xmm10 + pxor %xmm10,%xmm5 + movdqu %xmm5,48(%r13) + je .Lctr_enc_done + movdqu 64(%r12),%xmm11 + pxor %xmm11,%xmm2 + movdqu %xmm2,64(%r13) + cmpq $6,%r14 + jb .Lctr_enc_done + movdqu 80(%r12),%xmm12 + pxor %xmm12,%xmm6 + movdqu %xmm6,80(%r13) + je .Lctr_enc_done + movdqu 96(%r12),%xmm13 + pxor %xmm13,%xmm1 + movdqu %xmm1,96(%r13) + jmp .Lctr_enc_done + +.align 16 +.Lctr_enc_short: + leaq 32(%rbp),%rdi + leaq 48(%rbp),%rsi + leaq (%r15),%rdx + call asm_AES_encrypt + movdqu (%r12),%xmm0 + leaq 16(%r12),%r12 + movl 44(%rbp),%eax + bswapl %eax + pxor 48(%rbp),%xmm0 + incl %eax + movdqu %xmm0,(%r13) + bswapl %eax + leaq 16(%r13),%r13 + movl %eax,44(%rsp) + decq %r14 + jnz .Lctr_enc_short + +.Lctr_enc_done: + leaq (%rsp),%rax + pxor %xmm0,%xmm0 +.Lctr_enc_bzero: + movdqa %xmm0,0(%rax) + movdqa %xmm0,16(%rax) + leaq 32(%rax),%rax + cmpq %rax,%rbp + ja .Lctr_enc_bzero + + leaq 120(%rbp),%rax +.cfi_def_cfa %rax,8 + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbx +.cfi_restore %rbx + movq -8(%rax),%rbp +.cfi_restore %rbp + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lctr_enc_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ossl_bsaes_ctr32_encrypt_blocks,.-ossl_bsaes_ctr32_encrypt_blocks +.globl ossl_bsaes_xts_encrypt +.type ossl_bsaes_xts_encrypt,@function +.align 16 +ossl_bsaes_xts_encrypt: +.cfi_startproc + movq %rsp,%rax +.Lxts_enc_prologue: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + leaq -72(%rsp),%rsp +.cfi_adjust_cfa_offset 0x48 + movq %rsp,%rbp +.cfi_def_cfa_register %rbp + movq %rdi,%r12 + movq %rsi,%r13 + movq %rdx,%r14 + movq %rcx,%r15 + + leaq (%r9),%rdi + leaq 32(%rbp),%rsi + leaq (%r8),%rdx + call asm_AES_encrypt + + movl 240(%r15),%eax + movq %r14,%rbx + + movl %eax,%edx + shlq $7,%rax + subq $96,%rax + subq %rax,%rsp + + movq %rsp,%rax + movq %r15,%rcx + movl %edx,%r10d + call _bsaes_key_convert + pxor %xmm6,%xmm7 + movdqa %xmm7,(%rax) + + andq $-16,%r14 + subq $0x80,%rsp + movdqa 32(%rbp),%xmm6 + + pxor %xmm14,%xmm14 + movdqa .Lxts_magic(%rip),%xmm12 + pcmpgtd %xmm6,%xmm14 + + subq $0x80,%r14 + jc .Lxts_enc_short + jmp .Lxts_enc_loop + +.align 16 +.Lxts_enc_loop: + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm15 + movdqa %xmm6,0(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm0 + movdqa %xmm6,16(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 0(%r12),%xmm7 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm1 + movdqa %xmm6,32(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 16(%r12),%xmm8 + pxor %xmm7,%xmm15 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm2 + movdqa %xmm6,48(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 32(%r12),%xmm9 + pxor %xmm8,%xmm0 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm3 + movdqa %xmm6,64(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 48(%r12),%xmm10 + pxor %xmm9,%xmm1 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm4 + movdqa %xmm6,80(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 64(%r12),%xmm11 + pxor %xmm10,%xmm2 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm5 + movdqa %xmm6,96(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 80(%r12),%xmm12 + pxor %xmm11,%xmm3 + movdqu 96(%r12),%xmm13 + pxor %xmm12,%xmm4 + movdqu 112(%r12),%xmm14 + leaq 128(%r12),%r12 + movdqa %xmm6,112(%rsp) + pxor %xmm13,%xmm5 + leaq 128(%rsp),%rax + pxor %xmm14,%xmm6 + movl %edx,%r10d + + call _bsaes_encrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm3 + movdqu %xmm0,16(%r13) + pxor 48(%rsp),%xmm5 + movdqu %xmm3,32(%r13) + pxor 64(%rsp),%xmm2 + movdqu %xmm5,48(%r13) + pxor 80(%rsp),%xmm6 + movdqu %xmm2,64(%r13) + pxor 96(%rsp),%xmm1 + movdqu %xmm6,80(%r13) + pxor 112(%rsp),%xmm4 + movdqu %xmm1,96(%r13) + movdqu %xmm4,112(%r13) + leaq 128(%r13),%r13 + + movdqa 112(%rsp),%xmm6 + pxor %xmm14,%xmm14 + movdqa .Lxts_magic(%rip),%xmm12 + pcmpgtd %xmm6,%xmm14 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + + subq $0x80,%r14 + jnc .Lxts_enc_loop + +.Lxts_enc_short: + addq $0x80,%r14 + jz .Lxts_enc_done + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm15 + movdqa %xmm6,0(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm0 + movdqa %xmm6,16(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 0(%r12),%xmm7 + cmpq $16,%r14 + je .Lxts_enc_1 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm1 + movdqa %xmm6,32(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 16(%r12),%xmm8 + cmpq $32,%r14 + je .Lxts_enc_2 + pxor %xmm7,%xmm15 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm2 + movdqa %xmm6,48(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 32(%r12),%xmm9 + cmpq $48,%r14 + je .Lxts_enc_3 + pxor %xmm8,%xmm0 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm3 + movdqa %xmm6,64(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 48(%r12),%xmm10 + cmpq $64,%r14 + je .Lxts_enc_4 + pxor %xmm9,%xmm1 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm4 + movdqa %xmm6,80(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 64(%r12),%xmm11 + cmpq $80,%r14 + je .Lxts_enc_5 + pxor %xmm10,%xmm2 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm5 + movdqa %xmm6,96(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 80(%r12),%xmm12 + cmpq $96,%r14 + je .Lxts_enc_6 + pxor %xmm11,%xmm3 + movdqu 96(%r12),%xmm13 + pxor %xmm12,%xmm4 + movdqa %xmm6,112(%rsp) + leaq 112(%r12),%r12 + pxor %xmm13,%xmm5 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_encrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm3 + movdqu %xmm0,16(%r13) + pxor 48(%rsp),%xmm5 + movdqu %xmm3,32(%r13) + pxor 64(%rsp),%xmm2 + movdqu %xmm5,48(%r13) + pxor 80(%rsp),%xmm6 + movdqu %xmm2,64(%r13) + pxor 96(%rsp),%xmm1 + movdqu %xmm6,80(%r13) + movdqu %xmm1,96(%r13) + leaq 112(%r13),%r13 + + movdqa 112(%rsp),%xmm6 + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_6: + pxor %xmm11,%xmm3 + leaq 96(%r12),%r12 + pxor %xmm12,%xmm4 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_encrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm3 + movdqu %xmm0,16(%r13) + pxor 48(%rsp),%xmm5 + movdqu %xmm3,32(%r13) + pxor 64(%rsp),%xmm2 + movdqu %xmm5,48(%r13) + pxor 80(%rsp),%xmm6 + movdqu %xmm2,64(%r13) + movdqu %xmm6,80(%r13) + leaq 96(%r13),%r13 + + movdqa 96(%rsp),%xmm6 + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_5: + pxor %xmm10,%xmm2 + leaq 80(%r12),%r12 + pxor %xmm11,%xmm3 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_encrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm3 + movdqu %xmm0,16(%r13) + pxor 48(%rsp),%xmm5 + movdqu %xmm3,32(%r13) + pxor 64(%rsp),%xmm2 + movdqu %xmm5,48(%r13) + movdqu %xmm2,64(%r13) + leaq 80(%r13),%r13 + + movdqa 80(%rsp),%xmm6 + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_4: + pxor %xmm9,%xmm1 + leaq 64(%r12),%r12 + pxor %xmm10,%xmm2 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_encrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm3 + movdqu %xmm0,16(%r13) + pxor 48(%rsp),%xmm5 + movdqu %xmm3,32(%r13) + movdqu %xmm5,48(%r13) + leaq 64(%r13),%r13 + + movdqa 64(%rsp),%xmm6 + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_3: + pxor %xmm8,%xmm0 + leaq 48(%r12),%r12 + pxor %xmm9,%xmm1 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_encrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm3 + movdqu %xmm0,16(%r13) + movdqu %xmm3,32(%r13) + leaq 48(%r13),%r13 + + movdqa 48(%rsp),%xmm6 + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_2: + pxor %xmm7,%xmm15 + leaq 32(%r12),%r12 + pxor %xmm8,%xmm0 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_encrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + movdqu %xmm0,16(%r13) + leaq 32(%r13),%r13 + + movdqa 32(%rsp),%xmm6 + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_1: + pxor %xmm15,%xmm7 + leaq 16(%r12),%r12 + movdqa %xmm7,32(%rbp) + leaq 32(%rbp),%rdi + leaq 32(%rbp),%rsi + leaq (%r15),%rdx + call asm_AES_encrypt + pxor 32(%rbp),%xmm15 + + + + + + movdqu %xmm15,0(%r13) + leaq 16(%r13),%r13 + + movdqa 16(%rsp),%xmm6 + +.Lxts_enc_done: + andl $15,%ebx + jz .Lxts_enc_ret + movq %r13,%rdx + +.Lxts_enc_steal: + movzbl (%r12),%eax + movzbl -16(%rdx),%ecx + leaq 1(%r12),%r12 + movb %al,-16(%rdx) + movb %cl,0(%rdx) + leaq 1(%rdx),%rdx + subl $1,%ebx + jnz .Lxts_enc_steal + + movdqu -16(%r13),%xmm15 + leaq 32(%rbp),%rdi + pxor %xmm6,%xmm15 + leaq 32(%rbp),%rsi + movdqa %xmm15,32(%rbp) + leaq (%r15),%rdx + call asm_AES_encrypt + pxor 32(%rbp),%xmm6 + movdqu %xmm6,-16(%r13) + +.Lxts_enc_ret: + leaq (%rsp),%rax + pxor %xmm0,%xmm0 +.Lxts_enc_bzero: + movdqa %xmm0,0(%rax) + movdqa %xmm0,16(%rax) + leaq 32(%rax),%rax + cmpq %rax,%rbp + ja .Lxts_enc_bzero + + leaq 120(%rbp),%rax +.cfi_def_cfa %rax,8 + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbx +.cfi_restore %rbx + movq -8(%rax),%rbp +.cfi_restore %rbp + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lxts_enc_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ossl_bsaes_xts_encrypt,.-ossl_bsaes_xts_encrypt + +.globl ossl_bsaes_xts_decrypt +.type ossl_bsaes_xts_decrypt,@function +.align 16 +ossl_bsaes_xts_decrypt: +.cfi_startproc + movq %rsp,%rax +.Lxts_dec_prologue: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + leaq -72(%rsp),%rsp +.cfi_adjust_cfa_offset 0x48 + movq %rsp,%rbp + movq %rdi,%r12 + movq %rsi,%r13 + movq %rdx,%r14 + movq %rcx,%r15 + + leaq (%r9),%rdi + leaq 32(%rbp),%rsi + leaq (%r8),%rdx + call asm_AES_encrypt + + movl 240(%r15),%eax + movq %r14,%rbx + + movl %eax,%edx + shlq $7,%rax + subq $96,%rax + subq %rax,%rsp + + movq %rsp,%rax + movq %r15,%rcx + movl %edx,%r10d + call _bsaes_key_convert + pxor (%rsp),%xmm7 + movdqa %xmm6,(%rax) + movdqa %xmm7,(%rsp) + + xorl %eax,%eax + andq $-16,%r14 + testl $15,%ebx + setnz %al + shlq $4,%rax + subq %rax,%r14 + + subq $0x80,%rsp + movdqa 32(%rbp),%xmm6 + + pxor %xmm14,%xmm14 + movdqa .Lxts_magic(%rip),%xmm12 + pcmpgtd %xmm6,%xmm14 + + subq $0x80,%r14 + jc .Lxts_dec_short + jmp .Lxts_dec_loop + +.align 16 +.Lxts_dec_loop: + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm15 + movdqa %xmm6,0(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm0 + movdqa %xmm6,16(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 0(%r12),%xmm7 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm1 + movdqa %xmm6,32(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 16(%r12),%xmm8 + pxor %xmm7,%xmm15 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm2 + movdqa %xmm6,48(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 32(%r12),%xmm9 + pxor %xmm8,%xmm0 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm3 + movdqa %xmm6,64(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 48(%r12),%xmm10 + pxor %xmm9,%xmm1 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm4 + movdqa %xmm6,80(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 64(%r12),%xmm11 + pxor %xmm10,%xmm2 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm5 + movdqa %xmm6,96(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 80(%r12),%xmm12 + pxor %xmm11,%xmm3 + movdqu 96(%r12),%xmm13 + pxor %xmm12,%xmm4 + movdqu 112(%r12),%xmm14 + leaq 128(%r12),%r12 + movdqa %xmm6,112(%rsp) + pxor %xmm13,%xmm5 + leaq 128(%rsp),%rax + pxor %xmm14,%xmm6 + movl %edx,%r10d + + call _bsaes_decrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm5 + movdqu %xmm0,16(%r13) + pxor 48(%rsp),%xmm3 + movdqu %xmm5,32(%r13) + pxor 64(%rsp),%xmm1 + movdqu %xmm3,48(%r13) + pxor 80(%rsp),%xmm6 + movdqu %xmm1,64(%r13) + pxor 96(%rsp),%xmm2 + movdqu %xmm6,80(%r13) + pxor 112(%rsp),%xmm4 + movdqu %xmm2,96(%r13) + movdqu %xmm4,112(%r13) + leaq 128(%r13),%r13 + + movdqa 112(%rsp),%xmm6 + pxor %xmm14,%xmm14 + movdqa .Lxts_magic(%rip),%xmm12 + pcmpgtd %xmm6,%xmm14 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + + subq $0x80,%r14 + jnc .Lxts_dec_loop + +.Lxts_dec_short: + addq $0x80,%r14 + jz .Lxts_dec_done + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm15 + movdqa %xmm6,0(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm0 + movdqa %xmm6,16(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 0(%r12),%xmm7 + cmpq $16,%r14 + je .Lxts_dec_1 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm1 + movdqa %xmm6,32(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 16(%r12),%xmm8 + cmpq $32,%r14 + je .Lxts_dec_2 + pxor %xmm7,%xmm15 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm2 + movdqa %xmm6,48(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 32(%r12),%xmm9 + cmpq $48,%r14 + je .Lxts_dec_3 + pxor %xmm8,%xmm0 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm3 + movdqa %xmm6,64(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 48(%r12),%xmm10 + cmpq $64,%r14 + je .Lxts_dec_4 + pxor %xmm9,%xmm1 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm4 + movdqa %xmm6,80(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 64(%r12),%xmm11 + cmpq $80,%r14 + je .Lxts_dec_5 + pxor %xmm10,%xmm2 + pshufd $0x13,%xmm14,%xmm13 + pxor %xmm14,%xmm14 + movdqa %xmm6,%xmm5 + movdqa %xmm6,96(%rsp) + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + pcmpgtd %xmm6,%xmm14 + pxor %xmm13,%xmm6 + movdqu 80(%r12),%xmm12 + cmpq $96,%r14 + je .Lxts_dec_6 + pxor %xmm11,%xmm3 + movdqu 96(%r12),%xmm13 + pxor %xmm12,%xmm4 + movdqa %xmm6,112(%rsp) + leaq 112(%r12),%r12 + pxor %xmm13,%xmm5 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_decrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm5 + movdqu %xmm0,16(%r13) + pxor 48(%rsp),%xmm3 + movdqu %xmm5,32(%r13) + pxor 64(%rsp),%xmm1 + movdqu %xmm3,48(%r13) + pxor 80(%rsp),%xmm6 + movdqu %xmm1,64(%r13) + pxor 96(%rsp),%xmm2 + movdqu %xmm6,80(%r13) + movdqu %xmm2,96(%r13) + leaq 112(%r13),%r13 + + movdqa 112(%rsp),%xmm6 + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_6: + pxor %xmm11,%xmm3 + leaq 96(%r12),%r12 + pxor %xmm12,%xmm4 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_decrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm5 + movdqu %xmm0,16(%r13) + pxor 48(%rsp),%xmm3 + movdqu %xmm5,32(%r13) + pxor 64(%rsp),%xmm1 + movdqu %xmm3,48(%r13) + pxor 80(%rsp),%xmm6 + movdqu %xmm1,64(%r13) + movdqu %xmm6,80(%r13) + leaq 96(%r13),%r13 + + movdqa 96(%rsp),%xmm6 + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_5: + pxor %xmm10,%xmm2 + leaq 80(%r12),%r12 + pxor %xmm11,%xmm3 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_decrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm5 + movdqu %xmm0,16(%r13) + pxor 48(%rsp),%xmm3 + movdqu %xmm5,32(%r13) + pxor 64(%rsp),%xmm1 + movdqu %xmm3,48(%r13) + movdqu %xmm1,64(%r13) + leaq 80(%r13),%r13 + + movdqa 80(%rsp),%xmm6 + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_4: + pxor %xmm9,%xmm1 + leaq 64(%r12),%r12 + pxor %xmm10,%xmm2 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_decrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm5 + movdqu %xmm0,16(%r13) + pxor 48(%rsp),%xmm3 + movdqu %xmm5,32(%r13) + movdqu %xmm3,48(%r13) + leaq 64(%r13),%r13 + + movdqa 64(%rsp),%xmm6 + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_3: + pxor %xmm8,%xmm0 + leaq 48(%r12),%r12 + pxor %xmm9,%xmm1 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_decrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + pxor 32(%rsp),%xmm5 + movdqu %xmm0,16(%r13) + movdqu %xmm5,32(%r13) + leaq 48(%r13),%r13 + + movdqa 48(%rsp),%xmm6 + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_2: + pxor %xmm7,%xmm15 + leaq 32(%r12),%r12 + pxor %xmm8,%xmm0 + leaq 128(%rsp),%rax + movl %edx,%r10d + + call _bsaes_decrypt8 + + pxor 0(%rsp),%xmm15 + pxor 16(%rsp),%xmm0 + movdqu %xmm15,0(%r13) + movdqu %xmm0,16(%r13) + leaq 32(%r13),%r13 + + movdqa 32(%rsp),%xmm6 + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_1: + pxor %xmm15,%xmm7 + leaq 16(%r12),%r12 + movdqa %xmm7,32(%rbp) + leaq 32(%rbp),%rdi + leaq 32(%rbp),%rsi + leaq (%r15),%rdx + call asm_AES_decrypt + pxor 32(%rbp),%xmm15 + + + + + + movdqu %xmm15,0(%r13) + leaq 16(%r13),%r13 + + movdqa 16(%rsp),%xmm6 + +.Lxts_dec_done: + andl $15,%ebx + jz .Lxts_dec_ret + + pxor %xmm14,%xmm14 + movdqa .Lxts_magic(%rip),%xmm12 + pcmpgtd %xmm6,%xmm14 + pshufd $0x13,%xmm14,%xmm13 + movdqa %xmm6,%xmm5 + paddq %xmm6,%xmm6 + pand %xmm12,%xmm13 + movdqu (%r12),%xmm15 + pxor %xmm13,%xmm6 + + leaq 32(%rbp),%rdi + pxor %xmm6,%xmm15 + leaq 32(%rbp),%rsi + movdqa %xmm15,32(%rbp) + leaq (%r15),%rdx + call asm_AES_decrypt + pxor 32(%rbp),%xmm6 + movq %r13,%rdx + movdqu %xmm6,(%r13) + +.Lxts_dec_steal: + movzbl 16(%r12),%eax + movzbl (%rdx),%ecx + leaq 1(%r12),%r12 + movb %al,(%rdx) + movb %cl,16(%rdx) + leaq 1(%rdx),%rdx + subl $1,%ebx + jnz .Lxts_dec_steal + + movdqu (%r13),%xmm15 + leaq 32(%rbp),%rdi + pxor %xmm5,%xmm15 + leaq 32(%rbp),%rsi + movdqa %xmm15,32(%rbp) + leaq (%r15),%rdx + call asm_AES_decrypt + pxor 32(%rbp),%xmm5 + movdqu %xmm5,(%r13) + +.Lxts_dec_ret: + leaq (%rsp),%rax + pxor %xmm0,%xmm0 +.Lxts_dec_bzero: + movdqa %xmm0,0(%rax) + movdqa %xmm0,16(%rax) + leaq 32(%rax),%rax + cmpq %rax,%rbp + ja .Lxts_dec_bzero + + leaq 120(%rbp),%rax +.cfi_def_cfa %rax,8 + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbx +.cfi_restore %rbx + movq -8(%rax),%rbp +.cfi_restore %rbp + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lxts_dec_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ossl_bsaes_xts_decrypt,.-ossl_bsaes_xts_decrypt +.type _bsaes_const,@object +.align 64 +_bsaes_const: +.LM0ISR: +.quad 0x0a0e0206070b0f03, 0x0004080c0d010509 +.LISRM0: +.quad 0x01040b0e0205080f, 0x0306090c00070a0d +.LISR: +.quad 0x0504070602010003, 0x0f0e0d0c080b0a09 +.LBS0: +.quad 0x5555555555555555, 0x5555555555555555 +.LBS1: +.quad 0x3333333333333333, 0x3333333333333333 +.LBS2: +.quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f +.LSR: +.quad 0x0504070600030201, 0x0f0e0d0c0a09080b +.LSRM0: +.quad 0x0304090e00050a0f, 0x01060b0c0207080d +.LM0SR: +.quad 0x0a0e02060f03070b, 0x0004080c05090d01 +.LSWPUP: +.quad 0x0706050403020100, 0x0c0d0e0f0b0a0908 +.LSWPUPM0SR: +.quad 0x0a0d02060c03070b, 0x0004080f05090e01 +.LADD1: +.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 +.byte 66,105,116,45,115,108,105,99,101,100,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,69,109,105,108,105,97,32,75,195,164,115,112,101,114,44,32,80,101,116,101,114,32,83,99,104,119,97,98,101,44,32,65,110,100,121,32,80,111,108,121,97,107,111,118,0 +.align 64 +.size _bsaes_const,.-_bsaes_const + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/aes/build.info b/crypto/openssl/crypto/aes/build.info index 0f04863640de..b250903fa6e2 100644 --- a/crypto/openssl/crypto/aes/build.info +++ b/crypto/openssl/crypto/aes/build.info @@ -1,64 +1,128 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - aes_misc.c aes_ecb.c aes_cfb.c aes_ofb.c \ - aes_ige.c aes_wrap.c {- $target{aes_asm_src} -} + +$AESASM=aes_core.c aes_cbc.c +IF[{- !$disabled{asm} -}] + $AESASM_x86=aes-586.S + $AESDEF_x86=AES_ASM + $AESASM_x86_sse2=vpaes-x86.S aesni-x86.S + $AESDEF_x86_sse2=VPAES_ASM OPENSSL_IA32_SSE2 + + $AESASM_x86_64=\ + 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 + $AESDEF_x86_64=AES_ASM VPAES_ASM BSAES_ASM + + $AESASM_ia64=aes_core.c aes_cbc.c aes-ia64.s + $AESDEF_ia64=AES_ASM + + $AESASM_sparcv9=\ + aes_core.c aes_cbc.c aes-sparcv9.S aest4-sparcv9.S aesfx-sparcv9.S + $AESDEF_sparcv9=AES_ASM + + $AESASM_mips32=aes_cbc.c aes-mips.S + $AESDEF_mips32=AES_ASM + $AESASM_mips64=$AESASM_mips32 + $AESDEF_mips64=$AESDEF_mips32 + + $AESASM_s390x=aes-s390x.S + # aes-390x.S implements AES_ctr32_encrypt and AES_xts_[en|de]crypt + $AESDEF_s390x=AES_ASM AES_CTR_ASM AES_XTS_ASM + + $AESASM_armv4=aes_cbc.c aes-armv4.S bsaes-armv7.S aesv8-armx.S + $AESDEF_armv4=AES_ASM BSAES_ASM + $AESASM_aarch64=aes_core.c aes_cbc.c aesv8-armx.S vpaes-armv8.S + $AESDEF_aarch64=VPAES_ASM + + $AESASM_parisc11=aes_core.c aes_cbc.c aes-parisc.s + $AESDEF_parisc11=AES_ASM + $AESASM_parisc20_64=$AESASM_parisc11 + $AESDEF_parisc20_64=$AESDEF_parisc11 + + $AESASM_ppc32=aes_core.c aes_cbc.c aes-ppc.s vpaes-ppc.s aesp8-ppc.s + $AESDEF_ppc32=AES_ASM VPAES_ASM + $AESASM_ppc64=$AESASM_ppc32 + $AESDEF_ppc64=$AESDEF_ppc32 + + $AESASM_c64xplus=aes-c64xplus.s aes_cbc.c + # aes-c64xplus.s implements AES_ctr32_encrypt + $AESDEF_c64xplus=AES_ASM AES_CTR_ASM + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$AESASM_{- $target{asm_arch} -}] + $AESASM=$AESASM_{- $target{asm_arch} -} + $AESDEF=$AESDEF_{- $target{asm_arch} -} + IF[{- !$disabled{sse2} -}] + $AESASM=$AESASM $AESASM_{- $target{asm_arch} -}_sse2 + $AESDEF=$AESDEF $AESDEF_{- $target{asm_arch} -}_sse2 + ENDIF + ENDIF +ENDIF + +$COMMON=aes_misc.c aes_ecb.c $AESASM +SOURCE[../../libcrypto]=$COMMON aes_cfb.c aes_ofb.c aes_wrap.c +IF[{- !$disabled{'deprecated-3.0'} -}] + SOURCE[../../libcrypto]=aes_ige.c +ENDIF +SOURCE[../../providers/libfips.a]=$COMMON + +# Implementations are now spread across several libraries, so the defines +# need to be applied to all affected libraries and modules. +DEFINE[../../libcrypto]=$AESDEF +DEFINE[../../providers/libfips.a]=$AESDEF +DEFINE[../../providers/libdefault.a]=$AESDEF +# We only need to include the AESDEF stuff in the legacy provider when it's a +# separate module and it's dynamically linked with libcrypto. Otherwise, it +# already gets everything that the static libcrypto.a has, and doesn't need it +# added again. +IF[{- !$disabled{module} && !$disabled{shared} -}] + DEFINE[../providers/liblegacy.a]=$AESDEF +ENDIF GENERATE[aes-ia64.s]=asm/aes-ia64.S -GENERATE[aes-586.s]=asm/aes-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[aes-586.s]=../perlasm/x86asm.pl -GENERATE[vpaes-x86.s]=asm/vpaes-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[vpaes-586.s]=../perlasm/x86asm.pl -GENERATE[aesni-x86.s]=asm/aesni-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[aesni-586.s]=../perlasm/x86asm.pl - -GENERATE[aes-x86_64.s]=asm/aes-x86_64.pl $(PERLASM_SCHEME) -GENERATE[vpaes-x86_64.s]=asm/vpaes-x86_64.pl $(PERLASM_SCHEME) -GENERATE[bsaes-x86_64.s]=asm/bsaes-x86_64.pl $(PERLASM_SCHEME) -GENERATE[aesni-x86_64.s]=asm/aesni-x86_64.pl $(PERLASM_SCHEME) -GENERATE[aesni-sha1-x86_64.s]=asm/aesni-sha1-x86_64.pl $(PERLASM_SCHEME) -GENERATE[aesni-sha256-x86_64.s]=asm/aesni-sha256-x86_64.pl $(PERLASM_SCHEME) -GENERATE[aesni-mb-x86_64.s]=asm/aesni-mb-x86_64.pl $(PERLASM_SCHEME) - -GENERATE[aes-sparcv9.S]=asm/aes-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[aes-586.S]=asm/aes-586.pl +DEPEND[aes-586.S]=../perlasm/x86asm.pl +GENERATE[vpaes-x86.S]=asm/vpaes-x86.pl +DEPEND[vpaes-586.S]=../perlasm/x86asm.pl +GENERATE[aesni-x86.S]=asm/aesni-x86.pl +DEPEND[aesni-586.S]=../perlasm/x86asm.pl + +GENERATE[aes-x86_64.s]=asm/aes-x86_64.pl +GENERATE[vpaes-x86_64.s]=asm/vpaes-x86_64.pl +GENERATE[bsaes-x86_64.s]=asm/bsaes-x86_64.pl +GENERATE[aesni-x86_64.s]=asm/aesni-x86_64.pl +GENERATE[aesni-sha1-x86_64.s]=asm/aesni-sha1-x86_64.pl +GENERATE[aesni-sha256-x86_64.s]=asm/aesni-sha256-x86_64.pl +GENERATE[aesni-mb-x86_64.s]=asm/aesni-mb-x86_64.pl + +GENERATE[aes-sparcv9.S]=asm/aes-sparcv9.pl INCLUDE[aes-sparcv9.o]=.. -GENERATE[aest4-sparcv9.S]=asm/aest4-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[aest4-sparcv9.S]=asm/aest4-sparcv9.pl INCLUDE[aest4-sparcv9.o]=.. DEPEND[aest4-sparcv9.S]=../perlasm/sparcv9_modes.pl -GENERATE[aesfx-sparcv9.S]=asm/aesfx-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[aesfx-sparcv9.S]=asm/aesfx-sparcv9.pl INCLUDE[aesfx-sparcv9.o]=.. -GENERATE[aes-ppc.s]=asm/aes-ppc.pl $(PERLASM_SCHEME) -GENERATE[vpaes-ppc.s]=asm/vpaes-ppc.pl $(PERLASM_SCHEME) -GENERATE[aesp8-ppc.s]=asm/aesp8-ppc.pl $(PERLASM_SCHEME) +GENERATE[aes-ppc.s]=asm/aes-ppc.pl +GENERATE[vpaes-ppc.s]=asm/vpaes-ppc.pl +GENERATE[aesp8-ppc.s]=asm/aesp8-ppc.pl -GENERATE[aes-parisc.s]=asm/aes-parisc.pl $(PERLASM_SCHEME) +GENERATE[aes-parisc.s]=asm/aes-parisc.pl -GENERATE[aes-mips.S]=asm/aes-mips.pl $(PERLASM_SCHEME) +GENERATE[aes-mips.S]=asm/aes-mips.pl INCLUDE[aes-mips.o]=.. -GENERATE[aesv8-armx.S]=asm/aesv8-armx.pl $(PERLASM_SCHEME) +GENERATE[aesv8-armx.S]=asm/aesv8-armx.pl INCLUDE[aesv8-armx.o]=.. -GENERATE[vpaes-armv8.S]=asm/vpaes-armv8.pl $(PERLASM_SCHEME) +GENERATE[vpaes-armv8.S]=asm/vpaes-armv8.pl -GENERATE[aes-armv4.S]=asm/aes-armv4.pl $(PERLASM_SCHEME) +GENERATE[aes-armv4.S]=asm/aes-armv4.pl INCLUDE[aes-armv4.o]=.. -GENERATE[bsaes-armv7.S]=asm/bsaes-armv7.pl $(PERLASM_SCHEME) +GENERATE[bsaes-armv7.S]=asm/bsaes-armv7.pl INCLUDE[bsaes-armv7.o]=.. -GENERATE[aes-s390x.S]=asm/aes-s390x.pl $(PERLASM_SCHEME) +GENERATE[aes-s390x.S]=asm/aes-s390x.pl INCLUDE[aes-s390x.o]=.. -BEGINRAW[Makefile] -##### AES assembler implementations - -# GNU make "catch all" -{- $builddir -}/aes-%.S: {- $sourcedir -}/asm/aes-%.pl - CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ -{- $builddir -}/bsaes-%.S: {- $sourcedir -}/asm/bsaes-%.pl - CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ - -ENDRAW[Makefile] +GENERATE[aes-c64xplus.S]=asm/aes-c64xplus.pl diff --git a/crypto/openssl/crypto/aes/vpaes-armv8.S b/crypto/openssl/crypto/aes/vpaes-armv8.S new file mode 100644 index 000000000000..4724cdfd27fc --- /dev/null +++ b/crypto/openssl/crypto/aes/vpaes-armv8.S @@ -0,0 +1,1196 @@ +.text + +.type _vpaes_consts,%object +.align 7 // totally strategic alignment +_vpaes_consts: +.Lk_mc_forward: // mc_forward +.quad 0x0407060500030201, 0x0C0F0E0D080B0A09 +.quad 0x080B0A0904070605, 0x000302010C0F0E0D +.quad 0x0C0F0E0D080B0A09, 0x0407060500030201 +.quad 0x000302010C0F0E0D, 0x080B0A0904070605 +.Lk_mc_backward: // mc_backward +.quad 0x0605040702010003, 0x0E0D0C0F0A09080B +.quad 0x020100030E0D0C0F, 0x0A09080B06050407 +.quad 0x0E0D0C0F0A09080B, 0x0605040702010003 +.quad 0x0A09080B06050407, 0x020100030E0D0C0F +.Lk_sr: // sr +.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908 +.quad 0x030E09040F0A0500, 0x0B06010C07020D08 +.quad 0x0F060D040B020900, 0x070E050C030A0108 +.quad 0x0B0E0104070A0D00, 0x0306090C0F020508 + +// +// "Hot" constants +// +.Lk_inv: // inv, inva +.quad 0x0E05060F0D080180, 0x040703090A0B0C02 +.quad 0x01040A060F0B0780, 0x030D0E0C02050809 +.Lk_ipt: // input transform (lo, hi) +.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808 +.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81 +.Lk_sbo: // sbou, sbot +.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878 +.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA +.Lk_sb1: // sb1u, sb1t +.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF +.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544 +.Lk_sb2: // sb2u, sb2t +.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A +.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD + +// +// Decryption stuff +// +.Lk_dipt: // decryption input transform +.quad 0x0F505B040B545F00, 0x154A411E114E451A +.quad 0x86E383E660056500, 0x12771772F491F194 +.Lk_dsbo: // decryption sbox final output +.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D +.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C +.Lk_dsb9: // decryption sbox output *9*u, *9*t +.quad 0x851C03539A86D600, 0xCAD51F504F994CC9 +.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565 +.Lk_dsbd: // decryption sbox output *D*u, *D*t +.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439 +.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3 +.Lk_dsbb: // decryption sbox output *B*u, *B*t +.quad 0xD022649296B44200, 0x602646F6B0F2D404 +.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B +.Lk_dsbe: // decryption sbox output *E*u, *E*t +.quad 0x46F2929626D4D000, 0x2242600464B4F6B0 +.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32 + +// +// Key schedule constants +// +.Lk_dksd: // decryption key schedule: invskew x*D +.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9 +.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E +.Lk_dksb: // decryption key schedule: invskew x*B +.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99 +.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8 +.Lk_dkse: // decryption key schedule: invskew x*E + 0x63 +.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086 +.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487 +.Lk_dks9: // decryption key schedule: invskew x*9 +.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC +.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE + +.Lk_rcon: // rcon +.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81 + +.Lk_opt: // output transform +.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808 +.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0 +.Lk_deskew: // deskew tables: inverts the sbox's "skew" +.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A +.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77 + +.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,65,82,77,118,56,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 +.align 2 +.size _vpaes_consts,.-_vpaes_consts +.align 6 +// +// _aes_preheat +// +// Fills register %r10 -> .aes_consts (so you can -fPIC) +// and %xmm9-%xmm15 as specified below. +// +.type _vpaes_encrypt_preheat,%function +.align 4 +_vpaes_encrypt_preheat: + adr x10, .Lk_inv + movi v17.16b, #0x0f + ld1 {v18.2d,v19.2d}, [x10],#32 // .Lk_inv + ld1 {v20.2d,v21.2d,v22.2d,v23.2d}, [x10],#64 // .Lk_ipt, .Lk_sbo + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x10] // .Lk_sb1, .Lk_sb2 + ret +.size _vpaes_encrypt_preheat,.-_vpaes_encrypt_preheat + +// +// _aes_encrypt_core +// +// AES-encrypt %xmm0. +// +// Inputs: +// %xmm0 = input +// %xmm9-%xmm15 as in _vpaes_preheat +// (%rdx) = scheduled keys +// +// Output in %xmm0 +// Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax +// Preserves %xmm6 - %xmm8 so you get some local vectors +// +// +.type _vpaes_encrypt_core,%function +.align 4 +_vpaes_encrypt_core: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + adr x11, .Lk_mc_forward+16 + // vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo + ld1 {v16.2d}, [x9], #16 // vmovdqu (%r9), %xmm5 # round0 key + and v1.16b, v7.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v7.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + tbl v1.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm1 + // vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi + tbl v2.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm3, %xmm2 + eor v0.16b, v1.16b, v16.16b // vpxor %xmm5, %xmm1, %xmm0 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + b .Lenc_entry + +.align 4 +.Lenc_loop: + // middle of middle round + add x10, x11, #0x40 + tbl v4.16b, {v25.16b}, v2.16b // vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u + ld1 {v1.2d}, [x11], #16 // vmovdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[] + tbl v0.16b, {v24.16b}, v3.16b // vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + tbl v5.16b, {v27.16b}, v2.16b // vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + tbl v2.16b, {v26.16b}, v3.16b // vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t + ld1 {v4.2d}, [x10] // vmovdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[] + tbl v3.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm3 # 0 = B + eor v2.16b, v2.16b, v5.16b // vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A + tbl v0.16b, {v0.16b}, v4.16b // vpshufb %xmm4, %xmm0, %xmm0 # 3 = D + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B + tbl v4.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C + eor v0.16b, v0.16b, v3.16b // vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D + and x11, x11, #~(1<<6) // and $0x30, %r11 # ... mod 4 + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D + sub w8, w8, #1 // nr-- + +.Lenc_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm0, %xmm9, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + tbl v5.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v3.16b, v3.16b, v5.16b // vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v4.16b, v4.16b, v5.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v3.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm5 + cbnz w8, .Lenc_loop + + // middle of last round + add x10, x11, #0x80 + // vmovdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo + // vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16 + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + ld1 {v1.2d}, [x10] // vmovdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[] + tbl v0.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + tbl v0.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm0 + ret +.size _vpaes_encrypt_core,.-_vpaes_encrypt_core + +.globl vpaes_encrypt +.type vpaes_encrypt,%function +.align 4 +vpaes_encrypt: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v7.16b}, [x0] + bl _vpaes_encrypt_preheat + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1] + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_encrypt,.-vpaes_encrypt + +.type _vpaes_encrypt_2x,%function +.align 4 +_vpaes_encrypt_2x: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + adr x11, .Lk_mc_forward+16 + // vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo + ld1 {v16.2d}, [x9], #16 // vmovdqu (%r9), %xmm5 # round0 key + and v1.16b, v14.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v14.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + and v9.16b, v15.16b, v17.16b + ushr v8.16b, v15.16b, #4 + tbl v1.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm1 + tbl v9.16b, {v20.16b}, v9.16b + // vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi + tbl v2.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm3, %xmm2 + tbl v10.16b, {v21.16b}, v8.16b + eor v0.16b, v1.16b, v16.16b // vpxor %xmm5, %xmm1, %xmm0 + eor v8.16b, v9.16b, v16.16b + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + eor v8.16b, v8.16b, v10.16b + b .Lenc_2x_entry + +.align 4 +.Lenc_2x_loop: + // middle of middle round + add x10, x11, #0x40 + tbl v4.16b, {v25.16b}, v2.16b // vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u + tbl v12.16b, {v25.16b}, v10.16b + ld1 {v1.2d}, [x11], #16 // vmovdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[] + tbl v0.16b, {v24.16b}, v3.16b // vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t + tbl v8.16b, {v24.16b}, v11.16b + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + tbl v5.16b, {v27.16b}, v2.16b // vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u + tbl v13.16b, {v27.16b}, v10.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + eor v8.16b, v8.16b, v12.16b + tbl v2.16b, {v26.16b}, v3.16b // vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t + tbl v10.16b, {v26.16b}, v11.16b + ld1 {v4.2d}, [x10] // vmovdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[] + tbl v3.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm3 # 0 = B + tbl v11.16b, {v8.16b}, v1.16b + eor v2.16b, v2.16b, v5.16b // vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A + eor v10.16b, v10.16b, v13.16b + tbl v0.16b, {v0.16b}, v4.16b // vpshufb %xmm4, %xmm0, %xmm0 # 3 = D + tbl v8.16b, {v8.16b}, v4.16b + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B + eor v11.16b, v11.16b, v10.16b + tbl v4.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C + tbl v12.16b, {v11.16b},v1.16b + eor v0.16b, v0.16b, v3.16b // vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D + eor v8.16b, v8.16b, v11.16b + and x11, x11, #~(1<<6) // and $0x30, %r11 # ... mod 4 + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D + eor v8.16b, v8.16b, v12.16b + sub w8, w8, #1 // nr-- + +.Lenc_2x_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm0, %xmm9, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + and v9.16b, v8.16b, v17.16b + ushr v8.16b, v8.16b, #4 + tbl v5.16b, {v19.16b},v1.16b // vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k + tbl v13.16b, {v19.16b},v9.16b + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + eor v9.16b, v9.16b, v8.16b + tbl v3.16b, {v18.16b},v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v11.16b, {v18.16b},v8.16b + tbl v4.16b, {v18.16b},v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + tbl v12.16b, {v18.16b},v9.16b + eor v3.16b, v3.16b, v5.16b // vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v11.16b, v11.16b, v13.16b + eor v4.16b, v4.16b, v5.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + eor v12.16b, v12.16b, v13.16b + tbl v2.16b, {v18.16b},v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v10.16b, {v18.16b},v11.16b + tbl v3.16b, {v18.16b},v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + tbl v11.16b, {v18.16b},v12.16b + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v10.16b, v10.16b, v9.16b + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + eor v11.16b, v11.16b, v8.16b + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm5 + cbnz w8, .Lenc_2x_loop + + // middle of last round + add x10, x11, #0x80 + // vmovdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo + // vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16 + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + tbl v12.16b, {v22.16b}, v10.16b + ld1 {v1.2d}, [x10] // vmovdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[] + tbl v0.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t + tbl v8.16b, {v23.16b}, v11.16b + eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A + eor v8.16b, v8.16b, v12.16b + tbl v0.16b, {v0.16b},v1.16b // vpshufb %xmm1, %xmm0, %xmm0 + tbl v1.16b, {v8.16b},v1.16b + ret +.size _vpaes_encrypt_2x,.-_vpaes_encrypt_2x + +.type _vpaes_decrypt_preheat,%function +.align 4 +_vpaes_decrypt_preheat: + adr x10, .Lk_inv + movi v17.16b, #0x0f + adr x11, .Lk_dipt + ld1 {v18.2d,v19.2d}, [x10],#32 // .Lk_inv + ld1 {v20.2d,v21.2d,v22.2d,v23.2d}, [x11],#64 // .Lk_dipt, .Lk_dsbo + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x11],#64 // .Lk_dsb9, .Lk_dsbd + ld1 {v28.2d,v29.2d,v30.2d,v31.2d}, [x11] // .Lk_dsbb, .Lk_dsbe + ret +.size _vpaes_decrypt_preheat,.-_vpaes_decrypt_preheat + +// +// Decryption core +// +// Same API as encryption core. +// +.type _vpaes_decrypt_core,%function +.align 4 +_vpaes_decrypt_core: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + + // vmovdqa .Lk_dipt(%rip), %xmm2 # iptlo + lsl x11, x8, #4 // mov %rax, %r11; shl $4, %r11 + eor x11, x11, #0x30 // xor $0x30, %r11 + adr x10, .Lk_sr + and x11, x11, #0x30 // and $0x30, %r11 + add x11, x11, x10 + adr x10, .Lk_mc_forward+48 + + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm4 # round0 key + and v1.16b, v7.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v7.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + tbl v2.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + ld1 {v5.2d}, [x10] // vmovdqa .Lk_mc_forward+48(%rip), %xmm5 + // vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi + tbl v0.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + eor v2.16b, v2.16b, v16.16b // vpxor %xmm4, %xmm2, %xmm2 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + b .Ldec_entry + +.align 4 +.Ldec_loop: +// +// Inverse mix columns +// + // vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u + // vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t + tbl v4.16b, {v24.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u + tbl v1.16b, {v25.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t + eor v0.16b, v4.16b, v16.16b // vpxor %xmm4, %xmm0, %xmm0 + // vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt + + tbl v4.16b, {v26.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v27.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + // vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt + + tbl v4.16b, {v28.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v29.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + // vmovdqa 0x40(%r10), %xmm4 # 4 : sbeu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x50(%r10), %xmm1 # 0 : sbet + + tbl v4.16b, {v30.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu + tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v1.16b, {v31.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + ext v5.16b, v5.16b, v5.16b, #12 // vpalignr $12, %xmm5, %xmm5, %xmm5 + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + sub w8, w8, #1 // sub $1,%rax # nr-- + +.Ldec_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + tbl v2.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v3.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm0 + cbnz w8, .Ldec_loop + + // middle of last round + // vmovdqa 0x60(%r10), %xmm4 # 3 : sbou + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + // vmovdqa 0x70(%r10), %xmm1 # 0 : sbot + ld1 {v2.2d}, [x11] // vmovdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160 + tbl v1.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t + eor v4.16b, v4.16b, v16.16b // vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k + eor v0.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm0 # 0 = A + tbl v0.16b, {v0.16b}, v2.16b // vpshufb %xmm2, %xmm0, %xmm0 + ret +.size _vpaes_decrypt_core,.-_vpaes_decrypt_core + +.globl vpaes_decrypt +.type vpaes_decrypt,%function +.align 4 +vpaes_decrypt: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v7.16b}, [x0] + bl _vpaes_decrypt_preheat + bl _vpaes_decrypt_core + st1 {v0.16b}, [x1] + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_decrypt,.-vpaes_decrypt + +// v14-v15 input, v0-v1 output +.type _vpaes_decrypt_2x,%function +.align 4 +_vpaes_decrypt_2x: + mov x9, x2 + ldr w8, [x2,#240] // pull rounds + + // vmovdqa .Lk_dipt(%rip), %xmm2 # iptlo + lsl x11, x8, #4 // mov %rax, %r11; shl $4, %r11 + eor x11, x11, #0x30 // xor $0x30, %r11 + adr x10, .Lk_sr + and x11, x11, #0x30 // and $0x30, %r11 + add x11, x11, x10 + adr x10, .Lk_mc_forward+48 + + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm4 # round0 key + and v1.16b, v14.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v14.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + and v9.16b, v15.16b, v17.16b + ushr v8.16b, v15.16b, #4 + tbl v2.16b, {v20.16b},v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + tbl v10.16b, {v20.16b},v9.16b + ld1 {v5.2d}, [x10] // vmovdqa .Lk_mc_forward+48(%rip), %xmm5 + // vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi + tbl v0.16b, {v21.16b},v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + tbl v8.16b, {v21.16b},v8.16b + eor v2.16b, v2.16b, v16.16b // vpxor %xmm4, %xmm2, %xmm2 + eor v10.16b, v10.16b, v16.16b + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + eor v8.16b, v8.16b, v10.16b + b .Ldec_2x_entry + +.align 4 +.Ldec_2x_loop: +// +// Inverse mix columns +// + // vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u + // vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t + tbl v4.16b, {v24.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u + tbl v12.16b, {v24.16b}, v10.16b + tbl v1.16b, {v25.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t + tbl v9.16b, {v25.16b}, v11.16b + eor v0.16b, v4.16b, v16.16b // vpxor %xmm4, %xmm0, %xmm0 + eor v8.16b, v12.16b, v16.16b + // vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + // vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt + + tbl v4.16b, {v26.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu + tbl v12.16b, {v26.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v27.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt + tbl v9.16b, {v27.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + // vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + // vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt + + tbl v4.16b, {v28.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu + tbl v12.16b, {v28.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v29.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt + tbl v9.16b, {v29.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + // vmovdqa 0x40(%r10), %xmm4 # 4 : sbeu + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + // vmovdqa 0x50(%r10), %xmm1 # 0 : sbet + + tbl v4.16b, {v30.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu + tbl v12.16b, {v30.16b}, v10.16b + tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch + tbl v8.16b, {v8.16b},v5.16b + tbl v1.16b, {v31.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet + tbl v9.16b, {v31.16b}, v11.16b + eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch + eor v8.16b, v8.16b, v12.16b + ext v5.16b, v5.16b, v5.16b, #12 // vpalignr $12, %xmm5, %xmm5, %xmm5 + eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch + eor v8.16b, v8.16b, v9.16b + sub w8, w8, #1 // sub $1,%rax # nr-- + +.Ldec_2x_entry: + // top of round + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + and v9.16b, v8.16b, v17.16b + ushr v8.16b, v8.16b, #4 + tbl v2.16b, {v19.16b},v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + tbl v10.16b, {v19.16b},v9.16b + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + eor v9.16b, v9.16b, v8.16b + tbl v3.16b, {v18.16b},v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + tbl v11.16b, {v18.16b},v8.16b + tbl v4.16b, {v18.16b},v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + tbl v12.16b, {v18.16b},v9.16b + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + eor v11.16b, v11.16b, v10.16b + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + eor v12.16b, v12.16b, v10.16b + tbl v2.16b, {v18.16b},v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak + tbl v10.16b, {v18.16b},v11.16b + tbl v3.16b, {v18.16b},v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak + tbl v11.16b, {v18.16b},v12.16b + eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io + eor v10.16b, v10.16b, v9.16b + eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo + eor v11.16b, v11.16b, v8.16b + ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm0 + cbnz w8, .Ldec_2x_loop + + // middle of last round + // vmovdqa 0x60(%r10), %xmm4 # 3 : sbou + tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou + tbl v12.16b, {v22.16b}, v10.16b + // vmovdqa 0x70(%r10), %xmm1 # 0 : sbot + tbl v1.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t + tbl v9.16b, {v23.16b}, v11.16b + ld1 {v2.2d}, [x11] // vmovdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160 + eor v4.16b, v4.16b, v16.16b // vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k + eor v12.16b, v12.16b, v16.16b + eor v0.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm0 # 0 = A + eor v8.16b, v9.16b, v12.16b + tbl v0.16b, {v0.16b},v2.16b // vpshufb %xmm2, %xmm0, %xmm0 + tbl v1.16b, {v8.16b},v2.16b + ret +.size _vpaes_decrypt_2x,.-_vpaes_decrypt_2x +//////////////////////////////////////////////////////// +// // +// AES key schedule // +// // +//////////////////////////////////////////////////////// +.type _vpaes_key_preheat,%function +.align 4 +_vpaes_key_preheat: + adr x10, .Lk_inv + movi v16.16b, #0x5b // .Lk_s63 + adr x11, .Lk_sb1 + movi v17.16b, #0x0f // .Lk_s0F + ld1 {v18.2d,v19.2d,v20.2d,v21.2d}, [x10] // .Lk_inv, .Lk_ipt + adr x10, .Lk_dksd + ld1 {v22.2d,v23.2d}, [x11] // .Lk_sb1 + adr x11, .Lk_mc_forward + ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x10],#64 // .Lk_dksd, .Lk_dksb + ld1 {v28.2d,v29.2d,v30.2d,v31.2d}, [x10],#64 // .Lk_dkse, .Lk_dks9 + ld1 {v8.2d}, [x10] // .Lk_rcon + ld1 {v9.2d}, [x11] // .Lk_mc_forward[0] + ret +.size _vpaes_key_preheat,.-_vpaes_key_preheat + +.type _vpaes_schedule_core,%function +.align 4 +_vpaes_schedule_core: +.inst 0xd503233f // paciasp + stp x29, x30, [sp,#-16]! + add x29,sp,#0 + + bl _vpaes_key_preheat // load the tables + + ld1 {v0.16b}, [x0],#16 // vmovdqu (%rdi), %xmm0 # load key (unaligned) + + // input transform + mov v3.16b, v0.16b // vmovdqa %xmm0, %xmm3 + bl _vpaes_schedule_transform + mov v7.16b, v0.16b // vmovdqa %xmm0, %xmm7 + + adr x10, .Lk_sr // lea .Lk_sr(%rip),%r10 + add x8, x8, x10 + cbnz w3, .Lschedule_am_decrypting + + // encrypting, output zeroth round key after transform + st1 {v0.2d}, [x2] // vmovdqu %xmm0, (%rdx) + b .Lschedule_go + +.Lschedule_am_decrypting: + // decrypting, output zeroth round key after shiftrows + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + tbl v3.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + st1 {v3.2d}, [x2] // vmovdqu %xmm3, (%rdx) + eor x8, x8, #0x30 // xor $0x30, %r8 + +.Lschedule_go: + cmp w1, #192 // cmp $192, %esi + b.hi .Lschedule_256 + b.eq .Lschedule_192 + // 128: fall though + +// +// .schedule_128 +// +// 128-bit specific part of key schedule. +// +// This schedule is really simple, because all its parts +// are accomplished by the subroutines. +// +.Lschedule_128: + mov x0, #10 // mov $10, %esi + +.Loop_schedule_128: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_round + cbz x0, .Lschedule_mangle_last + bl _vpaes_schedule_mangle // write output + b .Loop_schedule_128 + +// +// .aes_schedule_192 +// +// 192-bit specific part of key schedule. +// +// The main body of this schedule is the same as the 128-bit +// schedule, but with more smearing. The long, high side is +// stored in %xmm7 as before, and the short, low side is in +// the high bits of %xmm6. +// +// This schedule is somewhat nastier, however, because each +// round produces 192 bits of key material, or 1.5 round keys. +// Therefore, on each cycle we do 2 rounds and produce 3 round +// keys. +// +.align 4 +.Lschedule_192: + sub x0, x0, #8 + ld1 {v0.16b}, [x0] // vmovdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned) + bl _vpaes_schedule_transform // input transform + mov v6.16b, v0.16b // vmovdqa %xmm0, %xmm6 # save short part + eor v4.16b, v4.16b, v4.16b // vpxor %xmm4, %xmm4, %xmm4 # clear 4 + ins v6.d[0], v4.d[0] // vmovhlps %xmm4, %xmm6, %xmm6 # clobber low side with zeros + mov x0, #4 // mov $4, %esi + +.Loop_schedule_192: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_round + ext v0.16b, v6.16b, v0.16b, #8 // vpalignr $8,%xmm6,%xmm0,%xmm0 + bl _vpaes_schedule_mangle // save key n + bl _vpaes_schedule_192_smear + bl _vpaes_schedule_mangle // save key n+1 + bl _vpaes_schedule_round + cbz x0, .Lschedule_mangle_last + bl _vpaes_schedule_mangle // save key n+2 + bl _vpaes_schedule_192_smear + b .Loop_schedule_192 + +// +// .aes_schedule_256 +// +// 256-bit specific part of key schedule. +// +// The structure here is very similar to the 128-bit +// schedule, but with an additional "low side" in +// %xmm6. The low side's rounds are the same as the +// high side's, except no rcon and no rotation. +// +.align 4 +.Lschedule_256: + ld1 {v0.16b}, [x0] // vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned) + bl _vpaes_schedule_transform // input transform + mov x0, #7 // mov $7, %esi + +.Loop_schedule_256: + sub x0, x0, #1 // dec %esi + bl _vpaes_schedule_mangle // output low result + mov v6.16b, v0.16b // vmovdqa %xmm0, %xmm6 # save cur_lo in xmm6 + + // high round + bl _vpaes_schedule_round + cbz x0, .Lschedule_mangle_last + bl _vpaes_schedule_mangle + + // low round. swap xmm7 and xmm6 + dup v0.4s, v0.s[3] // vpshufd $0xFF, %xmm0, %xmm0 + movi v4.16b, #0 + mov v5.16b, v7.16b // vmovdqa %xmm7, %xmm5 + mov v7.16b, v6.16b // vmovdqa %xmm6, %xmm7 + bl _vpaes_schedule_low_round + mov v7.16b, v5.16b // vmovdqa %xmm5, %xmm7 + + b .Loop_schedule_256 + +// +// .aes_schedule_mangle_last +// +// Mangler for last round of key schedule +// Mangles %xmm0 +// when encrypting, outputs out(%xmm0) ^ 63 +// when decrypting, outputs unskew(%xmm0) +// +// Always called right before return... jumps to cleanup and exits +// +.align 4 +.Lschedule_mangle_last: + // schedule last round key from xmm0 + adr x11, .Lk_deskew // lea .Lk_deskew(%rip),%r11 # prepare to deskew + cbnz w3, .Lschedule_mangle_last_dec + + // encrypting + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10),%xmm1 + adr x11, .Lk_opt // lea .Lk_opt(%rip), %r11 # prepare to output transform + add x2, x2, #32 // add $32, %rdx + tbl v0.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm0 # output permute + +.Lschedule_mangle_last_dec: + ld1 {v20.2d,v21.2d}, [x11] // reload constants + sub x2, x2, #16 // add $-16, %rdx + eor v0.16b, v0.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm0, %xmm0 + bl _vpaes_schedule_transform // output transform + st1 {v0.2d}, [x2] // vmovdqu %xmm0, (%rdx) # save last key + + // cleanup + eor v0.16b, v0.16b, v0.16b // vpxor %xmm0, %xmm0, %xmm0 + eor v1.16b, v1.16b, v1.16b // vpxor %xmm1, %xmm1, %xmm1 + eor v2.16b, v2.16b, v2.16b // vpxor %xmm2, %xmm2, %xmm2 + eor v3.16b, v3.16b, v3.16b // vpxor %xmm3, %xmm3, %xmm3 + eor v4.16b, v4.16b, v4.16b // vpxor %xmm4, %xmm4, %xmm4 + eor v5.16b, v5.16b, v5.16b // vpxor %xmm5, %xmm5, %xmm5 + eor v6.16b, v6.16b, v6.16b // vpxor %xmm6, %xmm6, %xmm6 + eor v7.16b, v7.16b, v7.16b // vpxor %xmm7, %xmm7, %xmm7 + ldp x29, x30, [sp],#16 +.inst 0xd50323bf // autiasp + ret +.size _vpaes_schedule_core,.-_vpaes_schedule_core + +// +// .aes_schedule_192_smear +// +// Smear the short, low side in the 192-bit key schedule. +// +// Inputs: +// %xmm7: high side, b a x y +// %xmm6: low side, d c 0 0 +// %xmm13: 0 +// +// Outputs: +// %xmm6: b+c+d b+c 0 0 +// %xmm0: b+c+d b+c b a +// +.type _vpaes_schedule_192_smear,%function +.align 4 +_vpaes_schedule_192_smear: + movi v1.16b, #0 + dup v0.4s, v7.s[3] + ins v1.s[3], v6.s[2] // vpshufd $0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0 + ins v0.s[0], v7.s[2] // vpshufd $0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a + eor v6.16b, v6.16b, v1.16b // vpxor %xmm1, %xmm6, %xmm6 # -> c+d c 0 0 + eor v1.16b, v1.16b, v1.16b // vpxor %xmm1, %xmm1, %xmm1 + eor v6.16b, v6.16b, v0.16b // vpxor %xmm0, %xmm6, %xmm6 # -> b+c+d b+c b a + mov v0.16b, v6.16b // vmovdqa %xmm6, %xmm0 + ins v6.d[0], v1.d[0] // vmovhlps %xmm1, %xmm6, %xmm6 # clobber low side with zeros + ret +.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear + +// +// .aes_schedule_round +// +// Runs one main round of the key schedule on %xmm0, %xmm7 +// +// Specifically, runs subbytes on the high dword of %xmm0 +// then rotates it by one byte and xors into the low dword of +// %xmm7. +// +// Adds rcon from low byte of %xmm8, then rotates %xmm8 for +// next rcon. +// +// Smears the dwords of %xmm7 by xoring the low into the +// second low, result into third, result into highest. +// +// Returns results in %xmm7 = %xmm0. +// Clobbers %xmm1-%xmm4, %r11. +// +.type _vpaes_schedule_round,%function +.align 4 +_vpaes_schedule_round: + // extract rcon from xmm8 + movi v4.16b, #0 // vpxor %xmm4, %xmm4, %xmm4 + ext v1.16b, v8.16b, v4.16b, #15 // vpalignr $15, %xmm8, %xmm4, %xmm1 + ext v8.16b, v8.16b, v8.16b, #15 // vpalignr $15, %xmm8, %xmm8, %xmm8 + eor v7.16b, v7.16b, v1.16b // vpxor %xmm1, %xmm7, %xmm7 + + // rotate + dup v0.4s, v0.s[3] // vpshufd $0xFF, %xmm0, %xmm0 + ext v0.16b, v0.16b, v0.16b, #1 // vpalignr $1, %xmm0, %xmm0, %xmm0 + + // fall through... + + // low round: same as high round, but no rotation and no rcon. +_vpaes_schedule_low_round: + // smear xmm7 + ext v1.16b, v4.16b, v7.16b, #12 // vpslldq $4, %xmm7, %xmm1 + eor v7.16b, v7.16b, v1.16b // vpxor %xmm1, %xmm7, %xmm7 + ext v4.16b, v4.16b, v7.16b, #8 // vpslldq $8, %xmm7, %xmm4 + + // subbytes + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i + eor v7.16b, v7.16b, v4.16b // vpxor %xmm4, %xmm7, %xmm7 + tbl v2.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k + eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j + tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k + tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j + eor v7.16b, v7.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm7, %xmm7 + tbl v3.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm3 # 2 = 1/iak + eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k + tbl v2.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm2 # 3 = 1/jak + eor v3.16b, v3.16b, v1.16b // vpxor %xmm1, %xmm3, %xmm3 # 2 = io + eor v2.16b, v2.16b, v0.16b // vpxor %xmm0, %xmm2, %xmm2 # 3 = jo + tbl v4.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm13, %xmm4 # 4 = sbou + tbl v1.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm12, %xmm1 # 0 = sb1t + eor v1.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm1 # 0 = sbox output + + // add in smeared stuff + eor v0.16b, v1.16b, v7.16b // vpxor %xmm7, %xmm1, %xmm0 + eor v7.16b, v1.16b, v7.16b // vmovdqa %xmm0, %xmm7 + ret +.size _vpaes_schedule_round,.-_vpaes_schedule_round + +// +// .aes_schedule_transform +// +// Linear-transform %xmm0 according to tables at (%r11) +// +// Requires that %xmm9 = 0x0F0F... as in preheat +// Output in %xmm0 +// Clobbers %xmm1, %xmm2 +// +.type _vpaes_schedule_transform,%function +.align 4 +_vpaes_schedule_transform: + and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 + ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 + // vmovdqa (%r11), %xmm2 # lo + tbl v2.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm2 + // vmovdqa 16(%r11), %xmm1 # hi + tbl v0.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm1, %xmm0 + eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0 + ret +.size _vpaes_schedule_transform,.-_vpaes_schedule_transform + +// +// .aes_schedule_mangle +// +// Mangle xmm0 from (basis-transformed) standard version +// to our version. +// +// On encrypt, +// xor with 0x63 +// multiply by circulant 0,1,1,1 +// apply shiftrows transform +// +// On decrypt, +// xor with 0x63 +// multiply by "inverse mixcolumns" circulant E,B,D,9 +// deskew +// apply shiftrows transform +// +// +// Writes out to (%rdx), and increments or decrements it +// Keeps track of round number mod 4 in %r8 +// Preserves xmm0 +// Clobbers xmm1-xmm5 +// +.type _vpaes_schedule_mangle,%function +.align 4 +_vpaes_schedule_mangle: + mov v4.16b, v0.16b // vmovdqa %xmm0, %xmm4 # save xmm0 for later + // vmovdqa .Lk_mc_forward(%rip),%xmm5 + cbnz w3, .Lschedule_mangle_dec + + // encrypting + eor v4.16b, v0.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm0, %xmm4 + add x2, x2, #16 // add $16, %rdx + tbl v4.16b, {v4.16b}, v9.16b // vpshufb %xmm5, %xmm4, %xmm4 + tbl v1.16b, {v4.16b}, v9.16b // vpshufb %xmm5, %xmm4, %xmm1 + tbl v3.16b, {v1.16b}, v9.16b // vpshufb %xmm5, %xmm1, %xmm3 + eor v4.16b, v4.16b, v1.16b // vpxor %xmm1, %xmm4, %xmm4 + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + eor v3.16b, v3.16b, v4.16b // vpxor %xmm4, %xmm3, %xmm3 + + b .Lschedule_mangle_both +.align 4 +.Lschedule_mangle_dec: + // inverse mix columns + // lea .Lk_dksd(%rip),%r11 + ushr v1.16b, v4.16b, #4 // vpsrlb $4, %xmm4, %xmm1 # 1 = hi + and v4.16b, v4.16b, v17.16b // vpand %xmm9, %xmm4, %xmm4 # 4 = lo + + // vmovdqa 0x00(%r11), %xmm2 + tbl v2.16b, {v24.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + // vmovdqa 0x10(%r11), %xmm3 + tbl v3.16b, {v25.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + + // vmovdqa 0x20(%r11), %xmm2 + tbl v2.16b, {v26.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + // vmovdqa 0x30(%r11), %xmm3 + tbl v3.16b, {v27.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + + // vmovdqa 0x40(%r11), %xmm2 + tbl v2.16b, {v28.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + // vmovdqa 0x50(%r11), %xmm3 + tbl v3.16b, {v29.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 + + // vmovdqa 0x60(%r11), %xmm2 + tbl v2.16b, {v30.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2 + tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3 + // vmovdqa 0x70(%r11), %xmm4 + tbl v4.16b, {v31.16b}, v1.16b // vpshufb %xmm1, %xmm4, %xmm4 + ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1 + eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2 + eor v3.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm3 + + sub x2, x2, #16 // add $-16, %rdx + +.Lschedule_mangle_both: + tbl v3.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3 + add x8, x8, #64-16 // add $-16, %r8 + and x8, x8, #~(1<<6) // and $0x30, %r8 + st1 {v3.2d}, [x2] // vmovdqu %xmm3, (%rdx) + ret +.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle + +.globl vpaes_set_encrypt_key +.type vpaes_set_encrypt_key,%function +.align 4 +vpaes_set_encrypt_key: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + + lsr w9, w1, #5 // shr $5,%eax + add w9, w9, #5 // $5,%eax + str w9, [x2,#240] // mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + + mov w3, #0 // mov $0,%ecx + mov x8, #0x30 // mov $0x30,%r8d + bl _vpaes_schedule_core + eor x0, x0, x0 + + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key + +.globl vpaes_set_decrypt_key +.type vpaes_set_decrypt_key,%function +.align 4 +vpaes_set_decrypt_key: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + + lsr w9, w1, #5 // shr $5,%eax + add w9, w9, #5 // $5,%eax + str w9, [x2,#240] // mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + lsl w9, w9, #4 // shl $4,%eax + add x2, x2, #16 // lea 16(%rdx,%rax),%rdx + add x2, x2, x9 + + mov w3, #1 // mov $1,%ecx + lsr w8, w1, #1 // shr $1,%r8d + and x8, x8, #32 // and $32,%r8d + eor x8, x8, #32 // xor $32,%r8d # nbits==192?0:32 + bl _vpaes_schedule_core + + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key +.globl vpaes_cbc_encrypt +.type vpaes_cbc_encrypt,%function +.align 4 +vpaes_cbc_encrypt: + cbz x2, .Lcbc_abort + cmp w5, #0 // check direction + b.eq vpaes_cbc_decrypt + +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov x17, x2 // reassign + mov x2, x3 // reassign + + ld1 {v0.16b}, [x4] // load ivec + bl _vpaes_encrypt_preheat + b .Lcbc_enc_loop + +.align 4 +.Lcbc_enc_loop: + ld1 {v7.16b}, [x0],#16 // load input + eor v7.16b, v7.16b, v0.16b // xor with ivec + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1],#16 // save output + subs x17, x17, #16 + b.hi .Lcbc_enc_loop + + st1 {v0.16b}, [x4] // write ivec + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp +.Lcbc_abort: + ret +.size vpaes_cbc_encrypt,.-vpaes_cbc_encrypt + +.type vpaes_cbc_decrypt,%function +.align 4 +vpaes_cbc_decrypt: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + stp d10,d11,[sp,#-16]! + stp d12,d13,[sp,#-16]! + stp d14,d15,[sp,#-16]! + + mov x17, x2 // reassign + mov x2, x3 // reassign + ld1 {v6.16b}, [x4] // load ivec + bl _vpaes_decrypt_preheat + tst x17, #16 + b.eq .Lcbc_dec_loop2x + + ld1 {v7.16b}, [x0], #16 // load input + bl _vpaes_decrypt_core + eor v0.16b, v0.16b, v6.16b // xor with ivec + orr v6.16b, v7.16b, v7.16b // next ivec value + st1 {v0.16b}, [x1], #16 + subs x17, x17, #16 + b.ls .Lcbc_dec_done + +.align 4 +.Lcbc_dec_loop2x: + ld1 {v14.16b,v15.16b}, [x0], #32 + bl _vpaes_decrypt_2x + eor v0.16b, v0.16b, v6.16b // xor with ivec + eor v1.16b, v1.16b, v14.16b + orr v6.16b, v15.16b, v15.16b + st1 {v0.16b,v1.16b}, [x1], #32 + subs x17, x17, #32 + b.hi .Lcbc_dec_loop2x + +.Lcbc_dec_done: + st1 {v6.16b}, [x4] + + ldp d14,d15,[sp],#16 + ldp d12,d13,[sp],#16 + ldp d10,d11,[sp],#16 + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_cbc_decrypt,.-vpaes_cbc_decrypt +.globl vpaes_ecb_encrypt +.type vpaes_ecb_encrypt,%function +.align 4 +vpaes_ecb_encrypt: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + stp d10,d11,[sp,#-16]! + stp d12,d13,[sp,#-16]! + stp d14,d15,[sp,#-16]! + + mov x17, x2 + mov x2, x3 + bl _vpaes_encrypt_preheat + tst x17, #16 + b.eq .Lecb_enc_loop + + ld1 {v7.16b}, [x0],#16 + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1],#16 + subs x17, x17, #16 + b.ls .Lecb_enc_done + +.align 4 +.Lecb_enc_loop: + ld1 {v14.16b,v15.16b}, [x0], #32 + bl _vpaes_encrypt_2x + st1 {v0.16b,v1.16b}, [x1], #32 + subs x17, x17, #32 + b.hi .Lecb_enc_loop + +.Lecb_enc_done: + ldp d14,d15,[sp],#16 + ldp d12,d13,[sp],#16 + ldp d10,d11,[sp],#16 + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_ecb_encrypt,.-vpaes_ecb_encrypt + +.globl vpaes_ecb_decrypt +.type vpaes_ecb_decrypt,%function +.align 4 +vpaes_ecb_decrypt: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + stp d8,d9,[sp,#-16]! // ABI spec says so + stp d10,d11,[sp,#-16]! + stp d12,d13,[sp,#-16]! + stp d14,d15,[sp,#-16]! + + mov x17, x2 + mov x2, x3 + bl _vpaes_decrypt_preheat + tst x17, #16 + b.eq .Lecb_dec_loop + + ld1 {v7.16b}, [x0],#16 + bl _vpaes_encrypt_core + st1 {v0.16b}, [x1],#16 + subs x17, x17, #16 + b.ls .Lecb_dec_done + +.align 4 +.Lecb_dec_loop: + ld1 {v14.16b,v15.16b}, [x0], #32 + bl _vpaes_decrypt_2x + st1 {v0.16b,v1.16b}, [x1], #32 + subs x17, x17, #32 + b.hi .Lecb_dec_loop + +.Lecb_dec_done: + ldp d14,d15,[sp],#16 + ldp d12,d13,[sp],#16 + ldp d10,d11,[sp],#16 + ldp d8,d9,[sp],#16 + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size vpaes_ecb_decrypt,.-vpaes_ecb_decrypt diff --git a/crypto/openssl/crypto/aes/vpaes-x86.S b/crypto/openssl/crypto/aes/vpaes-x86.S new file mode 100644 index 000000000000..f3adb70545a6 --- /dev/null +++ b/crypto/openssl/crypto/aes/vpaes-x86.S @@ -0,0 +1,742 @@ +.text +.align 64 +.L_vpaes_consts: +.long 218628480,235210255,168496130,67568393 +.long 252381056,17041926,33884169,51187212 +.long 252645135,252645135,252645135,252645135 +.long 1512730624,3266504856,1377990664,3401244816 +.long 830229760,1275146365,2969422977,3447763452 +.long 3411033600,2979783055,338359620,2782886510 +.long 4209124096,907596821,221174255,1006095553 +.long 191964160,3799684038,3164090317,1589111125 +.long 182528256,1777043520,2877432650,3265356744 +.long 1874708224,3503451415,3305285752,363511674 +.long 1606117888,3487855781,1093350906,2384367825 +.long 197121,67569157,134941193,202313229 +.long 67569157,134941193,202313229,197121 +.long 134941193,202313229,197121,67569157 +.long 202313229,197121,67569157,134941193 +.long 33619971,100992007,168364043,235736079 +.long 235736079,33619971,100992007,168364043 +.long 168364043,235736079,33619971,100992007 +.long 100992007,168364043,235736079,33619971 +.long 50462976,117835012,185207048,252579084 +.long 252314880,51251460,117574920,184942860 +.long 184682752,252054788,50987272,118359308 +.long 118099200,185467140,251790600,50727180 +.long 2946363062,528716217,1300004225,1881839624 +.long 1532713819,1532713819,1532713819,1532713819 +.long 3602276352,4288629033,3737020424,4153884961 +.long 1354558464,32357713,2958822624,3775749553 +.long 1201988352,132424512,1572796698,503232858 +.long 2213177600,1597421020,4103937655,675398315 +.long 2749646592,4273543773,1511898873,121693092 +.long 3040248576,1103263732,2871565598,1608280554 +.long 2236667136,2588920351,482954393,64377734 +.long 3069987328,291237287,2117370568,3650299247 +.long 533321216,3573750986,2572112006,1401264716 +.long 1339849704,2721158661,548607111,3445553514 +.long 2128193280,3054596040,2183486460,1257083700 +.long 655635200,1165381986,3923443150,2344132524 +.long 190078720,256924420,290342170,357187870 +.long 1610966272,2263057382,4103205268,309794674 +.long 2592527872,2233205587,1335446729,3402964816 +.long 3973531904,3225098121,3002836325,1918774430 +.long 3870401024,2102906079,2284471353,4117666579 +.long 617007872,1021508343,366931923,691083277 +.long 2528395776,3491914898,2968704004,1613121270 +.long 3445188352,3247741094,844474987,4093578302 +.long 651481088,1190302358,1689581232,574775300 +.long 4289380608,206939853,2555985458,2489840491 +.long 2130264064,327674451,3566485037,3349835193 +.long 2470714624,316102159,3636825756,3393945945 +.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105 +.byte 111,110,32,65,69,83,32,102,111,114,32,120,56,54,47,83 +.byte 83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117 +.byte 114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105 +.byte 118,101,114,115,105,116,121,41,0 +.align 64 +.type _vpaes_preheat,@function +.align 16 +_vpaes_preheat: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + addl (%esp),%ebp + movdqa -48(%ebp),%xmm7 + movdqa -16(%ebp),%xmm6 + ret +.size _vpaes_preheat,.-_vpaes_preheat +.type _vpaes_encrypt_core,@function +.align 16 +_vpaes_encrypt_core: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl $16,%ecx + movl 240(%edx),%eax + movdqa %xmm6,%xmm1 + movdqa (%ebp),%xmm2 + pandn %xmm0,%xmm1 + pand %xmm6,%xmm0 + movdqu (%edx),%xmm5 +.byte 102,15,56,0,208 + movdqa 16(%ebp),%xmm0 + pxor %xmm5,%xmm2 + psrld $4,%xmm1 + addl $16,%edx +.byte 102,15,56,0,193 + leal 192(%ebp),%ebx + pxor %xmm2,%xmm0 + jmp .L000enc_entry +.align 16 +.L001enc_loop: + movdqa 32(%ebp),%xmm4 + movdqa 48(%ebp),%xmm0 +.byte 102,15,56,0,226 +.byte 102,15,56,0,195 + pxor %xmm5,%xmm4 + movdqa 64(%ebp),%xmm5 + pxor %xmm4,%xmm0 + movdqa -64(%ebx,%ecx,1),%xmm1 +.byte 102,15,56,0,234 + movdqa 80(%ebp),%xmm2 + movdqa (%ebx,%ecx,1),%xmm4 +.byte 102,15,56,0,211 + movdqa %xmm0,%xmm3 + pxor %xmm5,%xmm2 +.byte 102,15,56,0,193 + addl $16,%edx + pxor %xmm2,%xmm0 +.byte 102,15,56,0,220 + addl $16,%ecx + pxor %xmm0,%xmm3 +.byte 102,15,56,0,193 + andl $48,%ecx + subl $1,%eax + pxor %xmm3,%xmm0 +.L000enc_entry: + movdqa %xmm6,%xmm1 + movdqa -32(%ebp),%xmm5 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm6,%xmm0 +.byte 102,15,56,0,232 + movdqa %xmm7,%xmm3 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,217 + movdqa %xmm7,%xmm4 + pxor %xmm5,%xmm3 +.byte 102,15,56,0,224 + movdqa %xmm7,%xmm2 + pxor %xmm5,%xmm4 +.byte 102,15,56,0,211 + movdqa %xmm7,%xmm3 + pxor %xmm0,%xmm2 +.byte 102,15,56,0,220 + movdqu (%edx),%xmm5 + pxor %xmm1,%xmm3 + jnz .L001enc_loop + movdqa 96(%ebp),%xmm4 + movdqa 112(%ebp),%xmm0 +.byte 102,15,56,0,226 + pxor %xmm5,%xmm4 +.byte 102,15,56,0,195 + movdqa 64(%ebx,%ecx,1),%xmm1 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,193 + ret +.size _vpaes_encrypt_core,.-_vpaes_encrypt_core +.type _vpaes_decrypt_core,@function +.align 16 +_vpaes_decrypt_core: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + leal 608(%ebp),%ebx + movl 240(%edx),%eax + movdqa %xmm6,%xmm1 + movdqa -64(%ebx),%xmm2 + pandn %xmm0,%xmm1 + movl %eax,%ecx + psrld $4,%xmm1 + movdqu (%edx),%xmm5 + shll $4,%ecx + pand %xmm6,%xmm0 +.byte 102,15,56,0,208 + movdqa -48(%ebx),%xmm0 + xorl $48,%ecx +.byte 102,15,56,0,193 + andl $48,%ecx + pxor %xmm5,%xmm2 + movdqa 176(%ebp),%xmm5 + pxor %xmm2,%xmm0 + addl $16,%edx + leal -352(%ebx,%ecx,1),%ecx + jmp .L002dec_entry +.align 16 +.L003dec_loop: + movdqa -32(%ebx),%xmm4 + movdqa -16(%ebx),%xmm1 +.byte 102,15,56,0,226 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa (%ebx),%xmm4 + pxor %xmm1,%xmm0 + movdqa 16(%ebx),%xmm1 +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 32(%ebx),%xmm4 + pxor %xmm1,%xmm0 + movdqa 48(%ebx),%xmm1 +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 64(%ebx),%xmm4 + pxor %xmm1,%xmm0 + movdqa 80(%ebx),%xmm1 +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + addl $16,%edx +.byte 102,15,58,15,237,12 + pxor %xmm1,%xmm0 + subl $1,%eax +.L002dec_entry: + movdqa %xmm6,%xmm1 + movdqa -32(%ebp),%xmm2 + pandn %xmm0,%xmm1 + pand %xmm6,%xmm0 + psrld $4,%xmm1 +.byte 102,15,56,0,208 + movdqa %xmm7,%xmm3 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,217 + movdqa %xmm7,%xmm4 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,224 + pxor %xmm2,%xmm4 + movdqa %xmm7,%xmm2 +.byte 102,15,56,0,211 + movdqa %xmm7,%xmm3 + pxor %xmm0,%xmm2 +.byte 102,15,56,0,220 + movdqu (%edx),%xmm0 + pxor %xmm1,%xmm3 + jnz .L003dec_loop + movdqa 96(%ebx),%xmm4 +.byte 102,15,56,0,226 + pxor %xmm0,%xmm4 + movdqa 112(%ebx),%xmm0 + movdqa (%ecx),%xmm2 +.byte 102,15,56,0,195 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,194 + ret +.size _vpaes_decrypt_core,.-_vpaes_decrypt_core +.type _vpaes_schedule_core,@function +.align 16 +_vpaes_schedule_core: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + addl (%esp),%ebp + movdqu (%esi),%xmm0 + movdqa 320(%ebp),%xmm2 + movdqa %xmm0,%xmm3 + leal (%ebp),%ebx + movdqa %xmm2,4(%esp) + call _vpaes_schedule_transform + movdqa %xmm0,%xmm7 + testl %edi,%edi + jnz .L004schedule_am_decrypting + movdqu %xmm0,(%edx) + jmp .L005schedule_go +.L004schedule_am_decrypting: + movdqa 256(%ebp,%ecx,1),%xmm1 +.byte 102,15,56,0,217 + movdqu %xmm3,(%edx) + xorl $48,%ecx +.L005schedule_go: + cmpl $192,%eax + ja .L006schedule_256 + je .L007schedule_192 +.L008schedule_128: + movl $10,%eax +.L009loop_schedule_128: + call _vpaes_schedule_round + decl %eax + jz .L010schedule_mangle_last + call _vpaes_schedule_mangle + jmp .L009loop_schedule_128 +.align 16 +.L007schedule_192: + movdqu 8(%esi),%xmm0 + call _vpaes_schedule_transform + movdqa %xmm0,%xmm6 + pxor %xmm4,%xmm4 + movhlps %xmm4,%xmm6 + movl $4,%eax +.L011loop_schedule_192: + call _vpaes_schedule_round +.byte 102,15,58,15,198,8 + call _vpaes_schedule_mangle + call _vpaes_schedule_192_smear + call _vpaes_schedule_mangle + call _vpaes_schedule_round + decl %eax + jz .L010schedule_mangle_last + call _vpaes_schedule_mangle + call _vpaes_schedule_192_smear + jmp .L011loop_schedule_192 +.align 16 +.L006schedule_256: + movdqu 16(%esi),%xmm0 + call _vpaes_schedule_transform + movl $7,%eax +.L012loop_schedule_256: + call _vpaes_schedule_mangle + movdqa %xmm0,%xmm6 + call _vpaes_schedule_round + decl %eax + jz .L010schedule_mangle_last + call _vpaes_schedule_mangle + pshufd $255,%xmm0,%xmm0 + movdqa %xmm7,20(%esp) + movdqa %xmm6,%xmm7 + call .L_vpaes_schedule_low_round + movdqa 20(%esp),%xmm7 + jmp .L012loop_schedule_256 +.align 16 +.L010schedule_mangle_last: + leal 384(%ebp),%ebx + testl %edi,%edi + jnz .L013schedule_mangle_last_dec + movdqa 256(%ebp,%ecx,1),%xmm1 +.byte 102,15,56,0,193 + leal 352(%ebp),%ebx + addl $32,%edx +.L013schedule_mangle_last_dec: + addl $-16,%edx + pxor 336(%ebp),%xmm0 + call _vpaes_schedule_transform + movdqu %xmm0,(%edx) + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + ret +.size _vpaes_schedule_core,.-_vpaes_schedule_core +.type _vpaes_schedule_192_smear,@function +.align 16 +_vpaes_schedule_192_smear: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pshufd $128,%xmm6,%xmm1 + pshufd $254,%xmm7,%xmm0 + pxor %xmm1,%xmm6 + pxor %xmm1,%xmm1 + pxor %xmm0,%xmm6 + movdqa %xmm6,%xmm0 + movhlps %xmm1,%xmm6 + ret +.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear +.type _vpaes_schedule_round,@function +.align 16 +_vpaes_schedule_round: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movdqa 8(%esp),%xmm2 + pxor %xmm1,%xmm1 +.byte 102,15,58,15,202,15 +.byte 102,15,58,15,210,15 + pxor %xmm1,%xmm7 + pshufd $255,%xmm0,%xmm0 +.byte 102,15,58,15,192,1 + movdqa %xmm2,8(%esp) +.L_vpaes_schedule_low_round: + movdqa %xmm7,%xmm1 + pslldq $4,%xmm7 + pxor %xmm1,%xmm7 + movdqa %xmm7,%xmm1 + pslldq $8,%xmm7 + pxor %xmm1,%xmm7 + pxor 336(%ebp),%xmm7 + movdqa -16(%ebp),%xmm4 + movdqa -48(%ebp),%xmm5 + movdqa %xmm4,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm4,%xmm0 + movdqa -32(%ebp),%xmm2 +.byte 102,15,56,0,208 + pxor %xmm1,%xmm0 + movdqa %xmm5,%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 + movdqa %xmm5,%xmm4 +.byte 102,15,56,0,224 + pxor %xmm2,%xmm4 + movdqa %xmm5,%xmm2 +.byte 102,15,56,0,211 + pxor %xmm0,%xmm2 + movdqa %xmm5,%xmm3 +.byte 102,15,56,0,220 + pxor %xmm1,%xmm3 + movdqa 32(%ebp),%xmm4 +.byte 102,15,56,0,226 + movdqa 48(%ebp),%xmm0 +.byte 102,15,56,0,195 + pxor %xmm4,%xmm0 + pxor %xmm7,%xmm0 + movdqa %xmm0,%xmm7 + ret +.size _vpaes_schedule_round,.-_vpaes_schedule_round +.type _vpaes_schedule_transform,@function +.align 16 +_vpaes_schedule_transform: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movdqa -16(%ebp),%xmm2 + movdqa %xmm2,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm2,%xmm0 + movdqa (%ebx),%xmm2 +.byte 102,15,56,0,208 + movdqa 16(%ebx),%xmm0 +.byte 102,15,56,0,193 + pxor %xmm2,%xmm0 + ret +.size _vpaes_schedule_transform,.-_vpaes_schedule_transform +.type _vpaes_schedule_mangle,@function +.align 16 +_vpaes_schedule_mangle: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movdqa %xmm0,%xmm4 + movdqa 128(%ebp),%xmm5 + testl %edi,%edi + jnz .L014schedule_mangle_dec + addl $16,%edx + pxor 336(%ebp),%xmm4 +.byte 102,15,56,0,229 + movdqa %xmm4,%xmm3 +.byte 102,15,56,0,229 + pxor %xmm4,%xmm3 +.byte 102,15,56,0,229 + pxor %xmm4,%xmm3 + jmp .L015schedule_mangle_both +.align 16 +.L014schedule_mangle_dec: + movdqa -16(%ebp),%xmm2 + leal 416(%ebp),%esi + movdqa %xmm2,%xmm1 + pandn %xmm4,%xmm1 + psrld $4,%xmm1 + pand %xmm2,%xmm4 + movdqa (%esi),%xmm2 +.byte 102,15,56,0,212 + movdqa 16(%esi),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + movdqa 32(%esi),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 48(%esi),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + movdqa 64(%esi),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 80(%esi),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + movdqa 96(%esi),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 112(%esi),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 + addl $-16,%edx +.L015schedule_mangle_both: + movdqa 256(%ebp,%ecx,1),%xmm1 +.byte 102,15,56,0,217 + addl $-16,%ecx + andl $48,%ecx + movdqu %xmm3,(%edx) + ret +.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle +.globl vpaes_set_encrypt_key +.type vpaes_set_encrypt_key,@function +.align 16 +vpaes_set_encrypt_key: +.L_vpaes_set_encrypt_key_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + leal -56(%esp),%ebx + movl 24(%esp),%eax + andl $-16,%ebx + movl 28(%esp),%edx + xchgl %esp,%ebx + movl %ebx,48(%esp) + movl %eax,%ebx + shrl $5,%ebx + addl $5,%ebx + movl %ebx,240(%edx) + movl $48,%ecx + movl $0,%edi + leal .L_vpaes_consts+0x30-.L016pic_point,%ebp + call _vpaes_schedule_core +.L016pic_point: + movl 48(%esp),%esp + xorl %eax,%eax + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size vpaes_set_encrypt_key,.-.L_vpaes_set_encrypt_key_begin +.globl vpaes_set_decrypt_key +.type vpaes_set_decrypt_key,@function +.align 16 +vpaes_set_decrypt_key: +.L_vpaes_set_decrypt_key_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + leal -56(%esp),%ebx + movl 24(%esp),%eax + andl $-16,%ebx + movl 28(%esp),%edx + xchgl %esp,%ebx + movl %ebx,48(%esp) + movl %eax,%ebx + shrl $5,%ebx + addl $5,%ebx + movl %ebx,240(%edx) + shll $4,%ebx + leal 16(%edx,%ebx,1),%edx + movl $1,%edi + movl %eax,%ecx + shrl $1,%ecx + andl $32,%ecx + xorl $32,%ecx + leal .L_vpaes_consts+0x30-.L017pic_point,%ebp + call _vpaes_schedule_core +.L017pic_point: + movl 48(%esp),%esp + xorl %eax,%eax + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size vpaes_set_decrypt_key,.-.L_vpaes_set_decrypt_key_begin +.globl vpaes_encrypt +.type vpaes_encrypt,@function +.align 16 +vpaes_encrypt: +.L_vpaes_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + leal .L_vpaes_consts+0x30-.L018pic_point,%ebp + call _vpaes_preheat +.L018pic_point: + movl 20(%esp),%esi + leal -56(%esp),%ebx + movl 24(%esp),%edi + andl $-16,%ebx + movl 28(%esp),%edx + xchgl %esp,%ebx + movl %ebx,48(%esp) + movdqu (%esi),%xmm0 + call _vpaes_encrypt_core + movdqu %xmm0,(%edi) + movl 48(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size vpaes_encrypt,.-.L_vpaes_encrypt_begin +.globl vpaes_decrypt +.type vpaes_decrypt,@function +.align 16 +vpaes_decrypt: +.L_vpaes_decrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + leal .L_vpaes_consts+0x30-.L019pic_point,%ebp + call _vpaes_preheat +.L019pic_point: + movl 20(%esp),%esi + leal -56(%esp),%ebx + movl 24(%esp),%edi + andl $-16,%ebx + movl 28(%esp),%edx + xchgl %esp,%ebx + movl %ebx,48(%esp) + movdqu (%esi),%xmm0 + call _vpaes_decrypt_core + movdqu %xmm0,(%edi) + movl 48(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size vpaes_decrypt,.-.L_vpaes_decrypt_begin +.globl vpaes_cbc_encrypt +.type vpaes_cbc_encrypt,@function +.align 16 +vpaes_cbc_encrypt: +.L_vpaes_cbc_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl 32(%esp),%edx + subl $16,%eax + jc .L020cbc_abort + leal -56(%esp),%ebx + movl 36(%esp),%ebp + andl $-16,%ebx + movl 40(%esp),%ecx + xchgl %esp,%ebx + movdqu (%ebp),%xmm1 + subl %esi,%edi + movl %ebx,48(%esp) + movl %edi,(%esp) + movl %edx,4(%esp) + movl %ebp,8(%esp) + movl %eax,%edi + leal .L_vpaes_consts+0x30-.L021pic_point,%ebp + call _vpaes_preheat +.L021pic_point: + cmpl $0,%ecx + je .L022cbc_dec_loop + jmp .L023cbc_enc_loop +.align 16 +.L023cbc_enc_loop: + movdqu (%esi),%xmm0 + pxor %xmm1,%xmm0 + call _vpaes_encrypt_core + movl (%esp),%ebx + movl 4(%esp),%edx + movdqa %xmm0,%xmm1 + movdqu %xmm0,(%ebx,%esi,1) + leal 16(%esi),%esi + subl $16,%edi + jnc .L023cbc_enc_loop + jmp .L024cbc_done +.align 16 +.L022cbc_dec_loop: + movdqu (%esi),%xmm0 + movdqa %xmm1,16(%esp) + movdqa %xmm0,32(%esp) + call _vpaes_decrypt_core + movl (%esp),%ebx + movl 4(%esp),%edx + pxor 16(%esp),%xmm0 + movdqa 32(%esp),%xmm1 + movdqu %xmm0,(%ebx,%esi,1) + leal 16(%esi),%esi + subl $16,%edi + jnc .L022cbc_dec_loop +.L024cbc_done: + movl 8(%esp),%ebx + movl 48(%esp),%esp + movdqu %xmm1,(%ebx) +.L020cbc_abort: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size vpaes_cbc_encrypt,.-.L_vpaes_cbc_encrypt_begin + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/aes/vpaes-x86_64.S b/crypto/openssl/crypto/aes/vpaes-x86_64.S new file mode 100644 index 000000000000..7783c6a659f9 --- /dev/null +++ b/crypto/openssl/crypto/aes/vpaes-x86_64.S @@ -0,0 +1,879 @@ +.text + + + + + + + + + + + + + + + + +.type _vpaes_encrypt_core,@function +.align 16 +_vpaes_encrypt_core: +.cfi_startproc + movq %rdx,%r9 + movq $16,%r11 + movl 240(%rdx),%eax + movdqa %xmm9,%xmm1 + movdqa .Lk_ipt(%rip),%xmm2 + pandn %xmm0,%xmm1 + movdqu (%r9),%xmm5 + psrld $4,%xmm1 + pand %xmm9,%xmm0 +.byte 102,15,56,0,208 + movdqa .Lk_ipt+16(%rip),%xmm0 +.byte 102,15,56,0,193 + pxor %xmm5,%xmm2 + addq $16,%r9 + pxor %xmm2,%xmm0 + leaq .Lk_mc_backward(%rip),%r10 + jmp .Lenc_entry + +.align 16 +.Lenc_loop: + + movdqa %xmm13,%xmm4 + movdqa %xmm12,%xmm0 +.byte 102,15,56,0,226 +.byte 102,15,56,0,195 + pxor %xmm5,%xmm4 + movdqa %xmm15,%xmm5 + pxor %xmm4,%xmm0 + movdqa -64(%r11,%r10,1),%xmm1 +.byte 102,15,56,0,234 + movdqa (%r11,%r10,1),%xmm4 + movdqa %xmm14,%xmm2 +.byte 102,15,56,0,211 + movdqa %xmm0,%xmm3 + pxor %xmm5,%xmm2 +.byte 102,15,56,0,193 + addq $16,%r9 + pxor %xmm2,%xmm0 +.byte 102,15,56,0,220 + addq $16,%r11 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,193 + andq $0x30,%r11 + subq $1,%rax + pxor %xmm3,%xmm0 + +.Lenc_entry: + + movdqa %xmm9,%xmm1 + movdqa %xmm11,%xmm5 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm0 +.byte 102,15,56,0,232 + movdqa %xmm10,%xmm3 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,217 + movdqa %xmm10,%xmm4 + pxor %xmm5,%xmm3 +.byte 102,15,56,0,224 + movdqa %xmm10,%xmm2 + pxor %xmm5,%xmm4 +.byte 102,15,56,0,211 + movdqa %xmm10,%xmm3 + pxor %xmm0,%xmm2 +.byte 102,15,56,0,220 + movdqu (%r9),%xmm5 + pxor %xmm1,%xmm3 + jnz .Lenc_loop + + + movdqa -96(%r10),%xmm4 + movdqa -80(%r10),%xmm0 +.byte 102,15,56,0,226 + pxor %xmm5,%xmm4 +.byte 102,15,56,0,195 + movdqa 64(%r11,%r10,1),%xmm1 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,193 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_encrypt_core,.-_vpaes_encrypt_core + + + + + + +.type _vpaes_decrypt_core,@function +.align 16 +_vpaes_decrypt_core: +.cfi_startproc + movq %rdx,%r9 + movl 240(%rdx),%eax + movdqa %xmm9,%xmm1 + movdqa .Lk_dipt(%rip),%xmm2 + pandn %xmm0,%xmm1 + movq %rax,%r11 + psrld $4,%xmm1 + movdqu (%r9),%xmm5 + shlq $4,%r11 + pand %xmm9,%xmm0 +.byte 102,15,56,0,208 + movdqa .Lk_dipt+16(%rip),%xmm0 + xorq $0x30,%r11 + leaq .Lk_dsbd(%rip),%r10 +.byte 102,15,56,0,193 + andq $0x30,%r11 + pxor %xmm5,%xmm2 + movdqa .Lk_mc_forward+48(%rip),%xmm5 + pxor %xmm2,%xmm0 + addq $16,%r9 + addq %r10,%r11 + jmp .Ldec_entry + +.align 16 +.Ldec_loop: + + + + movdqa -32(%r10),%xmm4 + movdqa -16(%r10),%xmm1 +.byte 102,15,56,0,226 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 0(%r10),%xmm4 + pxor %xmm1,%xmm0 + movdqa 16(%r10),%xmm1 + +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 32(%r10),%xmm4 + pxor %xmm1,%xmm0 + movdqa 48(%r10),%xmm1 + +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + movdqa 64(%r10),%xmm4 + pxor %xmm1,%xmm0 + movdqa 80(%r10),%xmm1 + +.byte 102,15,56,0,226 +.byte 102,15,56,0,197 +.byte 102,15,56,0,203 + pxor %xmm4,%xmm0 + addq $16,%r9 +.byte 102,15,58,15,237,12 + pxor %xmm1,%xmm0 + subq $1,%rax + +.Ldec_entry: + + movdqa %xmm9,%xmm1 + pandn %xmm0,%xmm1 + movdqa %xmm11,%xmm2 + psrld $4,%xmm1 + pand %xmm9,%xmm0 +.byte 102,15,56,0,208 + movdqa %xmm10,%xmm3 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,217 + movdqa %xmm10,%xmm4 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,224 + pxor %xmm2,%xmm4 + movdqa %xmm10,%xmm2 +.byte 102,15,56,0,211 + movdqa %xmm10,%xmm3 + pxor %xmm0,%xmm2 +.byte 102,15,56,0,220 + movdqu (%r9),%xmm0 + pxor %xmm1,%xmm3 + jnz .Ldec_loop + + + movdqa 96(%r10),%xmm4 +.byte 102,15,56,0,226 + pxor %xmm0,%xmm4 + movdqa 112(%r10),%xmm0 + movdqa -352(%r11),%xmm2 +.byte 102,15,56,0,195 + pxor %xmm4,%xmm0 +.byte 102,15,56,0,194 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_decrypt_core,.-_vpaes_decrypt_core + + + + + + +.type _vpaes_schedule_core,@function +.align 16 +_vpaes_schedule_core: +.cfi_startproc + + + + + + call _vpaes_preheat + movdqa .Lk_rcon(%rip),%xmm8 + movdqu (%rdi),%xmm0 + + + movdqa %xmm0,%xmm3 + leaq .Lk_ipt(%rip),%r11 + call _vpaes_schedule_transform + movdqa %xmm0,%xmm7 + + leaq .Lk_sr(%rip),%r10 + testq %rcx,%rcx + jnz .Lschedule_am_decrypting + + + movdqu %xmm0,(%rdx) + jmp .Lschedule_go + +.Lschedule_am_decrypting: + + movdqa (%r8,%r10,1),%xmm1 +.byte 102,15,56,0,217 + movdqu %xmm3,(%rdx) + xorq $0x30,%r8 + +.Lschedule_go: + cmpl $192,%esi + ja .Lschedule_256 + je .Lschedule_192 + + + + + + + + + + +.Lschedule_128: + movl $10,%esi + +.Loop_schedule_128: + call _vpaes_schedule_round + decq %rsi + jz .Lschedule_mangle_last + call _vpaes_schedule_mangle + jmp .Loop_schedule_128 + + + + + + + + + + + + + + + + +.align 16 +.Lschedule_192: + movdqu 8(%rdi),%xmm0 + call _vpaes_schedule_transform + movdqa %xmm0,%xmm6 + pxor %xmm4,%xmm4 + movhlps %xmm4,%xmm6 + movl $4,%esi + +.Loop_schedule_192: + call _vpaes_schedule_round +.byte 102,15,58,15,198,8 + call _vpaes_schedule_mangle + call _vpaes_schedule_192_smear + call _vpaes_schedule_mangle + call _vpaes_schedule_round + decq %rsi + jz .Lschedule_mangle_last + call _vpaes_schedule_mangle + call _vpaes_schedule_192_smear + jmp .Loop_schedule_192 + + + + + + + + + + + +.align 16 +.Lschedule_256: + movdqu 16(%rdi),%xmm0 + call _vpaes_schedule_transform + movl $7,%esi + +.Loop_schedule_256: + call _vpaes_schedule_mangle + movdqa %xmm0,%xmm6 + + + call _vpaes_schedule_round + decq %rsi + jz .Lschedule_mangle_last + call _vpaes_schedule_mangle + + + pshufd $0xFF,%xmm0,%xmm0 + movdqa %xmm7,%xmm5 + movdqa %xmm6,%xmm7 + call _vpaes_schedule_low_round + movdqa %xmm5,%xmm7 + + jmp .Loop_schedule_256 + + + + + + + + + + + + +.align 16 +.Lschedule_mangle_last: + + leaq .Lk_deskew(%rip),%r11 + testq %rcx,%rcx + jnz .Lschedule_mangle_last_dec + + + movdqa (%r8,%r10,1),%xmm1 +.byte 102,15,56,0,193 + leaq .Lk_opt(%rip),%r11 + addq $32,%rdx + +.Lschedule_mangle_last_dec: + addq $-16,%rdx + pxor .Lk_s63(%rip),%xmm0 + call _vpaes_schedule_transform + movdqu %xmm0,(%rdx) + + + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_schedule_core,.-_vpaes_schedule_core + + + + + + + + + + + + + + + +.type _vpaes_schedule_192_smear,@function +.align 16 +_vpaes_schedule_192_smear: +.cfi_startproc + pshufd $0x80,%xmm6,%xmm1 + pshufd $0xFE,%xmm7,%xmm0 + pxor %xmm1,%xmm6 + pxor %xmm1,%xmm1 + pxor %xmm0,%xmm6 + movdqa %xmm6,%xmm0 + movhlps %xmm1,%xmm6 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear + + + + + + + + + + + + + + + + + + + +.type _vpaes_schedule_round,@function +.align 16 +_vpaes_schedule_round: +.cfi_startproc + + pxor %xmm1,%xmm1 +.byte 102,65,15,58,15,200,15 +.byte 102,69,15,58,15,192,15 + pxor %xmm1,%xmm7 + + + pshufd $0xFF,%xmm0,%xmm0 +.byte 102,15,58,15,192,1 + + + + +_vpaes_schedule_low_round: + + movdqa %xmm7,%xmm1 + pslldq $4,%xmm7 + pxor %xmm1,%xmm7 + movdqa %xmm7,%xmm1 + pslldq $8,%xmm7 + pxor %xmm1,%xmm7 + pxor .Lk_s63(%rip),%xmm7 + + + movdqa %xmm9,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm0 + movdqa %xmm11,%xmm2 +.byte 102,15,56,0,208 + pxor %xmm1,%xmm0 + movdqa %xmm10,%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 + movdqa %xmm10,%xmm4 +.byte 102,15,56,0,224 + pxor %xmm2,%xmm4 + movdqa %xmm10,%xmm2 +.byte 102,15,56,0,211 + pxor %xmm0,%xmm2 + movdqa %xmm10,%xmm3 +.byte 102,15,56,0,220 + pxor %xmm1,%xmm3 + movdqa %xmm13,%xmm4 +.byte 102,15,56,0,226 + movdqa %xmm12,%xmm0 +.byte 102,15,56,0,195 + pxor %xmm4,%xmm0 + + + pxor %xmm7,%xmm0 + movdqa %xmm0,%xmm7 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_schedule_round,.-_vpaes_schedule_round + + + + + + + + + + +.type _vpaes_schedule_transform,@function +.align 16 +_vpaes_schedule_transform: +.cfi_startproc + movdqa %xmm9,%xmm1 + pandn %xmm0,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm0 + movdqa (%r11),%xmm2 +.byte 102,15,56,0,208 + movdqa 16(%r11),%xmm0 +.byte 102,15,56,0,193 + pxor %xmm2,%xmm0 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_schedule_transform,.-_vpaes_schedule_transform + + + + + + + + + + + + + + + + + + + + + + + + +.type _vpaes_schedule_mangle,@function +.align 16 +_vpaes_schedule_mangle: +.cfi_startproc + movdqa %xmm0,%xmm4 + movdqa .Lk_mc_forward(%rip),%xmm5 + testq %rcx,%rcx + jnz .Lschedule_mangle_dec + + + addq $16,%rdx + pxor .Lk_s63(%rip),%xmm4 +.byte 102,15,56,0,229 + movdqa %xmm4,%xmm3 +.byte 102,15,56,0,229 + pxor %xmm4,%xmm3 +.byte 102,15,56,0,229 + pxor %xmm4,%xmm3 + + jmp .Lschedule_mangle_both +.align 16 +.Lschedule_mangle_dec: + + leaq .Lk_dksd(%rip),%r11 + movdqa %xmm9,%xmm1 + pandn %xmm4,%xmm1 + psrld $4,%xmm1 + pand %xmm9,%xmm4 + + movdqa 0(%r11),%xmm2 +.byte 102,15,56,0,212 + movdqa 16(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + + movdqa 32(%r11),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 48(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + + movdqa 64(%r11),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 80(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 +.byte 102,15,56,0,221 + + movdqa 96(%r11),%xmm2 +.byte 102,15,56,0,212 + pxor %xmm3,%xmm2 + movdqa 112(%r11),%xmm3 +.byte 102,15,56,0,217 + pxor %xmm2,%xmm3 + + addq $-16,%rdx + +.Lschedule_mangle_both: + movdqa (%r8,%r10,1),%xmm1 +.byte 102,15,56,0,217 + addq $-16,%r8 + andq $0x30,%r8 + movdqu %xmm3,(%rdx) + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle + + + + +.globl vpaes_set_encrypt_key +.type vpaes_set_encrypt_key,@function +.align 16 +vpaes_set_encrypt_key: +.cfi_startproc +.byte 243,15,30,250 + movl %esi,%eax + shrl $5,%eax + addl $5,%eax + movl %eax,240(%rdx) + + movl $0,%ecx + movl $0x30,%r8d + call _vpaes_schedule_core + xorl %eax,%eax + .byte 0xf3,0xc3 +.cfi_endproc +.size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key + +.globl vpaes_set_decrypt_key +.type vpaes_set_decrypt_key,@function +.align 16 +vpaes_set_decrypt_key: +.cfi_startproc +.byte 243,15,30,250 + movl %esi,%eax + shrl $5,%eax + addl $5,%eax + movl %eax,240(%rdx) + shll $4,%eax + leaq 16(%rdx,%rax,1),%rdx + + movl $1,%ecx + movl %esi,%r8d + shrl $1,%r8d + andl $32,%r8d + xorl $32,%r8d + call _vpaes_schedule_core + xorl %eax,%eax + .byte 0xf3,0xc3 +.cfi_endproc +.size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key + +.globl vpaes_encrypt +.type vpaes_encrypt,@function +.align 16 +vpaes_encrypt: +.cfi_startproc +.byte 243,15,30,250 + movdqu (%rdi),%xmm0 + call _vpaes_preheat + call _vpaes_encrypt_core + movdqu %xmm0,(%rsi) + .byte 0xf3,0xc3 +.cfi_endproc +.size vpaes_encrypt,.-vpaes_encrypt + +.globl vpaes_decrypt +.type vpaes_decrypt,@function +.align 16 +vpaes_decrypt: +.cfi_startproc +.byte 243,15,30,250 + movdqu (%rdi),%xmm0 + call _vpaes_preheat + call _vpaes_decrypt_core + movdqu %xmm0,(%rsi) + .byte 0xf3,0xc3 +.cfi_endproc +.size vpaes_decrypt,.-vpaes_decrypt +.globl vpaes_cbc_encrypt +.type vpaes_cbc_encrypt,@function +.align 16 +vpaes_cbc_encrypt: +.cfi_startproc +.byte 243,15,30,250 + xchgq %rcx,%rdx + subq $16,%rcx + jc .Lcbc_abort + movdqu (%r8),%xmm6 + subq %rdi,%rsi + call _vpaes_preheat + cmpl $0,%r9d + je .Lcbc_dec_loop + jmp .Lcbc_enc_loop +.align 16 +.Lcbc_enc_loop: + movdqu (%rdi),%xmm0 + pxor %xmm6,%xmm0 + call _vpaes_encrypt_core + movdqa %xmm0,%xmm6 + movdqu %xmm0,(%rsi,%rdi,1) + leaq 16(%rdi),%rdi + subq $16,%rcx + jnc .Lcbc_enc_loop + jmp .Lcbc_done +.align 16 +.Lcbc_dec_loop: + movdqu (%rdi),%xmm0 + movdqa %xmm0,%xmm7 + call _vpaes_decrypt_core + pxor %xmm6,%xmm0 + movdqa %xmm7,%xmm6 + movdqu %xmm0,(%rsi,%rdi,1) + leaq 16(%rdi),%rdi + subq $16,%rcx + jnc .Lcbc_dec_loop +.Lcbc_done: + movdqu %xmm6,(%r8) +.Lcbc_abort: + .byte 0xf3,0xc3 +.cfi_endproc +.size vpaes_cbc_encrypt,.-vpaes_cbc_encrypt + + + + + + +.type _vpaes_preheat,@function +.align 16 +_vpaes_preheat: +.cfi_startproc + leaq .Lk_s0F(%rip),%r10 + movdqa -32(%r10),%xmm10 + movdqa -16(%r10),%xmm11 + movdqa 0(%r10),%xmm9 + movdqa 48(%r10),%xmm13 + movdqa 64(%r10),%xmm12 + movdqa 80(%r10),%xmm15 + movdqa 96(%r10),%xmm14 + .byte 0xf3,0xc3 +.cfi_endproc +.size _vpaes_preheat,.-_vpaes_preheat + + + + + +.type _vpaes_consts,@object +.align 64 +_vpaes_consts: +.Lk_inv: +.quad 0x0E05060F0D080180, 0x040703090A0B0C02 +.quad 0x01040A060F0B0780, 0x030D0E0C02050809 + +.Lk_s0F: +.quad 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F + +.Lk_ipt: +.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808 +.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81 + +.Lk_sb1: +.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544 +.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF +.Lk_sb2: +.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD +.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A +.Lk_sbo: +.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878 +.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA + +.Lk_mc_forward: +.quad 0x0407060500030201, 0x0C0F0E0D080B0A09 +.quad 0x080B0A0904070605, 0x000302010C0F0E0D +.quad 0x0C0F0E0D080B0A09, 0x0407060500030201 +.quad 0x000302010C0F0E0D, 0x080B0A0904070605 + +.Lk_mc_backward: +.quad 0x0605040702010003, 0x0E0D0C0F0A09080B +.quad 0x020100030E0D0C0F, 0x0A09080B06050407 +.quad 0x0E0D0C0F0A09080B, 0x0605040702010003 +.quad 0x0A09080B06050407, 0x020100030E0D0C0F + +.Lk_sr: +.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908 +.quad 0x030E09040F0A0500, 0x0B06010C07020D08 +.quad 0x0F060D040B020900, 0x070E050C030A0108 +.quad 0x0B0E0104070A0D00, 0x0306090C0F020508 + +.Lk_rcon: +.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81 + +.Lk_s63: +.quad 0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B + +.Lk_opt: +.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808 +.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0 + +.Lk_deskew: +.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A +.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77 + + + + + +.Lk_dksd: +.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9 +.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E +.Lk_dksb: +.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99 +.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8 +.Lk_dkse: +.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086 +.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487 +.Lk_dks9: +.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC +.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE + + + + + +.Lk_dipt: +.quad 0x0F505B040B545F00, 0x154A411E114E451A +.quad 0x86E383E660056500, 0x12771772F491F194 + +.Lk_dsb9: +.quad 0x851C03539A86D600, 0xCAD51F504F994CC9 +.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565 +.Lk_dsbd: +.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439 +.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3 +.Lk_dsbb: +.quad 0xD022649296B44200, 0x602646F6B0F2D404 +.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B +.Lk_dsbe: +.quad 0x46F2929626D4D000, 0x2242600464B4F6B0 +.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32 +.Lk_dsbo: +.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D +.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C +.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 +.align 64 +.size _vpaes_consts,.-_vpaes_consts + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/aria/aria.c b/crypto/openssl/crypto/aria/aria.c index ce55d5266429..5e60bc521023 100644 --- a/crypto/openssl/crypto/aria/aria.c +++ b/crypto/openssl/crypto/aria/aria.c @@ -1,8 +1,8 @@ /* - * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -468,8 +468,8 @@ static const uint32_t X2[256] = { (Y) = (TMP2) ^ rotr32((TMP) ^ (TMP2), 16); \ } while(0) -void aria_encrypt(const unsigned char *in, unsigned char *out, - const ARIA_KEY *key) +void ossl_aria_encrypt(const unsigned char *in, unsigned char *out, + const ARIA_KEY *key) { register uint32_t reg0, reg1, reg2, reg3; int Nr; @@ -535,8 +535,8 @@ void aria_encrypt(const unsigned char *in, unsigned char *out, PUT_U32_BE(out, 3, reg3); } -int aria_set_encrypt_key(const unsigned char *userKey, const int bits, - ARIA_KEY *key) +int ossl_aria_set_encrypt_key(const unsigned char *userKey, const int bits, + ARIA_KEY *key) { register uint32_t reg0, reg1, reg2, reg3; uint32_t w0[4], w1[4], w2[4], w3[4]; @@ -667,8 +667,8 @@ int aria_set_encrypt_key(const unsigned char *userKey, const int bits, return 0; } -int aria_set_decrypt_key(const unsigned char *userKey, const int bits, - ARIA_KEY *key) +int ossl_aria_set_decrypt_key(const unsigned char *userKey, const int bits, + ARIA_KEY *key) { ARIA_u128 *rk_head; ARIA_u128 *rk_tail; @@ -676,7 +676,7 @@ int aria_set_decrypt_key(const unsigned char *userKey, const int bits, register uint32_t reg0, reg1, reg2, reg3; uint32_t s0, s1, s2, s3; - const int r = aria_set_encrypt_key(userKey, bits, key); + const int r = ossl_aria_set_encrypt_key(userKey, bits, key); if (r != 0) { return r; @@ -1007,7 +1007,7 @@ static void sl2(ARIA_c128 o, const ARIA_u128 *x, const ARIA_u128 *y) { unsigned int i; for (i = 0; i < ARIA_BLOCK_SIZE; i += 4) { - o[i ] = sb3[x->c[i ] ^ y->c[i ]]; + o[i ] = sb3[x->c[i ] ^ y->c[i ]]; o[i + 1] = sb4[x->c[i + 1] ^ y->c[i + 1]]; o[i + 2] = sb1[x->c[i + 2] ^ y->c[i + 2]]; o[i + 3] = sb2[x->c[i + 3] ^ y->c[i + 3]]; @@ -1106,8 +1106,8 @@ static void do_encrypt(unsigned char *o, const unsigned char *pin, * Encrypt a single block * in and out can overlap */ -void aria_encrypt(const unsigned char *in, unsigned char *out, - const ARIA_KEY *key) +void ossl_aria_encrypt(const unsigned char *in, unsigned char *out, + const ARIA_KEY *key) { assert(in != NULL && out != NULL && key != NULL); do_encrypt(out, in, key->rounds, key->rd_key); @@ -1119,8 +1119,8 @@ void aria_encrypt(const unsigned char *in, unsigned char *out, * We short circuit execution of the last two * or four rotations based on the key size. */ -int aria_set_encrypt_key(const unsigned char *userKey, const int bits, - ARIA_KEY *key) +int ossl_aria_set_encrypt_key(const unsigned char *userKey, const int bits, + ARIA_KEY *key) { const ARIA_u128 *ck1, *ck2, *ck3; ARIA_u128 kr, w0, w1, w2, w3; @@ -1192,11 +1192,11 @@ int aria_set_encrypt_key(const unsigned char *userKey, const int bits, /* * Expand the cipher key into the decryption key schedule. */ -int aria_set_decrypt_key(const unsigned char *userKey, const int bits, - ARIA_KEY *key) +int ossl_aria_set_decrypt_key(const unsigned char *userKey, const int bits, + ARIA_KEY *key) { ARIA_KEY ek; - const int r = aria_set_encrypt_key(userKey, bits, &ek); + const int r = ossl_aria_set_encrypt_key(userKey, bits, &ek); unsigned int i, rounds = ek.rounds; if (r == 0) { diff --git a/crypto/openssl/crypto/arm64cpuid.S b/crypto/openssl/crypto/arm64cpuid.S new file mode 100644 index 000000000000..7fb4c7507a0d --- /dev/null +++ b/crypto/openssl/crypto/arm64cpuid.S @@ -0,0 +1,129 @@ +#include "arm_arch.h" + +.text +.arch armv8-a+crypto + +.align 5 +.globl _armv7_neon_probe +.type _armv7_neon_probe,%function +_armv7_neon_probe: + orr v15.16b, v15.16b, v15.16b + ret +.size _armv7_neon_probe,.-_armv7_neon_probe + +.globl _armv7_tick +.type _armv7_tick,%function +_armv7_tick: +#ifdef __APPLE__ + mrs x0, CNTPCT_EL0 +#else + mrs x0, CNTVCT_EL0 +#endif + ret +.size _armv7_tick,.-_armv7_tick + +.globl _armv8_aes_probe +.type _armv8_aes_probe,%function +_armv8_aes_probe: + aese v0.16b, v0.16b + ret +.size _armv8_aes_probe,.-_armv8_aes_probe + +.globl _armv8_sha1_probe +.type _armv8_sha1_probe,%function +_armv8_sha1_probe: + sha1h s0, s0 + ret +.size _armv8_sha1_probe,.-_armv8_sha1_probe + +.globl _armv8_sha256_probe +.type _armv8_sha256_probe,%function +_armv8_sha256_probe: + sha256su0 v0.4s, v0.4s + ret +.size _armv8_sha256_probe,.-_armv8_sha256_probe + +.globl _armv8_pmull_probe +.type _armv8_pmull_probe,%function +_armv8_pmull_probe: + pmull v0.1q, v0.1d, v0.1d + ret +.size _armv8_pmull_probe,.-_armv8_pmull_probe + +.globl _armv8_sha512_probe +.type _armv8_sha512_probe,%function +_armv8_sha512_probe: +.long 0xcec08000 // sha512su0 v0.2d,v0.2d + ret +.size _armv8_sha512_probe,.-_armv8_sha512_probe + +.globl _armv8_cpuid_probe +.type _armv8_cpuid_probe,%function +_armv8_cpuid_probe: + mrs x0, midr_el1 + ret +.size _armv8_cpuid_probe,.-_armv8_cpuid_probe + +.globl OPENSSL_cleanse +.type OPENSSL_cleanse,%function +.align 5 +OPENSSL_cleanse: + cbz x1,.Lret // len==0? + cmp x1,#15 + b.hi .Lot // len>15 + nop +.Little: + strb wzr,[x0],#1 // store byte-by-byte + subs x1,x1,#1 + b.ne .Little +.Lret: ret + +.align 4 +.Lot: tst x0,#7 + b.eq .Laligned // inp is aligned + strb wzr,[x0],#1 // store byte-by-byte + sub x1,x1,#1 + b .Lot + +.align 4 +.Laligned: + str xzr,[x0],#8 // store word-by-word + sub x1,x1,#8 + tst x1,#-8 + b.ne .Laligned // len>=8 + cbnz x1,.Little // len!=0? + ret +.size OPENSSL_cleanse,.-OPENSSL_cleanse + +.globl CRYPTO_memcmp +.type CRYPTO_memcmp,%function +.align 4 +CRYPTO_memcmp: + eor w3,w3,w3 + cbz x2,.Lno_data // len==0? + cmp x2,#16 + b.ne .Loop_cmp + ldp x8,x9,[x0] + ldp x10,x11,[x1] + eor x8,x8,x10 + eor x9,x9,x11 + orr x8,x8,x9 + mov x0,#1 + cmp x8,#0 + csel x0,xzr,x0,eq + ret + +.align 4 +.Loop_cmp: + ldrb w4,[x0],#1 + ldrb w5,[x1],#1 + eor w4,w4,w5 + orr w3,w3,w4 + subs x2,x2,#1 + b.ne .Loop_cmp + +.Lno_data: + neg w0,w3 + lsr w0,w0,#31 + ret +.size CRYPTO_memcmp,.-CRYPTO_memcmp diff --git a/crypto/openssl/crypto/arm64cpuid.pl b/crypto/openssl/crypto/arm64cpuid.pl index 319927e6c729..ac76dd449f37 100755 --- a/crypto/openssl/crypto/arm64cpuid.pl +++ b/crypto/openssl/crypto/arm64cpuid.pl @@ -1,21 +1,24 @@ #! /usr/bin/env perl # Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 -$flavour = shift; -$output = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ( $xlate="${dir}perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $code.=<<___; @@ -78,6 +81,13 @@ _armv8_sha512_probe: ret .size _armv8_sha512_probe,.-_armv8_sha512_probe +.globl _armv8_cpuid_probe +.type _armv8_cpuid_probe,%function +_armv8_cpuid_probe: + mrs x0, midr_el1 + ret +.size _armv8_cpuid_probe,.-_armv8_cpuid_probe + .globl OPENSSL_cleanse .type OPENSSL_cleanse,%function .align 5 diff --git a/crypto/openssl/crypto/arm_arch.h b/crypto/openssl/crypto/arm_arch.h index 8b7105571d78..45d7e1556475 100644 --- a/crypto/openssl/crypto/arm_arch.h +++ b/crypto/openssl/crypto/arm_arch.h @@ -1,7 +1,7 @@ /* - * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -71,6 +71,8 @@ # ifndef __ASSEMBLER__ extern unsigned int OPENSSL_armcap_P; +extern unsigned int OPENSSL_arm_midr; +extern unsigned int OPENSSL_armv8_rsa_neonized; # endif # define ARMV7_NEON (1<<0) @@ -80,5 +82,48 @@ extern unsigned int OPENSSL_armcap_P; # define ARMV8_SHA256 (1<<4) # define ARMV8_PMULL (1<<5) # define ARMV8_SHA512 (1<<6) +# define ARMV8_CPUID (1<<7) +/* + * MIDR_EL1 system register + * + * 63___ _ ___32_31___ _ ___24_23_____20_19_____16_15__ _ __4_3_______0 + * | | | | | | | + * |RES0 | Implementer | Variant | Arch | PartNum |Revision| + * |____ _ _____|_____ _ _____|_________|_______ _|____ _ ___|________| + * + */ + +# define ARM_CPU_IMP_ARM 0x41 + +# define ARM_CPU_PART_CORTEX_A72 0xD08 +# define ARM_CPU_PART_N1 0xD0C + +# define MIDR_PARTNUM_SHIFT 4 +# define MIDR_PARTNUM_MASK (0xfffU << MIDR_PARTNUM_SHIFT) +# define MIDR_PARTNUM(midr) \ + (((midr) & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT) + +# define MIDR_IMPLEMENTER_SHIFT 24 +# define MIDR_IMPLEMENTER_MASK (0xffU << MIDR_IMPLEMENTER_SHIFT) +# define MIDR_IMPLEMENTER(midr) \ + (((midr) & MIDR_IMPLEMENTER_MASK) >> MIDR_IMPLEMENTER_SHIFT) + +# define MIDR_ARCHITECTURE_SHIFT 16 +# define MIDR_ARCHITECTURE_MASK (0xfU << MIDR_ARCHITECTURE_SHIFT) +# define MIDR_ARCHITECTURE(midr) \ + (((midr) & MIDR_ARCHITECTURE_MASK) >> MIDR_ARCHITECTURE_SHIFT) + +# define MIDR_CPU_MODEL_MASK \ + (MIDR_IMPLEMENTER_MASK | \ + MIDR_PARTNUM_MASK | \ + MIDR_ARCHITECTURE_MASK) + +# define MIDR_CPU_MODEL(imp, partnum) \ + (((imp) << MIDR_IMPLEMENTER_SHIFT) | \ + (0xfU << MIDR_ARCHITECTURE_SHIFT) | \ + ((partnum) << MIDR_PARTNUM_SHIFT)) + +# define MIDR_IS_CPU_MODEL(midr, imp, partnum) \ + (((midr) & MIDR_CPU_MODEL_MASK) == MIDR_CPU_MODEL(imp, partnum)) #endif diff --git a/crypto/openssl/crypto/armcap.c b/crypto/openssl/crypto/armcap.c index 48c5d4d64e32..c021330e32fd 100644 --- a/crypto/openssl/crypto/armcap.c +++ b/crypto/openssl/crypto/armcap.c @@ -1,7 +1,7 @@ /* - * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,11 +13,16 @@ #include #include #include +#ifdef __APPLE__ +#include +#endif #include "internal/cryptlib.h" #include "arm_arch.h" unsigned int OPENSSL_armcap_P = 0; +unsigned int OPENSSL_arm_midr = 0; +unsigned int OPENSSL_armv8_rsa_neonized = 0; #if __ARM_MAX_ARCH__<7 void OPENSSL_cpuid_setup(void) @@ -48,6 +53,7 @@ void _armv8_sha256_probe(void); void _armv8_pmull_probe(void); # ifdef __aarch64__ void _armv8_sha512_probe(void); +unsigned int _armv8_cpuid_probe(void); # endif uint32_t _armv7_tick(void); @@ -130,6 +136,7 @@ static unsigned long getauxval(unsigned long key) # define HWCAP_CE_PMULL (1 << 4) # define HWCAP_CE_SHA1 (1 << 5) # define HWCAP_CE_SHA256 (1 << 6) +# define HWCAP_CPUID (1 << 11) # define HWCAP_CE_SHA512 (1 << 21) # endif @@ -144,12 +151,15 @@ void OPENSSL_cpuid_setup(void) return; trigger = 1; + OPENSSL_armcap_P = 0; + if ((e = getenv("OPENSSL_armcap"))) { OPENSSL_armcap_P = (unsigned int)strtoul(e, NULL, 0); return; } -# if defined(__APPLE__) && !defined(__aarch64__) +# if defined(__APPLE__) +# if !defined(__aarch64__) /* * Capability probing by catching SIGILL appears to be problematic * on iOS. But since Apple universe is "monocultural", it's actually @@ -165,9 +175,16 @@ void OPENSSL_cpuid_setup(void) * Unified code works because it never triggers SIGILL on Apple * devices... */ -# endif +# else + { + unsigned int sha512; + size_t len = sizeof(sha512); - OPENSSL_armcap_P = 0; + if (sysctlbyname("hw.optional.armv8_2_sha512", &sha512, &len, NULL, 0) == 0 && sha512 == 1) + OPENSSL_armcap_P |= ARMV8_SHA512; + } +# endif +# endif # ifdef OSSL_IMPLEMENT_GETAUXVAL if (getauxval(HWCAP) & HWCAP_NEON) { @@ -190,6 +207,9 @@ void OPENSSL_cpuid_setup(void) # ifdef __aarch64__ if (hwcap & HWCAP_CE_SHA512) OPENSSL_armcap_P |= ARMV8_SHA512; + + if (hwcap & HWCAP_CPUID) + OPENSSL_armcap_P |= ARMV8_CPUID; # endif } # endif @@ -237,13 +257,24 @@ void OPENSSL_cpuid_setup(void) } # endif - /* Things that getauxval didn't tell us */ - if (sigsetjmp(ill_jmp, 1) == 0) { - _armv7_tick(); - OPENSSL_armcap_P |= ARMV7_TICK; - } + /* + * Probing for ARMV7_TICK is known to produce unreliable results, + * so we will only use the feature when the user explicitly enables + * it with OPENSSL_armcap. + */ sigaction(SIGILL, &ill_oact, NULL); sigprocmask(SIG_SETMASK, &oset, NULL); + +# ifdef __aarch64__ + if (OPENSSL_armcap_P & ARMV8_CPUID) + OPENSSL_arm_midr = _armv8_cpuid_probe(); + + if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N1)) && + (OPENSSL_armcap_P & ARMV7_NEON)) { + OPENSSL_armv8_rsa_neonized = 1; + } +# endif } #endif diff --git a/crypto/openssl/crypto/armv4cpuid.pl b/crypto/openssl/crypto/armv4cpuid.pl index d1b71f836f10..8991fd4afe8e 100755 --- a/crypto/openssl/crypto/armv4cpuid.pl +++ b/crypto/openssl/crypto/armv4cpuid.pl @@ -1,27 +1,29 @@ #! /usr/bin/env perl # Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 -$flavour = shift; -$output = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ( $xlate="${dir}perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $code.=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) && !defined(__APPLE__) .syntax unified .thumb @@ -30,6 +32,8 @@ $code.=<<___; #undef __thumb2__ #endif +.text + .align 5 .global OPENSSL_atomic_add .type OPENSSL_atomic_add,%function diff --git a/crypto/openssl/crypto/asn1/a_bitstr.c b/crypto/openssl/crypto/asn1/a_bitstr.c index f462dd107368..7c256493571e 100644 --- a/crypto/openssl/crypto/asn1/a_bitstr.c +++ b/crypto/openssl/crypto/asn1/a_bitstr.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -18,7 +18,7 @@ int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) return ASN1_STRING_set(x, d, len); } -int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) +int ossl_i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) { int ret, j, bits, len; unsigned char *p, *d; @@ -76,8 +76,8 @@ int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) return ret; } -ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, - const unsigned char **pp, long len) +ASN1_BIT_STRING *ossl_c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long len) { ASN1_BIT_STRING *ret = NULL; const unsigned char *p; @@ -134,7 +134,7 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, *pp = p; return ret; err: - ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i); + ERR_raise(ERR_LIB_ASN1, i); if ((a == NULL) || (*a != ret)) ASN1_BIT_STRING_free(ret); return NULL; @@ -164,7 +164,7 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) return 1; /* Don't need to set */ c = OPENSSL_clear_realloc(a->data, a->length, w + 1); if (c == NULL) { - ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } if (w + 1 - a->length > 0) diff --git a/crypto/openssl/crypto/asn1/a_d2i_fp.c b/crypto/openssl/crypto/asn1/a_d2i_fp.c index a452b3deba08..e8602053f974 100644 --- a/crypto/openssl/crypto/asn1/a_d2i_fp.c +++ b/crypto/openssl/crypto/asn1/a_d2i_fp.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,6 +13,7 @@ #include "internal/numbers.h" #include #include +#include "internal/asn1.h" #include "crypto/asn1.h" #ifndef NO_OLD_ASN1 @@ -24,7 +25,7 @@ void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x) void *ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - ASN1err(ASN1_F_ASN1_D2I_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); return NULL; } BIO_set_fp(b, in, BIO_NOCLOSE); @@ -54,39 +55,53 @@ void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x) #endif -void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) +void *ASN1_item_d2i_bio_ex(const ASN1_ITEM *it, BIO *in, void *x, + OSSL_LIB_CTX *libctx, const char *propq) { BUF_MEM *b = NULL; const unsigned char *p; void *ret = NULL; int len; + if (in == NULL) + return NULL; len = asn1_d2i_read_bio(in, &b); if (len < 0) goto err; p = (const unsigned char *)b->data; - ret = ASN1_item_d2i(x, &p, len, it); + ret = ASN1_item_d2i_ex(x, &p, len, it, libctx, propq); err: BUF_MEM_free(b); return ret; } +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) +{ + return ASN1_item_d2i_bio_ex(it, in, x, NULL, NULL); +} + #ifndef OPENSSL_NO_STDIO -void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) +void *ASN1_item_d2i_fp_ex(const ASN1_ITEM *it, FILE *in, void *x, + OSSL_LIB_CTX *libctx, const char *propq) { BIO *b; char *ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_D2I_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); return NULL; } BIO_set_fp(b, in, BIO_NOCLOSE); - ret = ASN1_item_d2i_bio(it, b, x); + ret = ASN1_item_d2i_bio_ex(it, b, x, libctx, propq); BIO_free(b); return ret; } + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) +{ + return ASN1_item_d2i_fp_ex(it, in, x, NULL, NULL); +} #endif #define HEADER_SIZE 8 @@ -100,6 +115,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) uint32_t eos = 0; size_t off = 0; size_t len = 0; + size_t diff; const unsigned char *q; long slen; @@ -107,27 +123,28 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) b = BUF_MEM_new(); if (b == NULL) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } - ERR_clear_error(); + ERR_set_mark(); for (;;) { - if (want >= (len - off)) { - want -= (len - off); + diff = len - off; + if (want >= diff) { + want -= diff; if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } i = BIO_read(in, &(b->data[len]), want); - if ((i < 0) && ((len - off) == 0)) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA); + if (i < 0 && diff == 0) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA); goto err; } if (i > 0) { if (len + i < len) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG); goto err; } len += i; @@ -137,15 +154,17 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) p = (unsigned char *)&(b->data[off]); q = p; - inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off); + diff = len - off; + if (diff == 0) + goto err; + inf = ASN1_get_object(&q, &slen, &tag, &xclass, diff); if (inf & 0x80) { unsigned long e; - e = ERR_GET_REASON(ERR_peek_error()); + e = ERR_GET_REASON(ERR_peek_last_error()); if (e != ASN1_R_TOO_LONG) goto err; - else - ERR_clear_error(); /* clear error */ + ERR_pop_to_mark(); } i = q - p; /* header length */ off += i; /* end of data */ @@ -153,7 +172,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) if (inf & 1) { /* no data body so go round again */ if (eos == UINT32_MAX) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG); goto err; } eos++; @@ -174,7 +193,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) want -= (len - off); if (want > INT_MAX /* BIO_read takes an int length */ || len + want < len) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG); goto err; } while (want > 0) { @@ -187,15 +206,14 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) size_t chunk = want > chunk_max ? chunk_max : want; if (!BUF_MEM_grow_clean(b, len + chunk)) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } want -= chunk; while (chunk > 0) { i = BIO_read(in, &(b->data[len]), chunk); if (i <= 0) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, - ASN1_R_NOT_ENOUGH_DATA); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA); goto err; } /* @@ -210,7 +228,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) } } if (off + slen < off) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG); goto err; } off += slen; @@ -222,13 +240,14 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) } if (off > INT_MAX) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG); goto err; } *pb = b; return off; err: + ERR_clear_last_mark(); BUF_MEM_free(b); return -1; } diff --git a/crypto/openssl/crypto/asn1/a_digest.c b/crypto/openssl/crypto/asn1/a_digest.c index cc3532ea7df2..72cc8807799d 100644 --- a/crypto/openssl/crypto/asn1/a_digest.c +++ b/crypto/openssl/crypto/asn1/a_digest.c @@ -1,24 +1,29 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include #include "internal/cryptlib.h" +#include #include #include #include #include +#include "crypto/x509.h" -#ifndef NO_ASN1_OLD +#ifndef OPENSSL_NO_DEPRECATED_3_0 int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, unsigned char *md, unsigned int *len) @@ -28,11 +33,11 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, inl = i2d(data, NULL); if (inl <= 0) { - ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR); return 0; } if ((str = OPENSSL_malloc(inl)) == NULL) { - ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } p = str; @@ -48,20 +53,42 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, #endif -int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, - unsigned char *md, unsigned int *len) +int ossl_asn1_item_digest_ex(const ASN1_ITEM *it, const EVP_MD *md, void *asn, + unsigned char *data, unsigned int *len, + OSSL_LIB_CTX *libctx, const char *propq) { - int i; + int i, ret = 0; unsigned char *str = NULL; + EVP_MD *fetched_md = (EVP_MD *)md; i = ASN1_item_i2d(asn, &str, it); - if (!str) + if (i < 0 || str == NULL) return 0; - if (!EVP_Digest(str, i, md, len, type, NULL)) { - OPENSSL_free(str); - return 0; + if (EVP_MD_get0_provider(md) == NULL) { +#if !defined(OPENSSL_NO_ENGINE) + ENGINE *tmpeng = ENGINE_get_digest_engine(EVP_MD_get_type(md)); + + if (tmpeng != NULL) + ENGINE_finish(tmpeng); + else +#endif + fetched_md = EVP_MD_fetch(libctx, EVP_MD_get0_name(md), propq); } + if (fetched_md == NULL) + goto err; + + ret = EVP_Digest(str, i, data, len, fetched_md, NULL); +err: OPENSSL_free(str); - return 1; + if (fetched_md != md) + EVP_MD_free(fetched_md); + return ret; } + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *md, void *asn, + unsigned char *data, unsigned int *len) +{ + return ossl_asn1_item_digest_ex(it, md, asn, data, len, NULL, NULL); +} + diff --git a/crypto/openssl/crypto/asn1/a_dup.c b/crypto/openssl/crypto/asn1/a_dup.c index 50af6b000609..93e8b2aa8dab 100644 --- a/crypto/openssl/crypto/asn1/a_dup.c +++ b/crypto/openssl/crypto/asn1/a_dup.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,11 +9,11 @@ #include #include "internal/cryptlib.h" -#include +#include #ifndef NO_OLD_ASN1 -void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x) +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x) { unsigned char *b, *p; const unsigned char *p2; @@ -24,9 +24,12 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x) return NULL; i = i2d(x, NULL); + if (i <= 0) + return NULL; + b = OPENSSL_malloc(i + 10); if (b == NULL) { - ASN1err(ASN1_F_ASN1_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } p = b; @@ -46,23 +49,49 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x) * decode. */ -void *ASN1_item_dup(const ASN1_ITEM *it, void *x) +void *ASN1_item_dup(const ASN1_ITEM *it, const void *x) { + ASN1_aux_cb *asn1_cb = NULL; unsigned char *b = NULL; const unsigned char *p; long i; - void *ret; + ASN1_VALUE *ret; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; if (x == NULL) return NULL; + if (it->itype == ASN1_ITYPE_SEQUENCE || it->itype == ASN1_ITYPE_CHOICE + || it->itype == ASN1_ITYPE_NDEF_SEQUENCE) { + const ASN1_AUX *aux = it->funcs; + + asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + } + + if (asn1_cb != NULL) { + if (!asn1_cb(ASN1_OP_DUP_PRE, (ASN1_VALUE **)&x, it, NULL) + || !asn1_cb(ASN1_OP_GET0_LIBCTX, (ASN1_VALUE **)&x, it, &libctx) + || !asn1_cb(ASN1_OP_GET0_PROPQ, (ASN1_VALUE **)&x, it, &propq)) + goto auxerr; + } + i = ASN1_item_i2d(x, &b, it); if (b == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } p = b; - ret = ASN1_item_d2i(NULL, &p, i, it); + ret = ASN1_item_d2i_ex(NULL, &p, i, it, libctx, propq); OPENSSL_free(b); + + if (asn1_cb != NULL + && !asn1_cb(ASN1_OP_DUP_POST, &ret, it, (void *)x)) + goto auxerr; + return ret; + + auxerr: + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_AUX_ERROR, "Type=%s", it->sname); + return NULL; } diff --git a/crypto/openssl/crypto/asn1/a_gentm.c b/crypto/openssl/crypto/asn1/a_gentm.c index 133bbb1581cb..0c06ac3c4163 100644 --- a/crypto/openssl/crypto/asn1/a_gentm.c +++ b/crypto/openssl/crypto/asn1/a_gentm.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -16,14 +16,18 @@ #include "internal/cryptlib.h" #include #include "asn1_local.h" +#include + +IMPLEMENT_ASN1_DUP_FUNCTION(ASN1_GENERALIZEDTIME) /* This is the primary function used to parse ASN1_GENERALIZEDTIME */ -int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) +static int asn1_generalizedtime_to_tm(struct tm *tm, + const ASN1_GENERALIZEDTIME *d) { - /* wrapper around asn1_time_to_tm */ + /* wrapper around ossl_asn1_time_to_tm */ if (d->type != V_ASN1_GENERALIZEDTIME) return 0; - return asn1_time_to_tm(tm, d); + return ossl_asn1_time_to_tm(tm, d); } int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d) @@ -71,7 +75,7 @@ ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, return NULL; } - return asn1_time_from_tm(s, ts, V_ASN1_GENERALIZEDTIME); + return ossl_asn1_time_from_tm(s, ts, V_ASN1_GENERALIZEDTIME); } int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm) diff --git a/crypto/openssl/crypto/asn1/a_i2d_fp.c b/crypto/openssl/crypto/asn1/a_i2d_fp.c index 980c65a25d2d..4cc4773666c4 100644 --- a/crypto/openssl/crypto/asn1/a_i2d_fp.c +++ b/crypto/openssl/crypto/asn1/a_i2d_fp.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,13 +15,13 @@ #ifndef NO_OLD_ASN1 # ifndef OPENSSL_NO_STDIO -int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x) +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, const void *x) { BIO *b; int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - ASN1err(ASN1_F_ASN1_I2D_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, out, BIO_NOCLOSE); @@ -31,7 +31,7 @@ int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x) } # endif -int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x) +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, const void *x) { char *b; unsigned char *p; @@ -43,7 +43,7 @@ int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x) b = OPENSSL_malloc(n); if (b == NULL) { - ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } @@ -68,13 +68,13 @@ int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x) #endif #ifndef OPENSSL_NO_STDIO -int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, const void *x) { BIO *b; int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_I2D_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, out, BIO_NOCLOSE); @@ -84,14 +84,14 @@ int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) } #endif -int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, const void *x) { unsigned char *b = NULL; int i, j = 0, n, ret = 1; n = ASN1_item_i2d(x, &b, it); if (b == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } @@ -109,3 +109,21 @@ int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) OPENSSL_free(b); return ret; } + +BIO *ASN1_item_i2d_mem_bio(const ASN1_ITEM *it, const ASN1_VALUE *val) +{ + BIO *res; + + if (it == NULL || val == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if ((res = BIO_new(BIO_s_mem())) == NULL) + return NULL; + if (ASN1_item_i2d_bio(it, res, val) <= 0) { + BIO_free(res); + res = NULL; + } + return res; +} diff --git a/crypto/openssl/crypto/asn1/a_int.c b/crypto/openssl/crypto/asn1/a_int.c index 9c1a9f52b5e6..19e41ec73e35 100644 --- a/crypto/openssl/crypto/asn1/a_int.c +++ b/crypto/openssl/crypto/asn1/a_int.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -79,8 +79,14 @@ static void twos_complement(unsigned char *dst, const unsigned char *src, unsigned int carry = pad & 1; /* Begin at the end of the encoding */ - dst += len; - src += len; + if (len != 0) { + /* + * if len == 0 then src/dst could be NULL, and this would be undefined + * behaviour. + */ + dst += len; + src += len; + } /* two's complement value: ~value + 1 */ while (len-- != 0) { *(--dst) = (unsigned char)(carry += *(--src) ^ pad); @@ -151,7 +157,7 @@ static size_t c2i_ibuf(unsigned char *b, int *pneg, int neg, pad; /* Zero content length is illegal */ if (plen == 0) { - ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_ZERO_CONTENT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT); return 0; } neg = p[0] & 0x80; @@ -184,7 +190,7 @@ static size_t c2i_ibuf(unsigned char *b, int *pneg, } /* reject illegal padding: first two octets MSB can't match */ if (pad && (neg == (p[1] & 0x80))) { - ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_PADDING); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_PADDING); return 0; } @@ -198,7 +204,7 @@ static size_t c2i_ibuf(unsigned char *b, int *pneg, return plen; } -int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) +int ossl_i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) { return i2c_ibuf(a->data, a->length, a->type & V_ASN1_NEG, pp); } @@ -210,7 +216,7 @@ static int asn1_get_uint64(uint64_t *pr, const unsigned char *b, size_t blen) uint64_t r; if (blen > sizeof(*pr)) { - ASN1err(ASN1_F_ASN1_GET_UINT64, ASN1_R_TOO_LARGE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE); return 0; } if (b == NULL) @@ -262,14 +268,14 @@ static int asn1_get_int64(int64_t *pr, const unsigned char *b, size_t blen, * on ones'-complement system. */ *pr = (int64_t)(0 - r); } else { - ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_SMALL); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL); return 0; } } else { if (r <= INT64_MAX) { *pr = (int64_t)r; } else { - ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_LARGE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE); return 0; } } @@ -277,8 +283,8 @@ static int asn1_get_int64(int64_t *pr, const unsigned char *b, size_t blen, } /* Convert ASN1 INTEGER content octets to ASN1_INTEGER structure */ -ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, - long len) +ASN1_INTEGER *ossl_c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long len) { ASN1_INTEGER *ret = NULL; size_t r; @@ -302,16 +308,18 @@ ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, c2i_ibuf(ret->data, &neg, *pp, len); - if (neg) + if (neg != 0) ret->type |= V_ASN1_NEG; + else + ret->type &= ~V_ASN1_NEG; *pp += len; if (a != NULL) (*a) = ret; return ret; err: - ASN1err(ASN1_F_C2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); - if ((a == NULL) || (*a != ret)) + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (a == NULL || *a != ret) ASN1_INTEGER_free(ret); return NULL; } @@ -319,11 +327,11 @@ ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, static int asn1_string_get_int64(int64_t *pr, const ASN1_STRING *a, int itype) { if (a == NULL) { - ASN1err(ASN1_F_ASN1_STRING_GET_INT64, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER); return 0; } if ((a->type & ~V_ASN1_NEG) != itype) { - ASN1err(ASN1_F_ASN1_STRING_GET_INT64, ASN1_R_WRONG_INTEGER_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_WRONG_INTEGER_TYPE); return 0; } return asn1_get_int64(pr, a->data, a->length, a->type & V_ASN1_NEG); @@ -354,15 +362,15 @@ static int asn1_string_get_uint64(uint64_t *pr, const ASN1_STRING *a, int itype) { if (a == NULL) { - ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER); return 0; } if ((a->type & ~V_ASN1_NEG) != itype) { - ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ASN1_R_WRONG_INTEGER_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_WRONG_INTEGER_TYPE); return 0; } if (a->type & V_ASN1_NEG) { - ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ASN1_R_ILLEGAL_NEGATIVE_VALUE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_NEGATIVE_VALUE); return 0; } return asn1_get_uint64(pr, a->data, a->length); @@ -390,7 +398,7 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, ASN1_INTEGER *ret = NULL; const unsigned char *p; unsigned char *s; - long len; + long len = 0; int inf, tag, xclass; int i; @@ -413,6 +421,10 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, goto err; } + if (len < 0) { + i = ASN1_R_ILLEGAL_NEGATIVE_VALUE; + goto err; + } /* * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies * a missing NULL parameter. @@ -440,7 +452,7 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, *pp = p; return ret; err: - ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i); + ERR_raise(ERR_LIB_ASN1, i); if ((a == NULL) || (*a != ret)) ASN1_INTEGER_free(ret); return NULL; @@ -460,7 +472,7 @@ static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai, } if (ret == NULL) { - ASN1err(ASN1_F_BN_TO_ASN1_STRING, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; } @@ -473,7 +485,7 @@ static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai, len = 1; if (ASN1_STRING_set(ret, NULL, len) == 0) { - ASN1err(ASN1_F_BN_TO_ASN1_STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } @@ -496,13 +508,13 @@ static BIGNUM *asn1_string_to_bn(const ASN1_INTEGER *ai, BIGNUM *bn, BIGNUM *ret; if ((ai->type & ~V_ASN1_NEG) != itype) { - ASN1err(ASN1_F_ASN1_STRING_TO_BN, ASN1_R_WRONG_INTEGER_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_WRONG_INTEGER_TYPE); return NULL; } ret = BN_bin2bn(ai->data, ai->length, bn); if (ret == NULL) { - ASN1err(ASN1_F_ASN1_STRING_TO_BN, ASN1_R_BN_LIB); + ERR_raise(ERR_LIB_ASN1, ASN1_R_BN_LIB); return NULL; } if (ai->type & V_ASN1_NEG) @@ -603,7 +615,8 @@ BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn) } /* Internal functions used by x_int64.c */ -int c2i_uint64_int(uint64_t *ret, int *neg, const unsigned char **pp, long len) +int ossl_c2i_uint64_int(uint64_t *ret, int *neg, + const unsigned char **pp, long len) { unsigned char buf[sizeof(uint64_t)]; size_t buflen; @@ -612,14 +625,14 @@ int c2i_uint64_int(uint64_t *ret, int *neg, const unsigned char **pp, long len) if (buflen == 0) return 0; if (buflen > sizeof(uint64_t)) { - ASN1err(ASN1_F_C2I_UINT64_INT, ASN1_R_TOO_LARGE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE); return 0; } (void)c2i_ibuf(buf, neg, *pp, len); return asn1_get_uint64(ret, buf, buflen); } -int i2c_uint64_int(unsigned char *p, uint64_t r, int neg) +int ossl_i2c_uint64_int(unsigned char *p, uint64_t r, int neg) { unsigned char buf[sizeof(uint64_t)]; size_t off; diff --git a/crypto/openssl/crypto/asn1/a_mbstr.c b/crypto/openssl/crypto/asn1/a_mbstr.c index bdb697ab30c1..22dea873eeba 100644 --- a/crypto/openssl/crypto/asn1/a_mbstr.c +++ b/crypto/openssl/crypto/asn1/a_mbstr.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,6 +10,7 @@ #include #include "crypto/ctype.h" #include "internal/cryptlib.h" +#include "internal/unicode.h" #include static int traverse_string(const unsigned char *p, int len, int inform, @@ -49,20 +50,20 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, ASN1_STRING *dest; unsigned char *p; int nchar; - char strbuf[32]; int (*cpyfunc) (unsigned long, void *) = NULL; if (len == -1) len = strlen((const char *)in); if (!mask) mask = DIRSTRING_TYPE; + if (len < 0) + return -1; /* First do a string check and work out the number of characters */ switch (inform) { case MBSTRING_BMP: if (len & 1) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, - ASN1_R_INVALID_BMPSTRING_LENGTH); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH); return -1; } nchar = len >> 1; @@ -70,8 +71,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, case MBSTRING_UNIV: if (len & 3) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, - ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); return -1; } nchar = len >> 2; @@ -82,7 +82,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, /* This counts the characters and does utf8 syntax checking */ ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar); if (ret < 0) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_UTF8STRING); return -1; } break; @@ -92,27 +92,25 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, break; default: - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT); return -1; } if ((minsize > 0) && (nchar < minsize)) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT); - BIO_snprintf(strbuf, sizeof(strbuf), "%ld", minsize); - ERR_add_error_data(2, "minsize=", strbuf); + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_STRING_TOO_SHORT, + "minsize=%ld", minsize); return -1; } if ((maxsize > 0) && (nchar > maxsize)) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG); - BIO_snprintf(strbuf, sizeof(strbuf), "%ld", maxsize); - ERR_add_error_data(2, "maxsize=", strbuf); + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG, + "maxsize=%ld", maxsize); return -1; } /* Now work out minimal type (if any) */ if (traverse_string(in, len, inform, type_str, &mask) < 0) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_CHARACTERS); return -1; } @@ -149,7 +147,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, free_out = 1; dest = ASN1_STRING_type_new(str_type); if (dest == NULL) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } *out = dest; @@ -157,7 +155,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, /* If both the same type just copy across */ if (inform == outform) { if (!ASN1_STRING_set(dest, in, len)) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } return str_type; @@ -189,7 +187,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, if ((p = OPENSSL_malloc(outlen + 1)) == NULL) { if (free_out) ASN1_STRING_free(dest); - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } dest->length = outlen; @@ -247,6 +245,9 @@ static int traverse_string(const unsigned char *p, int len, int inform, static int in_utf8(unsigned long value, void *arg) { int *nchar; + + if (!is_unicode_valid(value)) + return -2; nchar = arg; (*nchar)++; return 1; @@ -256,9 +257,13 @@ static int in_utf8(unsigned long value, void *arg) static int out_utf8(unsigned long value, void *arg) { - int *outlen; + int *outlen, len; + + len = UTF8_putc(NULL, -1, value); + if (len <= 0) + return len; outlen = arg; - *outlen += UTF8_putc(NULL, -1, value); + *outlen += len; return 1; } @@ -283,6 +288,8 @@ static int type_str(unsigned long value, void *arg) types &= ~B_ASN1_T61STRING; if ((types & B_ASN1_BMPSTRING) && (value > 0xffff)) types &= ~B_ASN1_BMPSTRING; + if ((types & B_ASN1_UTF8STRING) && !is_unicode_valid(value)) + types &= ~B_ASN1_UTF8STRING; if (!types) return -1; *((unsigned long *)arg) = types; diff --git a/crypto/openssl/crypto/asn1/a_object.c b/crypto/openssl/crypto/asn1/a_object.c index 8ade9e50a7cb..c96c36e73029 100644 --- a/crypto/openssl/crypto/asn1/a_object.c +++ b/crypto/openssl/crypto/asn1/a_object.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -32,7 +32,7 @@ int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp) if (*pp == NULL) { if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) { - ASN1err(ASN1_F_I2D_ASN1_OBJECT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } } else { @@ -70,12 +70,12 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) if ((c >= '0') && (c <= '2')) { first = c - '0'; } else { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_FIRST_NUM_TOO_LARGE); goto err; } if (num <= 0) { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MISSING_SECOND_NUMBER); goto err; } c = *(p++); @@ -84,7 +84,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) if (num <= 0) break; if ((c != '.') && (c != ' ')) { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_SEPARATOR); goto err; } l = 0; @@ -97,7 +97,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) if ((c == ' ') || (c == '.')) break; if (!ossl_isdigit(c)) { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_DIGIT); goto err; } if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) { @@ -116,8 +116,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) } if (len == 0) { if ((first < 2) && (l >= 40)) { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, - ASN1_R_SECOND_NUMBER_TOO_LARGE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE); goto err; } if (use_bn) { @@ -136,8 +135,10 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) OPENSSL_free(tmp); tmpsize = blsize + 32; tmp = OPENSSL_malloc(tmpsize); - if (tmp == NULL) + if (tmp == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; + } } while (blsize--) { BN_ULONG t = BN_div_word(bl, 0x80L); @@ -157,7 +158,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) } if (out != NULL) { if (len + i > olen) { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_ASN1, ASN1_R_BUFFER_TOO_SMALL); goto err; } while (--i > 0) @@ -191,8 +192,12 @@ int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) return BIO_write(bp, "NULL", 4); i = i2t_ASN1_OBJECT(buf, sizeof(buf), a); if (i > (int)(sizeof(buf) - 1)) { + if (i > INT_MAX - 1) { /* catch an integer overflow */ + ERR_raise(ERR_LIB_ASN1, ASN1_R_LENGTH_TOO_LONG); + return -1; + } if ((p = OPENSSL_malloc(i + 1)) == NULL) { - ASN1err(ASN1_F_I2A_ASN1_OBJECT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } i2t_ASN1_OBJECT(p, i + 1, a); @@ -227,17 +232,17 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, i = ASN1_R_EXPECTING_AN_OBJECT; goto err; } - ret = c2i_ASN1_OBJECT(a, &p, len); + ret = ossl_c2i_ASN1_OBJECT(a, &p, len); if (ret) *pp = p; return ret; err: - ASN1err(ASN1_F_D2I_ASN1_OBJECT, i); + ERR_raise(ERR_LIB_ASN1, i); return NULL; } -ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, - long len) +ASN1_OBJECT *ossl_c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long len) { ASN1_OBJECT *ret = NULL, tobj; const unsigned char *p; @@ -251,7 +256,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, */ if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL || p[len - 1] & 0x80) { - ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_OBJECT_ENCODING); return NULL; } /* Now 0 < len <= INT_MAX, so the cast is safe. */ @@ -281,7 +286,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, } for (i = 0; i < length; i++, p++) { if (*p == 0x80 && (!i || !(p[-1] & 0x80))) { - ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_OBJECT_ENCODING); return NULL; } } @@ -329,7 +334,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, *pp = p; return ret; err: - ASN1err(ASN1_F_C2I_ASN1_OBJECT, i); + ERR_raise(ERR_LIB_ASN1, i); if ((a == NULL) || (*a != ret)) ASN1_OBJECT_free(ret); return NULL; @@ -341,7 +346,7 @@ ASN1_OBJECT *ASN1_OBJECT_new(void) ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } ret->flags = ASN1_OBJECT_FLAG_DYNAMIC; @@ -353,9 +358,11 @@ void ASN1_OBJECT_free(ASN1_OBJECT *a) if (a == NULL) return; if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { -#ifndef CONST_STRICT /* disable purely for compile-time strict - * const checking. Doing this on a "real" - * compile will cause memory leaks */ +#ifndef CONST_STRICT + /* + * Disable purely for compile-time strict const checking. Doing this + * on a "real" compile will cause memory leaks + */ OPENSSL_free((void*)a->sn); OPENSSL_free((void*)a->ln); #endif diff --git a/crypto/openssl/crypto/asn1/a_octet.c b/crypto/openssl/crypto/asn1/a_octet.c index 2e1205caea00..fcb2ef0a7d08 100644 --- a/crypto/openssl/crypto/asn1/a_octet.c +++ b/crypto/openssl/crypto/asn1/a_octet.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/asn1/a_print.c b/crypto/openssl/crypto/asn1/a_print.c index 3790e82bb13a..d2768f74bdcd 100644 --- a/crypto/openssl/crypto/asn1/a_print.c +++ b/crypto/openssl/crypto/asn1/a_print.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/asn1/a_sign.c b/crypto/openssl/crypto/asn1/a_sign.c index 72381b665551..302045cfcdfa 100644 --- a/crypto/openssl/crypto/asn1/a_sign.c +++ b/crypto/openssl/crypto/asn1/a_sign.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -18,10 +18,11 @@ #include #include #include +#include #include "crypto/asn1.h" #include "crypto/evp.h" -#ifndef NO_ASN1_OLD +#ifndef OPENSSL_NO_DEPRECATED_3_0 int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, @@ -34,7 +35,7 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, X509_ALGOR *a; if (ctx == NULL) { - ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } for (i = 0; i < 2; i++) { @@ -61,27 +62,27 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_OBJECT_free(a->algorithm); a->algorithm = OBJ_nid2obj(type->pkey_type); if (a->algorithm == NULL) { - ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_OBJECT_TYPE); goto err; } if (a->algorithm->length == 0) { - ASN1err(ASN1_F_ASN1_SIGN, - ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); + ERR_raise(ERR_LIB_ASN1, + ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); goto err; } } inl = i2d(data, NULL); if (inl <= 0) { - ASN1err(ASN1_F_ASN1_SIGN, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR); goto err; } inll = (size_t)inl; buf_in = OPENSSL_malloc(inll); - outll = outl = EVP_PKEY_size(pkey); + outll = outl = EVP_PKEY_get_size(pkey); buf_out = OPENSSL_malloc(outll); if (buf_in == NULL || buf_out == NULL) { outl = 0; - ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } p = buf_in; @@ -92,7 +93,7 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, || !EVP_SignFinal(ctx, (unsigned char *)buf_out, (unsigned int *)&outl, pkey)) { outl = 0; - ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } OPENSSL_free(signature->data); @@ -114,54 +115,104 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, #endif -int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, - EVP_PKEY *pkey, const EVP_MD *type) +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, const void *data, + EVP_PKEY *pkey, const EVP_MD *md) { - int rv; - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + return ASN1_item_sign_ex(it, algor1, algor2, signature, data, NULL, pkey, + md, NULL, NULL); +} + +int ASN1_item_sign_ex(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + const void *data, const ASN1_OCTET_STRING *id, + EVP_PKEY *pkey, const EVP_MD *md, OSSL_LIB_CTX *libctx, + const char *propq) +{ + int rv = 0; + EVP_MD_CTX *ctx = evp_md_ctx_new_ex(pkey, id, libctx, propq); if (ctx == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_SIGN, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!EVP_DigestSignInit(ctx, NULL, type, NULL, pkey)) { - EVP_MD_CTX_free(ctx); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } + /* We can use the non _ex variant here since the pkey is already setup */ + if (!EVP_DigestSignInit(ctx, NULL, md, NULL, pkey)) + goto err; - rv = ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, ctx); + rv = ASN1_item_sign_ctx(it, algor1, algor2, signature, data, ctx); + err: + EVP_PKEY_CTX_free(EVP_MD_CTX_get_pkey_ctx(ctx)); EVP_MD_CTX_free(ctx); return rv; } -int ASN1_item_sign_ctx(const ASN1_ITEM *it, - X509_ALGOR *algor1, X509_ALGOR *algor2, - ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) +int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + const void *data, EVP_MD_CTX *ctx) { - const EVP_MD *type; + const EVP_MD *md; EVP_PKEY *pkey; unsigned char *buf_in = NULL, *buf_out = NULL; size_t inl = 0, outl = 0, outll = 0; int signid, paramtype, buf_len = 0; - int rv; + int rv, pkey_id; - type = EVP_MD_CTX_md(ctx); - pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); + md = EVP_MD_CTX_get0_md(ctx); + pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx)); if (pkey == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); + ERR_raise(ERR_LIB_ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); goto err; } if (pkey->ameth == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); - goto err; - } + EVP_PKEY_CTX *pctx = EVP_MD_CTX_get_pkey_ctx(ctx); + OSSL_PARAM params[2]; + unsigned char aid[128]; + size_t aid_len = 0; + + if (pctx == NULL + || !EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); + goto err; + } - if (pkey->ameth->item_sign) { - rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature); + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, + aid, sizeof(aid)); + params[1] = OSSL_PARAM_construct_end(); + + if (EVP_PKEY_CTX_get_params(pctx, params) <= 0) + goto err; + + if ((aid_len = params[0].return_size) == 0) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + goto err; + } + + if (algor1 != NULL) { + const unsigned char *pp = aid; + + if (d2i_X509_ALGOR(&algor1, &pp, aid_len) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (algor2 != NULL) { + const unsigned char *pp = aid; + + if (d2i_X509_ALGOR(&algor2, &pp, aid_len) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + rv = 3; + } else if (pkey->ameth->item_sign) { + rv = pkey->ameth->item_sign(ctx, it, data, algor1, algor2, signature); if (rv == 1) outl = signature->length; /*- @@ -172,7 +223,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, * 3: ASN1 method sets algorithm identifiers: just sign. */ if (rv <= 0) - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); if (rv <= 1) goto err; } else { @@ -180,15 +231,19 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, } if (rv == 2) { - if (type == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); + if (md == NULL) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); goto err; } - if (!OBJ_find_sigid_by_algs(&signid, - EVP_MD_nid(type), - pkey->ameth->pkey_id)) { - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, - ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + + pkey_id = +#ifndef OPENSSL_NO_SM2 + EVP_PKEY_get_id(pkey) == NID_sm2 ? NID_sm2 : +#endif + pkey->ameth->pkey_id; + + if (!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(md), pkey_id)) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); goto err; } @@ -204,24 +259,29 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, } - buf_len = ASN1_item_i2d(asn, &buf_in, it); + buf_len = ASN1_item_i2d(data, &buf_in, it); if (buf_len <= 0) { outl = 0; - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR); goto err; } inl = buf_len; - outll = outl = EVP_PKEY_size(pkey); + if (!EVP_DigestSign(ctx, NULL, &outll, buf_in, inl)) { + outl = 0; + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); + goto err; + } + outl = outll; buf_out = OPENSSL_malloc(outll); if (buf_in == NULL || buf_out == NULL) { outl = 0; - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_DigestSign(ctx, buf_out, &outl, buf_in, inl)) { outl = 0; - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } OPENSSL_free(signature->data); diff --git a/crypto/openssl/crypto/asn1/a_strex.c b/crypto/openssl/crypto/asn1/a_strex.c index 284dde274c9f..b31761aae6f5 100644 --- a/crypto/openssl/crypto/asn1/a_strex.c +++ b/crypto/openssl/crypto/asn1/a_strex.c @@ -1,7 +1,7 @@ /* * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -32,7 +32,7 @@ ASN1_STRFLGS_ESC_MSB) /* - * Three IO functions for sending data to memory, a BIO and and a FILE + * Three IO functions for sending data to memory, a BIO and a FILE * pointer. */ static int send_bio_chars(void *arg, const void *buf, int len) @@ -152,13 +152,13 @@ static int do_buf(unsigned char *buf, int buflen, switch (charwidth) { case 4: if (buflen & 3) { - ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); return -1; } break; case 2: if (buflen & 1) { - ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_BMPSTRING_LENGTH); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH); return -1; } break; @@ -283,7 +283,7 @@ static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, if (der_len <= 0) return -1; if ((der_buf = OPENSSL_malloc(der_len)) == NULL) { - ASN1err(ASN1_F_DO_DUMP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } p = der_buf; diff --git a/crypto/openssl/crypto/asn1/a_strnid.c b/crypto/openssl/crypto/asn1/a_strnid.c index f19a9de647b1..9e54db929282 100644 --- a/crypto/openssl/crypto/asn1/a_strnid.c +++ b/crypto/openssl/crypto/asn1/a_strnid.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -51,7 +51,7 @@ int ASN1_STRING_set_default_mask_asc(const char *p) char *end; if (strncmp(p, "MASK:", 5) == 0) { - if (!p[5]) + if (p[5] == '\0') return 0; mask = strtoul(p + 5, &end, 0); if (*end) @@ -129,6 +129,9 @@ ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid) int idx; ASN1_STRING_TABLE fnd; + /* "stable" can be impacted by config, so load the config file first */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + fnd.nid = nid; if (stable) { idx = sk_ASN1_STRING_TABLE_find(stable, &fnd); @@ -157,7 +160,7 @@ static ASN1_STRING_TABLE *stable_get(int nid) if (tmp != NULL && tmp->flags & STABLE_FLAGS_MALLOC) return tmp; if ((rv = OPENSSL_zalloc(sizeof(*rv))) == NULL) { - ASN1err(ASN1_F_STABLE_GET, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } if (!sk_ASN1_STRING_TABLE_push(stable, rv)) { @@ -187,7 +190,7 @@ int ASN1_STRING_TABLE_add(int nid, tmp = stable_get(nid); if (tmp == NULL) { - ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } if (minsize >= 0) diff --git a/crypto/openssl/crypto/asn1/a_time.c b/crypto/openssl/crypto/asn1/a_time.c index 54e0de1931c2..9b3074e47e84 100644 --- a/crypto/openssl/crypto/asn1/a_time.c +++ b/crypto/openssl/crypto/asn1/a_time.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -16,6 +16,7 @@ #include #include +#include "crypto/asn1.h" #include "crypto/ctype.h" #include "internal/cryptlib.h" #include @@ -24,6 +25,7 @@ IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME) IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME) +IMPLEMENT_ASN1_DUP_FUNCTION(ASN1_TIME) static int is_utc(const int year) { @@ -71,7 +73,7 @@ static void determine_days(struct tm *tm) tm->tm_wday = (d + (13 * m) / 5 + y + y / 4 + c / 4 + 5 * c + 6) % 7; } -int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) +int ossl_asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) { static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 }; static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 }; @@ -128,14 +130,14 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) i++; break; } - if (!ascii_isdigit(a[o])) + if (!ossl_ascii_isdigit(a[o])) goto err; n = a[o] - num_zero; /* incomplete 2-digital number */ if (++o == l) goto err; - if (!ascii_isdigit(a[o])) + if (!ossl_ascii_isdigit(a[o])) goto err; n = (n * 10) + a[o] - num_zero; /* no more bytes to read, but we haven't seen time-zone yet */ @@ -196,7 +198,7 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) if (++o == l) goto err; i = o; - while ((o < l) && ascii_isdigit(a[o])) + while ((o < l) && ossl_ascii_isdigit(a[o])) o++; /* Must have at least one digit after decimal point */ if (i == o) @@ -227,11 +229,11 @@ 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 (!ascii_isdigit(a[o])) + if (!ossl_ascii_isdigit(a[o])) goto err; n = a[o] - num_zero; o++; - if (!ascii_isdigit(a[o])) + if (!ossl_ascii_isdigit(a[o])) goto err; n = (n * 10) + a[o] - num_zero; i2 = (d->type == V_ASN1_UTCTIME) ? i + 1 : i; @@ -262,7 +264,7 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) return 0; } -ASN1_TIME *asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type) +ASN1_TIME *ossl_asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type) { char* p; ASN1_TIME *tmps = NULL; @@ -327,14 +329,14 @@ ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, ts = OPENSSL_gmtime(&t, &data); if (ts == NULL) { - ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ERROR_GETTING_TIME); return NULL; } if (offset_day || offset_sec) { if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) return NULL; } - return asn1_time_from_tm(s, ts, V_ASN1_UNDEF); + return ossl_asn1_time_from_tm(s, ts, V_ASN1_UNDEF); } int ASN1_TIME_check(const ASN1_TIME *t) @@ -359,7 +361,7 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, if (out != NULL) ret = *out; - ret = asn1_time_from_tm(ret, &tm, V_ASN1_GENERALIZEDTIME); + ret = ossl_asn1_time_from_tm(ret, &tm, V_ASN1_GENERALIZEDTIME); if (out != NULL && ret != NULL) *out = ret; @@ -408,7 +410,7 @@ int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str) */ if (s != NULL && t.type == V_ASN1_GENERALIZEDTIME) { - if (!asn1_time_to_tm(&tm, &t)) + if (!ossl_asn1_time_to_tm(&tm, &t)) goto out; if (is_utc(tm.tm_year)) { t.length -= 2; @@ -418,8 +420,10 @@ int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str) * new t.data would be freed after ASN1_STRING_copy is done. */ t.data = OPENSSL_zalloc(t.length + 1); - if (t.data == NULL) + if (t.data == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto out; + } memcpy(t.data, str + 2, t.length); t.type = V_ASN1_UTCTIME; } @@ -446,7 +450,7 @@ int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm) return 0; } - return asn1_time_to_tm(tm, s); + return ossl_asn1_time_to_tm(tm, s); } int ASN1_TIME_diff(int *pday, int *psec, @@ -466,17 +470,31 @@ static const char _asn1_mon[12][4] = { "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +/* prints the time with the default date format (RFC 822) */ int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) +{ + return ASN1_TIME_print_ex(bp, tm, ASN1_DTFLGS_RFC822); +} + +/* returns 1 on success, 0 on BIO write error or parse failure */ +int ASN1_TIME_print_ex(BIO *bp, const ASN1_TIME *tm, unsigned long flags) +{ + return ossl_asn1_time_print_ex(bp, tm, flags) > 0; +} + + +/* prints the time with the date format of ISO 8601 */ +/* returns 0 on BIO write error, else -1 in case of parse failure, else 1 */ +int ossl_asn1_time_print_ex(BIO *bp, const ASN1_TIME *tm, unsigned long flags) { 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 */ - goto err; - } + /* ossl_asn1_time_to_tm will check the time type */ + if (!ossl_asn1_time_to_tm(&stm, tm)) + return BIO_write(bp, "Bad time value", 14) ? -1 : 0; l = tm->length; v = (char *)tm->data; @@ -494,23 +512,38 @@ int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) if (tm->length > 15 && v[14] == period) { f = &v[14]; f_len = 1; - while (14 + f_len < l && ascii_isdigit(f[f_len])) + while (14 + f_len < l && ossl_ascii_isdigit(f[f_len])) ++f_len; } - return BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s", + if ((flags & ASN1_DTFLGS_TYPE_MASK) == ASN1_DTFLGS_ISO8601) { + return BIO_printf(bp, "%4d-%02d-%02d %02d:%02d:%02d%.*s%s", + stm.tm_year + 1900, stm.tm_mon + 1, + stm.tm_mday, stm.tm_hour, + stm.tm_min, stm.tm_sec, f_len, f, + (gmt ? "Z" : "")) > 0; + } + else { + return BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s", _asn1_mon[stm.tm_mon], stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec, f_len, f, stm.tm_year + 1900, (gmt ? " GMT" : "")) > 0; + } } else { - return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s", + if ((flags & ASN1_DTFLGS_TYPE_MASK) == ASN1_DTFLGS_ISO8601) { + return BIO_printf(bp, "%4d-%02d-%02d %02d:%02d:%02d%s", + stm.tm_year + 1900, stm.tm_mon + 1, + stm.tm_mday, stm.tm_hour, + stm.tm_min, stm.tm_sec, + (gmt ? "Z" : "")) > 0; + } + else { + return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s", _asn1_mon[stm.tm_mon], stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec, stm.tm_year + 1900, (gmt ? " GMT" : "")) > 0; + } } - err: - BIO_write(bp, "Bad time value", 14); - return 0; } int ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t) @@ -541,7 +574,7 @@ int ASN1_TIME_normalize(ASN1_TIME *t) if (!ASN1_TIME_to_tm(t, &tm)) return 0; - return asn1_time_from_tm(t, &tm, V_ASN1_UNDEF) != NULL; + return ossl_asn1_time_from_tm(t, &tm, V_ASN1_UNDEF) != NULL; } int ASN1_TIME_compare(const ASN1_TIME *a, const ASN1_TIME *b) diff --git a/crypto/openssl/crypto/asn1/a_type.c b/crypto/openssl/crypto/asn1/a_type.c index 4a96315df03b..6b638bd80c18 100644 --- a/crypto/openssl/crypto/asn1/a_type.c +++ b/crypto/openssl/crypto/asn1/a_type.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -29,7 +29,7 @@ void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) && a->type != V_ASN1_NULL && a->value.ptr != NULL) { ASN1_TYPE **tmp_a = &a; - asn1_primitive_free((ASN1_VALUE **)tmp_a, NULL, 0); + ossl_asn1_primitive_free((ASN1_VALUE **)tmp_a, NULL, 0); } a->type = type; if (type == V_ASN1_BOOLEAN) diff --git a/crypto/openssl/crypto/asn1/a_utctm.c b/crypto/openssl/crypto/asn1/a_utctm.c index 0ff37b16c51f..323941ba97e2 100644 --- a/crypto/openssl/crypto/asn1/a_utctm.c +++ b/crypto/openssl/crypto/asn1/a_utctm.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,19 +12,22 @@ #include "internal/cryptlib.h" #include #include "asn1_local.h" +#include + +IMPLEMENT_ASN1_DUP_FUNCTION(ASN1_UTCTIME) /* This is the primary function used to parse ASN1_UTCTIME */ -int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d) +int ossl_asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d) { - /* wrapper around ans1_time_to_tm */ + /* wrapper around ossl_asn1_time_to_tm */ if (d->type != V_ASN1_UTCTIME) return 0; - return asn1_time_to_tm(tm, d); + return ossl_asn1_time_to_tm(tm, d); } int ASN1_UTCTIME_check(const ASN1_UTCTIME *d) { - return asn1_utctime_to_tm(NULL, d); + return ossl_asn1_utctime_to_tm(NULL, d); } /* Sets the string via simple copy without cleaning it up */ @@ -66,7 +69,7 @@ ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, return NULL; } - return asn1_time_from_tm(s, ts, V_ASN1_UTCTIME); + return ossl_asn1_time_from_tm(s, ts, V_ASN1_UTCTIME); } int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t) @@ -74,7 +77,7 @@ int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t) struct tm stm, ttm; int day, sec; - if (!asn1_utctime_to_tm(&stm, s)) + if (!ossl_asn1_utctime_to_tm(&stm, s)) return -2; if (OPENSSL_gmtime(&t, &ttm) == NULL) diff --git a/crypto/openssl/crypto/asn1/a_utf8.c b/crypto/openssl/crypto/asn1/a_utf8.c index e2dc09f6aee5..6572726cf1e5 100644 --- a/crypto/openssl/crypto/asn1/a_utf8.c +++ b/crypto/openssl/crypto/asn1/a_utf8.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,6 +9,7 @@ #include #include "internal/cryptlib.h" +#include "internal/unicode.h" #include /* UTF8 utilities */ @@ -58,6 +59,8 @@ int UTF8_getc(const unsigned char *str, int len, unsigned long *val) value |= *p++ & 0x3f; if (value < 0x800) return -4; + if (is_unicode_surrogate(value)) + return -2; ret = 3; } else if ((*p & 0xf8) == 0xf0) { if (len < 4) @@ -73,40 +76,6 @@ int UTF8_getc(const unsigned char *str, int len, unsigned long *val) if (value < 0x10000) return -4; ret = 4; - } else if ((*p & 0xfc) == 0xf8) { - if (len < 5) - return -1; - if (((p[1] & 0xc0) != 0x80) - || ((p[2] & 0xc0) != 0x80) - || ((p[3] & 0xc0) != 0x80) - || ((p[4] & 0xc0) != 0x80)) - return -3; - value = ((unsigned long)(*p++ & 0x3)) << 24; - value |= ((unsigned long)(*p++ & 0x3f)) << 18; - value |= ((unsigned long)(*p++ & 0x3f)) << 12; - value |= (*p++ & 0x3f) << 6; - value |= *p++ & 0x3f; - if (value < 0x200000) - return -4; - ret = 5; - } else if ((*p & 0xfe) == 0xfc) { - if (len < 6) - return -1; - if (((p[1] & 0xc0) != 0x80) - || ((p[2] & 0xc0) != 0x80) - || ((p[3] & 0xc0) != 0x80) - || ((p[4] & 0xc0) != 0x80) - || ((p[5] & 0xc0) != 0x80)) - return -3; - value = ((unsigned long)(*p++ & 0x1)) << 30; - value |= ((unsigned long)(*p++ & 0x3f)) << 24; - value |= ((unsigned long)(*p++ & 0x3f)) << 18; - value |= ((unsigned long)(*p++ & 0x3f)) << 12; - value |= (*p++ & 0x3f) << 6; - value |= *p++ & 0x3f; - if (value < 0x4000000) - return -4; - ret = 6; } else return -2; *val = value; @@ -116,15 +85,15 @@ int UTF8_getc(const unsigned char *str, int len, unsigned long *val) /* * This takes a character 'value' and writes the UTF8 encoded value in 'str' * where 'str' is a buffer containing 'len' characters. Returns the number of - * characters written or -1 if 'len' is too small. 'str' can be set to NULL - * in which case it just returns the number of characters. It will need at - * most 6 characters. + * characters written, -1 if 'len' is too small or -2 if 'value' is out of + * range. 'str' can be set to NULL in which case it just returns the number of + * characters. It will need at most 4 characters. */ int UTF8_putc(unsigned char *str, int len, unsigned long value) { if (!str) - len = 6; /* Maximum we will need */ + len = 4; /* Maximum we will need */ else if (len <= 0) return -1; if (value < 0x80) { @@ -142,6 +111,8 @@ int UTF8_putc(unsigned char *str, int len, unsigned long value) return 2; } if (value < 0x10000) { + if (is_unicode_surrogate(value)) + return -2; if (len < 3) return -1; if (str) { @@ -151,7 +122,7 @@ int UTF8_putc(unsigned char *str, int len, unsigned long value) } return 3; } - if (value < 0x200000) { + if (value < UNICODE_LIMIT) { if (len < 4) return -1; if (str) { @@ -162,27 +133,5 @@ int UTF8_putc(unsigned char *str, int len, unsigned long value) } return 4; } - if (value < 0x4000000) { - if (len < 5) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8); - *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 5; - } - if (len < 6) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc); - *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 6; + return -2; } diff --git a/crypto/openssl/crypto/asn1/a_verify.c b/crypto/openssl/crypto/asn1/a_verify.c index 4b5f54234fa5..9bf9bdd14ecc 100644 --- a/crypto/openssl/crypto/asn1/a_verify.c +++ b/crypto/openssl/crypto/asn1/a_verify.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,8 +20,9 @@ #include #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/rsa.h" -#ifndef NO_ASN1_OLD +#ifndef OPENSSL_NO_DEPRECATED_3_0 int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey) @@ -32,29 +33,29 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, int ret = -1, i, inl; if (ctx == NULL) { - ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } i = OBJ_obj2nid(a->algorithm); type = EVP_get_digestbyname(OBJ_nid2sn(i)); if (type == NULL) { - ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); goto err; } if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { - ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); goto err; } inl = i2d(data, NULL); if (inl <= 0) { - ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR); goto err; } buf_in = OPENSSL_malloc((unsigned int)inl); if (buf_in == NULL) { - ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } p = buf_in; @@ -66,14 +67,14 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, OPENSSL_clear_free(buf_in, (unsigned int)inl); if (!ret) { - ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } ret = -1; if (EVP_VerifyFinal(ctx, (unsigned char *)signature->data, (unsigned int)signature->length, pkey) <= 0) { - ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); ret = 0; goto err; } @@ -85,81 +86,127 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, #endif -int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, - ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) +int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, + EVP_PKEY *pkey) { - EVP_MD_CTX *ctx = NULL; + return ASN1_item_verify_ex(it, alg, signature, data, NULL, pkey, NULL, NULL); +} + +int ASN1_item_verify_ex(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, + const ASN1_OCTET_STRING *id, EVP_PKEY *pkey, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_MD_CTX *ctx; + int rv = -1; + + if ((ctx = evp_md_ctx_new_ex(pkey, id, libctx, propq)) != NULL) { + rv = ASN1_item_verify_ctx(it, alg, signature, data, ctx); + EVP_PKEY_CTX_free(EVP_MD_CTX_get_pkey_ctx(ctx)); + EVP_MD_CTX_free(ctx); + } + return rv; +} + +int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, + EVP_MD_CTX *ctx) +{ + EVP_PKEY *pkey; unsigned char *buf_in = NULL; int ret = -1, inl = 0; int mdnid, pknid; size_t inll = 0; - if (!pkey) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); + pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx)); + + if (pkey == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER); return -1; } if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); return -1; } - ctx = EVP_MD_CTX_new(); - if (ctx == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - /* Convert signature OID into digest and public key OIDs */ - if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &mdnid, &pknid)) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } - if (mdnid == NID_undef) { - if (!pkey->ameth || !pkey->ameth->item_verify) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, - ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + + if (mdnid == NID_undef && evp_pkey_is_legacy(pkey)) { + if (pkey->ameth == NULL || pkey->ameth->item_verify == NULL) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } - ret = pkey->ameth->item_verify(ctx, it, asn, a, signature, pkey); + ret = pkey->ameth->item_verify(ctx, it, data, alg, signature, pkey); /* - * Return value of 2 means carry on, anything else means we exit - * straight away: either a fatal error of the underlying verification - * routine handles all verification. + * Return values meaning: + * <=0: error. + * 1: method does everything. + * 2: carry on as normal, method has called EVP_DigestVerifyInit() */ - if (ret != 2) + if (ret <= 0) + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); + if (ret <= 1) goto err; - ret = -1; } else { - const EVP_MD *type = EVP_get_digestbynid(mdnid); - - if (type == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, - ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); - goto err; - } - - /* Check public key OID matches public key type */ - if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE); - goto err; - } + const EVP_MD *type = NULL; - if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); - ret = 0; - goto err; + /* + * We don't yet have the ability for providers to be able to handle + * X509_ALGOR style parameters. Fortunately the only one that needs this + * so far is RSA-PSS, so we just special case this for now. In some + * future version of OpenSSL we should push this to the provider. + */ + if (mdnid == NID_undef && pknid == EVP_PKEY_RSA_PSS) { + if (!EVP_PKEY_is_a(pkey, "RSA") && !EVP_PKEY_is_a(pkey, "RSA-PSS")) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE); + goto err; + } + /* This function also calls EVP_DigestVerifyInit */ + if (ossl_rsa_pss_to_ctx(ctx, NULL, alg, pkey) <= 0) { + ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR); + goto err; + } + } else { + /* Check public key OID matches public key type */ + if (!EVP_PKEY_is_a(pkey, OBJ_nid2sn(pknid))) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE); + goto err; + } + + if (mdnid != NID_undef) { + type = EVP_get_digestbynid(mdnid); + if (type == NULL) { + ERR_raise(ERR_LIB_ASN1, + ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + goto err; + } + } + + /* + * Note that some algorithms (notably Ed25519 and Ed448) may allow + * a NULL digest value. + */ + if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) { + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); + ret = 0; + goto err; + } } - } - inl = ASN1_item_i2d(asn, &buf_in, it); + inl = ASN1_item_i2d(data, &buf_in, it); if (inl <= 0) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR); goto err; } if (buf_in == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } inll = inl; @@ -167,12 +214,11 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ret = EVP_DigestVerify(ctx, signature->data, (size_t)signature->length, buf_in, inl); if (ret <= 0) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } ret = 1; err: OPENSSL_clear_free(buf_in, inll); - EVP_MD_CTX_free(ctx); return ret; } diff --git a/crypto/openssl/crypto/asn1/ameth_lib.c b/crypto/openssl/crypto/asn1/ameth_lib.c index 5e8c3ed1d5b0..8b15da3beed6 100644 --- a/crypto/openssl/crypto/asn1/ameth_lib.c +++ b/crypto/openssl/crypto/asn1/ameth_lib.c @@ -1,13 +1,15 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include "e_os.h" /* for strncasecmp */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "internal/cryptlib.h" #include #include @@ -56,6 +58,7 @@ static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type) { EVP_PKEY_ASN1_METHOD tmp; const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret; + tmp.pkey_id = type; if (app_methods) { int idx; @@ -64,7 +67,7 @@ static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type) return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); } ret = OBJ_bsearch_ameth(&t, standard_methods, OSSL_NELEM(standard_methods)); - if (!ret || !*ret) + if (ret == NULL || *ret == NULL) return NULL; return *ret; } @@ -130,7 +133,7 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, if (ameth->pkey_flags & ASN1_PKEY_ALIAS) continue; if ((int)strlen(ameth->pem_str) == len - && strncasecmp(ameth->pem_str, str, len) == 0) + && OPENSSL_strncasecmp(ameth->pem_str, str, len) == 0) return ameth; } return NULL; @@ -152,7 +155,7 @@ int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) && (ameth->pkey_flags & ASN1_PKEY_ALIAS) != 0) || (ameth->pem_str != NULL && (ameth->pkey_flags & ASN1_PKEY_ALIAS) == 0))) { - EVPerr(EVP_F_EVP_PKEY_ASN1_ADD0, ERR_R_PASSED_INVALID_ARGUMENT); + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } @@ -164,8 +167,8 @@ int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) tmp.pkey_id = ameth->pkey_id; if (sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp) >= 0) { - EVPerr(EVP_F_EVP_PKEY_ASN1_ADD0, - EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED); + ERR_raise(ERR_LIB_EVP, + EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED); return 0; } @@ -219,8 +222,10 @@ EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, { EVP_PKEY_ASN1_METHOD *ameth = OPENSSL_zalloc(sizeof(*ameth)); - if (ameth == NULL) + if (ameth == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; + } ameth->pkey_id = id; ameth->pkey_base_id = id; @@ -228,13 +233,13 @@ EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, if (info) { ameth->info = OPENSSL_strdup(info); - if (!ameth->info) + if (ameth->info == NULL) goto err; } if (pem_str) { ameth->pem_str = OPENSSL_strdup(pem_str); - if (!ameth->pem_str) + if (ameth->pem_str == NULL) goto err; } @@ -242,46 +247,27 @@ EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, err: EVP_PKEY_asn1_free(ameth); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; - } void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, const EVP_PKEY_ASN1_METHOD *src) { - - dst->pub_decode = src->pub_decode; - dst->pub_encode = src->pub_encode; - dst->pub_cmp = src->pub_cmp; - dst->pub_print = src->pub_print; - - dst->priv_decode = src->priv_decode; - dst->priv_encode = src->priv_encode; - dst->priv_print = src->priv_print; - - dst->old_priv_encode = src->old_priv_encode; - dst->old_priv_decode = src->old_priv_decode; - - dst->pkey_size = src->pkey_size; - dst->pkey_bits = src->pkey_bits; - - dst->param_decode = src->param_decode; - dst->param_encode = src->param_encode; - dst->param_missing = src->param_missing; - dst->param_copy = src->param_copy; - dst->param_cmp = src->param_cmp; - dst->param_print = src->param_print; - - dst->pkey_free = src->pkey_free; - dst->pkey_ctrl = src->pkey_ctrl; - - dst->item_sign = src->item_sign; - dst->item_verify = src->item_verify; - - dst->siginf_set = src->siginf_set; - - dst->pkey_check = src->pkey_check; - + int pkey_id = dst->pkey_id; + int pkey_base_id = dst->pkey_base_id; + unsigned long pkey_flags = dst->pkey_flags; + char *pem_str = dst->pem_str; + char *info = dst->info; + + *dst = *src; + + /* We only copy the function pointers so restore the other values */ + dst->pkey_id = pkey_id; + dst->pkey_base_id = pkey_base_id; + dst->pkey_flags = pkey_flags; + dst->pem_str = pem_str; + dst->info = info; } void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth) @@ -295,7 +281,7 @@ void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth) void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, int (*pub_decode) (EVP_PKEY *pk, - X509_PUBKEY *pub), + const X509_PUBKEY *pub), int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk), int (*pub_cmp) (const EVP_PKEY *a, @@ -376,13 +362,13 @@ void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth, void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, - void *asn, - X509_ALGOR *a, - ASN1_BIT_STRING *sig, + const void *data, + const X509_ALGOR *a, + const ASN1_BIT_STRING *sig, EVP_PKEY *pkey), int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, - void *asn, + const void *data, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig)) diff --git a/crypto/openssl/crypto/asn1/asn1_err.c b/crypto/openssl/crypto/asn1/asn1_err.c index cc0a59ca4c8b..a7b32e3a6e1a 100644 --- a/crypto/openssl/crypto/asn1/asn1_err.c +++ b/crypto/openssl/crypto/asn1/asn1_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,150 +10,10 @@ #include #include +#include "crypto/asn1err.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA ASN1_str_functs[] = { - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_A2D_ASN1_OBJECT, 0), "a2d_ASN1_OBJECT"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_A2I_ASN1_INTEGER, 0), "a2i_ASN1_INTEGER"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_A2I_ASN1_STRING, 0), "a2i_ASN1_STRING"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_APPEND_EXP, 0), "append_exp"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_BIO_INIT, 0), "asn1_bio_init"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_BIT_STRING_SET_BIT, 0), - "ASN1_BIT_STRING_set_bit"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_CB, 0), "asn1_cb"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_CHECK_TLEN, 0), "asn1_check_tlen"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_COLLECT, 0), "asn1_collect"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_EX_PRIMITIVE, 0), - "asn1_d2i_ex_primitive"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_FP, 0), "ASN1_d2i_fp"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_READ_BIO, 0), "asn1_d2i_read_bio"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DIGEST, 0), "ASN1_digest"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DO_ADB, 0), "asn1_do_adb"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DO_LOCK, 0), "asn1_do_lock"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_DUP, 0), "ASN1_dup"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ENC_SAVE, 0), "asn1_enc_save"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_EX_C2I, 0), "asn1_ex_c2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_FIND_END, 0), "asn1_find_end"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GENERALIZEDTIME_ADJ, 0), - "ASN1_GENERALIZEDTIME_adj"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GENERATE_V3, 0), "ASN1_generate_v3"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_INT64, 0), "asn1_get_int64"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, 0), "ASN1_get_object"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_UINT64, 0), "asn1_get_uint64"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_I2D_BIO, 0), "ASN1_i2d_bio"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_I2D_FP, 0), "ASN1_i2d_fp"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_D2I_FP, 0), "ASN1_item_d2i_fp"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_DUP, 0), "ASN1_item_dup"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_EMBED_D2I, 0), - "asn1_item_embed_d2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_EMBED_NEW, 0), - "asn1_item_embed_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_EX_I2D, 0), "ASN1_item_ex_i2d"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_FLAGS_I2D, 0), - "asn1_item_flags_i2d"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_I2D_BIO, 0), "ASN1_item_i2d_bio"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_I2D_FP, 0), "ASN1_item_i2d_fp"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_PACK, 0), "ASN1_item_pack"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_SIGN, 0), "ASN1_item_sign"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_SIGN_CTX, 0), - "ASN1_item_sign_ctx"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_UNPACK, 0), "ASN1_item_unpack"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_VERIFY, 0), "ASN1_item_verify"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_MBSTRING_NCOPY, 0), - "ASN1_mbstring_ncopy"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_OBJECT_NEW, 0), "ASN1_OBJECT_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_OUTPUT_DATA, 0), "asn1_output_data"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_PCTX_NEW, 0), "ASN1_PCTX_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_PRIMITIVE_NEW, 0), - "asn1_primitive_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_SCTX_NEW, 0), "ASN1_SCTX_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_SIGN, 0), "ASN1_sign"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STR2TYPE, 0), "asn1_str2type"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_GET_INT64, 0), - "asn1_string_get_int64"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_GET_UINT64, 0), - "asn1_string_get_uint64"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_SET, 0), "ASN1_STRING_set"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_TABLE_ADD, 0), - "ASN1_STRING_TABLE_add"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_TO_BN, 0), "asn1_string_to_bn"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_STRING_TYPE_NEW, 0), - "ASN1_STRING_type_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TEMPLATE_EX_D2I, 0), - "asn1_template_ex_d2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TEMPLATE_NEW, 0), "asn1_template_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 0), - "asn1_template_noexp_d2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TIME_ADJ, 0), "ASN1_TIME_adj"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, 0), - "ASN1_TYPE_get_int_octetstring"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_TYPE_GET_OCTETSTRING, 0), - "ASN1_TYPE_get_octetstring"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_UTCTIME_ADJ, 0), "ASN1_UTCTIME_adj"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_VERIFY, 0), "ASN1_verify"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_B64_READ_ASN1, 0), "b64_read_asn1"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_B64_WRITE_ASN1, 0), "B64_write_ASN1"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_BIO_NEW_NDEF, 0), "BIO_new_NDEF"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_BITSTR_CB, 0), "bitstr_cb"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_BN_TO_ASN1_STRING, 0), "bn_to_asn1_string"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_ASN1_BIT_STRING, 0), - "c2i_ASN1_BIT_STRING"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_ASN1_INTEGER, 0), "c2i_ASN1_INTEGER"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_ASN1_OBJECT, 0), "c2i_ASN1_OBJECT"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_IBUF, 0), "c2i_ibuf"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_C2I_UINT64_INT, 0), "c2i_uint64_int"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_COLLECT_DATA, 0), "collect_data"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_ASN1_OBJECT, 0), "d2i_ASN1_OBJECT"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_ASN1_UINTEGER, 0), "d2i_ASN1_UINTEGER"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_AUTOPRIVATEKEY, 0), - "d2i_AutoPrivateKey"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_PRIVATEKEY, 0), "d2i_PrivateKey"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_D2I_PUBLICKEY, 0), "d2i_PublicKey"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_BUF, 0), "do_buf"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_CREATE, 0), "do_create"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_DUMP, 0), "do_dump"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_DO_TCREATE, 0), "do_tcreate"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2A_ASN1_OBJECT, 0), "i2a_ASN1_OBJECT"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_ASN1_BIO_STREAM, 0), - "i2d_ASN1_bio_stream"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_ASN1_OBJECT, 0), "i2d_ASN1_OBJECT"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_DSA_PUBKEY, 0), "i2d_DSA_PUBKEY"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_EC_PUBKEY, 0), "i2d_EC_PUBKEY"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_PRIVATEKEY, 0), "i2d_PrivateKey"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_PUBLICKEY, 0), "i2d_PublicKey"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_I2D_RSA_PUBKEY, 0), "i2d_RSA_PUBKEY"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_LONG_C2I, 0), "long_c2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_NDEF_PREFIX, 0), "ndef_prefix"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_NDEF_SUFFIX, 0), "ndef_suffix"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_OID_MODULE_INIT, 0), "oid_module_init"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PARSE_TAGGING, 0), "parse_tagging"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE2_SET_IV, 0), "PKCS5_pbe2_set_iv"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE2_SET_SCRYPT, 0), - "PKCS5_pbe2_set_scrypt"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE_SET, 0), "PKCS5_pbe_set"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBE_SET0_ALGOR, 0), - "PKCS5_pbe_set0_algor"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_PBKDF2_SET, 0), "PKCS5_pbkdf2_set"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_PKCS5_SCRYPT_SET, 0), "pkcs5_scrypt_set"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_SMIME_READ_ASN1, 0), "SMIME_read_ASN1"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_SMIME_TEXT, 0), "SMIME_text"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_STABLE_GET, 0), "stable_get"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_STBL_MODULE_INIT, 0), "stbl_module_init"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT32_C2I, 0), "uint32_c2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT32_NEW, 0), "uint32_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT64_C2I, 0), "uint64_c2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_UINT64_NEW, 0), "uint64_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_CRL_ADD0_REVOKED, 0), - "X509_CRL_add0_revoked"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_INFO_NEW, 0), "X509_INFO_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_NAME_ENCODE, 0), "x509_name_encode"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_NAME_EX_D2I, 0), "x509_name_ex_d2i"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_NAME_EX_NEW, 0), "x509_name_ex_new"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_X509_PKEY_NEW, 0), "X509_PKEY_new"}, - {0, NULL} -}; - static const ERR_STRING_DATA ASN1_str_reasons[] = { {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ADDING_OBJECT), "adding object"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ASN1_PARSE_ERROR), "asn1 parse error"}, @@ -249,6 +109,7 @@ static const ERR_STRING_DATA ASN1_str_reasons[] = { {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_UTF8STRING), "invalid utf8string"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_VALUE), "invalid value"}, + {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_LENGTH_TOO_LONG), "length too long"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_LIST_ERROR), "list error"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MIME_NO_CONTENT_TYPE), "mime no content type"}, @@ -313,6 +174,7 @@ static const ERR_STRING_DATA ASN1_str_reasons[] = { {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNEXPECTED_EOC), "unexpected eoc"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH), "universalstring is wrong length"}, + {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_DIGEST), "unknown digest"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_FORMAT), "unknown format"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM), "unknown message digest algorithm"}, @@ -340,13 +202,11 @@ static const ERR_STRING_DATA ASN1_str_reasons[] = { #endif -int ERR_load_ASN1_strings(void) +int ossl_err_load_ASN1_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) { - ERR_load_strings_const(ASN1_str_functs); + if (ERR_reason_error_string(ASN1_str_reasons[0].error) == NULL) ERR_load_strings_const(ASN1_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/asn1/asn1_gen.c b/crypto/openssl/crypto/asn1/asn1_gen.c index 493a693aa384..64620a4f28a7 100644 --- a/crypto/openssl/crypto/asn1/asn1_gen.c +++ b/crypto/openssl/crypto/asn1/asn1_gen.c @@ -1,7 +1,7 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -91,7 +91,7 @@ ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf) int err = 0; ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); if (err) - ASN1err(ASN1_F_ASN1_GENERATE_V3, err); + ERR_raise(ERR_LIB_ASN1, err); return ret; } @@ -263,8 +263,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr) utype = asn1_str2tag(elem, len); if (utype == -1) { - ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG); - ERR_add_error_data(2, "tag=", elem); + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_UNKNOWN_TAG, "tag=%s", elem); return -1; } @@ -274,7 +273,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr) arg->str = vstart; /* If no value and not end of string, error */ if (!vstart && elem[len]) { - ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MISSING_VALUE); return -1; } return 0; @@ -285,7 +284,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr) case ASN1_GEN_FLAG_IMP: /* Check for illegal multiple IMPLICIT tagging */ if (arg->imp_tag != -1) { - ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING); return -1; } if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) @@ -322,7 +321,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr) case ASN1_GEN_FLAG_FORMAT: if (!vstart) { - ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT); return -1; } if (strncmp(vstart, "ASCII", 5) == 0) @@ -334,7 +333,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr) else if (strncmp(vstart, "BITLIST", 7) == 0) arg->format = ASN1_GEN_FORMAT_BITLIST; else { - ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT); return -1; } break; @@ -347,7 +346,6 @@ static int asn1_cb(const char *elem, int len, void *bitstr) static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) { - char erch[2]; long tag_num; char *eptr; if (!vstart) @@ -357,7 +355,7 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) if (eptr && *eptr && (eptr > vstart + vlen)) return 0; if (tag_num < 0) { - ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_NUMBER); return 0; } *ptag = tag_num; @@ -386,10 +384,8 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) break; default: - erch[0] = *eptr; - erch[1] = 0; - ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER); - ERR_add_error_data(2, "Char=", erch); + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_INVALID_MODIFIER, + "Char=%c", *eptr); return 0; } @@ -469,12 +465,12 @@ static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, tag_exp_type *exp_tmp; /* Can only have IMPLICIT if permitted */ if ((arg->imp_tag != -1) && !imp_ok) { - ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG); return 0; } if (arg->exp_count == ASN1_FLAG_EXP_MAX) { - ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED); + ERR_raise(ERR_LIB_ASN1, ASN1_R_DEPTH_EXCEEDED); return 0; } @@ -568,7 +564,8 @@ static int asn1_str2tag(const char *tagstr, int len) tntmp = tnst; for (i = 0; i < OSSL_NELEM(tnst); i++, tntmp++) { - if ((len == tntmp->len) && (strncmp(tntmp->strnam, tagstr, len) == 0)) + if ((len == tntmp->len) + && (OPENSSL_strncasecmp(tntmp->strnam, tagstr, len) == 0)) return tntmp->tag; } @@ -584,7 +581,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) int no_unused = 1; if ((atmp = ASN1_TYPE_new()) == NULL) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } @@ -595,21 +592,21 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) case V_ASN1_NULL: if (str && *str) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_NULL_VALUE); goto bad_form; } break; case V_ASN1_BOOLEAN: if (format != ASN1_GEN_FORMAT_ASCII) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NOT_ASCII_FORMAT); goto bad_form; } vtmp.name = NULL; vtmp.section = NULL; vtmp.value = (char *)str; if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_BOOLEAN); goto bad_str; } break; @@ -617,23 +614,23 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) case V_ASN1_INTEGER: case V_ASN1_ENUMERATED: if (format != ASN1_GEN_FORMAT_ASCII) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT); goto bad_form; } if ((atmp->value.integer = s2i_ASN1_INTEGER(NULL, str)) == NULL) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_INTEGER); goto bad_str; } break; case V_ASN1_OBJECT: if (format != ASN1_GEN_FORMAT_ASCII) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT); goto bad_form; } if ((atmp->value.object = OBJ_txt2obj(str, 0)) == NULL) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_OBJECT); goto bad_str; } break; @@ -641,20 +638,20 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) case V_ASN1_UTCTIME: case V_ASN1_GENERALIZEDTIME: if (format != ASN1_GEN_FORMAT_ASCII) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT); goto bad_form; } if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto bad_str; } if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto bad_str; } atmp->value.asn1_string->type = utype; if (!ASN1_TIME_check(atmp->value.asn1_string)) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_TIME_VALUE); goto bad_str; } @@ -674,13 +671,13 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) else if (format == ASN1_GEN_FORMAT_UTF8) format = MBSTRING_UTF8; else { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_FORMAT); goto bad_form; } if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, -1, format, ASN1_tag2bit(utype)) <= 0) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto bad_str; } @@ -689,13 +686,13 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) case V_ASN1_BIT_STRING: case V_ASN1_OCTET_STRING: if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto bad_form; } if (format == ASN1_GEN_FORMAT_HEX) { if ((rdata = OPENSSL_hexstr2buf(str, &rdlen)) == NULL) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_HEX); goto bad_str; } atmp->value.asn1_string->data = rdata; @@ -707,13 +704,13 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) && (utype == V_ASN1_BIT_STRING)) { if (!CONF_parse_list (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); + ERR_raise(ERR_LIB_ASN1, ASN1_R_LIST_ERROR); goto bad_str; } no_unused = 0; } else { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT); goto bad_form; } @@ -726,7 +723,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) break; default: - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE); goto bad_str; } @@ -752,11 +749,11 @@ static int bitstr_cb(const char *elem, int len, void *bitstr) if (eptr && *eptr && (eptr != elem + len)) return 0; if (bitnum < 0) { - ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_NUMBER); return 0; } if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { - ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } return 1; diff --git a/crypto/openssl/crypto/asn1/asn1_item_list.c b/crypto/openssl/crypto/asn1/asn1_item_list.c index 9798192f4be2..b5a83ba8914b 100644 --- a/crypto/openssl/crypto/asn1/asn1_item_list.c +++ b/crypto/openssl/crypto/asn1/asn1_item_list.c @@ -1,12 +1,15 @@ /* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use the low level ASN1 items until they are removed */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include "internal/cryptlib.h" #include diff --git a/crypto/openssl/crypto/asn1/asn1_item_list.h b/crypto/openssl/crypto/asn1/asn1_item_list.h index db8107ed1b19..1432012b7c7c 100644 --- a/crypto/openssl/crypto/asn1/asn1_item_list.h +++ b/crypto/openssl/crypto/asn1/asn1_item_list.h @@ -1,7 +1,7 @@ /* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -63,8 +63,10 @@ static ASN1_ITEM_EXP *asn1_item_list[] = { ASN1_ITEM_ref(DIST_POINT_NAME), ASN1_ITEM_ref(DIST_POINT), #ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_DEPRECATED_3_0 ASN1_ITEM_ref(ECPARAMETERS), ASN1_ITEM_ref(ECPKPARAMETERS), +# endif #endif ASN1_ITEM_ref(EDIPARTYNAME), ASN1_ITEM_ref(EXTENDED_KEY_USAGE), @@ -78,7 +80,7 @@ static ASN1_ITEM_EXP *asn1_item_list[] = { ASN1_ITEM_ref(IPAddressRange), #endif ASN1_ITEM_ref(ISSUING_DIST_POINT), -#if OPENSSL_API_COMPAT < 0x10200000L +#ifndef OPENSSL_NO_DEPRECATED_3_0 ASN1_ITEM_ref(LONG), #endif ASN1_ITEM_ref(NAME_CONSTRAINTS), @@ -134,7 +136,7 @@ static ASN1_ITEM_EXP *asn1_item_list[] = { ASN1_ITEM_ref(POLICY_MAPPING), ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), ASN1_ITEM_ref(PROXY_POLICY), -#ifndef OPENSSL_NO_RSA +#ifndef OPENSSL_NO_DEPRECATED_3_0 ASN1_ITEM_ref(RSAPrivateKey), ASN1_ITEM_ref(RSAPublicKey), ASN1_ITEM_ref(RSA_OAEP_PARAMS), @@ -145,6 +147,7 @@ static ASN1_ITEM_EXP *asn1_item_list[] = { #endif ASN1_ITEM_ref(SXNETID), ASN1_ITEM_ref(SXNET), + ASN1_ITEM_ref(ISSUER_SIGN_TOOL), ASN1_ITEM_ref(USERNOTICE), ASN1_ITEM_ref(X509_ALGORS), ASN1_ITEM_ref(X509_ALGOR), @@ -164,7 +167,7 @@ static ASN1_ITEM_EXP *asn1_item_list[] = { ASN1_ITEM_ref(X509_SIG), ASN1_ITEM_ref(X509_VAL), ASN1_ITEM_ref(X509), -#if OPENSSL_API_COMPAT < 0x10200000L +#ifndef OPENSSL_NO_DEPRECATED_3_0 ASN1_ITEM_ref(ZLONG), #endif ASN1_ITEM_ref(INT32), diff --git a/crypto/openssl/crypto/asn1/asn1_lib.c b/crypto/openssl/crypto/asn1/asn1_lib.c index b9b7ad8e9e02..5359cbc11720 100644 --- a/crypto/openssl/crypto/asn1/asn1_lib.c +++ b/crypto/openssl/crypto/asn1/asn1_lib.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -22,11 +22,13 @@ static int _asn1_check_infinite_end(const unsigned char **p, long len) /* * If there is 0 or 1 byte left, the length check should pick things up */ - if (len <= 0) - return 1; - else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) { - (*p) += 2; + if (len <= 0) { return 1; + } else { + if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) { + (*p) += 2; + return 1; + } } return 0; } @@ -45,13 +47,15 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, int *pclass, long omax) { int i, ret; - long l; + long len; const unsigned char *p = *pp; int tag, xclass, inf; long max = omax; - if (!max) - goto err; + if (omax <= 0) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL); + return 0x80; + } ret = (*p & V_ASN1_CONSTRUCTED); xclass = (*p & V_ASN1_PRIVATE); i = *p & V_ASN1_PRIMITIVE_TAG; @@ -59,18 +63,18 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, p++; if (--max == 0) goto err; - l = 0; + len = 0; while (*p & 0x80) { - l <<= 7L; - l |= *(p++) & 0x7f; + len <<= 7L; + len |= *(p++) & 0x7f; if (--max == 0) goto err; - if (l > (INT_MAX >> 7L)) + if (len > (INT_MAX >> 7L)) goto err; } - l <<= 7L; - l |= *(p++) & 0x7f; - tag = (int)l; + len <<= 7L; + len |= *(p++) & 0x7f; + tag = (int)len; if (--max == 0) goto err; } else { @@ -88,7 +92,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, goto err; if (*plength > (omax - (p - *pp))) { - ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG); /* * Set this so that even if things are not long enough the values are * set correctly @@ -98,7 +102,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, *pp = p; return ret | inf; err: - ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG); return 0x80; } @@ -141,8 +145,9 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, } if (ret > LONG_MAX) return 0; - } else + } else { ret = i; + } } *pp = p; *rl = (long)ret; @@ -150,7 +155,7 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, } /* - * class 0 is constructed constructed == 2 for indefinite length constructed + * constructed == 2 for indefinite length constructed */ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, int xclass) @@ -160,9 +165,9 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, i = (constructed) ? V_ASN1_CONSTRUCTED : 0; i |= (xclass & V_ASN1_PRIVATE); - if (tag < 31) + if (tag < 31) { *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG); - else { + } else { *(p++) = i | V_ASN1_PRIMITIVE_TAG; for (i = 0, ttag = tag; ttag > 0; i++) ttag >>= 7; @@ -185,6 +190,7 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, int ASN1_put_eoc(unsigned char **pp) { unsigned char *p = *pp; + *p++ = 0; *p++ = 0; *pp = p; @@ -194,20 +200,21 @@ int ASN1_put_eoc(unsigned char **pp) static void asn1_put_length(unsigned char **pp, int length) { unsigned char *p = *pp; - int i, l; - if (length <= 127) + int i, len; + + if (length <= 127) { *(p++) = (unsigned char)length; - else { - l = length; - for (i = 0; l > 0; i++) - l >>= 8; + } else { + len = length; + for (i = 0; len > 0; i++) + len >>= 8; *(p++) = i | 0x80; - l = i; + len = i; while (i-- > 0) { p[i] = length & 0xff; length >>= 8; } - p += l; + p += len; } *pp = p; } @@ -215,6 +222,7 @@ static void asn1_put_length(unsigned char **pp, int length) int ASN1_object_size(int constructed, int length, int tag) { int ret = 1; + if (length < 0) return -1; if (tag >= 31) { @@ -256,6 +264,7 @@ int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) { ASN1_STRING *ret; + if (!str) return NULL; ret = ASN1_STRING_new(); @@ -287,7 +296,7 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in) * '\0' terminator even though this isn't strictly necessary. */ if (len > INT_MAX - 1) { - ASN1err(0, ASN1_R_TOO_LARGE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE); return 0; } if ((size_t)str->length <= len || str->data == NULL) { @@ -299,7 +308,7 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in) str->data = OPENSSL_realloc(c, len + 1); #endif if (str->data == NULL) { - ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); str->data = c; return 0; } @@ -340,14 +349,14 @@ ASN1_STRING *ASN1_STRING_type_new(int type) ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } ret->type = type; return ret; } -void asn1_string_embed_free(ASN1_STRING *a, int embed) +void ossl_asn1_string_embed_free(ASN1_STRING *a, int embed) { if (a == NULL) return; @@ -361,7 +370,7 @@ void ASN1_STRING_free(ASN1_STRING *a) { if (a == NULL) return; - asn1_string_embed_free(a, a->flags & ASN1_STRING_FLAG_EMBED); + ossl_asn1_string_embed_free(a, a->flags & ASN1_STRING_FLAG_EMBED); } void ASN1_STRING_clear_free(ASN1_STRING *a) @@ -385,8 +394,9 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) return a->type - b->type; else return i; - } else + } else { return i; + } } int ASN1_STRING_length(const ASN1_STRING *x) @@ -394,10 +404,12 @@ int ASN1_STRING_length(const ASN1_STRING *x) return x->length; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 void ASN1_STRING_length_set(ASN1_STRING *x, int len) { x->length = len; } +#endif int ASN1_STRING_type(const ASN1_STRING *x) { @@ -409,9 +421,50 @@ const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) return x->data; } -# if OPENSSL_API_COMPAT < 0x10100000L +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 unsigned char *ASN1_STRING_data(ASN1_STRING *x) { return x->data; } #endif + +/* |max_len| excludes NUL terminator and may be 0 to indicate no restriction */ +char *ossl_sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, + const char *sep, size_t max_len) +{ + int i; + ASN1_UTF8STRING *current; + size_t length = 0, sep_len; + char *result = NULL; + char *p; + + if (sep == NULL) + sep = ""; + sep_len = strlen(sep); + + for (i = 0; i < sk_ASN1_UTF8STRING_num(text); i++) { + current = sk_ASN1_UTF8STRING_value(text, i); + if (i > 0) + length += sep_len; + length += ASN1_STRING_length(current); + if (max_len != 0 && length > max_len) + return NULL; + } + if ((result = OPENSSL_malloc(length + 1)) == NULL) + return NULL; + + p = result; + for (i = 0; i < sk_ASN1_UTF8STRING_num(text); i++) { + current = sk_ASN1_UTF8STRING_value(text, i); + length = ASN1_STRING_length(current); + if (i > 0 && sep_len > 0) { + strncpy(p, sep, sep_len + 1); /* using + 1 to silence gcc warning */ + p += sep_len; + } + strncpy(p, (const char *)ASN1_STRING_get0_data(current), length); + p += length; + } + *p = '\0'; + + return result; +} diff --git a/crypto/openssl/crypto/asn1/asn1_local.h b/crypto/openssl/crypto/asn1/asn1_local.h index cec141721b34..f73bd8fc6a30 100644 --- a/crypto/openssl/crypto/asn1/asn1_local.h +++ b/crypto/openssl/crypto/asn1/asn1_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2005-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,9 +9,11 @@ /* Internal ASN1 structures and functions: not for application use */ -int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d); -int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d); -int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d); +typedef const ASN1_VALUE const_ASN1_VALUE; +SKM_DEFINE_STACK_OF(const_ASN1_VALUE, const ASN1_VALUE, ASN1_VALUE) + +int ossl_asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d); +int ossl_asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d); /* ASN1 scan context structure */ @@ -43,41 +45,50 @@ DEFINE_STACK_OF(MIME_PARAM) typedef struct mime_header_st MIME_HEADER; DEFINE_STACK_OF(MIME_HEADER) -void asn1_string_embed_free(ASN1_STRING *a, int embed); +void ossl_asn1_string_embed_free(ASN1_STRING *a, int embed); -int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); -int asn1_set_choice_selector(ASN1_VALUE **pval, int value, - const ASN1_ITEM *it); +int ossl_asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); +int ossl_asn1_get_choice_selector_const(const ASN1_VALUE **pval, + const ASN1_ITEM *it); +int ossl_asn1_set_choice_selector(ASN1_VALUE **pval, int value, + const ASN1_ITEM *it); -ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +ASN1_VALUE **ossl_asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +const ASN1_VALUE **ossl_asn1_get_const_field_ptr(const ASN1_VALUE **pval, + const ASN1_TEMPLATE *tt); -const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, - int nullerr); +const ASN1_TEMPLATE *ossl_asn1_do_adb(const ASN1_VALUE *val, + const ASN1_TEMPLATE *tt, + int nullerr); -int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it); +int ossl_asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it); -void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); -void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); -int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, - const ASN1_ITEM *it); -int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, - const ASN1_ITEM *it); +void ossl_asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); +void ossl_asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +int ossl_asn1_enc_restore(int *len, unsigned char **out, const ASN1_VALUE **pval, + const ASN1_ITEM *it); +int ossl_asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, + const ASN1_ITEM *it); -void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed); -void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed); -void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +void ossl_asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed); +void ossl_asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed); +void ossl_asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); -ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, - long length); -int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp); -ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, - const unsigned char **pp, long length); -int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); -ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, - long length); +ASN1_OBJECT *ossl_c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); +int ossl_i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp); +ASN1_BIT_STRING *ossl_c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long length); +int ossl_i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); +ASN1_INTEGER *ossl_c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); /* Internal functions used by x_int64.c */ -int c2i_uint64_int(uint64_t *ret, int *neg, const unsigned char **pp, long len); -int i2c_uint64_int(unsigned char *p, uint64_t r, int neg); +int ossl_c2i_uint64_int(uint64_t *ret, int *neg, const unsigned char **pp, + long len); +int ossl_i2c_uint64_int(unsigned char *p, uint64_t r, int neg); + +ASN1_TIME *ossl_asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type); -ASN1_TIME *asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type); +int ossl_asn1_item_ex_new_intern(ASN1_VALUE **pval, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq); diff --git a/crypto/openssl/crypto/asn1/asn1_par.c b/crypto/openssl/crypto/asn1/asn1_parse.c similarity index 87% rename from crypto/openssl/crypto/asn1/asn1_par.c rename to crypto/openssl/crypto/asn1/asn1_parse.c index a32fa47f2206..04d7ef66cfc9 100644 --- a/crypto/openssl/crypto/asn1/asn1_par.c +++ b/crypto/openssl/crypto/asn1/asn1_parse.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -17,25 +17,47 @@ #define ASN1_PARSE_MAXDEPTH 128 #endif -static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, - int indent); static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset, int depth, int indent, int dump); -static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, - int indent) +static int asn1_print_info(BIO *bp, long offset, int depth, int hl, long len, + int tag, int xclass, int constructed, int indent) { - static const char fmt[] = "%-18s"; char str[128]; const char *p; + int pop_f_prefix = 0; + long saved_indent = -1; + int i = 0; + BIO *bio = NULL; if (constructed & V_ASN1_CONSTRUCTED) p = "cons: "; else p = "prim: "; - if (BIO_write(bp, p, 6) < 6) - goto err; - BIO_indent(bp, indent, 128); + if (constructed != (V_ASN1_CONSTRUCTED | 1)) { + if (BIO_snprintf(str, sizeof(str), "%5ld:d=%-2d hl=%ld l=%4ld %s", + offset, depth, (long)hl, len, p) <= 0) + goto err; + } else { + if (BIO_snprintf(str, sizeof(str), "%5ld:d=%-2d hl=%ld l=inf %s", + offset, depth, (long)hl, p) <= 0) + goto err; + } + if (bp != NULL) { + if (BIO_set_prefix(bp, str) <= 0) { + if ((bio = BIO_new(BIO_f_prefix())) == NULL + || (bp = BIO_push(bio, bp)) == NULL) + goto err; + pop_f_prefix = 1; + } + saved_indent = BIO_get_indent(bp); + if (BIO_set_prefix(bp, str) <= 0 || BIO_set_indent(bp, indent) < 0) + goto err; + } + /* + * BIO_set_prefix made a copy of |str|, so we can safely use it for + * something else, ASN.1 tag printout. + */ p = str; if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) BIO_snprintf(str, sizeof(str), "priv [ %d ] ", tag); @@ -48,11 +70,14 @@ static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, else p = ASN1_tag2str(tag); - if (BIO_printf(bp, fmt, p) <= 0) - goto err; - return 1; + i = (BIO_printf(bp, "%-18s", p) > 0); err: - return 0; + if (saved_indent >= 0) + BIO_set_indent(bp, saved_indent); + if (pop_f_prefix) + BIO_pop(bp); + BIO_free(bio); + return i; } int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent) @@ -92,9 +117,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, op = p; j = ASN1_get_object(&p, &len, &tag, &xclass, length); if (j & 0x80) { - if (BIO_write(bp, "Error in encoding\n", 18) <= 0) - goto end; - ret = 0; + BIO_puts(bp, "Error in encoding\n"); goto end; } hl = (p - op); @@ -102,19 +125,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, /* * if j == 0x21 it is a constructed indefinite length object */ - if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp)) - <= 0) - goto end; - - if (j != (V_ASN1_CONSTRUCTED | 1)) { - if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ", - depth, (long)hl, len) <= 0) - goto end; - } else { - if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0) - goto end; - } - if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0)) + if (!asn1_print_info(bp, (long)offset + (long)(op - *pp), depth, + hl, len, tag, xclass, j, (indent) ? depth : 0)) goto end; if (j & V_ASN1_CONSTRUCTED) { const unsigned char *sp = p; @@ -124,7 +136,6 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, goto end; if (len > length) { BIO_printf(bp, "length is greater than %ld\n", length); - ret = 0; goto end; } if ((j == 0x21) && (len == 0)) { @@ -132,10 +143,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, r = asn1_parse2(bp, &p, (long)(tot - p), offset + (p - *pp), depth + 1, indent, dump); - if (r == 0) { - ret = 0; + if (r == 0) goto end; - } if ((r == 2) || (p >= tot)) { len = p - sp; break; @@ -149,10 +158,8 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, r = asn1_parse2(bp, &p, tmp, offset + (p - *pp), depth + 1, indent, dump); - if (r == 0) { - ret = 0; + if (r == 0) goto end; - } tmp -= p - sp; } } diff --git a/crypto/openssl/crypto/asn1/asn_mime.c b/crypto/openssl/crypto/asn1/asn_mime.c index 36853612b69c..b44b0f36858b 100644 --- a/crypto/openssl/crypto/asn1/asn_mime.c +++ b/crypto/openssl/crypto/asn1/asn_mime.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,6 +14,7 @@ #include #include #include +#include #include "crypto/evp.h" #include "internal/bio.h" #include "asn1_local.h" @@ -53,7 +54,7 @@ static int mime_param_cmp(const MIME_PARAM *const *a, const MIME_PARAM *const *b); static void mime_param_free(MIME_PARAM *param); static int mime_bound_check(char *line, int linelen, const char *bound, int blen); -static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret); +static int multi_split(BIO *bio, int flags, const char *bound, STACK_OF(BIO) **ret); static int strip_eol(char *linebuf, int *plen, int flags); static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, const char *name); static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, const char *name); @@ -64,18 +65,24 @@ static void mime_hdr_free(MIME_HEADER *hdr); /* Output an ASN1 structure in BER format streaming if necessary */ +/* unfortunately cannot constify this due to CMS_stream() and PKCS7_stream() */ int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, const ASN1_ITEM *it) { + int rv = 1; + /* If streaming create stream BIO and copy all content through it */ if (flags & SMIME_STREAM) { BIO *bio, *tbio; bio = BIO_new_NDEF(out, val, it); if (!bio) { - ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } - SMIME_crlf_copy(in, bio, flags); + if (!SMIME_crlf_copy(in, bio, flags)) { + rv = 0; + } + (void)BIO_flush(bio); /* Free up successive BIOs until we hit the old output BIO */ do { @@ -90,7 +97,7 @@ int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, */ else ASN1_item_i2d_bio(it, out, val); - return 1; + return rv; } /* Base 64 read and write of ASN1 structure */ @@ -102,7 +109,7 @@ static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags, int r; b64 = BIO_new(BIO_f_base64()); if (b64 == NULL) { - ASN1err(ASN1_F_B64_WRITE_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } /* @@ -128,19 +135,20 @@ int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, return r; } -static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) +static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it, ASN1_VALUE **x, + OSSL_LIB_CTX *libctx, const char *propq) { BIO *b64; ASN1_VALUE *val; if ((b64 = BIO_new(BIO_f_base64())) == NULL) { - ASN1err(ASN1_F_B64_READ_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } bio = BIO_push(b64, bio); - val = ASN1_item_d2i_bio(it, bio, NULL); + val = ASN1_item_d2i_bio_ex(it, bio, x, libctx, propq); if (!val) - ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR); + ERR_raise(ERR_LIB_ASN1, ASN1_R_DECODE_ERROR); (void)BIO_flush(bio); BIO_pop(bio); BIO_free(b64); @@ -207,9 +215,9 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) goto err; default: - if (have_unknown) + if (have_unknown) { write_comma = 0; - else { + } else { BIO_puts(out, "unknown"); have_unknown = 1; } @@ -227,14 +235,16 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) /* SMIME sender */ -int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, - int ctype_nid, int econt_nid, - STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it) +int SMIME_write_ASN1_ex(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq) { char bound[33], c; int i; const char *mime_prefix, *mime_eol, *cname = "smime.p7m"; const char *msg_type = NULL; + if (flags & SMIME_OLDMIME) mime_prefix = "application/x-pkcs7-"; else @@ -247,7 +257,7 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, if ((flags & SMIME_DETACHED) && data) { /* We want multipart/signed */ /* Generate a random boundary */ - if (RAND_bytes((unsigned char *)bound, 32) <= 0) + if (RAND_bytes_ex(libctx, (unsigned char *)bound, 32, 0) <= 0) return 0; for (i = 0; i < 32; i++) { c = bound[i] & 0xf; @@ -288,9 +298,9 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, /* Determine smime-type header */ - if (ctype_nid == NID_pkcs7_enveloped) + if (ctype_nid == NID_pkcs7_enveloped) { msg_type = "enveloped-data"; - else if (ctype_nid == NID_pkcs7_signed) { + } else if (ctype_nid == NID_pkcs7_signed) { if (econt_nid == NID_id_smime_ct_receipt) msg_type = "signed-receipt"; else if (sk_X509_ALGOR_num(mdalgs) >= 0) @@ -317,8 +327,17 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, return 1; } +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it) +{ + return SMIME_write_ASN1_ex(bio, val, data, flags, ctype_nid, econt_nid, + mdalgs, it, NULL, NULL); +} + /* Handle output of ASN1 data */ +/* cannot constify val because of CMS_dataFinal() */ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, const ASN1_ITEM *it) { @@ -332,12 +351,11 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, * set up to finalise when it is written through. */ if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) { - SMIME_crlf_copy(data, out, flags); - return 1; + return SMIME_crlf_copy(data, out, flags); } if (!aux || !aux->asn1_cb) { - ASN1err(ASN1_F_ASN1_OUTPUT_DATA, ASN1_R_STREAMING_NOT_SUPPORTED); + ERR_raise(ERR_LIB_ASN1, ASN1_R_STREAMING_NOT_SUPPORTED); return 0; } @@ -351,7 +369,8 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, return 0; /* Copy data across, passing through filter BIOs for processing */ - SMIME_crlf_copy(data, sarg.ndef_bio, flags); + if (!SMIME_crlf_copy(data, sarg.ndef_bio, flags)) + rv = 0; /* Finalize structure */ if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0) @@ -375,7 +394,9 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, * opaque this is set to NULL */ -ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) +ASN1_VALUE *SMIME_read_ASN1_ex(BIO *bio, int flags, BIO **bcont, + const ASN1_ITEM *it, ASN1_VALUE **x, + OSSL_LIB_CTX *libctx, const char *propq) { BIO *asnin; STACK_OF(MIME_HEADER) *headers = NULL; @@ -389,14 +410,14 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) *bcont = NULL; if ((headers = mime_parse_hdr(bio)) == NULL) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MIME_PARSE_ERROR); return NULL; } if ((hdr = mime_hdr_find(headers, "content-type")) == NULL || hdr->value == NULL) { sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NO_CONTENT_TYPE); return NULL; } @@ -405,15 +426,15 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) if (strcmp(hdr->value, "multipart/signed") == 0) { /* Split into two parts */ prm = mime_param_find(hdr, "boundary"); - if (!prm || !prm->param_value) { + if (prm == NULL || prm->param_value == NULL) { sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY); return NULL; } - ret = multi_split(bio, prm->param_value, &parts); + ret = multi_split(bio, flags, prm->param_value, &parts); sk_MIME_HEADER_pop_free(headers, mime_hdr_free); if (!ret || (sk_BIO_num(parts) != 2)) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE); sk_BIO_pop_free(parts, BIO_vfree); return NULL; } @@ -422,7 +443,7 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) asnin = sk_BIO_value(parts, 1); if ((headers = mime_parse_hdr(asnin)) == NULL) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR); sk_BIO_pop_free(parts, BIO_vfree); return NULL; } @@ -432,23 +453,23 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) if ((hdr = mime_hdr_find(headers, "content-type")) == NULL || hdr->value == NULL) { sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE); sk_BIO_pop_free(parts, BIO_vfree); return NULL; } if (strcmp(hdr->value, "application/x-pkcs7-signature") && strcmp(hdr->value, "application/pkcs7-signature")) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE); - ERR_add_error_data(2, "type: ", hdr->value); + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE, + "type: %s", hdr->value); sk_MIME_HEADER_pop_free(headers, mime_hdr_free); sk_BIO_pop_free(parts, BIO_vfree); return NULL; } sk_MIME_HEADER_pop_free(headers, mime_hdr_free); /* Read in ASN1 */ - if ((val = b64_read_asn1(asnin, it)) == NULL) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR); + if ((val = b64_read_asn1(asnin, it, x, libctx, propq)) == NULL) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR); sk_BIO_pop_free(parts, BIO_vfree); return NULL; } @@ -457,8 +478,9 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) *bcont = sk_BIO_value(parts, 0); BIO_free(asnin); sk_BIO_free(parts); - } else + } else { sk_BIO_pop_free(parts, BIO_vfree); + } return val; } @@ -466,20 +488,24 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) if (strcmp(hdr->value, "application/x-pkcs7-mime") && strcmp(hdr->value, "application/pkcs7-mime")) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_INVALID_MIME_TYPE); - ERR_add_error_data(2, "type: ", hdr->value); + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_INVALID_MIME_TYPE, + "type: %s", hdr->value); sk_MIME_HEADER_pop_free(headers, mime_hdr_free); return NULL; } sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - if ((val = b64_read_asn1(bio, it)) == NULL) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR); + if ((val = b64_read_asn1(bio, it, x, libctx, propq)) == NULL) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_ASN1_PARSE_ERROR); return NULL; } return val; +} +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) +{ + return SMIME_read_ASN1_ex(bio, 0, bcont, it, NULL, NULL, NULL); } /* Copy text from one BIO to another making the output CRLF at EOL */ @@ -495,8 +521,10 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags) * when streaming as we don't end up with one OCTET STRING per line. */ bf = BIO_new(BIO_f_buffer()); - if (bf == NULL) + if (bf == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; + } out = BIO_push(bf, out); if (flags & SMIME_BINARY) { while ((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0) @@ -507,7 +535,7 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags) BIO_printf(out, "Content-Type: text/plain\r\n\r\n"); while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) { eol = strip_eol(linebuf, &len, flags); - if (len) { + if (len > 0) { /* Not EOF: write out all CRLF */ if (flags & SMIME_ASCIICRLF) { int i; @@ -518,10 +546,11 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags) BIO_write(out, linebuf, len); if (eol) BIO_write(out, "\r\n", 2); - } else if (flags & SMIME_ASCIICRLF) + } else if (flags & SMIME_ASCIICRLF) { eolcnt++; - else if (eol) + } else if (eol) { BIO_write(out, "\r\n", 2); + } } } ret = BIO_flush(out); @@ -542,18 +571,18 @@ int SMIME_text(BIO *in, BIO *out) MIME_HEADER *hdr; if ((headers = mime_parse_hdr(in)) == NULL) { - ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MIME_PARSE_ERROR); return 0; } if ((hdr = mime_hdr_find(headers, "content-type")) == NULL || hdr->value == NULL) { - ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MIME_NO_CONTENT_TYPE); sk_MIME_HEADER_pop_free(headers, mime_hdr_free); return 0; } if (strcmp(hdr->value, "text/plain")) { - ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_INVALID_MIME_TYPE); - ERR_add_error_data(2, "type: ", hdr->value); + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_INVALID_MIME_TYPE, + "type: %s", hdr->value); sk_MIME_HEADER_pop_free(headers, mime_hdr_free); return 0; } @@ -570,7 +599,7 @@ int SMIME_text(BIO *in, BIO *out) * canonical parts in a STACK of bios */ -static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret) +static int multi_split(BIO *bio, int flags, const char *bound, STACK_OF(BIO) **ret) { char linebuf[MAX_SMLEN]; int len, blen; @@ -587,7 +616,7 @@ static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret) *ret = parts; if (*ret == NULL) return 0; - while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) { + while ((len = BIO_get_line(bio, linebuf, MAX_SMLEN)) > 0) { state = mime_bound_check(linebuf, len, bound, blen); if (state == 1) { first = 1; @@ -598,9 +627,9 @@ static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret) return 0; } return 1; - } else if (part) { - /* Strip CR+LF from linebuf */ - next_eol = strip_eol(linebuf, &len, 0); + } else if (part != 0) { + /* Strip (possibly CR +) LF from linebuf */ + next_eol = strip_eol(linebuf, &len, flags); if (first) { first = 0; if (bpart) @@ -612,10 +641,20 @@ static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret) if (bpart == NULL) return 0; BIO_set_mem_eof_return(bpart, 0); - } else if (eol) - BIO_write(bpart, "\r\n", 2); + } else if (eol) { + if ( +#ifndef OPENSSL_NO_CMS + (flags & CMS_BINARY) == 0 +#else + 1 +#endif + || (flags & SMIME_CRLFEOL) != 0) + BIO_write(bpart, "\r\n", 2); + else + BIO_write(bpart, "\n", 1); + } eol = next_eol; - if (len) + if (len > 0) BIO_write(bpart, linebuf, len); } } @@ -739,15 +778,16 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio) goto err; mhdr = new_hdr; new_hdr = NULL; - } else if (state == MIME_VALUE) + } else if (state == MIME_VALUE) { mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); + } if (p == linebuf) break; /* Blank line means end of headers */ } return headers; -err: + err: mime_hdr_free(new_hdr); sk_MIME_HEADER_pop_free(headers, mime_hdr_free); return NULL; @@ -762,7 +802,7 @@ static char *strip_ends(char *name) static char *strip_start(char *name) { char *p, c; - /* Look for first non white space or quote */ + /* Look for first non whitespace or quote */ for (p = name; (c = *p); p++) { if (c == '"') { /* Next char is start of string if non null */ @@ -783,7 +823,7 @@ static char *strip_end(char *name) char *p, c; if (!name) return NULL; - /* Look for first non white space or quote */ + /* Look for first non whitespace or quote */ for (p = name + strlen(name) - 1; p >= name; p--) { c = *p; if (c == '"') { @@ -869,8 +909,8 @@ static int mime_hdr_addparam(MIME_HEADER *mhdr, const char *name, const char *va static int mime_hdr_cmp(const MIME_HEADER *const *a, const MIME_HEADER *const *b) { - if (!(*a)->name || !(*b)->name) - return ! !(*a)->name - ! !(*b)->name; + if ((*a)->name == NULL || (*b)->name == NULL) + return ((*a)->name != NULL) - ((*b)->name != NULL); return strcmp((*a)->name, (*b)->name); } @@ -878,8 +918,8 @@ static int mime_hdr_cmp(const MIME_HEADER *const *a, static int mime_param_cmp(const MIME_PARAM *const *a, const MIME_PARAM *const *b) { - if (!(*a)->param_name || !(*b)->param_name) - return ! !(*a)->param_name - ! !(*b)->param_name; + if ((*a)->param_name == NULL || (*b)->param_name == NULL) + return ((*a)->param_name != NULL) - ((*b)->param_name != NULL); return strcmp((*a)->param_name, (*b)->param_name); } @@ -959,11 +999,26 @@ static int strip_eol(char *linebuf, int *plen, int flags) char *p, c; int is_eol = 0; +#ifndef OPENSSL_NO_CMS + if ((flags & CMS_BINARY) != 0) { + if (len <= 0 || linebuf[len - 1] != '\n') + return 0; + if ((flags & SMIME_CRLFEOL) != 0) { + if (len <= 1 || linebuf[len - 2] != '\r') + return 0; + len--; + } + len--; + *plen = len; + return 1; + } +#endif + for (p = linebuf + len - 1; len > 0; len--, p--) { c = *p; if (c == '\n') { is_eol = 1; - } else if (is_eol && flags & SMIME_ASCIICRLF && c == 32) { + } else if (is_eol && (flags & SMIME_ASCIICRLF) != 0 && c == 32) { /* Strip trailing space on a line; 32 == ASCII for ' ' */ continue; } else if (c != '\r') { diff --git a/crypto/openssl/crypto/asn1/asn_moid.c b/crypto/openssl/crypto/asn1/asn_moid.c index 732ce972aa29..526219c1a723 100644 --- a/crypto/openssl/crypto/asn1/asn_moid.c +++ b/crypto/openssl/crypto/asn1/asn_moid.c @@ -1,7 +1,7 @@ /* - * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -29,13 +29,13 @@ static int oid_module_init(CONF_IMODULE *md, const CONF *cnf) oid_section = CONF_imodule_get_value(md); if ((sktmp = NCONF_get_section(cnf, oid_section)) == NULL) { - ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ERROR_LOADING_SECTION); return 0; } for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { oval = sk_CONF_VALUE_value(sktmp, i); if (!do_create(oval->value, oval->name)) { - ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ADDING_OBJECT); return 0; } } @@ -84,7 +84,7 @@ static int do_create(const char *value, const char *name) } p++; if ((lntmp = OPENSSL_malloc((p - ln) + 1)) == NULL) { - ASN1err(ASN1_F_DO_CREATE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } memcpy(lntmp, ln, p - ln); diff --git a/crypto/openssl/crypto/asn1/asn_mstbl.c b/crypto/openssl/crypto/asn1/asn_mstbl.c index ddcbcd07fe6e..3543cd22568f 100644 --- a/crypto/openssl/crypto/asn1/asn_mstbl.c +++ b/crypto/openssl/crypto/asn1/asn_mstbl.c @@ -1,7 +1,7 @@ /* - * Copyright 2012-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -26,13 +26,13 @@ static int stbl_module_init(CONF_IMODULE *md, const CONF *cnf) stbl_section = CONF_imodule_get_value(md); if ((sktmp = NCONF_get_section(cnf, stbl_section)) == NULL) { - ASN1err(ASN1_F_STBL_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ERROR_LOADING_SECTION); return 0; } for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { mval = sk_CONF_VALUE_value(sktmp, i); if (!do_tcreate(mval->value, mval->name)) { - ASN1err(ASN1_F_STBL_MODULE_INIT, ASN1_R_INVALID_VALUE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_VALUE); return 0; } } @@ -96,17 +96,17 @@ static int do_tcreate(const char *value, const char *name) rv = 1; err: if (rv == 0) { - ASN1err(ASN1_F_DO_TCREATE, ASN1_R_INVALID_STRING_TABLE_VALUE); if (cnf) - ERR_add_error_data(4, "field=", cnf->name, - ", value=", cnf->value); + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_INVALID_STRING_TABLE_VALUE, + "field=%s, value=%s", cnf->name, cnf->value); else - ERR_add_error_data(4, "name=", name, ", value=", value); + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_INVALID_STRING_TABLE_VALUE, + "name=%s, value=%s", name, value); } else { rv = ASN1_STRING_TABLE_add(nid, tbl_min, tbl_max, tbl_mask, tbl_flags); if (!rv) - ASN1err(ASN1_F_DO_TCREATE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); } sk_CONF_VALUE_pop_free(lst, X509V3_conf_free); return rv; diff --git a/crypto/openssl/crypto/asn1/asn_pack.c b/crypto/openssl/crypto/asn1/asn_pack.c index 63bc30675655..292e6d817697 100644 --- a/crypto/openssl/crypto/asn1/asn_pack.c +++ b/crypto/openssl/crypto/asn1/asn_pack.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,7 +19,7 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) if (oct == NULL || *oct == NULL) { if ((octmp = ASN1_STRING_new()) == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } } else { @@ -30,11 +30,11 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) octmp->data = NULL; if ((octmp->length = ASN1_item_i2d(obj, &octmp->data, it)) == 0) { - ASN1err(ASN1_F_ASN1_ITEM_PACK, ASN1_R_ENCODE_ERROR); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ENCODE_ERROR); goto err; } if (octmp->data == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } @@ -57,6 +57,6 @@ void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it) p = oct->data; if ((ret = ASN1_item_d2i(NULL, &p, oct->length, it)) == NULL) - ASN1err(ASN1_F_ASN1_ITEM_UNPACK, ASN1_R_DECODE_ERROR); + ERR_raise(ERR_LIB_ASN1, ASN1_R_DECODE_ERROR); return ret; } diff --git a/crypto/openssl/crypto/asn1/bio_asn1.c b/crypto/openssl/crypto/asn1/bio_asn1.c index 17b0d1aa6cad..0ff239120451 100644 --- a/crypto/openssl/crypto/asn1/bio_asn1.c +++ b/crypto/openssl/crypto/asn1/bio_asn1.c @@ -1,7 +1,7 @@ /* * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -79,10 +79,8 @@ static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, static const BIO_METHOD methods_asn1 = { BIO_TYPE_ASN1, "asn1", - /* TODO: Convert to new style write function */ bwrite_conv, asn1_bio_write, - /* TODO: Convert to new style read function */ bread_conv, asn1_bio_read, asn1_bio_puts, @@ -102,8 +100,10 @@ static int asn1_bio_new(BIO *b) { BIO_ASN1_BUF_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) + if (ctx == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; + } if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) { OPENSSL_free(ctx); return 0; @@ -116,8 +116,8 @@ static int asn1_bio_new(BIO *b) static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size) { - if ((ctx->buf = OPENSSL_malloc(size)) == NULL) { - ASN1err(ASN1_F_ASN1_BIO_INIT, ERR_R_MALLOC_FAILURE); + if (size <= 0 || (ctx->buf = OPENSSL_malloc(size)) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } ctx->bufsize = size; diff --git a/crypto/openssl/crypto/asn1/bio_ndef.c b/crypto/openssl/crypto/asn1/bio_ndef.c index c8a776b482d0..e5b5319d7fd0 100644 --- a/crypto/openssl/crypto/asn1/bio_ndef.c +++ b/crypto/openssl/crypto/asn1/bio_ndef.c @@ -1,7 +1,7 @@ /* * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -64,7 +64,7 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) BIO *pop_bio = NULL; if (!aux || !aux->asn1_cb) { - ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED); + ERR_raise(ERR_LIB_ASN1, ASN1_R_STREAMING_NOT_SUPPORTED); return NULL; } ndef_aux = OPENSSL_zalloc(sizeof(*ndef_aux)); @@ -132,7 +132,7 @@ static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg) unsigned char *p; int derlen; - if (!parg) + if (parg == NULL) return 0; ndef_aux = *(NDEF_SUPPORT **)parg; @@ -141,15 +141,15 @@ static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg) if (derlen < 0) return 0; if ((p = OPENSSL_malloc(derlen)) == NULL) { - ASN1err(ASN1_F_NDEF_PREFIX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } ndef_aux->derbuf = p; *pbuf = p; - derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); + ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); - if (!*ndef_aux->boundary) + if (*ndef_aux->boundary == NULL) return 0; *plen = *ndef_aux->boundary - *pbuf; @@ -162,7 +162,7 @@ static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, { NDEF_SUPPORT *ndef_aux; - if (!parg) + if (parg == NULL) return 0; ndef_aux = *(NDEF_SUPPORT **)parg; @@ -197,7 +197,7 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) const ASN1_AUX *aux; ASN1_STREAM_ARG sarg; - if (!parg) + if (parg == NULL) return 0; ndef_aux = *(NDEF_SUPPORT **)parg; @@ -213,8 +213,10 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) return 0; derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); + if (derlen < 0) + return 0; if ((p = OPENSSL_malloc(derlen)) == NULL) { - ASN1err(ASN1_F_NDEF_SUFFIX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } @@ -222,7 +224,7 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) *pbuf = p; derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); - if (!*ndef_aux->boundary) + if (*ndef_aux->boundary == NULL) return 0; *pbuf = *ndef_aux->boundary; *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf); diff --git a/crypto/openssl/crypto/asn1/build.info b/crypto/openssl/crypto/asn1/build.info index d3e92c81acfe..33b86fdd31f5 100644 --- a/crypto/openssl/crypto/asn1/build.info +++ b/crypto/openssl/crypto/asn1/build.info @@ -4,13 +4,20 @@ SOURCE[../../libcrypto]=\ a_print.c a_type.c a_dup.c a_d2i_fp.c a_i2d_fp.c \ a_utf8.c a_sign.c a_digest.c a_verify.c a_mbstr.c a_strex.c \ x_algor.c x_val.c x_sig.c x_bignum.c \ - x_long.c x_int64.c x_info.c x_spki.c nsseq.c \ - d2i_pu.c d2i_pr.c i2d_pu.c i2d_pr.c\ + x_int64.c x_info.c x_spki.c nsseq.c \ + d2i_pu.c d2i_pr.c i2d_evp.c \ t_pkey.c t_spki.c t_bitst.c \ tasn_new.c tasn_fre.c tasn_enc.c tasn_dec.c tasn_utl.c tasn_typ.c \ tasn_prn.c tasn_scn.c ameth_lib.c \ - f_int.c f_string.c n_pkey.c \ + f_int.c f_string.c \ x_pkey.c bio_asn1.c bio_ndef.c asn_mime.c \ - asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_strnid.c \ + asn1_gen.c asn1_parse.c asn1_lib.c asn1_err.c a_strnid.c \ evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p5_scrypt.c p8_pkey.c \ - asn_moid.c asn_mstbl.c asn1_item_list.c + asn_moid.c asn_mstbl.c asn1_item_list.c \ + d2i_param.c +IF[{- !$disabled{'rsa'} and !$disabled{'rc4'} -}] + SOURCE[../../libcrypto]=n_pkey.c +ENDIF +IF[{- !$disabled{'deprecated-3.0'} -}] + SOURCE[../../libcrypto]=x_long.c +ENDIF diff --git a/crypto/openssl/crypto/asn1/charmap.h b/crypto/openssl/crypto/asn1/charmap.h index 5630291bd58c..ac1eb076cc26 100644 --- a/crypto/openssl/crypto/asn1/charmap.h +++ b/crypto/openssl/crypto/asn1/charmap.h @@ -2,9 +2,9 @@ * WARNING: do not edit! * Generated by crypto/asn1/charmap.pl * - * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/asn1/charmap.pl b/crypto/openssl/crypto/asn1/charmap.pl old mode 100755 new mode 100644 index 52fa5a7900ca..78053dee15fb --- a/crypto/openssl/crypto/asn1/charmap.pl +++ b/crypto/openssl/crypto/asn1/charmap.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -87,6 +87,7 @@ $arr[ord("?")] |= $PSTRING_CHAR; # Year the file was generated. my $YEAR = OpenSSL::copyright::year_of($0); + print < +#include "internal/cryptlib.h" +#include +#include +#include "internal/asn1.h" +#include "crypto/asn1.h" +#include "crypto/evp.h" + +EVP_PKEY *d2i_KeyParams(int type, EVP_PKEY **a, const unsigned char **pp, + long length) +{ + EVP_PKEY *ret = NULL; + + if ((a == NULL) || (*a == NULL)) { + if ((ret = EVP_PKEY_new()) == NULL) + return NULL; + } else + ret = *a; + + if (type != EVP_PKEY_get_id(ret) && !EVP_PKEY_set_type(ret, type)) + goto err; + + if (ret->ameth == NULL || ret->ameth->param_decode == NULL) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE); + goto err; + } + + if (!ret->ameth->param_decode(ret, pp, length)) + goto err; + + if (a != NULL) + (*a) = ret; + return ret; +err: + if (a == NULL || *a != ret) + EVP_PKEY_free(ret); + return NULL; +} + +EVP_PKEY *d2i_KeyParams_bio(int type, EVP_PKEY **a, BIO *in) +{ + BUF_MEM *b = NULL; + const unsigned char *p; + void *ret = NULL; + int len; + + len = asn1_d2i_read_bio(in, &b); + if (len < 0) + goto err; + + p = (unsigned char *)b->data; + ret = d2i_KeyParams(type, a, &p, len); +err: + BUF_MEM_free(b); + return ret; +} diff --git a/crypto/openssl/crypto/asn1/d2i_pr.c b/crypto/openssl/crypto/asn1/d2i_pr.c index 2094963036fe..720b7fd6c050 100644 --- a/crypto/openssl/crypto/asn1/d2i_pr.c +++ b/crypto/openssl/crypto/asn1/d2i_pr.c @@ -1,32 +1,89 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include "internal/cryptlib.h" #include #include #include +#include #include #include #include #include "crypto/asn1.h" #include "crypto/evp.h" +#include "internal/asn1.h" -EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, - long length) +static EVP_PKEY * +d2i_PrivateKey_decoder(int keytype, EVP_PKEY **a, const unsigned char **pp, + long length, OSSL_LIB_CTX *libctx, const char *propq) +{ + OSSL_DECODER_CTX *dctx = NULL; + size_t len = length; + EVP_PKEY *pkey = NULL, *bak_a = NULL; + EVP_PKEY **ppkey = &pkey; + const char *key_name = NULL; + const char *input_structures[] = { "type-specific", "PrivateKeyInfo", NULL }; + int i, ret; + + if (keytype != EVP_PKEY_NONE) { + key_name = evp_pkey_type2name(keytype); + if (key_name == NULL) + return NULL; + } + + for (i = 0; i < (int)OSSL_NELEM(input_structures); ++i) { + const unsigned char *p = *pp; + + if (a != NULL && (bak_a = *a) != NULL) + ppkey = a; + dctx = OSSL_DECODER_CTX_new_for_pkey(ppkey, "DER", + input_structures[i], key_name, + EVP_PKEY_KEYPAIR, libctx, propq); + if (a != NULL) + *a = bak_a; + if (dctx == NULL) + continue; + + ret = OSSL_DECODER_from_data(dctx, pp, &len); + OSSL_DECODER_CTX_free(dctx); + if (ret) { + if (*ppkey != NULL + && evp_keymgmt_util_has(*ppkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY)) { + if (a != NULL) + *a = *ppkey; + return *ppkey; + } + *pp = p; + goto err; + } + } + /* Fall through to error if all decodes failed */ +err: + if (ppkey != a) + EVP_PKEY_free(*ppkey); + return NULL; +} + +EVP_PKEY * +ossl_d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, const unsigned char **pp, + long length, OSSL_LIB_CTX *libctx, const char *propq) { EVP_PKEY *ret; const unsigned char *p = *pp; - if ((a == NULL) || (*a == NULL)) { + if (a == NULL || *a == NULL) { if ((ret = EVP_PKEY_new()) == NULL) { - ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return NULL; } } else { @@ -37,35 +94,45 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, #endif } - if (!EVP_PKEY_set_type(ret, type)) { - ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); + if (!EVP_PKEY_set_type(ret, keytype)) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); goto err; } + ERR_set_mark(); if (!ret->ameth->old_priv_decode || !ret->ameth->old_priv_decode(ret, &p, length)) { - if (ret->ameth->priv_decode) { + if (ret->ameth->priv_decode != NULL + || ret->ameth->priv_decode_ex != NULL) { EVP_PKEY *tmp; PKCS8_PRIV_KEY_INFO *p8 = NULL; p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); - if (!p8) + if (p8 == NULL) { + ERR_clear_last_mark(); goto err; - tmp = EVP_PKCS82PKEY(p8); + } + tmp = evp_pkcs82pkey_legacy(p8, libctx, propq); PKCS8_PRIV_KEY_INFO_free(p8); - if (tmp == NULL) + if (tmp == NULL) { + ERR_clear_last_mark(); goto err; + } EVP_PKEY_free(ret); ret = tmp; - if (EVP_PKEY_type(type) != EVP_PKEY_base_id(ret)) + ERR_pop_to_mark(); + if (EVP_PKEY_type(keytype) != EVP_PKEY_get_base_id(ret)) goto err; } else { - ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB); + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } + } else { + ERR_clear_last_mark(); } *pp = p; if (a != NULL) - (*a) = ret; + *a = ret; return ret; err: if (a == NULL || *a != ret) @@ -73,58 +140,36 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, return NULL; } -/* - * This works like d2i_PrivateKey() except it automatically works out the - * type - */ - -static EVP_PKEY *key_as_pkcs8(const unsigned char **pp, long length, int *carry_on) +EVP_PKEY *d2i_PrivateKey_ex(int keytype, EVP_PKEY **a, const unsigned char **pp, + long length, OSSL_LIB_CTX *libctx, + const char *propq) { - const unsigned char *p = *pp; - PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); EVP_PKEY *ret; - if (p8 == NULL) - return NULL; - - ret = EVP_PKCS82PKEY(p8); + ret = d2i_PrivateKey_decoder(keytype, a, pp, length, libctx, propq); + /* try the legacy path if the decoder failed */ if (ret == NULL) - *carry_on = 0; - - PKCS8_PRIV_KEY_INFO_free(p8); - - if (ret != NULL) - *pp = p; - + ret = ossl_d2i_PrivateKey_legacy(keytype, a, pp, length, libctx, propq); return ret; } -EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, - long length) +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length) +{ + return d2i_PrivateKey_ex(type, a, pp, length, NULL, NULL); +} + +static EVP_PKEY *d2i_AutoPrivateKey_legacy(EVP_PKEY **a, + const unsigned char **pp, + long length, + OSSL_LIB_CTX *libctx, + const char *propq) { STACK_OF(ASN1_TYPE) *inkey; const unsigned char *p; int keytype; - EVP_PKEY *ret = NULL; - int carry_on = 1; - - ERR_set_mark(); - ret = key_as_pkcs8(pp, length, &carry_on); - if (ret != NULL) { - ERR_clear_last_mark(); - if (a != NULL) - *a = ret; - return ret; - } - if (carry_on == 0) { - ERR_clear_last_mark(); - ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY, - ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return NULL; - } p = *pp; - /* * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by * analyzing it we can determine the passed structure: this assumes the @@ -136,19 +181,55 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, * Since we only need to discern "traditional format" RSA and DSA keys we * can just count the elements. */ - if (sk_ASN1_TYPE_num(inkey) == 6) + if (sk_ASN1_TYPE_num(inkey) == 6) { keytype = EVP_PKEY_DSA; - else if (sk_ASN1_TYPE_num(inkey) == 4) + } else if (sk_ASN1_TYPE_num(inkey) == 4) { keytype = EVP_PKEY_EC; - else + } else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not + * traditional format */ + PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); + EVP_PKEY *ret; + + sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); + if (p8 == NULL) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return NULL; + } + ret = evp_pkcs82pkey_legacy(p8, libctx, propq); + PKCS8_PRIV_KEY_INFO_free(p8); + if (ret == NULL) + return NULL; + *pp = p; + if (a != NULL) { + *a = ret; + } + return ret; + } else { keytype = EVP_PKEY_RSA; + } sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); + return ossl_d2i_PrivateKey_legacy(keytype, a, pp, length, libctx, propq); +} - ret = d2i_PrivateKey(keytype, a, pp, length); - if (ret != NULL) - ERR_pop_to_mark(); - else - ERR_clear_last_mark(); +/* + * This works like d2i_PrivateKey() except it passes the keytype as + * EVP_PKEY_NONE, which then figures out the type during decoding. + */ +EVP_PKEY *d2i_AutoPrivateKey_ex(EVP_PKEY **a, const unsigned char **pp, + long length, OSSL_LIB_CTX *libctx, + const char *propq) +{ + EVP_PKEY *ret; + ret = d2i_PrivateKey_decoder(EVP_PKEY_NONE, a, pp, length, libctx, propq); + /* try the legacy path if the decoder failed */ + if (ret == NULL) + ret = d2i_AutoPrivateKey_legacy(a, pp, length, libctx, propq); return ret; } + +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length) +{ + return d2i_AutoPrivateKey_ex(a, pp, length, NULL, NULL); +} diff --git a/crypto/openssl/crypto/asn1/d2i_pu.c b/crypto/openssl/crypto/asn1/d2i_pu.c index 8327ac16ca9c..cf7825c43903 100644 --- a/crypto/openssl/crypto/asn1/d2i_pu.c +++ b/crypto/openssl/crypto/asn1/d2i_pu.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -23,55 +29,70 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) { EVP_PKEY *ret; + EVP_PKEY *copy = NULL; if ((a == NULL) || (*a == NULL)) { if ((ret = EVP_PKEY_new()) == NULL) { - ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return NULL; } - } else + } else { ret = *a; - if (type != EVP_PKEY_id(ret) && !EVP_PKEY_set_type(ret, type)) { - ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); +#ifndef OPENSSL_NO_EC + if (evp_pkey_is_provided(ret) + && EVP_PKEY_get_base_id(ret) == EVP_PKEY_EC) { + if (!evp_pkey_copy_downgraded(©, ret)) + goto err; + } +#endif + } + + if ((type != EVP_PKEY_get_id(ret) || copy != NULL) + && !EVP_PKEY_set_type(ret, type)) { + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } - switch (EVP_PKEY_id(ret)) { -#ifndef OPENSSL_NO_RSA + switch (EVP_PKEY_get_base_id(ret)) { case EVP_PKEY_RSA: if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) == NULL) { - ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } break; -#endif #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: - /* TMP UGLY CAST */ if (!d2i_DSAPublicKey(&ret->pkey.dsa, pp, length)) { - ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } break; #endif #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: + if (copy != NULL) { + /* use downgraded parameters from copy */ + ret->pkey.ec = copy->pkey.ec; + copy->pkey.ec = NULL; + } if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) { - ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } break; #endif default: - ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); goto err; } if (a != NULL) (*a) = ret; + EVP_PKEY_free(copy); return ret; err: if (a == NULL || *a != ret) EVP_PKEY_free(ret); + EVP_PKEY_free(copy); return NULL; } diff --git a/crypto/openssl/crypto/asn1/evp_asn1.c b/crypto/openssl/crypto/asn1/evp_asn1.c index 895085a520a1..13d8ed3893ab 100644 --- a/crypto/openssl/crypto/asn1/evp_asn1.c +++ b/crypto/openssl/crypto/asn1/evp_asn1.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,6 +11,7 @@ #include "internal/cryptlib.h" #include #include +#include "crypto/asn1.h" int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len) { @@ -26,14 +27,17 @@ int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len) return 1; } -/* int max_len: for returned value */ +/* int max_len: for returned value + * if passing NULL in data, nothing is copied but the necessary length + * for it is returned. + */ int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len) { int ret, num; const unsigned char *p; if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) { - ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_DATA_IS_WRONG); return -1; } p = ASN1_STRING_get0_data(a->value.octet_string); @@ -42,7 +46,36 @@ int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_l num = ret; else num = max_len; - memcpy(data, p, num); + if (num > 0 && data != NULL) + memcpy(data, p, num); + return ret; +} + +static ossl_inline void asn1_type_init_oct(ASN1_OCTET_STRING *oct, + unsigned char *data, int len) +{ + oct->data = data; + oct->type = V_ASN1_OCTET_STRING; + oct->length = len; + oct->flags = 0; +} + +static int asn1_type_get_int_oct(ASN1_OCTET_STRING *oct, int32_t anum, + long *num, unsigned char *data, int max_len) +{ + int ret = ASN1_STRING_length(oct), n; + + if (num != NULL) + *num = anum; + + if (max_len > ret) + n = ret; + else + n = max_len; + + if (data != NULL) + memcpy(data, ASN1_STRING_get0_data(oct), n); + return ret; } @@ -66,25 +99,18 @@ int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data, atmp.num = num; atmp.oct = &oct; - oct.data = data; - oct.type = V_ASN1_OCTET_STRING; - oct.length = len; - oct.flags = 0; + asn1_type_init_oct(&oct, data, len); if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(asn1_int_oct), &atmp, &a)) return 1; return 0; } -/* - * we return the actual length... - */ -/* int max_len: for returned value */ int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, unsigned char *data, int max_len) { asn1_int_oct *atmp = NULL; - int ret = -1, n; + int ret = -1; if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) { goto err; @@ -95,21 +121,67 @@ int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, if (atmp == NULL) goto err; - if (num != NULL) - *num = atmp->num; + ret = asn1_type_get_int_oct(atmp->oct, atmp->num, num, data, max_len); - ret = ASN1_STRING_length(atmp->oct); - if (max_len > ret) - n = ret; - else - n = max_len; - - if (data != NULL) - memcpy(data, ASN1_STRING_get0_data(atmp->oct), n); if (ret == -1) { err: - ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_DATA_IS_WRONG); } M_ASN1_free_of(atmp, asn1_int_oct); return ret; } + +typedef struct { + ASN1_OCTET_STRING *oct; + int32_t num; +} asn1_oct_int; + +/* + * Defined in RFC 5084 - + * Section 2. "Content-Authenticated Encryption Algorithms" + */ +ASN1_SEQUENCE(asn1_oct_int) = { + ASN1_SIMPLE(asn1_oct_int, oct, ASN1_OCTET_STRING), + ASN1_EMBED(asn1_oct_int, num, INT32) +} static_ASN1_SEQUENCE_END(asn1_oct_int) + +DECLARE_ASN1_ITEM(asn1_oct_int) + +int ossl_asn1_type_set_octetstring_int(ASN1_TYPE *a, long num, + unsigned char *data, int len) +{ + asn1_oct_int atmp; + ASN1_OCTET_STRING oct; + + atmp.num = num; + atmp.oct = &oct; + asn1_type_init_oct(&oct, data, len); + + if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(asn1_oct_int), &atmp, &a)) + return 1; + return 0; +} + +int ossl_asn1_type_get_octetstring_int(const ASN1_TYPE *a, long *num, + unsigned char *data, int max_len) +{ + asn1_oct_int *atmp = NULL; + int ret = -1; + + if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) + goto err; + + atmp = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(asn1_oct_int), a); + + if (atmp == NULL) + goto err; + + ret = asn1_type_get_int_oct(atmp->oct, atmp->num, num, data, max_len); + + if (ret == -1) { + err: + ERR_raise(ERR_LIB_ASN1, ASN1_R_DATA_IS_WRONG); + } + M_ASN1_free_of(atmp, asn1_oct_int); + return ret; +} diff --git a/crypto/openssl/crypto/asn1/f_int.c b/crypto/openssl/crypto/asn1/f_int.c index 3a18381173d4..d41e0069af63 100644 --- a/crypto/openssl/crypto/asn1/f_int.c +++ b/crypto/openssl/crypto/asn1/f_int.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -100,7 +100,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) k = 0; i -= again; if (i % 2 != 0) { - ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ODD_NUMBER_OF_CHARS); OPENSSL_free(s); return 0; } @@ -108,7 +108,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) if (num + i > slen) { sp = OPENSSL_clear_realloc(s, slen, num + i * 2); if (sp == NULL) { - ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); OPENSSL_free(s); return 0; } @@ -119,8 +119,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) for (n = 0; n < 2; n++) { m = OPENSSL_hexchar2int(bufp[k + n]); if (m < 0) { - ASN1err(ASN1_F_A2I_ASN1_INTEGER, - ASN1_R_NON_HEX_CHARACTERS); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NON_HEX_CHARACTERS); goto err; } s[num + j] <<= 4; @@ -137,7 +136,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) bs->data = s; return 1; err: - ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_SHORT_LINE); OPENSSL_free(s); return 0; } diff --git a/crypto/openssl/crypto/asn1/f_string.c b/crypto/openssl/crypto/asn1/f_string.c index 53dfec71b5d4..4b65110d9866 100644 --- a/crypto/openssl/crypto/asn1/f_string.c +++ b/crypto/openssl/crypto/asn1/f_string.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -91,7 +91,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size) k = 0; i -= again; if (i % 2 != 0) { - ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ODD_NUMBER_OF_CHARS); OPENSSL_free(s); return 0; } @@ -99,7 +99,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size) if (num + i > slen) { sp = OPENSSL_realloc(s, (unsigned int)num + i * 2); if (sp == NULL) { - ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); OPENSSL_free(s); return 0; } @@ -110,8 +110,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size) for (n = 0; n < 2; n++) { m = OPENSSL_hexchar2int(bufp[k + n]); if (m < 0) { - ASN1err(ASN1_F_A2I_ASN1_STRING, - ASN1_R_NON_HEX_CHARACTERS); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NON_HEX_CHARACTERS); OPENSSL_free(s); return 0; } @@ -130,7 +129,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size) return 1; err: - ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_SHORT_LINE); OPENSSL_free(s); return 0; } diff --git a/crypto/openssl/crypto/asn1/i2d_evp.c b/crypto/openssl/crypto/asn1/i2d_evp.c new file mode 100644 index 000000000000..0d66411be8fd --- /dev/null +++ b/crypto/openssl/crypto/asn1/i2d_evp.c @@ -0,0 +1,149 @@ +/* + * Copyright 1995-2022 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 + */ + +/* + * Low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include +#include /* For i2d_RSAPublicKey */ +#include /* For i2d_DSAPublicKey */ +#include /* For i2o_ECPublicKey */ +#include "crypto/asn1.h" +#include "crypto/evp.h" + +struct type_and_structure_st { + const char *output_type; + const char *output_structure; +}; + +static int i2d_provided(const EVP_PKEY *a, int selection, + const struct type_and_structure_st *output_info, + unsigned char **pp) +{ + OSSL_ENCODER_CTX *ctx = NULL; + int ret; + + for (ret = -1; + ret == -1 && output_info->output_type != NULL; + output_info++) { + /* + * The i2d_ calls don't take a boundary length for *pp. However, + * OSSL_ENCODER_to_data() needs one, so we make one up. Because + * OSSL_ENCODER_to_data() decrements this number by the amount of + * bytes written, we need to calculate the length written further + * down, when pp != NULL. + */ + size_t len = INT_MAX; + int pp_was_NULL = (pp == NULL || *pp == NULL); + + ctx = OSSL_ENCODER_CTX_new_for_pkey(a, selection, + output_info->output_type, + output_info->output_structure, + NULL); + if (ctx == NULL) + return -1; + if (OSSL_ENCODER_to_data(ctx, pp, &len)) { + if (pp_was_NULL) + ret = (int)len; + else + ret = INT_MAX - (int)len; + } + OSSL_ENCODER_CTX_free(ctx); + ctx = NULL; + } + + if (ret == -1) + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE); + return ret; +} + +int i2d_KeyParams(const EVP_PKEY *a, unsigned char **pp) +{ + if (evp_pkey_is_provided(a)) { + static const struct type_and_structure_st output_info[] = { + { "DER", "type-specific" }, + { NULL, } + }; + + return i2d_provided(a, EVP_PKEY_KEY_PARAMETERS, output_info, pp); + } + if (a->ameth != NULL && a->ameth->param_encode != NULL) + return a->ameth->param_encode(a, pp); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE); + return -1; +} + +int i2d_KeyParams_bio(BIO *bp, const EVP_PKEY *pkey) +{ + return ASN1_i2d_bio_of(EVP_PKEY, i2d_KeyParams, bp, pkey); +} + +int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp) +{ + if (evp_pkey_is_provided(a)) { + static const struct type_and_structure_st output_info[] = { + { "DER", "type-specific" }, + { "DER", "PrivateKeyInfo" }, + { NULL, } + }; + + return i2d_provided(a, EVP_PKEY_KEYPAIR, output_info, pp); + } + if (a->ameth != NULL && a->ameth->old_priv_encode != NULL) { + return a->ameth->old_priv_encode(a, pp); + } + if (a->ameth != NULL && a->ameth->priv_encode != NULL) { + PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a); + int ret = 0; + + if (p8 != NULL) { + ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp); + PKCS8_PRIV_KEY_INFO_free(p8); + } + return ret; + } + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return -1; +} + +int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp) +{ + if (evp_pkey_is_provided(a)) { + static const struct type_and_structure_st output_info[] = { + { "DER", "type-specific" }, + { "blob", NULL }, /* for EC */ + { NULL, } + }; + + return i2d_provided(a, EVP_PKEY_PUBLIC_KEY, output_info, pp); + } + switch (EVP_PKEY_get_base_id(a)) { + case EVP_PKEY_RSA: + return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp); +#ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp); +#endif +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp); +#endif + default: + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return -1; + } +} diff --git a/crypto/openssl/crypto/asn1/i2d_pr.c b/crypto/openssl/crypto/asn1/i2d_pr.c deleted file mode 100644 index 0374c0bfbdc0..000000000000 --- a/crypto/openssl/crypto/asn1/i2d_pr.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 1995-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 - */ - -#include -#include "internal/cryptlib.h" -#include -#include -#include "crypto/asn1.h" -#include "crypto/evp.h" - -int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) -{ - if (a->ameth && a->ameth->old_priv_encode) { - return a->ameth->old_priv_encode(a, pp); - } - if (a->ameth && a->ameth->priv_encode) { - PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a); - int ret = 0; - if (p8 != NULL) { - ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp); - PKCS8_PRIV_KEY_INFO_free(p8); - } - return ret; - } - ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return -1; -} diff --git a/crypto/openssl/crypto/asn1/i2d_pu.c b/crypto/openssl/crypto/asn1/i2d_pu.c deleted file mode 100644 index 8986c43cbee5..000000000000 --- a/crypto/openssl/crypto/asn1/i2d_pu.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 1995-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 - */ - -#include -#include "internal/cryptlib.h" -#include -#include -#include -#include -#include -#include - -int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp) -{ - switch (EVP_PKEY_id(a)) { -#ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp); -#endif -#ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp); -#endif -#ifndef OPENSSL_NO_EC - case EVP_PKEY_EC: - return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp); -#endif - default: - ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return -1; - } -} diff --git a/crypto/openssl/crypto/asn1/n_pkey.c b/crypto/openssl/crypto/asn1/n_pkey.c index d1fb8a146d62..eb0918f79f97 100644 --- a/crypto/openssl/crypto/asn1/n_pkey.c +++ b/crypto/openssl/crypto/asn1/n_pkey.c @@ -1,26 +1,26 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include "openssl/opensslconf.h" -#ifdef OPENSSL_NO_RSA -NON_EMPTY_TRANSLATION_UNIT -#else - -# include "internal/cryptlib.h" -# include -# include -# include -# include -# include -# include - -# ifndef OPENSSL_NO_RC4 +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include +#include +#include + +#define ASN1_BROKEN_SEQUENCE(tname) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ + ASN1_SEQUENCE(tname) +#define static_ASN1_BROKEN_SEQUENCE_END(stname) \ + static_ASN1_SEQUENCE_END_ref(stname, stname) typedef struct netscape_pkey_st { int32_t version; @@ -43,9 +43,9 @@ ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = { ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG) } static_ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY) -DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY) -IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_ENCRYPTED_PKEY) +DECLARE_ASN1_ENCODE_FUNCTIONS_name(NETSCAPE_ENCRYPTED_PKEY, NETSCAPE_ENCRYPTED_PKEY) +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_ENCRYPTED_PKEY) ASN1_SEQUENCE(NETSCAPE_PKEY) = { ASN1_EMBED(NETSCAPE_PKEY, version, INT32), @@ -53,10 +53,6 @@ ASN1_SEQUENCE(NETSCAPE_PKEY) = { ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING) } static_ASN1_SEQUENCE_END(NETSCAPE_PKEY) -DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY) -IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY) - -# endif /* OPENSSL_NO_RC4 */ - -#endif +DECLARE_ASN1_FUNCTIONS(NETSCAPE_PKEY) +DECLARE_ASN1_ENCODE_FUNCTIONS_name(NETSCAPE_PKEY, NETSCAPE_PKEY) +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_PKEY) diff --git a/crypto/openssl/crypto/asn1/nsseq.c b/crypto/openssl/crypto/asn1/nsseq.c index c7baf40d30f5..09dc24f25f8d 100644 --- a/crypto/openssl/crypto/asn1/nsseq.c +++ b/crypto/openssl/crypto/asn1/nsseq.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/asn1/p5_pbe.c b/crypto/openssl/crypto/asn1/p5_pbe.c index ab7e16898fa3..9bc8aaa7a31e 100644 --- a/crypto/openssl/crypto/asn1/p5_pbe.c +++ b/crypto/openssl/crypto/asn1/p5_pbe.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -24,8 +24,9 @@ IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM) /* Set an algorithm identifier for a PKCS#5 PBE algorithm */ -int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, - const unsigned char *salt, int saltlen) +int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen, + OSSL_LIB_CTX *ctx) { PBEPARAM *pbe = NULL; ASN1_STRING *pbe_str = NULL; @@ -33,33 +34,35 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, pbe = PBEPARAM_new(); if (pbe == NULL) { - ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } if (iter <= 0) iter = PKCS5_DEFAULT_ITER; if (!ASN1_INTEGER_set(pbe->iter, iter)) { - ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } if (!saltlen) saltlen = PKCS5_SALT_LEN; + if (saltlen < 0) + goto err; sstr = OPENSSL_malloc(saltlen); if (sstr == NULL) { - ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } if (salt) memcpy(sstr, salt, saltlen); - else if (RAND_bytes(sstr, saltlen) <= 0) + else if (RAND_bytes_ex(ctx, sstr, saltlen, 0) <= 0) goto err; ASN1_STRING_set0(pbe->salt, sstr, saltlen); sstr = NULL; if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) { - ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } @@ -76,21 +79,35 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, return 0; } +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen) +{ + return PKCS5_pbe_set0_algor_ex(algor, alg, iter, salt, saltlen, NULL); +} + /* Return an algorithm identifier for a PKCS#5 PBE algorithm */ -X509_ALGOR *PKCS5_pbe_set(int alg, int iter, - const unsigned char *salt, int saltlen) +X509_ALGOR *PKCS5_pbe_set_ex(int alg, int iter, + const unsigned char *salt, int saltlen, + OSSL_LIB_CTX *ctx) { X509_ALGOR *ret; ret = X509_ALGOR_new(); if (ret == NULL) { - ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } - if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen)) + if (PKCS5_pbe_set0_algor_ex(ret, alg, iter, salt, saltlen, ctx)) return ret; X509_ALGOR_free(ret); return NULL; } + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen) +{ + return PKCS5_pbe_set_ex(alg, iter, salt, saltlen, NULL); +} + diff --git a/crypto/openssl/crypto/asn1/p5_pbev2.c b/crypto/openssl/crypto/asn1/p5_pbev2.c index f91ba08f1ea4..711743a77b59 100644 --- a/crypto/openssl/crypto/asn1/p5_pbev2.c +++ b/crypto/openssl/crypto/asn1/p5_pbev2.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,6 +10,8 @@ #include #include "internal/cryptlib.h" #include +#include +#include #include #include @@ -37,20 +39,20 @@ IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM) * and IV. */ -X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, - unsigned char *salt, int saltlen, - unsigned char *aiv, int prf_nid) +X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid, + OSSL_LIB_CTX *libctx) { X509_ALGOR *scheme = NULL, *ret = NULL; - int alg_nid, keylen; + int alg_nid, keylen, ivlen; EVP_CIPHER_CTX *ctx = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; PBE2PARAM *pbe2 = NULL; - alg_nid = EVP_CIPHER_type(cipher); + alg_nid = EVP_CIPHER_get_type(cipher); if (alg_nid == NID_undef) { - ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, - ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + ERR_raise(ERR_LIB_ASN1, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); goto err; } @@ -64,10 +66,11 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, goto merr; /* Create random IV */ - if (EVP_CIPHER_iv_length(cipher)) { + ivlen = EVP_CIPHER_get_iv_length(cipher); + if (ivlen > 0) { if (aiv) - memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); - else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0) + memcpy(iv, aiv, ivlen); + else if (RAND_bytes_ex(libctx, iv, ivlen, 0) <= 0) goto err; } @@ -79,25 +82,26 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0)) goto err; if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) <= 0) { - ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); goto err; } /* * If prf NID unspecified see if cipher has a preference. An error is OK * here: just means use default PRF. */ + ERR_set_mark(); if ((prf_nid == -1) && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) { - ERR_clear_error(); prf_nid = NID_hmacWithSHA256; } + ERR_pop_to_mark(); EVP_CIPHER_CTX_free(ctx); ctx = NULL; /* If its RC2 then we'd better setup the key length */ if (alg_nid == NID_rc2_cbc) - keylen = EVP_CIPHER_key_length(cipher); + keylen = EVP_CIPHER_get_key_length(cipher); else keylen = -1; @@ -105,9 +109,10 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, X509_ALGOR_free(pbe2->keyfunc); - pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen); + pbe2->keyfunc = PKCS5_pbkdf2_set_ex(iter, salt, saltlen, prf_nid, keylen, + libctx); - if (!pbe2->keyfunc) + if (pbe2->keyfunc == NULL) goto merr; /* Now set up top level AlgorithmIdentifier */ @@ -129,7 +134,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, return ret; merr: - ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); err: EVP_CIPHER_CTX_free(ctx); @@ -140,14 +145,25 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, return NULL; } +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid) +{ + return PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, aiv, prf_nid, + NULL); +} + X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, unsigned char *salt, int saltlen) { - return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1); + return PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, NULL, -1, + NULL); } -X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, - int prf_nid, int keylen) + +X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen, + OSSL_LIB_CTX *libctx) { X509_ALGOR *keyfunc = NULL; PBKDF2PARAM *kdf = NULL; @@ -161,6 +177,8 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, kdf->salt->value.octet_string = osalt; kdf->salt->type = V_ASN1_OCTET_STRING; + if (saltlen < 0) + goto merr; if (saltlen == 0) saltlen = PKCS5_SALT_LEN; if ((osalt->data = OPENSSL_malloc(saltlen)) == NULL) @@ -170,7 +188,7 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, if (salt) memcpy(osalt->data, salt, saltlen); - else if (RAND_bytes(osalt->data, saltlen) <= 0) + else if (RAND_bytes_ex(libctx, osalt->data, saltlen, 0) <= 0) goto merr; if (iter <= 0) @@ -214,8 +232,15 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, return keyfunc; merr: - ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); PBKDF2PARAM_free(kdf); X509_ALGOR_free(keyfunc); return NULL; } + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen) +{ + return PKCS5_pbkdf2_set_ex(iter, salt, saltlen, prf_nid, keylen, NULL); +} + diff --git a/crypto/openssl/crypto/asn1/p5_scrypt.c b/crypto/openssl/crypto/asn1/p5_scrypt.c index 1491d96ec8d3..a02190d0dc11 100644 --- a/crypto/openssl/crypto/asn1/p5_scrypt.c +++ b/crypto/openssl/crypto/asn1/p5_scrypt.c @@ -1,7 +1,7 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,10 +10,12 @@ #include #include "internal/cryptlib.h" #include +#include #include #include #include #include +#include "crypto/evp.h" #ifndef OPENSSL_NO_SCRYPT /* PKCS#5 scrypt password based encryption structures */ @@ -49,20 +51,18 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, PBE2PARAM *pbe2 = NULL; if (!cipher) { - ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER); goto err; } if (EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) { - ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, - ASN1_R_INVALID_SCRYPT_PARAMETERS); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_SCRYPT_PARAMETERS); goto err; } - alg_nid = EVP_CIPHER_type(cipher); + alg_nid = EVP_CIPHER_get_type(cipher); if (alg_nid == NID_undef) { - ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, - ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + ERR_raise(ERR_LIB_ASN1, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); goto err; } @@ -79,10 +79,10 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, goto merr; /* Create random IV */ - if (EVP_CIPHER_iv_length(cipher)) { + if (EVP_CIPHER_get_iv_length(cipher)) { if (aiv) - memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); - else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0) + memcpy(iv, aiv, EVP_CIPHER_get_iv_length(cipher)); + else if (RAND_bytes(iv, EVP_CIPHER_get_iv_length(cipher)) <= 0) goto err; } @@ -94,8 +94,7 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0) == 0) goto err; if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) <= 0) { - ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, - ASN1_R_ERROR_SETTING_CIPHER_PARAMS); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); goto err; } EVP_CIPHER_CTX_free(ctx); @@ -104,7 +103,7 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, /* If its RC2 then we'd better setup the key length */ if (alg_nid == NID_rc2_cbc) - keylen = EVP_CIPHER_key_length(cipher); + keylen = EVP_CIPHER_get_key_length(cipher); /* Setup keyfunc */ @@ -135,7 +134,7 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, return ret; merr: - ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); err: PBE2PARAM_free(pbe2); @@ -202,26 +201,27 @@ static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen, return keyfunc; merr: - ASN1err(ASN1_F_PKCS5_SCRYPT_SET, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); err: SCRYPT_PARAMS_free(sparam); X509_ALGOR_free(keyfunc); return NULL; } -int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, - int passlen, ASN1_TYPE *param, - const EVP_CIPHER *c, const EVP_MD *md, int en_de) +int PKCS5_v2_scrypt_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, int en_de, + OSSL_LIB_CTX *libctx, const char *propq) { unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; uint64_t p, r, N; size_t saltlen; size_t keylen = 0; - int rv = 0; + int t, rv = 0; SCRYPT_PARAMS *sparam = NULL; - if (EVP_CIPHER_CTX_cipher(ctx) == NULL) { - EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_NO_CIPHER_SET); + if (EVP_CIPHER_CTX_get0_cipher(ctx) == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); goto err; } @@ -230,11 +230,16 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, sparam = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), param); if (sparam == NULL) { - EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_DECODE_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); goto err; } - keylen = EVP_CIPHER_CTX_key_length(ctx); + t = EVP_CIPHER_CTX_get_key_length(ctx); + if (t < 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH); + goto err; + } + keylen = t; /* Now check the parameters of sparam */ @@ -242,8 +247,7 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, uint64_t spkeylen; if ((ASN1_INTEGER_get_uint64(&spkeylen, sparam->keyLength) == 0) || (spkeylen != keylen)) { - EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, - EVP_R_UNSUPPORTED_KEYLENGTH); + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEYLENGTH); goto err; } } @@ -251,9 +255,9 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, if (ASN1_INTEGER_get_uint64(&N, sparam->costParameter) == 0 || ASN1_INTEGER_get_uint64(&r, sparam->blockSize) == 0 || ASN1_INTEGER_get_uint64(&p, sparam->parallelizationParameter) == 0 - || EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) { - EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, - EVP_R_ILLEGAL_SCRYPT_PARAMETERS); + || EVP_PBE_scrypt_ex(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0, + libctx, propq) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_ILLEGAL_SCRYPT_PARAMETERS); goto err; } @@ -261,8 +265,8 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, salt = sparam->salt->data; saltlen = sparam->salt->length; - if (EVP_PBE_scrypt(pass, passlen, salt, saltlen, N, r, p, 0, key, keylen) - == 0) + if (EVP_PBE_scrypt_ex(pass, passlen, salt, saltlen, N, r, p, 0, key, + keylen, libctx, propq) == 0) goto err; rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); err: @@ -271,4 +275,12 @@ int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, SCRYPT_PARAMS_free(sparam); return rv; } + +int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, int en_de) +{ + return PKCS5_v2_scrypt_keyivgen_ex(ctx, pass, passlen, param, c, md, en_de, NULL, NULL); +} + #endif /* OPENSSL_NO_SCRYPT */ diff --git a/crypto/openssl/crypto/asn1/p8_pkey.c b/crypto/openssl/crypto/asn1/p8_pkey.c index ab509b1ac976..dee188519c22 100644 --- a/crypto/openssl/crypto/asn1/p8_pkey.c +++ b/crypto/openssl/crypto/asn1/p8_pkey.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -78,3 +78,14 @@ int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, return 1; return 0; } + +int PKCS8_pkey_add1_attr_by_OBJ(PKCS8_PRIV_KEY_INFO *p8, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) +{ + return (X509at_add1_attr_by_OBJ(&p8->attributes, obj, type, bytes, len) != NULL); +} + +int PKCS8_pkey_add1_attr(PKCS8_PRIV_KEY_INFO *p8, X509_ATTRIBUTE *attr) +{ + return (X509at_add1_attr(&p8->attributes, attr) != NULL); +} diff --git a/crypto/openssl/crypto/asn1/standard_methods.h b/crypto/openssl/crypto/asn1/standard_methods.h index e74de55ffeb6..0b0c7ef6864f 100644 --- a/crypto/openssl/crypto/asn1/standard_methods.h +++ b/crypto/openssl/crypto/asn1/standard_methods.h @@ -1,7 +1,7 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,49 +13,35 @@ * is used to search it. */ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { -#ifndef OPENSSL_NO_RSA - &rsa_asn1_meths[0], - &rsa_asn1_meths[1], -#endif + &ossl_rsa_asn1_meths[0], + &ossl_rsa_asn1_meths[1], #ifndef OPENSSL_NO_DH - &dh_asn1_meth, + &ossl_dh_asn1_meth, #endif #ifndef OPENSSL_NO_DSA - &dsa_asn1_meths[0], - &dsa_asn1_meths[1], - &dsa_asn1_meths[2], - &dsa_asn1_meths[3], - &dsa_asn1_meths[4], + &ossl_dsa_asn1_meths[0], + &ossl_dsa_asn1_meths[1], + &ossl_dsa_asn1_meths[2], + &ossl_dsa_asn1_meths[3], + &ossl_dsa_asn1_meths[4], #endif #ifndef OPENSSL_NO_EC - &eckey_asn1_meth, -#endif - &hmac_asn1_meth, -#ifndef OPENSSL_NO_CMAC - &cmac_asn1_meth, -#endif -#ifndef OPENSSL_NO_RSA - &rsa_pss_asn1_meth, + &ossl_eckey_asn1_meth, #endif + &ossl_rsa_pss_asn1_meth, #ifndef OPENSSL_NO_DH - &dhx_asn1_meth, + &ossl_dhx_asn1_meth, #endif #ifndef OPENSSL_NO_EC - &ecx25519_asn1_meth, - &ecx448_asn1_meth, -#endif -#ifndef OPENSSL_NO_POLY1305 - &poly1305_asn1_meth, -#endif -#ifndef OPENSSL_NO_SIPHASH - &siphash_asn1_meth, + &ossl_ecx25519_asn1_meth, + &ossl_ecx448_asn1_meth, #endif #ifndef OPENSSL_NO_EC - &ed25519_asn1_meth, - &ed448_asn1_meth, + &ossl_ed25519_asn1_meth, + &ossl_ed448_asn1_meth, #endif #ifndef OPENSSL_NO_SM2 - &sm2_asn1_meth, + &ossl_sm2_asn1_meth, #endif }; diff --git a/crypto/openssl/crypto/asn1/t_bitst.c b/crypto/openssl/crypto/asn1/t_bitst.c index c0aeca4c78cc..e7b817f78e15 100644 --- a/crypto/openssl/crypto/asn1/t_bitst.c +++ b/crypto/openssl/crypto/asn1/t_bitst.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/asn1/t_pkey.c b/crypto/openssl/crypto/asn1/t_pkey.c index 651622aedc8f..03579c877cfc 100644 --- a/crypto/openssl/crypto/asn1/t_pkey.c +++ b/crypto/openssl/crypto/asn1/t_pkey.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/asn1/t_spki.c b/crypto/openssl/crypto/asn1/t_spki.c index 3d4aea8ad9a4..0397f1f9ee50 100644 --- a/crypto/openssl/crypto/asn1/t_spki.c +++ b/crypto/openssl/crypto/asn1/t_spki.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -30,7 +30,7 @@ int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki) BIO_printf(out, " Public Key Algorithm: %s\n", (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); pkey = X509_PUBKEY_get(spki->spkac->pubkey); - if (!pkey) + if (pkey == NULL) BIO_printf(out, " Unable to load public key\n"); else { EVP_PKEY_print_public(out, pkey, 4, NULL); diff --git a/crypto/openssl/crypto/asn1/tasn_dec.c b/crypto/openssl/crypto/asn1/tasn_dec.c index 82577b1edefe..11198087a57b 100644 --- a/crypto/openssl/crypto/asn1/tasn_dec.c +++ b/crypto/openssl/crypto/asn1/tasn_dec.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -17,7 +17,6 @@ #include "internal/numbers.h" #include "asn1_local.h" - /* * Constructed types with a recursive definition (such as can be found in PKCS7) * could eventually exceed the stack given malicious input with excessive @@ -29,7 +28,8 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx, - int depth); + int depth, OSSL_LIB_CTX *libctx, + const char *propq); static int asn1_check_eoc(const unsigned char **in, long len); static int asn1_find_end(const unsigned char **in, long len, char inf); @@ -47,11 +47,13 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth); + ASN1_TLC *ctx, int depth, OSSL_LIB_CTX *libctx, + const char *propq); static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth); + ASN1_TLC *ctx, int depth, + OSSL_LIB_CTX *libctx, const char *propq); static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, @@ -67,7 +69,7 @@ static const unsigned long tag2bit[32] = { /* tags 4- 7 */ B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, /* tags 8-11 */ - B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, + B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, 0, B_ASN1_UNKNOWN, /* tags 12-15 */ B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags 16-19 */ @@ -91,9 +93,9 @@ unsigned long ASN1_tag2bit(int tag) /* Macro to initialize and invalidate the cache */ -#define asn1_tlc_clear(c) if (c) (c)->valid = 0 +#define asn1_tlc_clear(c) do { if ((c) != NULL) (c)->valid = 0; } while (0) /* Version to avoid compiler warning about 'c' always non-NULL */ -#define asn1_tlc_clear_nc(c) (c)->valid = 0 +#define asn1_tlc_clear_nc(c) do {(c)->valid = 0; } while (0) /* * Decode an ASN1 item, this currently behaves just like a standard 'd2i' @@ -102,29 +104,54 @@ unsigned long ASN1_tag2bit(int tag) * this will simply be a special case. */ -ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, - const unsigned char **in, long len, - const ASN1_ITEM *it) +static int asn1_item_ex_d2i_intern(ASN1_VALUE **pval, const unsigned char **in, + long len, const ASN1_ITEM *it, int tag, + int aclass, char opt, ASN1_TLC *ctx, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int rv; + + if (pval == NULL || it == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0, + libctx, propq); + if (rv <= 0) + ASN1_item_ex_free(pval, it); + return rv; +} + +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) +{ + return asn1_item_ex_d2i_intern(pval, in, len, it, tag, aclass, opt, ctx, + NULL, NULL); +} + +ASN1_VALUE *ASN1_item_d2i_ex(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it, OSSL_LIB_CTX *libctx, + const char *propq) { ASN1_TLC c; ASN1_VALUE *ptmpval = NULL; - if (!pval) + + if (pval == NULL) pval = &ptmpval; asn1_tlc_clear_nc(&c); - if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) + if (asn1_item_ex_d2i_intern(pval, in, len, it, -1, 0, 0, &c, libctx, + propq) > 0) return *pval; return NULL; } -int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it) { - int rv; - rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); - if (rv <= 0) - ASN1_item_ex_free(pval, it); - return rv; + return ASN1_item_d2i_ex(pval, in, len, it, NULL, NULL); } /* @@ -135,11 +162,12 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx, - int depth) + int depth, OSSL_LIB_CTX *libctx, + const char *propq) { const ASN1_TEMPLATE *tt, *errtt = NULL; const ASN1_EXTERN_FUNCS *ef; - const ASN1_AUX *aux = it->funcs; + const ASN1_AUX *aux; ASN1_aux_cb *asn1_cb; const unsigned char *p = NULL, *q; unsigned char oclass; @@ -149,15 +177,23 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, int otag; int ret = 0; ASN1_VALUE **pchptr; - if (!pval) + + if (pval == NULL || it == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER); return 0; + } + if (len <= 0) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL); + return 0; + } + aux = it->funcs; if (aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; else asn1_cb = 0; if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_NESTED_TOO_DEEP); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NESTED_TOO_DEEP); goto err; } @@ -171,12 +207,12 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, * template in the template itself. */ if ((tag != -1) || opt) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, - ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); + ERR_raise(ERR_LIB_ASN1, + ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); goto err; } - return asn1_template_ex_d2i(pval, in, len, - it->templates, opt, ctx, depth); + return asn1_template_ex_d2i(pval, in, len, it->templates, opt, ctx, + depth, libctx, propq); } return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt, ctx); @@ -187,7 +223,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, * if tag != -1, then this looks like an error in the template. */ if (tag != -1) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_BAD_TEMPLATE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_TEMPLATE); goto err; } @@ -196,7 +232,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, &p, len, -1, 0, 1, ctx); if (!ret) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; } @@ -205,7 +241,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, /* If OPTIONAL, assume this is OK */ if (opt) return -1; - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL); goto err; } @@ -214,7 +250,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, /* If OPTIONAL, assume this is OK */ if (opt) return -1; - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MSTRING_WRONG_TAG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MSTRING_WRONG_TAG); goto err; } return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); @@ -222,6 +258,9 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, case ASN1_ITYPE_EXTERN: /* Use new style d2i */ ef = it->funcs; + if (ef->asn1_ex_d2i_ex != NULL) + return ef->asn1_ex_d2i_ex(pval, in, len, it, tag, aclass, opt, ctx, + libctx, propq); return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); case ASN1_ITYPE_CHOICE: @@ -230,7 +269,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, * if tag != -1, then this looks like an error in the template. */ if (tag != -1) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_BAD_TEMPLATE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_TEMPLATE); goto err; } @@ -238,25 +277,26 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, goto auxerr; if (*pval) { /* Free up and zero CHOICE value if initialised */ - i = asn1_get_choice_selector(pval, it); + i = ossl_asn1_get_choice_selector(pval, it); if ((i >= 0) && (i < it->tcount)) { tt = it->templates + i; - pchptr = asn1_get_field_ptr(pval, tt); - asn1_template_free(pchptr, tt); - asn1_set_choice_selector(pval, -1, it); + pchptr = ossl_asn1_get_field_ptr(pval, tt); + ossl_asn1_template_free(pchptr, tt); + ossl_asn1_set_choice_selector(pval, -1, it); } - } else if (!ASN1_item_ex_new(pval, it)) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR); + } else if (!ossl_asn1_item_ex_new_intern(pval, it, libctx, propq)) { + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; } /* CHOICE type, try each possibility in turn */ p = *in; for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { - pchptr = asn1_get_field_ptr(pval, tt); + pchptr = ossl_asn1_get_field_ptr(pval, tt); /* * We mark field as OPTIONAL so its absence can be recognised. */ - ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth); + ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth, + libctx, propq); /* If field not present, try the next one */ if (ret == -1) continue; @@ -267,9 +307,9 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, * Must be an ASN1 parsing error. * Free up any partial choice value */ - asn1_template_free(pchptr, tt); + ossl_asn1_template_free(pchptr, tt); errtt = tt; - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; } @@ -281,11 +321,11 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, ASN1_item_ex_free(pval, it); return -1; } - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE); goto err; } - asn1_set_choice_selector(pval, i, it); + ossl_asn1_set_choice_selector(pval, i, it); if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) goto auxerr; @@ -306,7 +346,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, &p, len, tag, aclass, opt, ctx); if (!ret) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; } else if (ret == -1) return -1; @@ -318,12 +358,13 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, else seq_nolen = seq_eoc; if (!cst) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); + ERR_raise(ERR_LIB_ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); goto err; } - if (!*pval && !ASN1_item_ex_new(pval, it)) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR); + if (*pval == NULL + && !ossl_asn1_item_ex_new_intern(pval, it, libctx, propq)) { + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; } @@ -335,11 +376,11 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, if (tt->flags & ASN1_TFLG_ADB_MASK) { const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 0); + seqtt = ossl_asn1_do_adb(*pval, tt, 0); if (seqtt == NULL) continue; - pseqval = asn1_get_field_ptr(pval, seqtt); - asn1_template_free(pseqval, seqtt); + pseqval = ossl_asn1_get_field_ptr(pval, seqtt); + ossl_asn1_template_free(pseqval, seqtt); } } @@ -347,22 +388,21 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 1); + seqtt = ossl_asn1_do_adb(*pval, tt, 1); if (seqtt == NULL) goto err; - pseqval = asn1_get_field_ptr(pval, seqtt); + pseqval = ossl_asn1_get_field_ptr(pval, seqtt); /* Have we ran out of data? */ if (!len) break; q = p; if (asn1_check_eoc(&p, len)) { if (!seq_eoc) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_UNEXPECTED_EOC); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNEXPECTED_EOC); goto err; } len -= p - q; seq_eoc = 0; - q = p; break; } /* @@ -380,7 +420,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, */ ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx, - depth); + depth, libctx, propq); if (!ret) { errtt = seqtt; goto err; @@ -388,7 +428,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, /* * OPTIONAL component absent. Free and zero the field. */ - asn1_template_free(pseqval, seqtt); + ossl_asn1_template_free(pseqval, seqtt); continue; } /* Update length */ @@ -397,12 +437,12 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, /* Check for EOC if expecting one */ if (seq_eoc && !asn1_check_eoc(&p, len)) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MISSING_EOC); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MISSING_EOC); goto err; } /* Check all data read */ if (!seq_nolen && len) { - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH); + ERR_raise(ERR_LIB_ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH); goto err; } @@ -413,21 +453,21 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, */ for (; i < it->tcount; tt++, i++) { const ASN1_TEMPLATE *seqtt; - seqtt = asn1_do_adb(pval, tt, 1); + seqtt = ossl_asn1_do_adb(*pval, tt, 1); if (seqtt == NULL) goto err; if (seqtt->flags & ASN1_TFLG_OPTIONAL) { ASN1_VALUE **pseqval; - pseqval = asn1_get_field_ptr(pval, seqtt); - asn1_template_free(pseqval, seqtt); + pseqval = ossl_asn1_get_field_ptr(pval, seqtt); + ossl_asn1_template_free(pseqval, seqtt); } else { errtt = seqtt; - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_FIELD_MISSING); + ERR_raise(ERR_LIB_ASN1, ASN1_R_FIELD_MISSING); goto err; } } /* Save encoding */ - if (!asn1_enc_save(pval, *in, p - *in, it)) + if (!ossl_asn1_enc_save(pval, *in, p - *in, it)) goto auxerr; if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) goto auxerr; @@ -438,7 +478,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, return 0; } auxerr: - ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_AUX_ERROR); + ERR_raise(ERR_LIB_ASN1, ASN1_R_AUX_ERROR); err: if (errtt) ERR_add_error_data(4, "Field=", errtt->field_name, @@ -456,7 +496,8 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth) + ASN1_TLC *ctx, int depth, + OSSL_LIB_CTX *libctx, const char *propq) { int flags, aclass; int ret; @@ -481,19 +522,19 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, &p, inlen, tt->tag, aclass, opt, ctx); q = p; if (!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); return 0; } else if (ret == -1) return -1; if (!cst) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, - ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); + ERR_raise(ERR_LIB_ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); return 0; } /* We've found the field so it can't be OPTIONAL now */ - ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); + ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth, libctx, + propq); if (!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); return 0; } /* We read the field in OK so update length */ @@ -501,7 +542,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, if (exp_eoc) { /* If NDEF we must have an EOC here */ if (!asn1_check_eoc(&p, len)) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MISSING_EOC); goto err; } } else { @@ -509,13 +550,13 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, * Otherwise we must hit the EXPLICIT tag end or its an error */ if (len) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, - ASN1_R_EXPLICIT_LENGTH_MISMATCH); + ERR_raise(ERR_LIB_ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH); goto err; } } } else - return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth); + return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth, + libctx, propq); *in = p; return 1; @@ -527,7 +568,8 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth) + ASN1_TLC *ctx, int depth, + OSSL_LIB_CTX *libctx, const char *propq) { int flags, aclass; int ret; @@ -539,7 +581,6 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, aclass = flags & ASN1_TFLG_TAG_CLASS; p = *in; - q = p; /* * If field is embedded then val needs fixing so it is a pointer to @@ -569,11 +610,11 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, &p, len, sktag, skaclass, opt, ctx); if (!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); return 0; } else if (ret == -1) return -1; - if (!*val) + if (*val == NULL) *val = (ASN1_VALUE *)sk_ASN1_VALUE_new_null(); else { /* @@ -587,8 +628,8 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, } } - if (!*val) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); + if (*val == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } @@ -599,8 +640,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, /* See if EOC found */ if (asn1_check_eoc(&p, len)) { if (!sk_eoc) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, - ASN1_R_UNEXPECTED_EOC); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNEXPECTED_EOC); goto err; } len -= p - q; @@ -608,42 +648,41 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, break; } skfield = NULL; - if (!asn1_item_embed_d2i(&skfield, &p, len, + if (asn1_item_embed_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx, - depth)) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, - ERR_R_NESTED_ASN1_ERROR); + depth, libctx, propq) <= 0) { + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); /* |skfield| may be partially allocated despite failure. */ ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item)); goto err; } len -= p - q; if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item)); goto err; } } if (sk_eoc) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MISSING_EOC); goto err; } } else if (flags & ASN1_TFLG_IMPTAG) { /* IMPLICIT tagging */ ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, - ctx, depth); + ctx, depth, libctx, propq); if (!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; } else if (ret == -1) return -1; } else { /* Nothing special */ ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), - -1, 0, opt, ctx, depth); + -1, 0, opt, ctx, depth, libctx, propq); if (!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); goto err; } else if (ret == -1) return -1; @@ -668,8 +707,9 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, BUF_MEM buf = { 0, NULL, 0, 0 }; const unsigned char *cont = NULL; long len; - if (!pval) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); + + if (pval == NULL) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_NULL); return 0; /* Should never happen */ } @@ -683,19 +723,18 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, /* If type is ANY need to figure out type from tag */ unsigned char oclass; if (tag >= 0) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_TAGGED_ANY); return 0; } if (opt) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, - ASN1_R_ILLEGAL_OPTIONAL_ANY); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY); return 0; } p = *in; ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, &p, inlen, -1, 0, 0, ctx); if (!ret) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); return 0; } if (oclass != V_ASN1_UNIVERSAL) @@ -710,7 +749,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, &p, inlen, tag, aclass, opt, ctx); if (!ret) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); return 0; } else if (ret == -1) return -1; @@ -727,8 +766,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, } /* SEQUENCE and SET must be constructed */ else if (!cst) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, - ASN1_R_TYPE_NOT_CONSTRUCTED); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED); return 0; } @@ -746,7 +784,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER || utype == V_ASN1_ENUMERATED) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); return 0; } @@ -764,7 +802,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, len = buf.length; /* Append a final null to string */ if (!BUF_MEM_grow_clean(&buf, len + 1)) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } buf.data[len] = 0; @@ -805,7 +843,7 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, return pf->prim_c2i(pval, cont, len, utype, free_cont, it); /* If ANY type clear type and set pointer to internal value */ if (it->utype == V_ASN1_ANY) { - if (!*pval) { + if (*pval == NULL) { typ = ASN1_TYPE_new(); if (typ == NULL) goto err; @@ -820,13 +858,13 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, } switch (utype) { case V_ASN1_OBJECT: - if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) + if (!ossl_c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) goto err; break; case V_ASN1_NULL: if (len) { - ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); goto err; } *pval = (ASN1_VALUE *)1; @@ -834,7 +872,7 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, case V_ASN1_BOOLEAN: if (len != 1) { - ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); + ERR_raise(ERR_LIB_ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); goto err; } else { ASN1_BOOLEAN *tbool; @@ -844,14 +882,14 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, break; case V_ASN1_BIT_STRING: - if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) + if (!ossl_c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) goto err; break; case V_ASN1_INTEGER: case V_ASN1_ENUMERATED: tint = (ASN1_INTEGER **)pval; - if (!c2i_ASN1_INTEGER(tint, &cont, len)) + if (!ossl_c2i_ASN1_INTEGER(tint, &cont, len)) goto err; /* Fixup type to match the expected form */ (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); @@ -876,19 +914,18 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, case V_ASN1_SEQUENCE: default: if (utype == V_ASN1_BMPSTRING && (len & 1)) { - ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); + ERR_raise(ERR_LIB_ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); goto err; } if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) { - ASN1err(ASN1_F_ASN1_EX_C2I, - ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); goto err; } /* All based on ASN1_STRING and handled the same */ - if (!*pval) { + if (*pval == NULL) { stmp = ASN1_STRING_type_new(utype); if (stmp == NULL) { - ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } *pval = (ASN1_VALUE *)stmp; @@ -904,7 +941,7 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, *free_cont = 0; } else { if (!ASN1_STRING_set(stmp, cont, len)) { - ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); ASN1_STRING_free(stmp); *pval = NULL; goto err; @@ -962,12 +999,12 @@ static int asn1_find_end(const unsigned char **in, long len, char inf) /* Just read in a header: only care about the length */ if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, -1, 0, 0, NULL)) { - ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); return 0; } if (inf) { if (expected_eoc == UINT32_MAX) { - ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); return 0; } expected_eoc++; @@ -977,7 +1014,7 @@ static int asn1_find_end(const unsigned char **in, long len, char inf) len -= p - q; } if (expected_eoc) { - ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MISSING_EOC); return 0; } *in = p; @@ -1024,7 +1061,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, * EOC is illegal outside indefinite length constructed form */ if (!inf) { - ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNEXPECTED_EOC); return 0; } inf = 0; @@ -1033,14 +1070,14 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, len, tag, aclass, 0, NULL)) { - ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); return 0; } /* If indefinite length constructed update max length */ if (cst) { if (depth >= ASN1_MAX_STRING_NEST) { - ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING); + ERR_raise(ERR_LIB_ASN1, ASN1_R_NESTED_ASN1_STRING); return 0; } if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1)) @@ -1050,7 +1087,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, len -= p - q; } if (inf) { - ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC); + ERR_raise(ERR_LIB_ASN1, ASN1_R_MISSING_EOC); return 0; } *in = p; @@ -1063,7 +1100,7 @@ static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) if (buf) { len = buf->length; if (!BUF_MEM_grow_clean(buf, len + plen)) { - ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } memcpy(buf->data + len, *p, plen); @@ -1077,10 +1114,11 @@ static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) static int asn1_check_eoc(const unsigned char **in, long len) { const unsigned char *p; + if (len < 2) return 0; p = *in; - if (!p[0] && !p[1]) { + if (p[0] == '\0' && p[1] == '\0') { *in += 2; return 1; } @@ -1106,7 +1144,11 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, p = *in; q = p; - if (ctx && ctx->valid) { + if (len <= 0) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL); + goto err; + } + if (ctx != NULL && ctx->valid) { i = ctx->ret; plen = ctx->plen; pclass = ctx->pclass; @@ -1114,7 +1156,7 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, p += ctx->hdrlen; } else { i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); - if (ctx) { + if (ctx != NULL) { ctx->ret = i; ctx->plen = plen; ctx->pclass = pclass; @@ -1125,29 +1167,26 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, * If definite length, and no error, length + header can't exceed * total amount of data available. */ - if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { - ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); - asn1_tlc_clear(ctx); - return 0; + if ((i & 0x81) == 0 && (plen + ctx->hdrlen) > len) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG); + goto err; } } } - if (i & 0x80) { - ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER); - asn1_tlc_clear(ctx); - return 0; + if ((i & 0x80) != 0) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_OBJECT_HEADER); + goto err; } if (exptag >= 0) { - if ((exptag != ptag) || (expclass != pclass)) { + if (exptag != ptag || expclass != pclass) { /* * If type is OPTIONAL, not an error: indicate missing type. */ - if (opt) + if (opt != 0) return -1; - asn1_tlc_clear(ctx); - ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG); - return 0; + ERR_raise(ERR_LIB_ASN1, ASN1_R_WRONG_TAG); + goto err; } /* * We have a tag and class match: assume we are going to do something @@ -1156,24 +1195,28 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, asn1_tlc_clear(ctx); } - if (i & 1) + if ((i & 1) != 0) plen = len - (p - q); - if (inf) + if (inf != NULL) *inf = i & 1; - if (cst) + if (cst != NULL) *cst = i & V_ASN1_CONSTRUCTED; - if (olen) + if (olen != NULL) *olen = plen; - if (oclass) + if (oclass != NULL) *oclass = pclass; - if (otag) + if (otag != NULL) *otag = ptag; *in = p; return 1; + + err: + asn1_tlc_clear(ctx); + return 0; } diff --git a/crypto/openssl/crypto/asn1/tasn_enc.c b/crypto/openssl/crypto/asn1/tasn_enc.c index bcc96337bca4..3ea18b0280dd 100644 --- a/crypto/openssl/crypto/asn1/tasn_enc.c +++ b/crypto/openssl/crypto/asn1/tasn_enc.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -16,16 +16,17 @@ #include "crypto/asn1.h" #include "asn1_local.h" -static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, +static int asn1_i2d_ex_primitive(const ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); -static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, +static int asn1_set_seq_out(STACK_OF(const_ASN1_VALUE) *sk, + unsigned char **out, int skcontlen, const ASN1_ITEM *item, int do_sort, int iclass); -static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, +static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt, int tag, int aclass); -static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, +static int asn1_item_flags_i2d(const ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it, int flags); -static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, +static int asn1_ex_i2c(const ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ITEM *it); /* @@ -33,13 +34,13 @@ static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, * indefinite length constructed encoding, where appropriate */ -int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, +int ASN1_item_ndef_i2d(const ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) { return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF); } -int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) +int ASN1_item_i2d(const ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) { return asn1_item_flags_i2d(val, out, it, 0); } @@ -51,10 +52,10 @@ int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) * allocated and populated with the encoding. */ -static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, +static int asn1_item_flags_i2d(const ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it, int flags) { - if (out && !*out) { + if (out != NULL && *out == NULL) { unsigned char *p, *buf; int len; @@ -62,7 +63,7 @@ static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, if (len <= 0) return len; if ((buf = OPENSSL_malloc(len)) == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_FLAGS_I2D, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } p = buf; @@ -79,20 +80,22 @@ static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, * performs the normal item handling: it can be used in external types. */ -int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, +int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) { const ASN1_TEMPLATE *tt = NULL; int i, seqcontlen, seqlen, ndef = 1; const ASN1_EXTERN_FUNCS *ef; const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb = 0; + ASN1_aux_const_cb *asn1_cb = NULL; - if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && *pval == NULL) return 0; - if (aux && aux->asn1_cb) - asn1_cb = aux->asn1_cb; + if (aux != NULL) { + asn1_cb = ((aux->flags & ASN1_AFLG_CONST_CB) != 0) ? aux->asn1_const_cb + : (ASN1_aux_const_cb *)aux->asn1_cb; /* backward compatibility */ + } switch (it->itype) { @@ -108,7 +111,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, * if tag != -1, then this looks like an error in the template. */ if (tag != -1) { - ASN1err(ASN1_F_ASN1_ITEM_EX_I2D, ASN1_R_BAD_TEMPLATE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_TEMPLATE); return -1; } return asn1_i2d_ex_primitive(pval, out, it, -1, aclass); @@ -119,17 +122,17 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, * if tag != -1, then this looks like an error in the template. */ if (tag != -1) { - ASN1err(ASN1_F_ASN1_ITEM_EX_I2D, ASN1_R_BAD_TEMPLATE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_TEMPLATE); return -1; } if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) return 0; - i = asn1_get_choice_selector(pval, it); + i = ossl_asn1_get_choice_selector_const(pval, it); if ((i >= 0) && (i < it->tcount)) { - ASN1_VALUE **pchval; + const ASN1_VALUE **pchval; const ASN1_TEMPLATE *chtt; chtt = it->templates + i; - pchval = asn1_get_field_ptr(pval, chtt); + pchval = ossl_asn1_get_const_field_ptr(pval, chtt); return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass); } /* Fixme: error condition if selector out of range */ @@ -149,7 +152,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, /* fall through */ case ASN1_ITYPE_SEQUENCE: - i = asn1_enc_restore(&seqcontlen, out, pval, it); + i = ossl_asn1_enc_restore(&seqcontlen, out, pval, it); /* An error occurred */ if (i < 0) return 0; @@ -170,12 +173,12 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, /* First work out sequence content length */ for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { const ASN1_TEMPLATE *seqtt; - ASN1_VALUE **pseqval; + const ASN1_VALUE **pseqval; int tmplen; - seqtt = asn1_do_adb(pval, tt, 1); + seqtt = ossl_asn1_do_adb(*pval, tt, 1); if (!seqtt) return 0; - pseqval = asn1_get_field_ptr(pval, seqtt); + pseqval = ossl_asn1_get_const_field_ptr(pval, seqtt); tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass); if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen)) return -1; @@ -189,11 +192,11 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, ASN1_put_object(out, ndef, seqcontlen, tag, aclass); for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { const ASN1_TEMPLATE *seqtt; - ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 1); + const ASN1_VALUE **pseqval; + seqtt = ossl_asn1_do_adb(*pval, tt, 1); if (!seqtt) return 0; - pseqval = asn1_get_field_ptr(pval, seqtt); + pseqval = ossl_asn1_get_const_field_ptr(pval, seqtt); /* FIXME: check for errors in enhanced version */ asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass); } @@ -210,12 +213,12 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, return 0; } -static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, +static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt, int tag, int iclass) { - int i, ret, flags, ttag, tclass, ndef; - ASN1_VALUE *tval; - flags = tt->flags; + const int flags = tt->flags; + int i, ret, ttag, tclass, ndef, len; + const ASN1_VALUE *tval; /* * If field is embedded then val needs fixing so it is a pointer to @@ -266,12 +269,12 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, if (flags & ASN1_TFLG_SK_MASK) { /* SET OF, SEQUENCE OF */ - STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; + STACK_OF(const_ASN1_VALUE) *sk = (STACK_OF(const_ASN1_VALUE) *)*pval; int isset, sktag, skaclass; int skcontlen, sklen; - ASN1_VALUE *skitem; + const ASN1_VALUE *skitem; - if (!*pval) + if (*pval == NULL) return 0; if (flags & ASN1_TFLG_SET_OF) { @@ -299,14 +302,17 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, /* Determine total length of items */ skcontlen = 0; - for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { - int tmplen; - skitem = sk_ASN1_VALUE_value(sk, i); - tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), - -1, iclass); - if (tmplen == -1 || (skcontlen > INT_MAX - tmplen)) + for (i = 0; i < sk_const_ASN1_VALUE_num(sk); i++) { + skitem = sk_const_ASN1_VALUE_value(sk, i); + len = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), + -1, iclass); + if (len == -1 || (skcontlen > INT_MAX - len)) return -1; - skcontlen += tmplen; + if (len == 0 && (tt->flags & ASN1_TFLG_OPTIONAL) == 0) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT); + return -1; + } + skcontlen += len; } sklen = ASN1_object_size(ndef, skcontlen, sktag); if (sklen == -1) @@ -342,8 +348,13 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, /* EXPLICIT tagging */ /* Find length of tagged item */ i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass); - if (!i) + if (i == 0) { + if ((tt->flags & ASN1_TFLG_OPTIONAL) == 0) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT); + return -1; + } return 0; + } /* Find length of EXPLICIT tag */ ret = ASN1_object_size(ndef, i, ttag); if (out && ret != -1) { @@ -357,9 +368,13 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, } /* Either normal or IMPLICIT tagging: combine class and flags */ - return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), - ttag, tclass | iclass); - + len = ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), + ttag, tclass | iclass); + if (len == 0 && (tt->flags & ASN1_TFLG_OPTIONAL) == 0) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT); + return -1; + } + return len; } /* Temporary structure used to hold DER encoding of items for SET OF */ @@ -367,7 +382,7 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, typedef struct { unsigned char *data; int length; - ASN1_VALUE *field; + const ASN1_VALUE *field; } DER_ENC; static int der_cmp(const void *a, const void *b) @@ -383,34 +398,38 @@ static int der_cmp(const void *a, const void *b) /* Output the content octets of SET OF or SEQUENCE OF */ -static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, +static int asn1_set_seq_out(STACK_OF(const_ASN1_VALUE) *sk, + unsigned char **out, int skcontlen, const ASN1_ITEM *item, int do_sort, int iclass) { - int i; - ASN1_VALUE *skitem; + int i, ret = 0; + const ASN1_VALUE *skitem; unsigned char *tmpdat = NULL, *p = NULL; DER_ENC *derlst = NULL, *tder; + if (do_sort) { /* Don't need to sort less than 2 items */ - if (sk_ASN1_VALUE_num(sk) < 2) + if (sk_const_ASN1_VALUE_num(sk) < 2) do_sort = 0; else { - derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) + derlst = OPENSSL_malloc(sk_const_ASN1_VALUE_num(sk) * sizeof(*derlst)); - if (derlst == NULL) + if (derlst == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; + } tmpdat = OPENSSL_malloc(skcontlen); if (tmpdat == NULL) { - OPENSSL_free(derlst); - return 0; + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + goto err; } } } /* If not sorting just output each item */ if (!do_sort) { - for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { - skitem = sk_ASN1_VALUE_value(sk, i); + for (i = 0; i < sk_const_ASN1_VALUE_num(sk); i++) { + skitem = sk_const_ASN1_VALUE_value(sk, i); ASN1_item_ex_i2d(&skitem, out, item, -1, iclass); } return 1; @@ -418,33 +437,35 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, p = tmpdat; /* Doing sort: build up a list of each member's DER encoding */ - for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { - skitem = sk_ASN1_VALUE_value(sk, i); + for (i = 0, tder = derlst; i < sk_const_ASN1_VALUE_num(sk); i++, tder++) { + skitem = sk_const_ASN1_VALUE_value(sk, i); tder->data = p; tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass); tder->field = skitem; } /* Now sort them */ - qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp); + qsort(derlst, sk_const_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp); /* Output sorted DER encoding */ p = *out; - for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { + for (i = 0, tder = derlst; i < sk_const_ASN1_VALUE_num(sk); i++, tder++) { memcpy(p, tder->data, tder->length); p += tder->length; } *out = p; /* If do_sort is 2 then reorder the STACK */ if (do_sort == 2) { - for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) - (void)sk_ASN1_VALUE_set(sk, i, tder->field); + for (i = 0, tder = derlst; i < sk_const_ASN1_VALUE_num(sk); i++, tder++) + (void)sk_const_ASN1_VALUE_set(sk, i, tder->field); } + ret = 1; +err: OPENSSL_free(derlst); OPENSSL_free(tmpdat); - return 1; + return ret; } -static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, +static int asn1_i2d_ex_primitive(const ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) { int len; @@ -504,7 +525,7 @@ static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, /* Produce content octets from a structure */ -static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, +static int asn1_ex_i2c(const ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ITEM *it) { ASN1_BOOLEAN *tbool = NULL; @@ -522,7 +543,7 @@ static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, /* Should type be omitted? */ if ((it->itype != ASN1_ITYPE_PRIMITIVE) || (it->utype != V_ASN1_BOOLEAN)) { - if (!*pval) + if (*pval == NULL) return -1; } @@ -537,7 +558,7 @@ static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, typ = (ASN1_TYPE *)*pval; utype = typ->type; *putype = utype; - pval = &typ->value.asn1_value; + pval = (const ASN1_VALUE **)&typ->value.asn1_value; /* actually is const */ } else utype = *putype; @@ -574,15 +595,15 @@ static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, break; case V_ASN1_BIT_STRING: - return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, - cout ? &cout : NULL); + return ossl_i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, + cout ? &cout : NULL); case V_ASN1_INTEGER: case V_ASN1_ENUMERATED: /* * These are all have the same content format as ASN1_INTEGER */ - return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); + return ossl_i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); case V_ASN1_OCTET_STRING: case V_ASN1_NUMERICSTRING: diff --git a/crypto/openssl/crypto/asn1/tasn_fre.c b/crypto/openssl/crypto/asn1/tasn_fre.c index 2916bef7863a..13aa6a728e2c 100644 --- a/crypto/openssl/crypto/asn1/tasn_fre.c +++ b/crypto/openssl/crypto/asn1/tasn_fre.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -17,15 +17,15 @@ void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) { - asn1_item_embed_free(&val, it, 0); + ossl_asn1_item_embed_free(&val, it, 0); } void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { - asn1_item_embed_free(pval, it, 0); + ossl_asn1_item_embed_free(pval, it, 0); } -void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) +void ossl_asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) { const ASN1_TEMPLATE *tt = NULL, *seqtt; const ASN1_EXTERN_FUNCS *ef; @@ -33,9 +33,9 @@ void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) ASN1_aux_cb *asn1_cb; int i; - if (!pval) + if (pval == NULL) return; - if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && *pval == NULL) return; if (aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; @@ -46,13 +46,13 @@ void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) case ASN1_ITYPE_PRIMITIVE: if (it->templates) - asn1_template_free(pval, it->templates); + ossl_asn1_template_free(pval, it->templates); else - asn1_primitive_free(pval, it, embed); + ossl_asn1_primitive_free(pval, it, embed); break; case ASN1_ITYPE_MSTRING: - asn1_primitive_free(pval, it, embed); + ossl_asn1_primitive_free(pval, it, embed); break; case ASN1_ITYPE_CHOICE: @@ -61,13 +61,13 @@ void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) if (i == 2) return; } - i = asn1_get_choice_selector(pval, it); + i = ossl_asn1_get_choice_selector(pval, it); if ((i >= 0) && (i < it->tcount)) { ASN1_VALUE **pchval; tt = it->templates + i; - pchval = asn1_get_field_ptr(pval, tt); - asn1_template_free(pchval, tt); + pchval = ossl_asn1_get_field_ptr(pval, tt); + ossl_asn1_template_free(pchval, tt); } if (asn1_cb) asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); @@ -85,14 +85,14 @@ void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) case ASN1_ITYPE_NDEF_SEQUENCE: case ASN1_ITYPE_SEQUENCE: - if (asn1_do_lock(pval, -1, it) != 0) /* if error or ref-counter > 0 */ + if (ossl_asn1_do_lock(pval, -1, it) != 0) /* if error or ref-counter > 0 */ return; if (asn1_cb) { i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); if (i == 2) return; } - asn1_enc_free(pval, it); + ossl_asn1_enc_free(pval, it); /* * If we free up as normal we will invalidate any ANY DEFINED BY * field and we won't be able to determine the type of the field it @@ -103,11 +103,11 @@ void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) ASN1_VALUE **pseqval; tt--; - seqtt = asn1_do_adb(pval, tt, 0); + seqtt = ossl_asn1_do_adb(*pval, tt, 0); if (!seqtt) continue; - pseqval = asn1_get_field_ptr(pval, seqtt); - asn1_template_free(pseqval, seqtt); + pseqval = ossl_asn1_get_field_ptr(pval, seqtt); + ossl_asn1_template_free(pseqval, seqtt); } if (asn1_cb) asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); @@ -119,7 +119,7 @@ void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) } } -void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +void ossl_asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { int embed = tt->flags & ASN1_TFLG_EMBED; ASN1_VALUE *tval; @@ -134,16 +134,16 @@ void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i); - asn1_item_embed_free(&vtmp, ASN1_ITEM_ptr(tt->item), embed); + ossl_asn1_item_embed_free(&vtmp, ASN1_ITEM_ptr(tt->item), embed); } sk_ASN1_VALUE_free(sk); *pval = NULL; } else { - asn1_item_embed_free(pval, ASN1_ITEM_ptr(tt->item), embed); + ossl_asn1_item_embed_free(pval, ASN1_ITEM_ptr(tt->item), embed); } } -void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) +void ossl_asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) { int utype; @@ -168,15 +168,15 @@ void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) utype = typ->type; pval = &typ->value.asn1_value; - if (!*pval) + if (*pval == NULL) return; } else if (it->itype == ASN1_ITYPE_MSTRING) { utype = -1; - if (!*pval) + if (*pval == NULL) return; } else { utype = it->utype; - if ((utype != V_ASN1_BOOLEAN) && !*pval) + if ((utype != V_ASN1_BOOLEAN) && *pval == NULL) return; } @@ -196,12 +196,12 @@ void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) break; case V_ASN1_ANY: - asn1_primitive_free(pval, NULL, 0); + ossl_asn1_primitive_free(pval, NULL, 0); OPENSSL_free(*pval); break; default: - asn1_string_embed_free((ASN1_STRING *)*pval, embed); + ossl_asn1_string_embed_free((ASN1_STRING *)*pval, embed); break; } *pval = NULL; diff --git a/crypto/openssl/crypto/asn1/tasn_new.c b/crypto/openssl/crypto/asn1/tasn_new.c index 287f2af33b58..4b624bbdd4e5 100644 --- a/crypto/openssl/crypto/asn1/tasn_new.c +++ b/crypto/openssl/crypto/asn1/tasn_new.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -16,11 +16,13 @@ #include "asn1_local.h" static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, - int embed); + int embed, OSSL_LIB_CTX *libctx, + const char *propq); static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed); static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); -static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, + OSSL_LIB_CTX *libctx, const char *propq); static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); @@ -32,14 +34,31 @@ ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) return NULL; } +ASN1_VALUE *ASN1_item_new_ex(const ASN1_ITEM *it, OSSL_LIB_CTX *libctx, + const char *propq) +{ + ASN1_VALUE *ret = NULL; + if (asn1_item_embed_new(&ret, it, 0, libctx, propq) > 0) + return ret; + return NULL; +} + /* Allocate an ASN1 structure */ + +int ossl_asn1_item_ex_new_intern(ASN1_VALUE **pval, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return asn1_item_embed_new(pval, it, 0, libctx, propq); +} + int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { - return asn1_item_embed_new(pval, it, 0); + return asn1_item_embed_new(pval, it, 0, NULL, NULL); } -int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) +int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed, + OSSL_LIB_CTX *libctx, const char *propq) { const ASN1_TEMPLATE *tt = NULL; const ASN1_EXTERN_FUNCS *ef; @@ -52,23 +71,24 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) else asn1_cb = 0; -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_push(it->sname ? it->sname : "asn1_item_embed_new"); -#endif - switch (it->itype) { case ASN1_ITYPE_EXTERN: ef = it->funcs; - if (ef && ef->asn1_ex_new) { - if (!ef->asn1_ex_new(pval, it)) - goto memerr; + if (ef != NULL) { + if (ef->asn1_ex_new_ex != NULL) { + if (!ef->asn1_ex_new_ex(pval, it, libctx, propq)) + goto memerr; + } else if (ef->asn1_ex_new != NULL) { + if (!ef->asn1_ex_new(pval, it)) + goto memerr; + } } break; case ASN1_ITYPE_PRIMITIVE: if (it->templates) { - if (!asn1_template_new(pval, it->templates)) + if (!asn1_template_new(pval, it->templates, libctx, propq)) goto memerr; } else if (!asn1_primitive_new(pval, it, embed)) goto memerr; @@ -85,9 +105,6 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) if (!i) goto auxerr; if (i == 2) { -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif return 1; } } @@ -98,7 +115,7 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) if (*pval == NULL) goto memerr; } - asn1_set_choice_selector(pval, -1, it); + ossl_asn1_set_choice_selector(pval, -1, it); if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) goto auxerr2; break; @@ -110,9 +127,6 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) if (!i) goto auxerr; if (i == 2) { -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif return 1; } } @@ -124,44 +138,35 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) goto memerr; } /* 0 : init. lock */ - if (asn1_do_lock(pval, 0, it) < 0) { + if (ossl_asn1_do_lock(pval, 0, it) < 0) { if (!embed) { OPENSSL_free(*pval); *pval = NULL; } goto memerr; } - asn1_enc_init(pval, it); + ossl_asn1_enc_init(pval, it); for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { - pseqval = asn1_get_field_ptr(pval, tt); - if (!asn1_template_new(pseqval, tt)) + pseqval = ossl_asn1_get_field_ptr(pval, tt); + if (!asn1_template_new(pseqval, tt, libctx, propq)) goto memerr2; } if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) goto auxerr2; break; } -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif return 1; memerr2: - asn1_item_embed_free(pval, it, embed); + ossl_asn1_item_embed_free(pval, it, embed); memerr: - ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE); -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; auxerr2: - asn1_item_embed_free(pval, it, embed); + ossl_asn1_item_embed_free(pval, it, embed); auxerr: - ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR); -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif + ERR_raise(ERR_LIB_ASN1, ASN1_R_AUX_ERROR); return 0; } @@ -199,7 +204,8 @@ static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) } } -static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, + OSSL_LIB_CTX *libctx, const char *propq) { const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); int embed = tt->flags & ASN1_TFLG_EMBED; @@ -219,16 +225,12 @@ static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) *pval = NULL; return 1; } -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_push(tt->field_name - ? tt->field_name : "asn1_template_new"); -#endif /* If SET OF or SEQUENCE OF, its a STACK */ if (tt->flags & ASN1_TFLG_SK_MASK) { STACK_OF(ASN1_VALUE) *skval; skval = sk_ASN1_VALUE_new_null(); if (!skval) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); ret = 0; goto done; } @@ -237,11 +239,8 @@ static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) goto done; } /* Otherwise pass it back to the item routine */ - ret = asn1_item_embed_new(pval, it, embed); + ret = asn1_item_embed_new(pval, it, embed, libctx, propq); done: -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - OPENSSL_mem_debug_pop(); -#endif return ret; } @@ -300,7 +299,7 @@ static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it, case V_ASN1_ANY: if ((typ = OPENSSL_malloc(sizeof(*typ))) == NULL) { - ASN1err(ASN1_F_ASN1_PRIMITIVE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } typ->value.ptr = NULL; diff --git a/crypto/openssl/crypto/asn1/tasn_prn.c b/crypto/openssl/crypto/asn1/tasn_prn.c index 56d5ea0f39e3..7d8618e26c22 100644 --- a/crypto/openssl/crypto/asn1/tasn_prn.c +++ b/crypto/openssl/crypto/asn1/tasn_prn.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -38,7 +38,7 @@ ASN1_PCTX *ASN1_PCTX_new(void) ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } return ret; @@ -101,15 +101,15 @@ void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags) /* Main print routines */ -static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, +static int asn1_item_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent, const ASN1_ITEM *it, const char *fname, const char *sname, int nohdr, const ASN1_PCTX *pctx); -static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, +static int asn1_template_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent, const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx); -static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, +static int asn1_primitive_print(BIO *out, const ASN1_VALUE **fld, const ASN1_ITEM *it, int indent, const char *fname, const char *sname, const ASN1_PCTX *pctx); @@ -118,7 +118,7 @@ static int asn1_print_fsname(BIO *out, int indent, const char *fname, const char *sname, const ASN1_PCTX *pctx); -int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, +int ASN1_item_print(BIO *out, const ASN1_VALUE *ifld, int indent, const ASN1_ITEM *it, const ASN1_PCTX *pctx) { const char *sname; @@ -131,25 +131,25 @@ int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx); } -static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, +static int asn1_item_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent, const ASN1_ITEM *it, const char *fname, const char *sname, int nohdr, const ASN1_PCTX *pctx) { const ASN1_TEMPLATE *tt; const ASN1_EXTERN_FUNCS *ef; - ASN1_VALUE **tmpfld; + const ASN1_VALUE **tmpfld; const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb; + ASN1_aux_const_cb *asn1_cb = NULL; ASN1_PRINT_ARG parg; int i; - if (aux && aux->asn1_cb) { + if (aux != NULL) { parg.out = out; parg.indent = indent; parg.pctx = pctx; - asn1_cb = aux->asn1_cb; - } else - asn1_cb = 0; + asn1_cb = ((aux->flags & ASN1_AFLG_CONST_CB) != 0) ? aux->asn1_const_cb + : (ASN1_aux_const_cb *)aux->asn1_cb; /* backward compatibility */ + } if (((it->itype != ASN1_ITYPE_PRIMITIVE) || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) { @@ -195,7 +195,7 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, case ASN1_ITYPE_CHOICE: /* CHOICE type, get selector */ - i = asn1_get_choice_selector(fld, it); + i = ossl_asn1_get_choice_selector_const(fld, it); /* This should never happen... */ if ((i < 0) || (i >= it->tcount)) { if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0) @@ -203,7 +203,7 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, return 1; } tt = it->templates + i; - tmpfld = asn1_get_field_ptr(fld, tt); + tmpfld = ossl_asn1_get_const_field_ptr(fld, tt); if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx)) return 0; break; @@ -233,10 +233,10 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, /* Print each field entry */ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { const ASN1_TEMPLATE *seqtt; - seqtt = asn1_do_adb(fld, tt, 1); + seqtt = ossl_asn1_do_adb(*fld, tt, 1); if (!seqtt) return 0; - tmpfld = asn1_get_field_ptr(fld, seqtt); + tmpfld = ossl_asn1_get_const_field_ptr(fld, seqtt); if (!asn1_template_print_ctx(out, tmpfld, indent + 2, seqtt, pctx)) return 0; @@ -261,12 +261,12 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, return 1; } -static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, +static int asn1_template_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent, const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx) { int i, flags; const char *sname, *fname; - ASN1_VALUE *tfld; + const ASN1_VALUE *tfld; flags = tt->flags; if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME) sname = ASN1_ITEM_ptr(tt->item)->sname; @@ -282,14 +282,14 @@ static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, * a pointer to a field. */ if (flags & ASN1_TFLG_EMBED) { - tfld = (ASN1_VALUE *)fld; + tfld = (const ASN1_VALUE *)fld; fld = &tfld; } if (flags & ASN1_TFLG_SK_MASK) { char *tname; - ASN1_VALUE *skitem; - STACK_OF(ASN1_VALUE) *stack; + const ASN1_VALUE *skitem; + STACK_OF(const_ASN1_VALUE) *stack; /* SET OF, SEQUENCE OF */ if (fname) { @@ -304,12 +304,12 @@ static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0) return 0; } - stack = (STACK_OF(ASN1_VALUE) *)*fld; - for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) { + stack = (STACK_OF(const_ASN1_VALUE) *)*fld; + for (i = 0; i < sk_const_ASN1_VALUE_num(stack); i++) { if ((i > 0) && (BIO_puts(out, "\n") <= 0)) return 0; - skitem = sk_ASN1_VALUE_value(stack, i); + skitem = sk_const_ASN1_VALUE_value(stack, i); if (!asn1_item_print_ctx(out, &skitem, indent + 2, ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx)) @@ -430,7 +430,7 @@ static int asn1_print_obstring(BIO *out, const ASN1_STRING *str, int indent) return 1; } -static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, +static int asn1_primitive_print(BIO *out, const ASN1_VALUE **fld, const ASN1_ITEM *it, int indent, const char *fname, const char *sname, const ASN1_PCTX *pctx) @@ -456,9 +456,9 @@ static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, str = (ASN1_STRING *)*fld; } if (utype == V_ASN1_ANY) { - ASN1_TYPE *atype = (ASN1_TYPE *)*fld; + const ASN1_TYPE *atype = (const ASN1_TYPE *)*fld; utype = atype->type; - fld = &atype->value.asn1_value; + fld = (const ASN1_VALUE **)&atype->value.asn1_value; /* actually is const */ str = (ASN1_STRING *)*fld; if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE) pname = NULL; diff --git a/crypto/openssl/crypto/asn1/tasn_scn.c b/crypto/openssl/crypto/asn1/tasn_scn.c index f0f218ae8bbe..bde697ee9925 100644 --- a/crypto/openssl/crypto/asn1/tasn_scn.c +++ b/crypto/openssl/crypto/asn1/tasn_scn.c @@ -1,7 +1,7 @@ /* - * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -27,7 +27,7 @@ ASN1_SCTX *ASN1_SCTX_new(int (*scan_cb) (ASN1_SCTX *ctx)) ASN1_SCTX *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ASN1err(ASN1_F_ASN1_SCTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } ret->scan_cb = scan_cb; diff --git a/crypto/openssl/crypto/asn1/tasn_typ.c b/crypto/openssl/crypto/asn1/tasn_typ.c index 98d987901413..8095e32370fc 100644 --- a/crypto/openssl/crypto/asn1/tasn_typ.c +++ b/crypto/openssl/crypto/asn1/tasn_typ.c @@ -1,7 +1,7 @@ /* * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -80,5 +80,5 @@ ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY) ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY) diff --git a/crypto/openssl/crypto/asn1/tasn_utl.c b/crypto/openssl/crypto/asn1/tasn_utl.c index a448685e19a9..e5f25d88df69 100644 --- a/crypto/openssl/crypto/asn1/tasn_utl.c +++ b/crypto/openssl/crypto/asn1/tasn_utl.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -26,9 +26,18 @@ * Given an ASN1_ITEM CHOICE type return the selector value */ -int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) +int ossl_asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) { int *sel = offset2ptr(*pval, it->utype); + + return *sel; +} + +int ossl_asn1_get_choice_selector_const(const ASN1_VALUE **pval, + const ASN1_ITEM *it) +{ + int *sel = offset2ptr(*pval, it->utype); + return *sel; } @@ -36,10 +45,11 @@ int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) * Given an ASN1_ITEM CHOICE type set the selector value, return old value. */ -int asn1_set_choice_selector(ASN1_VALUE **pval, int value, - const ASN1_ITEM *it) +int ossl_asn1_set_choice_selector(ASN1_VALUE **pval, int value, + const ASN1_ITEM *it) { int *sel, ret; + sel = offset2ptr(*pval, it->utype); ret = *sel; *sel = value; @@ -55,7 +65,7 @@ int asn1_set_choice_selector(ASN1_VALUE **pval, int value, * It returns -1 on initialisation error. * Used by ASN1_SEQUENCE construct of X509, X509_REQ, X509_CRL objects */ -int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) +int ossl_asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) { const ASN1_AUX *aux; CRYPTO_REF_COUNT *lck; @@ -66,7 +76,7 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE)) return 0; aux = it->funcs; - if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) + if (aux == NULL || (aux->flags & ASN1_AFLG_REFCOUNT) == 0) return 0; lck = offset2ptr(*pval, aux->ref_offset); lock = offset2ptr(*pval, aux->ref_lock); @@ -76,7 +86,7 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) *lck = ret = 1; *lock = CRYPTO_THREAD_lock_new(); if (*lock == NULL) { - ASN1err(ASN1_F_ASN1_DO_LOCK, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } break; @@ -87,9 +97,7 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) case -1: if (!CRYPTO_DOWN_REF(lck, &ret, *lock)) return -1; /* failed */ -#ifdef REF_PRINT - fprintf(stderr, "%p:%4d:%s\n", it, ret, it->sname); -#endif + REF_PRINT_EX(it->sname, ret, (void *)it); REF_ASSERT_ISNT(ret < 0); if (ret == 0) { CRYPTO_THREAD_lock_free(*lock); @@ -104,30 +112,44 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) { const ASN1_AUX *aux; - if (!pval || !*pval) + + if (pval == NULL || *pval == NULL) + return NULL; + aux = it->funcs; + if (aux == NULL || (aux->flags & ASN1_AFLG_ENCODING) == 0) + return NULL; + return offset2ptr(*pval, aux->enc_offset); +} + +static const ASN1_ENCODING *asn1_get_const_enc_ptr(const ASN1_VALUE **pval, + const ASN1_ITEM *it) +{ + const ASN1_AUX *aux; + + if (pval == NULL || *pval == NULL) return NULL; aux = it->funcs; - if (!aux || !(aux->flags & ASN1_AFLG_ENCODING)) + if (aux == NULL || (aux->flags & ASN1_AFLG_ENCODING) == 0) return NULL; return offset2ptr(*pval, aux->enc_offset); } -void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) +void ossl_asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); - if (enc) { + ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it); + + if (enc != NULL) { enc->enc = NULL; enc->len = 0; enc->modified = 1; } } -void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +void ossl_asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); - if (enc) { + ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it); + + if (enc != NULL) { OPENSSL_free(enc->enc); enc->enc = NULL; enc->len = 0; @@ -135,17 +157,19 @@ void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) } } -int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, - const ASN1_ITEM *it) +int ossl_asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, + const ASN1_ITEM *it) { - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); - if (!enc) + ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it); + + if (enc == NULL) return 1; OPENSSL_free(enc->enc); + if (inlen <= 0) + return 0; if ((enc->enc = OPENSSL_malloc(inlen)) == NULL) { - ASN1err(ASN1_F_ASN1_ENC_SAVE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } memcpy(enc->enc, in, inlen); @@ -155,27 +179,27 @@ int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, return 1; } -int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, - const ASN1_ITEM *it) +int ossl_asn1_enc_restore(int *len, unsigned char **out, const ASN1_VALUE **pval, + const ASN1_ITEM *it) { - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); - if (!enc || enc->modified) + const ASN1_ENCODING *enc = asn1_get_const_enc_ptr(pval, it); + + if (enc == NULL || enc->modified) return 0; if (out) { memcpy(*out, enc->enc, enc->len); *out += enc->len; } - if (len) + if (len != NULL) *len = enc->len; return 1; } /* Given an ASN1_TEMPLATE get a pointer to a field */ -ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +ASN1_VALUE **ossl_asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { - ASN1_VALUE **pvaltmp; - pvaltmp = offset2ptr(*pval, tt->offset); + ASN1_VALUE **pvaltmp = offset2ptr(*pval, tt->offset); + /* * NOTE for BOOLEAN types the field is just a plain int so we can't * return int **, so settle for (int *). @@ -183,31 +207,40 @@ ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) return pvaltmp; } +/* Given an ASN1_TEMPLATE get a const pointer to a field */ +const ASN1_VALUE **ossl_asn1_get_const_field_ptr(const ASN1_VALUE **pval, + const ASN1_TEMPLATE *tt) +{ + return offset2ptr(*pval, tt->offset); +} + /* * Handle ANY DEFINED BY template, find the selector, look up the relevant * ASN1_TEMPLATE in the table and return it. */ -const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, - int nullerr) +const ASN1_TEMPLATE *ossl_asn1_do_adb(const ASN1_VALUE *val, + const ASN1_TEMPLATE *tt, + int nullerr) { const ASN1_ADB *adb; const ASN1_ADB_TABLE *atbl; long selector; - ASN1_VALUE **sfld; + const ASN1_VALUE **sfld; int i; - if (!(tt->flags & ASN1_TFLG_ADB_MASK)) + + if ((tt->flags & ASN1_TFLG_ADB_MASK) == 0) return tt; /* Else ANY DEFINED BY ... get the table */ adb = ASN1_ADB_ptr(tt->item); /* Get the selector field */ - sfld = offset2ptr(*pval, adb->offset); + sfld = offset2ptr(val, adb->offset); /* Check if NULL */ if (*sfld == NULL) { - if (!adb->null_tt) + if (adb->null_tt == NULL) goto err; return adb->null_tt; } @@ -216,14 +249,14 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, * Convert type to a long: NB: don't check for NID_undef here because it * might be a legitimate value in the table */ - if (tt->flags & ASN1_TFLG_ADB_OID) + if ((tt->flags & ASN1_TFLG_ADB_OID) != 0) selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld); else selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld); /* Let application callback translate value */ if (adb->adb_cb != NULL && adb->adb_cb(&selector) == 0) { - ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); return NULL; } @@ -248,6 +281,6 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, err: /* FIXME: should log the value or OID of unsupported type */ if (nullerr) - ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); return NULL; } diff --git a/crypto/openssl/crypto/asn1/tbl_standard.h b/crypto/openssl/crypto/asn1/tbl_standard.h index 777a73448246..3e8fe81eebdd 100644 --- a/crypto/openssl/crypto/asn1/tbl_standard.h +++ b/crypto/openssl/crypto/asn1/tbl_standard.h @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -56,6 +56,7 @@ static const ASN1_STRING_TABLE tbl_standard[] = { {NID_SNILS, 1, 11, B_ASN1_NUMERICSTRING, STABLE_NO_MASK}, {NID_countryCode3c, 3, 3, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, {NID_countryCode3n, 3, 3, B_ASN1_NUMERICSTRING, STABLE_NO_MASK}, - {NID_dnsName, 0, -1, B_ASN1_UTF8STRING, STABLE_NO_MASK} + {NID_dnsName, 0, -1, B_ASN1_UTF8STRING, STABLE_NO_MASK}, + {NID_id_on_SmtpUTF8Mailbox, 1, ub_email_address, B_ASN1_UTF8STRING, STABLE_NO_MASK} }; diff --git a/crypto/openssl/crypto/asn1/x_algor.c b/crypto/openssl/crypto/asn1/x_algor.c index c9a8f1e9d1d4..c0a5f76803ee 100644 --- a/crypto/openssl/crypto/asn1/x_algor.c +++ b/crypto/openssl/crypto/asn1/x_algor.c @@ -1,7 +1,7 @@ /* - * Copyright 1998-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,6 +11,8 @@ #include #include #include +#include +#include "crypto/asn1.h" #include "crypto/evp.h" ASN1_SEQUENCE(X509_ALGOR) = { @@ -78,7 +80,7 @@ void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) else param_type = V_ASN1_NULL; - X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_get_type(md)), param_type, NULL); } @@ -96,7 +98,7 @@ int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src) { if (src == NULL || dest == NULL) - return 0; + return 0; if (dest->algorithm) ASN1_OBJECT_free(dest->algorithm); @@ -108,9 +110,9 @@ int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src) if (src->algorithm) if ((dest->algorithm = OBJ_dup(src->algorithm)) == NULL) - return 0; + return 0; - if (src->parameter) { + if (src->parameter != NULL) { dest->parameter = ASN1_TYPE_new(); if (dest->parameter == NULL) return 0; @@ -118,9 +120,71 @@ int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src) /* Assuming this is also correct for a BOOL. * set does copy as a side effect. */ - if (ASN1_TYPE_set1(dest->parameter, - src->parameter->type, src->parameter->value.ptr) == 0) + if (ASN1_TYPE_set1(dest->parameter, src->parameter->type, + src->parameter->value.ptr) == 0) return 0; } + + return 1; +} + +/* allocate and set algorithm ID from EVP_MD, default SHA1 */ +int ossl_x509_algor_new_from_md(X509_ALGOR **palg, const EVP_MD *md) +{ + /* Default is SHA1 so no need to create it - still success */ + if (md == NULL || EVP_MD_is_a(md, "SHA1")) + return 1; + *palg = X509_ALGOR_new(); + if (*palg == NULL) + return 0; + X509_ALGOR_set_md(*palg, md); return 1; } + +/* convert algorithm ID to EVP_MD, default SHA1 */ +const EVP_MD *ossl_x509_algor_get_md(X509_ALGOR *alg) +{ + const EVP_MD *md; + + if (alg == NULL) + return EVP_sha1(); + md = EVP_get_digestbyobj(alg->algorithm); + if (md == NULL) + ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_DIGEST); + return md; +} + +X509_ALGOR *ossl_x509_algor_mgf1_decode(X509_ALGOR *alg) +{ + if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) + return NULL; + return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR), + alg->parameter); +} + +/* Allocate and set MGF1 algorithm ID from EVP_MD */ +int ossl_x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) +{ + X509_ALGOR *algtmp = NULL; + ASN1_STRING *stmp = NULL; + + *palg = NULL; + if (mgf1md == NULL || EVP_MD_is_a(mgf1md, "SHA1")) + return 1; + /* need to embed algorithm ID inside another */ + if (!ossl_x509_algor_new_from_md(&algtmp, mgf1md)) + goto err; + if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL) + goto err; + *palg = X509_ALGOR_new(); + if (*palg == NULL) + goto err; + X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); + stmp = NULL; + err: + ASN1_STRING_free(stmp); + X509_ALGOR_free(algtmp); + if (*palg != NULL) + return 1; + return 0; +} diff --git a/crypto/openssl/crypto/asn1/x_bignum.c b/crypto/openssl/crypto/asn1/x_bignum.c index c6b3accd3a10..3ae58a49f0b2 100644 --- a/crypto/openssl/crypto/asn1/x_bignum.c +++ b/crypto/openssl/crypto/asn1/x_bignum.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -25,13 +25,13 @@ static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it); static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it); -static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, +static int bn_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); -static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, +static int bn_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx); static ASN1_PRIMITIVE_FUNCS bignum_pf = { @@ -91,7 +91,7 @@ static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it) *pval = NULL; } -static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, +static int bn_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it) { BIGNUM *bn; @@ -146,7 +146,7 @@ static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, return ret; } -static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, +static int bn_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx) { if (!BN_print(out, *(BIGNUM **)pval)) diff --git a/crypto/openssl/crypto/asn1/x_info.c b/crypto/openssl/crypto/asn1/x_info.c index 8d99f07c6361..f8bc4789884e 100644 --- a/crypto/openssl/crypto/asn1/x_info.c +++ b/crypto/openssl/crypto/asn1/x_info.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,7 +19,7 @@ X509_INFO *X509_INFO_new(void) ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ASN1err(ASN1_F_X509_INFO_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/openssl/crypto/asn1/x_int64.c b/crypto/openssl/crypto/asn1/x_int64.c index 96c1a259e1fe..eb78c7e36723 100644 --- a/crypto/openssl/crypto/asn1/x_int64.c +++ b/crypto/openssl/crypto/asn1/x_int64.c @@ -1,7 +1,7 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -29,7 +29,7 @@ static int uint64_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint64_t))) == NULL) { - ASN1err(ASN1_F_UINT64_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -46,8 +46,8 @@ static void uint64_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) **(uint64_t **)pval = 0; } -static int uint64_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, - const ASN1_ITEM *it) +static int uint64_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it) { uint64_t utmp; int neg = 0; @@ -62,16 +62,16 @@ static int uint64_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, return -1; if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED && (int64_t)utmp < 0) { - /* i2c_uint64_int() assumes positive values */ + /* ossl_i2c_uint64_int() assumes positive values */ utmp = 0 - utmp; neg = 1; } - return i2c_uint64_int(cont, utmp, neg); + return ossl_i2c_uint64_int(cont, utmp, neg); } static int uint64_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, - int utype, char *free_cont, const ASN1_ITEM *it) + int utype, char *free_cont, const ASN1_ITEM *it) { uint64_t utmp = 0; char *cp; @@ -91,19 +91,19 @@ static int uint64_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, if (len == 0) goto long_compat; - if (!c2i_uint64_int(&utmp, &neg, &cont, len)) + if (!ossl_c2i_uint64_int(&utmp, &neg, &cont, len)) return 0; if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) { - ASN1err(ASN1_F_UINT64_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_NEGATIVE_VALUE); return 0; } if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED && !neg && utmp > INT64_MAX) { - ASN1err(ASN1_F_UINT64_C2I, ASN1_R_TOO_LARGE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE); return 0; } if (neg) - /* c2i_uint64_int() returns positive values */ + /* ossl_c2i_uint64_int() returns positive values */ utmp = 0 - utmp; long_compat: @@ -111,7 +111,7 @@ static int uint64_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, return 1; } -static int uint64_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, +static int uint64_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx) { if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED) @@ -124,7 +124,7 @@ static int uint64_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, static int uint32_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint32_t))) == NULL) { - ASN1err(ASN1_F_UINT32_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -141,8 +141,8 @@ static void uint32_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) **(uint32_t **)pval = 0; } -static int uint32_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, - const ASN1_ITEM *it) +static int uint32_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it) { uint32_t utmp; int neg = 0; @@ -157,12 +157,12 @@ static int uint32_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, return -1; if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED && (int32_t)utmp < 0) { - /* i2c_uint64_int() assumes positive values */ + /* ossl_i2c_uint64_int() assumes positive values */ utmp = 0 - utmp; neg = 1; } - return i2c_uint64_int(cont, (uint64_t)utmp, neg); + return ossl_i2c_uint64_int(cont, (uint64_t)utmp, neg); } /* @@ -173,7 +173,7 @@ static int uint32_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, #define ABS_INT32_MIN ((uint32_t)INT32_MAX + 1) static int uint32_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, - int utype, char *free_cont, const ASN1_ITEM *it) + int utype, char *free_cont, const ASN1_ITEM *it) { uint64_t utmp = 0; uint32_t utmp2 = 0; @@ -194,22 +194,22 @@ static int uint32_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, if (len == 0) goto long_compat; - if (!c2i_uint64_int(&utmp, &neg, &cont, len)) + if (!ossl_c2i_uint64_int(&utmp, &neg, &cont, len)) return 0; if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) { - ASN1err(ASN1_F_UINT32_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_NEGATIVE_VALUE); return 0; } if (neg) { if (utmp > ABS_INT32_MIN) { - ASN1err(ASN1_F_UINT32_C2I, ASN1_R_TOO_SMALL); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL); return 0; } utmp = 0 - utmp; } else { if (((it->size & INTxx_FLAG_SIGNED) != 0 && utmp > INT32_MAX) || ((it->size & INTxx_FLAG_SIGNED) == 0 && utmp > UINT32_MAX)) { - ASN1err(ASN1_F_UINT32_C2I, ASN1_R_TOO_LARGE); + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE); return 0; } } @@ -220,7 +220,7 @@ static int uint32_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, return 1; } -static int uint32_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, +static int uint32_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx) { if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED) diff --git a/crypto/openssl/crypto/asn1/x_long.c b/crypto/openssl/crypto/asn1/x_long.c index bf9371ef55aa..0685780f08a0 100644 --- a/crypto/openssl/crypto/asn1/x_long.c +++ b/crypto/openssl/crypto/asn1/x_long.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,10 +11,6 @@ #include "internal/cryptlib.h" #include -#if !(OPENSSL_API_COMPAT < 0x10200000L) -NON_EMPTY_TRANSLATION_UNIT -#else - #define COPY_SIZE(a, b) (sizeof(a) < sizeof(b) ? sizeof(a) : sizeof(b)) /* @@ -25,11 +21,11 @@ NON_EMPTY_TRANSLATION_UNIT static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it); static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it); -static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, +static int long_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); -static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, +static int long_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx); static ASN1_PRIMITIVE_FUNCS long_pf = { @@ -86,7 +82,7 @@ static int num_bits_ulong(unsigned long value) return (int)ret; } -static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, +static int long_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it) { long ltmp; @@ -156,7 +152,7 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, } } if (len > (int)sizeof(long)) { - ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); return 0; } @@ -167,7 +163,7 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, else sign = 0; } else if (((sign ^ cont[0]) & 0x80) == 0) { /* same sign bit? */ - ASN1err(ASN1_F_LONG_C2I, ASN1_R_ILLEGAL_PADDING); + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_PADDING); return 0; } utmp = 0; @@ -177,20 +173,20 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, } ltmp = (long)utmp; if (ltmp < 0) { - ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); return 0; } if (sign) ltmp = -ltmp - 1; if (ltmp == it->size) { - ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); + ERR_raise(ERR_LIB_ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); return 0; } memcpy(pval, <mp, COPY_SIZE(*pval, ltmp)); return 1; } -static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, +static int long_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx) { long l; @@ -198,4 +194,3 @@ static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, memcpy(&l, pval, COPY_SIZE(*pval, l)); return BIO_printf(out, "%ld\n", l); } -#endif diff --git a/crypto/openssl/crypto/asn1/x_pkey.c b/crypto/openssl/crypto/asn1/x_pkey.c index 593049f0f26e..b63c7c6489f4 100644 --- a/crypto/openssl/crypto/asn1/x_pkey.c +++ b/crypto/openssl/crypto/asn1/x_pkey.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -29,7 +29,7 @@ X509_PKEY *X509_PKEY_new(void) return ret; err: X509_PKEY_free(ret); - ASN1err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/openssl/crypto/asn1/x_sig.c b/crypto/openssl/crypto/asn1/x_sig.c index fb24e240cba8..759a9566531e 100644 --- a/crypto/openssl/crypto/asn1/x_sig.c +++ b/crypto/openssl/crypto/asn1/x_sig.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/asn1/x_spki.c b/crypto/openssl/crypto/asn1/x_spki.c index 0d72a3f3a9d2..2d7de66eb79c 100644 --- a/crypto/openssl/crypto/asn1/x_spki.c +++ b/crypto/openssl/crypto/asn1/x_spki.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/asn1/x_val.c b/crypto/openssl/crypto/asn1/x_val.c index d1f1d3bff989..a4e57cbcc714 100644 --- a/crypto/openssl/crypto/asn1/x_val.c +++ b/crypto/openssl/crypto/asn1/x_val.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/asn1_dsa.c b/crypto/openssl/crypto/asn1_dsa.c new file mode 100644 index 000000000000..0782fe7c2a54 --- /dev/null +++ b/crypto/openssl/crypto/asn1_dsa.c @@ -0,0 +1,252 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * A simple ASN.1 DER encoder/decoder for DSA-Sig-Value and ECDSA-Sig-Value. + * + * DSA-Sig-Value ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + * + * ECDSA-Sig-Value ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + */ + +#include +#include +#include "crypto/asn1_dsa.h" +#include "internal/packet.h" + +#define ID_SEQUENCE 0x30 +#define ID_INTEGER 0x02 + +/* + * Outputs the encoding of the length octets for a DER value with a content + * length of cont_len bytes to pkt. The maximum supported content length is + * 65535 (0xffff) bytes. + * + * Returns 1 on success or 0 on error. + */ +int ossl_encode_der_length(WPACKET *pkt, size_t cont_len) +{ + if (cont_len > 0xffff) + return 0; /* Too large for supported length encodings */ + + if (cont_len > 0xff) { + if (!WPACKET_put_bytes_u8(pkt, 0x82) + || !WPACKET_put_bytes_u16(pkt, cont_len)) + return 0; + } else { + if (cont_len > 0x7f + && !WPACKET_put_bytes_u8(pkt, 0x81)) + return 0; + if (!WPACKET_put_bytes_u8(pkt, cont_len)) + return 0; + } + + return 1; +} + +/* + * Outputs the DER encoding of a positive ASN.1 INTEGER to pkt. + * + * Results in an error if n is negative or too large. + * + * Returns 1 on success or 0 on error. + */ +int ossl_encode_der_integer(WPACKET *pkt, const BIGNUM *n) +{ + unsigned char *bnbytes; + size_t cont_len; + + if (BN_is_negative(n)) + return 0; + + /* + * Calculate the ASN.1 INTEGER DER content length for n. + * This is the number of whole bytes required to represent n (i.e. rounded + * down), plus one. + * If n is zero then the content is a single zero byte (length = 1). + * If the number of bits of n is a multiple of 8 then an extra zero padding + * byte is included to ensure that the value is still treated as positive + * in the INTEGER two's complement representation. + */ + cont_len = BN_num_bits(n) / 8 + 1; + + if (!WPACKET_start_sub_packet(pkt) + || !WPACKET_put_bytes_u8(pkt, ID_INTEGER) + || !ossl_encode_der_length(pkt, cont_len) + || !WPACKET_allocate_bytes(pkt, cont_len, &bnbytes) + || !WPACKET_close(pkt)) + return 0; + + if (bnbytes != NULL + && BN_bn2binpad(n, bnbytes, (int)cont_len) != (int)cont_len) + return 0; + + return 1; +} + +/* + * Outputs the DER encoding of a DSA-Sig-Value or ECDSA-Sig-Value to pkt. pkt + * may be initialised with a NULL buffer which enables pkt to be used to + * calculate how many bytes would be needed. + * + * Returns 1 on success or 0 on error. + */ +int ossl_encode_der_dsa_sig(WPACKET *pkt, const BIGNUM *r, const BIGNUM *s) +{ + WPACKET tmppkt, *dummypkt; + size_t cont_len; + int isnull = WPACKET_is_null_buf(pkt); + + if (!WPACKET_start_sub_packet(pkt)) + return 0; + + if (!isnull) { + if (!WPACKET_init_null(&tmppkt, 0)) + return 0; + dummypkt = &tmppkt; + } else { + /* If the input packet has a NULL buffer, we don't need a dummy packet */ + dummypkt = pkt; + } + + /* Calculate the content length */ + if (!ossl_encode_der_integer(dummypkt, r) + || !ossl_encode_der_integer(dummypkt, s) + || !WPACKET_get_length(dummypkt, &cont_len) + || (!isnull && !WPACKET_finish(dummypkt))) { + if (!isnull) + WPACKET_cleanup(dummypkt); + return 0; + } + + /* Add the tag and length bytes */ + if (!WPACKET_put_bytes_u8(pkt, ID_SEQUENCE) + || !ossl_encode_der_length(pkt, cont_len) + /* + * Really encode the integers. We already wrote to the main pkt + * if it had a NULL buffer, so don't do it again + */ + || (!isnull && !ossl_encode_der_integer(pkt, r)) + || (!isnull && !ossl_encode_der_integer(pkt, s)) + || !WPACKET_close(pkt)) + return 0; + + return 1; +} + +/* + * Decodes the DER length octets in pkt and initialises subpkt with the + * following bytes of that length. + * + * Returns 1 on success or 0 on failure. + */ +int ossl_decode_der_length(PACKET *pkt, PACKET *subpkt) +{ + unsigned int byte; + + if (!PACKET_get_1(pkt, &byte)) + return 0; + + if (byte < 0x80) + return PACKET_get_sub_packet(pkt, subpkt, (size_t)byte); + if (byte == 0x81) + return PACKET_get_length_prefixed_1(pkt, subpkt); + if (byte == 0x82) + return PACKET_get_length_prefixed_2(pkt, subpkt); + + /* Too large, invalid, or not DER. */ + return 0; +} + +/* + * Decodes a single ASN.1 INTEGER value from pkt, which must be DER encoded, + * and updates n with the decoded value. + * + * The BIGNUM, n, must have already been allocated by calling BN_new(). + * pkt must not be NULL. + * + * An attempt to consume more than len bytes results in an error. + * Returns 1 on success or 0 on error. + * + * If the PACKET is supposed to only contain a single INTEGER value with no + * trailing garbage then it is up to the caller to verify that all bytes + * were consumed. + */ +int ossl_decode_der_integer(PACKET *pkt, BIGNUM *n) +{ + PACKET contpkt, tmppkt; + unsigned int tag, tmp; + + /* Check we have an integer and get the content bytes */ + if (!PACKET_get_1(pkt, &tag) + || tag != ID_INTEGER + || !ossl_decode_der_length(pkt, &contpkt)) + return 0; + + /* Peek ahead at the first bytes to check for proper encoding */ + tmppkt = contpkt; + /* The INTEGER must be positive */ + if (!PACKET_get_1(&tmppkt, &tmp) + || (tmp & 0x80) != 0) + return 0; + /* If there a zero padding byte the next byte must have the msb set */ + if (PACKET_remaining(&tmppkt) > 0 && tmp == 0) { + if (!PACKET_get_1(&tmppkt, &tmp) + || (tmp & 0x80) == 0) + return 0; + } + + if (BN_bin2bn(PACKET_data(&contpkt), + (int)PACKET_remaining(&contpkt), n) == NULL) + return 0; + + return 1; +} + +/* + * Decodes a single DSA-Sig-Value or ECDSA-Sig-Value from *ppin, which must be + * DER encoded, updates r and s with the decoded values, and increments *ppin + * past the data that was consumed. + * + * The BIGNUMs, r and s, must have already been allocated by calls to BN_new(). + * ppin and *ppin must not be NULL. + * + * An attempt to consume more than len bytes results in an error. + * Returns the number of bytes of input consumed or 0 if an error occurs. + * + * If the buffer is supposed to only contain a single [EC]DSA-Sig-Value with no + * trailing garbage then it is up to the caller to verify that all bytes + * were consumed. + */ +size_t ossl_decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, + const unsigned char **ppin, size_t len) +{ + size_t consumed; + PACKET pkt, contpkt; + unsigned int tag; + + if (!PACKET_buf_init(&pkt, *ppin, len) + || !PACKET_get_1(&pkt, &tag) + || tag != ID_SEQUENCE + || !ossl_decode_der_length(&pkt, &contpkt) + || !ossl_decode_der_integer(&contpkt, r) + || !ossl_decode_der_integer(&contpkt, s) + || PACKET_remaining(&contpkt) != 0) + return 0; + + consumed = PACKET_data(&pkt) - *ppin; + *ppin += consumed; + return consumed; +} diff --git a/crypto/openssl/crypto/async/arch/async_null.c b/crypto/openssl/crypto/async/arch/async_null.c index 26801f873130..675c1d35bf0c 100644 --- a/crypto/openssl/crypto/async/arch/async_null.c +++ b/crypto/openssl/crypto/async/arch/async_null.c @@ -1,7 +1,7 @@ /* * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/async/arch/async_null.h b/crypto/openssl/crypto/async/arch/async_null.h index aef40b5d9ee0..c62aba69a874 100644 --- a/crypto/openssl/crypto/async/arch/async_null.h +++ b/crypto/openssl/crypto/async/arch/async_null.h @@ -1,7 +1,7 @@ /* * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/async/arch/async_posix.c b/crypto/openssl/crypto/async/arch/async_posix.c index 95678d4fa686..e107e09a352f 100644 --- a/crypto/openssl/crypto/async/arch/async_posix.c +++ b/crypto/openssl/crypto/async/arch/async_posix.c @@ -1,7 +1,7 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -34,7 +34,9 @@ void async_local_cleanup(void) int async_fibre_makecontext(async_fibre *fibre) { +#ifndef USE_SWAPCONTEXT fibre->env_init = 0; +#endif if (getcontext(&fibre->fibre) == 0) { fibre->fibre.uc_stack.ss_sp = OPENSSL_malloc(STACKSIZE); if (fibre->fibre.uc_stack.ss_sp != NULL) { diff --git a/crypto/openssl/crypto/async/arch/async_posix.h b/crypto/openssl/crypto/async/arch/async_posix.h index 873c0316ddf3..a17c6b8e68af 100644 --- a/crypto/openssl/crypto/async/arch/async_posix.h +++ b/crypto/openssl/crypto/async/arch/async_posix.h @@ -1,7 +1,7 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -25,17 +25,47 @@ # define ASYNC_POSIX # define ASYNC_ARCH +# if defined(__CET__) || defined(__ia64__) +/* + * When Intel CET is enabled, makecontext will create a different + * shadow stack for each context. async_fibre_swapcontext cannot + * use _longjmp. It must call swapcontext to swap shadow stack as + * well as normal stack. + * On IA64 the register stack engine is not saved across setjmp/longjmp. Here + * swapcontext() performs correctly. + */ +# define USE_SWAPCONTEXT +# endif +# if defined(__aarch64__) && defined(__clang__) \ + && defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1 +/* + * setjmp/longjmp don't currently work with BTI on all libc implementations + * when compiled by clang. This is because clang doesn't put a BTI after the + * call to setjmp where it returns the second time. This then fails on libc + * implementations - notably glibc - which use an indirect jump to there. + * So use the swapcontext implementation, which does work. + * See https://github.com/llvm/llvm-project/issues/48888. + */ +# define USE_SWAPCONTEXT +# endif # include -# include +# ifndef USE_SWAPCONTEXT +# include +# endif typedef struct async_fibre_st { ucontext_t fibre; +# ifndef USE_SWAPCONTEXT jmp_buf env; int env_init; +# endif } async_fibre; static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r) { +# ifdef USE_SWAPCONTEXT + swapcontext(&o->fibre, &n->fibre); +# else o->env_init = 1; if (!r || !_setjmp(o->env)) { @@ -44,6 +74,7 @@ static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, i else setcontext(&n->fibre); } +# endif return 1; } diff --git a/crypto/openssl/crypto/async/arch/async_win.h b/crypto/openssl/crypto/async/arch/async_win.h index 61cfdd72dec6..0fab95996e27 100644 --- a/crypto/openssl/crypto/async/arch/async_win.h +++ b/crypto/openssl/crypto/async/arch/async_win.h @@ -1,7 +1,7 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -26,8 +26,16 @@ typedef struct async_fibre_st { # define async_fibre_swapcontext(o,n,r) \ (SwitchToFiber((n)->fibre), 1) -# define async_fibre_makecontext(c) \ + +# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 +# define async_fibre_makecontext(c) \ + ((c)->fibre = CreateFiberEx(0, 0, FIBER_FLAG_FLOAT_SWITCH, \ + async_start_func_win, 0)) +# else +# define async_fibre_makecontext(c) \ ((c)->fibre = CreateFiber(0, async_start_func_win, 0)) +# endif + # define async_fibre_free(f) (DeleteFiber((f)->fibre)) int async_fibre_init_dispatcher(async_fibre *fibre); diff --git a/crypto/openssl/crypto/async/async.c b/crypto/openssl/crypto/async/async.c index 326015c605e9..a320d455b7bb 100644 --- a/crypto/openssl/crypto/async/async.c +++ b/crypto/openssl/crypto/async/async.c @@ -1,7 +1,7 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -30,16 +30,18 @@ static CRYPTO_THREAD_LOCAL ctxkey; static CRYPTO_THREAD_LOCAL poolkey; +static void async_delete_thread_state(void *arg); + static async_ctx *async_ctx_new(void) { async_ctx *nctx; - if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) + if (!ossl_init_thread_start(NULL, NULL, async_delete_thread_state)) return NULL; nctx = OPENSSL_malloc(sizeof(*nctx)); if (nctx == NULL) { - ASYNCerr(ASYNC_F_ASYNC_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); goto err; } @@ -81,7 +83,7 @@ static ASYNC_JOB *async_job_new(void) job = OPENSSL_zalloc(sizeof(*job)); if (job == NULL) { - ASYNCerr(ASYNC_F_ASYNC_JOB_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); return NULL; } @@ -136,6 +138,10 @@ static void async_release_job(ASYNC_JOB *job) { async_pool *pool; pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); + if (pool == NULL) { + ERR_raise(ERR_LIB_ASYNC, ERR_R_INTERNAL_ERROR); + return; + } OPENSSL_free(job->funcargs); job->funcargs = NULL; sk_ASYNC_JOB_push(pool->jobs, job); @@ -146,6 +152,10 @@ void async_start_func(void) ASYNC_JOB *job; async_ctx *ctx = async_get_ctx(); + if (ctx == NULL) { + ERR_raise(ERR_LIB_ASYNC, ERR_R_INTERNAL_ERROR); + return; + } while (1) { /* Run the job */ job = ctx->currjob; @@ -159,7 +169,7 @@ void async_start_func(void) * Should not happen. Getting here will close the thread...can't do * much about it */ - ASYNCerr(ASYNC_F_ASYNC_START_FUNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT); + ERR_raise(ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT); } } } @@ -168,6 +178,7 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, int (*func)(void *), void *args, size_t size) { async_ctx *ctx; + OSSL_LIB_CTX *libctx; if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) return ASYNC_ERR; @@ -178,7 +189,7 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, if (ctx == NULL) return ASYNC_ERR; - if (*job) + if (*job != NULL) ctx->currjob = *job; for (;;) { @@ -200,19 +211,38 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, } if (ctx->currjob->status == ASYNC_JOB_PAUSED) { + if (*job == NULL) + return ASYNC_ERR; ctx->currjob = *job; + + /* + * Restore the default libctx to what it was the last time the + * fibre ran + */ + libctx = OSSL_LIB_CTX_set0_default(ctx->currjob->libctx); + if (libctx == NULL) { + /* Failed to set the default context */ + ERR_raise(ERR_LIB_ASYNC, ERR_R_INTERNAL_ERROR); + goto err; + } /* Resume previous job */ if (!async_fibre_swapcontext(&ctx->dispatcher, &ctx->currjob->fibrectx, 1)) { - ASYNCerr(ASYNC_F_ASYNC_START_JOB, - ASYNC_R_FAILED_TO_SWAP_CONTEXT); + ctx->currjob->libctx = OSSL_LIB_CTX_set0_default(libctx); + ERR_raise(ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT); goto err; } + /* + * In case the fibre changed the default libctx we set it back + * again to what it was originally, and remember what it had + * been changed to. + */ + ctx->currjob->libctx = OSSL_LIB_CTX_set0_default(libctx); continue; } /* Should not happen */ - ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_ASYNC, ERR_R_INTERNAL_ERROR); async_release_job(ctx->currjob); ctx->currjob = NULL; *job = NULL; @@ -226,7 +256,7 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, if (args != NULL) { ctx->currjob->funcargs = OPENSSL_malloc(size); if (ctx->currjob->funcargs == NULL) { - ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); async_release_job(ctx->currjob); ctx->currjob = NULL; return ASYNC_ERR; @@ -238,11 +268,17 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, ctx->currjob->func = func; ctx->currjob->waitctx = wctx; + libctx = ossl_lib_ctx_get_concrete(NULL); if (!async_fibre_swapcontext(&ctx->dispatcher, &ctx->currjob->fibrectx, 1)) { - ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); + ERR_raise(ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT); goto err; } + /* + * In case the fibre changed the default libctx we set it back again + * to what it was, and remember what it had been changed to. + */ + ctx->currjob->libctx = OSSL_LIB_CTX_set0_default(libctx); } err: @@ -272,7 +308,7 @@ int ASYNC_pause_job(void) if (!async_fibre_swapcontext(&job->fibrectx, &ctx->dispatcher, 1)) { - ASYNCerr(ASYNC_F_ASYNC_PAUSE_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); + ERR_raise(ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT); return 0; } /* Reset counts of added and deleted fds */ @@ -285,7 +321,7 @@ static void async_empty_pool(async_pool *pool) { ASYNC_JOB *job; - if (!pool || !pool->jobs) + if (pool == NULL || pool->jobs == NULL) return; do { @@ -319,25 +355,25 @@ int ASYNC_init_thread(size_t max_size, size_t init_size) size_t curr_size = 0; if (init_size > max_size) { - ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_INVALID_POOL_SIZE); + ERR_raise(ERR_LIB_ASYNC, ASYNC_R_INVALID_POOL_SIZE); return 0; } if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) return 0; - if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) + if (!ossl_init_thread_start(NULL, NULL, async_delete_thread_state)) return 0; pool = OPENSSL_zalloc(sizeof(*pool)); if (pool == NULL) { - ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); return 0; } pool->jobs = sk_ASYNC_JOB_new_reserve(NULL, init_size); if (pool->jobs == NULL) { - ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); OPENSSL_free(pool); return 0; } @@ -362,7 +398,7 @@ int ASYNC_init_thread(size_t max_size, size_t init_size) } pool->curr_size = curr_size; if (!CRYPTO_THREAD_set_local(&poolkey, pool)) { - ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_FAILED_TO_SET_POOL); + ERR_raise(ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SET_POOL); goto err; } @@ -374,7 +410,7 @@ int ASYNC_init_thread(size_t max_size, size_t init_size) return 0; } -void async_delete_thread_state(void) +static void async_delete_thread_state(void *arg) { async_pool *pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); @@ -393,7 +429,7 @@ void ASYNC_cleanup_thread(void) if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) return; - async_delete_thread_state(); + async_delete_thread_state(NULL); } ASYNC_JOB *ASYNC_get_current_job(void) diff --git a/crypto/openssl/crypto/async/async_err.c b/crypto/openssl/crypto/async/async_err.c index fd5527aae8c9..34db12fb969c 100644 --- a/crypto/openssl/crypto/async/async_err.c +++ b/crypto/openssl/crypto/async/async_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,22 +10,10 @@ #include #include +#include "crypto/asyncerr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA ASYNC_str_functs[] = { - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_CTX_NEW, 0), "async_ctx_new"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_INIT_THREAD, 0), - "ASYNC_init_thread"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_JOB_NEW, 0), "async_job_new"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_PAUSE_JOB, 0), "ASYNC_pause_job"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_START_FUNC, 0), "async_start_func"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_START_JOB, 0), "ASYNC_start_job"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD, 0), - "ASYNC_WAIT_CTX_set_wait_fd"}, - {0, NULL} -}; - static const ERR_STRING_DATA ASYNC_str_reasons[] = { {ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_FAILED_TO_SET_POOL), "failed to set pool"}, @@ -39,13 +27,11 @@ static const ERR_STRING_DATA ASYNC_str_reasons[] = { #endif -int ERR_load_ASYNC_strings(void) +int ossl_err_load_ASYNC_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(ASYNC_str_functs[0].error) == NULL) { - ERR_load_strings_const(ASYNC_str_functs); + if (ERR_reason_error_string(ASYNC_str_reasons[0].error) == NULL) ERR_load_strings_const(ASYNC_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/async/async_local.h b/crypto/openssl/crypto/async/async_local.h index dd1a85e02684..c06f413cf604 100644 --- a/crypto/openssl/crypto/async/async_local.h +++ b/crypto/openssl/crypto/async/async_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -43,6 +43,7 @@ struct async_job_st { int ret; int status; ASYNC_WAIT_CTX *waitctx; + OSSL_LIB_CTX *libctx; }; struct fd_lookup_st { @@ -59,6 +60,9 @@ struct async_wait_ctx_st { struct fd_lookup_st *fds; size_t numadd; size_t numdel; + ASYNC_callback_fn callback; + void *callback_arg; + int status; }; DEFINE_STACK_OF(ASYNC_JOB) diff --git a/crypto/openssl/crypto/async/async_wait.c b/crypto/openssl/crypto/async/async_wait.c index 7723f949a67e..df7d29302182 100644 --- a/crypto/openssl/crypto/async/async_wait.c +++ b/crypto/openssl/crypto/async/async_wait.c @@ -1,7 +1,7 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -48,7 +48,7 @@ int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key, struct fd_lookup_st *fdlookup; if ((fdlookup = OPENSSL_zalloc(sizeof(*fdlookup))) == NULL) { - ASYNCerr(ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); return 0; } @@ -182,6 +182,41 @@ int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key) return 0; } +int ASYNC_WAIT_CTX_set_callback(ASYNC_WAIT_CTX *ctx, + ASYNC_callback_fn callback, + void *callback_arg) +{ + if (ctx == NULL) + return 0; + + ctx->callback = callback; + ctx->callback_arg = callback_arg; + return 1; +} + +int ASYNC_WAIT_CTX_get_callback(ASYNC_WAIT_CTX *ctx, + ASYNC_callback_fn *callback, + void **callback_arg) +{ + if (ctx->callback == NULL) + return 0; + + *callback = ctx->callback; + *callback_arg = ctx->callback_arg; + return 1; +} + +int ASYNC_WAIT_CTX_set_status(ASYNC_WAIT_CTX *ctx, int status) +{ + ctx->status = status; + return 1; +} + +int ASYNC_WAIT_CTX_get_status(ASYNC_WAIT_CTX *ctx) +{ + return ctx->status; +} + void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx) { struct fd_lookup_st *curr, *prev = NULL; diff --git a/crypto/openssl/crypto/bf/asm/bf-586.pl b/crypto/openssl/crypto/bf/asm/bf-586.pl index cddc17bddafa..336448635ab3 100755 --- a/crypto/openssl/crypto/bf/asm/bf-586.pl +++ b/crypto/openssl/crypto/bf/asm/bf-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -12,8 +12,7 @@ push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; require "cbc.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/bf/bf-586.S b/crypto/openssl/crypto/bf/bf-586.S new file mode 100644 index 000000000000..801b28d56381 --- /dev/null +++ b/crypto/openssl/crypto/bf/bf-586.S @@ -0,0 +1,962 @@ +.text +.globl BF_encrypt +.type BF_encrypt,@function +.align 16 +BF_encrypt: +.L_BF_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + + pushl %ebp + pushl %ebx + movl 12(%esp),%ebx + movl 16(%esp),%ebp + pushl %esi + pushl %edi + + movl (%ebx),%edi + movl 4(%ebx),%esi + xorl %eax,%eax + movl (%ebp),%ebx + xorl %ecx,%ecx + xorl %ebx,%edi + + + movl 4(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 8(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 12(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 16(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 20(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 24(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 28(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 32(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 36(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 40(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 44(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 48(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 52(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 56(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 60(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 64(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + + movl 20(%esp),%eax + xorl %ebx,%edi + movl 68(%ebp),%edx + xorl %edx,%esi + movl %edi,4(%eax) + movl %esi,(%eax) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size BF_encrypt,.-.L_BF_encrypt_begin +.globl BF_decrypt +.type BF_decrypt,@function +.align 16 +BF_decrypt: +.L_BF_decrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + + pushl %ebp + pushl %ebx + movl 12(%esp),%ebx + movl 16(%esp),%ebp + pushl %esi + pushl %edi + + movl (%ebx),%edi + movl 4(%ebx),%esi + xorl %eax,%eax + movl 68(%ebp),%ebx + xorl %ecx,%ecx + xorl %ebx,%edi + + + movl 64(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 60(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 56(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 52(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 48(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 44(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 40(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 36(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 32(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 28(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 24(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 20(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 16(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 12(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%edi + + + movl 8(%ebp),%edx + movl %edi,%ebx + xorl %edx,%esi + shrl $16,%ebx + movl %edi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + xorl %eax,%eax + xorl %ebx,%esi + + + movl 4(%ebp),%edx + movl %esi,%ebx + xorl %edx,%edi + shrl $16,%ebx + movl %esi,%edx + movb %bh,%al + andl $255,%ebx + movb %dh,%cl + andl $255,%edx + movl 72(%ebp,%eax,4),%eax + movl 1096(%ebp,%ebx,4),%ebx + addl %eax,%ebx + movl 2120(%ebp,%ecx,4),%eax + xorl %eax,%ebx + movl 3144(%ebp,%edx,4),%edx + addl %edx,%ebx + + movl 20(%esp),%eax + xorl %ebx,%edi + movl (%ebp),%edx + xorl %edx,%esi + movl %edi,4(%eax) + movl %esi,(%eax) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size BF_decrypt,.-.L_BF_decrypt_begin +.globl BF_cbc_encrypt +.type BF_cbc_encrypt,@function +.align 16 +BF_cbc_encrypt: +.L_BF_cbc_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 28(%esp),%ebp + + movl 36(%esp),%ebx + movl (%ebx),%esi + movl 4(%ebx),%edi + pushl %edi + pushl %esi + pushl %edi + pushl %esi + movl %esp,%ebx + movl 36(%esp),%esi + movl 40(%esp),%edi + + movl 56(%esp),%ecx + + movl 48(%esp),%eax + pushl %eax + pushl %ebx + cmpl $0,%ecx + jz .L000decrypt + andl $4294967288,%ebp + movl 8(%esp),%eax + movl 12(%esp),%ebx + jz .L001encrypt_finish +.L002encrypt_loop: + movl (%esi),%ecx + movl 4(%esi),%edx + xorl %ecx,%eax + xorl %edx,%ebx + bswap %eax + bswap %ebx + movl %eax,8(%esp) + movl %ebx,12(%esp) + call .L_BF_encrypt_begin + movl 8(%esp),%eax + movl 12(%esp),%ebx + bswap %eax + bswap %ebx + movl %eax,(%edi) + movl %ebx,4(%edi) + addl $8,%esi + addl $8,%edi + subl $8,%ebp + jnz .L002encrypt_loop +.L001encrypt_finish: + movl 52(%esp),%ebp + andl $7,%ebp + jz .L003finish + call .L004PIC_point +.L004PIC_point: + popl %edx + leal .L005cbc_enc_jmp_table-.L004PIC_point(%edx),%ecx + movl (%ecx,%ebp,4),%ebp + addl %edx,%ebp + xorl %ecx,%ecx + xorl %edx,%edx + jmp *%ebp +.L006ej7: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 6(%esi),%dh + shll $8,%edx +.L007ej6: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 5(%esi),%dh +.L008ej5: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 4(%esi),%dl +.L009ej4: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl (%esi),%ecx + jmp .L010ejend +.L011ej3: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 2(%esi),%ch + shll $8,%ecx +.L012ej2: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 1(%esi),%ch +.L013ej1: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb (%esi),%cl +.L010ejend: + xorl %ecx,%eax + xorl %edx,%ebx + bswap %eax + bswap %ebx + movl %eax,8(%esp) + movl %ebx,12(%esp) + call .L_BF_encrypt_begin + movl 8(%esp),%eax + movl 12(%esp),%ebx + bswap %eax + bswap %ebx + movl %eax,(%edi) + movl %ebx,4(%edi) + jmp .L003finish +.L000decrypt: + andl $4294967288,%ebp + movl 16(%esp),%eax + movl 20(%esp),%ebx + jz .L014decrypt_finish +.L015decrypt_loop: + movl (%esi),%eax + movl 4(%esi),%ebx + bswap %eax + bswap %ebx + movl %eax,8(%esp) + movl %ebx,12(%esp) + call .L_BF_decrypt_begin + movl 8(%esp),%eax + movl 12(%esp),%ebx + bswap %eax + bswap %ebx + movl 16(%esp),%ecx + movl 20(%esp),%edx + xorl %eax,%ecx + xorl %ebx,%edx + movl (%esi),%eax + movl 4(%esi),%ebx + movl %ecx,(%edi) + movl %edx,4(%edi) + movl %eax,16(%esp) + movl %ebx,20(%esp) + addl $8,%esi + addl $8,%edi + subl $8,%ebp + jnz .L015decrypt_loop +.L014decrypt_finish: + movl 52(%esp),%ebp + andl $7,%ebp + jz .L003finish + movl (%esi),%eax + movl 4(%esi),%ebx + bswap %eax + bswap %ebx + movl %eax,8(%esp) + movl %ebx,12(%esp) + call .L_BF_decrypt_begin + movl 8(%esp),%eax + movl 12(%esp),%ebx + bswap %eax + bswap %ebx + movl 16(%esp),%ecx + movl 20(%esp),%edx + xorl %eax,%ecx + xorl %ebx,%edx + movl (%esi),%eax + movl 4(%esi),%ebx +.L016dj7: + rorl $16,%edx + movb %dl,6(%edi) + shrl $16,%edx +.L017dj6: + movb %dh,5(%edi) +.L018dj5: + movb %dl,4(%edi) +.L019dj4: + movl %ecx,(%edi) + jmp .L020djend +.L021dj3: + rorl $16,%ecx + movb %cl,2(%edi) + shll $16,%ecx +.L022dj2: + movb %ch,1(%esi) +.L023dj1: + movb %cl,(%esi) +.L020djend: + jmp .L003finish +.L003finish: + movl 60(%esp),%ecx + addl $24,%esp + movl %eax,(%ecx) + movl %ebx,4(%ecx) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 64 +.L005cbc_enc_jmp_table: +.long 0 +.long .L013ej1-.L004PIC_point +.long .L012ej2-.L004PIC_point +.long .L011ej3-.L004PIC_point +.long .L009ej4-.L004PIC_point +.long .L008ej5-.L004PIC_point +.long .L007ej6-.L004PIC_point +.long .L006ej7-.L004PIC_point +.align 64 +.size BF_cbc_encrypt,.-.L_BF_cbc_encrypt_begin + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/bf/bf_cfb64.c b/crypto/openssl/crypto/bf/bf_cfb64.c index 12332c540d66..d7a92662042b 100644 --- a/crypto/openssl/crypto/bf/bf_cfb64.c +++ b/crypto/openssl/crypto/bf/bf_cfb64.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "bf_local.h" diff --git a/crypto/openssl/crypto/bf/bf_ecb.c b/crypto/openssl/crypto/bf/bf_ecb.c index 38e784cc2dad..b02768261d8b 100644 --- a/crypto/openssl/crypto/bf/bf_ecb.c +++ b/crypto/openssl/crypto/bf/bf_ecb.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "bf_local.h" #include diff --git a/crypto/openssl/crypto/bf/bf_enc.c b/crypto/openssl/crypto/bf/bf_enc.c index 423a4697a51e..40ddaf4af61b 100644 --- a/crypto/openssl/crypto/bf/bf_enc.c +++ b/crypto/openssl/crypto/bf/bf_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "bf_local.h" diff --git a/crypto/openssl/crypto/bf/bf_local.h b/crypto/openssl/crypto/bf/bf_local.h index 8c76976fa4d9..080f37a5f94c 100644 --- a/crypto/openssl/crypto/bf/bf_local.h +++ b/crypto/openssl/crypto/bf/bf_local.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bf/bf_ofb64.c b/crypto/openssl/crypto/bf/bf_ofb64.c index 5d75401fcca5..086c3f07f0bc 100644 --- a/crypto/openssl/crypto/bf/bf_ofb64.c +++ b/crypto/openssl/crypto/bf/bf_ofb64.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "bf_local.h" diff --git a/crypto/openssl/crypto/bf/bf_pi.h b/crypto/openssl/crypto/bf/bf_pi.h index a054b03f8122..8b9896e7f3e0 100644 --- a/crypto/openssl/crypto/bf/bf_pi.h +++ b/crypto/openssl/crypto/bf/bf_pi.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bf/bf_skey.c b/crypto/openssl/crypto/bf/bf_skey.c index ed29cf9153a4..9728be297c17 100644 --- a/crypto/openssl/crypto/bf/bf_skey.c +++ b/crypto/openssl/crypto/bf/bf_skey.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/openssl/crypto/bf/build.info b/crypto/openssl/crypto/bf/build.info index 29adc8ce5072..d24ab5ae573d 100644 --- a/crypto/openssl/crypto/bf/build.info +++ b/crypto/openssl/crypto/bf/build.info @@ -1,7 +1,25 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c \ - {- $target{bf_asm_src} -} -GENERATE[bf-586.s]=asm/bf-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[bf-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl +$BFASM=bf_enc.c +IF[{- !$disabled{asm} -}] + $BFASM_x86=bf-586.S + + # Now that we have defined all the arch specific variables, use the + # appropriate one + IF[$BFASM_{- $target{asm_arch} -}] + $BFASM=$BFASM_{- $target{asm_arch} -} + ENDIF +ENDIF + +$ALL=bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c $BFASM + +SOURCE[../../libcrypto]=$ALL + +# When all deprecated symbols are removed, libcrypto doesn't export the +# blowfish functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=$ALL +ENDIF + +GENERATE[bf-586.S]=asm/bf-586.pl +DEPEND[bf-586.S]=../perlasm/x86asm.pl ../perlasm/cbc.pl diff --git a/crypto/openssl/crypto/bio/bf_buff.c b/crypto/openssl/crypto/bio/bf_buff.c index 51ae1f918d87..53bd02fe1416 100644 --- a/crypto/openssl/crypto/bio/bf_buff.c +++ b/crypto/openssl/crypto/bio/bf_buff.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -25,10 +25,8 @@ static long buffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); static const BIO_METHOD methods_buffer = { BIO_TYPE_BUFFER, "buffer", - /* TODO: Convert to new style write function */ bwrite_conv, buffer_write, - /* TODO: Convert to new style read function */ bread_conv, buffer_read, buffer_puts, @@ -289,7 +287,9 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) break; case BIO_C_SET_BUFF_READ_DATA: if (num > ctx->ibuf_size) { - p1 = OPENSSL_malloc((int)num); + if (num <= 0) + return 0; + p1 = OPENSSL_malloc((size_t)num); if (p1 == NULL) goto malloc_error; OPENSSL_free(ctx->ibuf); @@ -318,12 +318,14 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) p1 = ctx->ibuf; p2 = ctx->obuf; if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) { - p1 = OPENSSL_malloc((int)num); + if (num <= 0) + return 0; + p1 = OPENSSL_malloc((size_t)num); if (p1 == NULL) goto malloc_error; } if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) { - p2 = OPENSSL_malloc((int)num); + p2 = OPENSSL_malloc((size_t)num); if (p2 == NULL) { if (p1 != ctx->ibuf) OPENSSL_free(p1); @@ -381,8 +383,8 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) break; case BIO_CTRL_DUP: dbio = (BIO *)ptr; - if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) || - !BIO_set_write_buffer_size(dbio, ctx->obuf_size)) + if (BIO_set_read_buffer_size(dbio, ctx->ibuf_size) <= 0 || + BIO_set_write_buffer_size(dbio, ctx->obuf_size) <= 0) ret = 0; break; case BIO_CTRL_PEEK: @@ -404,22 +406,15 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) } return ret; malloc_error: - BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } static long buffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) { - long ret = 1; - if (b->next_bio == NULL) return 0; - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return ret; + return BIO_callback_ctrl(b->next_bio, cmd, fp); } static int buffer_gets(BIO *b, char *buf, int size) diff --git a/crypto/openssl/crypto/bio/bf_lbuf.c b/crypto/openssl/crypto/bio/bf_lbuf.c index 72f9901813ea..6908e64d3652 100644 --- a/crypto/openssl/crypto/bio/bf_lbuf.c +++ b/crypto/openssl/crypto/bio/bf_lbuf.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -30,10 +30,8 @@ static long linebuffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); static const BIO_METHOD methods_linebuffer = { BIO_TYPE_LINEBUFFER, "linebuffer", - /* TODO: Convert to new style write function */ bwrite_conv, linebuffer_write, - /* TODO: Convert to new style read function */ bread_conv, linebuffer_read, linebuffer_puts, @@ -60,12 +58,12 @@ static int linebuffer_new(BIO *bi) BIO_LINEBUFFER_CTX *ctx; if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL) { - BIOerr(BIO_F_LINEBUFFER_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } ctx->obuf = OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE); if (ctx->obuf == NULL) { - BIOerr(BIO_F_LINEBUFFER_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); OPENSSL_free(ctx); return 0; } @@ -232,10 +230,12 @@ static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) } break; case BIO_C_SET_BUFF_SIZE: + if (num > INT_MAX) + return 0; obs = (int)num; p = ctx->obuf; if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) { - p = OPENSSL_malloc((int)num); + p = OPENSSL_malloc((size_t)obs); if (p == NULL) goto malloc_error; } @@ -284,7 +284,7 @@ static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) break; case BIO_CTRL_DUP: dbio = (BIO *)ptr; - if (!BIO_set_write_buffer_size(dbio, ctx->obuf_size)) + if (BIO_set_write_buffer_size(dbio, ctx->obuf_size) <= 0) ret = 0; break; default: @@ -295,22 +295,15 @@ static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) } return ret; malloc_error: - BIOerr(BIO_F_LINEBUFFER_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } static long linebuffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) { - long ret = 1; - if (b->next_bio == NULL) return 0; - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return ret; + return BIO_callback_ctrl(b->next_bio, cmd, fp); } static int linebuffer_gets(BIO *b, char *buf, int size) diff --git a/crypto/openssl/crypto/bio/bf_nbio.c b/crypto/openssl/crypto/bio/bf_nbio.c index dd7011ab669f..f9ea1730ba31 100644 --- a/crypto/openssl/crypto/bio/bf_nbio.c +++ b/crypto/openssl/crypto/bio/bf_nbio.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -34,10 +34,8 @@ typedef struct nbio_test_st { static const BIO_METHOD methods_nbiof = { BIO_TYPE_NBIO_TEST, "non-blocking IO test filter", - /* TODO: Convert to new style write function */ bwrite_conv, nbiof_write, - /* TODO: Convert to new style read function */ bread_conv, nbiof_read, nbiof_puts, @@ -58,7 +56,7 @@ static int nbiof_new(BIO *bi) NBIO_TEST *nt; if ((nt = OPENSSL_zalloc(sizeof(*nt))) == NULL) { - BIOerr(BIO_F_NBIOF_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } nt->lrn = -1; @@ -173,16 +171,9 @@ static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr) static long nbiof_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) { - long ret = 1; - if (b->next_bio == NULL) return 0; - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return ret; + return BIO_callback_ctrl(b->next_bio, cmd, fp); } static int nbiof_gets(BIO *bp, char *buf, int size) diff --git a/crypto/openssl/crypto/bio/bf_null.c b/crypto/openssl/crypto/bio/bf_null.c index 48c6be692a5d..7add76a4ca5c 100644 --- a/crypto/openssl/crypto/bio/bf_null.c +++ b/crypto/openssl/crypto/bio/bf_null.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -25,10 +25,8 @@ static long nullf_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); static const BIO_METHOD methods_nullf = { BIO_TYPE_NULL_FILTER, "NULL filter", - /* TODO: Convert to new style write function */ bwrite_conv, nullf_write, - /* TODO: Convert to new style read function */ bread_conv, nullf_read, nullf_puts, @@ -95,16 +93,9 @@ static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr) static long nullf_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) { - long ret = 1; - if (b->next_bio == NULL) return 0; - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return ret; + return BIO_callback_ctrl(b->next_bio, cmd, fp); } static int nullf_gets(BIO *bp, char *buf, int size) diff --git a/crypto/openssl/apps/bf_prefix.c b/crypto/openssl/crypto/bio/bf_prefix.c similarity index 60% rename from crypto/openssl/apps/bf_prefix.c rename to crypto/openssl/crypto/bio/bf_prefix.c index bae3c91bf8b3..872efa13b559 100644 --- a/crypto/openssl/apps/bf_prefix.c +++ b/crypto/openssl/crypto/bio/bf_prefix.c @@ -1,7 +1,7 @@ /* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,8 +10,7 @@ #include #include #include -#include -#include "apps.h" +#include "bio_local.h" static int prefix_write(BIO *b, const char *out, size_t outl, size_t *numwritten); @@ -23,31 +22,31 @@ static int prefix_create(BIO *b); static int prefix_destroy(BIO *b); static long prefix_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); -static BIO_METHOD *prefix_meth = NULL; - -BIO_METHOD *apps_bf_prefix(void) +static const BIO_METHOD prefix_meth = { + BIO_TYPE_BUFFER, + "prefix", + prefix_write, + NULL, + prefix_read, + NULL, + prefix_puts, + prefix_gets, + prefix_ctrl, + prefix_create, + prefix_destroy, + prefix_callback_ctrl, +}; + +const BIO_METHOD *BIO_f_prefix(void) { - if (prefix_meth == NULL) { - if ((prefix_meth = - BIO_meth_new(BIO_TYPE_FILTER, "Prefix filter")) == NULL - || !BIO_meth_set_create(prefix_meth, prefix_create) - || !BIO_meth_set_destroy(prefix_meth, prefix_destroy) - || !BIO_meth_set_write_ex(prefix_meth, prefix_write) - || !BIO_meth_set_read_ex(prefix_meth, prefix_read) - || !BIO_meth_set_puts(prefix_meth, prefix_puts) - || !BIO_meth_set_gets(prefix_meth, prefix_gets) - || !BIO_meth_set_ctrl(prefix_meth, prefix_ctrl) - || !BIO_meth_set_callback_ctrl(prefix_meth, prefix_callback_ctrl)) { - BIO_meth_free(prefix_meth); - prefix_meth = NULL; - } - } - return prefix_meth; + return &prefix_meth; } typedef struct prefix_ctx_st { - char *prefix; - int linestart; /* flag to indicate we're at the line start */ + char *prefix; /* Text prefix, given by user */ + unsigned int indent; /* Indentation amount, given by user */ + + int linestart; /* flag to indicate we're at the line start */ } PREFIX_CTX; static int prefix_create(BIO *b) @@ -58,6 +57,7 @@ static int prefix_create(BIO *b) return 0; ctx->prefix = NULL; + ctx->indent = 0; ctx->linestart = 1; BIO_set_data(b, ctx); BIO_set_init(b, 1); @@ -86,9 +86,16 @@ static int prefix_write(BIO *b, const char *out, size_t outl, if (ctx == NULL) return 0; - /* If no prefix is set or if it's empty, we've got nothing to do here */ - if (ctx->prefix == NULL || *ctx->prefix == '\0') { - /* We do note if what comes next will be a new line, though */ + /* + * If no prefix is set or if it's empty, and no indentation amount is set, + * we've got nothing to do here + */ + if ((ctx->prefix == NULL || *ctx->prefix == '\0') + && ctx->indent == 0) { + /* + * We do note if what comes next will be a new line, though, so we're + * prepared to handle prefix and indentation the next time around. + */ if (outl > 0) ctx->linestart = (out[outl-1] == '\n'); return BIO_write_ex(BIO_next(b), out, outl, numwritten); @@ -100,13 +107,18 @@ static int prefix_write(BIO *b, const char *out, size_t outl, size_t i; char c; - /* If we know that we're at the start of the line, output the prefix */ + /* + * If we know that we're at the start of the line, output prefix and + * indentation. + */ if (ctx->linestart) { size_t dontcare; - if (!BIO_write_ex(BIO_next(b), ctx->prefix, strlen(ctx->prefix), - &dontcare)) + if (ctx->prefix != NULL + && !BIO_write_ex(BIO_next(b), ctx->prefix, strlen(ctx->prefix), + &dontcare)) return 0; + BIO_printf(BIO_next(b), "%*s", ctx->indent, ""); ctx->linestart = 0; } @@ -139,21 +151,39 @@ static int prefix_write(BIO *b, const char *out, size_t outl, static long prefix_ctrl(BIO *b, int cmd, long num, void *ptr) { long ret = 0; + PREFIX_CTX *ctx; - switch (cmd) { - case PREFIX_CTRL_SET_PREFIX: - { - PREFIX_CTX *ctx = BIO_get_data(b); - - if (ctx == NULL) - break; + if (b == NULL || (ctx = BIO_get_data(b)) == NULL) + return -1; - OPENSSL_free(ctx->prefix); + switch (cmd) { + case BIO_CTRL_SET_PREFIX: + OPENSSL_free(ctx->prefix); + if (ptr == NULL) { + ctx->prefix = NULL; + ret = 1; + } else { ctx->prefix = OPENSSL_strdup((const char *)ptr); ret = ctx->prefix != NULL; } break; + case BIO_CTRL_SET_INDENT: + if (num >= 0) { + ctx->indent = (unsigned int)num; + ret = 1; + } + break; + case BIO_CTRL_GET_INDENT: + ret = (long)ctx->indent; + break; default: + /* Commands that we intercept before passing them along */ + switch (cmd) { + case BIO_C_FILE_SEEK: + case BIO_CTRL_RESET: + ctx->linestart = 1; + break; + } if (BIO_next(b) != NULL) ret = BIO_ctrl(BIO_next(b), cmd, num, ptr); break; diff --git a/crypto/openssl/crypto/bio/bf_readbuff.c b/crypto/openssl/crypto/bio/bf_readbuff.c new file mode 100644 index 000000000000..135ccef83bf3 --- /dev/null +++ b/crypto/openssl/crypto/bio/bf_readbuff.c @@ -0,0 +1,288 @@ +/* + * Copyright 2021 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 + */ + +/* + * This is a read only BIO filter that can be used to add BIO_tell() and + * BIO_seek() support to source/sink BIO's (such as a file BIO that uses stdin). + * It does this by caching ALL data read from the BIO source/sink into a + * resizable memory buffer. + */ + +#include +#include +#include "bio_local.h" +#include "internal/cryptlib.h" + +#define DEFAULT_BUFFER_SIZE 4096 + +static int readbuffer_write(BIO *h, const char *buf, int num); +static int readbuffer_read(BIO *h, char *buf, int size); +static int readbuffer_puts(BIO *h, const char *str); +static int readbuffer_gets(BIO *h, char *str, int size); +static long readbuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int readbuffer_new(BIO *h); +static int readbuffer_free(BIO *data); +static long readbuffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); + +static const BIO_METHOD methods_readbuffer = { + BIO_TYPE_BUFFER, + "readbuffer", + bwrite_conv, + readbuffer_write, + bread_conv, + readbuffer_read, + readbuffer_puts, + readbuffer_gets, + readbuffer_ctrl, + readbuffer_new, + readbuffer_free, + readbuffer_callback_ctrl, +}; + +const BIO_METHOD *BIO_f_readbuffer(void) +{ + return &methods_readbuffer; +} + +static int readbuffer_new(BIO *bi) +{ + BIO_F_BUFFER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx == NULL) + return 0; + ctx->ibuf_size = DEFAULT_BUFFER_SIZE; + ctx->ibuf = OPENSSL_zalloc(DEFAULT_BUFFER_SIZE); + if (ctx->ibuf == NULL) { + OPENSSL_free(ctx); + return 0; + } + + bi->init = 1; + bi->ptr = (char *)ctx; + bi->flags = 0; + return 1; +} + +static int readbuffer_free(BIO *a) +{ + BIO_F_BUFFER_CTX *b; + + if (a == NULL) + return 0; + b = (BIO_F_BUFFER_CTX *)a->ptr; + OPENSSL_free(b->ibuf); + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return 1; +} + +static int readbuffer_resize(BIO_F_BUFFER_CTX *ctx, int sz) +{ + char *tmp; + + /* Figure out how many blocks are required */ + sz += (ctx->ibuf_off + DEFAULT_BUFFER_SIZE - 1); + sz = DEFAULT_BUFFER_SIZE * (sz / DEFAULT_BUFFER_SIZE); + + /* Resize if the buffer is not big enough */ + if (sz > ctx->ibuf_size) { + tmp = OPENSSL_realloc(ctx->ibuf, sz); + if (tmp == NULL) + return 0; + ctx->ibuf = tmp; + ctx->ibuf_size = sz; + } + return 1; +} + +static int readbuffer_read(BIO *b, char *out, int outl) +{ + int i, num = 0; + BIO_F_BUFFER_CTX *ctx; + + if (out == NULL || outl == 0) + return 0; + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return 0; + BIO_clear_retry_flags(b); + + for (;;) { + i = ctx->ibuf_len; + /* If there is something in the buffer just read it. */ + if (i != 0) { + if (i > outl) + i = outl; + memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i); + ctx->ibuf_off += i; + ctx->ibuf_len -= i; + num += i; + /* Exit if we have read the bytes required out of the buffer */ + if (outl == i) + return num; + outl -= i; + out += i; + } + + /* Only gets here if the buffer has been consumed */ + if (!readbuffer_resize(ctx, outl)) + return 0; + + /* Do some buffering by reading from the next bio */ + i = BIO_read(b->next_bio, ctx->ibuf + ctx->ibuf_off, outl); + if (i <= 0) { + BIO_copy_next_retry(b); + if (i < 0) + return ((num > 0) ? num : i); + else + return num; /* i == 0 */ + } + ctx->ibuf_len = i; + } +} + +static int readbuffer_write(BIO *b, const char *in, int inl) +{ + return 0; +} +static int readbuffer_puts(BIO *b, const char *str) +{ + return 0; +} + +static long readbuffer_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO_F_BUFFER_CTX *ctx; + long ret = 1, sz; + + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + + switch (cmd) { + case BIO_CTRL_EOF: + if (ctx->ibuf_len > 0) + return 0; + if (b->next_bio == NULL) + return 1; + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + + case BIO_C_FILE_SEEK: + case BIO_CTRL_RESET: + sz = ctx->ibuf_off + ctx->ibuf_len; + /* Assume it can only seek backwards */ + if (num < 0 || num > sz) + return 0; + ctx->ibuf_off = num; + ctx->ibuf_len = sz - num; + break; + + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = (long)ctx->ibuf_off; + break; + case BIO_CTRL_PENDING: + ret = (long)ctx->ibuf_len; + if (ret == 0) { + if (b->next_bio == NULL) + return 0; + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + } + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static long readbuffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) +{ + if (b->next_bio == NULL) + return 0; + return BIO_callback_ctrl(b->next_bio, cmd, fp); +} + +static int readbuffer_gets(BIO *b, char *buf, int size) +{ + BIO_F_BUFFER_CTX *ctx; + int num = 0, num_chars, found_newline; + char *p; + int i, j; + + if (size == 0) + return 0; + --size; /* the passed in size includes the terminator - so remove it here */ + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + BIO_clear_retry_flags(b); + + /* If data is already buffered then use this first */ + if (ctx->ibuf_len > 0) { + p = ctx->ibuf + ctx->ibuf_off; + found_newline = 0; + for (num_chars = 0; + (num_chars < ctx->ibuf_len) && (num_chars < size); + num_chars++) { + *buf++ = p[num_chars]; + if (p[num_chars] == '\n') { + found_newline = 1; + num_chars++; + break; + } + } + num += num_chars; + size -= num_chars; + ctx->ibuf_len -= num_chars; + ctx->ibuf_off += num_chars; + if (found_newline || size == 0) { + *buf = '\0'; + return num; + } + } + /* + * If there is no buffered data left then read any remaining data from the + * next bio. + */ + + /* Resize if we have to */ + if (!readbuffer_resize(ctx, 1 + size)) + return 0; + /* + * Read more data from the next bio using BIO_read_ex: + * Note we cannot use BIO_gets() here as it does not work on a + * binary stream that contains 0x00. (Since strlen() will stop at + * any 0x00 not at the last read '\n' in a FILE bio). + * Also note that some applications open and close the file bio + * multiple times and need to read the next available block when using + * stdin - so we need to READ one byte at a time! + */ + p = ctx->ibuf + ctx->ibuf_off; + for (i = 0; i < size; ++i) { + j = BIO_read(b->next_bio, p, 1); + if (j <= 0) { + BIO_copy_next_retry(b); + *buf = '\0'; + return num > 0 ? num : j; + } + *buf++ = *p; + num++; + ctx->ibuf_off++; + if (*p == '\n') + break; + ++p; + } + *buf = '\0'; + return num; +} diff --git a/crypto/openssl/crypto/bio/b_addr.c b/crypto/openssl/crypto/bio/bio_addr.c similarity index 90% rename from crypto/openssl/crypto/bio/b_addr.c rename to crypto/openssl/crypto/bio/bio_addr.c index 0af7a330bc68..a80774bbd7ca 100644 --- a/crypto/openssl/crypto/bio/b_addr.c +++ b/crypto/openssl/crypto/bio/bio_addr.c @@ -1,7 +1,7 @@ /* * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,6 +11,16 @@ # define _GNU_SOURCE #endif +/* + * VC configurations may define UNICODE, to indicate to the C RTL that + * WCHAR functions are preferred. + * This affects functions like gai_strerror(), which is implemented as + * an alias macro for gai_strerrorA() (which returns a const char *) or + * gai_strerrorW() (which returns a const WCHAR *). This source file + * assumes POSIX declarations, so prefer the non-UNICODE definitions. + */ +#undef UNICODE + #include #include @@ -44,7 +54,7 @@ BIO_ADDR *BIO_ADDR_new(void) BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - BIOerr(BIO_F_BIO_ADDR_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return NULL; } @@ -211,13 +221,12 @@ static int addr_strings(const BIO_ADDR *ap, int numeric, flags)) != 0) { # ifdef EAI_SYSTEM if (ret == EAI_SYSTEM) { - SYSerr(SYS_F_GETNAMEINFO, get_last_socket_error()); - BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getnameinfo()"); } else # endif { - BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB); - ERR_add_error_data(1, gai_strerror(ret)); + ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB, gai_strerror(ret)); } return 0; } @@ -258,7 +267,7 @@ static int addr_strings(const BIO_ADDR *ap, int numeric, OPENSSL_free(*service); *service = NULL; } - BIOerr(BIO_F_ADDR_STRINGS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } @@ -545,13 +554,13 @@ int BIO_parse_hostserv(const char *hostserv, char **host, char **service, return 1; amb_err: - BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_AMBIGUOUS_HOST_OR_SERVICE); + ERR_raise(ERR_LIB_BIO, BIO_R_AMBIGUOUS_HOST_OR_SERVICE); return 0; spec_err: - BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_MALFORMED_HOST_OR_SERVICE); + ERR_raise(ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE); return 0; memerr: - BIOerr(BIO_F_BIO_PARSE_HOSTSERV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } @@ -570,7 +579,7 @@ static int addrinfo_wrap(int family, int socktype, BIO_ADDRINFO **bai) { if ((*bai = OPENSSL_zalloc(sizeof(**bai))) == NULL) { - BIOerr(BIO_F_ADDRINFO_WRAP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } @@ -607,8 +616,6 @@ static int addrinfo_wrap(int family, int socktype, DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init) { - if (!OPENSSL_init_crypto(0, NULL)) - return 0; bio_lookup_lock = CRYPTO_THREAD_lock_new(); return bio_lookup_lock != NULL; } @@ -621,8 +628,8 @@ int BIO_lookup(const char *host, const char *service, } /*- - * BIO_lookup_ex - look up the node and service you want to connect to. - * @node: the node you want to connect to. + * BIO_lookup_ex - look up the host and service you want to connect to. + * @host: the host (or node, in case family == AF_UNIX) you want to connect to. * @service: the service you want to connect to. * @lookup_type: declare intent with the result, client or server. * @family: the address family you want to use. Use AF_UNSPEC for any, or @@ -635,7 +642,7 @@ int BIO_lookup(const char *host, const char *service, * with 0 for the protocol) * @res: Storage place for the resulting list of returned addresses * - * This will do a lookup of the node and service that you want to connect to. + * This will do a lookup of the host and service that you want to connect to. * It returns a linked list of different addresses you can try to connect to. * * When no longer needed you should call BIO_ADDRINFO_free() to free the result. @@ -660,7 +667,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, #endif break; default: - BIOerr(BIO_F_BIO_LOOKUP_EX, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY); + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY); return 0; } @@ -669,7 +676,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res)) return 1; else - BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } #endif @@ -706,13 +713,14 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, switch ((gai_ret = getaddrinfo(host, service, &hints, res))) { # ifdef EAI_SYSTEM case EAI_SYSTEM: - SYSerr(SYS_F_GETADDRINFO, get_last_socket_error()); - BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getaddrinfo()"); + ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB); break; # endif # ifdef EAI_MEMORY case EAI_MEMORY: - BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); break; # endif case 0: @@ -727,8 +735,8 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, goto retry; } # endif - BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB); - ERR_add_error_data(1, gai_strerror(old_ret ? old_ret : gai_ret)); + ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB, + gai_strerror(old_ret ? old_ret : gai_ret)); break; } } else { @@ -769,12 +777,15 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, #endif if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) { - BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); ret = 0; goto err; } - CRYPTO_THREAD_write_lock(bio_lookup_lock); + if (!CRYPTO_THREAD_write_lock(bio_lookup_lock)) { + ret = 0; + goto err; + } he_fallback_address = INADDR_ANY; if (host == NULL) { he = &he_fallback; @@ -788,7 +799,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, default: /* We forgot to handle a lookup type! */ assert("We forgot to handle a lookup type!" == NULL); - BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); ret = 0; goto err; } @@ -810,12 +821,15 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, */ # if defined(OPENSSL_SYS_VXWORKS) /* h_errno doesn't exist on VxWorks */ - SYSerr(SYS_F_GETHOSTBYNAME, 1000 ); + ERR_raise_data(ERR_LIB_SYS, 1000, + "calling gethostbyname()"); # else - SYSerr(SYS_F_GETHOSTBYNAME, 1000 + h_errno); + ERR_raise_data(ERR_LIB_SYS, 1000 + h_errno, + "calling gethostbyname()"); # endif #else - SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling gethostbyname()"); #endif ret = 0; goto err; @@ -861,15 +875,12 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, se = getservbyname(service, proto); if (se == NULL) { -#ifndef OPENSSL_SYS_WINDOWS - SYSerr(SYS_F_GETSERVBYNAME, errno); -#else - SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError()); -#endif + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getservbyname()"); goto err; } } else { - BIOerr(BIO_F_BIO_LOOKUP_EX, BIO_R_MALFORMED_HOST_OR_SERVICE); + ERR_raise(ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE); goto err; } } @@ -911,7 +922,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, addrinfo_malloc_err: BIO_ADDRINFO_free(*res); *res = NULL; - BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); ret = 0; goto err; } diff --git a/crypto/openssl/crypto/bio/bio_cb.c b/crypto/openssl/crypto/bio/bio_cb.c index a153100a8825..522a05369dc7 100644 --- a/crypto/openssl/crypto/bio/bio_cb.c +++ b/crypto/openssl/crypto/bio/bio_cb.c @@ -1,12 +1,14 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include @@ -14,25 +16,25 @@ #include "internal/cryptlib.h" #include -long BIO_debug_callback(BIO *bio, int cmd, const char *argp, - int argi, long argl, long ret) +long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len, + int argi, long argl, int ret, size_t *processed) { BIO *b; char buf[256]; char *p; - long r = 1; - int len, left; + int left; + size_t l = 0; - if (BIO_CB_RETURN & cmd) - r = ret; + if (processed != NULL) + l = *processed; - len = BIO_snprintf(buf, sizeof(buf), "BIO[%p]: ", (void *)bio); + left = BIO_snprintf(buf, sizeof(buf), "BIO[%p]: ", (void *)bio); /* Ignore errors and continue printing the other information. */ - if (len < 0) - len = 0; - p = buf + len; - left = sizeof(buf) - len; + if (left < 0) + left = 0; + p = buf + left; + left = sizeof(buf) - left; switch (cmd) { case BIO_CB_FREE: @@ -40,47 +42,47 @@ long BIO_debug_callback(BIO *bio, int cmd, const char *argp, break; case BIO_CB_READ: if (bio->method->type & BIO_TYPE_DESCRIPTOR) - BIO_snprintf(p, left, "read(%d,%lu) - %s fd=%d\n", - bio->num, (unsigned long)argi, + BIO_snprintf(p, left, "read(%d,%zu) - %s fd=%d\n", + bio->num, len, bio->method->name, bio->num); else - BIO_snprintf(p, left, "read(%d,%lu) - %s\n", - bio->num, (unsigned long)argi, bio->method->name); + BIO_snprintf(p, left, "read(%d,%zu) - %s\n", + bio->num, len, bio->method->name); break; case BIO_CB_WRITE: if (bio->method->type & BIO_TYPE_DESCRIPTOR) - BIO_snprintf(p, left, "write(%d,%lu) - %s fd=%d\n", - bio->num, (unsigned long)argi, + BIO_snprintf(p, left, "write(%d,%zu) - %s fd=%d\n", + bio->num, len, bio->method->name, bio->num); else - BIO_snprintf(p, left, "write(%d,%lu) - %s\n", - bio->num, (unsigned long)argi, bio->method->name); + BIO_snprintf(p, left, "write(%d,%zu) - %s\n", + bio->num, len, bio->method->name); break; case BIO_CB_PUTS: BIO_snprintf(p, left, "puts() - %s\n", bio->method->name); break; case BIO_CB_GETS: - BIO_snprintf(p, left, "gets(%lu) - %s\n", (unsigned long)argi, + BIO_snprintf(p, left, "gets(%zu) - %s\n", len, bio->method->name); break; case BIO_CB_CTRL: - BIO_snprintf(p, left, "ctrl(%lu) - %s\n", (unsigned long)argi, + BIO_snprintf(p, left, "ctrl(%d) - %s\n", argi, bio->method->name); break; case BIO_CB_RETURN | BIO_CB_READ: - BIO_snprintf(p, left, "read return %ld\n", ret); + BIO_snprintf(p, left, "read return %d processed: %zu\n", ret, l); break; case BIO_CB_RETURN | BIO_CB_WRITE: - BIO_snprintf(p, left, "write return %ld\n", ret); + BIO_snprintf(p, left, "write return %d processed: %zu\n", ret, l); break; case BIO_CB_RETURN | BIO_CB_GETS: - BIO_snprintf(p, left, "gets return %ld\n", ret); + BIO_snprintf(p, left, "gets return %d processed: %zu\n", ret, l); break; case BIO_CB_RETURN | BIO_CB_PUTS: - BIO_snprintf(p, left, "puts return %ld\n", ret); + BIO_snprintf(p, left, "puts return %d processed: %zu\n", ret, l); break; case BIO_CB_RETURN | BIO_CB_CTRL: - BIO_snprintf(p, left, "ctrl return %ld\n", ret); + BIO_snprintf(p, left, "ctrl return %d\n", ret); break; default: BIO_snprintf(p, left, "bio callback - unknown type (%d)\n", cmd); @@ -94,5 +96,19 @@ long BIO_debug_callback(BIO *bio, int cmd, const char *argp, else fputs(buf, stderr); #endif - return r; + return ret; +} + +#ifndef OPENSSL_NO_DEPRECATED_3_0 +long BIO_debug_callback(BIO *bio, int cmd, const char *argp, + int argi, long argl, long ret) +{ + size_t processed = 0; + + if (ret > 0) + processed = (size_t)ret; + BIO_debug_callback_ex(bio, cmd, argp, (size_t)argi, + argi, argl, ret > 0 ? 1 : (int)ret, &processed); + return ret; } +#endif diff --git a/crypto/openssl/crypto/bio/b_dump.c b/crypto/openssl/crypto/bio/bio_dump.c similarity index 77% rename from crypto/openssl/crypto/bio/b_dump.c rename to crypto/openssl/crypto/bio/bio_dump.c index f175e244b233..c453da62688c 100644 --- a/crypto/openssl/crypto/bio/b_dump.c +++ b/crypto/openssl/crypto/bio/bio_dump.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,15 +20,16 @@ #define SPACE(buf, pos, n) (sizeof(buf) - (pos) > (n)) int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), - void *u, const char *s, int len) + void *u, const void *s, int len) { return BIO_dump_indent_cb(cb, u, s, len, 0); } int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), - void *u, const char *s, int len, int indent) + void *u, const void *v, int len, int indent) { - int ret = 0; + const unsigned char *s = v; + int res, ret = 0; char buf[288 + 1]; int i, j, rows, n; unsigned char ch; @@ -51,7 +52,7 @@ int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), if (((i * dump_width) + j) >= len) { strcpy(buf + n, " "); } else { - ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; + ch = *(s + i * dump_width + j) & 0xff; BIO_snprintf(buf + n, 4, "%02x%c", ch, j == 7 ? '-' : ' '); } @@ -66,7 +67,7 @@ int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), if (((i * dump_width) + j) >= len) break; if (SPACE(buf, n, 1)) { - ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; + ch = *(s + i * dump_width + j) & 0xff; #ifndef CHARSET_EBCDIC buf[n++] = ((ch >= ' ') && (ch <= '~')) ? ch : '.'; #else @@ -85,7 +86,10 @@ int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), * if this is the last call then update the ddt_dump thing so that we * will move the selection point in the debug window */ - ret += cb((void *)buf, n, u); + res = cb((void *)buf, n, u); + if (res < 0) + return res; + ret += res; } return ret; } @@ -96,12 +100,12 @@ static int write_fp(const void *data, size_t len, void *fp) return UP_fwrite(data, len, 1, fp); } -int BIO_dump_fp(FILE *fp, const char *s, int len) +int BIO_dump_fp(FILE *fp, const void *s, int len) { return BIO_dump_cb(write_fp, fp, s, len); } -int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent) +int BIO_dump_indent_fp(FILE *fp, const void *s, int len, int indent) { return BIO_dump_indent_cb(write_fp, fp, s, len, indent); } @@ -112,19 +116,20 @@ static int write_bio(const void *data, size_t len, void *bp) return BIO_write((BIO *)bp, (const char *)data, len); } -int BIO_dump(BIO *bp, const char *s, int len) +int BIO_dump(BIO *bp, const void *s, int len) { return BIO_dump_cb(write_bio, bp, s, len); } -int BIO_dump_indent(BIO *bp, const char *s, int len, int indent) +int BIO_dump_indent(BIO *bp, const void *s, int len, int indent) { return BIO_dump_indent_cb(write_bio, bp, s, len, indent); } -int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, +int BIO_hex_string(BIO *out, int indent, int width, const void *data, int datalen) { + const unsigned char *d = data; int i, j = 0; if (datalen < 1) @@ -134,7 +139,7 @@ int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, if (i && !j) BIO_printf(out, "%*s", indent, ""); - BIO_printf(out, "%02X:", data[i]); + BIO_printf(out, "%02X:", d[i]); j = (j + 1) % width; if (!j) @@ -143,6 +148,6 @@ int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, if (i && !j) BIO_printf(out, "%*s", indent, ""); - BIO_printf(out, "%02X", data[datalen - 1]); + BIO_printf(out, "%02X", d[datalen - 1]); return 1; } diff --git a/crypto/openssl/crypto/bio/bio_err.c b/crypto/openssl/crypto/bio/bio_err.c index 7aa9dabb2915..7a36c61148a7 100644 --- a/crypto/openssl/crypto/bio/bio_err.c +++ b/crypto/openssl/crypto/bio/bio_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,69 +10,10 @@ #include #include +#include "crypto/bioerr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA BIO_str_functs[] = { - {ERR_PACK(ERR_LIB_BIO, BIO_F_ACPT_STATE, 0), "acpt_state"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_ADDRINFO_WRAP, 0), "addrinfo_wrap"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_ADDR_STRINGS, 0), "addr_strings"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT, 0), "BIO_accept"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT_EX, 0), "BIO_accept_ex"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT_NEW, 0), "BIO_ACCEPT_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ADDR_NEW, 0), "BIO_ADDR_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_BIND, 0), "BIO_bind"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CALLBACK_CTRL, 0), "BIO_callback_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CONNECT, 0), "BIO_connect"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CONNECT_NEW, 0), "BIO_CONNECT_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CTRL, 0), "BIO_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GETS, 0), "BIO_gets"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_HOST_IP, 0), "BIO_get_host_ip"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_NEW_INDEX, 0), "BIO_get_new_index"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_PORT, 0), "BIO_get_port"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LISTEN, 0), "BIO_listen"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LOOKUP, 0), "BIO_lookup"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LOOKUP_EX, 0), "BIO_lookup_ex"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_MAKE_PAIR, 0), "bio_make_pair"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_METH_NEW, 0), "BIO_meth_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW, 0), "BIO_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_DGRAM_SCTP, 0), "BIO_new_dgram_sctp"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_FILE, 0), "BIO_new_file"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_MEM_BUF, 0), "BIO_new_mem_buf"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NREAD, 0), "BIO_nread"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NREAD0, 0), "BIO_nread0"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NWRITE, 0), "BIO_nwrite"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NWRITE0, 0), "BIO_nwrite0"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_PARSE_HOSTSERV, 0), "BIO_parse_hostserv"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_PUTS, 0), "BIO_puts"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ, 0), "BIO_read"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ_EX, 0), "BIO_read_ex"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ_INTERN, 0), "bio_read_intern"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCKET, 0), "BIO_socket"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCKET_NBIO, 0), "BIO_socket_nbio"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCK_INFO, 0), "BIO_sock_info"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCK_INIT, 0), "BIO_sock_init"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE, 0), "BIO_write"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE_EX, 0), "BIO_write_ex"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE_INTERN, 0), "bio_write_intern"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_BUFFER_CTRL, 0), "buffer_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_CONN_CTRL, 0), "conn_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_CONN_STATE, 0), "conn_state"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_NEW, 0), "dgram_sctp_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_READ, 0), "dgram_sctp_read"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_WRITE, 0), "dgram_sctp_write"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_DOAPR_OUTCH, 0), "doapr_outch"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_FILE_CTRL, 0), "file_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_FILE_READ, 0), "file_read"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_LINEBUFFER_CTRL, 0), "linebuffer_ctrl"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_LINEBUFFER_NEW, 0), "linebuffer_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_MEM_WRITE, 0), "mem_write"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_NBIOF_NEW, 0), "nbiof_new"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_SLG_WRITE, 0), "slg_write"}, - {ERR_PACK(ERR_LIB_BIO, BIO_F_SSL_NEW, 0), "SSL_new"}, - {0, NULL} -}; - static const ERR_STRING_DATA BIO_str_reasons[] = { {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ACCEPT_ERROR), "accept error"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET), @@ -82,6 +23,7 @@ static const ERR_STRING_DATA BIO_str_reasons[] = { {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BAD_FOPEN_MODE), "bad fopen mode"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BROKEN_PIPE), "broken pipe"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_ERROR), "connect error"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_TIMEOUT), "connect timeout"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), "gethostbyname addr is not af inet"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETSOCKNAME_ERROR), "getsockname error"}, @@ -104,7 +46,8 @@ static const ERR_STRING_DATA BIO_str_reasons[] = { "no hostname or service specified"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_DEFINED), "no port defined"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "no such file"}, - {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NULL_PARAMETER), "null parameter"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_ERROR), "transfer error"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_TIMEOUT), "transfer timeout"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_BIND_SOCKET), "unable to bind socket"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_CREATE_SOCKET), @@ -133,13 +76,11 @@ static const ERR_STRING_DATA BIO_str_reasons[] = { #endif -int ERR_load_BIO_strings(void) +int ossl_err_load_BIO_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) { - ERR_load_strings_const(BIO_str_functs); + if (ERR_reason_error_string(BIO_str_reasons[0].error) == NULL) ERR_load_strings_const(BIO_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/bio/bio_lib.c b/crypto/openssl/crypto/bio/bio_lib.c index d2202e537b30..ecc16a5ee36a 100644 --- a/crypto/openssl/crypto/bio/bio_lib.c +++ b/crypto/openssl/crypto/bio/bio_lib.c @@ -1,26 +1,32 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include +#include "internal/numbers.h" #include "bio_local.h" -#include "internal/cryptlib.h" - /* * Helper macro for the callback to determine whether an operator expects a * len parameter or not */ -#define HAS_LEN_OPER(o) ((o) == BIO_CB_READ || (o) == BIO_CB_WRITE || \ - (o) == BIO_CB_GETS) +#define HAS_LEN_OPER(o) ((o) == BIO_CB_READ || (o) == BIO_CB_WRITE \ + || (o) == BIO_CB_GETS) +#ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HAS_CALLBACK(b) ((b)->callback != NULL || (b)->callback_ex != NULL) +#else +# define HAS_CALLBACK(b) ((b)->callback_ex != NULL) +#endif /* * Helper function to work out whether to call the new style callback or the old * one, and translate between the two. @@ -29,14 +35,18 @@ * for the "long" used for "inret" */ static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len, - int argi, long argl, long inret, size_t *processed) + int argi, long argl, long inret, + size_t *processed) { - long ret; + long ret = inret; +#ifndef OPENSSL_NO_DEPRECATED_3_0 int bareoper; if (b->callback_ex != NULL) +#endif return b->callback_ex(b, oper, argp, len, argi, argl, inret, processed); +#ifndef OPENSSL_NO_DEPRECATED_3_0 /* Strip off any BIO_CB_RETURN flag */ bareoper = oper & ~BIO_CB_RETURN; @@ -64,19 +74,20 @@ static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len, *processed = (size_t)ret; ret = 1; } - +#endif return ret; } -BIO *BIO_new(const BIO_METHOD *method) +BIO *BIO_new_ex(OSSL_LIB_CTX *libctx, const BIO_METHOD *method) { BIO *bio = OPENSSL_zalloc(sizeof(*bio)); if (bio == NULL) { - BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return NULL; } + bio->libctx = libctx; bio->method = method; bio->shutdown = 1; bio->references = 1; @@ -86,13 +97,13 @@ BIO *BIO_new(const BIO_METHOD *method) bio->lock = CRYPTO_THREAD_lock_new(); if (bio->lock == NULL) { - BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); goto err; } if (method->create != NULL && !method->create(bio)) { - BIOerr(BIO_F_BIO_NEW, ERR_R_INIT_FAIL); + ERR_raise(ERR_LIB_BIO, ERR_R_INIT_FAIL); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); CRYPTO_THREAD_lock_free(bio->lock); goto err; @@ -107,6 +118,11 @@ BIO *BIO_new(const BIO_METHOD *method) return NULL; } +BIO *BIO_new(const BIO_METHOD *method) +{ + return BIO_new_ex(NULL, method); +} + int BIO_free(BIO *a) { int ret; @@ -122,10 +138,10 @@ int BIO_free(BIO *a) return 1; REF_ASSERT_ISNT(ret < 0); - if (a->callback != NULL || a->callback_ex != NULL) { + if (HAS_CALLBACK(a)) { ret = (int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0, 0L, 1L, NULL); if (ret <= 0) - return ret; + return 0; } if ((a->method != NULL) && (a->method->destroy != NULL)) @@ -184,7 +200,7 @@ int BIO_up_ref(BIO *a) REF_PRINT_COUNT("BIO", a); REF_ASSERT_ISNT(i < 2); - return ((i > 1) ? 1 : 0); + return i > 1; } void BIO_clear_flags(BIO *b, int flags) @@ -202,6 +218,7 @@ void BIO_set_flags(BIO *b, int flags) b->flags |= flags; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 BIO_callback_fn BIO_get_callback(const BIO *b) { return b->callback; @@ -211,6 +228,7 @@ void BIO_set_callback(BIO *b, BIO_callback_fn cb) { b->callback = cb; } +#endif BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b) { @@ -252,19 +270,23 @@ static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes) { int ret; - if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) { - BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNSUPPORTED_METHOD); + if (b == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + if (b->method == NULL || b->method->bread == NULL) { + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); return -2; } - if ((b->callback != NULL || b->callback_ex != NULL) && + if (HAS_CALLBACK(b) && ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L, NULL)) <= 0)) return ret; if (!b->init) { - BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNINITIALIZED); - return -2; + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return -1; } ret = b->method->bread(b, data, dlen, readbytes); @@ -272,13 +294,13 @@ static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes) if (ret > 0) b->num_read += (uint64_t)*readbytes; - if (b->callback != NULL || b->callback_ex != NULL) + if (HAS_CALLBACK(b)) ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, data, dlen, 0, 0L, ret, readbytes); /* Shouldn't happen */ if (ret > 0 && *readbytes > dlen) { - BIOerr(BIO_F_BIO_READ_INTERN, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); return -1; } @@ -305,50 +327,50 @@ int BIO_read(BIO *b, void *data, int dlen) int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes) { - int ret; - - ret = bio_read_intern(b, data, dlen, readbytes); - - if (ret > 0) - ret = 1; - else - ret = 0; - - return ret; + return bio_read_intern(b, data, dlen, readbytes) > 0; } static int bio_write_intern(BIO *b, const void *data, size_t dlen, size_t *written) { + size_t local_written; int ret; + if (written != NULL) + *written = 0; + /* + * b == NULL is not an error but just means that zero bytes are written. + * Do not raise an error here. + */ if (b == NULL) return 0; - if ((b->method == NULL) || (b->method->bwrite == NULL)) { - BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNSUPPORTED_METHOD); + if (b->method == NULL || b->method->bwrite == NULL) { + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); return -2; } - if ((b->callback != NULL || b->callback_ex != NULL) && + if (HAS_CALLBACK(b) && ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, data, dlen, 0, 0L, 1L, NULL)) <= 0)) return ret; if (!b->init) { - BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNINITIALIZED); - return -2; + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return -1; } - ret = b->method->bwrite(b, data, dlen, written); + ret = b->method->bwrite(b, data, dlen, &local_written); if (ret > 0) - b->num_write += (uint64_t)*written; + b->num_write += (uint64_t)local_written; - if (b->callback != NULL || b->callback_ex != NULL) + if (HAS_CALLBACK(b)) ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, data, - dlen, 0, 0L, ret, written); + dlen, 0, 0L, ret, &local_written); + if (written != NULL) + *written = local_written; return ret; } @@ -357,13 +379,13 @@ int BIO_write(BIO *b, const void *data, int dlen) size_t written; int ret; - if (dlen < 0) + if (dlen <= 0) return 0; ret = bio_write_intern(b, data, (size_t)dlen, &written); if (ret > 0) { - /* *written should always be <= dlen */ + /* written should always be <= dlen */ ret = (int)written; } @@ -372,16 +394,8 @@ int BIO_write(BIO *b, const void *data, int dlen) int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written) { - int ret; - - ret = bio_write_intern(b, data, dlen, written); - - if (ret > 0) - ret = 1; - else - ret = 0; - - return ret; + return bio_write_intern(b, data, dlen, written) > 0 + || (b != NULL && dlen == 0); /* order is important for *written */ } int BIO_puts(BIO *b, const char *buf) @@ -389,20 +403,24 @@ int BIO_puts(BIO *b, const char *buf) int ret; size_t written = 0; - if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) { - BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD); + if (b == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + if (b->method == NULL || b->method->bputs == NULL) { + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); return -2; } - if (b->callback != NULL || b->callback_ex != NULL) { + if (HAS_CALLBACK(b)) { ret = (int)bio_call_callback(b, BIO_CB_PUTS, buf, 0, 0, 0L, 1L, NULL); if (ret <= 0) return ret; } if (!b->init) { - BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED); - return -2; + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return -1; } ret = b->method->bputs(b, buf); @@ -413,13 +431,13 @@ int BIO_puts(BIO *b, const char *buf) ret = 1; } - if (b->callback != NULL || b->callback_ex != NULL) + if (HAS_CALLBACK(b)) ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, buf, 0, 0, 0L, ret, &written); if (ret > 0) { if (written > INT_MAX) { - BIOerr(BIO_F_BIO_PUTS, BIO_R_LENGTH_TOO_LONG); + ERR_raise(ERR_LIB_BIO, BIO_R_LENGTH_TOO_LONG); ret = -1; } else { ret = (int)written; @@ -434,25 +452,29 @@ int BIO_gets(BIO *b, char *buf, int size) int ret; size_t readbytes = 0; - if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) { - BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD); + if (b == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + if (b->method == NULL || b->method->bgets == NULL) { + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); return -2; } if (size < 0) { - BIOerr(BIO_F_BIO_GETS, BIO_R_INVALID_ARGUMENT); - return 0; + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT); + return -1; } - if (b->callback != NULL || b->callback_ex != NULL) { + if (HAS_CALLBACK(b)) { ret = (int)bio_call_callback(b, BIO_CB_GETS, buf, size, 0, 0L, 1, NULL); if (ret <= 0) return ret; } if (!b->init) { - BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED); - return -2; + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return -1; } ret = b->method->bgets(b, buf, size); @@ -462,7 +484,7 @@ int BIO_gets(BIO *b, char *buf, int size) ret = 1; } - if (b->callback != NULL || b->callback_ex != NULL) + if (HAS_CALLBACK(b)) ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, buf, size, 0, 0L, ret, &readbytes); @@ -477,6 +499,37 @@ int BIO_gets(BIO *b, char *buf, int size) return ret; } +int BIO_get_line(BIO *bio, char *buf, int size) +{ + int ret = 0; + char *ptr = buf; + + if (buf == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + if (size <= 0) { + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT); + return -1; + } + *buf = '\0'; + + if (bio == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + if (!bio->init) { + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return -1; + } + + while (size-- > 1 && (ret = BIO_read(bio, ptr, 1)) > 0) + if (*ptr++ == '\n') + break; + *ptr = '\0'; + return ret > 0 || BIO_eof(bio) ? ptr - buf : ret; +} + int BIO_indent(BIO *b, int indent, int max) { if (indent < 0) @@ -512,14 +565,13 @@ long BIO_ctrl(BIO *b, int cmd, long larg, void *parg) long ret; if (b == NULL) - return 0; - - if ((b->method == NULL) || (b->method->ctrl == NULL)) { - BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD); + return -1; + if (b->method == NULL || b->method->ctrl == NULL) { + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); return -2; } - if (b->callback != NULL || b->callback_ex != NULL) { + if (HAS_CALLBACK(b)) { ret = bio_call_callback(b, BIO_CB_CTRL, parg, 0, cmd, larg, 1L, NULL); if (ret <= 0) return ret; @@ -527,7 +579,7 @@ long BIO_ctrl(BIO *b, int cmd, long larg, void *parg) ret = b->method->ctrl(b, cmd, larg, parg); - if (b->callback != NULL || b->callback_ex != NULL) + if (HAS_CALLBACK(b)) ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, 0, cmd, larg, ret, NULL); @@ -539,15 +591,14 @@ long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) long ret; if (b == NULL) - return 0; - - if ((b->method == NULL) || (b->method->callback_ctrl == NULL) - || (cmd != BIO_CTRL_SET_CALLBACK)) { - BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD); + return -2; + if (b->method == NULL || b->method->callback_ctrl == NULL + || cmd != BIO_CTRL_SET_CALLBACK) { + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); return -2; } - if (b->callback != NULL || b->callback_ex != NULL) { + if (HAS_CALLBACK(b)) { ret = bio_call_callback(b, BIO_CB_CTRL, (void *)&fp, 0, cmd, 0, 1L, NULL); if (ret <= 0) @@ -556,7 +607,7 @@ long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) ret = b->method->callback_ctrl(b, cmd, fp); - if (b->callback != NULL || b->callback_ex != NULL) + if (HAS_CALLBACK(b)) ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, 0, cmd, 0, ret, NULL); @@ -570,12 +621,28 @@ long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) */ size_t BIO_ctrl_pending(BIO *bio) { - return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); + long ret = BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); + + if (ret < 0) + ret = 0; +#if LONG_MAX > SIZE_MAX + if (ret > SIZE_MAX) + ret = SIZE_MAX; +#endif + return (size_t)ret; } size_t BIO_ctrl_wpending(BIO *bio) { - return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); + long ret = BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); + + if (ret < 0) + ret = 0; +#if LONG_MAX > SIZE_MAX + if (ret > SIZE_MAX) + ret = SIZE_MAX; +#endif + return (size_t)ret; } /* put the 'bio' on the end of b's list of operators */ @@ -649,8 +716,10 @@ BIO *BIO_find_type(BIO *bio, int type) { int mt, mask; - if (bio == NULL) + if (bio == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); return NULL; + } mask = type & 0xff; do { if (bio->method != NULL) { @@ -659,8 +728,9 @@ BIO *BIO_find_type(BIO *bio, int type) if (!mask) { if (mt & type) return bio; - } else if (mt == type) + } else if (mt == type) { return bio; + } } bio = bio->next_bio; } while (bio != NULL); @@ -702,7 +772,9 @@ BIO *BIO_dup_chain(BIO *in) for (bio = in; bio != NULL; bio = bio->next_bio) { if ((new_bio = BIO_new(bio->method)) == NULL) goto err; +#ifndef OPENSSL_NO_DEPRECATED_3_0 new_bio->callback = bio->callback; +#endif new_bio->callback_ex = bio->callback_ex; new_bio->cb_arg = bio->cb_arg; new_bio->init = bio->init; @@ -750,7 +822,7 @@ int BIO_set_ex_data(BIO *bio, int idx, void *data) return CRYPTO_set_ex_data(&(bio->ex_data), idx, data); } -void *BIO_get_ex_data(BIO *bio, int idx) +void *BIO_get_ex_data(const BIO *bio, int idx) { return CRYPTO_get_ex_data(&(bio->ex_data), idx); } @@ -784,3 +856,127 @@ void bio_cleanup(void) CRYPTO_THREAD_lock_free(bio_type_lock); bio_type_lock = NULL; } + +/* Internal variant of the below BIO_wait() not calling BIOerr() */ +static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds) +{ +#ifndef OPENSSL_NO_SOCK + int fd; +#endif + long sec_diff; + + if (max_time == 0) /* no timeout */ + return 1; + +#ifndef OPENSSL_NO_SOCK + if (BIO_get_fd(bio, &fd) > 0 && fd < FD_SETSIZE) + return BIO_socket_wait(fd, BIO_should_read(bio), max_time); +#endif + /* fall back to polling since no sockets are available */ + + sec_diff = (long)(max_time - time(NULL)); /* might overflow */ + if (sec_diff < 0) + return 0; /* clearly timeout */ + + /* now take a nap at most the given number of milliseconds */ + if (sec_diff == 0) { /* we are below the 1 seconds resolution of max_time */ + if (nap_milliseconds > 1000) + nap_milliseconds = 1000; + } else { /* for sec_diff > 0, take min(sec_diff * 1000, nap_milliseconds) */ + if ((unsigned long)sec_diff * 1000 < nap_milliseconds) + nap_milliseconds = (unsigned int)sec_diff * 1000; + } + ossl_sleep(nap_milliseconds); + return 1; +} + +/*- + * Wait on (typically socket-based) BIO at most until max_time. + * Succeed immediately if max_time == 0. + * If sockets are not available support polling: succeed after waiting at most + * the number of nap_milliseconds in order to avoid a tight busy loop. + * Call BIOerr(...) on timeout or error. + * Returns -1 on error, 0 on timeout, and 1 on success. + */ +int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds) +{ + int rv = bio_wait(bio, max_time, nap_milliseconds); + + if (rv <= 0) + ERR_raise(ERR_LIB_BIO, + rv == 0 ? BIO_R_TRANSFER_TIMEOUT : BIO_R_TRANSFER_ERROR); + return rv; +} + +/* + * Connect via given BIO using BIO_do_connect() until success/timeout/error. + * Parameter timeout == 0 means no timeout, < 0 means exactly one try. + * For non-blocking and potentially even non-socket BIOs perform polling with + * the given density: between polls sleep nap_milliseconds using BIO_wait() + * in order to avoid a tight busy loop. + * Returns -1 on error, 0 on timeout, and 1 on success. + */ +int BIO_do_connect_retry(BIO *bio, int timeout, int nap_milliseconds) +{ + int blocking = timeout <= 0; + time_t max_time = timeout > 0 ? time(NULL) + timeout : 0; + int rv; + + if (bio == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + if (nap_milliseconds < 0) + nap_milliseconds = 100; + BIO_set_nbio(bio, !blocking); + + retry: + ERR_set_mark(); + rv = BIO_do_connect(bio); + + if (rv <= 0) { /* could be timeout or retryable error or fatal error */ + int err = ERR_peek_last_error(); + int reason = ERR_GET_REASON(err); + int do_retry = BIO_should_retry(bio); /* may be 1 only if !blocking */ + + if (ERR_GET_LIB(err) == ERR_LIB_BIO) { + switch (reason) { + case ERR_R_SYS_LIB: + /* + * likely retryable system error occurred, which may be + * EAGAIN (resource temporarily unavailable) some 40 secs after + * calling getaddrinfo(): Temporary failure in name resolution + * or a premature ETIMEDOUT, some 30 seconds after connect() + */ + case BIO_R_CONNECT_ERROR: + case BIO_R_NBIO_CONNECT_ERROR: + /* some likely retryable connection error occurred */ + (void)BIO_reset(bio); /* often needed to avoid retry failure */ + do_retry = 1; + break; + default: + break; + } + } + if (timeout >= 0 && do_retry) { + ERR_pop_to_mark(); + /* will not actually wait if timeout == 0 (i.e., blocking BIO): */ + rv = bio_wait(bio, max_time, nap_milliseconds); + if (rv > 0) + goto retry; + ERR_raise(ERR_LIB_BIO, + rv == 0 ? BIO_R_CONNECT_TIMEOUT : BIO_R_CONNECT_ERROR); + } else { + ERR_clear_last_mark(); + rv = -1; + if (err == 0) /* missing error queue entry */ + /* workaround: general error */ + ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR); + } + } else { + ERR_clear_last_mark(); + } + + return rv; +} diff --git a/crypto/openssl/crypto/bio/bio_local.h b/crypto/openssl/crypto/bio/bio_local.h index 8b2122129396..749e8f810c30 100644 --- a/crypto/openssl/crypto/bio/bio_local.h +++ b/crypto/openssl/crypto/bio/bio_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,7 +9,6 @@ #include "e_os.h" #include "internal/sockets.h" -#include "internal/refcount.h" /* BEGIN BIO_ADDRINFO/BIO_ADDR stuff. */ @@ -30,7 +29,7 @@ # ifdef OSSL_INTERNAL_CRYPTLIB_H # error internal/cryptlib.h included before bio_local.h # endif -# ifdef HEADER_BIO_H +# ifdef OPENSSL_BIO_H # error openssl/bio.h included before bio_local.h # endif @@ -88,6 +87,7 @@ union bio_addr_st { #include "internal/cryptlib.h" #include "internal/bio.h" +#include "internal/refcount.h" typedef struct bio_f_buffer_ctx_struct { /*- @@ -113,9 +113,12 @@ typedef struct bio_f_buffer_ctx_struct { } BIO_F_BUFFER_CTX; struct bio_st { + OSSL_LIB_CTX *libctx; const BIO_METHOD *method; /* bio, mode, argp, argi, argl, ret */ +#ifndef OPENSSL_NO_DEPRECATED_3_0 BIO_callback_fn callback; +#endif BIO_callback_fn_ex callback_ex; char *cb_arg; /* first argument for the callback */ int init; @@ -152,7 +155,7 @@ extern CRYPTO_RWLOCK *bio_type_lock; void bio_sock_cleanup_int(void); -#if BIO_FLAGS_UPLINK==0 +#if BIO_FLAGS_UPLINK_INTERNAL==0 /* Shortcut UPLINK calls on most platforms... */ # define UP_stdin stdin # define UP_stdout stdout diff --git a/crypto/openssl/crypto/bio/bio_meth.c b/crypto/openssl/crypto/bio/bio_meth.c index da116461922e..469715ba09eb 100644 --- a/crypto/openssl/crypto/bio/bio_meth.c +++ b/crypto/openssl/crypto/bio/bio_meth.c @@ -1,7 +1,7 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -25,7 +25,7 @@ int BIO_get_new_index(void) int newval; if (!RUN_ONCE(&bio_type_init, do_bio_type_init)) { - BIOerr(BIO_F_BIO_GET_NEW_INDEX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return -1; } if (!CRYPTO_UP_REF(&bio_count, &newval, bio_type_lock)) @@ -40,7 +40,7 @@ BIO_METHOD *BIO_meth_new(int type, const char *name) if (biom == NULL || (biom->name = OPENSSL_strdup(name)) == NULL) { OPENSSL_free(biom); - BIOerr(BIO_F_BIO_METH_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return NULL; } biom->type = type; diff --git a/crypto/openssl/crypto/bio/b_print.c b/crypto/openssl/crypto/bio/bio_print.c similarity index 97% rename from crypto/openssl/crypto/bio/b_print.c rename to crypto/openssl/crypto/bio/bio_print.c index 45d4e9f004b1..4c9c3af7cfd6 100644 --- a/crypto/openssl/crypto/bio/b_print.c +++ b/crypto/openssl/crypto/bio/bio_print.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,7 +13,7 @@ #include "crypto/ctype.h" #include "internal/numbers.h" #include -#include +#include /* * Copyright Patrick Powell 1995 @@ -344,7 +344,7 @@ _dopr(char **sbuffer, break; case 'w': /* not supported yet, treat as next char */ - ch = *format++; + format++; break; default: /* unknown, skip */ @@ -638,6 +638,7 @@ fmtfp(char **sbuffer, /* * Should not happen. If we're in F_FORMAT then exp < max? */ + (void)doapr_outch(sbuffer, buffer, currlen, maxlen, '\0'); return 0; } } else { @@ -659,6 +660,7 @@ fmtfp(char **sbuffer, */ if (ufvalue >= (double)(ULONG_MAX - 65535) + 65536.0) { /* Number too big */ + (void)doapr_outch(sbuffer, buffer, currlen, maxlen, '\0'); return 0; } intpart = (unsigned long)ufvalue; @@ -722,8 +724,10 @@ fmtfp(char **sbuffer, tmpexp = (tmpexp / 10); } while (tmpexp > 0 && eplace < (int)sizeof(econvert)); /* Exponent is huge!! Too big to print */ - if (tmpexp > 0) + if (tmpexp > 0) { + (void)doapr_outch(sbuffer, buffer, currlen, maxlen, '\0'); return 0; + } /* Add a leading 0 for single digit exponents */ if (eplace == 1) econvert[eplace++] = '0'; @@ -844,7 +848,7 @@ doapr_outch(char **sbuffer, *maxlen += BUFFER_INC; if (*buffer == NULL) { if ((*buffer = OPENSSL_malloc(*maxlen)) == NULL) { - BIOerr(BIO_F_DOAPR_OUTCH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } if (*currlen > 0) { @@ -855,9 +859,12 @@ doapr_outch(char **sbuffer, *sbuffer = NULL; } else { char *tmpbuf; + tmpbuf = OPENSSL_realloc(*buffer, *maxlen); - if (tmpbuf == NULL) + if (tmpbuf == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; + } *buffer = tmpbuf; } } @@ -949,6 +956,5 @@ int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) * been large enough.) */ return -1; - else - return (retlen <= INT_MAX) ? (int)retlen : -1; + return (retlen <= INT_MAX) ? (int)retlen : -1; } diff --git a/crypto/openssl/crypto/bio/b_sock.c b/crypto/openssl/crypto/bio/bio_sock.c similarity index 75% rename from crypto/openssl/crypto/bio/b_sock.c rename to crypto/openssl/crypto/bio/bio_sock.c index df431e6d523d..476cbcc5cef1 100644 --- a/crypto/openssl/crypto/bio/b_sock.c +++ b/crypto/openssl/crypto/bio/bio_sock.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,7 +9,6 @@ #include #include -#include #include "bio_local.h" #ifndef OPENSSL_NO_SOCK # define SOCKET_PROTOCOL IPPROTO_TCP @@ -24,7 +23,26 @@ static int wsa_init_done = 0; # endif -# if OPENSSL_API_COMPAT < 0x10100000L +# if defined __TANDEM +# include +# include /* select */ +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +# elif defined _WIN32 +# include /* for type fd_set */ +# else +# include +# if defined __VMS +# include +# elif defined _HPUX_SOURCE +# include +# else +# include +# endif +# endif + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 int BIO_get_host_ip(const char *str, unsigned char *ip) { BIO_ADDRINFO *res = NULL; @@ -37,8 +55,7 @@ int BIO_get_host_ip(const char *str, unsigned char *ip) size_t l; if (BIO_ADDRINFO_family(res) != AF_INET) { - BIOerr(BIO_F_BIO_GET_HOST_IP, - BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET); + ERR_raise(ERR_LIB_BIO, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET); } else if (BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), NULL, &l)) { /* * Because only AF_INET addresses will reach this far, we can assert @@ -61,7 +78,7 @@ int BIO_get_port(const char *str, unsigned short *port_ptr) int ret = 0; if (str == NULL) { - BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED); + ERR_raise(ERR_LIB_BIO, BIO_R_NO_PORT_DEFINED); return 0; } @@ -70,8 +87,7 @@ int BIO_get_port(const char *str, unsigned short *port_ptr) if (BIO_lookup(NULL, str, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) { if (BIO_ADDRINFO_family(res) != AF_INET) { - BIOerr(BIO_F_BIO_GET_PORT, - BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET); + ERR_raise(ERR_LIB_BIO, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET); } else { *port_ptr = ntohs(BIO_ADDR_rawport(BIO_ADDRINFO_address(res))); ret = 1; @@ -103,7 +119,7 @@ int BIO_sock_error(int sock) return j; } -# if OPENSSL_API_COMPAT < 0x10100000L +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 struct hostent *BIO_gethostbyname(const char *name) { /* @@ -120,8 +136,6 @@ int BIO_sock_init(void) static struct WSAData wsa_state; if (!wsa_init_done) { - int err; - wsa_init_done = 1; memset(&wsa_state, 0, sizeof(wsa_state)); /* @@ -131,9 +145,9 @@ int BIO_sock_init(void) * probed at run-time with DSO_global_lookup. */ if (WSAStartup(0x0202, &wsa_state) != 0) { - err = WSAGetLastError(); - SYSerr(SYS_F_WSASTARTUP, err); - BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling wsastartup()"); + ERR_raise(ERR_LIB_BIO, BIO_R_WSASTARTUP); return -1; } } @@ -192,11 +206,12 @@ int BIO_socket_ioctl(int fd, long type, void *arg) i = ioctlsocket(fd, type, ARG); # endif /* __DJGPP__ */ if (i < 0) - SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling ioctlsocket()"); return i; } -# if OPENSSL_API_COMPAT < 0x10100000L +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 int BIO_get_accept_socket(char *host, int bind_mode) { int s = INVALID_SOCKET; @@ -243,8 +258,9 @@ int BIO_accept(int sock, char **ip_port) ret = -2; goto end; } - SYSerr(SYS_F_ACCEPT, get_last_socket_error()); - BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling accept()"); + ERR_raise(ERR_LIB_BIO, BIO_R_ACCEPT_ERROR); goto end; } @@ -257,7 +273,7 @@ int BIO_accept(int sock, char **ip_port) *ip_port = NULL; if (*ip_port == NULL) { - BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); BIO_closesocket(ret); ret = (int)INVALID_SOCKET; } else { @@ -308,7 +324,8 @@ int BIO_socket_nbio(int s, int mode) l = fcntl(s, F_GETFL, 0); if (l == -1) { - SYSerr(SYS_F_FCNTL, get_last_sys_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fcntl()"); ret = -1; } else { # if defined(O_NONBLOCK) @@ -326,12 +343,13 @@ int BIO_socket_nbio(int s, int mode) ret = fcntl(s, F_SETFL, l); if (ret < 0) { - SYSerr(SYS_F_FCNTL, get_last_sys_error()); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fcntl()"); } } # else /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */ - BIOerr(BIO_F_BIO_SOCKET_NBIO, ERR_R_PASSED_INVALID_ARGUMENT); + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_INVALID_ARGUMENT); # endif return (ret == 0); @@ -349,21 +367,49 @@ int BIO_sock_info(int sock, ret = getsockname(sock, BIO_ADDR_sockaddr_noconst(info->addr), &addr_len); if (ret == -1) { - SYSerr(SYS_F_GETSOCKNAME, get_last_socket_error()); - BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_ERROR); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getsockname()"); + ERR_raise(ERR_LIB_BIO, BIO_R_GETSOCKNAME_ERROR); return 0; } if ((size_t)addr_len > sizeof(*info->addr)) { - BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS); + ERR_raise(ERR_LIB_BIO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS); return 0; } } break; default: - BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_UNKNOWN_INFO_TYPE); + ERR_raise(ERR_LIB_BIO, BIO_R_UNKNOWN_INFO_TYPE); return 0; } return 1; } -#endif +/* + * Wait on fd at most until max_time; succeed immediately if max_time == 0. + * If for_read == 0 then assume to wait for writing, else wait for reading. + * Returns -1 on error, 0 on timeout, and 1 on success. + */ +int BIO_socket_wait(int fd, int for_read, time_t max_time) +{ + fd_set confds; + struct timeval tv; + time_t now; + + if (fd < 0 || fd >= FD_SETSIZE) + return -1; + if (max_time == 0) + return 1; + + now = time(NULL); + if (max_time < now) + return 0; + + FD_ZERO(&confds); + openssl_fdset(fd, &confds); + tv.tv_usec = 0; + tv.tv_sec = (long)(max_time - now); /* might overflow */ + return select(fd + 1, for_read ? &confds : NULL, + for_read ? NULL : &confds, NULL, &tv); +} +#endif /* !defined(OPENSSL_NO_SOCK) */ diff --git a/crypto/openssl/crypto/bio/b_sock2.c b/crypto/openssl/crypto/bio/bio_sock2.c similarity index 75% rename from crypto/openssl/crypto/bio/b_sock2.c rename to crypto/openssl/crypto/bio/bio_sock2.c index 771729880e4a..8bdad0c0b6ae 100644 --- a/crypto/openssl/crypto/bio/b_sock2.c +++ b/crypto/openssl/crypto/bio/bio_sock2.c @@ -1,7 +1,7 @@ /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -47,21 +47,11 @@ int BIO_socket(int domain, int socktype, int protocol, int options) sock = socket(domain, socktype, protocol); if (sock == -1) { - SYSerr(SYS_F_SOCKET, get_last_socket_error()); - BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling socket()"); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET); return INVALID_SOCKET; } -# ifndef OPENSSL_NO_KTLS - { - /* - * The new socket is created successfully regardless of ktls_enable. - * ktls_enable doesn't change any functionality of the socket, except - * changing the setsockopt to enable the processing of ktls_start. - * Thus, it is not a problem to call it for non-TLS sockets. - */ - ktls_enable(sock); - } -# endif return sock; } @@ -91,7 +81,7 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options) const int on = 1; if (sock == -1) { - BIOerr(BIO_F_BIO_CONNECT, BIO_R_INVALID_SOCKET); + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_SOCKET); return 0; } @@ -101,8 +91,9 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options) if (options & BIO_SOCK_KEEPALIVE) { if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); - BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_KEEPALIVE); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_KEEPALIVE); return 0; } } @@ -110,8 +101,9 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options) if (options & BIO_SOCK_NODELAY) { if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); - BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_NODELAY); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_NODELAY); return 0; } } @@ -119,11 +111,21 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options) if (connect(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) == -1) { if (!BIO_sock_should_retry(-1)) { - SYSerr(SYS_F_CONNECT, get_last_socket_error()); - BIOerr(BIO_F_BIO_CONNECT, BIO_R_CONNECT_ERROR); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling connect()"); + ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR); } return 0; } +# ifndef OPENSSL_NO_KTLS + /* + * The new socket is created successfully regardless of ktls_enable. + * ktls_enable doesn't change any functionality of the socket, except + * changing the setsockopt to enable the processing of ktls_start. + * Thus, it is not a problem to call it for non-TLS sockets. + */ + ktls_enable(sock); +# endif return 1; } @@ -150,7 +152,7 @@ int BIO_bind(int sock, const BIO_ADDR *addr, int options) # endif if (sock == -1) { - BIOerr(BIO_F_BIO_BIND, BIO_R_INVALID_SOCKET); + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_SOCKET); return 0; } @@ -162,16 +164,18 @@ int BIO_bind(int sock, const BIO_ADDR *addr, int options) if (options & BIO_SOCK_REUSEADDR) { if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); - BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_REUSEADDR); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_REUSEADDR); return 0; } } # endif if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) { - SYSerr(SYS_F_BIND, get_last_socket_error()); - BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_BIND_SOCKET); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error() /* may be 0 */, + "calling bind()"); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_BIND_SOCKET); return 0; } @@ -222,15 +226,16 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) socklen_t socktype_len = sizeof(socktype); if (sock == -1) { - BIOerr(BIO_F_BIO_LISTEN, BIO_R_INVALID_SOCKET); + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_SOCKET); return 0; } if (getsockopt(sock, SOL_SOCKET, SO_TYPE, (void *)&socktype, &socktype_len) != 0 || socktype_len != sizeof(socktype)) { - SYSerr(SYS_F_GETSOCKOPT, get_last_socket_error()); - BIOerr(BIO_F_BIO_LISTEN, BIO_R_GETTING_SOCKTYPE); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getsockopt()"); + ERR_raise(ERR_LIB_BIO, BIO_R_GETTING_SOCKTYPE); return 0; } @@ -240,8 +245,9 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) if (options & BIO_SOCK_KEEPALIVE) { if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); - BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_KEEPALIVE); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_KEEPALIVE); return 0; } } @@ -249,8 +255,9 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) if (options & BIO_SOCK_NODELAY) { if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); - BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_NODELAY); return 0; } } @@ -265,8 +272,9 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) on = options & BIO_SOCK_V6_ONLY ? 1 : 0; if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const void *)&on, sizeof(on)) != 0) { - SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error()); - BIOerr(BIO_F_BIO_LISTEN, BIO_R_LISTEN_V6_ONLY); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); + ERR_raise(ERR_LIB_BIO, BIO_R_LISTEN_V6_ONLY); return 0; } } @@ -276,8 +284,9 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) return 0; if (socktype != SOCK_DGRAM && listen(sock, MAX_LISTEN) == -1) { - SYSerr(SYS_F_LISTEN, get_last_socket_error()); - BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_LISTEN_SOCKET); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling listen()"); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_LISTEN_SOCKET); return 0; } @@ -303,8 +312,9 @@ int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options) BIO_ADDR_sockaddr_noconst(addr), &len); if (accepted_sock == -1) { if (!BIO_sock_should_retry(accepted_sock)) { - SYSerr(SYS_F_ACCEPT, get_last_socket_error()); - BIOerr(BIO_F_BIO_ACCEPT_EX, BIO_R_ACCEPT_ERROR); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling accept()"); + ERR_raise(ERR_LIB_BIO, BIO_R_ACCEPT_ERROR); } return INVALID_SOCKET; } @@ -323,7 +333,7 @@ int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options) */ int BIO_closesocket(int sock) { - if (closesocket(sock) < 0) + if (sock < 0 || closesocket(sock) < 0) return 0; return 1; } diff --git a/crypto/openssl/crypto/bio/bss_acpt.c b/crypto/openssl/crypto/bio/bss_acpt.c index 4461eae2333d..1cda96733548 100644 --- a/crypto/openssl/crypto/bio/bss_acpt.c +++ b/crypto/openssl/crypto/bio/bss_acpt.c @@ -1,12 +1,14 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include "bio_local.h" @@ -54,10 +56,8 @@ static void BIO_ACCEPT_free(BIO_ACCEPT *a); static const BIO_METHOD methods_acceptp = { BIO_TYPE_ACCEPT, "socket accept", - /* TODO: Convert to new style write function */ bwrite_conv, acpt_write, - /* TODO: Convert to new style read function */ bread_conv, acpt_read, acpt_puts, @@ -93,7 +93,7 @@ static BIO_ACCEPT *BIO_ACCEPT_new(void) BIO_ACCEPT *ret; if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - BIOerr(BIO_F_BIO_ACCEPT_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return NULL; } ret->accept_family = BIO_FAMILY_IPANY; @@ -156,10 +156,10 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c) switch (c->state) { case ACPT_S_BEFORE: if (c->param_addr == NULL && c->param_serv == NULL) { - BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED); - ERR_add_error_data(4, - "hostname=", c->param_addr, - " service=", c->param_serv); + ERR_raise_data(ERR_LIB_BIO, + BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED, + "hostname=%s, service=%s", + c->param_addr, c->param_serv); goto exit_loop; } @@ -192,7 +192,7 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c) family = AF_INET6; } else { #endif - BIOerr(BIO_F_ACPT_STATE, BIO_R_UNAVAILABLE_IP_FAMILY); + ERR_raise(ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY); goto exit_loop; } break; @@ -203,7 +203,7 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c) family = AF_UNSPEC; break; default: - BIOerr(BIO_F_ACPT_STATE, BIO_R_UNSUPPORTED_IP_FAMILY); + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY); goto exit_loop; } if (BIO_lookup(c->param_addr, c->param_serv, BIO_LOOKUP_SERVER, @@ -211,26 +211,31 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c) goto exit_loop; } if (c->addr_first == NULL) { - BIOerr(BIO_F_ACPT_STATE, BIO_R_LOOKUP_RETURNED_NOTHING); + ERR_raise(ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING); goto exit_loop; } - /* We're currently not iterating, but set this as preparation - * for possible future development in that regard - */ c->addr_iter = c->addr_first; c->state = ACPT_S_CREATE_SOCKET; break; case ACPT_S_CREATE_SOCKET: + ERR_set_mark(); s = BIO_socket(BIO_ADDRINFO_family(c->addr_iter), BIO_ADDRINFO_socktype(c->addr_iter), BIO_ADDRINFO_protocol(c->addr_iter), 0); if (s == (int)INVALID_SOCKET) { - SYSerr(SYS_F_SOCKET, get_last_socket_error()); - ERR_add_error_data(4, - "hostname=", c->param_addr, - " service=", c->param_serv); - BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET); + if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) != NULL) { + /* + * if there are more addresses to try, do that first + */ + ERR_pop_to_mark(); + break; + } + ERR_clear_last_mark(); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling socket(%s, %s)", + c->param_addr, c->param_serv); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET); goto exit_loop; } c->accept_sock = s; @@ -306,9 +311,11 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c) if (bio == NULL) goto exit_loop; + BIO_set_callback_ex(bio, BIO_get_callback_ex(b)); +#ifndef OPENSSL_NO_DEPRECATED_3_0 BIO_set_callback(bio, BIO_get_callback(b)); +#endif BIO_set_callback_arg(bio, BIO_get_callback_arg(b)); - /* * If the accept BIO has an bio_chain, we dup it and put the new * socket at the end. diff --git a/crypto/openssl/crypto/bio/bss_bio.c b/crypto/openssl/crypto/bio/bss_bio.c index c97349e43282..7fa8778cae10 100644 --- a/crypto/openssl/crypto/bio/bss_bio.c +++ b/crypto/openssl/crypto/bio/bss_bio.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -38,10 +38,8 @@ static void bio_destroy_pair(BIO *bio); static const BIO_METHOD methods_biop = { BIO_TYPE_BIO, "BIO pair", - /* TODO: Convert to new style write function */ bwrite_conv, bio_write, - /* TODO: Convert to new style read function */ bread_conv, bio_read, bio_puts, @@ -286,7 +284,7 @@ static int bio_write(BIO *bio, const char *buf, int num_) b->request = 0; if (b->closed) { /* we already closed */ - BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE); + ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE); return -1; } @@ -362,7 +360,7 @@ static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf) b->request = 0; if (b->closed) { - BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); + ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE); return -1; } @@ -427,10 +425,10 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) case BIO_C_SET_WRITE_BUF_SIZE: if (b->peer) { - BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE); + ERR_raise(ERR_LIB_BIO, BIO_R_IN_USE); ret = 0; } else if (num == 0) { - BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT); + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT); ret = 0; } else { size_t new_size = num; @@ -616,14 +614,14 @@ static int bio_make_pair(BIO *bio1, BIO *bio2) b2 = bio2->ptr; if (b1->peer != NULL || b2->peer != NULL) { - BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); + ERR_raise(ERR_LIB_BIO, BIO_R_IN_USE); return 0; } if (b1->buf == NULL) { b1->buf = OPENSSL_malloc(b1->size); if (b1->buf == NULL) { - BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } b1->len = 0; @@ -633,7 +631,7 @@ static int bio_make_pair(BIO *bio1, BIO *bio2) if (b2->buf == NULL) { b2->buf = OPENSSL_malloc(b2->size); if (b2->buf == NULL) { - BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } b2->len = 0; @@ -750,7 +748,7 @@ int BIO_nread0(BIO *bio, char **buf) long ret; if (!bio->init) { - BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); return -2; } @@ -766,7 +764,7 @@ int BIO_nread(BIO *bio, char **buf, int num) int ret; if (!bio->init) { - BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); return -2; } @@ -781,7 +779,7 @@ int BIO_nwrite0(BIO *bio, char **buf) long ret; if (!bio->init) { - BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); return -2; } @@ -797,7 +795,7 @@ int BIO_nwrite(BIO *bio, char **buf, int num) int ret; if (!bio->init) { - BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); return -2; } diff --git a/crypto/openssl/crypto/bio/bss_conn.c b/crypto/openssl/crypto/bio/bss_conn.c index 10cf20871cb0..0d91f25fe70e 100644 --- a/crypto/openssl/crypto/bio/bss_conn.c +++ b/crypto/openssl/crypto/bio/bss_conn.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -63,10 +63,8 @@ void BIO_CONNECT_free(BIO_CONNECT *a); static const BIO_METHOD methods_connectp = { BIO_TYPE_CONNECT, "socket connect", - /* TODO: Convert to new style write function */ bwrite_conv, conn_write, - /* TODO: Convert to new style read function */ bread_conv, conn_read, conn_puts, @@ -89,10 +87,10 @@ static int conn_state(BIO *b, BIO_CONNECT *c) switch (c->state) { case BIO_CONN_S_BEFORE: if (c->param_hostname == NULL && c->param_service == NULL) { - BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED); - ERR_add_error_data(4, - "hostname=", c->param_hostname, - " service=", c->param_service); + ERR_raise_data(ERR_LIB_BIO, + BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED, + "hostname=%s service=%s", + c->param_hostname, c->param_service); goto exit_loop; } c->state = BIO_CONN_S_GET_ADDR; @@ -111,7 +109,7 @@ static int conn_state(BIO *b, BIO_CONNECT *c) family = AF_INET6; } else { #endif - BIOerr(BIO_F_CONN_STATE, BIO_R_UNAVAILABLE_IP_FAMILY); + ERR_raise(ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY); goto exit_loop; } break; @@ -122,7 +120,7 @@ static int conn_state(BIO *b, BIO_CONNECT *c) family = AF_UNSPEC; break; default: - BIOerr(BIO_F_CONN_STATE, BIO_R_UNSUPPORTED_IP_FAMILY); + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY); goto exit_loop; } if (BIO_lookup(c->param_hostname, c->param_service, @@ -131,7 +129,7 @@ static int conn_state(BIO *b, BIO_CONNECT *c) goto exit_loop; } if (c->addr_first == NULL) { - BIOerr(BIO_F_CONN_STATE, BIO_R_LOOKUP_RETURNED_NOTHING); + ERR_raise(ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING); goto exit_loop; } c->addr_iter = c->addr_first; @@ -143,11 +141,10 @@ static int conn_state(BIO *b, BIO_CONNECT *c) BIO_ADDRINFO_socktype(c->addr_iter), BIO_ADDRINFO_protocol(c->addr_iter), 0); if (ret == (int)INVALID_SOCKET) { - SYSerr(SYS_F_SOCKET, get_last_socket_error()); - ERR_add_error_data(4, - "hostname=", c->param_hostname, - " service=", c->param_service); - BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling socket(%s, %s)", + c->param_hostname, c->param_service); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET); goto exit_loop; } b->num = ret; @@ -156,6 +153,7 @@ static int conn_state(BIO *b, BIO_CONNECT *c) case BIO_CONN_S_CONNECT: BIO_clear_retry_flags(b); + ERR_set_mark(); ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter), BIO_SOCK_KEEPALIVE | c->connect_mode); b->retry_reason = 0; @@ -164,7 +162,7 @@ static int conn_state(BIO *b, BIO_CONNECT *c) BIO_set_retry_special(b); c->state = BIO_CONN_S_BLOCKED_CONNECT; b->retry_reason = BIO_RR_CONNECT; - ERR_clear_error(); + ERR_pop_to_mark(); } else if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) != NULL) { /* @@ -172,23 +170,27 @@ static int conn_state(BIO *b, BIO_CONNECT *c) */ BIO_closesocket(b->num); c->state = BIO_CONN_S_CREATE_SOCKET; - ERR_clear_error(); + ERR_pop_to_mark(); break; } else { - SYSerr(SYS_F_CONNECT, get_last_socket_error()); - ERR_add_error_data(4, - "hostname=", c->param_hostname, - " service=", c->param_service); + ERR_clear_last_mark(); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling connect(%s, %s)", + c->param_hostname, c->param_service); c->state = BIO_CONN_S_CONNECT_ERROR; break; } goto exit_loop; } else { + ERR_clear_last_mark(); c->state = BIO_CONN_S_OK; } break; case BIO_CONN_S_BLOCKED_CONNECT: + /* wait for socket being writable, before querying BIO_sock_error */ + if (BIO_socket_wait(b->num, 0, time(NULL)) == 0) + break; i = BIO_sock_error(b->num); if (i != 0) { BIO_clear_retry_flags(b); @@ -198,22 +200,30 @@ static int conn_state(BIO *b, BIO_CONNECT *c) */ BIO_closesocket(b->num); c->state = BIO_CONN_S_CREATE_SOCKET; - ERR_clear_error(); break; } - SYSerr(SYS_F_CONNECT, i); - ERR_add_error_data(4, - "hostname=", c->param_hostname, - " service=", c->param_service); - BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR); + ERR_raise_data(ERR_LIB_SYS, i, + "calling connect(%s, %s)", + c->param_hostname, c->param_service); + ERR_raise(ERR_LIB_BIO, BIO_R_NBIO_CONNECT_ERROR); ret = 0; goto exit_loop; - } else + } else { c->state = BIO_CONN_S_OK; +# ifndef OPENSSL_NO_KTLS + /* + * The new socket is created successfully regardless of ktls_enable. + * ktls_enable doesn't change any functionality of the socket, except + * changing the setsockopt to enable the processing of ktls_start. + * Thus, it is not a problem to call it for non-TLS sockets. + */ + ktls_enable(b->num); +# endif + } break; case BIO_CONN_S_CONNECT_ERROR: - BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR); + ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR); ret = 0; goto exit_loop; @@ -244,7 +254,7 @@ BIO_CONNECT *BIO_CONNECT_new(void) BIO_CONNECT *ret; if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - BIOerr(BIO_F_BIO_CONNECT_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return NULL; } ret->state = BIO_CONN_S_BEFORE; diff --git a/crypto/openssl/crypto/bio/bss_core.c b/crypto/openssl/crypto/bio/bss_core.c new file mode 100644 index 000000000000..7a84b20460c8 --- /dev/null +++ b/crypto/openssl/crypto/bio/bss_core.c @@ -0,0 +1,194 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "bio_local.h" +#include "internal/cryptlib.h" + +typedef struct { + OSSL_FUNC_BIO_read_ex_fn *c_bio_read_ex; + OSSL_FUNC_BIO_write_ex_fn *c_bio_write_ex; + OSSL_FUNC_BIO_gets_fn *c_bio_gets; + OSSL_FUNC_BIO_puts_fn *c_bio_puts; + OSSL_FUNC_BIO_ctrl_fn *c_bio_ctrl; + OSSL_FUNC_BIO_up_ref_fn *c_bio_up_ref; + OSSL_FUNC_BIO_free_fn *c_bio_free; +} BIO_CORE_GLOBALS; + +static void bio_core_globals_free(void *vbcg) +{ + OPENSSL_free(vbcg); +} + +static void *bio_core_globals_new(OSSL_LIB_CTX *ctx) +{ + return OPENSSL_zalloc(sizeof(BIO_CORE_GLOBALS)); +} + +static const OSSL_LIB_CTX_METHOD bio_core_globals_method = { + OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, + bio_core_globals_new, + bio_core_globals_free, +}; + +static ossl_inline BIO_CORE_GLOBALS *get_globals(OSSL_LIB_CTX *libctx) +{ + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_BIO_CORE_INDEX, + &bio_core_globals_method); +} + +static int bio_core_read_ex(BIO *bio, char *data, size_t data_len, + size_t *bytes_read) +{ + BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx); + + if (bcgbl == NULL || bcgbl->c_bio_read_ex == NULL) + return 0; + return bcgbl->c_bio_read_ex(BIO_get_data(bio), data, data_len, bytes_read); +} + +static int bio_core_write_ex(BIO *bio, const char *data, size_t data_len, + size_t *written) +{ + BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx); + + if (bcgbl == NULL || bcgbl->c_bio_write_ex == NULL) + return 0; + return bcgbl->c_bio_write_ex(BIO_get_data(bio), data, data_len, written); +} + +static long bio_core_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx); + + if (bcgbl == NULL || bcgbl->c_bio_ctrl == NULL) + return -1; + return bcgbl->c_bio_ctrl(BIO_get_data(bio), cmd, num, ptr); +} + +static int bio_core_gets(BIO *bio, char *buf, int size) +{ + BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx); + + if (bcgbl == NULL || bcgbl->c_bio_gets == NULL) + return -1; + return bcgbl->c_bio_gets(BIO_get_data(bio), buf, size); +} + +static int bio_core_puts(BIO *bio, const char *str) +{ + BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx); + + if (bcgbl == NULL || bcgbl->c_bio_puts == NULL) + return -1; + return bcgbl->c_bio_puts(BIO_get_data(bio), str); +} + +static int bio_core_new(BIO *bio) +{ + BIO_set_init(bio, 1); + + return 1; +} + +static int bio_core_free(BIO *bio) +{ + BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx); + + if (bcgbl == NULL) + return 0; + + BIO_set_init(bio, 0); + bcgbl->c_bio_free(BIO_get_data(bio)); + + return 1; +} + +static const BIO_METHOD corebiometh = { + BIO_TYPE_CORE_TO_PROV, + "BIO to Core filter", + bio_core_write_ex, + NULL, + bio_core_read_ex, + NULL, + bio_core_puts, + bio_core_gets, + bio_core_ctrl, + bio_core_new, + bio_core_free, + NULL, +}; + +const BIO_METHOD *BIO_s_core(void) +{ + return &corebiometh; +} + +BIO *BIO_new_from_core_bio(OSSL_LIB_CTX *libctx, OSSL_CORE_BIO *corebio) +{ + BIO *outbio; + BIO_CORE_GLOBALS *bcgbl = get_globals(libctx); + + /* Check the library context has been initialised with the callbacks */ + if (bcgbl == NULL || (bcgbl->c_bio_write_ex == NULL && bcgbl->c_bio_read_ex == NULL)) + return NULL; + + if ((outbio = BIO_new_ex(libctx, BIO_s_core())) == NULL) + return NULL; + + if (!bcgbl->c_bio_up_ref(corebio)) { + BIO_free(outbio); + return NULL; + } + BIO_set_data(outbio, corebio); + return outbio; +} + +int ossl_bio_init_core(OSSL_LIB_CTX *libctx, const OSSL_DISPATCH *fns) +{ + BIO_CORE_GLOBALS *bcgbl = get_globals(libctx); + + if (bcgbl == NULL) + return 0; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_BIO_READ_EX: + if (bcgbl->c_bio_read_ex == NULL) + bcgbl->c_bio_read_ex = OSSL_FUNC_BIO_read_ex(fns); + break; + case OSSL_FUNC_BIO_WRITE_EX: + if (bcgbl->c_bio_write_ex == NULL) + bcgbl->c_bio_write_ex = OSSL_FUNC_BIO_write_ex(fns); + break; + case OSSL_FUNC_BIO_GETS: + if (bcgbl->c_bio_gets == NULL) + bcgbl->c_bio_gets = OSSL_FUNC_BIO_gets(fns); + break; + case OSSL_FUNC_BIO_PUTS: + if (bcgbl->c_bio_puts == NULL) + bcgbl->c_bio_puts = OSSL_FUNC_BIO_puts(fns); + break; + case OSSL_FUNC_BIO_CTRL: + if (bcgbl->c_bio_ctrl == NULL) + bcgbl->c_bio_ctrl = OSSL_FUNC_BIO_ctrl(fns); + break; + case OSSL_FUNC_BIO_UP_REF: + if (bcgbl->c_bio_up_ref == NULL) + bcgbl->c_bio_up_ref = OSSL_FUNC_BIO_up_ref(fns); + break; + case OSSL_FUNC_BIO_FREE: + if (bcgbl->c_bio_free == NULL) + bcgbl->c_bio_free = OSSL_FUNC_BIO_free(fns); + break; + } + } + + return 1; +} diff --git a/crypto/openssl/crypto/bio/bss_dgram.c b/crypto/openssl/crypto/bio/bss_dgram.c index c87ba4d26508..8ca1cf64ed47 100644 --- a/crypto/openssl/crypto/bio/bss_dgram.c +++ b/crypto/openssl/crypto/bio/bss_dgram.c @@ -1,7 +1,7 @@ /* - * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -57,6 +57,8 @@ static int dgram_sctp_puts(BIO *h, const char *str); static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int dgram_sctp_new(BIO *h); static int dgram_sctp_free(BIO *data); +static int dgram_sctp_wait_for_dry(BIO *b); +static int dgram_sctp_msg_waiting(BIO *b); # ifdef SCTP_AUTHENTICATION_EVENT static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp); @@ -70,10 +72,8 @@ static void get_current_time(struct timeval *t); static const BIO_METHOD methods_dgramp = { BIO_TYPE_DGRAM, "datagram socket", - /* TODO: Convert to new style write function */ bwrite_conv, dgram_write, - /* TODO: Convert to new style read function */ bread_conv, dgram_read, dgram_puts, @@ -88,10 +88,8 @@ static const BIO_METHOD methods_dgramp = { static const BIO_METHOD methods_dgramp_sctp = { BIO_TYPE_DGRAM_SCTP, "datagram sctp socket", - /* TODO: Convert to new style write function */ bwrite_conv, dgram_sctp_write, - /* TODO: Convert to new style write function */ bread_conv, dgram_sctp_read, dgram_sctp_puts, @@ -128,7 +126,7 @@ typedef struct bio_dgram_sctp_data_st { struct bio_dgram_sctp_sndinfo sndinfo; struct bio_dgram_sctp_rcvinfo rcvinfo; struct bio_dgram_sctp_prinfo prinfo; - void (*handle_notifications) (BIO *bio, void *context, void *buf); + BIO_dgram_sctp_notification_handler_fn handle_notifications; void *notification_context; int in_handshake; int ccs_rcvd; @@ -197,12 +195,6 @@ static void dgram_adjust_rcv_timeout(BIO *b) { # if defined(SO_RCVTIMEO) bio_dgram_data *data = (bio_dgram_data *)b->ptr; - union { - size_t s; - int i; - } sz = { - 0 - }; /* Is a timer active? */ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { @@ -212,21 +204,21 @@ static void dgram_adjust_rcv_timeout(BIO *b) # ifdef OPENSSL_SYS_WINDOWS int timeout; - sz.i = sizeof(timeout); + int sz = sizeof(timeout); if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, &sz.i) < 0) { + (void *)&timeout, &sz) < 0) { perror("getsockopt"); } else { data->socket_timeout.tv_sec = timeout / 1000; data->socket_timeout.tv_usec = (timeout % 1000) * 1000; } # else - sz.i = sizeof(data->socket_timeout); + socklen_t sz = sizeof(data->socket_timeout); if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - &(data->socket_timeout), (void *)&sz) < 0) { + &(data->socket_timeout), &sz) < 0) { perror("getsockopt"); - } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) - OPENSSL_assert(sz.s <= sizeof(data->socket_timeout)); + } else + OPENSSL_assert(sz <= sizeof(data->socket_timeout)); # endif /* Get current time */ @@ -609,19 +601,14 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) break; case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: { - union { - size_t s; - int i; - } sz = { - 0 - }; # ifdef OPENSSL_SYS_WINDOWS + int sz = 0; int timeout; struct timeval *tv = (struct timeval *)ptr; - sz.i = sizeof(timeout); + sz = sizeof(timeout); if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, &sz.i) < 0) { + (void *)&timeout, &sz) < 0) { perror("getsockopt"); ret = -1; } else { @@ -630,16 +617,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) ret = sizeof(*tv); } # else - sz.i = sizeof(struct timeval); + socklen_t sz = sizeof(struct timeval); if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - ptr, (void *)&sz) < 0) { + ptr, &sz) < 0) { perror("getsockopt"); ret = -1; - } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { - OPENSSL_assert(sz.s <= sizeof(struct timeval)); - ret = (int)sz.s; - } else - ret = sz.i; + } else { + OPENSSL_assert(sz <= sizeof(struct timeval)); + ret = (int)sz; + } # endif } break; @@ -666,19 +652,14 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) break; case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: { - union { - size_t s; - int i; - } sz = { - 0 - }; # ifdef OPENSSL_SYS_WINDOWS + int sz = 0; int timeout; struct timeval *tv = (struct timeval *)ptr; - sz.i = sizeof(timeout); + sz = sizeof(timeout); if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, - (void *)&timeout, &sz.i) < 0) { + (void *)&timeout, &sz) < 0) { perror("getsockopt"); ret = -1; } else { @@ -687,16 +668,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) ret = sizeof(*tv); } # else - sz.i = sizeof(struct timeval); + socklen_t sz = sizeof(struct timeval); if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, - ptr, (void *)&sz) < 0) { + ptr, &sz) < 0) { perror("getsockopt"); ret = -1; - } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { - OPENSSL_assert(sz.s <= sizeof(struct timeval)); - ret = (int)sz.s; - } else - ret = sz.i; + } else { + OPENSSL_assert(sz <= sizeof(struct timeval)); + ret = (int)sz; + } # endif } break; @@ -845,8 +825,8 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag) sizeof(struct sctp_authchunk)); if (ret < 0) { BIO_vfree(bio); - BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB); - ERR_add_error_data(1, "Ensure SCTP AUTH chunks are enabled in kernel"); + ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB, + "Ensure SCTP AUTH chunks are enabled in kernel"); return NULL; } auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE; @@ -855,8 +835,8 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag) sizeof(struct sctp_authchunk)); if (ret < 0) { BIO_vfree(bio); - BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB); - ERR_add_error_data(1, "Ensure SCTP AUTH chunks are enabled in kernel"); + ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB, + "Ensure SCTP AUTH chunks are enabled in kernel"); return NULL; } @@ -893,10 +873,9 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag) if (!auth_data || !auth_forward) { BIO_vfree(bio); - BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB); - ERR_add_error_data(1, - "Ensure SCTP AUTH chunks are enabled on the " - "underlying socket"); + ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB, + "Ensure SCTP AUTH chunks are enabled on the " + "underlying socket"); return NULL; } @@ -960,7 +939,7 @@ static int dgram_sctp_new(BIO *bi) bi->init = 0; bi->num = 0; if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) { - BIOerr(BIO_F_DGRAM_SCTP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } # ifdef SCTP_PR_SCTP_NONE @@ -1011,7 +990,6 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) int ret = 0, n = 0, i, optval; socklen_t optlen; bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; - union sctp_notification *snp; struct msghdr msg; struct iovec iov; struct cmsghdr *cmsg; @@ -1077,8 +1055,10 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) } if (msg.msg_flags & MSG_NOTIFICATION) { - snp = (union sctp_notification *)out; - if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) { + union sctp_notification snp; + + memcpy(&snp, out, sizeof(snp)); + if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) { # ifdef SCTP_EVENT struct sctp_event event; # else @@ -1118,17 +1098,19 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) # endif } # ifdef SCTP_AUTHENTICATION_EVENT - if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) - dgram_sctp_handle_auth_free_key_event(b, snp); + if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) + dgram_sctp_handle_auth_free_key_event(b, &snp); # endif if (data->handle_notifications != NULL) data->handle_notifications(b, data->notification_context, (void *)out); + memset(&snp, 0, sizeof(snp)); memset(out, 0, outl); - } else + } else { ret += n; + } } while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl)); @@ -1195,7 +1177,7 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); authchunks = OPENSSL_malloc(optlen); if (authchunks == NULL) { - BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return -1; } memset(authchunks, 0, optlen); @@ -1215,7 +1197,7 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) OPENSSL_free(authchunks); if (!auth_data || !auth_forward) { - BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR); + ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR); return -1; } @@ -1566,6 +1548,10 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) else data->save_shutdown = 0; break; + case BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY: + return dgram_sctp_wait_for_dry(b); + case BIO_CTRL_DGRAM_SCTP_MSG_WAITING: + return dgram_sctp_msg_waiting(b); default: /* @@ -1578,11 +1564,8 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) } int BIO_dgram_sctp_notification_cb(BIO *b, - void (*handle_notifications) (BIO *bio, - void - *context, - void *buf), - void *context) + BIO_dgram_sctp_notification_handler_fn handle_notifications, + void *context) { bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; @@ -1609,6 +1592,11 @@ int BIO_dgram_sctp_notification_cb(BIO *b, * 1 when dry */ int BIO_dgram_sctp_wait_for_dry(BIO *b) +{ + return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY, 0, NULL); +} + +static int dgram_sctp_wait_for_dry(BIO *b) { int is_dry = 0; int sockflags = 0; @@ -1767,6 +1755,11 @@ int BIO_dgram_sctp_wait_for_dry(BIO *b) } int BIO_dgram_sctp_msg_waiting(BIO *b) +{ + return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_MSG_WAITING, 0, NULL); +} + +static int dgram_sctp_msg_waiting(BIO *b) { int n, sockflags; union sctp_notification snp; @@ -1907,22 +1900,22 @@ static void get_current_time(struct timeval *t) { # if defined(_WIN32) SYSTEMTIME st; - union { - unsigned __int64 ul; - FILETIME ft; - } now; + unsigned __int64 now_ul; + FILETIME now_ft; GetSystemTime(&st); - SystemTimeToFileTime(&st, &now.ft); + SystemTimeToFileTime(&st, &now_ft); + now_ul = ((unsigned __int64)now_ft.dwHighDateTime << 32) | now_ft.dwLowDateTime; # ifdef __MINGW32__ - now.ul -= 116444736000000000ULL; + now_ul -= 116444736000000000ULL; # else - now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ + now_ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ # endif - t->tv_sec = (long)(now.ul / 10000000); - t->tv_usec = ((int)(now.ul % 10000000)) / 10; + t->tv_sec = (long)(now_ul / 10000000); + t->tv_usec = ((int)(now_ul % 10000000)) / 10; # else - gettimeofday(t, NULL); + if (gettimeofday(t, NULL) < 0) + perror("gettimeofday"); # endif } diff --git a/crypto/openssl/crypto/bio/bss_fd.c b/crypto/openssl/crypto/bio/bss_fd.c index 8d03e48ce993..f756225edb21 100644 --- a/crypto/openssl/crypto/bio/bss_fd.c +++ b/crypto/openssl/crypto/bio/bss_fd.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -60,10 +60,8 @@ int BIO_fd_should_retry(int s); static const BIO_METHOD methods_fdp = { BIO_TYPE_FD, "file descriptor", - /* TODO: Convert to new style write function */ bwrite_conv, fd_write, - /* TODO: Convert to new style read function */ bread_conv, fd_read, fd_puts, @@ -94,7 +92,7 @@ static int fd_new(BIO *bi) bi->init = 0; bi->num = -1; bi->ptr = NULL; - bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */ + bi->flags = BIO_FLAGS_UPLINK_INTERNAL; /* essentially redundant */ return 1; } @@ -107,7 +105,7 @@ static int fd_free(BIO *a) UP_close(a->num); } a->init = 0; - a->flags = BIO_FLAGS_UPLINK; + a->flags = BIO_FLAGS_UPLINK_INTERNAL; } return 1; } diff --git a/crypto/openssl/crypto/bio/bss_file.c b/crypto/openssl/crypto/bio/bss_file.c index 1a70ce799404..a6143b6abcf6 100644 --- a/crypto/openssl/crypto/bio/bss_file.c +++ b/crypto/openssl/crypto/bio/bss_file.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -42,10 +42,8 @@ static int file_free(BIO *data); static const BIO_METHOD methods_filep = { BIO_TYPE_FILE, "FILE pointer", - /* TODO: Convert to new style write function */ bwrite_conv, file_write, - /* TODO: Convert to new style read function */ bread_conv, file_read, file_puts, @@ -66,16 +64,17 @@ BIO *BIO_new_file(const char *filename, const char *mode) fp_flags |= BIO_FP_TEXT; if (file == NULL) { - SYSerr(SYS_F_FOPEN, get_last_sys_error()); - ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fopen(%s, %s)", + filename, mode); if (errno == ENOENT #ifdef ENXIO || errno == ENXIO #endif ) - BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE); + ERR_raise(ERR_LIB_BIO, BIO_R_NO_SUCH_FILE); else - BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB); return NULL; } if ((ret = BIO_new(BIO_s_file())) == NULL) { @@ -83,8 +82,8 @@ BIO *BIO_new_file(const char *filename, const char *mode) return NULL; } - BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage - * UPLINK */ + /* we did fopen -> we disengage UPLINK */ + BIO_clear_flags(ret, BIO_FLAGS_UPLINK_INTERNAL); BIO_set_fp(ret, file, fp_flags); return ret; } @@ -97,7 +96,7 @@ BIO *BIO_new_fp(FILE *stream, int close_flag) return NULL; /* redundant flag, left for documentation purposes */ - BIO_set_flags(ret, BIO_FLAGS_UPLINK); + BIO_set_flags(ret, BIO_FLAGS_UPLINK_INTERNAL); BIO_set_fp(ret, stream, close_flag); return ret; } @@ -112,7 +111,7 @@ static int file_new(BIO *bi) bi->init = 0; bi->num = 0; bi->ptr = NULL; - bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */ + bi->flags = BIO_FLAGS_UPLINK_INTERNAL; /* default to UPLINK */ return 1; } @@ -122,12 +121,12 @@ static int file_free(BIO *a) return 0; if (a->shutdown) { if ((a->init) && (a->ptr != NULL)) { - if (a->flags & BIO_FLAGS_UPLINK) + if (a->flags & BIO_FLAGS_UPLINK_INTERNAL) UP_fclose(a->ptr); else fclose(a->ptr); a->ptr = NULL; - a->flags = BIO_FLAGS_UPLINK; + a->flags = BIO_FLAGS_UPLINK_INTERNAL; } a->init = 0; } @@ -139,15 +138,16 @@ static int file_read(BIO *b, char *out, int outl) int ret = 0; if (b->init && (out != NULL)) { - if (b->flags & BIO_FLAGS_UPLINK) + if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) ret = UP_fread(out, 1, (int)outl, b->ptr); else ret = fread(out, 1, (int)outl, (FILE *)b->ptr); if (ret == 0 - && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) : - ferror((FILE *)b->ptr)) { - SYSerr(SYS_F_FREAD, get_last_sys_error()); - BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB); + && (b->flags & BIO_FLAGS_UPLINK_INTERNAL + ? UP_ferror((FILE *)b->ptr) : ferror((FILE *)b->ptr))) { + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fread()"); + ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB); ret = -1; } } @@ -159,7 +159,7 @@ static int file_write(BIO *b, const char *in, int inl) int ret = 0; if (b->init && (in != NULL)) { - if (b->flags & BIO_FLAGS_UPLINK) + if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) ret = UP_fwrite(in, (int)inl, 1, b->ptr); else ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr); @@ -186,20 +186,20 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) switch (cmd) { case BIO_C_FILE_SEEK: case BIO_CTRL_RESET: - if (b->flags & BIO_FLAGS_UPLINK) + if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) ret = (long)UP_fseek(b->ptr, num, 0); else ret = (long)fseek(fp, num, 0); break; case BIO_CTRL_EOF: - if (b->flags & BIO_FLAGS_UPLINK) + if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) ret = (long)UP_feof(fp); else ret = (long)feof(fp); break; case BIO_C_FILE_TELL: case BIO_CTRL_INFO: - if (b->flags & BIO_FLAGS_UPLINK) + if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) ret = UP_ftell(b->ptr); else ret = ftell(fp); @@ -209,22 +209,22 @@ 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 BIO_FLAGS_UPLINK_INTERNAL!=0 # if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) # define _IOB_ENTRIES 20 # endif /* Safety net to catch purely internal BIO_set_fp calls */ -# if defined(_MSC_VER) && _MSC_VER>=1900 +# if (defined(_MSC_VER) && _MSC_VER>=1900) || defined(__BORLANDC__) if (ptr == stdin || ptr == stdout || ptr == stderr) - BIO_clear_flags(b, BIO_FLAGS_UPLINK); + BIO_clear_flags(b, BIO_FLAGS_UPLINK_INTERNAL); # 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); + BIO_clear_flags(b, BIO_FLAGS_UPLINK_INTERNAL); # endif # endif # ifdef UP_fsetmod - if (b->flags & BIO_FLAGS_UPLINK) + if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b')); else # endif @@ -235,6 +235,15 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) _setmode(fd, _O_TEXT); else _setmode(fd, _O_BINARY); + /* + * Reports show that ftell() isn't trustable in text mode. + * This has been confirmed as a bug in the Universal C RTL, see + * https://developercommunity.visualstudio.com/content/problem/425878/fseek-ftell-fail-in-text-mode-for-unix-style-text.html + * The suggested work-around from Microsoft engineering is to + * turn off buffering until the bug is resolved. + */ + if ((num & BIO_FP_TEXT) != 0) + setvbuf((FILE *)ptr, NULL, _IONBF, 0); # elif defined(OPENSSL_SYS_MSDOS) int fd = fileno((FILE *)ptr); /* Set correct text/binary mode */ @@ -270,7 +279,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) else if (num & BIO_FP_READ) OPENSSL_strlcpy(p, "r", sizeof(p)); else { - BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE); + ERR_raise(ERR_LIB_BIO, BIO_R_BAD_FOPEN_MODE); ret = 0; break; } @@ -285,16 +294,17 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) # endif fp = openssl_fopen(ptr, p); if (fp == NULL) { - SYSerr(SYS_F_FOPEN, get_last_sys_error()); - ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); - BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fopen(%s, %s)", + ptr, p); + ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB); ret = 0; break; } b->ptr = fp; b->init = 1; - BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage - * UPLINK */ + /* we did fopen -> we disengage UPLINK */ + BIO_clear_flags(b, BIO_FLAGS_UPLINK_INTERNAL); break; case BIO_C_GET_FILE_PTR: /* the ptr parameter is actually a FILE ** in this case. */ @@ -310,12 +320,12 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) b->shutdown = (int)num; break; case BIO_CTRL_FLUSH: - st = b->flags & BIO_FLAGS_UPLINK + st = b->flags & BIO_FLAGS_UPLINK_INTERNAL ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr); if (st == EOF) { - SYSerr(SYS_F_FFLUSH, get_last_sys_error()); - ERR_add_error_data(1, "fflush()"); - BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling fflush()"); + ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB); ret = 0; } break; @@ -339,7 +349,7 @@ static int file_gets(BIO *bp, char *buf, int size) int ret = 0; buf[0] = '\0'; - if (bp->flags & BIO_FLAGS_UPLINK) { + if (bp->flags & BIO_FLAGS_UPLINK_INTERNAL) { if (!UP_fgets(buf, size, bp->ptr)) goto err; } else { @@ -395,10 +405,8 @@ static int file_free(BIO *a) static const BIO_METHOD methods_filep = { BIO_TYPE_FILE, "FILE pointer", - /* TODO: Convert to new style write function */ bwrite_conv, file_write, - /* TODO: Convert to new style read function */ bread_conv, file_read, file_puts, diff --git a/crypto/openssl/crypto/bio/bss_log.c b/crypto/openssl/crypto/bio/bss_log.c index b9579faaa2a5..82abfd5cec63 100644 --- a/crypto/openssl/crypto/bio/bss_log.c +++ b/crypto/openssl/crypto/bio/bss_log.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -87,7 +87,6 @@ static void xcloselog(BIO *bp); static const BIO_METHOD methods_slg = { BIO_TYPE_MEM, "syslog", - /* TODO: Convert to new style write function */ bwrite_conv, slg_write, NULL, /* slg_write_old, */ @@ -196,8 +195,10 @@ static int slg_write(BIO *b, const char *in, int inl) /* The default */ }; + if (inl < 0) + return 0; if ((buf = OPENSSL_malloc(inl + 1)) == NULL) { - BIOerr(BIO_F_SLG_WRITE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } memcpy(buf, in, inl); diff --git a/crypto/openssl/crypto/bio/bss_mem.c b/crypto/openssl/crypto/bio/bss_mem.c index 2420b26553e0..9153c1f1cd81 100644 --- a/crypto/openssl/crypto/bio/bss_mem.c +++ b/crypto/openssl/crypto/bio/bss_mem.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -26,10 +26,8 @@ static int mem_buf_sync(BIO *h); static const BIO_METHOD mem_method = { BIO_TYPE_MEM, "memory buffer", - /* TODO: Convert to new style write function */ bwrite_conv, mem_write, - /* TODO: Convert to new style read function */ bread_conv, mem_read, mem_puts, @@ -43,10 +41,8 @@ static const BIO_METHOD mem_method = { static const BIO_METHOD secmem_method = { BIO_TYPE_MEM, "secure memory buffer", - /* TODO: Convert to new style write function */ bwrite_conv, mem_write, - /* TODO: Convert to new style read function */ bread_conv, mem_read, mem_puts, @@ -91,7 +87,7 @@ BIO *BIO_new_mem_buf(const void *buf, int len) size_t sz; if (buf == NULL) { - BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER); + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); return NULL; } sz = (len < 0) ? strlen(buf) : (size_t)len; @@ -176,6 +172,7 @@ static int mem_buf_free(BIO *a) /* * Reallocate memory buffer if read pointer differs + * NOT FOR RDONLY */ static int mem_buf_sync(BIO *b) { @@ -220,17 +217,17 @@ static int mem_write(BIO *b, const char *in, int inl) int blen; BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr; - if (in == NULL) { - BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER); - goto end; - } if (b->flags & BIO_FLAGS_MEM_RDONLY) { - BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO); + ERR_raise(ERR_LIB_BIO, BIO_R_WRITE_TO_READ_ONLY_BIO); goto end; } BIO_clear_retry_flags(b); if (inl == 0) return 0; + if (in == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + goto end; + } blen = bbm->readp->length; mem_buf_sync(b); if (BUF_MEM_grow_clean(bbm->buf, blen + inl) == 0) @@ -247,12 +244,18 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) long ret = 1; char **pptr; BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr; - BUF_MEM *bm; + BUF_MEM *bm, *bo; /* bio_mem, bio_other */ + long off, remain; - if (b->flags & BIO_FLAGS_MEM_RDONLY) + if (b->flags & BIO_FLAGS_MEM_RDONLY) { bm = bbm->buf; - else + bo = bbm->readp; + } else { bm = bbm->readp; + bo = bbm->buf; + } + off = (bm->data == bo->data) ? 0 : bm->data - bo->data; + remain = bm->length; switch (cmd) { case BIO_CTRL_RESET: @@ -270,6 +273,18 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) } } break; + case BIO_C_FILE_SEEK: + if (num < 0 || num > off + remain) + return -1; /* Can't see outside of the current buffer */ + + bm->data = (num != 0) ? bo->data + num : bo->data; + bm->length = bo->length - num; + bm->max = bo->max - num; + off = num; + /* FALLTHRU */ + case BIO_C_FILE_TELL: + ret = off; + break; case BIO_CTRL_EOF: ret = (long)(bm->length == 0); break; @@ -280,7 +295,7 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) ret = (long)bm->length; if (ptr != NULL) { pptr = (char **)ptr; - *pptr = (char *)bm->data; + *pptr = (char *)(bm->data); } break; case BIO_C_SET_BUF_MEM: diff --git a/crypto/openssl/crypto/bio/bss_null.c b/crypto/openssl/crypto/bio/bss_null.c index e73ce7841d41..ba266f186c21 100644 --- a/crypto/openssl/crypto/bio/bss_null.c +++ b/crypto/openssl/crypto/bio/bss_null.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,10 +20,8 @@ static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2); static const BIO_METHOD null_method = { BIO_TYPE_NULL, "NULL", - /* TODO: Convert to new style write function */ bwrite_conv, null_write, - /* TODO: Convert to new style read function */ bread_conv, null_read, null_puts, diff --git a/crypto/openssl/crypto/bio/bss_sock.c b/crypto/openssl/crypto/bio/bss_sock.c index 8de1f5829207..f5d88102303a 100644 --- a/crypto/openssl/crypto/bio/bss_sock.c +++ b/crypto/openssl/crypto/bio/bss_sock.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -38,10 +38,8 @@ int BIO_sock_should_retry(int s); static const BIO_METHOD methods_sockp = { BIO_TYPE_SOCKET, "socket", - /* TODO: Convert to new style write function */ bwrite_conv, sock_write, - /* TODO: Convert to new style read function */ bread_conv, sock_read, sock_puts, diff --git a/crypto/openssl/crypto/bio/build.info b/crypto/openssl/crypto/bio/build.info index d1e7d73c5509..b203ed5e63fe 100644 --- a/crypto/openssl/crypto/bio/build.info +++ b/crypto/openssl/crypto/bio/build.info @@ -1,8 +1,18 @@ LIBS=../../libcrypto + +# Base library SOURCE[../../libcrypto]=\ bio_lib.c bio_cb.c bio_err.c \ - bss_mem.c bss_null.c bss_fd.c \ - bss_file.c bss_sock.c bss_conn.c \ - bf_null.c bf_buff.c b_print.c b_dump.c b_addr.c \ - b_sock.c b_sock2.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c \ - bss_dgram.c bio_meth.c bf_lbuf.c + bio_print.c bio_dump.c bio_addr.c \ + bio_sock.c bio_sock2.c \ + bio_meth.c ossl_core_bio.c + +# Source / sink implementations +SOURCE[../../libcrypto]=\ + bss_null.c bss_mem.c bss_bio.c bss_fd.c bss_file.c \ + bss_sock.c bss_conn.c bss_acpt.c bss_dgram.c \ + bss_log.c bss_core.c + +# Filters +SOURCE[../../libcrypto]=\ + bf_null.c bf_buff.c bf_lbuf.c bf_nbio.c bf_prefix.c bf_readbuff.c diff --git a/crypto/openssl/crypto/bio/ossl_core_bio.c b/crypto/openssl/crypto/bio/ossl_core_bio.c new file mode 100644 index 000000000000..328302ea34e6 --- /dev/null +++ b/crypto/openssl/crypto/bio/ossl_core_bio.c @@ -0,0 +1,124 @@ +/* + * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "bio_local.h" + +/*- + * Core BIO structure + * This is distinct from a BIO to prevent casting between the two which could + * lead to versioning problems. + */ +struct ossl_core_bio_st { + CRYPTO_REF_COUNT ref_cnt; + CRYPTO_RWLOCK *ref_lock; + BIO *bio; +}; + +static OSSL_CORE_BIO *core_bio_new(void) +{ + OSSL_CORE_BIO *cb = OPENSSL_malloc(sizeof(*cb)); + + if (cb == NULL || (cb->ref_lock = CRYPTO_THREAD_lock_new()) == NULL) { + OPENSSL_free(cb); + return NULL; + } + cb->ref_cnt = 1; + return cb; +} + +int ossl_core_bio_up_ref(OSSL_CORE_BIO *cb) +{ + int ref = 0; + + return CRYPTO_UP_REF(&cb->ref_cnt, &ref, cb->ref_lock); +} + +int ossl_core_bio_free(OSSL_CORE_BIO *cb) +{ + int ref = 0, res = 1; + + if (cb != NULL) { + CRYPTO_DOWN_REF(&cb->ref_cnt, &ref, cb->ref_lock); + if (ref <= 0) { + res = BIO_free(cb->bio); + CRYPTO_THREAD_lock_free(cb->ref_lock); + OPENSSL_free(cb); + } + } + return res; +} + +OSSL_CORE_BIO *ossl_core_bio_new_from_bio(BIO *bio) +{ + OSSL_CORE_BIO *cb = core_bio_new(); + + if (cb == NULL || !BIO_up_ref(bio)) { + ossl_core_bio_free(cb); + return NULL; + } + cb->bio = bio; + return cb; +} + +static OSSL_CORE_BIO *core_bio_new_from_new_bio(BIO *bio) +{ + OSSL_CORE_BIO *cb = NULL; + + if (bio == NULL) + return NULL; + if ((cb = core_bio_new()) == NULL) { + BIO_free(bio); + return NULL; + } + cb->bio = bio; + return cb; +} + +OSSL_CORE_BIO *ossl_core_bio_new_file(const char *filename, const char *mode) +{ + return core_bio_new_from_new_bio(BIO_new_file(filename, mode)); +} + +OSSL_CORE_BIO *ossl_core_bio_new_mem_buf(const void *buf, int len) +{ + return core_bio_new_from_new_bio(BIO_new_mem_buf(buf, len)); +} + +int ossl_core_bio_read_ex(OSSL_CORE_BIO *cb, void *data, size_t dlen, + size_t *readbytes) +{ + return BIO_read_ex(cb->bio, data, dlen, readbytes); +} + +int ossl_core_bio_write_ex(OSSL_CORE_BIO *cb, const void *data, size_t dlen, + size_t *written) +{ + return BIO_write_ex(cb->bio, data, dlen, written); +} + +int ossl_core_bio_gets(OSSL_CORE_BIO *cb, char *buf, int size) +{ + return BIO_gets(cb->bio, buf, size); +} + +int ossl_core_bio_puts(OSSL_CORE_BIO *cb, const char *buf) +{ + return BIO_puts(cb->bio, buf); +} + +long ossl_core_bio_ctrl(OSSL_CORE_BIO *cb, int cmd, long larg, void *parg) +{ + return BIO_ctrl(cb->bio, cmd, larg, parg); +} + +int ossl_core_bio_vprintf(OSSL_CORE_BIO *cb, const char *format, va_list args) +{ + return BIO_vprintf(cb->bio, format, args); +} diff --git a/crypto/openssl/crypto/blake2/blake2_local.h b/crypto/openssl/crypto/blake2/blake2_local.h deleted file mode 100644 index 926bae944c17..000000000000 --- a/crypto/openssl/crypto/blake2/blake2_local.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2016-2017 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 - */ - -/* - * Derived from the BLAKE2 reference implementation written by Samuel Neves. - * Copyright 2012, Samuel Neves - * More information about the BLAKE2 hash function and its implementations - * can be found at https://blake2.net. - */ - -#include - -#define BLAKE2S_BLOCKBYTES 64 -#define BLAKE2S_OUTBYTES 32 -#define BLAKE2S_KEYBYTES 32 -#define BLAKE2S_SALTBYTES 8 -#define BLAKE2S_PERSONALBYTES 8 - -#define BLAKE2B_BLOCKBYTES 128 -#define BLAKE2B_OUTBYTES 64 -#define BLAKE2B_KEYBYTES 64 -#define BLAKE2B_SALTBYTES 16 -#define BLAKE2B_PERSONALBYTES 16 - -struct blake2s_param_st { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint8_t leaf_length[4];/* 8 */ - uint8_t node_offset[6];/* 14 */ - uint8_t node_depth; /* 15 */ - uint8_t inner_length; /* 16 */ - uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ - uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ -}; - -typedef struct blake2s_param_st BLAKE2S_PARAM; - -struct blake2s_ctx_st { - uint32_t h[8]; - uint32_t t[2]; - uint32_t f[2]; - uint8_t buf[BLAKE2S_BLOCKBYTES]; - size_t buflen; -}; - -struct blake2b_param_st { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint8_t leaf_length[4];/* 8 */ - uint8_t node_offset[8];/* 16 */ - uint8_t node_depth; /* 17 */ - uint8_t inner_length; /* 18 */ - uint8_t reserved[14]; /* 32 */ - uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ - uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ -}; - -typedef struct blake2b_param_st BLAKE2B_PARAM; - -struct blake2b_ctx_st { - uint64_t h[8]; - uint64_t t[2]; - uint64_t f[2]; - uint8_t buf[BLAKE2B_BLOCKBYTES]; - size_t buflen; -}; - -#define BLAKE2B_DIGEST_LENGTH 64 -#define BLAKE2S_DIGEST_LENGTH 32 - -typedef struct blake2s_ctx_st BLAKE2S_CTX; -typedef struct blake2b_ctx_st BLAKE2B_CTX; - -int BLAKE2b_Init(BLAKE2B_CTX *c); -int BLAKE2b_Update(BLAKE2B_CTX *c, const void *data, size_t datalen); -int BLAKE2b_Final(unsigned char *md, BLAKE2B_CTX *c); - -int BLAKE2s_Init(BLAKE2S_CTX *c); -int BLAKE2s_Update(BLAKE2S_CTX *c, const void *data, size_t datalen); -int BLAKE2s_Final(unsigned char *md, BLAKE2S_CTX *c); diff --git a/crypto/openssl/crypto/blake2/build.info b/crypto/openssl/crypto/blake2/build.info deleted file mode 100644 index 0036f084826e..000000000000 --- a/crypto/openssl/crypto/blake2/build.info +++ /dev/null @@ -1,3 +0,0 @@ -LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - blake2b.c blake2s.c m_blake2b.c m_blake2s.c diff --git a/crypto/openssl/crypto/blake2/m_blake2b.c b/crypto/openssl/crypto/blake2/m_blake2b.c deleted file mode 100644 index ce4d8f95652f..000000000000 --- a/crypto/openssl/crypto/blake2/m_blake2b.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 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 - */ - -/* - * Derived from the BLAKE2 reference implementation written by Samuel Neves. - * Copyright 2012, Samuel Neves - * More information about the BLAKE2 hash function and its implementations - * can be found at https://blake2.net. - */ - -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_BLAKE2 - -# include -# include -# include "blake2_local.h" -# include "crypto/evp.h" - -static int init(EVP_MD_CTX *ctx) -{ - return BLAKE2b_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return BLAKE2b_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return BLAKE2b_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD blake2b_md = { - NID_blake2b512, - 0, - BLAKE2B_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - BLAKE2B_BLOCKBYTES, - sizeof(EVP_MD *) + sizeof(BLAKE2B_CTX), -}; - -const EVP_MD *EVP_blake2b512(void) -{ - return &blake2b_md; -} -#endif diff --git a/crypto/openssl/crypto/blake2/m_blake2s.c b/crypto/openssl/crypto/blake2/m_blake2s.c deleted file mode 100644 index b8fb048b30bf..000000000000 --- a/crypto/openssl/crypto/blake2/m_blake2s.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 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 - */ - -/* - * Derived from the BLAKE2 reference implementation written by Samuel Neves. - * Copyright 2012, Samuel Neves - * More information about the BLAKE2 hash function and its implementations - * can be found at https://blake2.net. - */ - -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_BLAKE2 - -# include -# include -# include "blake2_local.h" -# include "crypto/evp.h" - -static int init(EVP_MD_CTX *ctx) -{ - return BLAKE2s_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return BLAKE2s_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return BLAKE2s_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD blake2s_md = { - NID_blake2s256, - 0, - BLAKE2S_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - BLAKE2S_BLOCKBYTES, - sizeof(EVP_MD *) + sizeof(BLAKE2S_CTX), -}; - -const EVP_MD *EVP_blake2s256(void) -{ - return &blake2s_md; -} -#endif diff --git a/crypto/openssl/crypto/bn/README.pod b/crypto/openssl/crypto/bn/README.pod index 5d5c4fa99fa1..1286fc0d4132 100644 --- a/crypto/openssl/crypto/bn/README.pod +++ b/crypto/openssl/crypto/bn/README.pod @@ -233,7 +233,7 @@ L Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. -Licensed under the OpenSSL license (the "License"). You may not use +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. diff --git a/crypto/openssl/crypto/bn/armv8-mont.S b/crypto/openssl/crypto/bn/armv8-mont.S new file mode 100644 index 000000000000..98d06f934a9e --- /dev/null +++ b/crypto/openssl/crypto/bn/armv8-mont.S @@ -0,0 +1,2124 @@ +#ifndef __KERNEL__ +# include "arm_arch.h" + +.hidden OPENSSL_armv8_rsa_neonized +#endif +.text + +.globl bn_mul_mont +.type bn_mul_mont,%function +.align 5 +bn_mul_mont: +.Lbn_mul_mont: + tst x5,#3 + b.ne .Lmul_mont + cmp x5,#32 + b.le .Lscalar_impl +#ifndef __KERNEL__ + adrp x17,OPENSSL_armv8_rsa_neonized + ldr w17,[x17,#:lo12:OPENSSL_armv8_rsa_neonized] + cbnz w17, bn_mul8x_mont_neon +#endif + +.Lscalar_impl: + tst x5,#7 + b.eq __bn_sqr8x_mont + tst x5,#3 + b.eq __bn_mul4x_mont + +.Lmul_mont: + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + ldr x9,[x2],#8 // bp[0] + sub x22,sp,x5,lsl#3 + ldp x7,x8,[x1],#16 // ap[0..1] + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + and x22,x22,#-16 // ABI says so + ldp x13,x14,[x3],#16 // np[0..1] + + mul x6,x7,x9 // ap[0]*bp[0] + sub x21,x5,#16 // j=num-2 + umulh x7,x7,x9 + mul x10,x8,x9 // ap[1]*bp[0] + umulh x11,x8,x9 + + mul x15,x6,x4 // "tp[0]"*n0 + mov sp,x22 // alloca + + // (*) mul x12,x13,x15 // np[0]*m1 + umulh x13,x13,x15 + mul x16,x14,x15 // np[1]*m1 + // (*) adds x12,x12,x6 // discarded + // (*) As for removal of first multiplication and addition + // instructions. The outcome of first addition is + // guaranteed to be zero, which leaves two computationally + // significant outcomes: it either carries or not. Then + // question is when does it carry? Is there alternative + // way to deduce it? If you follow operations, you can + // observe that condition for carry is quite simple: + // x6 being non-zero. So that carry can be calculated + // by adding -1 to x6. That's what next instruction does. + subs xzr,x6,#1 // (*) + umulh x17,x14,x15 + adc x13,x13,xzr + cbz x21,.L1st_skip + +.L1st: + ldr x8,[x1],#8 + adds x6,x10,x7 + sub x21,x21,#8 // j-- + adc x7,x11,xzr + + ldr x14,[x3],#8 + adds x12,x16,x13 + mul x10,x8,x9 // ap[j]*bp[0] + adc x13,x17,xzr + umulh x11,x8,x9 + + adds x12,x12,x6 + mul x16,x14,x15 // np[j]*m1 + adc x13,x13,xzr + umulh x17,x14,x15 + str x12,[x22],#8 // tp[j-1] + cbnz x21,.L1st + +.L1st_skip: + adds x6,x10,x7 + sub x1,x1,x5 // rewind x1 + adc x7,x11,xzr + + adds x12,x16,x13 + sub x3,x3,x5 // rewind x3 + adc x13,x17,xzr + + adds x12,x12,x6 + sub x20,x5,#8 // i=num-1 + adcs x13,x13,x7 + + adc x19,xzr,xzr // upmost overflow bit + stp x12,x13,[x22] + +.Louter: + ldr x9,[x2],#8 // bp[i] + ldp x7,x8,[x1],#16 + ldr x23,[sp] // tp[0] + add x22,sp,#8 + + mul x6,x7,x9 // ap[0]*bp[i] + sub x21,x5,#16 // j=num-2 + umulh x7,x7,x9 + ldp x13,x14,[x3],#16 + mul x10,x8,x9 // ap[1]*bp[i] + adds x6,x6,x23 + umulh x11,x8,x9 + adc x7,x7,xzr + + mul x15,x6,x4 + sub x20,x20,#8 // i-- + + // (*) mul x12,x13,x15 // np[0]*m1 + umulh x13,x13,x15 + mul x16,x14,x15 // np[1]*m1 + // (*) adds x12,x12,x6 + subs xzr,x6,#1 // (*) + umulh x17,x14,x15 + cbz x21,.Linner_skip + +.Linner: + ldr x8,[x1],#8 + adc x13,x13,xzr + ldr x23,[x22],#8 // tp[j] + adds x6,x10,x7 + sub x21,x21,#8 // j-- + adc x7,x11,xzr + + adds x12,x16,x13 + ldr x14,[x3],#8 + adc x13,x17,xzr + + mul x10,x8,x9 // ap[j]*bp[i] + adds x6,x6,x23 + umulh x11,x8,x9 + adc x7,x7,xzr + + mul x16,x14,x15 // np[j]*m1 + adds x12,x12,x6 + umulh x17,x14,x15 + stur x12,[x22,#-16] // tp[j-1] + cbnz x21,.Linner + +.Linner_skip: + ldr x23,[x22],#8 // tp[j] + adc x13,x13,xzr + adds x6,x10,x7 + sub x1,x1,x5 // rewind x1 + adc x7,x11,xzr + + adds x12,x16,x13 + sub x3,x3,x5 // rewind x3 + adcs x13,x17,x19 + adc x19,xzr,xzr + + adds x6,x6,x23 + adc x7,x7,xzr + + adds x12,x12,x6 + adcs x13,x13,x7 + adc x19,x19,xzr // upmost overflow bit + stp x12,x13,[x22,#-16] + + cbnz x20,.Louter + + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + ldr x23,[sp] // tp[0] + add x22,sp,#8 + ldr x14,[x3],#8 // np[0] + subs x21,x5,#8 // j=num-1 and clear borrow + mov x1,x0 +.Lsub: + sbcs x8,x23,x14 // tp[j]-np[j] + ldr x23,[x22],#8 + sub x21,x21,#8 // j-- + ldr x14,[x3],#8 + str x8,[x1],#8 // rp[j]=tp[j]-np[j] + cbnz x21,.Lsub + + sbcs x8,x23,x14 + sbcs x19,x19,xzr // did it borrow? + str x8,[x1],#8 // rp[num-1] + + ldr x23,[sp] // tp[0] + add x22,sp,#8 + ldr x8,[x0],#8 // rp[0] + sub x5,x5,#8 // num-- + nop +.Lcond_copy: + sub x5,x5,#8 // num-- + csel x14,x23,x8,lo // did it borrow? + ldr x23,[x22],#8 + ldr x8,[x0],#8 + stur xzr,[x22,#-16] // wipe tp + stur x14,[x0,#-16] + cbnz x5,.Lcond_copy + + csel x14,x23,x8,lo + stur xzr,[x22,#-8] // wipe tp + stur x14,[x0,#-8] + + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldr x29,[sp],#64 + ret +.size bn_mul_mont,.-bn_mul_mont +.type bn_mul8x_mont_neon,%function +.align 5 +bn_mul8x_mont_neon: + stp x29,x30,[sp,#-80]! + mov x16,sp + stp d8,d9,[sp,#16] + stp d10,d11,[sp,#32] + stp d12,d13,[sp,#48] + stp d14,d15,[sp,#64] + lsl x5,x5,#1 + eor v14.16b,v14.16b,v14.16b + +.align 4 +.LNEON_8n: + eor v6.16b,v6.16b,v6.16b + sub x7,sp,#128 + eor v7.16b,v7.16b,v7.16b + sub x7,x7,x5,lsl#4 + eor v8.16b,v8.16b,v8.16b + and x7,x7,#-64 + eor v9.16b,v9.16b,v9.16b + mov sp,x7 // alloca + eor v10.16b,v10.16b,v10.16b + add x7,x7,#256 + eor v11.16b,v11.16b,v11.16b + sub x8,x5,#8 + eor v12.16b,v12.16b,v12.16b + eor v13.16b,v13.16b,v13.16b + +.LNEON_8n_init: + st1 {v6.2d,v7.2d},[x7],#32 + subs x8,x8,#8 + st1 {v8.2d,v9.2d},[x7],#32 + st1 {v10.2d,v11.2d},[x7],#32 + st1 {v12.2d,v13.2d},[x7],#32 + bne .LNEON_8n_init + + add x6,sp,#256 + ld1 {v0.4s,v1.4s},[x1],#32 + add x10,sp,#8 + ldr s30,[x4],#4 + mov x9,x5 + b .LNEON_8n_outer + +.align 4 +.LNEON_8n_outer: + ldr s28,[x2],#4 // *b++ + uxtl v28.4s,v28.4h + add x7,sp,#128 + ld1 {v2.4s,v3.4s},[x3],#32 + + umlal v6.2d,v28.2s,v0.s[0] + umlal v7.2d,v28.2s,v0.s[1] + umlal v8.2d,v28.2s,v0.s[2] + shl v29.2d,v6.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v9.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v6.2d + umlal v10.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v11.2d,v28.2s,v1.s[1] + st1 {v28.2s},[sp] // put aside smashed b[8*i+0] + umlal v12.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v13.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v6.2d,v29.2s,v2.s[0] + umlal v7.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v8.2d,v29.2s,v2.s[2] + ushr v15.2d,v6.2d,#16 + umlal v9.2d,v29.2s,v2.s[3] + umlal v10.2d,v29.2s,v3.s[0] + ext v6.16b,v6.16b,v6.16b,#8 + add v6.2d,v6.2d,v15.2d + umlal v11.2d,v29.2s,v3.s[1] + ushr v6.2d,v6.2d,#16 + umlal v12.2d,v29.2s,v3.s[2] + umlal v13.2d,v29.2s,v3.s[3] + add v16.2d,v7.2d,v6.2d + ins v7.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+0] + umlal v7.2d,v28.2s,v0.s[0] + ld1 {v6.2d},[x6],#16 + umlal v8.2d,v28.2s,v0.s[1] + umlal v9.2d,v28.2s,v0.s[2] + shl v29.2d,v7.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v10.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v7.2d + umlal v11.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v12.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+1] + umlal v13.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v6.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v7.2d,v29.2s,v2.s[0] + umlal v8.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v9.2d,v29.2s,v2.s[2] + ushr v15.2d,v7.2d,#16 + umlal v10.2d,v29.2s,v2.s[3] + umlal v11.2d,v29.2s,v3.s[0] + ext v7.16b,v7.16b,v7.16b,#8 + add v7.2d,v7.2d,v15.2d + umlal v12.2d,v29.2s,v3.s[1] + ushr v7.2d,v7.2d,#16 + umlal v13.2d,v29.2s,v3.s[2] + umlal v6.2d,v29.2s,v3.s[3] + add v16.2d,v8.2d,v7.2d + ins v8.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+1] + umlal v8.2d,v28.2s,v0.s[0] + ld1 {v7.2d},[x6],#16 + umlal v9.2d,v28.2s,v0.s[1] + umlal v10.2d,v28.2s,v0.s[2] + shl v29.2d,v8.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v11.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v8.2d + umlal v12.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v13.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+2] + umlal v6.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v7.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v8.2d,v29.2s,v2.s[0] + umlal v9.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v10.2d,v29.2s,v2.s[2] + ushr v15.2d,v8.2d,#16 + umlal v11.2d,v29.2s,v2.s[3] + umlal v12.2d,v29.2s,v3.s[0] + ext v8.16b,v8.16b,v8.16b,#8 + add v8.2d,v8.2d,v15.2d + umlal v13.2d,v29.2s,v3.s[1] + ushr v8.2d,v8.2d,#16 + umlal v6.2d,v29.2s,v3.s[2] + umlal v7.2d,v29.2s,v3.s[3] + add v16.2d,v9.2d,v8.2d + ins v9.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+2] + umlal v9.2d,v28.2s,v0.s[0] + ld1 {v8.2d},[x6],#16 + umlal v10.2d,v28.2s,v0.s[1] + umlal v11.2d,v28.2s,v0.s[2] + shl v29.2d,v9.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v12.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v9.2d + umlal v13.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v6.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+3] + umlal v7.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v8.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v9.2d,v29.2s,v2.s[0] + umlal v10.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v11.2d,v29.2s,v2.s[2] + ushr v15.2d,v9.2d,#16 + umlal v12.2d,v29.2s,v2.s[3] + umlal v13.2d,v29.2s,v3.s[0] + ext v9.16b,v9.16b,v9.16b,#8 + add v9.2d,v9.2d,v15.2d + umlal v6.2d,v29.2s,v3.s[1] + ushr v9.2d,v9.2d,#16 + umlal v7.2d,v29.2s,v3.s[2] + umlal v8.2d,v29.2s,v3.s[3] + add v16.2d,v10.2d,v9.2d + ins v10.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+3] + umlal v10.2d,v28.2s,v0.s[0] + ld1 {v9.2d},[x6],#16 + umlal v11.2d,v28.2s,v0.s[1] + umlal v12.2d,v28.2s,v0.s[2] + shl v29.2d,v10.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v13.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v10.2d + umlal v6.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v7.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+4] + umlal v8.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v9.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v10.2d,v29.2s,v2.s[0] + umlal v11.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v12.2d,v29.2s,v2.s[2] + ushr v15.2d,v10.2d,#16 + umlal v13.2d,v29.2s,v2.s[3] + umlal v6.2d,v29.2s,v3.s[0] + ext v10.16b,v10.16b,v10.16b,#8 + add v10.2d,v10.2d,v15.2d + umlal v7.2d,v29.2s,v3.s[1] + ushr v10.2d,v10.2d,#16 + umlal v8.2d,v29.2s,v3.s[2] + umlal v9.2d,v29.2s,v3.s[3] + add v16.2d,v11.2d,v10.2d + ins v11.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+4] + umlal v11.2d,v28.2s,v0.s[0] + ld1 {v10.2d},[x6],#16 + umlal v12.2d,v28.2s,v0.s[1] + umlal v13.2d,v28.2s,v0.s[2] + shl v29.2d,v11.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v6.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v11.2d + umlal v7.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v8.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+5] + umlal v9.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v10.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v11.2d,v29.2s,v2.s[0] + umlal v12.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v13.2d,v29.2s,v2.s[2] + ushr v15.2d,v11.2d,#16 + umlal v6.2d,v29.2s,v2.s[3] + umlal v7.2d,v29.2s,v3.s[0] + ext v11.16b,v11.16b,v11.16b,#8 + add v11.2d,v11.2d,v15.2d + umlal v8.2d,v29.2s,v3.s[1] + ushr v11.2d,v11.2d,#16 + umlal v9.2d,v29.2s,v3.s[2] + umlal v10.2d,v29.2s,v3.s[3] + add v16.2d,v12.2d,v11.2d + ins v12.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+5] + umlal v12.2d,v28.2s,v0.s[0] + ld1 {v11.2d},[x6],#16 + umlal v13.2d,v28.2s,v0.s[1] + umlal v6.2d,v28.2s,v0.s[2] + shl v29.2d,v12.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v7.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v12.2d + umlal v8.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v9.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+6] + umlal v10.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v11.2d,v28.2s,v1.s[3] + ldr s28,[x2],#4 // *b++ + umlal v12.2d,v29.2s,v2.s[0] + umlal v13.2d,v29.2s,v2.s[1] + uxtl v28.4s,v28.4h + umlal v6.2d,v29.2s,v2.s[2] + ushr v15.2d,v12.2d,#16 + umlal v7.2d,v29.2s,v2.s[3] + umlal v8.2d,v29.2s,v3.s[0] + ext v12.16b,v12.16b,v12.16b,#8 + add v12.2d,v12.2d,v15.2d + umlal v9.2d,v29.2s,v3.s[1] + ushr v12.2d,v12.2d,#16 + umlal v10.2d,v29.2s,v3.s[2] + umlal v11.2d,v29.2s,v3.s[3] + add v16.2d,v13.2d,v12.2d + ins v13.d[0],v16.d[0] + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+6] + umlal v13.2d,v28.2s,v0.s[0] + ld1 {v12.2d},[x6],#16 + umlal v6.2d,v28.2s,v0.s[1] + umlal v7.2d,v28.2s,v0.s[2] + shl v29.2d,v13.2d,#16 + ext v29.16b,v29.16b,v29.16b,#8 + umlal v8.2d,v28.2s,v0.s[3] + add v29.2d,v29.2d,v13.2d + umlal v9.2d,v28.2s,v1.s[0] + mul v29.2s,v29.2s,v30.2s + umlal v10.2d,v28.2s,v1.s[1] + st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+7] + umlal v11.2d,v28.2s,v1.s[2] + uxtl v29.4s,v29.4h + umlal v12.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[sp] // pull smashed b[8*i+0] + umlal v13.2d,v29.2s,v2.s[0] + ld1 {v0.4s,v1.4s},[x1],#32 + umlal v6.2d,v29.2s,v2.s[1] + umlal v7.2d,v29.2s,v2.s[2] + mov v5.16b,v13.16b + ushr v5.2d,v5.2d,#16 + ext v13.16b,v13.16b,v13.16b,#8 + umlal v8.2d,v29.2s,v2.s[3] + umlal v9.2d,v29.2s,v3.s[0] + add v13.2d,v13.2d,v5.2d + umlal v10.2d,v29.2s,v3.s[1] + ushr v13.2d,v13.2d,#16 + eor v15.16b,v15.16b,v15.16b + ins v13.d[1],v15.d[0] + umlal v11.2d,v29.2s,v3.s[2] + umlal v12.2d,v29.2s,v3.s[3] + add v6.2d,v6.2d,v13.2d + st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+7] + add x10,sp,#8 // rewind + sub x8,x5,#8 + b .LNEON_8n_inner + +.align 4 +.LNEON_8n_inner: + subs x8,x8,#8 + umlal v6.2d,v28.2s,v0.s[0] + ld1 {v13.2d},[x6] + umlal v7.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+0] + umlal v8.2d,v28.2s,v0.s[2] + ld1 {v2.4s,v3.4s},[x3],#32 + umlal v9.2d,v28.2s,v0.s[3] + b.eq .LInner_jump + add x6,x6,#16 // don't advance in last iteration +.LInner_jump: + umlal v10.2d,v28.2s,v1.s[0] + umlal v11.2d,v28.2s,v1.s[1] + umlal v12.2d,v28.2s,v1.s[2] + umlal v13.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+1] + umlal v6.2d,v29.2s,v2.s[0] + umlal v7.2d,v29.2s,v2.s[1] + umlal v8.2d,v29.2s,v2.s[2] + umlal v9.2d,v29.2s,v2.s[3] + umlal v10.2d,v29.2s,v3.s[0] + umlal v11.2d,v29.2s,v3.s[1] + umlal v12.2d,v29.2s,v3.s[2] + umlal v13.2d,v29.2s,v3.s[3] + st1 {v6.2d},[x7],#16 + umlal v7.2d,v28.2s,v0.s[0] + ld1 {v6.2d},[x6] + umlal v8.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+1] + umlal v9.2d,v28.2s,v0.s[2] + b.eq .LInner_jump1 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump1: + umlal v10.2d,v28.2s,v0.s[3] + umlal v11.2d,v28.2s,v1.s[0] + umlal v12.2d,v28.2s,v1.s[1] + umlal v13.2d,v28.2s,v1.s[2] + umlal v6.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+2] + umlal v7.2d,v29.2s,v2.s[0] + umlal v8.2d,v29.2s,v2.s[1] + umlal v9.2d,v29.2s,v2.s[2] + umlal v10.2d,v29.2s,v2.s[3] + umlal v11.2d,v29.2s,v3.s[0] + umlal v12.2d,v29.2s,v3.s[1] + umlal v13.2d,v29.2s,v3.s[2] + umlal v6.2d,v29.2s,v3.s[3] + st1 {v7.2d},[x7],#16 + umlal v8.2d,v28.2s,v0.s[0] + ld1 {v7.2d},[x6] + umlal v9.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+2] + umlal v10.2d,v28.2s,v0.s[2] + b.eq .LInner_jump2 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump2: + umlal v11.2d,v28.2s,v0.s[3] + umlal v12.2d,v28.2s,v1.s[0] + umlal v13.2d,v28.2s,v1.s[1] + umlal v6.2d,v28.2s,v1.s[2] + umlal v7.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+3] + umlal v8.2d,v29.2s,v2.s[0] + umlal v9.2d,v29.2s,v2.s[1] + umlal v10.2d,v29.2s,v2.s[2] + umlal v11.2d,v29.2s,v2.s[3] + umlal v12.2d,v29.2s,v3.s[0] + umlal v13.2d,v29.2s,v3.s[1] + umlal v6.2d,v29.2s,v3.s[2] + umlal v7.2d,v29.2s,v3.s[3] + st1 {v8.2d},[x7],#16 + umlal v9.2d,v28.2s,v0.s[0] + ld1 {v8.2d},[x6] + umlal v10.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+3] + umlal v11.2d,v28.2s,v0.s[2] + b.eq .LInner_jump3 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump3: + umlal v12.2d,v28.2s,v0.s[3] + umlal v13.2d,v28.2s,v1.s[0] + umlal v6.2d,v28.2s,v1.s[1] + umlal v7.2d,v28.2s,v1.s[2] + umlal v8.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+4] + umlal v9.2d,v29.2s,v2.s[0] + umlal v10.2d,v29.2s,v2.s[1] + umlal v11.2d,v29.2s,v2.s[2] + umlal v12.2d,v29.2s,v2.s[3] + umlal v13.2d,v29.2s,v3.s[0] + umlal v6.2d,v29.2s,v3.s[1] + umlal v7.2d,v29.2s,v3.s[2] + umlal v8.2d,v29.2s,v3.s[3] + st1 {v9.2d},[x7],#16 + umlal v10.2d,v28.2s,v0.s[0] + ld1 {v9.2d},[x6] + umlal v11.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+4] + umlal v12.2d,v28.2s,v0.s[2] + b.eq .LInner_jump4 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump4: + umlal v13.2d,v28.2s,v0.s[3] + umlal v6.2d,v28.2s,v1.s[0] + umlal v7.2d,v28.2s,v1.s[1] + umlal v8.2d,v28.2s,v1.s[2] + umlal v9.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+5] + umlal v10.2d,v29.2s,v2.s[0] + umlal v11.2d,v29.2s,v2.s[1] + umlal v12.2d,v29.2s,v2.s[2] + umlal v13.2d,v29.2s,v2.s[3] + umlal v6.2d,v29.2s,v3.s[0] + umlal v7.2d,v29.2s,v3.s[1] + umlal v8.2d,v29.2s,v3.s[2] + umlal v9.2d,v29.2s,v3.s[3] + st1 {v10.2d},[x7],#16 + umlal v11.2d,v28.2s,v0.s[0] + ld1 {v10.2d},[x6] + umlal v12.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+5] + umlal v13.2d,v28.2s,v0.s[2] + b.eq .LInner_jump5 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump5: + umlal v6.2d,v28.2s,v0.s[3] + umlal v7.2d,v28.2s,v1.s[0] + umlal v8.2d,v28.2s,v1.s[1] + umlal v9.2d,v28.2s,v1.s[2] + umlal v10.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+6] + umlal v11.2d,v29.2s,v2.s[0] + umlal v12.2d,v29.2s,v2.s[1] + umlal v13.2d,v29.2s,v2.s[2] + umlal v6.2d,v29.2s,v2.s[3] + umlal v7.2d,v29.2s,v3.s[0] + umlal v8.2d,v29.2s,v3.s[1] + umlal v9.2d,v29.2s,v3.s[2] + umlal v10.2d,v29.2s,v3.s[3] + st1 {v11.2d},[x7],#16 + umlal v12.2d,v28.2s,v0.s[0] + ld1 {v11.2d},[x6] + umlal v13.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+6] + umlal v6.2d,v28.2s,v0.s[2] + b.eq .LInner_jump6 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump6: + umlal v7.2d,v28.2s,v0.s[3] + umlal v8.2d,v28.2s,v1.s[0] + umlal v9.2d,v28.2s,v1.s[1] + umlal v10.2d,v28.2s,v1.s[2] + umlal v11.2d,v28.2s,v1.s[3] + ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+7] + umlal v12.2d,v29.2s,v2.s[0] + umlal v13.2d,v29.2s,v2.s[1] + umlal v6.2d,v29.2s,v2.s[2] + umlal v7.2d,v29.2s,v2.s[3] + umlal v8.2d,v29.2s,v3.s[0] + umlal v9.2d,v29.2s,v3.s[1] + umlal v10.2d,v29.2s,v3.s[2] + umlal v11.2d,v29.2s,v3.s[3] + st1 {v12.2d},[x7],#16 + umlal v13.2d,v28.2s,v0.s[0] + ld1 {v12.2d},[x6] + umlal v6.2d,v28.2s,v0.s[1] + ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+7] + umlal v7.2d,v28.2s,v0.s[2] + b.eq .LInner_jump7 + add x6,x6,#16 // don't advance in last iteration +.LInner_jump7: + umlal v8.2d,v28.2s,v0.s[3] + umlal v9.2d,v28.2s,v1.s[0] + umlal v10.2d,v28.2s,v1.s[1] + umlal v11.2d,v28.2s,v1.s[2] + umlal v12.2d,v28.2s,v1.s[3] + b.ne .LInner_after_rewind8 + sub x1,x1,x5,lsl#2 // rewind +.LInner_after_rewind8: + umlal v13.2d,v29.2s,v2.s[0] + ld1 {v28.2s},[sp] // pull smashed b[8*i+0] + umlal v6.2d,v29.2s,v2.s[1] + ld1 {v0.4s,v1.4s},[x1],#32 + umlal v7.2d,v29.2s,v2.s[2] + add x10,sp,#8 // rewind + umlal v8.2d,v29.2s,v2.s[3] + umlal v9.2d,v29.2s,v3.s[0] + umlal v10.2d,v29.2s,v3.s[1] + umlal v11.2d,v29.2s,v3.s[2] + st1 {v13.2d},[x7],#16 + umlal v12.2d,v29.2s,v3.s[3] + + bne .LNEON_8n_inner + add x6,sp,#128 + st1 {v6.2d,v7.2d},[x7],#32 + eor v2.16b,v2.16b,v2.16b // v2 + st1 {v8.2d,v9.2d},[x7],#32 + eor v3.16b,v3.16b,v3.16b // v3 + st1 {v10.2d,v11.2d},[x7],#32 + st1 {v12.2d},[x7] + + subs x9,x9,#8 + ld1 {v6.2d,v7.2d},[x6],#32 + ld1 {v8.2d,v9.2d},[x6],#32 + ld1 {v10.2d,v11.2d},[x6],#32 + ld1 {v12.2d,v13.2d},[x6],#32 + + b.eq .LInner_8n_jump_2steps + sub x3,x3,x5,lsl#2 // rewind + b .LNEON_8n_outer + +.LInner_8n_jump_2steps: + add x7,sp,#128 + st1 {v2.2d,v3.2d}, [sp],#32 // start wiping stack frame + mov v5.16b,v6.16b + ushr v15.2d,v6.2d,#16 + ext v6.16b,v6.16b,v6.16b,#8 + st1 {v2.2d,v3.2d}, [sp],#32 + add v6.2d,v6.2d,v15.2d + st1 {v2.2d,v3.2d}, [sp],#32 + ushr v15.2d,v6.2d,#16 + st1 {v2.2d,v3.2d}, [sp],#32 + zip1 v6.4h,v5.4h,v6.4h + ins v15.d[1],v14.d[0] + + mov x8,x5 + b .LNEON_tail_entry + +.align 4 +.LNEON_tail: + add v6.2d,v6.2d,v15.2d + mov v5.16b,v6.16b + ushr v15.2d,v6.2d,#16 + ext v6.16b,v6.16b,v6.16b,#8 + ld1 {v8.2d,v9.2d}, [x6],#32 + add v6.2d,v6.2d,v15.2d + ld1 {v10.2d,v11.2d}, [x6],#32 + ushr v15.2d,v6.2d,#16 + ld1 {v12.2d,v13.2d}, [x6],#32 + zip1 v6.4h,v5.4h,v6.4h + ins v15.d[1],v14.d[0] + +.LNEON_tail_entry: + add v7.2d,v7.2d,v15.2d + st1 {v6.s}[0], [x7],#4 + ushr v15.2d,v7.2d,#16 + mov v5.16b,v7.16b + ext v7.16b,v7.16b,v7.16b,#8 + add v7.2d,v7.2d,v15.2d + ushr v15.2d,v7.2d,#16 + zip1 v7.4h,v5.4h,v7.4h + ins v15.d[1],v14.d[0] + add v8.2d,v8.2d,v15.2d + st1 {v7.s}[0], [x7],#4 + ushr v15.2d,v8.2d,#16 + mov v5.16b,v8.16b + ext v8.16b,v8.16b,v8.16b,#8 + add v8.2d,v8.2d,v15.2d + ushr v15.2d,v8.2d,#16 + zip1 v8.4h,v5.4h,v8.4h + ins v15.d[1],v14.d[0] + add v9.2d,v9.2d,v15.2d + st1 {v8.s}[0], [x7],#4 + ushr v15.2d,v9.2d,#16 + mov v5.16b,v9.16b + ext v9.16b,v9.16b,v9.16b,#8 + add v9.2d,v9.2d,v15.2d + ushr v15.2d,v9.2d,#16 + zip1 v9.4h,v5.4h,v9.4h + ins v15.d[1],v14.d[0] + add v10.2d,v10.2d,v15.2d + st1 {v9.s}[0], [x7],#4 + ushr v15.2d,v10.2d,#16 + mov v5.16b,v10.16b + ext v10.16b,v10.16b,v10.16b,#8 + add v10.2d,v10.2d,v15.2d + ushr v15.2d,v10.2d,#16 + zip1 v10.4h,v5.4h,v10.4h + ins v15.d[1],v14.d[0] + add v11.2d,v11.2d,v15.2d + st1 {v10.s}[0], [x7],#4 + ushr v15.2d,v11.2d,#16 + mov v5.16b,v11.16b + ext v11.16b,v11.16b,v11.16b,#8 + add v11.2d,v11.2d,v15.2d + ushr v15.2d,v11.2d,#16 + zip1 v11.4h,v5.4h,v11.4h + ins v15.d[1],v14.d[0] + add v12.2d,v12.2d,v15.2d + st1 {v11.s}[0], [x7],#4 + ushr v15.2d,v12.2d,#16 + mov v5.16b,v12.16b + ext v12.16b,v12.16b,v12.16b,#8 + add v12.2d,v12.2d,v15.2d + ushr v15.2d,v12.2d,#16 + zip1 v12.4h,v5.4h,v12.4h + ins v15.d[1],v14.d[0] + add v13.2d,v13.2d,v15.2d + st1 {v12.s}[0], [x7],#4 + ushr v15.2d,v13.2d,#16 + mov v5.16b,v13.16b + ext v13.16b,v13.16b,v13.16b,#8 + add v13.2d,v13.2d,v15.2d + ushr v15.2d,v13.2d,#16 + zip1 v13.4h,v5.4h,v13.4h + ins v15.d[1],v14.d[0] + ld1 {v6.2d,v7.2d}, [x6],#32 + subs x8,x8,#8 + st1 {v13.s}[0], [x7],#4 + bne .LNEON_tail + + st1 {v15.s}[0], [x7],#4 // top-most bit + sub x3,x3,x5,lsl#2 // rewind x3 + subs x1,sp,#0 // clear carry flag + add x2,sp,x5,lsl#2 + +.LNEON_sub: + ldp w4,w5,[x1],#8 + ldp w6,w7,[x1],#8 + ldp w8,w9,[x3],#8 + ldp w10,w11,[x3],#8 + sbcs w8,w4,w8 + sbcs w9,w5,w9 + sbcs w10,w6,w10 + sbcs w11,w7,w11 + sub x17,x2,x1 + stp w8,w9,[x0],#8 + stp w10,w11,[x0],#8 + cbnz x17,.LNEON_sub + + ldr w10, [x1] // load top-most bit + mov x11,sp + eor v0.16b,v0.16b,v0.16b + sub x11,x2,x11 // this is num*4 + eor v1.16b,v1.16b,v1.16b + mov x1,sp + sub x0,x0,x11 // rewind x0 + mov x3,x2 // second 3/4th of frame + sbcs w10,w10,wzr // result is carry flag + +.LNEON_copy_n_zap: + ldp w4,w5,[x1],#8 + ldp w6,w7,[x1],#8 + ldp w8,w9,[x0],#8 + ldp w10,w11,[x0] + sub x0,x0,#8 + b.cs .LCopy_1 + mov w8,w4 + mov w9,w5 + mov w10,w6 + mov w11,w7 +.LCopy_1: + st1 {v0.2d,v1.2d}, [x3],#32 // wipe + st1 {v0.2d,v1.2d}, [x3],#32 // wipe + ldp w4,w5,[x1],#8 + ldp w6,w7,[x1],#8 + stp w8,w9,[x0],#8 + stp w10,w11,[x0],#8 + sub x1,x1,#32 + ldp w8,w9,[x0],#8 + ldp w10,w11,[x0] + sub x0,x0,#8 + b.cs .LCopy_2 + mov w8, w4 + mov w9, w5 + mov w10, w6 + mov w11, w7 +.LCopy_2: + st1 {v0.2d,v1.2d}, [x1],#32 // wipe + st1 {v0.2d,v1.2d}, [x3],#32 // wipe + sub x17,x2,x1 // preserves carry + stp w8,w9,[x0],#8 + stp w10,w11,[x0],#8 + cbnz x17,.LNEON_copy_n_zap + + mov sp,x16 + ldp d14,d15,[sp,#64] + ldp d12,d13,[sp,#48] + ldp d10,d11,[sp,#32] + ldp d8,d9,[sp,#16] + ldr x29,[sp],#80 + ret // bx lr + +.size bn_mul8x_mont_neon,.-bn_mul8x_mont_neon +.type __bn_sqr8x_mont,%function +.align 5 +__bn_sqr8x_mont: + cmp x1,x2 + b.ne __bn_mul4x_mont +.Lsqr8x_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + stp x0,x3,[sp,#96] // offload rp and np + + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + ldp x10,x11,[x1,#8*4] + ldp x12,x13,[x1,#8*6] + + sub x2,sp,x5,lsl#4 + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + mov sp,x2 // alloca + sub x27,x5,#8*8 + b .Lsqr8x_zero_start + +.Lsqr8x_zero: + sub x27,x27,#8*8 + stp xzr,xzr,[x2,#8*0] + stp xzr,xzr,[x2,#8*2] + stp xzr,xzr,[x2,#8*4] + stp xzr,xzr,[x2,#8*6] +.Lsqr8x_zero_start: + stp xzr,xzr,[x2,#8*8] + stp xzr,xzr,[x2,#8*10] + stp xzr,xzr,[x2,#8*12] + stp xzr,xzr,[x2,#8*14] + add x2,x2,#8*16 + cbnz x27,.Lsqr8x_zero + + add x3,x1,x5 + add x1,x1,#8*8 + mov x19,xzr + mov x20,xzr + mov x21,xzr + mov x22,xzr + mov x23,xzr + mov x24,xzr + mov x25,xzr + mov x26,xzr + mov x2,sp + str x4,[x29,#112] // offload n0 + + // Multiply everything but a[i]*a[i] +.align 4 +.Lsqr8x_outer_loop: + // a[1]a[0] (i) + // a[2]a[0] + // a[3]a[0] + // a[4]a[0] + // a[5]a[0] + // a[6]a[0] + // a[7]a[0] + // a[2]a[1] (ii) + // a[3]a[1] + // a[4]a[1] + // a[5]a[1] + // a[6]a[1] + // a[7]a[1] + // a[3]a[2] (iii) + // a[4]a[2] + // a[5]a[2] + // a[6]a[2] + // a[7]a[2] + // a[4]a[3] (iv) + // a[5]a[3] + // a[6]a[3] + // a[7]a[3] + // a[5]a[4] (v) + // a[6]a[4] + // a[7]a[4] + // a[6]a[5] (vi) + // a[7]a[5] + // a[7]a[6] (vii) + + mul x14,x7,x6 // lo(a[1..7]*a[0]) (i) + mul x15,x8,x6 + mul x16,x9,x6 + mul x17,x10,x6 + adds x20,x20,x14 // t[1]+lo(a[1]*a[0]) + mul x14,x11,x6 + adcs x21,x21,x15 + mul x15,x12,x6 + adcs x22,x22,x16 + mul x16,x13,x6 + adcs x23,x23,x17 + umulh x17,x7,x6 // hi(a[1..7]*a[0]) + adcs x24,x24,x14 + umulh x14,x8,x6 + adcs x25,x25,x15 + umulh x15,x9,x6 + adcs x26,x26,x16 + umulh x16,x10,x6 + stp x19,x20,[x2],#8*2 // t[0..1] + adc x19,xzr,xzr // t[8] + adds x21,x21,x17 // t[2]+lo(a[1]*a[0]) + umulh x17,x11,x6 + adcs x22,x22,x14 + umulh x14,x12,x6 + adcs x23,x23,x15 + umulh x15,x13,x6 + adcs x24,x24,x16 + mul x16,x8,x7 // lo(a[2..7]*a[1]) (ii) + adcs x25,x25,x17 + mul x17,x9,x7 + adcs x26,x26,x14 + mul x14,x10,x7 + adc x19,x19,x15 + + mul x15,x11,x7 + adds x22,x22,x16 + mul x16,x12,x7 + adcs x23,x23,x17 + mul x17,x13,x7 + adcs x24,x24,x14 + umulh x14,x8,x7 // hi(a[2..7]*a[1]) + adcs x25,x25,x15 + umulh x15,x9,x7 + adcs x26,x26,x16 + umulh x16,x10,x7 + adcs x19,x19,x17 + umulh x17,x11,x7 + stp x21,x22,[x2],#8*2 // t[2..3] + adc x20,xzr,xzr // t[9] + adds x23,x23,x14 + umulh x14,x12,x7 + adcs x24,x24,x15 + umulh x15,x13,x7 + adcs x25,x25,x16 + mul x16,x9,x8 // lo(a[3..7]*a[2]) (iii) + adcs x26,x26,x17 + mul x17,x10,x8 + adcs x19,x19,x14 + mul x14,x11,x8 + adc x20,x20,x15 + + mul x15,x12,x8 + adds x24,x24,x16 + mul x16,x13,x8 + adcs x25,x25,x17 + umulh x17,x9,x8 // hi(a[3..7]*a[2]) + adcs x26,x26,x14 + umulh x14,x10,x8 + adcs x19,x19,x15 + umulh x15,x11,x8 + adcs x20,x20,x16 + umulh x16,x12,x8 + stp x23,x24,[x2],#8*2 // t[4..5] + adc x21,xzr,xzr // t[10] + adds x25,x25,x17 + umulh x17,x13,x8 + adcs x26,x26,x14 + mul x14,x10,x9 // lo(a[4..7]*a[3]) (iv) + adcs x19,x19,x15 + mul x15,x11,x9 + adcs x20,x20,x16 + mul x16,x12,x9 + adc x21,x21,x17 + + mul x17,x13,x9 + adds x26,x26,x14 + umulh x14,x10,x9 // hi(a[4..7]*a[3]) + adcs x19,x19,x15 + umulh x15,x11,x9 + adcs x20,x20,x16 + umulh x16,x12,x9 + adcs x21,x21,x17 + umulh x17,x13,x9 + stp x25,x26,[x2],#8*2 // t[6..7] + adc x22,xzr,xzr // t[11] + adds x19,x19,x14 + mul x14,x11,x10 // lo(a[5..7]*a[4]) (v) + adcs x20,x20,x15 + mul x15,x12,x10 + adcs x21,x21,x16 + mul x16,x13,x10 + adc x22,x22,x17 + + umulh x17,x11,x10 // hi(a[5..7]*a[4]) + adds x20,x20,x14 + umulh x14,x12,x10 + adcs x21,x21,x15 + umulh x15,x13,x10 + adcs x22,x22,x16 + mul x16,x12,x11 // lo(a[6..7]*a[5]) (vi) + adc x23,xzr,xzr // t[12] + adds x21,x21,x17 + mul x17,x13,x11 + adcs x22,x22,x14 + umulh x14,x12,x11 // hi(a[6..7]*a[5]) + adc x23,x23,x15 + + umulh x15,x13,x11 + adds x22,x22,x16 + mul x16,x13,x12 // lo(a[7]*a[6]) (vii) + adcs x23,x23,x17 + umulh x17,x13,x12 // hi(a[7]*a[6]) + adc x24,xzr,xzr // t[13] + adds x23,x23,x14 + sub x27,x3,x1 // done yet? + adc x24,x24,x15 + + adds x24,x24,x16 + sub x14,x3,x5 // rewinded ap + adc x25,xzr,xzr // t[14] + add x25,x25,x17 + + cbz x27,.Lsqr8x_outer_break + + mov x4,x6 + ldp x6,x7,[x2,#8*0] + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + adds x19,x19,x6 + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x0,x1 + adcs x26,xzr,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved below + mov x27,#-8*8 + + // a[8]a[0] + // a[9]a[0] + // a[a]a[0] + // a[b]a[0] + // a[c]a[0] + // a[d]a[0] + // a[e]a[0] + // a[f]a[0] + // a[8]a[1] + // a[f]a[1]........................ + // a[8]a[2] + // a[f]a[2]........................ + // a[8]a[3] + // a[f]a[3]........................ + // a[8]a[4] + // a[f]a[4]........................ + // a[8]a[5] + // a[f]a[5]........................ + // a[8]a[6] + // a[f]a[6]........................ + // a[8]a[7] + // a[f]a[7]........................ +.Lsqr8x_mul: + mul x14,x6,x4 + adc x28,xzr,xzr // carry bit, modulo-scheduled + mul x15,x7,x4 + add x27,x27,#8 + mul x16,x8,x4 + mul x17,x9,x4 + adds x19,x19,x14 + mul x14,x10,x4 + adcs x20,x20,x15 + mul x15,x11,x4 + adcs x21,x21,x16 + mul x16,x12,x4 + adcs x22,x22,x17 + mul x17,x13,x4 + adcs x23,x23,x14 + umulh x14,x6,x4 + adcs x24,x24,x15 + umulh x15,x7,x4 + adcs x25,x25,x16 + umulh x16,x8,x4 + adcs x26,x26,x17 + umulh x17,x9,x4 + adc x28,x28,xzr + str x19,[x2],#8 + adds x19,x20,x14 + umulh x14,x10,x4 + adcs x20,x21,x15 + umulh x15,x11,x4 + adcs x21,x22,x16 + umulh x16,x12,x4 + adcs x22,x23,x17 + umulh x17,x13,x4 + ldr x4,[x0,x27] + adcs x23,x24,x14 + adcs x24,x25,x15 + adcs x25,x26,x16 + adcs x26,x28,x17 + //adc x28,xzr,xzr // moved above + cbnz x27,.Lsqr8x_mul + // note that carry flag is guaranteed + // to be zero at this point + cmp x1,x3 // done yet? + b.eq .Lsqr8x_break + + ldp x6,x7,[x2,#8*0] + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + adds x19,x19,x6 + ldur x4,[x0,#-8*8] + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x27,#-8*8 + adcs x26,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved above + b .Lsqr8x_mul + +.align 4 +.Lsqr8x_break: + ldp x6,x7,[x0,#8*0] + add x1,x0,#8*8 + ldp x8,x9,[x0,#8*2] + sub x14,x3,x1 // is it last iteration? + ldp x10,x11,[x0,#8*4] + sub x15,x2,x14 + ldp x12,x13,[x0,#8*6] + cbz x14,.Lsqr8x_outer_loop + + stp x19,x20,[x2,#8*0] + ldp x19,x20,[x15,#8*0] + stp x21,x22,[x2,#8*2] + ldp x21,x22,[x15,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[x15,#8*4] + stp x25,x26,[x2,#8*6] + mov x2,x15 + ldp x25,x26,[x15,#8*6] + b .Lsqr8x_outer_loop + +.align 4 +.Lsqr8x_outer_break: + // Now multiply above result by 2 and add a[n-1]*a[n-1]|...|a[0]*a[0] + ldp x7,x9,[x14,#8*0] // recall that x14 is &a[0] + ldp x15,x16,[sp,#8*1] + ldp x11,x13,[x14,#8*2] + add x1,x14,#8*4 + ldp x17,x14,[sp,#8*3] + + stp x19,x20,[x2,#8*0] + mul x19,x7,x7 + stp x21,x22,[x2,#8*2] + umulh x7,x7,x7 + stp x23,x24,[x2,#8*4] + mul x8,x9,x9 + stp x25,x26,[x2,#8*6] + mov x2,sp + umulh x9,x9,x9 + adds x20,x7,x15,lsl#1 + extr x15,x16,x15,#63 + sub x27,x5,#8*4 + +.Lsqr4x_shift_n_add: + adcs x21,x8,x15 + extr x16,x17,x16,#63 + sub x27,x27,#8*4 + adcs x22,x9,x16 + ldp x15,x16,[x2,#8*5] + mul x10,x11,x11 + ldp x7,x9,[x1],#8*2 + umulh x11,x11,x11 + mul x12,x13,x13 + umulh x13,x13,x13 + extr x17,x14,x17,#63 + stp x19,x20,[x2,#8*0] + adcs x23,x10,x17 + extr x14,x15,x14,#63 + stp x21,x22,[x2,#8*2] + adcs x24,x11,x14 + ldp x17,x14,[x2,#8*7] + extr x15,x16,x15,#63 + adcs x25,x12,x15 + extr x16,x17,x16,#63 + adcs x26,x13,x16 + ldp x15,x16,[x2,#8*9] + mul x6,x7,x7 + ldp x11,x13,[x1],#8*2 + umulh x7,x7,x7 + mul x8,x9,x9 + umulh x9,x9,x9 + stp x23,x24,[x2,#8*4] + extr x17,x14,x17,#63 + stp x25,x26,[x2,#8*6] + add x2,x2,#8*8 + adcs x19,x6,x17 + extr x14,x15,x14,#63 + adcs x20,x7,x14 + ldp x17,x14,[x2,#8*3] + extr x15,x16,x15,#63 + cbnz x27,.Lsqr4x_shift_n_add + ldp x1,x4,[x29,#104] // pull np and n0 + + adcs x21,x8,x15 + extr x16,x17,x16,#63 + adcs x22,x9,x16 + ldp x15,x16,[x2,#8*5] + mul x10,x11,x11 + umulh x11,x11,x11 + stp x19,x20,[x2,#8*0] + mul x12,x13,x13 + umulh x13,x13,x13 + stp x21,x22,[x2,#8*2] + extr x17,x14,x17,#63 + adcs x23,x10,x17 + extr x14,x15,x14,#63 + ldp x19,x20,[sp,#8*0] + adcs x24,x11,x14 + extr x15,x16,x15,#63 + ldp x6,x7,[x1,#8*0] + adcs x25,x12,x15 + extr x16,xzr,x16,#63 + ldp x8,x9,[x1,#8*2] + adc x26,x13,x16 + ldp x10,x11,[x1,#8*4] + + // Reduce by 512 bits per iteration + mul x28,x4,x19 // t[0]*n0 + ldp x12,x13,[x1,#8*6] + add x3,x1,x5 + ldp x21,x22,[sp,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[sp,#8*4] + stp x25,x26,[x2,#8*6] + ldp x25,x26,[sp,#8*6] + add x1,x1,#8*8 + mov x30,xzr // initial top-most carry + mov x2,sp + mov x27,#8 + +.Lsqr8x_reduction: + // (*) mul x14,x6,x28 // lo(n[0-7])*lo(t[0]*n0) + mul x15,x7,x28 + sub x27,x27,#1 + mul x16,x8,x28 + str x28,[x2],#8 // put aside t[0]*n0 for tail processing + mul x17,x9,x28 + // (*) adds xzr,x19,x14 + subs xzr,x19,#1 // (*) + mul x14,x10,x28 + adcs x19,x20,x15 + mul x15,x11,x28 + adcs x20,x21,x16 + mul x16,x12,x28 + adcs x21,x22,x17 + mul x17,x13,x28 + adcs x22,x23,x14 + umulh x14,x6,x28 // hi(n[0-7])*lo(t[0]*n0) + adcs x23,x24,x15 + umulh x15,x7,x28 + adcs x24,x25,x16 + umulh x16,x8,x28 + adcs x25,x26,x17 + umulh x17,x9,x28 + adc x26,xzr,xzr + adds x19,x19,x14 + umulh x14,x10,x28 + adcs x20,x20,x15 + umulh x15,x11,x28 + adcs x21,x21,x16 + umulh x16,x12,x28 + adcs x22,x22,x17 + umulh x17,x13,x28 + mul x28,x4,x19 // next t[0]*n0 + adcs x23,x23,x14 + adcs x24,x24,x15 + adcs x25,x25,x16 + adc x26,x26,x17 + cbnz x27,.Lsqr8x_reduction + + ldp x14,x15,[x2,#8*0] + ldp x16,x17,[x2,#8*2] + mov x0,x2 + sub x27,x3,x1 // done yet? + adds x19,x19,x14 + adcs x20,x20,x15 + ldp x14,x15,[x2,#8*4] + adcs x21,x21,x16 + adcs x22,x22,x17 + ldp x16,x17,[x2,#8*6] + adcs x23,x23,x14 + adcs x24,x24,x15 + adcs x25,x25,x16 + adcs x26,x26,x17 + //adc x28,xzr,xzr // moved below + cbz x27,.Lsqr8x8_post_condition + + ldur x4,[x2,#-8*8] + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + ldp x10,x11,[x1,#8*4] + mov x27,#-8*8 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + +.Lsqr8x_tail: + mul x14,x6,x4 + adc x28,xzr,xzr // carry bit, modulo-scheduled + mul x15,x7,x4 + add x27,x27,#8 + mul x16,x8,x4 + mul x17,x9,x4 + adds x19,x19,x14 + mul x14,x10,x4 + adcs x20,x20,x15 + mul x15,x11,x4 + adcs x21,x21,x16 + mul x16,x12,x4 + adcs x22,x22,x17 + mul x17,x13,x4 + adcs x23,x23,x14 + umulh x14,x6,x4 + adcs x24,x24,x15 + umulh x15,x7,x4 + adcs x25,x25,x16 + umulh x16,x8,x4 + adcs x26,x26,x17 + umulh x17,x9,x4 + adc x28,x28,xzr + str x19,[x2],#8 + adds x19,x20,x14 + umulh x14,x10,x4 + adcs x20,x21,x15 + umulh x15,x11,x4 + adcs x21,x22,x16 + umulh x16,x12,x4 + adcs x22,x23,x17 + umulh x17,x13,x4 + ldr x4,[x0,x27] + adcs x23,x24,x14 + adcs x24,x25,x15 + adcs x25,x26,x16 + adcs x26,x28,x17 + //adc x28,xzr,xzr // moved above + cbnz x27,.Lsqr8x_tail + // note that carry flag is guaranteed + // to be zero at this point + ldp x6,x7,[x2,#8*0] + sub x27,x3,x1 // done yet? + sub x16,x3,x5 // rewinded np + ldp x8,x9,[x2,#8*2] + ldp x10,x11,[x2,#8*4] + ldp x12,x13,[x2,#8*6] + cbz x27,.Lsqr8x_tail_break + + ldur x4,[x0,#-8*8] + adds x19,x19,x6 + adcs x20,x20,x7 + ldp x6,x7,[x1,#8*0] + adcs x21,x21,x8 + adcs x22,x22,x9 + ldp x8,x9,[x1,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x1,#8*4] + adcs x25,x25,x12 + mov x27,#-8*8 + adcs x26,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + //adc x28,xzr,xzr // moved above + b .Lsqr8x_tail + +.align 4 +.Lsqr8x_tail_break: + ldr x4,[x29,#112] // pull n0 + add x27,x2,#8*8 // end of current t[num] window + + subs xzr,x30,#1 // "move" top-most carry to carry bit + adcs x14,x19,x6 + adcs x15,x20,x7 + ldp x19,x20,[x0,#8*0] + adcs x21,x21,x8 + ldp x6,x7,[x16,#8*0] // recall that x16 is &n[0] + adcs x22,x22,x9 + ldp x8,x9,[x16,#8*2] + adcs x23,x23,x10 + adcs x24,x24,x11 + ldp x10,x11,[x16,#8*4] + adcs x25,x25,x12 + adcs x26,x26,x13 + ldp x12,x13,[x16,#8*6] + add x1,x16,#8*8 + adc x30,xzr,xzr // top-most carry + mul x28,x4,x19 + stp x14,x15,[x2,#8*0] + stp x21,x22,[x2,#8*2] + ldp x21,x22,[x0,#8*2] + stp x23,x24,[x2,#8*4] + ldp x23,x24,[x0,#8*4] + cmp x27,x29 // did we hit the bottom? + stp x25,x26,[x2,#8*6] + mov x2,x0 // slide the window + ldp x25,x26,[x0,#8*6] + mov x27,#8 + b.ne .Lsqr8x_reduction + + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + ldr x0,[x29,#96] // pull rp + add x2,x2,#8*8 + subs x14,x19,x6 + sbcs x15,x20,x7 + sub x27,x5,#8*8 + mov x3,x0 // x0 copy + +.Lsqr8x_sub: + sbcs x16,x21,x8 + ldp x6,x7,[x1,#8*0] + sbcs x17,x22,x9 + stp x14,x15,[x0,#8*0] + sbcs x14,x23,x10 + ldp x8,x9,[x1,#8*2] + sbcs x15,x24,x11 + stp x16,x17,[x0,#8*2] + sbcs x16,x25,x12 + ldp x10,x11,[x1,#8*4] + sbcs x17,x26,x13 + ldp x12,x13,[x1,#8*6] + add x1,x1,#8*8 + ldp x19,x20,[x2,#8*0] + sub x27,x27,#8*8 + ldp x21,x22,[x2,#8*2] + ldp x23,x24,[x2,#8*4] + ldp x25,x26,[x2,#8*6] + add x2,x2,#8*8 + stp x14,x15,[x0,#8*4] + sbcs x14,x19,x6 + stp x16,x17,[x0,#8*6] + add x0,x0,#8*8 + sbcs x15,x20,x7 + cbnz x27,.Lsqr8x_sub + + sbcs x16,x21,x8 + mov x2,sp + add x1,sp,x5 + ldp x6,x7,[x3,#8*0] + sbcs x17,x22,x9 + stp x14,x15,[x0,#8*0] + sbcs x14,x23,x10 + ldp x8,x9,[x3,#8*2] + sbcs x15,x24,x11 + stp x16,x17,[x0,#8*2] + sbcs x16,x25,x12 + ldp x19,x20,[x1,#8*0] + sbcs x17,x26,x13 + ldp x21,x22,[x1,#8*2] + sbcs xzr,x30,xzr // did it borrow? + ldr x30,[x29,#8] // pull return address + stp x14,x15,[x0,#8*4] + stp x16,x17,[x0,#8*6] + + sub x27,x5,#8*4 +.Lsqr4x_cond_copy: + sub x27,x27,#8*4 + csel x14,x19,x6,lo + stp xzr,xzr,[x2,#8*0] + csel x15,x20,x7,lo + ldp x6,x7,[x3,#8*4] + ldp x19,x20,[x1,#8*4] + csel x16,x21,x8,lo + stp xzr,xzr,[x2,#8*2] + add x2,x2,#8*4 + csel x17,x22,x9,lo + ldp x8,x9,[x3,#8*6] + ldp x21,x22,[x1,#8*6] + add x1,x1,#8*4 + stp x14,x15,[x3,#8*0] + stp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + stp xzr,xzr,[x1,#8*0] + stp xzr,xzr,[x1,#8*2] + cbnz x27,.Lsqr4x_cond_copy + + csel x14,x19,x6,lo + stp xzr,xzr,[x2,#8*0] + csel x15,x20,x7,lo + stp xzr,xzr,[x2,#8*2] + csel x16,x21,x8,lo + csel x17,x22,x9,lo + stp x14,x15,[x3,#8*0] + stp x16,x17,[x3,#8*2] + + b .Lsqr8x_done + +.align 4 +.Lsqr8x8_post_condition: + adc x28,xzr,xzr + ldr x30,[x29,#8] // pull return address + // x19-7,x28 hold result, x6-7 hold modulus + subs x6,x19,x6 + ldr x1,[x29,#96] // pull rp + sbcs x7,x20,x7 + stp xzr,xzr,[sp,#8*0] + sbcs x8,x21,x8 + stp xzr,xzr,[sp,#8*2] + sbcs x9,x22,x9 + stp xzr,xzr,[sp,#8*4] + sbcs x10,x23,x10 + stp xzr,xzr,[sp,#8*6] + sbcs x11,x24,x11 + stp xzr,xzr,[sp,#8*8] + sbcs x12,x25,x12 + stp xzr,xzr,[sp,#8*10] + sbcs x13,x26,x13 + stp xzr,xzr,[sp,#8*12] + sbcs x28,x28,xzr // did it borrow? + stp xzr,xzr,[sp,#8*14] + + // x6-7 hold result-modulus + csel x6,x19,x6,lo + csel x7,x20,x7,lo + csel x8,x21,x8,lo + csel x9,x22,x9,lo + stp x6,x7,[x1,#8*0] + csel x10,x23,x10,lo + csel x11,x24,x11,lo + stp x8,x9,[x1,#8*2] + csel x12,x25,x12,lo + csel x13,x26,x13,lo + stp x10,x11,[x1,#8*4] + stp x12,x13,[x1,#8*6] + +.Lsqr8x_done: + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldr x29,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size __bn_sqr8x_mont,.-__bn_sqr8x_mont +.type __bn_mul4x_mont,%function +.align 5 +__bn_mul4x_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + + sub x26,sp,x5,lsl#3 + lsl x5,x5,#3 + ldr x4,[x4] // *n0 + sub sp,x26,#8*4 // alloca + + add x10,x2,x5 + add x27,x1,x5 + stp x0,x10,[x29,#96] // offload rp and &b[num] + + ldr x24,[x2,#8*0] // b[0] + ldp x6,x7,[x1,#8*0] // a[0..3] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + mov x19,xzr + mov x20,xzr + mov x21,xzr + mov x22,xzr + ldp x14,x15,[x3,#8*0] // n[0..3] + ldp x16,x17,[x3,#8*2] + adds x3,x3,#8*4 // clear carry bit + mov x0,xzr + mov x28,#0 + mov x26,sp + +.Loop_mul4x_1st_reduction: + mul x10,x6,x24 // lo(a[0..3]*b[0]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[0..3]*b[0]) + adcs x20,x20,x11 + mul x25,x19,x4 // t[0]*n0 + adcs x21,x21,x12 + umulh x11,x7,x24 + adcs x22,x22,x13 + umulh x12,x8,x24 + adc x23,xzr,xzr + umulh x13,x9,x24 + ldr x24,[x2,x28] // next b[i] (or b[0]) + adds x20,x20,x10 + // (*) mul x10,x14,x25 // lo(n[0..3]*t[0]*n0) + str x25,[x26],#8 // put aside t[0]*n0 for tail processing + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + // (*) adds xzr,x19,x10 + subs xzr,x19,#1 // (*) + umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0) + adcs x19,x20,x11 + umulh x11,x15,x25 + adcs x20,x21,x12 + umulh x12,x16,x25 + adcs x21,x22,x13 + umulh x13,x17,x25 + adcs x22,x23,x0 + adc x0,xzr,xzr + adds x19,x19,x10 + sub x10,x27,x1 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_1st_reduction + + cbz x10,.Lmul4x4_post_condition + + ldp x6,x7,[x1,#8*0] // a[4..7] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + ldr x25,[sp] // a[0]*n0 + ldp x14,x15,[x3,#8*0] // n[4..7] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + +.Loop_mul4x_1st_tail: + mul x10,x6,x24 // lo(a[4..7]*b[i]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[4..7]*b[i]) + adcs x20,x20,x11 + umulh x11,x7,x24 + adcs x21,x21,x12 + umulh x12,x8,x24 + adcs x22,x22,x13 + umulh x13,x9,x24 + adc x23,xzr,xzr + ldr x24,[x2,x28] // next b[i] (or b[0]) + adds x20,x20,x10 + mul x10,x14,x25 // lo(n[4..7]*a[0]*n0) + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + adds x19,x19,x10 + umulh x10,x14,x25 // hi(n[4..7]*a[0]*n0) + adcs x20,x20,x11 + umulh x11,x15,x25 + adcs x21,x21,x12 + umulh x12,x16,x25 + adcs x22,x22,x13 + adcs x23,x23,x0 + umulh x13,x17,x25 + adc x0,xzr,xzr + ldr x25,[sp,x28] // next t[0]*n0 + str x19,[x26],#8 // result!!! + adds x19,x20,x10 + sub x10,x27,x1 // done yet? + adcs x20,x21,x11 + adcs x21,x22,x12 + adcs x22,x23,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_1st_tail + + sub x11,x27,x5 // rewinded x1 + cbz x10,.Lmul4x_proceed + + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + ldp x14,x15,[x3,#8*0] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + b .Loop_mul4x_1st_tail + +.align 5 +.Lmul4x_proceed: + ldr x24,[x2,#8*4]! // *++b + adc x30,x0,xzr + ldp x6,x7,[x11,#8*0] // a[0..3] + sub x3,x3,x5 // rewind np + ldp x8,x9,[x11,#8*2] + add x1,x11,#8*4 + + stp x19,x20,[x26,#8*0] // result!!! + ldp x19,x20,[sp,#8*4] // t[0..3] + stp x21,x22,[x26,#8*2] // result!!! + ldp x21,x22,[sp,#8*6] + + ldp x14,x15,[x3,#8*0] // n[0..3] + mov x26,sp + ldp x16,x17,[x3,#8*2] + adds x3,x3,#8*4 // clear carry bit + mov x0,xzr + +.align 4 +.Loop_mul4x_reduction: + mul x10,x6,x24 // lo(a[0..3]*b[4]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[0..3]*b[4]) + adcs x20,x20,x11 + mul x25,x19,x4 // t[0]*n0 + adcs x21,x21,x12 + umulh x11,x7,x24 + adcs x22,x22,x13 + umulh x12,x8,x24 + adc x23,xzr,xzr + umulh x13,x9,x24 + ldr x24,[x2,x28] // next b[i] + adds x20,x20,x10 + // (*) mul x10,x14,x25 + str x25,[x26],#8 // put aside t[0]*n0 for tail processing + adcs x21,x21,x11 + mul x11,x15,x25 // lo(n[0..3]*t[0]*n0 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + // (*) adds xzr,x19,x10 + subs xzr,x19,#1 // (*) + umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0 + adcs x19,x20,x11 + umulh x11,x15,x25 + adcs x20,x21,x12 + umulh x12,x16,x25 + adcs x21,x22,x13 + umulh x13,x17,x25 + adcs x22,x23,x0 + adc x0,xzr,xzr + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_reduction + + adc x0,x0,xzr + ldp x10,x11,[x26,#8*4] // t[4..7] + ldp x12,x13,[x26,#8*6] + ldp x6,x7,[x1,#8*0] // a[4..7] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + + ldr x25,[sp] // t[0]*n0 + ldp x14,x15,[x3,#8*0] // n[4..7] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + +.align 4 +.Loop_mul4x_tail: + mul x10,x6,x24 // lo(a[4..7]*b[4]) + adc x0,x0,xzr // modulo-scheduled + mul x11,x7,x24 + add x28,x28,#8 + mul x12,x8,x24 + and x28,x28,#31 + mul x13,x9,x24 + adds x19,x19,x10 + umulh x10,x6,x24 // hi(a[4..7]*b[4]) + adcs x20,x20,x11 + umulh x11,x7,x24 + adcs x21,x21,x12 + umulh x12,x8,x24 + adcs x22,x22,x13 + umulh x13,x9,x24 + adc x23,xzr,xzr + ldr x24,[x2,x28] // next b[i] + adds x20,x20,x10 + mul x10,x14,x25 // lo(n[4..7]*t[0]*n0) + adcs x21,x21,x11 + mul x11,x15,x25 + adcs x22,x22,x12 + mul x12,x16,x25 + adc x23,x23,x13 // can't overflow + mul x13,x17,x25 + adds x19,x19,x10 + umulh x10,x14,x25 // hi(n[4..7]*t[0]*n0) + adcs x20,x20,x11 + umulh x11,x15,x25 + adcs x21,x21,x12 + umulh x12,x16,x25 + adcs x22,x22,x13 + umulh x13,x17,x25 + adcs x23,x23,x0 + ldr x25,[sp,x28] // next a[0]*n0 + adc x0,xzr,xzr + str x19,[x26],#8 // result!!! + adds x19,x20,x10 + sub x10,x27,x1 // done yet? + adcs x20,x21,x11 + adcs x21,x22,x12 + adcs x22,x23,x13 + //adc x0,x0,xzr + cbnz x28,.Loop_mul4x_tail + + sub x11,x3,x5 // rewinded np? + adc x0,x0,xzr + cbz x10,.Loop_mul4x_break + + ldp x10,x11,[x26,#8*4] + ldp x12,x13,[x26,#8*6] + ldp x6,x7,[x1,#8*0] + ldp x8,x9,[x1,#8*2] + add x1,x1,#8*4 + adds x19,x19,x10 + adcs x20,x20,x11 + adcs x21,x21,x12 + adcs x22,x22,x13 + //adc x0,x0,xzr + ldp x14,x15,[x3,#8*0] + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + b .Loop_mul4x_tail + +.align 4 +.Loop_mul4x_break: + ldp x12,x13,[x29,#96] // pull rp and &b[num] + adds x19,x19,x30 + add x2,x2,#8*4 // bp++ + adcs x20,x20,xzr + sub x1,x1,x5 // rewind ap + adcs x21,x21,xzr + stp x19,x20,[x26,#8*0] // result!!! + adcs x22,x22,xzr + ldp x19,x20,[sp,#8*4] // t[0..3] + adc x30,x0,xzr + stp x21,x22,[x26,#8*2] // result!!! + cmp x2,x13 // done yet? + ldp x21,x22,[sp,#8*6] + ldp x14,x15,[x11,#8*0] // n[0..3] + ldp x16,x17,[x11,#8*2] + add x3,x11,#8*4 + b.eq .Lmul4x_post + + ldr x24,[x2] + ldp x6,x7,[x1,#8*0] // a[0..3] + ldp x8,x9,[x1,#8*2] + adds x1,x1,#8*4 // clear carry bit + mov x0,xzr + mov x26,sp + b .Loop_mul4x_reduction + +.align 4 +.Lmul4x_post: + // Final step. We see if result is larger than modulus, and + // if it is, subtract the modulus. But comparison implies + // subtraction. So we subtract modulus, see if it borrowed, + // and conditionally copy original value. + mov x0,x12 + mov x27,x12 // x0 copy + subs x10,x19,x14 + add x26,sp,#8*8 + sbcs x11,x20,x15 + sub x28,x5,#8*4 + +.Lmul4x_sub: + sbcs x12,x21,x16 + ldp x14,x15,[x3,#8*0] + sub x28,x28,#8*4 + ldp x19,x20,[x26,#8*0] + sbcs x13,x22,x17 + ldp x16,x17,[x3,#8*2] + add x3,x3,#8*4 + ldp x21,x22,[x26,#8*2] + add x26,x26,#8*4 + stp x10,x11,[x0,#8*0] + sbcs x10,x19,x14 + stp x12,x13,[x0,#8*2] + add x0,x0,#8*4 + sbcs x11,x20,x15 + cbnz x28,.Lmul4x_sub + + sbcs x12,x21,x16 + mov x26,sp + add x1,sp,#8*4 + ldp x6,x7,[x27,#8*0] + sbcs x13,x22,x17 + stp x10,x11,[x0,#8*0] + ldp x8,x9,[x27,#8*2] + stp x12,x13,[x0,#8*2] + ldp x19,x20,[x1,#8*0] + ldp x21,x22,[x1,#8*2] + sbcs xzr,x30,xzr // did it borrow? + ldr x30,[x29,#8] // pull return address + + sub x28,x5,#8*4 +.Lmul4x_cond_copy: + sub x28,x28,#8*4 + csel x10,x19,x6,lo + stp xzr,xzr,[x26,#8*0] + csel x11,x20,x7,lo + ldp x6,x7,[x27,#8*4] + ldp x19,x20,[x1,#8*4] + csel x12,x21,x8,lo + stp xzr,xzr,[x26,#8*2] + add x26,x26,#8*4 + csel x13,x22,x9,lo + ldp x8,x9,[x27,#8*6] + ldp x21,x22,[x1,#8*6] + add x1,x1,#8*4 + stp x10,x11,[x27,#8*0] + stp x12,x13,[x27,#8*2] + add x27,x27,#8*4 + cbnz x28,.Lmul4x_cond_copy + + csel x10,x19,x6,lo + stp xzr,xzr,[x26,#8*0] + csel x11,x20,x7,lo + stp xzr,xzr,[x26,#8*2] + csel x12,x21,x8,lo + stp xzr,xzr,[x26,#8*3] + csel x13,x22,x9,lo + stp xzr,xzr,[x26,#8*4] + stp x10,x11,[x27,#8*0] + stp x12,x13,[x27,#8*2] + + b .Lmul4x_done + +.align 4 +.Lmul4x4_post_condition: + adc x0,x0,xzr + ldr x1,[x29,#96] // pull rp + // x19-3,x0 hold result, x14-7 hold modulus + subs x6,x19,x14 + ldr x30,[x29,#8] // pull return address + sbcs x7,x20,x15 + stp xzr,xzr,[sp,#8*0] + sbcs x8,x21,x16 + stp xzr,xzr,[sp,#8*2] + sbcs x9,x22,x17 + stp xzr,xzr,[sp,#8*4] + sbcs xzr,x0,xzr // did it borrow? + stp xzr,xzr,[sp,#8*6] + + // x6-3 hold result-modulus + csel x6,x19,x6,lo + csel x7,x20,x7,lo + csel x8,x21,x8,lo + csel x9,x22,x9,lo + stp x6,x7,[x1,#8*0] + stp x8,x9,[x1,#8*2] + +.Lmul4x_done: + ldp x19,x20,[x29,#16] + mov sp,x29 + ldp x21,x22,[x29,#32] + mov x0,#1 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldr x29,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size __bn_mul4x_mont,.-__bn_mul4x_mont +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 4 diff --git a/crypto/openssl/crypto/bn/asm/armv4-gf2m.pl b/crypto/openssl/crypto/bn/asm/armv4-gf2m.pl index 3a83cb855007..d380c89f1f2b 100755 --- a/crypto/openssl/crypto/bn/asm/armv4-gf2m.pl +++ b/crypto/openssl/crypto/bn/asm/armv4-gf2m.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -39,9 +39,10 @@ # # http://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -49,21 +50,23 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $1"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $code=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) .syntax unified .thumb #else .code 32 #endif + +.text ___ ################ # private interface to mul_1x1_ialu @@ -176,11 +179,13 @@ bn_GF2m_mul_2x2: #if __ARM_MAX_ARCH__>=7 stmdb sp!,{r10,lr} ldr r12,.LOPENSSL_armcap +# if !defined(_WIN32) adr r10,.LOPENSSL_armcap ldr r12,[r12,r10] -#ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r12,[r12] -#endif +# endif tst r12,#ARMV7_NEON itt ne ldrne r10,[sp],#8 @@ -310,7 +315,11 @@ $code.=<<___; #if __ARM_MAX_ARCH__>=7 .align 5 .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-. +# endif #endif .asciz "GF(2^m) Multiplication for ARMv4/NEON, CRYPTOGAMS by " .align 5 diff --git a/crypto/openssl/crypto/bn/asm/armv4-mont.pl b/crypto/openssl/crypto/bn/asm/armv4-mont.pl index eadc8bbf6322..c26df751a5eb 100755 --- a/crypto/openssl/crypto/bn/asm/armv4-mont.pl +++ b/crypto/openssl/crypto/bn/asm/armv4-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -54,9 +54,10 @@ # integer-only on Cortex-A8, ~10-210% on Cortex-A15, ~70-450% on # Snapdragon S4. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -64,9 +65,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $1"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $num="r0"; # starts as num argument, but holds &tp[num-1] @@ -97,7 +99,6 @@ $_num="$num,#15*4"; $_bpend=$_num; $code=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) .syntax unified .thumb @@ -105,10 +106,16 @@ $code=<<___; .code 32 #endif +.text + #if __ARM_MAX_ARCH__>=7 .align 5 .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.Lbn_mul_mont +# endif #endif .global bn_mul_mont @@ -122,12 +129,14 @@ bn_mul_mont: #if __ARM_MAX_ARCH__>=7 tst ip,#7 bne .Lialu - adr r0,.Lbn_mul_mont - ldr r2,.LOPENSSL_armcap + ldr r0,.LOPENSSL_armcap +#if !defined(_WIN32) + adr r2,.Lbn_mul_mont ldr r0,[r0,r2] -#ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r0,[r0] -#endif +# endif tst r0,#ARMV7_NEON @ NEON available? ldmia sp, {r0,r2} beq .Lialu diff --git a/crypto/openssl/crypto/bn/asm/armv8-mont.pl b/crypto/openssl/crypto/bn/asm/armv8-mont.pl index bc9a18dc4ce6..54d2e8245f15 100755 --- a/crypto/openssl/crypto/bn/asm/armv8-mont.pl +++ b/crypto/openssl/crypto/bn/asm/armv8-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -40,15 +40,18 @@ # 50-70% improvement for RSA4096 sign. RSA2048 sign is ~25% faster # on Cortex-A57 and ~60-100% faster on others. -$flavour = shift; -$output = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $1"; *STDOUT=*OUT; ($lo0,$hi0,$aj,$m0,$alo,$ahi, @@ -64,16 +67,34 @@ $n0="x4"; # const BN_ULONG *n0, $num="x5"; # int num); $code.=<<___; +#ifndef __KERNEL__ +# include "arm_arch.h" +.extern OPENSSL_armv8_rsa_neonized +.hidden OPENSSL_armv8_rsa_neonized +#endif .text .globl bn_mul_mont .type bn_mul_mont,%function .align 5 bn_mul_mont: +.Lbn_mul_mont: + tst $num,#3 + b.ne .Lmul_mont + cmp $num,#32 + b.le .Lscalar_impl +#ifndef __KERNEL__ + adrp x17,OPENSSL_armv8_rsa_neonized + ldr w17,[x17,#:lo12:OPENSSL_armv8_rsa_neonized] + cbnz w17, bn_mul8x_mont_neon +#endif + +.Lscalar_impl: tst $num,#7 b.eq __bn_sqr8x_mont tst $num,#3 b.eq __bn_mul4x_mont + .Lmul_mont: stp x29,x30,[sp,#-64]! add x29,sp,#0 @@ -197,7 +218,7 @@ bn_mul_mont: mul $nlo,$nj,$m1 // np[j]*m1 adds $lo1,$lo1,$lo0 umulh $nhi,$nj,$m1 - str $lo1,[$tp,#-16] // tp[j-1] + stur $lo1,[$tp,#-16] // tp[j-1] cbnz $j,.Linner .Linner_skip: @@ -253,13 +274,13 @@ bn_mul_mont: csel $nj,$tj,$aj,lo // did it borrow? ldr $tj,[$tp],#8 ldr $aj,[$rp],#8 - str xzr,[$tp,#-16] // wipe tp - str $nj,[$rp,#-16] + stur xzr,[$tp,#-16] // wipe tp + stur $nj,[$rp,#-16] cbnz $num,.Lcond_copy csel $nj,$tj,$aj,lo - str xzr,[$tp,#-8] // wipe tp - str $nj,[$rp,#-8] + stur xzr,[$tp,#-8] // wipe tp + stur $nj,[$rp,#-8] ldp x19,x20,[x29,#16] mov sp,x29 @@ -271,6 +292,369 @@ bn_mul_mont: .size bn_mul_mont,.-bn_mul_mont ___ { +my ($A0,$A1,$N0,$N1)=map("v$_",(0..3)); +my ($Z,$Temp)=("v4.16b","v5"); +my @ACC=map("v$_",(6..13)); +my ($Bi,$Ni,$M0)=map("v$_",(28..30)); +my $sBi="s28"; +my $sM0="s30"; +my $zero="v14"; +my $temp="v15"; +my $ACCTemp="v16"; + +my ($rptr,$aptr,$bptr,$nptr,$n0,$num)=map("x$_",(0..5)); +my ($tinptr,$toutptr,$inner,$outer,$bnptr)=map("x$_",(6..11)); + +$code.=<<___; +.type bn_mul8x_mont_neon,%function +.align 5 +bn_mul8x_mont_neon: + stp x29,x30,[sp,#-80]! + mov x16,sp + stp d8,d9,[sp,#16] + stp d10,d11,[sp,#32] + stp d12,d13,[sp,#48] + stp d14,d15,[sp,#64] + lsl $num,$num,#1 + eor $zero.16b,$zero.16b,$zero.16b + +.align 4 +.LNEON_8n: + eor @ACC[0].16b,@ACC[0].16b,@ACC[0].16b + sub $toutptr,sp,#128 + eor @ACC[1].16b,@ACC[1].16b,@ACC[1].16b + sub $toutptr,$toutptr,$num,lsl#4 + eor @ACC[2].16b,@ACC[2].16b,@ACC[2].16b + and $toutptr,$toutptr,#-64 + eor @ACC[3].16b,@ACC[3].16b,@ACC[3].16b + mov sp,$toutptr // alloca + eor @ACC[4].16b,@ACC[4].16b,@ACC[4].16b + add $toutptr,$toutptr,#256 + eor @ACC[5].16b,@ACC[5].16b,@ACC[5].16b + sub $inner,$num,#8 + eor @ACC[6].16b,@ACC[6].16b,@ACC[6].16b + eor @ACC[7].16b,@ACC[7].16b,@ACC[7].16b + +.LNEON_8n_init: + st1 {@ACC[0].2d,@ACC[1].2d},[$toutptr],#32 + subs $inner,$inner,#8 + st1 {@ACC[2].2d,@ACC[3].2d},[$toutptr],#32 + st1 {@ACC[4].2d,@ACC[5].2d},[$toutptr],#32 + st1 {@ACC[6].2d,@ACC[7].2d},[$toutptr],#32 + bne .LNEON_8n_init + + add $tinptr,sp,#256 + ld1 {$A0.4s,$A1.4s},[$aptr],#32 + add $bnptr,sp,#8 + ldr $sM0,[$n0],#4 + mov $outer,$num + b .LNEON_8n_outer + +.align 4 +.LNEON_8n_outer: + ldr $sBi,[$bptr],#4 // *b++ + uxtl $Bi.4s,$Bi.4h + add $toutptr,sp,#128 + ld1 {$N0.4s,$N1.4s},[$nptr],#32 + + umlal @ACC[0].2d,$Bi.2s,$A0.s[0] + umlal @ACC[1].2d,$Bi.2s,$A0.s[1] + umlal @ACC[2].2d,$Bi.2s,$A0.s[2] + shl $Ni.2d,@ACC[0].2d,#16 + ext $Ni.16b,$Ni.16b,$Ni.16b,#8 + umlal @ACC[3].2d,$Bi.2s,$A0.s[3] + add $Ni.2d,$Ni.2d,@ACC[0].2d + umlal @ACC[4].2d,$Bi.2s,$A1.s[0] + mul $Ni.2s,$Ni.2s,$M0.2s + umlal @ACC[5].2d,$Bi.2s,$A1.s[1] + st1 {$Bi.2s},[sp] // put aside smashed b[8*i+0] + umlal @ACC[6].2d,$Bi.2s,$A1.s[2] + uxtl $Ni.4s,$Ni.4h + umlal @ACC[7].2d,$Bi.2s,$A1.s[3] +___ +for ($i=0; $i<7;) { +$code.=<<___; + ldr $sBi,[$bptr],#4 // *b++ + umlal @ACC[0].2d,$Ni.2s,$N0.s[0] + umlal @ACC[1].2d,$Ni.2s,$N0.s[1] + uxtl $Bi.4s,$Bi.4h + umlal @ACC[2].2d,$Ni.2s,$N0.s[2] + ushr $temp.2d,@ACC[0].2d,#16 + umlal @ACC[3].2d,$Ni.2s,$N0.s[3] + umlal @ACC[4].2d,$Ni.2s,$N1.s[0] + ext @ACC[0].16b,@ACC[0].16b,@ACC[0].16b,#8 + add @ACC[0].2d,@ACC[0].2d,$temp.2d + umlal @ACC[5].2d,$Ni.2s,$N1.s[1] + ushr @ACC[0].2d,@ACC[0].2d,#16 + umlal @ACC[6].2d,$Ni.2s,$N1.s[2] + umlal @ACC[7].2d,$Ni.2s,$N1.s[3] + add $ACCTemp.2d,@ACC[1].2d,@ACC[0].2d + ins @ACC[1].d[0],$ACCTemp.d[0] + st1 {$Ni.2s},[$bnptr],#8 // put aside smashed m[8*i+$i] +___ + push(@ACC,shift(@ACC)); $i++; +$code.=<<___; + umlal @ACC[0].2d,$Bi.2s,$A0.s[0] + ld1 {@ACC[7].2d},[$tinptr],#16 + umlal @ACC[1].2d,$Bi.2s,$A0.s[1] + umlal @ACC[2].2d,$Bi.2s,$A0.s[2] + shl $Ni.2d,@ACC[0].2d,#16 + ext $Ni.16b,$Ni.16b,$Ni.16b,#8 + umlal @ACC[3].2d,$Bi.2s,$A0.s[3] + add $Ni.2d,$Ni.2d,@ACC[0].2d + umlal @ACC[4].2d,$Bi.2s,$A1.s[0] + mul $Ni.2s,$Ni.2s,$M0.2s + umlal @ACC[5].2d,$Bi.2s,$A1.s[1] + st1 {$Bi.2s},[$bnptr],#8 // put aside smashed b[8*i+$i] + umlal @ACC[6].2d,$Bi.2s,$A1.s[2] + uxtl $Ni.4s,$Ni.4h + umlal @ACC[7].2d,$Bi.2s,$A1.s[3] +___ +} +$code.=<<___; + ld1 {$Bi.2s},[sp] // pull smashed b[8*i+0] + umlal @ACC[0].2d,$Ni.2s,$N0.s[0] + ld1 {$A0.4s,$A1.4s},[$aptr],#32 + umlal @ACC[1].2d,$Ni.2s,$N0.s[1] + umlal @ACC[2].2d,$Ni.2s,$N0.s[2] + mov $Temp.16b,@ACC[0].16b + ushr $Temp.2d,$Temp.2d,#16 + ext @ACC[0].16b,@ACC[0].16b,@ACC[0].16b,#8 + umlal @ACC[3].2d,$Ni.2s,$N0.s[3] + umlal @ACC[4].2d,$Ni.2s,$N1.s[0] + add @ACC[0].2d,@ACC[0].2d,$Temp.2d + umlal @ACC[5].2d,$Ni.2s,$N1.s[1] + ushr @ACC[0].2d,@ACC[0].2d,#16 + eor $temp.16b,$temp.16b,$temp.16b + ins @ACC[0].d[1],$temp.d[0] + umlal @ACC[6].2d,$Ni.2s,$N1.s[2] + umlal @ACC[7].2d,$Ni.2s,$N1.s[3] + add @ACC[1].2d,@ACC[1].2d,@ACC[0].2d + st1 {$Ni.2s},[$bnptr],#8 // put aside smashed m[8*i+$i] + add $bnptr,sp,#8 // rewind +___ + push(@ACC,shift(@ACC)); +$code.=<<___; + sub $inner,$num,#8 + b .LNEON_8n_inner + +.align 4 +.LNEON_8n_inner: + subs $inner,$inner,#8 + umlal @ACC[0].2d,$Bi.2s,$A0.s[0] + ld1 {@ACC[7].2d},[$tinptr] + umlal @ACC[1].2d,$Bi.2s,$A0.s[1] + ld1 {$Ni.2s},[$bnptr],#8 // pull smashed m[8*i+0] + umlal @ACC[2].2d,$Bi.2s,$A0.s[2] + ld1 {$N0.4s,$N1.4s},[$nptr],#32 + umlal @ACC[3].2d,$Bi.2s,$A0.s[3] + b.eq .LInner_jump + add $tinptr,$tinptr,#16 // don't advance in last iteration +.LInner_jump: + umlal @ACC[4].2d,$Bi.2s,$A1.s[0] + umlal @ACC[5].2d,$Bi.2s,$A1.s[1] + umlal @ACC[6].2d,$Bi.2s,$A1.s[2] + umlal @ACC[7].2d,$Bi.2s,$A1.s[3] +___ +for ($i=1; $i<8; $i++) { +$code.=<<___; + ld1 {$Bi.2s},[$bnptr],#8 // pull smashed b[8*i+$i] + umlal @ACC[0].2d,$Ni.2s,$N0.s[0] + umlal @ACC[1].2d,$Ni.2s,$N0.s[1] + umlal @ACC[2].2d,$Ni.2s,$N0.s[2] + umlal @ACC[3].2d,$Ni.2s,$N0.s[3] + umlal @ACC[4].2d,$Ni.2s,$N1.s[0] + umlal @ACC[5].2d,$Ni.2s,$N1.s[1] + umlal @ACC[6].2d,$Ni.2s,$N1.s[2] + umlal @ACC[7].2d,$Ni.2s,$N1.s[3] + st1 {@ACC[0].2d},[$toutptr],#16 +___ + push(@ACC,shift(@ACC)); +$code.=<<___; + umlal @ACC[0].2d,$Bi.2s,$A0.s[0] + ld1 {@ACC[7].2d},[$tinptr] + umlal @ACC[1].2d,$Bi.2s,$A0.s[1] + ld1 {$Ni.2s},[$bnptr],#8 // pull smashed m[8*i+$i] + umlal @ACC[2].2d,$Bi.2s,$A0.s[2] + b.eq .LInner_jump$i + add $tinptr,$tinptr,#16 // don't advance in last iteration +.LInner_jump$i: + umlal @ACC[3].2d,$Bi.2s,$A0.s[3] + umlal @ACC[4].2d,$Bi.2s,$A1.s[0] + umlal @ACC[5].2d,$Bi.2s,$A1.s[1] + umlal @ACC[6].2d,$Bi.2s,$A1.s[2] + umlal @ACC[7].2d,$Bi.2s,$A1.s[3] +___ +} +$code.=<<___; + b.ne .LInner_after_rewind$i + sub $aptr,$aptr,$num,lsl#2 // rewind +.LInner_after_rewind$i: + umlal @ACC[0].2d,$Ni.2s,$N0.s[0] + ld1 {$Bi.2s},[sp] // pull smashed b[8*i+0] + umlal @ACC[1].2d,$Ni.2s,$N0.s[1] + ld1 {$A0.4s,$A1.4s},[$aptr],#32 + umlal @ACC[2].2d,$Ni.2s,$N0.s[2] + add $bnptr,sp,#8 // rewind + umlal @ACC[3].2d,$Ni.2s,$N0.s[3] + umlal @ACC[4].2d,$Ni.2s,$N1.s[0] + umlal @ACC[5].2d,$Ni.2s,$N1.s[1] + umlal @ACC[6].2d,$Ni.2s,$N1.s[2] + st1 {@ACC[0].2d},[$toutptr],#16 + umlal @ACC[7].2d,$Ni.2s,$N1.s[3] + + bne .LNEON_8n_inner +___ + push(@ACC,shift(@ACC)); +$code.=<<___; + add $tinptr,sp,#128 + st1 {@ACC[0].2d,@ACC[1].2d},[$toutptr],#32 + eor $N0.16b,$N0.16b,$N0.16b // $N0 + st1 {@ACC[2].2d,@ACC[3].2d},[$toutptr],#32 + eor $N1.16b,$N1.16b,$N1.16b // $N1 + st1 {@ACC[4].2d,@ACC[5].2d},[$toutptr],#32 + st1 {@ACC[6].2d},[$toutptr] + + subs $outer,$outer,#8 + ld1 {@ACC[0].2d,@ACC[1].2d},[$tinptr],#32 + ld1 {@ACC[2].2d,@ACC[3].2d},[$tinptr],#32 + ld1 {@ACC[4].2d,@ACC[5].2d},[$tinptr],#32 + ld1 {@ACC[6].2d,@ACC[7].2d},[$tinptr],#32 + + b.eq .LInner_8n_jump_2steps + sub $nptr,$nptr,$num,lsl#2 // rewind + b .LNEON_8n_outer + +.LInner_8n_jump_2steps: + add $toutptr,sp,#128 + st1 {$N0.2d,$N1.2d}, [sp],#32 // start wiping stack frame + mov $Temp.16b,@ACC[0].16b + ushr $temp.2d,@ACC[0].2d,#16 + ext @ACC[0].16b,@ACC[0].16b,@ACC[0].16b,#8 + st1 {$N0.2d,$N1.2d}, [sp],#32 + add @ACC[0].2d,@ACC[0].2d,$temp.2d + st1 {$N0.2d,$N1.2d}, [sp],#32 + ushr $temp.2d,@ACC[0].2d,#16 + st1 {$N0.2d,$N1.2d}, [sp],#32 + zip1 @ACC[0].4h,$Temp.4h,@ACC[0].4h + ins $temp.d[1],$zero.d[0] + + mov $inner,$num + b .LNEON_tail_entry + +.align 4 +.LNEON_tail: + add @ACC[0].2d,@ACC[0].2d,$temp.2d + mov $Temp.16b,@ACC[0].16b + ushr $temp.2d,@ACC[0].2d,#16 + ext @ACC[0].16b,@ACC[0].16b,@ACC[0].16b,#8 + ld1 {@ACC[2].2d,@ACC[3].2d}, [$tinptr],#32 + add @ACC[0].2d,@ACC[0].2d,$temp.2d + ld1 {@ACC[4].2d,@ACC[5].2d}, [$tinptr],#32 + ushr $temp.2d,@ACC[0].2d,#16 + ld1 {@ACC[6].2d,@ACC[7].2d}, [$tinptr],#32 + zip1 @ACC[0].4h,$Temp.4h,@ACC[0].4h + ins $temp.d[1],$zero.d[0] + +.LNEON_tail_entry: +___ +for ($i=1; $i<8; $i++) { +$code.=<<___; + add @ACC[1].2d,@ACC[1].2d,$temp.2d + st1 {@ACC[0].s}[0], [$toutptr],#4 + ushr $temp.2d,@ACC[1].2d,#16 + mov $Temp.16b,@ACC[1].16b + ext @ACC[1].16b,@ACC[1].16b,@ACC[1].16b,#8 + add @ACC[1].2d,@ACC[1].2d,$temp.2d + ushr $temp.2d,@ACC[1].2d,#16 + zip1 @ACC[1].4h,$Temp.4h,@ACC[1].4h + ins $temp.d[1],$zero.d[0] +___ + push(@ACC,shift(@ACC)); +} + push(@ACC,shift(@ACC)); +$code.=<<___; + ld1 {@ACC[0].2d,@ACC[1].2d}, [$tinptr],#32 + subs $inner,$inner,#8 + st1 {@ACC[7].s}[0], [$toutptr],#4 + bne .LNEON_tail + + st1 {$temp.s}[0], [$toutptr],#4 // top-most bit + sub $nptr,$nptr,$num,lsl#2 // rewind $nptr + subs $aptr,sp,#0 // clear carry flag + add $bptr,sp,$num,lsl#2 + +.LNEON_sub: + ldp w4,w5,[$aptr],#8 + ldp w6,w7,[$aptr],#8 + ldp w8,w9,[$nptr],#8 + ldp w10,w11,[$nptr],#8 + sbcs w8,w4,w8 + sbcs w9,w5,w9 + sbcs w10,w6,w10 + sbcs w11,w7,w11 + sub x17,$bptr,$aptr + stp w8,w9,[$rptr],#8 + stp w10,w11,[$rptr],#8 + cbnz x17,.LNEON_sub + + ldr w10, [$aptr] // load top-most bit + mov x11,sp + eor v0.16b,v0.16b,v0.16b + sub x11,$bptr,x11 // this is num*4 + eor v1.16b,v1.16b,v1.16b + mov $aptr,sp + sub $rptr,$rptr,x11 // rewind $rptr + mov $nptr,$bptr // second 3/4th of frame + sbcs w10,w10,wzr // result is carry flag + +.LNEON_copy_n_zap: + ldp w4,w5,[$aptr],#8 + ldp w6,w7,[$aptr],#8 + ldp w8,w9,[$rptr],#8 + ldp w10,w11,[$rptr] + sub $rptr,$rptr,#8 + b.cs .LCopy_1 + mov w8,w4 + mov w9,w5 + mov w10,w6 + mov w11,w7 +.LCopy_1: + st1 {v0.2d,v1.2d}, [$nptr],#32 // wipe + st1 {v0.2d,v1.2d}, [$nptr],#32 // wipe + ldp w4,w5,[$aptr],#8 + ldp w6,w7,[$aptr],#8 + stp w8,w9,[$rptr],#8 + stp w10,w11,[$rptr],#8 + sub $aptr,$aptr,#32 + ldp w8,w9,[$rptr],#8 + ldp w10,w11,[$rptr] + sub $rptr,$rptr,#8 + b.cs .LCopy_2 + mov w8, w4 + mov w9, w5 + mov w10, w6 + mov w11, w7 +.LCopy_2: + st1 {v0.2d,v1.2d}, [$aptr],#32 // wipe + st1 {v0.2d,v1.2d}, [$nptr],#32 // wipe + sub x17,$bptr,$aptr // preserves carry + stp w8,w9,[$rptr],#8 + stp w10,w11,[$rptr],#8 + cbnz x17,.LNEON_copy_n_zap + + mov sp,x16 + ldp d14,d15,[sp,#64] + ldp d12,d13,[sp,#48] + ldp d10,d11,[sp,#32] + ldp d8,d9,[sp,#16] + ldr x29,[sp],#80 + ret // bx lr + +.size bn_mul8x_mont_neon,.-bn_mul8x_mont_neon +___ +} +{ ######################################################################## # Following is ARMv8 adaptation of sqrx8x_mont from x86_64-mont5 module. @@ -596,7 +980,7 @@ __bn_sqr8x_mont: ldp $a4,$a5,[$tp,#8*4] ldp $a6,$a7,[$tp,#8*6] adds $acc0,$acc0,$a0 - ldr $n0,[$rp,#-8*8] + ldur $n0,[$rp,#-8*8] adcs $acc1,$acc1,$a1 ldp $a0,$a1,[$ap,#8*0] adcs $acc2,$acc2,$a2 @@ -794,7 +1178,7 @@ $code.=<<___; //adc $carry,xzr,xzr // moved below cbz $cnt,.Lsqr8x8_post_condition - ldr $n0,[$tp,#-8*8] + ldur $n0,[$tp,#-8*8] ldp $a0,$a1,[$np,#8*0] ldp $a2,$a3,[$np,#8*2] ldp $a4,$a5,[$np,#8*4] @@ -852,7 +1236,7 @@ $code.=<<___; ldp $a6,$a7,[$tp,#8*6] cbz $cnt,.Lsqr8x_tail_break - ldr $n0,[$rp,#-8*8] + ldur $n0,[$rp,#-8*8] adds $acc0,$acc0,$a0 adcs $acc1,$acc1,$a1 ldp $a0,$a1,[$np,#8*0] diff --git a/crypto/openssl/crypto/bn/asm/bn-586.pl b/crypto/openssl/crypto/bn/asm/bn-586.pl index e0422405d5f3..56a9229add9d 100755 --- a/crypto/openssl/crypto/bn/asm/bn-586.pl +++ b/crypto/openssl/crypto/bn/asm/bn-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -11,8 +11,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/openssl/crypto/bn/asm/bn-c64xplus.asm b/crypto/openssl/crypto/bn/asm/bn-c64xplus.asm index de6d37728fba..e273d37c1fc3 100644 --- a/crypto/openssl/crypto/bn/asm/bn-c64xplus.asm +++ b/crypto/openssl/crypto/bn/asm/bn-c64xplus.asm @@ -1,6 +1,6 @@ ;; Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved. ;; -;; Licensed under the OpenSSL license (the "License"). You may not use +;; 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 @@ -10,8 +10,7 @@ ;; project. ;; ;; Rights for redistribution and usage in source and binary forms are -;; granted according to the OpenSSL license. Warranty of any kind is -;; disclaimed. +;; granted according to the License. Warranty of any kind is disclaimed. ;;==================================================================== ;; Compiler-generated multiply-n-add SPLOOP runs at 12*n cycles, n ;; being the number of 32-bit words, addition - 8*n. Corresponding 4x diff --git a/crypto/openssl/crypto/bn/asm/c64xplus-gf2m.pl b/crypto/openssl/crypto/bn/asm/c64xplus-gf2m.pl index 3bb8d120e96a..5b58f3ac5478 100755 --- a/crypto/openssl/crypto/bn/asm/c64xplus-gf2m.pl +++ b/crypto/openssl/crypto/bn/asm/c64xplus-gf2m.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -23,8 +23,7 @@ # totally unfair, because this module utilizes Galois Field Multiply # instruction. -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; ($rp,$a1,$a0,$b1,$b0)=("A4","B4","A6","B6","A8"); # argument vector diff --git a/crypto/openssl/crypto/bn/asm/co-586.pl b/crypto/openssl/crypto/bn/asm/co-586.pl index 3c34fa885c30..139d95dae843 100755 --- a/crypto/openssl/crypto/bn/asm/co-586.pl +++ b/crypto/openssl/crypto/bn/asm/co-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -10,8 +10,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/openssl/crypto/bn/asm/ia64-mont.pl b/crypto/openssl/crypto/bn/asm/ia64-mont.pl index 7a4e74d71942..ab0ad9d1b395 100755 --- a/crypto/openssl/crypto/bn/asm/ia64-mont.pl +++ b/crypto/openssl/crypto/bn/asm/ia64-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -67,7 +67,8 @@ # hereafter less for longer keys, while verify - by 74-13%. # DSA performance improves by 115-30%. -$output=pop; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; if ($^O eq "hpux") { $ADDP="addp4"; diff --git a/crypto/openssl/crypto/bn/asm/ia64.S b/crypto/openssl/crypto/bn/asm/ia64.S index 0a26735c6979..0d64e98c48b0 100644 --- a/crypto/openssl/crypto/bn/asm/ia64.S +++ b/crypto/openssl/crypto/bn/asm/ia64.S @@ -3,9 +3,9 @@ .ident "ia64.S, Version 2.1" .ident "IA-64 ISA artwork by Andy Polyakov " -// Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. // -// Licensed under the OpenSSL license (the "License"). You may not use +// 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 @@ -16,8 +16,7 @@ // project. // // Rights for redistribution and usage in source and binary forms are -// granted according to the OpenSSL license. Warranty of any kind is -// disclaimed. +// granted according to the License. Warranty of any kind is disclaimed. // ==================================================================== // // Version 2.x is Itanium2 re-tune. Few words about how Itanium2 is diff --git a/crypto/openssl/crypto/bn/asm/mips-mont.pl b/crypto/openssl/crypto/bn/asm/mips-mont.pl index 3b79a4b186d7..687cc90928b4 100755 --- a/crypto/openssl/crypto/bn/asm/mips-mont.pl +++ b/crypto/openssl/crypto/bn/asm/mips-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -52,8 +52,12 @@ # ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); # ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); # ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); -# -$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +# supported flavours are o32,n32,64,nubi32,nubi64, default is o32 +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : "o32"; if ($flavour =~ /64|n32/i) { $PTR_ADD="daddu"; # incidentally works even on n32 @@ -74,8 +78,7 @@ $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0x00fff000 : 0x00ff0000; # ###################################################################### -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; if ($flavour =~ /64|n32/i) { $LD="ld"; diff --git a/crypto/openssl/crypto/bn/asm/mips.pl b/crypto/openssl/crypto/bn/asm/mips.pl index 76fe82334f88..bc18826d08f8 100755 --- a/crypto/openssl/crypto/bn/asm/mips.pl +++ b/crypto/openssl/crypto/bn/asm/mips.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2010-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -12,8 +12,7 @@ # project. # # Rights for redistribution and usage in source and binary forms are -# granted according to the OpenSSL license. Warranty of any kind is -# disclaimed. +# granted according to the License. Warranty of any kind is disclaimed. # ==================================================================== @@ -55,9 +54,10 @@ # has to content with 40-85% improvement depending on benchmark and # key length, more for longer keys. -$flavour = shift || "o32"; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : "o32"; if ($flavour =~ /64|n32/i) { $LD="ld"; @@ -92,6 +92,8 @@ if ($flavour =~ /64|n32/i) { $code="#if !(defined (__mips_isa_rev) && (__mips_isa_rev >= 6))\n.set mips2\n#endif\n"; } +$output and open STDOUT,">$output"; + # Below is N32/64 register layout used in the original module. # ($zero,$at,$v0,$v1)=map("\$$_",(0..3)); diff --git a/crypto/openssl/crypto/bn/asm/parisc-mont.pl b/crypto/openssl/crypto/bn/asm/parisc-mont.pl index 6a7c714a156e..d6ca83c40bac 100755 --- a/crypto/openssl/crypto/bn/asm/parisc-mont.pl +++ b/crypto/openssl/crypto/bn/asm/parisc-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -69,10 +69,12 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -$flavour = shift; -$output = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; -open STDOUT,">$output"; +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/openssl/crypto/bn/asm/ppc-mont.pl b/crypto/openssl/crypto/bn/asm/ppc-mont.pl index 278314c57bd6..c3072f0d5f84 100755 --- a/crypto/openssl/crypto/bn/asm/ppc-mont.pl +++ b/crypto/openssl/crypto/bn/asm/ppc-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -41,7 +41,10 @@ # builds. On low-end 32-bit processors performance improvement turned # to be marginal... -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /32/) { $BITS= 32; @@ -94,7 +97,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $sp="r1"; $toc="r2"; diff --git a/crypto/openssl/crypto/bn/asm/ppc.pl b/crypto/openssl/crypto/bn/asm/ppc.pl index a8d3f14e9b8e..5015f7e7efe1 100755 --- a/crypto/openssl/crypto/bn/asm/ppc.pl +++ b/crypto/openssl/crypto/bn/asm/ppc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -103,7 +103,10 @@ # Performance increase of ~60% # Based on submission from Suresh N. Chari of IBM -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /32/) { $BITS= 32; @@ -159,7 +162,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $data=<= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /32/) { $SIZE_T=4; @@ -108,7 +111,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=64; # padded frame header $TRANSFER=16*8; diff --git a/crypto/openssl/crypto/bn/asm/rsaz-avx2.pl b/crypto/openssl/crypto/bn/asm/rsaz-avx2.pl index 0be771febc16..3d0e342a6b8c 100755 --- a/crypto/openssl/crypto/bn/asm/rsaz-avx2.pl +++ b/crypto/openssl/crypto/bn/asm/rsaz-avx2.pl @@ -2,7 +2,7 @@ # Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2012, Intel Corporation. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -37,9 +37,10 @@ # (***) scalar AD*X code is faster than AVX2 and is preferred code # path for Broadwell; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -72,7 +73,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|based on LLVM) ([0-9 $addx = ($ver>=3.03); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT = *OUT; if ($avx>1) {{{ diff --git a/crypto/openssl/crypto/bn/asm/rsaz-avx512.pl b/crypto/openssl/crypto/bn/asm/rsaz-avx512.pl new file mode 100644 index 000000000000..8d1d19f6c728 --- /dev/null +++ b/crypto/openssl/crypto/bn/asm/rsaz-avx512.pl @@ -0,0 +1,754 @@ +# Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright (c) 2020, Intel Corporation. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html +# +# +# Originally written by Ilya Albrekht, Sergey Kirillov and Andrey Matyukov +# Intel Corporation +# +# December 2020 +# +# Initial release. +# +# Implementation utilizes 256-bit (ymm) registers to avoid frequency scaling issues. +# +# IceLake-Client @ 1.3GHz +# |---------+----------------------+--------------+-------------| +# | | OpenSSL 3.0.0-alpha9 | this | Unit | +# |---------+----------------------+--------------+-------------| +# | rsa2048 | 2 127 659 | 1 015 625 | cycles/sign | +# | | 611 | 1280 / +109% | sign/s | +# |---------+----------------------+--------------+-------------| +# + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); +$avx512ifma=0; + +$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"; + +if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` + =~ /GNU assembler version ([2-9]\.[0-9]+)/) { + $avx512ifma = ($1>=2.26); +} + +if (!$avx512 && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) && + `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)(?:\.([0-9]+))?/) { + $avx512ifma = ($1==2.11 && $2>=8) + ($1>=2.12); +} + +if (!$avx512 && `$ENV{CC} -v 2>&1` + =~ /(Apple)?\s*((?:clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)\.([0-9]+)?/) { + my $ver = $3 + $4/100.0 + $5/10000.0; # 3.1.0->3.01, 3.10.1->3.1001 + if ($1) { + # Apple conditions, they use a different version series, see + # https://en.wikipedia.org/wiki/Xcode#Xcode_7.0_-_10.x_(since_Free_On-Device_Development)_2 + # clang 7.0.0 is Apple clang 10.0.1 + $avx512ifma = ($ver>=10.0001) + } else { + $avx512ifma = ($3>=7.0); + } +} + +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; +*STDOUT=*OUT; + +if ($avx512ifma>0) {{{ +@_6_args_universal_ABI = ("%rdi","%rsi","%rdx","%rcx","%r8","%r9"); + +$code.=<<___; +.extern OPENSSL_ia32cap_P +.globl ossl_rsaz_avx512ifma_eligible +.type ossl_rsaz_avx512ifma_eligible,\@abi-omnipotent +.align 32 +ossl_rsaz_avx512ifma_eligible: + mov OPENSSL_ia32cap_P+8(%rip), %ecx + xor %eax,%eax + and \$`1<<31|1<<21|1<<17|1<<16`, %ecx # avx512vl + avx512ifma + avx512dq + avx512f + cmp \$`1<<31|1<<21|1<<17|1<<16`, %ecx + cmove %ecx,%eax + ret +.size ossl_rsaz_avx512ifma_eligible, .-ossl_rsaz_avx512ifma_eligible +___ + +############################################################################### +# Almost Montgomery Multiplication (AMM) for 20-digit number in radix 2^52. +# +# AMM is defined as presented in the paper +# "Efficient Software Implementations of Modular Exponentiation" by Shay Gueron. +# +# The input and output are presented in 2^52 radix domain, i.e. +# |res|, |a|, |b|, |m| are arrays of 20 64-bit qwords with 12 high bits zeroed. +# |k0| is a Montgomery coefficient, which is here k0 = -1/m mod 2^64 +# (note, the implementation counts only 52 bits from it). +# +# NB: the AMM implementation does not perform "conditional" subtraction step as +# specified in the original algorithm as according to the paper "Enhanced Montgomery +# Multiplication" by Shay Gueron (see Lemma 1), the result will be always < 2*2^1024 +# and can be used as a direct input to the next AMM iteration. +# This post-condition is true, provided the correct parameter |s| is choosen, i.e. +# s >= n + 2 * k, which matches our case: 1040 > 1024 + 2 * 1. +# +# void ossl_rsaz_amm52x20_x1_256(BN_ULONG *res, +# const BN_ULONG *a, +# const BN_ULONG *b, +# const BN_ULONG *m, +# BN_ULONG k0); +############################################################################### +{ +# input parameters ("%rdi","%rsi","%rdx","%rcx","%r8") +my ($res,$a,$b,$m,$k0) = @_6_args_universal_ABI; + +my $mask52 = "%rax"; +my $acc0_0 = "%r9"; +my $acc0_0_low = "%r9d"; +my $acc0_1 = "%r15"; +my $acc0_1_low = "%r15d"; +my $b_ptr = "%r11"; + +my $iter = "%ebx"; + +my $zero = "%ymm0"; +my ($R0_0,$R0_0h,$R1_0,$R1_0h,$R2_0) = ("%ymm1", map("%ymm$_",(16..19))); +my ($R0_1,$R0_1h,$R1_1,$R1_1h,$R2_1) = ("%ymm2", map("%ymm$_",(20..23))); +my $Bi = "%ymm3"; +my $Yi = "%ymm4"; + +# Registers mapping for normalization. +# We can reuse Bi, Yi registers here. +my $TMP = $Bi; +my $mask52x4 = $Yi; +my ($T0,$T0h,$T1,$T1h,$T2) = map("%ymm$_", (24..28)); + +sub amm52x20_x1() { +# _data_offset - offset in the |a| or |m| arrays pointing to the beginning +# of data for corresponding AMM operation; +# _b_offset - offset in the |b| array pointing to the next qword digit; +my ($_data_offset,$_b_offset,$_acc,$_R0,$_R0h,$_R1,$_R1h,$_R2,$_k0) = @_; +my $_R0_xmm = $_R0; +$_R0_xmm =~ s/%y/%x/; +$code.=<<___; + movq $_b_offset($b_ptr), %r13 # b[i] + + vpbroadcastq %r13, $Bi # broadcast b[i] + movq $_data_offset($a), %rdx + mulx %r13, %r13, %r12 # a[0]*b[i] = (t0,t2) + addq %r13, $_acc # acc += t0 + movq %r12, %r10 + adcq \$0, %r10 # t2 += CF + + movq $_k0, %r13 + imulq $_acc, %r13 # acc * k0 + andq $mask52, %r13 # yi = (acc * k0) & mask52 + + vpbroadcastq %r13, $Yi # broadcast y[i] + movq $_data_offset($m), %rdx + mulx %r13, %r13, %r12 # yi * m[0] = (t0,t1) + addq %r13, $_acc # acc += t0 + adcq %r12, %r10 # t2 += (t1 + CF) + + shrq \$52, $_acc + salq \$12, %r10 + or %r10, $_acc # acc = ((acc >> 52) | (t2 << 12)) + + vpmadd52luq `$_data_offset+64*0`($a), $Bi, $_R0 + vpmadd52luq `$_data_offset+64*0+32`($a), $Bi, $_R0h + vpmadd52luq `$_data_offset+64*1`($a), $Bi, $_R1 + vpmadd52luq `$_data_offset+64*1+32`($a), $Bi, $_R1h + vpmadd52luq `$_data_offset+64*2`($a), $Bi, $_R2 + + vpmadd52luq `$_data_offset+64*0`($m), $Yi, $_R0 + vpmadd52luq `$_data_offset+64*0+32`($m), $Yi, $_R0h + vpmadd52luq `$_data_offset+64*1`($m), $Yi, $_R1 + vpmadd52luq `$_data_offset+64*1+32`($m), $Yi, $_R1h + vpmadd52luq `$_data_offset+64*2`($m), $Yi, $_R2 + + # Shift accumulators right by 1 qword, zero extending the highest one + valignq \$1, $_R0, $_R0h, $_R0 + valignq \$1, $_R0h, $_R1, $_R0h + valignq \$1, $_R1, $_R1h, $_R1 + valignq \$1, $_R1h, $_R2, $_R1h + valignq \$1, $_R2, $zero, $_R2 + + vmovq $_R0_xmm, %r13 + addq %r13, $_acc # acc += R0[0] + + vpmadd52huq `$_data_offset+64*0`($a), $Bi, $_R0 + vpmadd52huq `$_data_offset+64*0+32`($a), $Bi, $_R0h + vpmadd52huq `$_data_offset+64*1`($a), $Bi, $_R1 + vpmadd52huq `$_data_offset+64*1+32`($a), $Bi, $_R1h + vpmadd52huq `$_data_offset+64*2`($a), $Bi, $_R2 + + vpmadd52huq `$_data_offset+64*0`($m), $Yi, $_R0 + vpmadd52huq `$_data_offset+64*0+32`($m), $Yi, $_R0h + vpmadd52huq `$_data_offset+64*1`($m), $Yi, $_R1 + vpmadd52huq `$_data_offset+64*1+32`($m), $Yi, $_R1h + vpmadd52huq `$_data_offset+64*2`($m), $Yi, $_R2 +___ +} + +# Normalization routine: handles carry bits in R0..R2 QWs and +# gets R0..R2 back to normalized 2^52 representation. +# +# Uses %r8-14,%e[bcd]x +sub amm52x20_x1_norm { +my ($_acc,$_R0,$_R0h,$_R1,$_R1h,$_R2) = @_; +$code.=<<___; + # Put accumulator to low qword in R0 + vpbroadcastq $_acc, $TMP + vpblendd \$3, $TMP, $_R0, $_R0 + + # Extract "carries" (12 high bits) from each QW of R0..R2 + # Save them to LSB of QWs in T0..T2 + vpsrlq \$52, $_R0, $T0 + vpsrlq \$52, $_R0h, $T0h + vpsrlq \$52, $_R1, $T1 + vpsrlq \$52, $_R1h, $T1h + vpsrlq \$52, $_R2, $T2 + + # "Shift left" T0..T2 by 1 QW + valignq \$3, $T1h, $T2, $T2 + valignq \$3, $T1, $T1h, $T1h + valignq \$3, $T0h, $T1, $T1 + valignq \$3, $T0, $T0h, $T0h + valignq \$3, $zero, $T0, $T0 + + # Drop "carries" from R0..R2 QWs + vpandq $mask52x4, $_R0, $_R0 + vpandq $mask52x4, $_R0h, $_R0h + vpandq $mask52x4, $_R1, $_R1 + vpandq $mask52x4, $_R1h, $_R1h + vpandq $mask52x4, $_R2, $_R2 + + # Sum R0..R2 with corresponding adjusted carries + vpaddq $T0, $_R0, $_R0 + vpaddq $T0h, $_R0h, $_R0h + vpaddq $T1, $_R1, $_R1 + vpaddq $T1h, $_R1h, $_R1h + vpaddq $T2, $_R2, $_R2 + + # Now handle carry bits from this addition + # Get mask of QWs which 52-bit parts overflow... + vpcmpuq \$1, $_R0, $mask52x4, %k1 # OP=lt + vpcmpuq \$1, $_R0h, $mask52x4, %k2 + vpcmpuq \$1, $_R1, $mask52x4, %k3 + vpcmpuq \$1, $_R1h, $mask52x4, %k4 + vpcmpuq \$1, $_R2, $mask52x4, %k5 + kmovb %k1, %r14d # k1 + kmovb %k2, %r13d # k1h + kmovb %k3, %r12d # k2 + kmovb %k4, %r11d # k2h + kmovb %k5, %r10d # k3 + + # ...or saturated + vpcmpuq \$0, $_R0, $mask52x4, %k1 # OP=eq + vpcmpuq \$0, $_R0h, $mask52x4, %k2 + vpcmpuq \$0, $_R1, $mask52x4, %k3 + vpcmpuq \$0, $_R1h, $mask52x4, %k4 + vpcmpuq \$0, $_R2, $mask52x4, %k5 + kmovb %k1, %r9d # k4 + kmovb %k2, %r8d # k4h + kmovb %k3, %ebx # k5 + kmovb %k4, %ecx # k5h + kmovb %k5, %edx # k6 + + # Get mask of QWs where carries shall be propagated to. + # Merge 4-bit masks to 8-bit values to use add with carry. + shl \$4, %r13b + or %r13b, %r14b + shl \$4, %r11b + or %r11b, %r12b + + add %r14b, %r14b + adc %r12b, %r12b + adc %r10b, %r10b + + shl \$4, %r8b + or %r8b,%r9b + shl \$4, %cl + or %cl, %bl + + add %r9b, %r14b + adc %bl, %r12b + adc %dl, %r10b + + xor %r9b, %r14b + xor %bl, %r12b + xor %dl, %r10b + + kmovb %r14d, %k1 + shr \$4, %r14b + kmovb %r14d, %k2 + kmovb %r12d, %k3 + shr \$4, %r12b + kmovb %r12d, %k4 + kmovb %r10d, %k5 + + # Add carries according to the obtained mask + vpsubq $mask52x4, $_R0, ${_R0}{%k1} + vpsubq $mask52x4, $_R0h, ${_R0h}{%k2} + vpsubq $mask52x4, $_R1, ${_R1}{%k3} + vpsubq $mask52x4, $_R1h, ${_R1h}{%k4} + vpsubq $mask52x4, $_R2, ${_R2}{%k5} + + vpandq $mask52x4, $_R0, $_R0 + vpandq $mask52x4, $_R0h, $_R0h + vpandq $mask52x4, $_R1, $_R1 + vpandq $mask52x4, $_R1h, $_R1h + vpandq $mask52x4, $_R2, $_R2 +___ +} + +$code.=<<___; +.text + +.globl ossl_rsaz_amm52x20_x1_256 +.type ossl_rsaz_amm52x20_x1_256,\@function,5 +.align 32 +ossl_rsaz_amm52x20_x1_256: +.cfi_startproc + endbranch + 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 +.Lrsaz_amm52x20_x1_256_body: + + # Zeroing accumulators + vpxord $zero, $zero, $zero + vmovdqa64 $zero, $R0_0 + vmovdqa64 $zero, $R0_0h + vmovdqa64 $zero, $R1_0 + vmovdqa64 $zero, $R1_0h + vmovdqa64 $zero, $R2_0 + + xorl $acc0_0_low, $acc0_0_low + + movq $b, $b_ptr # backup address of b + movq \$0xfffffffffffff, $mask52 # 52-bit mask + + # Loop over 20 digits unrolled by 4 + mov \$5, $iter + +.align 32 +.Lloop5: +___ + foreach my $idx (0..3) { + &amm52x20_x1(0,8*$idx,$acc0_0,$R0_0,$R0_0h,$R1_0,$R1_0h,$R2_0,$k0); + } +$code.=<<___; + lea `4*8`($b_ptr), $b_ptr + dec $iter + jne .Lloop5 + + vmovdqa64 .Lmask52x4(%rip), $mask52x4 +___ + &amm52x20_x1_norm($acc0_0,$R0_0,$R0_0h,$R1_0,$R1_0h,$R2_0); +$code.=<<___; + + vmovdqu64 $R0_0, ($res) + vmovdqu64 $R0_0h, 32($res) + vmovdqu64 $R1_0, 64($res) + vmovdqu64 $R1_0h, 96($res) + vmovdqu64 $R2_0, 128($res) + + vzeroupper + mov 0(%rsp),%r15 +.cfi_restore %r15 + mov 8(%rsp),%r14 +.cfi_restore %r14 + mov 16(%rsp),%r13 +.cfi_restore %r13 + mov 24(%rsp),%r12 +.cfi_restore %r12 + mov 32(%rsp),%rbp +.cfi_restore %rbp + mov 40(%rsp),%rbx +.cfi_restore %rbx + lea 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lrsaz_amm52x20_x1_256_epilogue: + ret +.cfi_endproc +.size ossl_rsaz_amm52x20_x1_256, .-ossl_rsaz_amm52x20_x1_256 +___ + +$code.=<<___; +.data +.align 32 +.Lmask52x4: + .quad 0xfffffffffffff + .quad 0xfffffffffffff + .quad 0xfffffffffffff + .quad 0xfffffffffffff +___ + +############################################################################### +# Dual Almost Montgomery Multiplication for 20-digit number in radix 2^52 +# +# See description of ossl_rsaz_amm52x20_x1_256() above for details about Almost +# Montgomery Multiplication algorithm and function input parameters description. +# +# This function does two AMMs for two independent inputs, hence dual. +# +# void ossl_rsaz_amm52x20_x2_256(BN_ULONG out[2][20], +# const BN_ULONG a[2][20], +# const BN_ULONG b[2][20], +# const BN_ULONG m[2][20], +# const BN_ULONG k0[2]); +############################################################################### + +$code.=<<___; +.text + +.globl ossl_rsaz_amm52x20_x2_256 +.type ossl_rsaz_amm52x20_x2_256,\@function,5 +.align 32 +ossl_rsaz_amm52x20_x2_256: +.cfi_startproc + endbranch + 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 +.Lrsaz_amm52x20_x2_256_body: + + # Zeroing accumulators + vpxord $zero, $zero, $zero + vmovdqa64 $zero, $R0_0 + vmovdqa64 $zero, $R0_0h + vmovdqa64 $zero, $R1_0 + vmovdqa64 $zero, $R1_0h + vmovdqa64 $zero, $R2_0 + vmovdqa64 $zero, $R0_1 + vmovdqa64 $zero, $R0_1h + vmovdqa64 $zero, $R1_1 + vmovdqa64 $zero, $R1_1h + vmovdqa64 $zero, $R2_1 + + xorl $acc0_0_low, $acc0_0_low + xorl $acc0_1_low, $acc0_1_low + + movq $b, $b_ptr # backup address of b + movq \$0xfffffffffffff, $mask52 # 52-bit mask + + mov \$20, $iter + +.align 32 +.Lloop20: +___ + &amm52x20_x1( 0, 0,$acc0_0,$R0_0,$R0_0h,$R1_0,$R1_0h,$R2_0,"($k0)"); + # 20*8 = offset of the next dimension in two-dimension array + &amm52x20_x1(20*8,20*8,$acc0_1,$R0_1,$R0_1h,$R1_1,$R1_1h,$R2_1,"8($k0)"); +$code.=<<___; + lea 8($b_ptr), $b_ptr + dec $iter + jne .Lloop20 + + vmovdqa64 .Lmask52x4(%rip), $mask52x4 +___ + &amm52x20_x1_norm($acc0_0,$R0_0,$R0_0h,$R1_0,$R1_0h,$R2_0); + &amm52x20_x1_norm($acc0_1,$R0_1,$R0_1h,$R1_1,$R1_1h,$R2_1); +$code.=<<___; + + vmovdqu64 $R0_0, ($res) + vmovdqu64 $R0_0h, 32($res) + vmovdqu64 $R1_0, 64($res) + vmovdqu64 $R1_0h, 96($res) + vmovdqu64 $R2_0, 128($res) + + vmovdqu64 $R0_1, 160($res) + vmovdqu64 $R0_1h, 192($res) + vmovdqu64 $R1_1, 224($res) + vmovdqu64 $R1_1h, 256($res) + vmovdqu64 $R2_1, 288($res) + + vzeroupper + mov 0(%rsp),%r15 +.cfi_restore %r15 + mov 8(%rsp),%r14 +.cfi_restore %r14 + mov 16(%rsp),%r13 +.cfi_restore %r13 + mov 24(%rsp),%r12 +.cfi_restore %r12 + mov 32(%rsp),%rbp +.cfi_restore %rbp + mov 40(%rsp),%rbx +.cfi_restore %rbx + lea 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lrsaz_amm52x20_x2_256_epilogue: + ret +.cfi_endproc +.size ossl_rsaz_amm52x20_x2_256, .-ossl_rsaz_amm52x20_x2_256 +___ +} + +############################################################################### +# Constant time extraction from the precomputed table of powers base^i, where +# i = 0..2^EXP_WIN_SIZE-1 +# +# The input |red_table| contains precomputations for two independent base values, +# so the |tbl_idx| indicates for which base shall we extract the value. +# |red_table_idx| is a power index. +# +# Extracted value (output) is 20 digit number in 2^52 radix. +# +# void ossl_extract_multiplier_2x20_win5(BN_ULONG *red_Y, +# const BN_ULONG red_table[1 << EXP_WIN_SIZE][2][20], +# int red_table_idx, +# int tbl_idx); # 0 or 1 +# +# EXP_WIN_SIZE = 5 +############################################################################### +{ +# input parameters +my ($out,$red_tbl,$red_tbl_idx,$tbl_idx) = @_6_args_universal_ABI; + +my ($t0,$t1,$t2,$t3,$t4) = map("%ymm$_", (0..4)); +my $t4xmm = $t4; +$t4xmm =~ s/%y/%x/; +my ($tmp0,$tmp1,$tmp2,$tmp3,$tmp4) = map("%ymm$_", (16..20)); +my ($cur_idx,$idx,$ones) = map("%ymm$_", (21..23)); + +$code.=<<___; +.text + +.align 32 +.globl ossl_extract_multiplier_2x20_win5 +.type ossl_extract_multiplier_2x20_win5,\@function,4 +ossl_extract_multiplier_2x20_win5: +.cfi_startproc + endbranch + leaq ($tbl_idx,$tbl_idx,4), %rax + salq \$5, %rax + addq %rax, $red_tbl + + vmovdqa64 .Lones(%rip), $ones # broadcast ones + vpbroadcastq $red_tbl_idx, $idx + leaq `(1<<5)*2*20*8`($red_tbl), %rax # holds end of the tbl + + vpxor $t4xmm, $t4xmm, $t4xmm + vmovdqa64 $t4, $t3 # zeroing t0..4, cur_idx + vmovdqa64 $t4, $t2 + vmovdqa64 $t4, $t1 + vmovdqa64 $t4, $t0 + vmovdqa64 $t4, $cur_idx + +.align 32 +.Lloop: + vpcmpq \$0, $cur_idx, $idx, %k1 # mask of (idx == cur_idx) + addq \$320, $red_tbl # 320 = 2 * 20 digits * 8 bytes + vpaddq $ones, $cur_idx, $cur_idx # increment cur_idx + vmovdqu64 -320($red_tbl), $tmp0 # load data from red_tbl + vmovdqu64 -288($red_tbl), $tmp1 + vmovdqu64 -256($red_tbl), $tmp2 + vmovdqu64 -224($red_tbl), $tmp3 + vmovdqu64 -192($red_tbl), $tmp4 + vpblendmq $tmp0, $t0, ${t0}{%k1} # extract data when mask is not zero + vpblendmq $tmp1, $t1, ${t1}{%k1} + vpblendmq $tmp2, $t2, ${t2}{%k1} + vpblendmq $tmp3, $t3, ${t3}{%k1} + vpblendmq $tmp4, $t4, ${t4}{%k1} + cmpq $red_tbl, %rax + jne .Lloop + + vmovdqu64 $t0, ($out) # store t0..4 + vmovdqu64 $t1, 32($out) + vmovdqu64 $t2, 64($out) + vmovdqu64 $t3, 96($out) + vmovdqu64 $t4, 128($out) + + ret +.cfi_endproc +.size ossl_extract_multiplier_2x20_win5, .-ossl_extract_multiplier_2x20_win5 +___ +$code.=<<___; +.data +.align 32 +.Lones: + .quad 1,1,1,1 +___ +} + +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___ +.extern __imp_RtlVirtualUnwind +.type rsaz_def_handler,\@abi-omnipotent +.align 16 +rsaz_def_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<.Lprologue + jb .Lcommon_seh_tail + + mov 152($context),%rax # pull context->Rsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=.Lepilogue + jae .Lcommon_seh_tail + + lea 48(%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->R14 + +.Lcommon_seh_tail: + 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 + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%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 rsaz_def_handler,.-rsaz_def_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_ossl_rsaz_amm52x20_x1_256 + .rva .LSEH_end_ossl_rsaz_amm52x20_x1_256 + .rva .LSEH_info_ossl_rsaz_amm52x20_x1_256 + + .rva .LSEH_begin_ossl_rsaz_amm52x20_x2_256 + .rva .LSEH_end_ossl_rsaz_amm52x20_x2_256 + .rva .LSEH_info_ossl_rsaz_amm52x20_x2_256 + + .rva .LSEH_begin_ossl_extract_multiplier_2x20_win5 + .rva .LSEH_end_ossl_extract_multiplier_2x20_win5 + .rva .LSEH_info_ossl_extract_multiplier_2x20_win5 + +.section .xdata +.align 8 +.LSEH_info_ossl_rsaz_amm52x20_x1_256: + .byte 9,0,0,0 + .rva rsaz_def_handler + .rva .Lrsaz_amm52x20_x1_256_body,.Lrsaz_amm52x20_x1_256_epilogue +.LSEH_info_ossl_rsaz_amm52x20_x2_256: + .byte 9,0,0,0 + .rva rsaz_def_handler + .rva .Lrsaz_amm52x20_x2_256_body,.Lrsaz_amm52x20_x2_256_epilogue +.LSEH_info_ossl_extract_multiplier_2x20_win5: + .byte 9,0,0,0 + .rva rsaz_def_handler + .rva .LSEH_begin_ossl_extract_multiplier_2x20_win5,.LSEH_begin_ossl_extract_multiplier_2x20_win5 +___ +} +}}} else {{{ # fallback for old assembler +$code.=<<___; +.text + +.globl ossl_rsaz_avx512ifma_eligible +.type ossl_rsaz_avx512ifma_eligible,\@abi-omnipotent +ossl_rsaz_avx512ifma_eligible: + xor %eax,%eax + ret +.size ossl_rsaz_avx512ifma_eligible, .-ossl_rsaz_avx512ifma_eligible + +.globl ossl_rsaz_amm52x20_x1_256 +.globl ossl_rsaz_amm52x20_x2_256 +.globl ossl_extract_multiplier_2x20_win5 +.type ossl_rsaz_amm52x20_x1_256,\@abi-omnipotent +ossl_rsaz_amm52x20_x1_256: +ossl_rsaz_amm52x20_x2_256: +ossl_extract_multiplier_2x20_win5: + .byte 0x0f,0x0b # ud2 + ret +.size ossl_rsaz_amm52x20_x1_256, .-ossl_rsaz_amm52x20_x1_256 +___ +}}} + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/bn/asm/rsaz-x86_64.pl b/crypto/openssl/crypto/bn/asm/rsaz-x86_64.pl index cf08ce9b8356..5c7d526fa37a 100755 --- a/crypto/openssl/crypto/bn/asm/rsaz-x86_64.pl +++ b/crypto/openssl/crypto/bn/asm/rsaz-x86_64.pl @@ -2,7 +2,7 @@ # Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2012, Intel Corporation. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -52,9 +52,10 @@ # purposes; # (**) MULX was attempted, but found to give only marginal improvement; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -63,7 +64,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` diff --git a/crypto/openssl/crypto/bn/asm/s390x-gf2m.pl b/crypto/openssl/crypto/bn/asm/s390x-gf2m.pl index a7e4b8a97d30..038a6bc97440 100755 --- a/crypto/openssl/crypto/bn/asm/s390x-gf2m.pl +++ b/crypto/openssl/crypto/bn/asm/s390x-gf2m.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -32,7 +32,10 @@ # so that improvement coefficients can vary from one specific # setup to another. -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -42,8 +45,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $stdframe=16*$SIZE_T+4*8; diff --git a/crypto/openssl/crypto/bn/asm/s390x-mont.pl b/crypto/openssl/crypto/bn/asm/s390x-mont.pl index bc8c8951e060..af088ccae10d 100755 --- a/crypto/openssl/crypto/bn/asm/s390x-mont.pl +++ b/crypto/openssl/crypto/bn/asm/s390x-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -51,7 +51,10 @@ # On z990 it was measured to perform 2.6-2.2 times better than # compiler-generated code, less for longer keys... -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -61,8 +64,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $stdframe=16*$SIZE_T+4*8; diff --git a/crypto/openssl/crypto/bn/asm/s390x.S b/crypto/openssl/crypto/bn/asm/s390x.S index b666c41a88a4..65a0898739b6 100644 --- a/crypto/openssl/crypto/bn/asm/s390x.S +++ b/crypto/openssl/crypto/bn/asm/s390x.S @@ -2,7 +2,7 @@ // ==================================================================== // Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. // -// Licensed under the OpenSSL license (the "License"). You may not use +// 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 diff --git a/crypto/openssl/crypto/bn/asm/sparct4-mont.pl b/crypto/openssl/crypto/bn/asm/sparct4-mont.pl index 62e297a01692..8a3bedc9af42 100755 --- a/crypto/openssl/crypto/bn/asm/sparct4-mont.pl +++ b/crypto/openssl/crypto/bn/asm/sparct4-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -83,11 +83,13 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "sparcv9_modes.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #ifdef __arch64__ .register %g2,#scratch diff --git a/crypto/openssl/crypto/bn/asm/sparcv8.S b/crypto/openssl/crypto/bn/asm/sparcv8.S index 75d72eb92c74..94487008443e 100644 --- a/crypto/openssl/crypto/bn/asm/sparcv8.S +++ b/crypto/openssl/crypto/bn/asm/sparcv8.S @@ -5,7 +5,7 @@ * ==================================================================== * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bn/asm/sparcv8plus.S b/crypto/openssl/crypto/bn/asm/sparcv8plus.S index d520ffa7c248..696dc7b5fe09 100644 --- a/crypto/openssl/crypto/bn/asm/sparcv8plus.S +++ b/crypto/openssl/crypto/bn/asm/sparcv8plus.S @@ -3,9 +3,9 @@ /* * ==================================================================== - * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bn/asm/sparcv9-gf2m.pl b/crypto/openssl/crypto/bn/asm/sparcv9-gf2m.pl index 238a93dca56c..9f773f183c96 100755 --- a/crypto/openssl/crypto/bn/asm/sparcv9-gf2m.pl +++ b/crypto/openssl/crypto/bn/asm/sparcv9-gf2m.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -25,8 +25,7 @@ # ~100-230% faster than gcc-generated code and ~35-90% faster than # the pure SPARCv9 code path. -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $locals=16*8; @@ -39,7 +38,10 @@ $tab="%l0"; ($lo,$hi,$b)=("%g1",$a8,"%o7"); $a=$lo; $code.=<<___; -#include +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #ifdef __arch64__ .register %g2,#scratch diff --git a/crypto/openssl/crypto/bn/asm/sparcv9-mont.pl b/crypto/openssl/crypto/bn/asm/sparcv9-mont.pl index d1a3c2bc4343..fe51fcaf81c7 100755 --- a/crypto/openssl/crypto/bn/asm/sparcv9-mont.pl +++ b/crypto/openssl/crypto/bn/asm/sparcv9-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -49,8 +49,7 @@ # module still have hidden potential [see TODO list there], which is # estimated to be larger than 20%... -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; # int bn_mul_mont( $rp="%i0"; # BN_ULONG *rp, @@ -84,7 +83,10 @@ $tpj="%l7"; $fname="bn_mul_mont_int"; $code=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" .section ".text",#alloc,#execinstr diff --git a/crypto/openssl/crypto/bn/asm/sparcv9a-mont.pl b/crypto/openssl/crypto/bn/asm/sparcv9a-mont.pl index 7a1fca1263a9..08773bc75835 100755 --- a/crypto/openssl/crypto/bn/asm/sparcv9a-mont.pl +++ b/crypto/openssl/crypto/bn/asm/sparcv9a-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -62,8 +62,10 @@ # key length, more for longer keys] on USI&II cores and 30-80% - on # USIII&IV. -$output = pop; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; + +$output and open STDOUT,">$output"; $fname="bn_mul_mont_fpu"; @@ -124,7 +126,10 @@ $nhia="%f56"; $nhib="%f58"; $nhic="%f60"; $nhid="%f62"; $ASI_FL16_P=0xD2; # magic ASI value to engage 16-bit FP load $code=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" .section ".text",#alloc,#execinstr diff --git a/crypto/openssl/crypto/bn/asm/via-mont.pl b/crypto/openssl/crypto/bn/asm/via-mont.pl index 9dbc8d458792..365dc652fe51 100755 --- a/crypto/openssl/crypto/bn/asm/via-mont.pl +++ b/crypto/openssl/crypto/bn/asm/via-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -88,8 +88,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/openssl/crypto/bn/asm/vis3-mont.pl b/crypto/openssl/crypto/bn/asm/vis3-mont.pl index d797af8745dc..f7e6c38635ac 100755 --- a/crypto/openssl/crypto/bn/asm/vis3-mont.pl +++ b/crypto/openssl/crypto/bn/asm/vis3-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -25,14 +25,16 @@ # for reference purposes, because T4 has dedicated Montgomery # multiplication and squaring *instructions* that deliver even more. -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $frame = "STACK_FRAME"; $bias = "STACK_BIAS"; $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #ifdef __arch64__ .register %g2,#scratch diff --git a/crypto/openssl/crypto/bn/asm/x86-gf2m.pl b/crypto/openssl/crypto/bn/asm/x86-gf2m.pl index 436d90b11ea4..469effd39e56 100755 --- a/crypto/openssl/crypto/bn/asm/x86-gf2m.pl +++ b/crypto/openssl/crypto/bn/asm/x86-gf2m.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -43,8 +43,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$x86only = $ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/bn/asm/x86-mont.pl b/crypto/openssl/crypto/bn/asm/x86-mont.pl index 2103f806b65a..8fff9e1d3686 100755 --- a/crypto/openssl/crypto/bn/asm/x86-mont.pl +++ b/crypto/openssl/crypto/bn/asm/x86-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -37,8 +37,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/openssl/crypto/bn/asm/x86_64-gcc.c b/crypto/openssl/crypto/bn/asm/x86_64-gcc.c index e6fdaadf0e91..68453b3d5276 100644 --- a/crypto/openssl/crypto/bn/asm/x86_64-gcc.c +++ b/crypto/openssl/crypto/bn/asm/x86_64-gcc.c @@ -1,7 +1,7 @@ /* * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -18,8 +18,7 @@ * project. * * Rights for redistribution and usage in source and binary forms are - * granted according to the OpenSSL license. Warranty of any kind is - * disclaimed. + * granted according to the License. Warranty of any kind is disclaimed. * * Q. Version 0.1? It doesn't sound like Andy, he used to assign real * versions, like 1.0... diff --git a/crypto/openssl/crypto/bn/asm/x86_64-gf2m.pl b/crypto/openssl/crypto/bn/asm/x86_64-gf2m.pl index 655f13c89ee8..4c4dfc41ffe6 100755 --- a/crypto/openssl/crypto/bn/asm/x86_64-gf2m.pl +++ b/crypto/openssl/crypto/bn/asm/x86_64-gf2m.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -27,9 +27,10 @@ # these coefficients are not ones for bn_GF2m_mul_2x2 itself, as not # all CPU time is burnt in it... -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -38,7 +39,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; ($lo,$hi)=("%rax","%rdx"); $a=$lo; diff --git a/crypto/openssl/crypto/bn/asm/x86_64-mont.pl b/crypto/openssl/crypto/bn/asm/x86_64-mont.pl index f14d4e63b975..140072b899dc 100755 --- a/crypto/openssl/crypto/bn/asm/x86_64-mont.pl +++ b/crypto/openssl/crypto/bn/asm/x86_64-mont.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -46,9 +46,10 @@ # # Add MULX/ADOX/ADCX code path. -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -57,7 +58,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` diff --git a/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl b/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl index 33cb769c36d5..185d9e76ce23 100755 --- a/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl +++ b/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2011-2022 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -31,9 +31,10 @@ # the np argument is not just modulus value, but one interleaved # with 0. This is to optimize post-condition... -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -42,7 +43,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` diff --git a/crypto/openssl/crypto/bn/bn-586.S b/crypto/openssl/crypto/bn/bn-586.S new file mode 100644 index 000000000000..a74e6470b438 --- /dev/null +++ b/crypto/openssl/crypto/bn/bn-586.S @@ -0,0 +1,1581 @@ +.text +.globl bn_mul_add_words +.type bn_mul_add_words,@function +.align 16 +bn_mul_add_words: +.L_bn_mul_add_words_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + call .L000PIC_me_up +.L000PIC_me_up: + popl %eax + leal OPENSSL_ia32cap_P-.L000PIC_me_up(%eax),%eax + btl $26,(%eax) + jnc .L001maw_non_sse2 + movl 4(%esp),%eax + movl 8(%esp),%edx + movl 12(%esp),%ecx + movd 16(%esp),%mm0 + pxor %mm1,%mm1 + jmp .L002maw_sse2_entry +.align 16 +.L003maw_sse2_unrolled: + movd (%eax),%mm3 + paddq %mm3,%mm1 + movd (%edx),%mm2 + pmuludq %mm0,%mm2 + movd 4(%edx),%mm4 + pmuludq %mm0,%mm4 + movd 8(%edx),%mm6 + pmuludq %mm0,%mm6 + movd 12(%edx),%mm7 + pmuludq %mm0,%mm7 + paddq %mm2,%mm1 + movd 4(%eax),%mm3 + paddq %mm4,%mm3 + movd 8(%eax),%mm5 + paddq %mm6,%mm5 + movd 12(%eax),%mm4 + paddq %mm4,%mm7 + movd %mm1,(%eax) + movd 16(%edx),%mm2 + pmuludq %mm0,%mm2 + psrlq $32,%mm1 + movd 20(%edx),%mm4 + pmuludq %mm0,%mm4 + paddq %mm3,%mm1 + movd 24(%edx),%mm6 + pmuludq %mm0,%mm6 + movd %mm1,4(%eax) + psrlq $32,%mm1 + movd 28(%edx),%mm3 + addl $32,%edx + pmuludq %mm0,%mm3 + paddq %mm5,%mm1 + movd 16(%eax),%mm5 + paddq %mm5,%mm2 + movd %mm1,8(%eax) + psrlq $32,%mm1 + paddq %mm7,%mm1 + movd 20(%eax),%mm5 + paddq %mm5,%mm4 + movd %mm1,12(%eax) + psrlq $32,%mm1 + paddq %mm2,%mm1 + movd 24(%eax),%mm5 + paddq %mm5,%mm6 + movd %mm1,16(%eax) + psrlq $32,%mm1 + paddq %mm4,%mm1 + movd 28(%eax),%mm5 + paddq %mm5,%mm3 + movd %mm1,20(%eax) + psrlq $32,%mm1 + paddq %mm6,%mm1 + movd %mm1,24(%eax) + psrlq $32,%mm1 + paddq %mm3,%mm1 + movd %mm1,28(%eax) + leal 32(%eax),%eax + psrlq $32,%mm1 + subl $8,%ecx + jz .L004maw_sse2_exit +.L002maw_sse2_entry: + testl $4294967288,%ecx + jnz .L003maw_sse2_unrolled +.align 4 +.L005maw_sse2_loop: + movd (%edx),%mm2 + movd (%eax),%mm3 + pmuludq %mm0,%mm2 + leal 4(%edx),%edx + paddq %mm3,%mm1 + paddq %mm2,%mm1 + movd %mm1,(%eax) + subl $1,%ecx + psrlq $32,%mm1 + leal 4(%eax),%eax + jnz .L005maw_sse2_loop +.L004maw_sse2_exit: + movd %mm1,%eax + emms + ret +.align 16 +.L001maw_non_sse2: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + xorl %esi,%esi + movl 20(%esp),%edi + movl 28(%esp),%ecx + movl 24(%esp),%ebx + andl $4294967288,%ecx + movl 32(%esp),%ebp + pushl %ecx + jz .L006maw_finish +.align 16 +.L007maw_loop: + + movl (%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl (%edi),%eax + adcl $0,%edx + movl %eax,(%edi) + movl %edx,%esi + + movl 4(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 4(%edi),%eax + adcl $0,%edx + movl %eax,4(%edi) + movl %edx,%esi + + movl 8(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 8(%edi),%eax + adcl $0,%edx + movl %eax,8(%edi) + movl %edx,%esi + + movl 12(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 12(%edi),%eax + adcl $0,%edx + movl %eax,12(%edi) + movl %edx,%esi + + movl 16(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 16(%edi),%eax + adcl $0,%edx + movl %eax,16(%edi) + movl %edx,%esi + + movl 20(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 20(%edi),%eax + adcl $0,%edx + movl %eax,20(%edi) + movl %edx,%esi + + movl 24(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 24(%edi),%eax + adcl $0,%edx + movl %eax,24(%edi) + movl %edx,%esi + + movl 28(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 28(%edi),%eax + adcl $0,%edx + movl %eax,28(%edi) + movl %edx,%esi + + subl $8,%ecx + leal 32(%ebx),%ebx + leal 32(%edi),%edi + jnz .L007maw_loop +.L006maw_finish: + movl 32(%esp),%ecx + andl $7,%ecx + jnz .L008maw_finish2 + jmp .L009maw_end +.L008maw_finish2: + + movl (%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl (%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 4(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 4(%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,4(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 8(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 8(%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,8(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 12(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 12(%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,12(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 16(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 16(%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,16(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 20(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 20(%edi),%eax + adcl $0,%edx + decl %ecx + movl %eax,20(%edi) + movl %edx,%esi + jz .L009maw_end + + movl 24(%ebx),%eax + mull %ebp + addl %esi,%eax + adcl $0,%edx + addl 24(%edi),%eax + adcl $0,%edx + movl %eax,24(%edi) + movl %edx,%esi +.L009maw_end: + movl %esi,%eax + popl %ecx + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_mul_add_words,.-.L_bn_mul_add_words_begin +.globl bn_mul_words +.type bn_mul_words,@function +.align 16 +bn_mul_words: +.L_bn_mul_words_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + call .L010PIC_me_up +.L010PIC_me_up: + popl %eax + leal OPENSSL_ia32cap_P-.L010PIC_me_up(%eax),%eax + btl $26,(%eax) + jnc .L011mw_non_sse2 + movl 4(%esp),%eax + movl 8(%esp),%edx + movl 12(%esp),%ecx + movd 16(%esp),%mm0 + pxor %mm1,%mm1 +.align 16 +.L012mw_sse2_loop: + movd (%edx),%mm2 + pmuludq %mm0,%mm2 + leal 4(%edx),%edx + paddq %mm2,%mm1 + movd %mm1,(%eax) + subl $1,%ecx + psrlq $32,%mm1 + leal 4(%eax),%eax + jnz .L012mw_sse2_loop + movd %mm1,%eax + emms + ret +.align 16 +.L011mw_non_sse2: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + xorl %esi,%esi + movl 20(%esp),%edi + movl 24(%esp),%ebx + movl 28(%esp),%ebp + movl 32(%esp),%ecx + andl $4294967288,%ebp + jz .L013mw_finish +.L014mw_loop: + + movl (%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,(%edi) + movl %edx,%esi + + movl 4(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,4(%edi) + movl %edx,%esi + + movl 8(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,8(%edi) + movl %edx,%esi + + movl 12(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,12(%edi) + movl %edx,%esi + + movl 16(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,16(%edi) + movl %edx,%esi + + movl 20(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,20(%edi) + movl %edx,%esi + + movl 24(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,24(%edi) + movl %edx,%esi + + movl 28(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,28(%edi) + movl %edx,%esi + + addl $32,%ebx + addl $32,%edi + subl $8,%ebp + jz .L013mw_finish + jmp .L014mw_loop +.L013mw_finish: + movl 28(%esp),%ebp + andl $7,%ebp + jnz .L015mw_finish2 + jmp .L016mw_end +.L015mw_finish2: + + movl (%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 4(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,4(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 8(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,8(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 12(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,12(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 16(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,16(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 20(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,20(%edi) + movl %edx,%esi + decl %ebp + jz .L016mw_end + + movl 24(%ebx),%eax + mull %ecx + addl %esi,%eax + adcl $0,%edx + movl %eax,24(%edi) + movl %edx,%esi +.L016mw_end: + movl %esi,%eax + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_mul_words,.-.L_bn_mul_words_begin +.globl bn_sqr_words +.type bn_sqr_words,@function +.align 16 +bn_sqr_words: +.L_bn_sqr_words_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + call .L017PIC_me_up +.L017PIC_me_up: + popl %eax + leal OPENSSL_ia32cap_P-.L017PIC_me_up(%eax),%eax + btl $26,(%eax) + jnc .L018sqr_non_sse2 + movl 4(%esp),%eax + movl 8(%esp),%edx + movl 12(%esp),%ecx +.align 16 +.L019sqr_sse2_loop: + movd (%edx),%mm0 + pmuludq %mm0,%mm0 + leal 4(%edx),%edx + movq %mm0,(%eax) + subl $1,%ecx + leal 8(%eax),%eax + jnz .L019sqr_sse2_loop + emms + ret +.align 16 +.L018sqr_non_sse2: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%ebx + andl $4294967288,%ebx + jz .L020sw_finish +.L021sw_loop: + + movl (%edi),%eax + mull %eax + movl %eax,(%esi) + movl %edx,4(%esi) + + movl 4(%edi),%eax + mull %eax + movl %eax,8(%esi) + movl %edx,12(%esi) + + movl 8(%edi),%eax + mull %eax + movl %eax,16(%esi) + movl %edx,20(%esi) + + movl 12(%edi),%eax + mull %eax + movl %eax,24(%esi) + movl %edx,28(%esi) + + movl 16(%edi),%eax + mull %eax + movl %eax,32(%esi) + movl %edx,36(%esi) + + movl 20(%edi),%eax + mull %eax + movl %eax,40(%esi) + movl %edx,44(%esi) + + movl 24(%edi),%eax + mull %eax + movl %eax,48(%esi) + movl %edx,52(%esi) + + movl 28(%edi),%eax + mull %eax + movl %eax,56(%esi) + movl %edx,60(%esi) + + addl $32,%edi + addl $64,%esi + subl $8,%ebx + jnz .L021sw_loop +.L020sw_finish: + movl 28(%esp),%ebx + andl $7,%ebx + jz .L022sw_end + + movl (%edi),%eax + mull %eax + movl %eax,(%esi) + decl %ebx + movl %edx,4(%esi) + jz .L022sw_end + + movl 4(%edi),%eax + mull %eax + movl %eax,8(%esi) + decl %ebx + movl %edx,12(%esi) + jz .L022sw_end + + movl 8(%edi),%eax + mull %eax + movl %eax,16(%esi) + decl %ebx + movl %edx,20(%esi) + jz .L022sw_end + + movl 12(%edi),%eax + mull %eax + movl %eax,24(%esi) + decl %ebx + movl %edx,28(%esi) + jz .L022sw_end + + movl 16(%edi),%eax + mull %eax + movl %eax,32(%esi) + decl %ebx + movl %edx,36(%esi) + jz .L022sw_end + + movl 20(%edi),%eax + mull %eax + movl %eax,40(%esi) + decl %ebx + movl %edx,44(%esi) + jz .L022sw_end + + movl 24(%edi),%eax + mull %eax + movl %eax,48(%esi) + movl %edx,52(%esi) +.L022sw_end: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_sqr_words,.-.L_bn_sqr_words_begin +.globl bn_div_words +.type bn_div_words,@function +.align 16 +bn_div_words: +.L_bn_div_words_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl 4(%esp),%edx + movl 8(%esp),%eax + movl 12(%esp),%ecx + divl %ecx + ret +.size bn_div_words,.-.L_bn_div_words_begin +.globl bn_add_words +.type bn_add_words,@function +.align 16 +bn_add_words: +.L_bn_add_words_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl 20(%esp),%ebx + movl 24(%esp),%esi + movl 28(%esp),%edi + movl 32(%esp),%ebp + xorl %eax,%eax + andl $4294967288,%ebp + jz .L023aw_finish +.L024aw_loop: + + movl (%esi),%ecx + movl (%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + + movl 4(%esi),%ecx + movl 4(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,4(%ebx) + + movl 8(%esi),%ecx + movl 8(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,8(%ebx) + + movl 12(%esi),%ecx + movl 12(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,12(%ebx) + + movl 16(%esi),%ecx + movl 16(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,16(%ebx) + + movl 20(%esi),%ecx + movl 20(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,20(%ebx) + + movl 24(%esi),%ecx + movl 24(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,24(%ebx) + + movl 28(%esi),%ecx + movl 28(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,28(%ebx) + + addl $32,%esi + addl $32,%edi + addl $32,%ebx + subl $8,%ebp + jnz .L024aw_loop +.L023aw_finish: + movl 32(%esp),%ebp + andl $7,%ebp + jz .L025aw_end + + movl (%esi),%ecx + movl (%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,(%ebx) + jz .L025aw_end + + movl 4(%esi),%ecx + movl 4(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,4(%ebx) + jz .L025aw_end + + movl 8(%esi),%ecx + movl 8(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,8(%ebx) + jz .L025aw_end + + movl 12(%esi),%ecx + movl 12(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,12(%ebx) + jz .L025aw_end + + movl 16(%esi),%ecx + movl 16(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,16(%ebx) + jz .L025aw_end + + movl 20(%esi),%ecx + movl 20(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,20(%ebx) + jz .L025aw_end + + movl 24(%esi),%ecx + movl 24(%edi),%edx + addl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + addl %edx,%ecx + adcl $0,%eax + movl %ecx,24(%ebx) +.L025aw_end: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_add_words,.-.L_bn_add_words_begin +.globl bn_sub_words +.type bn_sub_words,@function +.align 16 +bn_sub_words: +.L_bn_sub_words_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl 20(%esp),%ebx + movl 24(%esp),%esi + movl 28(%esp),%edi + movl 32(%esp),%ebp + xorl %eax,%eax + andl $4294967288,%ebp + jz .L026aw_finish +.L027aw_loop: + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + + movl 4(%esi),%ecx + movl 4(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,4(%ebx) + + movl 8(%esi),%ecx + movl 8(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,8(%ebx) + + movl 12(%esi),%ecx + movl 12(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,12(%ebx) + + movl 16(%esi),%ecx + movl 16(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,16(%ebx) + + movl 20(%esi),%ecx + movl 20(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,20(%ebx) + + movl 24(%esi),%ecx + movl 24(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,24(%ebx) + + movl 28(%esi),%ecx + movl 28(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,28(%ebx) + + addl $32,%esi + addl $32,%edi + addl $32,%ebx + subl $8,%ebp + jnz .L027aw_loop +.L026aw_finish: + movl 32(%esp),%ebp + andl $7,%ebp + jz .L028aw_end + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,(%ebx) + jz .L028aw_end + + movl 4(%esi),%ecx + movl 4(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,4(%ebx) + jz .L028aw_end + + movl 8(%esi),%ecx + movl 8(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,8(%ebx) + jz .L028aw_end + + movl 12(%esi),%ecx + movl 12(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,12(%ebx) + jz .L028aw_end + + movl 16(%esi),%ecx + movl 16(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,16(%ebx) + jz .L028aw_end + + movl 20(%esi),%ecx + movl 20(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,20(%ebx) + jz .L028aw_end + + movl 24(%esi),%ecx + movl 24(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,24(%ebx) +.L028aw_end: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_sub_words,.-.L_bn_sub_words_begin +.globl bn_sub_part_words +.type bn_sub_part_words,@function +.align 16 +bn_sub_part_words: +.L_bn_sub_part_words_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl 20(%esp),%ebx + movl 24(%esp),%esi + movl 28(%esp),%edi + movl 32(%esp),%ebp + xorl %eax,%eax + andl $4294967288,%ebp + jz .L029aw_finish +.L030aw_loop: + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + + movl 4(%esi),%ecx + movl 4(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,4(%ebx) + + movl 8(%esi),%ecx + movl 8(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,8(%ebx) + + movl 12(%esi),%ecx + movl 12(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,12(%ebx) + + movl 16(%esi),%ecx + movl 16(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,16(%ebx) + + movl 20(%esi),%ecx + movl 20(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,20(%ebx) + + movl 24(%esi),%ecx + movl 24(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,24(%ebx) + + movl 28(%esi),%ecx + movl 28(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,28(%ebx) + + addl $32,%esi + addl $32,%edi + addl $32,%ebx + subl $8,%ebp + jnz .L030aw_loop +.L029aw_finish: + movl 32(%esp),%ebp + andl $7,%ebp + jz .L031aw_end + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + addl $4,%esi + addl $4,%edi + addl $4,%ebx + decl %ebp + jz .L031aw_end + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + addl $4,%esi + addl $4,%edi + addl $4,%ebx + decl %ebp + jz .L031aw_end + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + addl $4,%esi + addl $4,%edi + addl $4,%ebx + decl %ebp + jz .L031aw_end + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + addl $4,%esi + addl $4,%edi + addl $4,%ebx + decl %ebp + jz .L031aw_end + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + addl $4,%esi + addl $4,%edi + addl $4,%ebx + decl %ebp + jz .L031aw_end + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + addl $4,%esi + addl $4,%edi + addl $4,%ebx + decl %ebp + jz .L031aw_end + + movl (%esi),%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + addl $4,%esi + addl $4,%edi + addl $4,%ebx +.L031aw_end: + cmpl $0,36(%esp) + je .L032pw_end + movl 36(%esp),%ebp + cmpl $0,%ebp + je .L032pw_end + jge .L033pw_pos + + movl $0,%edx + subl %ebp,%edx + movl %edx,%ebp + andl $4294967288,%ebp + jz .L034pw_neg_finish +.L035pw_neg_loop: + + movl $0,%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,(%ebx) + + movl $0,%ecx + movl 4(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,4(%ebx) + + movl $0,%ecx + movl 8(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,8(%ebx) + + movl $0,%ecx + movl 12(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,12(%ebx) + + movl $0,%ecx + movl 16(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,16(%ebx) + + movl $0,%ecx + movl 20(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,20(%ebx) + + movl $0,%ecx + movl 24(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,24(%ebx) + + movl $0,%ecx + movl 28(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,28(%ebx) + + addl $32,%edi + addl $32,%ebx + subl $8,%ebp + jnz .L035pw_neg_loop +.L034pw_neg_finish: + movl 36(%esp),%edx + movl $0,%ebp + subl %edx,%ebp + andl $7,%ebp + jz .L032pw_end + + movl $0,%ecx + movl (%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,(%ebx) + jz .L032pw_end + + movl $0,%ecx + movl 4(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,4(%ebx) + jz .L032pw_end + + movl $0,%ecx + movl 8(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,8(%ebx) + jz .L032pw_end + + movl $0,%ecx + movl 12(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,12(%ebx) + jz .L032pw_end + + movl $0,%ecx + movl 16(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,16(%ebx) + jz .L032pw_end + + movl $0,%ecx + movl 20(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + decl %ebp + movl %ecx,20(%ebx) + jz .L032pw_end + + movl $0,%ecx + movl 24(%edi),%edx + subl %eax,%ecx + movl $0,%eax + adcl %eax,%eax + subl %edx,%ecx + adcl $0,%eax + movl %ecx,24(%ebx) + jmp .L032pw_end +.L033pw_pos: + andl $4294967288,%ebp + jz .L036pw_pos_finish +.L037pw_pos_loop: + + movl (%esi),%ecx + subl %eax,%ecx + movl %ecx,(%ebx) + jnc .L038pw_nc0 + + movl 4(%esi),%ecx + subl %eax,%ecx + movl %ecx,4(%ebx) + jnc .L039pw_nc1 + + movl 8(%esi),%ecx + subl %eax,%ecx + movl %ecx,8(%ebx) + jnc .L040pw_nc2 + + movl 12(%esi),%ecx + subl %eax,%ecx + movl %ecx,12(%ebx) + jnc .L041pw_nc3 + + movl 16(%esi),%ecx + subl %eax,%ecx + movl %ecx,16(%ebx) + jnc .L042pw_nc4 + + movl 20(%esi),%ecx + subl %eax,%ecx + movl %ecx,20(%ebx) + jnc .L043pw_nc5 + + movl 24(%esi),%ecx + subl %eax,%ecx + movl %ecx,24(%ebx) + jnc .L044pw_nc6 + + movl 28(%esi),%ecx + subl %eax,%ecx + movl %ecx,28(%ebx) + jnc .L045pw_nc7 + + addl $32,%esi + addl $32,%ebx + subl $8,%ebp + jnz .L037pw_pos_loop +.L036pw_pos_finish: + movl 36(%esp),%ebp + andl $7,%ebp + jz .L032pw_end + + movl (%esi),%ecx + subl %eax,%ecx + movl %ecx,(%ebx) + jnc .L046pw_tail_nc0 + decl %ebp + jz .L032pw_end + + movl 4(%esi),%ecx + subl %eax,%ecx + movl %ecx,4(%ebx) + jnc .L047pw_tail_nc1 + decl %ebp + jz .L032pw_end + + movl 8(%esi),%ecx + subl %eax,%ecx + movl %ecx,8(%ebx) + jnc .L048pw_tail_nc2 + decl %ebp + jz .L032pw_end + + movl 12(%esi),%ecx + subl %eax,%ecx + movl %ecx,12(%ebx) + jnc .L049pw_tail_nc3 + decl %ebp + jz .L032pw_end + + movl 16(%esi),%ecx + subl %eax,%ecx + movl %ecx,16(%ebx) + jnc .L050pw_tail_nc4 + decl %ebp + jz .L032pw_end + + movl 20(%esi),%ecx + subl %eax,%ecx + movl %ecx,20(%ebx) + jnc .L051pw_tail_nc5 + decl %ebp + jz .L032pw_end + + movl 24(%esi),%ecx + subl %eax,%ecx + movl %ecx,24(%ebx) + jnc .L052pw_tail_nc6 + movl $1,%eax + jmp .L032pw_end +.L053pw_nc_loop: + movl (%esi),%ecx + movl %ecx,(%ebx) +.L038pw_nc0: + movl 4(%esi),%ecx + movl %ecx,4(%ebx) +.L039pw_nc1: + movl 8(%esi),%ecx + movl %ecx,8(%ebx) +.L040pw_nc2: + movl 12(%esi),%ecx + movl %ecx,12(%ebx) +.L041pw_nc3: + movl 16(%esi),%ecx + movl %ecx,16(%ebx) +.L042pw_nc4: + movl 20(%esi),%ecx + movl %ecx,20(%ebx) +.L043pw_nc5: + movl 24(%esi),%ecx + movl %ecx,24(%ebx) +.L044pw_nc6: + movl 28(%esi),%ecx + movl %ecx,28(%ebx) +.L045pw_nc7: + + addl $32,%esi + addl $32,%ebx + subl $8,%ebp + jnz .L053pw_nc_loop + movl 36(%esp),%ebp + andl $7,%ebp + jz .L054pw_nc_end + movl (%esi),%ecx + movl %ecx,(%ebx) +.L046pw_tail_nc0: + decl %ebp + jz .L054pw_nc_end + movl 4(%esi),%ecx + movl %ecx,4(%ebx) +.L047pw_tail_nc1: + decl %ebp + jz .L054pw_nc_end + movl 8(%esi),%ecx + movl %ecx,8(%ebx) +.L048pw_tail_nc2: + decl %ebp + jz .L054pw_nc_end + movl 12(%esi),%ecx + movl %ecx,12(%ebx) +.L049pw_tail_nc3: + decl %ebp + jz .L054pw_nc_end + movl 16(%esi),%ecx + movl %ecx,16(%ebx) +.L050pw_tail_nc4: + decl %ebp + jz .L054pw_nc_end + movl 20(%esi),%ecx + movl %ecx,20(%ebx) +.L051pw_tail_nc5: + decl %ebp + jz .L054pw_nc_end + movl 24(%esi),%ecx + movl %ecx,24(%ebx) +.L052pw_tail_nc6: +.L054pw_nc_end: + movl $0,%eax +.L032pw_end: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_sub_part_words,.-.L_bn_sub_part_words_begin +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/bn/bn_add.c b/crypto/openssl/crypto/bn/bn_add.c index 8ffe49618a8b..ae3e549e4430 100644 --- a/crypto/openssl/crypto/bn/bn_add.c +++ b/crypto/openssl/crypto/bn/bn_add.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -136,7 +136,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) dif = max - min; if (dif < 0) { /* hmm... should not be happening */ - BNerr(BN_F_BN_USUB, BN_R_ARG2_LT_ARG3); + ERR_raise(ERR_LIB_BN, BN_R_ARG2_LT_ARG3); return 0; } diff --git a/crypto/openssl/crypto/bn/bn_asm.c b/crypto/openssl/crypto/bn/bn_asm.c index 4d83a8cf1115..257701d9dc7c 100644 --- a/crypto/openssl/crypto/bn/bn_asm.c +++ b/crypto/openssl/crypto/bn/bn_asm.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bn/bn_blind.c b/crypto/openssl/crypto/bn/bn_blind.c index dd5beea7c93e..0b6d1bccc2a2 100644 --- a/crypto/openssl/crypto/bn/bn_blind.c +++ b/crypto/openssl/crypto/bn/bn_blind.c @@ -1,7 +1,7 @@ /* * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,13 +20,13 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) bn_check_top(mod); if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); return NULL; } ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } @@ -81,7 +81,7 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) int ret = 0; if ((b->A == NULL) || (b->Ai == NULL)) { - BNerr(BN_F_BN_BLINDING_UPDATE, BN_R_NOT_INITIALIZED); + ERR_raise(ERR_LIB_BN, BN_R_NOT_INITIALIZED); goto err; } @@ -124,7 +124,7 @@ int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) bn_check_top(n); if ((b->A == NULL) || (b->Ai == NULL)) { - BNerr(BN_F_BN_BLINDING_CONVERT_EX, BN_R_NOT_INITIALIZED); + ERR_raise(ERR_LIB_BN, BN_R_NOT_INITIALIZED); return 0; } @@ -158,7 +158,7 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, bn_check_top(n); if (r == NULL && (r = b->Ai) == NULL) { - BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED); + ERR_raise(ERR_LIB_BN, BN_R_NOT_INITIALIZED); return 0; } @@ -256,7 +256,7 @@ BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, do { int rv; - if (!BN_priv_rand_range(ret->A, ret->mod)) + if (!BN_priv_rand_range_ex(ret->A, ret->mod, 0, ctx)) goto err; if (int_bn_mod_inverse(ret->Ai, ret->A, ret->mod, ctx, &rv)) break; @@ -268,7 +268,7 @@ BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, goto err; if (retry_counter-- == 0) { - BNerr(BN_F_BN_BLINDING_CREATE_PARAM, BN_R_TOO_MANY_ITERATIONS); + ERR_raise(ERR_LIB_BN, BN_R_TOO_MANY_ITERATIONS); goto err; } } while (1); diff --git a/crypto/openssl/crypto/bn/bn_const.c b/crypto/openssl/crypto/bn/bn_const.c index 39dd61202ad7..a36e0ac792dd 100644 --- a/crypto/openssl/crypto/bn/bn_const.c +++ b/crypto/openssl/crypto/bn/bn_const.c @@ -1,13 +1,17 @@ /* - * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include +#include "crypto/bn_dh.h" + +#define COPY_BN(dst, src) (dst != NULL) ? BN_copy(dst, &src) : BN_dup(&src) + /*- * "First Oakley Default Group" from RFC2409, section 6.1. @@ -80,33 +84,7 @@ BIGNUM *BN_get_rfc2409_prime_1024(BIGNUM *bn) BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *bn) { - static const unsigned char RFC3526_PRIME_1536[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), bn); + return COPY_BN(bn, ossl_bignum_modp_1536_p); } /*- @@ -119,41 +97,7 @@ BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *bn) BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *bn) { - static const unsigned char RFC3526_PRIME_2048[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_2048, sizeof(RFC3526_PRIME_2048), bn); + return COPY_BN(bn, ossl_bignum_modp_2048_p); } /*- @@ -166,57 +110,7 @@ BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *bn) BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *bn) { - static const unsigned char RFC3526_PRIME_3072[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_3072, sizeof(RFC3526_PRIME_3072), bn); + return COPY_BN(bn, ossl_bignum_modp_3072_p); } /*- @@ -229,73 +123,7 @@ BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *bn) BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *bn) { - static const unsigned char RFC3526_PRIME_4096[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, - 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, - 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, - 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, - 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, - 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, - 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, - 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, - 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, - 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, - 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, - 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, - 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, - 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, - 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, - 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, - 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_4096, sizeof(RFC3526_PRIME_4096), bn); + return COPY_BN(bn, ossl_bignum_modp_4096_p); } /*- @@ -308,105 +136,7 @@ BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *bn) BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *bn) { - static const unsigned char RFC3526_PRIME_6144[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, - 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, - 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, - 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, - 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, - 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, - 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, - 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, - 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, - 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, - 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, - 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, - 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, - 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, - 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, - 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, - 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, - 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, - 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, - 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, - 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, - 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, - 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, - 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, - 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, - 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, - 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, - 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, - 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, - 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, - 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, - 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, - 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, - 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, - 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, - 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, - 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, - 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, - 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, - 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, - 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, - 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, - 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, - 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, - 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, - 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, - 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, - 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, - 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_6144, sizeof(RFC3526_PRIME_6144), bn); + return COPY_BN(bn, ossl_bignum_modp_6144_p); } /*- @@ -419,135 +149,5 @@ BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *bn) BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *bn) { - static const unsigned char RFC3526_PRIME_8192[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, - 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, - 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, - 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, - 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, - 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, - 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, - 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, - 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, - 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, - 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, - 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, - 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, - 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, - 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, - 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, - 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, - 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, - 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, - 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, - 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, - 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, - 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, - 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, - 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, - 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, - 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, - 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, - 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, - 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, - 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, - 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, - 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, - 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, - 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, - 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, - 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, - 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, - 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, - 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, - 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, - 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, - 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, - 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, - 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, - 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, - 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, - 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, - 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59, - 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4, - 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, - 0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA, - 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00, - 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, - 0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66, - 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68, - 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, - 0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D, - 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9, - 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, - 0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7, - 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B, - 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, - 0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8, - 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A, - 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, - 0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D, - 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36, - 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, - 0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D, - 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1, - 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, - 0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68, - 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92, - 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, - 0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B, - 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47, - 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, - 0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF, - 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71, - 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_8192, sizeof(RFC3526_PRIME_8192), bn); + return COPY_BN(bn, ossl_bignum_modp_8192_p); } diff --git a/crypto/openssl/crypto/bn/bn_conv.c b/crypto/openssl/crypto/bn/bn_conv.c new file mode 100644 index 000000000000..75054f5d6a6c --- /dev/null +++ b/crypto/openssl/crypto/bn/bn_conv.c @@ -0,0 +1,291 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "crypto/ctype.h" +#include "bn_local.h" + +static const char Hex[] = "0123456789ABCDEF"; + +/* Must 'OPENSSL_free' the returned data */ +char *BN_bn2hex(const BIGNUM *a) +{ + int i, j, v, z = 0; + char *buf; + char *p; + + if (BN_is_zero(a)) + return OPENSSL_strdup("0"); + buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2); + if (buf == NULL) { + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + goto err; + } + p = buf; + if (a->neg) + *p++ = '-'; + for (i = a->top - 1; i >= 0; i--) { + for (j = BN_BITS2 - 8; j >= 0; j -= 8) { + /* strip leading zeros */ + v = (int)((a->d[i] >> j) & 0xff); + if (z || v != 0) { + *p++ = Hex[v >> 4]; + *p++ = Hex[v & 0x0f]; + z = 1; + } + } + } + *p = '\0'; + err: + return buf; +} + +#ifndef FIPS_MODULE +/* No BIO_snprintf in FIPS_MODULE */ +/* Must 'OPENSSL_free' the returned data */ +char *BN_bn2dec(const BIGNUM *a) +{ + int i = 0, num, ok = 0, n, tbytes; + char *buf = NULL; + char *p; + BIGNUM *t = NULL; + BN_ULONG *bn_data = NULL, *lp; + int bn_data_num; + + /*- + * get an upper bound for the length of the decimal integer + * num <= (BN_num_bits(a) + 1) * log(2) + * <= 3 * BN_num_bits(a) * 0.101 + log(2) + 1 (rounding error) + * <= 3 * BN_num_bits(a) / 10 + 3 * BN_num_bits / 1000 + 1 + 1 + */ + i = BN_num_bits(a) * 3; + num = (i / 10 + i / 1000 + 1) + 1; + tbytes = num + 3; /* negative and terminator and one spare? */ + bn_data_num = num / BN_DEC_NUM + 1; + bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG)); + buf = OPENSSL_malloc(tbytes); + if (buf == NULL || bn_data == NULL) { + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((t = BN_dup(a)) == NULL) + goto err; + + p = buf; + lp = bn_data; + if (BN_is_zero(t)) { + *p++ = '0'; + *p++ = '\0'; + } else { + if (BN_is_negative(t)) + *p++ = '-'; + + while (!BN_is_zero(t)) { + if (lp - bn_data >= bn_data_num) + goto err; + *lp = BN_div_word(t, BN_DEC_CONV); + if (*lp == (BN_ULONG)-1) + goto err; + lp++; + } + lp--; + /* + * We now have a series of blocks, BN_DEC_NUM chars in length, where + * the last one needs truncation. The blocks need to be reversed in + * order. + */ + n = BIO_snprintf(p, tbytes - (size_t)(p - buf), BN_DEC_FMT1, *lp); + if (n < 0) + goto err; + p += n; + while (lp != bn_data) { + lp--; + n = BIO_snprintf(p, tbytes - (size_t)(p - buf), BN_DEC_FMT2, *lp); + if (n < 0) + goto err; + p += n; + } + } + ok = 1; + err: + OPENSSL_free(bn_data); + BN_free(t); + if (ok) + return buf; + OPENSSL_free(buf); + return NULL; +} +#endif + +int BN_hex2bn(BIGNUM **bn, const char *a) +{ + BIGNUM *ret = NULL; + BN_ULONG l = 0; + int neg = 0, h, m, i, j, k, c; + int num; + + if (a == NULL || *a == '\0') + return 0; + + if (*a == '-') { + neg = 1; + a++; + } + + for (i = 0; i <= INT_MAX / 4 && ossl_isxdigit(a[i]); i++) + continue; + + if (i == 0 || i > INT_MAX / 4) + return 0; + + num = i + neg; + if (bn == NULL) + return num; + + /* a is the start of the hex digits, and it is 'i' long */ + if (*bn == NULL) { + if ((ret = BN_new()) == NULL) + return 0; + } else { + ret = *bn; + if (BN_get_flags(ret, BN_FLG_STATIC_DATA)) { + ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + BN_zero(ret); + } + + /* i is the number of hex digits */ + if (bn_expand(ret, i * 4) == NULL) + goto err; + + j = i; /* least significant 'hex' */ + m = 0; + h = 0; + while (j > 0) { + m = (BN_BYTES * 2 <= j) ? BN_BYTES * 2 : j; + l = 0; + for (;;) { + c = a[j - m]; + k = OPENSSL_hexchar2int(c); + if (k < 0) + k = 0; /* paranoia */ + l = (l << 4) | k; + + if (--m <= 0) { + ret->d[h++] = l; + break; + } + } + j -= BN_BYTES * 2; + } + ret->top = h; + bn_correct_top(ret); + + *bn = ret; + bn_check_top(ret); + /* Don't set the negative flag if it's zero. */ + if (ret->top != 0) + ret->neg = neg; + return num; + err: + if (*bn == NULL) + BN_free(ret); + return 0; +} + +int BN_dec2bn(BIGNUM **bn, const char *a) +{ + BIGNUM *ret = NULL; + BN_ULONG l = 0; + int neg = 0, i, j; + int num; + + if (a == NULL || *a == '\0') + return 0; + if (*a == '-') { + neg = 1; + a++; + } + + for (i = 0; i <= INT_MAX / 4 && ossl_isdigit(a[i]); i++) + continue; + + if (i == 0 || i > INT_MAX / 4) + goto err; + + num = i + neg; + if (bn == NULL) + return num; + + /* + * a is the start of the digits, and it is 'i' long. We chop it into + * BN_DEC_NUM digits at a time + */ + if (*bn == NULL) { + if ((ret = BN_new()) == NULL) + return 0; + } else { + ret = *bn; + BN_zero(ret); + } + + /* i is the number of digits, a bit of an over expand */ + if (bn_expand(ret, i * 4) == NULL) + goto err; + + j = BN_DEC_NUM - i % BN_DEC_NUM; + if (j == BN_DEC_NUM) + j = 0; + l = 0; + while (--i >= 0) { + l *= 10; + l += *a - '0'; + a++; + if (++j == BN_DEC_NUM) { + if (!BN_mul_word(ret, BN_DEC_CONV) + || !BN_add_word(ret, l)) + goto err; + l = 0; + j = 0; + } + } + + bn_correct_top(ret); + *bn = ret; + bn_check_top(ret); + /* Don't set the negative flag if it's zero. */ + if (ret->top != 0) + ret->neg = neg; + return num; + err: + if (*bn == NULL) + BN_free(ret); + return 0; +} + +int BN_asc2bn(BIGNUM **bn, const char *a) +{ + const char *p = a; + + if (*p == '-') + p++; + + if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) { + if (!BN_hex2bn(bn, p + 2)) + return 0; + } else { + if (!BN_dec2bn(bn, p)) + return 0; + } + /* Don't set the negative flag if it's zero. */ + if (*a == '-' && (*bn)->top != 0) + (*bn)->neg = 1; + return 1; +} diff --git a/crypto/openssl/crypto/bn/bn_ctx.c b/crypto/openssl/crypto/bn/bn_ctx.c index 042cb247d37f..35a7ddbab737 100644 --- a/crypto/openssl/crypto/bn/bn_ctx.c +++ b/crypto/openssl/crypto/bn/bn_ctx.c @@ -1,28 +1,16 @@ /* - * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#include #include "internal/cryptlib.h" #include "bn_local.h" -/*- - * TODO list - * - * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and - * check they can be safely removed. - * - Check +1 and other ugliness in BN_from_montgomery() - * - * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an - * appropriate 'block' size that will be honoured by bn_expand_internal() to - * prevent piddly little reallocations. OTOH, profiling bignum expansions in - * BN_CTX doesn't show this to be a big issue. - */ - /* How many bignums are in each "pool item"; */ #define BN_CTX_POOL_SIZE 16 /* The stack frame info is resizing, set a first-time expansion size; */ @@ -85,93 +73,105 @@ struct bignum_ctx { int too_many; /* Flags. */ int flags; + /* The library context */ + OSSL_LIB_CTX *libctx; }; -/* Enable this to find BN_CTX bugs */ -#ifdef BN_CTX_DEBUG -static const char *ctxdbg_cur = NULL; -static void ctxdbg(BN_CTX *ctx) +#ifndef FIPS_MODULE +/* Debugging functionality */ +static void ctxdbg(BIO *channel, const char *text, BN_CTX *ctx) { unsigned int bnidx = 0, fpidx = 0; BN_POOL_ITEM *item = ctx->pool.head; BN_STACK *stack = &ctx->stack; - fprintf(stderr, "(%16p): ", ctx); + + BIO_printf(channel, "%s\n", text); + BIO_printf(channel, " (%16p): ", (void*)ctx); while (bnidx < ctx->used) { - fprintf(stderr, "%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax); + BIO_printf(channel, "%03x ", + item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax); if (!(bnidx % BN_CTX_POOL_SIZE)) item = item->next; } - fprintf(stderr, "\n"); + BIO_printf(channel, "\n"); bnidx = 0; - fprintf(stderr, " : "); + BIO_printf(channel, " %16s : ", ""); while (fpidx < stack->depth) { while (bnidx++ < stack->indexes[fpidx]) - fprintf(stderr, " "); - fprintf(stderr, "^^^ "); + BIO_printf(channel, " "); + BIO_printf(channel, "^^^ "); bnidx++; fpidx++; } - fprintf(stderr, "\n"); + BIO_printf(channel, "\n"); } -# define CTXDBG_ENTRY(str, ctx) do { \ - ctxdbg_cur = (str); \ - fprintf(stderr,"Starting %s\n", ctxdbg_cur); \ - ctxdbg(ctx); \ - } while(0) -# define CTXDBG_EXIT(ctx) do { \ - fprintf(stderr,"Ending %s\n", ctxdbg_cur); \ - ctxdbg(ctx); \ - } while(0) -# define CTXDBG_RET(ctx,ret) +# define CTXDBG(str, ctx) \ + OSSL_TRACE_BEGIN(BN_CTX) { \ + ctxdbg(trc_out, str, ctx); \ + } OSSL_TRACE_END(BN_CTX) #else -# define CTXDBG_ENTRY(str, ctx) -# define CTXDBG_EXIT(ctx) -# define CTXDBG_RET(ctx,ret) -#endif - +/* We do not want tracing in FIPS module */ +# define CTXDBG(str, ctx) do {} while(0) +#endif /* FIPS_MODULE */ -BN_CTX *BN_CTX_new(void) +BN_CTX *BN_CTX_new_ex(OSSL_LIB_CTX *ctx) { BN_CTX *ret; if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); return NULL; } /* Initialise the structure */ BN_POOL_init(&ret->pool); BN_STACK_init(&ret->stack); + ret->libctx = ctx; return ret; } -BN_CTX *BN_CTX_secure_new(void) +#ifndef FIPS_MODULE +BN_CTX *BN_CTX_new(void) { - BN_CTX *ret = BN_CTX_new(); + return BN_CTX_new_ex(NULL); +} +#endif + +BN_CTX *BN_CTX_secure_new_ex(OSSL_LIB_CTX *ctx) +{ + BN_CTX *ret = BN_CTX_new_ex(ctx); if (ret != NULL) ret->flags = BN_FLG_SECURE; return ret; } +#ifndef FIPS_MODULE +BN_CTX *BN_CTX_secure_new(void) +{ + return BN_CTX_secure_new_ex(NULL); +} +#endif + void BN_CTX_free(BN_CTX *ctx) { if (ctx == NULL) return; -#ifdef BN_CTX_DEBUG - { +#ifndef FIPS_MODULE + OSSL_TRACE_BEGIN(BN_CTX) { BN_POOL_ITEM *pool = ctx->pool.head; - fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\n", - ctx->stack.size, ctx->pool.size); - fprintf(stderr, "dmaxs: "); + BIO_printf(trc_out, + "BN_CTX_free(): stack-size=%d, pool-bignums=%d\n", + ctx->stack.size, ctx->pool.size); + BIO_printf(trc_out, " dmaxs: "); while (pool) { unsigned loop = 0; while (loop < BN_CTX_POOL_SIZE) - fprintf(stderr, "%02x ", pool->vals[loop++].dmax); + BIO_printf(trc_out, "%02x ", pool->vals[loop++].dmax); pool = pool->next; } - fprintf(stderr, "\n"); - } + BIO_printf(trc_out, "\n"); + } OSSL_TRACE_END(BN_CTX); #endif BN_STACK_finish(&ctx->stack); BN_POOL_finish(&ctx->pool); @@ -180,23 +180,23 @@ void BN_CTX_free(BN_CTX *ctx) void BN_CTX_start(BN_CTX *ctx) { - CTXDBG_ENTRY("BN_CTX_start", ctx); + CTXDBG("ENTER BN_CTX_start()", ctx); /* If we're already overflowing ... */ if (ctx->err_stack || ctx->too_many) ctx->err_stack++; /* (Try to) get a new frame pointer */ else if (!BN_STACK_push(&ctx->stack, ctx->used)) { - BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + ERR_raise(ERR_LIB_BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES); ctx->err_stack++; } - CTXDBG_EXIT(ctx); + CTXDBG("LEAVE BN_CTX_start()", ctx); } void BN_CTX_end(BN_CTX *ctx) { if (ctx == NULL) return; - CTXDBG_ENTRY("BN_CTX_end", ctx); + CTXDBG("ENTER BN_CTX_end()", ctx); if (ctx->err_stack) ctx->err_stack--; else { @@ -208,14 +208,14 @@ void BN_CTX_end(BN_CTX *ctx) /* Unjam "too_many" in case "get" had failed */ ctx->too_many = 0; } - CTXDBG_EXIT(ctx); + CTXDBG("LEAVE BN_CTX_end()", ctx); } BIGNUM *BN_CTX_get(BN_CTX *ctx) { BIGNUM *ret; - CTXDBG_ENTRY("BN_CTX_get", ctx); + CTXDBG("ENTER BN_CTX_get()", ctx); if (ctx->err_stack || ctx->too_many) return NULL; if ((ret = BN_POOL_get(&ctx->pool, ctx->flags)) == NULL) { @@ -224,7 +224,7 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx) * the error stack. */ ctx->too_many = 1; - BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + ERR_raise(ERR_LIB_BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES); return NULL; } /* OK, make sure the returned bignum is "zero" */ @@ -232,10 +232,17 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx) /* clear BN_FLG_CONSTTIME if leaked from previous frames */ ret->flags &= (~BN_FLG_CONSTTIME); ctx->used++; - CTXDBG_RET(ctx, ret); + CTXDBG("LEAVE BN_CTX_get()", ctx); return ret; } +OSSL_LIB_CTX *ossl_bn_get_libctx(BN_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + return ctx->libctx; +} + /************/ /* BN_STACK */ /************/ @@ -262,7 +269,7 @@ static int BN_STACK_push(BN_STACK *st, unsigned int idx) unsigned int *newitems; if ((newitems = OPENSSL_malloc(sizeof(*newitems) * newsize)) == NULL) { - BNerr(BN_F_BN_STACK_PUSH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); return 0; } if (st->depth) @@ -316,7 +323,7 @@ static BIGNUM *BN_POOL_get(BN_POOL *p, int flag) BN_POOL_ITEM *item; if ((item = OPENSSL_malloc(sizeof(*item))) == NULL) { - BNerr(BN_F_BN_POOL_GET, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); return NULL; } for (loop = 0, bn = item->vals; loop++ < BN_CTX_POOL_SIZE; bn++) { diff --git a/crypto/openssl/crypto/bn/bn_depr.c b/crypto/openssl/crypto/bn/bn_depr.c index b60269cd57a6..d55397016a51 100644 --- a/crypto/openssl/crypto/bn/bn_depr.c +++ b/crypto/openssl/crypto/bn/bn_depr.c @@ -1,7 +1,7 @@ /* - * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,14 +13,11 @@ */ #include -#if OPENSSL_API_COMPAT >= 0x00908000L -NON_EMPTY_TRANSLATION_UNIT -#else -# include -# include -# include "internal/cryptlib.h" -# include "bn_local.h" +#include +#include +#include "internal/cryptlib.h" +#include "bn_local.h" BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, @@ -52,7 +49,7 @@ int BN_is_prime(const BIGNUM *a, int checks, { BN_GENCB cb; BN_GENCB_set_old(&cb, callback, cb_arg); - return BN_is_prime_ex(a, checks, ctx_passed, &cb); + return ossl_bn_check_prime(a, checks, ctx_passed, 0, &cb); } int BN_is_prime_fasttest(const BIGNUM *a, int checks, @@ -62,7 +59,5 @@ int BN_is_prime_fasttest(const BIGNUM *a, int checks, { BN_GENCB cb; BN_GENCB_set_old(&cb, callback, cb_arg); - return BN_is_prime_fasttest_ex(a, checks, ctx_passed, - do_trial_division, &cb); + return ossl_bn_check_prime(a, checks, ctx_passed, do_trial_division, &cb); } -#endif diff --git a/crypto/openssl/crypto/bn/bn_dh.c b/crypto/openssl/crypto/bn/bn_dh.c index 58c44f0b179e..c0967e534c8c 100644 --- a/crypto/openssl/crypto/bn/bn_dh.c +++ b/crypto/openssl/crypto/bn/bn_dh.c @@ -1,7 +1,7 @@ /* - * Copyright 2014-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,503 +10,1045 @@ #include "bn_local.h" #include "internal/nelem.h" -#ifndef OPENSSL_NO_DH -#include -#include "crypto/bn_dh.h" -/* DH parameters from RFC5114 */ +# include +# include "crypto/bn_dh.h" # if BN_BITS2 == 64 -static const BN_ULONG dh1024_160_p[] = { - 0xDF1FB2BC2E4A4371ULL, 0xE68CFDA76D4DA708ULL, 0x45BF37DF365C1A65ULL, - 0xA151AF5F0DC8B4BDULL, 0xFAA31A4FF55BCCC0ULL, 0x4EFFD6FAE5644738ULL, - 0x98488E9C219A7372ULL, 0xACCBDD7D90C4BD70ULL, 0x24975C3CD49B83BFULL, - 0x13ECB4AEA9061123ULL, 0x9838EF1E2EE652C0ULL, 0x6073E28675A23D18ULL, - 0x9A6A9DCA52D23B61ULL, 0x52C99FBCFB06A3C6ULL, 0xDE92DE5EAE5D54ECULL, - 0xB10B8F96A080E01DULL -}; +# define BN_DEF(lo, hi) (BN_ULONG)hi << 32 | lo +# else +# define BN_DEF(lo, hi) lo, hi +# endif -static const BN_ULONG dh1024_160_g[] = { - 0x855E6EEB22B3B2E5ULL, 0x858F4DCEF97C2A24ULL, 0x2D779D5918D08BC8ULL, - 0xD662A4D18E73AFA3ULL, 0x1DBF0A0169B6A28AULL, 0xA6A24C087A091F53ULL, - 0x909D0D2263F80A76ULL, 0xD7FBD7D3B9A92EE1ULL, 0x5E91547F9E2749F4ULL, - 0x160217B4B01B886AULL, 0x777E690F5504F213ULL, 0x266FEA1E5C41564BULL, - 0xD6406CFF14266D31ULL, 0xF8104DD258AC507FULL, 0x6765A442EFB99905ULL, - 0xA4D1CBD5C3FD3412ULL -}; +/* DH parameters from RFC3526 */ -static const BN_ULONG dh1024_160_q[] = { - 0x64B7CB9D49462353ULL, 0x81A8DF278ABA4E7DULL, 0x00000000F518AA87ULL +# ifndef FIPS_MODULE +/* + * "1536-bit MODP Group" from RFC3526, Section 2. + * + * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } + * + * RFC3526 specifies a generator of 2. + * RFC2412 specifies a generator of 22. + */ +static const BN_ULONG modp_1536_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xCA237327, 0xF1746C08), + BN_DEF(0x4ABC9804, 0x670C354E), BN_DEF(0x7096966D, 0x9ED52907), + BN_DEF(0x208552BB, 0x1C62F356), BN_DEF(0xDCA3AD96, 0x83655D23), + BN_DEF(0xFD24CF5F, 0x69163FA8), BN_DEF(0x1C55D39A, 0x98DA4836), + BN_DEF(0xA163BF05, 0xC2007CB8), BN_DEF(0xECE45B3D, 0x49286651), + BN_DEF(0x7C4B1FE6, 0xAE9F2411), BN_DEF(0x5A899FA5, 0xEE386BFB), + BN_DEF(0xF406B7ED, 0x0BFF5CB6), BN_DEF(0xA637ED6B, 0xF44C42E9), + BN_DEF(0x625E7EC6, 0xE485B576), BN_DEF(0x6D51C245, 0x4FE1356D), + BN_DEF(0xF25F1437, 0x302B0A6D), BN_DEF(0xCD3A431B, 0xEF9519B3), + BN_DEF(0x8E3404DD, 0x514A0879), BN_DEF(0x3B139B22, 0x020BBEA6), + BN_DEF(0x8A67CC74, 0x29024E08), BN_DEF(0x80DC1CD1, 0xC4C6628B), + BN_DEF(0x2168C234, 0xC90FDAA2), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) }; - -static const BN_ULONG dh2048_224_p[] = { - 0x0AC4DFFE0C10E64FULL, 0xCF9DE5384E71B81CULL, 0x7EF363E2FFA31F71ULL, - 0xE3FB73C16B8E75B9ULL, 0xC9B53DCF4BA80A29ULL, 0x23F10B0E16E79763ULL, - 0xC52172E413042E9BULL, 0xBE60E69CC928B2B9ULL, 0x80CD86A1B9E587E8ULL, - 0x315D75E198C641A4ULL, 0xCDF93ACC44328387ULL, 0x15987D9ADC0A486DULL, - 0x7310F7121FD5A074ULL, 0x278273C7DE31EFDCULL, 0x1602E714415D9330ULL, - 0x81286130BC8985DBULL, 0xB3BF8A3170918836ULL, 0x6A00E0A0B9C49708ULL, - 0xC6BA0B2C8BBC27BEULL, 0xC9F98D11ED34DBF6ULL, 0x7AD5B7D0B6C12207ULL, - 0xD91E8FEF55B7394BULL, 0x9037C9EDEFDA4DF8ULL, 0x6D3F8152AD6AC212ULL, - 0x1DE6B85A1274A0A6ULL, 0xEB3D688A309C180EULL, 0xAF9A3C407BA1DF15ULL, - 0xE6FA141DF95A56DBULL, 0xB54B1597B61D0A75ULL, 0xA20D64E5683B9FD1ULL, - 0xD660FAA79559C51FULL, 0xAD107E1E9123A9D0ULL +/* q = (p - 1) / 2 */ +static const BN_ULONG modp_1536_q[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x6511B993, 0x78BA3604), + BN_DEF(0x255E4C02, 0xB3861AA7), BN_DEF(0xB84B4B36, 0xCF6A9483), + BN_DEF(0x1042A95D, 0x0E3179AB), BN_DEF(0xEE51D6CB, 0xC1B2AE91), + BN_DEF(0x7E9267AF, 0x348B1FD4), BN_DEF(0x0E2AE9CD, 0xCC6D241B), + BN_DEF(0x50B1DF82, 0xE1003E5C), BN_DEF(0xF6722D9E, 0x24943328), + BN_DEF(0xBE258FF3, 0xD74F9208), BN_DEF(0xAD44CFD2, 0xF71C35FD), + BN_DEF(0x7A035BF6, 0x85FFAE5B), BN_DEF(0xD31BF6B5, 0x7A262174), + BN_DEF(0x312F3F63, 0xF242DABB), BN_DEF(0xB6A8E122, 0xA7F09AB6), + BN_DEF(0xF92F8A1B, 0x98158536), BN_DEF(0xE69D218D, 0xF7CA8CD9), + BN_DEF(0xC71A026E, 0x28A5043C), BN_DEF(0x1D89CD91, 0x0105DF53), + BN_DEF(0x4533E63A, 0x94812704), BN_DEF(0xC06E0E68, 0x62633145), + BN_DEF(0x10B4611A, 0xE487ED51), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF) }; +# endif /* FIPS_MODULE */ -static const BN_ULONG dh2048_224_g[] = { - 0x84B890D3191F2BFAULL, 0x81BC087F2A7065B3ULL, 0x19C418E1F6EC0179ULL, - 0x7B5A0F1C71CFFF4CULL, 0xEDFE72FE9B6AA4BDULL, 0x81E1BCFE94B30269ULL, - 0x566AFBB48D6C0191ULL, 0xB539CCE3409D13CDULL, 0x6AA21E7F5F2FF381ULL, - 0xD9E263E4770589EFULL, 0x10E183EDD19963DDULL, 0xB70A8137150B8EEBULL, - 0x051AE3D428C8F8ACULL, 0xBB77A86F0C1AB15BULL, 0x6E3025E316A330EFULL, - 0x19529A45D6F83456ULL, 0xF180EB34118E98D1ULL, 0xB5F6C6B250717CBEULL, - 0x09939D54DA7460CDULL, 0xE247150422EA1ED4ULL, 0xB8A762D0521BC98AULL, - 0xF4D027275AC1348BULL, 0xC17669101999024AULL, 0xBE5E9001A8D66AD7ULL, - 0xC57DB17C620A8652ULL, 0xAB739D7700C29F52ULL, 0xDD921F01A70C4AFAULL, - 0xA6824A4E10B9A6F0ULL, 0x74866A08CFE4FFE3ULL, 0x6CDEBE7B89998CAFULL, - 0x9DF30B5C8FFDAC50ULL, 0xAC4032EF4F2D9AE3ULL +/*- + * "2048-bit MODP Group" from RFC3526, Section 3. + * + * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } + * + * RFC3526 specifies a generator of 2. + */ +static const BN_ULONG modp_2048_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x8AACAA68, 0x15728E5A), + BN_DEF(0x98FA0510, 0x15D22618), BN_DEF(0xEA956AE5, 0x3995497C), + BN_DEF(0x95581718, 0xDE2BCBF6), BN_DEF(0x6F4C52C9, 0xB5C55DF0), + BN_DEF(0xEC07A28F, 0x9B2783A2), BN_DEF(0x180E8603, 0xE39E772C), + BN_DEF(0x2E36CE3B, 0x32905E46), BN_DEF(0xCA18217C, 0xF1746C08), + BN_DEF(0x4ABC9804, 0x670C354E), BN_DEF(0x7096966D, 0x9ED52907), + BN_DEF(0x208552BB, 0x1C62F356), BN_DEF(0xDCA3AD96, 0x83655D23), + BN_DEF(0xFD24CF5F, 0x69163FA8), BN_DEF(0x1C55D39A, 0x98DA4836), + BN_DEF(0xA163BF05, 0xC2007CB8), BN_DEF(0xECE45B3D, 0x49286651), + BN_DEF(0x7C4B1FE6, 0xAE9F2411), BN_DEF(0x5A899FA5, 0xEE386BFB), + BN_DEF(0xF406B7ED, 0x0BFF5CB6), BN_DEF(0xA637ED6B, 0xF44C42E9), + BN_DEF(0x625E7EC6, 0xE485B576), BN_DEF(0x6D51C245, 0x4FE1356D), + BN_DEF(0xF25F1437, 0x302B0A6D), BN_DEF(0xCD3A431B, 0xEF9519B3), + BN_DEF(0x8E3404DD, 0x514A0879), BN_DEF(0x3B139B22, 0x020BBEA6), + BN_DEF(0x8A67CC74, 0x29024E08), BN_DEF(0x80DC1CD1, 0xC4C6628B), + BN_DEF(0x2168C234, 0xC90FDAA2), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) }; - -static const BN_ULONG dh2048_224_q[] = { - 0xBF389A99B36371EBULL, 0x1F80535A4738CEBCULL, 0xC58D93FE99717710ULL, - 0x00000000801C0D34ULL +/* q = (p - 1) / 2 */ +static const BN_ULONG modp_2048_q[] = { + BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), BN_DEF(0x45565534, 0x0AB9472D), + BN_DEF(0x4C7D0288, 0x8AE9130C), BN_DEF(0x754AB572, 0x1CCAA4BE), + BN_DEF(0x4AAC0B8C, 0xEF15E5FB), BN_DEF(0x37A62964, 0xDAE2AEF8), + BN_DEF(0x7603D147, 0xCD93C1D1), BN_DEF(0x0C074301, 0xF1CF3B96), + BN_DEF(0x171B671D, 0x19482F23), BN_DEF(0x650C10BE, 0x78BA3604), + BN_DEF(0x255E4C02, 0xB3861AA7), BN_DEF(0xB84B4B36, 0xCF6A9483), + BN_DEF(0x1042A95D, 0x0E3179AB), BN_DEF(0xEE51D6CB, 0xC1B2AE91), + BN_DEF(0x7E9267AF, 0x348B1FD4), BN_DEF(0x0E2AE9CD, 0xCC6D241B), + BN_DEF(0x50B1DF82, 0xE1003E5C), BN_DEF(0xF6722D9E, 0x24943328), + BN_DEF(0xBE258FF3, 0xD74F9208), BN_DEF(0xAD44CFD2, 0xF71C35FD), + BN_DEF(0x7A035BF6, 0x85FFAE5B), BN_DEF(0xD31BF6B5, 0x7A262174), + BN_DEF(0x312F3F63, 0xF242DABB), BN_DEF(0xB6A8E122, 0xA7F09AB6), + BN_DEF(0xF92F8A1B, 0x98158536), BN_DEF(0xE69D218D, 0xF7CA8CD9), + BN_DEF(0xC71A026E, 0x28A5043C), BN_DEF(0x1D89CD91, 0x0105DF53), + BN_DEF(0x4533E63A, 0x94812704), BN_DEF(0xC06E0E68, 0x62633145), + BN_DEF(0x10B4611A, 0xE487ED51), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), }; -static const BN_ULONG dh2048_256_p[] = { - 0xDB094AE91E1A1597ULL, 0x693877FAD7EF09CAULL, 0x6116D2276E11715FULL, - 0xA4B54330C198AF12ULL, 0x75F26375D7014103ULL, 0xC3A3960A54E710C3ULL, - 0xDED4010ABD0BE621ULL, 0xC0B857F689962856ULL, 0xB3CA3F7971506026ULL, - 0x1CCACB83E6B486F6ULL, 0x67E144E514056425ULL, 0xF6A167B5A41825D9ULL, - 0x3AD8347796524D8EULL, 0xF13C6D9A51BFA4ABULL, 0x2D52526735488A0EULL, - 0xB63ACAE1CAA6B790ULL, 0x4FDB70C581B23F76ULL, 0xBC39A0BF12307F5CULL, - 0xB941F54EB1E59BB8ULL, 0x6C5BFC11D45F9088ULL, 0x22E0B1EF4275BF7BULL, - 0x91F9E6725B4758C0ULL, 0x5A8A9D306BCF67EDULL, 0x209E0C6497517ABDULL, - 0x3BF4296D830E9A7CULL, 0x16C3D91134096FAAULL, 0xFAF7DF4561B2AA30ULL, - 0xE00DF8F1D61957D4ULL, 0x5D2CEED4435E3B00ULL, 0x8CEEF608660DD0F2ULL, - 0xFFBBD19C65195999ULL, 0x87A8E61DB4B6663CULL +/*- + * "3072-bit MODP Group" from RFC3526, Section 4. + * + * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 } + * + * RFC3526 specifies a generator of 2. + */ +static const BN_ULONG modp_3072_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xA93AD2CA, 0x4B82D120), + BN_DEF(0xE0FD108E, 0x43DB5BFC), BN_DEF(0x74E5AB31, 0x08E24FA0), + BN_DEF(0xBAD946E2, 0x770988C0), BN_DEF(0x7A615D6C, 0xBBE11757), + BN_DEF(0x177B200C, 0x521F2B18), BN_DEF(0x3EC86A64, 0xD8760273), + BN_DEF(0xD98A0864, 0xF12FFA06), BN_DEF(0x1AD2EE6B, 0xCEE3D226), + BN_DEF(0x4A25619D, 0x1E8C94E0), BN_DEF(0xDB0933D7, 0xABF5AE8C), + BN_DEF(0xA6E1E4C7, 0xB3970F85), BN_DEF(0x5D060C7D, 0x8AEA7157), + BN_DEF(0x58DBEF0A, 0xECFB8504), BN_DEF(0xDF1CBA64, 0xA85521AB), + BN_DEF(0x04507A33, 0xAD33170D), BN_DEF(0x8AAAC42D, 0x15728E5A), + BN_DEF(0x98FA0510, 0x15D22618), BN_DEF(0xEA956AE5, 0x3995497C), + BN_DEF(0x95581718, 0xDE2BCBF6), BN_DEF(0x6F4C52C9, 0xB5C55DF0), + BN_DEF(0xEC07A28F, 0x9B2783A2), BN_DEF(0x180E8603, 0xE39E772C), + BN_DEF(0x2E36CE3B, 0x32905E46), BN_DEF(0xCA18217C, 0xF1746C08), + BN_DEF(0x4ABC9804, 0x670C354E), BN_DEF(0x7096966D, 0x9ED52907), + BN_DEF(0x208552BB, 0x1C62F356), BN_DEF(0xDCA3AD96, 0x83655D23), + BN_DEF(0xFD24CF5F, 0x69163FA8), BN_DEF(0x1C55D39A, 0x98DA4836), + BN_DEF(0xA163BF05, 0xC2007CB8), BN_DEF(0xECE45B3D, 0x49286651), + BN_DEF(0x7C4B1FE6, 0xAE9F2411), BN_DEF(0x5A899FA5, 0xEE386BFB), + BN_DEF(0xF406B7ED, 0x0BFF5CB6), BN_DEF(0xA637ED6B, 0xF44C42E9), + BN_DEF(0x625E7EC6, 0xE485B576), BN_DEF(0x6D51C245, 0x4FE1356D), + BN_DEF(0xF25F1437, 0x302B0A6D), BN_DEF(0xCD3A431B, 0xEF9519B3), + BN_DEF(0x8E3404DD, 0x514A0879), BN_DEF(0x3B139B22, 0x020BBEA6), + BN_DEF(0x8A67CC74, 0x29024E08), BN_DEF(0x80DC1CD1, 0xC4C6628B), + BN_DEF(0x2168C234, 0xC90FDAA2), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) }; - -static const BN_ULONG dh2048_256_g[] = { - 0x664B4C0F6CC41659ULL, 0x5E2327CFEF98C582ULL, 0xD647D148D4795451ULL, - 0x2F63078490F00EF8ULL, 0x184B523D1DB246C3ULL, 0xC7891428CDC67EB6ULL, - 0x7FD028370DF92B52ULL, 0xB3353BBB64E0EC37ULL, 0xECD06E1557CD0915ULL, - 0xB7D2BBD2DF016199ULL, 0xC8484B1E052588B9ULL, 0xDB2A3B7313D3FE14ULL, - 0xD052B985D182EA0AULL, 0xA4BD1BFFE83B9C80ULL, 0xDFC967C1FB3F2E55ULL, - 0xB5045AF2767164E1ULL, 0x1D14348F6F2F9193ULL, 0x64E67982428EBC83ULL, - 0x8AC376D282D6ED38ULL, 0x777DE62AAAB8A862ULL, 0xDDF463E5E9EC144BULL, - 0x0196F931C77A57F2ULL, 0xA55AE31341000A65ULL, 0x901228F8C28CBB18ULL, - 0xBC3773BF7E8C6F62ULL, 0xBE3A6C1B0C6B47B1ULL, 0xFF4FED4AAC0BB555ULL, - 0x10DBC15077BE463FULL, 0x07F4793A1A0BA125ULL, 0x4CA7B18F21EF2054ULL, - 0x2E77506660EDBD48ULL, 0x3FB32C9B73134D0BULL +/* q = (p - 1) / 2 */ +static const BN_ULONG modp_3072_q[] = { + BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), BN_DEF(0x549D6965, 0x25C16890), + BN_DEF(0x707E8847, 0xA1EDADFE), BN_DEF(0x3A72D598, 0x047127D0), + BN_DEF(0x5D6CA371, 0x3B84C460), BN_DEF(0xBD30AEB6, 0x5DF08BAB), + BN_DEF(0x0BBD9006, 0x290F958C), BN_DEF(0x9F643532, 0x6C3B0139), + BN_DEF(0x6CC50432, 0xF897FD03), BN_DEF(0x0D697735, 0xE771E913), + BN_DEF(0x2512B0CE, 0x8F464A70), BN_DEF(0x6D8499EB, 0xD5FAD746), + BN_DEF(0xD370F263, 0xD9CB87C2), BN_DEF(0xAE83063E, 0x457538AB), + BN_DEF(0x2C6DF785, 0x767DC282), BN_DEF(0xEF8E5D32, 0xD42A90D5), + BN_DEF(0x82283D19, 0xD6998B86), BN_DEF(0x45556216, 0x0AB9472D), + BN_DEF(0x4C7D0288, 0x8AE9130C), BN_DEF(0x754AB572, 0x1CCAA4BE), + BN_DEF(0x4AAC0B8C, 0xEF15E5FB), BN_DEF(0x37A62964, 0xDAE2AEF8), + BN_DEF(0x7603D147, 0xCD93C1D1), BN_DEF(0x0C074301, 0xF1CF3B96), + BN_DEF(0x171B671D, 0x19482F23), BN_DEF(0x650C10BE, 0x78BA3604), + BN_DEF(0x255E4C02, 0xB3861AA7), BN_DEF(0xB84B4B36, 0xCF6A9483), + BN_DEF(0x1042A95D, 0x0E3179AB), BN_DEF(0xEE51D6CB, 0xC1B2AE91), + BN_DEF(0x7E9267AF, 0x348B1FD4), BN_DEF(0x0E2AE9CD, 0xCC6D241B), + BN_DEF(0x50B1DF82, 0xE1003E5C), BN_DEF(0xF6722D9E, 0x24943328), + BN_DEF(0xBE258FF3, 0xD74F9208), BN_DEF(0xAD44CFD2, 0xF71C35FD), + BN_DEF(0x7A035BF6, 0x85FFAE5B), BN_DEF(0xD31BF6B5, 0x7A262174), + BN_DEF(0x312F3F63, 0xF242DABB), BN_DEF(0xB6A8E122, 0xA7F09AB6), + BN_DEF(0xF92F8A1B, 0x98158536), BN_DEF(0xE69D218D, 0xF7CA8CD9), + BN_DEF(0xC71A026E, 0x28A5043C), BN_DEF(0x1D89CD91, 0x0105DF53), + BN_DEF(0x4533E63A, 0x94812704), BN_DEF(0xC06E0E68, 0x62633145), + BN_DEF(0x10B4611A, 0xE487ED51), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), }; -static const BN_ULONG dh2048_256_q[] = { - 0xA308B0FE64F5FBD3ULL, 0x99B1A47D1EB3750BULL, 0xB447997640129DA2ULL, - 0x8CF83642A709A097ULL +/*- + * "4096-bit MODP Group" from RFC3526, Section 5. + * + * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 } + * + * RFC3526 specifies a generator of 2. + */ +static const BN_ULONG modp_4096_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x34063199, 0x4DF435C9), + BN_DEF(0x90A6C08F, 0x86FFB7DC), BN_DEF(0x8D8FDDC1, 0x93B4EA98), + BN_DEF(0xD5B05AA9, 0xD0069127), BN_DEF(0x2170481C, 0xB81BDD76), + BN_DEF(0xCEE2D7AF, 0x1F612970), BN_DEF(0x515BE7ED, 0x233BA186), + BN_DEF(0xA090C3A2, 0x99B2964F), BN_DEF(0x4E6BC05D, 0x287C5947), + BN_DEF(0x1FBECAA6, 0x2E8EFC14), BN_DEF(0x04DE8EF9, 0xDBBBC2DB), + BN_DEF(0x2AD44CE8, 0x2583E9CA), BN_DEF(0xB6150BDA, 0x1A946834), + BN_DEF(0x6AF4E23C, 0x99C32718), BN_DEF(0xBDBA5B26, 0x88719A10), + BN_DEF(0xA787E6D7, 0x1A723C12), BN_DEF(0xA9210801, 0x4B82D120), + BN_DEF(0xE0FD108E, 0x43DB5BFC), BN_DEF(0x74E5AB31, 0x08E24FA0), + BN_DEF(0xBAD946E2, 0x770988C0), BN_DEF(0x7A615D6C, 0xBBE11757), + BN_DEF(0x177B200C, 0x521F2B18), BN_DEF(0x3EC86A64, 0xD8760273), + BN_DEF(0xD98A0864, 0xF12FFA06), BN_DEF(0x1AD2EE6B, 0xCEE3D226), + BN_DEF(0x4A25619D, 0x1E8C94E0), BN_DEF(0xDB0933D7, 0xABF5AE8C), + BN_DEF(0xA6E1E4C7, 0xB3970F85), BN_DEF(0x5D060C7D, 0x8AEA7157), + BN_DEF(0x58DBEF0A, 0xECFB8504), BN_DEF(0xDF1CBA64, 0xA85521AB), + BN_DEF(0x04507A33, 0xAD33170D), BN_DEF(0x8AAAC42D, 0x15728E5A), + BN_DEF(0x98FA0510, 0x15D22618), BN_DEF(0xEA956AE5, 0x3995497C), + BN_DEF(0x95581718, 0xDE2BCBF6), BN_DEF(0x6F4C52C9, 0xB5C55DF0), + BN_DEF(0xEC07A28F, 0x9B2783A2), BN_DEF(0x180E8603, 0xE39E772C), + BN_DEF(0x2E36CE3B, 0x32905E46), BN_DEF(0xCA18217C, 0xF1746C08), + BN_DEF(0x4ABC9804, 0x670C354E), BN_DEF(0x7096966D, 0x9ED52907), + BN_DEF(0x208552BB, 0x1C62F356), BN_DEF(0xDCA3AD96, 0x83655D23), + BN_DEF(0xFD24CF5F, 0x69163FA8), BN_DEF(0x1C55D39A, 0x98DA4836), + BN_DEF(0xA163BF05, 0xC2007CB8), BN_DEF(0xECE45B3D, 0x49286651), + BN_DEF(0x7C4B1FE6, 0xAE9F2411), BN_DEF(0x5A899FA5, 0xEE386BFB), + BN_DEF(0xF406B7ED, 0x0BFF5CB6), BN_DEF(0xA637ED6B, 0xF44C42E9), + BN_DEF(0x625E7EC6, 0xE485B576), BN_DEF(0x6D51C245, 0x4FE1356D), + BN_DEF(0xF25F1437, 0x302B0A6D), BN_DEF(0xCD3A431B, 0xEF9519B3), + BN_DEF(0x8E3404DD, 0x514A0879), BN_DEF(0x3B139B22, 0x020BBEA6), + BN_DEF(0x8A67CC74, 0x29024E08), BN_DEF(0x80DC1CD1, 0xC4C6628B), + BN_DEF(0x2168C234, 0xC90FDAA2), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) }; - -/* Primes from RFC 7919 */ -static const BN_ULONG ffdhe2048_p[] = { - 0xFFFFFFFFFFFFFFFFULL, 0x886B423861285C97ULL, 0xC6F34A26C1B2EFFAULL, - 0xC58EF1837D1683B2ULL, 0x3BB5FCBC2EC22005ULL, 0xC3FE3B1B4C6FAD73ULL, - 0x8E4F1232EEF28183ULL, 0x9172FE9CE98583FFULL, 0xC03404CD28342F61ULL, - 0x9E02FCE1CDF7E2ECULL, 0x0B07A7C8EE0A6D70ULL, 0xAE56EDE76372BB19ULL, - 0x1D4F42A3DE394DF4ULL, 0xB96ADAB760D7F468ULL, 0xD108A94BB2C8E3FBULL, - 0xBC0AB182B324FB61ULL, 0x30ACCA4F483A797AULL, 0x1DF158A136ADE735ULL, - 0xE2A689DAF3EFE872ULL, 0x984F0C70E0E68B77ULL, 0xB557135E7F57C935ULL, - 0x856365553DED1AF3ULL, 0x2433F51F5F066ED0ULL, 0xD3DF1ED5D5FD6561ULL, - 0xF681B202AEC4617AULL, 0x7D2FE363630C75D8ULL, 0xCC939DCE249B3EF9ULL, - 0xA9E13641146433FBULL, 0xD8B9C583CE2D3695ULL, 0xAFDC5620273D3CF1ULL, - 0xADF85458A2BB4A9AULL, 0xFFFFFFFFFFFFFFFFULL +/* q = (p - 1) / 2 */ +static const BN_ULONG modp_4096_q[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x9A0318CC, 0xA6FA1AE4), + BN_DEF(0x48536047, 0xC37FDBEE), BN_DEF(0x46C7EEE0, 0xC9DA754C), + BN_DEF(0xEAD82D54, 0x68034893), BN_DEF(0x10B8240E, 0xDC0DEEBB), + BN_DEF(0x67716BD7, 0x8FB094B8), BN_DEF(0x28ADF3F6, 0x119DD0C3), + BN_DEF(0xD04861D1, 0xCCD94B27), BN_DEF(0xA735E02E, 0x143E2CA3), + BN_DEF(0x0FDF6553, 0x97477E0A), BN_DEF(0x826F477C, 0x6DDDE16D), + BN_DEF(0x156A2674, 0x12C1F4E5), BN_DEF(0x5B0A85ED, 0x0D4A341A), + BN_DEF(0x357A711E, 0x4CE1938C), BN_DEF(0x5EDD2D93, 0xC438CD08), + BN_DEF(0x53C3F36B, 0x8D391E09), BN_DEF(0x54908400, 0x25C16890), + BN_DEF(0x707E8847, 0xA1EDADFE), BN_DEF(0x3A72D598, 0x047127D0), + BN_DEF(0x5D6CA371, 0x3B84C460), BN_DEF(0xBD30AEB6, 0x5DF08BAB), + BN_DEF(0x0BBD9006, 0x290F958C), BN_DEF(0x9F643532, 0x6C3B0139), + BN_DEF(0x6CC50432, 0xF897FD03), BN_DEF(0x0D697735, 0xE771E913), + BN_DEF(0x2512B0CE, 0x8F464A70), BN_DEF(0x6D8499EB, 0xD5FAD746), + BN_DEF(0xD370F263, 0xD9CB87C2), BN_DEF(0xAE83063E, 0x457538AB), + BN_DEF(0x2C6DF785, 0x767DC282), BN_DEF(0xEF8E5D32, 0xD42A90D5), + BN_DEF(0x82283D19, 0xD6998B86), BN_DEF(0x45556216, 0x0AB9472D), + BN_DEF(0x4C7D0288, 0x8AE9130C), BN_DEF(0x754AB572, 0x1CCAA4BE), + BN_DEF(0x4AAC0B8C, 0xEF15E5FB), BN_DEF(0x37A62964, 0xDAE2AEF8), + BN_DEF(0x7603D147, 0xCD93C1D1), BN_DEF(0x0C074301, 0xF1CF3B96), + BN_DEF(0x171B671D, 0x19482F23), BN_DEF(0x650C10BE, 0x78BA3604), + BN_DEF(0x255E4C02, 0xB3861AA7), BN_DEF(0xB84B4B36, 0xCF6A9483), + BN_DEF(0x1042A95D, 0x0E3179AB), BN_DEF(0xEE51D6CB, 0xC1B2AE91), + BN_DEF(0x7E9267AF, 0x348B1FD4), BN_DEF(0x0E2AE9CD, 0xCC6D241B), + BN_DEF(0x50B1DF82, 0xE1003E5C), BN_DEF(0xF6722D9E, 0x24943328), + BN_DEF(0xBE258FF3, 0xD74F9208), BN_DEF(0xAD44CFD2, 0xF71C35FD), + BN_DEF(0x7A035BF6, 0x85FFAE5B), BN_DEF(0xD31BF6B5, 0x7A262174), + BN_DEF(0x312F3F63, 0xF242DABB), BN_DEF(0xB6A8E122, 0xA7F09AB6), + BN_DEF(0xF92F8A1B, 0x98158536), BN_DEF(0xE69D218D, 0xF7CA8CD9), + BN_DEF(0xC71A026E, 0x28A5043C), BN_DEF(0x1D89CD91, 0x0105DF53), + BN_DEF(0x4533E63A, 0x94812704), BN_DEF(0xC06E0E68, 0x62633145), + BN_DEF(0x10B4611A, 0xE487ED51), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), }; -static const BN_ULONG ffdhe3072_p[] = { - 0xFFFFFFFFFFFFFFFFULL, 0x25E41D2B66C62E37ULL, 0x3C1B20EE3FD59D7CULL, - 0x0ABCD06BFA53DDEFULL, 0x1DBF9A42D5C4484EULL, 0xABC521979B0DEADAULL, - 0xE86D2BC522363A0DULL, 0x5CAE82AB9C9DF69EULL, 0x64F2E21E71F54BFFULL, - 0xF4FD4452E2D74DD3ULL, 0xB4130C93BC437944ULL, 0xAEFE130985139270ULL, - 0x598CB0FAC186D91CULL, 0x7AD91D2691F7F7EEULL, 0x61B46FC9D6E6C907ULL, - 0xBC34F4DEF99C0238ULL, 0xDE355B3B6519035BULL, 0x886B4238611FCFDCULL, - 0xC6F34A26C1B2EFFAULL, 0xC58EF1837D1683B2ULL, 0x3BB5FCBC2EC22005ULL, - 0xC3FE3B1B4C6FAD73ULL, 0x8E4F1232EEF28183ULL, 0x9172FE9CE98583FFULL, - 0xC03404CD28342F61ULL, 0x9E02FCE1CDF7E2ECULL, 0x0B07A7C8EE0A6D70ULL, - 0xAE56EDE76372BB19ULL, 0x1D4F42A3DE394DF4ULL, 0xB96ADAB760D7F468ULL, - 0xD108A94BB2C8E3FBULL, 0xBC0AB182B324FB61ULL, 0x30ACCA4F483A797AULL, - 0x1DF158A136ADE735ULL, 0xE2A689DAF3EFE872ULL, 0x984F0C70E0E68B77ULL, - 0xB557135E7F57C935ULL, 0x856365553DED1AF3ULL, 0x2433F51F5F066ED0ULL, - 0xD3DF1ED5D5FD6561ULL, 0xF681B202AEC4617AULL, 0x7D2FE363630C75D8ULL, - 0xCC939DCE249B3EF9ULL, 0xA9E13641146433FBULL, 0xD8B9C583CE2D3695ULL, - 0xAFDC5620273D3CF1ULL, 0xADF85458A2BB4A9AULL, 0xFFFFFFFFFFFFFFFFULL +/*- + * "6144-bit MODP Group" from RFC3526, Section 6. + * + * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 } + * + * RFC3526 specifies a generator of 2. + */ +static const BN_ULONG modp_6144_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x6DCC4024, 0xE694F91E), + BN_DEF(0x0B7474D6, 0x12BF2D5B), BN_DEF(0x3F4860EE, 0x043E8F66), + BN_DEF(0x6E3C0468, 0x387FE8D7), BN_DEF(0x2EF29632, 0xDA56C9EC), + BN_DEF(0xA313D55C, 0xEB19CCB1), BN_DEF(0x8A1FBFF0, 0xF550AA3D), + BN_DEF(0xB7C5DA76, 0x06A1D58B), BN_DEF(0xF29BE328, 0xA79715EE), + BN_DEF(0x0F8037E0, 0x14CC5ED2), BN_DEF(0xBF48E1D8, 0xCC8F6D7E), + BN_DEF(0x2B4154AA, 0x4BD407B2), BN_DEF(0xFF585AC5, 0x0F1D45B7), + BN_DEF(0x36CC88BE, 0x23A97A7E), BN_DEF(0xBEC7E8F3, 0x59E7C97F), + BN_DEF(0x900B1C9E, 0xB5A84031), BN_DEF(0x46980C82, 0xD55E702F), + BN_DEF(0x6E74FEF6, 0xF482D7CE), BN_DEF(0xD1721D03, 0xF032EA15), + BN_DEF(0xC64B92EC, 0x5983CA01), BN_DEF(0x378CD2BF, 0x6FB8F401), + BN_DEF(0x2BD7AF42, 0x33205151), BN_DEF(0xE6CC254B, 0xDB7F1447), + BN_DEF(0xCED4BB1B, 0x44CE6CBA), BN_DEF(0xCF9B14ED, 0xDA3EDBEB), + BN_DEF(0x865A8918, 0x179727B0), BN_DEF(0x9027D831, 0xB06A53ED), + BN_DEF(0x413001AE, 0xE5DB382F), BN_DEF(0xAD9E530E, 0xF8FF9406), + BN_DEF(0x3DBA37BD, 0xC9751E76), BN_DEF(0x602646DE, 0xC1D4DCB2), + BN_DEF(0xD27C7026, 0x36C3FAB4), BN_DEF(0x34028492, 0x4DF435C9), + BN_DEF(0x90A6C08F, 0x86FFB7DC), BN_DEF(0x8D8FDDC1, 0x93B4EA98), + BN_DEF(0xD5B05AA9, 0xD0069127), BN_DEF(0x2170481C, 0xB81BDD76), + BN_DEF(0xCEE2D7AF, 0x1F612970), BN_DEF(0x515BE7ED, 0x233BA186), + BN_DEF(0xA090C3A2, 0x99B2964F), BN_DEF(0x4E6BC05D, 0x287C5947), + BN_DEF(0x1FBECAA6, 0x2E8EFC14), BN_DEF(0x04DE8EF9, 0xDBBBC2DB), + BN_DEF(0x2AD44CE8, 0x2583E9CA), BN_DEF(0xB6150BDA, 0x1A946834), + BN_DEF(0x6AF4E23C, 0x99C32718), BN_DEF(0xBDBA5B26, 0x88719A10), + BN_DEF(0xA787E6D7, 0x1A723C12), BN_DEF(0xA9210801, 0x4B82D120), + BN_DEF(0xE0FD108E, 0x43DB5BFC), BN_DEF(0x74E5AB31, 0x08E24FA0), + BN_DEF(0xBAD946E2, 0x770988C0), BN_DEF(0x7A615D6C, 0xBBE11757), + BN_DEF(0x177B200C, 0x521F2B18), BN_DEF(0x3EC86A64, 0xD8760273), + BN_DEF(0xD98A0864, 0xF12FFA06), BN_DEF(0x1AD2EE6B, 0xCEE3D226), + BN_DEF(0x4A25619D, 0x1E8C94E0), BN_DEF(0xDB0933D7, 0xABF5AE8C), + BN_DEF(0xA6E1E4C7, 0xB3970F85), BN_DEF(0x5D060C7D, 0x8AEA7157), + BN_DEF(0x58DBEF0A, 0xECFB8504), BN_DEF(0xDF1CBA64, 0xA85521AB), + BN_DEF(0x04507A33, 0xAD33170D), BN_DEF(0x8AAAC42D, 0x15728E5A), + BN_DEF(0x98FA0510, 0x15D22618), BN_DEF(0xEA956AE5, 0x3995497C), + BN_DEF(0x95581718, 0xDE2BCBF6), BN_DEF(0x6F4C52C9, 0xB5C55DF0), + BN_DEF(0xEC07A28F, 0x9B2783A2), BN_DEF(0x180E8603, 0xE39E772C), + BN_DEF(0x2E36CE3B, 0x32905E46), BN_DEF(0xCA18217C, 0xF1746C08), + BN_DEF(0x4ABC9804, 0x670C354E), BN_DEF(0x7096966D, 0x9ED52907), + BN_DEF(0x208552BB, 0x1C62F356), BN_DEF(0xDCA3AD96, 0x83655D23), + BN_DEF(0xFD24CF5F, 0x69163FA8), BN_DEF(0x1C55D39A, 0x98DA4836), + BN_DEF(0xA163BF05, 0xC2007CB8), BN_DEF(0xECE45B3D, 0x49286651), + BN_DEF(0x7C4B1FE6, 0xAE9F2411), BN_DEF(0x5A899FA5, 0xEE386BFB), + BN_DEF(0xF406B7ED, 0x0BFF5CB6), BN_DEF(0xA637ED6B, 0xF44C42E9), + BN_DEF(0x625E7EC6, 0xE485B576), BN_DEF(0x6D51C245, 0x4FE1356D), + BN_DEF(0xF25F1437, 0x302B0A6D), BN_DEF(0xCD3A431B, 0xEF9519B3), + BN_DEF(0x8E3404DD, 0x514A0879), BN_DEF(0x3B139B22, 0x020BBEA6), + BN_DEF(0x8A67CC74, 0x29024E08), BN_DEF(0x80DC1CD1, 0xC4C6628B), + BN_DEF(0x2168C234, 0xC90FDAA2), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) }; - -static const BN_ULONG ffdhe4096_p[] = { - 0xFFFFFFFFFFFFFFFFULL, 0xC68A007E5E655F6AULL, 0x4DB5A851F44182E1ULL, - 0x8EC9B55A7F88A46BULL, 0x0A8291CDCEC97DCFULL, 0x2A4ECEA9F98D0ACCULL, - 0x1A1DB93D7140003CULL, 0x092999A333CB8B7AULL, 0x6DC778F971AD0038ULL, - 0xA907600A918130C4ULL, 0xED6A1E012D9E6832ULL, 0x7135C886EFB4318AULL, - 0x87F55BA57E31CC7AULL, 0x7763CF1D55034004ULL, 0xAC7D5F42D69F6D18ULL, - 0x7930E9E4E58857B6ULL, 0x6E6F52C3164DF4FBULL, 0x25E41D2B669E1EF1ULL, - 0x3C1B20EE3FD59D7CULL, 0x0ABCD06BFA53DDEFULL, 0x1DBF9A42D5C4484EULL, - 0xABC521979B0DEADAULL, 0xE86D2BC522363A0DULL, 0x5CAE82AB9C9DF69EULL, - 0x64F2E21E71F54BFFULL, 0xF4FD4452E2D74DD3ULL, 0xB4130C93BC437944ULL, - 0xAEFE130985139270ULL, 0x598CB0FAC186D91CULL, 0x7AD91D2691F7F7EEULL, - 0x61B46FC9D6E6C907ULL, 0xBC34F4DEF99C0238ULL, 0xDE355B3B6519035BULL, - 0x886B4238611FCFDCULL, 0xC6F34A26C1B2EFFAULL, 0xC58EF1837D1683B2ULL, - 0x3BB5FCBC2EC22005ULL, 0xC3FE3B1B4C6FAD73ULL, 0x8E4F1232EEF28183ULL, - 0x9172FE9CE98583FFULL, 0xC03404CD28342F61ULL, 0x9E02FCE1CDF7E2ECULL, - 0x0B07A7C8EE0A6D70ULL, 0xAE56EDE76372BB19ULL, 0x1D4F42A3DE394DF4ULL, - 0xB96ADAB760D7F468ULL, 0xD108A94BB2C8E3FBULL, 0xBC0AB182B324FB61ULL, - 0x30ACCA4F483A797AULL, 0x1DF158A136ADE735ULL, 0xE2A689DAF3EFE872ULL, - 0x984F0C70E0E68B77ULL, 0xB557135E7F57C935ULL, 0x856365553DED1AF3ULL, - 0x2433F51F5F066ED0ULL, 0xD3DF1ED5D5FD6561ULL, 0xF681B202AEC4617AULL, - 0x7D2FE363630C75D8ULL, 0xCC939DCE249B3EF9ULL, 0xA9E13641146433FBULL, - 0xD8B9C583CE2D3695ULL, 0xAFDC5620273D3CF1ULL, 0xADF85458A2BB4A9AULL, - 0xFFFFFFFFFFFFFFFFULL +/* q = (p - 1) / 2 */ +static const BN_ULONG modp_6144_q[] = { + BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), BN_DEF(0x36E62012, 0x734A7C8F), + BN_DEF(0x85BA3A6B, 0x095F96AD), BN_DEF(0x1FA43077, 0x021F47B3), + BN_DEF(0xB71E0234, 0x1C3FF46B), BN_DEF(0x17794B19, 0x6D2B64F6), + BN_DEF(0xD189EAAE, 0x758CE658), BN_DEF(0xC50FDFF8, 0x7AA8551E), + BN_DEF(0xDBE2ED3B, 0x0350EAC5), BN_DEF(0x794DF194, 0x53CB8AF7), + BN_DEF(0x07C01BF0, 0x0A662F69), BN_DEF(0x5FA470EC, 0x6647B6BF), + BN_DEF(0x15A0AA55, 0xA5EA03D9), BN_DEF(0xFFAC2D62, 0x078EA2DB), + BN_DEF(0x1B66445F, 0x91D4BD3F), BN_DEF(0xDF63F479, 0x2CF3E4BF), + BN_DEF(0xC8058E4F, 0x5AD42018), BN_DEF(0xA34C0641, 0x6AAF3817), + BN_DEF(0x373A7F7B, 0xFA416BE7), BN_DEF(0xE8B90E81, 0x7819750A), + BN_DEF(0xE325C976, 0xACC1E500), BN_DEF(0x9BC6695F, 0x37DC7A00), + BN_DEF(0x95EBD7A1, 0x999028A8), BN_DEF(0xF36612A5, 0xEDBF8A23), + BN_DEF(0x676A5D8D, 0xA267365D), BN_DEF(0xE7CD8A76, 0x6D1F6DF5), + BN_DEF(0x432D448C, 0x8BCB93D8), BN_DEF(0xC813EC18, 0x583529F6), + BN_DEF(0xA09800D7, 0x72ED9C17), BN_DEF(0x56CF2987, 0xFC7FCA03), + BN_DEF(0x1EDD1BDE, 0x64BA8F3B), BN_DEF(0x3013236F, 0x60EA6E59), + BN_DEF(0x693E3813, 0x1B61FD5A), BN_DEF(0x9A014249, 0xA6FA1AE4), + BN_DEF(0x48536047, 0xC37FDBEE), BN_DEF(0x46C7EEE0, 0xC9DA754C), + BN_DEF(0xEAD82D54, 0x68034893), BN_DEF(0x10B8240E, 0xDC0DEEBB), + BN_DEF(0x67716BD7, 0x8FB094B8), BN_DEF(0x28ADF3F6, 0x119DD0C3), + BN_DEF(0xD04861D1, 0xCCD94B27), BN_DEF(0xA735E02E, 0x143E2CA3), + BN_DEF(0x0FDF6553, 0x97477E0A), BN_DEF(0x826F477C, 0x6DDDE16D), + BN_DEF(0x156A2674, 0x12C1F4E5), BN_DEF(0x5B0A85ED, 0x0D4A341A), + BN_DEF(0x357A711E, 0x4CE1938C), BN_DEF(0x5EDD2D93, 0xC438CD08), + BN_DEF(0x53C3F36B, 0x8D391E09), BN_DEF(0x54908400, 0x25C16890), + BN_DEF(0x707E8847, 0xA1EDADFE), BN_DEF(0x3A72D598, 0x047127D0), + BN_DEF(0x5D6CA371, 0x3B84C460), BN_DEF(0xBD30AEB6, 0x5DF08BAB), + BN_DEF(0x0BBD9006, 0x290F958C), BN_DEF(0x9F643532, 0x6C3B0139), + BN_DEF(0x6CC50432, 0xF897FD03), BN_DEF(0x0D697735, 0xE771E913), + BN_DEF(0x2512B0CE, 0x8F464A70), BN_DEF(0x6D8499EB, 0xD5FAD746), + BN_DEF(0xD370F263, 0xD9CB87C2), BN_DEF(0xAE83063E, 0x457538AB), + BN_DEF(0x2C6DF785, 0x767DC282), BN_DEF(0xEF8E5D32, 0xD42A90D5), + BN_DEF(0x82283D19, 0xD6998B86), BN_DEF(0x45556216, 0x0AB9472D), + BN_DEF(0x4C7D0288, 0x8AE9130C), BN_DEF(0x754AB572, 0x1CCAA4BE), + BN_DEF(0x4AAC0B8C, 0xEF15E5FB), BN_DEF(0x37A62964, 0xDAE2AEF8), + BN_DEF(0x7603D147, 0xCD93C1D1), BN_DEF(0x0C074301, 0xF1CF3B96), + BN_DEF(0x171B671D, 0x19482F23), BN_DEF(0x650C10BE, 0x78BA3604), + BN_DEF(0x255E4C02, 0xB3861AA7), BN_DEF(0xB84B4B36, 0xCF6A9483), + BN_DEF(0x1042A95D, 0x0E3179AB), BN_DEF(0xEE51D6CB, 0xC1B2AE91), + BN_DEF(0x7E9267AF, 0x348B1FD4), BN_DEF(0x0E2AE9CD, 0xCC6D241B), + BN_DEF(0x50B1DF82, 0xE1003E5C), BN_DEF(0xF6722D9E, 0x24943328), + BN_DEF(0xBE258FF3, 0xD74F9208), BN_DEF(0xAD44CFD2, 0xF71C35FD), + BN_DEF(0x7A035BF6, 0x85FFAE5B), BN_DEF(0xD31BF6B5, 0x7A262174), + BN_DEF(0x312F3F63, 0xF242DABB), BN_DEF(0xB6A8E122, 0xA7F09AB6), + BN_DEF(0xF92F8A1B, 0x98158536), BN_DEF(0xE69D218D, 0xF7CA8CD9), + BN_DEF(0xC71A026E, 0x28A5043C), BN_DEF(0x1D89CD91, 0x0105DF53), + BN_DEF(0x4533E63A, 0x94812704), BN_DEF(0xC06E0E68, 0x62633145), + BN_DEF(0x10B4611A, 0xE487ED51), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), }; -static const BN_ULONG ffdhe6144_p[] = { - 0xFFFFFFFFFFFFFFFFULL, 0xA40E329CD0E40E65ULL, 0xA41D570D7938DAD4ULL, - 0x62A69526D43161C1ULL, 0x3FDD4A8E9ADB1E69ULL, 0x5B3B71F9DC6B80D6ULL, - 0xEC9D1810C6272B04ULL, 0x8CCF2DD5CACEF403ULL, 0xE49F5235C95B9117ULL, - 0x505DC82DB854338AULL, 0x62292C311562A846ULL, 0xD72B03746AE77F5EULL, - 0xF9C9091B462D538CULL, 0x0AE8DB5847A67CBEULL, 0xB3A739C122611682ULL, - 0xEEAAC0232A281BF6ULL, 0x94C6651E77CAF992ULL, 0x763E4E4B94B2BBC1ULL, - 0x587E38DA0077D9B4ULL, 0x7FB29F8C183023C3ULL, 0x0ABEC1FFF9E3A26EULL, - 0xA00EF092350511E3ULL, 0xB855322EDB6340D8ULL, 0xA52471F7A9A96910ULL, - 0x388147FB4CFDB477ULL, 0x9B1F5C3E4E46041FULL, 0xCDAD0657FCCFEC71ULL, - 0xB38E8C334C701C3AULL, 0x917BDD64B1C0FD4CULL, 0x3BB454329B7624C8ULL, - 0x23BA4442CAF53EA6ULL, 0x4E677D2C38532A3AULL, 0x0BFD64B645036C7AULL, - 0xC68A007E5E0DD902ULL, 0x4DB5A851F44182E1ULL, 0x8EC9B55A7F88A46BULL, - 0x0A8291CDCEC97DCFULL, 0x2A4ECEA9F98D0ACCULL, 0x1A1DB93D7140003CULL, - 0x092999A333CB8B7AULL, 0x6DC778F971AD0038ULL, 0xA907600A918130C4ULL, - 0xED6A1E012D9E6832ULL, 0x7135C886EFB4318AULL, 0x87F55BA57E31CC7AULL, - 0x7763CF1D55034004ULL, 0xAC7D5F42D69F6D18ULL, 0x7930E9E4E58857B6ULL, - 0x6E6F52C3164DF4FBULL, 0x25E41D2B669E1EF1ULL, 0x3C1B20EE3FD59D7CULL, - 0x0ABCD06BFA53DDEFULL, 0x1DBF9A42D5C4484EULL, 0xABC521979B0DEADAULL, - 0xE86D2BC522363A0DULL, 0x5CAE82AB9C9DF69EULL, 0x64F2E21E71F54BFFULL, - 0xF4FD4452E2D74DD3ULL, 0xB4130C93BC437944ULL, 0xAEFE130985139270ULL, - 0x598CB0FAC186D91CULL, 0x7AD91D2691F7F7EEULL, 0x61B46FC9D6E6C907ULL, - 0xBC34F4DEF99C0238ULL, 0xDE355B3B6519035BULL, 0x886B4238611FCFDCULL, - 0xC6F34A26C1B2EFFAULL, 0xC58EF1837D1683B2ULL, 0x3BB5FCBC2EC22005ULL, - 0xC3FE3B1B4C6FAD73ULL, 0x8E4F1232EEF28183ULL, 0x9172FE9CE98583FFULL, - 0xC03404CD28342F61ULL, 0x9E02FCE1CDF7E2ECULL, 0x0B07A7C8EE0A6D70ULL, - 0xAE56EDE76372BB19ULL, 0x1D4F42A3DE394DF4ULL, 0xB96ADAB760D7F468ULL, - 0xD108A94BB2C8E3FBULL, 0xBC0AB182B324FB61ULL, 0x30ACCA4F483A797AULL, - 0x1DF158A136ADE735ULL, 0xE2A689DAF3EFE872ULL, 0x984F0C70E0E68B77ULL, - 0xB557135E7F57C935ULL, 0x856365553DED1AF3ULL, 0x2433F51F5F066ED0ULL, - 0xD3DF1ED5D5FD6561ULL, 0xF681B202AEC4617AULL, 0x7D2FE363630C75D8ULL, - 0xCC939DCE249B3EF9ULL, 0xA9E13641146433FBULL, 0xD8B9C583CE2D3695ULL, - 0xAFDC5620273D3CF1ULL, 0xADF85458A2BB4A9AULL, 0xFFFFFFFFFFFFFFFFULL +/* + * "8192-bit MODP Group" from RFC3526, Section 7. + * + * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 } + * + * RFC3526 specifies a generator of 2. + */ +static const BN_ULONG modp_8192_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x98EDD3DF, 0x60C980DD), + BN_DEF(0x80B96E71, 0xC81F56E8), BN_DEF(0x765694DF, 0x9E3050E2), + BN_DEF(0x5677E9AA, 0x9558E447), BN_DEF(0xFC026E47, 0xC9190DA6), + BN_DEF(0xD5EE382B, 0x889A002E), BN_DEF(0x481C6CD7, 0x4009438B), + BN_DEF(0xEB879F92, 0x359046F4), BN_DEF(0x1ECFA268, 0xFAF36BC3), + BN_DEF(0x7EE74D73, 0xB1D510BD), BN_DEF(0x5DED7EA1, 0xF9AB4819), + BN_DEF(0x0846851D, 0x64F31CC5), BN_DEF(0xA0255DC1, 0x4597E899), + BN_DEF(0x74AB6A36, 0xDF310EE0), BN_DEF(0x3F44F82D, 0x6D2A13F8), + BN_DEF(0xB3A278A6, 0x062B3CF5), BN_DEF(0xED5BDD3A, 0x79683303), + BN_DEF(0xA2C087E8, 0xFA9D4B7F), BN_DEF(0x2F8385DD, 0x4BCBC886), + BN_DEF(0x6CEA306B, 0x3473FC64), BN_DEF(0x1A23F0C7, 0x13EB57A8), + BN_DEF(0xA4037C07, 0x22222E04), BN_DEF(0xFC848AD9, 0xE3FDB8BE), + BN_DEF(0xE39D652D, 0x238F16CB), BN_DEF(0x2BF1C978, 0x3423B474), + BN_DEF(0x5AE4F568, 0x3AAB639C), BN_DEF(0x6BA42466, 0x2576F693), + BN_DEF(0x8AFC47ED, 0x741FA7BF), BN_DEF(0x8D9DD300, 0x3BC832B6), + BN_DEF(0x73B931BA, 0xD8BEC4D0), BN_DEF(0xA932DF8C, 0x38777CB6), + BN_DEF(0x12FEE5E4, 0x74A3926F), BN_DEF(0x6DBE1159, 0xE694F91E), + BN_DEF(0x0B7474D6, 0x12BF2D5B), BN_DEF(0x3F4860EE, 0x043E8F66), + BN_DEF(0x6E3C0468, 0x387FE8D7), BN_DEF(0x2EF29632, 0xDA56C9EC), + BN_DEF(0xA313D55C, 0xEB19CCB1), BN_DEF(0x8A1FBFF0, 0xF550AA3D), + BN_DEF(0xB7C5DA76, 0x06A1D58B), BN_DEF(0xF29BE328, 0xA79715EE), + BN_DEF(0x0F8037E0, 0x14CC5ED2), BN_DEF(0xBF48E1D8, 0xCC8F6D7E), + BN_DEF(0x2B4154AA, 0x4BD407B2), BN_DEF(0xFF585AC5, 0x0F1D45B7), + BN_DEF(0x36CC88BE, 0x23A97A7E), BN_DEF(0xBEC7E8F3, 0x59E7C97F), + BN_DEF(0x900B1C9E, 0xB5A84031), BN_DEF(0x46980C82, 0xD55E702F), + BN_DEF(0x6E74FEF6, 0xF482D7CE), BN_DEF(0xD1721D03, 0xF032EA15), + BN_DEF(0xC64B92EC, 0x5983CA01), BN_DEF(0x378CD2BF, 0x6FB8F401), + BN_DEF(0x2BD7AF42, 0x33205151), BN_DEF(0xE6CC254B, 0xDB7F1447), + BN_DEF(0xCED4BB1B, 0x44CE6CBA), BN_DEF(0xCF9B14ED, 0xDA3EDBEB), + BN_DEF(0x865A8918, 0x179727B0), BN_DEF(0x9027D831, 0xB06A53ED), + BN_DEF(0x413001AE, 0xE5DB382F), BN_DEF(0xAD9E530E, 0xF8FF9406), + BN_DEF(0x3DBA37BD, 0xC9751E76), BN_DEF(0x602646DE, 0xC1D4DCB2), + BN_DEF(0xD27C7026, 0x36C3FAB4), BN_DEF(0x34028492, 0x4DF435C9), + BN_DEF(0x90A6C08F, 0x86FFB7DC), BN_DEF(0x8D8FDDC1, 0x93B4EA98), + BN_DEF(0xD5B05AA9, 0xD0069127), BN_DEF(0x2170481C, 0xB81BDD76), + BN_DEF(0xCEE2D7AF, 0x1F612970), BN_DEF(0x515BE7ED, 0x233BA186), + BN_DEF(0xA090C3A2, 0x99B2964F), BN_DEF(0x4E6BC05D, 0x287C5947), + BN_DEF(0x1FBECAA6, 0x2E8EFC14), BN_DEF(0x04DE8EF9, 0xDBBBC2DB), + BN_DEF(0x2AD44CE8, 0x2583E9CA), BN_DEF(0xB6150BDA, 0x1A946834), + BN_DEF(0x6AF4E23C, 0x99C32718), BN_DEF(0xBDBA5B26, 0x88719A10), + BN_DEF(0xA787E6D7, 0x1A723C12), BN_DEF(0xA9210801, 0x4B82D120), + BN_DEF(0xE0FD108E, 0x43DB5BFC), BN_DEF(0x74E5AB31, 0x08E24FA0), + BN_DEF(0xBAD946E2, 0x770988C0), BN_DEF(0x7A615D6C, 0xBBE11757), + BN_DEF(0x177B200C, 0x521F2B18), BN_DEF(0x3EC86A64, 0xD8760273), + BN_DEF(0xD98A0864, 0xF12FFA06), BN_DEF(0x1AD2EE6B, 0xCEE3D226), + BN_DEF(0x4A25619D, 0x1E8C94E0), BN_DEF(0xDB0933D7, 0xABF5AE8C), + BN_DEF(0xA6E1E4C7, 0xB3970F85), BN_DEF(0x5D060C7D, 0x8AEA7157), + BN_DEF(0x58DBEF0A, 0xECFB8504), BN_DEF(0xDF1CBA64, 0xA85521AB), + BN_DEF(0x04507A33, 0xAD33170D), BN_DEF(0x8AAAC42D, 0x15728E5A), + BN_DEF(0x98FA0510, 0x15D22618), BN_DEF(0xEA956AE5, 0x3995497C), + BN_DEF(0x95581718, 0xDE2BCBF6), BN_DEF(0x6F4C52C9, 0xB5C55DF0), + BN_DEF(0xEC07A28F, 0x9B2783A2), BN_DEF(0x180E8603, 0xE39E772C), + BN_DEF(0x2E36CE3B, 0x32905E46), BN_DEF(0xCA18217C, 0xF1746C08), + BN_DEF(0x4ABC9804, 0x670C354E), BN_DEF(0x7096966D, 0x9ED52907), + BN_DEF(0x208552BB, 0x1C62F356), BN_DEF(0xDCA3AD96, 0x83655D23), + BN_DEF(0xFD24CF5F, 0x69163FA8), BN_DEF(0x1C55D39A, 0x98DA4836), + BN_DEF(0xA163BF05, 0xC2007CB8), BN_DEF(0xECE45B3D, 0x49286651), + BN_DEF(0x7C4B1FE6, 0xAE9F2411), BN_DEF(0x5A899FA5, 0xEE386BFB), + BN_DEF(0xF406B7ED, 0x0BFF5CB6), BN_DEF(0xA637ED6B, 0xF44C42E9), + BN_DEF(0x625E7EC6, 0xE485B576), BN_DEF(0x6D51C245, 0x4FE1356D), + BN_DEF(0xF25F1437, 0x302B0A6D), BN_DEF(0xCD3A431B, 0xEF9519B3), + BN_DEF(0x8E3404DD, 0x514A0879), BN_DEF(0x3B139B22, 0x020BBEA6), + BN_DEF(0x8A67CC74, 0x29024E08), BN_DEF(0x80DC1CD1, 0xC4C6628B), + BN_DEF(0x2168C234, 0xC90FDAA2), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) }; - -static const BN_ULONG ffdhe8192_p[] = { - 0xFFFFFFFFFFFFFFFFULL, 0xD68C8BB7C5C6424CULL, 0x011E2A94838FF88CULL, - 0x0822E506A9F4614EULL, 0x97D11D49F7A8443DULL, 0xA6BBFDE530677F0DULL, - 0x2F741EF8C1FE86FEULL, 0xFAFABE1C5D71A87EULL, 0xDED2FBABFBE58A30ULL, - 0xB6855DFE72B0A66EULL, 0x1EFC8CE0BA8A4FE8ULL, 0x83F81D4A3F2FA457ULL, - 0xA1FE3075A577E231ULL, 0xD5B8019488D9C0A0ULL, 0x624816CDAD9A95F9ULL, - 0x99E9E31650C1217BULL, 0x51AA691E0E423CFCULL, 0x1C217E6C3826E52CULL, - 0x51A8A93109703FEEULL, 0xBB7099876A460E74ULL, 0x541FC68C9C86B022ULL, - 0x59160CC046FD8251ULL, 0x2846C0BA35C35F5CULL, 0x54504AC78B758282ULL, - 0x29388839D2AF05E4ULL, 0xCB2C0F1CC01BD702ULL, 0x555B2F747C932665ULL, - 0x86B63142A3AB8829ULL, 0x0B8CC3BDF64B10EFULL, 0x687FEB69EDD1CC5EULL, - 0xFDB23FCEC9509D43ULL, 0x1E425A31D951AE64ULL, 0x36AD004CF600C838ULL, - 0xA40E329CCFF46AAAULL, 0xA41D570D7938DAD4ULL, 0x62A69526D43161C1ULL, - 0x3FDD4A8E9ADB1E69ULL, 0x5B3B71F9DC6B80D6ULL, 0xEC9D1810C6272B04ULL, - 0x8CCF2DD5CACEF403ULL, 0xE49F5235C95B9117ULL, 0x505DC82DB854338AULL, - 0x62292C311562A846ULL, 0xD72B03746AE77F5EULL, 0xF9C9091B462D538CULL, - 0x0AE8DB5847A67CBEULL, 0xB3A739C122611682ULL, 0xEEAAC0232A281BF6ULL, - 0x94C6651E77CAF992ULL, 0x763E4E4B94B2BBC1ULL, 0x587E38DA0077D9B4ULL, - 0x7FB29F8C183023C3ULL, 0x0ABEC1FFF9E3A26EULL, 0xA00EF092350511E3ULL, - 0xB855322EDB6340D8ULL, 0xA52471F7A9A96910ULL, 0x388147FB4CFDB477ULL, - 0x9B1F5C3E4E46041FULL, 0xCDAD0657FCCFEC71ULL, 0xB38E8C334C701C3AULL, - 0x917BDD64B1C0FD4CULL, 0x3BB454329B7624C8ULL, 0x23BA4442CAF53EA6ULL, - 0x4E677D2C38532A3AULL, 0x0BFD64B645036C7AULL, 0xC68A007E5E0DD902ULL, - 0x4DB5A851F44182E1ULL, 0x8EC9B55A7F88A46BULL, 0x0A8291CDCEC97DCFULL, - 0x2A4ECEA9F98D0ACCULL, 0x1A1DB93D7140003CULL, 0x092999A333CB8B7AULL, - 0x6DC778F971AD0038ULL, 0xA907600A918130C4ULL, 0xED6A1E012D9E6832ULL, - 0x7135C886EFB4318AULL, 0x87F55BA57E31CC7AULL, 0x7763CF1D55034004ULL, - 0xAC7D5F42D69F6D18ULL, 0x7930E9E4E58857B6ULL, 0x6E6F52C3164DF4FBULL, - 0x25E41D2B669E1EF1ULL, 0x3C1B20EE3FD59D7CULL, 0x0ABCD06BFA53DDEFULL, - 0x1DBF9A42D5C4484EULL, 0xABC521979B0DEADAULL, 0xE86D2BC522363A0DULL, - 0x5CAE82AB9C9DF69EULL, 0x64F2E21E71F54BFFULL, 0xF4FD4452E2D74DD3ULL, - 0xB4130C93BC437944ULL, 0xAEFE130985139270ULL, 0x598CB0FAC186D91CULL, - 0x7AD91D2691F7F7EEULL, 0x61B46FC9D6E6C907ULL, 0xBC34F4DEF99C0238ULL, - 0xDE355B3B6519035BULL, 0x886B4238611FCFDCULL, 0xC6F34A26C1B2EFFAULL, - 0xC58EF1837D1683B2ULL, 0x3BB5FCBC2EC22005ULL, 0xC3FE3B1B4C6FAD73ULL, - 0x8E4F1232EEF28183ULL, 0x9172FE9CE98583FFULL, 0xC03404CD28342F61ULL, - 0x9E02FCE1CDF7E2ECULL, 0x0B07A7C8EE0A6D70ULL, 0xAE56EDE76372BB19ULL, - 0x1D4F42A3DE394DF4ULL, 0xB96ADAB760D7F468ULL, 0xD108A94BB2C8E3FBULL, - 0xBC0AB182B324FB61ULL, 0x30ACCA4F483A797AULL, 0x1DF158A136ADE735ULL, - 0xE2A689DAF3EFE872ULL, 0x984F0C70E0E68B77ULL, 0xB557135E7F57C935ULL, - 0x856365553DED1AF3ULL, 0x2433F51F5F066ED0ULL, 0xD3DF1ED5D5FD6561ULL, - 0xF681B202AEC4617AULL, 0x7D2FE363630C75D8ULL, 0xCC939DCE249B3EF9ULL, - 0xA9E13641146433FBULL, 0xD8B9C583CE2D3695ULL, 0xAFDC5620273D3CF1ULL, - 0xADF85458A2BB4A9AULL, 0xFFFFFFFFFFFFFFFFULL +/* q = (p - 1) / 2 */ +static const BN_ULONG modp_8192_q[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xCC76E9EF, 0xB064C06E), + BN_DEF(0x405CB738, 0xE40FAB74), BN_DEF(0x3B2B4A6F, 0x4F182871), + BN_DEF(0xAB3BF4D5, 0xCAAC7223), BN_DEF(0x7E013723, 0xE48C86D3), + BN_DEF(0x6AF71C15, 0xC44D0017), BN_DEF(0xA40E366B, 0x2004A1C5), + BN_DEF(0x75C3CFC9, 0x1AC8237A), BN_DEF(0x8F67D134, 0xFD79B5E1), + BN_DEF(0xBF73A6B9, 0xD8EA885E), BN_DEF(0xAEF6BF50, 0xFCD5A40C), + BN_DEF(0x8423428E, 0xB2798E62), BN_DEF(0xD012AEE0, 0x22CBF44C), + BN_DEF(0x3A55B51B, 0xEF988770), BN_DEF(0x1FA27C16, 0x369509FC), + BN_DEF(0xD9D13C53, 0x03159E7A), BN_DEF(0xF6ADEE9D, 0x3CB41981), + BN_DEF(0xD16043F4, 0xFD4EA5BF), BN_DEF(0x17C1C2EE, 0xA5E5E443), + BN_DEF(0x36751835, 0x9A39FE32), BN_DEF(0x0D11F863, 0x89F5ABD4), + BN_DEF(0x5201BE03, 0x91111702), BN_DEF(0x7E42456C, 0xF1FEDC5F), + BN_DEF(0xF1CEB296, 0x11C78B65), BN_DEF(0x15F8E4BC, 0x1A11DA3A), + BN_DEF(0x2D727AB4, 0x1D55B1CE), BN_DEF(0xB5D21233, 0x92BB7B49), + BN_DEF(0xC57E23F6, 0x3A0FD3DF), BN_DEF(0x46CEE980, 0x1DE4195B), + BN_DEF(0x39DC98DD, 0x6C5F6268), BN_DEF(0x54996FC6, 0x1C3BBE5B), + BN_DEF(0x897F72F2, 0xBA51C937), BN_DEF(0x36DF08AC, 0x734A7C8F), + BN_DEF(0x85BA3A6B, 0x095F96AD), BN_DEF(0x1FA43077, 0x021F47B3), + BN_DEF(0xB71E0234, 0x1C3FF46B), BN_DEF(0x17794B19, 0x6D2B64F6), + BN_DEF(0xD189EAAE, 0x758CE658), BN_DEF(0xC50FDFF8, 0x7AA8551E), + BN_DEF(0xDBE2ED3B, 0x0350EAC5), BN_DEF(0x794DF194, 0x53CB8AF7), + BN_DEF(0x07C01BF0, 0x0A662F69), BN_DEF(0x5FA470EC, 0x6647B6BF), + BN_DEF(0x15A0AA55, 0xA5EA03D9), BN_DEF(0xFFAC2D62, 0x078EA2DB), + BN_DEF(0x1B66445F, 0x91D4BD3F), BN_DEF(0xDF63F479, 0x2CF3E4BF), + BN_DEF(0xC8058E4F, 0x5AD42018), BN_DEF(0xA34C0641, 0x6AAF3817), + BN_DEF(0x373A7F7B, 0xFA416BE7), BN_DEF(0xE8B90E81, 0x7819750A), + BN_DEF(0xE325C976, 0xACC1E500), BN_DEF(0x9BC6695F, 0x37DC7A00), + BN_DEF(0x95EBD7A1, 0x999028A8), BN_DEF(0xF36612A5, 0xEDBF8A23), + BN_DEF(0x676A5D8D, 0xA267365D), BN_DEF(0xE7CD8A76, 0x6D1F6DF5), + BN_DEF(0x432D448C, 0x8BCB93D8), BN_DEF(0xC813EC18, 0x583529F6), + BN_DEF(0xA09800D7, 0x72ED9C17), BN_DEF(0x56CF2987, 0xFC7FCA03), + BN_DEF(0x1EDD1BDE, 0x64BA8F3B), BN_DEF(0x3013236F, 0x60EA6E59), + BN_DEF(0x693E3813, 0x1B61FD5A), BN_DEF(0x9A014249, 0xA6FA1AE4), + BN_DEF(0x48536047, 0xC37FDBEE), BN_DEF(0x46C7EEE0, 0xC9DA754C), + BN_DEF(0xEAD82D54, 0x68034893), BN_DEF(0x10B8240E, 0xDC0DEEBB), + BN_DEF(0x67716BD7, 0x8FB094B8), BN_DEF(0x28ADF3F6, 0x119DD0C3), + BN_DEF(0xD04861D1, 0xCCD94B27), BN_DEF(0xA735E02E, 0x143E2CA3), + BN_DEF(0x0FDF6553, 0x97477E0A), BN_DEF(0x826F477C, 0x6DDDE16D), + BN_DEF(0x156A2674, 0x12C1F4E5), BN_DEF(0x5B0A85ED, 0x0D4A341A), + BN_DEF(0x357A711E, 0x4CE1938C), BN_DEF(0x5EDD2D93, 0xC438CD08), + BN_DEF(0x53C3F36B, 0x8D391E09), BN_DEF(0x54908400, 0x25C16890), + BN_DEF(0x707E8847, 0xA1EDADFE), BN_DEF(0x3A72D598, 0x047127D0), + BN_DEF(0x5D6CA371, 0x3B84C460), BN_DEF(0xBD30AEB6, 0x5DF08BAB), + BN_DEF(0x0BBD9006, 0x290F958C), BN_DEF(0x9F643532, 0x6C3B0139), + BN_DEF(0x6CC50432, 0xF897FD03), BN_DEF(0x0D697735, 0xE771E913), + BN_DEF(0x2512B0CE, 0x8F464A70), BN_DEF(0x6D8499EB, 0xD5FAD746), + BN_DEF(0xD370F263, 0xD9CB87C2), BN_DEF(0xAE83063E, 0x457538AB), + BN_DEF(0x2C6DF785, 0x767DC282), BN_DEF(0xEF8E5D32, 0xD42A90D5), + BN_DEF(0x82283D19, 0xD6998B86), BN_DEF(0x45556216, 0x0AB9472D), + BN_DEF(0x4C7D0288, 0x8AE9130C), BN_DEF(0x754AB572, 0x1CCAA4BE), + BN_DEF(0x4AAC0B8C, 0xEF15E5FB), BN_DEF(0x37A62964, 0xDAE2AEF8), + BN_DEF(0x7603D147, 0xCD93C1D1), BN_DEF(0x0C074301, 0xF1CF3B96), + BN_DEF(0x171B671D, 0x19482F23), BN_DEF(0x650C10BE, 0x78BA3604), + BN_DEF(0x255E4C02, 0xB3861AA7), BN_DEF(0xB84B4B36, 0xCF6A9483), + BN_DEF(0x1042A95D, 0x0E3179AB), BN_DEF(0xEE51D6CB, 0xC1B2AE91), + BN_DEF(0x7E9267AF, 0x348B1FD4), BN_DEF(0x0E2AE9CD, 0xCC6D241B), + BN_DEF(0x50B1DF82, 0xE1003E5C), BN_DEF(0xF6722D9E, 0x24943328), + BN_DEF(0xBE258FF3, 0xD74F9208), BN_DEF(0xAD44CFD2, 0xF71C35FD), + BN_DEF(0x7A035BF6, 0x85FFAE5B), BN_DEF(0xD31BF6B5, 0x7A262174), + BN_DEF(0x312F3F63, 0xF242DABB), BN_DEF(0xB6A8E122, 0xA7F09AB6), + BN_DEF(0xF92F8A1B, 0x98158536), BN_DEF(0xE69D218D, 0xF7CA8CD9), + BN_DEF(0xC71A026E, 0x28A5043C), BN_DEF(0x1D89CD91, 0x0105DF53), + BN_DEF(0x4533E63A, 0x94812704), BN_DEF(0xC06E0E68, 0x62633145), + BN_DEF(0x10B4611A, 0xE487ED51), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), }; -# elif BN_BITS2 == 32 - +/* DH parameters from RFC5114 */ static const BN_ULONG dh1024_160_p[] = { - 0x2E4A4371, 0xDF1FB2BC, 0x6D4DA708, 0xE68CFDA7, 0x365C1A65, 0x45BF37DF, - 0x0DC8B4BD, 0xA151AF5F, 0xF55BCCC0, 0xFAA31A4F, 0xE5644738, 0x4EFFD6FA, - 0x219A7372, 0x98488E9C, 0x90C4BD70, 0xACCBDD7D, 0xD49B83BF, 0x24975C3C, - 0xA9061123, 0x13ECB4AE, 0x2EE652C0, 0x9838EF1E, 0x75A23D18, 0x6073E286, - 0x52D23B61, 0x9A6A9DCA, 0xFB06A3C6, 0x52C99FBC, 0xAE5D54EC, 0xDE92DE5E, - 0xA080E01D, 0xB10B8F96 + BN_DEF(0x2E4A4371, 0xDF1FB2BC), BN_DEF(0x6D4DA708, 0xE68CFDA7), + BN_DEF(0x365C1A65, 0x45BF37DF), BN_DEF(0x0DC8B4BD, 0xA151AF5F), + BN_DEF(0xF55BCCC0, 0xFAA31A4F), BN_DEF(0xE5644738, 0x4EFFD6FA), + BN_DEF(0x219A7372, 0x98488E9C), BN_DEF(0x90C4BD70, 0xACCBDD7D), + BN_DEF(0xD49B83BF, 0x24975C3C), BN_DEF(0xA9061123, 0x13ECB4AE), + BN_DEF(0x2EE652C0, 0x9838EF1E), BN_DEF(0x75A23D18, 0x6073E286), + BN_DEF(0x52D23B61, 0x9A6A9DCA), BN_DEF(0xFB06A3C6, 0x52C99FBC), + BN_DEF(0xAE5D54EC, 0xDE92DE5E), BN_DEF(0xA080E01D, 0xB10B8F96) }; - -static const BN_ULONG dh1024_160_g[] = { - 0x22B3B2E5, 0x855E6EEB, 0xF97C2A24, 0x858F4DCE, 0x18D08BC8, 0x2D779D59, - 0x8E73AFA3, 0xD662A4D1, 0x69B6A28A, 0x1DBF0A01, 0x7A091F53, 0xA6A24C08, - 0x63F80A76, 0x909D0D22, 0xB9A92EE1, 0xD7FBD7D3, 0x9E2749F4, 0x5E91547F, - 0xB01B886A, 0x160217B4, 0x5504F213, 0x777E690F, 0x5C41564B, 0x266FEA1E, - 0x14266D31, 0xD6406CFF, 0x58AC507F, 0xF8104DD2, 0xEFB99905, 0x6765A442, - 0xC3FD3412, 0xA4D1CBD5 -}; - static const BN_ULONG dh1024_160_q[] = { - 0x49462353, 0x64B7CB9D, 0x8ABA4E7D, 0x81A8DF27, 0xF518AA87 + BN_DEF(0x49462353, 0x64B7CB9D), BN_DEF(0x8ABA4E7D, 0x81A8DF27), + (BN_ULONG)0xF518AA87 }; - -static const BN_ULONG dh2048_224_p[] = { - 0x0C10E64F, 0x0AC4DFFE, 0x4E71B81C, 0xCF9DE538, 0xFFA31F71, 0x7EF363E2, - 0x6B8E75B9, 0xE3FB73C1, 0x4BA80A29, 0xC9B53DCF, 0x16E79763, 0x23F10B0E, - 0x13042E9B, 0xC52172E4, 0xC928B2B9, 0xBE60E69C, 0xB9E587E8, 0x80CD86A1, - 0x98C641A4, 0x315D75E1, 0x44328387, 0xCDF93ACC, 0xDC0A486D, 0x15987D9A, - 0x1FD5A074, 0x7310F712, 0xDE31EFDC, 0x278273C7, 0x415D9330, 0x1602E714, - 0xBC8985DB, 0x81286130, 0x70918836, 0xB3BF8A31, 0xB9C49708, 0x6A00E0A0, - 0x8BBC27BE, 0xC6BA0B2C, 0xED34DBF6, 0xC9F98D11, 0xB6C12207, 0x7AD5B7D0, - 0x55B7394B, 0xD91E8FEF, 0xEFDA4DF8, 0x9037C9ED, 0xAD6AC212, 0x6D3F8152, - 0x1274A0A6, 0x1DE6B85A, 0x309C180E, 0xEB3D688A, 0x7BA1DF15, 0xAF9A3C40, - 0xF95A56DB, 0xE6FA141D, 0xB61D0A75, 0xB54B1597, 0x683B9FD1, 0xA20D64E5, - 0x9559C51F, 0xD660FAA7, 0x9123A9D0, 0xAD107E1E +static const BN_ULONG dh1024_160_g[] = { + BN_DEF(0x22B3B2E5, 0x855E6EEB), BN_DEF(0xF97C2A24, 0x858F4DCE), + BN_DEF(0x18D08BC8, 0x2D779D59), BN_DEF(0x8E73AFA3, 0xD662A4D1), + BN_DEF(0x69B6A28A, 0x1DBF0A01), BN_DEF(0x7A091F53, 0xA6A24C08), + BN_DEF(0x63F80A76, 0x909D0D22), BN_DEF(0xB9A92EE1, 0xD7FBD7D3), + BN_DEF(0x9E2749F4, 0x5E91547F), BN_DEF(0xB01B886A, 0x160217B4), + BN_DEF(0x5504F213, 0x777E690F), BN_DEF(0x5C41564B, 0x266FEA1E), + BN_DEF(0x14266D31, 0xD6406CFF), BN_DEF(0x58AC507F, 0xF8104DD2), + BN_DEF(0xEFB99905, 0x6765A442), BN_DEF(0xC3FD3412, 0xA4D1CBD5) }; -static const BN_ULONG dh2048_224_g[] = { - 0x191F2BFA, 0x84B890D3, 0x2A7065B3, 0x81BC087F, 0xF6EC0179, 0x19C418E1, - 0x71CFFF4C, 0x7B5A0F1C, 0x9B6AA4BD, 0xEDFE72FE, 0x94B30269, 0x81E1BCFE, - 0x8D6C0191, 0x566AFBB4, 0x409D13CD, 0xB539CCE3, 0x5F2FF381, 0x6AA21E7F, - 0x770589EF, 0xD9E263E4, 0xD19963DD, 0x10E183ED, 0x150B8EEB, 0xB70A8137, - 0x28C8F8AC, 0x051AE3D4, 0x0C1AB15B, 0xBB77A86F, 0x16A330EF, 0x6E3025E3, - 0xD6F83456, 0x19529A45, 0x118E98D1, 0xF180EB34, 0x50717CBE, 0xB5F6C6B2, - 0xDA7460CD, 0x09939D54, 0x22EA1ED4, 0xE2471504, 0x521BC98A, 0xB8A762D0, - 0x5AC1348B, 0xF4D02727, 0x1999024A, 0xC1766910, 0xA8D66AD7, 0xBE5E9001, - 0x620A8652, 0xC57DB17C, 0x00C29F52, 0xAB739D77, 0xA70C4AFA, 0xDD921F01, - 0x10B9A6F0, 0xA6824A4E, 0xCFE4FFE3, 0x74866A08, 0x89998CAF, 0x6CDEBE7B, - 0x8FFDAC50, 0x9DF30B5C, 0x4F2D9AE3, 0xAC4032EF +static const BN_ULONG dh2048_224_p[] = { + BN_DEF(0x0C10E64F, 0x0AC4DFFE), BN_DEF(0x4E71B81C, 0xCF9DE538), + BN_DEF(0xFFA31F71, 0x7EF363E2), BN_DEF(0x6B8E75B9, 0xE3FB73C1), + BN_DEF(0x4BA80A29, 0xC9B53DCF), BN_DEF(0x16E79763, 0x23F10B0E), + BN_DEF(0x13042E9B, 0xC52172E4), BN_DEF(0xC928B2B9, 0xBE60E69C), + BN_DEF(0xB9E587E8, 0x80CD86A1), BN_DEF(0x98C641A4, 0x315D75E1), + BN_DEF(0x44328387, 0xCDF93ACC), BN_DEF(0xDC0A486D, 0x15987D9A), + BN_DEF(0x1FD5A074, 0x7310F712), BN_DEF(0xDE31EFDC, 0x278273C7), + BN_DEF(0x415D9330, 0x1602E714), BN_DEF(0xBC8985DB, 0x81286130), + BN_DEF(0x70918836, 0xB3BF8A31), BN_DEF(0xB9C49708, 0x6A00E0A0), + BN_DEF(0x8BBC27BE, 0xC6BA0B2C), BN_DEF(0xED34DBF6, 0xC9F98D11), + BN_DEF(0xB6C12207, 0x7AD5B7D0), BN_DEF(0x55B7394B, 0xD91E8FEF), + BN_DEF(0xEFDA4DF8, 0x9037C9ED), BN_DEF(0xAD6AC212, 0x6D3F8152), + BN_DEF(0x1274A0A6, 0x1DE6B85A), BN_DEF(0x309C180E, 0xEB3D688A), + BN_DEF(0x7BA1DF15, 0xAF9A3C40), BN_DEF(0xF95A56DB, 0xE6FA141D), + BN_DEF(0xB61D0A75, 0xB54B1597), BN_DEF(0x683B9FD1, 0xA20D64E5), + BN_DEF(0x9559C51F, 0xD660FAA7), BN_DEF(0x9123A9D0, 0xAD107E1E) }; - static const BN_ULONG dh2048_224_q[] = { - 0xB36371EB, 0xBF389A99, 0x4738CEBC, 0x1F80535A, 0x99717710, 0xC58D93FE, - 0x801C0D34 + BN_DEF(0xB36371EB, 0xBF389A99), BN_DEF(0x4738CEBC, 0x1F80535A), + BN_DEF(0x99717710, 0xC58D93FE), (BN_ULONG)0x801C0D34 }; - -static const BN_ULONG dh2048_256_p[] = { - 0x1E1A1597, 0xDB094AE9, 0xD7EF09CA, 0x693877FA, 0x6E11715F, 0x6116D227, - 0xC198AF12, 0xA4B54330, 0xD7014103, 0x75F26375, 0x54E710C3, 0xC3A3960A, - 0xBD0BE621, 0xDED4010A, 0x89962856, 0xC0B857F6, 0x71506026, 0xB3CA3F79, - 0xE6B486F6, 0x1CCACB83, 0x14056425, 0x67E144E5, 0xA41825D9, 0xF6A167B5, - 0x96524D8E, 0x3AD83477, 0x51BFA4AB, 0xF13C6D9A, 0x35488A0E, 0x2D525267, - 0xCAA6B790, 0xB63ACAE1, 0x81B23F76, 0x4FDB70C5, 0x12307F5C, 0xBC39A0BF, - 0xB1E59BB8, 0xB941F54E, 0xD45F9088, 0x6C5BFC11, 0x4275BF7B, 0x22E0B1EF, - 0x5B4758C0, 0x91F9E672, 0x6BCF67ED, 0x5A8A9D30, 0x97517ABD, 0x209E0C64, - 0x830E9A7C, 0x3BF4296D, 0x34096FAA, 0x16C3D911, 0x61B2AA30, 0xFAF7DF45, - 0xD61957D4, 0xE00DF8F1, 0x435E3B00, 0x5D2CEED4, 0x660DD0F2, 0x8CEEF608, - 0x65195999, 0xFFBBD19C, 0xB4B6663C, 0x87A8E61D +static const BN_ULONG dh2048_224_g[] = { + BN_DEF(0x191F2BFA, 0x84B890D3), BN_DEF(0x2A7065B3, 0x81BC087F), + BN_DEF(0xF6EC0179, 0x19C418E1), BN_DEF(0x71CFFF4C, 0x7B5A0F1C), + BN_DEF(0x9B6AA4BD, 0xEDFE72FE), BN_DEF(0x94B30269, 0x81E1BCFE), + BN_DEF(0x8D6C0191, 0x566AFBB4), BN_DEF(0x409D13CD, 0xB539CCE3), + BN_DEF(0x5F2FF381, 0x6AA21E7F), BN_DEF(0x770589EF, 0xD9E263E4), + BN_DEF(0xD19963DD, 0x10E183ED), BN_DEF(0x150B8EEB, 0xB70A8137), + BN_DEF(0x28C8F8AC, 0x051AE3D4), BN_DEF(0x0C1AB15B, 0xBB77A86F), + BN_DEF(0x16A330EF, 0x6E3025E3), BN_DEF(0xD6F83456, 0x19529A45), + BN_DEF(0x118E98D1, 0xF180EB34), BN_DEF(0x50717CBE, 0xB5F6C6B2), + BN_DEF(0xDA7460CD, 0x09939D54), BN_DEF(0x22EA1ED4, 0xE2471504), + BN_DEF(0x521BC98A, 0xB8A762D0), BN_DEF(0x5AC1348B, 0xF4D02727), + BN_DEF(0x1999024A, 0xC1766910), BN_DEF(0xA8D66AD7, 0xBE5E9001), + BN_DEF(0x620A8652, 0xC57DB17C), BN_DEF(0x00C29F52, 0xAB739D77), + BN_DEF(0xA70C4AFA, 0xDD921F01), BN_DEF(0x10B9A6F0, 0xA6824A4E), + BN_DEF(0xCFE4FFE3, 0x74866A08), BN_DEF(0x89998CAF, 0x6CDEBE7B), + BN_DEF(0x8FFDAC50, 0x9DF30B5C), BN_DEF(0x4F2D9AE3, 0xAC4032EF) }; -static const BN_ULONG dh2048_256_g[] = { - 0x6CC41659, 0x664B4C0F, 0xEF98C582, 0x5E2327CF, 0xD4795451, 0xD647D148, - 0x90F00EF8, 0x2F630784, 0x1DB246C3, 0x184B523D, 0xCDC67EB6, 0xC7891428, - 0x0DF92B52, 0x7FD02837, 0x64E0EC37, 0xB3353BBB, 0x57CD0915, 0xECD06E15, - 0xDF016199, 0xB7D2BBD2, 0x052588B9, 0xC8484B1E, 0x13D3FE14, 0xDB2A3B73, - 0xD182EA0A, 0xD052B985, 0xE83B9C80, 0xA4BD1BFF, 0xFB3F2E55, 0xDFC967C1, - 0x767164E1, 0xB5045AF2, 0x6F2F9193, 0x1D14348F, 0x428EBC83, 0x64E67982, - 0x82D6ED38, 0x8AC376D2, 0xAAB8A862, 0x777DE62A, 0xE9EC144B, 0xDDF463E5, - 0xC77A57F2, 0x0196F931, 0x41000A65, 0xA55AE313, 0xC28CBB18, 0x901228F8, - 0x7E8C6F62, 0xBC3773BF, 0x0C6B47B1, 0xBE3A6C1B, 0xAC0BB555, 0xFF4FED4A, - 0x77BE463F, 0x10DBC150, 0x1A0BA125, 0x07F4793A, 0x21EF2054, 0x4CA7B18F, - 0x60EDBD48, 0x2E775066, 0x73134D0B, 0x3FB32C9B +static const BN_ULONG dh2048_256_p[] = { + BN_DEF(0x1E1A1597, 0xDB094AE9), BN_DEF(0xD7EF09CA, 0x693877FA), + BN_DEF(0x6E11715F, 0x6116D227), BN_DEF(0xC198AF12, 0xA4B54330), + BN_DEF(0xD7014103, 0x75F26375), BN_DEF(0x54E710C3, 0xC3A3960A), + BN_DEF(0xBD0BE621, 0xDED4010A), BN_DEF(0x89962856, 0xC0B857F6), + BN_DEF(0x71506026, 0xB3CA3F79), BN_DEF(0xE6B486F6, 0x1CCACB83), + BN_DEF(0x14056425, 0x67E144E5), BN_DEF(0xA41825D9, 0xF6A167B5), + BN_DEF(0x96524D8E, 0x3AD83477), BN_DEF(0x51BFA4AB, 0xF13C6D9A), + BN_DEF(0x35488A0E, 0x2D525267), BN_DEF(0xCAA6B790, 0xB63ACAE1), + BN_DEF(0x81B23F76, 0x4FDB70C5), BN_DEF(0x12307F5C, 0xBC39A0BF), + BN_DEF(0xB1E59BB8, 0xB941F54E), BN_DEF(0xD45F9088, 0x6C5BFC11), + BN_DEF(0x4275BF7B, 0x22E0B1EF), BN_DEF(0x5B4758C0, 0x91F9E672), + BN_DEF(0x6BCF67ED, 0x5A8A9D30), BN_DEF(0x97517ABD, 0x209E0C64), + BN_DEF(0x830E9A7C, 0x3BF4296D), BN_DEF(0x34096FAA, 0x16C3D911), + BN_DEF(0x61B2AA30, 0xFAF7DF45), BN_DEF(0xD61957D4, 0xE00DF8F1), + BN_DEF(0x435E3B00, 0x5D2CEED4), BN_DEF(0x660DD0F2, 0x8CEEF608), + BN_DEF(0x65195999, 0xFFBBD19C), BN_DEF(0xB4B6663C, 0x87A8E61D) }; - static const BN_ULONG dh2048_256_q[] = { - 0x64F5FBD3, 0xA308B0FE, 0x1EB3750B, 0x99B1A47D, 0x40129DA2, 0xB4479976, - 0xA709A097, 0x8CF83642 + BN_DEF(0x64F5FBD3, 0xA308B0FE), BN_DEF(0x1EB3750B, 0x99B1A47D), + BN_DEF(0x40129DA2, 0xB4479976), BN_DEF(0xA709A097, 0x8CF83642) +}; +static const BN_ULONG dh2048_256_g[] = { + BN_DEF(0x6CC41659, 0x664B4C0F), BN_DEF(0xEF98C582, 0x5E2327CF), + BN_DEF(0xD4795451, 0xD647D148), BN_DEF(0x90F00EF8, 0x2F630784), + BN_DEF(0x1DB246C3, 0x184B523D), BN_DEF(0xCDC67EB6, 0xC7891428), + BN_DEF(0x0DF92B52, 0x7FD02837), BN_DEF(0x64E0EC37, 0xB3353BBB), + BN_DEF(0x57CD0915, 0xECD06E15), BN_DEF(0xDF016199, 0xB7D2BBD2), + BN_DEF(0x052588B9, 0xC8484B1E), BN_DEF(0x13D3FE14, 0xDB2A3B73), + BN_DEF(0xD182EA0A, 0xD052B985), BN_DEF(0xE83B9C80, 0xA4BD1BFF), + BN_DEF(0xFB3F2E55, 0xDFC967C1), BN_DEF(0x767164E1, 0xB5045AF2), + BN_DEF(0x6F2F9193, 0x1D14348F), BN_DEF(0x428EBC83, 0x64E67982), + BN_DEF(0x82D6ED38, 0x8AC376D2), BN_DEF(0xAAB8A862, 0x777DE62A), + BN_DEF(0xE9EC144B, 0xDDF463E5), BN_DEF(0xC77A57F2, 0x0196F931), + BN_DEF(0x41000A65, 0xA55AE313), BN_DEF(0xC28CBB18, 0x901228F8), + BN_DEF(0x7E8C6F62, 0xBC3773BF), BN_DEF(0x0C6B47B1, 0xBE3A6C1B), + BN_DEF(0xAC0BB555, 0xFF4FED4A), BN_DEF(0x77BE463F, 0x10DBC150), + BN_DEF(0x1A0BA125, 0x07F4793A), BN_DEF(0x21EF2054, 0x4CA7B18F), + BN_DEF(0x60EDBD48, 0x2E775066), BN_DEF(0x73134D0B, 0x3FB32C9B) }; /* Primes from RFC 7919 */ - static const BN_ULONG ffdhe2048_p[] = { - 0xFFFFFFFF, 0xFFFFFFFF, 0x61285C97, 0x886B4238, 0xC1B2EFFA, 0xC6F34A26, - 0x7D1683B2, 0xC58EF183, 0x2EC22005, 0x3BB5FCBC, 0x4C6FAD73, 0xC3FE3B1B, - 0xEEF28183, 0x8E4F1232, 0xE98583FF, 0x9172FE9C, 0x28342F61, 0xC03404CD, - 0xCDF7E2EC, 0x9E02FCE1, 0xEE0A6D70, 0x0B07A7C8, 0x6372BB19, 0xAE56EDE7, - 0xDE394DF4, 0x1D4F42A3, 0x60D7F468, 0xB96ADAB7, 0xB2C8E3FB, 0xD108A94B, - 0xB324FB61, 0xBC0AB182, 0x483A797A, 0x30ACCA4F, 0x36ADE735, 0x1DF158A1, - 0xF3EFE872, 0xE2A689DA, 0xE0E68B77, 0x984F0C70, 0x7F57C935, 0xB557135E, - 0x3DED1AF3, 0x85636555, 0x5F066ED0, 0x2433F51F, 0xD5FD6561, 0xD3DF1ED5, - 0xAEC4617A, 0xF681B202, 0x630C75D8, 0x7D2FE363, 0x249B3EF9, 0xCC939DCE, - 0x146433FB, 0xA9E13641, 0xCE2D3695, 0xD8B9C583, 0x273D3CF1, 0xAFDC5620, - 0xA2BB4A9A, 0xADF85458, 0xFFFFFFFF, 0xFFFFFFFF + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x61285C97, 0x886B4238), + BN_DEF(0xC1B2EFFA, 0xC6F34A26), BN_DEF(0x7D1683B2, 0xC58EF183), + BN_DEF(0x2EC22005, 0x3BB5FCBC), BN_DEF(0x4C6FAD73, 0xC3FE3B1B), + BN_DEF(0xEEF28183, 0x8E4F1232), BN_DEF(0xE98583FF, 0x9172FE9C), + BN_DEF(0x28342F61, 0xC03404CD), BN_DEF(0xCDF7E2EC, 0x9E02FCE1), + BN_DEF(0xEE0A6D70, 0x0B07A7C8), BN_DEF(0x6372BB19, 0xAE56EDE7), + BN_DEF(0xDE394DF4, 0x1D4F42A3), BN_DEF(0x60D7F468, 0xB96ADAB7), + BN_DEF(0xB2C8E3FB, 0xD108A94B), BN_DEF(0xB324FB61, 0xBC0AB182), + BN_DEF(0x483A797A, 0x30ACCA4F), BN_DEF(0x36ADE735, 0x1DF158A1), + BN_DEF(0xF3EFE872, 0xE2A689DA), BN_DEF(0xE0E68B77, 0x984F0C70), + BN_DEF(0x7F57C935, 0xB557135E), BN_DEF(0x3DED1AF3, 0x85636555), + BN_DEF(0x5F066ED0, 0x2433F51F), BN_DEF(0xD5FD6561, 0xD3DF1ED5), + BN_DEF(0xAEC4617A, 0xF681B202), BN_DEF(0x630C75D8, 0x7D2FE363), + BN_DEF(0x249B3EF9, 0xCC939DCE), BN_DEF(0x146433FB, 0xA9E13641), + BN_DEF(0xCE2D3695, 0xD8B9C583), BN_DEF(0x273D3CF1, 0xAFDC5620), + BN_DEF(0xA2BB4A9A, 0xADF85458), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; +/* q = (p - 1) / 2 */ +static const BN_ULONG ffdhe2048_q[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x30942E4B, 0x4435A11C), + BN_DEF(0x60D977FD, 0x6379A513), BN_DEF(0xBE8B41D9, 0xE2C778C1), + BN_DEF(0x17611002, 0x9DDAFE5E), BN_DEF(0xA637D6B9, 0xE1FF1D8D), + BN_DEF(0x777940C1, 0xC7278919), BN_DEF(0x74C2C1FF, 0xC8B97F4E), + BN_DEF(0x941A17B0, 0x601A0266), BN_DEF(0xE6FBF176, 0x4F017E70), + BN_DEF(0x770536B8, 0x8583D3E4), BN_DEF(0xB1B95D8C, 0x572B76F3), + BN_DEF(0xEF1CA6FA, 0x0EA7A151), BN_DEF(0xB06BFA34, 0xDCB56D5B), + BN_DEF(0xD96471FD, 0xE88454A5), BN_DEF(0x59927DB0, 0x5E0558C1), + BN_DEF(0xA41D3CBD, 0x98566527), BN_DEF(0x9B56F39A, 0x0EF8AC50), + BN_DEF(0x79F7F439, 0xF15344ED), BN_DEF(0x707345BB, 0xCC278638), + BN_DEF(0x3FABE49A, 0xDAAB89AF), BN_DEF(0x9EF68D79, 0x42B1B2AA), + BN_DEF(0xAF833768, 0x9219FA8F), BN_DEF(0xEAFEB2B0, 0x69EF8F6A), + BN_DEF(0x576230BD, 0x7B40D901), BN_DEF(0xB1863AEC, 0xBE97F1B1), + BN_DEF(0x124D9F7C, 0xE649CEE7), BN_DEF(0x8A3219FD, 0xD4F09B20), + BN_DEF(0xE7169B4A, 0xEC5CE2C1), BN_DEF(0x139E9E78, 0x57EE2B10), + BN_DEF(0x515DA54D, 0xD6FC2A2C), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), }; static const BN_ULONG ffdhe3072_p[] = { - 0xFFFFFFFF, 0xFFFFFFFF, 0x66C62E37, 0x25E41D2B, 0x3FD59D7C, 0x3C1B20EE, - 0xFA53DDEF, 0x0ABCD06B, 0xD5C4484E, 0x1DBF9A42, 0x9B0DEADA, 0xABC52197, - 0x22363A0D, 0xE86D2BC5, 0x9C9DF69E, 0x5CAE82AB, 0x71F54BFF, 0x64F2E21E, - 0xE2D74DD3, 0xF4FD4452, 0xBC437944, 0xB4130C93, 0x85139270, 0xAEFE1309, - 0xC186D91C, 0x598CB0FA, 0x91F7F7EE, 0x7AD91D26, 0xD6E6C907, 0x61B46FC9, - 0xF99C0238, 0xBC34F4DE, 0x6519035B, 0xDE355B3B, 0x611FCFDC, 0x886B4238, - 0xC1B2EFFA, 0xC6F34A26, 0x7D1683B2, 0xC58EF183, 0x2EC22005, 0x3BB5FCBC, - 0x4C6FAD73, 0xC3FE3B1B, 0xEEF28183, 0x8E4F1232, 0xE98583FF, 0x9172FE9C, - 0x28342F61, 0xC03404CD, 0xCDF7E2EC, 0x9E02FCE1, 0xEE0A6D70, 0x0B07A7C8, - 0x6372BB19, 0xAE56EDE7, 0xDE394DF4, 0x1D4F42A3, 0x60D7F468, 0xB96ADAB7, - 0xB2C8E3FB, 0xD108A94B, 0xB324FB61, 0xBC0AB182, 0x483A797A, 0x30ACCA4F, - 0x36ADE735, 0x1DF158A1, 0xF3EFE872, 0xE2A689DA, 0xE0E68B77, 0x984F0C70, - 0x7F57C935, 0xB557135E, 0x3DED1AF3, 0x85636555, 0x5F066ED0, 0x2433F51F, - 0xD5FD6561, 0xD3DF1ED5, 0xAEC4617A, 0xF681B202, 0x630C75D8, 0x7D2FE363, - 0x249B3EF9, 0xCC939DCE, 0x146433FB, 0xA9E13641, 0xCE2D3695, 0xD8B9C583, - 0x273D3CF1, 0xAFDC5620, 0xA2BB4A9A, 0xADF85458, 0xFFFFFFFF, 0xFFFFFFFF + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x66C62E37, 0x25E41D2B), + BN_DEF(0x3FD59D7C, 0x3C1B20EE), BN_DEF(0xFA53DDEF, 0x0ABCD06B), + BN_DEF(0xD5C4484E, 0x1DBF9A42), BN_DEF(0x9B0DEADA, 0xABC52197), + BN_DEF(0x22363A0D, 0xE86D2BC5), BN_DEF(0x9C9DF69E, 0x5CAE82AB), + BN_DEF(0x71F54BFF, 0x64F2E21E), BN_DEF(0xE2D74DD3, 0xF4FD4452), + BN_DEF(0xBC437944, 0xB4130C93), BN_DEF(0x85139270, 0xAEFE1309), + BN_DEF(0xC186D91C, 0x598CB0FA), BN_DEF(0x91F7F7EE, 0x7AD91D26), + BN_DEF(0xD6E6C907, 0x61B46FC9), BN_DEF(0xF99C0238, 0xBC34F4DE), + BN_DEF(0x6519035B, 0xDE355B3B), BN_DEF(0x611FCFDC, 0x886B4238), + BN_DEF(0xC1B2EFFA, 0xC6F34A26), BN_DEF(0x7D1683B2, 0xC58EF183), + BN_DEF(0x2EC22005, 0x3BB5FCBC), BN_DEF(0x4C6FAD73, 0xC3FE3B1B), + BN_DEF(0xEEF28183, 0x8E4F1232), BN_DEF(0xE98583FF, 0x9172FE9C), + BN_DEF(0x28342F61, 0xC03404CD), BN_DEF(0xCDF7E2EC, 0x9E02FCE1), + BN_DEF(0xEE0A6D70, 0x0B07A7C8), BN_DEF(0x6372BB19, 0xAE56EDE7), + BN_DEF(0xDE394DF4, 0x1D4F42A3), BN_DEF(0x60D7F468, 0xB96ADAB7), + BN_DEF(0xB2C8E3FB, 0xD108A94B), BN_DEF(0xB324FB61, 0xBC0AB182), + BN_DEF(0x483A797A, 0x30ACCA4F), BN_DEF(0x36ADE735, 0x1DF158A1), + BN_DEF(0xF3EFE872, 0xE2A689DA), BN_DEF(0xE0E68B77, 0x984F0C70), + BN_DEF(0x7F57C935, 0xB557135E), BN_DEF(0x3DED1AF3, 0x85636555), + BN_DEF(0x5F066ED0, 0x2433F51F), BN_DEF(0xD5FD6561, 0xD3DF1ED5), + BN_DEF(0xAEC4617A, 0xF681B202), BN_DEF(0x630C75D8, 0x7D2FE363), + BN_DEF(0x249B3EF9, 0xCC939DCE), BN_DEF(0x146433FB, 0xA9E13641), + BN_DEF(0xCE2D3695, 0xD8B9C583), BN_DEF(0x273D3CF1, 0xAFDC5620), + BN_DEF(0xA2BB4A9A, 0xADF85458), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; +/* q = (p - 1) / 2 */ +static const BN_ULONG ffdhe3072_q[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xB363171B, 0x12F20E95), + BN_DEF(0x1FEACEBE, 0x9E0D9077), BN_DEF(0xFD29EEF7, 0x055E6835), + BN_DEF(0x6AE22427, 0x0EDFCD21), BN_DEF(0xCD86F56D, 0xD5E290CB), + BN_DEF(0x911B1D06, 0x743695E2), BN_DEF(0xCE4EFB4F, 0xAE574155), + BN_DEF(0x38FAA5FF, 0xB279710F), BN_DEF(0x716BA6E9, 0x7A7EA229), + BN_DEF(0xDE21BCA2, 0x5A098649), BN_DEF(0xC289C938, 0x577F0984), + BN_DEF(0x60C36C8E, 0x2CC6587D), BN_DEF(0x48FBFBF7, 0xBD6C8E93), + BN_DEF(0xEB736483, 0x30DA37E4), BN_DEF(0x7CCE011C, 0xDE1A7A6F), + BN_DEF(0xB28C81AD, 0x6F1AAD9D), BN_DEF(0x308FE7EE, 0x4435A11C), + BN_DEF(0x60D977FD, 0x6379A513), BN_DEF(0xBE8B41D9, 0xE2C778C1), + BN_DEF(0x17611002, 0x9DDAFE5E), BN_DEF(0xA637D6B9, 0xE1FF1D8D), + BN_DEF(0x777940C1, 0xC7278919), BN_DEF(0x74C2C1FF, 0xC8B97F4E), + BN_DEF(0x941A17B0, 0x601A0266), BN_DEF(0xE6FBF176, 0x4F017E70), + BN_DEF(0x770536B8, 0x8583D3E4), BN_DEF(0xB1B95D8C, 0x572B76F3), + BN_DEF(0xEF1CA6FA, 0x0EA7A151), BN_DEF(0xB06BFA34, 0xDCB56D5B), + BN_DEF(0xD96471FD, 0xE88454A5), BN_DEF(0x59927DB0, 0x5E0558C1), + BN_DEF(0xA41D3CBD, 0x98566527), BN_DEF(0x9B56F39A, 0x0EF8AC50), + BN_DEF(0x79F7F439, 0xF15344ED), BN_DEF(0x707345BB, 0xCC278638), + BN_DEF(0x3FABE49A, 0xDAAB89AF), BN_DEF(0x9EF68D79, 0x42B1B2AA), + BN_DEF(0xAF833768, 0x9219FA8F), BN_DEF(0xEAFEB2B0, 0x69EF8F6A), + BN_DEF(0x576230BD, 0x7B40D901), BN_DEF(0xB1863AEC, 0xBE97F1B1), + BN_DEF(0x124D9F7C, 0xE649CEE7), BN_DEF(0x8A3219FD, 0xD4F09B20), + BN_DEF(0xE7169B4A, 0xEC5CE2C1), BN_DEF(0x139E9E78, 0x57EE2B10), + BN_DEF(0x515DA54D, 0xD6FC2A2C), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), }; static const BN_ULONG ffdhe4096_p[] = { - 0xFFFFFFFF, 0xFFFFFFFF, 0x5E655F6A, 0xC68A007E, 0xF44182E1, 0x4DB5A851, - 0x7F88A46B, 0x8EC9B55A, 0xCEC97DCF, 0x0A8291CD, 0xF98D0ACC, 0x2A4ECEA9, - 0x7140003C, 0x1A1DB93D, 0x33CB8B7A, 0x092999A3, 0x71AD0038, 0x6DC778F9, - 0x918130C4, 0xA907600A, 0x2D9E6832, 0xED6A1E01, 0xEFB4318A, 0x7135C886, - 0x7E31CC7A, 0x87F55BA5, 0x55034004, 0x7763CF1D, 0xD69F6D18, 0xAC7D5F42, - 0xE58857B6, 0x7930E9E4, 0x164DF4FB, 0x6E6F52C3, 0x669E1EF1, 0x25E41D2B, - 0x3FD59D7C, 0x3C1B20EE, 0xFA53DDEF, 0x0ABCD06B, 0xD5C4484E, 0x1DBF9A42, - 0x9B0DEADA, 0xABC52197, 0x22363A0D, 0xE86D2BC5, 0x9C9DF69E, 0x5CAE82AB, - 0x71F54BFF, 0x64F2E21E, 0xE2D74DD3, 0xF4FD4452, 0xBC437944, 0xB4130C93, - 0x85139270, 0xAEFE1309, 0xC186D91C, 0x598CB0FA, 0x91F7F7EE, 0x7AD91D26, - 0xD6E6C907, 0x61B46FC9, 0xF99C0238, 0xBC34F4DE, 0x6519035B, 0xDE355B3B, - 0x611FCFDC, 0x886B4238, 0xC1B2EFFA, 0xC6F34A26, 0x7D1683B2, 0xC58EF183, - 0x2EC22005, 0x3BB5FCBC, 0x4C6FAD73, 0xC3FE3B1B, 0xEEF28183, 0x8E4F1232, - 0xE98583FF, 0x9172FE9C, 0x28342F61, 0xC03404CD, 0xCDF7E2EC, 0x9E02FCE1, - 0xEE0A6D70, 0x0B07A7C8, 0x6372BB19, 0xAE56EDE7, 0xDE394DF4, 0x1D4F42A3, - 0x60D7F468, 0xB96ADAB7, 0xB2C8E3FB, 0xD108A94B, 0xB324FB61, 0xBC0AB182, - 0x483A797A, 0x30ACCA4F, 0x36ADE735, 0x1DF158A1, 0xF3EFE872, 0xE2A689DA, - 0xE0E68B77, 0x984F0C70, 0x7F57C935, 0xB557135E, 0x3DED1AF3, 0x85636555, - 0x5F066ED0, 0x2433F51F, 0xD5FD6561, 0xD3DF1ED5, 0xAEC4617A, 0xF681B202, - 0x630C75D8, 0x7D2FE363, 0x249B3EF9, 0xCC939DCE, 0x146433FB, 0xA9E13641, - 0xCE2D3695, 0xD8B9C583, 0x273D3CF1, 0xAFDC5620, 0xA2BB4A9A, 0xADF85458, - 0xFFFFFFFF, 0xFFFFFFFF + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x5E655F6A, 0xC68A007E), + BN_DEF(0xF44182E1, 0x4DB5A851), BN_DEF(0x7F88A46B, 0x8EC9B55A), + BN_DEF(0xCEC97DCF, 0x0A8291CD), BN_DEF(0xF98D0ACC, 0x2A4ECEA9), + BN_DEF(0x7140003C, 0x1A1DB93D), BN_DEF(0x33CB8B7A, 0x092999A3), + BN_DEF(0x71AD0038, 0x6DC778F9), BN_DEF(0x918130C4, 0xA907600A), + BN_DEF(0x2D9E6832, 0xED6A1E01), BN_DEF(0xEFB4318A, 0x7135C886), + BN_DEF(0x7E31CC7A, 0x87F55BA5), BN_DEF(0x55034004, 0x7763CF1D), + BN_DEF(0xD69F6D18, 0xAC7D5F42), BN_DEF(0xE58857B6, 0x7930E9E4), + BN_DEF(0x164DF4FB, 0x6E6F52C3), BN_DEF(0x669E1EF1, 0x25E41D2B), + BN_DEF(0x3FD59D7C, 0x3C1B20EE), BN_DEF(0xFA53DDEF, 0x0ABCD06B), + BN_DEF(0xD5C4484E, 0x1DBF9A42), BN_DEF(0x9B0DEADA, 0xABC52197), + BN_DEF(0x22363A0D, 0xE86D2BC5), BN_DEF(0x9C9DF69E, 0x5CAE82AB), + BN_DEF(0x71F54BFF, 0x64F2E21E), BN_DEF(0xE2D74DD3, 0xF4FD4452), + BN_DEF(0xBC437944, 0xB4130C93), BN_DEF(0x85139270, 0xAEFE1309), + BN_DEF(0xC186D91C, 0x598CB0FA), BN_DEF(0x91F7F7EE, 0x7AD91D26), + BN_DEF(0xD6E6C907, 0x61B46FC9), BN_DEF(0xF99C0238, 0xBC34F4DE), + BN_DEF(0x6519035B, 0xDE355B3B), BN_DEF(0x611FCFDC, 0x886B4238), + BN_DEF(0xC1B2EFFA, 0xC6F34A26), BN_DEF(0x7D1683B2, 0xC58EF183), + BN_DEF(0x2EC22005, 0x3BB5FCBC), BN_DEF(0x4C6FAD73, 0xC3FE3B1B), + BN_DEF(0xEEF28183, 0x8E4F1232), BN_DEF(0xE98583FF, 0x9172FE9C), + BN_DEF(0x28342F61, 0xC03404CD), BN_DEF(0xCDF7E2EC, 0x9E02FCE1), + BN_DEF(0xEE0A6D70, 0x0B07A7C8), BN_DEF(0x6372BB19, 0xAE56EDE7), + BN_DEF(0xDE394DF4, 0x1D4F42A3), BN_DEF(0x60D7F468, 0xB96ADAB7), + BN_DEF(0xB2C8E3FB, 0xD108A94B), BN_DEF(0xB324FB61, 0xBC0AB182), + BN_DEF(0x483A797A, 0x30ACCA4F), BN_DEF(0x36ADE735, 0x1DF158A1), + BN_DEF(0xF3EFE872, 0xE2A689DA), BN_DEF(0xE0E68B77, 0x984F0C70), + BN_DEF(0x7F57C935, 0xB557135E), BN_DEF(0x3DED1AF3, 0x85636555), + BN_DEF(0x5F066ED0, 0x2433F51F), BN_DEF(0xD5FD6561, 0xD3DF1ED5), + BN_DEF(0xAEC4617A, 0xF681B202), BN_DEF(0x630C75D8, 0x7D2FE363), + BN_DEF(0x249B3EF9, 0xCC939DCE), BN_DEF(0x146433FB, 0xA9E13641), + BN_DEF(0xCE2D3695, 0xD8B9C583), BN_DEF(0x273D3CF1, 0xAFDC5620), + BN_DEF(0xA2BB4A9A, 0xADF85458), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; +/* q = (p - 1) / 2 */ +static const BN_ULONG ffdhe4096_q[] = { + BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), BN_DEF(0x2F32AFB5, 0xE345003F), + BN_DEF(0xFA20C170, 0xA6DAD428), BN_DEF(0x3FC45235, 0xC764DAAD), + BN_DEF(0xE764BEE7, 0x054148E6), BN_DEF(0xFCC68566, 0x15276754), + BN_DEF(0xB8A0001E, 0x0D0EDC9E), BN_DEF(0x99E5C5BD, 0x0494CCD1), + BN_DEF(0xB8D6801C, 0x36E3BC7C), BN_DEF(0x48C09862, 0x5483B005), + BN_DEF(0x96CF3419, 0x76B50F00), BN_DEF(0x77DA18C5, 0x389AE443), + BN_DEF(0xBF18E63D, 0x43FAADD2), BN_DEF(0xAA81A002, 0x3BB1E78E), + BN_DEF(0x6B4FB68C, 0x563EAFA1), BN_DEF(0x72C42BDB, 0xBC9874F2), + BN_DEF(0x8B26FA7D, 0xB737A961), BN_DEF(0xB34F0F78, 0x12F20E95), + BN_DEF(0x1FEACEBE, 0x9E0D9077), BN_DEF(0xFD29EEF7, 0x055E6835), + BN_DEF(0x6AE22427, 0x0EDFCD21), BN_DEF(0xCD86F56D, 0xD5E290CB), + BN_DEF(0x911B1D06, 0x743695E2), BN_DEF(0xCE4EFB4F, 0xAE574155), + BN_DEF(0x38FAA5FF, 0xB279710F), BN_DEF(0x716BA6E9, 0x7A7EA229), + BN_DEF(0xDE21BCA2, 0x5A098649), BN_DEF(0xC289C938, 0x577F0984), + BN_DEF(0x60C36C8E, 0x2CC6587D), BN_DEF(0x48FBFBF7, 0xBD6C8E93), + BN_DEF(0xEB736483, 0x30DA37E4), BN_DEF(0x7CCE011C, 0xDE1A7A6F), + BN_DEF(0xB28C81AD, 0x6F1AAD9D), BN_DEF(0x308FE7EE, 0x4435A11C), + BN_DEF(0x60D977FD, 0x6379A513), BN_DEF(0xBE8B41D9, 0xE2C778C1), + BN_DEF(0x17611002, 0x9DDAFE5E), BN_DEF(0xA637D6B9, 0xE1FF1D8D), + BN_DEF(0x777940C1, 0xC7278919), BN_DEF(0x74C2C1FF, 0xC8B97F4E), + BN_DEF(0x941A17B0, 0x601A0266), BN_DEF(0xE6FBF176, 0x4F017E70), + BN_DEF(0x770536B8, 0x8583D3E4), BN_DEF(0xB1B95D8C, 0x572B76F3), + BN_DEF(0xEF1CA6FA, 0x0EA7A151), BN_DEF(0xB06BFA34, 0xDCB56D5B), + BN_DEF(0xD96471FD, 0xE88454A5), BN_DEF(0x59927DB0, 0x5E0558C1), + BN_DEF(0xA41D3CBD, 0x98566527), BN_DEF(0x9B56F39A, 0x0EF8AC50), + BN_DEF(0x79F7F439, 0xF15344ED), BN_DEF(0x707345BB, 0xCC278638), + BN_DEF(0x3FABE49A, 0xDAAB89AF), BN_DEF(0x9EF68D79, 0x42B1B2AA), + BN_DEF(0xAF833768, 0x9219FA8F), BN_DEF(0xEAFEB2B0, 0x69EF8F6A), + BN_DEF(0x576230BD, 0x7B40D901), BN_DEF(0xB1863AEC, 0xBE97F1B1), + BN_DEF(0x124D9F7C, 0xE649CEE7), BN_DEF(0x8A3219FD, 0xD4F09B20), + BN_DEF(0xE7169B4A, 0xEC5CE2C1), BN_DEF(0x139E9E78, 0x57EE2B10), + BN_DEF(0x515DA54D, 0xD6FC2A2C), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), }; static const BN_ULONG ffdhe6144_p[] = { - 0xFFFFFFFF, 0xFFFFFFFF, 0xD0E40E65, 0xA40E329C, 0x7938DAD4, 0xA41D570D, - 0xD43161C1, 0x62A69526, 0x9ADB1E69, 0x3FDD4A8E, 0xDC6B80D6, 0x5B3B71F9, - 0xC6272B04, 0xEC9D1810, 0xCACEF403, 0x8CCF2DD5, 0xC95B9117, 0xE49F5235, - 0xB854338A, 0x505DC82D, 0x1562A846, 0x62292C31, 0x6AE77F5E, 0xD72B0374, - 0x462D538C, 0xF9C9091B, 0x47A67CBE, 0x0AE8DB58, 0x22611682, 0xB3A739C1, - 0x2A281BF6, 0xEEAAC023, 0x77CAF992, 0x94C6651E, 0x94B2BBC1, 0x763E4E4B, - 0x0077D9B4, 0x587E38DA, 0x183023C3, 0x7FB29F8C, 0xF9E3A26E, 0x0ABEC1FF, - 0x350511E3, 0xA00EF092, 0xDB6340D8, 0xB855322E, 0xA9A96910, 0xA52471F7, - 0x4CFDB477, 0x388147FB, 0x4E46041F, 0x9B1F5C3E, 0xFCCFEC71, 0xCDAD0657, - 0x4C701C3A, 0xB38E8C33, 0xB1C0FD4C, 0x917BDD64, 0x9B7624C8, 0x3BB45432, - 0xCAF53EA6, 0x23BA4442, 0x38532A3A, 0x4E677D2C, 0x45036C7A, 0x0BFD64B6, - 0x5E0DD902, 0xC68A007E, 0xF44182E1, 0x4DB5A851, 0x7F88A46B, 0x8EC9B55A, - 0xCEC97DCF, 0x0A8291CD, 0xF98D0ACC, 0x2A4ECEA9, 0x7140003C, 0x1A1DB93D, - 0x33CB8B7A, 0x092999A3, 0x71AD0038, 0x6DC778F9, 0x918130C4, 0xA907600A, - 0x2D9E6832, 0xED6A1E01, 0xEFB4318A, 0x7135C886, 0x7E31CC7A, 0x87F55BA5, - 0x55034004, 0x7763CF1D, 0xD69F6D18, 0xAC7D5F42, 0xE58857B6, 0x7930E9E4, - 0x164DF4FB, 0x6E6F52C3, 0x669E1EF1, 0x25E41D2B, 0x3FD59D7C, 0x3C1B20EE, - 0xFA53DDEF, 0x0ABCD06B, 0xD5C4484E, 0x1DBF9A42, 0x9B0DEADA, 0xABC52197, - 0x22363A0D, 0xE86D2BC5, 0x9C9DF69E, 0x5CAE82AB, 0x71F54BFF, 0x64F2E21E, - 0xE2D74DD3, 0xF4FD4452, 0xBC437944, 0xB4130C93, 0x85139270, 0xAEFE1309, - 0xC186D91C, 0x598CB0FA, 0x91F7F7EE, 0x7AD91D26, 0xD6E6C907, 0x61B46FC9, - 0xF99C0238, 0xBC34F4DE, 0x6519035B, 0xDE355B3B, 0x611FCFDC, 0x886B4238, - 0xC1B2EFFA, 0xC6F34A26, 0x7D1683B2, 0xC58EF183, 0x2EC22005, 0x3BB5FCBC, - 0x4C6FAD73, 0xC3FE3B1B, 0xEEF28183, 0x8E4F1232, 0xE98583FF, 0x9172FE9C, - 0x28342F61, 0xC03404CD, 0xCDF7E2EC, 0x9E02FCE1, 0xEE0A6D70, 0x0B07A7C8, - 0x6372BB19, 0xAE56EDE7, 0xDE394DF4, 0x1D4F42A3, 0x60D7F468, 0xB96ADAB7, - 0xB2C8E3FB, 0xD108A94B, 0xB324FB61, 0xBC0AB182, 0x483A797A, 0x30ACCA4F, - 0x36ADE735, 0x1DF158A1, 0xF3EFE872, 0xE2A689DA, 0xE0E68B77, 0x984F0C70, - 0x7F57C935, 0xB557135E, 0x3DED1AF3, 0x85636555, 0x5F066ED0, 0x2433F51F, - 0xD5FD6561, 0xD3DF1ED5, 0xAEC4617A, 0xF681B202, 0x630C75D8, 0x7D2FE363, - 0x249B3EF9, 0xCC939DCE, 0x146433FB, 0xA9E13641, 0xCE2D3695, 0xD8B9C583, - 0x273D3CF1, 0xAFDC5620, 0xA2BB4A9A, 0xADF85458, 0xFFFFFFFF, 0xFFFFFFFF + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xD0E40E65, 0xA40E329C), + BN_DEF(0x7938DAD4, 0xA41D570D), BN_DEF(0xD43161C1, 0x62A69526), + BN_DEF(0x9ADB1E69, 0x3FDD4A8E), BN_DEF(0xDC6B80D6, 0x5B3B71F9), + BN_DEF(0xC6272B04, 0xEC9D1810), BN_DEF(0xCACEF403, 0x8CCF2DD5), + BN_DEF(0xC95B9117, 0xE49F5235), BN_DEF(0xB854338A, 0x505DC82D), + BN_DEF(0x1562A846, 0x62292C31), BN_DEF(0x6AE77F5E, 0xD72B0374), + BN_DEF(0x462D538C, 0xF9C9091B), BN_DEF(0x47A67CBE, 0x0AE8DB58), + BN_DEF(0x22611682, 0xB3A739C1), BN_DEF(0x2A281BF6, 0xEEAAC023), + BN_DEF(0x77CAF992, 0x94C6651E), BN_DEF(0x94B2BBC1, 0x763E4E4B), + BN_DEF(0x0077D9B4, 0x587E38DA), BN_DEF(0x183023C3, 0x7FB29F8C), + BN_DEF(0xF9E3A26E, 0x0ABEC1FF), BN_DEF(0x350511E3, 0xA00EF092), + BN_DEF(0xDB6340D8, 0xB855322E), BN_DEF(0xA9A96910, 0xA52471F7), + BN_DEF(0x4CFDB477, 0x388147FB), BN_DEF(0x4E46041F, 0x9B1F5C3E), + BN_DEF(0xFCCFEC71, 0xCDAD0657), BN_DEF(0x4C701C3A, 0xB38E8C33), + BN_DEF(0xB1C0FD4C, 0x917BDD64), BN_DEF(0x9B7624C8, 0x3BB45432), + BN_DEF(0xCAF53EA6, 0x23BA4442), BN_DEF(0x38532A3A, 0x4E677D2C), + BN_DEF(0x45036C7A, 0x0BFD64B6), BN_DEF(0x5E0DD902, 0xC68A007E), + BN_DEF(0xF44182E1, 0x4DB5A851), BN_DEF(0x7F88A46B, 0x8EC9B55A), + BN_DEF(0xCEC97DCF, 0x0A8291CD), BN_DEF(0xF98D0ACC, 0x2A4ECEA9), + BN_DEF(0x7140003C, 0x1A1DB93D), BN_DEF(0x33CB8B7A, 0x092999A3), + BN_DEF(0x71AD0038, 0x6DC778F9), BN_DEF(0x918130C4, 0xA907600A), + BN_DEF(0x2D9E6832, 0xED6A1E01), BN_DEF(0xEFB4318A, 0x7135C886), + BN_DEF(0x7E31CC7A, 0x87F55BA5), BN_DEF(0x55034004, 0x7763CF1D), + BN_DEF(0xD69F6D18, 0xAC7D5F42), BN_DEF(0xE58857B6, 0x7930E9E4), + BN_DEF(0x164DF4FB, 0x6E6F52C3), BN_DEF(0x669E1EF1, 0x25E41D2B), + BN_DEF(0x3FD59D7C, 0x3C1B20EE), BN_DEF(0xFA53DDEF, 0x0ABCD06B), + BN_DEF(0xD5C4484E, 0x1DBF9A42), BN_DEF(0x9B0DEADA, 0xABC52197), + BN_DEF(0x22363A0D, 0xE86D2BC5), BN_DEF(0x9C9DF69E, 0x5CAE82AB), + BN_DEF(0x71F54BFF, 0x64F2E21E), BN_DEF(0xE2D74DD3, 0xF4FD4452), + BN_DEF(0xBC437944, 0xB4130C93), BN_DEF(0x85139270, 0xAEFE1309), + BN_DEF(0xC186D91C, 0x598CB0FA), BN_DEF(0x91F7F7EE, 0x7AD91D26), + BN_DEF(0xD6E6C907, 0x61B46FC9), BN_DEF(0xF99C0238, 0xBC34F4DE), + BN_DEF(0x6519035B, 0xDE355B3B), BN_DEF(0x611FCFDC, 0x886B4238), + BN_DEF(0xC1B2EFFA, 0xC6F34A26), BN_DEF(0x7D1683B2, 0xC58EF183), + BN_DEF(0x2EC22005, 0x3BB5FCBC), BN_DEF(0x4C6FAD73, 0xC3FE3B1B), + BN_DEF(0xEEF28183, 0x8E4F1232), BN_DEF(0xE98583FF, 0x9172FE9C), + BN_DEF(0x28342F61, 0xC03404CD), BN_DEF(0xCDF7E2EC, 0x9E02FCE1), + BN_DEF(0xEE0A6D70, 0x0B07A7C8), BN_DEF(0x6372BB19, 0xAE56EDE7), + BN_DEF(0xDE394DF4, 0x1D4F42A3), BN_DEF(0x60D7F468, 0xB96ADAB7), + BN_DEF(0xB2C8E3FB, 0xD108A94B), BN_DEF(0xB324FB61, 0xBC0AB182), + BN_DEF(0x483A797A, 0x30ACCA4F), BN_DEF(0x36ADE735, 0x1DF158A1), + BN_DEF(0xF3EFE872, 0xE2A689DA), BN_DEF(0xE0E68B77, 0x984F0C70), + BN_DEF(0x7F57C935, 0xB557135E), BN_DEF(0x3DED1AF3, 0x85636555), + BN_DEF(0x5F066ED0, 0x2433F51F), BN_DEF(0xD5FD6561, 0xD3DF1ED5), + BN_DEF(0xAEC4617A, 0xF681B202), BN_DEF(0x630C75D8, 0x7D2FE363), + BN_DEF(0x249B3EF9, 0xCC939DCE), BN_DEF(0x146433FB, 0xA9E13641), + BN_DEF(0xCE2D3695, 0xD8B9C583), BN_DEF(0x273D3CF1, 0xAFDC5620), + BN_DEF(0xA2BB4A9A, 0xADF85458), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; +/* q = (p - 1) / 2 */ +static const BN_ULONG ffdhe6144_q[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x68720732, 0x5207194E), + BN_DEF(0xBC9C6D6A, 0xD20EAB86), BN_DEF(0x6A18B0E0, 0xB1534A93), + BN_DEF(0x4D6D8F34, 0x1FEEA547), BN_DEF(0xEE35C06B, 0x2D9DB8FC), + BN_DEF(0x63139582, 0xF64E8C08), BN_DEF(0xE5677A01, 0xC66796EA), + BN_DEF(0xE4ADC88B, 0x724FA91A), BN_DEF(0xDC2A19C5, 0x282EE416), + BN_DEF(0x8AB15423, 0x31149618), BN_DEF(0x3573BFAF, 0x6B9581BA), + BN_DEF(0xA316A9C6, 0x7CE4848D), BN_DEF(0x23D33E5F, 0x05746DAC), + BN_DEF(0x91308B41, 0x59D39CE0), BN_DEF(0x95140DFB, 0x77556011), + BN_DEF(0x3BE57CC9, 0xCA63328F), BN_DEF(0xCA595DE0, 0x3B1F2725), + BN_DEF(0x003BECDA, 0xAC3F1C6D), BN_DEF(0x0C1811E1, 0x3FD94FC6), + BN_DEF(0xFCF1D137, 0x855F60FF), BN_DEF(0x1A8288F1, 0x50077849), + BN_DEF(0x6DB1A06C, 0x5C2A9917), BN_DEF(0xD4D4B488, 0xD29238FB), + BN_DEF(0xA67EDA3B, 0x9C40A3FD), BN_DEF(0x2723020F, 0xCD8FAE1F), + BN_DEF(0xFE67F638, 0x66D6832B), BN_DEF(0xA6380E1D, 0x59C74619), + BN_DEF(0x58E07EA6, 0x48BDEEB2), BN_DEF(0x4DBB1264, 0x1DDA2A19), + BN_DEF(0x657A9F53, 0x11DD2221), BN_DEF(0x1C29951D, 0x2733BE96), + BN_DEF(0x2281B63D, 0x05FEB25B), BN_DEF(0x2F06EC81, 0xE345003F), + BN_DEF(0xFA20C170, 0xA6DAD428), BN_DEF(0x3FC45235, 0xC764DAAD), + BN_DEF(0xE764BEE7, 0x054148E6), BN_DEF(0xFCC68566, 0x15276754), + BN_DEF(0xB8A0001E, 0x0D0EDC9E), BN_DEF(0x99E5C5BD, 0x0494CCD1), + BN_DEF(0xB8D6801C, 0x36E3BC7C), BN_DEF(0x48C09862, 0x5483B005), + BN_DEF(0x96CF3419, 0x76B50F00), BN_DEF(0x77DA18C5, 0x389AE443), + BN_DEF(0xBF18E63D, 0x43FAADD2), BN_DEF(0xAA81A002, 0x3BB1E78E), + BN_DEF(0x6B4FB68C, 0x563EAFA1), BN_DEF(0x72C42BDB, 0xBC9874F2), + BN_DEF(0x8B26FA7D, 0xB737A961), BN_DEF(0xB34F0F78, 0x12F20E95), + BN_DEF(0x1FEACEBE, 0x9E0D9077), BN_DEF(0xFD29EEF7, 0x055E6835), + BN_DEF(0x6AE22427, 0x0EDFCD21), BN_DEF(0xCD86F56D, 0xD5E290CB), + BN_DEF(0x911B1D06, 0x743695E2), BN_DEF(0xCE4EFB4F, 0xAE574155), + BN_DEF(0x38FAA5FF, 0xB279710F), BN_DEF(0x716BA6E9, 0x7A7EA229), + BN_DEF(0xDE21BCA2, 0x5A098649), BN_DEF(0xC289C938, 0x577F0984), + BN_DEF(0x60C36C8E, 0x2CC6587D), BN_DEF(0x48FBFBF7, 0xBD6C8E93), + BN_DEF(0xEB736483, 0x30DA37E4), BN_DEF(0x7CCE011C, 0xDE1A7A6F), + BN_DEF(0xB28C81AD, 0x6F1AAD9D), BN_DEF(0x308FE7EE, 0x4435A11C), + BN_DEF(0x60D977FD, 0x6379A513), BN_DEF(0xBE8B41D9, 0xE2C778C1), + BN_DEF(0x17611002, 0x9DDAFE5E), BN_DEF(0xA637D6B9, 0xE1FF1D8D), + BN_DEF(0x777940C1, 0xC7278919), BN_DEF(0x74C2C1FF, 0xC8B97F4E), + BN_DEF(0x941A17B0, 0x601A0266), BN_DEF(0xE6FBF176, 0x4F017E70), + BN_DEF(0x770536B8, 0x8583D3E4), BN_DEF(0xB1B95D8C, 0x572B76F3), + BN_DEF(0xEF1CA6FA, 0x0EA7A151), BN_DEF(0xB06BFA34, 0xDCB56D5B), + BN_DEF(0xD96471FD, 0xE88454A5), BN_DEF(0x59927DB0, 0x5E0558C1), + BN_DEF(0xA41D3CBD, 0x98566527), BN_DEF(0x9B56F39A, 0x0EF8AC50), + BN_DEF(0x79F7F439, 0xF15344ED), BN_DEF(0x707345BB, 0xCC278638), + BN_DEF(0x3FABE49A, 0xDAAB89AF), BN_DEF(0x9EF68D79, 0x42B1B2AA), + BN_DEF(0xAF833768, 0x9219FA8F), BN_DEF(0xEAFEB2B0, 0x69EF8F6A), + BN_DEF(0x576230BD, 0x7B40D901), BN_DEF(0xB1863AEC, 0xBE97F1B1), + BN_DEF(0x124D9F7C, 0xE649CEE7), BN_DEF(0x8A3219FD, 0xD4F09B20), + BN_DEF(0xE7169B4A, 0xEC5CE2C1), BN_DEF(0x139E9E78, 0x57EE2B10), + BN_DEF(0x515DA54D, 0xD6FC2A2C), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), }; static const BN_ULONG ffdhe8192_p[] = { - 0xFFFFFFFF, 0xFFFFFFFF, 0xC5C6424C, 0xD68C8BB7, 0x838FF88C, 0x011E2A94, - 0xA9F4614E, 0x0822E506, 0xF7A8443D, 0x97D11D49, 0x30677F0D, 0xA6BBFDE5, - 0xC1FE86FE, 0x2F741EF8, 0x5D71A87E, 0xFAFABE1C, 0xFBE58A30, 0xDED2FBAB, - 0x72B0A66E, 0xB6855DFE, 0xBA8A4FE8, 0x1EFC8CE0, 0x3F2FA457, 0x83F81D4A, - 0xA577E231, 0xA1FE3075, 0x88D9C0A0, 0xD5B80194, 0xAD9A95F9, 0x624816CD, - 0x50C1217B, 0x99E9E316, 0x0E423CFC, 0x51AA691E, 0x3826E52C, 0x1C217E6C, - 0x09703FEE, 0x51A8A931, 0x6A460E74, 0xBB709987, 0x9C86B022, 0x541FC68C, - 0x46FD8251, 0x59160CC0, 0x35C35F5C, 0x2846C0BA, 0x8B758282, 0x54504AC7, - 0xD2AF05E4, 0x29388839, 0xC01BD702, 0xCB2C0F1C, 0x7C932665, 0x555B2F74, - 0xA3AB8829, 0x86B63142, 0xF64B10EF, 0x0B8CC3BD, 0xEDD1CC5E, 0x687FEB69, - 0xC9509D43, 0xFDB23FCE, 0xD951AE64, 0x1E425A31, 0xF600C838, 0x36AD004C, - 0xCFF46AAA, 0xA40E329C, 0x7938DAD4, 0xA41D570D, 0xD43161C1, 0x62A69526, - 0x9ADB1E69, 0x3FDD4A8E, 0xDC6B80D6, 0x5B3B71F9, 0xC6272B04, 0xEC9D1810, - 0xCACEF403, 0x8CCF2DD5, 0xC95B9117, 0xE49F5235, 0xB854338A, 0x505DC82D, - 0x1562A846, 0x62292C31, 0x6AE77F5E, 0xD72B0374, 0x462D538C, 0xF9C9091B, - 0x47A67CBE, 0x0AE8DB58, 0x22611682, 0xB3A739C1, 0x2A281BF6, 0xEEAAC023, - 0x77CAF992, 0x94C6651E, 0x94B2BBC1, 0x763E4E4B, 0x0077D9B4, 0x587E38DA, - 0x183023C3, 0x7FB29F8C, 0xF9E3A26E, 0x0ABEC1FF, 0x350511E3, 0xA00EF092, - 0xDB6340D8, 0xB855322E, 0xA9A96910, 0xA52471F7, 0x4CFDB477, 0x388147FB, - 0x4E46041F, 0x9B1F5C3E, 0xFCCFEC71, 0xCDAD0657, 0x4C701C3A, 0xB38E8C33, - 0xB1C0FD4C, 0x917BDD64, 0x9B7624C8, 0x3BB45432, 0xCAF53EA6, 0x23BA4442, - 0x38532A3A, 0x4E677D2C, 0x45036C7A, 0x0BFD64B6, 0x5E0DD902, 0xC68A007E, - 0xF44182E1, 0x4DB5A851, 0x7F88A46B, 0x8EC9B55A, 0xCEC97DCF, 0x0A8291CD, - 0xF98D0ACC, 0x2A4ECEA9, 0x7140003C, 0x1A1DB93D, 0x33CB8B7A, 0x092999A3, - 0x71AD0038, 0x6DC778F9, 0x918130C4, 0xA907600A, 0x2D9E6832, 0xED6A1E01, - 0xEFB4318A, 0x7135C886, 0x7E31CC7A, 0x87F55BA5, 0x55034004, 0x7763CF1D, - 0xD69F6D18, 0xAC7D5F42, 0xE58857B6, 0x7930E9E4, 0x164DF4FB, 0x6E6F52C3, - 0x669E1EF1, 0x25E41D2B, 0x3FD59D7C, 0x3C1B20EE, 0xFA53DDEF, 0x0ABCD06B, - 0xD5C4484E, 0x1DBF9A42, 0x9B0DEADA, 0xABC52197, 0x22363A0D, 0xE86D2BC5, - 0x9C9DF69E, 0x5CAE82AB, 0x71F54BFF, 0x64F2E21E, 0xE2D74DD3, 0xF4FD4452, - 0xBC437944, 0xB4130C93, 0x85139270, 0xAEFE1309, 0xC186D91C, 0x598CB0FA, - 0x91F7F7EE, 0x7AD91D26, 0xD6E6C907, 0x61B46FC9, 0xF99C0238, 0xBC34F4DE, - 0x6519035B, 0xDE355B3B, 0x611FCFDC, 0x886B4238, 0xC1B2EFFA, 0xC6F34A26, - 0x7D1683B2, 0xC58EF183, 0x2EC22005, 0x3BB5FCBC, 0x4C6FAD73, 0xC3FE3B1B, - 0xEEF28183, 0x8E4F1232, 0xE98583FF, 0x9172FE9C, 0x28342F61, 0xC03404CD, - 0xCDF7E2EC, 0x9E02FCE1, 0xEE0A6D70, 0x0B07A7C8, 0x6372BB19, 0xAE56EDE7, - 0xDE394DF4, 0x1D4F42A3, 0x60D7F468, 0xB96ADAB7, 0xB2C8E3FB, 0xD108A94B, - 0xB324FB61, 0xBC0AB182, 0x483A797A, 0x30ACCA4F, 0x36ADE735, 0x1DF158A1, - 0xF3EFE872, 0xE2A689DA, 0xE0E68B77, 0x984F0C70, 0x7F57C935, 0xB557135E, - 0x3DED1AF3, 0x85636555, 0x5F066ED0, 0x2433F51F, 0xD5FD6561, 0xD3DF1ED5, - 0xAEC4617A, 0xF681B202, 0x630C75D8, 0x7D2FE363, 0x249B3EF9, 0xCC939DCE, - 0x146433FB, 0xA9E13641, 0xCE2D3695, 0xD8B9C583, 0x273D3CF1, 0xAFDC5620, - 0xA2BB4A9A, 0xADF85458, 0xFFFFFFFF, 0xFFFFFFFF + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xC5C6424C, 0xD68C8BB7), + BN_DEF(0x838FF88C, 0x011E2A94), BN_DEF(0xA9F4614E, 0x0822E506), + BN_DEF(0xF7A8443D, 0x97D11D49), BN_DEF(0x30677F0D, 0xA6BBFDE5), + BN_DEF(0xC1FE86FE, 0x2F741EF8), BN_DEF(0x5D71A87E, 0xFAFABE1C), + BN_DEF(0xFBE58A30, 0xDED2FBAB), BN_DEF(0x72B0A66E, 0xB6855DFE), + BN_DEF(0xBA8A4FE8, 0x1EFC8CE0), BN_DEF(0x3F2FA457, 0x83F81D4A), + BN_DEF(0xA577E231, 0xA1FE3075), BN_DEF(0x88D9C0A0, 0xD5B80194), + BN_DEF(0xAD9A95F9, 0x624816CD), BN_DEF(0x50C1217B, 0x99E9E316), + BN_DEF(0x0E423CFC, 0x51AA691E), BN_DEF(0x3826E52C, 0x1C217E6C), + BN_DEF(0x09703FEE, 0x51A8A931), BN_DEF(0x6A460E74, 0xBB709987), + BN_DEF(0x9C86B022, 0x541FC68C), BN_DEF(0x46FD8251, 0x59160CC0), + BN_DEF(0x35C35F5C, 0x2846C0BA), BN_DEF(0x8B758282, 0x54504AC7), + BN_DEF(0xD2AF05E4, 0x29388839), BN_DEF(0xC01BD702, 0xCB2C0F1C), + BN_DEF(0x7C932665, 0x555B2F74), BN_DEF(0xA3AB8829, 0x86B63142), + BN_DEF(0xF64B10EF, 0x0B8CC3BD), BN_DEF(0xEDD1CC5E, 0x687FEB69), + BN_DEF(0xC9509D43, 0xFDB23FCE), BN_DEF(0xD951AE64, 0x1E425A31), + BN_DEF(0xF600C838, 0x36AD004C), BN_DEF(0xCFF46AAA, 0xA40E329C), + BN_DEF(0x7938DAD4, 0xA41D570D), BN_DEF(0xD43161C1, 0x62A69526), + BN_DEF(0x9ADB1E69, 0x3FDD4A8E), BN_DEF(0xDC6B80D6, 0x5B3B71F9), + BN_DEF(0xC6272B04, 0xEC9D1810), BN_DEF(0xCACEF403, 0x8CCF2DD5), + BN_DEF(0xC95B9117, 0xE49F5235), BN_DEF(0xB854338A, 0x505DC82D), + BN_DEF(0x1562A846, 0x62292C31), BN_DEF(0x6AE77F5E, 0xD72B0374), + BN_DEF(0x462D538C, 0xF9C9091B), BN_DEF(0x47A67CBE, 0x0AE8DB58), + BN_DEF(0x22611682, 0xB3A739C1), BN_DEF(0x2A281BF6, 0xEEAAC023), + BN_DEF(0x77CAF992, 0x94C6651E), BN_DEF(0x94B2BBC1, 0x763E4E4B), + BN_DEF(0x0077D9B4, 0x587E38DA), BN_DEF(0x183023C3, 0x7FB29F8C), + BN_DEF(0xF9E3A26E, 0x0ABEC1FF), BN_DEF(0x350511E3, 0xA00EF092), + BN_DEF(0xDB6340D8, 0xB855322E), BN_DEF(0xA9A96910, 0xA52471F7), + BN_DEF(0x4CFDB477, 0x388147FB), BN_DEF(0x4E46041F, 0x9B1F5C3E), + BN_DEF(0xFCCFEC71, 0xCDAD0657), BN_DEF(0x4C701C3A, 0xB38E8C33), + BN_DEF(0xB1C0FD4C, 0x917BDD64), BN_DEF(0x9B7624C8, 0x3BB45432), + BN_DEF(0xCAF53EA6, 0x23BA4442), BN_DEF(0x38532A3A, 0x4E677D2C), + BN_DEF(0x45036C7A, 0x0BFD64B6), BN_DEF(0x5E0DD902, 0xC68A007E), + BN_DEF(0xF44182E1, 0x4DB5A851), BN_DEF(0x7F88A46B, 0x8EC9B55A), + BN_DEF(0xCEC97DCF, 0x0A8291CD), BN_DEF(0xF98D0ACC, 0x2A4ECEA9), + BN_DEF(0x7140003C, 0x1A1DB93D), BN_DEF(0x33CB8B7A, 0x092999A3), + BN_DEF(0x71AD0038, 0x6DC778F9), BN_DEF(0x918130C4, 0xA907600A), + BN_DEF(0x2D9E6832, 0xED6A1E01), BN_DEF(0xEFB4318A, 0x7135C886), + BN_DEF(0x7E31CC7A, 0x87F55BA5), BN_DEF(0x55034004, 0x7763CF1D), + BN_DEF(0xD69F6D18, 0xAC7D5F42), BN_DEF(0xE58857B6, 0x7930E9E4), + BN_DEF(0x164DF4FB, 0x6E6F52C3), BN_DEF(0x669E1EF1, 0x25E41D2B), + BN_DEF(0x3FD59D7C, 0x3C1B20EE), BN_DEF(0xFA53DDEF, 0x0ABCD06B), + BN_DEF(0xD5C4484E, 0x1DBF9A42), BN_DEF(0x9B0DEADA, 0xABC52197), + BN_DEF(0x22363A0D, 0xE86D2BC5), BN_DEF(0x9C9DF69E, 0x5CAE82AB), + BN_DEF(0x71F54BFF, 0x64F2E21E), BN_DEF(0xE2D74DD3, 0xF4FD4452), + BN_DEF(0xBC437944, 0xB4130C93), BN_DEF(0x85139270, 0xAEFE1309), + BN_DEF(0xC186D91C, 0x598CB0FA), BN_DEF(0x91F7F7EE, 0x7AD91D26), + BN_DEF(0xD6E6C907, 0x61B46FC9), BN_DEF(0xF99C0238, 0xBC34F4DE), + BN_DEF(0x6519035B, 0xDE355B3B), BN_DEF(0x611FCFDC, 0x886B4238), + BN_DEF(0xC1B2EFFA, 0xC6F34A26), BN_DEF(0x7D1683B2, 0xC58EF183), + BN_DEF(0x2EC22005, 0x3BB5FCBC), BN_DEF(0x4C6FAD73, 0xC3FE3B1B), + BN_DEF(0xEEF28183, 0x8E4F1232), BN_DEF(0xE98583FF, 0x9172FE9C), + BN_DEF(0x28342F61, 0xC03404CD), BN_DEF(0xCDF7E2EC, 0x9E02FCE1), + BN_DEF(0xEE0A6D70, 0x0B07A7C8), BN_DEF(0x6372BB19, 0xAE56EDE7), + BN_DEF(0xDE394DF4, 0x1D4F42A3), BN_DEF(0x60D7F468, 0xB96ADAB7), + BN_DEF(0xB2C8E3FB, 0xD108A94B), BN_DEF(0xB324FB61, 0xBC0AB182), + BN_DEF(0x483A797A, 0x30ACCA4F), BN_DEF(0x36ADE735, 0x1DF158A1), + BN_DEF(0xF3EFE872, 0xE2A689DA), BN_DEF(0xE0E68B77, 0x984F0C70), + BN_DEF(0x7F57C935, 0xB557135E), BN_DEF(0x3DED1AF3, 0x85636555), + BN_DEF(0x5F066ED0, 0x2433F51F), BN_DEF(0xD5FD6561, 0xD3DF1ED5), + BN_DEF(0xAEC4617A, 0xF681B202), BN_DEF(0x630C75D8, 0x7D2FE363), + BN_DEF(0x249B3EF9, 0xCC939DCE), BN_DEF(0x146433FB, 0xA9E13641), + BN_DEF(0xCE2D3695, 0xD8B9C583), BN_DEF(0x273D3CF1, 0xAFDC5620), + BN_DEF(0xA2BB4A9A, 0xADF85458), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; +/* q = (p - 1) / 2 */ +static const BN_ULONG ffdhe8192_q[] = { + BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), BN_DEF(0xE2E32126, 0x6B4645DB), + BN_DEF(0x41C7FC46, 0x008F154A), BN_DEF(0x54FA30A7, 0x84117283), + BN_DEF(0xFBD4221E, 0xCBE88EA4), BN_DEF(0x9833BF86, 0x535DFEF2), + BN_DEF(0x60FF437F, 0x17BA0F7C), BN_DEF(0x2EB8D43F, 0x7D7D5F0E), + BN_DEF(0xFDF2C518, 0x6F697DD5), BN_DEF(0x39585337, 0x5B42AEFF), + BN_DEF(0x5D4527F4, 0x8F7E4670), BN_DEF(0x1F97D22B, 0xC1FC0EA5), + BN_DEF(0xD2BBF118, 0x50FF183A), BN_DEF(0x446CE050, 0xEADC00CA), + BN_DEF(0xD6CD4AFC, 0xB1240B66), BN_DEF(0x286090BD, 0x4CF4F18B), + BN_DEF(0x07211E7E, 0x28D5348F), BN_DEF(0x1C137296, 0x0E10BF36), + BN_DEF(0x84B81FF7, 0x28D45498), BN_DEF(0xB523073A, 0x5DB84CC3), + BN_DEF(0x4E435811, 0xAA0FE346), BN_DEF(0x237EC128, 0x2C8B0660), + BN_DEF(0x1AE1AFAE, 0x1423605D), BN_DEF(0xC5BAC141, 0x2A282563), + BN_DEF(0xE95782F2, 0x149C441C), BN_DEF(0x600DEB81, 0xE596078E), + BN_DEF(0x3E499332, 0xAAAD97BA), BN_DEF(0x51D5C414, 0xC35B18A1), + BN_DEF(0xFB258877, 0x05C661DE), BN_DEF(0xF6E8E62F, 0xB43FF5B4), + BN_DEF(0x64A84EA1, 0x7ED91FE7), BN_DEF(0xECA8D732, 0x0F212D18), + BN_DEF(0x7B00641C, 0x1B568026), BN_DEF(0x67FA3555, 0x5207194E), + BN_DEF(0xBC9C6D6A, 0xD20EAB86), BN_DEF(0x6A18B0E0, 0xB1534A93), + BN_DEF(0x4D6D8F34, 0x1FEEA547), BN_DEF(0xEE35C06B, 0x2D9DB8FC), + BN_DEF(0x63139582, 0xF64E8C08), BN_DEF(0xE5677A01, 0xC66796EA), + BN_DEF(0xE4ADC88B, 0x724FA91A), BN_DEF(0xDC2A19C5, 0x282EE416), + BN_DEF(0x8AB15423, 0x31149618), BN_DEF(0x3573BFAF, 0x6B9581BA), + BN_DEF(0xA316A9C6, 0x7CE4848D), BN_DEF(0x23D33E5F, 0x05746DAC), + BN_DEF(0x91308B41, 0x59D39CE0), BN_DEF(0x95140DFB, 0x77556011), + BN_DEF(0x3BE57CC9, 0xCA63328F), BN_DEF(0xCA595DE0, 0x3B1F2725), + BN_DEF(0x003BECDA, 0xAC3F1C6D), BN_DEF(0x0C1811E1, 0x3FD94FC6), + BN_DEF(0xFCF1D137, 0x855F60FF), BN_DEF(0x1A8288F1, 0x50077849), + BN_DEF(0x6DB1A06C, 0x5C2A9917), BN_DEF(0xD4D4B488, 0xD29238FB), + BN_DEF(0xA67EDA3B, 0x9C40A3FD), BN_DEF(0x2723020F, 0xCD8FAE1F), + BN_DEF(0xFE67F638, 0x66D6832B), BN_DEF(0xA6380E1D, 0x59C74619), + BN_DEF(0x58E07EA6, 0x48BDEEB2), BN_DEF(0x4DBB1264, 0x1DDA2A19), + BN_DEF(0x657A9F53, 0x11DD2221), BN_DEF(0x1C29951D, 0x2733BE96), + BN_DEF(0x2281B63D, 0x05FEB25B), BN_DEF(0x2F06EC81, 0xE345003F), + BN_DEF(0xFA20C170, 0xA6DAD428), BN_DEF(0x3FC45235, 0xC764DAAD), + BN_DEF(0xE764BEE7, 0x054148E6), BN_DEF(0xFCC68566, 0x15276754), + BN_DEF(0xB8A0001E, 0x0D0EDC9E), BN_DEF(0x99E5C5BD, 0x0494CCD1), + BN_DEF(0xB8D6801C, 0x36E3BC7C), BN_DEF(0x48C09862, 0x5483B005), + BN_DEF(0x96CF3419, 0x76B50F00), BN_DEF(0x77DA18C5, 0x389AE443), + BN_DEF(0xBF18E63D, 0x43FAADD2), BN_DEF(0xAA81A002, 0x3BB1E78E), + BN_DEF(0x6B4FB68C, 0x563EAFA1), BN_DEF(0x72C42BDB, 0xBC9874F2), + BN_DEF(0x8B26FA7D, 0xB737A961), BN_DEF(0xB34F0F78, 0x12F20E95), + BN_DEF(0x1FEACEBE, 0x9E0D9077), BN_DEF(0xFD29EEF7, 0x055E6835), + BN_DEF(0x6AE22427, 0x0EDFCD21), BN_DEF(0xCD86F56D, 0xD5E290CB), + BN_DEF(0x911B1D06, 0x743695E2), BN_DEF(0xCE4EFB4F, 0xAE574155), + BN_DEF(0x38FAA5FF, 0xB279710F), BN_DEF(0x716BA6E9, 0x7A7EA229), + BN_DEF(0xDE21BCA2, 0x5A098649), BN_DEF(0xC289C938, 0x577F0984), + BN_DEF(0x60C36C8E, 0x2CC6587D), BN_DEF(0x48FBFBF7, 0xBD6C8E93), + BN_DEF(0xEB736483, 0x30DA37E4), BN_DEF(0x7CCE011C, 0xDE1A7A6F), + BN_DEF(0xB28C81AD, 0x6F1AAD9D), BN_DEF(0x308FE7EE, 0x4435A11C), + BN_DEF(0x60D977FD, 0x6379A513), BN_DEF(0xBE8B41D9, 0xE2C778C1), + BN_DEF(0x17611002, 0x9DDAFE5E), BN_DEF(0xA637D6B9, 0xE1FF1D8D), + BN_DEF(0x777940C1, 0xC7278919), BN_DEF(0x74C2C1FF, 0xC8B97F4E), + BN_DEF(0x941A17B0, 0x601A0266), BN_DEF(0xE6FBF176, 0x4F017E70), + BN_DEF(0x770536B8, 0x8583D3E4), BN_DEF(0xB1B95D8C, 0x572B76F3), + BN_DEF(0xEF1CA6FA, 0x0EA7A151), BN_DEF(0xB06BFA34, 0xDCB56D5B), + BN_DEF(0xD96471FD, 0xE88454A5), BN_DEF(0x59927DB0, 0x5E0558C1), + BN_DEF(0xA41D3CBD, 0x98566527), BN_DEF(0x9B56F39A, 0x0EF8AC50), + BN_DEF(0x79F7F439, 0xF15344ED), BN_DEF(0x707345BB, 0xCC278638), + BN_DEF(0x3FABE49A, 0xDAAB89AF), BN_DEF(0x9EF68D79, 0x42B1B2AA), + BN_DEF(0xAF833768, 0x9219FA8F), BN_DEF(0xEAFEB2B0, 0x69EF8F6A), + BN_DEF(0x576230BD, 0x7B40D901), BN_DEF(0xB1863AEC, 0xBE97F1B1), + BN_DEF(0x124D9F7C, 0xE649CEE7), BN_DEF(0x8A3219FD, 0xD4F09B20), + BN_DEF(0xE7169B4A, 0xEC5CE2C1), BN_DEF(0x139E9E78, 0x57EE2B10), + BN_DEF(0x515DA54D, 0xD6FC2A2C), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), }; - -# else -# error "unsupported BN_BITS2" -# endif /* Macro to make a BIGNUM from static data */ -# define make_dh_bn(x) extern const BIGNUM _bignum_##x; \ - const BIGNUM _bignum_##x = { (BN_ULONG *) x, \ - OSSL_NELEM(x),\ - OSSL_NELEM(x),\ - 0, BN_FLG_STATIC_DATA }; +# define make_dh_bn(x) \ + extern const BIGNUM ossl_bignum_##x; \ + const BIGNUM ossl_bignum_##x = { \ + (BN_ULONG *) x, \ + OSSL_NELEM(x), \ + OSSL_NELEM(x), \ + 0, BN_FLG_STATIC_DATA }; static const BN_ULONG value_2 = 2; -const BIGNUM _bignum_const_2 = - { (BN_ULONG *)&value_2, 1, 1, 0, BN_FLG_STATIC_DATA }; +const BIGNUM ossl_bignum_const_2 = { + (BN_ULONG *)&value_2, 1, 1, 0, BN_FLG_STATIC_DATA +}; make_dh_bn(dh1024_160_p) -make_dh_bn(dh1024_160_g) make_dh_bn(dh1024_160_q) +make_dh_bn(dh1024_160_g) make_dh_bn(dh2048_224_p) -make_dh_bn(dh2048_224_g) make_dh_bn(dh2048_224_q) +make_dh_bn(dh2048_224_g) make_dh_bn(dh2048_256_p) -make_dh_bn(dh2048_256_g) make_dh_bn(dh2048_256_q) +make_dh_bn(dh2048_256_g) make_dh_bn(ffdhe2048_p) +make_dh_bn(ffdhe2048_q) make_dh_bn(ffdhe3072_p) +make_dh_bn(ffdhe3072_q) make_dh_bn(ffdhe4096_p) +make_dh_bn(ffdhe4096_q) make_dh_bn(ffdhe6144_p) +make_dh_bn(ffdhe6144_q) make_dh_bn(ffdhe8192_p) +make_dh_bn(ffdhe8192_q) - -#endif +# ifndef FIPS_MODULE +make_dh_bn(modp_1536_p) +make_dh_bn(modp_1536_q) +# endif +make_dh_bn(modp_2048_p) +make_dh_bn(modp_2048_q) +make_dh_bn(modp_3072_p) +make_dh_bn(modp_3072_q) +make_dh_bn(modp_4096_p) +make_dh_bn(modp_4096_q) +make_dh_bn(modp_6144_p) +make_dh_bn(modp_6144_q) +make_dh_bn(modp_8192_p) +make_dh_bn(modp_8192_q) diff --git a/crypto/openssl/crypto/bn/bn_div.c b/crypto/openssl/crypto/bn/bn_div.c index 4273618825cc..ff66baa48f22 100644 --- a/crypto/openssl/crypto/bn/bn_div.c +++ b/crypto/openssl/crypto/bn/bn_div.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -24,7 +24,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, bn_check_top(m); bn_check_top(d); if (BN_is_zero(d)) { - BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO); + ERR_raise(ERR_LIB_BN, BN_R_DIV_BY_ZERO); return 0; } @@ -97,7 +97,7 @@ BN_ULONG bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0); */ # if BN_BITS2 == 64 && defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16 # undef BN_ULLONG -# define BN_ULLONG __uint128_t +# define BN_ULLONG uint128_t # define BN_LLONG # endif @@ -212,7 +212,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, int ret; if (BN_is_zero(divisor)) { - BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO); + ERR_raise(ERR_LIB_BN, BN_R_DIV_BY_ZERO); return 0; } @@ -222,7 +222,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, * BN_DEBUG builds) */ if (divisor->d[divisor->top - 1] == 0) { - BNerr(BN_F_BN_DIV, BN_R_NOT_INITIALIZED); + ERR_raise(ERR_LIB_BN, BN_R_NOT_INITIALIZED); return 0; } diff --git a/crypto/openssl/crypto/bn/bn_err.c b/crypto/openssl/crypto/bn/bn_err.c index 6f5464b54054..953be9ed4717 100644 --- a/crypto/openssl/crypto/bn/bn_err.c +++ b/crypto/openssl/crypto/bn/bn_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,74 +10,10 @@ #include #include +#include "crypto/bnerr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA BN_str_functs[] = { - {ERR_PACK(ERR_LIB_BN, BN_F_BNRAND, 0), "bnrand"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BNRAND_RANGE, 0), "bnrand_range"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BLINDING_CONVERT_EX, 0), - "BN_BLINDING_convert_ex"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BLINDING_CREATE_PARAM, 0), - "BN_BLINDING_create_param"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BLINDING_INVERT_EX, 0), - "BN_BLINDING_invert_ex"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BLINDING_NEW, 0), "BN_BLINDING_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BLINDING_UPDATE, 0), "BN_BLINDING_update"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BN2DEC, 0), "BN_bn2dec"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_BN2HEX, 0), "BN_bn2hex"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_COMPUTE_WNAF, 0), "bn_compute_wNAF"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_CTX_GET, 0), "BN_CTX_get"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_CTX_NEW, 0), "BN_CTX_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_CTX_START, 0), "BN_CTX_start"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_DIV, 0), "BN_div"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_DIV_RECP, 0), "BN_div_recp"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_EXP, 0), "BN_exp"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_EXPAND_INTERNAL, 0), "bn_expand_internal"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GENCB_NEW, 0), "BN_GENCB_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GENERATE_DSA_NONCE, 0), - "BN_generate_dsa_nonce"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GENERATE_PRIME_EX, 0), - "BN_generate_prime_ex"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD, 0), "BN_GF2m_mod"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_EXP, 0), "BN_GF2m_mod_exp"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_MUL, 0), "BN_GF2m_mod_mul"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_SOLVE_QUAD, 0), - "BN_GF2m_mod_solve_quad"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, 0), - "BN_GF2m_mod_solve_quad_arr"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_SQR, 0), "BN_GF2m_mod_sqr"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_GF2M_MOD_SQRT, 0), "BN_GF2m_mod_sqrt"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_LSHIFT, 0), "BN_lshift"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP2_MONT, 0), "BN_mod_exp2_mont"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP_MONT, 0), "BN_mod_exp_mont"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP_MONT_CONSTTIME, 0), - "BN_mod_exp_mont_consttime"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP_MONT_WORD, 0), - "BN_mod_exp_mont_word"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP_RECP, 0), "BN_mod_exp_recp"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_EXP_SIMPLE, 0), "BN_mod_exp_simple"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_INVERSE, 0), "BN_mod_inverse"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_INVERSE_NO_BRANCH, 0), - "BN_mod_inverse_no_branch"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_LSHIFT_QUICK, 0), "BN_mod_lshift_quick"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MOD_SQRT, 0), "BN_mod_sqrt"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MONT_CTX_NEW, 0), "BN_MONT_CTX_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_MPI2BN, 0), "BN_mpi2bn"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_NEW, 0), "BN_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_POOL_GET, 0), "BN_POOL_get"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_RAND, 0), "BN_rand"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_RAND_RANGE, 0), "BN_rand_range"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_RECP_CTX_NEW, 0), "BN_RECP_CTX_new"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_RSHIFT, 0), "BN_rshift"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_SET_WORDS, 0), "bn_set_words"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_STACK_PUSH, 0), "BN_STACK_push"}, - {ERR_PACK(ERR_LIB_BN, BN_F_BN_USUB, 0), "BN_usub"}, - {ERR_PACK(ERR_LIB_BN, BN_F_OSSL_BN_RSA_DO_UNBLIND, 0), - "ossl_bn_rsa_do_unblind"}, - {0, NULL} -}; - static const ERR_STRING_DATA BN_str_reasons[] = { {ERR_PACK(ERR_LIB_BN, 0, BN_R_ARG2_LT_ARG3), "arg2 lt arg3"}, {ERR_PACK(ERR_LIB_BN, 0, BN_R_BAD_RECIPROCAL), "bad reciprocal"}, @@ -96,7 +32,9 @@ static const ERR_STRING_DATA BN_str_reasons[] = { {ERR_PACK(ERR_LIB_BN, 0, BN_R_NOT_A_SQUARE), "not a square"}, {ERR_PACK(ERR_LIB_BN, 0, BN_R_NOT_INITIALIZED), "not initialized"}, {ERR_PACK(ERR_LIB_BN, 0, BN_R_NO_INVERSE), "no inverse"}, + {ERR_PACK(ERR_LIB_BN, 0, BN_R_NO_PRIME_CANDIDATE), "no prime candidate"}, {ERR_PACK(ERR_LIB_BN, 0, BN_R_NO_SOLUTION), "no solution"}, + {ERR_PACK(ERR_LIB_BN, 0, BN_R_NO_SUITABLE_DIGEST), "no suitable digest"}, {ERR_PACK(ERR_LIB_BN, 0, BN_R_PRIVATE_KEY_TOO_LARGE), "private key too large"}, {ERR_PACK(ERR_LIB_BN, 0, BN_R_P_IS_NOT_PRIME), "p is not prime"}, @@ -108,13 +46,11 @@ static const ERR_STRING_DATA BN_str_reasons[] = { #endif -int ERR_load_BN_strings(void) +int ossl_err_load_BN_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(BN_str_functs[0].error) == NULL) { - ERR_load_strings_const(BN_str_functs); + if (ERR_reason_error_string(BN_str_reasons[0].error) == NULL) ERR_load_strings_const(BN_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/bn/bn_exp.c b/crypto/openssl/crypto/bn/bn_exp.c index 517e3c29fc70..4e169ae1f9a4 100644 --- a/crypto/openssl/crypto/bn/bn_exp.c +++ b/crypto/openssl/crypto/bn/bn_exp.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -29,8 +29,7 @@ #undef SPARC_T4_MONT #if defined(OPENSSL_BN_ASM_MONT) && (defined(__sparc__) || defined(__sparc)) -# include "sparc_arch.h" -extern unsigned int OPENSSL_sparcv9cap_P[]; +# include "crypto/sparc_arch.h" # define SPARC_T4_MONT #endif @@ -55,7 +54,7 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 || BN_get_flags(a, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ - BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -181,7 +180,7 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ - BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -262,7 +261,6 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, * a window to do. To do this we need to scan forward until the last * set bit before the end of the window */ - j = wstart; wvalue = 1; wend = 0; for (i = 1; i < window; i++) { @@ -319,7 +317,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, bn_check_top(m); if (!BN_is_odd(m)) { - BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS); + ERR_raise(ERR_LIB_BN, BN_R_CALLED_WITH_EVEN_MODULUS); return 0; } @@ -421,7 +419,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, * a window to do. To do this we need to scan forward until the last * set bit before the end of the window */ - j = wstart; wvalue = 1; wend = 0; for (i = 1; i < window; i++) { @@ -623,7 +620,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, bn_check_top(m); if (!BN_is_odd(m)) { - BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS); + ERR_raise(ERR_LIB_BN, BN_R_CALLED_WITH_EVEN_MODULUS); return 0; } @@ -841,7 +838,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, /* * BN_to_montgomery can contaminate words above .top [in - * BN_DEBUG[_DEBUG] build]... + * BN_DEBUG build... */ for (i = am.top; i < top; i++) am.d[i] = 0; @@ -950,7 +947,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, /* * BN_to_montgomery can contaminate words above .top [in - * BN_DEBUG[_DEBUG] build]... + * BN_DEBUG build... */ for (i = am.top; i < top; i++) am.d[i] = 0; @@ -1184,7 +1181,7 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ - BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -1192,7 +1189,7 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, bn_check_top(m); if (!BN_is_odd(m)) { - BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS); + ERR_raise(ERR_LIB_BN, BN_R_CALLED_WITH_EVEN_MODULUS); return 0; } if (m->top == 1) @@ -1316,7 +1313,7 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ - BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -1383,7 +1380,6 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, * a window to do. To do this we need to scan forward until the last * set bit before the end of the window */ - j = wstart; wvalue = 1; wend = 0; for (i = 1; i < window; i++) { @@ -1422,3 +1418,85 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, bn_check_top(r); return ret; } + +/* + * This is a variant of modular exponentiation optimization that does + * parallel 2-primes exponentiation using 256-bit (AVX512VL) AVX512_IFMA ISA + * in 52-bit binary redundant representation. + * If such instructions are not available, or input data size is not supported, + * it falls back to two BN_mod_exp_mont_consttime() calls. + */ +int BN_mod_exp_mont_consttime_x2(BIGNUM *rr1, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *m1, BN_MONT_CTX *in_mont1, + BIGNUM *rr2, const BIGNUM *a2, const BIGNUM *p2, + const BIGNUM *m2, BN_MONT_CTX *in_mont2, + BN_CTX *ctx) +{ + int ret = 0; + +#ifdef RSAZ_ENABLED + BN_MONT_CTX *mont1 = NULL; + BN_MONT_CTX *mont2 = NULL; + + if (ossl_rsaz_avx512ifma_eligible() && + ((a1->top == 16) && (p1->top == 16) && (BN_num_bits(m1) == 1024) && + (a2->top == 16) && (p2->top == 16) && (BN_num_bits(m2) == 1024))) { + + if (bn_wexpand(rr1, 16) == NULL) + goto err; + if (bn_wexpand(rr2, 16) == NULL) + goto err; + + /* Ensure that montgomery contexts are initialized */ + if (in_mont1 != NULL) { + mont1 = in_mont1; + } else { + if ((mont1 = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont1, m1, ctx)) + goto err; + } + if (in_mont2 != NULL) { + mont2 = in_mont2; + } else { + if ((mont2 = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont2, m2, ctx)) + goto err; + } + + ret = ossl_rsaz_mod_exp_avx512_x2(rr1->d, a1->d, p1->d, m1->d, + mont1->RR.d, mont1->n0[0], + rr2->d, a2->d, p2->d, m2->d, + mont2->RR.d, mont2->n0[0], + 1024 /* factor bit size */); + + rr1->top = 16; + rr1->neg = 0; + bn_correct_top(rr1); + bn_check_top(rr1); + + rr2->top = 16; + rr2->neg = 0; + bn_correct_top(rr2); + bn_check_top(rr2); + + goto err; + } +#endif + + /* rr1 = a1^p1 mod m1 */ + ret = BN_mod_exp_mont_consttime(rr1, a1, p1, m1, ctx, in_mont1); + /* rr2 = a2^p2 mod m2 */ + ret &= BN_mod_exp_mont_consttime(rr2, a2, p2, m2, ctx, in_mont2); + +#ifdef RSAZ_ENABLED +err: + if (in_mont2 == NULL) + BN_MONT_CTX_free(mont2); + if (in_mont1 == NULL) + BN_MONT_CTX_free(mont1); +#endif + + return ret; +} diff --git a/crypto/openssl/crypto/bn/bn_exp2.c b/crypto/openssl/crypto/bn/bn_exp2.c index eac0896e6869..f5e29fd14de3 100644 --- a/crypto/openssl/crypto/bn/bn_exp2.c +++ b/crypto/openssl/crypto/bn/bn_exp2.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -33,7 +33,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1, bn_check_top(m); if (!BN_is_odd(m)) { - BNerr(BN_F_BN_MOD_EXP2_MONT, BN_R_CALLED_WITH_EVEN_MODULUS); + ERR_raise(ERR_LIB_BN, BN_R_CALLED_WITH_EVEN_MODULUS); return 0; } bits1 = BN_num_bits(p1); diff --git a/crypto/openssl/crypto/bn/bn_gcd.c b/crypto/openssl/crypto/bn/bn_gcd.c index 6190bf1eddb0..59d024f674eb 100644 --- a/crypto/openssl/crypto/bn/bn_gcd.c +++ b/crypto/openssl/crypto/bn/bn_gcd.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -520,16 +520,16 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, int noinv = 0; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(NULL); if (ctx == NULL) { - BNerr(BN_F_BN_MOD_INVERSE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); return NULL; } } rv = int_bn_mod_inverse(in, a, n, ctx, &noinv); if (noinv) - BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE); + ERR_raise(ERR_LIB_BN, BN_R_NO_INVERSE); BN_CTX_free(new_ctx); return rv; } diff --git a/crypto/openssl/crypto/bn/bn_gf2m.c b/crypto/openssl/crypto/bn/bn_gf2m.c index a2ea86755182..304c2ea08d0e 100644 --- a/crypto/openssl/crypto/bn/bn_gf2m.c +++ b/crypto/openssl/crypto/bn/bn_gf2m.c @@ -1,8 +1,8 @@ /* - * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2021 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 + * 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 @@ -297,7 +297,7 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]) bn_check_top(a); - if (!p[0]) { + if (p[0] == 0) { /* reduction mod 1 => return 0 */ BN_zero(r); return 1; @@ -395,7 +395,7 @@ int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p) bn_check_top(p); ret = BN_GF2m_poly2arr(p, arr, OSSL_NELEM(arr)); if (!ret || ret > (int)OSSL_NELEM(arr)) { - BNerr(BN_F_BN_GF2M_MOD, BN_R_INVALID_LENGTH); + ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); return 0; } ret = BN_GF2m_mod_arr(r, a, arr); @@ -467,15 +467,20 @@ int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, { int ret = 0; const int max = BN_num_bits(p) + 1; - int *arr = NULL; + int *arr; + bn_check_top(a); bn_check_top(b); bn_check_top(p); - if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL) - goto err; + + arr = OPENSSL_malloc(sizeof(*arr) * max); + if (arr == NULL) { + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + return 0; + } ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { - BNerr(BN_F_BN_GF2M_MOD_MUL, BN_R_INVALID_LENGTH); + ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); goto err; } ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx); @@ -525,15 +530,19 @@ int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { int ret = 0; const int max = BN_num_bits(p) + 1; - int *arr = NULL; + int *arr; bn_check_top(a); bn_check_top(p); - if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL) - goto err; + + arr = OPENSSL_malloc(sizeof(*arr) * max); + if (arr == NULL) { + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + return 0; + } ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { - BNerr(BN_F_BN_GF2M_MOD_SQR, BN_R_INVALID_LENGTH); + ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); goto err; } ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx); @@ -706,8 +715,8 @@ static int BN_GF2m_mod_inv_vartime(BIGNUM *r, const BIGNUM *a, ret = 1; err: -# ifdef BN_DEBUG /* BN_CTX_end would complain about the - * expanded form */ +# ifdef BN_DEBUG + /* BN_CTX_end would complain about the expanded form */ bn_correct_top(c); bn_correct_top(u); bn_correct_top(v); @@ -732,8 +741,8 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) /* generate blinding value */ do { - if (!BN_priv_rand(b, BN_num_bits(p) - 1, - BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(b, BN_num_bits(p) - 1, + BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, 0, ctx)) goto err; } while (BN_is_zero(b)); @@ -899,15 +908,20 @@ int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, { int ret = 0; const int max = BN_num_bits(p) + 1; - int *arr = NULL; + int *arr; + bn_check_top(a); bn_check_top(b); bn_check_top(p); - if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL) - goto err; + + arr = OPENSSL_malloc(sizeof(*arr) * max); + if (arr == NULL) { + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + return 0; + } ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { - BNerr(BN_F_BN_GF2M_MOD_EXP, BN_R_INVALID_LENGTH); + ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); goto err; } ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx); @@ -929,7 +943,7 @@ int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], bn_check_top(a); - if (!p[0]) { + if (p[0] == 0) { /* reduction mod 1 => return 0 */ BN_zero(r); return 1; @@ -959,14 +973,19 @@ int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { int ret = 0; const int max = BN_num_bits(p) + 1; - int *arr = NULL; + int *arr; + bn_check_top(a); bn_check_top(p); - if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL) - goto err; + + arr = OPENSSL_malloc(sizeof(*arr) * max); + if (arr == NULL) { + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + return 0; + } ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { - BNerr(BN_F_BN_GF2M_MOD_SQRT, BN_R_INVALID_LENGTH); + ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); goto err; } ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx); @@ -988,7 +1007,7 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], bn_check_top(a_); - if (!p[0]) { + if (p[0] == 0) { /* reduction mod 1 => return 0 */ BN_zero(r); return 1; @@ -1031,7 +1050,8 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], if (tmp == NULL) goto err; do { - if (!BN_priv_rand(rho, p[0], BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(rho, p[0], BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY, + 0, ctx)) goto err; if (!BN_GF2m_mod_arr(rho, rho, p)) goto err; @@ -1053,7 +1073,7 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], count++; } while (BN_is_zero(w) && (count < MAX_ITERATIONS)); if (BN_is_zero(w)) { - BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_TOO_MANY_ITERATIONS); + ERR_raise(ERR_LIB_BN, BN_R_TOO_MANY_ITERATIONS); goto err; } } @@ -1063,7 +1083,7 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], if (!BN_GF2m_add(w, z, w)) goto err; if (BN_GF2m_cmp(w, a)) { - BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION); + ERR_raise(ERR_LIB_BN, BN_R_NO_SOLUTION); goto err; } @@ -1089,14 +1109,19 @@ int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, { int ret = 0; const int max = BN_num_bits(p) + 1; - int *arr = NULL; + int *arr; + bn_check_top(a); bn_check_top(p); - if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL) + + arr = OPENSSL_malloc(sizeof(*arr) * max); + if (arr == NULL) { + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); goto err; + } ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { - BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD, BN_R_INVALID_LENGTH); + ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); goto err; } ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx); diff --git a/crypto/openssl/crypto/bn/bn_intern.c b/crypto/openssl/crypto/bn/bn_intern.c index 147b4fa022cf..c0f7f5fea604 100644 --- a/crypto/openssl/crypto/bn/bn_intern.c +++ b/crypto/openssl/crypto/bn/bn_intern.c @@ -1,7 +1,7 @@ /* - * Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -30,7 +30,7 @@ signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) if (BN_is_zero(scalar)) { r = OPENSSL_malloc(1); if (r == NULL) { - BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); goto err; } r[0] = 0; @@ -40,7 +40,7 @@ signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) if (w <= 0 || w > 7) { /* 'signed char' can represent integers with * absolute values less than 2^7 */ - BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); goto err; } bit = 1 << w; /* at most 128 */ @@ -52,7 +52,7 @@ signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) } if (scalar->d == NULL || scalar->top == 0) { - BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); goto err; } @@ -63,7 +63,7 @@ signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) * BN_num_bits(scalar) + 1) */ if (r == NULL) { - BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); goto err; } window_val = scalar->d[0] & mask; @@ -98,7 +98,7 @@ signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) } if (digit <= -bit || digit >= bit || !(digit & 1)) { - BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); goto err; } @@ -110,7 +110,7 @@ signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) */ if (window_val != 0 && window_val != next_bit && window_val != bit) { - BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); goto err; } } @@ -121,13 +121,13 @@ signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) window_val += bit * BN_is_bit_set(scalar, j + w); if (window_val > next_bit) { - BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); goto err; } } if (j > len + 1) { - BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_BN, ERR_R_INTERNAL_ERROR); goto err; } *ret_len = j; @@ -188,7 +188,7 @@ void bn_set_static_words(BIGNUM *a, const BN_ULONG *words, int size) int bn_set_words(BIGNUM *a, const BN_ULONG *words, int num_words) { if (bn_wexpand(a, num_words) == NULL) { - BNerr(BN_F_BN_SET_WORDS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/crypto/openssl/crypto/bn/bn_kron.c b/crypto/openssl/crypto/bn/bn_kron.c index c1e09d272120..8258536dcace 100644 --- a/crypto/openssl/crypto/bn/bn_kron.c +++ b/crypto/openssl/crypto/bn/bn_kron.c @@ -1,7 +1,7 @@ /* * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bn/bn_lib.c b/crypto/openssl/crypto/bn/bn_lib.c index eb4a31849bef..7ad6842560b4 100644 --- a/crypto/openssl/crypto/bn/bn_lib.c +++ b/crypto/openssl/crypto/bn/bn_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,12 +10,13 @@ #include #include #include "internal/cryptlib.h" +#include "internal/endian.h" #include "bn_local.h" #include #include "internal/constant_time.h" /* This stuff appears to be completely unused, so is deprecated */ -#if OPENSSL_API_COMPAT < 0x00908000L +#ifndef OPENSSL_NO_DEPRECATED_0_9_8 /*- * For a 32 bit machine * 2 - 4 == 128 @@ -244,7 +245,7 @@ BIGNUM *BN_new(void) BIGNUM *ret; if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); return NULL; } ret->flags = BN_FLG_MALLOCED; @@ -267,11 +268,11 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) BN_ULONG *a = NULL; if (words > (INT_MAX / (4 * BN_BITS2))) { - BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG); + ERR_raise(ERR_LIB_BN, BN_R_BIGNUM_TOO_LONG); return NULL; } if (BN_get_flags(b, BN_FLG_STATIC_DATA)) { - BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); + ERR_raise(ERR_LIB_BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); return NULL; } if (BN_get_flags(b, BN_FLG_SECURE)) @@ -279,7 +280,7 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) else a = OPENSSL_zalloc(words * sizeof(*a)); if (a == NULL) { - BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); return NULL; } @@ -504,7 +505,8 @@ int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianess_t endiane /* Swipe through whole available data and don't give away padded zero. */ atop = a->dmax * BN_BYTES; if (atop == 0) { - OPENSSL_cleanse(to, tolen); + if (tolen != 0) + memset(to, '\0', tolen); return tolen; } @@ -593,6 +595,24 @@ int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen) return bn2binpad(a, to, tolen, little); } +BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret) +{ + DECLARE_IS_ENDIAN; + + if (IS_LITTLE_ENDIAN) + return BN_lebin2bn(s, len, ret); + return BN_bin2bn(s, len, ret); +} + +int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen) +{ + DECLARE_IS_ENDIAN; + + if (IS_LITTLE_ENDIAN) + return BN_bn2lebinpad(a, to, tolen); + return BN_bn2binpad(a, to, tolen); +} + int BN_ucmp(const BIGNUM *a, const BIGNUM *b) { int i; @@ -947,7 +967,7 @@ BN_GENCB *BN_GENCB_new(void) BN_GENCB *ret; if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { - BNerr(BN_F_BN_GENCB_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/openssl/crypto/bn/bn_local.h b/crypto/openssl/crypto/bn/bn_local.h index 30b7614fdbb2..2cc445607e18 100644 --- a/crypto/openssl/crypto/bn/bn_local.h +++ b/crypto/openssl/crypto/bn/bn_local.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -22,18 +22,25 @@ # endif # include "crypto/bn.h" +# include "internal/cryptlib.h" +# include "internal/numbers.h" /* * These preprocessor symbols control various aspects of the bignum headers * and library code. They're not defined by any "normal" configuration, as - * they are intended for development and testing purposes. NB: defining all - * three can be useful for debugging application code as well as openssl + * they are intended for development and testing purposes. NB: defining + * them can be useful for debugging application code as well as openssl * itself. BN_DEBUG - turn on various debugging alterations to the bignum - * code BN_DEBUG_RAND - uses random poisoning of unused words to trip up - * mismanagement of bignum internals. You must also define BN_DEBUG. + * code BN_RAND_DEBUG - uses random poisoning of unused words to trip up + * mismanagement of bignum internals. Enable BN_RAND_DEBUG is known to + * break some of the OpenSSL tests. */ -/* #define BN_DEBUG */ -/* #define BN_DEBUG_RAND */ +# if defined(BN_RAND_DEBUG) && !defined(BN_DEBUG) +# define BN_DEBUG +# endif +# if defined(BN_RAND_DEBUG) +# include +# endif /* * This should limit the stack usage due to alloca to about 4K. @@ -145,7 +152,7 @@ * bn_check_top() is as before. * - if BN_DEBUG *is* defined; * - bn_check_top() tries to pollute unused words even if the bignum 'top' is - * consistent. (ed: only if BN_DEBUG_RAND is defined) + * consistent. (ed: only if BN_RAND_DEBUG is defined) * - bn_fix_top() maps to bn_check_top() rather than "fixing" anything. * The idea is to have debug builds flag up inconsistent bignums when they * occur. If that occurs in a bn_fix_top(), we examine the code in question; if @@ -171,7 +178,7 @@ * all operations manipulating the bit in question in non-BN_DEBUG build. */ # define BN_FLG_FIXED_TOP 0x10000 -# ifdef BN_DEBUG_RAND +# ifdef BN_RAND_DEBUG # define bn_pollute(a) \ do { \ const BIGNUM *_bnum1 = (a); \ @@ -182,7 +189,7 @@ * wouldn't be constructed with top!=dmax. */ \ BN_ULONG *_not_const; \ memcpy(&_not_const, &_bnum1->d, sizeof(_not_const)); \ - RAND_bytes(&_tmp_char, 1); /* Debug only - safe to ignore error return */\ + (void)RAND_bytes(&_tmp_char, 1); /* Debug only - safe to ignore error return */\ memset(_not_const + _bnum1->top, _tmp_char, \ sizeof(*_not_const) * (_bnum1->dmax - _bnum1->top)); \ } \ @@ -408,9 +415,9 @@ struct bn_blinding_st { */ # if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16 && \ (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)) -# define BN_UMULT_HIGH(a,b) (((__uint128_t)(a)*(b))>>64) +# define BN_UMULT_HIGH(a,b) (((uint128_t)(a)*(b))>>64) # define BN_UMULT_LOHI(low,high,a,b) ({ \ - __uint128_t ret=(__uint128_t)(a)*(b); \ + uint128_t ret=(uint128_t)(a)*(b); \ (high)=ret>>64; (low)=ret; }) # elif defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT)) # if defined(__DECC) @@ -483,7 +490,7 @@ unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b, # endif /* cpu */ # endif /* OPENSSL_NO_ASM */ -# ifdef BN_DEBUG_RAND +# ifdef BN_RAND_DEBUG # define bn_clear_top2max(a) \ { \ int ind = (a)->dmax - (a)->top; \ @@ -699,4 +706,7 @@ static ossl_inline BIGNUM *bn_expand(BIGNUM *a, int bits) return bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2); } +int ossl_bn_check_prime(const BIGNUM *w, int checks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb); + #endif diff --git a/crypto/openssl/crypto/bn/bn_mod.c b/crypto/openssl/crypto/bn/bn_mod.c index f7d2e2650ed8..7f5afa25ecc8 100644 --- a/crypto/openssl/crypto/bn/bn_mod.c +++ b/crypto/openssl/crypto/bn/bn_mod.c @@ -1,7 +1,7 @@ /* - * Copyright 1998-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -56,9 +56,13 @@ int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, if (bn_wexpand(r, mtop) == NULL) return 0; - if (mtop > sizeof(storage) / sizeof(storage[0]) - && (tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG))) == NULL) - return 0; + if (mtop > sizeof(storage) / sizeof(storage[0])) { + tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG)); + if (tp == NULL) { + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + return 0; + } + } ap = a->d != NULL ? a->d : tp; bp = b->d != NULL ? b->d : tp; @@ -291,7 +295,7 @@ int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) /* max_shift >= 0 */ if (max_shift < 0) { - BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED); + ERR_raise(ERR_LIB_BN, BN_R_INPUT_NOT_REDUCED); return 0; } diff --git a/crypto/openssl/crypto/bn/bn_mont.c b/crypto/openssl/crypto/bn/bn_mont.c index 7617b0df5e70..1c5d66bbf863 100644 --- a/crypto/openssl/crypto/bn/bn_mont.c +++ b/crypto/openssl/crypto/bn/bn_mont.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -230,7 +230,7 @@ BN_MONT_CTX *BN_MONT_CTX_new(void) BN_MONT_CTX *ret; if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { - BNerr(BN_F_BN_MONT_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); return NULL; } @@ -430,14 +430,15 @@ BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_RWLOCK *lock, { BN_MONT_CTX *ret; - CRYPTO_THREAD_read_lock(lock); + if (!CRYPTO_THREAD_read_lock(lock)) + return NULL; ret = *pmont; CRYPTO_THREAD_unlock(lock); if (ret) return ret; /* - * We don't want to serialise globally while doing our lazy-init math in + * We don't want to serialize globally while doing our lazy-init math in * BN_MONT_CTX_set. That punishes threads that are doing independent * things. Instead, punish the case where more than one thread tries to * lazy-init the same 'pmont', by having each do the lazy-init math work @@ -453,7 +454,11 @@ BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_RWLOCK *lock, } /* The locked compare-and-set, after the local work is done. */ - CRYPTO_THREAD_write_lock(lock); + if (!CRYPTO_THREAD_write_lock(lock)) { + BN_MONT_CTX_free(ret); + return NULL; + } + if (*pmont) { BN_MONT_CTX_free(ret); ret = *pmont; diff --git a/crypto/openssl/crypto/bn/bn_mpi.c b/crypto/openssl/crypto/bn/bn_mpi.c index 0902da5d076e..4eba0ae57002 100644 --- a/crypto/openssl/crypto/bn/bn_mpi.c +++ b/crypto/openssl/crypto/bn/bn_mpi.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -46,13 +46,13 @@ BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain) BIGNUM *a = NULL; if (n < 4 || (d[0] & 0x80) != 0) { - BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH); + ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); return NULL; } len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int) d[3]; if ((len + 4) != n) { - BNerr(BN_F_BN_MPI2BN, BN_R_ENCODING_ERROR); + ERR_raise(ERR_LIB_BN, BN_R_ENCODING_ERROR); return NULL; } diff --git a/crypto/openssl/crypto/bn/bn_mul.c b/crypto/openssl/crypto/bn/bn_mul.c index 6743e7be8166..dc6b6f5a1215 100644 --- a/crypto/openssl/crypto/bn/bn_mul.c +++ b/crypto/openssl/crypto/bn/bn_mul.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bn/bn_nist.c b/crypto/openssl/crypto/bn/bn_nist.c index c29e62ed3fef..da10c4054a3e 100644 --- a/crypto/openssl/crypto/bn/bn_nist.c +++ b/crypto/openssl/crypto/bn/bn_nist.c @@ -1,7 +1,7 @@ /* * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -184,7 +184,7 @@ static const BN_ULONG _nist_p_521_sqr[] = { # error "unsupported BN_BITS2" #endif -static const BIGNUM _bignum_nist_p_192 = { +static const BIGNUM ossl_bignum_nist_p_192 = { (BN_ULONG *)_nist_p_192[0], BN_NIST_192_TOP, BN_NIST_192_TOP, @@ -192,7 +192,7 @@ static const BIGNUM _bignum_nist_p_192 = { BN_FLG_STATIC_DATA }; -static const BIGNUM _bignum_nist_p_224 = { +static const BIGNUM ossl_bignum_nist_p_224 = { (BN_ULONG *)_nist_p_224[0], BN_NIST_224_TOP, BN_NIST_224_TOP, @@ -200,7 +200,7 @@ static const BIGNUM _bignum_nist_p_224 = { BN_FLG_STATIC_DATA }; -static const BIGNUM _bignum_nist_p_256 = { +static const BIGNUM ossl_bignum_nist_p_256 = { (BN_ULONG *)_nist_p_256[0], BN_NIST_256_TOP, BN_NIST_256_TOP, @@ -208,7 +208,7 @@ static const BIGNUM _bignum_nist_p_256 = { BN_FLG_STATIC_DATA }; -static const BIGNUM _bignum_nist_p_384 = { +static const BIGNUM ossl_bignum_nist_p_384 = { (BN_ULONG *)_nist_p_384[0], BN_NIST_384_TOP, BN_NIST_384_TOP, @@ -216,7 +216,7 @@ static const BIGNUM _bignum_nist_p_384 = { BN_FLG_STATIC_DATA }; -static const BIGNUM _bignum_nist_p_521 = { +static const BIGNUM ossl_bignum_nist_p_521 = { (BN_ULONG *)_nist_p_521, BN_NIST_521_TOP, BN_NIST_521_TOP, @@ -226,27 +226,27 @@ static const BIGNUM _bignum_nist_p_521 = { const BIGNUM *BN_get0_nist_prime_192(void) { - return &_bignum_nist_p_192; + return &ossl_bignum_nist_p_192; } const BIGNUM *BN_get0_nist_prime_224(void) { - return &_bignum_nist_p_224; + return &ossl_bignum_nist_p_224; } const BIGNUM *BN_get0_nist_prime_256(void) { - return &_bignum_nist_p_256; + return &ossl_bignum_nist_p_256; } const BIGNUM *BN_get0_nist_prime_384(void) { - return &_bignum_nist_p_384; + return &ossl_bignum_nist_p_384; } const BIGNUM *BN_get0_nist_prime_521(void) { - return &_bignum_nist_p_521; + return &ossl_bignum_nist_p_521; } /* @@ -339,16 +339,16 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, } buf; BN_ULONG c_d[BN_NIST_192_TOP], *res; PTR_SIZE_INT mask; - static const BIGNUM _bignum_nist_p_192_sqr = { + static const BIGNUM ossl_bignum_nist_p_192_sqr = { (BN_ULONG *)_nist_p_192_sqr, OSSL_NELEM(_nist_p_192_sqr), OSSL_NELEM(_nist_p_192_sqr), 0, BN_FLG_STATIC_DATA }; - field = &_bignum_nist_p_192; /* just to make sure */ + field = &ossl_bignum_nist_p_192; /* just to make sure */ - if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_192_sqr) >= 0) + if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_192_sqr) >= 0) return BN_nnmod(r, a, field, ctx); i = BN_ucmp(field, a); @@ -484,16 +484,16 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, bn_addsub_f f; PTR_SIZE_INT p; } u; - static const BIGNUM _bignum_nist_p_224_sqr = { + static const BIGNUM ossl_bignum_nist_p_224_sqr = { (BN_ULONG *)_nist_p_224_sqr, OSSL_NELEM(_nist_p_224_sqr), OSSL_NELEM(_nist_p_224_sqr), 0, BN_FLG_STATIC_DATA }; - field = &_bignum_nist_p_224; /* just to make sure */ + field = &ossl_bignum_nist_p_224; /* just to make sure */ - if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_224_sqr) >= 0) + if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_224_sqr) >= 0) return BN_nnmod(r, a, field, ctx); i = BN_ucmp(field, a); @@ -665,16 +665,16 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, bn_addsub_f f; PTR_SIZE_INT p; } u; - static const BIGNUM _bignum_nist_p_256_sqr = { + static const BIGNUM ossl_bignum_nist_p_256_sqr = { (BN_ULONG *)_nist_p_256_sqr, OSSL_NELEM(_nist_p_256_sqr), OSSL_NELEM(_nist_p_256_sqr), 0, BN_FLG_STATIC_DATA }; - field = &_bignum_nist_p_256; /* just to make sure */ + field = &ossl_bignum_nist_p_256; /* just to make sure */ - if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_256_sqr) >= 0) + if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_256_sqr) >= 0) return BN_nnmod(r, a, field, ctx); i = BN_ucmp(field, a); @@ -911,16 +911,16 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, bn_addsub_f f; PTR_SIZE_INT p; } u; - static const BIGNUM _bignum_nist_p_384_sqr = { + static const BIGNUM ossl_bignum_nist_p_384_sqr = { (BN_ULONG *)_nist_p_384_sqr, OSSL_NELEM(_nist_p_384_sqr), OSSL_NELEM(_nist_p_384_sqr), 0, BN_FLG_STATIC_DATA }; - field = &_bignum_nist_p_384; /* just to make sure */ + field = &ossl_bignum_nist_p_384; /* just to make sure */ - if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_384_sqr) >= 0) + if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_384_sqr) >= 0) return BN_nnmod(r, a, field, ctx); i = BN_ucmp(field, a); @@ -1169,16 +1169,16 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, int top = a->top, i; BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res; PTR_SIZE_INT mask; - static const BIGNUM _bignum_nist_p_521_sqr = { + static const BIGNUM ossl_bignum_nist_p_521_sqr = { (BN_ULONG *)_nist_p_521_sqr, OSSL_NELEM(_nist_p_521_sqr), OSSL_NELEM(_nist_p_521_sqr), 0, BN_FLG_STATIC_DATA }; - field = &_bignum_nist_p_521; /* just to make sure */ + field = &ossl_bignum_nist_p_521; /* just to make sure */ - if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_521_sqr) >= 0) + if (BN_is_negative(a) || BN_ucmp(a, &ossl_bignum_nist_p_521_sqr) >= 0) return BN_nnmod(r, a, field, ctx); i = BN_ucmp(field, a); @@ -1236,15 +1236,15 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, int (*BN_nist_mod_func(const BIGNUM *p)) (BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx) { - if (BN_ucmp(&_bignum_nist_p_192, p) == 0) + if (BN_ucmp(&ossl_bignum_nist_p_192, p) == 0) return BN_nist_mod_192; - if (BN_ucmp(&_bignum_nist_p_224, p) == 0) + if (BN_ucmp(&ossl_bignum_nist_p_224, p) == 0) return BN_nist_mod_224; - if (BN_ucmp(&_bignum_nist_p_256, p) == 0) + if (BN_ucmp(&ossl_bignum_nist_p_256, p) == 0) return BN_nist_mod_256; - if (BN_ucmp(&_bignum_nist_p_384, p) == 0) + if (BN_ucmp(&ossl_bignum_nist_p_384, p) == 0) return BN_nist_mod_384; - if (BN_ucmp(&_bignum_nist_p_521, p) == 0) + if (BN_ucmp(&ossl_bignum_nist_p_521, p) == 0) return BN_nist_mod_521; return 0; } diff --git a/crypto/openssl/crypto/bn/bn_ppc.c b/crypto/openssl/crypto/bn/bn_ppc.c new file mode 100644 index 000000000000..3ee76ea96574 --- /dev/null +++ b/crypto/openssl/crypto/bn/bn_ppc.c @@ -0,0 +1,38 @@ +/* + * Copyright 2009-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/ppc_arch.h" +#include "bn_local.h" + +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num) +{ + int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); + int bn_mul4x_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); + + if (num < 4) + return 0; + + if ((num & 3) == 0) + return bn_mul4x_mont_int(rp, ap, bp, np, n0, num); + + /* + * There used to be [optional] call to bn_mul_mont_fpu64 here, + * but above subroutine is faster on contemporary processors. + * Formulation means that there might be old processors where + * FPU code path would be faster, POWER6 perhaps, but there was + * no opportunity to figure it out... + */ + + return bn_mul_mont_int(rp, ap, bp, np, n0, num); +} diff --git a/crypto/openssl/crypto/bn/bn_prime.c b/crypto/openssl/crypto/bn/bn_prime.c index d0cf3779fa50..ddd31a025254 100644 --- a/crypto/openssl/crypto/bn/bn_prime.c +++ b/crypto/openssl/crypto/bn/bn_prime.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,16 +19,85 @@ */ #include "bn_prime.h" -static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, - const BIGNUM *a1_odd, int k, BN_CTX *ctx, - BN_MONT_CTX *mont); -static int probable_prime(BIGNUM *rnd, int bits, int safe, prime_t *mods); +static int probable_prime(BIGNUM *rnd, int bits, int safe, prime_t *mods, + BN_CTX *ctx); static int probable_prime_dh(BIGNUM *rnd, int bits, int safe, prime_t *mods, const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); +static int bn_is_prime_int(const BIGNUM *w, int checks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb); #define square(x) ((BN_ULONG)(x) * (BN_ULONG)(x)) +#if BN_BITS2 == 64 +# define BN_DEF(lo, hi) (BN_ULONG)hi<<32|lo +#else +# define BN_DEF(lo, hi) lo, hi +#endif + +/* + * See SP800 89 5.3.3 (Step f) + * The product of the set of primes ranging from 3 to 751 + * Generated using process in test/bn_internal_test.c test_bn_small_factors(). + * This includes 751 (which is not currently included in SP 800-89). + */ +static const BN_ULONG small_prime_factors[] = { + BN_DEF(0x3ef4e3e1, 0xc4309333), BN_DEF(0xcd2d655f, 0x71161eb6), + BN_DEF(0x0bf94862, 0x95e2238c), BN_DEF(0x24f7912b, 0x3eb233d3), + BN_DEF(0xbf26c483, 0x6b55514b), BN_DEF(0x5a144871, 0x0a84d817), + BN_DEF(0x9b82210a, 0x77d12fee), BN_DEF(0x97f050b3, 0xdb5b93c2), + BN_DEF(0x4d6c026b, 0x4acad6b9), BN_DEF(0x54aec893, 0xeb7751f3), + BN_DEF(0x36bc85c4, 0xdba53368), BN_DEF(0x7f5ec78e, 0xd85a1b28), + BN_DEF(0x6b322244, 0x2eb072d8), BN_DEF(0x5e2b3aea, 0xbba51112), + BN_DEF(0x0e2486bf, 0x36ed1a6c), BN_DEF(0xec0c5727, 0x5f270460), + (BN_ULONG)0x000017b1 +}; + +#define BN_SMALL_PRIME_FACTORS_TOP OSSL_NELEM(small_prime_factors) +static const BIGNUM _bignum_small_prime_factors = { + (BN_ULONG *)small_prime_factors, + BN_SMALL_PRIME_FACTORS_TOP, + BN_SMALL_PRIME_FACTORS_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +const BIGNUM *ossl_bn_get0_small_factors(void) +{ + return &_bignum_small_prime_factors; +} + +/* + * Calculate the number of trial divisions that gives the best speed in + * combination with Miller-Rabin prime test, based on the sized of the prime. + */ +static int calc_trial_divisions(int bits) +{ + if (bits <= 512) + return 64; + else if (bits <= 1024) + return 128; + else if (bits <= 2048) + return 384; + else if (bits <= 4096) + return 1024; + return NUMPRIMES; +} + +/* + * Use a minimum of 64 rounds of Miller-Rabin, which should give a false + * positive rate of 2^-128. If the size of the prime is larger than 2048 + * the user probably wants a higher security level than 128, so switch + * to 128 rounds giving a false positive rate of 2^-256. + * Returns the number of rounds. + */ +static int bn_mr_min_checks(int bits) +{ + if (bits > 2048) + return 128; + return 64; +} + int BN_GENCB_call(BN_GENCB *cb, int a, int b) { /* No callback means continue */ @@ -51,19 +120,19 @@ int BN_GENCB_call(BN_GENCB *cb, int a, int b) return 0; } -int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, - const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) +int BN_generate_prime_ex2(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb, + BN_CTX *ctx) { BIGNUM *t; int found = 0; int i, j, c1 = 0; - BN_CTX *ctx = NULL; prime_t *mods = NULL; - int checks = BN_prime_checks_for_size(bits); + int checks = bn_mr_min_checks(bits); if (bits < 2) { /* There are no prime numbers this small. */ - BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL); + ERR_raise(ERR_LIB_BN, BN_R_BITS_TOO_SMALL); return 0; } else if (add == NULL && safe && bits < 6 && bits != 3) { /* @@ -71,17 +140,16 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, * But the following two safe primes with less than 6 bits (11, 23) * are unreachable for BN_rand with BN_RAND_TOP_TWO. */ - BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL); + ERR_raise(ERR_LIB_BN, BN_R_BITS_TOO_SMALL); return 0; } mods = OPENSSL_zalloc(sizeof(*mods) * NUMPRIMES); - if (mods == NULL) - goto err; + if (mods == NULL) { + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + return 0; + } - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; BN_CTX_start(ctx); t = BN_CTX_get(ctx); if (t == NULL) @@ -89,7 +157,7 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, loop: /* make a random number and set the top and bottom bits */ if (add == NULL) { - if (!probable_prime(ret, bits, safe, mods)) + if (!probable_prime(ret, bits, safe, mods, ctx)) goto err; } else { if (!probable_prime_dh(ret, bits, safe, mods, add, rem, ctx)) @@ -101,7 +169,7 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, goto err; if (!safe) { - i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb); + i = bn_is_prime_int(ret, checks, ctx, 0, cb); if (i == -1) goto err; if (i == 0) @@ -115,13 +183,13 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, goto err; for (i = 0; i < checks; i++) { - j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb); + j = bn_is_prime_int(ret, 1, ctx, 0, cb); if (j == -1) goto err; if (j == 0) goto loop; - j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb); + j = bn_is_prime_int(t, 1, ctx, 0, cb); if (j == -1) goto err; if (j == 0) @@ -137,152 +205,292 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, err: OPENSSL_free(mods); BN_CTX_end(ctx); - BN_CTX_free(ctx); bn_check_top(ret); return found; } +#ifndef FIPS_MODULE +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) +{ + BN_CTX *ctx = BN_CTX_new(); + int retval; + + if (ctx == NULL) + return 0; + + retval = BN_generate_prime_ex2(ret, bits, safe, add, rem, cb, ctx); + + BN_CTX_free(ctx); + return retval; +} +#endif + +#ifndef OPENSSL_NO_DEPRECATED_3_0 int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb) { - return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb); + return ossl_bn_check_prime(a, checks, ctx_passed, 0, cb); } -int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, +int BN_is_prime_fasttest_ex(const BIGNUM *w, int checks, BN_CTX *ctx, int do_trial_division, BN_GENCB *cb) { - int i, j, ret = -1; - int k; - BN_CTX *ctx = NULL; - BIGNUM *A1, *A1_odd, *A3, *check; /* taken from ctx */ - BN_MONT_CTX *mont = NULL; + return ossl_bn_check_prime(w, checks, ctx, do_trial_division, cb); +} +#endif - /* Take care of the really small primes 2 & 3 */ - if (BN_is_word(a, 2) || BN_is_word(a, 3)) - return 1; +/* Wrapper around bn_is_prime_int that sets the minimum number of checks */ +int ossl_bn_check_prime(const BIGNUM *w, int checks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb) +{ + int min_checks = bn_mr_min_checks(BN_num_bits(w)); + + if (checks < min_checks) + checks = min_checks; + + return bn_is_prime_int(w, checks, ctx, do_trial_division, cb); +} + +int BN_check_prime(const BIGNUM *p, BN_CTX *ctx, BN_GENCB *cb) +{ + return ossl_bn_check_prime(p, 0, ctx, 1, cb); +} + +/* + * Tests that |w| is probably prime + * See FIPS 186-4 C.3.1 Miller Rabin Probabilistic Primality Test. + * + * Returns 0 when composite, 1 when probable prime, -1 on error. + */ +static int bn_is_prime_int(const BIGNUM *w, int checks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb) +{ + int i, status, ret = -1; +#ifndef FIPS_MODULE + BN_CTX *ctxlocal = NULL; +#else + + if (ctx == NULL) + return -1; +#endif - /* Check odd and bigger than 1 */ - if (!BN_is_odd(a) || BN_cmp(a, BN_value_one()) <= 0) + /* w must be bigger than 1 */ + if (BN_cmp(w, BN_value_one()) <= 0) return 0; - if (checks == BN_prime_checks) - checks = BN_prime_checks_for_size(BN_num_bits(a)); + /* w must be odd */ + if (BN_is_odd(w)) { + /* Take care of the really small prime 3 */ + if (BN_is_word(w, 3)) + return 1; + } else { + /* 2 is the only even prime */ + return BN_is_word(w, 2); + } /* first look for small factors */ if (do_trial_division) { - for (i = 1; i < NUMPRIMES; i++) { - BN_ULONG mod = BN_mod_word(a, primes[i]); + int trial_divisions = calc_trial_divisions(BN_num_bits(w)); + + for (i = 1; i < trial_divisions; i++) { + BN_ULONG mod = BN_mod_word(w, primes[i]); if (mod == (BN_ULONG)-1) - goto err; + return -1; if (mod == 0) - return BN_is_word(a, primes[i]); + return BN_is_word(w, primes[i]); } if (!BN_GENCB_call(cb, 1, -1)) - goto err; + return -1; } - - if (ctx_passed != NULL) - ctx = ctx_passed; - else if ((ctx = BN_CTX_new()) == NULL) +#ifndef FIPS_MODULE + if (ctx == NULL && (ctxlocal = ctx = BN_CTX_new()) == NULL) goto err; - BN_CTX_start(ctx); +#endif - A1 = BN_CTX_get(ctx); - A3 = BN_CTX_get(ctx); - A1_odd = BN_CTX_get(ctx); - check = BN_CTX_get(ctx); - if (check == NULL) + if (!ossl_bn_miller_rabin_is_prime(w, checks, ctx, cb, 0, &status)) { + ret = -1; goto err; + } + ret = (status == BN_PRIMETEST_PROBABLY_PRIME); +err: +#ifndef FIPS_MODULE + BN_CTX_free(ctxlocal); +#endif + return ret; +} - /* compute A1 := a - 1 */ - if (!BN_copy(A1, a) || !BN_sub_word(A1, 1)) +/* + * Refer to FIPS 186-4 C.3.2 Enhanced Miller-Rabin Probabilistic Primality Test. + * OR C.3.1 Miller-Rabin Probabilistic Primality Test (if enhanced is zero). + * The Step numbers listed in the code refer to the enhanced case. + * + * if enhanced is set, then status returns one of the following: + * BN_PRIMETEST_PROBABLY_PRIME + * BN_PRIMETEST_COMPOSITE_WITH_FACTOR + * BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME + * if enhanced is zero, then status returns either + * BN_PRIMETEST_PROBABLY_PRIME or + * BN_PRIMETEST_COMPOSITE + * + * returns 0 if there was an error, otherwise it returns 1. + */ +int ossl_bn_miller_rabin_is_prime(const BIGNUM *w, int iterations, BN_CTX *ctx, + BN_GENCB *cb, int enhanced, int *status) +{ + int i, j, a, ret = 0; + BIGNUM *g, *w1, *w3, *x, *m, *z, *b; + BN_MONT_CTX *mont = NULL; + + /* w must be odd */ + if (!BN_is_odd(w)) + return 0; + + BN_CTX_start(ctx); + g = BN_CTX_get(ctx); + w1 = BN_CTX_get(ctx); + w3 = BN_CTX_get(ctx); + x = BN_CTX_get(ctx); + m = BN_CTX_get(ctx); + z = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + + if (!(b != NULL + /* w1 := w - 1 */ + && BN_copy(w1, w) + && BN_sub_word(w1, 1) + /* w3 := w - 3 */ + && BN_copy(w3, w) + && BN_sub_word(w3, 3))) goto err; - /* compute A3 := a - 3 */ - if (!BN_copy(A3, a) || !BN_sub_word(A3, 3)) + + /* check w is larger than 3, otherwise the random b will be too small */ + if (BN_is_zero(w3) || BN_is_negative(w3)) goto err; - /* write A1 as A1_odd * 2^k */ - k = 1; - while (!BN_is_bit_set(A1, k)) - k++; - if (!BN_rshift(A1_odd, A1, k)) + /* (Step 1) Calculate largest integer 'a' such that 2^a divides w-1 */ + a = 1; + while (!BN_is_bit_set(w1, a)) + a++; + /* (Step 2) m = (w-1) / 2^a */ + if (!BN_rshift(m, w1, a)) goto err; /* Montgomery setup for computations mod a */ mont = BN_MONT_CTX_new(); - if (mont == NULL) - goto err; - if (!BN_MONT_CTX_set(mont, a, ctx)) + if (mont == NULL || !BN_MONT_CTX_set(mont, w, ctx)) goto err; - for (i = 0; i < checks; i++) { - /* 1 < check < a-1 */ - if (!BN_priv_rand_range(check, A3) || !BN_add_word(check, 2)) + if (iterations == 0) + iterations = bn_mr_min_checks(BN_num_bits(w)); + + /* (Step 4) */ + for (i = 0; i < iterations; ++i) { + /* (Step 4.1) obtain a Random string of bits b where 1 < b < w-1 */ + if (!BN_priv_rand_range_ex(b, w3, 0, ctx) + || !BN_add_word(b, 2)) /* 1 < b < w-1 */ goto err; - j = witness(check, a, A1, A1_odd, k, ctx, mont); - if (j == -1) + if (enhanced) { + /* (Step 4.3) */ + if (!BN_gcd(g, b, w, ctx)) + goto err; + /* (Step 4.4) */ + if (!BN_is_one(g)) { + *status = BN_PRIMETEST_COMPOSITE_WITH_FACTOR; + ret = 1; + goto err; + } + } + /* (Step 4.5) z = b^m mod w */ + if (!BN_mod_exp_mont(z, b, m, w, ctx, mont)) goto err; - if (j) { - ret = 0; + /* (Step 4.6) if (z = 1 or z = w-1) */ + if (BN_is_one(z) || BN_cmp(z, w1) == 0) + goto outer_loop; + /* (Step 4.7) for j = 1 to a-1 */ + for (j = 1; j < a ; ++j) { + /* (Step 4.7.1 - 4.7.2) x = z. z = x^2 mod w */ + if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) + goto err; + /* (Step 4.7.3) */ + if (BN_cmp(z, w1) == 0) + goto outer_loop; + /* (Step 4.7.4) */ + if (BN_is_one(z)) + goto composite; + } + /* At this point z = b^((w-1)/2) mod w */ + /* (Steps 4.8 - 4.9) x = z, z = x^2 mod w */ + if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) + goto err; + /* (Step 4.10) */ + if (BN_is_one(z)) + goto composite; + /* (Step 4.11) x = b^(w-1) mod w */ + if (!BN_copy(x, z)) goto err; +composite: + if (enhanced) { + /* (Step 4.1.2) g = GCD(x-1, w) */ + if (!BN_sub_word(x, 1) || !BN_gcd(g, x, w, ctx)) + goto err; + /* (Steps 4.1.3 - 4.1.4) */ + if (BN_is_one(g)) + *status = BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME; + else + *status = BN_PRIMETEST_COMPOSITE_WITH_FACTOR; + } else { + *status = BN_PRIMETEST_COMPOSITE; } + ret = 1; + goto err; +outer_loop: ; + /* (Step 4.1.5) */ if (!BN_GENCB_call(cb, 1, i)) goto err; } + /* (Step 5) */ + *status = BN_PRIMETEST_PROBABLY_PRIME; ret = 1; - err: - if (ctx != NULL) { - BN_CTX_end(ctx); - if (ctx_passed == NULL) - BN_CTX_free(ctx); - } +err: + BN_clear(g); + BN_clear(w1); + BN_clear(w3); + BN_clear(x); + BN_clear(m); + BN_clear(z); + BN_clear(b); + BN_CTX_end(ctx); BN_MONT_CTX_free(mont); - return ret; } -static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, - const BIGNUM *a1_odd, int k, BN_CTX *ctx, - BN_MONT_CTX *mont) -{ - if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */ - return -1; - if (BN_is_one(w)) - return 0; /* probably prime */ - if (BN_cmp(w, a1) == 0) - return 0; /* w == -1 (mod a), 'a' is probably prime */ - while (--k) { - if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */ - return -1; - if (BN_is_one(w)) - return 1; /* 'a' is composite, otherwise a previous 'w' - * would have been == -1 (mod 'a') */ - if (BN_cmp(w, a1) == 0) - return 0; /* w == -1 (mod a), 'a' is probably prime */ - } - /* - * If we get here, 'w' is the (a-1)/2-th power of the original 'w', and - * it is neither -1 nor +1 -- so 'a' cannot be prime - */ - bn_check_top(w); - return 1; -} - -static int probable_prime(BIGNUM *rnd, int bits, int safe, prime_t *mods) +/* + * Generate a random number of |bits| bits that is probably prime by sieving. + * If |safe| != 0, it generates a safe prime. + * |mods| is a preallocated array that gets reused when called again. + * + * The probably prime is saved in |rnd|. + * + * Returns 1 on success and 0 on error. + */ +static int probable_prime(BIGNUM *rnd, int bits, int safe, prime_t *mods, + BN_CTX *ctx) { int i; BN_ULONG delta; - BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; + int trial_divisions = calc_trial_divisions(bits); + BN_ULONG maxdelta = BN_MASK2 - primes[trial_divisions - 1]; again: - /* TODO: Not all primes are private */ - if (!BN_priv_rand(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD)) + if (!BN_priv_rand_ex(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD, 0, + ctx)) return 0; if (safe && !BN_set_bit(rnd, 1)) return 0; /* we now have a random number 'rnd' to test. */ - for (i = 1; i < NUMPRIMES; i++) { + for (i = 1; i < trial_divisions; i++) { BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]); if (mod == (BN_ULONG)-1) return 0; @@ -290,7 +498,7 @@ static int probable_prime(BIGNUM *rnd, int bits, int safe, prime_t *mods) } delta = 0; loop: - for (i = 1; i < NUMPRIMES; i++) { + for (i = 1; i < trial_divisions; i++) { /* * check that rnd is a prime and also that * gcd(rnd-1,primes) == 1 (except for 2) @@ -317,6 +525,14 @@ static int probable_prime(BIGNUM *rnd, int bits, int safe, prime_t *mods) return 1; } +/* + * Generate a random number |rnd| of |bits| bits that is probably prime + * and satisfies |rnd| % |add| == |rem| by sieving. + * If |safe| != 0, it generates a safe prime. + * |mods| is a preallocated array that gets reused when called again. + * + * Returns 1 on success and 0 on error. + */ static int probable_prime_dh(BIGNUM *rnd, int bits, int safe, prime_t *mods, const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx) @@ -324,7 +540,8 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, int safe, prime_t *mods, int i, ret = 0; BIGNUM *t1; BN_ULONG delta; - BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; + int trial_divisions = calc_trial_divisions(bits); + BN_ULONG maxdelta = BN_MASK2 - primes[trial_divisions - 1]; BN_CTX_start(ctx); if ((t1 = BN_CTX_get(ctx)) == NULL) @@ -334,7 +551,7 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, int safe, prime_t *mods, maxdelta = BN_MASK2 - BN_get_word(add); again: - if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) + if (!BN_rand_ex(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD, 0, ctx)) goto err; /* we need ((rnd-rem) % add) == 0 */ @@ -358,7 +575,7 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, int safe, prime_t *mods, } /* we now have a random number 'rnd' to test. */ - for (i = 1; i < NUMPRIMES; i++) { + for (i = 1; i < trial_divisions; i++) { BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]); if (mod == (BN_ULONG)-1) goto err; @@ -366,7 +583,7 @@ static int probable_prime_dh(BIGNUM *rnd, int bits, int safe, prime_t *mods, } delta = 0; loop: - for (i = 1; i < NUMPRIMES; i++) { + for (i = 1; i < trial_divisions; i++) { /* check that rnd is a prime */ if (bits <= 31 && delta <= 0x7fffffff && square(primes[i]) > BN_get_word(rnd) + delta) diff --git a/crypto/openssl/crypto/bn/bn_prime.h b/crypto/openssl/crypto/bn/bn_prime.h index 8f2d7e995a01..8a859ac02e26 100644 --- a/crypto/openssl/crypto/bn/bn_prime.h +++ b/crypto/openssl/crypto/bn/bn_prime.h @@ -2,9 +2,9 @@ * WARNING: do not edit! * Generated by crypto/bn/bn_prime.pl * - * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bn/bn_prime.pl b/crypto/openssl/crypto/bn/bn_prime.pl old mode 100755 new mode 100644 index d2eaac6564f8..a7a764627b94 --- a/crypto/openssl/crypto/bn/bn_prime.pl +++ b/crypto/openssl/crypto/bn/bn_prime.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -11,6 +11,7 @@ use OpenSSL::copyright; # The year the output file is generated. my $YEAR = OpenSSL::copyright::year_of($0); + print <<"EOF"; /* * WARNING: do not edit! @@ -18,7 +19,7 @@ print <<"EOF"; * * Copyright 1998-$YEAR The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bn/bn_print.c b/crypto/openssl/crypto/bn/bn_print.c index 17ac6e7cac1c..ccc954c5b1c0 100644 --- a/crypto/openssl/crypto/bn/bn_print.c +++ b/crypto/openssl/crypto/bn/bn_print.c @@ -1,292 +1,19 @@ /* * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include -#include "crypto/ctype.h" -#include -#include "internal/cryptlib.h" -#include +#include #include "bn_local.h" static const char Hex[] = "0123456789ABCDEF"; -/* Must 'OPENSSL_free' the returned data */ -char *BN_bn2hex(const BIGNUM *a) -{ - int i, j, v, z = 0; - char *buf; - char *p; - - if (BN_is_zero(a)) - return OPENSSL_strdup("0"); - buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2); - if (buf == NULL) { - BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE); - goto err; - } - p = buf; - if (a->neg) - *p++ = '-'; - for (i = a->top - 1; i >= 0; i--) { - for (j = BN_BITS2 - 8; j >= 0; j -= 8) { - /* strip leading zeros */ - v = (int)((a->d[i] >> j) & 0xff); - if (z || v != 0) { - *p++ = Hex[v >> 4]; - *p++ = Hex[v & 0x0f]; - z = 1; - } - } - } - *p = '\0'; - err: - return buf; -} - -/* Must 'OPENSSL_free' the returned data */ -char *BN_bn2dec(const BIGNUM *a) -{ - int i = 0, num, ok = 0, n, tbytes; - char *buf = NULL; - char *p; - BIGNUM *t = NULL; - BN_ULONG *bn_data = NULL, *lp; - int bn_data_num; - - /*- - * get an upper bound for the length of the decimal integer - * num <= (BN_num_bits(a) + 1) * log(2) - * <= 3 * BN_num_bits(a) * 0.101 + log(2) + 1 (rounding error) - * <= 3 * BN_num_bits(a) / 10 + 3 * BN_num_bits / 1000 + 1 + 1 - */ - i = BN_num_bits(a) * 3; - num = (i / 10 + i / 1000 + 1) + 1; - tbytes = num + 3; /* negative and terminator and one spare? */ - bn_data_num = num / BN_DEC_NUM + 1; - bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG)); - buf = OPENSSL_malloc(tbytes); - if (buf == NULL || bn_data == NULL) { - BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE); - goto err; - } - if ((t = BN_dup(a)) == NULL) - goto err; - - p = buf; - lp = bn_data; - if (BN_is_zero(t)) { - *p++ = '0'; - *p++ = '\0'; - } else { - if (BN_is_negative(t)) - *p++ = '-'; - - while (!BN_is_zero(t)) { - if (lp - bn_data >= bn_data_num) - goto err; - *lp = BN_div_word(t, BN_DEC_CONV); - if (*lp == (BN_ULONG)-1) - goto err; - lp++; - } - lp--; - /* - * We now have a series of blocks, BN_DEC_NUM chars in length, where - * the last one needs truncation. The blocks need to be reversed in - * order. - */ - n = BIO_snprintf(p, tbytes - (size_t)(p - buf), BN_DEC_FMT1, *lp); - if (n < 0) - goto err; - p += n; - while (lp != bn_data) { - lp--; - n = BIO_snprintf(p, tbytes - (size_t)(p - buf), BN_DEC_FMT2, *lp); - if (n < 0) - goto err; - p += n; - } - } - ok = 1; - err: - OPENSSL_free(bn_data); - BN_free(t); - if (ok) - return buf; - OPENSSL_free(buf); - return NULL; -} - -int BN_hex2bn(BIGNUM **bn, const char *a) -{ - BIGNUM *ret = NULL; - BN_ULONG l = 0; - int neg = 0, h, m, i, j, k, c; - int num; - - if (a == NULL || *a == '\0') - return 0; - - if (*a == '-') { - neg = 1; - a++; - } - - for (i = 0; i <= INT_MAX / 4 && ossl_isxdigit(a[i]); i++) - continue; - - if (i == 0 || i > INT_MAX / 4) - return 0; - - num = i + neg; - if (bn == NULL) - return num; - - /* a is the start of the hex digits, and it is 'i' long */ - if (*bn == NULL) { - if ((ret = BN_new()) == NULL) - return 0; - } else { - ret = *bn; - BN_zero(ret); - } - - /* i is the number of hex digits */ - if (bn_expand(ret, i * 4) == NULL) - goto err; - - j = i; /* least significant 'hex' */ - m = 0; - h = 0; - while (j > 0) { - m = (BN_BYTES * 2 <= j) ? BN_BYTES * 2 : j; - l = 0; - for (;;) { - c = a[j - m]; - k = OPENSSL_hexchar2int(c); - if (k < 0) - k = 0; /* paranoia */ - l = (l << 4) | k; - - if (--m <= 0) { - ret->d[h++] = l; - break; - } - } - j -= BN_BYTES * 2; - } - ret->top = h; - bn_correct_top(ret); - - *bn = ret; - bn_check_top(ret); - /* Don't set the negative flag if it's zero. */ - if (ret->top != 0) - ret->neg = neg; - return num; - err: - if (*bn == NULL) - BN_free(ret); - return 0; -} - -int BN_dec2bn(BIGNUM **bn, const char *a) -{ - BIGNUM *ret = NULL; - BN_ULONG l = 0; - int neg = 0, i, j; - int num; - - if (a == NULL || *a == '\0') - return 0; - if (*a == '-') { - neg = 1; - a++; - } - - for (i = 0; i <= INT_MAX / 4 && ossl_isdigit(a[i]); i++) - continue; - - if (i == 0 || i > INT_MAX / 4) - goto err; - - num = i + neg; - if (bn == NULL) - return num; - - /* - * a is the start of the digits, and it is 'i' long. We chop it into - * BN_DEC_NUM digits at a time - */ - if (*bn == NULL) { - if ((ret = BN_new()) == NULL) - return 0; - } else { - ret = *bn; - BN_zero(ret); - } - - /* i is the number of digits, a bit of an over expand */ - if (bn_expand(ret, i * 4) == NULL) - goto err; - - j = BN_DEC_NUM - i % BN_DEC_NUM; - if (j == BN_DEC_NUM) - j = 0; - l = 0; - while (--i >= 0) { - l *= 10; - l += *a - '0'; - a++; - if (++j == BN_DEC_NUM) { - if (!BN_mul_word(ret, BN_DEC_CONV) - || !BN_add_word(ret, l)) - goto err; - l = 0; - j = 0; - } - } - - bn_correct_top(ret); - *bn = ret; - bn_check_top(ret); - /* Don't set the negative flag if it's zero. */ - if (ret->top != 0) - ret->neg = neg; - return num; - err: - if (*bn == NULL) - BN_free(ret); - return 0; -} - -int BN_asc2bn(BIGNUM **bn, const char *a) -{ - const char *p = a; - - if (*p == '-') - p++; - - if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) { - if (!BN_hex2bn(bn, p + 2)) - return 0; - } else { - if (!BN_dec2bn(bn, p)) - return 0; - } - /* Don't set the negative flag if it's zero. */ - if (*a == '-' && (*bn)->top != 0) - (*bn)->neg = 1; - return 1; -} - -# ifndef OPENSSL_NO_STDIO +#ifndef OPENSSL_NO_STDIO int BN_print_fp(FILE *fp, const BIGNUM *a) { BIO *b; @@ -299,7 +26,7 @@ int BN_print_fp(FILE *fp, const BIGNUM *a) BIO_free(b); return ret; } -# endif +#endif int BN_print(BIO *bp, const BIGNUM *a) { diff --git a/crypto/openssl/crypto/bn/bn_rand.c b/crypto/openssl/crypto/bn/bn_rand.c index 6b4b50a068f1..2ca426ff76ed 100644 --- a/crypto/openssl/crypto/bn/bn_rand.c +++ b/crypto/openssl/crypto/bn/bn_rand.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,18 +10,22 @@ #include #include #include "internal/cryptlib.h" +#include "crypto/rand.h" #include "bn_local.h" #include #include +#include typedef enum bnrand_flag_e { NORMAL, TESTING, PRIVATE } BNRAND_FLAG; -static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom) +static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom, + unsigned int strength, BN_CTX *ctx) { unsigned char *buf = NULL; int b, ret = 0, bit, bytes, mask; + OSSL_LIB_CTX *libctx = ossl_bn_get_libctx(ctx); if (bits == 0) { if (top != BN_RAND_TOP_ANY || bottom != BN_RAND_BOTTOM_ANY) @@ -38,12 +42,13 @@ static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom) buf = OPENSSL_malloc(bytes); if (buf == NULL) { - BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); goto err; } /* make a random number and set the top and bottom bits */ - b = flag == NORMAL ? RAND_bytes(buf, bytes) : RAND_priv_bytes(buf, bytes); + b = flag == NORMAL ? RAND_bytes_ex(libctx, buf, bytes, strength) + : RAND_priv_bytes_ex(libctx, buf, bytes, strength); if (b <= 0) goto err; @@ -55,7 +60,7 @@ static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom) unsigned char c; for (i = 0; i < bytes; i++) { - if (RAND_bytes(&c, 1) <= 0) + if (RAND_bytes_ex(libctx, &c, 1, strength) <= 0) goto err; if (c >= 128 && i > 0) buf[i] = buf[i - 1]; @@ -90,33 +95,54 @@ static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom) return ret; toosmall: - BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL); + ERR_raise(ERR_LIB_BN, BN_R_BITS_TOO_SMALL); return 0; } +int BN_rand_ex(BIGNUM *rnd, int bits, int top, int bottom, + unsigned int strength, BN_CTX *ctx) +{ + return bnrand(NORMAL, rnd, bits, top, bottom, strength, ctx); +} +#ifndef FIPS_MODULE int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) { - return bnrand(NORMAL, rnd, bits, top, bottom); + return bnrand(NORMAL, rnd, bits, top, bottom, 0, NULL); } int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom) { - return bnrand(TESTING, rnd, bits, top, bottom); + return bnrand(TESTING, rnd, bits, top, bottom, 0, NULL); +} +#endif + +int BN_priv_rand_ex(BIGNUM *rnd, int bits, int top, int bottom, + unsigned int strength, BN_CTX *ctx) +{ + return bnrand(PRIVATE, rnd, bits, top, bottom, strength, ctx); } +#ifndef FIPS_MODULE int BN_priv_rand(BIGNUM *rnd, int bits, int top, int bottom) { - return bnrand(PRIVATE, rnd, bits, top, bottom); + return bnrand(PRIVATE, rnd, bits, top, bottom, 0, NULL); } +#endif /* random number r: 0 <= r < range */ -static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range) +static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range, + unsigned int strength, BN_CTX *ctx) { int n; int count = 100; + if (r == NULL) { + ERR_raise(ERR_LIB_BN, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (range->neg || BN_is_zero(range)) { - BNerr(BN_F_BNRAND_RANGE, BN_R_INVALID_RANGE); + ERR_raise(ERR_LIB_BN, BN_R_INVALID_RANGE); return 0; } @@ -132,7 +158,8 @@ static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range) * than range */ do { - if (!bnrand(flag, r, n + 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) + if (!bnrand(flag, r, n + 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, + strength, ctx)) return 0; /* @@ -150,7 +177,7 @@ static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range) } if (!--count) { - BNerr(BN_F_BNRAND_RANGE, BN_R_TOO_MANY_ITERATIONS); + ERR_raise(ERR_LIB_BN, BN_R_TOO_MANY_ITERATIONS); return 0; } @@ -159,11 +186,12 @@ static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range) } else { do { /* range = 11..._2 or range = 101..._2 */ - if (!bnrand(flag, r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) + if (!bnrand(flag, r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, 0, + ctx)) return 0; if (!--count) { - BNerr(BN_F_BNRAND_RANGE, BN_R_TOO_MANY_ITERATIONS); + ERR_raise(ERR_LIB_BN, BN_R_TOO_MANY_ITERATIONS); return 0; } } @@ -174,16 +202,32 @@ static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range) return 1; } +int BN_rand_range_ex(BIGNUM *r, const BIGNUM *range, unsigned int strength, + BN_CTX *ctx) +{ + return bnrand_range(NORMAL, r, range, strength, ctx); +} + +#ifndef FIPS_MODULE int BN_rand_range(BIGNUM *r, const BIGNUM *range) { - return bnrand_range(NORMAL, r, range); + return bnrand_range(NORMAL, r, range, 0, NULL); } +#endif +int BN_priv_rand_range_ex(BIGNUM *r, const BIGNUM *range, unsigned int strength, + BN_CTX *ctx) +{ + return bnrand_range(PRIVATE, r, range, strength, ctx); +} + +#ifndef FIPS_MODULE int BN_priv_rand_range(BIGNUM *r, const BIGNUM *range) { - return bnrand_range(PRIVATE, r, range); + return bnrand_range(PRIVATE, r, range, 0, NULL); } +# ifndef OPENSSL_NO_DEPRECATED_3_0 int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) { return BN_rand(rnd, bits, top, bottom); @@ -193,6 +237,8 @@ int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) { return BN_rand_range(r, range); } +# endif +#endif /* * BN_generate_dsa_nonce generates a random number 0 <= out < range. Unlike @@ -206,7 +252,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv, const unsigned char *message, size_t message_len, BN_CTX *ctx) { - SHA512_CTX sha; + EVP_MD_CTX *mdctx = EVP_MD_CTX_new(); /* * We use 512 bits of random data per iteration to ensure that we have at * least |range| bits of randomness. @@ -217,8 +263,13 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, /* We generate |range|+8 bytes of random output. */ const unsigned num_k_bytes = BN_num_bytes(range) + 8; unsigned char private_bytes[96]; - unsigned char *k_bytes; + unsigned char *k_bytes = NULL; int ret = 0; + EVP_MD *md = NULL; + OSSL_LIB_CTX *libctx = ossl_bn_get_libctx(ctx); + + if (mdctx == NULL) + goto err; k_bytes = OPENSSL_malloc(num_k_bytes); if (k_bytes == NULL) @@ -231,19 +282,27 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, * large and we don't handle this case in order to avoid leaking the * length of the private key. */ - BNerr(BN_F_BN_GENERATE_DSA_NONCE, BN_R_PRIVATE_KEY_TOO_LARGE); + ERR_raise(ERR_LIB_BN, BN_R_PRIVATE_KEY_TOO_LARGE); goto err; } + md = EVP_MD_fetch(libctx, "SHA512", NULL); + if (md == NULL) { + ERR_raise(ERR_LIB_BN, BN_R_NO_SUITABLE_DIGEST); + goto err; + } for (done = 0; done < num_k_bytes;) { - if (RAND_priv_bytes(random_bytes, sizeof(random_bytes)) != 1) + if (RAND_priv_bytes_ex(libctx, random_bytes, sizeof(random_bytes), 0) <= 0) + goto err; + + if (!EVP_DigestInit_ex(mdctx, md, NULL) + || !EVP_DigestUpdate(mdctx, &done, sizeof(done)) + || !EVP_DigestUpdate(mdctx, private_bytes, + sizeof(private_bytes)) + || !EVP_DigestUpdate(mdctx, message, message_len) + || !EVP_DigestUpdate(mdctx, random_bytes, sizeof(random_bytes)) + || !EVP_DigestFinal_ex(mdctx, digest, NULL)) goto err; - SHA512_Init(&sha); - SHA512_Update(&sha, &done, sizeof(done)); - SHA512_Update(&sha, private_bytes, sizeof(private_bytes)); - SHA512_Update(&sha, message, message_len); - SHA512_Update(&sha, random_bytes, sizeof(random_bytes)); - SHA512_Final(digest, &sha); todo = num_k_bytes - done; if (todo > SHA512_DIGEST_LENGTH) @@ -259,7 +318,11 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, ret = 1; err: - OPENSSL_free(k_bytes); + EVP_MD_CTX_free(mdctx); + EVP_MD_free(md); + OPENSSL_clear_free(k_bytes, num_k_bytes); + OPENSSL_cleanse(digest, sizeof(digest)); + OPENSSL_cleanse(random_bytes, sizeof(random_bytes)); OPENSSL_cleanse(private_bytes, sizeof(private_bytes)); return ret; } diff --git a/crypto/openssl/crypto/bn/bn_recp.c b/crypto/openssl/crypto/bn/bn_recp.c index e82231334123..96a6b19ab0da 100644 --- a/crypto/openssl/crypto/bn/bn_recp.c +++ b/crypto/openssl/crypto/bn/bn_recp.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -22,7 +22,7 @@ BN_RECP_CTX *BN_RECP_CTX_new(void) BN_RECP_CTX *ret; if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - BNerr(BN_F_BN_RECP_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); return NULL; } @@ -146,7 +146,7 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, j = 0; while (BN_ucmp(r, &(recp->N)) >= 0) { if (j++ > 2) { - BNerr(BN_F_BN_DIV_RECP, BN_R_BAD_RECIPROCAL); + ERR_raise(ERR_LIB_BN, BN_R_BAD_RECIPROCAL); goto err; } if (!BN_usub(r, r, &(recp->N))) diff --git a/crypto/openssl/crypto/bn/bn_rsa_fips186_4.c b/crypto/openssl/crypto/bn/bn_rsa_fips186_4.c new file mode 100644 index 000000000000..abce1aa2d830 --- /dev/null +++ b/crypto/openssl/crypto/bn/bn_rsa_fips186_4.c @@ -0,0 +1,367 @@ +/* + * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * According to NIST SP800-131A "Transitioning the use of cryptographic + * algorithms and key lengths" Generation of 1024 bit RSA keys are no longer + * allowed for signatures (Table 2) or key transport (Table 5). In the code + * below any attempt to generate 1024 bit RSA keys will result in an error (Note + * that digital signature verification can still use deprecated 1024 bit keys). + * + * FIPS 186-4 relies on the use of the auxiliary primes p1, p2, q1 and q2 that + * must be generated before the module generates the RSA primes p and q. + * Table B.1 in FIPS 186-4 specifies RSA modulus lengths of 2048 and + * 3072 bits only, the min/max total length of the auxiliary primes. + * FIPS 186-5 Table A.1 includes an additional entry for 4096 which has been + * included here. + */ +#include +#include +#include "bn_local.h" +#include "crypto/bn.h" +#include "internal/nelem.h" + +#if BN_BITS2 == 64 +# define BN_DEF(lo, hi) (BN_ULONG)hi<<32|lo +#else +# define BN_DEF(lo, hi) lo, hi +#endif + +/* 1 / sqrt(2) * 2^256, rounded up */ +static const BN_ULONG inv_sqrt_2_val[] = { + BN_DEF(0x83339916UL, 0xED17AC85UL), BN_DEF(0x893BA84CUL, 0x1D6F60BAUL), + BN_DEF(0x754ABE9FUL, 0x597D89B3UL), BN_DEF(0xF9DE6484UL, 0xB504F333UL) +}; + +const BIGNUM ossl_bn_inv_sqrt_2 = { + (BN_ULONG *)inv_sqrt_2_val, + OSSL_NELEM(inv_sqrt_2_val), + OSSL_NELEM(inv_sqrt_2_val), + 0, + BN_FLG_STATIC_DATA +}; + +/* + * FIPS 186-5 Table A.1. "Min length of auxiliary primes p1, p2, q1, q2". + * (FIPS 186-5 has an entry for >= 4096 bits). + * + * Params: + * nbits The key size in bits. + * Returns: + * The minimum size of the auxiliary primes or 0 if nbits is invalid. + */ +static int bn_rsa_fips186_5_aux_prime_min_size(int nbits) +{ + if (nbits >= 4096) + return 201; + if (nbits >= 3072) + return 171; + if (nbits >= 2048) + return 141; + return 0; +} + +/* + * FIPS 186-5 Table A.1 "Max of len(p1) + len(p2) and + * len(q1) + len(q2) for p,q Probable Primes". + * (FIPS 186-5 has an entry for >= 4096 bits). + * Params: + * nbits The key size in bits. + * Returns: + * The maximum length or 0 if nbits is invalid. + */ +static int bn_rsa_fips186_5_aux_prime_max_sum_size_for_prob_primes(int nbits) +{ + if (nbits >= 4096) + return 2030; + if (nbits >= 3072) + return 1518; + if (nbits >= 2048) + return 1007; + return 0; +} + +/* + * Find the first odd integer that is a probable prime. + * + * See section FIPS 186-4 B.3.6 (Steps 4.2/5.2). + * + * Params: + * Xp1 The passed in starting point to find a probably prime. + * p1 The returned probable prime (first odd integer >= Xp1) + * ctx A BN_CTX object. + * cb An optional BIGNUM callback. + * Returns: 1 on success otherwise it returns 0. + */ +static int bn_rsa_fips186_4_find_aux_prob_prime(const BIGNUM *Xp1, + BIGNUM *p1, BN_CTX *ctx, + BN_GENCB *cb) +{ + int ret = 0; + int i = 0; + int tmp = 0; + + if (BN_copy(p1, Xp1) == NULL) + return 0; + BN_set_flags(p1, BN_FLG_CONSTTIME); + + /* Find the first odd number >= Xp1 that is probably prime */ + for(;;) { + i++; + BN_GENCB_call(cb, 0, i); + /* MR test with trial division */ + tmp = BN_check_prime(p1, ctx, cb); + if (tmp > 0) + break; + if (tmp < 0) + goto err; + /* Get next odd number */ + if (!BN_add_word(p1, 2)) + goto err; + } + BN_GENCB_call(cb, 2, i); + ret = 1; +err: + return ret; +} + +/* + * Generate a probable prime (p or q). + * + * See FIPS 186-4 B.3.6 (Steps 4 & 5) + * + * Params: + * p The returned probable prime. + * Xpout An optionally returned random number used during generation of p. + * p1, p2 The returned auxiliary primes. If NULL they are not returned. + * Xp An optional passed in value (that is random number used during + * generation of p). + * Xp1, Xp2 Optional passed in values that are normally generated + * internally. Used to find p1, p2. + * nlen The bit length of the modulus (the key size). + * e The public exponent. + * ctx A BN_CTX object. + * cb An optional BIGNUM callback. + * Returns: 1 on success otherwise it returns 0. + */ +int ossl_bn_rsa_fips186_4_gen_prob_primes(BIGNUM *p, BIGNUM *Xpout, + BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, + const BIGNUM *Xp2, int nlen, + const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb) +{ + int ret = 0; + BIGNUM *p1i = NULL, *p2i = NULL, *Xp1i = NULL, *Xp2i = NULL; + int bitlen; + + if (p == NULL || Xpout == NULL) + return 0; + + BN_CTX_start(ctx); + + p1i = (p1 != NULL) ? p1 : BN_CTX_get(ctx); + p2i = (p2 != NULL) ? p2 : BN_CTX_get(ctx); + Xp1i = (Xp1 != NULL) ? (BIGNUM *)Xp1 : BN_CTX_get(ctx); + Xp2i = (Xp2 != NULL) ? (BIGNUM *)Xp2 : BN_CTX_get(ctx); + if (p1i == NULL || p2i == NULL || Xp1i == NULL || Xp2i == NULL) + goto err; + + bitlen = bn_rsa_fips186_5_aux_prime_min_size(nlen); + if (bitlen == 0) + goto err; + + /* (Steps 4.1/5.1): Randomly generate Xp1 if it is not passed in */ + if (Xp1 == NULL) { + /* Set the top and bottom bits to make it odd and the correct size */ + if (!BN_priv_rand_ex(Xp1i, bitlen, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD, + 0, ctx)) + goto err; + } + /* (Steps 4.1/5.1): Randomly generate Xp2 if it is not passed in */ + if (Xp2 == NULL) { + /* Set the top and bottom bits to make it odd and the correct size */ + if (!BN_priv_rand_ex(Xp2i, bitlen, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD, + 0, ctx)) + goto err; + } + + /* (Steps 4.2/5.2) - find first auxiliary probable primes */ + if (!bn_rsa_fips186_4_find_aux_prob_prime(Xp1i, p1i, ctx, cb) + || !bn_rsa_fips186_4_find_aux_prob_prime(Xp2i, p2i, ctx, cb)) + goto err; + /* (Table B.1) auxiliary prime Max length check */ + if ((BN_num_bits(p1i) + BN_num_bits(p2i)) >= + bn_rsa_fips186_5_aux_prime_max_sum_size_for_prob_primes(nlen)) + goto err; + /* (Steps 4.3/5.3) - generate prime */ + if (!ossl_bn_rsa_fips186_4_derive_prime(p, Xpout, Xp, p1i, p2i, nlen, e, + ctx, cb)) + goto err; + ret = 1; +err: + /* Zeroize any internally generated values that are not returned */ + if (p1 == NULL) + BN_clear(p1i); + if (p2 == NULL) + BN_clear(p2i); + if (Xp1 == NULL) + BN_clear(Xp1i); + if (Xp2 == NULL) + BN_clear(Xp2i); + BN_CTX_end(ctx); + return ret; +} + +/* + * Constructs a probable prime (a candidate for p or q) using 2 auxiliary + * prime numbers and the Chinese Remainder Theorem. + * + * See FIPS 186-4 C.9 "Compute a Probable Prime Factor Based on Auxiliary + * Primes". Used by FIPS 186-4 B.3.6 Section (4.3) for p and Section (5.3) for q. + * + * Params: + * Y The returned prime factor (private_prime_factor) of the modulus n. + * X The returned random number used during generation of the prime factor. + * Xin An optional passed in value for X used for testing purposes. + * r1 An auxiliary prime. + * r2 An auxiliary prime. + * nlen The desired length of n (the RSA modulus). + * e The public exponent. + * ctx A BN_CTX object. + * cb An optional BIGNUM callback object. + * Returns: 1 on success otherwise it returns 0. + * Assumptions: + * Y, X, r1, r2, e are not NULL. + */ +int ossl_bn_rsa_fips186_4_derive_prime(BIGNUM *Y, BIGNUM *X, const BIGNUM *Xin, + const BIGNUM *r1, const BIGNUM *r2, + int nlen, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb) +{ + int ret = 0; + int i, imax; + int bits = nlen >> 1; + BIGNUM *tmp, *R, *r1r2x2, *y1, *r1x2; + BIGNUM *base, *range; + + BN_CTX_start(ctx); + + base = BN_CTX_get(ctx); + range = BN_CTX_get(ctx); + R = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + r1r2x2 = BN_CTX_get(ctx); + y1 = BN_CTX_get(ctx); + r1x2 = BN_CTX_get(ctx); + if (r1x2 == NULL) + goto err; + + if (Xin != NULL && BN_copy(X, Xin) == NULL) + goto err; + + /* + * We need to generate a random number X in the range + * 1/sqrt(2) * 2^(nlen/2) <= X < 2^(nlen/2). + * We can rewrite that as: + * base = 1/sqrt(2) * 2^(nlen/2) + * range = ((2^(nlen/2))) - (1/sqrt(2) * 2^(nlen/2)) + * X = base + random(range) + * We only have the first 256 bit of 1/sqrt(2) + */ + if (Xin == NULL) { + if (bits < BN_num_bits(&ossl_bn_inv_sqrt_2)) + goto err; + if (!BN_lshift(base, &ossl_bn_inv_sqrt_2, + bits - BN_num_bits(&ossl_bn_inv_sqrt_2)) + || !BN_lshift(range, BN_value_one(), bits) + || !BN_sub(range, range, base)) + goto err; + } + + if (!(BN_lshift1(r1x2, r1) + /* (Step 1) GCD(2r1, r2) = 1 */ + && BN_gcd(tmp, r1x2, r2, ctx) + && BN_is_one(tmp) + /* (Step 2) R = ((r2^-1 mod 2r1) * r2) - ((2r1^-1 mod r2)*2r1) */ + && BN_mod_inverse(R, r2, r1x2, ctx) + && BN_mul(R, R, r2, ctx) /* R = (r2^-1 mod 2r1) * r2 */ + && BN_mod_inverse(tmp, r1x2, r2, ctx) + && BN_mul(tmp, tmp, r1x2, ctx) /* tmp = (2r1^-1 mod r2)*2r1 */ + && BN_sub(R, R, tmp) + /* Calculate 2r1r2 */ + && BN_mul(r1r2x2, r1x2, r2, ctx))) + goto err; + /* Make positive by adding the modulus */ + if (BN_is_negative(R) && !BN_add(R, R, r1r2x2)) + goto err; + + /* + * In FIPS 186-4 imax was set to 5 * nlen/2. + * Analysis by Allen Roginsky (See https://csrc.nist.gov/CSRC/media/Publications/fips/186/4/final/documents/comments-received-fips186-4-december-2015.pdf + * page 68) indicates this has a 1 in 2 million chance of failure. + * The number has been updated to 20 * nlen/2 as used in + * FIPS186-5 Appendix B.9 Step 9. + */ + imax = 20 * bits; /* max = 20/2 * nbits */ + for (;;) { + if (Xin == NULL) { + /* + * (Step 3) Choose Random X such that + * sqrt(2) * 2^(nlen/2-1) <= Random X <= (2^(nlen/2)) - 1. + */ + if (!BN_priv_rand_range_ex(X, range, 0, ctx) || !BN_add(X, X, base)) + goto end; + } + /* (Step 4) Y = X + ((R - X) mod 2r1r2) */ + if (!BN_mod_sub(Y, R, X, r1r2x2, ctx) || !BN_add(Y, Y, X)) + goto err; + /* (Step 5) */ + i = 0; + for (;;) { + /* (Step 6) */ + if (BN_num_bits(Y) > bits) { + if (Xin == NULL) + break; /* Randomly Generated X so Go back to Step 3 */ + else + goto err; /* X is not random so it will always fail */ + } + BN_GENCB_call(cb, 0, 2); + + /* (Step 7) If GCD(Y-1) == 1 & Y is probably prime then return Y */ + if (BN_copy(y1, Y) == NULL + || !BN_sub_word(y1, 1) + || !BN_gcd(tmp, y1, e, ctx)) + goto err; + if (BN_is_one(tmp)) { + int rv = BN_check_prime(Y, ctx, cb); + + if (rv > 0) + goto end; + if (rv < 0) + goto err; + } + /* (Step 8-10) */ + if (++i >= imax) { + ERR_raise(ERR_LIB_BN, BN_R_NO_PRIME_CANDIDATE); + goto err; + } + if (!BN_add(Y, Y, r1r2x2)) + goto err; + } + } +end: + ret = 1; + BN_GENCB_call(cb, 3, 0); +err: + BN_clear(y1); + BN_CTX_end(ctx); + return ret; +} diff --git a/crypto/openssl/crypto/bn/bn_shift.c b/crypto/openssl/crypto/bn/bn_shift.c index 210a83f586d2..8fcb04324e6d 100644 --- a/crypto/openssl/crypto/bn/bn_shift.c +++ b/crypto/openssl/crypto/bn/bn_shift.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -83,7 +83,7 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) int ret; if (n < 0) { - BNerr(BN_F_BN_LSHIFT, BN_R_INVALID_SHIFT); + ERR_raise(ERR_LIB_BN, BN_R_INVALID_SHIFT); return 0; } @@ -152,7 +152,7 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) int ret = 0; if (n < 0) { - BNerr(BN_F_BN_RSHIFT, BN_R_INVALID_SHIFT); + ERR_raise(ERR_LIB_BN, BN_R_INVALID_SHIFT); return 0; } diff --git a/crypto/openssl/crypto/bn/bn_sparc.c b/crypto/openssl/crypto/bn/bn_sparc.c new file mode 100644 index 000000000000..a810c3b1faee --- /dev/null +++ b/crypto/openssl/crypto/bn/bn_sparc.c @@ -0,0 +1,77 @@ +/* + * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/cryptlib.h" +#include "crypto/sparc_arch.h" +#include "bn_local.h" /* for definition of bn_mul_mont */ + +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num) +{ + int bn_mul_mont_vis3(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); + int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); + int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); + + if (!(num & 1) && num >= 6) { + if ((num & 15) == 0 && num <= 64 && + (OPENSSL_sparcv9cap_P[1] & (CFR_MONTMUL | CFR_MONTSQR)) == + (CFR_MONTMUL | CFR_MONTSQR)) { + typedef int (*bn_mul_mont_f) (BN_ULONG *rp, const BN_ULONG *ap, + const BN_ULONG *bp, + const BN_ULONG *np, + const BN_ULONG *n0); + int bn_mul_mont_t4_8(BN_ULONG *rp, const BN_ULONG *ap, + const BN_ULONG *bp, const BN_ULONG *np, + const BN_ULONG *n0); + int bn_mul_mont_t4_16(BN_ULONG *rp, const BN_ULONG *ap, + const BN_ULONG *bp, const BN_ULONG *np, + const BN_ULONG *n0); + int bn_mul_mont_t4_24(BN_ULONG *rp, const BN_ULONG *ap, + const BN_ULONG *bp, const BN_ULONG *np, + const BN_ULONG *n0); + int bn_mul_mont_t4_32(BN_ULONG *rp, const BN_ULONG *ap, + const BN_ULONG *bp, const BN_ULONG *np, + const BN_ULONG *n0); + static const bn_mul_mont_f funcs[4] = { + bn_mul_mont_t4_8, bn_mul_mont_t4_16, + bn_mul_mont_t4_24, bn_mul_mont_t4_32 + }; + bn_mul_mont_f worker = funcs[num / 16 - 1]; + + if ((*worker) (rp, ap, bp, np, n0)) + return 1; + /* retry once and fall back */ + if ((*worker) (rp, ap, bp, np, n0)) + return 1; + return bn_mul_mont_vis3(rp, ap, bp, np, n0, num); + } + if ((OPENSSL_sparcv9cap_P[0] & SPARCV9_VIS3)) + return bn_mul_mont_vis3(rp, ap, bp, np, n0, num); + else if (num >= 8 && + /* + * bn_mul_mont_fpu doesn't use FMADD, we just use the + * flag to detect when FPU path is preferable in cases + * when current heuristics is unreliable. [it works + * out because FMADD-capable processors where FPU + * code path is undesirable are also VIS3-capable and + * VIS3 code path takes precedence.] + */ + ( (OPENSSL_sparcv9cap_P[0] & SPARCV9_FMADD) || + (OPENSSL_sparcv9cap_P[0] & + (SPARCV9_PREFER_FPU | SPARCV9_VIS1)) == + (SPARCV9_PREFER_FPU | SPARCV9_VIS1) )) + return bn_mul_mont_fpu(rp, ap, bp, np, n0, num); + } + return bn_mul_mont_int(rp, ap, bp, np, n0, num); +} diff --git a/crypto/openssl/crypto/bn/bn_sqr.c b/crypto/openssl/crypto/bn/bn_sqr.c index 7f3a179177b6..990bed90b590 100644 --- a/crypto/openssl/crypto/bn/bn_sqr.c +++ b/crypto/openssl/crypto/bn/bn_sqr.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bn/bn_sqrt.c b/crypto/openssl/crypto/bn/bn_sqrt.c index 6a42ce8a9413..5c77e72132d4 100644 --- a/crypto/openssl/crypto/bn/bn_sqrt.c +++ b/crypto/openssl/crypto/bn/bn_sqrt.c @@ -1,7 +1,7 @@ /* * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -23,6 +23,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) int r; BIGNUM *A, *b, *q, *t, *x, *y; int e, i, j; + int used_ctx = 0; if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) { if (BN_abs_is_word(p, 2)) { @@ -39,7 +40,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) return ret; } - BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); + ERR_raise(ERR_LIB_BN, BN_R_P_IS_NOT_PRIME); return NULL; } @@ -58,6 +59,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) } BN_CTX_start(ctx); + used_ctx = 1; A = BN_CTX_get(ctx); b = BN_CTX_get(ctx); q = BN_CTX_get(ctx); @@ -181,7 +183,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) if (!BN_set_word(y, i)) goto end; } else { - if (!BN_priv_rand(y, BN_num_bits(p), 0, 0)) + if (!BN_priv_rand_ex(y, BN_num_bits(p), 0, 0, 0, ctx)) goto end; if (BN_ucmp(y, p) >= 0) { if (!(p->neg ? BN_add : BN_sub) (y, y, p)) @@ -198,7 +200,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) goto end; if (r == 0) { /* m divides p */ - BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); + ERR_raise(ERR_LIB_BN, BN_R_P_IS_NOT_PRIME); goto end; } } @@ -210,7 +212,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) * than just bad luck. Even if p is not prime, we should have found * some y such that r == -1. */ - BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS); + ERR_raise(ERR_LIB_BN, BN_R_TOO_MANY_ITERATIONS); goto end; } @@ -225,7 +227,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) if (!BN_mod_exp(y, y, q, p, ctx)) goto end; if (BN_is_one(y)) { - BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); + ERR_raise(ERR_LIB_BN, BN_R_P_IS_NOT_PRIME); goto end; } @@ -317,7 +319,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) } /* If not found, a is not a square or p is not prime. */ if (i >= e) { - BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); + ERR_raise(ERR_LIB_BN, BN_R_NOT_A_SQUARE); goto end; } @@ -348,7 +350,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) err = 1; if (!err && 0 != BN_cmp(x, A)) { - BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); + ERR_raise(ERR_LIB_BN, BN_R_NOT_A_SQUARE); err = 1; } } @@ -359,7 +361,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) BN_clear_free(ret); ret = NULL; } - BN_CTX_end(ctx); + if (used_ctx) + BN_CTX_end(ctx); bn_check_top(ret); return ret; } diff --git a/crypto/openssl/crypto/bn/bn_srp.c b/crypto/openssl/crypto/bn/bn_srp.c index 820757be60e3..ffb8fc61e0fe 100644 --- a/crypto/openssl/crypto/bn/bn_srp.c +++ b/crypto/openssl/crypto/bn/bn_srp.c @@ -1,7 +1,7 @@ /* - * Copyright 2014-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -48,7 +48,7 @@ static const BN_ULONG bn_group_1024_value[] = { bn_pack4(0xEEAF, 0x0AB9, 0xADB3, 0x8DD6) }; -const BIGNUM bn_group_1024 = { +const BIGNUM ossl_bn_group_1024 = { (BN_ULONG *)bn_group_1024_value, OSSL_NELEM(bn_group_1024_value), OSSL_NELEM(bn_group_1024_value), @@ -83,7 +83,7 @@ static const BN_ULONG bn_group_1536_value[] = { bn_pack4(0x9DEF, 0x3CAF, 0xB939, 0x277A) }; -const BIGNUM bn_group_1536 = { +const BIGNUM ossl_bn_group_1536 = { (BN_ULONG *)bn_group_1536_value, OSSL_NELEM(bn_group_1536_value), OSSL_NELEM(bn_group_1536_value), @@ -126,7 +126,7 @@ static const BN_ULONG bn_group_2048_value[] = { bn_pack4(0xAC6B, 0xDB41, 0x324A, 0x9A9B) }; -const BIGNUM bn_group_2048 = { +const BIGNUM ossl_bn_group_2048 = { (BN_ULONG *)bn_group_2048_value, OSSL_NELEM(bn_group_2048_value), OSSL_NELEM(bn_group_2048_value), @@ -185,7 +185,7 @@ static const BN_ULONG bn_group_3072_value[] = { bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) }; -const BIGNUM bn_group_3072 = { +const BIGNUM ossl_bn_group_3072 = { (BN_ULONG *)bn_group_3072_value, OSSL_NELEM(bn_group_3072_value), OSSL_NELEM(bn_group_3072_value), @@ -260,7 +260,7 @@ static const BN_ULONG bn_group_4096_value[] = { bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) }; -const BIGNUM bn_group_4096 = { +const BIGNUM ossl_bn_group_4096 = { (BN_ULONG *)bn_group_4096_value, OSSL_NELEM(bn_group_4096_value), OSSL_NELEM(bn_group_4096_value), @@ -367,7 +367,7 @@ static const BN_ULONG bn_group_6144_value[] = { bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) }; -const BIGNUM bn_group_6144 = { +const BIGNUM ossl_bn_group_6144 = { (BN_ULONG *)bn_group_6144_value, OSSL_NELEM(bn_group_6144_value), OSSL_NELEM(bn_group_6144_value), @@ -506,7 +506,7 @@ static const BN_ULONG bn_group_8192_value[] = { bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) }; -const BIGNUM bn_group_8192 = { +const BIGNUM ossl_bn_group_8192 = { (BN_ULONG *)bn_group_8192_value, OSSL_NELEM(bn_group_8192_value), OSSL_NELEM(bn_group_8192_value), @@ -516,7 +516,7 @@ const BIGNUM bn_group_8192 = { static const BN_ULONG bn_generator_19_value[] = { 19 }; -const BIGNUM bn_generator_19 = { +const BIGNUM ossl_bn_generator_19 = { (BN_ULONG *)bn_generator_19_value, 1, 1, @@ -525,7 +525,7 @@ const BIGNUM bn_generator_19 = { }; static const BN_ULONG bn_generator_5_value[] = { 5 }; -const BIGNUM bn_generator_5 = { +const BIGNUM ossl_bn_generator_5 = { (BN_ULONG *)bn_generator_5_value, 1, 1, @@ -534,7 +534,7 @@ const BIGNUM bn_generator_5 = { }; static const BN_ULONG bn_generator_2_value[] = { 2 }; -const BIGNUM bn_generator_2 = { +const BIGNUM ossl_bn_generator_2 = { (BN_ULONG *)bn_generator_2_value, 1, 1, diff --git a/crypto/openssl/crypto/bn/bn_word.c b/crypto/openssl/crypto/bn/bn_word.c index 18fb3030a8f4..93c014793e22 100644 --- a/crypto/openssl/crypto/bn/bn_word.c +++ b/crypto/openssl/crypto/bn/bn_word.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bn/bn_x931p.c b/crypto/openssl/crypto/bn/bn_x931p.c index 009950259d41..20d35cf7afbd 100644 --- a/crypto/openssl/crypto/bn/bn_x931p.c +++ b/crypto/openssl/crypto/bn/bn_x931p.c @@ -1,12 +1,14 @@ /* - * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include "bn_local.h" @@ -30,7 +32,7 @@ static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx, i++; BN_GENCB_call(cb, 0, i); /* NB 27 MR is specified in X9.31 */ - is_prime = BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb); + is_prime = BN_check_prime(pi, ctx, cb); if (is_prime < 0) return 0; if (is_prime) @@ -131,7 +133,7 @@ int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, * offering similar or better guarantees 50 MR is considerably * better. */ - int r = BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb); + int r = BN_check_prime(p, ctx, cb); if (r < 0) goto err; if (r) @@ -173,8 +175,9 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) * - 1. By setting the top two bits we ensure that the lower bound is * exceeded. */ - if (!BN_priv_rand(Xp, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY)) - goto err; + if (!BN_priv_rand_ex(Xp, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY, 0, + ctx)) + return 0; BN_CTX_start(ctx); t = BN_CTX_get(ctx); @@ -182,7 +185,8 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) goto err; for (i = 0; i < 1000; i++) { - if (!BN_priv_rand(Xq, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(Xq, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY, 0, + ctx)) goto err; /* Check that |Xp - Xq| > 2^(nbits - 100) */ @@ -227,9 +231,9 @@ int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, if (Xp1 == NULL || Xp2 == NULL) goto error; - if (!BN_priv_rand(Xp1, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(Xp1, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY, 0, ctx)) goto error; - if (!BN_priv_rand(Xp2, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(Xp2, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY, 0, ctx)) goto error; if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb)) goto error; diff --git a/crypto/openssl/crypto/bn/build.info b/crypto/openssl/crypto/bn/build.info index c9fe2fdada69..f4ff6192393e 100644 --- a/crypto/openssl/crypto/bn/build.info +++ b/crypto/openssl/crypto/bn/build.info @@ -1,67 +1,177 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \ - bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \ - bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c \ - {- $target{bn_asm_src} -} \ + +$BNASM=bn_asm.c +IF[{- !$disabled{asm} -}] + # Define source files and macros per asm architecture + # Known macros are: + # + # OPENSSL_BN_ASM_PART_WORDS For any collection with /-586/ file names + # OPENSSL_BN_ASM_MONT For any collection with /-mont/ file names + # OPENSSL_BN_ASM_MONT5 For any collection with /-mont5/ file names + # OPENSSL_BN_ASM_GF2m For any collection with /-gf2m/ file names + # OPENSSL_IA32_SSE2 For any collection with /86/ file names + # when sse2 is enabled + # BN_DIV3W For any collection with /-div3w/ file names + # + # All variables are named in such a way that they can be "indexed" with + # $target{asm_arch} + + $BNASM_x86=bn-586.S co-586.S x86-mont.S x86-gf2m.S + # bn-586 is the only one implementing bn_*_part_words + # => OPENSSL_BN_ASM_PART_WORDS + $BNDEF_x86=OPENSSL_BN_ASM_PART_WORDS OPENSSL_BN_ASM_MONT OPENSSL_BN_ASM_GF2m + $BNDEF_x86_sse2=OPENSSL_IA32_SSE2 + + $BNASM_x86_64=\ + x86_64-mont.s x86_64-mont5.s x86_64-gf2m.s rsaz_exp.c rsaz-x86_64.s \ + rsaz-avx2.s rsaz_exp_x2.c rsaz-avx512.s + IF[{- $config{target} !~ /^VC/ -}] + $BNASM_x86_64=asm/x86_64-gcc.c $BNASM_x86_64 + ELSE + $BNASM_x86_64=bn_asm.c $BNASM_x86_64 + ENDIF + $BNDEF_x86_64=OPENSSL_BN_ASM_MONT OPENSSL_BN_ASM_MONT5 OPENSSL_BN_ASM_GF2m + $BNDEF_x86_64_sse2=OPENSSL_IA32_SSE2 + + IF[{- $config{target} !~ /^VC/ -}] + $BNASM_ia64=bn-ia64.s ia64-mont.s + ELSE + $BNASM_ia64=bn_asm.c ia64-mont.s + ENDIF + + $BNASM_sparcv9=asm/sparcv8plus.S sparcv9-mont.S sparcv9a-mont.S vis3-mont.S \ + sparct4-mont.S bn_sparc.c + $BNDEF_sparcv9=OPENSSL_BN_ASM_MONT + $BNASM_sparcv9_ec2m=sparcv9-gf2m.S + $BNDEF_sparcv9_ec2m=OPENSSL_BN_ASM_GF2m + + $BNASM_sparcv8=asm/sparcv8.S + + $BNASM_alpha=bn_asm.c alpha-mont.S + $BNDEF_alpha=OPENSSL_BN_ASM_MONT + + $BNASM_mips32=bn-mips.S mips-mont.S + $BNDEF_mips32=OPENSSL_BN_ASM_MONT + $BNASM_mips64=$BNASM_mips32 + $BNDEF_mips64=$BNDEF_mips32 + + IF[{- ($target{perlasm_scheme} // '') eq '31' -}] + $BNASM_s390x=bn_asm.c s390x-mont.S + ELSE + $BNASM_s390x=asm/s390x.S s390x-mont.S + ENDIF + $BNDEF_s390x=OPENSSL_BN_ASM_MONT + $BNASM_s390x_ec2m=s390x-gf2m.s + $BNDEF_s390x_ec2m=OPENSSL_BN_ASM_GF2m + + $BNASM_armv4=bn_asm.c armv4-mont.S + $BNDEF_armv4=OPENSSL_BN_ASM_MONT + $BNASM_armv4_ec2m=armv4-gf2m.S + $BNDEF_armv4_ec2m=OPENSSL_BN_ASM_GF2m + + $BNASM_aarch64=bn_asm.c armv8-mont.S + $BNDEF_aarch64=OPENSSL_BN_ASM_MONT + + $BNASM_parisc11=bn_asm.c parisc-mont.s + $BNDEF_parisc11=OPENSSL_BN_ASM_MONT + $BNASM_parisc20_64=$BNASM_parisc11 + $BNDEF_parisc20_64=$BNDEF_parisc11 + + $BNASM_ppc32=bn_ppc.c bn-ppc.s ppc-mont.s + $BNDEF_ppc32=OPENSSL_BN_ASM_MONT + $BNASM_ppc64=$BNASM_ppc32 + $BNDEF_ppc64=$BNDEF_ppc32 + + $BNASM_c64xplus=asm/bn-c64xplus.asm + $BNASM_c64xplus_ec2m=c64xplus-gf2m.s + $BNDEF_c64xplus_ec2m=OPENSSL_BN_ASM_GF2m + + # Now that we have defined all the arch specific variables, use the + # appropriate ones, and define the appropriate macros + IF[$BNASM_{- $target{asm_arch} -}] + $BNASM=$BNASM_{- $target{asm_arch} -} + $BNDEF=$BNDEF_{- $target{asm_arch} -} + IF[{- !$disabled{ec2m} -}] + $BNASM=$BNASM $BNASM_{- $target{asm_arch} -}_ec2m + $BNDEF=$BNDEF $BNDEF_{- $target{asm_arch} -}_ec2m + ENDIF + IF[{- !$disabled{sse2} -}] + $BNDEF=$BNDEF $BNDEF_{- $target{asm_arch} -}_sse2 + ENDIF + ENDIF +ENDIF + +$COMMON=bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c \ + bn_mod.c bn_conv.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \ + bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_sqr.c \ bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \ - bn_depr.c bn_const.c bn_x931p.c bn_intern.c bn_dh.c bn_srp.c \ - rsa_sup_mul.c + bn_intern.c bn_dh.c bn_rsa_fips186_4.c bn_const.c rsa_sup_mul.c +SOURCE[../../libcrypto]=$COMMON $BNASM bn_print.c bn_err.c bn_srp.c +DEFINE[../../libcrypto]=$BNDEF +IF[{- !$disabled{'deprecated-0.9.8'} -}] + SOURCE[../../libcrypto]=bn_depr.c +ENDIF +IF[{- !$disabled{'deprecated-3.0'} -}] + SOURCE[../../libcrypto]=bn_x931p.c +ENDIF +SOURCE[../../providers/libfips.a]=$COMMON $BNASM +DEFINE[../../providers/libfips.a]=$BNDEF +# Implementations are now spread across several libraries, so the defines +# need to be applied to all affected libraries and modules. +DEFINE[../../providers/libcommon.a]=$BNDEF INCLUDE[bn_exp.o]=.. -GENERATE[bn-586.s]=asm/bn-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[bn-586.s]=../perlasm/x86asm.pl -GENERATE[co-586.s]=asm/co-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[co-586.s]=../perlasm/x86asm.pl -GENERATE[x86-mont.s]=asm/x86-mont.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[x86-mont.s]=../perlasm/x86asm.pl -GENERATE[x86-gf2m.s]=asm/x86-gf2m.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[x86-gf2m.s]=../perlasm/x86asm.pl - -GENERATE[sparcv9a-mont.S]=asm/sparcv9a-mont.pl $(PERLASM_SCHEME) +GENERATE[bn-586.S]=asm/bn-586.pl +DEPEND[bn-586.S]=../perlasm/x86asm.pl +GENERATE[co-586.S]=asm/co-586.pl +DEPEND[co-586.S]=../perlasm/x86asm.pl +GENERATE[x86-mont.S]=asm/x86-mont.pl +DEPEND[x86-mont.S]=../perlasm/x86asm.pl +GENERATE[x86-gf2m.S]=asm/x86-gf2m.pl +DEPEND[x86-gf2m.S]=../perlasm/x86asm.pl + +GENERATE[sparcv9a-mont.S]=asm/sparcv9a-mont.pl INCLUDE[sparcv9a-mont.o]=.. -GENERATE[sparcv9-mont.S]=asm/sparcv9-mont.pl $(PERLASM_SCHEME) +GENERATE[sparcv9-mont.S]=asm/sparcv9-mont.pl INCLUDE[sparcv9-mont.o]=.. -GENERATE[vis3-mont.S]=asm/vis3-mont.pl $(PERLASM_SCHEME) +GENERATE[vis3-mont.S]=asm/vis3-mont.pl INCLUDE[vis3-mont.o]=.. -GENERATE[sparct4-mont.S]=asm/sparct4-mont.pl $(PERLASM_SCHEME) +GENERATE[sparct4-mont.S]=asm/sparct4-mont.pl INCLUDE[sparct4-mont.o]=.. -GENERATE[sparcv9-gf2m.S]=asm/sparcv9-gf2m.pl $(PERLASM_SCHEME) +GENERATE[sparcv9-gf2m.S]=asm/sparcv9-gf2m.pl INCLUDE[sparcv9-gf2m.o]=.. -GENERATE[bn-mips.S]=asm/mips.pl $(PERLASM_SCHEME) +GENERATE[bn-mips.S]=asm/mips.pl INCLUDE[bn-mips.o]=.. -GENERATE[mips-mont.S]=asm/mips-mont.pl $(PERLASM_SCHEME) +GENERATE[mips-mont.S]=asm/mips-mont.pl INCLUDE[mips-mont.o]=.. -GENERATE[s390x-mont.S]=asm/s390x-mont.pl $(PERLASM_SCHEME) -GENERATE[s390x-gf2m.s]=asm/s390x-gf2m.pl $(PERLASM_SCHEME) +GENERATE[s390x-mont.S]=asm/s390x-mont.pl +GENERATE[s390x-gf2m.s]=asm/s390x-gf2m.pl -GENERATE[x86_64-mont.s]=asm/x86_64-mont.pl $(PERLASM_SCHEME) -GENERATE[x86_64-mont5.s]=asm/x86_64-mont5.pl $(PERLASM_SCHEME) -GENERATE[x86_64-gf2m.s]=asm/x86_64-gf2m.pl $(PERLASM_SCHEME) -GENERATE[rsaz-x86_64.s]=asm/rsaz-x86_64.pl $(PERLASM_SCHEME) -GENERATE[rsaz-avx2.s]=asm/rsaz-avx2.pl $(PERLASM_SCHEME) +GENERATE[x86_64-mont.s]=asm/x86_64-mont.pl +GENERATE[x86_64-mont5.s]=asm/x86_64-mont5.pl +GENERATE[x86_64-gf2m.s]=asm/x86_64-gf2m.pl +GENERATE[rsaz-x86_64.s]=asm/rsaz-x86_64.pl +GENERATE[rsaz-avx2.s]=asm/rsaz-avx2.pl +GENERATE[rsaz-avx512.s]=asm/rsaz-avx512.pl GENERATE[bn-ia64.s]=asm/ia64.S -GENERATE[ia64-mont.s]=asm/ia64-mont.pl $(LIB_CFLAGS) $(LIB_CPPFLAGS) +GENERATE[ia64-mont.s]=asm/ia64-mont.pl -GENERATE[parisc-mont.s]=asm/parisc-mont.pl $(PERLASM_SCHEME) +GENERATE[parisc-mont.s]=asm/parisc-mont.pl # ppc - AIX, Linux, MacOS X... -GENERATE[bn-ppc.s]=asm/ppc.pl $(PERLASM_SCHEME) -GENERATE[ppc-mont.s]=asm/ppc-mont.pl $(PERLASM_SCHEME) -GENERATE[ppc64-mont.s]=asm/ppc64-mont.pl $(PERLASM_SCHEME) +GENERATE[bn-ppc.s]=asm/ppc.pl +GENERATE[ppc-mont.s]=asm/ppc-mont.pl +GENERATE[ppc64-mont.s]=asm/ppc64-mont.pl -GENERATE[alpha-mont.S]=asm/alpha-mont.pl $(PERLASM_SCHEME) +GENERATE[alpha-mont.S]=asm/alpha-mont.pl -GENERATE[armv4-mont.S]=asm/armv4-mont.pl $(PERLASM_SCHEME) +GENERATE[armv4-mont.S]=asm/armv4-mont.pl INCLUDE[armv4-mont.o]=.. -GENERATE[armv4-gf2m.S]=asm/armv4-gf2m.pl $(PERLASM_SCHEME) +GENERATE[armv4-gf2m.S]=asm/armv4-gf2m.pl INCLUDE[armv4-gf2m.o]=.. -GENERATE[armv8-mont.S]=asm/armv8-mont.pl $(PERLASM_SCHEME) +GENERATE[armv8-mont.S]=asm/armv8-mont.pl +INCLUDE[armv8-mont.o]=.. diff --git a/crypto/openssl/crypto/bn/co-586.S b/crypto/openssl/crypto/bn/co-586.S new file mode 100644 index 000000000000..bc8cd28886ae --- /dev/null +++ b/crypto/openssl/crypto/bn/co-586.S @@ -0,0 +1,1290 @@ +.text +.globl bn_mul_comba8 +.type bn_mul_comba8,@function +.align 16 +bn_mul_comba8: +.L_bn_mul_comba8_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %esi + movl 12(%esp),%esi + pushl %edi + movl 20(%esp),%edi + pushl %ebp + pushl %ebx + xorl %ebx,%ebx + movl (%esi),%eax + xorl %ecx,%ecx + movl (%edi),%edx + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl (%edi),%edx + adcl $0,%ebp + movl %ebx,(%eax) + movl 4(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl (%esi),%eax + adcl %edx,%ebp + movl 4(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl (%edi),%edx + adcl $0,%ebx + movl %ecx,4(%eax) + movl 8(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 4(%esi),%eax + adcl %edx,%ebx + movl 4(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl (%esi),%eax + adcl %edx,%ebx + movl 8(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl (%edi),%edx + adcl $0,%ecx + movl %ebp,8(%eax) + movl 12(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 8(%esi),%eax + adcl %edx,%ecx + movl 4(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 4(%esi),%eax + adcl %edx,%ecx + movl 8(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl (%esi),%eax + adcl %edx,%ecx + movl 12(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl (%edi),%edx + adcl $0,%ebp + movl %ebx,12(%eax) + movl 16(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl 12(%esi),%eax + adcl %edx,%ebp + movl 4(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 8(%esi),%eax + adcl %edx,%ebp + movl 8(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 4(%esi),%eax + adcl %edx,%ebp + movl 12(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl (%esi),%eax + adcl %edx,%ebp + movl 16(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl (%edi),%edx + adcl $0,%ebx + movl %ecx,16(%eax) + movl 20(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 16(%esi),%eax + adcl %edx,%ebx + movl 4(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 12(%esi),%eax + adcl %edx,%ebx + movl 8(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 8(%esi),%eax + adcl %edx,%ebx + movl 12(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 4(%esi),%eax + adcl %edx,%ebx + movl 16(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl (%esi),%eax + adcl %edx,%ebx + movl 20(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl (%edi),%edx + adcl $0,%ecx + movl %ebp,20(%eax) + movl 24(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esi),%eax + adcl %edx,%ecx + movl 4(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 16(%esi),%eax + adcl %edx,%ecx + movl 8(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 12(%esi),%eax + adcl %edx,%ecx + movl 12(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 8(%esi),%eax + adcl %edx,%ecx + movl 16(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 4(%esi),%eax + adcl %edx,%ecx + movl 20(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl (%esi),%eax + adcl %edx,%ecx + movl 24(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl (%edi),%edx + adcl $0,%ebp + movl %ebx,24(%eax) + movl 28(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl 24(%esi),%eax + adcl %edx,%ebp + movl 4(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esi),%eax + adcl %edx,%ebp + movl 8(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 16(%esi),%eax + adcl %edx,%ebp + movl 12(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 12(%esi),%eax + adcl %edx,%ebp + movl 16(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 8(%esi),%eax + adcl %edx,%ebp + movl 20(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 4(%esi),%eax + adcl %edx,%ebp + movl 24(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl (%esi),%eax + adcl %edx,%ebp + movl 28(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl 4(%edi),%edx + adcl $0,%ebx + movl %ecx,28(%eax) + movl 28(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 24(%esi),%eax + adcl %edx,%ebx + movl 8(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esi),%eax + adcl %edx,%ebx + movl 12(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 16(%esi),%eax + adcl %edx,%ebx + movl 16(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 12(%esi),%eax + adcl %edx,%ebx + movl 20(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 8(%esi),%eax + adcl %edx,%ebx + movl 24(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 4(%esi),%eax + adcl %edx,%ebx + movl 28(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl 8(%edi),%edx + adcl $0,%ecx + movl %ebp,32(%eax) + movl 28(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 24(%esi),%eax + adcl %edx,%ecx + movl 12(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esi),%eax + adcl %edx,%ecx + movl 16(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 16(%esi),%eax + adcl %edx,%ecx + movl 20(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 12(%esi),%eax + adcl %edx,%ecx + movl 24(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 8(%esi),%eax + adcl %edx,%ecx + movl 28(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl 12(%edi),%edx + adcl $0,%ebp + movl %ebx,36(%eax) + movl 28(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl 24(%esi),%eax + adcl %edx,%ebp + movl 16(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esi),%eax + adcl %edx,%ebp + movl 20(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 16(%esi),%eax + adcl %edx,%ebp + movl 24(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 12(%esi),%eax + adcl %edx,%ebp + movl 28(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl 16(%edi),%edx + adcl $0,%ebx + movl %ecx,40(%eax) + movl 28(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 24(%esi),%eax + adcl %edx,%ebx + movl 20(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esi),%eax + adcl %edx,%ebx + movl 24(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 16(%esi),%eax + adcl %edx,%ebx + movl 28(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl 20(%edi),%edx + adcl $0,%ecx + movl %ebp,44(%eax) + movl 28(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 24(%esi),%eax + adcl %edx,%ecx + movl 24(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esi),%eax + adcl %edx,%ecx + movl 28(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl 24(%edi),%edx + adcl $0,%ebp + movl %ebx,48(%eax) + movl 28(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl 24(%esi),%eax + adcl %edx,%ebp + movl 28(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl 28(%edi),%edx + adcl $0,%ebx + movl %ecx,52(%eax) + movl 28(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + adcl $0,%ecx + movl %ebp,56(%eax) + + + movl %ebx,60(%eax) + popl %ebx + popl %ebp + popl %edi + popl %esi + ret +.size bn_mul_comba8,.-.L_bn_mul_comba8_begin +.globl bn_mul_comba4 +.type bn_mul_comba4,@function +.align 16 +bn_mul_comba4: +.L_bn_mul_comba4_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %esi + movl 12(%esp),%esi + pushl %edi + movl 20(%esp),%edi + pushl %ebp + pushl %ebx + xorl %ebx,%ebx + movl (%esi),%eax + xorl %ecx,%ecx + movl (%edi),%edx + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl (%edi),%edx + adcl $0,%ebp + movl %ebx,(%eax) + movl 4(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl (%esi),%eax + adcl %edx,%ebp + movl 4(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl (%edi),%edx + adcl $0,%ebx + movl %ecx,4(%eax) + movl 8(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 4(%esi),%eax + adcl %edx,%ebx + movl 4(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl (%esi),%eax + adcl %edx,%ebx + movl 8(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl (%edi),%edx + adcl $0,%ecx + movl %ebp,8(%eax) + movl 12(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 8(%esi),%eax + adcl %edx,%ecx + movl 4(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 4(%esi),%eax + adcl %edx,%ecx + movl 8(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl (%esi),%eax + adcl %edx,%ecx + movl 12(%edi),%edx + adcl $0,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + movl 4(%edi),%edx + adcl $0,%ebp + movl %ebx,12(%eax) + movl 12(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%ecx + movl 8(%esi),%eax + adcl %edx,%ebp + movl 8(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 4(%esi),%eax + adcl %edx,%ebp + movl 12(%edi),%edx + adcl $0,%ebx + + mull %edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edx,%ebp + movl 8(%edi),%edx + adcl $0,%ebx + movl %ecx,16(%eax) + movl 12(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%ebp + movl 8(%esi),%eax + adcl %edx,%ebx + movl 12(%edi),%edx + adcl $0,%ecx + + mull %edx + addl %eax,%ebp + movl 20(%esp),%eax + adcl %edx,%ebx + movl 12(%edi),%edx + adcl $0,%ecx + movl %ebp,20(%eax) + movl 12(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%ebx + movl 20(%esp),%eax + adcl %edx,%ecx + adcl $0,%ebp + movl %ebx,24(%eax) + + + movl %ecx,28(%eax) + popl %ebx + popl %ebp + popl %edi + popl %esi + ret +.size bn_mul_comba4,.-.L_bn_mul_comba4_begin +.globl bn_sqr_comba8 +.type bn_sqr_comba8,@function +.align 16 +bn_sqr_comba8: +.L_bn_sqr_comba8_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %esi + pushl %edi + pushl %ebp + pushl %ebx + movl 20(%esp),%edi + movl 24(%esp),%esi + xorl %ebx,%ebx + xorl %ecx,%ecx + movl (%esi),%eax + + xorl %ebp,%ebp + + mull %eax + addl %eax,%ebx + adcl %edx,%ecx + movl (%esi),%edx + adcl $0,%ebp + movl %ebx,(%edi) + movl 4(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 8(%esi),%eax + adcl $0,%ebx + movl %ecx,4(%edi) + movl (%esi),%edx + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 4(%esi),%eax + adcl $0,%ecx + + mull %eax + addl %eax,%ebp + adcl %edx,%ebx + movl (%esi),%edx + adcl $0,%ecx + movl %ebp,8(%edi) + movl 12(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 8(%esi),%eax + adcl $0,%ebp + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 16(%esi),%eax + adcl $0,%ebp + movl %ebx,12(%edi) + movl (%esi),%edx + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 12(%esi),%eax + adcl $0,%ebx + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 8(%esi),%eax + adcl $0,%ebx + + mull %eax + addl %eax,%ecx + adcl %edx,%ebp + movl (%esi),%edx + adcl $0,%ebx + movl %ecx,16(%edi) + movl 20(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 16(%esi),%eax + adcl $0,%ecx + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 12(%esi),%eax + adcl $0,%ecx + movl 8(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 24(%esi),%eax + adcl $0,%ecx + movl %ebp,20(%edi) + movl (%esi),%edx + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 20(%esi),%eax + adcl $0,%ebp + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 16(%esi),%eax + adcl $0,%ebp + movl 8(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 12(%esi),%eax + adcl $0,%ebp + + mull %eax + addl %eax,%ebx + adcl %edx,%ecx + movl (%esi),%edx + adcl $0,%ebp + movl %ebx,24(%edi) + movl 28(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 24(%esi),%eax + adcl $0,%ebx + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 20(%esi),%eax + adcl $0,%ebx + movl 8(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 16(%esi),%eax + adcl $0,%ebx + movl 12(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 28(%esi),%eax + adcl $0,%ebx + movl %ecx,28(%edi) + movl 4(%esi),%edx + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 24(%esi),%eax + adcl $0,%ecx + movl 8(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 20(%esi),%eax + adcl $0,%ecx + movl 12(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 16(%esi),%eax + adcl $0,%ecx + + mull %eax + addl %eax,%ebp + adcl %edx,%ebx + movl 8(%esi),%edx + adcl $0,%ecx + movl %ebp,32(%edi) + movl 28(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 24(%esi),%eax + adcl $0,%ebp + movl 12(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 20(%esi),%eax + adcl $0,%ebp + movl 16(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 28(%esi),%eax + adcl $0,%ebp + movl %ebx,36(%edi) + movl 12(%esi),%edx + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 24(%esi),%eax + adcl $0,%ebx + movl 16(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 20(%esi),%eax + adcl $0,%ebx + + mull %eax + addl %eax,%ecx + adcl %edx,%ebp + movl 16(%esi),%edx + adcl $0,%ebx + movl %ecx,40(%edi) + movl 28(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 24(%esi),%eax + adcl $0,%ecx + movl 20(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 28(%esi),%eax + adcl $0,%ecx + movl %ebp,44(%edi) + movl 20(%esi),%edx + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 24(%esi),%eax + adcl $0,%ebp + + mull %eax + addl %eax,%ebx + adcl %edx,%ecx + movl 24(%esi),%edx + adcl $0,%ebp + movl %ebx,48(%edi) + movl 28(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 28(%esi),%eax + adcl $0,%ebx + movl %ecx,52(%edi) + + + xorl %ecx,%ecx + + mull %eax + addl %eax,%ebp + adcl %edx,%ebx + adcl $0,%ecx + movl %ebp,56(%edi) + + movl %ebx,60(%edi) + popl %ebx + popl %ebp + popl %edi + popl %esi + ret +.size bn_sqr_comba8,.-.L_bn_sqr_comba8_begin +.globl bn_sqr_comba4 +.type bn_sqr_comba4,@function +.align 16 +bn_sqr_comba4: +.L_bn_sqr_comba4_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %esi + pushl %edi + pushl %ebp + pushl %ebx + movl 20(%esp),%edi + movl 24(%esp),%esi + xorl %ebx,%ebx + xorl %ecx,%ecx + movl (%esi),%eax + + xorl %ebp,%ebp + + mull %eax + addl %eax,%ebx + adcl %edx,%ecx + movl (%esi),%edx + adcl $0,%ebp + movl %ebx,(%edi) + movl 4(%esi),%eax + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 8(%esi),%eax + adcl $0,%ebx + movl %ecx,4(%edi) + movl (%esi),%edx + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 4(%esi),%eax + adcl $0,%ecx + + mull %eax + addl %eax,%ebp + adcl %edx,%ebx + movl (%esi),%edx + adcl $0,%ecx + movl %ebp,8(%edi) + movl 12(%esi),%eax + + + xorl %ebp,%ebp + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 8(%esi),%eax + adcl $0,%ebp + movl 4(%esi),%edx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebp + addl %eax,%ebx + adcl %edx,%ecx + movl 12(%esi),%eax + adcl $0,%ebp + movl %ebx,12(%edi) + movl 4(%esi),%edx + + + xorl %ebx,%ebx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ebx + addl %eax,%ecx + adcl %edx,%ebp + movl 8(%esi),%eax + adcl $0,%ebx + + mull %eax + addl %eax,%ecx + adcl %edx,%ebp + movl 8(%esi),%edx + adcl $0,%ebx + movl %ecx,16(%edi) + movl 12(%esi),%eax + + + xorl %ecx,%ecx + + mull %edx + addl %eax,%eax + adcl %edx,%edx + adcl $0,%ecx + addl %eax,%ebp + adcl %edx,%ebx + movl 12(%esi),%eax + adcl $0,%ecx + movl %ebp,20(%edi) + + + xorl %ebp,%ebp + + mull %eax + addl %eax,%ebx + adcl %edx,%ecx + adcl $0,%ebp + movl %ebx,24(%edi) + + movl %ecx,28(%edi) + popl %ebx + popl %ebp + popl %edi + popl %esi + ret +.size bn_sqr_comba4,.-.L_bn_sqr_comba4_begin + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/bn/rsa_sup_mul.c b/crypto/openssl/crypto/bn/rsa_sup_mul.c index acafefd5febf..0e0d02e1946e 100644 --- a/crypto/openssl/crypto/bn/rsa_sup_mul.c +++ b/crypto/openssl/crypto/bn/rsa_sup_mul.c @@ -5,6 +5,7 @@ #include #include #include +#include "internal/endian.h" #include "internal/numbers.h" #include "internal/constant_time.h" #include "bn_local.h" @@ -12,8 +13,7 @@ # if BN_BYTES == 8 typedef uint64_t limb_t; # if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16 -/* nonstandard; implemented by gcc on 64-bit platforms */ -typedef __uint128_t limb2_t; +typedef uint128_t limb2_t; # define HAVE_LIMB2_T # endif # define LIMB_BIT_SIZE 64 @@ -439,7 +439,7 @@ static void mod_montgomery(limb_t *ret, limb_t *a, size_t anum, limb_t *mod, /* add multiples of the modulus to the value until R divides it cleanly */ for (i = modnum; i > 0; i--, rp--) { - v = _mul_add_limb(rp, mod, modnum, rp[modnum - 1] * ni0, tmp2); + v = _mul_add_limb(rp, mod, modnum, rp[modnum-1] * ni0, tmp2); v = v + carry + rp[-1]; carry |= (v != rp[-1]); carry &= (v <= rp[-1]); @@ -467,48 +467,38 @@ static void BN_to_limb(const BIGNUM *bn, limb_t *buf, size_t limbs) #if LIMB_BYTE_SIZE == 8 static ossl_inline uint64_t be64(uint64_t host) { - const union { - long one; - char little; - } is_endian = { 1 }; - - if (is_endian.little) { - uint64_t big = 0; - - big |= (host & 0xff00000000000000) >> 56; - big |= (host & 0x00ff000000000000) >> 40; - big |= (host & 0x0000ff0000000000) >> 24; - big |= (host & 0x000000ff00000000) >> 8; - big |= (host & 0x00000000ff000000) << 8; - big |= (host & 0x0000000000ff0000) << 24; - big |= (host & 0x000000000000ff00) << 40; - big |= (host & 0x00000000000000ff) << 56; - return big; - } else { + uint64_t big = 0; + DECLARE_IS_ENDIAN; + + if (!IS_LITTLE_ENDIAN) return host; - } + + big |= (host & 0xff00000000000000) >> 56; + big |= (host & 0x00ff000000000000) >> 40; + big |= (host & 0x0000ff0000000000) >> 24; + big |= (host & 0x000000ff00000000) >> 8; + big |= (host & 0x00000000ff000000) << 8; + big |= (host & 0x0000000000ff0000) << 24; + big |= (host & 0x000000000000ff00) << 40; + big |= (host & 0x00000000000000ff) << 56; + return big; } #else /* Not all platforms have htobe32(). */ static ossl_inline uint32_t be32(uint32_t host) { - const union { - long one; - char little; - } is_endian = { 1 }; - - if (is_endian.little) { - uint32_t big = 0; - - big |= (host & 0xff000000) >> 24; - big |= (host & 0x00ff0000) >> 8; - big |= (host & 0x0000ff00) << 8; - big |= (host & 0x000000ff) << 24; - return big; - } else { + uint32_t big = 0; + DECLARE_IS_ENDIAN; + + if (!IS_LITTLE_ENDIAN) return host; - } + + big |= (host & 0xff000000) >> 24; + big |= (host & 0x00ff0000) >> 8; + big |= (host & 0x0000ff00) << 8; + big |= (host & 0x000000ff) << 24; + return big; } #endif @@ -579,7 +569,7 @@ int ossl_bn_rsa_do_unblind(const BIGNUM *intermediate, /* modulus size in bytes can be equal to num but after limbs conversion it becomes bigger */ if (num < BN_num_bytes(to_mod)) { - BNerr(BN_F_OSSL_BN_RSA_DO_UNBLIND, ERR_R_PASSED_INVALID_ARGUMENT); + ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT); goto err; } diff --git a/crypto/openssl/crypto/bn/rsaz-avx2.S b/crypto/openssl/crypto/bn/rsaz-avx2.S new file mode 100644 index 000000000000..80d6c8176645 --- /dev/null +++ b/crypto/openssl/crypto/bn/rsaz-avx2.S @@ -0,0 +1,1765 @@ +.text + +.globl rsaz_1024_sqr_avx2 +.type rsaz_1024_sqr_avx2,@function +.align 64 +rsaz_1024_sqr_avx2: +.cfi_startproc + leaq (%rsp),%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + vzeroupper + movq %rax,%rbp +.cfi_def_cfa_register %rbp + movq %rdx,%r13 + subq $832,%rsp + movq %r13,%r15 + subq $-128,%rdi + subq $-128,%rsi + subq $-128,%r13 + + andq $4095,%r15 + addq $320,%r15 + shrq $12,%r15 + vpxor %ymm9,%ymm9,%ymm9 + jz .Lsqr_1024_no_n_copy + + + + + + subq $320,%rsp + vmovdqu 0-128(%r13),%ymm0 + andq $-2048,%rsp + vmovdqu 32-128(%r13),%ymm1 + vmovdqu 64-128(%r13),%ymm2 + vmovdqu 96-128(%r13),%ymm3 + vmovdqu 128-128(%r13),%ymm4 + vmovdqu 160-128(%r13),%ymm5 + vmovdqu 192-128(%r13),%ymm6 + vmovdqu 224-128(%r13),%ymm7 + vmovdqu 256-128(%r13),%ymm8 + leaq 832+128(%rsp),%r13 + vmovdqu %ymm0,0-128(%r13) + vmovdqu %ymm1,32-128(%r13) + vmovdqu %ymm2,64-128(%r13) + vmovdqu %ymm3,96-128(%r13) + vmovdqu %ymm4,128-128(%r13) + vmovdqu %ymm5,160-128(%r13) + vmovdqu %ymm6,192-128(%r13) + vmovdqu %ymm7,224-128(%r13) + vmovdqu %ymm8,256-128(%r13) + vmovdqu %ymm9,288-128(%r13) + +.Lsqr_1024_no_n_copy: + andq $-1024,%rsp + + vmovdqu 32-128(%rsi),%ymm1 + vmovdqu 64-128(%rsi),%ymm2 + vmovdqu 96-128(%rsi),%ymm3 + vmovdqu 128-128(%rsi),%ymm4 + vmovdqu 160-128(%rsi),%ymm5 + vmovdqu 192-128(%rsi),%ymm6 + vmovdqu 224-128(%rsi),%ymm7 + vmovdqu 256-128(%rsi),%ymm8 + + leaq 192(%rsp),%rbx + vmovdqu .Land_mask(%rip),%ymm15 + jmp .LOOP_GRANDE_SQR_1024 + +.align 32 +.LOOP_GRANDE_SQR_1024: + leaq 576+128(%rsp),%r9 + leaq 448(%rsp),%r12 + + + + + vpaddq %ymm1,%ymm1,%ymm1 + vpbroadcastq 0-128(%rsi),%ymm10 + vpaddq %ymm2,%ymm2,%ymm2 + vmovdqa %ymm1,0-128(%r9) + vpaddq %ymm3,%ymm3,%ymm3 + vmovdqa %ymm2,32-128(%r9) + vpaddq %ymm4,%ymm4,%ymm4 + vmovdqa %ymm3,64-128(%r9) + vpaddq %ymm5,%ymm5,%ymm5 + vmovdqa %ymm4,96-128(%r9) + vpaddq %ymm6,%ymm6,%ymm6 + vmovdqa %ymm5,128-128(%r9) + vpaddq %ymm7,%ymm7,%ymm7 + vmovdqa %ymm6,160-128(%r9) + vpaddq %ymm8,%ymm8,%ymm8 + vmovdqa %ymm7,192-128(%r9) + vpxor %ymm9,%ymm9,%ymm9 + vmovdqa %ymm8,224-128(%r9) + + vpmuludq 0-128(%rsi),%ymm10,%ymm0 + vpbroadcastq 32-128(%rsi),%ymm11 + vmovdqu %ymm9,288-192(%rbx) + vpmuludq %ymm10,%ymm1,%ymm1 + vmovdqu %ymm9,320-448(%r12) + vpmuludq %ymm10,%ymm2,%ymm2 + vmovdqu %ymm9,352-448(%r12) + vpmuludq %ymm10,%ymm3,%ymm3 + vmovdqu %ymm9,384-448(%r12) + vpmuludq %ymm10,%ymm4,%ymm4 + vmovdqu %ymm9,416-448(%r12) + vpmuludq %ymm10,%ymm5,%ymm5 + vmovdqu %ymm9,448-448(%r12) + vpmuludq %ymm10,%ymm6,%ymm6 + vmovdqu %ymm9,480-448(%r12) + vpmuludq %ymm10,%ymm7,%ymm7 + vmovdqu %ymm9,512-448(%r12) + vpmuludq %ymm10,%ymm8,%ymm8 + vpbroadcastq 64-128(%rsi),%ymm10 + vmovdqu %ymm9,544-448(%r12) + + movq %rsi,%r15 + movl $4,%r14d + jmp .Lsqr_entry_1024 +.align 32 +.LOOP_SQR_1024: + vpbroadcastq 32-128(%r15),%ymm11 + vpmuludq 0-128(%rsi),%ymm10,%ymm0 + vpaddq 0-192(%rbx),%ymm0,%ymm0 + vpmuludq 0-128(%r9),%ymm10,%ymm1 + vpaddq 32-192(%rbx),%ymm1,%ymm1 + vpmuludq 32-128(%r9),%ymm10,%ymm2 + vpaddq 64-192(%rbx),%ymm2,%ymm2 + vpmuludq 64-128(%r9),%ymm10,%ymm3 + vpaddq 96-192(%rbx),%ymm3,%ymm3 + vpmuludq 96-128(%r9),%ymm10,%ymm4 + vpaddq 128-192(%rbx),%ymm4,%ymm4 + vpmuludq 128-128(%r9),%ymm10,%ymm5 + vpaddq 160-192(%rbx),%ymm5,%ymm5 + vpmuludq 160-128(%r9),%ymm10,%ymm6 + vpaddq 192-192(%rbx),%ymm6,%ymm6 + vpmuludq 192-128(%r9),%ymm10,%ymm7 + vpaddq 224-192(%rbx),%ymm7,%ymm7 + vpmuludq 224-128(%r9),%ymm10,%ymm8 + vpbroadcastq 64-128(%r15),%ymm10 + vpaddq 256-192(%rbx),%ymm8,%ymm8 +.Lsqr_entry_1024: + vmovdqu %ymm0,0-192(%rbx) + vmovdqu %ymm1,32-192(%rbx) + + vpmuludq 32-128(%rsi),%ymm11,%ymm12 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 32-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm3,%ymm3 + vpmuludq 64-128(%r9),%ymm11,%ymm13 + vpaddq %ymm13,%ymm4,%ymm4 + vpmuludq 96-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 128-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm6,%ymm6 + vpmuludq 160-128(%r9),%ymm11,%ymm13 + vpaddq %ymm13,%ymm7,%ymm7 + vpmuludq 192-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq 224-128(%r9),%ymm11,%ymm0 + vpbroadcastq 96-128(%r15),%ymm11 + vpaddq 288-192(%rbx),%ymm0,%ymm0 + + vmovdqu %ymm2,64-192(%rbx) + vmovdqu %ymm3,96-192(%rbx) + + vpmuludq 64-128(%rsi),%ymm10,%ymm13 + vpaddq %ymm13,%ymm4,%ymm4 + vpmuludq 64-128(%r9),%ymm10,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 96-128(%r9),%ymm10,%ymm14 + vpaddq %ymm14,%ymm6,%ymm6 + vpmuludq 128-128(%r9),%ymm10,%ymm13 + vpaddq %ymm13,%ymm7,%ymm7 + vpmuludq 160-128(%r9),%ymm10,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq 192-128(%r9),%ymm10,%ymm14 + vpaddq %ymm14,%ymm0,%ymm0 + vpmuludq 224-128(%r9),%ymm10,%ymm1 + vpbroadcastq 128-128(%r15),%ymm10 + vpaddq 320-448(%r12),%ymm1,%ymm1 + + vmovdqu %ymm4,128-192(%rbx) + vmovdqu %ymm5,160-192(%rbx) + + vpmuludq 96-128(%rsi),%ymm11,%ymm12 + vpaddq %ymm12,%ymm6,%ymm6 + vpmuludq 96-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm7,%ymm7 + vpmuludq 128-128(%r9),%ymm11,%ymm13 + vpaddq %ymm13,%ymm8,%ymm8 + vpmuludq 160-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm0,%ymm0 + vpmuludq 192-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm1,%ymm1 + vpmuludq 224-128(%r9),%ymm11,%ymm2 + vpbroadcastq 160-128(%r15),%ymm11 + vpaddq 352-448(%r12),%ymm2,%ymm2 + + vmovdqu %ymm6,192-192(%rbx) + vmovdqu %ymm7,224-192(%rbx) + + vpmuludq 128-128(%rsi),%ymm10,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq 128-128(%r9),%ymm10,%ymm14 + vpaddq %ymm14,%ymm0,%ymm0 + vpmuludq 160-128(%r9),%ymm10,%ymm13 + vpaddq %ymm13,%ymm1,%ymm1 + vpmuludq 192-128(%r9),%ymm10,%ymm12 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 224-128(%r9),%ymm10,%ymm3 + vpbroadcastq 192-128(%r15),%ymm10 + vpaddq 384-448(%r12),%ymm3,%ymm3 + + vmovdqu %ymm8,256-192(%rbx) + vmovdqu %ymm0,288-192(%rbx) + leaq 8(%rbx),%rbx + + vpmuludq 160-128(%rsi),%ymm11,%ymm13 + vpaddq %ymm13,%ymm1,%ymm1 + vpmuludq 160-128(%r9),%ymm11,%ymm12 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 192-128(%r9),%ymm11,%ymm14 + vpaddq %ymm14,%ymm3,%ymm3 + vpmuludq 224-128(%r9),%ymm11,%ymm4 + vpbroadcastq 224-128(%r15),%ymm11 + vpaddq 416-448(%r12),%ymm4,%ymm4 + + vmovdqu %ymm1,320-448(%r12) + vmovdqu %ymm2,352-448(%r12) + + vpmuludq 192-128(%rsi),%ymm10,%ymm12 + vpaddq %ymm12,%ymm3,%ymm3 + vpmuludq 192-128(%r9),%ymm10,%ymm14 + vpbroadcastq 256-128(%r15),%ymm0 + vpaddq %ymm14,%ymm4,%ymm4 + vpmuludq 224-128(%r9),%ymm10,%ymm5 + vpbroadcastq 0+8-128(%r15),%ymm10 + vpaddq 448-448(%r12),%ymm5,%ymm5 + + vmovdqu %ymm3,384-448(%r12) + vmovdqu %ymm4,416-448(%r12) + leaq 8(%r15),%r15 + + vpmuludq 224-128(%rsi),%ymm11,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 224-128(%r9),%ymm11,%ymm6 + vpaddq 480-448(%r12),%ymm6,%ymm6 + + vpmuludq 256-128(%rsi),%ymm0,%ymm7 + vmovdqu %ymm5,448-448(%r12) + vpaddq 512-448(%r12),%ymm7,%ymm7 + vmovdqu %ymm6,480-448(%r12) + vmovdqu %ymm7,512-448(%r12) + leaq 8(%r12),%r12 + + decl %r14d + jnz .LOOP_SQR_1024 + + vmovdqu 256(%rsp),%ymm8 + vmovdqu 288(%rsp),%ymm1 + vmovdqu 320(%rsp),%ymm2 + leaq 192(%rsp),%rbx + + vpsrlq $29,%ymm8,%ymm14 + vpand %ymm15,%ymm8,%ymm8 + vpsrlq $29,%ymm1,%ymm11 + vpand %ymm15,%ymm1,%ymm1 + + vpermq $0x93,%ymm14,%ymm14 + vpxor %ymm9,%ymm9,%ymm9 + vpermq $0x93,%ymm11,%ymm11 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm8,%ymm8 + vpblendd $3,%ymm11,%ymm9,%ymm11 + vpaddq %ymm14,%ymm1,%ymm1 + vpaddq %ymm11,%ymm2,%ymm2 + vmovdqu %ymm1,288-192(%rbx) + vmovdqu %ymm2,320-192(%rbx) + + movq (%rsp),%rax + movq 8(%rsp),%r10 + movq 16(%rsp),%r11 + movq 24(%rsp),%r12 + vmovdqu 32(%rsp),%ymm1 + vmovdqu 64-192(%rbx),%ymm2 + vmovdqu 96-192(%rbx),%ymm3 + vmovdqu 128-192(%rbx),%ymm4 + vmovdqu 160-192(%rbx),%ymm5 + vmovdqu 192-192(%rbx),%ymm6 + vmovdqu 224-192(%rbx),%ymm7 + + movq %rax,%r9 + imull %ecx,%eax + andl $0x1fffffff,%eax + vmovd %eax,%xmm12 + + movq %rax,%rdx + imulq -128(%r13),%rax + vpbroadcastq %xmm12,%ymm12 + addq %rax,%r9 + movq %rdx,%rax + imulq 8-128(%r13),%rax + shrq $29,%r9 + addq %rax,%r10 + movq %rdx,%rax + imulq 16-128(%r13),%rax + addq %r9,%r10 + addq %rax,%r11 + imulq 24-128(%r13),%rdx + addq %rdx,%r12 + + movq %r10,%rax + imull %ecx,%eax + andl $0x1fffffff,%eax + + movl $9,%r14d + jmp .LOOP_REDUCE_1024 + +.align 32 +.LOOP_REDUCE_1024: + vmovd %eax,%xmm13 + vpbroadcastq %xmm13,%ymm13 + + vpmuludq 32-128(%r13),%ymm12,%ymm10 + movq %rax,%rdx + imulq -128(%r13),%rax + vpaddq %ymm10,%ymm1,%ymm1 + addq %rax,%r10 + vpmuludq 64-128(%r13),%ymm12,%ymm14 + movq %rdx,%rax + imulq 8-128(%r13),%rax + vpaddq %ymm14,%ymm2,%ymm2 + vpmuludq 96-128(%r13),%ymm12,%ymm11 +.byte 0x67 + addq %rax,%r11 +.byte 0x67 + movq %rdx,%rax + imulq 16-128(%r13),%rax + shrq $29,%r10 + vpaddq %ymm11,%ymm3,%ymm3 + vpmuludq 128-128(%r13),%ymm12,%ymm10 + addq %rax,%r12 + addq %r10,%r11 + vpaddq %ymm10,%ymm4,%ymm4 + vpmuludq 160-128(%r13),%ymm12,%ymm14 + movq %r11,%rax + imull %ecx,%eax + vpaddq %ymm14,%ymm5,%ymm5 + vpmuludq 192-128(%r13),%ymm12,%ymm11 + andl $0x1fffffff,%eax + vpaddq %ymm11,%ymm6,%ymm6 + vpmuludq 224-128(%r13),%ymm12,%ymm10 + vpaddq %ymm10,%ymm7,%ymm7 + vpmuludq 256-128(%r13),%ymm12,%ymm14 + vmovd %eax,%xmm12 + + vpaddq %ymm14,%ymm8,%ymm8 + + vpbroadcastq %xmm12,%ymm12 + + vpmuludq 32-8-128(%r13),%ymm13,%ymm11 + vmovdqu 96-8-128(%r13),%ymm14 + movq %rax,%rdx + imulq -128(%r13),%rax + vpaddq %ymm11,%ymm1,%ymm1 + vpmuludq 64-8-128(%r13),%ymm13,%ymm10 + vmovdqu 128-8-128(%r13),%ymm11 + addq %rax,%r11 + movq %rdx,%rax + imulq 8-128(%r13),%rax + vpaddq %ymm10,%ymm2,%ymm2 + addq %r12,%rax + shrq $29,%r11 + vpmuludq %ymm13,%ymm14,%ymm14 + vmovdqu 160-8-128(%r13),%ymm10 + addq %r11,%rax + vpaddq %ymm14,%ymm3,%ymm3 + vpmuludq %ymm13,%ymm11,%ymm11 + vmovdqu 192-8-128(%r13),%ymm14 +.byte 0x67 + movq %rax,%r12 + imull %ecx,%eax + vpaddq %ymm11,%ymm4,%ymm4 + vpmuludq %ymm13,%ymm10,%ymm10 +.byte 0xc4,0x41,0x7e,0x6f,0x9d,0x58,0x00,0x00,0x00 + andl $0x1fffffff,%eax + vpaddq %ymm10,%ymm5,%ymm5 + vpmuludq %ymm13,%ymm14,%ymm14 + vmovdqu 256-8-128(%r13),%ymm10 + vpaddq %ymm14,%ymm6,%ymm6 + vpmuludq %ymm13,%ymm11,%ymm11 + vmovdqu 288-8-128(%r13),%ymm9 + vmovd %eax,%xmm0 + imulq -128(%r13),%rax + vpaddq %ymm11,%ymm7,%ymm7 + vpmuludq %ymm13,%ymm10,%ymm10 + vmovdqu 32-16-128(%r13),%ymm14 + vpbroadcastq %xmm0,%ymm0 + vpaddq %ymm10,%ymm8,%ymm8 + vpmuludq %ymm13,%ymm9,%ymm9 + vmovdqu 64-16-128(%r13),%ymm11 + addq %rax,%r12 + + vmovdqu 32-24-128(%r13),%ymm13 + vpmuludq %ymm12,%ymm14,%ymm14 + vmovdqu 96-16-128(%r13),%ymm10 + vpaddq %ymm14,%ymm1,%ymm1 + vpmuludq %ymm0,%ymm13,%ymm13 + vpmuludq %ymm12,%ymm11,%ymm11 +.byte 0xc4,0x41,0x7e,0x6f,0xb5,0xf0,0xff,0xff,0xff + vpaddq %ymm1,%ymm13,%ymm13 + vpaddq %ymm11,%ymm2,%ymm2 + vpmuludq %ymm12,%ymm10,%ymm10 + vmovdqu 160-16-128(%r13),%ymm11 +.byte 0x67 + vmovq %xmm13,%rax + vmovdqu %ymm13,(%rsp) + vpaddq %ymm10,%ymm3,%ymm3 + vpmuludq %ymm12,%ymm14,%ymm14 + vmovdqu 192-16-128(%r13),%ymm10 + vpaddq %ymm14,%ymm4,%ymm4 + vpmuludq %ymm12,%ymm11,%ymm11 + vmovdqu 224-16-128(%r13),%ymm14 + vpaddq %ymm11,%ymm5,%ymm5 + vpmuludq %ymm12,%ymm10,%ymm10 + vmovdqu 256-16-128(%r13),%ymm11 + vpaddq %ymm10,%ymm6,%ymm6 + vpmuludq %ymm12,%ymm14,%ymm14 + shrq $29,%r12 + vmovdqu 288-16-128(%r13),%ymm10 + addq %r12,%rax + vpaddq %ymm14,%ymm7,%ymm7 + vpmuludq %ymm12,%ymm11,%ymm11 + + movq %rax,%r9 + imull %ecx,%eax + vpaddq %ymm11,%ymm8,%ymm8 + vpmuludq %ymm12,%ymm10,%ymm10 + andl $0x1fffffff,%eax + vmovd %eax,%xmm12 + vmovdqu 96-24-128(%r13),%ymm11 +.byte 0x67 + vpaddq %ymm10,%ymm9,%ymm9 + vpbroadcastq %xmm12,%ymm12 + + vpmuludq 64-24-128(%r13),%ymm0,%ymm14 + vmovdqu 128-24-128(%r13),%ymm10 + movq %rax,%rdx + imulq -128(%r13),%rax + movq 8(%rsp),%r10 + vpaddq %ymm14,%ymm2,%ymm1 + vpmuludq %ymm0,%ymm11,%ymm11 + vmovdqu 160-24-128(%r13),%ymm14 + addq %rax,%r9 + movq %rdx,%rax + imulq 8-128(%r13),%rax +.byte 0x67 + shrq $29,%r9 + movq 16(%rsp),%r11 + vpaddq %ymm11,%ymm3,%ymm2 + vpmuludq %ymm0,%ymm10,%ymm10 + vmovdqu 192-24-128(%r13),%ymm11 + addq %rax,%r10 + movq %rdx,%rax + imulq 16-128(%r13),%rax + vpaddq %ymm10,%ymm4,%ymm3 + vpmuludq %ymm0,%ymm14,%ymm14 + vmovdqu 224-24-128(%r13),%ymm10 + imulq 24-128(%r13),%rdx + addq %rax,%r11 + leaq (%r9,%r10,1),%rax + vpaddq %ymm14,%ymm5,%ymm4 + vpmuludq %ymm0,%ymm11,%ymm11 + vmovdqu 256-24-128(%r13),%ymm14 + movq %rax,%r10 + imull %ecx,%eax + vpmuludq %ymm0,%ymm10,%ymm10 + vpaddq %ymm11,%ymm6,%ymm5 + vmovdqu 288-24-128(%r13),%ymm11 + andl $0x1fffffff,%eax + vpaddq %ymm10,%ymm7,%ymm6 + vpmuludq %ymm0,%ymm14,%ymm14 + addq 24(%rsp),%rdx + vpaddq %ymm14,%ymm8,%ymm7 + vpmuludq %ymm0,%ymm11,%ymm11 + vpaddq %ymm11,%ymm9,%ymm8 + vmovq %r12,%xmm9 + movq %rdx,%r12 + + decl %r14d + jnz .LOOP_REDUCE_1024 + leaq 448(%rsp),%r12 + vpaddq %ymm9,%ymm13,%ymm0 + vpxor %ymm9,%ymm9,%ymm9 + + vpaddq 288-192(%rbx),%ymm0,%ymm0 + vpaddq 320-448(%r12),%ymm1,%ymm1 + vpaddq 352-448(%r12),%ymm2,%ymm2 + vpaddq 384-448(%r12),%ymm3,%ymm3 + vpaddq 416-448(%r12),%ymm4,%ymm4 + vpaddq 448-448(%r12),%ymm5,%ymm5 + vpaddq 480-448(%r12),%ymm6,%ymm6 + vpaddq 512-448(%r12),%ymm7,%ymm7 + vpaddq 544-448(%r12),%ymm8,%ymm8 + + vpsrlq $29,%ymm0,%ymm14 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm11 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm3,%ymm3 + vpermq $0x93,%ymm12,%ymm12 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm13,%ymm13 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm0,%ymm0 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm1,%ymm1 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm2,%ymm2 + vpblendd $3,%ymm13,%ymm9,%ymm13 + vpaddq %ymm12,%ymm3,%ymm3 + vpaddq %ymm13,%ymm4,%ymm4 + + vpsrlq $29,%ymm0,%ymm14 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm11 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm3,%ymm3 + vpermq $0x93,%ymm12,%ymm12 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm13,%ymm13 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm0,%ymm0 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm1,%ymm1 + vmovdqu %ymm0,0-128(%rdi) + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm2,%ymm2 + vmovdqu %ymm1,32-128(%rdi) + vpblendd $3,%ymm13,%ymm9,%ymm13 + vpaddq %ymm12,%ymm3,%ymm3 + vmovdqu %ymm2,64-128(%rdi) + vpaddq %ymm13,%ymm4,%ymm4 + vmovdqu %ymm3,96-128(%rdi) + vpsrlq $29,%ymm4,%ymm14 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm11 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm13,%ymm13 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm4,%ymm4 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm5,%ymm5 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm6,%ymm6 + vpblendd $3,%ymm13,%ymm0,%ymm13 + vpaddq %ymm12,%ymm7,%ymm7 + vpaddq %ymm13,%ymm8,%ymm8 + + vpsrlq $29,%ymm4,%ymm14 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm11 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm12 + vpermq $0x93,%ymm14,%ymm14 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm13 + vpermq $0x93,%ymm11,%ymm11 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm13,%ymm13 + + vpblendd $3,%ymm9,%ymm14,%ymm10 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm14,%ymm11,%ymm14 + vpaddq %ymm10,%ymm4,%ymm4 + vpblendd $3,%ymm11,%ymm12,%ymm11 + vpaddq %ymm14,%ymm5,%ymm5 + vmovdqu %ymm4,128-128(%rdi) + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm11,%ymm6,%ymm6 + vmovdqu %ymm5,160-128(%rdi) + vpblendd $3,%ymm13,%ymm0,%ymm13 + vpaddq %ymm12,%ymm7,%ymm7 + vmovdqu %ymm6,192-128(%rdi) + vpaddq %ymm13,%ymm8,%ymm8 + vmovdqu %ymm7,224-128(%rdi) + vmovdqu %ymm8,256-128(%rdi) + + movq %rdi,%rsi + decl %r8d + jne .LOOP_GRANDE_SQR_1024 + + vzeroall + movq %rbp,%rax +.cfi_def_cfa_register %rax + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lsqr_1024_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_1024_sqr_avx2,.-rsaz_1024_sqr_avx2 +.globl rsaz_1024_mul_avx2 +.type rsaz_1024_mul_avx2,@function +.align 64 +rsaz_1024_mul_avx2: +.cfi_startproc + leaq (%rsp),%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + movq %rax,%rbp +.cfi_def_cfa_register %rbp + vzeroall + movq %rdx,%r13 + subq $64,%rsp + + + + + + +.byte 0x67,0x67 + movq %rsi,%r15 + andq $4095,%r15 + addq $320,%r15 + shrq $12,%r15 + movq %rsi,%r15 + cmovnzq %r13,%rsi + cmovnzq %r15,%r13 + + movq %rcx,%r15 + subq $-128,%rsi + subq $-128,%rcx + subq $-128,%rdi + + andq $4095,%r15 + addq $320,%r15 +.byte 0x67,0x67 + shrq $12,%r15 + jz .Lmul_1024_no_n_copy + + + + + + subq $320,%rsp + vmovdqu 0-128(%rcx),%ymm0 + andq $-512,%rsp + vmovdqu 32-128(%rcx),%ymm1 + vmovdqu 64-128(%rcx),%ymm2 + vmovdqu 96-128(%rcx),%ymm3 + vmovdqu 128-128(%rcx),%ymm4 + vmovdqu 160-128(%rcx),%ymm5 + vmovdqu 192-128(%rcx),%ymm6 + vmovdqu 224-128(%rcx),%ymm7 + vmovdqu 256-128(%rcx),%ymm8 + leaq 64+128(%rsp),%rcx + vmovdqu %ymm0,0-128(%rcx) + vpxor %ymm0,%ymm0,%ymm0 + vmovdqu %ymm1,32-128(%rcx) + vpxor %ymm1,%ymm1,%ymm1 + vmovdqu %ymm2,64-128(%rcx) + vpxor %ymm2,%ymm2,%ymm2 + vmovdqu %ymm3,96-128(%rcx) + vpxor %ymm3,%ymm3,%ymm3 + vmovdqu %ymm4,128-128(%rcx) + vpxor %ymm4,%ymm4,%ymm4 + vmovdqu %ymm5,160-128(%rcx) + vpxor %ymm5,%ymm5,%ymm5 + vmovdqu %ymm6,192-128(%rcx) + vpxor %ymm6,%ymm6,%ymm6 + vmovdqu %ymm7,224-128(%rcx) + vpxor %ymm7,%ymm7,%ymm7 + vmovdqu %ymm8,256-128(%rcx) + vmovdqa %ymm0,%ymm8 + vmovdqu %ymm9,288-128(%rcx) +.Lmul_1024_no_n_copy: + andq $-64,%rsp + + movq (%r13),%rbx + vpbroadcastq (%r13),%ymm10 + vmovdqu %ymm0,(%rsp) + xorq %r9,%r9 +.byte 0x67 + xorq %r10,%r10 + xorq %r11,%r11 + xorq %r12,%r12 + + vmovdqu .Land_mask(%rip),%ymm15 + movl $9,%r14d + vmovdqu %ymm9,288-128(%rdi) + jmp .Loop_mul_1024 + +.align 32 +.Loop_mul_1024: + vpsrlq $29,%ymm3,%ymm9 + movq %rbx,%rax + imulq -128(%rsi),%rax + addq %r9,%rax + movq %rbx,%r10 + imulq 8-128(%rsi),%r10 + addq 8(%rsp),%r10 + + movq %rax,%r9 + imull %r8d,%eax + andl $0x1fffffff,%eax + + movq %rbx,%r11 + imulq 16-128(%rsi),%r11 + addq 16(%rsp),%r11 + + movq %rbx,%r12 + imulq 24-128(%rsi),%r12 + addq 24(%rsp),%r12 + vpmuludq 32-128(%rsi),%ymm10,%ymm0 + vmovd %eax,%xmm11 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq 64-128(%rsi),%ymm10,%ymm12 + vpbroadcastq %xmm11,%ymm11 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq 96-128(%rsi),%ymm10,%ymm13 + vpand %ymm15,%ymm3,%ymm3 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq 128-128(%rsi),%ymm10,%ymm0 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq 160-128(%rsi),%ymm10,%ymm12 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq 192-128(%rsi),%ymm10,%ymm13 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq 224-128(%rsi),%ymm10,%ymm0 + vpermq $0x93,%ymm9,%ymm9 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq 256-128(%rsi),%ymm10,%ymm12 + vpbroadcastq 8(%r13),%ymm10 + vpaddq %ymm12,%ymm8,%ymm8 + + movq %rax,%rdx + imulq -128(%rcx),%rax + addq %rax,%r9 + movq %rdx,%rax + imulq 8-128(%rcx),%rax + addq %rax,%r10 + movq %rdx,%rax + imulq 16-128(%rcx),%rax + addq %rax,%r11 + shrq $29,%r9 + imulq 24-128(%rcx),%rdx + addq %rdx,%r12 + addq %r9,%r10 + + vpmuludq 32-128(%rcx),%ymm11,%ymm13 + vmovq %xmm10,%rbx + vpaddq %ymm13,%ymm1,%ymm1 + vpmuludq 64-128(%rcx),%ymm11,%ymm0 + vpaddq %ymm0,%ymm2,%ymm2 + vpmuludq 96-128(%rcx),%ymm11,%ymm12 + vpaddq %ymm12,%ymm3,%ymm3 + vpmuludq 128-128(%rcx),%ymm11,%ymm13 + vpaddq %ymm13,%ymm4,%ymm4 + vpmuludq 160-128(%rcx),%ymm11,%ymm0 + vpaddq %ymm0,%ymm5,%ymm5 + vpmuludq 192-128(%rcx),%ymm11,%ymm12 + vpaddq %ymm12,%ymm6,%ymm6 + vpmuludq 224-128(%rcx),%ymm11,%ymm13 + vpblendd $3,%ymm14,%ymm9,%ymm12 + vpaddq %ymm13,%ymm7,%ymm7 + vpmuludq 256-128(%rcx),%ymm11,%ymm0 + vpaddq %ymm12,%ymm3,%ymm3 + vpaddq %ymm0,%ymm8,%ymm8 + + movq %rbx,%rax + imulq -128(%rsi),%rax + addq %rax,%r10 + vmovdqu -8+32-128(%rsi),%ymm12 + movq %rbx,%rax + imulq 8-128(%rsi),%rax + addq %rax,%r11 + vmovdqu -8+64-128(%rsi),%ymm13 + + movq %r10,%rax + vpblendd $0xfc,%ymm14,%ymm9,%ymm9 + imull %r8d,%eax + vpaddq %ymm9,%ymm4,%ymm4 + andl $0x1fffffff,%eax + + imulq 16-128(%rsi),%rbx + addq %rbx,%r12 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovd %eax,%xmm11 + vmovdqu -8+96-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm1,%ymm1 + vpmuludq %ymm10,%ymm13,%ymm13 + vpbroadcastq %xmm11,%ymm11 + vmovdqu -8+128-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm2,%ymm2 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -8+160-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm3,%ymm3 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -8+192-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm4,%ymm4 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -8+224-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm5,%ymm5 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -8+256-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm6,%ymm6 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -8+288-128(%rsi),%ymm9 + vpaddq %ymm12,%ymm7,%ymm7 + vpmuludq %ymm10,%ymm13,%ymm13 + vpaddq %ymm13,%ymm8,%ymm8 + vpmuludq %ymm10,%ymm9,%ymm9 + vpbroadcastq 16(%r13),%ymm10 + + movq %rax,%rdx + imulq -128(%rcx),%rax + addq %rax,%r10 + vmovdqu -8+32-128(%rcx),%ymm0 + movq %rdx,%rax + imulq 8-128(%rcx),%rax + addq %rax,%r11 + vmovdqu -8+64-128(%rcx),%ymm12 + shrq $29,%r10 + imulq 16-128(%rcx),%rdx + addq %rdx,%r12 + addq %r10,%r11 + + vpmuludq %ymm11,%ymm0,%ymm0 + vmovq %xmm10,%rbx + vmovdqu -8+96-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -8+128-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -8+160-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -8+192-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -8+224-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -8+256-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -8+288-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm11,%ymm12,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm11,%ymm13,%ymm13 + vpaddq %ymm13,%ymm9,%ymm9 + + vmovdqu -16+32-128(%rsi),%ymm0 + movq %rbx,%rax + imulq -128(%rsi),%rax + addq %r11,%rax + + vmovdqu -16+64-128(%rsi),%ymm12 + movq %rax,%r11 + imull %r8d,%eax + andl $0x1fffffff,%eax + + imulq 8-128(%rsi),%rbx + addq %rbx,%r12 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovd %eax,%xmm11 + vmovdqu -16+96-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm10,%ymm12,%ymm12 + vpbroadcastq %xmm11,%ymm11 + vmovdqu -16+128-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -16+160-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -16+192-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -16+224-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -16+256-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -16+288-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm10,%ymm12,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm10,%ymm13,%ymm13 + vpbroadcastq 24(%r13),%ymm10 + vpaddq %ymm13,%ymm9,%ymm9 + + vmovdqu -16+32-128(%rcx),%ymm0 + movq %rax,%rdx + imulq -128(%rcx),%rax + addq %rax,%r11 + vmovdqu -16+64-128(%rcx),%ymm12 + imulq 8-128(%rcx),%rdx + addq %rdx,%r12 + shrq $29,%r11 + + vpmuludq %ymm11,%ymm0,%ymm0 + vmovq %xmm10,%rbx + vmovdqu -16+96-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -16+128-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -16+160-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -16+192-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -16+224-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -16+256-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -16+288-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -24+32-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -24+64-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm9,%ymm9 + + addq %r11,%r12 + imulq -128(%rsi),%rbx + addq %rbx,%r12 + + movq %r12,%rax + imull %r8d,%eax + andl $0x1fffffff,%eax + + vpmuludq %ymm10,%ymm0,%ymm0 + vmovd %eax,%xmm11 + vmovdqu -24+96-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm1,%ymm1 + vpmuludq %ymm10,%ymm12,%ymm12 + vpbroadcastq %xmm11,%ymm11 + vmovdqu -24+128-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm2,%ymm2 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -24+160-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm3,%ymm3 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -24+192-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm4,%ymm4 + vpmuludq %ymm10,%ymm12,%ymm12 + vmovdqu -24+224-128(%rsi),%ymm0 + vpaddq %ymm12,%ymm5,%ymm5 + vpmuludq %ymm10,%ymm13,%ymm13 + vmovdqu -24+256-128(%rsi),%ymm12 + vpaddq %ymm13,%ymm6,%ymm6 + vpmuludq %ymm10,%ymm0,%ymm0 + vmovdqu -24+288-128(%rsi),%ymm13 + vpaddq %ymm0,%ymm7,%ymm7 + vpmuludq %ymm10,%ymm12,%ymm12 + vpaddq %ymm12,%ymm8,%ymm8 + vpmuludq %ymm10,%ymm13,%ymm13 + vpbroadcastq 32(%r13),%ymm10 + vpaddq %ymm13,%ymm9,%ymm9 + addq $32,%r13 + + vmovdqu -24+32-128(%rcx),%ymm0 + imulq -128(%rcx),%rax + addq %rax,%r12 + shrq $29,%r12 + + vmovdqu -24+64-128(%rcx),%ymm12 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovq %xmm10,%rbx + vmovdqu -24+96-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm1,%ymm0 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu %ymm0,(%rsp) + vpaddq %ymm12,%ymm2,%ymm1 + vmovdqu -24+128-128(%rcx),%ymm0 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -24+160-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm3,%ymm2 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -24+192-128(%rcx),%ymm13 + vpaddq %ymm0,%ymm4,%ymm3 + vpmuludq %ymm11,%ymm12,%ymm12 + vmovdqu -24+224-128(%rcx),%ymm0 + vpaddq %ymm12,%ymm5,%ymm4 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovdqu -24+256-128(%rcx),%ymm12 + vpaddq %ymm13,%ymm6,%ymm5 + vpmuludq %ymm11,%ymm0,%ymm0 + vmovdqu -24+288-128(%rcx),%ymm13 + movq %r12,%r9 + vpaddq %ymm0,%ymm7,%ymm6 + vpmuludq %ymm11,%ymm12,%ymm12 + addq (%rsp),%r9 + vpaddq %ymm12,%ymm8,%ymm7 + vpmuludq %ymm11,%ymm13,%ymm13 + vmovq %r12,%xmm12 + vpaddq %ymm13,%ymm9,%ymm8 + + decl %r14d + jnz .Loop_mul_1024 + vpaddq (%rsp),%ymm12,%ymm0 + + vpsrlq $29,%ymm0,%ymm12 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm13 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm3,%ymm3 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm10,%ymm10 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpermq $0x93,%ymm11,%ymm11 + vpaddq %ymm9,%ymm0,%ymm0 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm1,%ymm1 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm2,%ymm2 + vpblendd $3,%ymm11,%ymm14,%ymm11 + vpaddq %ymm10,%ymm3,%ymm3 + vpaddq %ymm11,%ymm4,%ymm4 + + vpsrlq $29,%ymm0,%ymm12 + vpand %ymm15,%ymm0,%ymm0 + vpsrlq $29,%ymm1,%ymm13 + vpand %ymm15,%ymm1,%ymm1 + vpsrlq $29,%ymm2,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm2,%ymm2 + vpsrlq $29,%ymm3,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm3,%ymm3 + vpermq $0x93,%ymm10,%ymm10 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm11,%ymm11 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm9,%ymm0,%ymm0 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm1,%ymm1 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm2,%ymm2 + vpblendd $3,%ymm11,%ymm14,%ymm11 + vpaddq %ymm10,%ymm3,%ymm3 + vpaddq %ymm11,%ymm4,%ymm4 + + vmovdqu %ymm0,0-128(%rdi) + vmovdqu %ymm1,32-128(%rdi) + vmovdqu %ymm2,64-128(%rdi) + vmovdqu %ymm3,96-128(%rdi) + vpsrlq $29,%ymm4,%ymm12 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm13 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm10,%ymm10 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm11,%ymm11 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm9,%ymm4,%ymm4 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm5,%ymm5 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm6,%ymm6 + vpblendd $3,%ymm11,%ymm0,%ymm11 + vpaddq %ymm10,%ymm7,%ymm7 + vpaddq %ymm11,%ymm8,%ymm8 + + vpsrlq $29,%ymm4,%ymm12 + vpand %ymm15,%ymm4,%ymm4 + vpsrlq $29,%ymm5,%ymm13 + vpand %ymm15,%ymm5,%ymm5 + vpsrlq $29,%ymm6,%ymm10 + vpermq $0x93,%ymm12,%ymm12 + vpand %ymm15,%ymm6,%ymm6 + vpsrlq $29,%ymm7,%ymm11 + vpermq $0x93,%ymm13,%ymm13 + vpand %ymm15,%ymm7,%ymm7 + vpsrlq $29,%ymm8,%ymm0 + vpermq $0x93,%ymm10,%ymm10 + vpand %ymm15,%ymm8,%ymm8 + vpermq $0x93,%ymm11,%ymm11 + + vpblendd $3,%ymm14,%ymm12,%ymm9 + vpermq $0x93,%ymm0,%ymm0 + vpblendd $3,%ymm12,%ymm13,%ymm12 + vpaddq %ymm9,%ymm4,%ymm4 + vpblendd $3,%ymm13,%ymm10,%ymm13 + vpaddq %ymm12,%ymm5,%ymm5 + vpblendd $3,%ymm10,%ymm11,%ymm10 + vpaddq %ymm13,%ymm6,%ymm6 + vpblendd $3,%ymm11,%ymm0,%ymm11 + vpaddq %ymm10,%ymm7,%ymm7 + vpaddq %ymm11,%ymm8,%ymm8 + + vmovdqu %ymm4,128-128(%rdi) + vmovdqu %ymm5,160-128(%rdi) + vmovdqu %ymm6,192-128(%rdi) + vmovdqu %ymm7,224-128(%rdi) + vmovdqu %ymm8,256-128(%rdi) + vzeroupper + + movq %rbp,%rax +.cfi_def_cfa_register %rax + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lmul_1024_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_1024_mul_avx2,.-rsaz_1024_mul_avx2 +.globl rsaz_1024_red2norm_avx2 +.type rsaz_1024_red2norm_avx2,@function +.align 32 +rsaz_1024_red2norm_avx2: +.cfi_startproc + subq $-128,%rsi + xorq %rax,%rax + movq -128(%rsi),%r8 + movq -120(%rsi),%r9 + movq -112(%rsi),%r10 + shlq $0,%r8 + shlq $29,%r9 + movq %r10,%r11 + shlq $58,%r10 + shrq $6,%r11 + addq %r8,%rax + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,0(%rdi) + movq %r11,%rax + movq -104(%rsi),%r8 + movq -96(%rsi),%r9 + shlq $23,%r8 + movq %r9,%r10 + shlq $52,%r9 + shrq $12,%r10 + addq %r8,%rax + addq %r9,%rax + adcq $0,%r10 + movq %rax,8(%rdi) + movq %r10,%rax + movq -88(%rsi),%r11 + movq -80(%rsi),%r8 + shlq $17,%r11 + movq %r8,%r9 + shlq $46,%r8 + shrq $18,%r9 + addq %r11,%rax + addq %r8,%rax + adcq $0,%r9 + movq %rax,16(%rdi) + movq %r9,%rax + movq -72(%rsi),%r10 + movq -64(%rsi),%r11 + shlq $11,%r10 + movq %r11,%r8 + shlq $40,%r11 + shrq $24,%r8 + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,24(%rdi) + movq %r8,%rax + movq -56(%rsi),%r9 + movq -48(%rsi),%r10 + movq -40(%rsi),%r11 + shlq $5,%r9 + shlq $34,%r10 + movq %r11,%r8 + shlq $63,%r11 + shrq $1,%r8 + addq %r9,%rax + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,32(%rdi) + movq %r8,%rax + movq -32(%rsi),%r9 + movq -24(%rsi),%r10 + shlq $28,%r9 + movq %r10,%r11 + shlq $57,%r10 + shrq $7,%r11 + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,40(%rdi) + movq %r11,%rax + movq -16(%rsi),%r8 + movq -8(%rsi),%r9 + shlq $22,%r8 + movq %r9,%r10 + shlq $51,%r9 + shrq $13,%r10 + addq %r8,%rax + addq %r9,%rax + adcq $0,%r10 + movq %rax,48(%rdi) + movq %r10,%rax + movq 0(%rsi),%r11 + movq 8(%rsi),%r8 + shlq $16,%r11 + movq %r8,%r9 + shlq $45,%r8 + shrq $19,%r9 + addq %r11,%rax + addq %r8,%rax + adcq $0,%r9 + movq %rax,56(%rdi) + movq %r9,%rax + movq 16(%rsi),%r10 + movq 24(%rsi),%r11 + shlq $10,%r10 + movq %r11,%r8 + shlq $39,%r11 + shrq $25,%r8 + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,64(%rdi) + movq %r8,%rax + movq 32(%rsi),%r9 + movq 40(%rsi),%r10 + movq 48(%rsi),%r11 + shlq $4,%r9 + shlq $33,%r10 + movq %r11,%r8 + shlq $62,%r11 + shrq $2,%r8 + addq %r9,%rax + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,72(%rdi) + movq %r8,%rax + movq 56(%rsi),%r9 + movq 64(%rsi),%r10 + shlq $27,%r9 + movq %r10,%r11 + shlq $56,%r10 + shrq $8,%r11 + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,80(%rdi) + movq %r11,%rax + movq 72(%rsi),%r8 + movq 80(%rsi),%r9 + shlq $21,%r8 + movq %r9,%r10 + shlq $50,%r9 + shrq $14,%r10 + addq %r8,%rax + addq %r9,%rax + adcq $0,%r10 + movq %rax,88(%rdi) + movq %r10,%rax + movq 88(%rsi),%r11 + movq 96(%rsi),%r8 + shlq $15,%r11 + movq %r8,%r9 + shlq $44,%r8 + shrq $20,%r9 + addq %r11,%rax + addq %r8,%rax + adcq $0,%r9 + movq %rax,96(%rdi) + movq %r9,%rax + movq 104(%rsi),%r10 + movq 112(%rsi),%r11 + shlq $9,%r10 + movq %r11,%r8 + shlq $38,%r11 + shrq $26,%r8 + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,104(%rdi) + movq %r8,%rax + movq 120(%rsi),%r9 + movq 128(%rsi),%r10 + movq 136(%rsi),%r11 + shlq $3,%r9 + shlq $32,%r10 + movq %r11,%r8 + shlq $61,%r11 + shrq $3,%r8 + addq %r9,%rax + addq %r10,%rax + addq %r11,%rax + adcq $0,%r8 + movq %rax,112(%rdi) + movq %r8,%rax + movq 144(%rsi),%r9 + movq 152(%rsi),%r10 + shlq $26,%r9 + movq %r10,%r11 + shlq $55,%r10 + shrq $9,%r11 + addq %r9,%rax + addq %r10,%rax + adcq $0,%r11 + movq %rax,120(%rdi) + movq %r11,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_1024_red2norm_avx2,.-rsaz_1024_red2norm_avx2 + +.globl rsaz_1024_norm2red_avx2 +.type rsaz_1024_norm2red_avx2,@function +.align 32 +rsaz_1024_norm2red_avx2: +.cfi_startproc + subq $-128,%rdi + movq (%rsi),%r8 + movl $0x1fffffff,%eax + movq 8(%rsi),%r9 + movq %r8,%r11 + shrq $0,%r11 + andq %rax,%r11 + movq %r11,-128(%rdi) + movq %r8,%r10 + shrq $29,%r10 + andq %rax,%r10 + movq %r10,-120(%rdi) + shrdq $58,%r9,%r8 + andq %rax,%r8 + movq %r8,-112(%rdi) + movq 16(%rsi),%r10 + movq %r9,%r8 + shrq $23,%r8 + andq %rax,%r8 + movq %r8,-104(%rdi) + shrdq $52,%r10,%r9 + andq %rax,%r9 + movq %r9,-96(%rdi) + movq 24(%rsi),%r11 + movq %r10,%r9 + shrq $17,%r9 + andq %rax,%r9 + movq %r9,-88(%rdi) + shrdq $46,%r11,%r10 + andq %rax,%r10 + movq %r10,-80(%rdi) + movq 32(%rsi),%r8 + movq %r11,%r10 + shrq $11,%r10 + andq %rax,%r10 + movq %r10,-72(%rdi) + shrdq $40,%r8,%r11 + andq %rax,%r11 + movq %r11,-64(%rdi) + movq 40(%rsi),%r9 + movq %r8,%r11 + shrq $5,%r11 + andq %rax,%r11 + movq %r11,-56(%rdi) + movq %r8,%r10 + shrq $34,%r10 + andq %rax,%r10 + movq %r10,-48(%rdi) + shrdq $63,%r9,%r8 + andq %rax,%r8 + movq %r8,-40(%rdi) + movq 48(%rsi),%r10 + movq %r9,%r8 + shrq $28,%r8 + andq %rax,%r8 + movq %r8,-32(%rdi) + shrdq $57,%r10,%r9 + andq %rax,%r9 + movq %r9,-24(%rdi) + movq 56(%rsi),%r11 + movq %r10,%r9 + shrq $22,%r9 + andq %rax,%r9 + movq %r9,-16(%rdi) + shrdq $51,%r11,%r10 + andq %rax,%r10 + movq %r10,-8(%rdi) + movq 64(%rsi),%r8 + movq %r11,%r10 + shrq $16,%r10 + andq %rax,%r10 + movq %r10,0(%rdi) + shrdq $45,%r8,%r11 + andq %rax,%r11 + movq %r11,8(%rdi) + movq 72(%rsi),%r9 + movq %r8,%r11 + shrq $10,%r11 + andq %rax,%r11 + movq %r11,16(%rdi) + shrdq $39,%r9,%r8 + andq %rax,%r8 + movq %r8,24(%rdi) + movq 80(%rsi),%r10 + movq %r9,%r8 + shrq $4,%r8 + andq %rax,%r8 + movq %r8,32(%rdi) + movq %r9,%r11 + shrq $33,%r11 + andq %rax,%r11 + movq %r11,40(%rdi) + shrdq $62,%r10,%r9 + andq %rax,%r9 + movq %r9,48(%rdi) + movq 88(%rsi),%r11 + movq %r10,%r9 + shrq $27,%r9 + andq %rax,%r9 + movq %r9,56(%rdi) + shrdq $56,%r11,%r10 + andq %rax,%r10 + movq %r10,64(%rdi) + movq 96(%rsi),%r8 + movq %r11,%r10 + shrq $21,%r10 + andq %rax,%r10 + movq %r10,72(%rdi) + shrdq $50,%r8,%r11 + andq %rax,%r11 + movq %r11,80(%rdi) + movq 104(%rsi),%r9 + movq %r8,%r11 + shrq $15,%r11 + andq %rax,%r11 + movq %r11,88(%rdi) + shrdq $44,%r9,%r8 + andq %rax,%r8 + movq %r8,96(%rdi) + movq 112(%rsi),%r10 + movq %r9,%r8 + shrq $9,%r8 + andq %rax,%r8 + movq %r8,104(%rdi) + shrdq $38,%r10,%r9 + andq %rax,%r9 + movq %r9,112(%rdi) + movq 120(%rsi),%r11 + movq %r10,%r9 + shrq $3,%r9 + andq %rax,%r9 + movq %r9,120(%rdi) + movq %r10,%r8 + shrq $32,%r8 + andq %rax,%r8 + movq %r8,128(%rdi) + shrdq $61,%r11,%r10 + andq %rax,%r10 + movq %r10,136(%rdi) + xorq %r8,%r8 + movq %r11,%r10 + shrq $26,%r10 + andq %rax,%r10 + movq %r10,144(%rdi) + shrdq $55,%r8,%r11 + andq %rax,%r11 + movq %r11,152(%rdi) + movq %r8,160(%rdi) + movq %r8,168(%rdi) + movq %r8,176(%rdi) + movq %r8,184(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_1024_norm2red_avx2,.-rsaz_1024_norm2red_avx2 +.globl rsaz_1024_scatter5_avx2 +.type rsaz_1024_scatter5_avx2,@function +.align 32 +rsaz_1024_scatter5_avx2: +.cfi_startproc + vzeroupper + vmovdqu .Lscatter_permd(%rip),%ymm5 + shll $4,%edx + leaq (%rdi,%rdx,1),%rdi + movl $9,%eax + jmp .Loop_scatter_1024 + +.align 32 +.Loop_scatter_1024: + vmovdqu (%rsi),%ymm0 + leaq 32(%rsi),%rsi + vpermd %ymm0,%ymm5,%ymm0 + vmovdqu %xmm0,(%rdi) + leaq 512(%rdi),%rdi + decl %eax + jnz .Loop_scatter_1024 + + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_1024_scatter5_avx2,.-rsaz_1024_scatter5_avx2 + +.globl rsaz_1024_gather5_avx2 +.type rsaz_1024_gather5_avx2,@function +.align 32 +rsaz_1024_gather5_avx2: +.cfi_startproc + vzeroupper + movq %rsp,%r11 +.cfi_def_cfa_register %r11 + leaq -256(%rsp),%rsp + andq $-32,%rsp + leaq .Linc(%rip),%r10 + leaq -128(%rsp),%rax + + vmovd %edx,%xmm4 + vmovdqa (%r10),%ymm0 + vmovdqa 32(%r10),%ymm1 + vmovdqa 64(%r10),%ymm5 + vpbroadcastd %xmm4,%ymm4 + + vpaddd %ymm5,%ymm0,%ymm2 + vpcmpeqd %ymm4,%ymm0,%ymm0 + vpaddd %ymm5,%ymm1,%ymm3 + vpcmpeqd %ymm4,%ymm1,%ymm1 + vmovdqa %ymm0,0+128(%rax) + vpaddd %ymm5,%ymm2,%ymm0 + vpcmpeqd %ymm4,%ymm2,%ymm2 + vmovdqa %ymm1,32+128(%rax) + vpaddd %ymm5,%ymm3,%ymm1 + vpcmpeqd %ymm4,%ymm3,%ymm3 + vmovdqa %ymm2,64+128(%rax) + vpaddd %ymm5,%ymm0,%ymm2 + vpcmpeqd %ymm4,%ymm0,%ymm0 + vmovdqa %ymm3,96+128(%rax) + vpaddd %ymm5,%ymm1,%ymm3 + vpcmpeqd %ymm4,%ymm1,%ymm1 + vmovdqa %ymm0,128+128(%rax) + vpaddd %ymm5,%ymm2,%ymm8 + vpcmpeqd %ymm4,%ymm2,%ymm2 + vmovdqa %ymm1,160+128(%rax) + vpaddd %ymm5,%ymm3,%ymm9 + vpcmpeqd %ymm4,%ymm3,%ymm3 + vmovdqa %ymm2,192+128(%rax) + vpaddd %ymm5,%ymm8,%ymm10 + vpcmpeqd %ymm4,%ymm8,%ymm8 + vmovdqa %ymm3,224+128(%rax) + vpaddd %ymm5,%ymm9,%ymm11 + vpcmpeqd %ymm4,%ymm9,%ymm9 + vpaddd %ymm5,%ymm10,%ymm12 + vpcmpeqd %ymm4,%ymm10,%ymm10 + vpaddd %ymm5,%ymm11,%ymm13 + vpcmpeqd %ymm4,%ymm11,%ymm11 + vpaddd %ymm5,%ymm12,%ymm14 + vpcmpeqd %ymm4,%ymm12,%ymm12 + vpaddd %ymm5,%ymm13,%ymm15 + vpcmpeqd %ymm4,%ymm13,%ymm13 + vpcmpeqd %ymm4,%ymm14,%ymm14 + vpcmpeqd %ymm4,%ymm15,%ymm15 + + vmovdqa -32(%r10),%ymm7 + leaq 128(%rsi),%rsi + movl $9,%edx + +.Loop_gather_1024: + vmovdqa 0-128(%rsi),%ymm0 + vmovdqa 32-128(%rsi),%ymm1 + vmovdqa 64-128(%rsi),%ymm2 + vmovdqa 96-128(%rsi),%ymm3 + vpand 0+128(%rax),%ymm0,%ymm0 + vpand 32+128(%rax),%ymm1,%ymm1 + vpand 64+128(%rax),%ymm2,%ymm2 + vpor %ymm0,%ymm1,%ymm4 + vpand 96+128(%rax),%ymm3,%ymm3 + vmovdqa 128-128(%rsi),%ymm0 + vmovdqa 160-128(%rsi),%ymm1 + vpor %ymm2,%ymm3,%ymm5 + vmovdqa 192-128(%rsi),%ymm2 + vmovdqa 224-128(%rsi),%ymm3 + vpand 128+128(%rax),%ymm0,%ymm0 + vpand 160+128(%rax),%ymm1,%ymm1 + vpand 192+128(%rax),%ymm2,%ymm2 + vpor %ymm0,%ymm4,%ymm4 + vpand 224+128(%rax),%ymm3,%ymm3 + vpand 256-128(%rsi),%ymm8,%ymm0 + vpor %ymm1,%ymm5,%ymm5 + vpand 288-128(%rsi),%ymm9,%ymm1 + vpor %ymm2,%ymm4,%ymm4 + vpand 320-128(%rsi),%ymm10,%ymm2 + vpor %ymm3,%ymm5,%ymm5 + vpand 352-128(%rsi),%ymm11,%ymm3 + vpor %ymm0,%ymm4,%ymm4 + vpand 384-128(%rsi),%ymm12,%ymm0 + vpor %ymm1,%ymm5,%ymm5 + vpand 416-128(%rsi),%ymm13,%ymm1 + vpor %ymm2,%ymm4,%ymm4 + vpand 448-128(%rsi),%ymm14,%ymm2 + vpor %ymm3,%ymm5,%ymm5 + vpand 480-128(%rsi),%ymm15,%ymm3 + leaq 512(%rsi),%rsi + vpor %ymm0,%ymm4,%ymm4 + vpor %ymm1,%ymm5,%ymm5 + vpor %ymm2,%ymm4,%ymm4 + vpor %ymm3,%ymm5,%ymm5 + + vpor %ymm5,%ymm4,%ymm4 + vextracti128 $1,%ymm4,%xmm5 + vpor %xmm4,%xmm5,%xmm5 + vpermd %ymm5,%ymm7,%ymm5 + vmovdqu %ymm5,(%rdi) + leaq 32(%rdi),%rdi + decl %edx + jnz .Loop_gather_1024 + + vpxor %ymm0,%ymm0,%ymm0 + vmovdqu %ymm0,(%rdi) + vzeroupper + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_rsaz_1024_gather5: +.size rsaz_1024_gather5_avx2,.-rsaz_1024_gather5_avx2 + +.globl rsaz_avx2_eligible +.type rsaz_avx2_eligible,@function +.align 32 +rsaz_avx2_eligible: + movl OPENSSL_ia32cap_P+8(%rip),%eax + movl $524544,%ecx + movl $0,%edx + andl %eax,%ecx + cmpl $524544,%ecx + cmovel %edx,%eax + andl $32,%eax + shrl $5,%eax + .byte 0xf3,0xc3 +.size rsaz_avx2_eligible,.-rsaz_avx2_eligible + +.align 64 +.Land_mask: +.quad 0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff +.Lscatter_permd: +.long 0,2,4,6,7,7,7,7 +.Lgather_permd: +.long 0,7,1,7,2,7,3,7 +.Linc: +.long 0,0,0,0, 1,1,1,1 +.long 2,2,2,2, 3,3,3,3 +.long 4,4,4,4, 4,4,4,4 +.align 64 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/bn/rsaz-avx512.S b/crypto/openssl/crypto/bn/rsaz-avx512.S new file mode 100644 index 000000000000..9bbe8ebf7d98 --- /dev/null +++ b/crypto/openssl/crypto/bn/rsaz-avx512.S @@ -0,0 +1,901 @@ + +.globl ossl_rsaz_avx512ifma_eligible +.type ossl_rsaz_avx512ifma_eligible,@function +.align 32 +ossl_rsaz_avx512ifma_eligible: + movl OPENSSL_ia32cap_P+8(%rip),%ecx + xorl %eax,%eax + andl $2149777408,%ecx + cmpl $2149777408,%ecx + cmovel %ecx,%eax + .byte 0xf3,0xc3 +.size ossl_rsaz_avx512ifma_eligible, .-ossl_rsaz_avx512ifma_eligible +.text + +.globl ossl_rsaz_amm52x20_x1_256 +.type ossl_rsaz_amm52x20_x1_256,@function +.align 32 +ossl_rsaz_amm52x20_x1_256: +.cfi_startproc +.byte 243,15,30,250 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lrsaz_amm52x20_x1_256_body: + + + vpxord %ymm0,%ymm0,%ymm0 + vmovdqa64 %ymm0,%ymm1 + vmovdqa64 %ymm0,%ymm16 + vmovdqa64 %ymm0,%ymm17 + vmovdqa64 %ymm0,%ymm18 + vmovdqa64 %ymm0,%ymm19 + + xorl %r9d,%r9d + + movq %rdx,%r11 + movq $0xfffffffffffff,%rax + + + movl $5,%ebx + +.align 32 +.Lloop5: + movq 0(%r11),%r13 + + vpbroadcastq %r13,%ymm3 + movq 0(%rsi),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r9 + movq %r12,%r10 + adcq $0,%r10 + + movq %r8,%r13 + imulq %r9,%r13 + andq %rax,%r13 + + vpbroadcastq %r13,%ymm4 + movq 0(%rcx),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r9 + adcq %r12,%r10 + + shrq $52,%r9 + salq $12,%r10 + orq %r10,%r9 + + vpmadd52luq 0(%rsi),%ymm3,%ymm1 + vpmadd52luq 32(%rsi),%ymm3,%ymm16 + vpmadd52luq 64(%rsi),%ymm3,%ymm17 + vpmadd52luq 96(%rsi),%ymm3,%ymm18 + vpmadd52luq 128(%rsi),%ymm3,%ymm19 + + vpmadd52luq 0(%rcx),%ymm4,%ymm1 + vpmadd52luq 32(%rcx),%ymm4,%ymm16 + vpmadd52luq 64(%rcx),%ymm4,%ymm17 + vpmadd52luq 96(%rcx),%ymm4,%ymm18 + vpmadd52luq 128(%rcx),%ymm4,%ymm19 + + + valignq $1,%ymm1,%ymm16,%ymm1 + valignq $1,%ymm16,%ymm17,%ymm16 + valignq $1,%ymm17,%ymm18,%ymm17 + valignq $1,%ymm18,%ymm19,%ymm18 + valignq $1,%ymm19,%ymm0,%ymm19 + + vmovq %xmm1,%r13 + addq %r13,%r9 + + vpmadd52huq 0(%rsi),%ymm3,%ymm1 + vpmadd52huq 32(%rsi),%ymm3,%ymm16 + vpmadd52huq 64(%rsi),%ymm3,%ymm17 + vpmadd52huq 96(%rsi),%ymm3,%ymm18 + vpmadd52huq 128(%rsi),%ymm3,%ymm19 + + vpmadd52huq 0(%rcx),%ymm4,%ymm1 + vpmadd52huq 32(%rcx),%ymm4,%ymm16 + vpmadd52huq 64(%rcx),%ymm4,%ymm17 + vpmadd52huq 96(%rcx),%ymm4,%ymm18 + vpmadd52huq 128(%rcx),%ymm4,%ymm19 + movq 8(%r11),%r13 + + vpbroadcastq %r13,%ymm3 + movq 0(%rsi),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r9 + movq %r12,%r10 + adcq $0,%r10 + + movq %r8,%r13 + imulq %r9,%r13 + andq %rax,%r13 + + vpbroadcastq %r13,%ymm4 + movq 0(%rcx),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r9 + adcq %r12,%r10 + + shrq $52,%r9 + salq $12,%r10 + orq %r10,%r9 + + vpmadd52luq 0(%rsi),%ymm3,%ymm1 + vpmadd52luq 32(%rsi),%ymm3,%ymm16 + vpmadd52luq 64(%rsi),%ymm3,%ymm17 + vpmadd52luq 96(%rsi),%ymm3,%ymm18 + vpmadd52luq 128(%rsi),%ymm3,%ymm19 + + vpmadd52luq 0(%rcx),%ymm4,%ymm1 + vpmadd52luq 32(%rcx),%ymm4,%ymm16 + vpmadd52luq 64(%rcx),%ymm4,%ymm17 + vpmadd52luq 96(%rcx),%ymm4,%ymm18 + vpmadd52luq 128(%rcx),%ymm4,%ymm19 + + + valignq $1,%ymm1,%ymm16,%ymm1 + valignq $1,%ymm16,%ymm17,%ymm16 + valignq $1,%ymm17,%ymm18,%ymm17 + valignq $1,%ymm18,%ymm19,%ymm18 + valignq $1,%ymm19,%ymm0,%ymm19 + + vmovq %xmm1,%r13 + addq %r13,%r9 + + vpmadd52huq 0(%rsi),%ymm3,%ymm1 + vpmadd52huq 32(%rsi),%ymm3,%ymm16 + vpmadd52huq 64(%rsi),%ymm3,%ymm17 + vpmadd52huq 96(%rsi),%ymm3,%ymm18 + vpmadd52huq 128(%rsi),%ymm3,%ymm19 + + vpmadd52huq 0(%rcx),%ymm4,%ymm1 + vpmadd52huq 32(%rcx),%ymm4,%ymm16 + vpmadd52huq 64(%rcx),%ymm4,%ymm17 + vpmadd52huq 96(%rcx),%ymm4,%ymm18 + vpmadd52huq 128(%rcx),%ymm4,%ymm19 + movq 16(%r11),%r13 + + vpbroadcastq %r13,%ymm3 + movq 0(%rsi),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r9 + movq %r12,%r10 + adcq $0,%r10 + + movq %r8,%r13 + imulq %r9,%r13 + andq %rax,%r13 + + vpbroadcastq %r13,%ymm4 + movq 0(%rcx),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r9 + adcq %r12,%r10 + + shrq $52,%r9 + salq $12,%r10 + orq %r10,%r9 + + vpmadd52luq 0(%rsi),%ymm3,%ymm1 + vpmadd52luq 32(%rsi),%ymm3,%ymm16 + vpmadd52luq 64(%rsi),%ymm3,%ymm17 + vpmadd52luq 96(%rsi),%ymm3,%ymm18 + vpmadd52luq 128(%rsi),%ymm3,%ymm19 + + vpmadd52luq 0(%rcx),%ymm4,%ymm1 + vpmadd52luq 32(%rcx),%ymm4,%ymm16 + vpmadd52luq 64(%rcx),%ymm4,%ymm17 + vpmadd52luq 96(%rcx),%ymm4,%ymm18 + vpmadd52luq 128(%rcx),%ymm4,%ymm19 + + + valignq $1,%ymm1,%ymm16,%ymm1 + valignq $1,%ymm16,%ymm17,%ymm16 + valignq $1,%ymm17,%ymm18,%ymm17 + valignq $1,%ymm18,%ymm19,%ymm18 + valignq $1,%ymm19,%ymm0,%ymm19 + + vmovq %xmm1,%r13 + addq %r13,%r9 + + vpmadd52huq 0(%rsi),%ymm3,%ymm1 + vpmadd52huq 32(%rsi),%ymm3,%ymm16 + vpmadd52huq 64(%rsi),%ymm3,%ymm17 + vpmadd52huq 96(%rsi),%ymm3,%ymm18 + vpmadd52huq 128(%rsi),%ymm3,%ymm19 + + vpmadd52huq 0(%rcx),%ymm4,%ymm1 + vpmadd52huq 32(%rcx),%ymm4,%ymm16 + vpmadd52huq 64(%rcx),%ymm4,%ymm17 + vpmadd52huq 96(%rcx),%ymm4,%ymm18 + vpmadd52huq 128(%rcx),%ymm4,%ymm19 + movq 24(%r11),%r13 + + vpbroadcastq %r13,%ymm3 + movq 0(%rsi),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r9 + movq %r12,%r10 + adcq $0,%r10 + + movq %r8,%r13 + imulq %r9,%r13 + andq %rax,%r13 + + vpbroadcastq %r13,%ymm4 + movq 0(%rcx),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r9 + adcq %r12,%r10 + + shrq $52,%r9 + salq $12,%r10 + orq %r10,%r9 + + vpmadd52luq 0(%rsi),%ymm3,%ymm1 + vpmadd52luq 32(%rsi),%ymm3,%ymm16 + vpmadd52luq 64(%rsi),%ymm3,%ymm17 + vpmadd52luq 96(%rsi),%ymm3,%ymm18 + vpmadd52luq 128(%rsi),%ymm3,%ymm19 + + vpmadd52luq 0(%rcx),%ymm4,%ymm1 + vpmadd52luq 32(%rcx),%ymm4,%ymm16 + vpmadd52luq 64(%rcx),%ymm4,%ymm17 + vpmadd52luq 96(%rcx),%ymm4,%ymm18 + vpmadd52luq 128(%rcx),%ymm4,%ymm19 + + + valignq $1,%ymm1,%ymm16,%ymm1 + valignq $1,%ymm16,%ymm17,%ymm16 + valignq $1,%ymm17,%ymm18,%ymm17 + valignq $1,%ymm18,%ymm19,%ymm18 + valignq $1,%ymm19,%ymm0,%ymm19 + + vmovq %xmm1,%r13 + addq %r13,%r9 + + vpmadd52huq 0(%rsi),%ymm3,%ymm1 + vpmadd52huq 32(%rsi),%ymm3,%ymm16 + vpmadd52huq 64(%rsi),%ymm3,%ymm17 + vpmadd52huq 96(%rsi),%ymm3,%ymm18 + vpmadd52huq 128(%rsi),%ymm3,%ymm19 + + vpmadd52huq 0(%rcx),%ymm4,%ymm1 + vpmadd52huq 32(%rcx),%ymm4,%ymm16 + vpmadd52huq 64(%rcx),%ymm4,%ymm17 + vpmadd52huq 96(%rcx),%ymm4,%ymm18 + vpmadd52huq 128(%rcx),%ymm4,%ymm19 + leaq 32(%r11),%r11 + decl %ebx + jne .Lloop5 + + vmovdqa64 .Lmask52x4(%rip),%ymm4 + + vpbroadcastq %r9,%ymm3 + vpblendd $3,%ymm3,%ymm1,%ymm1 + + + + vpsrlq $52,%ymm1,%ymm24 + vpsrlq $52,%ymm16,%ymm25 + vpsrlq $52,%ymm17,%ymm26 + vpsrlq $52,%ymm18,%ymm27 + vpsrlq $52,%ymm19,%ymm28 + + + valignq $3,%ymm27,%ymm28,%ymm28 + valignq $3,%ymm26,%ymm27,%ymm27 + valignq $3,%ymm25,%ymm26,%ymm26 + valignq $3,%ymm24,%ymm25,%ymm25 + valignq $3,%ymm0,%ymm24,%ymm24 + + + vpandq %ymm4,%ymm1,%ymm1 + vpandq %ymm4,%ymm16,%ymm16 + vpandq %ymm4,%ymm17,%ymm17 + vpandq %ymm4,%ymm18,%ymm18 + vpandq %ymm4,%ymm19,%ymm19 + + + vpaddq %ymm24,%ymm1,%ymm1 + vpaddq %ymm25,%ymm16,%ymm16 + vpaddq %ymm26,%ymm17,%ymm17 + vpaddq %ymm27,%ymm18,%ymm18 + vpaddq %ymm28,%ymm19,%ymm19 + + + + vpcmpuq $1,%ymm1,%ymm4,%k1 + vpcmpuq $1,%ymm16,%ymm4,%k2 + vpcmpuq $1,%ymm17,%ymm4,%k3 + vpcmpuq $1,%ymm18,%ymm4,%k4 + vpcmpuq $1,%ymm19,%ymm4,%k5 + kmovb %k1,%r14d + kmovb %k2,%r13d + kmovb %k3,%r12d + kmovb %k4,%r11d + kmovb %k5,%r10d + + + vpcmpuq $0,%ymm1,%ymm4,%k1 + vpcmpuq $0,%ymm16,%ymm4,%k2 + vpcmpuq $0,%ymm17,%ymm4,%k3 + vpcmpuq $0,%ymm18,%ymm4,%k4 + vpcmpuq $0,%ymm19,%ymm4,%k5 + kmovb %k1,%r9d + kmovb %k2,%r8d + kmovb %k3,%ebx + kmovb %k4,%ecx + kmovb %k5,%edx + + + + shlb $4,%r13b + orb %r13b,%r14b + shlb $4,%r11b + orb %r11b,%r12b + + addb %r14b,%r14b + adcb %r12b,%r12b + adcb %r10b,%r10b + + shlb $4,%r8b + orb %r8b,%r9b + shlb $4,%cl + orb %cl,%bl + + addb %r9b,%r14b + adcb %bl,%r12b + adcb %dl,%r10b + + xorb %r9b,%r14b + xorb %bl,%r12b + xorb %dl,%r10b + + kmovb %r14d,%k1 + shrb $4,%r14b + kmovb %r14d,%k2 + kmovb %r12d,%k3 + shrb $4,%r12b + kmovb %r12d,%k4 + kmovb %r10d,%k5 + + + vpsubq %ymm4,%ymm1,%ymm1{%k1} + vpsubq %ymm4,%ymm16,%ymm16{%k2} + vpsubq %ymm4,%ymm17,%ymm17{%k3} + vpsubq %ymm4,%ymm18,%ymm18{%k4} + vpsubq %ymm4,%ymm19,%ymm19{%k5} + + vpandq %ymm4,%ymm1,%ymm1 + vpandq %ymm4,%ymm16,%ymm16 + vpandq %ymm4,%ymm17,%ymm17 + vpandq %ymm4,%ymm18,%ymm18 + vpandq %ymm4,%ymm19,%ymm19 + + vmovdqu64 %ymm1,(%rdi) + vmovdqu64 %ymm16,32(%rdi) + vmovdqu64 %ymm17,64(%rdi) + vmovdqu64 %ymm18,96(%rdi) + vmovdqu64 %ymm19,128(%rdi) + + vzeroupper + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbp +.cfi_restore %rbp + movq 40(%rsp),%rbx +.cfi_restore %rbx + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lrsaz_amm52x20_x1_256_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ossl_rsaz_amm52x20_x1_256, .-ossl_rsaz_amm52x20_x1_256 +.data +.align 32 +.Lmask52x4: +.quad 0xfffffffffffff +.quad 0xfffffffffffff +.quad 0xfffffffffffff +.quad 0xfffffffffffff +.text + +.globl ossl_rsaz_amm52x20_x2_256 +.type ossl_rsaz_amm52x20_x2_256,@function +.align 32 +ossl_rsaz_amm52x20_x2_256: +.cfi_startproc +.byte 243,15,30,250 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lrsaz_amm52x20_x2_256_body: + + + vpxord %ymm0,%ymm0,%ymm0 + vmovdqa64 %ymm0,%ymm1 + vmovdqa64 %ymm0,%ymm16 + vmovdqa64 %ymm0,%ymm17 + vmovdqa64 %ymm0,%ymm18 + vmovdqa64 %ymm0,%ymm19 + vmovdqa64 %ymm0,%ymm2 + vmovdqa64 %ymm0,%ymm20 + vmovdqa64 %ymm0,%ymm21 + vmovdqa64 %ymm0,%ymm22 + vmovdqa64 %ymm0,%ymm23 + + xorl %r9d,%r9d + xorl %r15d,%r15d + + movq %rdx,%r11 + movq $0xfffffffffffff,%rax + + movl $20,%ebx + +.align 32 +.Lloop20: + movq 0(%r11),%r13 + + vpbroadcastq %r13,%ymm3 + movq 0(%rsi),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r9 + movq %r12,%r10 + adcq $0,%r10 + + movq (%r8),%r13 + imulq %r9,%r13 + andq %rax,%r13 + + vpbroadcastq %r13,%ymm4 + movq 0(%rcx),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r9 + adcq %r12,%r10 + + shrq $52,%r9 + salq $12,%r10 + orq %r10,%r9 + + vpmadd52luq 0(%rsi),%ymm3,%ymm1 + vpmadd52luq 32(%rsi),%ymm3,%ymm16 + vpmadd52luq 64(%rsi),%ymm3,%ymm17 + vpmadd52luq 96(%rsi),%ymm3,%ymm18 + vpmadd52luq 128(%rsi),%ymm3,%ymm19 + + vpmadd52luq 0(%rcx),%ymm4,%ymm1 + vpmadd52luq 32(%rcx),%ymm4,%ymm16 + vpmadd52luq 64(%rcx),%ymm4,%ymm17 + vpmadd52luq 96(%rcx),%ymm4,%ymm18 + vpmadd52luq 128(%rcx),%ymm4,%ymm19 + + + valignq $1,%ymm1,%ymm16,%ymm1 + valignq $1,%ymm16,%ymm17,%ymm16 + valignq $1,%ymm17,%ymm18,%ymm17 + valignq $1,%ymm18,%ymm19,%ymm18 + valignq $1,%ymm19,%ymm0,%ymm19 + + vmovq %xmm1,%r13 + addq %r13,%r9 + + vpmadd52huq 0(%rsi),%ymm3,%ymm1 + vpmadd52huq 32(%rsi),%ymm3,%ymm16 + vpmadd52huq 64(%rsi),%ymm3,%ymm17 + vpmadd52huq 96(%rsi),%ymm3,%ymm18 + vpmadd52huq 128(%rsi),%ymm3,%ymm19 + + vpmadd52huq 0(%rcx),%ymm4,%ymm1 + vpmadd52huq 32(%rcx),%ymm4,%ymm16 + vpmadd52huq 64(%rcx),%ymm4,%ymm17 + vpmadd52huq 96(%rcx),%ymm4,%ymm18 + vpmadd52huq 128(%rcx),%ymm4,%ymm19 + movq 160(%r11),%r13 + + vpbroadcastq %r13,%ymm3 + movq 160(%rsi),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r15 + movq %r12,%r10 + adcq $0,%r10 + + movq 8(%r8),%r13 + imulq %r15,%r13 + andq %rax,%r13 + + vpbroadcastq %r13,%ymm4 + movq 160(%rcx),%rdx + mulxq %r13,%r13,%r12 + addq %r13,%r15 + adcq %r12,%r10 + + shrq $52,%r15 + salq $12,%r10 + orq %r10,%r15 + + vpmadd52luq 160(%rsi),%ymm3,%ymm2 + vpmadd52luq 192(%rsi),%ymm3,%ymm20 + vpmadd52luq 224(%rsi),%ymm3,%ymm21 + vpmadd52luq 256(%rsi),%ymm3,%ymm22 + vpmadd52luq 288(%rsi),%ymm3,%ymm23 + + vpmadd52luq 160(%rcx),%ymm4,%ymm2 + vpmadd52luq 192(%rcx),%ymm4,%ymm20 + vpmadd52luq 224(%rcx),%ymm4,%ymm21 + vpmadd52luq 256(%rcx),%ymm4,%ymm22 + vpmadd52luq 288(%rcx),%ymm4,%ymm23 + + + valignq $1,%ymm2,%ymm20,%ymm2 + valignq $1,%ymm20,%ymm21,%ymm20 + valignq $1,%ymm21,%ymm22,%ymm21 + valignq $1,%ymm22,%ymm23,%ymm22 + valignq $1,%ymm23,%ymm0,%ymm23 + + vmovq %xmm2,%r13 + addq %r13,%r15 + + vpmadd52huq 160(%rsi),%ymm3,%ymm2 + vpmadd52huq 192(%rsi),%ymm3,%ymm20 + vpmadd52huq 224(%rsi),%ymm3,%ymm21 + vpmadd52huq 256(%rsi),%ymm3,%ymm22 + vpmadd52huq 288(%rsi),%ymm3,%ymm23 + + vpmadd52huq 160(%rcx),%ymm4,%ymm2 + vpmadd52huq 192(%rcx),%ymm4,%ymm20 + vpmadd52huq 224(%rcx),%ymm4,%ymm21 + vpmadd52huq 256(%rcx),%ymm4,%ymm22 + vpmadd52huq 288(%rcx),%ymm4,%ymm23 + leaq 8(%r11),%r11 + decl %ebx + jne .Lloop20 + + vmovdqa64 .Lmask52x4(%rip),%ymm4 + + vpbroadcastq %r9,%ymm3 + vpblendd $3,%ymm3,%ymm1,%ymm1 + + + + vpsrlq $52,%ymm1,%ymm24 + vpsrlq $52,%ymm16,%ymm25 + vpsrlq $52,%ymm17,%ymm26 + vpsrlq $52,%ymm18,%ymm27 + vpsrlq $52,%ymm19,%ymm28 + + + valignq $3,%ymm27,%ymm28,%ymm28 + valignq $3,%ymm26,%ymm27,%ymm27 + valignq $3,%ymm25,%ymm26,%ymm26 + valignq $3,%ymm24,%ymm25,%ymm25 + valignq $3,%ymm0,%ymm24,%ymm24 + + + vpandq %ymm4,%ymm1,%ymm1 + vpandq %ymm4,%ymm16,%ymm16 + vpandq %ymm4,%ymm17,%ymm17 + vpandq %ymm4,%ymm18,%ymm18 + vpandq %ymm4,%ymm19,%ymm19 + + + vpaddq %ymm24,%ymm1,%ymm1 + vpaddq %ymm25,%ymm16,%ymm16 + vpaddq %ymm26,%ymm17,%ymm17 + vpaddq %ymm27,%ymm18,%ymm18 + vpaddq %ymm28,%ymm19,%ymm19 + + + + vpcmpuq $1,%ymm1,%ymm4,%k1 + vpcmpuq $1,%ymm16,%ymm4,%k2 + vpcmpuq $1,%ymm17,%ymm4,%k3 + vpcmpuq $1,%ymm18,%ymm4,%k4 + vpcmpuq $1,%ymm19,%ymm4,%k5 + kmovb %k1,%r14d + kmovb %k2,%r13d + kmovb %k3,%r12d + kmovb %k4,%r11d + kmovb %k5,%r10d + + + vpcmpuq $0,%ymm1,%ymm4,%k1 + vpcmpuq $0,%ymm16,%ymm4,%k2 + vpcmpuq $0,%ymm17,%ymm4,%k3 + vpcmpuq $0,%ymm18,%ymm4,%k4 + vpcmpuq $0,%ymm19,%ymm4,%k5 + kmovb %k1,%r9d + kmovb %k2,%r8d + kmovb %k3,%ebx + kmovb %k4,%ecx + kmovb %k5,%edx + + + + shlb $4,%r13b + orb %r13b,%r14b + shlb $4,%r11b + orb %r11b,%r12b + + addb %r14b,%r14b + adcb %r12b,%r12b + adcb %r10b,%r10b + + shlb $4,%r8b + orb %r8b,%r9b + shlb $4,%cl + orb %cl,%bl + + addb %r9b,%r14b + adcb %bl,%r12b + adcb %dl,%r10b + + xorb %r9b,%r14b + xorb %bl,%r12b + xorb %dl,%r10b + + kmovb %r14d,%k1 + shrb $4,%r14b + kmovb %r14d,%k2 + kmovb %r12d,%k3 + shrb $4,%r12b + kmovb %r12d,%k4 + kmovb %r10d,%k5 + + + vpsubq %ymm4,%ymm1,%ymm1{%k1} + vpsubq %ymm4,%ymm16,%ymm16{%k2} + vpsubq %ymm4,%ymm17,%ymm17{%k3} + vpsubq %ymm4,%ymm18,%ymm18{%k4} + vpsubq %ymm4,%ymm19,%ymm19{%k5} + + vpandq %ymm4,%ymm1,%ymm1 + vpandq %ymm4,%ymm16,%ymm16 + vpandq %ymm4,%ymm17,%ymm17 + vpandq %ymm4,%ymm18,%ymm18 + vpandq %ymm4,%ymm19,%ymm19 + + vpbroadcastq %r15,%ymm3 + vpblendd $3,%ymm3,%ymm2,%ymm2 + + + + vpsrlq $52,%ymm2,%ymm24 + vpsrlq $52,%ymm20,%ymm25 + vpsrlq $52,%ymm21,%ymm26 + vpsrlq $52,%ymm22,%ymm27 + vpsrlq $52,%ymm23,%ymm28 + + + valignq $3,%ymm27,%ymm28,%ymm28 + valignq $3,%ymm26,%ymm27,%ymm27 + valignq $3,%ymm25,%ymm26,%ymm26 + valignq $3,%ymm24,%ymm25,%ymm25 + valignq $3,%ymm0,%ymm24,%ymm24 + + + vpandq %ymm4,%ymm2,%ymm2 + vpandq %ymm4,%ymm20,%ymm20 + vpandq %ymm4,%ymm21,%ymm21 + vpandq %ymm4,%ymm22,%ymm22 + vpandq %ymm4,%ymm23,%ymm23 + + + vpaddq %ymm24,%ymm2,%ymm2 + vpaddq %ymm25,%ymm20,%ymm20 + vpaddq %ymm26,%ymm21,%ymm21 + vpaddq %ymm27,%ymm22,%ymm22 + vpaddq %ymm28,%ymm23,%ymm23 + + + + vpcmpuq $1,%ymm2,%ymm4,%k1 + vpcmpuq $1,%ymm20,%ymm4,%k2 + vpcmpuq $1,%ymm21,%ymm4,%k3 + vpcmpuq $1,%ymm22,%ymm4,%k4 + vpcmpuq $1,%ymm23,%ymm4,%k5 + kmovb %k1,%r14d + kmovb %k2,%r13d + kmovb %k3,%r12d + kmovb %k4,%r11d + kmovb %k5,%r10d + + + vpcmpuq $0,%ymm2,%ymm4,%k1 + vpcmpuq $0,%ymm20,%ymm4,%k2 + vpcmpuq $0,%ymm21,%ymm4,%k3 + vpcmpuq $0,%ymm22,%ymm4,%k4 + vpcmpuq $0,%ymm23,%ymm4,%k5 + kmovb %k1,%r9d + kmovb %k2,%r8d + kmovb %k3,%ebx + kmovb %k4,%ecx + kmovb %k5,%edx + + + + shlb $4,%r13b + orb %r13b,%r14b + shlb $4,%r11b + orb %r11b,%r12b + + addb %r14b,%r14b + adcb %r12b,%r12b + adcb %r10b,%r10b + + shlb $4,%r8b + orb %r8b,%r9b + shlb $4,%cl + orb %cl,%bl + + addb %r9b,%r14b + adcb %bl,%r12b + adcb %dl,%r10b + + xorb %r9b,%r14b + xorb %bl,%r12b + xorb %dl,%r10b + + kmovb %r14d,%k1 + shrb $4,%r14b + kmovb %r14d,%k2 + kmovb %r12d,%k3 + shrb $4,%r12b + kmovb %r12d,%k4 + kmovb %r10d,%k5 + + + vpsubq %ymm4,%ymm2,%ymm2{%k1} + vpsubq %ymm4,%ymm20,%ymm20{%k2} + vpsubq %ymm4,%ymm21,%ymm21{%k3} + vpsubq %ymm4,%ymm22,%ymm22{%k4} + vpsubq %ymm4,%ymm23,%ymm23{%k5} + + vpandq %ymm4,%ymm2,%ymm2 + vpandq %ymm4,%ymm20,%ymm20 + vpandq %ymm4,%ymm21,%ymm21 + vpandq %ymm4,%ymm22,%ymm22 + vpandq %ymm4,%ymm23,%ymm23 + + vmovdqu64 %ymm1,(%rdi) + vmovdqu64 %ymm16,32(%rdi) + vmovdqu64 %ymm17,64(%rdi) + vmovdqu64 %ymm18,96(%rdi) + vmovdqu64 %ymm19,128(%rdi) + + vmovdqu64 %ymm2,160(%rdi) + vmovdqu64 %ymm20,192(%rdi) + vmovdqu64 %ymm21,224(%rdi) + vmovdqu64 %ymm22,256(%rdi) + vmovdqu64 %ymm23,288(%rdi) + + vzeroupper + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbp +.cfi_restore %rbp + movq 40(%rsp),%rbx +.cfi_restore %rbx + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lrsaz_amm52x20_x2_256_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ossl_rsaz_amm52x20_x2_256, .-ossl_rsaz_amm52x20_x2_256 +.text + +.align 32 +.globl ossl_extract_multiplier_2x20_win5 +.type ossl_extract_multiplier_2x20_win5,@function +ossl_extract_multiplier_2x20_win5: +.cfi_startproc +.byte 243,15,30,250 + leaq (%rcx,%rcx,4),%rax + salq $5,%rax + addq %rax,%rsi + + vmovdqa64 .Lones(%rip),%ymm23 + vpbroadcastq %rdx,%ymm22 + leaq 10240(%rsi),%rax + + vpxor %xmm4,%xmm4,%xmm4 + vmovdqa64 %ymm4,%ymm3 + vmovdqa64 %ymm4,%ymm2 + vmovdqa64 %ymm4,%ymm1 + vmovdqa64 %ymm4,%ymm0 + vmovdqa64 %ymm4,%ymm21 + +.align 32 +.Lloop: + vpcmpq $0,%ymm21,%ymm22,%k1 + addq $320,%rsi + vpaddq %ymm23,%ymm21,%ymm21 + vmovdqu64 -320(%rsi),%ymm16 + vmovdqu64 -288(%rsi),%ymm17 + vmovdqu64 -256(%rsi),%ymm18 + vmovdqu64 -224(%rsi),%ymm19 + vmovdqu64 -192(%rsi),%ymm20 + vpblendmq %ymm16,%ymm0,%ymm0{%k1} + vpblendmq %ymm17,%ymm1,%ymm1{%k1} + vpblendmq %ymm18,%ymm2,%ymm2{%k1} + vpblendmq %ymm19,%ymm3,%ymm3{%k1} + vpblendmq %ymm20,%ymm4,%ymm4{%k1} + cmpq %rsi,%rax + jne .Lloop + + vmovdqu64 %ymm0,(%rdi) + vmovdqu64 %ymm1,32(%rdi) + vmovdqu64 %ymm2,64(%rdi) + vmovdqu64 %ymm3,96(%rdi) + vmovdqu64 %ymm4,128(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size ossl_extract_multiplier_2x20_win5, .-ossl_extract_multiplier_2x20_win5 +.data +.align 32 +.Lones: +.quad 1,1,1,1 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/bn/rsaz-x86_64.S b/crypto/openssl/crypto/bn/rsaz-x86_64.S new file mode 100644 index 000000000000..0b2513c819db --- /dev/null +++ b/crypto/openssl/crypto/bn/rsaz-x86_64.S @@ -0,0 +1,2036 @@ +.text + + + +.globl rsaz_512_sqr +.type rsaz_512_sqr,@function +.align 32 +rsaz_512_sqr: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + + subq $128+24,%rsp +.cfi_adjust_cfa_offset 128+24 +.Lsqr_body: +.byte 102,72,15,110,202 + movq (%rsi),%rdx + movq 8(%rsi),%rax + movq %rcx,128(%rsp) + movl $0x80100,%r11d + andl OPENSSL_ia32cap_P+8(%rip),%r11d + cmpl $0x80100,%r11d + je .Loop_sqrx + jmp .Loop_sqr + +.align 32 +.Loop_sqr: + movl %r8d,128+8(%rsp) + + movq %rdx,%rbx + movq %rax,%rbp + mulq %rdx + movq %rax,%r8 + movq 16(%rsi),%rax + movq %rdx,%r9 + + mulq %rbx + addq %rax,%r9 + movq 24(%rsi),%rax + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r10 + movq 32(%rsi),%rax + movq %rdx,%r11 + adcq $0,%r11 + + mulq %rbx + addq %rax,%r11 + movq 40(%rsi),%rax + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r12 + movq 48(%rsi),%rax + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r13 + movq 56(%rsi),%rax + movq %rdx,%r14 + adcq $0,%r14 + + mulq %rbx + addq %rax,%r14 + movq %rbx,%rax + adcq $0,%rdx + + xorq %rcx,%rcx + addq %r8,%r8 + movq %rdx,%r15 + adcq $0,%rcx + + mulq %rax + addq %r8,%rdx + adcq $0,%rcx + + movq %rax,(%rsp) + movq %rdx,8(%rsp) + + + movq 16(%rsi),%rax + mulq %rbp + addq %rax,%r10 + movq 24(%rsi),%rax + movq %rdx,%rbx + adcq $0,%rbx + + mulq %rbp + addq %rax,%r11 + movq 32(%rsi),%rax + adcq $0,%rdx + addq %rbx,%r11 + movq %rdx,%rbx + adcq $0,%rbx + + mulq %rbp + addq %rax,%r12 + movq 40(%rsi),%rax + adcq $0,%rdx + addq %rbx,%r12 + movq %rdx,%rbx + adcq $0,%rbx + + mulq %rbp + addq %rax,%r13 + movq 48(%rsi),%rax + adcq $0,%rdx + addq %rbx,%r13 + movq %rdx,%rbx + adcq $0,%rbx + + mulq %rbp + addq %rax,%r14 + movq 56(%rsi),%rax + adcq $0,%rdx + addq %rbx,%r14 + movq %rdx,%rbx + adcq $0,%rbx + + mulq %rbp + addq %rax,%r15 + movq %rbp,%rax + adcq $0,%rdx + addq %rbx,%r15 + adcq $0,%rdx + + xorq %rbx,%rbx + addq %r9,%r9 + movq %rdx,%r8 + adcq %r10,%r10 + adcq $0,%rbx + + mulq %rax + + addq %rcx,%rax + movq 16(%rsi),%rbp + addq %rax,%r9 + movq 24(%rsi),%rax + adcq %rdx,%r10 + adcq $0,%rbx + + movq %r9,16(%rsp) + movq %r10,24(%rsp) + + + mulq %rbp + addq %rax,%r12 + movq 32(%rsi),%rax + movq %rdx,%rcx + adcq $0,%rcx + + mulq %rbp + addq %rax,%r13 + movq 40(%rsi),%rax + adcq $0,%rdx + addq %rcx,%r13 + movq %rdx,%rcx + adcq $0,%rcx + + mulq %rbp + addq %rax,%r14 + movq 48(%rsi),%rax + adcq $0,%rdx + addq %rcx,%r14 + movq %rdx,%rcx + adcq $0,%rcx + + mulq %rbp + addq %rax,%r15 + movq 56(%rsi),%rax + adcq $0,%rdx + addq %rcx,%r15 + movq %rdx,%rcx + adcq $0,%rcx + + mulq %rbp + addq %rax,%r8 + movq %rbp,%rax + adcq $0,%rdx + addq %rcx,%r8 + adcq $0,%rdx + + xorq %rcx,%rcx + addq %r11,%r11 + movq %rdx,%r9 + adcq %r12,%r12 + adcq $0,%rcx + + mulq %rax + + addq %rbx,%rax + movq 24(%rsi),%r10 + addq %rax,%r11 + movq 32(%rsi),%rax + adcq %rdx,%r12 + adcq $0,%rcx + + movq %r11,32(%rsp) + movq %r12,40(%rsp) + + + movq %rax,%r11 + mulq %r10 + addq %rax,%r14 + movq 40(%rsi),%rax + movq %rdx,%rbx + adcq $0,%rbx + + movq %rax,%r12 + mulq %r10 + addq %rax,%r15 + movq 48(%rsi),%rax + adcq $0,%rdx + addq %rbx,%r15 + movq %rdx,%rbx + adcq $0,%rbx + + movq %rax,%rbp + mulq %r10 + addq %rax,%r8 + movq 56(%rsi),%rax + adcq $0,%rdx + addq %rbx,%r8 + movq %rdx,%rbx + adcq $0,%rbx + + mulq %r10 + addq %rax,%r9 + movq %r10,%rax + adcq $0,%rdx + addq %rbx,%r9 + adcq $0,%rdx + + xorq %rbx,%rbx + addq %r13,%r13 + movq %rdx,%r10 + adcq %r14,%r14 + adcq $0,%rbx + + mulq %rax + + addq %rcx,%rax + addq %rax,%r13 + movq %r12,%rax + adcq %rdx,%r14 + adcq $0,%rbx + + movq %r13,48(%rsp) + movq %r14,56(%rsp) + + + mulq %r11 + addq %rax,%r8 + movq %rbp,%rax + movq %rdx,%rcx + adcq $0,%rcx + + mulq %r11 + addq %rax,%r9 + movq 56(%rsi),%rax + adcq $0,%rdx + addq %rcx,%r9 + movq %rdx,%rcx + adcq $0,%rcx + + movq %rax,%r14 + mulq %r11 + addq %rax,%r10 + movq %r11,%rax + adcq $0,%rdx + addq %rcx,%r10 + adcq $0,%rdx + + xorq %rcx,%rcx + addq %r15,%r15 + movq %rdx,%r11 + adcq %r8,%r8 + adcq $0,%rcx + + mulq %rax + + addq %rbx,%rax + addq %rax,%r15 + movq %rbp,%rax + adcq %rdx,%r8 + adcq $0,%rcx + + movq %r15,64(%rsp) + movq %r8,72(%rsp) + + + mulq %r12 + addq %rax,%r10 + movq %r14,%rax + movq %rdx,%rbx + adcq $0,%rbx + + mulq %r12 + addq %rax,%r11 + movq %r12,%rax + adcq $0,%rdx + addq %rbx,%r11 + adcq $0,%rdx + + xorq %rbx,%rbx + addq %r9,%r9 + movq %rdx,%r12 + adcq %r10,%r10 + adcq $0,%rbx + + mulq %rax + + addq %rcx,%rax + addq %rax,%r9 + movq %r14,%rax + adcq %rdx,%r10 + adcq $0,%rbx + + movq %r9,80(%rsp) + movq %r10,88(%rsp) + + + mulq %rbp + addq %rax,%r12 + movq %rbp,%rax + adcq $0,%rdx + + xorq %rcx,%rcx + addq %r11,%r11 + movq %rdx,%r13 + adcq %r12,%r12 + adcq $0,%rcx + + mulq %rax + + addq %rbx,%rax + addq %rax,%r11 + movq %r14,%rax + adcq %rdx,%r12 + adcq $0,%rcx + + movq %r11,96(%rsp) + movq %r12,104(%rsp) + + + xorq %rbx,%rbx + addq %r13,%r13 + adcq $0,%rbx + + mulq %rax + + addq %rcx,%rax + addq %r13,%rax + adcq %rbx,%rdx + + movq (%rsp),%r8 + movq 8(%rsp),%r9 + movq 16(%rsp),%r10 + movq 24(%rsp),%r11 + movq 32(%rsp),%r12 + movq 40(%rsp),%r13 + movq 48(%rsp),%r14 + movq 56(%rsp),%r15 +.byte 102,72,15,126,205 + + movq %rax,112(%rsp) + movq %rdx,120(%rsp) + + call __rsaz_512_reduce + + addq 64(%rsp),%r8 + adcq 72(%rsp),%r9 + adcq 80(%rsp),%r10 + adcq 88(%rsp),%r11 + adcq 96(%rsp),%r12 + adcq 104(%rsp),%r13 + adcq 112(%rsp),%r14 + adcq 120(%rsp),%r15 + sbbq %rcx,%rcx + + call __rsaz_512_subtract + + movq %r8,%rdx + movq %r9,%rax + movl 128+8(%rsp),%r8d + movq %rdi,%rsi + + decl %r8d + jnz .Loop_sqr + jmp .Lsqr_tail + +.align 32 +.Loop_sqrx: + movl %r8d,128+8(%rsp) +.byte 102,72,15,110,199 + + mulxq %rax,%r8,%r9 + movq %rax,%rbx + + mulxq 16(%rsi),%rcx,%r10 + xorq %rbp,%rbp + + mulxq 24(%rsi),%rax,%r11 + adcxq %rcx,%r9 + +.byte 0xc4,0x62,0xf3,0xf6,0xa6,0x20,0x00,0x00,0x00 + adcxq %rax,%r10 + +.byte 0xc4,0x62,0xfb,0xf6,0xae,0x28,0x00,0x00,0x00 + adcxq %rcx,%r11 + + mulxq 48(%rsi),%rcx,%r14 + adcxq %rax,%r12 + adcxq %rcx,%r13 + + mulxq 56(%rsi),%rax,%r15 + adcxq %rax,%r14 + adcxq %rbp,%r15 + + mulxq %rdx,%rax,%rdi + movq %rbx,%rdx + xorq %rcx,%rcx + adoxq %r8,%r8 + adcxq %rdi,%r8 + adoxq %rbp,%rcx + adcxq %rbp,%rcx + + movq %rax,(%rsp) + movq %r8,8(%rsp) + + +.byte 0xc4,0xe2,0xfb,0xf6,0x9e,0x10,0x00,0x00,0x00 + adoxq %rax,%r10 + adcxq %rbx,%r11 + + mulxq 24(%rsi),%rdi,%r8 + adoxq %rdi,%r11 +.byte 0x66 + adcxq %r8,%r12 + + mulxq 32(%rsi),%rax,%rbx + adoxq %rax,%r12 + adcxq %rbx,%r13 + + mulxq 40(%rsi),%rdi,%r8 + adoxq %rdi,%r13 + adcxq %r8,%r14 + +.byte 0xc4,0xe2,0xfb,0xf6,0x9e,0x30,0x00,0x00,0x00 + adoxq %rax,%r14 + adcxq %rbx,%r15 + +.byte 0xc4,0x62,0xc3,0xf6,0x86,0x38,0x00,0x00,0x00 + adoxq %rdi,%r15 + adcxq %rbp,%r8 + mulxq %rdx,%rax,%rdi + adoxq %rbp,%r8 +.byte 0x48,0x8b,0x96,0x10,0x00,0x00,0x00 + + xorq %rbx,%rbx + adoxq %r9,%r9 + + adcxq %rcx,%rax + adoxq %r10,%r10 + adcxq %rax,%r9 + adoxq %rbp,%rbx + adcxq %rdi,%r10 + adcxq %rbp,%rbx + + movq %r9,16(%rsp) +.byte 0x4c,0x89,0x94,0x24,0x18,0x00,0x00,0x00 + + + mulxq 24(%rsi),%rdi,%r9 + adoxq %rdi,%r12 + adcxq %r9,%r13 + + mulxq 32(%rsi),%rax,%rcx + adoxq %rax,%r13 + adcxq %rcx,%r14 + +.byte 0xc4,0x62,0xc3,0xf6,0x8e,0x28,0x00,0x00,0x00 + adoxq %rdi,%r14 + adcxq %r9,%r15 + +.byte 0xc4,0xe2,0xfb,0xf6,0x8e,0x30,0x00,0x00,0x00 + adoxq %rax,%r15 + adcxq %rcx,%r8 + + mulxq 56(%rsi),%rdi,%r9 + adoxq %rdi,%r8 + adcxq %rbp,%r9 + mulxq %rdx,%rax,%rdi + adoxq %rbp,%r9 + movq 24(%rsi),%rdx + + xorq %rcx,%rcx + adoxq %r11,%r11 + + adcxq %rbx,%rax + adoxq %r12,%r12 + adcxq %rax,%r11 + adoxq %rbp,%rcx + adcxq %rdi,%r12 + adcxq %rbp,%rcx + + movq %r11,32(%rsp) + movq %r12,40(%rsp) + + + mulxq 32(%rsi),%rax,%rbx + adoxq %rax,%r14 + adcxq %rbx,%r15 + + mulxq 40(%rsi),%rdi,%r10 + adoxq %rdi,%r15 + adcxq %r10,%r8 + + mulxq 48(%rsi),%rax,%rbx + adoxq %rax,%r8 + adcxq %rbx,%r9 + + mulxq 56(%rsi),%rdi,%r10 + adoxq %rdi,%r9 + adcxq %rbp,%r10 + mulxq %rdx,%rax,%rdi + adoxq %rbp,%r10 + movq 32(%rsi),%rdx + + xorq %rbx,%rbx + adoxq %r13,%r13 + + adcxq %rcx,%rax + adoxq %r14,%r14 + adcxq %rax,%r13 + adoxq %rbp,%rbx + adcxq %rdi,%r14 + adcxq %rbp,%rbx + + movq %r13,48(%rsp) + movq %r14,56(%rsp) + + + mulxq 40(%rsi),%rdi,%r11 + adoxq %rdi,%r8 + adcxq %r11,%r9 + + mulxq 48(%rsi),%rax,%rcx + adoxq %rax,%r9 + adcxq %rcx,%r10 + + mulxq 56(%rsi),%rdi,%r11 + adoxq %rdi,%r10 + adcxq %rbp,%r11 + mulxq %rdx,%rax,%rdi + movq 40(%rsi),%rdx + adoxq %rbp,%r11 + + xorq %rcx,%rcx + adoxq %r15,%r15 + + adcxq %rbx,%rax + adoxq %r8,%r8 + adcxq %rax,%r15 + adoxq %rbp,%rcx + adcxq %rdi,%r8 + adcxq %rbp,%rcx + + movq %r15,64(%rsp) + movq %r8,72(%rsp) + + +.byte 0xc4,0xe2,0xfb,0xf6,0x9e,0x30,0x00,0x00,0x00 + adoxq %rax,%r10 + adcxq %rbx,%r11 + +.byte 0xc4,0x62,0xc3,0xf6,0xa6,0x38,0x00,0x00,0x00 + adoxq %rdi,%r11 + adcxq %rbp,%r12 + mulxq %rdx,%rax,%rdi + adoxq %rbp,%r12 + movq 48(%rsi),%rdx + + xorq %rbx,%rbx + adoxq %r9,%r9 + + adcxq %rcx,%rax + adoxq %r10,%r10 + adcxq %rax,%r9 + adcxq %rdi,%r10 + adoxq %rbp,%rbx + adcxq %rbp,%rbx + + movq %r9,80(%rsp) + movq %r10,88(%rsp) + + +.byte 0xc4,0x62,0xfb,0xf6,0xae,0x38,0x00,0x00,0x00 + adoxq %rax,%r12 + adoxq %rbp,%r13 + + mulxq %rdx,%rax,%rdi + xorq %rcx,%rcx + movq 56(%rsi),%rdx + adoxq %r11,%r11 + + adcxq %rbx,%rax + adoxq %r12,%r12 + adcxq %rax,%r11 + adoxq %rbp,%rcx + adcxq %rdi,%r12 + adcxq %rbp,%rcx + +.byte 0x4c,0x89,0x9c,0x24,0x60,0x00,0x00,0x00 +.byte 0x4c,0x89,0xa4,0x24,0x68,0x00,0x00,0x00 + + + mulxq %rdx,%rax,%rdx + xorq %rbx,%rbx + adoxq %r13,%r13 + + adcxq %rcx,%rax + adoxq %rbp,%rbx + adcxq %r13,%rax + adcxq %rdx,%rbx + +.byte 102,72,15,126,199 +.byte 102,72,15,126,205 + + movq 128(%rsp),%rdx + movq (%rsp),%r8 + movq 8(%rsp),%r9 + movq 16(%rsp),%r10 + movq 24(%rsp),%r11 + movq 32(%rsp),%r12 + movq 40(%rsp),%r13 + movq 48(%rsp),%r14 + movq 56(%rsp),%r15 + + movq %rax,112(%rsp) + movq %rbx,120(%rsp) + + call __rsaz_512_reducex + + addq 64(%rsp),%r8 + adcq 72(%rsp),%r9 + adcq 80(%rsp),%r10 + adcq 88(%rsp),%r11 + adcq 96(%rsp),%r12 + adcq 104(%rsp),%r13 + adcq 112(%rsp),%r14 + adcq 120(%rsp),%r15 + sbbq %rcx,%rcx + + call __rsaz_512_subtract + + movq %r8,%rdx + movq %r9,%rax + movl 128+8(%rsp),%r8d + movq %rdi,%rsi + + decl %r8d + jnz .Loop_sqrx + +.Lsqr_tail: + + leaq 128+24+48(%rsp),%rax +.cfi_def_cfa %rax,8 + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lsqr_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_512_sqr,.-rsaz_512_sqr +.globl rsaz_512_mul +.type rsaz_512_mul,@function +.align 32 +rsaz_512_mul: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + + subq $128+24,%rsp +.cfi_adjust_cfa_offset 128+24 +.Lmul_body: +.byte 102,72,15,110,199 +.byte 102,72,15,110,201 + movq %r8,128(%rsp) + movl $0x80100,%r11d + andl OPENSSL_ia32cap_P+8(%rip),%r11d + cmpl $0x80100,%r11d + je .Lmulx + movq (%rdx),%rbx + movq %rdx,%rbp + call __rsaz_512_mul + +.byte 102,72,15,126,199 +.byte 102,72,15,126,205 + + movq (%rsp),%r8 + movq 8(%rsp),%r9 + movq 16(%rsp),%r10 + movq 24(%rsp),%r11 + movq 32(%rsp),%r12 + movq 40(%rsp),%r13 + movq 48(%rsp),%r14 + movq 56(%rsp),%r15 + + call __rsaz_512_reduce + jmp .Lmul_tail + +.align 32 +.Lmulx: + movq %rdx,%rbp + movq (%rdx),%rdx + call __rsaz_512_mulx + +.byte 102,72,15,126,199 +.byte 102,72,15,126,205 + + movq 128(%rsp),%rdx + movq (%rsp),%r8 + movq 8(%rsp),%r9 + movq 16(%rsp),%r10 + movq 24(%rsp),%r11 + movq 32(%rsp),%r12 + movq 40(%rsp),%r13 + movq 48(%rsp),%r14 + movq 56(%rsp),%r15 + + call __rsaz_512_reducex +.Lmul_tail: + addq 64(%rsp),%r8 + adcq 72(%rsp),%r9 + adcq 80(%rsp),%r10 + adcq 88(%rsp),%r11 + adcq 96(%rsp),%r12 + adcq 104(%rsp),%r13 + adcq 112(%rsp),%r14 + adcq 120(%rsp),%r15 + sbbq %rcx,%rcx + + call __rsaz_512_subtract + + leaq 128+24+48(%rsp),%rax +.cfi_def_cfa %rax,8 + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lmul_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_512_mul,.-rsaz_512_mul +.globl rsaz_512_mul_gather4 +.type rsaz_512_mul_gather4,@function +.align 32 +rsaz_512_mul_gather4: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + + subq $152,%rsp +.cfi_adjust_cfa_offset 152 +.Lmul_gather4_body: + movd %r9d,%xmm8 + movdqa .Linc+16(%rip),%xmm1 + movdqa .Linc(%rip),%xmm0 + + pshufd $0,%xmm8,%xmm8 + movdqa %xmm1,%xmm7 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm8,%xmm0 + movdqa %xmm7,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm8,%xmm1 + movdqa %xmm7,%xmm4 + paddd %xmm2,%xmm3 + pcmpeqd %xmm8,%xmm2 + movdqa %xmm7,%xmm5 + paddd %xmm3,%xmm4 + pcmpeqd %xmm8,%xmm3 + movdqa %xmm7,%xmm6 + paddd %xmm4,%xmm5 + pcmpeqd %xmm8,%xmm4 + paddd %xmm5,%xmm6 + pcmpeqd %xmm8,%xmm5 + paddd %xmm6,%xmm7 + pcmpeqd %xmm8,%xmm6 + pcmpeqd %xmm8,%xmm7 + + movdqa 0(%rdx),%xmm8 + movdqa 16(%rdx),%xmm9 + movdqa 32(%rdx),%xmm10 + movdqa 48(%rdx),%xmm11 + pand %xmm0,%xmm8 + movdqa 64(%rdx),%xmm12 + pand %xmm1,%xmm9 + movdqa 80(%rdx),%xmm13 + pand %xmm2,%xmm10 + movdqa 96(%rdx),%xmm14 + pand %xmm3,%xmm11 + movdqa 112(%rdx),%xmm15 + leaq 128(%rdx),%rbp + pand %xmm4,%xmm12 + pand %xmm5,%xmm13 + pand %xmm6,%xmm14 + pand %xmm7,%xmm15 + por %xmm10,%xmm8 + por %xmm11,%xmm9 + por %xmm12,%xmm8 + por %xmm13,%xmm9 + por %xmm14,%xmm8 + por %xmm15,%xmm9 + + por %xmm9,%xmm8 + pshufd $0x4e,%xmm8,%xmm9 + por %xmm9,%xmm8 + movl $0x80100,%r11d + andl OPENSSL_ia32cap_P+8(%rip),%r11d + cmpl $0x80100,%r11d + je .Lmulx_gather +.byte 102,76,15,126,195 + + movq %r8,128(%rsp) + movq %rdi,128+8(%rsp) + movq %rcx,128+16(%rsp) + + movq (%rsi),%rax + movq 8(%rsi),%rcx + mulq %rbx + movq %rax,(%rsp) + movq %rcx,%rax + movq %rdx,%r8 + + mulq %rbx + addq %rax,%r8 + movq 16(%rsi),%rax + movq %rdx,%r9 + adcq $0,%r9 + + mulq %rbx + addq %rax,%r9 + movq 24(%rsi),%rax + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r10 + movq 32(%rsi),%rax + movq %rdx,%r11 + adcq $0,%r11 + + mulq %rbx + addq %rax,%r11 + movq 40(%rsi),%rax + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r12 + movq 48(%rsi),%rax + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r13 + movq 56(%rsi),%rax + movq %rdx,%r14 + adcq $0,%r14 + + mulq %rbx + addq %rax,%r14 + movq (%rsi),%rax + movq %rdx,%r15 + adcq $0,%r15 + + leaq 8(%rsp),%rdi + movl $7,%ecx + jmp .Loop_mul_gather + +.align 32 +.Loop_mul_gather: + movdqa 0(%rbp),%xmm8 + movdqa 16(%rbp),%xmm9 + movdqa 32(%rbp),%xmm10 + movdqa 48(%rbp),%xmm11 + pand %xmm0,%xmm8 + movdqa 64(%rbp),%xmm12 + pand %xmm1,%xmm9 + movdqa 80(%rbp),%xmm13 + pand %xmm2,%xmm10 + movdqa 96(%rbp),%xmm14 + pand %xmm3,%xmm11 + movdqa 112(%rbp),%xmm15 + leaq 128(%rbp),%rbp + pand %xmm4,%xmm12 + pand %xmm5,%xmm13 + pand %xmm6,%xmm14 + pand %xmm7,%xmm15 + por %xmm10,%xmm8 + por %xmm11,%xmm9 + por %xmm12,%xmm8 + por %xmm13,%xmm9 + por %xmm14,%xmm8 + por %xmm15,%xmm9 + + por %xmm9,%xmm8 + pshufd $0x4e,%xmm8,%xmm9 + por %xmm9,%xmm8 +.byte 102,76,15,126,195 + + mulq %rbx + addq %rax,%r8 + movq 8(%rsi),%rax + movq %r8,(%rdi) + movq %rdx,%r8 + adcq $0,%r8 + + mulq %rbx + addq %rax,%r9 + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r9,%r8 + movq %rdx,%r9 + adcq $0,%r9 + + mulq %rbx + addq %rax,%r10 + movq 24(%rsi),%rax + adcq $0,%rdx + addq %r10,%r9 + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r11 + movq 32(%rsi),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + + mulq %rbx + addq %rax,%r12 + movq 40(%rsi),%rax + adcq $0,%rdx + addq %r12,%r11 + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r13 + movq 48(%rsi),%rax + adcq $0,%rdx + addq %r13,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r14 + movq 56(%rsi),%rax + adcq $0,%rdx + addq %r14,%r13 + movq %rdx,%r14 + adcq $0,%r14 + + mulq %rbx + addq %rax,%r15 + movq (%rsi),%rax + adcq $0,%rdx + addq %r15,%r14 + movq %rdx,%r15 + adcq $0,%r15 + + leaq 8(%rdi),%rdi + + decl %ecx + jnz .Loop_mul_gather + + movq %r8,(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + + movq 128+8(%rsp),%rdi + movq 128+16(%rsp),%rbp + + movq (%rsp),%r8 + movq 8(%rsp),%r9 + movq 16(%rsp),%r10 + movq 24(%rsp),%r11 + movq 32(%rsp),%r12 + movq 40(%rsp),%r13 + movq 48(%rsp),%r14 + movq 56(%rsp),%r15 + + call __rsaz_512_reduce + jmp .Lmul_gather_tail + +.align 32 +.Lmulx_gather: +.byte 102,76,15,126,194 + + movq %r8,128(%rsp) + movq %rdi,128+8(%rsp) + movq %rcx,128+16(%rsp) + + mulxq (%rsi),%rbx,%r8 + movq %rbx,(%rsp) + xorl %edi,%edi + + mulxq 8(%rsi),%rax,%r9 + + mulxq 16(%rsi),%rbx,%r10 + adcxq %rax,%r8 + + mulxq 24(%rsi),%rax,%r11 + adcxq %rbx,%r9 + + mulxq 32(%rsi),%rbx,%r12 + adcxq %rax,%r10 + + mulxq 40(%rsi),%rax,%r13 + adcxq %rbx,%r11 + + mulxq 48(%rsi),%rbx,%r14 + adcxq %rax,%r12 + + mulxq 56(%rsi),%rax,%r15 + adcxq %rbx,%r13 + adcxq %rax,%r14 +.byte 0x67 + movq %r8,%rbx + adcxq %rdi,%r15 + + movq $-7,%rcx + jmp .Loop_mulx_gather + +.align 32 +.Loop_mulx_gather: + movdqa 0(%rbp),%xmm8 + movdqa 16(%rbp),%xmm9 + movdqa 32(%rbp),%xmm10 + movdqa 48(%rbp),%xmm11 + pand %xmm0,%xmm8 + movdqa 64(%rbp),%xmm12 + pand %xmm1,%xmm9 + movdqa 80(%rbp),%xmm13 + pand %xmm2,%xmm10 + movdqa 96(%rbp),%xmm14 + pand %xmm3,%xmm11 + movdqa 112(%rbp),%xmm15 + leaq 128(%rbp),%rbp + pand %xmm4,%xmm12 + pand %xmm5,%xmm13 + pand %xmm6,%xmm14 + pand %xmm7,%xmm15 + por %xmm10,%xmm8 + por %xmm11,%xmm9 + por %xmm12,%xmm8 + por %xmm13,%xmm9 + por %xmm14,%xmm8 + por %xmm15,%xmm9 + + por %xmm9,%xmm8 + pshufd $0x4e,%xmm8,%xmm9 + por %xmm9,%xmm8 +.byte 102,76,15,126,194 + +.byte 0xc4,0x62,0xfb,0xf6,0x86,0x00,0x00,0x00,0x00 + adcxq %rax,%rbx + adoxq %r9,%r8 + + mulxq 8(%rsi),%rax,%r9 + adcxq %rax,%r8 + adoxq %r10,%r9 + + mulxq 16(%rsi),%rax,%r10 + adcxq %rax,%r9 + adoxq %r11,%r10 + +.byte 0xc4,0x62,0xfb,0xf6,0x9e,0x18,0x00,0x00,0x00 + adcxq %rax,%r10 + adoxq %r12,%r11 + + mulxq 32(%rsi),%rax,%r12 + adcxq %rax,%r11 + adoxq %r13,%r12 + + mulxq 40(%rsi),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + +.byte 0xc4,0x62,0xfb,0xf6,0xb6,0x30,0x00,0x00,0x00 + adcxq %rax,%r13 +.byte 0x67 + adoxq %r15,%r14 + + mulxq 56(%rsi),%rax,%r15 + movq %rbx,64(%rsp,%rcx,8) + adcxq %rax,%r14 + adoxq %rdi,%r15 + movq %r8,%rbx + adcxq %rdi,%r15 + + incq %rcx + jnz .Loop_mulx_gather + + movq %r8,64(%rsp) + movq %r9,64+8(%rsp) + movq %r10,64+16(%rsp) + movq %r11,64+24(%rsp) + movq %r12,64+32(%rsp) + movq %r13,64+40(%rsp) + movq %r14,64+48(%rsp) + movq %r15,64+56(%rsp) + + movq 128(%rsp),%rdx + movq 128+8(%rsp),%rdi + movq 128+16(%rsp),%rbp + + movq (%rsp),%r8 + movq 8(%rsp),%r9 + movq 16(%rsp),%r10 + movq 24(%rsp),%r11 + movq 32(%rsp),%r12 + movq 40(%rsp),%r13 + movq 48(%rsp),%r14 + movq 56(%rsp),%r15 + + call __rsaz_512_reducex + +.Lmul_gather_tail: + addq 64(%rsp),%r8 + adcq 72(%rsp),%r9 + adcq 80(%rsp),%r10 + adcq 88(%rsp),%r11 + adcq 96(%rsp),%r12 + adcq 104(%rsp),%r13 + adcq 112(%rsp),%r14 + adcq 120(%rsp),%r15 + sbbq %rcx,%rcx + + call __rsaz_512_subtract + + leaq 128+24+48(%rsp),%rax +.cfi_def_cfa %rax,8 + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lmul_gather4_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_512_mul_gather4,.-rsaz_512_mul_gather4 +.globl rsaz_512_mul_scatter4 +.type rsaz_512_mul_scatter4,@function +.align 32 +rsaz_512_mul_scatter4: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + + movl %r9d,%r9d + subq $128+24,%rsp +.cfi_adjust_cfa_offset 128+24 +.Lmul_scatter4_body: + leaq (%r8,%r9,8),%r8 +.byte 102,72,15,110,199 +.byte 102,72,15,110,202 +.byte 102,73,15,110,208 + movq %rcx,128(%rsp) + + movq %rdi,%rbp + movl $0x80100,%r11d + andl OPENSSL_ia32cap_P+8(%rip),%r11d + cmpl $0x80100,%r11d + je .Lmulx_scatter + movq (%rdi),%rbx + call __rsaz_512_mul + +.byte 102,72,15,126,199 +.byte 102,72,15,126,205 + + movq (%rsp),%r8 + movq 8(%rsp),%r9 + movq 16(%rsp),%r10 + movq 24(%rsp),%r11 + movq 32(%rsp),%r12 + movq 40(%rsp),%r13 + movq 48(%rsp),%r14 + movq 56(%rsp),%r15 + + call __rsaz_512_reduce + jmp .Lmul_scatter_tail + +.align 32 +.Lmulx_scatter: + movq (%rdi),%rdx + call __rsaz_512_mulx + +.byte 102,72,15,126,199 +.byte 102,72,15,126,205 + + movq 128(%rsp),%rdx + movq (%rsp),%r8 + movq 8(%rsp),%r9 + movq 16(%rsp),%r10 + movq 24(%rsp),%r11 + movq 32(%rsp),%r12 + movq 40(%rsp),%r13 + movq 48(%rsp),%r14 + movq 56(%rsp),%r15 + + call __rsaz_512_reducex + +.Lmul_scatter_tail: + addq 64(%rsp),%r8 + adcq 72(%rsp),%r9 + adcq 80(%rsp),%r10 + adcq 88(%rsp),%r11 + adcq 96(%rsp),%r12 + adcq 104(%rsp),%r13 + adcq 112(%rsp),%r14 + adcq 120(%rsp),%r15 +.byte 102,72,15,126,214 + sbbq %rcx,%rcx + + call __rsaz_512_subtract + + movq %r8,0(%rsi) + movq %r9,128(%rsi) + movq %r10,256(%rsi) + movq %r11,384(%rsi) + movq %r12,512(%rsi) + movq %r13,640(%rsi) + movq %r14,768(%rsi) + movq %r15,896(%rsi) + + leaq 128+24+48(%rsp),%rax +.cfi_def_cfa %rax,8 + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lmul_scatter4_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_512_mul_scatter4,.-rsaz_512_mul_scatter4 +.globl rsaz_512_mul_by_one +.type rsaz_512_mul_by_one,@function +.align 32 +rsaz_512_mul_by_one: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + + subq $128+24,%rsp +.cfi_adjust_cfa_offset 128+24 +.Lmul_by_one_body: + movl OPENSSL_ia32cap_P+8(%rip),%eax + movq %rdx,%rbp + movq %rcx,128(%rsp) + + movq (%rsi),%r8 + pxor %xmm0,%xmm0 + movq 8(%rsi),%r9 + movq 16(%rsi),%r10 + movq 24(%rsi),%r11 + movq 32(%rsi),%r12 + movq 40(%rsi),%r13 + movq 48(%rsi),%r14 + movq 56(%rsi),%r15 + + movdqa %xmm0,(%rsp) + movdqa %xmm0,16(%rsp) + movdqa %xmm0,32(%rsp) + movdqa %xmm0,48(%rsp) + movdqa %xmm0,64(%rsp) + movdqa %xmm0,80(%rsp) + movdqa %xmm0,96(%rsp) + andl $0x80100,%eax + cmpl $0x80100,%eax + je .Lby_one_callx + call __rsaz_512_reduce + jmp .Lby_one_tail +.align 32 +.Lby_one_callx: + movq 128(%rsp),%rdx + call __rsaz_512_reducex +.Lby_one_tail: + movq %r8,(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + + leaq 128+24+48(%rsp),%rax +.cfi_def_cfa %rax,8 + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lmul_by_one_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_512_mul_by_one,.-rsaz_512_mul_by_one +.type __rsaz_512_reduce,@function +.align 32 +__rsaz_512_reduce: +.cfi_startproc + movq %r8,%rbx + imulq 128+8(%rsp),%rbx + movq 0(%rbp),%rax + movl $8,%ecx + jmp .Lreduction_loop + +.align 32 +.Lreduction_loop: + mulq %rbx + movq 8(%rbp),%rax + negq %r8 + movq %rdx,%r8 + adcq $0,%r8 + + mulq %rbx + addq %rax,%r9 + movq 16(%rbp),%rax + adcq $0,%rdx + addq %r9,%r8 + movq %rdx,%r9 + adcq $0,%r9 + + mulq %rbx + addq %rax,%r10 + movq 24(%rbp),%rax + adcq $0,%rdx + addq %r10,%r9 + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r11 + movq 32(%rbp),%rax + adcq $0,%rdx + addq %r11,%r10 + movq 128+8(%rsp),%rsi + + + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbx + addq %rax,%r12 + movq 40(%rbp),%rax + adcq $0,%rdx + imulq %r8,%rsi + addq %r12,%r11 + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r13 + movq 48(%rbp),%rax + adcq $0,%rdx + addq %r13,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r14 + movq 56(%rbp),%rax + adcq $0,%rdx + addq %r14,%r13 + movq %rdx,%r14 + adcq $0,%r14 + + mulq %rbx + movq %rsi,%rbx + addq %rax,%r15 + movq 0(%rbp),%rax + adcq $0,%rdx + addq %r15,%r14 + movq %rdx,%r15 + adcq $0,%r15 + + decl %ecx + jne .Lreduction_loop + + .byte 0xf3,0xc3 +.cfi_endproc +.size __rsaz_512_reduce,.-__rsaz_512_reduce +.type __rsaz_512_reducex,@function +.align 32 +__rsaz_512_reducex: +.cfi_startproc + + imulq %r8,%rdx + xorq %rsi,%rsi + movl $8,%ecx + jmp .Lreduction_loopx + +.align 32 +.Lreduction_loopx: + movq %r8,%rbx + mulxq 0(%rbp),%rax,%r8 + adcxq %rbx,%rax + adoxq %r9,%r8 + + mulxq 8(%rbp),%rax,%r9 + adcxq %rax,%r8 + adoxq %r10,%r9 + + mulxq 16(%rbp),%rbx,%r10 + adcxq %rbx,%r9 + adoxq %r11,%r10 + + mulxq 24(%rbp),%rbx,%r11 + adcxq %rbx,%r10 + adoxq %r12,%r11 + +.byte 0xc4,0x62,0xe3,0xf6,0xa5,0x20,0x00,0x00,0x00 + movq %rdx,%rax + movq %r8,%rdx + adcxq %rbx,%r11 + adoxq %r13,%r12 + + mulxq 128+8(%rsp),%rbx,%rdx + movq %rax,%rdx + + mulxq 40(%rbp),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + +.byte 0xc4,0x62,0xfb,0xf6,0xb5,0x30,0x00,0x00,0x00 + adcxq %rax,%r13 + adoxq %r15,%r14 + + mulxq 56(%rbp),%rax,%r15 + movq %rbx,%rdx + adcxq %rax,%r14 + adoxq %rsi,%r15 + adcxq %rsi,%r15 + + decl %ecx + jne .Lreduction_loopx + + .byte 0xf3,0xc3 +.cfi_endproc +.size __rsaz_512_reducex,.-__rsaz_512_reducex +.type __rsaz_512_subtract,@function +.align 32 +__rsaz_512_subtract: +.cfi_startproc + movq %r8,(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + + movq 0(%rbp),%r8 + movq 8(%rbp),%r9 + negq %r8 + notq %r9 + andq %rcx,%r8 + movq 16(%rbp),%r10 + andq %rcx,%r9 + notq %r10 + movq 24(%rbp),%r11 + andq %rcx,%r10 + notq %r11 + movq 32(%rbp),%r12 + andq %rcx,%r11 + notq %r12 + movq 40(%rbp),%r13 + andq %rcx,%r12 + notq %r13 + movq 48(%rbp),%r14 + andq %rcx,%r13 + notq %r14 + movq 56(%rbp),%r15 + andq %rcx,%r14 + notq %r15 + andq %rcx,%r15 + + addq (%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + + movq %r8,(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __rsaz_512_subtract,.-__rsaz_512_subtract +.type __rsaz_512_mul,@function +.align 32 +__rsaz_512_mul: +.cfi_startproc + leaq 8(%rsp),%rdi + + movq (%rsi),%rax + mulq %rbx + movq %rax,(%rdi) + movq 8(%rsi),%rax + movq %rdx,%r8 + + mulq %rbx + addq %rax,%r8 + movq 16(%rsi),%rax + movq %rdx,%r9 + adcq $0,%r9 + + mulq %rbx + addq %rax,%r9 + movq 24(%rsi),%rax + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r10 + movq 32(%rsi),%rax + movq %rdx,%r11 + adcq $0,%r11 + + mulq %rbx + addq %rax,%r11 + movq 40(%rsi),%rax + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r12 + movq 48(%rsi),%rax + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r13 + movq 56(%rsi),%rax + movq %rdx,%r14 + adcq $0,%r14 + + mulq %rbx + addq %rax,%r14 + movq (%rsi),%rax + movq %rdx,%r15 + adcq $0,%r15 + + leaq 8(%rbp),%rbp + leaq 8(%rdi),%rdi + + movl $7,%ecx + jmp .Loop_mul + +.align 32 +.Loop_mul: + movq (%rbp),%rbx + mulq %rbx + addq %rax,%r8 + movq 8(%rsi),%rax + movq %r8,(%rdi) + movq %rdx,%r8 + adcq $0,%r8 + + mulq %rbx + addq %rax,%r9 + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r9,%r8 + movq %rdx,%r9 + adcq $0,%r9 + + mulq %rbx + addq %rax,%r10 + movq 24(%rsi),%rax + adcq $0,%rdx + addq %r10,%r9 + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r11 + movq 32(%rsi),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + + mulq %rbx + addq %rax,%r12 + movq 40(%rsi),%rax + adcq $0,%rdx + addq %r12,%r11 + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r13 + movq 48(%rsi),%rax + adcq $0,%rdx + addq %r13,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r14 + movq 56(%rsi),%rax + adcq $0,%rdx + addq %r14,%r13 + movq %rdx,%r14 + leaq 8(%rbp),%rbp + adcq $0,%r14 + + mulq %rbx + addq %rax,%r15 + movq (%rsi),%rax + adcq $0,%rdx + addq %r15,%r14 + movq %rdx,%r15 + adcq $0,%r15 + + leaq 8(%rdi),%rdi + + decl %ecx + jnz .Loop_mul + + movq %r8,(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __rsaz_512_mul,.-__rsaz_512_mul +.type __rsaz_512_mulx,@function +.align 32 +__rsaz_512_mulx: +.cfi_startproc + mulxq (%rsi),%rbx,%r8 + movq $-6,%rcx + + mulxq 8(%rsi),%rax,%r9 + movq %rbx,8(%rsp) + + mulxq 16(%rsi),%rbx,%r10 + adcq %rax,%r8 + + mulxq 24(%rsi),%rax,%r11 + adcq %rbx,%r9 + + mulxq 32(%rsi),%rbx,%r12 + adcq %rax,%r10 + + mulxq 40(%rsi),%rax,%r13 + adcq %rbx,%r11 + + mulxq 48(%rsi),%rbx,%r14 + adcq %rax,%r12 + + mulxq 56(%rsi),%rax,%r15 + movq 8(%rbp),%rdx + adcq %rbx,%r13 + adcq %rax,%r14 + adcq $0,%r15 + + xorq %rdi,%rdi + jmp .Loop_mulx + +.align 32 +.Loop_mulx: + movq %r8,%rbx + mulxq (%rsi),%rax,%r8 + adcxq %rax,%rbx + adoxq %r9,%r8 + + mulxq 8(%rsi),%rax,%r9 + adcxq %rax,%r8 + adoxq %r10,%r9 + + mulxq 16(%rsi),%rax,%r10 + adcxq %rax,%r9 + adoxq %r11,%r10 + + mulxq 24(%rsi),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + +.byte 0x3e,0xc4,0x62,0xfb,0xf6,0xa6,0x20,0x00,0x00,0x00 + adcxq %rax,%r11 + adoxq %r13,%r12 + + mulxq 40(%rsi),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + + mulxq 48(%rsi),%rax,%r14 + adcxq %rax,%r13 + adoxq %r15,%r14 + + mulxq 56(%rsi),%rax,%r15 + movq 64(%rbp,%rcx,8),%rdx + movq %rbx,8+64-8(%rsp,%rcx,8) + adcxq %rax,%r14 + adoxq %rdi,%r15 + adcxq %rdi,%r15 + + incq %rcx + jnz .Loop_mulx + + movq %r8,%rbx + mulxq (%rsi),%rax,%r8 + adcxq %rax,%rbx + adoxq %r9,%r8 + +.byte 0xc4,0x62,0xfb,0xf6,0x8e,0x08,0x00,0x00,0x00 + adcxq %rax,%r8 + adoxq %r10,%r9 + +.byte 0xc4,0x62,0xfb,0xf6,0x96,0x10,0x00,0x00,0x00 + adcxq %rax,%r9 + adoxq %r11,%r10 + + mulxq 24(%rsi),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + + mulxq 32(%rsi),%rax,%r12 + adcxq %rax,%r11 + adoxq %r13,%r12 + + mulxq 40(%rsi),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + +.byte 0xc4,0x62,0xfb,0xf6,0xb6,0x30,0x00,0x00,0x00 + adcxq %rax,%r13 + adoxq %r15,%r14 + +.byte 0xc4,0x62,0xfb,0xf6,0xbe,0x38,0x00,0x00,0x00 + adcxq %rax,%r14 + adoxq %rdi,%r15 + adcxq %rdi,%r15 + + movq %rbx,8+64-8(%rsp) + movq %r8,8+64(%rsp) + movq %r9,8+64+8(%rsp) + movq %r10,8+64+16(%rsp) + movq %r11,8+64+24(%rsp) + movq %r12,8+64+32(%rsp) + movq %r13,8+64+40(%rsp) + movq %r14,8+64+48(%rsp) + movq %r15,8+64+56(%rsp) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __rsaz_512_mulx,.-__rsaz_512_mulx +.globl rsaz_512_scatter4 +.type rsaz_512_scatter4,@function +.align 16 +rsaz_512_scatter4: +.cfi_startproc + leaq (%rdi,%rdx,8),%rdi + movl $8,%r9d + jmp .Loop_scatter +.align 16 +.Loop_scatter: + movq (%rsi),%rax + leaq 8(%rsi),%rsi + movq %rax,(%rdi) + leaq 128(%rdi),%rdi + decl %r9d + jnz .Loop_scatter + .byte 0xf3,0xc3 +.cfi_endproc +.size rsaz_512_scatter4,.-rsaz_512_scatter4 + +.globl rsaz_512_gather4 +.type rsaz_512_gather4,@function +.align 16 +rsaz_512_gather4: +.cfi_startproc + movd %edx,%xmm8 + movdqa .Linc+16(%rip),%xmm1 + movdqa .Linc(%rip),%xmm0 + + pshufd $0,%xmm8,%xmm8 + movdqa %xmm1,%xmm7 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm8,%xmm0 + movdqa %xmm7,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm8,%xmm1 + movdqa %xmm7,%xmm4 + paddd %xmm2,%xmm3 + pcmpeqd %xmm8,%xmm2 + movdqa %xmm7,%xmm5 + paddd %xmm3,%xmm4 + pcmpeqd %xmm8,%xmm3 + movdqa %xmm7,%xmm6 + paddd %xmm4,%xmm5 + pcmpeqd %xmm8,%xmm4 + paddd %xmm5,%xmm6 + pcmpeqd %xmm8,%xmm5 + paddd %xmm6,%xmm7 + pcmpeqd %xmm8,%xmm6 + pcmpeqd %xmm8,%xmm7 + movl $8,%r9d + jmp .Loop_gather +.align 16 +.Loop_gather: + movdqa 0(%rsi),%xmm8 + movdqa 16(%rsi),%xmm9 + movdqa 32(%rsi),%xmm10 + movdqa 48(%rsi),%xmm11 + pand %xmm0,%xmm8 + movdqa 64(%rsi),%xmm12 + pand %xmm1,%xmm9 + movdqa 80(%rsi),%xmm13 + pand %xmm2,%xmm10 + movdqa 96(%rsi),%xmm14 + pand %xmm3,%xmm11 + movdqa 112(%rsi),%xmm15 + leaq 128(%rsi),%rsi + pand %xmm4,%xmm12 + pand %xmm5,%xmm13 + pand %xmm6,%xmm14 + pand %xmm7,%xmm15 + por %xmm10,%xmm8 + por %xmm11,%xmm9 + por %xmm12,%xmm8 + por %xmm13,%xmm9 + por %xmm14,%xmm8 + por %xmm15,%xmm9 + + por %xmm9,%xmm8 + pshufd $0x4e,%xmm8,%xmm9 + por %xmm9,%xmm8 + movq %xmm8,(%rdi) + leaq 8(%rdi),%rdi + decl %r9d + jnz .Loop_gather + .byte 0xf3,0xc3 +.LSEH_end_rsaz_512_gather4: +.cfi_endproc +.size rsaz_512_gather4,.-rsaz_512_gather4 + +.align 64 +.Linc: +.long 0,0, 1,1 +.long 2,2, 2,2 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/bn/rsaz_exp.c b/crypto/openssl/crypto/bn/rsaz_exp.c index a2ab58bbeb4c..2a1ff09eefc9 100644 --- a/crypto/openssl/crypto/bn/rsaz_exp.c +++ b/crypto/openssl/crypto/bn/rsaz_exp.c @@ -2,7 +2,7 @@ * Copyright 2013-2022 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2012, Intel Corporation. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/bn/rsaz_exp.h b/crypto/openssl/crypto/bn/rsaz_exp.h index 1532a7e07179..e27e9f047138 100644 --- a/crypto/openssl/crypto/bn/rsaz_exp.h +++ b/crypto/openssl/crypto/bn/rsaz_exp.h @@ -1,8 +1,8 @@ /* * Copyright 2013-2022 The OpenSSL Project Authors. All Rights Reserved. - * Copyright (c) 2012, Intel Corporation. All Rights Reserved. + * Copyright (c) 2020, Intel Corporation. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -37,6 +37,23 @@ void RSAZ_512_mod_exp(BN_ULONG result[8], const BN_ULONG m_norm[8], BN_ULONG k0, const BN_ULONG RR[8]); + +int ossl_rsaz_avx512ifma_eligible(void); + +int ossl_rsaz_mod_exp_avx512_x2(BN_ULONG *res1, + const BN_ULONG *base1, + const BN_ULONG *exponent1, + const BN_ULONG *m1, + const BN_ULONG *RR1, + BN_ULONG k0_1, + BN_ULONG *res2, + const BN_ULONG *base2, + const BN_ULONG *exponent2, + const BN_ULONG *m2, + const BN_ULONG *RR2, + BN_ULONG k0_2, + int factor_size); + static ossl_inline void bn_select_words(BN_ULONG *r, BN_ULONG mask, const BN_ULONG *a, const BN_ULONG *b, size_t num) diff --git a/crypto/openssl/crypto/bn/rsaz_exp_x2.c b/crypto/openssl/crypto/bn/rsaz_exp_x2.c new file mode 100644 index 000000000000..b19050dfee8c --- /dev/null +++ b/crypto/openssl/crypto/bn/rsaz_exp_x2.c @@ -0,0 +1,575 @@ +/* + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2020, Intel Corporation. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * + * Originally written by Ilya Albrekht, Sergey Kirillov and Andrey Matyukov + * Intel Corporation + * + */ + +#include +#include +#include "rsaz_exp.h" + +#ifndef RSAZ_ENABLED +NON_EMPTY_TRANSLATION_UNIT +#else +# include +# include + +# if defined(__GNUC__) +# define ALIGN64 __attribute__((aligned(64))) +# elif defined(_MSC_VER) +# define ALIGN64 __declspec(align(64)) +# else +# define ALIGN64 +# endif + +# define ALIGN_OF(ptr, boundary) \ + ((unsigned char *)(ptr) + (boundary - (((size_t)(ptr)) & (boundary - 1)))) + +/* Internal radix */ +# define DIGIT_SIZE (52) +/* 52-bit mask */ +# define DIGIT_MASK ((uint64_t)0xFFFFFFFFFFFFF) + +# define BITS2WORD8_SIZE(x) (((x) + 7) >> 3) +# define BITS2WORD64_SIZE(x) (((x) + 63) >> 6) + +static ossl_inline uint64_t get_digit52(const uint8_t *in, int in_len); +static ossl_inline void put_digit52(uint8_t *out, int out_len, uint64_t digit); +static void to_words52(BN_ULONG *out, int out_len, const BN_ULONG *in, + int in_bitsize); +static void from_words52(BN_ULONG *bn_out, int out_bitsize, const BN_ULONG *in); +static ossl_inline void set_bit(BN_ULONG *a, int idx); + +/* Number of |digit_size|-bit digits in |bitsize|-bit value */ +static ossl_inline int number_of_digits(int bitsize, int digit_size) +{ + return (bitsize + digit_size - 1) / digit_size; +} + +typedef void (*AMM52)(BN_ULONG *res, const BN_ULONG *base, + const BN_ULONG *exp, const BN_ULONG *m, BN_ULONG k0); +typedef void (*EXP52_x2)(BN_ULONG *res, const BN_ULONG *base, + const BN_ULONG *exp[2], const BN_ULONG *m, + const BN_ULONG *rr, const BN_ULONG k0[2]); + +/* + * For details of the methods declared below please refer to + * crypto/bn/asm/rsaz-avx512.pl + * + * Naming notes: + * amm = Almost Montgomery Multiplication + * ams = Almost Montgomery Squaring + * 52x20 - data represented as array of 20 digits in 52-bit radix + * _x1_/_x2_ - 1 or 2 independent inputs/outputs + * _256 suffix - uses 256-bit (AVX512VL) registers + */ + +/*AMM = Almost Montgomery Multiplication. */ +void ossl_rsaz_amm52x20_x1_256(BN_ULONG *res, const BN_ULONG *base, + const BN_ULONG *exp, const BN_ULONG *m, + BN_ULONG k0); +static void RSAZ_exp52x20_x2_256(BN_ULONG *res, const BN_ULONG *base, + const BN_ULONG *exp[2], const BN_ULONG *m, + const BN_ULONG *rr, const BN_ULONG k0[2]); +void ossl_rsaz_amm52x20_x2_256(BN_ULONG *out, const BN_ULONG *a, + const BN_ULONG *b, const BN_ULONG *m, + const BN_ULONG k0[2]); +void ossl_extract_multiplier_2x20_win5(BN_ULONG *red_Y, + const BN_ULONG *red_table, + int red_table_idx, int tbl_idx); + +/* + * Dual Montgomery modular exponentiation using prime moduli of the + * same bit size, optimized with AVX512 ISA. + * + * Input and output parameters for each exponentiation are independent and + * denoted here by index |i|, i = 1..2. + * + * Input and output are all in regular 2^64 radix. + * + * Each moduli shall be |factor_size| bit size. + * + * NOTE: currently only 2x1024 case is supported. + * + * [out] res|i| - result of modular exponentiation: array of qword values + * in regular (2^64) radix. Size of array shall be enough + * to hold |factor_size| bits. + * [in] base|i| - base + * [in] exp|i| - exponent + * [in] m|i| - moduli + * [in] rr|i| - Montgomery parameter RR = R^2 mod m|i| + * [in] k0_|i| - Montgomery parameter k0 = -1/m|i| mod 2^64 + * [in] factor_size - moduli bit size + * + * \return 0 in case of failure, + * 1 in case of success. + */ +int ossl_rsaz_mod_exp_avx512_x2(BN_ULONG *res1, + const BN_ULONG *base1, + const BN_ULONG *exp1, + const BN_ULONG *m1, + const BN_ULONG *rr1, + BN_ULONG k0_1, + BN_ULONG *res2, + const BN_ULONG *base2, + const BN_ULONG *exp2, + const BN_ULONG *m2, + const BN_ULONG *rr2, + BN_ULONG k0_2, + int factor_size) +{ + int ret = 0; + + /* + * Number of word-size (BN_ULONG) digits to store exponent in redundant + * representation. + */ + int exp_digits = number_of_digits(factor_size + 2, DIGIT_SIZE); + int coeff_pow = 4 * (DIGIT_SIZE * exp_digits - factor_size); + BN_ULONG *base1_red, *m1_red, *rr1_red; + BN_ULONG *base2_red, *m2_red, *rr2_red; + BN_ULONG *coeff_red; + BN_ULONG *storage = NULL; + BN_ULONG *storage_aligned = NULL; + BN_ULONG storage_len_bytes = 7 * exp_digits * sizeof(BN_ULONG); + + /* AMM = Almost Montgomery Multiplication */ + AMM52 amm = NULL; + /* Dual (2-exps in parallel) exponentiation */ + EXP52_x2 exp_x2 = NULL; + + const BN_ULONG *exp[2] = {0}; + BN_ULONG k0[2] = {0}; + + /* Only 1024-bit factor size is supported now */ + switch (factor_size) { + case 1024: + amm = ossl_rsaz_amm52x20_x1_256; + exp_x2 = RSAZ_exp52x20_x2_256; + break; + default: + goto err; + } + + storage = (BN_ULONG *)OPENSSL_malloc(storage_len_bytes + 64); + if (storage == NULL) + goto err; + storage_aligned = (BN_ULONG *)ALIGN_OF(storage, 64); + + /* Memory layout for red(undant) representations */ + base1_red = storage_aligned; + base2_red = storage_aligned + 1 * exp_digits; + m1_red = storage_aligned + 2 * exp_digits; + m2_red = storage_aligned + 3 * exp_digits; + rr1_red = storage_aligned + 4 * exp_digits; + rr2_red = storage_aligned + 5 * exp_digits; + coeff_red = storage_aligned + 6 * exp_digits; + + /* Convert base_i, m_i, rr_i, from regular to 52-bit radix */ + to_words52(base1_red, exp_digits, base1, factor_size); + to_words52(base2_red, exp_digits, base2, factor_size); + to_words52(m1_red, exp_digits, m1, factor_size); + to_words52(m2_red, exp_digits, m2, factor_size); + to_words52(rr1_red, exp_digits, rr1, factor_size); + to_words52(rr2_red, exp_digits, rr2, factor_size); + + /* + * Compute target domain Montgomery converters RR' for each modulus + * based on precomputed original domain's RR. + * + * RR -> RR' transformation steps: + * (1) coeff = 2^k + * (2) t = AMM(RR,RR) = RR^2 / R' mod m + * (3) RR' = AMM(t, coeff) = RR^2 * 2^k / R'^2 mod m + * where + * k = 4 * (52 * digits52 - modlen) + * R = 2^(64 * ceil(modlen/64)) mod m + * RR = R^2 mod M + * R' = 2^(52 * ceil(modlen/52)) mod m + * + * modlen = 1024: k = 64, RR = 2^2048 mod m, RR' = 2^2080 mod m + */ + memset(coeff_red, 0, exp_digits * sizeof(BN_ULONG)); + /* (1) in reduced domain representation */ + set_bit(coeff_red, 64 * (int)(coeff_pow / 52) + coeff_pow % 52); + + amm(rr1_red, rr1_red, rr1_red, m1_red, k0_1); /* (2) for m1 */ + amm(rr1_red, rr1_red, coeff_red, m1_red, k0_1); /* (3) for m1 */ + + amm(rr2_red, rr2_red, rr2_red, m2_red, k0_2); /* (2) for m2 */ + amm(rr2_red, rr2_red, coeff_red, m2_red, k0_2); /* (3) for m2 */ + + exp[0] = exp1; + exp[1] = exp2; + + k0[0] = k0_1; + k0[1] = k0_2; + + exp_x2(rr1_red, base1_red, exp, m1_red, rr1_red, k0); + + /* Convert rr_i back to regular radix */ + from_words52(res1, factor_size, rr1_red); + from_words52(res2, factor_size, rr2_red); + + /* bn_reduce_once_in_place expects number of BN_ULONG, not bit size */ + factor_size /= sizeof(BN_ULONG) * 8; + + bn_reduce_once_in_place(res1, /*carry=*/0, m1, storage, factor_size); + bn_reduce_once_in_place(res2, /*carry=*/0, m2, storage, factor_size); + + ret = 1; +err: + if (storage != NULL) { + OPENSSL_cleanse(storage, storage_len_bytes); + OPENSSL_free(storage); + } + return ret; +} + +/* + * Dual 1024-bit w-ary modular exponentiation using prime moduli of the same + * bit size using Almost Montgomery Multiplication, optimized with AVX512_IFMA + * ISA. + * + * The parameter w (window size) = 5. + * + * [out] res - result of modular exponentiation: 2x20 qword + * values in 2^52 radix. + * [in] base - base (2x20 qword values in 2^52 radix) + * [in] exp - array of 2 pointers to 16 qword values in 2^64 radix. + * Exponent is not converted to redundant representation. + * [in] m - moduli (2x20 qword values in 2^52 radix) + * [in] rr - Montgomery parameter for 2 moduli: RR = 2^2080 mod m. + * (2x20 qword values in 2^52 radix) + * [in] k0 - Montgomery parameter for 2 moduli: k0 = -1/m mod 2^64 + * + * \return (void). + */ +static void RSAZ_exp52x20_x2_256(BN_ULONG *out, /* [2][20] */ + const BN_ULONG *base, /* [2][20] */ + const BN_ULONG *exp[2], /* 2x16 */ + const BN_ULONG *m, /* [2][20] */ + const BN_ULONG *rr, /* [2][20] */ + const BN_ULONG k0[2]) +{ +# define BITSIZE_MODULUS (1024) +# define EXP_WIN_SIZE (5) +# define EXP_WIN_MASK ((1U << EXP_WIN_SIZE) - 1) +/* + * Number of digits (64-bit words) in redundant representation to handle + * modulus bits + */ +# define RED_DIGITS (20) +# define EXP_DIGITS (16) +# define DAMM ossl_rsaz_amm52x20_x2_256 +/* + * Squaring is done using multiplication now. That can be a subject of + * optimization in future. + */ +# define DAMS(r,a,m,k0) \ + ossl_rsaz_amm52x20_x2_256((r),(a),(a),(m),(k0)) + + /* Allocate stack for red(undant) result Y and multiplier X */ + ALIGN64 BN_ULONG red_Y[2][RED_DIGITS]; + ALIGN64 BN_ULONG red_X[2][RED_DIGITS]; + + /* Allocate expanded exponent */ + ALIGN64 BN_ULONG expz[2][EXP_DIGITS + 1]; + + /* Pre-computed table of base powers */ + ALIGN64 BN_ULONG red_table[1U << EXP_WIN_SIZE][2][RED_DIGITS]; + + int idx; + + memset(red_Y, 0, sizeof(red_Y)); + memset(red_table, 0, sizeof(red_table)); + memset(red_X, 0, sizeof(red_X)); + + /* + * Compute table of powers base^i, i = 0, ..., (2^EXP_WIN_SIZE) - 1 + * table[0] = mont(x^0) = mont(1) + * table[1] = mont(x^1) = mont(x) + */ + red_X[0][0] = 1; + red_X[1][0] = 1; + DAMM(red_table[0][0], (const BN_ULONG*)red_X, rr, m, k0); + DAMM(red_table[1][0], base, rr, m, k0); + + for (idx = 1; idx < (int)((1U << EXP_WIN_SIZE) / 2); idx++) { + DAMS(red_table[2 * idx + 0][0], red_table[1 * idx][0], m, k0); + DAMM(red_table[2 * idx + 1][0], red_table[2 * idx][0], red_table[1][0], m, k0); + } + + /* Copy and expand exponents */ + memcpy(expz[0], exp[0], EXP_DIGITS * sizeof(BN_ULONG)); + expz[0][EXP_DIGITS] = 0; + memcpy(expz[1], exp[1], EXP_DIGITS * sizeof(BN_ULONG)); + expz[1][EXP_DIGITS] = 0; + + /* Exponentiation */ + { + const int rem = BITSIZE_MODULUS % EXP_WIN_SIZE; + BN_ULONG table_idx_mask = EXP_WIN_MASK; + + int exp_bit_no = BITSIZE_MODULUS - rem; + int exp_chunk_no = exp_bit_no / 64; + int exp_chunk_shift = exp_bit_no % 64; + + BN_ULONG red_table_idx_0, red_table_idx_1; + + /* + * If rem == 0, then + * exp_bit_no = modulus_bitsize - exp_win_size + * However, this isn't possible because rem is { 1024, 1536, 2048 } % 5 + * which is { 4, 1, 3 } respectively. + * + * If this assertion ever fails the fix above is easy. + */ + OPENSSL_assert(rem != 0); + + /* Process 1-st exp window - just init result */ + red_table_idx_0 = expz[0][exp_chunk_no]; + red_table_idx_1 = expz[1][exp_chunk_no]; + /* + * The function operates with fixed moduli sizes divisible by 64, + * thus table index here is always in supported range [0, EXP_WIN_SIZE). + */ + red_table_idx_0 >>= exp_chunk_shift; + red_table_idx_1 >>= exp_chunk_shift; + + ossl_extract_multiplier_2x20_win5(red_Y[0], (const BN_ULONG*)red_table, + (int)red_table_idx_0, 0); + ossl_extract_multiplier_2x20_win5(red_Y[1], (const BN_ULONG*)red_table, + (int)red_table_idx_1, 1); + + /* Process other exp windows */ + for (exp_bit_no -= EXP_WIN_SIZE; exp_bit_no >= 0; exp_bit_no -= EXP_WIN_SIZE) { + /* Extract pre-computed multiplier from the table */ + { + BN_ULONG T; + + exp_chunk_no = exp_bit_no / 64; + exp_chunk_shift = exp_bit_no % 64; + { + red_table_idx_0 = expz[0][exp_chunk_no]; + T = expz[0][exp_chunk_no + 1]; + + red_table_idx_0 >>= exp_chunk_shift; + /* + * Get additional bits from then next quadword + * when 64-bit boundaries are crossed. + */ + if (exp_chunk_shift > 64 - EXP_WIN_SIZE) { + T <<= (64 - exp_chunk_shift); + red_table_idx_0 ^= T; + } + red_table_idx_0 &= table_idx_mask; + + ossl_extract_multiplier_2x20_win5(red_X[0], + (const BN_ULONG*)red_table, + (int)red_table_idx_0, 0); + } + { + red_table_idx_1 = expz[1][exp_chunk_no]; + T = expz[1][exp_chunk_no + 1]; + + red_table_idx_1 >>= exp_chunk_shift; + /* + * Get additional bits from then next quadword + * when 64-bit boundaries are crossed. + */ + if (exp_chunk_shift > 64 - EXP_WIN_SIZE) { + T <<= (64 - exp_chunk_shift); + red_table_idx_1 ^= T; + } + red_table_idx_1 &= table_idx_mask; + + ossl_extract_multiplier_2x20_win5(red_X[1], + (const BN_ULONG*)red_table, + (int)red_table_idx_1, 1); + } + } + + /* Series of squaring */ + DAMS((BN_ULONG*)red_Y, (const BN_ULONG*)red_Y, m, k0); + DAMS((BN_ULONG*)red_Y, (const BN_ULONG*)red_Y, m, k0); + DAMS((BN_ULONG*)red_Y, (const BN_ULONG*)red_Y, m, k0); + DAMS((BN_ULONG*)red_Y, (const BN_ULONG*)red_Y, m, k0); + DAMS((BN_ULONG*)red_Y, (const BN_ULONG*)red_Y, m, k0); + + DAMM((BN_ULONG*)red_Y, (const BN_ULONG*)red_Y, (const BN_ULONG*)red_X, m, k0); + } + } + + /* + * + * NB: After the last AMM of exponentiation in Montgomery domain, the result + * may be 1025-bit, but the conversion out of Montgomery domain performs an + * AMM(x,1) which guarantees that the final result is less than |m|, so no + * conditional subtraction is needed here. See "Efficient Software + * Implementations of Modular Exponentiation" (by Shay Gueron) paper for details. + */ + + /* Convert result back in regular 2^52 domain */ + memset(red_X, 0, sizeof(red_X)); + red_X[0][0] = 1; + red_X[1][0] = 1; + DAMM(out, (const BN_ULONG*)red_Y, (const BN_ULONG*)red_X, m, k0); + + /* Clear exponents */ + OPENSSL_cleanse(expz, sizeof(expz)); + OPENSSL_cleanse(red_Y, sizeof(red_Y)); + +# undef DAMS +# undef DAMM +# undef EXP_DIGITS +# undef RED_DIGITS +# undef EXP_WIN_MASK +# undef EXP_WIN_SIZE +# undef BITSIZE_MODULUS +} + +static ossl_inline uint64_t get_digit52(const uint8_t *in, int in_len) +{ + uint64_t digit = 0; + + assert(in != NULL); + + for (; in_len > 0; in_len--) { + digit <<= 8; + digit += (uint64_t)(in[in_len - 1]); + } + return digit; +} + +/* + * Convert array of words in regular (base=2^64) representation to array of + * words in redundant (base=2^52) one. + */ +static void to_words52(BN_ULONG *out, int out_len, + const BN_ULONG *in, int in_bitsize) +{ + uint8_t *in_str = NULL; + + assert(out != NULL); + assert(in != NULL); + /* Check destination buffer capacity */ + assert(out_len >= number_of_digits(in_bitsize, DIGIT_SIZE)); + + in_str = (uint8_t *)in; + + for (; in_bitsize >= (2 * DIGIT_SIZE); in_bitsize -= (2 * DIGIT_SIZE), out += 2) { + uint64_t digit; + + memcpy(&digit, in_str, sizeof(digit)); + out[0] = digit & DIGIT_MASK; + in_str += 6; + memcpy(&digit, in_str, sizeof(digit)); + out[1] = (digit >> 4) & DIGIT_MASK; + in_str += 7; + out_len -= 2; + } + + if (in_bitsize > DIGIT_SIZE) { + uint64_t digit = get_digit52(in_str, 7); + + out[0] = digit & DIGIT_MASK; + in_str += 6; + in_bitsize -= DIGIT_SIZE; + digit = get_digit52(in_str, BITS2WORD8_SIZE(in_bitsize)); + out[1] = digit >> 4; + out += 2; + out_len -= 2; + } else if (in_bitsize > 0) { + out[0] = get_digit52(in_str, BITS2WORD8_SIZE(in_bitsize)); + out++; + out_len--; + } + + while (out_len > 0) { + *out = 0; + out_len--; + out++; + } +} + +static ossl_inline void put_digit52(uint8_t *pStr, int strLen, uint64_t digit) +{ + assert(pStr != NULL); + + for (; strLen > 0; strLen--) { + *pStr++ = (uint8_t)(digit & 0xFF); + digit >>= 8; + } +} + +/* + * Convert array of words in redundant (base=2^52) representation to array of + * words in regular (base=2^64) one. + */ +static void from_words52(BN_ULONG *out, int out_bitsize, const BN_ULONG *in) +{ + int i; + int out_len = BITS2WORD64_SIZE(out_bitsize); + + assert(out != NULL); + assert(in != NULL); + + for (i = 0; i < out_len; i++) + out[i] = 0; + + { + uint8_t *out_str = (uint8_t *)out; + + for (; out_bitsize >= (2 * DIGIT_SIZE); + out_bitsize -= (2 * DIGIT_SIZE), in += 2) { + uint64_t digit; + + digit = in[0]; + memcpy(out_str, &digit, sizeof(digit)); + out_str += 6; + digit = digit >> 48 | in[1] << 4; + memcpy(out_str, &digit, sizeof(digit)); + out_str += 7; + } + + if (out_bitsize > DIGIT_SIZE) { + put_digit52(out_str, 7, in[0]); + out_str += 6; + out_bitsize -= DIGIT_SIZE; + put_digit52(out_str, BITS2WORD8_SIZE(out_bitsize), + (in[1] << 4 | in[0] >> 48)); + } else if (out_bitsize) { + put_digit52(out_str, BITS2WORD8_SIZE(out_bitsize), in[0]); + } + } +} + +/* + * Set bit at index |idx| in the words array |a|. + * It does not do any boundaries checks, make sure the index is valid before + * calling the function. + */ +static ossl_inline void set_bit(BN_ULONG *a, int idx) +{ + assert(a != NULL); + + { + int i, j; + + i = idx / BN_BITS2; + j = idx % BN_BITS2; + a[i] |= (((BN_ULONG)1) << j); + } +} + +#endif diff --git a/crypto/openssl/crypto/bn/x86-gf2m.S b/crypto/openssl/crypto/bn/x86-gf2m.S new file mode 100644 index 000000000000..b784b7cbe310 --- /dev/null +++ b/crypto/openssl/crypto/bn/x86-gf2m.S @@ -0,0 +1,377 @@ +.text +.type _mul_1x1_mmx,@function +.align 16 +_mul_1x1_mmx: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + subl $36,%esp + movl %eax,%ecx + leal (%eax,%eax,1),%edx + andl $1073741823,%ecx + leal (%edx,%edx,1),%ebp + movl $0,(%esp) + andl $2147483647,%edx + movd %eax,%mm2 + movd %ebx,%mm3 + movl %ecx,4(%esp) + xorl %edx,%ecx + pxor %mm5,%mm5 + pxor %mm4,%mm4 + movl %edx,8(%esp) + xorl %ebp,%edx + movl %ecx,12(%esp) + pcmpgtd %mm2,%mm5 + paddd %mm2,%mm2 + xorl %edx,%ecx + movl %ebp,16(%esp) + xorl %edx,%ebp + pand %mm3,%mm5 + pcmpgtd %mm2,%mm4 + movl %ecx,20(%esp) + xorl %ecx,%ebp + psllq $31,%mm5 + pand %mm3,%mm4 + movl %edx,24(%esp) + movl $7,%esi + movl %ebp,28(%esp) + movl %esi,%ebp + andl %ebx,%esi + shrl $3,%ebx + movl %ebp,%edi + psllq $30,%mm4 + andl %ebx,%edi + shrl $3,%ebx + movd (%esp,%esi,4),%mm0 + movl %ebp,%esi + andl %ebx,%esi + shrl $3,%ebx + movd (%esp,%edi,4),%mm2 + movl %ebp,%edi + psllq $3,%mm2 + andl %ebx,%edi + shrl $3,%ebx + pxor %mm2,%mm0 + movd (%esp,%esi,4),%mm1 + movl %ebp,%esi + psllq $6,%mm1 + andl %ebx,%esi + shrl $3,%ebx + pxor %mm1,%mm0 + movd (%esp,%edi,4),%mm2 + movl %ebp,%edi + psllq $9,%mm2 + andl %ebx,%edi + shrl $3,%ebx + pxor %mm2,%mm0 + movd (%esp,%esi,4),%mm1 + movl %ebp,%esi + psllq $12,%mm1 + andl %ebx,%esi + shrl $3,%ebx + pxor %mm1,%mm0 + movd (%esp,%edi,4),%mm2 + movl %ebp,%edi + psllq $15,%mm2 + andl %ebx,%edi + shrl $3,%ebx + pxor %mm2,%mm0 + movd (%esp,%esi,4),%mm1 + movl %ebp,%esi + psllq $18,%mm1 + andl %ebx,%esi + shrl $3,%ebx + pxor %mm1,%mm0 + movd (%esp,%edi,4),%mm2 + movl %ebp,%edi + psllq $21,%mm2 + andl %ebx,%edi + shrl $3,%ebx + pxor %mm2,%mm0 + movd (%esp,%esi,4),%mm1 + movl %ebp,%esi + psllq $24,%mm1 + andl %ebx,%esi + shrl $3,%ebx + pxor %mm1,%mm0 + movd (%esp,%edi,4),%mm2 + pxor %mm4,%mm0 + psllq $27,%mm2 + pxor %mm2,%mm0 + movd (%esp,%esi,4),%mm1 + pxor %mm5,%mm0 + psllq $30,%mm1 + addl $36,%esp + pxor %mm1,%mm0 + ret +.size _mul_1x1_mmx,.-_mul_1x1_mmx +.type _mul_1x1_ialu,@function +.align 16 +_mul_1x1_ialu: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + subl $36,%esp + movl %eax,%ecx + leal (%eax,%eax,1),%edx + leal (,%eax,4),%ebp + andl $1073741823,%ecx + leal (%eax,%eax,1),%edi + sarl $31,%eax + movl $0,(%esp) + andl $2147483647,%edx + movl %ecx,4(%esp) + xorl %edx,%ecx + movl %edx,8(%esp) + xorl %ebp,%edx + movl %ecx,12(%esp) + xorl %edx,%ecx + movl %ebp,16(%esp) + xorl %edx,%ebp + movl %ecx,20(%esp) + xorl %ecx,%ebp + sarl $31,%edi + andl %ebx,%eax + movl %edx,24(%esp) + andl %ebx,%edi + movl %ebp,28(%esp) + movl %eax,%edx + shll $31,%eax + movl %edi,%ecx + shrl $1,%edx + movl $7,%esi + shll $30,%edi + andl %ebx,%esi + shrl $2,%ecx + xorl %edi,%eax + shrl $3,%ebx + movl $7,%edi + andl %ebx,%edi + shrl $3,%ebx + xorl %ecx,%edx + xorl (%esp,%esi,4),%eax + movl $7,%esi + andl %ebx,%esi + shrl $3,%ebx + movl (%esp,%edi,4),%ebp + movl $7,%edi + movl %ebp,%ecx + shll $3,%ebp + andl %ebx,%edi + shrl $29,%ecx + xorl %ebp,%eax + shrl $3,%ebx + xorl %ecx,%edx + movl (%esp,%esi,4),%ecx + movl $7,%esi + movl %ecx,%ebp + shll $6,%ecx + andl %ebx,%esi + shrl $26,%ebp + xorl %ecx,%eax + shrl $3,%ebx + xorl %ebp,%edx + movl (%esp,%edi,4),%ebp + movl $7,%edi + movl %ebp,%ecx + shll $9,%ebp + andl %ebx,%edi + shrl $23,%ecx + xorl %ebp,%eax + shrl $3,%ebx + xorl %ecx,%edx + movl (%esp,%esi,4),%ecx + movl $7,%esi + movl %ecx,%ebp + shll $12,%ecx + andl %ebx,%esi + shrl $20,%ebp + xorl %ecx,%eax + shrl $3,%ebx + xorl %ebp,%edx + movl (%esp,%edi,4),%ebp + movl $7,%edi + movl %ebp,%ecx + shll $15,%ebp + andl %ebx,%edi + shrl $17,%ecx + xorl %ebp,%eax + shrl $3,%ebx + xorl %ecx,%edx + movl (%esp,%esi,4),%ecx + movl $7,%esi + movl %ecx,%ebp + shll $18,%ecx + andl %ebx,%esi + shrl $14,%ebp + xorl %ecx,%eax + shrl $3,%ebx + xorl %ebp,%edx + movl (%esp,%edi,4),%ebp + movl $7,%edi + movl %ebp,%ecx + shll $21,%ebp + andl %ebx,%edi + shrl $11,%ecx + xorl %ebp,%eax + shrl $3,%ebx + xorl %ecx,%edx + movl (%esp,%esi,4),%ecx + movl $7,%esi + movl %ecx,%ebp + shll $24,%ecx + andl %ebx,%esi + shrl $8,%ebp + xorl %ecx,%eax + shrl $3,%ebx + xorl %ebp,%edx + movl (%esp,%edi,4),%ebp + movl %ebp,%ecx + shll $27,%ebp + movl (%esp,%esi,4),%edi + shrl $5,%ecx + movl %edi,%esi + xorl %ebp,%eax + shll $30,%edi + xorl %ecx,%edx + shrl $2,%esi + xorl %edi,%eax + xorl %esi,%edx + addl $36,%esp + ret +.size _mul_1x1_ialu,.-_mul_1x1_ialu +.globl bn_GF2m_mul_2x2 +.type bn_GF2m_mul_2x2,@function +.align 16 +bn_GF2m_mul_2x2: +.L_bn_GF2m_mul_2x2_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + call .L000PIC_me_up +.L000PIC_me_up: + popl %edx + leal OPENSSL_ia32cap_P-.L000PIC_me_up(%edx),%edx + movl (%edx),%eax + movl 4(%edx),%edx + testl $8388608,%eax + jz .L001ialu + testl $16777216,%eax + jz .L002mmx + testl $2,%edx + jz .L002mmx + movups 8(%esp),%xmm0 + shufps $177,%xmm0,%xmm0 +.byte 102,15,58,68,192,1 + movl 4(%esp),%eax + movups %xmm0,(%eax) + ret +.align 16 +.L002mmx: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%eax + movl 32(%esp),%ebx + call _mul_1x1_mmx + movq %mm0,%mm7 + movl 28(%esp),%eax + movl 36(%esp),%ebx + call _mul_1x1_mmx + movq %mm0,%mm6 + movl 24(%esp),%eax + movl 32(%esp),%ebx + xorl 28(%esp),%eax + xorl 36(%esp),%ebx + call _mul_1x1_mmx + pxor %mm7,%mm0 + movl 20(%esp),%eax + pxor %mm6,%mm0 + movq %mm0,%mm2 + psllq $32,%mm0 + popl %edi + psrlq $32,%mm2 + popl %esi + pxor %mm6,%mm0 + popl %ebx + pxor %mm7,%mm2 + movq %mm0,(%eax) + popl %ebp + movq %mm2,8(%eax) + emms + ret +.align 16 +.L001ialu: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + subl $20,%esp + movl 44(%esp),%eax + movl 52(%esp),%ebx + call _mul_1x1_ialu + movl %eax,8(%esp) + movl %edx,12(%esp) + movl 48(%esp),%eax + movl 56(%esp),%ebx + call _mul_1x1_ialu + movl %eax,(%esp) + movl %edx,4(%esp) + movl 44(%esp),%eax + movl 52(%esp),%ebx + xorl 48(%esp),%eax + xorl 56(%esp),%ebx + call _mul_1x1_ialu + movl 40(%esp),%ebp + movl (%esp),%ebx + movl 4(%esp),%ecx + movl 8(%esp),%edi + movl 12(%esp),%esi + xorl %edx,%eax + xorl %ecx,%edx + xorl %ebx,%eax + movl %ebx,(%ebp) + xorl %edi,%edx + movl %esi,12(%ebp) + xorl %esi,%eax + addl $20,%esp + xorl %esi,%edx + popl %edi + xorl %edx,%eax + popl %esi + movl %edx,8(%ebp) + popl %ebx + movl %eax,4(%ebp) + popl %ebp + ret +.size bn_GF2m_mul_2x2,.-.L_bn_GF2m_mul_2x2_begin +.byte 71,70,40,50,94,109,41,32,77,117,108,116,105,112,108,105 +.byte 99,97,116,105,111,110,32,102,111,114,32,120,56,54,44,32 +.byte 67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97 +.byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103 +.byte 62,0 +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/bn/x86-mont.S b/crypto/openssl/crypto/bn/x86-mont.S new file mode 100644 index 000000000000..5d8a4c6cb316 --- /dev/null +++ b/crypto/openssl/crypto/bn/x86-mont.S @@ -0,0 +1,497 @@ +.text +.globl bn_mul_mont +.type bn_mul_mont,@function +.align 16 +bn_mul_mont: +.L_bn_mul_mont_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + xorl %eax,%eax + movl 40(%esp),%edi + cmpl $4,%edi + jl .L000just_leave + leal 20(%esp),%esi + leal 24(%esp),%edx + addl $2,%edi + negl %edi + leal -32(%esp,%edi,4),%ebp + negl %edi + movl %ebp,%eax + subl %edx,%eax + andl $2047,%eax + subl %eax,%ebp + xorl %ebp,%edx + andl $2048,%edx + xorl $2048,%edx + subl %edx,%ebp + andl $-64,%ebp + movl %esp,%eax + subl %ebp,%eax + andl $-4096,%eax + movl %esp,%edx + leal (%ebp,%eax,1),%esp + movl (%esp),%eax + cmpl %ebp,%esp + ja .L001page_walk + jmp .L002page_walk_done +.align 16 +.L001page_walk: + leal -4096(%esp),%esp + movl (%esp),%eax + cmpl %ebp,%esp + ja .L001page_walk +.L002page_walk_done: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%ebp + movl 16(%esi),%esi + movl (%esi),%esi + movl %eax,4(%esp) + movl %ebx,8(%esp) + movl %ecx,12(%esp) + movl %ebp,16(%esp) + movl %esi,20(%esp) + leal -3(%edi),%ebx + movl %edx,24(%esp) + call .L003PIC_me_up +.L003PIC_me_up: + popl %eax + leal OPENSSL_ia32cap_P-.L003PIC_me_up(%eax),%eax + btl $26,(%eax) + jnc .L004non_sse2 + movl $-1,%eax + movd %eax,%mm7 + movl 8(%esp),%esi + movl 12(%esp),%edi + movl 16(%esp),%ebp + xorl %edx,%edx + xorl %ecx,%ecx + movd (%edi),%mm4 + movd (%esi),%mm5 + movd (%ebp),%mm3 + pmuludq %mm4,%mm5 + movq %mm5,%mm2 + movq %mm5,%mm0 + pand %mm7,%mm0 + pmuludq 20(%esp),%mm5 + pmuludq %mm5,%mm3 + paddq %mm0,%mm3 + movd 4(%ebp),%mm1 + movd 4(%esi),%mm0 + psrlq $32,%mm2 + psrlq $32,%mm3 + incl %ecx +.align 16 +.L0051st: + pmuludq %mm4,%mm0 + pmuludq %mm5,%mm1 + paddq %mm0,%mm2 + paddq %mm1,%mm3 + movq %mm2,%mm0 + pand %mm7,%mm0 + movd 4(%ebp,%ecx,4),%mm1 + paddq %mm0,%mm3 + movd 4(%esi,%ecx,4),%mm0 + psrlq $32,%mm2 + movd %mm3,28(%esp,%ecx,4) + psrlq $32,%mm3 + leal 1(%ecx),%ecx + cmpl %ebx,%ecx + jl .L0051st + pmuludq %mm4,%mm0 + pmuludq %mm5,%mm1 + paddq %mm0,%mm2 + paddq %mm1,%mm3 + movq %mm2,%mm0 + pand %mm7,%mm0 + paddq %mm0,%mm3 + movd %mm3,28(%esp,%ecx,4) + psrlq $32,%mm2 + psrlq $32,%mm3 + paddq %mm2,%mm3 + movq %mm3,32(%esp,%ebx,4) + incl %edx +.L006outer: + xorl %ecx,%ecx + movd (%edi,%edx,4),%mm4 + movd (%esi),%mm5 + movd 32(%esp),%mm6 + movd (%ebp),%mm3 + pmuludq %mm4,%mm5 + paddq %mm6,%mm5 + movq %mm5,%mm0 + movq %mm5,%mm2 + pand %mm7,%mm0 + pmuludq 20(%esp),%mm5 + pmuludq %mm5,%mm3 + paddq %mm0,%mm3 + movd 36(%esp),%mm6 + movd 4(%ebp),%mm1 + movd 4(%esi),%mm0 + psrlq $32,%mm2 + psrlq $32,%mm3 + paddq %mm6,%mm2 + incl %ecx + decl %ebx +.L007inner: + pmuludq %mm4,%mm0 + pmuludq %mm5,%mm1 + paddq %mm0,%mm2 + paddq %mm1,%mm3 + movq %mm2,%mm0 + movd 36(%esp,%ecx,4),%mm6 + pand %mm7,%mm0 + movd 4(%ebp,%ecx,4),%mm1 + paddq %mm0,%mm3 + movd 4(%esi,%ecx,4),%mm0 + psrlq $32,%mm2 + movd %mm3,28(%esp,%ecx,4) + psrlq $32,%mm3 + paddq %mm6,%mm2 + decl %ebx + leal 1(%ecx),%ecx + jnz .L007inner + movl %ecx,%ebx + pmuludq %mm4,%mm0 + pmuludq %mm5,%mm1 + paddq %mm0,%mm2 + paddq %mm1,%mm3 + movq %mm2,%mm0 + pand %mm7,%mm0 + paddq %mm0,%mm3 + movd %mm3,28(%esp,%ecx,4) + psrlq $32,%mm2 + psrlq $32,%mm3 + movd 36(%esp,%ebx,4),%mm6 + paddq %mm2,%mm3 + paddq %mm6,%mm3 + movq %mm3,32(%esp,%ebx,4) + leal 1(%edx),%edx + cmpl %ebx,%edx + jle .L006outer + emms + jmp .L008common_tail +.align 16 +.L004non_sse2: + movl 8(%esp),%esi + leal 1(%ebx),%ebp + movl 12(%esp),%edi + xorl %ecx,%ecx + movl %esi,%edx + andl $1,%ebp + subl %edi,%edx + leal 4(%edi,%ebx,4),%eax + orl %edx,%ebp + movl (%edi),%edi + jz .L009bn_sqr_mont + movl %eax,28(%esp) + movl (%esi),%eax + xorl %edx,%edx +.align 16 +.L010mull: + movl %edx,%ebp + mull %edi + addl %eax,%ebp + leal 1(%ecx),%ecx + adcl $0,%edx + movl (%esi,%ecx,4),%eax + cmpl %ebx,%ecx + movl %ebp,28(%esp,%ecx,4) + jl .L010mull + movl %edx,%ebp + mull %edi + movl 20(%esp),%edi + addl %ebp,%eax + movl 16(%esp),%esi + adcl $0,%edx + imull 32(%esp),%edi + movl %eax,32(%esp,%ebx,4) + xorl %ecx,%ecx + movl %edx,36(%esp,%ebx,4) + movl %ecx,40(%esp,%ebx,4) + movl (%esi),%eax + mull %edi + addl 32(%esp),%eax + movl 4(%esi),%eax + adcl $0,%edx + incl %ecx + jmp .L0112ndmadd +.align 16 +.L0121stmadd: + movl %edx,%ebp + mull %edi + addl 32(%esp,%ecx,4),%ebp + leal 1(%ecx),%ecx + adcl $0,%edx + addl %eax,%ebp + movl (%esi,%ecx,4),%eax + adcl $0,%edx + cmpl %ebx,%ecx + movl %ebp,28(%esp,%ecx,4) + jl .L0121stmadd + movl %edx,%ebp + mull %edi + addl 32(%esp,%ebx,4),%eax + movl 20(%esp),%edi + adcl $0,%edx + movl 16(%esp),%esi + addl %eax,%ebp + adcl $0,%edx + imull 32(%esp),%edi + xorl %ecx,%ecx + addl 36(%esp,%ebx,4),%edx + movl %ebp,32(%esp,%ebx,4) + adcl $0,%ecx + movl (%esi),%eax + movl %edx,36(%esp,%ebx,4) + movl %ecx,40(%esp,%ebx,4) + mull %edi + addl 32(%esp),%eax + movl 4(%esi),%eax + adcl $0,%edx + movl $1,%ecx +.align 16 +.L0112ndmadd: + movl %edx,%ebp + mull %edi + addl 32(%esp,%ecx,4),%ebp + leal 1(%ecx),%ecx + adcl $0,%edx + addl %eax,%ebp + movl (%esi,%ecx,4),%eax + adcl $0,%edx + cmpl %ebx,%ecx + movl %ebp,24(%esp,%ecx,4) + jl .L0112ndmadd + movl %edx,%ebp + mull %edi + addl 32(%esp,%ebx,4),%ebp + adcl $0,%edx + addl %eax,%ebp + adcl $0,%edx + movl %ebp,28(%esp,%ebx,4) + xorl %eax,%eax + movl 12(%esp),%ecx + addl 36(%esp,%ebx,4),%edx + adcl 40(%esp,%ebx,4),%eax + leal 4(%ecx),%ecx + movl %edx,32(%esp,%ebx,4) + cmpl 28(%esp),%ecx + movl %eax,36(%esp,%ebx,4) + je .L008common_tail + movl (%ecx),%edi + movl 8(%esp),%esi + movl %ecx,12(%esp) + xorl %ecx,%ecx + xorl %edx,%edx + movl (%esi),%eax + jmp .L0121stmadd +.align 16 +.L009bn_sqr_mont: + movl %ebx,(%esp) + movl %ecx,12(%esp) + movl %edi,%eax + mull %edi + movl %eax,32(%esp) + movl %edx,%ebx + shrl $1,%edx + andl $1,%ebx + incl %ecx +.align 16 +.L013sqr: + movl (%esi,%ecx,4),%eax + movl %edx,%ebp + mull %edi + addl %ebp,%eax + leal 1(%ecx),%ecx + adcl $0,%edx + leal (%ebx,%eax,2),%ebp + shrl $31,%eax + cmpl (%esp),%ecx + movl %eax,%ebx + movl %ebp,28(%esp,%ecx,4) + jl .L013sqr + movl (%esi,%ecx,4),%eax + movl %edx,%ebp + mull %edi + addl %ebp,%eax + movl 20(%esp),%edi + adcl $0,%edx + movl 16(%esp),%esi + leal (%ebx,%eax,2),%ebp + imull 32(%esp),%edi + shrl $31,%eax + movl %ebp,32(%esp,%ecx,4) + leal (%eax,%edx,2),%ebp + movl (%esi),%eax + shrl $31,%edx + movl %ebp,36(%esp,%ecx,4) + movl %edx,40(%esp,%ecx,4) + mull %edi + addl 32(%esp),%eax + movl %ecx,%ebx + adcl $0,%edx + movl 4(%esi),%eax + movl $1,%ecx +.align 16 +.L0143rdmadd: + movl %edx,%ebp + mull %edi + addl 32(%esp,%ecx,4),%ebp + adcl $0,%edx + addl %eax,%ebp + movl 4(%esi,%ecx,4),%eax + adcl $0,%edx + movl %ebp,28(%esp,%ecx,4) + movl %edx,%ebp + mull %edi + addl 36(%esp,%ecx,4),%ebp + leal 2(%ecx),%ecx + adcl $0,%edx + addl %eax,%ebp + movl (%esi,%ecx,4),%eax + adcl $0,%edx + cmpl %ebx,%ecx + movl %ebp,24(%esp,%ecx,4) + jl .L0143rdmadd + movl %edx,%ebp + mull %edi + addl 32(%esp,%ebx,4),%ebp + adcl $0,%edx + addl %eax,%ebp + adcl $0,%edx + movl %ebp,28(%esp,%ebx,4) + movl 12(%esp),%ecx + xorl %eax,%eax + movl 8(%esp),%esi + addl 36(%esp,%ebx,4),%edx + adcl 40(%esp,%ebx,4),%eax + movl %edx,32(%esp,%ebx,4) + cmpl %ebx,%ecx + movl %eax,36(%esp,%ebx,4) + je .L008common_tail + movl 4(%esi,%ecx,4),%edi + leal 1(%ecx),%ecx + movl %edi,%eax + movl %ecx,12(%esp) + mull %edi + addl 32(%esp,%ecx,4),%eax + adcl $0,%edx + movl %eax,32(%esp,%ecx,4) + xorl %ebp,%ebp + cmpl %ebx,%ecx + leal 1(%ecx),%ecx + je .L015sqrlast + movl %edx,%ebx + shrl $1,%edx + andl $1,%ebx +.align 16 +.L016sqradd: + movl (%esi,%ecx,4),%eax + movl %edx,%ebp + mull %edi + addl %ebp,%eax + leal (%eax,%eax,1),%ebp + adcl $0,%edx + shrl $31,%eax + addl 32(%esp,%ecx,4),%ebp + leal 1(%ecx),%ecx + adcl $0,%eax + addl %ebx,%ebp + adcl $0,%eax + cmpl (%esp),%ecx + movl %ebp,28(%esp,%ecx,4) + movl %eax,%ebx + jle .L016sqradd + movl %edx,%ebp + addl %edx,%edx + shrl $31,%ebp + addl %ebx,%edx + adcl $0,%ebp +.L015sqrlast: + movl 20(%esp),%edi + movl 16(%esp),%esi + imull 32(%esp),%edi + addl 32(%esp,%ecx,4),%edx + movl (%esi),%eax + adcl $0,%ebp + movl %edx,32(%esp,%ecx,4) + movl %ebp,36(%esp,%ecx,4) + mull %edi + addl 32(%esp),%eax + leal -1(%ecx),%ebx + adcl $0,%edx + movl $1,%ecx + movl 4(%esi),%eax + jmp .L0143rdmadd +.align 16 +.L008common_tail: + movl 16(%esp),%ebp + movl 4(%esp),%edi + leal 32(%esp),%esi + movl (%esi),%eax + movl %ebx,%ecx + xorl %edx,%edx +.align 16 +.L017sub: + sbbl (%ebp,%edx,4),%eax + movl %eax,(%edi,%edx,4) + decl %ecx + movl 4(%esi,%edx,4),%eax + leal 1(%edx),%edx + jge .L017sub + sbbl $0,%eax + movl $-1,%edx + xorl %eax,%edx + jmp .L018copy +.align 16 +.L018copy: + movl 32(%esp,%ebx,4),%esi + movl (%edi,%ebx,4),%ebp + movl %ecx,32(%esp,%ebx,4) + andl %eax,%esi + andl %edx,%ebp + orl %esi,%ebp + movl %ebp,(%edi,%ebx,4) + decl %ebx + jge .L018copy + movl 24(%esp),%esp + movl $1,%eax +.L000just_leave: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size bn_mul_mont,.-.L_bn_mul_mont_begin +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105 +.byte 112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56 +.byte 54,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121 +.byte 32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46 +.byte 111,114,103,62,0 +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/bn/x86_64-gf2m.S b/crypto/openssl/crypto/bn/x86_64-gf2m.S new file mode 100644 index 000000000000..7dde3fcc0ceb --- /dev/null +++ b/crypto/openssl/crypto/bn/x86_64-gf2m.S @@ -0,0 +1,332 @@ +.text + +.type _mul_1x1,@function +.align 16 +_mul_1x1: +.cfi_startproc + subq $128+8,%rsp +.cfi_adjust_cfa_offset 128+8 + movq $-1,%r9 + leaq (%rax,%rax,1),%rsi + shrq $3,%r9 + leaq (,%rax,4),%rdi + andq %rax,%r9 + leaq (,%rax,8),%r12 + sarq $63,%rax + leaq (%r9,%r9,1),%r10 + sarq $63,%rsi + leaq (,%r9,4),%r11 + andq %rbp,%rax + sarq $63,%rdi + movq %rax,%rdx + shlq $63,%rax + andq %rbp,%rsi + shrq $1,%rdx + movq %rsi,%rcx + shlq $62,%rsi + andq %rbp,%rdi + shrq $2,%rcx + xorq %rsi,%rax + movq %rdi,%rbx + shlq $61,%rdi + xorq %rcx,%rdx + shrq $3,%rbx + xorq %rdi,%rax + xorq %rbx,%rdx + + movq %r9,%r13 + movq $0,0(%rsp) + xorq %r10,%r13 + movq %r9,8(%rsp) + movq %r11,%r14 + movq %r10,16(%rsp) + xorq %r12,%r14 + movq %r13,24(%rsp) + + xorq %r11,%r9 + movq %r11,32(%rsp) + xorq %r11,%r10 + movq %r9,40(%rsp) + xorq %r11,%r13 + movq %r10,48(%rsp) + xorq %r14,%r9 + movq %r13,56(%rsp) + xorq %r14,%r10 + + movq %r12,64(%rsp) + xorq %r14,%r13 + movq %r9,72(%rsp) + xorq %r11,%r9 + movq %r10,80(%rsp) + xorq %r11,%r10 + movq %r13,88(%rsp) + + xorq %r11,%r13 + movq %r14,96(%rsp) + movq %r8,%rsi + movq %r9,104(%rsp) + andq %rbp,%rsi + movq %r10,112(%rsp) + shrq $4,%rbp + movq %r13,120(%rsp) + movq %r8,%rdi + andq %rbp,%rdi + shrq $4,%rbp + + movq (%rsp,%rsi,8),%xmm0 + movq %r8,%rsi + andq %rbp,%rsi + shrq $4,%rbp + movq (%rsp,%rdi,8),%rcx + movq %r8,%rdi + movq %rcx,%rbx + shlq $4,%rcx + andq %rbp,%rdi + movq (%rsp,%rsi,8),%xmm1 + shrq $60,%rbx + xorq %rcx,%rax + pslldq $1,%xmm1 + movq %r8,%rsi + shrq $4,%rbp + xorq %rbx,%rdx + andq %rbp,%rsi + shrq $4,%rbp + pxor %xmm1,%xmm0 + movq (%rsp,%rdi,8),%rcx + movq %r8,%rdi + movq %rcx,%rbx + shlq $12,%rcx + andq %rbp,%rdi + movq (%rsp,%rsi,8),%xmm1 + shrq $52,%rbx + xorq %rcx,%rax + pslldq $2,%xmm1 + movq %r8,%rsi + shrq $4,%rbp + xorq %rbx,%rdx + andq %rbp,%rsi + shrq $4,%rbp + pxor %xmm1,%xmm0 + movq (%rsp,%rdi,8),%rcx + movq %r8,%rdi + movq %rcx,%rbx + shlq $20,%rcx + andq %rbp,%rdi + movq (%rsp,%rsi,8),%xmm1 + shrq $44,%rbx + xorq %rcx,%rax + pslldq $3,%xmm1 + movq %r8,%rsi + shrq $4,%rbp + xorq %rbx,%rdx + andq %rbp,%rsi + shrq $4,%rbp + pxor %xmm1,%xmm0 + movq (%rsp,%rdi,8),%rcx + movq %r8,%rdi + movq %rcx,%rbx + shlq $28,%rcx + andq %rbp,%rdi + movq (%rsp,%rsi,8),%xmm1 + shrq $36,%rbx + xorq %rcx,%rax + pslldq $4,%xmm1 + movq %r8,%rsi + shrq $4,%rbp + xorq %rbx,%rdx + andq %rbp,%rsi + shrq $4,%rbp + pxor %xmm1,%xmm0 + movq (%rsp,%rdi,8),%rcx + movq %r8,%rdi + movq %rcx,%rbx + shlq $36,%rcx + andq %rbp,%rdi + movq (%rsp,%rsi,8),%xmm1 + shrq $28,%rbx + xorq %rcx,%rax + pslldq $5,%xmm1 + movq %r8,%rsi + shrq $4,%rbp + xorq %rbx,%rdx + andq %rbp,%rsi + shrq $4,%rbp + pxor %xmm1,%xmm0 + movq (%rsp,%rdi,8),%rcx + movq %r8,%rdi + movq %rcx,%rbx + shlq $44,%rcx + andq %rbp,%rdi + movq (%rsp,%rsi,8),%xmm1 + shrq $20,%rbx + xorq %rcx,%rax + pslldq $6,%xmm1 + movq %r8,%rsi + shrq $4,%rbp + xorq %rbx,%rdx + andq %rbp,%rsi + shrq $4,%rbp + pxor %xmm1,%xmm0 + movq (%rsp,%rdi,8),%rcx + movq %r8,%rdi + movq %rcx,%rbx + shlq $52,%rcx + andq %rbp,%rdi + movq (%rsp,%rsi,8),%xmm1 + shrq $12,%rbx + xorq %rcx,%rax + pslldq $7,%xmm1 + movq %r8,%rsi + shrq $4,%rbp + xorq %rbx,%rdx + andq %rbp,%rsi + shrq $4,%rbp + pxor %xmm1,%xmm0 + movq (%rsp,%rdi,8),%rcx + movq %rcx,%rbx + shlq $60,%rcx +.byte 102,72,15,126,198 + shrq $4,%rbx + xorq %rcx,%rax + psrldq $8,%xmm0 + xorq %rbx,%rdx +.byte 102,72,15,126,199 + xorq %rsi,%rax + xorq %rdi,%rdx + + addq $128+8,%rsp +.cfi_adjust_cfa_offset -128-8 + .byte 0xf3,0xc3 +.Lend_mul_1x1: +.cfi_endproc +.size _mul_1x1,.-_mul_1x1 + +.globl bn_GF2m_mul_2x2 +.type bn_GF2m_mul_2x2,@function +.align 16 +bn_GF2m_mul_2x2: +.cfi_startproc + movq %rsp,%rax + movq OPENSSL_ia32cap_P(%rip),%r10 + btq $33,%r10 + jnc .Lvanilla_mul_2x2 + +.byte 102,72,15,110,198 +.byte 102,72,15,110,201 +.byte 102,72,15,110,210 +.byte 102,73,15,110,216 + movdqa %xmm0,%xmm4 + movdqa %xmm1,%xmm5 +.byte 102,15,58,68,193,0 + pxor %xmm2,%xmm4 + pxor %xmm3,%xmm5 +.byte 102,15,58,68,211,0 +.byte 102,15,58,68,229,0 + xorps %xmm0,%xmm4 + xorps %xmm2,%xmm4 + movdqa %xmm4,%xmm5 + pslldq $8,%xmm4 + psrldq $8,%xmm5 + pxor %xmm4,%xmm2 + pxor %xmm5,%xmm0 + movdqu %xmm2,0(%rdi) + movdqu %xmm0,16(%rdi) + .byte 0xf3,0xc3 + +.align 16 +.Lvanilla_mul_2x2: + leaq -136(%rsp),%rsp +.cfi_adjust_cfa_offset 8*17 + movq %r14,80(%rsp) +.cfi_rel_offset %r14,8*10 + movq %r13,88(%rsp) +.cfi_rel_offset %r13,8*11 + movq %r12,96(%rsp) +.cfi_rel_offset %r12,8*12 + movq %rbp,104(%rsp) +.cfi_rel_offset %rbp,8*13 + movq %rbx,112(%rsp) +.cfi_rel_offset %rbx,8*14 +.Lbody_mul_2x2: + movq %rdi,32(%rsp) + movq %rsi,40(%rsp) + movq %rdx,48(%rsp) + movq %rcx,56(%rsp) + movq %r8,64(%rsp) + + movq $0xf,%r8 + movq %rsi,%rax + movq %rcx,%rbp + call _mul_1x1 + movq %rax,16(%rsp) + movq %rdx,24(%rsp) + + movq 48(%rsp),%rax + movq 64(%rsp),%rbp + call _mul_1x1 + movq %rax,0(%rsp) + movq %rdx,8(%rsp) + + movq 40(%rsp),%rax + movq 56(%rsp),%rbp + xorq 48(%rsp),%rax + xorq 64(%rsp),%rbp + call _mul_1x1 + movq 0(%rsp),%rbx + movq 8(%rsp),%rcx + movq 16(%rsp),%rdi + movq 24(%rsp),%rsi + movq 32(%rsp),%rbp + + xorq %rdx,%rax + xorq %rcx,%rdx + xorq %rbx,%rax + movq %rbx,0(%rbp) + xorq %rdi,%rdx + movq %rsi,24(%rbp) + xorq %rsi,%rax + xorq %rsi,%rdx + xorq %rdx,%rax + movq %rdx,16(%rbp) + movq %rax,8(%rbp) + + movq 80(%rsp),%r14 +.cfi_restore %r14 + movq 88(%rsp),%r13 +.cfi_restore %r13 + movq 96(%rsp),%r12 +.cfi_restore %r12 + movq 104(%rsp),%rbp +.cfi_restore %rbp + movq 112(%rsp),%rbx +.cfi_restore %rbx + leaq 136(%rsp),%rsp +.cfi_adjust_cfa_offset -8*17 +.Lepilogue_mul_2x2: + .byte 0xf3,0xc3 +.Lend_mul_2x2: +.cfi_endproc +.size bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2 +.byte 71,70,40,50,94,109,41,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 16 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/bn/x86_64-mont.S b/crypto/openssl/crypto/bn/x86_64-mont.S new file mode 100644 index 000000000000..42d7460caa88 --- /dev/null +++ b/crypto/openssl/crypto/bn/x86_64-mont.S @@ -0,0 +1,1260 @@ +.text + + + +.globl bn_mul_mont +.type bn_mul_mont,@function +.align 16 +bn_mul_mont: +.cfi_startproc + movl %r9d,%r9d + movq %rsp,%rax +.cfi_def_cfa_register %rax + testl $3,%r9d + jnz .Lmul_enter + cmpl $8,%r9d + jb .Lmul_enter + movl OPENSSL_ia32cap_P+8(%rip),%r11d + cmpq %rsi,%rdx + jne .Lmul4x_enter + testl $7,%r9d + jz .Lsqr8x_enter + jmp .Lmul4x_enter + +.align 16 +.Lmul_enter: + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + negq %r9 + movq %rsp,%r11 + leaq -16(%rsp,%r9,8),%r10 + negq %r9 + andq $-1024,%r10 + + + + + + + + + + subq %r10,%r11 + andq $-4096,%r11 + leaq (%r10,%r11,1),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul_page_walk + jmp .Lmul_page_walk_done + +.align 16 +.Lmul_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul_page_walk +.Lmul_page_walk_done: + + movq %rax,8(%rsp,%r9,8) +.cfi_escape 0x0f,0x0a,0x77,0x08,0x79,0x00,0x38,0x1e,0x22,0x06,0x23,0x08 +.Lmul_body: + movq %rdx,%r12 + movq (%r8),%r8 + movq (%r12),%rbx + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .L1st_enter + +.align 16 +.L1st: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r13 + movq %r10,%r11 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.L1st_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 1(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + cmpq %r9,%r15 + jne .L1st + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + movq %r10,%r11 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + jmp .Louter +.align 16 +.Louter: + movq (%r12,%r14,8),%rbx + xorq %r15,%r15 + movq %r8,%rbp + movq (%rsp),%r10 + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq 8(%rsp),%r10 + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .Linner_enter + +.align 16 +.Linner: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.Linner_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + leaq 1(%r15),%r15 + + mulq %rbp + cmpq %r9,%r15 + jne .Linner + + addq %rax,%r13 + movq (%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + cmpq %r9,%r14 + jb .Louter + + xorq %r14,%r14 + movq (%rsp),%rax + movq %r9,%r15 + +.align 16 +.Lsub: sbbq (%rcx,%r14,8),%rax + movq %rax,(%rdi,%r14,8) + movq 8(%rsp,%r14,8),%rax + leaq 1(%r14),%r14 + decq %r15 + jnz .Lsub + + sbbq $0,%rax + movq $-1,%rbx + xorq %rax,%rbx + xorq %r14,%r14 + movq %r9,%r15 + +.Lcopy: + movq (%rdi,%r14,8),%rcx + movq (%rsp,%r14,8),%rdx + andq %rbx,%rcx + andq %rax,%rdx + movq %r9,(%rsp,%r14,8) + orq %rcx,%rdx + movq %rdx,(%rdi,%r14,8) + leaq 1(%r14),%r14 + subq $1,%r15 + jnz .Lcopy + + movq 8(%rsp,%r9,8),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmul_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mul_mont,.-bn_mul_mont +.type bn_mul4x_mont,@function +.align 16 +bn_mul4x_mont: +.cfi_startproc + movl %r9d,%r9d + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lmul4x_enter: + andl $0x80100,%r11d + cmpl $0x80100,%r11d + je .Lmulx4x_enter + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + negq %r9 + movq %rsp,%r11 + leaq -32(%rsp,%r9,8),%r10 + negq %r9 + andq $-1024,%r10 + + subq %r10,%r11 + andq $-4096,%r11 + leaq (%r10,%r11,1),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul4x_page_walk + jmp .Lmul4x_page_walk_done + +.Lmul4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul4x_page_walk +.Lmul4x_page_walk_done: + + movq %rax,8(%rsp,%r9,8) +.cfi_escape 0x0f,0x0a,0x77,0x08,0x79,0x00,0x38,0x1e,0x22,0x06,0x23,0x08 +.Lmul4x_body: + movq %rdi,16(%rsp,%r9,8) + movq %rdx,%r12 + movq (%r8),%r8 + movq (%r12),%rbx + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp .L1st4x +.align 16 +.L1st4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jb .L1st4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + leaq 1(%r14),%r14 +.align 4 +.Louter4x: + movq (%r12,%r14,8),%rbx + xorq %r15,%r15 + movq (%rsp),%r10 + movq %r8,%rbp + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%rsp),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 4(%r15),%r15 + adcq $0,%rdx + movq %rdi,(%rsp) + movq %rdx,%r13 + jmp .Linner4x +.align 16 +.Linner4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq 8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 4(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq -16(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-32(%rsp,%r15,8) + movq %rdx,%r13 + cmpq %r9,%r15 + jb .Linner4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -16(%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%rsp,%r15,8) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx,%r15,8),%rax + adcq $0,%rdx + addq -8(%rsp,%r15,8),%r11 + adcq $0,%rdx + leaq 1(%r14),%r14 + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%rsp,%r15,8) + movq %rdx,%r13 + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + addq (%rsp,%r9,8),%r13 + adcq $0,%rdi + movq %r13,-8(%rsp,%r15,8) + movq %rdi,(%rsp,%r15,8) + + cmpq %r9,%r14 + jb .Louter4x + movq 16(%rsp,%r9,8),%rdi + leaq -4(%r9),%r15 + movq 0(%rsp),%rax + movq 8(%rsp),%rdx + shrq $2,%r15 + leaq (%rsp),%rsi + xorq %r14,%r14 + + subq 0(%rcx),%rax + movq 16(%rsi),%rbx + movq 24(%rsi),%rbp + sbbq 8(%rcx),%rdx + +.Lsub4x: + movq %rax,0(%rdi,%r14,8) + movq %rdx,8(%rdi,%r14,8) + sbbq 16(%rcx,%r14,8),%rbx + movq 32(%rsi,%r14,8),%rax + movq 40(%rsi,%r14,8),%rdx + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + movq %rbp,24(%rdi,%r14,8) + sbbq 32(%rcx,%r14,8),%rax + movq 48(%rsi,%r14,8),%rbx + movq 56(%rsi,%r14,8),%rbp + sbbq 40(%rcx,%r14,8),%rdx + leaq 4(%r14),%r14 + decq %r15 + jnz .Lsub4x + + movq %rax,0(%rdi,%r14,8) + movq 32(%rsi,%r14,8),%rax + sbbq 16(%rcx,%r14,8),%rbx + movq %rdx,8(%rdi,%r14,8) + sbbq 24(%rcx,%r14,8),%rbp + movq %rbx,16(%rdi,%r14,8) + + sbbq $0,%rax + movq %rbp,24(%rdi,%r14,8) + pxor %xmm0,%xmm0 +.byte 102,72,15,110,224 + pcmpeqd %xmm5,%xmm5 + pshufd $0,%xmm4,%xmm4 + movq %r9,%r15 + pxor %xmm4,%xmm5 + shrq $2,%r15 + xorl %eax,%eax + + jmp .Lcopy4x +.align 16 +.Lcopy4x: + movdqa (%rsp,%rax,1),%xmm1 + movdqu (%rdi,%rax,1),%xmm2 + pand %xmm4,%xmm1 + pand %xmm5,%xmm2 + movdqa 16(%rsp,%rax,1),%xmm3 + movdqa %xmm0,(%rsp,%rax,1) + por %xmm2,%xmm1 + movdqu 16(%rdi,%rax,1),%xmm2 + movdqu %xmm1,(%rdi,%rax,1) + pand %xmm4,%xmm3 + pand %xmm5,%xmm2 + movdqa %xmm0,16(%rsp,%rax,1) + por %xmm2,%xmm3 + movdqu %xmm3,16(%rdi,%rax,1) + leaq 32(%rax),%rax + decq %r15 + jnz .Lcopy4x + movq 8(%rsp,%r9,8),%rsi +.cfi_def_cfa %rsi, 8 + movq $1,%rax + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmul4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mul4x_mont,.-bn_mul4x_mont + + + +.type bn_sqr8x_mont,@function +.align 32 +bn_sqr8x_mont: +.cfi_startproc + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lsqr8x_enter: + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lsqr8x_prologue: + + movl %r9d,%r10d + shll $3,%r9d + shlq $3+2,%r10 + negq %r9 + + + + + + + leaq -64(%rsp,%r9,2),%r11 + movq %rsp,%rbp + movq (%r8),%r8 + subq %rsi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb .Lsqr8x_sp_alt + subq %r11,%rbp + leaq -64(%rbp,%r9,2),%rbp + jmp .Lsqr8x_sp_done + +.align 32 +.Lsqr8x_sp_alt: + leaq 4096-64(,%r9,2),%r10 + leaq -64(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +.Lsqr8x_sp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lsqr8x_page_walk + jmp .Lsqr8x_page_walk_done + +.align 16 +.Lsqr8x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lsqr8x_page_walk +.Lsqr8x_page_walk_done: + + movq %r9,%r10 + negq %r9 + + movq %r8,32(%rsp) + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 +.Lsqr8x_body: + +.byte 102,72,15,110,209 + pxor %xmm0,%xmm0 +.byte 102,72,15,110,207 +.byte 102,73,15,110,218 + movl OPENSSL_ia32cap_P+8(%rip),%eax + andl $0x80100,%eax + cmpl $0x80100,%eax + jne .Lsqr8x_nox + + call bn_sqrx8x_internal + + + + + leaq (%r8,%rcx,1),%rbx + movq %rcx,%r9 + movq %rcx,%rdx +.byte 102,72,15,126,207 + sarq $3+2,%rcx + jmp .Lsqr8x_sub + +.align 32 +.Lsqr8x_nox: + call bn_sqr8x_internal + + + + + leaq (%rdi,%r9,1),%rbx + movq %r9,%rcx + movq %r9,%rdx +.byte 102,72,15,126,207 + sarq $3+2,%rcx + jmp .Lsqr8x_sub + +.align 32 +.Lsqr8x_sub: + movq 0(%rbx),%r12 + movq 8(%rbx),%r13 + movq 16(%rbx),%r14 + movq 24(%rbx),%r15 + leaq 32(%rbx),%rbx + sbbq 0(%rbp),%r12 + sbbq 8(%rbp),%r13 + sbbq 16(%rbp),%r14 + sbbq 24(%rbp),%r15 + leaq 32(%rbp),%rbp + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r14,16(%rdi) + movq %r15,24(%rdi) + leaq 32(%rdi),%rdi + incq %rcx + jnz .Lsqr8x_sub + + sbbq $0,%rax + leaq (%rbx,%r9,1),%rbx + leaq (%rdi,%r9,1),%rdi + +.byte 102,72,15,110,200 + pxor %xmm0,%xmm0 + pshufd $0,%xmm1,%xmm1 + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + jmp .Lsqr8x_cond_copy + +.align 32 +.Lsqr8x_cond_copy: + movdqa 0(%rbx),%xmm2 + movdqa 16(%rbx),%xmm3 + leaq 32(%rbx),%rbx + movdqu 0(%rdi),%xmm4 + movdqu 16(%rdi),%xmm5 + leaq 32(%rdi),%rdi + movdqa %xmm0,-32(%rbx) + movdqa %xmm0,-16(%rbx) + movdqa %xmm0,-32(%rbx,%rdx,1) + movdqa %xmm0,-16(%rbx,%rdx,1) + pcmpeqd %xmm1,%xmm0 + pand %xmm1,%xmm2 + pand %xmm1,%xmm3 + pand %xmm0,%xmm4 + pand %xmm0,%xmm5 + pxor %xmm0,%xmm0 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqu %xmm4,-32(%rdi) + movdqu %xmm5,-16(%rdi) + addq $32,%r9 + jnz .Lsqr8x_cond_copy + + movq $1,%rax + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lsqr8x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_sqr8x_mont,.-bn_sqr8x_mont +.type bn_mulx4x_mont,@function +.align 32 +bn_mulx4x_mont: +.cfi_startproc + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lmulx4x_enter: + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lmulx4x_prologue: + + shll $3,%r9d + xorq %r10,%r10 + subq %r9,%r10 + movq (%r8),%r8 + leaq -72(%rsp,%r10,1),%rbp + andq $-128,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmulx4x_page_walk + jmp .Lmulx4x_page_walk_done + +.align 16 +.Lmulx4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmulx4x_page_walk +.Lmulx4x_page_walk_done: + + leaq (%rdx,%r9,1),%r10 + + + + + + + + + + + + + movq %r9,0(%rsp) + shrq $5,%r9 + movq %r10,16(%rsp) + subq $1,%r9 + movq %r8,24(%rsp) + movq %rdi,32(%rsp) + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 + movq %r9,48(%rsp) + jmp .Lmulx4x_body + +.align 32 +.Lmulx4x_body: + leaq 8(%rdx),%rdi + movq (%rdx),%rdx + leaq 64+32(%rsp),%rbx + movq %rdx,%r9 + + mulxq 0(%rsi),%r8,%rax + mulxq 8(%rsi),%r11,%r14 + addq %rax,%r11 + movq %rdi,8(%rsp) + mulxq 16(%rsi),%r12,%r13 + adcq %r14,%r12 + adcq $0,%r13 + + movq %r8,%rdi + imulq 24(%rsp),%r8 + xorq %rbp,%rbp + + mulxq 24(%rsi),%rax,%r14 + movq %r8,%rdx + leaq 32(%rsi),%rsi + adcxq %rax,%r13 + adcxq %rbp,%r14 + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%rdi + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 +.byte 0xc4,0x62,0xfb,0xf6,0xa1,0x10,0x00,0x00,0x00 + movq 48(%rsp),%rdi + movq %r10,-32(%rbx) + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-24(%rbx) + adcxq %rax,%r12 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r12,-16(%rbx) + + jmp .Lmulx4x_1st + +.align 32 +.Lmulx4x_1st: + adcxq %rbp,%r15 + mulxq 0(%rsi),%r10,%rax + adcxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 +.byte 0x67,0x67 + movq %r8,%rdx + adcxq %rax,%r13 + adcxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + movq %r11,-32(%rbx) + adoxq %r15,%r13 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r13,-16(%rbx) + + decq %rdi + jnz .Lmulx4x_1st + + movq 0(%rsp),%rax + movq 8(%rsp),%rdi + adcq %rbp,%r15 + addq %r15,%r14 + sbbq %r15,%r15 + movq %r14,-8(%rbx) + jmp .Lmulx4x_outer + +.align 32 +.Lmulx4x_outer: + movq (%rdi),%rdx + leaq 8(%rdi),%rdi + subq %rax,%rsi + movq %r15,(%rbx) + leaq 64+32(%rsp),%rbx + subq %rax,%rcx + + mulxq 0(%rsi),%r8,%r11 + xorl %ebp,%ebp + movq %rdx,%r9 + mulxq 8(%rsi),%r14,%r12 + adoxq -32(%rbx),%r8 + adcxq %r14,%r11 + mulxq 16(%rsi),%r15,%r13 + adoxq -24(%rbx),%r11 + adcxq %r15,%r12 + adoxq -16(%rbx),%r12 + adcxq %rbp,%r13 + adoxq %rbp,%r13 + + movq %rdi,8(%rsp) + movq %r8,%r15 + imulq 24(%rsp),%r8 + xorl %ebp,%ebp + + mulxq 24(%rsi),%rax,%r14 + movq %r8,%rdx + adcxq %rax,%r13 + adoxq -8(%rbx),%r13 + adcxq %rbp,%r14 + leaq 32(%rsi),%rsi + adoxq %rbp,%r14 + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%r15 + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + mulxq 16(%rcx),%rax,%r12 + movq %r10,-32(%rbx) + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-24(%rbx) + leaq 32(%rcx),%rcx + adcxq %rax,%r12 + adoxq %rbp,%r15 + movq 48(%rsp),%rdi + movq %r12,-16(%rbx) + + jmp .Lmulx4x_inner + +.align 32 +.Lmulx4x_inner: + mulxq 0(%rsi),%r10,%rax + adcxq %rbp,%r15 + adoxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq 0(%rbx),%r10 + adoxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq 8(%rbx),%r11 + adoxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 + movq %r8,%rdx + adcxq 16(%rbx),%r12 + adoxq %rax,%r13 + adcxq 24(%rbx),%r13 + adoxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + adcxq %rbp,%r14 + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + adoxq %r15,%r13 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-32(%rbx) + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r13,-16(%rbx) + + decq %rdi + jnz .Lmulx4x_inner + + movq 0(%rsp),%rax + movq 8(%rsp),%rdi + adcq %rbp,%r15 + subq 0(%rbx),%rbp + adcq %r15,%r14 + sbbq %r15,%r15 + movq %r14,-8(%rbx) + + cmpq 16(%rsp),%rdi + jne .Lmulx4x_outer + + leaq 64(%rsp),%rbx + subq %rax,%rcx + negq %r15 + movq %rax,%rdx + shrq $3+2,%rax + movq 32(%rsp),%rdi + jmp .Lmulx4x_sub + +.align 32 +.Lmulx4x_sub: + movq 0(%rbx),%r11 + movq 8(%rbx),%r12 + movq 16(%rbx),%r13 + movq 24(%rbx),%r14 + leaq 32(%rbx),%rbx + sbbq 0(%rcx),%r11 + sbbq 8(%rcx),%r12 + sbbq 16(%rcx),%r13 + sbbq 24(%rcx),%r14 + leaq 32(%rcx),%rcx + movq %r11,0(%rdi) + movq %r12,8(%rdi) + movq %r13,16(%rdi) + movq %r14,24(%rdi) + leaq 32(%rdi),%rdi + decq %rax + jnz .Lmulx4x_sub + + sbbq $0,%r15 + leaq 64(%rsp),%rbx + subq %rdx,%rdi + +.byte 102,73,15,110,207 + pxor %xmm0,%xmm0 + pshufd $0,%xmm1,%xmm1 + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + jmp .Lmulx4x_cond_copy + +.align 32 +.Lmulx4x_cond_copy: + movdqa 0(%rbx),%xmm2 + movdqa 16(%rbx),%xmm3 + leaq 32(%rbx),%rbx + movdqu 0(%rdi),%xmm4 + movdqu 16(%rdi),%xmm5 + leaq 32(%rdi),%rdi + movdqa %xmm0,-32(%rbx) + movdqa %xmm0,-16(%rbx) + pcmpeqd %xmm1,%xmm0 + pand %xmm1,%xmm2 + pand %xmm1,%xmm3 + pand %xmm0,%xmm4 + pand %xmm0,%xmm5 + pxor %xmm0,%xmm0 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqu %xmm4,-32(%rdi) + movdqu %xmm5,-16(%rdi) + subq $32,%rdx + jnz .Lmulx4x_cond_copy + + movq %rdx,(%rbx) + + movq $1,%rax + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmulx4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mulx4x_mont,.-bn_mulx4x_mont +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 16 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/bn/x86_64-mont5.S b/crypto/openssl/crypto/bn/x86_64-mont5.S new file mode 100644 index 000000000000..0eb8b6c8b5c7 --- /dev/null +++ b/crypto/openssl/crypto/bn/x86_64-mont5.S @@ -0,0 +1,3624 @@ +.text + + + +.globl bn_mul_mont_gather5 +.type bn_mul_mont_gather5,@function +.align 64 +bn_mul_mont_gather5: +.cfi_startproc + movl %r9d,%r9d + movq %rsp,%rax +.cfi_def_cfa_register %rax + testl $7,%r9d + jnz .Lmul_enter + movl OPENSSL_ia32cap_P+8(%rip),%r11d + jmp .Lmul4x_enter + +.align 16 +.Lmul_enter: + movd 8(%rsp),%xmm5 + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + negq %r9 + movq %rsp,%r11 + leaq -280(%rsp,%r9,8),%r10 + negq %r9 + andq $-1024,%r10 + + + + + + + + + + subq %r10,%r11 + andq $-4096,%r11 + leaq (%r10,%r11,1),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul_page_walk + jmp .Lmul_page_walk_done + +.Lmul_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r11 + cmpq %r10,%rsp + ja .Lmul_page_walk +.Lmul_page_walk_done: + + leaq .Linc(%rip),%r10 + movq %rax,8(%rsp,%r9,8) +.cfi_escape 0x0f,0x0a,0x77,0x08,0x79,0x00,0x38,0x1e,0x22,0x06,0x23,0x08 +.Lmul_body: + + leaq 128(%rdx),%r12 + movdqa 0(%r10),%xmm0 + movdqa 16(%r10),%xmm1 + leaq 24-112(%rsp,%r9,8),%r10 + andq $-16,%r10 + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 +.byte 0x67 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 +.byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + pand 64(%r12),%xmm0 + + pand 80(%r12),%xmm1 + pand 96(%r12),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%r12),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%r12),%xmm4 + movdqa -112(%r12),%xmm5 + movdqa -96(%r12),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%r12),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%r12),%xmm4 + movdqa -48(%r12),%xmm5 + movdqa -32(%r12),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%r12),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%r12),%xmm4 + movdqa 16(%r12),%xmm5 + movdqa 32(%r12),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%r12),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%r12),%r12 +.byte 102,72,15,126,195 + + movq (%r8),%r8 + movq (%rsi),%rax + + xorq %r14,%r14 + xorq %r15,%r15 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .L1st_enter + +.align 16 +.L1st: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r13 + movq %r10,%r11 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.L1st_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + leaq 1(%r15),%r15 + movq %rdx,%r10 + + mulq %rbp + cmpq %r9,%r15 + jne .L1st + + + addq %rax,%r13 + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-16(%rsp,%r9,8) + movq %rdx,%r13 + movq %r10,%r11 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + jmp .Louter +.align 16 +.Louter: + leaq 24+128(%rsp,%r9,8),%rdx + andq $-16,%rdx + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r12),%xmm0 + movdqa -112(%r12),%xmm1 + movdqa -96(%r12),%xmm2 + movdqa -80(%r12),%xmm3 + pand -128(%rdx),%xmm0 + pand -112(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -80(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r12),%xmm0 + movdqa -48(%r12),%xmm1 + movdqa -32(%r12),%xmm2 + movdqa -16(%r12),%xmm3 + pand -64(%rdx),%xmm0 + pand -48(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -16(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r12),%xmm0 + movdqa 16(%r12),%xmm1 + movdqa 32(%r12),%xmm2 + movdqa 48(%r12),%xmm3 + pand 0(%rdx),%xmm0 + pand 16(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 48(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r12),%xmm0 + movdqa 80(%r12),%xmm1 + movdqa 96(%r12),%xmm2 + movdqa 112(%r12),%xmm3 + pand 64(%rdx),%xmm0 + pand 80(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 112(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%r12),%r12 + + movq (%rsi),%rax +.byte 102,72,15,126,195 + + xorq %r15,%r15 + movq %r8,%rbp + movq (%rsp),%r10 + + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi),%rax + adcq $0,%rdx + movq 8(%rsp),%r10 + movq %rdx,%r13 + + leaq 1(%r15),%r15 + jmp .Linner_enter + +.align 16 +.Linner: + addq %rax,%r13 + movq (%rsi,%r15,8),%rax + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r15,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r15,8) + movq %rdx,%r13 + +.Linner_enter: + mulq %rbx + addq %rax,%r11 + movq (%rcx,%r15,8),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + leaq 1(%r15),%r15 + + mulq %rbp + cmpq %r9,%r15 + jne .Linner + + addq %rax,%r13 + adcq $0,%rdx + addq %r10,%r13 + movq (%rsp,%r9,8),%r10 + adcq $0,%rdx + movq %r13,-16(%rsp,%r9,8) + movq %rdx,%r13 + + xorq %rdx,%rdx + addq %r11,%r13 + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%rsp,%r9,8) + movq %rdx,(%rsp,%r9,8) + + leaq 1(%r14),%r14 + cmpq %r9,%r14 + jb .Louter + + xorq %r14,%r14 + movq (%rsp),%rax + leaq (%rsp),%rsi + movq %r9,%r15 + jmp .Lsub +.align 16 +.Lsub: sbbq (%rcx,%r14,8),%rax + movq %rax,(%rdi,%r14,8) + movq 8(%rsi,%r14,8),%rax + leaq 1(%r14),%r14 + decq %r15 + jnz .Lsub + + sbbq $0,%rax + movq $-1,%rbx + xorq %rax,%rbx + xorq %r14,%r14 + movq %r9,%r15 + +.Lcopy: + movq (%rdi,%r14,8),%rcx + movq (%rsp,%r14,8),%rdx + andq %rbx,%rcx + andq %rax,%rdx + movq %r14,(%rsp,%r14,8) + orq %rcx,%rdx + movq %rdx,(%rdi,%r14,8) + leaq 1(%r14),%r14 + subq $1,%r15 + jnz .Lcopy + + movq 8(%rsp,%r9,8),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmul_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mul_mont_gather5,.-bn_mul_mont_gather5 +.type bn_mul4x_mont_gather5,@function +.align 32 +bn_mul4x_mont_gather5: +.cfi_startproc +.byte 0x67 + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lmul4x_enter: + andl $0x80108,%r11d + cmpl $0x80108,%r11d + je .Lmulx4x_enter + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lmul4x_prologue: + +.byte 0x67 + shll $3,%r9d + leaq (%r9,%r9,2),%r10 + negq %r9 + + + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb .Lmul4xsp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp .Lmul4xsp_done + +.align 32 +.Lmul4xsp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +.Lmul4xsp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmul4x_page_walk + jmp .Lmul4x_page_walk_done + +.Lmul4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmul4x_page_walk +.Lmul4x_page_walk_done: + + negq %r9 + + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 +.Lmul4x_body: + + call mul4x_internal + + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmul4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mul4x_mont_gather5,.-bn_mul4x_mont_gather5 + +.type mul4x_internal,@function +.align 32 +mul4x_internal: +.cfi_startproc + shlq $5,%r9 + movd 8(%rax),%xmm5 + leaq .Linc(%rip),%rax + leaq 128(%rdx,%r9,1),%r13 + shrq $5,%r9 + movdqa 0(%rax),%xmm0 + movdqa 16(%rax),%xmm1 + leaq 88-112(%rsp,%r9,1),%r10 + leaq 128(%rdx),%r12 + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 +.byte 0x67,0x67 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 +.byte 0x67 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 +.byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + pand 64(%r12),%xmm0 + + pand 80(%r12),%xmm1 + pand 96(%r12),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%r12),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%r12),%xmm4 + movdqa -112(%r12),%xmm5 + movdqa -96(%r12),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%r12),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%r12),%xmm4 + movdqa -48(%r12),%xmm5 + movdqa -32(%r12),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%r12),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%r12),%xmm4 + movdqa 16(%r12),%xmm5 + movdqa 32(%r12),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%r12),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%r12),%r12 +.byte 102,72,15,126,195 + + movq %r13,16+8(%rsp) + movq %rdi,56+8(%rsp) + + movq (%r8),%r8 + movq (%rsi),%rax + leaq (%rsi,%r9,1),%rsi + negq %r9 + + movq %r8,%rbp + mulq %rbx + movq %rax,%r10 + movq (%rcx),%rax + + imulq %r10,%rbp + leaq 64+8(%rsp),%r14 + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi,%r9,1),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%r9),%r15 + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %rdi,(%r14) + movq %rdx,%r13 + jmp .L1st4x + +.align 32 +.L1st4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%r14) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq 0(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-8(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %rdi,(%r14) + movq %rdx,%r13 + + addq $32,%r15 + jnz .L1st4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx),%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %rdi,-16(%r14) + movq %rdx,%r13 + + leaq (%rcx,%r9,1),%rcx + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + movq %r13,-8(%r14) + + jmp .Louter4x + +.align 32 +.Louter4x: + leaq 16+128(%r14),%rdx + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r12),%xmm0 + movdqa -112(%r12),%xmm1 + movdqa -96(%r12),%xmm2 + movdqa -80(%r12),%xmm3 + pand -128(%rdx),%xmm0 + pand -112(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -80(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r12),%xmm0 + movdqa -48(%r12),%xmm1 + movdqa -32(%r12),%xmm2 + movdqa -16(%r12),%xmm3 + pand -64(%rdx),%xmm0 + pand -48(%rdx),%xmm1 + por %xmm0,%xmm4 + pand -32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand -16(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r12),%xmm0 + movdqa 16(%r12),%xmm1 + movdqa 32(%r12),%xmm2 + movdqa 48(%r12),%xmm3 + pand 0(%rdx),%xmm0 + pand 16(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 32(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 48(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r12),%xmm0 + movdqa 80(%r12),%xmm1 + movdqa 96(%r12),%xmm2 + movdqa 112(%r12),%xmm3 + pand 64(%rdx),%xmm0 + pand 80(%rdx),%xmm1 + por %xmm0,%xmm4 + pand 96(%rdx),%xmm2 + por %xmm1,%xmm5 + pand 112(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%r12),%r12 +.byte 102,72,15,126,195 + + movq (%r14,%r9,1),%r10 + movq %r8,%rbp + mulq %rbx + addq %rax,%r10 + movq (%rcx),%rax + adcq $0,%rdx + + imulq %r10,%rbp + movq %rdx,%r11 + movq %rdi,(%r14) + + leaq (%r14,%r9,1),%r14 + + mulq %rbp + addq %rax,%r10 + movq 8(%rsi,%r9,1),%rax + adcq $0,%rdx + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%r9),%r15 + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %rdx,%r13 + jmp .Linner4x + +.align 32 +.Linner4x: + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + adcq $0,%rdx + addq 16(%r14),%r10 + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-32(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq -8(%rcx),%rax + adcq $0,%rdx + addq -8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%r13 + + mulq %rbx + addq %rax,%r10 + movq 0(%rcx),%rax + adcq $0,%rdx + addq (%r14),%r10 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq 8(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-16(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq 8(%rcx),%rax + adcq $0,%rdx + addq 8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq 16(%rsi,%r15,1),%rax + adcq $0,%rdx + addq %r11,%rdi + leaq 32(%rcx),%rcx + adcq $0,%rdx + movq %r13,-8(%r14) + movq %rdx,%r13 + + addq $32,%r15 + jnz .Linner4x + + mulq %rbx + addq %rax,%r10 + movq -16(%rcx),%rax + adcq $0,%rdx + addq 16(%r14),%r10 + leaq 32(%r14),%r14 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %rbp + addq %rax,%r13 + movq -8(%rsi),%rax + adcq $0,%rdx + addq %r10,%r13 + adcq $0,%rdx + movq %rdi,-32(%r14) + movq %rdx,%rdi + + mulq %rbx + addq %rax,%r11 + movq %rbp,%rax + movq -8(%rcx),%rbp + adcq $0,%rdx + addq -8(%r14),%r11 + adcq $0,%rdx + movq %rdx,%r10 + + mulq %rbp + addq %rax,%rdi + movq (%rsi,%r9,1),%rax + adcq $0,%rdx + addq %r11,%rdi + adcq $0,%rdx + movq %r13,-24(%r14) + movq %rdx,%r13 + + movq %rdi,-16(%r14) + leaq (%rcx,%r9,1),%rcx + + xorq %rdi,%rdi + addq %r10,%r13 + adcq $0,%rdi + addq (%r14),%r13 + adcq $0,%rdi + movq %r13,-8(%r14) + + cmpq 16+8(%rsp),%r12 + jb .Louter4x + xorq %rax,%rax + subq %r13,%rbp + adcq %r15,%r15 + orq %r15,%rdi + subq %rdi,%rax + leaq (%r14,%r9,1),%rbx + movq (%rcx),%r12 + leaq (%rcx),%rbp + movq %r9,%rcx + sarq $3+2,%rcx + movq 56+8(%rsp),%rdi + decq %r12 + xorq %r10,%r10 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp .Lsqr4x_sub_entry +.cfi_endproc +.size mul4x_internal,.-mul4x_internal +.globl bn_power5 +.type bn_power5,@function +.align 32 +bn_power5: +.cfi_startproc + movq %rsp,%rax +.cfi_def_cfa_register %rax + movl OPENSSL_ia32cap_P+8(%rip),%r11d + andl $0x80108,%r11d + cmpl $0x80108,%r11d + je .Lpowerx5_enter + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lpower5_prologue: + + shll $3,%r9d + leal (%r9,%r9,2),%r10d + negq %r9 + movq (%r8),%r8 + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb .Lpwr_sp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp .Lpwr_sp_done + +.align 32 +.Lpwr_sp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +.Lpwr_sp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lpwr_page_walk + jmp .Lpwr_page_walk_done + +.Lpwr_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lpwr_page_walk +.Lpwr_page_walk_done: + + movq %r9,%r10 + negq %r9 + + + + + + + + + + + movq %r8,32(%rsp) + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 +.Lpower5_body: +.byte 102,72,15,110,207 +.byte 102,72,15,110,209 +.byte 102,73,15,110,218 +.byte 102,72,15,110,226 + + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + call __bn_sqr8x_internal + call __bn_post4x_internal + +.byte 102,72,15,126,209 +.byte 102,72,15,126,226 + movq %rsi,%rdi + movq 40(%rsp),%rax + leaq 32(%rsp),%r8 + + call mul4x_internal + + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpower5_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_power5,.-bn_power5 + +.globl bn_sqr8x_internal +.hidden bn_sqr8x_internal +.type bn_sqr8x_internal,@function +.align 32 +bn_sqr8x_internal: +__bn_sqr8x_internal: +.cfi_startproc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + leaq 32(%r10),%rbp + leaq (%rsi,%r9,1),%rsi + + movq %r9,%rcx + + + movq -32(%rsi,%rbp,1),%r14 + leaq 48+8(%rsp,%r9,2),%rdi + movq -24(%rsi,%rbp,1),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi,%rbp,1),%rbx + movq %rax,%r15 + + mulq %r14 + movq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + movq %r10,-24(%rdi,%rbp,1) + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq $0,%rdx + movq %r11,-16(%rdi,%rbp,1) + movq %rdx,%r10 + + + movq -8(%rsi,%rbp,1),%rbx + mulq %r15 + movq %rax,%r12 + movq %rbx,%rax + movq %rdx,%r13 + + leaq (%rbp),%rcx + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + movq %r10,-8(%rdi,%rcx,1) + jmp .Lsqr4x_1st + +.align 32 +.Lsqr4x_1st: + movq (%rsi,%rcx,1),%rbx + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + movq %rdx,%r12 + adcq $0,%r12 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq 8(%rsi,%rcx,1),%rbx + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + adcq $0,%r10 + + + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + movq %r11,(%rdi,%rcx,1) + movq %rdx,%r13 + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq 16(%rsi,%rcx,1),%rbx + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + movq %r10,8(%rdi,%rcx,1) + movq %rdx,%r12 + adcq $0,%r12 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq 24(%rsi,%rcx,1),%rbx + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + adcq $0,%r10 + + + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + movq %r11,16(%rdi,%rcx,1) + movq %rdx,%r13 + adcq $0,%r13 + leaq 32(%rcx),%rcx + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + movq %r10,-8(%rdi,%rcx,1) + + cmpq $0,%rcx + jne .Lsqr4x_1st + + mulq %r15 + addq %rax,%r13 + leaq 16(%rbp),%rbp + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + + movq %r13,(%rdi) + movq %rdx,%r12 + movq %rdx,8(%rdi) + jmp .Lsqr4x_outer + +.align 32 +.Lsqr4x_outer: + movq -32(%rsi,%rbp,1),%r14 + leaq 48+8(%rsp,%r9,2),%rdi + movq -24(%rsi,%rbp,1),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi,%rbp,1),%rbx + movq %rax,%r15 + + mulq %r14 + movq -24(%rdi,%rbp,1),%r10 + addq %rax,%r10 + movq %rbx,%rax + adcq $0,%rdx + movq %r10,-24(%rdi,%rbp,1) + movq %rdx,%r11 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + adcq $0,%rdx + addq -16(%rdi,%rbp,1),%r11 + movq %rdx,%r10 + adcq $0,%r10 + movq %r11,-16(%rdi,%rbp,1) + + xorq %r12,%r12 + + movq -8(%rsi,%rbp,1),%rbx + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + adcq $0,%rdx + addq -8(%rdi,%rbp,1),%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq $0,%rdx + addq %r12,%r10 + movq %rdx,%r11 + adcq $0,%r11 + movq %r10,-8(%rdi,%rbp,1) + + leaq (%rbp),%rcx + jmp .Lsqr4x_inner + +.align 32 +.Lsqr4x_inner: + movq (%rsi,%rcx,1),%rbx + mulq %r15 + addq %rax,%r13 + movq %rbx,%rax + movq %rdx,%r12 + adcq $0,%r12 + addq (%rdi,%rcx,1),%r13 + adcq $0,%r12 + +.byte 0x67 + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq 8(%rsi,%rcx,1),%rbx + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + adcq $0,%r10 + + mulq %r15 + addq %rax,%r12 + movq %r11,(%rdi,%rcx,1) + movq %rbx,%rax + movq %rdx,%r13 + adcq $0,%r13 + addq 8(%rdi,%rcx,1),%r12 + leaq 16(%rcx),%rcx + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + adcq $0,%rdx + addq %r12,%r10 + movq %rdx,%r11 + adcq $0,%r11 + movq %r10,-8(%rdi,%rcx,1) + + cmpq $0,%rcx + jne .Lsqr4x_inner + +.byte 0x67 + mulq %r15 + addq %rax,%r13 + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + + movq %r13,(%rdi) + movq %rdx,%r12 + movq %rdx,8(%rdi) + + addq $16,%rbp + jnz .Lsqr4x_outer + + + movq -32(%rsi),%r14 + leaq 48+8(%rsp,%r9,2),%rdi + movq -24(%rsi),%rax + leaq -32(%rdi,%rbp,1),%rdi + movq -16(%rsi),%rbx + movq %rax,%r15 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + + mulq %r14 + addq %rax,%r11 + movq %rbx,%rax + movq %r10,-24(%rdi) + movq %rdx,%r10 + adcq $0,%r10 + addq %r13,%r11 + movq -8(%rsi),%rbx + adcq $0,%r10 + + mulq %r15 + addq %rax,%r12 + movq %rbx,%rax + movq %r11,-16(%rdi) + movq %rdx,%r13 + adcq $0,%r13 + + mulq %r14 + addq %rax,%r10 + movq %rbx,%rax + movq %rdx,%r11 + adcq $0,%r11 + addq %r12,%r10 + adcq $0,%r11 + movq %r10,-8(%rdi) + + mulq %r15 + addq %rax,%r13 + movq -16(%rsi),%rax + adcq $0,%rdx + addq %r11,%r13 + adcq $0,%rdx + + movq %r13,(%rdi) + movq %rdx,%r12 + movq %rdx,8(%rdi) + + mulq %rbx + addq $16,%rbp + xorq %r14,%r14 + subq %r9,%rbp + xorq %r15,%r15 + + addq %r12,%rax + adcq $0,%rdx + movq %rax,8(%rdi) + movq %rdx,16(%rdi) + movq %r15,24(%rdi) + + movq -16(%rsi,%rbp,1),%rax + leaq 48+8(%rsp),%rdi + xorq %r10,%r10 + movq 8(%rdi),%r11 + + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq 16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 24(%rdi),%r11 + adcq %rax,%r12 + movq -8(%rsi,%rbp,1),%rax + movq %r12,(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,8(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 32(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 40(%rdi),%r11 + adcq %rax,%rbx + movq 0(%rsi,%rbp,1),%rax + movq %rbx,16(%rdi) + adcq %rdx,%r8 + leaq 16(%rbp),%rbp + movq %r8,24(%rdi) + sbbq %r15,%r15 + leaq 64(%rdi),%rdi + jmp .Lsqr4x_shift_n_add + +.align 32 +.Lsqr4x_shift_n_add: + leaq (%r14,%r10,2),%r12 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi),%r11 + adcq %rax,%r12 + movq -8(%rsi,%rbp,1),%rax + movq %r12,-32(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 0(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 8(%rdi),%r11 + adcq %rax,%rbx + movq 0(%rsi,%rbp,1),%rax + movq %rbx,-16(%rdi) + adcq %rdx,%r8 + + leaq (%r14,%r10,2),%r12 + movq %r8,-8(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq 16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 24(%rdi),%r11 + adcq %rax,%r12 + movq 8(%rsi,%rbp,1),%rax + movq %r12,0(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,8(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + movq 32(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq 40(%rdi),%r11 + adcq %rax,%rbx + movq 16(%rsi,%rbp,1),%rax + movq %rbx,16(%rdi) + adcq %rdx,%r8 + movq %r8,24(%rdi) + sbbq %r15,%r15 + leaq 64(%rdi),%rdi + addq $32,%rbp + jnz .Lsqr4x_shift_n_add + + leaq (%r14,%r10,2),%r12 +.byte 0x67 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r13 + shrq $63,%r11 + orq %r10,%r13 + movq -16(%rdi),%r10 + movq %r11,%r14 + mulq %rax + negq %r15 + movq -8(%rdi),%r11 + adcq %rax,%r12 + movq -8(%rsi),%rax + movq %r12,-32(%rdi) + adcq %rdx,%r13 + + leaq (%r14,%r10,2),%rbx + movq %r13,-24(%rdi) + sbbq %r15,%r15 + shrq $63,%r10 + leaq (%rcx,%r11,2),%r8 + shrq $63,%r11 + orq %r10,%r8 + mulq %rax + negq %r15 + adcq %rax,%rbx + adcq %rdx,%r8 + movq %rbx,-16(%rdi) + movq %r8,-8(%rdi) +.byte 102,72,15,126,213 +__bn_sqr8x_reduction: + xorq %rax,%rax + leaq (%r9,%rbp,1),%rcx + leaq 48+8(%rsp,%r9,2),%rdx + movq %rcx,0+8(%rsp) + leaq 48+8(%rsp,%r9,1),%rdi + movq %rdx,8+8(%rsp) + negq %r9 + jmp .L8x_reduction_loop + +.align 32 +.L8x_reduction_loop: + leaq (%rdi,%r9,1),%rdi +.byte 0x66 + movq 0(%rdi),%rbx + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + movq 32(%rdi),%r12 + movq 40(%rdi),%r13 + movq 48(%rdi),%r14 + movq 56(%rdi),%r15 + movq %rax,(%rdx) + leaq 64(%rdi),%rdi + +.byte 0x67 + movq %rbx,%r8 + imulq 32+8(%rsp),%rbx + movq 0(%rbp),%rax + movl $8,%ecx + jmp .L8x_reduce + +.align 32 +.L8x_reduce: + mulq %rbx + movq 8(%rbp),%rax + negq %r8 + movq %rdx,%r8 + adcq $0,%r8 + + mulq %rbx + addq %rax,%r9 + movq 16(%rbp),%rax + adcq $0,%rdx + addq %r9,%r8 + movq %rbx,48-8+8(%rsp,%rcx,8) + movq %rdx,%r9 + adcq $0,%r9 + + mulq %rbx + addq %rax,%r10 + movq 24(%rbp),%rax + adcq $0,%rdx + addq %r10,%r9 + movq 32+8(%rsp),%rsi + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r11 + movq 32(%rbp),%rax + adcq $0,%rdx + imulq %r8,%rsi + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + + mulq %rbx + addq %rax,%r12 + movq 40(%rbp),%rax + adcq $0,%rdx + addq %r12,%r11 + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r13 + movq 48(%rbp),%rax + adcq $0,%rdx + addq %r13,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r14 + movq 56(%rbp),%rax + adcq $0,%rdx + addq %r14,%r13 + movq %rdx,%r14 + adcq $0,%r14 + + mulq %rbx + movq %rsi,%rbx + addq %rax,%r15 + movq 0(%rbp),%rax + adcq $0,%rdx + addq %r15,%r14 + movq %rdx,%r15 + adcq $0,%r15 + + decl %ecx + jnz .L8x_reduce + + leaq 64(%rbp),%rbp + xorq %rax,%rax + movq 8+8(%rsp),%rdx + cmpq 0+8(%rsp),%rbp + jae .L8x_no_tail + +.byte 0x66 + addq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + sbbq %rsi,%rsi + + movq 48+56+8(%rsp),%rbx + movl $8,%ecx + movq 0(%rbp),%rax + jmp .L8x_tail + +.align 32 +.L8x_tail: + mulq %rbx + addq %rax,%r8 + movq 8(%rbp),%rax + movq %r8,(%rdi) + movq %rdx,%r8 + adcq $0,%r8 + + mulq %rbx + addq %rax,%r9 + movq 16(%rbp),%rax + adcq $0,%rdx + addq %r9,%r8 + leaq 8(%rdi),%rdi + movq %rdx,%r9 + adcq $0,%r9 + + mulq %rbx + addq %rax,%r10 + movq 24(%rbp),%rax + adcq $0,%rdx + addq %r10,%r9 + movq %rdx,%r10 + adcq $0,%r10 + + mulq %rbx + addq %rax,%r11 + movq 32(%rbp),%rax + adcq $0,%rdx + addq %r11,%r10 + movq %rdx,%r11 + adcq $0,%r11 + + mulq %rbx + addq %rax,%r12 + movq 40(%rbp),%rax + adcq $0,%rdx + addq %r12,%r11 + movq %rdx,%r12 + adcq $0,%r12 + + mulq %rbx + addq %rax,%r13 + movq 48(%rbp),%rax + adcq $0,%rdx + addq %r13,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + mulq %rbx + addq %rax,%r14 + movq 56(%rbp),%rax + adcq $0,%rdx + addq %r14,%r13 + movq %rdx,%r14 + adcq $0,%r14 + + mulq %rbx + movq 48-16+8(%rsp,%rcx,8),%rbx + addq %rax,%r15 + adcq $0,%rdx + addq %r15,%r14 + movq 0(%rbp),%rax + movq %rdx,%r15 + adcq $0,%r15 + + decl %ecx + jnz .L8x_tail + + leaq 64(%rbp),%rbp + movq 8+8(%rsp),%rdx + cmpq 0+8(%rsp),%rbp + jae .L8x_tail_done + + movq 48+56+8(%rsp),%rbx + negq %rsi + movq 0(%rbp),%rax + adcq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + sbbq %rsi,%rsi + + movl $8,%ecx + jmp .L8x_tail + +.align 32 +.L8x_tail_done: + xorq %rax,%rax + addq (%rdx),%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + adcq $0,%rax + + negq %rsi +.L8x_no_tail: + adcq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + adcq $0,%rax + movq -8(%rbp),%rcx + xorq %rsi,%rsi + +.byte 102,72,15,126,213 + + movq %r8,0(%rdi) + movq %r9,8(%rdi) +.byte 102,73,15,126,217 + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + leaq 64(%rdi),%rdi + + cmpq %rdx,%rdi + jb .L8x_reduction_loop + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_sqr8x_internal,.-bn_sqr8x_internal +.type __bn_post4x_internal,@function +.align 32 +__bn_post4x_internal: +.cfi_startproc + movq 0(%rbp),%r12 + leaq (%rdi,%r9,1),%rbx + movq %r9,%rcx +.byte 102,72,15,126,207 + negq %rax +.byte 102,72,15,126,206 + sarq $3+2,%rcx + decq %r12 + xorq %r10,%r10 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp .Lsqr4x_sub_entry + +.align 16 +.Lsqr4x_sub: + movq 0(%rbp),%r12 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 +.Lsqr4x_sub_entry: + leaq 32(%rbp),%rbp + notq %r12 + notq %r13 + notq %r14 + notq %r15 + andq %rax,%r12 + andq %rax,%r13 + andq %rax,%r14 + andq %rax,%r15 + + negq %r10 + adcq 0(%rbx),%r12 + adcq 8(%rbx),%r13 + adcq 16(%rbx),%r14 + adcq 24(%rbx),%r15 + movq %r12,0(%rdi) + leaq 32(%rbx),%rbx + movq %r13,8(%rdi) + sbbq %r10,%r10 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + leaq 32(%rdi),%rdi + + incq %rcx + jnz .Lsqr4x_sub + + movq %r9,%r10 + negq %r9 + .byte 0xf3,0xc3 +.cfi_endproc +.size __bn_post4x_internal,.-__bn_post4x_internal +.type bn_mulx4x_mont_gather5,@function +.align 32 +bn_mulx4x_mont_gather5: +.cfi_startproc + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lmulx4x_enter: + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lmulx4x_prologue: + + shll $3,%r9d + leaq (%r9,%r9,2),%r10 + negq %r9 + movq (%r8),%r8 + + + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb .Lmulx4xsp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp .Lmulx4xsp_done + +.Lmulx4xsp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +.Lmulx4xsp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmulx4x_page_walk + jmp .Lmulx4x_page_walk_done + +.Lmulx4x_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lmulx4x_page_walk +.Lmulx4x_page_walk_done: + + + + + + + + + + + + + + movq %r8,32(%rsp) + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 +.Lmulx4x_body: + call mulx4x_internal + + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lmulx4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_mulx4x_mont_gather5,.-bn_mulx4x_mont_gather5 + +.type mulx4x_internal,@function +.align 32 +mulx4x_internal: +.cfi_startproc + movq %r9,8(%rsp) + movq %r9,%r10 + negq %r9 + shlq $5,%r9 + negq %r10 + leaq 128(%rdx,%r9,1),%r13 + shrq $5+5,%r9 + movd 8(%rax),%xmm5 + subq $1,%r9 + leaq .Linc(%rip),%rax + movq %r13,16+8(%rsp) + movq %r9,24+8(%rsp) + movq %rdi,56+8(%rsp) + movdqa 0(%rax),%xmm0 + movdqa 16(%rax),%xmm1 + leaq 88-112(%rsp,%r10,1),%r10 + leaq 128(%rdx),%rdi + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 +.byte 0x67 + movdqa %xmm1,%xmm2 +.byte 0x67 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,112(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,128(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,144(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,160(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,176(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,192(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,208(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,224(%r10) + movdqa %xmm4,%xmm3 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,240(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,256(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,272(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,288(%r10) + movdqa %xmm4,%xmm3 +.byte 0x67 + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,304(%r10) + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,320(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,336(%r10) + + pand 64(%rdi),%xmm0 + pand 80(%rdi),%xmm1 + pand 96(%rdi),%xmm2 + movdqa %xmm3,352(%r10) + pand 112(%rdi),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -128(%rdi),%xmm4 + movdqa -112(%rdi),%xmm5 + movdqa -96(%rdi),%xmm2 + pand 112(%r10),%xmm4 + movdqa -80(%rdi),%xmm3 + pand 128(%r10),%xmm5 + por %xmm4,%xmm0 + pand 144(%r10),%xmm2 + por %xmm5,%xmm1 + pand 160(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa -64(%rdi),%xmm4 + movdqa -48(%rdi),%xmm5 + movdqa -32(%rdi),%xmm2 + pand 176(%r10),%xmm4 + movdqa -16(%rdi),%xmm3 + pand 192(%r10),%xmm5 + por %xmm4,%xmm0 + pand 208(%r10),%xmm2 + por %xmm5,%xmm1 + pand 224(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + movdqa 0(%rdi),%xmm4 + movdqa 16(%rdi),%xmm5 + movdqa 32(%rdi),%xmm2 + pand 240(%r10),%xmm4 + movdqa 48(%rdi),%xmm3 + pand 256(%r10),%xmm5 + por %xmm4,%xmm0 + pand 272(%r10),%xmm2 + por %xmm5,%xmm1 + pand 288(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 + pxor %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 + por %xmm1,%xmm0 + leaq 256(%rdi),%rdi +.byte 102,72,15,126,194 + leaq 64+32+8(%rsp),%rbx + + movq %rdx,%r9 + mulxq 0(%rsi),%r8,%rax + mulxq 8(%rsi),%r11,%r12 + addq %rax,%r11 + mulxq 16(%rsi),%rax,%r13 + adcq %rax,%r12 + adcq $0,%r13 + mulxq 24(%rsi),%rax,%r14 + + movq %r8,%r15 + imulq 32+8(%rsp),%r8 + xorq %rbp,%rbp + movq %r8,%rdx + + movq %rdi,8+8(%rsp) + + leaq 32(%rsi),%rsi + adcxq %rax,%r13 + adcxq %rbp,%r14 + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%r15 + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + mulxq 16(%rcx),%rax,%r12 + movq 24+8(%rsp),%rdi + movq %r10,-32(%rbx) + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r11,-24(%rbx) + adcxq %rax,%r12 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r12,-16(%rbx) + jmp .Lmulx4x_1st + +.align 32 +.Lmulx4x_1st: + adcxq %rbp,%r15 + mulxq 0(%rsi),%r10,%rax + adcxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 +.byte 0x67,0x67 + movq %r8,%rdx + adcxq %rax,%r13 + adcxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + movq %r11,-32(%rbx) + adoxq %r15,%r13 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + leaq 32(%rcx),%rcx + movq %r13,-16(%rbx) + + decq %rdi + jnz .Lmulx4x_1st + + movq 8(%rsp),%rax + adcq %rbp,%r15 + leaq (%rsi,%rax,1),%rsi + addq %r15,%r14 + movq 8+8(%rsp),%rdi + adcq %rbp,%rbp + movq %r14,-8(%rbx) + jmp .Lmulx4x_outer + +.align 32 +.Lmulx4x_outer: + leaq 16-256(%rbx),%r10 + pxor %xmm4,%xmm4 +.byte 0x67,0x67 + pxor %xmm5,%xmm5 + movdqa -128(%rdi),%xmm0 + movdqa -112(%rdi),%xmm1 + movdqa -96(%rdi),%xmm2 + pand 256(%r10),%xmm0 + movdqa -80(%rdi),%xmm3 + pand 272(%r10),%xmm1 + por %xmm0,%xmm4 + pand 288(%r10),%xmm2 + por %xmm1,%xmm5 + pand 304(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%rdi),%xmm0 + movdqa -48(%rdi),%xmm1 + movdqa -32(%rdi),%xmm2 + pand 320(%r10),%xmm0 + movdqa -16(%rdi),%xmm3 + pand 336(%r10),%xmm1 + por %xmm0,%xmm4 + pand 352(%r10),%xmm2 + por %xmm1,%xmm5 + pand 368(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%rdi),%xmm0 + movdqa 16(%rdi),%xmm1 + movdqa 32(%rdi),%xmm2 + pand 384(%r10),%xmm0 + movdqa 48(%rdi),%xmm3 + pand 400(%r10),%xmm1 + por %xmm0,%xmm4 + pand 416(%r10),%xmm2 + por %xmm1,%xmm5 + pand 432(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%rdi),%xmm0 + movdqa 80(%rdi),%xmm1 + movdqa 96(%rdi),%xmm2 + pand 448(%r10),%xmm0 + movdqa 112(%rdi),%xmm3 + pand 464(%r10),%xmm1 + por %xmm0,%xmm4 + pand 480(%r10),%xmm2 + por %xmm1,%xmm5 + pand 496(%r10),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + leaq 256(%rdi),%rdi +.byte 102,72,15,126,194 + + movq %rbp,(%rbx) + leaq 32(%rbx,%rax,1),%rbx + mulxq 0(%rsi),%r8,%r11 + xorq %rbp,%rbp + movq %rdx,%r9 + mulxq 8(%rsi),%r14,%r12 + adoxq -32(%rbx),%r8 + adcxq %r14,%r11 + mulxq 16(%rsi),%r15,%r13 + adoxq -24(%rbx),%r11 + adcxq %r15,%r12 + mulxq 24(%rsi),%rdx,%r14 + adoxq -16(%rbx),%r12 + adcxq %rdx,%r13 + leaq (%rcx,%rax,1),%rcx + leaq 32(%rsi),%rsi + adoxq -8(%rbx),%r13 + adcxq %rbp,%r14 + adoxq %rbp,%r14 + + movq %r8,%r15 + imulq 32+8(%rsp),%r8 + + movq %r8,%rdx + xorq %rbp,%rbp + movq %rdi,8+8(%rsp) + + mulxq 0(%rcx),%rax,%r10 + adcxq %rax,%r15 + adoxq %r11,%r10 + mulxq 8(%rcx),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + mulxq 16(%rcx),%rax,%r12 + adcxq %rax,%r11 + adoxq %r13,%r12 + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + movq 24+8(%rsp),%rdi + movq %r10,-32(%rbx) + adcxq %rax,%r12 + movq %r11,-24(%rbx) + adoxq %rbp,%r15 + movq %r12,-16(%rbx) + leaq 32(%rcx),%rcx + jmp .Lmulx4x_inner + +.align 32 +.Lmulx4x_inner: + mulxq 0(%rsi),%r10,%rax + adcxq %rbp,%r15 + adoxq %r14,%r10 + mulxq 8(%rsi),%r11,%r14 + adcxq 0(%rbx),%r10 + adoxq %rax,%r11 + mulxq 16(%rsi),%r12,%rax + adcxq 8(%rbx),%r11 + adoxq %r14,%r12 + mulxq 24(%rsi),%r13,%r14 + movq %r8,%rdx + adcxq 16(%rbx),%r12 + adoxq %rax,%r13 + adcxq 24(%rbx),%r13 + adoxq %rbp,%r14 + leaq 32(%rsi),%rsi + leaq 32(%rbx),%rbx + adcxq %rbp,%r14 + + adoxq %r15,%r10 + mulxq 0(%rcx),%rax,%r15 + adcxq %rax,%r10 + adoxq %r15,%r11 + mulxq 8(%rcx),%rax,%r15 + adcxq %rax,%r11 + adoxq %r15,%r12 + mulxq 16(%rcx),%rax,%r15 + movq %r10,-40(%rbx) + adcxq %rax,%r12 + adoxq %r15,%r13 + movq %r11,-32(%rbx) + mulxq 24(%rcx),%rax,%r15 + movq %r9,%rdx + leaq 32(%rcx),%rcx + movq %r12,-24(%rbx) + adcxq %rax,%r13 + adoxq %rbp,%r15 + movq %r13,-16(%rbx) + + decq %rdi + jnz .Lmulx4x_inner + + movq 0+8(%rsp),%rax + adcq %rbp,%r15 + subq 0(%rbx),%rdi + movq 8+8(%rsp),%rdi + movq 16+8(%rsp),%r10 + adcq %r15,%r14 + leaq (%rsi,%rax,1),%rsi + adcq %rbp,%rbp + movq %r14,-8(%rbx) + + cmpq %r10,%rdi + jb .Lmulx4x_outer + + movq -8(%rcx),%r10 + movq %rbp,%r8 + movq (%rcx,%rax,1),%r12 + leaq (%rcx,%rax,1),%rbp + movq %rax,%rcx + leaq (%rbx,%rax,1),%rdi + xorl %eax,%eax + xorq %r15,%r15 + subq %r14,%r10 + adcq %r15,%r15 + orq %r15,%r8 + sarq $3+2,%rcx + subq %r8,%rax + movq 56+8(%rsp),%rdx + decq %r12 + movq 8(%rbp),%r13 + xorq %r8,%r8 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp .Lsqrx4x_sub_entry +.cfi_endproc +.size mulx4x_internal,.-mulx4x_internal +.type bn_powerx5,@function +.align 32 +bn_powerx5: +.cfi_startproc + movq %rsp,%rax +.cfi_def_cfa_register %rax +.Lpowerx5_enter: + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 +.Lpowerx5_prologue: + + shll $3,%r9d + leaq (%r9,%r9,2),%r10 + negq %r9 + movq (%r8),%r8 + + + + + + + + + leaq -320(%rsp,%r9,2),%r11 + movq %rsp,%rbp + subq %rdi,%r11 + andq $4095,%r11 + cmpq %r11,%r10 + jb .Lpwrx_sp_alt + subq %r11,%rbp + leaq -320(%rbp,%r9,2),%rbp + jmp .Lpwrx_sp_done + +.align 32 +.Lpwrx_sp_alt: + leaq 4096-320(,%r9,2),%r10 + leaq -320(%rbp,%r9,2),%rbp + subq %r10,%r11 + movq $0,%r10 + cmovcq %r10,%r11 + subq %r11,%rbp +.Lpwrx_sp_done: + andq $-64,%rbp + movq %rsp,%r11 + subq %rbp,%r11 + andq $-4096,%r11 + leaq (%r11,%rbp,1),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lpwrx_page_walk + jmp .Lpwrx_page_walk_done + +.Lpwrx_page_walk: + leaq -4096(%rsp),%rsp + movq (%rsp),%r10 + cmpq %rbp,%rsp + ja .Lpwrx_page_walk +.Lpwrx_page_walk_done: + + movq %r9,%r10 + negq %r9 + + + + + + + + + + + + + pxor %xmm0,%xmm0 +.byte 102,72,15,110,207 +.byte 102,72,15,110,209 +.byte 102,73,15,110,218 +.byte 102,72,15,110,226 + movq %r8,32(%rsp) + movq %rax,40(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 +.Lpowerx5_body: + + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + call __bn_sqrx8x_internal + call __bn_postx4x_internal + + movq %r10,%r9 + movq %rsi,%rdi +.byte 102,72,15,126,209 +.byte 102,72,15,126,226 + movq 40(%rsp),%rax + + call mulx4x_internal + + movq 40(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq $1,%rax + + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpowerx5_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_powerx5,.-bn_powerx5 + +.globl bn_sqrx8x_internal +.hidden bn_sqrx8x_internal +.type bn_sqrx8x_internal,@function +.align 32 +bn_sqrx8x_internal: +__bn_sqrx8x_internal: +.cfi_startproc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + leaq 48+8(%rsp),%rdi + leaq (%rsi,%r9,1),%rbp + movq %r9,0+8(%rsp) + movq %rbp,8+8(%rsp) + jmp .Lsqr8x_zero_start + +.align 32 +.byte 0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00 +.Lsqrx8x_zero: +.byte 0x3e + movdqa %xmm0,0(%rdi) + movdqa %xmm0,16(%rdi) + movdqa %xmm0,32(%rdi) + movdqa %xmm0,48(%rdi) +.Lsqr8x_zero_start: + movdqa %xmm0,64(%rdi) + movdqa %xmm0,80(%rdi) + movdqa %xmm0,96(%rdi) + movdqa %xmm0,112(%rdi) + leaq 128(%rdi),%rdi + subq $64,%r9 + jnz .Lsqrx8x_zero + + movq 0(%rsi),%rdx + + xorq %r10,%r10 + xorq %r11,%r11 + xorq %r12,%r12 + xorq %r13,%r13 + xorq %r14,%r14 + xorq %r15,%r15 + leaq 48+8(%rsp),%rdi + xorq %rbp,%rbp + jmp .Lsqrx8x_outer_loop + +.align 32 +.Lsqrx8x_outer_loop: + mulxq 8(%rsi),%r8,%rax + adcxq %r9,%r8 + adoxq %rax,%r10 + mulxq 16(%rsi),%r9,%rax + adcxq %r10,%r9 + adoxq %rax,%r11 +.byte 0xc4,0xe2,0xab,0xf6,0x86,0x18,0x00,0x00,0x00 + adcxq %r11,%r10 + adoxq %rax,%r12 +.byte 0xc4,0xe2,0xa3,0xf6,0x86,0x20,0x00,0x00,0x00 + adcxq %r12,%r11 + adoxq %rax,%r13 + mulxq 40(%rsi),%r12,%rax + adcxq %r13,%r12 + adoxq %rax,%r14 + mulxq 48(%rsi),%r13,%rax + adcxq %r14,%r13 + adoxq %r15,%rax + mulxq 56(%rsi),%r14,%r15 + movq 8(%rsi),%rdx + adcxq %rax,%r14 + adoxq %rbp,%r15 + adcq 64(%rdi),%r15 + movq %r8,8(%rdi) + movq %r9,16(%rdi) + sbbq %rcx,%rcx + xorq %rbp,%rbp + + + mulxq 16(%rsi),%r8,%rbx + mulxq 24(%rsi),%r9,%rax + adcxq %r10,%r8 + adoxq %rbx,%r9 + mulxq 32(%rsi),%r10,%rbx + adcxq %r11,%r9 + adoxq %rax,%r10 +.byte 0xc4,0xe2,0xa3,0xf6,0x86,0x28,0x00,0x00,0x00 + adcxq %r12,%r10 + adoxq %rbx,%r11 +.byte 0xc4,0xe2,0x9b,0xf6,0x9e,0x30,0x00,0x00,0x00 + adcxq %r13,%r11 + adoxq %r14,%r12 +.byte 0xc4,0x62,0x93,0xf6,0xb6,0x38,0x00,0x00,0x00 + movq 16(%rsi),%rdx + adcxq %rax,%r12 + adoxq %rbx,%r13 + adcxq %r15,%r13 + adoxq %rbp,%r14 + adcxq %rbp,%r14 + + movq %r8,24(%rdi) + movq %r9,32(%rdi) + + mulxq 24(%rsi),%r8,%rbx + mulxq 32(%rsi),%r9,%rax + adcxq %r10,%r8 + adoxq %rbx,%r9 + mulxq 40(%rsi),%r10,%rbx + adcxq %r11,%r9 + adoxq %rax,%r10 +.byte 0xc4,0xe2,0xa3,0xf6,0x86,0x30,0x00,0x00,0x00 + adcxq %r12,%r10 + adoxq %r13,%r11 +.byte 0xc4,0x62,0x9b,0xf6,0xae,0x38,0x00,0x00,0x00 +.byte 0x3e + movq 24(%rsi),%rdx + adcxq %rbx,%r11 + adoxq %rax,%r12 + adcxq %r14,%r12 + movq %r8,40(%rdi) + movq %r9,48(%rdi) + mulxq 32(%rsi),%r8,%rax + adoxq %rbp,%r13 + adcxq %rbp,%r13 + + mulxq 40(%rsi),%r9,%rbx + adcxq %r10,%r8 + adoxq %rax,%r9 + mulxq 48(%rsi),%r10,%rax + adcxq %r11,%r9 + adoxq %r12,%r10 + mulxq 56(%rsi),%r11,%r12 + movq 32(%rsi),%rdx + movq 40(%rsi),%r14 + adcxq %rbx,%r10 + adoxq %rax,%r11 + movq 48(%rsi),%r15 + adcxq %r13,%r11 + adoxq %rbp,%r12 + adcxq %rbp,%r12 + + movq %r8,56(%rdi) + movq %r9,64(%rdi) + + mulxq %r14,%r9,%rax + movq 56(%rsi),%r8 + adcxq %r10,%r9 + mulxq %r15,%r10,%rbx + adoxq %rax,%r10 + adcxq %r11,%r10 + mulxq %r8,%r11,%rax + movq %r14,%rdx + adoxq %rbx,%r11 + adcxq %r12,%r11 + + adcxq %rbp,%rax + + mulxq %r15,%r14,%rbx + mulxq %r8,%r12,%r13 + movq %r15,%rdx + leaq 64(%rsi),%rsi + adcxq %r14,%r11 + adoxq %rbx,%r12 + adcxq %rax,%r12 + adoxq %rbp,%r13 + +.byte 0x67,0x67 + mulxq %r8,%r8,%r14 + adcxq %r8,%r13 + adcxq %rbp,%r14 + + cmpq 8+8(%rsp),%rsi + je .Lsqrx8x_outer_break + + negq %rcx + movq $-8,%rcx + movq %rbp,%r15 + movq 64(%rdi),%r8 + adcxq 72(%rdi),%r9 + adcxq 80(%rdi),%r10 + adcxq 88(%rdi),%r11 + adcq 96(%rdi),%r12 + adcq 104(%rdi),%r13 + adcq 112(%rdi),%r14 + adcq 120(%rdi),%r15 + leaq (%rsi),%rbp + leaq 128(%rdi),%rdi + sbbq %rax,%rax + + movq -64(%rsi),%rdx + movq %rax,16+8(%rsp) + movq %rdi,24+8(%rsp) + + + xorl %eax,%eax + jmp .Lsqrx8x_loop + +.align 32 +.Lsqrx8x_loop: + movq %r8,%rbx + mulxq 0(%rbp),%rax,%r8 + adcxq %rax,%rbx + adoxq %r9,%r8 + + mulxq 8(%rbp),%rax,%r9 + adcxq %rax,%r8 + adoxq %r10,%r9 + + mulxq 16(%rbp),%rax,%r10 + adcxq %rax,%r9 + adoxq %r11,%r10 + + mulxq 24(%rbp),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + +.byte 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 + adcxq %rax,%r11 + adoxq %r13,%r12 + + mulxq 40(%rbp),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + + mulxq 48(%rbp),%rax,%r14 + movq %rbx,(%rdi,%rcx,8) + movl $0,%ebx + adcxq %rax,%r13 + adoxq %r15,%r14 + +.byte 0xc4,0x62,0xfb,0xf6,0xbd,0x38,0x00,0x00,0x00 + movq 8(%rsi,%rcx,8),%rdx + adcxq %rax,%r14 + adoxq %rbx,%r15 + adcxq %rbx,%r15 + +.byte 0x67 + incq %rcx + jnz .Lsqrx8x_loop + + leaq 64(%rbp),%rbp + movq $-8,%rcx + cmpq 8+8(%rsp),%rbp + je .Lsqrx8x_break + + subq 16+8(%rsp),%rbx +.byte 0x66 + movq -64(%rsi),%rdx + adcxq 0(%rdi),%r8 + adcxq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + leaq 64(%rdi),%rdi +.byte 0x67 + sbbq %rax,%rax + xorl %ebx,%ebx + movq %rax,16+8(%rsp) + jmp .Lsqrx8x_loop + +.align 32 +.Lsqrx8x_break: + xorq %rbp,%rbp + subq 16+8(%rsp),%rbx + adcxq %rbp,%r8 + movq 24+8(%rsp),%rcx + adcxq %rbp,%r9 + movq 0(%rsi),%rdx + adcq $0,%r10 + movq %r8,0(%rdi) + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + cmpq %rcx,%rdi + je .Lsqrx8x_outer_loop + + movq %r9,8(%rdi) + movq 8(%rcx),%r9 + movq %r10,16(%rdi) + movq 16(%rcx),%r10 + movq %r11,24(%rdi) + movq 24(%rcx),%r11 + movq %r12,32(%rdi) + movq 32(%rcx),%r12 + movq %r13,40(%rdi) + movq 40(%rcx),%r13 + movq %r14,48(%rdi) + movq 48(%rcx),%r14 + movq %r15,56(%rdi) + movq 56(%rcx),%r15 + movq %rcx,%rdi + jmp .Lsqrx8x_outer_loop + +.align 32 +.Lsqrx8x_outer_break: + movq %r9,72(%rdi) +.byte 102,72,15,126,217 + movq %r10,80(%rdi) + movq %r11,88(%rdi) + movq %r12,96(%rdi) + movq %r13,104(%rdi) + movq %r14,112(%rdi) + leaq 48+8(%rsp),%rdi + movq (%rsi,%rcx,1),%rdx + + movq 8(%rdi),%r11 + xorq %r10,%r10 + movq 0+8(%rsp),%r9 + adoxq %r11,%r11 + movq 16(%rdi),%r12 + movq 24(%rdi),%r13 + + +.align 32 +.Lsqrx4x_shift_n_add: + mulxq %rdx,%rax,%rbx + adoxq %r12,%r12 + adcxq %r10,%rax +.byte 0x48,0x8b,0x94,0x0e,0x08,0x00,0x00,0x00 +.byte 0x4c,0x8b,0x97,0x20,0x00,0x00,0x00 + adoxq %r13,%r13 + adcxq %r11,%rbx + movq 40(%rdi),%r11 + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + + mulxq %rdx,%rax,%rbx + adoxq %r10,%r10 + adcxq %r12,%rax + movq 16(%rsi,%rcx,1),%rdx + movq 48(%rdi),%r12 + adoxq %r11,%r11 + adcxq %r13,%rbx + movq 56(%rdi),%r13 + movq %rax,16(%rdi) + movq %rbx,24(%rdi) + + mulxq %rdx,%rax,%rbx + adoxq %r12,%r12 + adcxq %r10,%rax + movq 24(%rsi,%rcx,1),%rdx + leaq 32(%rcx),%rcx + movq 64(%rdi),%r10 + adoxq %r13,%r13 + adcxq %r11,%rbx + movq 72(%rdi),%r11 + movq %rax,32(%rdi) + movq %rbx,40(%rdi) + + mulxq %rdx,%rax,%rbx + adoxq %r10,%r10 + adcxq %r12,%rax + jrcxz .Lsqrx4x_shift_n_add_break +.byte 0x48,0x8b,0x94,0x0e,0x00,0x00,0x00,0x00 + adoxq %r11,%r11 + adcxq %r13,%rbx + movq 80(%rdi),%r12 + movq 88(%rdi),%r13 + movq %rax,48(%rdi) + movq %rbx,56(%rdi) + leaq 64(%rdi),%rdi + nop + jmp .Lsqrx4x_shift_n_add + +.align 32 +.Lsqrx4x_shift_n_add_break: + adcxq %r13,%rbx + movq %rax,48(%rdi) + movq %rbx,56(%rdi) + leaq 64(%rdi),%rdi +.byte 102,72,15,126,213 +__bn_sqrx8x_reduction: + xorl %eax,%eax + movq 32+8(%rsp),%rbx + movq 48+8(%rsp),%rdx + leaq -64(%rbp,%r9,1),%rcx + + movq %rcx,0+8(%rsp) + movq %rdi,8+8(%rsp) + + leaq 48+8(%rsp),%rdi + jmp .Lsqrx8x_reduction_loop + +.align 32 +.Lsqrx8x_reduction_loop: + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + movq 32(%rdi),%r12 + movq %rdx,%r8 + imulq %rbx,%rdx + movq 40(%rdi),%r13 + movq 48(%rdi),%r14 + movq 56(%rdi),%r15 + movq %rax,24+8(%rsp) + + leaq 64(%rdi),%rdi + xorq %rsi,%rsi + movq $-8,%rcx + jmp .Lsqrx8x_reduce + +.align 32 +.Lsqrx8x_reduce: + movq %r8,%rbx + mulxq 0(%rbp),%rax,%r8 + adcxq %rbx,%rax + adoxq %r9,%r8 + + mulxq 8(%rbp),%rbx,%r9 + adcxq %rbx,%r8 + adoxq %r10,%r9 + + mulxq 16(%rbp),%rbx,%r10 + adcxq %rbx,%r9 + adoxq %r11,%r10 + + mulxq 24(%rbp),%rbx,%r11 + adcxq %rbx,%r10 + adoxq %r12,%r11 + +.byte 0xc4,0x62,0xe3,0xf6,0xa5,0x20,0x00,0x00,0x00 + movq %rdx,%rax + movq %r8,%rdx + adcxq %rbx,%r11 + adoxq %r13,%r12 + + mulxq 32+8(%rsp),%rbx,%rdx + movq %rax,%rdx + movq %rax,64+48+8(%rsp,%rcx,8) + + mulxq 40(%rbp),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + + mulxq 48(%rbp),%rax,%r14 + adcxq %rax,%r13 + adoxq %r15,%r14 + + mulxq 56(%rbp),%rax,%r15 + movq %rbx,%rdx + adcxq %rax,%r14 + adoxq %rsi,%r15 + adcxq %rsi,%r15 + +.byte 0x67,0x67,0x67 + incq %rcx + jnz .Lsqrx8x_reduce + + movq %rsi,%rax + cmpq 0+8(%rsp),%rbp + jae .Lsqrx8x_no_tail + + movq 48+8(%rsp),%rdx + addq 0(%rdi),%r8 + leaq 64(%rbp),%rbp + movq $-8,%rcx + adcxq 8(%rdi),%r9 + adcxq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + leaq 64(%rdi),%rdi + sbbq %rax,%rax + + xorq %rsi,%rsi + movq %rax,16+8(%rsp) + jmp .Lsqrx8x_tail + +.align 32 +.Lsqrx8x_tail: + movq %r8,%rbx + mulxq 0(%rbp),%rax,%r8 + adcxq %rax,%rbx + adoxq %r9,%r8 + + mulxq 8(%rbp),%rax,%r9 + adcxq %rax,%r8 + adoxq %r10,%r9 + + mulxq 16(%rbp),%rax,%r10 + adcxq %rax,%r9 + adoxq %r11,%r10 + + mulxq 24(%rbp),%rax,%r11 + adcxq %rax,%r10 + adoxq %r12,%r11 + +.byte 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 + adcxq %rax,%r11 + adoxq %r13,%r12 + + mulxq 40(%rbp),%rax,%r13 + adcxq %rax,%r12 + adoxq %r14,%r13 + + mulxq 48(%rbp),%rax,%r14 + adcxq %rax,%r13 + adoxq %r15,%r14 + + mulxq 56(%rbp),%rax,%r15 + movq 72+48+8(%rsp,%rcx,8),%rdx + adcxq %rax,%r14 + adoxq %rsi,%r15 + movq %rbx,(%rdi,%rcx,8) + movq %r8,%rbx + adcxq %rsi,%r15 + + incq %rcx + jnz .Lsqrx8x_tail + + cmpq 0+8(%rsp),%rbp + jae .Lsqrx8x_tail_done + + subq 16+8(%rsp),%rsi + movq 48+8(%rsp),%rdx + leaq 64(%rbp),%rbp + adcq 0(%rdi),%r8 + adcq 8(%rdi),%r9 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + leaq 64(%rdi),%rdi + sbbq %rax,%rax + subq $8,%rcx + + xorq %rsi,%rsi + movq %rax,16+8(%rsp) + jmp .Lsqrx8x_tail + +.align 32 +.Lsqrx8x_tail_done: + xorq %rax,%rax + addq 24+8(%rsp),%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + adcq $0,%r12 + adcq $0,%r13 + adcq $0,%r14 + adcq $0,%r15 + adcq $0,%rax + + subq 16+8(%rsp),%rsi +.Lsqrx8x_no_tail: + adcq 0(%rdi),%r8 +.byte 102,72,15,126,217 + adcq 8(%rdi),%r9 + movq 56(%rbp),%rsi +.byte 102,72,15,126,213 + adcq 16(%rdi),%r10 + adcq 24(%rdi),%r11 + adcq 32(%rdi),%r12 + adcq 40(%rdi),%r13 + adcq 48(%rdi),%r14 + adcq 56(%rdi),%r15 + adcq $0,%rax + + movq 32+8(%rsp),%rbx + movq 64(%rdi,%rcx,1),%rdx + + movq %r8,0(%rdi) + leaq 64(%rdi),%r8 + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + + leaq 64(%rdi,%rcx,1),%rdi + cmpq 8+8(%rsp),%r8 + jb .Lsqrx8x_reduction_loop + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_sqrx8x_internal,.-bn_sqrx8x_internal +.align 32 +__bn_postx4x_internal: +.cfi_startproc + movq 0(%rbp),%r12 + movq %rcx,%r10 + movq %rcx,%r9 + negq %rax + sarq $3+2,%rcx + +.byte 102,72,15,126,202 +.byte 102,72,15,126,206 + decq %r12 + movq 8(%rbp),%r13 + xorq %r8,%r8 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 + jmp .Lsqrx4x_sub_entry + +.align 16 +.Lsqrx4x_sub: + movq 0(%rbp),%r12 + movq 8(%rbp),%r13 + movq 16(%rbp),%r14 + movq 24(%rbp),%r15 +.Lsqrx4x_sub_entry: + andnq %rax,%r12,%r12 + leaq 32(%rbp),%rbp + andnq %rax,%r13,%r13 + andnq %rax,%r14,%r14 + andnq %rax,%r15,%r15 + + negq %r8 + adcq 0(%rdi),%r12 + adcq 8(%rdi),%r13 + adcq 16(%rdi),%r14 + adcq 24(%rdi),%r15 + movq %r12,0(%rdx) + leaq 32(%rdi),%rdi + movq %r13,8(%rdx) + sbbq %r8,%r8 + movq %r14,16(%rdx) + movq %r15,24(%rdx) + leaq 32(%rdx),%rdx + + incq %rcx + jnz .Lsqrx4x_sub + + negq %r9 + + .byte 0xf3,0xc3 +.cfi_endproc +.size __bn_postx4x_internal,.-__bn_postx4x_internal +.globl bn_get_bits5 +.type bn_get_bits5,@function +.align 16 +bn_get_bits5: +.cfi_startproc + leaq 0(%rdi),%r10 + leaq 1(%rdi),%r11 + movl %esi,%ecx + shrl $4,%esi + andl $15,%ecx + leal -8(%rcx),%eax + cmpl $11,%ecx + cmovaq %r11,%r10 + cmoval %eax,%ecx + movzwl (%r10,%rsi,2),%eax + shrl %cl,%eax + andl $31,%eax + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_get_bits5,.-bn_get_bits5 + +.globl bn_scatter5 +.type bn_scatter5,@function +.align 16 +bn_scatter5: +.cfi_startproc + cmpl $0,%esi + jz .Lscatter_epilogue + leaq (%rdx,%rcx,8),%rdx +.Lscatter: + movq (%rdi),%rax + leaq 8(%rdi),%rdi + movq %rax,(%rdx) + leaq 256(%rdx),%rdx + subl $1,%esi + jnz .Lscatter +.Lscatter_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size bn_scatter5,.-bn_scatter5 + +.globl bn_gather5 +.type bn_gather5,@function +.align 32 +bn_gather5: +.LSEH_begin_bn_gather5: +.cfi_startproc + +.byte 0x4c,0x8d,0x14,0x24 +.byte 0x48,0x81,0xec,0x08,0x01,0x00,0x00 + leaq .Linc(%rip),%rax + andq $-16,%rsp + + movd %ecx,%xmm5 + movdqa 0(%rax),%xmm0 + movdqa 16(%rax),%xmm1 + leaq 128(%rdx),%r11 + leaq 128(%rsp),%rax + + pshufd $0,%xmm5,%xmm5 + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,-128(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,-112(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,-96(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,-80(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,-64(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,-48(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,-32(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,-16(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,0(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,16(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,32(%rax) + movdqa %xmm4,%xmm2 + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,48(%rax) + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,64(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,80(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,96(%rax) + movdqa %xmm4,%xmm2 + movdqa %xmm3,112(%rax) + jmp .Lgather + +.align 32 +.Lgather: + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + movdqa -128(%r11),%xmm0 + movdqa -112(%r11),%xmm1 + movdqa -96(%r11),%xmm2 + pand -128(%rax),%xmm0 + movdqa -80(%r11),%xmm3 + pand -112(%rax),%xmm1 + por %xmm0,%xmm4 + pand -96(%rax),%xmm2 + por %xmm1,%xmm5 + pand -80(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa -64(%r11),%xmm0 + movdqa -48(%r11),%xmm1 + movdqa -32(%r11),%xmm2 + pand -64(%rax),%xmm0 + movdqa -16(%r11),%xmm3 + pand -48(%rax),%xmm1 + por %xmm0,%xmm4 + pand -32(%rax),%xmm2 + por %xmm1,%xmm5 + pand -16(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 0(%r11),%xmm0 + movdqa 16(%r11),%xmm1 + movdqa 32(%r11),%xmm2 + pand 0(%rax),%xmm0 + movdqa 48(%r11),%xmm3 + pand 16(%rax),%xmm1 + por %xmm0,%xmm4 + pand 32(%rax),%xmm2 + por %xmm1,%xmm5 + pand 48(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + movdqa 64(%r11),%xmm0 + movdqa 80(%r11),%xmm1 + movdqa 96(%r11),%xmm2 + pand 64(%rax),%xmm0 + movdqa 112(%r11),%xmm3 + pand 80(%rax),%xmm1 + por %xmm0,%xmm4 + pand 96(%rax),%xmm2 + por %xmm1,%xmm5 + pand 112(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 + por %xmm5,%xmm4 + leaq 256(%r11),%r11 + pshufd $0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + movq %xmm0,(%rdi) + leaq 8(%rdi),%rdi + subl $1,%esi + jnz .Lgather + + leaq (%r10),%rsp + .byte 0xf3,0xc3 +.LSEH_end_bn_gather5: +.cfi_endproc +.size bn_gather5,.-bn_gather5 +.align 64 +.Linc: +.long 0,0, 1,1 +.long 2,2, 2,2 +.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/bsearch.c b/crypto/openssl/crypto/bsearch.c new file mode 100644 index 000000000000..f812c4f8ef0f --- /dev/null +++ b/crypto/openssl/crypto/bsearch.c @@ -0,0 +1,44 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" + +const void *ossl_bsearch(const void *key, const void *base, int num, + int size, int (*cmp) (const void *, const void *), + int flags) +{ + const char *base_ = base; + int l, h, i = 0, c = 0; + const char *p = NULL; + + if (num == 0) + return NULL; + l = 0; + h = num; + while (l < h) { + i = (l + h) / 2; + p = &(base_[i * size]); + c = (*cmp) (key, p); + if (c < 0) + h = i; + else if (c > 0) + l = i + 1; + else + break; + } + if (c != 0 && !(flags & OSSL_BSEARCH_VALUE_ON_NOMATCH)) + p = NULL; + else if (c == 0 && (flags & OSSL_BSEARCH_FIRST_VALUE_ON_MATCH)) { + while (i > 0 && (*cmp) (key, &(base_[(i - 1) * size])) == 0) + i--; + p = &(base_[i * size]); + } + return p; +} diff --git a/crypto/openssl/crypto/buffer/buf_err.c b/crypto/openssl/crypto/buffer/buf_err.c index 7e6e53226a93..9233b0a23c17 100644 --- a/crypto/openssl/crypto/buffer/buf_err.c +++ b/crypto/openssl/crypto/buffer/buf_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,29 +10,21 @@ #include #include +#include "crypto/buffererr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA BUF_str_functs[] = { - {ERR_PACK(ERR_LIB_BUF, BUF_F_BUF_MEM_GROW, 0), "BUF_MEM_grow"}, - {ERR_PACK(ERR_LIB_BUF, BUF_F_BUF_MEM_GROW_CLEAN, 0), "BUF_MEM_grow_clean"}, - {ERR_PACK(ERR_LIB_BUF, BUF_F_BUF_MEM_NEW, 0), "BUF_MEM_new"}, - {0, NULL} -}; - static const ERR_STRING_DATA BUF_str_reasons[] = { {0, NULL} }; #endif -int ERR_load_BUF_strings(void) +int ossl_err_load_BUF_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(BUF_str_functs[0].error) == NULL) { - ERR_load_strings_const(BUF_str_functs); + if (ERR_reason_error_string(BUF_str_reasons[0].error) == NULL) ERR_load_strings_const(BUF_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/buffer/buffer.c b/crypto/openssl/crypto/buffer/buffer.c index 72258abb9e5e..db1ea38b195a 100644 --- a/crypto/openssl/crypto/buffer/buffer.c +++ b/crypto/openssl/crypto/buffer/buffer.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -34,7 +34,7 @@ BUF_MEM *BUF_MEM_new(void) ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - BUFerr(BUF_F_BUF_MEM_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE); return NULL; } return ret; @@ -87,7 +87,7 @@ size_t BUF_MEM_grow(BUF_MEM *str, size_t len) } /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ if (len > LIMIT_BEFORE_EXPANSION) { - BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE); return 0; } n = (len + 3) / 3 * 4; @@ -96,7 +96,7 @@ size_t BUF_MEM_grow(BUF_MEM *str, size_t len) else ret = OPENSSL_realloc(str->data, n); if (ret == NULL) { - BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE); len = 0; } else { str->data = ret; @@ -125,7 +125,7 @@ size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len) } /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ if (len > LIMIT_BEFORE_EXPANSION) { - BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE); return 0; } n = (len + 3) / 3 * 4; @@ -134,7 +134,7 @@ size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len) else ret = OPENSSL_clear_realloc(str->data, str->max, n); if (ret == NULL) { - BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE); len = 0; } else { str->data = ret; diff --git a/crypto/openssl/crypto/buffer/build.info b/crypto/openssl/crypto/buffer/build.info index 54da1f92a834..6f31397be722 100644 --- a/crypto/openssl/crypto/buffer/build.info +++ b/crypto/openssl/crypto/buffer/build.info @@ -1,2 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=buffer.c buf_err.c +SOURCE[../../providers/libfips.a]=buffer.c diff --git a/crypto/openssl/crypto/build.info b/crypto/openssl/crypto/build.info index 2c619c62e843..16584234feb7 100644 --- a/crypto/openssl/crypto/build.info +++ b/crypto/openssl/crypto/build.info @@ -1,39 +1,140 @@ +# Note that these directories are filtered in Configure. Look for %skipdir +# there for further explanations. +SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \ + txt_db pkcs7 pkcs12 ui kdf store property \ + md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 \ + siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \ + seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \ + err comp http ocsp cms ts srp cmac ct async ess crmf cmp encode_decode \ + ffc + LIBS=../libcrypto -SOURCE[../libcrypto]=\ - cryptlib.c mem.c mem_dbg.c cversion.c ex_data.c cpt_err.c \ - ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fopen.c ctype.c \ - threads_pthread.c threads_win.c threads_none.c getenv.c \ - o_init.c o_fips.c mem_sec.c init.c {- $target{cpuid_asm_src} -} \ - {- $target{uplink_aux_src} -} -EXTRA= ../ms/uplink-x86.pl ../ms/uplink.c ../ms/applink.c \ - x86cpuid.pl x86_64cpuid.pl ia64cpuid.S \ - ppccpuid.pl pariscid.pl alphacpuid.pl arm64cpuid.pl armv4cpuid.pl +$UPLINKSRC= +$UPLINKDEF= +IF[{- !$disabled{uplink} -}] + $UPLINKSRC_common=../ms/uplink.c + $UPLINKSRC_x86=$UPLINKSRC_common uplink-x86.S + $UPLINKSRC_x86_64=$UPLINKSRC_common uplink-x86_64.s + $UPLINKSRC_ia64=$UPLINKSRC_common uplink-ia64.s + + IF[$UPLINKSRC_{- $target{uplink_arch} -}] + $UPLINKSRC=$UPLINKSRC_{- $target{uplink_arch} -} + $UPLINKDEF=OPENSSL_USE_APPLINK + ENDIF +ENDIF + +$CPUIDASM=mem_clr.c +$CPUIDDEF= +IF[{- !$disabled{asm} && $config{processor} ne '386' -}] + $CPUIDASM_x86=x86cpuid.S + + $CPUIDASM_x86_64=x86_64cpuid.s + + $CPUIDASM_ia64=ia64cpuid.s + + $CPUIDASM_sparcv9=sparcv9cap.c sparccpuid.S + + $CPUIDASM_alpha=alphacpuid.s + + $CPUIDASM_s390x=s390xcap.c s390xcpuid.S + + $CPUIDASM_armv4=armcap.c armv4cpuid.S + + $CPUIDASM_aarch64=armcap.c arm64cpuid.S + + $CPUIDASM_parisc11=pariscid.s + $CPUIDASM_parisc20_64=$CPUIDASM_parisc11 + + $CPUIDASM_ppc32=ppccpuid.s ppccap.c + $CPUIDASM_ppc64=$CPUIDASM_ppc32 + + $CPUIDASM_c64xplus=c64xpluscpuid.s + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$CPUIDASM_{- $target{asm_arch} -}] + $CPUIDASM=$CPUIDASM_{- $target{asm_arch} -} + $CPUIDDEF=OPENSSL_CPUID_OBJ + ENDIF +ENDIF + +# CPUID support. We need to add that explicitly in every shared library and +# provider module that uses it. ctype.c is included here because the CPUID +# uses functions from there to parse magic environment variables. +$CPUID_COMMON=$CPUIDASM cpuid.c ctype.c +INCLUDE[cpuid.o]=.. + +SOURCE[../libcrypto]=$CPUID_COMMON +DEFINE[../libcrypto]=$CPUIDDEF +SOURCE[../providers/libfips.a]=$CPUID_COMMON +DEFINE[../providers/libfips.a]=$CPUIDDEF +# We only need to include the CPUID stuff in the legacy provider when it's a +# separate module and it's dynamically linked with libcrypto. Otherwise, it +# already gets everything that the static libcrypto.a has, and doesn't need it +# added again. +IF[{- !$disabled{module} && !$disabled{shared} -}] + SOURCE[../providers/liblegacy.a]=$CPUID_COMMON + DEFINE[../providers/liblegacy.a]=$CPUIDDEF +ENDIF + +# Implementations are now spread across several libraries, so the CPUID define +# need to be applied to all affected libraries and modules. +DEFINE[../providers/libcommon.a]=$CPUIDDEF +DEFINE[../providers/libdefault.a]=$CPUIDDEF + +# The Core +$CORE_COMMON=provider_core.c provider_predefined.c \ + core_fetch.c core_algorithm.c core_namemap.c self_test_core.c + +SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c +SOURCE[../providers/libfips.a]=$CORE_COMMON + +# Central utilities +$UTIL_COMMON=\ + cryptlib.c params.c params_from_text.c bsearch.c ex_data.c o_str.c \ + threads_pthread.c threads_win.c threads_none.c initthread.c \ + context.c sparse_array.c asn1_dsa.c packet.c param_build.c \ + param_build_set.c der_writer.c threads_lib.c params_dup.c + +IF[{- !$disabled{shared} -}] + SOURCE[../libssl]=sparse_array.c +ENDIF + +SOURCE[../libcrypto]=$UTIL_COMMON \ + mem.c mem_sec.c \ + cversion.c info.c cpt_err.c ebcdic.c uid.c o_time.c o_dir.c \ + o_fopen.c getenv.c o_init.c init.c trace.c provider.c provider_child.c \ + punycode.c passphrase.c +SOURCE[../providers/libfips.a]=$UTIL_COMMON + +SOURCE[../libcrypto]=$UPLINKSRC +DEFINE[../libcrypto]=$UPLINKDEF + +DEPEND[info.o]=buildinf.h DEPEND[cversion.o]=buildinf.h GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q)" "$(PLATFORM)" -DEPEND[buildinf.h]=../configdata.pm -GENERATE[uplink-x86.s]=../ms/uplink-x86.pl $(PERLASM_SCHEME) -GENERATE[uplink-x86_64.s]=../ms/uplink-x86_64.pl $(PERLASM_SCHEME) -GENERATE[uplink-ia64.s]=../ms/uplink-ia64.pl $(PERLASM_SCHEME) +GENERATE[uplink-x86.S]=../ms/uplink-x86.pl +GENERATE[uplink-x86_64.s]=../ms/uplink-x86_64.pl +GENERATE[uplink-ia64.s]=../ms/uplink-ia64.pl -GENERATE[x86cpuid.s]=x86cpuid.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +GENERATE[x86cpuid.S]=x86cpuid.pl DEPEND[x86cpuid.s]=perlasm/x86asm.pl -GENERATE[x86_64cpuid.s]=x86_64cpuid.pl $(PERLASM_SCHEME) +GENERATE[x86_64cpuid.s]=x86_64cpuid.pl GENERATE[ia64cpuid.s]=ia64cpuid.S -GENERATE[ppccpuid.s]=ppccpuid.pl $(PERLASM_SCHEME) -GENERATE[pariscid.s]=pariscid.pl $(PERLASM_SCHEME) +GENERATE[ppccpuid.s]=ppccpuid.pl +GENERATE[pariscid.s]=pariscid.pl GENERATE[alphacpuid.s]=alphacpuid.pl -GENERATE[arm64cpuid.S]=arm64cpuid.pl $(PERLASM_SCHEME) +GENERATE[arm64cpuid.S]=arm64cpuid.pl INCLUDE[arm64cpuid.o]=. -GENERATE[armv4cpuid.S]=armv4cpuid.pl $(PERLASM_SCHEME) +GENERATE[armv4cpuid.S]=armv4cpuid.pl INCLUDE[armv4cpuid.o]=. -GENERATE[s390xcpuid.S]=s390xcpuid.pl $(PERLASM_SCHEME) +GENERATE[s390xcpuid.S]=s390xcpuid.pl INCLUDE[s390xcpuid.o]=. -IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-)/ -}] +IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-|BC-)/ -}] SHARED_SOURCE[../libcrypto]=dllmain.c ENDIF diff --git a/crypto/openssl/crypto/c64xpluscpuid.pl b/crypto/openssl/crypto/c64xpluscpuid.pl index 9aeee574ebf8..20728c03bc69 100755 --- a/crypto/openssl/crypto/c64xpluscpuid.pl +++ b/crypto/openssl/crypto/c64xpluscpuid.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 diff --git a/crypto/openssl/crypto/camellia/asm/cmll-x86.pl b/crypto/openssl/crypto/camellia/asm/cmll-x86.pl index cd514acfae4a..284d31ca9435 100755 --- a/crypto/openssl/crypto/camellia/asm/cmll-x86.pl +++ b/crypto/openssl/crypto/camellia/asm/cmll-x86.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -49,8 +49,7 @@ require "x86asm.pl"; $OPENSSL=1; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/camellia/asm/cmll-x86_64.pl b/crypto/openssl/crypto/camellia/asm/cmll-x86_64.pl index 59e1840160ff..7e069614d915 100755 --- a/crypto/openssl/crypto/camellia/asm/cmll-x86_64.pl +++ b/crypto/openssl/crypto/camellia/asm/cmll-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -36,9 +36,10 @@ # EM64T, pre-Core2 Intel x86_64 CPU, is not as impressive, because it # apparently emulates some of 64-bit operations in [32-bit] microcode. -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -47,7 +48,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; } @@ -685,6 +687,7 @@ $code.=<<___; .align 16 Camellia_cbc_encrypt: .cfi_startproc + endbranch cmp \$0,%rdx je .Lcbc_abort push %rbx diff --git a/crypto/openssl/crypto/camellia/asm/cmllt4-sparcv9.pl b/crypto/openssl/crypto/camellia/asm/cmllt4-sparcv9.pl index 71a40f6af90c..86e38d65c476 100755 --- a/crypto/openssl/crypto/camellia/asm/cmllt4-sparcv9.pl +++ b/crypto/openssl/crypto/camellia/asm/cmllt4-sparcv9.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -53,8 +53,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "sparcv9_modes.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $::evp=1; # if $evp is set to 0, script generates module with # Camellia_[en|de]crypt, Camellia_set_key and Camellia_cbc_encrypt @@ -67,7 +66,10 @@ $::evp=1; # if $evp is set to 0, script generates module with my ($inp,$out,$key,$rounds,$tmp,$mask)=map("%o$_",(0..5)); $code=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" .text diff --git a/crypto/openssl/crypto/camellia/build.info b/crypto/openssl/crypto/camellia/build.info index e36a19bd4d0b..f13cd8c958be 100644 --- a/crypto/openssl/crypto/camellia/build.info +++ b/crypto/openssl/crypto/camellia/build.info @@ -1,13 +1,25 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - cmll_ecb.c cmll_ofb.c cmll_cfb.c cmll_ctr.c \ - {- $target{cmll_asm_src} -} - -GENERATE[cmll-x86.s]=asm/cmll-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) \ - $(PROCESSOR) -DEPEND[cmll-x86.s]=../perlasm/x86asm.pl -GENERATE[cmll-x86_64.s]=asm/cmll-x86_64.pl $(PERLASM_SCHEME) -GENERATE[cmllt4-sparcv9.S]=asm/cmllt4-sparcv9.pl $(PERLASM_SCHEME) + +$CMLLASM=camellia.c cmll_misc.c cmll_cbc.c +IF[{- !$disabled{asm} -}] + $CMLLASM_x86=cmll-x86.S + $CMLLASM_x86_64=cmll-x86_64.s cmll_misc.c + $CMLLASM_sparcv9=camellia.c cmll_misc.c cmll_cbc.c cmllt4-sparcv9.S + + # Now that we have defined all the arch specific variables, use the + # appropriate one + IF[$CMLLASM_{- $target{asm_arch} -}] + $CMLLASM=$CMLLASM_{- $target{asm_arch} -} + $CMLLDEF=CMLL_ASM + ENDIF +ENDIF + +SOURCE[../../libcrypto]=cmll_ecb.c cmll_ofb.c cmll_cfb.c cmll_ctr.c $CMLLASM +DEFINE[../../libcrypto]=$CMLLDEF + +GENERATE[cmll-x86.S]=asm/cmll-x86.pl +DEPEND[cmll-x86.S]=../perlasm/x86asm.pl +GENERATE[cmll-x86_64.s]=asm/cmll-x86_64.pl +GENERATE[cmllt4-sparcv9.S]=asm/cmllt4-sparcv9.pl INCLUDE[cmllt4-sparcv9.o]=.. DEPEND[cmllt4-sparcv9.S]=../perlasm/sparcv9_modes.pl diff --git a/crypto/openssl/crypto/camellia/camellia.c b/crypto/openssl/crypto/camellia/camellia.c index f623864bc413..a4de9f891ab8 100644 --- a/crypto/openssl/crypto/camellia/camellia.c +++ b/crypto/openssl/crypto/camellia/camellia.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -39,6 +39,12 @@ * words reasonable performance even with not so modern compilers. */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cmll_local.h" #include @@ -493,9 +499,9 @@ void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], PUTU32(plaintext + 12, s1); } -void Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[], - const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) +void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, u8 plaintext[]) { Camellia_DecryptBlock_Rounds(keyBitLength == 128 ? 3 : 4, - plaintext, keyTable, ciphertext); + ciphertext, keyTable, plaintext); } diff --git a/crypto/openssl/crypto/camellia/cmll-x86.S b/crypto/openssl/crypto/camellia/cmll-x86.S new file mode 100644 index 000000000000..f4b77edc3333 --- /dev/null +++ b/crypto/openssl/crypto/camellia/cmll-x86.S @@ -0,0 +1,2446 @@ +.text +.globl Camellia_EncryptBlock_Rounds +.type Camellia_EncryptBlock_Rounds,@function +.align 16 +Camellia_EncryptBlock_Rounds: +.L_Camellia_EncryptBlock_Rounds_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%eax + movl 24(%esp),%esi + movl 28(%esp),%edi + movl %esp,%ebx + subl $28,%esp + andl $-64,%esp + leal -127(%edi),%ecx + subl %esp,%ecx + negl %ecx + andl $960,%ecx + subl %ecx,%esp + addl $4,%esp + shll $6,%eax + leal (%edi,%eax,1),%eax + movl %ebx,20(%esp) + movl %eax,16(%esp) + call .L000pic_point +.L000pic_point: + popl %ebp + leal .LCamellia_SBOX-.L000pic_point(%ebp),%ebp + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + bswap %eax + movl 12(%esi),%edx + bswap %ebx + bswap %ecx + bswap %edx + call _x86_Camellia_encrypt + movl 20(%esp),%esp + bswap %eax + movl 32(%esp),%esi + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size Camellia_EncryptBlock_Rounds,.-.L_Camellia_EncryptBlock_Rounds_begin +.globl Camellia_EncryptBlock +.type Camellia_EncryptBlock,@function +.align 16 +Camellia_EncryptBlock: +.L_Camellia_EncryptBlock_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl $128,%eax + subl 4(%esp),%eax + movl $3,%eax + adcl $0,%eax + movl %eax,4(%esp) + jmp .L_Camellia_EncryptBlock_Rounds_begin +.size Camellia_EncryptBlock,.-.L_Camellia_EncryptBlock_begin +.globl Camellia_encrypt +.type Camellia_encrypt,@function +.align 16 +Camellia_encrypt: +.L_Camellia_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 28(%esp),%edi + movl %esp,%ebx + subl $28,%esp + andl $-64,%esp + movl 272(%edi),%eax + leal -127(%edi),%ecx + subl %esp,%ecx + negl %ecx + andl $960,%ecx + subl %ecx,%esp + addl $4,%esp + shll $6,%eax + leal (%edi,%eax,1),%eax + movl %ebx,20(%esp) + movl %eax,16(%esp) + call .L001pic_point +.L001pic_point: + popl %ebp + leal .LCamellia_SBOX-.L001pic_point(%ebp),%ebp + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + bswap %eax + movl 12(%esi),%edx + bswap %ebx + bswap %ecx + bswap %edx + call _x86_Camellia_encrypt + movl 20(%esp),%esp + bswap %eax + movl 24(%esp),%esi + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size Camellia_encrypt,.-.L_Camellia_encrypt_begin +.type _x86_Camellia_encrypt,@function +.align 16 +_x86_Camellia_encrypt: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + movl 16(%edi),%esi + movl %eax,4(%esp) + movl %ebx,8(%esp) + movl %ecx,12(%esp) + movl %edx,16(%esp) +.align 16 +.L002loop: + xorl %esi,%eax + xorl 20(%edi),%ebx + movzbl %ah,%esi + movl 2052(%ebp,%esi,8),%edx + movzbl %al,%esi + xorl 4(%ebp,%esi,8),%edx + shrl $16,%eax + movzbl %bl,%esi + movl (%ebp,%esi,8),%ecx + movzbl %ah,%esi + xorl (%ebp,%esi,8),%edx + movzbl %bh,%esi + xorl 4(%ebp,%esi,8),%ecx + shrl $16,%ebx + movzbl %al,%eax + xorl 2048(%ebp,%eax,8),%edx + movzbl %bh,%esi + movl 16(%esp),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl 2048(%ebp,%esi,8),%ecx + movzbl %bl,%esi + movl 12(%esp),%ebx + xorl %eax,%edx + xorl 2052(%ebp,%esi,8),%ecx + movl 24(%edi),%esi + xorl %ecx,%edx + movl %edx,16(%esp) + xorl %ebx,%ecx + movl %ecx,12(%esp) + xorl %esi,%ecx + xorl 28(%edi),%edx + movzbl %ch,%esi + movl 2052(%ebp,%esi,8),%ebx + movzbl %cl,%esi + xorl 4(%ebp,%esi,8),%ebx + shrl $16,%ecx + movzbl %dl,%esi + movl (%ebp,%esi,8),%eax + movzbl %ch,%esi + xorl (%ebp,%esi,8),%ebx + movzbl %dh,%esi + xorl 4(%ebp,%esi,8),%eax + shrl $16,%edx + movzbl %cl,%ecx + xorl 2048(%ebp,%ecx,8),%ebx + movzbl %dh,%esi + movl 8(%esp),%ecx + xorl %ebx,%eax + rorl $8,%ebx + xorl 2048(%ebp,%esi,8),%eax + movzbl %dl,%esi + movl 4(%esp),%edx + xorl %ecx,%ebx + xorl 2052(%ebp,%esi,8),%eax + movl 32(%edi),%esi + xorl %eax,%ebx + movl %ebx,8(%esp) + xorl %edx,%eax + movl %eax,4(%esp) + xorl %esi,%eax + xorl 36(%edi),%ebx + movzbl %ah,%esi + movl 2052(%ebp,%esi,8),%edx + movzbl %al,%esi + xorl 4(%ebp,%esi,8),%edx + shrl $16,%eax + movzbl %bl,%esi + movl (%ebp,%esi,8),%ecx + movzbl %ah,%esi + xorl (%ebp,%esi,8),%edx + movzbl %bh,%esi + xorl 4(%ebp,%esi,8),%ecx + shrl $16,%ebx + movzbl %al,%eax + xorl 2048(%ebp,%eax,8),%edx + movzbl %bh,%esi + movl 16(%esp),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl 2048(%ebp,%esi,8),%ecx + movzbl %bl,%esi + movl 12(%esp),%ebx + xorl %eax,%edx + xorl 2052(%ebp,%esi,8),%ecx + movl 40(%edi),%esi + xorl %ecx,%edx + movl %edx,16(%esp) + xorl %ebx,%ecx + movl %ecx,12(%esp) + xorl %esi,%ecx + xorl 44(%edi),%edx + movzbl %ch,%esi + movl 2052(%ebp,%esi,8),%ebx + movzbl %cl,%esi + xorl 4(%ebp,%esi,8),%ebx + shrl $16,%ecx + movzbl %dl,%esi + movl (%ebp,%esi,8),%eax + movzbl %ch,%esi + xorl (%ebp,%esi,8),%ebx + movzbl %dh,%esi + xorl 4(%ebp,%esi,8),%eax + shrl $16,%edx + movzbl %cl,%ecx + xorl 2048(%ebp,%ecx,8),%ebx + movzbl %dh,%esi + movl 8(%esp),%ecx + xorl %ebx,%eax + rorl $8,%ebx + xorl 2048(%ebp,%esi,8),%eax + movzbl %dl,%esi + movl 4(%esp),%edx + xorl %ecx,%ebx + xorl 2052(%ebp,%esi,8),%eax + movl 48(%edi),%esi + xorl %eax,%ebx + movl %ebx,8(%esp) + xorl %edx,%eax + movl %eax,4(%esp) + xorl %esi,%eax + xorl 52(%edi),%ebx + movzbl %ah,%esi + movl 2052(%ebp,%esi,8),%edx + movzbl %al,%esi + xorl 4(%ebp,%esi,8),%edx + shrl $16,%eax + movzbl %bl,%esi + movl (%ebp,%esi,8),%ecx + movzbl %ah,%esi + xorl (%ebp,%esi,8),%edx + movzbl %bh,%esi + xorl 4(%ebp,%esi,8),%ecx + shrl $16,%ebx + movzbl %al,%eax + xorl 2048(%ebp,%eax,8),%edx + movzbl %bh,%esi + movl 16(%esp),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl 2048(%ebp,%esi,8),%ecx + movzbl %bl,%esi + movl 12(%esp),%ebx + xorl %eax,%edx + xorl 2052(%ebp,%esi,8),%ecx + movl 56(%edi),%esi + xorl %ecx,%edx + movl %edx,16(%esp) + xorl %ebx,%ecx + movl %ecx,12(%esp) + xorl %esi,%ecx + xorl 60(%edi),%edx + movzbl %ch,%esi + movl 2052(%ebp,%esi,8),%ebx + movzbl %cl,%esi + xorl 4(%ebp,%esi,8),%ebx + shrl $16,%ecx + movzbl %dl,%esi + movl (%ebp,%esi,8),%eax + movzbl %ch,%esi + xorl (%ebp,%esi,8),%ebx + movzbl %dh,%esi + xorl 4(%ebp,%esi,8),%eax + shrl $16,%edx + movzbl %cl,%ecx + xorl 2048(%ebp,%ecx,8),%ebx + movzbl %dh,%esi + movl 8(%esp),%ecx + xorl %ebx,%eax + rorl $8,%ebx + xorl 2048(%ebp,%esi,8),%eax + movzbl %dl,%esi + movl 4(%esp),%edx + xorl %ecx,%ebx + xorl 2052(%ebp,%esi,8),%eax + movl 64(%edi),%esi + xorl %eax,%ebx + movl %ebx,8(%esp) + xorl %edx,%eax + movl %eax,4(%esp) + addl $64,%edi + cmpl 20(%esp),%edi + je .L003done + andl %eax,%esi + movl 16(%esp),%edx + roll $1,%esi + movl %edx,%ecx + xorl %esi,%ebx + orl 12(%edi),%ecx + movl %ebx,8(%esp) + xorl 12(%esp),%ecx + movl 4(%edi),%esi + movl %ecx,12(%esp) + orl %ebx,%esi + andl 8(%edi),%ecx + xorl %esi,%eax + roll $1,%ecx + movl %eax,4(%esp) + xorl %ecx,%edx + movl 16(%edi),%esi + movl %edx,16(%esp) + jmp .L002loop +.align 8 +.L003done: + movl %eax,%ecx + movl %ebx,%edx + movl 12(%esp),%eax + movl 16(%esp),%ebx + xorl %esi,%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + ret +.size _x86_Camellia_encrypt,.-_x86_Camellia_encrypt +.globl Camellia_DecryptBlock_Rounds +.type Camellia_DecryptBlock_Rounds,@function +.align 16 +Camellia_DecryptBlock_Rounds: +.L_Camellia_DecryptBlock_Rounds_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%eax + movl 24(%esp),%esi + movl 28(%esp),%edi + movl %esp,%ebx + subl $28,%esp + andl $-64,%esp + leal -127(%edi),%ecx + subl %esp,%ecx + negl %ecx + andl $960,%ecx + subl %ecx,%esp + addl $4,%esp + shll $6,%eax + movl %edi,16(%esp) + leal (%edi,%eax,1),%edi + movl %ebx,20(%esp) + call .L004pic_point +.L004pic_point: + popl %ebp + leal .LCamellia_SBOX-.L004pic_point(%ebp),%ebp + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + bswap %eax + movl 12(%esi),%edx + bswap %ebx + bswap %ecx + bswap %edx + call _x86_Camellia_decrypt + movl 20(%esp),%esp + bswap %eax + movl 32(%esp),%esi + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size Camellia_DecryptBlock_Rounds,.-.L_Camellia_DecryptBlock_Rounds_begin +.globl Camellia_DecryptBlock +.type Camellia_DecryptBlock,@function +.align 16 +Camellia_DecryptBlock: +.L_Camellia_DecryptBlock_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl $128,%eax + subl 4(%esp),%eax + movl $3,%eax + adcl $0,%eax + movl %eax,4(%esp) + jmp .L_Camellia_DecryptBlock_Rounds_begin +.size Camellia_DecryptBlock,.-.L_Camellia_DecryptBlock_begin +.globl Camellia_decrypt +.type Camellia_decrypt,@function +.align 16 +Camellia_decrypt: +.L_Camellia_decrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 28(%esp),%edi + movl %esp,%ebx + subl $28,%esp + andl $-64,%esp + movl 272(%edi),%eax + leal -127(%edi),%ecx + subl %esp,%ecx + negl %ecx + andl $960,%ecx + subl %ecx,%esp + addl $4,%esp + shll $6,%eax + movl %edi,16(%esp) + leal (%edi,%eax,1),%edi + movl %ebx,20(%esp) + call .L005pic_point +.L005pic_point: + popl %ebp + leal .LCamellia_SBOX-.L005pic_point(%ebp),%ebp + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + bswap %eax + movl 12(%esi),%edx + bswap %ebx + bswap %ecx + bswap %edx + call _x86_Camellia_decrypt + movl 20(%esp),%esp + bswap %eax + movl 24(%esp),%esi + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size Camellia_decrypt,.-.L_Camellia_decrypt_begin +.type _x86_Camellia_decrypt,@function +.align 16 +_x86_Camellia_decrypt: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + movl -8(%edi),%esi + movl %eax,4(%esp) + movl %ebx,8(%esp) + movl %ecx,12(%esp) + movl %edx,16(%esp) +.align 16 +.L006loop: + xorl %esi,%eax + xorl -4(%edi),%ebx + movzbl %ah,%esi + movl 2052(%ebp,%esi,8),%edx + movzbl %al,%esi + xorl 4(%ebp,%esi,8),%edx + shrl $16,%eax + movzbl %bl,%esi + movl (%ebp,%esi,8),%ecx + movzbl %ah,%esi + xorl (%ebp,%esi,8),%edx + movzbl %bh,%esi + xorl 4(%ebp,%esi,8),%ecx + shrl $16,%ebx + movzbl %al,%eax + xorl 2048(%ebp,%eax,8),%edx + movzbl %bh,%esi + movl 16(%esp),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl 2048(%ebp,%esi,8),%ecx + movzbl %bl,%esi + movl 12(%esp),%ebx + xorl %eax,%edx + xorl 2052(%ebp,%esi,8),%ecx + movl -16(%edi),%esi + xorl %ecx,%edx + movl %edx,16(%esp) + xorl %ebx,%ecx + movl %ecx,12(%esp) + xorl %esi,%ecx + xorl -12(%edi),%edx + movzbl %ch,%esi + movl 2052(%ebp,%esi,8),%ebx + movzbl %cl,%esi + xorl 4(%ebp,%esi,8),%ebx + shrl $16,%ecx + movzbl %dl,%esi + movl (%ebp,%esi,8),%eax + movzbl %ch,%esi + xorl (%ebp,%esi,8),%ebx + movzbl %dh,%esi + xorl 4(%ebp,%esi,8),%eax + shrl $16,%edx + movzbl %cl,%ecx + xorl 2048(%ebp,%ecx,8),%ebx + movzbl %dh,%esi + movl 8(%esp),%ecx + xorl %ebx,%eax + rorl $8,%ebx + xorl 2048(%ebp,%esi,8),%eax + movzbl %dl,%esi + movl 4(%esp),%edx + xorl %ecx,%ebx + xorl 2052(%ebp,%esi,8),%eax + movl -24(%edi),%esi + xorl %eax,%ebx + movl %ebx,8(%esp) + xorl %edx,%eax + movl %eax,4(%esp) + xorl %esi,%eax + xorl -20(%edi),%ebx + movzbl %ah,%esi + movl 2052(%ebp,%esi,8),%edx + movzbl %al,%esi + xorl 4(%ebp,%esi,8),%edx + shrl $16,%eax + movzbl %bl,%esi + movl (%ebp,%esi,8),%ecx + movzbl %ah,%esi + xorl (%ebp,%esi,8),%edx + movzbl %bh,%esi + xorl 4(%ebp,%esi,8),%ecx + shrl $16,%ebx + movzbl %al,%eax + xorl 2048(%ebp,%eax,8),%edx + movzbl %bh,%esi + movl 16(%esp),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl 2048(%ebp,%esi,8),%ecx + movzbl %bl,%esi + movl 12(%esp),%ebx + xorl %eax,%edx + xorl 2052(%ebp,%esi,8),%ecx + movl -32(%edi),%esi + xorl %ecx,%edx + movl %edx,16(%esp) + xorl %ebx,%ecx + movl %ecx,12(%esp) + xorl %esi,%ecx + xorl -28(%edi),%edx + movzbl %ch,%esi + movl 2052(%ebp,%esi,8),%ebx + movzbl %cl,%esi + xorl 4(%ebp,%esi,8),%ebx + shrl $16,%ecx + movzbl %dl,%esi + movl (%ebp,%esi,8),%eax + movzbl %ch,%esi + xorl (%ebp,%esi,8),%ebx + movzbl %dh,%esi + xorl 4(%ebp,%esi,8),%eax + shrl $16,%edx + movzbl %cl,%ecx + xorl 2048(%ebp,%ecx,8),%ebx + movzbl %dh,%esi + movl 8(%esp),%ecx + xorl %ebx,%eax + rorl $8,%ebx + xorl 2048(%ebp,%esi,8),%eax + movzbl %dl,%esi + movl 4(%esp),%edx + xorl %ecx,%ebx + xorl 2052(%ebp,%esi,8),%eax + movl -40(%edi),%esi + xorl %eax,%ebx + movl %ebx,8(%esp) + xorl %edx,%eax + movl %eax,4(%esp) + xorl %esi,%eax + xorl -36(%edi),%ebx + movzbl %ah,%esi + movl 2052(%ebp,%esi,8),%edx + movzbl %al,%esi + xorl 4(%ebp,%esi,8),%edx + shrl $16,%eax + movzbl %bl,%esi + movl (%ebp,%esi,8),%ecx + movzbl %ah,%esi + xorl (%ebp,%esi,8),%edx + movzbl %bh,%esi + xorl 4(%ebp,%esi,8),%ecx + shrl $16,%ebx + movzbl %al,%eax + xorl 2048(%ebp,%eax,8),%edx + movzbl %bh,%esi + movl 16(%esp),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl 2048(%ebp,%esi,8),%ecx + movzbl %bl,%esi + movl 12(%esp),%ebx + xorl %eax,%edx + xorl 2052(%ebp,%esi,8),%ecx + movl -48(%edi),%esi + xorl %ecx,%edx + movl %edx,16(%esp) + xorl %ebx,%ecx + movl %ecx,12(%esp) + xorl %esi,%ecx + xorl -44(%edi),%edx + movzbl %ch,%esi + movl 2052(%ebp,%esi,8),%ebx + movzbl %cl,%esi + xorl 4(%ebp,%esi,8),%ebx + shrl $16,%ecx + movzbl %dl,%esi + movl (%ebp,%esi,8),%eax + movzbl %ch,%esi + xorl (%ebp,%esi,8),%ebx + movzbl %dh,%esi + xorl 4(%ebp,%esi,8),%eax + shrl $16,%edx + movzbl %cl,%ecx + xorl 2048(%ebp,%ecx,8),%ebx + movzbl %dh,%esi + movl 8(%esp),%ecx + xorl %ebx,%eax + rorl $8,%ebx + xorl 2048(%ebp,%esi,8),%eax + movzbl %dl,%esi + movl 4(%esp),%edx + xorl %ecx,%ebx + xorl 2052(%ebp,%esi,8),%eax + movl -56(%edi),%esi + xorl %eax,%ebx + movl %ebx,8(%esp) + xorl %edx,%eax + movl %eax,4(%esp) + subl $64,%edi + cmpl 20(%esp),%edi + je .L007done + andl %eax,%esi + movl 16(%esp),%edx + roll $1,%esi + movl %edx,%ecx + xorl %esi,%ebx + orl 4(%edi),%ecx + movl %ebx,8(%esp) + xorl 12(%esp),%ecx + movl 12(%edi),%esi + movl %ecx,12(%esp) + orl %ebx,%esi + andl (%edi),%ecx + xorl %esi,%eax + roll $1,%ecx + movl %eax,4(%esp) + xorl %ecx,%edx + movl -8(%edi),%esi + movl %edx,16(%esp) + jmp .L006loop +.align 8 +.L007done: + movl %eax,%ecx + movl %ebx,%edx + movl 12(%esp),%eax + movl 16(%esp),%ebx + xorl %esi,%ecx + xorl 12(%edi),%edx + xorl (%edi),%eax + xorl 4(%edi),%ebx + ret +.size _x86_Camellia_decrypt,.-_x86_Camellia_decrypt +.globl Camellia_Ekeygen +.type Camellia_Ekeygen,@function +.align 16 +Camellia_Ekeygen: +.L_Camellia_Ekeygen_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + subl $16,%esp + movl 36(%esp),%ebp + movl 40(%esp),%esi + movl 44(%esp),%edi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + cmpl $128,%ebp + je .L0081st128 + movl 16(%esi),%eax + movl 20(%esi),%ebx + cmpl $192,%ebp + je .L0091st192 + movl 24(%esi),%ecx + movl 28(%esi),%edx + jmp .L0101st256 +.align 4 +.L0091st192: + movl %eax,%ecx + movl %ebx,%edx + notl %ecx + notl %edx +.align 4 +.L0101st256: + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,32(%edi) + movl %ebx,36(%edi) + movl %ecx,40(%edi) + movl %edx,44(%edi) + xorl (%edi),%eax + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx +.align 4 +.L0081st128: + call .L011pic_point +.L011pic_point: + popl %ebp + leal .LCamellia_SBOX-.L011pic_point(%ebp),%ebp + leal .LCamellia_SIGMA-.LCamellia_SBOX(%ebp),%edi + movl (%edi),%esi + movl %eax,(%esp) + movl %ebx,4(%esp) + movl %ecx,8(%esp) + movl %edx,12(%esp) + xorl %esi,%eax + xorl 4(%edi),%ebx + movzbl %ah,%esi + movl 2052(%ebp,%esi,8),%edx + movzbl %al,%esi + xorl 4(%ebp,%esi,8),%edx + shrl $16,%eax + movzbl %bl,%esi + movl (%ebp,%esi,8),%ecx + movzbl %ah,%esi + xorl (%ebp,%esi,8),%edx + movzbl %bh,%esi + xorl 4(%ebp,%esi,8),%ecx + shrl $16,%ebx + movzbl %al,%eax + xorl 2048(%ebp,%eax,8),%edx + movzbl %bh,%esi + movl 12(%esp),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl 2048(%ebp,%esi,8),%ecx + movzbl %bl,%esi + movl 8(%esp),%ebx + xorl %eax,%edx + xorl 2052(%ebp,%esi,8),%ecx + movl 8(%edi),%esi + xorl %ecx,%edx + movl %edx,12(%esp) + xorl %ebx,%ecx + movl %ecx,8(%esp) + xorl %esi,%ecx + xorl 12(%edi),%edx + movzbl %ch,%esi + movl 2052(%ebp,%esi,8),%ebx + movzbl %cl,%esi + xorl 4(%ebp,%esi,8),%ebx + shrl $16,%ecx + movzbl %dl,%esi + movl (%ebp,%esi,8),%eax + movzbl %ch,%esi + xorl (%ebp,%esi,8),%ebx + movzbl %dh,%esi + xorl 4(%ebp,%esi,8),%eax + shrl $16,%edx + movzbl %cl,%ecx + xorl 2048(%ebp,%ecx,8),%ebx + movzbl %dh,%esi + movl 4(%esp),%ecx + xorl %ebx,%eax + rorl $8,%ebx + xorl 2048(%ebp,%esi,8),%eax + movzbl %dl,%esi + movl (%esp),%edx + xorl %ecx,%ebx + xorl 2052(%ebp,%esi,8),%eax + movl 16(%edi),%esi + xorl %eax,%ebx + movl %ebx,4(%esp) + xorl %edx,%eax + movl %eax,(%esp) + movl 8(%esp),%ecx + movl 12(%esp),%edx + movl 44(%esp),%esi + xorl (%esi),%eax + xorl 4(%esi),%ebx + xorl 8(%esi),%ecx + xorl 12(%esi),%edx + movl 16(%edi),%esi + movl %eax,(%esp) + movl %ebx,4(%esp) + movl %ecx,8(%esp) + movl %edx,12(%esp) + xorl %esi,%eax + xorl 20(%edi),%ebx + movzbl %ah,%esi + movl 2052(%ebp,%esi,8),%edx + movzbl %al,%esi + xorl 4(%ebp,%esi,8),%edx + shrl $16,%eax + movzbl %bl,%esi + movl (%ebp,%esi,8),%ecx + movzbl %ah,%esi + xorl (%ebp,%esi,8),%edx + movzbl %bh,%esi + xorl 4(%ebp,%esi,8),%ecx + shrl $16,%ebx + movzbl %al,%eax + xorl 2048(%ebp,%eax,8),%edx + movzbl %bh,%esi + movl 12(%esp),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl 2048(%ebp,%esi,8),%ecx + movzbl %bl,%esi + movl 8(%esp),%ebx + xorl %eax,%edx + xorl 2052(%ebp,%esi,8),%ecx + movl 24(%edi),%esi + xorl %ecx,%edx + movl %edx,12(%esp) + xorl %ebx,%ecx + movl %ecx,8(%esp) + xorl %esi,%ecx + xorl 28(%edi),%edx + movzbl %ch,%esi + movl 2052(%ebp,%esi,8),%ebx + movzbl %cl,%esi + xorl 4(%ebp,%esi,8),%ebx + shrl $16,%ecx + movzbl %dl,%esi + movl (%ebp,%esi,8),%eax + movzbl %ch,%esi + xorl (%ebp,%esi,8),%ebx + movzbl %dh,%esi + xorl 4(%ebp,%esi,8),%eax + shrl $16,%edx + movzbl %cl,%ecx + xorl 2048(%ebp,%ecx,8),%ebx + movzbl %dh,%esi + movl 4(%esp),%ecx + xorl %ebx,%eax + rorl $8,%ebx + xorl 2048(%ebp,%esi,8),%eax + movzbl %dl,%esi + movl (%esp),%edx + xorl %ecx,%ebx + xorl 2052(%ebp,%esi,8),%eax + movl 32(%edi),%esi + xorl %eax,%ebx + movl %ebx,4(%esp) + xorl %edx,%eax + movl %eax,(%esp) + movl 8(%esp),%ecx + movl 12(%esp),%edx + movl 36(%esp),%esi + cmpl $128,%esi + jne .L0122nd256 + movl 44(%esp),%edi + leal 128(%edi),%edi + movl %eax,-112(%edi) + movl %ebx,-108(%edi) + movl %ecx,-104(%edi) + movl %edx,-100(%edi) + movl %eax,%ebp + shll $15,%eax + movl %ebx,%esi + shrl $17,%esi + shll $15,%ebx + orl %esi,%eax + movl %ecx,%esi + shll $15,%ecx + movl %eax,-80(%edi) + shrl $17,%esi + orl %esi,%ebx + shrl $17,%ebp + movl %edx,%esi + shrl $17,%esi + movl %ebx,-76(%edi) + shll $15,%edx + orl %esi,%ecx + orl %ebp,%edx + movl %ecx,-72(%edi) + movl %edx,-68(%edi) + movl %eax,%ebp + shll $15,%eax + movl %ebx,%esi + shrl $17,%esi + shll $15,%ebx + orl %esi,%eax + movl %ecx,%esi + shll $15,%ecx + movl %eax,-64(%edi) + shrl $17,%esi + orl %esi,%ebx + shrl $17,%ebp + movl %edx,%esi + shrl $17,%esi + movl %ebx,-60(%edi) + shll $15,%edx + orl %esi,%ecx + orl %ebp,%edx + movl %ecx,-56(%edi) + movl %edx,-52(%edi) + movl %eax,%ebp + shll $15,%eax + movl %ebx,%esi + shrl $17,%esi + shll $15,%ebx + orl %esi,%eax + movl %ecx,%esi + shll $15,%ecx + movl %eax,-32(%edi) + shrl $17,%esi + orl %esi,%ebx + shrl $17,%ebp + movl %edx,%esi + shrl $17,%esi + movl %ebx,-28(%edi) + shll $15,%edx + orl %esi,%ecx + orl %ebp,%edx + movl %eax,%ebp + shll $15,%eax + movl %ebx,%esi + shrl $17,%esi + shll $15,%ebx + orl %esi,%eax + movl %ecx,%esi + shll $15,%ecx + movl %eax,-16(%edi) + shrl $17,%esi + orl %esi,%ebx + shrl $17,%ebp + movl %edx,%esi + shrl $17,%esi + movl %ebx,-12(%edi) + shll $15,%edx + orl %esi,%ecx + orl %ebp,%edx + movl %ecx,-8(%edi) + movl %edx,-4(%edi) + movl %ebx,%ebp + shll $2,%ebx + movl %ecx,%esi + shrl $30,%esi + shll $2,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $2,%edx + movl %ebx,32(%edi) + shrl $30,%esi + orl %esi,%ecx + shrl $30,%ebp + movl %eax,%esi + shrl $30,%esi + movl %ecx,36(%edi) + shll $2,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,40(%edi) + movl %eax,44(%edi) + movl %ebx,%ebp + shll $17,%ebx + movl %ecx,%esi + shrl $15,%esi + shll $17,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $17,%edx + movl %ebx,64(%edi) + shrl $15,%esi + orl %esi,%ecx + shrl $15,%ebp + movl %eax,%esi + shrl $15,%esi + movl %ecx,68(%edi) + shll $17,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,72(%edi) + movl %eax,76(%edi) + movl -128(%edi),%ebx + movl -124(%edi),%ecx + movl -120(%edi),%edx + movl -116(%edi),%eax + movl %ebx,%ebp + shll $15,%ebx + movl %ecx,%esi + shrl $17,%esi + shll $15,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $15,%edx + movl %ebx,-96(%edi) + shrl $17,%esi + orl %esi,%ecx + shrl $17,%ebp + movl %eax,%esi + shrl $17,%esi + movl %ecx,-92(%edi) + shll $15,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,-88(%edi) + movl %eax,-84(%edi) + movl %ebx,%ebp + shll $30,%ebx + movl %ecx,%esi + shrl $2,%esi + shll $30,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $30,%edx + movl %ebx,-48(%edi) + shrl $2,%esi + orl %esi,%ecx + shrl $2,%ebp + movl %eax,%esi + shrl $2,%esi + movl %ecx,-44(%edi) + shll $30,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,-40(%edi) + movl %eax,-36(%edi) + movl %ebx,%ebp + shll $15,%ebx + movl %ecx,%esi + shrl $17,%esi + shll $15,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $15,%edx + shrl $17,%esi + orl %esi,%ecx + shrl $17,%ebp + movl %eax,%esi + shrl $17,%esi + shll $15,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,-24(%edi) + movl %eax,-20(%edi) + movl %ebx,%ebp + shll $17,%ebx + movl %ecx,%esi + shrl $15,%esi + shll $17,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $17,%edx + movl %ebx,(%edi) + shrl $15,%esi + orl %esi,%ecx + shrl $15,%ebp + movl %eax,%esi + shrl $15,%esi + movl %ecx,4(%edi) + shll $17,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,8(%edi) + movl %eax,12(%edi) + movl %ebx,%ebp + shll $17,%ebx + movl %ecx,%esi + shrl $15,%esi + shll $17,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $17,%edx + movl %ebx,16(%edi) + shrl $15,%esi + orl %esi,%ecx + shrl $15,%ebp + movl %eax,%esi + shrl $15,%esi + movl %ecx,20(%edi) + shll $17,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,24(%edi) + movl %eax,28(%edi) + movl %ebx,%ebp + shll $17,%ebx + movl %ecx,%esi + shrl $15,%esi + shll $17,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $17,%edx + movl %ebx,48(%edi) + shrl $15,%esi + orl %esi,%ecx + shrl $15,%ebp + movl %eax,%esi + shrl $15,%esi + movl %ecx,52(%edi) + shll $17,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,56(%edi) + movl %eax,60(%edi) + movl $3,%eax + jmp .L013done +.align 16 +.L0122nd256: + movl 44(%esp),%esi + movl %eax,48(%esi) + movl %ebx,52(%esi) + movl %ecx,56(%esi) + movl %edx,60(%esi) + xorl 32(%esi),%eax + xorl 36(%esi),%ebx + xorl 40(%esi),%ecx + xorl 44(%esi),%edx + movl 32(%edi),%esi + movl %eax,(%esp) + movl %ebx,4(%esp) + movl %ecx,8(%esp) + movl %edx,12(%esp) + xorl %esi,%eax + xorl 36(%edi),%ebx + movzbl %ah,%esi + movl 2052(%ebp,%esi,8),%edx + movzbl %al,%esi + xorl 4(%ebp,%esi,8),%edx + shrl $16,%eax + movzbl %bl,%esi + movl (%ebp,%esi,8),%ecx + movzbl %ah,%esi + xorl (%ebp,%esi,8),%edx + movzbl %bh,%esi + xorl 4(%ebp,%esi,8),%ecx + shrl $16,%ebx + movzbl %al,%eax + xorl 2048(%ebp,%eax,8),%edx + movzbl %bh,%esi + movl 12(%esp),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl 2048(%ebp,%esi,8),%ecx + movzbl %bl,%esi + movl 8(%esp),%ebx + xorl %eax,%edx + xorl 2052(%ebp,%esi,8),%ecx + movl 40(%edi),%esi + xorl %ecx,%edx + movl %edx,12(%esp) + xorl %ebx,%ecx + movl %ecx,8(%esp) + xorl %esi,%ecx + xorl 44(%edi),%edx + movzbl %ch,%esi + movl 2052(%ebp,%esi,8),%ebx + movzbl %cl,%esi + xorl 4(%ebp,%esi,8),%ebx + shrl $16,%ecx + movzbl %dl,%esi + movl (%ebp,%esi,8),%eax + movzbl %ch,%esi + xorl (%ebp,%esi,8),%ebx + movzbl %dh,%esi + xorl 4(%ebp,%esi,8),%eax + shrl $16,%edx + movzbl %cl,%ecx + xorl 2048(%ebp,%ecx,8),%ebx + movzbl %dh,%esi + movl 4(%esp),%ecx + xorl %ebx,%eax + rorl $8,%ebx + xorl 2048(%ebp,%esi,8),%eax + movzbl %dl,%esi + movl (%esp),%edx + xorl %ecx,%ebx + xorl 2052(%ebp,%esi,8),%eax + movl 48(%edi),%esi + xorl %eax,%ebx + movl %ebx,4(%esp) + xorl %edx,%eax + movl %eax,(%esp) + movl 8(%esp),%ecx + movl 12(%esp),%edx + movl 44(%esp),%edi + leal 128(%edi),%edi + movl %eax,-112(%edi) + movl %ebx,-108(%edi) + movl %ecx,-104(%edi) + movl %edx,-100(%edi) + movl %eax,%ebp + shll $30,%eax + movl %ebx,%esi + shrl $2,%esi + shll $30,%ebx + orl %esi,%eax + movl %ecx,%esi + shll $30,%ecx + movl %eax,-48(%edi) + shrl $2,%esi + orl %esi,%ebx + shrl $2,%ebp + movl %edx,%esi + shrl $2,%esi + movl %ebx,-44(%edi) + shll $30,%edx + orl %esi,%ecx + orl %ebp,%edx + movl %ecx,-40(%edi) + movl %edx,-36(%edi) + movl %eax,%ebp + shll $30,%eax + movl %ebx,%esi + shrl $2,%esi + shll $30,%ebx + orl %esi,%eax + movl %ecx,%esi + shll $30,%ecx + movl %eax,32(%edi) + shrl $2,%esi + orl %esi,%ebx + shrl $2,%ebp + movl %edx,%esi + shrl $2,%esi + movl %ebx,36(%edi) + shll $30,%edx + orl %esi,%ecx + orl %ebp,%edx + movl %ecx,40(%edi) + movl %edx,44(%edi) + movl %ebx,%ebp + shll $19,%ebx + movl %ecx,%esi + shrl $13,%esi + shll $19,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $19,%edx + movl %ebx,128(%edi) + shrl $13,%esi + orl %esi,%ecx + shrl $13,%ebp + movl %eax,%esi + shrl $13,%esi + movl %ecx,132(%edi) + shll $19,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,136(%edi) + movl %eax,140(%edi) + movl -96(%edi),%ebx + movl -92(%edi),%ecx + movl -88(%edi),%edx + movl -84(%edi),%eax + movl %ebx,%ebp + shll $15,%ebx + movl %ecx,%esi + shrl $17,%esi + shll $15,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $15,%edx + movl %ebx,-96(%edi) + shrl $17,%esi + orl %esi,%ecx + shrl $17,%ebp + movl %eax,%esi + shrl $17,%esi + movl %ecx,-92(%edi) + shll $15,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,-88(%edi) + movl %eax,-84(%edi) + movl %ebx,%ebp + shll $15,%ebx + movl %ecx,%esi + shrl $17,%esi + shll $15,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $15,%edx + movl %ebx,-64(%edi) + shrl $17,%esi + orl %esi,%ecx + shrl $17,%ebp + movl %eax,%esi + shrl $17,%esi + movl %ecx,-60(%edi) + shll $15,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,-56(%edi) + movl %eax,-52(%edi) + movl %ebx,%ebp + shll $30,%ebx + movl %ecx,%esi + shrl $2,%esi + shll $30,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $30,%edx + movl %ebx,16(%edi) + shrl $2,%esi + orl %esi,%ecx + shrl $2,%ebp + movl %eax,%esi + shrl $2,%esi + movl %ecx,20(%edi) + shll $30,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,24(%edi) + movl %eax,28(%edi) + movl %ecx,%ebp + shll $2,%ecx + movl %edx,%esi + shrl $30,%esi + shll $2,%edx + orl %esi,%ecx + movl %eax,%esi + shll $2,%eax + movl %ecx,80(%edi) + shrl $30,%esi + orl %esi,%edx + shrl $30,%ebp + movl %ebx,%esi + shrl $30,%esi + movl %edx,84(%edi) + shll $2,%ebx + orl %esi,%eax + orl %ebp,%ebx + movl %eax,88(%edi) + movl %ebx,92(%edi) + movl -80(%edi),%ecx + movl -76(%edi),%edx + movl -72(%edi),%eax + movl -68(%edi),%ebx + movl %ecx,%ebp + shll $15,%ecx + movl %edx,%esi + shrl $17,%esi + shll $15,%edx + orl %esi,%ecx + movl %eax,%esi + shll $15,%eax + movl %ecx,-80(%edi) + shrl $17,%esi + orl %esi,%edx + shrl $17,%ebp + movl %ebx,%esi + shrl $17,%esi + movl %edx,-76(%edi) + shll $15,%ebx + orl %esi,%eax + orl %ebp,%ebx + movl %eax,-72(%edi) + movl %ebx,-68(%edi) + movl %ecx,%ebp + shll $30,%ecx + movl %edx,%esi + shrl $2,%esi + shll $30,%edx + orl %esi,%ecx + movl %eax,%esi + shll $30,%eax + movl %ecx,-16(%edi) + shrl $2,%esi + orl %esi,%edx + shrl $2,%ebp + movl %ebx,%esi + shrl $2,%esi + movl %edx,-12(%edi) + shll $30,%ebx + orl %esi,%eax + orl %ebp,%ebx + movl %eax,-8(%edi) + movl %ebx,-4(%edi) + movl %edx,64(%edi) + movl %eax,68(%edi) + movl %ebx,72(%edi) + movl %ecx,76(%edi) + movl %edx,%ebp + shll $17,%edx + movl %eax,%esi + shrl $15,%esi + shll $17,%eax + orl %esi,%edx + movl %ebx,%esi + shll $17,%ebx + movl %edx,96(%edi) + shrl $15,%esi + orl %esi,%eax + shrl $15,%ebp + movl %ecx,%esi + shrl $15,%esi + movl %eax,100(%edi) + shll $17,%ecx + orl %esi,%ebx + orl %ebp,%ecx + movl %ebx,104(%edi) + movl %ecx,108(%edi) + movl -128(%edi),%edx + movl -124(%edi),%eax + movl -120(%edi),%ebx + movl -116(%edi),%ecx + movl %eax,%ebp + shll $13,%eax + movl %ebx,%esi + shrl $19,%esi + shll $13,%ebx + orl %esi,%eax + movl %ecx,%esi + shll $13,%ecx + movl %eax,-32(%edi) + shrl $19,%esi + orl %esi,%ebx + shrl $19,%ebp + movl %edx,%esi + shrl $19,%esi + movl %ebx,-28(%edi) + shll $13,%edx + orl %esi,%ecx + orl %ebp,%edx + movl %ecx,-24(%edi) + movl %edx,-20(%edi) + movl %eax,%ebp + shll $15,%eax + movl %ebx,%esi + shrl $17,%esi + shll $15,%ebx + orl %esi,%eax + movl %ecx,%esi + shll $15,%ecx + movl %eax,(%edi) + shrl $17,%esi + orl %esi,%ebx + shrl $17,%ebp + movl %edx,%esi + shrl $17,%esi + movl %ebx,4(%edi) + shll $15,%edx + orl %esi,%ecx + orl %ebp,%edx + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl %eax,%ebp + shll $17,%eax + movl %ebx,%esi + shrl $15,%esi + shll $17,%ebx + orl %esi,%eax + movl %ecx,%esi + shll $17,%ecx + movl %eax,48(%edi) + shrl $15,%esi + orl %esi,%ebx + shrl $15,%ebp + movl %edx,%esi + shrl $15,%esi + movl %ebx,52(%edi) + shll $17,%edx + orl %esi,%ecx + orl %ebp,%edx + movl %ecx,56(%edi) + movl %edx,60(%edi) + movl %ebx,%ebp + shll $2,%ebx + movl %ecx,%esi + shrl $30,%esi + shll $2,%ecx + orl %esi,%ebx + movl %edx,%esi + shll $2,%edx + movl %ebx,112(%edi) + shrl $30,%esi + orl %esi,%ecx + shrl $30,%ebp + movl %eax,%esi + shrl $30,%esi + movl %ecx,116(%edi) + shll $2,%eax + orl %esi,%edx + orl %ebp,%eax + movl %edx,120(%edi) + movl %eax,124(%edi) + movl $4,%eax +.L013done: + leal 144(%edi),%edx + addl $16,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size Camellia_Ekeygen,.-.L_Camellia_Ekeygen_begin +.globl Camellia_set_key +.type Camellia_set_key,@function +.align 16 +Camellia_set_key: +.L_Camellia_set_key_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebx + movl 8(%esp),%ecx + movl 12(%esp),%ebx + movl 16(%esp),%edx + movl $-1,%eax + testl %ecx,%ecx + jz .L014done + testl %edx,%edx + jz .L014done + movl $-2,%eax + cmpl $256,%ebx + je .L015arg_ok + cmpl $192,%ebx + je .L015arg_ok + cmpl $128,%ebx + jne .L014done +.align 4 +.L015arg_ok: + pushl %edx + pushl %ecx + pushl %ebx + call .L_Camellia_Ekeygen_begin + addl $12,%esp + movl %eax,(%edx) + xorl %eax,%eax +.align 4 +.L014done: + popl %ebx + ret +.size Camellia_set_key,.-.L_Camellia_set_key_begin +.align 64 +.LCamellia_SIGMA: +.long 2694735487,1003262091,3061508184,1286239154,3337565999,3914302142,1426019237,4057165596,283453434,3731369245,2958461122,3018244605,0,0,0,0 +.align 64 +.LCamellia_SBOX: +.long 1886416896,1886388336 +.long 2189591040,741081132 +.long 741092352,3014852787 +.long 3974949888,3233808576 +.long 3014898432,3840147684 +.long 656877312,1465319511 +.long 3233857536,3941204202 +.long 3857048832,2930639022 +.long 3840205824,589496355 +.long 2240120064,1802174571 +.long 1465341696,1162149957 +.long 892679424,2779054245 +.long 3941263872,3991732461 +.long 202116096,1330577487 +.long 2930683392,488439837 +.long 1094795520,2459041938 +.long 589505280,2256928902 +.long 4025478912,2947481775 +.long 1802201856,2088501372 +.long 2475922176,522125343 +.long 1162167552,1044250686 +.long 421075200,3705405660 +.long 2779096320,1583218782 +.long 555819264,185270283 +.long 3991792896,2795896998 +.long 235802112,960036921 +.long 1330597632,3587506389 +.long 1313754624,1566376029 +.long 488447232,3654877401 +.long 1701143808,1515847770 +.long 2459079168,1364262993 +.long 3183328512,1819017324 +.long 2256963072,2341142667 +.long 3099113472,2593783962 +.long 2947526400,4227531003 +.long 2408550144,2964324528 +.long 2088532992,1953759348 +.long 3958106880,724238379 +.long 522133248,4042260720 +.long 3469659648,2223243396 +.long 1044266496,3755933919 +.long 808464384,3419078859 +.long 3705461760,875823156 +.long 1600085760,1987444854 +.long 1583242752,1835860077 +.long 3318072576,2846425257 +.long 185273088,3520135377 +.long 437918208,67371012 +.long 2795939328,336855060 +.long 3789676800,976879674 +.long 960051456,3739091166 +.long 3402287616,286326801 +.long 3587560704,842137650 +.long 1195853568,2627469468 +.long 1566399744,1397948499 +.long 1027423488,4075946226 +.long 3654932736,4278059262 +.long 16843008,3486449871 +.long 1515870720,3284336835 +.long 3604403712,2054815866 +.long 1364283648,606339108 +.long 1448498688,3907518696 +.long 1819044864,1616904288 +.long 1296911616,1768489065 +.long 2341178112,2863268010 +.long 218959104,2694840480 +.long 2593823232,2711683233 +.long 1717986816,1650589794 +.long 4227595008,1414791252 +.long 3435973632,505282590 +.long 2964369408,3772776672 +.long 757935360,1684275300 +.long 1953788928,269484048 +.long 303174144,0 +.long 724249344,2745368739 +.long 538976256,1970602101 +.long 4042321920,2324299914 +.long 2981212416,3873833190 +.long 2223277056,151584777 +.long 2576980224,3722248413 +.long 3755990784,2273771655 +.long 1280068608,2206400643 +.long 3419130624,3452764365 +.long 3267543552,2425356432 +.long 875836416,1936916595 +.long 2122219008,4143317238 +.long 1987474944,2644312221 +.long 84215040,3216965823 +.long 1835887872,1381105746 +.long 3082270464,3638034648 +.long 2846468352,3368550600 +.long 825307392,3334865094 +.long 3520188672,2172715137 +.long 387389184,1869545583 +.long 67372032,320012307 +.long 3621246720,1667432547 +.long 336860160,3924361449 +.long 1482184704,2812739751 +.long 976894464,2677997727 +.long 1633771776,3166437564 +.long 3739147776,690552873 +.long 454761216,4193845497 +.long 286331136,791609391 +.long 471604224,3031695540 +.long 842150400,2021130360 +.long 252645120,101056518 +.long 2627509248,3890675943 +.long 370546176,1903231089 +.long 1397969664,3570663636 +.long 404232192,2880110763 +.long 4076007936,2290614408 +.long 572662272,2374828173 +.long 4278124032,1920073842 +.long 1145324544,3115909305 +.long 3486502656,4177002744 +.long 2998055424,2896953516 +.long 3284386560,909508662 +.long 3048584448,707395626 +.long 2054846976,1010565180 +.long 2442236160,4059103473 +.long 606348288,1077936192 +.long 134744064,3553820883 +.long 3907577856,3149594811 +.long 2829625344,1128464451 +.long 1616928768,353697813 +.long 4244438016,2913796269 +.long 1768515840,2004287607 +.long 1347440640,2155872384 +.long 2863311360,2189557890 +.long 3503345664,3974889708 +.long 2694881280,656867367 +.long 2105376000,3856990437 +.long 2711724288,2240086149 +.long 2307492096,892665909 +.long 1650614784,202113036 +.long 2543294208,1094778945 +.long 1414812672,4025417967 +.long 1532713728,2475884691 +.long 505290240,421068825 +.long 2509608192,555810849 +.long 3772833792,235798542 +.long 4294967040,1313734734 +.long 1684300800,1701118053 +.long 3537031680,3183280317 +.long 269488128,3099066552 +.long 3301229568,2408513679 +.long 0,3958046955 +.long 1212696576,3469607118 +.long 2745410304,808452144 +.long 4160222976,1600061535 +.long 1970631936,3318022341 +.long 3688618752,437911578 +.long 2324335104,3789619425 +.long 50529024,3402236106 +.long 3873891840,1195835463 +.long 3671775744,1027407933 +.long 151587072,16842753 +.long 1061109504,3604349142 +.long 3722304768,1448476758 +.long 2492765184,1296891981 +.long 2273806080,218955789 +.long 1549556736,1717960806 +.long 2206434048,3435921612 +.long 33686016,757923885 +.long 3452816640,303169554 +.long 1246382592,538968096 +.long 2425393152,2981167281 +.long 858993408,2576941209 +.long 1936945920,1280049228 +.long 1734829824,3267494082 +.long 4143379968,2122186878 +.long 4092850944,84213765 +.long 2644352256,3082223799 +.long 2139062016,825294897 +.long 3217014528,387383319 +.long 3806519808,3621191895 +.long 1381126656,1482162264 +.long 2610666240,1633747041 +.long 3638089728,454754331 +.long 640034304,471597084 +.long 3368601600,252641295 +.long 926365440,370540566 +.long 3334915584,404226072 +.long 993737472,572653602 +.long 2172748032,1145307204 +.long 2526451200,2998010034 +.long 1869573888,3048538293 +.long 1263225600,2442199185 +.long 320017152,134742024 +.long 3200171520,2829582504 +.long 1667457792,4244373756 +.long 774778368,1347420240 +.long 3924420864,3503292624 +.long 2038003968,2105344125 +.long 2812782336,2307457161 +.long 2358021120,2543255703 +.long 2678038272,1532690523 +.long 1852730880,2509570197 +.long 3166485504,4294902015 +.long 2391707136,3536978130 +.long 690563328,3301179588 +.long 4126536960,1212678216 +.long 4193908992,4160159991 +.long 3065427456,3688562907 +.long 791621376,50528259 +.long 4261281024,3671720154 +.long 3031741440,1061093439 +.long 1499027712,2492727444 +.long 2021160960,1549533276 +.long 2560137216,33685506 +.long 101058048,1246363722 +.long 1785358848,858980403 +.long 3890734848,1734803559 +.long 1179010560,4092788979 +.long 1903259904,2139029631 +.long 3132799488,3806462178 +.long 3570717696,2610626715 +.long 623191296,640024614 +.long 2880154368,926351415 +.long 1111638528,993722427 +.long 2290649088,2526412950 +.long 2728567296,1263206475 +.long 2374864128,3200123070 +.long 4210752000,774766638 +.long 1920102912,2037973113 +.long 117901056,2357985420 +.long 3115956480,1852702830 +.long 1431655680,2391670926 +.long 4177065984,4126474485 +.long 4008635904,3065381046 +.long 2896997376,4261216509 +.long 168430080,1499005017 +.long 909522432,2560098456 +.long 1229539584,1785331818 +.long 707406336,1178992710 +.long 1751672832,3132752058 +.long 1010580480,623181861 +.long 943208448,1111621698 +.long 4059164928,2728525986 +.long 2762253312,4210688250 +.long 1077952512,117899271 +.long 673720320,1431634005 +.long 3553874688,4008575214 +.long 2071689984,168427530 +.long 3149642496,1229520969 +.long 3385444608,1751646312 +.long 1128481536,943194168 +.long 3250700544,2762211492 +.long 353703168,673710120 +.long 3823362816,2071658619 +.long 2913840384,3385393353 +.long 4109693952,3250651329 +.long 2004317952,3823304931 +.long 3351758592,4109631732 +.long 2155905024,3351707847 +.long 2661195264,2661154974 +.long 14737632,939538488 +.long 328965,1090535745 +.long 5789784,369104406 +.long 14277081,1979741814 +.long 6776679,3640711641 +.long 5131854,2466288531 +.long 8487297,1610637408 +.long 13355979,4060148466 +.long 13224393,1912631922 +.long 723723,3254829762 +.long 11447982,2868947883 +.long 6974058,2583730842 +.long 14013909,1962964341 +.long 1579032,100664838 +.long 6118749,1459640151 +.long 8553090,2684395680 +.long 4605510,2432733585 +.long 14671839,4144035831 +.long 14079702,3036722613 +.long 2565927,3372272073 +.long 9079434,2717950626 +.long 3289650,2348846220 +.long 4934475,3523269330 +.long 4342338,2415956112 +.long 14408667,4127258358 +.long 1842204,117442311 +.long 10395294,2801837991 +.long 10263708,654321447 +.long 3815994,2382401166 +.long 13290186,2986390194 +.long 2434341,1224755529 +.long 8092539,3724599006 +.long 855309,1124090691 +.long 7434609,1543527516 +.long 6250335,3607156695 +.long 2039583,3338717127 +.long 16316664,1040203326 +.long 14145495,4110480885 +.long 4079166,2399178639 +.long 10329501,1728079719 +.long 8158332,520101663 +.long 6316128,402659352 +.long 12171705,1845522030 +.long 12500670,2936057775 +.long 12369084,788541231 +.long 9145227,3791708898 +.long 1447446,2231403909 +.long 3421236,218107149 +.long 5066061,1392530259 +.long 12829635,4026593520 +.long 7500402,2617285788 +.long 9803157,1694524773 +.long 11250603,3925928682 +.long 9342606,2734728099 +.long 12237498,2919280302 +.long 8026746,2650840734 +.long 11776947,3959483628 +.long 131586,2147516544 +.long 11842740,754986285 +.long 11382189,1795189611 +.long 10658466,2818615464 +.long 11316396,721431339 +.long 14211288,905983542 +.long 10132122,2785060518 +.long 1513239,3305162181 +.long 1710618,2248181382 +.long 3487029,1291865421 +.long 13421772,855651123 +.long 16250871,4244700669 +.long 10066329,1711302246 +.long 6381921,1476417624 +.long 5921370,2516620950 +.long 15263976,973093434 +.long 2368548,150997257 +.long 5658198,2499843477 +.long 4210752,268439568 +.long 14803425,2013296760 +.long 6513507,3623934168 +.long 592137,1107313218 +.long 3355443,3422604492 +.long 12566463,4009816047 +.long 10000536,637543974 +.long 9934743,3842041317 +.long 8750469,1627414881 +.long 6842472,436214298 +.long 16579836,1056980799 +.long 15527148,989870907 +.long 657930,2181071490 +.long 14342874,3053500086 +.long 7303023,3674266587 +.long 5460819,3556824276 +.long 6447714,2550175896 +.long 10724259,3892373736 +.long 3026478,2332068747 +.long 526344,33554946 +.long 11513775,3942706155 +.long 2631720,167774730 +.long 11579568,738208812 +.long 7631988,486546717 +.long 12763842,2952835248 +.long 12434877,1862299503 +.long 3552822,2365623693 +.long 2236962,2281736328 +.long 3684408,234884622 +.long 6579300,419436825 +.long 1973790,2264958855 +.long 3750201,1308642894 +.long 2894892,184552203 +.long 10921638,2835392937 +.long 3158064,201329676 +.long 15066597,2030074233 +.long 4473924,285217041 +.long 16645629,2130739071 +.long 8947848,570434082 +.long 10461087,3875596263 +.long 6645093,1493195097 +.long 8882055,3774931425 +.long 7039851,3657489114 +.long 16053492,1023425853 +.long 2302755,3355494600 +.long 4737096,301994514 +.long 1052688,67109892 +.long 13750737,1946186868 +.long 5329233,1409307732 +.long 12632256,805318704 +.long 16382457,2113961598 +.long 13816530,3019945140 +.long 10526880,671098920 +.long 5592405,1426085205 +.long 10592673,1744857192 +.long 4276545,1342197840 +.long 16448250,3187719870 +.long 4408131,3489714384 +.long 1250067,3288384708 +.long 12895428,822096177 +.long 3092271,3405827019 +.long 11053224,704653866 +.long 11974326,2902502829 +.long 3947580,251662095 +.long 2829099,3389049546 +.long 12698049,1879076976 +.long 16777215,4278255615 +.long 13158600,838873650 +.long 10855845,1761634665 +.long 2105376,134219784 +.long 9013641,1644192354 +.long 0,0 +.long 9474192,603989028 +.long 4671303,3506491857 +.long 15724527,4211145723 +.long 15395562,3120609978 +.long 12040119,3976261101 +.long 1381653,1157645637 +.long 394758,2164294017 +.long 13487565,1929409395 +.long 11908533,1828744557 +.long 1184274,2214626436 +.long 8289918,2667618207 +.long 12303291,3993038574 +.long 2697513,1241533002 +.long 986895,3271607235 +.long 12105912,771763758 +.long 460551,3238052289 +.long 263172,16777473 +.long 10197915,3858818790 +.long 9737364,620766501 +.long 2171169,1207978056 +.long 6710886,2566953369 +.long 15132390,3103832505 +.long 13553358,3003167667 +.long 15592941,2063629179 +.long 15198183,4177590777 +.long 3881787,3456159438 +.long 16711422,3204497343 +.long 8355711,3741376479 +.long 12961221,1895854449 +.long 10790052,687876393 +.long 3618615,3439381965 +.long 11645361,1811967084 +.long 5000268,318771987 +.long 9539985,1677747300 +.long 7237230,2600508315 +.long 9276813,1660969827 +.long 7763574,2634063261 +.long 197379,3221274816 +.long 2960685,1258310475 +.long 14606046,3070277559 +.long 9868950,2768283045 +.long 2500134,2298513801 +.long 8224125,1593859935 +.long 13027014,2969612721 +.long 6052956,385881879 +.long 13882323,4093703412 +.long 15921906,3154164924 +.long 5197647,3540046803 +.long 1644825,1174423110 +.long 4144959,3472936911 +.long 14474460,922761015 +.long 7960953,1577082462 +.long 1907997,1191200583 +.long 5395026,2483066004 +.long 15461355,4194368250 +.long 15987699,4227923196 +.long 7171437,1526750043 +.long 6184542,2533398423 +.long 16514043,4261478142 +.long 6908265,1509972570 +.long 11711154,2885725356 +.long 15790320,1006648380 +.long 3223857,1275087948 +.long 789516,50332419 +.long 13948116,889206069 +.long 13619151,4076925939 +.long 9211020,587211555 +.long 14869218,3087055032 +.long 7697781,1560304989 +.long 11119017,1778412138 +.long 4868682,2449511058 +.long 5723991,3573601749 +.long 8684676,553656609 +.long 1118481,1140868164 +.long 4539717,1358975313 +.long 1776411,3321939654 +.long 16119285,2097184125 +.long 15000804,956315961 +.long 921102,2197848963 +.long 7566195,3691044060 +.long 11184810,2852170410 +.long 15856113,2080406652 +.long 14540253,1996519287 +.long 5855577,1442862678 +.long 1315860,83887365 +.long 7105644,452991771 +.long 9605778,2751505572 +.long 5526612,352326933 +.long 13684944,872428596 +.long 7895160,503324190 +.long 7368816,469769244 +.long 14935011,4160813304 +.long 4802889,1375752786 +.long 8421504,536879136 +.long 5263440,335549460 +.long 10987431,3909151209 +.long 16185078,3170942397 +.long 7829367,3707821533 +.long 9671571,3825263844 +.long 8816262,2701173153 +.long 8618883,3758153952 +.long 2763306,2315291274 +.long 13092807,4043370993 +.long 5987163,3590379222 +.long 15329769,2046851706 +.long 15658734,3137387451 +.long 9408399,3808486371 +.long 65793,1073758272 +.long 4013373,1325420367 +.globl Camellia_cbc_encrypt +.type Camellia_cbc_encrypt,@function +.align 16 +Camellia_cbc_encrypt: +.L_Camellia_cbc_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 28(%esp),%ecx + cmpl $0,%ecx + je .L016enc_out + pushfl + cld + movl 24(%esp),%eax + movl 28(%esp),%ebx + movl 36(%esp),%edx + movl 40(%esp),%ebp + leal -64(%esp),%esi + andl $-64,%esi + leal -127(%edx),%edi + subl %esi,%edi + negl %edi + andl $960,%edi + subl %edi,%esi + movl 44(%esp),%edi + xchgl %esi,%esp + addl $4,%esp + movl %esi,20(%esp) + movl %eax,24(%esp) + movl %ebx,28(%esp) + movl %ecx,32(%esp) + movl %edx,36(%esp) + movl %ebp,40(%esp) + call .L017pic_point +.L017pic_point: + popl %ebp + leal .LCamellia_SBOX-.L017pic_point(%ebp),%ebp + movl $32,%esi +.align 4 +.L018prefetch_sbox: + movl (%ebp),%eax + movl 32(%ebp),%ebx + movl 64(%ebp),%ecx + movl 96(%ebp),%edx + leal 128(%ebp),%ebp + decl %esi + jnz .L018prefetch_sbox + movl 36(%esp),%eax + subl $4096,%ebp + movl 24(%esp),%esi + movl 272(%eax),%edx + cmpl $0,%edi + je .L019DECRYPT + movl 32(%esp),%ecx + movl 40(%esp),%edi + shll $6,%edx + leal (%eax,%edx,1),%edx + movl %edx,16(%esp) + testl $4294967280,%ecx + jz .L020enc_tail + movl (%edi),%eax + movl 4(%edi),%ebx +.align 4 +.L021enc_loop: + movl 8(%edi),%ecx + movl 12(%edi),%edx + xorl (%esi),%eax + xorl 4(%esi),%ebx + xorl 8(%esi),%ecx + bswap %eax + xorl 12(%esi),%edx + bswap %ebx + movl 36(%esp),%edi + bswap %ecx + bswap %edx + call _x86_Camellia_encrypt + movl 24(%esp),%esi + movl 28(%esp),%edi + bswap %eax + bswap %ebx + bswap %ecx + movl %eax,(%edi) + bswap %edx + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 32(%esp),%ecx + leal 16(%esi),%esi + movl %esi,24(%esp) + leal 16(%edi),%edx + movl %edx,28(%esp) + subl $16,%ecx + testl $4294967280,%ecx + movl %ecx,32(%esp) + jnz .L021enc_loop + testl $15,%ecx + jnz .L020enc_tail + movl 40(%esp),%esi + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + movl 20(%esp),%esp + popfl +.L016enc_out: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + pushfl +.align 4 +.L020enc_tail: + movl %edi,%eax + movl 28(%esp),%edi + pushl %eax + movl $16,%ebx + subl %ecx,%ebx + cmpl %esi,%edi + je .L022enc_in_place +.align 4 +.long 2767451785 + jmp .L023enc_skip_in_place +.L022enc_in_place: + leal (%edi,%ecx,1),%edi +.L023enc_skip_in_place: + movl %ebx,%ecx + xorl %eax,%eax +.align 4 +.long 2868115081 + popl %edi + movl 28(%esp),%esi + movl (%edi),%eax + movl 4(%edi),%ebx + movl $16,32(%esp) + jmp .L021enc_loop +.align 16 +.L019DECRYPT: + shll $6,%edx + leal (%eax,%edx,1),%edx + movl %eax,16(%esp) + movl %edx,36(%esp) + cmpl 28(%esp),%esi + je .L024dec_in_place + movl 40(%esp),%edi + movl %edi,44(%esp) +.align 4 +.L025dec_loop: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + bswap %eax + movl 12(%esi),%edx + bswap %ebx + movl 36(%esp),%edi + bswap %ecx + bswap %edx + call _x86_Camellia_decrypt + movl 44(%esp),%edi + movl 32(%esp),%esi + bswap %eax + bswap %ebx + bswap %ecx + xorl (%edi),%eax + bswap %edx + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + subl $16,%esi + jc .L026dec_partial + movl %esi,32(%esp) + movl 24(%esp),%esi + movl 28(%esp),%edi + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl %esi,44(%esp) + leal 16(%esi),%esi + movl %esi,24(%esp) + leal 16(%edi),%edi + movl %edi,28(%esp) + jnz .L025dec_loop + movl 44(%esp),%edi +.L027dec_end: + movl 40(%esp),%esi + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + jmp .L028dec_out +.align 4 +.L026dec_partial: + leal 44(%esp),%edi + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + leal 16(%esi),%ecx + movl %edi,%esi + movl 28(%esp),%edi +.long 2767451785 + movl 24(%esp),%edi + jmp .L027dec_end +.align 4 +.L024dec_in_place: +.L029dec_in_place_loop: + leal 44(%esp),%edi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + bswap %eax + movl %edx,12(%edi) + bswap %ebx + movl 36(%esp),%edi + bswap %ecx + bswap %edx + call _x86_Camellia_decrypt + movl 40(%esp),%edi + movl 28(%esp),%esi + bswap %eax + bswap %ebx + bswap %ecx + xorl (%edi),%eax + bswap %edx + xorl 4(%edi),%ebx + xorl 8(%edi),%ecx + xorl 12(%edi),%edx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %ecx,8(%esi) + movl %edx,12(%esi) + leal 16(%esi),%esi + movl %esi,28(%esp) + leal 44(%esp),%esi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 24(%esp),%esi + leal 16(%esi),%esi + movl %esi,24(%esp) + movl 32(%esp),%ecx + subl $16,%ecx + jc .L030dec_in_place_partial + movl %ecx,32(%esp) + jnz .L029dec_in_place_loop + jmp .L028dec_out +.align 4 +.L030dec_in_place_partial: + movl 28(%esp),%edi + leal 44(%esp),%esi + leal (%edi,%ecx,1),%edi + leal 16(%esi,%ecx,1),%esi + negl %ecx +.long 2767451785 +.align 4 +.L028dec_out: + movl 20(%esp),%esp + popfl + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size Camellia_cbc_encrypt,.-.L_Camellia_cbc_encrypt_begin +.byte 67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54 +.byte 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115 +.byte 115,108,46,111,114,103,62,0 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/camellia/cmll-x86_64.S b/crypto/openssl/crypto/camellia/cmll-x86_64.S new file mode 100644 index 000000000000..605c25d74be3 --- /dev/null +++ b/crypto/openssl/crypto/camellia/cmll-x86_64.S @@ -0,0 +1,1946 @@ +.text + + +.globl Camellia_EncryptBlock +.type Camellia_EncryptBlock,@function +.align 16 +Camellia_EncryptBlock: +.cfi_startproc + movl $128,%eax + subl %edi,%eax + movl $3,%edi + adcl $0,%edi + jmp .Lenc_rounds +.cfi_endproc +.size Camellia_EncryptBlock,.-Camellia_EncryptBlock + +.globl Camellia_EncryptBlock_Rounds +.type Camellia_EncryptBlock_Rounds,@function +.align 16 +.Lenc_rounds: +Camellia_EncryptBlock_Rounds: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-32 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-40 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-48 +.Lenc_prologue: + + + movq %rcx,%r13 + movq %rdx,%r14 + + shll $6,%edi + leaq .LCamellia_SBOX(%rip),%rbp + leaq (%r14,%rdi,1),%r15 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + bswapl %r8d + movl 12(%rsi),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_encrypt + + bswapl %r8d + bswapl %r9d + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%rbp +.cfi_restore %rbp + movq 32(%rsp),%rbx +.cfi_restore %rbx + leaq 40(%rsp),%rsp +.cfi_adjust_cfa_offset -40 +.Lenc_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size Camellia_EncryptBlock_Rounds,.-Camellia_EncryptBlock_Rounds + +.type _x86_64_Camellia_encrypt,@function +.align 16 +_x86_64_Camellia_encrypt: +.cfi_startproc + xorl 0(%r14),%r9d + xorl 4(%r14),%r8d + xorl 8(%r14),%r11d + xorl 12(%r14),%r10d +.align 16 +.Leloop: + movl 16(%r14),%ebx + movl 20(%r14),%eax + + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 24(%r14),%ebx + movl 28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 32(%r14),%ebx + movl 36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 40(%r14),%ebx + movl 44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 48(%r14),%ebx + movl 52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 56(%r14),%ebx + movl 60(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 64(%r14),%ebx + movl 68(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + leaq 64(%r14),%r14 + cmpq %r15,%r14 + movl 8(%r14),%edx + movl 12(%r14),%ecx + je .Ledone + + andl %r8d,%eax + orl %r11d,%edx + roll $1,%eax + xorl %edx,%r10d + xorl %eax,%r9d + andl %r10d,%ecx + orl %r9d,%ebx + roll $1,%ecx + xorl %ebx,%r8d + xorl %ecx,%r11d + jmp .Leloop + +.align 16 +.Ledone: + xorl %r10d,%eax + xorl %r11d,%ebx + xorl %r8d,%ecx + xorl %r9d,%edx + + movl %eax,%r8d + movl %ebx,%r9d + movl %ecx,%r10d + movl %edx,%r11d + +.byte 0xf3,0xc3 +.cfi_endproc +.size _x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt + + +.globl Camellia_DecryptBlock +.type Camellia_DecryptBlock,@function +.align 16 +Camellia_DecryptBlock: +.cfi_startproc + movl $128,%eax + subl %edi,%eax + movl $3,%edi + adcl $0,%edi + jmp .Ldec_rounds +.cfi_endproc +.size Camellia_DecryptBlock,.-Camellia_DecryptBlock + +.globl Camellia_DecryptBlock_Rounds +.type Camellia_DecryptBlock_Rounds,@function +.align 16 +.Ldec_rounds: +Camellia_DecryptBlock_Rounds: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-32 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-40 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-48 +.Ldec_prologue: + + + movq %rcx,%r13 + movq %rdx,%r15 + + shll $6,%edi + leaq .LCamellia_SBOX(%rip),%rbp + leaq (%r15,%rdi,1),%r14 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + bswapl %r8d + movl 12(%rsi),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_decrypt + + bswapl %r8d + bswapl %r9d + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%rbp +.cfi_restore %rbp + movq 32(%rsp),%rbx +.cfi_restore %rbx + leaq 40(%rsp),%rsp +.cfi_adjust_cfa_offset -40 +.Ldec_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size Camellia_DecryptBlock_Rounds,.-Camellia_DecryptBlock_Rounds + +.type _x86_64_Camellia_decrypt,@function +.align 16 +_x86_64_Camellia_decrypt: +.cfi_startproc + xorl 0(%r14),%r9d + xorl 4(%r14),%r8d + xorl 8(%r14),%r11d + xorl 12(%r14),%r10d +.align 16 +.Ldloop: + movl -8(%r14),%ebx + movl -4(%r14),%eax + + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -16(%r14),%ebx + movl -12(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -24(%r14),%ebx + movl -20(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -32(%r14),%ebx + movl -28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -40(%r14),%ebx + movl -36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -48(%r14),%ebx + movl -44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl -56(%r14),%ebx + movl -52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + leaq -64(%r14),%r14 + cmpq %r15,%r14 + movl 0(%r14),%edx + movl 4(%r14),%ecx + je .Lddone + + andl %r8d,%eax + orl %r11d,%edx + roll $1,%eax + xorl %edx,%r10d + xorl %eax,%r9d + andl %r10d,%ecx + orl %r9d,%ebx + roll $1,%ecx + xorl %ebx,%r8d + xorl %ecx,%r11d + + jmp .Ldloop + +.align 16 +.Lddone: + xorl %r10d,%ecx + xorl %r11d,%edx + xorl %r8d,%eax + xorl %r9d,%ebx + + movl %ecx,%r8d + movl %edx,%r9d + movl %eax,%r10d + movl %ebx,%r11d + +.byte 0xf3,0xc3 +.cfi_endproc +.size _x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt +.globl Camellia_Ekeygen +.type Camellia_Ekeygen,@function +.align 16 +Camellia_Ekeygen: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-32 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-40 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-48 +.Lkey_prologue: + + movl %edi,%r15d + movq %rdx,%r13 + + movl 0(%rsi),%r8d + movl 4(%rsi),%r9d + movl 8(%rsi),%r10d + movl 12(%rsi),%r11d + + bswapl %r8d + bswapl %r9d + bswapl %r10d + bswapl %r11d + movl %r9d,0(%r13) + movl %r8d,4(%r13) + movl %r11d,8(%r13) + movl %r10d,12(%r13) + cmpq $128,%r15 + je .L1st128 + + movl 16(%rsi),%r8d + movl 20(%rsi),%r9d + cmpq $192,%r15 + je .L1st192 + movl 24(%rsi),%r10d + movl 28(%rsi),%r11d + jmp .L1st256 +.L1st192: + movl %r8d,%r10d + movl %r9d,%r11d + notl %r10d + notl %r11d +.L1st256: + bswapl %r8d + bswapl %r9d + bswapl %r10d + bswapl %r11d + movl %r9d,32(%r13) + movl %r8d,36(%r13) + movl %r11d,40(%r13) + movl %r10d,44(%r13) + xorl 0(%r13),%r9d + xorl 4(%r13),%r8d + xorl 8(%r13),%r11d + xorl 12(%r13),%r10d + +.L1st128: + leaq .LCamellia_SIGMA(%rip),%r14 + leaq .LCamellia_SBOX(%rip),%rbp + + movl 0(%r14),%ebx + movl 4(%r14),%eax + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 8(%r14),%ebx + movl 12(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 16(%r14),%ebx + movl 20(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + xorl 0(%r13),%r9d + xorl 4(%r13),%r8d + xorl 8(%r13),%r11d + xorl 12(%r13),%r10d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 24(%r14),%ebx + movl 28(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 32(%r14),%ebx + movl 36(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + cmpq $128,%r15 + jne .L2nd256 + + leaq 128(%r13),%r13 + shlq $32,%r8 + shlq $32,%r10 + orq %r9,%r8 + orq %r11,%r10 + movq -128(%r13),%rax + movq -120(%r13),%rbx + movq %r8,-112(%r13) + movq %r10,-104(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rax,-96(%r13) + movq %rbx,-88(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-80(%r13) + movq %r10,-72(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-64(%r13) + movq %r10,-56(%r13) + movq %rax,%r11 + shlq $30,%rax + movq %rbx,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%rax + shlq $30,%rbx + orq %r11,%rbx + movq %rax,-48(%r13) + movq %rbx,-40(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-32(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rbx,-24(%r13) + movq %r8,%r11 + shlq $15,%r8 + movq %r10,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r8 + shlq $15,%r10 + orq %r11,%r10 + movq %r8,-16(%r13) + movq %r10,-8(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,0(%r13) + movq %rbx,8(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,16(%r13) + movq %rbx,24(%r13) + movq %r8,%r11 + shlq $34,%r8 + movq %r10,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%r8 + shlq $34,%r10 + orq %r11,%r10 + movq %r8,32(%r13) + movq %r10,40(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,48(%r13) + movq %rbx,56(%r13) + movq %r8,%r11 + shlq $17,%r8 + movq %r10,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%r8 + shlq $17,%r10 + orq %r11,%r10 + movq %r8,64(%r13) + movq %r10,72(%r13) + movl $3,%eax + jmp .Ldone +.align 16 +.L2nd256: + movl %r9d,48(%r13) + movl %r8d,52(%r13) + movl %r11d,56(%r13) + movl %r10d,60(%r13) + xorl 32(%r13),%r9d + xorl 36(%r13),%r8d + xorl 40(%r13),%r11d + xorl 44(%r13),%r10d + xorl %r8d,%eax + xorl %r9d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 40(%r14),%ebx + movl 44(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r10d + xorl %ecx,%r11d + xorl %edx,%r11d + xorl %r10d,%eax + xorl %r11d,%ebx + movzbl %ah,%esi + movzbl %bl,%edi + movl 2052(%rbp,%rsi,8),%edx + movl 0(%rbp,%rdi,8),%ecx + movzbl %al,%esi + shrl $16,%eax + movzbl %bh,%edi + xorl 4(%rbp,%rsi,8),%edx + shrl $16,%ebx + xorl 4(%rbp,%rdi,8),%ecx + movzbl %ah,%esi + movzbl %bl,%edi + xorl 0(%rbp,%rsi,8),%edx + xorl 2052(%rbp,%rdi,8),%ecx + movzbl %al,%esi + movzbl %bh,%edi + xorl 2048(%rbp,%rsi,8),%edx + xorl 2048(%rbp,%rdi,8),%ecx + movl 48(%r14),%ebx + movl 52(%r14),%eax + xorl %edx,%ecx + rorl $8,%edx + xorl %ecx,%r8d + xorl %ecx,%r9d + xorl %edx,%r9d + movq 0(%r13),%rax + movq 8(%r13),%rbx + movq 32(%r13),%rcx + movq 40(%r13),%rdx + movq 48(%r13),%r14 + movq 56(%r13),%r15 + leaq 128(%r13),%r13 + shlq $32,%r8 + shlq $32,%r10 + orq %r9,%r8 + orq %r11,%r10 + movq %r8,-112(%r13) + movq %r10,-104(%r13) + movq %rcx,%r11 + shlq $15,%rcx + movq %rdx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rcx + shlq $15,%rdx + orq %r11,%rdx + movq %rcx,-96(%r13) + movq %rdx,-88(%r13) + movq %r14,%r11 + shlq $15,%r14 + movq %r15,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%r14 + shlq $15,%r15 + orq %r11,%r15 + movq %r14,-80(%r13) + movq %r15,-72(%r13) + movq %rcx,%r11 + shlq $15,%rcx + movq %rdx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rcx + shlq $15,%rdx + orq %r11,%rdx + movq %rcx,-64(%r13) + movq %rdx,-56(%r13) + movq %r8,%r11 + shlq $30,%r8 + movq %r10,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r8 + shlq $30,%r10 + orq %r11,%r10 + movq %r8,-48(%r13) + movq %r10,-40(%r13) + movq %rax,%r11 + shlq $45,%rax + movq %rbx,%r9 + shrq $19,%r9 + shrq $19,%r11 + orq %r9,%rax + shlq $45,%rbx + orq %r11,%rbx + movq %rax,-32(%r13) + movq %rbx,-24(%r13) + movq %r14,%r11 + shlq $30,%r14 + movq %r15,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r14 + shlq $30,%r15 + orq %r11,%r15 + movq %r14,-16(%r13) + movq %r15,-8(%r13) + movq %rax,%r11 + shlq $15,%rax + movq %rbx,%r9 + shrq $49,%r9 + shrq $49,%r11 + orq %r9,%rax + shlq $15,%rbx + orq %r11,%rbx + movq %rax,0(%r13) + movq %rbx,8(%r13) + movq %rcx,%r11 + shlq $30,%rcx + movq %rdx,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%rcx + shlq $30,%rdx + orq %r11,%rdx + movq %rcx,16(%r13) + movq %rdx,24(%r13) + movq %r8,%r11 + shlq $30,%r8 + movq %r10,%r9 + shrq $34,%r9 + shrq $34,%r11 + orq %r9,%r8 + shlq $30,%r10 + orq %r11,%r10 + movq %r8,32(%r13) + movq %r10,40(%r13) + movq %rax,%r11 + shlq $17,%rax + movq %rbx,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%rax + shlq $17,%rbx + orq %r11,%rbx + movq %rax,48(%r13) + movq %rbx,56(%r13) + movq %r14,%r11 + shlq $32,%r14 + movq %r15,%r9 + shrq $32,%r9 + shrq $32,%r11 + orq %r9,%r14 + shlq $32,%r15 + orq %r11,%r15 + movq %r14,64(%r13) + movq %r15,72(%r13) + movq %rcx,%r11 + shlq $34,%rcx + movq %rdx,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%rcx + shlq $34,%rdx + orq %r11,%rdx + movq %rcx,80(%r13) + movq %rdx,88(%r13) + movq %r14,%r11 + shlq $17,%r14 + movq %r15,%r9 + shrq $47,%r9 + shrq $47,%r11 + orq %r9,%r14 + shlq $17,%r15 + orq %r11,%r15 + movq %r14,96(%r13) + movq %r15,104(%r13) + movq %rax,%r11 + shlq $34,%rax + movq %rbx,%r9 + shrq $30,%r9 + shrq $30,%r11 + orq %r9,%rax + shlq $34,%rbx + orq %r11,%rbx + movq %rax,112(%r13) + movq %rbx,120(%r13) + movq %r8,%r11 + shlq $51,%r8 + movq %r10,%r9 + shrq $13,%r9 + shrq $13,%r11 + orq %r9,%r8 + shlq $51,%r10 + orq %r11,%r10 + movq %r8,128(%r13) + movq %r10,136(%r13) + movl $4,%eax +.Ldone: + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%rbp +.cfi_restore %rbp + movq 32(%rsp),%rbx +.cfi_restore %rbx + leaq 40(%rsp),%rsp +.cfi_adjust_cfa_offset -40 +.Lkey_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size Camellia_Ekeygen,.-Camellia_Ekeygen +.align 64 +.LCamellia_SIGMA: +.long 0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858 +.long 0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5 +.long 0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2 +.long 0, 0, 0, 0 +.LCamellia_SBOX: +.long 0x70707000,0x70700070 +.long 0x82828200,0x2c2c002c +.long 0x2c2c2c00,0xb3b300b3 +.long 0xececec00,0xc0c000c0 +.long 0xb3b3b300,0xe4e400e4 +.long 0x27272700,0x57570057 +.long 0xc0c0c000,0xeaea00ea +.long 0xe5e5e500,0xaeae00ae +.long 0xe4e4e400,0x23230023 +.long 0x85858500,0x6b6b006b +.long 0x57575700,0x45450045 +.long 0x35353500,0xa5a500a5 +.long 0xeaeaea00,0xeded00ed +.long 0x0c0c0c00,0x4f4f004f +.long 0xaeaeae00,0x1d1d001d +.long 0x41414100,0x92920092 +.long 0x23232300,0x86860086 +.long 0xefefef00,0xafaf00af +.long 0x6b6b6b00,0x7c7c007c +.long 0x93939300,0x1f1f001f +.long 0x45454500,0x3e3e003e +.long 0x19191900,0xdcdc00dc +.long 0xa5a5a500,0x5e5e005e +.long 0x21212100,0x0b0b000b +.long 0xededed00,0xa6a600a6 +.long 0x0e0e0e00,0x39390039 +.long 0x4f4f4f00,0xd5d500d5 +.long 0x4e4e4e00,0x5d5d005d +.long 0x1d1d1d00,0xd9d900d9 +.long 0x65656500,0x5a5a005a +.long 0x92929200,0x51510051 +.long 0xbdbdbd00,0x6c6c006c +.long 0x86868600,0x8b8b008b +.long 0xb8b8b800,0x9a9a009a +.long 0xafafaf00,0xfbfb00fb +.long 0x8f8f8f00,0xb0b000b0 +.long 0x7c7c7c00,0x74740074 +.long 0xebebeb00,0x2b2b002b +.long 0x1f1f1f00,0xf0f000f0 +.long 0xcecece00,0x84840084 +.long 0x3e3e3e00,0xdfdf00df +.long 0x30303000,0xcbcb00cb +.long 0xdcdcdc00,0x34340034 +.long 0x5f5f5f00,0x76760076 +.long 0x5e5e5e00,0x6d6d006d +.long 0xc5c5c500,0xa9a900a9 +.long 0x0b0b0b00,0xd1d100d1 +.long 0x1a1a1a00,0x04040004 +.long 0xa6a6a600,0x14140014 +.long 0xe1e1e100,0x3a3a003a +.long 0x39393900,0xdede00de +.long 0xcacaca00,0x11110011 +.long 0xd5d5d500,0x32320032 +.long 0x47474700,0x9c9c009c +.long 0x5d5d5d00,0x53530053 +.long 0x3d3d3d00,0xf2f200f2 +.long 0xd9d9d900,0xfefe00fe +.long 0x01010100,0xcfcf00cf +.long 0x5a5a5a00,0xc3c300c3 +.long 0xd6d6d600,0x7a7a007a +.long 0x51515100,0x24240024 +.long 0x56565600,0xe8e800e8 +.long 0x6c6c6c00,0x60600060 +.long 0x4d4d4d00,0x69690069 +.long 0x8b8b8b00,0xaaaa00aa +.long 0x0d0d0d00,0xa0a000a0 +.long 0x9a9a9a00,0xa1a100a1 +.long 0x66666600,0x62620062 +.long 0xfbfbfb00,0x54540054 +.long 0xcccccc00,0x1e1e001e +.long 0xb0b0b000,0xe0e000e0 +.long 0x2d2d2d00,0x64640064 +.long 0x74747400,0x10100010 +.long 0x12121200,0x00000000 +.long 0x2b2b2b00,0xa3a300a3 +.long 0x20202000,0x75750075 +.long 0xf0f0f000,0x8a8a008a +.long 0xb1b1b100,0xe6e600e6 +.long 0x84848400,0x09090009 +.long 0x99999900,0xdddd00dd +.long 0xdfdfdf00,0x87870087 +.long 0x4c4c4c00,0x83830083 +.long 0xcbcbcb00,0xcdcd00cd +.long 0xc2c2c200,0x90900090 +.long 0x34343400,0x73730073 +.long 0x7e7e7e00,0xf6f600f6 +.long 0x76767600,0x9d9d009d +.long 0x05050500,0xbfbf00bf +.long 0x6d6d6d00,0x52520052 +.long 0xb7b7b700,0xd8d800d8 +.long 0xa9a9a900,0xc8c800c8 +.long 0x31313100,0xc6c600c6 +.long 0xd1d1d100,0x81810081 +.long 0x17171700,0x6f6f006f +.long 0x04040400,0x13130013 +.long 0xd7d7d700,0x63630063 +.long 0x14141400,0xe9e900e9 +.long 0x58585800,0xa7a700a7 +.long 0x3a3a3a00,0x9f9f009f +.long 0x61616100,0xbcbc00bc +.long 0xdedede00,0x29290029 +.long 0x1b1b1b00,0xf9f900f9 +.long 0x11111100,0x2f2f002f +.long 0x1c1c1c00,0xb4b400b4 +.long 0x32323200,0x78780078 +.long 0x0f0f0f00,0x06060006 +.long 0x9c9c9c00,0xe7e700e7 +.long 0x16161600,0x71710071 +.long 0x53535300,0xd4d400d4 +.long 0x18181800,0xabab00ab +.long 0xf2f2f200,0x88880088 +.long 0x22222200,0x8d8d008d +.long 0xfefefe00,0x72720072 +.long 0x44444400,0xb9b900b9 +.long 0xcfcfcf00,0xf8f800f8 +.long 0xb2b2b200,0xacac00ac +.long 0xc3c3c300,0x36360036 +.long 0xb5b5b500,0x2a2a002a +.long 0x7a7a7a00,0x3c3c003c +.long 0x91919100,0xf1f100f1 +.long 0x24242400,0x40400040 +.long 0x08080800,0xd3d300d3 +.long 0xe8e8e800,0xbbbb00bb +.long 0xa8a8a800,0x43430043 +.long 0x60606000,0x15150015 +.long 0xfcfcfc00,0xadad00ad +.long 0x69696900,0x77770077 +.long 0x50505000,0x80800080 +.long 0xaaaaaa00,0x82820082 +.long 0xd0d0d000,0xecec00ec +.long 0xa0a0a000,0x27270027 +.long 0x7d7d7d00,0xe5e500e5 +.long 0xa1a1a100,0x85850085 +.long 0x89898900,0x35350035 +.long 0x62626200,0x0c0c000c +.long 0x97979700,0x41410041 +.long 0x54545400,0xefef00ef +.long 0x5b5b5b00,0x93930093 +.long 0x1e1e1e00,0x19190019 +.long 0x95959500,0x21210021 +.long 0xe0e0e000,0x0e0e000e +.long 0xffffff00,0x4e4e004e +.long 0x64646400,0x65650065 +.long 0xd2d2d200,0xbdbd00bd +.long 0x10101000,0xb8b800b8 +.long 0xc4c4c400,0x8f8f008f +.long 0x00000000,0xebeb00eb +.long 0x48484800,0xcece00ce +.long 0xa3a3a300,0x30300030 +.long 0xf7f7f700,0x5f5f005f +.long 0x75757500,0xc5c500c5 +.long 0xdbdbdb00,0x1a1a001a +.long 0x8a8a8a00,0xe1e100e1 +.long 0x03030300,0xcaca00ca +.long 0xe6e6e600,0x47470047 +.long 0xdadada00,0x3d3d003d +.long 0x09090900,0x01010001 +.long 0x3f3f3f00,0xd6d600d6 +.long 0xdddddd00,0x56560056 +.long 0x94949400,0x4d4d004d +.long 0x87878700,0x0d0d000d +.long 0x5c5c5c00,0x66660066 +.long 0x83838300,0xcccc00cc +.long 0x02020200,0x2d2d002d +.long 0xcdcdcd00,0x12120012 +.long 0x4a4a4a00,0x20200020 +.long 0x90909000,0xb1b100b1 +.long 0x33333300,0x99990099 +.long 0x73737300,0x4c4c004c +.long 0x67676700,0xc2c200c2 +.long 0xf6f6f600,0x7e7e007e +.long 0xf3f3f300,0x05050005 +.long 0x9d9d9d00,0xb7b700b7 +.long 0x7f7f7f00,0x31310031 +.long 0xbfbfbf00,0x17170017 +.long 0xe2e2e200,0xd7d700d7 +.long 0x52525200,0x58580058 +.long 0x9b9b9b00,0x61610061 +.long 0xd8d8d800,0x1b1b001b +.long 0x26262600,0x1c1c001c +.long 0xc8c8c800,0x0f0f000f +.long 0x37373700,0x16160016 +.long 0xc6c6c600,0x18180018 +.long 0x3b3b3b00,0x22220022 +.long 0x81818100,0x44440044 +.long 0x96969600,0xb2b200b2 +.long 0x6f6f6f00,0xb5b500b5 +.long 0x4b4b4b00,0x91910091 +.long 0x13131300,0x08080008 +.long 0xbebebe00,0xa8a800a8 +.long 0x63636300,0xfcfc00fc +.long 0x2e2e2e00,0x50500050 +.long 0xe9e9e900,0xd0d000d0 +.long 0x79797900,0x7d7d007d +.long 0xa7a7a700,0x89890089 +.long 0x8c8c8c00,0x97970097 +.long 0x9f9f9f00,0x5b5b005b +.long 0x6e6e6e00,0x95950095 +.long 0xbcbcbc00,0xffff00ff +.long 0x8e8e8e00,0xd2d200d2 +.long 0x29292900,0xc4c400c4 +.long 0xf5f5f500,0x48480048 +.long 0xf9f9f900,0xf7f700f7 +.long 0xb6b6b600,0xdbdb00db +.long 0x2f2f2f00,0x03030003 +.long 0xfdfdfd00,0xdada00da +.long 0xb4b4b400,0x3f3f003f +.long 0x59595900,0x94940094 +.long 0x78787800,0x5c5c005c +.long 0x98989800,0x02020002 +.long 0x06060600,0x4a4a004a +.long 0x6a6a6a00,0x33330033 +.long 0xe7e7e700,0x67670067 +.long 0x46464600,0xf3f300f3 +.long 0x71717100,0x7f7f007f +.long 0xbababa00,0xe2e200e2 +.long 0xd4d4d400,0x9b9b009b +.long 0x25252500,0x26260026 +.long 0xababab00,0x37370037 +.long 0x42424200,0x3b3b003b +.long 0x88888800,0x96960096 +.long 0xa2a2a200,0x4b4b004b +.long 0x8d8d8d00,0xbebe00be +.long 0xfafafa00,0x2e2e002e +.long 0x72727200,0x79790079 +.long 0x07070700,0x8c8c008c +.long 0xb9b9b900,0x6e6e006e +.long 0x55555500,0x8e8e008e +.long 0xf8f8f800,0xf5f500f5 +.long 0xeeeeee00,0xb6b600b6 +.long 0xacacac00,0xfdfd00fd +.long 0x0a0a0a00,0x59590059 +.long 0x36363600,0x98980098 +.long 0x49494900,0x6a6a006a +.long 0x2a2a2a00,0x46460046 +.long 0x68686800,0xbaba00ba +.long 0x3c3c3c00,0x25250025 +.long 0x38383800,0x42420042 +.long 0xf1f1f100,0xa2a200a2 +.long 0xa4a4a400,0xfafa00fa +.long 0x40404000,0x07070007 +.long 0x28282800,0x55550055 +.long 0xd3d3d300,0xeeee00ee +.long 0x7b7b7b00,0x0a0a000a +.long 0xbbbbbb00,0x49490049 +.long 0xc9c9c900,0x68680068 +.long 0x43434300,0x38380038 +.long 0xc1c1c100,0xa4a400a4 +.long 0x15151500,0x28280028 +.long 0xe3e3e300,0x7b7b007b +.long 0xadadad00,0xc9c900c9 +.long 0xf4f4f400,0xc1c100c1 +.long 0x77777700,0xe3e300e3 +.long 0xc7c7c700,0xf4f400f4 +.long 0x80808000,0xc7c700c7 +.long 0x9e9e9e00,0x9e9e009e +.long 0x00e0e0e0,0x38003838 +.long 0x00050505,0x41004141 +.long 0x00585858,0x16001616 +.long 0x00d9d9d9,0x76007676 +.long 0x00676767,0xd900d9d9 +.long 0x004e4e4e,0x93009393 +.long 0x00818181,0x60006060 +.long 0x00cbcbcb,0xf200f2f2 +.long 0x00c9c9c9,0x72007272 +.long 0x000b0b0b,0xc200c2c2 +.long 0x00aeaeae,0xab00abab +.long 0x006a6a6a,0x9a009a9a +.long 0x00d5d5d5,0x75007575 +.long 0x00181818,0x06000606 +.long 0x005d5d5d,0x57005757 +.long 0x00828282,0xa000a0a0 +.long 0x00464646,0x91009191 +.long 0x00dfdfdf,0xf700f7f7 +.long 0x00d6d6d6,0xb500b5b5 +.long 0x00272727,0xc900c9c9 +.long 0x008a8a8a,0xa200a2a2 +.long 0x00323232,0x8c008c8c +.long 0x004b4b4b,0xd200d2d2 +.long 0x00424242,0x90009090 +.long 0x00dbdbdb,0xf600f6f6 +.long 0x001c1c1c,0x07000707 +.long 0x009e9e9e,0xa700a7a7 +.long 0x009c9c9c,0x27002727 +.long 0x003a3a3a,0x8e008e8e +.long 0x00cacaca,0xb200b2b2 +.long 0x00252525,0x49004949 +.long 0x007b7b7b,0xde00dede +.long 0x000d0d0d,0x43004343 +.long 0x00717171,0x5c005c5c +.long 0x005f5f5f,0xd700d7d7 +.long 0x001f1f1f,0xc700c7c7 +.long 0x00f8f8f8,0x3e003e3e +.long 0x00d7d7d7,0xf500f5f5 +.long 0x003e3e3e,0x8f008f8f +.long 0x009d9d9d,0x67006767 +.long 0x007c7c7c,0x1f001f1f +.long 0x00606060,0x18001818 +.long 0x00b9b9b9,0x6e006e6e +.long 0x00bebebe,0xaf00afaf +.long 0x00bcbcbc,0x2f002f2f +.long 0x008b8b8b,0xe200e2e2 +.long 0x00161616,0x85008585 +.long 0x00343434,0x0d000d0d +.long 0x004d4d4d,0x53005353 +.long 0x00c3c3c3,0xf000f0f0 +.long 0x00727272,0x9c009c9c +.long 0x00959595,0x65006565 +.long 0x00ababab,0xea00eaea +.long 0x008e8e8e,0xa300a3a3 +.long 0x00bababa,0xae00aeae +.long 0x007a7a7a,0x9e009e9e +.long 0x00b3b3b3,0xec00ecec +.long 0x00020202,0x80008080 +.long 0x00b4b4b4,0x2d002d2d +.long 0x00adadad,0x6b006b6b +.long 0x00a2a2a2,0xa800a8a8 +.long 0x00acacac,0x2b002b2b +.long 0x00d8d8d8,0x36003636 +.long 0x009a9a9a,0xa600a6a6 +.long 0x00171717,0xc500c5c5 +.long 0x001a1a1a,0x86008686 +.long 0x00353535,0x4d004d4d +.long 0x00cccccc,0x33003333 +.long 0x00f7f7f7,0xfd00fdfd +.long 0x00999999,0x66006666 +.long 0x00616161,0x58005858 +.long 0x005a5a5a,0x96009696 +.long 0x00e8e8e8,0x3a003a3a +.long 0x00242424,0x09000909 +.long 0x00565656,0x95009595 +.long 0x00404040,0x10001010 +.long 0x00e1e1e1,0x78007878 +.long 0x00636363,0xd800d8d8 +.long 0x00090909,0x42004242 +.long 0x00333333,0xcc00cccc +.long 0x00bfbfbf,0xef00efef +.long 0x00989898,0x26002626 +.long 0x00979797,0xe500e5e5 +.long 0x00858585,0x61006161 +.long 0x00686868,0x1a001a1a +.long 0x00fcfcfc,0x3f003f3f +.long 0x00ececec,0x3b003b3b +.long 0x000a0a0a,0x82008282 +.long 0x00dadada,0xb600b6b6 +.long 0x006f6f6f,0xdb00dbdb +.long 0x00535353,0xd400d4d4 +.long 0x00626262,0x98009898 +.long 0x00a3a3a3,0xe800e8e8 +.long 0x002e2e2e,0x8b008b8b +.long 0x00080808,0x02000202 +.long 0x00afafaf,0xeb00ebeb +.long 0x00282828,0x0a000a0a +.long 0x00b0b0b0,0x2c002c2c +.long 0x00747474,0x1d001d1d +.long 0x00c2c2c2,0xb000b0b0 +.long 0x00bdbdbd,0x6f006f6f +.long 0x00363636,0x8d008d8d +.long 0x00222222,0x88008888 +.long 0x00383838,0x0e000e0e +.long 0x00646464,0x19001919 +.long 0x001e1e1e,0x87008787 +.long 0x00393939,0x4e004e4e +.long 0x002c2c2c,0x0b000b0b +.long 0x00a6a6a6,0xa900a9a9 +.long 0x00303030,0x0c000c0c +.long 0x00e5e5e5,0x79007979 +.long 0x00444444,0x11001111 +.long 0x00fdfdfd,0x7f007f7f +.long 0x00888888,0x22002222 +.long 0x009f9f9f,0xe700e7e7 +.long 0x00656565,0x59005959 +.long 0x00878787,0xe100e1e1 +.long 0x006b6b6b,0xda00dada +.long 0x00f4f4f4,0x3d003d3d +.long 0x00232323,0xc800c8c8 +.long 0x00484848,0x12001212 +.long 0x00101010,0x04000404 +.long 0x00d1d1d1,0x74007474 +.long 0x00515151,0x54005454 +.long 0x00c0c0c0,0x30003030 +.long 0x00f9f9f9,0x7e007e7e +.long 0x00d2d2d2,0xb400b4b4 +.long 0x00a0a0a0,0x28002828 +.long 0x00555555,0x55005555 +.long 0x00a1a1a1,0x68006868 +.long 0x00414141,0x50005050 +.long 0x00fafafa,0xbe00bebe +.long 0x00434343,0xd000d0d0 +.long 0x00131313,0xc400c4c4 +.long 0x00c4c4c4,0x31003131 +.long 0x002f2f2f,0xcb00cbcb +.long 0x00a8a8a8,0x2a002a2a +.long 0x00b6b6b6,0xad00adad +.long 0x003c3c3c,0x0f000f0f +.long 0x002b2b2b,0xca00caca +.long 0x00c1c1c1,0x70007070 +.long 0x00ffffff,0xff00ffff +.long 0x00c8c8c8,0x32003232 +.long 0x00a5a5a5,0x69006969 +.long 0x00202020,0x08000808 +.long 0x00898989,0x62006262 +.long 0x00000000,0x00000000 +.long 0x00909090,0x24002424 +.long 0x00474747,0xd100d1d1 +.long 0x00efefef,0xfb00fbfb +.long 0x00eaeaea,0xba00baba +.long 0x00b7b7b7,0xed00eded +.long 0x00151515,0x45004545 +.long 0x00060606,0x81008181 +.long 0x00cdcdcd,0x73007373 +.long 0x00b5b5b5,0x6d006d6d +.long 0x00121212,0x84008484 +.long 0x007e7e7e,0x9f009f9f +.long 0x00bbbbbb,0xee00eeee +.long 0x00292929,0x4a004a4a +.long 0x000f0f0f,0xc300c3c3 +.long 0x00b8b8b8,0x2e002e2e +.long 0x00070707,0xc100c1c1 +.long 0x00040404,0x01000101 +.long 0x009b9b9b,0xe600e6e6 +.long 0x00949494,0x25002525 +.long 0x00212121,0x48004848 +.long 0x00666666,0x99009999 +.long 0x00e6e6e6,0xb900b9b9 +.long 0x00cecece,0xb300b3b3 +.long 0x00ededed,0x7b007b7b +.long 0x00e7e7e7,0xf900f9f9 +.long 0x003b3b3b,0xce00cece +.long 0x00fefefe,0xbf00bfbf +.long 0x007f7f7f,0xdf00dfdf +.long 0x00c5c5c5,0x71007171 +.long 0x00a4a4a4,0x29002929 +.long 0x00373737,0xcd00cdcd +.long 0x00b1b1b1,0x6c006c6c +.long 0x004c4c4c,0x13001313 +.long 0x00919191,0x64006464 +.long 0x006e6e6e,0x9b009b9b +.long 0x008d8d8d,0x63006363 +.long 0x00767676,0x9d009d9d +.long 0x00030303,0xc000c0c0 +.long 0x002d2d2d,0x4b004b4b +.long 0x00dedede,0xb700b7b7 +.long 0x00969696,0xa500a5a5 +.long 0x00262626,0x89008989 +.long 0x007d7d7d,0x5f005f5f +.long 0x00c6c6c6,0xb100b1b1 +.long 0x005c5c5c,0x17001717 +.long 0x00d3d3d3,0xf400f4f4 +.long 0x00f2f2f2,0xbc00bcbc +.long 0x004f4f4f,0xd300d3d3 +.long 0x00191919,0x46004646 +.long 0x003f3f3f,0xcf00cfcf +.long 0x00dcdcdc,0x37003737 +.long 0x00797979,0x5e005e5e +.long 0x001d1d1d,0x47004747 +.long 0x00525252,0x94009494 +.long 0x00ebebeb,0xfa00fafa +.long 0x00f3f3f3,0xfc00fcfc +.long 0x006d6d6d,0x5b005b5b +.long 0x005e5e5e,0x97009797 +.long 0x00fbfbfb,0xfe00fefe +.long 0x00696969,0x5a005a5a +.long 0x00b2b2b2,0xac00acac +.long 0x00f0f0f0,0x3c003c3c +.long 0x00313131,0x4c004c4c +.long 0x000c0c0c,0x03000303 +.long 0x00d4d4d4,0x35003535 +.long 0x00cfcfcf,0xf300f3f3 +.long 0x008c8c8c,0x23002323 +.long 0x00e2e2e2,0xb800b8b8 +.long 0x00757575,0x5d005d5d +.long 0x00a9a9a9,0x6a006a6a +.long 0x004a4a4a,0x92009292 +.long 0x00575757,0xd500d5d5 +.long 0x00848484,0x21002121 +.long 0x00111111,0x44004444 +.long 0x00454545,0x51005151 +.long 0x001b1b1b,0xc600c6c6 +.long 0x00f5f5f5,0x7d007d7d +.long 0x00e4e4e4,0x39003939 +.long 0x000e0e0e,0x83008383 +.long 0x00737373,0xdc00dcdc +.long 0x00aaaaaa,0xaa00aaaa +.long 0x00f1f1f1,0x7c007c7c +.long 0x00dddddd,0x77007777 +.long 0x00595959,0x56005656 +.long 0x00141414,0x05000505 +.long 0x006c6c6c,0x1b001b1b +.long 0x00929292,0xa400a4a4 +.long 0x00545454,0x15001515 +.long 0x00d0d0d0,0x34003434 +.long 0x00787878,0x1e001e1e +.long 0x00707070,0x1c001c1c +.long 0x00e3e3e3,0xf800f8f8 +.long 0x00494949,0x52005252 +.long 0x00808080,0x20002020 +.long 0x00505050,0x14001414 +.long 0x00a7a7a7,0xe900e9e9 +.long 0x00f6f6f6,0xbd00bdbd +.long 0x00777777,0xdd00dddd +.long 0x00939393,0xe400e4e4 +.long 0x00868686,0xa100a1a1 +.long 0x00838383,0xe000e0e0 +.long 0x002a2a2a,0x8a008a8a +.long 0x00c7c7c7,0xf100f1f1 +.long 0x005b5b5b,0xd600d6d6 +.long 0x00e9e9e9,0x7a007a7a +.long 0x00eeeeee,0xbb00bbbb +.long 0x008f8f8f,0xe300e3e3 +.long 0x00010101,0x40004040 +.long 0x003d3d3d,0x4f004f4f +.globl Camellia_cbc_encrypt +.type Camellia_cbc_encrypt,@function +.align 16 +Camellia_cbc_encrypt: +.cfi_startproc +.byte 243,15,30,250 + cmpq $0,%rdx + je .Lcbc_abort + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lcbc_prologue: + + movq %rsp,%rbp +.cfi_def_cfa_register %rbp + subq $64,%rsp + andq $-64,%rsp + + + + leaq -64-63(%rcx),%r10 + subq %rsp,%r10 + negq %r10 + andq $0x3C0,%r10 + subq %r10,%rsp + + + movq %rdi,%r12 + movq %rsi,%r13 + movq %r8,%rbx + movq %rcx,%r14 + movl 272(%rcx),%r15d + + movq %r8,40(%rsp) + movq %rbp,48(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x30,0x06,0x23,0x38 + +.Lcbc_body: + leaq .LCamellia_SBOX(%rip),%rbp + + movl $32,%ecx +.align 4 +.Lcbc_prefetch_sbox: + movq 0(%rbp),%rax + movq 32(%rbp),%rsi + movq 64(%rbp),%rdi + movq 96(%rbp),%r11 + leaq 128(%rbp),%rbp + loop .Lcbc_prefetch_sbox + subq $4096,%rbp + shlq $6,%r15 + movq %rdx,%rcx + leaq (%r14,%r15,1),%r15 + + cmpl $0,%r9d + je .LCBC_DECRYPT + + andq $-16,%rdx + andq $15,%rcx + leaq (%r12,%rdx,1),%rdx + movq %r14,0(%rsp) + movq %rdx,8(%rsp) + movq %rcx,16(%rsp) + + cmpq %r12,%rdx + movl 0(%rbx),%r8d + movl 4(%rbx),%r9d + movl 8(%rbx),%r10d + movl 12(%rbx),%r11d + je .Lcbc_enc_tail + jmp .Lcbc_eloop + +.align 16 +.Lcbc_eloop: + xorl 0(%r12),%r8d + xorl 4(%r12),%r9d + xorl 8(%r12),%r10d + bswapl %r8d + xorl 12(%r12),%r11d + bswapl %r9d + bswapl %r10d + bswapl %r11d + + call _x86_64_Camellia_encrypt + + movq 0(%rsp),%r14 + bswapl %r8d + movq 8(%rsp),%rdx + bswapl %r9d + movq 16(%rsp),%rcx + bswapl %r10d + movl %r8d,0(%r13) + bswapl %r11d + movl %r9d,4(%r13) + movl %r10d,8(%r13) + leaq 16(%r12),%r12 + movl %r11d,12(%r13) + cmpq %rdx,%r12 + leaq 16(%r13),%r13 + jne .Lcbc_eloop + + cmpq $0,%rcx + jne .Lcbc_enc_tail + + movq 40(%rsp),%r13 + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + jmp .Lcbc_done + +.align 16 +.Lcbc_enc_tail: + xorq %rax,%rax + movq %rax,0+24(%rsp) + movq %rax,8+24(%rsp) + movq %rax,16(%rsp) + +.Lcbc_enc_pushf: + pushfq + cld + movq %r12,%rsi + leaq 8+24(%rsp),%rdi +.long 0x9066A4F3 + popfq +.Lcbc_enc_popf: + + leaq 24(%rsp),%r12 + leaq 16+24(%rsp),%rax + movq %rax,8(%rsp) + jmp .Lcbc_eloop + +.align 16 +.LCBC_DECRYPT: + xchgq %r14,%r15 + addq $15,%rdx + andq $15,%rcx + andq $-16,%rdx + movq %r14,0(%rsp) + leaq (%r12,%rdx,1),%rdx + movq %rdx,8(%rsp) + movq %rcx,16(%rsp) + + movq (%rbx),%rax + movq 8(%rbx),%rbx + jmp .Lcbc_dloop +.align 16 +.Lcbc_dloop: + movl 0(%r12),%r8d + movl 4(%r12),%r9d + movl 8(%r12),%r10d + bswapl %r8d + movl 12(%r12),%r11d + bswapl %r9d + movq %rax,0+24(%rsp) + bswapl %r10d + movq %rbx,8+24(%rsp) + bswapl %r11d + + call _x86_64_Camellia_decrypt + + movq 0(%rsp),%r14 + movq 8(%rsp),%rdx + movq 16(%rsp),%rcx + + bswapl %r8d + movq (%r12),%rax + bswapl %r9d + movq 8(%r12),%rbx + bswapl %r10d + xorl 0+24(%rsp),%r8d + bswapl %r11d + xorl 4+24(%rsp),%r9d + xorl 8+24(%rsp),%r10d + leaq 16(%r12),%r12 + xorl 12+24(%rsp),%r11d + cmpq %rdx,%r12 + je .Lcbc_ddone + + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + leaq 16(%r13),%r13 + jmp .Lcbc_dloop + +.align 16 +.Lcbc_ddone: + movq 40(%rsp),%rdx + cmpq $0,%rcx + jne .Lcbc_dec_tail + + movl %r8d,0(%r13) + movl %r9d,4(%r13) + movl %r10d,8(%r13) + movl %r11d,12(%r13) + + movq %rax,(%rdx) + movq %rbx,8(%rdx) + jmp .Lcbc_done +.align 16 +.Lcbc_dec_tail: + movl %r8d,0+24(%rsp) + movl %r9d,4+24(%rsp) + movl %r10d,8+24(%rsp) + movl %r11d,12+24(%rsp) + +.Lcbc_dec_pushf: + pushfq + cld + leaq 8+24(%rsp),%rsi + leaq (%r13),%rdi +.long 0x9066A4F3 + popfq +.Lcbc_dec_popf: + + movq %rax,(%rdx) + movq %rbx,8(%rdx) + jmp .Lcbc_done + +.align 16 +.Lcbc_done: + movq 48(%rsp),%rcx +.cfi_def_cfa %rcx,56 + movq 0(%rcx),%r15 +.cfi_restore %r15 + movq 8(%rcx),%r14 +.cfi_restore %r14 + movq 16(%rcx),%r13 +.cfi_restore %r13 + movq 24(%rcx),%r12 +.cfi_restore %r12 + movq 32(%rcx),%rbp +.cfi_restore %rbp + movq 40(%rcx),%rbx +.cfi_restore %rbx + leaq 48(%rcx),%rsp +.cfi_def_cfa %rsp,8 +.Lcbc_abort: + .byte 0xf3,0xc3 +.cfi_endproc +.size Camellia_cbc_encrypt,.-Camellia_cbc_encrypt + +.byte 67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54,95,54,52,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/camellia/cmll_cbc.c b/crypto/openssl/crypto/camellia/cmll_cbc.c index b19171ded26b..140681a9bd26 100644 --- a/crypto/openssl/crypto/camellia/cmll_cbc.c +++ b/crypto/openssl/crypto/camellia/cmll_cbc.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/openssl/crypto/camellia/cmll_cfb.c b/crypto/openssl/crypto/camellia/cmll_cfb.c index 4f49eaded66c..8a92572d9395 100644 --- a/crypto/openssl/crypto/camellia/cmll_cfb.c +++ b/crypto/openssl/crypto/camellia/cmll_cfb.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/openssl/crypto/camellia/cmll_ctr.c b/crypto/openssl/crypto/camellia/cmll_ctr.c index 161d1e18c136..26d875e34c41 100644 --- a/crypto/openssl/crypto/camellia/cmll_ctr.c +++ b/crypto/openssl/crypto/camellia/cmll_ctr.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/openssl/crypto/camellia/cmll_ecb.c b/crypto/openssl/crypto/camellia/cmll_ecb.c index 5760d1ed35fc..86ffbd51e6c2 100644 --- a/crypto/openssl/crypto/camellia/cmll_ecb.c +++ b/crypto/openssl/crypto/camellia/cmll_ecb.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cmll_local.h" diff --git a/crypto/openssl/crypto/camellia/cmll_local.h b/crypto/openssl/crypto/camellia/cmll_local.h index d16baa55facc..c1d940d3d8f8 100644 --- a/crypto/openssl/crypto/camellia/cmll_local.h +++ b/crypto/openssl/crypto/camellia/cmll_local.h @@ -1,7 +1,7 @@ /* * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/camellia/cmll_misc.c b/crypto/openssl/crypto/camellia/cmll_misc.c index d8fc3738c404..f98dff7e3daa 100644 --- a/crypto/openssl/crypto/camellia/cmll_misc.c +++ b/crypto/openssl/crypto/camellia/cmll_misc.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include "cmll_local.h" diff --git a/crypto/openssl/crypto/camellia/cmll_ofb.c b/crypto/openssl/crypto/camellia/cmll_ofb.c index b43c685c751f..4eeb0b5b75ee 100644 --- a/crypto/openssl/crypto/camellia/cmll_ofb.c +++ b/crypto/openssl/crypto/camellia/cmll_ofb.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/openssl/crypto/cast/asm/cast-586.pl b/crypto/openssl/crypto/cast/asm/cast-586.pl index 04710819380a..044d703c1278 100755 --- a/crypto/openssl/crypto/cast/asm/cast-586.pl +++ b/crypto/openssl/crypto/cast/asm/cast-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -18,8 +18,7 @@ push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; require "cbc.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/cast/build.info b/crypto/openssl/crypto/cast/build.info index b0f59f38002c..4395f0ac22a2 100644 --- a/crypto/openssl/crypto/cast/build.info +++ b/crypto/openssl/crypto/cast/build.info @@ -1,7 +1,26 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - c_skey.c c_ecb.c {- $target{cast_asm_src} -} c_cfb64.c c_ofb64.c -GENERATE[cast-586.s]=asm/cast-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[cast-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl +$CASTASM=c_enc.c +# CAST assembly source is not PIC +IF[{- !$disabled{asm} && $disabled{pic} -}] + $CASTASM_x86=cast-586.S + + # Now that we have defined all the arch specific variables, use the + # appropriate one + IF[$CASTASM_{- $target{asm_arch} -}] + $CASTASM=$CASTASM_{- $target{asm_arch} -} + ENDIF +ENDIF + +$ALL=c_skey.c c_ecb.c $CASTASM c_cfb64.c c_ofb64.c + +SOURCE[../../libcrypto]=$ALL + +# When all deprecated symbols are removed, libcrypto doesn't export the +# cast functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=$ALL +ENDIF + +GENERATE[cast-586.S]=asm/cast-586.pl +DEPEND[cast-586.S]=../perlasm/x86asm.pl ../perlasm/cbc.pl diff --git a/crypto/openssl/crypto/cast/c_cfb64.c b/crypto/openssl/crypto/cast/c_cfb64.c index 72221595382b..97081734ecb7 100644 --- a/crypto/openssl/crypto/cast/c_cfb64.c +++ b/crypto/openssl/crypto/cast/c_cfb64.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cast_local.h" diff --git a/crypto/openssl/crypto/cast/c_ecb.c b/crypto/openssl/crypto/cast/c_ecb.c index 6fe093f75b1b..a0ab660f8489 100644 --- a/crypto/openssl/crypto/cast/c_ecb.c +++ b/crypto/openssl/crypto/cast/c_ecb.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cast_local.h" #include diff --git a/crypto/openssl/crypto/cast/c_enc.c b/crypto/openssl/crypto/cast/c_enc.c index d27d1fc0a54f..4ed945a50887 100644 --- a/crypto/openssl/crypto/cast/c_enc.c +++ b/crypto/openssl/crypto/cast/c_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cast_local.h" diff --git a/crypto/openssl/crypto/cast/c_ofb64.c b/crypto/openssl/crypto/cast/c_ofb64.c index 49c0cfade577..d4aa10ff6867 100644 --- a/crypto/openssl/crypto/cast/c_ofb64.c +++ b/crypto/openssl/crypto/cast/c_ofb64.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cast_local.h" diff --git a/crypto/openssl/crypto/cast/c_skey.c b/crypto/openssl/crypto/cast/c_skey.c index 0311482d20dd..030e20ea3147 100644 --- a/crypto/openssl/crypto/cast/c_skey.c +++ b/crypto/openssl/crypto/cast/c_skey.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "cast_local.h" #include "cast_s.h" diff --git a/crypto/openssl/crypto/cast/cast_local.h b/crypto/openssl/crypto/cast/cast_local.h index 35e89930a8c0..4434a342002a 100644 --- a/crypto/openssl/crypto/cast/cast_local.h +++ b/crypto/openssl/crypto/cast/cast_local.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/cast/cast_s.h b/crypto/openssl/crypto/cast/cast_s.h index b27415b967f5..57163d17e124 100644 --- a/crypto/openssl/crypto/cast/cast_s.h +++ b/crypto/openssl/crypto/cast/cast_s.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/chacha/asm/chacha-armv4.pl b/crypto/openssl/crypto/chacha/asm/chacha-armv4.pl index 81c616add313..0aa13519eb83 100755 --- a/crypto/openssl/crypto/chacha/asm/chacha-armv4.pl +++ b/crypto/openssl/crypto/chacha/asm/chacha-armv4.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -34,9 +34,10 @@ # but then Snapdragon S4 and Cortex-A8 results get # 20-25% worse; -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -44,9 +45,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour $output" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } sub AUTOLOAD() # thunk [simplified] x86-style perlasm @@ -171,7 +173,6 @@ my @ret; $code.=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) || defined(__clang__) .syntax unified #endif @@ -185,6 +186,8 @@ $code.=<<___; #define ldrhsb ldrbhs #endif +.text + .align 5 .Lsigma: .long 0x61707865,0x3320646e,0x79622d32,0x6b206574 @ endian-neutral @@ -192,7 +195,11 @@ $code.=<<___; .long 1,0,0,0 #if __ARM_MAX_ARCH__>=7 .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.LChaCha20_ctr32 +# endif #else .word -1 #endif @@ -219,8 +226,10 @@ ChaCha20_ctr32: cmp r2,#192 @ test len bls .Lshort ldr r4,[r14,#-32] +# if !defined(_WIN32) ldr r4,[r14,r4] -# ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r4,[r4] # endif tst r4,#ARMV7_NEON diff --git a/crypto/openssl/crypto/chacha/asm/chacha-armv8.pl b/crypto/openssl/crypto/chacha/asm/chacha-armv8.pl index 84c98014803b..dcdc4a04e367 100755 --- a/crypto/openssl/crypto/chacha/asm/chacha-armv8.pl +++ b/crypto/openssl/crypto/chacha/asm/chacha-armv8.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -18,32 +18,44 @@ # # ChaCha20 for ARMv8. # +# April 2019 +# +# Replace 3xNEON+1xIALU code path with 4+1. 4+1 is actually fastest +# option on most(*), but not all, processors, yet 6+2 is retained. +# This is because penalties are considered tolerable in comparison to +# improvement on processors where 6+2 helps. Most notably +37% on +# ThunderX2. It's server-oriented processor which will have to serve +# as many requests as possible. While others are mostly clients, when +# performance doesn't have to be absolute top-notch, just fast enough, +# as majority of time is spent "entertaining" relatively slow human. +# # Performance in cycles per byte out of large buffer. # -# IALU/gcc-4.9 3xNEON+1xIALU 6xNEON+2xIALU +# IALU/gcc-4.9 4xNEON+1xIALU 6xNEON+2xIALU # -# Apple A7 5.50/+49% 3.33 1.70 -# Cortex-A53 8.40/+80% 4.72 4.72(*) -# Cortex-A57 8.06/+43% 4.90 4.43(**) -# Denver 4.50/+82% 2.63 2.67(*) -# X-Gene 9.50/+46% 8.82 8.89(*) -# Mongoose 8.00/+44% 3.64 3.25 -# Kryo 8.17/+50% 4.83 4.65 +# Apple A7 5.50/+49% 2.72 1.60 +# Cortex-A53 8.40/+80% 4.06 4.45(*) +# Cortex-A57 8.06/+43% 4.15 4.40(*) +# Denver 4.50/+82% 2.30 2.70(*) +# X-Gene 9.50/+46% 8.20 8.90(*) +# Mongoose 8.00/+44% 2.74 3.12(*) +# Kryo 8.17/+50% 4.47 4.65(*) +# ThunderX2 7.22/+48% 5.64 4.10 # -# (*) it's expected that doubling interleave factor doesn't help -# all processors, only those with higher NEON latency and -# higher instruction issue rate; -# (**) expected improvement was actually higher; +# (*) slower than 4+1:-( -$flavour=shift; -$output=shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; sub AUTOLOAD() # thunk [simplified] x86-style perlasm @@ -120,42 +132,37 @@ my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2)); } $code.=<<___; -#include "arm_arch.h" - -.text - +#ifndef __KERNEL__ +# include "arm_arch.h" .extern OPENSSL_armcap_P .hidden OPENSSL_armcap_P +#endif + +.text .align 5 .Lsigma: .quad 0x3320646e61707865,0x6b20657479622d32 // endian-neutral .Lone: -.long 1,0,0,0 -.LOPENSSL_armcap_P: -#ifdef __ILP32__ -.long OPENSSL_armcap_P-. -#else -.quad OPENSSL_armcap_P-. -#endif -.asciz "ChaCha20 for ARMv8, CRYPTOGAMS by " +.long 1,2,3,4 +.Lrot24: +.long 0x02010003,0x06050407,0x0a09080b,0x0e0d0c0f +.asciz "ChaCha20 for ARMv8, CRYPTOGAMS by \@dot-asm" .globl ChaCha20_ctr32 .type ChaCha20_ctr32,%function .align 5 ChaCha20_ctr32: cbz $len,.Labort - adr @x[0],.LOPENSSL_armcap_P cmp $len,#192 b.lo .Lshort -#ifdef __ILP32__ - ldrsw @x[1],[@x[0]] -#else - ldr @x[1],[@x[0]] -#endif - ldr w17,[@x[1],@x[0]] + +#ifndef __KERNEL__ + adrp x17,OPENSSL_armcap_P + ldr w17,[x17,#:lo12:OPENSSL_armcap_P] tst w17,#ARMV7_NEON - b.ne ChaCha20_neon + b.ne .LChaCha20_neon +#endif .Lshort: .inst 0xd503233f // paciasp @@ -174,7 +181,7 @@ ChaCha20_ctr32: ldp @d[2],@d[3],[$key] // load key ldp @d[4],@d[5],[$key,#16] ldp @d[6],@d[7],[$ctr] // load counter -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror @d[2],@d[2],#32 ror @d[3],@d[3],#32 ror @d[4],@d[4],#32 @@ -243,7 +250,7 @@ $code.=<<___; add @x[14],@x[14],@x[15],lsl#32 ldp @x[13],@x[15],[$inp,#48] add $inp,$inp,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] @@ -300,7 +307,7 @@ $code.=<<___; add @x[10],@x[10],@x[11],lsl#32 add @x[12],@x[12],@x[13],lsl#32 add @x[14],@x[14],@x[15],lsl#32 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] @@ -341,46 +348,91 @@ $code.=<<___; ___ {{{ -my ($A0,$B0,$C0,$D0,$A1,$B1,$C1,$D1,$A2,$B2,$C2,$D2,$T0,$T1,$T2,$T3) = - map("v$_.4s",(0..7,16..23)); -my (@K)=map("v$_.4s",(24..30)); -my $ONE="v31.4s"; +my @K = map("v$_.4s",(0..3)); +my ($xt0,$xt1,$xt2,$xt3, $CTR,$ROT24) = map("v$_.4s",(4..9)); +my @X = map("v$_.4s",(16,20,24,28, 17,21,25,29, 18,22,26,30, 19,23,27,31)); +my ($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3, + $xc0,$xc1,$xc2,$xc3, $xd0,$xd1,$xd2,$xd3) = @X; -sub NEONROUND { -my $odd = pop; -my ($a,$b,$c,$d,$t)=@_; +sub NEON_lane_ROUND { +my ($a0,$b0,$c0,$d0)=@_; +my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0)); +my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1)); +my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2)); +my @x=map("'$_'",@X); ( - "&add ('$a','$a','$b')", - "&eor ('$d','$d','$a')", - "&rev32_16 ('$d','$d')", # vrot ($d,16) - - "&add ('$c','$c','$d')", - "&eor ('$t','$b','$c')", - "&ushr ('$b','$t',20)", - "&sli ('$b','$t',12)", - - "&add ('$a','$a','$b')", - "&eor ('$t','$d','$a')", - "&ushr ('$d','$t',24)", - "&sli ('$d','$t',8)", - - "&add ('$c','$c','$d')", - "&eor ('$t','$b','$c')", - "&ushr ('$b','$t',25)", - "&sli ('$b','$t',7)", - - "&ext ('$c','$c','$c',8)", - "&ext ('$d','$d','$d',$odd?4:12)", - "&ext ('$b','$b','$b',$odd?12:4)" + "&add (@x[$a0],@x[$a0],@x[$b0])", # Q1 + "&add (@x[$a1],@x[$a1],@x[$b1])", # Q2 + "&add (@x[$a2],@x[$a2],@x[$b2])", # Q3 + "&add (@x[$a3],@x[$a3],@x[$b3])", # Q4 + "&eor (@x[$d0],@x[$d0],@x[$a0])", + "&eor (@x[$d1],@x[$d1],@x[$a1])", + "&eor (@x[$d2],@x[$d2],@x[$a2])", + "&eor (@x[$d3],@x[$d3],@x[$a3])", + "&rev32_16 (@x[$d0],@x[$d0])", + "&rev32_16 (@x[$d1],@x[$d1])", + "&rev32_16 (@x[$d2],@x[$d2])", + "&rev32_16 (@x[$d3],@x[$d3])", + + "&add (@x[$c0],@x[$c0],@x[$d0])", + "&add (@x[$c1],@x[$c1],@x[$d1])", + "&add (@x[$c2],@x[$c2],@x[$d2])", + "&add (@x[$c3],@x[$c3],@x[$d3])", + "&eor ('$xt0',@x[$b0],@x[$c0])", + "&eor ('$xt1',@x[$b1],@x[$c1])", + "&eor ('$xt2',@x[$b2],@x[$c2])", + "&eor ('$xt3',@x[$b3],@x[$c3])", + "&ushr (@x[$b0],'$xt0',20)", + "&ushr (@x[$b1],'$xt1',20)", + "&ushr (@x[$b2],'$xt2',20)", + "&ushr (@x[$b3],'$xt3',20)", + "&sli (@x[$b0],'$xt0',12)", + "&sli (@x[$b1],'$xt1',12)", + "&sli (@x[$b2],'$xt2',12)", + "&sli (@x[$b3],'$xt3',12)", + + "&add (@x[$a0],@x[$a0],@x[$b0])", + "&add (@x[$a1],@x[$a1],@x[$b1])", + "&add (@x[$a2],@x[$a2],@x[$b2])", + "&add (@x[$a3],@x[$a3],@x[$b3])", + "&eor ('$xt0',@x[$d0],@x[$a0])", + "&eor ('$xt1',@x[$d1],@x[$a1])", + "&eor ('$xt2',@x[$d2],@x[$a2])", + "&eor ('$xt3',@x[$d3],@x[$a3])", + "&tbl (@x[$d0],'{$xt0}','$ROT24')", + "&tbl (@x[$d1],'{$xt1}','$ROT24')", + "&tbl (@x[$d2],'{$xt2}','$ROT24')", + "&tbl (@x[$d3],'{$xt3}','$ROT24')", + + "&add (@x[$c0],@x[$c0],@x[$d0])", + "&add (@x[$c1],@x[$c1],@x[$d1])", + "&add (@x[$c2],@x[$c2],@x[$d2])", + "&add (@x[$c3],@x[$c3],@x[$d3])", + "&eor ('$xt0',@x[$b0],@x[$c0])", + "&eor ('$xt1',@x[$b1],@x[$c1])", + "&eor ('$xt2',@x[$b2],@x[$c2])", + "&eor ('$xt3',@x[$b3],@x[$c3])", + "&ushr (@x[$b0],'$xt0',25)", + "&ushr (@x[$b1],'$xt1',25)", + "&ushr (@x[$b2],'$xt2',25)", + "&ushr (@x[$b3],'$xt3',25)", + "&sli (@x[$b0],'$xt0',7)", + "&sli (@x[$b1],'$xt1',7)", + "&sli (@x[$b2],'$xt2',7)", + "&sli (@x[$b3],'$xt3',7)" ); } $code.=<<___; +#ifdef __KERNEL__ +.globl ChaCha20_neon +#endif .type ChaCha20_neon,%function .align 5 ChaCha20_neon: +.LChaCha20_neon: .inst 0xd503233f // paciasp stp x29,x30,[sp,#-96]! add x29,sp,#0 @@ -403,8 +455,9 @@ ChaCha20_neon: ld1 {@K[1],@K[2]},[$key] ldp @d[6],@d[7],[$ctr] // load counter ld1 {@K[3]},[$ctr] - ld1 {$ONE},[@x[0]] -#ifdef __ARMEB__ + stp d8,d9,[sp] // meet ABI requirements + ld1 {$CTR,$ROT24},[@x[0]] +#ifdef __AARCH64EB__ rev64 @K[0],@K[0] ror @d[2],@d[2],#32 ror @d[3],@d[3],#32 @@ -413,115 +466,129 @@ ChaCha20_neon: ror @d[6],@d[6],#32 ror @d[7],@d[7],#32 #endif - add @K[3],@K[3],$ONE // += 1 - add @K[4],@K[3],$ONE - add @K[5],@K[4],$ONE - shl $ONE,$ONE,#2 // 1 -> 4 .Loop_outer_neon: - mov.32 @x[0],@d[0] // unpack key block - lsr @x[1],@d[0],#32 - mov $A0,@K[0] - mov.32 @x[2],@d[1] - lsr @x[3],@d[1],#32 - mov $A1,@K[0] - mov.32 @x[4],@d[2] - lsr @x[5],@d[2],#32 - mov $A2,@K[0] - mov.32 @x[6],@d[3] - mov $B0,@K[1] - lsr @x[7],@d[3],#32 - mov $B1,@K[1] - mov.32 @x[8],@d[4] - mov $B2,@K[1] - lsr @x[9],@d[4],#32 - mov $D0,@K[3] - mov.32 @x[10],@d[5] - mov $D1,@K[4] - lsr @x[11],@d[5],#32 - mov $D2,@K[5] - mov.32 @x[12],@d[6] - mov $C0,@K[2] - lsr @x[13],@d[6],#32 - mov $C1,@K[2] - mov.32 @x[14],@d[7] - mov $C2,@K[2] - lsr @x[15],@d[7],#32 + dup $xa0,@{K[0]}[0] // unpack key block + mov.32 @x[0],@d[0] + dup $xa1,@{K[0]}[1] + lsr @x[1],@d[0],#32 + dup $xa2,@{K[0]}[2] + mov.32 @x[2],@d[1] + dup $xa3,@{K[0]}[3] + lsr @x[3],@d[1],#32 + dup $xb0,@{K[1]}[0] + mov.32 @x[4],@d[2] + dup $xb1,@{K[1]}[1] + lsr @x[5],@d[2],#32 + dup $xb2,@{K[1]}[2] + mov.32 @x[6],@d[3] + dup $xb3,@{K[1]}[3] + lsr @x[7],@d[3],#32 + dup $xd0,@{K[3]}[0] + mov.32 @x[8],@d[4] + dup $xd1,@{K[3]}[1] + lsr @x[9],@d[4],#32 + dup $xd2,@{K[3]}[2] + mov.32 @x[10],@d[5] + dup $xd3,@{K[3]}[3] + lsr @x[11],@d[5],#32 + add $xd0,$xd0,$CTR + mov.32 @x[12],@d[6] + dup $xc0,@{K[2]}[0] + lsr @x[13],@d[6],#32 + dup $xc1,@{K[2]}[1] + mov.32 @x[14],@d[7] + dup $xc2,@{K[2]}[2] + lsr @x[15],@d[7],#32 + dup $xc3,@{K[2]}[3] mov $ctr,#10 - subs $len,$len,#256 + subs $len,$len,#320 .Loop_neon: sub $ctr,$ctr,#1 ___ - my @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,0); - my @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,0); - my @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,0); - my @thread3=&ROUND(0,4,8,12); - - foreach (@thread0) { - eval; eval(shift(@thread3)); - eval(shift(@thread1)); eval(shift(@thread3)); - eval(shift(@thread2)); eval(shift(@thread3)); - } - - @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,1); - @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,1); - @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,1); - @thread3=&ROUND(0,5,10,15); + my @plus_one=&ROUND(0,4,8,12); + foreach (&NEON_lane_ROUND(0,4,8,12)) { eval; eval(shift(@plus_one)); } - foreach (@thread0) { - eval; eval(shift(@thread3)); - eval(shift(@thread1)); eval(shift(@thread3)); - eval(shift(@thread2)); eval(shift(@thread3)); - } + @plus_one=&ROUND(0,5,10,15); + foreach (&NEON_lane_ROUND(0,5,10,15)) { eval; eval(shift(@plus_one)); } $code.=<<___; cbnz $ctr,.Loop_neon - add.32 @x[0],@x[0],@d[0] // accumulate key block - add $A0,$A0,@K[0] - add @x[1],@x[1],@d[0],lsr#32 - add $A1,$A1,@K[0] - add.32 @x[2],@x[2],@d[1] - add $A2,$A2,@K[0] - add @x[3],@x[3],@d[1],lsr#32 - add $C0,$C0,@K[2] - add.32 @x[4],@x[4],@d[2] - add $C1,$C1,@K[2] - add @x[5],@x[5],@d[2],lsr#32 - add $C2,$C2,@K[2] - add.32 @x[6],@x[6],@d[3] - add $D0,$D0,@K[3] - add @x[7],@x[7],@d[3],lsr#32 - add.32 @x[8],@x[8],@d[4] - add $D1,$D1,@K[4] - add @x[9],@x[9],@d[4],lsr#32 - add.32 @x[10],@x[10],@d[5] - add $D2,$D2,@K[5] - add @x[11],@x[11],@d[5],lsr#32 - add.32 @x[12],@x[12],@d[6] - add $B0,$B0,@K[1] - add @x[13],@x[13],@d[6],lsr#32 - add.32 @x[14],@x[14],@d[7] - add $B1,$B1,@K[1] - add @x[15],@x[15],@d[7],lsr#32 - add $B2,$B2,@K[1] + add $xd0,$xd0,$CTR + + zip1 $xt0,$xa0,$xa1 // transpose data + zip1 $xt1,$xa2,$xa3 + zip2 $xt2,$xa0,$xa1 + zip2 $xt3,$xa2,$xa3 + zip1.64 $xa0,$xt0,$xt1 + zip2.64 $xa1,$xt0,$xt1 + zip1.64 $xa2,$xt2,$xt3 + zip2.64 $xa3,$xt2,$xt3 + + zip1 $xt0,$xb0,$xb1 + zip1 $xt1,$xb2,$xb3 + zip2 $xt2,$xb0,$xb1 + zip2 $xt3,$xb2,$xb3 + zip1.64 $xb0,$xt0,$xt1 + zip2.64 $xb1,$xt0,$xt1 + zip1.64 $xb2,$xt2,$xt3 + zip2.64 $xb3,$xt2,$xt3 + + zip1 $xt0,$xc0,$xc1 + add.32 @x[0],@x[0],@d[0] // accumulate key block + zip1 $xt1,$xc2,$xc3 + add @x[1],@x[1],@d[0],lsr#32 + zip2 $xt2,$xc0,$xc1 + add.32 @x[2],@x[2],@d[1] + zip2 $xt3,$xc2,$xc3 + add @x[3],@x[3],@d[1],lsr#32 + zip1.64 $xc0,$xt0,$xt1 + add.32 @x[4],@x[4],@d[2] + zip2.64 $xc1,$xt0,$xt1 + add @x[5],@x[5],@d[2],lsr#32 + zip1.64 $xc2,$xt2,$xt3 + add.32 @x[6],@x[6],@d[3] + zip2.64 $xc3,$xt2,$xt3 + add @x[7],@x[7],@d[3],lsr#32 + + zip1 $xt0,$xd0,$xd1 + add.32 @x[8],@x[8],@d[4] + zip1 $xt1,$xd2,$xd3 + add @x[9],@x[9],@d[4],lsr#32 + zip2 $xt2,$xd0,$xd1 + add.32 @x[10],@x[10],@d[5] + zip2 $xt3,$xd2,$xd3 + add @x[11],@x[11],@d[5],lsr#32 + zip1.64 $xd0,$xt0,$xt1 + add.32 @x[12],@x[12],@d[6] + zip2.64 $xd1,$xt0,$xt1 + add @x[13],@x[13],@d[6],lsr#32 + zip1.64 $xd2,$xt2,$xt3 + add.32 @x[14],@x[14],@d[7] + zip2.64 $xd3,$xt2,$xt3 + add @x[15],@x[15],@d[7],lsr#32 b.lo .Ltail_neon add @x[0],@x[0],@x[1],lsl#32 // pack add @x[2],@x[2],@x[3],lsl#32 ldp @x[1],@x[3],[$inp,#0] // load input + add $xa0,$xa0,@K[0] // accumulate key block add @x[4],@x[4],@x[5],lsl#32 add @x[6],@x[6],@x[7],lsl#32 ldp @x[5],@x[7],[$inp,#16] + add $xb0,$xb0,@K[1] add @x[8],@x[8],@x[9],lsl#32 add @x[10],@x[10],@x[11],lsl#32 ldp @x[9],@x[11],[$inp,#32] + add $xc0,$xc0,@K[2] add @x[12],@x[12],@x[13],lsl#32 add @x[14],@x[14],@x[15],lsl#32 ldp @x[13],@x[15],[$inp,#48] + add $xd0,$xd0,@K[3] add $inp,$inp,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] @@ -531,48 +598,68 @@ $code.=<<___; rev @x[12],@x[12] rev @x[14],@x[14] #endif - ld1.8 {$T0-$T3},[$inp],#64 + ld1.8 {$xt0-$xt3},[$inp],#64 eor @x[0],@x[0],@x[1] + add $xa1,$xa1,@K[0] eor @x[2],@x[2],@x[3] + add $xb1,$xb1,@K[1] eor @x[4],@x[4],@x[5] + add $xc1,$xc1,@K[2] eor @x[6],@x[6],@x[7] + add $xd1,$xd1,@K[3] eor @x[8],@x[8],@x[9] - eor $A0,$A0,$T0 + eor $xa0,$xa0,$xt0 + movi $xt0,#5 eor @x[10],@x[10],@x[11] - eor $B0,$B0,$T1 + eor $xb0,$xb0,$xt1 eor @x[12],@x[12],@x[13] - eor $C0,$C0,$T2 + eor $xc0,$xc0,$xt2 eor @x[14],@x[14],@x[15] - eor $D0,$D0,$T3 - ld1.8 {$T0-$T3},[$inp],#64 + eor $xd0,$xd0,$xt3 + add $CTR,$CTR,$xt0 // += 5 + ld1.8 {$xt0-$xt3},[$inp],#64 stp @x[0],@x[2],[$out,#0] // store output - add @d[6],@d[6],#4 // increment counter + add @d[6],@d[6],#5 // increment counter stp @x[4],@x[6],[$out,#16] - add @K[3],@K[3],$ONE // += 4 stp @x[8],@x[10],[$out,#32] - add @K[4],@K[4],$ONE stp @x[12],@x[14],[$out,#48] - add @K[5],@K[5],$ONE add $out,$out,#64 - st1.8 {$A0-$D0},[$out],#64 - ld1.8 {$A0-$D0},[$inp],#64 - - eor $A1,$A1,$T0 - eor $B1,$B1,$T1 - eor $C1,$C1,$T2 - eor $D1,$D1,$T3 - st1.8 {$A1-$D1},[$out],#64 - - eor $A2,$A2,$A0 - eor $B2,$B2,$B0 - eor $C2,$C2,$C0 - eor $D2,$D2,$D0 - st1.8 {$A2-$D2},[$out],#64 + st1.8 {$xa0-$xd0},[$out],#64 + add $xa2,$xa2,@K[0] + add $xb2,$xb2,@K[1] + add $xc2,$xc2,@K[2] + add $xd2,$xd2,@K[3] + ld1.8 {$xa0-$xd0},[$inp],#64 + + eor $xa1,$xa1,$xt0 + eor $xb1,$xb1,$xt1 + eor $xc1,$xc1,$xt2 + eor $xd1,$xd1,$xt3 + st1.8 {$xa1-$xd1},[$out],#64 + add $xa3,$xa3,@K[0] + add $xb3,$xb3,@K[1] + add $xc3,$xc3,@K[2] + add $xd3,$xd3,@K[3] + ld1.8 {$xa1-$xd1},[$inp],#64 + + eor $xa2,$xa2,$xa0 + eor $xb2,$xb2,$xb0 + eor $xc2,$xc2,$xc0 + eor $xd2,$xd2,$xd0 + st1.8 {$xa2-$xd2},[$out],#64 + + eor $xa3,$xa3,$xa1 + eor $xb3,$xb3,$xb1 + eor $xc3,$xc3,$xc1 + eor $xd3,$xd3,$xd1 + st1.8 {$xa3-$xd3},[$out],#64 b.hi .Loop_outer_neon + ldp d8,d9,[sp] // meet ABI requirements + ldp x19,x20,[x29,#16] add sp,sp,#64 ldp x21,x22,[x29,#32] @@ -583,8 +670,10 @@ $code.=<<___; .inst 0xd50323bf // autiasp ret +.align 4 .Ltail_neon: - add $len,$len,#256 + add $len,$len,#320 + ldp d8,d9,[sp] // meet ABI requirements cmp $len,#64 b.lo .Less_than_64 @@ -601,7 +690,7 @@ $code.=<<___; add @x[14],@x[14],@x[15],lsl#32 ldp @x[13],@x[15],[$inp,#48] add $inp,$inp,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] @@ -621,48 +710,68 @@ $code.=<<___; eor @x[14],@x[14],@x[15] stp @x[0],@x[2],[$out,#0] // store output - add @d[6],@d[6],#4 // increment counter + add $xa0,$xa0,@K[0] // accumulate key block stp @x[4],@x[6],[$out,#16] + add $xb0,$xb0,@K[1] stp @x[8],@x[10],[$out,#32] + add $xc0,$xc0,@K[2] stp @x[12],@x[14],[$out,#48] + add $xd0,$xd0,@K[3] add $out,$out,#64 b.eq .Ldone_neon sub $len,$len,#64 cmp $len,#64 - b.lo .Less_than_128 - - ld1.8 {$T0-$T3},[$inp],#64 - eor $A0,$A0,$T0 - eor $B0,$B0,$T1 - eor $C0,$C0,$T2 - eor $D0,$D0,$T3 - st1.8 {$A0-$D0},[$out],#64 + b.lo .Last_neon + + ld1.8 {$xt0-$xt3},[$inp],#64 + eor $xa0,$xa0,$xt0 + eor $xb0,$xb0,$xt1 + eor $xc0,$xc0,$xt2 + eor $xd0,$xd0,$xt3 + st1.8 {$xa0-$xd0},[$out],#64 b.eq .Ldone_neon + + add $xa0,$xa1,@K[0] + add $xb0,$xb1,@K[1] sub $len,$len,#64 + add $xc0,$xc1,@K[2] cmp $len,#64 - b.lo .Less_than_192 - - ld1.8 {$T0-$T3},[$inp],#64 - eor $A1,$A1,$T0 - eor $B1,$B1,$T1 - eor $C1,$C1,$T2 - eor $D1,$D1,$T3 - st1.8 {$A1-$D1},[$out],#64 + add $xd0,$xd1,@K[3] + b.lo .Last_neon + + ld1.8 {$xt0-$xt3},[$inp],#64 + eor $xa1,$xa0,$xt0 + eor $xb1,$xb0,$xt1 + eor $xc1,$xc0,$xt2 + eor $xd1,$xd0,$xt3 + st1.8 {$xa1-$xd1},[$out],#64 b.eq .Ldone_neon - sub $len,$len,#64 - st1.8 {$A2-$D2},[sp] - b .Last_neon + add $xa0,$xa2,@K[0] + add $xb0,$xb2,@K[1] + sub $len,$len,#64 + add $xc0,$xc2,@K[2] + cmp $len,#64 + add $xd0,$xd2,@K[3] + b.lo .Last_neon + + ld1.8 {$xt0-$xt3},[$inp],#64 + eor $xa2,$xa0,$xt0 + eor $xb2,$xb0,$xt1 + eor $xc2,$xc0,$xt2 + eor $xd2,$xd0,$xt3 + st1.8 {$xa2-$xd2},[$out],#64 + b.eq .Ldone_neon -.Less_than_128: - st1.8 {$A0-$D0},[sp] - b .Last_neon -.Less_than_192: - st1.8 {$A1-$D1},[sp] - b .Last_neon + add $xa0,$xa3,@K[0] + add $xb0,$xb3,@K[1] + add $xc0,$xc3,@K[2] + add $xd0,$xd3,@K[3] + sub $len,$len,#64 -.align 4 .Last_neon: + st1.8 {$xa0-$xd0},[sp] + sub $out,$out,#1 add $inp,$inp,$len add $out,$out,$len @@ -695,9 +804,41 @@ $code.=<<___; .size ChaCha20_neon,.-ChaCha20_neon ___ { +my @K = map("v$_.4s",(0..6)); my ($T0,$T1,$T2,$T3,$T4,$T5)=@K; my ($A0,$B0,$C0,$D0,$A1,$B1,$C1,$D1,$A2,$B2,$C2,$D2, - $A3,$B3,$C3,$D3,$A4,$B4,$C4,$D4,$A5,$B5,$C5,$D5) = map("v$_.4s",(0..23)); + $A3,$B3,$C3,$D3,$A4,$B4,$C4,$D4,$A5,$B5,$C5,$D5) = map("v$_.4s",(8..31)); +my $rot24 = @K[6]; +my $ONE = "v7.4s"; + +sub NEONROUND { +my $odd = pop; +my ($a,$b,$c,$d,$t)=@_; + + ( + "&add ('$a','$a','$b')", + "&eor ('$d','$d','$a')", + "&rev32_16 ('$d','$d')", # vrot ($d,16) + + "&add ('$c','$c','$d')", + "&eor ('$t','$b','$c')", + "&ushr ('$b','$t',20)", + "&sli ('$b','$t',12)", + + "&add ('$a','$a','$b')", + "&eor ('$d','$d','$a')", + "&tbl ('$d','{$d}','$rot24')", + + "&add ('$c','$c','$d')", + "&eor ('$t','$b','$c')", + "&ushr ('$b','$t',25)", + "&sli ('$b','$t',7)", + + "&ext ('$c','$c','$c',8)", + "&ext ('$d','$d','$d',$odd?4:12)", + "&ext ('$b','$b','$b',$odd?12:4)" + ); +} $code.=<<___; .type ChaCha20_512_neon,%function @@ -717,6 +858,7 @@ ChaCha20_512_neon: .L512_or_more_neon: sub sp,sp,#128+64 + eor $ONE,$ONE,$ONE ldp @d[0],@d[1],[@x[0]] // load sigma ld1 {@K[0]},[@x[0]],#16 ldp @d[2],@d[3],[$key] // load key @@ -724,8 +866,9 @@ ChaCha20_512_neon: ld1 {@K[1],@K[2]},[$key] ldp @d[6],@d[7],[$ctr] // load counter ld1 {@K[3]},[$ctr] - ld1 {$ONE},[@x[0]] -#ifdef __ARMEB__ + ld1 {$ONE}[0],[@x[0]] + add $key,@x[0],#16 // .Lrot24 +#ifdef __AARCH64EB__ rev64 @K[0],@K[0] ror @d[2],@d[2],#32 ror @d[3],@d[3],#32 @@ -792,9 +935,10 @@ ChaCha20_512_neon: mov $C4,@K[2] stp @K[3],@K[4],[sp,#48] // off-load key block, variable part mov $C5,@K[2] - str @K[5],[sp,#80] + stp @K[5],@K[6],[sp,#80] mov $ctr,#5 + ld1 {$rot24},[$key] subs $len,$len,#512 .Loop_upper_neon: sub $ctr,$ctr,#1 @@ -867,7 +1011,7 @@ $code.=<<___; add @x[14],@x[14],@x[15],lsl#32 ldp @x[13],@x[15],[$inp,#48] add $inp,$inp,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] @@ -956,6 +1100,7 @@ $code.=<<___; add.32 @x[2],@x[2],@d[1] ldp @K[4],@K[5],[sp,#64] add @x[3],@x[3],@d[1],lsr#32 + ldr @K[6],[sp,#96] add $A0,$A0,@K[0] add.32 @x[4],@x[4],@d[2] add $A1,$A1,@K[0] @@ -1008,7 +1153,7 @@ $code.=<<___; add $inp,$inp,#64 add $B5,$B5,@K[1] -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] @@ -1086,26 +1231,26 @@ $code.=<<___; b.hs .Loop_outer_512_neon adds $len,$len,#512 - ushr $A0,$ONE,#2 // 4 -> 1 + ushr $ONE,$ONE,#1 // 4 -> 2 - ldp d8,d9,[sp,#128+0] // meet ABI requirements - ldp d10,d11,[sp,#128+16] + ldp d10,d11,[sp,#128+16] // meet ABI requirements ldp d12,d13,[sp,#128+32] ldp d14,d15,[sp,#128+48] - stp @K[0],$ONE,[sp,#0] // wipe off-load area - stp @K[0],$ONE,[sp,#32] - stp @K[0],$ONE,[sp,#64] + stp @K[0],@K[0],[sp,#0] // wipe off-load area + stp @K[0],@K[0],[sp,#32] + stp @K[0],@K[0],[sp,#64] b.eq .Ldone_512_neon + sub $key,$key,#16 // .Lone cmp $len,#192 - sub @K[3],@K[3],$A0 // -= 1 - sub @K[4],@K[4],$A0 - sub @K[5],@K[5],$A0 add sp,sp,#128 + sub @K[3],@K[3],$ONE // -= 2 + ld1 {$CTR,$ROT24},[$key] b.hs .Loop_outer_neon + ldp d8,d9,[sp,#0] // meet ABI requirements eor @K[1],@K[1],@K[1] eor @K[2],@K[2],@K[2] eor @K[3],@K[3],@K[3] @@ -1115,6 +1260,7 @@ $code.=<<___; b .Loop_outer .Ldone_512_neon: + ldp d8,d9,[sp,#128+0] // meet ABI requirements ldp x19,x20,[x29,#16] add sp,sp,#128+64 ldp x21,x22,[x29,#32] @@ -1133,9 +1279,11 @@ foreach (split("\n",$code)) { s/\`([^\`]*)\`/eval $1/geo; (s/\b([a-z]+)\.32\b/$1/ and (s/x([0-9]+)/w$1/g or 1)) or - (m/\b(eor|ext|mov)\b/ and (s/\.4s/\.16b/g or 1)) or + (m/\b(eor|ext|mov|tbl)\b/ and (s/\.4s/\.16b/g or 1)) or (s/\b((?:ld|st)1)\.8\b/$1/ and (s/\.4s/\.16b/g or 1)) or (m/\b(ld|st)[rp]\b/ and (s/v([0-9]+)\.4s/q$1/g or 1)) or + (m/\b(dup|ld1)\b/ and (s/\.4(s}?\[[0-3]\])/.$1/g or 1)) or + (s/\b(zip[12])\.64\b/$1/ and (s/\.4s/\.2d/g or 1)) or (s/\brev32\.16\b/rev32/ and (s/\.4s/\.8h/g or 1)); #s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo; diff --git a/crypto/openssl/crypto/chacha/asm/chacha-c64xplus.pl b/crypto/openssl/crypto/chacha/asm/chacha-c64xplus.pl index 4bd18a4f8f95..a10f7c0aff3f 100755 --- a/crypto/openssl/crypto/chacha/asm/chacha-c64xplus.pl +++ b/crypto/openssl/crypto/chacha/asm/chacha-c64xplus.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -24,8 +24,7 @@ # dependent on input length. This module on the other hand is free # from such limitation. -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; ($OUT,$INP,$LEN,$KEYB,$COUNTERA)=("A4","B4","A6","B6","A8"); ($KEYA,$COUNTERB,$STEP)=("A7","B7","A3"); diff --git a/crypto/openssl/crypto/chacha/asm/chacha-ia64.pl b/crypto/openssl/crypto/chacha/asm/chacha-ia64.pl new file mode 100644 index 000000000000..b13d97285575 --- /dev/null +++ b/crypto/openssl/crypto/chacha/asm/chacha-ia64.pl @@ -0,0 +1,291 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov, @dot-asm, initially for use with OpenSSL. +# ==================================================================== +# +# ChaCha20 for Itanium. +# +# March 2019 +# +# Itanium 9xxx, which has pair of shifters, manages to process one byte +# in 9.3 cycles. This aligns perfectly with theoretical estimate. +# On the other hand, pre-9000 CPU has single shifter and each extr/dep +# pairs below takes additional cycle. Then final input->xor->output +# pass runs slower than expected... Overall result is 15.6 cpb, two +# cycles more than theoretical estimate. + +$output = pop and open STDOUT, ">$output"; + +my @k = map("r$_",(16..31)); +my @x = map("r$_",(38..53)); +my @y = map("r$_",(8..11)); +my @z = map("r$_",(15,35..37)); +my ($out,$inp,$len,$key,$counter) = map("r$_",(32..36)); + +$code.=<<___; +#if defined(_HPUX_SOURCE) +# if !defined(_LP64) +# define ADDP addp4 +# else +# define ADDP add +# endif +#else +# define ADDP add +#endif + +.text + +.global ChaCha20_ctr32# +.proc ChaCha20_ctr32# +.align 32 +ChaCha20_ctr32: + .prologue + .save ar.pfs,r2 +{ .mmi; alloc r2=ar.pfs,5,17,0,0 + ADDP @k[11]=4,$key + .save ar.lc,r3 + mov r3=ar.lc } +{ .mmi; ADDP $key=0,$key + ADDP $counter=0,$counter + .save pr,r14 + mov r14=pr };; + + .body +{ .mlx; ld4 @k[4]=[$key],8 + movl @k[0]=0x61707865 } +{ .mlx; ld4 @k[5]=[@k[11]],8 + movl @k[1]=0x3320646e };; +{ .mlx; ld4 @k[6]=[$key],8 + movl @k[2]=0x79622d32 } +{ .mlx; ld4 @k[7]=[@k[11]],8 + movl @k[3]=0x6b206574 };; +{ .mmi; ld4 @k[8]=[$key],8 + ld4 @k[9]=[@k[11]],8 + add @k[15]=4,$counter };; +{ .mmi; ld4 @k[10]=[$key] + ld4 @k[11]=[@k[11]] + mov @x[0]=@k[0] };; +{ .mmi; ld4 @k[12]=[$counter],8 + ld4 @k[13]=[@k[15]],8 + mov @x[1]=@k[1] };; +{ .mmi; ld4 @k[14]=[$counter] + ld4 @k[15]=[@k[15]] + mov @x[2]=@k[2] } +{ .mmi; mov @x[3]=@k[3] + mov @x[4]=@k[4] + mov @x[5]=@k[5] };; +{ .mmi; mov @x[6]=@k[6] + mov @x[7]=@k[7] + mov @x[8]=@k[8] } +{ .mmi; mov @x[9]=@k[9] + mov @x[10]=@k[10] + mov @x[11]=@k[11] } +{ .mmi; mov @x[12]=@k[12] + mov @x[13]=@k[13] + mov @x[14]=@k[14] };; + +.Loop_outer: +{ .mii; mov @x[15]=@k[15] + mov ar.lc=9 + mov ar.ec=1 } +{ .mmb; cmp.geu p6,p0=64,$len + sub @z[1]=64,$len + brp.loop.imp .Loop_top,.Loop_end-16 };; + +.Loop_top: +___ +sub ROUND { +my ($a0,$b0,$c0,$d0)=@_; +my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0)); +my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1)); +my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2)); + +$code.=<<___; +{ .mmi; add @x[$a0]=@x[$a0],@x[$b0] + add @x[$a1]=@x[$a1],@x[$b1] + add @x[$a2]=@x[$a2],@x[$b2] };; +{ .mmi; add @x[$a3]=@x[$a3],@x[$b3] + xor @x[$d0]=@x[$d0],@x[$a0] + xor @x[$d1]=@x[$d1],@x[$a1] };; +{ .mmi; xor @x[$d2]=@x[$d2],@x[$a2] + xor @x[$d3]=@x[$d3],@x[$a3] + extr.u @y[0]=@x[$d0],16,16 };; +{ .mii; extr.u @y[1]=@x[$d1],16,16 + dep @x[$d0]=@x[$d0],@y[0],16,16 };; +{ .mii; add @x[$c0]=@x[$c0],@x[$d0] + extr.u @y[2]=@x[$d2],16,16 + dep @x[$d1]=@x[$d1],@y[1],16,16 };; +{ .mii; add @x[$c1]=@x[$c1],@x[$d1] + xor @x[$b0]=@x[$b0],@x[$c0] + extr.u @y[3]=@x[$d3],16,16 };; +{ .mii; xor @x[$b1]=@x[$b1],@x[$c1] + dep @x[$d2]=@x[$d2],@y[2],16,16 + dep @x[$d3]=@x[$d3],@y[3],16,16 };; +{ .mmi; add @x[$c2]=@x[$c2],@x[$d2] + add @x[$c3]=@x[$c3],@x[$d3] + extr.u @y[0]=@x[$b0],20,12 };; +{ .mmi; xor @x[$b2]=@x[$b2],@x[$c2] + xor @x[$b3]=@x[$b3],@x[$c3] + dep.z @x[$b0]=@x[$b0],12,20 };; +{ .mii; or @x[$b0]=@x[$b0],@y[0] + extr.u @y[1]=@x[$b1],20,12 + dep.z @x[$b1]=@x[$b1],12,20 };; +{ .mii; add @x[$a0]=@x[$a0],@x[$b0] + extr.u @y[2]=@x[$b2],20,12 + extr.u @y[3]=@x[$b3],20,12 } +{ .mii; or @x[$b1]=@x[$b1],@y[1] + dep.z @x[$b2]=@x[$b2],12,20 + dep.z @x[$b3]=@x[$b3],12,20 };; +{ .mmi; or @x[$b2]=@x[$b2],@y[2] + or @x[$b3]=@x[$b3],@y[3] + add @x[$a1]=@x[$a1],@x[$b1] };; +{ .mmi; add @x[$a2]=@x[$a2],@x[$b2] + add @x[$a3]=@x[$a3],@x[$b3] + xor @x[$d0]=@x[$d0],@x[$a0] };; +{ .mii; xor @x[$d1]=@x[$d1],@x[$a1] + extr.u @y[0]=@x[$d0],24,8 + dep.z @x[$d0]=@x[$d0],8,24 };; +{ .mii; or @x[$d0]=@x[$d0],@y[0] + extr.u @y[1]=@x[$d1],24,8 + dep.z @x[$d1]=@x[$d1],8,24 };; +{ .mmi; or @x[$d1]=@x[$d1],@y[1] + xor @x[$d2]=@x[$d2],@x[$a2] + xor @x[$d3]=@x[$d3],@x[$a3] };; +{ .mii; add @x[$c0]=@x[$c0],@x[$d0] + extr.u @y[2]=@x[$d2],24,8 + dep.z @x[$d2]=@x[$d2],8,24 };; +{ .mii; xor @x[$b0]=@x[$b0],@x[$c0] + extr.u @y[3]=@x[$d3],24,8 + dep.z @x[$d3]=@x[$d3],8,24 };; +{ .mmi; or @x[$d2]=@x[$d2],@y[2] + or @x[$d3]=@x[$d3],@y[3] + extr.u @y[0]=@x[$b0],25,7 };; +{ .mmi; add @x[$c1]=@x[$c1],@x[$d1] + add @x[$c2]=@x[$c2],@x[$d2] + dep.z @x[$b0]=@x[$b0],7,25 };; +{ .mmi; xor @x[$b1]=@x[$b1],@x[$c1] + xor @x[$b2]=@x[$b2],@x[$c2] + add @x[$c3]=@x[$c3],@x[$d3] };; +{ .mii; xor @x[$b3]=@x[$b3],@x[$c3] + extr.u @y[1]=@x[$b1],25,7 + dep.z @x[$b1]=@x[$b1],7,25 };; +{ .mii; or @x[$b0]=@x[$b0],@y[0] + extr.u @y[2]=@x[$b2],25,7 + dep.z @x[$b2]=@x[$b2],7,25 };; +{ .mii; or @x[$b1]=@x[$b1],@y[1] + extr.u @y[3]=@x[$b3],25,7 + dep.z @x[$b3]=@x[$b3],7,25 };; +___ +$code.=<<___ if ($d0 == 12); +{ .mmi; or @x[$b2]=@x[$b2],@y[2] + or @x[$b3]=@x[$b3],@y[3] + mov @z[0]=-1 };; +___ +$code.=<<___ if ($d0 == 15); +{ .mmb; or @x[$b2]=@x[$b2],@y[2] + or @x[$b3]=@x[$b3],@y[3] + br.ctop.sptk .Loop_top };; +___ +} + &ROUND(0, 4, 8, 12); + &ROUND(0, 5, 10, 15); +$code.=<<___; +.Loop_end: + +{ .mmi; add @x[0]=@x[0],@k[0] + add @x[1]=@x[1],@k[1] +(p6) shr.u @z[0]=@z[0],@z[1] } +{ .mmb; add @x[2]=@x[2],@k[2] + add @x[3]=@x[3],@k[3] + clrrrb.pr };; +{ .mmi; add @x[4]=@x[4],@k[4] + add @x[5]=@x[5],@k[5] + add @x[6]=@x[6],@k[6] } +{ .mmi; add @x[7]=@x[7],@k[7] + add @x[8]=@x[8],@k[8] + add @x[9]=@x[9],@k[9] } +{ .mmi; add @x[10]=@x[10],@k[10] + add @x[11]=@x[11],@k[11] + add @x[12]=@x[12],@k[12] } +{ .mmi; add @x[13]=@x[13],@k[13] + add @x[14]=@x[14],@k[14] + add @x[15]=@x[15],@k[15] } +{ .mmi; add @k[12]=1,@k[12] // next counter + mov pr=@z[0],0x1ffff };; + +////////////////////////////////////////////////////////////////// +// Each predicate bit corresponds to byte to be processed. Note +// that p0 is wired to 1, but it works out, because there always +// is at least one byte to process... +{ .mmi; (p0) ld1 @z[0]=[$inp],1 + shr.u @y[1]=@x[0],8 };; +{ .mmi; (p1) ld1 @z[1]=[$inp],1 + (p2) shr.u @y[2]=@x[0],16 };; +{ .mmi; (p2) ld1 @z[2]=[$inp],1 + (p0) xor @z[0]=@z[0],@x[0] + (p3) shr.u @y[3]=@x[0],24 };; +___ +for(my $i0=0; $i0<60; $i0+=4) { +my ($i1, $i2, $i3, $i4, $i5, $i6, $i7) = map($i0+$_,(1..7)); +my $k = $i0/4+1; + +$code.=<<___; +{ .mmi; (p$i3) ld1 @z[3]=[$inp],1 + (p$i0) st1 [$out]=@z[0],1 + (p$i1) xor @z[1]=@z[1],@y[1] };; +{ .mmi; (p$i4) ld1 @z[0]=[$inp],1 + (p$i5) shr.u @y[1]=@x[$k],8 } +{ .mmi; (p$i1) st1 [$out]=@z[1],1 + (p$i2) xor @z[2]=@z[2],@y[2] + (p1) mov @x[$k-1]=@k[$k-1] };; +{ .mfi; (p$i5) ld1 @z[1]=[$inp],1 + (p$i6) shr.u @y[2]=@x[$k],16 } +{ .mfi; (p$i2) st1 [$out]=@z[2],1 + (p$i3) xor @z[3]=@z[3],@y[3] };; +{ .mfi; (p$i6) ld1 @z[2]=[$inp],1 + (p$i7) shr.u @y[3]=@x[$k],24 } +___ +$code.=<<___ if ($i0==0); # p1,p2 are available for reuse in first round +{ .mmi; (p$i3) st1 [$out]=@z[3],1 + (p$i4) xor @z[0]=@z[0],@x[$k] + cmp.ltu p1,p2=64,$len };; +___ +$code.=<<___ if ($i0>0); +{ .mfi; (p$i3) st1 [$out]=@z[3],1 + (p$i4) xor @z[0]=@z[0],@x[$k] };; +___ +} +$code.=<<___; +{ .mmi; (p63) ld1 @z[3]=[$inp],1 + (p60) st1 [$out]=@z[0],1 + (p61) xor @z[1]=@z[1],@y[1] };; +{ .mmi; (p61) st1 [$out]=@z[1],1 + (p62) xor @z[2]=@z[2],@y[2] };; +{ .mmi; (p62) st1 [$out]=@z[2],1 + (p63) xor @z[3]=@z[3],@y[3] + (p2) mov ar.lc=r3 };; +{ .mib; (p63) st1 [$out]=@z[3],1 + (p1) add $len=-64,$len +(p1) br.dptk.many .Loop_outer };; + +{ .mmi; mov @k[4]=0 // wipe key material + mov @k[5]=0 + mov @k[6]=0 } +{ .mmi; mov @k[7]=0 + mov @k[8]=0 + mov @k[9]=0 } +{ .mmi; mov @k[10]=0 + mov @k[11]=0 + mov @k[12]=0 } +{ .mmi; mov @k[13]=0 + mov @k[14]=0 + mov @k[15]=0 } +{ .mib; mov pr=r14,0x1ffff + br.ret.sptk.many b0 };; +.endp ChaCha20_ctr32# +stringz "ChaCha20 for IA64, CRYPTOGAMS by \@dot-asm" +___ + +print $code; +close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/chacha/asm/chacha-ppc.pl b/crypto/openssl/crypto/chacha/asm/chacha-ppc.pl index 3073deac17ee..60982dddb211 100755 --- a/crypto/openssl/crypto/chacha/asm/chacha-ppc.pl +++ b/crypto/openssl/crypto/chacha/asm/chacha-ppc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -44,7 +44,10 @@ # instructions, which is why switch to vector-only code pays # off that much; -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -69,7 +72,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $LOCALS=6*$SIZE_T; $FRAME=$LOCALS+64+18*$SIZE_T; # 64 is for local variables diff --git a/crypto/openssl/crypto/chacha/asm/chacha-s390x.pl b/crypto/openssl/crypto/chacha/asm/chacha-s390x.pl index dd66a9c60309..9e29ebccb596 100755 --- a/crypto/openssl/crypto/chacha/asm/chacha-s390x.pl +++ b/crypto/openssl/crypto/chacha/asm/chacha-s390x.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2016-2020 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 +# 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 @@ -20,41 +20,53 @@ # # 3 times faster than compiler-generated code. -$flavour = shift; +# +# August 2018 +# +# Add vx code path: 4x"vertical". +# +# Copyright IBM Corp. 2018 +# Author: Patrick Steuer + +# +# February 2019 +# +# Add 6x"horizontal" VX implementation. It's ~25% faster than IBM's +# 4x"vertical" submission [on z13] and >3 faster than scalar code. +# But to harness overheads revert to transliteration of VSX code path +# from chacha-ppc module, which is also 4x"vertical", to handle inputs +# not longer than 256 bytes. + +use strict; +use FindBin qw($Bin); +use lib "$Bin/../.."; +use perlasm::s390x qw(:DEFAULT :VX :EI AUTOLOAD LABEL INCLUDE); +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +my ($z,$SIZE_T); if ($flavour =~ /3[12]/) { + $z=0; # S/390 ABI $SIZE_T=4; - $g=""; } else { + $z=1; # zSeries ABI $SIZE_T=8; - $g="g"; -} - -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; - -sub AUTOLOAD() # thunk [simplified] x86-style perlasm -{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; - $code .= "\t$opcode\t".join(',',@_)."\n"; } my $sp="%r15"; - my $stdframe=16*$SIZE_T+4*8; -my $frame=$stdframe+4*20; - -my ($out,$inp,$len,$key,$counter)=map("%r$_",(2..6)); +sub ROUND { my @x=map("%r$_",(0..7,"x","x","x","x",(10..13))); my @t=map("%r$_",(8,9)); - -sub ROUND { my ($a0,$b0,$c0,$d0)=@_; my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0)); my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1)); my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2)); -my ($xc,$xc_)=map("\"$_\"",@t); -my @x=map("\"$_\"",@x); +my ($xc,$xc_)=map("$_",@t); # Consider order in which variables are addressed by their # index: @@ -78,249 +90,967 @@ my @x=map("\"$_\"",@x); # 'c' stores and loads in the middle, but none in the beginning # or end. - ( - "&alr (@x[$a0],@x[$b0])", # Q1 - "&alr (@x[$a1],@x[$b1])", # Q2 - "&xr (@x[$d0],@x[$a0])", - "&xr (@x[$d1],@x[$a1])", - "&rll (@x[$d0],@x[$d0],16)", - "&rll (@x[$d1],@x[$d1],16)", - - "&alr ($xc,@x[$d0])", - "&alr ($xc_,@x[$d1])", - "&xr (@x[$b0],$xc)", - "&xr (@x[$b1],$xc_)", - "&rll (@x[$b0],@x[$b0],12)", - "&rll (@x[$b1],@x[$b1],12)", - - "&alr (@x[$a0],@x[$b0])", - "&alr (@x[$a1],@x[$b1])", - "&xr (@x[$d0],@x[$a0])", - "&xr (@x[$d1],@x[$a1])", - "&rll (@x[$d0],@x[$d0],8)", - "&rll (@x[$d1],@x[$d1],8)", - - "&alr ($xc,@x[$d0])", - "&alr ($xc_,@x[$d1])", - "&xr (@x[$b0],$xc)", - "&xr (@x[$b1],$xc_)", - "&rll (@x[$b0],@x[$b0],7)", - "&rll (@x[$b1],@x[$b1],7)", - - "&stm ($xc,$xc_,'$stdframe+4*8+4*$c0($sp)')", # reload pair of 'c's - "&lm ($xc,$xc_,'$stdframe+4*8+4*$c2($sp)')", - - "&alr (@x[$a2],@x[$b2])", # Q3 - "&alr (@x[$a3],@x[$b3])", # Q4 - "&xr (@x[$d2],@x[$a2])", - "&xr (@x[$d3],@x[$a3])", - "&rll (@x[$d2],@x[$d2],16)", - "&rll (@x[$d3],@x[$d3],16)", - - "&alr ($xc,@x[$d2])", - "&alr ($xc_,@x[$d3])", - "&xr (@x[$b2],$xc)", - "&xr (@x[$b3],$xc_)", - "&rll (@x[$b2],@x[$b2],12)", - "&rll (@x[$b3],@x[$b3],12)", - - "&alr (@x[$a2],@x[$b2])", - "&alr (@x[$a3],@x[$b3])", - "&xr (@x[$d2],@x[$a2])", - "&xr (@x[$d3],@x[$a3])", - "&rll (@x[$d2],@x[$d2],8)", - "&rll (@x[$d3],@x[$d3],8)", - - "&alr ($xc,@x[$d2])", - "&alr ($xc_,@x[$d3])", - "&xr (@x[$b2],$xc)", - "&xr (@x[$b3],$xc_)", - "&rll (@x[$b2],@x[$b2],7)", - "&rll (@x[$b3],@x[$b3],7)" - ); + alr (@x[$a0],@x[$b0]); # Q1 + alr (@x[$a1],@x[$b1]); # Q2 + xr (@x[$d0],@x[$a0]); + xr (@x[$d1],@x[$a1]); + rll (@x[$d0],@x[$d0],16); + rll (@x[$d1],@x[$d1],16); + + alr ($xc,@x[$d0]); + alr ($xc_,@x[$d1]); + xr (@x[$b0],$xc); + xr (@x[$b1],$xc_); + rll (@x[$b0],@x[$b0],12); + rll (@x[$b1],@x[$b1],12); + + alr (@x[$a0],@x[$b0]); + alr (@x[$a1],@x[$b1]); + xr (@x[$d0],@x[$a0]); + xr (@x[$d1],@x[$a1]); + rll (@x[$d0],@x[$d0],8); + rll (@x[$d1],@x[$d1],8); + + alr ($xc,@x[$d0]); + alr ($xc_,@x[$d1]); + xr (@x[$b0],$xc); + xr (@x[$b1],$xc_); + rll (@x[$b0],@x[$b0],7); + rll (@x[$b1],@x[$b1],7); + + stm ($xc,$xc_,"$stdframe+4*8+4*$c0($sp)"); # reload pair of 'c's + lm ($xc,$xc_,"$stdframe+4*8+4*$c2($sp)"); + + alr (@x[$a2],@x[$b2]); # Q3 + alr (@x[$a3],@x[$b3]); # Q4 + xr (@x[$d2],@x[$a2]); + xr (@x[$d3],@x[$a3]); + rll (@x[$d2],@x[$d2],16); + rll (@x[$d3],@x[$d3],16); + + alr ($xc,@x[$d2]); + alr ($xc_,@x[$d3]); + xr (@x[$b2],$xc); + xr (@x[$b3],$xc_); + rll (@x[$b2],@x[$b2],12); + rll (@x[$b3],@x[$b3],12); + + alr (@x[$a2],@x[$b2]); + alr (@x[$a3],@x[$b3]); + xr (@x[$d2],@x[$a2]); + xr (@x[$d3],@x[$a3]); + rll (@x[$d2],@x[$d2],8); + rll (@x[$d3],@x[$d3],8); + + alr ($xc,@x[$d2]); + alr ($xc_,@x[$d3]); + xr (@x[$b2],$xc); + xr (@x[$b3],$xc_); + rll (@x[$b2],@x[$b2],7); + rll (@x[$b3],@x[$b3],7); +} + +sub VX_lane_ROUND { +my ($a0,$b0,$c0,$d0)=@_; +my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0)); +my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1)); +my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2)); +my @x=map("%v$_",(0..15)); + + vaf (@x[$a0],@x[$a0],@x[$b0]); # Q1 + vx (@x[$d0],@x[$d0],@x[$a0]); + verllf (@x[$d0],@x[$d0],16); + vaf (@x[$a1],@x[$a1],@x[$b1]); # Q2 + vx (@x[$d1],@x[$d1],@x[$a1]); + verllf (@x[$d1],@x[$d1],16); + vaf (@x[$a2],@x[$a2],@x[$b2]); # Q3 + vx (@x[$d2],@x[$d2],@x[$a2]); + verllf (@x[$d2],@x[$d2],16); + vaf (@x[$a3],@x[$a3],@x[$b3]); # Q4 + vx (@x[$d3],@x[$d3],@x[$a3]); + verllf (@x[$d3],@x[$d3],16); + + vaf (@x[$c0],@x[$c0],@x[$d0]); + vx (@x[$b0],@x[$b0],@x[$c0]); + verllf (@x[$b0],@x[$b0],12); + vaf (@x[$c1],@x[$c1],@x[$d1]); + vx (@x[$b1],@x[$b1],@x[$c1]); + verllf (@x[$b1],@x[$b1],12); + vaf (@x[$c2],@x[$c2],@x[$d2]); + vx (@x[$b2],@x[$b2],@x[$c2]); + verllf (@x[$b2],@x[$b2],12); + vaf (@x[$c3],@x[$c3],@x[$d3]); + vx (@x[$b3],@x[$b3],@x[$c3]); + verllf (@x[$b3],@x[$b3],12); + + vaf (@x[$a0],@x[$a0],@x[$b0]); + vx (@x[$d0],@x[$d0],@x[$a0]); + verllf (@x[$d0],@x[$d0],8); + vaf (@x[$a1],@x[$a1],@x[$b1]); + vx (@x[$d1],@x[$d1],@x[$a1]); + verllf (@x[$d1],@x[$d1],8); + vaf (@x[$a2],@x[$a2],@x[$b2]); + vx (@x[$d2],@x[$d2],@x[$a2]); + verllf (@x[$d2],@x[$d2],8); + vaf (@x[$a3],@x[$a3],@x[$b3]); + vx (@x[$d3],@x[$d3],@x[$a3]); + verllf (@x[$d3],@x[$d3],8); + + vaf (@x[$c0],@x[$c0],@x[$d0]); + vx (@x[$b0],@x[$b0],@x[$c0]); + verllf (@x[$b0],@x[$b0],7); + vaf (@x[$c1],@x[$c1],@x[$d1]); + vx (@x[$b1],@x[$b1],@x[$c1]); + verllf (@x[$b1],@x[$b1],7); + vaf (@x[$c2],@x[$c2],@x[$d2]); + vx (@x[$b2],@x[$b2],@x[$c2]); + verllf (@x[$b2],@x[$b2],7); + vaf (@x[$c3],@x[$c3],@x[$d3]); + vx (@x[$b3],@x[$b3],@x[$c3]); + verllf (@x[$b3],@x[$b3],7); +} + +sub VX_ROUND { +my @a=@_[0..5]; +my @b=@_[6..11]; +my @c=@_[12..17]; +my @d=@_[18..23]; +my $odd=@_[24]; + + vaf (@a[$_],@a[$_],@b[$_]) for (0..5); + vx (@d[$_],@d[$_],@a[$_]) for (0..5); + verllf (@d[$_],@d[$_],16) for (0..5); + + vaf (@c[$_],@c[$_],@d[$_]) for (0..5); + vx (@b[$_],@b[$_],@c[$_]) for (0..5); + verllf (@b[$_],@b[$_],12) for (0..5); + + vaf (@a[$_],@a[$_],@b[$_]) for (0..5); + vx (@d[$_],@d[$_],@a[$_]) for (0..5); + verllf (@d[$_],@d[$_],8) for (0..5); + + vaf (@c[$_],@c[$_],@d[$_]) for (0..5); + vx (@b[$_],@b[$_],@c[$_]) for (0..5); + verllf (@b[$_],@b[$_],7) for (0..5); + + vsldb (@c[$_],@c[$_],@c[$_],8) for (0..5); + vsldb (@b[$_],@b[$_],@b[$_],$odd?12:4) for (0..5); + vsldb (@d[$_],@d[$_],@d[$_],$odd?4:12) for (0..5); +} + +PERLASM_BEGIN($output); + +INCLUDE ("s390x_arch.h"); +TEXT (); + +################ +# void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len, +# const unsigned int key[8], const unsigned int counter[4]) +my ($out,$inp,$len,$key,$counter)=map("%r$_",(2..6)); +{ +my $frame=$stdframe+4*20; +my @x=map("%r$_",(0..7,"x","x","x","x",(10..13))); +my @t=map("%r$_",(8,9)); + +GLOBL ("ChaCha20_ctr32"); +TYPE ("ChaCha20_ctr32","\@function"); +ALIGN (32); +LABEL ("ChaCha20_ctr32"); + larl ("%r1","OPENSSL_s390xcap_P"); + + lghi ("%r0",64); +&{$z? \<gr:\<r} ($len,$len); # len==0? + bzr ("%r14"); + lg ("%r1","S390X_STFLE+16(%r1)"); +&{$z? \&clgr:\&clr} ($len,"%r0"); + jle (".Lshort"); + + tmhh ("%r1",0x4000); # check for vx bit + jnz (".LChaCha20_ctr32_vx"); + +LABEL (".Lshort"); +&{$z? \&aghi:\&ahi} ($len,-64); +&{$z? \&lghi:\&lhi} ("%r1",-$frame); +&{$z? \&stmg:\&stm} ("%r6","%r15","6*$SIZE_T($sp)"); +&{$z? \&slgr:\&slr} ($out,$inp); # difference + la ($len,"0($inp,$len)"); # end of input minus 64 + larl ("%r7",".Lsigma"); + lgr ("%r0",$sp); + la ($sp,"0(%r1,$sp)"); +&{$z? \&stg:\&st} ("%r0","0($sp)"); + + lmg ("%r8","%r11","0($key)"); # load key + lmg ("%r12","%r13","0($counter)"); # load counter + lmg ("%r6","%r7","0(%r7)"); # load sigma constant + + la ("%r14","0($inp)"); +&{$z? \&stg:\&st} ($out,"$frame+3*$SIZE_T($sp)"); +&{$z? \&stg:\&st} ($len,"$frame+4*$SIZE_T($sp)"); + stmg ("%r6","%r13","$stdframe($sp)");# copy key schedule to stack + srlg (@x[12],"%r12",32); # 32-bit counter value + j (".Loop_outer"); + +ALIGN (16); +LABEL (".Loop_outer"); + lm (@x[0],@x[7],"$stdframe+4*0($sp)"); # load x[0]-x[7] + lm (@t[0],@t[1],"$stdframe+4*10($sp)"); # load x[10]-x[11] + lm (@x[13],@x[15],"$stdframe+4*13($sp)"); # load x[13]-x[15] + stm (@t[0],@t[1],"$stdframe+4*8+4*10($sp)");# offload x[10]-x[11] + lm (@t[0],@t[1],"$stdframe+4*8($sp)"); # load x[8]-x[9] + st (@x[12],"$stdframe+4*12($sp)"); # save counter +&{$z? \&stg:\&st} ("%r14","$frame+2*$SIZE_T($sp)");# save input pointer + lhi ("%r14",10); + j (".Loop"); + +ALIGN (4); +LABEL (".Loop"); + ROUND (0, 4, 8,12); + ROUND (0, 5,10,15); + brct ("%r14",".Loop"); + +&{$z? \&lg:\&l} ("%r14","$frame+2*$SIZE_T($sp)");# pull input pointer + stm (@t[0],@t[1],"$stdframe+4*8+4*8($sp)"); # offload x[8]-x[9] +&{$z? \&lmg:\&lm} (@t[0],@t[1],"$frame+3*$SIZE_T($sp)"); + + al (@x[0],"$stdframe+4*0($sp)"); # accumulate key schedule + al (@x[1],"$stdframe+4*1($sp)"); + al (@x[2],"$stdframe+4*2($sp)"); + al (@x[3],"$stdframe+4*3($sp)"); + al (@x[4],"$stdframe+4*4($sp)"); + al (@x[5],"$stdframe+4*5($sp)"); + al (@x[6],"$stdframe+4*6($sp)"); + al (@x[7],"$stdframe+4*7($sp)"); + lrvr (@x[0],@x[0]); + lrvr (@x[1],@x[1]); + lrvr (@x[2],@x[2]); + lrvr (@x[3],@x[3]); + lrvr (@x[4],@x[4]); + lrvr (@x[5],@x[5]); + lrvr (@x[6],@x[6]); + lrvr (@x[7],@x[7]); + al (@x[12],"$stdframe+4*12($sp)"); + al (@x[13],"$stdframe+4*13($sp)"); + al (@x[14],"$stdframe+4*14($sp)"); + al (@x[15],"$stdframe+4*15($sp)"); + lrvr (@x[12],@x[12]); + lrvr (@x[13],@x[13]); + lrvr (@x[14],@x[14]); + lrvr (@x[15],@x[15]); + + la (@t[0],"0(@t[0],%r14)"); # reconstruct output pointer +&{$z? \&clgr:\&clr} ("%r14",@t[1]); + jh (".Ltail"); + + x (@x[0],"4*0(%r14)"); # xor with input + x (@x[1],"4*1(%r14)"); + st (@x[0],"4*0(@t[0])"); # store output + x (@x[2],"4*2(%r14)"); + st (@x[1],"4*1(@t[0])"); + x (@x[3],"4*3(%r14)"); + st (@x[2],"4*2(@t[0])"); + x (@x[4],"4*4(%r14)"); + st (@x[3],"4*3(@t[0])"); + lm (@x[0],@x[3],"$stdframe+4*8+4*8($sp)"); # load x[8]-x[11] + x (@x[5],"4*5(%r14)"); + st (@x[4],"4*4(@t[0])"); + x (@x[6],"4*6(%r14)"); + al (@x[0],"$stdframe+4*8($sp)"); + st (@x[5],"4*5(@t[0])"); + x (@x[7],"4*7(%r14)"); + al (@x[1],"$stdframe+4*9($sp)"); + st (@x[6],"4*6(@t[0])"); + x (@x[12],"4*12(%r14)"); + al (@x[2],"$stdframe+4*10($sp)"); + st (@x[7],"4*7(@t[0])"); + x (@x[13],"4*13(%r14)"); + al (@x[3],"$stdframe+4*11($sp)"); + st (@x[12],"4*12(@t[0])"); + x (@x[14],"4*14(%r14)"); + st (@x[13],"4*13(@t[0])"); + x (@x[15],"4*15(%r14)"); + st (@x[14],"4*14(@t[0])"); + lrvr (@x[0],@x[0]); + st (@x[15],"4*15(@t[0])"); + lrvr (@x[1],@x[1]); + lrvr (@x[2],@x[2]); + lrvr (@x[3],@x[3]); + lhi (@x[12],1); + x (@x[0],"4*8(%r14)"); + al (@x[12],"$stdframe+4*12($sp)"); # increment counter + x (@x[1],"4*9(%r14)"); + st (@x[0],"4*8(@t[0])"); + x (@x[2],"4*10(%r14)"); + st (@x[1],"4*9(@t[0])"); + x (@x[3],"4*11(%r14)"); + st (@x[2],"4*10(@t[0])"); + st (@x[3],"4*11(@t[0])"); + +&{$z? \&clgr:\&clr} ("%r14",@t[1]); # done yet? + la ("%r14","64(%r14)"); + jl (".Loop_outer"); + +LABEL (".Ldone"); + xgr ("%r0","%r0"); + xgr ("%r1","%r1"); + xgr ("%r2","%r2"); + xgr ("%r3","%r3"); + stmg ("%r0","%r3","$stdframe+4*4($sp)"); # wipe key copy + stmg ("%r0","%r3","$stdframe+4*12($sp)"); + +&{$z? \&lmg:\&lm} ("%r6","%r15","$frame+6*$SIZE_T($sp)"); + br ("%r14"); + +ALIGN (16); +LABEL (".Ltail"); + la (@t[1],"64($t[1])"); + stm (@x[0],@x[7],"$stdframe+4*0($sp)"); +&{$z? \&slgr:\&slr} (@t[1],"%r14"); + lm (@x[0],@x[3],"$stdframe+4*8+4*8($sp)"); +&{$z? \&lghi:\&lhi} (@x[6],0); + stm (@x[12],@x[15],"$stdframe+4*12($sp)"); + al (@x[0],"$stdframe+4*8($sp)"); + al (@x[1],"$stdframe+4*9($sp)"); + al (@x[2],"$stdframe+4*10($sp)"); + al (@x[3],"$stdframe+4*11($sp)"); + lrvr (@x[0],@x[0]); + lrvr (@x[1],@x[1]); + lrvr (@x[2],@x[2]); + lrvr (@x[3],@x[3]); + stm (@x[0],@x[3],"$stdframe+4*8($sp)"); + +LABEL (".Loop_tail"); + llgc (@x[4],"0(@x[6],%r14)"); + llgc (@x[5],"$stdframe(@x[6],$sp)"); + xr (@x[5],@x[4]); + stc (@x[5],"0(@x[6],@t[0])"); + la (@x[6],"1(@x[6])"); + brct (@t[1],".Loop_tail"); + + j (".Ldone"); +SIZE ("ChaCha20_ctr32",".-ChaCha20_ctr32"); } -$code.=<<___; -.text - -.globl ChaCha20_ctr32 -.type ChaCha20_ctr32,\@function -.align 32 -ChaCha20_ctr32: - lt${g}r $len,$len # $len==0? - bzr %r14 - a${g}hi $len,-64 - l${g}hi %r1,-$frame - stm${g} %r6,%r15,`6*$SIZE_T`($sp) - sl${g}r $out,$inp # difference - la $len,0($inp,$len) # end of input minus 64 - larl %r7,.Lsigma - lgr %r0,$sp - la $sp,0(%r1,$sp) - st${g} %r0,0($sp) - - lmg %r8,%r11,0($key) # load key - lmg %r12,%r13,0($counter) # load counter - lmg %r6,%r7,0(%r7) # load sigma constant - - la %r14,0($inp) - st${g} $out,$frame+3*$SIZE_T($sp) - st${g} $len,$frame+4*$SIZE_T($sp) - stmg %r6,%r13,$stdframe($sp) # copy key schedule to stack - srlg @x[12],%r12,32 # 32-bit counter value - j .Loop_outer - -.align 16 -.Loop_outer: - lm @x[0],@x[7],$stdframe+4*0($sp) # load x[0]-x[7] - lm @t[0],@t[1],$stdframe+4*10($sp) # load x[10]-x[11] - lm @x[13],@x[15],$stdframe+4*13($sp) # load x[13]-x[15] - stm @t[0],@t[1],$stdframe+4*8+4*10($sp) # offload x[10]-x[11] - lm @t[0],@t[1],$stdframe+4*8($sp) # load x[8]-x[9] - st @x[12],$stdframe+4*12($sp) # save counter - st${g} %r14,$frame+2*$SIZE_T($sp) # save input pointer - lhi %r14,10 - j .Loop - -.align 4 -.Loop: -___ - foreach (&ROUND(0, 4, 8,12)) { eval; } - foreach (&ROUND(0, 5,10,15)) { eval; } -$code.=<<___; - brct %r14,.Loop - - l${g} %r14,$frame+2*$SIZE_T($sp) # pull input pointer - stm @t[0],@t[1],$stdframe+4*8+4*8($sp) # offload x[8]-x[9] - lm${g} @t[0],@t[1],$frame+3*$SIZE_T($sp) - - al @x[0],$stdframe+4*0($sp) # accumulate key schedule - al @x[1],$stdframe+4*1($sp) - al @x[2],$stdframe+4*2($sp) - al @x[3],$stdframe+4*3($sp) - al @x[4],$stdframe+4*4($sp) - al @x[5],$stdframe+4*5($sp) - al @x[6],$stdframe+4*6($sp) - al @x[7],$stdframe+4*7($sp) - lrvr @x[0],@x[0] - lrvr @x[1],@x[1] - lrvr @x[2],@x[2] - lrvr @x[3],@x[3] - lrvr @x[4],@x[4] - lrvr @x[5],@x[5] - lrvr @x[6],@x[6] - lrvr @x[7],@x[7] - al @x[12],$stdframe+4*12($sp) - al @x[13],$stdframe+4*13($sp) - al @x[14],$stdframe+4*14($sp) - al @x[15],$stdframe+4*15($sp) - lrvr @x[12],@x[12] - lrvr @x[13],@x[13] - lrvr @x[14],@x[14] - lrvr @x[15],@x[15] - - la @t[0],0(@t[0],%r14) # reconstruct output pointer - cl${g}r %r14,@t[1] - jh .Ltail - - x @x[0],4*0(%r14) # xor with input - x @x[1],4*1(%r14) - st @x[0],4*0(@t[0]) # store output - x @x[2],4*2(%r14) - st @x[1],4*1(@t[0]) - x @x[3],4*3(%r14) - st @x[2],4*2(@t[0]) - x @x[4],4*4(%r14) - st @x[3],4*3(@t[0]) - lm @x[0],@x[3],$stdframe+4*8+4*8($sp) # load x[8]-x[11] - x @x[5],4*5(%r14) - st @x[4],4*4(@t[0]) - x @x[6],4*6(%r14) - al @x[0],$stdframe+4*8($sp) - st @x[5],4*5(@t[0]) - x @x[7],4*7(%r14) - al @x[1],$stdframe+4*9($sp) - st @x[6],4*6(@t[0]) - x @x[12],4*12(%r14) - al @x[2],$stdframe+4*10($sp) - st @x[7],4*7(@t[0]) - x @x[13],4*13(%r14) - al @x[3],$stdframe+4*11($sp) - st @x[12],4*12(@t[0]) - x @x[14],4*14(%r14) - st @x[13],4*13(@t[0]) - x @x[15],4*15(%r14) - st @x[14],4*14(@t[0]) - lrvr @x[0],@x[0] - st @x[15],4*15(@t[0]) - lrvr @x[1],@x[1] - lrvr @x[2],@x[2] - lrvr @x[3],@x[3] - lhi @x[12],1 - x @x[0],4*8(%r14) - al @x[12],$stdframe+4*12($sp) # increment counter - x @x[1],4*9(%r14) - st @x[0],4*8(@t[0]) - x @x[2],4*10(%r14) - st @x[1],4*9(@t[0]) - x @x[3],4*11(%r14) - st @x[2],4*10(@t[0]) - st @x[3],4*11(@t[0]) - - cl${g}r %r14,@t[1] # done yet? - la %r14,64(%r14) - jl .Loop_outer - -.Ldone: - xgr %r0,%r0 - xgr %r1,%r1 - xgr %r2,%r2 - xgr %r3,%r3 - stmg %r0,%r3,$stdframe+4*4($sp) # wipe key copy - stmg %r0,%r3,$stdframe+4*12($sp) - - lm${g} %r6,%r15,`$frame+6*$SIZE_T`($sp) - br %r14 - -.align 16 -.Ltail: - la @t[1],64($t[1]) - stm @x[0],@x[7],$stdframe+4*0($sp) - sl${g}r @t[1],%r14 - lm @x[0],@x[3],$stdframe+4*8+4*8($sp) - l${g}hi @x[6],0 - stm @x[12],@x[15],$stdframe+4*12($sp) - al @x[0],$stdframe+4*8($sp) - al @x[1],$stdframe+4*9($sp) - al @x[2],$stdframe+4*10($sp) - al @x[3],$stdframe+4*11($sp) - lrvr @x[0],@x[0] - lrvr @x[1],@x[1] - lrvr @x[2],@x[2] - lrvr @x[3],@x[3] - stm @x[0],@x[3],$stdframe+4*8($sp) - -.Loop_tail: - llgc @x[4],0(@x[6],%r14) - llgc @x[5],$stdframe(@x[6],$sp) - xr @x[5],@x[4] - stc @x[5],0(@x[6],@t[0]) - la @x[6],1(@x[6]) - brct @t[1],.Loop_tail - - j .Ldone -.size ChaCha20_ctr32,.-ChaCha20_ctr32 - -.align 32 -.Lsigma: -.long 0x61707865,0x3320646e,0x79622d32,0x6b206574 # endian-neutral -.asciz "ChaCha20 for s390x, CRYPTOGAMS by " -.align 4 -___ - -foreach (split("\n",$code)) { - s/\`([^\`]*)\`/eval $1/ge; - - print $_,"\n"; +######################################################################## +# 4x"vertical" layout minimizes amount of instructions, but pipeline +# runs underutilized [because of vector instructions' high latency]. +# On the other hand minimum amount of data it takes to fully utilize +# the pipeline is higher, so that effectively, short inputs would be +# processed slower. Hence this code path targeting <=256 bytes lengths. +# +{ +my ($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3, + $xc0,$xc1,$xc2,$xc3, $xd0,$xd1,$xd2,$xd3)=map("%v$_",(0..15)); +my @K=map("%v$_",(16..19)); +my $CTR="%v26"; +my ($xt0,$xt1,$xt2,$xt3)=map("%v$_",(27..30)); +my $beperm="%v31"; +my ($x00,$x10,$x20,$x30)=(0,map("r$_",(8..10))); +my $FRAME=$stdframe+4*16; + +ALIGN (32); +LABEL ("ChaCha20_ctr32_4x"); +LABEL (".LChaCha20_ctr32_4x"); +&{$z? \&stmg:\&stm} ("%r6","%r7","6*$SIZE_T($sp)"); +if (!$z) { + std ("%f4","16*$SIZE_T+2*8($sp)"); + std ("%f6","16*$SIZE_T+3*8($sp)"); } -close STDOUT or die "error closing STDOUT: $!"; +&{$z? \&lghi:\&lhi} ("%r1",-$FRAME); + lgr ("%r0",$sp); + la ($sp,"0(%r1,$sp)"); +&{$z? \&stg:\&st} ("%r0","0($sp)"); # back-chain +if ($z) { + std ("%f8","$stdframe+8*0($sp)"); + std ("%f9","$stdframe+8*1($sp)"); + std ("%f10","$stdframe+8*2($sp)"); + std ("%f11","$stdframe+8*3($sp)"); + std ("%f12","$stdframe+8*4($sp)"); + std ("%f13","$stdframe+8*5($sp)"); + std ("%f14","$stdframe+8*6($sp)"); + std ("%f15","$stdframe+8*7($sp)"); +} + larl ("%r7",".Lsigma"); + lhi ("%r0",10); + lhi ("%r1",0); + + vl (@K[0],"0(%r7)"); # load sigma + vl (@K[1],"0($key)"); # load key + vl (@K[2],"16($key)"); + vl (@K[3],"0($counter)"); # load counter + + vl ($beperm,"0x40(%r7)"); + vl ($xt1,"0x50(%r7)"); + vrepf ($CTR,@K[3],0); + vlvgf (@K[3],"%r1",0); # clear @K[3].word[0] + vaf ($CTR,$CTR,$xt1); + +#LABEL (".Loop_outer_4x"); + vlm ($xa0,$xa3,"0x60(%r7)"); # load [smashed] sigma + + vrepf ($xb0,@K[1],0); # smash the key + vrepf ($xb1,@K[1],1); + vrepf ($xb2,@K[1],2); + vrepf ($xb3,@K[1],3); + + vrepf ($xc0,@K[2],0); + vrepf ($xc1,@K[2],1); + vrepf ($xc2,@K[2],2); + vrepf ($xc3,@K[2],3); + + vlr ($xd0,$CTR); + vrepf ($xd1,@K[3],1); + vrepf ($xd2,@K[3],2); + vrepf ($xd3,@K[3],3); + +LABEL (".Loop_4x"); + VX_lane_ROUND(0, 4, 8,12); + VX_lane_ROUND(0, 5,10,15); + brct ("%r0",".Loop_4x"); + + vaf ($xd0,$xd0,$CTR); + + vmrhf ($xt0,$xa0,$xa1); # transpose data + vmrhf ($xt1,$xa2,$xa3); + vmrlf ($xt2,$xa0,$xa1); + vmrlf ($xt3,$xa2,$xa3); + vpdi ($xa0,$xt0,$xt1,0b0000); + vpdi ($xa1,$xt0,$xt1,0b0101); + vpdi ($xa2,$xt2,$xt3,0b0000); + vpdi ($xa3,$xt2,$xt3,0b0101); + + vmrhf ($xt0,$xb0,$xb1); + vmrhf ($xt1,$xb2,$xb3); + vmrlf ($xt2,$xb0,$xb1); + vmrlf ($xt3,$xb2,$xb3); + vpdi ($xb0,$xt0,$xt1,0b0000); + vpdi ($xb1,$xt0,$xt1,0b0101); + vpdi ($xb2,$xt2,$xt3,0b0000); + vpdi ($xb3,$xt2,$xt3,0b0101); + + vmrhf ($xt0,$xc0,$xc1); + vmrhf ($xt1,$xc2,$xc3); + vmrlf ($xt2,$xc0,$xc1); + vmrlf ($xt3,$xc2,$xc3); + vpdi ($xc0,$xt0,$xt1,0b0000); + vpdi ($xc1,$xt0,$xt1,0b0101); + vpdi ($xc2,$xt2,$xt3,0b0000); + vpdi ($xc3,$xt2,$xt3,0b0101); + + vmrhf ($xt0,$xd0,$xd1); + vmrhf ($xt1,$xd2,$xd3); + vmrlf ($xt2,$xd0,$xd1); + vmrlf ($xt3,$xd2,$xd3); + vpdi ($xd0,$xt0,$xt1,0b0000); + vpdi ($xd1,$xt0,$xt1,0b0101); + vpdi ($xd2,$xt2,$xt3,0b0000); + vpdi ($xd3,$xt2,$xt3,0b0101); + + #vrepif ($xt0,4); + #vaf ($CTR,$CTR,$xt0); # next counter value + + vaf ($xa0,$xa0,@K[0]); + vaf ($xb0,$xb0,@K[1]); + vaf ($xc0,$xc0,@K[2]); + vaf ($xd0,$xd0,@K[3]); + + vperm ($xa0,$xa0,$xa0,$beperm); + vperm ($xb0,$xb0,$xb0,$beperm); + vperm ($xc0,$xc0,$xc0,$beperm); + vperm ($xd0,$xd0,$xd0,$beperm); + + #&{$z? \&clgfi:\&clfi} ($len,0x40); + #jl (".Ltail_4x"); + + vlm ($xt0,$xt3,"0($inp)"); + + vx ($xt0,$xt0,$xa0); + vx ($xt1,$xt1,$xb0); + vx ($xt2,$xt2,$xc0); + vx ($xt3,$xt3,$xd0); + + vstm ($xt0,$xt3,"0($out)"); + + la ($inp,"0x40($inp)"); + la ($out,"0x40($out)"); +&{$z? \&aghi:\&ahi} ($len,-0x40); + #je (".Ldone_4x"); + + vaf ($xa0,$xa1,@K[0]); + vaf ($xb0,$xb1,@K[1]); + vaf ($xc0,$xc1,@K[2]); + vaf ($xd0,$xd1,@K[3]); + + vperm ($xa0,$xa0,$xa0,$beperm); + vperm ($xb0,$xb0,$xb0,$beperm); + vperm ($xc0,$xc0,$xc0,$beperm); + vperm ($xd0,$xd0,$xd0,$beperm); + +&{$z? \&clgfi:\&clfi} ($len,0x40); + jl (".Ltail_4x"); + + vlm ($xt0,$xt3,"0($inp)"); + + vx ($xt0,$xt0,$xa0); + vx ($xt1,$xt1,$xb0); + vx ($xt2,$xt2,$xc0); + vx ($xt3,$xt3,$xd0); + + vstm ($xt0,$xt3,"0($out)"); + + la ($inp,"0x40($inp)"); + la ($out,"0x40($out)"); +&{$z? \&aghi:\&ahi} ($len,-0x40); + je (".Ldone_4x"); + + vaf ($xa0,$xa2,@K[0]); + vaf ($xb0,$xb2,@K[1]); + vaf ($xc0,$xc2,@K[2]); + vaf ($xd0,$xd2,@K[3]); + + vperm ($xa0,$xa0,$xa0,$beperm); + vperm ($xb0,$xb0,$xb0,$beperm); + vperm ($xc0,$xc0,$xc0,$beperm); + vperm ($xd0,$xd0,$xd0,$beperm); + +&{$z? \&clgfi:\&clfi} ($len,0x40); + jl (".Ltail_4x"); + + vlm ($xt0,$xt3,"0($inp)"); + + vx ($xt0,$xt0,$xa0); + vx ($xt1,$xt1,$xb0); + vx ($xt2,$xt2,$xc0); + vx ($xt3,$xt3,$xd0); + + vstm ($xt0,$xt3,"0($out)"); + + la ($inp,"0x40($inp)"); + la ($out,"0x40($out)"); +&{$z? \&aghi:\&ahi} ($len,-0x40); + je (".Ldone_4x"); + + vaf ($xa0,$xa3,@K[0]); + vaf ($xb0,$xb3,@K[1]); + vaf ($xc0,$xc3,@K[2]); + vaf ($xd0,$xd3,@K[3]); + + vperm ($xa0,$xa0,$xa0,$beperm); + vperm ($xb0,$xb0,$xb0,$beperm); + vperm ($xc0,$xc0,$xc0,$beperm); + vperm ($xd0,$xd0,$xd0,$beperm); + +&{$z? \&clgfi:\&clfi} ($len,0x40); + jl (".Ltail_4x"); + + vlm ($xt0,$xt3,"0($inp)"); + + vx ($xt0,$xt0,$xa0); + vx ($xt1,$xt1,$xb0); + vx ($xt2,$xt2,$xc0); + vx ($xt3,$xt3,$xd0); + + vstm ($xt0,$xt3,"0($out)"); + + #la $inp,0x40($inp)); + #la $out,0x40($out)); + #lhi %r0,10); + #&{$z? \&aghi:\&ahi} $len,-0x40); + #jne .Loop_outer_4x); + +LABEL (".Ldone_4x"); +if (!$z) { + ld ("%f4","$FRAME+16*$SIZE_T+2*8($sp)"); + ld ("%f6","$FRAME+16*$SIZE_T+3*8($sp)"); +} else { + ld ("%f8","$stdframe+8*0($sp)"); + ld ("%f9","$stdframe+8*1($sp)"); + ld ("%f10","$stdframe+8*2($sp)"); + ld ("%f11","$stdframe+8*3($sp)"); + ld ("%f12","$stdframe+8*4($sp)"); + ld ("%f13","$stdframe+8*5($sp)"); + ld ("%f14","$stdframe+8*6($sp)"); + ld ("%f15","$stdframe+8*7($sp)"); +} +&{$z? \&lmg:\&lm} ("%r6","%r7","$FRAME+6*$SIZE_T($sp)"); + la ($sp,"$FRAME($sp)"); + br ("%r14"); + +ALIGN (16); +LABEL (".Ltail_4x"); +if (!$z) { + vlr ($xt0,$xb0); + ld ("%f4","$FRAME+16*$SIZE_T+2*8($sp)"); + ld ("%f6","$FRAME+16*$SIZE_T+3*8($sp)"); + + vst ($xa0,"$stdframe+0x00($sp)"); + vst ($xt0,"$stdframe+0x10($sp)"); + vst ($xc0,"$stdframe+0x20($sp)"); + vst ($xd0,"$stdframe+0x30($sp)"); +} else { + vlr ($xt0,$xc0); + ld ("%f8","$stdframe+8*0($sp)"); + ld ("%f9","$stdframe+8*1($sp)"); + ld ("%f10","$stdframe+8*2($sp)"); + ld ("%f11","$stdframe+8*3($sp)"); + vlr ($xt1,$xd0); + ld ("%f12","$stdframe+8*4($sp)"); + ld ("%f13","$stdframe+8*5($sp)"); + ld ("%f14","$stdframe+8*6($sp)"); + ld ("%f15","$stdframe+8*7($sp)"); + + vst ($xa0,"$stdframe+0x00($sp)"); + vst ($xb0,"$stdframe+0x10($sp)"); + vst ($xt0,"$stdframe+0x20($sp)"); + vst ($xt1,"$stdframe+0x30($sp)"); +} + lghi ("%r1",0); + +LABEL (".Loop_tail_4x"); + llgc ("%r5","0(%r1,$inp)"); + llgc ("%r6","$stdframe(%r1,$sp)"); + xr ("%r6","%r5"); + stc ("%r6","0(%r1,$out)"); + la ("%r1","1(%r1)"); + brct ($len,".Loop_tail_4x"); + +&{$z? \&lmg:\&lm} ("%r6","%r7","$FRAME+6*$SIZE_T($sp)"); + la ($sp,"$FRAME($sp)"); + br ("%r14"); +SIZE ("ChaCha20_ctr32_4x",".-ChaCha20_ctr32_4x"); +} + +######################################################################## +# 6x"horizontal" layout is optimal fit for the platform in its current +# shape, more specifically for given vector instructions' latency. Well, +# computational part of 8x"vertical" would be faster, but it consumes +# all registers and dealing with that will diminish the return... +# +{ +my ($a0,$b0,$c0,$d0, $a1,$b1,$c1,$d1, + $a2,$b2,$c2,$d2, $a3,$b3,$c3,$d3, + $a4,$b4,$c4,$d4, $a5,$b5,$c5,$d5)=map("%v$_",(0..23)); +my @K=map("%v$_",(27,24..26)); +my ($t0,$t1,$t2,$t3)=map("%v$_",27..30); +my $beperm="%v31"; +my $FRAME=$stdframe + 4*16; + +GLOBL ("ChaCha20_ctr32_vx"); +ALIGN (32); +LABEL ("ChaCha20_ctr32_vx"); +LABEL (".LChaCha20_ctr32_vx"); +&{$z? \&clgfi:\&clfi} ($len,256); + jle (".LChaCha20_ctr32_4x"); +&{$z? \&stmg:\&stm} ("%r6","%r7","6*$SIZE_T($sp)"); +if (!$z) { + std ("%f4","16*$SIZE_T+2*8($sp)"); + std ("%f6","16*$SIZE_T+3*8($sp)"); +} +&{$z? \&lghi:\&lhi} ("%r1",-$FRAME); + lgr ("%r0",$sp); + la ($sp,"0(%r1,$sp)"); +&{$z? \&stg:\&st} ("%r0","0($sp)"); # back-chain +if ($z) { + std ("%f8","$FRAME-8*8($sp)"); + std ("%f9","$FRAME-8*7($sp)"); + std ("%f10","$FRAME-8*6($sp)"); + std ("%f11","$FRAME-8*5($sp)"); + std ("%f12","$FRAME-8*4($sp)"); + std ("%f13","$FRAME-8*3($sp)"); + std ("%f14","$FRAME-8*2($sp)"); + std ("%f15","$FRAME-8*1($sp)"); +} + larl ("%r7",".Lsigma"); + lhi ("%r0",10); + + vlm (@K[1],@K[2],"0($key)"); # load key + vl (@K[3],"0($counter)"); # load counter + + vlm (@K[0],"$beperm","0(%r7)"); # load sigma, increments, ... + +LABEL (".Loop_outer_vx"); + vlr ($a0,@K[0]); + vlr ($b0,@K[1]); + vlr ($a1,@K[0]); + vlr ($b1,@K[1]); + vlr ($a2,@K[0]); + vlr ($b2,@K[1]); + vlr ($a3,@K[0]); + vlr ($b3,@K[1]); + vlr ($a4,@K[0]); + vlr ($b4,@K[1]); + vlr ($a5,@K[0]); + vlr ($b5,@K[1]); + + vlr ($d0,@K[3]); + vaf ($d1,@K[3],$t1); # K[3]+1 + vaf ($d2,@K[3],$t2); # K[3]+2 + vaf ($d3,@K[3],$t3); # K[3]+3 + vaf ($d4,$d2,$t2); # K[3]+4 + vaf ($d5,$d2,$t3); # K[3]+5 + + vlr ($c0,@K[2]); + vlr ($c1,@K[2]); + vlr ($c2,@K[2]); + vlr ($c3,@K[2]); + vlr ($c4,@K[2]); + vlr ($c5,@K[2]); + + vlr ($t1,$d1); + vlr ($t2,$d2); + vlr ($t3,$d3); + +ALIGN (4); +LABEL (".Loop_vx"); + + VX_ROUND($a0,$a1,$a2,$a3,$a4,$a5, + $b0,$b1,$b2,$b3,$b4,$b5, + $c0,$c1,$c2,$c3,$c4,$c5, + $d0,$d1,$d2,$d3,$d4,$d5, + 0); + + VX_ROUND($a0,$a1,$a2,$a3,$a4,$a5, + $b0,$b1,$b2,$b3,$b4,$b5, + $c0,$c1,$c2,$c3,$c4,$c5, + $d0,$d1,$d2,$d3,$d4,$d5, + 1); + + brct ("%r0",".Loop_vx"); + + vaf ($a0,$a0,@K[0]); + vaf ($b0,$b0,@K[1]); + vaf ($c0,$c0,@K[2]); + vaf ($d0,$d0,@K[3]); + vaf ($a1,$a1,@K[0]); + vaf ($d1,$d1,$t1); # +K[3]+1 + + vperm ($a0,$a0,$a0,$beperm); + vperm ($b0,$b0,$b0,$beperm); + vperm ($c0,$c0,$c0,$beperm); + vperm ($d0,$d0,$d0,$beperm); + +&{$z? \&clgfi:\&clfi} ($len,0x40); + jl (".Ltail_vx"); + + vaf ($d2,$d2,$t2); # +K[3]+2 + vaf ($d3,$d3,$t3); # +K[3]+3 + vlm ($t0,$t3,"0($inp)"); + + vx ($a0,$a0,$t0); + vx ($b0,$b0,$t1); + vx ($c0,$c0,$t2); + vx ($d0,$d0,$t3); + + vlm (@K[0],$t3,"0(%r7)"); # re-load sigma and increments + + vstm ($a0,$d0,"0($out)"); + + la ($inp,"0x40($inp)"); + la ($out,"0x40($out)"); +&{$z? \&aghi:\&ahi} ($len,-0x40); + je (".Ldone_vx"); + + vaf ($b1,$b1,@K[1]); + vaf ($c1,$c1,@K[2]); + + vperm ($a0,$a1,$a1,$beperm); + vperm ($b0,$b1,$b1,$beperm); + vperm ($c0,$c1,$c1,$beperm); + vperm ($d0,$d1,$d1,$beperm); + +&{$z? \&clgfi:\&clfi} ($len,0x40); + jl (".Ltail_vx"); + + vlm ($a1,$d1,"0($inp)"); + + vx ($a0,$a0,$a1); + vx ($b0,$b0,$b1); + vx ($c0,$c0,$c1); + vx ($d0,$d0,$d1); + + vstm ($a0,$d0,"0($out)"); + + la ($inp,"0x40($inp)"); + la ($out,"0x40($out)"); +&{$z? \&aghi:\&ahi} ($len,-0x40); + je (".Ldone_vx"); + + vaf ($a2,$a2,@K[0]); + vaf ($b2,$b2,@K[1]); + vaf ($c2,$c2,@K[2]); + + vperm ($a0,$a2,$a2,$beperm); + vperm ($b0,$b2,$b2,$beperm); + vperm ($c0,$c2,$c2,$beperm); + vperm ($d0,$d2,$d2,$beperm); + +&{$z? \&clgfi:\&clfi} ($len,0x40); + jl (".Ltail_vx"); + + vlm ($a1,$d1,"0($inp)"); + + vx ($a0,$a0,$a1); + vx ($b0,$b0,$b1); + vx ($c0,$c0,$c1); + vx ($d0,$d0,$d1); + + vstm ($a0,$d0,"0($out)"); + + la ($inp,"0x40($inp)"); + la ($out,"0x40($out)"); +&{$z? \&aghi:\&ahi} ($len,-0x40); + je (".Ldone_vx"); + + vaf ($a3,$a3,@K[0]); + vaf ($b3,$b3,@K[1]); + vaf ($c3,$c3,@K[2]); + vaf ($d2,@K[3],$t3); # K[3]+3 + + vperm ($a0,$a3,$a3,$beperm); + vperm ($b0,$b3,$b3,$beperm); + vperm ($c0,$c3,$c3,$beperm); + vperm ($d0,$d3,$d3,$beperm); + +&{$z? \&clgfi:\&clfi} ($len,0x40); + jl (".Ltail_vx"); + + vaf ($d3,$d2,$t1); # K[3]+4 + vlm ($a1,$d1,"0($inp)"); + + vx ($a0,$a0,$a1); + vx ($b0,$b0,$b1); + vx ($c0,$c0,$c1); + vx ($d0,$d0,$d1); + + vstm ($a0,$d0,"0($out)"); + + la ($inp,"0x40($inp)"); + la ($out,"0x40($out)"); +&{$z? \&aghi:\&ahi} ($len,-0x40); + je (".Ldone_vx"); + + vaf ($a4,$a4,@K[0]); + vaf ($b4,$b4,@K[1]); + vaf ($c4,$c4,@K[2]); + vaf ($d4,$d4,$d3); # +K[3]+4 + vaf ($d3,$d3,$t1); # K[3]+5 + vaf (@K[3],$d2,$t3); # K[3]+=6 + + vperm ($a0,$a4,$a4,$beperm); + vperm ($b0,$b4,$b4,$beperm); + vperm ($c0,$c4,$c4,$beperm); + vperm ($d0,$d4,$d4,$beperm); + +&{$z? \&clgfi:\&clfi} ($len,0x40); + jl (".Ltail_vx"); + + vlm ($a1,$d1,"0($inp)"); + + vx ($a0,$a0,$a1); + vx ($b0,$b0,$b1); + vx ($c0,$c0,$c1); + vx ($d0,$d0,$d1); + + vstm ($a0,$d0,"0($out)"); + + la ($inp,"0x40($inp)"); + la ($out,"0x40($out)"); +&{$z? \&aghi:\&ahi} ($len,-0x40); + je (".Ldone_vx"); + + vaf ($a5,$a5,@K[0]); + vaf ($b5,$b5,@K[1]); + vaf ($c5,$c5,@K[2]); + vaf ($d5,$d5,$d3); # +K[3]+5 + + vperm ($a0,$a5,$a5,$beperm); + vperm ($b0,$b5,$b5,$beperm); + vperm ($c0,$c5,$c5,$beperm); + vperm ($d0,$d5,$d5,$beperm); + +&{$z? \&clgfi:\&clfi} ($len,0x40); + jl (".Ltail_vx"); + + vlm ($a1,$d1,"0($inp)"); + + vx ($a0,$a0,$a1); + vx ($b0,$b0,$b1); + vx ($c0,$c0,$c1); + vx ($d0,$d0,$d1); + + vstm ($a0,$d0,"0($out)"); + + la ($inp,"0x40($inp)"); + la ($out,"0x40($out)"); + lhi ("%r0",10); +&{$z? \&aghi:\&ahi} ($len,-0x40); + jne (".Loop_outer_vx"); + +LABEL (".Ldone_vx"); +if (!$z) { + ld ("%f4","$FRAME+16*$SIZE_T+2*8($sp)"); + ld ("%f6","$FRAME+16*$SIZE_T+3*8($sp)"); +} else { + ld ("%f8","$FRAME-8*8($sp)"); + ld ("%f9","$FRAME-8*7($sp)"); + ld ("%f10","$FRAME-8*6($sp)"); + ld ("%f11","$FRAME-8*5($sp)"); + ld ("%f12","$FRAME-8*4($sp)"); + ld ("%f13","$FRAME-8*3($sp)"); + ld ("%f14","$FRAME-8*2($sp)"); + ld ("%f15","$FRAME-8*1($sp)"); +} +&{$z? \&lmg:\&lm} ("%r6","%r7","$FRAME+6*$SIZE_T($sp)"); + la ($sp,"$FRAME($sp)"); + br ("%r14"); + +ALIGN (16); +LABEL (".Ltail_vx"); +if (!$z) { + ld ("%f4","$FRAME+16*$SIZE_T+2*8($sp)"); + ld ("%f6","$FRAME+16*$SIZE_T+3*8($sp)"); +} else { + ld ("%f8","$FRAME-8*8($sp)"); + ld ("%f9","$FRAME-8*7($sp)"); + ld ("%f10","$FRAME-8*6($sp)"); + ld ("%f11","$FRAME-8*5($sp)"); + ld ("%f12","$FRAME-8*4($sp)"); + ld ("%f13","$FRAME-8*3($sp)"); + ld ("%f14","$FRAME-8*2($sp)"); + ld ("%f15","$FRAME-8*1($sp)"); +} + vstm ($a0,$d0,"$stdframe($sp)"); + lghi ("%r1",0); + +LABEL (".Loop_tail_vx"); + llgc ("%r5","0(%r1,$inp)"); + llgc ("%r6","$stdframe(%r1,$sp)"); + xr ("%r6","%r5"); + stc ("%r6","0(%r1,$out)"); + la ("%r1","1(%r1)"); + brct ($len,".Loop_tail_vx"); + +&{$z? \&lmg:\&lm} ("%r6","%r7","$FRAME+6*$SIZE_T($sp)"); + la ($sp,"$FRAME($sp)"); + br ("%r14"); +SIZE ("ChaCha20_ctr32_vx",".-ChaCha20_ctr32_vx"); +} +################ + +ALIGN (32); +LABEL (".Lsigma"); +LONG (0x61707865,0x3320646e,0x79622d32,0x6b206574); # endian-neutral sigma +LONG (1,0,0,0); +LONG (2,0,0,0); +LONG (3,0,0,0); +LONG (0x03020100,0x07060504,0x0b0a0908,0x0f0e0d0c); # byte swap + +LONG (0,1,2,3); +LONG (0x61707865,0x61707865,0x61707865,0x61707865); # smashed sigma +LONG (0x3320646e,0x3320646e,0x3320646e,0x3320646e); +LONG (0x79622d32,0x79622d32,0x79622d32,0x79622d32); +LONG (0x6b206574,0x6b206574,0x6b206574,0x6b206574); + +ASCIZ ("\"ChaCha20 for s390x, CRYPTOGAMS by \""); +ALIGN (4); + +PERLASM_END(); diff --git a/crypto/openssl/crypto/chacha/asm/chacha-x86.pl b/crypto/openssl/crypto/chacha/asm/chacha-x86.pl index 492fda5f114c..d0e83d88cec3 100755 --- a/crypto/openssl/crypto/chacha/asm/chacha-x86.pl +++ b/crypto/openssl/crypto/chacha/asm/chacha-x86.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -40,8 +40,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/chacha/asm/chacha-x86_64.pl b/crypto/openssl/crypto/chacha/asm/chacha-x86_64.pl index c0e5d863dcb2..cdb900c037fd 100755 --- a/crypto/openssl/crypto/chacha/asm/chacha-x86_64.pl +++ b/crypto/openssl/crypto/chacha/asm/chacha-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -58,9 +58,10 @@ # (vi) even though Skylake-X can execute AVX512F code and deliver 0.57 # cpb in single thread, the corresponding capability is suppressed; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -89,7 +90,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0 $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; # input parameter block diff --git a/crypto/openssl/crypto/chacha/build.info b/crypto/openssl/crypto/chacha/build.info index e75ca72b67d4..e7159dc066dc 100644 --- a/crypto/openssl/crypto/chacha/build.info +++ b/crypto/openssl/crypto/chacha/build.info @@ -1,20 +1,40 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]={- $target{chacha_asm_src} -} -GENERATE[chacha-x86.s]=asm/chacha-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -GENERATE[chacha-x86_64.s]=asm/chacha-x86_64.pl $(PERLASM_SCHEME) -GENERATE[chacha-ppc.s]=asm/chacha-ppc.pl $(PERLASM_SCHEME) -GENERATE[chacha-armv4.S]=asm/chacha-armv4.pl $(PERLASM_SCHEME) +$CHACHAASM=chacha_enc.c +IF[{- !$disabled{asm} -}] + $CHACHAASM_x86=chacha-x86.S + $CHACHAASM_x86_64=chacha-x86_64.s + + $CHACHAASM_ia64=chacha-ia64.s + + $CHACHAASM_s390x=chacha-s390x.S + + $CHACHAASM_armv4=chacha-armv4.S + $CHACHAASM_aarch64=chacha-armv8.S + + $CHACHAASM_ppc32=chacha_ppc.c chacha-ppc.s + $CHACHAASM_ppc64=$CHACHAASM_ppc32 + + $CHACHAASM_c64xplus=chacha-c64xplus.s + + # Now that we have defined all the arch specific variables, use the + # appropriate one + IF[$CHACHAASM_{- $target{asm_arch} -}] + $CHACHAASM=$CHACHAASM_{- $target{asm_arch} -} + ENDIF +ENDIF + +SOURCE[../../libcrypto]=$CHACHAASM + +GENERATE[chacha-x86.S]=asm/chacha-x86.pl +GENERATE[chacha-x86_64.s]=asm/chacha-x86_64.pl +GENERATE[chacha-ppc.s]=asm/chacha-ppc.pl +GENERATE[chacha-armv4.S]=asm/chacha-armv4.pl INCLUDE[chacha-armv4.o]=.. -GENERATE[chacha-armv8.S]=asm/chacha-armv8.pl $(PERLASM_SCHEME) +GENERATE[chacha-armv8.S]=asm/chacha-armv8.pl INCLUDE[chacha-armv8.o]=.. -GENERATE[chacha-s390x.S]=asm/chacha-s390x.pl $(PERLASM_SCHEME) INCLUDE[chacha-s390x.o]=.. - -BEGINRAW[Makefile(unix)] -##### CHACHA assembler implementations - -{- $builddir -}/chacha-%.S: {- $sourcedir -}/asm/chacha-%.pl - CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ -ENDRAW[Makefile(unix)] +GENERATE[chacha-c64xplus.S]=asm/chacha-c64xplus.pl +GENERATE[chacha-s390x.S]=asm/chacha-s390x.pl +GENERATE[chacha-ia64.S]=asm/chacha-ia64.pl +GENERATE[chacha-ia64.s]=chacha-ia64.S diff --git a/crypto/openssl/crypto/chacha/chacha-armv8.S b/crypto/openssl/crypto/chacha/chacha-armv8.S new file mode 100644 index 000000000000..66eb96ec57bb --- /dev/null +++ b/crypto/openssl/crypto/chacha/chacha-armv8.S @@ -0,0 +1,2034 @@ +#ifndef __KERNEL__ +# include "arm_arch.h" + +.hidden OPENSSL_armcap_P +#endif + +.text + +.align 5 +.Lsigma: +.quad 0x3320646e61707865,0x6b20657479622d32 // endian-neutral +.Lone: +.long 1,2,3,4 +.Lrot24: +.long 0x02010003,0x06050407,0x0a09080b,0x0e0d0c0f +.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,64,100,111,116,45,97,115,109,0 +.align 2 + +.globl ChaCha20_ctr32 +.type ChaCha20_ctr32,%function +.align 5 +ChaCha20_ctr32: + cbz x2,.Labort + cmp x2,#192 + b.lo .Lshort + +#ifndef __KERNEL__ + adrp x17,OPENSSL_armcap_P + ldr w17,[x17,#:lo12:OPENSSL_armcap_P] + tst w17,#ARMV7_NEON + b.ne .LChaCha20_neon +#endif + +.Lshort: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + + adr x5,.Lsigma + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#64 + + ldp x22,x23,[x5] // load sigma + ldp x24,x25,[x3] // load key + ldp x26,x27,[x3,#16] + ldp x28,x30,[x4] // load counter +#ifdef __AARCH64EB__ + ror x24,x24,#32 + ror x25,x25,#32 + ror x26,x26,#32 + ror x27,x27,#32 + ror x28,x28,#32 + ror x30,x30,#32 +#endif + +.Loop_outer: + mov w5,w22 // unpack key block + lsr x6,x22,#32 + mov w7,w23 + lsr x8,x23,#32 + mov w9,w24 + lsr x10,x24,#32 + mov w11,w25 + lsr x12,x25,#32 + mov w13,w26 + lsr x14,x26,#32 + mov w15,w27 + lsr x16,x27,#32 + mov w17,w28 + lsr x19,x28,#32 + mov w20,w30 + lsr x21,x30,#32 + + mov x4,#10 + subs x2,x2,#64 +.Loop: + sub x4,x4,#1 + add w5,w5,w9 + add w6,w6,w10 + add w7,w7,w11 + add w8,w8,w12 + eor w17,w17,w5 + eor w19,w19,w6 + eor w20,w20,w7 + eor w21,w21,w8 + ror w17,w17,#16 + ror w19,w19,#16 + ror w20,w20,#16 + ror w21,w21,#16 + add w13,w13,w17 + add w14,w14,w19 + add w15,w15,w20 + add w16,w16,w21 + eor w9,w9,w13 + eor w10,w10,w14 + eor w11,w11,w15 + eor w12,w12,w16 + ror w9,w9,#20 + ror w10,w10,#20 + ror w11,w11,#20 + ror w12,w12,#20 + add w5,w5,w9 + add w6,w6,w10 + add w7,w7,w11 + add w8,w8,w12 + eor w17,w17,w5 + eor w19,w19,w6 + eor w20,w20,w7 + eor w21,w21,w8 + ror w17,w17,#24 + ror w19,w19,#24 + ror w20,w20,#24 + ror w21,w21,#24 + add w13,w13,w17 + add w14,w14,w19 + add w15,w15,w20 + add w16,w16,w21 + eor w9,w9,w13 + eor w10,w10,w14 + eor w11,w11,w15 + eor w12,w12,w16 + ror w9,w9,#25 + ror w10,w10,#25 + ror w11,w11,#25 + ror w12,w12,#25 + add w5,w5,w10 + add w6,w6,w11 + add w7,w7,w12 + add w8,w8,w9 + eor w21,w21,w5 + eor w17,w17,w6 + eor w19,w19,w7 + eor w20,w20,w8 + ror w21,w21,#16 + ror w17,w17,#16 + ror w19,w19,#16 + ror w20,w20,#16 + add w15,w15,w21 + add w16,w16,w17 + add w13,w13,w19 + add w14,w14,w20 + eor w10,w10,w15 + eor w11,w11,w16 + eor w12,w12,w13 + eor w9,w9,w14 + ror w10,w10,#20 + ror w11,w11,#20 + ror w12,w12,#20 + ror w9,w9,#20 + add w5,w5,w10 + add w6,w6,w11 + add w7,w7,w12 + add w8,w8,w9 + eor w21,w21,w5 + eor w17,w17,w6 + eor w19,w19,w7 + eor w20,w20,w8 + ror w21,w21,#24 + ror w17,w17,#24 + ror w19,w19,#24 + ror w20,w20,#24 + add w15,w15,w21 + add w16,w16,w17 + add w13,w13,w19 + add w14,w14,w20 + eor w10,w10,w15 + eor w11,w11,w16 + eor w12,w12,w13 + eor w9,w9,w14 + ror w10,w10,#25 + ror w11,w11,#25 + ror w12,w12,#25 + ror w9,w9,#25 + cbnz x4,.Loop + + add w5,w5,w22 // accumulate key block + add x6,x6,x22,lsr#32 + add w7,w7,w23 + add x8,x8,x23,lsr#32 + add w9,w9,w24 + add x10,x10,x24,lsr#32 + add w11,w11,w25 + add x12,x12,x25,lsr#32 + add w13,w13,w26 + add x14,x14,x26,lsr#32 + add w15,w15,w27 + add x16,x16,x27,lsr#32 + add w17,w17,w28 + add x19,x19,x28,lsr#32 + add w20,w20,w30 + add x21,x21,x30,lsr#32 + + b.lo .Ltail + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor x15,x15,x16 + eor x17,x17,x19 + eor x20,x20,x21 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#1 // increment counter + stp x9,x11,[x0,#16] + stp x13,x15,[x0,#32] + stp x17,x20,[x0,#48] + add x0,x0,#64 + + b.hi .Loop_outer + + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 +.inst 0xd50323bf // autiasp +.Labort: + ret + +.align 4 +.Ltail: + add x2,x2,#64 +.Less_than_64: + sub x0,x0,#1 + add x1,x1,x2 + add x0,x0,x2 + add x4,sp,x2 + neg x2,x2 + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + stp x5,x7,[sp,#0] + stp x9,x11,[sp,#16] + stp x13,x15,[sp,#32] + stp x17,x20,[sp,#48] + +.Loop_tail: + ldrb w10,[x1,x2] + ldrb w11,[x4,x2] + add x2,x2,#1 + eor w10,w10,w11 + strb w10,[x0,x2] + cbnz x2,.Loop_tail + + stp xzr,xzr,[sp,#0] + stp xzr,xzr,[sp,#16] + stp xzr,xzr,[sp,#32] + stp xzr,xzr,[sp,#48] + + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 +.inst 0xd50323bf // autiasp + ret +.size ChaCha20_ctr32,.-ChaCha20_ctr32 + +#ifdef __KERNEL__ +.globl ChaCha20_neon +#endif +.type ChaCha20_neon,%function +.align 5 +ChaCha20_neon: +.LChaCha20_neon: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + + adr x5,.Lsigma + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + cmp x2,#512 + b.hs .L512_or_more_neon + + sub sp,sp,#64 + + ldp x22,x23,[x5] // load sigma + ld1 {v0.4s},[x5],#16 + ldp x24,x25,[x3] // load key + ldp x26,x27,[x3,#16] + ld1 {v1.4s,v2.4s},[x3] + ldp x28,x30,[x4] // load counter + ld1 {v3.4s},[x4] + stp d8,d9,[sp] // meet ABI requirements + ld1 {v8.4s,v9.4s},[x5] +#ifdef __AARCH64EB__ + rev64 v0.4s,v0.4s + ror x24,x24,#32 + ror x25,x25,#32 + ror x26,x26,#32 + ror x27,x27,#32 + ror x28,x28,#32 + ror x30,x30,#32 +#endif + +.Loop_outer_neon: + dup v16.4s,v0.s[0] // unpack key block + mov w5,w22 + dup v20.4s,v0.s[1] + lsr x6,x22,#32 + dup v24.4s,v0.s[2] + mov w7,w23 + dup v28.4s,v0.s[3] + lsr x8,x23,#32 + dup v17.4s,v1.s[0] + mov w9,w24 + dup v21.4s,v1.s[1] + lsr x10,x24,#32 + dup v25.4s,v1.s[2] + mov w11,w25 + dup v29.4s,v1.s[3] + lsr x12,x25,#32 + dup v19.4s,v3.s[0] + mov w13,w26 + dup v23.4s,v3.s[1] + lsr x14,x26,#32 + dup v27.4s,v3.s[2] + mov w15,w27 + dup v31.4s,v3.s[3] + lsr x16,x27,#32 + add v19.4s,v19.4s,v8.4s + mov w17,w28 + dup v18.4s,v2.s[0] + lsr x19,x28,#32 + dup v22.4s,v2.s[1] + mov w20,w30 + dup v26.4s,v2.s[2] + lsr x21,x30,#32 + dup v30.4s,v2.s[3] + + mov x4,#10 + subs x2,x2,#320 +.Loop_neon: + sub x4,x4,#1 + add v16.4s,v16.4s,v17.4s + add w5,w5,w9 + add v20.4s,v20.4s,v21.4s + add w6,w6,w10 + add v24.4s,v24.4s,v25.4s + add w7,w7,w11 + add v28.4s,v28.4s,v29.4s + add w8,w8,w12 + eor v19.16b,v19.16b,v16.16b + eor w17,w17,w5 + eor v23.16b,v23.16b,v20.16b + eor w19,w19,w6 + eor v27.16b,v27.16b,v24.16b + eor w20,w20,w7 + eor v31.16b,v31.16b,v28.16b + eor w21,w21,w8 + rev32 v19.8h,v19.8h + ror w17,w17,#16 + rev32 v23.8h,v23.8h + ror w19,w19,#16 + rev32 v27.8h,v27.8h + ror w20,w20,#16 + rev32 v31.8h,v31.8h + ror w21,w21,#16 + add v18.4s,v18.4s,v19.4s + add w13,w13,w17 + add v22.4s,v22.4s,v23.4s + add w14,w14,w19 + add v26.4s,v26.4s,v27.4s + add w15,w15,w20 + add v30.4s,v30.4s,v31.4s + add w16,w16,w21 + eor v4.16b,v17.16b,v18.16b + eor w9,w9,w13 + eor v5.16b,v21.16b,v22.16b + eor w10,w10,w14 + eor v6.16b,v25.16b,v26.16b + eor w11,w11,w15 + eor v7.16b,v29.16b,v30.16b + eor w12,w12,w16 + ushr v17.4s,v4.4s,#20 + ror w9,w9,#20 + ushr v21.4s,v5.4s,#20 + ror w10,w10,#20 + ushr v25.4s,v6.4s,#20 + ror w11,w11,#20 + ushr v29.4s,v7.4s,#20 + ror w12,w12,#20 + sli v17.4s,v4.4s,#12 + add w5,w5,w9 + sli v21.4s,v5.4s,#12 + add w6,w6,w10 + sli v25.4s,v6.4s,#12 + add w7,w7,w11 + sli v29.4s,v7.4s,#12 + add w8,w8,w12 + add v16.4s,v16.4s,v17.4s + eor w17,w17,w5 + add v20.4s,v20.4s,v21.4s + eor w19,w19,w6 + add v24.4s,v24.4s,v25.4s + eor w20,w20,w7 + add v28.4s,v28.4s,v29.4s + eor w21,w21,w8 + eor v4.16b,v19.16b,v16.16b + ror w17,w17,#24 + eor v5.16b,v23.16b,v20.16b + ror w19,w19,#24 + eor v6.16b,v27.16b,v24.16b + ror w20,w20,#24 + eor v7.16b,v31.16b,v28.16b + ror w21,w21,#24 + tbl v19.16b,{v4.16b},v9.16b + add w13,w13,w17 + tbl v23.16b,{v5.16b},v9.16b + add w14,w14,w19 + tbl v27.16b,{v6.16b},v9.16b + add w15,w15,w20 + tbl v31.16b,{v7.16b},v9.16b + add w16,w16,w21 + add v18.4s,v18.4s,v19.4s + eor w9,w9,w13 + add v22.4s,v22.4s,v23.4s + eor w10,w10,w14 + add v26.4s,v26.4s,v27.4s + eor w11,w11,w15 + add v30.4s,v30.4s,v31.4s + eor w12,w12,w16 + eor v4.16b,v17.16b,v18.16b + ror w9,w9,#25 + eor v5.16b,v21.16b,v22.16b + ror w10,w10,#25 + eor v6.16b,v25.16b,v26.16b + ror w11,w11,#25 + eor v7.16b,v29.16b,v30.16b + ror w12,w12,#25 + ushr v17.4s,v4.4s,#25 + ushr v21.4s,v5.4s,#25 + ushr v25.4s,v6.4s,#25 + ushr v29.4s,v7.4s,#25 + sli v17.4s,v4.4s,#7 + sli v21.4s,v5.4s,#7 + sli v25.4s,v6.4s,#7 + sli v29.4s,v7.4s,#7 + add v16.4s,v16.4s,v21.4s + add w5,w5,w10 + add v20.4s,v20.4s,v25.4s + add w6,w6,w11 + add v24.4s,v24.4s,v29.4s + add w7,w7,w12 + add v28.4s,v28.4s,v17.4s + add w8,w8,w9 + eor v31.16b,v31.16b,v16.16b + eor w21,w21,w5 + eor v19.16b,v19.16b,v20.16b + eor w17,w17,w6 + eor v23.16b,v23.16b,v24.16b + eor w19,w19,w7 + eor v27.16b,v27.16b,v28.16b + eor w20,w20,w8 + rev32 v31.8h,v31.8h + ror w21,w21,#16 + rev32 v19.8h,v19.8h + ror w17,w17,#16 + rev32 v23.8h,v23.8h + ror w19,w19,#16 + rev32 v27.8h,v27.8h + ror w20,w20,#16 + add v26.4s,v26.4s,v31.4s + add w15,w15,w21 + add v30.4s,v30.4s,v19.4s + add w16,w16,w17 + add v18.4s,v18.4s,v23.4s + add w13,w13,w19 + add v22.4s,v22.4s,v27.4s + add w14,w14,w20 + eor v4.16b,v21.16b,v26.16b + eor w10,w10,w15 + eor v5.16b,v25.16b,v30.16b + eor w11,w11,w16 + eor v6.16b,v29.16b,v18.16b + eor w12,w12,w13 + eor v7.16b,v17.16b,v22.16b + eor w9,w9,w14 + ushr v21.4s,v4.4s,#20 + ror w10,w10,#20 + ushr v25.4s,v5.4s,#20 + ror w11,w11,#20 + ushr v29.4s,v6.4s,#20 + ror w12,w12,#20 + ushr v17.4s,v7.4s,#20 + ror w9,w9,#20 + sli v21.4s,v4.4s,#12 + add w5,w5,w10 + sli v25.4s,v5.4s,#12 + add w6,w6,w11 + sli v29.4s,v6.4s,#12 + add w7,w7,w12 + sli v17.4s,v7.4s,#12 + add w8,w8,w9 + add v16.4s,v16.4s,v21.4s + eor w21,w21,w5 + add v20.4s,v20.4s,v25.4s + eor w17,w17,w6 + add v24.4s,v24.4s,v29.4s + eor w19,w19,w7 + add v28.4s,v28.4s,v17.4s + eor w20,w20,w8 + eor v4.16b,v31.16b,v16.16b + ror w21,w21,#24 + eor v5.16b,v19.16b,v20.16b + ror w17,w17,#24 + eor v6.16b,v23.16b,v24.16b + ror w19,w19,#24 + eor v7.16b,v27.16b,v28.16b + ror w20,w20,#24 + tbl v31.16b,{v4.16b},v9.16b + add w15,w15,w21 + tbl v19.16b,{v5.16b},v9.16b + add w16,w16,w17 + tbl v23.16b,{v6.16b},v9.16b + add w13,w13,w19 + tbl v27.16b,{v7.16b},v9.16b + add w14,w14,w20 + add v26.4s,v26.4s,v31.4s + eor w10,w10,w15 + add v30.4s,v30.4s,v19.4s + eor w11,w11,w16 + add v18.4s,v18.4s,v23.4s + eor w12,w12,w13 + add v22.4s,v22.4s,v27.4s + eor w9,w9,w14 + eor v4.16b,v21.16b,v26.16b + ror w10,w10,#25 + eor v5.16b,v25.16b,v30.16b + ror w11,w11,#25 + eor v6.16b,v29.16b,v18.16b + ror w12,w12,#25 + eor v7.16b,v17.16b,v22.16b + ror w9,w9,#25 + ushr v21.4s,v4.4s,#25 + ushr v25.4s,v5.4s,#25 + ushr v29.4s,v6.4s,#25 + ushr v17.4s,v7.4s,#25 + sli v21.4s,v4.4s,#7 + sli v25.4s,v5.4s,#7 + sli v29.4s,v6.4s,#7 + sli v17.4s,v7.4s,#7 + cbnz x4,.Loop_neon + + add v19.4s,v19.4s,v8.4s + + zip1 v4.4s,v16.4s,v20.4s // transpose data + zip1 v5.4s,v24.4s,v28.4s + zip2 v6.4s,v16.4s,v20.4s + zip2 v7.4s,v24.4s,v28.4s + zip1 v16.2d,v4.2d,v5.2d + zip2 v20.2d,v4.2d,v5.2d + zip1 v24.2d,v6.2d,v7.2d + zip2 v28.2d,v6.2d,v7.2d + + zip1 v4.4s,v17.4s,v21.4s + zip1 v5.4s,v25.4s,v29.4s + zip2 v6.4s,v17.4s,v21.4s + zip2 v7.4s,v25.4s,v29.4s + zip1 v17.2d,v4.2d,v5.2d + zip2 v21.2d,v4.2d,v5.2d + zip1 v25.2d,v6.2d,v7.2d + zip2 v29.2d,v6.2d,v7.2d + + zip1 v4.4s,v18.4s,v22.4s + add w5,w5,w22 // accumulate key block + zip1 v5.4s,v26.4s,v30.4s + add x6,x6,x22,lsr#32 + zip2 v6.4s,v18.4s,v22.4s + add w7,w7,w23 + zip2 v7.4s,v26.4s,v30.4s + add x8,x8,x23,lsr#32 + zip1 v18.2d,v4.2d,v5.2d + add w9,w9,w24 + zip2 v22.2d,v4.2d,v5.2d + add x10,x10,x24,lsr#32 + zip1 v26.2d,v6.2d,v7.2d + add w11,w11,w25 + zip2 v30.2d,v6.2d,v7.2d + add x12,x12,x25,lsr#32 + + zip1 v4.4s,v19.4s,v23.4s + add w13,w13,w26 + zip1 v5.4s,v27.4s,v31.4s + add x14,x14,x26,lsr#32 + zip2 v6.4s,v19.4s,v23.4s + add w15,w15,w27 + zip2 v7.4s,v27.4s,v31.4s + add x16,x16,x27,lsr#32 + zip1 v19.2d,v4.2d,v5.2d + add w17,w17,w28 + zip2 v23.2d,v4.2d,v5.2d + add x19,x19,x28,lsr#32 + zip1 v27.2d,v6.2d,v7.2d + add w20,w20,w30 + zip2 v31.2d,v6.2d,v7.2d + add x21,x21,x30,lsr#32 + + b.lo .Ltail_neon + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add v16.4s,v16.4s,v0.4s // accumulate key block + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add v17.4s,v17.4s,v1.4s + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add v18.4s,v18.4s,v2.4s + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add v19.4s,v19.4s,v3.4s + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + eor x5,x5,x6 + add v20.4s,v20.4s,v0.4s + eor x7,x7,x8 + add v21.4s,v21.4s,v1.4s + eor x9,x9,x10 + add v22.4s,v22.4s,v2.4s + eor x11,x11,x12 + add v23.4s,v23.4s,v3.4s + eor x13,x13,x14 + eor v16.16b,v16.16b,v4.16b + movi v4.4s,#5 + eor x15,x15,x16 + eor v17.16b,v17.16b,v5.16b + eor x17,x17,x19 + eor v18.16b,v18.16b,v6.16b + eor x20,x20,x21 + eor v19.16b,v19.16b,v7.16b + add v8.4s,v8.4s,v4.4s // += 5 + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#5 // increment counter + stp x9,x11,[x0,#16] + stp x13,x15,[x0,#32] + stp x17,x20,[x0,#48] + add x0,x0,#64 + + st1 {v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64 + add v24.4s,v24.4s,v0.4s + add v25.4s,v25.4s,v1.4s + add v26.4s,v26.4s,v2.4s + add v27.4s,v27.4s,v3.4s + ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x1],#64 + + eor v20.16b,v20.16b,v4.16b + eor v21.16b,v21.16b,v5.16b + eor v22.16b,v22.16b,v6.16b + eor v23.16b,v23.16b,v7.16b + st1 {v20.16b,v21.16b,v22.16b,v23.16b},[x0],#64 + add v28.4s,v28.4s,v0.4s + add v29.4s,v29.4s,v1.4s + add v30.4s,v30.4s,v2.4s + add v31.4s,v31.4s,v3.4s + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + + eor v24.16b,v24.16b,v16.16b + eor v25.16b,v25.16b,v17.16b + eor v26.16b,v26.16b,v18.16b + eor v27.16b,v27.16b,v19.16b + st1 {v24.16b,v25.16b,v26.16b,v27.16b},[x0],#64 + + eor v28.16b,v28.16b,v20.16b + eor v29.16b,v29.16b,v21.16b + eor v30.16b,v30.16b,v22.16b + eor v31.16b,v31.16b,v23.16b + st1 {v28.16b,v29.16b,v30.16b,v31.16b},[x0],#64 + + b.hi .Loop_outer_neon + + ldp d8,d9,[sp] // meet ABI requirements + + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 +.inst 0xd50323bf // autiasp + ret + +.align 4 +.Ltail_neon: + add x2,x2,#320 + ldp d8,d9,[sp] // meet ABI requirements + cmp x2,#64 + b.lo .Less_than_64 + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor x15,x15,x16 + eor x17,x17,x19 + eor x20,x20,x21 + + stp x5,x7,[x0,#0] // store output + add v16.4s,v16.4s,v0.4s // accumulate key block + stp x9,x11,[x0,#16] + add v17.4s,v17.4s,v1.4s + stp x13,x15,[x0,#32] + add v18.4s,v18.4s,v2.4s + stp x17,x20,[x0,#48] + add v19.4s,v19.4s,v3.4s + add x0,x0,#64 + b.eq .Ldone_neon + sub x2,x2,#64 + cmp x2,#64 + b.lo .Last_neon + + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + eor v16.16b,v16.16b,v4.16b + eor v17.16b,v17.16b,v5.16b + eor v18.16b,v18.16b,v6.16b + eor v19.16b,v19.16b,v7.16b + st1 {v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64 + b.eq .Ldone_neon + + add v16.4s,v20.4s,v0.4s + add v17.4s,v21.4s,v1.4s + sub x2,x2,#64 + add v18.4s,v22.4s,v2.4s + cmp x2,#64 + add v19.4s,v23.4s,v3.4s + b.lo .Last_neon + + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + eor v20.16b,v16.16b,v4.16b + eor v21.16b,v17.16b,v5.16b + eor v22.16b,v18.16b,v6.16b + eor v23.16b,v19.16b,v7.16b + st1 {v20.16b,v21.16b,v22.16b,v23.16b},[x0],#64 + b.eq .Ldone_neon + + add v16.4s,v24.4s,v0.4s + add v17.4s,v25.4s,v1.4s + sub x2,x2,#64 + add v18.4s,v26.4s,v2.4s + cmp x2,#64 + add v19.4s,v27.4s,v3.4s + b.lo .Last_neon + + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + eor v24.16b,v16.16b,v4.16b + eor v25.16b,v17.16b,v5.16b + eor v26.16b,v18.16b,v6.16b + eor v27.16b,v19.16b,v7.16b + st1 {v24.16b,v25.16b,v26.16b,v27.16b},[x0],#64 + b.eq .Ldone_neon + + add v16.4s,v28.4s,v0.4s + add v17.4s,v29.4s,v1.4s + add v18.4s,v30.4s,v2.4s + add v19.4s,v31.4s,v3.4s + sub x2,x2,#64 + +.Last_neon: + st1 {v16.16b,v17.16b,v18.16b,v19.16b},[sp] + + sub x0,x0,#1 + add x1,x1,x2 + add x0,x0,x2 + add x4,sp,x2 + neg x2,x2 + +.Loop_tail_neon: + ldrb w10,[x1,x2] + ldrb w11,[x4,x2] + add x2,x2,#1 + eor w10,w10,w11 + strb w10,[x0,x2] + cbnz x2,.Loop_tail_neon + + stp xzr,xzr,[sp,#0] + stp xzr,xzr,[sp,#16] + stp xzr,xzr,[sp,#32] + stp xzr,xzr,[sp,#48] + +.Ldone_neon: + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 +.inst 0xd50323bf // autiasp + ret +.size ChaCha20_neon,.-ChaCha20_neon +.type ChaCha20_512_neon,%function +.align 5 +ChaCha20_512_neon: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + + adr x5,.Lsigma + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + +.L512_or_more_neon: + sub sp,sp,#128+64 + + eor v7.16b,v7.16b,v7.16b + ldp x22,x23,[x5] // load sigma + ld1 {v0.4s},[x5],#16 + ldp x24,x25,[x3] // load key + ldp x26,x27,[x3,#16] + ld1 {v1.4s,v2.4s},[x3] + ldp x28,x30,[x4] // load counter + ld1 {v3.4s},[x4] + ld1 {v7.s}[0],[x5] + add x3,x5,#16 // .Lrot24 +#ifdef __AARCH64EB__ + rev64 v0.4s,v0.4s + ror x24,x24,#32 + ror x25,x25,#32 + ror x26,x26,#32 + ror x27,x27,#32 + ror x28,x28,#32 + ror x30,x30,#32 +#endif + add v3.4s,v3.4s,v7.4s // += 1 + stp q0,q1,[sp,#0] // off-load key block, invariant part + add v3.4s,v3.4s,v7.4s // not typo + str q2,[sp,#32] + add v4.4s,v3.4s,v7.4s + add v5.4s,v4.4s,v7.4s + add v6.4s,v5.4s,v7.4s + shl v7.4s,v7.4s,#2 // 1 -> 4 + + stp d8,d9,[sp,#128+0] // meet ABI requirements + stp d10,d11,[sp,#128+16] + stp d12,d13,[sp,#128+32] + stp d14,d15,[sp,#128+48] + + sub x2,x2,#512 // not typo + +.Loop_outer_512_neon: + mov v8.16b,v0.16b + mov v12.16b,v0.16b + mov v16.16b,v0.16b + mov v20.16b,v0.16b + mov v24.16b,v0.16b + mov v28.16b,v0.16b + mov v9.16b,v1.16b + mov w5,w22 // unpack key block + mov v13.16b,v1.16b + lsr x6,x22,#32 + mov v17.16b,v1.16b + mov w7,w23 + mov v21.16b,v1.16b + lsr x8,x23,#32 + mov v25.16b,v1.16b + mov w9,w24 + mov v29.16b,v1.16b + lsr x10,x24,#32 + mov v11.16b,v3.16b + mov w11,w25 + mov v15.16b,v4.16b + lsr x12,x25,#32 + mov v19.16b,v5.16b + mov w13,w26 + mov v23.16b,v6.16b + lsr x14,x26,#32 + mov v10.16b,v2.16b + mov w15,w27 + mov v14.16b,v2.16b + lsr x16,x27,#32 + add v27.4s,v11.4s,v7.4s // +4 + mov w17,w28 + add v31.4s,v15.4s,v7.4s // +4 + lsr x19,x28,#32 + mov v18.16b,v2.16b + mov w20,w30 + mov v22.16b,v2.16b + lsr x21,x30,#32 + mov v26.16b,v2.16b + stp q3,q4,[sp,#48] // off-load key block, variable part + mov v30.16b,v2.16b + stp q5,q6,[sp,#80] + + mov x4,#5 + ld1 {v6.4s},[x3] + subs x2,x2,#512 +.Loop_upper_neon: + sub x4,x4,#1 + add v8.4s,v8.4s,v9.4s + add w5,w5,w9 + add v12.4s,v12.4s,v13.4s + add w6,w6,w10 + add v16.4s,v16.4s,v17.4s + add w7,w7,w11 + add v20.4s,v20.4s,v21.4s + add w8,w8,w12 + add v24.4s,v24.4s,v25.4s + eor w17,w17,w5 + add v28.4s,v28.4s,v29.4s + eor w19,w19,w6 + eor v11.16b,v11.16b,v8.16b + eor w20,w20,w7 + eor v15.16b,v15.16b,v12.16b + eor w21,w21,w8 + eor v19.16b,v19.16b,v16.16b + ror w17,w17,#16 + eor v23.16b,v23.16b,v20.16b + ror w19,w19,#16 + eor v27.16b,v27.16b,v24.16b + ror w20,w20,#16 + eor v31.16b,v31.16b,v28.16b + ror w21,w21,#16 + rev32 v11.8h,v11.8h + add w13,w13,w17 + rev32 v15.8h,v15.8h + add w14,w14,w19 + rev32 v19.8h,v19.8h + add w15,w15,w20 + rev32 v23.8h,v23.8h + add w16,w16,w21 + rev32 v27.8h,v27.8h + eor w9,w9,w13 + rev32 v31.8h,v31.8h + eor w10,w10,w14 + add v10.4s,v10.4s,v11.4s + eor w11,w11,w15 + add v14.4s,v14.4s,v15.4s + eor w12,w12,w16 + add v18.4s,v18.4s,v19.4s + ror w9,w9,#20 + add v22.4s,v22.4s,v23.4s + ror w10,w10,#20 + add v26.4s,v26.4s,v27.4s + ror w11,w11,#20 + add v30.4s,v30.4s,v31.4s + ror w12,w12,#20 + eor v0.16b,v9.16b,v10.16b + add w5,w5,w9 + eor v1.16b,v13.16b,v14.16b + add w6,w6,w10 + eor v2.16b,v17.16b,v18.16b + add w7,w7,w11 + eor v3.16b,v21.16b,v22.16b + add w8,w8,w12 + eor v4.16b,v25.16b,v26.16b + eor w17,w17,w5 + eor v5.16b,v29.16b,v30.16b + eor w19,w19,w6 + ushr v9.4s,v0.4s,#20 + eor w20,w20,w7 + ushr v13.4s,v1.4s,#20 + eor w21,w21,w8 + ushr v17.4s,v2.4s,#20 + ror w17,w17,#24 + ushr v21.4s,v3.4s,#20 + ror w19,w19,#24 + ushr v25.4s,v4.4s,#20 + ror w20,w20,#24 + ushr v29.4s,v5.4s,#20 + ror w21,w21,#24 + sli v9.4s,v0.4s,#12 + add w13,w13,w17 + sli v13.4s,v1.4s,#12 + add w14,w14,w19 + sli v17.4s,v2.4s,#12 + add w15,w15,w20 + sli v21.4s,v3.4s,#12 + add w16,w16,w21 + sli v25.4s,v4.4s,#12 + eor w9,w9,w13 + sli v29.4s,v5.4s,#12 + eor w10,w10,w14 + add v8.4s,v8.4s,v9.4s + eor w11,w11,w15 + add v12.4s,v12.4s,v13.4s + eor w12,w12,w16 + add v16.4s,v16.4s,v17.4s + ror w9,w9,#25 + add v20.4s,v20.4s,v21.4s + ror w10,w10,#25 + add v24.4s,v24.4s,v25.4s + ror w11,w11,#25 + add v28.4s,v28.4s,v29.4s + ror w12,w12,#25 + eor v11.16b,v11.16b,v8.16b + add w5,w5,w10 + eor v15.16b,v15.16b,v12.16b + add w6,w6,w11 + eor v19.16b,v19.16b,v16.16b + add w7,w7,w12 + eor v23.16b,v23.16b,v20.16b + add w8,w8,w9 + eor v27.16b,v27.16b,v24.16b + eor w21,w21,w5 + eor v31.16b,v31.16b,v28.16b + eor w17,w17,w6 + tbl v11.16b,{v11.16b},v6.16b + eor w19,w19,w7 + tbl v15.16b,{v15.16b},v6.16b + eor w20,w20,w8 + tbl v19.16b,{v19.16b},v6.16b + ror w21,w21,#16 + tbl v23.16b,{v23.16b},v6.16b + ror w17,w17,#16 + tbl v27.16b,{v27.16b},v6.16b + ror w19,w19,#16 + tbl v31.16b,{v31.16b},v6.16b + ror w20,w20,#16 + add v10.4s,v10.4s,v11.4s + add w15,w15,w21 + add v14.4s,v14.4s,v15.4s + add w16,w16,w17 + add v18.4s,v18.4s,v19.4s + add w13,w13,w19 + add v22.4s,v22.4s,v23.4s + add w14,w14,w20 + add v26.4s,v26.4s,v27.4s + eor w10,w10,w15 + add v30.4s,v30.4s,v31.4s + eor w11,w11,w16 + eor v0.16b,v9.16b,v10.16b + eor w12,w12,w13 + eor v1.16b,v13.16b,v14.16b + eor w9,w9,w14 + eor v2.16b,v17.16b,v18.16b + ror w10,w10,#20 + eor v3.16b,v21.16b,v22.16b + ror w11,w11,#20 + eor v4.16b,v25.16b,v26.16b + ror w12,w12,#20 + eor v5.16b,v29.16b,v30.16b + ror w9,w9,#20 + ushr v9.4s,v0.4s,#25 + add w5,w5,w10 + ushr v13.4s,v1.4s,#25 + add w6,w6,w11 + ushr v17.4s,v2.4s,#25 + add w7,w7,w12 + ushr v21.4s,v3.4s,#25 + add w8,w8,w9 + ushr v25.4s,v4.4s,#25 + eor w21,w21,w5 + ushr v29.4s,v5.4s,#25 + eor w17,w17,w6 + sli v9.4s,v0.4s,#7 + eor w19,w19,w7 + sli v13.4s,v1.4s,#7 + eor w20,w20,w8 + sli v17.4s,v2.4s,#7 + ror w21,w21,#24 + sli v21.4s,v3.4s,#7 + ror w17,w17,#24 + sli v25.4s,v4.4s,#7 + ror w19,w19,#24 + sli v29.4s,v5.4s,#7 + ror w20,w20,#24 + ext v10.16b,v10.16b,v10.16b,#8 + add w15,w15,w21 + ext v14.16b,v14.16b,v14.16b,#8 + add w16,w16,w17 + ext v18.16b,v18.16b,v18.16b,#8 + add w13,w13,w19 + ext v22.16b,v22.16b,v22.16b,#8 + add w14,w14,w20 + ext v26.16b,v26.16b,v26.16b,#8 + eor w10,w10,w15 + ext v30.16b,v30.16b,v30.16b,#8 + eor w11,w11,w16 + ext v11.16b,v11.16b,v11.16b,#12 + eor w12,w12,w13 + ext v15.16b,v15.16b,v15.16b,#12 + eor w9,w9,w14 + ext v19.16b,v19.16b,v19.16b,#12 + ror w10,w10,#25 + ext v23.16b,v23.16b,v23.16b,#12 + ror w11,w11,#25 + ext v27.16b,v27.16b,v27.16b,#12 + ror w12,w12,#25 + ext v31.16b,v31.16b,v31.16b,#12 + ror w9,w9,#25 + ext v9.16b,v9.16b,v9.16b,#4 + ext v13.16b,v13.16b,v13.16b,#4 + ext v17.16b,v17.16b,v17.16b,#4 + ext v21.16b,v21.16b,v21.16b,#4 + ext v25.16b,v25.16b,v25.16b,#4 + ext v29.16b,v29.16b,v29.16b,#4 + add v8.4s,v8.4s,v9.4s + add w5,w5,w9 + add v12.4s,v12.4s,v13.4s + add w6,w6,w10 + add v16.4s,v16.4s,v17.4s + add w7,w7,w11 + add v20.4s,v20.4s,v21.4s + add w8,w8,w12 + add v24.4s,v24.4s,v25.4s + eor w17,w17,w5 + add v28.4s,v28.4s,v29.4s + eor w19,w19,w6 + eor v11.16b,v11.16b,v8.16b + eor w20,w20,w7 + eor v15.16b,v15.16b,v12.16b + eor w21,w21,w8 + eor v19.16b,v19.16b,v16.16b + ror w17,w17,#16 + eor v23.16b,v23.16b,v20.16b + ror w19,w19,#16 + eor v27.16b,v27.16b,v24.16b + ror w20,w20,#16 + eor v31.16b,v31.16b,v28.16b + ror w21,w21,#16 + rev32 v11.8h,v11.8h + add w13,w13,w17 + rev32 v15.8h,v15.8h + add w14,w14,w19 + rev32 v19.8h,v19.8h + add w15,w15,w20 + rev32 v23.8h,v23.8h + add w16,w16,w21 + rev32 v27.8h,v27.8h + eor w9,w9,w13 + rev32 v31.8h,v31.8h + eor w10,w10,w14 + add v10.4s,v10.4s,v11.4s + eor w11,w11,w15 + add v14.4s,v14.4s,v15.4s + eor w12,w12,w16 + add v18.4s,v18.4s,v19.4s + ror w9,w9,#20 + add v22.4s,v22.4s,v23.4s + ror w10,w10,#20 + add v26.4s,v26.4s,v27.4s + ror w11,w11,#20 + add v30.4s,v30.4s,v31.4s + ror w12,w12,#20 + eor v0.16b,v9.16b,v10.16b + add w5,w5,w9 + eor v1.16b,v13.16b,v14.16b + add w6,w6,w10 + eor v2.16b,v17.16b,v18.16b + add w7,w7,w11 + eor v3.16b,v21.16b,v22.16b + add w8,w8,w12 + eor v4.16b,v25.16b,v26.16b + eor w17,w17,w5 + eor v5.16b,v29.16b,v30.16b + eor w19,w19,w6 + ushr v9.4s,v0.4s,#20 + eor w20,w20,w7 + ushr v13.4s,v1.4s,#20 + eor w21,w21,w8 + ushr v17.4s,v2.4s,#20 + ror w17,w17,#24 + ushr v21.4s,v3.4s,#20 + ror w19,w19,#24 + ushr v25.4s,v4.4s,#20 + ror w20,w20,#24 + ushr v29.4s,v5.4s,#20 + ror w21,w21,#24 + sli v9.4s,v0.4s,#12 + add w13,w13,w17 + sli v13.4s,v1.4s,#12 + add w14,w14,w19 + sli v17.4s,v2.4s,#12 + add w15,w15,w20 + sli v21.4s,v3.4s,#12 + add w16,w16,w21 + sli v25.4s,v4.4s,#12 + eor w9,w9,w13 + sli v29.4s,v5.4s,#12 + eor w10,w10,w14 + add v8.4s,v8.4s,v9.4s + eor w11,w11,w15 + add v12.4s,v12.4s,v13.4s + eor w12,w12,w16 + add v16.4s,v16.4s,v17.4s + ror w9,w9,#25 + add v20.4s,v20.4s,v21.4s + ror w10,w10,#25 + add v24.4s,v24.4s,v25.4s + ror w11,w11,#25 + add v28.4s,v28.4s,v29.4s + ror w12,w12,#25 + eor v11.16b,v11.16b,v8.16b + add w5,w5,w10 + eor v15.16b,v15.16b,v12.16b + add w6,w6,w11 + eor v19.16b,v19.16b,v16.16b + add w7,w7,w12 + eor v23.16b,v23.16b,v20.16b + add w8,w8,w9 + eor v27.16b,v27.16b,v24.16b + eor w21,w21,w5 + eor v31.16b,v31.16b,v28.16b + eor w17,w17,w6 + tbl v11.16b,{v11.16b},v6.16b + eor w19,w19,w7 + tbl v15.16b,{v15.16b},v6.16b + eor w20,w20,w8 + tbl v19.16b,{v19.16b},v6.16b + ror w21,w21,#16 + tbl v23.16b,{v23.16b},v6.16b + ror w17,w17,#16 + tbl v27.16b,{v27.16b},v6.16b + ror w19,w19,#16 + tbl v31.16b,{v31.16b},v6.16b + ror w20,w20,#16 + add v10.4s,v10.4s,v11.4s + add w15,w15,w21 + add v14.4s,v14.4s,v15.4s + add w16,w16,w17 + add v18.4s,v18.4s,v19.4s + add w13,w13,w19 + add v22.4s,v22.4s,v23.4s + add w14,w14,w20 + add v26.4s,v26.4s,v27.4s + eor w10,w10,w15 + add v30.4s,v30.4s,v31.4s + eor w11,w11,w16 + eor v0.16b,v9.16b,v10.16b + eor w12,w12,w13 + eor v1.16b,v13.16b,v14.16b + eor w9,w9,w14 + eor v2.16b,v17.16b,v18.16b + ror w10,w10,#20 + eor v3.16b,v21.16b,v22.16b + ror w11,w11,#20 + eor v4.16b,v25.16b,v26.16b + ror w12,w12,#20 + eor v5.16b,v29.16b,v30.16b + ror w9,w9,#20 + ushr v9.4s,v0.4s,#25 + add w5,w5,w10 + ushr v13.4s,v1.4s,#25 + add w6,w6,w11 + ushr v17.4s,v2.4s,#25 + add w7,w7,w12 + ushr v21.4s,v3.4s,#25 + add w8,w8,w9 + ushr v25.4s,v4.4s,#25 + eor w21,w21,w5 + ushr v29.4s,v5.4s,#25 + eor w17,w17,w6 + sli v9.4s,v0.4s,#7 + eor w19,w19,w7 + sli v13.4s,v1.4s,#7 + eor w20,w20,w8 + sli v17.4s,v2.4s,#7 + ror w21,w21,#24 + sli v21.4s,v3.4s,#7 + ror w17,w17,#24 + sli v25.4s,v4.4s,#7 + ror w19,w19,#24 + sli v29.4s,v5.4s,#7 + ror w20,w20,#24 + ext v10.16b,v10.16b,v10.16b,#8 + add w15,w15,w21 + ext v14.16b,v14.16b,v14.16b,#8 + add w16,w16,w17 + ext v18.16b,v18.16b,v18.16b,#8 + add w13,w13,w19 + ext v22.16b,v22.16b,v22.16b,#8 + add w14,w14,w20 + ext v26.16b,v26.16b,v26.16b,#8 + eor w10,w10,w15 + ext v30.16b,v30.16b,v30.16b,#8 + eor w11,w11,w16 + ext v11.16b,v11.16b,v11.16b,#4 + eor w12,w12,w13 + ext v15.16b,v15.16b,v15.16b,#4 + eor w9,w9,w14 + ext v19.16b,v19.16b,v19.16b,#4 + ror w10,w10,#25 + ext v23.16b,v23.16b,v23.16b,#4 + ror w11,w11,#25 + ext v27.16b,v27.16b,v27.16b,#4 + ror w12,w12,#25 + ext v31.16b,v31.16b,v31.16b,#4 + ror w9,w9,#25 + ext v9.16b,v9.16b,v9.16b,#12 + ext v13.16b,v13.16b,v13.16b,#12 + ext v17.16b,v17.16b,v17.16b,#12 + ext v21.16b,v21.16b,v21.16b,#12 + ext v25.16b,v25.16b,v25.16b,#12 + ext v29.16b,v29.16b,v29.16b,#12 + cbnz x4,.Loop_upper_neon + + add w5,w5,w22 // accumulate key block + add x6,x6,x22,lsr#32 + add w7,w7,w23 + add x8,x8,x23,lsr#32 + add w9,w9,w24 + add x10,x10,x24,lsr#32 + add w11,w11,w25 + add x12,x12,x25,lsr#32 + add w13,w13,w26 + add x14,x14,x26,lsr#32 + add w15,w15,w27 + add x16,x16,x27,lsr#32 + add w17,w17,w28 + add x19,x19,x28,lsr#32 + add w20,w20,w30 + add x21,x21,x30,lsr#32 + + add x5,x5,x6,lsl#32 // pack + add x7,x7,x8,lsl#32 + ldp x6,x8,[x1,#0] // load input + add x9,x9,x10,lsl#32 + add x11,x11,x12,lsl#32 + ldp x10,x12,[x1,#16] + add x13,x13,x14,lsl#32 + add x15,x15,x16,lsl#32 + ldp x14,x16,[x1,#32] + add x17,x17,x19,lsl#32 + add x20,x20,x21,lsl#32 + ldp x19,x21,[x1,#48] + add x1,x1,#64 +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor x15,x15,x16 + eor x17,x17,x19 + eor x20,x20,x21 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#1 // increment counter + mov w5,w22 // unpack key block + lsr x6,x22,#32 + stp x9,x11,[x0,#16] + mov w7,w23 + lsr x8,x23,#32 + stp x13,x15,[x0,#32] + mov w9,w24 + lsr x10,x24,#32 + stp x17,x20,[x0,#48] + add x0,x0,#64 + mov w11,w25 + lsr x12,x25,#32 + mov w13,w26 + lsr x14,x26,#32 + mov w15,w27 + lsr x16,x27,#32 + mov w17,w28 + lsr x19,x28,#32 + mov w20,w30 + lsr x21,x30,#32 + + mov x4,#5 +.Loop_lower_neon: + sub x4,x4,#1 + add v8.4s,v8.4s,v9.4s + add w5,w5,w9 + add v12.4s,v12.4s,v13.4s + add w6,w6,w10 + add v16.4s,v16.4s,v17.4s + add w7,w7,w11 + add v20.4s,v20.4s,v21.4s + add w8,w8,w12 + add v24.4s,v24.4s,v25.4s + eor w17,w17,w5 + add v28.4s,v28.4s,v29.4s + eor w19,w19,w6 + eor v11.16b,v11.16b,v8.16b + eor w20,w20,w7 + eor v15.16b,v15.16b,v12.16b + eor w21,w21,w8 + eor v19.16b,v19.16b,v16.16b + ror w17,w17,#16 + eor v23.16b,v23.16b,v20.16b + ror w19,w19,#16 + eor v27.16b,v27.16b,v24.16b + ror w20,w20,#16 + eor v31.16b,v31.16b,v28.16b + ror w21,w21,#16 + rev32 v11.8h,v11.8h + add w13,w13,w17 + rev32 v15.8h,v15.8h + add w14,w14,w19 + rev32 v19.8h,v19.8h + add w15,w15,w20 + rev32 v23.8h,v23.8h + add w16,w16,w21 + rev32 v27.8h,v27.8h + eor w9,w9,w13 + rev32 v31.8h,v31.8h + eor w10,w10,w14 + add v10.4s,v10.4s,v11.4s + eor w11,w11,w15 + add v14.4s,v14.4s,v15.4s + eor w12,w12,w16 + add v18.4s,v18.4s,v19.4s + ror w9,w9,#20 + add v22.4s,v22.4s,v23.4s + ror w10,w10,#20 + add v26.4s,v26.4s,v27.4s + ror w11,w11,#20 + add v30.4s,v30.4s,v31.4s + ror w12,w12,#20 + eor v0.16b,v9.16b,v10.16b + add w5,w5,w9 + eor v1.16b,v13.16b,v14.16b + add w6,w6,w10 + eor v2.16b,v17.16b,v18.16b + add w7,w7,w11 + eor v3.16b,v21.16b,v22.16b + add w8,w8,w12 + eor v4.16b,v25.16b,v26.16b + eor w17,w17,w5 + eor v5.16b,v29.16b,v30.16b + eor w19,w19,w6 + ushr v9.4s,v0.4s,#20 + eor w20,w20,w7 + ushr v13.4s,v1.4s,#20 + eor w21,w21,w8 + ushr v17.4s,v2.4s,#20 + ror w17,w17,#24 + ushr v21.4s,v3.4s,#20 + ror w19,w19,#24 + ushr v25.4s,v4.4s,#20 + ror w20,w20,#24 + ushr v29.4s,v5.4s,#20 + ror w21,w21,#24 + sli v9.4s,v0.4s,#12 + add w13,w13,w17 + sli v13.4s,v1.4s,#12 + add w14,w14,w19 + sli v17.4s,v2.4s,#12 + add w15,w15,w20 + sli v21.4s,v3.4s,#12 + add w16,w16,w21 + sli v25.4s,v4.4s,#12 + eor w9,w9,w13 + sli v29.4s,v5.4s,#12 + eor w10,w10,w14 + add v8.4s,v8.4s,v9.4s + eor w11,w11,w15 + add v12.4s,v12.4s,v13.4s + eor w12,w12,w16 + add v16.4s,v16.4s,v17.4s + ror w9,w9,#25 + add v20.4s,v20.4s,v21.4s + ror w10,w10,#25 + add v24.4s,v24.4s,v25.4s + ror w11,w11,#25 + add v28.4s,v28.4s,v29.4s + ror w12,w12,#25 + eor v11.16b,v11.16b,v8.16b + add w5,w5,w10 + eor v15.16b,v15.16b,v12.16b + add w6,w6,w11 + eor v19.16b,v19.16b,v16.16b + add w7,w7,w12 + eor v23.16b,v23.16b,v20.16b + add w8,w8,w9 + eor v27.16b,v27.16b,v24.16b + eor w21,w21,w5 + eor v31.16b,v31.16b,v28.16b + eor w17,w17,w6 + tbl v11.16b,{v11.16b},v6.16b + eor w19,w19,w7 + tbl v15.16b,{v15.16b},v6.16b + eor w20,w20,w8 + tbl v19.16b,{v19.16b},v6.16b + ror w21,w21,#16 + tbl v23.16b,{v23.16b},v6.16b + ror w17,w17,#16 + tbl v27.16b,{v27.16b},v6.16b + ror w19,w19,#16 + tbl v31.16b,{v31.16b},v6.16b + ror w20,w20,#16 + add v10.4s,v10.4s,v11.4s + add w15,w15,w21 + add v14.4s,v14.4s,v15.4s + add w16,w16,w17 + add v18.4s,v18.4s,v19.4s + add w13,w13,w19 + add v22.4s,v22.4s,v23.4s + add w14,w14,w20 + add v26.4s,v26.4s,v27.4s + eor w10,w10,w15 + add v30.4s,v30.4s,v31.4s + eor w11,w11,w16 + eor v0.16b,v9.16b,v10.16b + eor w12,w12,w13 + eor v1.16b,v13.16b,v14.16b + eor w9,w9,w14 + eor v2.16b,v17.16b,v18.16b + ror w10,w10,#20 + eor v3.16b,v21.16b,v22.16b + ror w11,w11,#20 + eor v4.16b,v25.16b,v26.16b + ror w12,w12,#20 + eor v5.16b,v29.16b,v30.16b + ror w9,w9,#20 + ushr v9.4s,v0.4s,#25 + add w5,w5,w10 + ushr v13.4s,v1.4s,#25 + add w6,w6,w11 + ushr v17.4s,v2.4s,#25 + add w7,w7,w12 + ushr v21.4s,v3.4s,#25 + add w8,w8,w9 + ushr v25.4s,v4.4s,#25 + eor w21,w21,w5 + ushr v29.4s,v5.4s,#25 + eor w17,w17,w6 + sli v9.4s,v0.4s,#7 + eor w19,w19,w7 + sli v13.4s,v1.4s,#7 + eor w20,w20,w8 + sli v17.4s,v2.4s,#7 + ror w21,w21,#24 + sli v21.4s,v3.4s,#7 + ror w17,w17,#24 + sli v25.4s,v4.4s,#7 + ror w19,w19,#24 + sli v29.4s,v5.4s,#7 + ror w20,w20,#24 + ext v10.16b,v10.16b,v10.16b,#8 + add w15,w15,w21 + ext v14.16b,v14.16b,v14.16b,#8 + add w16,w16,w17 + ext v18.16b,v18.16b,v18.16b,#8 + add w13,w13,w19 + ext v22.16b,v22.16b,v22.16b,#8 + add w14,w14,w20 + ext v26.16b,v26.16b,v26.16b,#8 + eor w10,w10,w15 + ext v30.16b,v30.16b,v30.16b,#8 + eor w11,w11,w16 + ext v11.16b,v11.16b,v11.16b,#12 + eor w12,w12,w13 + ext v15.16b,v15.16b,v15.16b,#12 + eor w9,w9,w14 + ext v19.16b,v19.16b,v19.16b,#12 + ror w10,w10,#25 + ext v23.16b,v23.16b,v23.16b,#12 + ror w11,w11,#25 + ext v27.16b,v27.16b,v27.16b,#12 + ror w12,w12,#25 + ext v31.16b,v31.16b,v31.16b,#12 + ror w9,w9,#25 + ext v9.16b,v9.16b,v9.16b,#4 + ext v13.16b,v13.16b,v13.16b,#4 + ext v17.16b,v17.16b,v17.16b,#4 + ext v21.16b,v21.16b,v21.16b,#4 + ext v25.16b,v25.16b,v25.16b,#4 + ext v29.16b,v29.16b,v29.16b,#4 + add v8.4s,v8.4s,v9.4s + add w5,w5,w9 + add v12.4s,v12.4s,v13.4s + add w6,w6,w10 + add v16.4s,v16.4s,v17.4s + add w7,w7,w11 + add v20.4s,v20.4s,v21.4s + add w8,w8,w12 + add v24.4s,v24.4s,v25.4s + eor w17,w17,w5 + add v28.4s,v28.4s,v29.4s + eor w19,w19,w6 + eor v11.16b,v11.16b,v8.16b + eor w20,w20,w7 + eor v15.16b,v15.16b,v12.16b + eor w21,w21,w8 + eor v19.16b,v19.16b,v16.16b + ror w17,w17,#16 + eor v23.16b,v23.16b,v20.16b + ror w19,w19,#16 + eor v27.16b,v27.16b,v24.16b + ror w20,w20,#16 + eor v31.16b,v31.16b,v28.16b + ror w21,w21,#16 + rev32 v11.8h,v11.8h + add w13,w13,w17 + rev32 v15.8h,v15.8h + add w14,w14,w19 + rev32 v19.8h,v19.8h + add w15,w15,w20 + rev32 v23.8h,v23.8h + add w16,w16,w21 + rev32 v27.8h,v27.8h + eor w9,w9,w13 + rev32 v31.8h,v31.8h + eor w10,w10,w14 + add v10.4s,v10.4s,v11.4s + eor w11,w11,w15 + add v14.4s,v14.4s,v15.4s + eor w12,w12,w16 + add v18.4s,v18.4s,v19.4s + ror w9,w9,#20 + add v22.4s,v22.4s,v23.4s + ror w10,w10,#20 + add v26.4s,v26.4s,v27.4s + ror w11,w11,#20 + add v30.4s,v30.4s,v31.4s + ror w12,w12,#20 + eor v0.16b,v9.16b,v10.16b + add w5,w5,w9 + eor v1.16b,v13.16b,v14.16b + add w6,w6,w10 + eor v2.16b,v17.16b,v18.16b + add w7,w7,w11 + eor v3.16b,v21.16b,v22.16b + add w8,w8,w12 + eor v4.16b,v25.16b,v26.16b + eor w17,w17,w5 + eor v5.16b,v29.16b,v30.16b + eor w19,w19,w6 + ushr v9.4s,v0.4s,#20 + eor w20,w20,w7 + ushr v13.4s,v1.4s,#20 + eor w21,w21,w8 + ushr v17.4s,v2.4s,#20 + ror w17,w17,#24 + ushr v21.4s,v3.4s,#20 + ror w19,w19,#24 + ushr v25.4s,v4.4s,#20 + ror w20,w20,#24 + ushr v29.4s,v5.4s,#20 + ror w21,w21,#24 + sli v9.4s,v0.4s,#12 + add w13,w13,w17 + sli v13.4s,v1.4s,#12 + add w14,w14,w19 + sli v17.4s,v2.4s,#12 + add w15,w15,w20 + sli v21.4s,v3.4s,#12 + add w16,w16,w21 + sli v25.4s,v4.4s,#12 + eor w9,w9,w13 + sli v29.4s,v5.4s,#12 + eor w10,w10,w14 + add v8.4s,v8.4s,v9.4s + eor w11,w11,w15 + add v12.4s,v12.4s,v13.4s + eor w12,w12,w16 + add v16.4s,v16.4s,v17.4s + ror w9,w9,#25 + add v20.4s,v20.4s,v21.4s + ror w10,w10,#25 + add v24.4s,v24.4s,v25.4s + ror w11,w11,#25 + add v28.4s,v28.4s,v29.4s + ror w12,w12,#25 + eor v11.16b,v11.16b,v8.16b + add w5,w5,w10 + eor v15.16b,v15.16b,v12.16b + add w6,w6,w11 + eor v19.16b,v19.16b,v16.16b + add w7,w7,w12 + eor v23.16b,v23.16b,v20.16b + add w8,w8,w9 + eor v27.16b,v27.16b,v24.16b + eor w21,w21,w5 + eor v31.16b,v31.16b,v28.16b + eor w17,w17,w6 + tbl v11.16b,{v11.16b},v6.16b + eor w19,w19,w7 + tbl v15.16b,{v15.16b},v6.16b + eor w20,w20,w8 + tbl v19.16b,{v19.16b},v6.16b + ror w21,w21,#16 + tbl v23.16b,{v23.16b},v6.16b + ror w17,w17,#16 + tbl v27.16b,{v27.16b},v6.16b + ror w19,w19,#16 + tbl v31.16b,{v31.16b},v6.16b + ror w20,w20,#16 + add v10.4s,v10.4s,v11.4s + add w15,w15,w21 + add v14.4s,v14.4s,v15.4s + add w16,w16,w17 + add v18.4s,v18.4s,v19.4s + add w13,w13,w19 + add v22.4s,v22.4s,v23.4s + add w14,w14,w20 + add v26.4s,v26.4s,v27.4s + eor w10,w10,w15 + add v30.4s,v30.4s,v31.4s + eor w11,w11,w16 + eor v0.16b,v9.16b,v10.16b + eor w12,w12,w13 + eor v1.16b,v13.16b,v14.16b + eor w9,w9,w14 + eor v2.16b,v17.16b,v18.16b + ror w10,w10,#20 + eor v3.16b,v21.16b,v22.16b + ror w11,w11,#20 + eor v4.16b,v25.16b,v26.16b + ror w12,w12,#20 + eor v5.16b,v29.16b,v30.16b + ror w9,w9,#20 + ushr v9.4s,v0.4s,#25 + add w5,w5,w10 + ushr v13.4s,v1.4s,#25 + add w6,w6,w11 + ushr v17.4s,v2.4s,#25 + add w7,w7,w12 + ushr v21.4s,v3.4s,#25 + add w8,w8,w9 + ushr v25.4s,v4.4s,#25 + eor w21,w21,w5 + ushr v29.4s,v5.4s,#25 + eor w17,w17,w6 + sli v9.4s,v0.4s,#7 + eor w19,w19,w7 + sli v13.4s,v1.4s,#7 + eor w20,w20,w8 + sli v17.4s,v2.4s,#7 + ror w21,w21,#24 + sli v21.4s,v3.4s,#7 + ror w17,w17,#24 + sli v25.4s,v4.4s,#7 + ror w19,w19,#24 + sli v29.4s,v5.4s,#7 + ror w20,w20,#24 + ext v10.16b,v10.16b,v10.16b,#8 + add w15,w15,w21 + ext v14.16b,v14.16b,v14.16b,#8 + add w16,w16,w17 + ext v18.16b,v18.16b,v18.16b,#8 + add w13,w13,w19 + ext v22.16b,v22.16b,v22.16b,#8 + add w14,w14,w20 + ext v26.16b,v26.16b,v26.16b,#8 + eor w10,w10,w15 + ext v30.16b,v30.16b,v30.16b,#8 + eor w11,w11,w16 + ext v11.16b,v11.16b,v11.16b,#4 + eor w12,w12,w13 + ext v15.16b,v15.16b,v15.16b,#4 + eor w9,w9,w14 + ext v19.16b,v19.16b,v19.16b,#4 + ror w10,w10,#25 + ext v23.16b,v23.16b,v23.16b,#4 + ror w11,w11,#25 + ext v27.16b,v27.16b,v27.16b,#4 + ror w12,w12,#25 + ext v31.16b,v31.16b,v31.16b,#4 + ror w9,w9,#25 + ext v9.16b,v9.16b,v9.16b,#12 + ext v13.16b,v13.16b,v13.16b,#12 + ext v17.16b,v17.16b,v17.16b,#12 + ext v21.16b,v21.16b,v21.16b,#12 + ext v25.16b,v25.16b,v25.16b,#12 + ext v29.16b,v29.16b,v29.16b,#12 + cbnz x4,.Loop_lower_neon + + add w5,w5,w22 // accumulate key block + ldp q0,q1,[sp,#0] + add x6,x6,x22,lsr#32 + ldp q2,q3,[sp,#32] + add w7,w7,w23 + ldp q4,q5,[sp,#64] + add x8,x8,x23,lsr#32 + ldr q6,[sp,#96] + add v8.4s,v8.4s,v0.4s + add w9,w9,w24 + add v12.4s,v12.4s,v0.4s + add x10,x10,x24,lsr#32 + add v16.4s,v16.4s,v0.4s + add w11,w11,w25 + add v20.4s,v20.4s,v0.4s + add x12,x12,x25,lsr#32 + add v24.4s,v24.4s,v0.4s + add w13,w13,w26 + add v28.4s,v28.4s,v0.4s + add x14,x14,x26,lsr#32 + add v10.4s,v10.4s,v2.4s + add w15,w15,w27 + add v14.4s,v14.4s,v2.4s + add x16,x16,x27,lsr#32 + add v18.4s,v18.4s,v2.4s + add w17,w17,w28 + add v22.4s,v22.4s,v2.4s + add x19,x19,x28,lsr#32 + add v26.4s,v26.4s,v2.4s + add w20,w20,w30 + add v30.4s,v30.4s,v2.4s + add x21,x21,x30,lsr#32 + add v27.4s,v27.4s,v7.4s // +4 + add x5,x5,x6,lsl#32 // pack + add v31.4s,v31.4s,v7.4s // +4 + add x7,x7,x8,lsl#32 + add v11.4s,v11.4s,v3.4s + ldp x6,x8,[x1,#0] // load input + add v15.4s,v15.4s,v4.4s + add x9,x9,x10,lsl#32 + add v19.4s,v19.4s,v5.4s + add x11,x11,x12,lsl#32 + add v23.4s,v23.4s,v6.4s + ldp x10,x12,[x1,#16] + add v27.4s,v27.4s,v3.4s + add x13,x13,x14,lsl#32 + add v31.4s,v31.4s,v4.4s + add x15,x15,x16,lsl#32 + add v9.4s,v9.4s,v1.4s + ldp x14,x16,[x1,#32] + add v13.4s,v13.4s,v1.4s + add x17,x17,x19,lsl#32 + add v17.4s,v17.4s,v1.4s + add x20,x20,x21,lsl#32 + add v21.4s,v21.4s,v1.4s + ldp x19,x21,[x1,#48] + add v25.4s,v25.4s,v1.4s + add x1,x1,#64 + add v29.4s,v29.4s,v1.4s + +#ifdef __AARCH64EB__ + rev x5,x5 + rev x7,x7 + rev x9,x9 + rev x11,x11 + rev x13,x13 + rev x15,x15 + rev x17,x17 + rev x20,x20 +#endif + ld1 {v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64 + eor x5,x5,x6 + eor x7,x7,x8 + eor x9,x9,x10 + eor x11,x11,x12 + eor x13,x13,x14 + eor v8.16b,v8.16b,v0.16b + eor x15,x15,x16 + eor v9.16b,v9.16b,v1.16b + eor x17,x17,x19 + eor v10.16b,v10.16b,v2.16b + eor x20,x20,x21 + eor v11.16b,v11.16b,v3.16b + ld1 {v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64 + + stp x5,x7,[x0,#0] // store output + add x28,x28,#7 // increment counter + stp x9,x11,[x0,#16] + stp x13,x15,[x0,#32] + stp x17,x20,[x0,#48] + add x0,x0,#64 + st1 {v8.16b,v9.16b,v10.16b,v11.16b},[x0],#64 + + ld1 {v8.16b,v9.16b,v10.16b,v11.16b},[x1],#64 + eor v12.16b,v12.16b,v0.16b + eor v13.16b,v13.16b,v1.16b + eor v14.16b,v14.16b,v2.16b + eor v15.16b,v15.16b,v3.16b + st1 {v12.16b,v13.16b,v14.16b,v15.16b},[x0],#64 + + ld1 {v12.16b,v13.16b,v14.16b,v15.16b},[x1],#64 + eor v16.16b,v16.16b,v8.16b + ldp q0,q1,[sp,#0] + eor v17.16b,v17.16b,v9.16b + ldp q2,q3,[sp,#32] + eor v18.16b,v18.16b,v10.16b + eor v19.16b,v19.16b,v11.16b + st1 {v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64 + + ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x1],#64 + eor v20.16b,v20.16b,v12.16b + eor v21.16b,v21.16b,v13.16b + eor v22.16b,v22.16b,v14.16b + eor v23.16b,v23.16b,v15.16b + st1 {v20.16b,v21.16b,v22.16b,v23.16b},[x0],#64 + + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + eor v24.16b,v24.16b,v16.16b + eor v25.16b,v25.16b,v17.16b + eor v26.16b,v26.16b,v18.16b + eor v27.16b,v27.16b,v19.16b + st1 {v24.16b,v25.16b,v26.16b,v27.16b},[x0],#64 + + shl v8.4s,v7.4s,#1 // 4 -> 8 + eor v28.16b,v28.16b,v20.16b + eor v29.16b,v29.16b,v21.16b + eor v30.16b,v30.16b,v22.16b + eor v31.16b,v31.16b,v23.16b + st1 {v28.16b,v29.16b,v30.16b,v31.16b},[x0],#64 + + add v3.4s,v3.4s,v8.4s // += 8 + add v4.4s,v4.4s,v8.4s + add v5.4s,v5.4s,v8.4s + add v6.4s,v6.4s,v8.4s + + b.hs .Loop_outer_512_neon + + adds x2,x2,#512 + ushr v7.4s,v7.4s,#1 // 4 -> 2 + + ldp d10,d11,[sp,#128+16] // meet ABI requirements + ldp d12,d13,[sp,#128+32] + ldp d14,d15,[sp,#128+48] + + stp q0,q0,[sp,#0] // wipe off-load area + stp q0,q0,[sp,#32] + stp q0,q0,[sp,#64] + + b.eq .Ldone_512_neon + + sub x3,x3,#16 // .Lone + cmp x2,#192 + add sp,sp,#128 + sub v3.4s,v3.4s,v7.4s // -= 2 + ld1 {v8.4s,v9.4s},[x3] + b.hs .Loop_outer_neon + + ldp d8,d9,[sp,#0] // meet ABI requirements + eor v1.16b,v1.16b,v1.16b + eor v2.16b,v2.16b,v2.16b + eor v3.16b,v3.16b,v3.16b + eor v4.16b,v4.16b,v4.16b + eor v5.16b,v5.16b,v5.16b + eor v6.16b,v6.16b,v6.16b + b .Loop_outer + +.Ldone_512_neon: + ldp d8,d9,[sp,#128+0] // meet ABI requirements + ldp x19,x20,[x29,#16] + add sp,sp,#128+64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 +.inst 0xd50323bf // autiasp + ret +.size ChaCha20_512_neon,.-ChaCha20_512_neon diff --git a/crypto/openssl/crypto/chacha/chacha-x86.S b/crypto/openssl/crypto/chacha/chacha-x86.S new file mode 100644 index 000000000000..1fe410585d96 --- /dev/null +++ b/crypto/openssl/crypto/chacha/chacha-x86.S @@ -0,0 +1,1040 @@ +.text +.globl ChaCha20_ctr32 +.type ChaCha20_ctr32,@function +.align 16 +ChaCha20_ctr32: +.L_ChaCha20_ctr32_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + xorl %eax,%eax + cmpl 28(%esp),%eax + je .L000no_data + call .Lpic_point +.Lpic_point: + popl %eax + leal OPENSSL_ia32cap_P-.Lpic_point(%eax),%ebp + testl $16777216,(%ebp) + jz .L001x86 + testl $512,4(%ebp) + jz .L001x86 + jmp .Lssse3_shortcut +.L001x86: + movl 32(%esp),%esi + movl 36(%esp),%edi + subl $132,%esp + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,80(%esp) + movl %ebx,84(%esp) + movl %ecx,88(%esp) + movl %edx,92(%esp) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + movl %eax,96(%esp) + movl %ebx,100(%esp) + movl %ecx,104(%esp) + movl %edx,108(%esp) + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + subl $1,%eax + movl %eax,112(%esp) + movl %ebx,116(%esp) + movl %ecx,120(%esp) + movl %edx,124(%esp) + jmp .L002entry +.align 16 +.L003outer_loop: + movl %ebx,156(%esp) + movl %eax,152(%esp) + movl %ecx,160(%esp) +.L002entry: + movl $1634760805,%eax + movl $857760878,4(%esp) + movl $2036477234,8(%esp) + movl $1797285236,12(%esp) + movl 84(%esp),%ebx + movl 88(%esp),%ebp + movl 104(%esp),%ecx + movl 108(%esp),%esi + movl 116(%esp),%edx + movl 120(%esp),%edi + movl %ebx,20(%esp) + movl %ebp,24(%esp) + movl %ecx,40(%esp) + movl %esi,44(%esp) + movl %edx,52(%esp) + movl %edi,56(%esp) + movl 92(%esp),%ebx + movl 124(%esp),%edi + movl 112(%esp),%edx + movl 80(%esp),%ebp + movl 96(%esp),%ecx + movl 100(%esp),%esi + addl $1,%edx + movl %ebx,28(%esp) + movl %edi,60(%esp) + movl %edx,112(%esp) + movl $10,%ebx + jmp .L004loop +.align 16 +.L004loop: + addl %ebp,%eax + movl %ebx,128(%esp) + movl %ebp,%ebx + xorl %eax,%edx + roll $16,%edx + addl %edx,%ecx + xorl %ecx,%ebx + movl 52(%esp),%edi + roll $12,%ebx + movl 20(%esp),%ebp + addl %ebx,%eax + xorl %eax,%edx + movl %eax,(%esp) + roll $8,%edx + movl 4(%esp),%eax + addl %edx,%ecx + movl %edx,48(%esp) + xorl %ecx,%ebx + addl %ebp,%eax + roll $7,%ebx + xorl %eax,%edi + movl %ecx,32(%esp) + roll $16,%edi + movl %ebx,16(%esp) + addl %edi,%esi + movl 40(%esp),%ecx + xorl %esi,%ebp + movl 56(%esp),%edx + roll $12,%ebp + movl 24(%esp),%ebx + addl %ebp,%eax + xorl %eax,%edi + movl %eax,4(%esp) + roll $8,%edi + movl 8(%esp),%eax + addl %edi,%esi + movl %edi,52(%esp) + xorl %esi,%ebp + addl %ebx,%eax + roll $7,%ebp + xorl %eax,%edx + movl %esi,36(%esp) + roll $16,%edx + movl %ebp,20(%esp) + addl %edx,%ecx + movl 44(%esp),%esi + xorl %ecx,%ebx + movl 60(%esp),%edi + roll $12,%ebx + movl 28(%esp),%ebp + addl %ebx,%eax + xorl %eax,%edx + movl %eax,8(%esp) + roll $8,%edx + movl 12(%esp),%eax + addl %edx,%ecx + movl %edx,56(%esp) + xorl %ecx,%ebx + addl %ebp,%eax + roll $7,%ebx + xorl %eax,%edi + roll $16,%edi + movl %ebx,24(%esp) + addl %edi,%esi + xorl %esi,%ebp + roll $12,%ebp + movl 20(%esp),%ebx + addl %ebp,%eax + xorl %eax,%edi + movl %eax,12(%esp) + roll $8,%edi + movl (%esp),%eax + addl %edi,%esi + movl %edi,%edx + xorl %esi,%ebp + addl %ebx,%eax + roll $7,%ebp + xorl %eax,%edx + roll $16,%edx + movl %ebp,28(%esp) + addl %edx,%ecx + xorl %ecx,%ebx + movl 48(%esp),%edi + roll $12,%ebx + movl 24(%esp),%ebp + addl %ebx,%eax + xorl %eax,%edx + movl %eax,(%esp) + roll $8,%edx + movl 4(%esp),%eax + addl %edx,%ecx + movl %edx,60(%esp) + xorl %ecx,%ebx + addl %ebp,%eax + roll $7,%ebx + xorl %eax,%edi + movl %ecx,40(%esp) + roll $16,%edi + movl %ebx,20(%esp) + addl %edi,%esi + movl 32(%esp),%ecx + xorl %esi,%ebp + movl 52(%esp),%edx + roll $12,%ebp + movl 28(%esp),%ebx + addl %ebp,%eax + xorl %eax,%edi + movl %eax,4(%esp) + roll $8,%edi + movl 8(%esp),%eax + addl %edi,%esi + movl %edi,48(%esp) + xorl %esi,%ebp + addl %ebx,%eax + roll $7,%ebp + xorl %eax,%edx + movl %esi,44(%esp) + roll $16,%edx + movl %ebp,24(%esp) + addl %edx,%ecx + movl 36(%esp),%esi + xorl %ecx,%ebx + movl 56(%esp),%edi + roll $12,%ebx + movl 16(%esp),%ebp + addl %ebx,%eax + xorl %eax,%edx + movl %eax,8(%esp) + roll $8,%edx + movl 12(%esp),%eax + addl %edx,%ecx + movl %edx,52(%esp) + xorl %ecx,%ebx + addl %ebp,%eax + roll $7,%ebx + xorl %eax,%edi + roll $16,%edi + movl %ebx,28(%esp) + addl %edi,%esi + xorl %esi,%ebp + movl 48(%esp),%edx + roll $12,%ebp + movl 128(%esp),%ebx + addl %ebp,%eax + xorl %eax,%edi + movl %eax,12(%esp) + roll $8,%edi + movl (%esp),%eax + addl %edi,%esi + movl %edi,56(%esp) + xorl %esi,%ebp + roll $7,%ebp + decl %ebx + jnz .L004loop + movl 160(%esp),%ebx + addl $1634760805,%eax + addl 80(%esp),%ebp + addl 96(%esp),%ecx + addl 100(%esp),%esi + cmpl $64,%ebx + jb .L005tail + movl 156(%esp),%ebx + addl 112(%esp),%edx + addl 120(%esp),%edi + xorl (%ebx),%eax + xorl 16(%ebx),%ebp + movl %eax,(%esp) + movl 152(%esp),%eax + xorl 32(%ebx),%ecx + xorl 36(%ebx),%esi + xorl 48(%ebx),%edx + xorl 56(%ebx),%edi + movl %ebp,16(%eax) + movl %ecx,32(%eax) + movl %esi,36(%eax) + movl %edx,48(%eax) + movl %edi,56(%eax) + movl 4(%esp),%ebp + movl 8(%esp),%ecx + movl 12(%esp),%esi + movl 20(%esp),%edx + movl 24(%esp),%edi + addl $857760878,%ebp + addl $2036477234,%ecx + addl $1797285236,%esi + addl 84(%esp),%edx + addl 88(%esp),%edi + xorl 4(%ebx),%ebp + xorl 8(%ebx),%ecx + xorl 12(%ebx),%esi + xorl 20(%ebx),%edx + xorl 24(%ebx),%edi + movl %ebp,4(%eax) + movl %ecx,8(%eax) + movl %esi,12(%eax) + movl %edx,20(%eax) + movl %edi,24(%eax) + movl 28(%esp),%ebp + movl 40(%esp),%ecx + movl 44(%esp),%esi + movl 52(%esp),%edx + movl 60(%esp),%edi + addl 92(%esp),%ebp + addl 104(%esp),%ecx + addl 108(%esp),%esi + addl 116(%esp),%edx + addl 124(%esp),%edi + xorl 28(%ebx),%ebp + xorl 40(%ebx),%ecx + xorl 44(%ebx),%esi + xorl 52(%ebx),%edx + xorl 60(%ebx),%edi + leal 64(%ebx),%ebx + movl %ebp,28(%eax) + movl (%esp),%ebp + movl %ecx,40(%eax) + movl 160(%esp),%ecx + movl %esi,44(%eax) + movl %edx,52(%eax) + movl %edi,60(%eax) + movl %ebp,(%eax) + leal 64(%eax),%eax + subl $64,%ecx + jnz .L003outer_loop + jmp .L006done +.L005tail: + addl 112(%esp),%edx + addl 120(%esp),%edi + movl %eax,(%esp) + movl %ebp,16(%esp) + movl %ecx,32(%esp) + movl %esi,36(%esp) + movl %edx,48(%esp) + movl %edi,56(%esp) + movl 4(%esp),%ebp + movl 8(%esp),%ecx + movl 12(%esp),%esi + movl 20(%esp),%edx + movl 24(%esp),%edi + addl $857760878,%ebp + addl $2036477234,%ecx + addl $1797285236,%esi + addl 84(%esp),%edx + addl 88(%esp),%edi + movl %ebp,4(%esp) + movl %ecx,8(%esp) + movl %esi,12(%esp) + movl %edx,20(%esp) + movl %edi,24(%esp) + movl 28(%esp),%ebp + movl 40(%esp),%ecx + movl 44(%esp),%esi + movl 52(%esp),%edx + movl 60(%esp),%edi + addl 92(%esp),%ebp + addl 104(%esp),%ecx + addl 108(%esp),%esi + addl 116(%esp),%edx + addl 124(%esp),%edi + movl %ebp,28(%esp) + movl 156(%esp),%ebp + movl %ecx,40(%esp) + movl 152(%esp),%ecx + movl %esi,44(%esp) + xorl %esi,%esi + movl %edx,52(%esp) + movl %edi,60(%esp) + xorl %eax,%eax + xorl %edx,%edx +.L007tail_loop: + movb (%esi,%ebp,1),%al + movb (%esp,%esi,1),%dl + leal 1(%esi),%esi + xorb %dl,%al + movb %al,-1(%ecx,%esi,1) + decl %ebx + jnz .L007tail_loop +.L006done: + addl $132,%esp +.L000no_data: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ChaCha20_ctr32,.-.L_ChaCha20_ctr32_begin +.globl ChaCha20_ssse3 +.type ChaCha20_ssse3,@function +.align 16 +ChaCha20_ssse3: +.L_ChaCha20_ssse3_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi +.Lssse3_shortcut: + testl $2048,4(%ebp) + jnz .Lxop_shortcut + movl 20(%esp),%edi + movl 24(%esp),%esi + movl 28(%esp),%ecx + movl 32(%esp),%edx + movl 36(%esp),%ebx + movl %esp,%ebp + subl $524,%esp + andl $-64,%esp + movl %ebp,512(%esp) + leal .Lssse3_data-.Lpic_point(%eax),%eax + movdqu (%ebx),%xmm3 +.L0081x: + movdqa 32(%eax),%xmm0 + movdqu (%edx),%xmm1 + movdqu 16(%edx),%xmm2 + movdqa (%eax),%xmm6 + movdqa 16(%eax),%xmm7 + movl %ebp,48(%esp) + movdqa %xmm0,(%esp) + movdqa %xmm1,16(%esp) + movdqa %xmm2,32(%esp) + movdqa %xmm3,48(%esp) + movl $10,%edx + jmp .L009loop1x +.align 16 +.L010outer1x: + movdqa 80(%eax),%xmm3 + movdqa (%esp),%xmm0 + movdqa 16(%esp),%xmm1 + movdqa 32(%esp),%xmm2 + paddd 48(%esp),%xmm3 + movl $10,%edx + movdqa %xmm3,48(%esp) + jmp .L009loop1x +.align 16 +.L009loop1x: + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,222 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $20,%xmm1 + pslld $12,%xmm4 + por %xmm4,%xmm1 + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,223 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $25,%xmm1 + pslld $7,%xmm4 + por %xmm4,%xmm1 + pshufd $78,%xmm2,%xmm2 + pshufd $57,%xmm1,%xmm1 + pshufd $147,%xmm3,%xmm3 + nop + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,222 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $20,%xmm1 + pslld $12,%xmm4 + por %xmm4,%xmm1 + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,223 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $25,%xmm1 + pslld $7,%xmm4 + por %xmm4,%xmm1 + pshufd $78,%xmm2,%xmm2 + pshufd $147,%xmm1,%xmm1 + pshufd $57,%xmm3,%xmm3 + decl %edx + jnz .L009loop1x + paddd (%esp),%xmm0 + paddd 16(%esp),%xmm1 + paddd 32(%esp),%xmm2 + paddd 48(%esp),%xmm3 + cmpl $64,%ecx + jb .L011tail + movdqu (%esi),%xmm4 + movdqu 16(%esi),%xmm5 + pxor %xmm4,%xmm0 + movdqu 32(%esi),%xmm4 + pxor %xmm5,%xmm1 + movdqu 48(%esi),%xmm5 + pxor %xmm4,%xmm2 + pxor %xmm5,%xmm3 + leal 64(%esi),%esi + movdqu %xmm0,(%edi) + movdqu %xmm1,16(%edi) + movdqu %xmm2,32(%edi) + movdqu %xmm3,48(%edi) + leal 64(%edi),%edi + subl $64,%ecx + jnz .L010outer1x + jmp .L012done +.L011tail: + movdqa %xmm0,(%esp) + movdqa %xmm1,16(%esp) + movdqa %xmm2,32(%esp) + movdqa %xmm3,48(%esp) + xorl %eax,%eax + xorl %edx,%edx + xorl %ebp,%ebp +.L013tail_loop: + movb (%esp,%ebp,1),%al + movb (%esi,%ebp,1),%dl + leal 1(%ebp),%ebp + xorb %dl,%al + movb %al,-1(%edi,%ebp,1) + decl %ecx + jnz .L013tail_loop +.L012done: + movl 512(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ChaCha20_ssse3,.-.L_ChaCha20_ssse3_begin +.align 64 +.Lssse3_data: +.byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13 +.byte 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14 +.long 1634760805,857760878,2036477234,1797285236 +.long 0,1,2,3 +.long 4,4,4,4 +.long 1,0,0,0 +.long 4,0,0,0 +.long 0,-1,-1,-1 +.align 64 +.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54 +.byte 44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32 +.byte 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111 +.byte 114,103,62,0 +.globl ChaCha20_xop +.type ChaCha20_xop,@function +.align 16 +ChaCha20_xop: +.L_ChaCha20_xop_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi +.Lxop_shortcut: + movl 20(%esp),%edi + movl 24(%esp),%esi + movl 28(%esp),%ecx + movl 32(%esp),%edx + movl 36(%esp),%ebx + vzeroupper + movl %esp,%ebp + subl $524,%esp + andl $-64,%esp + movl %ebp,512(%esp) + leal .Lssse3_data-.Lpic_point(%eax),%eax + vmovdqu (%ebx),%xmm3 + cmpl $256,%ecx + jb .L0141x + movl %edx,516(%esp) + movl %ebx,520(%esp) + subl $256,%ecx + leal 384(%esp),%ebp + vmovdqu (%edx),%xmm7 + vpshufd $0,%xmm3,%xmm0 + vpshufd $85,%xmm3,%xmm1 + vpshufd $170,%xmm3,%xmm2 + vpshufd $255,%xmm3,%xmm3 + vpaddd 48(%eax),%xmm0,%xmm0 + vpshufd $0,%xmm7,%xmm4 + vpshufd $85,%xmm7,%xmm5 + vpsubd 64(%eax),%xmm0,%xmm0 + vpshufd $170,%xmm7,%xmm6 + vpshufd $255,%xmm7,%xmm7 + vmovdqa %xmm0,64(%ebp) + vmovdqa %xmm1,80(%ebp) + vmovdqa %xmm2,96(%ebp) + vmovdqa %xmm3,112(%ebp) + vmovdqu 16(%edx),%xmm3 + vmovdqa %xmm4,-64(%ebp) + vmovdqa %xmm5,-48(%ebp) + vmovdqa %xmm6,-32(%ebp) + vmovdqa %xmm7,-16(%ebp) + vmovdqa 32(%eax),%xmm7 + leal 128(%esp),%ebx + vpshufd $0,%xmm3,%xmm0 + vpshufd $85,%xmm3,%xmm1 + vpshufd $170,%xmm3,%xmm2 + vpshufd $255,%xmm3,%xmm3 + vpshufd $0,%xmm7,%xmm4 + vpshufd $85,%xmm7,%xmm5 + vpshufd $170,%xmm7,%xmm6 + vpshufd $255,%xmm7,%xmm7 + vmovdqa %xmm0,(%ebp) + vmovdqa %xmm1,16(%ebp) + vmovdqa %xmm2,32(%ebp) + vmovdqa %xmm3,48(%ebp) + vmovdqa %xmm4,-128(%ebp) + vmovdqa %xmm5,-112(%ebp) + vmovdqa %xmm6,-96(%ebp) + vmovdqa %xmm7,-80(%ebp) + leal 128(%esi),%esi + leal 128(%edi),%edi + jmp .L015outer_loop +.align 32 +.L015outer_loop: + vmovdqa -112(%ebp),%xmm1 + vmovdqa -96(%ebp),%xmm2 + vmovdqa -80(%ebp),%xmm3 + vmovdqa -48(%ebp),%xmm5 + vmovdqa -32(%ebp),%xmm6 + vmovdqa -16(%ebp),%xmm7 + vmovdqa %xmm1,-112(%ebx) + vmovdqa %xmm2,-96(%ebx) + vmovdqa %xmm3,-80(%ebx) + vmovdqa %xmm5,-48(%ebx) + vmovdqa %xmm6,-32(%ebx) + vmovdqa %xmm7,-16(%ebx) + vmovdqa 32(%ebp),%xmm2 + vmovdqa 48(%ebp),%xmm3 + vmovdqa 64(%ebp),%xmm4 + vmovdqa 80(%ebp),%xmm5 + vmovdqa 96(%ebp),%xmm6 + vmovdqa 112(%ebp),%xmm7 + vpaddd 64(%eax),%xmm4,%xmm4 + vmovdqa %xmm2,32(%ebx) + vmovdqa %xmm3,48(%ebx) + vmovdqa %xmm4,64(%ebx) + vmovdqa %xmm5,80(%ebx) + vmovdqa %xmm6,96(%ebx) + vmovdqa %xmm7,112(%ebx) + vmovdqa %xmm4,64(%ebp) + vmovdqa -128(%ebp),%xmm0 + vmovdqa %xmm4,%xmm6 + vmovdqa -64(%ebp),%xmm3 + vmovdqa (%ebp),%xmm4 + vmovdqa 16(%ebp),%xmm5 + movl $10,%edx + nop +.align 32 +.L016loop: + vpaddd %xmm3,%xmm0,%xmm0 + vpxor %xmm0,%xmm6,%xmm6 +.byte 143,232,120,194,246,16 + vpaddd %xmm6,%xmm4,%xmm4 + vpxor %xmm4,%xmm3,%xmm2 + vmovdqa -112(%ebx),%xmm1 +.byte 143,232,120,194,210,12 + vmovdqa -48(%ebx),%xmm3 + vpaddd %xmm2,%xmm0,%xmm0 + vmovdqa 80(%ebx),%xmm7 + vpxor %xmm0,%xmm6,%xmm6 + vpaddd %xmm3,%xmm1,%xmm1 +.byte 143,232,120,194,246,8 + vmovdqa %xmm0,-128(%ebx) + vpaddd %xmm6,%xmm4,%xmm4 + vmovdqa %xmm6,64(%ebx) + vpxor %xmm4,%xmm2,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 +.byte 143,232,120,194,210,7 + vmovdqa %xmm4,(%ebx) +.byte 143,232,120,194,255,16 + vmovdqa %xmm2,-64(%ebx) + vpaddd %xmm7,%xmm5,%xmm5 + vmovdqa 32(%ebx),%xmm4 + vpxor %xmm5,%xmm3,%xmm3 + vmovdqa -96(%ebx),%xmm0 +.byte 143,232,120,194,219,12 + vmovdqa -32(%ebx),%xmm2 + vpaddd %xmm3,%xmm1,%xmm1 + vmovdqa 96(%ebx),%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + vpaddd %xmm2,%xmm0,%xmm0 +.byte 143,232,120,194,255,8 + vmovdqa %xmm1,-112(%ebx) + vpaddd %xmm7,%xmm5,%xmm5 + vmovdqa %xmm7,80(%ebx) + vpxor %xmm5,%xmm3,%xmm3 + vpxor %xmm0,%xmm6,%xmm6 +.byte 143,232,120,194,219,7 + vmovdqa %xmm5,16(%ebx) +.byte 143,232,120,194,246,16 + vmovdqa %xmm3,-48(%ebx) + vpaddd %xmm6,%xmm4,%xmm4 + vmovdqa 48(%ebx),%xmm5 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa -80(%ebx),%xmm1 +.byte 143,232,120,194,210,12 + vmovdqa -16(%ebx),%xmm3 + vpaddd %xmm2,%xmm0,%xmm0 + vmovdqa 112(%ebx),%xmm7 + vpxor %xmm0,%xmm6,%xmm6 + vpaddd %xmm3,%xmm1,%xmm1 +.byte 143,232,120,194,246,8 + vmovdqa %xmm0,-96(%ebx) + vpaddd %xmm6,%xmm4,%xmm4 + vmovdqa %xmm6,96(%ebx) + vpxor %xmm4,%xmm2,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 +.byte 143,232,120,194,210,7 +.byte 143,232,120,194,255,16 + vmovdqa %xmm2,-32(%ebx) + vpaddd %xmm7,%xmm5,%xmm5 + vpxor %xmm5,%xmm3,%xmm3 + vmovdqa -128(%ebx),%xmm0 +.byte 143,232,120,194,219,12 + vmovdqa -48(%ebx),%xmm2 + vpaddd %xmm3,%xmm1,%xmm1 + vpxor %xmm1,%xmm7,%xmm7 + vpaddd %xmm2,%xmm0,%xmm0 +.byte 143,232,120,194,255,8 + vmovdqa %xmm1,-80(%ebx) + vpaddd %xmm7,%xmm5,%xmm5 + vpxor %xmm5,%xmm3,%xmm3 + vpxor %xmm0,%xmm7,%xmm6 +.byte 143,232,120,194,219,7 +.byte 143,232,120,194,246,16 + vmovdqa %xmm3,-16(%ebx) + vpaddd %xmm6,%xmm4,%xmm4 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa -112(%ebx),%xmm1 +.byte 143,232,120,194,210,12 + vmovdqa -32(%ebx),%xmm3 + vpaddd %xmm2,%xmm0,%xmm0 + vmovdqa 64(%ebx),%xmm7 + vpxor %xmm0,%xmm6,%xmm6 + vpaddd %xmm3,%xmm1,%xmm1 +.byte 143,232,120,194,246,8 + vmovdqa %xmm0,-128(%ebx) + vpaddd %xmm6,%xmm4,%xmm4 + vmovdqa %xmm6,112(%ebx) + vpxor %xmm4,%xmm2,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 +.byte 143,232,120,194,210,7 + vmovdqa %xmm4,32(%ebx) +.byte 143,232,120,194,255,16 + vmovdqa %xmm2,-48(%ebx) + vpaddd %xmm7,%xmm5,%xmm5 + vmovdqa (%ebx),%xmm4 + vpxor %xmm5,%xmm3,%xmm3 + vmovdqa -96(%ebx),%xmm0 +.byte 143,232,120,194,219,12 + vmovdqa -16(%ebx),%xmm2 + vpaddd %xmm3,%xmm1,%xmm1 + vmovdqa 80(%ebx),%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + vpaddd %xmm2,%xmm0,%xmm0 +.byte 143,232,120,194,255,8 + vmovdqa %xmm1,-112(%ebx) + vpaddd %xmm7,%xmm5,%xmm5 + vmovdqa %xmm7,64(%ebx) + vpxor %xmm5,%xmm3,%xmm3 + vpxor %xmm0,%xmm6,%xmm6 +.byte 143,232,120,194,219,7 + vmovdqa %xmm5,48(%ebx) +.byte 143,232,120,194,246,16 + vmovdqa %xmm3,-32(%ebx) + vpaddd %xmm6,%xmm4,%xmm4 + vmovdqa 16(%ebx),%xmm5 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa -80(%ebx),%xmm1 +.byte 143,232,120,194,210,12 + vmovdqa -64(%ebx),%xmm3 + vpaddd %xmm2,%xmm0,%xmm0 + vmovdqa 96(%ebx),%xmm7 + vpxor %xmm0,%xmm6,%xmm6 + vpaddd %xmm3,%xmm1,%xmm1 +.byte 143,232,120,194,246,8 + vmovdqa %xmm0,-96(%ebx) + vpaddd %xmm6,%xmm4,%xmm4 + vmovdqa %xmm6,80(%ebx) + vpxor %xmm4,%xmm2,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 +.byte 143,232,120,194,210,7 +.byte 143,232,120,194,255,16 + vmovdqa %xmm2,-16(%ebx) + vpaddd %xmm7,%xmm5,%xmm5 + vpxor %xmm5,%xmm3,%xmm3 + vmovdqa -128(%ebx),%xmm0 +.byte 143,232,120,194,219,12 + vpaddd %xmm3,%xmm1,%xmm1 + vmovdqa 64(%ebx),%xmm6 + vpxor %xmm1,%xmm7,%xmm7 +.byte 143,232,120,194,255,8 + vmovdqa %xmm1,-80(%ebx) + vpaddd %xmm7,%xmm5,%xmm5 + vmovdqa %xmm7,96(%ebx) + vpxor %xmm5,%xmm3,%xmm3 +.byte 143,232,120,194,219,7 + decl %edx + jnz .L016loop + vmovdqa %xmm3,-64(%ebx) + vmovdqa %xmm4,(%ebx) + vmovdqa %xmm5,16(%ebx) + vmovdqa %xmm6,64(%ebx) + vmovdqa %xmm7,96(%ebx) + vmovdqa -112(%ebx),%xmm1 + vmovdqa -96(%ebx),%xmm2 + vmovdqa -80(%ebx),%xmm3 + vpaddd -128(%ebp),%xmm0,%xmm0 + vpaddd -112(%ebp),%xmm1,%xmm1 + vpaddd -96(%ebp),%xmm2,%xmm2 + vpaddd -80(%ebp),%xmm3,%xmm3 + vpunpckldq %xmm1,%xmm0,%xmm6 + vpunpckldq %xmm3,%xmm2,%xmm7 + vpunpckhdq %xmm1,%xmm0,%xmm0 + vpunpckhdq %xmm3,%xmm2,%xmm2 + vpunpcklqdq %xmm7,%xmm6,%xmm1 + vpunpckhqdq %xmm7,%xmm6,%xmm6 + vpunpcklqdq %xmm2,%xmm0,%xmm7 + vpunpckhqdq %xmm2,%xmm0,%xmm3 + vpxor -128(%esi),%xmm1,%xmm4 + vpxor -64(%esi),%xmm6,%xmm5 + vpxor (%esi),%xmm7,%xmm6 + vpxor 64(%esi),%xmm3,%xmm7 + leal 16(%esi),%esi + vmovdqa -64(%ebx),%xmm0 + vmovdqa -48(%ebx),%xmm1 + vmovdqa -32(%ebx),%xmm2 + vmovdqa -16(%ebx),%xmm3 + vmovdqu %xmm4,-128(%edi) + vmovdqu %xmm5,-64(%edi) + vmovdqu %xmm6,(%edi) + vmovdqu %xmm7,64(%edi) + leal 16(%edi),%edi + vpaddd -64(%ebp),%xmm0,%xmm0 + vpaddd -48(%ebp),%xmm1,%xmm1 + vpaddd -32(%ebp),%xmm2,%xmm2 + vpaddd -16(%ebp),%xmm3,%xmm3 + vpunpckldq %xmm1,%xmm0,%xmm6 + vpunpckldq %xmm3,%xmm2,%xmm7 + vpunpckhdq %xmm1,%xmm0,%xmm0 + vpunpckhdq %xmm3,%xmm2,%xmm2 + vpunpcklqdq %xmm7,%xmm6,%xmm1 + vpunpckhqdq %xmm7,%xmm6,%xmm6 + vpunpcklqdq %xmm2,%xmm0,%xmm7 + vpunpckhqdq %xmm2,%xmm0,%xmm3 + vpxor -128(%esi),%xmm1,%xmm4 + vpxor -64(%esi),%xmm6,%xmm5 + vpxor (%esi),%xmm7,%xmm6 + vpxor 64(%esi),%xmm3,%xmm7 + leal 16(%esi),%esi + vmovdqa (%ebx),%xmm0 + vmovdqa 16(%ebx),%xmm1 + vmovdqa 32(%ebx),%xmm2 + vmovdqa 48(%ebx),%xmm3 + vmovdqu %xmm4,-128(%edi) + vmovdqu %xmm5,-64(%edi) + vmovdqu %xmm6,(%edi) + vmovdqu %xmm7,64(%edi) + leal 16(%edi),%edi + vpaddd (%ebp),%xmm0,%xmm0 + vpaddd 16(%ebp),%xmm1,%xmm1 + vpaddd 32(%ebp),%xmm2,%xmm2 + vpaddd 48(%ebp),%xmm3,%xmm3 + vpunpckldq %xmm1,%xmm0,%xmm6 + vpunpckldq %xmm3,%xmm2,%xmm7 + vpunpckhdq %xmm1,%xmm0,%xmm0 + vpunpckhdq %xmm3,%xmm2,%xmm2 + vpunpcklqdq %xmm7,%xmm6,%xmm1 + vpunpckhqdq %xmm7,%xmm6,%xmm6 + vpunpcklqdq %xmm2,%xmm0,%xmm7 + vpunpckhqdq %xmm2,%xmm0,%xmm3 + vpxor -128(%esi),%xmm1,%xmm4 + vpxor -64(%esi),%xmm6,%xmm5 + vpxor (%esi),%xmm7,%xmm6 + vpxor 64(%esi),%xmm3,%xmm7 + leal 16(%esi),%esi + vmovdqa 64(%ebx),%xmm0 + vmovdqa 80(%ebx),%xmm1 + vmovdqa 96(%ebx),%xmm2 + vmovdqa 112(%ebx),%xmm3 + vmovdqu %xmm4,-128(%edi) + vmovdqu %xmm5,-64(%edi) + vmovdqu %xmm6,(%edi) + vmovdqu %xmm7,64(%edi) + leal 16(%edi),%edi + vpaddd 64(%ebp),%xmm0,%xmm0 + vpaddd 80(%ebp),%xmm1,%xmm1 + vpaddd 96(%ebp),%xmm2,%xmm2 + vpaddd 112(%ebp),%xmm3,%xmm3 + vpunpckldq %xmm1,%xmm0,%xmm6 + vpunpckldq %xmm3,%xmm2,%xmm7 + vpunpckhdq %xmm1,%xmm0,%xmm0 + vpunpckhdq %xmm3,%xmm2,%xmm2 + vpunpcklqdq %xmm7,%xmm6,%xmm1 + vpunpckhqdq %xmm7,%xmm6,%xmm6 + vpunpcklqdq %xmm2,%xmm0,%xmm7 + vpunpckhqdq %xmm2,%xmm0,%xmm3 + vpxor -128(%esi),%xmm1,%xmm4 + vpxor -64(%esi),%xmm6,%xmm5 + vpxor (%esi),%xmm7,%xmm6 + vpxor 64(%esi),%xmm3,%xmm7 + leal 208(%esi),%esi + vmovdqu %xmm4,-128(%edi) + vmovdqu %xmm5,-64(%edi) + vmovdqu %xmm6,(%edi) + vmovdqu %xmm7,64(%edi) + leal 208(%edi),%edi + subl $256,%ecx + jnc .L015outer_loop + addl $256,%ecx + jz .L017done + movl 520(%esp),%ebx + leal -128(%esi),%esi + movl 516(%esp),%edx + leal -128(%edi),%edi + vmovd 64(%ebp),%xmm2 + vmovdqu (%ebx),%xmm3 + vpaddd 96(%eax),%xmm2,%xmm2 + vpand 112(%eax),%xmm3,%xmm3 + vpor %xmm2,%xmm3,%xmm3 +.L0141x: + vmovdqa 32(%eax),%xmm0 + vmovdqu (%edx),%xmm1 + vmovdqu 16(%edx),%xmm2 + vmovdqa (%eax),%xmm6 + vmovdqa 16(%eax),%xmm7 + movl %ebp,48(%esp) + vmovdqa %xmm0,(%esp) + vmovdqa %xmm1,16(%esp) + vmovdqa %xmm2,32(%esp) + vmovdqa %xmm3,48(%esp) + movl $10,%edx + jmp .L018loop1x +.align 16 +.L019outer1x: + vmovdqa 80(%eax),%xmm3 + vmovdqa (%esp),%xmm0 + vmovdqa 16(%esp),%xmm1 + vmovdqa 32(%esp),%xmm2 + vpaddd 48(%esp),%xmm3,%xmm3 + movl $10,%edx + vmovdqa %xmm3,48(%esp) + jmp .L018loop1x +.align 16 +.L018loop1x: + vpaddd %xmm1,%xmm0,%xmm0 + vpxor %xmm0,%xmm3,%xmm3 +.byte 143,232,120,194,219,16 + vpaddd %xmm3,%xmm2,%xmm2 + vpxor %xmm2,%xmm1,%xmm1 +.byte 143,232,120,194,201,12 + vpaddd %xmm1,%xmm0,%xmm0 + vpxor %xmm0,%xmm3,%xmm3 +.byte 143,232,120,194,219,8 + vpaddd %xmm3,%xmm2,%xmm2 + vpxor %xmm2,%xmm1,%xmm1 +.byte 143,232,120,194,201,7 + vpshufd $78,%xmm2,%xmm2 + vpshufd $57,%xmm1,%xmm1 + vpshufd $147,%xmm3,%xmm3 + vpaddd %xmm1,%xmm0,%xmm0 + vpxor %xmm0,%xmm3,%xmm3 +.byte 143,232,120,194,219,16 + vpaddd %xmm3,%xmm2,%xmm2 + vpxor %xmm2,%xmm1,%xmm1 +.byte 143,232,120,194,201,12 + vpaddd %xmm1,%xmm0,%xmm0 + vpxor %xmm0,%xmm3,%xmm3 +.byte 143,232,120,194,219,8 + vpaddd %xmm3,%xmm2,%xmm2 + vpxor %xmm2,%xmm1,%xmm1 +.byte 143,232,120,194,201,7 + vpshufd $78,%xmm2,%xmm2 + vpshufd $147,%xmm1,%xmm1 + vpshufd $57,%xmm3,%xmm3 + decl %edx + jnz .L018loop1x + vpaddd (%esp),%xmm0,%xmm0 + vpaddd 16(%esp),%xmm1,%xmm1 + vpaddd 32(%esp),%xmm2,%xmm2 + vpaddd 48(%esp),%xmm3,%xmm3 + cmpl $64,%ecx + jb .L020tail + vpxor (%esi),%xmm0,%xmm0 + vpxor 16(%esi),%xmm1,%xmm1 + vpxor 32(%esi),%xmm2,%xmm2 + vpxor 48(%esi),%xmm3,%xmm3 + leal 64(%esi),%esi + vmovdqu %xmm0,(%edi) + vmovdqu %xmm1,16(%edi) + vmovdqu %xmm2,32(%edi) + vmovdqu %xmm3,48(%edi) + leal 64(%edi),%edi + subl $64,%ecx + jnz .L019outer1x + jmp .L017done +.L020tail: + vmovdqa %xmm0,(%esp) + vmovdqa %xmm1,16(%esp) + vmovdqa %xmm2,32(%esp) + vmovdqa %xmm3,48(%esp) + xorl %eax,%eax + xorl %edx,%edx + xorl %ebp,%ebp +.L021tail_loop: + movb (%esp,%ebp,1),%al + movb (%esi,%ebp,1),%dl + leal 1(%ebp),%ebp + xorb %dl,%al + movb %al,-1(%edi,%ebp,1) + decl %ecx + jnz .L021tail_loop +.L017done: + vzeroupper + movl 512(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ChaCha20_xop,.-.L_ChaCha20_xop_begin +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/chacha/chacha-x86_64.S b/crypto/openssl/crypto/chacha/chacha-x86_64.S new file mode 100644 index 000000000000..ec5251a82f42 --- /dev/null +++ b/crypto/openssl/crypto/chacha/chacha-x86_64.S @@ -0,0 +1,2214 @@ +.text + + + +.align 64 +.Lzero: +.long 0,0,0,0 +.Lone: +.long 1,0,0,0 +.Linc: +.long 0,1,2,3 +.Lfour: +.long 4,4,4,4 +.Lincy: +.long 0,2,4,6,1,3,5,7 +.Leight: +.long 8,8,8,8,8,8,8,8 +.Lrot16: +.byte 0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd +.Lrot24: +.byte 0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe +.Ltwoy: +.long 2,0,0,0, 2,0,0,0 +.align 64 +.Lzeroz: +.long 0,0,0,0, 1,0,0,0, 2,0,0,0, 3,0,0,0 +.Lfourz: +.long 4,0,0,0, 4,0,0,0, 4,0,0,0, 4,0,0,0 +.Lincz: +.long 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +.Lsixteen: +.long 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 +.Lsigma: +.byte 101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107,0 +.byte 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.globl ChaCha20_ctr32 +.type ChaCha20_ctr32,@function +.align 64 +ChaCha20_ctr32: +.cfi_startproc + cmpq $0,%rdx + je .Lno_data + movq OPENSSL_ia32cap_P+4(%rip),%r10 + testl $512,%r10d + jnz .LChaCha20_ssse3 + + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $64+24,%rsp +.cfi_adjust_cfa_offset 64+24 +.Lctr32_body: + + + movdqu (%rcx),%xmm1 + movdqu 16(%rcx),%xmm2 + movdqu (%r8),%xmm3 + movdqa .Lone(%rip),%xmm4 + + + movdqa %xmm1,16(%rsp) + movdqa %xmm2,32(%rsp) + movdqa %xmm3,48(%rsp) + movq %rdx,%rbp + jmp .Loop_outer + +.align 32 +.Loop_outer: + movl $0x61707865,%eax + movl $0x3320646e,%ebx + movl $0x79622d32,%ecx + movl $0x6b206574,%edx + movl 16(%rsp),%r8d + movl 20(%rsp),%r9d + movl 24(%rsp),%r10d + movl 28(%rsp),%r11d + movd %xmm3,%r12d + movl 52(%rsp),%r13d + movl 56(%rsp),%r14d + movl 60(%rsp),%r15d + + movq %rbp,64+0(%rsp) + movl $10,%ebp + movq %rsi,64+8(%rsp) +.byte 102,72,15,126,214 + movq %rdi,64+16(%rsp) + movq %rsi,%rdi + shrq $32,%rdi + jmp .Loop + +.align 32 +.Loop: + addl %r8d,%eax + xorl %eax,%r12d + roll $16,%r12d + addl %r9d,%ebx + xorl %ebx,%r13d + roll $16,%r13d + addl %r12d,%esi + xorl %esi,%r8d + roll $12,%r8d + addl %r13d,%edi + xorl %edi,%r9d + roll $12,%r9d + addl %r8d,%eax + xorl %eax,%r12d + roll $8,%r12d + addl %r9d,%ebx + xorl %ebx,%r13d + roll $8,%r13d + addl %r12d,%esi + xorl %esi,%r8d + roll $7,%r8d + addl %r13d,%edi + xorl %edi,%r9d + roll $7,%r9d + movl %esi,32(%rsp) + movl %edi,36(%rsp) + movl 40(%rsp),%esi + movl 44(%rsp),%edi + addl %r10d,%ecx + xorl %ecx,%r14d + roll $16,%r14d + addl %r11d,%edx + xorl %edx,%r15d + roll $16,%r15d + addl %r14d,%esi + xorl %esi,%r10d + roll $12,%r10d + addl %r15d,%edi + xorl %edi,%r11d + roll $12,%r11d + addl %r10d,%ecx + xorl %ecx,%r14d + roll $8,%r14d + addl %r11d,%edx + xorl %edx,%r15d + roll $8,%r15d + addl %r14d,%esi + xorl %esi,%r10d + roll $7,%r10d + addl %r15d,%edi + xorl %edi,%r11d + roll $7,%r11d + addl %r9d,%eax + xorl %eax,%r15d + roll $16,%r15d + addl %r10d,%ebx + xorl %ebx,%r12d + roll $16,%r12d + addl %r15d,%esi + xorl %esi,%r9d + roll $12,%r9d + addl %r12d,%edi + xorl %edi,%r10d + roll $12,%r10d + addl %r9d,%eax + xorl %eax,%r15d + roll $8,%r15d + addl %r10d,%ebx + xorl %ebx,%r12d + roll $8,%r12d + addl %r15d,%esi + xorl %esi,%r9d + roll $7,%r9d + addl %r12d,%edi + xorl %edi,%r10d + roll $7,%r10d + movl %esi,40(%rsp) + movl %edi,44(%rsp) + movl 32(%rsp),%esi + movl 36(%rsp),%edi + addl %r11d,%ecx + xorl %ecx,%r13d + roll $16,%r13d + addl %r8d,%edx + xorl %edx,%r14d + roll $16,%r14d + addl %r13d,%esi + xorl %esi,%r11d + roll $12,%r11d + addl %r14d,%edi + xorl %edi,%r8d + roll $12,%r8d + addl %r11d,%ecx + xorl %ecx,%r13d + roll $8,%r13d + addl %r8d,%edx + xorl %edx,%r14d + roll $8,%r14d + addl %r13d,%esi + xorl %esi,%r11d + roll $7,%r11d + addl %r14d,%edi + xorl %edi,%r8d + roll $7,%r8d + decl %ebp + jnz .Loop + movl %edi,36(%rsp) + movl %esi,32(%rsp) + movq 64(%rsp),%rbp + movdqa %xmm2,%xmm1 + movq 64+8(%rsp),%rsi + paddd %xmm4,%xmm3 + movq 64+16(%rsp),%rdi + + addl $0x61707865,%eax + addl $0x3320646e,%ebx + addl $0x79622d32,%ecx + addl $0x6b206574,%edx + addl 16(%rsp),%r8d + addl 20(%rsp),%r9d + addl 24(%rsp),%r10d + addl 28(%rsp),%r11d + addl 48(%rsp),%r12d + addl 52(%rsp),%r13d + addl 56(%rsp),%r14d + addl 60(%rsp),%r15d + paddd 32(%rsp),%xmm1 + + cmpq $64,%rbp + jb .Ltail + + xorl 0(%rsi),%eax + xorl 4(%rsi),%ebx + xorl 8(%rsi),%ecx + xorl 12(%rsi),%edx + xorl 16(%rsi),%r8d + xorl 20(%rsi),%r9d + xorl 24(%rsi),%r10d + xorl 28(%rsi),%r11d + movdqu 32(%rsi),%xmm0 + xorl 48(%rsi),%r12d + xorl 52(%rsi),%r13d + xorl 56(%rsi),%r14d + xorl 60(%rsi),%r15d + leaq 64(%rsi),%rsi + pxor %xmm1,%xmm0 + + movdqa %xmm2,32(%rsp) + movd %xmm3,48(%rsp) + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + movdqu %xmm0,32(%rdi) + movl %r12d,48(%rdi) + movl %r13d,52(%rdi) + movl %r14d,56(%rdi) + movl %r15d,60(%rdi) + leaq 64(%rdi),%rdi + + subq $64,%rbp + jnz .Loop_outer + + jmp .Ldone + +.align 16 +.Ltail: + movl %eax,0(%rsp) + movl %ebx,4(%rsp) + xorq %rbx,%rbx + movl %ecx,8(%rsp) + movl %edx,12(%rsp) + movl %r8d,16(%rsp) + movl %r9d,20(%rsp) + movl %r10d,24(%rsp) + movl %r11d,28(%rsp) + movdqa %xmm1,32(%rsp) + movl %r12d,48(%rsp) + movl %r13d,52(%rsp) + movl %r14d,56(%rsp) + movl %r15d,60(%rsp) + +.Loop_tail: + movzbl (%rsi,%rbx,1),%eax + movzbl (%rsp,%rbx,1),%edx + leaq 1(%rbx),%rbx + xorl %edx,%eax + movb %al,-1(%rdi,%rbx,1) + decq %rbp + jnz .Loop_tail + +.Ldone: + leaq 64+24+48(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lno_data: + .byte 0xf3,0xc3 +.cfi_endproc +.size ChaCha20_ctr32,.-ChaCha20_ctr32 +.type ChaCha20_ssse3,@function +.align 32 +ChaCha20_ssse3: +.cfi_startproc +.LChaCha20_ssse3: + movq %rsp,%r9 +.cfi_def_cfa_register %r9 + testl $2048,%r10d + jnz .LChaCha20_4xop + cmpq $128,%rdx + je .LChaCha20_128 + ja .LChaCha20_4x + +.Ldo_sse3_after_all: + subq $64+8,%rsp + movdqa .Lsigma(%rip),%xmm0 + movdqu (%rcx),%xmm1 + movdqu 16(%rcx),%xmm2 + movdqu (%r8),%xmm3 + movdqa .Lrot16(%rip),%xmm6 + movdqa .Lrot24(%rip),%xmm7 + + movdqa %xmm0,0(%rsp) + movdqa %xmm1,16(%rsp) + movdqa %xmm2,32(%rsp) + movdqa %xmm3,48(%rsp) + movq $10,%r8 + jmp .Loop_ssse3 + +.align 32 +.Loop_outer_ssse3: + movdqa .Lone(%rip),%xmm3 + movdqa 0(%rsp),%xmm0 + movdqa 16(%rsp),%xmm1 + movdqa 32(%rsp),%xmm2 + paddd 48(%rsp),%xmm3 + movq $10,%r8 + movdqa %xmm3,48(%rsp) + jmp .Loop_ssse3 + +.align 32 +.Loop_ssse3: + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,222 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $20,%xmm1 + pslld $12,%xmm4 + por %xmm4,%xmm1 + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,223 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $25,%xmm1 + pslld $7,%xmm4 + por %xmm4,%xmm1 + pshufd $78,%xmm2,%xmm2 + pshufd $57,%xmm1,%xmm1 + pshufd $147,%xmm3,%xmm3 + nop + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,222 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $20,%xmm1 + pslld $12,%xmm4 + por %xmm4,%xmm1 + paddd %xmm1,%xmm0 + pxor %xmm0,%xmm3 +.byte 102,15,56,0,223 + paddd %xmm3,%xmm2 + pxor %xmm2,%xmm1 + movdqa %xmm1,%xmm4 + psrld $25,%xmm1 + pslld $7,%xmm4 + por %xmm4,%xmm1 + pshufd $78,%xmm2,%xmm2 + pshufd $147,%xmm1,%xmm1 + pshufd $57,%xmm3,%xmm3 + decq %r8 + jnz .Loop_ssse3 + paddd 0(%rsp),%xmm0 + paddd 16(%rsp),%xmm1 + paddd 32(%rsp),%xmm2 + paddd 48(%rsp),%xmm3 + + cmpq $64,%rdx + jb .Ltail_ssse3 + + movdqu 0(%rsi),%xmm4 + movdqu 16(%rsi),%xmm5 + pxor %xmm4,%xmm0 + movdqu 32(%rsi),%xmm4 + pxor %xmm5,%xmm1 + movdqu 48(%rsi),%xmm5 + leaq 64(%rsi),%rsi + pxor %xmm4,%xmm2 + pxor %xmm5,%xmm3 + + movdqu %xmm0,0(%rdi) + movdqu %xmm1,16(%rdi) + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + leaq 64(%rdi),%rdi + + subq $64,%rdx + jnz .Loop_outer_ssse3 + + jmp .Ldone_ssse3 + +.align 16 +.Ltail_ssse3: + movdqa %xmm0,0(%rsp) + movdqa %xmm1,16(%rsp) + movdqa %xmm2,32(%rsp) + movdqa %xmm3,48(%rsp) + xorq %r8,%r8 + +.Loop_tail_ssse3: + movzbl (%rsi,%r8,1),%eax + movzbl (%rsp,%r8,1),%ecx + leaq 1(%r8),%r8 + xorl %ecx,%eax + movb %al,-1(%rdi,%r8,1) + decq %rdx + jnz .Loop_tail_ssse3 + +.Ldone_ssse3: + leaq (%r9),%rsp +.cfi_def_cfa_register %rsp +.Lssse3_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ChaCha20_ssse3,.-ChaCha20_ssse3 +.type ChaCha20_128,@function +.align 32 +ChaCha20_128: +.cfi_startproc +.LChaCha20_128: + movq %rsp,%r9 +.cfi_def_cfa_register %r9 + subq $64+8,%rsp + movdqa .Lsigma(%rip),%xmm8 + movdqu (%rcx),%xmm9 + movdqu 16(%rcx),%xmm2 + movdqu (%r8),%xmm3 + movdqa .Lone(%rip),%xmm1 + movdqa .Lrot16(%rip),%xmm6 + movdqa .Lrot24(%rip),%xmm7 + + movdqa %xmm8,%xmm10 + movdqa %xmm8,0(%rsp) + movdqa %xmm9,%xmm11 + movdqa %xmm9,16(%rsp) + movdqa %xmm2,%xmm0 + movdqa %xmm2,32(%rsp) + paddd %xmm3,%xmm1 + movdqa %xmm3,48(%rsp) + movq $10,%r8 + jmp .Loop_128 + +.align 32 +.Loop_128: + paddd %xmm9,%xmm8 + pxor %xmm8,%xmm3 + paddd %xmm11,%xmm10 + pxor %xmm10,%xmm1 +.byte 102,15,56,0,222 +.byte 102,15,56,0,206 + paddd %xmm3,%xmm2 + paddd %xmm1,%xmm0 + pxor %xmm2,%xmm9 + pxor %xmm0,%xmm11 + movdqa %xmm9,%xmm4 + psrld $20,%xmm9 + movdqa %xmm11,%xmm5 + pslld $12,%xmm4 + psrld $20,%xmm11 + por %xmm4,%xmm9 + pslld $12,%xmm5 + por %xmm5,%xmm11 + paddd %xmm9,%xmm8 + pxor %xmm8,%xmm3 + paddd %xmm11,%xmm10 + pxor %xmm10,%xmm1 +.byte 102,15,56,0,223 +.byte 102,15,56,0,207 + paddd %xmm3,%xmm2 + paddd %xmm1,%xmm0 + pxor %xmm2,%xmm9 + pxor %xmm0,%xmm11 + movdqa %xmm9,%xmm4 + psrld $25,%xmm9 + movdqa %xmm11,%xmm5 + pslld $7,%xmm4 + psrld $25,%xmm11 + por %xmm4,%xmm9 + pslld $7,%xmm5 + por %xmm5,%xmm11 + pshufd $78,%xmm2,%xmm2 + pshufd $57,%xmm9,%xmm9 + pshufd $147,%xmm3,%xmm3 + pshufd $78,%xmm0,%xmm0 + pshufd $57,%xmm11,%xmm11 + pshufd $147,%xmm1,%xmm1 + paddd %xmm9,%xmm8 + pxor %xmm8,%xmm3 + paddd %xmm11,%xmm10 + pxor %xmm10,%xmm1 +.byte 102,15,56,0,222 +.byte 102,15,56,0,206 + paddd %xmm3,%xmm2 + paddd %xmm1,%xmm0 + pxor %xmm2,%xmm9 + pxor %xmm0,%xmm11 + movdqa %xmm9,%xmm4 + psrld $20,%xmm9 + movdqa %xmm11,%xmm5 + pslld $12,%xmm4 + psrld $20,%xmm11 + por %xmm4,%xmm9 + pslld $12,%xmm5 + por %xmm5,%xmm11 + paddd %xmm9,%xmm8 + pxor %xmm8,%xmm3 + paddd %xmm11,%xmm10 + pxor %xmm10,%xmm1 +.byte 102,15,56,0,223 +.byte 102,15,56,0,207 + paddd %xmm3,%xmm2 + paddd %xmm1,%xmm0 + pxor %xmm2,%xmm9 + pxor %xmm0,%xmm11 + movdqa %xmm9,%xmm4 + psrld $25,%xmm9 + movdqa %xmm11,%xmm5 + pslld $7,%xmm4 + psrld $25,%xmm11 + por %xmm4,%xmm9 + pslld $7,%xmm5 + por %xmm5,%xmm11 + pshufd $78,%xmm2,%xmm2 + pshufd $147,%xmm9,%xmm9 + pshufd $57,%xmm3,%xmm3 + pshufd $78,%xmm0,%xmm0 + pshufd $147,%xmm11,%xmm11 + pshufd $57,%xmm1,%xmm1 + decq %r8 + jnz .Loop_128 + paddd 0(%rsp),%xmm8 + paddd 16(%rsp),%xmm9 + paddd 32(%rsp),%xmm2 + paddd 48(%rsp),%xmm3 + paddd .Lone(%rip),%xmm1 + paddd 0(%rsp),%xmm10 + paddd 16(%rsp),%xmm11 + paddd 32(%rsp),%xmm0 + paddd 48(%rsp),%xmm1 + + movdqu 0(%rsi),%xmm4 + movdqu 16(%rsi),%xmm5 + pxor %xmm4,%xmm8 + movdqu 32(%rsi),%xmm4 + pxor %xmm5,%xmm9 + movdqu 48(%rsi),%xmm5 + pxor %xmm4,%xmm2 + movdqu 64(%rsi),%xmm4 + pxor %xmm5,%xmm3 + movdqu 80(%rsi),%xmm5 + pxor %xmm4,%xmm10 + movdqu 96(%rsi),%xmm4 + pxor %xmm5,%xmm11 + movdqu 112(%rsi),%xmm5 + pxor %xmm4,%xmm0 + pxor %xmm5,%xmm1 + + movdqu %xmm8,0(%rdi) + movdqu %xmm9,16(%rdi) + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + movdqu %xmm10,64(%rdi) + movdqu %xmm11,80(%rdi) + movdqu %xmm0,96(%rdi) + movdqu %xmm1,112(%rdi) + leaq (%r9),%rsp +.cfi_def_cfa_register %rsp +.L128_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ChaCha20_128,.-ChaCha20_128 +.type ChaCha20_4x,@function +.align 32 +ChaCha20_4x: +.cfi_startproc +.LChaCha20_4x: + movq %rsp,%r9 +.cfi_def_cfa_register %r9 + movq %r10,%r11 + shrq $32,%r10 + testq $32,%r10 + jnz .LChaCha20_8x + cmpq $192,%rdx + ja .Lproceed4x + + andq $71303168,%r11 + cmpq $4194304,%r11 + je .Ldo_sse3_after_all + +.Lproceed4x: + subq $0x140+8,%rsp + movdqa .Lsigma(%rip),%xmm11 + movdqu (%rcx),%xmm15 + movdqu 16(%rcx),%xmm7 + movdqu (%r8),%xmm3 + leaq 256(%rsp),%rcx + leaq .Lrot16(%rip),%r10 + leaq .Lrot24(%rip),%r11 + + pshufd $0x00,%xmm11,%xmm8 + pshufd $0x55,%xmm11,%xmm9 + movdqa %xmm8,64(%rsp) + pshufd $0xaa,%xmm11,%xmm10 + movdqa %xmm9,80(%rsp) + pshufd $0xff,%xmm11,%xmm11 + movdqa %xmm10,96(%rsp) + movdqa %xmm11,112(%rsp) + + pshufd $0x00,%xmm15,%xmm12 + pshufd $0x55,%xmm15,%xmm13 + movdqa %xmm12,128-256(%rcx) + pshufd $0xaa,%xmm15,%xmm14 + movdqa %xmm13,144-256(%rcx) + pshufd $0xff,%xmm15,%xmm15 + movdqa %xmm14,160-256(%rcx) + movdqa %xmm15,176-256(%rcx) + + pshufd $0x00,%xmm7,%xmm4 + pshufd $0x55,%xmm7,%xmm5 + movdqa %xmm4,192-256(%rcx) + pshufd $0xaa,%xmm7,%xmm6 + movdqa %xmm5,208-256(%rcx) + pshufd $0xff,%xmm7,%xmm7 + movdqa %xmm6,224-256(%rcx) + movdqa %xmm7,240-256(%rcx) + + pshufd $0x00,%xmm3,%xmm0 + pshufd $0x55,%xmm3,%xmm1 + paddd .Linc(%rip),%xmm0 + pshufd $0xaa,%xmm3,%xmm2 + movdqa %xmm1,272-256(%rcx) + pshufd $0xff,%xmm3,%xmm3 + movdqa %xmm2,288-256(%rcx) + movdqa %xmm3,304-256(%rcx) + + jmp .Loop_enter4x + +.align 32 +.Loop_outer4x: + movdqa 64(%rsp),%xmm8 + movdqa 80(%rsp),%xmm9 + movdqa 96(%rsp),%xmm10 + movdqa 112(%rsp),%xmm11 + movdqa 128-256(%rcx),%xmm12 + movdqa 144-256(%rcx),%xmm13 + movdqa 160-256(%rcx),%xmm14 + movdqa 176-256(%rcx),%xmm15 + movdqa 192-256(%rcx),%xmm4 + movdqa 208-256(%rcx),%xmm5 + movdqa 224-256(%rcx),%xmm6 + movdqa 240-256(%rcx),%xmm7 + movdqa 256-256(%rcx),%xmm0 + movdqa 272-256(%rcx),%xmm1 + movdqa 288-256(%rcx),%xmm2 + movdqa 304-256(%rcx),%xmm3 + paddd .Lfour(%rip),%xmm0 + +.Loop_enter4x: + movdqa %xmm6,32(%rsp) + movdqa %xmm7,48(%rsp) + movdqa (%r10),%xmm7 + movl $10,%eax + movdqa %xmm0,256-256(%rcx) + jmp .Loop4x + +.align 32 +.Loop4x: + paddd %xmm12,%xmm8 + paddd %xmm13,%xmm9 + pxor %xmm8,%xmm0 + pxor %xmm9,%xmm1 +.byte 102,15,56,0,199 +.byte 102,15,56,0,207 + paddd %xmm0,%xmm4 + paddd %xmm1,%xmm5 + pxor %xmm4,%xmm12 + pxor %xmm5,%xmm13 + movdqa %xmm12,%xmm6 + pslld $12,%xmm12 + psrld $20,%xmm6 + movdqa %xmm13,%xmm7 + pslld $12,%xmm13 + por %xmm6,%xmm12 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm13 + paddd %xmm12,%xmm8 + paddd %xmm13,%xmm9 + pxor %xmm8,%xmm0 + pxor %xmm9,%xmm1 +.byte 102,15,56,0,198 +.byte 102,15,56,0,206 + paddd %xmm0,%xmm4 + paddd %xmm1,%xmm5 + pxor %xmm4,%xmm12 + pxor %xmm5,%xmm13 + movdqa %xmm12,%xmm7 + pslld $7,%xmm12 + psrld $25,%xmm7 + movdqa %xmm13,%xmm6 + pslld $7,%xmm13 + por %xmm7,%xmm12 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm13 + movdqa %xmm4,0(%rsp) + movdqa %xmm5,16(%rsp) + movdqa 32(%rsp),%xmm4 + movdqa 48(%rsp),%xmm5 + paddd %xmm14,%xmm10 + paddd %xmm15,%xmm11 + pxor %xmm10,%xmm2 + pxor %xmm11,%xmm3 +.byte 102,15,56,0,215 +.byte 102,15,56,0,223 + paddd %xmm2,%xmm4 + paddd %xmm3,%xmm5 + pxor %xmm4,%xmm14 + pxor %xmm5,%xmm15 + movdqa %xmm14,%xmm6 + pslld $12,%xmm14 + psrld $20,%xmm6 + movdqa %xmm15,%xmm7 + pslld $12,%xmm15 + por %xmm6,%xmm14 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm15 + paddd %xmm14,%xmm10 + paddd %xmm15,%xmm11 + pxor %xmm10,%xmm2 + pxor %xmm11,%xmm3 +.byte 102,15,56,0,214 +.byte 102,15,56,0,222 + paddd %xmm2,%xmm4 + paddd %xmm3,%xmm5 + pxor %xmm4,%xmm14 + pxor %xmm5,%xmm15 + movdqa %xmm14,%xmm7 + pslld $7,%xmm14 + psrld $25,%xmm7 + movdqa %xmm15,%xmm6 + pslld $7,%xmm15 + por %xmm7,%xmm14 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm15 + paddd %xmm13,%xmm8 + paddd %xmm14,%xmm9 + pxor %xmm8,%xmm3 + pxor %xmm9,%xmm0 +.byte 102,15,56,0,223 +.byte 102,15,56,0,199 + paddd %xmm3,%xmm4 + paddd %xmm0,%xmm5 + pxor %xmm4,%xmm13 + pxor %xmm5,%xmm14 + movdqa %xmm13,%xmm6 + pslld $12,%xmm13 + psrld $20,%xmm6 + movdqa %xmm14,%xmm7 + pslld $12,%xmm14 + por %xmm6,%xmm13 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm14 + paddd %xmm13,%xmm8 + paddd %xmm14,%xmm9 + pxor %xmm8,%xmm3 + pxor %xmm9,%xmm0 +.byte 102,15,56,0,222 +.byte 102,15,56,0,198 + paddd %xmm3,%xmm4 + paddd %xmm0,%xmm5 + pxor %xmm4,%xmm13 + pxor %xmm5,%xmm14 + movdqa %xmm13,%xmm7 + pslld $7,%xmm13 + psrld $25,%xmm7 + movdqa %xmm14,%xmm6 + pslld $7,%xmm14 + por %xmm7,%xmm13 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm14 + movdqa %xmm4,32(%rsp) + movdqa %xmm5,48(%rsp) + movdqa 0(%rsp),%xmm4 + movdqa 16(%rsp),%xmm5 + paddd %xmm15,%xmm10 + paddd %xmm12,%xmm11 + pxor %xmm10,%xmm1 + pxor %xmm11,%xmm2 +.byte 102,15,56,0,207 +.byte 102,15,56,0,215 + paddd %xmm1,%xmm4 + paddd %xmm2,%xmm5 + pxor %xmm4,%xmm15 + pxor %xmm5,%xmm12 + movdqa %xmm15,%xmm6 + pslld $12,%xmm15 + psrld $20,%xmm6 + movdqa %xmm12,%xmm7 + pslld $12,%xmm12 + por %xmm6,%xmm15 + psrld $20,%xmm7 + movdqa (%r11),%xmm6 + por %xmm7,%xmm12 + paddd %xmm15,%xmm10 + paddd %xmm12,%xmm11 + pxor %xmm10,%xmm1 + pxor %xmm11,%xmm2 +.byte 102,15,56,0,206 +.byte 102,15,56,0,214 + paddd %xmm1,%xmm4 + paddd %xmm2,%xmm5 + pxor %xmm4,%xmm15 + pxor %xmm5,%xmm12 + movdqa %xmm15,%xmm7 + pslld $7,%xmm15 + psrld $25,%xmm7 + movdqa %xmm12,%xmm6 + pslld $7,%xmm12 + por %xmm7,%xmm15 + psrld $25,%xmm6 + movdqa (%r10),%xmm7 + por %xmm6,%xmm12 + decl %eax + jnz .Loop4x + + paddd 64(%rsp),%xmm8 + paddd 80(%rsp),%xmm9 + paddd 96(%rsp),%xmm10 + paddd 112(%rsp),%xmm11 + + movdqa %xmm8,%xmm6 + punpckldq %xmm9,%xmm8 + movdqa %xmm10,%xmm7 + punpckldq %xmm11,%xmm10 + punpckhdq %xmm9,%xmm6 + punpckhdq %xmm11,%xmm7 + movdqa %xmm8,%xmm9 + punpcklqdq %xmm10,%xmm8 + movdqa %xmm6,%xmm11 + punpcklqdq %xmm7,%xmm6 + punpckhqdq %xmm10,%xmm9 + punpckhqdq %xmm7,%xmm11 + paddd 128-256(%rcx),%xmm12 + paddd 144-256(%rcx),%xmm13 + paddd 160-256(%rcx),%xmm14 + paddd 176-256(%rcx),%xmm15 + + movdqa %xmm8,0(%rsp) + movdqa %xmm9,16(%rsp) + movdqa 32(%rsp),%xmm8 + movdqa 48(%rsp),%xmm9 + + movdqa %xmm12,%xmm10 + punpckldq %xmm13,%xmm12 + movdqa %xmm14,%xmm7 + punpckldq %xmm15,%xmm14 + punpckhdq %xmm13,%xmm10 + punpckhdq %xmm15,%xmm7 + movdqa %xmm12,%xmm13 + punpcklqdq %xmm14,%xmm12 + movdqa %xmm10,%xmm15 + punpcklqdq %xmm7,%xmm10 + punpckhqdq %xmm14,%xmm13 + punpckhqdq %xmm7,%xmm15 + paddd 192-256(%rcx),%xmm4 + paddd 208-256(%rcx),%xmm5 + paddd 224-256(%rcx),%xmm8 + paddd 240-256(%rcx),%xmm9 + + movdqa %xmm6,32(%rsp) + movdqa %xmm11,48(%rsp) + + movdqa %xmm4,%xmm14 + punpckldq %xmm5,%xmm4 + movdqa %xmm8,%xmm7 + punpckldq %xmm9,%xmm8 + punpckhdq %xmm5,%xmm14 + punpckhdq %xmm9,%xmm7 + movdqa %xmm4,%xmm5 + punpcklqdq %xmm8,%xmm4 + movdqa %xmm14,%xmm9 + punpcklqdq %xmm7,%xmm14 + punpckhqdq %xmm8,%xmm5 + punpckhqdq %xmm7,%xmm9 + paddd 256-256(%rcx),%xmm0 + paddd 272-256(%rcx),%xmm1 + paddd 288-256(%rcx),%xmm2 + paddd 304-256(%rcx),%xmm3 + + movdqa %xmm0,%xmm8 + punpckldq %xmm1,%xmm0 + movdqa %xmm2,%xmm7 + punpckldq %xmm3,%xmm2 + punpckhdq %xmm1,%xmm8 + punpckhdq %xmm3,%xmm7 + movdqa %xmm0,%xmm1 + punpcklqdq %xmm2,%xmm0 + movdqa %xmm8,%xmm3 + punpcklqdq %xmm7,%xmm8 + punpckhqdq %xmm2,%xmm1 + punpckhqdq %xmm7,%xmm3 + cmpq $256,%rdx + jb .Ltail4x + + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + leaq 128(%rsi),%rsi + pxor 16(%rsp),%xmm6 + pxor %xmm13,%xmm11 + pxor %xmm5,%xmm2 + pxor %xmm1,%xmm7 + + movdqu %xmm6,64(%rdi) + movdqu 0(%rsi),%xmm6 + movdqu %xmm11,80(%rdi) + movdqu 16(%rsi),%xmm11 + movdqu %xmm2,96(%rdi) + movdqu 32(%rsi),%xmm2 + movdqu %xmm7,112(%rdi) + leaq 128(%rdi),%rdi + movdqu 48(%rsi),%xmm7 + pxor 32(%rsp),%xmm6 + pxor %xmm10,%xmm11 + pxor %xmm14,%xmm2 + pxor %xmm8,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + leaq 128(%rsi),%rsi + pxor 48(%rsp),%xmm6 + pxor %xmm15,%xmm11 + pxor %xmm9,%xmm2 + pxor %xmm3,%xmm7 + movdqu %xmm6,64(%rdi) + movdqu %xmm11,80(%rdi) + movdqu %xmm2,96(%rdi) + movdqu %xmm7,112(%rdi) + leaq 128(%rdi),%rdi + + subq $256,%rdx + jnz .Loop_outer4x + + jmp .Ldone4x + +.Ltail4x: + cmpq $192,%rdx + jae .L192_or_more4x + cmpq $128,%rdx + jae .L128_or_more4x + cmpq $64,%rdx + jae .L64_or_more4x + + + xorq %r10,%r10 + + movdqa %xmm12,16(%rsp) + movdqa %xmm4,32(%rsp) + movdqa %xmm0,48(%rsp) + jmp .Loop_tail4x + +.align 32 +.L64_or_more4x: + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + movdqu %xmm6,0(%rdi) + movdqu %xmm11,16(%rdi) + movdqu %xmm2,32(%rdi) + movdqu %xmm7,48(%rdi) + je .Ldone4x + + movdqa 16(%rsp),%xmm6 + leaq 64(%rsi),%rsi + xorq %r10,%r10 + movdqa %xmm6,0(%rsp) + movdqa %xmm13,16(%rsp) + leaq 64(%rdi),%rdi + movdqa %xmm5,32(%rsp) + subq $64,%rdx + movdqa %xmm1,48(%rsp) + jmp .Loop_tail4x + +.align 32 +.L128_or_more4x: + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + pxor 16(%rsp),%xmm6 + pxor %xmm13,%xmm11 + pxor %xmm5,%xmm2 + pxor %xmm1,%xmm7 + movdqu %xmm6,64(%rdi) + movdqu %xmm11,80(%rdi) + movdqu %xmm2,96(%rdi) + movdqu %xmm7,112(%rdi) + je .Ldone4x + + movdqa 32(%rsp),%xmm6 + leaq 128(%rsi),%rsi + xorq %r10,%r10 + movdqa %xmm6,0(%rsp) + movdqa %xmm10,16(%rsp) + leaq 128(%rdi),%rdi + movdqa %xmm14,32(%rsp) + subq $128,%rdx + movdqa %xmm8,48(%rsp) + jmp .Loop_tail4x + +.align 32 +.L192_or_more4x: + movdqu 0(%rsi),%xmm6 + movdqu 16(%rsi),%xmm11 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm7 + pxor 0(%rsp),%xmm6 + pxor %xmm12,%xmm11 + pxor %xmm4,%xmm2 + pxor %xmm0,%xmm7 + + movdqu %xmm6,0(%rdi) + movdqu 64(%rsi),%xmm6 + movdqu %xmm11,16(%rdi) + movdqu 80(%rsi),%xmm11 + movdqu %xmm2,32(%rdi) + movdqu 96(%rsi),%xmm2 + movdqu %xmm7,48(%rdi) + movdqu 112(%rsi),%xmm7 + leaq 128(%rsi),%rsi + pxor 16(%rsp),%xmm6 + pxor %xmm13,%xmm11 + pxor %xmm5,%xmm2 + pxor %xmm1,%xmm7 + + movdqu %xmm6,64(%rdi) + movdqu 0(%rsi),%xmm6 + movdqu %xmm11,80(%rdi) + movdqu 16(%rsi),%xmm11 + movdqu %xmm2,96(%rdi) + movdqu 32(%rsi),%xmm2 + movdqu %xmm7,112(%rdi) + leaq 128(%rdi),%rdi + movdqu 48(%rsi),%xmm7 + pxor 32(%rsp),%xmm6 + pxor %xmm10,%xmm11 + pxor %xmm14,%xmm2 + pxor %xmm8,%xmm7 + movdqu %xmm6,0(%rdi) + movdqu %xmm11,16(%rdi) + movdqu %xmm2,32(%rdi) + movdqu %xmm7,48(%rdi) + je .Ldone4x + + movdqa 48(%rsp),%xmm6 + leaq 64(%rsi),%rsi + xorq %r10,%r10 + movdqa %xmm6,0(%rsp) + movdqa %xmm15,16(%rsp) + leaq 64(%rdi),%rdi + movdqa %xmm9,32(%rsp) + subq $192,%rdx + movdqa %xmm3,48(%rsp) + +.Loop_tail4x: + movzbl (%rsi,%r10,1),%eax + movzbl (%rsp,%r10,1),%ecx + leaq 1(%r10),%r10 + xorl %ecx,%eax + movb %al,-1(%rdi,%r10,1) + decq %rdx + jnz .Loop_tail4x + +.Ldone4x: + leaq (%r9),%rsp +.cfi_def_cfa_register %rsp +.L4x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ChaCha20_4x,.-ChaCha20_4x +.type ChaCha20_4xop,@function +.align 32 +ChaCha20_4xop: +.cfi_startproc +.LChaCha20_4xop: + movq %rsp,%r9 +.cfi_def_cfa_register %r9 + subq $0x140+8,%rsp + vzeroupper + + vmovdqa .Lsigma(%rip),%xmm11 + vmovdqu (%rcx),%xmm3 + vmovdqu 16(%rcx),%xmm15 + vmovdqu (%r8),%xmm7 + leaq 256(%rsp),%rcx + + vpshufd $0x00,%xmm11,%xmm8 + vpshufd $0x55,%xmm11,%xmm9 + vmovdqa %xmm8,64(%rsp) + vpshufd $0xaa,%xmm11,%xmm10 + vmovdqa %xmm9,80(%rsp) + vpshufd $0xff,%xmm11,%xmm11 + vmovdqa %xmm10,96(%rsp) + vmovdqa %xmm11,112(%rsp) + + vpshufd $0x00,%xmm3,%xmm0 + vpshufd $0x55,%xmm3,%xmm1 + vmovdqa %xmm0,128-256(%rcx) + vpshufd $0xaa,%xmm3,%xmm2 + vmovdqa %xmm1,144-256(%rcx) + vpshufd $0xff,%xmm3,%xmm3 + vmovdqa %xmm2,160-256(%rcx) + vmovdqa %xmm3,176-256(%rcx) + + vpshufd $0x00,%xmm15,%xmm12 + vpshufd $0x55,%xmm15,%xmm13 + vmovdqa %xmm12,192-256(%rcx) + vpshufd $0xaa,%xmm15,%xmm14 + vmovdqa %xmm13,208-256(%rcx) + vpshufd $0xff,%xmm15,%xmm15 + vmovdqa %xmm14,224-256(%rcx) + vmovdqa %xmm15,240-256(%rcx) + + vpshufd $0x00,%xmm7,%xmm4 + vpshufd $0x55,%xmm7,%xmm5 + vpaddd .Linc(%rip),%xmm4,%xmm4 + vpshufd $0xaa,%xmm7,%xmm6 + vmovdqa %xmm5,272-256(%rcx) + vpshufd $0xff,%xmm7,%xmm7 + vmovdqa %xmm6,288-256(%rcx) + vmovdqa %xmm7,304-256(%rcx) + + jmp .Loop_enter4xop + +.align 32 +.Loop_outer4xop: + vmovdqa 64(%rsp),%xmm8 + vmovdqa 80(%rsp),%xmm9 + vmovdqa 96(%rsp),%xmm10 + vmovdqa 112(%rsp),%xmm11 + vmovdqa 128-256(%rcx),%xmm0 + vmovdqa 144-256(%rcx),%xmm1 + vmovdqa 160-256(%rcx),%xmm2 + vmovdqa 176-256(%rcx),%xmm3 + vmovdqa 192-256(%rcx),%xmm12 + vmovdqa 208-256(%rcx),%xmm13 + vmovdqa 224-256(%rcx),%xmm14 + vmovdqa 240-256(%rcx),%xmm15 + vmovdqa 256-256(%rcx),%xmm4 + vmovdqa 272-256(%rcx),%xmm5 + vmovdqa 288-256(%rcx),%xmm6 + vmovdqa 304-256(%rcx),%xmm7 + vpaddd .Lfour(%rip),%xmm4,%xmm4 + +.Loop_enter4xop: + movl $10,%eax + vmovdqa %xmm4,256-256(%rcx) + jmp .Loop4xop + +.align 32 +.Loop4xop: + vpaddd %xmm0,%xmm8,%xmm8 + vpaddd %xmm1,%xmm9,%xmm9 + vpaddd %xmm2,%xmm10,%xmm10 + vpaddd %xmm3,%xmm11,%xmm11 + vpxor %xmm4,%xmm8,%xmm4 + vpxor %xmm5,%xmm9,%xmm5 + vpxor %xmm6,%xmm10,%xmm6 + vpxor %xmm7,%xmm11,%xmm7 +.byte 143,232,120,194,228,16 +.byte 143,232,120,194,237,16 +.byte 143,232,120,194,246,16 +.byte 143,232,120,194,255,16 + vpaddd %xmm4,%xmm12,%xmm12 + vpaddd %xmm5,%xmm13,%xmm13 + vpaddd %xmm6,%xmm14,%xmm14 + vpaddd %xmm7,%xmm15,%xmm15 + vpxor %xmm0,%xmm12,%xmm0 + vpxor %xmm1,%xmm13,%xmm1 + vpxor %xmm14,%xmm2,%xmm2 + vpxor %xmm15,%xmm3,%xmm3 +.byte 143,232,120,194,192,12 +.byte 143,232,120,194,201,12 +.byte 143,232,120,194,210,12 +.byte 143,232,120,194,219,12 + vpaddd %xmm8,%xmm0,%xmm8 + vpaddd %xmm9,%xmm1,%xmm9 + vpaddd %xmm2,%xmm10,%xmm10 + vpaddd %xmm3,%xmm11,%xmm11 + vpxor %xmm4,%xmm8,%xmm4 + vpxor %xmm5,%xmm9,%xmm5 + vpxor %xmm6,%xmm10,%xmm6 + vpxor %xmm7,%xmm11,%xmm7 +.byte 143,232,120,194,228,8 +.byte 143,232,120,194,237,8 +.byte 143,232,120,194,246,8 +.byte 143,232,120,194,255,8 + vpaddd %xmm4,%xmm12,%xmm12 + vpaddd %xmm5,%xmm13,%xmm13 + vpaddd %xmm6,%xmm14,%xmm14 + vpaddd %xmm7,%xmm15,%xmm15 + vpxor %xmm0,%xmm12,%xmm0 + vpxor %xmm1,%xmm13,%xmm1 + vpxor %xmm14,%xmm2,%xmm2 + vpxor %xmm15,%xmm3,%xmm3 +.byte 143,232,120,194,192,7 +.byte 143,232,120,194,201,7 +.byte 143,232,120,194,210,7 +.byte 143,232,120,194,219,7 + vpaddd %xmm1,%xmm8,%xmm8 + vpaddd %xmm2,%xmm9,%xmm9 + vpaddd %xmm3,%xmm10,%xmm10 + vpaddd %xmm0,%xmm11,%xmm11 + vpxor %xmm7,%xmm8,%xmm7 + vpxor %xmm4,%xmm9,%xmm4 + vpxor %xmm5,%xmm10,%xmm5 + vpxor %xmm6,%xmm11,%xmm6 +.byte 143,232,120,194,255,16 +.byte 143,232,120,194,228,16 +.byte 143,232,120,194,237,16 +.byte 143,232,120,194,246,16 + vpaddd %xmm7,%xmm14,%xmm14 + vpaddd %xmm4,%xmm15,%xmm15 + vpaddd %xmm5,%xmm12,%xmm12 + vpaddd %xmm6,%xmm13,%xmm13 + vpxor %xmm1,%xmm14,%xmm1 + vpxor %xmm2,%xmm15,%xmm2 + vpxor %xmm12,%xmm3,%xmm3 + vpxor %xmm13,%xmm0,%xmm0 +.byte 143,232,120,194,201,12 +.byte 143,232,120,194,210,12 +.byte 143,232,120,194,219,12 +.byte 143,232,120,194,192,12 + vpaddd %xmm8,%xmm1,%xmm8 + vpaddd %xmm9,%xmm2,%xmm9 + vpaddd %xmm3,%xmm10,%xmm10 + vpaddd %xmm0,%xmm11,%xmm11 + vpxor %xmm7,%xmm8,%xmm7 + vpxor %xmm4,%xmm9,%xmm4 + vpxor %xmm5,%xmm10,%xmm5 + vpxor %xmm6,%xmm11,%xmm6 +.byte 143,232,120,194,255,8 +.byte 143,232,120,194,228,8 +.byte 143,232,120,194,237,8 +.byte 143,232,120,194,246,8 + vpaddd %xmm7,%xmm14,%xmm14 + vpaddd %xmm4,%xmm15,%xmm15 + vpaddd %xmm5,%xmm12,%xmm12 + vpaddd %xmm6,%xmm13,%xmm13 + vpxor %xmm1,%xmm14,%xmm1 + vpxor %xmm2,%xmm15,%xmm2 + vpxor %xmm12,%xmm3,%xmm3 + vpxor %xmm13,%xmm0,%xmm0 +.byte 143,232,120,194,201,7 +.byte 143,232,120,194,210,7 +.byte 143,232,120,194,219,7 +.byte 143,232,120,194,192,7 + decl %eax + jnz .Loop4xop + + vpaddd 64(%rsp),%xmm8,%xmm8 + vpaddd 80(%rsp),%xmm9,%xmm9 + vpaddd 96(%rsp),%xmm10,%xmm10 + vpaddd 112(%rsp),%xmm11,%xmm11 + + vmovdqa %xmm14,32(%rsp) + vmovdqa %xmm15,48(%rsp) + + vpunpckldq %xmm9,%xmm8,%xmm14 + vpunpckldq %xmm11,%xmm10,%xmm15 + vpunpckhdq %xmm9,%xmm8,%xmm8 + vpunpckhdq %xmm11,%xmm10,%xmm10 + vpunpcklqdq %xmm15,%xmm14,%xmm9 + vpunpckhqdq %xmm15,%xmm14,%xmm14 + vpunpcklqdq %xmm10,%xmm8,%xmm11 + vpunpckhqdq %xmm10,%xmm8,%xmm8 + vpaddd 128-256(%rcx),%xmm0,%xmm0 + vpaddd 144-256(%rcx),%xmm1,%xmm1 + vpaddd 160-256(%rcx),%xmm2,%xmm2 + vpaddd 176-256(%rcx),%xmm3,%xmm3 + + vmovdqa %xmm9,0(%rsp) + vmovdqa %xmm14,16(%rsp) + vmovdqa 32(%rsp),%xmm9 + vmovdqa 48(%rsp),%xmm14 + + vpunpckldq %xmm1,%xmm0,%xmm10 + vpunpckldq %xmm3,%xmm2,%xmm15 + vpunpckhdq %xmm1,%xmm0,%xmm0 + vpunpckhdq %xmm3,%xmm2,%xmm2 + vpunpcklqdq %xmm15,%xmm10,%xmm1 + vpunpckhqdq %xmm15,%xmm10,%xmm10 + vpunpcklqdq %xmm2,%xmm0,%xmm3 + vpunpckhqdq %xmm2,%xmm0,%xmm0 + vpaddd 192-256(%rcx),%xmm12,%xmm12 + vpaddd 208-256(%rcx),%xmm13,%xmm13 + vpaddd 224-256(%rcx),%xmm9,%xmm9 + vpaddd 240-256(%rcx),%xmm14,%xmm14 + + vpunpckldq %xmm13,%xmm12,%xmm2 + vpunpckldq %xmm14,%xmm9,%xmm15 + vpunpckhdq %xmm13,%xmm12,%xmm12 + vpunpckhdq %xmm14,%xmm9,%xmm9 + vpunpcklqdq %xmm15,%xmm2,%xmm13 + vpunpckhqdq %xmm15,%xmm2,%xmm2 + vpunpcklqdq %xmm9,%xmm12,%xmm14 + vpunpckhqdq %xmm9,%xmm12,%xmm12 + vpaddd 256-256(%rcx),%xmm4,%xmm4 + vpaddd 272-256(%rcx),%xmm5,%xmm5 + vpaddd 288-256(%rcx),%xmm6,%xmm6 + vpaddd 304-256(%rcx),%xmm7,%xmm7 + + vpunpckldq %xmm5,%xmm4,%xmm9 + vpunpckldq %xmm7,%xmm6,%xmm15 + vpunpckhdq %xmm5,%xmm4,%xmm4 + vpunpckhdq %xmm7,%xmm6,%xmm6 + vpunpcklqdq %xmm15,%xmm9,%xmm5 + vpunpckhqdq %xmm15,%xmm9,%xmm9 + vpunpcklqdq %xmm6,%xmm4,%xmm7 + vpunpckhqdq %xmm6,%xmm4,%xmm4 + vmovdqa 0(%rsp),%xmm6 + vmovdqa 16(%rsp),%xmm15 + + cmpq $256,%rdx + jb .Ltail4xop + + vpxor 0(%rsi),%xmm6,%xmm6 + vpxor 16(%rsi),%xmm1,%xmm1 + vpxor 32(%rsi),%xmm13,%xmm13 + vpxor 48(%rsi),%xmm5,%xmm5 + vpxor 64(%rsi),%xmm15,%xmm15 + vpxor 80(%rsi),%xmm10,%xmm10 + vpxor 96(%rsi),%xmm2,%xmm2 + vpxor 112(%rsi),%xmm9,%xmm9 + leaq 128(%rsi),%rsi + vpxor 0(%rsi),%xmm11,%xmm11 + vpxor 16(%rsi),%xmm3,%xmm3 + vpxor 32(%rsi),%xmm14,%xmm14 + vpxor 48(%rsi),%xmm7,%xmm7 + vpxor 64(%rsi),%xmm8,%xmm8 + vpxor 80(%rsi),%xmm0,%xmm0 + vpxor 96(%rsi),%xmm12,%xmm12 + vpxor 112(%rsi),%xmm4,%xmm4 + leaq 128(%rsi),%rsi + + vmovdqu %xmm6,0(%rdi) + vmovdqu %xmm1,16(%rdi) + vmovdqu %xmm13,32(%rdi) + vmovdqu %xmm5,48(%rdi) + vmovdqu %xmm15,64(%rdi) + vmovdqu %xmm10,80(%rdi) + vmovdqu %xmm2,96(%rdi) + vmovdqu %xmm9,112(%rdi) + leaq 128(%rdi),%rdi + vmovdqu %xmm11,0(%rdi) + vmovdqu %xmm3,16(%rdi) + vmovdqu %xmm14,32(%rdi) + vmovdqu %xmm7,48(%rdi) + vmovdqu %xmm8,64(%rdi) + vmovdqu %xmm0,80(%rdi) + vmovdqu %xmm12,96(%rdi) + vmovdqu %xmm4,112(%rdi) + leaq 128(%rdi),%rdi + + subq $256,%rdx + jnz .Loop_outer4xop + + jmp .Ldone4xop + +.align 32 +.Ltail4xop: + cmpq $192,%rdx + jae .L192_or_more4xop + cmpq $128,%rdx + jae .L128_or_more4xop + cmpq $64,%rdx + jae .L64_or_more4xop + + xorq %r10,%r10 + vmovdqa %xmm6,0(%rsp) + vmovdqa %xmm1,16(%rsp) + vmovdqa %xmm13,32(%rsp) + vmovdqa %xmm5,48(%rsp) + jmp .Loop_tail4xop + +.align 32 +.L64_or_more4xop: + vpxor 0(%rsi),%xmm6,%xmm6 + vpxor 16(%rsi),%xmm1,%xmm1 + vpxor 32(%rsi),%xmm13,%xmm13 + vpxor 48(%rsi),%xmm5,%xmm5 + vmovdqu %xmm6,0(%rdi) + vmovdqu %xmm1,16(%rdi) + vmovdqu %xmm13,32(%rdi) + vmovdqu %xmm5,48(%rdi) + je .Ldone4xop + + leaq 64(%rsi),%rsi + vmovdqa %xmm15,0(%rsp) + xorq %r10,%r10 + vmovdqa %xmm10,16(%rsp) + leaq 64(%rdi),%rdi + vmovdqa %xmm2,32(%rsp) + subq $64,%rdx + vmovdqa %xmm9,48(%rsp) + jmp .Loop_tail4xop + +.align 32 +.L128_or_more4xop: + vpxor 0(%rsi),%xmm6,%xmm6 + vpxor 16(%rsi),%xmm1,%xmm1 + vpxor 32(%rsi),%xmm13,%xmm13 + vpxor 48(%rsi),%xmm5,%xmm5 + vpxor 64(%rsi),%xmm15,%xmm15 + vpxor 80(%rsi),%xmm10,%xmm10 + vpxor 96(%rsi),%xmm2,%xmm2 + vpxor 112(%rsi),%xmm9,%xmm9 + + vmovdqu %xmm6,0(%rdi) + vmovdqu %xmm1,16(%rdi) + vmovdqu %xmm13,32(%rdi) + vmovdqu %xmm5,48(%rdi) + vmovdqu %xmm15,64(%rdi) + vmovdqu %xmm10,80(%rdi) + vmovdqu %xmm2,96(%rdi) + vmovdqu %xmm9,112(%rdi) + je .Ldone4xop + + leaq 128(%rsi),%rsi + vmovdqa %xmm11,0(%rsp) + xorq %r10,%r10 + vmovdqa %xmm3,16(%rsp) + leaq 128(%rdi),%rdi + vmovdqa %xmm14,32(%rsp) + subq $128,%rdx + vmovdqa %xmm7,48(%rsp) + jmp .Loop_tail4xop + +.align 32 +.L192_or_more4xop: + vpxor 0(%rsi),%xmm6,%xmm6 + vpxor 16(%rsi),%xmm1,%xmm1 + vpxor 32(%rsi),%xmm13,%xmm13 + vpxor 48(%rsi),%xmm5,%xmm5 + vpxor 64(%rsi),%xmm15,%xmm15 + vpxor 80(%rsi),%xmm10,%xmm10 + vpxor 96(%rsi),%xmm2,%xmm2 + vpxor 112(%rsi),%xmm9,%xmm9 + leaq 128(%rsi),%rsi + vpxor 0(%rsi),%xmm11,%xmm11 + vpxor 16(%rsi),%xmm3,%xmm3 + vpxor 32(%rsi),%xmm14,%xmm14 + vpxor 48(%rsi),%xmm7,%xmm7 + + vmovdqu %xmm6,0(%rdi) + vmovdqu %xmm1,16(%rdi) + vmovdqu %xmm13,32(%rdi) + vmovdqu %xmm5,48(%rdi) + vmovdqu %xmm15,64(%rdi) + vmovdqu %xmm10,80(%rdi) + vmovdqu %xmm2,96(%rdi) + vmovdqu %xmm9,112(%rdi) + leaq 128(%rdi),%rdi + vmovdqu %xmm11,0(%rdi) + vmovdqu %xmm3,16(%rdi) + vmovdqu %xmm14,32(%rdi) + vmovdqu %xmm7,48(%rdi) + je .Ldone4xop + + leaq 64(%rsi),%rsi + vmovdqa %xmm8,0(%rsp) + xorq %r10,%r10 + vmovdqa %xmm0,16(%rsp) + leaq 64(%rdi),%rdi + vmovdqa %xmm12,32(%rsp) + subq $192,%rdx + vmovdqa %xmm4,48(%rsp) + +.Loop_tail4xop: + movzbl (%rsi,%r10,1),%eax + movzbl (%rsp,%r10,1),%ecx + leaq 1(%r10),%r10 + xorl %ecx,%eax + movb %al,-1(%rdi,%r10,1) + decq %rdx + jnz .Loop_tail4xop + +.Ldone4xop: + vzeroupper + leaq (%r9),%rsp +.cfi_def_cfa_register %rsp +.L4xop_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ChaCha20_4xop,.-ChaCha20_4xop +.type ChaCha20_8x,@function +.align 32 +ChaCha20_8x: +.cfi_startproc +.LChaCha20_8x: + movq %rsp,%r9 +.cfi_def_cfa_register %r9 + subq $0x280+8,%rsp + andq $-32,%rsp + vzeroupper + + + + + + + + + + + vbroadcasti128 .Lsigma(%rip),%ymm11 + vbroadcasti128 (%rcx),%ymm3 + vbroadcasti128 16(%rcx),%ymm15 + vbroadcasti128 (%r8),%ymm7 + leaq 256(%rsp),%rcx + leaq 512(%rsp),%rax + leaq .Lrot16(%rip),%r10 + leaq .Lrot24(%rip),%r11 + + vpshufd $0x00,%ymm11,%ymm8 + vpshufd $0x55,%ymm11,%ymm9 + vmovdqa %ymm8,128-256(%rcx) + vpshufd $0xaa,%ymm11,%ymm10 + vmovdqa %ymm9,160-256(%rcx) + vpshufd $0xff,%ymm11,%ymm11 + vmovdqa %ymm10,192-256(%rcx) + vmovdqa %ymm11,224-256(%rcx) + + vpshufd $0x00,%ymm3,%ymm0 + vpshufd $0x55,%ymm3,%ymm1 + vmovdqa %ymm0,256-256(%rcx) + vpshufd $0xaa,%ymm3,%ymm2 + vmovdqa %ymm1,288-256(%rcx) + vpshufd $0xff,%ymm3,%ymm3 + vmovdqa %ymm2,320-256(%rcx) + vmovdqa %ymm3,352-256(%rcx) + + vpshufd $0x00,%ymm15,%ymm12 + vpshufd $0x55,%ymm15,%ymm13 + vmovdqa %ymm12,384-512(%rax) + vpshufd $0xaa,%ymm15,%ymm14 + vmovdqa %ymm13,416-512(%rax) + vpshufd $0xff,%ymm15,%ymm15 + vmovdqa %ymm14,448-512(%rax) + vmovdqa %ymm15,480-512(%rax) + + vpshufd $0x00,%ymm7,%ymm4 + vpshufd $0x55,%ymm7,%ymm5 + vpaddd .Lincy(%rip),%ymm4,%ymm4 + vpshufd $0xaa,%ymm7,%ymm6 + vmovdqa %ymm5,544-512(%rax) + vpshufd $0xff,%ymm7,%ymm7 + vmovdqa %ymm6,576-512(%rax) + vmovdqa %ymm7,608-512(%rax) + + jmp .Loop_enter8x + +.align 32 +.Loop_outer8x: + vmovdqa 128-256(%rcx),%ymm8 + vmovdqa 160-256(%rcx),%ymm9 + vmovdqa 192-256(%rcx),%ymm10 + vmovdqa 224-256(%rcx),%ymm11 + vmovdqa 256-256(%rcx),%ymm0 + vmovdqa 288-256(%rcx),%ymm1 + vmovdqa 320-256(%rcx),%ymm2 + vmovdqa 352-256(%rcx),%ymm3 + vmovdqa 384-512(%rax),%ymm12 + vmovdqa 416-512(%rax),%ymm13 + vmovdqa 448-512(%rax),%ymm14 + vmovdqa 480-512(%rax),%ymm15 + vmovdqa 512-512(%rax),%ymm4 + vmovdqa 544-512(%rax),%ymm5 + vmovdqa 576-512(%rax),%ymm6 + vmovdqa 608-512(%rax),%ymm7 + vpaddd .Leight(%rip),%ymm4,%ymm4 + +.Loop_enter8x: + vmovdqa %ymm14,64(%rsp) + vmovdqa %ymm15,96(%rsp) + vbroadcasti128 (%r10),%ymm15 + vmovdqa %ymm4,512-512(%rax) + movl $10,%eax + jmp .Loop8x + +.align 32 +.Loop8x: + vpaddd %ymm0,%ymm8,%ymm8 + vpxor %ymm4,%ymm8,%ymm4 + vpshufb %ymm15,%ymm4,%ymm4 + vpaddd %ymm1,%ymm9,%ymm9 + vpxor %ymm5,%ymm9,%ymm5 + vpshufb %ymm15,%ymm5,%ymm5 + vpaddd %ymm4,%ymm12,%ymm12 + vpxor %ymm0,%ymm12,%ymm0 + vpslld $12,%ymm0,%ymm14 + vpsrld $20,%ymm0,%ymm0 + vpor %ymm0,%ymm14,%ymm0 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm5,%ymm13,%ymm13 + vpxor %ymm1,%ymm13,%ymm1 + vpslld $12,%ymm1,%ymm15 + vpsrld $20,%ymm1,%ymm1 + vpor %ymm1,%ymm15,%ymm1 + vpaddd %ymm0,%ymm8,%ymm8 + vpxor %ymm4,%ymm8,%ymm4 + vpshufb %ymm14,%ymm4,%ymm4 + vpaddd %ymm1,%ymm9,%ymm9 + vpxor %ymm5,%ymm9,%ymm5 + vpshufb %ymm14,%ymm5,%ymm5 + vpaddd %ymm4,%ymm12,%ymm12 + vpxor %ymm0,%ymm12,%ymm0 + vpslld $7,%ymm0,%ymm15 + vpsrld $25,%ymm0,%ymm0 + vpor %ymm0,%ymm15,%ymm0 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm5,%ymm13,%ymm13 + vpxor %ymm1,%ymm13,%ymm1 + vpslld $7,%ymm1,%ymm14 + vpsrld $25,%ymm1,%ymm1 + vpor %ymm1,%ymm14,%ymm1 + vmovdqa %ymm12,0(%rsp) + vmovdqa %ymm13,32(%rsp) + vmovdqa 64(%rsp),%ymm12 + vmovdqa 96(%rsp),%ymm13 + vpaddd %ymm2,%ymm10,%ymm10 + vpxor %ymm6,%ymm10,%ymm6 + vpshufb %ymm15,%ymm6,%ymm6 + vpaddd %ymm3,%ymm11,%ymm11 + vpxor %ymm7,%ymm11,%ymm7 + vpshufb %ymm15,%ymm7,%ymm7 + vpaddd %ymm6,%ymm12,%ymm12 + vpxor %ymm2,%ymm12,%ymm2 + vpslld $12,%ymm2,%ymm14 + vpsrld $20,%ymm2,%ymm2 + vpor %ymm2,%ymm14,%ymm2 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm7,%ymm13,%ymm13 + vpxor %ymm3,%ymm13,%ymm3 + vpslld $12,%ymm3,%ymm15 + vpsrld $20,%ymm3,%ymm3 + vpor %ymm3,%ymm15,%ymm3 + vpaddd %ymm2,%ymm10,%ymm10 + vpxor %ymm6,%ymm10,%ymm6 + vpshufb %ymm14,%ymm6,%ymm6 + vpaddd %ymm3,%ymm11,%ymm11 + vpxor %ymm7,%ymm11,%ymm7 + vpshufb %ymm14,%ymm7,%ymm7 + vpaddd %ymm6,%ymm12,%ymm12 + vpxor %ymm2,%ymm12,%ymm2 + vpslld $7,%ymm2,%ymm15 + vpsrld $25,%ymm2,%ymm2 + vpor %ymm2,%ymm15,%ymm2 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm7,%ymm13,%ymm13 + vpxor %ymm3,%ymm13,%ymm3 + vpslld $7,%ymm3,%ymm14 + vpsrld $25,%ymm3,%ymm3 + vpor %ymm3,%ymm14,%ymm3 + vpaddd %ymm1,%ymm8,%ymm8 + vpxor %ymm7,%ymm8,%ymm7 + vpshufb %ymm15,%ymm7,%ymm7 + vpaddd %ymm2,%ymm9,%ymm9 + vpxor %ymm4,%ymm9,%ymm4 + vpshufb %ymm15,%ymm4,%ymm4 + vpaddd %ymm7,%ymm12,%ymm12 + vpxor %ymm1,%ymm12,%ymm1 + vpslld $12,%ymm1,%ymm14 + vpsrld $20,%ymm1,%ymm1 + vpor %ymm1,%ymm14,%ymm1 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm4,%ymm13,%ymm13 + vpxor %ymm2,%ymm13,%ymm2 + vpslld $12,%ymm2,%ymm15 + vpsrld $20,%ymm2,%ymm2 + vpor %ymm2,%ymm15,%ymm2 + vpaddd %ymm1,%ymm8,%ymm8 + vpxor %ymm7,%ymm8,%ymm7 + vpshufb %ymm14,%ymm7,%ymm7 + vpaddd %ymm2,%ymm9,%ymm9 + vpxor %ymm4,%ymm9,%ymm4 + vpshufb %ymm14,%ymm4,%ymm4 + vpaddd %ymm7,%ymm12,%ymm12 + vpxor %ymm1,%ymm12,%ymm1 + vpslld $7,%ymm1,%ymm15 + vpsrld $25,%ymm1,%ymm1 + vpor %ymm1,%ymm15,%ymm1 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm4,%ymm13,%ymm13 + vpxor %ymm2,%ymm13,%ymm2 + vpslld $7,%ymm2,%ymm14 + vpsrld $25,%ymm2,%ymm2 + vpor %ymm2,%ymm14,%ymm2 + vmovdqa %ymm12,64(%rsp) + vmovdqa %ymm13,96(%rsp) + vmovdqa 0(%rsp),%ymm12 + vmovdqa 32(%rsp),%ymm13 + vpaddd %ymm3,%ymm10,%ymm10 + vpxor %ymm5,%ymm10,%ymm5 + vpshufb %ymm15,%ymm5,%ymm5 + vpaddd %ymm0,%ymm11,%ymm11 + vpxor %ymm6,%ymm11,%ymm6 + vpshufb %ymm15,%ymm6,%ymm6 + vpaddd %ymm5,%ymm12,%ymm12 + vpxor %ymm3,%ymm12,%ymm3 + vpslld $12,%ymm3,%ymm14 + vpsrld $20,%ymm3,%ymm3 + vpor %ymm3,%ymm14,%ymm3 + vbroadcasti128 (%r11),%ymm14 + vpaddd %ymm6,%ymm13,%ymm13 + vpxor %ymm0,%ymm13,%ymm0 + vpslld $12,%ymm0,%ymm15 + vpsrld $20,%ymm0,%ymm0 + vpor %ymm0,%ymm15,%ymm0 + vpaddd %ymm3,%ymm10,%ymm10 + vpxor %ymm5,%ymm10,%ymm5 + vpshufb %ymm14,%ymm5,%ymm5 + vpaddd %ymm0,%ymm11,%ymm11 + vpxor %ymm6,%ymm11,%ymm6 + vpshufb %ymm14,%ymm6,%ymm6 + vpaddd %ymm5,%ymm12,%ymm12 + vpxor %ymm3,%ymm12,%ymm3 + vpslld $7,%ymm3,%ymm15 + vpsrld $25,%ymm3,%ymm3 + vpor %ymm3,%ymm15,%ymm3 + vbroadcasti128 (%r10),%ymm15 + vpaddd %ymm6,%ymm13,%ymm13 + vpxor %ymm0,%ymm13,%ymm0 + vpslld $7,%ymm0,%ymm14 + vpsrld $25,%ymm0,%ymm0 + vpor %ymm0,%ymm14,%ymm0 + decl %eax + jnz .Loop8x + + leaq 512(%rsp),%rax + vpaddd 128-256(%rcx),%ymm8,%ymm8 + vpaddd 160-256(%rcx),%ymm9,%ymm9 + vpaddd 192-256(%rcx),%ymm10,%ymm10 + vpaddd 224-256(%rcx),%ymm11,%ymm11 + + vpunpckldq %ymm9,%ymm8,%ymm14 + vpunpckldq %ymm11,%ymm10,%ymm15 + vpunpckhdq %ymm9,%ymm8,%ymm8 + vpunpckhdq %ymm11,%ymm10,%ymm10 + vpunpcklqdq %ymm15,%ymm14,%ymm9 + vpunpckhqdq %ymm15,%ymm14,%ymm14 + vpunpcklqdq %ymm10,%ymm8,%ymm11 + vpunpckhqdq %ymm10,%ymm8,%ymm8 + vpaddd 256-256(%rcx),%ymm0,%ymm0 + vpaddd 288-256(%rcx),%ymm1,%ymm1 + vpaddd 320-256(%rcx),%ymm2,%ymm2 + vpaddd 352-256(%rcx),%ymm3,%ymm3 + + vpunpckldq %ymm1,%ymm0,%ymm10 + vpunpckldq %ymm3,%ymm2,%ymm15 + vpunpckhdq %ymm1,%ymm0,%ymm0 + vpunpckhdq %ymm3,%ymm2,%ymm2 + vpunpcklqdq %ymm15,%ymm10,%ymm1 + vpunpckhqdq %ymm15,%ymm10,%ymm10 + vpunpcklqdq %ymm2,%ymm0,%ymm3 + vpunpckhqdq %ymm2,%ymm0,%ymm0 + vperm2i128 $0x20,%ymm1,%ymm9,%ymm15 + vperm2i128 $0x31,%ymm1,%ymm9,%ymm1 + vperm2i128 $0x20,%ymm10,%ymm14,%ymm9 + vperm2i128 $0x31,%ymm10,%ymm14,%ymm10 + vperm2i128 $0x20,%ymm3,%ymm11,%ymm14 + vperm2i128 $0x31,%ymm3,%ymm11,%ymm3 + vperm2i128 $0x20,%ymm0,%ymm8,%ymm11 + vperm2i128 $0x31,%ymm0,%ymm8,%ymm0 + vmovdqa %ymm15,0(%rsp) + vmovdqa %ymm9,32(%rsp) + vmovdqa 64(%rsp),%ymm15 + vmovdqa 96(%rsp),%ymm9 + + vpaddd 384-512(%rax),%ymm12,%ymm12 + vpaddd 416-512(%rax),%ymm13,%ymm13 + vpaddd 448-512(%rax),%ymm15,%ymm15 + vpaddd 480-512(%rax),%ymm9,%ymm9 + + vpunpckldq %ymm13,%ymm12,%ymm2 + vpunpckldq %ymm9,%ymm15,%ymm8 + vpunpckhdq %ymm13,%ymm12,%ymm12 + vpunpckhdq %ymm9,%ymm15,%ymm15 + vpunpcklqdq %ymm8,%ymm2,%ymm13 + vpunpckhqdq %ymm8,%ymm2,%ymm2 + vpunpcklqdq %ymm15,%ymm12,%ymm9 + vpunpckhqdq %ymm15,%ymm12,%ymm12 + vpaddd 512-512(%rax),%ymm4,%ymm4 + vpaddd 544-512(%rax),%ymm5,%ymm5 + vpaddd 576-512(%rax),%ymm6,%ymm6 + vpaddd 608-512(%rax),%ymm7,%ymm7 + + vpunpckldq %ymm5,%ymm4,%ymm15 + vpunpckldq %ymm7,%ymm6,%ymm8 + vpunpckhdq %ymm5,%ymm4,%ymm4 + vpunpckhdq %ymm7,%ymm6,%ymm6 + vpunpcklqdq %ymm8,%ymm15,%ymm5 + vpunpckhqdq %ymm8,%ymm15,%ymm15 + vpunpcklqdq %ymm6,%ymm4,%ymm7 + vpunpckhqdq %ymm6,%ymm4,%ymm4 + vperm2i128 $0x20,%ymm5,%ymm13,%ymm8 + vperm2i128 $0x31,%ymm5,%ymm13,%ymm5 + vperm2i128 $0x20,%ymm15,%ymm2,%ymm13 + vperm2i128 $0x31,%ymm15,%ymm2,%ymm15 + vperm2i128 $0x20,%ymm7,%ymm9,%ymm2 + vperm2i128 $0x31,%ymm7,%ymm9,%ymm7 + vperm2i128 $0x20,%ymm4,%ymm12,%ymm9 + vperm2i128 $0x31,%ymm4,%ymm12,%ymm4 + vmovdqa 0(%rsp),%ymm6 + vmovdqa 32(%rsp),%ymm12 + + cmpq $512,%rdx + jb .Ltail8x + + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + leaq 128(%rsi),%rsi + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + leaq 128(%rdi),%rdi + + vpxor 0(%rsi),%ymm12,%ymm12 + vpxor 32(%rsi),%ymm13,%ymm13 + vpxor 64(%rsi),%ymm10,%ymm10 + vpxor 96(%rsi),%ymm15,%ymm15 + leaq 128(%rsi),%rsi + vmovdqu %ymm12,0(%rdi) + vmovdqu %ymm13,32(%rdi) + vmovdqu %ymm10,64(%rdi) + vmovdqu %ymm15,96(%rdi) + leaq 128(%rdi),%rdi + + vpxor 0(%rsi),%ymm14,%ymm14 + vpxor 32(%rsi),%ymm2,%ymm2 + vpxor 64(%rsi),%ymm3,%ymm3 + vpxor 96(%rsi),%ymm7,%ymm7 + leaq 128(%rsi),%rsi + vmovdqu %ymm14,0(%rdi) + vmovdqu %ymm2,32(%rdi) + vmovdqu %ymm3,64(%rdi) + vmovdqu %ymm7,96(%rdi) + leaq 128(%rdi),%rdi + + vpxor 0(%rsi),%ymm11,%ymm11 + vpxor 32(%rsi),%ymm9,%ymm9 + vpxor 64(%rsi),%ymm0,%ymm0 + vpxor 96(%rsi),%ymm4,%ymm4 + leaq 128(%rsi),%rsi + vmovdqu %ymm11,0(%rdi) + vmovdqu %ymm9,32(%rdi) + vmovdqu %ymm0,64(%rdi) + vmovdqu %ymm4,96(%rdi) + leaq 128(%rdi),%rdi + + subq $512,%rdx + jnz .Loop_outer8x + + jmp .Ldone8x + +.Ltail8x: + cmpq $448,%rdx + jae .L448_or_more8x + cmpq $384,%rdx + jae .L384_or_more8x + cmpq $320,%rdx + jae .L320_or_more8x + cmpq $256,%rdx + jae .L256_or_more8x + cmpq $192,%rdx + jae .L192_or_more8x + cmpq $128,%rdx + jae .L128_or_more8x + cmpq $64,%rdx + jae .L64_or_more8x + + xorq %r10,%r10 + vmovdqa %ymm6,0(%rsp) + vmovdqa %ymm8,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L64_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + je .Ldone8x + + leaq 64(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm1,0(%rsp) + leaq 64(%rdi),%rdi + subq $64,%rdx + vmovdqa %ymm5,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L128_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + je .Ldone8x + + leaq 128(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm12,0(%rsp) + leaq 128(%rdi),%rdi + subq $128,%rdx + vmovdqa %ymm13,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L192_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + je .Ldone8x + + leaq 192(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm10,0(%rsp) + leaq 192(%rdi),%rdi + subq $192,%rdx + vmovdqa %ymm15,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L256_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + je .Ldone8x + + leaq 256(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm14,0(%rsp) + leaq 256(%rdi),%rdi + subq $256,%rdx + vmovdqa %ymm2,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L320_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vpxor 256(%rsi),%ymm14,%ymm14 + vpxor 288(%rsi),%ymm2,%ymm2 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + vmovdqu %ymm14,256(%rdi) + vmovdqu %ymm2,288(%rdi) + je .Ldone8x + + leaq 320(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm3,0(%rsp) + leaq 320(%rdi),%rdi + subq $320,%rdx + vmovdqa %ymm7,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L384_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vpxor 256(%rsi),%ymm14,%ymm14 + vpxor 288(%rsi),%ymm2,%ymm2 + vpxor 320(%rsi),%ymm3,%ymm3 + vpxor 352(%rsi),%ymm7,%ymm7 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + vmovdqu %ymm14,256(%rdi) + vmovdqu %ymm2,288(%rdi) + vmovdqu %ymm3,320(%rdi) + vmovdqu %ymm7,352(%rdi) + je .Ldone8x + + leaq 384(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm11,0(%rsp) + leaq 384(%rdi),%rdi + subq $384,%rdx + vmovdqa %ymm9,32(%rsp) + jmp .Loop_tail8x + +.align 32 +.L448_or_more8x: + vpxor 0(%rsi),%ymm6,%ymm6 + vpxor 32(%rsi),%ymm8,%ymm8 + vpxor 64(%rsi),%ymm1,%ymm1 + vpxor 96(%rsi),%ymm5,%ymm5 + vpxor 128(%rsi),%ymm12,%ymm12 + vpxor 160(%rsi),%ymm13,%ymm13 + vpxor 192(%rsi),%ymm10,%ymm10 + vpxor 224(%rsi),%ymm15,%ymm15 + vpxor 256(%rsi),%ymm14,%ymm14 + vpxor 288(%rsi),%ymm2,%ymm2 + vpxor 320(%rsi),%ymm3,%ymm3 + vpxor 352(%rsi),%ymm7,%ymm7 + vpxor 384(%rsi),%ymm11,%ymm11 + vpxor 416(%rsi),%ymm9,%ymm9 + vmovdqu %ymm6,0(%rdi) + vmovdqu %ymm8,32(%rdi) + vmovdqu %ymm1,64(%rdi) + vmovdqu %ymm5,96(%rdi) + vmovdqu %ymm12,128(%rdi) + vmovdqu %ymm13,160(%rdi) + vmovdqu %ymm10,192(%rdi) + vmovdqu %ymm15,224(%rdi) + vmovdqu %ymm14,256(%rdi) + vmovdqu %ymm2,288(%rdi) + vmovdqu %ymm3,320(%rdi) + vmovdqu %ymm7,352(%rdi) + vmovdqu %ymm11,384(%rdi) + vmovdqu %ymm9,416(%rdi) + je .Ldone8x + + leaq 448(%rsi),%rsi + xorq %r10,%r10 + vmovdqa %ymm0,0(%rsp) + leaq 448(%rdi),%rdi + subq $448,%rdx + vmovdqa %ymm4,32(%rsp) + +.Loop_tail8x: + movzbl (%rsi,%r10,1),%eax + movzbl (%rsp,%r10,1),%ecx + leaq 1(%r10),%r10 + xorl %ecx,%eax + movb %al,-1(%rdi,%r10,1) + decq %rdx + jnz .Loop_tail8x + +.Ldone8x: + vzeroall + leaq (%r9),%rsp +.cfi_def_cfa_register %rsp +.L8x_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ChaCha20_8x,.-ChaCha20_8x + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/chacha/chacha_enc.c b/crypto/openssl/crypto/chacha/chacha_enc.c index 18251eac08de..c5d1d63d8027 100644 --- a/crypto/openssl/crypto/chacha/chacha_enc.c +++ b/crypto/openssl/crypto/chacha/chacha_enc.c @@ -1,7 +1,7 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,6 +11,7 @@ #include +#include "internal/endian.h" #include "crypto/chacha.h" #include "crypto/ctype.h" @@ -43,10 +44,7 @@ static void chacha20_core(chacha_buf *output, const u32 input[16]) { u32 x[16]; int i; - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; memcpy(x, input, sizeof(x)); @@ -61,7 +59,7 @@ static void chacha20_core(chacha_buf *output, const u32 input[16]) QUARTERROUND(3, 4, 9, 14); } - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { for (i = 0; i < 16; ++i) output->u[i] = x[i] + input[i]; } else { diff --git a/crypto/openssl/crypto/chacha/chacha_ppc.c b/crypto/openssl/crypto/chacha/chacha_ppc.c new file mode 100644 index 000000000000..5319040cc167 --- /dev/null +++ b/crypto/openssl/crypto/chacha/chacha_ppc.c @@ -0,0 +1,35 @@ +/* + * Copyright 2009-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +#include +#include "crypto/chacha.h" +#include "crypto/ppc_arch.h" + +void ChaCha20_ctr32_int(unsigned char *out, const unsigned char *inp, + size_t len, const unsigned int key[8], + const unsigned int counter[4]); +void ChaCha20_ctr32_vmx(unsigned char *out, const unsigned char *inp, + size_t len, const unsigned int key[8], + const unsigned int counter[4]); +void ChaCha20_ctr32_vsx(unsigned char *out, const unsigned char *inp, + size_t len, const unsigned int key[8], + const unsigned int counter[4]); +void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, + size_t len, const unsigned int key[8], + const unsigned int counter[4]) +{ + OPENSSL_ppccap_P & PPC_CRYPTO207 + ? ChaCha20_ctr32_vsx(out, inp, len, key, counter) + : OPENSSL_ppccap_P & PPC_ALTIVEC + ? ChaCha20_ctr32_vmx(out, inp, len, key, counter) + : ChaCha20_ctr32_int(out, inp, len, key, counter); +} diff --git a/crypto/openssl/crypto/cmac/build.info b/crypto/openssl/crypto/cmac/build.info index c8a4949a0729..0c0e50941f67 100644 --- a/crypto/openssl/crypto/cmac/build.info +++ b/crypto/openssl/crypto/cmac/build.info @@ -1,2 +1,6 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=cmac.c cm_ameth.c cm_pmeth.c + +$COMMON=cmac.c + +SOURCE[../../libcrypto]=$COMMON +SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/openssl/crypto/cmac/cm_ameth.c b/crypto/openssl/crypto/cmac/cm_ameth.c deleted file mode 100644 index 82adf18c8019..000000000000 --- a/crypto/openssl/crypto/cmac/cm_ameth.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2010-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 - */ - -#include -#include "internal/cryptlib.h" -#include -#include -#include "crypto/asn1.h" - -/* - * CMAC "ASN1" method. This is just here to indicate the maximum CMAC output - * length and to free up a CMAC key. - */ - -static int cmac_size(const EVP_PKEY *pkey) -{ - return EVP_MAX_BLOCK_LENGTH; -} - -static void cmac_key_free(EVP_PKEY *pkey) -{ - CMAC_CTX *cmctx = EVP_PKEY_get0(pkey); - CMAC_CTX_free(cmctx); -} - -const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = { - EVP_PKEY_CMAC, - EVP_PKEY_CMAC, - 0, - - "CMAC", - "OpenSSL CMAC method", - - 0, 0, 0, 0, - - 0, 0, 0, - - cmac_size, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, - - cmac_key_free, - 0, - 0, 0 -}; diff --git a/crypto/openssl/crypto/cmac/cm_pmeth.c b/crypto/openssl/crypto/cmac/cm_pmeth.c deleted file mode 100644 index 5574f25be868..000000000000 --- a/crypto/openssl/crypto/cmac/cm_pmeth.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2010-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 - */ - -#include -#include "internal/cryptlib.h" -#include -#include -#include -#include -#include "crypto/evp.h" - -/* The context structure and "key" is simply a CMAC_CTX */ - -static int pkey_cmac_init(EVP_PKEY_CTX *ctx) -{ - ctx->data = CMAC_CTX_new(); - if (ctx->data == NULL) - return 0; - ctx->keygen_info_count = 0; - return 1; -} - -static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - if (!pkey_cmac_init(dst)) - return 0; - if (!CMAC_CTX_copy(dst->data, src->data)) - return 0; - return 1; -} - -static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx) -{ - CMAC_CTX_free(ctx->data); -} - -static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - CMAC_CTX *cmkey = CMAC_CTX_new(); - CMAC_CTX *cmctx = ctx->data; - if (cmkey == NULL) - return 0; - if (!CMAC_CTX_copy(cmkey, cmctx)) { - CMAC_CTX_free(cmkey); - return 0; - } - EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey); - - return 1; -} - -static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - if (!CMAC_Update(EVP_MD_CTX_pkey_ctx(ctx)->data, data, count)) - return 0; - return 1; -} - -static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -{ - EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); - EVP_MD_CTX_set_update_fn(mctx, int_update); - return 1; -} - -static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - EVP_MD_CTX *mctx) -{ - return CMAC_Final(ctx->data, sig, siglen); -} - -static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - CMAC_CTX *cmctx = ctx->data; - switch (type) { - - case EVP_PKEY_CTRL_SET_MAC_KEY: - if (!p2 || p1 < 0) - return 0; - if (!CMAC_Init(cmctx, p2, p1, NULL, NULL)) - return 0; - break; - - case EVP_PKEY_CTRL_CIPHER: - if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine)) - return 0; - break; - - case EVP_PKEY_CTRL_MD: - if (ctx->pkey && !CMAC_CTX_copy(ctx->data, - (CMAC_CTX *)ctx->pkey->pkey.ptr)) - return 0; - if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL)) - return 0; - break; - - default: - return -2; - - } - return 1; -} - -static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (!value) { - return 0; - } - if (strcmp(type, "cipher") == 0) { - const EVP_CIPHER *c; - c = EVP_get_cipherbyname(value); - if (!c) - return 0; - return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c); - } - if (strcmp(type, "key") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); - if (strcmp(type, "hexkey") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); - return -2; -} - -const EVP_PKEY_METHOD cmac_pkey_meth = { - EVP_PKEY_CMAC, - EVP_PKEY_FLAG_SIGCTX_CUSTOM, - pkey_cmac_init, - pkey_cmac_copy, - pkey_cmac_cleanup, - - 0, 0, - - 0, - pkey_cmac_keygen, - - 0, 0, - - 0, 0, - - 0, 0, - - cmac_signctx_init, - cmac_signctx, - - 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_cmac_ctrl, - pkey_cmac_ctrl_str -}; diff --git a/crypto/openssl/crypto/cmac/cmac.c b/crypto/openssl/crypto/cmac/cmac.c index 1fac53101687..7f94727085e5 100644 --- a/crypto/openssl/crypto/cmac/cmac.c +++ b/crypto/openssl/crypto/cmac/cmac.c @@ -1,12 +1,18 @@ /* - * Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2010-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * CMAC low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include #include @@ -48,7 +54,7 @@ CMAC_CTX *CMAC_CTX_new(void) CMAC_CTX *ctx; if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL) { - CRYPTOerr(CRYPTO_F_CMAC_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return NULL; } ctx->cctx = EVP_CIPHER_CTX_new(); @@ -87,11 +93,13 @@ void CMAC_CTX_free(CMAC_CTX *ctx) int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in) { int bl; + if (in->nlast_block == -1) return 0; + if ((bl = EVP_CIPHER_CTX_get_block_size(in->cctx)) < 0) + return 0; if (!EVP_CIPHER_CTX_copy(out->cctx, in->cctx)) return 0; - bl = EVP_CIPHER_CTX_block_size(in->cctx); memcpy(out->k1, in->k1, bl); memcpy(out->k2, in->k2, bl); memcpy(out->tbl, in->tbl, bl); @@ -104,6 +112,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, const EVP_CIPHER *cipher, ENGINE *impl) { static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH] = { 0 }; + /* All zeros means restart */ if (!key && !cipher && !impl && keylen == 0) { /* Not initialised */ @@ -111,7 +120,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, return 0; if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv)) return 0; - memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(ctx->cctx)); + memset(ctx->tbl, 0, EVP_CIPHER_CTX_get_block_size(ctx->cctx)); ctx->nlast_block = 0; return 1; } @@ -128,13 +137,14 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, /* If anything fails then ensure we can't use this ctx */ ctx->nlast_block = -1; - if (!EVP_CIPHER_CTX_cipher(ctx->cctx)) + if (EVP_CIPHER_CTX_get0_cipher(ctx->cctx) == NULL) return 0; - if (!EVP_CIPHER_CTX_set_key_length(ctx->cctx, keylen)) + if (EVP_CIPHER_CTX_set_key_length(ctx->cctx, keylen) <= 0) return 0; if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, key, zero_iv)) return 0; - bl = EVP_CIPHER_CTX_block_size(ctx->cctx); + if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) < 0) + return 0; if (EVP_Cipher(ctx->cctx, ctx->tbl, zero_iv, bl) <= 0) return 0; make_kn(ctx->k1, ctx->tbl, bl); @@ -153,15 +163,18 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) { const unsigned char *data = in; - size_t bl; + int bl; + if (ctx->nlast_block == -1) return 0; if (dlen == 0) return 1; - bl = EVP_CIPHER_CTX_block_size(ctx->cctx); + if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) < 0) + return 0; /* Copy into partial block if we need to */ if (ctx->nlast_block > 0) { size_t nleft; + nleft = bl - ctx->nlast_block; if (dlen < nleft) nleft = dlen; @@ -177,7 +190,7 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) return 0; } /* Encrypt all but one of the complete blocks left */ - while (dlen > bl) { + while (dlen > (size_t)bl) { if (EVP_Cipher(ctx->cctx, ctx->tbl, data, bl) <= 0) return 0; dlen -= bl; @@ -193,10 +206,13 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) { int i, bl, lb; + if (ctx->nlast_block == -1) return 0; - bl = EVP_CIPHER_CTX_block_size(ctx->cctx); - *poutlen = (size_t)bl; + if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) < 0) + return 0; + if (poutlen != NULL) + *poutlen = (size_t)bl; if (!out) return 1; lb = ctx->nlast_block; @@ -211,7 +227,7 @@ int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) for (i = 0; i < bl; i++) out[i] = ctx->last_block[i] ^ ctx->k2[i]; } - if (!EVP_Cipher(ctx->cctx, out, out, bl)) { + if (EVP_Cipher(ctx->cctx, out, out, bl) <= 0) { OPENSSL_cleanse(out, bl); return 0; } diff --git a/crypto/openssl/crypto/cmp/build.info b/crypto/openssl/crypto/cmp/build.info new file mode 100644 index 000000000000..a2a57c14ec10 --- /dev/null +++ b/crypto/openssl/crypto/cmp/build.info @@ -0,0 +1,4 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \ + cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c \ + cmp_server.c cmp_client.c cmp_http.c diff --git a/crypto/openssl/crypto/cmp/cmp_asn.c b/crypto/openssl/crypto/cmp/cmp_asn.c new file mode 100644 index 000000000000..0ca107554c96 --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_asn.c @@ -0,0 +1,459 @@ +/* + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include "cmp_local.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include + +/* ASN.1 declarations from RFC4210 */ +ASN1_SEQUENCE(OSSL_CMP_REVANNCONTENT) = { + /* OSSL_CMP_PKISTATUS is effectively ASN1_INTEGER so it is used directly */ + ASN1_SIMPLE(OSSL_CMP_REVANNCONTENT, status, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CMP_REVANNCONTENT, certId, OSSL_CRMF_CERTID), + ASN1_SIMPLE(OSSL_CMP_REVANNCONTENT, willBeRevokedAt, ASN1_GENERALIZEDTIME), + ASN1_SIMPLE(OSSL_CMP_REVANNCONTENT, badSinceDate, ASN1_GENERALIZEDTIME), + ASN1_OPT(OSSL_CMP_REVANNCONTENT, crlDetails, X509_EXTENSIONS) +} ASN1_SEQUENCE_END(OSSL_CMP_REVANNCONTENT) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_REVANNCONTENT) + + +ASN1_SEQUENCE(OSSL_CMP_CHALLENGE) = { + ASN1_OPT(OSSL_CMP_CHALLENGE, owf, X509_ALGOR), + ASN1_SIMPLE(OSSL_CMP_CHALLENGE, witness, ASN1_OCTET_STRING), + ASN1_SIMPLE(OSSL_CMP_CHALLENGE, challenge, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(OSSL_CMP_CHALLENGE) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CHALLENGE) + + +ASN1_ITEM_TEMPLATE(OSSL_CMP_POPODECKEYCHALLCONTENT) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, + OSSL_CMP_POPODECKEYCHALLCONTENT, OSSL_CMP_CHALLENGE) +ASN1_ITEM_TEMPLATE_END(OSSL_CMP_POPODECKEYCHALLCONTENT) + + +ASN1_ITEM_TEMPLATE(OSSL_CMP_POPODECKEYRESPCONTENT) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, + OSSL_CMP_POPODECKEYRESPCONTENT, ASN1_INTEGER) +ASN1_ITEM_TEMPLATE_END(OSSL_CMP_POPODECKEYRESPCONTENT) + + +ASN1_SEQUENCE(OSSL_CMP_CAKEYUPDANNCONTENT) = { + /* OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly */ + ASN1_SIMPLE(OSSL_CMP_CAKEYUPDANNCONTENT, oldWithNew, X509), + /* OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly */ + ASN1_SIMPLE(OSSL_CMP_CAKEYUPDANNCONTENT, newWithOld, X509), + /* OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly */ + ASN1_SIMPLE(OSSL_CMP_CAKEYUPDANNCONTENT, newWithNew, X509) +} ASN1_SEQUENCE_END(OSSL_CMP_CAKEYUPDANNCONTENT) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT) + + +ASN1_SEQUENCE(OSSL_CMP_ERRORMSGCONTENT) = { + ASN1_SIMPLE(OSSL_CMP_ERRORMSGCONTENT, pKIStatusInfo, OSSL_CMP_PKISI), + ASN1_OPT(OSSL_CMP_ERRORMSGCONTENT, errorCode, ASN1_INTEGER), + /* + * OSSL_CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING + * so it is used directly + * + */ + ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ERRORMSGCONTENT, errorDetails, + ASN1_UTF8STRING) +} ASN1_SEQUENCE_END(OSSL_CMP_ERRORMSGCONTENT) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_ERRORMSGCONTENT) + +ASN1_ADB_TEMPLATE(infotypeandvalue_default) = ASN1_OPT(OSSL_CMP_ITAV, + infoValue.other, + ASN1_ANY); +/* ITAV means InfoTypeAndValue */ +ASN1_ADB(OSSL_CMP_ITAV) = { + /* OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly */ + ADB_ENTRY(NID_id_it_caProtEncCert, ASN1_OPT(OSSL_CMP_ITAV, + infoValue.caProtEncCert, X509)), + ADB_ENTRY(NID_id_it_signKeyPairTypes, + ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, + infoValue.signKeyPairTypes, X509_ALGOR)), + ADB_ENTRY(NID_id_it_encKeyPairTypes, + ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, + infoValue.encKeyPairTypes, X509_ALGOR)), + ADB_ENTRY(NID_id_it_preferredSymmAlg, + ASN1_OPT(OSSL_CMP_ITAV, infoValue.preferredSymmAlg, + X509_ALGOR)), + ADB_ENTRY(NID_id_it_caKeyUpdateInfo, + ASN1_OPT(OSSL_CMP_ITAV, infoValue.caKeyUpdateInfo, + OSSL_CMP_CAKEYUPDANNCONTENT)), + ADB_ENTRY(NID_id_it_currentCRL, + ASN1_OPT(OSSL_CMP_ITAV, infoValue.currentCRL, X509_CRL)), + ADB_ENTRY(NID_id_it_unsupportedOIDs, + ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, + infoValue.unsupportedOIDs, ASN1_OBJECT)), + ADB_ENTRY(NID_id_it_keyPairParamReq, + ASN1_OPT(OSSL_CMP_ITAV, infoValue.keyPairParamReq, + ASN1_OBJECT)), + ADB_ENTRY(NID_id_it_keyPairParamRep, + ASN1_OPT(OSSL_CMP_ITAV, infoValue.keyPairParamRep, + X509_ALGOR)), + ADB_ENTRY(NID_id_it_revPassphrase, + ASN1_OPT(OSSL_CMP_ITAV, infoValue.revPassphrase, + OSSL_CRMF_ENCRYPTEDVALUE)), + ADB_ENTRY(NID_id_it_implicitConfirm, + ASN1_OPT(OSSL_CMP_ITAV, infoValue.implicitConfirm, + ASN1_NULL)), + ADB_ENTRY(NID_id_it_confirmWaitTime, + ASN1_OPT(OSSL_CMP_ITAV, infoValue.confirmWaitTime, + ASN1_GENERALIZEDTIME)), + ADB_ENTRY(NID_id_it_origPKIMessage, + ASN1_OPT(OSSL_CMP_ITAV, infoValue.origPKIMessage, + OSSL_CMP_MSGS)), + ADB_ENTRY(NID_id_it_suppLangTags, + ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.suppLangTagsValue, + ASN1_UTF8STRING)), +} ASN1_ADB_END(OSSL_CMP_ITAV, 0, infoType, 0, + &infotypeandvalue_default_tt, NULL); + + +ASN1_SEQUENCE(OSSL_CMP_ITAV) = { + ASN1_SIMPLE(OSSL_CMP_ITAV, infoType, ASN1_OBJECT), + ASN1_ADB_OBJECT(OSSL_CMP_ITAV) +} ASN1_SEQUENCE_END(OSSL_CMP_ITAV) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_ITAV) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV) + +OSSL_CMP_ITAV *OSSL_CMP_ITAV_create(ASN1_OBJECT *type, ASN1_TYPE *value) +{ + OSSL_CMP_ITAV *itav; + + if (type == NULL || (itav = OSSL_CMP_ITAV_new()) == NULL) + return NULL; + OSSL_CMP_ITAV_set0(itav, type, value); + return itav; +} + +void OSSL_CMP_ITAV_set0(OSSL_CMP_ITAV *itav, ASN1_OBJECT *type, + ASN1_TYPE *value) +{ + itav->infoType = type; + itav->infoValue.other = value; +} + +ASN1_OBJECT *OSSL_CMP_ITAV_get0_type(const OSSL_CMP_ITAV *itav) +{ + if (itav == NULL) + return NULL; + return itav->infoType; +} + +ASN1_TYPE *OSSL_CMP_ITAV_get0_value(const OSSL_CMP_ITAV *itav) +{ + if (itav == NULL) + return NULL; + return itav->infoValue.other; +} + +int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p, + OSSL_CMP_ITAV *itav) +{ + int created = 0; + + if (itav_sk_p == NULL || itav == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + goto err; + } + + if (*itav_sk_p == NULL) { + if ((*itav_sk_p = sk_OSSL_CMP_ITAV_new_null()) == NULL) + goto err; + created = 1; + } + if (!sk_OSSL_CMP_ITAV_push(*itav_sk_p, itav)) + goto err; + return 1; + + err: + if (created != 0) { + sk_OSSL_CMP_ITAV_free(*itav_sk_p); + *itav_sk_p = NULL; + } + return 0; +} + +/* get ASN.1 encoded integer, return -1 on error */ +int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a) +{ + int64_t res; + + if (!ASN1_INTEGER_get_int64(&res, a)) { + ERR_raise(ERR_LIB_CMP, ASN1_R_INVALID_NUMBER); + return -1; + } + if (res < INT_MIN) { + ERR_raise(ERR_LIB_CMP, ASN1_R_TOO_SMALL); + return -1; + } + if (res > INT_MAX) { + ERR_raise(ERR_LIB_CMP, ASN1_R_TOO_LARGE); + return -1; + } + return (int)res; +} + +static int ossl_cmp_msg_cb(int operation, ASN1_VALUE **pval, + const ASN1_ITEM *it, void *exarg) +{ + OSSL_CMP_MSG *msg = (OSSL_CMP_MSG *)*pval; + + switch (operation) { + case ASN1_OP_FREE_POST: + OPENSSL_free(msg->propq); + break; + + case ASN1_OP_DUP_POST: + { + OSSL_CMP_MSG *old = exarg; + + if (!ossl_cmp_msg_set0_libctx(msg, old->libctx, old->propq)) + return 0; + } + break; + case ASN1_OP_GET0_LIBCTX: + { + OSSL_LIB_CTX **libctx = exarg; + + *libctx = msg->libctx; + } + break; + case ASN1_OP_GET0_PROPQ: + { + const char **propq = exarg; + + *propq = msg->propq; + } + break; + default: + break; + } + + return 1; +} + +ASN1_CHOICE(OSSL_CMP_CERTORENCCERT) = { + /* OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly */ + ASN1_EXP(OSSL_CMP_CERTORENCCERT, value.certificate, X509, 0), + ASN1_EXP(OSSL_CMP_CERTORENCCERT, value.encryptedCert, + OSSL_CRMF_ENCRYPTEDVALUE, 1), +} ASN1_CHOICE_END(OSSL_CMP_CERTORENCCERT) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CERTORENCCERT) + + +ASN1_SEQUENCE(OSSL_CMP_CERTIFIEDKEYPAIR) = { + ASN1_SIMPLE(OSSL_CMP_CERTIFIEDKEYPAIR, certOrEncCert, + OSSL_CMP_CERTORENCCERT), + ASN1_EXP_OPT(OSSL_CMP_CERTIFIEDKEYPAIR, privateKey, + OSSL_CRMF_ENCRYPTEDVALUE, 0), + ASN1_EXP_OPT(OSSL_CMP_CERTIFIEDKEYPAIR, publicationInfo, + OSSL_CRMF_PKIPUBLICATIONINFO, 1) +} ASN1_SEQUENCE_END(OSSL_CMP_CERTIFIEDKEYPAIR) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CERTIFIEDKEYPAIR) + + +ASN1_SEQUENCE(OSSL_CMP_REVDETAILS) = { + ASN1_SIMPLE(OSSL_CMP_REVDETAILS, certDetails, OSSL_CRMF_CERTTEMPLATE), + ASN1_OPT(OSSL_CMP_REVDETAILS, crlEntryDetails, X509_EXTENSIONS) +} ASN1_SEQUENCE_END(OSSL_CMP_REVDETAILS) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_REVDETAILS) + + +ASN1_ITEM_TEMPLATE(OSSL_CMP_REVREQCONTENT) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, OSSL_CMP_REVREQCONTENT, + OSSL_CMP_REVDETAILS) +ASN1_ITEM_TEMPLATE_END(OSSL_CMP_REVREQCONTENT) + + +ASN1_SEQUENCE(OSSL_CMP_REVREPCONTENT) = { + ASN1_SEQUENCE_OF(OSSL_CMP_REVREPCONTENT, status, OSSL_CMP_PKISI), + ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_REVREPCONTENT, revCerts, OSSL_CRMF_CERTID, + 0), + ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_REVREPCONTENT, crls, X509_CRL, 1) +} ASN1_SEQUENCE_END(OSSL_CMP_REVREPCONTENT) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_REVREPCONTENT) + + +ASN1_SEQUENCE(OSSL_CMP_KEYRECREPCONTENT) = { + ASN1_SIMPLE(OSSL_CMP_KEYRECREPCONTENT, status, OSSL_CMP_PKISI), + ASN1_EXP_OPT(OSSL_CMP_KEYRECREPCONTENT, newSigCert, X509, 0), + ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_KEYRECREPCONTENT, caCerts, X509, 1), + ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_KEYRECREPCONTENT, keyPairHist, + OSSL_CMP_CERTIFIEDKEYPAIR, 2) +} ASN1_SEQUENCE_END(OSSL_CMP_KEYRECREPCONTENT) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_KEYRECREPCONTENT) + + +ASN1_ITEM_TEMPLATE(OSSL_CMP_PKISTATUS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_UNIVERSAL, 0, status, ASN1_INTEGER) +ASN1_ITEM_TEMPLATE_END(OSSL_CMP_PKISTATUS) + +ASN1_SEQUENCE(OSSL_CMP_PKISI) = { + ASN1_SIMPLE(OSSL_CMP_PKISI, status, OSSL_CMP_PKISTATUS), + /* + * CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING + * so it is used directly + */ + ASN1_SEQUENCE_OF_OPT(OSSL_CMP_PKISI, statusString, ASN1_UTF8STRING), + /* + * OSSL_CMP_PKIFAILUREINFO is effectively ASN1_BIT_STRING so used directly + */ + ASN1_OPT(OSSL_CMP_PKISI, failInfo, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(OSSL_CMP_PKISI) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_PKISI) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI) + +ASN1_SEQUENCE(OSSL_CMP_CERTSTATUS) = { + ASN1_SIMPLE(OSSL_CMP_CERTSTATUS, certHash, ASN1_OCTET_STRING), + ASN1_SIMPLE(OSSL_CMP_CERTSTATUS, certReqId, ASN1_INTEGER), + ASN1_OPT(OSSL_CMP_CERTSTATUS, statusInfo, OSSL_CMP_PKISI) +} ASN1_SEQUENCE_END(OSSL_CMP_CERTSTATUS) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CERTSTATUS) + +ASN1_ITEM_TEMPLATE(OSSL_CMP_CERTCONFIRMCONTENT) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, OSSL_CMP_CERTCONFIRMCONTENT, + OSSL_CMP_CERTSTATUS) +ASN1_ITEM_TEMPLATE_END(OSSL_CMP_CERTCONFIRMCONTENT) + +ASN1_SEQUENCE(OSSL_CMP_CERTRESPONSE) = { + ASN1_SIMPLE(OSSL_CMP_CERTRESPONSE, certReqId, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CMP_CERTRESPONSE, status, OSSL_CMP_PKISI), + ASN1_OPT(OSSL_CMP_CERTRESPONSE, certifiedKeyPair, + OSSL_CMP_CERTIFIEDKEYPAIR), + ASN1_OPT(OSSL_CMP_CERTRESPONSE, rspInfo, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(OSSL_CMP_CERTRESPONSE) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CERTRESPONSE) + +ASN1_SEQUENCE(OSSL_CMP_POLLREQ) = { + ASN1_SIMPLE(OSSL_CMP_POLLREQ, certReqId, ASN1_INTEGER) +} ASN1_SEQUENCE_END(OSSL_CMP_POLLREQ) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_POLLREQ) + +ASN1_ITEM_TEMPLATE(OSSL_CMP_POLLREQCONTENT) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, OSSL_CMP_POLLREQCONTENT, + OSSL_CMP_POLLREQ) +ASN1_ITEM_TEMPLATE_END(OSSL_CMP_POLLREQCONTENT) + +ASN1_SEQUENCE(OSSL_CMP_POLLREP) = { + ASN1_SIMPLE(OSSL_CMP_POLLREP, certReqId, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CMP_POLLREP, checkAfter, ASN1_INTEGER), + ASN1_SEQUENCE_OF_OPT(OSSL_CMP_POLLREP, reason, ASN1_UTF8STRING), +} ASN1_SEQUENCE_END(OSSL_CMP_POLLREP) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_POLLREP) + +ASN1_ITEM_TEMPLATE(OSSL_CMP_POLLREPCONTENT) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, + OSSL_CMP_POLLREPCONTENT, + OSSL_CMP_POLLREP) +ASN1_ITEM_TEMPLATE_END(OSSL_CMP_POLLREPCONTENT) + +ASN1_SEQUENCE(OSSL_CMP_CERTREPMESSAGE) = { + /* OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly */ + ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_CERTREPMESSAGE, caPubs, X509, 1), + ASN1_SEQUENCE_OF(OSSL_CMP_CERTREPMESSAGE, response, OSSL_CMP_CERTRESPONSE) +} ASN1_SEQUENCE_END(OSSL_CMP_CERTREPMESSAGE) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CERTREPMESSAGE) + +ASN1_ITEM_TEMPLATE(OSSL_CMP_GENMSGCONTENT) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, OSSL_CMP_GENMSGCONTENT, + OSSL_CMP_ITAV) +ASN1_ITEM_TEMPLATE_END(OSSL_CMP_GENMSGCONTENT) + +ASN1_ITEM_TEMPLATE(OSSL_CMP_GENREPCONTENT) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, OSSL_CMP_GENREPCONTENT, + OSSL_CMP_ITAV) +ASN1_ITEM_TEMPLATE_END(OSSL_CMP_GENREPCONTENT) + +ASN1_ITEM_TEMPLATE(OSSL_CMP_CRLANNCONTENT) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, + OSSL_CMP_CRLANNCONTENT, X509_CRL) +ASN1_ITEM_TEMPLATE_END(OSSL_CMP_CRLANNCONTENT) + +ASN1_CHOICE(OSSL_CMP_PKIBODY) = { + ASN1_EXP(OSSL_CMP_PKIBODY, value.ir, OSSL_CRMF_MSGS, 0), + ASN1_EXP(OSSL_CMP_PKIBODY, value.ip, OSSL_CMP_CERTREPMESSAGE, 1), + ASN1_EXP(OSSL_CMP_PKIBODY, value.cr, OSSL_CRMF_MSGS, 2), + ASN1_EXP(OSSL_CMP_PKIBODY, value.cp, OSSL_CMP_CERTREPMESSAGE, 3), + ASN1_EXP(OSSL_CMP_PKIBODY, value.p10cr, X509_REQ, 4), + ASN1_EXP(OSSL_CMP_PKIBODY, value.popdecc, + OSSL_CMP_POPODECKEYCHALLCONTENT, 5), + ASN1_EXP(OSSL_CMP_PKIBODY, value.popdecr, + OSSL_CMP_POPODECKEYRESPCONTENT, 6), + ASN1_EXP(OSSL_CMP_PKIBODY, value.kur, OSSL_CRMF_MSGS, 7), + ASN1_EXP(OSSL_CMP_PKIBODY, value.kup, OSSL_CMP_CERTREPMESSAGE, 8), + ASN1_EXP(OSSL_CMP_PKIBODY, value.krr, OSSL_CRMF_MSGS, 9), + ASN1_EXP(OSSL_CMP_PKIBODY, value.krp, OSSL_CMP_KEYRECREPCONTENT, 10), + ASN1_EXP(OSSL_CMP_PKIBODY, value.rr, OSSL_CMP_REVREQCONTENT, 11), + ASN1_EXP(OSSL_CMP_PKIBODY, value.rp, OSSL_CMP_REVREPCONTENT, 12), + ASN1_EXP(OSSL_CMP_PKIBODY, value.ccr, OSSL_CRMF_MSGS, 13), + ASN1_EXP(OSSL_CMP_PKIBODY, value.ccp, OSSL_CMP_CERTREPMESSAGE, 14), + ASN1_EXP(OSSL_CMP_PKIBODY, value.ckuann, OSSL_CMP_CAKEYUPDANNCONTENT, 15), + ASN1_EXP(OSSL_CMP_PKIBODY, value.cann, X509, 16), + ASN1_EXP(OSSL_CMP_PKIBODY, value.rann, OSSL_CMP_REVANNCONTENT, 17), + ASN1_EXP(OSSL_CMP_PKIBODY, value.crlann, OSSL_CMP_CRLANNCONTENT, 18), + ASN1_EXP(OSSL_CMP_PKIBODY, value.pkiconf, ASN1_ANY, 19), + ASN1_EXP(OSSL_CMP_PKIBODY, value.nested, OSSL_CMP_MSGS, 20), + ASN1_EXP(OSSL_CMP_PKIBODY, value.genm, OSSL_CMP_GENMSGCONTENT, 21), + ASN1_EXP(OSSL_CMP_PKIBODY, value.genp, OSSL_CMP_GENREPCONTENT, 22), + ASN1_EXP(OSSL_CMP_PKIBODY, value.error, OSSL_CMP_ERRORMSGCONTENT, 23), + ASN1_EXP(OSSL_CMP_PKIBODY, value.certConf, OSSL_CMP_CERTCONFIRMCONTENT, 24), + ASN1_EXP(OSSL_CMP_PKIBODY, value.pollReq, OSSL_CMP_POLLREQCONTENT, 25), + ASN1_EXP(OSSL_CMP_PKIBODY, value.pollRep, OSSL_CMP_POLLREPCONTENT, 26), +} ASN1_CHOICE_END(OSSL_CMP_PKIBODY) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_PKIBODY) + +ASN1_SEQUENCE(OSSL_CMP_PKIHEADER) = { + ASN1_SIMPLE(OSSL_CMP_PKIHEADER, pvno, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CMP_PKIHEADER, sender, GENERAL_NAME), + ASN1_SIMPLE(OSSL_CMP_PKIHEADER, recipient, GENERAL_NAME), + ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, messageTime, ASN1_GENERALIZEDTIME, 0), + ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, protectionAlg, X509_ALGOR, 1), + ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, senderKID, ASN1_OCTET_STRING, 2), + ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, recipKID, ASN1_OCTET_STRING, 3), + ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, transactionID, ASN1_OCTET_STRING, 4), + ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, senderNonce, ASN1_OCTET_STRING, 5), + ASN1_EXP_OPT(OSSL_CMP_PKIHEADER, recipNonce, ASN1_OCTET_STRING, 6), + /* + * OSSL_CMP_PKIFREETEXT is effectively a sequence of ASN1_UTF8STRING + * so it is used directly + */ + ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_PKIHEADER, freeText, ASN1_UTF8STRING, 7), + ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_PKIHEADER, generalInfo, + OSSL_CMP_ITAV, 8) +} ASN1_SEQUENCE_END(OSSL_CMP_PKIHEADER) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_PKIHEADER) + +ASN1_SEQUENCE(OSSL_CMP_PROTECTEDPART) = { + ASN1_SIMPLE(OSSL_CMP_MSG, header, OSSL_CMP_PKIHEADER), + ASN1_SIMPLE(OSSL_CMP_MSG, body, OSSL_CMP_PKIBODY) +} ASN1_SEQUENCE_END(OSSL_CMP_PROTECTEDPART) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_PROTECTEDPART) + +ASN1_SEQUENCE_cb(OSSL_CMP_MSG, ossl_cmp_msg_cb) = { + ASN1_SIMPLE(OSSL_CMP_MSG, header, OSSL_CMP_PKIHEADER), + ASN1_SIMPLE(OSSL_CMP_MSG, body, OSSL_CMP_PKIBODY), + ASN1_EXP_OPT(OSSL_CMP_MSG, protection, ASN1_BIT_STRING, 0), + /* OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly */ + ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_MSG, extraCerts, X509, 1) +} ASN1_SEQUENCE_END_cb(OSSL_CMP_MSG, OSSL_CMP_MSG) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CMP_MSG) + +ASN1_ITEM_TEMPLATE(OSSL_CMP_MSGS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, OSSL_CMP_MSGS, + OSSL_CMP_MSG) +ASN1_ITEM_TEMPLATE_END(OSSL_CMP_MSGS) diff --git a/crypto/openssl/crypto/cmp/cmp_client.c b/crypto/openssl/crypto/cmp/cmp_client.c new file mode 100644 index 000000000000..22ae7d07e82d --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_client.c @@ -0,0 +1,890 @@ +/* + * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "cmp_local.h" +#include "internal/cryptlib.h" +#include "e_os.h" /* ossl_sleep() */ + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include +#include +#include +#include + +#define IS_CREP(t) ((t) == OSSL_CMP_PKIBODY_IP || (t) == OSSL_CMP_PKIBODY_CP \ + || (t) == OSSL_CMP_PKIBODY_KUP) + +/*- + * Evaluate whether there's an exception (violating the standard) configured for + * handling negative responses without protection or with invalid protection. + * Returns 1 on acceptance, 0 on rejection, or -1 on (internal) error. + */ +static int unprotected_exception(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *rep, + int invalid_protection, + int expected_type /* ignored here */) +{ + int rcvd_type = OSSL_CMP_MSG_get_bodytype(rep /* may be NULL */); + const char *msg_type = NULL; + + if (!ossl_assert(ctx != NULL && rep != NULL)) + return -1; + + if (!ctx->unprotectedErrors) + return 0; + + switch (rcvd_type) { + case OSSL_CMP_PKIBODY_ERROR: + msg_type = "error response"; + break; + case OSSL_CMP_PKIBODY_RP: + { + OSSL_CMP_PKISI *si = + ossl_cmp_revrepcontent_get_pkisi(rep->body->value.rp, + OSSL_CMP_REVREQSID); + + if (si == NULL) + return -1; + if (ossl_cmp_pkisi_get_status(si) == OSSL_CMP_PKISTATUS_rejection) + msg_type = "revocation response message with rejection status"; + break; + } + case OSSL_CMP_PKIBODY_PKICONF: + msg_type = "PKI Confirmation message"; + break; + default: + if (IS_CREP(rcvd_type)) { + OSSL_CMP_CERTREPMESSAGE *crepmsg = rep->body->value.ip; + OSSL_CMP_CERTRESPONSE *crep = + ossl_cmp_certrepmessage_get0_certresponse(crepmsg, + -1 /* any rid */); + + if (sk_OSSL_CMP_CERTRESPONSE_num(crepmsg->response) > 1) + return -1; + if (crep == NULL) + return -1; + if (ossl_cmp_pkisi_get_status(crep->status) + == OSSL_CMP_PKISTATUS_rejection) + msg_type = "CertRepMessage with rejection status"; + } + } + if (msg_type == NULL) + return 0; + ossl_cmp_log2(WARN, ctx, "ignoring %s protection of %s", + invalid_protection ? "invalid" : "missing", msg_type); + return 1; +} + +/* Save error info from PKIStatusInfo field of a certresponse into ctx */ +static int save_statusInfo(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si) +{ + int i; + OSSL_CMP_PKIFREETEXT *ss; + + if (!ossl_assert(ctx != NULL && si != NULL)) + return 0; + + ctx->status = ossl_cmp_pkisi_get_status(si); + if (ctx->status < OSSL_CMP_PKISTATUS_accepted) + return 0; + + ctx->failInfoCode = ossl_cmp_pkisi_get_pkifailureinfo(si); + + if (!ossl_cmp_ctx_set0_statusString(ctx, sk_ASN1_UTF8STRING_new_null()) + || (ctx->statusString == NULL)) + return 0; + + ss = si->statusString; /* may be NULL */ + for (i = 0; i < sk_ASN1_UTF8STRING_num(ss); i++) { + ASN1_UTF8STRING *str = sk_ASN1_UTF8STRING_value(ss, i); + + if (!sk_ASN1_UTF8STRING_push(ctx->statusString, ASN1_STRING_dup(str))) + return 0; + } + return 1; +} + +/*- + * Perform the generic aspects of sending a request and receiving a response. + * Returns 1 on success and provides the received PKIMESSAGE in *rep. + * Returns 0 on error. + * Regardless of success, caller is responsible for freeing *rep (unless NULL). + */ +static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, + OSSL_CMP_MSG **rep, int expected_type) +{ + int begin_transaction = + expected_type != OSSL_CMP_PKIBODY_POLLREP + && expected_type != OSSL_CMP_PKIBODY_PKICONF; + const char *req_type_str = + ossl_cmp_bodytype_to_string(OSSL_CMP_MSG_get_bodytype(req)); + const char *expected_type_str = ossl_cmp_bodytype_to_string(expected_type); + int bak_msg_timeout = ctx->msg_timeout; + int bt; + time_t now = time(NULL); + int time_left; + OSSL_CMP_transfer_cb_t transfer_cb = ctx->transfer_cb; + + if (transfer_cb == NULL) + transfer_cb = OSSL_CMP_MSG_http_perform; + *rep = NULL; + + if (ctx->total_timeout != 0 /* not waiting indefinitely */) { + if (begin_transaction) + ctx->end_time = now + ctx->total_timeout; + if (now >= ctx->end_time) { + ERR_raise(ERR_LIB_CMP, CMP_R_TOTAL_TIMEOUT); + return 0; + } + if (!ossl_assert(ctx->end_time - now < INT_MAX)) { + /* actually cannot happen due to assignment in initial_certreq() */ + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); + return 0; + } + time_left = (int)(ctx->end_time - now); + if (ctx->msg_timeout == 0 || time_left < ctx->msg_timeout) + ctx->msg_timeout = time_left; + } + + /* should print error queue since transfer_cb may call ERR_clear_error() */ + OSSL_CMP_CTX_print_errors(ctx); + + ossl_cmp_log1(INFO, ctx, "sending %s", req_type_str); + + *rep = (*transfer_cb)(ctx, req); + ctx->msg_timeout = bak_msg_timeout; + + if (*rep == NULL) { + ERR_raise_data(ERR_LIB_CMP, + ctx->total_timeout != 0 && time(NULL) >= ctx->end_time ? + CMP_R_TOTAL_TIMEOUT : CMP_R_TRANSFER_ERROR, + "request sent: %s, expected response: %s", + req_type_str, expected_type_str); + return 0; + } + + bt = OSSL_CMP_MSG_get_bodytype(*rep); + /* + * The body type in the 'bt' variable is not yet verified. + * Still we use this preliminary value already for a progress report because + * the following msg verification may also produce log entries and may fail. + */ + ossl_cmp_log1(INFO, ctx, "received %s", ossl_cmp_bodytype_to_string(bt)); + + /* copy received extraCerts to ctx->extraCertsIn so they can be retrieved */ + if (bt != OSSL_CMP_PKIBODY_POLLREP && bt != OSSL_CMP_PKIBODY_PKICONF + && !ossl_cmp_ctx_set1_extraCertsIn(ctx, (*rep)->extraCerts)) + return 0; + + if (!ossl_cmp_msg_check_update(ctx, *rep, unprotected_exception, + expected_type)) + return 0; + + if (bt == expected_type + /* as an answer to polling, there could be IP/CP/KUP: */ + || (IS_CREP(bt) && expected_type == OSSL_CMP_PKIBODY_POLLREP)) + return 1; + + /* received message type is not one of the expected ones (e.g., error) */ + ERR_raise(ERR_LIB_CMP, bt == OSSL_CMP_PKIBODY_ERROR ? CMP_R_RECEIVED_ERROR : + CMP_R_UNEXPECTED_PKIBODY); /* in next line for mkerr.pl */ + + if (bt != OSSL_CMP_PKIBODY_ERROR) { + ERR_add_error_data(3, "message type is '", + ossl_cmp_bodytype_to_string(bt), "'"); + } else { + OSSL_CMP_ERRORMSGCONTENT *emc = (*rep)->body->value.error; + OSSL_CMP_PKISI *si = emc->pKIStatusInfo; + char buf[OSSL_CMP_PKISI_BUFLEN]; + + if (save_statusInfo(ctx, si) + && OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf, + sizeof(buf)) != NULL) + ERR_add_error_data(1, buf); + if (emc->errorCode != NULL + && BIO_snprintf(buf, sizeof(buf), "; errorCode: %08lX", + ASN1_INTEGER_get(emc->errorCode)) > 0) + ERR_add_error_data(1, buf); + if (emc->errorDetails != NULL) { + char *text = ossl_sk_ASN1_UTF8STRING2text(emc->errorDetails, ", ", + OSSL_CMP_PKISI_BUFLEN - 1); + + if (text != NULL && *text != '\0') + ERR_add_error_data(2, "; errorDetails: ", text); + OPENSSL_free(text); + } + if (ctx->status != OSSL_CMP_PKISTATUS_rejection) { + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKISTATUS); + if (ctx->status == OSSL_CMP_PKISTATUS_waiting) + ctx->status = OSSL_CMP_PKISTATUS_rejection; + } + } + return 0; +} + +/*- + * When a 'waiting' PKIStatus has been received, this function is used to + * poll, which should yield a pollRep or finally a CertRepMessage in ip/cp/kup. + * On receiving a pollRep, which includes a checkAfter value, it return this + * value if sleep == 0, else it sleeps as long as indicated and retries. + * + * A transaction timeout is enabled if ctx->total_timeout is != 0. + * In this case polling will continue until the timeout is reached and then + * polling is done a last time even if this is before the "checkAfter" time. + * + * Returns -1 on receiving pollRep if sleep == 0, setting the checkAfter value. + * Returns 1 on success and provides the received PKIMESSAGE in *rep. + * In this case the caller is responsible for freeing *rep. + * Returns 0 on error (which includes the case that timeout has been reached). + */ +static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid, + OSSL_CMP_MSG **rep, int *checkAfter) +{ + OSSL_CMP_MSG *preq = NULL; + OSSL_CMP_MSG *prep = NULL; + + ossl_cmp_info(ctx, + "received 'waiting' PKIStatus, starting to poll for response"); + *rep = NULL; + for (;;) { + if ((preq = ossl_cmp_pollReq_new(ctx, rid)) == NULL) + goto err; + + if (!send_receive_check(ctx, preq, &prep, OSSL_CMP_PKIBODY_POLLREP)) + goto err; + + /* handle potential pollRep */ + if (OSSL_CMP_MSG_get_bodytype(prep) == OSSL_CMP_PKIBODY_POLLREP) { + OSSL_CMP_POLLREPCONTENT *prc = prep->body->value.pollRep; + OSSL_CMP_POLLREP *pollRep = NULL; + int64_t check_after; + char str[OSSL_CMP_PKISI_BUFLEN]; + int len; + + if (sk_OSSL_CMP_POLLREP_num(prc) > 1) { + ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED); + goto err; + } + pollRep = ossl_cmp_pollrepcontent_get0_pollrep(prc, rid); + if (pollRep == NULL) + goto err; + + if (!ASN1_INTEGER_get_int64(&check_after, pollRep->checkAfter)) { + ERR_raise(ERR_LIB_CMP, CMP_R_BAD_CHECKAFTER_IN_POLLREP); + goto err; + } + if (check_after < 0 || (uint64_t)check_after + > (sleep ? ULONG_MAX / 1000 : INT_MAX)) { + ERR_raise(ERR_LIB_CMP, CMP_R_CHECKAFTER_OUT_OF_RANGE); + if (BIO_snprintf(str, OSSL_CMP_PKISI_BUFLEN, "value = %jd", + check_after) >= 0) + ERR_add_error_data(1, str); + goto err; + } + + if (pollRep->reason == NULL + || (len = BIO_snprintf(str, OSSL_CMP_PKISI_BUFLEN, + " with reason = '")) < 0) { + *str = '\0'; + } else { + char *text = ossl_sk_ASN1_UTF8STRING2text(pollRep->reason, ", ", + sizeof(str) - len - 2); + + if (text == NULL + || BIO_snprintf(str + len, sizeof(str) - len, + "%s'", text) < 0) + *str = '\0'; + OPENSSL_free(text); + } + ossl_cmp_log2(INFO, ctx, + "received polling response%s; checkAfter = %ld seconds", + str, check_after); + + if (ctx->total_timeout != 0) { /* timeout is not infinite */ + const int exp = 5; /* expected max time per msg round trip */ + int64_t time_left = (int64_t)(ctx->end_time - exp - time(NULL)); + + if (time_left <= 0) { + ERR_raise(ERR_LIB_CMP, CMP_R_TOTAL_TIMEOUT); + goto err; + } + if (time_left < check_after) + check_after = time_left; + /* poll one last time just when timeout was reached */ + } + + OSSL_CMP_MSG_free(preq); + preq = NULL; + OSSL_CMP_MSG_free(prep); + prep = NULL; + if (sleep) { + ossl_sleep((unsigned long)(1000 * check_after)); + } else { + if (checkAfter != NULL) + *checkAfter = (int)check_after; + return -1; /* exits the loop */ + } + } else { + ossl_cmp_info(ctx, "received ip/cp/kup after polling"); + /* any other body type has been rejected by send_receive_check() */ + break; + } + } + if (prep == NULL) + goto err; + + OSSL_CMP_MSG_free(preq); + *rep = prep; + + return 1; + err: + OSSL_CMP_MSG_free(preq); + OSSL_CMP_MSG_free(prep); + return 0; +} + +/* + * Send certConf for IR, CR or KUR sequences and check response, + * not modifying ctx->status during the certConf exchange + */ +int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int fail_info, + const char *txt) +{ + OSSL_CMP_MSG *certConf; + OSSL_CMP_MSG *PKIconf = NULL; + int res = 0; + + /* OSSL_CMP_certConf_new() also checks if all necessary options are set */ + if ((certConf = ossl_cmp_certConf_new(ctx, fail_info, txt)) == NULL) + goto err; + + res = send_receive_check(ctx, certConf, &PKIconf, OSSL_CMP_PKIBODY_PKICONF); + + err: + OSSL_CMP_MSG_free(certConf); + OSSL_CMP_MSG_free(PKIconf); + return res; +} + +/* Send given error and check response */ +int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info, + const char *txt, int errorCode, const char *details) +{ + OSSL_CMP_MSG *error = NULL; + OSSL_CMP_PKISI *si = NULL; + OSSL_CMP_MSG *PKIconf = NULL; + int res = 0; + + /* not overwriting ctx->status on error exchange */ + if ((si = OSSL_CMP_STATUSINFO_new(status, fail_info, txt)) == NULL) + goto err; + /* ossl_cmp_error_new() also checks if all necessary options are set */ + if ((error = ossl_cmp_error_new(ctx, si, errorCode, details, 0)) == NULL) + goto err; + + res = send_receive_check(ctx, error, &PKIconf, OSSL_CMP_PKIBODY_PKICONF); + + err: + OSSL_CMP_MSG_free(error); + OSSL_CMP_PKISI_free(si); + OSSL_CMP_MSG_free(PKIconf); + return res; +} + +/*- + * Retrieve a copy of the certificate, if any, from the given CertResponse. + * Take into account PKIStatusInfo of CertResponse in ctx, report it on error. + * Returns NULL if not found or on error. + */ +static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype, + OSSL_CMP_CERTRESPONSE *crep) +{ + char buf[OSSL_CMP_PKISI_BUFLEN]; + X509 *crt = NULL; + EVP_PKEY *privkey; + + if (!ossl_assert(ctx != NULL && crep != NULL)) + return NULL; + + privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); + switch (ossl_cmp_pkisi_get_status(crep->status)) { + case OSSL_CMP_PKISTATUS_waiting: + ossl_cmp_err(ctx, + "received \"waiting\" status for cert when actually aiming to extract cert"); + ERR_raise(ERR_LIB_CMP, CMP_R_ENCOUNTERED_WAITING); + goto err; + case OSSL_CMP_PKISTATUS_grantedWithMods: + ossl_cmp_warn(ctx, "received \"grantedWithMods\" for certificate"); + break; + case OSSL_CMP_PKISTATUS_accepted: + break; + /* get all information in case of a rejection before going to error */ + case OSSL_CMP_PKISTATUS_rejection: + ossl_cmp_err(ctx, "received \"rejection\" status rather than cert"); + ERR_raise(ERR_LIB_CMP, CMP_R_REQUEST_REJECTED_BY_SERVER); + goto err; + case OSSL_CMP_PKISTATUS_revocationWarning: + ossl_cmp_warn(ctx, + "received \"revocationWarning\" - a revocation of the cert is imminent"); + break; + case OSSL_CMP_PKISTATUS_revocationNotification: + ossl_cmp_warn(ctx, + "received \"revocationNotification\" - a revocation of the cert has occurred"); + break; + case OSSL_CMP_PKISTATUS_keyUpdateWarning: + if (bodytype != OSSL_CMP_PKIBODY_KUR) { + ERR_raise(ERR_LIB_CMP, CMP_R_ENCOUNTERED_KEYUPDATEWARNING); + goto err; + } + break; + default: + ossl_cmp_log1(ERROR, ctx, + "received unsupported PKIStatus %d for certificate", + ctx->status); + ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_PKISTATUS); + goto err; + } + crt = ossl_cmp_certresponse_get1_cert(crep, ctx, privkey); + if (crt == NULL) /* according to PKIStatus, we can expect a cert */ + ERR_raise(ERR_LIB_CMP, CMP_R_CERTIFICATE_NOT_FOUND); + + return crt; + + err: + if (OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf, sizeof(buf)) != NULL) + ERR_add_error_data(1, buf); + return NULL; +} + +/*- + * Callback fn validating that the new certificate can be verified, using + * ctx->certConf_cb_arg, which has been initialized using opt_out_trusted, and + * ctx->untrusted, which at this point already contains msg->extraCerts. + * Returns 0 on acceptance, else a bit field reflecting PKIFailureInfo. + * Quoting from RFC 4210 section 5.1. Overall PKI Message: + * The extraCerts field can contain certificates that may be useful to + * the recipient. For example, this can be used by a CA or RA to + * present an end entity with certificates that it needs to verify its + * own new certificate (if, for example, the CA that issued the end + * entity's certificate is not a root CA for the end entity). Note that + * this field does not necessarily contain a certification path; the + * recipient may have to sort, select from, or otherwise process the + * extra certificates in order to use them. + * Note: While often handy, there is no hard requirement by CMP that + * an EE must be able to validate the certificates it gets enrolled. + */ +int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, + const char **text) +{ + X509_STORE *out_trusted = OSSL_CMP_CTX_get_certConf_cb_arg(ctx); + STACK_OF(X509) *chain = NULL; + (void)text; /* make (artificial) use of var to prevent compiler warning */ + + if (fail_info != 0) /* accept any error flagged by CMP core library */ + return fail_info; + + ossl_cmp_debug(ctx, "trying to build chain for newly enrolled cert"); + chain = X509_build_chain(cert, ctx->untrusted, out_trusted /* maybe NULL */, + 0, ctx->libctx, ctx->propq); + if (sk_X509_num(chain) > 0) + X509_free(sk_X509_shift(chain)); /* remove leaf (EE) cert */ + if (out_trusted != NULL) { + if (chain == NULL) { + ossl_cmp_err(ctx, "failed building chain for newly enrolled cert"); + fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_incorrectData; + } else { + ossl_cmp_debug(ctx, + "succeeded building proper chain for newly enrolled cert"); + } + } else if (chain == NULL) { + ossl_cmp_warn(ctx, "could not build approximate chain for newly enrolled cert, resorting to received extraCerts"); + chain = OSSL_CMP_CTX_get1_extraCertsIn(ctx); + } else { + ossl_cmp_debug(ctx, + "success building approximate chain for newly enrolled cert"); + } + (void)ossl_cmp_ctx_set1_newChain(ctx, chain); + sk_X509_pop_free(chain, X509_free); + + return fail_info; +} + +/*- + * Perform the generic handling of certificate responses for IR/CR/KUR/P10CR. + * Returns -1 on receiving pollRep if sleep == 0, setting the checkAfter value. + * Returns 1 on success and provides the received PKIMESSAGE in *resp. + * Returns 0 on error (which includes the case that timeout has been reached). + * Regardless of success, caller is responsible for freeing *resp (unless NULL). + */ +static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid, + OSSL_CMP_MSG **resp, int *checkAfter, + int req_type, int expected_type) +{ + EVP_PKEY *rkey = OSSL_CMP_CTX_get0_newPkey(ctx /* may be NULL */, 0); + int fail_info = 0; /* no failure */ + const char *txt = NULL; + OSSL_CMP_CERTREPMESSAGE *crepmsg; + OSSL_CMP_CERTRESPONSE *crep; + OSSL_CMP_certConf_cb_t cb; + X509 *cert; + char *subj = NULL; + int ret = 1; + + if (!ossl_assert(ctx != NULL)) + return 0; + + retry: + crepmsg = (*resp)->body->value.ip; /* same for cp and kup */ + if (sk_OSSL_CMP_CERTRESPONSE_num(crepmsg->response) > 1) { + ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED); + return 0; + } + crep = ossl_cmp_certrepmessage_get0_certresponse(crepmsg, rid); + if (crep == NULL) + return 0; + if (!save_statusInfo(ctx, crep->status)) + return 0; + if (rid == -1) { + /* for OSSL_CMP_PKIBODY_P10CR learn CertReqId from response */ + rid = ossl_cmp_asn1_get_int(crep->certReqId); + if (rid == -1) { + ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); + return 0; + } + } + + if (ossl_cmp_pkisi_get_status(crep->status) == OSSL_CMP_PKISTATUS_waiting) { + OSSL_CMP_MSG_free(*resp); + *resp = NULL; + if ((ret = poll_for_response(ctx, sleep, rid, resp, checkAfter)) != 0) { + if (ret == -1) /* at this point implies sleep == 0 */ + return ret; /* waiting */ + goto retry; /* got ip/cp/kup, which may still indicate 'waiting' */ + } else { + ERR_raise(ERR_LIB_CMP, CMP_R_POLLING_FAILED); + return 0; + } + } + + cert = get1_cert_status(ctx, (*resp)->body->type, crep); + if (cert == NULL) { + ERR_add_error_data(1, "; cannot extract certificate from response"); + return 0; + } + if (!ossl_cmp_ctx_set0_newCert(ctx, cert)) + return 0; + + /* + * if the CMP server returned certificates in the caPubs field, copy them + * to the context so that they can be retrieved if necessary + */ + if (crepmsg->caPubs != NULL + && !ossl_cmp_ctx_set1_caPubs(ctx, crepmsg->caPubs)) + return 0; + + subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); + if (rkey != NULL + /* X509_check_private_key() also works if rkey is just public key */ + && !(X509_check_private_key(ctx->newCert, rkey))) { + fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_incorrectData; + txt = "public key in new certificate does not match our enrollment key"; + /*- + * not calling (void)ossl_cmp_exchange_error(ctx, + * OSSL_CMP_PKISTATUS_rejection, fail_info, txt) + * not throwing CMP_R_CERTIFICATE_NOT_ACCEPTED with txt + * not returning 0 + * since we better leave this for the certConf_cb to decide + */ + } + + /* + * Execute the certification checking callback function, + * which can determine whether to accept a newly enrolled certificate. + * It may overrule the pre-decision reflected in 'fail_info' and '*txt'. + */ + cb = ctx->certConf_cb != NULL ? ctx->certConf_cb : OSSL_CMP_certConf_cb; + if ((fail_info = cb(ctx, ctx->newCert, fail_info, &txt)) != 0 + && txt == NULL) + txt = "CMP client did not accept it"; + if (fail_info != 0) /* immediately log error before any certConf exchange */ + ossl_cmp_log1(ERROR, ctx, + "rejecting newly enrolled cert with subject: %s", subj); + if (!ctx->disableConfirm + && !ossl_cmp_hdr_has_implicitConfirm((*resp)->header)) { + if (!ossl_cmp_exchange_certConf(ctx, fail_info, txt)) + ret = 0; + } + + /* not throwing failure earlier as transfer_cb may call ERR_clear_error() */ + if (fail_info != 0) { + ERR_raise_data(ERR_LIB_CMP, CMP_R_CERTIFICATE_NOT_ACCEPTED, + "rejecting newly enrolled cert with subject: %s; %s", + subj, txt); + ret = 0; + } + OPENSSL_free(subj); + return ret; +} + +static int initial_certreq(OSSL_CMP_CTX *ctx, + int req_type, const OSSL_CRMF_MSG *crm, + OSSL_CMP_MSG **p_rep, int rep_type) +{ + OSSL_CMP_MSG *req; + int res; + + ctx->status = OSSL_CMP_PKISTATUS_request; + if (!ossl_cmp_ctx_set0_newCert(ctx, NULL)) + return 0; + + /* also checks if all necessary options are set */ + if ((req = ossl_cmp_certreq_new(ctx, req_type, crm)) == NULL) + return 0; + + ctx->status = OSSL_CMP_PKISTATUS_trans; + res = send_receive_check(ctx, req, p_rep, rep_type); + OSSL_CMP_MSG_free(req); + return res; +} + +int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type, + const OSSL_CRMF_MSG *crm, int *checkAfter) +{ + OSSL_CMP_MSG *rep = NULL; + int is_p10 = req_type == OSSL_CMP_PKIBODY_P10CR; + int rid = is_p10 ? -1 : OSSL_CMP_CERTREQID; + int rep_type = is_p10 ? OSSL_CMP_PKIBODY_CP : req_type + 1; + int res = 0; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + + if (ctx->status != OSSL_CMP_PKISTATUS_waiting) { /* not polling already */ + if (!initial_certreq(ctx, req_type, crm, &rep, rep_type)) + goto err; + } else { + if (req_type < 0) + return ossl_cmp_exchange_error(ctx, OSSL_CMP_PKISTATUS_rejection, + 0, "polling aborted", + 0 /* errorCode */, "by application"); + res = poll_for_response(ctx, 0 /* no sleep */, rid, &rep, checkAfter); + if (res <= 0) /* waiting or error */ + return res; + } + res = cert_response(ctx, 0 /* no sleep */, rid, &rep, checkAfter, + req_type, rep_type); + + err: + OSSL_CMP_MSG_free(rep); + return res; +} + +/*- + * Do the full sequence CR/IR/KUR/P10CR, CP/IP/KUP/CP, + * certConf, PKIconf, and polling if required. + * Will sleep as long as indicated by the server (according to checkAfter). + * All enrollment options need to be present in the context. + * Returns pointer to received certificate, or NULL if none was received. + */ +X509 *OSSL_CMP_exec_certreq(OSSL_CMP_CTX *ctx, int req_type, + const OSSL_CRMF_MSG *crm) +{ + + OSSL_CMP_MSG *rep = NULL; + int is_p10 = req_type == OSSL_CMP_PKIBODY_P10CR; + int rid = is_p10 ? -1 : OSSL_CMP_CERTREQID; + int rep_type = is_p10 ? OSSL_CMP_PKIBODY_CP : req_type + 1; + X509 *result = NULL; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + + if (!initial_certreq(ctx, req_type, crm, &rep, rep_type)) + goto err; + + if (cert_response(ctx, 1 /* sleep */, rid, &rep, NULL, req_type, rep_type) + <= 0) + goto err; + + result = ctx->newCert; + err: + OSSL_CMP_MSG_free(rep); + return result; +} + +int OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx) +{ + OSSL_CMP_MSG *rr = NULL; + OSSL_CMP_MSG *rp = NULL; + const int num_RevDetails = 1; + const int rsid = OSSL_CMP_REVREQSID; + OSSL_CMP_REVREPCONTENT *rrep = NULL; + OSSL_CMP_PKISI *si = NULL; + char buf[OSSL_CMP_PKISI_BUFLEN]; + int ret = 0; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); + return 0; + } + ctx->status = OSSL_CMP_PKISTATUS_request; + if (ctx->oldCert == NULL && ctx->p10CSR == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_REFERENCE_CERT); + return 0; + } + + /* OSSL_CMP_rr_new() also checks if all necessary options are set */ + if ((rr = ossl_cmp_rr_new(ctx)) == NULL) + goto end; + + ctx->status = OSSL_CMP_PKISTATUS_trans; + if (!send_receive_check(ctx, rr, &rp, OSSL_CMP_PKIBODY_RP)) + goto end; + + rrep = rp->body->value.rp; +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (sk_OSSL_CMP_PKISI_num(rrep->status) != num_RevDetails) { + ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_RP_COMPONENT_COUNT); + goto end; + } +#else + if (sk_OSSL_CMP_PKISI_num(rrep->status) < 1) { + ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_RP_COMPONENT_COUNT); + goto end; + } +#endif + + /* evaluate PKIStatus field */ + si = ossl_cmp_revrepcontent_get_pkisi(rrep, rsid); + if (!save_statusInfo(ctx, si)) + goto err; + switch (ossl_cmp_pkisi_get_status(si)) { + case OSSL_CMP_PKISTATUS_accepted: + ossl_cmp_info(ctx, "revocation accepted (PKIStatus=accepted)"); + ret = 1; + break; + case OSSL_CMP_PKISTATUS_grantedWithMods: + ossl_cmp_info(ctx, "revocation accepted (PKIStatus=grantedWithMods)"); + ret = 1; + break; + case OSSL_CMP_PKISTATUS_rejection: + ERR_raise(ERR_LIB_CMP, CMP_R_REQUEST_REJECTED_BY_SERVER); + goto err; + case OSSL_CMP_PKISTATUS_revocationWarning: + ossl_cmp_info(ctx, "revocation accepted (PKIStatus=revocationWarning)"); + ret = 1; + break; + case OSSL_CMP_PKISTATUS_revocationNotification: + /* interpretation as warning or error depends on CA */ + ossl_cmp_warn(ctx, + "revocation accepted (PKIStatus=revocationNotification)"); + ret = 1; + break; + case OSSL_CMP_PKISTATUS_waiting: + case OSSL_CMP_PKISTATUS_keyUpdateWarning: + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKISTATUS); + goto err; + default: + ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_PKISTATUS); + goto err; + } + + /* check any present CertId in optional revCerts field */ + if (sk_OSSL_CRMF_CERTID_num(rrep->revCerts) >= 1) { + OSSL_CRMF_CERTID *cid; + OSSL_CRMF_CERTTEMPLATE *tmpl = + sk_OSSL_CMP_REVDETAILS_value(rr->body->value.rr, rsid)->certDetails; + const X509_NAME *issuer = OSSL_CRMF_CERTTEMPLATE_get0_issuer(tmpl); + const ASN1_INTEGER *serial = OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl); + + if (sk_OSSL_CRMF_CERTID_num(rrep->revCerts) != num_RevDetails) { + ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_RP_COMPONENT_COUNT); + ret = 0; + goto err; + } + if ((cid = ossl_cmp_revrepcontent_get_CertId(rrep, rsid)) == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_CERTID); + ret = 0; + goto err; + } + if (X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID_IN_RP); + ret = 0; + goto err; +#endif + } + if (ASN1_INTEGER_cmp(serial, + OSSL_CRMF_CERTID_get0_serialNumber(cid)) != 0) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_SERIAL_IN_RP); + ret = 0; + goto err; +#endif + } + } + + /* check number of any optionally present crls */ + if (rrep->crls != NULL && sk_X509_CRL_num(rrep->crls) != num_RevDetails) { + ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_RP_COMPONENT_COUNT); + ret = 0; + goto err; + } + + err: + if (ret == 0 + && OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf, sizeof(buf)) != NULL) + ERR_add_error_data(1, buf); + + end: + OSSL_CMP_MSG_free(rr); + OSSL_CMP_MSG_free(rp); + return ret; +} + +STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx) +{ + OSSL_CMP_MSG *genm; + OSSL_CMP_MSG *genp = NULL; + STACK_OF(OSSL_CMP_ITAV) *itavs = NULL; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); + return NULL; + } + ctx->status = OSSL_CMP_PKISTATUS_request; + + if ((genm = ossl_cmp_genm_new(ctx)) == NULL) + goto err; + + ctx->status = OSSL_CMP_PKISTATUS_trans; + if (!send_receive_check(ctx, genm, &genp, OSSL_CMP_PKIBODY_GENP)) + goto err; + ctx->status = OSSL_CMP_PKISTATUS_accepted; + + itavs = genp->body->value.genp; + if (itavs == NULL) + itavs = sk_OSSL_CMP_ITAV_new_null(); + /* received stack of itavs not to be freed with the genp */ + genp->body->value.genp = NULL; + + err: + OSSL_CMP_MSG_free(genm); + OSSL_CMP_MSG_free(genp); + + return itavs; /* NULL indicates error case */ +} diff --git a/crypto/openssl/crypto/cmp/cmp_ctx.c b/crypto/openssl/crypto/cmp/cmp_ctx.c new file mode 100644 index 000000000000..4b610b746e45 --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_ctx.c @@ -0,0 +1,1157 @@ +/* + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include /* for OCSP_REVOKED_STATUS_* */ + +#include "cmp_local.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include + +/* + * Get current certificate store containing trusted root CA certs + */ +X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return ctx->trusted; +} + +/* + * Set certificate store containing trusted (root) CA certs and possibly CRLs + * and a cert verification callback function used for CMP server authentication. + * Any already existing store entry is freed. Given NULL, the entry is reset. + */ +int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + X509_STORE_free(ctx->trusted); + ctx->trusted = store; + return 1; +} + +/* Get current list of non-trusted intermediate certs */ +STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return ctx->untrusted; +} + +/* + * Set untrusted certificates for path construction in authentication of + * the CMP server and potentially others (TLS server, newly enrolled cert). + */ +int OSSL_CMP_CTX_set1_untrusted(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs) +{ + STACK_OF(X509) *untrusted = NULL; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (!ossl_x509_add_certs_new(&untrusted, certs, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) + goto err; + sk_X509_pop_free(ctx->untrusted, X509_free); + ctx->untrusted = untrusted; + return 1; + err: + sk_X509_pop_free(untrusted, X509_free); + return 0; +} + +static int cmp_ctx_set_md(OSSL_CMP_CTX *ctx, EVP_MD **pmd, int nid) +{ + EVP_MD *md = EVP_MD_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propq); + /* fetching in advance to be able to throw error early if unsupported */ + + if (md == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + EVP_MD_free(*pmd); + *pmd = md; + return 1; +} + +/* + * Allocates and initializes OSSL_CMP_CTX context structure with default values. + * Returns new context on success, NULL on error + */ +OSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) +{ + OSSL_CMP_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx == NULL) + goto err; + + ctx->libctx = libctx; + if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) + goto oom; + + ctx->log_verbosity = OSSL_CMP_LOG_INFO; + + ctx->status = OSSL_CMP_PKISTATUS_unspecified; + ctx->failInfoCode = -1; + + ctx->keep_alive = 1; + ctx->msg_timeout = -1; + + if ((ctx->untrusted = sk_X509_new_null()) == NULL) + goto oom; + + ctx->pbm_slen = 16; + if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, NID_sha256)) + goto err; + ctx->pbm_itercnt = 500; + ctx->pbm_mac = NID_hmac_sha1; + + if (!cmp_ctx_set_md(ctx, &ctx->digest, NID_sha256)) + goto err; + ctx->popoMethod = OSSL_CRMF_POPO_SIGNATURE; + ctx->revocationReason = CRL_REASON_NONE; + + /* all other elements are initialized to 0 or NULL, respectively */ + return ctx; + + oom: + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + err: + OSSL_CMP_CTX_free(ctx); + return NULL; +} + +#define OSSL_CMP_ITAVs_free(itavs) \ + sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free); +#define X509_EXTENSIONS_free(exts) \ + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free) +#define OSSL_CMP_PKIFREETEXT_free(text) \ + sk_ASN1_UTF8STRING_pop_free(text, ASN1_UTF8STRING_free) + +/* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX */ +int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + + if (ctx->http_ctx != NULL) { + (void)OSSL_HTTP_close(ctx->http_ctx, 1); + ossl_cmp_debug(ctx, "disconnected from CMP server"); + ctx->http_ctx = NULL; + } + ctx->status = OSSL_CMP_PKISTATUS_unspecified; + ctx->failInfoCode = -1; + + OSSL_CMP_ITAVs_free(ctx->genm_ITAVs); + ctx->genm_ITAVs = NULL; + + return ossl_cmp_ctx_set0_statusString(ctx, NULL) + && ossl_cmp_ctx_set0_newCert(ctx, NULL) + && ossl_cmp_ctx_set1_newChain(ctx, NULL) + && ossl_cmp_ctx_set1_caPubs(ctx, NULL) + && ossl_cmp_ctx_set1_extraCertsIn(ctx, NULL) + && ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL) + && OSSL_CMP_CTX_set1_transactionID(ctx, NULL) + && OSSL_CMP_CTX_set1_senderNonce(ctx, NULL) + && ossl_cmp_ctx_set1_recipNonce(ctx, NULL); +} + +/* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new() */ +void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) + return; + + if (ctx->http_ctx != NULL) { + (void)OSSL_HTTP_close(ctx->http_ctx, 1); + ossl_cmp_debug(ctx, "disconnected from CMP server"); + } + OPENSSL_free(ctx->propq); + OPENSSL_free(ctx->serverPath); + OPENSSL_free(ctx->server); + OPENSSL_free(ctx->proxy); + OPENSSL_free(ctx->no_proxy); + + X509_free(ctx->srvCert); + X509_free(ctx->validatedSrvCert); + X509_NAME_free(ctx->expected_sender); + X509_STORE_free(ctx->trusted); + sk_X509_pop_free(ctx->untrusted, X509_free); + + X509_free(ctx->cert); + sk_X509_pop_free(ctx->chain, X509_free); + EVP_PKEY_free(ctx->pkey); + ASN1_OCTET_STRING_free(ctx->referenceValue); + if (ctx->secretValue != NULL) + OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length); + ASN1_OCTET_STRING_free(ctx->secretValue); + EVP_MD_free(ctx->pbm_owf); + + X509_NAME_free(ctx->recipient); + EVP_MD_free(ctx->digest); + ASN1_OCTET_STRING_free(ctx->transactionID); + ASN1_OCTET_STRING_free(ctx->senderNonce); + ASN1_OCTET_STRING_free(ctx->recipNonce); + sk_OSSL_CMP_ITAV_pop_free(ctx->geninfo_ITAVs, OSSL_CMP_ITAV_free); + sk_X509_pop_free(ctx->extraCertsOut, X509_free); + + EVP_PKEY_free(ctx->newPkey); + X509_NAME_free(ctx->issuer); + X509_NAME_free(ctx->subjectName); + sk_GENERAL_NAME_pop_free(ctx->subjectAltNames, GENERAL_NAME_free); + sk_X509_EXTENSION_pop_free(ctx->reqExtensions, X509_EXTENSION_free); + sk_POLICYINFO_pop_free(ctx->policies, POLICYINFO_free); + X509_free(ctx->oldCert); + X509_REQ_free(ctx->p10CSR); + + sk_OSSL_CMP_ITAV_pop_free(ctx->genm_ITAVs, OSSL_CMP_ITAV_free); + + sk_ASN1_UTF8STRING_pop_free(ctx->statusString, ASN1_UTF8STRING_free); + X509_free(ctx->newCert); + sk_X509_pop_free(ctx->newChain, X509_free); + sk_X509_pop_free(ctx->caPubs, X509_free); + sk_X509_pop_free(ctx->extraCertsIn, X509_free); + + OPENSSL_free(ctx); +} + +int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status) +{ + if (!ossl_assert(ctx != NULL)) + return 0; + ctx->status = status; + return 1; +} + +/* + * Returns the PKIStatus from the last CertRepMessage + * or Revocation Response or error message, -1 on error + */ +int OSSL_CMP_CTX_get_status(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return -1; + } + return ctx->status; +} + +/* + * Returns the statusString from the last CertRepMessage + * or Revocation Response or error message, NULL on error + */ +OSSL_CMP_PKIFREETEXT *OSSL_CMP_CTX_get0_statusString(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return ctx->statusString; +} + +int ossl_cmp_ctx_set0_statusString(OSSL_CMP_CTX *ctx, + OSSL_CMP_PKIFREETEXT *text) +{ + if (!ossl_assert(ctx != NULL)) + return 0; + sk_ASN1_UTF8STRING_pop_free(ctx->statusString, ASN1_UTF8STRING_free); + ctx->statusString = text; + return 1; +} + +int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert) +{ + if (!ossl_assert(ctx != NULL)) + return 0; + X509_free(ctx->validatedSrvCert); + ctx->validatedSrvCert = cert; + return 1; +} + +/* Set callback function for checking if the cert is ok or should be rejected */ +int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx->certConf_cb = cb; + return 1; +} + +/* + * Set argument, respectively a pointer to a structure containing arguments, + * optionally to be used by the certConf callback. + */ +int OSSL_CMP_CTX_set_certConf_cb_arg(OSSL_CMP_CTX *ctx, void *arg) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx->certConf_cb_arg = arg; + return 1; +} + +/* + * Get argument, respectively the pointer to a structure containing arguments, + * optionally to be used by certConf callback. + * Returns callback argument set previously (NULL if not set or on error) + */ +void *OSSL_CMP_CTX_get_certConf_cb_arg(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return ctx->certConf_cb_arg; +} + +#ifndef OPENSSL_NO_TRACE +static size_t ossl_cmp_log_trace_cb(const char *buf, size_t cnt, + int category, int cmd, void *vdata) +{ + OSSL_CMP_CTX *ctx = vdata; + const char *msg; + OSSL_CMP_severity level = -1; + char *func = NULL; + char *file = NULL; + int line = 0; + + if (buf == NULL || cnt == 0 || cmd != OSSL_TRACE_CTRL_WRITE || ctx == NULL) + return 0; + if (ctx->log_cb == NULL) + return 1; /* silently drop message */ + + msg = ossl_cmp_log_parse_metadata(buf, &level, &func, &file, &line); + + if (level > ctx->log_verbosity) /* excludes the case level is unknown */ + goto end; /* suppress output since severity is not sufficient */ + + if (!ctx->log_cb(func != NULL ? func : "(no func)", + file != NULL ? file : "(no file)", + line, level, msg)) + cnt = 0; + + end: + OPENSSL_free(func); + OPENSSL_free(file); + return cnt; +} +#endif + +/* Print CMP log messages (i.e., diagnostic info) via the log cb of the ctx */ +int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, + const char *func, const char *file, int line, + const char *level_str, const char *format, ...) +{ + va_list args; + char hugebuf[1024 * 2]; + int res = 0; + + if (ctx == NULL || ctx->log_cb == NULL) + return 1; /* silently drop message */ + + if (level > ctx->log_verbosity) /* excludes the case level is unknown */ + return 1; /* suppress output since severity is not sufficient */ + + if (format == NULL) + return 0; + + va_start(args, format); + + if (func == NULL) + func = "(unset function name)"; + if (file == NULL) + file = "(unset file name)"; + if (level_str == NULL) + level_str = "(unset level string)"; + +#ifndef OPENSSL_NO_TRACE + if (OSSL_TRACE_ENABLED(CMP)) { + OSSL_TRACE_BEGIN(CMP) { + int printed = + BIO_snprintf(hugebuf, sizeof(hugebuf), + "%s:%s:%d:" OSSL_CMP_LOG_PREFIX "%s: ", + func, file, line, level_str); + if (printed > 0 && (size_t)printed < sizeof(hugebuf)) { + if (BIO_vsnprintf(hugebuf + printed, + sizeof(hugebuf) - printed, format, args) > 0) + res = BIO_puts(trc_out, hugebuf) > 0; + } + } OSSL_TRACE_END(CMP); + } +#else /* compensate for disabled trace API */ + { + if (BIO_vsnprintf(hugebuf, sizeof(hugebuf), format, args) > 0) + res = ctx->log_cb(func, file, line, level, hugebuf); + } +#endif + va_end(args); + return res; +} + +/* Set a callback function for error reporting and logging messages */ +int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx->log_cb = cb; + +#ifndef OPENSSL_NO_TRACE + /* do also in case cb == NULL, to switch off logging output: */ + if (!OSSL_trace_set_callback(OSSL_TRACE_CATEGORY_CMP, + ossl_cmp_log_trace_cb, ctx)) + return 0; +#endif + + return 1; +} + +/* Print OpenSSL and CMP errors via the log cb of the ctx or ERR_print_errors */ +void OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx) +{ + if (ctx != NULL && OSSL_CMP_LOG_ERR > ctx->log_verbosity) + return; /* suppress output since severity is not sufficient */ + OSSL_CMP_print_errors_cb(ctx == NULL ? NULL : ctx->log_cb); +} + +/* + * Set or clear the reference value to be used for identification + * (i.e., the user name) when using PBMAC. + */ +int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx, + const unsigned char *ref, int len) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + return ossl_cmp_asn1_octet_string_set1_bytes(&ctx->referenceValue, ref, + len); +} + +/* Set or clear the password to be used for protecting messages with PBMAC */ +int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec, + const int len) +{ + ASN1_OCTET_STRING *secretValue = NULL; + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (ossl_cmp_asn1_octet_string_set1_bytes(&secretValue, sec, len) != 1) + return 0; + if (ctx->secretValue != NULL) { + OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length); + ASN1_OCTET_STRING_free(ctx->secretValue); + } + ctx->secretValue = secretValue; + return 1; +} + +/* Returns the cert chain computed by OSSL_CMP_certConf_cb(), NULL on error */ +STACK_OF(X509) *OSSL_CMP_CTX_get1_newChain(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return X509_chain_up_ref(ctx->newChain); +} + +/* + * Copies any given stack of inbound X509 certificates to newChain + * of the OSSL_CMP_CTX structure so that they may be retrieved later. + */ +int ossl_cmp_ctx_set1_newChain(OSSL_CMP_CTX *ctx, STACK_OF(X509) *newChain) +{ + if (!ossl_assert(ctx != NULL)) + return 0; + + sk_X509_pop_free(ctx->newChain, X509_free); + ctx->newChain = NULL; + return newChain == NULL || + (ctx->newChain = X509_chain_up_ref(newChain)) != NULL; +} + +/* Returns the stack of extraCerts received in CertRepMessage, NULL on error */ +STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return X509_chain_up_ref(ctx->extraCertsIn); +} + +/* + * Copies any given stack of inbound X509 certificates to extraCertsIn + * of the OSSL_CMP_CTX structure so that they may be retrieved later. + */ +int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx, + STACK_OF(X509) *extraCertsIn) +{ + if (!ossl_assert(ctx != NULL)) + return 0; + + sk_X509_pop_free(ctx->extraCertsIn, X509_free); + ctx->extraCertsIn = NULL; + return extraCertsIn == NULL + || (ctx->extraCertsIn = X509_chain_up_ref(extraCertsIn)) != NULL; +} + +/* + * Copies any given stack as the new stack of X509 + * certificates to send out in the extraCerts field. + */ +int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx, + STACK_OF(X509) *extraCertsOut) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + + sk_X509_pop_free(ctx->extraCertsOut, X509_free); + ctx->extraCertsOut = NULL; + return extraCertsOut == NULL + || (ctx->extraCertsOut = X509_chain_up_ref(extraCertsOut)) != NULL; +} + +/* + * Add the given policy info object + * to the X509_EXTENSIONS of the requested certificate template. + */ +int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo) +{ + if (ctx == NULL || pinfo == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + + if (ctx->policies == NULL + && (ctx->policies = CERTIFICATEPOLICIES_new()) == NULL) + return 0; + + return sk_POLICYINFO_push(ctx->policies, pinfo); +} + +/* Add an ITAV for geninfo of the PKI message header */ +int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + return OSSL_CMP_ITAV_push0_stack_item(&ctx->geninfo_ITAVs, itav); +} + +int OSSL_CMP_CTX_reset_geninfo_ITAVs(OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + OSSL_CMP_ITAVs_free(ctx->geninfo_ITAVs); + ctx->geninfo_ITAVs = NULL; + return 1; +} + +/* Add an itav for the body of outgoing general messages */ +int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + return OSSL_CMP_ITAV_push0_stack_item(&ctx->genm_ITAVs, itav); +} + +/* + * Returns a duplicate of the stack of X509 certificates that + * were received in the caPubs field of the last CertRepMessage. + * Returns NULL on error + */ +STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return X509_chain_up_ref(ctx->caPubs); +} + +/* + * Copies any given stack of certificates to the given + * OSSL_CMP_CTX structure so that they may be retrieved later. + */ +int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs) +{ + if (!ossl_assert(ctx != NULL)) + return 0; + + sk_X509_pop_free(ctx->caPubs, X509_free); + ctx->caPubs = NULL; + return caPubs == NULL || (ctx->caPubs = X509_chain_up_ref(caPubs)) != NULL; +} + +#define char_dup OPENSSL_strdup +#define char_free OPENSSL_free +#define DEFINE_OSSL_CMP_CTX_set1(FIELD, TYPE) /* this uses _dup */ \ +int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, const TYPE *val) \ +{ \ + TYPE *val_dup = NULL; \ + \ + if (ctx == NULL) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ + return 0; \ + } \ + \ + if (val != NULL && (val_dup = TYPE##_dup(val)) == NULL) \ + return 0; \ + TYPE##_free(ctx->FIELD); \ + ctx->FIELD = val_dup; \ + return 1; \ +} + +#define X509_invalid(cert) (!ossl_x509v3_cache_extensions(cert)) +#define EVP_PKEY_invalid(key) 0 +#define DEFINE_OSSL_CMP_CTX_set1_up_ref(FIELD, TYPE) \ +int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \ +{ \ + if (ctx == NULL) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ + return 0; \ + } \ + \ + /* prevent misleading error later on malformed cert or provider issue */ \ + if (val != NULL && TYPE##_invalid(val)) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_POTENTIALLY_INVALID_CERTIFICATE); \ + return 0; \ + } \ + if (val != NULL && !TYPE##_up_ref(val)) \ + return 0; \ + TYPE##_free(ctx->FIELD); \ + ctx->FIELD = val; \ + return 1; \ +} + +/* + * Pins the server certificate to be directly trusted (even if it is expired) + * for verifying response messages. + * Cert pointer is not consumed. It may be NULL to clear the entry. + */ +DEFINE_OSSL_CMP_CTX_set1_up_ref(srvCert, X509) + +/* Set the X509 name of the recipient. Set in the PKIHeader */ +DEFINE_OSSL_CMP_CTX_set1(recipient, X509_NAME) + +/* Store the X509 name of the expected sender in the PKIHeader of responses */ +DEFINE_OSSL_CMP_CTX_set1(expected_sender, X509_NAME) + +/* Set the X509 name of the issuer. Set in the PKIHeader */ +DEFINE_OSSL_CMP_CTX_set1(issuer, X509_NAME) + +/* + * Set the subject name that will be placed in the certificate + * request. This will be the subject name on the received certificate. + */ +DEFINE_OSSL_CMP_CTX_set1(subjectName, X509_NAME) + +/* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR */ +int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + + if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0 && exts != NULL + && X509v3_get_ext_by_NID(exts, NID_subject_alt_name, -1) >= 0) { + ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_SAN_SOURCES); + return 0; + } + sk_X509_EXTENSION_pop_free(ctx->reqExtensions, X509_EXTENSION_free); + ctx->reqExtensions = exts; + return 1; +} + +/* returns 1 if ctx contains a Subject Alternative Name extension, else 0 */ +int OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return -1; + } + /* if one of the following conditions 'fail' this is not an error */ + return ctx->reqExtensions != NULL + && X509v3_get_ext_by_NID(ctx->reqExtensions, + NID_subject_alt_name, -1) >= 0; +} + +/* + * Add a GENERAL_NAME structure that will be added to the CRMF + * request's extensions field to request subject alternative names. + */ +int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx, + const GENERAL_NAME *name) +{ + GENERAL_NAME *name_dup; + + if (ctx == NULL || name == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + + if (OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1) { + ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_SAN_SOURCES); + return 0; + } + + if (ctx->subjectAltNames == NULL + && (ctx->subjectAltNames = sk_GENERAL_NAME_new_null()) == NULL) + return 0; + if ((name_dup = GENERAL_NAME_dup(name)) == NULL) + return 0; + if (!sk_GENERAL_NAME_push(ctx->subjectAltNames, name_dup)) { + GENERAL_NAME_free(name_dup); + return 0; + } + return 1; +} + +/* + * Set our own client certificate, used for example in KUR and when + * doing the IR with existing certificate. + */ +DEFINE_OSSL_CMP_CTX_set1_up_ref(cert, X509) + +int OSSL_CMP_CTX_build_cert_chain(OSSL_CMP_CTX *ctx, X509_STORE *own_trusted, + STACK_OF(X509) *candidates) +{ + STACK_OF(X509) *chain; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + + if (!ossl_x509_add_certs_new(&ctx->untrusted, candidates, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) + return 0; + + ossl_cmp_debug(ctx, "trying to build chain for own CMP signer cert"); + chain = X509_build_chain(ctx->cert, ctx->untrusted, own_trusted, 0, + ctx->libctx, ctx->propq); + if (chain == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_FAILED_BUILDING_OWN_CHAIN); + return 0; + } + ossl_cmp_debug(ctx, "success building chain for own CMP signer cert"); + ctx->chain = chain; + return 1; +} + +/* + * Set the old certificate that we are updating in KUR + * or the certificate to be revoked in RR, respectively. + * Also used as reference cert (defaulting to cert) for deriving subject DN + * and SANs. Its issuer is used as default recipient in the CMP message header. + */ +DEFINE_OSSL_CMP_CTX_set1_up_ref(oldCert, X509) + +/* Set the PKCS#10 CSR to be sent in P10CR */ +DEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ) + +/* + * Set the (newly received in IP/KUP/CP) certificate in the context. + * This only permits for one cert to be enrolled at a time. + */ +int ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert) +{ + if (!ossl_assert(ctx != NULL)) + return 0; + + X509_free(ctx->newCert); + ctx->newCert = cert; + return 1; +} + +/* + * Get the (newly received in IP/KUP/CP) client certificate from the context + * This only permits for one client cert to be received... + */ +X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return ctx->newCert; +} + +/* Set the client's current private key */ +DEFINE_OSSL_CMP_CTX_set1_up_ref(pkey, EVP_PKEY) + +/* Set new key pair. Used e.g. when doing Key Update */ +int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + + EVP_PKEY_free(ctx->newPkey); + ctx->newPkey = pkey; + ctx->newPkey_priv = priv; + return 1; +} + +/* Get the private/public key to use for cert enrollment, or NULL on error */ +EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + + if (ctx->newPkey != NULL) + return priv && !ctx->newPkey_priv ? NULL : ctx->newPkey; + if (ctx->p10CSR != NULL) + return priv ? NULL : X509_REQ_get0_pubkey(ctx->p10CSR); + return ctx->pkey; /* may be NULL */ +} + +/* Set the given transactionID to the context */ +int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx, + const ASN1_OCTET_STRING *id) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + return ossl_cmp_asn1_octet_string_set1(&ctx->transactionID, id); +} + +/* Set the nonce to be used for the recipNonce in the message created next */ +int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx, + const ASN1_OCTET_STRING *nonce) +{ + if (!ossl_assert(ctx != NULL)) + return 0; + return ossl_cmp_asn1_octet_string_set1(&ctx->recipNonce, nonce); +} + +/* Stores the given nonce as the last senderNonce sent out */ +int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx, + const ASN1_OCTET_STRING *nonce) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + return ossl_cmp_asn1_octet_string_set1(&ctx->senderNonce, nonce); +} + +/* Set the proxy server to use for HTTP(S) connections */ +DEFINE_OSSL_CMP_CTX_set1(proxy, char) + +/* Set the (HTTP) host name of the CMP server */ +DEFINE_OSSL_CMP_CTX_set1(server, char) + +/* Set the server exclusion list of the HTTP proxy server */ +DEFINE_OSSL_CMP_CTX_set1(no_proxy, char) + +/* Set the http connect/disconnect callback function to be used for HTTP(S) */ +int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx->http_cb = cb; + return 1; +} + +/* Set argument optionally to be used by the http connect/disconnect callback */ +int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx->http_cb_arg = arg; + return 1; +} + +/* + * Get argument optionally to be used by the http connect/disconnect callback + * Returns callback argument set previously (NULL if not set or on error) + */ +void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return ctx->http_cb_arg; +} + +/* Set callback function for sending CMP request and receiving response */ +int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx->transfer_cb = cb; + return 1; +} + +/* Set argument optionally to be used by the transfer callback */ +int OSSL_CMP_CTX_set_transfer_cb_arg(OSSL_CMP_CTX *ctx, void *arg) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx->transfer_cb_arg = arg; + return 1; +} + +/* + * Get argument optionally to be used by the transfer callback. + * Returns callback argument set previously (NULL if not set or on error) + */ +void *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return ctx->transfer_cb_arg; +} + +/** Set the HTTP server port to be used */ +int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx->serverPort = port; + return 1; +} + +/* Set the HTTP path to be used on the server (e.g "pkix/") */ +DEFINE_OSSL_CMP_CTX_set1(serverPath, char) + +/* Set the failInfo error code as bit encoding in OSSL_CMP_CTX */ +int ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info) +{ + if (!ossl_assert(ctx != NULL)) + return 0; + ctx->failInfoCode = fail_info; + return 1; +} + +/* + * Get the failInfo error code in OSSL_CMP_CTX as bit encoding. + * Returns bit string as integer on success, -1 on error + */ +int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return -1; + } + return ctx->failInfoCode; +} + +/* Set a Boolean or integer option of the context to the "val" arg */ +int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) +{ + int min_val; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + + switch (opt) { + case OSSL_CMP_OPT_REVOCATION_REASON: + min_val = OCSP_REVOKED_STATUS_NOSTATUS; + break; + case OSSL_CMP_OPT_POPO_METHOD: + min_val = OSSL_CRMF_POPO_NONE; + break; + default: + min_val = 0; + break; + } + if (val < min_val) { + ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_SMALL); + return 0; + } + + switch (opt) { + case OSSL_CMP_OPT_LOG_VERBOSITY: + if (val > OSSL_CMP_LOG_MAX) { + ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE); + return 0; + } + ctx->log_verbosity = val; + break; + case OSSL_CMP_OPT_IMPLICIT_CONFIRM: + ctx->implicitConfirm = val; + break; + case OSSL_CMP_OPT_DISABLE_CONFIRM: + ctx->disableConfirm = val; + break; + case OSSL_CMP_OPT_UNPROTECTED_SEND: + ctx->unprotectedSend = val; + break; + case OSSL_CMP_OPT_UNPROTECTED_ERRORS: + ctx->unprotectedErrors = val; + break; + case OSSL_CMP_OPT_VALIDITY_DAYS: + ctx->days = val; + break; + case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT: + ctx->SubjectAltName_nodefault = val; + break; + case OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL: + ctx->setSubjectAltNameCritical = val; + break; + case OSSL_CMP_OPT_POLICIES_CRITICAL: + ctx->setPoliciesCritical = val; + break; + case OSSL_CMP_OPT_IGNORE_KEYUSAGE: + ctx->ignore_keyusage = val; + break; + case OSSL_CMP_OPT_POPO_METHOD: + if (val > OSSL_CRMF_POPO_KEYAGREE) { + ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE); + return 0; + } + ctx->popoMethod = val; + break; + case OSSL_CMP_OPT_DIGEST_ALGNID: + if (!cmp_ctx_set_md(ctx, &ctx->digest, val)) + return 0; + break; + case OSSL_CMP_OPT_OWF_ALGNID: + if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, val)) + return 0; + break; + case OSSL_CMP_OPT_MAC_ALGNID: + ctx->pbm_mac = val; + break; + case OSSL_CMP_OPT_KEEP_ALIVE: + ctx->keep_alive = val; + break; + case OSSL_CMP_OPT_MSG_TIMEOUT: + ctx->msg_timeout = val; + break; + case OSSL_CMP_OPT_TOTAL_TIMEOUT: + ctx->total_timeout = val; + break; + case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR: + ctx->permitTAInExtraCertsForIR = val; + break; + case OSSL_CMP_OPT_REVOCATION_REASON: + if (val > OCSP_REVOKED_STATUS_AACOMPROMISE) { + ERR_raise(ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE); + return 0; + } + ctx->revocationReason = val; + break; + default: + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_OPTION); + return 0; + } + + return 1; +} + +/* + * Reads a Boolean or integer option value from the context. + * Returns -1 on error (which is the default OSSL_CMP_OPT_REVOCATION_REASON) + */ +int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return -1; + } + + switch (opt) { + case OSSL_CMP_OPT_LOG_VERBOSITY: + return ctx->log_verbosity; + case OSSL_CMP_OPT_IMPLICIT_CONFIRM: + return ctx->implicitConfirm; + case OSSL_CMP_OPT_DISABLE_CONFIRM: + return ctx->disableConfirm; + case OSSL_CMP_OPT_UNPROTECTED_SEND: + return ctx->unprotectedSend; + case OSSL_CMP_OPT_UNPROTECTED_ERRORS: + return ctx->unprotectedErrors; + case OSSL_CMP_OPT_VALIDITY_DAYS: + return ctx->days; + case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT: + return ctx->SubjectAltName_nodefault; + case OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL: + return ctx->setSubjectAltNameCritical; + case OSSL_CMP_OPT_POLICIES_CRITICAL: + return ctx->setPoliciesCritical; + case OSSL_CMP_OPT_IGNORE_KEYUSAGE: + return ctx->ignore_keyusage; + case OSSL_CMP_OPT_POPO_METHOD: + return ctx->popoMethod; + case OSSL_CMP_OPT_DIGEST_ALGNID: + return EVP_MD_get_type(ctx->digest); + case OSSL_CMP_OPT_OWF_ALGNID: + return EVP_MD_get_type(ctx->pbm_owf); + case OSSL_CMP_OPT_MAC_ALGNID: + return ctx->pbm_mac; + case OSSL_CMP_OPT_KEEP_ALIVE: + return ctx->keep_alive; + case OSSL_CMP_OPT_MSG_TIMEOUT: + return ctx->msg_timeout; + case OSSL_CMP_OPT_TOTAL_TIMEOUT: + return ctx->total_timeout; + case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR: + return ctx->permitTAInExtraCertsForIR; + case OSSL_CMP_OPT_REVOCATION_REASON: + return ctx->revocationReason; + default: + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_OPTION); + return -1; + } +} diff --git a/crypto/openssl/crypto/cmp/cmp_err.c b/crypto/openssl/crypto/cmp/cmp_err.c new file mode 100644 index 000000000000..fe7b96348bae --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_err.c @@ -0,0 +1,178 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/cmperr.h" + +#ifndef OPENSSL_NO_CMP + +# ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA CMP_str_reasons[] = { + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ALGORITHM_NOT_SUPPORTED), + "algorithm not supported"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_CHECKAFTER_IN_POLLREP), + "bad checkafter in pollrep"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_REQUEST_ID), "bad request id"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTHASH_UNMATCHED), "certhash unmatched"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTID_NOT_FOUND), "certid not found"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_ACCEPTED), + "certificate not accepted"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_FOUND), + "certificate not found"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTREQMSG_NOT_FOUND), + "certreqmsg not found"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTRESPONSE_NOT_FOUND), + "certresponse not found"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH), + "cert and key do not match"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKAFTER_OUT_OF_RANGE), + "checkafter out of range"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING), + "encountered keyupdatewarning"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_WAITING), + "encountered waiting"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CALCULATING_PROTECTION), + "error calculating protection"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTCONF), + "error creating certconf"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTREP), + "error creating certrep"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTREQ), + "error creating certreq"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_ERROR), + "error creating error"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENM), + "error creating genm"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENP), + "error creating genp"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_PKICONF), + "error creating pkiconf"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_POLLREP), + "error creating pollrep"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_POLLREQ), + "error creating pollreq"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_RP), "error creating rp"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_RR), "error creating rr"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PARSING_PKISTATUS), + "error parsing pkistatus"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROCESSING_MESSAGE), + "error processing message"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROTECTING_MESSAGE), + "error protecting message"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_SETTING_CERTHASH), + "error setting certhash"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_UNEXPECTED_CERTCONF), + "error unexpected certconf"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_PROTECTION), + "error validating protection"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_SIGNATURE), + "error validating signature"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_BUILDING_OWN_CHAIN), + "failed building own chain"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY), + "failed extracting pubkey"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILURE_OBTAINING_RANDOM), + "failure obtaining random"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAIL_INFO_OUT_OF_RANGE), + "fail info out of range"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ARGS), "invalid args"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_OPTION), "invalid option"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_CERTID), "missing certid"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION), + "missing key input for creating protection"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE), + "missing key usage digitalsignature"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_P10CSR), "missing p10csr"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PBM_SECRET), "missing pbm secret"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PRIVATE_KEY), + "missing private key"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PROTECTION), "missing protection"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_REFERENCE_CERT), + "missing reference cert"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_SECRET), "missing secret"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_SENDER_IDENTIFICATION), + "missing sender identification"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_TRUST_ANCHOR), + "missing trust anchor"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_TRUST_STORE), + "missing trust store"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED), + "multiple requests not supported"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED), + "multiple responses not supported"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_SAN_SOURCES), + "multiple san sources"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_STDIO), "no stdio"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_SUITABLE_SENDER_CERT), + "no suitable sender cert"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NULL_ARGUMENT), "null argument"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKIBODY_ERROR), "pkibody error"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKISTATUSINFO_NOT_FOUND), + "pkistatusinfo not found"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_POLLING_FAILED), "polling failed"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_POTENTIALLY_INVALID_CERTIFICATE), + "potentially invalid certificate"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_RECEIVED_ERROR), "received error"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_RECIPNONCE_UNMATCHED), + "recipnonce unmatched"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_REQUEST_NOT_ACCEPTED), + "request not accepted"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_REQUEST_REJECTED_BY_SERVER), + "request rejected by server"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED), + "sender generalname type not supported"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG), + "srvcert does not validate msg"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TOTAL_TIMEOUT), "total timeout"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSACTIONID_UNMATCHED), + "transactionid unmatched"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSFER_ERROR), "transfer error"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS), + "unexpected pkistatus"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PVNO), "unexpected pvno"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID), + "unknown algorithm id"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_PKISTATUS), "unknown pkistatus"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_ALGORITHM), + "unsupported algorithm"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_KEY_TYPE), + "unsupported key type"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC), + "unsupported protection alg dhbasedmac"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_VALUE_TOO_LARGE), "value too large"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_VALUE_TOO_SMALL), "value too small"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_ALGORITHM_OID), + "wrong algorithm oid"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_CERTID), "wrong certid"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_CERTID_IN_RP), "wrong certid in rp"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_PBM_VALUE), "wrong pbm value"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_RP_COMPONENT_COUNT), + "wrong rp component count"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_SERIAL_IN_RP), "wrong serial in rp"}, + {0, NULL} +}; + +# endif + +int ossl_err_load_CMP_strings(void) +{ +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(CMP_str_reasons[0].error) == NULL) + ERR_load_strings_const(CMP_str_reasons); +# endif + return 1; +} +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/cmp/cmp_hdr.c b/crypto/openssl/crypto/cmp/cmp_hdr.c new file mode 100644 index 000000000000..8c553af61a53 --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_hdr.c @@ -0,0 +1,369 @@ +/* + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* CMP functions for PKIHeader handling */ + +#include "cmp_local.h" + +#include + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include + +int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno) +{ + if (!ossl_assert(hdr != NULL)) + return 0; + return ASN1_INTEGER_set(hdr->pvno, pvno); +} + +int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr) +{ + int64_t pvno; + + if (!ossl_assert(hdr != NULL)) + return -1; + if (!ASN1_INTEGER_get_int64(&pvno, hdr->pvno) || pvno < 0 || pvno > INT_MAX) + return -1; + return (int)pvno; +} + +int ossl_cmp_hdr_get_protection_nid(const OSSL_CMP_PKIHEADER *hdr) +{ + if (!ossl_assert(hdr != NULL) + || hdr->protectionAlg == NULL) + return NID_undef; + return OBJ_obj2nid(hdr->protectionAlg->algorithm); +} + +ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const + OSSL_CMP_PKIHEADER *hdr) +{ + if (hdr == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return hdr->transactionID; +} + +ASN1_OCTET_STRING *ossl_cmp_hdr_get0_senderNonce(const OSSL_CMP_PKIHEADER *hdr) +{ + if (!ossl_assert(hdr != NULL)) + return NULL; + return hdr->senderNonce; +} + +ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr) +{ + if (hdr == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return hdr->recipNonce; +} + +/* a NULL-DN as an empty sequence of RDNs */ +int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name) +{ + return name == NULL + || (name->type == GEN_DIRNAME && IS_NULL_DN(name->d.directoryName)); +} + +/* assign to *tgt a copy of src (which may be NULL to indicate an empty DN) */ +static int set1_general_name(GENERAL_NAME **tgt, const X509_NAME *src) +{ + GENERAL_NAME *name; + + if (!ossl_assert(tgt != NULL)) + return 0; + if ((name = GENERAL_NAME_new()) == NULL) + goto err; + name->type = GEN_DIRNAME; + + if (src == NULL) { /* NULL-DN */ + if ((name->d.directoryName = X509_NAME_new()) == NULL) + goto err; + } else if (!X509_NAME_set(&name->d.directoryName, src)) { + goto err; + } + + GENERAL_NAME_free(*tgt); + *tgt = name; + + return 1; + + err: + GENERAL_NAME_free(name); + return 0; +} + +/* + * Set the sender name in PKIHeader. + * when nm is NULL, sender is set to an empty string + * returns 1 on success, 0 on error + */ +int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm) +{ + if (!ossl_assert(hdr != NULL)) + return 0; + return set1_general_name(&hdr->sender, nm); +} + +int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm) +{ + if (!ossl_assert(hdr != NULL)) + return 0; + return set1_general_name(&hdr->recipient, nm); +} + +int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr) +{ + if (!ossl_assert(hdr != NULL)) + return 0; + if (hdr->messageTime == NULL + && (hdr->messageTime = ASN1_GENERALIZEDTIME_new()) == NULL) + return 0; + return ASN1_GENERALIZEDTIME_set(hdr->messageTime, time(NULL)) != NULL; +} + +/* assign to *tgt a random byte array of given length */ +static int set_random(ASN1_OCTET_STRING **tgt, OSSL_CMP_CTX *ctx, size_t len) +{ + unsigned char *bytes = OPENSSL_malloc(len); + int res = 0; + + if (bytes == NULL || RAND_bytes_ex(ctx->libctx, bytes, len, 0) <= 0) + ERR_raise(ERR_LIB_CMP, CMP_R_FAILURE_OBTAINING_RANDOM); + else + res = ossl_cmp_asn1_octet_string_set1_bytes(tgt, bytes, len); + OPENSSL_free(bytes); + return res; +} + +int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr, + const ASN1_OCTET_STRING *senderKID) +{ + if (!ossl_assert(hdr != NULL)) + return 0; + return ossl_cmp_asn1_octet_string_set1(&hdr->senderKID, senderKID); +} + +/* push the given text string to the given PKIFREETEXT ft */ +int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text) +{ + if (!ossl_assert(hdr != NULL && text != NULL)) + return 0; + + if (hdr->freeText == NULL + && (hdr->freeText = sk_ASN1_UTF8STRING_new_null()) == NULL) + return 0; + + return sk_ASN1_UTF8STRING_push(hdr->freeText, text); +} + +int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text) +{ + if (!ossl_assert(hdr != NULL && text != NULL)) + return 0; + + if (hdr->freeText == NULL + && (hdr->freeText = sk_ASN1_UTF8STRING_new_null()) == NULL) + return 0; + + return + ossl_cmp_sk_ASN1_UTF8STRING_push_str(hdr->freeText, (char *)text->data, + text->length); +} + +int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr, + OSSL_CMP_ITAV *itav) +{ + if (!ossl_assert(hdr != NULL && itav != NULL)) + return 0; + return OSSL_CMP_ITAV_push0_stack_item(&hdr->generalInfo, itav); +} + +int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr, + const STACK_OF(OSSL_CMP_ITAV) *itavs) +{ + int i; + OSSL_CMP_ITAV *itav; + + if (!ossl_assert(hdr != NULL)) + return 0; + + for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) { + itav = OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs, i)); + if (itav == NULL) + return 0; + + if (!ossl_cmp_hdr_generalInfo_push0_item(hdr, itav)) { + OSSL_CMP_ITAV_free(itav); + return 0; + } + } + return 1; +} + +int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr) +{ + OSSL_CMP_ITAV *itav; + ASN1_TYPE *asn1null; + + if (!ossl_assert(hdr != NULL)) + return 0; + asn1null = (ASN1_TYPE *)ASN1_NULL_new(); + if (asn1null == NULL) + return 0; + if ((itav = OSSL_CMP_ITAV_create(OBJ_nid2obj(NID_id_it_implicitConfirm), + asn1null)) == NULL) + goto err; + if (!ossl_cmp_hdr_generalInfo_push0_item(hdr, itav)) + goto err; + return 1; + + err: + ASN1_TYPE_free(asn1null); + OSSL_CMP_ITAV_free(itav); + return 0; +} + +/* return 1 if implicitConfirm in the generalInfo field of the header is set */ +int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr) +{ + int itavCount; + int i; + OSSL_CMP_ITAV *itav; + + if (!ossl_assert(hdr != NULL)) + return 0; + + itavCount = sk_OSSL_CMP_ITAV_num(hdr->generalInfo); + for (i = 0; i < itavCount; i++) { + itav = sk_OSSL_CMP_ITAV_value(hdr->generalInfo, i); + if (itav != NULL + && OBJ_obj2nid(itav->infoType) == NID_id_it_implicitConfirm) + return 1; + } + + return 0; +} + +/* + * set ctx->transactionID in CMP header + * if ctx->transactionID is NULL, a random one is created with 128 bit + * according to section 5.1.1: + * + * It is RECOMMENDED that the clients fill the transactionID field with + * 128 bits of (pseudo-) random data for the start of a transaction to + * reduce the probability of having the transactionID in use at the server. + */ +int ossl_cmp_hdr_set_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr) +{ + if (ctx->transactionID == NULL) { + char *tid; + + if (!set_random(&ctx->transactionID, ctx, + OSSL_CMP_TRANSACTIONID_LENGTH)) + return 0; + tid = OPENSSL_buf2hexstr(ctx->transactionID->data, + ctx->transactionID->length); + if (tid != NULL) + ossl_cmp_log1(DEBUG, ctx, + "Starting new transaction with ID=%s", tid); + OPENSSL_free(tid); + } + + return ossl_cmp_asn1_octet_string_set1(&hdr->transactionID, + ctx->transactionID); +} + +/* fill in all fields of the hdr according to the info given in ctx */ +int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr) +{ + const X509_NAME *sender; + const X509_NAME *rcp = NULL; + + if (!ossl_assert(ctx != NULL && hdr != NULL)) + return 0; + + /* set the CMP version */ + if (!ossl_cmp_hdr_set_pvno(hdr, OSSL_CMP_PVNO)) + return 0; + + /* + * If neither protection cert nor oldCert nor subject are given, + * sender name is not known to the client and thus set to NULL-DN + */ + sender = ctx->cert != NULL ? X509_get_subject_name(ctx->cert) : + ctx->oldCert != NULL ? X509_get_subject_name(ctx->oldCert) : + ctx->subjectName; + if (!ossl_cmp_hdr_set1_sender(hdr, sender)) + return 0; + + /* determine recipient entry in PKIHeader */ + if (ctx->recipient != NULL) + rcp = ctx->recipient; + else if (ctx->srvCert != NULL) + rcp = X509_get_subject_name(ctx->srvCert); + else if (ctx->issuer != NULL) + rcp = ctx->issuer; + else if (ctx->oldCert != NULL) + rcp = X509_get_issuer_name(ctx->oldCert); + else if (ctx->cert != NULL) + rcp = X509_get_issuer_name(ctx->cert); + if (!ossl_cmp_hdr_set1_recipient(hdr, rcp)) + return 0; + + /* set current time as message time */ + if (!ossl_cmp_hdr_update_messageTime(hdr)) + return 0; + + if (ctx->recipNonce != NULL + && !ossl_cmp_asn1_octet_string_set1(&hdr->recipNonce, + ctx->recipNonce)) + return 0; + + if (!ossl_cmp_hdr_set_transactionID(ctx, hdr)) + return 0; + + /*- + * set random senderNonce + * according to section 5.1.1: + * + * senderNonce present + * -- 128 (pseudo-)random bits + * The senderNonce and recipNonce fields protect the PKIMessage against + * replay attacks. The senderNonce will typically be 128 bits of + * (pseudo-) random data generated by the sender, whereas the recipNonce + * is copied from the senderNonce of the previous message in the + * transaction. + */ + if (!set_random(&hdr->senderNonce, ctx, OSSL_CMP_SENDERNONCE_LENGTH)) + return 0; + + /* store senderNonce - for cmp with recipNonce in next outgoing msg */ + if (!OSSL_CMP_CTX_set1_senderNonce(ctx, hdr->senderNonce)) + return 0; + + /*- + * freeText [7] PKIFreeText OPTIONAL, + * -- this may be used to indicate context-specific instructions + * -- (this field is intended for human consumption) + */ + if (ctx->freeText != NULL + && !ossl_cmp_hdr_push1_freeText(hdr, ctx->freeText)) + return 0; + + return 1; +} diff --git a/crypto/openssl/crypto/cmp/cmp_http.c b/crypto/openssl/crypto/cmp/cmp_http.c new file mode 100644 index 000000000000..d29bfa8674ad --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_http.c @@ -0,0 +1,106 @@ +/* + * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +#include +#include +#include "internal/sockets.h" + +#include +#include "cmp_local.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include +#include +#include +#include +#include + +static int keep_alive(int keep_alive, int body_type) +{ + if (keep_alive != 0 + /* + * Ask for persistent connection only if may need more round trips. + * Do so even with disableConfirm because polling might be needed. + */ + && body_type != OSSL_CMP_PKIBODY_IR + && body_type != OSSL_CMP_PKIBODY_CR + && body_type != OSSL_CMP_PKIBODY_P10CR + && body_type != OSSL_CMP_PKIBODY_KUR + && body_type != OSSL_CMP_PKIBODY_POLLREQ) + keep_alive = 0; + return keep_alive; +} + +/* + * Send the PKIMessage req and on success return the response, else NULL. + * Any previous error queue entries will likely be removed by ERR_clear_error(). + */ +OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *req) +{ + char server_port[32] = { '\0' }; + STACK_OF(CONF_VALUE) *headers = NULL; + const char content_type_pkix[] = "application/pkixcmp"; + int tls_used; + const ASN1_ITEM *it = ASN1_ITEM_rptr(OSSL_CMP_MSG); + BIO *req_mem, *rsp; + OSSL_CMP_MSG *res = NULL; + + if (ctx == NULL || req == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + + if (!X509V3_add_value("Pragma", "no-cache", &headers)) + return NULL; + if ((req_mem = ASN1_item_i2d_mem_bio(it, (const ASN1_VALUE *)req)) == NULL) + goto err; + + if (ctx->serverPort != 0) + BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort); + tls_used = OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL; + if (ctx->http_ctx == NULL) + ossl_cmp_log3(DEBUG, ctx, "connecting to CMP server %s:%s%s", + ctx->server, server_port, tls_used ? " using TLS" : ""); + + rsp = OSSL_HTTP_transfer(&ctx->http_ctx, ctx->server, server_port, + ctx->serverPath, tls_used, + ctx->proxy, ctx->no_proxy, + NULL /* bio */, NULL /* rbio */, + ctx->http_cb, OSSL_CMP_CTX_get_http_cb_arg(ctx), + 0 /* buf_size */, headers, + content_type_pkix, req_mem, + content_type_pkix, 1 /* expect_asn1 */, + OSSL_HTTP_DEFAULT_MAX_RESP_LEN, + ctx->msg_timeout, + keep_alive(ctx->keep_alive, req->body->type)); + BIO_free(req_mem); + res = (OSSL_CMP_MSG *)ASN1_item_d2i_bio(it, rsp, NULL); + BIO_free(rsp); + + if (ctx->http_ctx == NULL) + ossl_cmp_debug(ctx, "disconnected from CMP server"); + /* + * Note that on normal successful end of the transaction the connection + * is not closed at this level, but this will be done by the CMP client + * application via OSSL_CMP_CTX_free() or OSSL_CMP_CTX_reinit(). + */ + if (res != NULL) + ossl_cmp_debug(ctx, "finished reading response from CMP server"); + err: + sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); + return res; +} diff --git a/crypto/openssl/crypto/cmp/cmp_local.h b/crypto/openssl/crypto/cmp/cmp_local.h new file mode 100644 index 000000000000..3da021043b81 --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_local.h @@ -0,0 +1,930 @@ +/* + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_CRYPTO_CMP_LOCAL_H +# define OSSL_CRYPTO_CMP_LOCAL_H + +# include "internal/cryptlib.h" + +# include +# include + +/* explicit #includes not strictly needed since implied by the above: */ +# include +# include +# include +# include +# include +# include "crypto/x509.h" + +#define IS_NULL_DN(name) (X509_NAME_get_entry(name, 0) == NULL) + +/* + * this structure is used to store the context for CMP sessions + */ +struct ossl_cmp_ctx_st { + OSSL_LIB_CTX *libctx; + char *propq; + OSSL_CMP_log_cb_t log_cb; /* log callback for error/debug/etc. output */ + OSSL_CMP_severity log_verbosity; /* level of verbosity of log output */ + + /* message transfer */ + OSSL_CMP_transfer_cb_t transfer_cb; /* default: OSSL_CMP_MSG_http_perform */ + void *transfer_cb_arg; /* allows to store optional argument to cb */ + /* HTTP-based transfer */ + OSSL_HTTP_REQ_CTX *http_ctx; + char *serverPath; + char *server; + int serverPort; + char *proxy; + char *no_proxy; + int keep_alive; /* persistent connection: 0=no, 1=prefer, 2=require */ + int msg_timeout; /* max seconds to wait for each CMP message round trip */ + int total_timeout; /* max number of seconds an enrollment may take, incl. */ + /* attempts polling for a response if a 'waiting' PKIStatus is received */ + time_t end_time; /* session start time + totaltimeout */ + OSSL_HTTP_bio_cb_t http_cb; + void *http_cb_arg; /* allows to store optional argument to cb */ + + /* server authentication */ + /* + * unprotectedErrors may be set as workaround for broken server responses: + * accept missing or invalid protection of regular error messages, negative + * certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf + */ + int unprotectedErrors; + X509 *srvCert; /* certificate used to identify the server */ + X509 *validatedSrvCert; /* caches any already validated server cert */ + X509_NAME *expected_sender; /* expected sender in header of response */ + X509_STORE *trusted; /* trust store maybe w CRLs and cert verify callback */ + STACK_OF(X509) *untrusted; /* untrusted (intermediate CA) certs */ + int ignore_keyusage; /* ignore key usage entry when validating certs */ + /* + * permitTAInExtraCertsForIR allows use of root certs in extracerts + * when validating message protection; this is used for 3GPP-style E.7 + */ + int permitTAInExtraCertsForIR; + + /* client authentication */ + int unprotectedSend; /* send unprotected PKI messages */ + X509 *cert; /* protection cert used to identify and sign for MSG_SIG_ALG */ + STACK_OF(X509) *chain; /* (cached) chain of protection cert including it */ + EVP_PKEY *pkey; /* the key pair corresponding to cert */ + ASN1_OCTET_STRING *referenceValue; /* optional user name for MSG_MAC_ALG */ + ASN1_OCTET_STRING *secretValue; /* password/shared secret for MSG_MAC_ALG */ + /* PBMParameters for MSG_MAC_ALG */ + size_t pbm_slen; /* salt length, currently fixed to 16 */ + EVP_MD *pbm_owf; /* one-way function (OWF), default: SHA256 */ + int pbm_itercnt; /* OWF iteration count, currently fixed to 500 */ + int pbm_mac; /* NID of MAC algorithm, default: HMAC-SHA1 as per RFC 4210 */ + + /* CMP message header and extra certificates */ + X509_NAME *recipient; /* to set in recipient in pkiheader */ + EVP_MD *digest; /* digest used in MSG_SIG_ALG and POPO, default SHA256 */ + ASN1_OCTET_STRING *transactionID; /* the current transaction ID */ + ASN1_OCTET_STRING *senderNonce; /* last nonce sent */ + ASN1_OCTET_STRING *recipNonce; /* last nonce received */ + ASN1_UTF8STRING *freeText; /* optional string to include each msg */ + STACK_OF(OSSL_CMP_ITAV) *geninfo_ITAVs; + int implicitConfirm; /* set implicitConfirm in IR/KUR/CR messages */ + int disableConfirm; /* disable certConf in IR/KUR/CR for broken servers */ + STACK_OF(X509) *extraCertsOut; /* to be included in request messages */ + + /* certificate template */ + EVP_PKEY *newPkey; /* explicit new private/public key for cert enrollment */ + int newPkey_priv; /* flag indicating if newPkey contains private key */ + X509_NAME *issuer; /* issuer name to used in cert template */ + int days; /* Number of days new certificates are asked to be valid for */ + X509_NAME *subjectName; /* subject name to be used in cert template */ + STACK_OF(GENERAL_NAME) *subjectAltNames; /* to add to the cert template */ + int SubjectAltName_nodefault; + int setSubjectAltNameCritical; + X509_EXTENSIONS *reqExtensions; /* exts to be added to cert template */ + CERTIFICATEPOLICIES *policies; /* policies to be included in extensions */ + int setPoliciesCritical; + int popoMethod; /* Proof-of-possession mechanism; default: signature */ + X509 *oldCert; /* cert to be updated (via KUR) or to be revoked (via RR) */ + X509_REQ *p10CSR; /* for P10CR: PKCS#10 CSR to be sent */ + + /* misc body contents */ + int revocationReason; /* revocation reason code to be included in RR */ + STACK_OF(OSSL_CMP_ITAV) *genm_ITAVs; /* content of general message */ + + /* result returned in responses */ + int status; /* PKIStatus of last received IP/CP/KUP/RP/error or -1 */ + OSSL_CMP_PKIFREETEXT *statusString; /* of last IP/CP/KUP/RP/error */ + int failInfoCode; /* failInfoCode of last received IP/CP/KUP/error, or -1 */ + X509 *newCert; /* newly enrolled cert received from the CA */ + STACK_OF(X509) *newChain; /* chain of newly enrolled cert received */ + STACK_OF(X509) *caPubs; /* CA certs received from server (in IP message) */ + STACK_OF(X509) *extraCertsIn; /* extraCerts received from server */ + + /* certificate confirmation */ + OSSL_CMP_certConf_cb_t certConf_cb; /* callback for app checking new cert */ + void *certConf_cb_arg; /* allows to store an argument individual to cb */ +} /* OSSL_CMP_CTX */; + +/* + * ########################################################################## + * ASN.1 DECLARATIONS + * ########################################################################## + */ + +/*- + * RevAnnContent ::= SEQUENCE { + * status PKIStatus, + * certId CertId, + * willBeRevokedAt GeneralizedTime, + * badSinceDate GeneralizedTime, + * crlDetails Extensions OPTIONAL + * -- extra CRL details (e.g., crl number, reason, location, etc.) + * } + */ +typedef struct ossl_cmp_revanncontent_st { + ASN1_INTEGER *status; + OSSL_CRMF_CERTID *certId; + ASN1_GENERALIZEDTIME *willBeRevokedAt; + ASN1_GENERALIZEDTIME *badSinceDate; + X509_EXTENSIONS *crlDetails; +} OSSL_CMP_REVANNCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_REVANNCONTENT) + +/*- + * Challenge ::= SEQUENCE { + * owf AlgorithmIdentifier OPTIONAL, + * + * -- MUST be present in the first Challenge; MAY be omitted in + * -- any subsequent Challenge in POPODecKeyChallContent (if + * -- omitted, then the owf used in the immediately preceding + * -- Challenge is to be used). + * + * witness OCTET STRING, + * -- the result of applying the one-way function (owf) to a + * -- randomly-generated INTEGER, A. [Note that a different + * -- INTEGER MUST be used for each Challenge.] + * challenge OCTET STRING + * -- the encryption (under the public key for which the cert. + * -- request is being made) of Rand, where Rand is specified as + * -- Rand ::= SEQUENCE { + * -- int INTEGER, + * -- - the randomly-generated INTEGER A (above) + * -- sender GeneralName + * -- - the sender's name (as included in PKIHeader) + * -- } + * } + */ +typedef struct ossl_cmp_challenge_st { + X509_ALGOR *owf; + ASN1_OCTET_STRING *witness; + ASN1_OCTET_STRING *challenge; +} OSSL_CMP_CHALLENGE; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CHALLENGE) + +/*- + * CAKeyUpdAnnContent ::= SEQUENCE { + * oldWithNew Certificate, + * newWithOld Certificate, + * newWithNew Certificate + * } + */ +typedef struct ossl_cmp_cakeyupdanncontent_st { + X509 *oldWithNew; + X509 *newWithOld; + X509 *newWithNew; +} OSSL_CMP_CAKEYUPDANNCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT) + +/*- + * declared already here as it will be used in OSSL_CMP_MSG (nested) and + * infoType and infoValue + */ +typedef STACK_OF(OSSL_CMP_MSG) OSSL_CMP_MSGS; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_MSGS) + +/*- + * InfoTypeAndValue ::= SEQUENCE { + * infoType OBJECT IDENTIFIER, + * infoValue ANY DEFINED BY infoType OPTIONAL + * } + */ +struct ossl_cmp_itav_st { + ASN1_OBJECT *infoType; + union { + char *ptr; + /* NID_id_it_caProtEncCert - CA Protocol Encryption Certificate */ + X509 *caProtEncCert; + /* NID_id_it_signKeyPairTypes - Signing Key Pair Types */ + STACK_OF(X509_ALGOR) *signKeyPairTypes; + /* NID_id_it_encKeyPairTypes - Encryption/Key Agreement Key Pair Types */ + STACK_OF(X509_ALGOR) *encKeyPairTypes; + /* NID_id_it_preferredSymmAlg - Preferred Symmetric Algorithm */ + X509_ALGOR *preferredSymmAlg; + /* NID_id_it_caKeyUpdateInfo - Updated CA Key Pair */ + OSSL_CMP_CAKEYUPDANNCONTENT *caKeyUpdateInfo; + /* NID_id_it_currentCRL - CRL */ + X509_CRL *currentCRL; + /* NID_id_it_unsupportedOIDs - Unsupported Object Identifiers */ + STACK_OF(ASN1_OBJECT) *unsupportedOIDs; + /* NID_id_it_keyPairParamReq - Key Pair Parameters Request */ + ASN1_OBJECT *keyPairParamReq; + /* NID_id_it_keyPairParamRep - Key Pair Parameters Response */ + X509_ALGOR *keyPairParamRep; + /* NID_id_it_revPassphrase - Revocation Passphrase */ + OSSL_CRMF_ENCRYPTEDVALUE *revPassphrase; + /* NID_id_it_implicitConfirm - ImplicitConfirm */ + ASN1_NULL *implicitConfirm; + /* NID_id_it_confirmWaitTime - ConfirmWaitTime */ + ASN1_GENERALIZEDTIME *confirmWaitTime; + /* NID_id_it_origPKIMessage - origPKIMessage */ + OSSL_CMP_MSGS *origPKIMessage; + /* NID_id_it_suppLangTags - Supported Language Tags */ + STACK_OF(ASN1_UTF8STRING) *suppLangTagsValue; + /* this is to be used for so far undeclared objects */ + ASN1_TYPE *other; + } infoValue; +} /* OSSL_CMP_ITAV */; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ITAV) + +typedef struct ossl_cmp_certorenccert_st { + int type; + union { + X509 *certificate; + OSSL_CRMF_ENCRYPTEDVALUE *encryptedCert; + } value; +} OSSL_CMP_CERTORENCCERT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTORENCCERT) + +/*- + * CertifiedKeyPair ::= SEQUENCE { + * certOrEncCert CertOrEncCert, + * privateKey [0] EncryptedValue OPTIONAL, + * -- see [CRMF] for comment on encoding + * publicationInfo [1] PKIPublicationInfo OPTIONAL + * } + */ +typedef struct ossl_cmp_certifiedkeypair_st { + OSSL_CMP_CERTORENCCERT *certOrEncCert; + OSSL_CRMF_ENCRYPTEDVALUE *privateKey; + OSSL_CRMF_PKIPUBLICATIONINFO *publicationInfo; +} OSSL_CMP_CERTIFIEDKEYPAIR; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTIFIEDKEYPAIR) + +/*- + * PKIStatusInfo ::= SEQUENCE { + * status PKIStatus, + * statusString PKIFreeText OPTIONAL, + * failInfo PKIFailureInfo OPTIONAL + * } + */ +struct ossl_cmp_pkisi_st { + OSSL_CMP_PKISTATUS *status; + OSSL_CMP_PKIFREETEXT *statusString; + OSSL_CMP_PKIFAILUREINFO *failInfo; +} /* OSSL_CMP_PKISI */; + +/*- + * RevReqContent ::= SEQUENCE OF RevDetails + * + * RevDetails ::= SEQUENCE { + * certDetails CertTemplate, + * crlEntryDetails Extensions OPTIONAL + * } + */ +struct ossl_cmp_revdetails_st { + OSSL_CRMF_CERTTEMPLATE *certDetails; + X509_EXTENSIONS *crlEntryDetails; +} /* OSSL_CMP_REVDETAILS */; +typedef struct ossl_cmp_revdetails_st OSSL_CMP_REVDETAILS; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_REVDETAILS) +DEFINE_STACK_OF(OSSL_CMP_REVDETAILS) + +/*- + * RevRepContent ::= SEQUENCE { + * status SEQUENCE SIZE (1..MAX) OF PKIStatusInfo, + * -- in same order as was sent in RevReqContent + * revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId + * OPTIONAL, + * -- IDs for which revocation was requested + * -- (same order as status) + * crls [1] SEQUENCE SIZE (1..MAX) OF CertificateList + * OPTIONAL + * -- the resulting CRLs (there may be more than one) + * } + */ +struct ossl_cmp_revrepcontent_st { + STACK_OF(OSSL_CMP_PKISI) *status; + STACK_OF(OSSL_CRMF_CERTID) *revCerts; + STACK_OF(X509_CRL) *crls; +} /* OSSL_CMP_REVREPCONTENT */; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_REVREPCONTENT) + +/*- + * KeyRecRepContent ::= SEQUENCE { + * status PKIStatusInfo, + * newSigCert [0] Certificate OPTIONAL, + * caCerts [1] SEQUENCE SIZE (1..MAX) OF + * Certificate OPTIONAL, + * keyPairHist [2] SEQUENCE SIZE (1..MAX) OF + * CertifiedKeyPair OPTIONAL + * } + */ +typedef struct ossl_cmp_keyrecrepcontent_st { + OSSL_CMP_PKISI *status; + X509 *newSigCert; + STACK_OF(X509) *caCerts; + STACK_OF(OSSL_CMP_CERTIFIEDKEYPAIR) *keyPairHist; +} OSSL_CMP_KEYRECREPCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_KEYRECREPCONTENT) + +/*- + * ErrorMsgContent ::= SEQUENCE { + * pKIStatusInfo PKIStatusInfo, + * errorCode INTEGER OPTIONAL, + * -- implementation-specific error codes + * errorDetails PKIFreeText OPTIONAL + * -- implementation-specific error details + * } + */ +typedef struct ossl_cmp_errormsgcontent_st { + OSSL_CMP_PKISI *pKIStatusInfo; + ASN1_INTEGER *errorCode; + OSSL_CMP_PKIFREETEXT *errorDetails; +} OSSL_CMP_ERRORMSGCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ERRORMSGCONTENT) + +/*- + * CertConfirmContent ::= SEQUENCE OF CertStatus + * + * CertStatus ::= SEQUENCE { + * certHash OCTET STRING, + * -- the hash of the certificate, using the same hash algorithm + * -- as is used to create and verify the certificate signature + * certReqId INTEGER, + * -- to match this confirmation with the corresponding req/rep + * statusInfo PKIStatusInfo OPTIONAL + * } + */ +struct ossl_cmp_certstatus_st { + ASN1_OCTET_STRING *certHash; + ASN1_INTEGER *certReqId; + OSSL_CMP_PKISI *statusInfo; +} /* OSSL_CMP_CERTSTATUS */; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTSTATUS) +typedef STACK_OF(OSSL_CMP_CERTSTATUS) OSSL_CMP_CERTCONFIRMCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTCONFIRMCONTENT) + +/*- + * CertResponse ::= SEQUENCE { + * certReqId INTEGER, + * -- to match this response with corresponding request (a value + * -- of -1 is to be used if certReqId is not specified in the + * -- corresponding request) + * status PKIStatusInfo, + * certifiedKeyPair CertifiedKeyPair OPTIONAL, + * rspInfo OCTET STRING OPTIONAL + * -- analogous to the id-regInfo-utf8Pairs string defined + * -- for regInfo in CertReqMsg [CRMF] + * } + */ +struct ossl_cmp_certresponse_st { + ASN1_INTEGER *certReqId; + OSSL_CMP_PKISI *status; + OSSL_CMP_CERTIFIEDKEYPAIR *certifiedKeyPair; + ASN1_OCTET_STRING *rspInfo; +} /* OSSL_CMP_CERTRESPONSE */; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTRESPONSE) + +/*- + * CertRepMessage ::= SEQUENCE { + * caPubs [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate + * OPTIONAL, + * response SEQUENCE OF CertResponse + * } + */ +struct ossl_cmp_certrepmessage_st { + STACK_OF(X509) *caPubs; + STACK_OF(OSSL_CMP_CERTRESPONSE) *response; +} /* OSSL_CMP_CERTREPMESSAGE */; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTREPMESSAGE) + +/*- + * PollReqContent ::= SEQUENCE OF SEQUENCE { + * certReqId INTEGER + * } + */ +typedef struct ossl_cmp_pollreq_st { + ASN1_INTEGER *certReqId; +} OSSL_CMP_POLLREQ; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_POLLREQ) +DEFINE_STACK_OF(OSSL_CMP_POLLREQ) +typedef STACK_OF(OSSL_CMP_POLLREQ) OSSL_CMP_POLLREQCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_POLLREQCONTENT) + +/*- + * PollRepContent ::= SEQUENCE OF SEQUENCE { + * certReqId INTEGER, + * checkAfter INTEGER, -- time in seconds + * reason PKIFreeText OPTIONAL + * } + */ +struct ossl_cmp_pollrep_st { + ASN1_INTEGER *certReqId; + ASN1_INTEGER *checkAfter; + OSSL_CMP_PKIFREETEXT *reason; +} /* OSSL_CMP_POLLREP */; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_POLLREP) +DEFINE_STACK_OF(OSSL_CMP_POLLREP) +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_POLLREPCONTENT) + +/*- + * PKIHeader ::= SEQUENCE { + * pvno INTEGER { cmp1999(1), cmp2000(2) }, + * sender GeneralName, + * -- identifies the sender + * recipient GeneralName, + * -- identifies the intended recipient + * messageTime [0] GeneralizedTime OPTIONAL, + * -- time of production of this message (used when sender + * -- believes that the transport will be "suitable"; i.e., + * -- that the time will still be meaningful upon receipt) + * protectionAlg [1] AlgorithmIdentifier OPTIONAL, + * -- algorithm used for calculation of protection bits + * senderKID [2] KeyIdentifier OPTIONAL, + * recipKID [3] KeyIdentifier OPTIONAL, + * -- to identify specific keys used for protection + * transactionID [4] OCTET STRING OPTIONAL, + * -- identifies the transaction; i.e., this will be the same in + * -- corresponding request, response, certConf, and PKIConf + * -- messages + * senderNonce [5] OCTET STRING OPTIONAL, + * recipNonce [6] OCTET STRING OPTIONAL, + * -- nonces used to provide replay protection, senderNonce + * -- is inserted by the creator of this message; recipNonce + * -- is a nonce previously inserted in a related message by + * -- the intended recipient of this message + * freeText [7] PKIFreeText OPTIONAL, + * -- this may be used to indicate context-specific instructions + * -- (this field is intended for human consumption) + * generalInfo [8] SEQUENCE SIZE (1..MAX) OF + * InfoTypeAndValue OPTIONAL + * -- this may be used to convey context-specific information + * -- (this field not primarily intended for human consumption) + * } + */ +struct ossl_cmp_pkiheader_st { + ASN1_INTEGER *pvno; + GENERAL_NAME *sender; + GENERAL_NAME *recipient; + ASN1_GENERALIZEDTIME *messageTime; /* 0 */ + X509_ALGOR *protectionAlg; /* 1 */ + ASN1_OCTET_STRING *senderKID; /* 2 */ + ASN1_OCTET_STRING *recipKID; /* 3 */ + ASN1_OCTET_STRING *transactionID; /* 4 */ + ASN1_OCTET_STRING *senderNonce; /* 5 */ + ASN1_OCTET_STRING *recipNonce; /* 6 */ + OSSL_CMP_PKIFREETEXT *freeText; /* 7 */ + STACK_OF(OSSL_CMP_ITAV) *generalInfo; /* 8 */ +} /* OSSL_CMP_PKIHEADER */; + +typedef STACK_OF(OSSL_CMP_CHALLENGE) OSSL_CMP_POPODECKEYCHALLCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_POPODECKEYCHALLCONTENT) +typedef STACK_OF(ASN1_INTEGER) OSSL_CMP_POPODECKEYRESPCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_POPODECKEYRESPCONTENT) +typedef STACK_OF(OSSL_CMP_REVDETAILS) OSSL_CMP_REVREQCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_REVREQCONTENT) +typedef STACK_OF(X509_CRL) OSSL_CMP_CRLANNCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CRLANNCONTENT) +typedef STACK_OF(OSSL_CMP_ITAV) OSSL_CMP_GENMSGCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_GENMSGCONTENT) +typedef STACK_OF(OSSL_CMP_ITAV) OSSL_CMP_GENREPCONTENT; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_GENREPCONTENT) + +/*- + * PKIBody ::= CHOICE { -- message-specific body elements + * ir [0] CertReqMessages, --Initialization Request + * ip [1] CertRepMessage, --Initialization Response + * cr [2] CertReqMessages, --Certification Request + * cp [3] CertRepMessage, --Certification Response + * p10cr [4] CertificationRequest, --imported from [PKCS10] + * popdecc [5] POPODecKeyChallContent, --pop Challenge + * popdecr [6] POPODecKeyRespContent, --pop Response + * kur [7] CertReqMessages, --Key Update Request + * kup [8] CertRepMessage, --Key Update Response + * krr [9] CertReqMessages, --Key Recovery Request + * krp [10] KeyRecRepContent, --Key Recovery Response + * rr [11] RevReqContent, --Revocation Request + * rp [12] RevRepContent, --Revocation Response + * ccr [13] CertReqMessages, --Cross-Cert. Request + * ccp [14] CertRepMessage, --Cross-Cert. Response + * ckuann [15] CAKeyUpdAnnContent, --CA Key Update Ann. + * cann [16] CertAnnContent, --Certificate Ann. + * rann [17] RevAnnContent, --Revocation Ann. + * crlann [18] CRLAnnContent, --CRL Announcement + * pkiconf [19] PKIConfirmContent, --Confirmation + * nested [20] NestedMessageContent, --Nested Message + * genm [21] GenMsgContent, --General Message + * genp [22] GenRepContent, --General Response + * error [23] ErrorMsgContent, --Error Message + * certConf [24] CertConfirmContent, --Certificate confirm + * pollReq [25] PollReqContent, --Polling request + * pollRep [26] PollRepContent --Polling response + * } + */ +typedef struct ossl_cmp_pkibody_st { + int type; + union { + OSSL_CRMF_MSGS *ir; /* 0 */ + OSSL_CMP_CERTREPMESSAGE *ip; /* 1 */ + OSSL_CRMF_MSGS *cr; /* 2 */ + OSSL_CMP_CERTREPMESSAGE *cp; /* 3 */ + /*- + * p10cr [4] CertificationRequest, --imported from [PKCS10] + * + * PKCS10_CERTIFICATIONREQUEST is effectively X509_REQ + * so it is used directly + */ + X509_REQ *p10cr; /* 4 */ + /*- + * popdecc [5] POPODecKeyChallContent, --pop Challenge + * + * POPODecKeyChallContent ::= SEQUENCE OF Challenge + */ + OSSL_CMP_POPODECKEYCHALLCONTENT *popdecc; /* 5 */ + /*- + * popdecr [6] POPODecKeyRespContent, --pop Response + * + * POPODecKeyRespContent ::= SEQUENCE OF INTEGER + */ + OSSL_CMP_POPODECKEYRESPCONTENT *popdecr; /* 6 */ + OSSL_CRMF_MSGS *kur; /* 7 */ + OSSL_CMP_CERTREPMESSAGE *kup; /* 8 */ + OSSL_CRMF_MSGS *krr; /* 9 */ + + /*- + * krp [10] KeyRecRepContent, --Key Recovery Response + */ + OSSL_CMP_KEYRECREPCONTENT *krp; /* 10 */ + /*- + * rr [11] RevReqContent, --Revocation Request + */ + OSSL_CMP_REVREQCONTENT *rr; /* 11 */ + /*- + * rp [12] RevRepContent, --Revocation Response + */ + OSSL_CMP_REVREPCONTENT *rp; /* 12 */ + /*- + * ccr [13] CertReqMessages, --Cross-Cert. Request + */ + OSSL_CRMF_MSGS *ccr; /* 13 */ + /*- + * ccp [14] CertRepMessage, --Cross-Cert. Response + */ + OSSL_CMP_CERTREPMESSAGE *ccp; /* 14 */ + /*- + * ckuann [15] CAKeyUpdAnnContent, --CA Key Update Ann. + */ + OSSL_CMP_CAKEYUPDANNCONTENT *ckuann; /* 15 */ + /*- + * cann [16] CertAnnContent, --Certificate Ann. + * OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly + */ + X509 *cann; /* 16 */ + /*- + * rann [17] RevAnnContent, --Revocation Ann. + */ + OSSL_CMP_REVANNCONTENT *rann; /* 17 */ + /*- + * crlann [18] CRLAnnContent, --CRL Announcement + * CRLAnnContent ::= SEQUENCE OF CertificateList + */ + OSSL_CMP_CRLANNCONTENT *crlann; /* 18 */ + /*- + * PKIConfirmContent ::= NULL + * pkiconf [19] PKIConfirmContent, --Confirmation + * OSSL_CMP_PKICONFIRMCONTENT would be only a typedef of ASN1_NULL + * OSSL_CMP_CONFIRMCONTENT *pkiconf; + * + * NOTE: this should ASN1_NULL according to the RFC + * but there might be a struct in it when sent from faulty servers... + */ + ASN1_TYPE *pkiconf; /* 19 */ + /*- + * nested [20] NestedMessageContent, --Nested Message + * NestedMessageContent ::= PKIMessages + */ + OSSL_CMP_MSGS *nested; /* 20 */ + /*- + * genm [21] GenMsgContent, --General Message + * GenMsgContent ::= SEQUENCE OF InfoTypeAndValue + */ + OSSL_CMP_GENMSGCONTENT *genm; /* 21 */ + /*- + * genp [22] GenRepContent, --General Response + * GenRepContent ::= SEQUENCE OF InfoTypeAndValue + */ + OSSL_CMP_GENREPCONTENT *genp; /* 22 */ + /*- + * error [23] ErrorMsgContent, --Error Message + */ + OSSL_CMP_ERRORMSGCONTENT *error; /* 23 */ + /*- + * certConf [24] CertConfirmContent, --Certificate confirm + */ + OSSL_CMP_CERTCONFIRMCONTENT *certConf; /* 24 */ + /*- + * pollReq [25] PollReqContent, --Polling request + */ + OSSL_CMP_POLLREQCONTENT *pollReq; /* 25 */ + /*- + * pollRep [26] PollRepContent --Polling response + */ + OSSL_CMP_POLLREPCONTENT *pollRep; /* 26 */ + } value; +} OSSL_CMP_PKIBODY; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKIBODY) + +/*- + * PKIProtection ::= BIT STRING + * + * PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage + * + * PKIMessage ::= SEQUENCE { + * header PKIHeader, + * body PKIBody, + * protection [0] PKIProtection OPTIONAL, + * extraCerts [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate + * OPTIONAL + * } + */ +struct ossl_cmp_msg_st { + OSSL_CMP_PKIHEADER *header; + OSSL_CMP_PKIBODY *body; + ASN1_BIT_STRING *protection; /* 0 */ + /* OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly */ + STACK_OF(X509) *extraCerts; /* 1 */ + OSSL_LIB_CTX *libctx; + char *propq; +} /* OSSL_CMP_MSG */; +OSSL_CMP_MSG *OSSL_CMP_MSG_new(OSSL_LIB_CTX *libctx, const char *propq); +void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg); + +/*- + * ProtectedPart ::= SEQUENCE { + * header PKIHeader, + * body PKIBody + * } + */ +typedef struct ossl_cmp_protectedpart_st { + OSSL_CMP_PKIHEADER *header; + OSSL_CMP_PKIBODY *body; +} OSSL_CMP_PROTECTEDPART; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PROTECTEDPART) + +/*- + * this is not defined here as it is already in CRMF: + * id-PasswordBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 13} + * PBMParameter ::= SEQUENCE { + * salt OCTET STRING, + * -- note: implementations MAY wish to limit acceptable sizes + * -- of this string to values appropriate for their environment + * -- in order to reduce the risk of denial-of-service attacks + * owf AlgorithmIdentifier, + * -- AlgId for a One-Way Function (SHA-1 recommended) + * iterationCount INTEGER, + * -- number of times the OWF is applied + * -- note: implementations MAY wish to limit acceptable sizes + * -- of this integer to values appropriate for their environment + * -- in order to reduce the risk of denial-of-service attacks + * mac AlgorithmIdentifier + * -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11], + * } -- or HMAC [RFC2104, RFC2202]) + */ +/*- + * id-DHBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 30} + * DHBMParameter ::= SEQUENCE { + * owf AlgorithmIdentifier, + * -- AlgId for a One-Way Function (SHA-1 recommended) + * mac AlgorithmIdentifier + * -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11], + * } -- or HMAC [RFC2104, RFC2202]) + */ +/*- + * The following is not cared for, because it is described in section 5.2.5 + * that this is beyond the scope of CMP + * OOBCert ::= CMPCertificate + * + * OOBCertHash ::= SEQUENCE { + * hashAlg [0] AlgorithmIdentifier OPTIONAL, + * certId [1] CertId OPTIONAL, + * hashVal BIT STRING + * -- hashVal is calculated over the DER encoding of the + * -- self-signed certificate with the identifier certID. + * } + */ + +/* from cmp_asn.c */ +int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a); + +/* from cmp_util.c */ +const char *ossl_cmp_log_parse_metadata(const char *buf, + OSSL_CMP_severity *level, char **func, + char **file, int *line); +# define ossl_cmp_add_error_data(txt) ERR_add_error_txt(" : ", txt) +# define ossl_cmp_add_error_line(txt) ERR_add_error_txt("\n", txt) +/* The two functions manipulating X509_STORE could be generally useful */ +int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs, + int only_self_issued); +STACK_OF(X509) *ossl_cmp_X509_STORE_get1_certs(X509_STORE *store); +int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk, + const char *text, int len); +int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt, + const ASN1_OCTET_STRING *src); +int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt, + const unsigned char *bytes, int len); + +/* from cmp_ctx.c */ +int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, + const char *func, const char *file, int line, + const char *level_str, const char *format, ...); +# define ossl_cmp_log(level, ctx, msg) \ + ossl_cmp_print_log(OSSL_CMP_LOG_##level, ctx, OPENSSL_FUNC, OPENSSL_FILE, \ + OPENSSL_LINE, #level, "%s", msg) +# define ossl_cmp_log1(level, ctx, fmt, arg1) \ + ossl_cmp_print_log(OSSL_CMP_LOG_##level, ctx, OPENSSL_FUNC, OPENSSL_FILE, \ + OPENSSL_LINE, #level, fmt, arg1) +# define ossl_cmp_log2(level, ctx, fmt, arg1, arg2) \ + ossl_cmp_print_log(OSSL_CMP_LOG_##level, ctx, OPENSSL_FUNC, OPENSSL_FILE, \ + OPENSSL_LINE, #level, fmt, arg1, arg2) +# define ossl_cmp_log3(level, ctx, fmt, arg1, arg2, arg3) \ + ossl_cmp_print_log(OSSL_CMP_LOG_##level, ctx, OPENSSL_FUNC, OPENSSL_FILE, \ + OPENSSL_LINE, #level, fmt, arg1, arg2, arg3) +# define ossl_cmp_log4(level, ctx, fmt, arg1, arg2, arg3, arg4) \ + ossl_cmp_print_log(OSSL_CMP_LOG_##level, ctx, OPENSSL_FUNC, OPENSSL_FILE, \ + OPENSSL_LINE, #level, fmt, arg1, arg2, arg3, arg4) +# define OSSL_CMP_LOG_ERROR OSSL_CMP_LOG_ERR +# define OSSL_CMP_LOG_WARN OSSL_CMP_LOG_WARNING +# define ossl_cmp_alert(ctx, msg) ossl_cmp_log(ALERT, ctx, msg) +# define ossl_cmp_err(ctx, msg) ossl_cmp_log(ERROR, ctx, msg) +# define ossl_cmp_warn(ctx, msg) ossl_cmp_log(WARN, ctx, msg) +# define ossl_cmp_info(ctx, msg) ossl_cmp_log(INFO, ctx, msg) +# define ossl_cmp_debug(ctx, msg) ossl_cmp_log(DEBUG, ctx, msg) +# define ossl_cmp_trace(ctx, msg) ossl_cmp_log(TRACE, ctx, msg) +int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert); +int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status); +int ossl_cmp_ctx_set0_statusString(OSSL_CMP_CTX *ctx, + OSSL_CMP_PKIFREETEXT *text); +int ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info); +int ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert); +int ossl_cmp_ctx_set1_newChain(OSSL_CMP_CTX *ctx, STACK_OF(X509) *newChain); +int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs); +int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx, + STACK_OF(X509) *extraCertsIn); +int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx, + const ASN1_OCTET_STRING *nonce); + +/* from cmp_status.c */ +int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si); +const char *ossl_cmp_PKIStatus_to_string(int status); +OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *s); +int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si); +int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index); + +/* from cmp_hdr.c */ +int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno); +int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr); +int ossl_cmp_hdr_get_protection_nid(const OSSL_CMP_PKIHEADER *hdr); +ASN1_OCTET_STRING *ossl_cmp_hdr_get0_senderNonce(const OSSL_CMP_PKIHEADER *hdr); +int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name); +int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm); +int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm); +int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr); +int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr, + const ASN1_OCTET_STRING *senderKID); +int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text); +int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text); +int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr, + OSSL_CMP_ITAV *itav); +int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr, + const STACK_OF(OSSL_CMP_ITAV) *itavs); +int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr); +int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr); +# define OSSL_CMP_TRANSACTIONID_LENGTH 16 +# define OSSL_CMP_SENDERNONCE_LENGTH 16 +int ossl_cmp_hdr_set_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr); +int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr); + +/* from cmp_msg.c */ +/* OSSL_CMP_MSG bodytype ASN.1 choice IDs */ +# define OSSL_CMP_PKIBODY_IR 0 +# define OSSL_CMP_PKIBODY_IP 1 +# define OSSL_CMP_PKIBODY_CR 2 +# define OSSL_CMP_PKIBODY_CP 3 +# define OSSL_CMP_PKIBODY_P10CR 4 +# define OSSL_CMP_PKIBODY_POPDECC 5 +# define OSSL_CMP_PKIBODY_POPDECR 6 +# define OSSL_CMP_PKIBODY_KUR 7 +# define OSSL_CMP_PKIBODY_KUP 8 +# define OSSL_CMP_PKIBODY_KRR 9 +# define OSSL_CMP_PKIBODY_KRP 10 +# define OSSL_CMP_PKIBODY_RR 11 +# define OSSL_CMP_PKIBODY_RP 12 +# define OSSL_CMP_PKIBODY_CCR 13 +# define OSSL_CMP_PKIBODY_CCP 14 +# define OSSL_CMP_PKIBODY_CKUANN 15 +# define OSSL_CMP_PKIBODY_CANN 16 +# define OSSL_CMP_PKIBODY_RANN 17 +# define OSSL_CMP_PKIBODY_CRLANN 18 +# define OSSL_CMP_PKIBODY_PKICONF 19 +# define OSSL_CMP_PKIBODY_NESTED 20 +# define OSSL_CMP_PKIBODY_GENM 21 +# define OSSL_CMP_PKIBODY_GENP 22 +# define OSSL_CMP_PKIBODY_ERROR 23 +# define OSSL_CMP_PKIBODY_CERTCONF 24 +# define OSSL_CMP_PKIBODY_POLLREQ 25 +# define OSSL_CMP_PKIBODY_POLLREP 26 +# define OSSL_CMP_PKIBODY_TYPE_MAX OSSL_CMP_PKIBODY_POLLREP +/* certReqId for the first - and so far only - certificate request */ +# define OSSL_CMP_CERTREQID 0 +/* sequence id for the first - and so far only - revocation request */ +# define OSSL_CMP_REVREQSID 0 +int ossl_cmp_msg_set0_libctx(OSSL_CMP_MSG *msg, OSSL_LIB_CTX *libctx, + const char *propq); +const char *ossl_cmp_bodytype_to_string(int type); +int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type); +OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype); +OSSL_CMP_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int bodytype, + const OSSL_CRMF_MSG *crm); +OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype, + int certReqId, const OSSL_CMP_PKISI *si, + X509 *cert, const X509 *encryption_recip, + STACK_OF(X509) *chain, STACK_OF(X509) *caPubs, + int unprotectedErrors); +OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx); +OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si, + const OSSL_CRMF_CERTID *cid, + int unprotectedErrors); +OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx); +OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid, + int64_t poll_after); +int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav); +int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg, + const STACK_OF(OSSL_CMP_ITAV) *itavs); +OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx); +OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx, + const STACK_OF(OSSL_CMP_ITAV) *itavs); +OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si, + int64_t errorCode, const char *details, + int unprotected); +int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus, + ASN1_OCTET_STRING *hash); +OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info, + const char *text); +OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid); +OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid, + int64_t poll_after); +OSSL_CMP_PKISI * +ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid); +OSSL_CRMF_CERTID *ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rc, + int rsid); +OSSL_CMP_POLLREP * +ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc, + int rid); +OSSL_CMP_CERTRESPONSE * +ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm, + int rid); +X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep, + const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey); +OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file); + +/* from cmp_protect.c */ +int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); +ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg); +int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); + +/* from cmp_vfy.c */ +typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg, + int invalid_protection, int arg); +int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, + ossl_cmp_allow_unprotected_cb_t cb, int cb_arg); +int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, + ossl_cmp_allow_unprotected_cb_t cb, int cb_arg); +int ossl_cmp_verify_popo(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg, int accept_RAVerified); + +/* from cmp_client.c */ +int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int fail_info, + const char *txt); +int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info, + const char *txt, int errorCode, const char *detail); + +#endif /* !defined(OSSL_CRYPTO_CMP_LOCAL_H) */ diff --git a/crypto/openssl/crypto/cmp/cmp_msg.c b/crypto/openssl/crypto/cmp/cmp_msg.c new file mode 100644 index 000000000000..b244f1e17f0d --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_msg.c @@ -0,0 +1,1170 @@ +/* + * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* CMP functions for PKIMessage construction */ + +#include "cmp_local.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include +#include +#include + +OSSL_CMP_MSG *OSSL_CMP_MSG_new(OSSL_LIB_CTX *libctx, const char *propq) +{ + OSSL_CMP_MSG *msg = NULL; + + msg = (OSSL_CMP_MSG *)ASN1_item_new_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG), + libctx, propq); + if (!ossl_cmp_msg_set0_libctx(msg, libctx, propq)) { + OSSL_CMP_MSG_free(msg); + msg = NULL; + } + return msg; +} + +void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg) +{ + ASN1_item_free((ASN1_VALUE *)msg, ASN1_ITEM_rptr(OSSL_CMP_MSG)); +} + +/* + * This should only be used if the X509 object was embedded inside another + * asn1 object and it needs a libctx to operate. + * Use OSSL_CMP_MSG_new() instead if possible. + */ +int ossl_cmp_msg_set0_libctx(OSSL_CMP_MSG *msg, OSSL_LIB_CTX *libctx, + const char *propq) +{ + if (msg != NULL) { + msg->libctx = libctx; + OPENSSL_free(msg->propq); + msg->propq = NULL; + if (propq != NULL) { + msg->propq = OPENSSL_strdup(propq); + if (msg->propq == NULL) + return 0; + } + } + return 1; +} + + +OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg) +{ + if (msg == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return msg->header; +} + +const char *ossl_cmp_bodytype_to_string(int type) +{ + static const char *type_names[] = { + "IR", "IP", "CR", "CP", "P10CR", + "POPDECC", "POPDECR", "KUR", "KUP", + "KRR", "KRP", "RR", "RP", "CCR", "CCP", + "CKUANN", "CANN", "RANN", "CRLANN", "PKICONF", "NESTED", + "GENM", "GENP", "ERROR", "CERTCONF", "POLLREQ", "POLLREP", + }; + + if (type < 0 || type > OSSL_CMP_PKIBODY_TYPE_MAX) + return "illegal body type"; + return type_names[type]; +} + +int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type) +{ + if (!ossl_assert(msg != NULL && msg->body != NULL)) + return 0; + + msg->body->type = type; + return 1; +} + +int OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG *msg) +{ + if (!ossl_assert(msg != NULL && msg->body != NULL)) + return -1; + + return msg->body->type; +} + +/* Add an extension to the referenced extension stack, which may be NULL */ +static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex) +{ + X509_EXTENSION *ext; + int res; + + if (!ossl_assert(pexts != NULL)) /* pointer to var must not be NULL */ + return 0; + + if ((ext = X509V3_EXT_i2d(nid, crit, ex)) == NULL) + return 0; + + res = X509v3_add_ext(pexts, ext, 0) != NULL; + X509_EXTENSION_free(ext); + return res; +} + +/* Add extension list to the referenced extension stack, which may be NULL */ +static int add_extensions(STACK_OF(X509_EXTENSION) **target, + const STACK_OF(X509_EXTENSION) *exts) +{ + int i; + + if (target == NULL) + return 0; + + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); + ASN1_OBJECT *obj = X509_EXTENSION_get_object(ext); + int idx = X509v3_get_ext_by_OBJ(*target, obj, -1); + + /* Does extension exist in target? */ + if (idx != -1) { + /* Delete all extensions of same type */ + do { + X509_EXTENSION_free(sk_X509_EXTENSION_delete(*target, idx)); + idx = X509v3_get_ext_by_OBJ(*target, obj, -1); + } while (idx != -1); + } + if (!X509v3_add_ext(target, ext, -1)) + return 0; + } + return 1; +} + +/* Add a CRL revocation reason code to extension stack, which may be NULL */ +static int add_crl_reason_extension(X509_EXTENSIONS **pexts, int reason_code) +{ + ASN1_ENUMERATED *val = ASN1_ENUMERATED_new(); + int res = 0; + + if (val != NULL && ASN1_ENUMERATED_set(val, reason_code)) + res = add1_extension(pexts, NID_crl_reason, 0 /* non-critical */, val); + ASN1_ENUMERATED_free(val); + return res; +} + +OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype) +{ + OSSL_CMP_MSG *msg = NULL; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + if ((msg = OSSL_CMP_MSG_new(ctx->libctx, ctx->propq)) == NULL) + return NULL; + if (!ossl_cmp_hdr_init(ctx, msg->header) + || !ossl_cmp_msg_set_bodytype(msg, bodytype)) + goto err; + if (ctx->geninfo_ITAVs != NULL + && !ossl_cmp_hdr_generalInfo_push1_items(msg->header, + ctx->geninfo_ITAVs)) + goto err; + + switch (bodytype) { + case OSSL_CMP_PKIBODY_IR: + case OSSL_CMP_PKIBODY_CR: + case OSSL_CMP_PKIBODY_KUR: + if ((msg->body->value.ir = OSSL_CRMF_MSGS_new()) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_P10CR: + if (ctx->p10CSR == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_P10CSR); + goto err; + } + if ((msg->body->value.p10cr = X509_REQ_dup(ctx->p10CSR)) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_IP: + case OSSL_CMP_PKIBODY_CP: + case OSSL_CMP_PKIBODY_KUP: + if ((msg->body->value.ip = OSSL_CMP_CERTREPMESSAGE_new()) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_RR: + if ((msg->body->value.rr = sk_OSSL_CMP_REVDETAILS_new_null()) == NULL) + goto err; + return msg; + case OSSL_CMP_PKIBODY_RP: + if ((msg->body->value.rp = OSSL_CMP_REVREPCONTENT_new()) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_CERTCONF: + if ((msg->body->value.certConf = + sk_OSSL_CMP_CERTSTATUS_new_null()) == NULL) + goto err; + return msg; + case OSSL_CMP_PKIBODY_PKICONF: + if ((msg->body->value.pkiconf = ASN1_TYPE_new()) == NULL) + goto err; + ASN1_TYPE_set(msg->body->value.pkiconf, V_ASN1_NULL, NULL); + return msg; + + case OSSL_CMP_PKIBODY_POLLREQ: + if ((msg->body->value.pollReq = sk_OSSL_CMP_POLLREQ_new_null()) == NULL) + goto err; + return msg; + case OSSL_CMP_PKIBODY_POLLREP: + if ((msg->body->value.pollRep = sk_OSSL_CMP_POLLREP_new_null()) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_GENM: + case OSSL_CMP_PKIBODY_GENP: + if ((msg->body->value.genm = sk_OSSL_CMP_ITAV_new_null()) == NULL) + goto err; + return msg; + + case OSSL_CMP_PKIBODY_ERROR: + if ((msg->body->value.error = OSSL_CMP_ERRORMSGCONTENT_new()) == NULL) + goto err; + return msg; + + default: + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + goto err; + } + + err: + OSSL_CMP_MSG_free(msg); + return NULL; +} + +#define HAS_SAN(ctx) \ + (sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \ + || OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1) + +static const X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, int for_KUR, + const X509_NAME *ref_subj) +{ + if (ctx->subjectName != NULL) + return IS_NULL_DN(ctx->subjectName) ? NULL : ctx->subjectName; + if (ctx->p10CSR != NULL) /* first default is from any given CSR */ + return X509_REQ_get_subject_name(ctx->p10CSR); + if (for_KUR || !HAS_SAN(ctx)) + /* + * For KUR, copy subject from any reference cert as fallback. + * For IR or CR, do the same only if there is no subjectAltName. + */ + return ref_subj; + return NULL; +} + +OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid) +{ + OSSL_CRMF_MSG *crm = NULL; + X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->cert; + /* refcert defaults to current client cert */ + EVP_PKEY *rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0); + STACK_OF(GENERAL_NAME) *default_sans = NULL; + const X509_NAME *ref_subj = + refcert != NULL ? X509_get_subject_name(refcert) : NULL; + const X509_NAME *subject = determine_subj(ctx, for_KUR, ref_subj); + const X509_NAME *issuer = ctx->issuer != NULL || refcert == NULL + ? (IS_NULL_DN(ctx->issuer) ? NULL : ctx->issuer) + : X509_get_issuer_name(refcert); + int crit = ctx->setSubjectAltNameCritical || subject == NULL; + /* RFC5280: subjectAltName MUST be critical if subject is null */ + X509_EXTENSIONS *exts = NULL; + + if (rkey == NULL && ctx->p10CSR != NULL) + rkey = X509_REQ_get0_pubkey(ctx->p10CSR); + if (rkey == NULL && refcert != NULL) + rkey = X509_get0_pubkey(refcert); + if (rkey == NULL) + rkey = ctx->pkey; /* default is independent of ctx->oldCert */ + if (rkey == NULL) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; +#endif + } + if (for_KUR && refcert == NULL && ctx->p10CSR == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_REFERENCE_CERT); + return NULL; + } + if ((crm = OSSL_CRMF_MSG_new()) == NULL) + return NULL; + if (!OSSL_CRMF_MSG_set_certReqId(crm, rid) + /* + * fill certTemplate, corresponding to CertificationRequestInfo + * of PKCS#10. The rkey param cannot be NULL so far - + * it could be NULL if centralized key creation was supported + */ + || !OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_MSG_get0_tmpl(crm), rkey, + subject, issuer, NULL /* serial */)) + goto err; + if (ctx->days != 0) { + time_t now = time(NULL); + ASN1_TIME *notBefore = ASN1_TIME_adj(NULL, now, 0, 0); + ASN1_TIME *notAfter = ASN1_TIME_adj(NULL, now, ctx->days, 0); + + if (notBefore == NULL + || notAfter == NULL + || !OSSL_CRMF_MSG_set0_validity(crm, notBefore, notAfter)) { + ASN1_TIME_free(notBefore); + ASN1_TIME_free(notAfter); + goto err; + } + } + + /* extensions */ + if (ctx->p10CSR != NULL + && (exts = X509_REQ_get_extensions(ctx->p10CSR)) == NULL) + goto err; + if (!ctx->SubjectAltName_nodefault && !HAS_SAN(ctx) && refcert != NULL + && (default_sans = X509V3_get_d2i(X509_get0_extensions(refcert), + NID_subject_alt_name, NULL, NULL)) + != NULL + && !add1_extension(&exts, NID_subject_alt_name, crit, default_sans)) + goto err; + if (ctx->reqExtensions != NULL /* augment/override existing ones */ + && !add_extensions(&exts, ctx->reqExtensions)) + goto err; + if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0 + && !add1_extension(&exts, NID_subject_alt_name, + crit, ctx->subjectAltNames)) + goto err; + if (ctx->policies != NULL + && !add1_extension(&exts, NID_certificate_policies, + ctx->setPoliciesCritical, ctx->policies)) + goto err; + if (!OSSL_CRMF_MSG_set0_extensions(crm, exts)) + goto err; + exts = NULL; + /* end fill certTemplate, now set any controls */ + + /* for KUR, set OldCertId according to D.6 */ + if (for_KUR && refcert != NULL) { + OSSL_CRMF_CERTID *cid = + OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert), + X509_get0_serialNumber(refcert)); + int ret; + + if (cid == NULL) + goto err; + ret = OSSL_CRMF_MSG_set1_regCtrl_oldCertID(crm, cid); + OSSL_CRMF_CERTID_free(cid); + if (ret == 0) + goto err; + } + + goto end; + + err: + OSSL_CRMF_MSG_free(crm); + crm = NULL; + + end: + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + sk_GENERAL_NAME_pop_free(default_sans, GENERAL_NAME_free); + return crm; +} + +OSSL_CMP_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int type, + const OSSL_CRMF_MSG *crm) +{ + OSSL_CMP_MSG *msg; + OSSL_CRMF_MSG *local_crm = NULL; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + if (type != OSSL_CMP_PKIBODY_IR && type != OSSL_CMP_PKIBODY_CR + && type != OSSL_CMP_PKIBODY_KUR && type != OSSL_CMP_PKIBODY_P10CR) { + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); + return NULL; + } + if (type == OSSL_CMP_PKIBODY_P10CR && crm != NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); + return NULL; + } + + if ((msg = ossl_cmp_msg_create(ctx, type)) == NULL) + goto err; + + /* header */ + if (ctx->implicitConfirm && !ossl_cmp_hdr_set_implicitConfirm(msg->header)) + goto err; + + /* body */ + /* For P10CR the content has already been set in OSSL_CMP_MSG_create */ + if (type != OSSL_CMP_PKIBODY_P10CR) { + EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); + + /* + * privkey is NULL in case ctx->newPkey does not include a private key. + * We then may try to use ctx->pkey as fallback/default, but only + * if ctx-> newPkey does not include a (non-matching) public key: + */ + if (privkey == NULL && OSSL_CMP_CTX_get0_newPkey(ctx, 0) == NULL) + privkey = ctx->pkey; /* default is independent of ctx->oldCert */ + if (ctx->popoMethod == OSSL_CRMF_POPO_SIGNATURE && privkey == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY); + goto err; + } + if (crm == NULL) { + local_crm = OSSL_CMP_CTX_setup_CRM(ctx, + type == OSSL_CMP_PKIBODY_KUR, + OSSL_CMP_CERTREQID); + if (local_crm == NULL + || !OSSL_CRMF_MSG_create_popo(ctx->popoMethod, local_crm, + privkey, ctx->digest, + ctx->libctx, ctx->propq)) + goto err; + } else { + if ((local_crm = OSSL_CRMF_MSG_dup(crm)) == NULL) + goto err; + } + + /* value.ir is same for cr and kur */ + if (!sk_OSSL_CRMF_MSG_push(msg->body->value.ir, local_crm)) + goto err; + local_crm = NULL; + } + + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREQ); + OSSL_CRMF_MSG_free(local_crm); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype, + int certReqId, const OSSL_CMP_PKISI *si, + X509 *cert, const X509 *encryption_recip, + STACK_OF(X509) *chain, STACK_OF(X509) *caPubs, + int unprotectedErrors) +{ + OSSL_CMP_MSG *msg = NULL; + OSSL_CMP_CERTREPMESSAGE *repMsg = NULL; + OSSL_CMP_CERTRESPONSE *resp = NULL; + int status = OSSL_CMP_PKISTATUS_unspecified; + + if (!ossl_assert(ctx != NULL && si != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, bodytype)) == NULL) + goto err; + repMsg = msg->body->value.ip; /* value.ip is same for cp and kup */ + + /* header */ + if (ctx->implicitConfirm && !ossl_cmp_hdr_set_implicitConfirm(msg->header)) + goto err; + + /* body */ + if ((resp = OSSL_CMP_CERTRESPONSE_new()) == NULL) + goto err; + OSSL_CMP_PKISI_free(resp->status); + if ((resp->status = OSSL_CMP_PKISI_dup(si)) == NULL + || !ASN1_INTEGER_set(resp->certReqId, certReqId)) + goto err; + + status = ossl_cmp_pkisi_get_status(resp->status); + if (status != OSSL_CMP_PKISTATUS_rejection + && status != OSSL_CMP_PKISTATUS_waiting && cert != NULL) { + if (encryption_recip != NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_UNSUPPORTED); + goto err; + } + + if ((resp->certifiedKeyPair = OSSL_CMP_CERTIFIEDKEYPAIR_new()) + == NULL) + goto err; + resp->certifiedKeyPair->certOrEncCert->type = + OSSL_CMP_CERTORENCCERT_CERTIFICATE; + if (!X509_up_ref(cert)) + goto err; + resp->certifiedKeyPair->certOrEncCert->value.certificate = cert; + } + + if (!sk_OSSL_CMP_CERTRESPONSE_push(repMsg->response, resp)) + goto err; + resp = NULL; + + if (bodytype == OSSL_CMP_PKIBODY_IP && caPubs != NULL + && (repMsg->caPubs = X509_chain_up_ref(caPubs)) == NULL) + goto err; + if (sk_X509_num(chain) > 0 + && !ossl_x509_add_certs_new(&msg->extraCerts, chain, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) + goto err; + + if (!unprotectedErrors + || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection) + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREP); + OSSL_CMP_CERTRESPONSE_free(resp); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx) +{ + OSSL_CMP_MSG *msg = NULL; + OSSL_CMP_REVDETAILS *rd; + int ret; + + if (!ossl_assert(ctx != NULL && (ctx->oldCert != NULL + || ctx->p10CSR != NULL))) + return NULL; + + if ((rd = OSSL_CMP_REVDETAILS_new()) == NULL) + goto err; + + /* Fill the template from the contents of the certificate to be revoked */ + ret = ctx->oldCert != NULL + ? OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, + NULL /* pubkey would be redundant */, + NULL /* subject would be redundant */, + X509_get_issuer_name(ctx->oldCert), + X509_get0_serialNumber(ctx->oldCert)) + : OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, + X509_REQ_get0_pubkey(ctx->p10CSR), + X509_REQ_get_subject_name(ctx->p10CSR), + NULL, NULL); + if (!ret) + goto err; + + /* revocation reason code is optional */ + if (ctx->revocationReason != CRL_REASON_NONE + && !add_crl_reason_extension(&rd->crlEntryDetails, + ctx->revocationReason)) + goto err; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RR)) == NULL) + goto err; + + if (!sk_OSSL_CMP_REVDETAILS_push(msg->body->value.rr, rd)) + goto err; + rd = NULL; + /* Revocation Passphrase according to section 5.3.19.9 could be set here */ + + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_RR); + OSSL_CMP_MSG_free(msg); + OSSL_CMP_REVDETAILS_free(rd); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si, + const OSSL_CRMF_CERTID *cid, int unprotectedErrors) +{ + OSSL_CMP_REVREPCONTENT *rep = NULL; + OSSL_CMP_PKISI *si1 = NULL; + OSSL_CRMF_CERTID *cid_copy = NULL; + OSSL_CMP_MSG *msg = NULL; + + if (!ossl_assert(ctx != NULL && si != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RP)) == NULL) + goto err; + rep = msg->body->value.rp; + + if ((si1 = OSSL_CMP_PKISI_dup(si)) == NULL) + goto err; + + if (!sk_OSSL_CMP_PKISI_push(rep->status, si1)) { + OSSL_CMP_PKISI_free(si1); + goto err; + } + + if ((rep->revCerts = sk_OSSL_CRMF_CERTID_new_null()) == NULL) + goto err; + if (cid != NULL) { + if ((cid_copy = OSSL_CRMF_CERTID_dup(cid)) == NULL) + goto err; + if (!sk_OSSL_CRMF_CERTID_push(rep->revCerts, cid_copy)) { + OSSL_CRMF_CERTID_free(cid_copy); + goto err; + } + } + + if (!unprotectedErrors + || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection) + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_RP); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx) +{ + OSSL_CMP_MSG *msg; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_PKICONF)) == NULL) + goto err; + if (ossl_cmp_msg_protect(ctx, msg)) + return msg; + + err: + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_PKICONF); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav) +{ + int bodytype; + + if (!ossl_assert(msg != NULL && itav != NULL)) + return 0; + + bodytype = OSSL_CMP_MSG_get_bodytype(msg); + if (bodytype != OSSL_CMP_PKIBODY_GENM + && bodytype != OSSL_CMP_PKIBODY_GENP) { + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); + return 0; + } + + /* value.genp has the same structure, so this works for genp as well */ + return OSSL_CMP_ITAV_push0_stack_item(&msg->body->value.genm, itav); +} + +int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg, + const STACK_OF(OSSL_CMP_ITAV) *itavs) +{ + int i; + OSSL_CMP_ITAV *itav = NULL; + + if (!ossl_assert(msg != NULL)) + return 0; + + for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) { + itav = OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs, i)); + if (itav == NULL + || !ossl_cmp_msg_gen_push0_ITAV(msg, itav)) { + OSSL_CMP_ITAV_free(itav); + return 0; + } + } + return 1; +} + +/* + * Creates a new General Message/Response with an empty itav stack + * returns a pointer to the PKIMessage on success, NULL on error + */ +static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, + const STACK_OF(OSSL_CMP_ITAV) *itavs, + int body_type, int err_code) +{ + OSSL_CMP_MSG *msg = NULL; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, body_type)) == NULL) + return NULL; + + if (itavs != NULL && !ossl_cmp_msg_gen_push1_ITAVs(msg, itavs)) + goto err; + + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + ERR_raise(ERR_LIB_CMP, err_code); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx) +{ + return gen_new(ctx, ctx->genm_ITAVs, + OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM); +} + +OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx, + const STACK_OF(OSSL_CMP_ITAV) *itavs) +{ + return gen_new(ctx, itavs, + OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP); +} + +OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si, + int64_t errorCode, const char *details, + int unprotected) +{ + OSSL_CMP_MSG *msg = NULL; + const char *lib = NULL, *reason = NULL; + OSSL_CMP_PKIFREETEXT *ft; + + if (!ossl_assert(ctx != NULL && si != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_ERROR)) == NULL) + goto err; + + OSSL_CMP_PKISI_free(msg->body->value.error->pKIStatusInfo); + if ((msg->body->value.error->pKIStatusInfo = OSSL_CMP_PKISI_dup(si)) + == NULL) + goto err; + if ((msg->body->value.error->errorCode = ASN1_INTEGER_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set_int64(msg->body->value.error->errorCode, errorCode)) + goto err; + if (errorCode > 0 + && (uint64_t)errorCode < ((uint64_t)ERR_SYSTEM_FLAG << 1)) { + lib = ERR_lib_error_string((unsigned long)errorCode); + reason = ERR_reason_error_string((unsigned long)errorCode); + } + if (lib != NULL || reason != NULL || details != NULL) { + if ((ft = sk_ASN1_UTF8STRING_new_null()) == NULL) + goto err; + msg->body->value.error->errorDetails = ft; + if (lib != NULL && *lib != '\0' + && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, lib, -1)) + goto err; + if (reason != NULL && *reason != '\0' + && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, reason, -1)) + goto err; + if (details != NULL + && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, details, -1)) + goto err; + } + + if (!unprotected && !ossl_cmp_msg_protect(ctx, msg)) + goto err; + return msg; + + err: + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_ERROR); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +/* + * Set the certHash field of a OSSL_CMP_CERTSTATUS structure. + * This is used in the certConf message, for example, + * to confirm that the certificate was received successfully. + */ +int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus, + ASN1_OCTET_STRING *hash) +{ + if (!ossl_assert(certStatus != NULL)) + return 0; + ASN1_OCTET_STRING_free(certStatus->certHash); + certStatus->certHash = hash; + return 1; +} + +OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info, + const char *text) +{ + OSSL_CMP_MSG *msg = NULL; + OSSL_CMP_CERTSTATUS *certStatus = NULL; + ASN1_OCTET_STRING *certHash = NULL; + OSSL_CMP_PKISI *sinfo; + + if (!ossl_assert(ctx != NULL && ctx->newCert != NULL)) + return NULL; + + if ((unsigned)fail_info > OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN) { + ERR_raise(ERR_LIB_CMP, CMP_R_FAIL_INFO_OUT_OF_RANGE); + return NULL; + } + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_CERTCONF)) == NULL) + goto err; + + if ((certStatus = OSSL_CMP_CERTSTATUS_new()) == NULL) + goto err; + /* consume certStatus into msg right away so it gets deallocated with msg */ + if (!sk_OSSL_CMP_CERTSTATUS_push(msg->body->value.certConf, certStatus)) + goto err; + /* set the ID of the certReq */ + if (!ASN1_INTEGER_set(certStatus->certReqId, OSSL_CMP_CERTREQID)) + goto err; + /* + * The hash of the certificate, using the same hash algorithm + * as is used to create and verify the certificate signature. + * If not available, a default hash algorithm is used. + */ + if ((certHash = X509_digest_sig(ctx->newCert, NULL, NULL)) == NULL) + goto err; + + if (!ossl_cmp_certstatus_set0_certHash(certStatus, certHash)) + goto err; + certHash = NULL; + /* + * For any particular CertStatus, omission of the statusInfo field + * indicates ACCEPTANCE of the specified certificate. Alternatively, + * explicit status details (with respect to acceptance or rejection) MAY + * be provided in the statusInfo field, perhaps for auditing purposes at + * the CA/RA. + */ + sinfo = fail_info != 0 ? + OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) : + OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted, 0, text); + if (sinfo == NULL) + goto err; + certStatus->statusInfo = sinfo; + + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTCONF); + OSSL_CMP_MSG_free(msg); + ASN1_OCTET_STRING_free(certHash); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid) +{ + OSSL_CMP_MSG *msg = NULL; + OSSL_CMP_POLLREQ *preq = NULL; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREQ)) == NULL) + goto err; + + if ((preq = OSSL_CMP_POLLREQ_new()) == NULL + || !ASN1_INTEGER_set(preq->certReqId, crid) + || !sk_OSSL_CMP_POLLREQ_push(msg->body->value.pollReq, preq)) + goto err; + + preq = NULL; + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + + return msg; + + err: + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREQ); + OSSL_CMP_POLLREQ_free(preq); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid, + int64_t poll_after) +{ + OSSL_CMP_MSG *msg; + OSSL_CMP_POLLREP *prep; + + if (!ossl_assert(ctx != NULL)) + return NULL; + + if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_POLLREP)) == NULL) + goto err; + if ((prep = OSSL_CMP_POLLREP_new()) == NULL) + goto err; + if (!sk_OSSL_CMP_POLLREP_push(msg->body->value.pollRep, prep)) + goto err; + if (!ASN1_INTEGER_set(prep->certReqId, crid)) + goto err; + if (!ASN1_INTEGER_set_int64(prep->checkAfter, poll_after)) + goto err; + + if (!ossl_cmp_msg_protect(ctx, msg)) + goto err; + return msg; + + err: + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREP); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +/*- + * returns the status field of the RevRepContent with the given + * request/sequence id inside a revocation response. + * RevRepContent has the revocation statuses in same order as they were sent in + * RevReqContent. + * returns NULL on error + */ +OSSL_CMP_PKISI * +ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid) +{ + OSSL_CMP_PKISI *status; + + if (!ossl_assert(rrep != NULL)) + return NULL; + + if ((status = sk_OSSL_CMP_PKISI_value(rrep->status, rsid)) != NULL) + return status; + + ERR_raise(ERR_LIB_CMP, CMP_R_PKISTATUSINFO_NOT_FOUND); + return NULL; +} + +/* + * returns the CertId field in the revCerts part of the RevRepContent + * with the given request/sequence id inside a revocation response. + * RevRepContent has the CertIds in same order as they were sent in + * RevReqContent. + * returns NULL on error + */ +OSSL_CRMF_CERTID * +ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep, int rsid) +{ + OSSL_CRMF_CERTID *cid = NULL; + + if (!ossl_assert(rrep != NULL)) + return NULL; + + if ((cid = sk_OSSL_CRMF_CERTID_value(rrep->revCerts, rsid)) != NULL) + return cid; + + ERR_raise(ERR_LIB_CMP, CMP_R_CERTID_NOT_FOUND); + return NULL; +} + +static int suitable_rid(const ASN1_INTEGER *certReqId, int rid) +{ + int trid; + + if (rid == -1) + return 1; + + trid = ossl_cmp_asn1_get_int(certReqId); + + if (trid == -1) { + ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); + return 0; + } + return rid == trid; +} + +/* + * returns a pointer to the PollResponse with the given CertReqId + * (or the first one in case -1) inside a PollRepContent + * returns NULL on error or if no suitable PollResponse available + */ +OSSL_CMP_POLLREP * +ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc, + int rid) +{ + OSSL_CMP_POLLREP *pollRep = NULL; + int i; + + if (!ossl_assert(prc != NULL)) + return NULL; + + for (i = 0; i < sk_OSSL_CMP_POLLREP_num(prc); i++) { + pollRep = sk_OSSL_CMP_POLLREP_value(prc, i); + if (suitable_rid(pollRep->certReqId, rid)) + return pollRep; + } + + ERR_raise_data(ERR_LIB_CMP, CMP_R_CERTRESPONSE_NOT_FOUND, + "expected certReqId = %d", rid); + return NULL; +} + +/* + * returns a pointer to the CertResponse with the given CertReqId + * (or the first one in case -1) inside a CertRepMessage + * returns NULL on error or if no suitable CertResponse available + */ +OSSL_CMP_CERTRESPONSE * +ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm, + int rid) +{ + OSSL_CMP_CERTRESPONSE *crep = NULL; + int i; + + if (!ossl_assert(crm != NULL && crm->response != NULL)) + return NULL; + + for (i = 0; i < sk_OSSL_CMP_CERTRESPONSE_num(crm->response); i++) { + crep = sk_OSSL_CMP_CERTRESPONSE_value(crm->response, i); + if (suitable_rid(crep->certReqId, rid)) + return crep; + } + + ERR_raise_data(ERR_LIB_CMP, CMP_R_CERTRESPONSE_NOT_FOUND, + "expected certReqId = %d", rid); + return NULL; +} + +/*- + * Retrieve the newly enrolled certificate from the given certResponse crep. + * In case of indirect POPO uses the libctx and propq from ctx and private key. + * Returns a pointer to a copy of the found certificate, or NULL if not found. + */ +X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep, + const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey) +{ + OSSL_CMP_CERTORENCCERT *coec; + X509 *crt = NULL; + + if (!ossl_assert(crep != NULL && ctx != NULL)) + return NULL; + + if (crep->certifiedKeyPair + && (coec = crep->certifiedKeyPair->certOrEncCert) != NULL) { + switch (coec->type) { + case OSSL_CMP_CERTORENCCERT_CERTIFICATE: + crt = X509_dup(coec->value.certificate); + break; + case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT: + /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */ + if (pkey == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY); + return NULL; + } + crt = + OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec->value.encryptedCert, + ctx->libctx, ctx->propq, + pkey); + break; + default: + ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_CERT_TYPE); + return NULL; + } + } + if (crt == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_CERTIFICATE_NOT_FOUND); + else + (void)ossl_x509_set0_libctx(crt, ctx->libctx, ctx->propq); + return crt; +} + +int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) +{ + if (ctx == NULL || msg == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (!ossl_cmp_hdr_set_transactionID(ctx, msg->header)) + return 0; + return msg->header->protectionAlg == NULL + || ossl_cmp_msg_protect(ctx, msg); +} + +OSSL_CMP_MSG *OSSL_CMP_MSG_read(const char *file, OSSL_LIB_CTX *libctx, + const char *propq) +{ + OSSL_CMP_MSG *msg; + BIO *bio = NULL; + + if (file == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + + msg = OSSL_CMP_MSG_new(libctx, propq); + if (msg == NULL){ + ERR_raise(ERR_LIB_CMP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if ((bio = BIO_new_file(file, "rb")) == NULL + || d2i_OSSL_CMP_MSG_bio(bio, &msg) == NULL) { + OSSL_CMP_MSG_free(msg); + msg = NULL; + } + BIO_free(bio); + return msg; +} + +int OSSL_CMP_MSG_write(const char *file, const OSSL_CMP_MSG *msg) +{ + BIO *bio; + int res; + + if (file == NULL || msg == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return -1; + } + + bio = BIO_new_file(file, "wb"); + if (bio == NULL) + return -2; + res = i2d_OSSL_CMP_MSG_bio(bio, msg); + BIO_free(bio); + return res; +} + +OSSL_CMP_MSG *d2i_OSSL_CMP_MSG(OSSL_CMP_MSG **msg, const unsigned char **in, + long len) +{ + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + + if (msg != NULL && *msg != NULL) { + libctx = (*msg)->libctx; + propq = (*msg)->propq; + } + + return (OSSL_CMP_MSG *)ASN1_item_d2i_ex((ASN1_VALUE **)msg, in, len, + ASN1_ITEM_rptr(OSSL_CMP_MSG), + libctx, propq); +} + +int i2d_OSSL_CMP_MSG(const OSSL_CMP_MSG *msg, unsigned char **out) +{ + return ASN1_item_i2d((const ASN1_VALUE *)msg, out, + ASN1_ITEM_rptr(OSSL_CMP_MSG)); +} + +OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg) +{ + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + + if (msg != NULL && *msg != NULL) { + libctx = (*msg)->libctx; + propq = (*msg)->propq; + } + + return ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(OSSL_CMP_MSG), bio, msg, libctx, + propq); +} + +int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg) +{ + return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg); +} diff --git a/crypto/openssl/crypto/cmp/cmp_protect.c b/crypto/openssl/crypto/cmp/cmp_protect.c new file mode 100644 index 000000000000..02526196ad2a --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_protect.c @@ -0,0 +1,332 @@ +/* + * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "cmp_local.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include +#include +#include + +/* + * This function is also used by the internal verify_PBMAC() in cmp_vfy.c. + * + * Calculate protection for given PKImessage according to + * the algorithm and parameters in the message header's protectionAlg + * using the credentials, library context, and property criteria in the ctx. + * + * returns ASN1_BIT_STRING representing the protection on success, else NULL + */ +ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg) +{ + ASN1_BIT_STRING *prot = NULL; + OSSL_CMP_PROTECTEDPART prot_part; + const ASN1_OBJECT *algorOID = NULL; + const void *ppval = NULL; + int pptype = 0; + + if (!ossl_assert(ctx != NULL && msg != NULL)) + return NULL; + + /* construct data to be signed */ + prot_part.header = msg->header; + prot_part.body = msg->body; + + if (msg->header->protectionAlg == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_ALGORITHM_ID); + return NULL; + } + X509_ALGOR_get0(&algorOID, &pptype, &ppval, msg->header->protectionAlg); + + if (OBJ_obj2nid(algorOID) == NID_id_PasswordBasedMAC) { + int len; + size_t prot_part_der_len; + unsigned char *prot_part_der = NULL; + size_t sig_len; + unsigned char *protection = NULL; + OSSL_CRMF_PBMPARAMETER *pbm = NULL; + ASN1_STRING *pbm_str = NULL; + const unsigned char *pbm_str_uc = NULL; + + if (ctx->secretValue == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PBM_SECRET); + return NULL; + } + if (ppval == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CALCULATING_PROTECTION); + return NULL; + } + + len = i2d_OSSL_CMP_PROTECTEDPART(&prot_part, &prot_part_der); + if (len < 0 || prot_part_der == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CALCULATING_PROTECTION); + goto end; + } + prot_part_der_len = (size_t)len; + + pbm_str = (ASN1_STRING *)ppval; + pbm_str_uc = pbm_str->data; + pbm = d2i_OSSL_CRMF_PBMPARAMETER(NULL, &pbm_str_uc, pbm_str->length); + if (pbm == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_ALGORITHM_OID); + goto end; + } + + if (!OSSL_CRMF_pbm_new(ctx->libctx, ctx->propq, + pbm, prot_part_der, prot_part_der_len, + ctx->secretValue->data, ctx->secretValue->length, + &protection, &sig_len)) + goto end; + + if ((prot = ASN1_BIT_STRING_new()) == NULL) + goto end; + /* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */ + prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + prot->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) { + ASN1_BIT_STRING_free(prot); + prot = NULL; + } + end: + OSSL_CRMF_PBMPARAMETER_free(pbm); + OPENSSL_free(protection); + OPENSSL_free(prot_part_der); + return prot; + } else { + int md_nid; + const EVP_MD *md = NULL; + + if (ctx->pkey == NULL) { + ERR_raise(ERR_LIB_CMP, + CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION); + return NULL; + } + if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_nid, NULL) + || (md = EVP_get_digestbynid(md_nid)) == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_ALGORITHM_ID); + return NULL; + } + + if ((prot = ASN1_BIT_STRING_new()) == NULL) + return NULL; + if (ASN1_item_sign_ex(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART), NULL, + NULL, prot, &prot_part, NULL, ctx->pkey, md, + ctx->libctx, ctx->propq)) + return prot; + ASN1_BIT_STRING_free(prot); + return NULL; + } +} + +int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) +{ + if (!ossl_assert(ctx != NULL && msg != NULL)) + return 0; + + /* Add first ctx->cert and its chain if using signature-based protection */ + if (!ctx->unprotectedSend && ctx->secretValue == NULL + && ctx->cert != NULL && ctx->pkey != NULL) { + int prepend = X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP + | X509_ADD_FLAG_PREPEND | X509_ADD_FLAG_NO_SS; + + /* if not yet done try to build chain using available untrusted certs */ + if (ctx->chain == NULL) { + ossl_cmp_debug(ctx, + "trying to build chain for own CMP signer cert"); + ctx->chain = X509_build_chain(ctx->cert, ctx->untrusted, NULL, 0, + ctx->libctx, ctx->propq); + if (ctx->chain != NULL) { + ossl_cmp_debug(ctx, + "success building chain for own CMP signer cert"); + } else { + /* dump errors to avoid confusion when printing further ones */ + OSSL_CMP_CTX_print_errors(ctx); + ossl_cmp_warn(ctx, + "could not build chain for own CMP signer cert"); + } + } + if (ctx->chain != NULL) { + if (!ossl_x509_add_certs_new(&msg->extraCerts, ctx->chain, prepend)) + return 0; + } else { + /* make sure that at least our own signer cert is included first */ + if (!ossl_x509_add_cert_new(&msg->extraCerts, ctx->cert, prepend)) + return 0; + ossl_cmp_debug(ctx, "fallback: adding just own CMP signer cert"); + } + } + + /* add any additional certificates from ctx->extraCertsOut */ + if (!ossl_x509_add_certs_new(&msg->extraCerts, ctx->extraCertsOut, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) + return 0; + + /* in case extraCerts are empty list avoid empty ASN.1 sequence */ + if (sk_X509_num(msg->extraCerts) == 0) { + sk_X509_free(msg->extraCerts); + msg->extraCerts = NULL; + } + return 1; +} + +/* + * Create an X509_ALGOR structure for PasswordBasedMAC protection based on + * the pbm settings in the context + */ +static int set_pbmac_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg) +{ + OSSL_CRMF_PBMPARAMETER *pbm = NULL; + unsigned char *pbm_der = NULL; + int pbm_der_len; + ASN1_STRING *pbm_str = NULL; + + if (!ossl_assert(ctx != NULL)) + return 0; + + pbm = OSSL_CRMF_pbmp_new(ctx->libctx, ctx->pbm_slen, + EVP_MD_get_type(ctx->pbm_owf), ctx->pbm_itercnt, + ctx->pbm_mac); + pbm_str = ASN1_STRING_new(); + if (pbm == NULL || pbm_str == NULL) + goto err; + + if ((pbm_der_len = i2d_OSSL_CRMF_PBMPARAMETER(pbm, &pbm_der)) < 0) + goto err; + + if (!ASN1_STRING_set(pbm_str, pbm_der, pbm_der_len)) + goto err; + if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL) + goto err; + OPENSSL_free(pbm_der); + + X509_ALGOR_set0(*alg, OBJ_nid2obj(NID_id_PasswordBasedMAC), + V_ASN1_SEQUENCE, pbm_str); + OSSL_CRMF_PBMPARAMETER_free(pbm); + return 1; + + err: + ASN1_STRING_free(pbm_str); + OPENSSL_free(pbm_der); + OSSL_CRMF_PBMPARAMETER_free(pbm); + return 0; +} + +static int set_sig_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg) +{ + int nid = 0; + ASN1_OBJECT *algo = NULL; + + if (!OBJ_find_sigid_by_algs(&nid, EVP_MD_get_type(ctx->digest), + EVP_PKEY_get_id(ctx->pkey))) { + ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_KEY_TYPE); + return 0; + } + if ((algo = OBJ_nid2obj(nid)) == NULL) + return 0; + if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL) + return 0; + + if (X509_ALGOR_set0(*alg, algo, V_ASN1_UNDEF, NULL)) + return 1; + ASN1_OBJECT_free(algo); + return 0; +} + +static int set_senderKID(const OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg, + const ASN1_OCTET_STRING *id) +{ + if (id == NULL) + id = ctx->referenceValue; /* standard for PBM, fallback for sig-based */ + return id == NULL || ossl_cmp_hdr_set1_senderKID(msg->header, id); +} + +int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) +{ + if (!ossl_assert(ctx != NULL && msg != NULL)) + return 0; + + /* + * For the case of re-protection remove pre-existing protection. + */ + X509_ALGOR_free(msg->header->protectionAlg); + msg->header->protectionAlg = NULL; + ASN1_BIT_STRING_free(msg->protection); + msg->protection = NULL; + + if (ctx->unprotectedSend) { + if (!set_senderKID(ctx, msg, NULL)) + goto err; + } else if (ctx->secretValue != NULL) { + /* use PasswordBasedMac according to 5.1.3.1 if secretValue is given */ + if (!set_pbmac_algor(ctx, &msg->header->protectionAlg)) + goto err; + if (!set_senderKID(ctx, msg, NULL)) + goto err; + + /* + * will add any additional certificates from ctx->extraCertsOut + * while not needed to validate the protection certificate, + * the option to do this might be handy for certain use cases + */ + } else if (ctx->cert != NULL && ctx->pkey != NULL) { + /* use MSG_SIG_ALG according to 5.1.3.3 if client cert and key given */ + + /* make sure that key and certificate match */ + if (!X509_check_private_key(ctx->cert, ctx->pkey)) { + ERR_raise(ERR_LIB_CMP, CMP_R_CERT_AND_KEY_DO_NOT_MATCH); + goto err; + } + + if (!set_sig_algor(ctx, &msg->header->protectionAlg)) + goto err; + /* set senderKID to keyIdentifier of the cert according to 5.1.1 */ + if (!set_senderKID(ctx, msg, X509_get0_subject_key_id(ctx->cert))) + goto err; + + /* + * will add ctx->cert followed, if possible, by its chain built + * from ctx->untrusted, and then ctx->extraCertsOut + */ + } else { + ERR_raise(ERR_LIB_CMP, + CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION); + goto err; + } + if (!ctx->unprotectedSend + && ((msg->protection = ossl_cmp_calc_protection(ctx, msg)) == NULL)) + goto err; + + /* + * For signature-based protection add ctx->cert followed by its chain. + * Finally add any additional certificates from ctx->extraCertsOut; + * even if not needed to validate the protection + * the option to do this might be handy for certain use cases. + */ + if (!ossl_cmp_msg_add_extraCerts(ctx, msg)) + goto err; + + /* + * As required by RFC 4210 section 5.1.1., if the sender name is not known + * to the client it set to NULL-DN. In this case for identification at least + * the senderKID must be set, where we took the referenceValue as fallback. + */ + if (!(ossl_cmp_general_name_is_NULL_DN(msg->header->sender) + && msg->header->senderKID == NULL)) + return 1; + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_SENDER_IDENTIFICATION); + + err: + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROTECTING_MESSAGE); + return 0; +} diff --git a/crypto/openssl/crypto/cmp/cmp_server.c b/crypto/openssl/crypto/cmp/cmp_server.c new file mode 100644 index 000000000000..946c32c45ebf --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_server.c @@ -0,0 +1,644 @@ +/* + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* general CMP server functions */ + +#include + +#include "cmp_local.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include + +/* the context for the generic CMP server */ +struct ossl_cmp_srv_ctx_st +{ + OSSL_CMP_CTX *ctx; /* Client CMP context, partly reused for srv */ + void *custom_ctx; /* pointer to specific server context */ + + OSSL_CMP_SRV_cert_request_cb_t process_cert_request; + OSSL_CMP_SRV_rr_cb_t process_rr; + OSSL_CMP_SRV_genm_cb_t process_genm; + OSSL_CMP_SRV_error_cb_t process_error; + OSSL_CMP_SRV_certConf_cb_t process_certConf; + OSSL_CMP_SRV_pollReq_cb_t process_pollReq; + + int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */ + int acceptUnprotected; /* Accept requests with no/invalid prot. */ + int acceptRAVerified; /* Accept ir/cr/kur with POPO RAVerified */ + int grantImplicitConfirm; /* Grant implicit confirmation if requested */ + +}; /* OSSL_CMP_SRV_CTX */ + +void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx) +{ + if (srv_ctx == NULL) + return; + + OSSL_CMP_CTX_free(srv_ctx->ctx); + OPENSSL_free(srv_ctx); +} + +OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) +{ + OSSL_CMP_SRV_CTX *ctx = OPENSSL_zalloc(sizeof(OSSL_CMP_SRV_CTX)); + + if (ctx == NULL) + goto err; + + if ((ctx->ctx = OSSL_CMP_CTX_new(libctx, propq)) == NULL) + goto err; + + /* all other elements are initialized to 0 or NULL, respectively */ + return ctx; + err: + OSSL_CMP_SRV_CTX_free(ctx); + return NULL; +} + +int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx, + OSSL_CMP_SRV_cert_request_cb_t process_cert_request, + OSSL_CMP_SRV_rr_cb_t process_rr, + OSSL_CMP_SRV_genm_cb_t process_genm, + OSSL_CMP_SRV_error_cb_t process_error, + OSSL_CMP_SRV_certConf_cb_t process_certConf, + OSSL_CMP_SRV_pollReq_cb_t process_pollReq) +{ + if (srv_ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + srv_ctx->custom_ctx = custom_ctx; + srv_ctx->process_cert_request = process_cert_request; + srv_ctx->process_rr = process_rr; + srv_ctx->process_genm = process_genm; + srv_ctx->process_error = process_error; + srv_ctx->process_certConf = process_certConf; + srv_ctx->process_pollReq = process_pollReq; + return 1; +} + +OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx) +{ + if (srv_ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return srv_ctx->ctx; +} + +void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx) +{ + if (srv_ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + return srv_ctx->custom_ctx; +} + +int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx, + int val) +{ + if (srv_ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + srv_ctx->sendUnprotectedErrors = val != 0; + return 1; +} + +int OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX *srv_ctx, int val) +{ + if (srv_ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + srv_ctx->acceptUnprotected = val != 0; + return 1; +} + +int OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX *srv_ctx, int val) +{ + if (srv_ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + srv_ctx->acceptRAVerified = val != 0; + return 1; +} + +int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx, + int val) +{ + if (srv_ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + srv_ctx->grantImplicitConfirm = val != 0; + return 1; +} + +/* + * Processes an ir/cr/p10cr/kur and returns a certification response. + * Only handles the first certification request contained in req + * returns an ip/cp/kup on success and NULL on error + */ +static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req) +{ + OSSL_CMP_MSG *msg = NULL; + OSSL_CMP_PKISI *si = NULL; + X509 *certOut = NULL; + STACK_OF(X509) *chainOut = NULL, *caPubs = NULL; + const OSSL_CRMF_MSG *crm = NULL; + const X509_REQ *p10cr = NULL; + int bodytype; + int certReqId; + + if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL)) + return NULL; + + switch (OSSL_CMP_MSG_get_bodytype(req)) { + case OSSL_CMP_PKIBODY_P10CR: + case OSSL_CMP_PKIBODY_CR: + bodytype = OSSL_CMP_PKIBODY_CP; + break; + case OSSL_CMP_PKIBODY_IR: + bodytype = OSSL_CMP_PKIBODY_IP; + break; + case OSSL_CMP_PKIBODY_KUR: + bodytype = OSSL_CMP_PKIBODY_KUP; + break; + default: + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + return NULL; + } + + if (OSSL_CMP_MSG_get_bodytype(req) == OSSL_CMP_PKIBODY_P10CR) { + certReqId = OSSL_CMP_CERTREQID; + p10cr = req->body->value.p10cr; + } else { + OSSL_CRMF_MSGS *reqs = req->body->value.ir; /* same for cr and kur */ + + if (sk_OSSL_CRMF_MSG_num(reqs) != 1) { + ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED); + return NULL; + } + + if ((crm = sk_OSSL_CRMF_MSG_value(reqs, OSSL_CMP_CERTREQID)) == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND); + return NULL; + } + certReqId = OSSL_CRMF_MSG_get_certReqId(crm); + } + + if (!ossl_cmp_verify_popo(srv_ctx->ctx, req, srv_ctx->acceptRAVerified)) { + /* Proof of possession could not be verified */ + si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, + 1 << OSSL_CMP_PKIFAILUREINFO_badPOP, + ERR_reason_error_string(ERR_peek_error())); + if (si == NULL) + return NULL; + } else { + OSSL_CMP_PKIHEADER *hdr = OSSL_CMP_MSG_get0_header(req); + + si = srv_ctx->process_cert_request(srv_ctx, req, certReqId, crm, p10cr, + &certOut, &chainOut, &caPubs); + if (si == NULL) + goto err; + /* set OSSL_CMP_OPT_IMPLICIT_CONFIRM if and only if transaction ends */ + if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx, + OSSL_CMP_OPT_IMPLICIT_CONFIRM, + ossl_cmp_hdr_has_implicitConfirm(hdr) + && srv_ctx->grantImplicitConfirm + /* do not set if polling starts: */ + && certOut != NULL)) + goto err; + } + + msg = ossl_cmp_certrep_new(srv_ctx->ctx, bodytype, certReqId, si, + certOut, NULL /* enc */, chainOut, caPubs, + srv_ctx->sendUnprotectedErrors); + if (msg == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREP); + + err: + OSSL_CMP_PKISI_free(si); + X509_free(certOut); + sk_X509_pop_free(chainOut, X509_free); + sk_X509_pop_free(caPubs, X509_free); + return msg; +} + +static OSSL_CMP_MSG *process_rr(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req) +{ + OSSL_CMP_MSG *msg = NULL; + OSSL_CMP_REVDETAILS *details; + OSSL_CRMF_CERTID *certId = NULL; + OSSL_CRMF_CERTTEMPLATE *tmpl; + const X509_NAME *issuer; + const ASN1_INTEGER *serial; + OSSL_CMP_PKISI *si; + + if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL)) + return NULL; + + if (sk_OSSL_CMP_REVDETAILS_num(req->body->value.rr) != 1) { + ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED); + return NULL; + } + + if ((details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr, + OSSL_CMP_REVREQSID)) == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); + return NULL; + } + + tmpl = details->certDetails; + issuer = OSSL_CRMF_CERTTEMPLATE_get0_issuer(tmpl); + serial = OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl); + if (issuer != NULL && serial != NULL + && (certId = OSSL_CRMF_CERTID_gen(issuer, serial)) == NULL) + return NULL; + if ((si = srv_ctx->process_rr(srv_ctx, req, issuer, serial)) == NULL) + goto err; + + if ((msg = ossl_cmp_rp_new(srv_ctx->ctx, si, certId, + srv_ctx->sendUnprotectedErrors)) == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_RR); + + err: + OSSL_CRMF_CERTID_free(certId); + OSSL_CMP_PKISI_free(si); + return msg; +} + +/* + * Processes genm and creates a genp message mirroring the contents of the + * incoming message + */ +static OSSL_CMP_MSG *process_genm(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req) +{ + OSSL_CMP_GENMSGCONTENT *itavs; + OSSL_CMP_MSG *msg; + + if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL)) + return NULL; + + if (!srv_ctx->process_genm(srv_ctx, req, req->body->value.genm, &itavs)) + return NULL; + + msg = ossl_cmp_genp_new(srv_ctx->ctx, itavs); + sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free); + return msg; +} + +static OSSL_CMP_MSG *process_error(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req) +{ + OSSL_CMP_ERRORMSGCONTENT *errorContent; + OSSL_CMP_MSG *msg; + + if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL)) + return NULL; + errorContent = req->body->value.error; + srv_ctx->process_error(srv_ctx, req, errorContent->pKIStatusInfo, + errorContent->errorCode, errorContent->errorDetails); + + if ((msg = ossl_cmp_pkiconf_new(srv_ctx->ctx)) == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_PKICONF); + return msg; +} + +static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req) +{ + OSSL_CMP_CTX *ctx; + OSSL_CMP_CERTCONFIRMCONTENT *ccc; + int num; + OSSL_CMP_MSG *msg = NULL; + OSSL_CMP_CERTSTATUS *status = NULL; + + if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL)) + return NULL; + + ctx = srv_ctx->ctx; + ccc = req->body->value.certConf; + num = sk_OSSL_CMP_CERTSTATUS_num(ccc); + + if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM) == 1 + || ctx->status != OSSL_CMP_PKISTATUS_trans) { + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_UNEXPECTED_CERTCONF); + return NULL; + } + + if (num == 0) { + ossl_cmp_err(ctx, "certificate rejected by client"); + } else { + if (num > 1) + ossl_cmp_warn(ctx, "All CertStatus but the first will be ignored"); + status = sk_OSSL_CMP_CERTSTATUS_value(ccc, OSSL_CMP_CERTREQID); + } + + if (status != NULL) { + int certReqId = ossl_cmp_asn1_get_int(status->certReqId); + ASN1_OCTET_STRING *certHash = status->certHash; + OSSL_CMP_PKISI *si = status->statusInfo; + + if (!srv_ctx->process_certConf(srv_ctx, req, certReqId, certHash, si)) + return NULL; /* reason code may be: CMP_R_CERTHASH_UNMATCHED */ + + if (si != NULL + && ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_accepted) { + int pki_status = ossl_cmp_pkisi_get_status(si); + const char *str = ossl_cmp_PKIStatus_to_string(pki_status); + + ossl_cmp_log2(INFO, ctx, "certificate rejected by client %s %s", + str == NULL ? "without" : "with", + str == NULL ? "PKIStatus" : str); + } + } + + if ((msg = ossl_cmp_pkiconf_new(ctx)) == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_PKICONF); + return msg; +} + +static OSSL_CMP_MSG *process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req) +{ + OSSL_CMP_POLLREQCONTENT *prc; + OSSL_CMP_POLLREQ *pr; + int certReqId; + OSSL_CMP_MSG *certReq; + int64_t check_after = 0; + OSSL_CMP_MSG *msg = NULL; + + if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL)) + return NULL; + + prc = req->body->value.pollReq; + if (sk_OSSL_CMP_POLLREQ_num(prc) != 1) { + ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED); + return NULL; + } + + pr = sk_OSSL_CMP_POLLREQ_value(prc, 0); + certReqId = ossl_cmp_asn1_get_int(pr->certReqId); + if (!srv_ctx->process_pollReq(srv_ctx, req, certReqId, + &certReq, &check_after)) + return NULL; + + if (certReq != NULL) { + msg = process_cert_request(srv_ctx, certReq); + OSSL_CMP_MSG_free(certReq); + } else { + if ((msg = ossl_cmp_pollRep_new(srv_ctx->ctx, certReqId, + check_after)) == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREP); + } + return msg; +} + +/* + * Determine whether missing/invalid protection of request message is allowed. + * Return 1 on acceptance, 0 on rejection, or -1 on (internal) error. + */ +static int unprotected_exception(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *req, + int invalid_protection, + int accept_unprotected_requests) +{ + if (!ossl_assert(ctx != NULL && req != NULL)) + return -1; + + if (accept_unprotected_requests) { + ossl_cmp_log1(WARN, ctx, "ignoring %s protection of request message", + invalid_protection ? "invalid" : "missing"); + return 1; + } + if (OSSL_CMP_MSG_get_bodytype(req) == OSSL_CMP_PKIBODY_ERROR + && OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS) == 1) { + ossl_cmp_warn(ctx, "ignoring missing protection of error message"); + return 1; + } + return 0; +} + +/* + * returns created message and NULL on internal error + */ +OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req) +{ + OSSL_CMP_CTX *ctx; + ASN1_OCTET_STRING *backup_secret; + OSSL_CMP_PKIHEADER *hdr; + int req_type, rsp_type; + int res; + OSSL_CMP_MSG *rsp = NULL; + + if (srv_ctx == NULL || srv_ctx->ctx == NULL + || req == NULL || req->body == NULL + || (hdr = OSSL_CMP_MSG_get0_header(req)) == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx = srv_ctx->ctx; + backup_secret = ctx->secretValue; + req_type = OSSL_CMP_MSG_get_bodytype(req); + ossl_cmp_log1(DEBUG, ctx, + "received %s", ossl_cmp_bodytype_to_string(req_type)); + + /* + * Some things need to be done already before validating the message in + * order to be able to send an error message as far as needed and possible. + */ + if (hdr->sender->type != GEN_DIRNAME) { + ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED); + goto err; + } + if (!OSSL_CMP_CTX_set1_recipient(ctx, hdr->sender->d.directoryName)) + goto err; + + switch (req_type) { + case OSSL_CMP_PKIBODY_IR: + case OSSL_CMP_PKIBODY_CR: + case OSSL_CMP_PKIBODY_P10CR: + case OSSL_CMP_PKIBODY_KUR: + case OSSL_CMP_PKIBODY_RR: + case OSSL_CMP_PKIBODY_GENM: + case OSSL_CMP_PKIBODY_ERROR: + if (ctx->transactionID != NULL) { + char *tid; + + tid = OPENSSL_buf2hexstr(ctx->transactionID->data, + ctx->transactionID->length); + if (tid != NULL) + ossl_cmp_log1(WARN, ctx, + "Assuming that last transaction with ID=%s got aborted", + tid); + OPENSSL_free(tid); + } + /* start of a new transaction, reset transactionID and senderNonce */ + if (!OSSL_CMP_CTX_set1_transactionID(ctx, NULL) + || !OSSL_CMP_CTX_set1_senderNonce(ctx, NULL)) + goto err; + break; + default: + /* transactionID should be already initialized */ + if (ctx->transactionID == NULL) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + goto err; +#endif + } + } + + res = ossl_cmp_msg_check_update(ctx, req, unprotected_exception, + srv_ctx->acceptUnprotected); + if (ctx->secretValue != NULL && ctx->pkey != NULL + && ossl_cmp_hdr_get_protection_nid(hdr) != NID_id_PasswordBasedMAC) + ctx->secretValue = NULL; /* use MSG_SIG_ALG when protecting rsp */ + if (!res) + goto err; + + switch (req_type) { + case OSSL_CMP_PKIBODY_IR: + case OSSL_CMP_PKIBODY_CR: + case OSSL_CMP_PKIBODY_P10CR: + case OSSL_CMP_PKIBODY_KUR: + if (srv_ctx->process_cert_request == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + else + rsp = process_cert_request(srv_ctx, req); + break; + case OSSL_CMP_PKIBODY_RR: + if (srv_ctx->process_rr == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + else + rsp = process_rr(srv_ctx, req); + break; + case OSSL_CMP_PKIBODY_GENM: + if (srv_ctx->process_genm == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + else + rsp = process_genm(srv_ctx, req); + break; + case OSSL_CMP_PKIBODY_ERROR: + if (srv_ctx->process_error == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + else + rsp = process_error(srv_ctx, req); + break; + case OSSL_CMP_PKIBODY_CERTCONF: + if (srv_ctx->process_certConf == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + else + rsp = process_certConf(srv_ctx, req); + break; + case OSSL_CMP_PKIBODY_POLLREQ: + if (srv_ctx->process_pollReq == NULL) + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + else + rsp = process_pollReq(srv_ctx, req); + break; + default: + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); + break; + } + + err: + if (rsp == NULL) { + /* on error, try to respond with CMP error message to client */ + const char *data = NULL, *reason = NULL; + int flags = 0; + unsigned long err = ERR_peek_error_data(&data, &flags); + int fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_badRequest; + OSSL_CMP_PKISI *si = NULL; + + if (ctx->transactionID == NULL) { + /* ignore any (extra) error in next two function calls: */ + (void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID); + (void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce); + } + + if ((flags & ERR_TXT_STRING) == 0 || *data == '\0') + data = NULL; + reason = ERR_reason_error_string(err); + if ((si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, + fail_info, reason)) != NULL) { + rsp = ossl_cmp_error_new(srv_ctx->ctx, si, err, + data, srv_ctx->sendUnprotectedErrors); + OSSL_CMP_PKISI_free(si); + } + } + OSSL_CMP_CTX_print_errors(ctx); + ctx->secretValue = backup_secret; + + rsp_type = + rsp != NULL ? OSSL_CMP_MSG_get_bodytype(rsp) : OSSL_CMP_PKIBODY_ERROR; + if (rsp != NULL) + ossl_cmp_log1(DEBUG, ctx, + "sending %s", ossl_cmp_bodytype_to_string(rsp_type)); + else + ossl_cmp_log(ERR, ctx, "cannot send proper CMP response"); + + /* determine whether to keep the transaction open or not */ + ctx->status = OSSL_CMP_PKISTATUS_trans; + switch (rsp_type) { + case OSSL_CMP_PKIBODY_IP: + case OSSL_CMP_PKIBODY_CP: + case OSSL_CMP_PKIBODY_KUP: + if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM) == 0) + break; + /* fall through */ + + case OSSL_CMP_PKIBODY_RP: + case OSSL_CMP_PKIBODY_PKICONF: + case OSSL_CMP_PKIBODY_GENP: + case OSSL_CMP_PKIBODY_ERROR: + (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL); + (void)OSSL_CMP_CTX_set1_senderNonce(ctx, NULL); + ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */ + + default: /* not closing transaction in other cases */ + break; + } + return rsp; +} + +/* + * Server interface that may substitute OSSL_CMP_MSG_http_perform at the client. + * The OSSL_CMP_SRV_CTX must be set as client_ctx->transfer_cb_arg. + * returns received message on success, else NULL and pushes an element on the + * error stack. + */ +OSSL_CMP_MSG *OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx, + const OSSL_CMP_MSG *req) +{ + OSSL_CMP_SRV_CTX *srv_ctx = NULL; + + if (client_ctx == NULL || req == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + + if ((srv_ctx = OSSL_CMP_CTX_get_transfer_cb_arg(client_ctx)) == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_TRANSFER_ERROR); + return NULL; + } + + return OSSL_CMP_SRV_process_request(srv_ctx, req); +} diff --git a/crypto/openssl/crypto/cmp/cmp_status.c b/crypto/openssl/crypto/cmp/cmp_status.c new file mode 100644 index 000000000000..bfe6cd9906b8 --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_status.c @@ -0,0 +1,314 @@ +/* + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* CMP functions for PKIStatusInfo handling and PKIMessage decomposition */ + +#include + +#include "cmp_local.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include +#include /* needed in case config no-deprecated */ +#include +#include +#include +#include +#include /* for ASN1_R_TOO_SMALL and ASN1_R_TOO_LARGE */ + +/* CMP functions related to PKIStatus */ + +int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si) +{ + if (!ossl_assert(si != NULL && si->status != NULL)) + return -1; + return ossl_cmp_asn1_get_int(si->status); +} + +const char *ossl_cmp_PKIStatus_to_string(int status) +{ + switch (status) { + case OSSL_CMP_PKISTATUS_accepted: + return "PKIStatus: accepted"; + case OSSL_CMP_PKISTATUS_grantedWithMods: + return "PKIStatus: granted with modifications"; + case OSSL_CMP_PKISTATUS_rejection: + return "PKIStatus: rejection"; + case OSSL_CMP_PKISTATUS_waiting: + return "PKIStatus: waiting"; + case OSSL_CMP_PKISTATUS_revocationWarning: + return "PKIStatus: revocation warning - a revocation of the cert is imminent"; + case OSSL_CMP_PKISTATUS_revocationNotification: + return "PKIStatus: revocation notification - a revocation of the cert has occurred"; + case OSSL_CMP_PKISTATUS_keyUpdateWarning: + return "PKIStatus: key update warning - update already done for the cert"; + default: + ERR_raise_data(ERR_LIB_CMP, CMP_R_ERROR_PARSING_PKISTATUS, + "PKIStatus: invalid=%d", status); + return NULL; + } +} + +OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si) +{ + if (!ossl_assert(si != NULL)) + return NULL; + return si->statusString; +} + +int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si) +{ + int i; + int res = 0; + + if (!ossl_assert(si != NULL)) + return -1; + if (si->failInfo != NULL) + for (i = 0; i <= OSSL_CMP_PKIFAILUREINFO_MAX; i++) + if (ASN1_BIT_STRING_get_bit(si->failInfo, i)) + res |= 1 << i; + return res; +} + +/*- + * convert PKIFailureInfo number to human-readable string + * returns pointer to static string, or NULL on error + */ +static const char *CMP_PKIFAILUREINFO_to_string(int number) +{ + switch (number) { + case OSSL_CMP_PKIFAILUREINFO_badAlg: + return "badAlg"; + case OSSL_CMP_PKIFAILUREINFO_badMessageCheck: + return "badMessageCheck"; + case OSSL_CMP_PKIFAILUREINFO_badRequest: + return "badRequest"; + case OSSL_CMP_PKIFAILUREINFO_badTime: + return "badTime"; + case OSSL_CMP_PKIFAILUREINFO_badCertId: + return "badCertId"; + case OSSL_CMP_PKIFAILUREINFO_badDataFormat: + return "badDataFormat"; + case OSSL_CMP_PKIFAILUREINFO_wrongAuthority: + return "wrongAuthority"; + case OSSL_CMP_PKIFAILUREINFO_incorrectData: + return "incorrectData"; + case OSSL_CMP_PKIFAILUREINFO_missingTimeStamp: + return "missingTimeStamp"; + case OSSL_CMP_PKIFAILUREINFO_badPOP: + return "badPOP"; + case OSSL_CMP_PKIFAILUREINFO_certRevoked: + return "certRevoked"; + case OSSL_CMP_PKIFAILUREINFO_certConfirmed: + return "certConfirmed"; + case OSSL_CMP_PKIFAILUREINFO_wrongIntegrity: + return "wrongIntegrity"; + case OSSL_CMP_PKIFAILUREINFO_badRecipientNonce: + return "badRecipientNonce"; + case OSSL_CMP_PKIFAILUREINFO_timeNotAvailable: + return "timeNotAvailable"; + case OSSL_CMP_PKIFAILUREINFO_unacceptedPolicy: + return "unacceptedPolicy"; + case OSSL_CMP_PKIFAILUREINFO_unacceptedExtension: + return "unacceptedExtension"; + case OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable: + return "addInfoNotAvailable"; + case OSSL_CMP_PKIFAILUREINFO_badSenderNonce: + return "badSenderNonce"; + case OSSL_CMP_PKIFAILUREINFO_badCertTemplate: + return "badCertTemplate"; + case OSSL_CMP_PKIFAILUREINFO_signerNotTrusted: + return "signerNotTrusted"; + case OSSL_CMP_PKIFAILUREINFO_transactionIdInUse: + return "transactionIdInUse"; + case OSSL_CMP_PKIFAILUREINFO_unsupportedVersion: + return "unsupportedVersion"; + case OSSL_CMP_PKIFAILUREINFO_notAuthorized: + return "notAuthorized"; + case OSSL_CMP_PKIFAILUREINFO_systemUnavail: + return "systemUnavail"; + case OSSL_CMP_PKIFAILUREINFO_systemFailure: + return "systemFailure"; + case OSSL_CMP_PKIFAILUREINFO_duplicateCertReq: + return "duplicateCertReq"; + default: + return NULL; /* illegal failure number */ + } +} + +int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int bit_index) +{ + if (!ossl_assert(si != NULL && si->failInfo != NULL)) + return -1; + if (bit_index < 0 || bit_index > OSSL_CMP_PKIFAILUREINFO_MAX) { + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ARGS); + return -1; + } + + return ASN1_BIT_STRING_get_bit(si->failInfo, bit_index); +} + +/*- + * place human-readable error string created from PKIStatusInfo in given buffer + * returns pointer to the same buffer containing the string, or NULL on error + */ +static +char *snprint_PKIStatusInfo_parts(int status, int fail_info, + const OSSL_CMP_PKIFREETEXT *status_strings, + char *buf, size_t bufsize) +{ + int failure; + const char *status_string, *failure_string; + ASN1_UTF8STRING *text; + int i; + int printed_chars; + int failinfo_found = 0; + int n_status_strings; + char *write_ptr = buf; + + if (buf == NULL + || status < 0 + || (status_string = ossl_cmp_PKIStatus_to_string(status)) == NULL) + return NULL; + +#define ADVANCE_BUFFER \ + if (printed_chars < 0 || (size_t)printed_chars >= bufsize) \ + return NULL; \ + write_ptr += printed_chars; \ + bufsize -= printed_chars; + + printed_chars = BIO_snprintf(write_ptr, bufsize, "%s", status_string); + ADVANCE_BUFFER; + + /* + * failInfo is optional and may be empty; + * if present, print failInfo before statusString because it is more concise + */ + if (fail_info != -1 && fail_info != 0) { + printed_chars = BIO_snprintf(write_ptr, bufsize, "; PKIFailureInfo: "); + ADVANCE_BUFFER; + for (failure = 0; failure <= OSSL_CMP_PKIFAILUREINFO_MAX; failure++) { + if ((fail_info & (1 << failure)) != 0) { + failure_string = CMP_PKIFAILUREINFO_to_string(failure); + if (failure_string != NULL) { + printed_chars = BIO_snprintf(write_ptr, bufsize, "%s%s", + failinfo_found ? ", " : "", + failure_string); + ADVANCE_BUFFER; + failinfo_found = 1; + } + } + } + } + if (!failinfo_found && status != OSSL_CMP_PKISTATUS_accepted + && status != OSSL_CMP_PKISTATUS_grantedWithMods) { + printed_chars = BIO_snprintf(write_ptr, bufsize, "; "); + ADVANCE_BUFFER; + } + + /* statusString sequence is optional and may be empty */ + n_status_strings = sk_ASN1_UTF8STRING_num(status_strings); + if (n_status_strings > 0) { + printed_chars = BIO_snprintf(write_ptr, bufsize, "; StatusString%s: ", + n_status_strings > 1 ? "s" : ""); + ADVANCE_BUFFER; + for (i = 0; i < n_status_strings; i++) { + text = sk_ASN1_UTF8STRING_value(status_strings, i); + printed_chars = BIO_snprintf(write_ptr, bufsize, "\"%.*s\"%s", + ASN1_STRING_length(text), + ASN1_STRING_get0_data(text), + i < n_status_strings - 1 ? ", " : ""); + ADVANCE_BUFFER; + } + } +#undef ADVANCE_BUFFER + return buf; +} + +char *OSSL_CMP_snprint_PKIStatusInfo(const OSSL_CMP_PKISI *statusInfo, + char *buf, size_t bufsize) +{ + int failure_info; + + if (statusInfo == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + + failure_info = ossl_cmp_pkisi_get_pkifailureinfo(statusInfo); + + return snprint_PKIStatusInfo_parts(ASN1_INTEGER_get(statusInfo->status), + failure_info, + statusInfo->statusString, buf, bufsize); +} + +char *OSSL_CMP_CTX_snprint_PKIStatus(const OSSL_CMP_CTX *ctx, char *buf, + size_t bufsize) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return NULL; + } + + return snprint_PKIStatusInfo_parts(OSSL_CMP_CTX_get_status(ctx), + OSSL_CMP_CTX_get_failInfoCode(ctx), + OSSL_CMP_CTX_get0_statusString(ctx), + buf, bufsize); +} + +/*- + * Creates a new PKIStatusInfo structure and fills it in + * returns a pointer to the structure on success, NULL on error + * note: strongly overlaps with TS_RESP_CTX_set_status_info() + * and TS_RESP_CTX_add_failure_info() in ../ts/ts_rsp_sign.c + */ +OSSL_CMP_PKISI *OSSL_CMP_STATUSINFO_new(int status, int fail_info, + const char *text) +{ + OSSL_CMP_PKISI *si = OSSL_CMP_PKISI_new(); + ASN1_UTF8STRING *utf8_text = NULL; + int failure; + + if (si == NULL) + goto err; + if (!ASN1_INTEGER_set(si->status, status)) + goto err; + + if (text != NULL) { + if ((utf8_text = ASN1_UTF8STRING_new()) == NULL + || !ASN1_STRING_set(utf8_text, text, -1)) + goto err; + if ((si->statusString = sk_ASN1_UTF8STRING_new_null()) == NULL) + goto err; + if (!sk_ASN1_UTF8STRING_push(si->statusString, utf8_text)) + goto err; + /* Ownership is lost. */ + utf8_text = NULL; + } + + for (failure = 0; failure <= OSSL_CMP_PKIFAILUREINFO_MAX; failure++) { + if ((fail_info & (1 << failure)) != 0) { + if (si->failInfo == NULL + && (si->failInfo = ASN1_BIT_STRING_new()) == NULL) + goto err; + if (!ASN1_BIT_STRING_set_bit(si->failInfo, failure, 1)) + goto err; + } + } + return si; + + err: + OSSL_CMP_PKISI_free(si); + ASN1_UTF8STRING_free(utf8_text); + return NULL; +} diff --git a/crypto/openssl/crypto/cmp/cmp_util.c b/crypto/openssl/crypto/cmp/cmp_util.c new file mode 100644 index 000000000000..7cf27cc9d4b4 --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_util.c @@ -0,0 +1,286 @@ +/* + * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "cmp_local.h" /* just for decls of internal functions defined here */ +#include +#include /* should be implied by cmperr.h */ +#include + +/* + * use trace API for CMP-specific logging, prefixed by "CMP " and severity + */ + +int OSSL_CMP_log_open(void) /* is designed to be idempotent */ +{ +#ifdef OPENSSL_NO_TRACE + return 1; +#else +# ifndef OPENSSL_NO_STDIO + BIO *bio = BIO_new_fp(stdout, BIO_NOCLOSE); + + if (bio != NULL && OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_CMP, bio)) + return 1; + BIO_free(bio); +# endif + ERR_raise(ERR_LIB_CMP, CMP_R_NO_STDIO); + return 0; +#endif +} + +void OSSL_CMP_log_close(void) /* is designed to be idempotent */ +{ + (void)OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_CMP, NULL); +} + +/* return >= 0 if level contains logging level, possibly preceded by "CMP " */ +#define max_level_len 5 /* = max length of the below strings, e.g., "EMERG" */ +static OSSL_CMP_severity parse_level(const char *level) +{ + const char *end_level = strchr(level, ':'); + int len; + char level_copy[max_level_len + 1]; + + if (end_level == NULL) + return -1; + + if (strncmp(level, OSSL_CMP_LOG_PREFIX, + strlen(OSSL_CMP_LOG_PREFIX)) == 0) + level += strlen(OSSL_CMP_LOG_PREFIX); + len = end_level - level; + if (len > max_level_len) + return -1; + OPENSSL_strlcpy(level_copy, level, len + 1); + return + strcmp(level_copy, "EMERG") == 0 ? OSSL_CMP_LOG_EMERG : + strcmp(level_copy, "ALERT") == 0 ? OSSL_CMP_LOG_ALERT : + strcmp(level_copy, "CRIT") == 0 ? OSSL_CMP_LOG_CRIT : + strcmp(level_copy, "ERROR") == 0 ? OSSL_CMP_LOG_ERR : + strcmp(level_copy, "WARN") == 0 ? OSSL_CMP_LOG_WARNING : + strcmp(level_copy, "NOTE") == 0 ? OSSL_CMP_LOG_NOTICE : + strcmp(level_copy, "INFO") == 0 ? OSSL_CMP_LOG_INFO : + strcmp(level_copy, "DEBUG") == 0 ? OSSL_CMP_LOG_DEBUG : + -1; +} + +const char *ossl_cmp_log_parse_metadata(const char *buf, + OSSL_CMP_severity *level, + char **func, char **file, int *line) +{ + const char *p_func = buf; + const char *p_file = buf == NULL ? NULL : strchr(buf, ':'); + const char *p_level = buf; + const char *msg = buf; + + *level = -1; + *func = NULL; + *file = NULL; + *line = 0; + + if (p_file != NULL) { + const char *p_line = strchr(++p_file, ':'); + + if ((*level = parse_level(buf)) < 0 && p_line != NULL) { + /* check if buf contains location info and logging level */ + char *p_level_tmp = (char *)p_level; + const long line_number = strtol(++p_line, &p_level_tmp, 10); + + p_level = p_level_tmp; + if (p_level > p_line && *(p_level++) == ':') { + if ((*level = parse_level(p_level)) >= 0) { + *func = OPENSSL_strndup(p_func, p_file - 1 - p_func); + *file = OPENSSL_strndup(p_file, p_line - 1 - p_file); + /* no real problem if OPENSSL_strndup() returns NULL */ + *line = (int)line_number; + msg = strchr(p_level, ':'); + if (msg != NULL && *++msg == ' ') + msg++; + } + } + } + } + return msg; +} + +#define UNKNOWN_FUNC "(unknown function)" /* the default for OPENSSL_FUNC */ +/* + * substitute fallback if component/function name is NULL or empty or contains + * just pseudo-information "(unknown function)" due to -pedantic and macros.h + */ +static const char *improve_location_name(const char *func, const char *fallback) +{ + if (fallback == NULL) + return func == NULL ? UNKNOWN_FUNC : func; + + return func == NULL || *func == '\0' || strcmp(func, UNKNOWN_FUNC) == 0 + ? fallback : func; +} + +int OSSL_CMP_print_to_bio(BIO *bio, const char *component, const char *file, + int line, OSSL_CMP_severity level, const char *msg) +{ + const char *level_string = + level == OSSL_CMP_LOG_EMERG ? "EMERG" : + level == OSSL_CMP_LOG_ALERT ? "ALERT" : + level == OSSL_CMP_LOG_CRIT ? "CRIT" : + level == OSSL_CMP_LOG_ERR ? "error" : + level == OSSL_CMP_LOG_WARNING ? "warning" : + level == OSSL_CMP_LOG_NOTICE ? "NOTE" : + level == OSSL_CMP_LOG_INFO ? "info" : + level == OSSL_CMP_LOG_DEBUG ? "DEBUG" : "(unknown level)"; + +#ifndef NDEBUG + if (BIO_printf(bio, "%s:%s:%d:", improve_location_name(component, "CMP"), + file, line) < 0) + return 0; +#endif + return BIO_printf(bio, OSSL_CMP_LOG_PREFIX"%s: %s\n", + level_string, msg) >= 0; +} + +#define ERR_PRINT_BUF_SIZE 4096 +/* this is similar to ERR_print_errors_cb, but uses the CMP-specific cb type */ +void OSSL_CMP_print_errors_cb(OSSL_CMP_log_cb_t log_fn) +{ + unsigned long err; + char msg[ERR_PRINT_BUF_SIZE]; + const char *file = NULL, *func = NULL, *data = NULL; + int line, flags; + + while ((err = ERR_get_error_all(&file, &line, &func, &data, &flags)) != 0) { + const char *component = + improve_location_name(func, ERR_lib_error_string(err)); + unsigned long reason = ERR_GET_REASON(err); + const char *rs = NULL; + char rsbuf[256]; + +#ifndef OPENSSL_NO_ERR + if (ERR_SYSTEM_ERROR(err)) { + if (openssl_strerror_r(reason, rsbuf, sizeof(rsbuf))) + rs = rsbuf; + } else { + rs = ERR_reason_error_string(err); + } +#endif + if (rs == NULL) { + BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", reason); + rs = rsbuf; + } + if (data != NULL && (flags & ERR_TXT_STRING) != 0) + BIO_snprintf(msg, sizeof(msg), "%s:%s", rs, data); + else + BIO_snprintf(msg, sizeof(msg), "%s", rs); + + if (log_fn == NULL) { +#ifndef OPENSSL_NO_STDIO + BIO *bio = BIO_new_fp(stderr, BIO_NOCLOSE); + + if (bio != NULL) { + OSSL_CMP_print_to_bio(bio, component, file, line, + OSSL_CMP_LOG_ERR, msg); + BIO_free(bio); + } +#else + /* ERR_raise(ERR_LIB_CMP, CMP_R_NO_STDIO) makes no sense during error printing */ +#endif + } else { + if (log_fn(component, file, line, OSSL_CMP_LOG_ERR, msg) <= 0) + break; /* abort outputting the error report */ + } + } +} + +int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs, + int only_self_signed) +{ + int i; + + if (store == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (certs == NULL) + return 1; + for (i = 0; i < sk_X509_num(certs); i++) { + X509 *cert = sk_X509_value(certs, i); + + if (!only_self_signed || X509_self_signed(cert, 0) == 1) + if (!X509_STORE_add_cert(store, cert)) /* ups cert ref counter */ + return 0; + } + return 1; +} + +int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk, + const char *text, int len) +{ + ASN1_UTF8STRING *utf8string; + + if (!ossl_assert(sk != NULL && text != NULL)) + return 0; + if ((utf8string = ASN1_UTF8STRING_new()) == NULL) + return 0; + if (!ASN1_STRING_set(utf8string, text, len)) + goto err; + if (!sk_ASN1_UTF8STRING_push(sk, utf8string)) + goto err; + return 1; + + err: + ASN1_UTF8STRING_free(utf8string); + return 0; +} + +int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt, + const ASN1_OCTET_STRING *src) +{ + ASN1_OCTET_STRING *new; + if (tgt == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (*tgt == src) /* self-assignment */ + return 1; + + if (src != NULL) { + if ((new = ASN1_OCTET_STRING_dup(src)) == NULL) + return 0; + } else { + new = NULL; + } + + ASN1_OCTET_STRING_free(*tgt); + *tgt = new; + return 1; +} + +int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt, + const unsigned char *bytes, int len) +{ + ASN1_OCTET_STRING *new = NULL; + + if (tgt == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (bytes != NULL) { + if ((new = ASN1_OCTET_STRING_new()) == NULL + || !(ASN1_OCTET_STRING_set(new, bytes, len))) { + ASN1_OCTET_STRING_free(new); + return 0; + } + } + + ASN1_OCTET_STRING_free(*tgt); + *tgt = new; + return 1; +} diff --git a/crypto/openssl/crypto/cmp/cmp_vfy.c b/crypto/openssl/crypto/cmp/cmp_vfy.c new file mode 100644 index 000000000000..99cd56cb091f --- /dev/null +++ b/crypto/openssl/crypto/cmp/cmp_vfy.c @@ -0,0 +1,856 @@ +/* + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2020 + * Copyright Siemens AG 2015-2020 + * + * 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 + */ + +/* CMP functions for PKIMessage checking */ + +#include "cmp_local.h" +#include + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include +#include +#include + +/* Verify a message protected by signature according to RFC section 5.1.3.3 */ +static int verify_signature(const OSSL_CMP_CTX *cmp_ctx, + const OSSL_CMP_MSG *msg, X509 *cert) +{ + OSSL_CMP_PROTECTEDPART prot_part; + EVP_PKEY *pubkey = NULL; + BIO *bio; + int res = 0; + + if (!ossl_assert(cmp_ctx != NULL && msg != NULL && cert != NULL)) + return 0; + + bio = BIO_new(BIO_s_mem()); /* may be NULL */ + + /* verify that keyUsage, if present, contains digitalSignature */ + if (!cmp_ctx->ignore_keyusage + && (X509_get_key_usage(cert) & X509v3_KU_DIGITAL_SIGNATURE) == 0) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE); + goto sig_err; + } + + pubkey = X509_get_pubkey(cert); + if (pubkey == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_FAILED_EXTRACTING_PUBKEY); + goto sig_err; + } + + prot_part.header = msg->header; + prot_part.body = msg->body; + + if (ASN1_item_verify_ex(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART), + msg->header->protectionAlg, msg->protection, + &prot_part, NULL, pubkey, cmp_ctx->libctx, + cmp_ctx->propq) > 0) { + res = 1; + goto end; + } + + sig_err: + res = ossl_x509_print_ex_brief(bio, cert, X509_FLAG_NO_EXTENSIONS); + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_SIGNATURE); + if (res) + ERR_add_error_mem_bio("\n", bio); + res = 0; + + end: + EVP_PKEY_free(pubkey); + BIO_free(bio); + + return res; +} + +/* Verify a message protected with PBMAC */ +static int verify_PBMAC(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) +{ + ASN1_BIT_STRING *protection = NULL; + int valid = 0; + + /* generate expected protection for the message */ + if ((protection = ossl_cmp_calc_protection(ctx, msg)) == NULL) + return 0; /* failed to generate protection string! */ + + valid = msg->protection != NULL && msg->protection->length >= 0 + && msg->protection->type == protection->type + && msg->protection->length == protection->length + && CRYPTO_memcmp(msg->protection->data, protection->data, + protection->length) == 0; + ASN1_BIT_STRING_free(protection); + if (!valid) + ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_PBM_VALUE); + + return valid; +} + +/*- + * Attempt to validate certificate and path using any given store with trusted + * certs (possibly including CRLs and a cert verification callback function) + * and non-trusted intermediate certs from the given ctx. + * + * Returns 1 on successful validation and 0 otherwise. + */ +int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx, + X509_STORE *trusted_store, X509 *cert) +{ + int valid = 0; + X509_STORE_CTX *csc = NULL; + int err; + + if (ctx == NULL || cert == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + + if (trusted_store == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_TRUST_STORE); + return 0; + } + + if ((csc = X509_STORE_CTX_new_ex(ctx->libctx, ctx->propq)) == NULL + || !X509_STORE_CTX_init(csc, trusted_store, + cert, ctx->untrusted)) + goto err; + + valid = X509_verify_cert(csc) > 0; + + /* make sure suitable error is queued even if callback did not do */ + err = ERR_peek_last_error(); + if (!valid && ERR_GET_REASON(err) != CMP_R_POTENTIALLY_INVALID_CERTIFICATE) + ERR_raise(ERR_LIB_CMP, CMP_R_POTENTIALLY_INVALID_CERTIFICATE); + + err: + /* directly output any fresh errors, needed for check_msg_find_cert() */ + OSSL_CMP_CTX_print_errors(ctx); + X509_STORE_CTX_free(csc); + return valid; +} + +/* Return 0 if expect_name != NULL and there is no matching actual_name */ +static int check_name(const OSSL_CMP_CTX *ctx, int log_success, + const char *actual_desc, const X509_NAME *actual_name, + const char *expect_desc, const X509_NAME *expect_name) +{ + char *str; + + if (expect_name == NULL) + return 1; /* no expectation, thus trivially fulfilled */ + + /* make sure that a matching name is there */ + if (actual_name == NULL) { + ossl_cmp_log1(WARN, ctx, "missing %s", actual_desc); + return 0; + } + str = X509_NAME_oneline(actual_name, NULL, 0); + if (X509_NAME_cmp(actual_name, expect_name) == 0) { + if (log_success && str != NULL) + ossl_cmp_log2(INFO, ctx, " subject matches %s: %s", expect_desc, + str); + OPENSSL_free(str); + return 1; + } + + if (str != NULL) + ossl_cmp_log2(INFO, ctx, " actual name in %s = %s", actual_desc, str); + OPENSSL_free(str); + if ((str = X509_NAME_oneline(expect_name, NULL, 0)) != NULL) + ossl_cmp_log2(INFO, ctx, " does not match %s = %s", expect_desc, str); + OPENSSL_free(str); + return 0; +} + +/* Return 0 if skid != NULL and there is no matching subject key ID in cert */ +static int check_kid(const OSSL_CMP_CTX *ctx, + const ASN1_OCTET_STRING *ckid, + const ASN1_OCTET_STRING *skid) +{ + char *str; + + if (skid == NULL) + return 1; /* no expectation, thus trivially fulfilled */ + + /* make sure that the expected subject key identifier is there */ + if (ckid == NULL) { + ossl_cmp_warn(ctx, "missing Subject Key Identifier in certificate"); + return 0; + } + str = OPENSSL_buf2hexstr(ckid->data, ckid->length); + if (ASN1_OCTET_STRING_cmp(ckid, skid) == 0) { + if (str != NULL) + ossl_cmp_log1(INFO, ctx, " subjectKID matches senderKID: %s", str); + OPENSSL_free(str); + return 1; + } + + if (str != NULL) + ossl_cmp_log1(INFO, ctx, " cert Subject Key Identifier = %s", str); + OPENSSL_free(str); + if ((str = OPENSSL_buf2hexstr(skid->data, skid->length)) != NULL) + ossl_cmp_log1(INFO, ctx, " does not match senderKID = %s", str); + OPENSSL_free(str); + return 0; +} + +static int already_checked(const X509 *cert, + const STACK_OF(X509) *already_checked) +{ + int i; + + for (i = sk_X509_num(already_checked /* may be NULL */); i > 0; i--) + if (X509_cmp(sk_X509_value(already_checked, i - 1), cert) == 0) + return 1; + return 0; +} + +/*- + * Check if the given cert is acceptable as sender cert of the given message. + * The subject DN must match, the subject key ID as well if present in the msg, + * and the cert must be current (checked if ctx->trusted is not NULL). + * Note that cert revocation etc. is checked by OSSL_CMP_validate_cert_path(). + * + * Returns 0 on error or not acceptable, else 1. + */ +static int cert_acceptable(const OSSL_CMP_CTX *ctx, + const char *desc1, const char *desc2, X509 *cert, + const STACK_OF(X509) *already_checked1, + const STACK_OF(X509) *already_checked2, + const OSSL_CMP_MSG *msg) +{ + X509_STORE *ts = ctx->trusted; + int self_issued = X509_check_issued(cert, cert) == X509_V_OK; + char *str; + X509_VERIFY_PARAM *vpm = ts != NULL ? X509_STORE_get0_param(ts) : NULL; + int time_cmp; + + ossl_cmp_log3(INFO, ctx, " considering %s%s %s with..", + self_issued ? "self-issued ": "", desc1, desc2); + if ((str = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0)) != NULL) + ossl_cmp_log1(INFO, ctx, " subject = %s", str); + OPENSSL_free(str); + if (!self_issued) { + str = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); + if (str != NULL) + ossl_cmp_log1(INFO, ctx, " issuer = %s", str); + OPENSSL_free(str); + } + + if (already_checked(cert, already_checked1) + || already_checked(cert, already_checked2)) { + ossl_cmp_info(ctx, " cert has already been checked"); + return 0; + } + + time_cmp = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert), + X509_get0_notAfter(cert)); + if (time_cmp != 0) { + ossl_cmp_warn(ctx, time_cmp > 0 ? "cert has expired" + : "cert is not yet valid"); + return 0; + } + + if (!check_name(ctx, 1, + "cert subject", X509_get_subject_name(cert), + "sender field", msg->header->sender->d.directoryName)) + return 0; + + if (!check_kid(ctx, X509_get0_subject_key_id(cert), msg->header->senderKID)) + return 0; + /* prevent misleading error later in case x509v3_cache_extensions() fails */ + if (!ossl_x509v3_cache_extensions(cert)) { + ossl_cmp_warn(ctx, "cert appears to be invalid"); + return 0; + } + if (!verify_signature(ctx, msg, cert)) { + ossl_cmp_warn(ctx, "msg signature verification failed"); + return 0; + } + /* acceptable also if there is no senderKID in msg header */ + ossl_cmp_info(ctx, " cert seems acceptable"); + return 1; +} + +static int check_cert_path(const OSSL_CMP_CTX *ctx, X509_STORE *store, + X509 *scrt) +{ + if (OSSL_CMP_validate_cert_path(ctx, store, scrt)) + return 1; + + ossl_cmp_warn(ctx, + "msg signature validates but cert path validation failed"); + return 0; +} + +/* + * Exceptional handling for 3GPP TS 33.310 [3G/LTE Network Domain Security + * (NDS); Authentication Framework (AF)], only to use for IP messages + * and if the ctx option is explicitly set: use self-issued certificates + * from extraCerts as trust anchor to validate sender cert - + * provided it also can validate the newly enrolled certificate + */ +static int check_cert_path_3gpp(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg, X509 *scrt) +{ + int valid = 0; + X509_STORE *store; + + if (!ctx->permitTAInExtraCertsForIR) + return 0; + + if ((store = X509_STORE_new()) == NULL + || !ossl_cmp_X509_STORE_add1_certs(store, msg->extraCerts, + 1 /* self-issued only */)) + goto err; + + /* store does not include CRLs */ + valid = OSSL_CMP_validate_cert_path(ctx, store, scrt); + if (!valid) { + ossl_cmp_warn(ctx, + "also exceptional 3GPP mode cert path validation failed"); + } else { + /* + * verify that the newly enrolled certificate (which assumed rid == + * OSSL_CMP_CERTREQID) can also be validated with the same trusted store + */ + EVP_PKEY *pkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); + OSSL_CMP_CERTRESPONSE *crep = + ossl_cmp_certrepmessage_get0_certresponse(msg->body->value.ip, + OSSL_CMP_CERTREQID); + X509 *newcrt = ossl_cmp_certresponse_get1_cert(crep, ctx, pkey); + /* + * maybe better use get_cert_status() from cmp_client.c, which catches + * errors + */ + valid = OSSL_CMP_validate_cert_path(ctx, store, newcrt); + X509_free(newcrt); + } + + err: + X509_STORE_free(store); + return valid; +} + +static int check_msg_given_cert(const OSSL_CMP_CTX *ctx, X509 *cert, + const OSSL_CMP_MSG *msg) +{ + return cert_acceptable(ctx, "previously validated", "sender cert", + cert, NULL, NULL, msg) + && (check_cert_path(ctx, ctx->trusted, cert) + || check_cert_path_3gpp(ctx, msg, cert)); +} + +/*- + * Try all certs in given list for verifying msg, normally or in 3GPP mode. + * If already_checked1 == NULL then certs are assumed to be the msg->extraCerts. + * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). + */ +static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs, + const char *desc, + const STACK_OF(X509) *already_checked1, + const STACK_OF(X509) *already_checked2, + const OSSL_CMP_MSG *msg, int mode_3gpp) +{ + int in_extraCerts = already_checked1 == NULL; + int n_acceptable_certs = 0; + int i; + + if (sk_X509_num(certs) <= 0) { + ossl_cmp_log1(WARN, ctx, "no %s", desc); + return 0; + } + + for (i = 0; i < sk_X509_num(certs); i++) { /* certs may be NULL */ + X509 *cert = sk_X509_value(certs, i); + + if (!ossl_assert(cert != NULL)) + return 0; + if (!cert_acceptable(ctx, "cert from", desc, cert, + already_checked1, already_checked2, msg)) + continue; + n_acceptable_certs++; + if (mode_3gpp ? check_cert_path_3gpp(ctx, msg, cert) + : check_cert_path(ctx, ctx->trusted, cert)) { + /* store successful sender cert for further msgs in transaction */ + if (!X509_up_ref(cert)) + return 0; + if (!ossl_cmp_ctx_set0_validatedSrvCert(ctx, cert)) { + X509_free(cert); + return 0; + } + return 1; + } + } + if (in_extraCerts && n_acceptable_certs == 0) + ossl_cmp_warn(ctx, "no acceptable cert in extraCerts"); + return 0; +} + +/*- + * Verify msg trying first ctx->untrusted, which should include extraCerts + * at its front, then trying the trusted certs in truststore (if any) of ctx. + * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). + */ +static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, + int mode_3gpp) +{ + int ret = 0; + + if (mode_3gpp + && ((!ctx->permitTAInExtraCertsForIR + || OSSL_CMP_MSG_get_bodytype(msg) != OSSL_CMP_PKIBODY_IP))) + return 0; + + ossl_cmp_info(ctx, + mode_3gpp ? "normal mode failed; trying now 3GPP mode trusting extraCerts" + : "trying first normal mode using trust store"); + if (check_msg_with_certs(ctx, msg->extraCerts, "extraCerts", + NULL, NULL, msg, mode_3gpp)) + return 1; + if (check_msg_with_certs(ctx, ctx->untrusted, "untrusted certs", + msg->extraCerts, NULL, msg, mode_3gpp)) + return 1; + + if (ctx->trusted == NULL) { + ossl_cmp_warn(ctx, mode_3gpp ? "no self-issued extraCerts" + : "no trusted store"); + } else { + STACK_OF(X509) *trusted = X509_STORE_get1_all_certs(ctx->trusted); + ret = check_msg_with_certs(ctx, trusted, + mode_3gpp ? "self-issued extraCerts" + : "certs in trusted store", + msg->extraCerts, ctx->untrusted, + msg, mode_3gpp); + sk_X509_pop_free(trusted, X509_free); + } + return ret; +} + +static int no_log_cb(const char *func, const char *file, int line, + OSSL_CMP_severity level, const char *msg) +{ + return 1; +} + +/*- + * Verify message signature with any acceptable and valid candidate cert. + * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). + */ +static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) +{ + X509 *scrt = ctx->validatedSrvCert; /* previous successful sender cert */ + GENERAL_NAME *sender = msg->header->sender; + char *sname = NULL; + char *skid_str = NULL; + const ASN1_OCTET_STRING *skid = msg->header->senderKID; + OSSL_CMP_log_cb_t backup_log_cb = ctx->log_cb; + int res = 0; + + if (sender == NULL || msg->body == NULL) + return 0; /* other NULL cases already have been checked */ + if (sender->type != GEN_DIRNAME) { + ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED); + return 0; + } + + /* dump any hitherto errors to avoid confusion when printing further ones */ + OSSL_CMP_CTX_print_errors(ctx); + + /* enable clearing irrelevant errors in attempts to validate sender certs */ + (void)ERR_set_mark(); + ctx->log_cb = no_log_cb; /* temporarily disable logging */ + + /* + * try first cached scrt, used successfully earlier in same transaction, + * for validating this and any further msgs where extraCerts may be left out + */ + if (scrt != NULL) { + if (check_msg_given_cert(ctx, scrt, msg)) { + ctx->log_cb = backup_log_cb; + (void)ERR_pop_to_mark(); + return 1; + } + /* cached sender cert has shown to be no more successfully usable */ + (void)ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL); + /* re-do the above check (just) for adding diagnostic information */ + ossl_cmp_info(ctx, + "trying to verify msg signature with previously validated cert"); + (void)check_msg_given_cert(ctx, scrt, msg); + } + + res = check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */) + || check_msg_all_certs(ctx, msg, 1 /* 3gpp */); + ctx->log_cb = backup_log_cb; + if (res) { + /* discard any diagnostic information on trying to use certs */ + (void)ERR_pop_to_mark(); + goto end; + } + /* failed finding a sender cert that verifies the message signature */ + (void)ERR_clear_last_mark(); + + sname = X509_NAME_oneline(sender->d.directoryName, NULL, 0); + skid_str = skid == NULL ? NULL + : OPENSSL_buf2hexstr(skid->data, skid->length); + if (ctx->log_cb != NULL) { + ossl_cmp_info(ctx, "trying to verify msg signature with a valid cert that.."); + if (sname != NULL) + ossl_cmp_log1(INFO, ctx, "matches msg sender = %s", sname); + if (skid_str != NULL) + ossl_cmp_log1(INFO, ctx, "matches msg senderKID = %s", skid_str); + else + ossl_cmp_info(ctx, "while msg header does not contain senderKID"); + /* re-do the above checks (just) for adding diagnostic information */ + (void)check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */); + (void)check_msg_all_certs(ctx, msg, 1 /* 3gpp */); + } + + ERR_raise(ERR_LIB_CMP, CMP_R_NO_SUITABLE_SENDER_CERT); + if (sname != NULL) { + ERR_add_error_txt(NULL, "for msg sender name = "); + ERR_add_error_txt(NULL, sname); + } + if (skid_str != NULL) { + ERR_add_error_txt(" and ", "for msg senderKID = "); + ERR_add_error_txt(NULL, skid_str); + } + + end: + OPENSSL_free(sname); + OPENSSL_free(skid_str); + return res; +} + +/*- + * Validate the protection of the given PKIMessage using either password- + * based mac (PBM) or a signature algorithm. In the case of signature algorithm, + * the sender certificate can have been pinned by providing it in ctx->srvCert, + * else it is searched in msg->extraCerts, ctx->untrusted, in ctx->trusted + * (in this order) and is path is validated against ctx->trusted. + * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). + * + * If ctx->permitTAInExtraCertsForIR is true and when validating a CMP IP msg, + * the trust anchor for validating the IP msg may be taken from msg->extraCerts + * if a self-issued certificate is found there that can be used to + * validate the enrolled certificate returned in the IP. + * This is according to the need given in 3GPP TS 33.310. + * + * Returns 1 on success, 0 on error or validation failed. + */ +int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) +{ + X509 *scrt; + + ossl_cmp_debug(ctx, "validating CMP message"); + if (ctx == NULL || msg == NULL + || msg->header == NULL || msg->body == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + + if (msg->header->protectionAlg == NULL /* unprotected message */ + || msg->protection == NULL || msg->protection->data == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PROTECTION); + return 0; + } + + switch (ossl_cmp_hdr_get_protection_nid(msg->header)) { + /* 5.1.3.1. Shared Secret Information */ + case NID_id_PasswordBasedMAC: + if (ctx->secretValue == NULL) { + ossl_cmp_info(ctx, "no secret available for verifying PBM-based CMP message protection"); + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_SECRET); + return 0; + } + if (verify_PBMAC(ctx, msg)) { + /* + * RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is + * "shared secret information", then any certificate transported in + * the caPubs field may be directly trusted as a root CA + * certificate by the initiator.' + */ + switch (OSSL_CMP_MSG_get_bodytype(msg)) { + case -1: + return 0; + case OSSL_CMP_PKIBODY_IP: + case OSSL_CMP_PKIBODY_CP: + case OSSL_CMP_PKIBODY_KUP: + case OSSL_CMP_PKIBODY_CCP: + if (ctx->trusted != NULL) { + STACK_OF(X509) *certs = msg->body->value.ip->caPubs; + /* value.ip is same for cp, kup, and ccp */ + + if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0)) + /* adds both self-issued and not self-issued certs */ + return 0; + } + break; + default: + break; + } + ossl_cmp_debug(ctx, + "sucessfully validated PBM-based CMP message protection"); + return 1; + } + ossl_cmp_warn(ctx, "verifying PBM-based CMP message protection failed"); + break; + + /* + * 5.1.3.2 DH Key Pairs + * Not yet supported + */ + case NID_id_DHBasedMac: + ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC); + break; + + /* + * 5.1.3.3. Signature + */ + default: + scrt = ctx->srvCert; + if (scrt == NULL) { + if (ctx->trusted == NULL) { + ossl_cmp_info(ctx, "no trust store nor pinned server cert available for verifying signature-based CMP message protection"); + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_TRUST_ANCHOR); + return 0; + } + if (check_msg_find_cert(ctx, msg)) + return 1; + } else { /* use pinned sender cert */ + /* use ctx->srvCert for signature check even if not acceptable */ + if (verify_signature(ctx, msg, scrt)) { + ossl_cmp_debug(ctx, + "sucessfully validated signature-based CMP message protection"); + + return 1; + } + ossl_cmp_warn(ctx, "CMP message signature verification failed"); + ERR_raise(ERR_LIB_CMP, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG); + } + break; + } + return 0; +} + + +/*- + * Check received message (i.e., response by server or request from client) + * Any msg->extraCerts are prepended to ctx->untrusted. + * + * Ensures that: + * its sender is of appropriate type (curently only X509_NAME) and + * matches any expected sender or srvCert subject given in the ctx + * it has a valid body type + * its protection is valid (or invalid/absent, but only if a callback function + * is present and yields a positive result using also the supplied argument) + * its transaction ID matches the previous transaction ID stored in ctx (if any) + * its recipNonce matches the previous senderNonce stored in the ctx (if any) + * + * If everything is fine: + * learns the senderNonce from the received message, + * learns the transaction ID if it is not yet in ctx, + * and makes any certs in caPubs directly trusted. + * + * Returns 1 on success, 0 on error. + */ +int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, + ossl_cmp_allow_unprotected_cb_t cb, int cb_arg) +{ + OSSL_CMP_PKIHEADER *hdr; + const X509_NAME *expected_sender; + + if (!ossl_assert(ctx != NULL && msg != NULL && msg->header != NULL)) + return 0; + hdr = OSSL_CMP_MSG_get0_header(msg); + + /* validate sender name of received msg */ + if (hdr->sender->type != GEN_DIRNAME) { + ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED); + return 0; + } + /* + * Compare actual sender name of response with expected sender name. + * Mitigates risk to accept misused PBM secret + * or misused certificate of an unauthorized entity of a trusted hierarchy. + */ + expected_sender = ctx->expected_sender; + if (expected_sender == NULL && ctx->srvCert != NULL) + expected_sender = X509_get_subject_name(ctx->srvCert); + if (!check_name(ctx, 0, "sender DN field", hdr->sender->d.directoryName, + "expected sender", expected_sender)) + return 0; + /* Note: if recipient was NULL-DN it could be learned here if needed */ + + if (sk_X509_num(msg->extraCerts) > 10) + ossl_cmp_warn(ctx, + "received CMP message contains more than 10 extraCerts"); + /* + * Store any provided extraCerts in ctx for use in OSSL_CMP_validate_msg() + * and for future use, such that they are available to ctx->certConf_cb and + * the peer does not need to send them again in the same transaction. + * Note that it does not help validating the message before storing the + * extraCerts because they do not belong to the protected msg part anyway. + * For efficiency, the extraCerts are prepended so they get used first. + */ + if (!X509_add_certs(ctx->untrusted, msg->extraCerts, + /* this allows self-signed certs */ + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP + | X509_ADD_FLAG_PREPEND)) + return 0; + + /* validate message protection */ + if (hdr->protectionAlg != NULL) { + /* detect explicitly permitted exceptions for invalid protection */ + if (!OSSL_CMP_validate_msg(ctx, msg) + && (cb == NULL || (*cb)(ctx, msg, 1, cb_arg) <= 0)) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_PROTECTION); + return 0; +#endif + } + } else { + /* detect explicitly permitted exceptions for missing protection */ + if (cb == NULL || (*cb)(ctx, msg, 0, cb_arg) <= 0) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PROTECTION); + return 0; +#endif + } + } + + /* check CMP version number in header */ + if (ossl_cmp_hdr_get_pvno(hdr) != OSSL_CMP_PVNO) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PVNO); + return 0; +#endif + } + + if (OSSL_CMP_MSG_get_bodytype(msg) < 0) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ERR_raise(ERR_LIB_CMP, CMP_R_PKIBODY_ERROR); + return 0; +#endif + } + + /* compare received transactionID with the expected one in previous msg */ + if (ctx->transactionID != NULL + && (hdr->transactionID == NULL + || ASN1_OCTET_STRING_cmp(ctx->transactionID, + hdr->transactionID) != 0)) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ERR_raise(ERR_LIB_CMP, CMP_R_TRANSACTIONID_UNMATCHED); + return 0; +#endif + } + + /* compare received nonce with the one we sent */ + if (ctx->senderNonce != NULL + && (msg->header->recipNonce == NULL + || ASN1_OCTET_STRING_cmp(ctx->senderNonce, + hdr->recipNonce) != 0)) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ERR_raise(ERR_LIB_CMP, CMP_R_RECIPNONCE_UNMATCHED); + return 0; +#endif + } + + /* + * RFC 4210 section 5.1.1 states: the recipNonce is copied from + * the senderNonce of the previous message in the transaction. + * --> Store for setting in next message + */ + if (!ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce)) + return 0; + + /* if not yet present, learn transactionID */ + if (ctx->transactionID == NULL + && !OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID)) + return -1; + + /* + * Store any provided extraCerts in ctx for future use, + * such that they are available to ctx->certConf_cb and + * the peer does not need to send them again in the same transaction. + * For efficiency, the extraCerts are prepended so they get used first. + */ + if (!X509_add_certs(ctx->untrusted, msg->extraCerts, + /* this allows self-signed certs */ + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP + | X509_ADD_FLAG_PREPEND)) + return -1; + + if (ossl_cmp_hdr_get_protection_nid(hdr) == NID_id_PasswordBasedMAC) { + /* + * RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is + * "shared secret information", then any certificate transported in + * the caPubs field may be directly trusted as a root CA + * certificate by the initiator.' + */ + switch (OSSL_CMP_MSG_get_bodytype(msg)) { + case OSSL_CMP_PKIBODY_IP: + case OSSL_CMP_PKIBODY_CP: + case OSSL_CMP_PKIBODY_KUP: + case OSSL_CMP_PKIBODY_CCP: + if (ctx->trusted != NULL) { + STACK_OF(X509) *certs = msg->body->value.ip->caPubs; + /* value.ip is same for cp, kup, and ccp */ + + if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0)) + /* adds both self-issued and not self-issued certs */ + return 0; + } + break; + default: + break; + } + } + return 1; +} + +int ossl_cmp_verify_popo(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg, int acceptRAVerified) +{ + if (!ossl_assert(msg != NULL && msg->body != NULL)) + return 0; + switch (msg->body->type) { + case OSSL_CMP_PKIBODY_P10CR: + { + X509_REQ *req = msg->body->value.p10cr; + + if (X509_REQ_verify_ex(req, X509_REQ_get0_pubkey(req), ctx->libctx, + ctx->propq) <= 0) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ERR_raise(ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED); + return 0; +#endif + } + } + break; + case OSSL_CMP_PKIBODY_IR: + case OSSL_CMP_PKIBODY_CR: + case OSSL_CMP_PKIBODY_KUR: + if (!OSSL_CRMF_MSGS_verify_popo(msg->body->value.ir, OSSL_CMP_CERTREQID, + acceptRAVerified, + ctx->libctx, ctx->propq)) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + return 0; +#endif + } + break; + default: + ERR_raise(ERR_LIB_CMP, CMP_R_PKIBODY_ERROR); + return 0; + } + return 1; +} diff --git a/crypto/openssl/crypto/cms/build.info b/crypto/openssl/crypto/cms/build.info index cb675436ef06..5fabea7c53d1 100644 --- a/crypto/openssl/crypto/cms/build.info +++ b/crypto/openssl/crypto/cms/build.info @@ -2,4 +2,4 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]= \ cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \ cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c \ - cms_pwri.c cms_kari.c + cms_pwri.c cms_kari.c cms_rsa.c cms_dh.c cms_ec.c diff --git a/crypto/openssl/crypto/cms/cms_asn1.c b/crypto/openssl/crypto/cms/cms_asn1.c index 08069d72a29e..72cd14317d47 100644 --- a/crypto/openssl/crypto/cms/cms_asn1.c +++ b/crypto/openssl/crypto/cms/cms_asn1.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -245,6 +245,17 @@ ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = { ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1) } ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData) +/* Defined in RFC 5083 - Section 2.1. AuthEnvelopedData Type */ +ASN1_NDEF_SEQUENCE(CMS_AuthEnvelopedData) = { + ASN1_EMBED(CMS_AuthEnvelopedData, version, INT32), + ASN1_IMP_OPT(CMS_AuthEnvelopedData, originatorInfo, CMS_OriginatorInfo, 0), + ASN1_SET_OF(CMS_AuthEnvelopedData, recipientInfos, CMS_RecipientInfo), + ASN1_SIMPLE(CMS_AuthEnvelopedData, authEncryptedContentInfo, CMS_EncryptedContentInfo), + ASN1_IMP_SET_OF_OPT(CMS_AuthEnvelopedData, authAttrs, X509_ALGOR, 2), + ASN1_SIMPLE(CMS_AuthEnvelopedData, mac, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(CMS_AuthEnvelopedData, unauthAttrs, X509_ALGOR, 3) +} ASN1_NDEF_SEQUENCE_END(CMS_AuthEnvelopedData) + ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = { ASN1_EMBED(CMS_AuthenticatedData, version, INT32), ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0), @@ -273,6 +284,7 @@ ASN1_ADB(CMS_ContentInfo) = { ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)), ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)), ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)), + ADB_ENTRY(NID_id_smime_ct_authEnvelopedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authEnvelopedData, CMS_AuthEnvelopedData, 0)), ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)), ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)), } ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL); diff --git a/crypto/openssl/crypto/cms/cms_att.c b/crypto/openssl/crypto/cms/cms_att.c index 4f716619193a..5b99516b29a1 100644 --- a/crypto/openssl/crypto/cms/cms_att.c +++ b/crypto/openssl/crypto/cms/cms_att.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -125,7 +125,8 @@ int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, return 0; } -void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid, +void *CMS_signed_get0_data_by_OBJ(const CMS_SignerInfo *si, + const ASN1_OBJECT *oid, int lastpos, int type) { return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type); @@ -262,7 +263,7 @@ static int cms_check_attribute(int nid, int flags, int type, * 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 ossl_cms_si_check_attributes(const CMS_SignerInfo *si) { int i; int have_signed_attrs = (CMS_signed_get_attr_count(si) > 0); @@ -276,7 +277,7 @@ int CMS_si_check_attributes(const CMS_SignerInfo *si) 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); + ERR_raise(ERR_LIB_CMS, CMS_R_ATTRIBUTE_ERROR); return 0; } } diff --git a/crypto/openssl/crypto/cms/cms_cd.c b/crypto/openssl/crypto/cms/cms_cd.c index 45365b8ba247..6de6d55e58d8 100644 --- a/crypto/openssl/crypto/cms/cms_cd.c +++ b/crypto/openssl/crypto/cms/cms_cd.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -21,20 +21,22 @@ /* CMS CompressedData Utilities */ -CMS_ContentInfo *cms_CompressedData_create(int comp_nid) +CMS_ContentInfo *ossl_cms_CompressedData_create(int comp_nid, + OSSL_LIB_CTX *libctx, + const char *propq) { CMS_ContentInfo *cms; CMS_CompressedData *cd; + /* * Will need something cleverer if there is ever more than one * compression algorithm or parameters have some meaning... */ if (comp_nid != NID_zlib_compression) { - CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE, - CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); return NULL; } - cms = CMS_ContentInfo_new(); + cms = CMS_ContentInfo_new_ex(libctx, propq); if (cms == NULL) return NULL; @@ -60,20 +62,19 @@ CMS_ContentInfo *cms_CompressedData_create(int comp_nid) return NULL; } -BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms) +BIO *ossl_cms_CompressedData_init_bio(const CMS_ContentInfo *cms) { CMS_CompressedData *cd; const ASN1_OBJECT *compoid; + if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) { - CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, - CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA); + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA); return NULL; } cd = cms->d.compressedData; X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm); if (OBJ_obj2nid(compoid) != NID_zlib_compression) { - CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, - CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); return NULL; } return BIO_new(BIO_f_zlib()); diff --git a/crypto/openssl/crypto/cms/cms_dd.c b/crypto/openssl/crypto/cms/cms_dd.c index 0df2e698c237..6a7c049ef316 100644 --- a/crypto/openssl/crypto/cms/cms_dd.c +++ b/crypto/openssl/crypto/cms/cms_dd.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -17,11 +17,14 @@ /* CMS DigestedData Utilities */ -CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md) +CMS_ContentInfo *ossl_cms_DigestedData_create(const EVP_MD *md, + OSSL_LIB_CTX *libctx, + const char *propq) { CMS_ContentInfo *cms; CMS_DigestedData *dd; - cms = CMS_ContentInfo_new(); + + cms = CMS_ContentInfo_new_ex(libctx, propq); if (cms == NULL) return NULL; @@ -45,14 +48,16 @@ CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md) return NULL; } -BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms) +BIO *ossl_cms_DigestedData_init_bio(const CMS_ContentInfo *cms) { - CMS_DigestedData *dd; - dd = cms->d.digestedData; - return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm); + CMS_DigestedData *dd = cms->d.digestedData; + + return ossl_cms_DigestAlgorithm_init_bio(dd->digestAlgorithm, + ossl_cms_get0_cmsctx(cms)); } -int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify) +int ossl_cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, + int verify) { EVP_MD_CTX *mctx = EVP_MD_CTX_new(); unsigned char md[EVP_MAX_MD_SIZE]; @@ -61,13 +66,13 @@ int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify) CMS_DigestedData *dd; if (mctx == NULL) { - CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } dd = cms->d.digestedData; - if (!cms_DigestAlgorithm_find_ctx(mctx, chain, dd->digestAlgorithm)) + if (!ossl_cms_DigestAlgorithm_find_ctx(mctx, chain, dd->digestAlgorithm)) goto err; if (EVP_DigestFinal_ex(mctx, md, &mdlen) <= 0) @@ -75,14 +80,12 @@ int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify) if (verify) { if (mdlen != (unsigned int)dd->digest->length) { - CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, - CMS_R_MESSAGEDIGEST_WRONG_LENGTH); + ERR_raise(ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_WRONG_LENGTH); goto err; } if (memcmp(md, dd->digest->data, mdlen)) - CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, - CMS_R_VERIFICATION_FAILURE); + ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE); else r = 1; } else { diff --git a/crypto/openssl/crypto/cms/cms_dh.c b/crypto/openssl/crypto/cms/cms_dh.c new file mode 100644 index 000000000000..7cc36f835f21 --- /dev/null +++ b/crypto/openssl/crypto/cms/cms_dh.c @@ -0,0 +1,343 @@ +/* + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include "internal/sizes.h" +#include "crypto/evp.h" +#include "cms_local.h" + +static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, + X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) +{ + const ASN1_OBJECT *aoid; + int atype; + const void *aval; + ASN1_INTEGER *public_key = NULL; + int rv = 0; + EVP_PKEY *pkpeer = NULL, *pk = NULL; + BIGNUM *bnpub = NULL; + const unsigned char *p; + unsigned char *buf = NULL; + int plen; + + X509_ALGOR_get0(&aoid, &atype, &aval, alg); + if (OBJ_obj2nid(aoid) != NID_dhpublicnumber) + goto err; + /* Only absent parameters allowed in RFC XXXX */ + if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL) + goto err; + + pk = EVP_PKEY_CTX_get0_pkey(pctx); + if (pk == NULL || !EVP_PKEY_is_a(pk, "DHX")) + goto err; + + /* Get public key */ + plen = ASN1_STRING_length(pubkey); + p = ASN1_STRING_get0_data(pubkey); + if (p == NULL || plen == 0) + goto err; + + if ((public_key = d2i_ASN1_INTEGER(NULL, &p, plen)) == NULL) + goto err; + /* + * Pad to full p parameter size as that is checked by + * EVP_PKEY_set1_encoded_public_key() + */ + plen = EVP_PKEY_get_size(pk); + if ((bnpub = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) + goto err; + if ((buf = OPENSSL_malloc(plen)) == NULL) + goto err; + if (BN_bn2binpad(bnpub, buf, plen) < 0) + goto err; + + pkpeer = EVP_PKEY_new(); + if (pkpeer == NULL + || !EVP_PKEY_copy_parameters(pkpeer, pk) + || !EVP_PKEY_set1_encoded_public_key(pkpeer, buf, plen)) + goto err; + + if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) + rv = 1; + err: + ASN1_INTEGER_free(public_key); + BN_free(bnpub); + OPENSSL_free(buf); + EVP_PKEY_free(pkpeer); + return rv; +} + +static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) +{ + int rv = 0; + X509_ALGOR *alg, *kekalg = NULL; + ASN1_OCTET_STRING *ukm; + const unsigned char *p; + unsigned char *dukm = NULL; + size_t dukmlen = 0; + int keylen, plen; + EVP_CIPHER *kekcipher = NULL; + EVP_CIPHER_CTX *kekctx; + char name[OSSL_MAX_NAME_SIZE]; + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) + goto err; + + /* + * For DH we only have one OID permissible. If ever any more get defined + * we will need something cleverer. + */ + if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) { + ERR_raise(ERR_LIB_CMS, CMS_R_KDF_PARAMETER_ERROR); + goto err; + } + + if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0 + || EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) + goto err; + + if (alg->parameter->type != V_ASN1_SEQUENCE) + goto err; + + p = alg->parameter->value.sequence->data; + plen = alg->parameter->value.sequence->length; + kekalg = d2i_X509_ALGOR(NULL, &p, plen); + if (kekalg == NULL) + goto err; + kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); + if (kekctx == NULL) + goto err; + + if (OBJ_obj2txt(name, sizeof(name), kekalg->algorithm, 0) <= 0) + goto err; + + kekcipher = EVP_CIPHER_fetch(pctx->libctx, name, pctx->propquery); + if (kekcipher == NULL + || EVP_CIPHER_get_mode(kekcipher) != EVP_CIPH_WRAP_MODE) + goto err; + if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) + goto err; + if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) + goto err; + + keylen = EVP_CIPHER_CTX_get_key_length(kekctx); + if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) + goto err; + /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */ + if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, + OBJ_nid2obj(EVP_CIPHER_get_type(kekcipher))) + <= 0) + goto err; + + if (ukm != NULL) { + dukmlen = ASN1_STRING_length(ukm); + dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); + if (dukm == NULL) + goto err; + } + + if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) + goto err; + dukm = NULL; + + rv = 1; + err: + X509_ALGOR_free(kekalg); + EVP_CIPHER_free(kekcipher); + OPENSSL_free(dukm); + return rv; +} + +static int dh_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + + if (pctx == NULL) + return 0; + /* See if we need to set peer key */ + if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { + X509_ALGOR *alg; + ASN1_BIT_STRING *pubkey; + + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, + NULL, NULL, NULL)) + return 0; + if (alg == NULL || pubkey == NULL) + return 0; + if (!dh_cms_set_peerkey(pctx, alg, pubkey)) { + ERR_raise(ERR_LIB_CMS, CMS_R_PEER_KEY_ERROR); + return 0; + } + } + /* Set DH derivation parameters and initialise unwrap context */ + if (!dh_cms_set_shared_info(pctx, ri)) { + ERR_raise(ERR_LIB_CMS, CMS_R_SHARED_INFO_ERROR); + return 0; + } + return 1; +} + +static int dh_cms_encrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + EVP_CIPHER_CTX *ctx; + int keylen; + X509_ALGOR *talg, *wrap_alg = NULL; + const ASN1_OBJECT *aoid; + ASN1_BIT_STRING *pubkey; + ASN1_STRING *wrap_str; + ASN1_OCTET_STRING *ukm; + unsigned char *penc = NULL, *dukm = NULL; + int penclen; + size_t dukmlen = 0; + int rv = 0; + int kdf_type, wrap_nid; + const EVP_MD *kdf_md; + + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (pctx == NULL) + return 0; + /* Get ephemeral key */ + pkey = EVP_PKEY_CTX_get0_pkey(pctx); + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, + NULL, NULL, NULL)) + goto err; + + /* Is everything uninitialised? */ + X509_ALGOR_get0(&aoid, NULL, NULL, talg); + if (aoid == OBJ_nid2obj(NID_undef)) { + BIGNUM *bn_pub_key = NULL; + ASN1_INTEGER *pubk; + + if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &bn_pub_key)) + goto err; + + pubk = BN_to_ASN1_INTEGER(bn_pub_key, NULL); + BN_free(bn_pub_key); + if (pubk == NULL) + goto err; + + /* Set the key */ + penclen = i2d_ASN1_INTEGER(pubk, &penc); + ASN1_INTEGER_free(pubk); + if (penclen <= 0) + goto err; + ASN1_STRING_set0(pubkey, penc, penclen); + pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; + + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), + V_ASN1_UNDEF, NULL); + } + + /* See if custom parameters set */ + kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx); + if (kdf_type <= 0 || EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md) <= 0) + goto err; + + if (kdf_type == EVP_PKEY_DH_KDF_NONE) { + kdf_type = EVP_PKEY_DH_KDF_X9_42; + if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0) + goto err; + } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42) + /* Unknown KDF */ + goto err; + if (kdf_md == NULL) { + /* Only SHA1 supported */ + kdf_md = EVP_sha1(); + if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0) + goto err; + } else if (EVP_MD_get_type(kdf_md) != NID_sha1) + /* Unsupported digest */ + goto err; + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) + goto err; + + /* Get wrap NID */ + ctx = CMS_RecipientInfo_kari_get0_ctx(ri); + wrap_nid = EVP_CIPHER_CTX_get_type(ctx); + if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0) + goto err; + keylen = EVP_CIPHER_CTX_get_key_length(ctx); + + /* Package wrap algorithm in an AlgorithmIdentifier */ + + wrap_alg = X509_ALGOR_new(); + if (wrap_alg == NULL) + goto err; + wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); + wrap_alg->parameter = ASN1_TYPE_new(); + if (wrap_alg->parameter == NULL) + goto err; + if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) + goto err; + if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { + ASN1_TYPE_free(wrap_alg->parameter); + wrap_alg->parameter = NULL; + } + + if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) + goto err; + + if (ukm != NULL) { + dukmlen = ASN1_STRING_length(ukm); + dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); + if (dukm == NULL) + goto err; + } + + if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) + goto err; + dukm = NULL; + + /* + * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter + * of another AlgorithmIdentifier. + */ + penc = NULL; + penclen = i2d_X509_ALGOR(wrap_alg, &penc); + if (penc == NULL || penclen == 0) + goto err; + wrap_str = ASN1_STRING_new(); + if (wrap_str == NULL) + goto err; + ASN1_STRING_set0(wrap_str, penc, penclen); + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), + V_ASN1_SEQUENCE, wrap_str); + + rv = 1; + + err: + OPENSSL_free(penc); + X509_ALGOR_free(wrap_alg); + OPENSSL_free(dukm); + return rv; +} + +int ossl_cms_dh_envelope(CMS_RecipientInfo *ri, int decrypt) +{ + assert(decrypt == 0 || decrypt == 1); + + if (decrypt == 1) + return dh_cms_decrypt(ri); + + if (decrypt == 0) + return dh_cms_encrypt(ri); + + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; +} diff --git a/crypto/openssl/crypto/cms/cms_ec.c b/crypto/openssl/crypto/cms/cms_ec.c new file mode 100644 index 000000000000..8ecf730aa7b0 --- /dev/null +++ b/crypto/openssl/crypto/cms/cms_ec.c @@ -0,0 +1,413 @@ +/* + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/sizes.h" +#include "crypto/evp.h" +#include "cms_local.h" + +static EVP_PKEY *pkey_type2param(int ptype, const void *pval, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pctx = NULL; + OSSL_DECODER_CTX *ctx = NULL; + + if (ptype == V_ASN1_SEQUENCE) { + const ASN1_STRING *pstr = pval; + const unsigned char *pm = pstr->data; + size_t pmlen = (size_t)pstr->length; + int selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS; + + ctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", NULL, "EC", + selection, libctx, propq); + if (ctx == NULL) + goto err; + + if (!OSSL_DECODER_from_data(ctx, &pm, &pmlen)) { + ERR_raise(ERR_LIB_CMS, CMS_R_DECODE_ERROR); + goto err; + } + OSSL_DECODER_CTX_free(ctx); + return pkey; + } else if (ptype == V_ASN1_OBJECT) { + const ASN1_OBJECT *poid = pval; + char groupname[OSSL_MAX_NAME_SIZE]; + + /* type == V_ASN1_OBJECT => the parameters are given by an asn1 OID */ + pctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", propq); + if (pctx == NULL || EVP_PKEY_paramgen_init(pctx) <= 0) + goto err; + if (OBJ_obj2txt(groupname, sizeof(groupname), poid, 0) <= 0 + || EVP_PKEY_CTX_set_group_name(pctx, groupname) <= 0) { + ERR_raise(ERR_LIB_CMS, CMS_R_DECODE_ERROR); + goto err; + } + if (EVP_PKEY_paramgen(pctx, &pkey) <= 0) + goto err; + EVP_PKEY_CTX_free(pctx); + return pkey; + } + + ERR_raise(ERR_LIB_CMS, CMS_R_DECODE_ERROR); + return NULL; + + err: + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(pctx); + OSSL_DECODER_CTX_free(ctx); + return NULL; +} + +static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, + X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) +{ + const ASN1_OBJECT *aoid; + int atype; + const void *aval; + int rv = 0; + EVP_PKEY *pkpeer = NULL; + const unsigned char *p; + int plen; + + X509_ALGOR_get0(&aoid, &atype, &aval, alg); + if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) + goto err; + + /* If absent parameters get group from main key */ + if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) { + EVP_PKEY *pk; + + pk = EVP_PKEY_CTX_get0_pkey(pctx); + if (pk == NULL) + goto err; + + pkpeer = EVP_PKEY_new(); + if (pkpeer == NULL) + goto err; + if (!EVP_PKEY_copy_parameters(pkpeer, pk)) + goto err; + } else { + pkpeer = pkey_type2param(atype, aval, + EVP_PKEY_CTX_get0_libctx(pctx), + EVP_PKEY_CTX_get0_propq(pctx)); + if (pkpeer == NULL) + goto err; + } + /* We have parameters now set public key */ + plen = ASN1_STRING_length(pubkey); + p = ASN1_STRING_get0_data(pubkey); + if (p == NULL || plen == 0) + goto err; + + if (!EVP_PKEY_set1_encoded_public_key(pkpeer, p, plen)) + goto err; + + if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) + rv = 1; + err: + EVP_PKEY_free(pkpeer); + return rv; +} + +/* Set KDF parameters based on KDF NID */ +static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid) +{ + int kdf_nid, kdfmd_nid, cofactor; + const EVP_MD *kdf_md; + + if (eckdf_nid == NID_undef) + return 0; + + /* Lookup KDF type, cofactor mode and digest */ + if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid)) + return 0; + + if (kdf_nid == NID_dh_std_kdf) + cofactor = 0; + else if (kdf_nid == NID_dh_cofactor_kdf) + cofactor = 1; + else + return 0; + + if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0) + return 0; + + if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0) + return 0; + + kdf_md = EVP_get_digestbynid(kdfmd_nid); + if (!kdf_md) + return 0; + + if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) + return 0; + return 1; +} + +static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) +{ + int rv = 0; + X509_ALGOR *alg, *kekalg = NULL; + ASN1_OCTET_STRING *ukm; + const unsigned char *p; + unsigned char *der = NULL; + int plen, keylen; + EVP_CIPHER *kekcipher = NULL; + EVP_CIPHER_CTX *kekctx; + char name[OSSL_MAX_NAME_SIZE]; + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) + return 0; + + if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) { + ERR_raise(ERR_LIB_CMS, CMS_R_KDF_PARAMETER_ERROR); + return 0; + } + + if (alg->parameter->type != V_ASN1_SEQUENCE) + return 0; + + p = alg->parameter->value.sequence->data; + plen = alg->parameter->value.sequence->length; + kekalg = d2i_X509_ALGOR(NULL, &p, plen); + if (kekalg == NULL) + goto err; + kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); + if (kekctx == NULL) + goto err; + OBJ_obj2txt(name, sizeof(name), kekalg->algorithm, 0); + kekcipher = EVP_CIPHER_fetch(pctx->libctx, name, pctx->propquery); + if (kekcipher == NULL || EVP_CIPHER_get_mode(kekcipher) != EVP_CIPH_WRAP_MODE) + goto err; + if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) + goto err; + if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) + goto err; + + keylen = EVP_CIPHER_CTX_get_key_length(kekctx); + if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) + goto err; + + plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen); + + if (plen <= 0) + goto err; + + if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0) + goto err; + der = NULL; + + rv = 1; + err: + EVP_CIPHER_free(kekcipher); + X509_ALGOR_free(kekalg); + OPENSSL_free(der); + return rv; +} + +static int ecdh_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (pctx == NULL) + return 0; + /* See if we need to set peer key */ + if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { + X509_ALGOR *alg; + ASN1_BIT_STRING *pubkey; + + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, + NULL, NULL, NULL)) + return 0; + if (alg == NULL || pubkey == NULL) + return 0; + if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) { + ERR_raise(ERR_LIB_CMS, CMS_R_PEER_KEY_ERROR); + return 0; + } + } + /* Set ECDH derivation parameters and initialise unwrap context */ + if (!ecdh_cms_set_shared_info(pctx, ri)) { + ERR_raise(ERR_LIB_CMS, CMS_R_SHARED_INFO_ERROR); + return 0; + } + return 1; +} + +static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + EVP_CIPHER_CTX *ctx; + int keylen; + X509_ALGOR *talg, *wrap_alg = NULL; + const ASN1_OBJECT *aoid; + ASN1_BIT_STRING *pubkey; + ASN1_STRING *wrap_str; + ASN1_OCTET_STRING *ukm; + unsigned char *penc = NULL; + size_t penclen; + int rv = 0; + int ecdh_nid, kdf_type, kdf_nid, wrap_nid; + const EVP_MD *kdf_md; + + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (pctx == NULL) + return 0; + /* Get ephemeral key */ + pkey = EVP_PKEY_CTX_get0_pkey(pctx); + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, + NULL, NULL, NULL)) + goto err; + X509_ALGOR_get0(&aoid, NULL, NULL, talg); + /* Is everything uninitialised? */ + if (aoid == OBJ_nid2obj(NID_undef)) { + /* Set the key */ + + penclen = EVP_PKEY_get1_encoded_public_key(pkey, &penc); + ASN1_STRING_set0(pubkey, penc, penclen); + pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; + + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), + V_ASN1_UNDEF, NULL); + } + + /* See if custom parameters set */ + kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx); + if (kdf_type <= 0) + goto err; + if (EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md) <= 0) + goto err; + ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx); + if (ecdh_nid < 0) + goto err; + else if (ecdh_nid == 0) + ecdh_nid = NID_dh_std_kdf; + else if (ecdh_nid == 1) + ecdh_nid = NID_dh_cofactor_kdf; + + if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) { + kdf_type = EVP_PKEY_ECDH_KDF_X9_63; + if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0) + goto err; + } else + /* Unknown KDF */ + goto err; + if (kdf_md == NULL) { + /* Fixme later for better MD */ + kdf_md = EVP_sha1(); + if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) + goto err; + } + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) + goto err; + + /* Lookup NID for KDF+cofactor+digest */ + + if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_get_type(kdf_md), ecdh_nid)) + goto err; + /* Get wrap NID */ + ctx = CMS_RecipientInfo_kari_get0_ctx(ri); + wrap_nid = EVP_CIPHER_CTX_get_type(ctx); + keylen = EVP_CIPHER_CTX_get_key_length(ctx); + + /* Package wrap algorithm in an AlgorithmIdentifier */ + + wrap_alg = X509_ALGOR_new(); + if (wrap_alg == NULL) + goto err; + wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); + wrap_alg->parameter = ASN1_TYPE_new(); + if (wrap_alg->parameter == NULL) + goto err; + if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) + goto err; + if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { + ASN1_TYPE_free(wrap_alg->parameter); + wrap_alg->parameter = NULL; + } + + if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) + goto err; + + penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen); + + if (penclen == 0) + goto err; + + if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0) + goto err; + penc = NULL; + + /* + * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter + * of another AlgorithmIdentifier. + */ + penclen = i2d_X509_ALGOR(wrap_alg, &penc); + if (penc == NULL || penclen == 0) + goto err; + wrap_str = ASN1_STRING_new(); + if (wrap_str == NULL) + goto err; + ASN1_STRING_set0(wrap_str, penc, penclen); + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str); + + rv = 1; + + err: + OPENSSL_free(penc); + X509_ALGOR_free(wrap_alg); + return rv; +} + +int ossl_cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt) +{ + assert(decrypt == 0 || decrypt == 1); + + if (decrypt == 1) + return ecdh_cms_decrypt(ri); + + if (decrypt == 0) + return ecdh_cms_encrypt(ri); + + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; +} + +/* ECDSA and DSA implementation is the same */ +int ossl_cms_ecdsa_dsa_sign(CMS_SignerInfo *si, int verify) +{ + assert(verify == 0 || verify == 1); + + if (verify == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + EVP_PKEY *pkey = si->pkey; + + CMS_SignerInfo_get0_algs(si, NULL, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_get_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +} diff --git a/crypto/openssl/crypto/cms/cms_enc.c b/crypto/openssl/crypto/cms/cms_enc.c index 6f077b339a87..f7007c12319e 100644 --- a/crypto/openssl/crypto/cms/cms_enc.c +++ b/crypto/openssl/crypto/cms/cms_enc.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,84 +14,114 @@ #include #include #include +#include "crypto/evp.h" #include "cms_local.h" /* CMS EncryptedData Utilities */ /* Return BIO based on EncryptedContentInfo and key */ -BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) +BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, + const CMS_CTX *cms_ctx) { BIO *b; EVP_CIPHER_CTX *ctx; - const EVP_CIPHER *ciph; + EVP_CIPHER *fetched_ciph = NULL; + const EVP_CIPHER *cipher = NULL; X509_ALGOR *calg = ec->contentEncryptionAlgorithm; + evp_cipher_aead_asn1_params aparams; unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; unsigned char *tkey = NULL; + int len; + int ivlen = 0; size_t tkeylen = 0; - int ok = 0; - int enc, keep_key = 0; + OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(cms_ctx); + const char *propq = ossl_cms_ctx_get0_propq(cms_ctx); enc = ec->cipher ? 1 : 0; b = BIO_new(BIO_f_cipher()); if (b == NULL) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return NULL; } BIO_get_cipher_ctx(b, &ctx); + (void)ERR_set_mark(); if (enc) { - ciph = ec->cipher; + cipher = ec->cipher; /* * If not keeping key set cipher to NULL so subsequent calls decrypt. */ - if (ec->key) + if (ec->key != NULL) ec->cipher = NULL; } else { - ciph = EVP_get_cipherbyobj(calg->algorithm); - - if (!ciph) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); - goto err; - } + cipher = EVP_get_cipherbyobj(calg->algorithm); + } + if (cipher != NULL) { + fetched_ciph = EVP_CIPHER_fetch(libctx, EVP_CIPHER_get0_name(cipher), + propq); + if (fetched_ciph != NULL) + cipher = fetched_ciph; } + if (cipher == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER); + goto err; + } + (void)ERR_pop_to_mark(); - if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_CIPHER_INITIALISATION_ERROR); + if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc) <= 0) { + ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } if (enc) { - int ivlen; - - calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); + calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_get_type(ctx)); if (calg->algorithm == NULL) { - CMSerr(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM); goto err; } /* Generate a random IV if we need one */ - ivlen = EVP_CIPHER_CTX_iv_length(ctx); + ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); + if (ivlen < 0) { + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); + goto err; + } + if (ivlen > 0) { - if (RAND_bytes(iv, ivlen) <= 0) + if (RAND_bytes_ex(libctx, iv, ivlen, 0) <= 0) goto err; piv = iv; } - } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); - goto err; + } else { + if (evp_cipher_asn1_to_param_ex(ctx, calg->parameter, &aparams) <= 0) { + ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { + piv = aparams.iv; + if (ec->taglen > 0 + && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + ec->taglen, ec->tag) <= 0) { + ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_AEAD_SET_TAG_ERROR); + goto err; + } + } } - tkeylen = EVP_CIPHER_CTX_key_length(ctx); + len = EVP_CIPHER_CTX_get_key_length(ctx); + if (len <= 0) + goto err; + tkeylen = (size_t)len; + /* Generate random session key */ if (!enc || !ec->key) { tkey = OPENSSL_malloc(tkeylen); if (tkey == NULL) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) @@ -117,8 +147,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) * which may be useful in MMA. */ if (enc || ec->debug) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_INVALID_KEY_LENGTH); + ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); goto err; } else { /* Use random key */ @@ -132,19 +161,25 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) } if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_CIPHER_INITIALISATION_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } if (enc) { calg->parameter = ASN1_TYPE_new(); if (calg->parameter == NULL) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } - if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { + memcpy(aparams.iv, piv, ivlen); + aparams.iv_len = ivlen; + aparams.tag_len = EVP_CIPHER_CTX_get_tag_length(ctx); + if (aparams.tag_len <= 0) + goto err; + } + + if (evp_cipher_param_to_asn1_ex(ctx, calg->parameter, &aparams) <= 0) { + ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } /* If parameter type not set omit parameter */ @@ -156,6 +191,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) ok = 1; err: + EVP_CIPHER_free(fetched_ciph); if (!keep_key || !ok) { OPENSSL_clear_free(ec->key, ec->keylen); ec->key = NULL; @@ -167,20 +203,21 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) return NULL; } -int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, - const EVP_CIPHER *cipher, - const unsigned char *key, size_t keylen) +int ossl_cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, + const EVP_CIPHER *cipher, + const unsigned char *key, size_t keylen, + const CMS_CTX *cms_ctx) { ec->cipher = cipher; if (key) { if ((ec->key = OPENSSL_malloc(keylen)) == NULL) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return 0; } memcpy(ec->key, key, keylen); } ec->keylen = keylen; - if (cipher) + if (cipher != NULL) ec->contentType = OBJ_nid2obj(NID_pkcs7_data); return 1; } @@ -189,30 +226,33 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, const unsigned char *key, size_t keylen) { CMS_EncryptedContentInfo *ec; + if (!key || !keylen) { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_KEY); return 0; } if (ciph) { cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData); if (!cms->d.encryptedData) { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return 0; } cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted); cms->d.encryptedData->version = 0; } else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NOT_ENCRYPTED_DATA); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_ENCRYPTED_DATA); return 0; } ec = cms->d.encryptedData->encryptedContentInfo; - return cms_EncryptedContent_init(ec, ciph, key, keylen); + return ossl_cms_EncryptedContent_init(ec, ciph, key, keylen, + ossl_cms_get0_cmsctx(cms)); } -BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms) +BIO *ossl_cms_EncryptedData_init_bio(const CMS_ContentInfo *cms) { CMS_EncryptedData *enc = cms->d.encryptedData; if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) enc->version = 2; - return cms_EncryptedContent_init_bio(enc->encryptedContentInfo); + return ossl_cms_EncryptedContent_init_bio(enc->encryptedContentInfo, + ossl_cms_get0_cmsctx(cms)); } diff --git a/crypto/openssl/crypto/cms/cms_env.c b/crypto/openssl/crypto/cms/cms_env.c index 962a0137542a..51a1d7df848c 100644 --- a/crypto/openssl/crypto/cms/cms_env.c +++ b/crypto/openssl/crypto/cms/cms_env.c @@ -1,7 +1,7 @@ /* * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,29 +13,60 @@ #include #include #include -#include -#include "cms_local.h" +#include +#include "internal/sizes.h" #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/x509.h" +#include "cms_local.h" /* CMS EnvelopedData Utilities */ +static void cms_env_set_version(CMS_EnvelopedData *env); + +#define CMS_ENVELOPED_STANDARD 1 +#define CMS_ENVELOPED_AUTH 2 + +static int cms_get_enveloped_type(const CMS_ContentInfo *cms) +{ + int nid = OBJ_obj2nid(cms->contentType); + + switch (nid) { + case NID_pkcs7_enveloped: + return CMS_ENVELOPED_STANDARD; + + case NID_id_smime_ct_authEnvelopedData: + return CMS_ENVELOPED_AUTH; -CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) + default: + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); + return 0; + } +} + +CMS_EnvelopedData *ossl_cms_get0_enveloped(CMS_ContentInfo *cms) { if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { - CMSerr(CMS_F_CMS_GET0_ENVELOPED, - CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); return NULL; } return cms->d.envelopedData; } +CMS_AuthEnvelopedData *ossl_cms_get0_auth_enveloped(CMS_ContentInfo *cms) +{ + if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_authEnvelopedData) { + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); + return NULL; + } + return cms->d.authEnvelopedData; +} + static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) { if (cms->d.other == NULL) { cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); - if (!cms->d.envelopedData) { - CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE); + if (cms->d.envelopedData == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return NULL; } cms->d.envelopedData->version = 0; @@ -45,10 +76,30 @@ static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); return cms->d.envelopedData; } - return cms_get0_enveloped(cms); + return ossl_cms_get0_enveloped(cms); } -int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) +static CMS_AuthEnvelopedData * +cms_auth_enveloped_data_init(CMS_ContentInfo *cms) +{ + if (cms->d.other == NULL) { + cms->d.authEnvelopedData = M_ASN1_new_of(CMS_AuthEnvelopedData); + if (cms->d.authEnvelopedData == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + return NULL; + } + /* Defined in RFC 5083 - Section 2.1. "AuthEnvelopedData Type" */ + cms->d.authEnvelopedData->version = 0; + cms->d.authEnvelopedData->authEncryptedContentInfo->contentType = + OBJ_nid2obj(NID_pkcs7_data); + ASN1_OBJECT_free(cms->contentType); + cms->contentType = OBJ_nid2obj(NID_id_smime_ct_authEnvelopedData); + return cms->d.authEnvelopedData; + } + return ossl_cms_get0_auth_enveloped(cms); +} + +int ossl_cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) { EVP_PKEY *pkey; int i; @@ -56,35 +107,96 @@ int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) pkey = ri->d.ktri->pkey; else if (ri->type == CMS_RECIPINFO_AGREE) { EVP_PKEY_CTX *pctx = ri->d.kari->pctx; - if (!pctx) + + if (pctx == NULL) return 0; pkey = EVP_PKEY_CTX_get0_pkey(pctx); - if (!pkey) + if (pkey == NULL) return 0; } else return 0; - if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + + if (EVP_PKEY_is_a(pkey, "DHX") || EVP_PKEY_is_a(pkey, "DH")) + return ossl_cms_dh_envelope(ri, cmd); + else if (EVP_PKEY_is_a(pkey, "EC")) + return ossl_cms_ecdh_envelope(ri, cmd); + else if (EVP_PKEY_is_a(pkey, "RSA")) + return ossl_cms_rsa_envelope(ri, cmd); + + /* Something else? We'll give engines etc a chance to handle this */ + if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) return 1; i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri); if (i == -2) { - CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); return 0; } if (i <= 0) { - CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE); + ERR_raise(ERR_LIB_CMS, CMS_R_CTRL_FAILURE); return 0; } return 1; } +CMS_EncryptedContentInfo* ossl_cms_get0_env_enc_content(const CMS_ContentInfo *cms) +{ + switch (cms_get_enveloped_type(cms)) { + case CMS_ENVELOPED_STANDARD: + return cms->d.envelopedData->encryptedContentInfo; + + case CMS_ENVELOPED_AUTH: + return cms->d.authEnvelopedData->authEncryptedContentInfo; + + default: + return NULL; + } +} + STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms) { - CMS_EnvelopedData *env; - env = cms_get0_enveloped(cms); - if (!env) + switch (cms_get_enveloped_type(cms)) { + case CMS_ENVELOPED_STANDARD: + return cms->d.envelopedData->recipientInfos; + + case CMS_ENVELOPED_AUTH: + return cms->d.authEnvelopedData->recipientInfos; + + default: return NULL; - return env->recipientInfos; + } +} + +void ossl_cms_RecipientInfos_set_cmsctx(CMS_ContentInfo *cms) +{ + int i; + CMS_RecipientInfo *ri; + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); + STACK_OF(CMS_RecipientInfo) *rinfos = CMS_get0_RecipientInfos(cms); + + for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { + ri = sk_CMS_RecipientInfo_value(rinfos, i); + if (ri != NULL) { + switch (ri->type) { + case CMS_RECIPINFO_AGREE: + ri->d.kari->cms_ctx = ctx; + break; + case CMS_RECIPINFO_TRANS: + ri->d.ktri->cms_ctx = ctx; + ossl_x509_set0_libctx(ri->d.ktri->recip, + ossl_cms_ctx_get0_libctx(ctx), + ossl_cms_ctx_get0_propq(ctx)); + break; + case CMS_RECIPINFO_KEK: + ri->d.kekri->cms_ctx = ctx; + break; + case CMS_RECIPINFO_PASS: + ri->d.pwri->cms_ctx = ctx; + break; + default: + break; + } + } + } } int CMS_RecipientInfo_type(CMS_RecipientInfo *ri) @@ -101,32 +213,72 @@ EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri) return NULL; } -CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) +CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher, + OSSL_LIB_CTX *libctx, + const char *propq) { CMS_ContentInfo *cms; CMS_EnvelopedData *env; - cms = CMS_ContentInfo_new(); + + cms = CMS_ContentInfo_new_ex(libctx, propq); if (cms == NULL) goto merr; env = cms_enveloped_data_init(cms); if (env == NULL) goto merr; - if (!cms_EncryptedContent_init(env->encryptedContentInfo, - cipher, NULL, 0)) + + if (!ossl_cms_EncryptedContent_init(env->encryptedContentInfo, cipher, NULL, + 0, ossl_cms_get0_cmsctx(cms))) + goto merr; + return cms; + merr: + CMS_ContentInfo_free(cms); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + return NULL; +} + +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) +{ + return CMS_EnvelopedData_create_ex(cipher, NULL, NULL); +} + +CMS_ContentInfo * +CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx, + const char *propq) +{ + CMS_ContentInfo *cms; + CMS_AuthEnvelopedData *aenv; + + cms = CMS_ContentInfo_new_ex(libctx, propq); + if (cms == NULL) + goto merr; + aenv = cms_auth_enveloped_data_init(cms); + if (aenv == NULL) + goto merr; + if (!ossl_cms_EncryptedContent_init(aenv->authEncryptedContentInfo, + cipher, NULL, 0, + ossl_cms_get0_cmsctx(cms))) goto merr; return cms; merr: CMS_ContentInfo_free(cms); - CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return NULL; } + +CMS_ContentInfo *CMS_AuthEnvelopedData_create(const EVP_CIPHER *cipher) +{ + return CMS_AuthEnvelopedData_create_ex(cipher, NULL, NULL); +} + /* Key Transport Recipient Info (KTRI) routines */ /* Initialise a ktri based on passed certificate and key */ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, - EVP_PKEY *pk, unsigned int flags) + EVP_PKEY *pk, unsigned int flags, + const CMS_CTX *ctx) { CMS_KeyTransRecipientInfo *ktri; int idtype; @@ -137,6 +289,7 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, ri->type = CMS_RECIPINFO_TRANS; ktri = ri->d.ktri; + ktri->cms_ctx = ctx; if (flags & CMS_USE_KEYID) { ktri->version = 2; @@ -151,7 +304,7 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, * structure. */ - if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype)) + if (!ossl_cms_set1_SignerIdentifier(ktri->rid, recip, idtype, ctx)) return 0; X509_up_ref(recip); @@ -161,12 +314,14 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, ktri->recip = recip; if (flags & CMS_KEY_PARAM) { - ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + ktri->pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx), + ktri->pkey, + ossl_cms_ctx_get0_propq(ctx)); if (ktri->pctx == NULL) return 0; if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0) return 0; - } else if (!cms_env_asn1_ctrl(ri, 0)) + } else if (!ossl_cms_env_asn1_ctrl(ri, 0)) return 0; return 1; } @@ -175,67 +330,75 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, * Add a recipient certificate using appropriate type of RecipientInfo */ -CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, - X509 *recip, unsigned int flags) +CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, + EVP_PKEY *originatorPrivKey, + X509 *originator, unsigned int flags) { CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; + STACK_OF(CMS_RecipientInfo) *ris; EVP_PKEY *pk = NULL; - env = cms_get0_enveloped(cms); - if (!env) + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); + + ris = CMS_get0_RecipientInfos(cms); + if (ris == NULL) goto err; /* Initialize recipient info */ ri = M_ASN1_new_of(CMS_RecipientInfo); - if (!ri) + if (ri == NULL) goto merr; pk = X509_get0_pubkey(recip); - if (!pk) { - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY); + if (pk == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_GETTING_PUBLIC_KEY); goto err; } - switch (cms_pkey_get_ri_type(pk)) { + switch (ossl_cms_pkey_get_ri_type(pk)) { case CMS_RECIPINFO_TRANS: - if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags)) + if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags, ctx)) goto err; break; case CMS_RECIPINFO_AGREE: - if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags)) + if (!ossl_cms_RecipientInfo_kari_init(ri, recip, pk, originator, + originatorPrivKey, flags, ctx)) goto err; break; default: - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); goto err; } - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + if (!sk_CMS_RecipientInfo_push(ris, ri)) goto merr; return ri; merr: - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: M_ASN1_free_of(ri, CMS_RecipientInfo); return NULL; } +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, + unsigned int flags) +{ + return CMS_add1_recipient(cms, recip, NULL, NULL, flags); +} + int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, EVP_PKEY **pk, X509 **recip, X509_ALGOR **palg) { CMS_KeyTransRecipientInfo *ktri; if (ri->type != CMS_RECIPINFO_TRANS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS, - CMS_R_NOT_KEY_TRANSPORT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT); return 0; } @@ -257,29 +420,28 @@ int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, { CMS_KeyTransRecipientInfo *ktri; if (ri->type != CMS_RECIPINFO_TRANS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID, - CMS_R_NOT_KEY_TRANSPORT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT); return 0; } ktri = ri->d.ktri; - return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno); + return ossl_cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, + sno); } int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert) { if (ri->type != CMS_RECIPINFO_TRANS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP, - CMS_R_NOT_KEY_TRANSPORT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT); return -2; } - return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); + return ossl_cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); } int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) { if (ri->type != CMS_RECIPINFO_TRANS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT); return 0; } EVP_PKEY_free(ri->d.ktri->pkey); @@ -289,7 +451,7 @@ int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) /* Encrypt content key in key transport recipient info */ -static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, +static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri) { CMS_KeyTransRecipientInfo *ktri; @@ -297,23 +459,26 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, EVP_PKEY_CTX *pctx; unsigned char *ek = NULL; size_t eklen; + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); int ret = 0; if (ri->type != CMS_RECIPINFO_TRANS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT); return 0; } ktri = ri->d.ktri; - ec = cms->d.envelopedData->encryptedContentInfo; + ec = ossl_cms_get0_env_enc_content(cms); pctx = ktri->pctx; if (pctx) { - if (!cms_env_asn1_ctrl(ri, 0)) + if (!ossl_cms_env_asn1_ctrl(ri, 0)) goto err; } else { - pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx), + ktri->pkey, + ossl_cms_ctx_get0_propq(ctx)); if (pctx == NULL) return 0; @@ -321,19 +486,13 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, goto err; } - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, - EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); - goto err; - } - if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) goto err; ek = OPENSSL_malloc(eklen); if (ek == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } @@ -350,7 +509,6 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, ktri->pctx = NULL; OPENSSL_free(ek); return ret; - } /* Decrypt content key from KTRI */ @@ -364,42 +522,54 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, size_t eklen; int ret = 0; size_t fixlen = 0; + const EVP_CIPHER *cipher = NULL; + EVP_CIPHER *fetched_cipher = NULL; CMS_EncryptedContentInfo *ec; - ec = cms->d.envelopedData->encryptedContentInfo; + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); + OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx); + const char *propq = ossl_cms_ctx_get0_propq(ctx); + + ec = ossl_cms_get0_env_enc_content(cms); if (ktri->pkey == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_PRIVATE_KEY); 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); + char name[OSSL_MAX_NAME_SIZE]; + + OBJ_obj2txt(name, sizeof(name), calg->algorithm, 0); - if (ciph == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_UNKNOWN_CIPHER); + (void)ERR_set_mark(); + fetched_cipher = EVP_CIPHER_fetch(libctx, name, propq); + + if (fetched_cipher != NULL) + cipher = fetched_cipher; + else + cipher = EVP_get_cipherbyobj(calg->algorithm); + if (cipher == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER); return 0; } + (void)ERR_pop_to_mark(); - fixlen = EVP_CIPHER_key_length(ciph); + fixlen = EVP_CIPHER_get_key_length(cipher); + EVP_CIPHER_free(fetched_cipher); } - ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); + ktri->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); if (ktri->pctx == NULL) - return 0; - - if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) goto err; - if (!cms_env_asn1_ctrl(ri, 1)) + if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) goto err; - if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT, - EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); + if (!ossl_cms_env_asn1_ctrl(ri, 1)) goto err; - } if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen, ktri->encryptedKey->data, @@ -407,9 +577,8 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, goto err; ek = OPENSSL_malloc(eklen); - if (ek == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } @@ -418,7 +587,7 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, ktri->encryptedKey->length) <= 0 || eklen == 0 || (fixlen != 0 && eklen != fixlen)) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); + ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB); goto err; } @@ -445,7 +614,7 @@ int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, ASN1_OCTET_STRING tmp_os; CMS_KEKRecipientInfo *kekri; if (ri->type != CMS_RECIPINFO_KEK) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEK); return -2; } kekri = ri->d.kekri; @@ -483,10 +652,10 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, ASN1_TYPE *otherType) { CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; CMS_KEKRecipientInfo *kekri; - env = cms_get0_enveloped(cms); - if (!env) + STACK_OF(CMS_RecipientInfo) *ris = CMS_get0_RecipientInfos(cms); + + if (ris == NULL) goto err; if (nid == NID_undef) { @@ -504,7 +673,7 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, break; default: - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH); + ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); goto err; } @@ -513,13 +682,12 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, size_t exp_keylen = aes_wrap_keylen(nid); if (!exp_keylen) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, - CMS_R_UNSUPPORTED_KEK_ALGORITHM); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEK_ALGORITHM); goto err; } if (keylen != exp_keylen) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH); + ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); goto err; } @@ -543,7 +711,7 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, goto merr; } - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + if (!sk_CMS_RecipientInfo_push(ris, ri)) goto merr; /* After this point no calls can fail */ @@ -568,11 +736,10 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, return ri; merr: - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: M_ASN1_free_of(ri, CMS_RecipientInfo); return NULL; - } int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, @@ -584,7 +751,7 @@ int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, { CMS_KEKIdentifier *rkid; if (ri->type != CMS_RECIPINFO_KEK) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEK); return 0; } rkid = ri->d.kekri->kekid; @@ -614,7 +781,7 @@ int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, { CMS_KEKRecipientInfo *kekri; if (ri->type != CMS_RECIPINFO_KEK) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEK); return 0; } @@ -624,44 +791,83 @@ int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, return 1; } +static EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen, const CMS_CTX *ctx) +{ + const char *alg = NULL; + + switch(keylen) { + case 16: + alg = "AES-128-WRAP"; + break; + case 24: + alg = "AES-192-WRAP"; + break; + case 32: + alg = "AES-256-WRAP"; + break; + default: + return NULL; + } + return EVP_CIPHER_fetch(ossl_cms_ctx_get0_libctx(ctx), alg, + ossl_cms_ctx_get0_propq(ctx)); +} + + /* Encrypt content key in KEK recipient info */ -static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms, +static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri) { CMS_EncryptedContentInfo *ec; CMS_KEKRecipientInfo *kekri; - AES_KEY actx; unsigned char *wkey = NULL; int wkeylen; int r = 0; + EVP_CIPHER *cipher = NULL; + int outlen = 0; + EVP_CIPHER_CTX *ctx = NULL; + const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms); - ec = cms->d.envelopedData->encryptedContentInfo; + ec = ossl_cms_get0_env_enc_content(cms); + if (ec == NULL) + return 0; kekri = ri->d.kekri; - if (!kekri->key) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY); + if (kekri->key == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_NO_KEY); return 0; } - if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, - CMS_R_ERROR_SETTING_KEY); + cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx); + if (cipher == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); goto err; } + /* 8 byte prefix for AES wrap ciphers */ wkey = OPENSSL_malloc(ec->keylen + 8); - if (wkey == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } - wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + goto err; + } - if (wkeylen <= 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); + EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); + if (!EVP_EncryptInit_ex(ctx, cipher, NULL, kekri->key, NULL) + || !EVP_EncryptUpdate(ctx, wkey, &wkeylen, ec->key, ec->keylen) + || !EVP_EncryptFinal_ex(ctx, wkey + wkeylen, &outlen)) { + ERR_raise(ERR_LIB_CMS, CMS_R_WRAP_ERROR); + goto err; + } + wkeylen += outlen; + if (!ossl_assert((size_t)wkeylen == ec->keylen + 8)) { + ERR_raise(ERR_LIB_CMS, CMS_R_WRAP_ERROR); goto err; } @@ -670,13 +876,12 @@ static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms, r = 1; err: - + EVP_CIPHER_free(cipher); if (!r) OPENSSL_free(wkey); - OPENSSL_cleanse(&actx, sizeof(actx)); + EVP_CIPHER_CTX_free(ctx); return r; - } /* Decrypt content key in KEK recipient info */ @@ -686,56 +891,65 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, { CMS_EncryptedContentInfo *ec; CMS_KEKRecipientInfo *kekri; - AES_KEY actx; unsigned char *ukey = NULL; int ukeylen; int r = 0, wrap_nid; + EVP_CIPHER *cipher = NULL; + int outlen = 0; + EVP_CIPHER_CTX *ctx = NULL; + const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms); - ec = cms->d.envelopedData->encryptedContentInfo; + ec = ossl_cms_get0_env_enc_content(cms); + if (ec == NULL) + return 0; kekri = ri->d.kekri; if (!kekri->key) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_KEY); return 0; } wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); if (aes_wrap_keylen(wrap_nid) != kekri->keylen) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_INVALID_KEY_LENGTH); + ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); return 0; } /* If encrypted key length is invalid don't bother */ if (kekri->encryptedKey->length < 16) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); + ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); goto err; } - if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_ERROR_SETTING_KEY); + cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx); + if (cipher == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); goto err; } ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); - if (ukey == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } - ukeylen = AES_unwrap_key(&actx, NULL, ukey, - kekri->encryptedKey->data, - kekri->encryptedKey->length); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + goto err; + } - if (ukeylen <= 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR); + if (!EVP_DecryptInit_ex(ctx, cipher, NULL, kekri->key, NULL) + || !EVP_DecryptUpdate(ctx, ukey, &ukeylen, + kekri->encryptedKey->data, + kekri->encryptedKey->length) + || !EVP_DecryptFinal_ex(ctx, ukey + ukeylen, &outlen)) { + ERR_raise(ERR_LIB_CMS, CMS_R_UNWRAP_ERROR); goto err; } + ukeylen += outlen; OPENSSL_clear_free(ec->key, ec->keylen); ec->key = ukey; @@ -744,13 +958,12 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, r = 1; err: - + EVP_CIPHER_free(cipher); if (!r) OPENSSL_free(ukey); - OPENSSL_cleanse(&actx, sizeof(actx)); + EVP_CIPHER_CTX_free(ctx); return r; - } int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) @@ -763,33 +976,31 @@ int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) return cms_RecipientInfo_kekri_decrypt(cms, ri); case CMS_RECIPINFO_PASS: - return cms_RecipientInfo_pwri_crypt(cms, ri, 0); + return ossl_cms_RecipientInfo_pwri_crypt(cms, ri, 0); default: - CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, - CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE); return 0; } } -int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) +int CMS_RecipientInfo_encrypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri) { switch (ri->type) { case CMS_RECIPINFO_TRANS: return cms_RecipientInfo_ktri_encrypt(cms, ri); case CMS_RECIPINFO_AGREE: - return cms_RecipientInfo_kari_encrypt(cms, ri); + return ossl_cms_RecipientInfo_kari_encrypt(cms, ri); case CMS_RECIPINFO_KEK: return cms_RecipientInfo_kekri_encrypt(cms, ri); case CMS_RECIPINFO_PASS: - return cms_RecipientInfo_pwri_crypt(cms, ri, 1); + return ossl_cms_RecipientInfo_pwri_crypt(cms, ri, 1); default: - CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT, - CMS_R_UNSUPPORTED_RECIPIENT_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENT_TYPE); return 0; } } @@ -857,50 +1068,219 @@ static void cms_env_set_version(CMS_EnvelopedData *env) env->version = 0; } -BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) +static int cms_env_encrypt_content_key(const CMS_ContentInfo *cms, + STACK_OF(CMS_RecipientInfo) *ris) +{ + int i; + CMS_RecipientInfo *ri; + + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) + return -1; + } + return 1; +} + +static void cms_env_clear_ec(CMS_EncryptedContentInfo *ec) +{ + ec->cipher = NULL; + OPENSSL_clear_free(ec->key, ec->keylen); + ec->key = NULL; + ec->keylen = 0; +} + +static BIO *cms_EnvelopedData_Decryption_init_bio(CMS_ContentInfo *cms) +{ + CMS_EncryptedContentInfo *ec = cms->d.envelopedData->encryptedContentInfo; + BIO *contentBio = ossl_cms_EncryptedContent_init_bio(ec, + ossl_cms_get0_cmsctx(cms)); + EVP_CIPHER_CTX *ctx = NULL; + + if (contentBio == NULL) + return NULL; + + BIO_get_cipher_ctx(contentBio, &ctx); + if (ctx == NULL) { + BIO_free(contentBio); + return NULL; + } + /* + * If the selected cipher supports unprotected attributes, + * deal with it using special ctrl function + */ + if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) + & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0 + && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, 0, + cms->d.envelopedData->unprotectedAttrs) <= 0) { + BIO_free(contentBio); + return NULL; + } + return contentBio; +} + +static BIO *cms_EnvelopedData_Encryption_init_bio(CMS_ContentInfo *cms) { CMS_EncryptedContentInfo *ec; STACK_OF(CMS_RecipientInfo) *rinfos; - CMS_RecipientInfo *ri; - int i, ok = 0; + int ok = 0; BIO *ret; + CMS_EnvelopedData *env = cms->d.envelopedData; /* Get BIO first to set up key */ - ec = cms->d.envelopedData->encryptedContentInfo; - ret = cms_EncryptedContent_init_bio(ec); + ec = env->encryptedContentInfo; + ret = ossl_cms_EncryptedContent_init_bio(ec, ossl_cms_get0_cmsctx(cms)); - /* If error or no cipher end of processing */ - - if (!ret || !ec->cipher) + /* If error end of processing */ + if (!ret) return ret; /* Now encrypt content key according to each RecipientInfo type */ + rinfos = env->recipientInfos; + if (cms_env_encrypt_content_key(cms, rinfos) < 0) { + ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_SETTING_RECIPIENTINFO); + goto err; + } - rinfos = cms->d.envelopedData->recipientInfos; + /* And finally set the version */ + cms_env_set_version(env); - for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { - ri = sk_CMS_RecipientInfo_value(rinfos, i); - if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) { - CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, - CMS_R_ERROR_SETTING_RECIPIENTINFO); - goto err; - } + ok = 1; + + err: + cms_env_clear_ec(ec); + if (ok) + return ret; + BIO_free(ret); + return NULL; +} + +BIO *ossl_cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) +{ + if (cms->d.envelopedData->encryptedContentInfo->cipher != NULL) { + /* If cipher is set it's encryption */ + return cms_EnvelopedData_Encryption_init_bio(cms); + } + + /* If cipher is not set it's decryption */ + return cms_EnvelopedData_Decryption_init_bio(cms); +} + +BIO *ossl_cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_EncryptedContentInfo *ec; + STACK_OF(CMS_RecipientInfo) *rinfos; + int ok = 0; + BIO *ret; + CMS_AuthEnvelopedData *aenv = cms->d.authEnvelopedData; + + /* Get BIO first to set up key */ + ec = aenv->authEncryptedContentInfo; + /* Set tag for decryption */ + if (ec->cipher == NULL) { + ec->tag = aenv->mac->data; + ec->taglen = aenv->mac->length; + } + ret = ossl_cms_EncryptedContent_init_bio(ec, ossl_cms_get0_cmsctx(cms)); + + /* If error or no cipher end of processing */ + if (ret == NULL || ec->cipher == NULL) + return ret; + + /* Now encrypt content key according to each RecipientInfo type */ + rinfos = aenv->recipientInfos; + if (cms_env_encrypt_content_key(cms, rinfos) < 0) { + ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_SETTING_RECIPIENTINFO); + goto err; } - cms_env_set_version(cms->d.envelopedData); + + /* And finally set the version */ + aenv->version = 0; ok = 1; err: - ec->cipher = NULL; - OPENSSL_clear_free(ec->key, ec->keylen); - ec->key = NULL; - ec->keylen = 0; + cms_env_clear_ec(ec); if (ok) return ret; BIO_free(ret); return NULL; +} + +int ossl_cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain) +{ + CMS_EnvelopedData *env = NULL; + EVP_CIPHER_CTX *ctx = NULL; + BIO *mbio = BIO_find_type(chain, BIO_TYPE_CIPHER); + + env = ossl_cms_get0_enveloped(cms); + if (env == NULL) + return 0; + + if (mbio == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_NOT_FOUND); + return 0; + } + + BIO_get_cipher_ctx(mbio, &ctx); + + /* + * If the selected cipher supports unprotected attributes, + * deal with it using special ctrl function + */ + if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) + & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0) { + if (env->unprotectedAttrs == NULL) + env->unprotectedAttrs = sk_X509_ATTRIBUTE_new_null(); + + if (env->unprotectedAttrs == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, + 1, env->unprotectedAttrs) <= 0) { + ERR_raise(ERR_LIB_CMS, CMS_R_CTRL_FAILURE); + return 0; + } + } + cms_env_set_version(cms->d.envelopedData); + return 1; +} + +int ossl_cms_AuthEnvelopedData_final(CMS_ContentInfo *cms, BIO *cmsbio) +{ + EVP_CIPHER_CTX *ctx; + unsigned char *tag = NULL; + int taglen, ok = 0; + + BIO_get_cipher_ctx(cmsbio, &ctx); + + /* + * The tag is set only for encryption. There is nothing to do for + * decryption. + */ + if (!EVP_CIPHER_CTX_is_encrypting(ctx)) + return 1; + + taglen = EVP_CIPHER_CTX_get_tag_length(ctx); + if (taglen <= 0 + || (tag = OPENSSL_malloc(taglen)) == NULL + || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, + tag) <= 0) { + ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_GET_TAG); + goto err; + } + + if (!ASN1_OCTET_STRING_set(cms->d.authEnvelopedData->mac, tag, taglen)) + goto err; + + ok = 1; +err: + OPENSSL_free(tag); + return ok; } /* @@ -908,8 +1288,24 @@ BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) * retain compatibility with previous behaviour if the ctrl value isn't * supported we assume key transport. */ -int cms_pkey_get_ri_type(EVP_PKEY *pk) +int ossl_cms_pkey_get_ri_type(EVP_PKEY *pk) { + /* Check types that we know about */ + if (EVP_PKEY_is_a(pk, "DH")) + return CMS_RECIPINFO_AGREE; + else if (EVP_PKEY_is_a(pk, "DHX")) + return CMS_RECIPINFO_AGREE; + else if (EVP_PKEY_is_a(pk, "DSA")) + return CMS_RECIPINFO_NONE; + else if (EVP_PKEY_is_a(pk, "EC")) + return CMS_RECIPINFO_AGREE; + else if (EVP_PKEY_is_a(pk, "RSA")) + return CMS_RECIPINFO_TRANS; + + /* + * Otherwise this might ben an engine implementation, so see if we can get + * the type from the ameth. + */ if (pk->ameth && pk->ameth->pkey_ctrl) { int i, r; i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r); @@ -918,3 +1314,23 @@ int cms_pkey_get_ri_type(EVP_PKEY *pk) } return CMS_RECIPINFO_TRANS; } + +int ossl_cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type) +{ + int supportedRiType; + + if (pk->ameth != NULL && pk->ameth->pkey_ctrl != NULL) { + int i, r; + + i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED, + ri_type, &r); + if (i > 0) + return r; + } + + supportedRiType = ossl_cms_pkey_get_ri_type(pk); + if (supportedRiType < 0) + return 0; + + return (supportedRiType == ri_type); +} diff --git a/crypto/openssl/crypto/cms/cms_err.c b/crypto/openssl/crypto/cms/cms_err.c index 408fe13b87d9..dcbea201c8e5 100644 --- a/crypto/openssl/crypto/cms/cms_err.c +++ b/crypto/openssl/crypto/cms/cms_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,150 +10,11 @@ #include #include +#include "crypto/cmserr.h" -#ifndef OPENSSL_NO_ERR +#ifndef OPENSSL_NO_CMS -static const ERR_STRING_DATA CMS_str_functs[] = { - {ERR_PACK(ERR_LIB_CMS, CMS_F_CHECK_CONTENT, 0), "check_content"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD0_CERT, 0), "CMS_add0_cert"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD0_RECIPIENT_KEY, 0), - "CMS_add0_recipient_key"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, 0), - "CMS_add0_recipient_password"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECEIPTREQUEST, 0), - "CMS_add1_ReceiptRequest"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECIPIENT_CERT, 0), - "CMS_add1_recipient_cert"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNER, 0), "CMS_add1_signer"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNINGTIME, 0), - "cms_add1_signingTime"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESS, 0), "CMS_compress"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESSEDDATA_CREATE, 0), - "cms_CompressedData_create"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, 0), - "cms_CompressedData_init_bio"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COPY_CONTENT, 0), "cms_copy_content"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COPY_MESSAGEDIGEST, 0), - "cms_copy_messageDigest"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DATA, 0), "CMS_data"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DATAFINAL, 0), "CMS_dataFinal"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DATAINIT, 0), "CMS_dataInit"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT, 0), "CMS_decrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_KEY, 0), - "CMS_decrypt_set1_key"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_PASSWORD, 0), - "CMS_decrypt_set1_password"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_PKEY, 0), - "CMS_decrypt_set1_pkey"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, 0), - "cms_DigestAlgorithm_find_ctx"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, 0), - "cms_DigestAlgorithm_init_bio"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTEDDATA_DO_FINAL, 0), - "cms_DigestedData_do_final"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGEST_VERIFY, 0), "CMS_digest_verify"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCODE_RECEIPT, 0), "cms_encode_Receipt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPT, 0), "CMS_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDCONTENT_INIT, 0), - "cms_EncryptedContent_init"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, 0), - "cms_EncryptedContent_init_bio"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, 0), - "CMS_EncryptedData_decrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, 0), - "CMS_EncryptedData_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, 0), - "CMS_EncryptedData_set1_key"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_CREATE, 0), - "CMS_EnvelopedData_create"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, 0), - "cms_EnvelopedData_init_bio"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPED_DATA_INIT, 0), - "cms_enveloped_data_init"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENV_ASN1_CTRL, 0), "cms_env_asn1_ctrl"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_FINAL, 0), "CMS_final"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_CERTIFICATE_CHOICES, 0), - "cms_get0_certificate_choices"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_CONTENT, 0), "CMS_get0_content"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_ECONTENT_TYPE, 0), - "cms_get0_econtent_type"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_ENVELOPED, 0), "cms_get0_enveloped"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_REVOCATION_CHOICES, 0), - "cms_get0_revocation_choices"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_SIGNED, 0), "cms_get0_signed"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_MSGSIGDIGEST_ADD1, 0), - "cms_msgSigDigest_add1"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECEIPTREQUEST_CREATE0, 0), - "CMS_ReceiptRequest_create0"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECEIPT_VERIFY, 0), "cms_Receipt_verify"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_DECRYPT, 0), - "CMS_RecipientInfo_decrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_ENCRYPT, 0), - "CMS_RecipientInfo_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, 0), - "cms_RecipientInfo_kari_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG, 0), - "CMS_RecipientInfo_kari_get0_alg"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID, 0), - "CMS_RecipientInfo_kari_get0_orig_id"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS, 0), - "CMS_RecipientInfo_kari_get0_reks"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP, 0), - "CMS_RecipientInfo_kari_orig_id_cmp"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, 0), - "cms_RecipientInfo_kekri_decrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, 0), - "cms_RecipientInfo_kekri_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, 0), - "CMS_RecipientInfo_kekri_get0_id"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, 0), - "CMS_RecipientInfo_kekri_id_cmp"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP, 0), - "CMS_RecipientInfo_ktri_cert_cmp"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, 0), - "cms_RecipientInfo_ktri_decrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, 0), - "cms_RecipientInfo_ktri_encrypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS, 0), - "CMS_RecipientInfo_ktri_get0_algs"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID, 0), - "CMS_RecipientInfo_ktri_get0_signer_id"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, 0), - "cms_RecipientInfo_pwri_crypt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_SET0_KEY, 0), - "CMS_RecipientInfo_set0_key"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, 0), - "CMS_RecipientInfo_set0_password"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, 0), - "CMS_RecipientInfo_set0_pkey"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SD_ASN1_CTRL, 0), "cms_sd_asn1_ctrl"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET1_IAS, 0), "cms_set1_ias"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET1_KEYID, 0), "cms_set1_keyid"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET1_SIGNERIDENTIFIER, 0), - "cms_set1_SignerIdentifier"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET_DETACHED, 0), "CMS_set_detached"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGN, 0), "CMS_sign"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNED_DATA_INIT, 0), - "cms_signed_data_init"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, 0), - "cms_SignerInfo_content_sign"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_SIGN, 0), - "CMS_SignerInfo_sign"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_VERIFY, 0), - "CMS_SignerInfo_verify"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_VERIFY_CERT, 0), - "cms_signerinfo_verify_cert"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 0), - "CMS_SignerInfo_verify_content"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGN_RECEIPT, 0), "CMS_sign_receipt"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SI_CHECK_ATTRIBUTES, 0), - "CMS_si_check_attributes"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_STREAM, 0), "CMS_stream"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_UNCOMPRESS, 0), "CMS_uncompress"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_VERIFY, 0), "CMS_verify"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_KEK_UNWRAP_KEY, 0), "kek_unwrap_key"}, - {0, NULL} -}; +# ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA CMS_str_reasons[] = { {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ADD_SIGNER_ERROR), "add signer error"}, @@ -164,6 +25,9 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { "certificate has no keyid"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_AEAD_SET_TAG_ERROR), + "cipher aead set tag error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_GET_TAG), "cipher get tag"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_INITIALISATION_ERROR), "cipher initialisation error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR), @@ -186,6 +50,7 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { "content verify error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_ERROR), "ctrl error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_FAILURE), "ctrl failure"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECODE_ERROR), "decode error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECRYPT_ERROR), "decrypt error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_GETTING_PUBLIC_KEY), "error getting public key"}, @@ -194,11 +59,18 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_KEY), "error setting key"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_RECIPIENTINFO), "error setting recipientinfo"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR), + "ess signing certid mismatch error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH), "invalid encrypted key length"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER), "invalid key encryption parameter"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_LABEL), "invalid label"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_OAEP_PARAMETERS), + "invalid oaep parameters"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_KDF_PARAMETER_ERROR), + "kdf parameter error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MD_BIO_INIT_ERROR), "md bio init error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH), "messagedigest attribute wrong length"}, @@ -237,11 +109,13 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PUBLIC_KEY), "no public key"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_RECEIPT_REQUEST), "no receipt request"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_SIGNERS), "no signers"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PEER_KEY_ERROR), "peer key error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), "private key does not match certificate"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECEIPT_DECODE_ERROR), "receipt decode error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECIPIENT_ERROR), "recipient error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SHARED_INFO_ERROR), "shared info error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND), "signer certificate not found"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNFINAL_ERROR), "signfinal error"}, @@ -268,10 +142,14 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { "unsupported content encryption algorithm"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE), + "unsupported encryption type"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEK_ALGORITHM), "unsupported kek algorithm"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM), "unsupported key encryption algorithm"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_LABEL_SOURCE), + "unsupported label source"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE), "unsupported recipientinfo type"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENT_TYPE), @@ -285,15 +163,16 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { {0, NULL} }; -#endif +# endif -int ERR_load_CMS_strings(void) +int ossl_err_load_CMS_strings(void) { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(CMS_str_functs[0].error) == NULL) { - ERR_load_strings_const(CMS_str_functs); +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(CMS_str_reasons[0].error) == NULL) ERR_load_strings_const(CMS_str_reasons); - } -#endif +# endif return 1; } +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/cms/cms_ess.c b/crypto/openssl/crypto/cms/cms_ess.c index a21c443ae85e..6c43dd102a91 100644 --- a/crypto/openssl/crypto/cms/cms_ess.c +++ b/crypto/openssl/crypto/cms/cms_ess.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,42 +14,111 @@ #include #include #include +#include +#include "crypto/ess.h" +#include "crypto/x509.h" #include "cms_local.h" IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) -/* ESS services: for now just Signed Receipt related */ +/* ESS services */ int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr) { ASN1_STRING *str; - CMS_ReceiptRequest *rr = NULL; - if (prr) + CMS_ReceiptRequest *rr; + ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_receiptRequest); + + if (prr != NULL) *prr = NULL; - str = CMS_signed_get0_data_by_OBJ(si, - OBJ_nid2obj - (NID_id_smime_aa_receiptRequest), -3, - V_ASN1_SEQUENCE); - if (!str) + str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE); + if (str == NULL) return 0; rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest)); - if (!rr) + if (rr == NULL) return -1; - if (prr) + if (prr != NULL) *prr = rr; else CMS_ReceiptRequest_free(rr); return 1; } -CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, - int allorfirst, - STACK_OF(GENERAL_NAMES) - *receiptList, STACK_OF(GENERAL_NAMES) - *receiptsTo) +/* + * Returns 0 if attribute is not found, 1 if found, + * or -1 on attribute parsing failure. + */ +static int ossl_cms_signerinfo_get_signing_cert(const CMS_SignerInfo *si, + ESS_SIGNING_CERT **psc) { - CMS_ReceiptRequest *rr = NULL; + ASN1_STRING *str; + ESS_SIGNING_CERT *sc; + ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_signingCertificate); + + if (psc != NULL) + *psc = NULL; + str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE); + if (str == NULL) + return 0; + + sc = ASN1_item_unpack(str, ASN1_ITEM_rptr(ESS_SIGNING_CERT)); + if (sc == NULL) + return -1; + if (psc != NULL) + *psc = sc; + else + ESS_SIGNING_CERT_free(sc); + return 1; +} + +/* + * Returns 0 if attribute is not found, 1 if found, + * or -1 on attribute parsing failure. + */ +static int ossl_cms_signerinfo_get_signing_cert_v2(const CMS_SignerInfo *si, + ESS_SIGNING_CERT_V2 **psc) +{ + ASN1_STRING *str; + ESS_SIGNING_CERT_V2 *sc; + ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_signingCertificateV2); + + if (psc != NULL) + *psc = NULL; + str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE); + if (str == NULL) + return 0; + + sc = ASN1_item_unpack(str, ASN1_ITEM_rptr(ESS_SIGNING_CERT_V2)); + if (sc == NULL) + return -1; + if (psc != NULL) + *psc = sc; + else + ESS_SIGNING_CERT_V2_free(sc); + return 1; +} + +int ossl_cms_check_signing_certs(const CMS_SignerInfo *si, + const STACK_OF(X509) *chain) +{ + ESS_SIGNING_CERT *ss = NULL; + ESS_SIGNING_CERT_V2 *ssv2 = NULL; + int ret = ossl_cms_signerinfo_get_signing_cert(si, &ss) >= 0 + && ossl_cms_signerinfo_get_signing_cert_v2(si, &ssv2) >= 0 + && OSSL_ESS_check_signing_certs(ss, ssv2, chain, 1) > 0; + + ESS_SIGNING_CERT_free(ss); + ESS_SIGNING_CERT_V2_free(ssv2); + return ret; +} + +CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex( + unsigned char *id, int idlen, int allorfirst, + STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo, + OSSL_LIB_CTX *libctx) +{ + CMS_ReceiptRequest *rr; rr = CMS_ReceiptRequest_new(); if (rr == NULL) @@ -59,14 +128,15 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, else { if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) goto merr; - if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0) + if (RAND_bytes_ex(libctx, rr->signedContentIdentifier->data, 32, + 0) <= 0) goto err; } sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free); rr->receiptsTo = receiptsTo; - if (receiptList) { + if (receiptList != NULL) { rr->receiptsFrom->type = 1; rr->receiptsFrom->d.receiptList = receiptList; } else { @@ -77,7 +147,7 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, return rr; merr: - CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: CMS_ReceiptRequest_free(rr); @@ -85,6 +155,14 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, } +CMS_ReceiptRequest *CMS_ReceiptRequest_create0( + unsigned char *id, int idlen, int allorfirst, + STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo) +{ + return CMS_ReceiptRequest_create0_ex(id, idlen, allorfirst, receiptList, + receiptsTo, NULL); +} + int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) { unsigned char *rrder = NULL; @@ -102,7 +180,7 @@ int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) merr: if (!r) - CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); OPENSSL_free(rrder); @@ -116,20 +194,20 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, STACK_OF(GENERAL_NAMES) **plist, STACK_OF(GENERAL_NAMES) **prto) { - if (pcid) + if (pcid != NULL) *pcid = rr->signedContentIdentifier; if (rr->receiptsFrom->type == 0) { - if (pallorfirst) + if (pallorfirst != NULL) *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier; - if (plist) + if (plist != NULL) *plist = NULL; } else { - if (pallorfirst) + if (pallorfirst != NULL) *pallorfirst = -1; - if (plist) + if (plist != NULL) *plist = rr->receiptsFrom->d.receiptList; } - if (prto) + if (prto != NULL) *prto = rr->receiptsTo; } @@ -138,29 +216,32 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, static int cms_msgSigDigest(CMS_SignerInfo *si, unsigned char *dig, unsigned int *diglen) { - const EVP_MD *md; - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + const EVP_MD *md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + if (md == NULL) return 0; - if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, - si->signedAttrs, dig, diglen)) + if (!ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, + si->signedAttrs, dig, diglen, + ossl_cms_ctx_get0_libctx(si->cms_ctx), + ossl_cms_ctx_get0_propq(si->cms_ctx))) return 0; return 1; } /* Add a msgSigDigest attribute to a SignerInfo */ -int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) +int ossl_cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) { unsigned char dig[EVP_MAX_MD_SIZE]; unsigned int diglen; + if (!cms_msgSigDigest(src, dig, &diglen)) { - CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_ERROR); return 0; } if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest, V_ASN1_OCTET_STRING, dig, diglen)) { - CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -168,7 +249,7 @@ int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) /* Verify signed receipt after it has already passed normal CMS verify */ -int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) +int ossl_cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) { int r = 0, i; CMS_ReceiptRequest *rr = NULL; @@ -187,27 +268,27 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) goto err; if (sk_CMS_SignerInfo_num(sis) != 1) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER); + ERR_raise(ERR_LIB_CMS, CMS_R_NEED_ONE_SIGNER); goto err; } /* Check receipt content type */ if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_A_SIGNED_RECEIPT); goto err; } /* Extract and decode receipt content */ pcont = CMS_get0_content(cms); - if (!pcont || !*pcont) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT); + if (pcont == NULL || *pcont == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT); goto err; } rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt)); if (!rct) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_RECEIPT_DECODE_ERROR); goto err; } @@ -220,7 +301,7 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) } if (i == sk_CMS_SignerInfo_num(osis)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_SIGNATURE); goto err; } @@ -234,23 +315,22 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) V_ASN1_OCTET_STRING); if (!msig) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_MSGSIGDIGEST); goto err; } if (!cms_msgSigDigest(osi, dig, &diglen)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_ERROR); goto err; } if (diglen != (unsigned int)msig->length) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_WRONG_LENGTH); + ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_WRONG_LENGTH); goto err; } if (memcmp(dig, msig->data, diglen)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, - CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE); + ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE); goto err; } @@ -260,27 +340,27 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) OBJ_nid2obj(NID_pkcs9_contentType), -3, V_ASN1_OBJECT); if (!octype) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT_TYPE); goto err; } /* Compare details in receipt request */ if (OBJ_cmp(octype, rct->contentType)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH); + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_MISMATCH); goto err; } /* Get original receipt request details */ if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_RECEIPT_REQUEST); goto err; } if (ASN1_STRING_cmp(rr->signedContentIdentifier, rct->signedContentIdentifier)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENTIDENTIFIER_MISMATCH); + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENTIDENTIFIER_MISMATCH); goto err; } @@ -298,7 +378,7 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) * SignedData ContentInfo. */ -ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) +ASN1_OCTET_STRING *ossl_cms_encode_Receipt(CMS_SignerInfo *si) { CMS_Receipt rct; CMS_ReceiptRequest *rr = NULL; @@ -310,7 +390,7 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) /* Get original receipt request details */ if (CMS_get1_ReceiptRequest(si, &rr) <= 0) { - CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_RECEIPT_REQUEST); goto err; } @@ -320,7 +400,7 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) OBJ_nid2obj(NID_pkcs9_contentType), -3, V_ASN1_OBJECT); if (!ctype) { - CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT_TYPE); goto err; } diff --git a/crypto/openssl/crypto/cms/cms_io.c b/crypto/openssl/crypto/cms/cms_io.c index b37e485f5a28..dab70af73c33 100644 --- a/crypto/openssl/crypto/cms/cms_io.c +++ b/crypto/openssl/crypto/cms/cms_io.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,6 +14,7 @@ #include #include "cms_local.h" +/* unfortunately cannot constify BIO_new_NDEF() due to this and PKCS7_stream() */ int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) { ASN1_OCTET_STRING **pos; @@ -28,13 +29,24 @@ int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) *boundary = &(*pos)->data; return 1; } - CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return 0; } CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) { - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); + CMS_ContentInfo *ci; + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms == NULL ? NULL : *cms); + + ci = ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms, + ossl_cms_ctx_get0_libctx(ctx), + ossl_cms_ctx_get0_propq(ctx)); + if (ci != NULL) { + ERR_set_mark(); + ossl_cms_resolve_libctx(ci); + ERR_pop_to_mark(); + } + return ci; } int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms) @@ -42,7 +54,7 @@ int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms) return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); } -IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) +IMPLEMENT_PEM_rw(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) { @@ -70,19 +82,40 @@ int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) STACK_OF(X509_ALGOR) *mdalgs; int ctype_nid = OBJ_obj2nid(cms->contentType); int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms)); + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); + if (ctype_nid == NID_pkcs7_signed) mdalgs = cms->d.signedData->digestAlgorithms; else mdalgs = NULL; - return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, - ctype_nid, econt_nid, mdalgs, - ASN1_ITEM_rptr(CMS_ContentInfo)); + return SMIME_write_ASN1_ex(bio, (ASN1_VALUE *)cms, data, flags, ctype_nid, + econt_nid, mdalgs, + ASN1_ITEM_rptr(CMS_ContentInfo), + ossl_cms_ctx_get0_libctx(ctx), + ossl_cms_ctx_get0_propq(ctx)); +} + +CMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, int flags, BIO **bcont, + CMS_ContentInfo **cms) +{ + CMS_ContentInfo *ci; + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms == NULL ? NULL : *cms); + + ci = (CMS_ContentInfo *)SMIME_read_ASN1_ex(bio, flags, bcont, + ASN1_ITEM_rptr(CMS_ContentInfo), + (ASN1_VALUE **)cms, + ossl_cms_ctx_get0_libctx(ctx), + ossl_cms_ctx_get0_propq(ctx)); + if (ci != NULL) { + ERR_set_mark(); + ossl_cms_resolve_libctx(ci); + ERR_pop_to_mark(); + } + return ci; } CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont) { - return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont, - ASN1_ITEM_rptr - (CMS_ContentInfo)); + return SMIME_read_CMS_ex(bio, 0, bcont, NULL); } diff --git a/crypto/openssl/crypto/cms/cms_kari.c b/crypto/openssl/crypto/cms/cms_kari.c index cafc3040ac70..a2f422a78d8b 100644 --- a/crypto/openssl/crypto/cms/cms_kari.c +++ b/crypto/openssl/crypto/cms/cms_kari.c @@ -1,12 +1,18 @@ /* - * Copyright 2013-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2013-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * Low level key APIs (DH etc) are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" #include #include @@ -24,8 +30,7 @@ int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, ASN1_OCTET_STRING **pukm) { if (ri->type != CMS_RECIPINFO_AGREE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG, - CMS_R_NOT_KEY_AGREEMENT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT); return 0; } if (palg) @@ -41,8 +46,7 @@ STACK_OF(CMS_RecipientEncryptedKey) *CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri) { if (ri->type != CMS_RECIPINFO_AGREE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS, - CMS_R_NOT_KEY_AGREEMENT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT); return NULL; } return ri->d.kari->recipientEncryptedKeys; @@ -56,9 +60,9 @@ int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, ASN1_INTEGER **sno) { CMS_OriginatorIdentifierOrKey *oik; + if (ri->type != CMS_RECIPINFO_AGREE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID, - CMS_R_NOT_KEY_AGREEMENT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT); return 0; } oik = ri->d.kari->originator; @@ -93,16 +97,16 @@ int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert) { CMS_OriginatorIdentifierOrKey *oik; + if (ri->type != CMS_RECIPINFO_AGREE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP, - CMS_R_NOT_KEY_AGREEMENT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT); return -2; } oik = ri->d.kari->originator; if (oik->type == CMS_OIK_ISSUER_SERIAL) - return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert); + return ossl_cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert); else if (oik->type == CMS_OIK_KEYIDENTIFIER) - return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert); + return ossl_cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert); return -1; } @@ -113,6 +117,7 @@ int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, X509_NAME **issuer, ASN1_INTEGER **sno) { CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; + if (rid->type == CMS_REK_ISSUER_SERIAL) { if (issuer) *issuer = rid->d.issuerAndSerialNumber->issuer; @@ -144,26 +149,40 @@ int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, X509 *cert) { CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; + if (rid->type == CMS_REK_ISSUER_SERIAL) - return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert); + return ossl_cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert); else if (rid->type == CMS_REK_KEYIDENTIFIER) - return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert); + return ossl_cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, + cert); else return -1; } -int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) +int CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo *ri, + EVP_PKEY *pk, X509 *peer) { EVP_PKEY_CTX *pctx; CMS_KeyAgreeRecipientInfo *kari = ri->d.kari; EVP_PKEY_CTX_free(kari->pctx); kari->pctx = NULL; - if (!pk) + if (pk == NULL) return 1; - pctx = EVP_PKEY_CTX_new(pk, NULL); - if (!pctx || EVP_PKEY_derive_init(pctx) <= 0) + + pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(kari->cms_ctx), + pk, + ossl_cms_ctx_get0_propq(kari->cms_ctx)); + if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0) goto err; + + if (peer != NULL) { + EVP_PKEY *pub_pkey = X509_get0_pubkey(peer); + + if (EVP_PKEY_derive_set_peer(pctx, pub_pkey) <= 0) + goto err; + } + kari->pctx = pctx; return 1; err: @@ -171,6 +190,11 @@ int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) return 0; } +int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) +{ + return CMS_RecipientInfo_kari_set0_pkey_and_peer(ri, pk, NULL); +} + EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri) { if (ri->type == CMS_RECIPINFO_AGREE) @@ -193,7 +217,8 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, int rv = 0; unsigned char *out = NULL; int outlen; - keklen = EVP_CIPHER_CTX_key_length(kari->ctx); + + keklen = EVP_CIPHER_CTX_get_key_length(kari->ctx); if (keklen > EVP_MAX_KEY_LENGTH) return 0; /* Derive KEK */ @@ -234,15 +259,16 @@ int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, size_t enckeylen; size_t ceklen; CMS_EncryptedContentInfo *ec; + enckeylen = rek->encryptedKey->length; enckey = rek->encryptedKey->data; /* Setup all parameters to derive KEK */ - if (!cms_env_asn1_ctrl(ri, 1)) + if (!ossl_cms_env_asn1_ctrl(ri, 1)) goto err; /* Attempt to decrypt CEK */ if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0)) goto err; - ec = cms->d.envelopedData->encryptedContentInfo; + ec = ossl_cms_get0_env_enc_content(cms); OPENSSL_clear_free(ec->key, ec->keylen); ec->key = cek; ec->keylen = ceklen; @@ -260,16 +286,20 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *ekey = NULL; int rv = 0; - pctx = EVP_PKEY_CTX_new(pk, NULL); - if (!pctx) + const CMS_CTX *ctx = kari->cms_ctx; + OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx); + const char *propq = ossl_cms_ctx_get0_propq(ctx); + + pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propq); + if (pctx == NULL) goto err; if (EVP_PKEY_keygen_init(pctx) <= 0) goto err; if (EVP_PKEY_keygen(pctx, &ekey) <= 0) goto err; EVP_PKEY_CTX_free(pctx); - pctx = EVP_PKEY_CTX_new(ekey, NULL); - if (!pctx) + pctx = EVP_PKEY_CTX_new_from_pkey(libctx, ekey, propq); + if (pctx == NULL) goto err; if (EVP_PKEY_derive_init(pctx) <= 0) goto err; @@ -282,21 +312,48 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, return rv; } +/* Set originator private key and initialise context based on it */ +static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari, + EVP_PKEY *originatorPrivKey ) +{ + EVP_PKEY_CTX *pctx = NULL; + int rv = 0; + const CMS_CTX *ctx = kari->cms_ctx; + + pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx), + originatorPrivKey, + ossl_cms_ctx_get0_propq(ctx)); + if (pctx == NULL) + goto err; + if (EVP_PKEY_derive_init(pctx) <= 0) + goto err; + + kari->pctx = pctx; + rv = 1; + err: + if (rv == 0) + EVP_PKEY_CTX_free(pctx); + return rv; +} + /* Initialise a kari based on passed certificate and key */ -int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, - EVP_PKEY *pk, unsigned int flags) +int ossl_cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, + EVP_PKEY *recipPubKey, X509 *originator, + EVP_PKEY *originatorPrivKey, + unsigned int flags, const CMS_CTX *ctx) { CMS_KeyAgreeRecipientInfo *kari; CMS_RecipientEncryptedKey *rek = NULL; ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo); - if (!ri->d.kari) + if (ri->d.kari == NULL) return 0; ri->type = CMS_RECIPINFO_AGREE; kari = ri->d.kari; kari->version = 3; + kari->cms_ctx = ctx; rek = M_ASN1_new_of(CMS_RecipientEncryptedKey); if (rek == NULL) @@ -312,59 +369,112 @@ int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier); if (rek->rid->d.rKeyId == NULL) return 0; - if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip)) + if (!ossl_cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip)) return 0; } else { rek->rid->type = CMS_REK_ISSUER_SERIAL; - if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip)) + if (!ossl_cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip)) return 0; } - /* Create ephemeral key */ - if (!cms_kari_create_ephemeral_key(kari, pk)) - return 0; + if (originatorPrivKey == NULL && originator == NULL) { + /* Create ephemeral key */ + if (!cms_kari_create_ephemeral_key(kari, recipPubKey)) + return 0; + } else { + /* Use originator key */ + CMS_OriginatorIdentifierOrKey *oik = ri->d.kari->originator; - EVP_PKEY_up_ref(pk); - rek->pkey = pk; + if (originatorPrivKey == NULL || originator == NULL) + return 0; + + if (flags & CMS_USE_ORIGINATOR_KEYID) { + oik->type = CMS_OIK_KEYIDENTIFIER; + oik->d.subjectKeyIdentifier = ASN1_OCTET_STRING_new(); + if (oik->d.subjectKeyIdentifier == NULL) + return 0; + if (!ossl_cms_set1_keyid(&oik->d.subjectKeyIdentifier, originator)) + return 0; + } else { + oik->type = CMS_REK_ISSUER_SERIAL; + if (!ossl_cms_set1_ias(&oik->d.issuerAndSerialNumber, originator)) + return 0; + } + + if (!cms_kari_set_originator_private_key(kari, originatorPrivKey)) + return 0; + } + + EVP_PKEY_up_ref(recipPubKey); + rek->pkey = recipPubKey; return 1; } static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, const EVP_CIPHER *cipher) { + const CMS_CTX *cms_ctx = kari->cms_ctx; EVP_CIPHER_CTX *ctx = kari->ctx; const EVP_CIPHER *kekcipher; - int keylen = EVP_CIPHER_key_length(cipher); - /* If a suitable wrap algorithm is already set nothing to do */ - kekcipher = EVP_CIPHER_CTX_cipher(ctx); + EVP_CIPHER *fetched_kekcipher; + const char *kekcipher_name; + int keylen; + int ret; - if (kekcipher) { - if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE) + /* If a suitable wrap algorithm is already set nothing to do */ + kekcipher = EVP_CIPHER_CTX_get0_cipher(ctx); + if (kekcipher != NULL) { + if (EVP_CIPHER_CTX_get_mode(ctx) != EVP_CIPH_WRAP_MODE) return 0; return 1; } + if (cipher == NULL) + return 0; + keylen = EVP_CIPHER_get_key_length(cipher); + if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_GET_WRAP_CIPHER) != 0) { + ret = EVP_CIPHER_meth_get_ctrl(cipher)(NULL, EVP_CTRL_GET_WRAP_CIPHER, + 0, &kekcipher); + if (ret <= 0) + return 0; + + if (kekcipher != NULL) { + if (EVP_CIPHER_get_mode(kekcipher) != EVP_CIPH_WRAP_MODE) + return 0; + kekcipher_name = EVP_CIPHER_get0_name(kekcipher); + goto enc; + } + } + /* * Pick a cipher based on content encryption cipher. If it is DES3 use * DES3 wrap otherwise use AES wrap similar to key size. */ #ifndef OPENSSL_NO_DES - if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc) - kekcipher = EVP_des_ede3_wrap(); + if (EVP_CIPHER_get_type(cipher) == NID_des_ede3_cbc) + kekcipher_name = SN_id_smime_alg_CMS3DESwrap; else #endif if (keylen <= 16) - kekcipher = EVP_aes_128_wrap(); + kekcipher_name = SN_id_aes128_wrap; else if (keylen <= 24) - kekcipher = EVP_aes_192_wrap(); + kekcipher_name = SN_id_aes192_wrap; else - kekcipher = EVP_aes_256_wrap(); - return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL); + kekcipher_name = SN_id_aes256_wrap; +enc: + fetched_kekcipher = EVP_CIPHER_fetch(ossl_cms_ctx_get0_libctx(cms_ctx), + kekcipher_name, + ossl_cms_ctx_get0_propq(cms_ctx)); + if (fetched_kekcipher == NULL) + return 0; + ret = EVP_EncryptInit_ex(ctx, fetched_kekcipher, NULL, NULL, NULL); + EVP_CIPHER_free(fetched_kekcipher); + return ret; } /* Encrypt content key in key agreement recipient info */ -int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri) +int ossl_cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms, + CMS_RecipientInfo *ri) { CMS_KeyAgreeRecipientInfo *kari; CMS_EncryptedContentInfo *ec; @@ -373,12 +483,12 @@ int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, int i; if (ri->type != CMS_RECIPINFO_AGREE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT); return 0; } kari = ri->d.kari; reks = kari->recipientEncryptedKeys; - ec = cms->d.envelopedData->encryptedContentInfo; + ec = ossl_cms_get0_env_enc_content(cms); /* Initialise wrap algorithm parameters */ if (!cms_wrap_init(kari, ec->cipher)) return 0; @@ -394,7 +504,7 @@ int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, return 0; } /* Initialise KDF algorithm */ - if (!cms_env_asn1_ctrl(ri, 0)) + if (!ossl_cms_env_asn1_ctrl(ri, 0)) return 0; /* For each rek, derive KEK, encrypt CEK */ for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { @@ -410,5 +520,4 @@ int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, } return 1; - } diff --git a/crypto/openssl/crypto/cms/cms_lib.c b/crypto/openssl/crypto/cms/cms_lib.c index be4c2c703f1a..1fd542d2375c 100644 --- a/crypto/openssl/crypto/cms/cms_lib.c +++ b/crypto/openssl/crypto/cms/cms_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,20 +14,119 @@ #include #include #include +#include +#include "internal/sizes.h" +#include "crypto/x509.h" #include "cms_local.h" -IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo) +static STACK_OF(CMS_CertificateChoices) +**cms_get0_certificate_choices(CMS_ContentInfo *cms); + IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo) +CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a, + const unsigned char **in, long len) +{ + CMS_ContentInfo *ci; + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(a == NULL ? NULL : *a); + + ci = (CMS_ContentInfo *)ASN1_item_d2i_ex((ASN1_VALUE **)a, in, len, + (CMS_ContentInfo_it()), + ossl_cms_ctx_get0_libctx(ctx), + ossl_cms_ctx_get0_propq(ctx)); + if (ci != NULL) { + ERR_set_mark(); + ossl_cms_resolve_libctx(ci); + ERR_pop_to_mark(); + } + return ci; +} + +int i2d_CMS_ContentInfo(const CMS_ContentInfo *a, unsigned char **out) +{ + return ASN1_item_i2d((const ASN1_VALUE *)a, out, (CMS_ContentInfo_it())); +} + +CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq) +{ + CMS_ContentInfo *ci; + + ci = (CMS_ContentInfo *)ASN1_item_new_ex(ASN1_ITEM_rptr(CMS_ContentInfo), + libctx, propq); + if (ci != NULL) { + ci->ctx.libctx = libctx; + ci->ctx.propq = NULL; + if (propq != NULL) { + ci->ctx.propq = OPENSSL_strdup(propq); + if (ci->ctx.propq == NULL) { + CMS_ContentInfo_free(ci); + ci = NULL; + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + } + } + } + return ci; +} + +CMS_ContentInfo *CMS_ContentInfo_new(void) +{ + return CMS_ContentInfo_new_ex(NULL, NULL); +} + +void CMS_ContentInfo_free(CMS_ContentInfo *cms) +{ + if (cms != NULL) { + OPENSSL_free(cms->ctx.propq); + ASN1_item_free((ASN1_VALUE *)cms, ASN1_ITEM_rptr(CMS_ContentInfo)); + } +} + +const CMS_CTX *ossl_cms_get0_cmsctx(const CMS_ContentInfo *cms) +{ + return cms != NULL ? &cms->ctx : NULL; +} + +OSSL_LIB_CTX *ossl_cms_ctx_get0_libctx(const CMS_CTX *ctx) +{ + return ctx != NULL ? ctx->libctx : NULL; +} + +const char *ossl_cms_ctx_get0_propq(const CMS_CTX *ctx) +{ + return ctx != NULL ? ctx->propq : NULL; +} + +void ossl_cms_resolve_libctx(CMS_ContentInfo *ci) +{ + int i; + CMS_CertificateChoices *cch; + STACK_OF(CMS_CertificateChoices) **pcerts; + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(ci); + OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx); + const char *propq = ossl_cms_ctx_get0_propq(ctx); + + ossl_cms_SignerInfos_set_cmsctx(ci); + ossl_cms_RecipientInfos_set_cmsctx(ci); + + pcerts = cms_get0_certificate_choices(ci); + if (pcerts != NULL) { + for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { + cch = sk_CMS_CertificateChoices_value(*pcerts, i); + if (cch->type == CMS_CERTCHOICE_CERT) + ossl_x509_set0_libctx(cch->d.certificate, libctx, propq); + } + } +} + const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms) { return cms->contentType; } -CMS_ContentInfo *cms_Data_create(void) +CMS_ContentInfo *ossl_cms_Data_create(OSSL_LIB_CTX *libctx, const char *propq) { - CMS_ContentInfo *cms; - cms = CMS_ContentInfo_new(); + CMS_ContentInfo *cms = CMS_ContentInfo_new_ex(libctx, propq); + if (cms != NULL) { cms->contentType = OBJ_nid2obj(NID_pkcs7_data); /* Never detached */ @@ -36,18 +135,19 @@ CMS_ContentInfo *cms_Data_create(void) return cms; } -BIO *cms_content_bio(CMS_ContentInfo *cms) +BIO *ossl_cms_content_bio(CMS_ContentInfo *cms) { ASN1_OCTET_STRING **pos = CMS_get0_content(cms); - if (!pos) + + if (pos == NULL) return NULL; /* If content detached data goes nowhere: create NULL BIO */ - if (!*pos) + if (*pos == NULL) return BIO_new(BIO_s_null()); /* * If content not detached and created return memory BIO */ - if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT)) + if (*pos == NULL || ((*pos)->flags == ASN1_STRING_FLAG_CONT)) return BIO_new(BIO_s_mem()); /* Else content was read in: return read only BIO for it */ return BIO_new_mem_buf((*pos)->data, (*pos)->length); @@ -59,9 +159,9 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) if (icont) cont = icont; else - cont = cms_content_bio(cms); + cont = ossl_cms_content_bio(cms); if (!cont) { - CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT); return NULL; } switch (OBJ_obj2nid(cms->contentType)) { @@ -70,34 +170,37 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) return cont; case NID_pkcs7_signed: - cmsbio = cms_SignedData_init_bio(cms); + cmsbio = ossl_cms_SignedData_init_bio(cms); break; case NID_pkcs7_digest: - cmsbio = cms_DigestedData_init_bio(cms); + cmsbio = ossl_cms_DigestedData_init_bio(cms); break; #ifdef ZLIB case NID_id_smime_ct_compressedData: - cmsbio = cms_CompressedData_init_bio(cms); + cmsbio = ossl_cms_CompressedData_init_bio(cms); break; #endif case NID_pkcs7_encrypted: - cmsbio = cms_EncryptedData_init_bio(cms); + cmsbio = ossl_cms_EncryptedData_init_bio(cms); break; case NID_pkcs7_enveloped: - cmsbio = cms_EnvelopedData_init_bio(cms); + cmsbio = ossl_cms_EnvelopedData_init_bio(cms); + break; + + case NID_id_smime_ct_authEnvelopedData: + cmsbio = ossl_cms_AuthEnvelopedData_init_bio(cms); break; default: - CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_TYPE); goto err; } if (cmsbio) return BIO_push(cmsbio, cont); - err: if (!icont) BIO_free(cont); @@ -105,10 +208,12 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) } +/* unfortunately cannot constify SMIME_write_ASN1() due to this function */ int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) { ASN1_OCTET_STRING **pos = CMS_get0_content(cms); - if (!pos) + + if (pos == NULL) return 0; /* If embedded content find memory BIO and set content */ if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) { @@ -117,7 +222,7 @@ int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) long contlen; mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); if (!mbio) { - CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND); + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_NOT_FOUND); return 0; } contlen = BIO_get_mem_data(mbio, &cont); @@ -131,20 +236,25 @@ int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) switch (OBJ_obj2nid(cms->contentType)) { case NID_pkcs7_data: - case NID_pkcs7_enveloped: case NID_pkcs7_encrypted: case NID_id_smime_ct_compressedData: /* Nothing to do */ return 1; + case NID_pkcs7_enveloped: + return ossl_cms_EnvelopedData_final(cms, cmsbio); + + case NID_id_smime_ct_authEnvelopedData: + return ossl_cms_AuthEnvelopedData_final(cms, cmsbio); + case NID_pkcs7_signed: - return cms_SignedData_final(cms, cmsbio); + return ossl_cms_SignedData_final(cms, cmsbio); case NID_pkcs7_digest: - return cms_DigestedData_do_final(cms, cmsbio, 0); + return ossl_cms_DigestedData_do_final(cms, cmsbio, 0); default: - CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_TYPE); return 0; } } @@ -173,6 +283,10 @@ ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms) case NID_pkcs7_encrypted: return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; + case NID_id_smime_ct_authEnvelopedData: + return &cms->d.authEnvelopedData->authEncryptedContentInfo + ->encryptedContent; + case NID_id_smime_ct_authData: return &cms->d.authenticatedData->encapContentInfo->eContent; @@ -182,7 +296,7 @@ ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms) default: if (cms->d.other->type == V_ASN1_OCTET_STRING) return &cms->d.other->value.octet_string; - CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE); return NULL; } @@ -209,6 +323,9 @@ static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms) case NID_pkcs7_encrypted: return &cms->d.encryptedData->encryptedContentInfo->contentType; + case NID_id_smime_ct_authEnvelopedData: + return &cms->d.authEnvelopedData->authEncryptedContentInfo + ->contentType; case NID_id_smime_ct_authData: return &cms->d.authenticatedData->encapContentInfo->eContentType; @@ -216,7 +333,7 @@ static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms) return &cms->d.compressedData->encapContentInfo->eContentType; default: - CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, CMS_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE); return NULL; } @@ -234,13 +351,14 @@ const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms) int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) { ASN1_OBJECT **petype, *etype; + petype = cms_get0_econtent_type(cms); - if (!petype) + if (petype == NULL) return 0; - if (!oid) + if (oid == NULL) return 1; etype = OBJ_dup(oid); - if (!etype) + if (etype == NULL) return 0; ASN1_OBJECT_free(*petype); *petype = etype; @@ -250,10 +368,11 @@ int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) int CMS_is_detached(CMS_ContentInfo *cms) { ASN1_OCTET_STRING **pos; + pos = CMS_get0_content(cms); - if (!pos) + if (pos == NULL) return -1; - if (*pos) + if (*pos != NULL) return 0; return 1; } @@ -261,8 +380,9 @@ int CMS_is_detached(CMS_ContentInfo *cms) int CMS_set_detached(CMS_ContentInfo *cms, int detached) { ASN1_OCTET_STRING **pos; + pos = CMS_get0_content(cms); - if (!pos) + if (pos == NULL) return 0; if (detached) { ASN1_OCTET_STRING_free(*pos); @@ -278,39 +398,56 @@ int CMS_set_detached(CMS_ContentInfo *cms, int detached) (*pos)->flags |= ASN1_STRING_FLAG_CONT; return 1; } - CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return 0; } /* Create a digest BIO from an X509_ALGOR structure */ -BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) +BIO *ossl_cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm, + const CMS_CTX *ctx) { BIO *mdbio = NULL; const ASN1_OBJECT *digestoid; - const EVP_MD *digest; + const EVP_MD *digest = NULL; + EVP_MD *fetched_digest = NULL; + char alg[OSSL_MAX_NAME_SIZE]; + X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); - digest = EVP_get_digestbyobj(digestoid); - if (!digest) { - CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, - CMS_R_UNKNOWN_DIGEST_ALGORITHM); + OBJ_obj2txt(alg, sizeof(alg), digestoid, 0); + + (void)ERR_set_mark(); + fetched_digest = EVP_MD_fetch(ossl_cms_ctx_get0_libctx(ctx), alg, + ossl_cms_ctx_get0_propq(ctx)); + + if (fetched_digest != NULL) + digest = fetched_digest; + else + digest = EVP_get_digestbyobj(digestoid); + if (digest == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_DIGEST_ALGORITHM); goto err; } + (void)ERR_pop_to_mark(); + mdbio = BIO_new(BIO_f_md()); if (mdbio == NULL || !BIO_set_md(mdbio, digest)) { - CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_MD_BIO_INIT_ERROR); goto err; } + EVP_MD_free(fetched_digest); return mdbio; err: + EVP_MD_free(fetched_digest); BIO_free(mdbio); return NULL; } /* Locate a message digest content from a BIO chain based on SignerInfo */ -int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, - X509_ALGOR *mdalg) +int ossl_cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, + X509_ALGOR *mdalg) { int nid; const ASN1_OBJECT *mdoid; @@ -321,17 +458,16 @@ int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, EVP_MD_CTX *mtmp; chain = BIO_find_type(chain, BIO_TYPE_MD); if (chain == NULL) { - CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, - CMS_R_NO_MATCHING_DIGEST); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_DIGEST); return 0; } BIO_get_md_ctx(chain, &mtmp); - if (EVP_MD_CTX_type(mtmp) == nid + if (EVP_MD_CTX_get_type(mtmp) == nid /* * Workaround for broken implementations that use signature * algorithm OID instead of digest. */ - || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) + || EVP_MD_get_pkey_type(EVP_MD_CTX_get0_md(mtmp)) == nid) return EVP_MD_CTX_copy_ex(mctx, mtmp); chain = BIO_next(chain); } @@ -350,9 +486,13 @@ static STACK_OF(CMS_CertificateChoices) return NULL; return &cms->d.envelopedData->originatorInfo->certificates; + case NID_id_smime_ct_authEnvelopedData: + if (cms->d.authEnvelopedData->originatorInfo == NULL) + return NULL; + return &cms->d.authEnvelopedData->originatorInfo->certificates; + default: - CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES, - CMS_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE); return NULL; } @@ -362,12 +502,13 @@ CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms) { STACK_OF(CMS_CertificateChoices) **pcerts; CMS_CertificateChoices *cch; + pcerts = cms_get0_certificate_choices(cms); - if (!pcerts) + if (pcerts == NULL) return NULL; - if (!*pcerts) + if (*pcerts == NULL) *pcerts = sk_CMS_CertificateChoices_new_null(); - if (!*pcerts) + if (*pcerts == NULL) return NULL; cch = M_ASN1_new_of(CMS_CertificateChoices); if (!cch) @@ -384,15 +525,15 @@ int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) CMS_CertificateChoices *cch; STACK_OF(CMS_CertificateChoices) **pcerts; int i; + pcerts = cms_get0_certificate_choices(cms); - if (!pcerts) + if (pcerts == NULL) return 0; for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { cch = sk_CMS_CertificateChoices_value(*pcerts, i); if (cch->type == CMS_CERTCHOICE_CERT) { if (!X509_cmp(cch->d.certificate, cert)) { - CMSerr(CMS_F_CMS_ADD0_CERT, - CMS_R_CERTIFICATE_ALREADY_PRESENT); + ERR_raise(ERR_LIB_CMS, CMS_R_CERTIFICATE_ALREADY_PRESENT); return 0; } } @@ -427,9 +568,13 @@ static STACK_OF(CMS_RevocationInfoChoice) return NULL; return &cms->d.envelopedData->originatorInfo->crls; + case NID_id_smime_ct_authEnvelopedData: + if (cms->d.authEnvelopedData->originatorInfo == NULL) + return NULL; + return &cms->d.authEnvelopedData->originatorInfo->crls; + default: - CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES, - CMS_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE); return NULL; } @@ -439,15 +584,16 @@ CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) { STACK_OF(CMS_RevocationInfoChoice) **pcrls; CMS_RevocationInfoChoice *rch; + pcrls = cms_get0_revocation_choices(cms); - if (!pcrls) + if (pcrls == NULL) return NULL; - if (!*pcrls) + if (*pcrls == NULL) *pcrls = sk_CMS_RevocationInfoChoice_new_null(); - if (!*pcrls) + if (*pcrls == NULL) return NULL; rch = M_ASN1_new_of(CMS_RevocationInfoChoice); - if (!rch) + if (rch == NULL) return NULL; if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) { M_ASN1_free_of(rch, CMS_RevocationInfoChoice); @@ -482,22 +628,18 @@ STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) CMS_CertificateChoices *cch; STACK_OF(CMS_CertificateChoices) **pcerts; int i; + pcerts = cms_get0_certificate_choices(cms); - if (!pcerts) + if (pcerts == NULL) return NULL; for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { cch = sk_CMS_CertificateChoices_value(*pcerts, i); if (cch->type == 0) { - if (!certs) { - certs = sk_X509_new_null(); - if (!certs) - return NULL; - } - if (!sk_X509_push(certs, cch->d.certificate)) { + if (!ossl_x509_add_cert_new(&certs, cch->d.certificate, + X509_ADD_FLAG_UP_REF)) { sk_X509_pop_free(certs, X509_free); return NULL; } - X509_up_ref(cch->d.certificate); } } return certs; @@ -510,8 +652,9 @@ STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) STACK_OF(CMS_RevocationInfoChoice) **pcrls; CMS_RevocationInfoChoice *rch; int i; + pcrls = cms_get0_revocation_choices(cms); - if (!pcrls) + if (pcrls == NULL) return NULL; for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) { rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); @@ -531,16 +674,16 @@ STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) return crls; } -int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert) +int ossl_cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert) { int ret; ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert)); if (ret) return ret; - return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert)); + return ASN1_INTEGER_cmp(ias->serialNumber, X509_get0_serialNumber(cert)); } -int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert) +int ossl_cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert) { const ASN1_OCTET_STRING *cert_keyid = X509_get0_subject_key_id(cert); @@ -549,7 +692,7 @@ int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert) return ASN1_OCTET_STRING_cmp(keyid, cert_keyid); } -int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert) +int ossl_cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert) { CMS_IssuerAndSerialNumber *ias; ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber); @@ -557,29 +700,29 @@ int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert) goto err; if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert))) goto err; - if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert))) + if (!ASN1_STRING_copy(ias->serialNumber, X509_get0_serialNumber(cert))) goto err; M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber); *pias = ias; return 1; err: M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber); - CMSerr(CMS_F_CMS_SET1_IAS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return 0; } -int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert) +int ossl_cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert) { ASN1_OCTET_STRING *keyid = NULL; const ASN1_OCTET_STRING *cert_keyid; cert_keyid = X509_get0_subject_key_id(cert); if (cert_keyid == NULL) { - CMSerr(CMS_F_CMS_SET1_KEYID, CMS_R_CERTIFICATE_HAS_NO_KEYID); + ERR_raise(ERR_LIB_CMS, CMS_R_CERTIFICATE_HAS_NO_KEYID); return 0; } keyid = ASN1_STRING_dup(cert_keyid); if (!keyid) { - CMSerr(CMS_F_CMS_SET1_KEYID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return 0; } ASN1_OCTET_STRING_free(*pkeyid); diff --git a/crypto/openssl/crypto/cms/cms_local.h b/crypto/openssl/crypto/cms/cms_local.h index a0ce4448f603..15b4a29ce03d 100644 --- a/crypto/openssl/crypto/cms/cms_local.h +++ b/crypto/openssl/crypto/cms/cms_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -29,6 +29,7 @@ typedef struct CMS_EnvelopedData_st CMS_EnvelopedData; typedef struct CMS_DigestedData_st CMS_DigestedData; typedef struct CMS_EncryptedData_st CMS_EncryptedData; typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData; +typedef struct CMS_AuthEnvelopedData_st CMS_AuthEnvelopedData; typedef struct CMS_CompressedData_st CMS_CompressedData; typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat; typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo; @@ -43,6 +44,12 @@ typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo; typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo; typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo; typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom; +typedef struct CMS_CTX_st CMS_CTX; + +struct CMS_CTX_st { + OSSL_LIB_CTX *libctx; + char *propq; +}; struct CMS_ContentInfo_st { ASN1_OBJECT *contentType; @@ -52,12 +59,14 @@ struct CMS_ContentInfo_st { CMS_EnvelopedData *envelopedData; CMS_DigestedData *digestedData; CMS_EncryptedData *encryptedData; + CMS_AuthEnvelopedData *authEnvelopedData; CMS_AuthenticatedData *authenticatedData; CMS_CompressedData *compressedData; ASN1_TYPE *other; /* Other types ... */ void *otherData; } d; + CMS_CTX ctx; }; DEFINE_STACK_OF(CMS_CertificateChoices) @@ -92,6 +101,7 @@ struct CMS_SignerInfo_st { /* Digest and public key context for alternative parameters */ EVP_MD_CTX *mctx; EVP_PKEY_CTX *pctx; + const CMS_CTX *cms_ctx; }; struct CMS_SignerIdentifier_st { @@ -119,10 +129,12 @@ struct CMS_EncryptedContentInfo_st { ASN1_OBJECT *contentType; X509_ALGOR *contentEncryptionAlgorithm; ASN1_OCTET_STRING *encryptedContent; - /* Content encryption algorithm and key */ + /* Content encryption algorithm, key and tag */ const EVP_CIPHER *cipher; unsigned char *key; size_t keylen; + unsigned char *tag; + size_t taglen; /* 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 */ @@ -152,6 +164,7 @@ struct CMS_KeyTransRecipientInfo_st { EVP_PKEY *pkey; /* Public key context for this operation */ EVP_PKEY_CTX *pctx; + const CMS_CTX *cms_ctx; }; struct CMS_KeyAgreeRecipientInfo_st { @@ -164,6 +177,7 @@ struct CMS_KeyAgreeRecipientInfo_st { EVP_PKEY_CTX *pctx; /* Cipher context for CEK wrapping */ EVP_CIPHER_CTX *ctx; + const CMS_CTX *cms_ctx; }; struct CMS_OriginatorIdentifierOrKey_st { @@ -209,6 +223,7 @@ struct CMS_KEKRecipientInfo_st { /* Extra info: symmetric key to use */ unsigned char *key; size_t keylen; + const CMS_CTX *cms_ctx; }; struct CMS_KEKIdentifier_st { @@ -225,6 +240,7 @@ struct CMS_PasswordRecipientInfo_st { /* Extra info: password to use */ unsigned char *pass; size_t passlen; + const CMS_CTX *cms_ctx; }; struct CMS_OtherRecipientInfo_st { @@ -257,6 +273,16 @@ struct CMS_AuthenticatedData_st { STACK_OF(X509_ATTRIBUTE) *unauthAttrs; }; +struct CMS_AuthEnvelopedData_st { + int32_t version; + CMS_OriginatorInfo *originatorInfo; + STACK_OF(CMS_RecipientInfo) *recipientInfos; + CMS_EncryptedContentInfo *authEncryptedContentInfo; + STACK_OF(X509_ATTRIBUTE) *authAttrs; + ASN1_OCTET_STRING *mac; + STACK_OF(X509_ATTRIBUTE) *unauthAttrs; +}; + struct CMS_CompressedData_st { int32_t version; X509_ALGOR *compressionAlgorithm; @@ -362,66 +388,105 @@ DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber) # define CMS_OIK_KEYIDENTIFIER 1 # define CMS_OIK_PUBKEY 2 -BIO *cms_content_bio(CMS_ContentInfo *cms); - -CMS_ContentInfo *cms_Data_create(void); - -CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md); -BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms); -int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify); - -BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms); -int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain); -int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, - int type); -int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, - ASN1_OCTET_STRING **keyid, - X509_NAME **issuer, - ASN1_INTEGER **sno); -int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert); - -CMS_ContentInfo *cms_CompressedData_create(int comp_nid); -BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms); - -BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm); -int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, - X509_ALGOR *mdalg); - -int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert); -int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert); -int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert); -int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert); - -BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec); -BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms); -int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, - const EVP_CIPHER *cipher, - const unsigned char *key, size_t keylen); - -int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms); -int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src); -ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si); - -BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); -CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms); -int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd); -int cms_pkey_get_ri_type(EVP_PKEY *pk); +BIO *ossl_cms_content_bio(CMS_ContentInfo *cms); +const CMS_CTX *ossl_cms_get0_cmsctx(const CMS_ContentInfo *cms); +OSSL_LIB_CTX *ossl_cms_ctx_get0_libctx(const CMS_CTX *ctx); +const char *ossl_cms_ctx_get0_propq(const CMS_CTX *ctx); +void ossl_cms_resolve_libctx(CMS_ContentInfo *ci); + +CMS_ContentInfo *ossl_cms_Data_create(OSSL_LIB_CTX *ctx, const char *propq); + +CMS_ContentInfo *ossl_cms_DigestedData_create(const EVP_MD *md, + OSSL_LIB_CTX *libctx, + const char *propq); +BIO *ossl_cms_DigestedData_init_bio(const CMS_ContentInfo *cms); +int ossl_cms_DigestedData_do_final(const CMS_ContentInfo *cms, + BIO *chain, int verify); + +BIO *ossl_cms_SignedData_init_bio(CMS_ContentInfo *cms); +int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain); +int ossl_cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, + int type, const CMS_CTX *ctx); +int ossl_cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); +int ossl_cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert); + +CMS_ContentInfo *ossl_cms_CompressedData_create(int comp_nid, + OSSL_LIB_CTX *libctx, + const char *propq); +BIO *ossl_cms_CompressedData_init_bio(const CMS_ContentInfo *cms); + +BIO *ossl_cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm, + const CMS_CTX *ctx); +int ossl_cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, + X509_ALGOR *mdalg); + +int ossl_cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert); +int ossl_cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert); +int ossl_cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert); +int ossl_cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert); + +BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, + const CMS_CTX *ctx); +BIO *ossl_cms_EncryptedData_init_bio(const CMS_ContentInfo *cms); +int ossl_cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, + const EVP_CIPHER *cipher, + const unsigned char *key, size_t keylen, + const CMS_CTX *ctx); + +int ossl_cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms); +int ossl_cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src); +ASN1_OCTET_STRING *ossl_cms_encode_Receipt(CMS_SignerInfo *si); + +BIO *ossl_cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); +int ossl_cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain); +BIO *ossl_cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms); +int ossl_cms_AuthEnvelopedData_final(CMS_ContentInfo *cms, BIO *cmsbio); +CMS_EnvelopedData *ossl_cms_get0_enveloped(CMS_ContentInfo *cms); +CMS_AuthEnvelopedData *ossl_cms_get0_auth_enveloped(CMS_ContentInfo *cms); +CMS_EncryptedContentInfo *ossl_cms_get0_env_enc_content(const CMS_ContentInfo *cms); + +/* RecipientInfo routines */ +int ossl_cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd); +int ossl_cms_pkey_get_ri_type(EVP_PKEY *pk); +int ossl_cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type); + +void ossl_cms_RecipientInfos_set_cmsctx(CMS_ContentInfo *cms); + /* KARI routines */ -int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, - EVP_PKEY *pk, unsigned int flags); -int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri); +int ossl_cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, + EVP_PKEY *recipPubKey, X509 *originator, + EVP_PKEY *originatorPrivKey, + unsigned int flags, + const CMS_CTX *ctx); +int ossl_cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms, + CMS_RecipientInfo *ri); /* PWRI routines */ -int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, - int en_de); +int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, int en_de); /* SignerInfo routines */ -int CMS_si_check_attributes(const CMS_SignerInfo *si); +int ossl_cms_si_check_attributes(const CMS_SignerInfo *si); +void ossl_cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms); + + +/* ESS routines */ +int ossl_cms_check_signing_certs(const CMS_SignerInfo *si, + const STACK_OF(X509) *chain); + +int ossl_cms_dh_envelope(CMS_RecipientInfo *ri, int decrypt); +int ossl_cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt); +int ossl_cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt); +int ossl_cms_ecdsa_dsa_sign(CMS_SignerInfo *si, int verify); +int ossl_cms_rsa_sign(CMS_SignerInfo *si, int verify); DECLARE_ASN1_ITEM(CMS_CertificateChoices) DECLARE_ASN1_ITEM(CMS_DigestedData) DECLARE_ASN1_ITEM(CMS_EncryptedData) DECLARE_ASN1_ITEM(CMS_EnvelopedData) +DECLARE_ASN1_ITEM(CMS_AuthEnvelopedData) DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) DECLARE_ASN1_ITEM(CMS_KeyAgreeRecipientInfo) DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) diff --git a/crypto/openssl/crypto/cms/cms_pwri.c b/crypto/openssl/crypto/cms/cms_pwri.c index d7414883396c..2373092bed55 100644 --- a/crypto/openssl/crypto/cms/cms_pwri.c +++ b/crypto/openssl/crypto/cms/cms_pwri.c @@ -1,7 +1,7 @@ /* - * Copyright 2009-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2009-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,15 +15,16 @@ #include #include #include -#include "cms_local.h" +#include "internal/sizes.h" #include "crypto/asn1.h" +#include "cms_local.h" int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, unsigned char *pass, ossl_ssize_t passlen) { CMS_PasswordRecipientInfo *pwri; if (ri->type != CMS_RECIPINFO_PASS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_PWRI); return 0; } @@ -42,16 +43,21 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, ossl_ssize_t passlen, const EVP_CIPHER *kekciph) { + STACK_OF(CMS_RecipientInfo) *ris; CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; + CMS_EncryptedContentInfo *ec; CMS_PasswordRecipientInfo *pwri; EVP_CIPHER_CTX *ctx = NULL; X509_ALGOR *encalg = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; int ivlen; + const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms); - env = cms_get0_enveloped(cms); - if (!env) + ec = ossl_cms_get0_env_enc_content(cms); + if (ec == NULL) + return NULL; + ris = CMS_get0_RecipientInfos(cms); + if (ris == NULL) return NULL; if (wrap_nid <= 0) @@ -62,15 +68,14 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, /* Get from enveloped data */ if (kekciph == NULL) - kekciph = env->encryptedContentInfo->cipher; + kekciph = ec->cipher; if (kekciph == NULL) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_CIPHER); return NULL; } if (wrap_nid != NID_id_alg_PWRI_KEK) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, - CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); return NULL; } @@ -80,34 +85,41 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, goto merr; } ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + goto err; + } if (EVP_EncryptInit_ex(ctx, kekciph, NULL, NULL, NULL) <= 0) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); goto err; } - ivlen = EVP_CIPHER_CTX_iv_length(ctx); + ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); + if (ivlen < 0) { + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); + goto err; + } if (ivlen > 0) { - if (RAND_bytes(iv, ivlen) <= 0) + if (RAND_bytes_ex(ossl_cms_ctx_get0_libctx(cms_ctx), iv, ivlen, 0) <= 0) goto err; if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); goto err; } encalg->parameter = ASN1_TYPE_new(); if (!encalg->parameter) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, - CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } } - encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); + encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_get_type(ctx)); EVP_CIPHER_CTX_free(ctx); ctx = NULL; @@ -123,6 +135,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, ri->type = CMS_RECIPINFO_PASS; pwri = ri->d.pwri; + pwri->cms_ctx = cms_ctx; /* Since this is overwritten, free up empty structure already there */ X509_ALGOR_free(pwri->keyEncryptionAlgorithm); pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); @@ -146,19 +159,19 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1); - if (!pwri->keyDerivationAlgorithm) + if (pwri->keyDerivationAlgorithm == NULL) goto err; CMS_RecipientInfo_set0_password(ri, pass, passlen); pwri->version = 0; - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + if (!sk_CMS_RecipientInfo_push(ris, ri)) goto merr; return ri; merr: - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: EVP_CIPHER_CTX_free(ctx); if (ri) @@ -177,7 +190,7 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx) { - size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); + size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx); unsigned char *tmp; int outl, rv = 0; if (inlen < 2 * blocklen) { @@ -189,7 +202,7 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen, return 0; } if ((tmp = OPENSSL_malloc(inlen)) == NULL) { - CMSerr(CMS_F_KEK_UNWRAP_KEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return 0; } /* setup IV by decrypting last two blocks */ @@ -230,9 +243,9 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen, static int kek_wrap_key(unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen, - EVP_CIPHER_CTX *ctx) + EVP_CIPHER_CTX *ctx, const CMS_CTX *cms_ctx) { - size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); + size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx); size_t olen; int dummy; /* @@ -258,7 +271,8 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen, memcpy(out + 4, in, inlen); /* Add random padding to end */ if (olen > inlen + 4 - && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0) + && RAND_bytes_ex(ossl_cms_ctx_get0_libctx(cms_ctx), out + 4 + inlen, + olen - 4 - inlen, 0) <= 0) return 0; /* Encrypt twice */ if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen) @@ -273,31 +287,32 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen, /* Encrypt/Decrypt content key in PWRI recipient info */ -int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, - int en_de) +int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, int en_de) { CMS_EncryptedContentInfo *ec; CMS_PasswordRecipientInfo *pwri; int r = 0; X509_ALGOR *algtmp, *kekalg = NULL; EVP_CIPHER_CTX *kekctx = NULL; - const EVP_CIPHER *kekcipher; + char name[OSSL_MAX_NAME_SIZE]; + EVP_CIPHER *kekcipher; unsigned char *key = NULL; size_t keylen; + const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms); - ec = cms->d.envelopedData->encryptedContentInfo; + ec = ossl_cms_get0_env_enc_content(cms); pwri = ri->d.pwri; - if (!pwri->pass) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD); + if (pwri->pass == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_NO_PASSWORD); return 0; } algtmp = pwri->keyEncryptionAlgorithm; if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, - CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); return 0; } @@ -305,30 +320,30 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, algtmp->parameter); if (kekalg == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, - CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); + ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); return 0; } - kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); + OBJ_obj2txt(name, sizeof(name), kekalg->algorithm, 0); + kekcipher = EVP_CIPHER_fetch(ossl_cms_ctx_get0_libctx(cms_ctx), name, + ossl_cms_ctx_get0_propq(cms_ctx)); - if (!kekcipher) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER); - return 0; + if (kekcipher == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER); + goto err; } kekctx = EVP_CIPHER_CTX_new(); if (kekctx == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); - return 0; + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + goto err; } /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de)) goto err; EVP_CIPHER_CTX_set_padding(kekctx, 0); if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, - CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } @@ -339,7 +354,7 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, if (EVP_PBE_CipherInit(algtmp->algorithm, (char *)pwri->pass, pwri->passlen, algtmp->parameter, kekctx, en_de) < 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); goto err; } @@ -347,7 +362,7 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, if (en_de) { - if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx)) + if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx, cms_ctx)) goto err; key = OPENSSL_malloc(keylen); @@ -355,7 +370,7 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, if (key == NULL) goto err; - if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx)) + if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx, cms_ctx)) goto err; pwri->encryptedKey->data = key; pwri->encryptedKey->length = keylen; @@ -363,13 +378,13 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, key = OPENSSL_malloc(pwri->encryptedKey->length); if (key == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } if (!kek_unwrap_key(key, &keylen, pwri->encryptedKey->data, pwri->encryptedKey->length, kekctx)) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE); + ERR_raise(ERR_LIB_CMS, CMS_R_UNWRAP_FAILURE); goto err; } @@ -382,7 +397,7 @@ int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, r = 1; err: - + EVP_CIPHER_free(kekcipher); EVP_CIPHER_CTX_free(kekctx); if (!r) diff --git a/crypto/openssl/crypto/cms/cms_rsa.c b/crypto/openssl/crypto/cms/cms_rsa.c new file mode 100644 index 000000000000..997567fdbfac --- /dev/null +++ b/crypto/openssl/crypto/cms/cms_rsa.c @@ -0,0 +1,264 @@ +/* + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "crypto/asn1.h" +#include "crypto/rsa.h" +#include "cms_local.h" + +static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg) +{ + RSA_OAEP_PARAMS *oaep; + + oaep = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS), + alg->parameter); + + if (oaep == NULL) + return NULL; + + if (oaep->maskGenFunc != NULL) { + oaep->maskHash = ossl_x509_algor_mgf1_decode(oaep->maskGenFunc); + if (oaep->maskHash == NULL) { + RSA_OAEP_PARAMS_free(oaep); + return NULL; + } + } + return oaep; +} + +static int rsa_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pkctx; + X509_ALGOR *cmsalg; + int nid; + int rv = -1; + unsigned char *label = NULL; + int labellen = 0; + const EVP_MD *mgf1md = NULL, *md = NULL; + RSA_OAEP_PARAMS *oaep; + + pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (pkctx == NULL) + return 0; + if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) + return -1; + nid = OBJ_obj2nid(cmsalg->algorithm); + if (nid == NID_rsaEncryption) + return 1; + if (nid != NID_rsaesOaep) { + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE); + return -1; + } + /* Decode OAEP parameters */ + oaep = rsa_oaep_decode(cmsalg); + + if (oaep == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_OAEP_PARAMETERS); + goto err; + } + + mgf1md = ossl_x509_algor_get_md(oaep->maskHash); + if (mgf1md == NULL) + goto err; + md = ossl_x509_algor_get_md(oaep->hashFunc); + if (md == NULL) + goto err; + + if (oaep->pSourceFunc != NULL) { + X509_ALGOR *plab = oaep->pSourceFunc; + + if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_LABEL_SOURCE); + goto err; + } + if (plab->parameter->type != V_ASN1_OCTET_STRING) { + ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_LABEL); + goto err; + } + + label = plab->parameter->value.octet_string->data; + /* Stop label being freed when OAEP parameters are freed */ + plab->parameter->value.octet_string->data = NULL; + labellen = plab->parameter->value.octet_string->length; + } + + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) + goto err; + if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) + goto err; + if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) + goto err; + if (label != NULL + && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) + goto err; + /* Carry on */ + rv = 1; + + err: + RSA_OAEP_PARAMS_free(oaep); + return rv; +} + +static int rsa_cms_encrypt(CMS_RecipientInfo *ri) +{ + const EVP_MD *md, *mgf1md; + RSA_OAEP_PARAMS *oaep = NULL; + ASN1_STRING *os = NULL; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; + unsigned char *label; + + if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0) + return 0; + if (pkctx != NULL) { + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + } + if (pad_mode == RSA_PKCS1_PADDING) { + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return 1; + } + /* Not supported */ + if (pad_mode != RSA_PKCS1_OAEP_PADDING) + return 0; + if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) + goto err; + if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) + goto err; + labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); + if (labellen < 0) + goto err; + oaep = RSA_OAEP_PARAMS_new(); + if (oaep == NULL) + goto err; + if (!ossl_x509_algor_new_from_md(&oaep->hashFunc, md)) + goto err; + if (!ossl_x509_algor_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) + goto err; + if (labellen > 0) { + ASN1_OCTET_STRING *los; + + oaep->pSourceFunc = X509_ALGOR_new(); + if (oaep->pSourceFunc == NULL) + goto err; + los = ASN1_OCTET_STRING_new(); + if (los == NULL) + goto err; + if (!ASN1_OCTET_STRING_set(los, label, labellen)) { + ASN1_OCTET_STRING_free(los); + goto err; + } + X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), + V_ASN1_OCTET_STRING, los); + } + /* create string with pss parameter encoding. */ + if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) + goto err; + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); + os = NULL; + rv = 1; + err: + RSA_OAEP_PARAMS_free(oaep); + ASN1_STRING_free(os); + return rv; +} + +int ossl_cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt) +{ + assert(decrypt == 0 || decrypt == 1); + + if (decrypt == 1) + return rsa_cms_decrypt(ri); + + if (decrypt == 0) + return rsa_cms_encrypt(ri); + + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; +} + +static int rsa_cms_sign(CMS_SignerInfo *si) +{ + int pad_mode = RSA_PKCS1_PADDING; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + unsigned char aid[128]; + const unsigned char *pp = aid; + size_t aid_len = 0; + OSSL_PARAM params[2]; + + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + if (pkctx != NULL) { + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + } + if (pad_mode == RSA_PKCS1_PADDING) { + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return 1; + } + /* We don't support it */ + if (pad_mode != RSA_PKCS1_PSS_PADDING) + return 0; + + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_SIGNATURE_PARAM_ALGORITHM_ID, aid, sizeof(aid)); + params[1] = OSSL_PARAM_construct_end(); + + if (EVP_PKEY_CTX_get_params(pkctx, params) <= 0) + return 0; + if ((aid_len = params[0].return_size) == 0) + return 0; + if (d2i_X509_ALGOR(&alg, &pp, aid_len) == NULL) + return 0; + return 1; +} + +static int rsa_cms_verify(CMS_SignerInfo *si) +{ + int nid, nid2; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pkctx); + + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + nid = OBJ_obj2nid(alg->algorithm); + if (nid == EVP_PKEY_RSA_PSS) + return ossl_rsa_pss_to_ctx(NULL, pkctx, alg, NULL) > 0; + /* Only PSS allowed for PSS keys */ + if (EVP_PKEY_is_a(pkey, "RSA-PSS")) { + ERR_raise(ERR_LIB_RSA, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return 0; + } + if (nid == NID_rsaEncryption) + return 1; + /* Workaround for some implementation that use a signature OID */ + if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { + if (nid2 == NID_rsaEncryption) + return 1; + } + return 0; +} + +int ossl_cms_rsa_sign(CMS_SignerInfo *si, int verify) +{ + assert(verify == 0 || verify == 1); + + if (verify == 1) + return rsa_cms_verify(si); + + if (verify == 0) + return rsa_cms_sign(si); + + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; +} diff --git a/crypto/openssl/crypto/cms/cms_sd.c b/crypto/openssl/crypto/cms/cms_sd.c index 3f2a782565a8..34c021bba64a 100644 --- a/crypto/openssl/crypto/cms/cms_sd.c +++ b/crypto/openssl/crypto/cms/cms_sd.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,16 +14,20 @@ #include #include #include -#include "cms_local.h" +#include +#include "internal/sizes.h" #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/ess.h" +#include "crypto/x509.h" /* for ossl_x509_add_cert_new() */ +#include "cms_local.h" /* CMS SignedData Utilities */ static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms) { if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) { - CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); return NULL; } return cms->d.signedData; @@ -34,7 +38,7 @@ static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms) if (cms->d.other == NULL) { cms->d.signedData = M_ASN1_new_of(CMS_SignedData); if (!cms->d.signedData) { - CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return NULL; } cms->d.signedData->version = 1; @@ -58,6 +62,7 @@ int CMS_SignedData_init(CMS_ContentInfo *cms) return 0; } + /* Check structures and fixup version numbers (if necessary) */ static void cms_sd_set_version(CMS_SignedData *sd) @@ -137,9 +142,11 @@ static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) STACK_OF(CMS_SignerInfo) *sinfos; CMS_SignerInfo *sitmp; int i; + sinfos = CMS_get0_SignerInfos(cms); for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { ASN1_OCTET_STRING *messageDigest; + sitmp = sk_CMS_SignerInfo_value(sinfos, i); if (sitmp == si) continue; @@ -153,8 +160,7 @@ static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) (NID_pkcs9_messageDigest), -3, V_ASN1_OCTET_STRING); if (!messageDigest) { - CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, - CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); + ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); return 0; } @@ -165,25 +171,26 @@ static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) else return 0; } - CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_DIGEST); return 0; } -int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) +int ossl_cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, + int type, const CMS_CTX *ctx) { switch (type) { case CMS_SIGNERINFO_ISSUER_SERIAL: - if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert)) + if (!ossl_cms_set1_ias(&sid->d.issuerAndSerialNumber, cert)) return 0; break; case CMS_SIGNERINFO_KEYIDENTIFIER: - if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert)) + if (!ossl_cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert)) return 0; break; default: - CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID); + ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_ID); return 0; } @@ -192,10 +199,10 @@ int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) return 1; } -int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, - ASN1_OCTET_STRING **keyid, - X509_NAME **issuer, - ASN1_INTEGER **sno) +int ossl_cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno) { if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { if (issuer) @@ -210,12 +217,12 @@ int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, return 1; } -int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) +int ossl_cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) { if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) - return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert); + return ossl_cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert); else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) - return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert); + return ossl_cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert); else return -1; } @@ -224,20 +231,77 @@ static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd) { EVP_PKEY *pkey = si->pkey; int i; - if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + + if (EVP_PKEY_is_a(pkey, "DSA") || EVP_PKEY_is_a(pkey, "EC")) + return ossl_cms_ecdsa_dsa_sign(si, cmd); + else if (EVP_PKEY_is_a(pkey, "RSA") || EVP_PKEY_is_a(pkey, "RSA-PSS")) + return ossl_cms_rsa_sign(si, cmd); + + /* Something else? We'll give engines etc a chance to handle this */ + if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) return 1; i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si); if (i == -2) { - CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); return 0; } if (i <= 0) { - CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_CTRL_FAILURE); + ERR_raise(ERR_LIB_CMS, CMS_R_CTRL_FAILURE); return 0; } return 1; } +/* Add SigningCertificate signed attribute to the signer info. */ +static int ossl_cms_add1_signing_cert(CMS_SignerInfo *si, + const ESS_SIGNING_CERT *sc) +{ + ASN1_STRING *seq = NULL; + unsigned char *p, *pp = NULL; + int ret, len = i2d_ESS_SIGNING_CERT(sc, NULL); + + if (len <= 0 || (pp = OPENSSL_malloc(len)) == NULL) + return 0; + + p = pp; + i2d_ESS_SIGNING_CERT(sc, &p); + if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) { + ASN1_STRING_free(seq); + OPENSSL_free(pp); + return 0; + } + OPENSSL_free(pp); + ret = CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_signingCertificate, + V_ASN1_SEQUENCE, seq, -1); + ASN1_STRING_free(seq); + return ret; +} + +/* Add SigningCertificateV2 signed attribute to the signer info. */ +static int ossl_cms_add1_signing_cert_v2(CMS_SignerInfo *si, + const ESS_SIGNING_CERT_V2 *sc) +{ + ASN1_STRING *seq = NULL; + unsigned char *p, *pp = NULL; + int ret, len = i2d_ESS_SIGNING_CERT_V2(sc, NULL); + + if (len <= 0 || (pp = OPENSSL_malloc(len)) == NULL) + return 0; + + p = pp; + i2d_ESS_SIGNING_CERT_V2(sc, &p); + if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) { + ASN1_STRING_free(seq); + OPENSSL_free(pp); + return 0; + } + OPENSSL_free(pp); + ret = CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_signingCertificateV2, + V_ASN1_SEQUENCE, seq, -1); + ASN1_STRING_free(seq); + return ret; +} + CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, const EVP_MD *md, unsigned int flags) @@ -246,9 +310,10 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, CMS_SignerInfo *si = NULL; X509_ALGOR *alg; int i, type; + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); + if (!X509_check_private_key(signer, pk)) { - CMSerr(CMS_F_CMS_ADD1_SIGNER, - CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + ERR_raise(ERR_LIB_CMS, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); return NULL; } sd = cms_signed_data_init(cms); @@ -263,13 +328,14 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509_up_ref(signer); EVP_PKEY_up_ref(pk); + si->cms_ctx = ctx; si->pkey = pk; si->signer = signer; si->mctx = EVP_MD_CTX_new(); si->pctx = NULL; if (si->mctx == NULL) { - CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } @@ -283,7 +349,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, si->version = 1; } - if (!cms_set1_SignerIdentifier(si->sid, signer, type)) + if (!ossl_cms_set1_SignerIdentifier(si->sid, signer, type, ctx)) goto err; if (md == NULL) { @@ -292,13 +358,18 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, goto err; md = EVP_get_digestbynid(def_nid); if (md == NULL) { - CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_DEFAULT_DIGEST); goto err; } } if (!md) { - CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_DIGEST_SET); + goto err; + } + + if (md == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_NO_DIGEST_SET); goto err; } @@ -307,9 +378,12 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, /* See if digest is present in digestAlgorithms */ for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { const ASN1_OBJECT *aoid; + char name[OSSL_MAX_NAME_SIZE]; + alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); X509_ALGOR_get0(&aoid, NULL, NULL, alg); - if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) + OBJ_obj2txt(name, sizeof(name), aoid, 0); + if (EVP_MD_is_a(md, name)) break; } @@ -346,6 +420,27 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, if (!i) goto merr; } + if (flags & CMS_CADES) { + ESS_SIGNING_CERT *sc = NULL; + ESS_SIGNING_CERT_V2 *sc2 = NULL; + int add_sc; + + if (md == NULL || EVP_MD_is_a(md, SN_sha1)) { + if ((sc = OSSL_ESS_signing_cert_new_init(signer, + NULL, 1)) == NULL) + goto err; + add_sc = ossl_cms_add1_signing_cert(si, sc); + ESS_SIGNING_CERT_free(sc); + } else { + if ((sc2 = OSSL_ESS_signing_cert_v2_new_init(md, signer, + NULL, 1)) == NULL) + goto err; + add_sc = ossl_cms_add1_signing_cert_v2(si, sc2); + ESS_SIGNING_CERT_V2_free(sc2); + } + if (!add_sc) + goto err; + } if (flags & CMS_REUSE_DIGEST) { if (!cms_copy_messageDigest(cms, si)) goto err; @@ -365,16 +460,22 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, if (flags & CMS_KEY_PARAM) { if (flags & CMS_NOATTR) { - si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL); + si->pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx), + si->pkey, + ossl_cms_ctx_get0_propq(ctx)); if (si->pctx == NULL) goto err; if (EVP_PKEY_sign_init(si->pctx) <= 0) goto err; if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0) goto err; - } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <= - 0) + } else if (EVP_DigestSignInit_ex(si->mctx, &si->pctx, + EVP_MD_get0_name(md), + ossl_cms_ctx_get0_libctx(ctx), + ossl_cms_ctx_get0_propq(ctx), + pk, NULL) <= 0) { goto err; + } } if (!sd->signerInfos) @@ -385,23 +486,42 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, return si; merr: - CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: M_ASN1_free_of(si, CMS_SignerInfo); return NULL; } +void ossl_cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms) +{ + int i; + CMS_SignerInfo *si; + STACK_OF(CMS_SignerInfo) *sinfos; + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); + + ERR_set_mark(); + sinfos = CMS_get0_SignerInfos(cms); + ERR_pop_to_mark(); /* removes error in case sinfos == NULL */ + + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (si != NULL) + si->cms_ctx = ctx; + } +} + static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) { ASN1_TIME *tt; int r = 0; - if (t) + + if (t != NULL) tt = t; else tt = X509_gmtime_adj(NULL, 0); - if (!tt) + if (tt == NULL) goto merr; if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, @@ -409,14 +529,12 @@ static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) goto merr; r = 1; - merr: - - if (!t) + if (t == NULL) ASN1_TIME_free(tt); if (!r) - CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return r; @@ -434,11 +552,9 @@ EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si) STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms) { - CMS_SignedData *sd; - sd = cms_get0_signed(cms); - if (!sd) - return NULL; - return sd->signerInfos; + CMS_SignedData *sd = cms_get0_signed(cms); + + return sd != NULL ? sd->signerInfos : NULL; } STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) @@ -447,16 +563,13 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) STACK_OF(CMS_SignerInfo) *sinfos; CMS_SignerInfo *si; int i; + sinfos = CMS_get0_SignerInfos(cms); for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { si = sk_CMS_SignerInfo_value(sinfos, i); - if (si->signer) { - if (!signers) { - signers = sk_X509_new_null(); - if (!signers) - return NULL; - } - if (!sk_X509_push(signers, si->signer)) { + if (si->signer != NULL) { + if (!ossl_x509_add_cert_new(&signers, si->signer, + X509_ADD_FLAG_DEFAULT)) { sk_X509_free(signers); return NULL; } @@ -467,7 +580,7 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) { - if (signer) { + if (signer != NULL) { X509_up_ref(signer); EVP_PKEY_free(si->pkey); si->pkey = X509_get_pubkey(signer); @@ -480,12 +593,12 @@ int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno) { - return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); + return ossl_cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); } int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert) { - return cms_SignerIdentifier_cert_cmp(si->sid, cert); + return ossl_cms_SignerIdentifier_cert_cmp(si->sid, cert); } int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, @@ -498,13 +611,14 @@ int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, X509 *x; int i, j; int ret = 0; + sd = cms_get0_signed(cms); - if (!sd) + if (sd == NULL) return -1; certs = sd->certificates; for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { si = sk_CMS_SignerInfo_value(sd->signerInfos, i); - if (si->signer) + if (si->signer != NULL) continue; for (j = 0; j < sk_X509_num(scerts); j++) { @@ -516,7 +630,7 @@ int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, } } - if (si->signer || (flags & CMS_NOINTERN)) + if (si->signer != NULL || (flags & CMS_NOINTERN)) continue; for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) { @@ -538,13 +652,13 @@ void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, X509_ALGOR **pdig, X509_ALGOR **psig) { - if (pk) + if (pk != NULL) *pk = si->pkey; - if (signer) + if (signer != NULL) *signer = si->signer; - if (pdig) + if (pdig != NULL) *pdig = si->digestAlgorithm; - if (psig) + if (psig != NULL) *psig = si->signatureAlgorithm; } @@ -559,18 +673,19 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, EVP_MD_CTX *mctx = EVP_MD_CTX_new(); int r = 0; EVP_PKEY_CTX *pctx = NULL; + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); if (mctx == NULL) { - CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return 0; } - if (!si->pkey) { - CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY); + if (si->pkey == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_NO_PRIVATE_KEY); goto err; } - if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm)) + if (!ossl_cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm)) goto err; /* Set SignerInfo algorithm details if we used custom parameter */ if (si->pctx && !cms_sd_asn1_ctrl(si, 0)) @@ -583,6 +698,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, if (CMS_signed_get_attr_count(si) >= 0) { unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; + if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) goto err; if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, @@ -599,13 +715,14 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, size_t siglen; unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; + pctx = si->pctx; if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) goto err; - siglen = EVP_PKEY_size(si->pkey); + siglen = EVP_PKEY_get_size(si->pkey); sig = OPENSSL_malloc(siglen); if (sig == NULL) { - CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) { @@ -616,13 +733,16 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, } else { unsigned char *sig; unsigned int siglen; - sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey)); + + sig = OPENSSL_malloc(EVP_PKEY_get_size(si->pkey)); if (sig == NULL) { - CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } - if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) { - CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR); + if (!EVP_SignFinal_ex(mctx, sig, &siglen, si->pkey, + ossl_cms_ctx_get0_libctx(ctx), + ossl_cms_ctx_get0_propq(ctx))) { + ERR_raise(ERR_LIB_CMS, CMS_R_SIGNFINAL_ERROR); OPENSSL_free(sig); goto err; } @@ -638,11 +758,12 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, } -int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) +int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) { STACK_OF(CMS_SignerInfo) *sinfos; CMS_SignerInfo *si; int i; + sinfos = CMS_get0_SignerInfos(cms); for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { si = sk_CMS_SignerInfo_value(sinfos, i); @@ -660,10 +781,11 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) unsigned char *abuf = NULL; int alen; size_t siglen; - const EVP_MD *md = NULL; + const CMS_CTX *ctx = si->cms_ctx; + char md_name[OSSL_MAX_NAME_SIZE]; - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); - if (md == NULL) + if (OBJ_obj2txt(md_name, sizeof(md_name), + si->digestAlgorithm->algorithm, 0) <= 0) return 0; if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { @@ -671,24 +793,21 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) goto err; } - if (!CMS_si_check_attributes(si)) + if (!ossl_cms_si_check_attributes(si)) goto err; if (si->pctx) pctx = si->pctx; else { EVP_MD_CTX_reset(mctx); - if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0) + if (EVP_DigestSignInit_ex(mctx, &pctx, md_name, + ossl_cms_ctx_get0_libctx(ctx), + ossl_cms_ctx_get0_propq(ctx), si->pkey, + NULL) <= 0) goto err; si->pctx = pctx; } - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, - EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { - CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); - goto err; - } - alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, ASN1_ITEM_rptr(CMS_Attributes_Sign)); if (!abuf) @@ -704,12 +823,6 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0) goto err; - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, - EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { - CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); - goto err; - } - EVP_MD_CTX_reset(mctx); ASN1_STRING_set0(si->signature, abuf, siglen); @@ -727,25 +840,44 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) EVP_MD_CTX *mctx = NULL; unsigned char *abuf = NULL; int alen, r = -1; - const EVP_MD *md = NULL; - - if (!si->pkey) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY); + char name[OSSL_MAX_NAME_SIZE]; + const EVP_MD *md; + EVP_MD *fetched_md = NULL; + const CMS_CTX *ctx = si->cms_ctx; + OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx); + const char *propq = ossl_cms_ctx_get0_propq(ctx); + + if (si->pkey == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_NO_PUBLIC_KEY); return -1; } - if (!CMS_si_check_attributes(si)) + if (!ossl_cms_si_check_attributes(si)) return -1; - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); - if (md == NULL) + OBJ_obj2txt(name, sizeof(name), si->digestAlgorithm->algorithm, 0); + + (void)ERR_set_mark(); + fetched_md = EVP_MD_fetch(libctx, name, propq); + + if (fetched_md != NULL) + md = fetched_md; + else + md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + if (md == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_DIGEST_ALGORITHM); return -1; + } + (void)ERR_pop_to_mark(); + if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, ERR_R_MALLOC_FAILURE); - return -1; + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + goto err; } mctx = si->mctx; - if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0) + if (EVP_DigestVerifyInit_ex(mctx, &si->pctx, EVP_MD_get0_name(md), libctx, + propq, si->pkey, NULL) <= 0) goto err; if (!cms_sd_asn1_ctrl(si, 1)) @@ -753,7 +885,7 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, ASN1_ITEM_rptr(CMS_Attributes_Verify)); - if (!abuf) + if (abuf == NULL || alen < 0) goto err; r = EVP_DigestVerifyUpdate(mctx, abuf, alen); OPENSSL_free(abuf); @@ -764,32 +896,36 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) r = EVP_DigestVerifyFinal(mctx, si->signature->data, si->signature->length); if (r <= 0) - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); + ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE); err: + EVP_MD_free(fetched_md); EVP_MD_CTX_reset(mctx); return r; } /* Create a chain of digest BIOs from a CMS ContentInfo */ -BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms) +BIO *ossl_cms_SignedData_init_bio(CMS_ContentInfo *cms) { int i; CMS_SignedData *sd; BIO *chain = NULL; + sd = cms_get0_signed(cms); - if (!sd) + if (sd == NULL) return NULL; if (cms->d.signedData->encapContentInfo->partial) cms_sd_set_version(sd); for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { X509_ALGOR *digestAlgorithm; BIO *mdbio; + digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); - mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); - if (!mdbio) + mdbio = ossl_cms_DigestAlgorithm_init_bio(digestAlgorithm, + ossl_cms_get0_cmsctx(cms)); + if (mdbio == NULL) goto err; - if (chain) + if (chain != NULL) BIO_push(chain, mdbio); else chain = mdbio; @@ -810,7 +946,7 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) unsigned int mlen; if (mctx == NULL) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } /* If we have any signed attributes look for messageDigest value */ @@ -818,40 +954,40 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) os = CMS_signed_get0_data_by_OBJ(si, OBJ_nid2obj(NID_pkcs9_messageDigest), -3, V_ASN1_OCTET_STRING); - if (!os) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, - CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); + if (os == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); goto err; } } - if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm)) + if (!ossl_cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm)) goto err; if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, - CMS_R_UNABLE_TO_FINALIZE_CONTEXT); + ERR_raise(ERR_LIB_CMS, CMS_R_UNABLE_TO_FINALIZE_CONTEXT); goto err; } /* If messageDigest found compare it */ - if (os) { + if (os != NULL) { if (mlen != (unsigned int)os->length) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, - CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); + ERR_raise(ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); goto err; } if (memcmp(mval, os->data, mlen)) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, - CMS_R_VERIFICATION_FAILURE); + ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE); r = 0; } else r = 1; } else { - const EVP_MD *md = EVP_MD_CTX_md(mctx); - pkctx = EVP_PKEY_CTX_new(si->pkey, NULL); + const EVP_MD *md = EVP_MD_CTX_get0_md(mctx); + const CMS_CTX *ctx = si->cms_ctx; + + pkctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx), + si->pkey, + ossl_cms_ctx_get0_propq(ctx)); if (pkctx == NULL) goto err; if (EVP_PKEY_verify_init(pkctx) <= 0) @@ -864,8 +1000,7 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) r = EVP_PKEY_verify(pkctx, si->signature->data, si->signature->length, mval, mlen); if (r <= 0) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, - CMS_R_VERIFICATION_FAILURE); + ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE); r = 0; } } @@ -881,6 +1016,7 @@ int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) { unsigned char *smder = NULL; int smderlen, r; + smderlen = i2d_X509_ALGORS(algs, &smder); if (smderlen <= 0) return 0; @@ -895,6 +1031,7 @@ int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, { X509_ALGOR *alg; ASN1_INTEGER *key = NULL; + if (keysize > 0) { key = ASN1_INTEGER_new(); if (key == NULL || !ASN1_INTEGER_set(key, keysize)) { diff --git a/crypto/openssl/crypto/cms/cms_smime.c b/crypto/openssl/crypto/cms/cms_smime.c index 6e7dbc4da1fa..d17df31dd412 100644 --- a/crypto/openssl/crypto/cms/cms_smime.c +++ b/crypto/openssl/crypto/cms/cms_smime.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,6 +19,7 @@ static BIO *cms_get_text_bio(BIO *out, unsigned int flags) { BIO *rbio; + if (out == NULL) rbio = BIO_new(BIO_s_null()); else if (flags & CMS_TEXT) { @@ -38,7 +39,7 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) tmpout = cms_get_text_bio(out, flags); if (tmpout == NULL) { - CMSerr(CMS_F_CMS_COPY_CONTENT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } @@ -47,7 +48,7 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) i = BIO_read(in, buf, sizeof(buf)); if (i <= 0) { if (BIO_method_type(in) == BIO_TYPE_CIPHER) { - if (!BIO_get_cipher_status(in)) + if (BIO_get_cipher_status(in) <= 0) goto err; } if (i < 0) @@ -55,19 +56,18 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) break; } - if (tmpout && (BIO_write(tmpout, buf, i) != i)) + if (tmpout != NULL && (BIO_write(tmpout, buf, i) != i)) goto err; } if (flags & CMS_TEXT) { if (!SMIME_text(tmpout, out)) { - CMSerr(CMS_F_CMS_COPY_CONTENT, CMS_R_SMIME_TEXT_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR); goto err; } } r = 1; - err: if (tmpout != out) BIO_free(tmpout); @@ -78,8 +78,9 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) static int check_content(CMS_ContentInfo *cms) { ASN1_OCTET_STRING **pos = CMS_get0_content(cms); - if (!pos || !*pos) { - CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT); + + if (pos == NULL || *pos == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT); return 0; } return 1; @@ -87,80 +88,95 @@ static int check_content(CMS_ContentInfo *cms) static void do_free_upto(BIO *f, BIO *upto) { - if (upto) { + if (upto != NULL) { BIO *tbio; + do { tbio = BIO_pop(f); BIO_free(f); f = tbio; - } - while (f && f != upto); - } else + } while (f != NULL && f != upto); + } else { BIO_free_all(f); + } } int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) { BIO *cont; int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) { - CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA); + ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_DATA); return 0; } cont = CMS_dataInit(cms, NULL); - if (!cont) + if (cont == NULL) return 0; r = cms_copy_content(out, cont, flags); BIO_free_all(cont); return r; } -CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) +CMS_ContentInfo *CMS_data_create_ex(BIO *in, unsigned int flags, + OSSL_LIB_CTX *libctx, const char *propq) { - CMS_ContentInfo *cms; - cms = cms_Data_create(); - if (!cms) + CMS_ContentInfo *cms = ossl_cms_Data_create(libctx, propq); + + if (cms == NULL) return NULL; if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) return cms; CMS_ContentInfo_free(cms); - return NULL; } +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) +{ + return CMS_data_create_ex(in, flags, NULL, NULL); +} + int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags) { BIO *cont; int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) { - CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA); + ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_DIGESTED_DATA); return 0; } - if (!dcont && !check_content(cms)) + if (dcont == NULL && !check_content(cms)) return 0; cont = CMS_dataInit(cms, dcont); - if (!cont) + if (cont == NULL) return 0; + r = cms_copy_content(out, cont, flags); if (r) - r = cms_DigestedData_do_final(cms, cont, 1); + r = ossl_cms_DigestedData_do_final(cms, cont, 1); do_free_upto(cont, dcont); return r; } -CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, - unsigned int flags) +CMS_ContentInfo *CMS_digest_create_ex(BIO *in, const EVP_MD *md, + unsigned int flags, OSSL_LIB_CTX *ctx, + const char *propq) { CMS_ContentInfo *cms; - if (!md) + + /* + * Because the EVP_MD is cached and can be a legacy algorithm, we + * cannot fetch the algorithm if it isn't supplied. + */ + if (md == NULL) md = EVP_sha1(); - cms = cms_DigestedData_create(md); - if (!cms) + cms = ossl_cms_DigestedData_create(md, ctx, propq); + if (cms == NULL) return NULL; if (!(flags & CMS_DETACHED)) @@ -173,41 +189,50 @@ CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, return NULL; } +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags) +{ + return CMS_digest_create_ex(in, md, flags, NULL, NULL); +} + int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, const unsigned char *key, size_t keylen, BIO *dcont, BIO *out, unsigned int flags) { BIO *cont; int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, - CMS_R_TYPE_NOT_ENCRYPTED_DATA); + ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_ENCRYPTED_DATA); return 0; } - if (!dcont && !check_content(cms)) + if (dcont == NULL && !check_content(cms)) return 0; if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) return 0; cont = CMS_dataInit(cms, dcont); - if (!cont) + if (cont == NULL) return 0; r = cms_copy_content(out, cont, flags); do_free_upto(cont, dcont); return r; } -CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, - const unsigned char *key, - size_t keylen, unsigned int flags) +CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags, + OSSL_LIB_CTX *libctx, + const char *propq) { CMS_ContentInfo *cms; - if (!cipher) { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER); + + if (cipher == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_NO_CIPHER); return NULL; } - cms = CMS_ContentInfo_new(); + cms = CMS_ContentInfo_new_ex(libctx, propq); if (cms == NULL) return NULL; if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) @@ -224,38 +249,52 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, return NULL; } +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags) +{ + return CMS_EncryptedData_encrypt_ex(in, cipher, key, keylen, flags, NULL, + NULL); +} + static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, X509_STORE *store, STACK_OF(X509) *certs, - STACK_OF(X509_CRL) *crls) + STACK_OF(X509_CRL) *crls, + STACK_OF(X509) **chain, + const CMS_CTX *cms_ctx) { - X509_STORE_CTX *ctx = X509_STORE_CTX_new(); + X509_STORE_CTX *ctx; X509 *signer; int i, j, r = 0; + ctx = X509_STORE_CTX_new_ex(ossl_cms_ctx_get0_libctx(cms_ctx), + ossl_cms_ctx_get0_propq(cms_ctx)); if (ctx == NULL) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); if (!X509_STORE_CTX_init(ctx, store, signer, certs)) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_STORE_INIT_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_STORE_INIT_ERROR); goto err; } X509_STORE_CTX_set_default(ctx, "smime_sign"); - if (crls) + if (crls != NULL) X509_STORE_CTX_set0_crls(ctx, crls); i = X509_verify_cert(ctx); if (i <= 0) { j = X509_STORE_CTX_get_error(ctx); - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, - CMS_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(j)); + ERR_raise_data(ERR_LIB_CMS, CMS_R_CERTIFICATE_VERIFY_ERROR, + "Verify error: %s", X509_verify_cert_error_string(j)); goto err; } r = 1; + + /* also send back the trust chain when required */ + if (chain != NULL) + *chain = X509_STORE_CTX_get1_chain(ctx); err: X509_STORE_CTX_free(ctx); return r; @@ -269,14 +308,18 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, STACK_OF(CMS_SignerInfo) *sinfos; STACK_OF(X509) *cms_certs = NULL; STACK_OF(X509_CRL) *crls = NULL; + STACK_OF(X509) **si_chains = NULL; X509 *signer; int i, scount = 0, ret = 0; BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL; + int cadesVerify = (flags & CMS_CADES) != 0; + const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); - if (!dcont && !check_content(cms)) + if (dcont == NULL && !check_content(cms)) return 0; - if (dcont && !(flags & CMS_BINARY)) { + if (dcont != NULL && !(flags & CMS_BINARY)) { const ASN1_OBJECT *coid = CMS_get0_eContentType(cms); + if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF) flags |= CMS_ASCIICRLF; } @@ -286,7 +329,7 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, sinfos = CMS_get0_SignerInfos(cms); if (sk_CMS_SignerInfo_num(sinfos) <= 0) { - CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_SIGNERS); goto err; } @@ -301,32 +344,50 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, scount += CMS_set1_signers_certs(cms, certs, flags); if (scount != sk_CMS_SignerInfo_num(sinfos)) { - CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); + ERR_raise(ERR_LIB_CMS, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); goto err; } /* Attempt to verify all signers certs */ - - if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) { + /* at this point scount == sk_CMS_SignerInfo_num(sinfos) */ + + if ((flags & CMS_NO_SIGNER_CERT_VERIFY) == 0 || cadesVerify) { + if (cadesVerify) { + /* Certificate trust chain is required to check CAdES signature */ + si_chains = OPENSSL_zalloc(scount * sizeof(si_chains[0])); + if (si_chains == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + goto err; + } + } cms_certs = CMS_get1_certs(cms); if (!(flags & CMS_NOCRL)) crls = CMS_get1_crls(cms); - for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + for (i = 0; i < scount; i++) { si = sk_CMS_SignerInfo_value(sinfos, i); - if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls)) + + if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls, + si_chains ? &si_chains[i] : NULL, + ctx)) goto err; } } /* Attempt to verify all SignerInfo signed attribute signatures */ - if (!(flags & CMS_NO_ATTR_VERIFY)) { - for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + if ((flags & CMS_NO_ATTR_VERIFY) == 0 || cadesVerify) { + for (i = 0; i < scount; i++) { si = sk_CMS_SignerInfo_value(sinfos, i); if (CMS_signed_get_attr_count(si) < 0) continue; if (CMS_SignerInfo_verify(si) <= 0) goto err; + if (cadesVerify) { + STACK_OF(X509) *si_chain = si_chains ? si_chains[i] : NULL; + + if (ossl_cms_check_signing_certs(si, si_chain) <= 0) + goto err; + } } } @@ -337,17 +398,19 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, * reading from a read write memory BIO when signatures are calculated. */ - if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { + if (dcont != NULL && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { char *ptr; long len; + len = BIO_get_mem_data(dcont, &ptr); tmpin = (len == 0) ? dcont : BIO_new_mem_buf(ptr, len); if (tmpin == NULL) { - CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err2; } - } else + } else { tmpin = dcont; + } /* * If not binary mode and detached generate digests by *writing* through * the BIO. That makes it possible to canonicalise the input. @@ -358,28 +421,29 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, * included content doesn't override detached content. */ tmpout = cms_get_text_bio(out, flags); - if (!tmpout) { - CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE); + if (tmpout == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); goto err; } cmsbio = CMS_dataInit(cms, tmpout); - if (!cmsbio) + if (cmsbio == NULL) goto err; /* * Don't use SMIME_TEXT for verify: it adds headers and we want to * remove them. */ - SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT); + if (!SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT)) + goto err; if (flags & CMS_TEXT) { if (!SMIME_text(tmpout, out)) { - CMSerr(CMS_F_CMS_VERIFY, CMS_R_SMIME_TEXT_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR); goto err; } } } else { cmsbio = CMS_dataInit(cms, tmpin); - if (!cmsbio) + if (cmsbio == NULL) goto err; if (!cms_copy_content(out, cmsbio, flags)) @@ -390,14 +454,13 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { si = sk_CMS_SignerInfo_value(sinfos, i); if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) { - CMSerr(CMS_F_CMS_VERIFY, CMS_R_CONTENT_VERIFY_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_VERIFY_ERROR); goto err; } } } ret = 1; - err: if (!(flags & SMIME_BINARY) && dcont) { do_free_upto(cmsbio, tmpout); @@ -414,6 +477,11 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, BIO_free_all(tmpout); err2: + if (si_chains != NULL) { + for (i = 0; i < scount; ++i) + sk_X509_pop_free(si_chains[i], X509_free); + OPENSSL_free(si_chains); + } sk_X509_pop_free(cms_certs, X509_free); sk_X509_CRL_pop_free(crls, X509_CRL_free); @@ -425,21 +493,23 @@ int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, X509_STORE *store, unsigned int flags) { int r; + flags &= ~(CMS_DETACHED | CMS_TEXT); r = CMS_verify(rcms, certs, store, NULL, NULL, flags); if (r <= 0) return r; - return cms_Receipt_verify(rcms, ocms); + return ossl_cms_Receipt_verify(rcms, ocms); } -CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, - STACK_OF(X509) *certs, BIO *data, - unsigned int flags) +CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags, OSSL_LIB_CTX *libctx, + const char *propq) { CMS_ContentInfo *cms; int i; - cms = CMS_ContentInfo_new(); + cms = CMS_ContentInfo_new_ex(libctx, propq); if (cms == NULL || !CMS_SignedData_init(cms)) goto merr; if (flags & CMS_ASCIICRLF @@ -447,13 +517,14 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF))) goto err; - if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { - CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR); + if (pkey != NULL && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { + ERR_raise(ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR); goto err; } for (i = 0; i < sk_X509_num(certs); i++) { X509 *x = sk_X509_value(certs, i); + if (!CMS_add1_cert(cms, x)) goto merr; } @@ -468,13 +539,19 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, goto err; merr: - CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: CMS_ContentInfo_free(cms); return NULL; } +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, unsigned int flags) +{ + return CMS_sign_ex(signcert, pkey, certs, data, flags, NULL, NULL); +} + CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, unsigned int flags) @@ -484,19 +561,22 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, ASN1_OCTET_STRING **pos, *os; BIO *rct_cont = NULL; int r = 0; + const CMS_CTX *ctx = si->cms_ctx; flags &= ~(CMS_STREAM | CMS_TEXT); /* Not really detached but avoids content being allocated */ flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED; - if (!pkey || !signcert) { - CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT); + if (pkey == NULL || signcert == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_NO_KEY_OR_CERT); return NULL; } /* Initialize signed data */ - cms = CMS_sign(NULL, NULL, certs, NULL, flags); - if (!cms) + cms = CMS_sign_ex(NULL, NULL, certs, NULL, flags, + ossl_cms_ctx_get0_libctx(ctx), + ossl_cms_ctx_get0_propq(ctx)); + if (cms == NULL) goto err; /* Set inner content type to signed receipt */ @@ -505,23 +585,22 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags); if (!rct_si) { - CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR); goto err; } - os = cms_encode_Receipt(si); - - if (!os) + os = ossl_cms_encode_Receipt(si); + if (os == NULL) goto err; /* Set content to digest */ rct_cont = BIO_new_mem_buf(os->data, os->length); - if (!rct_cont) + if (rct_cont == NULL) goto err; /* Add msgSigDigest attribute */ - if (!cms_msgSigDigest_add1(rct_si, si)) + if (!ossl_cms_msgSigDigest_add1(rct_si, si)) goto err; /* Finalize structure */ @@ -530,6 +609,8 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, /* Set embedded content */ pos = CMS_get0_content(cms); + if (pos == NULL) + goto err; *pos = os; r = 1; @@ -543,19 +624,24 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, } -CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, - const EVP_CIPHER *cipher, unsigned int flags) +CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *data, + const EVP_CIPHER *cipher, unsigned int flags, + OSSL_LIB_CTX *libctx, const char *propq) { CMS_ContentInfo *cms; int i; X509 *recip; - cms = CMS_EnvelopedData_create(cipher); - if (!cms) + + + cms = (EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) + ? CMS_AuthEnvelopedData_create_ex(cipher, libctx, propq) + : CMS_EnvelopedData_create_ex(cipher, libctx, propq); + if (cms == NULL) goto merr; for (i = 0; i < sk_X509_num(certs); i++) { recip = sk_X509_value(certs, i); if (!CMS_add1_recipient_cert(cms, recip, flags)) { - CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_RECIPIENT_ERROR); goto err; } } @@ -570,25 +656,34 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, goto err; merr: - CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: CMS_ContentInfo_free(cms); return NULL; } -static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, - EVP_PKEY *pk, X509 *cert) +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, + const EVP_CIPHER *cipher, unsigned int flags) +{ + return CMS_encrypt_ex(certs, data, cipher, flags, NULL, NULL); +} + +static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, + EVP_PKEY *pk, X509 *cert, X509 *peer) { int i; STACK_OF(CMS_RecipientEncryptedKey) *reks; CMS_RecipientEncryptedKey *rek; + reks = CMS_RecipientInfo_kari_get0_reks(ri); for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { int rv; + rek = sk_CMS_RecipientEncryptedKey_value(reks, i); if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert)) continue; - CMS_RecipientInfo_kari_set0_pkey(ri, pk); + CMS_RecipientInfo_kari_set0_pkey_and_peer(ri, pk, peer); rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek); CMS_RecipientInfo_kari_set0_pkey(ri, NULL); if (rv > 0) @@ -599,28 +694,38 @@ static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, } int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) +{ + return CMS_decrypt_set1_pkey_and_peer(cms, pk, cert, NULL); +} + +int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, + X509 *cert, X509 *peer) { STACK_OF(CMS_RecipientInfo) *ris; CMS_RecipientInfo *ri; - int i, r, ri_type; + int i, r, cms_pkey_ri_type; int debug = 0, match_ri = 0; + ris = CMS_get0_RecipientInfos(cms); - if (ris) - debug = cms->d.envelopedData->encryptedContentInfo->debug; - ri_type = cms_pkey_get_ri_type(pk); - if (ri_type == CMS_RECIPINFO_NONE) { - CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - return 0; + if (ris != NULL) + debug = ossl_cms_get0_env_enc_content(cms)->debug; + + cms_pkey_ri_type = ossl_cms_pkey_get_ri_type(pk); + if (cms_pkey_ri_type == CMS_RECIPINFO_NONE) { + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; } for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + int ri_type; + ri = sk_CMS_RecipientInfo_value(ris, i); - if (CMS_RecipientInfo_type(ri) != ri_type) + ri_type = CMS_RecipientInfo_type(ri); + if (!ossl_cms_pkey_is_ri_type_supported(pk, ri_type)) continue; match_ri = 1; if (ri_type == CMS_RECIPINFO_AGREE) { - r = cms_kari_set1_pkey(cms, ri, pk, cert); + r = cms_kari_set1_pkey_and_peer(cms, ri, pk, cert, peer); if (r > 0) return 1; if (r < 0) @@ -630,12 +735,12 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) * If we have a cert try matching RecipientInfo otherwise try them * all. */ - else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) { + else if (cert == NULL|| !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) { EVP_PKEY_up_ref(pk); CMS_RecipientInfo_set0_pkey(ri, pk); r = CMS_RecipientInfo_decrypt(cms, ri); CMS_RecipientInfo_set0_pkey(ri, NULL); - if (cert) { + if (cert != NULL) { /* * If not debugging clear any error and return success to * avoid leaking of information useful to MMA @@ -646,7 +751,7 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) } if (r > 0) return 1; - CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_DECRYPT_ERROR); return 0; } /* @@ -654,17 +759,20 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) * successful decrypt. Always attempt to decrypt all recipients * to avoid leaking timing of a successful decrypt. */ - else if (r > 0 && debug) + else if (r > 0 && (debug || cms_pkey_ri_type != CMS_RECIPINFO_TRANS)) return 1; } } /* If no cert, key transport and not debugging always return success */ - if (cert == NULL && ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) { + if (cert == NULL + && cms_pkey_ri_type == CMS_RECIPINFO_TRANS + && match_ri + && !debug) { ERR_clear_error(); return 1; } - CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT); return 0; } @@ -676,6 +784,7 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms, STACK_OF(CMS_RecipientInfo) *ris; CMS_RecipientInfo *ri; int i, r; + ris = CMS_get0_RecipientInfos(cms); for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { ri = sk_CMS_RecipientInfo_value(ris, i); @@ -686,21 +795,21 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms, * If we have an id try matching RecipientInfo otherwise try them * all. */ - if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { + if (id == NULL || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { CMS_RecipientInfo_set0_key(ri, key, keylen); r = CMS_RecipientInfo_decrypt(cms, ri); CMS_RecipientInfo_set0_key(ri, NULL, 0); if (r > 0) return 1; - if (id) { - CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR); + if (id != NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_DECRYPT_ERROR); return 0; } ERR_clear_error(); } } - CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT); return 0; } @@ -711,6 +820,7 @@ int CMS_decrypt_set1_password(CMS_ContentInfo *cms, STACK_OF(CMS_RecipientInfo) *ris; CMS_RecipientInfo *ri; int i, r; + ris = CMS_get0_RecipientInfos(cms); for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { ri = sk_CMS_RecipientInfo_value(ris, i); @@ -723,7 +833,7 @@ int CMS_decrypt_set1_password(CMS_ContentInfo *cms, return 1; } - CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT); return 0; } @@ -733,26 +843,30 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, { int r; BIO *cont; - if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) { - CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA); + + int nid = OBJ_obj2nid(CMS_get0_type(cms)); + + if (nid != NID_pkcs7_enveloped + && nid != NID_id_smime_ct_authEnvelopedData) { + ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_ENVELOPED_DATA); return 0; } - if (!dcont && !check_content(cms)) + if (dcont == NULL && !check_content(cms)) return 0; if (flags & CMS_DEBUG_DECRYPT) - cms->d.envelopedData->encryptedContentInfo->debug = 1; + ossl_cms_get0_env_enc_content(cms)->debug = 1; else - cms->d.envelopedData->encryptedContentInfo->debug = 0; - if (!cert) - cms->d.envelopedData->encryptedContentInfo->havenocert = 1; + ossl_cms_get0_env_enc_content(cms)->debug = 0; + if (cert == NULL) + ossl_cms_get0_env_enc_content(cms)->havenocert = 1; else - cms->d.envelopedData->encryptedContentInfo->havenocert = 0; - if (!pk && !cert && !dcont && !out) + ossl_cms_get0_env_enc_content(cms)->havenocert = 0; + if (pk == NULL && cert == NULL && dcont == NULL && out == NULL) return 1; - if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) + if (pk != NULL && !CMS_decrypt_set1_pkey(cms, pk, cert)) return 0; cont = CMS_dataInit(cms, dcont); - if (!cont) + if (cont == NULL) return 0; r = cms_copy_content(out, cont, flags); do_free_upto(cont, dcont); @@ -765,22 +879,24 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) int ret = 0; if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) { - CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_LIB); + ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB); return 0; } - SMIME_crlf_copy(data, cmsbio, flags); + if (!SMIME_crlf_copy(data, cmsbio, flags)) { + goto err; + } (void)BIO_flush(cmsbio); if (!CMS_dataFinal(cms, cmsbio)) { - CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR); goto err; } ret = 1; - err: +err: do_free_upto(cmsbio, dcont); return ret; @@ -794,16 +910,17 @@ int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, { BIO *cont; int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) { - CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA); + ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_COMPRESSED_DATA); return 0; } - if (!dcont && !check_content(cms)) + if (dcont == NULL && !check_content(cms)) return 0; cont = CMS_dataInit(cms, dcont); - if (!cont) + if (cont == NULL) return 0; r = cms_copy_content(out, cont, flags); do_free_upto(cont, dcont); @@ -813,10 +930,11 @@ int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) { CMS_ContentInfo *cms; + if (comp_nid <= 0) comp_nid = NID_zlib_compression; - cms = cms_CompressedData_create(comp_nid); - if (!cms) + cms = ossl_cms_CompressedData_create(comp_nid, NULL, NULL); + if (cms == NULL) return NULL; if (!(flags & CMS_DETACHED)) @@ -834,13 +952,13 @@ CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags) { - CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); return 0; } CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) { - CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); return NULL; } diff --git a/crypto/openssl/crypto/comp/c_zlib.c b/crypto/openssl/crypto/comp/c_zlib.c index b81933791312..9a7087e44404 100644 --- a/crypto/openssl/crypto/comp/c_zlib.c +++ b/crypto/openssl/crypto/comp/c_zlib.c @@ -1,7 +1,7 @@ /* - * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,6 +15,7 @@ #include #include "crypto/cryptlib.h" #include "internal/bio.h" +#include "internal/thread_once.h" #include "comp_local.h" COMP_METHOD *COMP_zlib(void); @@ -102,7 +103,6 @@ static deflate_ft p_deflate = NULL; static deflateInit__ft p_deflateInit_ = NULL; static zError__ft p_zError = NULL; -static int zlib_loaded = 0; /* only attempt to init func pts once */ static DSO *zlib_dso = NULL; # define compress p_compress @@ -204,62 +204,59 @@ static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, return olen - state->istream.avail_out; } -#endif - -COMP_METHOD *COMP_zlib(void) +static CRYPTO_ONCE zlib_once = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init) { - COMP_METHOD *meth = &zlib_method_nozlib; - -#ifdef ZLIB_SHARED +# ifdef ZLIB_SHARED /* LIBZ may be externally defined, and we should respect that value */ -# ifndef LIBZ -# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) -# define LIBZ "ZLIB1" -# elif defined(OPENSSL_SYS_VMS) -# define LIBZ "LIBZ" -# else -# define LIBZ "z" +# ifndef LIBZ +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# define LIBZ "ZLIB1" +# elif defined(OPENSSL_SYS_VMS) +# define LIBZ "LIBZ" +# else +# define LIBZ "z" +# endif # endif -# endif - if (!zlib_loaded) { - zlib_dso = DSO_load(NULL, LIBZ, NULL, 0); - if (zlib_dso != NULL) { - p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress"); - p_inflateEnd - = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd"); - p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate"); - p_inflateInit_ - = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_"); - p_deflateEnd - = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd"); - p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate"); - p_deflateInit_ - = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_"); - p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError"); - - if (p_compress && p_inflateEnd && p_inflate - && p_inflateInit_ && p_deflateEnd - && p_deflate && p_deflateInit_ && p_zError) - zlib_loaded++; - - if (!OPENSSL_init_crypto(OPENSSL_INIT_ZLIB, NULL)) { - comp_zlib_cleanup_int(); - return meth; - } - if (zlib_loaded) - meth = &zlib_stateful_method; + zlib_dso = DSO_load(NULL, LIBZ, NULL, 0); + if (zlib_dso != NULL) { + p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress"); + p_inflateEnd = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd"); + p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate"); + p_inflateInit_ = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_"); + p_deflateEnd = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd"); + p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate"); + p_deflateInit_ = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_"); + p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError"); + + if (p_compress == NULL || p_inflateEnd == NULL + || p_inflate == NULL || p_inflateInit_ == NULL + || p_deflateEnd == NULL || p_deflate == NULL + || p_deflateInit_ == NULL || p_zError == NULL) { + ossl_comp_zlib_cleanup(); + return 0; } } +# endif + return 1; +} #endif -#if defined(ZLIB) - meth = &zlib_stateful_method; + +COMP_METHOD *COMP_zlib(void) +{ + COMP_METHOD *meth = &zlib_method_nozlib; + +#ifdef ZLIB + if (RUN_ONCE(&zlib_once, ossl_comp_zlib_init)) + meth = &zlib_stateful_method; #endif return meth; } -void comp_zlib_cleanup_int(void) +/* Also called from OPENSSL_cleanup() */ +void ossl_comp_zlib_cleanup(void) { #ifdef ZLIB_SHARED DSO_free(zlib_dso); @@ -296,10 +293,8 @@ static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); static const BIO_METHOD bio_meth_zlib = { BIO_TYPE_COMP, "zlib", - /* TODO: Convert to new style write function */ bwrite_conv, bio_zlib_write, - /* TODO: Convert to new style read function */ bread_conv, bio_zlib_read, NULL, /* bio_zlib_puts, */ @@ -318,16 +313,16 @@ const BIO_METHOD *BIO_f_zlib(void) static int bio_zlib_new(BIO *bi) { BIO_ZLIB_CTX *ctx; + # ifdef ZLIB_SHARED - (void)COMP_zlib(); - if (!zlib_loaded) { - COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED); + if (!RUN_ONCE(&zlib_once, ossl_comp_zlib_init)) { + ERR_raise(ERR_LIB_COMP, COMP_R_ZLIB_NOT_SUPPORTED); return 0; } # endif ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx == NULL) { - COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); return 0; } ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE; @@ -346,6 +341,7 @@ static int bio_zlib_new(BIO *bi) static int bio_zlib_free(BIO *bi) { BIO_ZLIB_CTX *ctx; + if (!bi) return 0; ctx = BIO_get_data(bi); @@ -381,10 +377,14 @@ static int bio_zlib_read(BIO *b, char *out, int outl) if (!ctx->ibuf) { ctx->ibuf = OPENSSL_malloc(ctx->ibufsize); if (ctx->ibuf == NULL) { - COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + return 0; + } + if ((ret = inflateInit(zin)) != Z_OK) { + ERR_raise_data(ERR_LIB_COMP, COMP_R_ZLIB_INFLATE_ERROR, + "zlib error: %s", zError(ret)); return 0; } - inflateInit(zin); zin->next_in = ctx->ibuf; zin->avail_in = 0; } @@ -397,8 +397,8 @@ static int bio_zlib_read(BIO *b, char *out, int outl) while (zin->avail_in) { ret = inflate(zin, 0); if ((ret != Z_OK) && (ret != Z_STREAM_END)) { - COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR); - ERR_add_error_data(2, "zlib error:", zError(ret)); + ERR_raise_data(ERR_LIB_COMP, COMP_R_ZLIB_INFLATE_ERROR, + "zlib error: %s", zError(ret)); return 0; } /* If EOF or we've read everything then return */ @@ -442,12 +442,16 @@ static int bio_zlib_write(BIO *b, const char *in, int inl) ctx->obuf = OPENSSL_malloc(ctx->obufsize); /* Need error here */ if (ctx->obuf == NULL) { - COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); return 0; } ctx->optr = ctx->obuf; ctx->ocount = 0; - deflateInit(zout, ctx->comp_level); + if ((ret = deflateInit(zout, ctx->comp_level)) != Z_OK) { + ERR_raise_data(ERR_LIB_COMP, COMP_R_ZLIB_DEFLATE_ERROR, + "zlib error: %s", zError(ret)); + return 0; + } zout->next_out = ctx->obuf; zout->avail_out = ctx->obufsize; } @@ -483,8 +487,8 @@ static int bio_zlib_write(BIO *b, const char *in, int inl) /* Compress some more */ ret = deflate(zout, 0); if (ret != Z_OK) { - COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR); - ERR_add_error_data(2, "zlib error:", zError(ret)); + ERR_raise_data(ERR_LIB_COMP, COMP_R_ZLIB_DEFLATE_ERROR, + "zlib error: %s", zError(ret)); return 0; } ctx->ocount = ctx->obufsize - zout->avail_out; @@ -532,8 +536,8 @@ static int bio_zlib_flush(BIO *b) if (ret == Z_STREAM_END) ctx->odone = 1; else if (ret != Z_OK) { - COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR); - ERR_add_error_data(2, "zlib error:", zError(ret)); + ERR_raise_data(ERR_LIB_COMP, COMP_R_ZLIB_DEFLATE_ERROR, + "zlib error: %s", zError(ret)); return 0; } ctx->ocount = ctx->obufsize - zout->avail_out; @@ -632,6 +636,7 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) { BIO *next = BIO_next(b); + if (next == NULL) return 0; return BIO_callback_ctrl(next, cmd, fp); diff --git a/crypto/openssl/crypto/comp/comp_err.c b/crypto/openssl/crypto/comp/comp_err.c index 2dca315cf1d3..70a6eea0f052 100644 --- a/crypto/openssl/crypto/comp/comp_err.c +++ b/crypto/openssl/crypto/comp/comp_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,17 +10,11 @@ #include #include +#include "crypto/comperr.h" -#ifndef OPENSSL_NO_ERR +#ifndef OPENSSL_NO_COMP -static const ERR_STRING_DATA COMP_str_functs[] = { - {ERR_PACK(ERR_LIB_COMP, COMP_F_BIO_ZLIB_FLUSH, 0), "bio_zlib_flush"}, - {ERR_PACK(ERR_LIB_COMP, COMP_F_BIO_ZLIB_NEW, 0), "bio_zlib_new"}, - {ERR_PACK(ERR_LIB_COMP, COMP_F_BIO_ZLIB_READ, 0), "bio_zlib_read"}, - {ERR_PACK(ERR_LIB_COMP, COMP_F_BIO_ZLIB_WRITE, 0), "bio_zlib_write"}, - {ERR_PACK(ERR_LIB_COMP, COMP_F_COMP_CTX_NEW, 0), "COMP_CTX_new"}, - {0, NULL} -}; +# ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA COMP_str_reasons[] = { {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZLIB_DEFLATE_ERROR), @@ -32,15 +26,16 @@ static const ERR_STRING_DATA COMP_str_reasons[] = { {0, NULL} }; -#endif +# endif -int ERR_load_COMP_strings(void) +int ossl_err_load_COMP_strings(void) { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(COMP_str_functs[0].error) == NULL) { - ERR_load_strings_const(COMP_str_functs); +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(COMP_str_reasons[0].error) == NULL) ERR_load_strings_const(COMP_str_reasons); - } -#endif +# endif return 1; } +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/comp/comp_lib.c b/crypto/openssl/crypto/comp/comp_lib.c index 56920e1cca51..bf9069d871a4 100644 --- a/crypto/openssl/crypto/comp/comp_lib.c +++ b/crypto/openssl/crypto/comp/comp_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 1998-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,7 +20,7 @@ COMP_CTX *COMP_CTX_new(COMP_METHOD *meth) COMP_CTX *ret; if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - COMPerr(COMP_F_COMP_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); return NULL; } ret->meth = meth; diff --git a/crypto/openssl/crypto/comp/comp_local.h b/crypto/openssl/crypto/comp/comp_local.h index aa45fca238da..acf113e31cd0 100644 --- a/crypto/openssl/crypto/comp/comp_local.h +++ b/crypto/openssl/crypto/comp/comp_local.h @@ -1,7 +1,7 @@ /* * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/conf/conf_api.c b/crypto/openssl/crypto/conf/conf_api.c index 5e57d749ce5e..7a4efe6dbb2b 100644 --- a/crypto/openssl/crypto/conf/conf_api.c +++ b/crypto/openssl/crypto/conf/conf_api.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,34 +15,31 @@ #include #include #include +#include "conf_local.h" static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf); static void value_free_stack_doall(CONF_VALUE *a); -/* Up until OpenSSL 0.9.5a, this was get_section */ CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) { - CONF_VALUE *v, vv; + CONF_VALUE vv; - if ((conf == NULL) || (section == NULL)) + if (conf == NULL || section == NULL) return NULL; vv.name = NULL; vv.section = (char *)section; - v = lh_CONF_VALUE_retrieve(conf->data, &vv); - return v; + return conf->data != NULL ? lh_CONF_VALUE_retrieve(conf->data, &vv) : NULL; } -/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, const char *section) { CONF_VALUE *v; v = _CONF_get_section(conf, section); - if (v != NULL) - return ((STACK_OF(CONF_VALUE) *)v->value); - else + if (v == NULL) return NULL; + return ((STACK_OF(CONF_VALUE) *)v->value); } int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) @@ -53,9 +50,8 @@ int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) ts = (STACK_OF(CONF_VALUE) *)section->value; value->section = section->section; - if (!sk_CONF_VALUE_push(ts, value)) { + if (!sk_CONF_VALUE_push(ts, value)) return 0; - } v = lh_CONF_VALUE_insert(conf->data, value); if (v != NULL) { @@ -75,28 +71,28 @@ char *_CONF_get_string(const CONF *conf, const char *section, if (name == NULL) return NULL; - if (conf != NULL) { - if (section != NULL) { - vv.name = (char *)name; - vv.section = (char *)section; - v = lh_CONF_VALUE_retrieve(conf->data, &vv); - if (v != NULL) - return v->value; - if (strcmp(section, "ENV") == 0) { - p = ossl_safe_getenv(name); - if (p != NULL) - return p; - } - } - vv.section = "default"; + if (conf == NULL) + return ossl_safe_getenv(name); + if (conf->data == NULL) + return NULL; + if (section != NULL) { vv.name = (char *)name; + vv.section = (char *)section; v = lh_CONF_VALUE_retrieve(conf->data, &vv); if (v != NULL) return v->value; - else - return NULL; - } else - return ossl_safe_getenv(name); + if (strcmp(section, "ENV") == 0) { + p = ossl_safe_getenv(name); + if (p != NULL) + return p; + } + } + vv.section = "default"; + vv.name = (char *)name; + v = lh_CONF_VALUE_retrieve(conf->data, &vv); + if (v == NULL) + return NULL; + return v->value; } static unsigned long conf_value_hash(const CONF_VALUE *v) @@ -110,24 +106,21 @@ static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) if (a->section != b->section) { i = strcmp(a->section, b->section); - if (i) + if (i != 0) return i; } - if ((a->name != NULL) && (b->name != NULL)) { - i = strcmp(a->name, b->name); - return i; - } else if (a->name == b->name) + if (a->name != NULL && b->name != NULL) + return strcmp(a->name, b->name); + if (a->name == b->name) return 0; - else - return ((a->name == NULL) ? -1 : 1); + return (a->name == NULL) ? -1 : 1; } int _CONF_new_data(CONF *conf) { - if (conf == NULL) { + if (conf == NULL) return 0; - } if (conf->data == NULL) { conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp); if (conf->data == NULL) @@ -142,7 +135,11 @@ IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, LH_CONF_VALUE); void _CONF_free_data(CONF *conf) { - if (conf == NULL || conf->data == NULL) + if (conf == NULL) + return; + + OPENSSL_free(conf->includedir); + if (conf->data == NULL) return; /* evil thing to make sure the 'OPENSSL_free()' works as expected */ @@ -185,7 +182,6 @@ static void value_free_stack_doall(CONF_VALUE *a) OPENSSL_free(a); } -/* Up until OpenSSL 0.9.5a, this was new_section */ CONF_VALUE *_CONF_new_section(CONF *conf, const char *section) { STACK_OF(CONF_VALUE) *sk = NULL; diff --git a/crypto/openssl/crypto/conf/conf_def.c b/crypto/openssl/crypto/conf/conf_def.c index 31c02cc49e22..b5d6668f4276 100644 --- a/crypto/openssl/crypto/conf/conf_def.c +++ b/crypto/openssl/crypto/conf/conf_def.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,11 +11,17 @@ #include #include +#include "e_os.h" /* struct stat */ +#ifdef __TANDEM +# include /* needed for stat.h */ +# include /* struct stat */ +#endif #include "internal/cryptlib.h" #include "internal/o_dir.h" #include #include #include +#include "conf_local.h" #include "conf_def.h" #include #include @@ -23,7 +29,6 @@ # include # ifdef _WIN32 # define stat _stat -# define strcasecmp _stricmp # endif #endif @@ -54,7 +59,9 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx); static CONF *def_create(CONF_METHOD *meth); static int def_init_default(CONF *conf); +#ifndef OPENSSL_NO_DEPRECATED_3_0 static int def_init_WIN32(CONF *conf); +#endif static int def_destroy(CONF *conf); static int def_destroy_data(CONF *conf); static int def_load(CONF *conf, const char *name, long *eline); @@ -76,6 +83,12 @@ static CONF_METHOD default_method = { def_load }; +CONF_METHOD *NCONF_default(void) +{ + return &default_method; +} + +#ifndef OPENSSL_NO_DEPRECATED_3_0 static CONF_METHOD WIN32_method = { "WIN32", def_create, @@ -89,15 +102,11 @@ static CONF_METHOD WIN32_method = { def_load }; -CONF_METHOD *NCONF_default(void) -{ - return &default_method; -} - CONF_METHOD *NCONF_WIN32(void) { return &WIN32_method; } +#endif static CONF *def_create(CONF_METHOD *meth) { @@ -117,24 +126,26 @@ static int def_init_default(CONF *conf) if (conf == NULL) return 0; + memset(conf, 0, sizeof(*conf)); conf->meth = &default_method; conf->meth_data = (void *)CONF_type_default; - conf->data = NULL; return 1; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 static int def_init_WIN32(CONF *conf) { if (conf == NULL) return 0; + memset(conf, 0, sizeof(*conf)); conf->meth = &WIN32_method; conf->meth_data = (void *)CONF_type_win32; - conf->data = NULL; return 1; } +#endif static int def_destroy(CONF *conf) { @@ -165,9 +176,9 @@ static int def_load(CONF *conf, const char *name, long *line) #endif if (in == NULL) { if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE) - CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE); + ERR_raise(ERR_LIB_CONF, CONF_R_NO_SUCH_FILE); else - CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_CONF, ERR_R_SYS_LIB); return 0; } @@ -177,6 +188,23 @@ static int def_load(CONF *conf, const char *name, long *line) return ret; } + +/* Parse a boolean value and fill in *flag. Return 0 on error. */ +static int parsebool(const char *pval, int *flag) +{ + if (OPENSSL_strcasecmp(pval, "on") == 0 + || OPENSSL_strcasecmp(pval, "true") == 0) { + *flag = 1; + } else if (OPENSSL_strcasecmp(pval, "off") == 0 + || OPENSSL_strcasecmp(pval, "false") == 0) { + *flag = 0; + } else { + ERR_raise(ERR_LIB_CONF, CONF_R_INVALID_PRAGMA); + return 0; + } + return 1; +} + static int def_load_bio(CONF *conf, BIO *in, long *line) { /* The macro BUFSIZE conflicts with a system macro in VxWorks */ @@ -200,24 +228,24 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) #endif if ((buff = BUF_MEM_new()) == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); goto err; } section = OPENSSL_strdup("default"); if (section == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); goto err; } if (_CONF_new_data(conf) == 0) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); goto err; } sv = _CONF_new_section(conf, section); if (sv == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + ERR_raise(ERR_LIB_CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } @@ -225,13 +253,14 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) again = 0; for (;;) { if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); goto err; } p = &(buff->data[bufnum]); *p = '\0'; read_retry: - BIO_gets(in, p, CONFBUFSIZE - 1); + if (in != NULL && BIO_gets(in, p, CONFBUFSIZE - 1) < 0) + goto err; p[CONFBUFSIZE - 1] = '\0'; ii = i = strlen(p); if (first_call) { @@ -248,7 +277,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) first_call = 0; } if (i == 0 && !again) { - /* the currently processed BIO is at EOF */ + /* the currently processed BIO is NULL or at EOF */ BIO *parent; #ifndef OPENSSL_NO_POSIX_IO @@ -334,8 +363,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) ss = p; goto again; } - CONFerr(CONF_F_DEF_LOAD_BIO, - CONF_R_MISSING_CLOSE_SQUARE_BRACKET); + ERR_raise(ERR_LIB_CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET); goto err; } *end = '\0'; @@ -344,8 +372,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) if ((sv = _CONF_get_section(conf, section)) == NULL) sv = _CONF_new_section(conf, section); if (sv == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, - CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + ERR_raise(ERR_LIB_CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } continue; @@ -362,10 +389,61 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) psection = section; } p = eat_ws(conf, end); - if (strncmp(pname, ".include", 8) == 0 + if (strncmp(pname, ".pragma", 7) == 0 + && (p != pname + 7 || *p == '=')) { + char *pval; + + if (*p == '=') { + p++; + p = eat_ws(conf, p); + } + trim_ws(conf, p); + + /* Pragma values take the form keyword:value */ + pval = strchr(p, ':'); + if (pval == NULL || pval == p || pval[1] == '\0') { + ERR_raise(ERR_LIB_CONF, CONF_R_INVALID_PRAGMA); + goto err; + } + + *pval++ = '\0'; + trim_ws(conf, p); + pval = eat_ws(conf, pval); + + /* + * Known pragmas: + * + * dollarid takes "on", "true or "off", "false" + * abspath takes "on", "true or "off", "false" + * includedir directory prefix + */ + if (strcmp(p, "dollarid") == 0) { + if (!parsebool(pval, &conf->flag_dollarid)) + goto err; + } else if (strcmp(p, "abspath") == 0) { + if (!parsebool(pval, &conf->flag_abspath)) + goto err; + } else if (strcmp(p, "includedir") == 0) { + OPENSSL_free(conf->includedir); + if ((conf->includedir = OPENSSL_strdup(pval)) == NULL) { + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + /* + * We *ignore* any unknown pragma. + */ + continue; + } else if (strncmp(pname, ".include", 8) == 0 && (p != pname + 8 || *p == '=')) { char *include = NULL; BIO *next; + const char *include_dir = ossl_safe_getenv("OPENSSL_CONF_INCLUDE"); + char *include_path = NULL; + + if (include_dir == NULL) + include_dir = conf->includedir; if (*p == '=') { p++; @@ -374,28 +452,56 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) trim_ws(conf, p); if (!str_copy(conf, psection, &include, p)) goto err; + + if (include_dir != NULL && !ossl_is_absolute_path(include)) { + size_t newlen = strlen(include_dir) + strlen(include) + 2; + + include_path = OPENSSL_malloc(newlen); + if (include_path == NULL) { + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + OPENSSL_free(include); + goto err; + } + + OPENSSL_strlcpy(include_path, include_dir, newlen); + if (!ossl_ends_with_dirsep(include_path)) + OPENSSL_strlcat(include_path, "/", newlen); + OPENSSL_strlcat(include_path, include, newlen); + OPENSSL_free(include); + } else { + include_path = include; + } + + if (conf->flag_abspath + && !ossl_is_absolute_path(include_path)) { + ERR_raise(ERR_LIB_CONF, CONF_R_RELATIVE_PATH); + OPENSSL_free(include_path); + goto err; + } + /* get the BIO of the included file */ #ifndef OPENSSL_NO_POSIX_IO - next = process_include(include, &dirctx, &dirpath); - if (include != dirpath) { + next = process_include(include_path, &dirctx, &dirpath); + if (include_path != dirpath) { /* dirpath will contain include in case of a directory */ - OPENSSL_free(include); + OPENSSL_free(include_path); } #else - next = BIO_new_file(include, "r"); - OPENSSL_free(include); + next = BIO_new_file(include_path, "r"); + OPENSSL_free(include_path); #endif + if (next != NULL) { /* push the currently processing BIO onto stack */ if (biosk == NULL) { if ((biosk = sk_BIO_new_null()) == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); BIO_free(next); goto err; } } if (!sk_BIO_push(biosk, in)) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); BIO_free(next); goto err; } @@ -404,7 +510,8 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) } continue; } else if (*p != '=') { - CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN); + ERR_raise_data(ERR_LIB_CONF, CONF_R_MISSING_EQUAL_SIGN, + "HERE-->%s", p); goto err; } *end = '\0'; @@ -413,13 +520,13 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) trim_ws(conf, start); if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); goto err; } v->name = OPENSSL_strdup(pname); v->value = NULL; if (v->name == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); goto err; } if (!str_copy(conf, psection, &(v->value), start)) @@ -430,14 +537,14 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) == NULL) tv = _CONF_new_section(conf, psection); if (tv == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, - CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + ERR_raise(ERR_LIB_CONF, + CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } } else tv = sv; if (_CONF_add_string(conf, tv, v) == 0) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); goto err; } v = NULL; @@ -451,6 +558,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) */ sk_BIO_free(biosk); return 1; + err: BUF_MEM_free(buff); OPENSSL_free(section); @@ -581,7 +689,10 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) buf->data[to++] = v; } else if (IS_EOF(conf, *from)) break; - else if (*from == '$') { + else if (*from == '$' + && (!conf->flag_dollarid + || from[1] == '{' + || from[1] == '(')) { size_t newsize; /* try to expand it */ @@ -598,7 +709,8 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) s++; cp = section; e = np = s; - while (IS_ALNUM(conf, *e)) + while (IS_ALNUM(conf, *e) + || (conf->flag_dollarid && IS_DOLLAR(conf, *e))) e++; if ((e[0] == ':') && (e[1] == ':')) { cp = np; @@ -607,7 +719,8 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) *rrp = '\0'; e += 2; np = e; - while (IS_ALNUM(conf, *e)) + while (IS_ALNUM(conf, *e) + || (conf->flag_dollarid && IS_DOLLAR(conf, *e))) e++; } r = *e; @@ -615,7 +728,7 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) rp = e; if (q) { if (r != q) { - CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE); + ERR_raise(ERR_LIB_CONF, CONF_R_NO_CLOSE_BRACE); goto err; } e++; @@ -635,16 +748,16 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) *rrp = rr; *rp = r; if (p == NULL) { - CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE); + ERR_raise(ERR_LIB_CONF, CONF_R_VARIABLE_HAS_NO_VALUE); goto err; } newsize = strlen(p) + buf->length - (e - from); if (newsize > MAX_CONF_VALUE_LENGTH) { - CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_EXPANSION_TOO_LONG); + ERR_raise(ERR_LIB_CONF, CONF_R_VARIABLE_EXPANSION_TOO_LONG); goto err; } if (!BUF_MEM_grow_clean(buf, newsize)) { - CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); goto err; } while (*p) @@ -685,21 +798,19 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx, char **dirpath) { - struct stat st = { 0 }; + struct stat st; BIO *next; if (stat(include, &st) < 0) { - SYSerr(SYS_F_STAT, errno); - ERR_add_error_data(1, include); + ERR_raise_data(ERR_LIB_SYS, errno, "calling stat(%s)", include); /* missing include file is not fatal error */ return NULL; } if (S_ISDIR(st.st_mode)) { if (*dirctx != NULL) { - CONFerr(CONF_F_PROCESS_INCLUDE, - CONF_R_RECURSIVE_DIRECTORY_INCLUDE); - ERR_add_error_data(1, include); + ERR_raise_data(ERR_LIB_CONF, CONF_R_RECURSIVE_DIRECTORY_INCLUDE, + "%s", include); return NULL; } /* a directory, load its contents */ @@ -728,8 +839,10 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) namelen = strlen(filename); - if ((namelen > 5 && strcasecmp(filename + namelen - 5, ".conf") == 0) - || (namelen > 4 && strcasecmp(filename + namelen - 4, ".cnf") == 0)) { + if ((namelen > 5 + && OPENSSL_strcasecmp(filename + namelen - 5, ".conf") == 0) + || (namelen > 4 + && OPENSSL_strcasecmp(filename + namelen - 4, ".cnf") == 0)) { size_t newlen; char *newpath; BIO *bio; @@ -737,7 +850,7 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) newlen = pathlen + namelen + 2; newpath = OPENSSL_zalloc(newlen); if (newpath == NULL) { - CONFerr(CONF_F_GET_NEXT_FILE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); break; } #ifdef OPENSSL_SYS_VMS @@ -822,7 +935,8 @@ static char *eat_alpha_numeric(CONF *conf, char *p) p = scan_esc(conf, p); continue; } - if (!IS_ALNUM_PUNCT(conf, *p)) + if (!(IS_ALNUM_PUNCT(conf, *p) + || (conf->flag_dollarid && IS_DOLLAR(conf, *p)))) return p; p++; } diff --git a/crypto/openssl/crypto/conf/conf_def.h b/crypto/openssl/crypto/conf/conf_def.h index 0490236287ac..1f66a58e0923 100644 --- a/crypto/openssl/crypto/conf/conf_def.h +++ b/crypto/openssl/crypto/conf/conf_def.h @@ -2,8 +2,8 @@ * WARNING: do not edit! * Generated by crypto/conf/keysets.pl * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. - * Licensed under the OpenSSL license (the "License"). You may not use + * Copyright 1995-2021 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 @@ -20,6 +20,7 @@ #define CONF_DQUOTE 1024 #define CONF_COMMENT 128 #define CONF_FCOMMENT 2048 +#define CONF_DOLLAR 4096 #define CONF_EOF 8 #define CONF_ALPHA (CONF_UPPER|CONF_LOWER) #define CONF_ALNUM (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) @@ -36,13 +37,14 @@ #define IS_ALNUM_PUNCT(conf,c) is_keytype(conf, c, CONF_ALNUM_PUNCT) #define IS_QUOTE(conf,c) is_keytype(conf, c, CONF_QUOTE) #define IS_DQUOTE(conf,c) is_keytype(conf, c, CONF_DQUOTE) +#define IS_DOLLAR(conf,c) is_keytype(conf, c, CONF_DOLLAR) static const unsigned short CONF_type_default[128] = { 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0010, 0x0200, 0x0040, 0x0080, 0x0000, 0x0200, 0x0200, 0x0040, + 0x0010, 0x0200, 0x0040, 0x0080, 0x1000, 0x0200, 0x0200, 0x0040, 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, @@ -56,12 +58,13 @@ static const unsigned short CONF_type_default[128] = { 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, }; +#ifndef OPENSSL_NO_DEPRECATED_3_0 static const unsigned short CONF_type_win32[128] = { 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0010, 0x0200, 0x0400, 0x0000, 0x0000, 0x0200, 0x0200, 0x0000, + 0x0010, 0x0200, 0x0400, 0x0000, 0x1000, 0x0200, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0A00, 0x0000, 0x0000, 0x0000, 0x0200, @@ -74,3 +77,4 @@ static const unsigned short CONF_type_win32[128] = { 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, }; +#endif diff --git a/crypto/openssl/crypto/conf/conf_err.c b/crypto/openssl/crypto/conf/conf_err.c index f7613584ec3e..68ee90b97055 100644 --- a/crypto/openssl/crypto/conf/conf_err.c +++ b/crypto/openssl/crypto/conf/conf_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,41 +10,17 @@ #include #include +#include "crypto/conferr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA CONF_str_functs[] = { - {ERR_PACK(ERR_LIB_CONF, CONF_F_CONF_DUMP_FP, 0), "CONF_dump_fp"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_CONF_LOAD, 0), "CONF_load"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_CONF_LOAD_FP, 0), "CONF_load_fp"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_CONF_PARSE_LIST, 0), "CONF_parse_list"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_DEF_LOAD, 0), "def_load"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_DEF_LOAD_BIO, 0), "def_load_bio"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_GET_NEXT_FILE, 0), "get_next_file"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_MODULE_ADD, 0), "module_add"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_MODULE_INIT, 0), "module_init"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_MODULE_LOAD_DSO, 0), "module_load_dso"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_MODULE_RUN, 0), "module_run"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_DUMP_BIO, 0), "NCONF_dump_bio"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_DUMP_FP, 0), "NCONF_dump_fp"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_GET_NUMBER_E, 0), - "NCONF_get_number_e"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_GET_SECTION, 0), "NCONF_get_section"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_GET_STRING, 0), "NCONF_get_string"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_LOAD, 0), "NCONF_load"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_LOAD_BIO, 0), "NCONF_load_bio"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_LOAD_FP, 0), "NCONF_load_fp"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_NCONF_NEW, 0), "NCONF_new"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_PROCESS_INCLUDE, 0), "process_include"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_SSL_MODULE_INIT, 0), "ssl_module_init"}, - {ERR_PACK(ERR_LIB_CONF, CONF_F_STR_COPY, 0), "str_copy"}, - {0, NULL} -}; - static const ERR_STRING_DATA CONF_str_reasons[] = { {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_ERROR_LOADING_DSO), "error loading dso"}, + {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_INVALID_PRAGMA), "invalid pragma"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_LIST_CANNOT_BE_NULL), "list cannot be null"}, + {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_MANDATORY_BRACES_IN_VARIABLE_EXPANSION), + "mandatory braces in variable expansion"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_MISSING_CLOSE_SQUARE_BRACKET), "missing close square bracket"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_MISSING_EQUAL_SIGN), @@ -61,8 +37,11 @@ static const ERR_STRING_DATA CONF_str_reasons[] = { {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_SUCH_FILE), "no such file"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_VALUE), "no value"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NUMBER_TOO_LARGE), "number too large"}, + {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION), + "openssl conf references missing section"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_RECURSIVE_DIRECTORY_INCLUDE), "recursive directory include"}, + {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_RELATIVE_PATH), "relative path"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_SSL_COMMAND_SECTION_EMPTY), "ssl command section empty"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_SSL_COMMAND_SECTION_NOT_FOUND), @@ -83,13 +62,11 @@ static const ERR_STRING_DATA CONF_str_reasons[] = { #endif -int ERR_load_CONF_strings(void) +int ossl_err_load_CONF_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(CONF_str_functs[0].error) == NULL) { - ERR_load_strings_const(CONF_str_functs); + if (ERR_reason_error_string(CONF_str_reasons[0].error) == NULL) ERR_load_strings_const(CONF_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/conf/conf_lib.c b/crypto/openssl/crypto/conf/conf_lib.c index add1dfa1c181..a2360035257a 100644 --- a/crypto/openssl/crypto/conf/conf_lib.c +++ b/crypto/openssl/crypto/conf/conf_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -16,6 +16,7 @@ #include #include #include +#include "conf_local.h" #include static CONF_METHOD *default_CONF_method = NULL; @@ -54,7 +55,7 @@ LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, in = BIO_new_file(file, "rb"); #endif if (in == NULL) { - CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_CONF, ERR_R_SYS_LIB); return NULL; } @@ -71,7 +72,7 @@ LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, BIO *btmp; LHASH_OF(CONF_VALUE) *ltmp; if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { - CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); return NULL; } ltmp = CONF_load_bio(conf, btmp, eline); @@ -101,6 +102,7 @@ STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, return NULL; } else { CONF ctmp; + CONF_set_nconf(&ctmp, conf); return NCONF_get_section(&ctmp, section); } @@ -113,6 +115,7 @@ char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, return NCONF_get_string(NULL, group, name); } else { CONF ctmp; + CONF_set_nconf(&ctmp, conf); return NCONF_get_string(&ctmp, group, name); } @@ -129,6 +132,7 @@ long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, status = NCONF_get_number_e(NULL, group, name, &result); } else { CONF ctmp; + CONF_set_nconf(&ctmp, conf); status = NCONF_get_number_e(&ctmp, group, name, &result); } @@ -150,7 +154,7 @@ int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) int ret; if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) { - CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); return 0; } ret = CONF_dump_bio(conf, btmp); @@ -162,6 +166,7 @@ int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) { CONF ctmp; + CONF_set_nconf(&ctmp, conf); return NCONF_dump_bio(&ctmp, out); } @@ -174,7 +179,7 @@ int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) * the "CONF classic" functions, for consistency. */ -CONF *NCONF_new(CONF_METHOD *meth) +CONF *NCONF_new_ex(OSSL_LIB_CTX *libctx, CONF_METHOD *meth) { CONF *ret; @@ -183,13 +188,19 @@ CONF *NCONF_new(CONF_METHOD *meth) ret = meth->create(meth); if (ret == NULL) { - CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); return NULL; } + ret->libctx = libctx; return ret; } +CONF *NCONF_new(CONF_METHOD *meth) +{ + return NCONF_new_ex(NULL, meth); +} + void NCONF_free(CONF *conf) { if (conf == NULL) @@ -204,10 +215,42 @@ void NCONF_free_data(CONF *conf) conf->meth->destroy_data(conf); } +OSSL_LIB_CTX *NCONF_get0_libctx(const CONF *conf) +{ + return conf->libctx; +} + +typedef STACK_OF(OPENSSL_CSTRING) SECTION_NAMES; + +IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, SECTION_NAMES); + +static void collect_section_name(const CONF_VALUE *v, SECTION_NAMES *names) +{ + /* A section is a CONF_VALUE with name == NULL */ + if (v->name == NULL) + sk_OPENSSL_CSTRING_push(names, v->section); +} + +static int section_name_cmp(OPENSSL_CSTRING const *a, OPENSSL_CSTRING const *b) +{ + return strcmp(*a, *b); +} + +STACK_OF(OPENSSL_CSTRING) *NCONF_get_section_names(const CONF *cnf) +{ + SECTION_NAMES *names; + + if ((names = sk_OPENSSL_CSTRING_new(section_name_cmp)) == NULL) + return NULL; + lh_CONF_VALUE_doall_SECTION_NAMES(cnf->data, collect_section_name, names); + sk_OPENSSL_CSTRING_sort(names); + return names; +} + int NCONF_load(CONF *conf, const char *file, long *eline) { if (conf == NULL) { - CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF); + ERR_raise(ERR_LIB_CONF, CONF_R_NO_CONF); return 0; } @@ -220,7 +263,7 @@ int NCONF_load_fp(CONF *conf, FILE *fp, long *eline) BIO *btmp; int ret; if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { - CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); return 0; } ret = NCONF_load_bio(conf, btmp, eline); @@ -232,7 +275,7 @@ int NCONF_load_fp(CONF *conf, FILE *fp, long *eline) int NCONF_load_bio(CONF *conf, BIO *bp, long *eline) { if (conf == NULL) { - CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF); + ERR_raise(ERR_LIB_CONF, CONF_R_NO_CONF); return 0; } @@ -242,12 +285,12 @@ int NCONF_load_bio(CONF *conf, BIO *bp, long *eline) STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) { if (conf == NULL) { - CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF); + ERR_raise(ERR_LIB_CONF, CONF_R_NO_CONF); return NULL; } if (section == NULL) { - CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION); + ERR_raise(ERR_LIB_CONF, CONF_R_NO_SECTION); return NULL; } @@ -266,12 +309,11 @@ char *NCONF_get_string(const CONF *conf, const char *group, const char *name) return s; if (conf == NULL) { - CONFerr(CONF_F_NCONF_GET_STRING, - CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); + ERR_raise(ERR_LIB_CONF, CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); return NULL; } - CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE); - ERR_add_error_data(4, "group=", group, " name=", name); + ERR_raise_data(ERR_LIB_CONF, CONF_R_NO_VALUE, + "group=%s name=%s", group, name); return NULL; } @@ -294,7 +336,7 @@ int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, int (*to_int)(const CONF *, char) = &default_to_int; if (result == NULL) { - CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_CONF, ERR_R_PASSED_NULL_PARAMETER); return 0; } @@ -313,7 +355,7 @@ int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, const int d = to_int(conf, *str); if (res > (LONG_MAX - d) / 10L) { - CONFerr(CONF_F_NCONF_GET_NUMBER_E, CONF_R_NUMBER_TOO_LARGE); + ERR_raise(ERR_LIB_CONF, CONF_R_NUMBER_TOO_LARGE); return 0; } res = res * 10 + d; @@ -323,13 +365,25 @@ int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, return 1; } +long _CONF_get_number(const CONF *conf, const char *section, + const char *name) +{ + int status; + long result = 0; + + ERR_set_mark(); + status = NCONF_get_number_e(conf, section, name, &result); + ERR_pop_to_mark(); + return status == 0 ? 0L : result; +} + #ifndef OPENSSL_NO_STDIO int NCONF_dump_fp(const CONF *conf, FILE *out) { BIO *btmp; int ret; if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) { - CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); return 0; } ret = NCONF_dump_bio(conf, btmp); @@ -341,7 +395,7 @@ int NCONF_dump_fp(const CONF *conf, FILE *out) int NCONF_dump_bio(const CONF *conf, BIO *out) { if (conf == NULL) { - CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF); + ERR_raise(ERR_LIB_CONF, CONF_R_NO_CONF); return 0; } diff --git a/crypto/openssl/crypto/conf/conf_local.h b/crypto/openssl/crypto/conf/conf_local.h index 6e1f7fe00d70..f3b16f113852 100644 --- a/crypto/openssl/crypto/conf/conf_local.h +++ b/crypto/openssl/crypto/conf/conf_local.h @@ -1,11 +1,11 @@ /* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ -void conf_add_ssl_module(void); - +#include +void ossl_config_add_ssl_module(void); diff --git a/crypto/openssl/crypto/conf/conf_mall.c b/crypto/openssl/crypto/conf/conf_mall.c index d7eaa8509b2f..bad19c96cca0 100644 --- a/crypto/openssl/crypto/conf/conf_mall.c +++ b/crypto/openssl/crypto/conf/conf_mall.c @@ -1,12 +1,15 @@ /* - * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include "internal/cryptlib.h" @@ -14,6 +17,8 @@ #include #include #include +#include "internal/provider.h" +#include "crypto/rand.h" #include "conf_local.h" /* Load all OpenSSL builtin modules */ @@ -27,5 +32,7 @@ void OPENSSL_load_builtin_modules(void) ENGINE_add_conf_module(); #endif EVP_add_alg_module(); - conf_add_ssl_module(); + ossl_config_add_ssl_module(); + ossl_provider_add_conf_module(); + ossl_random_add_conf_module(); } diff --git a/crypto/openssl/crypto/conf/conf_mod.c b/crypto/openssl/crypto/conf/conf_mod.c index e703d97f5451..17bbbf7a2747 100644 --- a/crypto/openssl/crypto/conf/conf_mod.c +++ b/crypto/openssl/crypto/conf/conf_mod.c @@ -1,19 +1,30 @@ /* - * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "internal/cryptlib.h" #include #include #include #include "internal/conf.h" +#include #include "internal/dso.h" +#include "internal/thread_once.h" #include +#include +#include +#include "conf_local.h" + +DEFINE_STACK_OF(CONF_MODULE) +DEFINE_STACK_OF(CONF_IMODULE) #define DSO_mod_init_name "OPENSSL_init" #define DSO_mod_finish_name "OPENSSL_finish" @@ -51,8 +62,12 @@ struct conf_imodule_st { void *usr_data; }; -static STACK_OF(CONF_MODULE) *supported_modules = NULL; -static STACK_OF(CONF_IMODULE) *initialized_modules = NULL; +static CRYPTO_ONCE init_module_list_lock = CRYPTO_ONCE_STATIC_INIT; +static CRYPTO_RWLOCK *module_list_lock = NULL; +static STACK_OF(CONF_MODULE) *supported_modules = NULL; /* protected by lock */ +static STACK_OF(CONF_IMODULE) *initialized_modules = NULL; /* protected by lock */ + +static CRYPTO_ONCE load_builtin_modules = CRYPTO_ONCE_STATIC_INIT; static void module_free(CONF_MODULE *md); static void module_finish(CONF_IMODULE *imod); @@ -67,6 +82,36 @@ static int module_init(CONF_MODULE *pmod, const char *name, const char *value, static CONF_MODULE *module_load_dso(const CONF *cnf, const char *name, const char *value); +static int conf_modules_finish_int(void); + +static void module_lists_free(void) +{ + CRYPTO_THREAD_lock_free(module_list_lock); + module_list_lock = NULL; + + sk_CONF_MODULE_free(supported_modules); + supported_modules = NULL; + + sk_CONF_IMODULE_free(initialized_modules); + initialized_modules = NULL; +} + +DEFINE_RUN_ONCE_STATIC(do_init_module_list_lock) +{ + module_list_lock = CRYPTO_THREAD_lock_new(); + if (module_list_lock == NULL) { + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +static int conf_diagnostics(const CONF *cnf) +{ + return _CONF_get_number(cnf, NULL, "config_diagnostics") != 0; +} + /* Main function: load modules from a CONF structure */ int CONF_modules_load(const CONF *cnf, const char *appname, @@ -75,12 +120,18 @@ int CONF_modules_load(const CONF *cnf, const char *appname, STACK_OF(CONF_VALUE) *values; CONF_VALUE *vl; char *vsection = NULL; - int ret, i; if (!cnf) return 1; + if (conf_diagnostics(cnf)) + flags &= ~(CONF_MFLAGS_IGNORE_ERRORS + | CONF_MFLAGS_IGNORE_RETURN_CODES + | CONF_MFLAGS_SILENT + | CONF_MFLAGS_IGNORE_MISSING_FILE); + + ERR_set_mark(); if (appname) vsection = NCONF_get_string(cnf, NULL, appname); @@ -88,72 +139,116 @@ int CONF_modules_load(const CONF *cnf, const char *appname, vsection = NCONF_get_string(cnf, NULL, "openssl_conf"); if (!vsection) { - ERR_clear_error(); + ERR_pop_to_mark(); return 1; } + OSSL_TRACE1(CONF, "Configuration in section %s\n", vsection); values = NCONF_get_section(cnf, vsection); - if (!values) + if (values == NULL) { + if (!(flags & CONF_MFLAGS_SILENT)) { + ERR_clear_last_mark(); + ERR_raise_data(ERR_LIB_CONF, + CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION, + "openssl_conf=%s", vsection); + } else { + ERR_pop_to_mark(); + } return 0; + } + ERR_pop_to_mark(); for (i = 0; i < sk_CONF_VALUE_num(values); i++) { vl = sk_CONF_VALUE_value(values, i); + ERR_set_mark(); ret = module_run(cnf, vl->name, vl->value, flags); + OSSL_TRACE3(CONF, "Running module %s (%s) returned %d\n", + vl->name, vl->value, ret); if (ret <= 0) - if (!(flags & CONF_MFLAGS_IGNORE_ERRORS)) + if (!(flags & CONF_MFLAGS_IGNORE_ERRORS)) { + ERR_clear_last_mark(); return ret; + } + ERR_pop_to_mark(); } return 1; } -int CONF_modules_load_file(const char *filename, const char *appname, - unsigned long flags) +int CONF_modules_load_file_ex(OSSL_LIB_CTX *libctx, const char *filename, + const char *appname, unsigned long flags) { char *file = NULL; CONF *conf = NULL; - int ret = 0; - conf = NCONF_new(NULL); - if (conf == NULL) - goto err; + int ret = 0, diagnostics = 0; if (filename == NULL) { file = CONF_get1_default_config_file(); - if (!file) + if (file == NULL) goto err; - } else + } else { file = (char *)filename; + } + + ERR_set_mark(); + conf = NCONF_new_ex(libctx, NULL); + if (conf == NULL) + goto err; if (NCONF_load(conf, file, NULL) <= 0) { if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) && (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) { - ERR_clear_error(); ret = 1; } goto err; } ret = CONF_modules_load(conf, appname, flags); + diagnostics = conf_diagnostics(conf); err: if (filename == NULL) OPENSSL_free(file); NCONF_free(conf); - if (flags & CONF_MFLAGS_IGNORE_RETURN_CODES) - return 1; + if ((flags & CONF_MFLAGS_IGNORE_RETURN_CODES) != 0 && !diagnostics) + ret = 1; + + if (ret > 0) + ERR_pop_to_mark(); + else + ERR_clear_last_mark(); return ret; } +int CONF_modules_load_file(const char *filename, + const char *appname, unsigned long flags) +{ + return CONF_modules_load_file_ex(NULL, filename, appname, flags); +} + +DEFINE_RUN_ONCE_STATIC(do_load_builtin_modules) +{ + OPENSSL_load_builtin_modules(); +#ifndef OPENSSL_NO_ENGINE + /* Need to load ENGINEs */ + ENGINE_load_builtin_engines(); +#endif + return 1; +} + static int module_run(const CONF *cnf, const char *name, const char *value, unsigned long flags) { CONF_MODULE *md; int ret; + if (!RUN_ONCE(&load_builtin_modules, do_load_builtin_modules)) + return -1; + md = module_find(name); /* Module not found: try to load DSO */ @@ -162,8 +257,8 @@ static int module_run(const CONF *cnf, const char *name, const char *value, if (!md) { if (!(flags & CONF_MFLAGS_SILENT)) { - CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME); - ERR_add_error_data(2, "module=", name); + ERR_raise_data(ERR_LIB_CONF, CONF_R_UNKNOWN_MODULE_NAME, + "module=%s", name); } return -1; } @@ -171,14 +266,10 @@ static int module_run(const CONF *cnf, const char *name, const char *value, ret = module_init(md, name, value, cnf); if (ret <= 0) { - if (!(flags & CONF_MFLAGS_SILENT)) { - char rcode[DECIMAL_SIZE(ret) + 1]; - - CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR); - BIO_snprintf(rcode, sizeof(rcode), "%-8d", ret); - ERR_add_error_data(6, "module=", name, ", value=", value, - ", retcode=", rcode); - } + if (!(flags & CONF_MFLAGS_SILENT)) + ERR_raise_data(ERR_LIB_CONF, CONF_R_MODULE_INITIALIZATION_ERROR, + "module=%s, value=%s retcode=%-8d", + name, value, ret); } return ret; @@ -194,19 +285,19 @@ static CONF_MODULE *module_load_dso(const CONF *cnf, const char *path = NULL; int errcode = 0; CONF_MODULE *md; + /* Look for alternative path in module section */ - path = NCONF_get_string(cnf, value, "path"); - if (!path) { - ERR_clear_error(); + path = _CONF_get_string(cnf, value, "path"); + if (path == NULL) { path = name; } dso = DSO_load(NULL, path, NULL, 0); - if (!dso) { + if (dso == NULL) { errcode = CONF_R_ERROR_LOADING_DSO; goto err; } ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name); - if (!ifunc) { + if (ifunc == NULL) { errcode = CONF_R_MISSING_INIT_FUNCTION; goto err; } @@ -214,15 +305,14 @@ static CONF_MODULE *module_load_dso(const CONF *cnf, /* All OK, add module */ md = module_add(dso, name, ifunc, ffunc); - if (!md) + if (md == NULL) goto err; return md; err: DSO_free(dso); - CONFerr(CONF_F_MODULE_LOAD_DSO, errcode); - ERR_add_error_data(4, "module=", name, ", path=", path); + ERR_raise_data(ERR_LIB_CONF, errcode, "module=%s, path=%s", name, path); return NULL; } @@ -231,31 +321,42 @@ static CONF_MODULE *module_add(DSO *dso, const char *name, conf_init_func *ifunc, conf_finish_func *ffunc) { CONF_MODULE *tmod = NULL; + + if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock)) + return NULL; + + if (!CRYPTO_THREAD_write_lock(module_list_lock)) + return NULL; + if (supported_modules == NULL) supported_modules = sk_CONF_MODULE_new_null(); if (supported_modules == NULL) - return NULL; + goto err; if ((tmod = OPENSSL_zalloc(sizeof(*tmod))) == NULL) { - CONFerr(CONF_F_MODULE_ADD, ERR_R_MALLOC_FAILURE); - return NULL; + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + goto err; } tmod->dso = dso; tmod->name = OPENSSL_strdup(name); tmod->init = ifunc; tmod->finish = ffunc; - if (tmod->name == NULL) { - OPENSSL_free(tmod); - return NULL; - } + if (tmod->name == NULL) + goto err; + + if (!sk_CONF_MODULE_push(supported_modules, tmod)) + goto err; - if (!sk_CONF_MODULE_push(supported_modules, tmod)) { + CRYPTO_THREAD_unlock(module_list_lock); + return tmod; + + err: + CRYPTO_THREAD_unlock(module_list_lock); + if (tmod != NULL) { OPENSSL_free(tmod->name); OPENSSL_free(tmod); - return NULL; } - - return tmod; + return NULL; } /* @@ -276,14 +377,22 @@ static CONF_MODULE *module_find(const char *name) else nchar = strlen(name); + if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock)) + return NULL; + + if (!CRYPTO_THREAD_read_lock(module_list_lock)) + return NULL; + for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) { tmod = sk_CONF_MODULE_value(supported_modules, i); - if (strncmp(tmod->name, name, nchar) == 0) + if (strncmp(tmod->name, name, nchar) == 0) { + CRYPTO_THREAD_unlock(module_list_lock); return tmod; + } } + CRYPTO_THREAD_unlock(module_list_lock); return NULL; - } /* initialize a module */ @@ -316,21 +425,30 @@ static int module_init(CONF_MODULE *pmod, const char *name, const char *value, goto err; } + if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock)) + goto err; + + if (!CRYPTO_THREAD_write_lock(module_list_lock)) + goto err; + if (initialized_modules == NULL) { initialized_modules = sk_CONF_IMODULE_new_null(); - if (!initialized_modules) { - CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE); + if (initialized_modules == NULL) { + CRYPTO_THREAD_unlock(module_list_lock); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); goto err; } } if (!sk_CONF_IMODULE_push(initialized_modules, imod)) { - CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE); + CRYPTO_THREAD_unlock(module_list_lock); + ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); goto err; } pmod->links++; + CRYPTO_THREAD_unlock(module_list_lock); return ret; err: @@ -360,7 +478,13 @@ void CONF_modules_unload(int all) { int i; CONF_MODULE *md; - CONF_modules_finish(); + + if (!conf_modules_finish_int()) /* also inits module list lock */ + return; + + if (!CRYPTO_THREAD_write_lock(module_list_lock)) + return; + /* unload modules in reverse order */ for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) { md = sk_CONF_MODULE_value(supported_modules, i); @@ -371,10 +495,13 @@ void CONF_modules_unload(int all) (void)sk_CONF_MODULE_delete(supported_modules, i); module_free(md); } + if (sk_CONF_MODULE_num(supported_modules) == 0) { sk_CONF_MODULE_free(supported_modules); supported_modules = NULL; } + + CRYPTO_THREAD_unlock(module_list_lock); } /* unload a single module */ @@ -387,15 +514,33 @@ static void module_free(CONF_MODULE *md) /* finish and free up all modules instances */ -void CONF_modules_finish(void) +static int conf_modules_finish_int(void) { CONF_IMODULE *imod; + + if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock)) + return 0; + + /* If module_list_lock is NULL here it means we were already unloaded */ + if (module_list_lock == NULL + || !CRYPTO_THREAD_write_lock(module_list_lock)) + return 0; + while (sk_CONF_IMODULE_num(initialized_modules) > 0) { imod = sk_CONF_IMODULE_pop(initialized_modules); module_finish(imod); } sk_CONF_IMODULE_free(initialized_modules); initialized_modules = NULL; + + CRYPTO_THREAD_unlock(module_list_lock); + + return 1; +} + +void CONF_modules_finish(void) +{ + conf_modules_finish_int(); } /* finish a module instance */ @@ -423,10 +568,10 @@ int CONF_module_add(const char *name, conf_init_func *ifunc, return 0; } -void conf_modules_free_int(void) +void ossl_config_modules_free(void) { - CONF_modules_finish(); - CONF_modules_unload(1); + CONF_modules_unload(1); /* calls CONF_modules_finish */ + module_lists_free(); } /* Utility functions */ @@ -477,28 +622,25 @@ void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data) } /* Return default config file name */ - char *CONF_get1_default_config_file(void) { + const char *t; char *file, *sep = ""; - int len; + size_t size; if ((file = ossl_safe_getenv("OPENSSL_CONF")) != NULL) return OPENSSL_strdup(file); - len = strlen(X509_get_default_cert_area()); + t = X509_get_default_cert_area(); #ifndef OPENSSL_SYS_VMS - len++; sep = "/"; #endif - len += strlen(OPENSSL_CONF); - - file = OPENSSL_malloc(len + 1); + size = strlen(t) + strlen(sep) + strlen(OPENSSL_CONF) + 1; + file = OPENSSL_malloc(size); if (file == NULL) return NULL; - BIO_snprintf(file, len + 1, "%s%s%s", X509_get_default_cert_area(), - sep, OPENSSL_CONF); + BIO_snprintf(file, size, "%s%s%s", t, sep, OPENSSL_CONF); return file; } @@ -518,7 +660,7 @@ int CONF_parse_list(const char *list_, int sep, int nospc, const char *lstart, *tmpend, *p; if (list_ == NULL) { - CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL); + ERR_raise(ERR_LIB_CONF, CONF_R_LIST_CANNOT_BE_NULL); return 0; } @@ -529,7 +671,7 @@ int CONF_parse_list(const char *list_, int sep, int nospc, lstart++; } p = strchr(lstart, sep); - if (p == lstart || !*lstart) + if (p == lstart || *lstart == '\0') ret = list_cb(NULL, 0, arg); else { if (p) diff --git a/crypto/openssl/crypto/conf/conf_sap.c b/crypto/openssl/crypto/conf/conf_sap.c index 82105de748ed..39efcdbf90fa 100644 --- a/crypto/openssl/crypto/conf/conf_sap.c +++ b/crypto/openssl/crypto/conf/conf_sap.c @@ -1,7 +1,7 @@ /* - * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,11 +11,12 @@ #include #include "internal/cryptlib.h" #include "internal/conf.h" +#include "conf_local.h" #include #include #include -#ifdef _WIN32 +#if defined(_WIN32) && !defined(__BORLANDC__) # define strdup _strdup #endif @@ -27,7 +28,7 @@ static int openssl_configured = 0; -#if OPENSSL_API_COMPAT < 0x10100000L +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 void OPENSSL_config(const char *appname) { OPENSSL_INIT_SETTINGS settings; @@ -40,31 +41,29 @@ void OPENSSL_config(const char *appname) } #endif -int openssl_config_int(const OPENSSL_INIT_SETTINGS *settings) +int ossl_config_int(const OPENSSL_INIT_SETTINGS *settings) { int ret = 0; +#if defined(OPENSSL_INIT_DEBUG) || !defined(OPENSSL_SYS_UEFI) const char *filename; const char *appname; unsigned long flags; +#endif if (openssl_configured) return 1; +#if defined(OPENSSL_INIT_DEBUG) || !defined(OPENSSL_SYS_UEFI) filename = settings ? settings->filename : NULL; appname = settings ? settings->appname : NULL; flags = settings ? settings->flags : DEFAULT_CONF_MFLAGS; +#endif #ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: openssl_config_int(%s, %s, %lu)\n", + fprintf(stderr, "OPENSSL_INIT: ossl_config_int(%s, %s, %lu)\n", filename, appname, flags); #endif - OPENSSL_load_builtin_modules(); -#ifndef OPENSSL_NO_ENGINE - /* Need to load ENGINEs */ - ENGINE_load_builtin_engines(); -#endif - ERR_clear_error(); #ifndef OPENSSL_SYS_UEFI ret = CONF_modules_load_file(filename, appname, flags); #endif @@ -72,7 +71,7 @@ int openssl_config_int(const OPENSSL_INIT_SETTINGS *settings) return ret; } -void openssl_no_config_int(void) +void ossl_no_config_int(void) { openssl_configured = 1; } diff --git a/crypto/openssl/crypto/conf/conf_ssl.c b/crypto/openssl/crypto/conf/conf_ssl.c index 4bd8117d365c..84c5b2afe581 100644 --- a/crypto/openssl/crypto/conf/conf_ssl.c +++ b/crypto/openssl/crypto/conf/conf_ssl.c @@ -1,7 +1,7 @@ /* - * Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -68,11 +68,12 @@ static int ssl_module_init(CONF_IMODULE *md, const CONF *cnf) ssl_conf_section = CONF_imodule_get_value(md); cmd_lists = NCONF_get_section(cnf, ssl_conf_section); if (sk_CONF_VALUE_num(cmd_lists) <= 0) { - if (cmd_lists == NULL) - CONFerr(CONF_F_SSL_MODULE_INIT, CONF_R_SSL_SECTION_NOT_FOUND); - else - CONFerr(CONF_F_SSL_MODULE_INIT, CONF_R_SSL_SECTION_EMPTY); - ERR_add_error_data(2, "section=", ssl_conf_section); + int rcode = + cmd_lists == NULL + ? CONF_R_SSL_SECTION_NOT_FOUND + : CONF_R_SSL_SECTION_EMPTY; + + ERR_raise_data(ERR_LIB_CONF, rcode, "section=%s", ssl_conf_section); goto err; } cnt = sk_CONF_VALUE_num(cmd_lists); @@ -87,13 +88,13 @@ static int ssl_module_init(CONF_IMODULE *md, const CONF *cnf) STACK_OF(CONF_VALUE) *cmds = NCONF_get_section(cnf, sect->value); if (sk_CONF_VALUE_num(cmds) <= 0) { - if (cmds == NULL) - CONFerr(CONF_F_SSL_MODULE_INIT, - CONF_R_SSL_COMMAND_SECTION_NOT_FOUND); - else - CONFerr(CONF_F_SSL_MODULE_INIT, - CONF_R_SSL_COMMAND_SECTION_EMPTY); - ERR_add_error_data(4, "name=", sect->name, ", value=", sect->value); + int rcode = + cmds == NULL + ? CONF_R_SSL_COMMAND_SECTION_NOT_FOUND + : CONF_R_SSL_COMMAND_SECTION_EMPTY; + + ERR_raise_data(ERR_LIB_CONF, rcode, + "name=%s, value=%s", sect->name, sect->value); goto err; } ssl_name->name = OPENSSL_strdup(sect->name); @@ -175,7 +176,7 @@ void conf_ssl_get_cmd(const SSL_CONF_CMD *cmd, size_t idx, char **cmdstr, *arg = cmd[idx].arg; } -void conf_add_ssl_module(void) +void ossl_config_add_ssl_module(void) { CONF_module_add("ssl_conf", ssl_module_init, ssl_module_free); } diff --git a/crypto/openssl/crypto/conf/keysets.pl b/crypto/openssl/crypto/conf/keysets.pl old mode 100755 new mode 100644 index 9c9a00dea8d7..7e83d800501b --- a/crypto/openssl/crypto/conf/keysets.pl +++ b/crypto/openssl/crypto/conf/keysets.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -23,6 +23,7 @@ my $QUOTE = 0x0040; my $DQUOTE = 0x0400; my $COMMENT = 0x0080; my $FCOMMENT = 0x0800; +my $DOLLAR = 0x1000; my $EOF = 0x0008; my @V_def; my @V_w32; @@ -41,6 +42,7 @@ foreach (0 .. 127) { $v |= $ESC if $c =~ /\\/; $v |= $QUOTE if $c =~ /['`"]/; # for emacs: "`' $v |= $COMMENT if $c =~ /\#/; + $v |= $DOLLAR if $c eq '$'; $v |= $EOF if $c =~ /\0/; push(@V_def, $v); @@ -53,6 +55,7 @@ foreach (0 .. 127) { $v |= $WS if $c =~ /[ \t\r\n]/; $v |= $DQUOTE if $c =~ /["]/; # for emacs: " $v |= $FCOMMENT if $c =~ /;/; + $v |= $DOLLAR if $c eq '$'; $v |= $EOF if $c =~ /\0/; push(@V_w32, $v); } @@ -65,7 +68,7 @@ print <<"EOF"; * Generated by crypto/conf/keysets.pl * * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved. - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -82,6 +85,7 @@ print <<"EOF"; #define CONF_DQUOTE $DQUOTE #define CONF_COMMENT $COMMENT #define CONF_FCOMMENT $FCOMMENT +#define CONF_DOLLAR $DOLLAR #define CONF_EOF $EOF #define CONF_ALPHA (CONF_UPPER|CONF_LOWER) #define CONF_ALNUM (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) @@ -98,6 +102,7 @@ print <<"EOF"; #define IS_ALNUM_PUNCT(conf,c) is_keytype(conf, c, CONF_ALNUM_PUNCT) #define IS_QUOTE(conf,c) is_keytype(conf, c, CONF_QUOTE) #define IS_DQUOTE(conf,c) is_keytype(conf, c, CONF_DQUOTE) +#define IS_DOLLAR(conf,c) is_keytype(conf, c, CONF_DOLLAR) EOF @@ -110,9 +115,11 @@ for ($i = 0; $i < 128; $i++) { } print "\n};\n\n"; +print "#ifndef OPENSSL_NO_DEPRECATED_3_0\n"; print "static const unsigned short CONF_type_win32[128] = {"; for ($i = 0; $i < 128; $i++) { print "\n " if ($i % 8) == 0; printf " 0x%04X,", $V_w32[$i]; } print "\n};\n"; +print "#endif\n"; diff --git a/crypto/openssl/crypto/context.c b/crypto/openssl/crypto/context.c new file mode 100644 index 000000000000..548665fba265 --- /dev/null +++ b/crypto/openssl/crypto/context.c @@ -0,0 +1,510 @@ +/* + * Copyright 2019-2022 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 "crypto/cryptlib.h" +#include +#include "internal/thread_once.h" +#include "internal/property.h" +#include "internal/core.h" +#include "internal/bio.h" +#include "internal/provider.h" +#include "crypto/ctype.h" +#include "crypto/rand.h" + +struct ossl_lib_ctx_onfree_list_st { + ossl_lib_ctx_onfree_fn *fn; + struct ossl_lib_ctx_onfree_list_st *next; +}; + +struct ossl_lib_ctx_st { + CRYPTO_RWLOCK *lock; + CRYPTO_EX_DATA data; + + /* + * For most data in the OSSL_LIB_CTX we just use ex_data to store it. But + * that doesn't work for ex_data itself - so we store that directly. + */ + OSSL_EX_DATA_GLOBAL global; + + /* Map internal static indexes to dynamically created indexes */ + int dyn_indexes[OSSL_LIB_CTX_MAX_INDEXES]; + + /* Keep a separate lock for each index */ + CRYPTO_RWLOCK *index_locks[OSSL_LIB_CTX_MAX_INDEXES]; + + CRYPTO_RWLOCK *oncelock; + int run_once_done[OSSL_LIB_CTX_MAX_RUN_ONCE]; + int run_once_ret[OSSL_LIB_CTX_MAX_RUN_ONCE]; + struct ossl_lib_ctx_onfree_list_st *onfreelist; + unsigned int ischild:1; +}; + +int ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx) +{ + return CRYPTO_THREAD_write_lock(ossl_lib_ctx_get_concrete(ctx)->lock); +} + +int ossl_lib_ctx_read_lock(OSSL_LIB_CTX *ctx) +{ + return CRYPTO_THREAD_read_lock(ossl_lib_ctx_get_concrete(ctx)->lock); +} + +int ossl_lib_ctx_unlock(OSSL_LIB_CTX *ctx) +{ + return CRYPTO_THREAD_unlock(ossl_lib_ctx_get_concrete(ctx)->lock); +} + +int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx) +{ + ctx = ossl_lib_ctx_get_concrete(ctx); + + if (ctx == NULL) + return 0; + return ctx->ischild; +} + +static int context_init(OSSL_LIB_CTX *ctx) +{ + size_t i; + int exdata_done = 0; + + ctx->lock = CRYPTO_THREAD_lock_new(); + if (ctx->lock == NULL) + return 0; + + ctx->oncelock = CRYPTO_THREAD_lock_new(); + if (ctx->oncelock == NULL) + goto err; + + for (i = 0; i < OSSL_LIB_CTX_MAX_INDEXES; i++) { + ctx->index_locks[i] = CRYPTO_THREAD_lock_new(); + ctx->dyn_indexes[i] = -1; + if (ctx->index_locks[i] == NULL) + goto err; + } + + /* OSSL_LIB_CTX is built on top of ex_data so we initialise that directly */ + if (!ossl_do_ex_data_init(ctx)) + goto err; + exdata_done = 1; + + if (!ossl_crypto_new_ex_data_ex(ctx, CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL, + &ctx->data)) + goto err; + + /* Everything depends on properties, so we also pre-initialise that */ + if (!ossl_property_parse_init(ctx)) + goto err; + + return 1; + err: + if (exdata_done) + ossl_crypto_cleanup_all_ex_data_int(ctx); + for (i = 0; i < OSSL_LIB_CTX_MAX_INDEXES; i++) + CRYPTO_THREAD_lock_free(ctx->index_locks[i]); + CRYPTO_THREAD_lock_free(ctx->oncelock); + CRYPTO_THREAD_lock_free(ctx->lock); + memset(ctx, '\0', sizeof(*ctx)); + return 0; +} + +static int context_deinit(OSSL_LIB_CTX *ctx) +{ + struct ossl_lib_ctx_onfree_list_st *tmp, *onfree; + int i; + + if (ctx == NULL) + return 1; + + ossl_ctx_thread_stop(ctx); + + onfree = ctx->onfreelist; + while (onfree != NULL) { + onfree->fn(ctx); + tmp = onfree; + onfree = onfree->next; + OPENSSL_free(tmp); + } + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL, &ctx->data); + ossl_crypto_cleanup_all_ex_data_int(ctx); + for (i = 0; i < OSSL_LIB_CTX_MAX_INDEXES; i++) + CRYPTO_THREAD_lock_free(ctx->index_locks[i]); + + CRYPTO_THREAD_lock_free(ctx->oncelock); + CRYPTO_THREAD_lock_free(ctx->lock); + ctx->lock = NULL; + return 1; +} + +#ifndef FIPS_MODULE +/* The default default context */ +static OSSL_LIB_CTX default_context_int; + +static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT; +static CRYPTO_THREAD_LOCAL default_context_thread_local; + +DEFINE_RUN_ONCE_STATIC(default_context_do_init) +{ + return CRYPTO_THREAD_init_local(&default_context_thread_local, NULL) + && context_init(&default_context_int); +} + +void ossl_lib_ctx_default_deinit(void) +{ + context_deinit(&default_context_int); + CRYPTO_THREAD_cleanup_local(&default_context_thread_local); +} + +static OSSL_LIB_CTX *get_thread_default_context(void) +{ + if (!RUN_ONCE(&default_context_init, default_context_do_init)) + return NULL; + + return CRYPTO_THREAD_get_local(&default_context_thread_local); +} + +static OSSL_LIB_CTX *get_default_context(void) +{ + OSSL_LIB_CTX *current_defctx = get_thread_default_context(); + + if (current_defctx == NULL) + current_defctx = &default_context_int; + return current_defctx; +} + +static int set_default_context(OSSL_LIB_CTX *defctx) +{ + if (defctx == &default_context_int) + defctx = NULL; + + return CRYPTO_THREAD_set_local(&default_context_thread_local, defctx); +} +#endif + +OSSL_LIB_CTX *OSSL_LIB_CTX_new(void) +{ + OSSL_LIB_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx != NULL && !context_init(ctx)) { + OPENSSL_free(ctx); + ctx = NULL; + } + return ctx; +} + +#ifndef FIPS_MODULE +OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in) +{ + OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new(); + + if (ctx == NULL) + return NULL; + + if (!ossl_bio_init_core(ctx, in)) { + OSSL_LIB_CTX_free(ctx); + return NULL; + } + + return ctx; +} + +OSSL_LIB_CTX *OSSL_LIB_CTX_new_child(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in) +{ + OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new_from_dispatch(handle, in); + + if (ctx == NULL) + return NULL; + + if (!ossl_provider_init_as_child(ctx, handle, in)) { + OSSL_LIB_CTX_free(ctx); + return NULL; + } + ctx->ischild = 1; + + return ctx; +} + +int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file) +{ + return CONF_modules_load_file_ex(ctx, config_file, NULL, 0) > 0; +} +#endif + +void OSSL_LIB_CTX_free(OSSL_LIB_CTX *ctx) +{ + if (ossl_lib_ctx_is_default(ctx)) + return; + +#ifndef FIPS_MODULE + if (ctx->ischild) + ossl_provider_deinit_child(ctx); +#endif + context_deinit(ctx); + OPENSSL_free(ctx); +} + +#ifndef FIPS_MODULE +OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void) +{ + if (!RUN_ONCE(&default_context_init, default_context_do_init)) + return NULL; + + return &default_context_int; +} + +OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx) +{ + OSSL_LIB_CTX *current_defctx; + + if ((current_defctx = get_default_context()) != NULL) { + if (libctx != NULL) + set_default_context(libctx); + return current_defctx; + } + + return NULL; +} + +void ossl_release_default_drbg_ctx(void) +{ + int dynidx = default_context_int.dyn_indexes[OSSL_LIB_CTX_DRBG_INDEX]; + + /* early release of the DRBG in global default libctx, no locking */ + if (dynidx != -1) { + void *data; + + data = CRYPTO_get_ex_data(&default_context_int.data, dynidx); + ossl_rand_ctx_free(data); + CRYPTO_set_ex_data(&default_context_int.data, dynidx, NULL); + } +} +#endif + +OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx) +{ +#ifndef FIPS_MODULE + if (ctx == NULL) + return get_default_context(); +#endif + return ctx; +} + +int ossl_lib_ctx_is_default(OSSL_LIB_CTX *ctx) +{ +#ifndef FIPS_MODULE + if (ctx == NULL || ctx == get_default_context()) + return 1; +#endif + return 0; +} + +int ossl_lib_ctx_is_global_default(OSSL_LIB_CTX *ctx) +{ +#ifndef FIPS_MODULE + if (ossl_lib_ctx_get_concrete(ctx) == &default_context_int) + return 1; +#endif + return 0; +} + +static void ossl_lib_ctx_generic_new(void *parent_ign, void *ptr_ign, + CRYPTO_EX_DATA *ad, int index, + long argl_ign, void *argp) +{ + const OSSL_LIB_CTX_METHOD *meth = argp; + OSSL_LIB_CTX *ctx = ossl_crypto_ex_data_get_ossl_lib_ctx(ad); + void *ptr = meth->new_func(ctx); + + if (ptr != NULL) { + if (!CRYPTO_THREAD_write_lock(ctx->lock)) + /* + * Can't return something, so best to hope that something will + * fail later. :( + */ + return; + CRYPTO_set_ex_data(ad, index, ptr); + CRYPTO_THREAD_unlock(ctx->lock); + } +} +static void ossl_lib_ctx_generic_free(void *parent_ign, void *ptr, + CRYPTO_EX_DATA *ad, int index, + long argl_ign, void *argp) +{ + const OSSL_LIB_CTX_METHOD *meth = argp; + + meth->free_func(ptr); +} + +static int ossl_lib_ctx_init_index(OSSL_LIB_CTX *ctx, int static_index, + const OSSL_LIB_CTX_METHOD *meth) +{ + int idx; + + ctx = ossl_lib_ctx_get_concrete(ctx); + if (ctx == NULL) + return 0; + + idx = ossl_crypto_get_ex_new_index_ex(ctx, CRYPTO_EX_INDEX_OSSL_LIB_CTX, 0, + (void *)meth, + ossl_lib_ctx_generic_new, + NULL, ossl_lib_ctx_generic_free, + meth->priority); + if (idx < 0) + return 0; + + ctx->dyn_indexes[static_index] = idx; + return 1; +} + +void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index, + const OSSL_LIB_CTX_METHOD *meth) +{ + void *data = NULL; + int dynidx; + + ctx = ossl_lib_ctx_get_concrete(ctx); + if (ctx == NULL) + return NULL; + + if (!CRYPTO_THREAD_read_lock(ctx->lock)) + return NULL; + dynidx = ctx->dyn_indexes[index]; + CRYPTO_THREAD_unlock(ctx->lock); + + if (dynidx != -1) { + if (!CRYPTO_THREAD_read_lock(ctx->index_locks[index])) + return NULL; + if (!CRYPTO_THREAD_read_lock(ctx->lock)) { + CRYPTO_THREAD_unlock(ctx->index_locks[index]); + return NULL; + } + data = CRYPTO_get_ex_data(&ctx->data, dynidx); + CRYPTO_THREAD_unlock(ctx->lock); + CRYPTO_THREAD_unlock(ctx->index_locks[index]); + return data; + } + + if (!CRYPTO_THREAD_write_lock(ctx->index_locks[index])) + return NULL; + if (!CRYPTO_THREAD_write_lock(ctx->lock)) { + CRYPTO_THREAD_unlock(ctx->index_locks[index]); + return NULL; + } + + dynidx = ctx->dyn_indexes[index]; + if (dynidx != -1) { + data = CRYPTO_get_ex_data(&ctx->data, dynidx); + CRYPTO_THREAD_unlock(ctx->lock); + CRYPTO_THREAD_unlock(ctx->index_locks[index]); + return data; + } + + if (!ossl_lib_ctx_init_index(ctx, index, meth)) { + CRYPTO_THREAD_unlock(ctx->lock); + CRYPTO_THREAD_unlock(ctx->index_locks[index]); + return NULL; + } + + CRYPTO_THREAD_unlock(ctx->lock); + + /* + * The alloc call ensures there's a value there. We release the ctx->lock + * for this, because the allocation itself may recursively call + * ossl_lib_ctx_get_data for other indexes (never this one). The allocation + * will itself aquire the ctx->lock when it actually comes to store the + * allocated data (see ossl_lib_ctx_generic_new() above). We call + * ossl_crypto_alloc_ex_data_intern() here instead of CRYPTO_alloc_ex_data(). + * They do the same thing except that the latter calls CRYPTO_get_ex_data() + * as well - which we must not do without holding the ctx->lock. + */ + if (ossl_crypto_alloc_ex_data_intern(CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL, + &ctx->data, ctx->dyn_indexes[index])) { + if (!CRYPTO_THREAD_read_lock(ctx->lock)) + goto end; + data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]); + CRYPTO_THREAD_unlock(ctx->lock); + } + +end: + CRYPTO_THREAD_unlock(ctx->index_locks[index]); + return data; +} + +OSSL_EX_DATA_GLOBAL *ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX *ctx) +{ + ctx = ossl_lib_ctx_get_concrete(ctx); + if (ctx == NULL) + return NULL; + return &ctx->global; +} + +int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx, + ossl_lib_ctx_run_once_fn run_once_fn) +{ + int done = 0, ret = 0; + + ctx = ossl_lib_ctx_get_concrete(ctx); + if (ctx == NULL) + return 0; + + if (!CRYPTO_THREAD_read_lock(ctx->oncelock)) + return 0; + done = ctx->run_once_done[idx]; + if (done) + ret = ctx->run_once_ret[idx]; + CRYPTO_THREAD_unlock(ctx->oncelock); + + if (done) + return ret; + + if (!CRYPTO_THREAD_write_lock(ctx->oncelock)) + return 0; + if (ctx->run_once_done[idx]) { + ret = ctx->run_once_ret[idx]; + CRYPTO_THREAD_unlock(ctx->oncelock); + return ret; + } + + ret = run_once_fn(ctx); + ctx->run_once_done[idx] = 1; + ctx->run_once_ret[idx] = ret; + CRYPTO_THREAD_unlock(ctx->oncelock); + + return ret; +} + +int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn) +{ + struct ossl_lib_ctx_onfree_list_st *newonfree + = OPENSSL_malloc(sizeof(*newonfree)); + + if (newonfree == NULL) + return 0; + + newonfree->fn = onfreefn; + newonfree->next = ctx->onfreelist; + ctx->onfreelist = newonfree; + + return 1; +} + +const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx) +{ +#ifdef FIPS_MODULE + return "FIPS internal library context"; +#else + if (ossl_lib_ctx_is_global_default(libctx)) + return "Global default library context"; + if (ossl_lib_ctx_is_default(libctx)) + return "Thread-local default library context"; + return "Non-default library context"; +#endif +} diff --git a/crypto/openssl/crypto/core_algorithm.c b/crypto/openssl/crypto/core_algorithm.c new file mode 100644 index 000000000000..c245c814d98c --- /dev/null +++ b/crypto/openssl/crypto/core_algorithm.c @@ -0,0 +1,199 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/core.h" +#include "internal/property.h" +#include "internal/provider.h" + +struct algorithm_data_st { + OSSL_LIB_CTX *libctx; + int operation_id; /* May be zero for finding them all */ + int (*pre)(OSSL_PROVIDER *, int operation_id, int no_store, void *data, + int *result); + int (*reserve_store)(int no_store, void *data); + void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store, + void *data); + int (*unreserve_store)(void *data); + int (*post)(OSSL_PROVIDER *, int operation_id, int no_store, void *data, + int *result); + void *data; +}; + +/* + * Process one OSSL_ALGORITHM array, for the operation |cur_operation|, + * by constructing methods for all its implementations and adding those + * to the appropriate method store. + * Which method store is appropriate is given by |no_store| ("permanent" + * if 0, temporary if 1) and other data in |data->data|. + * + * Returns: + * -1 to quit adding algorithm implementations immediately + * 0 if not successful, but adding should continue + * 1 if successful so far, and adding should continue + */ +static int algorithm_do_map(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *map, + int cur_operation, int no_store, void *cbdata) +{ + struct algorithm_data_st *data = cbdata; + int ret = 0; + + if (!data->reserve_store(no_store, data->data)) + /* Error, bail out! */ + return -1; + + /* Do we fulfill pre-conditions? */ + if (data->pre == NULL) { + /* If there is no pre-condition function, assume "yes" */ + ret = 1; + } else if (!data->pre(provider, cur_operation, no_store, data->data, + &ret)) { + /* Error, bail out! */ + ret = -1; + goto end; + } + + /* + * If pre-condition not fulfilled don't add this set of implementations, + * but do continue with the next. This simply means that another thread + * got to it first. + */ + if (ret == 0) { + ret = 1; + goto end; + } + + if (map != NULL) { + const OSSL_ALGORITHM *thismap; + + for (thismap = map; thismap->algorithm_names != NULL; thismap++) + data->fn(provider, thismap, no_store, data->data); + } + + /* Do we fulfill post-conditions? */ + if (data->post == NULL) { + /* If there is no post-condition function, assume "yes" */ + ret = 1; + } else if (!data->post(provider, cur_operation, no_store, data->data, + &ret)) { + /* Error, bail out! */ + ret = -1; + } + + end: + data->unreserve_store(data->data); + + return ret; +} + +/* + * Given a provider, process one operation given by |data->operation_id|, or + * if that's zero, process all known operations. + * For each such operation, query the associated OSSL_ALGORITHM array from + * the provider, then process that array with |algorithm_do_map()|. + */ +static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata) +{ + struct algorithm_data_st *data = cbdata; + int first_operation = 1; + int last_operation = OSSL_OP__HIGHEST; + int cur_operation; + int ok = 1; + + if (data->operation_id != 0) + first_operation = last_operation = data->operation_id; + + for (cur_operation = first_operation; + cur_operation <= last_operation; + cur_operation++) { + int no_store = 0; /* Assume caching is ok */ + const OSSL_ALGORITHM *map = NULL; + int ret = 0; + + map = ossl_provider_query_operation(provider, cur_operation, + &no_store); + ret = algorithm_do_map(provider, map, cur_operation, no_store, data); + ossl_provider_unquery_operation(provider, cur_operation, map); + + if (ret < 0) + /* Hard error, bail out immediately! */ + return 0; + + /* If post-condition not fulfilled, set general failure */ + if (!ret) + ok = 0; + } + + return ok; +} + +void ossl_algorithm_do_all(OSSL_LIB_CTX *libctx, int operation_id, + OSSL_PROVIDER *provider, + int (*pre)(OSSL_PROVIDER *, int operation_id, + int no_store, void *data, int *result), + int (*reserve_store)(int no_store, void *data), + void (*fn)(OSSL_PROVIDER *provider, + const OSSL_ALGORITHM *algo, + int no_store, void *data), + int (*unreserve_store)(void *data), + int (*post)(OSSL_PROVIDER *, int operation_id, + int no_store, void *data, int *result), + void *data) +{ + struct algorithm_data_st cbdata = { 0, }; + + cbdata.libctx = libctx; + cbdata.operation_id = operation_id; + cbdata.pre = pre; + cbdata.reserve_store = reserve_store; + cbdata.fn = fn; + cbdata.unreserve_store = unreserve_store; + cbdata.post = post; + cbdata.data = data; + + if (provider == NULL) { + ossl_provider_doall_activated(libctx, algorithm_do_this, &cbdata); + } else { + OSSL_LIB_CTX *libctx2 = ossl_provider_libctx(provider); + + /* + * If a provider is given, its library context MUST match the library + * context we're passed. If this turns out not to be true, there is + * a programming error in the functions up the call stack. + */ + if (!ossl_assert(ossl_lib_ctx_get_concrete(libctx) + == ossl_lib_ctx_get_concrete(libctx2))) + return; + + cbdata.libctx = libctx2; + algorithm_do_this(provider, &cbdata); + } +} + +char *ossl_algorithm_get1_first_name(const OSSL_ALGORITHM *algo) +{ + const char *first_name_end = NULL; + size_t first_name_len = 0; + char *ret; + + if (algo->algorithm_names == NULL) + return NULL; + + first_name_end = strchr(algo->algorithm_names, ':'); + if (first_name_end == NULL) + first_name_len = strlen(algo->algorithm_names); + else + first_name_len = first_name_end - algo->algorithm_names; + + ret = OPENSSL_strndup(algo->algorithm_names, first_name_len); + if (ret == NULL) + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return ret; +} diff --git a/crypto/openssl/crypto/core_fetch.c b/crypto/openssl/crypto/core_fetch.c new file mode 100644 index 000000000000..38db36ee1f75 --- /dev/null +++ b/crypto/openssl/crypto/core_fetch.c @@ -0,0 +1,171 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include +#include "internal/cryptlib.h" +#include "internal/core.h" +#include "internal/property.h" +#include "internal/provider.h" + +struct construct_data_st { + OSSL_LIB_CTX *libctx; + OSSL_METHOD_STORE *store; + int operation_id; + int force_store; + OSSL_METHOD_CONSTRUCT_METHOD *mcm; + void *mcm_data; +}; + +static int is_temporary_method_store(int no_store, void *cbdata) +{ + struct construct_data_st *data = cbdata; + + return no_store && !data->force_store; +} + +static int ossl_method_construct_reserve_store(int no_store, void *cbdata) +{ + struct construct_data_st *data = cbdata; + + if (is_temporary_method_store(no_store, data) && data->store == NULL) { + /* + * If we have been told not to store the method "permanently", we + * ask for a temporary store, and store the method there. + * The owner of |data->mcm| is completely responsible for managing + * that temporary store. + */ + if ((data->store = data->mcm->get_tmp_store(data->mcm_data)) == NULL) + return 0; + } + + return data->mcm->lock_store(data->store, data->mcm_data); +} + +static int ossl_method_construct_unreserve_store(void *cbdata) +{ + struct construct_data_st *data = cbdata; + + return data->mcm->unlock_store(data->store, data->mcm_data); +} + +static int ossl_method_construct_precondition(OSSL_PROVIDER *provider, + int operation_id, int no_store, + void *cbdata, int *result) +{ + if (!ossl_assert(result != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* Assume that no bits are set */ + *result = 0; + + /* No flag bits for temporary stores */ + if (!is_temporary_method_store(no_store, cbdata) + && !ossl_provider_test_operation_bit(provider, operation_id, result)) + return 0; + + /* + * The result we get tells if methods have already been constructed. + * However, we want to tell whether construction should happen (true) + * or not (false), which is the opposite of what we got. + */ + *result = !*result; + + return 1; +} + +static int ossl_method_construct_postcondition(OSSL_PROVIDER *provider, + int operation_id, int no_store, + void *cbdata, int *result) +{ + if (!ossl_assert(result != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + *result = 1; + + /* No flag bits for temporary stores */ + return is_temporary_method_store(no_store, cbdata) + || ossl_provider_set_operation_bit(provider, operation_id); +} + +static void ossl_method_construct_this(OSSL_PROVIDER *provider, + const OSSL_ALGORITHM *algo, + int no_store, void *cbdata) +{ + struct construct_data_st *data = cbdata; + void *method = NULL; + + if ((method = data->mcm->construct(algo, provider, data->mcm_data)) + == NULL) + return; + + /* + * Note regarding putting the method in stores: + * + * we don't need to care if it actually got in or not here. + * If it didn't get in, it will simply not be available when + * ossl_method_construct() tries to get it from the store. + * + * It is *expected* that the put function increments the refcnt + * of the passed method. + */ + data->mcm->put(data->store, method, provider, algo->algorithm_names, + algo->property_definition, data->mcm_data); + + /* refcnt-- because we're dropping the reference */ + data->mcm->destruct(method, data->mcm_data); +} + +void *ossl_method_construct(OSSL_LIB_CTX *libctx, int operation_id, + OSSL_PROVIDER **provider_rw, int force_store, + OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data) +{ + void *method = NULL; + OSSL_PROVIDER *provider = provider_rw != NULL ? *provider_rw : NULL; + struct construct_data_st cbdata; + + /* + * We might be tempted to try to look into the method store without + * constructing to see if we can find our method there already. + * Unfortunately that does not work well if the query contains + * optional properties as newly loaded providers can match them better. + * We trust that ossl_method_construct_precondition() and + * ossl_method_construct_postcondition() make sure that the + * ossl_algorithm_do_all() does very little when methods from + * a provider have already been constructed. + */ + + cbdata.store = NULL; + cbdata.force_store = force_store; + cbdata.mcm = mcm; + cbdata.mcm_data = mcm_data; + ossl_algorithm_do_all(libctx, operation_id, provider, + ossl_method_construct_precondition, + ossl_method_construct_reserve_store, + ossl_method_construct_this, + ossl_method_construct_unreserve_store, + ossl_method_construct_postcondition, + &cbdata); + + /* If there is a temporary store, try there first */ + if (cbdata.store != NULL) + method = mcm->get(cbdata.store, (const OSSL_PROVIDER **)provider_rw, + mcm_data); + + /* If no method was found yet, try the global store */ + if (method == NULL) + method = mcm->get(NULL, (const OSSL_PROVIDER **)provider_rw, mcm_data); + + return method; +} diff --git a/crypto/openssl/crypto/core_namemap.c b/crypto/openssl/crypto/core_namemap.c new file mode 100644 index 000000000000..7e11ab1c8845 --- /dev/null +++ b/crypto/openssl/crypto/core_namemap.c @@ -0,0 +1,531 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/namemap.h" +#include +#include "crypto/lhash.h" /* ossl_lh_strcasehash */ +#include "internal/tsan_assist.h" +#include "internal/sizes.h" + +/*- + * The namenum entry + * ================= + */ +typedef struct { + char *name; + int number; +} NAMENUM_ENTRY; + +DEFINE_LHASH_OF(NAMENUM_ENTRY); + +/*- + * The namemap itself + * ================== + */ + +struct ossl_namemap_st { + /* Flags */ + unsigned int stored:1; /* If 1, it's stored in a library context */ + + CRYPTO_RWLOCK *lock; + LHASH_OF(NAMENUM_ENTRY) *namenum; /* Name->number mapping */ + + TSAN_QUALIFIER int max_number; /* Current max number */ +}; + +/* LHASH callbacks */ + +static unsigned long namenum_hash(const NAMENUM_ENTRY *n) +{ + return ossl_lh_strcasehash(n->name); +} + +static int namenum_cmp(const NAMENUM_ENTRY *a, const NAMENUM_ENTRY *b) +{ + return OPENSSL_strcasecmp(a->name, b->name); +} + +static void namenum_free(NAMENUM_ENTRY *n) +{ + if (n != NULL) + OPENSSL_free(n->name); + OPENSSL_free(n); +} + +/* OSSL_LIB_CTX_METHOD functions for a namemap stored in a library context */ + +static void *stored_namemap_new(OSSL_LIB_CTX *libctx) +{ + OSSL_NAMEMAP *namemap = ossl_namemap_new(); + + if (namemap != NULL) + namemap->stored = 1; + + return namemap; +} + +static void stored_namemap_free(void *vnamemap) +{ + OSSL_NAMEMAP *namemap = vnamemap; + + if (namemap != NULL) { + /* Pretend it isn't stored, or ossl_namemap_free() will do nothing */ + namemap->stored = 0; + ossl_namemap_free(namemap); + } +} + +static const OSSL_LIB_CTX_METHOD stored_namemap_method = { + OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, + stored_namemap_new, + stored_namemap_free, +}; + +/*- + * API functions + * ============= + */ + +int ossl_namemap_empty(OSSL_NAMEMAP *namemap) +{ +#ifdef TSAN_REQUIRES_LOCKING + /* No TSAN support */ + int rv; + + if (namemap == NULL) + return 1; + + if (!CRYPTO_THREAD_read_lock(namemap->lock)) + return -1; + rv = namemap->max_number == 0; + CRYPTO_THREAD_unlock(namemap->lock); + return rv; +#else + /* Have TSAN support */ + return namemap == NULL || tsan_load(&namemap->max_number) == 0; +#endif +} + +typedef struct doall_names_data_st { + int number; + const char **names; + int found; +} DOALL_NAMES_DATA; + +static void do_name(const NAMENUM_ENTRY *namenum, DOALL_NAMES_DATA *data) +{ + if (namenum->number == data->number) + data->names[data->found++] = namenum->name; +} + +IMPLEMENT_LHASH_DOALL_ARG_CONST(NAMENUM_ENTRY, DOALL_NAMES_DATA); + +/* + * Call the callback for all names in the namemap with the given number. + * A return value 1 means that the callback was called for all names. A + * return value of 0 means that the callback was not called for any names. + */ +int ossl_namemap_doall_names(const OSSL_NAMEMAP *namemap, int number, + void (*fn)(const char *name, void *data), + void *data) +{ + DOALL_NAMES_DATA cbdata; + size_t num_names; + int i; + + cbdata.number = number; + cbdata.found = 0; + + /* + * We collect all the names first under a read lock. Subsequently we call + * the user function, so that we're not holding the read lock when in user + * code. This could lead to deadlocks. + */ + if (!CRYPTO_THREAD_read_lock(namemap->lock)) + return 0; + + num_names = lh_NAMENUM_ENTRY_num_items(namemap->namenum); + if (num_names == 0) { + CRYPTO_THREAD_unlock(namemap->lock); + return 0; + } + cbdata.names = OPENSSL_malloc(sizeof(*cbdata.names) * num_names); + if (cbdata.names == NULL) { + CRYPTO_THREAD_unlock(namemap->lock); + return 0; + } + lh_NAMENUM_ENTRY_doall_DOALL_NAMES_DATA(namemap->namenum, do_name, + &cbdata); + CRYPTO_THREAD_unlock(namemap->lock); + + for (i = 0; i < cbdata.found; i++) + fn(cbdata.names[i], data); + + OPENSSL_free(cbdata.names); + return 1; +} + +static int namemap_name2num_n(const OSSL_NAMEMAP *namemap, + const char *name, size_t name_len) +{ + NAMENUM_ENTRY *namenum_entry, namenum_tmpl; + + if ((namenum_tmpl.name = OPENSSL_strndup(name, name_len)) == NULL) + return 0; + namenum_tmpl.number = 0; + namenum_entry = + lh_NAMENUM_ENTRY_retrieve(namemap->namenum, &namenum_tmpl); + OPENSSL_free(namenum_tmpl.name); + return namenum_entry != NULL ? namenum_entry->number : 0; +} + +int ossl_namemap_name2num_n(const OSSL_NAMEMAP *namemap, + const char *name, size_t name_len) +{ + int number; + +#ifndef FIPS_MODULE + if (namemap == NULL) + namemap = ossl_namemap_stored(NULL); +#endif + + if (namemap == NULL) + return 0; + + if (!CRYPTO_THREAD_read_lock(namemap->lock)) + return 0; + number = namemap_name2num_n(namemap, name, name_len); + CRYPTO_THREAD_unlock(namemap->lock); + + return number; +} + +int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name) +{ + if (name == NULL) + return 0; + + return ossl_namemap_name2num_n(namemap, name, strlen(name)); +} + +struct num2name_data_st { + size_t idx; /* Countdown */ + const char *name; /* Result */ +}; + +static void do_num2name(const char *name, void *vdata) +{ + struct num2name_data_st *data = vdata; + + if (data->idx > 0) + data->idx--; + else if (data->name == NULL) + data->name = name; +} + +const char *ossl_namemap_num2name(const OSSL_NAMEMAP *namemap, int number, + size_t idx) +{ + struct num2name_data_st data; + + data.idx = idx; + data.name = NULL; + if (!ossl_namemap_doall_names(namemap, number, do_num2name, &data)) + return NULL; + return data.name; +} + +static int namemap_add_name_n(OSSL_NAMEMAP *namemap, int number, + const char *name, size_t name_len) +{ + NAMENUM_ENTRY *namenum = NULL; + int tmp_number; + + /* If it already exists, we don't add it */ + if ((tmp_number = namemap_name2num_n(namemap, name, name_len)) != 0) + return tmp_number; + + if ((namenum = OPENSSL_zalloc(sizeof(*namenum))) == NULL + || (namenum->name = OPENSSL_strndup(name, name_len)) == NULL) + goto err; + + /* The tsan_counter use here is safe since we're under lock */ + namenum->number = + number != 0 ? number : 1 + tsan_counter(&namemap->max_number); + (void)lh_NAMENUM_ENTRY_insert(namemap->namenum, namenum); + + if (lh_NAMENUM_ENTRY_error(namemap->namenum)) + goto err; + return namenum->number; + + err: + namenum_free(namenum); + return 0; +} + +int ossl_namemap_add_name_n(OSSL_NAMEMAP *namemap, int number, + const char *name, size_t name_len) +{ + int tmp_number; + +#ifndef FIPS_MODULE + if (namemap == NULL) + namemap = ossl_namemap_stored(NULL); +#endif + + if (name == NULL || name_len == 0 || namemap == NULL) + return 0; + + if (!CRYPTO_THREAD_write_lock(namemap->lock)) + return 0; + tmp_number = namemap_add_name_n(namemap, number, name, name_len); + CRYPTO_THREAD_unlock(namemap->lock); + return tmp_number; +} + +int ossl_namemap_add_name(OSSL_NAMEMAP *namemap, int number, const char *name) +{ + if (name == NULL) + return 0; + + return ossl_namemap_add_name_n(namemap, number, name, strlen(name)); +} + +int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number, + const char *names, const char separator) +{ + const char *p, *q; + size_t l; + + /* Check that we have a namemap */ + if (!ossl_assert(namemap != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!CRYPTO_THREAD_write_lock(namemap->lock)) + return 0; + /* + * Check that no name is an empty string, and that all names have at + * most one numeric identity together. + */ + for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) { + int this_number; + + if ((q = strchr(p, separator)) == NULL) + l = strlen(p); /* offset to \0 */ + else + l = q - p; /* offset to the next separator */ + + this_number = namemap_name2num_n(namemap, p, l); + + if (*p == '\0' || *p == separator) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_BAD_ALGORITHM_NAME); + goto err; + } + if (number == 0) { + number = this_number; + } else if (this_number != 0 && this_number != number) { + ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_CONFLICTING_NAMES, + "\"%.*s\" has an existing different identity %d (from \"%s\")", + l, p, this_number, names); + goto err; + } + } + + /* Now that we have checked, register all names */ + for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) { + int this_number; + + if ((q = strchr(p, separator)) == NULL) + l = strlen(p); /* offset to \0 */ + else + l = q - p; /* offset to the next separator */ + + this_number = namemap_add_name_n(namemap, number, p, l); + if (number == 0) { + number = this_number; + } else if (this_number != number) { + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR, + "Got number %d when expecting %d", + this_number, number); + goto err; + } + } + + CRYPTO_THREAD_unlock(namemap->lock); + return number; + + err: + CRYPTO_THREAD_unlock(namemap->lock); + return 0; +} + +/*- + * Pre-population + * ============== + */ + +#ifndef FIPS_MODULE +#include + +/* Creates an initial namemap with names found in the legacy method db */ +static void get_legacy_evp_names(int base_nid, int nid, const char *pem_name, + void *arg) +{ + int num = 0; + ASN1_OBJECT *obj; + + if (base_nid != NID_undef) { + num = ossl_namemap_add_name(arg, num, OBJ_nid2sn(base_nid)); + num = ossl_namemap_add_name(arg, num, OBJ_nid2ln(base_nid)); + } + + if (nid != NID_undef) { + num = ossl_namemap_add_name(arg, num, OBJ_nid2sn(nid)); + num = ossl_namemap_add_name(arg, num, OBJ_nid2ln(nid)); + if ((obj = OBJ_nid2obj(nid)) != NULL) { + char txtoid[OSSL_MAX_NAME_SIZE]; + + if (OBJ_obj2txt(txtoid, sizeof(txtoid), obj, 1) > 0) + num = ossl_namemap_add_name(arg, num, txtoid); + } + } + if (pem_name != NULL) + num = ossl_namemap_add_name(arg, num, pem_name); +} + +static void get_legacy_cipher_names(const OBJ_NAME *on, void *arg) +{ + const EVP_CIPHER *cipher = (void *)OBJ_NAME_get(on->name, on->type); + + if (cipher != NULL) + get_legacy_evp_names(NID_undef, EVP_CIPHER_get_type(cipher), NULL, arg); +} + +static void get_legacy_md_names(const OBJ_NAME *on, void *arg) +{ + const EVP_MD *md = (void *)OBJ_NAME_get(on->name, on->type); + + if (md != NULL) + get_legacy_evp_names(0, EVP_MD_get_type(md), NULL, arg); +} + +static void get_legacy_pkey_meth_names(const EVP_PKEY_ASN1_METHOD *ameth, + void *arg) +{ + int nid = 0, base_nid = 0, flags = 0; + const char *pem_name = NULL; + + EVP_PKEY_asn1_get0_info(&nid, &base_nid, &flags, NULL, &pem_name, ameth); + if (nid != NID_undef) { + if ((flags & ASN1_PKEY_ALIAS) == 0) { + switch (nid) { + case EVP_PKEY_DHX: + /* We know that the name "DHX" is used too */ + get_legacy_evp_names(0, nid, "DHX", arg); + /* FALLTHRU */ + default: + get_legacy_evp_names(0, nid, pem_name, arg); + } + } else { + /* + * Treat aliases carefully, some of them are undesirable, or + * should not be treated as such for providers. + */ + + switch (nid) { + case EVP_PKEY_SM2: + /* + * SM2 is a separate keytype with providers, not an alias for + * EC. + */ + get_legacy_evp_names(0, nid, pem_name, arg); + break; + default: + /* Use the short name of the base nid as the common reference */ + get_legacy_evp_names(base_nid, nid, pem_name, arg); + } + } + } +} +#endif + +/*- + * Constructors / destructors + * ========================== + */ + +OSSL_NAMEMAP *ossl_namemap_stored(OSSL_LIB_CTX *libctx) +{ +#ifndef FIPS_MODULE + int nms; +#endif + OSSL_NAMEMAP *namemap = + ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_NAMEMAP_INDEX, + &stored_namemap_method); + + if (namemap == NULL) + return NULL; + +#ifndef FIPS_MODULE + nms = ossl_namemap_empty(namemap); + if (nms < 0) { + /* + * Could not get lock to make the count, so maybe internal objects + * weren't added. This seems safest. + */ + return NULL; + } + if (nms == 1) { + int i, end; + + /* Before pilfering, we make sure the legacy database is populated */ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS + | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); + + OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, + get_legacy_cipher_names, namemap); + OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, + get_legacy_md_names, namemap); + + /* We also pilfer data from the legacy EVP_PKEY_ASN1_METHODs */ + for (i = 0, end = EVP_PKEY_asn1_get_count(); i < end; i++) + get_legacy_pkey_meth_names(EVP_PKEY_asn1_get0(i), namemap); + } +#endif + + return namemap; +} + +OSSL_NAMEMAP *ossl_namemap_new(void) +{ + OSSL_NAMEMAP *namemap; + + if ((namemap = OPENSSL_zalloc(sizeof(*namemap))) != NULL + && (namemap->lock = CRYPTO_THREAD_lock_new()) != NULL + && (namemap->namenum = + lh_NAMENUM_ENTRY_new(namenum_hash, namenum_cmp)) != NULL) + return namemap; + + ossl_namemap_free(namemap); + return NULL; +} + +void ossl_namemap_free(OSSL_NAMEMAP *namemap) +{ + if (namemap == NULL || namemap->stored) + return; + + lh_NAMENUM_ENTRY_doall(namemap->namenum, namenum_free); + lh_NAMENUM_ENTRY_free(namemap->namenum); + + CRYPTO_THREAD_lock_free(namemap->lock); + OPENSSL_free(namemap); +} diff --git a/crypto/openssl/crypto/cpt_err.c b/crypto/openssl/crypto/cpt_err.c index 4147b1cb9e23..8574f31a8124 100644 --- a/crypto/openssl/crypto/cpt_err.c +++ b/crypto/openssl/crypto/cpt_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,68 +10,61 @@ #include #include +#include "crypto/cryptoerr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA CRYPTO_str_functs[] = { - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CMAC_CTX_NEW, 0), "CMAC_CTX_new"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_DUP_EX_DATA, 0), - "CRYPTO_dup_ex_data"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_FREE_EX_DATA, 0), - "CRYPTO_free_ex_data"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, 0), - "CRYPTO_get_ex_new_index"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_MEMDUP, 0), "CRYPTO_memdup"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_NEW_EX_DATA, 0), - "CRYPTO_new_ex_data"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_OCB128_COPY_CTX, 0), - "CRYPTO_ocb128_copy_ctx"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_OCB128_INIT, 0), - "CRYPTO_ocb128_init"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_SET_EX_DATA, 0), - "CRYPTO_set_ex_data"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_FIPS_MODE_SET, 0), "FIPS_mode_set"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_GET_AND_LOCK, 0), "get_and_lock"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_ATEXIT, 0), "OPENSSL_atexit"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_BUF2HEXSTR, 0), - "OPENSSL_buf2hexstr"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_FOPEN, 0), "openssl_fopen"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_HEXSTR2BUF, 0), - "OPENSSL_hexstr2buf"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_INIT_CRYPTO, 0), - "OPENSSL_init_crypto"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_LH_NEW, 0), "OPENSSL_LH_new"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_SK_DEEP_COPY, 0), - "OPENSSL_sk_deep_copy"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_SK_DUP, 0), "OPENSSL_sk_dup"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PKEY_HMAC_INIT, 0), "pkey_hmac_init"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PKEY_POLY1305_INIT, 0), - "pkey_poly1305_init"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PKEY_SIPHASH_INIT, 0), - "pkey_siphash_init"}, - {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_SK_RESERVE, 0), "sk_reserve"}, - {0, NULL} -}; - static const ERR_STRING_DATA CRYPTO_str_reasons[] = { - {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED), - "fips mode not supported"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_BAD_ALGORITHM_NAME), + "bad algorithm name"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_CONFLICTING_NAMES), + "conflicting names"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_HEX_STRING_TOO_SHORT), + "hex string too short"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ILLEGAL_HEX_DIGIT), "illegal hex digit"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_DATA_SPACE), + "insufficient data space"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_PARAM_SIZE), + "insufficient param size"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE), + "insufficient secure data space"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INVALID_NEGATIVE_VALUE), + "invalid negative value"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INVALID_NULL_ARGUMENT), + "invalid null argument"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INVALID_OSSL_PARAM_TYPE), + "invalid ossl param type"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_ALREADY_EXISTS), + "provider already exists"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_SECTION_ERROR), + "provider section error"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_RANDOM_SECTION_ERROR), + "random section error"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_SECURE_MALLOC_FAILURE), + "secure malloc failure"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_STRING_TOO_LONG), "string too long"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_BYTES), "too many bytes"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_RECORDS), + "too many records"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_SMALL_BUFFER), + "too small buffer"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION), + "unknown name in random section"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ZERO_LENGTH_NUMBER), + "zero length number"}, {0, NULL} }; #endif -int ERR_load_CRYPTO_strings(void) +int ossl_err_load_CRYPTO_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL) { - ERR_load_strings_const(CRYPTO_str_functs); + if (ERR_reason_error_string(CRYPTO_str_reasons[0].error) == NULL) ERR_load_strings_const(CRYPTO_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/cpuid.c b/crypto/openssl/crypto/cpuid.c new file mode 100644 index 000000000000..090f6fe03ecc --- /dev/null +++ b/crypto/openssl/crypto/cpuid.c @@ -0,0 +1,214 @@ +/* + * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "e_os.h" +#include "crypto/cryptlib.h" + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) + +extern unsigned int OPENSSL_ia32cap_P[4]; + +# if defined(OPENSSL_CPUID_OBJ) + +/* + * Purpose of these minimalistic and character-type-agnostic subroutines + * is to break dependency on MSVCRT (on Windows) and locale. This makes + * OPENSSL_cpuid_setup safe to use as "constructor". "Character-type- + * agnostic" means that they work with either wide or 8-bit characters, + * exploiting the fact that first 127 characters can be simply casted + * between the sets, while the rest would be simply rejected by ossl_is* + * subroutines. + */ +# ifdef _WIN32 +typedef WCHAR variant_char; + +static variant_char *ossl_getenv(const char *name) +{ + /* + * Since we pull only one environment variable, it's simpler to + * to just ignore |name| and use equivalent wide-char L-literal. + * As well as to ignore excessively long values... + */ + static WCHAR value[48]; + DWORD len = GetEnvironmentVariableW(L"OPENSSL_ia32cap", value, 48); + + return (len > 0 && len < 48) ? value : NULL; +} +# else +typedef char variant_char; +# define ossl_getenv getenv +# endif + +# include "crypto/ctype.h" + +static int todigit(variant_char c) +{ + if (ossl_isdigit(c)) + return c - '0'; + else if (ossl_isxdigit(c)) + return ossl_tolower(c) - 'a' + 10; + + /* return largest base value to make caller terminate the loop */ + return 16; +} + +static uint64_t ossl_strtouint64(const variant_char *str) +{ + uint64_t ret = 0; + unsigned int digit, base = 10; + + if (*str == '0') { + base = 8, str++; + if (ossl_tolower(*str) == 'x') + base = 16, str++; + } + + while((digit = todigit(*str++)) < base) + ret = ret * base + digit; + + return ret; +} + +static variant_char *ossl_strchr(const variant_char *str, char srch) +{ variant_char c; + + while((c = *str)) { + if (c == srch) + return (variant_char *)str; + str++; + } + + return NULL; +} + +# define OPENSSL_CPUID_SETUP +typedef uint64_t IA32CAP; + +void OPENSSL_cpuid_setup(void) +{ + static int trigger = 0; + IA32CAP OPENSSL_ia32_cpuid(unsigned int *); + IA32CAP vec; + const variant_char *env; + + if (trigger) + return; + + trigger = 1; + if ((env = ossl_getenv("OPENSSL_ia32cap")) != NULL) { + int off = (env[0] == '~') ? 1 : 0; + + vec = ossl_strtouint64(env + off); + + if (off) { + IA32CAP mask = vec; + vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~mask; + if (mask & (1<<24)) { + /* + * User disables FXSR bit, mask even other capabilities + * that operate exclusively on XMM, so we don't have to + * double-check all the time. We mask PCLMULQDQ, AMD XOP, + * AES-NI and AVX. Formally speaking we don't have to + * do it in x86_64 case, but we can safely assume that + * x86_64 users won't actually flip this flag. + */ + vec &= ~((IA32CAP)(1<<1|1<<11|1<<25|1<<28) << 32); + } + } else if (env[0] == ':') { + vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); + } + + if ((env = ossl_strchr(env, ':')) != NULL) { + IA32CAP vecx; + + env++; + off = (env[0] == '~') ? 1 : 0; + vecx = ossl_strtouint64(env + off); + if (off) { + OPENSSL_ia32cap_P[2] &= ~(unsigned int)vecx; + OPENSSL_ia32cap_P[3] &= ~(unsigned int)(vecx >> 32); + } else { + OPENSSL_ia32cap_P[2] = (unsigned int)vecx; + OPENSSL_ia32cap_P[3] = (unsigned int)(vecx >> 32); + } + } else { + OPENSSL_ia32cap_P[2] = 0; + OPENSSL_ia32cap_P[3] = 0; + } + } else { + vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); + } + + /* + * |(1<<10) sets a reserved bit to signal that variable + * was initialized already... This is to avoid interference + * with cpuid snippets in ELF .init segment. + */ + OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10); + OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32); +} +# else +unsigned int OPENSSL_ia32cap_P[4]; +# endif +#endif + +#ifndef OPENSSL_CPUID_OBJ +# ifndef OPENSSL_CPUID_SETUP +void OPENSSL_cpuid_setup(void) +{ +} +# endif + +/* + * The rest are functions that are defined in the same assembler files as + * the CPUID functionality. + */ + +/* + * The volatile is used to to ensure that the compiler generates code that reads + * all values from the array and doesn't try to optimize this away. The standard + * doesn't actually require this behavior if the original data pointed to is + * not volatile, but compilers do this in practice anyway. + * + * There are also assembler versions of this function. + */ +# undef CRYPTO_memcmp +int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len) +{ + size_t i; + const volatile unsigned char *a = in_a; + const volatile unsigned char *b = in_b; + unsigned char x = 0; + + for (i = 0; i < len; i++) + x |= a[i] ^ b[i]; + + return x; +} + +/* + * For systems that don't provide an instruction counter register or equivalent. + */ +uint32_t OPENSSL_rdtsc(void) +{ + return 0; +} + +size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt) +{ + return 0; +} + +size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max) +{ + return 0; +} +#endif diff --git a/crypto/openssl/crypto/crmf/build.info b/crypto/openssl/crypto/crmf/build.info new file mode 100644 index 000000000000..7cfa8ec2b076 --- /dev/null +++ b/crypto/openssl/crypto/crmf/build.info @@ -0,0 +1,2 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=crmf_asn.c crmf_err.c crmf_lib.c crmf_pbm.c diff --git a/crypto/openssl/crypto/crmf/crmf_asn.c b/crypto/openssl/crypto/crmf/crmf_asn.c new file mode 100644 index 000000000000..3354b89736e9 --- /dev/null +++ b/crypto/openssl/crypto/crmf/crmf_asn.c @@ -0,0 +1,235 @@ +/*- + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * CRMF implementation by Martin Peylo, Miikka Viljanen, and David von Oheimb. + */ + +#include + +#include "crmf_local.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include + +ASN1_SEQUENCE(OSSL_CRMF_PRIVATEKEYINFO) = { + ASN1_SIMPLE(OSSL_CRMF_PRIVATEKEYINFO, version, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CRMF_PRIVATEKEYINFO, privateKeyAlgorithm, X509_ALGOR), + ASN1_SIMPLE(OSSL_CRMF_PRIVATEKEYINFO, privateKey, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(OSSL_CRMF_PRIVATEKEYINFO, attributes, X509_ATTRIBUTE, 0) +} ASN1_SEQUENCE_END(OSSL_CRMF_PRIVATEKEYINFO) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PRIVATEKEYINFO) + + +ASN1_CHOICE(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) = { + ASN1_SIMPLE(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER, value.string, ASN1_UTF8STRING), + ASN1_SIMPLE(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER, value.generalName, GENERAL_NAME) +} ASN1_CHOICE_END(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) + + +ASN1_SEQUENCE(OSSL_CRMF_ENCKEYWITHID) = { + ASN1_SIMPLE(OSSL_CRMF_ENCKEYWITHID, privateKey, OSSL_CRMF_PRIVATEKEYINFO), + ASN1_OPT(OSSL_CRMF_ENCKEYWITHID, identifier, + OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) +} ASN1_SEQUENCE_END(OSSL_CRMF_ENCKEYWITHID) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID) + + +ASN1_SEQUENCE(OSSL_CRMF_CERTID) = { + ASN1_SIMPLE(OSSL_CRMF_CERTID, issuer, GENERAL_NAME), + ASN1_SIMPLE(OSSL_CRMF_CERTID, serialNumber, ASN1_INTEGER) +} ASN1_SEQUENCE_END(OSSL_CRMF_CERTID) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_CERTID) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID) + + +ASN1_SEQUENCE(OSSL_CRMF_ENCRYPTEDVALUE) = { + ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, intendedAlg, X509_ALGOR, 0), + ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, symmAlg, X509_ALGOR, 1), + ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, encSymmKey, ASN1_BIT_STRING, 2), + ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, keyAlg, X509_ALGOR, 3), + ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, valueHint, ASN1_OCTET_STRING, 4), + ASN1_SIMPLE(OSSL_CRMF_ENCRYPTEDVALUE, encValue, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(OSSL_CRMF_ENCRYPTEDVALUE) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ENCRYPTEDVALUE) + +ASN1_SEQUENCE(OSSL_CRMF_SINGLEPUBINFO) = { + ASN1_SIMPLE(OSSL_CRMF_SINGLEPUBINFO, pubMethod, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CRMF_SINGLEPUBINFO, pubLocation, GENERAL_NAME) +} ASN1_SEQUENCE_END(OSSL_CRMF_SINGLEPUBINFO) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_SINGLEPUBINFO) + + +ASN1_SEQUENCE(OSSL_CRMF_PKIPUBLICATIONINFO) = { + ASN1_SIMPLE(OSSL_CRMF_PKIPUBLICATIONINFO, action, ASN1_INTEGER), + ASN1_SEQUENCE_OF_OPT(OSSL_CRMF_PKIPUBLICATIONINFO, pubInfos, + OSSL_CRMF_SINGLEPUBINFO) +} ASN1_SEQUENCE_END(OSSL_CRMF_PKIPUBLICATIONINFO) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PKIPUBLICATIONINFO) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_PKIPUBLICATIONINFO) + + +ASN1_SEQUENCE(OSSL_CRMF_PKMACVALUE) = { + ASN1_SIMPLE(OSSL_CRMF_PKMACVALUE, algId, X509_ALGOR), + ASN1_SIMPLE(OSSL_CRMF_PKMACVALUE, value, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(OSSL_CRMF_PKMACVALUE) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PKMACVALUE) + + +ASN1_CHOICE(OSSL_CRMF_POPOPRIVKEY) = { + ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.thisMessage, ASN1_BIT_STRING, 0), + ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.subsequentMessage, ASN1_INTEGER, 1), + ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.dhMAC, ASN1_BIT_STRING, 2), + ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.agreeMAC, OSSL_CRMF_PKMACVALUE, 3), + ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.encryptedKey, ASN1_NULL, 4), +} ASN1_CHOICE_END(OSSL_CRMF_POPOPRIVKEY) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOPRIVKEY) + + +ASN1_SEQUENCE(OSSL_CRMF_PBMPARAMETER) = { + ASN1_SIMPLE(OSSL_CRMF_PBMPARAMETER, salt, ASN1_OCTET_STRING), + ASN1_SIMPLE(OSSL_CRMF_PBMPARAMETER, owf, X509_ALGOR), + ASN1_SIMPLE(OSSL_CRMF_PBMPARAMETER, iterationCount, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CRMF_PBMPARAMETER, mac, X509_ALGOR) +} ASN1_SEQUENCE_END(OSSL_CRMF_PBMPARAMETER) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PBMPARAMETER) + + +ASN1_CHOICE(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) = { + ASN1_EXP(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO, value.sender, + GENERAL_NAME, 0), + ASN1_SIMPLE(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO, value.publicKeyMAC, + OSSL_CRMF_PKMACVALUE) +} ASN1_CHOICE_END(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) + + +ASN1_SEQUENCE(OSSL_CRMF_POPOSIGNINGKEYINPUT) = { + ASN1_SIMPLE(OSSL_CRMF_POPOSIGNINGKEYINPUT, authInfo, + OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO), + ASN1_SIMPLE(OSSL_CRMF_POPOSIGNINGKEYINPUT, publicKey, X509_PUBKEY) +} ASN1_SEQUENCE_END(OSSL_CRMF_POPOSIGNINGKEYINPUT) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT) + + +ASN1_SEQUENCE(OSSL_CRMF_POPOSIGNINGKEY) = { + ASN1_IMP_OPT(OSSL_CRMF_POPOSIGNINGKEY, poposkInput, + OSSL_CRMF_POPOSIGNINGKEYINPUT, 0), + ASN1_SIMPLE(OSSL_CRMF_POPOSIGNINGKEY, algorithmIdentifier, X509_ALGOR), + ASN1_SIMPLE(OSSL_CRMF_POPOSIGNINGKEY, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(OSSL_CRMF_POPOSIGNINGKEY) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEY) + + +ASN1_CHOICE(OSSL_CRMF_POPO) = { + ASN1_IMP(OSSL_CRMF_POPO, value.raVerified, ASN1_NULL, 0), + ASN1_IMP(OSSL_CRMF_POPO, value.signature, OSSL_CRMF_POPOSIGNINGKEY, 1), + ASN1_EXP(OSSL_CRMF_POPO, value.keyEncipherment, OSSL_CRMF_POPOPRIVKEY, 2), + ASN1_EXP(OSSL_CRMF_POPO, value.keyAgreement, OSSL_CRMF_POPOPRIVKEY, 3) +} ASN1_CHOICE_END(OSSL_CRMF_POPO) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPO) + + +ASN1_ADB_TEMPLATE(attributetypeandvalue_default) = + ASN1_OPT(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, value.other, ASN1_ANY); +ASN1_ADB(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) = { + ADB_ENTRY(NID_id_regCtrl_regToken, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.regToken, ASN1_UTF8STRING)), + ADB_ENTRY(NID_id_regCtrl_authenticator, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.authenticator, ASN1_UTF8STRING)), + ADB_ENTRY(NID_id_regCtrl_pkiPublicationInfo, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.pkiPublicationInfo, + OSSL_CRMF_PKIPUBLICATIONINFO)), + ADB_ENTRY(NID_id_regCtrl_oldCertID, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.oldCertID, OSSL_CRMF_CERTID)), + ADB_ENTRY(NID_id_regCtrl_protocolEncrKey, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.protocolEncrKey, X509_PUBKEY)), + ADB_ENTRY(NID_id_regInfo_utf8Pairs, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.utf8Pairs, ASN1_UTF8STRING)), + ADB_ENTRY(NID_id_regInfo_certReq, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.certReq, OSSL_CRMF_CERTREQUEST)), +} ASN1_ADB_END(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, 0, type, 0, + &attributetypeandvalue_default_tt, NULL); + + +ASN1_SEQUENCE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) = { + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, type, ASN1_OBJECT), + ASN1_ADB_OBJECT(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +} ASN1_SEQUENCE_END(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) + +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) + + +ASN1_SEQUENCE(OSSL_CRMF_OPTIONALVALIDITY) = { + ASN1_EXP_OPT(OSSL_CRMF_OPTIONALVALIDITY, notBefore, ASN1_TIME, 0), + ASN1_EXP_OPT(OSSL_CRMF_OPTIONALVALIDITY, notAfter, ASN1_TIME, 1) +} ASN1_SEQUENCE_END(OSSL_CRMF_OPTIONALVALIDITY) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_OPTIONALVALIDITY) + + +ASN1_SEQUENCE(OSSL_CRMF_CERTTEMPLATE) = { + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, version, ASN1_INTEGER, 0), + /* + * serialNumber MUST be omitted. This field is assigned by the CA + * during certificate creation. + */ + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, serialNumber, ASN1_INTEGER, 1), + /* + * signingAlg MUST be omitted. This field is assigned by the CA + * during certificate creation. + */ + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, signingAlg, X509_ALGOR, 2), + ASN1_EXP_OPT(OSSL_CRMF_CERTTEMPLATE, issuer, X509_NAME, 3), + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, validity, + OSSL_CRMF_OPTIONALVALIDITY, 4), + ASN1_EXP_OPT(OSSL_CRMF_CERTTEMPLATE, subject, X509_NAME, 5), + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, publicKey, X509_PUBKEY, 6), + /* issuerUID is deprecated in version 2 */ + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, issuerUID, ASN1_BIT_STRING, 7), + /* subjectUID is deprecated in version 2 */ + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, subjectUID, ASN1_BIT_STRING, 8), + ASN1_IMP_SEQUENCE_OF_OPT(OSSL_CRMF_CERTTEMPLATE, extensions, + X509_EXTENSION, 9), +} ASN1_SEQUENCE_END(OSSL_CRMF_CERTTEMPLATE) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_CERTTEMPLATE) + + +ASN1_SEQUENCE(OSSL_CRMF_CERTREQUEST) = { + ASN1_SIMPLE(OSSL_CRMF_CERTREQUEST, certReqId, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CRMF_CERTREQUEST, certTemplate, OSSL_CRMF_CERTTEMPLATE), + ASN1_SEQUENCE_OF_OPT(OSSL_CRMF_CERTREQUEST, controls, + OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +} ASN1_SEQUENCE_END(OSSL_CRMF_CERTREQUEST) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_CERTREQUEST) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTREQUEST) + + +ASN1_SEQUENCE(OSSL_CRMF_MSG) = { + ASN1_SIMPLE(OSSL_CRMF_MSG, certReq, OSSL_CRMF_CERTREQUEST), + ASN1_OPT(OSSL_CRMF_MSG, popo, OSSL_CRMF_POPO), + ASN1_SEQUENCE_OF_OPT(OSSL_CRMF_MSG, regInfo, + OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +} ASN1_SEQUENCE_END(OSSL_CRMF_MSG) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_MSG) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_MSG) + +ASN1_ITEM_TEMPLATE(OSSL_CRMF_MSGS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, + OSSL_CRMF_MSGS, OSSL_CRMF_MSG) +ASN1_ITEM_TEMPLATE_END(OSSL_CRMF_MSGS) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_MSGS) diff --git a/crypto/openssl/crypto/crmf/crmf_err.c b/crypto/openssl/crypto/crmf/crmf_err.c new file mode 100644 index 000000000000..44b2f2757d2c --- /dev/null +++ b/crypto/openssl/crypto/crmf/crmf_err.c @@ -0,0 +1,74 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/crmferr.h" + +#ifndef OPENSSL_NO_CRMF + +# ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA CRMF_str_reasons[] = { + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_BAD_PBM_ITERATIONCOUNT), + "bad pbm iterationcount"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_CRMFERROR), "crmferror"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR), "error"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECODING_CERTIFICATE), + "error decoding certificate"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_CERTIFICATE), + "error decrypting certificate"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY), + "error decrypting symmetric key"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_FAILURE_OBTAINING_RANDOM), + "failure obtaining random"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ITERATIONCOUNT_BELOW_100), + "iterationcount below 100"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_MALFORMED_IV), "malformed iv"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_NULL_ARGUMENT), "null argument"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPOSKINPUT_NOT_SUPPORTED), + "poposkinput not supported"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY), + "popo inconsistent public key"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING), "popo missing"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_PUBLIC_KEY), + "popo missing public key"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_SUBJECT), + "popo missing subject"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED), + "popo raverified not accepted"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_MAC_ALGOR_FAILURE), + "setting mac algor failure"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_OWF_ALGOR_FAILURE), + "setting owf algor failure"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALGORITHM), + "unsupported algorithm"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_CIPHER), + "unsupported cipher"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO), + "unsupported method for creating popo"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_METHOD), + "unsupported popo method"}, + {0, NULL} +}; + +# endif + +int ossl_err_load_CRMF_strings(void) +{ +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(CRMF_str_reasons[0].error) == NULL) + ERR_load_strings_const(CRMF_str_reasons); +# endif + return 1; +} +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/crmf/crmf_lib.c b/crypto/openssl/crypto/crmf/crmf_lib.c new file mode 100644 index 000000000000..3607fb0bf417 --- /dev/null +++ b/crypto/openssl/crypto/crmf/crmf_lib.c @@ -0,0 +1,715 @@ +/*- + * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2018 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * CRMF implementation by Martin Peylo, Miikka Viljanen, and David von Oheimb. + */ + +/* + * This file contains the functions that handle the individual items inside + * the CRMF structures + */ + +/* + * NAMING + * + * The 0 functions use the supplied structure pointer directly in the parent and + * it will be freed up when the parent is freed. + * + * The 1 functions use a copy of the supplied structure pointer (or in some + * cases increases its link count) in the parent and so both should be freed up. + */ + +#include + +#include "crmf_local.h" +#include "internal/constant_time.h" +#include "internal/sizes.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include + +/*- + * atyp = Attribute Type + * valt = Value Type + * ctrlinf = "regCtrl" or "regInfo" + */ +#define IMPLEMENT_CRMF_CTRL_FUNC(atyp, valt, ctrlinf) \ +valt *OSSL_CRMF_MSG_get0_##ctrlinf##_##atyp(const OSSL_CRMF_MSG *msg) \ +{ \ + int i; \ + STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *controls; \ + OSSL_CRMF_ATTRIBUTETYPEANDVALUE *atav = NULL; \ + \ + if (msg == NULL || msg->certReq == NULL) \ + return NULL; \ + controls = msg->certReq->controls; \ + for (i = 0; i < sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_num(controls); i++) { \ + atav = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_value(controls, i); \ + if (OBJ_obj2nid(atav->type) == NID_id_##ctrlinf##_##atyp) \ + return atav->value.atyp; \ + } \ + return NULL; \ +} \ + \ +int OSSL_CRMF_MSG_set1_##ctrlinf##_##atyp(OSSL_CRMF_MSG *msg, const valt *in) \ +{ \ + OSSL_CRMF_ATTRIBUTETYPEANDVALUE *atav = NULL; \ + \ + if (msg == NULL || in == NULL) \ + goto err; \ + if ((atav = OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new()) == NULL) \ + goto err; \ + if ((atav->type = OBJ_nid2obj(NID_id_##ctrlinf##_##atyp)) == NULL) \ + goto err; \ + if ((atav->value.atyp = valt##_dup(in)) == NULL) \ + goto err; \ + if (!OSSL_CRMF_MSG_push0_##ctrlinf(msg, atav)) \ + goto err; \ + return 1; \ + err: \ + OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(atav); \ + return 0; \ +} + + +/*- + * Pushes the given control attribute into the controls stack of a CertRequest + * (section 6) + * returns 1 on success, 0 on error + */ +static int OSSL_CRMF_MSG_push0_regCtrl(OSSL_CRMF_MSG *crm, + OSSL_CRMF_ATTRIBUTETYPEANDVALUE *ctrl) +{ + int new = 0; + + if (crm == NULL || crm->certReq == NULL || ctrl == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return 0; + } + + if (crm->certReq->controls == NULL) { + crm->certReq->controls = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new_null(); + if (crm->certReq->controls == NULL) + goto err; + new = 1; + } + if (!sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_push(crm->certReq->controls, ctrl)) + goto err; + + return 1; + err: + if (new != 0) { + sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(crm->certReq->controls); + crm->certReq->controls = NULL; + } + return 0; +} + +/* id-regCtrl-regToken Control (section 6.1) */ +IMPLEMENT_CRMF_CTRL_FUNC(regToken, ASN1_STRING, regCtrl) + +/* id-regCtrl-authenticator Control (section 6.2) */ +#define ASN1_UTF8STRING_dup ASN1_STRING_dup +IMPLEMENT_CRMF_CTRL_FUNC(authenticator, ASN1_UTF8STRING, regCtrl) + +int OSSL_CRMF_MSG_set0_SinglePubInfo(OSSL_CRMF_SINGLEPUBINFO *spi, + int method, GENERAL_NAME *nm) +{ + if (spi == NULL + || method < OSSL_CRMF_PUB_METHOD_DONTCARE + || method > OSSL_CRMF_PUB_METHOD_LDAP) { + ERR_raise(ERR_LIB_CRMF, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + if (!ASN1_INTEGER_set(spi->pubMethod, method)) + return 0; + GENERAL_NAME_free(spi->pubLocation); + spi->pubLocation = nm; + return 1; +} + +int +OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo(OSSL_CRMF_PKIPUBLICATIONINFO *pi, + OSSL_CRMF_SINGLEPUBINFO *spi) +{ + if (pi == NULL || spi == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return 0; + } + if (pi->pubInfos == NULL) + pi->pubInfos = sk_OSSL_CRMF_SINGLEPUBINFO_new_null(); + if (pi->pubInfos == NULL) + return 0; + + return sk_OSSL_CRMF_SINGLEPUBINFO_push(pi->pubInfos, spi); +} + +int OSSL_CRMF_MSG_set_PKIPublicationInfo_action(OSSL_CRMF_PKIPUBLICATIONINFO *pi, + int action) +{ + if (pi == NULL + || action < OSSL_CRMF_PUB_ACTION_DONTPUBLISH + || action > OSSL_CRMF_PUB_ACTION_PLEASEPUBLISH) { + ERR_raise(ERR_LIB_CRMF, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + return ASN1_INTEGER_set(pi->action, action); +} + +/* id-regCtrl-pkiPublicationInfo Control (section 6.3) */ +IMPLEMENT_CRMF_CTRL_FUNC(pkiPublicationInfo, OSSL_CRMF_PKIPUBLICATIONINFO, + regCtrl) + +/* id-regCtrl-oldCertID Control (section 6.5) from the given */ +IMPLEMENT_CRMF_CTRL_FUNC(oldCertID, OSSL_CRMF_CERTID, regCtrl) + +OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer, + const ASN1_INTEGER *serial) +{ + OSSL_CRMF_CERTID *cid = NULL; + + if (issuer == NULL || serial == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return NULL; + } + + if ((cid = OSSL_CRMF_CERTID_new()) == NULL) + goto err; + + if (!X509_NAME_set(&cid->issuer->d.directoryName, issuer)) + goto err; + cid->issuer->type = GEN_DIRNAME; + + ASN1_INTEGER_free(cid->serialNumber); + if ((cid->serialNumber = ASN1_INTEGER_dup(serial)) == NULL) + goto err; + + return cid; + + err: + OSSL_CRMF_CERTID_free(cid); + return NULL; +} + +/* + * id-regCtrl-protocolEncrKey Control (section 6.6) + */ +IMPLEMENT_CRMF_CTRL_FUNC(protocolEncrKey, X509_PUBKEY, regCtrl) + +/*- + * Pushes the attribute given in regInfo in to the CertReqMsg->regInfo stack. + * (section 7) + * returns 1 on success, 0 on error + */ +static int OSSL_CRMF_MSG_push0_regInfo(OSSL_CRMF_MSG *crm, + OSSL_CRMF_ATTRIBUTETYPEANDVALUE *ri) +{ + STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *info = NULL; + + if (crm == NULL || ri == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return 0; + } + + if (crm->regInfo == NULL) + crm->regInfo = info = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new_null(); + if (crm->regInfo == NULL) + goto err; + if (!sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_push(crm->regInfo, ri)) + goto err; + return 1; + + err: + if (info != NULL) + crm->regInfo = NULL; + sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(info); + return 0; +} + +/* id-regInfo-utf8Pairs to regInfo (section 7.1) */ +IMPLEMENT_CRMF_CTRL_FUNC(utf8Pairs, ASN1_UTF8STRING, regInfo) + +/* id-regInfo-certReq to regInfo (section 7.2) */ +IMPLEMENT_CRMF_CTRL_FUNC(certReq, OSSL_CRMF_CERTREQUEST, regInfo) + + +/* retrieves the certificate template of crm */ +OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm) +{ + if (crm == NULL || crm->certReq == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return NULL; + } + return crm->certReq->certTemplate; +} + + +int OSSL_CRMF_MSG_set0_validity(OSSL_CRMF_MSG *crm, + ASN1_TIME *notBefore, ASN1_TIME *notAfter) +{ + OSSL_CRMF_OPTIONALVALIDITY *vld; + OSSL_CRMF_CERTTEMPLATE *tmpl = OSSL_CRMF_MSG_get0_tmpl(crm); + + if (tmpl == NULL) { /* also crm == NULL implies this */ + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return 0; + } + + if ((vld = OSSL_CRMF_OPTIONALVALIDITY_new()) == NULL) + return 0; + vld->notBefore = notBefore; + vld->notAfter = notAfter; + tmpl->validity = vld; + return 1; +} + + +int OSSL_CRMF_MSG_set_certReqId(OSSL_CRMF_MSG *crm, int rid) +{ + if (crm == NULL || crm->certReq == NULL || crm->certReq->certReqId == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return 0; + } + + return ASN1_INTEGER_set(crm->certReq->certReqId, rid); +} + +/* get ASN.1 encoded integer, return -1 on error */ +static int crmf_asn1_get_int(const ASN1_INTEGER *a) +{ + int64_t res; + + if (!ASN1_INTEGER_get_int64(&res, a)) { + ERR_raise(ERR_LIB_CRMF, ASN1_R_INVALID_NUMBER); + return -1; + } + if (res < INT_MIN) { + ERR_raise(ERR_LIB_CRMF, ASN1_R_TOO_SMALL); + return -1; + } + if (res > INT_MAX) { + ERR_raise(ERR_LIB_CRMF, ASN1_R_TOO_LARGE); + return -1; + } + return (int)res; +} + +int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm) +{ + if (crm == NULL || /* not really needed: */ crm->certReq == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return -1; + } + return crmf_asn1_get_int(crm->certReq->certReqId); +} + + +int OSSL_CRMF_MSG_set0_extensions(OSSL_CRMF_MSG *crm, + X509_EXTENSIONS *exts) +{ + OSSL_CRMF_CERTTEMPLATE *tmpl = OSSL_CRMF_MSG_get0_tmpl(crm); + + if (tmpl == NULL) { /* also crm == NULL implies this */ + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return 0; + } + + if (sk_X509_EXTENSION_num(exts) == 0) { + sk_X509_EXTENSION_free(exts); + exts = NULL; /* do not include empty extensions list */ + } + + sk_X509_EXTENSION_pop_free(tmpl->extensions, X509_EXTENSION_free); + tmpl->extensions = exts; + return 1; +} + + +int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, + X509_EXTENSION *ext) +{ + int new = 0; + OSSL_CRMF_CERTTEMPLATE *tmpl = OSSL_CRMF_MSG_get0_tmpl(crm); + + if (tmpl == NULL || ext == NULL) { /* also crm == NULL implies this */ + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return 0; + } + + if (tmpl->extensions == NULL) { + if ((tmpl->extensions = sk_X509_EXTENSION_new_null()) == NULL) + goto err; + new = 1; + } + + if (!sk_X509_EXTENSION_push(tmpl->extensions, ext)) + goto err; + return 1; + err: + if (new != 0) { + sk_X509_EXTENSION_free(tmpl->extensions); + tmpl->extensions = NULL; + } + return 0; +} + +static int create_popo_signature(OSSL_CRMF_POPOSIGNINGKEY *ps, + const OSSL_CRMF_CERTREQUEST *cr, + EVP_PKEY *pkey, const EVP_MD *digest, + OSSL_LIB_CTX *libctx, const char *propq) +{ + char name[80] = ""; + + if (ps == NULL || cr == NULL || pkey == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return 0; + } + if (ps->poposkInput != NULL) { + /* We do not support cases 1+2 defined in RFC 4211, section 4.1 */ + ERR_raise(ERR_LIB_CRMF, CRMF_R_POPOSKINPUT_NOT_SUPPORTED); + return 0; + } + + if (EVP_PKEY_get_default_digest_name(pkey, name, sizeof(name)) > 0 + && strcmp(name, "UNDEF") == 0) /* at least for Ed25519, Ed448 */ + digest = NULL; + + return ASN1_item_sign_ex(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST), + ps->algorithmIdentifier, NULL, ps->signature, cr, + NULL, pkey, digest, libctx, propq); +} + + +int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm, + EVP_PKEY *pkey, const EVP_MD *digest, + OSSL_LIB_CTX *libctx, const char *propq) +{ + OSSL_CRMF_POPO *pp = NULL; + ASN1_INTEGER *tag = NULL; + + if (crm == NULL || (meth == OSSL_CRMF_POPO_SIGNATURE && pkey == NULL)) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return 0; + } + + if (meth == OSSL_CRMF_POPO_NONE) + goto end; + if ((pp = OSSL_CRMF_POPO_new()) == NULL) + goto err; + pp->type = meth; + + switch (meth) { + case OSSL_CRMF_POPO_RAVERIFIED: + if ((pp->value.raVerified = ASN1_NULL_new()) == NULL) + goto err; + break; + + case OSSL_CRMF_POPO_SIGNATURE: + { + OSSL_CRMF_POPOSIGNINGKEY *ps = OSSL_CRMF_POPOSIGNINGKEY_new(); + + if (ps == NULL) + goto err; + if (!create_popo_signature(ps, crm->certReq, pkey, digest, + libctx, propq)) { + OSSL_CRMF_POPOSIGNINGKEY_free(ps); + goto err; + } + pp->value.signature = ps; + } + break; + + case OSSL_CRMF_POPO_KEYENC: + if ((pp->value.keyEncipherment = OSSL_CRMF_POPOPRIVKEY_new()) == NULL) + goto err; + tag = ASN1_INTEGER_new(); + pp->value.keyEncipherment->type = + OSSL_CRMF_POPOPRIVKEY_SUBSEQUENTMESSAGE; + pp->value.keyEncipherment->value.subsequentMessage = tag; + if (tag == NULL + || !ASN1_INTEGER_set(tag, OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT)) + goto err; + break; + + default: + ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO); + goto err; + } + + end: + OSSL_CRMF_POPO_free(crm->popo); + crm->popo = pp; + + return 1; + err: + OSSL_CRMF_POPO_free(pp); + return 0; +} + +/* verifies the Proof-of-Possession of the request with the given rid in reqs */ +int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, + int rid, int acceptRAVerified, + OSSL_LIB_CTX *libctx, const char *propq) +{ + OSSL_CRMF_MSG *req = NULL; + X509_PUBKEY *pubkey = NULL; + OSSL_CRMF_POPOSIGNINGKEY *sig = NULL; + const ASN1_ITEM *it; + void *asn; + + if (reqs == NULL || (req = sk_OSSL_CRMF_MSG_value(reqs, rid)) == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return 0; + } + + if (req->popo == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_MISSING); + return 0; + } + + switch (req->popo->type) { + case OSSL_CRMF_POPO_RAVERIFIED: + if (!acceptRAVerified) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED); + return 0; + } + break; + case OSSL_CRMF_POPO_SIGNATURE: + pubkey = req->certReq->certTemplate->publicKey; + if (pubkey == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_MISSING_PUBLIC_KEY); + return 0; + } + sig = req->popo->value.signature; + if (sig->poposkInput != NULL) { + /* + * According to RFC 4211: publicKey contains a copy of + * the public key from the certificate template. This MUST be + * exactly the same value as contained in the certificate template. + */ + if (sig->poposkInput->publicKey == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_MISSING_PUBLIC_KEY); + return 0; + } + if (X509_PUBKEY_eq(pubkey, sig->poposkInput->publicKey) != 1) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY); + return 0; + } + it = ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT); + asn = sig->poposkInput; + } else { + if (req->certReq->certTemplate->subject == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_MISSING_SUBJECT); + return 0; + } + it = ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST); + asn = req->certReq; + } + if (ASN1_item_verify_ex(it, sig->algorithmIdentifier, sig->signature, + asn, NULL, X509_PUBKEY_get0(pubkey), libctx, + propq) < 1) + return 0; + break; + case OSSL_CRMF_POPO_KEYENC: + case OSSL_CRMF_POPO_KEYAGREE: + default: + ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_POPO_METHOD); + return 0; + } + return 1; +} + +/* retrieves the serialNumber of the given cert template or NULL on error */ +const ASN1_INTEGER +*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl) +{ + return tmpl != NULL ? tmpl->serialNumber : NULL; +} + +const X509_NAME + *OSSL_CRMF_CERTTEMPLATE_get0_subject(const OSSL_CRMF_CERTTEMPLATE *tmpl) +{ + return tmpl != NULL ? tmpl->subject : NULL; +} + +/* retrieves the issuer name of the given cert template or NULL on error */ +const X509_NAME + *OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl) +{ + return tmpl != NULL ? tmpl->issuer : NULL; +} + +X509_EXTENSIONS + *OSSL_CRMF_CERTTEMPLATE_get0_extensions(const OSSL_CRMF_CERTTEMPLATE *tmpl) +{ + return tmpl != NULL ? tmpl->extensions : NULL; +} + +/* retrieves the issuer name of the given CertId or NULL on error */ +const X509_NAME *OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid) +{ + return cid != NULL && cid->issuer->type == GEN_DIRNAME ? + cid->issuer->d.directoryName : NULL; +} + +/* retrieves the serialNumber of the given CertId or NULL on error */ +const ASN1_INTEGER *OSSL_CRMF_CERTID_get0_serialNumber(const OSSL_CRMF_CERTID *cid) +{ + return cid != NULL ? cid->serialNumber : NULL; +} + +/*- + * fill in certificate template. + * Any value argument that is NULL will leave the respective field unchanged. + */ +int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl, + EVP_PKEY *pubkey, + const X509_NAME *subject, + const X509_NAME *issuer, + const ASN1_INTEGER *serial) +{ + if (tmpl == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return 0; + } + if (subject != NULL && !X509_NAME_set((X509_NAME **)&tmpl->subject, subject)) + return 0; + if (issuer != NULL && !X509_NAME_set((X509_NAME **)&tmpl->issuer, issuer)) + return 0; + if (serial != NULL) { + ASN1_INTEGER_free(tmpl->serialNumber); + if ((tmpl->serialNumber = ASN1_INTEGER_dup(serial)) == NULL) + return 0; + } + if (pubkey != NULL && !X509_PUBKEY_set(&tmpl->publicKey, pubkey)) + return 0; + return 1; +} + + +/*- + * Decrypts the certificate in the given encryptedValue using private key pkey. + * This is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2. + * + * returns a pointer to the decrypted certificate + * returns NULL on error or if no certificate available + */ +X509 +*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert, + OSSL_LIB_CTX *libctx, const char *propq, + EVP_PKEY *pkey) +{ + X509 *cert = NULL; /* decrypted certificate */ + EVP_CIPHER_CTX *evp_ctx = NULL; /* context for symmetric encryption */ + unsigned char *ek = NULL; /* decrypted symmetric encryption key */ + size_t eksize = 0; /* size of decrypted symmetric encryption key */ + EVP_CIPHER *cipher = NULL; /* used cipher */ + int cikeysize = 0; /* key size from cipher */ + unsigned char *iv = NULL; /* initial vector for symmetric encryption */ + unsigned char *outbuf = NULL; /* decryption output buffer */ + const unsigned char *p = NULL; /* needed for decoding ASN1 */ + int n, outlen = 0; + EVP_PKEY_CTX *pkctx = NULL; /* private key context */ + char name[OSSL_MAX_NAME_SIZE]; + + if (ecert == NULL || ecert->symmAlg == NULL || ecert->encSymmKey == NULL + || ecert->encValue == NULL || pkey == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + return NULL; + } + + /* select symmetric cipher based on algorithm given in message */ + OBJ_obj2txt(name, sizeof(name), ecert->symmAlg->algorithm, 0); + + (void)ERR_set_mark(); + cipher = EVP_CIPHER_fetch(NULL, name, NULL); + + if (cipher == NULL) + cipher = (EVP_CIPHER *)EVP_get_cipherbyname(name); + + if (cipher == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_CIPHER); + goto end; + } + (void)ERR_pop_to_mark(); + + cikeysize = EVP_CIPHER_get_key_length(cipher); + /* first the symmetric key needs to be decrypted */ + pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); + if (pkctx != NULL && EVP_PKEY_decrypt_init(pkctx) > 0) { + ASN1_BIT_STRING *encKey = ecert->encSymmKey; + size_t failure; + int retval; + + if (EVP_PKEY_decrypt(pkctx, NULL, &eksize, + encKey->data, encKey->length) <= 0 + || (ek = OPENSSL_malloc(eksize)) == NULL) + goto end; + retval = EVP_PKEY_decrypt(pkctx, ek, &eksize, + encKey->data, encKey->length); + ERR_clear_error(); /* error state may have sensitive information */ + failure = ~constant_time_is_zero_s(constant_time_msb(retval) + | constant_time_is_zero(retval)); + failure |= ~constant_time_eq_s(eksize, (size_t)cikeysize); + if (failure) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY); + goto end; + } + } else { + goto end; + } + if ((iv = OPENSSL_malloc(EVP_CIPHER_get_iv_length(cipher))) == NULL) + goto end; + if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv, + EVP_CIPHER_get_iv_length(cipher)) + != EVP_CIPHER_get_iv_length(cipher)) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_MALFORMED_IV); + goto end; + } + + /* + * d2i_X509 changes the given pointer, so use p for decoding the message and + * keep the original pointer in outbuf so the memory can be freed later + */ + if ((p = outbuf = OPENSSL_malloc(ecert->encValue->length + + EVP_CIPHER_get_block_size(cipher))) == NULL + || (evp_ctx = EVP_CIPHER_CTX_new()) == NULL) + goto end; + EVP_CIPHER_CTX_set_padding(evp_ctx, 0); + + if (!EVP_DecryptInit(evp_ctx, cipher, ek, iv) + || !EVP_DecryptUpdate(evp_ctx, outbuf, &outlen, + ecert->encValue->data, + ecert->encValue->length) + || !EVP_DecryptFinal(evp_ctx, outbuf + outlen, &n)) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_CERTIFICATE); + goto end; + } + outlen += n; + + /* convert decrypted certificate from DER to internal ASN.1 structure */ + if ((cert = X509_new_ex(libctx, propq)) == NULL) + goto end; + if (d2i_X509(&cert, &p, outlen) == NULL) + ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECODING_CERTIFICATE); + end: + EVP_PKEY_CTX_free(pkctx); + OPENSSL_free(outbuf); + EVP_CIPHER_CTX_free(evp_ctx); + EVP_CIPHER_free(cipher); + OPENSSL_clear_free(ek, eksize); + OPENSSL_free(iv); + return cert; +} diff --git a/crypto/openssl/crypto/crmf/crmf_local.h b/crypto/openssl/crypto/crmf/crmf_local.h new file mode 100644 index 000000000000..3b8c3701b54d --- /dev/null +++ b/crypto/openssl/crypto/crmf/crmf_local.h @@ -0,0 +1,385 @@ +/*- + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * CRMF implementation by Martin Peylo, Miikka Viljanen, and David von Oheimb. + */ + +#ifndef OSSL_CRYPTO_CRMF_LOCAL_H +# define OSSL_CRYPTO_CRMF_LOCAL_H + +# include +# include + +/* explicit #includes not strictly needed since implied by the above: */ +# include +# include +# include +# include + +/*- + * EncryptedValue ::= SEQUENCE { + * intendedAlg [0] AlgorithmIdentifier OPTIONAL, + * -- the intended algorithm for which the value will be used + * symmAlg [1] AlgorithmIdentifier OPTIONAL, + * -- the symmetric algorithm used to encrypt the value + * encSymmKey [2] BIT STRING OPTIONAL, + * -- the (encrypted) symmetric key used to encrypt the value + * keyAlg [3] AlgorithmIdentifier OPTIONAL, + * -- algorithm used to encrypt the symmetric key + * valueHint [4] OCTET STRING OPTIONAL, + * -- a brief description or identifier of the encValue content + * -- (may be meaningful only to the sending entity, and + * -- used only if EncryptedValue might be re-examined + * -- by the sending entity in the future) + * encValue BIT STRING + * -- the encrypted value itself + * } + */ +struct ossl_crmf_encryptedvalue_st { + X509_ALGOR *intendedAlg; /* 0 */ + X509_ALGOR *symmAlg; /* 1 */ + ASN1_BIT_STRING *encSymmKey; /* 2 */ + X509_ALGOR *keyAlg; /* 3 */ + ASN1_OCTET_STRING *valueHint; /* 4 */ + ASN1_BIT_STRING *encValue; +} /* OSSL_CRMF_ENCRYPTEDVALUE */; + +/*- + * Attributes ::= SET OF Attribute + * => X509_ATTRIBUTE + * + * PrivateKeyInfo ::= SEQUENCE { + * version INTEGER, + * privateKeyAlgorithm AlgorithmIdentifier, + * privateKey OCTET STRING, + * attributes [0] IMPLICIT Attributes OPTIONAL + * } + */ +typedef struct ossl_crmf_privatekeyinfo_st { + ASN1_INTEGER *version; + X509_ALGOR *privateKeyAlgorithm; + ASN1_OCTET_STRING *privateKey; + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ +} OSSL_CRMF_PRIVATEKEYINFO; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PRIVATEKEYINFO) + +/*- + * section 4.2.1 Private Key Info Content Type + * id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21} + * + * EncKeyWithID ::= SEQUENCE { + * privateKey PrivateKeyInfo, + * identifier CHOICE { + * string UTF8String, + * generalName GeneralName + * } OPTIONAL + * } + */ +typedef struct ossl_crmf_enckeywithid_identifier_st { + int type; + union { + ASN1_UTF8STRING *string; + GENERAL_NAME *generalName; + } value; +} OSSL_CRMF_ENCKEYWITHID_IDENTIFIER; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) + +typedef struct ossl_crmf_enckeywithid_st { + OSSL_CRMF_PRIVATEKEYINFO *privateKey; + /* [0] */ + OSSL_CRMF_ENCKEYWITHID_IDENTIFIER *identifier; +} OSSL_CRMF_ENCKEYWITHID; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID) + +/*- + * CertId ::= SEQUENCE { + * issuer GeneralName, + * serialNumber INTEGER + * } + */ +struct ossl_crmf_certid_st { + GENERAL_NAME *issuer; + ASN1_INTEGER *serialNumber; +} /* OSSL_CRMF_CERTID */; + +/*- + * SinglePubInfo ::= SEQUENCE { + * pubMethod INTEGER { + * dontCare (0), + * x500 (1), + * web (2), + * ldap (3) }, + * pubLocation GeneralName OPTIONAL + * } + */ +struct ossl_crmf_singlepubinfo_st { + ASN1_INTEGER *pubMethod; + GENERAL_NAME *pubLocation; +} /* OSSL_CRMF_SINGLEPUBINFO */; +DEFINE_STACK_OF(OSSL_CRMF_SINGLEPUBINFO) +typedef STACK_OF(OSSL_CRMF_SINGLEPUBINFO) OSSL_CRMF_PUBINFOS; + + +/*- + * PKIPublicationInfo ::= SEQUENCE { + * action INTEGER { + * dontPublish (0), + * pleasePublish (1) }, + * pubInfos SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL + * -- pubInfos MUST NOT be present if action is "dontPublish" + * -- (if action is "pleasePublish" and pubInfos is omitted, + * -- "dontCare" is assumed) + * } + */ +struct ossl_crmf_pkipublicationinfo_st { + ASN1_INTEGER *action; + OSSL_CRMF_PUBINFOS *pubInfos; +} /* OSSL_CRMF_PKIPUBLICATIONINFO */; +DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_PKIPUBLICATIONINFO) + +/*- + * PKMACValue ::= SEQUENCE { + * algId AlgorithmIdentifier, + * -- algorithm value shall be PasswordBasedMac {1 2 840 113533 7 66 13} + * -- parameter value is PBMParameter + * value BIT STRING + * } + */ +typedef struct ossl_crmf_pkmacvalue_st { + X509_ALGOR *algId; + ASN1_BIT_STRING *value; +} OSSL_CRMF_PKMACVALUE; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PKMACVALUE) + +/*- + * SubsequentMessage ::= INTEGER { + * encrCert (0), + * -- requests that resulting certificate be encrypted for the + * -- end entity (following which, POP will be proven in a + * -- confirmation message) + * challengeResp (1) + * -- requests that CA engage in challenge-response exchange with + * -- end entity in order to prove private key possession + * } + * + * POPOPrivKey ::= CHOICE { + * thisMessage [0] BIT STRING, -- Deprecated + * -- possession is proven in this message (which contains the private + * -- key itself (encrypted for the CA)) + * subsequentMessage [1] SubsequentMessage, + * -- possession will be proven in a subsequent message + * dhMAC [2] BIT STRING, -- Deprecated + * agreeMAC [3] PKMACValue, + * encryptedKey [4] EnvelopedData + * } + */ + +typedef struct ossl_crmf_popoprivkey_st { + int type; + union { + ASN1_BIT_STRING *thisMessage; /* 0 */ /* Deprecated */ + ASN1_INTEGER *subsequentMessage; /* 1 */ + ASN1_BIT_STRING *dhMAC; /* 2 */ /* Deprecated */ + OSSL_CRMF_PKMACVALUE *agreeMAC; /* 3 */ + ASN1_NULL *encryptedKey; /* 4 */ + } value; +} OSSL_CRMF_POPOPRIVKEY; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOPRIVKEY) + +/*- + * PBMParameter ::= SEQUENCE { + * salt OCTET STRING, + * owf AlgorithmIdentifier, + * -- AlgId for a One-Way Function (SHA-1 recommended) + * iterationCount INTEGER, + * -- number of times the OWF is applied + * mac AlgorithmIdentifier + * -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11], + * -- or HMAC [HMAC, RFC2202]) + * } + */ +struct ossl_crmf_pbmparameter_st { + ASN1_OCTET_STRING *salt; + X509_ALGOR *owf; + ASN1_INTEGER *iterationCount; + X509_ALGOR *mac; +} /* OSSL_CRMF_PBMPARAMETER */; +# define OSSL_CRMF_PBM_MAX_ITERATION_COUNT 100000 /* if too large allows DoS */ + +/*- + * POPOSigningKeyInput ::= SEQUENCE { + * authInfo CHOICE { + * sender [0] GeneralName, + * -- used only if an authenticated identity has been + * -- established for the sender (e.g., a DN from a + * -- previously-issued and currently-valid certificate) + * publicKeyMAC PKMACValue }, + * -- used if no authenticated GeneralName currently exists for + * -- the sender; publicKeyMAC contains a password-based MAC + * -- on the DER-encoded value of publicKey + * publicKey SubjectPublicKeyInfo -- from CertTemplate + * } + */ +typedef struct ossl_crmf_poposigningkeyinput_authinfo_st { + int type; + union { + /* 0 */ GENERAL_NAME *sender; + /* 1 */ OSSL_CRMF_PKMACVALUE *publicKeyMAC; + } value; +} OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) + +typedef struct ossl_crmf_poposigningkeyinput_st { + OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO *authInfo; + X509_PUBKEY *publicKey; +} OSSL_CRMF_POPOSIGNINGKEYINPUT; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT) + +/*- + * POPOSigningKey ::= SEQUENCE { + * poposkInput [0] POPOSigningKeyInput OPTIONAL, + * algorithmIdentifier AlgorithmIdentifier, + * signature BIT STRING + * } + */ +struct ossl_crmf_poposigningkey_st { + OSSL_CRMF_POPOSIGNINGKEYINPUT *poposkInput; + X509_ALGOR *algorithmIdentifier; + ASN1_BIT_STRING *signature; +} /* OSSL_CRMF_POPOSIGNINGKEY */; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEY) + +/*- + * ProofOfPossession ::= CHOICE { + * raVerified [0] NULL, + * -- used if the RA has already verified that the requester is in + * -- possession of the private key + * signature [1] POPOSigningKey, + * keyEncipherment [2] POPOPrivKey, + * keyAgreement [3] POPOPrivKey + * } + */ +typedef struct ossl_crmf_popo_st { + int type; + union { + ASN1_NULL *raVerified; /* 0 */ + OSSL_CRMF_POPOSIGNINGKEY *signature; /* 1 */ + OSSL_CRMF_POPOPRIVKEY *keyEncipherment; /* 2 */ + OSSL_CRMF_POPOPRIVKEY *keyAgreement; /* 3 */ + } value; +} OSSL_CRMF_POPO; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPO) + +/*- + * OptionalValidity ::= SEQUENCE { + * notBefore [0] Time OPTIONAL, + * notAfter [1] Time OPTIONAL -- at least one MUST be present + * } + */ +struct ossl_crmf_optionalvalidity_st { + /* 0 */ ASN1_TIME *notBefore; + /* 1 */ ASN1_TIME *notAfter; +} /* OSSL_CRMF_OPTIONALVALIDITY */; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_OPTIONALVALIDITY) + +/*- + * CertTemplate ::= SEQUENCE { + * version [0] Version OPTIONAL, + * serialNumber [1] INTEGER OPTIONAL, + * signingAlg [2] AlgorithmIdentifier OPTIONAL, + * issuer [3] Name OPTIONAL, + * validity [4] OptionalValidity OPTIONAL, + * subject [5] Name OPTIONAL, + * publicKey [6] SubjectPublicKeyInfo OPTIONAL, + * issuerUID [7] UniqueIdentifier OPTIONAL, + * subjectUID [8] UniqueIdentifier OPTIONAL, + * extensions [9] Extensions OPTIONAL + * } + */ +struct ossl_crmf_certtemplate_st { + ASN1_INTEGER *version; + ASN1_INTEGER *serialNumber; /* serialNumber MUST be omitted */ + /* This field is assigned by the CA during certificate creation */ + X509_ALGOR *signingAlg; /* signingAlg MUST be omitted */ + /* This field is assigned by the CA during certificate creation */ + const X509_NAME *issuer; + OSSL_CRMF_OPTIONALVALIDITY *validity; + const X509_NAME *subject; + X509_PUBKEY *publicKey; + ASN1_BIT_STRING *issuerUID; /* deprecated in version 2 */ + /* According to rfc 3280: UniqueIdentifier ::= BIT STRING */ + ASN1_BIT_STRING *subjectUID; /* deprecated in version 2 */ + /* Could be X509_EXTENSION*S*, but that's only cosmetic */ + STACK_OF(X509_EXTENSION) *extensions; +} /* OSSL_CRMF_CERTTEMPLATE */; + +/*- + * CertRequest ::= SEQUENCE { + * certReqId INTEGER, -- ID for matching request and reply + * certTemplate CertTemplate, -- Selected fields of cert to be issued + * controls Controls OPTIONAL -- Attributes affecting issuance + * } + */ +struct ossl_crmf_certrequest_st { + ASN1_INTEGER *certReqId; + OSSL_CRMF_CERTTEMPLATE *certTemplate; + STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *controls; +} /* OSSL_CRMF_CERTREQUEST */; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTREQUEST) +DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTREQUEST) + +struct ossl_crmf_attributetypeandvalue_st { + ASN1_OBJECT *type; + union { + /* NID_id_regCtrl_regToken */ + ASN1_UTF8STRING *regToken; + + /* NID_id_regCtrl_authenticator */ + ASN1_UTF8STRING *authenticator; + + /* NID_id_regCtrl_pkiPublicationInfo */ + OSSL_CRMF_PKIPUBLICATIONINFO *pkiPublicationInfo; + + /* NID_id_regCtrl_oldCertID */ + OSSL_CRMF_CERTID *oldCertID; + + /* NID_id_regCtrl_protocolEncrKey */ + X509_PUBKEY *protocolEncrKey; + + /* NID_id_regInfo_utf8Pairs */ + ASN1_UTF8STRING *utf8Pairs; + + /* NID_id_regInfo_certReq */ + OSSL_CRMF_CERTREQUEST *certReq; + + ASN1_TYPE *other; + } value; +} /* OSSL_CRMF_ATTRIBUTETYPEANDVALUE */; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +DEFINE_STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) + +/*- + * CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg + * CertReqMsg ::= SEQUENCE { + * certReq CertRequest, + * popo ProofOfPossession OPTIONAL, + * -- content depends upon key type + * regInfo SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue OPTIONAL + * } + */ +struct ossl_crmf_msg_st { + OSSL_CRMF_CERTREQUEST *certReq; + /* 0 */ + OSSL_CRMF_POPO *popo; + /* 1 */ + STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *regInfo; +} /* OSSL_CRMF_MSG */; +#endif diff --git a/crypto/openssl/crypto/crmf/crmf_pbm.c b/crypto/openssl/crypto/crmf/crmf_pbm.c new file mode 100644 index 000000000000..88a8480cf73a --- /dev/null +++ b/crypto/openssl/crypto/crmf/crmf_pbm.c @@ -0,0 +1,233 @@ +/*- + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * CRMF implementation by Martin Peylo, Miikka Viljanen, and David von Oheimb. + */ + + +#include + +#include +#include +#include + +/* explicit #includes not strictly needed since implied by the above: */ +#include +#include +#include +#include +#include +#include + +#include "internal/sizes.h" + +#include "crmf_local.h" + +/*- + * creates and initializes OSSL_CRMF_PBMPARAMETER (section 4.4) + * |slen| SHOULD be at least 8 (16 is common) + * |owfnid| e.g., NID_sha256 + * |itercnt| MUST be >= 100 (e.g., 500) and <= OSSL_CRMF_PBM_MAX_ITERATION_COUNT + * |macnid| e.g., NID_hmac_sha1 + * returns pointer to OSSL_CRMF_PBMPARAMETER on success, NULL on error + */ +OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OSSL_LIB_CTX *libctx, size_t slen, + int owfnid, size_t itercnt, + int macnid) +{ + OSSL_CRMF_PBMPARAMETER *pbm = NULL; + unsigned char *salt = NULL; + + if ((pbm = OSSL_CRMF_PBMPARAMETER_new()) == NULL) + goto err; + + /* + * salt contains a randomly generated value used in computing the key + * of the MAC process. The salt SHOULD be at least 8 octets (64 + * bits) long. + */ + if ((salt = OPENSSL_malloc(slen)) == NULL) + goto err; + if (RAND_bytes_ex(libctx, salt, slen, 0) <= 0) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_FAILURE_OBTAINING_RANDOM); + goto err; + } + if (!ASN1_OCTET_STRING_set(pbm->salt, salt, (int)slen)) + goto err; + + /* + * owf identifies the hash algorithm and associated parameters used to + * compute the key used in the MAC process. All implementations MUST + * support SHA-1. + */ + if (!X509_ALGOR_set0(pbm->owf, OBJ_nid2obj(owfnid), V_ASN1_UNDEF, NULL)) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_SETTING_OWF_ALGOR_FAILURE); + goto err; + } + + /* + * iterationCount identifies the number of times the hash is applied + * during the key computation process. The iterationCount MUST be a + * minimum of 100. Many people suggest using values as high as 1000 + * iterations as the minimum value. The trade off here is between + * protection of the password from attacks and the time spent by the + * server processing all of the different iterations in deriving + * passwords. Hashing is generally considered a cheap operation but + * this may not be true with all hash functions in the future. + */ + if (itercnt < 100) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_ITERATIONCOUNT_BELOW_100); + goto err; + } + if (itercnt > OSSL_CRMF_PBM_MAX_ITERATION_COUNT) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_BAD_PBM_ITERATIONCOUNT); + goto err; + } + + if (!ASN1_INTEGER_set(pbm->iterationCount, itercnt)) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_CRMFERROR); + goto err; + } + + /* + * mac identifies the algorithm and associated parameters of the MAC + * function to be used. All implementations MUST support HMAC-SHA1 [HMAC]. + * All implementations SHOULD support DES-MAC and Triple-DES-MAC [PKCS11]. + */ + if (!X509_ALGOR_set0(pbm->mac, OBJ_nid2obj(macnid), V_ASN1_UNDEF, NULL)) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_SETTING_MAC_ALGOR_FAILURE); + goto err; + } + + OPENSSL_free(salt); + return pbm; + err: + OPENSSL_free(salt); + OSSL_CRMF_PBMPARAMETER_free(pbm); + return NULL; +} + +/*- + * calculates the PBM based on the settings of the given OSSL_CRMF_PBMPARAMETER + * |pbmp| identifies the algorithms, salt to use + * |msg| message to apply the PBM for + * |msglen| length of the message + * |sec| key to use + * |seclen| length of the key + * |out| pointer to the computed mac, will be set on success + * |outlen| if not NULL, will set variable to the length of the mac on success + * returns 1 on success, 0 on error + */ +int OSSL_CRMF_pbm_new(OSSL_LIB_CTX *libctx, const char *propq, + const OSSL_CRMF_PBMPARAMETER *pbmp, + const unsigned char *msg, size_t msglen, + const unsigned char *sec, size_t seclen, + unsigned char **out, size_t *outlen) +{ + int mac_nid, hmac_md_nid = NID_undef; + char mdname[OSSL_MAX_NAME_SIZE]; + char hmac_mdname[OSSL_MAX_NAME_SIZE]; + EVP_MD *owf = NULL; + EVP_MD_CTX *ctx = NULL; + unsigned char basekey[EVP_MAX_MD_SIZE]; + unsigned int bklen = EVP_MAX_MD_SIZE; + int64_t iterations; + unsigned char *mac_res = 0; + int ok = 0; + + if (out == NULL || pbmp == NULL || pbmp->mac == NULL + || pbmp->mac->algorithm == NULL || msg == NULL || sec == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); + goto err; + } + if ((mac_res = OPENSSL_malloc(EVP_MAX_MD_SIZE)) == NULL) + goto err; + + /* + * owf identifies the hash algorithm and associated parameters used to + * compute the key used in the MAC process. All implementations MUST + * support SHA-1. + */ + OBJ_obj2txt(mdname, sizeof(mdname), pbmp->owf->algorithm, 0); + if ((owf = EVP_MD_fetch(libctx, mdname, propq)) == NULL) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_ALGORITHM); + goto err; + } + + if ((ctx = EVP_MD_CTX_new()) == NULL) + goto err; + + /* compute the basekey of the salted secret */ + if (!EVP_DigestInit_ex(ctx, owf, NULL)) + goto err; + /* first the secret */ + if (!EVP_DigestUpdate(ctx, sec, seclen)) + goto err; + /* then the salt */ + if (!EVP_DigestUpdate(ctx, pbmp->salt->data, pbmp->salt->length)) + goto err; + if (!EVP_DigestFinal_ex(ctx, basekey, &bklen)) + goto err; + if (!ASN1_INTEGER_get_int64(&iterations, pbmp->iterationCount) + || iterations < 100 /* min from RFC */ + || iterations > OSSL_CRMF_PBM_MAX_ITERATION_COUNT) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_BAD_PBM_ITERATIONCOUNT); + goto err; + } + + /* the first iteration was already done above */ + while (--iterations > 0) { + if (!EVP_DigestInit_ex(ctx, owf, NULL)) + goto err; + if (!EVP_DigestUpdate(ctx, basekey, bklen)) + goto err; + if (!EVP_DigestFinal_ex(ctx, basekey, &bklen)) + goto err; + } + + /* + * mac identifies the algorithm and associated parameters of the MAC + * function to be used. All implementations MUST support HMAC-SHA1 [HMAC]. + * All implementations SHOULD support DES-MAC and Triple-DES-MAC [PKCS11]. + */ + mac_nid = OBJ_obj2nid(pbmp->mac->algorithm); + + if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, mac_nid, NULL, &hmac_md_nid, NULL) + || OBJ_obj2txt(hmac_mdname, sizeof(hmac_mdname), + OBJ_nid2obj(hmac_md_nid), 0) <= 0) { + ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_ALGORITHM); + goto err; + } + if (EVP_Q_mac(libctx, "HMAC", propq, hmac_mdname, NULL, basekey, bklen, + msg, msglen, mac_res, EVP_MAX_MD_SIZE, outlen) == NULL) + goto err; + + ok = 1; + + err: + OPENSSL_cleanse(basekey, bklen); + EVP_MD_free(owf); + EVP_MD_CTX_free(ctx); + + if (ok == 1) { + *out = mac_res; + return 1; + } + + OPENSSL_free(mac_res); + + if (pbmp != NULL && pbmp->mac != NULL) { + char buf[128]; + + if (OBJ_obj2txt(buf, sizeof(buf), pbmp->mac->algorithm, 0)) + ERR_add_error_data(1, buf); + } + return 0; +} diff --git a/crypto/openssl/crypto/cryptlib.c b/crypto/openssl/crypto/cryptlib.c index 1f36b20c86ed..6e73b8352cac 100644 --- a/crypto/openssl/crypto/cryptlib.c +++ b/crypto/openssl/crypto/cryptlib.c @@ -1,8 +1,8 @@ /* - * Copyright 1998-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2021 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 + * 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 @@ -12,161 +12,6 @@ #include "crypto/cryptlib.h" #include -#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64) - -extern unsigned int OPENSSL_ia32cap_P[4]; - -# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) - -/* - * Purpose of these minimalistic and character-type-agnostic subroutines - * is to break dependency on MSVCRT (on Windows) and locale. This makes - * OPENSSL_cpuid_setup safe to use as "constructor". "Character-type- - * agnostic" means that they work with either wide or 8-bit characters, - * exploiting the fact that first 127 characters can be simply casted - * between the sets, while the rest would be simply rejected by ossl_is* - * subroutines. - */ -# ifdef _WIN32 -typedef WCHAR variant_char; - -static variant_char *ossl_getenv(const char *name) -{ - /* - * Since we pull only one environment variable, it's simpler to - * to just ignore |name| and use equivalent wide-char L-literal. - * As well as to ignore excessively long values... - */ - static WCHAR value[48]; - DWORD len = GetEnvironmentVariableW(L"OPENSSL_ia32cap", value, 48); - - return (len > 0 && len < 48) ? value : NULL; -} -# else -typedef char variant_char; -# define ossl_getenv getenv -# endif - -# include "crypto/ctype.h" - -static int todigit(variant_char c) -{ - if (ossl_isdigit(c)) - return c - '0'; - else if (ossl_isxdigit(c)) - return ossl_tolower(c) - 'a' + 10; - - /* return largest base value to make caller terminate the loop */ - return 16; -} - -static uint64_t ossl_strtouint64(const variant_char *str) -{ - uint64_t ret = 0; - unsigned int digit, base = 10; - - if (*str == '0') { - base = 8, str++; - if (ossl_tolower(*str) == 'x') - base = 16, str++; - } - - while((digit = todigit(*str++)) < base) - ret = ret * base + digit; - - return ret; -} - -static variant_char *ossl_strchr(const variant_char *str, char srch) -{ variant_char c; - - while((c = *str)) { - if (c == srch) - return (variant_char *)str; - str++; - } - - return NULL; -} - -# define OPENSSL_CPUID_SETUP -typedef uint64_t IA32CAP; - -void OPENSSL_cpuid_setup(void) -{ - static int trigger = 0; - IA32CAP OPENSSL_ia32_cpuid(unsigned int *); - IA32CAP vec; - const variant_char *env; - - if (trigger) - return; - - trigger = 1; - if ((env = ossl_getenv("OPENSSL_ia32cap")) != NULL) { - int off = (env[0] == '~') ? 1 : 0; - - vec = ossl_strtouint64(env + off); - - if (off) { - IA32CAP mask = vec; - vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~mask; - if (mask & (1<<24)) { - /* - * User disables FXSR bit, mask even other capabilities - * that operate exclusively on XMM, so we don't have to - * double-check all the time. We mask PCLMULQDQ, AMD XOP, - * AES-NI and AVX. Formally speaking we don't have to - * do it in x86_64 case, but we can safely assume that - * x86_64 users won't actually flip this flag. - */ - vec &= ~((IA32CAP)(1<<1|1<<11|1<<25|1<<28) << 32); - } - } else if (env[0] == ':') { - vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); - } - - if ((env = ossl_strchr(env, ':')) != NULL) { - IA32CAP vecx; - - env++; - off = (env[0] == '~') ? 1 : 0; - vecx = ossl_strtouint64(env + off); - if (off) { - OPENSSL_ia32cap_P[2] &= ~(unsigned int)vecx; - OPENSSL_ia32cap_P[3] &= ~(unsigned int)(vecx >> 32); - } else { - OPENSSL_ia32cap_P[2] = (unsigned int)vecx; - OPENSSL_ia32cap_P[3] = (unsigned int)(vecx >> 32); - } - } else { - OPENSSL_ia32cap_P[2] = 0; - OPENSSL_ia32cap_P[3] = 0; - } - } else { - vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); - } - - /* - * |(1<<10) sets a reserved bit to signal that variable - * was initialized already... This is to avoid interference - * with cpuid snippets in ELF .init segment. - */ - OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10); - OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32); -} -# else -unsigned int OPENSSL_ia32cap_P[4]; -# endif -#endif -#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ) -void OPENSSL_cpuid_setup(void) -{ -} -#endif - #if defined(_WIN32) # include # include @@ -349,12 +194,6 @@ void OPENSSL_showfatal(const char *fmta, ...) # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 # ifdef OPENSSL_SYS_WIN_CORE /* ONECORE is always NONGUI and NT >= 0x0601 */ - - /* - * TODO: (For non GUI and no std error cases) - * Add event logging feature here. - */ - # if !defined(NDEBUG) /* * We are in a situation where we tried to report a critical @@ -430,44 +269,14 @@ void OPENSSL_die(const char *message, const char *file, int line) #endif } -#if !defined(OPENSSL_CPUID_OBJ) +#if defined(__TANDEM) && defined(OPENSSL_VPROC) /* - * The volatile is used to to ensure that the compiler generates code that reads - * all values from the array and doesn't try to optimize this away. The standard - * doesn't actually require this behavior if the original data pointed to is - * not volatile, but compilers do this in practice anyway. - * - * There are also assembler versions of this function. - */ -# undef CRYPTO_memcmp -int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len) -{ - size_t i; - const volatile unsigned char *a = in_a; - const volatile unsigned char *b = in_b; - unsigned char x = 0; - - for (i = 0; i < len; i++) - x |= a[i] ^ b[i]; - - return x; -} - -/* - * For systems that don't provide an instruction counter register or equivalent. + * Define a VPROC function for HP NonStop build crypto library. + * This is used by platform version identification tools. + * Do not inline this procedure or make it static. */ -uint32_t OPENSSL_rdtsc(void) -{ - return 0; -} - -size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt) -{ - return 0; -} - -size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max) -{ - return 0; -} -#endif +# define OPENSSL_VPROC_STRING_(x) x##_CRYPTO +# define OPENSSL_VPROC_STRING(x) OPENSSL_VPROC_STRING_(x) +# define OPENSSL_VPROC_FUNC OPENSSL_VPROC_STRING(OPENSSL_VPROC) +void OPENSSL_VPROC_FUNC(void) {} +#endif /* __TANDEM */ diff --git a/crypto/openssl/crypto/ct/ct_b64.c b/crypto/openssl/crypto/ct/ct_b64.c index 4abe11ca298b..d3f783962aec 100644 --- a/crypto/openssl/crypto/ct/ct_b64.c +++ b/crypto/openssl/crypto/ct/ct_b64.c @@ -1,7 +1,7 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -35,13 +35,13 @@ static int ct_base64_decode(const char *in, unsigned char **out) outlen = (inlen / 4) * 3; outbuf = OPENSSL_malloc(outlen); if (outbuf == NULL) { - CTerr(CT_F_CT_BASE64_DECODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); goto err; } outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen); if (outlen < 0) { - CTerr(CT_F_CT_BASE64_DECODE, CT_R_BASE64_DECODE_ERROR); + ERR_raise(ERR_LIB_CT, CT_R_BASE64_DECODE_ERROR); goto err; } @@ -71,7 +71,7 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64, int declen; if (sct == NULL) { - CTerr(CT_F_SCT_NEW_FROM_BASE64, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); return NULL; } @@ -80,13 +80,13 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64, * can only construct SCT versions that have been defined. */ if (!SCT_set_version(sct, version)) { - CTerr(CT_F_SCT_NEW_FROM_BASE64, CT_R_SCT_UNSUPPORTED_VERSION); + ERR_raise(ERR_LIB_CT, CT_R_SCT_UNSUPPORTED_VERSION); goto err; } declen = ct_base64_decode(logid_base64, &dec); if (declen < 0) { - CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR); + ERR_raise(ERR_LIB_CT, X509_R_BASE64_DECODE_ERROR); goto err; } if (!SCT_set0_log_id(sct, dec, declen)) @@ -95,7 +95,7 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64, declen = ct_base64_decode(extensions_base64, &dec); if (declen < 0) { - CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR); + ERR_raise(ERR_LIB_CT, X509_R_BASE64_DECODE_ERROR); goto err; } SCT_set0_extensions(sct, dec, declen); @@ -103,7 +103,7 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64, declen = ct_base64_decode(signature_base64, &dec); if (declen < 0) { - CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR); + ERR_raise(ERR_LIB_CT, X509_R_BASE64_DECODE_ERROR); goto err; } @@ -132,7 +132,9 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64, * 0 on decoding failure, or invalid parameter if any * -1 on internal (malloc) failure */ -int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *name) +int CTLOG_new_from_base64_ex(CTLOG **ct_log, const char *pkey_base64, + const char *name, OSSL_LIB_CTX *libctx, + const char *propq) { unsigned char *pkey_der = NULL; int pkey_der_len; @@ -140,25 +142,25 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n EVP_PKEY *pkey = NULL; if (ct_log == NULL) { - CTerr(CT_F_CTLOG_NEW_FROM_BASE64, ERR_R_PASSED_INVALID_ARGUMENT); + ERR_raise(ERR_LIB_CT, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der); if (pkey_der_len < 0) { - CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY); + ERR_raise(ERR_LIB_CT, CT_R_LOG_CONF_INVALID_KEY); return 0; } p = pkey_der; - pkey = d2i_PUBKEY(NULL, &p, pkey_der_len); + pkey = d2i_PUBKEY_ex(NULL, &p, pkey_der_len, libctx, propq); OPENSSL_free(pkey_der); if (pkey == NULL) { - CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY); + ERR_raise(ERR_LIB_CT, CT_R_LOG_CONF_INVALID_KEY); return 0; } - *ct_log = CTLOG_new(pkey, name); + *ct_log = CTLOG_new_ex(pkey, name, libctx, propq); if (*ct_log == NULL) { EVP_PKEY_free(pkey); return 0; @@ -166,3 +168,9 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n return 1; } + +int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, + const char *name) +{ + return CTLOG_new_from_base64_ex(ct_log, pkey_base64, name, NULL, NULL); +} diff --git a/crypto/openssl/crypto/ct/ct_err.c b/crypto/openssl/crypto/ct/ct_err.c index c0c62fee6c6a..c4dd05119eba 100644 --- a/crypto/openssl/crypto/ct/ct_err.c +++ b/crypto/openssl/crypto/ct/ct_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,47 +10,11 @@ #include #include +#include "crypto/cterr.h" -#ifndef OPENSSL_NO_ERR +#ifndef OPENSSL_NO_CT -static const ERR_STRING_DATA CT_str_functs[] = { - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW, 0), "CTLOG_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW_FROM_BASE64, 0), - "CTLOG_new_from_base64"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_NEW_FROM_CONF, 0), "ctlog_new_from_conf"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_CTX_NEW, 0), - "ctlog_store_load_ctx_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_FILE, 0), - "CTLOG_STORE_load_file"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_LOAD_LOG, 0), - "ctlog_store_load_log"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CTLOG_STORE_NEW, 0), "CTLOG_STORE_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CT_BASE64_DECODE, 0), "ct_base64_decode"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CT_POLICY_EVAL_CTX_NEW, 0), - "CT_POLICY_EVAL_CTX_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_CT_V1_LOG_ID_FROM_PKEY, 0), - "ct_v1_log_id_from_pkey"}, - {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT, 0), "i2o_SCT"}, - {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT_LIST, 0), "i2o_SCT_LIST"}, - {ERR_PACK(ERR_LIB_CT, CT_F_I2O_SCT_SIGNATURE, 0), "i2o_SCT_signature"}, - {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT, 0), "o2i_SCT"}, - {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT_LIST, 0), "o2i_SCT_LIST"}, - {ERR_PACK(ERR_LIB_CT, CT_F_O2I_SCT_SIGNATURE, 0), "o2i_SCT_signature"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_CTX_NEW, 0), "SCT_CTX_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_CTX_VERIFY, 0), "SCT_CTX_verify"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_NEW, 0), "SCT_new"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_NEW_FROM_BASE64, 0), "SCT_new_from_base64"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET0_LOG_ID, 0), "SCT_set0_log_id"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_EXTENSIONS, 0), "SCT_set1_extensions"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_LOG_ID, 0), "SCT_set1_log_id"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET1_SIGNATURE, 0), "SCT_set1_signature"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_LOG_ENTRY_TYPE, 0), - "SCT_set_log_entry_type"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_SIGNATURE_NID, 0), - "SCT_set_signature_nid"}, - {ERR_PACK(ERR_LIB_CT, CT_F_SCT_SET_VERSION, 0), "SCT_set_version"}, - {0, NULL} -}; +# ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA CT_str_reasons[] = { {ERR_PACK(ERR_LIB_CT, 0, CT_R_BASE64_DECODE_ERROR), "base64 decode error"}, @@ -82,15 +46,16 @@ static const ERR_STRING_DATA CT_str_reasons[] = { {0, NULL} }; -#endif +# endif -int ERR_load_CT_strings(void) +int ossl_err_load_CT_strings(void) { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(CT_str_functs[0].error) == NULL) { - ERR_load_strings_const(CT_str_functs); +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(CT_str_reasons[0].error) == NULL) ERR_load_strings_const(CT_str_reasons); - } -#endif +# endif return 1; } +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/ct/ct_local.h b/crypto/openssl/crypto/ct/ct_local.h index 9f983c91beae..e5614ddf5eb4 100644 --- a/crypto/openssl/crypto/ct/ct_local.h +++ b/crypto/openssl/crypto/ct/ct_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -100,6 +100,9 @@ struct sct_ctx_st { size_t prederlen; /* milliseconds since epoch (to check that the SCT isn't from the future) */ uint64_t epoch_time_in_ms; + + OSSL_LIB_CTX *libctx; + char *propq; }; /* Context when evaluating whether a Certificate Transparency policy is met */ @@ -109,12 +112,15 @@ struct ct_policy_eval_ctx_st { CTLOG_STORE *log_store; /* milliseconds since epoch (to check that SCTs aren't from the future) */ uint64_t epoch_time_in_ms; + + OSSL_LIB_CTX *libctx; + char *propq; }; /* * Creates a new context for verifying an SCT. */ -SCT_CTX *SCT_CTX_new(void); +SCT_CTX *SCT_CTX_new(OSSL_LIB_CTX *ctx, const char *propq); /* * Deletes an SCT verification context. */ @@ -184,11 +190,6 @@ __owur int SCT_is_complete(const SCT *sct); */ __owur int SCT_signature_is_complete(const SCT *sct); -/* - * TODO(RJPercival): Create an SCT_signature struct and make i2o_SCT_signature - * and o2i_SCT_signature conform to the i2d/d2i conventions. - */ - /* * Serialize (to TLS format) an |sct| signature and write it to |out|. * If |out| is null, no signature will be output but the length will be returned. @@ -213,4 +214,4 @@ __owur int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len); /* * Handlers for Certificate Transparency X509v3/OCSP extensions */ -extern const X509V3_EXT_METHOD v3_ct_scts[3]; +extern const X509V3_EXT_METHOD ossl_v3_ct_scts[3]; diff --git a/crypto/openssl/crypto/ct/ct_log.c b/crypto/openssl/crypto/ct/ct_log.c index c1bca3e1415e..d19dda2cd2f2 100644 --- a/crypto/openssl/crypto/ct/ct_log.c +++ b/crypto/openssl/crypto/ct/ct_log.c @@ -1,7 +1,7 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -22,6 +22,8 @@ * Information about a CT log server. */ struct ctlog_st { + OSSL_LIB_CTX *libctx; + char *propq; char *name; uint8_t log_id[CT_V1_HASHLEN]; EVP_PKEY *public_key; @@ -32,6 +34,8 @@ struct ctlog_st { * It takes ownership of any CTLOG instances added to it. */ struct ctlog_store_st { + OSSL_LIB_CTX *libctx; + char *propq; STACK_OF(CTLOG) *logs; }; @@ -59,7 +63,7 @@ static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new(void) CTLOG_STORE_LOAD_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx == NULL) - CTerr(CT_F_CTLOG_STORE_LOAD_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); return ctx; } @@ -70,69 +74,95 @@ static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx) } /* Converts a log's public key into a SHA256 log ID */ -static int ct_v1_log_id_from_pkey(EVP_PKEY *pkey, - unsigned char log_id[CT_V1_HASHLEN]) +static int ct_v1_log_id_from_pkey(CTLOG *log, EVP_PKEY *pkey) { int ret = 0; unsigned char *pkey_der = NULL; int pkey_der_len = i2d_PUBKEY(pkey, &pkey_der); + unsigned int len; + EVP_MD *sha256 = NULL; if (pkey_der_len <= 0) { - CTerr(CT_F_CT_V1_LOG_ID_FROM_PKEY, CT_R_LOG_KEY_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_LOG_KEY_INVALID); + goto err; + } + sha256 = EVP_MD_fetch(log->libctx, "SHA2-256", log->propq); + if (sha256 == NULL) { + ERR_raise(ERR_LIB_CT, ERR_R_EVP_LIB); goto err; } - SHA256(pkey_der, pkey_der_len, log_id); - ret = 1; + ret = EVP_Digest(pkey_der, pkey_der_len, log->log_id, &len, sha256, + NULL); err: + EVP_MD_free(sha256); OPENSSL_free(pkey_der); return ret; } -CTLOG_STORE *CTLOG_STORE_new(void) +CTLOG_STORE *CTLOG_STORE_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { CTLOG_STORE *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - CTerr(CT_F_CTLOG_STORE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); return NULL; } + ret->libctx = libctx; + if (propq != NULL) { + ret->propq = OPENSSL_strdup(propq); + if (ret->propq == NULL) { + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + goto err; + } + } + ret->logs = sk_CTLOG_new_null(); - if (ret->logs == NULL) + if (ret->logs == NULL) { + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); goto err; + } return ret; err: - OPENSSL_free(ret); + CTLOG_STORE_free(ret); return NULL; } +CTLOG_STORE *CTLOG_STORE_new(void) +{ + return CTLOG_STORE_new_ex(NULL, NULL); +} + void CTLOG_STORE_free(CTLOG_STORE *store) { if (store != NULL) { + OPENSSL_free(store->propq); sk_CTLOG_pop_free(store->logs, CTLOG_free); OPENSSL_free(store); } } -static int ctlog_new_from_conf(CTLOG **ct_log, const CONF *conf, const char *section) +static int ctlog_new_from_conf(CTLOG_STORE *store, CTLOG **ct_log, + const CONF *conf, const char *section) { const char *description = NCONF_get_string(conf, section, "description"); char *pkey_base64; if (description == NULL) { - CTerr(CT_F_CTLOG_NEW_FROM_CONF, CT_R_LOG_CONF_MISSING_DESCRIPTION); + ERR_raise(ERR_LIB_CT, CT_R_LOG_CONF_MISSING_DESCRIPTION); return 0; } pkey_base64 = NCONF_get_string(conf, section, "key"); if (pkey_base64 == NULL) { - CTerr(CT_F_CTLOG_NEW_FROM_CONF, CT_R_LOG_CONF_MISSING_KEY); + ERR_raise(ERR_LIB_CT, CT_R_LOG_CONF_MISSING_KEY); return 0; } - return CTLOG_new_from_base64(ct_log, pkey_base64, description); + return CTLOG_new_from_base64_ex(ct_log, pkey_base64, description, + store->libctx, store->propq); } int CTLOG_STORE_load_default_file(CTLOG_STORE *store) @@ -168,7 +198,7 @@ static int ctlog_store_load_log(const char *log_name, int log_name_len, if (tmp == NULL) goto mem_err; - ret = ctlog_new_from_conf(&ct_log, load_ctx->conf, tmp); + ret = ctlog_new_from_conf(load_ctx->log_store, &ct_log, load_ctx->conf, tmp); OPENSSL_free(tmp); if (ret < 0) { @@ -188,7 +218,7 @@ static int ctlog_store_load_log(const char *log_name, int log_name_len, mem_err: CTLOG_free(ct_log); - CTerr(CT_F_CTLOG_STORE_LOAD_LOG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); return -1; } @@ -206,19 +236,19 @@ int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file) goto end; if (NCONF_load(load_ctx->conf, file, NULL) <= 0) { - CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_LOG_CONF_INVALID); goto end; } enabled_logs = NCONF_get_string(load_ctx->conf, NULL, "enabled_logs"); if (enabled_logs == NULL) { - CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_LOG_CONF_INVALID); goto end; } if (!CONF_parse_list(enabled_logs, ',', 1, ctlog_store_load_log, load_ctx) || load_ctx->invalid_log_entries > 0) { - CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_LOG_CONF_INVALID); goto end; } @@ -234,22 +264,32 @@ int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file) * Takes ownership of the public key. * Copies the name. */ -CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name) +CTLOG *CTLOG_new_ex(EVP_PKEY *public_key, const char *name, OSSL_LIB_CTX *libctx, + const char *propq) { CTLOG *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); return NULL; } + ret->libctx = libctx; + if (propq != NULL) { + ret->propq = OPENSSL_strdup(propq); + if (ret->propq == NULL) { + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + goto err; + } + } + ret->name = OPENSSL_strdup(name); if (ret->name == NULL) { - CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); goto err; } - if (ct_v1_log_id_from_pkey(public_key, ret->log_id) != 1) + if (ct_v1_log_id_from_pkey(ret, public_key) != 1) goto err; ret->public_key = public_key; @@ -259,12 +299,18 @@ CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name) return NULL; } +CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name) +{ + return CTLOG_new_ex(public_key, name, NULL, NULL); +} + /* Frees CT log and associated structures */ void CTLOG_free(CTLOG *log) { if (log != NULL) { OPENSSL_free(log->name); EVP_PKEY_free(log->public_key); + OPENSSL_free(log->propq); OPENSSL_free(log); } } diff --git a/crypto/openssl/crypto/ct/ct_oct.c b/crypto/openssl/crypto/ct/ct_oct.c index d4b6645af48d..72a43374797c 100644 --- a/crypto/openssl/crypto/ct/ct_oct.c +++ b/crypto/openssl/crypto/ct/ct_oct.c @@ -1,7 +1,7 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -28,7 +28,7 @@ int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len) const unsigned char *p; if (sct->version != SCT_VERSION_V1) { - CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION); + ERR_raise(ERR_LIB_CT, CT_R_UNSUPPORTED_VERSION); return -1; } /* @@ -39,7 +39,7 @@ int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len) * all supported algorithms. */ if (len <= 4) { - CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE); + ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE); return -1; } @@ -48,14 +48,14 @@ int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len) sct->hash_alg = *p++; sct->sig_alg = *p++; if (SCT_get_signature_nid(sct) == NID_undef) { - CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE); + ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE); return -1; } /* Retrieve signature and check it is consistent with the buffer length */ n2s(p, siglen); len_remaining -= (p - *in); if (siglen > len_remaining) { - CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE); + ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE); return -1; } @@ -73,7 +73,7 @@ SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len) const unsigned char *p; if (len == 0 || len > MAX_SCT_SIZE) { - CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID); goto err; } @@ -96,12 +96,12 @@ SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len) * } */ if (len < 43) { - CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID); goto err; } len -= 43; p++; - sct->log_id = BUF_memdup(p, CT_V1_HASHLEN); + sct->log_id = OPENSSL_memdup(p, CT_V1_HASHLEN); if (sct->log_id == NULL) goto err; sct->log_id_len = CT_V1_HASHLEN; @@ -111,11 +111,11 @@ SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len) n2s(p, len2); if (len < len2) { - CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID); goto err; } if (len2 > 0) { - sct->ext = BUF_memdup(p, len2); + sct->ext = OPENSSL_memdup(p, len2); if (sct->ext == NULL) goto err; } @@ -125,14 +125,14 @@ SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len) sig_len = o2i_SCT_signature(sct, &p, len); if (sig_len <= 0) { - CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID); goto err; } len -= sig_len; *in = p + len; } else { /* If not V1 just cache encoding */ - sct->sct = BUF_memdup(p, len); + sct->sct = OPENSSL_memdup(p, len); if (sct->sct == NULL) goto err; sct->sct_len = len; @@ -156,12 +156,12 @@ int i2o_SCT_signature(const SCT *sct, unsigned char **out) unsigned char *p = NULL, *pstart = NULL; if (!SCT_signature_is_complete(sct)) { - CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE); + ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE); goto err; } if (sct->version != SCT_VERSION_V1) { - CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION); + ERR_raise(ERR_LIB_CT, CT_R_UNSUPPORTED_VERSION); goto err; } @@ -179,7 +179,7 @@ int i2o_SCT_signature(const SCT *sct, unsigned char **out) } else { pstart = p = OPENSSL_malloc(len); if (p == NULL) { - CTerr(CT_F_I2O_SCT_SIGNATURE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); goto err; } *out = p; @@ -203,7 +203,7 @@ int i2o_SCT(const SCT *sct, unsigned char **out) unsigned char *p = NULL, *pstart = NULL; if (!SCT_is_complete(sct)) { - CTerr(CT_F_I2O_SCT, CT_R_SCT_NOT_SET); + ERR_raise(ERR_LIB_CT, CT_R_SCT_NOT_SET); goto err; } /* @@ -226,7 +226,7 @@ int i2o_SCT(const SCT *sct, unsigned char **out) } else { pstart = p = OPENSSL_malloc(len); if (p == NULL) { - CTerr(CT_F_I2O_SCT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); goto err; } *out = p; @@ -261,13 +261,13 @@ STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, size_t list_len, sct_len; if (len < 2 || len > MAX_SCT_LIST_SIZE) { - CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_SCT_LIST_INVALID); return NULL; } n2s(*pp, list_len); if (list_len != len - 2) { - CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_SCT_LIST_INVALID); return NULL; } @@ -288,14 +288,14 @@ STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, SCT *sct; if (list_len < 2) { - CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_SCT_LIST_INVALID); goto err; } n2s(*pp, sct_len); list_len -= 2; if (sct_len == 0 || sct_len > list_len) { - CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_SCT_LIST_INVALID); goto err; } list_len -= sct_len; @@ -327,11 +327,11 @@ int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp) if (pp != NULL) { if (*pp == NULL) { if ((len = i2o_SCT_LIST(a, NULL)) == -1) { - CTerr(CT_F_I2O_SCT_LIST, CT_R_SCT_LIST_INVALID); + ERR_raise(ERR_LIB_CT, CT_R_SCT_LIST_INVALID); return -1; } if ((*pp = OPENSSL_malloc(len)) == NULL) { - CTerr(CT_F_I2O_SCT_LIST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); return -1; } is_pp_new = 1; diff --git a/crypto/openssl/crypto/ct/ct_policy.c b/crypto/openssl/crypto/ct/ct_policy.c index df66e8a494d0..80a8baabe163 100644 --- a/crypto/openssl/crypto/ct/ct_policy.c +++ b/crypto/openssl/crypto/ct/ct_policy.c @@ -1,7 +1,7 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -25,15 +25,26 @@ */ static const time_t SCT_CLOCK_DRIFT_TOLERANCE = 300; -CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void) +CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_ex(OSSL_LIB_CTX *libctx, + const char *propq) { CT_POLICY_EVAL_CTX *ctx = OPENSSL_zalloc(sizeof(CT_POLICY_EVAL_CTX)); if (ctx == NULL) { - CTerr(CT_F_CT_POLICY_EVAL_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); return NULL; } + ctx->libctx = libctx; + if (propq != NULL) { + ctx->propq = OPENSSL_strdup(propq); + if (ctx->propq == NULL) { + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ctx); + return NULL; + } + } + /* time(NULL) shouldn't ever fail, so don't bother checking for -1. */ ctx->epoch_time_in_ms = (uint64_t)(time(NULL) + SCT_CLOCK_DRIFT_TOLERANCE) * 1000; @@ -41,12 +52,18 @@ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void) return ctx; } +CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void) +{ + return CT_POLICY_EVAL_CTX_new_ex(NULL, NULL); +} + void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx) { if (ctx == NULL) return; X509_free(ctx->cert); X509_free(ctx->issuer); + OPENSSL_free(ctx->propq); OPENSSL_free(ctx); } diff --git a/crypto/openssl/crypto/ct/ct_prn.c b/crypto/openssl/crypto/ct/ct_prn.c index e6584b57f391..374235b7ec57 100644 --- a/crypto/openssl/crypto/ct/ct_prn.c +++ b/crypto/openssl/crypto/ct/ct_prn.c @@ -1,7 +1,7 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ct/ct_sct.c b/crypto/openssl/crypto/ct/ct_sct.c index 4ff36e2fbd49..10a67ed6d68d 100644 --- a/crypto/openssl/crypto/ct/ct_sct.c +++ b/crypto/openssl/crypto/ct/ct_sct.c @@ -1,7 +1,7 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -24,7 +24,7 @@ SCT *SCT_new(void) SCT *sct = OPENSSL_zalloc(sizeof(*sct)); if (sct == NULL) { - CTerr(CT_F_SCT_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); return NULL; } @@ -53,7 +53,7 @@ void SCT_LIST_free(STACK_OF(SCT) *a) int SCT_set_version(SCT *sct, sct_version_t version) { if (version != SCT_VERSION_V1) { - CTerr(CT_F_SCT_SET_VERSION, CT_R_UNSUPPORTED_VERSION); + ERR_raise(ERR_LIB_CT, CT_R_UNSUPPORTED_VERSION); return 0; } sct->version = version; @@ -73,14 +73,14 @@ int SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type) case CT_LOG_ENTRY_TYPE_NOT_SET: break; } - CTerr(CT_F_SCT_SET_LOG_ENTRY_TYPE, CT_R_UNSUPPORTED_ENTRY_TYPE); + ERR_raise(ERR_LIB_CT, CT_R_UNSUPPORTED_ENTRY_TYPE); return 0; } int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len) { if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) { - CTerr(CT_F_SCT_SET0_LOG_ID, CT_R_INVALID_LOG_ID_LENGTH); + ERR_raise(ERR_LIB_CT, CT_R_INVALID_LOG_ID_LENGTH); return 0; } @@ -94,7 +94,7 @@ int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len) int SCT_set1_log_id(SCT *sct, const unsigned char *log_id, size_t log_id_len) { if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) { - CTerr(CT_F_SCT_SET1_LOG_ID, CT_R_INVALID_LOG_ID_LENGTH); + ERR_raise(ERR_LIB_CT, CT_R_INVALID_LOG_ID_LENGTH); return 0; } @@ -106,7 +106,7 @@ int SCT_set1_log_id(SCT *sct, const unsigned char *log_id, size_t log_id_len) if (log_id != NULL && log_id_len > 0) { sct->log_id = OPENSSL_memdup(log_id, log_id_len); if (sct->log_id == NULL) { - CTerr(CT_F_SCT_SET1_LOG_ID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); return 0; } sct->log_id_len = log_id_len; @@ -135,7 +135,7 @@ int SCT_set_signature_nid(SCT *sct, int nid) sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; return 1; default: - CTerr(CT_F_SCT_SET_SIGNATURE_NID, CT_R_UNRECOGNIZED_SIGNATURE_NID); + ERR_raise(ERR_LIB_CT, CT_R_UNRECOGNIZED_SIGNATURE_NID); return 0; } } @@ -158,7 +158,7 @@ int SCT_set1_extensions(SCT *sct, const unsigned char *ext, size_t ext_len) if (ext != NULL && ext_len > 0) { sct->ext = OPENSSL_memdup(ext, ext_len); if (sct->ext == NULL) { - CTerr(CT_F_SCT_SET1_EXTENSIONS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); return 0; } sct->ext_len = ext_len; @@ -184,7 +184,7 @@ int SCT_set1_signature(SCT *sct, const unsigned char *sig, size_t sig_len) if (sig != NULL && sig_len > 0) { sct->sig = OPENSSL_memdup(sig, sig_len); if (sct->sig == NULL) { - CTerr(CT_F_SCT_SET1_SIGNATURE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); return 0; } sct->sig_len = sig_len; @@ -312,7 +312,7 @@ int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx) return 0; } - sctx = SCT_CTX_new(); + sctx = SCT_CTX_new(ctx->libctx, ctx->propq); if (sctx == NULL) goto err; @@ -343,7 +343,7 @@ int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx) * XXX: Potential for optimization. This repeats some idempotent heavy * lifting on the certificate for each candidate SCT, and appears to not * use any information in the SCT itself, only the certificate is - * processed. So it may make more sense to to do this just once, perhaps + * processed. So it may make more sense to do this just once, perhaps * associated with the shared (by all SCTs) policy eval ctx. * * XXX: Failure here is global (SCT independent) and represents either an diff --git a/crypto/openssl/crypto/ct/ct_sct_ctx.c b/crypto/openssl/crypto/ct/ct_sct_ctx.c index 841e768033e5..8653684814ee 100644 --- a/crypto/openssl/crypto/ct/ct_sct_ctx.c +++ b/crypto/openssl/crypto/ct/ct_sct_ctx.c @@ -1,7 +1,7 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,12 +20,24 @@ #include "ct_local.h" -SCT_CTX *SCT_CTX_new(void) +SCT_CTX *SCT_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) { SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx)); - if (sctx == NULL) - CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE); + if (sctx == NULL) { + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + return NULL; + } + + sctx->libctx = libctx; + if (propq != NULL) { + sctx->propq = OPENSSL_strdup(propq); + if (sctx->propq == NULL) { + ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + OPENSSL_free(sctx); + return NULL; + } + } return sctx; } @@ -39,6 +51,7 @@ void SCT_CTX_free(SCT_CTX *sctx) OPENSSL_free(sctx->ihash); OPENSSL_free(sctx->certder); OPENSSL_free(sctx->preder); + OPENSSL_free(sctx->propq); OPENSSL_free(sctx); } @@ -155,15 +168,12 @@ int SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner) * SCT. */ if (idx >= 0) { - X509_EXTENSION *ext; - /* Take a copy of certificate so we don't modify passed version */ pretmp = X509_dup(cert); if (pretmp == NULL) goto err; - ext = X509_delete_ext(pretmp, idx); - X509_EXTENSION_free(ext); + X509_EXTENSION_free(X509_delete_ext(pretmp, idx)); if (!ct_x509_cert_fixup(pretmp, presigner)) goto err; @@ -191,13 +201,17 @@ int SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner) return 0; } -__owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash, - size_t *hash_len) +__owur static int ct_public_key_hash(SCT_CTX *sctx, X509_PUBKEY *pkey, + unsigned char **hash, size_t *hash_len) { int ret = 0; unsigned char *md = NULL, *der = NULL; int der_len; unsigned int md_len; + EVP_MD *sha256 = EVP_MD_fetch(sctx->libctx, "SHA2-256", sctx->propq); + + if (sha256 == NULL) + goto err; /* Reuse buffer if possible */ if (*hash != NULL && *hash_len >= SHA256_DIGEST_LENGTH) { @@ -213,7 +227,7 @@ __owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash, if (der_len <= 0) goto err; - if (!EVP_Digest(der, der_len, md, &md_len, EVP_sha256(), NULL)) + if (!EVP_Digest(der, der_len, md, &md_len, sha256, NULL)) goto err; if (md != *hash) { @@ -225,6 +239,7 @@ __owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash, md = NULL; ret = 1; err: + EVP_MD_free(sha256); OPENSSL_free(md); OPENSSL_free(der); return ret; @@ -237,7 +252,7 @@ int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer) int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey) { - return ct_public_key_hash(pubkey, &sctx->ihash, &sctx->ihashlen); + return ct_public_key_hash(sctx, pubkey, &sctx->ihash, &sctx->ihashlen); } int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey) @@ -247,7 +262,7 @@ int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey) if (pkey == NULL) return 0; - if (!ct_public_key_hash(pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) { + if (!ct_public_key_hash(sctx, pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) { EVP_PKEY_free(pkey); return 0; } diff --git a/crypto/openssl/crypto/ct/ct_vfy.c b/crypto/openssl/crypto/ct/ct_vfy.c index 74fd34f4154e..27fb79f40383 100644 --- a/crypto/openssl/crypto/ct/ct_vfy.c +++ b/crypto/openssl/crypto/ct/ct_vfy.c @@ -1,7 +1,7 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -101,20 +101,20 @@ int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct) if (!SCT_is_complete(sct) || sctx->pkey == NULL || sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET || (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)) { - CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_NOT_SET); + ERR_raise(ERR_LIB_CT, CT_R_SCT_NOT_SET); return 0; } if (sct->version != SCT_VERSION_V1) { - CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_UNSUPPORTED_VERSION); + ERR_raise(ERR_LIB_CT, CT_R_SCT_UNSUPPORTED_VERSION); return 0; } if (sct->log_id_len != sctx->pkeyhashlen || memcmp(sct->log_id, sctx->pkeyhash, sctx->pkeyhashlen) != 0) { - CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_LOG_ID_MISMATCH); + ERR_raise(ERR_LIB_CT, CT_R_SCT_LOG_ID_MISMATCH); return 0; } if (sct->timestamp > sctx->epoch_time_in_ms) { - CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_FUTURE_TIMESTAMP); + ERR_raise(ERR_LIB_CT, CT_R_SCT_FUTURE_TIMESTAMP); return 0; } @@ -122,7 +122,8 @@ int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct) if (ctx == NULL) goto end; - if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey)) + if (!EVP_DigestVerifyInit_ex(ctx, NULL, "SHA2-256", sctx->libctx, + sctx->propq, sctx->pkey, NULL)) goto end; if (!sct_ctx_update(ctx, sctx, sct)) @@ -132,7 +133,7 @@ int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct) ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len); /* If ret < 0 some other error: fall through without setting error */ if (ret == 0) - CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_INVALID_SIGNATURE); + ERR_raise(ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE); end: EVP_MD_CTX_free(ctx); diff --git a/crypto/openssl/crypto/ct/ct_x509v3.c b/crypto/openssl/crypto/ct/ct_x509v3.c index 19c2a852d24a..1284ec711db9 100644 --- a/crypto/openssl/crypto/ct/ct_x509v3.c +++ b/crypto/openssl/crypto/ct/ct_x509v3.c @@ -1,7 +1,7 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -75,7 +75,7 @@ static STACK_OF(SCT) *ocsp_ext_d2i_SCT_LIST(STACK_OF(SCT) **a, } /* Handlers for X509v3/OCSP Certificate Transparency extensions */ -const X509V3_EXT_METHOD v3_ct_scts[3] = { +const X509V3_EXT_METHOD ossl_v3_ct_scts[3] = { /* X509v3 extension in certificates that contains SCTs */ { NID_ct_precert_scts, 0, NULL, NULL, (X509V3_EXT_FREE)SCT_LIST_free, diff --git a/crypto/openssl/crypto/ctype.c b/crypto/openssl/crypto/ctype.c index b7f1183f9ccf..de2e836ff783 100644 --- a/crypto/openssl/crypto/ctype.c +++ b/crypto/openssl/crypto/ctype.c @@ -1,7 +1,7 @@ /* - * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,7 +10,7 @@ #include #include #include "crypto/ctype.h" -#include "openssl/ebcdic.h" +#include /* * Define the character classes for each character in the seven bit ASCII @@ -257,6 +257,36 @@ int ossl_ctype_check(int c, unsigned int mask) return a >= 0 && a < max && (ctype_char_map[a] & mask) != 0; } +/* + * Implement some of the simplier functions directly to avoid the overhead of + * accessing memory via ctype_char_map[]. + */ + +#define ASCII_IS_DIGIT(c) (c >= 0x30 && c <= 0x39) +#define ASCII_IS_UPPER(c) (c >= 0x41 && c <= 0x5A) +#define ASCII_IS_LOWER(c) (c >= 0x61 && c <= 0x7A) + +int ossl_isdigit(int c) +{ + int a = ossl_toascii(c); + + return ASCII_IS_DIGIT(a); +} + +int ossl_isupper(int c) +{ + int a = ossl_toascii(c); + + return ASCII_IS_UPPER(a); +} + +int ossl_islower(int c) +{ + int a = ossl_toascii(c); + + return ASCII_IS_LOWER(a); +} + #if defined(CHARSET_EBCDIC) && !defined(CHARSET_EBCDIC_TEST) static const int case_change = 0x40; #else @@ -265,16 +295,19 @@ static const int case_change = 0x20; int ossl_tolower(int c) { - return ossl_isupper(c) ? c ^ case_change : c; + int a = ossl_toascii(c); + + return ASCII_IS_UPPER(a) ? c ^ case_change : c; } int ossl_toupper(int c) { - return ossl_islower(c) ? c ^ case_change : c; + int a = ossl_toascii(c); + + return ASCII_IS_LOWER(a) ? c ^ case_change : c; } -int ascii_isdigit(const char inchar) { - if (inchar > 0x2F && inchar < 0x3A) - return 1; - return 0; +int ossl_ascii_isdigit(int c) +{ + return ASCII_IS_DIGIT(c); } diff --git a/crypto/openssl/crypto/cversion.c b/crypto/openssl/crypto/cversion.c index 534e7eba55b3..530b0e805e8d 100644 --- a/crypto/openssl/crypto/cversion.c +++ b/crypto/openssl/crypto/cversion.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -16,11 +16,42 @@ unsigned long OpenSSL_version_num(void) return OPENSSL_VERSION_NUMBER; } +unsigned int OPENSSL_version_major(void) +{ + return OPENSSL_VERSION_MAJOR; +} + +unsigned int OPENSSL_version_minor(void) +{ + return OPENSSL_VERSION_MINOR; +} + +unsigned int OPENSSL_version_patch(void) +{ + return OPENSSL_VERSION_PATCH; +} + +const char *OPENSSL_version_pre_release(void) +{ + return OPENSSL_VERSION_PRE_RELEASE; +} + +const char *OPENSSL_version_build_metadata(void) +{ + return OPENSSL_VERSION_BUILD_METADATA; +} + +extern char ossl_cpu_info_str[]; + const char *OpenSSL_version(int t) { switch (t) { case OPENSSL_VERSION: return OPENSSL_VERSION_TEXT; + case OPENSSL_VERSION_STRING: + return OPENSSL_VERSION_STR; + case OPENSSL_FULL_VERSION_STRING: + return OPENSSL_FULL_VERSION_STR; case OPENSSL_BUILT_ON: return DATE; case OPENSSL_CFLAGS: @@ -39,6 +70,17 @@ const char *OpenSSL_version(int t) #else return "ENGINESDIR: N/A"; #endif + case OPENSSL_MODULES_DIR: +#ifdef MODULESDIR + return "MODULESDIR: \"" MODULESDIR "\""; +#else + return "MODULESDIR: N/A"; +#endif + case OPENSSL_CPU_INFO: + if (OPENSSL_info(OPENSSL_INFO_CPU_SETTINGS) != NULL) + return ossl_cpu_info_str; + else + return "CPUINFO: N/A"; } return "not available"; } diff --git a/crypto/openssl/crypto/der_writer.c b/crypto/openssl/crypto/der_writer.c new file mode 100644 index 000000000000..2ab7480a6749 --- /dev/null +++ b/crypto/openssl/crypto/der_writer.c @@ -0,0 +1,199 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/cryptlib.h" +#include "internal/der.h" +#include "crypto/bn.h" + +static int int_start_context(WPACKET *pkt, int tag) +{ + if (tag < 0) + return 1; + if (!ossl_assert(tag <= 30)) + return 0; + return WPACKET_start_sub_packet(pkt); +} + +static int int_end_context(WPACKET *pkt, int tag) +{ + /* + * If someone set the flag WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH on this + * sub-packet and this sub-packet has nothing written to it, the DER length + * will not be written, and the total written size will be unchanged before + * and after WPACKET_close(). We use size1 and size2 to determine if + * anything was written, and only write our tag if it has. + * + */ + size_t size1, size2; + + if (tag < 0) + return 1; + if (!ossl_assert(tag <= 30)) + return 0; + + /* Context specific are normally (?) constructed */ + tag |= DER_F_CONSTRUCTED | DER_C_CONTEXT; + + return WPACKET_get_total_written(pkt, &size1) + && WPACKET_close(pkt) + && WPACKET_get_total_written(pkt, &size2) + && (size1 == size2 || WPACKET_put_bytes_u8(pkt, tag)); +} + +int ossl_DER_w_precompiled(WPACKET *pkt, int tag, + const unsigned char *precompiled, + size_t precompiled_n) +{ + return int_start_context(pkt, tag) + && WPACKET_memcpy(pkt, precompiled, precompiled_n) + && int_end_context(pkt, tag); +} + +int ossl_DER_w_boolean(WPACKET *pkt, int tag, int b) +{ + return int_start_context(pkt, tag) + && WPACKET_start_sub_packet(pkt) + && (!b || WPACKET_put_bytes_u8(pkt, 0xFF)) + && !WPACKET_close(pkt) + && !WPACKET_put_bytes_u8(pkt, DER_P_BOOLEAN) + && int_end_context(pkt, tag); +} + +int ossl_DER_w_octet_string(WPACKET *pkt, int tag, + const unsigned char *data, size_t data_n) +{ + return int_start_context(pkt, tag) + && WPACKET_start_sub_packet(pkt) + && WPACKET_memcpy(pkt, data, data_n) + && WPACKET_close(pkt) + && WPACKET_put_bytes_u8(pkt, DER_P_OCTET_STRING) + && int_end_context(pkt, tag); +} + +int ossl_DER_w_octet_string_uint32(WPACKET *pkt, int tag, uint32_t value) +{ + unsigned char tmp[4] = { 0, 0, 0, 0 }; + unsigned char *pbuf = tmp + (sizeof(tmp) - 1); + + while (value > 0) { + *pbuf-- = (value & 0xFF); + value >>= 8; + } + return ossl_DER_w_octet_string(pkt, tag, tmp, sizeof(tmp)); +} + +static int int_der_w_integer(WPACKET *pkt, int tag, + int (*put_bytes)(WPACKET *pkt, const void *v, + unsigned int *top_byte), + const void *v) +{ + unsigned int top_byte = 0; + + return int_start_context(pkt, tag) + && WPACKET_start_sub_packet(pkt) + && put_bytes(pkt, v, &top_byte) + && ((top_byte & 0x80) == 0 || WPACKET_put_bytes_u8(pkt, 0)) + && WPACKET_close(pkt) + && WPACKET_put_bytes_u8(pkt, DER_P_INTEGER) + && int_end_context(pkt, tag); +} + +static int int_put_bytes_uint32(WPACKET *pkt, const void *v, + unsigned int *top_byte) +{ + const uint32_t *value = v; + uint32_t tmp = *value; + size_t n = 0; + + while (tmp != 0) { + n++; + *top_byte = (tmp & 0xFF); + tmp >>= 8; + } + if (n == 0) + n = 1; + + return WPACKET_put_bytes__(pkt, *value, n); +} + +/* For integers, we only support unsigned values for now */ +int ossl_DER_w_uint32(WPACKET *pkt, int tag, uint32_t v) +{ + return int_der_w_integer(pkt, tag, int_put_bytes_uint32, &v); +} + +static int int_put_bytes_bn(WPACKET *pkt, const void *v, + unsigned int *top_byte) +{ + unsigned char *p = NULL; + size_t n = BN_num_bytes(v); + + /* The BIGNUM limbs are in LE order */ + *top_byte = + ((bn_get_words(v) [(n - 1) / BN_BYTES]) >> (8 * ((n - 1) % BN_BYTES))) + & 0xFF; + + if (!WPACKET_allocate_bytes(pkt, n, &p)) + return 0; + if (p != NULL) + BN_bn2bin(v, p); + return 1; +} + +int ossl_DER_w_bn(WPACKET *pkt, int tag, const BIGNUM *v) +{ + if (v == NULL || BN_is_negative(v)) + return 0; + if (BN_is_zero(v)) + return ossl_DER_w_uint32(pkt, tag, 0); + + return int_der_w_integer(pkt, tag, int_put_bytes_bn, v); +} + +int ossl_DER_w_null(WPACKET *pkt, int tag) +{ + return int_start_context(pkt, tag) + && WPACKET_start_sub_packet(pkt) + && WPACKET_close(pkt) + && WPACKET_put_bytes_u8(pkt, DER_P_NULL) + && int_end_context(pkt, tag); +} + +/* Constructed things need a start and an end */ +int ossl_DER_w_begin_sequence(WPACKET *pkt, int tag) +{ + return int_start_context(pkt, tag) + && WPACKET_start_sub_packet(pkt); +} + +int ossl_DER_w_end_sequence(WPACKET *pkt, int tag) +{ + /* + * If someone set the flag WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH on this + * sub-packet and this sub-packet has nothing written to it, the DER length + * will not be written, and the total written size will be unchanged before + * and after WPACKET_close(). We use size1 and size2 to determine if + * anything was written, and only write our tag if it has. + * + * Because we know that int_end_context() needs to do the same check, + * we reproduce this flag if the written length was unchanged, or we will + * have an erroneous context tag. + */ + size_t size1, size2; + + return WPACKET_get_total_written(pkt, &size1) + && WPACKET_close(pkt) + && WPACKET_get_total_written(pkt, &size2) + && (size1 == size2 + ? WPACKET_set_flags(pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) + : WPACKET_put_bytes_u8(pkt, DER_F_CONSTRUCTED | DER_P_SEQUENCE)) + && int_end_context(pkt, tag); +} diff --git a/crypto/openssl/crypto/des/asm/crypt586.pl b/crypto/openssl/crypto/des/asm/crypt586.pl index d14b9f89b6b6..e175b4f5515b 100755 --- a/crypto/openssl/crypto/des/asm/crypt586.pl +++ b/crypto/openssl/crypto/des/asm/crypt586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -13,8 +13,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/openssl/crypto/des/asm/des-586.pl b/crypto/openssl/crypto/des/asm/des-586.pl index 07d9d87ac735..fe51a227ca57 100755 --- a/crypto/openssl/crypto/des/asm/des-586.pl +++ b/crypto/openssl/crypto/des/asm/des-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -20,8 +20,7 @@ require "desboth.pl"; # format. # -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/openssl/crypto/des/asm/des_enc.m4 b/crypto/openssl/crypto/des/asm/des_enc.m4 index ebb5e7cd1d75..c00ac6184d13 100644 --- a/crypto/openssl/crypto/des/asm/des_enc.m4 +++ b/crypto/openssl/crypto/des/asm/des_enc.m4 @@ -1,6 +1,6 @@ -! Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. +! Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. ! -! Licensed under the OpenSSL license (the "License"). You may not use +! 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 @@ -29,8 +29,6 @@ .ident "des_enc.m4 2.1" .file "des_enc-sparc.S" -#include - #if defined(__SUNPRO_C) && defined(__sparcv9) # define ABI64 /* They've said -xarch=v9 at command line */ #elif defined(__GNUC__) && defined(__arch64__) diff --git a/crypto/openssl/crypto/des/asm/desboth.pl b/crypto/openssl/crypto/des/asm/desboth.pl index ef7054e27506..afffd20d84cd 100755 --- a/crypto/openssl/crypto/des/asm/desboth.pl +++ b/crypto/openssl/crypto/des/asm/desboth.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 diff --git a/crypto/openssl/crypto/des/asm/dest4-sparcv9.pl b/crypto/openssl/crypto/des/asm/dest4-sparcv9.pl index 5c92a52b7957..afa15860f0a0 100755 --- a/crypto/openssl/crypto/des/asm/dest4-sparcv9.pl +++ b/crypto/openssl/crypto/des/asm/dest4-sparcv9.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2013-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -34,11 +34,13 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "sparcv9_modes.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #ifdef __arch64__ .register %g2,#scratch diff --git a/crypto/openssl/crypto/des/build.info b/crypto/openssl/crypto/des/build.info index 05cb154cd462..5a13e4f9bebc 100644 --- a/crypto/openssl/crypto/des/build.info +++ b/crypto/openssl/crypto/des/build.info @@ -1,19 +1,47 @@ +$DESASM=des_enc.c fcrypt_b.c +IF[{- !$disabled{asm} -}] + $DESASM_x86=des-586.S crypt586.S + $DESASM_sparcv9=des_enc-sparc.S fcrypt_b.c dest4-sparcv9.S + $DESASM_sparcv8=des_enc-sparc.S fcrypt_b.c + + # Now that we have defined all the arch specific variables, use the + # appropriate one + IF[$DESASM_{- $target{asm_arch} -}] + $DESASM=$DESASM_{- $target{asm_arch} -} + $DESDEF=DES_ASM + ENDIF +ENDIF + LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - set_key.c ecb_enc.c cbc_enc.c \ - ecb3_enc.c cfb64enc.c cfb64ede.c cfb_enc.c \ - ofb64ede.c ofb64enc.c ofb_enc.c \ - str2key.c pcbc_enc.c qud_cksm.c rand_key.c \ - {- $target{des_asm_src} -} \ - fcrypt.c xcbc_enc.c cbc_cksm.c +$COMMON=set_key.c ecb3_enc.c +$ALL=$COMMON\ + ecb_enc.c cbc_enc.c \ + cfb64enc.c cfb64ede.c cfb_enc.c \ + ofb64ede.c ofb64enc.c ofb_enc.c \ + str2key.c pcbc_enc.c qud_cksm.c rand_key.c \ + fcrypt.c xcbc_enc.c cbc_cksm.c + +SOURCE[../../libcrypto]=$ALL $DESASM +SOURCE[../../providers/libfips.a]=$COMMON $DESASM +IF[{- !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=$DESASM +ENDIF + +DEFINE[../../libcrypto]=$DESDEF +DEFINE[../../providers/libfips.a]=$DESDEF + +# When all deprecated symbols are removed, libcrypto doesn't export the +# DES functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{des} -}] + SOURCE[../../providers/liblegacy.a]=$ALL + DEFINE[../../providers/liblegacy.a]=$DESDEF +ENDIF GENERATE[des_enc-sparc.S]=asm/des_enc.m4 -GENERATE[dest4-sparcv9.S]=asm/dest4-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[dest4-sparcv9.S]=asm/dest4-sparcv9.pl INCLUDE[dest4-sparcv9.o]=.. -GENERATE[des-586.s]=asm/des-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) -DEPEND[des-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl -GENERATE[crypt586.s]=asm/crypt586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) -DEPEND[crypt586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl +GENERATE[des-586.S]=asm/des-586.pl +DEPEND[des-586.S]=../perlasm/x86asm.pl ../perlasm/cbc.pl +GENERATE[crypt586.S]=asm/crypt586.pl +DEPEND[crypt586.S]=../perlasm/x86asm.pl ../perlasm/cbc.pl diff --git a/crypto/openssl/crypto/des/cbc_cksm.c b/crypto/openssl/crypto/des/cbc_cksm.c index c5e2e017b84e..d8ab38bf2377 100644 --- a/crypto/openssl/crypto/des/cbc_cksm.c +++ b/crypto/openssl/crypto/des/cbc_cksm.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "des_local.h" DES_LONG DES_cbc_cksum(const unsigned char *in, DES_cblock *output, diff --git a/crypto/openssl/crypto/des/cbc_enc.c b/crypto/openssl/crypto/des/cbc_enc.c index 92e773f81f4a..aa8ac1a5c339 100644 --- a/crypto/openssl/crypto/des/cbc_enc.c +++ b/crypto/openssl/crypto/des/cbc_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #define CBC_ENC_C__DONT_UPDATE_IV #include "ncbc_enc.c" /* des_cbc_encrypt */ diff --git a/crypto/openssl/crypto/des/cfb64ede.c b/crypto/openssl/crypto/des/cfb64ede.c index 490d925f46f4..c8e4e5cd2d93 100644 --- a/crypto/openssl/crypto/des/cfb64ede.c +++ b/crypto/openssl/crypto/des/cfb64ede.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "des_local.h" /* diff --git a/crypto/openssl/crypto/des/cfb64enc.c b/crypto/openssl/crypto/des/cfb64enc.c index ca0e82164803..93ebf76825c9 100644 --- a/crypto/openssl/crypto/des/cfb64enc.c +++ b/crypto/openssl/crypto/des/cfb64enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "des_local.h" /* diff --git a/crypto/openssl/crypto/des/cfb_enc.c b/crypto/openssl/crypto/des/cfb_enc.c index 17018420e6cc..30458d50a12a 100644 --- a/crypto/openssl/crypto/des/cfb_enc.c +++ b/crypto/openssl/crypto/des/cfb_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "e_os.h" #include "des_local.h" #include diff --git a/crypto/openssl/crypto/des/crypt586.S b/crypto/openssl/crypto/des/crypt586.S new file mode 100644 index 000000000000..29ba0fa70a8e --- /dev/null +++ b/crypto/openssl/crypto/des/crypt586.S @@ -0,0 +1,900 @@ +.text +.globl fcrypt_body +.type fcrypt_body,@function +.align 16 +fcrypt_body: +.L_fcrypt_body_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + + xorl %edi,%edi + xorl %esi,%esi + call .L000PIC_me_up +.L000PIC_me_up: + popl %edx + leal _GLOBAL_OFFSET_TABLE_+[.-.L000PIC_me_up](%edx),%edx + movl DES_SPtrans@GOT(%edx),%edx + pushl %edx + movl 28(%esp),%ebp + pushl $25 +.L001start: + + + movl 36(%esp),%eax + movl %esi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %esi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl (%ebp),%ebx + xorl %ebx,%eax + movl 4(%ebp),%ecx + xorl %esi,%eax + xorl %esi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%edi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%edi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%edi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%edi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %edi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %edi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 8(%ebp),%ebx + xorl %ebx,%eax + movl 12(%ebp),%ecx + xorl %edi,%eax + xorl %edi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%esi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%esi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%esi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%esi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %esi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %esi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 16(%ebp),%ebx + xorl %ebx,%eax + movl 20(%ebp),%ecx + xorl %esi,%eax + xorl %esi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%edi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%edi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%edi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%edi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %edi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %edi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 24(%ebp),%ebx + xorl %ebx,%eax + movl 28(%ebp),%ecx + xorl %edi,%eax + xorl %edi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%esi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%esi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%esi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%esi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %esi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %esi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 32(%ebp),%ebx + xorl %ebx,%eax + movl 36(%ebp),%ecx + xorl %esi,%eax + xorl %esi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%edi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%edi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%edi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%edi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %edi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %edi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 40(%ebp),%ebx + xorl %ebx,%eax + movl 44(%ebp),%ecx + xorl %edi,%eax + xorl %edi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%esi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%esi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%esi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%esi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %esi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %esi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 48(%ebp),%ebx + xorl %ebx,%eax + movl 52(%ebp),%ecx + xorl %esi,%eax + xorl %esi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%edi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%edi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%edi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%edi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %edi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %edi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 56(%ebp),%ebx + xorl %ebx,%eax + movl 60(%ebp),%ecx + xorl %edi,%eax + xorl %edi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%esi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%esi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%esi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%esi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %esi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %esi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 64(%ebp),%ebx + xorl %ebx,%eax + movl 68(%ebp),%ecx + xorl %esi,%eax + xorl %esi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%edi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%edi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%edi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%edi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %edi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %edi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 72(%ebp),%ebx + xorl %ebx,%eax + movl 76(%ebp),%ecx + xorl %edi,%eax + xorl %edi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%esi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%esi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%esi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%esi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %esi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %esi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 80(%ebp),%ebx + xorl %ebx,%eax + movl 84(%ebp),%ecx + xorl %esi,%eax + xorl %esi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%edi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%edi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%edi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%edi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %edi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %edi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 88(%ebp),%ebx + xorl %ebx,%eax + movl 92(%ebp),%ecx + xorl %edi,%eax + xorl %edi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%esi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%esi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%esi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%esi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %esi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %esi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 96(%ebp),%ebx + xorl %ebx,%eax + movl 100(%ebp),%ecx + xorl %esi,%eax + xorl %esi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%edi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%edi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%edi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%edi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %edi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %edi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 104(%ebp),%ebx + xorl %ebx,%eax + movl 108(%ebp),%ecx + xorl %edi,%eax + xorl %edi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%esi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%esi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%esi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%esi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %esi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %esi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 112(%ebp),%ebx + xorl %ebx,%eax + movl 116(%ebp),%ecx + xorl %esi,%eax + xorl %esi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%edi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%edi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%edi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%edi + movl 32(%esp),%ebp + + + movl 36(%esp),%eax + movl %edi,%edx + shrl $16,%edx + movl 40(%esp),%ecx + xorl %edi,%edx + andl %edx,%eax + andl %ecx,%edx + movl %eax,%ebx + shll $16,%ebx + movl %edx,%ecx + shll $16,%ecx + xorl %ebx,%eax + xorl %ecx,%edx + movl 120(%ebp),%ebx + xorl %ebx,%eax + movl 124(%ebp),%ecx + xorl %edi,%eax + xorl %edi,%edx + xorl %ecx,%edx + andl $0xfcfcfcfc,%eax + xorl %ebx,%ebx + andl $0xcfcfcfcf,%edx + xorl %ecx,%ecx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + movl 4(%esp),%ebp + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + movl 0x600(%ebp,%ebx,1),%ebx + xorl %ebx,%esi + movl 0x700(%ebp,%ecx,1),%ebx + xorl %ebx,%esi + movl 0x400(%ebp,%eax,1),%ebx + xorl %ebx,%esi + movl 0x500(%ebp,%edx,1),%ebx + xorl %ebx,%esi + movl 32(%esp),%ebp + movl (%esp),%ebx + movl %edi,%eax + decl %ebx + movl %esi,%edi + movl %eax,%esi + movl %ebx,(%esp) + jnz .L001start + + + movl 28(%esp),%edx + rorl $1,%edi + movl %esi,%eax + xorl %edi,%esi + andl $0xaaaaaaaa,%esi + xorl %esi,%eax + xorl %esi,%edi + + roll $23,%eax + movl %eax,%esi + xorl %edi,%eax + andl $0x03fc03fc,%eax + xorl %eax,%esi + xorl %eax,%edi + + roll $10,%esi + movl %esi,%eax + xorl %edi,%esi + andl $0x33333333,%esi + xorl %esi,%eax + xorl %esi,%edi + + roll $18,%edi + movl %edi,%esi + xorl %eax,%edi + andl $0xfff0000f,%edi + xorl %edi,%esi + xorl %edi,%eax + + roll $12,%esi + movl %esi,%edi + xorl %eax,%esi + andl $0xf0f0f0f0,%esi + xorl %esi,%edi + xorl %esi,%eax + + rorl $4,%eax + movl %eax,(%edx) + movl %edi,4(%edx) + addl $8,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size fcrypt_body,.-.L_fcrypt_body_begin + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/des/des-586.S b/crypto/openssl/crypto/des/des-586.S new file mode 100644 index 000000000000..b3839fa8875d --- /dev/null +++ b/crypto/openssl/crypto/des/des-586.S @@ -0,0 +1,1964 @@ +.text +.globl DES_SPtrans +.type _x86_DES_encrypt,@function +.align 16 +_x86_DES_encrypt: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ecx + + movl (%ecx),%eax + xorl %ebx,%ebx + movl 4(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 8(%ecx),%eax + xorl %ebx,%ebx + movl 12(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 16(%ecx),%eax + xorl %ebx,%ebx + movl 20(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 24(%ecx),%eax + xorl %ebx,%ebx + movl 28(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 32(%ecx),%eax + xorl %ebx,%ebx + movl 36(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 40(%ecx),%eax + xorl %ebx,%ebx + movl 44(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 48(%ecx),%eax + xorl %ebx,%ebx + movl 52(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 56(%ecx),%eax + xorl %ebx,%ebx + movl 60(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 64(%ecx),%eax + xorl %ebx,%ebx + movl 68(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 72(%ecx),%eax + xorl %ebx,%ebx + movl 76(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 80(%ecx),%eax + xorl %ebx,%ebx + movl 84(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 88(%ecx),%eax + xorl %ebx,%ebx + movl 92(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 96(%ecx),%eax + xorl %ebx,%ebx + movl 100(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 104(%ecx),%eax + xorl %ebx,%ebx + movl 108(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 112(%ecx),%eax + xorl %ebx,%ebx + movl 116(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 120(%ecx),%eax + xorl %ebx,%ebx + movl 124(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + addl $4,%esp + ret +.size _x86_DES_encrypt,.-_x86_DES_encrypt +.type _x86_DES_decrypt,@function +.align 16 +_x86_DES_decrypt: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ecx + + movl 120(%ecx),%eax + xorl %ebx,%ebx + movl 124(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 112(%ecx),%eax + xorl %ebx,%ebx + movl 116(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 104(%ecx),%eax + xorl %ebx,%ebx + movl 108(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 96(%ecx),%eax + xorl %ebx,%ebx + movl 100(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 88(%ecx),%eax + xorl %ebx,%ebx + movl 92(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 80(%ecx),%eax + xorl %ebx,%ebx + movl 84(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 72(%ecx),%eax + xorl %ebx,%ebx + movl 76(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 64(%ecx),%eax + xorl %ebx,%ebx + movl 68(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 56(%ecx),%eax + xorl %ebx,%ebx + movl 60(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 48(%ecx),%eax + xorl %ebx,%ebx + movl 52(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 40(%ecx),%eax + xorl %ebx,%ebx + movl 44(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 32(%ecx),%eax + xorl %ebx,%ebx + movl 36(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 24(%ecx),%eax + xorl %ebx,%ebx + movl 28(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl 16(%ecx),%eax + xorl %ebx,%ebx + movl 20(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + + movl 8(%ecx),%eax + xorl %ebx,%ebx + movl 12(%ecx),%edx + xorl %esi,%eax + xorl %ecx,%ecx + xorl %esi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%edi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%edi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%edi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%edi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%edi + xorl 0x700(%ebp,%ecx,1),%edi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%edi + xorl 0x500(%ebp,%edx,1),%edi + + movl (%ecx),%eax + xorl %ebx,%ebx + movl 4(%ecx),%edx + xorl %edi,%eax + xorl %ecx,%ecx + xorl %edi,%edx + andl $0xfcfcfcfc,%eax + andl $0xcfcfcfcf,%edx + movb %al,%bl + movb %ah,%cl + rorl $4,%edx + xorl (%ebp,%ebx,1),%esi + movb %dl,%bl + xorl 0x200(%ebp,%ecx,1),%esi + movb %dh,%cl + shrl $16,%eax + xorl 0x100(%ebp,%ebx,1),%esi + movb %ah,%bl + shrl $16,%edx + xorl 0x300(%ebp,%ecx,1),%esi + movb %dh,%cl + andl $0xff,%eax + andl $0xff,%edx + xorl 0x600(%ebp,%ebx,1),%esi + xorl 0x700(%ebp,%ecx,1),%esi + movl (%esp),%ecx + xorl 0x400(%ebp,%eax,1),%esi + xorl 0x500(%ebp,%edx,1),%esi + addl $4,%esp + ret +.size _x86_DES_decrypt,.-_x86_DES_decrypt +.globl DES_encrypt1 +.type DES_encrypt1,@function +.align 16 +DES_encrypt1: +.L_DES_encrypt1_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %esi + pushl %edi + + + movl 12(%esp),%esi + xorl %ecx,%ecx + pushl %ebx + pushl %ebp + movl (%esi),%eax + movl 28(%esp),%ebx + movl 4(%esi),%edi + + + roll $4,%eax + movl %eax,%esi + xorl %edi,%eax + andl $0xf0f0f0f0,%eax + xorl %eax,%esi + xorl %eax,%edi + + roll $20,%edi + movl %edi,%eax + xorl %esi,%edi + andl $0xfff0000f,%edi + xorl %edi,%eax + xorl %edi,%esi + + roll $14,%eax + movl %eax,%edi + xorl %esi,%eax + andl $0x33333333,%eax + xorl %eax,%edi + xorl %eax,%esi + + roll $22,%esi + movl %esi,%eax + xorl %edi,%esi + andl $0x03fc03fc,%esi + xorl %esi,%eax + xorl %esi,%edi + + roll $9,%eax + movl %eax,%esi + xorl %edi,%eax + andl $0xaaaaaaaa,%eax + xorl %eax,%esi + xorl %eax,%edi + + roll $1,%edi + call .L000pic_point +.L000pic_point: + popl %ebp + leal .Ldes_sptrans-.L000pic_point(%ebp),%ebp + movl 24(%esp),%ecx + cmpl $0,%ebx + je .L001decrypt + call _x86_DES_encrypt + jmp .L002done +.L001decrypt: + call _x86_DES_decrypt +.L002done: + + + movl 20(%esp),%edx + rorl $1,%esi + movl %edi,%eax + xorl %esi,%edi + andl $0xaaaaaaaa,%edi + xorl %edi,%eax + xorl %edi,%esi + + roll $23,%eax + movl %eax,%edi + xorl %esi,%eax + andl $0x03fc03fc,%eax + xorl %eax,%edi + xorl %eax,%esi + + roll $10,%edi + movl %edi,%eax + xorl %esi,%edi + andl $0x33333333,%edi + xorl %edi,%eax + xorl %edi,%esi + + roll $18,%esi + movl %esi,%edi + xorl %eax,%esi + andl $0xfff0000f,%esi + xorl %esi,%edi + xorl %esi,%eax + + roll $12,%edi + movl %edi,%esi + xorl %eax,%edi + andl $0xf0f0f0f0,%edi + xorl %edi,%esi + xorl %edi,%eax + + rorl $4,%eax + movl %eax,(%edx) + movl %esi,4(%edx) + popl %ebp + popl %ebx + popl %edi + popl %esi + ret +.size DES_encrypt1,.-.L_DES_encrypt1_begin +.globl DES_encrypt2 +.type DES_encrypt2,@function +.align 16 +DES_encrypt2: +.L_DES_encrypt2_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %esi + pushl %edi + + + movl 12(%esp),%eax + xorl %ecx,%ecx + pushl %ebx + pushl %ebp + movl (%eax),%esi + movl 28(%esp),%ebx + roll $3,%esi + movl 4(%eax),%edi + roll $3,%edi + call .L003pic_point +.L003pic_point: + popl %ebp + leal .Ldes_sptrans-.L003pic_point(%ebp),%ebp + movl 24(%esp),%ecx + cmpl $0,%ebx + je .L004decrypt + call _x86_DES_encrypt + jmp .L005done +.L004decrypt: + call _x86_DES_decrypt +.L005done: + + + rorl $3,%edi + movl 20(%esp),%eax + rorl $3,%esi + movl %edi,(%eax) + movl %esi,4(%eax) + popl %ebp + popl %ebx + popl %edi + popl %esi + ret +.size DES_encrypt2,.-.L_DES_encrypt2_begin +.globl DES_encrypt3 +.type DES_encrypt3,@function +.align 16 +DES_encrypt3: +.L_DES_encrypt3_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebx + movl 8(%esp),%ebx + pushl %ebp + pushl %esi + pushl %edi + + + movl (%ebx),%edi + movl 4(%ebx),%esi + subl $12,%esp + + + roll $4,%edi + movl %edi,%edx + xorl %esi,%edi + andl $0xf0f0f0f0,%edi + xorl %edi,%edx + xorl %edi,%esi + + roll $20,%esi + movl %esi,%edi + xorl %edx,%esi + andl $0xfff0000f,%esi + xorl %esi,%edi + xorl %esi,%edx + + roll $14,%edi + movl %edi,%esi + xorl %edx,%edi + andl $0x33333333,%edi + xorl %edi,%esi + xorl %edi,%edx + + roll $22,%edx + movl %edx,%edi + xorl %esi,%edx + andl $0x03fc03fc,%edx + xorl %edx,%edi + xorl %edx,%esi + + roll $9,%edi + movl %edi,%edx + xorl %esi,%edi + andl $0xaaaaaaaa,%edi + xorl %edi,%edx + xorl %edi,%esi + + rorl $3,%edx + rorl $2,%esi + movl %esi,4(%ebx) + movl 36(%esp),%eax + movl %edx,(%ebx) + movl 40(%esp),%edi + movl 44(%esp),%esi + movl $1,8(%esp) + movl %eax,4(%esp) + movl %ebx,(%esp) + call .L_DES_encrypt2_begin + movl $0,8(%esp) + movl %edi,4(%esp) + movl %ebx,(%esp) + call .L_DES_encrypt2_begin + movl $1,8(%esp) + movl %esi,4(%esp) + movl %ebx,(%esp) + call .L_DES_encrypt2_begin + addl $12,%esp + movl (%ebx),%edi + movl 4(%ebx),%esi + + + roll $2,%esi + roll $3,%edi + movl %edi,%eax + xorl %esi,%edi + andl $0xaaaaaaaa,%edi + xorl %edi,%eax + xorl %edi,%esi + + roll $23,%eax + movl %eax,%edi + xorl %esi,%eax + andl $0x03fc03fc,%eax + xorl %eax,%edi + xorl %eax,%esi + + roll $10,%edi + movl %edi,%eax + xorl %esi,%edi + andl $0x33333333,%edi + xorl %edi,%eax + xorl %edi,%esi + + roll $18,%esi + movl %esi,%edi + xorl %eax,%esi + andl $0xfff0000f,%esi + xorl %esi,%edi + xorl %esi,%eax + + roll $12,%edi + movl %edi,%esi + xorl %eax,%edi + andl $0xf0f0f0f0,%edi + xorl %edi,%esi + xorl %edi,%eax + + rorl $4,%eax + movl %eax,(%ebx) + movl %esi,4(%ebx) + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +.size DES_encrypt3,.-.L_DES_encrypt3_begin +.globl DES_decrypt3 +.type DES_decrypt3,@function +.align 16 +DES_decrypt3: +.L_DES_decrypt3_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebx + movl 8(%esp),%ebx + pushl %ebp + pushl %esi + pushl %edi + + + movl (%ebx),%edi + movl 4(%ebx),%esi + subl $12,%esp + + + roll $4,%edi + movl %edi,%edx + xorl %esi,%edi + andl $0xf0f0f0f0,%edi + xorl %edi,%edx + xorl %edi,%esi + + roll $20,%esi + movl %esi,%edi + xorl %edx,%esi + andl $0xfff0000f,%esi + xorl %esi,%edi + xorl %esi,%edx + + roll $14,%edi + movl %edi,%esi + xorl %edx,%edi + andl $0x33333333,%edi + xorl %edi,%esi + xorl %edi,%edx + + roll $22,%edx + movl %edx,%edi + xorl %esi,%edx + andl $0x03fc03fc,%edx + xorl %edx,%edi + xorl %edx,%esi + + roll $9,%edi + movl %edi,%edx + xorl %esi,%edi + andl $0xaaaaaaaa,%edi + xorl %edi,%edx + xorl %edi,%esi + + rorl $3,%edx + rorl $2,%esi + movl %esi,4(%ebx) + movl 36(%esp),%esi + movl %edx,(%ebx) + movl 40(%esp),%edi + movl 44(%esp),%eax + movl $0,8(%esp) + movl %eax,4(%esp) + movl %ebx,(%esp) + call .L_DES_encrypt2_begin + movl $1,8(%esp) + movl %edi,4(%esp) + movl %ebx,(%esp) + call .L_DES_encrypt2_begin + movl $0,8(%esp) + movl %esi,4(%esp) + movl %ebx,(%esp) + call .L_DES_encrypt2_begin + addl $12,%esp + movl (%ebx),%edi + movl 4(%ebx),%esi + + + roll $2,%esi + roll $3,%edi + movl %edi,%eax + xorl %esi,%edi + andl $0xaaaaaaaa,%edi + xorl %edi,%eax + xorl %edi,%esi + + roll $23,%eax + movl %eax,%edi + xorl %esi,%eax + andl $0x03fc03fc,%eax + xorl %eax,%edi + xorl %eax,%esi + + roll $10,%edi + movl %edi,%eax + xorl %esi,%edi + andl $0x33333333,%edi + xorl %edi,%eax + xorl %edi,%esi + + roll $18,%esi + movl %esi,%edi + xorl %eax,%esi + andl $0xfff0000f,%esi + xorl %esi,%edi + xorl %esi,%eax + + roll $12,%edi + movl %edi,%esi + xorl %eax,%edi + andl $0xf0f0f0f0,%edi + xorl %edi,%esi + xorl %edi,%eax + + rorl $4,%eax + movl %eax,(%ebx) + movl %esi,4(%ebx) + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +.size DES_decrypt3,.-.L_DES_decrypt3_begin +.globl DES_ncbc_encrypt +.type DES_ncbc_encrypt,@function +.align 16 +DES_ncbc_encrypt: +.L_DES_ncbc_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 28(%esp),%ebp + + movl 36(%esp),%ebx + movl (%ebx),%esi + movl 4(%ebx),%edi + pushl %edi + pushl %esi + pushl %edi + pushl %esi + movl %esp,%ebx + movl 36(%esp),%esi + movl 40(%esp),%edi + + movl 56(%esp),%ecx + + pushl %ecx + + movl 52(%esp),%eax + pushl %eax + pushl %ebx + cmpl $0,%ecx + jz .L006decrypt + andl $4294967288,%ebp + movl 12(%esp),%eax + movl 16(%esp),%ebx + jz .L007encrypt_finish +.L008encrypt_loop: + movl (%esi),%ecx + movl 4(%esi),%edx + xorl %ecx,%eax + xorl %edx,%ebx + movl %eax,12(%esp) + movl %ebx,16(%esp) + call .L_DES_encrypt1_begin + movl 12(%esp),%eax + movl 16(%esp),%ebx + movl %eax,(%edi) + movl %ebx,4(%edi) + addl $8,%esi + addl $8,%edi + subl $8,%ebp + jnz .L008encrypt_loop +.L007encrypt_finish: + movl 56(%esp),%ebp + andl $7,%ebp + jz .L009finish + call .L010PIC_point +.L010PIC_point: + popl %edx + leal .L011cbc_enc_jmp_table-.L010PIC_point(%edx),%ecx + movl (%ecx,%ebp,4),%ebp + addl %edx,%ebp + xorl %ecx,%ecx + xorl %edx,%edx + jmp *%ebp +.L012ej7: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 6(%esi),%dh + shll $8,%edx +.L013ej6: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 5(%esi),%dh +.L014ej5: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 4(%esi),%dl +.L015ej4: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl (%esi),%ecx + jmp .L016ejend +.L017ej3: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 2(%esi),%ch + shll $8,%ecx +.L018ej2: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 1(%esi),%ch +.L019ej1: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb (%esi),%cl +.L016ejend: + xorl %ecx,%eax + xorl %edx,%ebx + movl %eax,12(%esp) + movl %ebx,16(%esp) + call .L_DES_encrypt1_begin + movl 12(%esp),%eax + movl 16(%esp),%ebx + movl %eax,(%edi) + movl %ebx,4(%edi) + jmp .L009finish +.L006decrypt: + andl $4294967288,%ebp + movl 20(%esp),%eax + movl 24(%esp),%ebx + jz .L020decrypt_finish +.L021decrypt_loop: + movl (%esi),%eax + movl 4(%esi),%ebx + movl %eax,12(%esp) + movl %ebx,16(%esp) + call .L_DES_encrypt1_begin + movl 12(%esp),%eax + movl 16(%esp),%ebx + movl 20(%esp),%ecx + movl 24(%esp),%edx + xorl %eax,%ecx + xorl %ebx,%edx + movl (%esi),%eax + movl 4(%esi),%ebx + movl %ecx,(%edi) + movl %edx,4(%edi) + movl %eax,20(%esp) + movl %ebx,24(%esp) + addl $8,%esi + addl $8,%edi + subl $8,%ebp + jnz .L021decrypt_loop +.L020decrypt_finish: + movl 56(%esp),%ebp + andl $7,%ebp + jz .L009finish + movl (%esi),%eax + movl 4(%esi),%ebx + movl %eax,12(%esp) + movl %ebx,16(%esp) + call .L_DES_encrypt1_begin + movl 12(%esp),%eax + movl 16(%esp),%ebx + movl 20(%esp),%ecx + movl 24(%esp),%edx + xorl %eax,%ecx + xorl %ebx,%edx + movl (%esi),%eax + movl 4(%esi),%ebx +.L022dj7: + rorl $16,%edx + movb %dl,6(%edi) + shrl $16,%edx +.L023dj6: + movb %dh,5(%edi) +.L024dj5: + movb %dl,4(%edi) +.L025dj4: + movl %ecx,(%edi) + jmp .L026djend +.L027dj3: + rorl $16,%ecx + movb %cl,2(%edi) + shll $16,%ecx +.L028dj2: + movb %ch,1(%esi) +.L029dj1: + movb %cl,(%esi) +.L026djend: + jmp .L009finish +.L009finish: + movl 64(%esp),%ecx + addl $28,%esp + movl %eax,(%ecx) + movl %ebx,4(%ecx) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 64 +.L011cbc_enc_jmp_table: +.long 0 +.long .L019ej1-.L010PIC_point +.long .L018ej2-.L010PIC_point +.long .L017ej3-.L010PIC_point +.long .L015ej4-.L010PIC_point +.long .L014ej5-.L010PIC_point +.long .L013ej6-.L010PIC_point +.long .L012ej7-.L010PIC_point +.align 64 +.size DES_ncbc_encrypt,.-.L_DES_ncbc_encrypt_begin +.globl DES_ede3_cbc_encrypt +.type DES_ede3_cbc_encrypt,@function +.align 16 +DES_ede3_cbc_encrypt: +.L_DES_ede3_cbc_encrypt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 28(%esp),%ebp + + movl 44(%esp),%ebx + movl (%ebx),%esi + movl 4(%ebx),%edi + pushl %edi + pushl %esi + pushl %edi + pushl %esi + movl %esp,%ebx + movl 36(%esp),%esi + movl 40(%esp),%edi + + movl 64(%esp),%ecx + + movl 56(%esp),%eax + pushl %eax + + movl 56(%esp),%eax + pushl %eax + + movl 56(%esp),%eax + pushl %eax + pushl %ebx + cmpl $0,%ecx + jz .L030decrypt + andl $4294967288,%ebp + movl 16(%esp),%eax + movl 20(%esp),%ebx + jz .L031encrypt_finish +.L032encrypt_loop: + movl (%esi),%ecx + movl 4(%esi),%edx + xorl %ecx,%eax + xorl %edx,%ebx + movl %eax,16(%esp) + movl %ebx,20(%esp) + call .L_DES_encrypt3_begin + movl 16(%esp),%eax + movl 20(%esp),%ebx + movl %eax,(%edi) + movl %ebx,4(%edi) + addl $8,%esi + addl $8,%edi + subl $8,%ebp + jnz .L032encrypt_loop +.L031encrypt_finish: + movl 60(%esp),%ebp + andl $7,%ebp + jz .L033finish + call .L034PIC_point +.L034PIC_point: + popl %edx + leal .L035cbc_enc_jmp_table-.L034PIC_point(%edx),%ecx + movl (%ecx,%ebp,4),%ebp + addl %edx,%ebp + xorl %ecx,%ecx + xorl %edx,%edx + jmp *%ebp +.L036ej7: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 6(%esi),%dh + shll $8,%edx +.L037ej6: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 5(%esi),%dh +.L038ej5: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 4(%esi),%dl +.L039ej4: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl (%esi),%ecx + jmp .L040ejend +.L041ej3: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 2(%esi),%ch + shll $8,%ecx +.L042ej2: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb 1(%esi),%ch +.L043ej1: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movb (%esi),%cl +.L040ejend: + xorl %ecx,%eax + xorl %edx,%ebx + movl %eax,16(%esp) + movl %ebx,20(%esp) + call .L_DES_encrypt3_begin + movl 16(%esp),%eax + movl 20(%esp),%ebx + movl %eax,(%edi) + movl %ebx,4(%edi) + jmp .L033finish +.L030decrypt: + andl $4294967288,%ebp + movl 24(%esp),%eax + movl 28(%esp),%ebx + jz .L044decrypt_finish +.L045decrypt_loop: + movl (%esi),%eax + movl 4(%esi),%ebx + movl %eax,16(%esp) + movl %ebx,20(%esp) + call .L_DES_decrypt3_begin + movl 16(%esp),%eax + movl 20(%esp),%ebx + movl 24(%esp),%ecx + movl 28(%esp),%edx + xorl %eax,%ecx + xorl %ebx,%edx + movl (%esi),%eax + movl 4(%esi),%ebx + movl %ecx,(%edi) + movl %edx,4(%edi) + movl %eax,24(%esp) + movl %ebx,28(%esp) + addl $8,%esi + addl $8,%edi + subl $8,%ebp + jnz .L045decrypt_loop +.L044decrypt_finish: + movl 60(%esp),%ebp + andl $7,%ebp + jz .L033finish + movl (%esi),%eax + movl 4(%esi),%ebx + movl %eax,16(%esp) + movl %ebx,20(%esp) + call .L_DES_decrypt3_begin + movl 16(%esp),%eax + movl 20(%esp),%ebx + movl 24(%esp),%ecx + movl 28(%esp),%edx + xorl %eax,%ecx + xorl %ebx,%edx + movl (%esi),%eax + movl 4(%esi),%ebx +.L046dj7: + rorl $16,%edx + movb %dl,6(%edi) + shrl $16,%edx +.L047dj6: + movb %dh,5(%edi) +.L048dj5: + movb %dl,4(%edi) +.L049dj4: + movl %ecx,(%edi) + jmp .L050djend +.L051dj3: + rorl $16,%ecx + movb %cl,2(%edi) + shll $16,%ecx +.L052dj2: + movb %ch,1(%esi) +.L053dj1: + movb %cl,(%esi) +.L050djend: + jmp .L033finish +.L033finish: + movl 76(%esp),%ecx + addl $32,%esp + movl %eax,(%ecx) + movl %ebx,4(%ecx) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 64 +.L035cbc_enc_jmp_table: +.long 0 +.long .L043ej1-.L034PIC_point +.long .L042ej2-.L034PIC_point +.long .L041ej3-.L034PIC_point +.long .L039ej4-.L034PIC_point +.long .L038ej5-.L034PIC_point +.long .L037ej6-.L034PIC_point +.long .L036ej7-.L034PIC_point +.align 64 +.size DES_ede3_cbc_encrypt,.-.L_DES_ede3_cbc_encrypt_begin +.align 64 +DES_SPtrans: +.Ldes_sptrans: +.long 34080768,524288,33554434,34080770 +.long 33554432,526338,524290,33554434 +.long 526338,34080768,34078720,2050 +.long 33556482,33554432,0,524290 +.long 524288,2,33556480,526336 +.long 34080770,34078720,2050,33556480 +.long 2,2048,526336,34078722 +.long 2048,33556482,34078722,0 +.long 0,34080770,33556480,524290 +.long 34080768,524288,2050,33556480 +.long 34078722,2048,526336,33554434 +.long 526338,2,33554434,34078720 +.long 34080770,526336,34078720,33556482 +.long 33554432,2050,524290,0 +.long 524288,33554432,33556482,34080768 +.long 2,34078722,2048,526338 +.long 1074823184,0,1081344,1074790400 +.long 1073741840,32784,1073774592,1081344 +.long 32768,1074790416,16,1073774592 +.long 1048592,1074823168,1074790400,16 +.long 1048576,1073774608,1074790416,32768 +.long 1081360,1073741824,0,1048592 +.long 1073774608,1081360,1074823168,1073741840 +.long 1073741824,1048576,32784,1074823184 +.long 1048592,1074823168,1073774592,1081360 +.long 1074823184,1048592,1073741840,0 +.long 1073741824,32784,1048576,1074790416 +.long 32768,1073741824,1081360,1073774608 +.long 1074823168,32768,0,1073741840 +.long 16,1074823184,1081344,1074790400 +.long 1074790416,1048576,32784,1073774592 +.long 1073774608,16,1074790400,1081344 +.long 67108865,67371264,256,67109121 +.long 262145,67108864,67109121,262400 +.long 67109120,262144,67371008,1 +.long 67371265,257,1,67371009 +.long 0,262145,67371264,256 +.long 257,67371265,262144,67108865 +.long 67371009,67109120,262401,67371008 +.long 262400,0,67108864,262401 +.long 67371264,256,1,262144 +.long 257,262145,67371008,67109121 +.long 0,67371264,262400,67371009 +.long 262145,67108864,67371265,1 +.long 262401,67108865,67108864,67371265 +.long 262144,67109120,67109121,262400 +.long 67109120,0,67371009,257 +.long 67108865,262401,256,67371008 +.long 4198408,268439552,8,272633864 +.long 0,272629760,268439560,4194312 +.long 272633856,268435464,268435456,4104 +.long 268435464,4198408,4194304,268435456 +.long 272629768,4198400,4096,8 +.long 4198400,268439560,272629760,4096 +.long 4104,0,4194312,272633856 +.long 268439552,272629768,272633864,4194304 +.long 272629768,4104,4194304,268435464 +.long 4198400,268439552,8,272629760 +.long 268439560,0,4096,4194312 +.long 0,272629768,272633856,4096 +.long 268435456,272633864,4198408,4194304 +.long 272633864,8,268439552,4198408 +.long 4194312,4198400,272629760,268439560 +.long 4104,268435456,268435464,272633856 +.long 134217728,65536,1024,134284320 +.long 134283296,134218752,66592,134283264 +.long 65536,32,134217760,66560 +.long 134218784,134283296,134284288,0 +.long 66560,134217728,65568,1056 +.long 134218752,66592,0,134217760 +.long 32,134218784,134284320,65568 +.long 134283264,1024,1056,134284288 +.long 134284288,134218784,65568,134283264 +.long 65536,32,134217760,134218752 +.long 134217728,66560,134284320,0 +.long 66592,134217728,1024,65568 +.long 134218784,1024,0,134284320 +.long 134283296,134284288,1056,65536 +.long 66560,134283296,134218752,1056 +.long 32,66592,134283264,134217760 +.long 2147483712,2097216,0,2149588992 +.long 2097216,8192,2147491904,2097152 +.long 8256,2149589056,2105344,2147483648 +.long 2147491840,2147483712,2149580800,2105408 +.long 2097152,2147491904,2149580864,0 +.long 8192,64,2149588992,2149580864 +.long 2149589056,2149580800,2147483648,8256 +.long 64,2105344,2105408,2147491840 +.long 8256,2147483648,2147491840,2105408 +.long 2149588992,2097216,0,2147491840 +.long 2147483648,8192,2149580864,2097152 +.long 2097216,2149589056,2105344,64 +.long 2149589056,2105344,2097152,2147491904 +.long 2147483712,2149580800,2105408,0 +.long 8192,2147483712,2147491904,2149588992 +.long 2149580800,8256,64,2149580864 +.long 16384,512,16777728,16777220 +.long 16794116,16388,16896,0 +.long 16777216,16777732,516,16793600 +.long 4,16794112,16793600,516 +.long 16777732,16384,16388,16794116 +.long 0,16777728,16777220,16896 +.long 16793604,16900,16794112,4 +.long 16900,16793604,512,16777216 +.long 16900,16793600,16793604,516 +.long 16384,512,16777216,16793604 +.long 16777732,16900,16896,0 +.long 512,16777220,4,16777728 +.long 0,16777732,16777728,16896 +.long 516,16384,16794116,16777216 +.long 16794112,4,16388,16794116 +.long 16777220,16794112,16793600,16388 +.long 545259648,545390592,131200,0 +.long 537001984,8388736,545259520,545390720 +.long 128,536870912,8519680,131200 +.long 8519808,537002112,536871040,545259520 +.long 131072,8519808,8388736,537001984 +.long 545390720,536871040,0,8519680 +.long 536870912,8388608,537002112,545259648 +.long 8388608,131072,545390592,128 +.long 8388608,131072,536871040,545390720 +.long 131200,536870912,0,8519680 +.long 545259648,537002112,537001984,8388736 +.long 545390592,128,8388736,537001984 +.long 545390720,8388608,545259520,536871040 +.long 8519680,131200,537002112,545259520 +.long 128,545390592,8519808,0 +.long 536870912,545259648,131072,8519808 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/des/des_enc.c b/crypto/openssl/crypto/des/des_enc.c index 45eec615d8b0..0041f21b8d3b 100644 --- a/crypto/openssl/crypto/des/des_enc.c +++ b/crypto/openssl/crypto/des/des_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "des_local.h" #include "spr.h" diff --git a/crypto/openssl/crypto/des/des_local.h b/crypto/openssl/crypto/des/des_local.h index 0f58a1c9ae2e..f888cb800169 100644 --- a/crypto/openssl/crypto/des/des_local.h +++ b/crypto/openssl/crypto/des/des_local.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/des/ecb3_enc.c b/crypto/openssl/crypto/des/ecb3_enc.c index 7afa8eaadde7..48e524dc3666 100644 --- a/crypto/openssl/crypto/des/ecb3_enc.c +++ b/crypto/openssl/crypto/des/ecb3_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "des_local.h" void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, diff --git a/crypto/openssl/crypto/des/ecb_enc.c b/crypto/openssl/crypto/des/ecb_enc.c index 513c65e116cd..c230a3737ce8 100644 --- a/crypto/openssl/crypto/des/ecb_enc.c +++ b/crypto/openssl/crypto/des/ecb_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "des_local.h" #include #include diff --git a/crypto/openssl/crypto/des/fcrypt.c b/crypto/openssl/crypto/des/fcrypt.c index e83cf76b615c..c3827a61c9bd 100644 --- a/crypto/openssl/crypto/des/fcrypt.c +++ b/crypto/openssl/crypto/des/fcrypt.c @@ -1,12 +1,18 @@ /* - * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + /* NOCW */ #include #ifdef _OSD_POSIX @@ -25,7 +31,7 @@ * Added more values to handle illegal salt values the way normal crypt() * implementations do. */ -static unsigned const char con_salt[128] = { +static const unsigned char con_salt[128] = { 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, @@ -44,7 +50,7 @@ static unsigned const char con_salt[128] = { 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, }; -static unsigned const char cov_2char[64] = { +static const unsigned char cov_2char[64] = { 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, diff --git a/crypto/openssl/crypto/des/fcrypt_b.c b/crypto/openssl/crypto/des/fcrypt_b.c index 22f967b8c6d3..e843e0e64397 100644 --- a/crypto/openssl/crypto/des/fcrypt_b.c +++ b/crypto/openssl/crypto/des/fcrypt_b.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #define DES_FCRYPT diff --git a/crypto/openssl/crypto/des/ncbc_enc.c b/crypto/openssl/crypto/des/ncbc_enc.c index cd4b071a3d73..e8decf1fbee0 100644 --- a/crypto/openssl/crypto/des/ncbc_enc.c +++ b/crypto/openssl/crypto/des/ncbc_enc.c @@ -1,7 +1,7 @@ /* * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/des/ofb64ede.c b/crypto/openssl/crypto/des/ofb64ede.c index 68cf2dc557c6..edcfac853011 100644 --- a/crypto/openssl/crypto/des/ofb64ede.c +++ b/crypto/openssl/crypto/des/ofb64ede.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "des_local.h" /* diff --git a/crypto/openssl/crypto/des/ofb64enc.c b/crypto/openssl/crypto/des/ofb64enc.c index 5796980c1865..73d4e21d2f9b 100644 --- a/crypto/openssl/crypto/des/ofb64enc.c +++ b/crypto/openssl/crypto/des/ofb64enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "des_local.h" /* diff --git a/crypto/openssl/crypto/des/ofb_enc.c b/crypto/openssl/crypto/des/ofb_enc.c index 2b0498994b51..50c7f4c43213 100644 --- a/crypto/openssl/crypto/des/ofb_enc.c +++ b/crypto/openssl/crypto/des/ofb_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "des_local.h" /* diff --git a/crypto/openssl/crypto/des/pcbc_enc.c b/crypto/openssl/crypto/des/pcbc_enc.c index 3490592741c6..dd9eb1a92774 100644 --- a/crypto/openssl/crypto/des/pcbc_enc.c +++ b/crypto/openssl/crypto/des/pcbc_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "des_local.h" void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, diff --git a/crypto/openssl/crypto/des/qud_cksm.c b/crypto/openssl/crypto/des/qud_cksm.c index 10b6abf69ea5..9f6839907797 100644 --- a/crypto/openssl/crypto/des/qud_cksm.c +++ b/crypto/openssl/crypto/des/qud_cksm.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,6 +13,13 @@ * only based on the code in this paper and is almost definitely not the same * as the MIT implementation. */ + +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "des_local.h" #define Q_B0(a) (((DES_LONG)(a))) diff --git a/crypto/openssl/crypto/des/rand_key.c b/crypto/openssl/crypto/des/rand_key.c index fe8aefec370d..4c6588787126 100644 --- a/crypto/openssl/crypto/des/rand_key.c +++ b/crypto/openssl/crypto/des/rand_key.c @@ -1,12 +1,18 @@ /* - * Copyright 1998-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/openssl/crypto/des/set_key.c b/crypto/openssl/crypto/des/set_key.c index cbcb616cb2ad..adcfb7f12451 100644 --- a/crypto/openssl/crypto/des/set_key.c +++ b/crypto/openssl/crypto/des/set_key.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,12 +15,18 @@ * 1.1 added norm_expand_bits * 1.0 First working version */ + +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include +#include "internal/constant_time.h" +#include "internal/nelem.h" #include "des_local.h" -/* defaults to false */ -OPENSSL_IMPLEMENT_GLOBAL(int, DES_check_key, 0) - static const unsigned char odd_parity[256] = { 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, @@ -58,15 +64,23 @@ void DES_set_odd_parity(DES_cblock *key) (*key)[i] = odd_parity[(*key)[i]]; } +/* + * Check that a key has the correct parity. + * Return 1 if parity is okay and 0 if not. + */ int DES_check_key_parity(const_DES_cblock *key) { unsigned int i; + unsigned char res = 0377, b; for (i = 0; i < DES_KEY_SZ; i++) { - if ((*key)[i] != odd_parity[(*key)[i]]) - return 0; + b = (*key)[i]; + b ^= b >> 4; + b ^= b >> 2; + b ^= b >> 1; + res &= constant_time_eq_8(b & 1, 1); } - return 1; + return (int)(res & 1); } /*- @@ -77,8 +91,7 @@ int DES_check_key_parity(const_DES_cblock *key) * %I John Wiley & Sons * %D 1984 */ -#define NUM_WEAK_KEY 16 -static const DES_cblock weak_keys[NUM_WEAK_KEY] = { +static const DES_cblock weak_keys[] = { /* weak keys */ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE}, @@ -99,14 +112,20 @@ static const DES_cblock weak_keys[NUM_WEAK_KEY] = { {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1} }; +/* + * Check for weak keys. + * Return 1 if the key is weak and 0 otherwise. + */ int DES_is_weak_key(const_DES_cblock *key) { - int i; + unsigned int i, res = 0; + int j; - for (i = 0; i < NUM_WEAK_KEY; i++) - if (memcmp(weak_keys[i], key, sizeof(DES_cblock)) == 0) - return 1; - return 0; + for (i = 0; i < OSSL_NELEM(weak_keys); i++) { + j = CRYPTO_memcmp(weak_keys[i], key, sizeof(DES_cblock)); + res |= constant_time_is_zero((unsigned int)j); + } + return (int)(res & 1); } /*- @@ -275,14 +294,17 @@ static const DES_LONG des_skb[8][64] = { } }; +/* Return values as DES_set_key_checked() but always set the key */ int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule) { - if (DES_check_key) { - return DES_set_key_checked(key, schedule); - } else { - DES_set_key_unchecked(key, schedule); - return 0; - } + int ret = 0; + + if (!DES_check_key_parity(key)) + ret = -1; + if (DES_is_weak_key(key)) + ret = -2; + DES_set_key_unchecked(key, schedule); + return ret; } /*- diff --git a/crypto/openssl/crypto/des/spr.h b/crypto/openssl/crypto/des/spr.h index 2404e092d4ac..1fe3394ba0dc 100644 --- a/crypto/openssl/crypto/des/spr.h +++ b/crypto/openssl/crypto/des/spr.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/des/str2key.c b/crypto/openssl/crypto/des/str2key.c index 61db60512567..f6687fe524f0 100644 --- a/crypto/openssl/crypto/des/str2key.c +++ b/crypto/openssl/crypto/des/str2key.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "des_local.h" diff --git a/crypto/openssl/crypto/des/xcbc_enc.c b/crypto/openssl/crypto/des/xcbc_enc.c index fb3fd5292cb6..8ad1f1db6dc3 100644 --- a/crypto/openssl/crypto/des/xcbc_enc.c +++ b/crypto/openssl/crypto/des/xcbc_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include "des_local.h" /* RSA's DESX */ diff --git a/crypto/openssl/crypto/dh/build.info b/crypto/openssl/crypto/dh/build.info index b19ff6dbac19..b41356727185 100644 --- a/crypto/openssl/crypto/dh/build.info +++ b/crypto/openssl/crypto/dh/build.info @@ -1,5 +1,13 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - dh_asn1.c dh_gen.c dh_key.c dh_lib.c dh_check.c dh_err.c dh_depr.c \ - dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_kdf.c dh_meth.c \ - dh_rfc7919.c + +$COMMON=dh_lib.c dh_key.c dh_group_params.c dh_check.c dh_backend.c dh_gen.c \ + dh_kdf.c + +SOURCE[../../libcrypto]=$COMMON\ + dh_asn1.c dh_err.c \ + dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_meth.c +IF[{- !$disabled{'deprecated-0.9.8'} -}] + SOURCE[../../libcrypto]=dh_depr.c +ENDIF + +SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/openssl/crypto/dh/dh1024.pem b/crypto/openssl/crypto/dh/dh1024.pem deleted file mode 100644 index 81d43f6a3eae..000000000000 --- a/crypto/openssl/crypto/dh/dh1024.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq -/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx -/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC ------END DH PARAMETERS----- diff --git a/crypto/openssl/crypto/dh/dh192.pem b/crypto/openssl/crypto/dh/dh192.pem deleted file mode 100644 index 521c07271d0d..000000000000 --- a/crypto/openssl/crypto/dh/dh192.pem +++ /dev/null @@ -1,3 +0,0 @@ ------BEGIN DH PARAMETERS----- -MB4CGQDUoLoCULb9LsYm5+/WN992xxbiLQlEuIsCAQM= ------END DH PARAMETERS----- diff --git a/crypto/openssl/crypto/dh/dh2048.pem b/crypto/openssl/crypto/dh/dh2048.pem deleted file mode 100644 index 295460f5081e..000000000000 --- a/crypto/openssl/crypto/dh/dh2048.pem +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o -AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh -z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo -pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW -aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA -Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg== ------END DH PARAMETERS----- ------BEGIN DH PARAMETERS----- -MIIBCAKCAQEArtA3w73zP6Lu3EOQtwogiXt3AXXpuS6yD4BhzNS1pZFyPHk0/an5 -8ydEkPhQZHKDW+BZJxxPLANaTudWo2YT8TgtvUdN6KSgMiEi6McwqDw+SADuvW+F -SKUYFxG6VFIxyEP6xBdf+vhJxEDbRG2EYsHDRRtJ76gp9cSKTHusf2R+4AAVGqnt -gRAbNqtcOar/7FSj+Pl8G3v0Bty0LcCSpbqgYlnv6z+rErQmmC6PPvSz97TDMCok -yKpCE9hFA1zkqK3TH4FmFvGeIaXJUIBZf4mArWuBTjWFW3nmhESRUn1VK3K3x42N -a5k6c2+EhrMFiLjxuH6JZoqL0/E93FF9SwIBAg== ------END DH PARAMETERS----- diff --git a/crypto/openssl/crypto/dh/dh4096.pem b/crypto/openssl/crypto/dh/dh4096.pem deleted file mode 100644 index 390943a21dc4..000000000000 --- a/crypto/openssl/crypto/dh/dh4096.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7 -vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H -TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF -bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1 -rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE -EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9 -bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3 -W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH -ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb -NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR -jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI= ------END DH PARAMETERS----- - diff --git a/crypto/openssl/crypto/dh/dh512.pem b/crypto/openssl/crypto/dh/dh512.pem deleted file mode 100644 index 0a4d863ebe27..000000000000 --- a/crypto/openssl/crypto/dh/dh512.pem +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN DH PARAMETERS----- -MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn -a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC ------END DH PARAMETERS----- diff --git a/crypto/openssl/crypto/dh/dh_ameth.c b/crypto/openssl/crypto/dh/dh_ameth.c index 576409ccb51b..8430872a9ab6 100644 --- a/crypto/openssl/crypto/dh/dh_ameth.c +++ b/crypto/openssl/crypto/dh/dh_ameth.c @@ -1,21 +1,30 @@ /* - * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include -#include "internal/cryptlib.h" #include #include -#include "dh_local.h" #include +#include +#include +#include "internal/ffc.h" +#include "internal/cryptlib.h" #include "crypto/asn1.h" +#include "crypto/dh.h" #include "crypto/evp.h" -#include +#include "dh_local.h" /* * i2d/d2i like DH parameter functions which use the appropriate routine for @@ -25,14 +34,20 @@ static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp, long length) { - if (pkey->ameth == &dhx_asn1_meth) - return d2i_DHxparams(NULL, pp, length); - return d2i_DHparams(NULL, pp, length); + DH *dh = NULL; + int is_dhx = (pkey->ameth == &ossl_dhx_asn1_meth); + + if (is_dhx) + dh = d2i_DHxparams(NULL, pp, length); + else + dh = d2i_DHparams(NULL, pp, length); + + return dh; } static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp) { - if (pkey->ameth == &dhx_asn1_meth) + if (pkey->ameth == &ossl_dhx_asn1_meth) return i2d_DHxparams(a, pp); return i2d_DHparams(a, pp); } @@ -42,7 +57,7 @@ static void int_dh_free(EVP_PKEY *pkey) DH_free(pkey->pkey.dh); } -static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +static int dh_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) { const unsigned char *p, *pm; int pklen, pmlen; @@ -59,7 +74,7 @@ static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) X509_ALGOR_get0(NULL, &ptype, &pval, palg); if (ptype != V_ASN1_SEQUENCE) { - DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR); + ERR_raise(ERR_LIB_DH, DH_R_PARAMETER_ENCODING_ERROR); goto err; } @@ -68,18 +83,18 @@ static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) pmlen = pstr->length; if ((dh = d2i_dhp(pkey, &pm, pmlen)) == NULL) { - DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); + ERR_raise(ERR_LIB_DH, DH_R_DECODE_ERROR); goto err; } if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) { - DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); + ERR_raise(ERR_LIB_DH, DH_R_DECODE_ERROR); goto err; } /* We have parameters now set public key */ if ((dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) { - DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR); + ERR_raise(ERR_LIB_DH, DH_R_BN_DECODE_ERROR); goto err; } @@ -91,7 +106,6 @@ static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) ASN1_INTEGER_free(public_key); DH_free(dh); return 0; - } static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) @@ -107,18 +121,18 @@ static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) str = ASN1_STRING_new(); if (str == NULL) { - DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); goto err; } str->length = i2d_dhp(pkey, dh, &str->data); if (str->length <= 0) { - DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); goto err; } ptype = V_ASN1_SEQUENCE; pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL); - if (!pub_key) + if (pub_key == NULL) goto err; penclen = i2d_ASN1_INTEGER(pub_key, &penc); @@ -126,7 +140,7 @@ static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) ASN1_INTEGER_free(pub_key); if (penclen <= 0) { - DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); goto err; } @@ -149,54 +163,15 @@ static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) static int dh_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) { - const unsigned char *p, *pm; - int pklen, pmlen; - int ptype; - const void *pval; - const ASN1_STRING *pstr; - const X509_ALGOR *palg; - ASN1_INTEGER *privkey = NULL; - - DH *dh = NULL; - - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) - return 0; - - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - if (ptype != V_ASN1_SEQUENCE) - goto decerr; - if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) - goto decerr; + int ret = 0; + DH *dh = ossl_dh_key_from_pkcs8(p8, NULL, NULL); - pstr = pval; - pm = pstr->data; - pmlen = pstr->length; - if ((dh = d2i_dhp(pkey, &pm, pmlen)) == NULL) - goto decerr; - - /* We have parameters now set private key */ - if ((dh->priv_key = BN_secure_new()) == NULL - || !ASN1_INTEGER_to_BN(privkey, dh->priv_key)) { - DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR); - goto dherr; + if (dh != NULL) { + ret = 1; + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); } - /* Calculate public key */ - if (!DH_generate_key(dh)) - goto dherr; - - EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); - - ASN1_STRING_clear_free(privkey); - - return 1; - decerr: - DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR); - dherr: - DH_free(dh); - ASN1_STRING_clear_free(privkey); - return 0; + return ret; } static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) @@ -209,13 +184,13 @@ static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) params = ASN1_STRING_new(); if (params == NULL) { - DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); goto err; } params->length = i2d_dhp(pkey, pkey->pkey.dh, ¶ms->data); if (params->length <= 0) { - DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); goto err; } params->type = V_ASN1_SEQUENCE; @@ -223,26 +198,29 @@ static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) /* Get private key into integer */ prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL); - if (!prkey) { - DHerr(DH_F_DH_PRIV_ENCODE, DH_R_BN_ERROR); + if (prkey == NULL) { + ERR_raise(ERR_LIB_DH, DH_R_BN_ERROR); goto err; } dplen = i2d_ASN1_INTEGER(prkey, &dp); ASN1_STRING_clear_free(prkey); - prkey = NULL; - if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, - V_ASN1_SEQUENCE, params, dp, dplen)) + if (dplen <= 0) { + ERR_raise(ERR_LIB_DH, DH_R_BN_ERROR); goto err; + } + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, + V_ASN1_SEQUENCE, params, dp, dplen)) { + OPENSSL_clear_free(dp, dplen); + goto err; + } return 1; err: - OPENSSL_free(dp); ASN1_STRING_free(params); - ASN1_STRING_clear_free(prkey); return 0; } @@ -251,10 +229,9 @@ static int dh_param_decode(EVP_PKEY *pkey, { DH *dh; - if ((dh = d2i_dhp(pkey, pder, derlen)) == NULL) { - DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB); + if ((dh = d2i_dhp(pkey, pder, derlen)) == NULL) return 0; - } + dh->dirty_cnt++; EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); return 1; } @@ -280,7 +257,7 @@ static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype) else pub_key = NULL; - if (x->p == NULL || (ptype == 2 && priv_key == NULL) + if (x->params.p == NULL || (ptype == 2 && priv_key == NULL) || (ptype > 0 && pub_key == NULL)) { reason = ERR_R_PASSED_NULL_PARAMETER; goto err; @@ -293,8 +270,8 @@ static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype) else ktype = "DH Parameters"; - BIO_indent(bp, indent, 128); - if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) + if (!BIO_indent(bp, indent, 128) + || BIO_printf(bp, "%s: (%d bit)\n", ktype, DH_bits(x)) <= 0) goto err; indent += 4; @@ -303,44 +280,20 @@ static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype) if (!ASN1_bn_print(bp, "public-key:", pub_key, NULL, indent)) goto err; - if (!ASN1_bn_print(bp, "prime:", x->p, NULL, indent)) - goto err; - if (!ASN1_bn_print(bp, "generator:", x->g, NULL, indent)) - goto err; - if (x->q && !ASN1_bn_print(bp, "subgroup order:", x->q, NULL, indent)) - goto err; - if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, NULL, indent)) - goto err; - if (x->seed) { - int i; - BIO_indent(bp, indent, 128); - BIO_puts(bp, "seed:"); - for (i = 0; i < x->seedlen; i++) { - if ((i % 15) == 0) { - if (BIO_puts(bp, "\n") <= 0 - || !BIO_indent(bp, indent + 4, 128)) - goto err; - } - if (BIO_printf(bp, "%02x%s", x->seed[i], - ((i + 1) == x->seedlen) ? "" : ":") <= 0) - goto err; - } - if (BIO_write(bp, "\n", 1) <= 0) - return 0; - } - if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, NULL, indent)) + if (!ossl_ffc_params_print(bp, &x->params, indent)) goto err; + if (x->length != 0) { - BIO_indent(bp, indent, 128); - if (BIO_printf(bp, "recommended-private-length: %d bits\n", - (int)x->length) <= 0) + if (!BIO_indent(bp, indent, 128) + || BIO_printf(bp, "recommended-private-length: %d bits\n", + (int)x->length) <= 0) goto err; } return 1; err: - DHerr(DH_F_DO_DH_PRINT, reason); + ERR_raise(ERR_LIB_DH, reason); return 0; } @@ -351,7 +304,7 @@ static int int_dh_size(const EVP_PKEY *pkey) static int dh_bits(const EVP_PKEY *pkey) { - return BN_num_bits(pkey->pkey.dh->p); + return DH_bits(pkey->pkey.dh); } static int dh_security_bits(const EVP_PKEY *pkey) @@ -361,64 +314,23 @@ static int dh_security_bits(const EVP_PKEY *pkey) static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { - if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) || - BN_cmp(a->pkey.dh->g, b->pkey.dh->g)) - return 0; - else if (a->ameth == &dhx_asn1_meth) { - if (BN_cmp(a->pkey.dh->q, b->pkey.dh->q)) - return 0; - } - return 1; -} - -static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src) -{ - BIGNUM *a; - - /* - * If source is read only just copy the pointer, so - * we don't have to reallocate it. - */ - if (src == NULL) - a = NULL; - else if (BN_get_flags(src, BN_FLG_STATIC_DATA) - && !BN_get_flags(src, BN_FLG_MALLOCED)) - a = (BIGNUM *)src; - else if ((a = BN_dup(src)) == NULL) - return 0; - BN_clear_free(*dst); - *dst = a; - return 1; + return ossl_ffc_params_cmp(&a->pkey.dh->params, &b->pkey.dh->params, + a->ameth != &ossl_dhx_asn1_meth); } static int int_dh_param_copy(DH *to, const DH *from, int is_x942) { if (is_x942 == -1) - is_x942 = ! !from->q; - if (!int_dh_bn_cpy(&to->p, from->p)) + is_x942 = (from->params.q != NULL); + if (!ossl_ffc_params_copy(&to->params, &from->params)) return 0; - if (!int_dh_bn_cpy(&to->g, from->g)) - return 0; - if (is_x942) { - if (!int_dh_bn_cpy(&to->q, from->q)) - return 0; - if (!int_dh_bn_cpy(&to->j, from->j)) - return 0; - OPENSSL_free(to->seed); - to->seed = NULL; - to->seedlen = 0; - if (from->seed) { - to->seed = OPENSSL_memdup(from->seed, from->seedlen); - if (!to->seed) - return 0; - to->seedlen = from->seedlen; - } - } else + if (!is_x942) to->length = from->length; + to->dirty_cnt++; return 1; } -DH *DHparams_dup(DH *dh) +DH *DHparams_dup(const DH *dh) { DH *ret; ret = DH_new(); @@ -439,14 +351,14 @@ static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) return 0; } return int_dh_param_copy(to->pkey.dh, from->pkey.dh, - from->ameth == &dhx_asn1_meth); + from->ameth == &ossl_dhx_asn1_meth); } static int dh_missing_parameters(const EVP_PKEY *a) { - if (a->pkey.dh == NULL || a->pkey.dh->p == NULL || a->pkey.dh->g == NULL) - return 1; - return 0; + return a->pkey.dh == NULL + || a->pkey.dh->params.p == NULL + || a->pkey.dh->params.g == NULL; } static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) @@ -482,27 +394,31 @@ int DHparams_print(BIO *bp, const DH *x) return do_dh_print(bp, x, 4, 0); } -#ifndef OPENSSL_NO_CMS -static int dh_cms_decrypt(CMS_RecipientInfo *ri); -static int dh_cms_encrypt(CMS_RecipientInfo *ri); -#endif - static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { + DH *dh; switch (op) { -#ifndef OPENSSL_NO_CMS - - case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (arg1 == 1) - return dh_cms_decrypt(arg2); - else if (arg1 == 0) - return dh_cms_encrypt(arg2); + case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: + /* We should only be here if we have a legacy key */ + if (!ossl_assert(evp_pkey_is_legacy(pkey))) + return 0; + dh = (DH *) evp_pkey_get0_DH_int(pkey); + if (dh == NULL) + return 0; + return ossl_dh_buf2key(dh, arg2, arg1); + case ASN1_PKEY_CTRL_GET1_TLS_ENCPT: + dh = (DH *) EVP_PKEY_get0_DH(pkey); + if (dh == NULL) + return 0; + return ossl_dh_key2buf(dh, arg2, 0, 1); + default: return -2; + } +} - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - *(int *)arg2 = CMS_RECIPINFO_AGREE; - return 1; -#endif +static int dhx_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { default: return -2; } @@ -514,7 +430,7 @@ static int dh_pkey_public_check(const EVP_PKEY *pkey) DH *dh = pkey->pkey.dh; if (dh->pub_key == NULL) { - DHerr(DH_F_DH_PKEY_PUBLIC_CHECK, DH_R_MISSING_PUBKEY); + ERR_raise(ERR_LIB_DH, DH_R_MISSING_PUBKEY); return 0; } @@ -528,7 +444,120 @@ static int dh_pkey_param_check(const EVP_PKEY *pkey) return DH_check_ex(dh); } -const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { +static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey) +{ + return pkey->pkey.dh->dirty_cnt; +} + +static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata, + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) +{ + DH *dh = from->pkey.dh; + OSSL_PARAM_BLD *tmpl; + const BIGNUM *p = DH_get0_p(dh), *g = DH_get0_g(dh), *q = DH_get0_q(dh); + long l = DH_get_length(dh); + const BIGNUM *pub_key = DH_get0_pub_key(dh); + const BIGNUM *priv_key = DH_get0_priv_key(dh); + OSSL_PARAM *params = NULL; + int selection = 0; + int rv = 0; + + if (p == NULL || g == NULL) + return 0; + + tmpl = OSSL_PARAM_BLD_new(); + if (tmpl == NULL) + return 0; + if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g)) + goto err; + if (q != NULL) { + if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q)) + goto err; + } + selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS; + if (l > 0) { + if (!OSSL_PARAM_BLD_push_long(tmpl, OSSL_PKEY_PARAM_DH_PRIV_LEN, l)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS; + } + if (pub_key != NULL) { + if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, pub_key)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + } + if (priv_key != NULL) { + if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, + priv_key)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY; + } + + if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) + goto err; + + /* We export, the provider imports */ + rv = importer(to_keydata, selection, params); + + OSSL_PARAM_free(params); +err: + OSSL_PARAM_BLD_free(tmpl); + return rv; +} + +static int dh_pkey_import_from_type(const OSSL_PARAM params[], void *vpctx, + int type) +{ + EVP_PKEY_CTX *pctx = vpctx; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); + DH *dh = ossl_dh_new_ex(pctx->libctx); + + if (dh == NULL) { + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + return 0; + } + DH_clear_flags(dh, DH_FLAG_TYPE_MASK); + DH_set_flags(dh, type == EVP_PKEY_DH ? DH_FLAG_TYPE_DH : DH_FLAG_TYPE_DHX); + + if (!ossl_dh_params_fromdata(dh, params) + || !ossl_dh_key_fromdata(dh, params, 1) + || !EVP_PKEY_assign(pkey, type, dh)) { + DH_free(dh); + return 0; + } + return 1; +} + +static int dh_pkey_import_from(const OSSL_PARAM params[], void *vpctx) +{ + return dh_pkey_import_from_type(params, vpctx, EVP_PKEY_DH); +} + +static int dhx_pkey_import_from(const OSSL_PARAM params[], void *vpctx) +{ + return dh_pkey_import_from_type(params, vpctx, EVP_PKEY_DHX); +} + +static int dh_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) +{ + DH *dh = from->pkey.dh; + DH *dupkey = NULL; + int ret; + + if (dh != NULL) { + dupkey = ossl_dh_dup(dh, OSSL_KEYMGMT_SELECT_ALL); + if (dupkey == NULL) + return 0; + } + + ret = EVP_PKEY_assign(to, from->type, dupkey); + if (!ret) + DH_free(dupkey); + return ret; +} + +const EVP_PKEY_ASN1_METHOD ossl_dh_asn1_meth = { EVP_PKEY_DH, EVP_PKEY_DH, 0, @@ -558,16 +587,23 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { 0, int_dh_free, - 0, + dh_pkey_ctrl, 0, 0, 0, 0, 0, 0, dh_pkey_public_check, - dh_pkey_param_check + dh_pkey_param_check, + + 0, 0, 0, 0, + + dh_pkey_dirty_cnt, + dh_pkey_export_to, + dh_pkey_import_from, + dh_pkey_copy }; -const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = { +const EVP_PKEY_ASN1_METHOD ossl_dhx_asn1_meth = { EVP_PKEY_DHX, EVP_PKEY_DHX, 0, @@ -597,315 +633,16 @@ const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = { 0, int_dh_free, - dh_pkey_ctrl, + dhx_pkey_ctrl, 0, 0, 0, 0, 0, 0, dh_pkey_public_check, - dh_pkey_param_check + dh_pkey_param_check, + 0, 0, 0, 0, + dh_pkey_dirty_cnt, + dh_pkey_export_to, + dhx_pkey_import_from, + dh_pkey_copy }; - -#ifndef OPENSSL_NO_CMS - -static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, - X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) -{ - const ASN1_OBJECT *aoid; - int atype; - const void *aval; - ASN1_INTEGER *public_key = NULL; - int rv = 0; - EVP_PKEY *pkpeer = NULL, *pk = NULL; - DH *dhpeer = NULL; - const unsigned char *p; - int plen; - - X509_ALGOR_get0(&aoid, &atype, &aval, alg); - if (OBJ_obj2nid(aoid) != NID_dhpublicnumber) - goto err; - /* Only absent parameters allowed in RFC XXXX */ - if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL) - goto err; - - pk = EVP_PKEY_CTX_get0_pkey(pctx); - if (pk == NULL || pk->type != EVP_PKEY_DHX) - goto err; - - /* Get parameters from parent key */ - dhpeer = DHparams_dup(pk->pkey.dh); - if (dhpeer == NULL) - goto err; - - /* We have parameters now set public key */ - plen = ASN1_STRING_length(pubkey); - p = ASN1_STRING_get0_data(pubkey); - if (p == NULL || plen == 0) - goto err; - - if ((public_key = d2i_ASN1_INTEGER(NULL, &p, plen)) == NULL) { - DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR); - goto err; - } - - /* We have parameters now set public key */ - if ((dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) { - DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR); - goto err; - } - - pkpeer = EVP_PKEY_new(); - if (pkpeer == NULL) - goto err; - - EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer); - dhpeer = NULL; - if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) - rv = 1; - err: - ASN1_INTEGER_free(public_key); - EVP_PKEY_free(pkpeer); - DH_free(dhpeer); - return rv; -} - -static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) -{ - int rv = 0; - - X509_ALGOR *alg, *kekalg = NULL; - ASN1_OCTET_STRING *ukm; - const unsigned char *p; - unsigned char *dukm = NULL; - size_t dukmlen = 0; - int keylen, plen; - const EVP_CIPHER *kekcipher; - EVP_CIPHER_CTX *kekctx; - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) - goto err; - - /* - * For DH we only have one OID permissible. If ever any more get defined - * we will need something cleverer. - */ - if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) { - DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR); - goto err; - } - - if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0) - goto err; - - if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) - goto err; - - if (alg->parameter->type != V_ASN1_SEQUENCE) - goto err; - - p = alg->parameter->value.sequence->data; - plen = alg->parameter->value.sequence->length; - kekalg = d2i_X509_ALGOR(NULL, &p, plen); - if (!kekalg) - goto err; - kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); - if (!kekctx) - goto err; - kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); - if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) - goto err; - if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) - goto err; - if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) - goto err; - - keylen = EVP_CIPHER_CTX_key_length(kekctx); - if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) - goto err; - /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */ - if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, - OBJ_nid2obj(EVP_CIPHER_type(kekcipher))) - <= 0) - goto err; - - if (ukm) { - dukmlen = ASN1_STRING_length(ukm); - dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); - if (!dukm) - goto err; - } - - if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) - goto err; - dukm = NULL; - - rv = 1; - err: - X509_ALGOR_free(kekalg); - OPENSSL_free(dukm); - return rv; -} - -static int dh_cms_decrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (!pctx) - return 0; - /* See if we need to set peer key */ - if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { - X509_ALGOR *alg; - ASN1_BIT_STRING *pubkey; - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, - NULL, NULL, NULL)) - return 0; - if (!alg || !pubkey) - return 0; - if (!dh_cms_set_peerkey(pctx, alg, pubkey)) { - DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR); - return 0; - } - } - /* Set DH derivation parameters and initialise unwrap context */ - if (!dh_cms_set_shared_info(pctx, ri)) { - DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR); - return 0; - } - return 1; -} - -static int dh_cms_encrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - EVP_PKEY *pkey; - EVP_CIPHER_CTX *ctx; - int keylen; - X509_ALGOR *talg, *wrap_alg = NULL; - const ASN1_OBJECT *aoid; - ASN1_BIT_STRING *pubkey; - ASN1_STRING *wrap_str; - ASN1_OCTET_STRING *ukm; - unsigned char *penc = NULL, *dukm = NULL; - int penclen; - size_t dukmlen = 0; - int rv = 0; - int kdf_type, wrap_nid; - const EVP_MD *kdf_md; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (!pctx) - return 0; - /* Get ephemeral key */ - pkey = EVP_PKEY_CTX_get0_pkey(pctx); - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, - NULL, NULL, NULL)) - goto err; - X509_ALGOR_get0(&aoid, NULL, NULL, talg); - /* Is everything uninitialised? */ - if (aoid == OBJ_nid2obj(NID_undef)) { - ASN1_INTEGER *pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL); - if (!pubk) - goto err; - /* Set the key */ - - penclen = i2d_ASN1_INTEGER(pubk, &penc); - ASN1_INTEGER_free(pubk); - if (penclen <= 0) - goto err; - ASN1_STRING_set0(pubkey, penc, penclen); - pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; - - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), - V_ASN1_UNDEF, NULL); - } - - /* See if custom parameters set */ - kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx); - if (kdf_type <= 0) - goto err; - if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md)) - goto err; - - if (kdf_type == EVP_PKEY_DH_KDF_NONE) { - kdf_type = EVP_PKEY_DH_KDF_X9_42; - if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0) - goto err; - } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42) - /* Unknown KDF */ - goto err; - if (kdf_md == NULL) { - /* Only SHA1 supported */ - kdf_md = EVP_sha1(); - if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0) - goto err; - } else if (EVP_MD_type(kdf_md) != NID_sha1) - /* Unsupported digest */ - goto err; - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) - goto err; - - /* Get wrap NID */ - ctx = CMS_RecipientInfo_kari_get0_ctx(ri); - wrap_nid = EVP_CIPHER_CTX_type(ctx); - if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0) - goto err; - keylen = EVP_CIPHER_CTX_key_length(ctx); - - /* Package wrap algorithm in an AlgorithmIdentifier */ - - wrap_alg = X509_ALGOR_new(); - if (wrap_alg == NULL) - goto err; - wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); - wrap_alg->parameter = ASN1_TYPE_new(); - if (wrap_alg->parameter == NULL) - goto err; - if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) - goto err; - if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { - ASN1_TYPE_free(wrap_alg->parameter); - wrap_alg->parameter = NULL; - } - - if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) - goto err; - - if (ukm) { - dukmlen = ASN1_STRING_length(ukm); - dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); - if (!dukm) - goto err; - } - - if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) - goto err; - dukm = NULL; - - /* - * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter - * of another AlgorithmIdentifier. - */ - penc = NULL; - penclen = i2d_X509_ALGOR(wrap_alg, &penc); - if (!penc || !penclen) - goto err; - wrap_str = ASN1_STRING_new(); - if (wrap_str == NULL) - goto err; - ASN1_STRING_set0(wrap_str, penc, penclen); - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), - V_ASN1_SEQUENCE, wrap_str); - - rv = 1; - - err: - OPENSSL_free(penc); - X509_ALGOR_free(wrap_alg); - OPENSSL_free(dukm); - return rv; -} - -#endif diff --git a/crypto/openssl/crypto/dh/dh_asn1.c b/crypto/openssl/crypto/dh/dh_asn1.c index e37f0904e560..5fa91a8ec7dc 100644 --- a/crypto/openssl/crypto/dh/dh_asn1.c +++ b/crypto/openssl/crypto/dh/dh_asn1.c @@ -1,18 +1,25 @@ /* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include #include "dh_local.h" #include #include +#include "crypto/dh.h" /* Override the default free and new methods */ static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, @@ -27,17 +34,24 @@ static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, DH_free((DH *)*pval); *pval = NULL; return 2; + } else if (operation == ASN1_OP_D2I_POST) { + DH *dh = (DH *)*pval; + + DH_clear_flags(dh, DH_FLAG_TYPE_MASK); + DH_set_flags(dh, DH_FLAG_TYPE_DH); + ossl_dh_cache_named_group(dh); + dh->dirty_cnt++; } return 1; } ASN1_SEQUENCE_cb(DHparams, dh_cb) = { - ASN1_SIMPLE(DH, p, BIGNUM), - ASN1_SIMPLE(DH, g, BIGNUM), + ASN1_SIMPLE(DH, params.p, BIGNUM), + ASN1_SIMPLE(DH, params.g, BIGNUM), ASN1_OPT_EMBED(DH, length, ZINT32), } ASN1_SEQUENCE_END_cb(DH, DHparams) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DH, DHparams, DHparams) /* * Internal only structures for handling X9.42 DH: this gets translated to or @@ -74,14 +88,14 @@ int_dhx942_dh *d2i_int_dhx(int_dhx942_dh **a, const unsigned char **pp, long length); int i2d_int_dhx(const int_dhx942_dh *a, unsigned char **pp); -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(int_dhx942_dh, DHxparams, int_dhx) - -/* Application public function: read in X9.42 DH parameters into DH structure */ +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(int_dhx942_dh, DHxparams, int_dhx) DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length) { + FFC_PARAMS *params; int_dhx942_dh *dhx = NULL; DH *dh = NULL; + dh = DH_new(); if (dh == NULL) return NULL; @@ -91,48 +105,63 @@ DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length) return NULL; } - if (a) { + if (a != NULL) { DH_free(*a); *a = dh; } - dh->p = dhx->p; - dh->q = dhx->q; - dh->g = dhx->g; - dh->j = dhx->j; + params = &dh->params; + DH_set0_pqg(dh, dhx->p, dhx->q, dhx->g); + ossl_ffc_params_set0_j(params, dhx->j); - if (dhx->vparams) { - dh->seed = dhx->vparams->seed->data; - dh->seedlen = dhx->vparams->seed->length; - dh->counter = dhx->vparams->counter; - dhx->vparams->seed->data = NULL; + if (dhx->vparams != NULL) { + /* The counter has a maximum value of 4 * numbits(p) - 1 */ + size_t counter = (size_t)BN_get_word(dhx->vparams->counter); + ossl_ffc_params_set_validate_params(params, dhx->vparams->seed->data, + dhx->vparams->seed->length, + counter); ASN1_BIT_STRING_free(dhx->vparams->seed); + BN_free(dhx->vparams->counter); OPENSSL_free(dhx->vparams); dhx->vparams = NULL; } OPENSSL_free(dhx); + DH_clear_flags(dh, DH_FLAG_TYPE_MASK); + DH_set_flags(dh, DH_FLAG_TYPE_DHX); return dh; } int i2d_DHxparams(const DH *dh, unsigned char **pp) { + int ret = 0; int_dhx942_dh dhx; - int_dhvparams dhv; - ASN1_BIT_STRING bs; - dhx.p = dh->p; - dhx.g = dh->g; - dhx.q = dh->q; - dhx.j = dh->j; - if (dh->counter && dh->seed && dh->seedlen > 0) { - bs.flags = ASN1_STRING_FLAG_BITS_LEFT; - bs.data = dh->seed; - bs.length = dh->seedlen; - dhv.seed = &bs; - dhv.counter = dh->counter; + int_dhvparams dhv = { NULL, NULL }; + ASN1_BIT_STRING seed; + size_t seedlen = 0; + const FFC_PARAMS *params = &dh->params; + int counter; + + ossl_ffc_params_get0_pqg(params, (const BIGNUM **)&dhx.p, + (const BIGNUM **)&dhx.q, (const BIGNUM **)&dhx.g); + dhx.j = params->j; + ossl_ffc_params_get_validate_params(params, &seed.data, &seedlen, &counter); + seed.length = (int)seedlen; + + if (counter != -1 && seed.data != NULL && seed.length > 0) { + seed.flags = ASN1_STRING_FLAG_BITS_LEFT; + dhv.seed = &seed; + dhv.counter = BN_new(); + if (dhv.counter == NULL) + return 0; + if (!BN_set_word(dhv.counter, (BN_ULONG)counter)) + goto err; dhx.vparams = &dhv; - } else + } else { dhx.vparams = NULL; - - return i2d_int_dhx(&dhx, pp); + } + ret = i2d_int_dhx(&dhx, pp); +err: + BN_free(dhv.counter); + return ret; } diff --git a/crypto/openssl/crypto/dh/dh_backend.c b/crypto/openssl/crypto/dh/dh_backend.c new file mode 100644 index 000000000000..726843fd30cd --- /dev/null +++ b/crypto/openssl/crypto/dh/dh_backend.c @@ -0,0 +1,250 @@ +/* + * Copyright 2020-2022 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 + */ + +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include +#ifndef FIPS_MODULE +# include +#endif +#include "internal/param_build_set.h" +#include "crypto/dh.h" +#include "dh_local.h" + +/* + * The intention with the "backend" source file is to offer backend functions + * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider + * implementations alike. + */ + +static int dh_ffc_params_fromdata(DH *dh, const OSSL_PARAM params[]) +{ + int ret; + FFC_PARAMS *ffc; + + if (dh == NULL) + return 0; + ffc = ossl_dh_get0_params(dh); + if (ffc == NULL) + return 0; + + ret = ossl_ffc_params_fromdata(ffc, params); + if (ret) + ossl_dh_cache_named_group(dh); /* This increments dh->dirty_cnt */ + return ret; +} + +int ossl_dh_params_fromdata(DH *dh, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *param_priv_len; + long priv_len; + + if (!dh_ffc_params_fromdata(dh, params)) + return 0; + + param_priv_len = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_LEN); + if (param_priv_len != NULL + && (!OSSL_PARAM_get_long(param_priv_len, &priv_len) + || !DH_set_length(dh, priv_len))) + return 0; + + return 1; +} + +int ossl_dh_key_fromdata(DH *dh, const OSSL_PARAM params[], int include_private) +{ + const OSSL_PARAM *param_priv_key, *param_pub_key; + BIGNUM *priv_key = NULL, *pub_key = NULL; + + if (dh == NULL) + return 0; + + param_priv_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); + param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); + + if (include_private + && param_priv_key != NULL + && !OSSL_PARAM_get_BN(param_priv_key, &priv_key)) + goto err; + + if (param_pub_key != NULL + && !OSSL_PARAM_get_BN(param_pub_key, &pub_key)) + goto err; + + if (!DH_set0_key(dh, pub_key, priv_key)) + goto err; + + return 1; + + err: + BN_clear_free(priv_key); + BN_free(pub_key); + return 0; +} + +int ossl_dh_params_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) +{ + long l = DH_get_length(dh); + + if (!ossl_ffc_params_todata(ossl_dh_get0_params(dh), bld, params)) + return 0; + if (l > 0 + && !ossl_param_build_set_long(bld, params, OSSL_PKEY_PARAM_DH_PRIV_LEN, l)) + return 0; + return 1; +} + +int ossl_dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[], + int include_private) +{ + const BIGNUM *priv = NULL, *pub = NULL; + + if (dh == NULL) + return 0; + + DH_get0_key(dh, &pub, &priv); + if (priv != NULL + && include_private + && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PRIV_KEY, priv)) + return 0; + if (pub != NULL + && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PUB_KEY, pub)) + return 0; + + return 1; +} + +int ossl_dh_is_foreign(const DH *dh) +{ +#ifndef FIPS_MODULE + if (dh->engine != NULL || ossl_dh_get_method(dh) != DH_OpenSSL()) + return 1; +#endif + return 0; +} + +static ossl_inline int dh_bn_dup_check(BIGNUM **out, const BIGNUM *f) +{ + if (f != NULL && (*out = BN_dup(f)) == NULL) + return 0; + return 1; +} + +DH *ossl_dh_dup(const DH *dh, int selection) +{ + DH *dupkey = NULL; + + /* Do not try to duplicate foreign DH keys */ + if (ossl_dh_is_foreign(dh)) + return NULL; + + if ((dupkey = ossl_dh_new_ex(dh->libctx)) == NULL) + return NULL; + + dupkey->length = DH_get_length(dh); + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0 + && !ossl_ffc_params_copy(&dupkey->params, &dh->params)) + goto err; + + dupkey->flags = dh->flags; + + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 + && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 + || !dh_bn_dup_check(&dupkey->pub_key, dh->pub_key))) + goto err; + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 + && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 + || !dh_bn_dup_check(&dupkey->priv_key, dh->priv_key))) + goto err; + +#ifndef FIPS_MODULE + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DH, + &dupkey->ex_data, &dh->ex_data)) + goto err; +#endif + + return dupkey; + + err: + DH_free(dupkey); + return NULL; +} + +#ifndef FIPS_MODULE +DH *ossl_dh_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + const void *pval; + const ASN1_STRING *pstr; + const X509_ALGOR *palg; + BIGNUM *privkey_bn = NULL; + ASN1_INTEGER *privkey = NULL; + DH *dh = NULL; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8inf)) + return 0; + + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype != V_ASN1_SEQUENCE) + goto decerr; + if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) + goto decerr; + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + switch (OBJ_obj2nid(palg->algorithm)) { + case NID_dhKeyAgreement: + dh = d2i_DHparams(NULL, &pm, pmlen); + break; + case NID_dhpublicnumber: + dh = d2i_DHxparams(NULL, &pm, pmlen); + break; + default: + goto decerr; + } + if (dh == NULL) + goto decerr; + + /* We have parameters now set private key */ + if ((privkey_bn = BN_secure_new()) == NULL + || !ASN1_INTEGER_to_BN(privkey, privkey_bn)) { + ERR_raise(ERR_LIB_DH, DH_R_BN_ERROR); + BN_clear_free(privkey_bn); + goto dherr; + } + if (!DH_set0_key(dh, NULL, privkey_bn)) + goto dherr; + /* Calculate public key, increments dirty_cnt */ + if (!DH_generate_key(dh)) + goto dherr; + + goto done; + + decerr: + ERR_raise(ERR_LIB_DH, EVP_R_DECODE_ERROR); + dherr: + DH_free(dh); + dh = NULL; + done: + ASN1_STRING_clear_free(privkey); + return dh; +} +#endif diff --git a/crypto/openssl/crypto/dh/dh_check.c b/crypto/openssl/crypto/dh/dh_check.c index 4ac169e75c23..0b391910d6b3 100644 --- a/crypto/openssl/crypto/dh/dh_check.c +++ b/crypto/openssl/crypto/dh/dh_check.c @@ -1,18 +1,23 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include #include "dh_local.h" - -# define DH_NUMBER_ITERATIONS_FOR_PRIME 64 +#include "crypto/dh.h" /*- * Check that p and g are suitable enough @@ -28,13 +33,39 @@ int DH_check_params_ex(const DH *dh) return 0; if ((errflags & DH_CHECK_P_NOT_PRIME) != 0) - DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_CHECK_P_NOT_PRIME); + ERR_raise(ERR_LIB_DH, DH_R_CHECK_P_NOT_PRIME); if ((errflags & DH_NOT_SUITABLE_GENERATOR) != 0) - DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_NOT_SUITABLE_GENERATOR); + ERR_raise(ERR_LIB_DH, DH_R_NOT_SUITABLE_GENERATOR); + if ((errflags & DH_MODULUS_TOO_SMALL) != 0) + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL); + if ((errflags & DH_MODULUS_TOO_LARGE) != 0) + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); return errflags == 0; } +#ifdef FIPS_MODULE +int DH_check_params(const DH *dh, int *ret) +{ + int nid; + + *ret = 0; + /* + * SP800-56A R3 Section 5.5.2 Assurances of Domain Parameter Validity + * (1a) The domain parameters correspond to any approved safe prime group. + */ + nid = DH_get_nid((DH *)dh); + if (nid != NID_undef) + return 1; + /* + * OR + * (2b) FFC domain params conform to FIPS-186-4 explicit domain param + * validity tests. + */ + return ossl_ffc_params_FIPS186_4_validate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, ret, NULL); +} +#else int DH_check_params(const DH *dh, int *ret) { int ok = 0; @@ -42,7 +73,7 @@ int DH_check_params(const DH *dh, int *ret) BN_CTX *ctx = NULL; *ret = 0; - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(dh->libctx); if (ctx == NULL) goto err; BN_CTX_start(ctx); @@ -50,14 +81,20 @@ int DH_check_params(const DH *dh, int *ret) if (tmp == NULL) goto err; - if (!BN_is_odd(dh->p)) + if (!BN_is_odd(dh->params.p)) *ret |= DH_CHECK_P_NOT_PRIME; - if (BN_is_negative(dh->g) || BN_is_zero(dh->g) || BN_is_one(dh->g)) + if (BN_is_negative(dh->params.g) + || BN_is_zero(dh->params.g) + || BN_is_one(dh->params.g)) *ret |= DH_NOT_SUITABLE_GENERATOR; - if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1)) + if (BN_copy(tmp, dh->params.p) == NULL || !BN_sub_word(tmp, 1)) goto err; - if (BN_cmp(dh->g, tmp) >= 0) + if (BN_cmp(dh->params.g, tmp) >= 0) *ret |= DH_NOT_SUITABLE_GENERATOR; + if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) + *ret |= DH_MODULUS_TOO_SMALL; + if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) + *ret |= DH_MODULUS_TOO_LARGE; ok = 1; err: @@ -65,6 +102,7 @@ int DH_check_params(const DH *dh, int *ret) BN_CTX_free(ctx); return ok; } +#endif /* FIPS_MODULE */ /*- * Check that p is a safe prime and @@ -78,33 +116,46 @@ int DH_check_ex(const DH *dh) return 0; if ((errflags & DH_NOT_SUITABLE_GENERATOR) != 0) - DHerr(DH_F_DH_CHECK_EX, DH_R_NOT_SUITABLE_GENERATOR); + ERR_raise(ERR_LIB_DH, DH_R_NOT_SUITABLE_GENERATOR); if ((errflags & DH_CHECK_Q_NOT_PRIME) != 0) - DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_Q_NOT_PRIME); + ERR_raise(ERR_LIB_DH, DH_R_CHECK_Q_NOT_PRIME); if ((errflags & DH_CHECK_INVALID_Q_VALUE) != 0) - DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_INVALID_Q_VALUE); + ERR_raise(ERR_LIB_DH, DH_R_CHECK_INVALID_Q_VALUE); if ((errflags & DH_CHECK_INVALID_J_VALUE) != 0) - DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_INVALID_J_VALUE); + ERR_raise(ERR_LIB_DH, DH_R_CHECK_INVALID_J_VALUE); if ((errflags & DH_UNABLE_TO_CHECK_GENERATOR) != 0) - DHerr(DH_F_DH_CHECK_EX, DH_R_UNABLE_TO_CHECK_GENERATOR); + ERR_raise(ERR_LIB_DH, DH_R_UNABLE_TO_CHECK_GENERATOR); if ((errflags & DH_CHECK_P_NOT_PRIME) != 0) - DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_P_NOT_PRIME); + ERR_raise(ERR_LIB_DH, DH_R_CHECK_P_NOT_PRIME); if ((errflags & DH_CHECK_P_NOT_SAFE_PRIME) != 0) - DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_P_NOT_SAFE_PRIME); + ERR_raise(ERR_LIB_DH, DH_R_CHECK_P_NOT_SAFE_PRIME); + if ((errflags & DH_MODULUS_TOO_SMALL) != 0) + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL); + if ((errflags & DH_MODULUS_TOO_LARGE) != 0) + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); return errflags == 0; } +/* Note: according to documentation - this only checks the params */ int DH_check(const DH *dh, int *ret) { +#ifdef FIPS_MODULE + return DH_check_params(dh, ret); +#else int ok = 0, r; BN_CTX *ctx = NULL; BIGNUM *t1 = NULL, *t2 = NULL; + int nid = DH_get_nid((DH *)dh); + + *ret = 0; + if (nid != NID_undef) + return 1; if (!DH_check_params(dh, ret)) return 0; - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(dh->libctx); if (ctx == NULL) goto err; BN_CTX_start(ctx); @@ -113,41 +164,42 @@ int DH_check(const DH *dh, int *ret) if (t2 == NULL) goto err; - if (dh->q) { - if (BN_cmp(dh->g, BN_value_one()) <= 0) + if (dh->params.q != NULL) { + if (BN_cmp(dh->params.g, BN_value_one()) <= 0) *ret |= DH_NOT_SUITABLE_GENERATOR; - else if (BN_cmp(dh->g, dh->p) >= 0) + else if (BN_cmp(dh->params.g, dh->params.p) >= 0) *ret |= DH_NOT_SUITABLE_GENERATOR; else { /* Check g^q == 1 mod p */ - if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx)) + if (!BN_mod_exp(t1, dh->params.g, dh->params.q, dh->params.p, ctx)) goto err; if (!BN_is_one(t1)) *ret |= DH_NOT_SUITABLE_GENERATOR; } - r = BN_is_prime_ex(dh->q, DH_NUMBER_ITERATIONS_FOR_PRIME, ctx, NULL); + r = BN_check_prime(dh->params.q, ctx, NULL); if (r < 0) goto err; if (!r) *ret |= DH_CHECK_Q_NOT_PRIME; /* Check p == 1 mod q i.e. q divides p - 1 */ - if (!BN_div(t1, t2, dh->p, dh->q, ctx)) + if (!BN_div(t1, t2, dh->params.p, dh->params.q, ctx)) goto err; if (!BN_is_one(t2)) *ret |= DH_CHECK_INVALID_Q_VALUE; - if (dh->j && BN_cmp(dh->j, t1)) + if (dh->params.j != NULL + && BN_cmp(dh->params.j, t1)) *ret |= DH_CHECK_INVALID_J_VALUE; } - r = BN_is_prime_ex(dh->p, DH_NUMBER_ITERATIONS_FOR_PRIME, ctx, NULL); + r = BN_check_prime(dh->params.p, ctx, NULL); if (r < 0) goto err; if (!r) *ret |= DH_CHECK_P_NOT_PRIME; - else if (!dh->q) { - if (!BN_rshift1(t1, dh->p)) + else if (dh->params.q == NULL) { + if (!BN_rshift1(t1, dh->params.p)) goto err; - r = BN_is_prime_ex(t1, DH_NUMBER_ITERATIONS_FOR_PRIME, ctx, NULL); + r = BN_check_prime(t1, ctx, NULL); if (r < 0) goto err; if (!r) @@ -158,6 +210,7 @@ int DH_check(const DH *dh, int *ret) BN_CTX_end(ctx); BN_CTX_free(ctx); return ok; +#endif /* FIPS_MODULE */ } int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key) @@ -168,47 +221,113 @@ int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key) return 0; if ((errflags & DH_CHECK_PUBKEY_TOO_SMALL) != 0) - DHerr(DH_F_DH_CHECK_PUB_KEY_EX, DH_R_CHECK_PUBKEY_TOO_SMALL); + ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_SMALL); if ((errflags & DH_CHECK_PUBKEY_TOO_LARGE) != 0) - DHerr(DH_F_DH_CHECK_PUB_KEY_EX, DH_R_CHECK_PUBKEY_TOO_LARGE); + ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_LARGE); if ((errflags & DH_CHECK_PUBKEY_INVALID) != 0) - DHerr(DH_F_DH_CHECK_PUB_KEY_EX, DH_R_CHECK_PUBKEY_INVALID); + ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID); return errflags == 0; } +/* + * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Full public key validation. + */ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) +{ + return ossl_ffc_validate_public_key(&dh->params, pub_key, ret); +} + +/* + * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Partial public key validation. + * To only be used with ephemeral FFC public keys generated using the approved + * safe-prime groups. + */ +int ossl_dh_check_pub_key_partial(const DH *dh, const BIGNUM *pub_key, int *ret) +{ + return ossl_ffc_validate_public_key_partial(&dh->params, pub_key, ret); +} + +int ossl_dh_check_priv_key(const DH *dh, const BIGNUM *priv_key, int *ret) { int ok = 0; - BIGNUM *tmp = NULL; - BN_CTX *ctx = NULL; + BIGNUM *two_powN = NULL, *upper; *ret = 0; - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); - if (tmp == NULL || !BN_set_word(tmp, 1)) - goto err; - if (BN_cmp(pub_key, tmp) <= 0) - *ret |= DH_CHECK_PUBKEY_TOO_SMALL; - if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1)) - goto err; - if (BN_cmp(pub_key, tmp) >= 0) - *ret |= DH_CHECK_PUBKEY_TOO_LARGE; + two_powN = BN_new(); + if (two_powN == NULL) + return 0; - if (dh->q != NULL) { - /* Check pub_key^q == 1 mod p */ - if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx)) - goto err; - if (!BN_is_one(tmp)) - *ret |= DH_CHECK_PUBKEY_INVALID; + if (dh->params.q != NULL) { + upper = dh->params.q; +#ifndef FIPS_MODULE + } else if (dh->params.p != NULL) { + /* + * We do not have q so we just check the key is within some + * reasonable range, or the number of bits is equal to dh->length. + */ + int length = dh->length; + + if (length == 0) { + length = BN_num_bits(dh->params.p) - 1; + if (BN_num_bits(priv_key) <= length + && BN_num_bits(priv_key) > 1) + ok = 1; + } else if (BN_num_bits(priv_key) == length) { + ok = 1; + } + goto end; +#endif + } else { + goto end; } + /* Is it from an approved Safe prime group ?*/ + if (DH_get_nid((DH *)dh) != NID_undef && dh->length != 0) { + if (!BN_lshift(two_powN, BN_value_one(), dh->length)) + goto end; + if (BN_cmp(two_powN, dh->params.q) < 0) + upper = two_powN; + } + if (!ossl_ffc_validate_private_key(upper, priv_key, ret)) + goto end; + ok = 1; - err: - BN_CTX_end(ctx); - BN_CTX_free(ctx); +end: + BN_free(two_powN); return ok; } + +/* + * FFC pairwise check from SP800-56A R3. + * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency + */ +int ossl_dh_check_pairwise(const DH *dh) +{ + int ret = 0; + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL; + + if (dh->params.p == NULL + || dh->params.g == NULL + || dh->priv_key == NULL + || dh->pub_key == NULL) + return 0; + + ctx = BN_CTX_new_ex(dh->libctx); + if (ctx == NULL) + goto err; + pub_key = BN_new(); + if (pub_key == NULL) + goto err; + + /* recalculate the public key = (g ^ priv) mod p */ + if (!ossl_dh_generate_public_key(ctx, dh, dh->priv_key, pub_key)) + goto err; + /* check it matches the existing pubic_key */ + ret = BN_cmp(pub_key, dh->pub_key) == 0; +err: + BN_free(pub_key); + BN_CTX_free(ctx); + return ret; +} diff --git a/crypto/openssl/crypto/dh/dh_depr.c b/crypto/openssl/crypto/dh/dh_depr.c index f8ed1b7461ee..5822d511d958 100644 --- a/crypto/openssl/crypto/dh/dh_depr.c +++ b/crypto/openssl/crypto/dh/dh_depr.c @@ -1,7 +1,7 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,15 +9,18 @@ /* This file contains deprecated functions as wrappers to the new ones */ +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include -#if OPENSSL_API_COMPAT >= 0x00908000L -NON_EMPTY_TRANSLATION_UNIT -#else -# include -# include "internal/cryptlib.h" -# include -# include +#include +#include "internal/cryptlib.h" +#include +#include DH *DH_generate_parameters(int prime_len, int generator, void (*callback) (int, int, void *), void *cb_arg) @@ -43,4 +46,3 @@ DH *DH_generate_parameters(int prime_len, int generator, DH_free(ret); return NULL; } -#endif diff --git a/crypto/openssl/crypto/dh/dh_err.c b/crypto/openssl/crypto/dh/dh_err.c index 7285587b4ade..4152397426cc 100644 --- a/crypto/openssl/crypto/dh/dh_err.c +++ b/crypto/openssl/crypto/dh/dh_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,43 +10,14 @@ #include #include +#include "crypto/dherr.h" -#ifndef OPENSSL_NO_ERR +#ifndef OPENSSL_NO_DH -static const ERR_STRING_DATA DH_str_functs[] = { - {ERR_PACK(ERR_LIB_DH, DH_F_COMPUTE_KEY, 0), "compute_key"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DHPARAMS_PRINT_FP, 0), "DHparams_print_fp"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_BUILTIN_GENPARAMS, 0), - "dh_builtin_genparams"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_EX, 0), "DH_check_ex"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PARAMS_EX, 0), "DH_check_params_ex"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PUB_KEY_EX, 0), "DH_check_pub_key_ex"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_DECRYPT, 0), "dh_cms_decrypt"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_SET_PEERKEY, 0), "dh_cms_set_peerkey"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_SET_SHARED_INFO, 0), - "dh_cms_set_shared_info"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_DUP, 0), "DH_meth_dup"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_NEW, 0), "DH_meth_new"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_METH_SET1_NAME, 0), "DH_meth_set1_name"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_NEW_BY_NID, 0), "DH_new_by_nid"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_NEW_METHOD, 0), "DH_new_method"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PARAM_DECODE, 0), "dh_param_decode"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PKEY_PUBLIC_CHECK, 0), - "dh_pkey_public_check"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PRIV_DECODE, 0), "dh_priv_decode"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PRIV_ENCODE, 0), "dh_priv_encode"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PUB_DECODE, 0), "dh_pub_decode"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DH_PUB_ENCODE, 0), "dh_pub_encode"}, - {ERR_PACK(ERR_LIB_DH, DH_F_DO_DH_PRINT, 0), "do_dh_print"}, - {ERR_PACK(ERR_LIB_DH, DH_F_GENERATE_KEY, 0), "generate_key"}, - {ERR_PACK(ERR_LIB_DH, DH_F_PKEY_DH_CTRL_STR, 0), "pkey_dh_ctrl_str"}, - {ERR_PACK(ERR_LIB_DH, DH_F_PKEY_DH_DERIVE, 0), "pkey_dh_derive"}, - {ERR_PACK(ERR_LIB_DH, DH_F_PKEY_DH_INIT, 0), "pkey_dh_init"}, - {ERR_PACK(ERR_LIB_DH, DH_F_PKEY_DH_KEYGEN, 0), "pkey_dh_keygen"}, - {0, NULL} -}; +# ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA DH_str_reasons[] = { + {ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_FFC_PARAMETERS), "bad ffc parameters"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR), "bad generator"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_DECODE_ERROR), "bn decode error"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_ERROR), "bn error"}, @@ -70,10 +41,12 @@ static const ERR_STRING_DATA DH_str_reasons[] = { {ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_PARAMETER_NID), "invalid parameter nid"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_PUBKEY), "invalid public key"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_SECRET), "invalid secret"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_KEYS_NOT_SET), "keys not set"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_MISSING_PUBKEY), "missing pubkey"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_SMALL), "modulus too small"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_NOT_SUITABLE_GENERATOR), "not suitable generator"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PARAMETERS_SET), "no parameters set"}, @@ -87,15 +60,16 @@ static const ERR_STRING_DATA DH_str_reasons[] = { {0, NULL} }; -#endif +# endif -int ERR_load_DH_strings(void) +int ossl_err_load_DH_strings(void) { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(DH_str_functs[0].error) == NULL) { - ERR_load_strings_const(DH_str_functs); +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(DH_str_reasons[0].error) == NULL) ERR_load_strings_const(DH_str_reasons); - } -#endif +# endif return 1; } +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/dh/dh_gen.c b/crypto/openssl/crypto/dh/dh_gen.c index ab82ab58bd2a..aec6b853169a 100644 --- a/crypto/openssl/crypto/dh/dh_gen.c +++ b/crypto/openssl/crypto/dh/dh_gen.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,22 +12,120 @@ * dh_depr.c as wrappers to these ones. - Geoff */ +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + * + * NOTE: When generating keys for key-agreement schemes - FIPS 140-2 IG 9.9 + * states that no additional pairwise tests are required (apart from the tests + * specified in SP800-56A) when generating keys. Hence DH pairwise tests are + * omitted here. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include +#include +#include "crypto/dh.h" #include "dh_local.h" +#ifndef FIPS_MODULE static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb); +#endif /* FIPS_MODULE */ + +int ossl_dh_generate_ffc_parameters(DH *dh, int type, int pbits, int qbits, + BN_GENCB *cb) +{ + int ret, res; + +#ifndef FIPS_MODULE + if (type == DH_PARAMGEN_TYPE_FIPS_186_2) + ret = ossl_ffc_params_FIPS186_2_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, + pbits, qbits, &res, cb); + else +#endif + ret = ossl_ffc_params_FIPS186_4_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, + pbits, qbits, &res, cb); + if (ret > 0) + dh->dirty_cnt++; + return ret; +} + +int ossl_dh_get_named_group_uid_from_size(int pbits) +{ + /* + * Just choose an approved safe prime group. + * The alternative to this is to generate FIPS186-4 domain parameters i.e. + * return dh_generate_ffc_parameters(ret, prime_len, 0, NULL, cb); + * As the FIPS186-4 generated params are for backwards compatibility, + * the safe prime group should be used as the default. + */ + int nid; + + switch (pbits) { + case 2048: + nid = NID_ffdhe2048; + break; + case 3072: + nid = NID_ffdhe3072; + break; + case 4096: + nid = NID_ffdhe4096; + break; + case 6144: + nid = NID_ffdhe6144; + break; + case 8192: + nid = NID_ffdhe8192; + break; + /* unsupported prime_len */ + default: + return NID_undef; + } + return nid; +} + +#ifdef FIPS_MODULE + +static int dh_gen_named_group(OSSL_LIB_CTX *libctx, DH *ret, int prime_len) +{ + DH *dh; + int ok = 0; + int nid = ossl_dh_get_named_group_uid_from_size(prime_len); + + if (nid == NID_undef) + return 0; + + dh = ossl_dh_new_by_nid_ex(libctx, nid); + if (dh != NULL + && ossl_ffc_params_copy(&ret->params, &dh->params)) { + ok = 1; + ret->dirty_cnt++; + } + DH_free(dh); + return ok; +} +#endif /* FIPS_MODULE */ int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb) { +#ifdef FIPS_MODULE + if (generator != 2) + return 0; + return dh_gen_named_group(ret->libctx, ret, prime_len); +#else if (ret->meth->generate_params) return ret->meth->generate_params(ret, prime_len, generator, cb); return dh_builtin_genparams(ret, prime_len, generator, cb); +#endif /* FIPS_MODULE */ } +#ifndef FIPS_MODULE /*- * We generate DH parameters as follows * find a prime p which is prime_len bits long, @@ -53,10 +151,6 @@ int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, * for 2, p mod 24 == 23 * for 3, p mod 12 == 11 * for 5, p mod 60 == 59 - * - * However for compatibility 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) @@ -65,7 +159,17 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, int g, ok = -1; BN_CTX *ctx = NULL; - ctx = BN_CTX_new(); + if (prime_len > OPENSSL_DH_MAX_MODULUS_BITS) { + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); + return 0; + } + + if (prime_len < DH_MIN_MODULUS_BITS) { + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL); + return 0; + } + + ctx = BN_CTX_new_ex(ret->libctx); if (ctx == NULL) goto err; BN_CTX_start(ctx); @@ -75,25 +179,25 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, goto err; /* Make sure 'ret' has the necessary elements */ - if (!ret->p && ((ret->p = BN_new()) == NULL)) + if (ret->params.p == NULL && ((ret->params.p = BN_new()) == NULL)) goto err; - if (!ret->g && ((ret->g = BN_new()) == NULL)) + if (ret->params.g == NULL && ((ret->params.g = BN_new()) == NULL)) goto err; if (generator <= 1) { - DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); + ERR_raise(ERR_LIB_DH, DH_R_BAD_GENERATOR); goto err; } if (generator == DH_GENERATOR_2) { if (!BN_set_word(t1, 24)) goto err; - if (!BN_set_word(t2, 11)) + if (!BN_set_word(t2, 23)) goto err; g = 2; } else if (generator == DH_GENERATOR_5) { if (!BN_set_word(t1, 60)) goto err; - if (!BN_set_word(t2, 23)) + if (!BN_set_word(t2, 59)) goto err; g = 5; } else { @@ -109,16 +213,17 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, g = generator; } - if (!BN_generate_prime_ex(ret->p, prime_len, 1, t1, t2, cb)) + if (!BN_generate_prime_ex2(ret->params.p, prime_len, 1, t1, t2, cb, ctx)) goto err; if (!BN_GENCB_call(cb, 3, 0)) goto err; - if (!BN_set_word(ret->g, g)) + if (!BN_set_word(ret->params.g, g)) goto err; + ret->dirty_cnt++; ok = 1; err: if (ok == -1) { - DHerr(DH_F_DH_BUILTIN_GENPARAMS, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_DH, ERR_R_BN_LIB); ok = 0; } @@ -126,3 +231,4 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_CTX_free(ctx); return ok; } +#endif /* FIPS_MODULE */ diff --git a/crypto/openssl/crypto/dh/dh_group_params.c b/crypto/openssl/crypto/dh/dh_group_params.c new file mode 100644 index 000000000000..460bd8f00989 --- /dev/null +++ b/crypto/openssl/crypto/dh/dh_group_params.c @@ -0,0 +1,99 @@ +/* + * Copyright 2017-2022 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 + */ + +/* DH parameters from RFC7919 and RFC3526 */ + +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "internal/cryptlib.h" +#include "internal/ffc.h" +#include "dh_local.h" +#include +#include +#include "internal/nelem.h" +#include "crypto/dh.h" + +static DH *dh_param_init(OSSL_LIB_CTX *libctx, const DH_NAMED_GROUP *group) +{ + DH *dh = ossl_dh_new_ex(libctx); + + if (dh == NULL) + return NULL; + + ossl_ffc_named_group_set(&dh->params, group); + dh->params.nid = ossl_ffc_named_group_get_uid(group); + dh->dirty_cnt++; + return dh; +} + +DH *ossl_dh_new_by_nid_ex(OSSL_LIB_CTX *libctx, int nid) +{ + const DH_NAMED_GROUP *group; + + if ((group = ossl_ffc_uid_to_dh_named_group(nid)) != NULL) + return dh_param_init(libctx, group); + + ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NID); + return NULL; +} + +DH *DH_new_by_nid(int nid) +{ + return ossl_dh_new_by_nid_ex(NULL, nid); +} + +void ossl_dh_cache_named_group(DH *dh) +{ + const DH_NAMED_GROUP *group; + + if (dh == NULL) + return; + + dh->params.nid = NID_undef; /* flush cached value */ + + /* Exit if p or g is not set */ + if (dh->params.p == NULL + || dh->params.g == NULL) + return; + + if ((group = ossl_ffc_numbers_to_dh_named_group(dh->params.p, + dh->params.q, + dh->params.g)) != NULL) { + if (dh->params.q == NULL) + dh->params.q = (BIGNUM *)ossl_ffc_named_group_get_q(group); + /* cache the nid and default key length */ + dh->params.nid = ossl_ffc_named_group_get_uid(group); + dh->params.keylength = ossl_ffc_named_group_get_keylength(group); + dh->dirty_cnt++; + } +} + +int ossl_dh_is_named_safe_prime_group(const DH *dh) +{ + int id = DH_get_nid(dh); + + /* + * Exclude RFC5114 groups (id = 1..3) since they do not have + * q = (p - 1) / 2 + */ + return (id > 3); +} + +int DH_get_nid(const DH *dh) +{ + if (dh == NULL) + return NID_undef; + + return dh->params.nid; +} diff --git a/crypto/openssl/crypto/dh/dh_kdf.c b/crypto/openssl/crypto/dh/dh_kdf.c index e17122bc82e3..6e99466e60b3 100644 --- a/crypto/openssl/crypto/dh/dh_kdf.c +++ b/crypto/openssl/crypto/dh/dh_kdf.c @@ -1,150 +1,81 @@ /* - * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2013-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include "e_os.h" +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" -#ifndef OPENSSL_NO_CMS +#include "e_os.h" +#include "e_os.h" #include +#include #include #include #include -#include - - -/* Key derivation from X9.42/RFC2631 */ -/* Uses CMS functions, hence the #ifdef wrapper. */ +#include +#include "internal/provider.h" +#include "crypto/dh.h" -#define DH_KDF_MAX (1L << 30) - -/* Skip past an ASN1 structure: for OBJECT skip content octets too */ - -static int skip_asn1(unsigned char **pp, long *plen, int exptag) +/* Key derivation function from X9.63/SECG */ +int ossl_dh_kdf_X9_42_asn1(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const char *cek_alg, + const unsigned char *ukm, size_t ukmlen, + const EVP_MD *md, + OSSL_LIB_CTX *libctx, const char *propq) { - const unsigned char *q = *pp; - int i, tag, xclass; - long tmplen; - i = ASN1_get_object(&q, &tmplen, &tag, &xclass, *plen); - if (i & 0x80) - return 0; - if (tag != exptag || xclass != V_ASN1_UNIVERSAL) - return 0; - if (tag == V_ASN1_OBJECT) - q += tmplen; - *plen -= q - *pp; - *pp = (unsigned char *)q; - return 1; -} - -/* - * Encode the DH shared info structure, return an offset to the counter value - * so we can update the structure without reencoding it. - */ + int ret = 0; + EVP_KDF_CTX *kctx = NULL; + EVP_KDF *kdf = NULL; + OSSL_PARAM params[5], *p = params; + const char *mdname = EVP_MD_get0_name(md); -static int dh_sharedinfo_encode(unsigned char **pder, unsigned char **pctr, - ASN1_OBJECT *key_oid, size_t outlen, - const unsigned char *ukm, size_t ukmlen) -{ - unsigned char *p; - int derlen; - long tlen; - /* "magic" value to check offset is sane */ - static unsigned char ctr[4] = { 0xF3, 0x17, 0x22, 0x53 }; - X509_ALGOR atmp; - ASN1_OCTET_STRING ctr_oct, ukm_oct, *pukm_oct; - ASN1_TYPE ctr_atype; - if (ukmlen > DH_KDF_MAX || outlen > DH_KDF_MAX) - return 0; - ctr_oct.data = ctr; - ctr_oct.length = 4; - ctr_oct.flags = 0; - ctr_oct.type = V_ASN1_OCTET_STRING; - ctr_atype.type = V_ASN1_OCTET_STRING; - ctr_atype.value.octet_string = &ctr_oct; - atmp.algorithm = key_oid; - atmp.parameter = &ctr_atype; - if (ukm) { - ukm_oct.type = V_ASN1_OCTET_STRING; - ukm_oct.flags = 0; - ukm_oct.data = (unsigned char *)ukm; - ukm_oct.length = ukmlen; - pukm_oct = &ukm_oct; - } else - pukm_oct = NULL; - derlen = CMS_SharedInfo_encode(pder, &atmp, pukm_oct, outlen); - if (derlen <= 0) - return 0; - p = *pder; - tlen = derlen; - if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)) - return 0; - if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)) - return 0; - if (!skip_asn1(&p, &tlen, V_ASN1_OBJECT)) - return 0; - if (!skip_asn1(&p, &tlen, V_ASN1_OCTET_STRING)) + kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_X942KDF_ASN1, propq); + if (kdf == NULL) return 0; - if (CRYPTO_memcmp(p, ctr, 4)) - return 0; - *pctr = p; - return derlen; + kctx = EVP_KDF_CTX_new(kdf); + if (kctx == NULL) + goto err; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + (unsigned char *)Z, Zlen); + if (ukm != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_UKM, + (unsigned char *)ukm, ukmlen); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG, + (char *)cek_alg, 0); + *p = OSSL_PARAM_construct_end(); + ret = EVP_KDF_derive(kctx, out, outlen, params) > 0; +err: + EVP_KDF_CTX_free(kctx); + EVP_KDF_free(kdf); + return ret; } +#if !defined(FIPS_MODULE) int DH_KDF_X9_42(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, ASN1_OBJECT *key_oid, const unsigned char *ukm, size_t ukmlen, const EVP_MD *md) { - EVP_MD_CTX *mctx = NULL; - int rv = 0; - unsigned int i; - size_t mdlen; - unsigned char *der = NULL, *ctr; - int derlen; - if (Zlen > DH_KDF_MAX) - return 0; - mctx = EVP_MD_CTX_new(); - if (mctx == NULL) + char key_alg[OSSL_MAX_NAME_SIZE]; + const OSSL_PROVIDER *prov = EVP_MD_get0_provider(md); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + + if (OBJ_obj2txt(key_alg, sizeof(key_alg), key_oid, 0) <= 0) return 0; - mdlen = EVP_MD_size(md); - derlen = dh_sharedinfo_encode(&der, &ctr, key_oid, outlen, ukm, ukmlen); - if (derlen == 0) - goto err; - for (i = 1;; i++) { - unsigned char mtmp[EVP_MAX_MD_SIZE]; - if (!EVP_DigestInit_ex(mctx, md, NULL) - || !EVP_DigestUpdate(mctx, Z, Zlen)) - goto err; - ctr[3] = i & 0xFF; - ctr[2] = (i >> 8) & 0xFF; - ctr[1] = (i >> 16) & 0xFF; - ctr[0] = (i >> 24) & 0xFF; - if (!EVP_DigestUpdate(mctx, der, derlen)) - goto err; - if (outlen >= mdlen) { - if (!EVP_DigestFinal(mctx, out, NULL)) - goto err; - outlen -= mdlen; - if (outlen == 0) - break; - out += mdlen; - } else { - if (!EVP_DigestFinal(mctx, mtmp, NULL)) - goto err; - memcpy(out, mtmp, outlen); - OPENSSL_cleanse(mtmp, mdlen); - break; - } - } - rv = 1; - err: - OPENSSL_free(der); - EVP_MD_CTX_free(mctx); - return rv; + + return ossl_dh_kdf_X9_42_asn1(out, outlen, Z, Zlen, key_alg, + ukm, ukmlen, md, libctx, NULL); } -#endif +#endif /* !defined(FIPS_MODULE) */ diff --git a/crypto/openssl/crypto/dh/dh_key.c b/crypto/openssl/crypto/dh/dh_key.c index 117f2fa883ff..4e9705beef73 100644 --- a/crypto/openssl/crypto/dh/dh_key.c +++ b/crypto/openssl/crypto/dh/dh_key.c @@ -1,28 +1,104 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include "dh_local.h" #include "crypto/bn.h" +#include "crypto/dh.h" +#include "crypto/security_bits.h" + +#ifdef FIPS_MODULE +# define MIN_STRENGTH 112 +#else +# define MIN_STRENGTH 80 +#endif static int generate_key(DH *dh); -static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); static int dh_init(DH *dh); static int dh_finish(DH *dh); -int DH_generate_key(DH *dh) +/* + * See SP800-56Ar3 Section 5.7.1.1 + * Finite Field Cryptography Diffie-Hellman (FFC DH) Primitive + */ +int ossl_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) { - return dh->meth->generate_key(dh); + BN_CTX *ctx = NULL; + BN_MONT_CTX *mont = NULL; + BIGNUM *z = NULL, *pminus1; + int ret = -1; + + if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) { + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); + goto err; + } + + if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) { + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL); + return 0; + } + + ctx = BN_CTX_new_ex(dh->libctx); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + pminus1 = BN_CTX_get(ctx); + z = BN_CTX_get(ctx); + if (z == NULL) + goto err; + + if (dh->priv_key == NULL) { + ERR_raise(ERR_LIB_DH, DH_R_NO_PRIVATE_VALUE); + goto err; + } + + if (dh->flags & DH_FLAG_CACHE_MONT_P) { + mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, + dh->lock, dh->params.p, ctx); + BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); + if (!mont) + goto err; + } + + /* (Step 1) Z = pub_key^priv_key mod p */ + if (!dh->meth->bn_mod_exp(dh, z, pub_key, dh->priv_key, dh->params.p, ctx, + mont)) { + ERR_raise(ERR_LIB_DH, ERR_R_BN_LIB); + goto err; + } + + /* (Step 2) Error if z <= 1 or z = p - 1 */ + if (BN_copy(pminus1, dh->params.p) == NULL + || !BN_sub_word(pminus1, 1) + || BN_cmp(z, BN_value_one()) <= 0 + || BN_cmp(z, pminus1) == 0) { + ERR_raise(ERR_LIB_DH, DH_R_INVALID_SECRET); + goto err; + } + + /* return the padded key, i.e. same number of bytes as the modulus */ + ret = BN_bn2binpad(z, key, BN_num_bytes(dh->params.p)); + err: + BN_clear(z); /* (Step 2) destroy intermediate values */ + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; } /*- @@ -35,7 +111,12 @@ int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) volatile size_t npad = 0, mask = 1; /* compute the key; ret is constant unless compute_key is external */ - if ((ret = dh->meth->compute_key(key, pub_key, dh)) <= 0) +#ifdef FIPS_MODULE + ret = ossl_dh_compute_key(key, pub_key, dh); +#else + ret = dh->meth->compute_key(key, pub_key, dh); +#endif + if (ret <= 0) return ret; /* count leading zero bytes, yet still touch all bytes */ @@ -59,10 +140,14 @@ int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) int rv, pad; /* rv is constant unless compute_key is external */ +#ifdef FIPS_MODULE + rv = ossl_dh_compute_key(key, pub_key, dh); +#else rv = dh->meth->compute_key(key, pub_key, dh); +#endif if (rv <= 0) return rv; - pad = BN_num_bytes(dh->p) - rv; + pad = BN_num_bytes(dh->params.p) - rv; /* pad is constant (zero) unless compute_key is external */ if (pad > 0) { memmove(key + pad, key, rv); @@ -74,7 +159,7 @@ int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) static DH_METHOD dh_ossl = { "OpenSSL DH Method", generate_key, - compute_key, + ossl_dh_compute_key, dh_bn_mod_exp, dh_init, dh_finish, @@ -90,31 +175,105 @@ const DH_METHOD *DH_OpenSSL(void) return &dh_ossl; } +const DH_METHOD *DH_get_default_method(void) +{ + return default_DH_method; +} + +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); +} + +static int dh_init(DH *dh) +{ + dh->flags |= DH_FLAG_CACHE_MONT_P; + ossl_ffc_params_init(&dh->params); + dh->dirty_cnt++; + return 1; +} + +static int dh_finish(DH *dh) +{ + BN_MONT_CTX_free(dh->method_mont_p); + return 1; +} + +#ifndef FIPS_MODULE void DH_set_default_method(const DH_METHOD *meth) { default_DH_method = meth; } +#endif /* FIPS_MODULE */ -const DH_METHOD *DH_get_default_method(void) +int DH_generate_key(DH *dh) { - return default_DH_method; +#ifdef FIPS_MODULE + return generate_key(dh); +#else + return dh->meth->generate_key(dh); +#endif +} + +int ossl_dh_generate_public_key(BN_CTX *ctx, const DH *dh, + const BIGNUM *priv_key, BIGNUM *pub_key) +{ + int ret = 0; + BIGNUM *prk = BN_new(); + BN_MONT_CTX *mont = NULL; + + if (prk == NULL) + return 0; + + if (dh->flags & DH_FLAG_CACHE_MONT_P) { + /* + * We take the input DH as const, but we lie, because in some cases we + * want to get a hold of its Montgomery context. + * + * We cast to remove the const qualifier in this case, it should be + * fine... + */ + BN_MONT_CTX **pmont = (BN_MONT_CTX **)&dh->method_mont_p; + + mont = BN_MONT_CTX_set_locked(pmont, dh->lock, dh->params.p, ctx); + if (mont == NULL) + goto err; + } + BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); + + /* pub_key = g^priv_key mod p */ + if (!dh->meth->bn_mod_exp(dh, pub_key, dh->params.g, prk, dh->params.p, + ctx, mont)) + goto err; + ret = 1; +err: + BN_clear_free(prk); + return ret; } static int generate_key(DH *dh) { int ok = 0; int generate_new_key = 0; +#ifndef FIPS_MODULE unsigned l; +#endif BN_CTX *ctx = NULL; - BN_MONT_CTX *mont = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; - if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { - DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE); + if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) { + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); return 0; } - ctx = BN_CTX_new(); + if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) { + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL); + return 0; + } + + ctx = BN_CTX_new_ex(dh->libctx); if (ctx == NULL) goto err; @@ -123,68 +282,85 @@ static int generate_key(DH *dh) if (priv_key == NULL) goto err; generate_new_key = 1; - } else + } else { priv_key = dh->priv_key; + } if (dh->pub_key == NULL) { pub_key = BN_new(); if (pub_key == NULL) goto err; - } else + } else { pub_key = dh->pub_key; - - if (dh->flags & DH_FLAG_CACHE_MONT_P) { - mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, - dh->lock, dh->p, ctx); - if (!mont) - goto err; } - if (generate_new_key) { - if (dh->q) { - do { - if (!BN_priv_rand_range(priv_key, dh->q)) - goto err; - } - while (BN_is_zero(priv_key) || BN_is_one(priv_key)); + /* Is it an approved safe prime ?*/ + if (DH_get_nid(dh) != NID_undef) { + int max_strength = + ossl_ifc_ffc_compute_security_bits(BN_num_bits(dh->params.p)); + + if (dh->params.q == NULL + || dh->length > BN_num_bits(dh->params.q)) + goto err; + /* dh->length = maximum bit length of generated private key */ + if (!ossl_ffc_generate_private_key(ctx, &dh->params, dh->length, + max_strength, priv_key)) + goto err; } else { - /* secret exponent length */ - 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)) +#ifdef FIPS_MODULE + if (dh->params.q == NULL) 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)) +#else + if (dh->params.q == NULL) { + /* secret exponent length, must satisfy 2^(l-1) <= p */ + if (dh->length != 0 + && dh->length >= BN_num_bits(dh->params.p)) + goto err; + l = dh->length ? dh->length : BN_num_bits(dh->params.p) - 1; + if (!BN_priv_rand_ex(priv_key, l, BN_RAND_TOP_ONE, + BN_RAND_BOTTOM_ANY, 0, ctx)) + 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->params.g, DH_GENERATOR_2) + && !BN_is_bit_set(dh->params.p, 2)) { + /* clear bit 0, since it won't be a secret anyway */ + if (!BN_clear_bit(priv_key, 0)) + goto err; + } + } else +#endif + { + /* Do a partial check for invalid p, q, g */ + if (!ossl_ffc_params_simple_validate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, NULL)) + goto err; + /* + * For FFC FIPS 186-4 keygen + * security strength s = 112, + * Max Private key size N = len(q) + */ + if (!ossl_ffc_generate_private_key(ctx, &dh->params, + BN_num_bits(dh->params.q), + MIN_STRENGTH, + priv_key)) goto err; } } } - { - BIGNUM *prk = BN_new(); - - if (prk == NULL) - goto err; - 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_clear_free(prk); - goto err; - } - /* We MUST free prk before any further use of priv_key */ - BN_clear_free(prk); - } + if (!ossl_dh_generate_public_key(ctx, dh, priv_key, pub_key)) + goto err; dh->pub_key = pub_key; dh->priv_key = priv_key; + dh->dirty_cnt++; ok = 1; err: if (ok != 1) - DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_DH, ERR_R_BN_LIB); if (pub_key != dh->pub_key) BN_free(pub_key); @@ -194,73 +370,73 @@ static int generate_key(DH *dh) return ok; } -static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +int ossl_dh_buf2key(DH *dh, const unsigned char *buf, size_t len) { - BN_CTX *ctx = NULL; - BN_MONT_CTX *mont = NULL; - BIGNUM *tmp; - int ret = -1; - int check_result; - - if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { - DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE); - goto err; - } + int err_reason = DH_R_BN_ERROR; + BIGNUM *pubkey = NULL; + const BIGNUM *p; + int ret; - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); - if (tmp == NULL) + if ((pubkey = BN_bin2bn(buf, len, NULL)) == NULL) goto err; - - if (dh->priv_key == NULL) { - DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE); + DH_get0_pqg(dh, &p, NULL, NULL); + if (p == NULL || BN_num_bytes(p) == 0) { + err_reason = DH_R_NO_PARAMETERS_SET; goto err; } - - if (dh->flags & DH_FLAG_CACHE_MONT_P) { - mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, - dh->lock, dh->p, ctx); - BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); - if (!mont) - goto err; - } - - if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) { - DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY); + /* Prevent small subgroup attacks per RFC 8446 Section 4.2.8.1 */ + if (!ossl_dh_check_pub_key_partial(dh, pubkey, &ret)) { + err_reason = DH_R_INVALID_PUBKEY; goto err; } - - if (!dh-> - meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, mont)) { - DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB); + if (DH_set0_key(dh, pubkey, NULL) != 1) goto err; - } - - ret = BN_bn2binpad(tmp, key, BN_num_bytes(dh->p)); - err: - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return ret; -} - -static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); -} - -static int dh_init(DH *dh) -{ - dh->flags |= DH_FLAG_CACHE_MONT_P; return 1; +err: + ERR_raise(ERR_LIB_DH, err_reason); + BN_free(pubkey); + return 0; } -static int dh_finish(DH *dh) +size_t ossl_dh_key2buf(const DH *dh, unsigned char **pbuf_out, size_t size, + int alloc) { - BN_MONT_CTX_free(dh->method_mont_p); - return 1; + const BIGNUM *pubkey; + unsigned char *pbuf = NULL; + const BIGNUM *p; + int p_size; + + DH_get0_pqg(dh, &p, NULL, NULL); + DH_get0_key(dh, &pubkey, NULL); + if (p == NULL || pubkey == NULL + || (p_size = BN_num_bytes(p)) == 0 + || BN_num_bytes(pubkey) == 0) { + ERR_raise(ERR_LIB_DH, DH_R_INVALID_PUBKEY); + return 0; + } + if (pbuf_out != NULL && (alloc || *pbuf_out != NULL)) { + if (!alloc) { + if (size >= (size_t)p_size) + pbuf = *pbuf_out; + } else { + pbuf = OPENSSL_malloc(p_size); + } + + if (pbuf == NULL) { + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + return 0; + } + /* + * As per Section 4.2.8.1 of RFC 8446 left pad public + * key with zeros to the size of p + */ + if (BN_bn2binpad(pubkey, pbuf, p_size) < 0) { + if (alloc) + OPENSSL_free(pbuf); + ERR_raise(ERR_LIB_DH, DH_R_BN_ERROR); + return 0; + } + *pbuf_out = pbuf; + } + return p_size; } diff --git a/crypto/openssl/crypto/dh/dh_lib.c b/crypto/openssl/crypto/dh/dh_lib.c index 04b79d355ca4..29cda5d7bfa8 100644 --- a/crypto/openssl/crypto/dh/dh_lib.c +++ b/crypto/openssl/crypto/dh/dh_lib.c @@ -1,19 +1,34 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include +#include +#ifndef FIPS_MODULE +# include +#endif +#include +#include #include "internal/cryptlib.h" #include "internal/refcount.h" -#include +#include "crypto/evp.h" +#include "crypto/dh.h" #include "dh_local.h" -#include +static DH *dh_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx); + +#ifndef FIPS_MODULE int DH_set_method(DH *dh, const DH_METHOD *meth) { /* @@ -34,34 +49,52 @@ int DH_set_method(DH *dh, const DH_METHOD *meth) return 1; } +const DH_METHOD *ossl_dh_get_method(const DH *dh) +{ + return dh->meth; +} +# ifndef OPENSSL_NO_DEPRECATED_3_0 DH *DH_new(void) { - return DH_new_method(NULL); + return dh_new_intern(NULL, NULL); } +# endif DH *DH_new_method(ENGINE *engine) +{ + return dh_new_intern(engine, NULL); +} +#endif /* !FIPS_MODULE */ + +DH *ossl_dh_new_ex(OSSL_LIB_CTX *libctx) +{ + return dh_new_intern(NULL, libctx); +} + +static DH *dh_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) { DH *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); return NULL; } ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } + ret->libctx = libctx; ret->meth = DH_get_default_method(); -#ifndef OPENSSL_NO_ENGINE +#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE) ret->flags = ret->meth->flags; /* early default init */ if (engine) { if (!ENGINE_init(engine)) { - DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_DH, ERR_R_ENGINE_LIB); goto err; } ret->engine = engine; @@ -70,7 +103,7 @@ DH *DH_new_method(ENGINE *engine) if (ret->engine) { ret->meth = ENGINE_get_DH(ret->engine); if (ret->meth == NULL) { - DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_DH, ERR_R_ENGINE_LIB); goto err; } } @@ -78,11 +111,13 @@ DH *DH_new_method(ENGINE *engine) ret->flags = ret->meth->flags; +#ifndef FIPS_MODULE if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data)) goto err; +#endif /* FIPS_MODULE */ if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - DHerr(DH_F_DH_NEW_METHOD, ERR_R_INIT_FAIL); + ERR_raise(ERR_LIB_DH, ERR_R_INIT_FAIL); goto err; } @@ -108,20 +143,16 @@ void DH_free(DH *r) if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE +#if !defined(FIPS_MODULE) +# if !defined(OPENSSL_NO_ENGINE) ENGINE_finish(r->engine); -#endif - +# endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); +#endif CRYPTO_THREAD_lock_free(r->lock); - BN_clear_free(r->p); - BN_clear_free(r->g); - BN_clear_free(r->q); - BN_clear_free(r->j); - OPENSSL_free(r->seed); - BN_clear_free(r->counter); + ossl_ffc_params_cleanup(&r->params); BN_clear_free(r->pub_key); BN_clear_free(r->priv_key); OPENSSL_free(r); @@ -139,76 +170,71 @@ int DH_up_ref(DH *r) return ((i > 1) ? 1 : 0); } +void ossl_dh_set0_libctx(DH *d, OSSL_LIB_CTX *libctx) +{ + d->libctx = libctx; +} + +#ifndef FIPS_MODULE int DH_set_ex_data(DH *d, int idx, void *arg) { return CRYPTO_set_ex_data(&d->ex_data, idx, arg); } -void *DH_get_ex_data(DH *d, int idx) +void *DH_get_ex_data(const DH *d, int idx) { return CRYPTO_get_ex_data(&d->ex_data, idx); } +#endif int DH_bits(const DH *dh) { - return BN_num_bits(dh->p); + if (dh->params.p != NULL) + return BN_num_bits(dh->params.p); + return -1; } int DH_size(const DH *dh) { - return BN_num_bytes(dh->p); + if (dh->params.p != NULL) + return BN_num_bytes(dh->params.p); + return -1; } int DH_security_bits(const DH *dh) { int N; - if (dh->q) - N = BN_num_bits(dh->q); + + if (dh->params.q != NULL) + N = BN_num_bits(dh->params.q); else if (dh->length) N = dh->length; else N = -1; - return BN_security_bits(BN_num_bits(dh->p), N); + if (dh->params.p != NULL) + return BN_security_bits(BN_num_bits(dh->params.p), N); + return -1; } - void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) { - if (p != NULL) - *p = dh->p; - if (q != NULL) - *q = dh->q; - if (g != NULL) - *g = dh->g; + ossl_ffc_params_get0_pqg(&dh->params, p, q, g); } int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) { - /* If the fields p and g in d are NULL, the corresponding input + /* + * If the fields p and g in dh are NULL, the corresponding input * parameters MUST be non-NULL. q may remain NULL. */ - if ((dh->p == NULL && p == NULL) - || (dh->g == NULL && g == NULL)) + if ((dh->params.p == NULL && p == NULL) + || (dh->params.g == NULL && g == NULL)) return 0; - if (p != NULL) { - BN_free(dh->p); - dh->p = p; - } - if (q != NULL) { - BN_free(dh->q); - dh->q = q; - } - if (g != NULL) { - BN_free(dh->g); - dh->g = g; - } - - if (q != NULL) { - dh->length = BN_num_bits(q); - } - + ossl_ffc_params_set0_pqg(&dh->params, p, q, g); + ossl_dh_cache_named_group(dh); + dh->dirty_cnt++; return 1; } @@ -220,6 +246,7 @@ long DH_get_length(const DH *dh) int DH_set_length(DH *dh, long length) { dh->length = length; + dh->dirty_cnt++; return 1; } @@ -242,22 +269,23 @@ int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) dh->priv_key = priv_key; } + dh->dirty_cnt++; return 1; } const BIGNUM *DH_get0_p(const DH *dh) { - return dh->p; + return dh->params.p; } const BIGNUM *DH_get0_q(const DH *dh) { - return dh->q; + return dh->params.q; } const BIGNUM *DH_get0_g(const DH *dh) { - return dh->g; + return dh->params.g; } const BIGNUM *DH_get0_priv_key(const DH *dh) @@ -285,7 +313,18 @@ void DH_set_flags(DH *dh, int flags) dh->flags |= flags; } +#ifndef FIPS_MODULE ENGINE *DH_get0_engine(DH *dh) { return dh->engine; } +#endif /*FIPS_MODULE */ + +FFC_PARAMS *ossl_dh_get0_params(DH *dh) +{ + return &dh->params; +} +int ossl_dh_get0_nid(const DH *dh) +{ + return dh->params.nid; +} diff --git a/crypto/openssl/crypto/dh/dh_local.h b/crypto/openssl/crypto/dh/dh_local.h index 0a8391a6c004..1ff075e3dc1d 100644 --- a/crypto/openssl/crypto/dh/dh_local.h +++ b/crypto/openssl/crypto/dh/dh_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,6 +9,9 @@ #include #include "internal/refcount.h" +#include "internal/ffc.h" + +#define DH_MIN_MODULUS_BITS 512 struct dh_st { /* @@ -17,24 +20,24 @@ struct dh_st { */ int pad; int version; - BIGNUM *p; - BIGNUM *g; - int32_t length; /* optional */ + FFC_PARAMS params; + /* max generated private key length (can be less than len(q)) */ + int32_t length; BIGNUM *pub_key; /* g^x % p */ BIGNUM *priv_key; /* x */ int flags; BN_MONT_CTX *method_mont_p; - /* Place holders if we want to do X9.42 DH */ - BIGNUM *q; - BIGNUM *j; - unsigned char *seed; - int seedlen; - BIGNUM *counter; CRYPTO_REF_COUNT references; +#ifndef FIPS_MODULE CRYPTO_EX_DATA ex_data; - const DH_METHOD *meth; ENGINE *engine; +#endif + OSSL_LIB_CTX *libctx; + const DH_METHOD *meth; CRYPTO_RWLOCK *lock; + + /* Provider data */ + size_t dirty_cnt; /* If any key material changes, increment this */ }; struct dh_method { diff --git a/crypto/openssl/crypto/dh/dh_meth.c b/crypto/openssl/crypto/dh/dh_meth.c index 8a54a8108fc3..5c15cd2b8cc2 100644 --- a/crypto/openssl/crypto/dh/dh_meth.c +++ b/crypto/openssl/crypto/dh/dh_meth.c @@ -1,12 +1,18 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "dh_local.h" #include #include @@ -25,7 +31,7 @@ DH_METHOD *DH_meth_new(const char *name, int flags) OPENSSL_free(dhm); } - DHerr(DH_F_DH_METH_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); return NULL; } @@ -51,7 +57,7 @@ DH_METHOD *DH_meth_dup(const DH_METHOD *dhm) OPENSSL_free(ret); } - DHerr(DH_F_DH_METH_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); return NULL; } @@ -65,7 +71,7 @@ int DH_meth_set1_name(DH_METHOD *dhm, const char *name) char *tmpname = OPENSSL_strdup(name); if (tmpname == NULL) { - DHerr(DH_F_DH_METH_SET1_NAME, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/crypto/openssl/crypto/dh/dh_pmeth.c b/crypto/openssl/crypto/dh/dh_pmeth.c index 1fd94deb4731..f201eede0df4 100644 --- a/crypto/openssl/crypto/dh/dh_pmeth.c +++ b/crypto/openssl/crypto/dh/dh_pmeth.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DH & DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -24,12 +30,11 @@ typedef struct { /* Parameter gen parameters */ int prime_len; int generator; - int use_dsa; + int paramgen_type; int subprime_len; int pad; /* message digest used for parameter generation */ const EVP_MD *md; - int rfc5114_param; int param_nid; /* Keygen callback info */ int gentmp[2]; @@ -51,7 +56,7 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx) DH_PKEY_CTX *dctx; if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) { - DHerr(DH_F_PKEY_DH_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); return 0; } dctx->prime_len = 2048; @@ -69,6 +74,7 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx) static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) { DH_PKEY_CTX *dctx = ctx->data; + if (dctx != NULL) { OPENSSL_free(dctx->kdf_ukm); ASN1_OBJECT_free(dctx->kdf_oid); @@ -77,9 +83,10 @@ static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) } -static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) { DH_PKEY_CTX *dctx, *sctx; + if (!pkey_dh_init(dst)) return 0; sctx = src->data; @@ -87,10 +94,9 @@ static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) dctx->prime_len = sctx->prime_len; dctx->subprime_len = sctx->subprime_len; dctx->generator = sctx->generator; - dctx->use_dsa = sctx->use_dsa; + dctx->paramgen_type = sctx->paramgen_type; dctx->pad = sctx->pad; dctx->md = sctx->md; - dctx->rfc5114_param = sctx->rfc5114_param; dctx->param_nid = sctx->param_nid; dctx->kdf_type = sctx->kdf_type; @@ -119,7 +125,7 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN: - if (dctx->use_dsa == 0) + if (dctx->paramgen_type == DH_PARAMGEN_TYPE_GENERATOR) return -2; dctx->subprime_len = p1; return 1; @@ -129,30 +135,30 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: - if (dctx->use_dsa) + if (dctx->paramgen_type != DH_PARAMGEN_TYPE_GENERATOR) return -2; dctx->generator = p1; return 1; case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE: #ifdef OPENSSL_NO_DSA - if (p1 != 0) + if (p1 != DH_PARAMGEN_TYPE_GENERATOR) return -2; #else if (p1 < 0 || p1 > 2) return -2; #endif - dctx->use_dsa = p1; + dctx->paramgen_type = p1; return 1; case EVP_PKEY_CTRL_DH_RFC5114: if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef) return -2; - dctx->rfc5114_param = p1; + dctx->param_nid = p1; return 1; case EVP_PKEY_CTRL_DH_NID: - if (p1 <= 0 || dctx->rfc5114_param != 0) + if (p1 <= 0 || dctx->param_nid != NID_undef) return -2; dctx->param_nid = p1; return 1; @@ -164,11 +170,7 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_DH_KDF_TYPE: if (p1 == -2) return dctx->kdf_type; -#ifdef OPENSSL_NO_CMS - if (p1 != EVP_PKEY_DH_KDF_NONE) -#else if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42) -#endif return -2; dctx->kdf_type = p1; return 1; @@ -229,11 +231,12 @@ static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, } if (strcmp(type, "dh_rfc5114") == 0) { DH_PKEY_CTX *dctx = ctx->data; - int len; - len = atoi(value); - if (len < 0 || len > 3) + int id; + + id = atoi(value); + if (id < 0 || id > 3) return -2; - dctx->rfc5114_param = len; + dctx->param_nid = id; return 1; } if (strcmp(type, "dh_param") == 0) { @@ -241,7 +244,7 @@ static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, int nid = OBJ_sn2nid(value); if (nid == NID_undef) { - DHerr(DH_F_PKEY_DH_CTRL_STR, DH_R_INVALID_PARAMETER_NAME); + ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME); return -2; } dctx->param_nid = nid; @@ -270,116 +273,91 @@ static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, return -2; } -#ifndef OPENSSL_NO_DSA - -extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, - const EVP_MD *evpmd, - const unsigned char *seed_in, size_t seed_len, - unsigned char *seed_out, int *counter_ret, - unsigned long *h_ret, BN_GENCB *cb); - -extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, - const EVP_MD *evpmd, - const unsigned char *seed_in, - size_t seed_len, int idx, - unsigned char *seed_out, int *counter_ret, - unsigned long *h_ret, BN_GENCB *cb); - -static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb) +static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx, + BN_GENCB *pcb) { - DSA *ret; + DH *ret; int rv = 0; + int res; int prime_len = dctx->prime_len; int subprime_len = dctx->subprime_len; - const EVP_MD *md = dctx->md; - if (dctx->use_dsa > 2) + + if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4) return NULL; - ret = DSA_new(); + ret = DH_new(); if (ret == NULL) return NULL; + if (subprime_len == -1) { if (prime_len >= 2048) subprime_len = 256; else subprime_len = 160; } - if (md == NULL) { - if (prime_len >= 2048) - md = EVP_sha256(); - else - md = EVP_sha1(); - } - if (dctx->use_dsa == 1) - rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md, - NULL, 0, NULL, NULL, NULL, pcb); - else if (dctx->use_dsa == 2) - rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md, - NULL, 0, -1, NULL, NULL, NULL, pcb); + + if (dctx->md != NULL) + ossl_ffc_set_digest(&ret->params, EVP_MD_get0_name(dctx->md), NULL); + +# ifndef FIPS_MODULE + if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2) + rv = ossl_ffc_params_FIPS186_2_generate(libctx, &ret->params, + FFC_PARAM_TYPE_DH, + prime_len, subprime_len, &res, + pcb); + else +# endif + /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */ + if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) + rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params, + FFC_PARAM_TYPE_DH, + prime_len, subprime_len, &res, + pcb); if (rv <= 0) { - DSA_free(ret); + DH_free(ret); return NULL; } return ret; } -#endif - -static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey) { DH *dh = NULL; DH_PKEY_CTX *dctx = ctx->data; - BN_GENCB *pcb; + BN_GENCB *pcb = NULL; int ret; - if (dctx->rfc5114_param) { - switch (dctx->rfc5114_param) { - case 1: - dh = DH_get_1024_160(); - break; - case 2: - dh = DH_get_2048_224(); - break; + /* + * Look for a safe prime group for key establishment. Which uses + * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX). + * RFC_5114 is also handled here for param_nid = (1..3) + */ + if (dctx->param_nid != NID_undef) { + int type = dctx->param_nid <= 3 ? EVP_PKEY_DHX : EVP_PKEY_DH; - case 3: - dh = DH_get_2048_256(); - break; - - default: - return -2; - } - EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); - return 1; - } - - if (dctx->param_nid != 0) { if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL) return 0; - EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh); + EVP_PKEY_assign(pkey, type, dh); return 1; } - if (ctx->pkey_gencb) { + if (ctx->pkey_gencb != NULL) { pcb = BN_GENCB_new(); if (pcb == NULL) return 0; evp_pkey_set_cb_translate(pcb, ctx); - } else - pcb = NULL; -#ifndef OPENSSL_NO_DSA - if (dctx->use_dsa) { - DSA *dsa_dh; - dsa_dh = dsa_dh_generate(dctx, pcb); + } +# ifdef FIPS_MODULE + dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4; +# endif /* FIPS_MODULE */ + if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) { + dh = ffc_params_generate(NULL, dctx, pcb); BN_GENCB_free(pcb); - if (dsa_dh == NULL) - return 0; - dh = DSA_dup_DH(dsa_dh); - DSA_free(dsa_dh); - if (!dh) + if (dh == NULL) return 0; EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); return 1; } -#endif dh = DH_new(); if (dh == NULL) { BN_GENCB_free(pcb); @@ -400,11 +378,11 @@ static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) DH_PKEY_CTX *dctx = ctx->data; DH *dh = NULL; - if (ctx->pkey == NULL && dctx->param_nid == 0) { - DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET); + if (ctx->pkey == NULL && dctx->param_nid == NID_undef) { + ERR_raise(ERR_LIB_DH, DH_R_NO_PARAMETERS_SET); return 0; } - if (dctx->param_nid != 0) + if (dctx->param_nid != NID_undef) dh = DH_new_by_nid(dctx->param_nid); else dh = DH_new(); @@ -414,7 +392,7 @@ static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) /* Note: if error return, pkey is freed by parent routine */ if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey)) return 0; - return DH_generate_key(pkey->pkey.dh); + return DH_generate_key((DH *)EVP_PKEY_get0_DH(pkey)); } static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, @@ -422,33 +400,40 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, { int ret; DH *dh; + const DH *dhpub; DH_PKEY_CTX *dctx = ctx->data; - BIGNUM *dhpub; - if (!ctx->pkey || !ctx->peerkey) { - DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); + BIGNUM *dhpubbn; + + if (ctx->pkey == NULL || ctx->peerkey == NULL) { + ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET); + return 0; + } + dh = (DH *)EVP_PKEY_get0_DH(ctx->pkey); + dhpub = EVP_PKEY_get0_DH(ctx->peerkey); + if (dhpub == NULL) { + ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET); return 0; } - dh = ctx->pkey->pkey.dh; - dhpub = ctx->peerkey->pkey.dh->pub_key; + dhpubbn = dhpub->pub_key; if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) { if (key == NULL) { *keylen = DH_size(dh); return 1; } if (dctx->pad) - ret = DH_compute_key_padded(key, dhpub, dh); + ret = DH_compute_key_padded(key, dhpubbn, dh); else - ret = DH_compute_key(key, dhpub, dh); + ret = DH_compute_key(key, dhpubbn, dh); if (ret < 0) return ret; *keylen = ret; return 1; } -#ifndef OPENSSL_NO_CMS else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { unsigned char *Z = NULL; - size_t Zlen = 0; + int Zlen = 0; + if (!dctx->kdf_outlen || !dctx->kdf_oid) return 0; if (key == NULL) { @@ -458,12 +443,13 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, if (*keylen != dctx->kdf_outlen) return 0; ret = 0; - Zlen = DH_size(dh); - Z = OPENSSL_malloc(Zlen); - if (Z == NULL) { - goto err; + if ((Zlen = DH_size(dh)) <= 0) + return 0; + if ((Z = OPENSSL_malloc(Zlen)) == NULL) { + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + return 0; } - if (DH_compute_key_padded(Z, dhpub, dh) <= 0) + if (DH_compute_key_padded(Z, dhpubbn, dh) <= 0) goto err; if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid, dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) @@ -474,11 +460,10 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, OPENSSL_clear_free(Z, Zlen); return ret; } -#endif return 0; } -const EVP_PKEY_METHOD dh_pkey_meth = { +static const EVP_PKEY_METHOD dh_pkey_meth = { EVP_PKEY_DH, 0, pkey_dh_init, @@ -512,7 +497,12 @@ const EVP_PKEY_METHOD dh_pkey_meth = { pkey_dh_ctrl_str }; -const EVP_PKEY_METHOD dhx_pkey_meth = { +const EVP_PKEY_METHOD *ossl_dh_pkey_method(void) +{ + return &dh_pkey_meth; +} + +static const EVP_PKEY_METHOD dhx_pkey_meth = { EVP_PKEY_DHX, 0, pkey_dh_init, @@ -545,3 +535,8 @@ const EVP_PKEY_METHOD dhx_pkey_meth = { pkey_dh_ctrl, pkey_dh_ctrl_str }; + +const EVP_PKEY_METHOD *ossl_dhx_pkey_method(void) +{ + return &dhx_pkey_meth; +} diff --git a/crypto/openssl/crypto/dh/dh_prn.c b/crypto/openssl/crypto/dh/dh_prn.c index aab1733db3b3..5d31254dcbc6 100644 --- a/crypto/openssl/crypto/dh/dh_prn.c +++ b/crypto/openssl/crypto/dh/dh_prn.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -19,7 +25,7 @@ int DHparams_print_fp(FILE *fp, const DH *x) int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - DHerr(DH_F_DHPARAMS_PRINT_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_DH, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); diff --git a/crypto/openssl/crypto/dh/dh_rfc5114.c b/crypto/openssl/crypto/dh/dh_rfc5114.c index e3603a05a322..7b1e0610bd71 100644 --- a/crypto/openssl/crypto/dh/dh_rfc5114.c +++ b/crypto/openssl/crypto/dh/dh_rfc5114.c @@ -1,12 +1,18 @@ /* - * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include "dh_local.h" @@ -26,10 +32,10 @@ DH *DH_get_##x(void) \ \ if (dh == NULL) \ return NULL; \ - dh->p = BN_dup(&_bignum_dh##x##_p); \ - dh->g = BN_dup(&_bignum_dh##x##_g); \ - dh->q = BN_dup(&_bignum_dh##x##_q); \ - if (dh->p == NULL || dh->q == NULL || dh->g == NULL) {\ + dh->params.p = BN_dup(&ossl_bignum_dh##x##_p); \ + dh->params.g = BN_dup(&ossl_bignum_dh##x##_g); \ + dh->params.q = BN_dup(&ossl_bignum_dh##x##_q); \ + if (dh->params.p == NULL || dh->params.q == NULL || dh->params.g == NULL) {\ DH_free(dh); \ return NULL; \ } \ diff --git a/crypto/openssl/crypto/dh/dh_rfc7919.c b/crypto/openssl/crypto/dh/dh_rfc7919.c deleted file mode 100644 index 03d30a1f5d59..000000000000 --- a/crypto/openssl/crypto/dh/dh_rfc7919.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" -#include "dh_local.h" -#include -#include -#include "crypto/bn_dh.h" - -static DH *dh_param_init(const BIGNUM *p, int32_t nbits) -{ - DH *dh = DH_new(); - if (dh == NULL) - return NULL; - dh->p = (BIGNUM *)p; - dh->g = (BIGNUM *)&_bignum_const_2; - dh->length = nbits; - return dh; -} - -DH *DH_new_by_nid(int nid) -{ - switch (nid) { - case NID_ffdhe2048: - return dh_param_init(&_bignum_ffdhe2048_p, 225); - case NID_ffdhe3072: - return dh_param_init(&_bignum_ffdhe3072_p, 275); - case NID_ffdhe4096: - return dh_param_init(&_bignum_ffdhe4096_p, 325); - case NID_ffdhe6144: - return dh_param_init(&_bignum_ffdhe6144_p, 375); - case NID_ffdhe8192: - return dh_param_init(&_bignum_ffdhe8192_p, 400); - default: - DHerr(DH_F_DH_NEW_BY_NID, DH_R_INVALID_PARAMETER_NID); - return NULL; - } -} - -int DH_get_nid(const DH *dh) -{ - int nid; - - if (BN_get_word(dh->g) != 2) - return NID_undef; - if (!BN_cmp(dh->p, &_bignum_ffdhe2048_p)) - nid = NID_ffdhe2048; - else if (!BN_cmp(dh->p, &_bignum_ffdhe3072_p)) - nid = NID_ffdhe3072; - else if (!BN_cmp(dh->p, &_bignum_ffdhe4096_p)) - nid = NID_ffdhe4096; - else if (!BN_cmp(dh->p, &_bignum_ffdhe6144_p)) - nid = NID_ffdhe6144; - else if (!BN_cmp(dh->p, &_bignum_ffdhe8192_p)) - nid = NID_ffdhe8192; - else - return NID_undef; - if (dh->q != NULL) { - BIGNUM *q = BN_dup(dh->p); - - /* Check q = p * 2 + 1 we already know q is odd, so just shift right */ - if (q == NULL || !BN_rshift1(q, q) || !BN_cmp(dh->q, q)) - nid = NID_undef; - BN_free(q); - } - return nid; -} diff --git a/crypto/openssl/crypto/dllmain.c b/crypto/openssl/crypto/dllmain.c index e8217893b9ed..48c0cd31227a 100644 --- a/crypto/openssl/crypto/dllmain.c +++ b/crypto/openssl/crypto/dllmain.c @@ -1,7 +1,7 @@ /* * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/dsa/build.info b/crypto/openssl/crypto/dsa/build.info index 2e759853a2a2..9a7d275c3500 100644 --- a/crypto/openssl/crypto/dsa/build.info +++ b/crypto/openssl/crypto/dsa/build.info @@ -1,5 +1,12 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - dsa_gen.c dsa_key.c dsa_lib.c dsa_asn1.c dsa_vrf.c dsa_sign.c \ - dsa_err.c dsa_ossl.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c \ + +$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_check.c \ + dsa_key.c dsa_backend.c dsa_gen.c + +SOURCE[../../libcrypto]=$COMMON\ + dsa_asn1.c dsa_err.c dsa_ameth.c dsa_pmeth.c dsa_prn.c \ dsa_meth.c +IF[{- !$disabled{'deprecated-0.9.8'} -}] + SOURCE[../../libcrypto]=dsa_depr.c +ENDIF +SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/openssl/crypto/dsa/dsa_ameth.c b/crypto/openssl/crypto/dsa/dsa_ameth.c index 2dcaa0815fd6..482b9e1e0aa7 100644 --- a/crypto/openssl/crypto/dsa/dsa_ameth.c +++ b/crypto/openssl/crypto/dsa/dsa_ameth.c @@ -1,23 +1,32 @@ /* - * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include -#include "internal/cryptlib.h" #include #include -#include "dsa_local.h" #include -#include +#include +#include +#include "internal/cryptlib.h" #include "crypto/asn1.h" +#include "crypto/dsa.h" #include "crypto/evp.h" +#include "internal/ffc.h" +#include "dsa_local.h" -static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +static int dsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) { const unsigned char *p, *pm; int pklen, pmlen; @@ -39,30 +48,31 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) pmlen = pstr->length; if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) { - DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); + ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR); goto err; } } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) { if ((dsa = DSA_new()) == NULL) { - DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); goto err; } } else { - DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR); + ERR_raise(ERR_LIB_DSA, DSA_R_PARAMETER_ENCODING_ERROR); goto err; } if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) { - DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); + ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR); goto err; } if ((dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) { - DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR); + ERR_raise(ERR_LIB_DSA, DSA_R_BN_DECODE_ERROR); goto err; } + dsa->dirty_cnt++; ASN1_INTEGER_free(public_key); EVP_PKEY_assign_DSA(pkey, dsa); return 1; @@ -85,15 +95,18 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) ASN1_OBJECT *aobj; dsa = pkey->pkey.dsa; - if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { + if (pkey->save_parameters + && dsa->params.p != NULL + && dsa->params.q != NULL + && dsa->params.g != NULL) { str = ASN1_STRING_new(); if (str == NULL) { - DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); goto err; } str->length = i2d_DSAparams(dsa, &str->data); if (str->length <= 0) { - DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); goto err; } ptype = V_ASN1_SEQUENCE; @@ -103,7 +116,7 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) pubint = BN_to_ASN1_INTEGER(dsa->pub_key, NULL); if (pubint == NULL) { - DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); goto err; } @@ -111,7 +124,7 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) ASN1_INTEGER_free(pubint); if (penclen <= 0) { - DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); goto err; } @@ -136,67 +149,14 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) static int dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) { - const unsigned char *p, *pm; - int pklen, pmlen; - int ptype; - const void *pval; - const ASN1_STRING *pstr; - const X509_ALGOR *palg; - ASN1_INTEGER *privkey = NULL; - BN_CTX *ctx = NULL; - - DSA *dsa = NULL; - int ret = 0; + DSA *dsa = ossl_dsa_key_from_pkcs8(p8, NULL, NULL); - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) - return 0; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) - goto decerr; - if (privkey->type == V_ASN1_NEG_INTEGER || ptype != V_ASN1_SEQUENCE) - goto decerr; - - pstr = pval; - pm = pstr->data; - pmlen = pstr->length; - if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) - goto decerr; - /* We have parameters now set private key */ - if ((dsa->priv_key = BN_secure_new()) == NULL - || !ASN1_INTEGER_to_BN(privkey, dsa->priv_key)) { - DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); - goto dsaerr; - } - /* Calculate public key */ - if ((dsa->pub_key = BN_new()) == NULL) { - DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); - goto dsaerr; - } - if ((ctx = BN_CTX_new()) == NULL) { - DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); - goto dsaerr; - } - - BN_set_flags(dsa->priv_key, BN_FLG_CONSTTIME); - if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { - DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); - goto dsaerr; + if (dsa != NULL) { + ret = 1; + EVP_PKEY_assign_DSA(pkey, dsa); } - EVP_PKEY_assign_DSA(pkey, dsa); - - ret = 1; - goto done; - - decerr: - DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_DECODE_ERROR); - dsaerr: - DSA_free(dsa); - done: - BN_CTX_free(ctx); - ASN1_STRING_clear_free(privkey); return ret; } @@ -207,21 +167,21 @@ static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) unsigned char *dp = NULL; int dplen; - if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) { - DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_MISSING_PARAMETERS); + if (pkey->pkey.dsa == NULL|| pkey->pkey.dsa->priv_key == NULL) { + ERR_raise(ERR_LIB_DSA, DSA_R_MISSING_PARAMETERS); goto err; } params = ASN1_STRING_new(); if (params == NULL) { - DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); goto err; } params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); if (params->length <= 0) { - DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); goto err; } params->type = V_ASN1_SEQUENCE; @@ -229,26 +189,29 @@ static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) /* Get private key into integer */ prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); - if (!prkey) { - DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR); + if (prkey == NULL) { + ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); goto err; } dplen = i2d_ASN1_INTEGER(prkey, &dp); ASN1_STRING_clear_free(prkey); - prkey = NULL; - if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, - V_ASN1_SEQUENCE, params, dp, dplen)) + if (dplen <= 0) { + ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); goto err; + } + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, + V_ASN1_SEQUENCE, params, dp, dplen)) { + OPENSSL_clear_free(dp, dplen); + goto err; + } return 1; err: - OPENSSL_free(dp); ASN1_STRING_free(params); - ASN1_STRING_clear_free(prkey); return 0; } @@ -271,54 +234,34 @@ static int dsa_missing_parameters(const EVP_PKEY *pkey) { DSA *dsa; dsa = pkey->pkey.dsa; - if (dsa == NULL || dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) - return 1; - return 0; + return dsa == NULL + || dsa->params.p == NULL + || dsa->params.q == NULL + || dsa->params.g == NULL; } static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { - BIGNUM *a; - if (to->pkey.dsa == NULL) { to->pkey.dsa = DSA_new(); if (to->pkey.dsa == NULL) return 0; } - - if ((a = BN_dup(from->pkey.dsa->p)) == NULL) + if (!ossl_ffc_params_copy(&to->pkey.dsa->params, &from->pkey.dsa->params)) return 0; - BN_free(to->pkey.dsa->p); - to->pkey.dsa->p = a; - if ((a = BN_dup(from->pkey.dsa->q)) == NULL) - return 0; - BN_free(to->pkey.dsa->q); - to->pkey.dsa->q = a; - - if ((a = BN_dup(from->pkey.dsa->g)) == NULL) - return 0; - BN_free(to->pkey.dsa->g); - to->pkey.dsa->g = a; + to->pkey.dsa->dirty_cnt++; return 1; } static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { - if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) || - BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) || - BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g)) - return 0; - else - return 1; + return ossl_ffc_params_cmp(&a->pkey.dsa->params, &b->pkey.dsa->params, 1); } static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0) - return 0; - else - return 1; + return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0; } static void int_dsa_free(EVP_PKEY *pkey) @@ -331,6 +274,10 @@ static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) int ret = 0; const char *ktype = NULL; const BIGNUM *priv_key, *pub_key; + int mod_len = 0; + + if (x->params.p != NULL) + mod_len = DSA_bits(x); if (ptype == 2) priv_key = x->priv_key; @@ -349,11 +296,13 @@ static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) else ktype = "DSA-Parameters"; - if (priv_key) { + if (priv_key != NULL) { if (!BIO_indent(bp, off, 128)) goto err; - if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) - <= 0) + if (BIO_printf(bp, "%s: (%d bit)\n", ktype, mod_len) <= 0) + goto err; + } else { + if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0) goto err; } @@ -361,11 +310,7 @@ static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) goto err; if (!ASN1_bn_print(bp, "pub: ", pub_key, NULL, off)) goto err; - if (!ASN1_bn_print(bp, "P: ", x->p, NULL, off)) - goto err; - if (!ASN1_bn_print(bp, "Q: ", x->q, NULL, off)) - goto err; - if (!ASN1_bn_print(bp, "G: ", x->g, NULL, off)) + if (!ossl_ffc_params_print(bp, &x->params, off)) goto err; ret = 1; err: @@ -377,10 +322,10 @@ static int dsa_param_decode(EVP_PKEY *pkey, { DSA *dsa; - if ((dsa = d2i_DSAparams(NULL, pder, derlen)) == NULL) { - DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB); + if ((dsa = d2i_DSAparams(NULL, pder, derlen)) == NULL) return 0; - } + + dsa->dirty_cnt++; EVP_PKEY_assign_DSA(pkey, dsa); return 1; } @@ -414,9 +359,10 @@ static int old_dsa_priv_decode(EVP_PKEY *pkey, DSA *dsa; if ((dsa = d2i_DSAPrivateKey(NULL, pder, derlen)) == NULL) { - DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB); + ERR_raise(ERR_LIB_DSA, ERR_R_DSA_LIB); return 0; } + dsa->dirty_cnt++; EVP_PKEY_assign_DSA(pkey, dsa); return 1; } @@ -432,7 +378,7 @@ static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, DSA_SIG *dsa_sig; const unsigned char *p; - if (!sig) { + if (sig == NULL) { if (BIO_puts(bp, "\n") <= 0) return 0; else @@ -440,7 +386,7 @@ static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, } p = sig->data; dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); - if (dsa_sig) { + if (dsa_sig != NULL) { int rv = 0; const BIGNUM *r, *s; @@ -458,63 +404,119 @@ static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, DSA_SIG_free(dsa_sig); return rv; } + if (BIO_puts(bp, "\n") <= 0) + return 0; return X509_signature_dump(bp, sig, indent); } static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { - case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - *(int *)arg2 = CMS_RECIPINFO_NONE; - return 1; -#endif - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: *(int *)arg2 = NID_sha256; return 1; default: return -2; + } +} + +static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey) +{ + return pkey->pkey.dsa->dirty_cnt; +} + +static int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) +{ + DSA *dsa = from->pkey.dsa; + OSSL_PARAM_BLD *tmpl; + const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa); + const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa); + const BIGNUM *priv_key = DSA_get0_priv_key(dsa); + OSSL_PARAM *params; + int selection = 0; + int rv = 0; + + if (p == NULL || q == NULL || g == NULL) + return 0; + + tmpl = OSSL_PARAM_BLD_new(); + if (tmpl == NULL) + return 0; + + if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS; + if (pub_key != NULL) { + if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, + pub_key)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + } + if (priv_key != NULL) { + if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, + priv_key)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY; + } + + if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) + goto err; + /* We export, the provider imports */ + rv = importer(to_keydata, selection, params); + + OSSL_PARAM_free(params); + err: + OSSL_PARAM_BLD_free(tmpl); + return rv; +} + +static int dsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx) +{ + EVP_PKEY_CTX *pctx = vpctx; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); + DSA *dsa = ossl_dsa_new(pctx->libctx); + + if (dsa == NULL) { + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + return 0; } + if (!ossl_dsa_ffc_params_fromdata(dsa, params) + || !ossl_dsa_key_fromdata(dsa, params, 1) + || !EVP_PKEY_assign_DSA(pkey, dsa)) { + DSA_free(dsa); + return 0; + } + return 1; +} + +static int dsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) +{ + DSA *dsa = from->pkey.dsa; + DSA *dupkey = NULL; + int ret; + + if (dsa != NULL) { + dupkey = ossl_dsa_dup(dsa, OSSL_KEYMGMT_SELECT_ALL); + if (dupkey == NULL) + return 0; + } + + ret = EVP_PKEY_assign_DSA(to, dupkey); + if (!ret) + DSA_free(dupkey); + return ret; } /* NB these are sorted in pkey_id order, lowest first */ -const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = { +const EVP_PKEY_ASN1_METHOD ossl_dsa_asn1_meths[5] = { { EVP_PKEY_DSA2, @@ -568,5 +570,15 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = { int_dsa_free, dsa_pkey_ctrl, old_dsa_priv_decode, - old_dsa_priv_encode} + old_dsa_priv_encode, + + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + + dsa_pkey_dirty_cnt, + dsa_pkey_export_to, + dsa_pkey_import_from, + dsa_pkey_copy + } }; diff --git a/crypto/openssl/crypto/dsa/dsa_asn1.c b/crypto/openssl/crypto/dsa/dsa_asn1.c index 9cafd5ca8a90..300ce6806df5 100644 --- a/crypto/openssl/crypto/dsa/dsa_asn1.c +++ b/crypto/openssl/crypto/dsa/dsa_asn1.c @@ -1,61 +1,25 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include "dsa_local.h" #include #include #include - -ASN1_SEQUENCE(DSA_SIG) = { - ASN1_SIMPLE(DSA_SIG, r, CBIGNUM), - ASN1_SIMPLE(DSA_SIG, s, CBIGNUM) -} static_ASN1_SEQUENCE_END(DSA_SIG) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG) - -DSA_SIG *DSA_SIG_new(void) -{ - DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); - if (sig == NULL) - DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE); - return sig; -} - -void DSA_SIG_free(DSA_SIG *sig) -{ - if (sig == NULL) - return; - BN_clear_free(sig->r); - BN_clear_free(sig->s); - OPENSSL_free(sig); -} - -void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) -{ - if (pr != NULL) - *pr = sig->r; - if (ps != NULL) - *ps = sig->s; -} - -int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) -{ - if (r == NULL || s == NULL) - return 0; - BN_clear_free(sig->r); - BN_clear_free(sig->s); - sig->r = r; - sig->s = s; - return 1; -} +#include "crypto/asn1_dsa.h" /* Override the default free and new methods */ static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, @@ -76,80 +40,33 @@ static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = { ASN1_EMBED(DSA, version, INT32), - ASN1_SIMPLE(DSA, p, BIGNUM), - ASN1_SIMPLE(DSA, q, BIGNUM), - ASN1_SIMPLE(DSA, g, BIGNUM), + ASN1_SIMPLE(DSA, params.p, BIGNUM), + ASN1_SIMPLE(DSA, params.q, BIGNUM), + ASN1_SIMPLE(DSA, params.g, BIGNUM), ASN1_SIMPLE(DSA, pub_key, BIGNUM), ASN1_SIMPLE(DSA, priv_key, CBIGNUM) } static_ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA, DSAPrivateKey, DSAPrivateKey) ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = { - ASN1_SIMPLE(DSA, p, BIGNUM), - ASN1_SIMPLE(DSA, q, BIGNUM), - ASN1_SIMPLE(DSA, g, BIGNUM), + ASN1_SIMPLE(DSA, params.p, BIGNUM), + ASN1_SIMPLE(DSA, params.q, BIGNUM), + ASN1_SIMPLE(DSA, params.g, BIGNUM), } static_ASN1_SEQUENCE_END_cb(DSA, DSAparams) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA, DSAparams, DSAparams) ASN1_SEQUENCE_cb(DSAPublicKey, dsa_cb) = { ASN1_SIMPLE(DSA, pub_key, BIGNUM), - ASN1_SIMPLE(DSA, p, BIGNUM), - ASN1_SIMPLE(DSA, q, BIGNUM), - ASN1_SIMPLE(DSA, g, BIGNUM) + ASN1_SIMPLE(DSA, params.p, BIGNUM), + ASN1_SIMPLE(DSA, params.q, BIGNUM), + ASN1_SIMPLE(DSA, params.g, BIGNUM) } static_ASN1_SEQUENCE_END_cb(DSA, DSAPublicKey) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA, DSAPublicKey, DSAPublicKey) -DSA *DSAparams_dup(DSA *dsa) +DSA *DSAparams_dup(const DSA *dsa) { return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa); } - -int DSA_sign(int type, const unsigned char *dgst, int dlen, - unsigned char *sig, unsigned int *siglen, DSA *dsa) -{ - DSA_SIG *s; - - s = DSA_do_sign(dgst, dlen, dsa); - if (s == NULL) { - *siglen = 0; - return 0; - } - *siglen = i2d_DSA_SIG(s, &sig); - DSA_SIG_free(s); - return 1; -} - -/* data has already been hashed (probably with SHA or SHA-1). */ -/*- - * returns - * 1: correct signature - * 0: incorrect signature - * -1: error - */ -int DSA_verify(int type, const unsigned char *dgst, int dgst_len, - const unsigned char *sigbuf, int siglen, DSA *dsa) -{ - DSA_SIG *s; - const unsigned char *p = sigbuf; - unsigned char *der = NULL; - int derlen = -1; - int ret = -1; - - s = DSA_SIG_new(); - if (s == NULL) - return ret; - if (d2i_DSA_SIG(&s, &p, siglen) == NULL) - goto err; - /* Ensure signature uses DER and doesn't have trailing garbage */ - derlen = i2d_DSA_SIG(s, &der); - if (derlen != siglen || memcmp(sigbuf, der, derlen)) - goto err; - ret = DSA_do_verify(dgst, dgst_len, s, dsa); - err: - OPENSSL_clear_free(der, derlen); - DSA_SIG_free(s); - return ret; -} diff --git a/crypto/openssl/crypto/dsa/dsa_backend.c b/crypto/openssl/crypto/dsa/dsa_backend.c new file mode 100644 index 000000000000..f9a71bdc9e0b --- /dev/null +++ b/crypto/openssl/crypto/dsa/dsa_backend.c @@ -0,0 +1,192 @@ +/* + * Copyright 2020-2022 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 + */ + +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include +#ifndef FIPS_MODULE +# include +#endif +#include "crypto/dsa.h" +#include "dsa_local.h" + +/* + * The intention with the "backend" source file is to offer backend support + * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider + * implementations alike. + */ + +int ossl_dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[], + int include_private) +{ + const OSSL_PARAM *param_priv_key = NULL, *param_pub_key; + BIGNUM *priv_key = NULL, *pub_key = NULL; + + if (dsa == NULL) + return 0; + + if (include_private) { + param_priv_key = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); + } + param_pub_key = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); + + /* It's ok if neither half is present */ + if (param_priv_key == NULL && param_pub_key == NULL) + return 1; + + if (param_pub_key != NULL && !OSSL_PARAM_get_BN(param_pub_key, &pub_key)) + goto err; + if (param_priv_key != NULL && !OSSL_PARAM_get_BN(param_priv_key, &priv_key)) + goto err; + + if (!DSA_set0_key(dsa, pub_key, priv_key)) + goto err; + + return 1; + + err: + BN_clear_free(priv_key); + BN_free(pub_key); + return 0; +} + +int ossl_dsa_is_foreign(const DSA *dsa) +{ +#ifndef FIPS_MODULE + if (dsa->engine != NULL || DSA_get_method((DSA *)dsa) != DSA_OpenSSL()) + return 1; +#endif + return 0; +} + +static ossl_inline int dsa_bn_dup_check(BIGNUM **out, const BIGNUM *f) +{ + if (f != NULL && (*out = BN_dup(f)) == NULL) + return 0; + return 1; +} + +DSA *ossl_dsa_dup(const DSA *dsa, int selection) +{ + DSA *dupkey = NULL; + + /* Do not try to duplicate foreign DSA keys */ + if (ossl_dsa_is_foreign(dsa)) + return NULL; + + if ((dupkey = ossl_dsa_new(dsa->libctx)) == NULL) + return NULL; + + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0 + && !ossl_ffc_params_copy(&dupkey->params, &dsa->params)) + goto err; + + dupkey->flags = dsa->flags; + + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 + && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 + || !dsa_bn_dup_check(&dupkey->pub_key, dsa->pub_key))) + goto err; + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 + && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 + || !dsa_bn_dup_check(&dupkey->priv_key, dsa->priv_key))) + goto err; + +#ifndef FIPS_MODULE + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DSA, + &dupkey->ex_data, &dsa->ex_data)) + goto err; +#endif + + return dupkey; + + err: + DSA_free(dupkey); + return NULL; +} + +#ifndef FIPS_MODULE +DSA *ossl_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + const void *pval; + const ASN1_STRING *pstr; + const X509_ALGOR *palg; + ASN1_INTEGER *privkey = NULL; + const BIGNUM *dsa_p, *dsa_g; + BIGNUM *dsa_pubkey = NULL, *dsa_privkey = NULL; + BN_CTX *ctx = NULL; + + DSA *dsa = NULL; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8inf)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) + goto decerr; + if (privkey->type == V_ASN1_NEG_INTEGER || ptype != V_ASN1_SEQUENCE) + goto decerr; + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) + goto decerr; + /* We have parameters now set private key */ + if ((dsa_privkey = BN_secure_new()) == NULL + || !ASN1_INTEGER_to_BN(privkey, dsa_privkey)) { + ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); + goto dsaerr; + } + /* Calculate public key */ + if ((dsa_pubkey = BN_new()) == NULL) { + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + if ((ctx = BN_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + + dsa_p = DSA_get0_p(dsa); + dsa_g = DSA_get0_g(dsa); + BN_set_flags(dsa_privkey, BN_FLG_CONSTTIME); + if (!BN_mod_exp(dsa_pubkey, dsa_g, dsa_privkey, dsa_p, ctx)) { + ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); + goto dsaerr; + } + DSA_set0_key(dsa, dsa_pubkey, dsa_privkey); + + goto done; + + decerr: + ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR); + dsaerr: + BN_free(dsa_privkey); + BN_free(dsa_pubkey); + DSA_free(dsa); + dsa = NULL; + done: + BN_CTX_free(ctx); + ASN1_STRING_clear_free(privkey); + return dsa; +} +#endif diff --git a/crypto/openssl/crypto/dsa/dsa_check.c b/crypto/openssl/crypto/dsa/dsa_check.c new file mode 100644 index 000000000000..7ee914a477ec --- /dev/null +++ b/crypto/openssl/crypto/dsa/dsa_check.c @@ -0,0 +1,95 @@ +/* + * Copyright 1995-2021 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 + */ + +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "internal/cryptlib.h" +#include +#include "dsa_local.h" +#include "crypto/dsa.h" + +int ossl_dsa_check_params(const DSA *dsa, int checktype, int *ret) +{ + if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK) + return ossl_ffc_params_simple_validate(dsa->libctx, &dsa->params, + FFC_PARAM_TYPE_DSA, ret); + else + /* + * Do full FFC domain params validation according to FIPS-186-4 + * - always in FIPS_MODULE + * - only if possible (i.e., seed is set) in default provider + */ + return ossl_ffc_params_full_validate(dsa->libctx, &dsa->params, + FFC_PARAM_TYPE_DSA, ret); +} + +/* + * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Full public key validation. + */ +int ossl_dsa_check_pub_key(const DSA *dsa, const BIGNUM *pub_key, int *ret) +{ + return ossl_ffc_validate_public_key(&dsa->params, pub_key, ret); +} + +/* + * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Partial public key validation. + * To only be used with ephemeral FFC public keys generated using the approved + * safe-prime groups. + */ +int ossl_dsa_check_pub_key_partial(const DSA *dsa, const BIGNUM *pub_key, int *ret) +{ + return ossl_ffc_validate_public_key_partial(&dsa->params, pub_key, ret); +} + +int ossl_dsa_check_priv_key(const DSA *dsa, const BIGNUM *priv_key, int *ret) +{ + *ret = 0; + + return (dsa->params.q != NULL + && ossl_ffc_validate_private_key(dsa->params.q, priv_key, ret)); +} + +/* + * FFC pairwise check from SP800-56A R3. + * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency + */ +int ossl_dsa_check_pairwise(const DSA *dsa) +{ + int ret = 0; + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL; + + if (dsa->params.p == NULL + || dsa->params.g == NULL + || dsa->priv_key == NULL + || dsa->pub_key == NULL) + return 0; + + ctx = BN_CTX_new_ex(dsa->libctx); + if (ctx == NULL) + goto err; + pub_key = BN_new(); + if (pub_key == NULL) + goto err; + + /* recalculate the public key = (g ^ priv) mod p */ + if (!ossl_dsa_generate_public_key(ctx, dsa, dsa->priv_key, pub_key)) + goto err; + /* check it matches the existing pubic_key */ + ret = BN_cmp(pub_key, dsa->pub_key) == 0; +err: + BN_free(pub_key); + BN_CTX_free(ctx); + return ret; +} diff --git a/crypto/openssl/crypto/dsa/dsa_depr.c b/crypto/openssl/crypto/dsa/dsa_depr.c index f51aea74978a..95f8d1f3a9cb 100644 --- a/crypto/openssl/crypto/dsa/dsa_depr.c +++ b/crypto/openssl/crypto/dsa/dsa_depr.c @@ -1,7 +1,7 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,24 +13,20 @@ */ /* - * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, - * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB - * 180-1) + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. */ -#define xxxHASH EVP_sha1() +#include "internal/deprecated.h" #include -#if OPENSSL_API_COMPAT >= 0x00908000L -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include "internal/cryptlib.h" -# include -# include -# include -# include + +#include +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, @@ -59,4 +55,3 @@ DSA *DSA_generate_parameters(int bits, DSA_free(ret); return NULL; } -#endif diff --git a/crypto/openssl/crypto/dsa/dsa_err.c b/crypto/openssl/crypto/dsa/dsa_err.c index 8dcf0548ac76..5685d5e83eb3 100644 --- a/crypto/openssl/crypto/dsa/dsa_err.c +++ b/crypto/openssl/crypto/dsa/dsa_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,40 +10,14 @@ #include #include +#include "crypto/dsaerr.h" -#ifndef OPENSSL_NO_ERR +#ifndef OPENSSL_NO_DSA -static const ERR_STRING_DATA DSA_str_functs[] = { - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSAPARAMS_PRINT, 0), "DSAparams_print"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSAPARAMS_PRINT_FP, 0), "DSAparams_print_fp"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_BUILTIN_PARAMGEN, 0), - "dsa_builtin_paramgen"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_BUILTIN_PARAMGEN2, 0), - "dsa_builtin_paramgen2"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_DO_SIGN, 0), "DSA_do_sign"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_DO_VERIFY, 0), "DSA_do_verify"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_DUP, 0), "DSA_meth_dup"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_NEW, 0), "DSA_meth_new"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_METH_SET1_NAME, 0), "DSA_meth_set1_name"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_NEW_METHOD, 0), "DSA_new_method"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PARAM_DECODE, 0), "dsa_param_decode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PRINT_FP, 0), "DSA_print_fp"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PRIV_DECODE, 0), "dsa_priv_decode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PRIV_ENCODE, 0), "dsa_priv_encode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PUB_DECODE, 0), "dsa_pub_decode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_PUB_ENCODE, 0), "dsa_pub_encode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_SIGN, 0), "DSA_sign"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_SIGN_SETUP, 0), "DSA_sign_setup"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_DSA_SIG_NEW, 0), "DSA_SIG_new"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_OLD_DSA_PRIV_DECODE, 0), - "old_dsa_priv_decode"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_PKEY_DSA_CTRL, 0), "pkey_dsa_ctrl"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_PKEY_DSA_CTRL_STR, 0), "pkey_dsa_ctrl_str"}, - {ERR_PACK(ERR_LIB_DSA, DSA_F_PKEY_DSA_KEYGEN, 0), "pkey_dsa_keygen"}, - {0, NULL} -}; +# ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA DSA_str_reasons[] = { + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BAD_FFC_PARAMETERS), "bad ffc parameters"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BAD_Q_VALUE), "bad q value"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BN_DECODE_ERROR), "bn decode error"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BN_ERROR), "bn error"}, @@ -58,21 +32,23 @@ static const ERR_STRING_DATA DSA_str_reasons[] = { {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), "parameter encoding error"}, + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_P_NOT_PRIME), "p not prime"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_Q_NOT_PRIME), "q not prime"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_SEED_LEN_SMALL), "seed_len is less than the length of q"}, {0, NULL} }; -#endif +# endif -int ERR_load_DSA_strings(void) +int ossl_err_load_DSA_strings(void) { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(DSA_str_functs[0].error) == NULL) { - ERR_load_strings_const(DSA_str_functs); +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(DSA_str_reasons[0].error) == NULL) ERR_load_strings_const(DSA_str_reasons); - } -#endif +# endif return 1; } +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/dsa/dsa_gen.c b/crypto/openssl/crypto/dsa/dsa_gen.c index 5d066a06c546..a45092141281 100644 --- a/crypto/openssl/crypto/dsa/dsa_gen.c +++ b/crypto/openssl/crypto/dsa/dsa_gen.c @@ -1,18 +1,17 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ /* - * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, - * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB - * 180-1) + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. */ -#define xxxHASH EVP_sha1() +#include "internal/deprecated.h" #include #include @@ -21,594 +20,58 @@ #include #include #include +#include "crypto/dsa.h" #include "dsa_local.h" -int DSA_generate_parameters_ex(DSA *ret, int bits, +int ossl_dsa_generate_ffc_parameters(DSA *dsa, int type, int pbits, int qbits, + BN_GENCB *cb) +{ + int ret = 0, res; + +#ifndef FIPS_MODULE + if (type == DSA_PARAMGEN_TYPE_FIPS_186_2) + ret = ossl_ffc_params_FIPS186_2_generate(dsa->libctx, &dsa->params, + FFC_PARAM_TYPE_DSA, + pbits, qbits, &res, cb); + else +#endif + ret = ossl_ffc_params_FIPS186_4_generate(dsa->libctx, &dsa->params, + FFC_PARAM_TYPE_DSA, + pbits, qbits, &res, cb); + if (ret > 0) + dsa->dirty_cnt++; + return ret; +} + +#ifndef FIPS_MODULE +int DSA_generate_parameters_ex(DSA *dsa, int bits, const unsigned char *seed_in, int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { - if (ret->meth->dsa_paramgen) - return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, + if (dsa->meth->dsa_paramgen) + return dsa->meth->dsa_paramgen(dsa, bits, seed_in, seed_len, counter_ret, h_ret, cb); - else { - const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1(); - size_t qbits = EVP_MD_size(evpmd) * 8; - - return dsa_builtin_paramgen(ret, bits, qbits, evpmd, - seed_in, seed_len, NULL, counter_ret, - h_ret, cb); - } -} - -int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, - const EVP_MD *evpmd, const unsigned char *seed_in, - size_t seed_len, unsigned char *seed_out, - int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) -{ - int ok = 0; - unsigned char seed[SHA256_DIGEST_LENGTH]; - unsigned char md[SHA256_DIGEST_LENGTH]; - unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH]; - BIGNUM *r0, *W, *X, *c, *test; - BIGNUM *g = NULL, *q = NULL, *p = NULL; - BN_MONT_CTX *mont = NULL; - int i, k, n = 0, m = 0, qsize = qbits >> 3; - int counter = 0; - int r = 0; - BN_CTX *ctx = NULL; - unsigned int h = 2; - - if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && - qsize != SHA256_DIGEST_LENGTH) - /* invalid q size */ + if (seed_in != NULL + && !ossl_ffc_params_set_validate_params(&dsa->params, seed_in, seed_len, + -1)) return 0; - if (evpmd == NULL) { - if (qsize == SHA_DIGEST_LENGTH) - evpmd = EVP_sha1(); - else if (qsize == SHA224_DIGEST_LENGTH) - evpmd = EVP_sha224(); - else - evpmd = EVP_sha256(); - } else { - qsize = EVP_MD_size(evpmd); - } - - if (bits < 512) - bits = 512; - - bits = (bits + 63) / 64 * 64; - - if (seed_in != NULL) { - if (seed_len < (size_t)qsize) { - DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_SEED_LEN_SMALL); + /* The old code used FIPS 186-2 DSA Parameter generation */ + if (bits < 2048 && seed_len <= 20) { + if (!ossl_dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_2, + bits, 160, cb)) return 0; - } - if (seed_len > (size_t)qsize) { - /* Only consume as much seed as is expected. */ - seed_len = qsize; - } - memcpy(seed, seed_in, seed_len); - } - - if ((mont = BN_MONT_CTX_new()) == NULL) - goto err; - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - - BN_CTX_start(ctx); - - r0 = BN_CTX_get(ctx); - g = BN_CTX_get(ctx); - W = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - c = BN_CTX_get(ctx); - p = BN_CTX_get(ctx); - test = BN_CTX_get(ctx); - - if (test == NULL) - goto err; - - if (!BN_lshift(test, BN_value_one(), bits - 1)) - goto err; - - for (;;) { - for (;;) { /* find q */ - int use_random_seed = (seed_in == NULL); - - /* step 1 */ - if (!BN_GENCB_call(cb, 0, m++)) - goto err; - - if (use_random_seed) { - if (RAND_bytes(seed, qsize) <= 0) - goto err; - } else { - /* If we come back through, use random seed next time. */ - seed_in = NULL; - } - memcpy(buf, seed, qsize); - memcpy(buf2, seed, qsize); - /* precompute "SEED + 1" for step 7: */ - for (i = qsize - 1; i >= 0; i--) { - buf[i]++; - if (buf[i] != 0) - break; - } - - /* step 2 */ - if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) - goto err; - if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) - goto err; - for (i = 0; i < qsize; i++) - md[i] ^= buf2[i]; - - /* step 3 */ - md[0] |= 0x80; - md[qsize - 1] |= 0x01; - if (!BN_bin2bn(md, qsize, q)) - goto err; - - /* step 4 */ - r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, - use_random_seed, cb); - if (r > 0) - break; - if (r != 0) - goto err; - - /* do a callback call */ - /* step 5 */ - } - - if (!BN_GENCB_call(cb, 2, 0)) - goto err; - if (!BN_GENCB_call(cb, 3, 0)) - goto err; - - /* step 6 */ - counter = 0; - /* "offset = 2" */ - - n = (bits - 1) / 160; - - for (;;) { - if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) - goto err; - - /* step 7 */ - BN_zero(W); - /* now 'buf' contains "SEED + offset - 1" */ - for (k = 0; k <= n; k++) { - /* - * obtain "SEED + offset + k" by incrementing: - */ - for (i = qsize - 1; i >= 0; i--) { - buf[i]++; - if (buf[i] != 0) - break; - } - - if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) - goto err; - - /* step 8 */ - if (!BN_bin2bn(md, qsize, r0)) - goto err; - if (!BN_lshift(r0, r0, (qsize << 3) * k)) - goto err; - if (!BN_add(W, W, r0)) - goto err; - } - - /* more of step 8 */ - if (!BN_mask_bits(W, bits - 1)) - goto err; - if (!BN_copy(X, W)) - goto err; - if (!BN_add(X, X, test)) - goto err; - - /* step 9 */ - if (!BN_lshift1(r0, q)) - goto err; - if (!BN_mod(c, X, r0, ctx)) - goto err; - if (!BN_sub(r0, c, BN_value_one())) - goto err; - if (!BN_sub(p, X, r0)) - goto err; - - /* step 10 */ - if (BN_cmp(p, test) >= 0) { - /* step 11 */ - r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); - if (r > 0) - goto end; /* found it */ - if (r != 0) - goto err; - } - - /* step 13 */ - counter++; - /* "offset = offset + n + 1" */ - - /* step 14 */ - if (counter >= 4096) - break; - } - } - end: - if (!BN_GENCB_call(cb, 2, 1)) - goto err; - - /* We now need to generate g */ - /* Set r0=(p-1)/q */ - if (!BN_sub(test, p, BN_value_one())) - goto err; - if (!BN_div(r0, NULL, test, q, ctx)) - goto err; - - if (!BN_set_word(test, h)) - goto err; - if (!BN_MONT_CTX_set(mont, p, ctx)) - goto err; - - for (;;) { - /* g=test^r0%p */ - if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) - goto err; - if (!BN_is_one(g)) - break; - if (!BN_add(test, test, BN_value_one())) - goto err; - h++; - } - - if (!BN_GENCB_call(cb, 3, 1)) - goto err; - - ok = 1; - err: - if (ok) { - BN_free(ret->p); - BN_free(ret->q); - BN_free(ret->g); - ret->p = BN_dup(p); - ret->q = BN_dup(q); - ret->g = BN_dup(g); - if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { - ok = 0; - goto err; - } - if (counter_ret != NULL) - *counter_ret = counter; - if (h_ret != NULL) - *h_ret = h; - if (seed_out) - memcpy(seed_out, seed, qsize); - } - BN_CTX_end(ctx); - BN_CTX_free(ctx); - BN_MONT_CTX_free(mont); - return ok; -} - -/* - * This is a parameter generation algorithm for the DSA2 algorithm as - * described in FIPS 186-3. - */ - -int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, - const EVP_MD *evpmd, const unsigned char *seed_in, - size_t seed_len, int idx, unsigned char *seed_out, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb) -{ - int ok = -1; - unsigned char *seed = NULL, *seed_tmp = NULL; - unsigned char md[EVP_MAX_MD_SIZE]; - int mdsize; - BIGNUM *r0, *W, *X, *c, *test; - BIGNUM *g = NULL, *q = NULL, *p = NULL; - BN_MONT_CTX *mont = NULL; - int i, k, n = 0, m = 0, qsize = N >> 3; - int counter = 0; - int r = 0; - BN_CTX *ctx = NULL; - EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - unsigned int h = 2; - - if (mctx == NULL) - goto err; - - /* make sure L > N, otherwise we'll get trapped in an infinite loop */ - if (L <= N) { - DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS); - goto err; - } - - if (evpmd == NULL) { - if (N == 160) - evpmd = EVP_sha1(); - else if (N == 224) - evpmd = EVP_sha224(); - else - evpmd = EVP_sha256(); - } - - mdsize = EVP_MD_size(evpmd); - /* If unverifiable g generation only don't need seed */ - if (!ret->p || !ret->q || idx >= 0) { - if (seed_len == 0) - seed_len = mdsize; - - seed = OPENSSL_malloc(seed_len); - - if (seed_out) - seed_tmp = seed_out; - else - seed_tmp = OPENSSL_malloc(seed_len); - - if (seed == NULL || seed_tmp == NULL) - goto err; - - if (seed_in) - memcpy(seed, seed_in, seed_len); - - } - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - - if ((mont = BN_MONT_CTX_new()) == NULL) - goto err; - - BN_CTX_start(ctx); - r0 = BN_CTX_get(ctx); - g = BN_CTX_get(ctx); - W = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - c = BN_CTX_get(ctx); - test = BN_CTX_get(ctx); - if (test == NULL) - goto err; - - /* if p, q already supplied generate g only */ - if (ret->p && ret->q) { - p = ret->p; - q = ret->q; - if (idx >= 0) - memcpy(seed_tmp, seed, seed_len); - goto g_only; } else { - p = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); - if (q == NULL) - goto err; - } - - if (!BN_lshift(test, BN_value_one(), L - 1)) - goto err; - for (;;) { - for (;;) { /* find q */ - unsigned char *pmd; - /* step 1 */ - if (!BN_GENCB_call(cb, 0, m++)) - goto err; - - if (!seed_in) { - if (RAND_bytes(seed, seed_len) <= 0) - goto err; - } - /* step 2 */ - if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL)) - goto err; - /* Take least significant bits of md */ - if (mdsize > qsize) - pmd = md + mdsize - qsize; - else - pmd = md; - - if (mdsize < qsize) - memset(md + mdsize, 0, qsize - mdsize); - - /* step 3 */ - pmd[0] |= 0x80; - pmd[qsize - 1] |= 0x01; - if (!BN_bin2bn(pmd, qsize, q)) - goto err; - - /* step 4 */ - r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, - seed_in ? 1 : 0, cb); - if (r > 0) - break; - if (r != 0) - goto err; - /* Provided seed didn't produce a prime: error */ - if (seed_in) { - ok = 0; - DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME); - goto err; - } - - /* do a callback call */ - /* step 5 */ - } - /* Copy seed to seed_out before we mess with it */ - if (seed_out) - memcpy(seed_out, seed, seed_len); - - if (!BN_GENCB_call(cb, 2, 0)) - goto err; - if (!BN_GENCB_call(cb, 3, 0)) - goto err; - - /* step 6 */ - counter = 0; - /* "offset = 1" */ - - n = (L - 1) / (mdsize << 3); - - for (;;) { - if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) - goto err; - - /* step 7 */ - BN_zero(W); - /* now 'buf' contains "SEED + offset - 1" */ - for (k = 0; k <= n; k++) { - /* - * obtain "SEED + offset + k" by incrementing: - */ - for (i = seed_len - 1; i >= 0; i--) { - seed[i]++; - if (seed[i] != 0) - break; - } - - if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL)) - goto err; - - /* step 8 */ - if (!BN_bin2bn(md, mdsize, r0)) - goto err; - if (!BN_lshift(r0, r0, (mdsize << 3) * k)) - goto err; - if (!BN_add(W, W, r0)) - goto err; - } - - /* more of step 8 */ - if (!BN_mask_bits(W, L - 1)) - goto err; - if (!BN_copy(X, W)) - goto err; - if (!BN_add(X, X, test)) - goto err; - - /* step 9 */ - if (!BN_lshift1(r0, q)) - goto err; - if (!BN_mod(c, X, r0, ctx)) - goto err; - if (!BN_sub(r0, c, BN_value_one())) - goto err; - if (!BN_sub(p, X, r0)) - goto err; - - /* step 10 */ - if (BN_cmp(p, test) >= 0) { - /* step 11 */ - r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); - if (r > 0) - goto end; /* found it */ - if (r != 0) - goto err; - } - - /* step 13 */ - counter++; - /* "offset = offset + n + 1" */ - - /* step 14 */ - if (counter >= (int)(4 * L)) - break; - } - if (seed_in) { - ok = 0; - DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS); - goto err; - } - } - end: - if (!BN_GENCB_call(cb, 2, 1)) - goto err; - - g_only: - - /* We now need to generate g */ - /* Set r0=(p-1)/q */ - if (!BN_sub(test, p, BN_value_one())) - goto err; - if (!BN_div(r0, NULL, test, q, ctx)) - goto err; - - if (idx < 0) { - if (!BN_set_word(test, h)) - goto err; - } else - h = 1; - if (!BN_MONT_CTX_set(mont, p, ctx)) - goto err; - - for (;;) { - static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e }; - if (idx >= 0) { - md[0] = idx & 0xff; - md[1] = (h >> 8) & 0xff; - md[2] = h & 0xff; - if (!EVP_DigestInit_ex(mctx, evpmd, NULL)) - goto err; - if (!EVP_DigestUpdate(mctx, seed_tmp, seed_len)) - goto err; - if (!EVP_DigestUpdate(mctx, ggen, sizeof(ggen))) - goto err; - if (!EVP_DigestUpdate(mctx, md, 3)) - goto err; - if (!EVP_DigestFinal_ex(mctx, md, NULL)) - goto err; - if (!BN_bin2bn(md, mdsize, test)) - goto err; - } - /* g=test^r0%p */ - if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) - goto err; - if (!BN_is_one(g)) - break; - if (idx < 0 && !BN_add(test, test, BN_value_one())) - goto err; - h++; - if (idx >= 0 && h > 0xffff) - goto err; + if (!ossl_dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_4, + bits, 0, cb)) + return 0; } - if (!BN_GENCB_call(cb, 3, 1)) - goto err; - - ok = 1; - err: - if (ok == 1) { - if (p != ret->p) { - BN_free(ret->p); - ret->p = BN_dup(p); - } - if (q != ret->q) { - BN_free(ret->q); - ret->q = BN_dup(q); - } - BN_free(ret->g); - ret->g = BN_dup(g); - if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { - ok = -1; - goto err; - } - if (counter_ret != NULL) - *counter_ret = counter; - if (h_ret != NULL) - *h_ret = h; - } - OPENSSL_free(seed); - if (seed_out != seed_tmp) - OPENSSL_free(seed_tmp); - BN_CTX_end(ctx); - BN_CTX_free(ctx); - BN_MONT_CTX_free(mont); - EVP_MD_CTX_free(mctx); - return ok; + if (counter_ret != NULL) + *counter_ret = dsa->params.pcounter; + if (h_ret != NULL) + *h_ret = dsa->params.h; + return 1; } +#endif diff --git a/crypto/openssl/crypto/dsa/dsa_key.c b/crypto/openssl/crypto/dsa/dsa_key.c index bdeddd4f61df..1f951a9d36a9 100644 --- a/crypto/openssl/crypto/dsa/dsa_key.c +++ b/crypto/openssl/crypto/dsa/dsa_key.c @@ -1,71 +1,130 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include "internal/cryptlib.h" #include +#include +#include "prov/providercommon.h" +#include "crypto/dsa.h" #include "dsa_local.h" -static int dsa_builtin_keygen(DSA *dsa); +#ifdef FIPS_MODULE +# define MIN_STRENGTH 112 +#else +# define MIN_STRENGTH 80 +#endif + +static int dsa_keygen(DSA *dsa, int pairwise_test); +static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg); int DSA_generate_key(DSA *dsa) { - if (dsa->meth->dsa_keygen) +#ifndef FIPS_MODULE + if (dsa->meth->dsa_keygen != NULL) return dsa->meth->dsa_keygen(dsa); - return dsa_builtin_keygen(dsa); +#endif + return dsa_keygen(dsa, 0); } -static int dsa_builtin_keygen(DSA *dsa) +int ossl_dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, + const BIGNUM *priv_key, BIGNUM *pub_key) +{ + int ret = 0; + BIGNUM *prk = BN_new(); + + if (prk == NULL) + return 0; + BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); + + /* pub_key = g ^ priv_key mod p */ + if (!BN_mod_exp(pub_key, dsa->params.g, prk, dsa->params.p, ctx)) + goto err; + ret = 1; +err: + BN_clear_free(prk); + return ret; +} + +static int dsa_keygen(DSA *dsa, int pairwise_test) { int ok = 0; BN_CTX *ctx = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(dsa->libctx)) == NULL) goto err; if (dsa->priv_key == NULL) { if ((priv_key = BN_secure_new()) == NULL) goto err; - } else + } else { priv_key = dsa->priv_key; + } - do - if (!BN_priv_rand_range(priv_key, dsa->q)) - goto err; - while (BN_is_zero(priv_key)) ; + /* Do a partial check for invalid p, q, g */ + if (!ossl_ffc_params_simple_validate(dsa->libctx, &dsa->params, + FFC_PARAM_TYPE_DSA, NULL)) + goto err; + + /* + * For FFC FIPS 186-4 keygen + * security strength s = 112, + * Max Private key size N = len(q) + */ + if (!ossl_ffc_generate_private_key(ctx, &dsa->params, + BN_num_bits(dsa->params.q), + MIN_STRENGTH, priv_key)) + goto err; if (dsa->pub_key == NULL) { if ((pub_key = BN_new()) == NULL) goto err; - } else + } else { pub_key = dsa->pub_key; - - { - BIGNUM *prk = BN_new(); - - if (prk == NULL) - goto err; - BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); - - if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) { - BN_free(prk); - goto err; - } - /* We MUST free prk before any further use of priv_key */ - BN_free(prk); } + if (!ossl_dsa_generate_public_key(ctx, dsa, priv_key, pub_key)) + goto err; + dsa->priv_key = priv_key; dsa->pub_key = pub_key; + +#ifdef FIPS_MODULE + pairwise_test = 1; +#endif /* FIPS_MODULE */ + ok = 1; + if (pairwise_test) { + OSSL_CALLBACK *cb = NULL; + void *cbarg = NULL; + + OSSL_SELF_TEST_get_callback(dsa->libctx, &cb, &cbarg); + ok = dsa_keygen_pairwise_test(dsa, cb, cbarg); + if (!ok) { + ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); + BN_free(dsa->pub_key); + BN_clear_free(dsa->priv_key); + dsa->pub_key = NULL; + dsa->priv_key = NULL; + BN_CTX_free(ctx); + return ok; + } + } + dsa->dirty_cnt++; err: if (pub_key != dsa->pub_key) @@ -73,5 +132,42 @@ static int dsa_builtin_keygen(DSA *dsa) if (priv_key != dsa->priv_key) BN_free(priv_key); BN_CTX_free(ctx); + return ok; } + +/* + * FIPS 140-2 IG 9.9 AS09.33 + * Perform a sign/verify operation. + */ +static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg) +{ + int ret = 0; + unsigned char dgst[16] = {0}; + unsigned int dgst_len = (unsigned int)sizeof(dgst); + DSA_SIG *sig = NULL; + OSSL_SELF_TEST *st = NULL; + + st = OSSL_SELF_TEST_new(cb, cbarg); + if (st == NULL) + goto err; + + OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, + OSSL_SELF_TEST_DESC_PCT_DSA); + + sig = DSA_do_sign(dgst, (int)dgst_len, dsa); + if (sig == NULL) + goto err; + + OSSL_SELF_TEST_oncorrupt_byte(st, dgst); + + if (DSA_do_verify(dgst, dgst_len, sig, dsa) != 1) + goto err; + + ret = 1; +err: + OSSL_SELF_TEST_onend(st, ret); + OSSL_SELF_TEST_free(st); + DSA_SIG_free(sig); + return ret; +} diff --git a/crypto/openssl/crypto/dsa/dsa_lib.c b/crypto/openssl/crypto/dsa/dsa_lib.c index f98af5853dc1..ccc701659217 100644 --- a/crypto/openssl/crypto/dsa/dsa_lib.c +++ b/crypto/openssl/crypto/dsa/dsa_lib.c @@ -1,24 +1,106 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#ifndef FIPS_MODULE +# include +#endif #include "internal/cryptlib.h" #include "internal/refcount.h" -#include +#include "crypto/dsa.h" +#include "crypto/dh.h" /* required by DSA_dup_DH() */ #include "dsa_local.h" -#include -#include -#include -DSA *DSA_new(void) +static DSA *dsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx); + +#ifndef FIPS_MODULE + +int DSA_set_ex_data(DSA *d, int idx, void *arg) +{ + return CRYPTO_set_ex_data(&d->ex_data, idx, arg); +} + +void *DSA_get_ex_data(const DSA *d, int idx) +{ + return CRYPTO_get_ex_data(&d->ex_data, idx); +} + +# ifndef OPENSSL_NO_DH +DH *DSA_dup_DH(const DSA *r) +{ + /* + * DSA has p, q, g, optional pub_key, optional priv_key. + * DH has p, optional length, g, optional pub_key, + * optional priv_key, optional q. + */ + DH *ret = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + if (r == NULL) + goto err; + ret = DH_new(); + if (ret == NULL) + goto err; + + if (!ossl_ffc_params_copy(ossl_dh_get0_params(ret), &r->params)) + goto err; + + if (r->pub_key != NULL) { + pub_key = BN_dup(r->pub_key); + if (pub_key == NULL) + goto err; + if (r->priv_key != NULL) { + priv_key = BN_dup(r->priv_key); + if (priv_key == NULL) + goto err; + } + if (!DH_set0_key(ret, pub_key, priv_key)) + goto err; + } else if (r->priv_key != NULL) { + /* Shouldn't happen */ + goto err; + } + + return ret; + + err: + BN_free(pub_key); + BN_free(priv_key); + DH_free(ret); + return NULL; +} +# endif /* OPENSSL_NO_DH */ + +void DSA_clear_flags(DSA *d, int flags) +{ + d->flags &= ~flags; +} + +int DSA_test_flags(const DSA *d, int flags) { - return DSA_new_method(NULL); + return d->flags & flags; +} + +void DSA_set_flags(DSA *d, int flags) +{ + d->flags |= flags; +} + +ENGINE *DSA_get0_engine(DSA *d) +{ + return d->engine; } int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) @@ -40,35 +122,38 @@ int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) meth->init(dsa); return 1; } +#endif /* FIPS_MODULE */ + const DSA_METHOD *DSA_get_method(DSA *d) { return d->meth; } -DSA *DSA_new_method(ENGINE *engine) +static DSA *dsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) { DSA *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); return NULL; } ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } + ret->libctx = libctx; ret->meth = DSA_get_default_method(); -#ifndef OPENSSL_NO_ENGINE +#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE) ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */ if (engine) { if (!ENGINE_init(engine)) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_DSA, ERR_R_ENGINE_LIB); goto err; } ret->engine = engine; @@ -77,7 +162,7 @@ DSA *DSA_new_method(ENGINE *engine) if (ret->engine) { ret->meth = ENGINE_get_DSA(ret->engine); if (ret->meth == NULL) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_DSA, ERR_R_ENGINE_LIB); goto err; } } @@ -85,11 +170,14 @@ DSA *DSA_new_method(ENGINE *engine) ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data)) +#ifndef FIPS_MODULE + if (!ossl_crypto_new_ex_data_ex(libctx, CRYPTO_EX_INDEX_DSA, ret, + &ret->ex_data)) goto err; +#endif if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL); + ERR_raise(ERR_LIB_DSA, ERR_R_INIT_FAIL); goto err; } @@ -100,6 +188,23 @@ DSA *DSA_new_method(ENGINE *engine) return NULL; } +DSA *DSA_new_method(ENGINE *engine) +{ + return dsa_new_intern(engine, NULL); +} + +DSA *ossl_dsa_new(OSSL_LIB_CTX *libctx) +{ + return dsa_new_intern(NULL, libctx); +} + +#ifndef FIPS_MODULE +DSA *DSA_new(void) +{ + return dsa_new_intern(NULL, NULL); +} +#endif + void DSA_free(DSA *r) { int i; @@ -115,17 +220,17 @@ void DSA_free(DSA *r) if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE +#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE) ENGINE_finish(r->engine); #endif +#ifndef FIPS_MODULE CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); +#endif CRYPTO_THREAD_lock_free(r->lock); - BN_clear_free(r->p); - BN_clear_free(r->q); - BN_clear_free(r->g); + ossl_ffc_params_cleanup(&r->params); BN_clear_free(r->pub_key); BN_clear_free(r->priv_key); OPENSSL_free(r); @@ -143,138 +248,56 @@ int DSA_up_ref(DSA *r) return ((i > 1) ? 1 : 0); } -int DSA_size(const DSA *r) +void ossl_dsa_set0_libctx(DSA *d, OSSL_LIB_CTX *libctx) { - int ret, i; - ASN1_INTEGER bs; - unsigned char buf[4]; /* 4 bytes looks really small. However, - * i2d_ASN1_INTEGER() will not look beyond - * the first byte, as long as the second - * parameter is NULL. */ - - i = BN_num_bits(r->q); - bs.length = (i + 7) / 8; - bs.data = buf; - bs.type = V_ASN1_INTEGER; - /* If the top bit is set the asn1 encoding is 1 larger. */ - buf[0] = 0xff; - - i = i2d_ASN1_INTEGER(&bs, NULL); - i += i; /* r and s */ - ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); - return ret; + d->libctx = libctx; } -int DSA_set_ex_data(DSA *d, int idx, void *arg) +void DSA_get0_pqg(const DSA *d, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) { - return CRYPTO_set_ex_data(&d->ex_data, idx, arg); + ossl_ffc_params_get0_pqg(&d->params, p, q, g); } -void *DSA_get_ex_data(DSA *d, int idx) +int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) { - return CRYPTO_get_ex_data(&d->ex_data, idx); + /* If the fields p, q and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((d->params.p == NULL && p == NULL) + || (d->params.q == NULL && q == NULL) + || (d->params.g == NULL && g == NULL)) + return 0; + + ossl_ffc_params_set0_pqg(&d->params, p, q, g); + d->dirty_cnt++; + + return 1; } -int DSA_security_bits(const DSA *d) +const BIGNUM *DSA_get0_p(const DSA *d) { - if (d->p && d->q) - return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q)); - return -1; + return d->params.p; } -#ifndef OPENSSL_NO_DH -DH *DSA_dup_DH(const DSA *r) +const BIGNUM *DSA_get0_q(const DSA *d) { - /* - * DSA has p, q, g, optional pub_key, optional priv_key. DH has p, - * optional length, g, optional pub_key, optional priv_key, optional q. - */ - - DH *ret = NULL; - BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL; - - if (r == NULL) - goto err; - ret = DH_new(); - if (ret == NULL) - goto err; - if (r->p != NULL || r->g != NULL || r->q != NULL) { - if (r->p == NULL || r->g == NULL || r->q == NULL) { - /* Shouldn't happen */ - goto err; - } - p = BN_dup(r->p); - g = BN_dup(r->g); - q = BN_dup(r->q); - if (p == NULL || g == NULL || q == NULL || !DH_set0_pqg(ret, p, q, g)) - goto err; - p = g = q = NULL; - } - - if (r->pub_key != NULL) { - pub_key = BN_dup(r->pub_key); - if (pub_key == NULL) - goto err; - if (r->priv_key != NULL) { - priv_key = BN_dup(r->priv_key); - if (priv_key == NULL) - goto err; - } - if (!DH_set0_key(ret, pub_key, priv_key)) - goto err; - } else if (r->priv_key != NULL) { - /* Shouldn't happen */ - goto err; - } - - return ret; - - err: - BN_free(p); - BN_free(g); - BN_free(q); - BN_free(pub_key); - BN_free(priv_key); - DH_free(ret); - return NULL; + return d->params.q; } -#endif -void DSA_get0_pqg(const DSA *d, - const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +const BIGNUM *DSA_get0_g(const DSA *d) { - if (p != NULL) - *p = d->p; - if (q != NULL) - *q = d->q; - if (g != NULL) - *g = d->g; + return d->params.g; } -int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) +const BIGNUM *DSA_get0_pub_key(const DSA *d) { - /* If the fields p, q and g in d are NULL, the corresponding input - * parameters MUST be non-NULL. - */ - if ((d->p == NULL && p == NULL) - || (d->q == NULL && q == NULL) - || (d->g == NULL && g == NULL)) - return 0; - - if (p != NULL) { - BN_free(d->p); - d->p = p; - } - if (q != NULL) { - BN_free(d->q); - d->q = q; - } - if (g != NULL) { - BN_free(d->g); - d->g = g; - } + return d->pub_key; +} - return 1; +const BIGNUM *DSA_get0_priv_key(const DSA *d) +{ + return d->priv_key; } void DSA_get0_key(const DSA *d, @@ -288,13 +311,6 @@ void DSA_get0_key(const DSA *d, int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) { - /* If the field pub_key in d is NULL, the corresponding input - * parameters MUST be non-NULL. The priv_key field may - * be left NULL. - */ - if (d->pub_key == NULL && pub_key == NULL) - return 0; - if (pub_key != NULL) { BN_free(d->pub_key); d->pub_key = pub_key; @@ -303,56 +319,44 @@ int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) BN_free(d->priv_key); d->priv_key = priv_key; } + d->dirty_cnt++; return 1; } -const BIGNUM *DSA_get0_p(const DSA *d) -{ - return d->p; -} - -const BIGNUM *DSA_get0_q(const DSA *d) -{ - return d->q; -} - -const BIGNUM *DSA_get0_g(const DSA *d) -{ - return d->g; -} - -const BIGNUM *DSA_get0_pub_key(const DSA *d) -{ - return d->pub_key; -} - -const BIGNUM *DSA_get0_priv_key(const DSA *d) +int DSA_security_bits(const DSA *d) { - return d->priv_key; + if (d->params.p != NULL && d->params.q != NULL) + return BN_security_bits(BN_num_bits(d->params.p), + BN_num_bits(d->params.q)); + return -1; } -void DSA_clear_flags(DSA *d, int flags) +int DSA_bits(const DSA *dsa) { - d->flags &= ~flags; + if (dsa->params.p != NULL) + return BN_num_bits(dsa->params.p); + return -1; } -int DSA_test_flags(const DSA *d, int flags) +FFC_PARAMS *ossl_dsa_get0_params(DSA *dsa) { - return d->flags & flags; + return &dsa->params; } -void DSA_set_flags(DSA *d, int flags) +int ossl_dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[]) { - d->flags |= flags; -} + int ret; + FFC_PARAMS *ffc; -ENGINE *DSA_get0_engine(DSA *d) -{ - return d->engine; -} + if (dsa == NULL) + return 0; + ffc = ossl_dsa_get0_params(dsa); + if (ffc == NULL) + return 0; -int DSA_bits(const DSA *dsa) -{ - return BN_num_bits(dsa->p); + ret = ossl_ffc_params_fromdata(ffc, params); + if (ret) + dsa->dirty_cnt++; + return ret; } diff --git a/crypto/openssl/crypto/dsa/dsa_local.h b/crypto/openssl/crypto/dsa/dsa_local.h index a81a4b49788d..9e33fae131ea 100644 --- a/crypto/openssl/crypto/dsa/dsa_local.h +++ b/crypto/openssl/crypto/dsa/dsa_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,6 +9,7 @@ #include #include "internal/refcount.h" +#include "internal/ffc.h" struct dsa_st { /* @@ -17,20 +18,24 @@ struct dsa_st { */ int pad; int32_t version; - BIGNUM *p; - BIGNUM *q; /* == 20 */ - BIGNUM *g; + FFC_PARAMS params; BIGNUM *pub_key; /* y public key */ BIGNUM *priv_key; /* x private key */ int flags; /* Normally used to cache montgomery values */ BN_MONT_CTX *method_mont_p; CRYPTO_REF_COUNT references; +#ifndef FIPS_MODULE CRYPTO_EX_DATA ex_data; +#endif const DSA_METHOD *meth; /* functional reference if 'meth' is ENGINE-provided */ ENGINE *engine; CRYPTO_RWLOCK *lock; + OSSL_LIB_CTX *libctx; + + /* Provider data */ + size_t dirty_cnt; /* If any key material changes, increment this */ }; struct DSA_SIG_st { @@ -64,14 +69,4 @@ struct dsa_method { int (*dsa_keygen) (DSA *dsa); }; -int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, - const EVP_MD *evpmd, const unsigned char *seed_in, - size_t seed_len, unsigned char *seed_out, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb); - -int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, - const EVP_MD *evpmd, const unsigned char *seed_in, - size_t seed_len, int idx, unsigned char *seed_out, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb); +DSA_SIG *ossl_dsa_do_sign_int(const unsigned char *dgst, int dlen, DSA *dsa); diff --git a/crypto/openssl/crypto/dsa/dsa_meth.c b/crypto/openssl/crypto/dsa/dsa_meth.c index 1e6ee2f4ed3b..2f0a0bf4608e 100644 --- a/crypto/openssl/crypto/dsa/dsa_meth.c +++ b/crypto/openssl/crypto/dsa/dsa_meth.c @@ -1,24 +1,23 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ /* - * Licensed under the OpenSSL licenses, (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * https://www.openssl.org/source/license.html - * or in the file LICENSE in the source distribution. + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. */ +#include "internal/deprecated.h" #include "dsa_local.h" #include #include +#ifndef OPENSSL_NO_DEPRECATED_3_0 DSA_METHOD *DSA_meth_new(const char *name, int flags) { DSA_METHOD *dsam = OPENSSL_zalloc(sizeof(*dsam)); @@ -33,7 +32,7 @@ DSA_METHOD *DSA_meth_new(const char *name, int flags) OPENSSL_free(dsam); } - DSAerr(DSA_F_DSA_METH_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -59,7 +58,7 @@ DSA_METHOD *DSA_meth_dup(const DSA_METHOD *dsam) OPENSSL_free(ret); } - DSAerr(DSA_F_DSA_METH_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -73,7 +72,7 @@ int DSA_meth_set1_name(DSA_METHOD *dsam, const char *name) char *tmpname = OPENSSL_strdup(name); if (tmpname == NULL) { - DSAerr(DSA_F_DSA_METH_SET1_NAME, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -222,3 +221,4 @@ int DSA_meth_set_keygen(DSA_METHOD *dsam, int (*keygen) (DSA *)) dsam->dsa_keygen = keygen; return 1; } +#endif diff --git a/crypto/openssl/crypto/dsa/dsa_ossl.c b/crypto/openssl/crypto/dsa/dsa_ossl.c index a983def64e76..86d89f4c724f 100644 --- a/crypto/openssl/crypto/dsa/dsa_ossl.c +++ b/crypto/openssl/crypto/dsa/dsa_ossl.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include "crypto/bn.h" @@ -44,10 +50,12 @@ static DSA_METHOD openssl_dsa_meth = { static const DSA_METHOD *default_DSA_method = &openssl_dsa_meth; +#ifndef FIPS_MODULE void DSA_set_default_method(const DSA_METHOD *meth) { default_DSA_method = meth; } +#endif /* FIPS_MODULE */ const DSA_METHOD *DSA_get_default_method(void) { @@ -59,7 +67,7 @@ const DSA_METHOD *DSA_OpenSSL(void) return &openssl_dsa_meth; } -static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +DSA_SIG *ossl_dsa_do_sign_int(const unsigned char *dgst, int dlen, DSA *dsa) { BIGNUM *kinv = NULL; BIGNUM *m, *blind, *blindm, *tmp; @@ -68,7 +76,9 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) DSA_SIG *ret = NULL; int rv = 0; - if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { + if (dsa->params.p == NULL + || dsa->params.q == NULL + || dsa->params.g == NULL) { reason = DSA_R_MISSING_PARAMETERS; goto err; } @@ -85,7 +95,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) if (ret->r == NULL || ret->s == NULL) goto err; - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(dsa->libctx); if (ctx == NULL) goto err; m = BN_CTX_get(ctx); @@ -99,13 +109,13 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) if (!dsa_sign_setup(dsa, ctx, &kinv, &ret->r, dgst, dlen)) goto err; - if (dlen > BN_num_bytes(dsa->q)) + if (dlen > BN_num_bytes(dsa->params.q)) /* * if the digest length is greater than the size of q use the * BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3, * 4.2 */ - dlen = BN_num_bytes(dsa->q); + dlen = BN_num_bytes(dsa->params.q); if (BN_bin2bn(dgst, dlen, m) == NULL) goto err; @@ -121,8 +131,8 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) /* Generate a blinding value */ do { - if (!BN_priv_rand(blind, BN_num_bits(dsa->q) - 1, - BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) + if (!BN_priv_rand_ex(blind, BN_num_bits(dsa->params.q) - 1, + BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, 0, ctx)) goto err; } while (BN_is_zero(blind)); BN_set_flags(blind, BN_FLG_CONSTTIME); @@ -130,27 +140,27 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) BN_set_flags(tmp, BN_FLG_CONSTTIME); /* tmp := blind * priv_key * r mod q */ - if (!BN_mod_mul(tmp, blind, dsa->priv_key, dsa->q, ctx)) + if (!BN_mod_mul(tmp, blind, dsa->priv_key, dsa->params.q, ctx)) goto err; - if (!BN_mod_mul(tmp, tmp, ret->r, dsa->q, ctx)) + if (!BN_mod_mul(tmp, tmp, ret->r, dsa->params.q, ctx)) goto err; /* blindm := blind * m mod q */ - if (!BN_mod_mul(blindm, blind, m, dsa->q, ctx)) + if (!BN_mod_mul(blindm, blind, m, dsa->params.q, ctx)) goto err; /* s : = (blind * priv_key * r) + (blind * m) mod q */ - if (!BN_mod_add_quick(ret->s, tmp, blindm, dsa->q)) + if (!BN_mod_add_quick(ret->s, tmp, blindm, dsa->params.q)) goto err; /* s := s * k^-1 mod q */ - if (!BN_mod_mul(ret->s, ret->s, kinv, dsa->q, ctx)) + if (!BN_mod_mul(ret->s, ret->s, kinv, dsa->params.q, ctx)) goto err; /* s:= s * blind^-1 mod q */ - if (BN_mod_inverse(blind, blind, dsa->q, ctx) == NULL) + if (BN_mod_inverse(blind, blind, dsa->params.q, ctx) == NULL) goto err; - if (!BN_mod_mul(ret->s, ret->s, blind, dsa->q, ctx)) + if (!BN_mod_mul(ret->s, ret->s, blind, dsa->params.q, ctx)) goto err; /* @@ -164,7 +174,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) err: if (rv == 0) { - DSAerr(DSA_F_DSA_DO_SIGN, reason); + ERR_raise(ERR_LIB_DSA, reason); DSA_SIG_free(ret); ret = NULL; } @@ -173,6 +183,11 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) return ret; } +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +{ + return ossl_dsa_do_sign_int(dgst, dlen, dsa); +} + static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { @@ -189,18 +204,20 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, int ret = 0; int q_bits, q_words; - if (!dsa->p || !dsa->q || !dsa->g) { - DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); + if (!dsa->params.p || !dsa->params.q || !dsa->params.g) { + ERR_raise(ERR_LIB_DSA, DSA_R_MISSING_PARAMETERS); return 0; } /* Reject obviously invalid parameters */ - if (BN_is_zero(dsa->p) || BN_is_zero(dsa->q) || BN_is_zero(dsa->g)) { - DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_INVALID_PARAMETERS); + if (BN_is_zero(dsa->params.p) + || BN_is_zero(dsa->params.q) + || BN_is_zero(dsa->params.g)) { + ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_PARAMETERS); return 0; } if (dsa->priv_key == NULL) { - DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PRIVATE_KEY); + ERR_raise(ERR_LIB_DSA, DSA_R_MISSING_PRIVATE_KEY); return 0; } @@ -210,14 +227,15 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, goto err; if (ctx_in == NULL) { - if ((ctx = BN_CTX_new()) == NULL) + /* if you don't pass in ctx_in you get a default libctx */ + if ((ctx = BN_CTX_new_ex(NULL)) == NULL) goto err; } else ctx = ctx_in; /* Preallocate space */ - q_bits = BN_num_bits(dsa->q); - q_words = bn_get_top(dsa->q); + q_bits = BN_num_bits(dsa->params.q); + q_words = bn_get_top(dsa->params.q); if (!bn_wexpand(k, q_words + 2) || !bn_wexpand(l, q_words + 2)) goto err; @@ -229,10 +247,10 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, * We calculate k from SHA512(private_key + H(message) + random). * This protects the private key from a weak PRNG. */ - if (!BN_generate_dsa_nonce(k, dsa->q, dsa->priv_key, dgst, + if (!BN_generate_dsa_nonce(k, dsa->params.q, dsa->priv_key, dgst, dlen, ctx)) goto err; - } else if (!BN_priv_rand_range(k, dsa->q)) + } else if (!BN_priv_rand_range_ex(k, dsa->params.q, 0, ctx)) goto err; } while (BN_is_zero(k)); @@ -241,7 +259,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, - dsa->lock, dsa->p, ctx)) + dsa->lock, dsa->params.p, ctx)) goto err; } @@ -260,26 +278,27 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, * https://github.com/openssl/openssl/pull/7486#discussion_r228323705 * The fix is to rework BN so these gymnastics aren't required. */ - if (!BN_add(l, k, dsa->q) - || !BN_add(k, l, dsa->q)) + if (!BN_add(l, k, dsa->params.q) + || !BN_add(k, l, dsa->params.q)) goto err; BN_consttime_swap(BN_is_bit_set(l, q_bits), k, l, q_words + 2); if ((dsa)->meth->bn_mod_exp != NULL) { - if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx, - dsa->method_mont_p)) + if (!dsa->meth->bn_mod_exp(dsa, r, dsa->params.g, k, dsa->params.p, + ctx, dsa->method_mont_p)) goto err; } else { - if (!BN_mod_exp_mont(r, dsa->g, k, dsa->p, ctx, dsa->method_mont_p)) + if (!BN_mod_exp_mont(r, dsa->params.g, k, dsa->params.p, ctx, + dsa->method_mont_p)) goto err; } - if (!BN_mod(r, r, dsa->q, ctx)) + if (!BN_mod(r, r, dsa->params.q, ctx)) goto err; /* Compute part of 's = inv(k) (m + xr) mod q' */ - if ((kinv = dsa_mod_inverse_fermat(k, dsa->q, ctx)) == NULL) + if ((kinv = dsa_mod_inverse_fermat(k, dsa->params.q, ctx)) == NULL) goto err; BN_clear_free(*kinvp); @@ -288,7 +307,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, ret = 1; err: if (!ret) - DSAerr(DSA_F_DSA_SIGN_SETUP, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_DSA, ERR_R_BN_LIB); if (ctx != ctx_in) BN_CTX_free(ctx); BN_clear_free(k); @@ -304,38 +323,41 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, BN_MONT_CTX *mont = NULL; const BIGNUM *r, *s; int ret = -1, i; - if (!dsa->p || !dsa->q || !dsa->g) { - DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS); + + if (dsa->params.p == NULL + || dsa->params.q == NULL + || dsa->params.g == NULL) { + ERR_raise(ERR_LIB_DSA, DSA_R_MISSING_PARAMETERS); return -1; } - i = BN_num_bits(dsa->q); + i = BN_num_bits(dsa->params.q); /* fips 186-3 allows only different sizes for q */ if (i != 160 && i != 224 && i != 256) { - DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE); + ERR_raise(ERR_LIB_DSA, DSA_R_BAD_Q_VALUE); return -1; } - if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { - DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE); + if (BN_num_bits(dsa->params.p) > OPENSSL_DSA_MAX_MODULUS_BITS) { + ERR_raise(ERR_LIB_DSA, DSA_R_MODULUS_TOO_LARGE); return -1; } u1 = BN_new(); u2 = BN_new(); t1 = BN_new(); - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(NULL); /* verify does not need a libctx */ if (u1 == NULL || u2 == NULL || t1 == NULL || ctx == NULL) goto err; DSA_SIG_get0(sig, &r, &s); if (BN_is_zero(r) || BN_is_negative(r) || - BN_ucmp(r, dsa->q) >= 0) { + BN_ucmp(r, dsa->params.q) >= 0) { ret = 0; goto err; } if (BN_is_zero(s) || BN_is_negative(s) || - BN_ucmp(s, dsa->q) >= 0) { + BN_ucmp(s, dsa->params.q) >= 0) { ret = 0; goto err; } @@ -343,7 +365,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, /* * Calculate W = inv(S) mod Q save W in u2 */ - if ((BN_mod_inverse(u2, s, dsa->q, ctx)) == NULL) + if ((BN_mod_inverse(u2, s, dsa->params.q, ctx)) == NULL) goto err; /* save M in u1 */ @@ -358,32 +380,32 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, goto err; /* u1 = M * w mod q */ - if (!BN_mod_mul(u1, u1, u2, dsa->q, ctx)) + if (!BN_mod_mul(u1, u1, u2, dsa->params.q, ctx)) goto err; /* u2 = r * w mod q */ - if (!BN_mod_mul(u2, r, u2, dsa->q, ctx)) + if (!BN_mod_mul(u2, r, u2, dsa->params.q, ctx)) goto err; if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p, - dsa->lock, dsa->p, ctx); + dsa->lock, dsa->params.p, ctx); if (!mont) goto err; } if (dsa->meth->dsa_mod_exp != NULL) { - if (!dsa->meth->dsa_mod_exp(dsa, t1, dsa->g, u1, dsa->pub_key, u2, - dsa->p, ctx, mont)) + if (!dsa->meth->dsa_mod_exp(dsa, t1, dsa->params.g, u1, dsa->pub_key, u2, + dsa->params.p, ctx, mont)) goto err; } else { - if (!BN_mod_exp2_mont(t1, dsa->g, u1, dsa->pub_key, u2, dsa->p, ctx, - mont)) + if (!BN_mod_exp2_mont(t1, dsa->params.g, u1, dsa->pub_key, u2, + dsa->params.p, ctx, mont)) goto err; } /* let u1 = u1 mod q */ - if (!BN_mod(u1, t1, dsa->q, ctx)) + if (!BN_mod(u1, t1, dsa->params.q, ctx)) goto err; /* @@ -393,7 +415,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, err: if (ret < 0) - DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_DSA, ERR_R_BN_LIB); BN_CTX_free(ctx); BN_free(u1); BN_free(u2); @@ -404,6 +426,8 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, static int dsa_init(DSA *dsa) { dsa->flags |= DSA_FLAG_CACHE_MONT_P; + ossl_ffc_params_init(&dsa->params); + dsa->dirty_cnt++; return 1; } diff --git a/crypto/openssl/crypto/dsa/dsa_pmeth.c b/crypto/openssl/crypto/dsa/dsa_pmeth.c index 4ca3747a4646..ba6be720a296 100644 --- a/crypto/openssl/crypto/dsa/dsa_pmeth.c +++ b/crypto/openssl/crypto/dsa/dsa_pmeth.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -47,7 +53,7 @@ static int pkey_dsa_init(EVP_PKEY_CTX *ctx) return 1; } -static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +static int pkey_dsa_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) { DSA_PKEY_CTX *dctx, *sctx; @@ -75,9 +81,14 @@ static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int ret; unsigned int sltmp; DSA_PKEY_CTX *dctx = ctx->data; - DSA *dsa = ctx->pkey->pkey.dsa; - - if (dctx->md != NULL && tbslen != (size_t)EVP_MD_size(dctx->md)) + /* + * Discard const. Its marked as const because this may be a cached copy of + * the "real" key. These calls don't make any modifications that need to + * be reflected back in the "original" key. + */ + DSA *dsa = (DSA *)EVP_PKEY_get0_DSA(ctx->pkey); + + if (dctx->md != NULL && tbslen != (size_t)EVP_MD_get_size(dctx->md)) return 0; ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, dsa); @@ -94,9 +105,14 @@ static int pkey_dsa_verify(EVP_PKEY_CTX *ctx, { int ret; DSA_PKEY_CTX *dctx = ctx->data; - DSA *dsa = ctx->pkey->pkey.dsa; - - if (dctx->md != NULL && tbslen != (size_t)EVP_MD_size(dctx->md)) + /* + * Discard const. Its marked as const because this may be a cached copy of + * the "real" key. These calls don't make any modifications that need to + * be reflected back in the "original" key. + */ + DSA *dsa = (DSA *)EVP_PKEY_get0_DSA(ctx->pkey); + + if (dctx->md != NULL && tbslen != (size_t)EVP_MD_get_size(dctx->md)) return 0; ret = DSA_verify(0, tbs, tbslen, sig, siglen, dsa); @@ -122,28 +138,28 @@ static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: - if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha256) { - DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); + if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256) { + ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE); return 0; } dctx->pmd = p2; return 1; case EVP_PKEY_CTRL_MD: - if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && - EVP_MD_type((const EVP_MD *)p2) != NID_dsa && - EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA && - EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha512 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) { - DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); + if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_dsa && + EVP_MD_get_type((const EVP_MD *)p2) != NID_dsaWithSHA && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha384 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha512 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_224 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_256 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_384 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_512) { + ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE); return 0; } dctx->md = p2; @@ -159,8 +175,7 @@ static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_PEER_KEY: - DSAerr(DSA_F_PKEY_DSA_CTRL, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ERR_raise(ERR_LIB_DSA, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; default: return -2; @@ -184,7 +199,7 @@ static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, const EVP_MD *md = EVP_get_digestbyname(value); if (md == NULL) { - DSAerr(DSA_F_PKEY_DSA_CTRL_STR, DSA_R_INVALID_DIGEST_TYPE); + ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE); return 0; } return EVP_PKEY_CTX_set_dsa_paramgen_md(ctx, md); @@ -197,7 +212,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) DSA *dsa = NULL; DSA_PKEY_CTX *dctx = ctx->data; BN_GENCB *pcb; - int ret; + int ret, res; if (ctx->pkey_gencb) { pcb = BN_GENCB_new(); @@ -211,10 +226,14 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) BN_GENCB_free(pcb); return 0; } - ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, - NULL, 0, NULL, NULL, NULL, pcb); + if (dctx->md != NULL) + ossl_ffc_set_digest(&dsa->params, EVP_MD_get0_name(dctx->md), NULL); + + ret = ossl_ffc_params_FIPS186_4_generate(NULL, &dsa->params, + FFC_PARAM_TYPE_DSA, dctx->nbits, + dctx->qbits, &res, pcb); BN_GENCB_free(pcb); - if (ret) + if (ret > 0) EVP_PKEY_assign_DSA(pkey, dsa); else DSA_free(dsa); @@ -226,7 +245,7 @@ static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) DSA *dsa = NULL; if (ctx->pkey == NULL) { - DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET); + ERR_raise(ERR_LIB_DSA, DSA_R_NO_PARAMETERS_SET); return 0; } dsa = DSA_new(); @@ -236,10 +255,10 @@ static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) /* Note: if error return, pkey is freed by parent routine */ if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) return 0; - return DSA_generate_key(pkey->pkey.dsa); + return DSA_generate_key((DSA *)EVP_PKEY_get0_DSA(pkey)); } -const EVP_PKEY_METHOD dsa_pkey_meth = { +static const EVP_PKEY_METHOD dsa_pkey_meth = { EVP_PKEY_DSA, EVP_PKEY_FLAG_AUTOARGLEN, pkey_dsa_init, @@ -271,3 +290,8 @@ const EVP_PKEY_METHOD dsa_pkey_meth = { pkey_dsa_ctrl, pkey_dsa_ctrl_str }; + +const EVP_PKEY_METHOD *ossl_dsa_pkey_method(void) +{ + return &dsa_pkey_meth; +} diff --git a/crypto/openssl/crypto/dsa/dsa_prn.c b/crypto/openssl/crypto/dsa/dsa_prn.c index 070b881e1fae..1164e0f5cbff 100644 --- a/crypto/openssl/crypto/dsa/dsa_prn.c +++ b/crypto/openssl/crypto/dsa/dsa_prn.c @@ -1,12 +1,18 @@ /* * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -19,7 +25,7 @@ int DSA_print_fp(FILE *fp, const DSA *x, int off) int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - DSAerr(DSA_F_DSA_PRINT_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_DSA, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -34,7 +40,7 @@ int DSAparams_print_fp(FILE *fp, const DSA *x) int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - DSAerr(DSA_F_DSAPARAMS_PRINT_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_DSA, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); diff --git a/crypto/openssl/crypto/dsa/dsa_sign.c b/crypto/openssl/crypto/dsa/dsa_sign.c index 51c7754b93e4..21b0cbd5fbef 100644 --- a/crypto/openssl/crypto/dsa/dsa_sign.c +++ b/crypto/openssl/crypto/dsa/dsa_sign.c @@ -1,24 +1,209 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include #include "internal/cryptlib.h" #include "dsa_local.h" -#include +#include "crypto/asn1_dsa.h" +#include "crypto/dsa.h" DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { return dsa->meth->dsa_do_sign(dgst, dlen, dsa); } -#if OPENSSL_API_COMPAT < 0x10200000L +#ifndef OPENSSL_NO_DEPRECATED_3_0 int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); } #endif + +DSA_SIG *DSA_SIG_new(void) +{ + DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); + if (sig == NULL) + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + return sig; +} + +void DSA_SIG_free(DSA_SIG *sig) +{ + if (sig == NULL) + return; + BN_clear_free(sig->r); + BN_clear_free(sig->s); + OPENSSL_free(sig); +} + +DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len) +{ + DSA_SIG *sig; + + if (len < 0) + return NULL; + if (psig != NULL && *psig != NULL) { + sig = *psig; + } else { + sig = DSA_SIG_new(); + if (sig == NULL) + return NULL; + } + if (sig->r == NULL) + sig->r = BN_new(); + if (sig->s == NULL) + sig->s = BN_new(); + if (sig->r == NULL || sig->s == NULL + || ossl_decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { + if (psig == NULL || *psig == NULL) + DSA_SIG_free(sig); + return NULL; + } + if (psig != NULL && *psig == NULL) + *psig = sig; + return sig; +} + +int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout) +{ + BUF_MEM *buf = NULL; + size_t encoded_len; + WPACKET pkt; + + if (ppout == NULL) { + if (!WPACKET_init_null(&pkt, 0)) + return -1; + } else if (*ppout == NULL) { + if ((buf = BUF_MEM_new()) == NULL + || !WPACKET_init_len(&pkt, buf, 0)) { + BUF_MEM_free(buf); + return -1; + } + } else { + if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0)) + return -1; + } + + if (!ossl_encode_der_dsa_sig(&pkt, sig->r, sig->s) + || !WPACKET_get_total_written(&pkt, &encoded_len) + || !WPACKET_finish(&pkt)) { + BUF_MEM_free(buf); + WPACKET_cleanup(&pkt); + return -1; + } + + if (ppout != NULL) { + if (*ppout == NULL) { + *ppout = (unsigned char *)buf->data; + buf->data = NULL; + BUF_MEM_free(buf); + } else { + *ppout += encoded_len; + } + } + + return (int)encoded_len; +} + +int DSA_size(const DSA *dsa) +{ + int ret = -1; + DSA_SIG sig; + + if (dsa->params.q != NULL) { + sig.r = sig.s = dsa->params.q; + ret = i2d_DSA_SIG(&sig, NULL); + + if (ret < 0) + ret = 0; + } + return ret; +} + +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} + +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return 0; + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} + +int ossl_dsa_sign_int(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa) +{ + DSA_SIG *s; + + /* legacy case uses the method table */ + if (dsa->libctx == NULL || dsa->meth != DSA_get_default_method()) + s = DSA_do_sign(dgst, dlen, dsa); + else + s = ossl_dsa_do_sign_int(dgst, dlen, dsa); + if (s == NULL) { + *siglen = 0; + return 0; + } + *siglen = i2d_DSA_SIG(s, &sig); + DSA_SIG_free(s); + return 1; +} + +int DSA_sign(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa) +{ + return ossl_dsa_sign_int(type, dgst, dlen, sig, siglen, dsa); +} + +/* data has already been hashed (probably with SHA or SHA-1). */ +/*- + * returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa) +{ + DSA_SIG *s; + const unsigned char *p = sigbuf; + unsigned char *der = NULL; + int derlen = -1; + int ret = -1; + + s = DSA_SIG_new(); + if (s == NULL) + return ret; + if (d2i_DSA_SIG(&s, &p, siglen) == NULL) + goto err; + /* Ensure signature uses DER and doesn't have trailing garbage */ + derlen = i2d_DSA_SIG(s, &der); + if (derlen != siglen || memcmp(sigbuf, der, derlen)) + goto err; + ret = DSA_do_verify(dgst, dgst_len, s, dsa); + err: + OPENSSL_clear_free(der, derlen); + DSA_SIG_free(s); + return ret; +} diff --git a/crypto/openssl/crypto/dsa/dsa_vrf.c b/crypto/openssl/crypto/dsa/dsa_vrf.c index 6f80a4aab7a5..b0a9d965d959 100644 --- a/crypto/openssl/crypto/dsa/dsa_vrf.c +++ b/crypto/openssl/crypto/dsa/dsa_vrf.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" #include "dsa_local.h" diff --git a/crypto/openssl/crypto/dso/dso_dl.c b/crypto/openssl/crypto/dso/dso_dl.c index 3bbb10e5ca98..f4e6e5f4573f 100644 --- a/crypto/openssl/crypto/dso/dso_dl.c +++ b/crypto/openssl/crypto/dso/dso_dl.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -61,7 +61,7 @@ static int dl_load(DSO *dso) char *filename = DSO_convert_filename(dso, NULL); if (filename == NULL) { - DSOerr(DSO_F_DL_LOAD, DSO_R_NO_FILENAME); + ERR_raise(ERR_LIB_DSO, DSO_R_NO_FILENAME); goto err; } ptr = shl_load(filename, BIND_IMMEDIATE | @@ -69,13 +69,17 @@ static int dl_load(DSO *dso) DYNAMIC_PATH), 0L); if (ptr == NULL) { char errbuf[160]; - DSOerr(DSO_F_DL_LOAD, DSO_R_LOAD_FAILED); + if (openssl_strerror_r(errno, errbuf, sizeof(errbuf))) - ERR_add_error_data(4, "filename(", filename, "): ", errbuf); + ERR_raise_data(ERR_LIB_DSO, DSO_R_LOAD_FAILED, + "filename(%s): %s", filename, errbuf); + else + ERR_raise_data(ERR_LIB_DSO, DSO_R_LOAD_FAILED, + "filename(%s): errno %d", filename, errno); goto err; } if (!sk_push(dso->meth_data, (char *)ptr)) { - DSOerr(DSO_F_DL_LOAD, DSO_R_STACK_ERROR); + ERR_raise(ERR_LIB_DSO, DSO_R_STACK_ERROR); goto err; } /* @@ -96,7 +100,7 @@ static int dl_unload(DSO *dso) { shl_t ptr; if (dso == NULL) { - DSOerr(DSO_F_DL_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (sk_num(dso->meth_data) < 1) @@ -104,7 +108,7 @@ static int dl_unload(DSO *dso) /* Is this statement legal? */ ptr = (shl_t) sk_pop(dso->meth_data); if (ptr == NULL) { - DSOerr(DSO_F_DL_UNLOAD, DSO_R_NULL_HANDLE); + ERR_raise(ERR_LIB_DSO, DSO_R_NULL_HANDLE); /* * Should push the value back onto the stack in case of a retry. */ @@ -121,23 +125,27 @@ static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname) void *sym; if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_DL_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (sk_num(dso->meth_data) < 1) { - DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_STACK_ERROR); + ERR_raise(ERR_LIB_DSO, DSO_R_STACK_ERROR); return NULL; } ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); if (ptr == NULL) { - DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_NULL_HANDLE); + ERR_raise(ERR_LIB_DSO, DSO_R_NULL_HANDLE); return NULL; } if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) { char errbuf[160]; - DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_SYM_FAILURE); + if (openssl_strerror_r(errno, errbuf, sizeof(errbuf))) - ERR_add_error_data(4, "symname(", symname, "): ", errbuf); + ERR_raise_data(ERR_LIB_DSO, DSO_R_SYM_FAILURE, + "symname(%s): %s", symname, errbuf); + else + ERR_raise_data(ERR_LIB_DSO, DSO_R_SYM_FAILURE, + "symname(%s): errno %d", symname, errno); return NULL; } return (DSO_FUNC_TYPE)sym; @@ -148,7 +156,7 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) char *merged; if (!filespec1 && !filespec2) { - DSOerr(DSO_F_DL_MERGER, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return NULL; } /* @@ -158,7 +166,7 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) if (!filespec2 || filespec1[0] == '/') { merged = OPENSSL_strdup(filespec1); if (merged == NULL) { - DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); return NULL; } } @@ -168,7 +176,7 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) else if (!filespec1) { merged = OPENSSL_strdup(filespec2); if (merged == NULL) { - DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); return NULL; } } else @@ -191,7 +199,7 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) } merged = OPENSSL_malloc(len + 2); if (merged == NULL) { - DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); return NULL; } strcpy(merged, filespec2); @@ -216,7 +224,7 @@ static char *dl_name_converter(DSO *dso, const char *filename) len = strlen(filename); rsize = len + 1; transform = (strstr(filename, "/") == NULL); - { + if (transform) { /* We will convert this to "%s.s?" or "lib%s.s?" */ rsize += strlen(DSO_EXTENSION); /* The length of ".s?" */ if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) @@ -224,7 +232,7 @@ static char *dl_name_converter(DSO *dso, const char *filename) } translated = OPENSSL_malloc(rsize); if (translated == NULL) { - DSOerr(DSO_F_DL_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); + ERR_raise(ERR_LIB_DSO, DSO_R_NAME_TRANSLATION_FAILED); return NULL; } if (transform) { diff --git a/crypto/openssl/crypto/dso/dso_dlfcn.c b/crypto/openssl/crypto/dso/dso_dlfcn.c index 4719e8f4f337..6a988cc72791 100644 --- a/crypto/openssl/crypto/dso/dso_dlfcn.c +++ b/crypto/openssl/crypto/dso/dso_dlfcn.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -30,7 +30,7 @@ # if defined(__SCO_VERSION__) || defined(_SCO_ELF) || \ (defined(__osf__) && !defined(RTLD_NEXT)) || \ (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \ - defined(__ANDROID__) + defined(__ANDROID__) || defined(__TANDEM) # undef HAVE_DLINFO # endif # endif @@ -102,7 +102,7 @@ static int dlfcn_load(DSO *dso) int saveerrno = get_last_sys_error(); if (filename == NULL) { - DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME); + ERR_raise(ERR_LIB_DSO, DSO_R_NO_FILENAME); goto err; } # ifdef RTLD_GLOBAL @@ -115,8 +115,8 @@ static int dlfcn_load(DSO *dso) # endif ptr = dlopen(filename, flags); if (ptr == NULL) { - DSOerr(DSO_F_DLFCN_LOAD, DSO_R_LOAD_FAILED); - ERR_add_error_data(4, "filename(", filename, "): ", dlerror()); + ERR_raise_data(ERR_LIB_DSO, DSO_R_LOAD_FAILED, + "filename(%s): %s", filename, dlerror()); goto err; } /* @@ -125,7 +125,7 @@ static int dlfcn_load(DSO *dso) */ set_sys_error(saveerrno); if (!sk_void_push(dso->meth_data, (char *)ptr)) { - DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR); + ERR_raise(ERR_LIB_DSO, DSO_R_STACK_ERROR); goto err; } /* Success */ @@ -143,14 +143,14 @@ static int dlfcn_unload(DSO *dso) { void *ptr; if (dso == NULL) { - DSOerr(DSO_F_DLFCN_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (sk_void_num(dso->meth_data) < 1) return 1; ptr = sk_void_pop(dso->meth_data); if (ptr == NULL) { - DSOerr(DSO_F_DLFCN_UNLOAD, DSO_R_NULL_HANDLE); + ERR_raise(ERR_LIB_DSO, DSO_R_NULL_HANDLE); /* * Should push the value back onto the stack in case of a retry. */ @@ -171,22 +171,22 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) } u; if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_DLFCN_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (sk_void_num(dso->meth_data) < 1) { - DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_STACK_ERROR); + ERR_raise(ERR_LIB_DSO, DSO_R_STACK_ERROR); return NULL; } ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); if (ptr == NULL) { - DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_NULL_HANDLE); + ERR_raise(ERR_LIB_DSO, DSO_R_NULL_HANDLE); return NULL; } u.dlret = dlsym(ptr, symname); if (u.dlret == NULL) { - DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_SYM_FAILURE); - ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); + ERR_raise_data(ERR_LIB_DSO, DSO_R_SYM_FAILURE, + "symname(%s): %s", symname, dlerror()); return NULL; } return u.sym; @@ -198,7 +198,7 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1, char *merged; if (!filespec1 && !filespec2) { - DSOerr(DSO_F_DLFCN_MERGER, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return NULL; } /* @@ -208,7 +208,7 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1, if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) { merged = OPENSSL_strdup(filespec1); if (merged == NULL) { - DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); return NULL; } } @@ -218,7 +218,7 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1, else if (!filespec1) { merged = OPENSSL_strdup(filespec2); if (merged == NULL) { - DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); return NULL; } } else { @@ -240,7 +240,7 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1, } merged = OPENSSL_malloc(len + 2); if (merged == NULL) { - DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); return NULL; } strcpy(merged, filespec2); @@ -266,7 +266,7 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename) } translated = OPENSSL_malloc(rsize); if (translated == NULL) { - DSOerr(DSO_F_DLFCN_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); + ERR_raise(ERR_LIB_DSO, DSO_R_NAME_TRANSLATION_FAILED); return NULL; } if (transform) { diff --git a/crypto/openssl/crypto/dso/dso_err.c b/crypto/openssl/crypto/dso/dso_err.c index 613072a8d6ec..6934a1b364bc 100644 --- a/crypto/openssl/crypto/dso/dso_err.c +++ b/crypto/openssl/crypto/dso/dso_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,48 +13,6 @@ #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA DSO_str_functs[] = { - {ERR_PACK(ERR_LIB_DSO, DSO_F_DLFCN_BIND_FUNC, 0), "dlfcn_bind_func"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DLFCN_LOAD, 0), "dlfcn_load"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DLFCN_MERGER, 0), "dlfcn_merger"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DLFCN_NAME_CONVERTER, 0), - "dlfcn_name_converter"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DLFCN_UNLOAD, 0), "dlfcn_unload"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DL_BIND_FUNC, 0), "dl_bind_func"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DL_LOAD, 0), "dl_load"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DL_MERGER, 0), "dl_merger"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DL_NAME_CONVERTER, 0), "dl_name_converter"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DL_UNLOAD, 0), "dl_unload"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_BIND_FUNC, 0), "DSO_bind_func"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_CONVERT_FILENAME, 0), - "DSO_convert_filename"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_CTRL, 0), "DSO_ctrl"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_FREE, 0), "DSO_free"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_GET_FILENAME, 0), "DSO_get_filename"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_GLOBAL_LOOKUP, 0), "DSO_global_lookup"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_LOAD, 0), "DSO_load"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_MERGE, 0), "DSO_merge"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_NEW_METHOD, 0), "DSO_new_method"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_PATHBYADDR, 0), "DSO_pathbyaddr"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_SET_FILENAME, 0), "DSO_set_filename"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_DSO_UP_REF, 0), "DSO_up_ref"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_VMS_BIND_SYM, 0), "vms_bind_sym"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_VMS_LOAD, 0), "vms_load"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_VMS_MERGER, 0), "vms_merger"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_VMS_UNLOAD, 0), "vms_unload"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_BIND_FUNC, 0), "win32_bind_func"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_GLOBALLOOKUP, 0), "win32_globallookup"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_JOINER, 0), "win32_joiner"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_LOAD, 0), "win32_load"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_MERGER, 0), "win32_merger"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_NAME_CONVERTER, 0), - "win32_name_converter"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_PATHBYADDR, 0), ""}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_SPLITTER, 0), "win32_splitter"}, - {ERR_PACK(ERR_LIB_DSO, DSO_F_WIN32_UNLOAD, 0), "win32_unload"}, - {0, NULL} -}; - static const ERR_STRING_DATA DSO_str_reasons[] = { {ERR_PACK(ERR_LIB_DSO, 0, DSO_R_CTRL_FAILED), "control command failed"}, {ERR_PACK(ERR_LIB_DSO, 0, DSO_R_DSO_ALREADY_LOADED), "dso already loaded"}, @@ -88,13 +46,11 @@ static const ERR_STRING_DATA DSO_str_reasons[] = { #endif -int ERR_load_DSO_strings(void) +int ossl_err_load_DSO_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(DSO_str_functs[0].error) == NULL) { - ERR_load_strings_const(DSO_str_functs); + if (ERR_reason_error_string(DSO_str_reasons[0].error) == NULL) ERR_load_strings_const(DSO_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/dso/dso_lib.c b/crypto/openssl/crypto/dso/dso_lib.c index 50a39bb7d5d8..9d755986d755 100644 --- a/crypto/openssl/crypto/dso/dso_lib.c +++ b/crypto/openssl/crypto/dso/dso_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,37 +10,27 @@ #include "dso_local.h" #include "internal/refcount.h" -static DSO_METHOD *default_DSO_meth = NULL; - static DSO *DSO_new_method(DSO_METHOD *meth) { DSO *ret; - if (default_DSO_meth == NULL) { - /* - * We default to DSO_METH_openssl() which in turn defaults to - * stealing the "best available" method. Will fallback to - * DSO_METH_null() in the worst case. - */ - default_DSO_meth = DSO_METHOD_openssl(); - } ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); return NULL; } ret->meth_data = sk_void_new_null(); if (ret->meth_data == NULL) { /* sk_new doesn't generate any errors so we do */ - DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } - ret->meth = default_DSO_meth; + ret->meth = DSO_METHOD_openssl(); ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); sk_void_free(ret->meth_data); OPENSSL_free(ret); return NULL; @@ -76,13 +66,13 @@ int DSO_free(DSO *dso) if ((dso->flags & DSO_FLAG_NO_UNLOAD_ON_FREE) == 0) { if ((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) { - DSOerr(DSO_F_DSO_FREE, DSO_R_UNLOAD_FAILED); + ERR_raise(ERR_LIB_DSO, DSO_R_UNLOAD_FAILED); return 0; } } if ((dso->meth->finish != NULL) && !dso->meth->finish(dso)) { - DSOerr(DSO_F_DSO_FREE, DSO_R_FINISH_FAILED); + ERR_raise(ERR_LIB_DSO, DSO_R_FINISH_FAILED); return 0; } @@ -104,14 +94,14 @@ int DSO_up_ref(DSO *dso) int i; if (dso == NULL) { - DSOerr(DSO_F_DSO_UP_REF, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (CRYPTO_UP_REF(&dso->references, &i, dso->lock) <= 0) return 0; - REF_PRINT_COUNT("DSO", r); + REF_PRINT_COUNT("DSO", dso); REF_ASSERT_ISNT(i < 2); return ((i > 1) ? 1 : 0); } @@ -124,20 +114,20 @@ DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags) if (dso == NULL) { ret = DSO_new_method(meth); if (ret == NULL) { - DSOerr(DSO_F_DSO_LOAD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); goto err; } allocated = 1; /* Pass the provided flags to the new DSO object */ if (DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_CTRL_FAILED); + ERR_raise(ERR_LIB_DSO, DSO_R_CTRL_FAILED); goto err; } } else ret = dso; /* Don't load if we're currently already loaded */ if (ret->filename != NULL) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_DSO_ALREADY_LOADED); + ERR_raise(ERR_LIB_DSO, DSO_R_DSO_ALREADY_LOADED); goto err; } /* @@ -146,20 +136,20 @@ DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags) */ if (filename != NULL) if (!DSO_set_filename(ret, filename)) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_SET_FILENAME_FAILED); + ERR_raise(ERR_LIB_DSO, DSO_R_SET_FILENAME_FAILED); goto err; } filename = ret->filename; if (filename == NULL) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_NO_FILENAME); + ERR_raise(ERR_LIB_DSO, DSO_R_NO_FILENAME); goto err; } if (ret->meth->dso_load == NULL) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_UNSUPPORTED); + ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED); goto err; } if (!ret->meth->dso_load(ret)) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_LOAD_FAILED); + ERR_raise(ERR_LIB_DSO, DSO_R_LOAD_FAILED); goto err; } /* Load succeeded */ @@ -175,15 +165,15 @@ DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname) DSO_FUNC_TYPE ret = NULL; if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_DSO_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (dso->meth->dso_bind_func == NULL) { - DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_UNSUPPORTED); + ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED); return NULL; } if ((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) { - DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_SYM_FAILURE); + ERR_raise(ERR_LIB_DSO, DSO_R_SYM_FAILURE); return NULL; } /* Success */ @@ -202,7 +192,7 @@ DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname) long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg) { if (dso == NULL) { - DSOerr(DSO_F_DSO_CTRL, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return -1; } /* @@ -222,7 +212,7 @@ long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg) break; } if ((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) { - DSOerr(DSO_F_DSO_CTRL, DSO_R_UNSUPPORTED); + ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED); return -1; } return dso->meth->dso_ctrl(dso, cmd, larg, parg); @@ -231,7 +221,7 @@ long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg) const char *DSO_get_filename(DSO *dso) { if (dso == NULL) { - DSOerr(DSO_F_DSO_GET_FILENAME, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return NULL; } return dso->filename; @@ -242,17 +232,17 @@ int DSO_set_filename(DSO *dso, const char *filename) char *copied; if ((dso == NULL) || (filename == NULL)) { - DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (dso->loaded_filename) { - DSOerr(DSO_F_DSO_SET_FILENAME, DSO_R_DSO_ALREADY_LOADED); + ERR_raise(ERR_LIB_DSO, DSO_R_DSO_ALREADY_LOADED); return 0; } /* We'll duplicate filename */ copied = OPENSSL_strdup(filename); if (copied == NULL) { - DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); return 0; } OPENSSL_free(dso->filename); @@ -265,7 +255,7 @@ char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2) char *result = NULL; if (dso == NULL || filespec1 == NULL) { - DSOerr(DSO_F_DSO_MERGE, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) { @@ -282,13 +272,13 @@ char *DSO_convert_filename(DSO *dso, const char *filename) char *result = NULL; if (dso == NULL) { - DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (filename == NULL) filename = dso->filename; if (filename == NULL) { - DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME); + ERR_raise(ERR_LIB_DSO, DSO_R_NO_FILENAME); return NULL; } if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) { @@ -300,7 +290,7 @@ char *DSO_convert_filename(DSO *dso, const char *filename) if (result == NULL) { result = OPENSSL_strdup(filename); if (result == NULL) { - DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); return NULL; } } @@ -309,11 +299,10 @@ char *DSO_convert_filename(DSO *dso, const char *filename) int DSO_pathbyaddr(void *addr, char *path, int sz) { - DSO_METHOD *meth = default_DSO_meth; - if (meth == NULL) - meth = DSO_METHOD_openssl(); + DSO_METHOD *meth = DSO_METHOD_openssl(); + if (meth->pathbyaddr == NULL) { - DSOerr(DSO_F_DSO_PATHBYADDR, DSO_R_UNSUPPORTED); + ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED); return -1; } return (*meth->pathbyaddr) (addr, path, sz); @@ -339,11 +328,10 @@ DSO *DSO_dsobyaddr(void *addr, int flags) void *DSO_global_lookup(const char *name) { - DSO_METHOD *meth = default_DSO_meth; - if (meth == NULL) - meth = DSO_METHOD_openssl(); + DSO_METHOD *meth = DSO_METHOD_openssl(); + if (meth->globallookup == NULL) { - DSOerr(DSO_F_DSO_GLOBAL_LOOKUP, DSO_R_UNSUPPORTED); + ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED); return NULL; } return (*meth->globallookup) (name); diff --git a/crypto/openssl/crypto/dso/dso_local.h b/crypto/openssl/crypto/dso/dso_local.h index 43b7df9d7832..8aa29c1826fe 100644 --- a/crypto/openssl/crypto/dso/dso_local.h +++ b/crypto/openssl/crypto/dso/dso_local.h @@ -1,7 +1,7 @@ /* * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/dso/dso_openssl.c b/crypto/openssl/crypto/dso/dso_openssl.c index c76a04db23f9..3f264a6c658b 100644 --- a/crypto/openssl/crypto/dso/dso_openssl.c +++ b/crypto/openssl/crypto/dso/dso_openssl.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ebcdic.c b/crypto/openssl/crypto/ebcdic.c index 2a8ca6101067..970ffc015c9d 100644 --- a/crypto/openssl/crypto/ebcdic.c +++ b/crypto/openssl/crypto/ebcdic.c @@ -1,7 +1,7 @@ /* * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ec/asm/ecp_nistp521-ppc64.pl b/crypto/openssl/crypto/ec/asm/ecp_nistp521-ppc64.pl new file mode 100755 index 000000000000..4260e24a1f57 --- /dev/null +++ b/crypto/openssl/crypto/ec/asm/ecp_nistp521-ppc64.pl @@ -0,0 +1,435 @@ +#! /usr/bin/env perl +# Copyright 2021-2022 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 +# +# ==================================================================== +# Written by Amitay Isaacs and Martin Schwenke +# for the OpenSSL project. +# ==================================================================== +# +# p521 lower-level primitives for PPC64 using vector instructions. +# + +use strict; +use warnings; + +my $flavour = shift; +my $output = ""; +while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} +if (!$output) { + $output = "-"; +} + +my ($xlate, $dir); +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +die "can't locate ppc-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +my $code = ""; + +my ($sp, $outp, $savelr, $savesp) = ("r1", "r3", "r10", "r12"); + +my $vzero = "v32"; + +sub startproc($) +{ + my ($name) = @_; + + $code.=<<___; + .globl ${name} + .align 5 +${name}: + +___ +} + +sub endproc($) +{ + my ($name) = @_; + + $code.=<<___; + blr + .size ${name},.-${name} + +___ +} + + +sub push_vrs($$) +{ + my ($min, $max) = @_; + + my $count = $max - $min + 1; + + $code.=<<___; + mr $savesp,$sp + stdu $sp,-16*`$count+1`($sp) + +___ + for (my $i = $min; $i <= $max; $i++) { + my $mult = $max - $i + 1; + $code.=<<___; + stxv $i,-16*$mult($savesp) +___ + + } + + $code.=<<___; + +___ +} + +sub pop_vrs($$) +{ + my ($min, $max) = @_; + + $code.=<<___; + ld $savesp,0($sp) +___ + for (my $i = $min; $i <= $max; $i++) { + my $mult = $max - $i + 1; + $code.=<<___; + lxv $i,-16*$mult($savesp) +___ + } + + $code.=<<___; + mr $sp,$savesp + +___ +} + +sub load_vrs($$) +{ + my ($pointer, $reg_list) = @_; + + for (my $i = 0; $i <= 8; $i++) { + my $offset = $i * 8; + $code.=<<___; + lxsd $reg_list->[$i],$offset($pointer) +___ + } + + $code.=<<___; + +___ +} + +sub store_vrs($$) +{ + my ($pointer, $reg_list) = @_; + + for (my $i = 0; $i <= 8; $i++) { + my $offset = $i * 16; + $code.=<<___; + stxv $reg_list->[$i],$offset($pointer) +___ + } + + $code.=<<___; + +___ +} + +$code.=<<___; +.text + +___ + +{ + # mul/square common + my ($t1, $t2, $t3, $t4) = ("v33", "v34", "v44", "v54"); + my ($zero, $one) = ("r8", "r9"); + my @out = map("v$_",(55..63)); + + { + # + # p521_felem_mul + # + + my ($in1p, $in2p) = ("r4", "r5"); + my @in1 = map("v$_",(45..53)); + my @in2 = map("v$_",(35..43)); + + startproc("p521_felem_mul"); + + push_vrs(52, 63); + + $code.=<<___; + vspltisw $vzero,0 + +___ + + load_vrs($in1p, \@in1); + load_vrs($in2p, \@in2); + + $code.=<<___; + vmsumudm $out[0],$in1[0],$in2[0],$vzero + + xxpermdi $t1,$in1[0],$in1[1],0b00 + xxpermdi $t2,$in2[1],$in2[0],0b00 + vmsumudm $out[1],$t1,$t2,$vzero + + xxpermdi $t2,$in2[2],$in2[1],0b00 + vmsumudm $out[2],$t1,$t2,$vzero + vmsumudm $out[2],$in1[2],$in2[0],$out[2] + + xxpermdi $t2,$in2[3],$in2[2],0b00 + vmsumudm $out[3],$t1,$t2,$vzero + xxpermdi $t3,$in1[2],$in1[3],0b00 + xxpermdi $t4,$in2[1],$in2[0],0b00 + vmsumudm $out[3],$t3,$t4,$out[3] + + xxpermdi $t2,$in2[4],$in2[3],0b00 + vmsumudm $out[4],$t1,$t2,$vzero + xxpermdi $t4,$in2[2],$in2[1],0b00 + vmsumudm $out[4],$t3,$t4,$out[4] + vmsumudm $out[4],$in1[4],$in2[0],$out[4] + + xxpermdi $t2,$in2[5],$in2[4],0b00 + vmsumudm $out[5],$t1,$t2,$vzero + xxpermdi $t4,$in2[3],$in2[2],0b00 + vmsumudm $out[5],$t3,$t4,$out[5] + + xxpermdi $t2,$in2[6],$in2[5],0b00 + vmsumudm $out[6],$t1,$t2,$vzero + xxpermdi $t4,$in2[4],$in2[3],0b00 + vmsumudm $out[6],$t3,$t4,$out[6] + + xxpermdi $t2,$in2[7],$in2[6],0b00 + vmsumudm $out[7],$t1,$t2,$vzero + xxpermdi $t4,$in2[5],$in2[4],0b00 + vmsumudm $out[7],$t3,$t4,$out[7] + + xxpermdi $t2,$in2[8],$in2[7],0b00 + vmsumudm $out[8],$t1,$t2,$vzero + xxpermdi $t4,$in2[6],$in2[5],0b00 + vmsumudm $out[8],$t3,$t4,$out[8] + + xxpermdi $t1,$in1[4],$in1[5],0b00 + xxpermdi $t2,$in2[1],$in2[0],0b00 + vmsumudm $out[5],$t1,$t2,$out[5] + + xxpermdi $t2,$in2[2],$in2[1],0b00 + vmsumudm $out[6],$t1,$t2,$out[6] + vmsumudm $out[6],$in1[6],$in2[0],$out[6] + + xxpermdi $t2,$in2[3],$in2[2],0b00 + vmsumudm $out[7],$t1,$t2,$out[7] + xxpermdi $t3,$in1[6],$in1[7],0b00 + xxpermdi $t4,$in2[1],$in2[0],0b00 + vmsumudm $out[7],$t3,$t4,$out[7] + + xxpermdi $t2,$in2[4],$in2[3],0b00 + vmsumudm $out[8],$t1,$t2,$out[8] + xxpermdi $t4,$in2[2],$in2[1],0b00 + vmsumudm $out[8],$t3,$t4,$out[8] + vmsumudm $out[8],$in1[8],$in2[0],$out[8] + + li $zero,0 + li $one,1 + mtvsrdd $t1,$one,$zero +___ + + for (my $i = 0; $i <= 8; $i++) { + $code.=<<___; + vsld $in2[$i],$in2[$i],$t1 +___ + } + + $code.=<<___; + + vmsumudm $out[7],$in1[8],$in2[8],$out[7] + + xxpermdi $t2,$in2[8],$in2[7],0b00 + xxpermdi $t1,$in1[7],$in1[8],0b00 + vmsumudm $out[6],$t1,$t2,$out[6] + + xxpermdi $t1,$in1[6],$in1[7],0b00 + vmsumudm $out[5],$t1,$t2,$out[5] + vmsumudm $out[5],$in1[8],$in2[6],$out[5] + + xxpermdi $t1,$in1[5],$in1[6],0b00 + vmsumudm $out[4],$t1,$t2,$out[4] + xxpermdi $t4,$in2[6],$in2[5],0b00 + xxpermdi $t3,$in1[7],$in1[8],0b00 + vmsumudm $out[4],$t3,$t4,$out[4] + + xxpermdi $t1,$in1[4],$in1[5],0b00 + vmsumudm $out[3],$t1,$t2,$out[3] + xxpermdi $t3,$in1[6],$in1[7],0b00 + vmsumudm $out[3],$t3,$t4,$out[3] + vmsumudm $out[3],$in1[8],$in2[4],$out[3] + + xxpermdi $t1,$in1[3],$in1[4],0b00 + vmsumudm $out[2],$t1,$t2,$out[2] + xxpermdi $t3,$in1[5],$in1[6],0b00 + vmsumudm $out[2],$t3,$t4,$out[2] + + xxpermdi $t1,$in1[2],$in1[3],0b00 + vmsumudm $out[1],$t1,$t2,$out[1] + xxpermdi $t3,$in1[4],$in1[5],0b00 + vmsumudm $out[1],$t3,$t4,$out[1] + + xxpermdi $t1,$in1[1],$in1[2],0b00 + vmsumudm $out[0],$t1,$t2,$out[0] + xxpermdi $t3,$in1[3],$in1[4],0b00 + vmsumudm $out[0],$t3,$t4,$out[0] + + xxpermdi $t2,$in2[4],$in2[3],0b00 + xxpermdi $t1,$in1[7],$in1[8],0b00 + vmsumudm $out[2],$t1,$t2,$out[2] + + xxpermdi $t1,$in1[6],$in1[7],0b00 + vmsumudm $out[1],$t1,$t2,$out[1] + vmsumudm $out[1],$in1[8],$in2[2],$out[1] + + xxpermdi $t1,$in1[5],$in1[6],0b00 + vmsumudm $out[0],$t1,$t2,$out[0] + xxpermdi $t4,$in2[2],$in2[1],0b00 + xxpermdi $t3,$in1[7],$in1[8],0b00 + vmsumudm $out[0],$t3,$t4,$out[0] + +___ + + store_vrs($outp, \@out); + + pop_vrs(52, 63); + + endproc("p521_felem_mul"); + } + + { + # + # p51_felem_square + # + + my ($inp) = ("r4"); + my @in = map("v$_",(45..53)); + my @inx2 = map("v$_",(35..43)); + + startproc("p521_felem_square"); + + push_vrs(52, 63); + + $code.=<<___; + vspltisw $vzero,0 + +___ + + load_vrs($inp, \@in); + + $code.=<<___; + li $zero,0 + li $one,1 + mtvsrdd $t1,$one,$zero +___ + + for (my $i = 0; $i <= 8; $i++) { + $code.=<<___; + vsld $inx2[$i],$in[$i],$t1 +___ + } + + $code.=<<___; + vmsumudm $out[0],$in[0],$in[0],$vzero + + vmsumudm $out[1],$in[0],$inx2[1],$vzero + + xxpermdi $t1,$in[0],$in[1],0b00 + xxpermdi $t2,$inx2[2],$in[1],0b00 + vmsumudm $out[2],$t1,$t2,$vzero + + xxpermdi $t2,$inx2[3],$inx2[2],0b00 + vmsumudm $out[3],$t1,$t2,$vzero + + xxpermdi $t2,$inx2[4],$inx2[3],0b00 + vmsumudm $out[4],$t1,$t2,$vzero + vmsumudm $out[4],$in[2],$in[2],$out[4] + + xxpermdi $t2,$inx2[5],$inx2[4],0b00 + vmsumudm $out[5],$t1,$t2,$vzero + vmsumudm $out[5],$in[2],$inx2[3],$out[5] + + xxpermdi $t2,$inx2[6],$inx2[5],0b00 + vmsumudm $out[6],$t1,$t2,$vzero + xxpermdi $t3,$in[2],$in[3],0b00 + xxpermdi $t4,$inx2[4],$in[3],0b00 + vmsumudm $out[6],$t3,$t4,$out[6] + + xxpermdi $t2,$inx2[7],$inx2[6],0b00 + vmsumudm $out[7],$t1,$t2,$vzero + xxpermdi $t4,$inx2[5],$inx2[4],0b00 + vmsumudm $out[7],$t3,$t4,$out[7] + + xxpermdi $t2,$inx2[8],$inx2[7],0b00 + vmsumudm $out[8],$t1,$t2,$vzero + xxpermdi $t4,$inx2[6],$inx2[5],0b00 + vmsumudm $out[8],$t3,$t4,$out[8] + vmsumudm $out[8],$in[4],$in[4],$out[8] + + vmsumudm $out[1],$in[5],$inx2[5],$out[1] + + vmsumudm $out[3],$in[6],$inx2[6],$out[3] + + vmsumudm $out[5],$in[7],$inx2[7],$out[5] + + vmsumudm $out[7],$in[8],$inx2[8],$out[7] + + mtvsrdd $t1,$one,$zero +___ + + for (my $i = 5; $i <= 8; $i++) { + $code.=<<___; + vsld $inx2[$i],$inx2[$i],$t1 +___ + } + + $code.=<<___; + + vmsumudm $out[6],$in[7],$inx2[8],$out[6] + + vmsumudm $out[5],$in[6],$inx2[8],$out[5] + + xxpermdi $t2,$inx2[8],$inx2[7],0b00 + xxpermdi $t1,$in[5],$in[6],0b00 + vmsumudm $out[4],$t1,$t2,$out[4] + + xxpermdi $t1,$in[4],$in[5],0b00 + vmsumudm $out[3],$t1,$t2,$out[3] + + xxpermdi $t1,$in[3],$in[4],0b00 + vmsumudm $out[2],$t1,$t2,$out[2] + vmsumudm $out[2],$in[5],$inx2[6],$out[2] + + xxpermdi $t1,$in[2],$in[3],0b00 + vmsumudm $out[1],$t1,$t2,$out[1] + vmsumudm $out[1],$in[4],$inx2[6],$out[1] + + xxpermdi $t1,$in[1],$in[2],0b00 + vmsumudm $out[0],$t1,$t2,$out[0] + xxpermdi $t2,$inx2[6],$inx2[5],0b00 + xxpermdi $t1,$in[3],$in[4],0b00 + vmsumudm $out[0],$t1,$t2,$out[0] + +___ + + store_vrs($outp, \@out); + + pop_vrs(52, 63); + + endproc("p521_felem_square"); + } +} + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/ec/asm/ecp_nistz256-armv4.pl b/crypto/openssl/crypto/ec/asm/ecp_nistz256-armv4.pl index fa833ce6aaf3..0adad26cb11f 100755 --- a/crypto/openssl/crypto/ec/asm/ecp_nistz256-armv4.pl +++ b/crypto/openssl/crypto/ec/asm/ecp_nistz256-armv4.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -33,9 +33,10 @@ # on benchmark. Lower coefficients are for ECDSA sign, server-side # operation. Keep in mind that +200% means 3x improvement. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -43,15 +44,15 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $code.=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) .syntax unified .thumb @@ -80,6 +81,7 @@ close TABLE; die "insane number of elements" if ($#arr != 64*16*37-1); $code.=<<___; +.rodata .globl ecp_nistz256_precomputed .type ecp_nistz256_precomputed,%object .align 12 @@ -104,6 +106,8 @@ for(1..37) { } $code.=<<___; .size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed + +.text .align 5 .LRR: @ 2^512 mod P precomputed for NIST P256 polynomial .long 0x00000003, 0x00000000, 0xffffffff, 0xfffffffb diff --git a/crypto/openssl/crypto/ec/asm/ecp_nistz256-armv8.pl b/crypto/openssl/crypto/ec/asm/ecp_nistz256-armv8.pl index e93e18f29f19..81ee3947d7e4 100755 --- a/crypto/openssl/crypto/ec/asm/ecp_nistz256-armv8.pl +++ b/crypto/openssl/crypto/ec/asm/ecp_nistz256-armv8.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -31,15 +31,18 @@ # on benchmark. Lower coefficients are for ECDSA sign, server-side # operation. Keep in mind that +400% means 5x improvement. -$flavour = shift; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; { @@ -1479,7 +1482,7 @@ $code.=<<___; //////////////////////////////////////////////////////////////////////// // void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], -// int rep); +// uint64_t rep); .globl ecp_nistz256_ord_sqr_mont .type ecp_nistz256_ord_sqr_mont,%function .align 4 @@ -1645,7 +1648,7 @@ ecp_nistz256_scatter_w5: ldp x4,x5,[$inp] // X ldp x6,x7,[$inp,#16] - str w4,[$out,#64*0-4] + stur w4,[$out,#64*0-4] lsr x4,x4,#32 str w5,[$out,#64*1-4] lsr x5,x5,#32 @@ -1661,7 +1664,7 @@ ecp_nistz256_scatter_w5: ldp x4,x5,[$inp,#32] // Y ldp x6,x7,[$inp,#48] - str w4,[$out,#64*0-4] + stur w4,[$out,#64*0-4] lsr x4,x4,#32 str w5,[$out,#64*1-4] lsr x5,x5,#32 @@ -1677,7 +1680,7 @@ ecp_nistz256_scatter_w5: ldp x4,x5,[$inp,#64] // Z ldp x6,x7,[$inp,#80] - str w4,[$out,#64*0-4] + stur w4,[$out,#64*0-4] lsr x4,x4,#32 str w5,[$out,#64*1-4] lsr x5,x5,#32 diff --git a/crypto/openssl/crypto/ec/asm/ecp_nistz256-ppc64.pl b/crypto/openssl/crypto/ec/asm/ecp_nistz256-ppc64.pl index 2bf54e2aa544..7f600cece9d7 100755 --- a/crypto/openssl/crypto/ec/asm/ecp_nistz256-ppc64.pl +++ b/crypto/openssl/crypto/ec/asm/ecp_nistz256-ppc64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -25,15 +25,18 @@ # POWER7 +260-530% # POWER8 +220-340% -$flavour = shift; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my $sp="r1"; @@ -1919,7 +1922,7 @@ $code.=<<___; ################################################################################ # void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], -# int rep); +# uint64_t rep); .globl ecp_nistz256_ord_sqr_mont .align 5 ecp_nistz256_ord_sqr_mont: diff --git a/crypto/openssl/crypto/ec/asm/ecp_nistz256-sparcv9.pl b/crypto/openssl/crypto/ec/asm/ecp_nistz256-sparcv9.pl index 042e122718b7..986e002cc94d 100755 --- a/crypto/openssl/crypto/ec/asm/ecp_nistz256-sparcv9.pl +++ b/crypto/openssl/crypto/ec/asm/ecp_nistz256-sparcv9.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -31,11 +31,13 @@ # on benchmark. Lower coefficients are for ECDSA sign, server-side # operation. Keep in mind that +200% means 3x improvement. -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #define LOCALS (STACK_BIAS+STACK_FRAME) #ifdef __arch64__ diff --git a/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86.pl b/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86.pl index e926d69b020b..e78f0cd7266d 100755 --- a/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86.pl +++ b/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -42,8 +42,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl b/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl index b50ee70191b2..430b14c86d8d 100755 --- a/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl +++ b/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl @@ -3,7 +3,7 @@ # Copyright (c) 2014, Intel Corporation. All Rights Reserved. # Copyright (c) 2015 CloudFlare, Inc. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -40,9 +40,10 @@ # higher - for ECDSA sign, relatively fastest server-side operation. # Keep in mind that +100% means 2x improvement. -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -51,7 +52,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` @@ -826,7 +828,7 @@ $code.=<<___; # void ecp_nistz256_ord_sqr_mont( # uint64_t res[4], # uint64_t a[4], -# int rep); +# uint64_t rep); .globl ecp_nistz256_ord_sqr_mont .type ecp_nistz256_ord_sqr_mont,\@function,3 diff --git a/crypto/openssl/crypto/ec/asm/x25519-ppc64.pl b/crypto/openssl/crypto/ec/asm/x25519-ppc64.pl index f4b523bf8a08..c1d9650c6bfa 100755 --- a/crypto/openssl/crypto/ec/asm/x25519-ppc64.pl +++ b/crypto/openssl/crypto/ec/asm/x25519-ppc64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -27,15 +27,18 @@ # this module delivers more than 2x improvement, and when it does, # from 12% to 30% improvement was measured... -$flavour = shift; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my $sp = "r1"; diff --git a/crypto/openssl/crypto/ec/asm/x25519-x86_64.pl b/crypto/openssl/crypto/ec/asm/x25519-x86_64.pl index 62599dacaccd..d2285269a308 100755 --- a/crypto/openssl/crypto/ec/asm/x25519-x86_64.pl +++ b/crypto/openssl/crypto/ec/asm/x25519-x86_64.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -61,9 +61,10 @@ # C implementation, so that comparison is always against # 2^51 radix; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -72,7 +73,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` diff --git a/crypto/openssl/crypto/ec/build.info b/crypto/openssl/crypto/ec/build.info index a1e673e347d0..a511e887a9ba 100644 --- a/crypto/openssl/crypto/ec/build.info +++ b/crypto/openssl/crypto/ec/build.info @@ -1,42 +1,105 @@ -LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \ - ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c \ - ec2_smpl.c ec_ameth.c ec_pmeth.c eck_prn.c \ - ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \ - ecp_oct.c ec2_oct.c ec_oct.c ec_kmeth.c ecdh_ossl.c ecdh_kdf.c \ - ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c ecx_meth.c \ - curve448/arch_32/f_impl.c curve448/f_generic.c curve448/scalar.c \ +$ECASM= +IF[{- !$disabled{asm} -}] + $ECASM_x86=ecp_nistz256.c ecp_nistz256-x86.S + $ECDEF_x86=ECP_NISTZ256_ASM + + $ECASM_x86_64=ecp_nistz256.c ecp_nistz256-x86_64.s x25519-x86_64.s + $ECDEF_x86_64=ECP_NISTZ256_ASM X25519_ASM + + $ECASM_ia64= + + $ECASM_sparcv9=ecp_nistz256.c ecp_nistz256-sparcv9.S + $ECDEF_sparcv9=ECP_NISTZ256_ASM + + $ECASM_sparcv8= + + $ECASM_alpha= + + $ECASM_mips32= + $ECASM_mips64= + + $ECASM_s390x=ecp_s390x_nistp.c ecx_s390x.c + $ECDEF_s390x=S390X_EC_ASM + + $ECASM_armv4=ecp_nistz256.c ecp_nistz256-armv4.S + $ECDEF_armv4=ECP_NISTZ256_ASM + $ECASM_aarch64=ecp_nistz256.c ecp_nistz256-armv8.S + $ECDEF_aarch64=ECP_NISTZ256_ASM + + $ECASM_parisc11= + $ECASM_parisc20_64= + + $ECASM_ppc32= + $ECASM_ppc64=ecp_nistz256.c ecp_ppc.c ecp_nistz256-ppc64.s x25519-ppc64.s + $ECDEF_ppc64=ECP_NISTZ256_ASM X25519_ASM + IF[{- !$disabled{'ec_nistp_64_gcc_128'} -}] + $ECASM_ppc64=$ECASM_ppc64 ecp_nistp521-ppc64.s + $ECDEF_ppc64=$ECDEF_ppc64 ECP_NISTP521_ASM + INCLUDE[ecp_nistp521.o]=.. + ENDIF + + $ECASM_c64xplus= + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$ECASM_{- $target{asm_arch} -}] + $ECASM=$ECASM_{- $target{asm_arch} -} + $ECDEF=$ECDEF_{- $target{asm_arch} -} + ENDIF +ENDIF + +$COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \ + ec_curve.c ec_check.c ec_key.c ec_kmeth.c ecx_key.c ec_asn1.c \ + ec2_smpl.c \ + ecp_oct.c ec2_oct.c ec_oct.c ecdh_ossl.c \ + ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c \ + curve448/f_generic.c curve448/scalar.c \ curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \ - {- $target{ec_asm_src} -} + $ECASM ec_backend.c ecx_backend.c ecdh_kdf.c curve448/arch_64/f_impl64.c \ + curve448/arch_32/f_impl32.c + +IF[{- !$disabled{'ec_nistp_64_gcc_128'} -}] + $COMMON=$COMMON ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c +ENDIF + +SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c \ + ec_err.c eck_prn.c \ + ec_deprecated.c ec_print.c +SOURCE[../../providers/libfips.a]=$COMMON -GENERATE[ecp_nistz256-x86.s]=asm/ecp_nistz256-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) +# Implementations are now spread across several libraries, so the defines +# need to be applied to all affected libraries and modules. +DEFINE[../../libcrypto]=$ECDEF +DEFINE[../../providers/libfips.a]=$ECDEF +DEFINE[../../providers/libdefault.a]=$ECDEF +# We only need to include the ECDEF stuff in the legacy provider when +# it's a separate module and it's dynamically linked with libcrypto. +# Otherwise, it already gets everything that the static libcrypto.a +# has, and doesn't need it added again. +IF[{- !$disabled{module} && !$disabled{shared} -}] + DEFINE[../providers/liblegacy.a]=$ECDEF +ENDIF -GENERATE[ecp_nistz256-x86_64.s]=asm/ecp_nistz256-x86_64.pl $(PERLASM_SCHEME) +GENERATE[ecp_nistz256-x86.S]=asm/ecp_nistz256-x86.pl -GENERATE[ecp_nistz256-avx2.s]=asm/ecp_nistz256-avx2.pl $(PERLASM_SCHEME) +GENERATE[ecp_nistz256-x86_64.s]=asm/ecp_nistz256-x86_64.pl -GENERATE[ecp_nistz256-sparcv9.S]=asm/ecp_nistz256-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[ecp_nistz256-avx2.s]=asm/ecp_nistz256-avx2.pl + +GENERATE[ecp_nistz256-sparcv9.S]=asm/ecp_nistz256-sparcv9.pl INCLUDE[ecp_nistz256-sparcv9.o]=.. -GENERATE[ecp_nistz256-armv4.S]=asm/ecp_nistz256-armv4.pl $(PERLASM_SCHEME) +INCLUDE[ecp_s390x_nistp.o]=.. +INCLUDE[ecx_s390x.o]=.. +INCLUDE[ecx_meth.o]=.. + +GENERATE[ecp_nistz256-armv4.S]=asm/ecp_nistz256-armv4.pl INCLUDE[ecp_nistz256-armv4.o]=.. -GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl $(PERLASM_SCHEME) +GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl INCLUDE[ecp_nistz256-armv8.o]=.. -GENERATE[ecp_nistz256-ppc64.s]=asm/ecp_nistz256-ppc64.pl $(PERLASM_SCHEME) - -GENERATE[x25519-x86_64.s]=asm/x25519-x86_64.pl $(PERLASM_SCHEME) -GENERATE[x25519-ppc64.s]=asm/x25519-ppc64.pl $(PERLASM_SCHEME) - -BEGINRAW[Makefile] -{- $builddir -}/ecp_nistz256-%.S: {- $sourcedir -}/asm/ecp_nistz256-%.pl - CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ -ENDRAW[Makefile] - -INCLUDE[curve448/arch_32/f_impl.o]=curve448/arch_32 curve448 -INCLUDE[curve448/f_generic.o]=curve448/arch_32 curve448 -INCLUDE[curve448/scalar.o]=curve448/arch_32 curve448 -INCLUDE[curve448/curve448_tables.o]=curve448/arch_32 curve448 -INCLUDE[curve448/eddsa.o]=curve448/arch_32 curve448 -INCLUDE[curve448/curve448.o]=curve448/arch_32 curve448 +GENERATE[ecp_nistz256-ppc64.s]=asm/ecp_nistz256-ppc64.pl + +GENERATE[ecp_nistp521-ppc64.s]=asm/ecp_nistp521-ppc64.pl + +GENERATE[x25519-x86_64.s]=asm/x25519-x86_64.pl +GENERATE[x25519-ppc64.s]=asm/x25519-ppc64.pl diff --git a/crypto/openssl/crypto/ec/curve25519.c b/crypto/openssl/crypto/ec/curve25519.c index 952da0e65385..50a8e6b169d2 100644 --- a/crypto/openssl/crypto/ec/curve25519.c +++ b/crypto/openssl/crypto/ec/curve25519.c @@ -1,16 +1,26 @@ /* - * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include +#include "crypto/ecx.h" #include "ec_local.h" +#include #include +#include "internal/numbers.h" + #if defined(X25519_ASM) && (defined(__x86_64) || defined(__x86_64__) || \ defined(_M_AMD64) || defined(_M_X64)) @@ -252,7 +262,7 @@ static void x25519_scalar_mulx(uint8_t out[32], const uint8_t scalar[32], #endif #if defined(X25519_ASM) \ - || ( (defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16) \ + || ( defined(INT128_MAX) \ && !defined(__sparc__) \ && (!defined(__SIZEOF_LONG__) || (__SIZEOF_LONG__ == 8)) \ && !(defined(__ANDROID__) && !defined(__clang__)) ) @@ -385,7 +395,7 @@ void x25519_fe51_mul121666(fe51 h, fe51 f); # define fe51_mul121666 x25519_fe51_mul121666 # else -typedef __uint128_t u128; +typedef uint128_t u128; static void fe51_mul(fe51 h, const fe51 f, const fe51 g) { @@ -5429,57 +5439,75 @@ static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, s[31] = (uint8_t) (s11 >> 17); } -int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, - const uint8_t public_key[32], const uint8_t private_key[32]) +int +ossl_ed25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, + const uint8_t public_key[32], const uint8_t private_key[32], + OSSL_LIB_CTX *libctx, const char *propq) { uint8_t az[SHA512_DIGEST_LENGTH]; uint8_t nonce[SHA512_DIGEST_LENGTH]; ge_p3 R; uint8_t hram[SHA512_DIGEST_LENGTH]; - SHA512_CTX hash_ctx; + EVP_MD *sha512 = EVP_MD_fetch(libctx, SN_sha512, propq); + EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new(); + unsigned int sz; + int res = 0; - SHA512_Init(&hash_ctx); - SHA512_Update(&hash_ctx, private_key, 32); - SHA512_Final(az, &hash_ctx); + if (sha512 == NULL || hash_ctx == NULL) + goto err; + + if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL) + || !EVP_DigestUpdate(hash_ctx, private_key, 32) + || !EVP_DigestFinal_ex(hash_ctx, az, &sz)) + goto err; az[0] &= 248; az[31] &= 63; az[31] |= 64; - SHA512_Init(&hash_ctx); - SHA512_Update(&hash_ctx, az + 32, 32); - SHA512_Update(&hash_ctx, message, message_len); - SHA512_Final(nonce, &hash_ctx); + if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL) + || !EVP_DigestUpdate(hash_ctx, az + 32, 32) + || !EVP_DigestUpdate(hash_ctx, message, message_len) + || !EVP_DigestFinal_ex(hash_ctx, nonce, &sz)) + goto err; x25519_sc_reduce(nonce); ge_scalarmult_base(&R, nonce); ge_p3_tobytes(out_sig, &R); - SHA512_Init(&hash_ctx); - SHA512_Update(&hash_ctx, out_sig, 32); - SHA512_Update(&hash_ctx, public_key, 32); - SHA512_Update(&hash_ctx, message, message_len); - SHA512_Final(hram, &hash_ctx); + if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL) + || !EVP_DigestUpdate(hash_ctx, out_sig, 32) + || !EVP_DigestUpdate(hash_ctx, public_key, 32) + || !EVP_DigestUpdate(hash_ctx, message, message_len) + || !EVP_DigestFinal_ex(hash_ctx, hram, &sz)) + goto err; x25519_sc_reduce(hram); sc_muladd(out_sig + 32, hram, az, nonce); - OPENSSL_cleanse(&hash_ctx, sizeof(hash_ctx)); + res = 1; +err: OPENSSL_cleanse(nonce, sizeof(nonce)); OPENSSL_cleanse(az, sizeof(az)); - - return 1; + EVP_MD_free(sha512); + EVP_MD_CTX_free(hash_ctx); + return res; } static const char allzeroes[15]; -int ED25519_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[64], const uint8_t public_key[32]) +int +ossl_ed25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[64], const uint8_t public_key[32], + OSSL_LIB_CTX *libctx, const char *propq) { int i; ge_p3 A; const uint8_t *r, *s; - SHA512_CTX hash_ctx; + EVP_MD *sha512; + EVP_MD_CTX *hash_ctx = NULL; + unsigned int sz; + int res = 0; ge_p2 R; uint8_t rcheck[32]; uint8_t h[SHA512_DIGEST_LENGTH]; @@ -5526,11 +5554,19 @@ int ED25519_verify(const uint8_t *message, size_t message_len, fe_neg(A.X, A.X); fe_neg(A.T, A.T); - SHA512_Init(&hash_ctx); - SHA512_Update(&hash_ctx, r, 32); - SHA512_Update(&hash_ctx, public_key, 32); - SHA512_Update(&hash_ctx, message, message_len); - SHA512_Final(h, &hash_ctx); + sha512 = EVP_MD_fetch(libctx, SN_sha512, propq); + if (sha512 == NULL) + return 0; + hash_ctx = EVP_MD_CTX_new(); + if (hash_ctx == NULL) + goto err; + + if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL) + || !EVP_DigestUpdate(hash_ctx, r, 32) + || !EVP_DigestUpdate(hash_ctx, public_key, 32) + || !EVP_DigestUpdate(hash_ctx, message, message_len) + || !EVP_DigestFinal_ex(hash_ctx, h, &sz)) + goto err; x25519_sc_reduce(h); @@ -5538,16 +5574,32 @@ int ED25519_verify(const uint8_t *message, size_t message_len, ge_tobytes(rcheck, &R); - return CRYPTO_memcmp(rcheck, r, sizeof(rcheck)) == 0; + res = CRYPTO_memcmp(rcheck, r, sizeof(rcheck)) == 0; +err: + EVP_MD_free(sha512); + EVP_MD_CTX_free(hash_ctx); + return res; } -void ED25519_public_from_private(uint8_t out_public_key[32], - const uint8_t private_key[32]) +int +ossl_ed25519_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[32], + const uint8_t private_key[32], + const char *propq) { uint8_t az[SHA512_DIGEST_LENGTH]; ge_p3 A; + int r; + EVP_MD *sha512 = NULL; - SHA512(private_key, 32, az); + sha512 = EVP_MD_fetch(ctx, SN_sha512, propq); + if (sha512 == NULL) + return 0; + r = EVP_Digest(private_key, 32, az, NULL, sha512, NULL); + EVP_MD_free(sha512); + if (!r) { + OPENSSL_cleanse(az, sizeof(az)); + return 0; + } az[0] &= 248; az[31] &= 63; @@ -5557,10 +5609,12 @@ void ED25519_public_from_private(uint8_t out_public_key[32], ge_p3_tobytes(out_public_key, &A); OPENSSL_cleanse(az, sizeof(az)); + return 1; } -int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32], - const uint8_t peer_public_value[32]) +int +ossl_x25519(uint8_t out_shared_key[32], const uint8_t private_key[32], + const uint8_t peer_public_value[32]) { static const uint8_t kZeros[32] = {0}; x25519_scalar_mult(out_shared_key, private_key, peer_public_value); @@ -5568,7 +5622,8 @@ int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32], return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0; } -void X25519_public_from_private(uint8_t out_public_value[32], +void +ossl_x25519_public_from_private(uint8_t out_public_value[32], const uint8_t private_key[32]) { uint8_t e[32]; diff --git a/crypto/openssl/crypto/ec/curve448/arch_32/arch_intrinsics.h b/crypto/openssl/crypto/ec/curve448/arch_32/arch_intrinsics.h index 5f6389863d15..7a54903ac95a 100644 --- a/crypto/openssl/crypto/ec/curve448/arch_32/arch_intrinsics.h +++ b/crypto/openssl/crypto/ec/curve448/arch_32/arch_intrinsics.h @@ -2,7 +2,7 @@ * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2016 Cryptography Research, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ec/curve448/arch_32/f_impl.h b/crypto/openssl/crypto/ec/curve448/arch_32/f_impl.h index e1ddddaee08d..5cd25c04e123 100644 --- a/crypto/openssl/crypto/ec/curve448/arch_32/f_impl.h +++ b/crypto/openssl/crypto/ec/curve448/arch_32/f_impl.h @@ -2,7 +2,7 @@ * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2014-2016 Cryptography Research, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ec/curve448/arch_32/f_impl.c b/crypto/openssl/crypto/ec/curve448/arch_32/f_impl32.c similarity index 87% rename from crypto/openssl/crypto/ec/curve448/arch_32/f_impl.c rename to crypto/openssl/crypto/ec/curve448/arch_32/f_impl32.c index 8a89d276edb6..8714a5142216 100644 --- a/crypto/openssl/crypto/ec/curve448/arch_32/f_impl.c +++ b/crypto/openssl/crypto/ec/curve448/arch_32/f_impl32.c @@ -1,8 +1,8 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2014 Cryptography Research, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,7 +10,16 @@ * Originally written by Mike Hamburg */ -#include "field.h" +#include "e_os.h" +#include +#include "internal/numbers.h" + +#ifdef UINT128_MAX +/* We have support for 128 bit ints, so do nothing here */ +NON_EMPTY_TRANSLATION_UNIT +#else + +# include "../field.h" void gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs) { @@ -93,3 +102,4 @@ void gf_sqr(gf_s * RESTRICT cs, const gf as) { gf_mul(cs, as, as); /* Performs better with a dedicated square */ } +#endif diff --git a/crypto/openssl/crypto/ec/curve448/arch_64/arch_intrinsics.h b/crypto/openssl/crypto/ec/curve448/arch_64/arch_intrinsics.h new file mode 100644 index 000000000000..e12b8cf22624 --- /dev/null +++ b/crypto/openssl/crypto/ec/curve448/arch_64/arch_intrinsics.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016 Cryptography Research, Inc. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Originally written by Mike Hamburg + */ + +#ifndef OSSL_CRYPTO_EC_CURVE448_ARCH_64_INTRINSICS_H +# define OSSL_CRYPTO_EC_CURVE448_ARCH_64_INTRINSICS_H + +# include "internal/constant_time.h" + +# define ARCH_WORD_BITS 64 + +# define word_is_zero(a) constant_time_is_zero_64(a) + +static ossl_inline uint128_t widemul(uint64_t a, uint64_t b) +{ + return ((uint128_t) a) * b; +} + +#endif /* OSSL_CRYPTO_EC_CURVE448_ARCH_64_INTRINSICS_H */ diff --git a/crypto/openssl/crypto/ec/curve448/arch_64/f_impl.h b/crypto/openssl/crypto/ec/curve448/arch_64/f_impl.h new file mode 100644 index 000000000000..faaeb8d9944b --- /dev/null +++ b/crypto/openssl/crypto/ec/curve448/arch_64/f_impl.h @@ -0,0 +1,58 @@ +/* + * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2016 Cryptography Research, Inc. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Originally written by Mike Hamburg + */ + +#ifndef OSSL_CRYPTO_EC_CURVE448_ARCH_64_F_IMPL_H +# define OSSL_CRYPTO_EC_CURVE448_ARCH_64_F_IMPL_H + +# define GF_HEADROOM 9999 /* Everything is reduced anyway */ +# define FIELD_LITERAL(a,b,c,d,e,f,g,h) {{a,b,c,d,e,f,g,h}} + +# define LIMB_PLACE_VALUE(i) 56 + +void gf_add_RAW(gf out, const gf a, const gf b) +{ + unsigned int i; + + for (i = 0; i < NLIMBS; i++) + out->limb[i] = a->limb[i] + b->limb[i]; + + gf_weak_reduce(out); +} + +void gf_sub_RAW(gf out, const gf a, const gf b) +{ + uint64_t co1 = ((1ULL << 56) - 1) * 2, co2 = co1 - 2; + unsigned int i; + + for (i = 0; i < NLIMBS; i++) + out->limb[i] = a->limb[i] - b->limb[i] + ((i == NLIMBS / 2) ? co2 : co1); + + gf_weak_reduce(out); +} + +void gf_bias(gf a, int amt) +{ +} + +void gf_weak_reduce(gf a) +{ + uint64_t mask = (1ULL << 56) - 1; + uint64_t tmp = a->limb[NLIMBS - 1] >> 56; + unsigned int i; + + a->limb[NLIMBS / 2] += tmp; + for (i = NLIMBS - 1; i > 0; i--) + a->limb[i] = (a->limb[i] & mask) + (a->limb[i - 1] >> 56); + a->limb[0] = (a->limb[0] & mask) + tmp; +} + +#endif /* OSSL_CRYPTO_EC_CURVE448_ARCH_64_F_IMPL_H */ diff --git a/crypto/openssl/crypto/ec/curve448/arch_64/f_impl64.c b/crypto/openssl/crypto/ec/curve448/arch_64/f_impl64.c new file mode 100644 index 000000000000..8f7a7dd391bd --- /dev/null +++ b/crypto/openssl/crypto/ec/curve448/arch_64/f_impl64.c @@ -0,0 +1,210 @@ +/* + * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014 Cryptography Research, Inc. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Originally written by Mike Hamburg + */ + +#include "e_os.h" +#include +#include "internal/numbers.h" + +#ifndef UINT128_MAX +/* No support for 128 bit ints, so do nothing here */ +NON_EMPTY_TRANSLATION_UNIT +#else + +# include "../field.h" + +void gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs) +{ + const uint64_t *a = as->limb, *b = bs->limb; + uint64_t *c = cs->limb; + uint128_t accum0 = 0, accum1 = 0, accum2; + uint64_t mask = (1ULL << 56) - 1; + uint64_t aa[4], bb[4], bbb[4]; + unsigned int i, j; + + for (i = 0; i < 4; i++) { + aa[i] = a[i] + a[i + 4]; + bb[i] = b[i] + b[i + 4]; + bbb[i] = bb[i] + b[i + 4]; + } + + for (i = 0; i < 4; i++) { + accum2 = 0; + + for (j = 0; j <= i; j++) { + accum2 += widemul(a[j], b[i - j]); + accum1 += widemul(aa[j], bb[i - j]); + accum0 += widemul(a[j + 4], b[i - j + 4]); + } + for (; j < 4; j++) { + accum2 += widemul(a[j], b[i - j + 8]); + accum1 += widemul(aa[j], bbb[i - j + 4]); + accum0 += widemul(a[j + 4], bb[i - j + 4]); + } + + accum1 -= accum2; + accum0 += accum2; + + c[i] = ((uint64_t)(accum0)) & mask; + c[i + 4] = ((uint64_t)(accum1)) & mask; + + accum0 >>= 56; + accum1 >>= 56; + } + + accum0 += accum1; + accum0 += c[4]; + accum1 += c[0]; + c[4] = ((uint64_t)(accum0)) & mask; + c[0] = ((uint64_t)(accum1)) & mask; + + accum0 >>= 56; + accum1 >>= 56; + + c[5] += ((uint64_t)(accum0)); + c[1] += ((uint64_t)(accum1)); +} + +void gf_mulw_unsigned(gf_s * RESTRICT cs, const gf as, uint32_t b) +{ + const uint64_t *a = as->limb; + uint64_t *c = cs->limb; + uint128_t accum0 = 0, accum4 = 0; + uint64_t mask = (1ULL << 56) - 1; + int i; + + for (i = 0; i < 4; i++) { + accum0 += widemul(b, a[i]); + accum4 += widemul(b, a[i + 4]); + c[i] = accum0 & mask; + accum0 >>= 56; + c[i + 4] = accum4 & mask; + accum4 >>= 56; + } + + accum0 += accum4 + c[4]; + c[4] = accum0 & mask; + c[5] += accum0 >> 56; + + accum4 += c[0]; + c[0] = accum4 & mask; + c[1] += accum4 >> 56; +} + +void gf_sqr(gf_s * RESTRICT cs, const gf as) +{ + const uint64_t *a = as->limb; + uint64_t *c = cs->limb; + uint128_t accum0 = 0, accum1 = 0, accum2; + uint64_t mask = (1ULL << 56) - 1; + uint64_t aa[4]; + unsigned int i; + + /* For some reason clang doesn't vectorize this without prompting? */ + for (i = 0; i < 4; i++) + aa[i] = a[i] + a[i + 4]; + + accum2 = widemul(a[0], a[3]); + accum0 = widemul(aa[0], aa[3]); + accum1 = widemul(a[4], a[7]); + + accum2 += widemul(a[1], a[2]); + accum0 += widemul(aa[1], aa[2]); + accum1 += widemul(a[5], a[6]); + + accum0 -= accum2; + accum1 += accum2; + + c[3] = ((uint64_t)(accum1)) << 1 & mask; + c[7] = ((uint64_t)(accum0)) << 1 & mask; + + accum0 >>= 55; + accum1 >>= 55; + + accum0 += widemul(2 * aa[1], aa[3]); + accum1 += widemul(2 * a[5], a[7]); + accum0 += widemul(aa[2], aa[2]); + accum1 += accum0; + + accum0 -= widemul(2 * a[1], a[3]); + accum1 += widemul(a[6], a[6]); + + accum2 = widemul(a[0], a[0]); + accum1 -= accum2; + accum0 += accum2; + + accum0 -= widemul(a[2], a[2]); + accum1 += widemul(aa[0], aa[0]); + accum0 += widemul(a[4], a[4]); + + c[0] = ((uint64_t)(accum0)) & mask; + c[4] = ((uint64_t)(accum1)) & mask; + + accum0 >>= 56; + accum1 >>= 56; + + accum2 = widemul(2 * aa[2], aa[3]); + accum0 -= widemul(2 * a[2], a[3]); + accum1 += widemul(2 * a[6], a[7]); + + accum1 += accum2; + accum0 += accum2; + + accum2 = widemul(2 * a[0], a[1]); + accum1 += widemul(2 * aa[0], aa[1]); + accum0 += widemul(2 * a[4], a[5]); + + accum1 -= accum2; + accum0 += accum2; + + c[1] = ((uint64_t)(accum0)) & mask; + c[5] = ((uint64_t)(accum1)) & mask; + + accum0 >>= 56; + accum1 >>= 56; + + accum2 = widemul(aa[3], aa[3]); + accum0 -= widemul(a[3], a[3]); + accum1 += widemul(a[7], a[7]); + + accum1 += accum2; + accum0 += accum2; + + accum2 = widemul(2 * a[0], a[2]); + accum1 += widemul(2 * aa[0], aa[2]); + accum0 += widemul(2 * a[4], a[6]); + + accum2 += widemul(a[1], a[1]); + accum1 += widemul(aa[1], aa[1]); + accum0 += widemul(a[5], a[5]); + + accum1 -= accum2; + accum0 += accum2; + + c[2] = ((uint64_t)(accum0)) & mask; + c[6] = ((uint64_t)(accum1)) & mask; + + accum0 >>= 56; + accum1 >>= 56; + + accum0 += c[3]; + accum1 += c[7]; + c[3] = ((uint64_t)(accum0)) & mask; + c[7] = ((uint64_t)(accum1)) & mask; + + /* we could almost stop here, but it wouldn't be stable, so... */ + + accum0 >>= 56; + accum1 >>= 56; + c[4] += ((uint64_t)(accum0)) + ((uint64_t)(accum1)); + c[0] += ((uint64_t)(accum1)); +} +#endif diff --git a/crypto/openssl/crypto/ec/curve448/curve448.c b/crypto/openssl/crypto/ec/curve448/curve448.c index 3d4db44564e9..6928d9693ca5 100644 --- a/crypto/openssl/crypto/ec/curve448/curve448.c +++ b/crypto/openssl/crypto/ec/curve448/curve448.c @@ -2,7 +2,7 @@ * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,6 +15,7 @@ #include "point_448.h" #include "ed448.h" +#include "crypto/ecx.h" #include "curve448_local.h" #define COFACTOR 4 @@ -54,7 +55,7 @@ static void gf_invert(gf y, const gf x, int assert_nonzero) } /** identity = (0,1) */ -const curve448_point_t curve448_point_identity = +const curve448_point_t ossl_curve448_point_identity = { {{{{0}}}, {{{1}}}, {{{1}}}, {{{0}}}} }; static void point_double_internal(curve448_point_t p, const curve448_point_t q, @@ -81,7 +82,7 @@ static void point_double_internal(curve448_point_t p, const curve448_point_t q, gf_mul(p->t, b, d); } -void curve448_point_double(curve448_point_t p, const curve448_point_t q) +void ossl_curve448_point_double(curve448_point_t p, const curve448_point_t q) { point_double_internal(p, q, 0); } @@ -183,8 +184,9 @@ static void sub_pniels_from_pt(curve448_point_t p, const pniels_t pn, sub_niels_from_pt(p, pn->n, before_double); } -c448_bool_t curve448_point_eq(const curve448_point_t p, - const curve448_point_t q) +c448_bool_t +ossl_curve448_point_eq(const curve448_point_t p, + const curve448_point_t q) { mask_t succ; gf a, b; @@ -197,7 +199,8 @@ c448_bool_t curve448_point_eq(const curve448_point_t p, return mask_to_bool(succ); } -c448_bool_t curve448_point_valid(const curve448_point_t p) +c448_bool_t +ossl_curve448_point_valid(const curve448_point_t p) { mask_t out; gf a, b, c; @@ -224,7 +227,8 @@ static ossl_inline void constant_time_lookup_niels(niels_s * RESTRICT ni, constant_time_lookup(ni, table, sizeof(niels_s), nelts, idx); } -void curve448_precomputed_scalarmul(curve448_point_t out, +void +ossl_curve448_precomputed_scalarmul(curve448_point_t out, const curve448_precomputed_s * table, const curve448_scalar_t scalar) { @@ -233,8 +237,8 @@ void curve448_precomputed_scalarmul(curve448_point_t out, niels_t ni; curve448_scalar_t scalar1x; - curve448_scalar_add(scalar1x, scalar, precomputed_scalarmul_adjustment); - curve448_scalar_halve(scalar1x, scalar1x); + ossl_curve448_scalar_add(scalar1x, scalar, precomputed_scalarmul_adjustment); + ossl_curve448_scalar_halve(scalar1x, scalar1x); for (i = s; i > 0; i--) { if (i != s) @@ -271,7 +275,8 @@ void curve448_precomputed_scalarmul(curve448_point_t out, OPENSSL_cleanse(scalar1x, sizeof(scalar1x)); } -void curve448_point_mul_by_ratio_and_encode_like_eddsa( +void +ossl_curve448_point_mul_by_ratio_and_encode_like_eddsa( uint8_t enc[EDDSA_448_PUBLIC_BYTES], const curve448_point_t p) { @@ -315,10 +320,11 @@ void curve448_point_mul_by_ratio_and_encode_like_eddsa( OPENSSL_cleanse(y, sizeof(y)); OPENSSL_cleanse(z, sizeof(z)); OPENSSL_cleanse(t, sizeof(t)); - curve448_point_destroy(q); + ossl_curve448_point_destroy(q); } -c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio( +c448_error_t +ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio( curve448_point_t p, const uint8_t enc[EDDSA_448_PUBLIC_BYTES]) { @@ -371,14 +377,15 @@ c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio( } OPENSSL_cleanse(enc2, sizeof(enc2)); - assert(curve448_point_valid(p) || ~succ); + assert(ossl_curve448_point_valid(p) || ~succ); return c448_succeed_if(mask_to_bool(succ)); } -c448_error_t x448_int(uint8_t out[X_PUBLIC_BYTES], - const uint8_t base[X_PUBLIC_BYTES], - const uint8_t scalar[X_PRIVATE_BYTES]) +c448_error_t +ossl_x448_int(uint8_t out[X_PUBLIC_BYTES], + const uint8_t base[X_PUBLIC_BYTES], + const uint8_t scalar[X_PRIVATE_BYTES]) { gf x1, x2, z2, x3, z3, t1, t2; int t; @@ -455,7 +462,8 @@ c448_error_t x448_int(uint8_t out[X_PUBLIC_BYTES], return c448_succeed_if(mask_to_bool(nz)); } -void curve448_point_mul_by_ratio_and_encode_like_x448(uint8_t +void +ossl_curve448_point_mul_by_ratio_and_encode_like_x448(uint8_t out[X_PUBLIC_BYTES], const curve448_point_t p) { @@ -466,11 +474,11 @@ void curve448_point_mul_by_ratio_and_encode_like_x448(uint8_t gf_mul(q->z, q->t, q->y); /* y/x */ gf_sqr(q->y, q->z); /* (y/x)^2 */ gf_serialize(out, q->y, 1); - curve448_point_destroy(q); + ossl_curve448_point_destroy(q); } -void x448_derive_public_key(uint8_t out[X_PUBLIC_BYTES], - const uint8_t scalar[X_PRIVATE_BYTES]) +void ossl_x448_derive_public_key(uint8_t out[X_PUBLIC_BYTES], + const uint8_t scalar[X_PRIVATE_BYTES]) { /* Scalar conditioning */ uint8_t scalar2[X_PRIVATE_BYTES]; @@ -484,15 +492,16 @@ void x448_derive_public_key(uint8_t out[X_PUBLIC_BYTES], scalar2[X_PRIVATE_BYTES - 1] &= ~((0u - 1u) << ((X_PRIVATE_BITS + 7) % 8)); scalar2[X_PRIVATE_BYTES - 1] |= 1 << ((X_PRIVATE_BITS + 7) % 8); - curve448_scalar_decode_long(the_scalar, scalar2, sizeof(scalar2)); + ossl_curve448_scalar_decode_long(the_scalar, scalar2, sizeof(scalar2)); /* Compensate for the encoding ratio */ for (i = 1; i < X448_ENCODE_RATIO; i <<= 1) - curve448_scalar_halve(the_scalar, the_scalar); + ossl_curve448_scalar_halve(the_scalar, the_scalar); - curve448_precomputed_scalarmul(p, curve448_precomputed_base, the_scalar); - curve448_point_mul_by_ratio_and_encode_like_x448(out, p); - curve448_point_destroy(p); + ossl_curve448_precomputed_scalarmul(p, ossl_curve448_precomputed_base, + the_scalar); + ossl_curve448_point_mul_by_ratio_and_encode_like_x448(out, p); + ossl_curve448_point_destroy(p); } /* Control for variable-time scalar multiply algorithms. */ @@ -501,9 +510,9 @@ struct smvt_control { }; #if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) -# define NUMTRAILINGZEROS __builtin_ctz +# define NUMTRAILINGZEROS __builtin_ctz #else -# define NUMTRAILINGZEROS numtrailingzeros +# define NUMTRAILINGZEROS numtrailingzeros static uint32_t numtrailingzeros(uint32_t i) { uint32_t tmp; @@ -610,7 +619,7 @@ static void prepare_wnaf_table(pniels_t * output, if (tbits == 0) return; - curve448_point_double(tmp, working); + ossl_curve448_point_double(tmp, working); pt_to_pniels(twop, tmp); add_pniels_to_pt(tmp, output[0], 0); @@ -621,11 +630,12 @@ static void prepare_wnaf_table(pniels_t * output, pt_to_pniels(output[i], tmp); } - curve448_point_destroy(tmp); + ossl_curve448_point_destroy(tmp); OPENSSL_cleanse(twop, sizeof(twop)); } -void curve448_base_double_scalarmul_non_secret(curve448_point_t combo, +void +ossl_curve448_base_double_scalarmul_non_secret(curve448_point_t combo, const curve448_scalar_t scalar1, const curve448_point_t base2, const curve448_scalar_t scalar2) @@ -645,7 +655,7 @@ void curve448_base_double_scalarmul_non_secret(curve448_point_t combo, i = control_var[0].power; if (i < 0) { - curve448_point_copy(combo, curve448_point_identity); + curve448_point_copy(combo, ossl_curve448_point_identity); return; } if (i > control_pre[0].power) { @@ -653,13 +663,14 @@ void curve448_base_double_scalarmul_non_secret(curve448_point_t combo, contv++; } else if (i == control_pre[0].power && i >= 0) { pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]); - add_niels_to_pt(combo, curve448_wnaf_base[control_pre[0].addend >> 1], + add_niels_to_pt(combo, + ossl_curve448_wnaf_base[control_pre[0].addend >> 1], i); contv++; contp++; } else { i = control_pre[0].power; - niels_to_pt(combo, curve448_wnaf_base[control_pre[0].addend >> 1]); + niels_to_pt(combo, ossl_curve448_wnaf_base[control_pre[0].addend >> 1]); contp++; } @@ -688,11 +699,11 @@ void curve448_base_double_scalarmul_non_secret(curve448_point_t combo, if (control_pre[contp].addend > 0) add_niels_to_pt(combo, - curve448_wnaf_base[control_pre[contp].addend + ossl_curve448_wnaf_base[control_pre[contp].addend >> 1], i); else sub_niels_from_pt(combo, - curve448_wnaf_base[(-control_pre + ossl_curve448_wnaf_base[(-control_pre [contp].addend) >> 1], i); contp++; } @@ -709,20 +720,20 @@ void curve448_base_double_scalarmul_non_secret(curve448_point_t combo, (void)ncb_pre; } -void curve448_point_destroy(curve448_point_t point) +void ossl_curve448_point_destroy(curve448_point_t point) { OPENSSL_cleanse(point, sizeof(curve448_point_t)); } -int X448(uint8_t out_shared_key[56], const uint8_t private_key[56], - const uint8_t peer_public_value[56]) +int ossl_x448(uint8_t out_shared_key[56], const uint8_t private_key[56], + const uint8_t peer_public_value[56]) { - return x448_int(out_shared_key, peer_public_value, private_key) + return ossl_x448_int(out_shared_key, peer_public_value, private_key) == C448_SUCCESS; } -void X448_public_from_private(uint8_t out_public_value[56], - const uint8_t private_key[56]) +void ossl_x448_public_from_private(uint8_t out_public_value[56], + const uint8_t private_key[56]) { - x448_derive_public_key(out_public_value, private_key); + ossl_x448_derive_public_key(out_public_value, private_key); } diff --git a/crypto/openssl/crypto/ec/curve448/curve448_local.h b/crypto/openssl/crypto/ec/curve448/curve448_local.h index b27770661f89..3410f091a655 100644 --- a/crypto/openssl/crypto/ec/curve448/curve448_local.h +++ b/crypto/openssl/crypto/ec/curve448/curve448_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,29 +10,15 @@ # define OSSL_CRYPTO_EC_CURVE448_LOCAL_H # include "curve448utils.h" -int X448(uint8_t out_shared_key[56], const uint8_t private_key[56], - const uint8_t peer_public_value[56]); +int +ossl_ed448ph_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], + const uint8_t public_key[57], const uint8_t private_key[57], + const uint8_t *context, size_t context_len, const char *propq); -void X448_public_from_private(uint8_t out_public_value[56], - const uint8_t private_key[56]); - -int ED448_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, - const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len); - -int ED448_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len); - -int ED448ph_sign(uint8_t *out_sig, const uint8_t hash[64], - const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len); - -int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[114], - const uint8_t public_key[57], const uint8_t *context, - size_t context_len); - -int ED448_public_from_private(uint8_t out_public_key[57], - const uint8_t private_key[57]); +int +ossl_ed448ph_verify(OSSL_LIB_CTX *ctx, const uint8_t hash[64], + const uint8_t signature[114], const uint8_t public_key[57], + const uint8_t *context, size_t context_len, + const char *propq); #endif /* OSSL_CRYPTO_EC_CURVE448_LOCAL_H */ diff --git a/crypto/openssl/crypto/ec/curve448/curve448_tables.c b/crypto/openssl/crypto/ec/curve448/curve448_tables.c index 9ef29769e3b3..0c6f626b3e6e 100644 --- a/crypto/openssl/crypto/ec/curve448/curve448_tables.c +++ b/crypto/openssl/crypto/ec/curve448/curve448_tables.c @@ -1,8 +1,8 @@ /* - * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -1058,7 +1058,7 @@ static const curve448_precomputed_s curve448_precomputed_base_table = { }} } }; -const struct curve448_precomputed_s *curve448_precomputed_base +const struct curve448_precomputed_s *ossl_curve448_precomputed_base = &curve448_precomputed_base_table; static const niels_t curve448_wnaf_base_table[32] = { @@ -1480,4 +1480,4 @@ static const niels_t curve448_wnaf_base_table[32] = { 0x001979c0df237316ULL, 0x00501e953a919b87ULL)}, }} }; -const niels_t *curve448_wnaf_base = curve448_wnaf_base_table; +const niels_t *ossl_curve448_wnaf_base = curve448_wnaf_base_table; diff --git a/crypto/openssl/crypto/ec/curve448/curve448utils.h b/crypto/openssl/crypto/ec/curve448/curve448utils.h index 86c258e745e4..664c6e6ff306 100644 --- a/crypto/openssl/crypto/ec/curve448/curve448utils.h +++ b/crypto/openssl/crypto/ec/curve448/curve448utils.h @@ -1,8 +1,8 @@ /* - * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015 Cryptography Research, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,6 +15,8 @@ # include +# include "internal/numbers.h" + /* * Internal word types. Somewhat tricky. This could be decided separately per * platform. However, the structs do need to be all the same size and @@ -41,9 +43,9 @@ typedef int64_t c448_sword_t; /* "Boolean" type, will be set to all-zero or all-one (i.e. -1u) */ typedef uint64_t c448_bool_t; /* Double-word size for internal computations */ -typedef __uint128_t c448_dword_t; +typedef uint128_t c448_dword_t; /* Signed double-word size for internal computations */ -typedef __int128_t c448_dsword_t; +typedef int128_t c448_dsword_t; # elif C448_WORD_BITS == 32 /* Word size for internal computations */ typedef uint32_t c448_word_t; diff --git a/crypto/openssl/crypto/ec/curve448/ed448.h b/crypto/openssl/crypto/ec/curve448/ed448.h index c1e5c2832f9b..00b2bae580ba 100644 --- a/crypto/openssl/crypto/ec/curve448/ed448.h +++ b/crypto/openssl/crypto/ec/curve448/ed448.h @@ -1,8 +1,8 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -37,9 +37,12 @@ * pubkey (out): The public key. * privkey (in): The private key. */ -c448_error_t c448_ed448_derive_public_key( - uint8_t pubkey [EDDSA_448_PUBLIC_BYTES], - const uint8_t privkey [EDDSA_448_PRIVATE_BYTES]); +c448_error_t +ossl_c448_ed448_derive_public_key( + OSSL_LIB_CTX *ctx, + uint8_t pubkey [EDDSA_448_PUBLIC_BYTES], + const uint8_t privkey [EDDSA_448_PRIVATE_BYTES], + const char *propq); /* * EdDSA signing. @@ -58,13 +61,15 @@ c448_error_t c448_ed448_derive_public_key( * non-prehashed messages, at least without some very careful protocol-level * disambiguation. For Ed448 it is safe. */ -c448_error_t c448_ed448_sign( - uint8_t signature[EDDSA_448_SIGNATURE_BYTES], - const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], - const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], - const uint8_t *message, size_t message_len, - uint8_t prehashed, const uint8_t *context, - size_t context_len); +c448_error_t +ossl_c448_ed448_sign(OSSL_LIB_CTX *ctx, + uint8_t signature[EDDSA_448_SIGNATURE_BYTES], + const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], + const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], + const uint8_t *message, size_t message_len, + uint8_t prehashed, const uint8_t *context, + size_t context_len, + const char *propq); /* * EdDSA signing with prehash. @@ -82,13 +87,15 @@ c448_error_t c448_ed448_sign( * non-prehashed messages, at least without some very careful protocol-level * disambiguation. For Ed448 it is safe. */ -c448_error_t c448_ed448_sign_prehash( - uint8_t signature[EDDSA_448_SIGNATURE_BYTES], - const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], - const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], - const uint8_t hash[64], - const uint8_t *context, - size_t context_len); +c448_error_t +ossl_c448_ed448_sign_prehash(OSSL_LIB_CTX *ctx, + uint8_t signature[EDDSA_448_SIGNATURE_BYTES], + const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], + const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], + const uint8_t hash[64], + const uint8_t *context, + size_t context_len, + const char *propq); /* * EdDSA signature verification. @@ -108,13 +115,16 @@ c448_error_t c448_ed448_sign_prehash( * non-prehashed messages, at least without some very careful protocol-level * disambiguation. For Ed448 it is safe. */ -c448_error_t c448_ed448_verify(const uint8_t - signature[EDDSA_448_SIGNATURE_BYTES], - const uint8_t - pubkey[EDDSA_448_PUBLIC_BYTES], - const uint8_t *message, size_t message_len, - uint8_t prehashed, const uint8_t *context, - uint8_t context_len); +c448_error_t +ossl_c448_ed448_verify(OSSL_LIB_CTX *ctx, + const uint8_t + signature[EDDSA_448_SIGNATURE_BYTES], + const uint8_t + pubkey[EDDSA_448_PUBLIC_BYTES], + const uint8_t *message, size_t message_len, + uint8_t prehashed, const uint8_t *context, + uint8_t context_len, + const char *propq); /* * EdDSA signature verification. @@ -133,12 +143,15 @@ c448_error_t c448_ed448_verify(const uint8_t * non-prehashed messages, at least without some very careful protocol-level * disambiguation. For Ed448 it is safe. */ -c448_error_t c448_ed448_verify_prehash( - const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], - const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], - const uint8_t hash[64], - const uint8_t *context, - uint8_t context_len); +c448_error_t +ossl_c448_ed448_verify_prehash( + OSSL_LIB_CTX *ctx, + const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], + const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], + const uint8_t hash[64], + const uint8_t *context, + uint8_t context_len, + const char *propq); /* * EdDSA point encoding. Used internally, exposed externally. @@ -163,7 +176,8 @@ c448_error_t c448_ed448_verify_prehash( * enc (out): The encoded point. * p (in): The point. */ -void curve448_point_mul_by_ratio_and_encode_like_eddsa( +void +ossl_curve448_point_mul_by_ratio_and_encode_like_eddsa( uint8_t enc [EDDSA_448_PUBLIC_BYTES], const curve448_point_t p); @@ -176,7 +190,8 @@ void curve448_point_mul_by_ratio_and_encode_like_eddsa( * enc (out): The encoded point. * p (in): The point. */ -c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio( +c448_error_t +ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio( curve448_point_t p, const uint8_t enc[EDDSA_448_PUBLIC_BYTES]); @@ -188,8 +203,11 @@ c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio( * x (out): The ECDH private key as in RFC7748 * ed (in): The EdDSA private key */ -c448_error_t c448_ed448_convert_private_key_to_x448( - uint8_t x[X448_PRIVATE_BYTES], - const uint8_t ed[EDDSA_448_PRIVATE_BYTES]); +c448_error_t +ossl_c448_ed448_convert_private_key_to_x448( + OSSL_LIB_CTX *ctx, + uint8_t x[X448_PRIVATE_BYTES], + const uint8_t ed[EDDSA_448_PRIVATE_BYTES], + const char *propq); #endif /* OSSL_CRYPTO_EC_CURVE448_ED448_H */ diff --git a/crypto/openssl/crypto/ec/curve448/eddsa.c b/crypto/openssl/crypto/ec/curve448/eddsa.c index 82741f543549..6648692ff395 100644 --- a/crypto/openssl/crypto/ec/curve448/eddsa.c +++ b/crypto/openssl/crypto/ec/curve448/eddsa.c @@ -1,8 +1,8 @@ /* - * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,6 +12,7 @@ #include #include #include +#include "crypto/ecx.h" #include "curve448_local.h" #include "word.h" #include "ed448.h" @@ -19,23 +20,31 @@ #define COFACTOR 4 -static c448_error_t oneshot_hash(uint8_t *out, size_t outlen, - const uint8_t *in, size_t inlen) +static c448_error_t oneshot_hash(OSSL_LIB_CTX *ctx, uint8_t *out, size_t outlen, + const uint8_t *in, size_t inlen, + const char *propq) { EVP_MD_CTX *hashctx = EVP_MD_CTX_new(); + EVP_MD *shake256 = NULL; + c448_error_t ret = C448_FAILURE; if (hashctx == NULL) return C448_FAILURE; - if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) + shake256 = EVP_MD_fetch(ctx, "SHAKE256", propq); + if (shake256 == NULL) + goto err; + + if (!EVP_DigestInit_ex(hashctx, shake256, NULL) || !EVP_DigestUpdate(hashctx, in, inlen) - || !EVP_DigestFinalXOF(hashctx, out, outlen)) { - EVP_MD_CTX_free(hashctx); - return C448_FAILURE; - } + || !EVP_DigestFinalXOF(hashctx, out, outlen)) + goto err; + ret = C448_SUCCESS; + err: EVP_MD_CTX_free(hashctx); - return C448_SUCCESS; + EVP_MD_free(shake256); + return ret; } static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES]) @@ -45,10 +54,12 @@ static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES]) secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 2] |= 0x80; } -static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed, +static c448_error_t hash_init_with_dom(OSSL_LIB_CTX *ctx, EVP_MD_CTX *hashctx, + uint8_t prehashed, uint8_t for_prehash, const uint8_t *context, - size_t context_len) + size_t context_len, + const char *propq) { #ifdef CHARSET_EBCDIC const char dom_s[] = {0x53, 0x69, 0x67, 0x45, @@ -57,6 +68,7 @@ static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed, const char dom_s[] = "SigEd448"; #endif uint8_t dom[2]; + EVP_MD *shake256 = NULL; if (context_len > UINT8_MAX) return C448_FAILURE; @@ -65,29 +77,42 @@ static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed, - (for_prehash == 0 ? 1 : 0)); dom[1] = (uint8_t)context_len; - if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) + shake256 = EVP_MD_fetch(ctx, "SHAKE256", propq); + if (shake256 == NULL) + return C448_FAILURE; + + if (!EVP_DigestInit_ex(hashctx, shake256, NULL) || !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s)) || !EVP_DigestUpdate(hashctx, dom, sizeof(dom)) - || !EVP_DigestUpdate(hashctx, context, context_len)) + || !EVP_DigestUpdate(hashctx, context, context_len)) { + EVP_MD_free(shake256); return C448_FAILURE; + } + EVP_MD_free(shake256); return C448_SUCCESS; } /* In this file because it uses the hash */ -c448_error_t c448_ed448_convert_private_key_to_x448( +c448_error_t +ossl_c448_ed448_convert_private_key_to_x448( + OSSL_LIB_CTX *ctx, uint8_t x[X448_PRIVATE_BYTES], - const uint8_t ed [EDDSA_448_PRIVATE_BYTES]) + const uint8_t ed [EDDSA_448_PRIVATE_BYTES], + const char *propq) { /* pass the private key through oneshot_hash function */ /* and keep the first X448_PRIVATE_BYTES bytes */ - return oneshot_hash(x, X448_PRIVATE_BYTES, ed, - EDDSA_448_PRIVATE_BYTES); + return oneshot_hash(ctx, x, X448_PRIVATE_BYTES, ed, + EDDSA_448_PRIVATE_BYTES, propq); } -c448_error_t c448_ed448_derive_public_key( +c448_error_t +ossl_c448_ed448_derive_public_key( + OSSL_LIB_CTX *ctx, uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], - const uint8_t privkey[EDDSA_448_PRIVATE_BYTES]) + const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], + const char *propq) { /* only this much used for keygen */ uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES]; @@ -95,14 +120,16 @@ c448_error_t c448_ed448_derive_public_key( unsigned int c; curve448_point_t p; - if (!oneshot_hash(secret_scalar_ser, sizeof(secret_scalar_ser), privkey, - EDDSA_448_PRIVATE_BYTES)) + if (!oneshot_hash(ctx, secret_scalar_ser, sizeof(secret_scalar_ser), + privkey, + EDDSA_448_PRIVATE_BYTES, + propq)) return C448_FAILURE; clamp(secret_scalar_ser); - curve448_scalar_decode_long(secret_scalar, secret_scalar_ser, - sizeof(secret_scalar_ser)); + ossl_curve448_scalar_decode_long(secret_scalar, secret_scalar_ser, + sizeof(secret_scalar_ser)); /* * Since we are going to mul_by_cofactor during encoding, divide by it @@ -113,27 +140,29 @@ c448_error_t c448_ed448_derive_public_key( * we might start at 2 instead of 1. */ for (c = 1; c < C448_EDDSA_ENCODE_RATIO; c <<= 1) - curve448_scalar_halve(secret_scalar, secret_scalar); + ossl_curve448_scalar_halve(secret_scalar, secret_scalar); - curve448_precomputed_scalarmul(p, curve448_precomputed_base, secret_scalar); + ossl_curve448_precomputed_scalarmul(p, ossl_curve448_precomputed_base, + secret_scalar); - curve448_point_mul_by_ratio_and_encode_like_eddsa(pubkey, p); + ossl_curve448_point_mul_by_ratio_and_encode_like_eddsa(pubkey, p); /* Cleanup */ - curve448_scalar_destroy(secret_scalar); - curve448_point_destroy(p); + ossl_curve448_scalar_destroy(secret_scalar); + ossl_curve448_point_destroy(p); OPENSSL_cleanse(secret_scalar_ser, sizeof(secret_scalar_ser)); return C448_SUCCESS; } -c448_error_t c448_ed448_sign( - uint8_t signature[EDDSA_448_SIGNATURE_BYTES], - const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], - const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], - const uint8_t *message, size_t message_len, - uint8_t prehashed, const uint8_t *context, - size_t context_len) +c448_error_t +ossl_c448_ed448_sign(OSSL_LIB_CTX *ctx, + uint8_t signature[EDDSA_448_SIGNATURE_BYTES], + const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], + const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], + const uint8_t *message, size_t message_len, + uint8_t prehashed, const uint8_t *context, + size_t context_len, const char *propq) { curve448_scalar_t secret_scalar; EVP_MD_CTX *hashctx = EVP_MD_CTX_new(); @@ -148,20 +177,21 @@ c448_error_t c448_ed448_sign( { /* - * Schedule the secret key, First EDDSA_448_PRIVATE_BYTES is serialised + * Schedule the secret key, First EDDSA_448_PRIVATE_BYTES is serialized * secret scalar,next EDDSA_448_PRIVATE_BYTES bytes is the seed. */ uint8_t expanded[EDDSA_448_PRIVATE_BYTES * 2]; - if (!oneshot_hash(expanded, sizeof(expanded), privkey, - EDDSA_448_PRIVATE_BYTES)) + if (!oneshot_hash(ctx, expanded, sizeof(expanded), privkey, + EDDSA_448_PRIVATE_BYTES, propq)) goto err; clamp(expanded); - curve448_scalar_decode_long(secret_scalar, expanded, - EDDSA_448_PRIVATE_BYTES); + ossl_curve448_scalar_decode_long(secret_scalar, expanded, + EDDSA_448_PRIVATE_BYTES); /* Hash to create the nonce */ - if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len) + if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, + context_len, propq) || !EVP_DigestUpdate(hashctx, expanded + EDDSA_448_PRIVATE_BYTES, EDDSA_448_PRIVATE_BYTES) @@ -178,7 +208,7 @@ c448_error_t c448_ed448_sign( if (!EVP_DigestFinalXOF(hashctx, nonce, sizeof(nonce))) goto err; - curve448_scalar_decode_long(nonce_scalar, nonce, sizeof(nonce)); + ossl_curve448_scalar_decode_long(nonce_scalar, nonce, sizeof(nonce)); OPENSSL_cleanse(nonce, sizeof(nonce)); } @@ -187,44 +217,45 @@ c448_error_t c448_ed448_sign( curve448_scalar_t nonce_scalar_2; curve448_point_t p; - curve448_scalar_halve(nonce_scalar_2, nonce_scalar); + ossl_curve448_scalar_halve(nonce_scalar_2, nonce_scalar); for (c = 2; c < C448_EDDSA_ENCODE_RATIO; c <<= 1) - curve448_scalar_halve(nonce_scalar_2, nonce_scalar_2); + ossl_curve448_scalar_halve(nonce_scalar_2, nonce_scalar_2); - curve448_precomputed_scalarmul(p, curve448_precomputed_base, - nonce_scalar_2); - curve448_point_mul_by_ratio_and_encode_like_eddsa(nonce_point, p); - curve448_point_destroy(p); - curve448_scalar_destroy(nonce_scalar_2); + ossl_curve448_precomputed_scalarmul(p, ossl_curve448_precomputed_base, + nonce_scalar_2); + ossl_curve448_point_mul_by_ratio_and_encode_like_eddsa(nonce_point, p); + ossl_curve448_point_destroy(p); + ossl_curve448_scalar_destroy(nonce_scalar_2); } { uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES]; /* Compute the challenge */ - if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len) + if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, context_len, + propq) || !EVP_DigestUpdate(hashctx, nonce_point, sizeof(nonce_point)) || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES) || !EVP_DigestUpdate(hashctx, message, message_len) || !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge))) goto err; - curve448_scalar_decode_long(challenge_scalar, challenge, - sizeof(challenge)); + ossl_curve448_scalar_decode_long(challenge_scalar, challenge, + sizeof(challenge)); OPENSSL_cleanse(challenge, sizeof(challenge)); } - curve448_scalar_mul(challenge_scalar, challenge_scalar, secret_scalar); - curve448_scalar_add(challenge_scalar, challenge_scalar, nonce_scalar); + ossl_curve448_scalar_mul(challenge_scalar, challenge_scalar, secret_scalar); + ossl_curve448_scalar_add(challenge_scalar, challenge_scalar, nonce_scalar); OPENSSL_cleanse(signature, EDDSA_448_SIGNATURE_BYTES); memcpy(signature, nonce_point, sizeof(nonce_point)); - curve448_scalar_encode(&signature[EDDSA_448_PUBLIC_BYTES], - challenge_scalar); + ossl_curve448_scalar_encode(&signature[EDDSA_448_PUBLIC_BYTES], + challenge_scalar); - curve448_scalar_destroy(secret_scalar); - curve448_scalar_destroy(nonce_scalar); - curve448_scalar_destroy(challenge_scalar); + ossl_curve448_scalar_destroy(secret_scalar); + ossl_curve448_scalar_destroy(nonce_scalar); + ossl_curve448_scalar_destroy(challenge_scalar); ret = C448_SUCCESS; err: @@ -232,23 +263,27 @@ c448_error_t c448_ed448_sign( return ret; } -c448_error_t c448_ed448_sign_prehash( +c448_error_t +ossl_c448_ed448_sign_prehash( + OSSL_LIB_CTX *ctx, uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, - size_t context_len) + size_t context_len, const char *propq) { - return c448_ed448_sign(signature, privkey, pubkey, hash, 64, 1, context, - context_len); + return ossl_c448_ed448_sign(ctx, signature, privkey, pubkey, hash, 64, 1, + context, context_len, propq); } -c448_error_t c448_ed448_verify( +c448_error_t +ossl_c448_ed448_verify( + OSSL_LIB_CTX *ctx, const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, - uint8_t context_len) + uint8_t context_len, const char *propq) { curve448_point_t pk_point, r_point; c448_error_t error; @@ -280,13 +315,13 @@ c448_error_t c448_ed448_verify( return C448_FAILURE; error = - curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey); + ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey); if (C448_SUCCESS != error) return error; error = - curve448_point_decode_like_eddsa_and_mul_by_ratio(r_point, signature); + ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio(r_point, signature); if (C448_SUCCESS != error) return error; @@ -296,8 +331,8 @@ c448_error_t c448_ed448_verify( uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES]; if (hashctx == NULL - || !hash_init_with_dom(hashctx, prehashed, 0, context, - context_len) + || !hash_init_with_dom(ctx, hashctx, prehashed, 0, context, + context_len, propq) || !EVP_DigestUpdate(hashctx, signature, EDDSA_448_PUBLIC_BYTES) || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES) || !EVP_DigestUpdate(hashctx, message, message_len) @@ -307,71 +342,82 @@ c448_error_t c448_ed448_verify( } EVP_MD_CTX_free(hashctx); - curve448_scalar_decode_long(challenge_scalar, challenge, - sizeof(challenge)); + ossl_curve448_scalar_decode_long(challenge_scalar, challenge, + sizeof(challenge)); OPENSSL_cleanse(challenge, sizeof(challenge)); } - curve448_scalar_sub(challenge_scalar, curve448_scalar_zero, - challenge_scalar); + ossl_curve448_scalar_sub(challenge_scalar, ossl_curve448_scalar_zero, + challenge_scalar); - curve448_scalar_decode_long(response_scalar, - &signature[EDDSA_448_PUBLIC_BYTES], - EDDSA_448_PRIVATE_BYTES); + ossl_curve448_scalar_decode_long(response_scalar, + &signature[EDDSA_448_PUBLIC_BYTES], + EDDSA_448_PRIVATE_BYTES); /* pk_point = -c(x(P)) + (cx + k)G = kG */ - curve448_base_double_scalarmul_non_secret(pk_point, - response_scalar, - pk_point, challenge_scalar); - return c448_succeed_if(curve448_point_eq(pk_point, r_point)); + ossl_curve448_base_double_scalarmul_non_secret(pk_point, + response_scalar, + pk_point, challenge_scalar); + return c448_succeed_if(ossl_curve448_point_eq(pk_point, r_point)); } -c448_error_t c448_ed448_verify_prehash( +c448_error_t +ossl_c448_ed448_verify_prehash( + OSSL_LIB_CTX *ctx, const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, - uint8_t context_len) + uint8_t context_len, const char *propq) { - return c448_ed448_verify(signature, pubkey, hash, 64, 1, context, - context_len); + return ossl_c448_ed448_verify(ctx, signature, pubkey, hash, 64, 1, context, + context_len, propq); } -int ED448_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, - const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len) +int +ossl_ed448_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t *message, + size_t message_len, const uint8_t public_key[57], + const uint8_t private_key[57], const uint8_t *context, + size_t context_len, const char *propq) { - return c448_ed448_sign(out_sig, private_key, public_key, message, - message_len, 0, context, context_len) - == C448_SUCCESS; + return ossl_c448_ed448_sign(ctx, out_sig, private_key, public_key, message, + message_len, 0, context, context_len, + propq) == C448_SUCCESS; } -int ED448_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len) +int +ossl_ed448_verify(OSSL_LIB_CTX *ctx, const uint8_t *message, size_t message_len, + const uint8_t signature[114], const uint8_t public_key[57], + const uint8_t *context, size_t context_len, const char *propq) { - return c448_ed448_verify(signature, public_key, message, message_len, 0, - context, (uint8_t)context_len) == C448_SUCCESS; + return ossl_c448_ed448_verify(ctx, signature, public_key, message, + message_len, 0, context, (uint8_t)context_len, + propq) == C448_SUCCESS; } -int ED448ph_sign(uint8_t *out_sig, const uint8_t hash[64], - const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len) +int +ossl_ed448ph_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], + const uint8_t public_key[57], const uint8_t private_key[57], + const uint8_t *context, size_t context_len, const char *propq) { - return c448_ed448_sign_prehash(out_sig, private_key, public_key, hash, - context, context_len) == C448_SUCCESS; - + return ossl_c448_ed448_sign_prehash(ctx, out_sig, private_key, public_key, + hash, context, context_len, + propq) == C448_SUCCESS; } -int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[114], - const uint8_t public_key[57], const uint8_t *context, - size_t context_len) +int +ossl_ed448ph_verify(OSSL_LIB_CTX *ctx, const uint8_t hash[64], + const uint8_t signature[114], const uint8_t public_key[57], + const uint8_t *context, size_t context_len, + const char *propq) { - return c448_ed448_verify_prehash(signature, public_key, hash, context, - (uint8_t)context_len) == C448_SUCCESS; + return ossl_c448_ed448_verify_prehash(ctx, signature, public_key, hash, + context, (uint8_t)context_len, + propq) == C448_SUCCESS; } -int ED448_public_from_private(uint8_t out_public_key[57], - const uint8_t private_key[57]) +int +ossl_ed448_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[57], + const uint8_t private_key[57], const char *propq) { - return c448_ed448_derive_public_key(out_public_key, private_key) - == C448_SUCCESS; + return ossl_c448_ed448_derive_public_key(ctx, out_public_key, private_key, + propq) == C448_SUCCESS; } diff --git a/crypto/openssl/crypto/ec/curve448/f_generic.c b/crypto/openssl/crypto/ec/curve448/f_generic.c index 09d08165e250..4c571810d3af 100644 --- a/crypto/openssl/crypto/ec/curve448/f_generic.c +++ b/crypto/openssl/crypto/ec/curve448/f_generic.c @@ -1,8 +1,8 @@ /* - * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -18,7 +18,7 @@ static const gf MODULUS = { }; /* Serialize to wire format. */ -void gf_serialize(uint8_t serial[SER_BYTES], const gf x, int with_hibit) +void gf_serialize(uint8_t *serial, const gf x, int with_hibit) { unsigned int j = 0, fill = 0; dword_t buffer = 0; diff --git a/crypto/openssl/crypto/ec/curve448/field.h b/crypto/openssl/crypto/ec/curve448/field.h index 4e4eda664f78..e1c633378950 100644 --- a/crypto/openssl/crypto/ec/curve448/field.h +++ b/crypto/openssl/crypto/ec/curve448/field.h @@ -2,7 +2,7 @@ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2014 Cryptography Research, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -62,14 +62,19 @@ mask_t gf_eq(const gf x, const gf y); mask_t gf_lobit(const gf x); mask_t gf_hibit(const gf x); -void gf_serialize(uint8_t serial[SER_BYTES], const gf x, int with_highbit); +void gf_serialize(uint8_t *serial, const gf x, int with_highbit); mask_t gf_deserialize(gf x, const uint8_t serial[SER_BYTES], int with_hibit, uint8_t hi_nmask); -# include "f_impl.h" /* Bring in the inline implementations */ # define LIMBPERM(i) (i) -# define LIMB_MASK(i) (((1)<limb, b, sc_p, 0); } -void curve448_scalar_add(curve448_scalar_t out, const curve448_scalar_t a, +void +ossl_curve448_scalar_add(curve448_scalar_t out, const curve448_scalar_t a, const curve448_scalar_t b) { c448_dword_t chain = 0; @@ -148,9 +150,9 @@ static ossl_inline void scalar_decode_short(curve448_scalar_t s, } } -c448_error_t curve448_scalar_decode( - curve448_scalar_t s, - const unsigned char ser[C448_SCALAR_BYTES]) +c448_error_t +ossl_curve448_scalar_decode(curve448_scalar_t s, + const unsigned char ser[C448_SCALAR_BYTES]) { unsigned int i; c448_dsword_t accum = 0; @@ -160,24 +162,25 @@ c448_error_t curve448_scalar_decode( accum = (accum + s->limb[i] - sc_p->limb[i]) >> WBITS; /* Here accum == 0 or -1 */ - curve448_scalar_mul(s, s, curve448_scalar_one); /* ham-handed reduce */ + ossl_curve448_scalar_mul(s, s, ossl_curve448_scalar_one); /* ham-handed reduce */ return c448_succeed_if(~word_is_zero((uint32_t)accum)); } -void curve448_scalar_destroy(curve448_scalar_t scalar) +void ossl_curve448_scalar_destroy(curve448_scalar_t scalar) { OPENSSL_cleanse(scalar, sizeof(curve448_scalar_t)); } -void curve448_scalar_decode_long(curve448_scalar_t s, +void +ossl_curve448_scalar_decode_long(curve448_scalar_t s, const unsigned char *ser, size_t ser_len) { size_t i; curve448_scalar_t t1, t2; if (ser_len == 0) { - curve448_scalar_copy(s, curve448_scalar_zero); + curve448_scalar_copy(s, ossl_curve448_scalar_zero); return; } @@ -190,24 +193,25 @@ void curve448_scalar_decode_long(curve448_scalar_t s, if (ser_len == sizeof(curve448_scalar_t)) { assert(i == 0); /* ham-handed reduce */ - curve448_scalar_mul(s, t1, curve448_scalar_one); - curve448_scalar_destroy(t1); + ossl_curve448_scalar_mul(s, t1, ossl_curve448_scalar_one); + ossl_curve448_scalar_destroy(t1); return; } while (i) { i -= C448_SCALAR_BYTES; sc_montmul(t1, t1, sc_r2); - (void)curve448_scalar_decode(t2, ser + i); - curve448_scalar_add(t1, t1, t2); + (void)ossl_curve448_scalar_decode(t2, ser + i); + ossl_curve448_scalar_add(t1, t1, t2); } curve448_scalar_copy(s, t1); - curve448_scalar_destroy(t1); - curve448_scalar_destroy(t2); + ossl_curve448_scalar_destroy(t1); + ossl_curve448_scalar_destroy(t2); } -void curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES], +void +ossl_curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES], const curve448_scalar_t s) { unsigned int i, j, k = 0; @@ -218,7 +222,8 @@ void curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES], } } -void curve448_scalar_halve(curve448_scalar_t out, const curve448_scalar_t a) +void +ossl_curve448_scalar_halve(curve448_scalar_t out, const curve448_scalar_t a) { c448_word_t mask = 0 - (a->limb[0] & 1); c448_dword_t chain = 0; diff --git a/crypto/openssl/crypto/ec/curve448/word.h b/crypto/openssl/crypto/ec/curve448/word.h index 237cc9b63139..f8292eef88f2 100644 --- a/crypto/openssl/crypto/ec/curve448/word.h +++ b/crypto/openssl/crypto/ec/curve448/word.h @@ -1,8 +1,8 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2014 Cryptography Research, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -17,15 +17,20 @@ # include # include # include -# include "arch_intrinsics.h" # include "curve448utils.h" +# ifdef INT128_MAX +# include "arch_64/arch_intrinsics.h" +# else +# include "arch_32/arch_intrinsics.h" +# endif + # if (ARCH_WORD_BITS == 64) typedef uint64_t word_t, mask_t; -typedef __uint128_t dword_t; +typedef uint128_t dword_t; typedef int32_t hsword_t; typedef int64_t sword_t; -typedef __int128_t dsword_t; +typedef int128_t dsword_t; # elif (ARCH_WORD_BITS == 32) typedef uint32_t word_t, mask_t; typedef uint64_t dword_t; diff --git a/crypto/openssl/crypto/ec/ec2_oct.c b/crypto/openssl/crypto/ec/ec2_oct.c index 788e6501fbcd..10a4932591d6 100644 --- a/crypto/openssl/crypto/ec/ec2_oct.c +++ b/crypto/openssl/crypto/ec/ec2_oct.c @@ -2,12 +2,18 @@ * Copyright 2011-2021 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 + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "ec_local.h" @@ -30,23 +36,22 @@ * the same method, but claim no priority date earlier than July 29, 1994 * (and additionally fail to cite the EUROCRYPT '92 publication as prior art). */ -int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, - EC_POINT *point, - const BIGNUM *x_, int y_bit, - BN_CTX *ctx) +int ossl_ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x_, int y_bit, + BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *tmp, *x, *y, *z; int ret = 0, z0; - - /* clear error queue */ - ERR_clear_error(); +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } +#endif y_bit = (y_bit != 0) ? 1 : 0; @@ -72,19 +77,24 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, goto err; if (!BN_GF2m_add(tmp, x, tmp)) goto err; + ERR_set_mark(); if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) { +#ifndef FIPS_MODULE unsigned long err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION) { - ERR_clear_error(); - ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, - EC_R_INVALID_COMPRESSED_POINT); + ERR_pop_to_mark(); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT); } else - ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, - ERR_R_BN_LIB); +#endif + { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + } goto err; } + ERR_clear_last_mark(); z0 = (BN_is_odd(z)) ? 1 : 0; if (!group->meth->field_mul(group, y, x, z, ctx)) goto err; @@ -101,7 +111,9 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, err: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } @@ -110,20 +122,23 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, * length will be returned. If the length len of buf is smaller than required * an error will be returned. */ -size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, - point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *ctx) +size_t ossl_ec_GF2m_simple_point2oct(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx) { size_t ret; - BN_CTX *new_ctx = NULL; int used_ctx = 0; BIGNUM *x, *y, *yxi; size_t field_len, i, skip; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif if ((form != POINT_CONVERSION_COMPRESSED) && (form != POINT_CONVERSION_UNCOMPRESSED) && (form != POINT_CONVERSION_HYBRID)) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM); goto err; } @@ -131,7 +146,7 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, /* encodes to a single 0 octet */ if (buf != NULL) { if (len < 1) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); return 0; } buf[0] = 0; @@ -148,15 +163,17 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, /* if 'buf' is NULL, just return required length */ if (buf != NULL) { if (len < ret) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); goto err; } +#ifndef FIPS_MODULE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } +#endif BN_CTX_start(ctx); used_ctx = 1; @@ -181,7 +198,7 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, skip = field_len - BN_num_bytes(x); if (skip > field_len) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } while (skip > 0) { @@ -191,7 +208,7 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, skip = BN_bn2bin(x, buf + i); i += skip; if (i != 1 + field_len) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } @@ -199,7 +216,7 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, || form == POINT_CONVERSION_HYBRID) { skip = field_len - BN_num_bytes(y); if (skip > field_len) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } while (skip > 0) { @@ -211,20 +228,24 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, } if (i != ret) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } } if (used_ctx) BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; err: if (used_ctx) BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return 0; } @@ -232,19 +253,21 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, * Converts an octet string representation to an EC_POINT. Note that the * simple implementation only uses affine coordinates. */ -int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, - const unsigned char *buf, size_t len, - BN_CTX *ctx) +int ossl_ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, + const unsigned char *buf, size_t len, + BN_CTX *ctx) { point_conversion_form_t form; int y_bit, m; - BN_CTX *new_ctx = NULL; BIGNUM *x, *y, *yxi; size_t field_len, enc_len; int ret = 0; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif if (len == 0) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); return 0; } @@ -265,18 +288,18 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) && (form != POINT_CONVERSION_UNCOMPRESSED) && (form != POINT_CONVERSION_HYBRID)) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); return 0; } if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); return 0; } /* The point at infinity is represented by a single zero octet. */ if (form == 0) { if (len != 1) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); return 0; } @@ -290,15 +313,17 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; if (len != enc_len) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); return 0; } +#ifndef FIPS_MODULE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } +#endif BN_CTX_start(ctx); x = BN_CTX_get(ctx); @@ -310,7 +335,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, if (!BN_bin2bn(buf + 1, field_len, x)) goto err; if (BN_num_bits(x) > m) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); goto err; } @@ -321,7 +346,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err; if (BN_num_bits(y) > m) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); goto err; } if (form == POINT_CONVERSION_HYBRID) { @@ -332,14 +357,14 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, */ if (BN_is_zero(x)) { if (y_bit != 0) { - ECerr(ERR_LIB_EC, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); goto err; } } else { if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err; if (y_bit != BN_is_odd(yxi)) { - ECerr(ERR_LIB_EC, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); goto err; } } @@ -357,7 +382,9 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, err: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } #endif diff --git a/crypto/openssl/crypto/ec/ec2_smpl.c b/crypto/openssl/crypto/ec/ec2_smpl.c index 84e5537a034a..3a59544c8b2f 100644 --- a/crypto/openssl/crypto/ec/ec2_smpl.c +++ b/crypto/openssl/crypto/ec/ec2_smpl.c @@ -1,13 +1,19 @@ /* - * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2021 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 + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "crypto/bn.h" @@ -19,7 +25,7 @@ * Initialize a GF(2^m)-based EC_GROUP structure. Note that all other members * are handled by EC_GROUP_new. */ -int ec_GF2m_simple_group_init(EC_GROUP *group) +int ossl_ec_GF2m_simple_group_init(EC_GROUP *group) { group->field = BN_new(); group->a = BN_new(); @@ -38,7 +44,7 @@ int ec_GF2m_simple_group_init(EC_GROUP *group) * Free a GF(2^m)-based EC_GROUP structure. Note that all other members are * handled by EC_GROUP_free. */ -void ec_GF2m_simple_group_finish(EC_GROUP *group) +void ossl_ec_GF2m_simple_group_finish(EC_GROUP *group) { BN_free(group->field); BN_free(group->a); @@ -49,7 +55,7 @@ void ec_GF2m_simple_group_finish(EC_GROUP *group) * Clear and free a GF(2^m)-based EC_GROUP structure. Note that all other * members are handled by EC_GROUP_clear_free. */ -void ec_GF2m_simple_group_clear_finish(EC_GROUP *group) +void ossl_ec_GF2m_simple_group_clear_finish(EC_GROUP *group) { BN_clear_free(group->field); BN_clear_free(group->a); @@ -66,7 +72,7 @@ void ec_GF2m_simple_group_clear_finish(EC_GROUP *group) * Copy a GF(2^m)-based EC_GROUP structure. Note that all other members are * handled by EC_GROUP_copy. */ -int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) +int ossl_ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) { if (!BN_copy(dest->field, src->field)) return 0; @@ -92,9 +98,9 @@ int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) } /* Set the curve parameters of an EC_GROUP structure. */ -int ec_GF2m_simple_group_set_curve(EC_GROUP *group, - const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) +int ossl_ec_GF2m_simple_group_set_curve(EC_GROUP *group, + const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) { int ret = 0, i; @@ -103,7 +109,7 @@ int ec_GF2m_simple_group_set_curve(EC_GROUP *group, goto err; i = BN_GF2m_poly2arr(group->field, group->poly, 6) - 1; if ((i != 5) && (i != 3)) { - ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD); + ERR_raise(ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD); goto err; } @@ -132,8 +138,8 @@ int ec_GF2m_simple_group_set_curve(EC_GROUP *group, * Get the curve parameters of an EC_GROUP structure. If p, a, or b are NULL * then there values will not be set but the method will return with success. */ -int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, - BIGNUM *a, BIGNUM *b, BN_CTX *ctx) +int ossl_ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, + BIGNUM *a, BIGNUM *b, BN_CTX *ctx) { int ret = 0; @@ -162,7 +168,7 @@ int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, * Gets the degree of the field. For a curve over GF(2^m) this is the value * m. */ -int ec_GF2m_simple_group_get_degree(const EC_GROUP *group) +int ossl_ec_GF2m_simple_group_get_degree(const EC_GROUP *group) { return BN_num_bits(group->field) - 1; } @@ -171,21 +177,22 @@ int ec_GF2m_simple_group_get_degree(const EC_GROUP *group) * Checks the discriminant of the curve. y^2 + x*y = x^3 + a*x^2 + b is an * elliptic curve <=> b != 0 (mod p) */ -int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, - BN_CTX *ctx) +int ossl_ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, + BN_CTX *ctx) { int ret = 0; BIGNUM *b; +#ifndef FIPS_MODULE BN_CTX *new_ctx = NULL; if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { - ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } } +#endif BN_CTX_start(ctx); b = BN_CTX_get(ctx); if (b == NULL) @@ -205,12 +212,14 @@ int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, err: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } /* Initializes an EC_POINT. */ -int ec_GF2m_simple_point_init(EC_POINT *point) +int ossl_ec_GF2m_simple_point_init(EC_POINT *point) { point->X = BN_new(); point->Y = BN_new(); @@ -226,7 +235,7 @@ int ec_GF2m_simple_point_init(EC_POINT *point) } /* Frees an EC_POINT. */ -void ec_GF2m_simple_point_finish(EC_POINT *point) +void ossl_ec_GF2m_simple_point_finish(EC_POINT *point) { BN_free(point->X); BN_free(point->Y); @@ -234,7 +243,7 @@ void ec_GF2m_simple_point_finish(EC_POINT *point) } /* Clears and frees an EC_POINT. */ -void ec_GF2m_simple_point_clear_finish(EC_POINT *point) +void ossl_ec_GF2m_simple_point_clear_finish(EC_POINT *point) { BN_clear_free(point->X); BN_clear_free(point->Y); @@ -246,7 +255,7 @@ void ec_GF2m_simple_point_clear_finish(EC_POINT *point) * Copy the contents of one EC_POINT into another. Assumes dest is * initialized. */ -int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src) +int ossl_ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src) { if (!BN_copy(dest->X, src->X)) return 0; @@ -264,8 +273,8 @@ int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src) * Set an EC_POINT to the point at infinity. A point at infinity is * represented by having Z=0. */ -int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, - EC_POINT *point) +int ossl_ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, + EC_POINT *point) { point->Z_is_one = 0; BN_zero(point->Z); @@ -276,15 +285,15 @@ int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, * Set the coordinates of an EC_POINT using affine coordinates. Note that * the simple implementation only uses affine coordinates. */ -int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, - EC_POINT *point, - const BIGNUM *x, - const BIGNUM *y, BN_CTX *ctx) +int ossl_ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, + BN_CTX *ctx) { int ret = 0; if (x == NULL || y == NULL) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, - ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } @@ -308,22 +317,20 @@ int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, * Gets the affine coordinates of an EC_POINT. Note that the simple * implementation only uses affine coordinates. */ -int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx) +int ossl_ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) { int ret = 0; if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, - EC_R_POINT_AT_INFINITY); + ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); return 0; } if (BN_cmp(point->Z, BN_value_one())) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (x != NULL) { @@ -346,12 +353,14 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, * Computes a + b and stores the result in r. r could be a or b, a could be * b. Uses algorithm A.10.2 of IEEE P1363. */ -int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *ctx) +int ossl_ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, + const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t; int ret = 0; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif if (EC_POINT_is_at_infinity(group, a)) { if (!EC_POINT_copy(r, b)) @@ -365,11 +374,13 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, return 1; } +#ifndef FIPS_MODULE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } +#endif BN_CTX_start(ctx); x0 = BN_CTX_get(ctx); @@ -453,7 +464,9 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, err: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } @@ -461,26 +474,28 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, * Computes 2 * a and stores the result in r. r could be a. Uses algorithm * A.10.2 of IEEE P1363. */ -int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - BN_CTX *ctx) +int ossl_ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, + const EC_POINT *a, BN_CTX *ctx) { - return ec_GF2m_simple_add(group, r, a, a, ctx); + return ossl_ec_GF2m_simple_add(group, r, a, a, ctx); } -int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) +int ossl_ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, + BN_CTX *ctx) { if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y)) /* point is its own inverse */ return 1; - if (!EC_POINT_make_affine(group, point, ctx)) + if (group->meth->make_affine == NULL + || !group->meth->make_affine(group, point, ctx)) return 0; return BN_GF2m_add(point->Y, point->X, point->Y); } /* Indicates whether the given point is the point at infinity. */ -int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, - const EC_POINT *point) +int ossl_ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, + const EC_POINT *point) { return BN_is_zero(point->Z); } @@ -490,15 +505,17 @@ int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation: * y^2 + x*y = x^3 + a*x^2 + b. */ -int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, - BN_CTX *ctx) +int ossl_ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) { int ret = -1; - BN_CTX *new_ctx = NULL; BIGNUM *lh, *y2; int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif if (EC_POINT_is_at_infinity(group, point)) return 1; @@ -510,11 +527,13 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, if (!point->Z_is_one) return -1; +#ifndef FIPS_MODULE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return -1; } +#endif BN_CTX_start(ctx); y2 = BN_CTX_get(ctx); @@ -546,7 +565,9 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, err: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } @@ -557,12 +578,14 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, * 0 equal (in affine coordinates) * 1 not equal */ -int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, - const EC_POINT *b, BN_CTX *ctx) +int ossl_ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) { BIGNUM *aX, *aY, *bX, *bY; - BN_CTX *new_ctx = NULL; int ret = -1; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif if (EC_POINT_is_at_infinity(group, a)) { return EC_POINT_is_at_infinity(group, b) ? 0 : 1; @@ -575,11 +598,13 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1; } +#ifndef FIPS_MODULE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return -1; } +#endif BN_CTX_start(ctx); aX = BN_CTX_get(ctx); @@ -597,26 +622,32 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, err: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } /* Forces the given EC_POINT to internally use affine coordinates. */ -int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, - BN_CTX *ctx) +int ossl_ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, + BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *x, *y; int ret = 0; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) return 1; +#ifndef FIPS_MODULE if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) return 0; } +#endif BN_CTX_start(ctx); x = BN_CTX_get(ctx); @@ -638,15 +669,17 @@ int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, err: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } /* * Forces each of the EC_POINTs in the given array to use affine coordinates. */ -int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, - EC_POINT *points[], BN_CTX *ctx) +int ossl_ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx) { size_t i; @@ -659,22 +692,22 @@ int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, } /* Wrapper to simple binary polynomial field multiplication implementation. */ -int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, - const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +int ossl_ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx); } /* Wrapper to simple binary polynomial field squaring implementation. */ -int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, - const BIGNUM *a, BN_CTX *ctx) +int ossl_ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) { return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx); } /* Wrapper to simple binary polynomial field division implementation. */ -int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, - const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +int ossl_ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { return BN_GF2m_mod_div(r, a, b, group->field, ctx); } @@ -696,9 +729,9 @@ int ec_GF2m_simple_ladder_pre(const EC_GROUP *group, /* s blinding: make sure lambda (s->Z here) is not zero */ do { - if (!BN_priv_rand(s->Z, BN_num_bits(group->field) - 1, - BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { - ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB); + if (!BN_priv_rand_ex(s->Z, BN_num_bits(group->field) - 1, + BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, 0, ctx)) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } } while (BN_is_zero(s->Z)); @@ -711,9 +744,9 @@ int ec_GF2m_simple_ladder_pre(const EC_GROUP *group, /* r blinding: make sure lambda (r->Y here for storage) is not zero */ do { - if (!BN_priv_rand(r->Y, BN_num_bits(group->field) - 1, - BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { - ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB); + if (!BN_priv_rand_ex(r->Y, BN_num_bits(group->field) - 1, + BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, 0, ctx)) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } } while (BN_is_zero(r->Y)); @@ -782,7 +815,7 @@ int ec_GF2m_simple_ladder_post(const EC_GROUP *group, if (BN_is_zero(s->Z)) { if (!EC_POINT_copy(r, p) || !EC_POINT_invert(group, r, ctx)) { - ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_POST, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); return 0; } return 1; @@ -793,7 +826,7 @@ int ec_GF2m_simple_ladder_post(const EC_GROUP *group, t1 = BN_CTX_get(ctx); t2 = BN_CTX_get(ctx); if (t2 == NULL) { - ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_POST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -856,15 +889,15 @@ int ec_GF2m_simple_points_mul(const EC_GROUP *group, EC_POINT *r, * order or cofactor set to 0. */ if (num > 1 || BN_is_zero(group->order) || BN_is_zero(group->cofactor)) - return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); + return ossl_ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); if (scalar != NULL && num == 0) /* Fixed point multiplication */ - return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx); + return ossl_ec_scalar_mul_ladder(group, r, scalar, NULL, ctx); if (scalar == NULL && num == 1) /* Variable point multiplication */ - return ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx); + return ossl_ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx); /*- * Double point multiplication: @@ -872,12 +905,12 @@ int ec_GF2m_simple_points_mul(const EC_GROUP *group, EC_POINT *r, */ if ((t = EC_POINT_new(group)) == NULL) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINTS_MUL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } - if (!ec_scalar_mul_ladder(group, t, scalar, NULL, ctx) - || !ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx) + if (!ossl_ec_scalar_mul_ladder(group, t, scalar, NULL, ctx) + || !ossl_ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx) || !EC_POINT_add(group, r, t, r, ctx)) goto err; @@ -899,7 +932,7 @@ static int ec_GF2m_simple_field_inv(const EC_GROUP *group, BIGNUM *r, int ret; if (!(ret = BN_GF2m_mod_inv(r, a, group->field, ctx))) - ECerr(EC_F_EC_GF2M_SIMPLE_FIELD_INV, EC_R_CANNOT_INVERT); + ERR_raise(ERR_LIB_EC, EC_R_CANNOT_INVERT); return ret; } @@ -908,54 +941,55 @@ const EC_METHOD *EC_GF2m_simple_method(void) static const EC_METHOD ret = { EC_FLAGS_DEFAULT_OCT, NID_X9_62_characteristic_two_field, - ec_GF2m_simple_group_init, - ec_GF2m_simple_group_finish, - ec_GF2m_simple_group_clear_finish, - ec_GF2m_simple_group_copy, - ec_GF2m_simple_group_set_curve, - ec_GF2m_simple_group_get_curve, - ec_GF2m_simple_group_get_degree, - ec_group_simple_order_bits, - ec_GF2m_simple_group_check_discriminant, - ec_GF2m_simple_point_init, - ec_GF2m_simple_point_finish, - ec_GF2m_simple_point_clear_finish, - ec_GF2m_simple_point_copy, - ec_GF2m_simple_point_set_to_infinity, - 0, /* set_Jprojective_coordinates_GFp */ - 0, /* get_Jprojective_coordinates_GFp */ - ec_GF2m_simple_point_set_affine_coordinates, - ec_GF2m_simple_point_get_affine_coordinates, + ossl_ec_GF2m_simple_group_init, + ossl_ec_GF2m_simple_group_finish, + ossl_ec_GF2m_simple_group_clear_finish, + ossl_ec_GF2m_simple_group_copy, + ossl_ec_GF2m_simple_group_set_curve, + ossl_ec_GF2m_simple_group_get_curve, + ossl_ec_GF2m_simple_group_get_degree, + ossl_ec_group_simple_order_bits, + ossl_ec_GF2m_simple_group_check_discriminant, + ossl_ec_GF2m_simple_point_init, + ossl_ec_GF2m_simple_point_finish, + ossl_ec_GF2m_simple_point_clear_finish, + ossl_ec_GF2m_simple_point_copy, + ossl_ec_GF2m_simple_point_set_to_infinity, + ossl_ec_GF2m_simple_point_set_affine_coordinates, + ossl_ec_GF2m_simple_point_get_affine_coordinates, 0, /* point_set_compressed_coordinates */ 0, /* point2oct */ 0, /* oct2point */ - ec_GF2m_simple_add, - ec_GF2m_simple_dbl, - ec_GF2m_simple_invert, - ec_GF2m_simple_is_at_infinity, - ec_GF2m_simple_is_on_curve, - ec_GF2m_simple_cmp, - ec_GF2m_simple_make_affine, - ec_GF2m_simple_points_make_affine, + ossl_ec_GF2m_simple_add, + ossl_ec_GF2m_simple_dbl, + ossl_ec_GF2m_simple_invert, + ossl_ec_GF2m_simple_is_at_infinity, + ossl_ec_GF2m_simple_is_on_curve, + ossl_ec_GF2m_simple_cmp, + ossl_ec_GF2m_simple_make_affine, + ossl_ec_GF2m_simple_points_make_affine, ec_GF2m_simple_points_mul, 0, /* precompute_mult */ 0, /* have_precompute_mult */ - ec_GF2m_simple_field_mul, - ec_GF2m_simple_field_sqr, - ec_GF2m_simple_field_div, + ossl_ec_GF2m_simple_field_mul, + ossl_ec_GF2m_simple_field_sqr, + ossl_ec_GF2m_simple_field_div, ec_GF2m_simple_field_inv, 0, /* field_encode */ 0, /* field_decode */ 0, /* field_set_to_one */ - ec_key_simple_priv2oct, - ec_key_simple_oct2priv, + ossl_ec_key_simple_priv2oct, + ossl_ec_key_simple_oct2priv, 0, /* set private */ - ec_key_simple_generate_key, - ec_key_simple_check_key, - ec_key_simple_generate_public_key, + ossl_ec_key_simple_generate_key, + ossl_ec_key_simple_check_key, + ossl_ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key, + ossl_ecdh_simple_compute_key, + ossl_ecdsa_simple_sign_setup, + ossl_ecdsa_simple_sign_sig, + ossl_ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ 0, /* blind_coordinates */ ec_GF2m_simple_ladder_pre, diff --git a/crypto/openssl/crypto/ec/ec_ameth.c b/crypto/openssl/crypto/ec/ec_ameth.c index 5098bd7a6602..d4348ff244c7 100644 --- a/crypto/openssl/crypto/ec/ec_ameth.c +++ b/crypto/openssl/crypto/ec/ec_ameth.c @@ -1,34 +1,38 @@ /* - * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDH and ECDSA low level APIs are deprecated for public use, but still ok + * for internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include #include #include -#include #include #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/x509.h" +#include +#include #include "ec_local.h" -#ifndef OPENSSL_NO_CMS -static int ecdh_cms_decrypt(CMS_RecipientInfo *ri); -static int ecdh_cms_encrypt(CMS_RecipientInfo *ri); -#endif - static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key) { const EC_GROUP *group; int nid; + if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { - ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); + ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS); return 0; } if (EC_GROUP_get_asn1_flag(group) @@ -38,8 +42,7 @@ static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key) ASN1_OBJECT *asn1obj = OBJ_nid2obj(nid); if (asn1obj == NULL || OBJ_length(asn1obj) == 0) { - ASN1_OBJECT_free(asn1obj); - ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_OID); + ERR_raise(ERR_LIB_EC, EC_R_MISSING_OID); return 0; } *ppval = asn1obj; @@ -50,20 +53,10 @@ static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key) pstr = ASN1_STRING_new(); if (pstr == NULL) return 0; - - /* - * The cast in the following line is intentional as the - * `i2d_ECParameters` signature can't be constified (see discussion at - * https://github.com/openssl/openssl/pull/9347 where related and - * required constification backports were rejected). - * - * This cast should be safe anyway, because we can expect - * `i2d_ECParameters()` to treat the first argument as if it was const. - */ - pstr->length = i2d_ECParameters((EC_KEY *)ec_key, &pstr->data); + pstr->length = i2d_ECParameters(ec_key, &pstr->data); if (pstr->length <= 0) { ASN1_STRING_free(pstr); - ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); return 0; } *ppval = pstr; @@ -81,7 +74,7 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) int penclen; if (!eckey_param2type(&ptype, &pval, ec_key)) { - ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); return 0; } penclen = i2o_ECPublicKey(ec_key, NULL); @@ -98,80 +91,32 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) ptype, pval, penc, penclen)) return 1; err: - if (ptype == V_ASN1_OBJECT) - ASN1_OBJECT_free(pval); - else + if (ptype == V_ASN1_SEQUENCE) ASN1_STRING_free(pval); OPENSSL_free(penc); return 0; } -static EC_KEY *eckey_type2param(int ptype, const void *pval) -{ - EC_KEY *eckey = NULL; - EC_GROUP *group = NULL; - - if (ptype == V_ASN1_SEQUENCE) { - const ASN1_STRING *pstr = pval; - const unsigned char *pm = pstr->data; - int pmlen = pstr->length; - - if ((eckey = d2i_ECParameters(NULL, &pm, pmlen)) == NULL) { - ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); - goto ecerr; - } - } else if (ptype == V_ASN1_OBJECT) { - const ASN1_OBJECT *poid = pval; - - /* - * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID - */ - if ((eckey = EC_KEY_new()) == NULL) { - ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); - goto ecerr; - } - group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); - if (group == NULL) - goto ecerr; - EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); - if (EC_KEY_set_group(eckey, group) == 0) - goto ecerr; - EC_GROUP_free(group); - } else { - ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); - goto ecerr; - } - - return eckey; - - ecerr: - EC_KEY_free(eckey); - EC_GROUP_free(group); - return NULL; -} - -static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) { const unsigned char *p = NULL; - const void *pval; - int ptype, pklen; + int pklen; EC_KEY *eckey = NULL; X509_ALGOR *palg; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; - if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + if (!ossl_x509_PUBKEY_get0_libctx(&libctx, &propq, pubkey) + || !X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) return 0; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - eckey = eckey_type2param(ptype, pval); + eckey = ossl_ec_key_param_from_x509_algor(palg, libctx, propq); - if (!eckey) { - ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); + if (!eckey) return 0; - } /* We have parameters now set public key */ if (!o2i_ECPublicKey(&eckey, &p, pklen)) { - ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR); + ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); goto ecerr; } @@ -189,6 +134,7 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec); + if (group == NULL || pa == NULL || pb == NULL) return -2; r = EC_POINT_cmp(group, pa, pb, NULL); @@ -199,49 +145,30 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) return -2; } -static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) +static int eckey_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8, + OSSL_LIB_CTX *libctx, const char *propq) { - const unsigned char *p = NULL; - const void *pval; - int ptype, pklen; - EC_KEY *eckey = NULL; - const X509_ALGOR *palg; - - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) - return 0; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - eckey = eckey_type2param(ptype, pval); - - if (!eckey) - goto ecliberr; + int ret = 0; + EC_KEY *eckey = ossl_ec_key_from_pkcs8(p8, libctx, propq); - /* We have parameters now set private key */ - if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { - ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); - goto ecerr; + if (eckey != NULL) { + ret = 1; + EVP_PKEY_assign_EC_KEY(pkey, eckey); } - EVP_PKEY_assign_EC_KEY(pkey, eckey); - return 1; - - ecliberr: - ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); - ecerr: - EC_KEY_free(eckey); - return 0; + return ret; } static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { EC_KEY ec_key = *(pkey->pkey.ec); - unsigned char *ep, *p; + unsigned char *ep = NULL; int eplen, ptype; void *pval; unsigned int old_flags; if (!eckey_param2type(&ptype, &pval, &ec_key)) { - ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); + ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); return 0; } @@ -254,30 +181,25 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) old_flags = EC_KEY_get_enc_flags(&ec_key); EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS); - eplen = i2d_ECPrivateKey(&ec_key, NULL); - if (!eplen) { - ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); - return 0; - } - ep = OPENSSL_malloc(eplen); - if (ep == NULL) { - ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); - return 0; - } - p = ep; - if (!i2d_ECPrivateKey(&ec_key, &p)) { - OPENSSL_free(ep); - ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); - return 0; + eplen = i2d_ECPrivateKey(&ec_key, &ep); + if (eplen <= 0) { + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); + goto err; } if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, ptype, pval, ep, eplen)) { - OPENSSL_free(ep); - return 0; + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); + OPENSSL_clear_free(ep, eplen); + goto err; } return 1; + + err: + if (ptype == V_ASN1_SEQUENCE) + ASN1_STRING_free(pval); + return 0; } static int int_ec_size(const EVP_PKEY *pkey) @@ -293,6 +215,7 @@ static int ec_bits(const EVP_PKEY *pkey) static int ec_security_bits(const EVP_PKEY *pkey) { int ecbits = ec_bits(pkey); + if (ecbits >= 512) return 256; if (ecbits >= 384) @@ -337,6 +260,7 @@ static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec); + if (group_a == NULL || group_b == NULL) return -2; if (EC_GROUP_cmp(group_a, group_b, NULL)) @@ -365,7 +289,7 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype) const EC_GROUP *group; if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { - ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } @@ -413,7 +337,7 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype) ret = 1; err: if (!ret) - ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); OPENSSL_clear_free(priv, privlen); OPENSSL_free(pub); return ret; @@ -424,10 +348,8 @@ static int eckey_param_decode(EVP_PKEY *pkey, { EC_KEY *eckey; - if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL) { - ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); + if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL) return 0; - } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; } @@ -460,10 +382,8 @@ static int old_ec_priv_decode(EVP_PKEY *pkey, { EC_KEY *ec; - if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL) { - ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); + if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL) return 0; - } EVP_PKEY_assign_EC_KEY(pkey, ec); return 1; } @@ -476,61 +396,20 @@ static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { - case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; - - case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (arg1 == 1) - return ecdh_cms_decrypt(arg2); - else if (arg1 == 0) - return ecdh_cms_encrypt(arg2); - return -2; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - *(int *)arg2 = CMS_RECIPINFO_AGREE; - return 1; -#endif - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) { + if (EVP_PKEY_get_id(pkey) == EVP_PKEY_SM2) { /* For SM2, the only valid digest-alg is SM3 */ *(int *)arg2 = NID_sm3; - } else { - *(int *)arg2 = NID_sha256; + return 2; /* Make it mandatory */ } + *(int *)arg2 = NID_sha256; return 1; case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: - return EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(pkey), arg2, arg1, NULL); + /* We should only be here if we have a legacy key */ + if (!ossl_assert(evp_pkey_is_legacy(pkey))) + return 0; + return EC_KEY_oct2key(evp_pkey_get0_EC_KEY_int(pkey), arg2, arg1, NULL); case ASN1_PKEY_CTRL_GET1_TLS_ENCPT: return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey), @@ -538,9 +417,7 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) default: return -2; - } - } static int ec_pkey_check(const EVP_PKEY *pkey) @@ -549,7 +426,7 @@ static int ec_pkey_check(const EVP_PKEY *pkey) /* stay consistent to what EVP_PKEY_check demands */ if (eckey->priv_key == NULL) { - ECerr(EC_F_EC_PKEY_CHECK, EC_R_MISSING_PRIVATE_KEY); + ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY); return 0; } @@ -578,14 +455,200 @@ static int ec_pkey_param_check(const EVP_PKEY *pkey) /* stay consistent to what EVP_PKEY_check demands */ if (eckey->group == NULL) { - ECerr(EC_F_EC_PKEY_PARAM_CHECK, EC_R_MISSING_PARAMETERS); + ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS); return 0; } return EC_GROUP_check(eckey->group, NULL); } -const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { +static +size_t ec_pkey_dirty_cnt(const EVP_PKEY *pkey) +{ + return pkey->pkey.ec->dirty_cnt; +} + +static +int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata, + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const EC_KEY *eckey = NULL; + const EC_GROUP *ecg = NULL; + unsigned char *pub_key_buf = NULL, *gen_buf = NULL; + size_t pub_key_buflen; + OSSL_PARAM_BLD *tmpl; + OSSL_PARAM *params = NULL; + const BIGNUM *priv_key = NULL; + const EC_POINT *pub_point = NULL; + int selection = 0; + int rv = 0; + BN_CTX *bnctx = NULL; + + if (from == NULL + || (eckey = from->pkey.ec) == NULL + || (ecg = EC_KEY_get0_group(eckey)) == NULL) + return 0; + + tmpl = OSSL_PARAM_BLD_new(); + if (tmpl == NULL) + return 0; + + /* + * EC_POINT_point2buf() can generate random numbers in some + * implementations so we need to ensure we use the correct libctx. + */ + bnctx = BN_CTX_new_ex(libctx); + if (bnctx == NULL) + goto err; + BN_CTX_start(bnctx); + + /* export the domain parameters */ + if (!ossl_ec_group_todata(ecg, tmpl, NULL, libctx, propq, bnctx, &gen_buf)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS; + + priv_key = EC_KEY_get0_private_key(eckey); + pub_point = EC_KEY_get0_public_key(eckey); + + if (pub_point != NULL) { + /* convert pub_point to a octet string according to the SECG standard */ + point_conversion_form_t format = EC_KEY_get_conv_form(eckey); + + if ((pub_key_buflen = EC_POINT_point2buf(ecg, pub_point, + format, + &pub_key_buf, bnctx)) == 0 + || !OSSL_PARAM_BLD_push_octet_string(tmpl, + OSSL_PKEY_PARAM_PUB_KEY, + pub_key_buf, + pub_key_buflen)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + } + + if (priv_key != NULL) { + size_t sz; + int ecbits; + int ecdh_cofactor_mode; + + /* + * Key import/export should never leak the bit length of the secret + * scalar in the key. + * + * For this reason, on export we use padded BIGNUMs with fixed length. + * + * When importing we also should make sure that, even if short lived, + * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as + * soon as possible, so that any processing of this BIGNUM might opt for + * constant time implementations in the backend. + * + * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have + * to preallocate the BIGNUM internal buffer to a fixed public size big + * enough that operations performed during the processing never trigger + * a realloc which would leak the size of the scalar through memory + * accesses. + * + * Fixed Length + * ------------ + * + * The order of the large prime subgroup of the curve is our choice for + * a fixed public size, as that is generally the upper bound for + * generating a private key in EC cryptosystems and should fit all valid + * secret scalars. + * + * For padding on export we just use the bit length of the order + * converted to bytes (rounding up). + * + * For preallocating the BIGNUM storage we look at the number of "words" + * required for the internal representation of the order, and we + * preallocate 2 extra "words" in case any of the subsequent processing + * might temporarily overflow the order length. + */ + ecbits = EC_GROUP_order_bits(ecg); + if (ecbits <= 0) + goto err; + + sz = (ecbits + 7 ) / 8; + if (!OSSL_PARAM_BLD_push_BN_pad(tmpl, + OSSL_PKEY_PARAM_PRIV_KEY, + priv_key, sz)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY; + + /* + * The ECDH Cofactor Mode is defined only if the EC_KEY actually + * contains a private key, so we check for the flag and export it only + * in this case. + */ + ecdh_cofactor_mode = + (EC_KEY_get_flags(eckey) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0; + + /* Export the ECDH_COFACTOR_MODE parameter */ + if (!OSSL_PARAM_BLD_push_int(tmpl, + OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, + ecdh_cofactor_mode)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS; + } + + params = OSSL_PARAM_BLD_to_param(tmpl); + + /* We export, the provider imports */ + rv = importer(to_keydata, selection, params); + + err: + OSSL_PARAM_BLD_free(tmpl); + OSSL_PARAM_free(params); + OPENSSL_free(pub_key_buf); + OPENSSL_free(gen_buf); + BN_CTX_end(bnctx); + BN_CTX_free(bnctx); + return rv; +} + +static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx) +{ + EVP_PKEY_CTX *pctx = vpctx; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); + EC_KEY *ec = EC_KEY_new_ex(pctx->libctx, pctx->propquery); + + if (ec == NULL) { + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!ossl_ec_group_fromdata(ec, params) + || !ossl_ec_key_otherparams_fromdata(ec, params) + || !ossl_ec_key_fromdata(ec, params, 1) + || !EVP_PKEY_assign_EC_KEY(pkey, ec)) { + EC_KEY_free(ec); + return 0; + } + return 1; +} + +static int ec_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) +{ + EC_KEY *eckey = from->pkey.ec; + EC_KEY *dupkey = NULL; + int ret; + + if (eckey != NULL) { + dupkey = EC_KEY_dup(eckey); + if (dupkey == NULL) + return 0; + } else { + /* necessary to properly copy empty SM2 keys */ + return EVP_PKEY_set_type(to, from->type); + } + + ret = EVP_PKEY_assign_EC_KEY(to, dupkey); + if (!ret) + EC_KEY_free(dupkey); + return ret; +} + +const EVP_PKEY_ASN1_METHOD ossl_eckey_asn1_meth = { EVP_PKEY_EC, EVP_PKEY_EC, 0, @@ -597,7 +660,7 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { eckey_pub_cmp, eckey_pub_print, - eckey_priv_decode, + NULL, eckey_priv_encode, eckey_priv_print, @@ -622,11 +685,22 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { ec_pkey_check, ec_pkey_public_check, - ec_pkey_param_check + ec_pkey_param_check, + + 0, /* set_priv_key */ + 0, /* set_pub_key */ + 0, /* get_priv_key */ + 0, /* get_pub_key */ + + ec_pkey_dirty_cnt, + ec_pkey_export_to, + ec_pkey_import_from, + ec_pkey_copy, + eckey_priv_decode_ex }; #if !defined(OPENSSL_NO_SM2) -const EVP_PKEY_ASN1_METHOD sm2_asn1_meth = { +const EVP_PKEY_ASN1_METHOD ossl_sm2_asn1_meth = { EVP_PKEY_SM2, EVP_PKEY_EC, ASN1_PKEY_ALIAS @@ -645,320 +719,3 @@ int ECParameters_print(BIO *bp, const EC_KEY *x) { return do_EC_KEY_print(bp, x, 4, EC_KEY_PRINT_PARAM); } - -#ifndef OPENSSL_NO_CMS - -static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, - X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) -{ - const ASN1_OBJECT *aoid; - int atype; - const void *aval; - int rv = 0; - EVP_PKEY *pkpeer = NULL; - EC_KEY *ecpeer = NULL; - const unsigned char *p; - int plen; - X509_ALGOR_get0(&aoid, &atype, &aval, alg); - if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) - goto err; - /* If absent parameters get group from main key */ - if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) { - const EC_GROUP *grp; - EVP_PKEY *pk; - pk = EVP_PKEY_CTX_get0_pkey(pctx); - if (!pk) - goto err; - grp = EC_KEY_get0_group(pk->pkey.ec); - ecpeer = EC_KEY_new(); - if (ecpeer == NULL) - goto err; - if (!EC_KEY_set_group(ecpeer, grp)) - goto err; - } else { - ecpeer = eckey_type2param(atype, aval); - if (!ecpeer) - goto err; - } - /* We have parameters now set public key */ - plen = ASN1_STRING_length(pubkey); - p = ASN1_STRING_get0_data(pubkey); - if (!p || !plen) - goto err; - if (!o2i_ECPublicKey(&ecpeer, &p, plen)) - goto err; - pkpeer = EVP_PKEY_new(); - if (pkpeer == NULL) - goto err; - EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer); - if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) - rv = 1; - err: - EC_KEY_free(ecpeer); - EVP_PKEY_free(pkpeer); - return rv; -} - -/* Set KDF parameters based on KDF NID */ -static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid) -{ - int kdf_nid, kdfmd_nid, cofactor; - const EVP_MD *kdf_md; - if (eckdf_nid == NID_undef) - return 0; - - /* Lookup KDF type, cofactor mode and digest */ - if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid)) - return 0; - - if (kdf_nid == NID_dh_std_kdf) - cofactor = 0; - else if (kdf_nid == NID_dh_cofactor_kdf) - cofactor = 1; - else - return 0; - - if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0) - return 0; - - if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0) - return 0; - - kdf_md = EVP_get_digestbynid(kdfmd_nid); - if (!kdf_md) - return 0; - - if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) - return 0; - return 1; -} - -static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) -{ - int rv = 0; - - X509_ALGOR *alg, *kekalg = NULL; - ASN1_OCTET_STRING *ukm; - const unsigned char *p; - unsigned char *der = NULL; - int plen, keylen; - const EVP_CIPHER *kekcipher; - EVP_CIPHER_CTX *kekctx; - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) - return 0; - - if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) { - ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR); - return 0; - } - - if (alg->parameter->type != V_ASN1_SEQUENCE) - return 0; - - p = alg->parameter->value.sequence->data; - plen = alg->parameter->value.sequence->length; - kekalg = d2i_X509_ALGOR(NULL, &p, plen); - if (!kekalg) - goto err; - kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); - if (!kekctx) - goto err; - kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); - if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) - goto err; - if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) - goto err; - if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) - goto err; - - keylen = EVP_CIPHER_CTX_key_length(kekctx); - if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) - goto err; - - plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen); - - if (!plen) - goto err; - - if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0) - goto err; - der = NULL; - - rv = 1; - err: - X509_ALGOR_free(kekalg); - OPENSSL_free(der); - return rv; -} - -static int ecdh_cms_decrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (!pctx) - return 0; - /* See if we need to set peer key */ - if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { - X509_ALGOR *alg; - ASN1_BIT_STRING *pubkey; - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, - NULL, NULL, NULL)) - return 0; - if (!alg || !pubkey) - return 0; - if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) { - ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR); - return 0; - } - } - /* Set ECDH derivation parameters and initialise unwrap context */ - if (!ecdh_cms_set_shared_info(pctx, ri)) { - ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR); - return 0; - } - return 1; -} - -static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - EVP_PKEY *pkey; - EVP_CIPHER_CTX *ctx; - int keylen; - X509_ALGOR *talg, *wrap_alg = NULL; - const ASN1_OBJECT *aoid; - ASN1_BIT_STRING *pubkey; - ASN1_STRING *wrap_str; - ASN1_OCTET_STRING *ukm; - unsigned char *penc = NULL; - int penclen; - int rv = 0; - int ecdh_nid, kdf_type, kdf_nid, wrap_nid; - const EVP_MD *kdf_md; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (!pctx) - return 0; - /* Get ephemeral key */ - pkey = EVP_PKEY_CTX_get0_pkey(pctx); - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, - NULL, NULL, NULL)) - goto err; - X509_ALGOR_get0(&aoid, NULL, NULL, talg); - /* Is everything uninitialised? */ - if (aoid == OBJ_nid2obj(NID_undef)) { - - EC_KEY *eckey = pkey->pkey.ec; - /* Set the key */ - unsigned char *p; - - penclen = i2o_ECPublicKey(eckey, NULL); - if (penclen <= 0) - goto err; - penc = OPENSSL_malloc(penclen); - if (penc == NULL) - goto err; - p = penc; - penclen = i2o_ECPublicKey(eckey, &p); - if (penclen <= 0) - goto err; - ASN1_STRING_set0(pubkey, penc, penclen); - pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; - - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), - V_ASN1_UNDEF, NULL); - } - - /* See if custom parameters set */ - kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx); - if (kdf_type <= 0) - goto err; - if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md)) - goto err; - ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx); - if (ecdh_nid < 0) - goto err; - else if (ecdh_nid == 0) - ecdh_nid = NID_dh_std_kdf; - else if (ecdh_nid == 1) - ecdh_nid = NID_dh_cofactor_kdf; - - if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) { - kdf_type = EVP_PKEY_ECDH_KDF_X9_63; - if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0) - goto err; - } else - /* Unknown KDF */ - goto err; - if (kdf_md == NULL) { - /* Fixme later for better MD */ - kdf_md = EVP_sha1(); - if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) - goto err; - } - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) - goto err; - - /* Lookup NID for KDF+cofactor+digest */ - - if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid)) - goto err; - /* Get wrap NID */ - ctx = CMS_RecipientInfo_kari_get0_ctx(ri); - wrap_nid = EVP_CIPHER_CTX_type(ctx); - keylen = EVP_CIPHER_CTX_key_length(ctx); - - /* Package wrap algorithm in an AlgorithmIdentifier */ - - wrap_alg = X509_ALGOR_new(); - if (wrap_alg == NULL) - goto err; - wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); - wrap_alg->parameter = ASN1_TYPE_new(); - if (wrap_alg->parameter == NULL) - goto err; - if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) - goto err; - if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { - ASN1_TYPE_free(wrap_alg->parameter); - wrap_alg->parameter = NULL; - } - - if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) - goto err; - - penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen); - - if (!penclen) - goto err; - - if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0) - goto err; - penc = NULL; - - /* - * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter - * of another AlgorithmIdentifier. - */ - penclen = i2d_X509_ALGOR(wrap_alg, &penc); - if (!penc || !penclen) - goto err; - wrap_str = ASN1_STRING_new(); - if (wrap_str == NULL) - goto err; - ASN1_STRING_set0(wrap_str, penc, penclen); - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str); - - rv = 1; - - err: - OPENSSL_free(penc); - X509_ALGOR_free(wrap_alg); - return rv; -} - -#endif diff --git a/crypto/openssl/crypto/ec/ec_asn1.c b/crypto/openssl/crypto/ec/ec_asn1.c index 1acbbde3d37b..7a0b35a59431 100644 --- a/crypto/openssl/crypto/ec/ec_asn1.c +++ b/crypto/openssl/crypto/ec/ec_asn1.c @@ -1,90 +1,27 @@ /* * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "ec_local.h" #include #include #include #include "internal/nelem.h" +#include "crypto/asn1_dsa.h" -int EC_GROUP_get_basis_type(const EC_GROUP *group) -{ - int i; - - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_characteristic_two_field) - /* everything else is currently not supported */ - return 0; - - /* Find the last non-zero element of group->poly[] */ - for (i = 0; - i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0; - i++) - continue; - - if (i == 4) - return NID_X9_62_ppBasis; - else if (i == 2) - return NID_X9_62_tpBasis; - else - /* everything else is currently not supported */ - return 0; -} - -#ifndef OPENSSL_NO_EC2M -int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) -{ - if (group == NULL) - return 0; - - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_characteristic_two_field - || !((group->poly[0] != 0) && (group->poly[1] != 0) - && (group->poly[2] == 0))) { - ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - - if (k) - *k = group->poly[1]; - - return 1; -} - -int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, - unsigned int *k2, unsigned int *k3) -{ - if (group == NULL) - return 0; - - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_characteristic_two_field - || !((group->poly[0] != 0) && (group->poly[1] != 0) - && (group->poly[2] != 0) && (group->poly[3] != 0) - && (group->poly[4] == 0))) { - ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - - if (k1) - *k1 = group->poly[3]; - if (k2) - *k2 = group->poly[2]; - if (k3) - *k3 = group->poly[1]; - - return 1; -} -#endif +#ifndef FIPS_MODULE /* some structures needed for the asn1 encoding */ typedef struct x9_62_pentanomial_st { @@ -223,9 +160,9 @@ ASN1_CHOICE(ECPKPARAMETERS) = { ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL) } ASN1_CHOICE_END(ECPKPARAMETERS) -DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS) -IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS) +DECLARE_ASN1_FUNCTIONS(ECPKPARAMETERS) +DECLARE_ASN1_ENCODE_FUNCTIONS_name(ECPKPARAMETERS, ECPKPARAMETERS) +IMPLEMENT_ASN1_FUNCTIONS(ECPKPARAMETERS) ASN1_SEQUENCE(EC_PRIVATEKEY) = { ASN1_EMBED(EC_PRIVATEKEY, version, INT32), @@ -234,9 +171,9 @@ ASN1_SEQUENCE(EC_PRIVATEKEY) = { ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1) } static_ASN1_SEQUENCE_END(EC_PRIVATEKEY) -DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY) -IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) +DECLARE_ASN1_FUNCTIONS(EC_PRIVATEKEY) +DECLARE_ASN1_ENCODE_FUNCTIONS_name(EC_PRIVATEKEY, EC_PRIVATEKEY) +IMPLEMENT_ASN1_FUNCTIONS(EC_PRIVATEKEY) /* some declarations of internal function */ @@ -259,33 +196,33 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) ASN1_OBJECT_free(field->fieldType); ASN1_TYPE_free(field->p.other); - nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + nid = EC_GROUP_get_field_type(group); /* set OID for the field */ if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_OBJ_LIB); goto err; } if (nid == NID_X9_62_prime_field) { if ((tmp = BN_new()) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } /* the parameters are specified by the prime number p */ if (!EC_GROUP_get_curve(group, tmp, NULL, NULL, NULL)) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } /* set the prime number */ field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL); if (field->p.prime == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } } else if (nid == NID_X9_62_characteristic_two_field) #ifdef OPENSSL_NO_EC2M { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); goto err; } #else @@ -297,7 +234,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) char_two = field->p.char_two; if (char_two == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -306,12 +243,12 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) field_type = EC_GROUP_get_basis_type(group); if (field_type == 0) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } /* set base type OID */ if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_OBJ_LIB); goto err; } @@ -323,11 +260,11 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) char_two->p.tpBasis = ASN1_INTEGER_new(); if (char_two->p.tpBasis == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } } else if (field_type == NID_X9_62_ppBasis) { @@ -338,7 +275,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) char_two->p.ppBasis = X9_62_PENTANOMIAL_new(); if (char_two->p.ppBasis == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -351,14 +288,14 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) /* for ONB the parameters are (asn1) NULL */ char_two->p.onBasis = ASN1_NULL_new(); if (char_two->p.onBasis == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } } } #endif else { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_UNSUPPORTED_FIELD); + ERR_raise(ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD); goto err; } @@ -380,13 +317,13 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) return 0; if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } /* get a and b */ if (!EC_GROUP_get_curve(group, NULL, tmp_1, tmp_2, NULL)) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -398,19 +335,19 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) len = ((size_t)EC_GROUP_get_degree(group) + 7) / 8; if ((a_buf = OPENSSL_malloc(len)) == NULL || (b_buf = OPENSSL_malloc(len)) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } if (BN_bn2binpad(tmp_1, a_buf, len) < 0 || BN_bn2binpad(tmp_2, b_buf, len) < 0) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* set a and b */ if (!ASN1_OCTET_STRING_set(curve->a, a_buf, len) || !ASN1_OCTET_STRING_set(curve->b, b_buf, len)) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } @@ -418,14 +355,14 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) if (group->seed) { if (!curve->seed) if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT; if (!ASN1_BIT_STRING_set(curve->seed, group->seed, (int)group->seed_len)) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } } else { @@ -444,7 +381,7 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) } ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, - ECPARAMETERS *params) + ECPARAMETERS *params) { size_t len = 0; ECPARAMETERS *ret = NULL; @@ -456,7 +393,7 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, if (params == NULL) { if ((ret = ECPARAMETERS_new()) == NULL) { - ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } } else @@ -467,19 +404,19 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, /* set the fieldID */ if (!ec_asn1_group2fieldid(group, ret->fieldID)) { - ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } /* set the curve */ if (!ec_asn1_group2curve(group, ret->curve)) { - ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } /* set the base point */ if ((point = EC_GROUP_get0_generator(group)) == NULL) { - ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, EC_R_UNDEFINED_GENERATOR); + ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR); goto err; } @@ -487,12 +424,12 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, len = EC_POINT_point2buf(group, point, form, &buffer, NULL); if (len == 0) { - ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { OPENSSL_free(buffer); - ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } ASN1_STRING_set0(ret->base, buffer, len); @@ -500,13 +437,13 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, /* set the order */ tmp = EC_GROUP_get0_order(group); if (tmp == NULL) { - ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } ret->order = BN_to_ASN1_INTEGER(tmp, orig = ret->order); if (ret->order == NULL) { ret->order = orig; - ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } @@ -516,7 +453,7 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, ret->cofactor = BN_to_ASN1_INTEGER(tmp, orig = ret->cofactor); if (ret->cofactor == NULL) { ret->cofactor = orig; - ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } } @@ -537,7 +474,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group, if (ret == NULL) { if ((ret = ECPKPARAMETERS_new()) == NULL) { - ECerr(EC_F_EC_GROUP_GET_ECPKPARAMETERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return NULL; } } else { @@ -558,7 +495,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group, if (asn1obj == NULL || OBJ_length(asn1obj) == 0) { ASN1_OBJECT_free(asn1obj); - ECerr(EC_F_EC_GROUP_GET_ECPKPARAMETERS, EC_R_MISSING_OID); + ERR_raise(ERR_LIB_EC, EC_R_MISSING_OID); ok = 0; } else { ret->type = ECPKPARAMETERS_TYPE_NAMED; @@ -592,9 +529,10 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) int curve_name = NID_undef; BN_CTX *ctx = NULL; - if (!params->fieldID || !params->fieldID->fieldType || - !params->fieldID->p.ptr) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR); + if (params->fieldID == NULL + || params->fieldID->fieldType == NULL + || params->fieldID->p.ptr == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); goto err; } @@ -604,20 +542,20 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) * encoded them incorrectly, so we must accept any length for backwards * compatibility. */ - if (!params->curve || !params->curve->a || - !params->curve->a->data || !params->curve->b || - !params->curve->b->data) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR); + if (params->curve == NULL + || params->curve->a == NULL || params->curve->a->data == NULL + || params->curve->b == NULL || params->curve->b->data == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); goto err; } a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); if (a == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); if (b == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -626,7 +564,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) if (tmp == NID_X9_62_characteristic_two_field) #ifdef OPENSSL_NO_EC2M { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_GF2M_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); goto err; } #else @@ -637,12 +575,12 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) field_bits = char_two->m; if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_FIELD_TOO_LARGE); + ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE); goto err; } if ((p = BN_new()) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -653,15 +591,14 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) long tmp_long; if (!char_two->p.tpBasis) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR); + ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); goto err; } tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis); if (!(char_two->m > tmp_long && tmp_long > 0)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, - EC_R_INVALID_TRINOMIAL_BASIS); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_TRINOMIAL_BASIS); goto err; } @@ -676,16 +613,15 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) X9_62_PENTANOMIAL *penta; penta = char_two->p.ppBasis; - if (!penta) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR); + if (penta == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); goto err; } if (! (char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, - EC_R_INVALID_PENTANOMIAL_BASIS); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_PENTANOMIAL_BASIS); goto err; } @@ -701,11 +637,11 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) if (!BN_set_bit(p, 0)) goto err; } else if (tmp == NID_X9_62_onBasis) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_NOT_IMPLEMENTED); + ERR_raise(ERR_LIB_EC, EC_R_NOT_IMPLEMENTED); goto err; } else { /* error */ - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR); + ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); goto err; } @@ -716,36 +652,36 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) else if (tmp == NID_X9_62_prime_field) { /* we have a curve over a prime field */ /* extract the prime number */ - if (!params->fieldID->p.prime) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR); + if (params->fieldID->p.prime == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); goto err; } p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); if (p == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } if (BN_is_negative(p) || BN_is_zero(p)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_FIELD); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); goto err; } field_bits = BN_num_bits(p); if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_FIELD_TOO_LARGE); + ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE); goto err; } /* create the EC_GROUP structure */ ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); } else { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_FIELD); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); goto err; } if (ret == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -758,12 +694,12 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) * zero length allocation request. */ if (params->curve->seed->length == 0) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR); + ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); goto err; } OPENSSL_free(ret->seed); if ((ret->seed = OPENSSL_malloc(params->curve->seed->length)) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } memcpy(ret->seed, params->curve->seed->data, @@ -775,7 +711,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) || params->base == NULL || params->base->data == NULL || params->base->length == 0) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR); + ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); goto err; } @@ -789,21 +725,21 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) /* extract the ec point */ if (!EC_POINT_oct2point(ret, point, params->base->data, params->base->length, NULL)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } /* extract the order */ if (ASN1_INTEGER_to_BN(params->order, a) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } if (BN_is_negative(a) || BN_is_zero(a)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_GROUP_ORDER); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); goto err; } if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */ - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_GROUP_ORDER); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); goto err; } @@ -812,12 +748,12 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) BN_free(b); b = NULL; } else if (ASN1_INTEGER_to_BN(params->cofactor, b) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } /* set the generator, order and cofactor (if present) */ if (!EC_GROUP_set_generator(ret, point, a, b)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -834,16 +770,16 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) * 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); + ERR_raise(ERR_LIB_EC, 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); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } - if ((curve_name = ec_curve_nid_from_params(dup, ctx)) != NID_undef) { + if ((curve_name = ossl_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 @@ -865,7 +801,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) #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); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } EC_GROUP_free(ret); @@ -917,7 +853,7 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params) int tmp = 0; if (params == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_MISSING_PARAMETERS); + ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS); return NULL; } @@ -925,8 +861,7 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params) /* the curve is given by an OID */ tmp = OBJ_obj2nid(params->value.named_curve); if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, - EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); + ERR_raise(ERR_LIB_EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); return NULL; } EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); @@ -934,7 +869,7 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params) /* the parameters are given by an ECPARAMETERS structure */ ret = EC_GROUP_new_from_ecparameters(params->value.parameters); if (!ret) { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); return NULL; } EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE); @@ -942,7 +877,7 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params) /* implicit parameters inherited from CA - unsupported */ return NULL; } else { - ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_ASN1_ERROR); + ERR_raise(ERR_LIB_EC, EC_R_ASN1_ERROR); return NULL; } @@ -958,13 +893,11 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) const unsigned char *p = *in; if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) { - ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE); ECPKPARAMETERS_free(params); return NULL; } if ((group = EC_GROUP_new_from_ecpkparameters(params)) == NULL) { - ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE); ECPKPARAMETERS_free(params); return NULL; } @@ -987,11 +920,11 @@ int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) int ret = 0; ECPKPARAMETERS *tmp = EC_GROUP_get_ecpkparameters(a, NULL); if (tmp == NULL) { - ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE); + ERR_raise(ERR_LIB_EC, EC_R_GROUP2PKPARAMETERS_FAILURE); return 0; } if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) { - ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE); + ERR_raise(ERR_LIB_EC, EC_R_I2D_ECPKPARAMETERS_FAILURE); ECPKPARAMETERS_free(tmp); return 0; } @@ -1007,14 +940,12 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) EC_PRIVATEKEY *priv_key = NULL; const unsigned char *p = *in; - if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) return NULL; - } if (a == NULL || *a == NULL) { if ((ret = EC_KEY_new()) == NULL) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } } else @@ -1029,7 +960,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) } if (ret->group == NULL) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -1041,14 +972,17 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) ASN1_STRING_length(pkey)) == 0) goto err; } else { - ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY); + ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY); goto err; } + if (EC_GROUP_get_curve_name(ret->group) == NID_sm2) + EC_KEY_set_flags(ret, EC_FLAG_SM2_RANGE); + EC_POINT_clear_free(ret->pub_key); ret->pub_key = EC_POINT_new(ret->group); if (ret->pub_key == NULL) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -1059,7 +993,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) pub_oct = ASN1_STRING_get0_data(priv_key->publicKey); pub_oct_len = ASN1_STRING_length(priv_key->publicKey); if (!EC_KEY_oct2key(ret, pub_oct, pub_oct_len, NULL)) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } } else { @@ -1074,6 +1008,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) *a = ret; EC_PRIVATEKEY_free(priv_key); *in = p; + ret->dirty_cnt++; return ret; err: @@ -1083,7 +1018,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) return NULL; } -int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) +int i2d_ECPrivateKey(const EC_KEY *a, unsigned char **out) { int ret = 0, ok = 0; unsigned char *priv= NULL, *pub= NULL; @@ -1093,12 +1028,12 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) if (a == NULL || a->group == NULL || (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); goto err; } if ((priv_key = EC_PRIVATEKEY_new()) == NULL) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -1107,7 +1042,7 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) privlen = EC_KEY_priv2buf(a, &priv); if (privlen == 0) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -1118,7 +1053,7 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) if ((priv_key->parameters = EC_GROUP_get_ecpkparameters(a->group, priv_key->parameters)) == NULL) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } } @@ -1126,14 +1061,14 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) { priv_key->publicKey = ASN1_BIT_STRING_new(); if (priv_key->publicKey == NULL) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } publen = EC_KEY_key2buf(a, a->conv_form, &pub, NULL); if (publen == 0) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -1144,7 +1079,7 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) } if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } ok = 1; @@ -1155,10 +1090,10 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) return (ok ? ret : 0); } -int i2d_ECParameters(EC_KEY *a, unsigned char **out) +int i2d_ECParameters(const EC_KEY *a, unsigned char **out) { if (a == NULL) { - ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } return i2d_ECPKParameters(a->group, out); @@ -1169,25 +1104,31 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) EC_KEY *ret; if (in == NULL || *in == NULL) { - ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (a == NULL || *a == NULL) { if ((ret = EC_KEY_new()) == NULL) { - ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return NULL; } } else ret = *a; if (!d2i_ECPKParameters(&ret->group, in, len)) { - ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB); if (a == NULL || *a != ret) EC_KEY_free(ret); + else + ret->dirty_cnt++; return NULL; } + if (EC_GROUP_get_curve_name(ret->group) == NID_sm2) + EC_KEY_set_flags(ret, EC_FLAG_SM2_RANGE); + + ret->dirty_cnt++; + if (a) *a = ret; @@ -1202,12 +1143,13 @@ EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) /* * sorry, but a EC_GROUP-structure is necessary to set the public key */ - ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } ret = *a; + /* EC_KEY_opt2key updates dirty_cnt */ if (!EC_KEY_oct2key(ret, *in, len, NULL)) { - ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); return 0; } *in += len; @@ -1220,7 +1162,7 @@ int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out) int new_buffer = 0; if (a == NULL) { - ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } @@ -1233,14 +1175,14 @@ int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out) if (*out == NULL) { if ((*out = OPENSSL_malloc(buf_len)) == NULL) { - ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } new_buffer = 1; } if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, *out, buf_len, NULL)) { - ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); if (new_buffer) { OPENSSL_free(*out); *out = NULL; @@ -1252,20 +1194,16 @@ int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out) return buf_len; } -ASN1_SEQUENCE(ECDSA_SIG) = { - ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM), - ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM) -} static_ASN1_SEQUENCE_END(ECDSA_SIG) +DECLARE_ASN1_FUNCTIONS(ECDSA_SIG) +DECLARE_ASN1_ENCODE_FUNCTIONS_name(ECDSA_SIG, ECDSA_SIG) -DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ECDSA_SIG, ECDSA_SIG, ECDSA_SIG) +#endif /* FIPS_MODULE */ ECDSA_SIG *ECDSA_SIG_new(void) { ECDSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); if (sig == NULL) - ECerr(EC_F_ECDSA_SIG_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return sig; } @@ -1278,6 +1216,75 @@ void ECDSA_SIG_free(ECDSA_SIG *sig) OPENSSL_free(sig); } +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **psig, const unsigned char **ppin, long len) +{ + ECDSA_SIG *sig; + + if (len < 0) + return NULL; + if (psig != NULL && *psig != NULL) { + sig = *psig; + } else { + sig = ECDSA_SIG_new(); + if (sig == NULL) + return NULL; + } + if (sig->r == NULL) + sig->r = BN_new(); + if (sig->s == NULL) + sig->s = BN_new(); + if (sig->r == NULL || sig->s == NULL + || ossl_decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { + if (psig == NULL || *psig == NULL) + ECDSA_SIG_free(sig); + return NULL; + } + if (psig != NULL && *psig == NULL) + *psig = sig; + return sig; +} + +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **ppout) +{ + BUF_MEM *buf = NULL; + size_t encoded_len; + WPACKET pkt; + + if (ppout == NULL) { + if (!WPACKET_init_null(&pkt, 0)) + return -1; + } else if (*ppout == NULL) { + if ((buf = BUF_MEM_new()) == NULL + || !WPACKET_init_len(&pkt, buf, 0)) { + BUF_MEM_free(buf); + return -1; + } + } else { + if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0)) + return -1; + } + + if (!ossl_encode_der_dsa_sig(&pkt, sig->r, sig->s) + || !WPACKET_get_total_written(&pkt, &encoded_len) + || !WPACKET_finish(&pkt)) { + BUF_MEM_free(buf); + WPACKET_cleanup(&pkt); + return -1; + } + + if (ppout != NULL) { + if (*ppout == NULL) { + *ppout = (unsigned char *)buf->data; + buf->data = NULL; + BUF_MEM_free(buf); + } else { + *ppout += encoded_len; + } + } + + return (int)encoded_len; +} + void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) { if (pr != NULL) @@ -1307,32 +1314,27 @@ int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) return 1; } -int ECDSA_size(const EC_KEY *r) +int ECDSA_size(const EC_KEY *ec) { - int ret, i; - ASN1_INTEGER bs; - unsigned char buf[4]; + int ret; + ECDSA_SIG sig; const EC_GROUP *group; + const BIGNUM *bn; - if (r == NULL) + if (ec == NULL) return 0; - group = EC_KEY_get0_group(r); + group = EC_KEY_get0_group(ec); if (group == NULL) return 0; - i = EC_GROUP_order_bits(group); - if (i == 0) + bn = EC_GROUP_get0_order(group); + if (bn == NULL) return 0; - bs.length = (i + 7) / 8; - bs.data = buf; - bs.type = V_ASN1_INTEGER; - /* If the top bit is set the asn1 encoding is 1 larger. */ - buf[0] = 0xff; - - i = i2d_ASN1_INTEGER(&bs, NULL); - i += i; /* r and s */ - ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); + + sig.r = sig.s = (BIGNUM *)bn; + ret = i2d_ECDSA_SIG(&sig, NULL); + if (ret < 0) - return 0; + ret = 0; return ret; } diff --git a/crypto/openssl/crypto/ec/ec_backend.c b/crypto/openssl/crypto/ec/ec_backend.c new file mode 100644 index 000000000000..98e2c418e416 --- /dev/null +++ b/crypto/openssl/crypto/ec/ec_backend.c @@ -0,0 +1,842 @@ +/* + * Copyright 2020-2022 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 + */ + +/* + * Low level APIs related to EC_KEY are deprecated for public use, + * but still ok for internal use. + */ +#include "internal/deprecated.h" + +#include +#include +#include +#include +#ifndef FIPS_MODULE +# include +# include +#endif +#include "crypto/bn.h" +#include "crypto/ec.h" +#include "ec_local.h" +#include "e_os.h" +#include "internal/param_build_set.h" + +/* Mapping between a flag and a name */ +static const OSSL_ITEM encoding_nameid_map[] = { + { OPENSSL_EC_EXPLICIT_CURVE, OSSL_PKEY_EC_ENCODING_EXPLICIT }, + { OPENSSL_EC_NAMED_CURVE, OSSL_PKEY_EC_ENCODING_GROUP }, +}; + +static const OSSL_ITEM check_group_type_nameid_map[] = { + { 0, OSSL_PKEY_EC_GROUP_CHECK_DEFAULT }, + { EC_FLAG_CHECK_NAMED_GROUP, OSSL_PKEY_EC_GROUP_CHECK_NAMED }, + { EC_FLAG_CHECK_NAMED_GROUP_NIST, OSSL_PKEY_EC_GROUP_CHECK_NAMED_NIST }, +}; + +static const OSSL_ITEM format_nameid_map[] = { + { (int)POINT_CONVERSION_UNCOMPRESSED, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_UNCOMPRESSED }, + { (int)POINT_CONVERSION_COMPRESSED, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED }, + { (int)POINT_CONVERSION_HYBRID, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_HYBRID }, +}; + +int ossl_ec_encoding_name2id(const char *name) +{ + size_t i, sz; + + /* Return the default value if there is no name */ + if (name == NULL) + return OPENSSL_EC_NAMED_CURVE; + + for (i = 0, sz = OSSL_NELEM(encoding_nameid_map); i < sz; i++) { + if (OPENSSL_strcasecmp(name, encoding_nameid_map[i].ptr) == 0) + return encoding_nameid_map[i].id; + } + return -1; +} + +static char *ec_param_encoding_id2name(int id) +{ + size_t i, sz; + + for (i = 0, sz = OSSL_NELEM(encoding_nameid_map); i < sz; i++) { + if (id == (int)encoding_nameid_map[i].id) + return encoding_nameid_map[i].ptr; + } + return NULL; +} + +char *ossl_ec_check_group_type_id2name(int id) +{ + size_t i, sz; + + for (i = 0, sz = OSSL_NELEM(check_group_type_nameid_map); i < sz; i++) { + if (id == (int)check_group_type_nameid_map[i].id) + return check_group_type_nameid_map[i].ptr; + } + return NULL; +} + +static int ec_check_group_type_name2id(const char *name) +{ + size_t i, sz; + + /* Return the default value if there is no name */ + if (name == NULL) + return 0; + + for (i = 0, sz = OSSL_NELEM(check_group_type_nameid_map); i < sz; i++) { + if (OPENSSL_strcasecmp(name, check_group_type_nameid_map[i].ptr) == 0) + return check_group_type_nameid_map[i].id; + } + return -1; +} + +int ossl_ec_set_check_group_type_from_name(EC_KEY *ec, const char *name) +{ + int flags = ec_check_group_type_name2id(name); + + if (flags == -1) + return 0; + EC_KEY_clear_flags(ec, EC_FLAG_CHECK_NAMED_GROUP_MASK); + EC_KEY_set_flags(ec, flags); + return 1; +} + +static int ec_set_check_group_type_from_param(EC_KEY *ec, const OSSL_PARAM *p) +{ + const char *name = NULL; + int status = 0; + + switch (p->data_type) { + case OSSL_PARAM_UTF8_STRING: + name = p->data; + status = (name != NULL); + break; + case OSSL_PARAM_UTF8_PTR: + status = OSSL_PARAM_get_utf8_ptr(p, &name); + break; + } + if (status) + return ossl_ec_set_check_group_type_from_name(ec, name); + return 0; +} + +int ossl_ec_pt_format_name2id(const char *name) +{ + size_t i, sz; + + /* Return the default value if there is no name */ + if (name == NULL) + return (int)POINT_CONVERSION_UNCOMPRESSED; + + for (i = 0, sz = OSSL_NELEM(format_nameid_map); i < sz; i++) { + if (OPENSSL_strcasecmp(name, format_nameid_map[i].ptr) == 0) + return format_nameid_map[i].id; + } + return -1; +} + +char *ossl_ec_pt_format_id2name(int id) +{ + size_t i, sz; + + for (i = 0, sz = OSSL_NELEM(format_nameid_map); i < sz; i++) { + if (id == (int)format_nameid_map[i].id) + return format_nameid_map[i].ptr; + } + return NULL; +} + +static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, + OSSL_PARAM params[], BN_CTX *bnctx, + unsigned char **genbuf) +{ + int ret = 0, fid; + const char *field_type; + const OSSL_PARAM *param = NULL; + const OSSL_PARAM *param_p = NULL; + const OSSL_PARAM *param_a = NULL; + const OSSL_PARAM *param_b = NULL; + + fid = EC_GROUP_get_field_type(group); + + if (fid == NID_X9_62_prime_field) { + field_type = SN_X9_62_prime_field; + } else if (fid == NID_X9_62_characteristic_two_field) { +#ifdef OPENSSL_NO_EC2M + ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); + goto err; +#else + field_type = SN_X9_62_characteristic_two_field; +#endif + } else { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); + return 0; + } + + param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_P); + param_a = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_A); + param_b = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_B); + if (tmpl != NULL || param_p != NULL || param_a != NULL || param_b != NULL) + { + BIGNUM *p = BN_CTX_get(bnctx); + BIGNUM *a = BN_CTX_get(bnctx); + BIGNUM *b = BN_CTX_get(bnctx); + + if (b == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_GROUP_get_curve(group, p, a, b, bnctx)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); + goto err; + } + if (!ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_P, p) + || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_A, a) + || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_B, b)) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ORDER); + if (tmpl != NULL || param != NULL) { + const BIGNUM *order = EC_GROUP_get0_order(group); + + if (order == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); + goto err; + } + if (!ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_ORDER, + order)) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE); + if (tmpl != NULL || param != NULL) { + if (!ossl_param_build_set_utf8_string(tmpl, params, + OSSL_PKEY_PARAM_EC_FIELD_TYPE, + field_type)) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GENERATOR); + if (tmpl != NULL || param != NULL) { + size_t genbuf_len; + const EC_POINT *genpt = EC_GROUP_get0_generator(group); + point_conversion_form_t genform = EC_GROUP_get_point_conversion_form(group); + + if (genpt == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); + goto err; + } + genbuf_len = EC_POINT_point2buf(group, genpt, genform, genbuf, bnctx); + if (genbuf_len == 0) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); + goto err; + } + if (!ossl_param_build_set_octet_string(tmpl, params, + OSSL_PKEY_PARAM_EC_GENERATOR, + *genbuf, genbuf_len)) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_COFACTOR); + if (tmpl != NULL || param != NULL) { + const BIGNUM *cofactor = EC_GROUP_get0_cofactor(group); + + if (cofactor != NULL + && !ossl_param_build_set_bn(tmpl, params, + OSSL_PKEY_PARAM_EC_COFACTOR, cofactor)) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED); + if (tmpl != NULL || param != NULL) { + unsigned char *seed = EC_GROUP_get0_seed(group); + size_t seed_len = EC_GROUP_get_seed_len(group); + + if (seed != NULL + && seed_len > 0 + && !ossl_param_build_set_octet_string(tmpl, params, + OSSL_PKEY_PARAM_EC_SEED, + seed, seed_len)) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + } + ret = 1; +err: + return ret; +} + +int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, + OSSL_PARAM params[], OSSL_LIB_CTX *libctx, + const char *propq, + BN_CTX *bnctx, unsigned char **genbuf) +{ + int ret = 0, curve_nid, encoding_flag; + const char *encoding_name, *pt_form_name; + point_conversion_form_t genform; + + if (group == NULL) { + ERR_raise(ERR_LIB_EC,EC_R_PASSED_NULL_PARAMETER); + return 0; + } + + genform = EC_GROUP_get_point_conversion_form(group); + pt_form_name = ossl_ec_pt_format_id2name(genform); + if (pt_form_name == NULL + || !ossl_param_build_set_utf8_string( + tmpl, params, + OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, pt_form_name)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM); + return 0; + } + encoding_flag = EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE; + encoding_name = ec_param_encoding_id2name(encoding_flag); + if (encoding_name == NULL + || !ossl_param_build_set_utf8_string(tmpl, params, + OSSL_PKEY_PARAM_EC_ENCODING, + encoding_name)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); + return 0; + } + + if (!ossl_param_build_set_int(tmpl, params, + OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, + group->decoded_from_explicit_params)) + return 0; + + curve_nid = EC_GROUP_get_curve_name(group); + + /* + * Get the explicit parameters in these two cases: + * - We do not have a template, i.e. specific parameters are requested + * - The curve is not a named curve + */ + if (tmpl == NULL || curve_nid == NID_undef) + if (!ec_group_explicit_todata(group, tmpl, params, bnctx, genbuf)) + goto err; + + if (curve_nid != NID_undef) { + /* Named curve */ + const char *curve_name = OSSL_EC_curve_nid2name(curve_nid); + + if (curve_name == NULL + || !ossl_param_build_set_utf8_string(tmpl, params, + OSSL_PKEY_PARAM_GROUP_NAME, + curve_name)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); + goto err; + } + } + ret = 1; +err: + return ret; +} + +/* + * The intention with the "backend" source file is to offer backend support + * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider + * implementations alike. + */ +int ossl_ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode) +{ + const EC_GROUP *ecg = EC_KEY_get0_group(ec); + const BIGNUM *cofactor; + /* + * mode can be only 0 for disable, or 1 for enable here. + * + * This is in contrast with the same parameter on an ECDH EVP_PKEY_CTX that + * also supports mode == -1 with the meaning of "reset to the default for + * the associated key". + */ + if (mode < 0 || mode > 1) + return 0; + + if ((cofactor = EC_GROUP_get0_cofactor(ecg)) == NULL ) + return 0; + + /* ECDH cofactor mode has no effect if cofactor is 1 */ + if (BN_is_one(cofactor)) + return 1; + + if (mode == 1) + EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH); + else if (mode == 0) + EC_KEY_clear_flags(ec, EC_FLAG_COFACTOR_ECDH); + + return 1; +} + +/* + * Callers of ossl_ec_key_fromdata MUST make sure that ec_key_params_fromdata has + * been called before! + * + * This function only gets the bare keypair, domain parameters and other + * parameters are treated separately, and domain parameters are required to + * define a keypair. + */ +int ossl_ec_key_fromdata(EC_KEY *ec, const OSSL_PARAM params[], int include_private) +{ + const OSSL_PARAM *param_priv_key = NULL, *param_pub_key = NULL; + BN_CTX *ctx = NULL; + BIGNUM *priv_key = NULL; + unsigned char *pub_key = NULL; + size_t pub_key_len; + const EC_GROUP *ecg = NULL; + EC_POINT *pub_point = NULL; + int ok = 0; + + ecg = EC_KEY_get0_group(ec); + if (ecg == NULL) + return 0; + + param_pub_key = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); + if (include_private) + param_priv_key = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); + + ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec)); + if (ctx == NULL) + goto err; + + if (param_pub_key != NULL) + if (!OSSL_PARAM_get_octet_string(param_pub_key, + (void **)&pub_key, 0, &pub_key_len) + || (pub_point = EC_POINT_new(ecg)) == NULL + || !EC_POINT_oct2point(ecg, pub_point, pub_key, pub_key_len, ctx)) + goto err; + + if (param_priv_key != NULL && include_private) { + int fixed_words; + const BIGNUM *order; + + /* + * Key import/export should never leak the bit length of the secret + * scalar in the key. + * + * For this reason, on export we use padded BIGNUMs with fixed length. + * + * When importing we also should make sure that, even if short lived, + * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as + * soon as possible, so that any processing of this BIGNUM might opt for + * constant time implementations in the backend. + * + * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have + * to preallocate the BIGNUM internal buffer to a fixed public size big + * enough that operations performed during the processing never trigger + * a realloc which would leak the size of the scalar through memory + * accesses. + * + * Fixed Length + * ------------ + * + * The order of the large prime subgroup of the curve is our choice for + * a fixed public size, as that is generally the upper bound for + * generating a private key in EC cryptosystems and should fit all valid + * secret scalars. + * + * For padding on export we just use the bit length of the order + * converted to bytes (rounding up). + * + * For preallocating the BIGNUM storage we look at the number of "words" + * required for the internal representation of the order, and we + * preallocate 2 extra "words" in case any of the subsequent processing + * might temporarily overflow the order length. + */ + order = EC_GROUP_get0_order(ecg); + if (order == NULL || BN_is_zero(order)) + goto err; + + fixed_words = bn_get_top(order) + 2; + + if ((priv_key = BN_secure_new()) == NULL) + goto err; + if (bn_wexpand(priv_key, fixed_words) == NULL) + goto err; + BN_set_flags(priv_key, BN_FLG_CONSTTIME); + + if (!OSSL_PARAM_get_BN(param_priv_key, &priv_key)) + goto err; + } + + if (priv_key != NULL + && !EC_KEY_set_private_key(ec, priv_key)) + goto err; + + if (pub_point != NULL + && !EC_KEY_set_public_key(ec, pub_point)) + goto err; + + ok = 1; + + err: + BN_CTX_free(ctx); + BN_clear_free(priv_key); + OPENSSL_free(pub_key); + EC_POINT_free(pub_point); + return ok; +} + +int ossl_ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +{ + int ok = 0; + EC_GROUP *group = NULL; + + if (ec == NULL) + return 0; + + group = EC_GROUP_new_from_params(params, ossl_ec_key_get_libctx(ec), + ossl_ec_key_get0_propq(ec)); + + if (!EC_KEY_set_group(ec, group)) + goto err; + ok = 1; +err: + EC_GROUP_free(group); + return ok; +} + +static int ec_key_point_format_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + int format = -1; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT); + if (p != NULL) { + if (!ossl_ec_pt_format_param2id(p, &format)) { + ECerr(0, EC_R_INVALID_FORM); + return 0; + } + EC_KEY_set_conv_form(ec, format); + } + return 1; +} + +static int ec_key_group_check_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE); + if (p != NULL) + return ec_set_check_group_type_from_param(ec, p); + return 1; +} + +static int ec_set_include_public(EC_KEY *ec, int include) +{ + int flags = EC_KEY_get_enc_flags(ec); + + if (!include) + flags |= EC_PKEY_NO_PUBKEY; + else + flags &= ~EC_PKEY_NO_PUBKEY; + EC_KEY_set_enc_flags(ec, flags); + return 1; +} + +int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + + if (ec == NULL) + return 0; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH); + if (p != NULL) { + int mode; + + if (!OSSL_PARAM_get_int(p, &mode) + || !ossl_ec_set_ecdh_cofactor_mode(ec, mode)) + return 0; + } + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC); + if (p != NULL) { + int include = 1; + + if (!OSSL_PARAM_get_int(p, &include) + || !ec_set_include_public(ec, include)) + return 0; + } + if (!ec_key_point_format_fromdata(ec, params)) + return 0; + if (!ec_key_group_check_fromdata(ec, params)) + return 0; + return 1; +} + +int ossl_ec_key_is_foreign(const EC_KEY *ec) +{ +#ifndef FIPS_MODULE + if (ec->engine != NULL || EC_KEY_get_method(ec) != EC_KEY_OpenSSL()) + return 1; +#endif + return 0; + +} + +EC_KEY *ossl_ec_key_dup(const EC_KEY *src, int selection) +{ + EC_KEY *ret; + + if (src == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if ((ret = ossl_ec_key_new_method_int(src->libctx, src->propq, + src->engine)) == NULL) + return NULL; + + /* copy the parameters */ + if (src->group != NULL + && (selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { + ret->group = ossl_ec_group_new_ex(src->libctx, src->propq, + src->group->meth); + if (ret->group == NULL + || !EC_GROUP_copy(ret->group, src->group)) + goto err; + + if (src->meth != NULL) { +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + if (src->engine != NULL && ENGINE_init(src->engine) == 0) + goto err; + ret->engine = src->engine; +#endif + ret->meth = src->meth; + } + } + + /* copy the public key */ + if (src->pub_key != NULL + && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { + if (ret->group == NULL) + /* no parameter-less keys allowed */ + goto err; + ret->pub_key = EC_POINT_new(ret->group); + if (ret->pub_key == NULL + || !EC_POINT_copy(ret->pub_key, src->pub_key)) + goto err; + } + + /* copy the private key */ + if (src->priv_key != NULL + && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + if (ret->group == NULL) + /* no parameter-less keys allowed */ + goto err; + ret->priv_key = BN_new(); + if (ret->priv_key == NULL || !BN_copy(ret->priv_key, src->priv_key)) + goto err; + if (ret->group->meth->keycopy + && ret->group->meth->keycopy(ret, src) == 0) + goto err; + } + + /* copy the rest */ + if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) { + ret->enc_flag = src->enc_flag; + ret->conv_form = src->conv_form; + } + + ret->version = src->version; + ret->flags = src->flags; + +#ifndef FIPS_MODULE + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, + &ret->ex_data, &src->ex_data)) + goto err; +#endif + + if (ret->meth != NULL && ret->meth->copy != NULL) { + if ((selection + & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR) + goto err; + if (ret->meth->copy(ret, src) == 0) + goto err; + } + + return ret; + err: + EC_KEY_free(ret); + return NULL; +} + +int ossl_ec_encoding_param2id(const OSSL_PARAM *p, int *id) +{ + const char *name = NULL; + int status = 0; + + switch (p->data_type) { + case OSSL_PARAM_UTF8_STRING: + /* The OSSL_PARAM functions have no support for this */ + name = p->data; + status = (name != NULL); + break; + case OSSL_PARAM_UTF8_PTR: + status = OSSL_PARAM_get_utf8_ptr(p, &name); + break; + } + if (status) { + int i = ossl_ec_encoding_name2id(name); + + if (i >= 0) { + *id = i; + return 1; + } + } + return 0; +} + +int ossl_ec_pt_format_param2id(const OSSL_PARAM *p, int *id) +{ + const char *name = NULL; + int status = 0; + + switch (p->data_type) { + case OSSL_PARAM_UTF8_STRING: + /* The OSSL_PARAM functions have no support for this */ + name = p->data; + status = (name != NULL); + break; + case OSSL_PARAM_UTF8_PTR: + status = OSSL_PARAM_get_utf8_ptr(p, &name); + break; + } + if (status) { + int i = ossl_ec_pt_format_name2id(name); + + if (i >= 0) { + *id = i; + return 1; + } + } + return 0; +} + +#ifndef FIPS_MODULE +int ossl_x509_algor_is_sm2(const X509_ALGOR *palg) +{ + int ptype = 0; + const void *pval = NULL; + + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype == V_ASN1_OBJECT) + return OBJ_obj2nid((ASN1_OBJECT *)pval) == NID_sm2; + + if (ptype == V_ASN1_SEQUENCE) { + const ASN1_STRING *str = pval; + const unsigned char *der = str->data; + int derlen = str->length; + EC_GROUP *group; + int ret; + + if ((group = d2i_ECPKParameters(NULL, &der, derlen)) == NULL) + ret = 0; + else + ret = (EC_GROUP_get_curve_name(group) == NID_sm2); + + EC_GROUP_free(group); + return ret; + } + + return 0; +} + +EC_KEY *ossl_ec_key_param_from_x509_algor(const X509_ALGOR *palg, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int ptype = 0; + const void *pval = NULL; + EC_KEY *eckey = NULL; + EC_GROUP *group = NULL; + + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + if ((eckey = EC_KEY_new_ex(libctx, propq)) == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto ecerr; + } + + if (ptype == V_ASN1_SEQUENCE) { + const ASN1_STRING *pstr = pval; + const unsigned char *pm = pstr->data; + int pmlen = pstr->length; + + + if (d2i_ECParameters(&eckey, &pm, pmlen) == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); + goto ecerr; + } + } else if (ptype == V_ASN1_OBJECT) { + const ASN1_OBJECT *poid = pval; + + /* + * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID + */ + + group = EC_GROUP_new_by_curve_name_ex(libctx, propq, OBJ_obj2nid(poid)); + if (group == NULL) + goto ecerr; + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + if (EC_KEY_set_group(eckey, group) == 0) + goto ecerr; + EC_GROUP_free(group); + } else { + ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); + goto ecerr; + } + + return eckey; + + ecerr: + EC_KEY_free(eckey); + EC_GROUP_free(group); + return NULL; +} + +EC_KEY *ossl_ec_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const unsigned char *p = NULL; + int pklen; + EC_KEY *eckey = NULL; + const X509_ALGOR *palg; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8inf)) + return 0; + eckey = ossl_ec_key_param_from_x509_algor(palg, libctx, propq); + if (eckey == NULL) + goto err; + + /* We have parameters now set private key */ + if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { + ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); + goto err; + } + + return eckey; + err: + EC_KEY_free(eckey); + return NULL; +} +#endif diff --git a/crypto/openssl/crypto/ec/ec_check.c b/crypto/openssl/crypto/ec/ec_check.c index d0706d2857e6..484124915dc6 100644 --- a/crypto/openssl/crypto/ec/ec_check.c +++ b/crypto/openssl/crypto/ec/ec_check.c @@ -1,22 +1,67 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "ec_local.h" #include +int EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only, + BN_CTX *ctx) +{ + int nid; + BN_CTX *new_ctx = NULL; + + if (group == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); + return NID_undef; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new_ex(NULL); + if (ctx == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + return NID_undef; + } + } + + nid = ossl_ec_curve_nid_from_params(group, ctx); + if (nid > 0 && nist_only && EC_curve_nid2nist(nid) == NULL) + nid = NID_undef; + + BN_CTX_free(new_ctx); + return nid; +} + int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) { +#ifdef FIPS_MODULE + /* + * ECC domain parameter validation. + * See SP800-56A R3 5.5.2 "Assurances of Domain-Parameter Validity" Part 1b. + */ + return EC_GROUP_check_named_curve(group, 1, ctx) >= 0 ? 1 : 0; +#else int ret = 0; const BIGNUM *order; BN_CTX *new_ctx = NULL; EC_POINT *point = NULL; + if (group == NULL || group->meth == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + /* Custom curves assumed to be correct */ if ((group->meth->flags & EC_FLAGS_CUSTOM_CURVE) != 0) return 1; @@ -24,24 +69,24 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { - ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } } /* check the discriminant */ if (!EC_GROUP_check_discriminant(group, ctx)) { - ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO); + ERR_raise(ERR_LIB_EC, EC_R_DISCRIMINANT_IS_ZERO); goto err; } /* check the generator */ if (group->generator == NULL) { - ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR); + ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR); goto err; } if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) { - ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE); + ERR_raise(ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE); goto err; } @@ -52,14 +97,14 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) if (order == NULL) goto err; if (BN_is_zero(order)) { - ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER); + ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_ORDER); goto err; } if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) goto err; if (!EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); goto err; } @@ -69,4 +114,5 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) BN_CTX_free(new_ctx); EC_POINT_free(point); return ret; +#endif /* FIPS_MODULE */ } diff --git a/crypto/openssl/crypto/ec/ec_curve.c b/crypto/openssl/crypto/ec/ec_curve.c index b4c14e91e175..b5b2f3342dfb 100644 --- a/crypto/openssl/crypto/ec/ec_curve.c +++ b/crypto/openssl/crypto/ec/ec_curve.c @@ -2,12 +2,18 @@ * Copyright 2002-2021 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 + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "ec_local.h" #include @@ -194,6 +200,7 @@ static const struct { } }; +# ifndef FIPS_MODULE /* the x9.62 prime curves (minus the nist prime curves) */ static const struct { EC_CURVE_DATA h; @@ -372,6 +379,7 @@ static const struct { 0x43, 0x21, 0x46, 0x52, 0x65, 0x51 } }; +#endif /* FIPS_MODULE */ static const struct { EC_CURVE_DATA h; @@ -411,6 +419,7 @@ static const struct { } }; +#ifndef FIPS_MODULE /* the secg prime curves (minus the nist and x9.62 prime curves) */ static const struct { EC_CURVE_DATA h; @@ -832,10 +841,13 @@ static const struct { 0x5C, 0x5C, 0x2A, 0x3D } }; +#endif /* FIPS_MODULE */ #ifndef OPENSSL_NO_EC2M /* characteristic two curves */ + +# ifndef FIPS_MODULE static const struct { EC_CURVE_DATA h; unsigned char data[20 + 15 * 6]; @@ -963,6 +975,7 @@ static const struct { 0x33, 0x04, 0x9B, 0xA9, 0x8F } }; +# endif /* FIPS_MODULE */ static const struct { EC_CURVE_DATA h; @@ -994,6 +1007,7 @@ static const struct { } }; +# ifndef FIPS_MODULE static const struct { EC_CURVE_DATA h; unsigned char data[0 + 21 * 6]; @@ -1022,6 +1036,7 @@ static const struct { 0xAA, 0xB6, 0x89, 0xC2, 0x9C, 0xA7, 0x10, 0x27, 0x9B } }; +# endif /* FIPS_MODULE */ static const struct { EC_CURVE_DATA h; @@ -1052,6 +1067,7 @@ static const struct { } }; +# ifndef FIPS_MODULE static const struct { EC_CURVE_DATA h; unsigned char data[20 + 25 * 6]; @@ -1127,6 +1143,7 @@ static const struct { 0xD5 } }; +# endif /* FIPS_MODULE */ static const struct { EC_CURVE_DATA h; @@ -1137,6 +1154,7 @@ static const struct { }, { /* no seed */ + /* p */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, @@ -1201,6 +1219,7 @@ static const struct { } }; +#ifndef FIPS_MODULE static const struct { EC_CURVE_DATA h; unsigned char data[0 + 30 * 6]; @@ -1210,6 +1229,7 @@ static const struct { }, { /* no seed */ + /* p */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, @@ -1235,6 +1255,7 @@ static const struct { 0x1D, 0xA8, 0x00, 0xE4, 0x78, 0xA5 } }; +# endif /* FIPS_MODULE */ static const struct { EC_CURVE_DATA h; @@ -1245,6 +1266,7 @@ static const struct { }, { /* no seed */ + /* p */ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1, @@ -1279,7 +1301,7 @@ static const struct { NID_X9_62_characteristic_two_field, 20, 36, 2 }, { - /* no seed */ + /* seed */ 0x77, 0xE2, 0xB0, 0x73, 0x70, 0xEB, 0x0F, 0x83, 0x2A, 0x6D, 0xD5, 0xB6, 0x2D, 0xFC, 0x88, 0xCD, 0x06, 0xBB, 0x84, 0xBE, /* p */ @@ -1517,6 +1539,7 @@ static const struct { } }; +# ifndef FIPS_MODULE static const struct { EC_CURVE_DATA h; unsigned char data[20 + 21 * 6]; @@ -2201,8 +2224,8 @@ static const struct { 0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20, 0xBA, 0xFC, 0xA7, 0x5E } }; - -#endif +# endif /* FIPS_MODULE */ +#endif /* OPENSSL_NO_EC2M */ /* * These curves were added by Annie Yousar. @@ -2212,6 +2235,7 @@ static const struct { * generation mechanism is different from those defined in ANSI X9.62. */ +#ifndef FIPS_MODULE static const struct { EC_CURVE_DATA h; unsigned char data[0 + 20 * 6]; @@ -2751,8 +2775,9 @@ static const struct { 0x9C, 0xA9, 0x00, 0x69 } }; +#endif /* FIPS_MODULE */ -#ifndef OPENSSL_NO_SM2 +#if !defined(OPENSSL_NO_SM2) && !defined(FIPS_MODULE) static const struct { EC_CURVE_DATA h; unsigned char data[0 + 32 * 6]; @@ -2798,6 +2823,79 @@ typedef struct _ec_list_element_st { const char *comment; } ec_list_element; +#ifdef FIPS_MODULE +static const ec_list_element curve_list[] = { + /* prime field curves */ + /* secg curves */ + {NID_secp224r1, &_EC_NIST_PRIME_224.h, +# if !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) + EC_GFp_nistp224_method, +# else + 0, +# endif + "NIST/SECG curve over a 224 bit prime field"}, + /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ + {NID_secp384r1, &_EC_NIST_PRIME_384.h, +# if defined(S390X_EC_ASM) + EC_GFp_s390x_nistp384_method, +# else + 0, +# endif + "NIST/SECG curve over a 384 bit prime field"}, + + {NID_secp521r1, &_EC_NIST_PRIME_521.h, +# if defined(S390X_EC_ASM) + EC_GFp_s390x_nistp521_method, +# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) + EC_GFp_nistp521_method, +# else + 0, +# endif + "NIST/SECG curve over a 521 bit prime field"}, + + /* X9.62 curves */ + {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, + "NIST/X9.62/SECG curve over a 192 bit prime field"}, + {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, +# if defined(ECP_NISTZ256_ASM) + EC_GFp_nistz256_method, +# elif defined(S390X_EC_ASM) + EC_GFp_s390x_nistp256_method, +# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) + EC_GFp_nistp256_method, +# else + 0, +# endif + "X9.62/SECG curve over a 256 bit prime field"}, + +# ifndef OPENSSL_NO_EC2M + /* characteristic two field curves */ + /* NIST/SECG curves */ + {NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0, + "NIST/SECG/WTLS curve over a 163 bit binary field"}, + {NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0, + "NIST/SECG curve over a 163 bit binary field"}, + {NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, + {NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, + {NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0, + "NIST/SECG curve over a 283 bit binary field"}, + {NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0, + "NIST/SECG curve over a 283 bit binary field"}, + {NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0, + "NIST/SECG curve over a 409 bit binary field"}, + {NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0, + "NIST/SECG curve over a 409 bit binary field"}, + {NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0, + "NIST/SECG curve over a 571 bit binary field"}, + {NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0, + "NIST/SECG curve over a 571 bit binary field"}, +# endif +}; + +#else + static const ec_list_element curve_list[] = { /* prime field curves */ /* secg curves */ @@ -2820,25 +2918,32 @@ static const ec_list_element curve_list[] = { "SECG curve over a 192 bit prime field"}, {NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, "SECG curve over a 224 bit prime field"}, -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 {NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field"}, -#else +# else {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field"}, -#endif +# endif {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field"}, /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ - {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, + {NID_secp384r1, &_EC_NIST_PRIME_384.h, +# if defined(S390X_EC_ASM) + EC_GFp_s390x_nistp384_method, +# else + 0, +# endif "NIST/SECG curve over a 384 bit prime field"}, -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 - {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, - "NIST/SECG curve over a 521 bit prime field"}, -#else - {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, + {NID_secp521r1, &_EC_NIST_PRIME_521.h, +# if defined(S390X_EC_ASM) + EC_GFp_s390x_nistp521_method, +# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) + EC_GFp_nistp521_method, +# else + 0, +# endif "NIST/SECG curve over a 521 bit prime field"}, -#endif /* X9.62 curves */ {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, "NIST/X9.62/SECG curve over a 192 bit prime field"}, @@ -2853,15 +2958,17 @@ static const ec_list_element curve_list[] = { {NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field"}, {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, -#if defined(ECP_NISTZ256_ASM) +# if defined(ECP_NISTZ256_ASM) EC_GFp_nistz256_method, -#elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) +# elif defined(S390X_EC_ASM) + EC_GFp_s390x_nistp256_method, +# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) EC_GFp_nistp256_method, -#else +# else 0, -#endif +# endif "X9.62/SECG curve over a 256 bit prime field"}, -#ifndef OPENSSL_NO_EC2M +# ifndef OPENSSL_NO_EC2M /* characteristic two field curves */ /* NIST/SECG curves */ {NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, @@ -2945,7 +3052,7 @@ static const ec_list_element curve_list[] = { "SECG curve over a 113 bit binary field"}, {NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field"}, -#endif +# endif {NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field"}, {NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, @@ -2954,15 +3061,15 @@ static const ec_list_element curve_list[] = { "WTLS curve over a 112 bit prime field"}, {NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, "WTLS curve over a 160 bit prime field"}, -#ifndef OPENSSL_NO_EC2M +# ifndef OPENSSL_NO_EC2M {NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"}, {NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"}, -#endif +# endif {NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, "WTLS curve over a 224 bit prime field"}, -#ifndef OPENSSL_NO_EC2M +# ifndef OPENSSL_NO_EC2M /* IPSec curves */ {NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n" @@ -2970,7 +3077,7 @@ static const ec_list_element curve_list[] = { {NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n" "\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, -#endif +# endif /* brainpool curves */ {NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0, "RFC 5639 curve over a 160 bit prime field"}, @@ -3000,15 +3107,32 @@ static const ec_list_element curve_list[] = { "RFC 5639 curve over a 512 bit prime field"}, {NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0, "RFC 5639 curve over a 512 bit prime field"}, -#ifndef OPENSSL_NO_SM2 +# ifndef OPENSSL_NO_SM2 {NID_sm2, &_EC_sm2p256v1.h, 0, "SM2 curve over a 256 bit prime field"}, -#endif +# endif }; +#endif /* FIPS_MODULE */ #define curve_list_length OSSL_NELEM(curve_list) -static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) +static const ec_list_element *ec_curve_nid2curve(int nid) +{ + size_t i; + + if (nid <= 0) + return NULL; + + for (i = 0; i < curve_list_length; i++) { + if (curve_list[i].nid == nid) + return &curve_list[i]; + } + return NULL; +} + +static EC_GROUP *ec_group_new_from_data(OSSL_LIB_CTX *libctx, + const char *propq, + const ec_list_element curve) { EC_GROUP *group = NULL; EC_POINT *P = NULL; @@ -3023,10 +3147,11 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) /* If no curve data curve method must handle everything */ if (curve.data == NULL) - return EC_GROUP_new(curve.meth != NULL ? curve.meth() : NULL); + return ossl_ec_group_new_ex(libctx, propq, + curve.meth != NULL ? curve.meth() : NULL); - if ((ctx = BN_CTX_new()) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); + if ((ctx = BN_CTX_new_ex(libctx)) == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -3039,20 +3164,20 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) if ((p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) == NULL || (a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) == NULL || (b = BN_bin2bn(params + 2 * param_len, param_len, NULL)) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } if (curve.meth != 0) { meth = curve.meth(); - if (((group = EC_GROUP_new(meth)) == NULL) || + if (((group = ossl_ec_group_new_ex(libctx, propq, meth)) == NULL) || (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } } else if (data->field_type == NID_X9_62_prime_field) { if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } } @@ -3061,7 +3186,7 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) * NID_X9_62_characteristic_two_field */ if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } } @@ -3070,35 +3195,36 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) EC_GROUP_set_curve_name(group, curve.nid); if ((P = EC_POINT_new(group)) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if ((x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) == NULL || (y = BN_bin2bn(params + 4 * param_len, param_len, NULL)) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } if (!EC_POINT_set_affine_coordinates(group, P, x, y, ctx)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if ((order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) == NULL || !BN_set_word(x, (BN_ULONG)data->cofactor)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } if (!EC_GROUP_set_generator(group, P, order, x)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (seed_len) { if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } } +#ifndef FIPS_MODULE if (EC_GROUP_get_asn1_flag(group) == OPENSSL_EC_NAMED_CURVE) { /* * Some curves don't have an associated OID: for those we should not @@ -3115,7 +3241,7 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) ASN1_OBJECT *asn1obj = OBJ_nid2obj(curve.nid); if (asn1obj == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_OBJ_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_OBJ_LIB); goto err; } if (OBJ_length(asn1obj) == 0) @@ -3123,6 +3249,16 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) ASN1_OBJECT_free(asn1obj); } +#else + /* + * Inside the FIPS module we do not support explicit curves anyway + * so the above check is not necessary. + * + * Skipping it is also necessary because `OBJ_length()` and + * `ASN1_OBJECT_free()` are not available within the FIPS module + * boundaries. + */ +#endif ok = 1; err: @@ -3141,28 +3277,33 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) return group; } -EC_GROUP *EC_GROUP_new_by_curve_name(int nid) +EC_GROUP *EC_GROUP_new_by_curve_name_ex(OSSL_LIB_CTX *libctx, const char *propq, + int nid) { - size_t i; EC_GROUP *ret = NULL; + const ec_list_element *curve; - if (nid <= 0) - return NULL; - - for (i = 0; i < curve_list_length; i++) - if (curve_list[i].nid == nid) { - ret = ec_group_new_from_data(curve_list[i]); - break; - } - - if (ret == NULL) { - ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP); + if ((curve = ec_curve_nid2curve(nid)) == NULL + || (ret = ec_group_new_from_data(libctx, propq, *curve)) == NULL) { +#ifndef FIPS_MODULE + ERR_raise_data(ERR_LIB_EC, EC_R_UNKNOWN_GROUP, + "name=%s", OBJ_nid2sn(nid)); +#else + ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_GROUP); +#endif return NULL; } return ret; } +#ifndef FIPS_MODULE +EC_GROUP *EC_GROUP_new_by_curve_name(int nid) +{ + return EC_GROUP_new_by_curve_name_ex(NULL, NULL, nid); +} +#endif + size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) { size_t i, min; @@ -3180,49 +3321,14 @@ size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) return curve_list_length; } -/* Functions to translate between common NIST curve names and NIDs */ - -typedef struct { - const char *name; /* NIST Name of curve */ - int nid; /* Curve NID */ -} EC_NIST_NAME; - -static EC_NIST_NAME nist_curves[] = { - {"B-163", NID_sect163r2}, - {"B-233", NID_sect233r1}, - {"B-283", NID_sect283r1}, - {"B-409", NID_sect409r1}, - {"B-571", NID_sect571r1}, - {"K-163", NID_sect163k1}, - {"K-233", NID_sect233k1}, - {"K-283", NID_sect283k1}, - {"K-409", NID_sect409k1}, - {"K-571", NID_sect571k1}, - {"P-192", NID_X9_62_prime192v1}, - {"P-224", NID_secp224r1}, - {"P-256", NID_X9_62_prime256v1}, - {"P-384", NID_secp384r1}, - {"P-521", NID_secp521r1} -}; - const char *EC_curve_nid2nist(int nid) { - size_t i; - for (i = 0; i < OSSL_NELEM(nist_curves); i++) { - if (nist_curves[i].nid == nid) - return nist_curves[i].name; - } - return NULL; + return ossl_ec_curve_nid2nist_int(nid); } int EC_curve_nist2nid(const char *name) { - size_t i; - for (i = 0; i < OSSL_NELEM(nist_curves); i++) { - if (strcmp(nist_curves[i].name, name) == 0) - return nist_curves[i].nid; - } - return NID_undef; + return ossl_ec_curve_nist2nid_int(name); } #define NUM_BN_FIELDS 6 @@ -3234,7 +3340,7 @@ int EC_curve_nist2nid(const char *name) * Returns: The nid associated with the found named curve, or NID_undef * if not found. If there was an error it returns -1. */ -int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx) +int ossl_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; @@ -3242,17 +3348,13 @@ int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx) unsigned char *param_bytes = NULL; const EC_CURVE_DATA *data; const EC_POINT *generator = NULL; - const EC_METHOD *meth; const BIGNUM *cofactor = NULL; /* An array of BIGNUMs for (p, a, b, x, y, order) */ BIGNUM *bn[NUM_BN_FIELDS] = {NULL, NULL, NULL, NULL, NULL, NULL}; - meth = EC_GROUP_method_of(group); - if (meth == NULL) - return -1; /* Use the optional named curve nid as a search field */ nid = EC_GROUP_get_curve_name(group); - field_type = EC_METHOD_get_field_type(meth); + field_type = EC_GROUP_get_field_type(group); seed_len = EC_GROUP_get_seed_len(group); seed = EC_GROUP_get0_seed(group); cofactor = EC_GROUP_get0_cofactor(group); diff --git a/crypto/openssl/crypto/ec/ec_cvt.c b/crypto/openssl/crypto/ec/ec_cvt.c index 944e317d9d14..1145bfb68f90 100644 --- a/crypto/openssl/crypto/ec/ec_cvt.c +++ b/crypto/openssl/crypto/ec/ec_cvt.c @@ -1,14 +1,21 @@ /* - * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 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 + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include +#include "crypto/bn.h" #include "ec_local.h" EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, @@ -47,12 +54,12 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, meth = EC_GFp_mont_method(); #endif - ret = EC_GROUP_new(meth); + ret = ossl_ec_group_new_ex(ossl_bn_get_libctx(ctx), NULL, meth); if (ret == NULL) return NULL; if (!EC_GROUP_set_curve(ret, p, a, b, ctx)) { - EC_GROUP_clear_free(ret); + EC_GROUP_free(ret); return NULL; } @@ -68,12 +75,12 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, meth = EC_GF2m_simple_method(); - ret = EC_GROUP_new(meth); + ret = ossl_ec_group_new_ex(ossl_bn_get_libctx(ctx), NULL, meth); if (ret == NULL) return NULL; if (!EC_GROUP_set_curve(ret, p, a, b, ctx)) { - EC_GROUP_clear_free(ret); + EC_GROUP_free(ret); return NULL; } diff --git a/crypto/openssl/crypto/ec/ec_deprecated.c b/crypto/openssl/crypto/ec/ec_deprecated.c new file mode 100644 index 000000000000..765894c32977 --- /dev/null +++ b/crypto/openssl/crypto/ec/ec_deprecated.c @@ -0,0 +1,78 @@ +/* + * Copyright 2002-2021 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 + */ + +/* + * Suppress deprecation warnings for EC low level implementations that are + * kept until removal. + */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include +#include +#include + +#ifndef OPENSSL_NO_DEPRECATED_3_0 +BIGNUM *EC_POINT_point2bn(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + BIGNUM *ret, BN_CTX *ctx) +{ + size_t buf_len = 0; + unsigned char *buf; + + buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx); + + if (buf_len == 0) + return NULL; + + ret = BN_bin2bn(buf, buf_len, ret); + + OPENSSL_free(buf); + + return ret; +} + +EC_POINT *EC_POINT_bn2point(const EC_GROUP *group, + const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx) +{ + size_t buf_len = 0; + unsigned char *buf; + EC_POINT *ret; + + if ((buf_len = BN_num_bytes(bn)) == 0) + buf_len = 1; + if ((buf = OPENSSL_malloc(buf_len)) == NULL) { + ECerr(EC_F_EC_POINT_BN2POINT, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (BN_bn2binpad(bn, buf, buf_len) < 0) { + OPENSSL_free(buf); + return NULL; + } + + if (point == NULL) { + if ((ret = EC_POINT_new(group)) == NULL) { + OPENSSL_free(buf); + return NULL; + } + } else + ret = point; + + if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) { + if (ret != point) + EC_POINT_clear_free(ret); + OPENSSL_free(buf); + return NULL; + } + + OPENSSL_free(buf); + return ret; +} +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ diff --git a/crypto/openssl/crypto/ec/ec_err.c b/crypto/openssl/crypto/ec/ec_err.c index bfe74226503e..4d6f2a76ad20 100644 --- a/crypto/openssl/crypto/ec/ec_err.c +++ b/crypto/openssl/crypto/ec/ec_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,283 +10,11 @@ #include #include +#include "crypto/ecerr.h" -#ifndef OPENSSL_NO_ERR +#ifndef OPENSSL_NO_EC -static const ERR_STRING_DATA EC_str_functs[] = { - {ERR_PACK(ERR_LIB_EC, EC_F_BN_TO_FELEM, 0), "BN_to_felem"}, - {ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPARAMETERS, 0), "d2i_ECParameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPKPARAMETERS, 0), "d2i_ECPKParameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPRIVATEKEY, 0), "d2i_ECPrivateKey"}, - {ERR_PACK(ERR_LIB_EC, EC_F_DO_EC_KEY_PRINT, 0), "do_EC_KEY_print"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_CMS_DECRYPT, 0), "ecdh_cms_decrypt"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_CMS_SET_SHARED_INFO, 0), - "ecdh_cms_set_shared_info"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_COMPUTE_KEY, 0), "ECDH_compute_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDH_SIMPLE_COMPUTE_KEY, 0), - "ecdh_simple_compute_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_DO_SIGN_EX, 0), "ECDSA_do_sign_ex"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_DO_VERIFY, 0), "ECDSA_do_verify"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIGN_EX, 0), "ECDSA_sign_ex"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIGN_SETUP, 0), "ECDSA_sign_setup"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIG_NEW, 0), "ECDSA_SIG_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_VERIFY, 0), "ECDSA_verify"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECD_ITEM_VERIFY, 0), "ecd_item_verify"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PARAM2TYPE, 0), "eckey_param2type"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PARAM_DECODE, 0), "eckey_param_decode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PRIV_DECODE, 0), "eckey_priv_decode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PRIV_ENCODE, 0), "eckey_priv_encode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PUB_DECODE, 0), "eckey_pub_decode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PUB_ENCODE, 0), "eckey_pub_encode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_TYPE2PARAM, 0), "eckey_type2param"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECPARAMETERS_PRINT, 0), "ECParameters_print"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECPARAMETERS_PRINT_FP, 0), - "ECParameters_print_fp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECPKPARAMETERS_PRINT, 0), - "ECPKParameters_print"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECPKPARAMETERS_PRINT_FP, 0), - "ECPKParameters_print_fp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_GET_AFFINE, 0), - "ecp_nistz256_get_affine"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_INV_MOD_ORD, 0), - "ecp_nistz256_inv_mod_ord"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, 0), - "ecp_nistz256_mult_precompute"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_POINTS_MUL, 0), - "ecp_nistz256_points_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_PRE_COMP_NEW, 0), - "ecp_nistz256_pre_comp_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_WINDOWED_MUL, 0), - "ecp_nistz256_windowed_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECX_KEY_OP, 0), "ecx_key_op"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECX_PRIV_ENCODE, 0), "ecx_priv_encode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_ECX_PUB_ENCODE, 0), "ecx_pub_encode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_ASN1_GROUP2CURVE, 0), "ec_asn1_group2curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_ASN1_GROUP2FIELDID, 0), - "ec_asn1_group2fieldid"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, 0), - "ec_GF2m_montgomery_point_multiply"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_FIELD_INV, 0), - "ec_GF2m_simple_field_inv"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0), - "ec_GF2m_simple_group_check_discriminant"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, 0), - "ec_GF2m_simple_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_LADDER_POST, 0), - "ec_GF2m_simple_ladder_post"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_LADDER_PRE, 0), - "ec_GF2m_simple_ladder_pre"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_OCT2POINT, 0), - "ec_GF2m_simple_oct2point"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT2OCT, 0), - "ec_GF2m_simple_point2oct"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINTS_MUL, 0), - "ec_GF2m_simple_points_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, 0), - "ec_GF2m_simple_point_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, 0), - "ec_GF2m_simple_point_set_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, 0), - "ec_GF2m_simple_set_compressed_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_DECODE, 0), - "ec_GFp_mont_field_decode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_ENCODE, 0), - "ec_GFp_mont_field_encode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_INV, 0), - "ec_GFp_mont_field_inv"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_MUL, 0), - "ec_GFp_mont_field_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, 0), - "ec_GFp_mont_field_set_to_one"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_SQR, 0), - "ec_GFp_mont_field_sqr"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_GROUP_SET_CURVE, 0), - "ec_GFp_mont_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE, 0), - "ec_GFp_nistp224_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_POINTS_MUL, 0), - "ec_GFp_nistp224_points_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, 0), - "ec_GFp_nistp224_point_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE, 0), - "ec_GFp_nistp256_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_POINTS_MUL, 0), - "ec_GFp_nistp256_points_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, 0), - "ec_GFp_nistp256_point_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE, 0), - "ec_GFp_nistp521_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_POINTS_MUL, 0), - "ec_GFp_nistp521_points_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, 0), - "ec_GFp_nistp521_point_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_FIELD_MUL, 0), - "ec_GFp_nist_field_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_FIELD_SQR, 0), - "ec_GFp_nist_field_sqr"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_GROUP_SET_CURVE, 0), - "ec_GFp_nist_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, 0), - "ec_GFp_simple_blind_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_FIELD_INV, 0), - "ec_GFp_simple_field_inv"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0), - "ec_GFp_simple_group_check_discriminant"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, 0), - "ec_GFp_simple_group_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, 0), - "ec_GFp_simple_make_affine"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_OCT2POINT, 0), - "ec_GFp_simple_oct2point"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT2OCT, 0), - "ec_GFp_simple_point2oct"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, 0), - "ec_GFp_simple_points_make_affine"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, 0), - "ec_GFp_simple_point_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, 0), - "ec_GFp_simple_point_set_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, 0), - "ec_GFp_simple_set_compressed_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_CHECK, 0), "EC_GROUP_check"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_CHECK_DISCRIMINANT, 0), - "EC_GROUP_check_discriminant"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_COPY, 0), "EC_GROUP_copy"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE, 0), "EC_GROUP_get_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE_GF2M, 0), - "EC_GROUP_get_curve_GF2m"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE_GFP, 0), - "EC_GROUP_get_curve_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_DEGREE, 0), "EC_GROUP_get_degree"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_ECPARAMETERS, 0), - "EC_GROUP_get_ecparameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_ECPKPARAMETERS, 0), - "EC_GROUP_get_ecpkparameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, 0), - "EC_GROUP_get_pentanomial_basis"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, 0), - "EC_GROUP_get_trinomial_basis"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW, 0), "EC_GROUP_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_BY_CURVE_NAME, 0), - "EC_GROUP_new_by_curve_name"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_DATA, 0), - "ec_group_new_from_data"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, 0), - "EC_GROUP_new_from_ecparameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, 0), - "EC_GROUP_new_from_ecpkparameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE, 0), "EC_GROUP_set_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE_GF2M, 0), - "EC_GROUP_set_curve_GF2m"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE_GFP, 0), - "EC_GROUP_set_curve_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_GENERATOR, 0), - "EC_GROUP_set_generator"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_SEED, 0), "EC_GROUP_set_seed"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_CHECK_KEY, 0), "EC_KEY_check_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_COPY, 0), "EC_KEY_copy"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_GENERATE_KEY, 0), "EC_KEY_generate_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_NEW, 0), "EC_KEY_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_NEW_METHOD, 0), "EC_KEY_new_method"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_OCT2PRIV, 0), "EC_KEY_oct2priv"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRINT, 0), "EC_KEY_print"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRINT_FP, 0), "EC_KEY_print_fp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRIV2BUF, 0), "EC_KEY_priv2buf"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRIV2OCT, 0), "EC_KEY_priv2oct"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 0), - "EC_KEY_set_public_key_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_CHECK_KEY, 0), - "ec_key_simple_check_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_OCT2PRIV, 0), - "ec_key_simple_oct2priv"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_PRIV2OCT, 0), - "ec_key_simple_priv2oct"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_PKEY_CHECK, 0), "ec_pkey_check"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_PKEY_PARAM_CHECK, 0), "ec_pkey_param_check"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINTS_MAKE_AFFINE, 0), - "EC_POINTs_make_affine"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINTS_MUL, 0), "EC_POINTs_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_ADD, 0), "EC_POINT_add"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_BN2POINT, 0), "EC_POINT_bn2point"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_CMP, 0), "EC_POINT_cmp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_COPY, 0), "EC_POINT_copy"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_DBL, 0), "EC_POINT_dbl"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES, 0), - "EC_POINT_get_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, 0), - "EC_POINT_get_affine_coordinates_GF2m"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, 0), - "EC_POINT_get_affine_coordinates_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, 0), - "EC_POINT_get_Jprojective_coordinates_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_INVERT, 0), "EC_POINT_invert"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_IS_AT_INFINITY, 0), - "EC_POINT_is_at_infinity"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_IS_ON_CURVE, 0), - "EC_POINT_is_on_curve"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_MAKE_AFFINE, 0), - "EC_POINT_make_affine"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_NEW, 0), "EC_POINT_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_OCT2POINT, 0), "EC_POINT_oct2point"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_POINT2BUF, 0), "EC_POINT_point2buf"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_POINT2OCT, 0), "EC_POINT_point2oct"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES, 0), - "EC_POINT_set_affine_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, 0), - "EC_POINT_set_affine_coordinates_GF2m"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, 0), - "EC_POINT_set_affine_coordinates_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES, 0), - "EC_POINT_set_compressed_coordinates"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, 0), - "EC_POINT_set_compressed_coordinates_GF2m"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, 0), - "EC_POINT_set_compressed_coordinates_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, 0), - "EC_POINT_set_Jprojective_coordinates_GFp"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_TO_INFINITY, 0), - "EC_POINT_set_to_infinity"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_PRE_COMP_NEW, 0), "ec_pre_comp_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_SCALAR_MUL_LADDER, 0), - "ec_scalar_mul_ladder"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_WNAF_MUL, 0), "ec_wNAF_mul"}, - {ERR_PACK(ERR_LIB_EC, EC_F_EC_WNAF_PRECOMPUTE_MULT, 0), - "ec_wNAF_precompute_mult"}, - {ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPARAMETERS, 0), "i2d_ECParameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPKPARAMETERS, 0), "i2d_ECPKParameters"}, - {ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPRIVATEKEY, 0), "i2d_ECPrivateKey"}, - {ERR_PACK(ERR_LIB_EC, EC_F_I2O_ECPUBLICKEY, 0), "i2o_ECPublicKey"}, - {ERR_PACK(ERR_LIB_EC, EC_F_NISTP224_PRE_COMP_NEW, 0), - "nistp224_pre_comp_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_NISTP256_PRE_COMP_NEW, 0), - "nistp256_pre_comp_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_NISTP521_PRE_COMP_NEW, 0), - "nistp521_pre_comp_new"}, - {ERR_PACK(ERR_LIB_EC, EC_F_O2I_ECPUBLICKEY, 0), "o2i_ECPublicKey"}, - {ERR_PACK(ERR_LIB_EC, EC_F_OLD_EC_PRIV_DECODE, 0), "old_ec_priv_decode"}, - {ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDH_COMPUTE_KEY, 0), - "ossl_ecdh_compute_key"}, - {ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDSA_SIGN_SIG, 0), "ossl_ecdsa_sign_sig"}, - {ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDSA_VERIFY_SIG, 0), - "ossl_ecdsa_verify_sig"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_CTRL, 0), "pkey_ecd_ctrl"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN, 0), "pkey_ecd_digestsign"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN25519, 0), - "pkey_ecd_digestsign25519"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN448, 0), - "pkey_ecd_digestsign448"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECX_DERIVE, 0), "pkey_ecx_derive"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL, 0), "pkey_ec_ctrl"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL_STR, 0), "pkey_ec_ctrl_str"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_DERIVE, 0), "pkey_ec_derive"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_INIT, 0), "pkey_ec_init"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_KDF_DERIVE, 0), "pkey_ec_kdf_derive"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_KEYGEN, 0), "pkey_ec_keygen"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_PARAMGEN, 0), "pkey_ec_paramgen"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_SIGN, 0), "pkey_ec_sign"}, - {ERR_PACK(ERR_LIB_EC, EC_F_VALIDATE_ECX_DERIVE, 0), "validate_ecx_derive"}, - {0, NULL} -}; +# ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA EC_str_reasons[] = { {ERR_PACK(ERR_LIB_EC, 0, EC_R_ASN1_ERROR), "asn1 error"}, @@ -298,15 +26,19 @@ static const ERR_STRING_DATA EC_str_reasons[] = { "coordinates out of range"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH), "curve does not support ecdh"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA), + "curve does not support ecdsa"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING), "curve does not support signing"}, - {ERR_PACK(ERR_LIB_EC, 0, EC_R_D2I_ECPKPARAMETERS_FAILURE), - "d2i ecpkparameters failure"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_DECODE_ERROR), "decode error"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE), "ec group new by name failure"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED), + "explicit params not supported"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_FAILED_MAKING_PUBLIC_KEY), + "failed making public key"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_FIELD_TOO_LARGE), "field too large"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_GROUP2PKPARAMETERS_FAILURE), @@ -315,7 +47,10 @@ static const ERR_STRING_DATA EC_str_reasons[] = { "i2d ecpkparameters failure"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_A), "invalid a"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ARGUMENT), "invalid argument"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_B), "invalid b"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COFACTOR), "invalid cofactor"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSION_BIT), @@ -326,14 +61,20 @@ static const ERR_STRING_DATA EC_str_reasons[] = { {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ENCODING), "invalid encoding"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FIELD), "invalid field"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FORM), "invalid form"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_GENERATOR), "invalid generator"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_GROUP_ORDER), "invalid group order"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_KEY), "invalid key"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_LENGTH), "invalid length"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_NAMED_GROUP_CONVERSION), + "invalid named group conversion"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_OUTPUT_LENGTH), "invalid output length"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_P), "invalid p"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PEER_KEY), "invalid peer key"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PRIVATE_KEY), "invalid private key"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_SEED), "invalid seed"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, @@ -356,8 +97,6 @@ static const ERR_STRING_DATA EC_str_reasons[] = { {ERR_PACK(ERR_LIB_EC, 0, EC_R_PASSED_NULL_PARAMETER), "passed null parameter"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_PEER_KEY_ERROR), "peer key error"}, - {ERR_PACK(ERR_LIB_EC, 0, EC_R_PKPARAMETERS2GROUP_FAILURE), - "pkparameters2group failure"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_AT_INFINITY), "point at infinity"}, @@ -381,15 +120,16 @@ static const ERR_STRING_DATA EC_str_reasons[] = { {0, NULL} }; -#endif +# endif -int ERR_load_EC_strings(void) +int ossl_err_load_EC_strings(void) { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(EC_str_functs[0].error) == NULL) { - ERR_load_strings_const(EC_str_functs); +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(EC_str_reasons[0].error) == NULL) ERR_load_strings_const(EC_str_reasons); - } -#endif +# endif return 1; } +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/ec/ec_key.c b/crypto/openssl/crypto/ec/ec_key.c index 63799002bc98..729d338b3379 100644 --- a/crypto/openssl/crypto/ec/ec_key.c +++ b/crypto/openssl/crypto/ec/ec_key.c @@ -2,31 +2,52 @@ * Copyright 2002-2022 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 + * 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 */ +/* + * EC_KEY low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" #include #include "ec_local.h" #include "internal/refcount.h" #include -#include +#ifndef FIPS_MODULE +# include +#endif +#include +#include "prov/providercommon.h" #include "crypto/bn.h" +static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb, + void *cbarg); + +#ifndef FIPS_MODULE EC_KEY *EC_KEY_new(void) { - return EC_KEY_new_method(NULL); + return ossl_ec_key_new_method_int(NULL, NULL, NULL); } +#endif -EC_KEY *EC_KEY_new_by_curve_name(int nid) +EC_KEY *EC_KEY_new_ex(OSSL_LIB_CTX *ctx, const char *propq) { - EC_KEY *ret = EC_KEY_new(); + return ossl_ec_key_new_method_int(ctx, propq, NULL); +} + +EC_KEY *EC_KEY_new_by_curve_name_ex(OSSL_LIB_CTX *ctx, const char *propq, + int nid) +{ + EC_KEY *ret = EC_KEY_new_ex(ctx, propq); if (ret == NULL) return NULL; - ret->group = EC_GROUP_new_by_curve_name(nid); + ret->group = EC_GROUP_new_by_curve_name_ex(ctx, propq, nid); if (ret->group == NULL) { EC_KEY_free(ret); return NULL; @@ -39,6 +60,13 @@ EC_KEY *EC_KEY_new_by_curve_name(int nid) return ret; } +#ifndef FIPS_MODULE +EC_KEY *EC_KEY_new_by_curve_name(int nid) +{ + return EC_KEY_new_by_curve_name_ex(NULL, NULL, nid); +} +#endif + void EC_KEY_free(EC_KEY *r) { int i; @@ -55,18 +83,21 @@ void EC_KEY_free(EC_KEY *r) if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) ENGINE_finish(r->engine); #endif if (r->group && r->group->meth->keyfinish) r->group->meth->keyfinish(r); +#ifndef FIPS_MODULE CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data); +#endif CRYPTO_THREAD_lock_free(r->lock); EC_GROUP_free(r->group); EC_POINT_free(r->pub_key); BN_clear_free(r->priv_key); + OPENSSL_free(r->propq); OPENSSL_clear_free((void *)r, sizeof(EC_KEY)); } @@ -74,7 +105,7 @@ void EC_KEY_free(EC_KEY *r) EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) { if (dest == NULL || src == NULL) { - ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (src->meth != dest->meth) { @@ -82,18 +113,19 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) dest->meth->finish(dest); if (dest->group && dest->group->meth->keyfinish) dest->group->meth->keyfinish(dest); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) if (ENGINE_finish(dest->engine) == 0) return 0; dest->engine = NULL; #endif } + dest->libctx = src->libctx; /* copy the parameters */ if (src->group != NULL) { - const EC_METHOD *meth = EC_GROUP_method_of(src->group); /* clear the old group */ EC_GROUP_free(dest->group); - dest->group = EC_GROUP_new(meth); + dest->group = ossl_ec_group_new_ex(src->libctx, src->propq, + src->group->meth); if (dest->group == NULL) return NULL; if (!EC_GROUP_copy(dest->group, src->group)) @@ -129,12 +161,14 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) dest->conv_form = src->conv_form; dest->version = src->version; dest->flags = src->flags; +#ifndef FIPS_MODULE if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, &dest->ex_data, &src->ex_data)) return NULL; +#endif if (src->meth != dest->meth) { -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) if (src->engine != NULL && ENGINE_init(src->engine) == 0) return NULL; dest->engine = src->engine; @@ -145,21 +179,14 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0) return NULL; + dest->dirty_cnt++; + return dest; } EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) { - EC_KEY *ret = EC_KEY_new_method(ec_key->engine); - - if (ret == NULL) - return NULL; - - if (EC_KEY_copy(ret, ec_key) == NULL) { - EC_KEY_free(ret); - return NULL; - } - return ret; + return ossl_ec_key_dup(ec_key, OSSL_KEYMGMT_SELECT_ALL); } int EC_KEY_up_ref(EC_KEY *r) @@ -182,156 +209,389 @@ ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey) int EC_KEY_generate_key(EC_KEY *eckey) { if (eckey == NULL || eckey->group == NULL) { - ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } - if (eckey->meth->keygen != NULL) - return eckey->meth->keygen(eckey); - ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED); + if (eckey->meth->keygen != NULL) { + int ret; + + ret = eckey->meth->keygen(eckey); + if (ret == 1) + eckey->dirty_cnt++; + + return ret; + } + ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED); return 0; } int ossl_ec_key_gen(EC_KEY *eckey) { - return eckey->group->meth->keygen(eckey); + int ret; + + ret = eckey->group->meth->keygen(eckey); + + if (ret == 1) + eckey->dirty_cnt++; + return ret; } -int ec_key_simple_generate_key(EC_KEY *eckey) +/* + * ECC Key generation. + * See SP800-56AR3 5.6.1.2.2 "Key Pair Generation by Testing Candidates" + * + * Params: + * libctx A context containing an optional self test callback. + * eckey An EC key object that contains domain params. The generated keypair + * is stored in this object. + * pairwise_test Set to non zero to perform a pairwise test. If the test + * fails then the keypair is not generated, + * Returns 1 if the keypair was generated or 0 otherwise. + */ +static int ec_generate_key(EC_KEY *eckey, int pairwise_test) { int ok = 0; - BN_CTX *ctx = NULL; BIGNUM *priv_key = NULL; - const BIGNUM *order = NULL; + const BIGNUM *tmp = NULL; + BIGNUM *order = NULL; EC_POINT *pub_key = NULL; + const EC_GROUP *group = eckey->group; + BN_CTX *ctx = BN_CTX_secure_new_ex(eckey->libctx); + int sm2 = EC_KEY_get_flags(eckey) & EC_FLAG_SM2_RANGE ? 1 : 0; - if ((ctx = BN_CTX_new()) == NULL) + if (ctx == NULL) goto err; if (eckey->priv_key == NULL) { - priv_key = BN_new(); + priv_key = BN_secure_new(); if (priv_key == NULL) goto err; } else priv_key = eckey->priv_key; - order = EC_GROUP_get0_order(eckey->group); - if (order == NULL) + /* + * Steps (1-2): Check domain parameters and security strength. + * These steps must be done by the user. This would need to be + * stated in the security policy. + */ + + tmp = EC_GROUP_get0_order(group); + if (tmp == NULL) goto err; + /* + * Steps (3-7): priv_key = DRBG_RAND(order_n_bits) (range [1, n-1]). + * Although this is slightly different from the standard, it is effectively + * equivalent as it gives an unbiased result ranging from 1..n-1. It is also + * faster as the standard needs to retry more often. Also doing + * 1 + rand[0..n-2] would effect the way that tests feed dummy entropy into + * rand so the simpler backward compatible method has been used here. + */ + + /* range of SM2 private key is [1, n-1) */ + if (sm2) { + order = BN_new(); + if (order == NULL || !BN_sub(order, tmp, BN_value_one())) + goto err; + } else { + order = BN_dup(tmp); + if (order == NULL) + goto err; + } + do - if (!BN_priv_rand_range(priv_key, order)) + if (!BN_priv_rand_range_ex(priv_key, order, 0, ctx)) goto err; while (BN_is_zero(priv_key)) ; if (eckey->pub_key == NULL) { - pub_key = EC_POINT_new(eckey->group); + pub_key = EC_POINT_new(group); if (pub_key == NULL) goto err; } else pub_key = eckey->pub_key; - if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) + /* Step (8) : pub_key = priv_key * G (where G is a point on the curve) */ + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) goto err; eckey->priv_key = priv_key; eckey->pub_key = pub_key; + priv_key = NULL; + pub_key = NULL; + + eckey->dirty_cnt++; + +#ifdef FIPS_MODULE + pairwise_test = 1; +#endif /* FIPS_MODULE */ ok = 1; + if (pairwise_test) { + OSSL_CALLBACK *cb = NULL; + void *cbarg = NULL; - err: - if (eckey->pub_key == NULL) - EC_POINT_free(pub_key); - if (eckey->priv_key != priv_key) - BN_free(priv_key); + OSSL_SELF_TEST_get_callback(eckey->libctx, &cb, &cbarg); + ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg); + } +err: + /* Step (9): If there is an error return an invalid keypair. */ + if (!ok) { + ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); + BN_clear(eckey->priv_key); + if (eckey->pub_key != NULL) + EC_POINT_set_to_infinity(group, eckey->pub_key); + } + + EC_POINT_free(pub_key); + BN_clear_free(priv_key); BN_CTX_free(ctx); + BN_free(order); return ok; } -int ec_key_simple_generate_public_key(EC_KEY *eckey) +int ossl_ec_key_simple_generate_key(EC_KEY *eckey) { - return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL, - NULL, NULL); + return ec_generate_key(eckey, 0); +} + +int ossl_ec_key_simple_generate_public_key(EC_KEY *eckey) +{ + int ret; + BN_CTX *ctx = BN_CTX_new_ex(eckey->libctx); + + if (ctx == NULL) + return 0; + + /* + * See SP800-56AR3 5.6.1.2.2: Step (8) + * pub_key = priv_key * G (where G is a point on the curve) + */ + ret = EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL, + NULL, ctx); + + BN_CTX_free(ctx); + if (ret == 1) + eckey->dirty_cnt++; + + return ret; } int EC_KEY_check_key(const EC_KEY *eckey) { if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) { - ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (eckey->group->meth->keycheck == NULL) { - ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } return eckey->group->meth->keycheck(eckey); } -int ec_key_simple_check_key(const EC_KEY *eckey) +/* + * Check the range of the EC public key. + * See SP800-56A R3 Section 5.6.2.3.3 (Part 2) + * i.e. + * - If q = odd prime p: Verify that xQ and yQ are integers in the + * interval[0, p - 1], OR + * - If q = 2m: Verify that xQ and yQ are bit strings of length m bits. + * Returns 1 if the public key has a valid range, otherwise it returns 0. + */ +static int ec_key_public_range_check(BN_CTX *ctx, const EC_KEY *key) { - int ok = 0; - BN_CTX *ctx = NULL; - const BIGNUM *order = NULL; - EC_POINT *point = NULL; + int ret = 0; + BIGNUM *x, *y; + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates(key->group, key->pub_key, x, y, ctx)) + goto err; + + if (EC_GROUP_get_field_type(key->group) == NID_X9_62_prime_field) { + if (BN_is_negative(x) + || BN_cmp(x, key->group->field) >= 0 + || BN_is_negative(y) + || BN_cmp(y, key->group->field) >= 0) { + goto err; + } + } else { + int m = EC_GROUP_get_degree(key->group); + if (BN_num_bits(x) > m || BN_num_bits(y) > m) { + goto err; + } + } + ret = 1; +err: + BN_CTX_end(ctx); + return ret; +} + +/* + * ECC Partial Public-Key Validation as specified in SP800-56A R3 + * Section 5.6.2.3.4 ECC Partial Public-Key Validation Routine. + */ +int ossl_ec_key_public_check_quick(const EC_KEY *eckey, BN_CTX *ctx) +{ if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) { - ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } + /* 5.6.2.3.3 (Step 1): Q != infinity */ if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { - ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY); - goto err; + ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); + return 0; } - if ((ctx = BN_CTX_new()) == NULL) - goto err; - if ((point = EC_POINT_new(eckey->group)) == NULL) - goto err; + /* 5.6.2.3.3 (Step 2) Test if the public key is in range */ + if (!ec_key_public_range_check(ctx, eckey)) { + ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } - /* testing whether the pub_key is on the elliptic curve */ + /* 5.6.2.3.3 (Step 3) is the pub_key on the elliptic curve */ if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { - ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); - goto err; + ERR_raise(ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE); + return 0; } - /* testing whether pub_key * order is the point at infinity */ + return 1; +} + +/* + * ECC Key validation as specified in SP800-56A R3. + * Section 5.6.2.3.3 ECC Full Public-Key Validation Routine. + */ +int ossl_ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx) +{ + int ret = 0; + EC_POINT *point = NULL; + const BIGNUM *order = NULL; + + if (!ossl_ec_key_public_check_quick(eckey, ctx)) + return 0; + + point = EC_POINT_new(eckey->group); + if (point == NULL) + return 0; + order = eckey->group->order; if (BN_is_zero(order)) { - ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); goto err; } + /* 5.6.2.3.3 (Step 4) : pub_key * order is the point at infinity. */ if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { - ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (!EC_POINT_is_at_infinity(eckey->group, point)) { - ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER); + ERR_raise(ERR_LIB_EC, EC_R_WRONG_ORDER); goto err; } - /* - * in case the priv_key is present : check if generator * priv_key == - * pub_key - */ + ret = 1; +err: + EC_POINT_free(point); + return ret; +} + +/* + * ECC Key validation as specified in SP800-56A R3. + * Section 5.6.2.1.2 Owner Assurance of Private-Key Validity + * The private key is in the range [1, order-1] + */ +int ossl_ec_key_private_check(const EC_KEY *eckey) +{ + if (eckey == NULL || eckey->group == NULL || eckey->priv_key == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (BN_cmp(eckey->priv_key, BN_value_one()) < 0 + || BN_cmp(eckey->priv_key, eckey->group->order) >= 0) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY); + return 0; + } + return 1; +} + +/* + * ECC Key validation as specified in SP800-56A R3. + * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency (b) + * Check if generator * priv_key = pub_key + */ +int ossl_ec_key_pairwise_check(const EC_KEY *eckey, BN_CTX *ctx) +{ + int ret = 0; + EC_POINT *point = NULL; + + if (eckey == NULL + || eckey->group == NULL + || eckey->pub_key == NULL + || eckey->priv_key == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + point = EC_POINT_new(eckey->group); + if (point == NULL) + goto err; + + + if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) { + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY); + goto err; + } + ret = 1; +err: + EC_POINT_free(point); + return ret; +} + + +/* + * ECC Key validation as specified in SP800-56A R3. + * Section 5.6.2.3.3 ECC Full Public-Key Validation + * Section 5.6.2.1.2 Owner Assurance of Private-Key Validity + * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency + * NOTES: + * Before calling this method in fips mode, there should be an assurance that + * an approved elliptic-curve group is used. + * Returns 1 if the key is valid, otherwise it returns 0. + */ +int ossl_ec_key_simple_check_key(const EC_KEY *eckey) +{ + int ok = 0; + BN_CTX *ctx = NULL; + + if (eckey == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL) + return 0; + + if (!ossl_ec_key_public_check(eckey, ctx)) + goto err; + if (eckey->priv_key != NULL) { - if (BN_cmp(eckey->priv_key, order) >= 0) { - ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER); - goto err; - } - if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, - NULL, NULL, ctx)) { - ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB); + if (!ossl_ec_key_private_check(eckey) + || !ossl_ec_key_pairwise_check(eckey, ctx)) goto err; - } - if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { - ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); - goto err; - } } ok = 1; - err: +err: BN_CTX_free(ctx); - EC_POINT_free(point); return ok; } @@ -344,11 +604,10 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, int ok = 0; if (key == NULL || key->group == NULL || x == NULL || y == NULL) { - ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, - ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(key->libctx); if (ctx == NULL) return 0; @@ -369,17 +628,15 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, goto err; /* - * Check if retrieved coordinates match originals and are less than field - * order: if not values are out of range. + * Check if retrieved coordinates match originals. The range check is done + * inside EC_KEY_check_key(). */ - if (BN_cmp(x, tx) || BN_cmp(y, ty) - || (BN_cmp(x, key->group->field) >= 0) - || (BN_cmp(y, key->group->field) >= 0)) { - ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, - EC_R_COORDINATES_OUT_OF_RANGE); + if (BN_cmp(x, tx) || BN_cmp(y, ty)) { + ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); goto err; } + /* EC_KEY_set_public_key updates dirty_cnt */ if (!EC_KEY_set_public_key(key, point)) goto err; @@ -396,6 +653,22 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, } +OSSL_LIB_CTX *ossl_ec_key_get_libctx(const EC_KEY *key) +{ + return key->libctx; +} + +const char *ossl_ec_key_get0_propq(const EC_KEY *key) +{ + return key->propq; +} + +void ossl_ec_key_set0_libctx(EC_KEY *key, OSSL_LIB_CTX *libctx) +{ + key->libctx = libctx; + /* Do we need to propagate this to the group? */ +} + const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) { return key->group; @@ -407,6 +680,10 @@ int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) return 0; EC_GROUP_free(key->group); key->group = EC_GROUP_dup(group); + if (key->group != NULL && EC_GROUP_get_curve_name(key->group) == NID_sm2) + EC_KEY_set_flags(key, EC_FLAG_SM2_RANGE); + + key->dirty_cnt++; return (key->group == NULL) ? 0 : 1; } @@ -505,6 +782,7 @@ int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) BN_clear_free(key->priv_key); key->priv_key = tmp_key; + key->dirty_cnt++; return 1; } @@ -521,6 +799,7 @@ int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) return 0; EC_POINT_free(key->pub_key); key->pub_key = EC_POINT_dup(pub_key, key->group); + key->dirty_cnt++; return (key->pub_key == NULL) ? 0 : 1; } @@ -552,12 +831,14 @@ void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) EC_GROUP_set_asn1_flag(key->group, flag); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) { if (key->group == NULL) return 0; return EC_GROUP_precompute_mult(key->group, ctx); } +#endif int EC_KEY_get_flags(const EC_KEY *key) { @@ -567,11 +848,13 @@ int EC_KEY_get_flags(const EC_KEY *key) void EC_KEY_set_flags(EC_KEY *key, int flags) { key->flags |= flags; + key->dirty_cnt++; } void EC_KEY_clear_flags(EC_KEY *key, int flags) { key->flags &= ~flags; + key->dirty_cnt++; } int EC_KEY_decoded_from_explicit_params(const EC_KEY *key) @@ -600,6 +883,7 @@ int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, return 0; if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0) return 0; + key->dirty_cnt++; /* * Save the point conversion form. * For non-custom curves the first octet of the buffer (excluding @@ -618,15 +902,15 @@ size_t EC_KEY_priv2oct(const EC_KEY *eckey, if (eckey->group == NULL || eckey->group->meth == NULL) return 0; if (eckey->group->meth->priv2oct == NULL) { - ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } return eckey->group->meth->priv2oct(eckey, buf, len); } -size_t ec_key_simple_priv2oct(const EC_KEY *eckey, - unsigned char *buf, size_t len) +size_t ossl_ec_key_simple_priv2oct(const EC_KEY *eckey, + unsigned char *buf, size_t len) { size_t buf_len; @@ -641,7 +925,7 @@ size_t ec_key_simple_priv2oct(const EC_KEY *eckey, /* Octetstring may need leading zeros if BN is to short */ if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) { - ECerr(EC_F_EC_KEY_SIMPLE_PRIV2OCT, EC_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); return 0; } @@ -650,27 +934,34 @@ size_t ec_key_simple_priv2oct(const EC_KEY *eckey, int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len) { + int ret; + if (eckey->group == NULL || eckey->group->meth == NULL) return 0; if (eckey->group->meth->oct2priv == NULL) { - ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - return eckey->group->meth->oct2priv(eckey, buf, len); + ret = eckey->group->meth->oct2priv(eckey, buf, len); + if (ret == 1) + eckey->dirty_cnt++; + return ret; } -int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len) +int ossl_ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, + size_t len) { if (eckey->priv_key == NULL) eckey->priv_key = BN_secure_new(); if (eckey->priv_key == NULL) { - ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } if (BN_bin2bn(buf, len, eckey->priv_key) == NULL) { - ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } + eckey->dirty_cnt++; return 1; } @@ -683,7 +974,7 @@ size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf) if (len == 0) return 0; if ((buf = OPENSSL_malloc(len)) == NULL) { - ECerr(EC_F_EC_KEY_PRIV2BUF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } len = EC_KEY_priv2oct(eckey, buf, len); @@ -702,3 +993,45 @@ int EC_KEY_can_sign(const EC_KEY *eckey) return 0; return 1; } + +/* + * FIPS 140-2 IG 9.9 AS09.33 + * Perform a sign/verify operation. + * + * NOTE: When generating keys for key-agreement schemes - FIPS 140-2 IG 9.9 + * states that no additional pairwise tests are required (apart from the tests + * specified in SP800-56A) when generating keys. Hence pairwise ECDH tests are + * omitted here. + */ +static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb, + void *cbarg) +{ + int ret = 0; + unsigned char dgst[16] = {0}; + int dgst_len = (int)sizeof(dgst); + ECDSA_SIG *sig = NULL; + OSSL_SELF_TEST *st = NULL; + + st = OSSL_SELF_TEST_new(cb, cbarg); + if (st == NULL) + return 0; + + OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, + OSSL_SELF_TEST_DESC_PCT_ECDSA); + + sig = ECDSA_do_sign(dgst, dgst_len, eckey); + if (sig == NULL) + goto err; + + OSSL_SELF_TEST_oncorrupt_byte(st, dgst); + + if (ECDSA_do_verify(dgst, dgst_len, sig, eckey) != 1) + goto err; + + ret = 1; +err: + OSSL_SELF_TEST_onend(st, ret); + OSSL_SELF_TEST_free(st); + ECDSA_SIG_free(sig); + return ret; +} diff --git a/crypto/openssl/crypto/ec/ec_kmeth.c b/crypto/openssl/crypto/ec/ec_kmeth.c index 53a4a9295201..8c011635cb42 100644 --- a/crypto/openssl/crypto/ec/ec_kmeth.c +++ b/crypto/openssl/crypto/ec/ec_kmeth.c @@ -1,15 +1,23 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDH and ECDSA low level APIs are deprecated for public use, but still ok + * for internal use. + */ +#include "internal/deprecated.h" + #include #include -#include +#ifndef FIPS_MODULE +# include +#endif #include #include "ec_local.h" @@ -59,7 +67,7 @@ int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) if (finish != NULL) finish(key); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) ENGINE_finish(key->engine); key->engine = NULL; #endif @@ -70,28 +78,37 @@ int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) return 1; } -EC_KEY *EC_KEY_new_method(ENGINE *engine) +EC_KEY *ossl_ec_key_new_method_int(OSSL_LIB_CTX *libctx, const char *propq, + ENGINE *engine) { EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return NULL; } + ret->libctx = libctx; + if (propq != NULL) { + ret->propq = OPENSSL_strdup(propq); + if (ret->propq == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + } + ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return NULL; + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; } ret->meth = EC_KEY_get_default_method(); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) if (engine != NULL) { if (!ENGINE_init(engine)) { - ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ENGINE_LIB); goto err; } ret->engine = engine; @@ -100,7 +117,7 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine) if (ret->engine != NULL) { ret->meth = ENGINE_get_EC(ret->engine); if (ret->meth == NULL) { - ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ENGINE_LIB); goto err; } } @@ -109,12 +126,15 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine) ret->version = 1; ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; +/* No ex_data inside the FIPS provider */ +#ifndef FIPS_MODULE if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) { goto err; } +#endif if (ret->meth->init != NULL && ret->meth->init(ret) == 0) { - ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_INIT_FAIL); + ERR_raise(ERR_LIB_EC, ERR_R_INIT_FAIL); goto err; } return ret; @@ -124,6 +144,13 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine) return NULL; } +#ifndef FIPS_MODULE +EC_KEY *EC_KEY_new_method(ENGINE *engine) +{ + return ossl_ec_key_new_method_int(NULL, NULL, engine); +} +#endif + int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *eckey, void *(*KDF) (const void *in, size_t inlen, void *out, @@ -132,11 +159,11 @@ int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, unsigned char *sec = NULL; size_t seclen; if (eckey->meth->compute_key == NULL) { - ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_OPERATION_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED); return 0; } if (outlen > INT_MAX) { - ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_INVALID_OUTPUT_LENGTH); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_OUTPUT_LENGTH); return 0; } if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey)) diff --git a/crypto/openssl/crypto/ec/ec_lib.c b/crypto/openssl/crypto/ec/ec_lib.c index 08db89fceeb5..b1696d93bd6d 100644 --- a/crypto/openssl/crypto/ec/ec_lib.c +++ b/crypto/openssl/crypto/ec/ec_lib.c @@ -1,41 +1,58 @@ /* - * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2022 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 + * 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 +/* + * EC_GROUP low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" +#include +#include +#include #include #include - +#include "crypto/ec.h" +#include "internal/nelem.h" #include "ec_local.h" /* functions for EC_GROUP objects */ -EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) +EC_GROUP *ossl_ec_group_new_ex(OSSL_LIB_CTX *libctx, const char *propq, + const EC_METHOD *meth) { EC_GROUP *ret; if (meth == NULL) { - ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL); + ERR_raise(ERR_LIB_EC, EC_R_SLOT_FULL); return NULL; } if (meth->group_init == 0) { - ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return NULL; } ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return NULL; } + ret->libctx = libctx; + if (propq != NULL) { + ret->propq = OPENSSL_strdup(propq); + if (ret->propq == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + } ret->meth = meth; if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) { ret->order = BN_new(); @@ -45,7 +62,7 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) if (ret->cofactor == NULL) goto err; } - ret->asn1_flag = OPENSSL_EC_NAMED_CURVE; + ret->asn1_flag = OPENSSL_EC_EXPLICIT_CURVE; ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; if (!meth->group_init(ret)) goto err; @@ -54,10 +71,20 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) err: BN_free(ret->order); BN_free(ret->cofactor); + OPENSSL_free(ret->propq); OPENSSL_free(ret); return NULL; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 +# ifndef FIPS_MODULE +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) +{ + return ossl_ec_group_new_ex(NULL, NULL, meth); +} +# endif +#endif + void EC_pre_comp_free(EC_GROUP *group) { switch (group->pre_comp_type) { @@ -105,9 +132,11 @@ void EC_GROUP_free(EC_GROUP *group) BN_free(group->order); BN_free(group->cofactor); OPENSSL_free(group->seed); + OPENSSL_free(group->propq); OPENSSL_free(group); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 void EC_GROUP_clear_free(EC_GROUP *group) { if (!group) @@ -126,20 +155,22 @@ void EC_GROUP_clear_free(EC_GROUP *group) OPENSSL_clear_free(group->seed, group->seed_len); OPENSSL_clear_free(group, sizeof(*group)); } +#endif int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) { if (dest->meth->group_copy == 0) { - ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (dest->meth != src->meth) { - ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } if (dest == src) return 1; + dest->libctx = src->libctx; dest->curve_name = src->curve_name; /* Copy precomputed */ @@ -216,7 +247,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) if (src->seed) { OPENSSL_free(dest->seed); if ((dest->seed = OPENSSL_malloc(src->seed_len)) == NULL) { - ECerr(EC_F_EC_GROUP_COPY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } if (!memcpy(dest->seed, src->seed, src->seed_len)) @@ -239,7 +270,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) if (a == NULL) return NULL; - if ((t = EC_GROUP_new(a->meth)) == NULL) + if ((t = ossl_ec_group_new_ex(a->libctx, a->propq, a->meth)) == NULL) return NULL; if (!EC_GROUP_copy(t, a)) goto err; @@ -254,6 +285,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) return t; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) { return group->meth; @@ -263,6 +295,7 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth) { return meth->field_type; } +#endif static int ec_precompute_mont_data(EC_GROUP *); @@ -295,7 +328,7 @@ static int ec_guess_cofactor(EC_GROUP *group) { return 1; } - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(group->libctx)) == NULL) return 0; BN_CTX_start(ctx); @@ -331,14 +364,14 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor) { if (generator == NULL) { - ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 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); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); return 0; } @@ -349,7 +382,7 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, */ 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); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); return 0; } @@ -359,7 +392,7 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, * 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); + ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_COFACTOR); return 0; } @@ -447,6 +480,10 @@ const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group) void EC_GROUP_set_curve_name(EC_GROUP *group, int nid) { group->curve_name = nid; + group->asn1_flag = + (nid != NID_undef) + ? OPENSSL_EC_NAMED_CURVE + : OPENSSL_EC_EXPLICIT_CURVE; } int EC_GROUP_get_curve_name(const EC_GROUP *group) @@ -454,6 +491,16 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group) return group->curve_name; } +const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group) +{ + return group->field; +} + +int EC_GROUP_get_field_type(const EC_GROUP *group) +{ + return group->meth->field_type; +} + void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) { group->asn1_flag = flag; @@ -486,7 +533,7 @@ size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len) return 1; if ((group->seed = OPENSSL_malloc(len)) == NULL) { - ECerr(EC_F_EC_GROUP_SET_SEED, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } memcpy(group->seed, p, len); @@ -509,7 +556,7 @@ int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { if (group->meth->group_set_curve == 0) { - ECerr(EC_F_EC_GROUP_SET_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } return group->meth->group_set_curve(group, p, a, b, ctx); @@ -519,13 +566,13 @@ int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) { if (group->meth->group_get_curve == NULL) { - ECerr(EC_F_EC_GROUP_GET_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } return group->meth->group_get_curve(group, p, a, b, ctx); } -#if OPENSSL_API_COMPAT < 0x10200000L +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { @@ -556,7 +603,7 @@ int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, int EC_GROUP_get_degree(const EC_GROUP *group) { if (group->meth->group_get_degree == 0) { - ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } return group->meth->group_get_degree(group); @@ -565,8 +612,7 @@ int EC_GROUP_get_degree(const EC_GROUP *group) int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) { if (group->meth->group_check_discriminant == 0) { - ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } return group->meth->group_check_discriminant(group, ctx); @@ -576,11 +622,12 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) { int r = 0; BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; +#ifndef FIPS_MODULE BN_CTX *ctx_new = NULL; +#endif /* compare the field types */ - if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != - EC_METHOD_get_field_type(EC_GROUP_method_of(b))) + if (EC_GROUP_get_field_type(a) != EC_GROUP_get_field_type(b)) return 1; /* compare the curve name (if present in both) */ if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && @@ -589,8 +636,10 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE) return 0; +#ifndef FIPS_MODULE if (ctx == NULL) ctx_new = ctx = BN_CTX_new(); +#endif if (ctx == NULL) return -1; @@ -603,7 +652,9 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) b3 = BN_CTX_get(ctx); if (b3 == NULL) { BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(ctx_new); +#endif return -1; } @@ -615,33 +666,47 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) !b->meth->group_get_curve(b, b1, b2, b3, ctx)) r = 1; - if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3)) + /* return 1 if the curve parameters are different */ + if (r || BN_cmp(a1, b1) != 0 || BN_cmp(a2, b2) != 0 || BN_cmp(a3, b3) != 0) r = 1; /* XXX EC_POINT_cmp() assumes that the methods are equal */ + /* return 1 if the generators are different */ if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a), - EC_GROUP_get0_generator(b), ctx)) + EC_GROUP_get0_generator(b), ctx) != 0) r = 1; if (!r) { const BIGNUM *ao, *bo, *ac, *bc; - /* compare the order and cofactor */ + /* compare the orders */ ao = EC_GROUP_get0_order(a); bo = EC_GROUP_get0_order(b); - ac = EC_GROUP_get0_cofactor(a); - bc = EC_GROUP_get0_cofactor(b); if (ao == NULL || bo == NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx_new); - return -1; + /* return an error if either order is NULL */ + r = -1; + goto end; } - if (BN_cmp(ao, bo) || BN_cmp(ac, bc)) + if (BN_cmp(ao, bo) != 0) { + /* return 1 if orders are different */ r = 1; + goto end; + } + /* + * It gets here if the curve parameters and generator matched. + * Now check the optional cofactors (if both are present). + */ + ac = EC_GROUP_get0_cofactor(a); + bc = EC_GROUP_get0_cofactor(b); + /* Returns 1 (mismatch) if both cofactors are specified and different */ + if (!BN_is_zero(ac) && !BN_is_zero(bc) && BN_cmp(ac, bc) != 0) + r = 1; + /* Returns 0 if the parameters matched */ } - +end: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(ctx_new); - +#endif return r; } @@ -652,17 +717,17 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) EC_POINT *ret; if (group == NULL) { - ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (group->meth->point_init == NULL) { - ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return NULL; } ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return NULL; } @@ -679,7 +744,7 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) void EC_POINT_free(EC_POINT *point) { - if (!point) + if (point == NULL) return; if (point->meth->point_finish != 0) @@ -689,7 +754,7 @@ void EC_POINT_free(EC_POINT *point) void EC_POINT_clear_free(EC_POINT *point) { - if (!point) + if (point == NULL) return; if (point->meth->point_clear_finish != 0) @@ -702,14 +767,14 @@ void EC_POINT_clear_free(EC_POINT *point) int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) { if (dest->meth->point_copy == 0) { - ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (dest->meth != src->meth || (dest->curve_name != src->curve_name - && dest->curve_name != 0 - && src->curve_name != 0)) { - ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS); + && dest->curve_name != 0 + && src->curve_name != 0)) { + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } if (dest == src) @@ -736,42 +801,42 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) return t; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 const EC_METHOD *EC_POINT_method_of(const EC_POINT *point) { return point->meth; } +#endif int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) { if (group->meth->point_set_to_infinity == 0) { - ECerr(EC_F_EC_POINT_SET_TO_INFINITY, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } return group->meth->point_set_to_infinity(group, point); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) { - if (group->meth->point_set_Jprojective_coordinates_GFp == 0) { - ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + if (group->meth->field_type != NID_X9_62_prime_field) { + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(point, group)) { - ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, - EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, - y, z, ctx); + return ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, + x, y, z, ctx); } int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, @@ -779,44 +844,42 @@ int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) { - if (group->meth->point_get_Jprojective_coordinates_GFp == 0) { - ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + if (group->meth->field_type != NID_X9_62_prime_field) { + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(point, group)) { - ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, - EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, - y, z, ctx); + return ossl_ec_GFp_simple_get_Jprojective_coordinates_GFp(group, point, + x, y, z, ctx); } +#endif int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { if (group->meth->point_set_affine_coordinates == NULL) { - ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(point, group)) { - ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx)) return 0; if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { - ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES, EC_R_POINT_IS_NOT_ON_CURVE); + ERR_raise(ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE); return 0; } return 1; } -#if OPENSSL_API_COMPAT < 0x10200000L +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) @@ -839,22 +902,21 @@ int EC_POINT_get_affine_coordinates(const EC_GROUP *group, BN_CTX *ctx) { if (group->meth->point_get_affine_coordinates == NULL) { - ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(point, group)) { - ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY); + ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); return 0; } return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); } -#if OPENSSL_API_COMPAT < 0x10200000L +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx) @@ -876,12 +938,12 @@ int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { if (group->meth->add == 0) { - ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group) || !ec_point_is_compat(b, group)) { - ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } return group->meth->add(group, r, a, b, ctx); @@ -891,11 +953,11 @@ int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) { if (group->meth->dbl == 0) { - ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group)) { - ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } return group->meth->dbl(group, r, a, ctx); @@ -904,11 +966,11 @@ int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) { if (group->meth->invert == 0) { - ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(a, group)) { - ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } return group->meth->invert(group, a, ctx); @@ -917,12 +979,11 @@ int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { if (group->meth->is_at_infinity == 0) { - ECerr(EC_F_EC_POINT_IS_AT_INFINITY, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(point, group)) { - ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } return group->meth->is_at_infinity(group, point); @@ -939,11 +1000,11 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) { if (group->meth->is_on_curve == 0) { - ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(point, group)) { - ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } return group->meth->is_on_curve(group, point, ctx); @@ -953,24 +1014,25 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { if (group->meth->point_cmp == 0) { - ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; } if (!ec_point_is_compat(a, group) || !ec_point_is_compat(b, group)) { - ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return -1; } return group->meth->point_cmp(group, a, b, ctx); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { if (group->meth->make_affine == 0) { - ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(point, group)) { - ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } return group->meth->make_affine(group, point, ctx); @@ -982,17 +1044,18 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, size_t i; if (group->meth->points_make_affine == 0) { - ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } for (i = 0; i < num; i++) { if (!ec_point_is_compat(points[i], group)) { - ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } } return group->meth->points_make_affine(group, num, points, ctx); } +#endif /* * Functions for point multiplication. If group->meth->mul is 0, we use the @@ -1000,16 +1063,19 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, * methods. */ +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) { int ret = 0; size_t i = 0; +#ifndef FIPS_MODULE BN_CTX *new_ctx = NULL; +#endif if (!ec_point_is_compat(r, group)) { - ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } @@ -1018,13 +1084,17 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, for (i = 0; i < num; i++) { if (!ec_point_is_compat(points[i], group)) { - ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } } - if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) { - ECerr(EC_F_EC_POINTS_MUL, ERR_R_INTERNAL_ERROR); +#ifndef FIPS_MODULE + if (ctx == NULL) + ctx = new_ctx = BN_CTX_secure_new(); +#endif + if (ctx == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); return 0; } @@ -1032,33 +1102,61 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, ret = group->meth->mul(group, r, scalar, num, points, scalars, ctx); else /* use default */ - ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); + ret = ossl_ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } +#endif int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) { - /* just a convenient interface to EC_POINTs_mul() */ + int ret = 0; + size_t num; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif + + if (!ec_point_is_compat(r, group) + || (point != NULL && !ec_point_is_compat(point, group))) { + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } - const EC_POINT *points[1]; - const BIGNUM *scalars[1]; + if (g_scalar == NULL && p_scalar == NULL) + return EC_POINT_set_to_infinity(group, r); - points[0] = point; - scalars[0] = p_scalar; +#ifndef FIPS_MODULE + if (ctx == NULL) + ctx = new_ctx = BN_CTX_secure_new(); +#endif + if (ctx == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); + return 0; + } + + num = (point != NULL && p_scalar != NULL) ? 1 : 0; + if (group->meth->mul != NULL) + ret = group->meth->mul(group, r, g_scalar, num, &point, &p_scalar, ctx); + else + /* use default */ + ret = ossl_ec_wNAF_mul(group, r, g_scalar, num, &point, &p_scalar, ctx); - return EC_POINTs_mul(group, r, g_scalar, - (point != NULL - && p_scalar != NULL), points, scalars, ctx); +#ifndef FIPS_MODULE + BN_CTX_free(new_ctx); +#endif + return ret; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { if (group->meth->mul == 0) /* use default */ - return ec_wNAF_precompute_mult(group, ctx); + return ossl_ec_wNAF_precompute_mult(group, ctx); if (group->meth->precompute_mult != 0) return group->meth->precompute_mult(group, ctx); @@ -1070,7 +1168,7 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group) { if (group->meth->mul == 0) /* use default */ - return ec_wNAF_have_precompute_mult(group); + return ossl_ec_wNAF_have_precompute_mult(group); if (group->meth->have_precompute_mult != 0) return group->meth->have_precompute_mult(group); @@ -1078,6 +1176,7 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group) return 0; /* cannot tell whether precomputation has * been performed */ } +#endif /* * ec_precompute_mont_data sets |group->mont_data| from |group->order| and @@ -1085,7 +1184,7 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group) */ static int ec_precompute_mont_data(EC_GROUP *group) { - BN_CTX *ctx = BN_CTX_new(); + BN_CTX *ctx = BN_CTX_new_ex(group->libctx); int ret = 0; BN_MONT_CTX_free(group->mont_data); @@ -1112,6 +1211,7 @@ static int ec_precompute_mont_data(EC_GROUP *group) return ret; } +#ifndef FIPS_MODULE int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg) { return CRYPTO_set_ex_data(&key->ex_data, idx, arg); @@ -1121,8 +1221,9 @@ void *EC_KEY_get_ex_data(const EC_KEY *key, int idx) { return CRYPTO_get_ex_data(&key->ex_data, idx); } +#endif -int ec_group_simple_order_bits(const EC_GROUP *group) +int ossl_ec_group_simple_order_bits(const EC_GROUP *group) { if (group->order == NULL) return 0; @@ -1133,13 +1234,19 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r, const BIGNUM *x, BN_CTX *ctx) { BIGNUM *e = NULL; - BN_CTX *new_ctx = NULL; int ret = 0; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif if (group->mont_data == NULL) return 0; - if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) +#ifndef FIPS_MODULE + if (ctx == NULL) + ctx = new_ctx = BN_CTX_secure_new(); +#endif + if (ctx == NULL) return 0; BN_CTX_start(ctx); @@ -1165,7 +1272,9 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r, err: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } @@ -1182,8 +1291,8 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r, * EC_METHODs must implement their own field_inverse_mod_ord for * other functionality. */ -int ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res, - const BIGNUM *x, BN_CTX *ctx) +int ossl_ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res, + const BIGNUM *x, BN_CTX *ctx) { if (group->meth->field_inverse_mod_ord != NULL) return group->meth->field_inverse_mod_ord(group, res, x, ctx); @@ -1201,10 +1310,451 @@ int ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res, * This wrapper returns 1 in case the underlying EC_METHOD does not * support coordinate blinding. */ -int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) +int ossl_ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, + BN_CTX *ctx) { if (group->meth->blind_coordinates == NULL) return 1; /* ignore if not implemented */ return group->meth->blind_coordinates(group, p, ctx); } + +int EC_GROUP_get_basis_type(const EC_GROUP *group) +{ + int i; + + if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field) + /* everything else is currently not supported */ + return 0; + + /* Find the last non-zero element of group->poly[] */ + for (i = 0; + i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0; + i++) + continue; + + if (i == 4) + return NID_X9_62_ppBasis; + else if (i == 2) + return NID_X9_62_tpBasis; + else + /* everything else is currently not supported */ + return 0; +} + +#ifndef OPENSSL_NO_EC2M +int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) +{ + if (group == NULL) + return 0; + + if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field + || !((group->poly[0] != 0) && (group->poly[1] != 0) + && (group->poly[2] == 0))) { + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (k) + *k = group->poly[1]; + + return 1; +} + +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, + unsigned int *k2, unsigned int *k3) +{ + if (group == NULL) + return 0; + + if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field + || !((group->poly[0] != 0) && (group->poly[1] != 0) + && (group->poly[2] != 0) && (group->poly[3] != 0) + && (group->poly[4] == 0))) { + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (k1) + *k1 = group->poly[3]; + if (k2) + *k2 = group->poly[2]; + if (k3) + *k3 = group->poly[1]; + + return 1; +} +#endif + +#ifndef FIPS_MODULE +/* + * Check if the explicit parameters group matches any 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. + */ +static EC_GROUP *ec_group_explicit_to_named(const EC_GROUP *group, + OSSL_LIB_CTX *libctx, + const char *propq, + BN_CTX *ctx) +{ + EC_GROUP *ret_group = NULL, *dup = NULL; + int curve_name_nid; + + const EC_POINT *point = EC_GROUP_get0_generator(group); + const BIGNUM *order = EC_GROUP_get0_order(group); + int no_seed = (EC_GROUP_get0_seed(group) == NULL); + + if ((dup = EC_GROUP_dup(group)) == NULL + || EC_GROUP_set_seed(dup, NULL, 0) != 1 + || !EC_GROUP_set_generator(dup, point, order, NULL)) + goto err; + if ((curve_name_nid = ossl_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. + */ + +# 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 == NID_wap_wsg_idm_ecid_wtls12) + curve_name_nid = NID_secp224r1; +# endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */ + + ret_group = EC_GROUP_new_by_curve_name_ex(libctx, propq, curve_name_nid); + if (ret_group == NULL) + goto err; + + /* + * Set the flag so that EC_GROUPs created from explicit parameters are + * serialized using explicit parameters by default. + */ + EC_GROUP_set_asn1_flag(ret_group, OPENSSL_EC_EXPLICIT_CURVE); + + /* + * If the input params do not contain the optional seed field we make + * sure it is not added to the returned group. + * + * The seed field is not really used inside libcrypto anyway, and + * adding it to parsed explicit parameter keys would alter their DER + * encoding output (because of the extra field) which could impact + * applications fingerprinting keys by their DER encoding. + */ + if (no_seed) { + if (EC_GROUP_set_seed(ret_group, NULL, 0) != 1) + goto err; + } + } else { + ret_group = (EC_GROUP *)group; + } + EC_GROUP_free(dup); + return ret_group; +err: + EC_GROUP_free(dup); + EC_GROUP_free(ret_group); + return NULL; +} +#endif /* FIPS_MODULE */ + +static EC_GROUP *group_new_from_name(const OSSL_PARAM *p, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int ok = 0, nid; + const char *curve_name = NULL; + + switch (p->data_type) { + case OSSL_PARAM_UTF8_STRING: + /* The OSSL_PARAM functions have no support for this */ + curve_name = p->data; + ok = (curve_name != NULL); + break; + case OSSL_PARAM_UTF8_PTR: + ok = OSSL_PARAM_get_utf8_ptr(p, &curve_name); + break; + } + + if (ok) { + nid = ossl_ec_curve_name2nid(curve_name); + if (nid == NID_undef) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); + return NULL; + } else { + return EC_GROUP_new_by_curve_name_ex(libctx, propq, nid); + } + } + return NULL; +} + +/* These parameters can be set directly into an EC_GROUP */ +int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[]) +{ + int encoding_flag = -1, format = -1; + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT); + if (p != NULL) { + if (!ossl_ec_pt_format_param2id(p, &format)) { + ECerr(0, EC_R_INVALID_FORM); + return 0; + } + EC_GROUP_set_point_conversion_form(group, format); + } + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING); + if (p != NULL) { + if (!ossl_ec_encoding_param2id(p, &encoding_flag)) { + ECerr(0, EC_R_INVALID_FORM); + return 0; + } + EC_GROUP_set_asn1_flag(group, encoding_flag); + } + /* Optional seed */ + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED); + if (p != NULL) { + /* The seed is allowed to be NULL */ + if (p->data_type != OSSL_PARAM_OCTET_STRING + || !EC_GROUP_set_seed(group, p->data, p->data_size)) { + ECerr(0, EC_R_INVALID_SEED); + return 0; + } + } + return 1; +} + +EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], + OSSL_LIB_CTX *libctx, const char *propq) +{ + const OSSL_PARAM *ptmp; + EC_GROUP *group = NULL; + +#ifndef FIPS_MODULE + const OSSL_PARAM *pa, *pb; + int ok = 0; + EC_GROUP *named_group = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL, *order = NULL, *cofactor = NULL; + EC_POINT *point = NULL; + int field_bits = 0; + int is_prime_field = 1; + BN_CTX *bnctx = NULL; + const unsigned char *buf = NULL; + int encoding_flag = -1; +#endif + + /* This is the simple named group case */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); + if (ptmp != NULL) { + int decoded = 0; + + if ((group = group_new_from_name(ptmp, libctx, propq)) == NULL) + return NULL; + if (!ossl_ec_group_set_params(group, params)) { + EC_GROUP_free(group); + return NULL; + } + + ptmp = OSSL_PARAM_locate_const(params, + OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS); + if (ptmp != NULL && !OSSL_PARAM_get_int(ptmp, &decoded)) { + ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS); + EC_GROUP_free(group); + return NULL; + } + group->decoded_from_explicit_params = decoded > 0; + return group; + } +#ifdef FIPS_MODULE + ERR_raise(ERR_LIB_EC, EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED); + return NULL; +#else + /* If it gets here then we are trying explicit parameters */ + bnctx = BN_CTX_new_ex(libctx); + if (bnctx == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + return 0; + } + BN_CTX_start(bnctx); + + p = BN_CTX_get(bnctx); + a = BN_CTX_get(bnctx); + b = BN_CTX_get(bnctx); + order = BN_CTX_get(bnctx); + if (order == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE); + if (ptmp == NULL || ptmp->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); + goto err; + } + if (OPENSSL_strcasecmp(ptmp->data, SN_X9_62_prime_field) == 0) { + is_prime_field = 1; + } else if (OPENSSL_strcasecmp(ptmp->data, + SN_X9_62_characteristic_two_field) == 0) { + is_prime_field = 0; + } else { + /* Invalid field */ + ERR_raise(ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD); + goto err; + } + + pa = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_A); + if (!OSSL_PARAM_get_BN(pa, &a)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_A); + goto err; + } + pb = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_B); + if (!OSSL_PARAM_get_BN(pb, &b)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_B); + goto err; + } + + /* extract the prime number or irreducible polynomial */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_P); + if (!OSSL_PARAM_get_BN(ptmp, &p)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_P); + goto err; + } + + if (is_prime_field) { + if (BN_is_negative(p) || BN_is_zero(p)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_P); + goto err; + } + field_bits = BN_num_bits(p); + if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { + ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE); + goto err; + } + + /* create the EC_GROUP structure */ + group = EC_GROUP_new_curve_GFp(p, a, b, bnctx); + } else { +# ifdef OPENSSL_NO_EC2M + ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); + goto err; +# else + /* create the EC_GROUP structure */ + group = EC_GROUP_new_curve_GF2m(p, a, b, NULL); + if (group != NULL) { + field_bits = EC_GROUP_get_degree(group); + if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { + ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE); + goto err; + } + } +# endif /* OPENSSL_NO_EC2M */ + } + + if (group == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); + goto err; + } + + /* Optional seed */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED); + if (ptmp != NULL) { + if (ptmp->data_type != OSSL_PARAM_OCTET_STRING) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_SEED); + goto err; + } + if (!EC_GROUP_set_seed(group, ptmp->data, ptmp->data_size)) + goto err; + } + + /* generator base point */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GENERATOR); + if (ptmp == NULL + || ptmp->data_type != OSSL_PARAM_OCTET_STRING) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); + goto err; + } + buf = (const unsigned char *)(ptmp->data); + if ((point = EC_POINT_new(group)) == NULL) + goto err; + EC_GROUP_set_point_conversion_form(group, + (point_conversion_form_t)buf[0] & ~0x01); + if (!EC_POINT_oct2point(group, point, buf, ptmp->data_size, bnctx)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); + goto err; + } + + /* order */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ORDER); + if (!OSSL_PARAM_get_BN(ptmp, &order) + || (BN_is_negative(order) || BN_is_zero(order)) + || (BN_num_bits(order) > (int)field_bits + 1)) { /* Hasse bound */ + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); + goto err; + } + + /* Optional cofactor */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_COFACTOR); + if (ptmp != NULL) { + cofactor = BN_CTX_get(bnctx); + if (cofactor == NULL || !OSSL_PARAM_get_BN(ptmp, &cofactor)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_COFACTOR); + goto err; + } + } + + /* set the generator, order and cofactor (if present) */ + if (!EC_GROUP_set_generator(group, point, order, cofactor)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); + goto err; + } + + named_group = ec_group_explicit_to_named(group, libctx, propq, bnctx); + if (named_group == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_NAMED_GROUP_CONVERSION); + goto err; + } + if (named_group == group) { + /* + * If we did not find a named group then the encoding should be explicit + * if it was specified + */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING); + if (ptmp != NULL + && !ossl_ec_encoding_param2id(ptmp, &encoding_flag)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); + goto err; + } + if (encoding_flag == OPENSSL_EC_NAMED_CURVE) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); + goto err; + } + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE); + } else { + EC_GROUP_free(group); + group = named_group; + } + /* We've imported the group from explicit parameters, set it so. */ + group->decoded_from_explicit_params = 1; + ok = 1; + err: + if (!ok) { + EC_GROUP_free(group); + group = NULL; + } + EC_POINT_free(point); + BN_CTX_end(bnctx); + BN_CTX_free(bnctx); + + return group; +#endif /* FIPS_MODULE */ +} diff --git a/crypto/openssl/crypto/ec/ec_local.h b/crypto/openssl/crypto/ec/ec_local.h index 64725a9c92f4..f34e06aea89a 100644 --- a/crypto/openssl/crypto/ec/ec_local.h +++ b/crypto/openssl/crypto/ec/ec_local.h @@ -1,8 +1,8 @@ /* - * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 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 + * 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 @@ -31,6 +31,10 @@ /* Curve does not support signing operations */ #define EC_FLAGS_NO_SIGN 0x4 +#ifdef OPENSSL_NO_DEPRECATED_3_0 +typedef struct ec_method_st EC_METHOD; +#endif + /* * Structure details are not part of the exported interface, so all this may * change in future versions. @@ -76,14 +80,6 @@ struct ec_method_st { * EC_POINT_set_compressed_coordinates: */ int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *); - int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *, - EC_POINT *, const BIGNUM *x, - const BIGNUM *y, - const BIGNUM *z, BN_CTX *); - int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *, - const EC_POINT *, BIGNUM *x, - BIGNUM *y, BIGNUM *z, - BN_CTX *); int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *, const BIGNUM *x, const BIGNUM *y, BN_CTX *); @@ -179,6 +175,14 @@ struct ec_method_st { /* custom ECDH operation */ int (*ecdh_compute_key)(unsigned char **pout, size_t *poutlen, const EC_POINT *pub_key, const EC_KEY *ecdh); + /* custom ECDSA */ + int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinvp, + BIGNUM **rp); + ECDSA_SIG *(*ecdsa_sign_sig)(const unsigned char *dgst, int dgstlen, + const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey); + int (*ecdsa_verify_sig)(const unsigned char *dgst, int dgstlen, + const ECDSA_SIG *sig, EC_KEY *eckey); /* Inverse modulo order */ int (*field_inverse_mod_ord)(const EC_GROUP *, BIGNUM *r, const BIGNUM *x, BN_CTX *); @@ -270,6 +274,9 @@ struct ec_group_st { NISTZ256_PRE_COMP *nistz256; EC_PRE_COMP *ec; } pre_comp; + + OSSL_LIB_CTX *libctx; + char *propq; }; #define SETPRECOMP(g, type, pre) \ @@ -288,8 +295,15 @@ struct ec_key_st { point_conversion_form_t conv_form; CRYPTO_REF_COUNT references; int flags; +#ifndef FIPS_MODULE CRYPTO_EX_DATA ex_data; +#endif CRYPTO_RWLOCK *lock; + OSSL_LIB_CTX *libctx; + char *propq; + + /* Provider data */ + size_t dirty_cnt; /* If any key material changes, increment this */ }; struct ec_point_st { @@ -311,13 +325,10 @@ struct ec_point_st { static ossl_inline int ec_point_is_compat(const EC_POINT *point, const EC_GROUP *group) { - if (group->meth != point->meth - || (group->curve_name != 0 - && point->curve_name != 0 - && group->curve_name != point->curve_name)) - return 0; - - return 1; + return group->meth == point->meth + && (group->curve_name == 0 + || point->curve_name == 0 + || group->curve_name == point->curve_name); } NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *); @@ -338,249 +349,264 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *); * method functions in ec_mult.c (ec_lib.c uses these as defaults if * group->method->mul is 0) */ -int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, - size_t num, const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); -int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *); -int ec_wNAF_have_precompute_mult(const EC_GROUP *group); +int ossl_ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *); +int ossl_ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *); +int ossl_ec_wNAF_have_precompute_mult(const EC_GROUP *group); /* method functions in ecp_smpl.c */ -int ec_GFp_simple_group_init(EC_GROUP *); -void ec_GFp_simple_group_finish(EC_GROUP *); -void ec_GFp_simple_group_clear_finish(EC_GROUP *); -int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *); -int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, BN_CTX *); -int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, - BIGNUM *b, BN_CTX *); -int ec_GFp_simple_group_get_degree(const EC_GROUP *); -int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); -int ec_GFp_simple_point_init(EC_POINT *); -void ec_GFp_simple_point_finish(EC_POINT *); -void ec_GFp_simple_point_clear_finish(EC_POINT *); -int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *); -int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); -int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, - EC_POINT *, const BIGNUM *x, - const BIGNUM *y, - const BIGNUM *z, BN_CTX *); -int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, - const EC_POINT *, BIGNUM *x, - BIGNUM *y, BIGNUM *z, +int ossl_ec_GFp_simple_group_init(EC_GROUP *); +void ossl_ec_GFp_simple_group_finish(EC_GROUP *); +void ossl_ec_GFp_simple_group_clear_finish(EC_GROUP *); +int ossl_ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *); +int ossl_ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *); +int ossl_ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *); +int ossl_ec_GFp_simple_group_get_degree(const EC_GROUP *); +int ossl_ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); +int ossl_ec_GFp_simple_point_init(EC_POINT *); +void ossl_ec_GFp_simple_point_finish(EC_POINT *); +void ossl_ec_GFp_simple_point_clear_finish(EC_POINT *); +int ossl_ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *); +int ossl_ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); +int ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, + EC_POINT *, + const BIGNUM *x, + const BIGNUM *y, + const BIGNUM *z, + BN_CTX *); +int ossl_ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, + const EC_POINT *, + BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *); +int ossl_ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, + const BIGNUM *y, BN_CTX *); +int ossl_ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, + const EC_POINT *, BIGNUM *x, + BIGNUM *y, BN_CTX *); +int ossl_ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, BN_CTX *); -int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, - const BIGNUM *y, BN_CTX *); -int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, - const EC_POINT *, BIGNUM *x, - BIGNUM *y, BN_CTX *); -int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, int y_bit, - BN_CTX *); -size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *); -int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *, - const unsigned char *buf, size_t len, BN_CTX *); -int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *); -int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, - BN_CTX *); -int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); -int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); -int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); -int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, - BN_CTX *); -int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); -int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, - EC_POINT *[], BN_CTX *); -int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); -int ec_GFp_simple_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); -int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, - BN_CTX *ctx); -int ec_GFp_simple_ladder_pre(const EC_GROUP *group, - EC_POINT *r, EC_POINT *s, - EC_POINT *p, BN_CTX *ctx); -int ec_GFp_simple_ladder_step(const EC_GROUP *group, - EC_POINT *r, EC_POINT *s, - EC_POINT *p, BN_CTX *ctx); -int ec_GFp_simple_ladder_post(const EC_GROUP *group, - EC_POINT *r, EC_POINT *s, - EC_POINT *p, BN_CTX *ctx); +size_t ossl_ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *); +int ossl_ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *, + const unsigned char *buf, size_t len, BN_CTX *); +int ossl_ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *); +int ossl_ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + BN_CTX *); +int ossl_ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ossl_ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); +int ossl_ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); +int ossl_ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, + const EC_POINT *b, BN_CTX *); +int ossl_ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ossl_ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, + EC_POINT *[], BN_CTX *); +int ossl_ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ossl_ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ossl_ec_GFp_simple_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ossl_ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, + BN_CTX *ctx); +int ossl_ec_GFp_simple_ladder_pre(const EC_GROUP *group, + EC_POINT *r, EC_POINT *s, + EC_POINT *p, BN_CTX *ctx); +int ossl_ec_GFp_simple_ladder_step(const EC_GROUP *group, + EC_POINT *r, EC_POINT *s, + EC_POINT *p, BN_CTX *ctx); +int ossl_ec_GFp_simple_ladder_post(const EC_GROUP *group, + EC_POINT *r, EC_POINT *s, + EC_POINT *p, BN_CTX *ctx); /* method functions in ecp_mont.c */ -int ec_GFp_mont_group_init(EC_GROUP *); -int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -void ec_GFp_mont_group_finish(EC_GROUP *); -void ec_GFp_mont_group_clear_finish(EC_GROUP *); -int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *); -int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); -int ec_GFp_mont_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); -int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); -int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); -int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *); +int ossl_ec_GFp_mont_group_init(EC_GROUP *); +int ossl_ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, + const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +void ossl_ec_GFp_mont_group_finish(EC_GROUP *); +void ossl_ec_GFp_mont_group_clear_finish(EC_GROUP *); +int ossl_ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *); +int ossl_ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ossl_ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ossl_ec_GFp_mont_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ossl_ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ossl_ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ossl_ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *); /* method functions in ecp_nist.c */ -int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src); -int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); +int ossl_ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src); +int ossl_ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, BN_CTX *); +int ossl_ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ossl_ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); /* method functions in ec2_smpl.c */ -int ec_GF2m_simple_group_init(EC_GROUP *); -void ec_GF2m_simple_group_finish(EC_GROUP *); -void ec_GF2m_simple_group_clear_finish(EC_GROUP *); -int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *); -int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, - BN_CTX *); -int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, - BIGNUM *b, BN_CTX *); -int ec_GF2m_simple_group_get_degree(const EC_GROUP *); -int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); -int ec_GF2m_simple_point_init(EC_POINT *); -void ec_GF2m_simple_point_finish(EC_POINT *); -void ec_GF2m_simple_point_clear_finish(EC_POINT *); -int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *); -int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); -int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, - const BIGNUM *y, BN_CTX *); -int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, - const EC_POINT *, BIGNUM *x, - BIGNUM *y, BN_CTX *); -int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, int y_bit, - BN_CTX *); -size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *); -int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *, - const unsigned char *buf, size_t len, BN_CTX *); -int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *); -int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, - BN_CTX *); -int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); -int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); -int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); -int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, - BN_CTX *); -int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); -int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, - EC_POINT *[], BN_CTX *); -int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); -int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); +int ossl_ec_GF2m_simple_group_init(EC_GROUP *); +void ossl_ec_GF2m_simple_group_finish(EC_GROUP *); +void ossl_ec_GF2m_simple_group_clear_finish(EC_GROUP *); +int ossl_ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *); +int ossl_ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *); +int ossl_ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *); +int ossl_ec_GF2m_simple_group_get_degree(const EC_GROUP *); +int ossl_ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); +int ossl_ec_GF2m_simple_point_init(EC_POINT *); +void ossl_ec_GF2m_simple_point_finish(EC_POINT *); +void ossl_ec_GF2m_simple_point_clear_finish(EC_POINT *); +int ossl_ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *); +int ossl_ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); +int ossl_ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, + EC_POINT *, + const BIGNUM *x, + const BIGNUM *y, BN_CTX *); +int ossl_ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, + const EC_POINT *, BIGNUM *x, + BIGNUM *y, BN_CTX *); +int ossl_ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, + BN_CTX *); +size_t ossl_ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *); +int ossl_ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *, + const unsigned char *buf, size_t len, BN_CTX *); +int ossl_ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *); +int ossl_ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + BN_CTX *); +int ossl_ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ossl_ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); +int ossl_ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); +int ossl_ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, + const EC_POINT *b, BN_CTX *); +int ossl_ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ossl_ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, + EC_POINT *[], BN_CTX *); +int ossl_ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ossl_ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ossl_ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# ifdef B_ENDIAN +# error "Can not enable ec_nistp_64_gcc_128 on big-endian systems" +# endif + /* method functions in ecp_nistp224.c */ -int ec_GFp_nistp224_group_init(EC_GROUP *group); -int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *n, - BN_CTX *); -int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx); -int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); -int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx); -int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx); -int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group); +int ossl_ec_GFp_nistp224_group_init(EC_GROUP *group); +int ossl_ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *); +int ossl_ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); +int ossl_ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ossl_ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx); +int ossl_ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ossl_ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group); /* method functions in ecp_nistp256.c */ -int ec_GFp_nistp256_group_init(EC_GROUP *group); -int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *n, - BN_CTX *); -int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx); -int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); -int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx); -int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx); -int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group); +int ossl_ec_GFp_nistp256_group_init(EC_GROUP *group); +int ossl_ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *); +int ossl_ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); +int ossl_ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ossl_ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx); +int ossl_ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ossl_ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group); /* method functions in ecp_nistp521.c */ -int ec_GFp_nistp521_group_init(EC_GROUP *group); -int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *n, - BN_CTX *); -int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx); -int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); -int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx); -int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx); -int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group); +int ossl_ec_GFp_nistp521_group_init(EC_GROUP *group); +int ossl_ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *); +int ossl_ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); +int ossl_ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ossl_ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx); +int ossl_ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ossl_ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group); /* utility functions in ecp_nistputil.c */ -void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, - size_t felem_size, - void *tmp_felems, - void (*felem_one) (void *out), - int (*felem_is_zero) (const void - *in), - void (*felem_assign) (void *out, - const void - *in), - void (*felem_square) (void *out, - const void - *in), - void (*felem_mul) (void *out, - const void - *in1, - const void - *in2), - void (*felem_inv) (void *out, - const void - *in), - void (*felem_contract) (void - *out, - const - void - *in)); -void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, - unsigned char *digit, unsigned char in); +void ossl_ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, + size_t felem_size, + void *tmp_felems, + void (*felem_one) (void *out), + int (*felem_is_zero) + (const void *in), + void (*felem_assign) + (void *out, const void *in), + void (*felem_square) + (void *out, const void *in), + void (*felem_mul) + (void *out, + const void *in1, + const void *in2), + void (*felem_inv) + (void *out, const void *in), + void (*felem_contract) + (void *out, const void *in)); +void ossl_ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, + unsigned char *digit, + unsigned char in); #endif -int ec_group_simple_order_bits(const EC_GROUP *group); +int ossl_ec_group_simple_order_bits(const EC_GROUP *group); + +/** + * Creates a new EC_GROUP object + * \param libctx The associated library context or NULL for the default + * library context + * \param propq Any property query string + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *ossl_ec_group_new_ex(OSSL_LIB_CTX *libctx, const char *propq, + const EC_METHOD *meth); #ifdef ECP_NISTZ256_ASM /** Returns GFp methods using montgomery multiplication, with x86-64 optimized @@ -589,15 +615,21 @@ int ec_group_simple_order_bits(const EC_GROUP *group); */ const EC_METHOD *EC_GFp_nistz256_method(void); #endif +#ifdef S390X_EC_ASM +const EC_METHOD *EC_GFp_s390x_nistp256_method(void); +const EC_METHOD *EC_GFp_s390x_nistp384_method(void); +const EC_METHOD *EC_GFp_s390x_nistp521_method(void); +#endif -size_t ec_key_simple_priv2oct(const EC_KEY *eckey, - unsigned char *buf, size_t len); -int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len); -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); +size_t ossl_ec_key_simple_priv2oct(const EC_KEY *eckey, + unsigned char *buf, size_t len); +int ossl_ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, + size_t len); +int ossl_ec_key_simple_generate_key(EC_KEY *eckey); +int ossl_ec_key_simple_generate_public_key(EC_KEY *eckey); +int ossl_ec_key_simple_check_key(const EC_KEY *eckey); -int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx); +int ossl_ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx); /* EC_METHOD definitions */ @@ -630,11 +662,14 @@ struct ec_key_method_st { #define EC_KEY_METHOD_DYNAMIC 1 +EC_KEY *ossl_ec_key_new_method_int(OSSL_LIB_CTX *libctx, const char *propq, + ENGINE *engine); + int ossl_ec_key_gen(EC_KEY *eckey); int ossl_ecdh_compute_key(unsigned char **pout, size_t *poutlen, const EC_POINT *pub_key, const EC_KEY *ecdh); -int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, - const EC_POINT *pub_key, const EC_KEY *ecdh); +int ossl_ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, + const EC_POINT *pub_key, const EC_KEY *ecdh); struct ECDSA_SIG_st { BIGNUM *r; @@ -653,18 +688,14 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey); +int ossl_ecdsa_simple_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); +ECDSA_SIG *ossl_ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey); +int ossl_ecdsa_simple_verify_sig(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); -int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, - const uint8_t public_key[32], const uint8_t private_key[32]); -int ED25519_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[64], const uint8_t public_key[32]); -void ED25519_public_from_private(uint8_t out_public_key[32], - const uint8_t private_key[32]); - -int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32], - const uint8_t peer_public_value[32]); -void X25519_public_from_private(uint8_t out_public_value[32], - const uint8_t private_key[32]); /*- * This functions computes a single point multiplication over the EC group, @@ -695,11 +726,12 @@ void X25519_public_from_private(uint8_t out_public_value[32], * * Returns 1 on success, 0 otherwise. */ -int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, const EC_POINT *point, - BN_CTX *ctx); +int ossl_ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, const EC_POINT *point, + BN_CTX *ctx); -int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx); +int ossl_ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, + BN_CTX *ctx); static ossl_inline int ec_point_ladder_pre(const EC_GROUP *group, EC_POINT *r, EC_POINT *s, diff --git a/crypto/openssl/crypto/ec/ec_mult.c b/crypto/openssl/crypto/ec/ec_mult.c index 9a1e3974ed9e..c6ec2964b7c4 100644 --- a/crypto/openssl/crypto/ec/ec_mult.c +++ b/crypto/openssl/crypto/ec/ec_mult.c @@ -1,13 +1,19 @@ /* - * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 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 + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include @@ -51,7 +57,7 @@ static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return ret; } @@ -62,7 +68,7 @@ static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } @@ -136,9 +142,9 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre) * * Returns 1 on success, 0 otherwise. */ -int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, const EC_POINT *point, - BN_CTX *ctx) +int ossl_ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, const EC_POINT *point, + BN_CTX *ctx) { int i, cardinality_bits, group_top, kbit, pbit, Z_is_one; EC_POINT *p = NULL; @@ -153,11 +159,11 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, return EC_POINT_set_to_infinity(group, r); if (BN_is_zero(group->order)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_ORDER); + ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_ORDER); return 0; } if (BN_is_zero(group->cofactor)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_COFACTOR); + ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_COFACTOR); return 0; } @@ -165,18 +171,18 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, if (((p = EC_POINT_new(group)) == NULL) || ((s = EC_POINT_new(group)) == NULL)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } if (point == NULL) { if (!EC_POINT_copy(p, group->generator)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } } else { if (!EC_POINT_copy(p, point)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } } @@ -189,12 +195,12 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, lambda = BN_CTX_get(ctx); k = BN_CTX_get(ctx); if (k == NULL) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } if (!BN_mul(cardinality, group->order, group->cofactor, ctx)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -208,12 +214,12 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, group_top = bn_get_top(cardinality); if ((bn_wexpand(k, group_top + 2) == NULL) || (bn_wexpand(lambda, group_top + 2) == NULL)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } if (!BN_copy(k, scalar)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -225,18 +231,18 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, * constant-timeness */ if (!BN_nnmod(k, k, cardinality, ctx)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } } if (!BN_add(lambda, k, cardinality)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } BN_set_flags(lambda, BN_FLG_CONSTTIME); if (!BN_add(k, lambda, cardinality)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* @@ -256,19 +262,20 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, || (bn_wexpand(p->X, group_top) == NULL) || (bn_wexpand(p->Y, group_top) == NULL) || (bn_wexpand(p->Z, group_top) == NULL)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* ensure input point is in affine coords for ladder step efficiency */ - if (!p->Z_is_one && !EC_POINT_make_affine(group, p, ctx)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB); + if (!p->Z_is_one && (group->meth->make_affine == NULL + || !group->meth->make_affine(group, p, ctx))) { + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } /* Initialize the Montgomery ladder */ if (!ec_point_ladder_pre(group, r, s, p, ctx)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_PRE_FAILURE); + ERR_raise(ERR_LIB_EC, EC_R_LADDER_PRE_FAILURE); goto err; } @@ -348,7 +355,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, /* Perform a single step of the Montgomery ladder */ if (!ec_point_ladder_step(group, r, s, p, ctx)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_STEP_FAILURE); + ERR_raise(ERR_LIB_EC, EC_R_LADDER_STEP_FAILURE); goto err; } /* @@ -363,7 +370,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, /* Finalize ladder (and recover full point coordinates) */ if (!ec_point_ladder_post(group, r, s, p, ctx)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_POST_FAILURE); + ERR_raise(ERR_LIB_EC, EC_R_LADDER_POST_FAILURE); goto err; } @@ -380,7 +387,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, #undef EC_POINT_BN_set_flags /* - * TODO: table should be optimised for the wNAF-based implementation, + * Table could be optimised for the wNAF-based implementation, * sometimes smaller windows will give better performance (thus the * boundaries should be increased) */ @@ -400,9 +407,9 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, * scalar*generator * in the addition if scalar != NULL */ -int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, - size_t num, const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *ctx) +int ossl_ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) { const EC_POINT *generator = NULL; EC_POINT *tmp = NULL; @@ -443,7 +450,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, * is why we ignore if BN_FLG_CONSTTIME is actually set and we * always call the ladder version. */ - return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx); + return ossl_ec_scalar_mul_ladder(group, r, scalar, NULL, ctx); } if ((scalar == NULL) && (num == 1) && (scalars[0] != group->order)) { /*- @@ -453,14 +460,15 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, * To protect the secret scalar, we ignore if BN_FLG_CONSTTIME is * actually set and we always call the ladder version. */ - return ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx); + return ossl_ec_scalar_mul_ladder(group, r, scalars[0], points[0], + ctx); } } if (scalar != NULL) { generator = EC_GROUP_get0_generator(group); if (generator == NULL) { - ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR); + ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR); goto err; } @@ -488,7 +496,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, /* check that pre_comp looks sane */ if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } } else { @@ -513,7 +521,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, wNAF[0] = NULL; /* preliminary pivot */ if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -543,7 +551,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, if (pre_comp == NULL) { if (num_scalar != 1) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } /* we have already generated a wNAF for 'scalar' */ @@ -552,7 +560,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t tmp_len = 0; if (num_scalar != 0) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } @@ -595,7 +603,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, */ numblocks = (tmp_len + blocksize - 1) / blocksize; if (numblocks > pre_comp->numblocks) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); OPENSSL_free(tmp_wNAF); goto err; } @@ -610,7 +618,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, if (i < totalnum - 1) { wNAF_len[i] = blocksize; if (tmp_len < blocksize) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); OPENSSL_free(tmp_wNAF); goto err; } @@ -625,7 +633,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, wNAF[i + 1] = NULL; wNAF[i] = OPENSSL_malloc(wNAF_len[i]); if (wNAF[i] == NULL) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); OPENSSL_free(tmp_wNAF); goto err; } @@ -634,7 +642,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, max_len = wNAF_len[i]; if (*tmp_points == NULL) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); OPENSSL_free(tmp_wNAF); goto err; } @@ -654,7 +662,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, */ val = OPENSSL_malloc((num_val + 1) * sizeof(val[0])); if (val == NULL) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } val[num_val] = NULL; /* pivot element */ @@ -671,7 +679,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, } } if (!(v == val + num_val)) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } @@ -705,7 +713,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, } } - if (!EC_POINTs_make_affine(group, num_val, val, ctx)) + if (group->meth->points_make_affine == NULL + || !group->meth->points_make_affine(group, num_val, val, ctx)) goto err; r_is_at_infinity = 1; @@ -745,12 +754,12 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, * Apply coordinate blinding for EC_POINT. * * The underlying EC_METHOD can optionally implement this function: - * ec_point_blind_coordinates() returns 0 in case of errors or 1 on + * ossl_ec_point_blind_coordinates() returns 0 in case of errors or 1 on * success or if coordinate blinding is not implemented for this * group. */ - if (!ec_point_blind_coordinates(group, r, ctx)) { - ECerr(EC_F_EC_WNAF_MUL, EC_R_POINT_COORDINATES_BLIND_FAILURE); + if (!ossl_ec_point_blind_coordinates(group, r, ctx)) { + ERR_raise(ERR_LIB_EC, EC_R_POINT_COORDINATES_BLIND_FAILURE); goto err; } @@ -799,9 +808,9 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, } /*- - * ec_wNAF_precompute_mult() + * ossl_ec_wNAF_precompute_mult() * creates an EC_PRE_COMP object with preprecomputed multiples of the generator - * for use with wNAF splitting as implemented in ec_wNAF_mul(). + * for use with wNAF splitting as implemented in ossl_ec_wNAF_mul(). * * 'pre_comp->points' is an array of multiples of the generator * of the following form: @@ -818,16 +827,19 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator * points[2^(w-1)*numblocks] = NULL */ -int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +int ossl_ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { const EC_POINT *generator; EC_POINT *tmp_point = NULL, *base = NULL, **var; - BN_CTX *new_ctx = NULL; const BIGNUM *order; size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num; EC_POINT **points = NULL; EC_PRE_COMP *pre_comp; int ret = 0; + int used_ctx = 0; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif /* if there is an old EC_PRE_COMP object, throw it away */ EC_pre_comp_free(group); @@ -836,23 +848,25 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) generator = EC_GROUP_get0_generator(group); if (generator == NULL) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR); + ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR); goto err; } - if (ctx == NULL) { +#ifndef FIPS_MODULE + if (ctx == NULL) ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - } +#endif + if (ctx == NULL) + goto err; BN_CTX_start(ctx); + used_ctx = 1; order = EC_GROUP_get0_order(group); if (order == NULL) goto err; if (BN_is_zero(order)) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER); + ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_ORDER); goto err; } @@ -880,7 +894,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) points = OPENSSL_malloc(sizeof(*points) * (num + 1)); if (points == NULL) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -888,14 +902,14 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) var[num] = NULL; /* pivot */ for (i = 0; i < num; i++) { if ((var[i] = EC_POINT_new(group)) == NULL) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } } if ((tmp_point = EC_POINT_new(group)) == NULL || (base = EC_POINT_new(group)) == NULL) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -927,7 +941,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) size_t k; if (blocksize <= 2) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } @@ -940,7 +954,8 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) } } - if (!EC_POINTs_make_affine(group, num, points, ctx)) + if (group->meth->points_make_affine == NULL + || !group->meth->points_make_affine(group, num, points, ctx)) goto err; pre_comp->group = group; @@ -955,8 +970,11 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) ret = 1; err: - BN_CTX_end(ctx); + if (used_ctx) + BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif EC_ec_pre_comp_free(pre_comp); if (points) { EC_POINT **p; @@ -970,7 +988,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) return ret; } -int ec_wNAF_have_precompute_mult(const EC_GROUP *group) +int ossl_ec_wNAF_have_precompute_mult(const EC_GROUP *group) { return HAVEPRECOMP(group, ec); } diff --git a/crypto/openssl/crypto/ec/ec_oct.c b/crypto/openssl/crypto/ec/ec_oct.c index 7ddc86b047ca..790a0b290771 100644 --- a/crypto/openssl/crypto/ec/ec_oct.c +++ b/crypto/openssl/crypto/ec/ec_oct.c @@ -1,13 +1,19 @@ /* - * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2021 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 + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include @@ -20,36 +26,33 @@ int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, { if (group->meth->point_set_compressed_coordinates == NULL && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { - ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(point, group)) { - ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES, - EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { if (group->meth->field_type == NID_X9_62_prime_field) - return ec_GFp_simple_set_compressed_coordinates(group, point, x, - y_bit, ctx); + return ossl_ec_GFp_simple_set_compressed_coordinates(group, point, x, + y_bit, ctx); else #ifdef OPENSSL_NO_EC2M { - ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES, - EC_R_GF2M_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); return 0; } #else - return ec_GF2m_simple_set_compressed_coordinates(group, point, x, - y_bit, ctx); + return ossl_ec_GF2m_simple_set_compressed_coordinates(group, point, + x, y_bit, ctx); #endif } return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx); } -#if OPENSSL_API_COMPAT < 0x10200000L +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, int y_bit, BN_CTX *ctx) @@ -73,25 +76,26 @@ size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, { if (group->meth->point2oct == 0 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { - ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(point, group)) { - ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { if (group->meth->field_type == NID_X9_62_prime_field) - return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx); + return ossl_ec_GFp_simple_point2oct(group, point, form, buf, len, + ctx); else #ifdef OPENSSL_NO_EC2M { - ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); return 0; } #else - return ec_GF2m_simple_point2oct(group, point, - form, buf, len, ctx); + return ossl_ec_GF2m_simple_point2oct(group, point, + form, buf, len, ctx); #endif } @@ -103,24 +107,24 @@ int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, { if (group->meth->oct2point == 0 && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { - ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (!ec_point_is_compat(point, group)) { - ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS); + ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { if (group->meth->field_type == NID_X9_62_prime_field) - return ec_GFp_simple_oct2point(group, point, buf, len, ctx); + return ossl_ec_GFp_simple_oct2point(group, point, buf, len, ctx); else #ifdef OPENSSL_NO_EC2M { - ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); return 0; } #else - return ec_GF2m_simple_oct2point(group, point, buf, len, ctx); + return ossl_ec_GF2m_simple_oct2point(group, point, buf, len, ctx); #endif } return group->meth->oct2point(group, point, buf, len, ctx); @@ -137,7 +141,7 @@ size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, if (len == 0) return 0; if ((buf = OPENSSL_malloc(len)) == NULL) { - ECerr(EC_F_EC_POINT_POINT2BUF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } len = EC_POINT_point2oct(group, point, form, buf, len, ctx); diff --git a/crypto/openssl/crypto/ec/ec_pmeth.c b/crypto/openssl/crypto/ec/ec_pmeth.c index 64d2cc93a620..19e2f0d0c04d 100644 --- a/crypto/openssl/crypto/ec/ec_pmeth.c +++ b/crypto/openssl/crypto/ec/ec_pmeth.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDH and ECDSA low level APIs are deprecated for public use, but still ok + * for internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -43,7 +49,7 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx) EC_PKEY_CTX *dctx; if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) { - ECerr(EC_F_PKEY_EC_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } @@ -53,7 +59,7 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx) return 1; } -static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +static int pkey_ec_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) { EC_PKEY_CTX *dctx, *sctx; if (!pkey_ec_init(dst)) @@ -103,7 +109,12 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, int ret, type; unsigned int sltmp; EC_PKEY_CTX *dctx = ctx->data; - EC_KEY *ec = ctx->pkey->pkey.ec; + /* + * Discard const. Its marked as const because this may be a cached copy of + * the "real" key. These calls don't make any modifications that need to + * be reflected back in the "original" key. + */ + EC_KEY *ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); const int sig_sz = ECDSA_size(ec); /* ensure cast to size_t is safe */ @@ -116,11 +127,11 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, } if (*siglen < (size_t)sig_sz) { - ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); return 0; } - type = (dctx->md != NULL) ? EVP_MD_type(dctx->md) : NID_sha1; + type = (dctx->md != NULL) ? EVP_MD_get_type(dctx->md) : NID_sha1; ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); @@ -136,10 +147,15 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx, { int ret, type; EC_PKEY_CTX *dctx = ctx->data; - EC_KEY *ec = ctx->pkey->pkey.ec; + /* + * Discard const. Its marked as const because this may be a cached copy of + * the "real" key. These calls don't make any modifications that need to + * be reflected back in the "original" key. + */ + EC_KEY *ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); if (dctx->md) - type = EVP_MD_type(dctx->md); + type = EVP_MD_get_type(dctx->md); else type = NID_sha1; @@ -155,21 +171,32 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) size_t outlen; const EC_POINT *pubkey = NULL; EC_KEY *eckey; + const EC_KEY *eckeypub; EC_PKEY_CTX *dctx = ctx->data; - if (!ctx->pkey || !ctx->peerkey) { - ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET); + + if (ctx->pkey == NULL || ctx->peerkey == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET); + return 0; + } + eckeypub = EVP_PKEY_get0_EC_KEY(ctx->peerkey); + if (eckeypub == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET); return 0; } - eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec; + eckey = dctx->co_key ? dctx->co_key + : (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); if (!key) { const EC_GROUP *group; group = EC_KEY_get0_group(eckey); + + if (group == NULL) + return 0; *keylen = (EC_GROUP_get_degree(group) + 7) / 8; return 1; } - pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); + pubkey = EC_KEY_get0_public_key(eckeypub); /* * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not @@ -203,14 +230,15 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, if (!pkey_ec_derive(ctx, NULL, &ktmplen)) return 0; if ((ktmp = OPENSSL_malloc(ktmplen)) == NULL) { - ECerr(EC_F_PKEY_EC_KDF_DERIVE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } if (!pkey_ec_derive(ctx, ktmp, &ktmplen)) goto err; /* Do KDF stuff */ - if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen, - dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) + if (!ossl_ecdh_kdf_X9_63(key, *keylen, ktmp, ktmplen, + dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md, + ctx->libctx, ctx->propquery)) goto err; rv = 1; @@ -228,7 +256,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: group = EC_GROUP_new_by_curve_name(p1); if (group == NULL) { - ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); return 0; } EC_GROUP_free(dctx->gen_group); @@ -237,7 +265,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_EC_PARAM_ENC: if (!dctx->gen_group) { - ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET); + ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET); return 0; } EC_GROUP_set_asn1_flag(dctx->gen_group, p1); @@ -249,14 +277,23 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) if (dctx->cofactor_mode != -1) return dctx->cofactor_mode; else { - EC_KEY *ec_key = ctx->pkey->pkey.ec; + const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ctx->pkey); return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0; } } else if (p1 < -1 || p1 > 1) return -2; dctx->cofactor_mode = p1; if (p1 != -1) { - EC_KEY *ec_key = ctx->pkey->pkey.ec; + EC_KEY *ec_key = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); + + /* + * We discarded the "const" above. This will only work if the key is + * a "real" legacy key, and not a cached copy of a provided key + */ + if (evp_pkey_is_provided(ctx->pkey)) { + ERR_raise(ERR_LIB_EC, ERR_R_UNSUPPORTED); + return 0; + } if (!ec_key->group) return -2; /* If cofactor is 1 cofactor mode does nothing */ @@ -318,17 +355,18 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return dctx->kdf_ukmlen; case EVP_PKEY_CTRL_MD: - if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && - EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha512 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) { - ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); + if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha384 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha512 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_224 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_256 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_384 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_512 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sm3) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE); return 0; } dctx->md = p2; @@ -362,7 +400,7 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, if (nid == NID_undef) nid = OBJ_ln2nid(value); if (nid == NID_undef) { - ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); return 0; } return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); @@ -378,7 +416,7 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, } else if (strcmp(type, "ecdh_kdf_md") == 0) { const EVP_MD *md; if ((md = EVP_get_digestbyname(value)) == NULL) { - ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST); return 0; } return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md); @@ -398,7 +436,7 @@ static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) int ret; if (dctx->gen_group == NULL) { - ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET); + ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET); return 0; } ec = EC_KEY_new(); @@ -417,7 +455,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) int ret; if (ctx->pkey == NULL && dctx->gen_group == NULL) { - ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET); + ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET); return 0; } ec = EC_KEY_new(); @@ -436,7 +474,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) return ret ? EC_KEY_generate_key(ec) : 0; } -const EVP_PKEY_METHOD ec_pkey_meth = { +static const EVP_PKEY_METHOD ec_pkey_meth = { EVP_PKEY_EC, 0, pkey_ec_init, @@ -474,3 +512,8 @@ const EVP_PKEY_METHOD ec_pkey_meth = { pkey_ec_ctrl, pkey_ec_ctrl_str }; + +const EVP_PKEY_METHOD *ossl_ec_pkey_method(void) +{ + return &ec_pkey_meth; +} diff --git a/crypto/openssl/crypto/ec/ec_print.c b/crypto/openssl/crypto/ec/ec_print.c index 660fc400fb75..ffe112052fbd 100644 --- a/crypto/openssl/crypto/ec/ec_print.c +++ b/crypto/openssl/crypto/ec/ec_print.c @@ -1,74 +1,16 @@ /* - * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 /* strlen */ #include -#include #include "ec_local.h" -BIGNUM *EC_POINT_point2bn(const EC_GROUP *group, - const EC_POINT *point, - point_conversion_form_t form, - BIGNUM *ret, BN_CTX *ctx) -{ - size_t buf_len = 0; - unsigned char *buf; - - buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx); - - if (buf_len == 0) - return NULL; - - ret = BN_bin2bn(buf, buf_len, ret); - - OPENSSL_free(buf); - - return ret; -} - -EC_POINT *EC_POINT_bn2point(const EC_GROUP *group, - const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx) -{ - size_t buf_len = 0; - unsigned char *buf; - EC_POINT *ret; - - if ((buf_len = BN_num_bytes(bn)) == 0) - buf_len = 1; - if ((buf = OPENSSL_malloc(buf_len)) == NULL) { - ECerr(EC_F_EC_POINT_BN2POINT, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (!BN_bn2binpad(bn, buf, buf_len)) { - OPENSSL_free(buf); - return NULL; - } - - if (point == NULL) { - if ((ret = EC_POINT_new(group)) == NULL) { - OPENSSL_free(buf); - return NULL; - } - } else - ret = point; - - if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) { - if (ret != point) - EC_POINT_clear_free(ret); - OPENSSL_free(buf); - return NULL; - } - - OPENSSL_free(buf); - return ret; -} - static const char *HEX_DIGITS = "0123456789ABCDEF"; /* the return value must be freed (using OPENSSL_free()) */ @@ -105,17 +47,39 @@ char *EC_POINT_point2hex(const EC_GROUP *group, } EC_POINT *EC_POINT_hex2point(const EC_GROUP *group, - const char *buf, EC_POINT *point, BN_CTX *ctx) + const char *hex, EC_POINT *point, BN_CTX *ctx) { - EC_POINT *ret = NULL; - BIGNUM *tmp_bn = NULL; + int ok = 0; + unsigned char *oct_buf = NULL; + size_t len, oct_buf_len = 0; + EC_POINT *pt = NULL; - if (!BN_hex2bn(&tmp_bn, buf)) + if (group == NULL || hex == NULL) return NULL; - ret = EC_POINT_bn2point(group, tmp_bn, point, ctx); - - BN_clear_free(tmp_bn); + if (point == NULL) { + pt = EC_POINT_new(group); + if (pt == NULL) + goto err; + } else { + pt = point; + } - return ret; + len = strlen(hex) / 2; + oct_buf = OPENSSL_malloc(len); + if (oct_buf == NULL) + goto err; + + if (!OPENSSL_hexstr2buf_ex(oct_buf, len, &oct_buf_len, hex, '\0') + || !EC_POINT_oct2point(group, pt, oct_buf, oct_buf_len, ctx)) + goto err; + ok = 1; +err: + OPENSSL_clear_free(oct_buf, oct_buf_len); + if (!ok) { + if (pt != point) + EC_POINT_clear_free(pt); + pt = NULL; + } + return pt; } diff --git a/crypto/openssl/crypto/ec/ecdh_kdf.c b/crypto/openssl/crypto/ec/ecdh_kdf.c index 96efac62f66f..de63bf8500b4 100644 --- a/crypto/openssl/crypto/ec/ecdh_kdf.c +++ b/crypto/openssl/crypto/ec/ecdh_kdf.c @@ -1,81 +1,65 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include +#include #include #include +#include #include "ec_local.h" /* Key derivation function from X9.63/SECG */ -/* Way more than we will ever need */ -#define ECDH_KDF_MAX (1 << 30) - -int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, - const unsigned char *Z, size_t Zlen, - const unsigned char *sinfo, size_t sinfolen, - const EVP_MD *md) +int ossl_ecdh_kdf_X9_63(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const unsigned char *sinfo, size_t sinfolen, + const EVP_MD *md, + OSSL_LIB_CTX *libctx, const char *propq) { - EVP_MD_CTX *mctx = NULL; - int rv = 0; - unsigned int i; - size_t mdlen; - unsigned char ctr[4]; - if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX - || Zlen > ECDH_KDF_MAX) - return 0; - mctx = EVP_MD_CTX_new(); - if (mctx == NULL) - return 0; - mdlen = EVP_MD_size(md); - for (i = 1;; i++) { - unsigned char mtmp[EVP_MAX_MD_SIZE]; - if (!EVP_DigestInit_ex(mctx, md, NULL)) - goto err; - ctr[3] = i & 0xFF; - ctr[2] = (i >> 8) & 0xFF; - ctr[1] = (i >> 16) & 0xFF; - ctr[0] = (i >> 24) & 0xFF; - if (!EVP_DigestUpdate(mctx, Z, Zlen)) - goto err; - if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr))) - goto err; - if (!EVP_DigestUpdate(mctx, sinfo, sinfolen)) - goto err; - if (outlen >= mdlen) { - if (!EVP_DigestFinal(mctx, out, NULL)) - goto err; - outlen -= mdlen; - if (outlen == 0) - break; - out += mdlen; - } else { - if (!EVP_DigestFinal(mctx, mtmp, NULL)) - goto err; - memcpy(out, mtmp, outlen); - OPENSSL_cleanse(mtmp, mdlen); - break; - } + int ret = 0; + EVP_KDF_CTX *kctx = NULL; + OSSL_PARAM params[4], *p = params; + const char *mdname = EVP_MD_get0_name(md); + EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_X963KDF, propq); + + if ((kctx = EVP_KDF_CTX_new(kdf)) != NULL) { + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + (void *)Z, Zlen); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, + (void *)sinfo, sinfolen); + *p = OSSL_PARAM_construct_end(); + + ret = EVP_KDF_derive(kctx, out, outlen, params) > 0; + EVP_KDF_CTX_free(kctx); } - rv = 1; - err: - EVP_MD_CTX_free(mctx); - return rv; + EVP_KDF_free(kdf); + return ret; } /*- * The old name for ecdh_KDF_X9_63 * Retained for ABI compatibility */ +#ifndef OPENSSL_NO_DEPRECATED_3_0 int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md) { - return ecdh_KDF_X9_63(out, outlen, Z, Zlen, sinfo, sinfolen, md); + return ossl_ecdh_kdf_X9_63(out, outlen, Z, Zlen, sinfo, sinfolen, md, NULL, + NULL); } +#endif diff --git a/crypto/openssl/crypto/ec/ecdh_ossl.c b/crypto/openssl/crypto/ec/ecdh_ossl.c index 0be00d43da4e..8016c6d7ad73 100644 --- a/crypto/openssl/crypto/ec/ecdh_ossl.c +++ b/crypto/openssl/crypto/ec/ecdh_ossl.c @@ -1,13 +1,19 @@ /* - * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2021 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 + * 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 */ +/* + * ECDH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include @@ -23,7 +29,7 @@ int ossl_ecdh_compute_key(unsigned char **psec, size_t *pseclen, const EC_POINT *pub_key, const EC_KEY *ecdh) { if (ecdh->group->meth->ecdh_compute_key == NULL) { - ECerr(EC_F_OSSL_ECDH_COMPUTE_KEY, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH); + ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH); return 0; } @@ -31,12 +37,17 @@ int ossl_ecdh_compute_key(unsigned char **psec, size_t *pseclen, } /*- - * This implementation is based on the following primitives in the IEEE 1363 standard: + * This implementation is based on the following primitives in the + * IEEE 1363 standard: * - ECKAS-DH1 * - ECSVDP-DH + * + * It also conforms to SP800-56A r3 + * See Section 5.7.1.2 "Elliptic Curve Cryptography Cofactor Diffie-Hellman + * (ECC CDH) Primitive:". The steps listed below refer to SP800-56A. */ -int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, - const EC_POINT *pub_key, const EC_KEY *ecdh) +int ossl_ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, + const EC_POINT *pub_key, const EC_KEY *ecdh) { BN_CTX *ctx; EC_POINT *tmp = NULL; @@ -47,61 +58,74 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, size_t buflen, len; unsigned char *buf = NULL; - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(ecdh->libctx)) == NULL) goto err; BN_CTX_start(ctx); x = BN_CTX_get(ctx); if (x == NULL) { - ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } priv_key = EC_KEY_get0_private_key(ecdh); if (priv_key == NULL) { - ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_MISSING_PRIVATE_KEY); + ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY); goto err; } group = EC_KEY_get0_group(ecdh); + /* + * Step(1) - Compute the point tmp = cofactor * owners_private_key + * * peer_public_key. + */ if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) { if (!EC_GROUP_get_cofactor(group, x, NULL) || !BN_mul(x, x, priv_key, ctx)) { - ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } priv_key = x; } if ((tmp = EC_POINT_new(group)) == NULL) { - ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) { - ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE); + ERR_raise(ERR_LIB_EC, EC_R_POINT_ARITHMETIC_FAILURE); goto err; } + /* + * Step(2) : If point tmp is at infinity then clear intermediate values and + * exit. Note: getting affine coordinates returns 0 if point is at infinity. + * Step(3a) : Get x-coordinate of point x = tmp.x + */ if (!EC_POINT_get_affine_coordinates(group, tmp, x, NULL, ctx)) { - ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE); + ERR_raise(ERR_LIB_EC, EC_R_POINT_ARITHMETIC_FAILURE); goto err; } + /* + * Step(3b) : convert x to a byte string, using the field-element-to-byte + * string conversion routine defined in Appendix C.2 + */ buflen = (EC_GROUP_get_degree(group) + 7) / 8; len = BN_num_bytes(x); if (len > buflen) { - ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } if ((buf = OPENSSL_malloc(buflen)) == NULL) { - ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } memset(buf, 0, buflen - len); if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) { - ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -112,6 +136,8 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, ret = 1; err: + /* Step(4) : Destroy all intermediate calculations */ + BN_clear(x); EC_POINT_clear_free(tmp); BN_CTX_end(ctx); BN_CTX_free(ctx); diff --git a/crypto/openssl/crypto/ec/ecdsa_ossl.c b/crypto/openssl/crypto/ec/ecdsa_ossl.c index 1da87bfb5e39..fe9b3cf59363 100644 --- a/crypto/openssl/crypto/ec/ecdsa_ossl.c +++ b/crypto/openssl/crypto/ec/ecdsa_ossl.c @@ -1,12 +1,18 @@ /* - * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include @@ -14,6 +20,41 @@ #include "crypto/bn.h" #include "ec_local.h" +int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) +{ + if (eckey->group->meth->ecdsa_sign_setup == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA); + return 0; + } + + return eckey->group->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); +} + +ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey) +{ + if (eckey->group->meth->ecdsa_sign_sig == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA); + return NULL; + } + + return eckey->group->meth->ecdsa_sign_sig(dgst, dgst_len, + in_kinv, in_r, eckey); +} + +int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) +{ + if (eckey->group->meth->ecdsa_verify_sig == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA); + return 0; + } + + return eckey->group->meth->ecdsa_verify_sig(dgst, dgst_len, sig, eckey); +} + int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey) @@ -44,35 +85,35 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, 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); + ERR_raise(ERR_LIB_EC, 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); + ERR_raise(ERR_LIB_EC, 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); + ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); return 0; } if ((ctx = ctx_in) == NULL) { - if ((ctx = BN_CTX_new()) == NULL) { - ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); + if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } } - k = BN_new(); /* this value is later returned in *kinvp */ + k = BN_secure_new(); /* this value is later returned in *kinvp */ r = BN_new(); /* this value is later returned in *rp */ X = BN_new(); if (k == NULL || r == NULL || X == NULL) { - ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } if ((tmp_point = EC_POINT_new(group)) == NULL) { - ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } order = EC_GROUP_get0_order(group); @@ -90,14 +131,12 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, if (dgst != NULL) { if (!BN_generate_dsa_nonce(k, order, priv_key, dgst, dlen, ctx)) { - ECerr(EC_F_ECDSA_SIGN_SETUP, - EC_R_RANDOM_NUMBER_GENERATION_FAILED); + ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; } } else { - if (!BN_priv_rand_range(k, order)) { - ECerr(EC_F_ECDSA_SIGN_SETUP, - EC_R_RANDOM_NUMBER_GENERATION_FAILED); + if (!BN_priv_rand_range_ex(k, order, 0, ctx)) { + ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; } } @@ -105,24 +144,24 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { - ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (!EC_POINT_get_affine_coordinates(group, tmp_point, X, NULL, ctx)) { - ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (!BN_nnmod(r, X, order, ctx)) { - ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } } while (BN_is_zero(r)); /* compute the inverse of k */ - if (!ec_group_do_inverse_ord(group, k, k, ctx)) { - ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + if (!ossl_ec_group_do_inverse_ord(group, k, k, ctx)) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -145,15 +184,15 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, return ret; } -int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp) +int ossl_ecdsa_simple_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) { return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0); } -ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, - const BIGNUM *in_kinv, const BIGNUM *in_r, - EC_KEY *eckey) +ECDSA_SIG *ossl_ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey) { int ok = 0, i; BIGNUM *kinv = NULL, *s, *m = NULL; @@ -167,35 +206,35 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, priv_key = EC_KEY_get0_private_key(eckey); if (group == NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (priv_key == NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_MISSING_PRIVATE_KEY); + ERR_raise(ERR_LIB_EC, 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); + ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); return NULL; } ret = ECDSA_SIG_new(); if (ret == NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return NULL; } ret->r = BN_new(); ret->s = BN_new(); if (ret->r == NULL || ret->s == NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } s = ret->s; - if ((ctx = BN_CTX_new()) == NULL + if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL || (m = BN_new()) == NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -207,25 +246,25 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, if (8 * dgst_len > i) dgst_len = (i + 7) / 8; if (!BN_bin2bn(dgst, dgst_len, m)) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* If still too long, truncate remaining bits with a shift */ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } do { if (in_kinv == NULL || in_r == NULL) { if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_ECDSA_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_ECDSA_LIB); goto err; } ckinv = kinv; } else { ckinv = in_kinv; if (BN_copy(ret->r, in_r) == NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } } @@ -239,11 +278,11 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, */ if (!bn_to_mont_fixed_top(s, ret->r, group->mont_data, ctx) || !bn_mul_mont_fixed_top(s, s, priv_key, group->mont_data, ctx)) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } if (!bn_mod_add_fixed_top(s, s, m, order)) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* @@ -252,7 +291,7 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, */ if (!bn_to_mont_fixed_top(s, s, group->mont_data, ctx) || !BN_mod_mul_montgomery(s, s, ckinv, group->mont_data, ctx)) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -262,7 +301,7 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, * generate new kinv and r values */ if (in_kinv != NULL && in_r != NULL) { - ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_NEED_NEW_SETUP_VALUES); + ERR_raise(ERR_LIB_EC, EC_R_NEED_NEW_SETUP_VALUES); goto err; } } else { @@ -314,8 +353,8 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, return ret; } -int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, - const ECDSA_SIG *sig, EC_KEY *eckey) +int ossl_ecdsa_simple_verify_sig(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) { int ret = -1, i; BN_CTX *ctx; @@ -328,18 +367,18 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, /* check input values */ if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_MISSING_PARAMETERS); + ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS); return -1; } if (!EC_KEY_can_sign(eckey)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); + ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); return -1; } - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(eckey->libctx); if (ctx == NULL) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return -1; } BN_CTX_start(ctx); @@ -348,26 +387,26 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, m = BN_CTX_get(ctx); X = BN_CTX_get(ctx); if (X == NULL) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } order = EC_GROUP_get0_order(group); if (order == NULL) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_BAD_SIGNATURE); + ERR_raise(ERR_LIB_EC, EC_R_BAD_SIGNATURE); ret = 0; /* signature is invalid */ goto err; } /* calculate tmp1 = inv(S) mod order */ - if (!ec_group_do_inverse_ord(group, u2, sig->s, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + if (!ossl_ec_group_do_inverse_ord(group, u2, sig->s, ctx)) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* digest -> m */ @@ -378,41 +417,41 @@ int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, if (8 * dgst_len > i) dgst_len = (i + 7) / 8; if (!BN_bin2bn(dgst, dgst_len, m)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* If still too long truncate remaining bits with a shift */ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* u1 = m * tmp mod order */ if (!BN_mod_mul(u1, m, u2, order, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* u2 = r * w mod q */ if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } if ((point = EC_POINT_new(group)) == NULL) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (!EC_POINT_get_affine_coordinates(group, point, X, NULL, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (!BN_nnmod(u1, X, order, ctx)) { - ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* if the signature is correct u1 is equal to sig->r */ diff --git a/crypto/openssl/crypto/ec/ecdsa_sign.c b/crypto/openssl/crypto/ec/ecdsa_sign.c index dc79c8c8e3df..0c0748c84f87 100644 --- a/crypto/openssl/crypto/ec/ecdsa_sign.c +++ b/crypto/openssl/crypto/ec/ecdsa_sign.c @@ -1,12 +1,18 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "ec_local.h" #include @@ -22,7 +28,7 @@ ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen, { if (eckey->meth->sign_sig != NULL) return eckey->meth->sign_sig(dgst, dlen, kinv, rp, eckey); - ECerr(EC_F_ECDSA_DO_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED); return NULL; } @@ -38,7 +44,7 @@ int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, { if (eckey->meth->sign != NULL) return eckey->meth->sign(type, dgst, dlen, sig, siglen, kinv, r, eckey); - ECerr(EC_F_ECDSA_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED); return 0; } @@ -47,6 +53,6 @@ int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, { if (eckey->meth->sign_setup != NULL) return eckey->meth->sign_setup(eckey, ctx_in, kinvp, rp); - ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_OPERATION_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED); return 0; } diff --git a/crypto/openssl/crypto/ec/ecdsa_vrf.c b/crypto/openssl/crypto/ec/ecdsa_vrf.c index ff597bdc143c..c148ecdb7cf6 100644 --- a/crypto/openssl/crypto/ec/ecdsa_vrf.c +++ b/crypto/openssl/crypto/ec/ecdsa_vrf.c @@ -1,12 +1,18 @@ /* * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "ec_local.h" #include @@ -22,7 +28,7 @@ int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, { if (eckey->meth->verify_sig != NULL) return eckey->meth->verify_sig(dgst, dgst_len, sig, eckey); - ECerr(EC_F_ECDSA_DO_VERIFY, EC_R_OPERATION_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED); return -1; } @@ -38,6 +44,6 @@ int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len, if (eckey->meth->verify != NULL) return eckey->meth->verify(type, dgst, dgst_len, sigbuf, sig_len, eckey); - ECerr(EC_F_ECDSA_VERIFY, EC_R_OPERATION_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED); return -1; } diff --git a/crypto/openssl/crypto/ec/eck_prn.c b/crypto/openssl/crypto/ec/eck_prn.c index b538fadcb10c..96ced7c8be0d 100644 --- a/crypto/openssl/crypto/ec/eck_prn.c +++ b/crypto/openssl/crypto/ec/eck_prn.c @@ -1,27 +1,30 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 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 + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include #include #include -#ifndef OPENSSL_NO_STDIO +#ifndef OPENSSL_NO_DEPRECATED_3_0 +# ifndef OPENSSL_NO_STDIO int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) { BIO *b; int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -36,7 +39,7 @@ int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BIO_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -51,7 +54,7 @@ int ECParameters_print_fp(FILE *fp, const EC_KEY *x) int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BIO_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -59,7 +62,7 @@ int ECParameters_print_fp(FILE *fp, const EC_KEY *x) BIO_free(b); return ret; } -#endif +#endif /* OPENSSL_NO_STDIO */ static int print_bin(BIO *fp, const char *str, const unsigned char *num, size_t len, int off); @@ -69,10 +72,11 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) int ret = 0, reason = ERR_R_BIO_LIB; BN_CTX *ctx = NULL; const EC_POINT *point = NULL; - BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL; + unsigned char *gen_buf = NULL; const BIGNUM *order = NULL, *cofactor = NULL; const unsigned char *seed; - size_t seed_len = 0; + size_t seed_len = 0, gen_buf_len = 0; static const char *gen_compressed = "Generator (compressed):"; static const char *gen_uncompressed = "Generator (uncompressed):"; @@ -112,10 +116,11 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) goto err; } } else { + const char *form_str; /* explicit parameters */ int is_char_two = 0; point_conversion_form_t form; - int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); + int tmp_nid = EC_GROUP_get_field_type(x); if (tmp_nid == NID_X9_62_characteristic_two_field) is_char_two = 1; @@ -144,7 +149,8 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) form = EC_GROUP_get_point_conversion_form(x); - if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) { + gen_buf_len = EC_POINT_point2buf(x, point, form, &gen_buf, ctx); + if (gen_buf_len == 0) { reason = ERR_R_EC_LIB; goto err; } @@ -185,22 +191,18 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) goto err; if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, NULL, off)) goto err; - if (form == POINT_CONVERSION_COMPRESSED) { - if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen, - NULL, off)) - goto err; - } else if (form == POINT_CONVERSION_UNCOMPRESSED) { - if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen, - NULL, off)) - goto err; - } else { /* form == POINT_CONVERSION_HYBRID */ - if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen, - NULL, off)) - goto err; - } - if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, - NULL, off)) + if (form == POINT_CONVERSION_COMPRESSED) + form_str = gen_compressed; + else if (form == POINT_CONVERSION_UNCOMPRESSED) + form_str = gen_uncompressed; + else + form_str = gen_hybrid; + if (gen_buf != NULL + && !print_bin(bp, form_str, gen_buf, gen_buf_len, off)) + goto err; + + if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, NULL, off)) goto err; if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, NULL, off)) @@ -211,11 +213,11 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) ret = 1; err: if (!ret) - ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); + ERR_raise(ERR_LIB_EC, reason); BN_free(p); BN_free(a); BN_free(b); - BN_free(gen); + OPENSSL_clear_free(gen_buf, gen_buf_len); BN_CTX_free(ctx); return ret; } @@ -257,3 +259,4 @@ static int print_bin(BIO *fp, const char *name, const unsigned char *buf, return 1; } +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ diff --git a/crypto/openssl/crypto/ec/ecp_mont.c b/crypto/openssl/crypto/ec/ecp_mont.c index bdc39d5efb0e..35b492453f57 100644 --- a/crypto/openssl/crypto/ec/ecp_mont.c +++ b/crypto/openssl/crypto/ec/ecp_mont.c @@ -1,13 +1,19 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 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 + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "ec_local.h" @@ -17,98 +23,99 @@ const EC_METHOD *EC_GFp_mont_method(void) static const EC_METHOD ret = { EC_FLAGS_DEFAULT_OCT, NID_X9_62_prime_field, - ec_GFp_mont_group_init, - ec_GFp_mont_group_finish, - ec_GFp_mont_group_clear_finish, - ec_GFp_mont_group_copy, - ec_GFp_mont_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_group_simple_order_bits, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_simple_point_get_affine_coordinates, + ossl_ec_GFp_mont_group_init, + ossl_ec_GFp_mont_group_finish, + ossl_ec_GFp_mont_group_clear_finish, + ossl_ec_GFp_mont_group_copy, + ossl_ec_GFp_mont_group_set_curve, + ossl_ec_GFp_simple_group_get_curve, + ossl_ec_GFp_simple_group_get_degree, + ossl_ec_group_simple_order_bits, + ossl_ec_GFp_simple_group_check_discriminant, + ossl_ec_GFp_simple_point_init, + ossl_ec_GFp_simple_point_finish, + ossl_ec_GFp_simple_point_clear_finish, + ossl_ec_GFp_simple_point_copy, + ossl_ec_GFp_simple_point_set_to_infinity, + ossl_ec_GFp_simple_point_set_affine_coordinates, + ossl_ec_GFp_simple_point_get_affine_coordinates, 0, 0, 0, - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, + ossl_ec_GFp_simple_add, + ossl_ec_GFp_simple_dbl, + ossl_ec_GFp_simple_invert, + ossl_ec_GFp_simple_is_at_infinity, + ossl_ec_GFp_simple_is_on_curve, + ossl_ec_GFp_simple_cmp, + ossl_ec_GFp_simple_make_affine, + ossl_ec_GFp_simple_points_make_affine, 0 /* mul */ , 0 /* precompute_mult */ , 0 /* have_precompute_mult */ , - ec_GFp_mont_field_mul, - ec_GFp_mont_field_sqr, + ossl_ec_GFp_mont_field_mul, + ossl_ec_GFp_mont_field_sqr, 0 /* field_div */ , - ec_GFp_mont_field_inv, - ec_GFp_mont_field_encode, - ec_GFp_mont_field_decode, - ec_GFp_mont_field_set_to_one, - ec_key_simple_priv2oct, - ec_key_simple_oct2priv, + ossl_ec_GFp_mont_field_inv, + ossl_ec_GFp_mont_field_encode, + ossl_ec_GFp_mont_field_decode, + ossl_ec_GFp_mont_field_set_to_one, + ossl_ec_key_simple_priv2oct, + ossl_ec_key_simple_oct2priv, 0, /* set private */ - ec_key_simple_generate_key, - ec_key_simple_check_key, - ec_key_simple_generate_public_key, + ossl_ec_key_simple_generate_key, + ossl_ec_key_simple_check_key, + ossl_ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key, + ossl_ecdh_simple_compute_key, + ossl_ecdsa_simple_sign_setup, + ossl_ecdsa_simple_sign_sig, + ossl_ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ - ec_GFp_simple_blind_coordinates, - ec_GFp_simple_ladder_pre, - ec_GFp_simple_ladder_step, - ec_GFp_simple_ladder_post + ossl_ec_GFp_simple_blind_coordinates, + ossl_ec_GFp_simple_ladder_pre, + ossl_ec_GFp_simple_ladder_step, + ossl_ec_GFp_simple_ladder_post }; return &ret; } -int ec_GFp_mont_group_init(EC_GROUP *group) +int ossl_ec_GFp_mont_group_init(EC_GROUP *group) { int ok; - ok = ec_GFp_simple_group_init(group); + ok = ossl_ec_GFp_simple_group_init(group); group->field_data1 = NULL; group->field_data2 = NULL; return ok; } -void ec_GFp_mont_group_finish(EC_GROUP *group) +void ossl_ec_GFp_mont_group_finish(EC_GROUP *group) { BN_MONT_CTX_free(group->field_data1); group->field_data1 = NULL; BN_free(group->field_data2); group->field_data2 = NULL; - ec_GFp_simple_group_finish(group); + ossl_ec_GFp_simple_group_finish(group); } -void ec_GFp_mont_group_clear_finish(EC_GROUP *group) +void ossl_ec_GFp_mont_group_clear_finish(EC_GROUP *group) { BN_MONT_CTX_free(group->field_data1); group->field_data1 = NULL; BN_clear_free(group->field_data2); group->field_data2 = NULL; - ec_GFp_simple_group_clear_finish(group); + ossl_ec_GFp_simple_group_clear_finish(group); } -int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) +int ossl_ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) { BN_MONT_CTX_free(dest->field_data1); dest->field_data1 = NULL; BN_clear_free(dest->field_data2); dest->field_data2 = NULL; - if (!ec_GFp_simple_group_copy(dest, src)) + if (!ossl_ec_GFp_simple_group_copy(dest, src)) return 0; if (src->field_data1 != NULL) { @@ -132,8 +139,9 @@ int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) return 0; } -int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +int ossl_ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { BN_CTX *new_ctx = NULL; BN_MONT_CTX *mont = NULL; @@ -146,7 +154,7 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, group->field_data2 = NULL; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -155,7 +163,7 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, if (mont == NULL) goto err; if (!BN_MONT_CTX_set(mont, p, ctx)) { - ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } one = BN_new(); @@ -169,7 +177,7 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, group->field_data2 = one; one = NULL; - ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx); if (!ret) { BN_MONT_CTX_free(group->field_data1); @@ -185,22 +193,22 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, return ret; } -int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) +int ossl_ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) { if (group->field_data1 == NULL) { - ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED); + ERR_raise(ERR_LIB_EC, EC_R_NOT_INITIALIZED); return 0; } return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx); } -int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - BN_CTX *ctx) +int ossl_ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) { if (group->field_data1 == NULL) { - ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED); + ERR_raise(ERR_LIB_EC, EC_R_NOT_INITIALIZED); return 0; } @@ -212,8 +220,8 @@ int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, * If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error. * We have a Mont structure, so SCA hardening is FLT inversion. */ -int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - BN_CTX *ctx) +int ossl_ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) { BIGNUM *e = NULL; BN_CTX *new_ctx = NULL; @@ -222,7 +230,8 @@ int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, if (group->field_data1 == NULL) return 0; - if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) + if (ctx == NULL + && (ctx = new_ctx = BN_CTX_secure_new_ex(group->libctx)) == NULL) return 0; BN_CTX_start(ctx); @@ -243,7 +252,7 @@ int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, /* throw an error on zero */ if (BN_is_zero(r)) { - ECerr(EC_F_EC_GFP_MONT_FIELD_INV, EC_R_CANNOT_INVERT); + ERR_raise(ERR_LIB_EC, EC_R_CANNOT_INVERT); goto err; } @@ -255,33 +264,33 @@ int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, return ret; } -int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, - const BIGNUM *a, BN_CTX *ctx) +int ossl_ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) { if (group->field_data1 == NULL) { - ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED); + ERR_raise(ERR_LIB_EC, EC_R_NOT_INITIALIZED); return 0; } return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx); } -int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, - const BIGNUM *a, BN_CTX *ctx) +int ossl_ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) { if (group->field_data1 == NULL) { - ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED); + ERR_raise(ERR_LIB_EC, EC_R_NOT_INITIALIZED); return 0; } return BN_from_montgomery(r, a, group->field_data1, ctx); } -int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, - BN_CTX *ctx) +int ossl_ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, + BN_CTX *ctx) { if (group->field_data2 == NULL) { - ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED); + ERR_raise(ERR_LIB_EC, EC_R_NOT_INITIALIZED); return 0; } diff --git a/crypto/openssl/crypto/ec/ecp_nist.c b/crypto/openssl/crypto/ec/ecp_nist.c index 9fd01279a891..3efd43e64c75 100644 --- a/crypto/openssl/crypto/ec/ecp_nist.c +++ b/crypto/openssl/crypto/ec/ecp_nist.c @@ -1,13 +1,19 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 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 + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include @@ -19,77 +25,79 @@ const EC_METHOD *EC_GFp_nist_method(void) static const EC_METHOD ret = { EC_FLAGS_DEFAULT_OCT, NID_X9_62_prime_field, - ec_GFp_simple_group_init, - ec_GFp_simple_group_finish, - ec_GFp_simple_group_clear_finish, - ec_GFp_nist_group_copy, - ec_GFp_nist_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_group_simple_order_bits, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_simple_point_get_affine_coordinates, + ossl_ec_GFp_simple_group_init, + ossl_ec_GFp_simple_group_finish, + ossl_ec_GFp_simple_group_clear_finish, + ossl_ec_GFp_nist_group_copy, + ossl_ec_GFp_nist_group_set_curve, + ossl_ec_GFp_simple_group_get_curve, + ossl_ec_GFp_simple_group_get_degree, + ossl_ec_group_simple_order_bits, + ossl_ec_GFp_simple_group_check_discriminant, + ossl_ec_GFp_simple_point_init, + ossl_ec_GFp_simple_point_finish, + ossl_ec_GFp_simple_point_clear_finish, + ossl_ec_GFp_simple_point_copy, + ossl_ec_GFp_simple_point_set_to_infinity, + ossl_ec_GFp_simple_point_set_affine_coordinates, + ossl_ec_GFp_simple_point_get_affine_coordinates, 0, 0, 0, - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, + ossl_ec_GFp_simple_add, + ossl_ec_GFp_simple_dbl, + ossl_ec_GFp_simple_invert, + ossl_ec_GFp_simple_is_at_infinity, + ossl_ec_GFp_simple_is_on_curve, + ossl_ec_GFp_simple_cmp, + ossl_ec_GFp_simple_make_affine, + ossl_ec_GFp_simple_points_make_affine, 0 /* mul */ , 0 /* precompute_mult */ , 0 /* have_precompute_mult */ , - ec_GFp_nist_field_mul, - ec_GFp_nist_field_sqr, + ossl_ec_GFp_nist_field_mul, + ossl_ec_GFp_nist_field_sqr, 0 /* field_div */ , - ec_GFp_simple_field_inv, + ossl_ec_GFp_simple_field_inv, 0 /* field_encode */ , 0 /* field_decode */ , 0, /* field_set_to_one */ - ec_key_simple_priv2oct, - ec_key_simple_oct2priv, + ossl_ec_key_simple_priv2oct, + ossl_ec_key_simple_oct2priv, 0, /* set private */ - ec_key_simple_generate_key, - ec_key_simple_check_key, - ec_key_simple_generate_public_key, + ossl_ec_key_simple_generate_key, + ossl_ec_key_simple_check_key, + ossl_ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key, + ossl_ecdh_simple_compute_key, + ossl_ecdsa_simple_sign_setup, + ossl_ecdsa_simple_sign_sig, + ossl_ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ - ec_GFp_simple_blind_coordinates, - ec_GFp_simple_ladder_pre, - ec_GFp_simple_ladder_step, - ec_GFp_simple_ladder_post + ossl_ec_GFp_simple_blind_coordinates, + ossl_ec_GFp_simple_ladder_pre, + ossl_ec_GFp_simple_ladder_step, + ossl_ec_GFp_simple_ladder_post }; return &ret; } -int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) +int ossl_ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) { dest->field_mod_func = src->field_mod_func; - return ec_GFp_simple_group_copy(dest, src); + return ossl_ec_GFp_simple_group_copy(dest, src); } -int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +int ossl_ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { int ret = 0; BN_CTX *new_ctx = NULL; if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) + if ((ctx = new_ctx = BN_CTX_new_ex(group->libctx)) == NULL) return 0; BN_CTX_start(ctx); @@ -105,11 +113,11 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0) group->field_mod_func = BN_nist_mod_521; else { - ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME); + ERR_raise(ERR_LIB_EC, EC_R_NOT_A_NIST_PRIME); goto err; } - ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx); err: BN_CTX_end(ctx); @@ -117,18 +125,18 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, return ret; } -int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) +int ossl_ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) { int ret = 0; BN_CTX *ctx_new = NULL; if (!group || !r || !a || !b) { - ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); goto err; } if (!ctx) - if ((ctx_new = ctx = BN_CTX_new()) == NULL) + if ((ctx_new = ctx = BN_CTX_new_ex(group->libctx)) == NULL) goto err; if (!BN_mul(r, a, b, ctx)) @@ -142,18 +150,18 @@ int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, return ret; } -int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - BN_CTX *ctx) +int ossl_ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) { int ret = 0; BN_CTX *ctx_new = NULL; if (!group || !r || !a) { - ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, EC_R_PASSED_NULL_PARAMETER); goto err; } if (!ctx) - if ((ctx_new = ctx = BN_CTX_new()) == NULL) + if ((ctx_new = ctx = BN_CTX_new_ex(group->libctx)) == NULL) goto err; if (!BN_sqr(r, a, ctx)) diff --git a/crypto/openssl/crypto/ec/ecp_nistp224.c b/crypto/openssl/crypto/ec/ecp_nistp224.c index 6f7d66c8bea4..5ab0dd7bef4f 100644 --- a/crypto/openssl/crypto/ec/ecp_nistp224.c +++ b/crypto/openssl/crypto/ec/ecp_nistp224.c @@ -1,7 +1,7 @@ /* - * Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2010-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -23,6 +23,12 @@ * limitations under the License. */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + /* * A 64-bit implementation of the NIST P-224 elliptic curve point multiplication * @@ -31,22 +37,17 @@ */ #include -#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128 -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include -# include "ec_local.h" - -# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16 - /* even with gcc, the typedef won't work for 32-bit platforms */ -typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit - * platforms */ -# else -# error "Your compiler doesn't appear to support 128-bit integer types" -# endif + +#include +#include +#include +#include "ec_local.h" + +#include "internal/numbers.h" + +#ifndef INT128_MAX +# error "Your compiler doesn't appear to support 128-bit integer types" +#endif typedef uint8_t u8; typedef uint64_t u64; @@ -245,54 +246,55 @@ const EC_METHOD *EC_GFp_nistp224_method(void) static const EC_METHOD ret = { EC_FLAGS_DEFAULT_OCT, NID_X9_62_prime_field, - ec_GFp_nistp224_group_init, - ec_GFp_simple_group_finish, - ec_GFp_simple_group_clear_finish, - ec_GFp_nist_group_copy, - ec_GFp_nistp224_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_group_simple_order_bits, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_nistp224_point_get_affine_coordinates, + ossl_ec_GFp_nistp224_group_init, + ossl_ec_GFp_simple_group_finish, + ossl_ec_GFp_simple_group_clear_finish, + ossl_ec_GFp_nist_group_copy, + ossl_ec_GFp_nistp224_group_set_curve, + ossl_ec_GFp_simple_group_get_curve, + ossl_ec_GFp_simple_group_get_degree, + ossl_ec_group_simple_order_bits, + ossl_ec_GFp_simple_group_check_discriminant, + ossl_ec_GFp_simple_point_init, + ossl_ec_GFp_simple_point_finish, + ossl_ec_GFp_simple_point_clear_finish, + ossl_ec_GFp_simple_point_copy, + ossl_ec_GFp_simple_point_set_to_infinity, + ossl_ec_GFp_simple_point_set_affine_coordinates, + ossl_ec_GFp_nistp224_point_get_affine_coordinates, 0 /* point_set_compressed_coordinates */ , 0 /* point2oct */ , 0 /* oct2point */ , - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, - ec_GFp_nistp224_points_mul, - ec_GFp_nistp224_precompute_mult, - ec_GFp_nistp224_have_precompute_mult, - ec_GFp_nist_field_mul, - ec_GFp_nist_field_sqr, + ossl_ec_GFp_simple_add, + ossl_ec_GFp_simple_dbl, + ossl_ec_GFp_simple_invert, + ossl_ec_GFp_simple_is_at_infinity, + ossl_ec_GFp_simple_is_on_curve, + ossl_ec_GFp_simple_cmp, + ossl_ec_GFp_simple_make_affine, + ossl_ec_GFp_simple_points_make_affine, + ossl_ec_GFp_nistp224_points_mul, + ossl_ec_GFp_nistp224_precompute_mult, + ossl_ec_GFp_nistp224_have_precompute_mult, + ossl_ec_GFp_nist_field_mul, + ossl_ec_GFp_nist_field_sqr, 0 /* field_div */ , - ec_GFp_simple_field_inv, + ossl_ec_GFp_simple_field_inv, 0 /* field_encode */ , 0 /* field_decode */ , 0, /* field_set_to_one */ - ec_key_simple_priv2oct, - ec_key_simple_oct2priv, + ossl_ec_key_simple_priv2oct, + ossl_ec_key_simple_oct2priv, 0, /* set private */ - ec_key_simple_generate_key, - ec_key_simple_check_key, - ec_key_simple_generate_public_key, + ossl_ec_key_simple_generate_key, + ossl_ec_key_simple_check_key, + ossl_ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key, + ossl_ecdh_simple_compute_key, + ossl_ecdsa_simple_sign_setup, + ossl_ecdsa_simple_sign_sig, + ossl_ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ 0, /* blind_coordinates */ 0, /* ladder_pre */ @@ -332,12 +334,12 @@ static int BN_to_felem(felem out, const BIGNUM *bn) int num_bytes; if (BN_is_negative(bn)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE); return 0; } 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); + ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE); return 0; } bin28_to_felem(out, b_out); @@ -663,7 +665,9 @@ static void felem_contract(felem out, const felem in) */ static void felem_neg(felem out, const felem in) { - widefelem tmp = {0}; + widefelem tmp; + + memset(tmp, 0, sizeof(tmp)); felem_diff_128_64(tmp, in); felem_reduce(out, tmp); } @@ -1201,7 +1205,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out, bits |= get_bit(scalars[num], i + 1) << 2; bits |= get_bit(scalars[num], i) << 1; bits |= get_bit(scalars[num], i - 1); - ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + ossl_ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); /* select the point to add or subtract */ select_point(digit, 17, pre_comp[num], tmp); @@ -1235,7 +1239,7 @@ static NISTP224_PRE_COMP *nistp224_pre_comp_new(void) NISTP224_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret)); if (!ret) { - ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return ret; } @@ -1243,7 +1247,7 @@ static NISTP224_PRE_COMP *nistp224_pre_comp_new(void) ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } @@ -1266,7 +1270,7 @@ void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *p) return; CRYPTO_DOWN_REF(&p->references, &i, p->lock); - REF_PRINT_COUNT("EC_nistp224", x); + REF_PRINT_COUNT("EC_nistp224", p); if (i > 0) return; REF_ASSERT_ISNT(i < 0); @@ -1280,25 +1284,29 @@ void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *p) * OPENSSL EC_METHOD FUNCTIONS */ -int ec_GFp_nistp224_group_init(EC_GROUP *group) +int ossl_ec_GFp_nistp224_group_init(EC_GROUP *group) { int ret; - ret = ec_GFp_simple_group_init(group); + ret = ossl_ec_GFp_simple_group_init(group); group->a_is_minus3 = 1; return ret; } -int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, - BN_CTX *ctx) +int ossl_ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { int ret = 0; - BN_CTX *new_ctx = NULL; BIGNUM *curve_p, *curve_a, *curve_b; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); curve_p = BN_CTX_get(ctx); curve_a = BN_CTX_get(ctx); @@ -1309,15 +1317,16 @@ int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a); BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b); if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { - ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE, - EC_R_WRONG_CURVE_PARAMETERS); + ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS); goto err; } group->field_mod_func = BN_nist_mod_224; - ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx); err: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } @@ -1325,17 +1334,16 @@ int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = * (X/Z^2, Y/Z^3) */ -int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx) +int ossl_ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) { felem z1, z2, x_in, y_in, x_out, y_out; widefelem tmp; if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, - EC_R_POINT_AT_INFINITY); + ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); return 0; } if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) || @@ -1349,8 +1357,7 @@ int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, felem_contract(x_out, x_in); if (x != NULL) { if (!felem_to_BN(x, x_out)) { - ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } } @@ -1361,8 +1368,7 @@ int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, felem_contract(y_out, y_in); if (y != NULL) { if (!felem_to_BN(y, y_out)) { - ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } } @@ -1376,36 +1382,36 @@ static void make_points_affine(size_t num, felem points[ /* num */ ][3], * Runs in constant time, unless an input is the point at infinity (which * normally shouldn't happen). */ - ec_GFp_nistp_points_make_affine_internal(num, - points, - sizeof(felem), - tmp_felems, - (void (*)(void *))felem_one, - felem_is_zero_int, - (void (*)(void *, const void *)) - felem_assign, - (void (*)(void *, const void *)) - felem_square_reduce, (void (*) - (void *, - const void - *, - const void - *)) - felem_mul_reduce, - (void (*)(void *, const void *)) - felem_inv, - (void (*)(void *, const void *)) - felem_contract); + ossl_ec_GFp_nistp_points_make_affine_internal(num, + points, + sizeof(felem), + tmp_felems, + (void (*)(void *))felem_one, + felem_is_zero_int, + (void (*)(void *, const void *)) + felem_assign, + (void (*)(void *, const void *)) + felem_square_reduce, (void (*) + (void *, + const void + *, + const void + *)) + felem_mul_reduce, + (void (*)(void *, const void *)) + felem_inv, + (void (*)(void *, const void *)) + felem_contract); } /* * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL * values Result is stored in r (r can equal one of the inputs). */ -int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx) +int ossl_ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) { int ret = 0; int j; @@ -1449,12 +1455,12 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, if (!felem_to_BN(x, g_pre_comp[0][1][0]) || !felem_to_BN(y, g_pre_comp[0][1][1]) || !felem_to_BN(z, g_pre_comp[0][1][2])) { - ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } - if (!EC_POINT_set_Jprojective_coordinates_GFp(group, - generator, x, y, z, - ctx)) + if (!ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, + generator, + x, y, z, ctx)) goto err; if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) /* precomputation matches generator */ @@ -1482,7 +1488,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, OPENSSL_malloc(sizeof(felem) * (num_points * 17 + 1)); if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_felems == NULL))) { - ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -1509,7 +1515,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, * constant-timeness */ if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } num_bytes = BN_bn2lebinpad(tmp_scalar, @@ -1519,7 +1525,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, secrets[i], sizeof(secrets[i])); } if (num_bytes < 0) { - ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* precompute multiples */ @@ -1561,7 +1567,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, * constant-timeness */ if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret)); @@ -1585,10 +1591,11 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, felem_contract(z_in, z_out); if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) || (!felem_to_BN(z, z_in))) { - ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } - ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); + ret = ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, r, x, y, z, + ctx); err: BN_CTX_end(ctx); @@ -1599,21 +1606,28 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, return ret; } -int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +int ossl_ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { int ret = 0; NISTP224_PRE_COMP *pre = NULL; int i, j; - BN_CTX *new_ctx = NULL; BIGNUM *x, *y; EC_POINT *generator = NULL; felem tmp_felems[32]; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif /* throw away old precomputation */ EC_pre_comp_free(group); + +#ifndef FIPS_MODULE if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); @@ -1721,14 +1735,14 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) err: BN_CTX_end(ctx); EC_POINT_free(generator); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif EC_nistp224_pre_comp_free(pre); return ret; } -int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group) +int ossl_ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group) { return HAVEPRECOMP(group, nistp224); } - -#endif diff --git a/crypto/openssl/crypto/ec/ecp_nistp256.c b/crypto/openssl/crypto/ec/ecp_nistp256.c index e23e9d2a0b34..4a55f925c465 100644 --- a/crypto/openssl/crypto/ec/ecp_nistp256.c +++ b/crypto/openssl/crypto/ec/ecp_nistp256.c @@ -1,7 +1,7 @@ /* - * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -23,6 +23,12 @@ * limitations under the License. */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + /* * A 64-bit implementation of the NIST P-256 elliptic curve point multiplication * @@ -32,23 +38,17 @@ */ #include -#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128 -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include -# include "ec_local.h" - -# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16 - /* even with gcc, the typedef won't work for 32-bit platforms */ -typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit - * platforms */ -typedef __int128_t int128_t; -# else -# error "Your compiler doesn't appear to support 128-bit integer types" -# endif + +#include +#include +#include +#include "ec_local.h" + +#include "internal/numbers.h" + +#ifndef INT128_MAX +# error "Your compiler doesn't appear to support 128-bit integer types" +#endif typedef uint8_t u8; typedef uint32_t u32; @@ -56,7 +56,7 @@ typedef uint64_t u64; /* * The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We - * can serialise an element of this field into 32 bytes. We call this an + * can serialize an element of this field into 32 bytes. We call this an * felem_bytearray. */ @@ -110,7 +110,7 @@ static const felem_bytearray nistp256_curve_params[5] = { * values are used as intermediate values before multiplication. */ -# define NLIMBS 4 +#define NLIMBS 4 typedef uint128_t limb; typedef limb felem[NLIMBS]; @@ -135,7 +135,7 @@ static void bin32_to_felem(felem out, const u8 in[32]) } /* - * smallfelem_to_bin32 takes a smallfelem and serialises into a little + * smallfelem_to_bin32 takes a smallfelem and serializes into a little * endian, 32 byte array. This assumes that the CPU is little-endian. */ static void smallfelem_to_bin32(u8 out[32], const smallfelem in) @@ -153,12 +153,12 @@ static int BN_to_felem(felem out, const BIGNUM *bn) int num_bytes; if (BN_is_negative(bn)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE); return 0; } 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); + ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE); return 0; } bin32_to_felem(out, b_out); @@ -242,9 +242,9 @@ static void longfelem_scalar(longfelem out, const u64 scalar) out[7] *= scalar; } -# define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9) -# define two105 (((limb)1) << 105) -# define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9) +#define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9) +#define two105 (((limb)1) << 105) +#define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9) /* zero105 is 0 mod p */ static const felem zero105 = @@ -287,9 +287,9 @@ static void felem_diff(felem out, const felem in) out[3] -= in[3]; } -# define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11) -# define two107 (((limb)1) << 107) -# define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11) +#define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11) +#define two107 (((limb)1) << 107) +#define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11) /* zero107 is 0 mod p */ static const felem zero107 = @@ -358,10 +358,10 @@ static void longfelem_diff(longfelem out, const longfelem in) out[7] -= in[7]; } -# define two64m0 (((limb)1) << 64) - 1 -# define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1 -# define two64m46 (((limb)1) << 64) - (((limb)1) << 46) -# define two64m32 (((limb)1) << 64) - (((limb)1) << 32) +#define two64m0 (((limb)1) << 64) - 1 +#define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1 +#define two64m46 (((limb)1) << 64) - (((limb)1) << 46) +#define two64m32 (((limb)1) << 64) - (((limb)1) << 32) /* zero110 is 0 mod p */ static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 }; @@ -711,9 +711,9 @@ static void felem_small_mul(longfelem out, const smallfelem small1, smallfelem_mul(out, small1, small2); } -# define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4) -# define two100 (((limb)1) << 100) -# define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4) +#define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4) +#define two100 (((limb)1) << 100) +#define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4) /* zero100 is 0 mod p */ static const felem zero100 = { two100m36m4, two100, two100m36p4, two100m36p4 }; @@ -1740,7 +1740,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out, bits |= get_bit(scalars[num], i + 1) << 2; bits |= get_bit(scalars[num], i) << 1; bits |= get_bit(scalars[num], i - 1); - ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + ossl_ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); /* * select the point to add or subtract, in constant time @@ -1781,54 +1781,55 @@ const EC_METHOD *EC_GFp_nistp256_method(void) static const EC_METHOD ret = { EC_FLAGS_DEFAULT_OCT, NID_X9_62_prime_field, - ec_GFp_nistp256_group_init, - ec_GFp_simple_group_finish, - ec_GFp_simple_group_clear_finish, - ec_GFp_nist_group_copy, - ec_GFp_nistp256_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_group_simple_order_bits, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_nistp256_point_get_affine_coordinates, + ossl_ec_GFp_nistp256_group_init, + ossl_ec_GFp_simple_group_finish, + ossl_ec_GFp_simple_group_clear_finish, + ossl_ec_GFp_nist_group_copy, + ossl_ec_GFp_nistp256_group_set_curve, + ossl_ec_GFp_simple_group_get_curve, + ossl_ec_GFp_simple_group_get_degree, + ossl_ec_group_simple_order_bits, + ossl_ec_GFp_simple_group_check_discriminant, + ossl_ec_GFp_simple_point_init, + ossl_ec_GFp_simple_point_finish, + ossl_ec_GFp_simple_point_clear_finish, + ossl_ec_GFp_simple_point_copy, + ossl_ec_GFp_simple_point_set_to_infinity, + ossl_ec_GFp_simple_point_set_affine_coordinates, + ossl_ec_GFp_nistp256_point_get_affine_coordinates, 0 /* point_set_compressed_coordinates */ , 0 /* point2oct */ , 0 /* oct2point */ , - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, - ec_GFp_nistp256_points_mul, - ec_GFp_nistp256_precompute_mult, - ec_GFp_nistp256_have_precompute_mult, - ec_GFp_nist_field_mul, - ec_GFp_nist_field_sqr, + ossl_ec_GFp_simple_add, + ossl_ec_GFp_simple_dbl, + ossl_ec_GFp_simple_invert, + ossl_ec_GFp_simple_is_at_infinity, + ossl_ec_GFp_simple_is_on_curve, + ossl_ec_GFp_simple_cmp, + ossl_ec_GFp_simple_make_affine, + ossl_ec_GFp_simple_points_make_affine, + ossl_ec_GFp_nistp256_points_mul, + ossl_ec_GFp_nistp256_precompute_mult, + ossl_ec_GFp_nistp256_have_precompute_mult, + ossl_ec_GFp_nist_field_mul, + ossl_ec_GFp_nist_field_sqr, 0 /* field_div */ , - ec_GFp_simple_field_inv, + ossl_ec_GFp_simple_field_inv, 0 /* field_encode */ , 0 /* field_decode */ , 0, /* field_set_to_one */ - ec_key_simple_priv2oct, - ec_key_simple_oct2priv, + ossl_ec_key_simple_priv2oct, + ossl_ec_key_simple_oct2priv, 0, /* set private */ - ec_key_simple_generate_key, - ec_key_simple_check_key, - ec_key_simple_generate_public_key, + ossl_ec_key_simple_generate_key, + ossl_ec_key_simple_check_key, + ossl_ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key, + ossl_ecdh_simple_compute_key, + ossl_ecdsa_simple_sign_setup, + ossl_ecdsa_simple_sign_sig, + ossl_ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ 0, /* blind_coordinates */ 0, /* ladder_pre */ @@ -1849,7 +1850,7 @@ static NISTP256_PRE_COMP *nistp256_pre_comp_new(void) NISTP256_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return ret; } @@ -1857,7 +1858,7 @@ static NISTP256_PRE_COMP *nistp256_pre_comp_new(void) ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } @@ -1880,7 +1881,7 @@ void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *pre) return; CRYPTO_DOWN_REF(&pre->references, &i, pre->lock); - REF_PRINT_COUNT("EC_nistp256", x); + REF_PRINT_COUNT("EC_nistp256", pre); if (i > 0) return; REF_ASSERT_ISNT(i < 0); @@ -1894,25 +1895,29 @@ void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *pre) * OPENSSL EC_METHOD FUNCTIONS */ -int ec_GFp_nistp256_group_init(EC_GROUP *group) +int ossl_ec_GFp_nistp256_group_init(EC_GROUP *group) { int ret; - ret = ec_GFp_simple_group_init(group); + ret = ossl_ec_GFp_simple_group_init(group); group->a_is_minus3 = 1; return ret; } -int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, - BN_CTX *ctx) +int ossl_ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { int ret = 0; - BN_CTX *new_ctx = NULL; BIGNUM *curve_p, *curve_a, *curve_b; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); curve_p = BN_CTX_get(ctx); curve_a = BN_CTX_get(ctx); @@ -1923,15 +1928,16 @@ int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a); BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b); if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { - ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE, - EC_R_WRONG_CURVE_PARAMETERS); + ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS); goto err; } group->field_mod_func = BN_nist_mod_256; - ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx); err: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } @@ -1939,18 +1945,17 @@ int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = * (X/Z^2, Y/Z^3) */ -int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx) +int ossl_ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) { felem z1, z2, x_in, y_in; smallfelem x_out, y_out; longfelem tmp; if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, - EC_R_POINT_AT_INFINITY); + ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); return 0; } if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) || @@ -1964,8 +1969,7 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, felem_contract(x_out, x_in); if (x != NULL) { if (!smallfelem_to_BN(x, x_out)) { - ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } } @@ -1976,8 +1980,7 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, felem_contract(y_out, y_in); if (y != NULL) { if (!smallfelem_to_BN(y, y_out)) { - ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } } @@ -1992,35 +1995,35 @@ static void make_points_affine(size_t num, smallfelem points[][3], * Runs in constant time, unless an input is the point at infinity (which * normally shouldn't happen). */ - ec_GFp_nistp_points_make_affine_internal(num, - points, - sizeof(smallfelem), - tmp_smallfelems, - (void (*)(void *))smallfelem_one, - smallfelem_is_zero_int, - (void (*)(void *, const void *)) - smallfelem_assign, - (void (*)(void *, const void *)) - smallfelem_square_contract, - (void (*) - (void *, const void *, - const void *)) - smallfelem_mul_contract, - (void (*)(void *, const void *)) - smallfelem_inv_contract, - /* nothing to contract */ - (void (*)(void *, const void *)) - smallfelem_assign); + ossl_ec_GFp_nistp_points_make_affine_internal(num, + points, + sizeof(smallfelem), + tmp_smallfelems, + (void (*)(void *))smallfelem_one, + smallfelem_is_zero_int, + (void (*)(void *, const void *)) + smallfelem_assign, + (void (*)(void *, const void *)) + smallfelem_square_contract, + (void (*) + (void *, const void *, + const void *)) + smallfelem_mul_contract, + (void (*)(void *, const void *)) + smallfelem_inv_contract, + /* nothing to contract */ + (void (*)(void *, const void *)) + smallfelem_assign); } /* * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL * values Result is stored in r (r can equal one of the inputs). */ -int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx) +int ossl_ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) { int ret = 0; int j; @@ -2065,12 +2068,12 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) || !smallfelem_to_BN(y, g_pre_comp[0][1][1]) || !smallfelem_to_BN(z, g_pre_comp[0][1][2])) { - ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } - if (!EC_POINT_set_Jprojective_coordinates_GFp(group, - generator, x, y, z, - ctx)) + if (!ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, + generator, + x, y, z, ctx)) goto err; if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) /* precomputation matches generator */ @@ -2097,7 +2100,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, OPENSSL_malloc(sizeof(*tmp_smallfelems) * (num_points * 17 + 1)); if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_smallfelems == NULL))) { - ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -2129,7 +2132,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, * constant-timeness */ if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } num_bytes = BN_bn2lebinpad(tmp_scalar, @@ -2139,7 +2142,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, secrets[i], sizeof(secrets[i])); } if (num_bytes < 0) { - ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* precompute multiples */ @@ -2183,7 +2186,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, * constant-timeness */ if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret)); @@ -2207,10 +2210,11 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, felem_contract(z_in, z_out); if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) || (!smallfelem_to_BN(z, z_in))) { - ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } - ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); + ret = ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, r, x, y, z, + ctx); err: BN_CTX_end(ctx); @@ -2221,22 +2225,29 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, return ret; } -int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +int ossl_ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { int ret = 0; NISTP256_PRE_COMP *pre = NULL; int i, j; - BN_CTX *new_ctx = NULL; BIGNUM *x, *y; EC_POINT *generator = NULL; smallfelem tmp_smallfelems[32]; felem x_tmp, y_tmp, z_tmp; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif /* throw away old precomputation */ EC_pre_comp_free(group); + +#ifndef FIPS_MODULE if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); @@ -2354,13 +2365,14 @@ int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx) err: BN_CTX_end(ctx); EC_POINT_free(generator); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif EC_nistp256_pre_comp_free(pre); return ret; } -int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group) +int ossl_ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group) { return HAVEPRECOMP(group, nistp256); } -#endif diff --git a/crypto/openssl/crypto/ec/ecp_nistp521.c b/crypto/openssl/crypto/ec/ecp_nistp521.c index 08b32787293b..31a97d793742 100644 --- a/crypto/openssl/crypto/ec/ecp_nistp521.c +++ b/crypto/openssl/crypto/ec/ecp_nistp521.c @@ -1,7 +1,7 @@ /* - * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -23,6 +23,12 @@ * limitations under the License. */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + /* * A 64-bit implementation of the NIST P-521 elliptic curve point multiplication * @@ -32,27 +38,22 @@ */ #include -#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128 -NON_EMPTY_TRANSLATION_UNIT -#else -# include -# include -# include "ec_local.h" +#include +#include +#include "ec_local.h" -# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16 - /* even with gcc, the typedef won't work for 32-bit platforms */ -typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit - * platforms */ -# else -# error "Your compiler doesn't appear to support 128-bit integer types" -# endif +#include "internal/numbers.h" + +#ifndef INT128_MAX +# error "Your compiler doesn't appear to support 128-bit integer types" +#endif typedef uint8_t u8; typedef uint64_t u64; /* - * The underlying field. P521 operates over GF(2^521-1). We can serialise an + * The underlying field. P521 operates over GF(2^521-1). We can serialize an * element of this field into 66 bytes where the most significant byte * contains only a single bit. We call this an felem_bytearray. */ @@ -125,7 +126,7 @@ static const felem_bytearray nistp521_curve_params[5] = { * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a * 'largefelem' */ -# define NLIMBS 9 +#define NLIMBS 9 typedef uint64_t limb; typedef limb limb_aX __attribute((__aligned__(1))); @@ -153,7 +154,7 @@ static void bin66_to_felem(felem out, const u8 in[66]) } /* - * felem_to_bin66 takes an felem and serialises into a little endian, 66 byte + * felem_to_bin66 takes an felem and serializes into a little endian, 66 byte * array. This assumes that the CPU is little-endian. */ static void felem_to_bin66(u8 out[66], const felem in) @@ -177,12 +178,12 @@ static int BN_to_felem(felem out, const BIGNUM *bn) int num_bytes; if (BN_is_negative(bn)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE); return 0; } 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); + ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE); return 0; } bin66_to_felem(out, b_out); @@ -400,7 +401,7 @@ static void felem_diff128(largefelem out, const largefelem in) * On exit: * out[i] < 17 * max(in[i]) * max(in[i]) */ -static void felem_square(largefelem out, const felem in) +static void felem_square_ref(largefelem out, const felem in) { felem inx2, inx4; felem_scalar(inx2, in, 2); @@ -484,7 +485,7 @@ static void felem_square(largefelem out, const felem in) * On exit: * out[i] < 17 * max(in1[i]) * max(in2[i]) */ -static void felem_mul(largefelem out, const felem in1, const felem in2) +static void felem_mul_ref(largefelem out, const felem in1, const felem in2) { felem in2x2; felem_scalar(in2x2, in2, 2); @@ -674,6 +675,57 @@ static void felem_reduce(felem out, const largefelem in) */ } +#if defined(ECP_NISTP521_ASM) +void felem_square_wrapper(largefelem out, const felem in); +void felem_mul_wrapper(largefelem out, const felem in1, const felem in2); + +static void (*felem_square_p)(largefelem out, const felem in) = + felem_square_wrapper; +static void (*felem_mul_p)(largefelem out, const felem in1, const felem in2) = + felem_mul_wrapper; + +void p521_felem_square(largefelem out, const felem in); +void p521_felem_mul(largefelem out, const felem in1, const felem in2); + +# if defined(_ARCH_PPC64) +# include "crypto/ppc_arch.h" +# endif + +void felem_select(void) +{ +# if defined(_ARCH_PPC64) + if ((OPENSSL_ppccap_P & PPC_MADD300) && (OPENSSL_ppccap_P & PPC_ALTIVEC)) { + felem_square_p = p521_felem_square; + felem_mul_p = p521_felem_mul; + + return; + } +# endif + + /* Default */ + felem_square_p = felem_square_ref; + felem_mul_p = felem_mul_ref; +} + +void felem_square_wrapper(largefelem out, const felem in) +{ + felem_select(); + felem_square_p(out, in); +} + +void felem_mul_wrapper(largefelem out, const felem in1, const felem in2) +{ + felem_select(); + felem_mul_p(out, in1, in2); +} + +# define felem_square felem_square_p +# define felem_mul felem_mul_p +#else +# define felem_square felem_square_ref +# define felem_mul felem_mul_ref +#endif + static void felem_square_reduce(felem out, const felem in) { largefelem tmp; @@ -1266,8 +1318,8 @@ static void point_add(felem x3, felem y3, felem z3, * This is obviously not constant-time but it will almost-never happen * for ECDH / ECDSA. The case where it can happen is during scalar-mult * where the intermediate value gets very close to the group order. - * Since |ec_GFp_nistp_recode_scalar_bits| produces signed digits for - * the scalar, it's possible for the intermediate value to be a small + * Since |ossl_ec_GFp_nistp_recode_scalar_bits| produces signed digits + * for the scalar, it's possible for the intermediate value to be a small * negative multiple of the base point, and for the final signed digit * to be the same value. We believe that this only occurs for the scalar * 1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff @@ -1584,7 +1636,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out, bits |= get_bit(scalars[num], i + 1) << 2; bits |= get_bit(scalars[num], i) << 1; bits |= get_bit(scalars[num], i - 1); - ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + ossl_ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); /* * select the point to add or subtract, in constant time @@ -1622,54 +1674,55 @@ const EC_METHOD *EC_GFp_nistp521_method(void) static const EC_METHOD ret = { EC_FLAGS_DEFAULT_OCT, NID_X9_62_prime_field, - ec_GFp_nistp521_group_init, - ec_GFp_simple_group_finish, - ec_GFp_simple_group_clear_finish, - ec_GFp_nist_group_copy, - ec_GFp_nistp521_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_group_simple_order_bits, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_nistp521_point_get_affine_coordinates, + ossl_ec_GFp_nistp521_group_init, + ossl_ec_GFp_simple_group_finish, + ossl_ec_GFp_simple_group_clear_finish, + ossl_ec_GFp_nist_group_copy, + ossl_ec_GFp_nistp521_group_set_curve, + ossl_ec_GFp_simple_group_get_curve, + ossl_ec_GFp_simple_group_get_degree, + ossl_ec_group_simple_order_bits, + ossl_ec_GFp_simple_group_check_discriminant, + ossl_ec_GFp_simple_point_init, + ossl_ec_GFp_simple_point_finish, + ossl_ec_GFp_simple_point_clear_finish, + ossl_ec_GFp_simple_point_copy, + ossl_ec_GFp_simple_point_set_to_infinity, + ossl_ec_GFp_simple_point_set_affine_coordinates, + ossl_ec_GFp_nistp521_point_get_affine_coordinates, 0 /* point_set_compressed_coordinates */ , 0 /* point2oct */ , 0 /* oct2point */ , - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, - ec_GFp_nistp521_points_mul, - ec_GFp_nistp521_precompute_mult, - ec_GFp_nistp521_have_precompute_mult, - ec_GFp_nist_field_mul, - ec_GFp_nist_field_sqr, + ossl_ec_GFp_simple_add, + ossl_ec_GFp_simple_dbl, + ossl_ec_GFp_simple_invert, + ossl_ec_GFp_simple_is_at_infinity, + ossl_ec_GFp_simple_is_on_curve, + ossl_ec_GFp_simple_cmp, + ossl_ec_GFp_simple_make_affine, + ossl_ec_GFp_simple_points_make_affine, + ossl_ec_GFp_nistp521_points_mul, + ossl_ec_GFp_nistp521_precompute_mult, + ossl_ec_GFp_nistp521_have_precompute_mult, + ossl_ec_GFp_nist_field_mul, + ossl_ec_GFp_nist_field_sqr, 0 /* field_div */ , - ec_GFp_simple_field_inv, + ossl_ec_GFp_simple_field_inv, 0 /* field_encode */ , 0 /* field_decode */ , 0, /* field_set_to_one */ - ec_key_simple_priv2oct, - ec_key_simple_oct2priv, + ossl_ec_key_simple_priv2oct, + ossl_ec_key_simple_oct2priv, 0, /* set private */ - ec_key_simple_generate_key, - ec_key_simple_check_key, - ec_key_simple_generate_public_key, + ossl_ec_key_simple_generate_key, + ossl_ec_key_simple_check_key, + ossl_ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key, + ossl_ecdh_simple_compute_key, + ossl_ecdsa_simple_sign_setup, + ossl_ecdsa_simple_sign_sig, + ossl_ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ 0, /* blind_coordinates */ 0, /* ladder_pre */ @@ -1690,7 +1743,7 @@ static NISTP521_PRE_COMP *nistp521_pre_comp_new(void) NISTP521_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return ret; } @@ -1698,7 +1751,7 @@ static NISTP521_PRE_COMP *nistp521_pre_comp_new(void) ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } @@ -1721,7 +1774,7 @@ void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *p) return; CRYPTO_DOWN_REF(&p->references, &i, p->lock); - REF_PRINT_COUNT("EC_nistp521", x); + REF_PRINT_COUNT("EC_nistp521", p); if (i > 0) return; REF_ASSERT_ISNT(i < 0); @@ -1735,25 +1788,29 @@ void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *p) * OPENSSL EC_METHOD FUNCTIONS */ -int ec_GFp_nistp521_group_init(EC_GROUP *group) +int ossl_ec_GFp_nistp521_group_init(EC_GROUP *group) { int ret; - ret = ec_GFp_simple_group_init(group); + ret = ossl_ec_GFp_simple_group_init(group); group->a_is_minus3 = 1; return ret; } -int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, - BN_CTX *ctx) +int ossl_ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { int ret = 0; - BN_CTX *new_ctx = NULL; BIGNUM *curve_p, *curve_a, *curve_b; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); curve_p = BN_CTX_get(ctx); curve_a = BN_CTX_get(ctx); @@ -1764,15 +1821,16 @@ int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a); BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b); if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { - ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE, - EC_R_WRONG_CURVE_PARAMETERS); + ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS); goto err; } group->field_mod_func = BN_nist_mod_521; - ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx); err: BN_CTX_end(ctx); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif return ret; } @@ -1780,17 +1838,16 @@ int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = * (X/Z^2, Y/Z^3) */ -int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx) +int ossl_ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) { felem z1, z2, x_in, y_in, x_out, y_out; largefelem tmp; if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, - EC_R_POINT_AT_INFINITY); + ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); return 0; } if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) || @@ -1804,8 +1861,7 @@ int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, felem_contract(x_out, x_in); if (x != NULL) { if (!felem_to_BN(x, x_out)) { - ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } } @@ -1816,8 +1872,7 @@ int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, felem_contract(y_out, y_in); if (y != NULL) { if (!felem_to_BN(y, y_out)) { - ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } } @@ -1832,36 +1887,36 @@ static void make_points_affine(size_t num, felem points[][3], * Runs in constant time, unless an input is the point at infinity (which * normally shouldn't happen). */ - ec_GFp_nistp_points_make_affine_internal(num, - points, - sizeof(felem), - tmp_felems, - (void (*)(void *))felem_one, - felem_is_zero_int, - (void (*)(void *, const void *)) - felem_assign, - (void (*)(void *, const void *)) - felem_square_reduce, (void (*) - (void *, - const void - *, - const void - *)) - felem_mul_reduce, - (void (*)(void *, const void *)) - felem_inv, - (void (*)(void *, const void *)) - felem_contract); + ossl_ec_GFp_nistp_points_make_affine_internal(num, + points, + sizeof(felem), + tmp_felems, + (void (*)(void *))felem_one, + felem_is_zero_int, + (void (*)(void *, const void *)) + felem_assign, + (void (*)(void *, const void *)) + felem_square_reduce, (void (*) + (void *, + const void + *, + const void + *)) + felem_mul_reduce, + (void (*)(void *, const void *)) + felem_inv, + (void (*)(void *, const void *)) + felem_contract); } /* * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL * values Result is stored in r (r can equal one of the inputs). */ -int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx) +int ossl_ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) { int ret = 0; int j; @@ -1905,12 +1960,12 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, if (!felem_to_BN(x, g_pre_comp[1][0]) || !felem_to_BN(y, g_pre_comp[1][1]) || !felem_to_BN(z, g_pre_comp[1][2])) { - ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } - if (!EC_POINT_set_Jprojective_coordinates_GFp(group, - generator, x, y, z, - ctx)) + if (!ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, + generator, + x, y, z, ctx)) goto err; if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) /* precomputation matches generator */ @@ -1938,7 +1993,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, OPENSSL_malloc(sizeof(*tmp_felems) * (num_points * 17 + 1)); if ((secrets == NULL) || (pre_comp == NULL) || (mixed && (tmp_felems == NULL))) { - ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -1968,7 +2023,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, * constant-timeness */ if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } num_bytes = BN_bn2lebinpad(tmp_scalar, @@ -1978,7 +2033,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, secrets[i], sizeof(secrets[i])); } if (num_bytes < 0) { - ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* precompute multiples */ @@ -2020,7 +2075,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, * constant-timeness */ if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret)); @@ -2045,10 +2100,11 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, felem_contract(z_in, z_out); if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) || (!felem_to_BN(z, z_in))) { - ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } - ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); + ret = ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, r, x, y, z, + ctx); err: BN_CTX_end(ctx); @@ -2059,21 +2115,28 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, return ret; } -int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +int ossl_ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { int ret = 0; NISTP521_PRE_COMP *pre = NULL; int i, j; - BN_CTX *new_ctx = NULL; BIGNUM *x, *y; EC_POINT *generator = NULL; felem tmp_felems[16]; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif /* throw away old precomputation */ EC_pre_comp_free(group); + +#ifndef FIPS_MODULE if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); @@ -2161,14 +2224,14 @@ int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx) err: BN_CTX_end(ctx); EC_POINT_free(generator); +#ifndef FIPS_MODULE BN_CTX_free(new_ctx); +#endif EC_nistp521_pre_comp_free(pre); return ret; } -int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group) +int ossl_ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group) { return HAVEPRECOMP(group, nistp521); } - -#endif diff --git a/crypto/openssl/crypto/ec/ecp_nistputil.c b/crypto/openssl/crypto/ec/ecp_nistputil.c index 60e1325c340f..4e8c0e276769 100644 --- a/crypto/openssl/crypto/ec/ecp_nistputil.c +++ b/crypto/openssl/crypto/ec/ecp_nistputil.c @@ -1,7 +1,7 @@ /* - * Copyright 2011-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -23,17 +23,20 @@ * limitations under the License. */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include -#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128 -NON_EMPTY_TRANSLATION_UNIT -#else /* * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c. */ -# include -# include "ec_local.h" +#include +#include "ec_local.h" /* * Convert an array of points into affine coordinates. (If the point at @@ -46,7 +49,8 @@ NON_EMPTY_TRANSLATION_UNIT * of size 'felem_size'. tmp_felems needs to point to a temporary array of * 'num'+1 field elements for storage of intermediate values. */ -void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, +void +ossl_ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, size_t felem_size, void *tmp_felems, void (*felem_one) (void *out), @@ -74,10 +78,10 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, { int i = 0; -# define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size]) -# define X(I) (&((char *)point_array)[3*(I) * felem_size]) -# define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size]) -# define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size]) +#define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size]) +#define X(I) (&((char *)point_array)[3*(I) * felem_size]) +#define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size]) +#define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size]) if (!felem_is_zero(Z(0))) felem_assign(tmp_felem(0), Z(0)); @@ -206,8 +210,8 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, * 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, - unsigned char *digit, unsigned char in) +void ossl_ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, + unsigned char *digit, unsigned char in) { unsigned char s, d; @@ -220,4 +224,3 @@ void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, *sign = s & 1; *digit = d; } -#endif diff --git a/crypto/openssl/crypto/ec/ecp_nistz256-armv8.S b/crypto/openssl/crypto/ec/ecp_nistz256-armv8.S new file mode 100644 index 000000000000..e7230f81f69c --- /dev/null +++ b/crypto/openssl/crypto/ec/ecp_nistz256-armv8.S @@ -0,0 +1,4242 @@ +#include "arm_arch.h" + +.text +.globl ecp_nistz256_precomputed +.type ecp_nistz256_precomputed,%object +.align 12 +ecp_nistz256_precomputed: +.byte 0x3c,0x4d,0x27,0xcc,0xf5,0x4a,0x4f,0x8f,0xe8,0xc8,0x04,0x68,0x09,0x4a,0x5b,0x80,0x9d,0x7a,0xe8,0x31,0x08,0x76,0x68,0x19,0x9f,0x08,0xb4,0x1f,0x32,0x43,0x89,0xd8,0x34,0xd3,0xf5,0xb7,0xb5,0xee,0x42,0x3e,0x91,0x01,0x06,0x7c,0xbf,0xd9,0x97,0x12,0xd3,0x1a,0xc9,0x04,0x8d,0x53,0x83,0x14,0x28,0xf0,0x8e,0x19,0xcc,0x91,0xe5,0x80 +.byte 0x14,0xd6,0xc1,0x8d,0x61,0x66,0x3b,0xa7,0x20,0x1e,0xe4,0x77,0xd7,0x66,0x05,0xfb,0x5c,0xa9,0x9a,0x7a,0xb2,0x30,0x50,0x28,0x87,0x80,0xfe,0xcd,0xe1,0xb3,0xff,0xa3,0x45,0x3c,0x7e,0x9b,0x08,0xc0,0xc1,0x9f,0x2e,0xad,0x7d,0x89,0x79,0x90,0x60,0xc6,0xac,0x17,0x64,0x59,0x4d,0xcf,0x56,0x7a,0xca,0x82,0xaa,0x6e,0x04,0x2f,0x1f,0x8b +.byte 0xa9,0xdd,0xeb,0x91,0x5c,0x77,0x17,0x99,0x4e,0xc2,0x45,0x69,0x2e,0xcf,0x60,0xc6,0x3c,0xad,0x65,0x33,0x35,0x6f,0xe4,0xd0,0x37,0x1f,0xe2,0x2c,0x66,0x98,0x55,0xe3,0x66,0xa2,0xc6,0x21,0xce,0x63,0x59,0x2e,0xd2,0x2b,0x8a,0x5a,0xcd,0xee,0xa7,0xad,0xf6,0x8c,0x3f,0x44,0x6c,0x12,0x30,0x8d,0xca,0xea,0x46,0x8a,0x4c,0x96,0xf9,0x96 +.byte 0x18,0x10,0x4e,0x46,0xc4,0x3e,0xa0,0x94,0x26,0x9d,0x62,0xd2,0x4b,0xb0,0xbc,0x0b,0xd5,0x56,0xa5,0xd2,0xc1,0x2f,0x2d,0x15,0xd8,0xed,0x97,0x17,0xcb,0x32,0x67,0xc5,0x0f,0x7c,0xde,0xa8,0x8c,0x4d,0xa0,0xb8,0x2e,0xed,0x24,0xd5,0xd5,0x49,0xca,0x77,0x1f,0x48,0x3b,0x83,0x54,0xb2,0xe7,0x7e,0x7a,0xa7,0x5c,0xed,0x7f,0xa1,0x9f,0x05 +.byte 0xd4,0xd4,0x90,0x0d,0xae,0x37,0x4e,0xd1,0x8f,0xd1,0x0a,0xa7,0x63,0x5b,0xb7,0x65,0xcb,0xc8,0xba,0x29,0xec,0x35,0x53,0xb2,0xac,0x32,0xf4,0xb7,0x6a,0xb1,0x69,0xcf,0x56,0x14,0x7f,0xd6,0xc5,0xca,0x88,0x1d,0x49,0xcf,0xfd,0x1f,0xcc,0xb1,0x13,0x30,0x42,0xd0,0x1c,0x6e,0x38,0x8e,0xf9,0x40,0xe7,0xe8,0xd6,0x28,0x1a,0x75,0x31,0xf3 +.byte 0x30,0x46,0x3f,0xb5,0x8a,0x47,0x35,0x4c,0x6e,0xdb,0x26,0x1a,0x25,0xa3,0xd8,0x0b,0x1d,0x51,0x12,0x91,0x4c,0x11,0x76,0x83,0x19,0xad,0x2a,0x3e,0xb4,0x1c,0x3c,0xfc,0x14,0x20,0x84,0x58,0x7b,0xc3,0x94,0x68,0x60,0x5c,0x3f,0x7c,0x26,0xb5,0x75,0x41,0x0b,0xc2,0xec,0xf3,0x96,0x5b,0xbb,0x41,0x32,0x00,0x4e,0x68,0xeb,0xf1,0xd9,0x96 +.byte 0xe7,0x00,0xac,0xb0,0x1b,0x39,0x46,0xf1,0xc9,0x18,0x7d,0xb7,0xc4,0x42,0xbc,0x8b,0x09,0x3e,0xa9,0x97,0x2e,0xc6,0xf8,0x38,0xa3,0xe4,0x2c,0x52,0x5d,0x24,0xf7,0xc5,0x15,0xab,0x16,0x5e,0x46,0x2c,0xd8,0xd7,0x4d,0xb3,0xf2,0xfd,0xe4,0x75,0x3c,0x34,0x95,0xb9,0x8c,0x92,0x35,0x42,0x8b,0xc4,0xc8,0x6c,0xd4,0x1e,0x67,0x35,0xd3,0x6d +.byte 0x79,0x85,0xff,0x74,0xbe,0x40,0x07,0x27,0x75,0x2c,0xea,0x04,0xcc,0xa2,0x72,0x80,0x97,0x5f,0xfe,0x8a,0x56,0x0f,0xf4,0x6d,0xa4,0x61,0x04,0x4b,0x5e,0xb4,0xe2,0xd8,0x87,0xb6,0xfd,0x3d,0x00,0x8a,0xa9,0xe4,0x62,0x5f,0x4f,0xec,0x1e,0x40,0x28,0x6b,0x21,0x0f,0x50,0x26,0x97,0xa0,0x25,0x8f,0x3e,0xf2,0x69,0xdc,0x36,0xe5,0xb8,0xdb +.byte 0x01,0x7d,0xfb,0x73,0x7d,0x3e,0xf7,0x55,0x41,0x39,0xe0,0x33,0x0d,0xe3,0x4b,0x6b,0x7b,0x3e,0x6e,0xdc,0x7d,0x9a,0x6e,0x35,0xb0,0x38,0x13,0x92,0x80,0xa1,0xe6,0xbf,0x03,0x9d,0xb7,0x7f,0x55,0xce,0x46,0x3c,0x22,0xc7,0xfa,0xfb,0x18,0xba,0x06,0xa0,0x09,0x78,0x3f,0xc0,0x79,0x5f,0xe6,0x6a,0x29,0xaf,0xd1,0xc7,0x84,0xa7,0xed,0xb9 +.byte 0xb6,0x82,0x81,0xc1,0x53,0xee,0x00,0x34,0xa8,0x81,0xdf,0x5a,0xd3,0x07,0x7e,0x2e,0x17,0x40,0xa1,0x2b,0xf4,0x2a,0x1f,0x9a,0x67,0x75,0x73,0xa8,0x58,0x65,0x17,0xdf,0xf1,0x84,0x76,0xc5,0x8d,0x48,0x93,0xe1,0x28,0xa5,0x73,0x10,0x6e,0x9e,0x39,0x03,0x69,0x52,0xdf,0xf9,0x46,0x7c,0x5b,0xf3,0x5b,0x9a,0x63,0xd9,0x4f,0xf5,0x8e,0x73 +.byte 0xed,0x33,0x7d,0x23,0xb9,0x6c,0x3c,0x9b,0xa7,0xcf,0x7f,0x34,0x6f,0x97,0xe2,0xfe,0x0a,0x8b,0xe1,0x86,0x83,0x91,0x2e,0xdd,0x6b,0xb1,0xbf,0xa6,0x92,0x4f,0x30,0x79,0x68,0x91,0x3e,0x06,0x17,0xe9,0x0b,0x25,0x07,0xa6,0x88,0x91,0x6c,0x6e,0xc8,0xd8,0xdc,0x68,0x5e,0x45,0xf2,0x55,0xef,0x56,0x38,0x29,0xd0,0x89,0x40,0x58,0x51,0x9f +.byte 0x5f,0xa4,0x08,0xc6,0x94,0x34,0xd2,0x6f,0x59,0x0f,0x6e,0xca,0x85,0x7f,0x56,0x3f,0xac,0x8f,0x25,0x0f,0x47,0xe3,0x9e,0x40,0xed,0xd8,0xae,0x30,0x0d,0xb4,0x47,0x40,0x4b,0xa3,0x23,0x1b,0x7f,0x0f,0xff,0xdf,0x6f,0x1d,0x87,0xb2,0x94,0xa0,0x36,0xbb,0x53,0x13,0x1e,0xaf,0x92,0xf8,0x07,0x95,0xc7,0xe4,0xa8,0x41,0xa9,0xed,0xf0,0x08 +.byte 0xfc,0xc1,0x4a,0xed,0x9a,0x4f,0x13,0xc5,0xed,0x8a,0x95,0xf5,0x69,0xf7,0xee,0x75,0xb6,0x4d,0xba,0x8f,0x65,0x23,0xe8,0x50,0x9e,0x7a,0xd7,0x28,0x3a,0x49,0xe7,0x4c,0x7c,0xc6,0x64,0xbd,0x8c,0x17,0x14,0x0b,0xb5,0xe3,0xb4,0xab,0x0b,0x9a,0xa9,0x29,0x84,0xaa,0xba,0x69,0xc4,0x2e,0xbf,0xca,0x57,0x0d,0xd3,0x36,0x21,0x61,0x00,0x13 +.byte 0x95,0xe3,0xf8,0xa6,0x64,0x74,0x02,0xb5,0xbf,0x86,0x07,0xde,0x67,0x48,0x23,0xe0,0x24,0x96,0x3a,0x86,0xb2,0xfa,0xa7,0x75,0xb4,0x26,0x42,0xcb,0x96,0x4e,0xf7,0x90,0xae,0xa5,0xe4,0xd0,0x45,0x31,0xe7,0x0f,0xe0,0xcb,0xbf,0x94,0x94,0x33,0x4f,0x65,0x04,0xfb,0xc0,0xc4,0x3f,0x51,0xa5,0xf3,0xea,0xc8,0xd5,0x23,0x66,0xe0,0x48,0x09 +.byte 0xba,0x6a,0x27,0x50,0xec,0xae,0xd2,0x2a,0xe6,0xf9,0xe4,0xde,0x35,0x6e,0xcc,0x82,0x76,0xfc,0x36,0x16,0xe1,0x9f,0xc7,0x0d,0xc1,0xc9,0x6a,0x23,0xbe,0xa1,0x3c,0xfd,0xce,0xa7,0x2e,0x91,0x36,0x23,0x5a,0x20,0xdf,0x55,0xc5,0x91,0x32,0x5c,0x62,0x49,0xe7,0x8b,0x0b,0x0e,0x9c,0x2e,0xee,0x1f,0xfe,0xca,0x00,0xfc,0x55,0xd7,0x9c,0x0a +.byte 0x75,0xaa,0xb0,0x46,0x90,0x55,0x2b,0x46,0xab,0x98,0x9d,0xab,0x0e,0x12,0x03,0x58,0xf1,0x4a,0x68,0x59,0x74,0xc9,0x37,0x6d,0x6f,0xe6,0xd3,0x73,0xf1,0xa3,0xdd,0xbe,0x85,0xca,0x74,0xc6,0xb6,0x51,0x6f,0x83,0x6f,0xa1,0x80,0x00,0x00,0x78,0x0a,0xa7,0xff,0xa7,0xe2,0x2e,0x5f,0x4f,0x31,0xbb,0x1b,0x99,0x21,0x33,0x59,0x6e,0x03,0x38 +.byte 0x10,0xd9,0x98,0xf2,0x0c,0xad,0x08,0x6b,0x00,0x49,0xb5,0x5e,0x11,0x60,0x70,0x49,0xff,0x79,0xac,0xba,0x30,0x3d,0x69,0x9f,0xaf,0xfb,0xd7,0xeb,0xe2,0xcd,0x0d,0x97,0xb9,0x94,0xc8,0x6e,0x06,0x3b,0x64,0x80,0x71,0x8f,0x81,0xb0,0x58,0xe0,0xc7,0xbd,0x27,0x6a,0xd4,0xb7,0xd9,0x6c,0xc1,0x44,0x38,0xe1,0x36,0xbc,0x0a,0x33,0x26,0x01 +.byte 0x25,0x90,0xbc,0x0a,0xc2,0xa3,0xbb,0xfc,0xeb,0x0b,0x1a,0x38,0x98,0x26,0x93,0xf5,0x2d,0x29,0x41,0x83,0x3b,0xba,0x40,0x46,0xf3,0xf6,0xfd,0x53,0xb9,0x7a,0x60,0x01,0x8a,0x8d,0xb4,0x57,0xd8,0xf3,0x36,0x72,0x22,0x2f,0x59,0xd3,0x7f,0x25,0xf2,0x05,0x61,0xfa,0x18,0x28,0xac,0xd5,0x14,0x00,0xaf,0x8b,0x7c,0x39,0xb5,0xa2,0xcb,0x1e +.byte 0x62,0x14,0xcb,0x10,0x76,0x17,0x23,0x2c,0xc8,0x25,0xac,0x37,0x9e,0x83,0x81,0x83,0xfe,0x2e,0x2c,0xd2,0x3f,0xf8,0x58,0x2b,0xf1,0x7f,0x4f,0xe1,0x17,0xc7,0xf7,0xad,0x57,0x67,0xc2,0x57,0x77,0x2e,0xfb,0xf2,0xce,0xa9,0x74,0x81,0x47,0xf8,0x5a,0x88,0x76,0xb1,0x43,0x75,0xc8,0xc4,0xc8,0x60,0x1e,0xd7,0xd1,0x1c,0xce,0x89,0x82,0xc6 +.byte 0x77,0x8d,0x87,0xe8,0xd0,0x5b,0x0c,0xf0,0x44,0x48,0x8d,0xee,0x55,0xc6,0xe4,0x2c,0x2c,0x41,0x75,0x5d,0x5a,0xd2,0xa3,0x1d,0x32,0x85,0x08,0xcf,0x03,0x3a,0x3c,0xfe,0x65,0x75,0xef,0xd2,0xa6,0x22,0x16,0x66,0x39,0x30,0x05,0xe3,0x57,0xab,0x71,0x6d,0x28,0xd5,0x2f,0xc6,0xa8,0x25,0x46,0x14,0xfd,0x7e,0xa2,0x67,0x7e,0x20,0x91,0xc2 +.byte 0x2b,0x03,0xdd,0xac,0xaa,0x1a,0xb5,0x2a,0x04,0xd6,0x15,0x9d,0x3f,0x54,0x24,0x7c,0x75,0xab,0x77,0xd9,0x6c,0x85,0xa2,0xf9,0x33,0xeb,0xeb,0xc0,0x27,0xcd,0x9d,0x58,0xae,0xa3,0x34,0x10,0xae,0x85,0x7d,0x4c,0x15,0x4c,0x90,0x46,0xe0,0x5b,0xec,0xa7,0xb2,0x68,0x85,0x01,0xed,0xf9,0x4a,0x85,0xe3,0xb6,0xea,0xe2,0x53,0xc0,0x32,0x83 +.byte 0x73,0x05,0x77,0xac,0xb5,0x96,0xaa,0xf0,0x9c,0x2c,0xa4,0xd2,0xd4,0xbf,0x74,0x2f,0x39,0x47,0x22,0x99,0x50,0x06,0x5f,0xcb,0x99,0xc5,0xc9,0x2e,0x70,0xd6,0x68,0x6a,0xc4,0x73,0x41,0xcb,0x8b,0xfd,0x23,0x98,0x11,0x59,0xad,0x20,0x8a,0x0d,0xaf,0xaa,0xd0,0xe2,0xeb,0x32,0x8b,0x6f,0x0e,0x43,0x12,0xe3,0x27,0x8f,0xf6,0xa4,0x76,0x0b +.byte 0xfb,0x22,0xad,0xda,0x1c,0x0a,0x3e,0x90,0xc0,0x7d,0xf3,0x09,0xbc,0x17,0x33,0xef,0xf1,0xf2,0x84,0x80,0x2a,0x0b,0x82,0xd7,0x95,0xc7,0xd2,0x08,0x4a,0xf4,0xf5,0x6d,0x09,0x06,0x8e,0xe4,0x74,0x63,0x8f,0x09,0xca,0xe2,0xd9,0x0e,0x1e,0x03,0x20,0x1b,0x4c,0xfb,0x1d,0x5a,0x2e,0x28,0xeb,0x84,0x82,0x6f,0x97,0x6f,0xcd,0x7a,0xc3,0xa7 +.byte 0x79,0x73,0x66,0x0c,0x94,0xd5,0xf4,0x8f,0x2c,0x73,0x1f,0x24,0xbc,0x17,0xee,0xd5,0xb0,0xa6,0xb8,0x04,0x6d,0x6a,0xd0,0x61,0xe3,0x1a,0x49,0x97,0x94,0xc5,0x8e,0xbc,0xac,0x5b,0x0b,0x0a,0xc5,0x74,0x06,0x89,0xee,0xc2,0xb7,0x5f,0x1b,0xa1,0x6b,0x1a,0xff,0xed,0xda,0x90,0x91,0xc1,0x0d,0x6a,0x06,0xd6,0xcb,0x02,0x71,0x17,0x95,0x7d +.byte 0xc6,0x3b,0x7e,0x6b,0xc8,0x73,0x03,0x0d,0x6b,0x8f,0x73,0x56,0x59,0x2e,0x09,0x23,0x4e,0xda,0xfc,0x4e,0xfc,0xa4,0x42,0x15,0x2e,0x10,0x6a,0x97,0x48,0x3c,0xb4,0xa4,0x0c,0x64,0x21,0xc3,0xeb,0x6c,0xac,0x27,0x4f,0x43,0x94,0x91,0x78,0xdc,0xfd,0xad,0x2b,0xa7,0x43,0x42,0xb0,0x51,0xdd,0x63,0xcc,0xcd,0xb7,0x15,0xfa,0x13,0x8d,0xc7 +.byte 0x55,0x3a,0x74,0x17,0x23,0x36,0x3e,0x23,0xe1,0x42,0x90,0xe1,0xb7,0xc7,0xda,0xb7,0x57,0xeb,0xc3,0xfb,0x62,0x58,0xbf,0x31,0x2a,0xfb,0xc7,0xdb,0x3d,0xfc,0x87,0x32,0xb1,0x3e,0xe5,0x3d,0x94,0x3d,0x86,0x32,0x61,0xfe,0x19,0xd2,0x32,0x31,0x8b,0x43,0xdb,0xab,0xa4,0xe5,0x34,0xc8,0x30,0xae,0x8c,0x02,0x53,0x99,0x35,0xb4,0x56,0x38 +.byte 0x37,0xcf,0xff,0xb0,0x05,0x21,0x12,0x65,0xc4,0xb3,0x9c,0x83,0x95,0x12,0xd3,0x03,0x7a,0x80,0x97,0x5b,0x67,0x33,0x27,0xfc,0x43,0xf2,0xf7,0xaa,0x60,0xb6,0xfc,0x55,0x44,0x30,0xa3,0x4a,0xa3,0x60,0x31,0xf7,0x01,0xfa,0xb0,0x8d,0x82,0x29,0xa7,0x03,0xb7,0x7e,0x3f,0xe5,0x66,0x26,0xb7,0x51,0xcf,0x8d,0xdd,0x6f,0x83,0x39,0xfc,0x9b +.byte 0xa5,0x3d,0xb6,0x41,0x89,0x54,0xc3,0xb2,0xf0,0x24,0x64,0xcb,0x53,0xfd,0x0a,0x91,0x6c,0x6f,0x28,0xfe,0xc1,0xe9,0x17,0x2e,0x65,0x55,0x2e,0xf2,0x48,0x52,0xb1,0x69,0xf0,0xdd,0x42,0xd5,0xdf,0x7c,0x36,0x75,0xdb,0x5b,0x3d,0xa9,0x6d,0xa4,0xeb,0x47,0x4f,0x2b,0x5c,0xd0,0x30,0xee,0xa7,0x74,0x6a,0x64,0x8a,0xbc,0x9b,0xe5,0x82,0x56 +.byte 0x76,0xe4,0x3f,0xf5,0x05,0x59,0x19,0x1e,0x80,0x47,0xf1,0x77,0xac,0x32,0x43,0x80,0x0a,0x1b,0x28,0xb6,0xf4,0xe8,0x7c,0x2f,0xeb,0xa8,0x4b,0x6a,0x59,0xb5,0xf8,0x77,0x68,0xd4,0x86,0x6c,0x87,0xdc,0xc4,0x00,0x4f,0xce,0xdb,0xf6,0x34,0xc3,0x74,0x02,0x08,0xdb,0x0d,0x34,0x8d,0xea,0x49,0x4a,0x30,0x5f,0x1b,0xcd,0xa6,0x3a,0x34,0x94 +.byte 0x5f,0x32,0x6a,0x62,0x96,0x4b,0x51,0x89,0x30,0xc9,0x90,0xdf,0x77,0x73,0x0e,0x3c,0x5c,0xbd,0x5c,0xee,0xd9,0x77,0xea,0x23,0x42,0xaa,0xa5,0x6b,0xf9,0x8c,0xc4,0x70,0x68,0xdd,0x0b,0x65,0xa3,0xc7,0xe4,0x7b,0x0a,0x89,0x85,0x25,0x7d,0x84,0x99,0x39,0xe6,0xb8,0xbe,0x7f,0x31,0x0f,0x84,0x0c,0x98,0x72,0xab,0x4c,0x44,0xb0,0xa4,0x83 +.byte 0x90,0xbb,0x93,0x73,0x07,0x07,0xba,0x63,0x5b,0x61,0x70,0xe1,0x84,0xae,0xaa,0xd6,0xa3,0x5a,0x54,0xd1,0xea,0xc7,0x2c,0x7b,0x67,0x4b,0x8a,0x7f,0x66,0x28,0x8d,0x22,0xec,0x82,0x64,0x69,0x63,0xf0,0x53,0x2d,0x10,0x9c,0x9c,0x34,0x4f,0xc6,0x96,0x40,0xdb,0xce,0x0e,0xf7,0x3a,0x8a,0xee,0x3f,0x32,0x5f,0x2b,0x0c,0x4a,0xbc,0x63,0xfb +.byte 0x18,0xf6,0x26,0x57,0xc9,0x13,0x13,0xb7,0xe0,0xcc,0x3e,0x4e,0x73,0xfa,0xe2,0x54,0xc1,0x67,0xfe,0xe2,0xec,0xfd,0xaf,0xf9,0x96,0x99,0x9f,0xe9,0xe2,0xd0,0x94,0x39,0x33,0xc9,0xca,0x35,0x27,0xad,0x58,0x46,0x98,0x64,0x17,0x5f,0xe9,0xce,0x4b,0xc8,0xab,0x0d,0xd2,0x88,0xec,0xbb,0x5c,0xba,0xc1,0x30,0x4c,0xd4,0x99,0x0d,0x07,0x95 +.byte 0x0a,0xa5,0xeb,0xa6,0x10,0x4b,0x4d,0x77,0x14,0x76,0x88,0x43,0x7f,0x6b,0x5d,0x9b,0x87,0x1d,0x6b,0x5d,0xb9,0x04,0xa9,0xc7,0x28,0x18,0x70,0xa1,0x99,0xbc,0x99,0xf5,0xf1,0x71,0xa9,0x3a,0xb6,0xe5,0x98,0x98,0x8f,0x7a,0x6c,0xda,0x1a,0x63,0x0e,0xf1,0xe8,0x10,0xa3,0x7c,0x64,0x7e,0xde,0x2a,0x59,0x1b,0x04,0xca,0x69,0x8e,0xba,0x2f +.byte 0x56,0xe1,0xa7,0xab,0x4f,0xe4,0x9d,0x49,0x33,0x9e,0x4e,0x5b,0xe1,0x58,0xc4,0x3f,0x99,0x5a,0x69,0x00,0xe5,0x5f,0x85,0xcb,0x62,0x80,0x5e,0x3d,0x88,0x0a,0x32,0x42,0xc1,0xf9,0x6a,0xa0,0xeb,0x65,0x2f,0x17,0x62,0x25,0x96,0x50,0xa2,0x6e,0xd6,0xdf,0x09,0xb7,0x1e,0x68,0xb2,0x10,0x2b,0xf3,0x9e,0xb2,0x67,0x75,0x9b,0xe3,0x76,0xfe +.byte 0x95,0xbe,0x83,0xcb,0xba,0x77,0x5b,0x2d,0x5f,0xdd,0x94,0xbb,0x0e,0x5d,0x83,0xa2,0xe7,0x48,0x4c,0x84,0x86,0x41,0x47,0x4b,0x96,0x24,0x89,0xa8,0x20,0x04,0xa5,0xef,0x8e,0xb6,0xeb,0xcd,0x3c,0x77,0xc5,0x65,0x5c,0xff,0xa6,0x0d,0x2b,0x58,0x21,0x5a,0x11,0xe2,0x24,0x64,0x1c,0xd6,0x18,0x9a,0xac,0x3f,0x42,0x0e,0xeb,0x32,0x3e,0xed +.byte 0xce,0x61,0xc9,0xe4,0xe7,0xd3,0x3f,0x53,0xa4,0x80,0x2b,0x1c,0xc0,0x99,0x63,0x52,0x93,0x5e,0xdc,0x78,0xe2,0x35,0x9e,0xb2,0xb4,0x1d,0x09,0xd1,0x5c,0x1c,0x4e,0xdb,0x3a,0x5d,0x8c,0x94,0x7d,0xfe,0x63,0xf2,0xa3,0xe9,0x61,0x73,0x78,0xc1,0xd9,0x17,0x5e,0x9a,0x73,0x58,0xc3,0xe7,0xa0,0x1f,0x2a,0x62,0x15,0xf8,0xdb,0xbb,0x38,0x80 +.byte 0x57,0xd3,0x1f,0x4c,0x4a,0x20,0x30,0xa9,0x7a,0x78,0x61,0xd9,0x90,0xb7,0x4f,0xd6,0x46,0x72,0xe7,0x41,0xb2,0xbb,0xfb,0x50,0xfe,0xe1,0xba,0x3e,0x73,0x2f,0x81,0x6d,0x2b,0x0b,0x90,0xbd,0x8a,0x3b,0x23,0x88,0xa2,0x7d,0x62,0x87,0x96,0xc9,0xcc,0x66,0x28,0x89,0xa7,0x29,0x41,0xd2,0xc5,0x5b,0xdb,0xc4,0x0c,0xbb,0x19,0x4e,0xd5,0x12 +.byte 0x53,0x48,0x5c,0xf2,0x9b,0x62,0xd0,0xa3,0x77,0x40,0x85,0x12,0x2b,0x2d,0x52,0x1b,0x31,0xbd,0xe9,0x1c,0xd4,0x87,0xa4,0xd7,0xc9,0x14,0xb7,0x39,0x66,0x8c,0xfe,0x3e,0x83,0x00,0x01,0xae,0x44,0x2d,0x7d,0xa1,0xda,0x66,0xb0,0x66,0xcb,0x62,0x55,0x9f,0x92,0x80,0x4e,0x8d,0x7f,0x70,0x95,0xc2,0xf2,0x1b,0xe9,0x35,0xf8,0x42,0x04,0x65 +.byte 0xf2,0x36,0x4c,0x96,0x30,0xd3,0x47,0x9d,0xb7,0x2b,0x76,0xac,0x75,0xb5,0xb8,0xf1,0x7d,0xa2,0x36,0xef,0x9d,0xa7,0x60,0x51,0x8d,0xcf,0x00,0x3d,0xdb,0xcc,0xe9,0xe2,0xc4,0x7b,0x3a,0xeb,0x2b,0xc3,0xd8,0x0b,0xb0,0x58,0x41,0xa0,0x47,0xab,0x07,0xf5,0x7c,0x9e,0x0b,0x7a,0x16,0x8f,0xb4,0xca,0x09,0xed,0x84,0xa1,0xfa,0xdc,0x7c,0x3c +.byte 0xdd,0x2f,0xb0,0x2d,0xeb,0x93,0x28,0xf5,0x1e,0x0c,0x1a,0x0c,0x35,0x27,0x40,0xf2,0x22,0x66,0x2d,0x82,0xf2,0x94,0x03,0xa5,0x4b,0x84,0x92,0x1d,0x98,0xd5,0xd9,0x09,0x6a,0xfd,0x65,0xe5,0xa1,0x0e,0xe2,0xd9,0xb6,0xd1,0xba,0xbf,0xc7,0x42,0x22,0x39,0x83,0xbf,0x37,0xf6,0x80,0xc2,0xea,0xdf,0xb9,0x33,0xa0,0xaf,0xd7,0xe3,0x70,0x9a +.byte 0x5c,0xf8,0x1a,0x47,0x2b,0xb5,0xdd,0x15,0xe3,0x08,0xc8,0x37,0xe3,0xc2,0x25,0x87,0x0e,0x3c,0xc5,0xae,0x61,0xa4,0x4a,0x56,0x50,0x08,0x58,0x68,0xa3,0x4a,0x28,0x08,0xef,0x92,0xd5,0x13,0x50,0x09,0x76,0x34,0x47,0xae,0xa8,0x7f,0xa5,0x2b,0x13,0xb7,0x5a,0x96,0x65,0x62,0xf2,0xaa,0xb4,0x4b,0x2a,0xad,0xea,0x2c,0x0d,0x1e,0x97,0x82 +.byte 0xe4,0x6f,0xfe,0xf4,0x88,0x14,0x7b,0xba,0x45,0xbe,0x61,0x56,0xd2,0x37,0x1b,0x65,0xb8,0x0b,0x77,0xcb,0x3c,0xfe,0x9f,0xe3,0x39,0xc5,0xfb,0x2a,0x18,0x9b,0x60,0x99,0xd5,0x6f,0x52,0xfe,0xd8,0x04,0x88,0x1c,0x9a,0x50,0xe5,0x3b,0x33,0x3f,0xca,0xc5,0x5b,0x9c,0x5f,0x35,0x13,0x65,0xa6,0x21,0x78,0x19,0xeb,0xff,0x35,0x70,0x81,0xaf +.byte 0x19,0x23,0x61,0xd6,0xeb,0xff,0xa6,0x9e,0x5d,0x3f,0x7f,0x89,0x2e,0x22,0xa4,0x0b,0x9c,0x4f,0xa9,0xff,0xbb,0x23,0x29,0xa1,0xf4,0x8a,0xb7,0x4b,0xfb,0xbf,0xeb,0x0a,0x47,0x87,0x78,0x2b,0x20,0x38,0x82,0xab,0x7e,0x2c,0xdc,0x08,0x2b,0xb4,0xae,0xd8,0x64,0x44,0x1a,0xdf,0x21,0x62,0x27,0xf2,0x61,0x63,0x37,0xad,0xd4,0x06,0x4e,0xae +.byte 0xba,0xeb,0x08,0xfa,0xe5,0xad,0x5d,0xcf,0xce,0x38,0xe5,0xca,0x74,0x83,0x42,0x4b,0xe8,0x8f,0xfb,0xff,0x83,0x4d,0x27,0x88,0x43,0x62,0xdd,0x80,0xa2,0x06,0x98,0x48,0x58,0x6f,0x54,0x16,0x6f,0xbf,0x81,0x36,0xc8,0xf3,0xea,0x4b,0xf7,0x5a,0x7b,0xb7,0xf4,0xa4,0x5e,0x22,0x52,0xe7,0x9e,0xb1,0xb6,0x7a,0xa8,0x22,0xee,0x68,0x82,0x8f +.byte 0xe4,0xcb,0xad,0x71,0xef,0x53,0xf2,0x7d,0xed,0x91,0x9e,0xf6,0x90,0x9e,0x54,0x19,0x30,0xaf,0x4a,0x17,0xc0,0x6a,0x9c,0x49,0x12,0x8b,0x6f,0xc7,0x47,0x1e,0xa2,0x64,0x28,0x1f,0x0c,0xd3,0x3e,0x59,0x66,0x8c,0x2e,0x11,0x52,0x6c,0x69,0x66,0x10,0xfb,0x27,0xe6,0x1c,0xae,0x6f,0x44,0x87,0x86,0x0d,0x3e,0xd3,0xa0,0x80,0xef,0x30,0xb9 +.byte 0xb8,0xd7,0x47,0x84,0x68,0x2b,0xf2,0x32,0x7b,0x89,0x93,0xd2,0x83,0x56,0x35,0xc3,0xbf,0x5c,0x24,0xec,0xad,0x2d,0xa4,0x49,0x63,0x89,0xc6,0xf9,0x24,0x51,0x1c,0x9b,0xd1,0xcb,0x30,0x82,0xda,0xb3,0xa7,0xe1,0x4d,0x96,0xd0,0x44,0x44,0x1d,0x4e,0xd7,0x7d,0x7a,0x51,0x2e,0x2f,0xc4,0x9f,0xdb,0x06,0x53,0xfc,0x51,0x56,0xe5,0xb9,0x6b +.byte 0x4a,0x2c,0x3e,0x62,0xc5,0x9c,0x42,0xe3,0xaf,0x3a,0x0f,0x0e,0x74,0x29,0x66,0x70,0x75,0x2a,0x06,0xd4,0x0f,0x0c,0xfd,0xea,0xcc,0x39,0xd0,0xa7,0x47,0x75,0x92,0x44,0x09,0xa2,0x3c,0x4e,0xad,0xaa,0xc4,0xc6,0xf9,0x35,0x82,0x23,0x25,0x43,0x94,0x26,0x14,0xde,0xf1,0xb9,0xb8,0xe0,0x75,0xe0,0x48,0x70,0x8a,0xc6,0x3c,0x72,0x98,0x72 +.byte 0x8b,0x15,0x58,0x17,0x73,0x29,0x67,0x21,0x56,0xc4,0x25,0x17,0x68,0xbe,0xd7,0x36,0x05,0x4b,0x58,0xa2,0x1b,0x64,0xe5,0x11,0x96,0x5a,0x3b,0xa6,0x90,0xb6,0x2d,0x7e,0x55,0xbb,0x31,0x93,0xe7,0xcc,0x2e,0x74,0xb6,0x9b,0x4d,0x04,0xc5,0x45,0x9b,0x0b,0x26,0xef,0x61,0x23,0x3d,0x7e,0xee,0x01,0x57,0xfa,0x77,0x12,0x47,0x64,0xac,0x8f +.byte 0x25,0xbe,0x8e,0x2e,0x68,0x11,0x95,0xf0,0x1a,0xd2,0x3d,0x66,0xc1,0xdb,0x97,0x9e,0xbb,0xba,0xc1,0x66,0xa4,0xb5,0x71,0x01,0xee,0xf5,0xbb,0x1e,0x9f,0x41,0xfc,0x40,0x74,0x26,0xf7,0xc6,0x2c,0x9c,0x1c,0x59,0xce,0xcf,0x18,0x17,0x81,0x5d,0xd4,0xe3,0xd8,0x46,0x62,0x9e,0x97,0xb1,0xca,0xac,0x01,0x3e,0xf8,0x96,0xa2,0xee,0xe0,0xf8 +.byte 0xf3,0x2d,0xe9,0xd2,0x1f,0x9f,0x41,0xbb,0x2f,0xe5,0x64,0x6d,0x5b,0xe7,0x47,0x0e,0x83,0x7b,0x08,0x5e,0x29,0x35,0x2f,0x75,0x31,0x44,0x4c,0xb7,0x61,0xa4,0x03,0x2e,0x15,0x94,0x7a,0xa0,0x46,0x31,0x7b,0x43,0xd9,0x14,0xa3,0x34,0x0c,0x83,0x93,0x75,0x8e,0x3a,0x1c,0xc3,0xe1,0x36,0x18,0x96,0x7a,0xfb,0x77,0xad,0xbb,0xe9,0x0d,0x4b +.byte 0x21,0x04,0x2e,0xdd,0x7a,0x63,0xc9,0x60,0xb1,0x9b,0xad,0xde,0x1f,0x65,0x8a,0x58,0x18,0x84,0x95,0xa9,0xac,0x3a,0xac,0xcb,0xb7,0xa9,0xeb,0x0c,0x7c,0x3a,0x98,0x9a,0x3f,0x56,0x23,0x51,0x58,0x59,0x4e,0xf5,0x57,0x60,0xe6,0x9d,0xf8,0xf7,0xed,0x9d,0x81,0x14,0x68,0xbe,0xaf,0x19,0xe5,0xb5,0x9b,0x5f,0xe4,0x51,0x44,0x4b,0x23,0x42 +.byte 0xdd,0x92,0x1a,0xe5,0x7e,0xef,0x77,0xbe,0x88,0x77,0x1e,0x8a,0xbd,0x2a,0x77,0xb1,0x0d,0x1b,0xe3,0x8a,0x7f,0x15,0x71,0x93,0xc9,0x5f,0x78,0x2d,0x77,0x9b,0x0c,0xad,0x76,0x3c,0x6b,0xe2,0x15,0x8e,0xe1,0x5e,0x1d,0x90,0xa5,0xd6,0xc7,0x55,0x5d,0x52,0xf7,0xcc,0x82,0x9b,0xdc,0x1d,0x80,0xa4,0xc7,0xbe,0x7c,0x4f,0xda,0x81,0x91,0x78 +.byte 0x88,0x0e,0x31,0xde,0x87,0x4c,0xdc,0x84,0x9a,0x65,0x89,0xfa,0x22,0x3e,0xde,0x3b,0x7f,0x7f,0x9b,0x3f,0x3e,0xda,0x13,0x31,0x59,0x7b,0x08,0x48,0x39,0x37,0xfd,0x1a,0x4f,0xa3,0x12,0xba,0xe5,0xd6,0xfa,0xa3,0x59,0x0b,0x3b,0x7d,0xde,0xc0,0x51,0xce,0x92,0x6b,0x3d,0x4b,0xd2,0xa4,0x68,0xc2,0x32,0x2d,0x01,0xbd,0x66,0x98,0x8f,0xa0 +.byte 0x86,0xfb,0x08,0x36,0xa9,0xd4,0x3b,0x7b,0x01,0x2d,0xaa,0x8c,0x64,0x19,0xa6,0x62,0x24,0x92,0x5e,0xc5,0x02,0x17,0x8e,0xf0,0x88,0xe9,0xd1,0x8b,0x69,0xda,0xed,0x9c,0x60,0x32,0xab,0xc0,0xbc,0x84,0x64,0x6e,0x32,0xb2,0xcd,0x24,0xf6,0xb2,0x9d,0xf5,0xf5,0x71,0xe2,0x01,0xbc,0x77,0x6a,0x5b,0x26,0x56,0xf7,0x04,0x84,0xff,0x7c,0xa4 +.byte 0xe8,0xa8,0x82,0x6c,0x40,0x24,0x93,0x3c,0x6e,0x7d,0x0d,0x22,0xd0,0xe4,0xef,0xc4,0x4e,0x26,0x66,0x61,0x75,0xe9,0x06,0x69,0x06,0xfd,0x97,0x68,0x96,0x67,0xec,0x96,0x09,0x73,0xe4,0x0a,0x3e,0xaa,0xb8,0x25,0x77,0x00,0x91,0x7a,0x2e,0xc8,0x81,0x75,0x78,0xb7,0xa5,0x27,0x55,0xf2,0xcf,0x9a,0xab,0xab,0x51,0x0a,0x65,0x47,0xbf,0x10 +.byte 0xd2,0x19,0x78,0x6b,0x35,0xf4,0xef,0x12,0x2b,0x5f,0x0c,0x28,0x7c,0xe8,0x64,0x55,0x2f,0x26,0x85,0x91,0x7a,0x9d,0x48,0x76,0x12,0x14,0x2d,0x4a,0x8a,0xd6,0xfa,0x7b,0xf9,0xc7,0x24,0x45,0xf6,0xbd,0x47,0xab,0xc6,0x4b,0x9e,0x39,0x77,0x57,0x04,0xa8,0x4d,0x43,0x99,0x5c,0xb1,0x3d,0xc2,0x4e,0xc5,0x17,0x66,0xc4,0xb6,0xdd,0x92,0x80 +.byte 0x85,0x3b,0x07,0x63,0x16,0x5f,0x67,0x76,0x9b,0xb5,0x8e,0xca,0x97,0xbb,0xf4,0x20,0xd0,0x4d,0x7b,0xd0,0xa3,0x74,0x6f,0x8a,0x68,0xc7,0x31,0x78,0x1b,0x72,0x45,0xa4,0xc4,0xf8,0xf8,0x26,0xa8,0x4d,0x08,0x2f,0x7b,0x3d,0xa0,0x2a,0xb5,0x65,0x27,0xc2,0x36,0x13,0x2d,0x8d,0x83,0xeb,0xf4,0x08,0x26,0x41,0x8b,0x32,0xf3,0x09,0x70,0x70 +.byte 0x5d,0x8a,0xcc,0xb8,0xe9,0xf7,0x08,0xdf,0x5f,0x4a,0xb8,0x8a,0xb7,0x1b,0xad,0xe2,0xc3,0x39,0x59,0xe0,0x7f,0xd0,0x66,0x7b,0x99,0x5a,0xde,0x52,0xe2,0x1f,0x47,0xc2,0x63,0x74,0x7a,0xa5,0x88,0xc3,0x24,0x70,0x4a,0x7d,0xdd,0xa4,0xe6,0xf8,0xfd,0x5c,0xfa,0x8c,0x4c,0x0f,0x52,0x95,0xf3,0x2c,0x76,0x47,0x7a,0xe8,0xdb,0xe0,0x9b,0x49 +.byte 0x88,0x5b,0x87,0x5a,0xd1,0x07,0x24,0x06,0x83,0x3b,0x25,0x23,0xe7,0xaa,0x79,0xef,0x74,0x02,0x12,0xfe,0x47,0x5c,0x77,0x73,0xf7,0x2e,0x4b,0x58,0x3b,0x60,0x7b,0x91,0x2f,0x0d,0xb4,0x6d,0x00,0x80,0x19,0xaa,0x88,0xbc,0xb2,0x7b,0xd9,0xb7,0xdd,0x32,0x47,0x62,0xf5,0x0f,0x46,0x95,0x4c,0x6c,0x01,0x67,0xfb,0xe4,0x2b,0xac,0x95,0x84 +.byte 0x25,0x0a,0xe5,0x4c,0x2d,0x4a,0x6e,0x77,0xfd,0xeb,0xe1,0x53,0xc9,0x2e,0x70,0x01,0x32,0x05,0x6d,0xc5,0xc9,0x5d,0x90,0xca,0x56,0xd1,0xd8,0x40,0x2a,0x51,0x4d,0x95,0xc3,0x57,0x8b,0xdd,0x62,0x9c,0x69,0xd1,0x03,0x89,0x95,0x38,0x2c,0xc1,0x6d,0x41,0xf2,0xc3,0xa2,0x9c,0x43,0xea,0xf1,0x02,0x00,0x56,0x46,0xbb,0x87,0x35,0x40,0x0e +.byte 0x18,0x51,0x29,0x39,0xbb,0x6d,0x15,0xf2,0xcd,0x54,0x23,0x95,0x69,0xdc,0x0a,0xb2,0x26,0xd9,0x25,0xe1,0xf1,0x07,0x7b,0x5e,0xc3,0x30,0x68,0x5f,0x2a,0xce,0x91,0x92,0x03,0x0c,0x62,0x11,0x43,0x80,0xe5,0x12,0xec,0xe3,0x4f,0x90,0xfe,0x38,0x6e,0xe9,0x7e,0x94,0x83,0x26,0x59,0x3f,0x3f,0x81,0xc6,0x94,0x98,0x09,0x80,0xff,0x01,0x44 +.byte 0xff,0x77,0x6a,0x4c,0x76,0x91,0xd9,0x12,0x59,0x9a,0x00,0x7c,0x87,0x06,0x17,0xf7,0x12,0xc7,0xee,0x04,0xd5,0x8d,0x68,0xc5,0x8d,0x80,0x10,0xcc,0x14,0x45,0xe8,0xd7,0x43,0x10,0x01,0x9e,0x61,0xc2,0xc0,0x66,0xfe,0xcf,0x5f,0x9f,0xcb,0xa3,0xf8,0xc7,0x07,0x41,0xe3,0xf2,0xda,0x6e,0x01,0x76,0xc6,0x49,0x49,0x01,0xc7,0xcf,0x6a,0x20 +.byte 0x71,0xc5,0xf0,0xb1,0xa0,0xc9,0xed,0xec,0x66,0x71,0x93,0xf5,0xc0,0x27,0x42,0xed,0xd5,0x6f,0x20,0xe1,0x86,0x3e,0xd0,0x5d,0x94,0x17,0x43,0xb4,0x98,0x0d,0x8a,0x31,0x6c,0x59,0xa9,0x0b,0xb3,0xa4,0x0b,0x46,0x0b,0xa8,0x79,0x62,0x3a,0x3d,0xbf,0xef,0x94,0xd3,0x31,0xf2,0xa1,0x55,0xe8,0x92,0x44,0x37,0x62,0x82,0x1b,0x60,0x87,0x67 +.byte 0x85,0x78,0xd5,0x84,0x73,0xa4,0xea,0x56,0x08,0x78,0x68,0x7f,0xfb,0x15,0x20,0x64,0xeb,0x6c,0xf7,0x5e,0xc0,0x79,0x83,0x59,0x7b,0xed,0x2d,0xa9,0x37,0x46,0xf3,0x62,0xb1,0xa1,0x2b,0x48,0x58,0xd9,0x0c,0x03,0xf7,0xf3,0x47,0xeb,0xd7,0x03,0x9b,0x85,0xd3,0xd7,0xd7,0x7e,0xfb,0x1a,0x25,0x83,0xda,0x06,0xa0,0x04,0x0d,0x6b,0x90,0x29 +.byte 0x2a,0xfc,0xcd,0x96,0xe9,0x17,0x4f,0xdd,0x2c,0x90,0xdf,0xf1,0xe3,0x08,0x0a,0xb8,0x0c,0x59,0x2a,0x83,0x62,0x94,0x00,0xd3,0x80,0x1a,0x31,0xd7,0x17,0x70,0xc7,0xa2,0x20,0x17,0x65,0x88,0xae,0x11,0x25,0xc9,0xba,0x76,0xa7,0x61,0x60,0xd1,0x59,0x50,0x22,0xdd,0xaa,0xcf,0x9d,0xc1,0x36,0x7d,0xf9,0x7b,0x69,0xc0,0x98,0xba,0x40,0xd5 +.byte 0xd6,0x46,0x93,0x92,0x7d,0x37,0x3f,0x3a,0x04,0x9a,0x84,0xaf,0x8e,0x61,0x04,0x26,0x54,0x33,0x84,0xc0,0xac,0x21,0x51,0xd7,0x9a,0x93,0x6e,0xf2,0x09,0x87,0xc5,0x35,0xa8,0x96,0xb0,0x64,0x90,0x35,0x52,0xed,0x0e,0xbc,0xdb,0xa6,0x06,0x3e,0xe7,0xea,0x57,0x4b,0xd7,0xc5,0x1c,0x76,0x3d,0x0d,0xc3,0x1f,0x8e,0x4f,0x12,0xdb,0x3a,0x21 +.byte 0x2a,0x69,0xc2,0x94,0xda,0x4c,0x91,0xcc,0xa8,0x36,0x89,0xd7,0x78,0xa8,0x74,0x79,0x63,0x92,0xeb,0x39,0x3b,0x84,0x8c,0xe5,0xc6,0x26,0xf0,0xef,0xcc,0xc1,0x72,0x4b,0x8e,0xcd,0xe4,0xd9,0x00,0x80,0xbc,0xdf,0xe2,0x61,0x53,0x04,0x81,0xb0,0x13,0xc5,0x6c,0x77,0x74,0xa3,0x0c,0x5b,0xef,0xef,0xea,0xc7,0x5b,0xeb,0xbf,0xee,0x54,0xd7 +.byte 0x7a,0x69,0x6e,0x39,0xc2,0xed,0x08,0x44,0x82,0x08,0x16,0x8b,0xf1,0x74,0x5f,0xeb,0x60,0xd5,0x46,0x63,0x80,0x39,0xe9,0x91,0x0a,0x17,0x8b,0xd4,0x09,0xdc,0xa6,0xab,0x6a,0xbc,0xf8,0xe9,0x09,0x19,0xc1,0x83,0x9f,0xdf,0xad,0x6c,0x31,0x94,0xb9,0xc5,0x77,0x83,0xd1,0xd8,0x76,0xeb,0x12,0x3c,0x00,0x31,0xea,0xac,0x97,0x39,0x16,0xd5 +.byte 0x81,0xfa,0x6d,0x10,0x5b,0x3e,0x20,0xe1,0x88,0x5c,0x4b,0xf3,0x04,0xd4,0xc3,0xb9,0xec,0xe5,0xb0,0x13,0xf5,0x09,0x5c,0xe8,0x27,0xe2,0xde,0x9b,0xac,0x2e,0xf2,0xe5,0x2c,0x33,0x4b,0x4f,0xec,0xc7,0x08,0xf9,0xc2,0xd3,0x1b,0x4d,0x81,0x69,0x14,0xa1,0xc5,0x0f,0xb2,0x57,0x8b,0xcc,0xca,0x3b,0xc9,0x9c,0x1f,0xee,0x06,0x4d,0xc7,0x62 +.byte 0xcb,0x8f,0x49,0x81,0xfb,0xa5,0x68,0x81,0x36,0x38,0x33,0x6b,0x9e,0x58,0xd4,0x24,0x67,0xf1,0x30,0xd6,0x08,0x61,0x5a,0x7f,0x2e,0x4e,0xf1,0xd6,0x64,0x75,0x72,0xb0,0xdf,0xcd,0xae,0x04,0x41,0xbd,0x04,0x2c,0x96,0x36,0x34,0x32,0xec,0xbd,0xd0,0xbf,0x8e,0xe8,0x47,0xe3,0x22,0xdd,0x79,0x53,0xcc,0x6a,0x25,0xf1,0x5e,0x63,0x09,0x98 +.byte 0xc5,0x6d,0x0a,0xe3,0x30,0xd6,0x52,0x70,0x21,0xb2,0xef,0x15,0x66,0x4a,0x2d,0x2b,0x5c,0xcb,0x39,0x1b,0x91,0x10,0xa6,0x02,0x22,0xd0,0xcc,0x32,0x50,0x5c,0x70,0x72,0xd1,0x03,0xb3,0x2d,0x2e,0x33,0xed,0xae,0x7a,0x07,0x3f,0x70,0x38,0x35,0xfc,0xcf,0xdb,0xfe,0x7b,0x26,0xd9,0x38,0x1e,0x52,0x07,0x2f,0x72,0x81,0xcc,0xd3,0x21,0x00 +.byte 0x63,0x48,0x38,0x44,0xb8,0x35,0xf2,0x4f,0xe5,0x33,0x8c,0xb3,0x07,0x0c,0xac,0x3d,0x73,0xe8,0xe3,0xb3,0x43,0xc5,0xb4,0x32,0xf4,0x41,0xdf,0x7b,0x06,0x3a,0xb8,0x67,0x17,0xc5,0xec,0x46,0x30,0xc0,0xa4,0x29,0x40,0xe4,0x8a,0xa3,0x14,0x84,0xa6,0x84,0xc7,0x5d,0x4b,0x57,0x37,0x9c,0x42,0xe6,0xa4,0x20,0xf7,0x5d,0xef,0x21,0xe2,0x80 +.byte 0x54,0x6d,0xf5,0xb5,0xbe,0xa3,0x95,0xcf,0x98,0xf8,0x38,0x46,0xa2,0x90,0x57,0x09,0x8f,0xb0,0x6d,0x01,0x5f,0x95,0x5a,0x78,0xf6,0xfd,0x01,0x0f,0xfd,0xa5,0xe2,0xcf,0x54,0xa3,0x2b,0xc1,0x30,0xbe,0x6d,0x1a,0xd3,0xdb,0x5a,0x17,0x43,0x46,0x93,0x81,0x0c,0x85,0x04,0x13,0xda,0xb4,0xde,0x81,0x48,0x5c,0xbc,0x42,0x9e,0x6d,0x6c,0x82 +.byte 0xff,0xa5,0x51,0xb1,0xd3,0xd2,0x3d,0x82,0x82,0xb4,0x96,0xb1,0x38,0x5d,0xc9,0x55,0xcb,0x9f,0xe5,0x47,0xd4,0x52,0x0f,0x76,0x54,0xec,0x39,0xb6,0x40,0xc3,0xc5,0xaa,0xc2,0x30,0x02,0xa0,0x68,0xc3,0x22,0x63,0x5a,0x8c,0x62,0x6d,0x40,0xc5,0xde,0x06,0x29,0x44,0x5d,0x2b,0x18,0x0a,0xa5,0x43,0x47,0xfe,0x5f,0x0f,0x63,0xa4,0x3c,0xa1 +.byte 0x62,0xcb,0x70,0x1d,0xf8,0x0e,0xc9,0xbe,0x27,0x0e,0x87,0x81,0x69,0x4c,0xea,0xbe,0xf9,0x9b,0xda,0xb6,0x9b,0xd0,0xdd,0xa0,0x1e,0x60,0x38,0x88,0x85,0x25,0x53,0xee,0x2c,0x77,0x53,0x82,0xb0,0x88,0x19,0x87,0x2a,0x77,0x7b,0x37,0x4b,0x4c,0xf4,0x96,0x5f,0x73,0xa1,0xbb,0x5c,0xfc,0x7e,0xbb,0xed,0x6f,0xb7,0x6f,0x9d,0x55,0xde,0xd3 +.byte 0xac,0xb9,0x8e,0x36,0x0f,0x3d,0xea,0x87,0xcd,0x19,0x33,0x1d,0xa8,0xee,0xfc,0xcd,0xe5,0x53,0x7b,0xdf,0x37,0x49,0x2d,0x73,0xf5,0x36,0xdd,0x42,0xc6,0x88,0x0d,0xf5,0xf2,0xba,0x2e,0x81,0xed,0x88,0x27,0x8d,0xe5,0x3f,0x83,0x5e,0xde,0x63,0x8f,0x67,0x2b,0x85,0xf3,0x2a,0x9b,0x26,0x3e,0x2b,0xe2,0x29,0xc5,0x5e,0x21,0x04,0xfe,0x5b +.byte 0xb9,0xd8,0xa7,0x7b,0xdf,0xcf,0x61,0xd6,0xaf,0x9b,0x17,0xcb,0xaf,0x8f,0x71,0xb3,0xc2,0x9d,0x9a,0x55,0x1d,0x3e,0x1d,0x17,0x25,0xc8,0x44,0x71,0x29,0x2f,0xc8,0x01,0x3b,0xe4,0xc4,0x2e,0xcc,0x3b,0xdb,0x34,0xbb,0xc0,0xcc,0xb6,0x07,0xe3,0x86,0x4c,0x62,0x02,0xe8,0xc3,0x11,0x85,0x6c,0x18,0x80,0xa3,0xbd,0x02,0x30,0x68,0x36,0xa3 +.byte 0xb6,0xc6,0xbd,0x82,0x43,0x40,0xed,0xa1,0xcf,0xc5,0xce,0xe4,0x27,0x8a,0xeb,0x8c,0x59,0xea,0x4a,0x81,0xd9,0x35,0x87,0x7d,0x6d,0xb2,0x8f,0x67,0x37,0x1f,0x11,0x60,0x0d,0xed,0x34,0xd5,0xa0,0x7b,0x46,0x71,0x68,0x19,0x69,0xd3,0x65,0x1d,0x47,0xf1,0x7e,0x16,0xd8,0xec,0xbb,0x52,0xc3,0x7b,0x62,0x5a,0xb3,0x60,0x67,0x2e,0xfd,0x57 +.byte 0xf2,0xfb,0x3d,0x63,0xe6,0x82,0x20,0xff,0x31,0x90,0x1d,0x5e,0x4f,0x04,0x9a,0xf8,0xb2,0x0c,0x84,0xff,0x7d,0xe2,0xec,0x4b,0x09,0xbb,0xdf,0xae,0xc5,0xaf,0xcb,0x8b,0xb5,0x5d,0xa8,0x53,0x78,0xf9,0xb9,0x43,0x71,0xa6,0xc2,0x10,0xfa,0xad,0xda,0xba,0x46,0x13,0x72,0x97,0xef,0x6f,0xe3,0x4f,0x5f,0xf9,0xec,0x25,0xdb,0xcd,0xca,0x33 +.byte 0x7e,0x50,0x73,0x5b,0xd0,0x9f,0xea,0xd5,0xd9,0x29,0xe8,0x1b,0xc1,0xf8,0x40,0xbf,0x50,0xdb,0x8e,0x39,0x0b,0xb7,0x6c,0xf1,0x34,0x0b,0x1f,0x88,0x27,0x4b,0xea,0x1d,0xb2,0x36,0x07,0x4b,0x22,0xa9,0xd0,0xf8,0xf2,0x13,0x8e,0x97,0x9d,0xd9,0x53,0xd3,0xdc,0x63,0x40,0x11,0xc7,0x74,0x9e,0xd9,0x83,0x01,0xae,0x36,0xcb,0x35,0x9a,0x0c +.byte 0xb5,0x15,0x0a,0xf5,0x41,0xa5,0x6c,0x72,0x40,0x80,0xf0,0x15,0xc0,0x80,0x23,0x0b,0xab,0x98,0xfc,0xab,0x81,0xe0,0x8b,0x61,0x91,0x18,0xd2,0x23,0x71,0xed,0x32,0x80,0x26,0x86,0x96,0xe9,0x90,0x5e,0x43,0xd2,0x89,0x8f,0x89,0x57,0x73,0xca,0xe1,0x42,0xa9,0xa9,0xed,0xdd,0xc5,0x9f,0xf7,0x00,0x0d,0xa3,0xe5,0xc8,0x6f,0x0c,0x14,0xa4 +.byte 0x9d,0x5a,0x14,0xaf,0x96,0x3a,0xb2,0x64,0xa7,0xac,0x20,0xa9,0x01,0x4c,0xec,0x64,0xc6,0x9b,0xfd,0x04,0xc5,0x2e,0xe7,0xdd,0xa5,0x8e,0xe7,0xe7,0x76,0x53,0x59,0x95,0x14,0x07,0xed,0xe9,0x96,0xd0,0x2d,0xc8,0x9d,0xa2,0x11,0xe3,0x02,0x20,0x68,0x09,0x25,0x69,0x07,0x88,0xdb,0x26,0x36,0xf5,0x8e,0xc3,0xf0,0x70,0x8c,0xeb,0xe6,0xcd +.byte 0xad,0xf3,0x49,0x6e,0x8a,0x54,0xa6,0xdd,0x97,0x8e,0x37,0x28,0x3a,0x6d,0xc4,0xdd,0x99,0x85,0xf7,0x96,0x63,0xb4,0xa2,0xdf,0xff,0x81,0x17,0xa1,0x22,0xb1,0x43,0x5b,0x29,0xdb,0x92,0x91,0xc9,0xc6,0x8d,0x29,0x1d,0x6e,0xe3,0x44,0x3e,0xe4,0x20,0xd5,0xf4,0x4a,0xfa,0xae,0xf6,0x2c,0xff,0x80,0xc9,0xce,0x7f,0x13,0x1e,0xd7,0x24,0xa2 +.byte 0xb3,0x90,0xb8,0x20,0x18,0xe5,0x6c,0x0e,0xf5,0xc6,0x26,0xd6,0xe9,0xe8,0x55,0xe4,0x3f,0x49,0x13,0xe2,0xca,0xef,0x9b,0xc0,0x8f,0x24,0x50,0x37,0xef,0x21,0xff,0x79,0xb7,0x5d,0x86,0x03,0xfb,0x85,0x75,0x74,0xbf,0xc5,0x3a,0x30,0xcc,0x00,0xc3,0x0d,0x4f,0x91,0xd6,0x31,0x19,0xd6,0xcd,0x0e,0x1c,0x53,0x88,0x75,0xb8,0xf9,0x68,0x7a +.byte 0xa4,0x3e,0x8d,0xed,0xba,0x05,0xb4,0x6c,0xe0,0x45,0x9c,0x41,0x34,0x24,0x82,0xaf,0x9a,0xcf,0x9e,0xd2,0x27,0x5c,0x7f,0xb3,0xcb,0xe5,0xad,0xb4,0x8e,0x74,0x9d,0xe4,0xba,0x55,0xb3,0xd3,0x32,0xbc,0x62,0x11,0xb3,0xa4,0x82,0xf0,0xd8,0xfc,0x79,0x03,0x70,0xae,0x7f,0x7f,0xc8,0x50,0xb5,0xbe,0x47,0x14,0x31,0xd7,0x16,0x65,0x52,0x3b +.byte 0xbb,0x42,0x38,0x23,0x77,0x4d,0x38,0x0b,0x0a,0x61,0x94,0xac,0xa3,0xc9,0xd7,0x99,0x4f,0x34,0x3a,0x88,0xe8,0x1d,0x0b,0x97,0x48,0x6d,0x5c,0x61,0x4c,0x3f,0xc2,0x7c,0x6c,0x63,0x00,0xdd,0x59,0xae,0xcd,0x17,0x0a,0x21,0x27,0x98,0x15,0x23,0x6d,0x84,0x7e,0x24,0xd4,0x7f,0x1b,0x3a,0x98,0x52,0xc3,0x60,0x33,0xd6,0xc1,0xfe,0x68,0xa8 +.byte 0x49,0x3d,0x7e,0x53,0xee,0x0d,0xed,0x89,0x9a,0x9a,0xe6,0xa1,0x47,0xc7,0xba,0xf3,0x73,0x5b,0xef,0x33,0x51,0x8c,0x1f,0x84,0xa6,0xef,0x77,0x94,0x2d,0xd6,0xda,0x8f,0x85,0x8c,0xd3,0xb6,0x02,0x68,0x9e,0x57,0xb6,0xd9,0x1a,0x8c,0xb5,0xf4,0x61,0x39,0x29,0xb5,0xb7,0x0d,0x0d,0xa6,0x81,0x87,0x54,0xc0,0xca,0x67,0x09,0xca,0x20,0xf3 +.byte 0x37,0x7e,0x03,0x3e,0x31,0x8c,0x51,0x89,0x06,0x81,0xf6,0x7b,0x8b,0xe3,0x4f,0xd0,0xb8,0x0c,0x34,0x7c,0xd6,0xfc,0x25,0xf8,0x00,0xa6,0x10,0x15,0x0d,0xeb,0x22,0x72,0x03,0x79,0x1c,0x84,0x1d,0x3d,0x10,0xaf,0x43,0x6d,0xd7,0xed,0x10,0x2c,0x14,0x26,0xd4,0xa1,0xee,0x6c,0x7f,0x52,0xe4,0x83,0xcc,0x5f,0x1a,0x4b,0xd0,0xc8,0xfb,0x27 +.byte 0x17,0x2c,0xf6,0x90,0x02,0xb4,0xb0,0x63,0x7c,0x14,0xec,0x9e,0x08,0x60,0xec,0x45,0x85,0xc6,0x76,0x42,0x4f,0x1c,0x5f,0x48,0x7f,0x87,0xef,0x8c,0x04,0x23,0x3c,0xda,0x39,0xbc,0xec,0x09,0xda,0xeb,0x9b,0x72,0x7a,0xb4,0x20,0x1c,0xb2,0xdd,0x2e,0x63,0x72,0xd7,0xb1,0xfe,0x5b,0x21,0x28,0xfb,0xeb,0x45,0x31,0x89,0xe5,0x3e,0xa0,0x85 +.byte 0xa6,0x96,0xdb,0x42,0xd5,0xb4,0x27,0x78,0x10,0xa0,0xcb,0x69,0x68,0x1e,0x76,0xed,0xbc,0x3c,0xa1,0x04,0x10,0x81,0x2a,0x4f,0x52,0x78,0x1e,0xae,0x5a,0x47,0x69,0x81,0xee,0xd3,0x14,0x1a,0x68,0x19,0x75,0x92,0x72,0x47,0x61,0x70,0xcf,0x96,0x35,0xa6,0xbb,0x00,0xaf,0x3e,0x90,0x86,0x22,0x9b,0x72,0x8a,0xa1,0x05,0xe2,0xfb,0xdc,0x30 +.byte 0xd5,0xdd,0x46,0x1f,0xf6,0x33,0x43,0xd1,0x59,0xc4,0x93,0x89,0x36,0x6a,0x7b,0x76,0xa7,0x40,0x6c,0xb1,0x9c,0xce,0x3a,0x8c,0xb6,0xd5,0xd1,0x0a,0x78,0xf6,0x08,0xfb,0xf5,0x9c,0xee,0x74,0x0d,0x39,0x51,0x6d,0x0e,0xa6,0xe9,0x22,0xd8,0x30,0xdf,0x16,0xf7,0xe3,0xbd,0xbb,0xe6,0x45,0xb8,0x9c,0xb5,0x49,0xf0,0xe8,0x7c,0xce,0x25,0xf8 +.byte 0x46,0xc0,0x59,0xc2,0xbc,0xdd,0xea,0x3e,0xeb,0x2e,0xf5,0xfd,0xd9,0x05,0x8a,0x2f,0xa3,0xa4,0x63,0xa6,0x50,0x08,0xce,0x2a,0x69,0xe7,0x58,0x57,0xa1,0xb2,0x44,0x41,0x04,0xfc,0x61,0xb1,0xb8,0x19,0x27,0x14,0x71,0x2f,0x55,0x64,0x28,0xa0,0xcc,0x47,0x0c,0xd4,0xed,0xfd,0x07,0x99,0xc6,0x9e,0xdc,0x5f,0x19,0x03,0x1a,0x00,0xda,0xf6 +.byte 0x2c,0x95,0xb0,0xd2,0xaa,0xfb,0xbc,0x1a,0xf3,0x62,0xaf,0x9c,0x38,0xde,0x61,0x30,0xd5,0x56,0x82,0x4b,0xf6,0xeb,0x34,0xc0,0xdc,0x51,0x97,0x89,0x80,0x47,0x9d,0x2a,0xae,0x0e,0x92,0x48,0xd2,0x9d,0x5a,0x67,0xef,0x33,0xa3,0xbe,0xdd,0x80,0x64,0x9c,0xc1,0xaf,0xf9,0x1a,0x4b,0x55,0x67,0x88,0x37,0x37,0xff,0x98,0xe3,0x9e,0xa9,0x4e +.byte 0x1f,0xa1,0x32,0x70,0xa3,0xbb,0xdc,0x6e,0xb3,0x6d,0xfe,0x8f,0x74,0x89,0xed,0xe1,0x13,0x3c,0x8f,0x08,0x75,0x84,0x84,0xee,0xac,0xcc,0xa5,0x47,0x9f,0x3e,0xb9,0xed,0x26,0x20,0xf7,0x7b,0xfb,0x8a,0x48,0x58,0x51,0x24,0xf9,0xeb,0x66,0x6d,0xd6,0x83,0x24,0xff,0x9f,0x0d,0x38,0x9c,0xf9,0x24,0x99,0x12,0x49,0xb6,0xdd,0xce,0x44,0xe7 +.byte 0x31,0x3d,0x4b,0x23,0x8a,0xd5,0x62,0xa2,0xdb,0x78,0x56,0x3a,0x62,0xc8,0x59,0x5f,0xcc,0x58,0x76,0x19,0x5d,0x48,0x4a,0xc2,0x87,0x21,0xc3,0x3d,0x3a,0x38,0xbd,0x20,0xfd,0xc3,0xa6,0xab,0x32,0xb8,0xc8,0xd1,0x5c,0xa5,0xb4,0x64,0x60,0xd2,0x87,0xb7,0xe9,0xc2,0x2b,0xb2,0x75,0x04,0xf4,0x6e,0x96,0x99,0x5d,0x08,0xff,0xa3,0x45,0x8a +.byte 0xad,0x7c,0xee,0x94,0x4e,0x45,0x86,0xad,0x0a,0x7a,0x5c,0x8f,0xff,0x28,0xb3,0x3c,0xf8,0x5e,0xb3,0x1e,0x5c,0xe0,0x22,0xf7,0x4e,0xe4,0xdf,0x1f,0xd2,0xa2,0x37,0x4a,0x87,0xa6,0x16,0x80,0x0c,0xc3,0x75,0x18,0xe4,0x76,0x8f,0xc3,0x1b,0xee,0xb1,0xe4,0x4b,0xeb,0x6f,0x15,0x48,0x60,0xaf,0x8e,0x0e,0xeb,0xbe,0x26,0xa3,0xbd,0x2a,0xb5 +.byte 0x6d,0x8b,0xd1,0xa1,0x0f,0x8e,0xaa,0xaa,0xb8,0x8d,0x84,0xe7,0x65,0x40,0x60,0x3d,0x59,0xb7,0x1c,0xef,0x08,0x0e,0x6f,0x21,0xb4,0xe6,0x10,0xda,0x59,0x9a,0x0f,0xe6,0xba,0xfd,0xed,0x7f,0xc1,0xe3,0x7a,0xb7,0x21,0x5d,0xcf,0x1c,0xbd,0xd2,0x59,0xc0,0x31,0xa5,0x8a,0x39,0x86,0x9e,0x7e,0x6a,0xcb,0x87,0x6f,0x01,0xba,0xa4,0x06,0x6b +.byte 0x3b,0x5d,0x68,0x85,0x11,0xd2,0x2a,0x3c,0x8e,0x3a,0x8c,0x8b,0x59,0xa0,0x4a,0xfb,0x76,0x85,0xe6,0x47,0xc3,0xf4,0xc4,0xe6,0xcc,0x7b,0xff,0x71,0x03,0xd1,0xc2,0x01,0xe4,0x5e,0x49,0x31,0xa6,0x0e,0x17,0x9b,0x42,0xdc,0x75,0xd6,0xfe,0x09,0x0b,0x6d,0x21,0x46,0xfe,0x40,0xcd,0x7c,0xdb,0xca,0xc9,0xba,0x64,0x83,0xd3,0xf7,0x0b,0xad +.byte 0xff,0xfd,0xe3,0xd9,0x49,0x7f,0x5d,0x48,0xaa,0xac,0xe5,0x74,0x2a,0x14,0x6f,0x64,0x21,0x81,0x09,0xcd,0x2d,0x19,0xf5,0x56,0x85,0xa8,0xec,0x98,0x65,0x46,0x99,0xec,0xbe,0xe3,0x86,0xd3,0x41,0x8b,0xe4,0x76,0x9b,0x5b,0x98,0x33,0x9e,0xdb,0xc9,0xde,0x89,0xfa,0x60,0x58,0xa8,0x2f,0x7a,0xca,0x30,0x91,0xc8,0x26,0x14,0x9c,0xd6,0x6d +.byte 0xc2,0x3c,0xca,0xe0,0x9a,0x13,0x72,0x63,0x5e,0x20,0xfd,0xa0,0xca,0xb2,0xed,0x37,0xc5,0xd4,0x4e,0xec,0x1f,0x74,0x25,0x37,0xe2,0xbe,0xb1,0x7f,0x52,0x26,0x28,0x4f,0x02,0xe5,0x6a,0x27,0xf3,0xc4,0x9c,0x69,0x09,0xac,0xff,0x77,0x9c,0xa4,0x1d,0xe7,0xa1,0x7c,0x37,0x70,0x3b,0x3c,0xc4,0x16,0x8f,0x5d,0xe5,0x05,0xa9,0x2c,0x91,0x2e +.byte 0x87,0xb0,0xa9,0x2e,0x32,0x73,0x5c,0x15,0x1e,0xbe,0x01,0xc9,0xd8,0x2e,0x26,0xf4,0x05,0x2d,0xe0,0xc0,0x38,0x81,0x61,0xf4,0x37,0x08,0xa0,0xc0,0x28,0x0a,0xb6,0xd4,0xcc,0x2c,0xc6,0xd4,0xda,0x48,0x49,0xcf,0x76,0x91,0x23,0x51,0x91,0xe7,0x50,0x94,0xae,0xb7,0x15,0x26,0xaa,0x82,0xd0,0x97,0xe8,0x5e,0xaa,0xfc,0xaa,0x60,0x62,0x81 +.byte 0x80,0xfd,0xfd,0xaf,0x65,0xcc,0x29,0x27,0x95,0xad,0x56,0xb9,0x85,0x66,0x49,0x62,0xb3,0x1a,0xf4,0x54,0xc7,0x5d,0x7f,0x73,0xe0,0xd2,0xc8,0x18,0x95,0x62,0x2f,0x5c,0x96,0xfb,0x63,0x15,0x46,0x07,0x5f,0x3e,0x52,0x18,0xf8,0x5d,0x45,0x0b,0xb6,0xf7,0xc5,0x3d,0x16,0xaa,0x0b,0x8f,0x9d,0x16,0xc8,0x93,0x13,0xd2,0xba,0x7a,0x52,0x1a +.byte 0x7a,0x73,0xc4,0xca,0xfb,0x04,0xaf,0x6f,0x3e,0xfa,0xff,0x29,0x09,0xe2,0x74,0x35,0xc1,0xfc,0x21,0xcf,0x5f,0xf7,0x82,0x55,0x75,0x27,0xc9,0x91,0xc5,0xbf,0xe6,0x68,0xb6,0x0f,0x10,0x0e,0x91,0x30,0xb7,0x05,0xca,0x59,0x4a,0x7f,0xb0,0xf6,0xaf,0xf1,0x5d,0xc9,0xc5,0x06,0xc5,0xf4,0xe1,0x75,0x16,0x9a,0x2c,0xc0,0x3f,0xc1,0x98,0x91 +.byte 0xb7,0xe6,0xb1,0xf2,0xf9,0xfa,0x6d,0x27,0x98,0x33,0x8b,0x73,0x7a,0x57,0x12,0x6f,0x80,0x11,0x28,0x17,0x7d,0xf1,0x26,0xaa,0x05,0xf1,0x6e,0x86,0x98,0xe7,0xf6,0x9f,0x9c,0x06,0x8f,0xec,0xd7,0x2d,0xb0,0x83,0xdf,0x23,0x80,0x34,0xd3,0xd7,0xf7,0xd5,0x0d,0x52,0x18,0xcd,0xc7,0xe7,0x15,0xc9,0x1b,0xae,0x58,0xcf,0xc5,0xdd,0x25,0x2a +.byte 0xff,0xa5,0xf3,0x6d,0x20,0xfd,0xda,0xfd,0x78,0x30,0x14,0x1f,0xb3,0x47,0xe3,0x2d,0x54,0x87,0xdc,0x30,0xbe,0x41,0xc0,0x48,0x52,0x82,0x49,0x78,0xad,0xfd,0x24,0xad,0xd6,0xc1,0x14,0x1e,0xa0,0xc1,0x3d,0x82,0x59,0x01,0x9b,0xc3,0xf4,0xf7,0x26,0xce,0x92,0x50,0x13,0x47,0xe0,0xf3,0xfa,0xd9,0x61,0x19,0x80,0x12,0xee,0x73,0x45,0x5b +.byte 0x34,0xfc,0xb2,0x84,0xb2,0x3f,0xdc,0x77,0x8e,0x2d,0xb3,0x62,0xb9,0x03,0x2d,0xb6,0x2a,0x17,0xcd,0xfb,0x54,0xc2,0x5e,0xb9,0xcf,0xd6,0x05,0xe2,0xac,0x3f,0xce,0x50,0x0f,0xa1,0x3e,0x67,0x68,0x46,0x0c,0xab,0xa1,0xdc,0x2a,0x26,0x1f,0x22,0x1b,0xa7,0xc9,0x3b,0x6c,0x97,0x5d,0x5c,0x7d,0x1a,0x46,0x4a,0x99,0x92,0x85,0x87,0x35,0x6c +.byte 0x78,0x9d,0xb0,0x39,0xd6,0x3b,0x52,0x60,0xb4,0xba,0xcc,0x2e,0xe9,0xe1,0x91,0x51,0xc1,0x52,0xc7,0x5d,0x84,0x95,0x54,0x25,0xdd,0xcd,0x40,0x35,0xa1,0xc8,0x7e,0xff,0x82,0x55,0x9f,0x64,0xef,0xa7,0xc1,0x79,0x57,0xc7,0x44,0xa8,0x1c,0x06,0xaa,0x2a,0x05,0x65,0x6c,0xdc,0x90,0x7d,0x2e,0x53,0x3c,0x56,0xe1,0x30,0xdf,0xcb,0x75,0x3d +.byte 0x36,0x88,0xfd,0x72,0x2d,0xc7,0x8e,0x2f,0x11,0x5a,0x2e,0xa9,0xd6,0x37,0x4b,0x31,0x4e,0x6e,0xa0,0x4a,0xd9,0xa9,0x48,0x18,0x50,0xb1,0x28,0xf6,0x74,0x03,0x44,0xa7,0x06,0x55,0x86,0x1a,0x1b,0x07,0x79,0xc4,0x25,0xba,0x5d,0xce,0xa2,0x96,0x7d,0x62,0xa7,0x21,0xf0,0xa7,0xc2,0x91,0x03,0x38,0x37,0x0b,0x20,0x40,0x88,0x7b,0x28,0xf4 +.byte 0xf3,0xc2,0xb0,0x4b,0xf6,0xef,0x2f,0xd9,0xb5,0x81,0x17,0x95,0x42,0x98,0x7f,0x18,0xd4,0x7e,0xa1,0x85,0xbf,0x62,0xdc,0x40,0xe4,0xd3,0xcc,0x78,0x01,0xec,0x12,0xcc,0x04,0x5b,0xfe,0xdb,0x39,0x7c,0x1e,0x56,0x7c,0x72,0x57,0xb9,0xdf,0x9d,0x43,0xd4,0xe3,0x1f,0xbf,0x69,0xfb,0x43,0x23,0xd8,0x75,0x81,0xe8,0x39,0x0f,0xe4,0xe9,0x51 +.byte 0xea,0xb7,0xa7,0xc6,0x17,0xc6,0x75,0x4c,0xa8,0x17,0x41,0x1c,0x55,0x8e,0x8d,0xf3,0x64,0xbc,0xc3,0x33,0xa7,0xc1,0xbe,0xa2,0x89,0x75,0xd6,0xda,0xad,0x44,0xd5,0xdd,0x18,0xe2,0xfc,0x1d,0xa1,0xbc,0x1a,0xb8,0x40,0x1a,0x4f,0x44,0x4b,0x56,0xe9,0xf4,0xa8,0x16,0xe6,0xc9,0x40,0x90,0x9b,0x49,0xae,0x62,0x12,0x3d,0x50,0x2e,0x7b,0x60 +.byte 0x6f,0x04,0x01,0x2c,0x83,0x2a,0xd2,0x92,0x63,0xa2,0xe2,0x39,0x9a,0xc4,0x1e,0x5a,0x53,0x3f,0x4d,0x69,0xfa,0x0a,0x22,0x13,0x80,0xa4,0x6e,0xfb,0x09,0xcb,0x35,0xd7,0x12,0xa4,0xcd,0xfc,0x0b,0x06,0xa6,0x5e,0xc6,0x4a,0x22,0x56,0x5d,0x7f,0x70,0xd0,0xf8,0xe6,0x96,0x77,0xce,0xd9,0x69,0x6c,0x06,0xac,0xaa,0x94,0x6d,0x57,0x1b,0x28 +.byte 0xb4,0x07,0x50,0x19,0xd1,0x86,0xba,0xe6,0xe6,0x31,0x74,0x1d,0x3d,0xe8,0xe2,0x7b,0xfe,0xc9,0x41,0x89,0x20,0x5b,0x6a,0xc0,0x18,0x16,0xee,0x35,0xfa,0x56,0x35,0x3e,0x53,0x99,0xfb,0x8d,0xae,0x75,0x4f,0xc5,0x8d,0xff,0x23,0xd5,0x42,0xf4,0x81,0x5c,0x8b,0x71,0x7a,0x22,0xb0,0x6b,0x45,0x86,0xa6,0xc6,0xdb,0xa6,0x83,0x01,0x28,0xde +.byte 0x38,0xaa,0x6e,0xf8,0x5a,0xf2,0xcc,0x3c,0xc5,0x65,0x78,0x37,0xe8,0x8a,0x59,0xf3,0xfe,0x8b,0xcd,0xf6,0x31,0x46,0xdc,0x72,0x19,0xf7,0x73,0xac,0x5c,0xf1,0xe3,0xfd,0x85,0x51,0xec,0x92,0x3a,0xf3,0xd7,0xb2,0x95,0x53,0x79,0x48,0xd3,0x29,0x84,0xec,0xc5,0x0a,0x71,0x15,0x52,0x69,0x6a,0xe1,0xab,0x69,0x94,0xc2,0x51,0xdf,0x27,0xd8 +.byte 0xb1,0x05,0xc4,0x12,0xea,0x1e,0xda,0x6e,0xf2,0xf5,0x8a,0xa8,0x72,0x74,0x5a,0xe5,0x45,0x5b,0x5f,0xf9,0xb0,0x56,0x5c,0x85,0xf7,0x63,0x8d,0x1d,0xbf,0xe9,0x7c,0x97,0xe9,0x37,0xb3,0x5b,0x4b,0x57,0xfc,0xf4,0x58,0x84,0x26,0x55,0x07,0xc7,0x0a,0xfe,0x5a,0x58,0xd0,0xd8,0x19,0xf4,0x02,0xad,0x2c,0x4e,0xbd,0xe1,0x07,0x48,0x3b,0xc4 +.byte 0xd6,0x23,0x3a,0x63,0xc3,0xf5,0x17,0x46,0x03,0xa4,0x9a,0x10,0xf9,0xac,0x70,0x9c,0x13,0x10,0x94,0xda,0x17,0xc5,0xbb,0x87,0x0f,0x9b,0x4f,0x54,0x55,0x6b,0x57,0x2d,0x12,0x0b,0xa7,0x9c,0x77,0x6d,0x67,0xb0,0x03,0xdf,0xc6,0xa2,0x76,0x96,0x0c,0xac,0x30,0xbc,0xa2,0x55,0x23,0x01,0xae,0x51,0x50,0xd4,0xab,0xd0,0xee,0x75,0xf1,0x96 +.byte 0x75,0xf5,0x2e,0xae,0x52,0x31,0x0b,0x0a,0x8a,0xdb,0x4c,0x4d,0x4c,0x80,0xfc,0xd7,0x68,0x05,0x54,0x47,0xa5,0xc4,0xb1,0x63,0x87,0x43,0x1b,0xe1,0x0b,0x4f,0xff,0x0c,0x02,0xf7,0x00,0xd4,0x8d,0x6e,0xa1,0x21,0x91,0x62,0xec,0x55,0xd5,0x72,0x70,0x59,0x7a,0xa4,0x0e,0x78,0x7a,0x87,0x1f,0x71,0x35,0x3b,0xf7,0x1f,0x66,0x8c,0x90,0xf9 +.byte 0x6d,0x1f,0x74,0x47,0x41,0xf5,0x21,0x98,0x0d,0x42,0x61,0x21,0x0b,0x62,0x59,0xc7,0x5e,0x58,0x37,0xfb,0xee,0xbb,0xa0,0x45,0xa8,0x84,0xae,0x41,0x29,0xc9,0x88,0x64,0x69,0x75,0xc1,0x5f,0x63,0x7c,0x00,0x1c,0x35,0x61,0x9e,0xad,0x19,0xd7,0xd8,0xf1,0x64,0x57,0x10,0x87,0x73,0xa8,0x8b,0x39,0x9b,0x1c,0x1a,0xc2,0x1b,0x01,0x1a,0x41 +.byte 0x26,0x58,0x93,0x8f,0xed,0xf9,0xe7,0xfe,0xcc,0x27,0x1b,0x6b,0xb8,0x28,0x5a,0x0b,0x04,0xa0,0x94,0x23,0x4b,0x21,0x5f,0xb3,0xc9,0xb6,0x7b,0x36,0x5a,0x67,0x6b,0xd2,0xc2,0x53,0x97,0x5d,0xa5,0x43,0xd3,0x79,0x83,0xe2,0x3b,0xe0,0xaf,0x5f,0xbd,0xf3,0xb0,0xfc,0x04,0x95,0x06,0x17,0x0c,0xe2,0x68,0xe8,0xf3,0x90,0xc7,0x2b,0x7b,0xcc +.byte 0xaa,0xce,0xf5,0x0b,0x3c,0x3f,0x10,0xa7,0x31,0x9d,0xf0,0x1e,0x3e,0x74,0x57,0xbd,0x87,0xe7,0x37,0xd0,0x37,0x09,0xae,0x03,0x96,0xb1,0xad,0x8f,0x2d,0x72,0xdc,0x0f,0xdf,0xd9,0xfb,0xcc,0xb8,0x48,0x62,0xf7,0xad,0x05,0x4d,0xc6,0xe5,0x92,0xe3,0x95,0xa0,0x74,0x7a,0xa6,0x84,0x13,0x68,0x17,0xaa,0x8f,0x40,0x2a,0x8d,0x2b,0x66,0xdc +.byte 0xf8,0xf6,0x6d,0x7c,0x7e,0x40,0x22,0x05,0x16,0x20,0xbc,0xe5,0xc2,0x87,0xe2,0xd5,0xbd,0x47,0xd5,0x69,0x95,0x12,0x25,0x1c,0xaa,0x9d,0xb5,0x73,0x08,0xaf,0xfb,0x46,0xa5,0x11,0x2c,0x93,0xc6,0xfc,0xc0,0x5e,0x0e,0x99,0x1c,0x80,0x5f,0xe5,0xc8,0x52,0x73,0x35,0x4d,0xbc,0x70,0xeb,0x40,0xc9,0x47,0x8a,0x8f,0x19,0xd9,0xa9,0xec,0x4b +.byte 0x88,0x53,0x56,0x08,0x4a,0xa2,0x32,0x1f,0xe2,0xbb,0x68,0x35,0xfd,0xf2,0x0e,0x0f,0x7f,0xc8,0xf1,0x59,0xac,0x97,0x8f,0x84,0x69,0xb6,0xb9,0x5f,0x84,0xe9,0xf2,0xf9,0x09,0xf6,0xf1,0x31,0xd7,0x1a,0xa8,0x25,0x32,0x5f,0xb1,0xa7,0x84,0x15,0xfa,0x07,0xa8,0x53,0xce,0x2a,0x26,0xe0,0x4d,0x07,0x4f,0x45,0x63,0x76,0xfd,0xe3,0xb4,0x4e +.byte 0x81,0x5e,0xe6,0x01,0x9c,0xf5,0x82,0x2d,0x71,0x0f,0x98,0xb4,0x72,0x06,0xbc,0x89,0x89,0x60,0x5f,0xd9,0x92,0xcf,0xb9,0x41,0xe3,0x13,0xaa,0xe4,0x80,0xb5,0x75,0xf4,0x9a,0x1b,0xc2,0xa3,0xa4,0xa9,0x0f,0x15,0xdc,0x26,0xdd,0x20,0x10,0x27,0xbd,0x06,0x77,0x12,0xa5,0xb3,0xde,0x9f,0xbf,0xc4,0xb6,0x1d,0x76,0xdc,0x16,0x00,0x2e,0xe2 +.byte 0x00,0x4d,0xb3,0x62,0x57,0x73,0x1e,0x90,0xe2,0xaa,0x4c,0x47,0xdf,0x6b,0x2d,0x66,0x2f,0x82,0x55,0x91,0x26,0x33,0xb9,0x3a,0xc7,0xf1,0x0a,0xda,0x9b,0x6b,0x05,0x82,0x0f,0x0e,0x30,0x74,0x0b,0xea,0x0f,0x49,0x55,0x3b,0xe7,0x42,0x48,0xca,0x82,0x3e,0x8c,0xbc,0xe2,0x88,0x43,0x44,0x0d,0x37,0x9b,0xd1,0xfc,0xf1,0x45,0x46,0x0e,0xe1 +.byte 0xec,0x91,0x39,0x96,0x7d,0xbc,0xd5,0xb1,0x11,0x55,0x54,0x49,0x4f,0x18,0xed,0xec,0x58,0xdb,0xb3,0x7d,0x64,0x8d,0xfc,0x65,0x1f,0xf0,0xe0,0xc0,0x41,0xc0,0x19,0xeb,0x16,0x16,0x71,0x36,0x88,0xcf,0x75,0x3d,0x9c,0xe6,0xa0,0x84,0x54,0x26,0x64,0x95,0x9a,0xe1,0x0b,0x51,0xcf,0x9a,0x55,0x60,0x4d,0x9d,0x1d,0x37,0x71,0xa8,0x94,0x0a +.byte 0x20,0xeb,0xf2,0x91,0x14,0xfc,0x12,0xb0,0x1e,0xe3,0x5e,0x3a,0xbb,0x22,0xde,0x20,0xb1,0x58,0xef,0x0b,0xb1,0xc2,0x2f,0xea,0xd8,0xdb,0x1d,0x3a,0x67,0x7b,0xbd,0x26,0xfa,0x4a,0x3c,0x3d,0xbd,0x87,0x4c,0xba,0x57,0xdf,0xfb,0x1d,0xf7,0x26,0x5f,0x52,0x4e,0xdd,0x9b,0x38,0x62,0xed,0x48,0xc1,0xae,0x7f,0xa8,0x13,0x05,0x09,0xff,0xc0 +.byte 0xd3,0x49,0x75,0x1f,0x6a,0xe0,0x79,0x94,0xc1,0xe9,0xe3,0xf5,0x33,0x40,0xd4,0x6b,0xfe,0x4d,0x6e,0x84,0xb9,0x20,0x68,0x2b,0x6c,0xb3,0xf1,0xb1,0x1c,0xfd,0x93,0x14,0x7f,0x35,0x9b,0xd5,0x07,0x15,0x87,0x56,0xb9,0x45,0x22,0x64,0x73,0xdb,0x34,0x35,0xca,0x15,0x4e,0xa2,0xa2,0xe2,0x7a,0x6e,0x14,0x46,0xf5,0xf1,0x70,0xd3,0x3a,0x2e +.byte 0x38,0x9d,0xf6,0xc6,0x29,0xd5,0x7f,0xc7,0x77,0x2c,0x33,0x55,0x1c,0xc2,0xf1,0xaf,0x8e,0x4d,0x1b,0x22,0x36,0x35,0x93,0x47,0xa5,0x59,0xb4,0x94,0x0f,0x2d,0x66,0x24,0x6f,0x57,0xa4,0x95,0xf3,0xd7,0xf3,0x59,0x9d,0xc0,0xda,0xa7,0xf7,0xf2,0x8d,0x93,0xc9,0x90,0x91,0x9e,0x12,0x3f,0x34,0x01,0x90,0x8b,0x13,0x09,0x3d,0x2f,0xa8,0x31 +.byte 0xfa,0x39,0x4a,0x7d,0x0d,0x34,0xa3,0xf1,0x75,0xdb,0xa2,0xd2,0x5c,0xf1,0x72,0xfd,0x7f,0x7b,0x15,0x92,0xf0,0x71,0xd6,0xa0,0x74,0x53,0x61,0x67,0xa4,0x8b,0x72,0x3a,0x66,0x0a,0xce,0xc9,0x1c,0x5b,0x4d,0xaa,0x0a,0x3a,0x91,0x0a,0xbb,0xef,0x6e,0x8d,0x00,0xc0,0xa1,0x89,0xa9,0xbd,0x5a,0x2d,0xf8,0x7c,0x1f,0xb2,0x5a,0x73,0x33,0xe7 +.byte 0xb3,0xfd,0xd4,0xe3,0x81,0x69,0x30,0xc1,0xf8,0x97,0x7b,0xf3,0x63,0xaa,0xd5,0x5a,0x98,0x95,0xb3,0x65,0x2d,0xf9,0x68,0x2e,0x2c,0x26,0xe6,0x77,0x8f,0x76,0x7a,0x02,0xc7,0x50,0x28,0x40,0xcf,0x44,0x66,0x18,0x54,0x52,0xef,0x79,0x26,0xc2,0x76,0x5b,0x71,0x92,0x49,0xba,0xe1,0xd7,0xf2,0xdd,0x57,0xe0,0x78,0x6e,0xb6,0xdd,0x0d,0x20 +.byte 0x85,0xf9,0x34,0x9e,0x65,0x6b,0x9f,0x41,0x24,0xe2,0xb1,0x2a,0xef,0x8b,0xd2,0x19,0x81,0x73,0x56,0x5a,0x84,0xd3,0x46,0xf8,0x74,0xe3,0x1f,0x3d,0xd9,0x16,0x86,0x38,0xf6,0x7c,0x04,0xab,0x9a,0x64,0x0e,0x48,0x06,0x4c,0x61,0xcd,0x2d,0x4d,0xef,0x6f,0xd6,0x7d,0x31,0x1c,0x56,0x65,0xc4,0xf1,0xa7,0x15,0xac,0xa4,0xe2,0x8b,0x83,0x5e +.byte 0x64,0x36,0x2e,0x77,0x94,0x2e,0x2e,0xa3,0x62,0xcf,0x6e,0x7a,0x6d,0x39,0xaf,0xf7,0x96,0x88,0x31,0x14,0x58,0x46,0x30,0x0c,0x36,0x3a,0x4c,0x53,0xe0,0xa7,0x24,0x76,0x84,0x0f,0xfb,0x7e,0x55,0xa0,0x0f,0x63,0xfc,0xd6,0x1f,0x58,0x68,0xb5,0xcc,0x77,0x4f,0x16,0x91,0xa7,0xfd,0x62,0xb3,0x88,0x13,0x7c,0xcb,0x63,0x6d,0xe4,0x38,0x4c +.byte 0x6e,0x3b,0xf7,0xe3,0x8d,0x52,0x84,0x61,0x19,0x12,0x51,0xbe,0xed,0x32,0x3d,0x77,0xdd,0xa1,0xc3,0x59,0x65,0x79,0xa1,0x6b,0xbc,0x65,0x6c,0xe3,0x7e,0x60,0x49,0xbd,0xcf,0x6f,0x61,0x97,0x98,0xbe,0x74,0x38,0xd1,0x09,0xc1,0x59,0xe5,0x7f,0xfe,0xbf,0xfd,0x60,0x1b,0x96,0x00,0x46,0x56,0x4d,0x81,0x4c,0x70,0x59,0x39,0x66,0x13,0x58 +.byte 0xe7,0x62,0x3a,0xfc,0x1b,0xe5,0xf9,0x03,0xd4,0x4b,0xab,0x1d,0x56,0x22,0x4a,0x09,0xa5,0xdd,0xac,0x39,0xbe,0x27,0x39,0xb3,0xe8,0xad,0xe0,0x07,0x86,0x10,0xce,0xa9,0x4e,0x8b,0x47,0x8d,0xb8,0x63,0x2f,0x61,0x1a,0x8b,0xd4,0xd3,0xfe,0x73,0x82,0x5a,0xd6,0xa9,0x46,0x56,0xa7,0x81,0xe9,0xda,0xb9,0x17,0xa7,0xc8,0x0f,0x24,0x16,0x6a +.byte 0x12,0xfe,0xc3,0x65,0x85,0x77,0xab,0x89,0x44,0x1b,0xa3,0x8b,0xfd,0x07,0xf4,0x77,0xaa,0xe1,0x71,0x33,0x74,0x93,0xdc,0x90,0x53,0x39,0x47,0x8c,0xea,0x18,0xe1,0x6a,0xed,0x8c,0x56,0x08,0x2f,0xa1,0x1f,0x22,0xf2,0xc0,0x12,0xcd,0xb7,0xdf,0xb6,0x3c,0xd6,0x22,0x6c,0x5b,0x00,0x0f,0xdb,0x66,0x5b,0x54,0x35,0x48,0x37,0x8c,0x79,0x74 +.byte 0xd1,0xb0,0x15,0x01,0x22,0x3a,0x7c,0x17,0x8c,0x20,0x06,0x9b,0x13,0x6e,0xee,0xbf,0xb4,0xac,0x01,0x61,0xb9,0x28,0x65,0x8e,0x53,0x12,0x4f,0xe0,0x5f,0xfc,0xdb,0x40,0x6c,0xa2,0x19,0x64,0x49,0x7a,0xc7,0xc5,0xc8,0x53,0x6e,0xd5,0x68,0xe1,0x61,0xe5,0x87,0xc2,0x99,0x59,0x4c,0x27,0xc8,0xd0,0xd0,0x10,0xce,0x9f,0x09,0xff,0xf5,0xa8 +.byte 0xf8,0x79,0xf6,0x0f,0x73,0xda,0x8a,0x36,0x8e,0x48,0x7e,0xbd,0x98,0x76,0x57,0xfa,0x5c,0xec,0xa5,0x3d,0x30,0xfe,0xa3,0xe5,0x27,0x87,0xcf,0x26,0xfe,0x61,0xe4,0xed,0xd1,0xfb,0xfc,0x91,0x5d,0xb6,0x70,0x2c,0x2c,0x59,0x14,0xd5,0x1d,0x9a,0xb9,0x2c,0xef,0x24,0x7b,0x10,0x8d,0x99,0x63,0xaa,0x82,0xf0,0x1c,0xe8,0xa0,0x00,0xa5,0xa7 +.byte 0xf8,0xc0,0x35,0x9e,0x12,0x18,0xaf,0x42,0x9d,0xe5,0x2b,0x72,0x6c,0x31,0xd8,0x8f,0x6c,0xde,0x2e,0x37,0xa6,0x73,0x06,0xe7,0x90,0x43,0x79,0x99,0x64,0xd1,0x17,0xa1,0x43,0x6d,0xd4,0x90,0x50,0xf2,0xcc,0x0b,0x73,0x49,0x9e,0x14,0x7c,0x49,0x92,0x05,0x0e,0x8c,0xda,0xb7,0x18,0xf0,0xcc,0xea,0xe4,0x32,0x58,0xc7,0xbd,0x8e,0xca,0x35 +.byte 0x52,0x9f,0xec,0x5d,0xa0,0x6c,0x83,0x61,0x07,0x74,0x37,0x4a,0x10,0xa0,0x98,0x83,0x3a,0x65,0x17,0x63,0xd0,0x22,0x96,0xb5,0xed,0xbb,0xbb,0x1c,0x18,0x8a,0x49,0x3d,0x0f,0xcc,0x24,0xb3,0x9b,0xb6,0x23,0x2e,0x9d,0x97,0xe7,0x31,0xf8,0x36,0x6d,0x7b,0xa1,0xf1,0x02,0xde,0x7c,0xad,0x77,0x5d,0x85,0x7c,0x39,0x61,0xc7,0xd7,0x3f,0x70 +.byte 0x1c,0xe1,0x0e,0x49,0xf4,0xcd,0xab,0xfd,0x4d,0x2f,0xc7,0xb7,0x53,0xfc,0xed,0xeb,0x41,0x2a,0x80,0x40,0xf3,0x47,0xf8,0x15,0xa0,0x4c,0x8b,0x34,0xf6,0x6a,0xb8,0x30,0x09,0x4d,0xe6,0x60,0xb7,0x24,0x6b,0x4c,0x26,0xdf,0x83,0x37,0xc7,0x96,0xba,0x35,0xda,0x29,0x4e,0xca,0x52,0xf7,0x41,0xd3,0x98,0x27,0xb2,0x9e,0xec,0xcc,0x12,0xdc +.byte 0x77,0xfd,0x11,0xbd,0xbd,0xbb,0x5e,0x0c,0x37,0x29,0xd2,0x4f,0x7d,0x5c,0x97,0xad,0x72,0x93,0x4a,0xfa,0x17,0x07,0x07,0x26,0xee,0xa7,0x29,0x2e,0xdb,0xf6,0x60,0x65,0x2d,0x85,0xbe,0x27,0x4d,0xf7,0x2b,0xb4,0x81,0xf5,0x3a,0x1d,0xae,0x25,0x8b,0x60,0xc2,0x75,0x3a,0xfd,0xf9,0x4d,0x90,0x7a,0x8a,0x3a,0xf6,0xa9,0xf0,0x11,0xd2,0xb9 +.byte 0xdb,0x23,0x40,0x9d,0x33,0xc3,0xbf,0x60,0x95,0x9c,0x6f,0xa9,0x82,0x42,0xe5,0x67,0x52,0x36,0xea,0x68,0x64,0x24,0x85,0x46,0x7e,0x2a,0x1a,0x6a,0x4b,0xa8,0xb0,0xa0,0x9c,0xb8,0x4a,0xb6,0x2e,0xb2,0x6b,0xf4,0x63,0x9f,0x54,0xb5,0x6f,0x1b,0xf5,0x71,0x7e,0xf8,0xef,0xb2,0x92,0xe2,0xcf,0x65,0xb4,0x02,0x9b,0x75,0x4b,0xf9,0x6b,0xa1 +.byte 0x24,0x3b,0xea,0x7f,0x31,0x08,0xd4,0xdc,0xab,0x12,0xc0,0xca,0x64,0xee,0xfa,0x61,0x1c,0x0f,0x24,0xc3,0x8c,0xbd,0xc8,0xd2,0x42,0xf7,0x1f,0x2e,0xd3,0xd1,0x51,0x86,0xfb,0xa2,0x95,0xc5,0x8c,0x5b,0x61,0x14,0xc9,0xe4,0x07,0xa1,0xf7,0x39,0x11,0x40,0x68,0xd6,0xe2,0x38,0x96,0x6f,0x99,0xf1,0xd2,0xfb,0x8e,0xb8,0x3d,0xf2,0x8a,0x4e +.byte 0x3e,0x54,0xd9,0x0e,0xd1,0xc9,0x31,0x04,0xa4,0xee,0xbe,0x51,0xcf,0x5f,0xd1,0xc8,0x13,0x96,0x9d,0x9b,0xdf,0x32,0xa9,0x38,0x8f,0xbc,0x7e,0x22,0x1a,0x52,0x5f,0x14,0x61,0xeb,0x78,0xf4,0x01,0xe9,0x5c,0x18,0x1c,0xb5,0xe1,0x80,0x06,0x3e,0x8e,0x72,0x33,0xf9,0xaa,0x49,0xec,0x5b,0x7a,0x04,0xf2,0x9b,0x48,0x8a,0x58,0x14,0x4b,0x7e +.byte 0x4d,0x26,0x0b,0xe0,0xf0,0x69,0xa3,0x36,0x75,0x3e,0x73,0xec,0x53,0x20,0x35,0x8e,0xfa,0x40,0xf0,0xcd,0x70,0xe1,0xe4,0x64,0x89,0x14,0x55,0xd7,0x20,0xe8,0xbd,0xc2,0x85,0xa8,0x4d,0x51,0x96,0x27,0x54,0x50,0xc7,0xa1,0x9c,0x35,0x52,0x1f,0x8b,0x6f,0xa2,0x62,0x36,0x94,0x02,0xb1,0x01,0xc6,0x4e,0x53,0x83,0x65,0x98,0x25,0x6d,0x26 +.byte 0x6d,0xef,0x4e,0x7a,0xe0,0x56,0x6a,0x6c,0x23,0xe8,0xa6,0x97,0xc1,0xf2,0xb1,0x2d,0x03,0x29,0xef,0xa0,0x6d,0x86,0x8d,0x5a,0x00,0x83,0x14,0xed,0xd4,0x1e,0x79,0xc4,0xb4,0x42,0xfd,0x53,0xaa,0xab,0xd7,0xa3,0xf9,0x7d,0x15,0x26,0xab,0x81,0xc4,0x7a,0x96,0x14,0x94,0x71,0xe1,0x7f,0xc1,0x67,0x5f,0x5f,0x11,0xb4,0x72,0x03,0xf8,0x9b +.byte 0x2f,0x82,0xa3,0x4e,0xda,0xfd,0x2a,0x31,0xf1,0x74,0x6d,0x96,0x7a,0x9c,0xf9,0x01,0xd9,0x55,0x8e,0x52,0xe4,0xae,0x22,0x14,0x7b,0xc0,0x5a,0xc4,0x31,0x23,0x9a,0x2e,0x9d,0x86,0x86,0xd5,0x66,0xc8,0x8b,0xdb,0x49,0x5f,0xca,0x57,0x51,0x50,0x75,0x3f,0xeb,0xb1,0xe5,0x84,0x42,0x8f,0x0f,0xca,0x86,0xcf,0xb0,0x17,0x06,0x06,0x46,0x8c +.byte 0x4a,0x84,0xde,0x28,0x84,0x24,0x7f,0x33,0x48,0xe8,0x89,0x87,0x1f,0x02,0x07,0x4f,0x36,0xa9,0xdc,0x8a,0x42,0xb6,0xc7,0x9c,0x47,0xd4,0xd4,0x2d,0xc0,0x17,0xb0,0xe6,0x23,0xb7,0xae,0x0d,0x9f,0x38,0x0a,0xdf,0x7f,0x73,0xbf,0x93,0x19,0x05,0x23,0xbf,0xc0,0x53,0x2d,0xcd,0x3e,0x73,0x01,0x78,0xa7,0xdc,0x6c,0x85,0x1d,0x25,0xc5,0x54 +.byte 0x68,0x95,0xc1,0x20,0x65,0xd9,0x01,0x85,0x7d,0xc9,0xba,0x63,0x43,0x7a,0x23,0xbb,0x95,0x3a,0x76,0x2d,0x75,0x1e,0xac,0x66,0x3e,0x20,0x30,0x8d,0x37,0x64,0x3c,0xc7,0x6f,0x36,0xb8,0x34,0x60,0xd2,0xb4,0x54,0x07,0x52,0x6c,0xfa,0x04,0xfe,0x2b,0x71,0x03,0x03,0x97,0xfc,0x4a,0xf9,0x4d,0x44,0x1a,0xf9,0xd7,0x4b,0xe5,0xe1,0xf9,0xb9 +.byte 0x41,0xa0,0x5b,0xa2,0x69,0x48,0xba,0xeb,0xcc,0x4e,0x55,0x4b,0xbd,0x41,0x09,0xa8,0x90,0x5c,0xc6,0xe3,0x20,0x0c,0x8f,0xfc,0x7e,0x0e,0x4f,0x3d,0x47,0x65,0x40,0x1e,0x79,0x9a,0xe0,0x8f,0x8f,0xe9,0xcb,0xaa,0x04,0xb8,0xd9,0x91,0x30,0x2a,0x4c,0x17,0x44,0xc0,0x03,0x4c,0x37,0xd3,0xdb,0x20,0xe5,0x8e,0x70,0x87,0x57,0x4f,0x8a,0xcf +.byte 0xee,0x64,0xbc,0xef,0x0f,0x9e,0xcf,0x95,0x5e,0x11,0x4f,0x7a,0x35,0x53,0x8c,0x85,0x6a,0xff,0x72,0x1b,0x35,0x51,0x89,0xf8,0x94,0x65,0x97,0xec,0xfe,0xbd,0x00,0x29,0x3d,0xe8,0x96,0x23,0xa4,0xe3,0xcf,0x81,0xb2,0x8f,0x73,0x4c,0x05,0xc3,0xcc,0x37,0x22,0x97,0xa0,0xda,0x49,0xb2,0xbd,0x07,0x2b,0x26,0xa0,0x6f,0x6b,0x1f,0xa6,0x15 +.byte 0xe3,0x6e,0x12,0xa4,0x51,0x1b,0x72,0x22,0x08,0xfe,0xf7,0x93,0x1a,0x9f,0x62,0x12,0xd4,0x11,0x1f,0xd1,0x80,0xeb,0xa4,0xb1,0xf4,0x37,0x3b,0x60,0xd8,0x2b,0x53,0xae,0x69,0xf8,0x48,0x38,0xf4,0x20,0x28,0xe1,0xfb,0x6a,0xec,0x6e,0x11,0x2e,0x2c,0x59,0x62,0x23,0x8a,0x82,0xc4,0x33,0x7b,0xdc,0x33,0x99,0x41,0x29,0x4f,0xa1,0x6e,0x3a +.byte 0x48,0x13,0x1c,0x1f,0xa3,0x1f,0xd2,0x02,0x79,0xe1,0xe4,0xb9,0x99,0xa4,0x50,0xea,0x53,0x96,0x4e,0x82,0x7c,0xee,0x65,0x07,0x26,0x87,0xf9,0x9d,0x45,0x17,0x37,0x61,0x7e,0x5f,0xb9,0xd2,0x55,0x3c,0x45,0xf7,0xec,0x33,0x08,0xa3,0x41,0x24,0x8f,0xb2,0x75,0x41,0xb6,0xa2,0x21,0xfe,0x94,0x7e,0x1e,0xe6,0x03,0x6e,0xf4,0xeb,0x23,0x59 +.byte 0x51,0x25,0x99,0x19,0x6d,0xf7,0xe3,0x22,0xd8,0x41,0x0f,0xd5,0xaf,0x0d,0xc6,0x3f,0x8e,0x36,0xee,0x90,0x23,0x67,0x03,0xcb,0xe3,0xaf,0xc4,0xf8,0x22,0x1f,0xd8,0x3e,0x94,0xdf,0x13,0xc9,0x4f,0x17,0x22,0x8c,0x93,0x6b,0x3f,0x60,0x1a,0xbd,0xfa,0x9f,0xe6,0x43,0x45,0xe1,0x0a,0x95,0x21,0x06,0x52,0xbd,0x58,0x56,0x84,0x56,0x36,0xf3 +.byte 0x55,0x58,0x46,0x62,0x6c,0xb3,0xa0,0x29,0x5a,0xfc,0xb4,0x87,0x5f,0x89,0xa5,0xab,0x6d,0x5a,0x44,0xc5,0xc8,0x50,0x83,0xe1,0x41,0xd4,0x97,0x6c,0x08,0xb1,0x43,0x33,0x0d,0x3a,0x8b,0x31,0xa1,0xae,0x77,0x71,0xb7,0x67,0x65,0xd7,0xa7,0xc9,0x6c,0x4a,0x9b,0x80,0xd5,0xbf,0xae,0x0f,0x9b,0xce,0x1a,0xa3,0x26,0xc6,0x19,0xa1,0x8d,0x12 +.byte 0xd9,0x09,0xae,0xac,0x9f,0x4b,0xab,0xaf,0xf6,0xc5,0x9e,0x26,0xe6,0x23,0xcb,0x3e,0x60,0x1e,0x3d,0xa1,0xec,0x59,0xca,0xf1,0x87,0x0e,0xaf,0x47,0x5f,0xab,0x17,0x99,0xbd,0x87,0x1c,0x1d,0x00,0xd6,0xb2,0x59,0x56,0xdd,0x49,0x20,0xb5,0x91,0xf8,0x0c,0xf1,0x80,0xc6,0x37,0x92,0xd7,0x2c,0x02,0x0d,0x47,0x1b,0x1b,0x6b,0x3f,0x60,0xd0 +.byte 0x21,0x9b,0x49,0x47,0x3c,0xaa,0x83,0x44,0x1b,0x92,0x8e,0xec,0x63,0x40,0xd6,0x9a,0x48,0x7c,0x5e,0x97,0xe4,0xf0,0x84,0x36,0x30,0x11,0x0b,0x7c,0x79,0x3b,0xff,0xdf,0x77,0xf6,0xc9,0xdb,0x49,0xdd,0x2a,0xe7,0xca,0x9a,0x5b,0xef,0xd4,0x84,0xe2,0x44,0x8b,0xef,0x4e,0x0d,0x13,0xd6,0xbb,0xba,0x29,0x02,0xae,0xfc,0x55,0x24,0xfa,0x4b +.byte 0x7d,0x71,0xc9,0xde,0x71,0x36,0xbc,0xac,0x31,0x5c,0xf8,0x20,0xdd,0xb8,0xae,0x03,0xd3,0xb0,0xdc,0x27,0x7f,0xc5,0xff,0xda,0x8a,0x36,0x2d,0x8f,0xae,0xbd,0xf8,0x92,0x28,0x8e,0x0c,0xc3,0xaf,0x4e,0x33,0xf0,0x71,0xdb,0xad,0x4d,0xc1,0xef,0x52,0x1c,0x84,0xdc,0x0d,0xf3,0xab,0xb9,0x0b,0xe0,0x18,0xa5,0x06,0xdc,0x78,0x41,0x73,0x35 +.byte 0x95,0x37,0x84,0xba,0xc1,0x4e,0x0a,0xe4,0x4d,0x05,0xfe,0x9d,0x74,0x68,0x4a,0x35,0xf0,0x15,0xaa,0x7b,0xfe,0x08,0x47,0xb2,0x84,0x65,0x1d,0x0d,0x9f,0xe7,0xe0,0x04,0xf9,0x1c,0xac,0x66,0xb3,0x75,0x96,0x8f,0x25,0xb6,0x29,0x53,0x52,0x50,0x7a,0x50,0xd1,0x89,0xc7,0x05,0xfb,0x3a,0xb0,0xfa,0x6b,0x96,0x9d,0xfc,0xb0,0xcd,0x68,0x21 +.byte 0x61,0xf6,0x65,0x64,0xa7,0xc6,0x56,0xbd,0xf0,0x9b,0x4a,0x9a,0xe2,0x8c,0xd8,0x88,0x70,0x82,0x0c,0x87,0x51,0x77,0x23,0xd8,0xd8,0xf8,0x4a,0xfe,0xf4,0x6d,0x3f,0x2a,0x36,0x0c,0x67,0x85,0x43,0x13,0x83,0xd5,0xe9,0x32,0xff,0x8c,0xec,0xd4,0x7f,0xd2,0x32,0x4d,0x4e,0xec,0x76,0x55,0xf9,0x0d,0xb7,0x57,0x6c,0xc4,0xd6,0x22,0xd3,0x6e +.byte 0x71,0x23,0x68,0x45,0x03,0x37,0x27,0x3d,0x56,0x89,0xbb,0x7c,0xf1,0xa8,0x09,0xd6,0xb2,0xc5,0xe6,0xf6,0x72,0x77,0x3e,0xb0,0x8a,0x3d,0x17,0xbd,0xd5,0x0d,0xdb,0x62,0xa7,0x07,0x66,0x35,0x19,0x12,0xff,0xcf,0xdd,0xb3,0x09,0xa3,0x58,0x5b,0x0d,0x87,0x76,0x33,0x28,0x98,0x91,0x48,0xac,0xa1,0x22,0x9f,0xda,0x36,0x03,0x8a,0xc1,0x5e +.byte 0x6c,0x2e,0x42,0x8e,0x1a,0x7d,0x75,0x69,0xb2,0xcf,0xb0,0x14,0x80,0xa8,0x91,0xc2,0xbc,0x24,0x8f,0x25,0x9a,0x9e,0xa3,0x4d,0x46,0x55,0x53,0x05,0x0c,0xf8,0xdb,0xe0,0xee,0xe4,0x32,0xff,0x39,0x74,0x9a,0xa8,0xf7,0xa4,0x6e,0x5b,0x9a,0x89,0x33,0x40,0xf4,0xce,0x54,0x4a,0x18,0xdb,0x11,0xe4,0x83,0x69,0x52,0xef,0x12,0xc6,0x13,0x6e +.byte 0x2a,0x14,0xb9,0x8e,0x38,0x8d,0x6b,0xef,0x02,0xc8,0x66,0xf0,0x78,0xaa,0xa6,0x04,0xa3,0xa5,0x1d,0xdb,0xac,0x02,0x23,0x4c,0x2a,0xa5,0xbf,0x66,0xa4,0x47,0xa9,0x8e,0x50,0xd2,0xf8,0xf5,0x0d,0x0f,0xc9,0x07,0xd8,0x1a,0x94,0x84,0xcf,0xb3,0x56,0x53,0x5f,0x83,0x1d,0x30,0xb6,0x94,0x36,0xf4,0x16,0x72,0x8c,0x6d,0x49,0xe4,0x6d,0x93 +.byte 0xb1,0xa1,0x97,0x70,0x75,0x47,0x3a,0x7e,0xa6,0x39,0x1d,0xf5,0xcc,0x37,0xaa,0x90,0x53,0xe1,0x9b,0xcb,0x9a,0x97,0x7d,0x18,0x4a,0x3c,0x1f,0x05,0xf4,0xe3,0x6f,0x7a,0x19,0x84,0xbc,0x68,0xa4,0x6e,0x5a,0xb5,0x7a,0x51,0xda,0xf5,0x75,0x1e,0xfe,0xb0,0x73,0x43,0x39,0x98,0xb7,0x1e,0x17,0x36,0x35,0x15,0x64,0x90,0xb6,0x83,0x43,0x8f +.byte 0xcd,0xb6,0x8c,0xc4,0xe4,0xee,0x0e,0x1c,0xbd,0x3a,0xe6,0x6e,0x44,0x73,0x88,0x30,0xa0,0xf0,0x97,0xf5,0x5e,0x12,0xea,0xd9,0xd7,0xb5,0xc5,0x1d,0xc7,0xc8,0x55,0xbb,0x2c,0x64,0x43,0x50,0x15,0x71,0x02,0xd3,0xf9,0xb4,0xe7,0x2f,0x0f,0x98,0x9e,0x87,0x40,0x2a,0x61,0x06,0x44,0xc2,0x47,0xaf,0x44,0x4f,0xdd,0xa3,0xb0,0xb2,0x8d,0x8c +.byte 0x83,0x96,0xd3,0x2a,0x38,0xdf,0x87,0x5d,0x1c,0x64,0xc8,0x4f,0x3c,0x41,0xc7,0xf8,0x64,0x58,0xa6,0x9b,0xcb,0xcd,0x77,0xdb,0x38,0xe7,0x30,0xb6,0x91,0x88,0xd8,0x9d,0x29,0x71,0x12,0x9e,0xdf,0x20,0xd9,0x14,0xa3,0xa0,0xbd,0x0a,0x99,0x67,0x0a,0xe1,0xe9,0xba,0xd0,0x1b,0xba,0xc8,0x8d,0x76,0x10,0xe8,0x30,0xa1,0x93,0xf4,0x95,0x6a +.byte 0x12,0xd5,0x95,0x31,0x7f,0xdb,0x33,0xfc,0xbf,0x7a,0xbe,0xe4,0xfa,0x50,0x1b,0x24,0x75,0x9b,0xf8,0x81,0x34,0xc8,0xfb,0xda,0x3c,0x6f,0x3b,0x9a,0xb2,0x6f,0x94,0x0c,0xd9,0xc3,0x05,0xd6,0x96,0x10,0x27,0xdb,0xd6,0x88,0x72,0xe4,0x8f,0xfc,0xd3,0x52,0xf8,0x63,0xb2,0xce,0xf1,0x2a,0xbc,0x1c,0x23,0x9d,0xfb,0x27,0xdd,0x8d,0xe4,0xcc +.byte 0x63,0xcf,0xad,0xe6,0xe9,0x4f,0xb8,0x8a,0x20,0x47,0x75,0x73,0x3f,0x27,0x07,0x5d,0x8c,0x8c,0x6e,0x7a,0x91,0xe2,0xf6,0xd5,0x70,0xd8,0x00,0xe5,0x0f,0xde,0x78,0xd8,0xb4,0xd3,0x18,0x5a,0x24,0x43,0x91,0x0c,0xbe,0x8b,0x1b,0x88,0x48,0x7e,0x94,0x05,0xd0,0xec,0xd2,0x71,0x26,0xc7,0x70,0xeb,0x8a,0x83,0x01,0x52,0xdb,0xe5,0x76,0x31 +.byte 0x19,0x14,0x13,0x90,0x5b,0x5a,0x94,0x89,0xe2,0x4e,0x2d,0x17,0xf6,0xbc,0x67,0xee,0x51,0xd4,0x00,0x83,0xe5,0x18,0xa5,0x54,0x6c,0xd2,0x7a,0x1f,0xdb,0x6f,0xed,0x7f,0x07,0xbb,0x9f,0x3a,0xc2,0x8c,0x04,0xf9,0x9a,0x55,0xe3,0x70,0xf3,0x36,0xfd,0x44,0x05,0xd9,0xf3,0xe1,0x87,0x2c,0x29,0xec,0x30,0x8b,0xb7,0xde,0x27,0xa4,0xcd,0xdf +.byte 0x64,0x0b,0x62,0xdf,0x34,0xa0,0xf5,0xa1,0x69,0xc9,0x0b,0x00,0x81,0xf4,0x03,0x5e,0xef,0xb8,0x26,0x49,0x71,0x5e,0xcd,0x76,0xa2,0x38,0x25,0x1f,0x92,0xc3,0xbf,0xdb,0xb3,0x29,0x37,0x06,0xc5,0xc2,0x3b,0xd8,0xbd,0x55,0xf2,0x7f,0xd5,0xd5,0x34,0x32,0xf1,0xa0,0x92,0x9b,0x1c,0xee,0x6f,0x48,0x40,0x6b,0xd1,0x45,0x09,0x3f,0xaf,0xdc +.byte 0xe1,0xac,0x75,0x9a,0x33,0xf7,0x50,0x4f,0x2c,0x3c,0x30,0x69,0x69,0x84,0xcb,0xe9,0xca,0xdf,0x8d,0x02,0x5d,0x30,0x71,0x99,0x7b,0xd5,0xb2,0x55,0xdd,0x9c,0x2f,0xae,0x11,0x41,0x01,0x6b,0xf7,0x95,0xe3,0xda,0xe3,0xcc,0xa4,0x17,0xd0,0x50,0xf9,0x4c,0x31,0x2b,0x4e,0xf7,0x49,0xbb,0x75,0x8f,0x28,0x19,0x9f,0x89,0x7b,0x78,0x80,0x41 +.byte 0x50,0x5a,0x5c,0x1e,0x82,0x93,0x9f,0x4f,0x61,0x96,0x29,0x0c,0x25,0xb3,0xe6,0xff,0x86,0x90,0x78,0x09,0x04,0xf9,0x2a,0x3d,0xa1,0xd5,0x68,0xa8,0x0d,0xd9,0x41,0x01,0xdc,0x41,0x01,0xff,0x20,0xc0,0x63,0x0b,0x4d,0xd5,0x80,0x78,0x82,0x05,0x51,0x62,0x09,0xf9,0x11,0xbd,0xde,0xc0,0x7d,0x3f,0xf2,0x30,0xfb,0x41,0x68,0x39,0xb0,0xc2 +.byte 0x2e,0x33,0x4e,0xa7,0x85,0x01,0x6b,0xd1,0xf9,0x78,0xef,0xe9,0x7c,0x0e,0xaf,0x13,0x1a,0xf5,0x97,0xde,0xf0,0xbb,0x67,0xf9,0x9b,0xab,0xee,0x86,0x73,0x9b,0x23,0x6c,0x56,0x0d,0xa0,0xda,0x4c,0xff,0x2b,0xc5,0x92,0xdb,0xee,0xbd,0xba,0x3a,0x54,0x21,0xc0,0x5c,0xfe,0x21,0xf1,0xbd,0xac,0xaf,0xa3,0x7a,0x52,0x62,0x15,0x8b,0x8f,0xb5 +.byte 0x82,0xc6,0x1a,0xfb,0x22,0xbc,0xa2,0x05,0x42,0xfe,0xb4,0x12,0x6b,0xad,0xa9,0x76,0xb7,0x6b,0x1c,0xd8,0x34,0x5c,0x7d,0xd5,0xa9,0x0d,0x91,0xf6,0xc1,0x47,0x69,0xbc,0x43,0x8f,0xb7,0xfc,0x84,0x2e,0xa0,0x8e,0x3f,0x52,0x3b,0xbd,0x1f,0x28,0x6b,0xc8,0x13,0x37,0xd6,0x44,0xe9,0x8d,0x08,0x92,0x96,0xe5,0x2c,0x57,0x34,0x59,0x21,0x04 +.byte 0xa8,0xaa,0x56,0x25,0xa4,0xc8,0xae,0x68,0x17,0x9e,0xa4,0xf4,0x42,0x64,0x57,0x4b,0x54,0x85,0x8a,0xd1,0x09,0x09,0x25,0x18,0x05,0xb0,0x09,0x9d,0xd9,0x75,0x21,0xd3,0x75,0x31,0xf8,0x35,0x46,0xc8,0xd4,0x47,0x9d,0x87,0xeb,0x40,0x95,0x19,0x24,0x7c,0x6e,0xe9,0xd5,0x14,0xaa,0xc3,0xbe,0x22,0x18,0xc1,0xa0,0x5f,0x34,0x98,0xc2,0x4d +.byte 0x3f,0xa6,0x09,0x57,0x1b,0x75,0xc6,0x89,0xee,0xf0,0xbd,0xbc,0x1a,0xd3,0xea,0x6e,0x82,0x06,0x90,0x4f,0xbb,0x61,0xac,0xbb,0x3e,0x8c,0x94,0xea,0x69,0x58,0x26,0x2e,0x17,0x78,0xad,0x14,0xa4,0x79,0x14,0xbd,0xc1,0x78,0xf9,0xbb,0x11,0x7e,0x8d,0xbf,0x3e,0xc8,0xc5,0x69,0xd7,0x5a,0x4c,0x4b,0x86,0x25,0x4c,0xe9,0x3a,0xc2,0xd9,0xf8 +.byte 0xbf,0x5e,0x46,0x4f,0xca,0xba,0x25,0x58,0x73,0x82,0x02,0x8a,0x41,0x9e,0x2d,0xa9,0x08,0xb4,0x60,0x2a,0x11,0x2c,0x2f,0x3d,0x5e,0x68,0xd8,0xa9,0x2e,0x1c,0xfa,0xdc,0xda,0xfb,0xfb,0xf3,0xb2,0x66,0xd3,0x57,0xe6,0x09,0xeb,0xe5,0xf4,0xed,0x2d,0xb7,0x3a,0xce,0x69,0x2d,0xb4,0x79,0x1a,0x99,0x9d,0xc8,0x99,0x9f,0x9b,0x78,0xd4,0x8a +.byte 0x73,0xd5,0x89,0x9f,0xda,0xdf,0xd0,0xca,0x6b,0x63,0x5a,0x1e,0xe0,0x2f,0x01,0xa4,0xd0,0x62,0xc0,0x5f,0x4e,0xd9,0xd3,0x47,0xe4,0x68,0x73,0x8c,0x87,0x50,0x91,0xec,0x8e,0x0b,0xa7,0xf0,0x4c,0x32,0x19,0xaa,0x00,0xbd,0xe4,0x20,0xab,0x5c,0x00,0xdb,0x18,0xc0,0xff,0xc1,0xc0,0x8f,0xa2,0x8c,0x47,0x91,0x86,0xde,0xa9,0x09,0xb5,0x86 +.byte 0xcc,0x1d,0x7f,0x4b,0x7d,0x16,0xf6,0x21,0xd0,0xf8,0xaa,0x16,0x20,0xa9,0xac,0x3e,0xef,0x56,0xee,0x0e,0x1d,0xd6,0x44,0x7d,0xa9,0x84,0x41,0x8d,0x69,0x69,0x92,0x74,0x87,0x3b,0x8a,0xbf,0x40,0x29,0x45,0xf9,0xa8,0x52,0x8c,0x99,0x95,0xe7,0x6a,0xcd,0x3f,0x74,0x2d,0xde,0x82,0x47,0x41,0xa6,0xd9,0x5a,0x30,0x6c,0x20,0x98,0x3f,0xfb +.byte 0x66,0x08,0x73,0x68,0xe1,0xcd,0xfd,0x3c,0x4f,0x33,0x6b,0x42,0xa4,0xab,0x78,0x22,0xb5,0xd9,0x6f,0x99,0xcb,0x85,0x6a,0x14,0xb9,0xd3,0x0f,0xfb,0xd7,0x07,0x7b,0xbe,0x6a,0xd9,0xba,0xde,0x98,0xac,0xd8,0xe5,0x40,0xcd,0x59,0x7f,0x88,0x3c,0x4e,0xfa,0xfe,0xbe,0x48,0x21,0xb5,0x40,0xd5,0xc8,0x1e,0x8a,0x56,0xd9,0xec,0x25,0xad,0x5e +.byte 0x31,0xf3,0xf2,0x3d,0x0b,0x56,0xb5,0x20,0x08,0xd3,0x02,0x81,0x93,0x29,0x3d,0xbd,0x0a,0x9c,0x26,0x74,0xdb,0x6b,0x7e,0xd1,0x4a,0x1a,0x1c,0x47,0x49,0x34,0xba,0x08,0x7a,0x6a,0xb3,0xd6,0x3b,0xd0,0x28,0x50,0xa1,0xd8,0x17,0x85,0x61,0xab,0x24,0x22,0xda,0xc8,0xb4,0x1b,0x07,0x2e,0x67,0x77,0x84,0xdc,0x6f,0xfd,0x51,0xa5,0xe8,0x34 +.byte 0x63,0xbd,0xae,0xae,0xc7,0x84,0x1d,0x60,0xc8,0x8f,0xde,0x22,0xfd,0x85,0xb4,0x12,0xb4,0x04,0x5b,0xe7,0xb5,0x58,0xf8,0x56,0x66,0xa3,0xb7,0x1e,0x54,0xd0,0xdb,0x12,0xaa,0x9c,0x89,0x5b,0xfa,0xf4,0xe7,0xe2,0xf4,0x9c,0x08,0xa8,0xbe,0x6b,0xe3,0xce,0x6a,0x88,0xb5,0x74,0xb9,0x49,0xaa,0x7b,0xcd,0xbc,0x17,0x81,0x61,0xe2,0x28,0x6f +.byte 0x4b,0xe8,0xa4,0x55,0xc5,0x1e,0x69,0x21,0x8f,0xfd,0xa8,0xd0,0xb9,0x6f,0x1b,0xfe,0x8c,0x5e,0xf9,0x7d,0xd9,0xc2,0xbe,0x0f,0x6f,0xbd,0xa7,0x94,0x10,0x4e,0xe0,0x5a,0xbb,0xa3,0x40,0x9a,0x5a,0xad,0x10,0x97,0x92,0x3b,0xbd,0xa7,0x75,0x77,0xc6,0xa6,0xde,0x42,0x00,0x3b,0xf7,0xe4,0xf4,0xd7,0xdd,0xaa,0x31,0x1e,0x64,0xae,0x17,0x0a +.byte 0x25,0xa0,0x94,0x5f,0x3c,0xbc,0x3d,0x00,0x00,0xd3,0xba,0x7b,0x98,0x81,0xe1,0xdf,0xba,0x60,0x08,0x2a,0xe5,0x66,0x08,0x3e,0xfa,0x81,0x0a,0x89,0x4e,0xe5,0x3b,0xc3,0xdf,0x21,0x9b,0x54,0xa3,0xb3,0xc3,0xc1,0xce,0xb4,0xaa,0x06,0xee,0x2e,0x34,0x55,0xcc,0x8b,0x0f,0xcd,0x1d,0x1b,0xd9,0x9e,0x59,0xf0,0x93,0xc9,0xba,0x35,0x5c,0x99 +.byte 0xf6,0x86,0x9e,0xe9,0xf8,0x84,0x80,0x05,0x76,0x6f,0x8b,0x38,0xb6,0xe0,0xdf,0x0c,0xb3,0xc7,0x6e,0x62,0x53,0xe4,0x69,0x0a,0xc1,0xcf,0x5b,0x84,0x75,0x78,0x56,0x35,0xa5,0x26,0xc6,0xae,0x76,0x2e,0xc8,0x29,0x8d,0x16,0xd1,0x4f,0x27,0x36,0x22,0x41,0x31,0xfb,0xbe,0xd0,0xf9,0x0a,0x06,0xbf,0x59,0x6e,0x06,0x20,0x0d,0x52,0x66,0x63 +.byte 0x38,0x2a,0xb6,0x15,0x0f,0x51,0x14,0x0b,0xd1,0x63,0x40,0x2a,0xfe,0x88,0x51,0x53,0x5d,0x82,0x4e,0x1b,0x91,0x30,0x7a,0x09,0xec,0xb6,0x53,0x10,0x87,0xba,0x34,0x1f,0x8a,0xf7,0x85,0x31,0x77,0x76,0xba,0x55,0x07,0x6b,0x80,0x5d,0x14,0x23,0x50,0xef,0x07,0x91,0xc5,0x71,0x3a,0x55,0x44,0x9d,0xbf,0xe6,0xab,0xde,0x7c,0xdd,0xe0,0xcb +.byte 0xcc,0xc1,0x78,0xb4,0x8c,0xd1,0x35,0x73,0x80,0x9c,0x44,0xff,0xf8,0x8a,0xaa,0x9a,0x94,0xcf,0xc9,0x51,0xfc,0xa5,0x3d,0x86,0xd6,0x67,0x71,0x1b,0xdb,0x83,0xb2,0x67,0xb0,0x17,0xce,0x13,0x1b,0x7a,0x84,0xc8,0xaf,0x69,0x7e,0xf0,0xab,0xc5,0x8c,0x37,0x12,0x43,0x33,0x5f,0xaa,0xde,0xcf,0x4c,0x73,0x7f,0x6b,0x80,0x18,0x27,0x72,0x62 +.byte 0xe8,0x3d,0x1c,0x94,0x91,0xfa,0x33,0xef,0x13,0x94,0x7f,0xb6,0x53,0xe3,0xd7,0x73,0x05,0x3e,0xe8,0x45,0xde,0x1e,0x1d,0xa4,0x41,0x11,0x0a,0x7f,0x62,0x6e,0x9f,0x9f,0xec,0xe9,0x87,0xe0,0x5d,0xbb,0xbc,0x0b,0x37,0xa2,0xf3,0x68,0x8a,0x24,0xec,0x98,0xe5,0x5d,0xbf,0xa1,0x60,0x2b,0xc2,0x74,0x4b,0x8b,0x85,0x44,0x28,0x02,0xd5,0xb9 +.byte 0xae,0x00,0x37,0x1e,0x0b,0x46,0xe6,0x40,0xf1,0xdc,0xa0,0xfc,0xae,0x04,0x7f,0xb6,0x46,0xa3,0x22,0x79,0x92,0xda,0x89,0xa0,0x38,0xf0,0xa2,0x4a,0x76,0x79,0x0c,0x46,0x4d,0xa9,0xe6,0x75,0xff,0x01,0xb3,0xe4,0x13,0xc2,0x53,0xe9,0x6d,0x1f,0xdd,0x88,0xcf,0x10,0xf5,0x16,0xef,0x05,0x59,0x51,0x15,0x49,0x17,0xda,0xff,0x0e,0xb3,0xb9 +.byte 0xae,0x79,0xc6,0xb1,0x94,0x08,0x09,0x30,0x9f,0x2a,0xfd,0x55,0xc0,0x41,0x8c,0xe5,0x0e,0xee,0xc2,0xa0,0x05,0x36,0x66,0x8d,0x9a,0xcc,0xc9,0xeb,0x1d,0x34,0xc0,0x1a,0x29,0xc2,0xcd,0xb7,0x25,0xd3,0x83,0xf8,0x1e,0xa0,0xf4,0x50,0xd4,0x08,0x0d,0xcb,0x6a,0x2f,0xa5,0x8b,0x30,0x94,0x89,0xea,0x94,0x6c,0x00,0x7e,0x7f,0xb5,0x4d,0x61 +.byte 0xa7,0x9d,0x94,0xcc,0x14,0x8f,0x75,0x1f,0xef,0x2b,0xbe,0x37,0xdd,0x19,0x41,0x2e,0x90,0x36,0x27,0xa5,0xa9,0x6c,0x75,0x8c,0x2d,0xe3,0x97,0x74,0x91,0xf3,0xb8,0xcb,0xcb,0x74,0xba,0xf0,0x57,0x70,0x89,0xee,0x4d,0xc5,0xfe,0x3e,0x60,0xe3,0x5b,0x28,0x36,0x91,0x6f,0xcd,0x6c,0x33,0xb6,0x44,0x0c,0xce,0x81,0xe4,0xdb,0x84,0xbe,0x4e +.byte 0xef,0xb8,0x75,0xf7,0x8b,0xb0,0xb7,0x0d,0x00,0x13,0x54,0x39,0xfd,0x9e,0x86,0x5c,0x59,0xd0,0x84,0x0f,0x97,0xc0,0xf8,0xfa,0x4a,0xcf,0x57,0xb8,0x24,0xf0,0xa8,0x40,0x70,0x9d,0xc4,0xe5,0xc7,0xc9,0xcb,0xb6,0xf4,0x0b,0xb5,0xcc,0xe0,0x90,0x2b,0x42,0x81,0xd6,0x59,0x2e,0x11,0xbd,0xe8,0xf5,0xef,0xa8,0x2b,0xdb,0x93,0x62,0x1e,0xef +.byte 0x3a,0x5f,0xf5,0x47,0x15,0x1f,0x03,0x6f,0x40,0x85,0xff,0x50,0x89,0x2e,0x72,0x8f,0x5c,0x0d,0x61,0x84,0x8d,0x8a,0x8f,0x2a,0x47,0x7c,0x97,0xfe,0x8a,0x97,0x6c,0xd5,0x1c,0x97,0xfa,0x59,0xbe,0x2c,0x0f,0x4d,0x85,0x7f,0x18,0xe3,0xea,0xe8,0xde,0x5a,0xf3,0x67,0xe1,0x71,0x7e,0x81,0xa3,0x74,0x0d,0xf4,0x3d,0x5a,0xec,0xc1,0xcf,0x6f +.byte 0x08,0x0f,0x5a,0x63,0x72,0x0b,0x46,0x5d,0x38,0x80,0xea,0xb7,0x12,0x5d,0xce,0x37,0x26,0xaa,0xd3,0x0d,0x93,0x4a,0x34,0x20,0xd5,0x51,0x54,0x1c,0x5e,0x53,0xa9,0xed,0x26,0x3c,0x29,0xaf,0xbe,0x73,0x34,0xa5,0xc3,0xbf,0x8c,0x8a,0xc3,0x30,0x89,0xaf,0xa9,0x2d,0x28,0x35,0x7d,0x6b,0x84,0x23,0x22,0xee,0x8c,0x82,0x04,0xbd,0x26,0x52 +.byte 0x26,0x73,0x76,0x05,0x35,0x0c,0xec,0xf7,0x54,0xb2,0x17,0x68,0xe9,0x68,0x67,0xbb,0x0d,0x98,0x19,0x32,0xa7,0xdb,0xf9,0xef,0x42,0xe7,0xc2,0xe2,0x39,0x9c,0xae,0xbb,0xdb,0x91,0x28,0x82,0x88,0x23,0x61,0x50,0x6d,0x61,0x39,0x73,0xf8,0x6a,0xee,0xf3,0xa9,0x2c,0x78,0x0d,0x5a,0xed,0xb1,0x08,0x8f,0x24,0xe5,0xb7,0xa4,0xdf,0x65,0x9a +.byte 0x72,0x3a,0x39,0x9c,0xf4,0x43,0xdc,0x8a,0xa3,0x3d,0xb5,0x1e,0x7b,0xe5,0x83,0x11,0x07,0xab,0x62,0x7e,0xac,0xab,0x52,0x94,0x0b,0xaf,0xdf,0x54,0x18,0xf1,0xc0,0x9f,0x1c,0x33,0x02,0xd9,0x62,0xc3,0xcc,0xaf,0x32,0x09,0x35,0x77,0xad,0x72,0xd6,0xb5,0x2d,0xaf,0xf9,0x39,0xfb,0x95,0xbb,0xf9,0x84,0x80,0x84,0xc8,0xc6,0x6d,0xb5,0x79 +.byte 0x25,0xf4,0x6c,0x71,0x26,0xda,0x74,0x86,0xad,0x52,0x47,0x8b,0x46,0x32,0xf6,0x2c,0x89,0xdb,0x93,0x1f,0x46,0x83,0x91,0x19,0xd2,0x0c,0x29,0x97,0x5f,0xa9,0x2b,0x87,0x0c,0x87,0x89,0xe6,0x63,0xa1,0x36,0xfb,0xfa,0xb4,0xb8,0x8e,0x5f,0xe9,0x8f,0x62,0xd2,0x81,0x1d,0x7b,0xc6,0x14,0x37,0x56,0x73,0x64,0x3d,0x0a,0xfd,0xe5,0x94,0x01 +.byte 0x09,0xc8,0x0d,0xa8,0x92,0xda,0x43,0xc4,0x41,0xca,0x3c,0x27,0x2c,0xbb,0xc4,0xb2,0x77,0x13,0xa6,0xb0,0x0e,0x97,0x6a,0xb2,0x83,0xe5,0x5e,0xa3,0xc0,0xe8,0x5e,0x0b,0xe6,0x00,0x04,0x6c,0x1b,0xac,0x84,0xab,0xd3,0xac,0x5f,0x39,0xc2,0xf8,0xfd,0x66,0xf7,0x97,0xd7,0xb9,0x6b,0xd8,0x2a,0x49,0xf7,0x67,0xd8,0xd5,0xa4,0x89,0x57,0xa6 +.byte 0x8f,0x7c,0xcf,0xaf,0xfe,0x3c,0x92,0xc8,0x23,0x2c,0x26,0x83,0x86,0x16,0x97,0x34,0x71,0x3e,0x82,0x2b,0xc7,0x75,0x5a,0x59,0xb3,0x44,0xdd,0x4e,0xd4,0x6d,0x1b,0x9f,0x3c,0x35,0xc4,0xe4,0xf2,0x95,0xb6,0x90,0x95,0xa7,0xc4,0x03,0x10,0x7d,0x3d,0xeb,0x74,0x29,0xaa,0x0c,0xd3,0x27,0xcd,0x3a,0x85,0x3c,0x88,0xd5,0x9a,0x46,0x84,0x8e +.byte 0x36,0xde,0xe3,0x6a,0x27,0xbf,0xc3,0xd0,0x3e,0xa3,0x0e,0x62,0x1f,0xdf,0x4c,0x02,0xa7,0x11,0x91,0xb0,0x6b,0x50,0xc1,0xe0,0x18,0x5a,0xc0,0x10,0xc7,0x1c,0xb6,0x36,0xac,0xe7,0x7d,0xad,0x34,0x63,0x4f,0x17,0xcc,0x41,0x30,0xec,0xd7,0x14,0xb9,0xfe,0x07,0x5c,0x3d,0xbe,0x08,0x77,0x5b,0xdf,0xa3,0x20,0x56,0x55,0xa2,0x8a,0xe7,0x0d +.byte 0xf6,0xfc,0x91,0x37,0xb8,0x92,0x6c,0xd9,0x5c,0xb0,0xc2,0xf7,0xc0,0x38,0xfa,0x54,0xc6,0xa1,0xd3,0x4d,0xae,0x49,0x0d,0xd1,0xc0,0xef,0xbe,0x27,0xce,0x23,0x8e,0xf2,0x9b,0x68,0x02,0x67,0x8f,0x53,0x9d,0xf6,0x23,0x57,0x85,0xdd,0x8d,0xd7,0xcb,0x47,0xf1,0xd8,0x17,0xd8,0x46,0x72,0x28,0x4b,0xac,0x94,0xd3,0x5d,0x53,0x4f,0x06,0x19 +.byte 0xc6,0x0e,0x0b,0x9f,0x58,0xc6,0x3f,0xea,0x4e,0x83,0x5e,0xd3,0xcc,0x44,0x55,0xa3,0xc7,0x24,0x19,0xea,0x1b,0x18,0xc1,0x18,0x5f,0x21,0x67,0x73,0x32,0x4e,0x31,0x69,0x05,0x40,0x79,0x7c,0x05,0x13,0xdd,0x50,0xea,0xfa,0xc2,0x26,0xe2,0x33,0xff,0x34,0x0d,0xda,0x77,0x27,0xe0,0xe7,0xa6,0x7b,0x8e,0xcd,0xdb,0x92,0x48,0x3a,0x2d,0x52 +.byte 0xf5,0x59,0xca,0xc7,0x47,0xda,0xb7,0xc7,0x8c,0x37,0x5e,0x29,0x30,0xf5,0x57,0x74,0x8b,0x10,0xcb,0x20,0x31,0x4b,0x12,0xe3,0x84,0xd2,0xb2,0xc3,0xd0,0xe3,0x94,0x18,0xa2,0xdc,0x8f,0x4d,0xc3,0x0a,0x43,0x07,0x2c,0x6b,0x41,0x64,0xc0,0x35,0x8f,0x37,0x9b,0xd7,0x78,0xab,0xd0,0xdc,0x1f,0x77,0x55,0xab,0x71,0xc8,0x99,0x98,0x00,0x29 +.byte 0x1c,0xab,0x3c,0x5f,0x82,0x96,0xc2,0xc8,0x9b,0xd4,0x68,0x3f,0x3d,0xe6,0x5a,0x4c,0x1c,0x7b,0x51,0xa3,0x79,0xe8,0x0e,0x8a,0x78,0xdc,0x98,0x63,0x80,0x74,0x32,0x9d,0x7c,0x3a,0x79,0x54,0xa7,0x4c,0xa4,0x4e,0xfc,0xa5,0x8a,0xa4,0x19,0xce,0x84,0xbb,0x8a,0xb9,0x93,0x4a,0x2d,0x82,0x5d,0x1d,0xf8,0x2f,0x85,0xb3,0x90,0x32,0x61,0x6d +.byte 0x13,0x33,0xac,0xbc,0x5d,0x3a,0x54,0x45,0x04,0x50,0x30,0x30,0xc7,0x58,0xbe,0xed,0xdd,0xa1,0xae,0x6d,0xe5,0xde,0xed,0x63,0x9f,0xd4,0x2b,0x8d,0x1f,0x69,0xde,0xda,0x55,0x3f,0x3b,0xe7,0xc8,0x73,0xc0,0x68,0x18,0x6a,0xb3,0xfb,0xce,0xaf,0x46,0x0a,0xcc,0x81,0xa8,0x96,0x6d,0xb6,0xa4,0x74,0xf3,0x8c,0x95,0x2d,0xa1,0xfe,0x09,0xb8 +.byte 0xdb,0x3c,0xcd,0xdc,0x5b,0x0e,0x2d,0xff,0x89,0x8a,0xfd,0x7a,0xe9,0x69,0x0b,0xdd,0x4e,0x9b,0x94,0x64,0xe4,0xb6,0x5d,0x69,0xef,0x9c,0xf6,0xe6,0x44,0x73,0xd5,0x86,0x47,0x63,0x77,0x3e,0x74,0xaa,0xf3,0x6b,0x1f,0x37,0xbf,0xef,0xa2,0xff,0x86,0x61,0x78,0xc4,0xb5,0xbd,0x5a,0x43,0x49,0x80,0x16,0xf2,0x4c,0xec,0x1e,0x07,0x0f,0x41 +.byte 0x60,0x6f,0x3a,0xd2,0xab,0x85,0xc0,0x5c,0xfc,0x9f,0x48,0xad,0x5e,0xe0,0x7d,0x66,0x8e,0x46,0xf1,0xc3,0xb0,0xbc,0x5e,0x3b,0x10,0x7c,0xfc,0xa3,0x27,0xbd,0x8f,0xae,0xd9,0x61,0x39,0xbf,0xca,0x27,0xbb,0xe7,0xda,0x59,0xa8,0x63,0x38,0x16,0xd9,0xb5,0xa6,0xd9,0x1c,0x2b,0xa1,0x42,0xec,0x50,0xd7,0x63,0x09,0x22,0xe0,0x0c,0xb8,0xec +.byte 0x12,0x9b,0xdb,0x8a,0xd3,0x02,0xcf,0x32,0xa9,0x88,0xa4,0x31,0xc8,0xa9,0xf4,0x03,0xf2,0x9d,0xe1,0x41,0xf0,0x0f,0x23,0x65,0xa8,0x99,0x55,0x87,0xf2,0x17,0x66,0xf0,0x94,0xe8,0xe9,0xb6,0xfd,0x10,0xb9,0x55,0xf4,0xda,0x06,0x7a,0xbe,0xe2,0xd3,0xfa,0xb8,0xf7,0x85,0xdf,0xee,0x39,0xdc,0x0f,0xda,0x87,0xf5,0x66,0xd8,0x1b,0x5c,0x0c +.byte 0x13,0xe8,0xa2,0xcd,0xdf,0x47,0x33,0xd7,0xf4,0x5c,0x79,0xc7,0xf4,0x68,0xe4,0x2d,0xa1,0xde,0x5c,0x06,0x1c,0x85,0xf1,0x2a,0xf9,0x73,0x44,0xbc,0xd3,0x57,0x4f,0x0f,0xcd,0xcc,0x40,0xeb,0x9d,0x35,0x8e,0xdf,0x1d,0x4a,0x61,0xd0,0x66,0xb5,0x16,0xce,0x45,0xc0,0xbf,0x01,0xe3,0xb2,0x51,0xba,0x53,0x18,0x2a,0xff,0x19,0xea,0x41,0xa2 +.byte 0xac,0x0b,0x50,0xd3,0xc1,0x6a,0x9c,0xb0,0x34,0x6f,0xa0,0xcb,0xc7,0xc6,0x79,0x5d,0x17,0x3a,0x4c,0xa3,0x16,0xdc,0xac,0x10,0xf0,0x24,0xad,0x9a,0x5b,0xa9,0x7e,0x45,0xcd,0xe9,0xad,0x87,0x04,0xbc,0x2a,0x05,0x59,0xd1,0xdb,0x86,0x22,0x40,0xdf,0xb1,0xff,0x8d,0x3c,0xf8,0x6a,0xf3,0xcb,0x60,0xf9,0x35,0xa6,0x42,0x81,0xcb,0x0f,0x7c +.byte 0xf7,0x24,0x3b,0x0c,0x94,0x32,0xd9,0xec,0xcf,0xd1,0x31,0x3e,0x3e,0xeb,0xa9,0xf2,0x1f,0x2d,0xa7,0x89,0xf7,0x67,0x7d,0x90,0x9d,0x40,0xf2,0xdb,0x07,0x8f,0xb8,0x6f,0xfd,0x78,0x6e,0xd0,0x9e,0xd5,0x7d,0xb0,0x7d,0x65,0xdc,0x6e,0x50,0xec,0x7a,0x5c,0x2c,0x3e,0x6f,0x64,0xa3,0x10,0x34,0xf7,0x71,0xc8,0x82,0xb6,0x96,0xb8,0xb1,0x2a +.byte 0xb4,0x03,0x95,0x75,0x90,0xac,0x6c,0x81,0x17,0x97,0x06,0xd0,0xb8,0xc5,0x98,0xc5,0x9e,0x46,0x07,0x13,0x02,0x9e,0x47,0x69,0xba,0x85,0x2d,0x09,0x86,0x50,0xe4,0x76,0xb1,0xa2,0xbe,0x8b,0x91,0x6b,0x3b,0x76,0xa3,0xb7,0xf5,0x7f,0xfe,0xf1,0xa4,0xf3,0xc3,0x53,0x64,0xef,0x97,0x86,0x96,0x8b,0xc4,0xae,0x06,0x8b,0xe8,0x3c,0xdc,0xff +.byte 0xfa,0xad,0xcb,0xcb,0x53,0x15,0xf2,0xcc,0x9f,0x48,0xf9,0x57,0x6a,0xcd,0xb2,0xee,0x46,0xc0,0xbf,0x82,0x58,0x60,0xda,0x2f,0xbd,0xde,0xc7,0x41,0xcb,0xf1,0x38,0x56,0x9d,0x38,0x38,0x3d,0xea,0x5e,0x38,0xf1,0xd0,0x02,0x35,0xee,0x4c,0x2f,0x1d,0x19,0xbd,0x08,0x01,0xc3,0x8f,0x75,0xe2,0xf3,0x93,0xbb,0x76,0x6b,0xd7,0x87,0x76,0x7f +.byte 0x3b,0x29,0x08,0x9f,0x3a,0xa5,0x44,0x96,0x5a,0xb3,0x78,0xa9,0xbe,0xf7,0x5d,0xda,0x06,0x37,0x98,0x5d,0xbe,0x6e,0xec,0x58,0x53,0xd1,0xa5,0xd7,0x7a,0x16,0xb1,0x59,0x98,0x42,0x37,0x76,0x1b,0xd6,0x2e,0xa7,0xdc,0x45,0xa6,0x9c,0x9c,0x99,0x24,0x0e,0x22,0xae,0x94,0x65,0xeb,0x4e,0x64,0xc3,0xb0,0xac,0x19,0x41,0xf1,0x62,0x65,0xb2 +.byte 0x35,0xf5,0x2f,0xdb,0xd2,0xf0,0x78,0x19,0x35,0x04,0x6f,0x9c,0xf4,0xaf,0x81,0x68,0x4f,0x8b,0x85,0xfa,0x31,0x23,0x06,0xeb,0x37,0x86,0x43,0x51,0xb3,0xd2,0x2a,0xd7,0xd5,0xa9,0x33,0xba,0xfd,0xb5,0x0e,0x6d,0x9a,0x91,0xf9,0xe7,0x27,0xb7,0xff,0xe6,0xe7,0x34,0xc5,0x1a,0xa3,0x45,0x3b,0x71,0x34,0x87,0x7e,0xe7,0xab,0x74,0xc5,0xff +.byte 0xeb,0x23,0x8f,0x3f,0x5d,0x1c,0x91,0x47,0xeb,0x3e,0x5f,0x5a,0xa6,0x5a,0xde,0xa9,0x5f,0xf4,0x8f,0x95,0xc6,0x25,0x3c,0xd5,0xaf,0xfd,0x4d,0x33,0x68,0xe1,0xa3,0x51,0x1b,0x07,0xad,0xb9,0xec,0xf1,0x50,0x51,0xbf,0xeb,0xe8,0x58,0x2a,0x50,0x0e,0x9d,0xc2,0x8a,0x83,0x8c,0xb0,0xb8,0xde,0x1d,0x7b,0x0f,0xff,0xfc,0xfc,0x31,0xe5,0x62 +.byte 0x40,0xc8,0x28,0x30,0x31,0xc9,0x82,0xab,0xbe,0x50,0xe5,0xfe,0x1f,0x49,0x17,0xf9,0xea,0x23,0xc7,0x6d,0x8d,0x63,0xc3,0x70,0x40,0x32,0x0b,0x48,0x7a,0xd9,0x03,0x52,0x1b,0xf4,0x90,0xd6,0x6d,0xd2,0xfc,0xec,0x24,0x7f,0x21,0x2e,0xd4,0xb5,0x60,0x44,0xd9,0x83,0xb0,0x3e,0x75,0x8a,0x6a,0x09,0xab,0xa8,0x4f,0x48,0x3c,0x2b,0x89,0x30 +.byte 0x29,0xdb,0x1a,0x8e,0x68,0xe4,0x89,0xed,0x10,0xe8,0x46,0xa7,0xf9,0x5f,0x7d,0x42,0xe0,0x8d,0xbc,0x3d,0x4d,0xd8,0x06,0x4a,0xf9,0xbb,0x97,0xa7,0xdb,0x24,0x0b,0xfc,0x49,0x92,0x5d,0x80,0xf8,0xed,0x57,0xc7,0x1e,0x82,0xed,0x41,0xb8,0xfd,0x71,0xb9,0xa5,0x11,0x52,0xdd,0x1e,0xa4,0xf1,0x02,0xc7,0x54,0x7c,0xdc,0x37,0x9f,0xfe,0x37 +.byte 0xe8,0xa5,0xcf,0xb0,0x3d,0x25,0x3f,0x24,0xfe,0xf2,0x63,0x97,0x3c,0x13,0xdc,0x31,0x78,0x07,0xf1,0x8e,0xee,0xc6,0x00,0xf8,0xfd,0x84,0x53,0x4d,0x92,0xa1,0xef,0xd0,0xb1,0x12,0x0a,0x12,0x91,0xeb,0x52,0xdd,0x6e,0x15,0x98,0xd2,0xe1,0x53,0x7a,0x0e,0x02,0x83,0xd3,0xd1,0xde,0x72,0x6e,0x5b,0x4b,0x8d,0x40,0xe3,0x2d,0x22,0x59,0x9d +.byte 0xee,0xbe,0x43,0x18,0x62,0x8c,0x77,0x18,0x91,0xf5,0x9e,0xbc,0x3e,0x8b,0x77,0xb6,0xdb,0x5c,0xcb,0xcd,0xdb,0x36,0xea,0xf5,0x1d,0x9b,0xa7,0x13,0xef,0xda,0xd0,0xe8,0xd8,0xb2,0x4c,0xc6,0x19,0x3d,0x77,0x2d,0x0d,0xad,0xe4,0x32,0x24,0xe9,0xd4,0x7f,0x72,0x1d,0xc6,0x6e,0x83,0x7d,0xb8,0x62,0x64,0x9d,0x9a,0xd7,0x13,0x93,0x92,0xf1 +.byte 0x37,0x98,0xcf,0x44,0x66,0xab,0xd1,0x61,0x6c,0x08,0xa7,0x41,0x4e,0x37,0xc1,0x67,0xfb,0x7c,0x22,0x8f,0xbd,0x93,0xb2,0x09,0x13,0xa0,0x48,0x60,0xaf,0xda,0x73,0x2b,0xa3,0x2a,0xf3,0x4d,0x8e,0x22,0x5b,0x7a,0x32,0xe6,0xca,0xff,0x0e,0xa1,0x0a,0x15,0x33,0x31,0x50,0x71,0x1c,0x85,0x26,0x9b,0x19,0xf2,0xe3,0x69,0x4e,0x2d,0xff,0x79 +.byte 0x80,0xfe,0x2c,0x2f,0x7a,0x49,0x95,0xf3,0x0e,0x78,0xb1,0x0c,0x1c,0x45,0x59,0x68,0x2a,0x37,0xf2,0x48,0x6f,0xd9,0x32,0xf7,0xfc,0xdc,0xbe,0xe3,0xdd,0x61,0x17,0xc0,0x08,0x9d,0xbc,0x2d,0x8d,0x24,0x1c,0xbb,0x53,0xbe,0x37,0x59,0x30,0x87,0xa0,0x14,0xf5,0x08,0xcf,0xd1,0xcc,0x84,0xa7,0x0f,0x69,0xe0,0x77,0x8c,0x0d,0xdc,0x82,0xe5 +.byte 0x88,0x9a,0x58,0x05,0xe3,0x4f,0xdd,0x55,0x1e,0x6e,0x90,0xd5,0x3c,0xa6,0xa6,0x10,0x24,0xe5,0x58,0x97,0xdc,0x31,0x87,0x39,0xdc,0x3a,0xe6,0x24,0x64,0x23,0x45,0xd8,0x01,0x1b,0xf6,0x38,0x68,0x9e,0x62,0x53,0x00,0x97,0x71,0x04,0xb5,0x3b,0x54,0xdb,0xb5,0xcb,0x30,0x91,0x14,0xce,0x94,0xd5,0xe0,0x96,0x70,0x99,0xa5,0xed,0x69,0x32 +.byte 0xc7,0xb7,0x14,0xff,0xc0,0xde,0x19,0x5d,0x31,0xdb,0xa7,0xc0,0x7a,0x94,0xec,0x60,0xfc,0x52,0x71,0x69,0x9b,0xd8,0xbe,0x97,0x0b,0xb5,0x70,0xa7,0x47,0x11,0x37,0x84,0xda,0x3c,0x23,0xfe,0xf2,0x53,0xad,0x55,0x71,0x1e,0x70,0x9b,0x7b,0x61,0x97,0xf8,0x71,0xc4,0xad,0x72,0x98,0x43,0x0c,0x33,0x30,0x2c,0xb2,0xd6,0x21,0x8d,0xbb,0x1b +.byte 0x85,0x82,0x24,0x14,0x85,0x95,0x88,0xff,0x3f,0x8c,0x88,0x96,0xa0,0xf8,0xd7,0x36,0x78,0x37,0x6d,0x92,0x09,0x04,0x76,0x27,0xb9,0xd5,0xea,0x0f,0x07,0x9f,0xe1,0x49,0x0e,0xd1,0x9c,0x46,0xcd,0x2b,0x7a,0x57,0xb6,0x56,0x39,0xe5,0x59,0x6b,0x1b,0x39,0xbf,0x15,0x3b,0x56,0xf5,0xc2,0x08,0x96,0xf5,0x63,0x4c,0x31,0x33,0x65,0x8b,0x74 +.byte 0x4e,0xde,0xa8,0x20,0xe0,0x7c,0x27,0xee,0x91,0x74,0xe8,0x24,0xb3,0xcf,0xa3,0xd4,0xf1,0xb9,0x18,0x43,0x05,0x5d,0x13,0x36,0x82,0xd1,0xbf,0x16,0x89,0x48,0x83,0xf0,0xcc,0x5c,0xbb,0x75,0x7e,0x71,0xc0,0x73,0xd1,0xf5,0x00,0x38,0x7f,0x10,0x98,0xd6,0xb9,0x14,0xea,0xd3,0x3f,0x0f,0xe3,0x61,0x1a,0x5e,0x21,0xd0,0x11,0x58,0x68,0x47 +.byte 0xf2,0xe5,0xe9,0x65,0x9a,0xc1,0xf4,0xa0,0x98,0x8e,0x9f,0x7f,0xbe,0x7e,0xd0,0xb6,0x88,0x4e,0xce,0xc1,0x8b,0xd4,0xd3,0x93,0xb7,0xd8,0xf3,0x0b,0xf3,0x73,0xc9,0x08,0x2f,0xcf,0xd8,0xbd,0xa6,0x1d,0x7c,0xfa,0x44,0x82,0x9f,0x03,0xca,0x56,0x3b,0xbf,0x4d,0x1e,0xbc,0x06,0xc2,0x37,0xfb,0xde,0xd3,0xa9,0xe3,0xae,0x61,0xef,0x26,0x7d +.byte 0xbd,0x2f,0xee,0x2d,0xe1,0x65,0x71,0x77,0xab,0x9c,0x96,0x4f,0x00,0xe2,0xde,0xd7,0x05,0x54,0x00,0xb6,0xaf,0x12,0x0c,0x79,0x1a,0xed,0x20,0x72,0xc7,0x3b,0x3a,0x10,0x15,0x74,0xff,0xbd,0xf8,0xaa,0x8f,0x3a,0x83,0x39,0x24,0xfa,0x53,0x2d,0xc3,0x61,0xfc,0x12,0x6b,0x54,0x33,0xbf,0x83,0xc9,0x59,0x00,0xf0,0xdc,0xa8,0x64,0xbc,0xb5 +.byte 0xc3,0x96,0x60,0x3e,0x7b,0xe2,0x08,0x19,0x92,0x17,0x80,0x9b,0x0c,0x09,0x49,0x68,0x8b,0x15,0xe3,0xce,0x0c,0xfa,0x0c,0x8b,0xf0,0xdc,0x58,0xb0,0x7b,0x82,0x85,0xd2,0x56,0x1c,0xfb,0xb5,0xd0,0x0e,0x0a,0x55,0x61,0xda,0xd8,0x20,0xc1,0x79,0x70,0x3c,0x69,0x8e,0x49,0x5f,0x1c,0xdb,0x22,0xb8,0xdd,0x4c,0x4f,0xca,0xe9,0x0f,0x9a,0x4e +.byte 0xff,0x56,0xbc,0xcf,0x72,0x09,0xa6,0x41,0x38,0xf0,0x7d,0xe7,0x45,0x0a,0x71,0x2c,0x92,0xdd,0x21,0x17,0xb2,0x3b,0x31,0x3c,0x91,0x11,0x69,0x29,0x50,0x31,0xe6,0xa6,0x10,0xc7,0x35,0xe8,0x44,0xec,0x74,0xa3,0x7e,0xb6,0x34,0xe5,0xb7,0xba,0xdf,0x5b,0x2f,0x85,0x02,0x6c,0xb0,0x71,0xb1,0x43,0xff,0x0e,0x47,0x04,0x63,0x4d,0x5b,0x81 +.byte 0x81,0x28,0x8b,0x84,0x79,0xad,0x2a,0x45,0x00,0x1c,0x0c,0x9f,0xef,0x35,0xbb,0x6d,0xc5,0x6a,0x6b,0xef,0x2b,0xae,0x78,0x66,0x05,0x7a,0x61,0x4c,0xe9,0x5e,0xf7,0x95,0x66,0x7e,0x1a,0xa7,0xdf,0x4c,0x4d,0x7c,0x66,0xa5,0x38,0x84,0x86,0x8d,0x66,0xcc,0x7f,0x32,0xb2,0x9c,0xc5,0x0d,0x3d,0xb7,0xb1,0xa6,0xc5,0x80,0x68,0xaf,0x79,0x81 +.byte 0x15,0x8f,0xec,0x50,0x5c,0x1b,0x57,0x31,0xd2,0xb9,0x16,0x66,0xf8,0x16,0xfd,0xcd,0xc7,0xa8,0x84,0x6f,0x35,0xea,0x3f,0xa4,0x72,0x8d,0xad,0xf4,0xd1,0x14,0x46,0xcc,0x06,0xed,0x71,0x39,0x07,0x99,0x28,0xc8,0xf9,0xc4,0xc2,0xec,0xde,0xb8,0x92,0xae,0xc5,0xf8,0xb2,0x49,0xc9,0x32,0x58,0xec,0x9f,0xb0,0x59,0xaf,0x49,0xef,0xe8,0x0d +.byte 0x4c,0x56,0x8d,0xf7,0x57,0xb0,0x09,0xbe,0xc2,0x6a,0x62,0xc4,0x87,0xf3,0x20,0x07,0xc9,0xe3,0x3b,0x31,0xcc,0x8d,0xcf,0x5d,0x18,0x00,0x2a,0x9f,0xde,0x80,0x1a,0x7e,0x95,0x93,0xd1,0xbd,0xe6,0xd4,0x69,0x37,0x96,0xbb,0x70,0xc5,0x3c,0x87,0x8f,0xff,0x95,0x97,0xfe,0x95,0x56,0x7b,0xba,0x03,0x3d,0x29,0x0f,0xdb,0xd0,0x65,0x4f,0xf8 +.byte 0xa8,0xf3,0x42,0x09,0xb5,0x81,0x34,0xc6,0xa9,0x60,0xb9,0xef,0x3e,0x9d,0xc5,0x42,0x1e,0x79,0x5d,0x2b,0xf2,0x46,0x0d,0xeb,0x88,0x84,0x8f,0xad,0x60,0x69,0x57,0x49,0x33,0xb4,0xdd,0xfe,0x10,0x65,0x65,0x51,0xaf,0x68,0xa0,0xce,0xbd,0xe1,0x6e,0x03,0xe1,0x5f,0xba,0x3f,0x36,0xca,0xed,0x20,0x95,0xfa,0xff,0x3c,0x65,0xa8,0xb1,0x6b +.byte 0xc5,0x91,0xa0,0xd5,0x36,0x38,0x1c,0x38,0xe9,0x1d,0x1b,0x67,0x4c,0x17,0xd3,0x29,0x92,0xa2,0x27,0x76,0x3d,0xe2,0x26,0x37,0x2a,0x2c,0xf6,0xee,0x64,0x40,0x8a,0x1c,0x2b,0xc1,0xd3,0x28,0xd0,0xcf,0x2d,0xc2,0x45,0xf4,0x37,0x5a,0x63,0xfb,0x18,0x67,0x01,0x0a,0xe8,0xe2,0x41,0xf7,0x15,0x47,0xa7,0xe9,0xc8,0x05,0xbc,0xc7,0x8f,0xf0 +.byte 0xc3,0xc5,0x9a,0x4e,0x0d,0x7b,0xf0,0x20,0x8c,0x21,0x49,0x99,0x0d,0xf7,0x34,0x84,0x35,0xfb,0x11,0x33,0xd6,0x46,0x14,0x3c,0xf1,0xb3,0x37,0xac,0x75,0x63,0xe7,0x1a,0x19,0xa4,0x49,0xf2,0x58,0x1d,0x56,0x55,0x64,0x46,0x25,0xff,0x7d,0x90,0x34,0x21,0x5d,0x00,0xa1,0xa8,0xaa,0xe0,0x93,0xe7,0xda,0x11,0x34,0x1d,0xa3,0x0c,0x67,0xae +.byte 0xf5,0x60,0x72,0x14,0xdf,0x08,0xf6,0x72,0x3e,0x48,0x41,0x3d,0x00,0x58,0xfb,0x0c,0x15,0x80,0x2d,0xd9,0x72,0x47,0xa6,0x20,0x6a,0x74,0x9e,0x06,0xb9,0xac,0x68,0x3a,0xe7,0xf1,0x19,0xb8,0x0b,0x66,0x07,0x4d,0xa0,0xb5,0xab,0xea,0x70,0xa1,0xdf,0x41,0x76,0x85,0x18,0x5b,0x6f,0x78,0x5a,0x5d,0x08,0xe0,0x1b,0xd8,0x06,0x73,0x1e,0x16 +.byte 0xcb,0xdb,0x02,0xf8,0x96,0x64,0x65,0xc5,0xc1,0x52,0xd4,0xd8,0xb3,0x1e,0xd4,0x09,0xfd,0xa7,0x30,0x41,0x5a,0xce,0x53,0x4d,0x11,0xc8,0xdd,0x13,0x50,0xd5,0x2e,0xa0,0xe6,0x48,0x49,0x31,0x4b,0x1d,0xce,0xfc,0x42,0xed,0x8f,0xc8,0xb3,0x0a,0xae,0x1d,0x4c,0x1e,0x4f,0x39,0xa4,0x37,0xc8,0x54,0xdf,0x40,0xa6,0x42,0x61,0x7d,0x34,0xd4 +.byte 0x75,0x0a,0x9f,0xf0,0x33,0x54,0xf3,0xc4,0xdc,0x4e,0x2f,0x81,0xc2,0x20,0xaa,0x4f,0xa0,0xae,0xa6,0xb8,0x50,0xf8,0x45,0xf1,0xf2,0xd1,0xd2,0xcf,0xc8,0xf0,0xf4,0x54,0x37,0xdc,0xfb,0x13,0xdf,0x38,0xc2,0x3f,0xe0,0x59,0xb5,0x9a,0x0f,0x27,0x87,0xd4,0xd3,0xdc,0xfd,0xda,0x1d,0xfa,0xdd,0x12,0xe0,0x7f,0x34,0x01,0xde,0x28,0xf5,0x0e +.byte 0xff,0x59,0xc7,0xbd,0x6a,0xe4,0x0c,0x85,0x7b,0x87,0xf9,0xd7,0xe2,0xed,0xb2,0xf7,0xb7,0x13,0xfb,0xfc,0x4d,0x25,0x52,0xfd,0x23,0x6b,0x10,0xd0,0x80,0xd8,0xbd,0xbd,0xf0,0x87,0xfc,0x38,0x85,0x83,0x20,0x5f,0x7c,0x26,0x14,0x93,0xd3,0xe1,0xdc,0xa4,0xda,0xa7,0xf9,0xfd,0x6c,0x9a,0x2b,0x75,0x82,0xf1,0x9f,0x1b,0x0c,0x43,0xd4,0x2d +.byte 0x5b,0x0c,0x54,0x7e,0x61,0x24,0x8e,0x50,0x25,0xd8,0x54,0xfd,0x30,0xec,0x4c,0xa8,0xb6,0xf0,0x35,0x67,0xf7,0xe4,0x3c,0xfd,0xc8,0x40,0xf4,0x2d,0xc5,0x4d,0xc3,0x29,0xc2,0x88,0x60,0xab,0xd9,0x2a,0xe8,0x31,0xcc,0x0c,0x9f,0x97,0xa8,0x2e,0xaa,0xa5,0xb6,0xee,0x3c,0x71,0xa9,0xff,0x90,0xb4,0x43,0x2e,0x16,0x80,0x8c,0xfe,0xb5,0x7a +.byte 0x40,0x58,0xd5,0x98,0x7e,0xca,0xaf,0x95,0xee,0x00,0x26,0x8d,0x5b,0xba,0x33,0xee,0x35,0xb5,0x9b,0xf8,0x08,0x1e,0x15,0x2d,0x01,0xb1,0x83,0xa6,0x57,0x58,0xd1,0xf3,0xa4,0xf1,0x3a,0x00,0xf4,0x40,0xee,0x35,0x3a,0x20,0xc2,0x13,0x1e,0xda,0x32,0xc2,0x35,0x74,0x29,0xce,0x51,0x3f,0xec,0xb2,0xd7,0x23,0xa7,0xc6,0xef,0x70,0xb9,0x88 +.byte 0x6f,0xa8,0xf5,0x5b,0xff,0xc5,0xf5,0xb4,0x3b,0x12,0x75,0x20,0xbf,0x61,0x8a,0xb1,0xae,0x01,0x9b,0x17,0xf4,0xf3,0x2d,0xfb,0x44,0xe8,0xac,0x29,0x81,0xc2,0x6d,0x50,0x05,0x11,0xd9,0x43,0xf8,0xc7,0x58,0x5d,0xbc,0x2d,0xc0,0x83,0xd2,0x81,0x41,0x1c,0x46,0x62,0x60,0x6e,0x65,0x52,0x4b,0x1c,0x88,0x72,0x1b,0x0e,0x8e,0x7d,0xa2,0xb5 +.byte 0x4e,0x28,0x32,0xf2,0xb1,0xfa,0xf1,0x4b,0xc5,0x85,0x95,0x2c,0x08,0x78,0x85,0x68,0xe5,0x20,0x23,0x8b,0xc4,0xf5,0xb2,0xdb,0xc1,0xdd,0xe5,0x69,0xa4,0x97,0xa9,0x6c,0x2e,0x3a,0x25,0x1c,0x24,0x54,0x97,0x3e,0x8d,0x61,0x61,0xa3,0x60,0xf5,0xd2,0x4e,0x90,0x25,0x06,0x09,0x31,0x7b,0x96,0xce,0xcc,0xb7,0xbc,0x63,0x9f,0x04,0x7d,0xec +.byte 0xa1,0x4a,0x65,0xd3,0x26,0xe1,0xbf,0xf9,0x88,0xea,0x5c,0x5d,0xfe,0xe9,0x60,0x77,0xbd,0xf2,0xa0,0x11,0x91,0x24,0xca,0xa1,0x0d,0x05,0x7b,0xe2,0x7d,0x22,0x2e,0xd2,0xc9,0x4b,0x78,0xce,0x0c,0x7b,0x49,0xaf,0xd6,0x59,0x5f,0xb4,0xbd,0x2e,0x4a,0x22,0xcb,0x5d,0x1c,0xd5,0xde,0xea,0x86,0x74,0xd5,0x15,0x52,0x59,0xfc,0x3d,0x7b,0x1c +.byte 0x3f,0x14,0xec,0xf2,0xc8,0x3c,0x88,0xbf,0x89,0xd5,0x23,0xc3,0x94,0x3c,0x28,0x04,0x91,0x6c,0x36,0x35,0x4b,0x75,0xf8,0xdc,0xf3,0xff,0xba,0x8c,0xa4,0xc7,0x85,0xc5,0x1a,0x30,0x4b,0x7c,0xc5,0x2f,0xb9,0x2a,0x14,0xaa,0x65,0xe3,0x92,0xdc,0xe1,0xed,0x3f,0xb6,0xff,0x0e,0x74,0xe0,0xb3,0xc9,0x4b,0xd1,0x96,0xfc,0x49,0x72,0xbe,0xb0 +.byte 0xc8,0x4a,0xd5,0xf0,0xb3,0x58,0x29,0x35,0x97,0xd4,0x5c,0xc7,0x0b,0x27,0x1d,0x14,0xdb,0xb7,0x5c,0x7e,0x6d,0xc1,0x56,0xa9,0x80,0x72,0x7d,0x75,0xc2,0x2f,0x07,0x28,0xb4,0xff,0xef,0xa7,0x34,0xed,0x31,0x44,0x85,0xe6,0xc3,0xa4,0x5f,0xe2,0xe8,0xab,0xd1,0x59,0xe7,0x32,0x20,0xd1,0xcc,0xef,0x6f,0xe1,0x10,0x89,0x6c,0x0c,0xf3,0x5f +.byte 0xe8,0xc7,0x1c,0x3b,0xeb,0x3e,0xa5,0x53,0x2d,0x48,0x64,0x92,0xa0,0xec,0xf3,0x75,0x5b,0x5b,0xe2,0x83,0x87,0x04,0xa7,0xd8,0x1b,0x44,0xfb,0x42,0xee,0xd8,0xf2,0x98,0xff,0x30,0xc8,0x09,0xf8,0x1a,0x95,0x46,0x2d,0xe7,0x43,0x10,0x90,0xf4,0x2c,0x8f,0x0b,0x60,0x6d,0xeb,0xbf,0x19,0xc1,0x9d,0x5c,0xc0,0xff,0xb1,0x86,0xbc,0x01,0x73 +.byte 0x35,0x1f,0xd8,0xf4,0xa1,0xd4,0x7f,0x2d,0x1b,0xf9,0xa6,0x78,0x1a,0x2e,0x2c,0xe2,0xcc,0x8b,0x5f,0xbb,0xb9,0x80,0x31,0x32,0xa5,0x5d,0x70,0x59,0xae,0xe3,0xac,0xab,0xde,0x38,0x09,0x07,0x57,0x5f,0xbf,0xe8,0xa0,0xb8,0xd0,0x03,0xac,0x02,0x0d,0x7f,0x7e,0x0c,0xd2,0xcf,0x46,0x01,0x07,0x9f,0x16,0xf6,0x2b,0x94,0xaf,0xae,0x66,0x09 +.byte 0xca,0x4c,0x5f,0x37,0x53,0xa6,0x50,0x82,0x3a,0x0a,0x7b,0xb3,0x52,0x2e,0x0f,0xe4,0x64,0xab,0x40,0x21,0x2d,0xb7,0x20,0x9b,0xe3,0x2f,0xec,0x2b,0xb3,0x31,0x60,0x51,0x2e,0xb6,0x68,0xac,0xae,0xee,0x2d,0x28,0x5b,0xe0,0xa7,0x85,0xab,0x95,0xba,0x53,0x8c,0xc0,0xf8,0x16,0x8f,0x42,0x01,0xef,0x00,0x32,0x44,0x8e,0x41,0xc9,0x05,0x5b +.byte 0xe0,0x3f,0xe1,0xd8,0xd4,0x97,0x8e,0xa0,0x14,0x84,0xce,0x5c,0xef,0xbe,0xa4,0xae,0x18,0x91,0xd9,0x48,0x9b,0xc3,0x7a,0x8f,0xfb,0xb3,0x3e,0xa9,0x87,0x74,0x84,0xd2,0xc6,0x7c,0xc9,0xce,0x01,0xa5,0xcc,0xff,0x5a,0xe8,0x94,0x98,0x54,0x2a,0x6e,0xd9,0x58,0x75,0xd4,0xdd,0x6c,0x7d,0x83,0x32,0xc9,0x4e,0x35,0x2c,0x51,0x26,0x68,0x1f +.byte 0x95,0x20,0x82,0x54,0x0a,0xad,0x5e,0xe2,0xba,0xf9,0xa3,0x54,0x24,0x93,0x4a,0x62,0xff,0x28,0x05,0xd2,0x22,0x62,0x82,0xd4,0x2d,0xe2,0xec,0x66,0xc5,0xee,0x63,0xd0,0xf6,0x93,0xa8,0x37,0xbf,0xdd,0xe0,0x95,0x0b,0x19,0xa1,0x9d,0x9a,0xf8,0x94,0x1a,0x3a,0x50,0x9e,0x66,0x75,0x8c,0x25,0xbd,0x18,0xb0,0x58,0x76,0x7f,0x2d,0x3d,0x06 +.byte 0x02,0xb3,0xcf,0xa3,0x14,0x6e,0xe7,0xc8,0xcd,0xe6,0xbe,0xae,0x92,0xd6,0xa2,0xfe,0x12,0xf0,0xdf,0x9f,0x9e,0xad,0x77,0x77,0xfb,0xfc,0x36,0xb7,0x82,0x9c,0xf1,0x51,0xc2,0x58,0xa0,0xf3,0xa0,0xd6,0x6e,0x64,0x28,0xac,0x09,0x8f,0x7b,0xef,0x19,0x87,0x76,0xb9,0x4e,0xca,0x1f,0x05,0xb6,0x00,0x4a,0x14,0x83,0xaf,0xff,0xd9,0xa1,0xc6 +.byte 0x0f,0x98,0x3a,0xcf,0x85,0x18,0xea,0xa6,0x9a,0x1e,0xae,0x7c,0xaa,0xae,0xef,0x89,0x5e,0x14,0x5d,0x2f,0x73,0x8f,0xd1,0xf0,0x77,0xcd,0x45,0x92,0x7f,0xee,0xb9,0x7c,0xc2,0x3c,0xff,0x56,0x56,0xa5,0xa5,0x49,0xe4,0x20,0xd6,0xa2,0xb6,0xe4,0xfc,0x86,0x53,0xce,0x9e,0x2b,0x7b,0xcb,0xcf,0x6a,0xd5,0x62,0xb7,0x34,0x0e,0x39,0xe2,0xaa +.byte 0x1c,0x24,0x30,0x71,0x94,0xb3,0x57,0xd8,0xe8,0xd4,0xc5,0x4f,0x33,0x2c,0x73,0x7e,0x48,0xba,0xb3,0x55,0x84,0x6d,0x10,0xcf,0x8f,0xf2,0xb6,0xdb,0x4e,0xcf,0x49,0x08,0xf6,0x5a,0x3c,0x7e,0xef,0x3f,0x5c,0x11,0x09,0xfe,0x26,0xfb,0xff,0x30,0xcb,0x81,0x12,0xea,0x1e,0xa9,0x6e,0xf8,0xea,0x4f,0x92,0x2c,0x23,0x99,0x35,0xa5,0x59,0xca +.byte 0x1d,0x66,0x72,0xad,0x5b,0x7c,0xb3,0x4a,0x7c,0x76,0x4c,0xf6,0xc1,0xec,0x68,0x5f,0x2c,0x17,0xbe,0x92,0xe1,0xa1,0xee,0x40,0x24,0x25,0x6b,0xc5,0x0b,0x6f,0x06,0xc0,0x05,0x8c,0x23,0x24,0x76,0xea,0xe9,0xb9,0xa1,0x3d,0x59,0x15,0xe7,0x65,0x47,0x5a,0x75,0x9b,0xc8,0x7b,0x86,0x97,0xf4,0x4a,0xa3,0xec,0x54,0x0e,0x66,0xef,0xda,0x41 +.byte 0xb8,0x3b,0xa6,0x86,0x63,0xe1,0x4e,0x89,0x92,0x40,0xf4,0x8b,0x32,0x47,0x3b,0x4b,0xb4,0xe6,0xd8,0x4b,0x1c,0xac,0x03,0xab,0xde,0x2e,0x63,0x96,0x3f,0x27,0xa1,0x32,0x11,0x35,0x24,0x6a,0xe9,0x0b,0x73,0x61,0x4e,0xd8,0xdc,0x91,0x98,0x01,0x8a,0x0d,0x61,0xec,0x39,0xbe,0x3b,0xb9,0x78,0x77,0xea,0xaa,0xa2,0x12,0x20,0x92,0x98,0x16 +.byte 0x27,0x3b,0xd1,0xfa,0x59,0xef,0x81,0x38,0x9f,0x42,0xe8,0xb4,0xab,0x4f,0x26,0x9a,0xe7,0x0b,0x05,0x03,0xfa,0xe1,0xe1,0x3d,0x45,0xac,0x7d,0x40,0xcc,0x2f,0xf2,0xb0,0x33,0x42,0x14,0xbd,0x91,0x3e,0xe1,0xb7,0x17,0x25,0xc3,0x92,0xcb,0x9e,0x44,0x1e,0x13,0x93,0x98,0x1f,0x96,0x64,0x3a,0xaa,0x53,0x9a,0x18,0xc0,0x34,0x3c,0x47,0x94 +.byte 0x14,0x70,0x67,0x76,0x2a,0x82,0xd3,0x6a,0x18,0x13,0xe7,0x01,0x8d,0x97,0x52,0x51,0x8e,0x08,0xde,0x44,0xb0,0x74,0x07,0x58,0x35,0xc2,0x29,0xb5,0xd7,0x00,0x46,0x31,0x34,0xd7,0x1f,0xdd,0xaa,0x5c,0x27,0xc7,0x37,0x71,0xe8,0xbe,0xad,0x89,0xf1,0xb2,0xd1,0x46,0x33,0x0c,0x2f,0x26,0x21,0x5e,0xc9,0xda,0x25,0xcd,0xd0,0x17,0x23,0x87 +.byte 0x15,0xc2,0xa0,0x1a,0x9f,0x6e,0xfb,0x63,0xe9,0x69,0xdf,0x79,0x18,0x33,0x2f,0x47,0xca,0x54,0x23,0x7e,0x4f,0x6e,0x38,0x06,0x99,0xfb,0xcd,0x22,0xdb,0x4b,0x3f,0x8a,0x05,0x2e,0x5c,0x56,0x65,0xb7,0xab,0x57,0x8b,0xdd,0x28,0xab,0x7e,0x77,0x32,0x0f,0xc6,0x3c,0xf3,0xde,0x43,0xb0,0x13,0x3b,0xbd,0x28,0x3a,0x8b,0xd5,0x6b,0x1d,0x5d +.byte 0x20,0x1a,0x5f,0xa6,0x01,0xed,0x88,0x7f,0x87,0x55,0x38,0xc2,0x0d,0x03,0x6c,0x41,0x6a,0x43,0xdf,0x09,0xf3,0x58,0x69,0x13,0xa1,0xd6,0x39,0x0c,0x8e,0x8f,0x40,0x67,0xe8,0x0e,0x9b,0x9b,0x42,0x30,0xd7,0xae,0x04,0x75,0x66,0xfb,0x4a,0xa7,0xe0,0xe9,0xea,0x6d,0x28,0x4f,0xc0,0x5c,0xd4,0xd4,0xb7,0x60,0x5a,0x35,0xc1,0xe8,0x5f,0xc3 +.byte 0x4f,0x7a,0x5d,0x8d,0xc2,0x29,0x6e,0x36,0x50,0x5b,0x82,0x63,0xf2,0xda,0x8d,0x02,0x61,0x09,0x69,0x0a,0x47,0x9d,0x58,0xf3,0xf6,0xe0,0xc0,0x09,0xd9,0x3b,0x8d,0xf5,0xba,0xf6,0xc4,0xf0,0x65,0x89,0x7b,0xdd,0x93,0x6b,0x6e,0x21,0xa1,0x2a,0x66,0xe0,0x8f,0x62,0xb0,0x49,0x60,0xa3,0x48,0x42,0x62,0xcc,0x26,0x1f,0x59,0x3a,0x7b,0xa7 +.byte 0x82,0x10,0x5f,0xc6,0xf8,0xa2,0xc0,0x07,0x7b,0x26,0x26,0x11,0xe2,0x5b,0xb8,0x86,0xb7,0x66,0xcf,0x0a,0xcc,0x6f,0xe8,0x02,0x22,0x4c,0x13,0x75,0xdc,0x68,0xf0,0x7c,0x0c,0x46,0x9a,0xa2,0x4c,0xf5,0x50,0x3f,0xf9,0xbc,0x01,0xb1,0xa1,0x28,0x90,0x07,0x6b,0x17,0x69,0x89,0x7b,0xe5,0x0a,0xf7,0x7b,0xe1,0x94,0x30,0xfc,0xd3,0x8d,0xd3 +.byte 0x99,0x37,0x91,0xd5,0xdf,0x59,0x2a,0x4f,0xfe,0x6c,0x37,0x4b,0x78,0x2c,0xa9,0x28,0x6a,0x5c,0xd6,0xe1,0x0b,0xad,0xae,0x62,0x7c,0x09,0xb8,0x90,0x3f,0x29,0x37,0x7b,0x79,0xee,0x55,0x02,0x05,0xef,0x28,0xa2,0xc7,0x07,0x2b,0xe6,0xab,0x87,0x9d,0x8f,0x4c,0x0f,0xc1,0x75,0x5d,0x88,0x7f,0x26,0xe0,0x1e,0xf8,0x3f,0xb5,0x2a,0x6c,0xe6 +.byte 0x7f,0x85,0xae,0x55,0x7b,0x58,0x34,0x4c,0x81,0x05,0x21,0xa1,0x5e,0xd7,0xb6,0x20,0x6e,0xf9,0x60,0x15,0xa4,0xb2,0x8f,0x68,0xd2,0x23,0x9f,0xbf,0xfa,0x6a,0xcb,0x87,0x7d,0x41,0x4a,0xae,0x28,0x4f,0x9e,0xbb,0x69,0x1c,0x37,0xb2,0xc9,0xd2,0x21,0xa1,0x2b,0x6b,0x5d,0xff,0xd6,0xdb,0x8f,0x21,0xd9,0x17,0xd6,0xe6,0x74,0xf2,0x20,0x0e +.byte 0x06,0xb5,0x0c,0xdc,0x74,0x4e,0x93,0xcb,0x27,0xc7,0x4b,0xf3,0xef,0x46,0xa8,0xf0,0x58,0x1c,0xa0,0x65,0x09,0x84,0xc7,0x2e,0xba,0x51,0xd9,0xd4,0x53,0x20,0xc7,0x20,0x85,0x93,0x2b,0xf3,0x42,0x93,0x7b,0x22,0x1c,0x8d,0x22,0x76,0xcf,0xde,0x6a,0xa1,0x76,0xea,0x65,0x20,0x2f,0x2e,0xdb,0x85,0xdd,0x73,0x43,0xf8,0xe0,0xe3,0x3a,0xe5 +.byte 0x02,0x57,0x96,0x54,0xbc,0xaf,0xa4,0xd5,0xda,0x9d,0x9d,0x8b,0x85,0x01,0x7c,0x72,0x03,0xfe,0x39,0x46,0xab,0x04,0xcc,0x62,0x71,0xf5,0xa5,0x67,0xd7,0xfc,0xc0,0xb6,0x95,0x74,0xdf,0x1c,0xfe,0x1c,0x5b,0x25,0xae,0x42,0x75,0x00,0x71,0x3c,0xec,0xfc,0x3c,0x7b,0x0f,0xec,0x44,0xc7,0xec,0x9b,0x86,0xf5,0x3d,0x47,0x15,0xf0,0x25,0xba +.byte 0x43,0xc8,0x68,0x15,0x4f,0xeb,0x35,0x76,0x2d,0x04,0xb7,0x9b,0xb8,0xa7,0x0d,0xb3,0xb4,0xf2,0x93,0x85,0xb1,0xb8,0x81,0x7c,0xd6,0x5f,0xbd,0xc2,0xcc,0xf4,0x0e,0x98,0x2c,0x06,0x54,0x2f,0x5e,0x49,0x94,0x93,0x78,0xa0,0x0a,0x33,0x2e,0x3f,0xb2,0xa7,0x81,0xed,0xe9,0xb6,0xb5,0x86,0x4b,0xa5,0xc0,0x51,0x30,0x9d,0xe2,0x9f,0xc2,0x56 +.byte 0x92,0x6b,0x96,0xca,0xcb,0x65,0x5c,0x0e,0xf4,0x91,0x2b,0x89,0xf4,0x27,0x55,0x26,0xd7,0x7b,0x00,0x19,0x1f,0x67,0x4e,0x43,0x24,0x81,0x05,0xb7,0xc6,0x41,0x1a,0x39,0x3d,0x40,0x3e,0x8a,0x03,0x94,0x63,0x1b,0xb1,0x87,0xb6,0xe1,0x52,0xd0,0xe8,0xbb,0x0e,0x37,0x72,0xe5,0xde,0x86,0xc0,0xdf,0x5b,0xc2,0xc6,0x0a,0x67,0xa7,0x4c,0x03 +.byte 0xb6,0xd8,0x7f,0x1d,0xb3,0xe3,0x84,0xb7,0x5c,0x04,0x15,0xe0,0xd0,0xae,0x44,0xac,0x39,0xa5,0xa2,0x86,0xc8,0xad,0x27,0xa0,0x36,0xa1,0x6e,0xaa,0x87,0x7a,0x43,0xae,0xa0,0x45,0x1a,0xac,0x04,0xe2,0x55,0xf2,0x9a,0x97,0x67,0xfb,0x01,0x8f,0xb8,0x80,0x9c,0x27,0x1d,0xbe,0xa3,0xf1,0x6d,0x66,0xf2,0x1a,0x99,0x99,0xf6,0xa5,0xba,0x58 +.byte 0x28,0x58,0xb5,0x44,0x5b,0x38,0x4a,0x3f,0x37,0x85,0x7e,0x36,0x8e,0x16,0xb9,0x1e,0x0b,0xbf,0x7d,0x0a,0x0c,0x83,0x53,0x0d,0xcc,0x37,0xe1,0x42,0xbb,0x0d,0xfc,0x01,0x25,0x10,0xbe,0xb5,0x83,0x2f,0xa5,0x42,0x98,0xbc,0xd6,0x50,0x75,0xda,0x32,0x2b,0x3f,0xd6,0xc1,0x1a,0xe7,0x0b,0x80,0x07,0x6f,0xfe,0x77,0x9e,0xe9,0x1e,0x45,0x65 +.byte 0x68,0x92,0x34,0x8b,0xce,0xf3,0xcd,0x94,0x17,0xe0,0x41,0x92,0x96,0xb5,0xd1,0x98,0xd1,0x25,0xd1,0x3d,0x76,0x88,0x86,0xb1,0x01,0x80,0xc7,0xde,0x60,0x20,0xb8,0x03,0xe7,0x3f,0x44,0x39,0xb1,0xb8,0x19,0x53,0x5a,0xc6,0xa0,0x18,0x8e,0x0e,0xb6,0xfd,0x7e,0xe7,0x7e,0x8a,0xeb,0x4c,0x35,0x4a,0x0f,0x52,0x81,0x68,0x12,0xe4,0x46,0x2e +.byte 0x20,0xb4,0x41,0x59,0xb3,0x16,0x02,0x9f,0xdb,0xe8,0xea,0xfd,0xe3,0x5d,0x14,0xd0,0x97,0x52,0x66,0xcb,0xb4,0x48,0xa3,0x05,0xab,0x73,0x8e,0x2c,0x46,0xc2,0x94,0xd5,0xc8,0x57,0xc4,0x13,0xa4,0x0b,0x7c,0x34,0xbf,0xb4,0x07,0x28,0x92,0xe2,0x1d,0x00,0xa6,0xf0,0xb0,0xbf,0xdd,0x5d,0x20,0x05,0x9f,0x53,0xcf,0x07,0xf7,0xe8,0x79,0x04 +.byte 0x57,0xd1,0xac,0x9c,0xdd,0xae,0xcd,0x8b,0x04,0x0a,0x2d,0x0a,0x0f,0x21,0x09,0xc8,0x0d,0xfa,0x23,0x26,0xe3,0xdb,0x84,0xc8,0x8e,0x9c,0x96,0x93,0x4f,0xcc,0x2f,0x96,0xed,0x04,0x91,0x0d,0xc7,0xbb,0x27,0xa3,0x6b,0x9d,0xe2,0x15,0x83,0x31,0x78,0xb5,0xb9,0x6d,0xb1,0x6c,0xa2,0x3e,0xf5,0x45,0x77,0xf4,0x96,0x3a,0xe6,0x10,0x08,0xfd +.byte 0x23,0xcc,0xda,0x27,0x73,0x67,0xbb,0x8b,0x59,0xe2,0xcf,0xda,0x57,0xf9,0x17,0xeb,0xeb,0x98,0x39,0x48,0xbf,0x3d,0x5b,0x7b,0xc2,0x11,0x4b,0xd6,0xb6,0x8a,0x14,0xb3,0xf5,0xc3,0x18,0xff,0xde,0x62,0x98,0x4a,0x1d,0x6b,0x4e,0x00,0x4f,0x7d,0x2f,0x67,0xf4,0x22,0x1e,0xdb,0x69,0xd5,0x87,0xfd,0xee,0x97,0x56,0xd4,0x00,0x0c,0x9e,0x22 +.byte 0x11,0xda,0x8e,0x3b,0x91,0xad,0xf1,0xb6,0x0a,0xba,0xe7,0xc6,0x14,0x0e,0xc4,0x85,0x5f,0x7d,0x69,0x7d,0x73,0x9c,0x83,0x6a,0x69,0xef,0x10,0xb0,0xe6,0x33,0x32,0x0f,0xd8,0x54,0xa4,0x9d,0x39,0xaf,0xfc,0x6d,0x4f,0xeb,0x34,0x89,0x2e,0xb0,0xa1,0xcd,0xe1,0x5b,0xab,0xe1,0xff,0x82,0x85,0x6b,0x5e,0xa9,0x9e,0x43,0x02,0x0d,0x38,0x33 +.byte 0xe1,0xbc,0xa4,0x77,0x8a,0x5e,0x54,0xa8,0xcf,0xc9,0x76,0xcb,0x73,0x21,0x1f,0xa7,0x1e,0x5c,0x0a,0xd6,0xa2,0x36,0x6f,0x07,0xa1,0x6b,0x0d,0x5a,0x21,0x3a,0xc3,0xc0,0xcd,0x9d,0xed,0x83,0x96,0x89,0xaa,0x55,0x56,0xfd,0x0a,0x97,0x3a,0x50,0xfd,0x95,0x3f,0xb7,0xfa,0x87,0x7d,0xa6,0x5d,0x12,0x65,0x3f,0x61,0x4f,0x86,0xdd,0x58,0x64 +.byte 0xd7,0xde,0xd6,0xb9,0x68,0x87,0xde,0xba,0x96,0xf5,0x1c,0xec,0x8e,0x81,0xfc,0xca,0x77,0xe2,0x85,0x11,0x93,0xc7,0xf2,0x0f,0x77,0xbb,0x7c,0xed,0x20,0x7a,0xe3,0xc5,0x76,0xff,0x04,0xc7,0xe6,0x7a,0xa1,0xfe,0x58,0x52,0x1b,0xec,0x27,0xbb,0xd4,0x27,0x7c,0xc7,0x4a,0xfb,0x07,0x62,0x99,0x36,0xff,0x6e,0x71,0x2f,0xbd,0x25,0xff,0x8d +.byte 0x97,0x14,0x56,0x23,0x7f,0x13,0x89,0x10,0xd8,0x29,0x1f,0x91,0x56,0x52,0x85,0xa7,0xd3,0x04,0xc9,0xe2,0x09,0xa2,0x0f,0xaa,0x28,0xb1,0x79,0xf9,0x08,0xf4,0x14,0x57,0xc4,0x54,0xd7,0x69,0xb0,0x37,0xf0,0x80,0x90,0xce,0x75,0x81,0xe7,0x75,0x0f,0x7f,0x71,0x58,0x3b,0x78,0x53,0x9b,0x4a,0x5e,0xcc,0x23,0x04,0x9e,0x0c,0xd7,0xd8,0x69 +.byte 0x90,0xdf,0x36,0x99,0x90,0xd3,0xfa,0x35,0xf7,0x13,0x64,0xb0,0xc0,0x70,0x0c,0xd4,0x87,0xc0,0xca,0xd8,0xca,0x8a,0xc3,0x9a,0xfa,0x73,0x34,0x18,0xe9,0x3a,0x85,0x42,0xc5,0xe1,0xaa,0xb5,0x87,0xac,0x43,0x9c,0xfa,0x7e,0x05,0x35,0xed,0x7e,0x0d,0x38,0x82,0x17,0x7f,0x22,0xa2,0x3d,0xd3,0x0d,0xd1,0xff,0x0a,0x68,0x52,0xd2,0x17,0x59 +.byte 0xaa,0x57,0xbd,0xd3,0xea,0x0c,0xe8,0xb0,0x22,0x13,0x59,0x42,0x46,0x34,0x58,0xa9,0x16,0xc5,0x9f,0x88,0x8f,0x75,0x02,0xbf,0x63,0xda,0x28,0xba,0x9a,0xcf,0xbb,0x73,0x58,0xb1,0x13,0xf2,0x68,0xd8,0x6b,0xfd,0x49,0x50,0xcf,0x09,0xea,0x6a,0xff,0x20,0x39,0xc5,0xae,0x70,0x79,0xea,0xec,0x9d,0x09,0xf8,0x51,0x1f,0xfd,0x01,0xd5,0x9f +.byte 0xec,0x29,0x36,0xfc,0x39,0xb4,0x4c,0x1f,0xe6,0xb4,0xcc,0x97,0x21,0xe5,0x19,0xe9,0x7a,0x60,0x6d,0x39,0x3c,0x31,0xd4,0x43,0x76,0xba,0x10,0xd9,0x3f,0x75,0x7a,0xa6,0x1d,0x02,0x88,0x3d,0xa5,0x9f,0x91,0x61,0x4e,0x32,0xec,0xf5,0xd3,0xe4,0x65,0xf7,0x0e,0x3b,0x8a,0x8f,0x22,0x31,0x71,0x8f,0xf1,0x5f,0x7b,0x04,0x88,0xf9,0x88,0x67 +.byte 0x14,0x85,0x74,0x9e,0x54,0x0b,0xed,0x7a,0x48,0xcd,0xcf,0xd2,0x05,0x38,0xd5,0x58,0xa2,0xaf,0x6a,0x28,0x21,0xfd,0x38,0x4e,0x83,0x06,0x15,0x60,0xfb,0x89,0x2a,0x72,0xfe,0x75,0xc7,0xa4,0xae,0xe4,0x5b,0xbb,0xde,0x54,0xde,0x77,0xbb,0x9d,0xd2,0x07,0x05,0x61,0x53,0x65,0x31,0xd4,0x3a,0x8a,0x7d,0x9d,0x30,0x09,0x25,0x28,0x72,0x19 +.byte 0xe4,0xae,0x1d,0xbf,0xa7,0xef,0x75,0xd0,0xe3,0xdc,0x0b,0xd1,0x17,0x9c,0xc6,0xdf,0x65,0x9a,0x7c,0x9d,0x0b,0x9a,0x3d,0x8f,0xb0,0xf5,0x51,0x46,0x6b,0x12,0x0d,0xe6,0xa9,0x3a,0xb5,0xe9,0x52,0x85,0xa5,0x25,0x1f,0xc9,0x8b,0xff,0xe3,0x37,0x25,0x97,0xd8,0x91,0x17,0xed,0xcf,0x2a,0x6d,0x4f,0xef,0x74,0x5e,0x92,0xa2,0x2d,0x84,0xa6 +.byte 0x09,0xc4,0xfc,0x36,0x95,0x54,0x25,0x9e,0xeb,0xd9,0xea,0x5a,0x01,0x0c,0x54,0xdb,0x82,0x01,0xed,0x0b,0xf7,0x9f,0x0d,0x8f,0x2e,0xee,0x7c,0x6e,0xb3,0xe7,0xe8,0x04,0xef,0x8d,0x5e,0xfe,0x3d,0x96,0x3a,0x65,0xd3,0xb2,0x11,0x75,0x1c,0x6f,0x2a,0xd3,0x26,0x1f,0x5f,0x35,0x02,0x0b,0x9f,0x38,0x5b,0xa5,0x3a,0x90,0x3e,0x03,0x9f,0x50 +.byte 0xf2,0xd7,0xe4,0x3c,0xd3,0x28,0x67,0x0a,0x5a,0xe8,0x59,0x6f,0x38,0x8f,0x8b,0x0d,0xe4,0x1c,0xfc,0x6e,0x07,0x69,0x7b,0xfb,0x04,0x30,0xe7,0xa6,0x13,0xfb,0x33,0xa0,0x52,0x6a,0xec,0x64,0xad,0x90,0xbd,0xba,0x15,0x12,0x48,0xed,0xd1,0x94,0x2d,0xe7,0x19,0x28,0x5e,0x7a,0x94,0xf4,0x79,0xd7,0x79,0xc9,0xf6,0x16,0xb4,0x88,0xee,0x15 +.byte 0xa2,0x68,0xe3,0x1d,0xd0,0xd2,0x63,0x78,0x7c,0xb3,0x30,0xac,0x63,0x7a,0x36,0xc5,0x50,0xbf,0x57,0xf6,0xfe,0x4e,0x43,0x4e,0xf9,0xc4,0xa2,0x2a,0xa7,0xa4,0x2c,0x18,0xb9,0x43,0x7b,0xe8,0xf6,0x14,0x4f,0x07,0x6e,0x65,0x9a,0xdd,0x10,0x2a,0x4c,0xa4,0x58,0x86,0x19,0xad,0x6d,0x5e,0x30,0xfb,0x5f,0xb6,0x9f,0x2a,0xac,0x90,0x0d,0xae +.byte 0xf9,0xab,0xc1,0x33,0xd3,0x73,0x1d,0x46,0xe5,0xc8,0x1e,0x1d,0x61,0xf1,0xda,0x53,0x3e,0x61,0xf0,0x9a,0xe4,0xb7,0x04,0xe9,0x5e,0xf6,0x11,0xa6,0x56,0x39,0xed,0xfb,0x06,0xd0,0x92,0xb9,0xb8,0xb5,0x3b,0x39,0xec,0xa5,0xc0,0xb1,0x7e,0x7e,0xfb,0x89,0x86,0xa8,0x70,0x47,0xa5,0x60,0x8c,0xf8,0x47,0x31,0x04,0x54,0x29,0xf3,0xa2,0x79 +.byte 0xac,0x24,0xda,0x33,0x6c,0x1c,0x34,0xc2,0xa0,0x96,0x27,0xbb,0x31,0xbf,0xc1,0xd9,0xc8,0x35,0xbc,0xb3,0x13,0x8a,0xb6,0x25,0x92,0xdc,0xcc,0x3b,0x8a,0x65,0xf3,0xf9,0xd1,0x2a,0xcd,0xb0,0xf4,0xd7,0x44,0xa0,0x27,0xfc,0x0e,0x69,0x46,0x0b,0x56,0x5b,0x58,0x40,0xd9,0xc4,0x37,0x9b,0x4d,0xa1,0x45,0xd8,0xab,0x4d,0x02,0x31,0x4f,0x93 +.byte 0x56,0xd0,0x26,0x99,0x1c,0xc7,0x2b,0xc2,0x80,0xb4,0xbd,0x6e,0xfe,0xa1,0xf7,0x8f,0x13,0x74,0x2c,0xa8,0x63,0xb1,0x3d,0x6d,0x32,0x4a,0x80,0x6a,0x7f,0xcf,0x6c,0x51,0xa9,0x21,0x34,0x4e,0x13,0x19,0x8f,0x33,0xfc,0x06,0x46,0x05,0xf0,0xcf,0xf1,0xce,0x20,0xe0,0x40,0xf2,0x0a,0xd0,0xf6,0xcc,0xcc,0xc2,0xc7,0x07,0x2e,0x9e,0x0a,0x1e +.byte 0x53,0x59,0xbb,0xe3,0x02,0xc8,0x20,0x9f,0x3c,0xe6,0xec,0xf7,0x8a,0x6d,0x3c,0x0f,0xb3,0x14,0x66,0x5c,0x51,0xbe,0x82,0xc2,0x0b,0x10,0x63,0xa9,0xd4,0x7f,0x12,0x88,0x13,0x81,0x8a,0x06,0x8a,0x7f,0xc8,0x89,0xe7,0xbd,0xce,0x51,0xdc,0x93,0x03,0x07,0x6f,0x8c,0xe6,0xcc,0x0d,0x45,0xa8,0xfc,0x02,0xe2,0x3e,0xa7,0xc8,0x83,0x77,0x98 +.byte 0x91,0x4e,0x1f,0x8d,0xed,0xa5,0x38,0x54,0x0e,0x4e,0x53,0x1c,0x0c,0x47,0x11,0x59,0x54,0x15,0xb5,0x47,0xb0,0x21,0xa1,0x3d,0xaa,0xef,0xee,0x9e,0x26,0x3c,0x39,0x75,0xff,0x1a,0x8c,0xbb,0x1a,0x49,0x62,0x21,0x76,0xe8,0x3d,0x10,0x55,0xf5,0x5a,0x44,0xf0,0xb3,0x81,0xd0,0x35,0x96,0x95,0x63,0xf7,0x50,0xb1,0xa0,0xf0,0x29,0x97,0xc9 +.byte 0x27,0x73,0xd8,0x29,0xef,0x74,0xd2,0x6d,0xf4,0xfb,0x72,0xa9,0x4f,0x12,0xd5,0xfd,0xc9,0xba,0xf0,0xbd,0xfd,0x5e,0x5c,0xfa,0x53,0xe3,0x96,0xab,0x57,0xc3,0xb6,0xe8,0x0e,0x43,0xe4,0x77,0x97,0x04,0x69,0xff,0x72,0xd0,0xd8,0xab,0xb9,0x19,0x25,0x89,0xf7,0xbb,0x01,0x03,0xf2,0xc6,0x8d,0xd5,0x86,0xe3,0xfe,0x9c,0xff,0x78,0xd7,0xfc +.byte 0xda,0xd4,0x69,0x8e,0xd6,0x31,0xfb,0x15,0xd3,0x38,0xfd,0x53,0xe2,0x4e,0xce,0xcc,0xfe,0x17,0xc5,0x88,0x92,0x28,0x98,0xb7,0xcf,0x7b,0x53,0x7b,0x96,0x14,0xaf,0xeb,0x5b,0x2d,0x16,0x41,0xcc,0x7b,0x65,0xe1,0x73,0x81,0x4e,0x8f,0xc3,0xad,0xe1,0x3f,0x0c,0xa7,0xbe,0x38,0xed,0x02,0x67,0xf5,0xfa,0x1d,0xb0,0xd5,0x4c,0xe1,0xd8,0x62 +.byte 0xc9,0xb5,0xf8,0x84,0xc4,0x51,0x57,0x14,0x11,0xf8,0x7d,0x1d,0xe7,0x81,0x85,0x61,0xa9,0x9f,0xc8,0x45,0xb9,0x2d,0x8a,0xc9,0xa3,0xfe,0x5a,0xf9,0xe0,0x1c,0x80,0xd8,0x77,0xaa,0x85,0xca,0x93,0x9a,0x2e,0x10,0x03,0x71,0x3d,0xb1,0x2a,0x64,0x2e,0xad,0x64,0xba,0x5c,0xaa,0x8a,0xc2,0x2a,0x80,0x28,0x2e,0xf9,0x93,0xe1,0x71,0x72,0xae +.byte 0xda,0xd8,0x4f,0x4c,0xec,0xb5,0xe3,0x05,0x10,0x5f,0x4c,0xe6,0xe1,0xf4,0x07,0x63,0x75,0x6f,0xc5,0xf9,0xcd,0xfc,0xfc,0x35,0x2f,0xe4,0xca,0x4b,0xfc,0xc3,0x20,0x8b,0x5c,0x4a,0x3c,0xf8,0x92,0xca,0x2b,0xb0,0xce,0xd9,0x4b,0xf0,0x44,0xcb,0x4e,0x83,0xf3,0x9d,0xb0,0xd4,0xab,0xba,0x2a,0x76,0xaa,0x87,0xcd,0xa2,0xd1,0x3f,0xa0,0xb9 +.byte 0xdb,0x7e,0x67,0x2d,0x92,0x4c,0xeb,0x3c,0xa6,0x8c,0x62,0x80,0x18,0x78,0x2b,0x9d,0x8f,0x5e,0xc3,0xa5,0x3b,0x10,0xb3,0x8a,0x3b,0x00,0x96,0xb2,0xab,0xce,0x8d,0xff,0x3c,0xee,0xeb,0x4f,0xfb,0xab,0x96,0x38,0x4c,0x15,0x6e,0x7c,0xf3,0x31,0x5f,0x8f,0x99,0x88,0x52,0x48,0x8b,0x71,0x1b,0x31,0x3f,0x7c,0xe4,0xae,0x9c,0x7b,0xeb,0x64 +.byte 0xe3,0x80,0xd4,0x56,0x9a,0x6a,0xd9,0xca,0xc5,0xf0,0x86,0xe7,0xda,0x80,0x8f,0x17,0x61,0xca,0x24,0x0b,0xb6,0xf9,0x24,0xc5,0x7a,0x28,0x42,0x32,0x7f,0x2b,0xde,0x44,0x30,0xed,0x69,0x63,0x07,0x3f,0xca,0x7b,0x02,0xea,0x6e,0xef,0x27,0x1d,0x76,0x32,0xc2,0x81,0x3d,0x03,0x9a,0xe7,0x0d,0x28,0x07,0x03,0x0c,0x65,0x73,0x58,0x26,0xc6 +.byte 0xfe,0xcc,0x33,0x7f,0x33,0xad,0xea,0x81,0x05,0xcc,0x61,0x1e,0x78,0x69,0x70,0xc9,0x1f,0x6e,0x4f,0xb8,0x19,0x42,0x03,0x03,0x9d,0x56,0x87,0x0e,0x9a,0x32,0x3a,0xba,0xb9,0x11,0x66,0x9f,0x4d,0xd1,0xb0,0x11,0xbf,0x46,0xfc,0xcf,0xe5,0xef,0xf1,0x61,0xeb,0xad,0x31,0x7c,0x0d,0x66,0x0d,0xa9,0x1f,0xe4,0xf9,0x80,0x9e,0xae,0x9e,0x34 +.byte 0x1e,0x95,0x6c,0xa2,0x77,0x69,0x84,0x77,0xb7,0xe8,0xca,0x1f,0xea,0xc1,0x34,0xe6,0x0d,0x4f,0xba,0x77,0x2b,0x8c,0xbe,0xff,0xc4,0x06,0xa3,0xb6,0x1a,0xbe,0x55,0x99,0x57,0x6f,0x54,0x24,0x93,0x7a,0x0d,0x52,0xd6,0xbb,0xd2,0x9c,0xd5,0x76,0x6a,0x22,0x66,0xdc,0x43,0x9a,0x7b,0x1b,0x11,0x80,0x02,0x0c,0x8f,0xc6,0xc6,0x02,0x42,0x29 +.byte 0x00,0xc4,0xb2,0xa1,0x6a,0x7f,0xa9,0x60,0x8d,0x41,0x4f,0xd3,0xde,0x33,0x5a,0x44,0x31,0xb0,0xdc,0xc0,0x0c,0x31,0x03,0x96,0x71,0x0a,0xce,0xe3,0x0b,0xc7,0xe3,0x5d,0xe0,0x88,0x4b,0xfd,0x4c,0x1a,0xce,0xaa,0x89,0xc6,0x99,0xa8,0xd3,0x1e,0xe9,0x6c,0x2a,0xbd,0x26,0x81,0x03,0x6a,0xf2,0xf2,0x0f,0x1e,0x9d,0x8a,0x59,0x45,0xbf,0x6d +.byte 0xb7,0xc8,0xec,0x77,0xb0,0x70,0x1a,0x31,0x21,0xeb,0x25,0x12,0xff,0x13,0x33,0x6b,0x47,0x34,0xd8,0x66,0x11,0x8a,0xc9,0x93,0x5b,0x2c,0x55,0x42,0xb2,0x9b,0x60,0xc6,0xba,0xab,0x12,0x12,0x5d,0x0a,0xd4,0x54,0x79,0x17,0x6d,0x31,0x7d,0x4f,0xf2,0x94,0x16,0x65,0x62,0x38,0x76,0x3a,0x7d,0x55,0x05,0xd9,0x17,0x45,0x62,0xb4,0x1d,0x31 +.byte 0x34,0x40,0xd3,0x8e,0xf9,0x29,0x4d,0x3f,0x93,0x9a,0x2e,0xa4,0x75,0x66,0xf6,0x62,0x8f,0xf9,0x8d,0x79,0x4b,0x51,0x7e,0xfb,0xeb,0x9a,0x86,0x96,0x01,0x79,0xbe,0xe4,0x42,0xb3,0xc8,0x28,0x9e,0xed,0xa8,0xb6,0x6d,0xd3,0x31,0xed,0x30,0x9e,0x6a,0x5b,0x02,0x4b,0xbd,0xb3,0xf2,0xf0,0x9d,0x50,0x09,0x40,0x71,0xfe,0x4b,0x91,0xc9,0xd6 +.byte 0x07,0x87,0x9e,0xdb,0xa9,0xcd,0x0b,0x95,0x18,0x5a,0x55,0x10,0xaa,0xe1,0x70,0xe9,0x2e,0xc2,0x31,0x6b,0x48,0x84,0x2f,0xe5,0x7b,0xdd,0x4c,0x03,0xed,0xb6,0xb6,0x64,0x24,0x38,0x7a,0x5a,0x15,0x35,0x9d,0x66,0x08,0x4d,0xa6,0x3c,0x96,0x1a,0xcd,0x02,0x61,0x40,0xde,0xac,0xc3,0x15,0x8c,0xca,0xe6,0x62,0xe9,0x61,0x68,0xf6,0x60,0xd3 +.byte 0x7e,0x5f,0x44,0xcf,0x09,0x01,0x60,0xc2,0xb1,0xfc,0x2f,0x41,0x4c,0xc1,0x06,0x72,0xcc,0xde,0x25,0xe0,0x8c,0x34,0xb8,0xe0,0xb2,0xeb,0x05,0x5d,0x9e,0x7e,0xf7,0x1e,0x24,0xcd,0x1b,0x14,0x3f,0x1b,0x13,0xc0,0x64,0x38,0x43,0x95,0xba,0x7b,0x61,0xa0,0xdc,0xe0,0xf5,0x80,0x13,0xa1,0xc5,0x48,0x92,0xc5,0xd5,0xd0,0x87,0x0c,0x73,0xae +.byte 0xe2,0xb3,0xe8,0x70,0x4a,0x7e,0xa0,0x13,0xc3,0xc6,0x9c,0x77,0x51,0xca,0x88,0xcf,0xe0,0x1e,0xff,0x6c,0xe2,0xc3,0x33,0xce,0x7f,0x3e,0x7d,0xd5,0x37,0x23,0x09,0xb7,0xbd,0xb7,0xec,0x9a,0x29,0xd6,0x4f,0xea,0x79,0x24,0x4c,0x09,0x74,0x9c,0x97,0x3b,0x08,0x1f,0x82,0xcc,0xae,0xc4,0x3f,0xcf,0xc6,0xcb,0xaf,0x8c,0x89,0x15,0x79,0xeb +.byte 0x88,0xb9,0x03,0xab,0xc6,0xf8,0x6e,0x54,0xde,0x50,0x6e,0xcf,0x8a,0x4b,0x3f,0x64,0xd0,0xcb,0x69,0xc2,0xe3,0x40,0x4a,0x94,0xe2,0x04,0xfa,0x9b,0x4a,0xf6,0x2b,0x93,0x0c,0x0e,0xf8,0x68,0xbc,0x6e,0x6c,0xe6,0xd9,0xb6,0x04,0x40,0xf4,0x60,0xbc,0xc1,0x1e,0x67,0x1f,0xce,0x5c,0x4d,0xba,0x78,0xa8,0xf5,0x96,0x00,0xb9,0x61,0x82,0x65 +.byte 0xb2,0x1d,0x42,0xb8,0x88,0x66,0x43,0xd9,0xfe,0xe0,0x86,0xef,0x5d,0x4d,0xcc,0xeb,0x57,0x9a,0x2b,0x27,0xf2,0xcf,0x68,0xc3,0x05,0x92,0x4d,0x4d,0xb7,0x46,0x7e,0xfd,0xb7,0x4a,0x4d,0x6f,0xac,0xc8,0x8d,0xf2,0xcd,0x52,0xcf,0x91,0x77,0x2d,0x68,0x06,0x7a,0xc9,0xf3,0x17,0xc6,0x8f,0x8f,0xb5,0x8f,0x74,0xfa,0x90,0xcc,0xfc,0xaf,0x4e +.byte 0xd2,0x29,0xd9,0x57,0x71,0xe9,0x52,0xd8,0x50,0xfa,0x4d,0x13,0x7c,0x42,0x15,0x22,0x65,0x26,0x08,0xda,0xaa,0x53,0xcf,0xeb,0xd1,0x87,0xd5,0x7c,0x4e,0x66,0x1c,0x7d,0xc9,0x03,0x59,0xf8,0x09,0x3e,0x1b,0x94,0x4c,0x39,0x56,0xeb,0xfd,0xb6,0xd0,0xf9,0x76,0x8b,0x5d,0x6e,0x44,0x15,0xcf,0x27,0x7f,0x69,0x9a,0x00,0x96,0xbe,0x80,0x5e +.byte 0xbb,0x5a,0x05,0xea,0x15,0xdd,0x44,0x69,0x9e,0x64,0xcd,0xba,0xf2,0x6f,0x67,0x10,0xc5,0xa1,0x75,0x85,0x5f,0xdc,0x61,0x43,0x34,0xc3,0x52,0x06,0xd4,0xe9,0x9f,0xdf,0xd4,0xa6,0x96,0xac,0xb1,0x21,0xdd,0x20,0x46,0x20,0x89,0x5f,0x0e,0x9d,0xa8,0xc7,0x75,0x3a,0x54,0x9e,0x7c,0x3a,0xd5,0xb2,0x68,0x77,0x06,0x1b,0x1c,0xbd,0xb3,0x02 +.byte 0xb5,0xdd,0x87,0x55,0x6b,0x00,0x9f,0x2c,0x30,0xb7,0x4e,0xc3,0x67,0x38,0x37,0x61,0x81,0x68,0xcb,0x14,0x81,0x27,0xd7,0x38,0x18,0x81,0x68,0x45,0xca,0xf4,0xaa,0xae,0x58,0x9e,0xf8,0xbe,0xe9,0x1e,0x05,0x19,0xf0,0xea,0x89,0xf8,0xa1,0x9c,0x7b,0x63,0xc1,0xcd,0x81,0xc8,0x95,0x56,0x81,0x81,0x29,0xb0,0x4d,0xbf,0xe6,0x8d,0xa3,0xb3 +.byte 0xfa,0xae,0x13,0xc8,0xca,0x4d,0x5c,0x5e,0xd9,0x17,0xf8,0x87,0xdb,0x5b,0xe2,0xd9,0xba,0xe3,0xe8,0xdb,0xcb,0x74,0x36,0x7e,0x0e,0x3a,0x94,0x6a,0xe9,0x9e,0x50,0x8e,0xf4,0xd4,0x15,0xb7,0x50,0x60,0x3f,0x14,0x72,0x41,0x9d,0x51,0x63,0x8c,0x31,0x95,0xf2,0xbc,0x14,0xc7,0x64,0x2c,0xee,0x0b,0xe6,0xde,0xf6,0x33,0x85,0x65,0x00,0x54 +.byte 0x54,0x84,0x85,0x94,0x87,0xa0,0xc3,0x95,0x4e,0x74,0xcb,0x2d,0x82,0x9e,0x46,0x7f,0xf5,0x64,0x60,0xfe,0x1a,0x37,0xee,0xa7,0xb6,0x85,0xb5,0x4e,0x30,0x11,0x39,0x4b,0xe9,0x57,0x18,0x3a,0x2c,0x6b,0xb9,0x8e,0x5a,0x54,0xa9,0x31,0xf7,0xe1,0xe0,0xc7,0x52,0xfe,0x76,0x9b,0xc6,0xfe,0xde,0xe0,0xe9,0xf9,0xf6,0x10,0xda,0xef,0x72,0x24 +.byte 0x9c,0xbe,0x4a,0xba,0x58,0x21,0x1b,0xe3,0x1d,0x80,0x10,0x76,0x70,0xde,0x8f,0xf3,0x07,0x93,0x01,0xe0,0xb4,0xd9,0x7d,0x60,0x0d,0x08,0x07,0xa4,0x6d,0x9b,0x2b,0x8c,0x9a,0x58,0x65,0x5e,0x29,0xf1,0x24,0xb2,0x31,0xfb,0xb7,0xad,0xf0,0x50,0x8e,0x25,0x1b,0x75,0xc5,0x82,0x88,0x8c,0x68,0x14,0x2c,0x28,0xa2,0xb6,0x93,0x14,0xe3,0x28 +.byte 0xd0,0x95,0x6f,0x79,0x91,0x03,0x75,0x82,0x5c,0x20,0x46,0x0d,0x53,0x40,0x2c,0x88,0x62,0xa4,0x8c,0xd5,0xf1,0xc1,0xbf,0xde,0x57,0x91,0xb2,0xa6,0x66,0x29,0xf0,0x6b,0xb8,0x5e,0x78,0x5f,0xd1,0x76,0x98,0xf2,0x56,0xc2,0x5f,0x48,0x1f,0xa6,0x98,0xb0,0x87,0x53,0x13,0x1d,0x1a,0xa7,0xdf,0xa5,0xea,0x37,0x12,0x6d,0x64,0x53,0xdc,0x04 +.byte 0x2d,0xb9,0xeb,0x78,0x89,0x7b,0x70,0xd2,0x6d,0x45,0x8d,0x45,0x50,0x57,0xc7,0xb2,0xaf,0xdd,0x72,0x0f,0x9f,0x1b,0x29,0x61,0x68,0xb5,0x4a,0xd4,0xe9,0xd7,0x10,0xe7,0xcd,0xe8,0x22,0xd3,0x54,0x0c,0x0b,0x32,0x77,0x7d,0x3e,0xed,0x6e,0x79,0x4b,0x7b,0x99,0x1f,0x9e,0xbe,0xe7,0x12,0x7c,0x94,0x36,0x1c,0x20,0x8a,0xd0,0xab,0xda,0x95 +.byte 0xf6,0x4f,0xbe,0x6f,0x44,0x0b,0xa3,0x7b,0x4d,0x00,0xf6,0xdf,0x6f,0xc8,0x50,0x9e,0x3e,0x0c,0x1e,0xfe,0xb8,0x39,0x9f,0x83,0x4f,0xb3,0x1f,0x7e,0x53,0x54,0x64,0x04,0xa3,0xf7,0x79,0x01,0x71,0xce,0x18,0x0d,0x47,0x4e,0xae,0x88,0x6a,0xe7,0x26,0x4e,0x59,0xee,0x3a,0x03,0xc2,0x4d,0x0c,0x29,0xf0,0x96,0x9d,0xc0,0xa3,0xb3,0x82,0xf9 +.byte 0xc4,0xf8,0x8b,0xae,0x68,0x47,0x39,0xdc,0x10,0xd7,0x09,0xb4,0x86,0x87,0xfa,0x7e,0x0c,0xe4,0xee,0x3a,0x35,0x1a,0x0e,0x95,0x88,0xce,0xe7,0x9e,0xcc,0xa5,0x58,0x98,0x48,0xbd,0x9c,0x27,0xe6,0xb9,0xf7,0xca,0x66,0xee,0x54,0x87,0xd0,0x6d,0xab,0x31,0x1a,0x57,0x33,0x8b,0x89,0xa0,0xc0,0x18,0x9a,0x87,0x5e,0x58,0x02,0xe5,0x50,0x47 +.byte 0x0f,0x60,0x53,0x9d,0x99,0xe4,0x0a,0xfa,0x4a,0xc3,0x77,0x4b,0x4d,0x4e,0x0c,0xbb,0x68,0xd9,0xb3,0xd3,0x59,0x78,0xdf,0x65,0x97,0x6e,0x22,0x5b,0x24,0x26,0xf9,0x2a,0x14,0x73,0xa7,0xec,0x65,0xfc,0xdf,0x7d,0x35,0x0d,0x44,0x1b,0x4b,0xad,0x6b,0x8f,0x0e,0xa3,0x3b,0x6b,0x40,0xb3,0xe3,0xd9,0x41,0xba,0xbf,0x95,0xbb,0x6e,0x91,0xf6 +.byte 0x63,0xb3,0xde,0xdb,0xc2,0x6f,0xfe,0x00,0xf1,0x53,0x96,0x37,0xa4,0x27,0x48,0x3e,0xf9,0x32,0x23,0x90,0x90,0xe0,0x01,0xde,0x08,0xad,0xc4,0x6c,0x25,0x7a,0x7f,0x2f,0xb7,0xb7,0xc6,0xaf,0xeb,0x91,0x9c,0xa2,0x9c,0xf7,0x7f,0x9f,0x74,0x9b,0x7d,0x54,0x66,0xf9,0xe0,0x73,0xb4,0x15,0x2b,0xaa,0x71,0x50,0xd0,0x74,0x5d,0xcd,0x1c,0x09 +.byte 0x4c,0x80,0xcc,0xdc,0x10,0xd9,0x96,0xb3,0xdc,0x09,0x73,0x1f,0x36,0x4c,0x1b,0x86,0x25,0x13,0x7c,0xd2,0xc6,0x9d,0x5a,0xce,0xd6,0x22,0x97,0x66,0x7b,0x7b,0x84,0xba,0x69,0xd2,0x87,0x9b,0x08,0xda,0x77,0x66,0x90,0xbc,0x7c,0x3c,0x5d,0x43,0x92,0x5f,0x05,0xfb,0x23,0x46,0x88,0xf7,0xa4,0x10,0xbd,0x7d,0x00,0x29,0x2d,0xa5,0x6a,0xab +.byte 0xcc,0xdd,0xcf,0x1e,0x2b,0x9b,0x5f,0xa9,0x94,0x14,0x99,0x6e,0x3b,0x41,0x52,0x61,0x16,0x17,0x44,0xcf,0x5b,0x34,0x5c,0x27,0x29,0x4a,0xc3,0xba,0x9a,0x0c,0x20,0x17,0x2b,0x92,0xd9,0xf1,0x76,0x51,0xd8,0xa5,0x4a,0x4b,0x4a,0x0b,0xe4,0x6b,0x93,0x61,0xc7,0xb3,0x23,0x7a,0x24,0xfa,0x5e,0xee,0x80,0x10,0x65,0x44,0xa5,0xed,0x72,0xd9 +.byte 0x8a,0x06,0x2a,0x86,0xa9,0x26,0x50,0xa1,0xb2,0xb2,0x8b,0x7b,0x4a,0x29,0xf1,0x18,0xef,0xff,0x61,0xf1,0xa1,0x48,0x0f,0x84,0x8c,0xef,0xd8,0x02,0x65,0x44,0x11,0xf2,0xe1,0xba,0x98,0x03,0xbe,0x5a,0x5d,0xb8,0x0a,0x88,0xd8,0x4a,0x49,0x4c,0x70,0xa6,0x98,0x81,0x36,0x56,0x92,0xde,0xcb,0xaf,0x33,0xf5,0x1c,0x0a,0xce,0x7a,0xc0,0xff +.byte 0x24,0x54,0xd3,0x9a,0x0f,0x82,0x76,0xe5,0x0e,0x82,0xb4,0xfe,0xc2,0xac,0xe4,0xba,0xa3,0x4c,0x8a,0x0d,0xa7,0x3e,0x2b,0x71,0x73,0x5f,0xd2,0x35,0xd3,0xae,0xc0,0x3e,0x6f,0x67,0x98,0x51,0xa6,0xdf,0xb2,0xf4,0xd2,0xc1,0x43,0xe2,0x0a,0x7c,0xa0,0xb6,0xff,0xfc,0xc0,0x88,0xe5,0x34,0x20,0x79,0x50,0xc3,0x06,0x5b,0x20,0x9f,0x05,0x33 +.byte 0x22,0x30,0xaf,0xc4,0xc3,0x17,0x09,0xbb,0x30,0x0f,0x42,0xb7,0xc1,0xe0,0x4c,0x71,0xc5,0xf7,0x96,0xb4,0xd4,0x0f,0x44,0x47,0xa3,0x06,0x17,0xbd,0x0f,0x7c,0xc6,0x53,0x07,0x34,0x9a,0x9a,0x2f,0x3f,0x01,0xea,0xdf,0x1c,0x06,0x33,0x15,0x9c,0x5a,0xe3,0x33,0x29,0xce,0x40,0x4b,0xb1,0x99,0xe0,0x80,0x6e,0x0c,0xa1,0x4c,0x34,0x01,0x21 +.byte 0x12,0xbe,0x67,0x26,0xe6,0xdb,0xab,0x8d,0x45,0xdd,0x12,0x60,0x02,0x1a,0xdd,0x85,0xd6,0x33,0x78,0x23,0xe1,0x58,0x2a,0x46,0xf0,0xc2,0x4d,0x71,0x59,0x5b,0x8d,0x65,0xa7,0x97,0xf4,0x71,0x88,0x7d,0x60,0xe0,0x2d,0x2d,0x09,0x2f,0x26,0x15,0xa7,0xbf,0x30,0x0b,0x99,0x08,0xd7,0x85,0xfc,0x0c,0x19,0x31,0xde,0x5e,0x55,0x91,0x13,0x45 +.byte 0x3a,0x6d,0xd0,0x61,0x02,0x81,0xa0,0x42,0x7d,0xd8,0x7d,0x41,0x11,0xd2,0x25,0xb7,0x15,0xa1,0x16,0x3e,0x70,0x77,0x1b,0x80,0xb7,0xf1,0x24,0x8e,0x70,0x8d,0x73,0x6d,0xba,0xf1,0x46,0x32,0x60,0xe4,0xc8,0x4d,0x69,0xc8,0x10,0xf8,0x2d,0x53,0xe1,0x81,0x96,0x20,0x9d,0x59,0x74,0xae,0x93,0x92,0x44,0x5a,0x09,0x79,0x20,0xcb,0xff,0xb2 +.byte 0x08,0x7a,0x81,0xee,0x98,0x83,0x0b,0xa4,0x15,0xb0,0xaa,0x55,0xb0,0xb5,0x60,0x09,0x21,0xeb,0xe2,0x9b,0x57,0x41,0xb9,0xb4,0xd9,0xbe,0x7d,0x60,0x5d,0x25,0xde,0x9f,0x9e,0x5b,0x7c,0xee,0xeb,0x87,0x54,0x6a,0xc3,0xcf,0xec,0x57,0xce,0x97,0x2e,0x47,0x84,0x4c,0x15,0xf4,0xf5,0xe9,0xd4,0x45,0x23,0x20,0xf0,0x0f,0xda,0x97,0xc2,0xb9 +.byte 0xb2,0xe2,0x44,0xea,0xbd,0x95,0x73,0xcc,0x94,0x03,0x0b,0x97,0xeb,0x03,0xc1,0x51,0xc8,0x14,0xa6,0x7d,0x18,0x30,0xa1,0xda,0xa3,0xcd,0x78,0x67,0xb0,0xc1,0x6c,0x88,0xdd,0xd6,0x52,0x4b,0x85,0x1d,0x4a,0xaa,0x44,0xec,0x3b,0xff,0x00,0xd8,0x9e,0x18,0xf8,0xac,0x4f,0x73,0x6d,0xc7,0x4b,0x59,0x15,0x85,0x87,0x02,0xd8,0xf1,0xe6,0xfb +.byte 0x66,0x57,0xcf,0x06,0x84,0x50,0xc5,0x67,0x94,0xc6,0x96,0xb2,0x1a,0x37,0x06,0x3d,0x21,0xf2,0x1e,0xb4,0xe7,0xcb,0x36,0x8b,0xa3,0xe3,0x84,0xa0,0x9a,0x31,0xdb,0x87,0xf9,0xb0,0xef,0x06,0xfe,0xb0,0x8a,0x32,0x53,0xb4,0x41,0x79,0x6b,0xf7,0x7c,0xf7,0x9c,0xc1,0xea,0x61,0xf3,0x75,0xac,0x1f,0x92,0x75,0x44,0x58,0x9a,0x20,0xa4,0x20 +.byte 0xe3,0x19,0x1c,0x0d,0x27,0xe5,0x2e,0xbd,0x14,0xcb,0x40,0x3f,0x1c,0x19,0x7c,0xf9,0x92,0x13,0x1a,0x71,0x87,0xaf,0x77,0x0f,0x50,0x92,0x06,0x75,0x2d,0x75,0xe0,0x2e,0x37,0x54,0xcd,0xac,0xcb,0xca,0x7c,0x0e,0x66,0x53,0x10,0x50,0x70,0x9a,0xa4,0x79,0x76,0x87,0x71,0x4a,0x55,0xd4,0xa3,0x83,0xb3,0x04,0xed,0xa9,0xd6,0x84,0x7d,0x1a +.byte 0x64,0x5d,0xf7,0x4f,0x55,0x97,0x5e,0x26,0x9c,0x03,0x42,0x0a,0x16,0xd3,0xdf,0xc8,0x07,0xb8,0xb3,0xe9,0xac,0xa9,0x99,0x83,0x32,0x5b,0x83,0xde,0x7f,0x2b,0x70,0xca,0x15,0x09,0x33,0x0e,0x28,0xc9,0x89,0xc6,0xa6,0x47,0xd1,0x56,0x04,0x40,0x5d,0xd2,0x17,0x1d,0x32,0x21,0x6d,0xb2,0xc7,0x89,0x14,0x98,0xc6,0x58,0xc4,0xca,0xda,0x0f +.byte 0x32,0xdd,0xe1,0xe1,0x9a,0x25,0x09,0x31,0x16,0xf1,0x48,0x40,0x1c,0xc2,0xf9,0xd0,0xba,0xec,0x07,0x94,0xea,0x17,0xcf,0x6e,0xbc,0xfd,0x70,0xb4,0xbb,0x40,0xae,0xc3,0xae,0xf7,0x56,0xf5,0x13,0x55,0xfb,0x4b,0x81,0x5d,0xab,0xf2,0x3f,0xd7,0xa7,0xe6,0xcf,0x17,0xef,0x1f,0x71,0x1b,0x92,0x67,0xd3,0xd2,0xed,0x89,0x14,0x8f,0x8d,0x83 +.byte 0xef,0x7f,0xca,0x65,0x6d,0x79,0x13,0x5f,0x6e,0xf9,0x5d,0x9a,0x68,0x54,0x71,0x5c,0x9d,0x03,0x7c,0x73,0x7a,0xc2,0x17,0x9b,0x5a,0x7d,0x45,0x24,0x0c,0x41,0x13,0xe4,0xcb,0xdb,0x7b,0xc6,0xfb,0x93,0x48,0xca,0xd3,0x01,0x68,0x3f,0x36,0xc0,0x4b,0x1d,0xfa,0x9f,0x25,0x0e,0xcc,0xd0,0xf7,0xa0,0x7a,0x14,0xac,0xd7,0x6e,0x00,0x9f,0xf1 +.byte 0xc0,0xdc,0xfc,0x3b,0xd9,0xbf,0x68,0xfd,0x65,0x34,0x66,0x18,0xe5,0x02,0x9a,0x2d,0xff,0xaa,0xf7,0x73,0x58,0x21,0xe3,0xff,0x23,0x0f,0x63,0x1f,0xf3,0x8b,0x08,0xc7,0x00,0x46,0xe7,0xef,0x85,0x5f,0x7f,0xd9,0x5f,0xc2,0x36,0xe2,0xb6,0xa3,0x00,0xcb,0xff,0xe0,0x22,0x28,0x8c,0xb1,0xb1,0x17,0x91,0x4a,0x4a,0xc8,0x77,0x5a,0xa9,0xb2 +.byte 0x6e,0xb7,0xf0,0x4f,0x70,0x34,0x7f,0x87,0x2a,0x0c,0xcb,0x16,0x24,0x9b,0x41,0xb2,0x3e,0x0a,0xc1,0x33,0xf3,0xbb,0x48,0x17,0x2f,0xe6,0xfc,0xf4,0x27,0xc0,0xdb,0x58,0x24,0x9b,0x99,0x43,0x25,0xfb,0xd3,0xcf,0x1c,0x5a,0x5f,0xbe,0x28,0x3a,0x84,0x51,0x19,0xc3,0x53,0x6b,0xc8,0x73,0x44,0x6e,0x3d,0x7e,0x01,0x37,0xc2,0x2b,0xf7,0xa8 +.byte 0x1f,0x8e,0xd8,0x02,0x5a,0xae,0x56,0x81,0x2b,0x46,0x1b,0x7d,0xca,0x27,0x1f,0x48,0x99,0x24,0x54,0x59,0x08,0xfd,0xb7,0xdf,0x0a,0x77,0xef,0x4e,0x89,0x21,0x71,0x71,0x3f,0x8c,0xd7,0x52,0x89,0x7a,0x0d,0x68,0x09,0xc8,0x88,0x9c,0x0c,0x60,0xca,0x77,0x96,0xeb,0x05,0xeb,0xeb,0x60,0x5b,0x68,0x51,0x2c,0xcb,0x8f,0xca,0x3b,0x18,0x39 +.byte 0x28,0x8f,0xda,0x17,0x9b,0x53,0x71,0x26,0xa9,0x19,0xfb,0x1e,0x4a,0xd0,0x14,0x93,0x1c,0xee,0xe1,0x21,0xea,0xb3,0x16,0x47,0xaf,0x50,0xe5,0xe5,0xd3,0x21,0x8c,0x67,0x46,0x5d,0x97,0x19,0xda,0x6e,0xd9,0x70,0x7d,0x9f,0xd6,0x25,0xd0,0xfb,0x01,0x62,0x0a,0x9e,0x49,0x3d,0x33,0x0d,0x35,0xe5,0xae,0xfd,0xeb,0xb5,0x9b,0xd8,0xc1,0x2a +.byte 0xee,0x4d,0xf2,0xfc,0x16,0x51,0xab,0x58,0x7a,0x9e,0x5c,0xca,0x0a,0x92,0xbb,0xbb,0xa8,0x5b,0xfb,0xf9,0x33,0x67,0x0e,0x13,0x4c,0x83,0x3a,0x25,0x84,0x23,0xe1,0x41,0xfb,0xf1,0x42,0xc1,0x8d,0x58,0x0c,0x5e,0x75,0x09,0x34,0x58,0x96,0x32,0x54,0xb6,0xd8,0xaa,0x48,0xc1,0xed,0xc0,0x92,0x5a,0xec,0xeb,0xb1,0x75,0x59,0xf6,0x35,0xf5 +.byte 0xfd,0x7d,0x96,0x9b,0x83,0x38,0x31,0x10,0xa4,0xd7,0xfb,0x28,0xf0,0xc9,0xe4,0x33,0x5d,0x66,0x81,0x9c,0x31,0x9a,0xe9,0x9a,0x5e,0x70,0xf7,0x61,0xf9,0x93,0xaf,0x2b,0xbd,0x78,0x9e,0xdc,0x61,0xe0,0xa9,0xd1,0xa0,0x8e,0x3a,0x5f,0xb1,0x71,0xe7,0x9e,0xfd,0x81,0xee,0xf0,0xd6,0x63,0xec,0x4a,0xca,0x30,0xaf,0xb6,0x2d,0xaa,0x2d,0xa1 +.byte 0x5a,0x38,0xb5,0xc6,0x3f,0x5f,0x63,0x48,0xd3,0x18,0xeb,0xe3,0x36,0xca,0x91,0x86,0x4b,0x6f,0x57,0x66,0x47,0x2f,0xce,0xe4,0x44,0x26,0xe4,0xfd,0x8c,0xde,0x74,0xdc,0x17,0x0e,0x7d,0x6a,0xcf,0x89,0x0e,0x7f,0x09,0x65,0xf8,0xeb,0x58,0x00,0x3d,0xc5,0x1b,0x14,0xc5,0xca,0xca,0x28,0xbc,0xb7,0x63,0x6f,0x3b,0xa4,0x62,0x23,0x0e,0xd5 +.byte 0x04,0x76,0x0c,0xe8,0xea,0x64,0x10,0x3a,0x76,0x03,0xd6,0xea,0x69,0x52,0x14,0xa7,0x5e,0x40,0x7e,0x14,0xdb,0x7f,0xbf,0xe8,0xf6,0xf0,0xdd,0x5e,0xac,0x55,0x44,0xfb,0x28,0xf3,0x16,0xcb,0xed,0x8f,0x10,0x01,0x91,0xac,0x2c,0x27,0x46,0x0c,0x51,0xd6,0xf6,0x30,0xa3,0x34,0xd0,0x5e,0x93,0xe8,0x4e,0xc0,0xb4,0x9b,0xc1,0xe8,0x20,0x7d +.byte 0xb7,0x68,0xdd,0xf1,0xc4,0x60,0x20,0x97,0xdd,0x5c,0x7c,0x9b,0xea,0xc0,0x22,0x84,0x2c,0x65,0x78,0xbd,0x18,0xa1,0x62,0x7e,0x06,0x49,0x96,0xde,0xd1,0x89,0x06,0x0d,0x35,0xa0,0xcc,0x22,0xd3,0xf5,0xa6,0x4b,0xb6,0xca,0x43,0x34,0x5a,0x3d,0x39,0x95,0x0b,0x95,0xbe,0xdc,0xe6,0x61,0x72,0xbe,0x2f,0x19,0x1c,0xe8,0x22,0x5e,0x18,0xc9 +.byte 0x59,0x4a,0x08,0xa3,0x85,0x5c,0x06,0x36,0x00,0x2e,0x84,0x3e,0x3e,0x07,0x5b,0xfa,0xda,0xbb,0xbb,0x57,0x20,0x6f,0x1b,0x8d,0xe5,0xc5,0xdb,0x8d,0x23,0x1a,0xfc,0x67,0xa9,0xc8,0xea,0xe1,0x54,0xbb,0x8a,0x8a,0x0b,0xa6,0x02,0x35,0xd6,0xd5,0x4d,0xff,0x09,0x79,0x31,0x9a,0xc2,0xad,0xa7,0x66,0xb5,0x3c,0xbd,0xb7,0xcb,0x17,0x30,0x4b +.byte 0x56,0xf5,0xd2,0x51,0x90,0xbb,0x47,0x00,0xc0,0xf3,0x8b,0xd7,0x10,0x33,0x6d,0xe8,0xe4,0xcf,0xd6,0xbf,0x35,0x75,0x8d,0x40,0x55,0xd7,0x5d,0xb0,0x40,0xf6,0x95,0xfb,0x1a,0x97,0x24,0xb8,0xc1,0x91,0x5f,0x66,0x6c,0xc7,0xdb,0x16,0xba,0xb8,0x07,0xf8,0xf8,0x91,0xb2,0x8c,0x26,0xb9,0xa2,0x59,0xb0,0xde,0x49,0x63,0xcc,0x7c,0x4c,0x48 +.byte 0xb5,0xe4,0xf9,0x81,0x28,0x48,0x9f,0xa0,0xa4,0xf8,0x0d,0xcc,0x7b,0xf3,0xce,0x08,0x85,0x73,0x4a,0x64,0xfc,0xa8,0xc0,0xae,0x7a,0xbf,0xa5,0x3f,0x45,0xaf,0xe7,0x7f,0x41,0x61,0x34,0x08,0x6e,0x09,0x0d,0x9d,0xea,0x90,0xbe,0x62,0x7c,0x38,0x92,0xa7,0x63,0xfa,0x03,0x80,0x10,0xc4,0x53,0x46,0x0b,0x44,0x88,0xea,0x50,0xb6,0x82,0xf8 +.byte 0x0b,0x2d,0x93,0x63,0x82,0x80,0x2b,0x61,0x3e,0x17,0xd1,0xd8,0x6c,0xb1,0xb4,0xbd,0xfd,0xad,0x1c,0x10,0x30,0xc1,0x78,0xd4,0x5f,0x21,0x49,0x54,0x7a,0x08,0x2b,0x25,0x3b,0xc9,0xb7,0x0a,0xf2,0x37,0x83,0xc0,0x43,0x73,0xee,0xd6,0x8b,0x92,0x15,0xde,0xfe,0x14,0xf1,0xfb,0x8b,0x4a,0x85,0x8d,0x78,0xe6,0x36,0x1a,0xbb,0x32,0x6c,0xdd +.byte 0x43,0x76,0xad,0x68,0x90,0x08,0xd2,0xbd,0x24,0x41,0xd4,0x93,0x17,0xa8,0x9f,0xeb,0x33,0x25,0x1f,0x1a,0xfd,0x45,0x20,0xc1,0x47,0xf1,0x25,0x09,0x89,0x14,0x9e,0x4c,0x88,0xa4,0x1c,0xb8,0xba,0x84,0xd5,0x7d,0x73,0xb2,0x9c,0x48,0x9f,0x84,0x31,0xd3,0x2c,0xe1,0x94,0x61,0x3e,0x5f,0x37,0x25,0xc7,0xb7,0x2d,0xc3,0xa9,0xaf,0xcc,0x0e +.byte 0xe6,0xc7,0x9a,0xa7,0x06,0xe3,0x41,0xb8,0xa6,0xa8,0x9a,0xe7,0x76,0xef,0x83,0x5a,0x80,0xa4,0xe3,0x0c,0x04,0xa2,0x0b,0x91,0x33,0x34,0x17,0xa4,0x02,0x2d,0x12,0x84,0x67,0x85,0x6b,0xc0,0x3a,0x0d,0x16,0xf2,0x66,0x04,0x71,0xe9,0xec,0xa6,0xbb,0x58,0x42,0x92,0x70,0xf5,0x0d,0x52,0xcd,0x1e,0x2d,0xd4,0x28,0x0f,0x68,0x35,0xd9,0xa4 +.byte 0x40,0x09,0x30,0xe9,0xbb,0xaf,0x77,0x63,0x4f,0xba,0x56,0x97,0xe8,0x92,0xcc,0xba,0xdb,0xe4,0xe0,0xdf,0x19,0x21,0x71,0x23,0x3d,0xd0,0xb1,0x25,0xd3,0xf8,0x53,0x01,0x30,0x9a,0xea,0x84,0x1b,0x18,0x68,0x4a,0xb9,0x9e,0x60,0xc4,0xfc,0xf7,0x56,0xb7,0x49,0xe1,0x50,0x38,0x7d,0x3d,0x87,0xa2,0xad,0x38,0x5c,0x0c,0x53,0x21,0xa0,0x56 +.byte 0x3a,0x94,0xd7,0xa8,0x23,0x96,0xa9,0x66,0x4e,0x88,0xae,0x4b,0x6e,0xcb,0xc6,0xa6,0xdb,0x1f,0x2e,0xae,0xe7,0x24,0xe2,0x1e,0xf7,0x3a,0x14,0x48,0x5e,0xfa,0x90,0x0a,0x84,0xa6,0x1c,0xaa,0x60,0xc0,0x2c,0x69,0xe8,0x36,0xb3,0xee,0x55,0x2a,0xf7,0x90,0xa1,0x92,0x4f,0x29,0x1e,0x49,0x6e,0x73,0x22,0x1f,0x8b,0x0c,0xb6,0xf4,0x3c,0xbf +.byte 0x82,0x47,0x49,0xc3,0x94,0x0e,0xcf,0x9b,0x86,0x88,0xc2,0xd0,0xd7,0xa7,0x43,0xfb,0x89,0x4b,0xbd,0x5d,0x4c,0x6b,0x7a,0xc7,0x74,0x1b,0xfb,0x48,0x12,0x68,0x61,0x91,0xf9,0xf3,0xb6,0x7f,0x4f,0x72,0x89,0xf0,0x72,0x46,0xf7,0x6f,0x84,0xd1,0x38,0x6d,0xd9,0x1b,0xa5,0xd1,0xe2,0x29,0xe0,0xa6,0xbf,0x1c,0xbd,0xfb,0xdd,0xdc,0xa5,0xae +.byte 0x7a,0x9c,0xd0,0xc3,0xfa,0x6f,0x72,0xa3,0xa2,0x8b,0x87,0x0d,0x9a,0x6a,0xfc,0x53,0x9a,0x08,0x61,0x86,0x67,0x2a,0x90,0x6a,0x09,0x20,0x8e,0xde,0x32,0x35,0x34,0x75,0xc0,0xa8,0xab,0x1b,0xc4,0x7c,0xc8,0xd9,0x90,0xcf,0x32,0x27,0x6c,0x68,0xf9,0x18,0x14,0x05,0x57,0x39,0xc6,0x9e,0x5e,0x38,0x07,0xdb,0x81,0xb4,0xa4,0x54,0x06,0xd6 +.byte 0x79,0x78,0x0e,0xc8,0xb9,0x56,0xda,0x08,0x2e,0x77,0x26,0xcc,0xf7,0xa5,0x2d,0xd8,0x91,0xa6,0xfc,0x25,0x0e,0x91,0xdd,0x3c,0xa8,0x14,0x7a,0x95,0x05,0x5b,0x15,0x7d,0x1d,0x9b,0x3c,0x8c,0xfd,0xdc,0xa5,0xcd,0xec,0xea,0x7a,0x2b,0x7e,0x79,0x21,0x54,0xea,0x7f,0x52,0xb4,0xbb,0x4f,0x07,0x95,0x39,0x4a,0xaf,0x2e,0xb4,0x1e,0x9e,0xc6 +.byte 0x0a,0x07,0x58,0xd4,0xa5,0x44,0x73,0xa8,0x84,0x26,0x67,0xb8,0x0f,0xc7,0x6b,0xa7,0x28,0xf6,0x05,0x91,0x3e,0x22,0xcd,0xd7,0xf5,0xfc,0xae,0x22,0x42,0x96,0x3b,0x57,0x91,0xce,0x44,0xd0,0xfd,0xc3,0x4c,0x8b,0x8b,0x67,0xfe,0x03,0x86,0x92,0x34,0xf7,0xf9,0x53,0xb3,0xdf,0x36,0xcf,0x16,0x1c,0x68,0x36,0x17,0x1f,0x41,0x56,0x1d,0xda +.byte 0x90,0xb3,0xab,0x03,0x97,0x88,0x23,0x65,0x89,0x72,0xe3,0x6d,0x8e,0x37,0x5d,0xee,0x89,0x81,0x11,0x27,0x8b,0xf0,0x9b,0xef,0xa2,0x34,0x45,0xcc,0x41,0xcf,0x2a,0x88,0x70,0xe4,0x78,0xfc,0xe1,0xb5,0x51,0x70,0x84,0x64,0xd1,0x10,0x71,0x5d,0xa4,0xb4,0x6d,0xb5,0x98,0x6e,0xcc,0x9a,0x62,0x14,0x30,0xce,0x1a,0xff,0x49,0xd6,0xaa,0xcc +.byte 0xe1,0x99,0x42,0xb1,0xfe,0x77,0x8a,0x2d,0xdb,0xc0,0x0d,0x50,0x53,0x0d,0x92,0xe5,0x2b,0xd0,0x78,0x83,0x08,0x4a,0x0c,0x1d,0x5b,0x03,0x22,0x65,0x3d,0x9e,0xdb,0xcf,0x01,0x61,0xf7,0x6d,0x2b,0x99,0xef,0xba,0x80,0x50,0xda,0xda,0x2d,0xbf,0x00,0xdf,0x6f,0xec,0x95,0xbc,0x5b,0x4e,0xda,0x83,0xe4,0x5d,0xf0,0xa7,0x1b,0x27,0xf1,0x76 +.byte 0x04,0x5d,0x3d,0x2c,0x12,0x15,0xad,0xef,0x47,0xdc,0x22,0x9b,0xc2,0x80,0x91,0xf3,0xbf,0x16,0xe9,0xd3,0x35,0x94,0x4b,0xfd,0xa3,0xa1,0xee,0x98,0xad,0x99,0xea,0x07,0xe1,0x0f,0xa7,0xbd,0x0b,0xfb,0xc0,0xd5,0xb0,0x49,0x37,0xc6,0x5f,0xe7,0x18,0xc1,0x60,0xe9,0x1d,0x5e,0x0e,0xea,0x73,0xf2,0xa1,0x75,0x7e,0x39,0x51,0x07,0x1e,0xcb +.byte 0x2a,0x5b,0x26,0x75,0xbe,0x02,0x5e,0xde,0x6c,0x37,0xb1,0x3c,0x1f,0x25,0x65,0x7d,0x9e,0x5d,0xa1,0x0b,0x98,0x27,0x53,0xb9,0xbb,0xc2,0x3e,0x8d,0x2d,0x5e,0x5c,0xbf,0xed,0x66,0xe8,0xd1,0x7d,0xaa,0xef,0xca,0x0e,0xd0,0x78,0x2b,0x89,0x07,0x76,0xb6,0xc3,0x92,0x42,0x3a,0x84,0x1d,0x81,0xc1,0xe8,0x1a,0xb8,0xe6,0xf1,0x43,0xcc,0x7a +.byte 0x59,0x4d,0x9f,0x00,0xfe,0x6a,0xe5,0x42,0x71,0x3c,0xcb,0xc8,0x45,0x18,0xf0,0xf2,0x81,0x9d,0x5a,0xb7,0x8d,0xbe,0x31,0xcb,0x7d,0xca,0xb7,0x19,0x57,0xb1,0x61,0x36,0x90,0x42,0xe2,0xc3,0xf5,0xa5,0x4b,0xc3,0xd4,0xe7,0x6c,0xb6,0x0c,0x06,0x19,0x4b,0x54,0x8f,0x2d,0xdc,0xc5,0x2b,0xff,0x1c,0x61,0x29,0xda,0x95,0x4f,0xa1,0x21,0x25 +.byte 0x24,0xbe,0xc7,0x34,0x2f,0xbf,0x33,0x6d,0x82,0x8f,0xf1,0xa9,0x97,0x5a,0x49,0x7f,0x60,0x00,0xf2,0x3e,0x7b,0x64,0xdf,0xc8,0xd3,0x5f,0x6e,0x1f,0xfb,0x71,0x80,0xf3,0x55,0x42,0xbe,0x32,0x7b,0xa9,0xeb,0xf6,0x31,0xe2,0xf0,0xd1,0xe9,0xbe,0x96,0x0e,0xb3,0xdf,0x3e,0xb2,0x2c,0xc3,0xce,0xbd,0xe7,0xfe,0x1c,0xed,0x2c,0x0b,0xaa,0x32 +.byte 0x76,0x82,0xb4,0x6b,0x18,0xa7,0x68,0x19,0xb7,0x27,0x21,0x4c,0xb0,0x22,0x98,0x58,0xd5,0x90,0x80,0xab,0xa1,0xfe,0x83,0xc5,0x66,0xf6,0x3e,0xa2,0xa9,0x6f,0x73,0xce,0x7f,0x0c,0xe6,0xde,0xee,0xb0,0xe6,0x2a,0xcc,0xcc,0xb0,0x53,0x8c,0xce,0xc8,0xdc,0xea,0x83,0xb4,0x0e,0x69,0x8d,0x90,0x86,0xaa,0xe3,0x3b,0xfb,0x88,0xe2,0xe8,0x27 +.byte 0x65,0x36,0x07,0xb3,0x91,0x0e,0x5a,0x6b,0x9f,0x0f,0xbd,0x81,0xb3,0x54,0x65,0x71,0xa4,0x2c,0x8e,0xda,0x47,0x04,0xce,0xfe,0x00,0x52,0xf1,0xdf,0x82,0x27,0x70,0x2a,0xb1,0x79,0x2f,0x27,0x7f,0xae,0x9e,0x5c,0x36,0xec,0xa0,0x2a,0xf3,0x74,0x78,0x01,0x17,0x74,0x2a,0x21,0x4f,0xb8,0xd2,0xe4,0xfe,0x5b,0x06,0x14,0xa5,0xb1,0xb1,0xff +.byte 0xee,0x79,0xf7,0x18,0xb9,0x31,0xa4,0x63,0x47,0x1c,0xdf,0x38,0x04,0x2d,0x18,0xca,0x14,0xf8,0x2f,0xec,0x0d,0x58,0xad,0xbb,0xf4,0x45,0x11,0x0e,0xfa,0x17,0x4c,0x5e,0xd4,0xa6,0xde,0xe4,0x13,0x44,0x2c,0xb9,0xfd,0xcd,0x41,0xe7,0xf9,0xda,0xbc,0x28,0x8f,0x0c,0x41,0x4d,0xa7,0x0d,0xf5,0x96,0xd7,0x8f,0x10,0x96,0xfb,0x75,0x75,0x86 +.byte 0xc9,0x6e,0x23,0x92,0x71,0x69,0x7b,0x94,0x61,0x1c,0x3f,0xcf,0x66,0x34,0x62,0x68,0x5d,0xee,0x7b,0x34,0x5d,0x2a,0x39,0xbb,0x6a,0x34,0xea,0x6e,0xe3,0xe9,0xdb,0xe4,0x34,0x6e,0x29,0x0b,0x21,0x38,0xe7,0x5b,0x79,0x37,0x54,0xf0,0xed,0xaa,0x07,0x2b,0x21,0x29,0x67,0xfe,0x7d,0xa5,0x99,0x0e,0x5d,0x05,0xe7,0x61,0x6e,0xd1,0x4a,0x15 +.byte 0x4a,0x56,0xb1,0x13,0x49,0x8c,0xf4,0x4f,0xd7,0xe9,0x68,0xae,0x09,0x37,0xd3,0x96,0x21,0xe8,0x1f,0x9f,0xa9,0xc6,0x54,0x57,0x63,0x09,0x1e,0x71,0xf2,0x48,0x9e,0x50,0xbb,0xb3,0xf1,0x4e,0x2d,0x1d,0x79,0x69,0x0a,0xa2,0xa9,0xdd,0x1b,0x55,0x62,0x6b,0x0d,0xcc,0x9c,0xb1,0x5e,0xc8,0x4c,0x4f,0x62,0x3c,0xc4,0xa3,0xb4,0xe4,0x34,0xec +.byte 0x9d,0x0c,0x1b,0x46,0x60,0x68,0xd5,0x04,0xd7,0x1b,0x3c,0x7a,0x98,0x0c,0xd9,0x87,0x2b,0x4f,0x97,0x5b,0x56,0x65,0xb0,0x06,0x6e,0x9e,0x06,0x37,0x0e,0xd2,0xa1,0x52,0xf5,0xaa,0x2b,0xec,0xbd,0x0f,0xb6,0xba,0x48,0x63,0x57,0x51,0xe3,0x00,0x53,0xf5,0x77,0xb2,0xa4,0xb1,0x44,0x01,0x3e,0xcf,0xe9,0x2a,0x7a,0xf5,0x19,0x5e,0x43,0x36 +.byte 0xe0,0x38,0x41,0xbc,0xda,0xb5,0xd0,0x69,0xdf,0xd2,0x04,0xd4,0xf8,0x38,0x37,0x1c,0x90,0x30,0xf2,0x3d,0x03,0xe4,0x3f,0x84,0x2c,0x9a,0xa4,0x8a,0x00,0x4e,0x49,0x24,0x62,0x06,0xb4,0x9d,0x33,0x8a,0x8e,0xd2,0xbd,0x1b,0xa1,0x83,0x0b,0xa5,0xa2,0x5c,0xcf,0xb1,0x65,0x85,0x92,0x1f,0xb0,0x2e,0x3b,0xb2,0xf3,0x80,0xff,0x9d,0x41,0x4d +.byte 0xcd,0x25,0x09,0x02,0x85,0xb3,0xa8,0x49,0x12,0x10,0xe7,0x5c,0x94,0x13,0x4b,0x52,0x53,0x35,0x9c,0xbc,0x7a,0xad,0x04,0x19,0x54,0x8a,0xbc,0x42,0x73,0xf1,0x0a,0x22,0x75,0xbf,0x3b,0x12,0xa8,0xa4,0x47,0x5c,0x95,0x48,0x60,0x71,0x5c,0x9a,0x39,0x5c,0xdb,0x44,0xe8,0x74,0x92,0x3e,0x2b,0x3b,0x1b,0xb7,0x21,0x98,0xe1,0x87,0x32,0xaf +.byte 0x4a,0xe3,0xda,0x4a,0x46,0xde,0x15,0x4c,0xdc,0xc6,0x60,0xe6,0xd7,0x92,0x29,0x05,0x21,0x22,0x9b,0xaf,0xc4,0xd7,0x6a,0xea,0x2c,0x82,0x5d,0xc7,0x81,0xe2,0x67,0x85,0xd2,0x16,0x6f,0x83,0xa8,0x82,0x5f,0x8f,0xf5,0x3a,0x50,0xba,0x04,0xcb,0x76,0x4d,0x80,0x16,0x12,0x72,0xa8,0x6c,0xac,0x78,0xf1,0x8c,0x93,0xab,0xe0,0xb5,0xdc,0xd1 +.byte 0xa5,0x40,0x0e,0x50,0x88,0xd2,0x9d,0x56,0xf6,0xa0,0xd4,0x45,0xcf,0xef,0x16,0x1a,0xa4,0xaa,0x91,0x5c,0xa3,0x8f,0x84,0xf8,0x3e,0x30,0x1f,0x5f,0x55,0xf9,0xd3,0x3d,0xb8,0x64,0xbb,0x3c,0x91,0xe4,0x0d,0xa5,0x43,0x14,0x75,0xe7,0xec,0x8c,0x12,0x56,0x34,0xb0,0xa9,0xae,0x93,0x91,0x34,0xfc,0x78,0xa3,0x81,0x51,0x45,0x7d,0x9f,0x7d +.byte 0x5e,0xc7,0x5e,0x51,0x17,0xfa,0x02,0x5d,0xb2,0xf7,0x79,0x4b,0x49,0xd2,0x1b,0x6f,0xfd,0x9e,0xff,0x75,0x74,0xf0,0x26,0x7e,0xd7,0x65,0xb0,0xf3,0x0a,0x0c,0xd2,0xa2,0x26,0x98,0x03,0x26,0xb5,0x67,0xc4,0xc0,0xed,0x80,0xd4,0x20,0xf6,0x7e,0x17,0x54,0xeb,0xde,0xc3,0x86,0x51,0xda,0xf7,0xe5,0xc7,0xfe,0xfc,0x71,0x83,0x80,0xbe,0xde +.byte 0x4b,0xda,0x83,0x76,0x63,0x04,0x03,0xdd,0xe0,0xe0,0x4e,0xb6,0x32,0xd5,0xd0,0xce,0xd7,0xaa,0xcd,0x5f,0x64,0xa6,0xd8,0x9e,0xc5,0x97,0x30,0xad,0xf1,0x82,0x8f,0x7c,0x18,0xec,0x30,0x1d,0x2d,0xb6,0xdb,0x33,0x65,0xed,0xe2,0x24,0xd8,0xba,0x0a,0x1f,0x79,0x2a,0x1c,0xe1,0x4e,0x04,0xa6,0x74,0x74,0x37,0x42,0x94,0xc4,0x99,0x0e,0xf8 +.byte 0x3f,0xf3,0xff,0xeb,0x7f,0x95,0x9c,0x47,0x56,0x68,0x6a,0x0d,0x6e,0x66,0x71,0x3b,0x51,0xd5,0x12,0x7e,0x59,0x39,0x43,0xb5,0x53,0xd3,0x1d,0xa2,0xe9,0xa1,0xc8,0x8d,0xf2,0x8e,0xa1,0x9c,0x36,0xdd,0xda,0xd3,0x61,0xd8,0xe9,0x76,0x5e,0xcb,0x0a,0x52,0xc8,0x5a,0x25,0x00,0x21,0xea,0x6a,0x96,0xde,0x02,0x76,0x02,0x63,0x73,0x28,0x63 +.byte 0x46,0x37,0xe1,0x75,0x2f,0x42,0x8f,0xee,0x2c,0x84,0x82,0x43,0x43,0x2d,0xa9,0x13,0x50,0x46,0x54,0xed,0x76,0xbd,0x10,0x1c,0x9b,0xa1,0x42,0x97,0x68,0xca,0x84,0x2e,0x1d,0x6f,0x86,0x67,0xaf,0xb7,0x20,0xc1,0x7c,0xab,0x70,0x20,0xa1,0x79,0x71,0xe4,0xb7,0x45,0x8a,0x04,0xd3,0x70,0x10,0xa8,0x28,0xc3,0x56,0xff,0x43,0x36,0x13,0x88 +.byte 0xb6,0x2d,0xfd,0x7f,0xbc,0xc9,0x1d,0x11,0x9a,0x7c,0xd0,0xfc,0x11,0xac,0x54,0xd5,0xc3,0x03,0xd1,0xe3,0x9e,0xff,0x03,0xdb,0xd9,0xd8,0x77,0x96,0x08,0xf4,0x1b,0xd9,0xfa,0x70,0xed,0xab,0x53,0x78,0xca,0x28,0xa7,0x29,0x49,0x45,0x37,0x10,0x8f,0x61,0x7d,0x11,0x99,0x2e,0xe8,0x5d,0x45,0x3a,0xe7,0xd2,0x6c,0xb6,0x03,0xc4,0x6d,0xaa +.byte 0x52,0x60,0x8c,0xc6,0x9c,0x17,0xba,0xf6,0x3b,0xd4,0x4b,0x26,0x63,0x92,0x8c,0xb9,0x6a,0xf2,0x26,0x91,0x9d,0x8d,0x99,0x39,0x26,0x7d,0xb5,0x4f,0x4c,0xc6,0x0e,0x2e,0xe1,0xc6,0xcb,0x98,0x93,0x71,0x9b,0xaa,0x01,0x40,0x70,0x93,0x2a,0xe8,0x27,0xc5,0x20,0xa7,0xd2,0x06,0x8b,0xb0,0x29,0xcd,0x4f,0x2c,0x5a,0xde,0x35,0xc7,0x2a,0x8e +.byte 0xa7,0xae,0x02,0xfa,0x8e,0x4d,0xf3,0x77,0x67,0xe0,0xcb,0x84,0x69,0xc6,0x05,0xe4,0x84,0xe3,0x6e,0x02,0x6c,0x3b,0x93,0x30,0x3e,0x89,0x2c,0xc7,0xa5,0x7e,0xaa,0x58,0x59,0x25,0xf6,0xff,0x56,0x9a,0x4a,0x70,0xbf,0x88,0x20,0x8d,0x51,0x5e,0x08,0x13,0x26,0x2c,0x5d,0x88,0x13,0x3e,0x32,0x7a,0xf6,0x17,0x5c,0xdb,0xc4,0xcd,0x5a,0x16 +.byte 0x65,0xe4,0x34,0xeb,0x21,0x6d,0xb9,0x30,0x5d,0xc0,0xa2,0xea,0x4f,0x63,0x0e,0xbe,0x32,0x91,0x89,0x6f,0x96,0x40,0xf3,0x5f,0xa3,0xf2,0x15,0xc3,0x3c,0x3c,0xb8,0x2f,0x0d,0xc2,0xcd,0x4e,0xa0,0xa5,0xf6,0x78,0x40,0x0b,0x90,0x11,0x52,0xff,0x8f,0x7f,0x6a,0x0c,0xd6,0x3b,0x64,0x80,0x47,0xfa,0x70,0xbe,0x01,0xdc,0xdf,0x5b,0x75,0x7c +.byte 0xca,0x66,0xf0,0x2a,0x53,0x89,0x55,0x87,0xf8,0xec,0xd1,0x18,0x22,0x0c,0xd5,0x0e,0xc8,0x1c,0xbc,0x1e,0x66,0x14,0x44,0x10,0x3c,0xd4,0x2e,0xca,0x0b,0xd8,0x3f,0x81,0xd8,0x9f,0x81,0xf6,0x62,0x23,0xe4,0xc7,0x0d,0xb0,0x1b,0x00,0xd8,0xf4,0x1a,0xdd,0x9b,0xa1,0x74,0xeb,0xf0,0x65,0x5c,0x82,0x00,0x17,0xa6,0x68,0x29,0xd5,0xa4,0x64 +.byte 0xd3,0x15,0x90,0xd0,0x91,0x17,0xfc,0xd2,0xd7,0xad,0x4b,0xd8,0x41,0x03,0x51,0xfd,0x61,0xac,0x34,0xd4,0xff,0xaa,0xb1,0x64,0x6c,0x79,0x78,0xf7,0x6b,0x18,0x03,0x2b,0x6b,0x9a,0xd7,0xce,0x55,0x6e,0xdd,0xab,0x2e,0xbc,0x27,0x3a,0x8c,0xa5,0x8d,0xf0,0x55,0x81,0x0c,0x6e,0x8d,0xd8,0xd2,0x24,0x5e,0x2e,0x56,0xa8,0x1e,0x9c,0x98,0x88 +.byte 0xd3,0xbe,0x90,0x56,0x70,0xe5,0xcc,0x49,0x2a,0x13,0x98,0x99,0xbd,0xc9,0x9f,0x53,0x85,0x07,0xbe,0x54,0xa7,0x4c,0xd6,0x96,0x7d,0x8f,0x24,0x79,0x67,0xb2,0x62,0x4c,0x6a,0xc1,0x6c,0xb7,0xdc,0xe9,0x21,0xe3,0x27,0xc7,0x53,0xff,0xe7,0xd1,0xea,0x60,0xa8,0x56,0x08,0x5c,0x29,0x0a,0x04,0x0c,0xda,0x7a,0x70,0x8c,0x3d,0x55,0x3f,0xcf +.byte 0x9e,0xea,0x74,0x8b,0xbc,0xf0,0xf1,0x3a,0x86,0x22,0xe5,0x54,0xa7,0x70,0xc2,0xcd,0xb8,0x9f,0x4e,0x9f,0x48,0xa8,0xc0,0x82,0x0d,0x73,0x8b,0x3c,0xfc,0x20,0xf4,0xbe,0x79,0xde,0x8e,0x3c,0x26,0x85,0xde,0x74,0xd1,0xe3,0xd5,0x8f,0x39,0x71,0x46,0x8c,0xbd,0x68,0x28,0x2d,0x36,0x0d,0x66,0xc1,0x0b,0x96,0x3e,0x11,0x2e,0x44,0x17,0xd5 +.byte 0xfe,0x0d,0x70,0x84,0x96,0x20,0x34,0x2f,0xbe,0xf0,0xf5,0x9b,0xb4,0x5a,0xa9,0x50,0x6a,0xda,0xdb,0x69,0xea,0xef,0xa9,0xaa,0x06,0xc0,0x68,0xa4,0x61,0x1b,0x4b,0xf8,0x0b,0x56,0x91,0xc8,0x6f,0x39,0x15,0xe2,0xcc,0xbf,0x2b,0x36,0x96,0x0c,0x84,0xfb,0x3d,0x4b,0x09,0xe3,0xc2,0x4b,0x05,0x5e,0xfa,0x30,0x75,0xc5,0x54,0xa5,0xbd,0x45 +.byte 0x1e,0x14,0x72,0xd6,0xfd,0xe0,0x8f,0x7b,0x46,0x9b,0x11,0x07,0x27,0x03,0xe1,0x2d,0xcc,0x0a,0x01,0x49,0x61,0xc4,0x61,0x78,0x06,0x5f,0xaa,0x01,0x5b,0x68,0xd7,0x29,0xb4,0x9e,0xd3,0xaf,0xc7,0x45,0xf0,0x23,0xaf,0x28,0xcd,0x96,0x23,0x61,0xb2,0xb4,0x21,0x96,0x5d,0x91,0x3e,0x71,0xb5,0x41,0xf1,0x29,0xf4,0x5b,0x45,0x77,0x16,0x00 +.byte 0x9d,0x39,0x2a,0x1c,0x38,0x6d,0x36,0x97,0x98,0x4c,0x84,0xfc,0xf5,0xf1,0x59,0x7a,0x8c,0x21,0xfb,0xbc,0x9b,0x0c,0x8d,0x60,0xb6,0xc4,0xe3,0x4b,0x33,0x4f,0x04,0x4c,0x27,0xd2,0xa0,0xe1,0x71,0x0b,0x6d,0x40,0x8d,0xba,0xb3,0x11,0x9b,0x07,0x97,0x82,0x01,0x47,0xaa,0x2a,0xd4,0xcc,0x02,0xd3,0x86,0x86,0xb5,0xd7,0x5d,0xbc,0xd0,0x0f +.byte 0x97,0x5c,0xe5,0xac,0xc6,0x53,0xb3,0x39,0x09,0x68,0x2e,0xcc,0xf3,0x43,0xba,0xed,0x15,0x90,0xbe,0x9d,0xeb,0xa4,0xfb,0x4a,0x20,0xcf,0x10,0xb9,0x47,0x99,0xb0,0x89,0x26,0xb9,0xbd,0x4b,0xf6,0xa5,0xbd,0x2f,0xad,0x1a,0x75,0xe8,0xff,0xc6,0x6b,0x6a,0x31,0xbe,0xec,0xd2,0xc4,0x39,0x9e,0x3b,0x05,0x3f,0x24,0xba,0xf1,0x4d,0x0c,0x0c +.byte 0x05,0x60,0x60,0x22,0x0c,0x1b,0x0b,0x6c,0x80,0xd5,0xe8,0x8f,0x81,0xee,0x80,0x41,0x4a,0x69,0x47,0xc6,0x4c,0xeb,0xf6,0x2b,0x91,0x7c,0x9f,0x22,0x74,0x7b,0x43,0x95,0x56,0x55,0xba,0x85,0x23,0xb3,0xc3,0xee,0x6a,0xcc,0x49,0x2c,0x6c,0x86,0x6d,0x60,0x5d,0x84,0x0c,0x3c,0x88,0x61,0x58,0x1d,0xfc,0x00,0x2c,0x84,0x49,0x4d,0x95,0x75 +.byte 0xc0,0x03,0x02,0x59,0xc0,0xe9,0x84,0xea,0xce,0x3f,0x8b,0x76,0xbf,0x19,0xaa,0x13,0x1b,0x8d,0x9f,0xb2,0xeb,0xb3,0x02,0x87,0xee,0xfe,0x73,0xdb,0xc4,0x19,0x27,0xaf,0x15,0x8d,0xf4,0x58,0x97,0x43,0xb9,0x45,0x32,0x5f,0x24,0x2d,0x08,0xfe,0xec,0xf2,0xf1,0x34,0x99,0x7a,0x66,0x44,0x3d,0xd4,0xf7,0x82,0xcf,0xca,0x6f,0x53,0x9f,0x0a +.byte 0x74,0x79,0x9b,0x45,0x5b,0x07,0x92,0x35,0xc6,0xf4,0xd1,0x90,0x2b,0x62,0xec,0x93,0x7b,0x05,0x90,0x75,0xb7,0xb6,0xd9,0x6c,0x30,0xdd,0x9b,0x2a,0x32,0xb1,0xba,0xab,0x1a,0x6c,0x2b,0xd8,0xfb,0x39,0x8e,0x80,0x98,0x6c,0xd0,0xb3,0xf3,0x76,0xe2,0xe6,0x5e,0xee,0xd0,0x29,0xd7,0x57,0x8f,0xc3,0x13,0xcb,0x45,0x90,0x3e,0xa2,0x54,0x88 +.byte 0xd5,0x50,0xd3,0x75,0xed,0x2d,0xa6,0x50,0x11,0x6b,0xb0,0xb6,0xf0,0x1d,0xc9,0x3d,0x1d,0x2a,0xda,0x5e,0x43,0x44,0xf4,0xef,0x3e,0xc7,0xa9,0xe0,0x6d,0x3c,0x38,0xbf,0x84,0x72,0xaf,0xea,0x60,0x15,0x03,0x14,0x77,0xb7,0xb3,0x15,0x4c,0xbc,0xbf,0x55,0x86,0x24,0x73,0x97,0x22,0x9d,0x59,0xa0,0x39,0x76,0x38,0xd1,0x1f,0x25,0xb0,0x64 +.byte 0xf3,0x10,0x67,0xf2,0x7c,0x11,0xf2,0xce,0xbe,0xaf,0x5e,0x2e,0xc5,0xc1,0x01,0xfa,0x80,0xf9,0x87,0xfc,0x5c,0xfd,0x66,0x50,0x01,0xc2,0x00,0x92,0x84,0x0f,0xdc,0xfc,0x10,0xa5,0x6e,0x45,0xf5,0xff,0x58,0x78,0x45,0x5e,0x50,0xbe,0xe3,0xc7,0x25,0x1e,0xdf,0x7f,0x68,0x6f,0xa5,0xb8,0xf8,0x69,0x89,0x5a,0x55,0x65,0xf4,0x96,0xe5,0x7a +.byte 0xa6,0x89,0x69,0x8d,0xdd,0x4f,0x24,0x5a,0x29,0x92,0x1e,0xca,0x74,0x65,0x7f,0xb8,0x32,0x75,0xb5,0x7b,0x15,0xea,0xeb,0xcc,0xf1,0x23,0x69,0xc7,0x58,0x1c,0x3a,0xaa,0x27,0x0a,0x11,0x79,0xcf,0xc9,0xb6,0xbd,0x9d,0x56,0x47,0x36,0x6b,0x7f,0x82,0xb5,0xa7,0x9f,0x79,0x72,0x16,0xba,0x50,0xef,0x37,0x68,0xdf,0xe0,0xd8,0x0c,0x16,0xcc +.byte 0x50,0x6c,0x25,0x63,0xc2,0xd6,0x7b,0xef,0xd9,0xa1,0xef,0x62,0x81,0x97,0x51,0x49,0x69,0xe3,0x13,0x6c,0x1a,0xd0,0x64,0x1b,0x3e,0x48,0x25,0x5b,0x34,0xe9,0xee,0x41,0x34,0xfb,0x8e,0x9d,0x3c,0xbc,0xc8,0xcf,0xe7,0xf8,0x72,0x21,0x0f,0x95,0xde,0x57,0xd7,0x2f,0x80,0x97,0xbd,0x8f,0x2c,0xde,0x19,0xa3,0xba,0x5c,0x92,0xa3,0x75,0x83 +.byte 0xe3,0xc9,0x33,0x3f,0x8f,0x09,0xfa,0x0b,0x60,0x0a,0x2f,0xb3,0x45,0x9d,0x8e,0x9d,0xa3,0x66,0x2d,0xda,0x37,0xe0,0x21,0x52,0x74,0x9d,0x59,0xa4,0x9e,0xea,0x15,0x22,0xb0,0xbf,0x3c,0xd4,0x59,0xef,0x27,0x60,0xf7,0xbf,0x5d,0x1d,0x36,0x9a,0xa5,0xfb,0x53,0x90,0x40,0x83,0x3a,0x20,0x3d,0x6b,0x47,0xbc,0xc3,0xe6,0x07,0xfe,0xd0,0x8e +.byte 0x40,0x42,0x65,0x2b,0x27,0xba,0x69,0x61,0x03,0x36,0x58,0x35,0x7e,0x82,0x53,0xb5,0xe2,0x25,0x31,0xc3,0x77,0xc1,0x91,0x13,0xa4,0x92,0x52,0xea,0x9f,0x43,0x44,0x6b,0x43,0xe9,0x11,0xd4,0x3d,0x53,0xba,0x6b,0x96,0xb5,0x96,0x29,0xa3,0x2a,0x0a,0xf2,0xb5,0x0c,0x5d,0x62,0x37,0xe0,0xd6,0xa2,0xbf,0xcd,0xf9,0x58,0x7f,0xa2,0xfd,0x54 +.byte 0x6a,0xa1,0x90,0xa5,0x61,0x9e,0xa6,0xc2,0xb9,0x80,0x7a,0xb8,0xaf,0x60,0x68,0xa7,0x27,0x77,0x41,0x03,0x4e,0xc1,0x96,0x46,0x23,0x1b,0xff,0xa1,0x37,0x28,0x33,0x27,0xc2,0x99,0xf7,0xcb,0x7f,0x1a,0xfb,0x41,0xc3,0x59,0x11,0xf8,0x39,0x50,0xbd,0x90,0x61,0x4a,0x67,0x4a,0x07,0x5f,0xb1,0x07,0x66,0x0b,0x52,0xad,0x90,0xc2,0xd7,0x4e +.byte 0x42,0x9e,0xcc,0x5c,0xeb,0xf2,0xdc,0xaa,0x52,0xcf,0x0e,0x7d,0xae,0x3e,0x1a,0x2c,0x9e,0x79,0xfb,0x29,0x10,0x29,0x61,0xa4,0x93,0x9d,0xa9,0xe9,0x71,0xc5,0xf7,0x07,0x13,0xe9,0xbd,0x2e,0x2d,0x0c,0xd6,0xaf,0x54,0x48,0x58,0xc2,0x91,0x37,0xf4,0x61,0x3a,0x96,0x81,0xdc,0x82,0x02,0xff,0xc9,0xf7,0xf7,0x9f,0x9f,0x28,0xd1,0xb1,0xe3 +.byte 0x2b,0x3d,0x85,0xef,0x15,0x82,0x3b,0x9a,0x17,0xee,0x7f,0xd3,0xa5,0x7c,0x41,0x27,0xc9,0x4c,0xe9,0x7a,0x30,0x9f,0xc5,0x34,0xaf,0xc8,0x1c,0x8a,0x7c,0xa6,0xf4,0xdc,0xa6,0xdb,0x68,0xc1,0xa1,0x13,0xb0,0x54,0x49,0x25,0x43,0xc0,0xd4,0x93,0xd6,0x70,0x53,0x3e,0x5f,0xd5,0x42,0x6e,0x78,0xb8,0x15,0x07,0x6a,0x91,0xe8,0xf1,0x2f,0xcf +.byte 0x07,0x84,0x25,0xb3,0x20,0xb9,0x35,0x25,0xbb,0x26,0x96,0x02,0x25,0xd5,0x83,0x23,0x71,0x6d,0x62,0xa7,0x99,0x73,0x63,0x2a,0x51,0x25,0x34,0x3d,0x51,0x95,0xc7,0x9b,0x01,0x0a,0xab,0x11,0xb2,0x32,0xcd,0xe3,0xef,0x63,0xa4,0x6d,0xdb,0x7b,0xf6,0x5f,0xc5,0xf3,0xe5,0x8c,0x6b,0x0a,0x04,0x33,0x53,0x0d,0xf6,0x13,0x8c,0xb8,0xc7,0xba +.byte 0xc2,0xf0,0xd4,0xa7,0x1a,0xce,0x7c,0x54,0x72,0x2b,0x89,0xf4,0x05,0x5c,0x30,0x42,0xe5,0x58,0x65,0x3a,0x2e,0xf9,0x40,0xab,0x2b,0xf9,0xc3,0x99,0x40,0x3c,0xb1,0x7b,0x2c,0xdc,0xfe,0x41,0x21,0x71,0x00,0x75,0xbd,0xea,0xf3,0x84,0x88,0x6b,0x9c,0xe2,0x80,0x2f,0xad,0x9f,0x9d,0x0a,0xdf,0xb5,0x38,0x61,0x89,0xfb,0x67,0x45,0x9c,0x39 +.byte 0xf9,0x84,0x54,0xc4,0xd6,0x6f,0x00,0x39,0x90,0x82,0xfa,0xce,0xae,0xe8,0xaf,0xa4,0x97,0x3a,0xfe,0x71,0xaf,0x5e,0x00,0xd1,0x9e,0x33,0x41,0x63,0xca,0xa5,0x5a,0x8b,0x09,0x2a,0x26,0xef,0x96,0xb7,0x5d,0xc4,0x92,0xfa,0x51,0xdb,0x1d,0x63,0x5f,0x7c,0x94,0x53,0x84,0xed,0xa3,0x99,0x07,0x9f,0xdc,0x55,0xb3,0x31,0x67,0x1a,0x63,0x05 +.byte 0xec,0x36,0x79,0x57,0xf8,0x39,0xc3,0xdd,0xd5,0x6a,0x21,0xfc,0x54,0xe6,0x28,0xc4,0xf1,0xd2,0xce,0x02,0x43,0x50,0x30,0x15,0x4d,0x3c,0xd0,0x1c,0xf6,0x7e,0xd0,0xa4,0x86,0xe7,0xf5,0xc2,0x06,0xc5,0xc4,0xa8,0xe2,0xd3,0xc7,0xcf,0xbd,0xab,0x9f,0xe3,0x42,0xc4,0xcd,0x65,0xfa,0xd3,0xcd,0xdf,0x55,0xc4,0xce,0x6e,0xe8,0xfc,0x96,0x0f +.byte 0xe2,0x92,0xca,0xde,0x37,0x7c,0xc9,0x80,0x4a,0x54,0xe9,0xfd,0x3c,0x4b,0x81,0xb8,0xd9,0x1a,0xf1,0x91,0x5d,0x9d,0xef,0x3e,0xd1,0x78,0xe2,0x1e,0x0e,0x09,0x62,0xdd,0xc6,0xb9,0xde,0x29,0xba,0xb0,0x62,0x49,0x53,0xb6,0x8d,0x9f,0xbf,0x4d,0x77,0xa4,0xd1,0x0b,0xf0,0x31,0x2e,0xe5,0x71,0x2e,0x18,0xa4,0xa7,0xcb,0xa6,0x30,0x24,0x11 +.byte 0x8d,0x16,0x21,0x71,0x6a,0x19,0xde,0x3c,0x5a,0x00,0xa6,0xe2,0x43,0x98,0xe8,0x83,0x10,0x76,0xef,0xca,0x67,0x61,0x80,0x98,0x48,0x06,0xa9,0xcd,0x13,0xa6,0x1e,0x5b,0x2b,0xef,0xb7,0x3a,0x24,0xf7,0x10,0x8d,0xc2,0xaa,0x9c,0x78,0x0d,0xd1,0x54,0xb1,0x4e,0x5a,0x21,0xc2,0xb4,0x11,0x15,0xdb,0xb3,0x9c,0xe4,0xf1,0xfc,0xa5,0x66,0x0c +.byte 0x56,0x34,0x05,0x14,0x88,0x2c,0xfc,0x3f,0x97,0x30,0xd5,0xd0,0xba,0xa3,0xf1,0x47,0xc0,0xf1,0x59,0x3c,0xda,0x1a,0xc1,0x90,0xae,0x4b,0x26,0xd3,0x5f,0xc9,0x8f,0x62,0x56,0x9c,0x64,0xec,0xda,0x63,0x37,0xa1,0xa2,0x87,0x74,0xcb,0xcc,0x27,0xcb,0x2a,0x97,0x57,0xa3,0xb9,0xac,0xe2,0xbd,0x97,0x93,0x21,0xb9,0x8b,0x82,0xa1,0xe7,0x76 +.byte 0xc1,0x49,0xd6,0xb2,0x52,0x7b,0xd6,0xbb,0x31,0x0f,0x87,0xc0,0xaa,0x91,0x70,0x19,0x76,0xa5,0xea,0xf0,0x87,0x47,0x50,0xc1,0xff,0xf7,0xa6,0x6c,0x65,0xff,0xdf,0x83,0x5c,0x54,0xf0,0xb1,0x18,0xe0,0x13,0x58,0x74,0xc0,0x67,0x0e,0xb8,0xdc,0x59,0x6c,0x19,0xf4,0xee,0x3a,0x07,0x63,0x68,0x1d,0x62,0x60,0xb5,0x71,0xce,0x21,0x61,0x8c +.byte 0xa5,0x74,0x9b,0x77,0x8e,0x15,0x20,0x18,0x19,0x96,0xf6,0xfa,0xd2,0x6c,0x03,0xcb,0xcb,0x8c,0x91,0x0d,0x29,0x91,0x70,0xc5,0x96,0x60,0x18,0xad,0x65,0x66,0x43,0xf9,0x13,0x97,0xe3,0xe3,0xcb,0xbf,0x68,0x0b,0xb2,0x87,0x9c,0xfa,0x96,0x48,0x14,0xef,0x6e,0xbd,0x45,0xb9,0x2f,0xbb,0x80,0x80,0xc5,0xf6,0x22,0x41,0x9a,0xec,0xdd,0x41 +.byte 0xfc,0xf3,0x0d,0x8e,0x2e,0x3c,0xda,0xef,0x2c,0xbd,0xbc,0x0e,0x88,0xd2,0x97,0x3d,0x40,0x37,0xa6,0xde,0x1d,0x00,0xeb,0x39,0xea,0x44,0xee,0x8a,0x2f,0x77,0xea,0xea,0x1d,0x90,0xd1,0xec,0xe4,0x31,0x0c,0xde,0x6f,0x55,0x17,0x5c,0x1e,0x19,0x91,0xac,0x36,0x00,0x26,0x17,0xa6,0xcd,0x8b,0xe2,0x72,0x6f,0x8f,0x3c,0xc6,0x76,0x6e,0x3d +.byte 0x4e,0x93,0xb3,0x8b,0xad,0x24,0x17,0x39,0xc0,0xfe,0xba,0x90,0xc5,0xbd,0x4b,0xe4,0xae,0xac,0xf6,0x55,0x72,0x3e,0xf0,0x12,0x32,0x5a,0xdd,0x8a,0x3f,0x67,0xb6,0xdf,0xf6,0x11,0x02,0xf5,0x84,0xcc,0x7d,0x36,0xe7,0x1b,0xf0,0x9a,0x52,0xbe,0xf3,0x06,0xd6,0xdb,0x02,0xd4,0x80,0x0b,0xcd,0xf0,0xfe,0xec,0x86,0x3f,0x89,0x34,0xcb,0x88 +.byte 0x34,0x28,0x57,0x00,0x33,0xeb,0x4f,0xfa,0xdb,0xd8,0x09,0xd9,0x56,0x53,0xc1,0x02,0xc0,0xa8,0x4c,0xdc,0xfd,0x26,0xb3,0x55,0x1d,0x47,0x0d,0x68,0x50,0xb8,0xa3,0xb4,0xf1,0x31,0xfa,0x16,0x33,0x94,0x40,0x95,0x53,0x9c,0x9f,0x5b,0x25,0x47,0xb1,0x27,0xbc,0x38,0x7d,0x23,0x01,0x7f,0x70,0x7a,0x61,0x0e,0x46,0x5c,0xcc,0xd7,0xcc,0x15 +.byte 0x15,0x0a,0xed,0x4c,0x99,0x66,0x3a,0xc3,0xc1,0x9a,0x7a,0x38,0x6a,0x0c,0xde,0x13,0x67,0x65,0xfc,0x06,0x99,0x7c,0xa5,0x90,0x8a,0x90,0x58,0xce,0xf3,0x23,0x76,0xfc,0x03,0xfb,0xb3,0x36,0x54,0xa9,0x33,0x35,0xfe,0xe3,0x3d,0x53,0x7e,0xe0,0xae,0xcf,0xc0,0xa2,0xe1,0x28,0xb9,0x97,0x96,0x87,0x90,0xa1,0x13,0xd0,0x1d,0x5b,0x43,0xf1 +.byte 0xa5,0xfa,0x81,0x83,0xe7,0x7b,0xa1,0x5f,0x9f,0xf5,0xd3,0xb6,0x80,0x8b,0x91,0xed,0x31,0x14,0x05,0x78,0x85,0x9d,0xea,0x59,0x69,0xa5,0x29,0xc5,0xf1,0xd7,0x9d,0xa3,0x8b,0x9d,0xe0,0x8d,0xc3,0x4e,0x2d,0xfa,0x1c,0x6c,0xd2,0xd7,0xcb,0xda,0x86,0x5d,0xb3,0x1a,0xb4,0x12,0xe3,0xa8,0xd7,0xe1,0x84,0xce,0x0e,0x06,0xd0,0x9e,0xf0,0xb1 +.byte 0x5b,0x2f,0x77,0x10,0x6f,0x41,0x2f,0x5b,0x48,0x43,0xf3,0xef,0xdb,0x09,0xdb,0x01,0x89,0xfc,0x7a,0x4a,0xc0,0x96,0x33,0xdf,0xbe,0x49,0x85,0xa7,0x88,0x93,0x05,0xf2,0x15,0x12,0x85,0x04,0x20,0x7d,0x8c,0xe2,0x0a,0xea,0xfe,0xed,0xbf,0x98,0xdb,0x9d,0x1f,0xaf,0x0f,0xbf,0xf7,0x12,0x4f,0x69,0x4e,0x87,0x09,0xf0,0xae,0x2a,0x4d,0x4c +.byte 0xbf,0xaa,0x08,0x2c,0x78,0x2d,0xbe,0xb9,0xf5,0x3c,0x4c,0xcd,0x75,0x93,0xc3,0x3c,0xc2,0x86,0x47,0xca,0xc1,0x9c,0x1c,0xe5,0x0d,0x8d,0x36,0x9c,0x44,0x40,0x89,0xfa,0x17,0x57,0x08,0xd4,0x22,0x9a,0x5b,0x94,0xbf,0x39,0xcd,0xbe,0xf7,0xd1,0xcd,0x35,0x74,0xdf,0xfa,0x5d,0x00,0xaa,0xaa,0x82,0x6d,0x9b,0xf8,0x69,0x51,0x9c,0xaa,0xaa +.byte 0xc8,0x2c,0xa2,0x68,0x57,0x3c,0x5f,0x10,0xa2,0x7b,0xee,0xc9,0x97,0x8d,0x5c,0x41,0x08,0x0d,0x30,0xd5,0x2b,0x5f,0x8d,0xdd,0xdc,0x2c,0xa8,0x52,0x6e,0xea,0x61,0x77,0xca,0x75,0xc3,0x56,0x6e,0x17,0x51,0x0e,0x00,0xb6,0x18,0xa0,0xe5,0x9d,0x49,0x4e,0x20,0x78,0x1e,0x5f,0x3e,0xec,0xc3,0x4a,0x41,0xf3,0xfe,0x89,0x64,0xac,0x4c,0x4d +.byte 0xa8,0x73,0x4f,0x31,0xc4,0xe2,0x62,0x69,0x2b,0x40,0xdf,0xef,0xed,0xf0,0x62,0x4e,0xc3,0x65,0xcc,0xcb,0xef,0xc1,0x28,0x61,0x71,0xac,0xa5,0x89,0x52,0x7b,0x32,0x59,0xc2,0x16,0x1a,0x63,0x18,0xb0,0xd8,0xe4,0x28,0x92,0xff,0x45,0xc1,0x24,0x56,0x86,0x66,0x23,0x7a,0xff,0xf7,0x33,0x30,0xdc,0xd1,0x7d,0xaf,0x68,0x10,0x4b,0xde,0x3e +.byte 0x4a,0x70,0xbe,0x31,0x1a,0x37,0x28,0xee,0xe0,0xba,0x65,0x8b,0x7d,0xea,0x07,0xce,0xf2,0x51,0x3d,0xcb,0xb2,0x33,0xd8,0xf3,0xa4,0xa0,0xcd,0x53,0x76,0xf9,0x46,0x5b,0x82,0xf9,0x9d,0x0e,0x29,0x5b,0xcf,0x76,0xd4,0x5c,0x47,0xf1,0x98,0x02,0x5a,0x16,0x18,0xf2,0x61,0x6d,0x3e,0x64,0x7f,0xbe,0x13,0x18,0xc2,0x45,0xd2,0x87,0x17,0xff +.byte 0xf1,0x01,0x0b,0x5d,0x21,0x0d,0x73,0x9a,0xeb,0x82,0xc4,0x9a,0xb3,0xe4,0x31,0x44,0x58,0xa2,0xfd,0x76,0xf6,0xbe,0x6f,0x75,0xcc,0xbb,0xe3,0xa2,0xa9,0x78,0x0f,0x4b,0x1d,0x47,0x2d,0x32,0x2c,0x45,0x5e,0xcd,0x8f,0x13,0xe2,0x9a,0x9d,0xa2,0xce,0x73,0x54,0x20,0xc0,0x44,0x1c,0x26,0xde,0x0d,0x72,0xb2,0xfa,0x4d,0x32,0x35,0xac,0x69 +.byte 0x4d,0x16,0x4a,0xd5,0x51,0x33,0xc1,0xe0,0x90,0x9c,0x93,0x66,0xed,0x16,0xac,0x7e,0x79,0x2b,0x0f,0xb4,0x42,0xaf,0x80,0x22,0x80,0x07,0x7d,0x72,0xe4,0xb3,0x3a,0x2c,0xb8,0x68,0x14,0x4d,0x31,0x5f,0xbb,0xac,0x43,0x3b,0x28,0xd6,0x81,0x81,0x26,0xe5,0xc4,0x67,0x7c,0x4a,0x42,0xc4,0x1a,0x59,0x04,0x2d,0xb8,0x26,0xfc,0x4e,0xc7,0xfc +.byte 0x11,0x61,0xe3,0x4b,0x2c,0x3f,0xdb,0x43,0xe4,0x24,0xb4,0xd1,0xc0,0xc0,0x01,0xe1,0xeb,0x84,0x0b,0x6d,0x93,0x83,0x07,0x9f,0x01,0xb8,0x9d,0xe5,0x7e,0x4d,0xa2,0x05,0x3e,0xf2,0x40,0x59,0x88,0xc8,0x8c,0x62,0x44,0x95,0x20,0x96,0x28,0xa9,0x3f,0x7c,0xed,0x85,0x03,0x65,0x49,0xf7,0x94,0x3d,0x51,0xe2,0x8e,0x21,0x19,0x7b,0x55,0x5f +.byte 0x55,0x70,0xf8,0xf0,0xce,0xd9,0x1a,0x10,0xbb,0xfe,0x65,0x72,0x8a,0x5b,0x6c,0x27,0xd3,0x57,0x61,0x07,0x7b,0x85,0xd6,0x21,0xd2,0x07,0x81,0xaa,0x17,0x73,0xb5,0xef,0x2d,0x84,0x7b,0x8f,0xe0,0xb3,0x9e,0x9f,0x31,0x82,0x33,0x07,0x14,0x84,0x79,0x18,0xc4,0xec,0x20,0xb5,0xec,0x21,0x4b,0x51,0x78,0x96,0xc6,0xe7,0xf0,0x6a,0x7a,0xb5 +.byte 0xe5,0xc2,0xef,0x24,0x4c,0x57,0xb6,0xf5,0xee,0xe5,0x69,0x2b,0x73,0x9e,0x66,0x91,0x9d,0xd4,0x24,0x58,0x4b,0x72,0x68,0xf6,0x62,0xb4,0x0c,0xe3,0xbd,0x1f,0x0b,0x42,0x6c,0xf9,0x6e,0x6a,0x64,0x64,0x69,0xa5,0x6d,0xe7,0x38,0x9f,0xb2,0x65,0x35,0x6b,0xd9,0x20,0x84,0xe4,0x5f,0x8b,0xfd,0x58,0xab,0x5f,0xe1,0x4c,0xf7,0xd7,0xf5,0xe7 +.byte 0xae,0xe8,0xc1,0x68,0xfe,0x0c,0xb1,0xe2,0xe4,0xca,0xf0,0xf1,0x20,0xbc,0xf9,0x99,0xef,0x4e,0x63,0xca,0x89,0xe4,0x7c,0x17,0x49,0x40,0x47,0xce,0x67,0x8e,0xbd,0xd0,0x96,0x8b,0x5a,0x0d,0x2f,0xd0,0x8f,0x4f,0x42,0x06,0x01,0x8e,0x47,0x35,0x13,0x9e,0xd1,0x24,0x85,0xe4,0x17,0x59,0xe8,0x1c,0xb3,0x25,0x53,0xf9,0xb4,0x96,0xb1,0x33 +.byte 0x97,0xb2,0x60,0xc7,0xb3,0x48,0xa2,0xfc,0x7f,0x86,0x94,0x2a,0xd3,0x94,0xfe,0x6d,0xa6,0x7a,0xa1,0xe1,0x96,0x5b,0xe8,0xe4,0x91,0xfb,0xf3,0x2c,0x84,0xb4,0x2f,0xbe,0xc9,0xdd,0x1c,0x9f,0x72,0x12,0xcb,0xbd,0x22,0x07,0xc4,0xec,0x05,0xe8,0x32,0x47,0x21,0x27,0xf6,0xc1,0x36,0x59,0x25,0x6c,0xbe,0xb9,0x3e,0xd4,0x1b,0x59,0x11,0x27 +.byte 0x6b,0xa3,0x64,0x71,0x98,0xeb,0x21,0x65,0xc0,0x4c,0x30,0xbd,0x51,0x2b,0xc3,0xfb,0xb1,0x33,0x56,0x1e,0xf0,0x92,0x0f,0x4b,0x63,0x3a,0x9c,0xfb,0xd1,0xac,0x8c,0xf0,0x3e,0xb7,0x0b,0xd2,0x52,0x62,0xd8,0x37,0x9a,0xef,0x79,0xdc,0xcb,0x87,0x1e,0x3d,0x9d,0x91,0x12,0xba,0x78,0x8a,0x11,0x57,0x96,0x44,0x8e,0x2b,0xd2,0xe3,0x4d,0x27 +.byte 0xec,0xba,0xef,0x1c,0x04,0x8d,0x56,0x56,0x11,0x74,0xc0,0xcc,0x1f,0x3d,0x7a,0xad,0x79,0x49,0x59,0xa3,0x71,0xe0,0xf5,0x89,0x89,0x8f,0xcf,0x1e,0x63,0x77,0x91,0x91,0xf1,0x0c,0x1c,0xcc,0x77,0x00,0xd7,0x28,0x9f,0x68,0xbc,0xb6,0x9d,0x33,0x43,0xb2,0x4a,0x72,0x3e,0x57,0x26,0xd0,0x00,0x93,0xc9,0x4c,0xc9,0x53,0x52,0xd9,0xe2,0x31 +.byte 0xc5,0x7f,0xf6,0xb6,0xc2,0x10,0x51,0x67,0xae,0x63,0x35,0x74,0xcc,0xd4,0x05,0xb3,0x08,0x23,0x35,0x37,0x8e,0xf1,0xbb,0x1d,0x56,0xff,0x62,0xa2,0x13,0x7b,0x01,0x75,0x6d,0xb3,0x92,0x51,0xdc,0x6e,0x08,0x76,0x25,0x52,0xbf,0x9a,0xea,0x89,0x0f,0x96,0xcc,0x79,0xd4,0x72,0xcf,0x65,0x79,0x4e,0x40,0xa3,0xae,0x67,0x0c,0x82,0x85,0x05 +.byte 0xfd,0x43,0x84,0x17,0x24,0x79,0xa9,0xa7,0x7f,0x24,0x76,0x57,0x66,0x11,0xd5,0x33,0x30,0x42,0x5b,0x5f,0x7c,0x04,0x4b,0x45,0xc3,0x69,0x20,0x02,0x92,0xe3,0x6a,0x06,0x8f,0xdf,0x30,0xf6,0x17,0x8f,0xc6,0x8c,0x5e,0x42,0xf3,0x59,0x7a,0x3a,0x55,0x3a,0xc1,0x96,0xd5,0x67,0x3d,0xab,0x32,0xee,0xf0,0x08,0x28,0x73,0xb0,0x11,0x1a,0x92 +.byte 0x4d,0xcc,0x0c,0x86,0xb2,0xa1,0xbf,0x9f,0xcd,0xc7,0x1c,0xbc,0xee,0x39,0x77,0x75,0xfc,0xe6,0x3b,0x62,0xf2,0xaf,0xd5,0xb6,0x77,0x2d,0x86,0x38,0x13,0x00,0xdb,0x71,0x4a,0x87,0x03,0x6d,0x99,0x28,0xf8,0x6a,0x23,0x2e,0xe2,0xb8,0x9c,0x18,0x02,0x00,0x9e,0x5b,0xf0,0x6f,0x9b,0x32,0xdc,0x6b,0x61,0xeb,0xeb,0xe9,0xfc,0xee,0x44,0xbc +.byte 0x4a,0x88,0x04,0xc0,0x10,0xc8,0x65,0x6c,0xa4,0xae,0x9a,0x36,0xb6,0x68,0xd5,0xbf,0x6d,0xe3,0x6f,0x5d,0xad,0xd6,0xf9,0xc8,0x06,0x36,0x25,0x64,0xc9,0x5b,0x71,0x7f,0xbf,0xe3,0x56,0x31,0x2a,0x93,0x47,0x46,0x39,0x91,0x80,0xc5,0xdd,0xdd,0xa1,0x25,0x85,0xd9,0x05,0x49,0x4f,0x1b,0xeb,0x2f,0x6e,0xd9,0xe4,0x65,0x3d,0xcd,0xbd,0x47 +.byte 0x37,0x27,0xb0,0xd1,0x9b,0xa4,0x89,0xd5,0xa0,0x0f,0x8b,0xc5,0xfd,0x91,0xa8,0x86,0x22,0x65,0xf1,0xe1,0x1e,0xb6,0xf7,0x50,0xe6,0x1e,0xf0,0x2b,0x9d,0x02,0xc9,0xe8,0x2a,0xb8,0x9b,0x89,0x28,0x25,0x43,0xcf,0x23,0x08,0xe2,0xa7,0x70,0x31,0x89,0xab,0x5b,0xd9,0x2e,0xa9,0xe4,0xe9,0x1d,0x63,0x7f,0xc6,0xc1,0xfb,0x63,0x45,0x9c,0xf1 +.byte 0xd4,0xc3,0x56,0xb6,0xad,0xb3,0x00,0xce,0x12,0x9e,0x63,0x33,0x25,0xd3,0xb2,0xee,0xa7,0x6b,0xa1,0xfd,0x20,0xa3,0xb2,0x07,0x1a,0x9d,0xed,0xe0,0x1d,0x70,0x5b,0x9f,0xc0,0xbc,0x83,0x09,0x94,0x47,0x8c,0x05,0xef,0x73,0x96,0x31,0xc7,0x35,0xc2,0x2c,0x00,0x2a,0x68,0xd1,0xc4,0xb3,0x3d,0x84,0x44,0x8c,0x93,0xfd,0x64,0x00,0x77,0x46 +.byte 0x18,0xac,0x83,0x9d,0xe5,0xe5,0x46,0x61,0x37,0x72,0x9f,0x0e,0x76,0x55,0xf7,0xca,0x36,0x57,0x24,0x16,0xfc,0x11,0x27,0xaa,0x44,0xa4,0xb0,0x58,0x41,0x46,0x94,0xc7,0x3b,0x9c,0xa3,0xe4,0x89,0xd9,0xdb,0x7b,0x64,0x69,0x84,0x9f,0xc8,0x09,0x6f,0xf7,0xf0,0x58,0x10,0x56,0x9f,0x26,0xf0,0x74,0x0c,0x76,0xcb,0x9d,0x45,0x3d,0xe7,0x94 +.byte 0x54,0xa3,0x84,0x08,0xb5,0x9c,0xff,0xdb,0xba,0x62,0x5e,0x87,0x0d,0x11,0x5d,0x96,0x06,0xd6,0xec,0xf4,0x3e,0x9d,0x66,0xbd,0xc4,0x64,0xed,0x03,0xe0,0xad,0x3f,0x4e,0xb4,0xef,0x16,0xdd,0xee,0xd6,0x00,0x27,0x62,0x74,0x0a,0xe0,0x68,0x72,0x4c,0x6d,0x62,0x15,0x87,0x6a,0xf0,0x25,0x9f,0x33,0x1d,0x92,0x3b,0xa3,0xa4,0xf1,0x81,0xdf +.byte 0xa8,0xed,0xaf,0xa5,0x8d,0x19,0x20,0x72,0x03,0x91,0xf0,0x34,0x60,0x70,0xbe,0xaa,0xdf,0xaa,0x24,0x1a,0x1f,0x1a,0x8d,0xb0,0x7b,0xef,0x10,0x43,0x69,0x24,0x74,0xf2,0x72,0x71,0xa1,0x8f,0x85,0x75,0x3e,0x8c,0xf6,0x0e,0x88,0xe2,0x1d,0x5c,0xb8,0xf1,0xc4,0x8a,0x21,0x76,0x20,0x50,0x3f,0xb3,0x8b,0x9f,0xa4,0x45,0x9e,0x07,0x60,0x22 +.byte 0x2c,0xa6,0xb1,0xc2,0xd2,0xcb,0xc6,0xd8,0xe9,0x94,0x66,0xfb,0x10,0x73,0x92,0x25,0x7e,0x31,0x42,0xf4,0x4a,0x75,0xac,0x78,0x43,0xcb,0xc0,0xc9,0xb0,0xaf,0xb4,0x22,0x8f,0x51,0x36,0x0f,0x5a,0xb8,0xbb,0x44,0x03,0x09,0xd0,0xf9,0x04,0xc8,0x73,0x8e,0xa1,0x76,0x27,0xde,0x72,0xf4,0x3a,0x79,0x63,0x85,0x32,0x09,0xad,0x12,0xe4,0xd7 +.byte 0x8f,0x8e,0x24,0x03,0x4f,0xde,0x39,0xac,0x81,0xe8,0x64,0x09,0x17,0xd7,0x99,0xe6,0x62,0xb7,0x53,0x20,0x9f,0xb9,0x3a,0xb9,0xb1,0x81,0xfa,0x6e,0x33,0xe7,0x4a,0xca,0xd7,0xa7,0xfa,0x7a,0xbf,0x0b,0x0a,0x99,0x3c,0xc7,0xbd,0xef,0xc7,0x90,0xda,0x62,0x30,0xc6,0x94,0x94,0x6b,0xee,0xbd,0xb7,0x0d,0x86,0xc5,0xb1,0x9a,0xb9,0x86,0x34 +.byte 0xc2,0x81,0x2b,0x09,0x7a,0x88,0x09,0x65,0xcf,0x51,0x78,0x19,0x1d,0x5a,0x62,0x2f,0xb3,0x43,0x8d,0xf5,0x9d,0x26,0x2f,0x4a,0x27,0x96,0x22,0x1b,0x4c,0xc8,0xd9,0x73,0x4b,0x32,0x01,0x11,0x7b,0x59,0x85,0xda,0x50,0x92,0x17,0x45,0xd4,0x1f,0xcf,0x98,0xf6,0x2c,0x69,0xba,0x43,0x22,0xdc,0x36,0x31,0xfb,0x1e,0xe8,0x54,0x24,0x0f,0x24 +.byte 0x4c,0xcd,0xbe,0xdb,0xd8,0x23,0x69,0xe2,0x97,0xf5,0x66,0xb2,0x66,0x6c,0xf2,0x90,0xd0,0x15,0x14,0x9a,0x47,0x65,0x97,0xb0,0xf2,0x3e,0x35,0x09,0xd2,0x3d,0x01,0x9c,0xb3,0xfd,0xf3,0x32,0x46,0x4e,0x11,0xab,0x88,0x9e,0x04,0x6d,0xf0,0xe1,0x9d,0x48,0x01,0x24,0xc3,0x87,0xdf,0x58,0xb6,0x6d,0x6d,0x4f,0xb9,0x1b,0x13,0xee,0x03,0x5b +.byte 0x75,0x39,0x28,0x31,0x90,0x70,0x49,0x10,0x71,0x87,0x76,0x30,0xac,0x88,0xb0,0xf6,0x6c,0xaf,0x5b,0xf4,0xf3,0xe7,0x25,0x75,0x8c,0xa3,0xf4,0xa7,0xd8,0x94,0x78,0xc8,0x77,0xc1,0x48,0x6c,0x62,0xf6,0x2c,0xb5,0x41,0x59,0xf6,0xd3,0xae,0x1b,0x55,0xed,0xdf,0xd1,0x59,0x63,0x76,0x03,0x65,0xd3,0xd0,0xcd,0xb6,0x5b,0x8f,0x1a,0x78,0x88 +.byte 0x78,0x07,0x14,0x3f,0xc3,0xd4,0x1c,0x69,0xd8,0x15,0x25,0xca,0x76,0x15,0x24,0x7d,0xed,0x69,0x2a,0xb5,0x04,0xd2,0x3b,0xbd,0x7a,0xb2,0xae,0x04,0x51,0x85,0x2b,0x1b,0xb0,0x3f,0x6d,0xbc,0xa0,0xc7,0x19,0x40,0xab,0x75,0x51,0x4b,0xa8,0x5a,0xd7,0xb5,0xc7,0xa8,0xfc,0x4a,0xcf,0xa9,0x9c,0xe6,0x2e,0x35,0x51,0x3b,0x05,0x41,0x43,0x7c +.byte 0x1f,0x2e,0x16,0x5d,0x2f,0xa8,0xe9,0xce,0x6d,0x06,0xa7,0x5a,0xed,0x07,0x39,0xe4,0x7e,0xc3,0x01,0x2d,0x97,0xe4,0xc1,0x89,0x2c,0xb4,0xb1,0xb5,0x7f,0x0a,0xe2,0x9f,0x82,0x36,0xee,0x9b,0x76,0xbc,0x9d,0x37,0xdf,0x5e,0x81,0x95,0x9b,0x2b,0xc4,0x58,0x20,0x6a,0xd2,0xc7,0xb6,0x82,0xe6,0xa2,0x52,0x73,0x4a,0xaf,0x37,0x5a,0xf6,0x6b +.byte 0xc4,0x2b,0x53,0x4e,0xca,0x44,0x17,0x9f,0x1c,0xeb,0x4d,0xf2,0xd1,0xb0,0x35,0xaa,0xc3,0xfe,0x77,0x34,0x2a,0x4a,0xe8,0x85,0x96,0x2f,0xa4,0x7d,0xdf,0xd0,0x6a,0x4a,0x0c,0x9b,0xd9,0x6a,0x00,0x92,0xb4,0xb1,0x9f,0xc3,0x56,0xee,0xcb,0xa5,0x3a,0x37,0x68,0xc8,0x7c,0x1e,0xa8,0x0a,0x3d,0xbc,0xd1,0xd0,0xd7,0x8b,0x32,0x34,0x20,0xfc +.byte 0xd3,0x9e,0xf5,0x18,0x3a,0xb9,0x87,0xae,0xde,0x6c,0xc0,0x7d,0xbd,0x20,0x00,0xe5,0x7b,0xcb,0xf9,0x7d,0x70,0x9a,0x10,0x45,0xc9,0x33,0x13,0x9d,0x2c,0x16,0x67,0xe6,0x36,0x38,0xcf,0xa2,0xf1,0xad,0xec,0x48,0x7f,0x9b,0x2a,0xdc,0x13,0xe2,0xee,0xef,0xf2,0x5c,0x3f,0x52,0x3a,0x72,0x79,0x9b,0xba,0x50,0xb2,0x2b,0xfb,0x97,0x8e,0xe6 +.byte 0x27,0x39,0x63,0x72,0x05,0x11,0x7d,0x2e,0xa8,0x44,0x08,0xf7,0xf3,0x26,0xe5,0xe4,0x6c,0x98,0x7b,0xb1,0x42,0x6d,0x74,0xd4,0x3b,0xfa,0x35,0xfa,0x0a,0xac,0x5e,0x9e,0x8f,0xc7,0x07,0xc5,0x50,0x25,0xfd,0xbf,0x13,0x52,0x3d,0xf1,0x18,0x1e,0x19,0x8c,0xf3,0x8b,0x4d,0xc8,0xfb,0x76,0xa4,0xe3,0x3f,0xb2,0x47,0x9c,0x50,0x97,0x32,0x65 +.byte 0x9e,0x42,0x81,0x21,0xd1,0x92,0xd2,0x81,0x4a,0x93,0x68,0xa2,0xc1,0x76,0xc8,0x40,0xce,0xfe,0x4e,0xc5,0xa7,0xb2,0x77,0x9f,0xc8,0xe5,0x41,0xb1,0xda,0x15,0xf6,0xfa,0x21,0x3f,0x11,0x5c,0xc6,0x62,0xda,0x01,0x7f,0x0f,0x9f,0x9e,0x98,0xfe,0x38,0x53,0x6c,0x7f,0xba,0x8b,0x55,0x01,0x36,0x33,0x41,0x5e,0xa9,0x78,0xbf,0x2e,0x60,0x4f +.byte 0xcb,0xe9,0x27,0x09,0x8c,0x01,0x2d,0x82,0x7d,0x3f,0xaf,0x8f,0x1e,0x37,0x79,0x35,0xfb,0xce,0x83,0xc5,0xf8,0xc5,0x54,0xfd,0x50,0xec,0x31,0xd1,0xb5,0x8a,0x4d,0x37,0xf6,0x7f,0x0e,0xbe,0x35,0xdd,0xa8,0x9e,0x5e,0xb9,0x3c,0xf4,0x2b,0xd2,0x97,0x56,0xd0,0x28,0xcb,0x60,0x27,0xcf,0x27,0x68,0x8a,0xa1,0xbf,0x9f,0xa3,0x45,0x4a,0x44 +.byte 0x71,0xe2,0xb2,0x9c,0x69,0x0b,0x18,0x69,0xcf,0x03,0xcc,0xc3,0x93,0xe0,0xf5,0xb7,0x4e,0xa4,0xdc,0x96,0xe0,0x2e,0xf8,0x3b,0xc6,0x67,0x30,0x06,0x5e,0xb9,0xb9,0x7d,0xaf,0x97,0x38,0x9a,0xf4,0x22,0x20,0x5a,0x9e,0x83,0x26,0x3c,0xcc,0x93,0x84,0x20,0x15,0x2e,0x85,0x23,0x17,0x1d,0x28,0xb4,0xe2,0x8f,0x2d,0x22,0x99,0x66,0xfd,0x6a +.byte 0xa8,0xe6,0xb7,0x19,0x18,0xec,0xbd,0x54,0xc2,0xcc,0xb7,0xb4,0x6b,0x10,0xdd,0xb5,0xe3,0x3b,0xb7,0x77,0xbf,0x66,0x65,0x82,0x6a,0xc6,0x0d,0x26,0xe6,0xe8,0xe1,0x96,0xe4,0x0b,0x3c,0xe3,0xf2,0xfb,0xd6,0x91,0x5d,0xb6,0x08,0x15,0x67,0x10,0xfa,0xf8,0xdc,0x72,0x84,0xca,0x48,0x29,0x75,0x98,0x62,0x30,0x43,0xa9,0xf1,0xde,0x58,0xb5 +.byte 0x6e,0x67,0x53,0x62,0x0d,0x06,0xa8,0x97,0x35,0x04,0x02,0x34,0x3f,0xd7,0x77,0x38,0xed,0x51,0x32,0x7c,0x6f,0x25,0x94,0x04,0x30,0xa5,0xfc,0xf1,0xb0,0x65,0x77,0x16,0xec,0xb0,0xf9,0x6d,0xaf,0xbc,0x75,0x6e,0x29,0x44,0x20,0x86,0x36,0xbe,0x22,0xe0,0xe1,0xc4,0x0c,0x97,0x10,0x45,0x3e,0x06,0xc3,0xee,0xa5,0x1f,0x97,0xc7,0xde,0xdb +.byte 0xf1,0x05,0xe3,0xb7,0x24,0xc5,0xa5,0xca,0x4e,0x8e,0x9e,0x44,0x7e,0x98,0xb1,0x3c,0xe9,0xa6,0xe5,0xa6,0x08,0xcb,0x08,0xd7,0xf6,0x38,0x37,0xa4,0x46,0xd1,0xdc,0x53,0x6f,0x6c,0x3f,0xca,0xa1,0x9b,0x7c,0xa6,0x44,0xd4,0x08,0x33,0xd2,0xf8,0x32,0xd2,0x4f,0x60,0x75,0x0f,0x49,0xf1,0x70,0x52,0x56,0x16,0x5b,0x3e,0x34,0x0e,0xe4,0x94 +.byte 0xc3,0xa9,0xd4,0x1c,0x9e,0xa4,0x10,0xce,0xc1,0x69,0x5b,0x3a,0xc9,0xd5,0xab,0x98,0x81,0x78,0x42,0x7e,0xf2,0x76,0x10,0xad,0x97,0x85,0x98,0x2f,0xe2,0x3f,0xb1,0x1d,0xc0,0x4d,0xa4,0x0b,0x54,0x7e,0x19,0x16,0x0a,0x71,0x74,0x37,0xfd,0x67,0x23,0x86,0xb2,0x3b,0x1e,0x49,0x92,0x92,0x1b,0x5f,0x65,0x56,0x76,0x6d,0x97,0x3b,0x91,0xc0 +.byte 0x5a,0x7e,0xf1,0x5b,0xe9,0x83,0xb9,0x67,0x2f,0xe1,0x0c,0xcf,0xe9,0x51,0x26,0x45,0x03,0x06,0x63,0xa4,0xb2,0x06,0xe0,0x8e,0xa3,0xbf,0xf5,0x7c,0x19,0xdf,0xfe,0x38,0x28,0x98,0xa1,0x23,0x16,0x69,0xc4,0x9f,0x20,0xe4,0x42,0x27,0x4e,0x7b,0xc9,0x42,0x5e,0xd2,0xb9,0xbf,0x33,0x03,0xbb,0x96,0x6d,0x80,0x65,0x90,0x3b,0x82,0x5b,0x68 +.byte 0x46,0x4f,0xe3,0xe0,0x0e,0xc5,0x90,0x91,0x80,0xf8,0xf4,0x9c,0xfe,0x03,0xaf,0x31,0x44,0xb7,0xfc,0x1f,0x65,0xc8,0x65,0x68,0xcc,0x27,0xb4,0x0d,0x81,0x14,0x9e,0x52,0xab,0xdd,0x71,0xf6,0xd9,0xcf,0x29,0x04,0xcd,0xae,0x6f,0xd6,0x41,0xb5,0xfd,0x1d,0x0f,0xbf,0x71,0xc2,0x60,0x98,0xb9,0xc0,0x6e,0x8a,0x2c,0x7d,0xec,0x31,0xa5,0xea +.byte 0x1a,0xb1,0xe4,0xc2,0x36,0xcb,0xf0,0xf4,0x3f,0x1d,0x03,0x01,0xcd,0xac,0xd0,0x9d,0x2e,0xa3,0xc4,0x54,0x49,0x75,0x90,0xac,0x7e,0x1e,0xc3,0x90,0xab,0x55,0xb0,0x34,0x0d,0xd6,0x99,0xb5,0x40,0xda,0xdd,0x30,0x57,0x61,0x15,0xec,0x8f,0x8c,0xc7,0xda,0xfc,0xf5,0x0a,0x86,0xd8,0x6b,0x0f,0x6e,0x09,0xb8,0x50,0x2a,0xea,0x51,0x84,0x33 +.byte 0x7a,0x97,0x0c,0x56,0x61,0x2c,0xd9,0x83,0xb9,0xb1,0x53,0x31,0x72,0x20,0x79,0x85,0x7f,0xdc,0xb8,0xfe,0xfa,0x9a,0xd4,0x6a,0x3c,0xc7,0xcc,0x75,0x20,0xba,0x9c,0xb9,0x1a,0xff,0x9c,0xbe,0xfd,0x87,0xb4,0xd7,0xe8,0x5e,0x22,0x6a,0x1b,0x91,0x52,0x6a,0x58,0xbc,0xf4,0xde,0xcc,0x18,0x37,0x0e,0xf5,0x22,0x91,0xd2,0x4f,0x08,0x91,0x62 +.byte 0x1c,0xb7,0xa0,0x7e,0x66,0x97,0xda,0xa0,0x3c,0xc8,0xe8,0xdc,0x61,0xa4,0x64,0x8b,0x0a,0x43,0x90,0x0c,0x78,0xd9,0x96,0x8a,0xb0,0x17,0x0f,0x32,0x17,0x11,0x82,0x69,0x9d,0x7c,0xa9,0xfd,0x9b,0xe3,0xeb,0x0d,0x44,0x1d,0xcb,0xf6,0xee,0x26,0x6b,0xd5,0x4c,0x49,0x69,0x18,0xd7,0xf3,0x63,0xd9,0x7e,0x83,0xdd,0xa3,0x2d,0xdf,0x88,0x10 +.byte 0xd1,0x5c,0xb0,0x7e,0x44,0xfe,0x64,0x39,0x33,0x05,0x04,0x54,0x74,0x4d,0xd5,0xbc,0xdf,0x19,0x52,0x81,0x60,0x92,0xc5,0x4e,0xa4,0xff,0xf0,0xa2,0xfd,0x88,0x96,0xde,0xb4,0x8d,0x58,0x06,0xfb,0x96,0x6f,0x0e,0xb0,0x4a,0x2b,0xed,0x15,0xa7,0xfb,0x9f,0xf2,0x30,0xc4,0xce,0x02,0x4d,0x83,0xb8,0x5d,0x10,0x60,0xb8,0xbc,0x05,0xa2,0xd4 +.byte 0xf1,0xae,0x46,0x56,0xb9,0xac,0x68,0x79,0x41,0x90,0xee,0x79,0xda,0x3a,0x91,0x7a,0xf6,0xdb,0xe3,0xea,0x91,0x48,0x77,0x4a,0xa3,0xab,0x9c,0x99,0x49,0x1f,0xc9,0xcd,0xe7,0x2e,0xe3,0xe7,0x78,0x6d,0x07,0x1b,0xc6,0x08,0x48,0xd8,0x20,0xff,0x19,0x8a,0x73,0x1d,0xc6,0xa1,0xd4,0x95,0x33,0xf7,0x45,0xab,0xea,0x05,0x3e,0xdf,0xde,0x68 +.byte 0xb2,0xb6,0xef,0x71,0xb4,0xd1,0x09,0x4b,0x43,0x16,0x35,0x1a,0xb6,0xcb,0x78,0x63,0xca,0x9e,0x9a,0xe3,0x86,0xb2,0x8e,0x7b,0x68,0x89,0xa7,0x5c,0xd3,0x06,0x21,0x88,0x94,0xde,0xa1,0xb1,0x3a,0xe8,0xb7,0xfa,0x58,0xc5,0xc8,0x01,0xfa,0x56,0xe4,0x0e,0x6b,0xeb,0x5d,0x67,0xf4,0x63,0xd4,0x44,0xe2,0xe7,0x42,0xfe,0x09,0x58,0xdf,0xd9 +.byte 0x1d,0xb7,0x14,0x91,0xac,0x88,0x49,0xf6,0x7c,0x03,0x92,0x11,0xb4,0x66,0x68,0x6c,0x94,0x2a,0x22,0xaf,0xa6,0xb1,0x29,0x2a,0xae,0xdd,0xa8,0x65,0xe4,0xa9,0x39,0x00,0x1e,0xca,0x17,0x99,0xba,0xd6,0xf2,0x20,0x21,0xbf,0x1a,0xab,0xca,0x7c,0x92,0x22,0xee,0x3c,0x0c,0xc6,0x63,0xcc,0x86,0xfe,0xc0,0x8f,0xac,0x18,0x4e,0x2b,0xa5,0x2e +.byte 0x46,0x57,0x8a,0xbf,0xdc,0xd1,0xd2,0x2c,0x5b,0xe2,0x96,0x81,0xca,0x41,0xb5,0x17,0x38,0x4a,0xa4,0xd2,0x0e,0xac,0x5d,0xe9,0x44,0x63,0x1b,0xb8,0x81,0xd6,0x69,0x1c,0x99,0xc5,0xdb,0xdd,0x18,0xc1,0x6d,0x28,0x7d,0x36,0x52,0x82,0xaa,0x1a,0x10,0x01,0x9d,0xf1,0x7b,0x09,0x69,0x56,0xb1,0x31,0xa3,0x54,0x3c,0x56,0xf9,0x82,0x8c,0x06 +.byte 0x5a,0x32,0x2d,0xc0,0x7c,0x7e,0x91,0x6d,0x73,0x7b,0x7c,0x45,0x0b,0x2c,0x2a,0x4f,0x3c,0xea,0x6b,0x2b,0x84,0x76,0xab,0x8d,0x4c,0x5c,0x64,0xa3,0x97,0x9f,0x56,0x20,0x05,0xf9,0xc2,0x20,0xf3,0xd0,0x6a,0x7f,0x7d,0x12,0xfc,0x20,0x52,0x5d,0xff,0x92,0xaf,0x4e,0x7f,0x8f,0x2f,0xd0,0x73,0x06,0x23,0x09,0xce,0x11,0xc0,0x1b,0x48,0x7d +.byte 0x11,0x51,0x06,0x0e,0x05,0x95,0xca,0x42,0x71,0x87,0xa3,0xa3,0xc1,0x27,0xf8,0xb1,0x24,0x92,0x38,0x95,0xf6,0x8f,0x3b,0x70,0x74,0x19,0x9b,0x08,0xb3,0x49,0xe9,0x57,0xd4,0xce,0x5b,0xdd,0xab,0x95,0x26,0xe9,0x70,0x21,0xef,0x16,0xdd,0x36,0x89,0xe5,0x9e,0xaf,0xc5,0x28,0x0c,0xd3,0x67,0x64,0xbc,0xfb,0x18,0x17,0x15,0x1e,0xa7,0xb7 +.byte 0x72,0x3d,0xfd,0x10,0x5c,0xa2,0xc1,0xbf,0x62,0x79,0x2b,0xa7,0xb9,0x1f,0x73,0xe6,0x11,0xd8,0xbc,0x74,0x6c,0x45,0x95,0xef,0xa2,0xda,0x90,0xc3,0x00,0x00,0xbb,0xc7,0x28,0x36,0x82,0xd4,0x5e,0x5c,0x11,0xea,0x7c,0xf6,0x79,0x66,0xff,0x93,0x77,0x49,0x05,0xc9,0xc1,0x8d,0x5c,0xf6,0xff,0xb9,0xf9,0xcd,0xb3,0x01,0x83,0x83,0x43,0x2d +.byte 0xa1,0x90,0x73,0xc9,0x32,0xae,0xdb,0xd0,0xf3,0x61,0x63,0x72,0x06,0xde,0x21,0x7b,0x3b,0x2d,0xec,0xd3,0x1d,0xfe,0xbd,0x6e,0xd8,0xe3,0x39,0xe0,0xa1,0x9f,0x67,0xaf,0xab,0x79,0xbc,0x59,0xf9,0xa7,0xdf,0x28,0x75,0xea,0x34,0x6b,0x25,0xde,0x49,0x1b,0x07,0x95,0x19,0x47,0x86,0x46,0x7b,0x68,0x30,0x70,0xec,0x9c,0x05,0xb6,0xc9,0x00 +.byte 0x68,0x10,0x4b,0xc4,0xe5,0xf1,0x67,0x3f,0xd4,0x3c,0xd6,0x49,0x98,0x71,0x23,0xff,0x07,0x6e,0x01,0x01,0x08,0x08,0x3d,0x8a,0xa1,0x71,0xdf,0x25,0x1a,0xef,0x60,0x86,0x6d,0x1c,0xd9,0x90,0x29,0x95,0xf2,0x4c,0x96,0xd3,0x17,0xe8,0x96,0x32,0x25,0x8c,0x65,0x38,0xbc,0x44,0x6a,0x5a,0xef,0x5a,0x72,0x12,0x43,0x2b,0xaf,0xc3,0xdc,0xb3 +.byte 0x6c,0x9f,0x57,0x61,0x2f,0x12,0x3f,0x72,0x16,0x4f,0x34,0xe3,0xb5,0xca,0x72,0xca,0x1c,0xdb,0xd2,0x8d,0x70,0x1f,0x19,0x75,0xb3,0x1b,0xdf,0xdb,0xb3,0xbf,0x6c,0x9a,0x70,0x64,0xa8,0xac,0x30,0x2d,0x4b,0x30,0xf5,0x4f,0x12,0x19,0xbd,0x65,0x25,0x70,0x33,0xe1,0x6f,0x18,0xdf,0x17,0xec,0xa3,0x80,0x51,0x6e,0xbb,0x33,0xa5,0xa8,0x58 +.byte 0x95,0x3c,0xab,0x86,0xd1,0x33,0xbe,0x55,0x04,0x8c,0x20,0x0d,0xfc,0x1a,0xa9,0x9d,0xb1,0x16,0x42,0x56,0x20,0xcc,0xa6,0x73,0xa0,0x85,0x3d,0xbf,0x1e,0xe0,0x01,0x51,0xd2,0xd7,0x2e,0x9d,0xd8,0x3c,0xea,0x03,0xf9,0x9a,0xbf,0x19,0x17,0x04,0x99,0xaf,0x8b,0xfc,0x9c,0x86,0xdf,0x58,0x78,0xfc,0x54,0x0d,0xac,0x26,0x27,0x2f,0x2e,0xbc +.byte 0xdd,0x4a,0xd5,0x6f,0x7c,0xd8,0x93,0xe3,0x51,0x9e,0xcc,0xc8,0xd2,0xfe,0x68,0xfb,0x5b,0x22,0xda,0xef,0x76,0xb9,0xc3,0xdd,0x13,0x52,0x24,0xb6,0x23,0x1f,0x69,0x22,0xb6,0xf5,0x86,0xff,0x2e,0x6e,0xd0,0xe0,0x21,0xbc,0x31,0x81,0xb5,0xc5,0xdb,0x36,0x58,0x44,0xe7,0xb8,0xf7,0xfd,0xd3,0x34,0xee,0xab,0xe6,0x99,0xf2,0x84,0x86,0x9b +.byte 0x67,0x45,0x08,0x07,0x66,0xae,0x6a,0x55,0xa2,0x74,0x46,0xda,0x02,0x82,0x67,0x93,0x60,0x64,0x5d,0x1f,0xac,0xe7,0x36,0xb6,0xcd,0x31,0x28,0x78,0x93,0xcd,0x54,0xe9,0x42,0xbb,0xb4,0xb3,0x15,0x72,0x12,0x31,0x85,0x15,0x68,0x3a,0x31,0x35,0xd6,0xc9,0x0d,0x3f,0xa0,0x4b,0x36,0x03,0xda,0xfd,0x7a,0xd6,0xce,0x0c,0xf5,0x14,0x23,0x71 +.byte 0x47,0x85,0x64,0xe7,0xe7,0x8b,0x8e,0x25,0x03,0x32,0x5f,0xa9,0x3b,0xdb,0x2b,0x27,0x7c,0x02,0xfb,0x79,0xd7,0x7a,0x76,0x75,0x69,0xfd,0x74,0x24,0xd2,0x72,0x8c,0xdd,0xc5,0xa1,0x45,0x90,0x50,0x65,0x95,0x41,0xae,0x7e,0x5c,0x83,0x3e,0x24,0x3c,0x02,0xa9,0x37,0x49,0x36,0x63,0x2f,0x18,0x92,0x3a,0x8a,0xe5,0x2a,0x6a,0x5c,0xa7,0x3e +.byte 0x98,0x24,0xfd,0xd9,0x3b,0x2d,0x4c,0xe2,0x8e,0x05,0x5b,0xdd,0x47,0x0f,0x19,0x5a,0x62,0x94,0xd6,0x6e,0x45,0xd8,0x99,0x43,0x78,0xa0,0xb1,0xdf,0x68,0x8a,0x56,0xa8,0xfb,0x2e,0x52,0x4e,0xfa,0x21,0xec,0x62,0x14,0xf5,0x90,0xdb,0x8c,0x02,0xa7,0xff,0x29,0x22,0xb8,0x40,0x87,0x58,0xda,0x4e,0xfd,0xab,0xeb,0xa2,0x40,0xce,0xfc,0x58 +.byte 0x46,0x37,0x3f,0x04,0x4e,0x36,0x76,0x44,0x3c,0xfc,0x54,0xb8,0x6f,0x4b,0x66,0x6a,0x4a,0x78,0x8f,0x33,0x86,0x07,0xe4,0x3c,0xb5,0x0f,0x86,0x2e,0x21,0x7e,0x44,0xce,0x18,0x77,0xe0,0xcc,0xd7,0x7f,0xc9,0xac,0xb7,0x2b,0x94,0xb5,0x91,0xcd,0x2c,0xfa,0xc7,0x98,0xbd,0xb0,0x2a,0x85,0x77,0xcf,0x82,0xd9,0xae,0x76,0x33,0x34,0xc0,0x9d +.byte 0x3a,0xbc,0x27,0xbc,0x97,0x25,0xf4,0xf1,0x43,0x53,0xac,0xf6,0xde,0xf5,0x1f,0xa6,0x6a,0xd5,0xe3,0x11,0x32,0x49,0x46,0x5b,0x56,0x68,0x07,0xdb,0x03,0xad,0xc2,0x35,0x16,0x8f,0x01,0xcc,0x8a,0xd2,0x0c,0x6b,0xb2,0x62,0x73,0x99,0xb5,0x74,0xf1,0x4b,0x2e,0xbc,0x8e,0xed,0xc0,0x55,0x56,0x40,0xae,0x24,0xf2,0x7e,0x1f,0xba,0x9d,0xc4 +.byte 0xd1,0x69,0xd3,0xba,0x21,0x83,0xf5,0xc4,0xbf,0x78,0x96,0x74,0xa1,0xd8,0x8c,0x35,0xba,0x9f,0xa0,0x0f,0xb5,0x6a,0xb2,0x72,0x52,0xfa,0x02,0x71,0xbb,0x79,0x61,0xbd,0xa9,0xee,0x22,0x7c,0xc5,0xac,0x6b,0x52,0x67,0xab,0xc4,0xd2,0x8d,0x26,0x1c,0x2b,0xaf,0x0c,0xa4,0xce,0xb5,0x11,0x99,0x4d,0x22,0x69,0x68,0xe0,0xc6,0x3e,0x84,0x3d +.byte 0xeb,0xad,0xc9,0x5b,0xb5,0xb4,0xba,0x06,0x9b,0x0a,0xb2,0x54,0x89,0xf2,0xb0,0x5f,0x41,0xb4,0x8b,0x21,0x31,0x29,0x94,0x52,0x1e,0xa7,0xc4,0xc2,0x97,0xb9,0x74,0x95,0xa3,0x30,0xfb,0x02,0x77,0x01,0x4f,0x32,0x03,0x34,0x8f,0x51,0x2d,0x10,0x61,0xee,0xc5,0x2f,0x89,0x42,0x3c,0xbe,0xed,0x66,0xa6,0x7a,0x10,0xc6,0x06,0x7e,0xb2,0x3d +.byte 0xf2,0xc9,0xd1,0x08,0x97,0x6c,0x6f,0x6d,0x06,0x9d,0x72,0xd0,0x5e,0x79,0x3b,0xa5,0xa5,0xd0,0xdc,0xc6,0xda,0x73,0xd2,0xf3,0x0a,0xfd,0x94,0xc2,0x9c,0x4b,0x85,0x38,0x8d,0xb2,0xfb,0x29,0xdd,0x90,0xc2,0xb7,0x8f,0x2c,0x52,0xa2,0x32,0x5e,0xa1,0x0f,0x62,0x38,0x58,0xfa,0x46,0x4e,0x87,0x4b,0xcf,0xc5,0xe9,0xfc,0xf2,0x97,0x62,0xdd +.byte 0x92,0xd2,0x41,0x7b,0xa2,0x2a,0xae,0x6e,0x4d,0xbc,0xef,0x43,0x18,0x6e,0xbb,0xe5,0x06,0x45,0x53,0xa1,0x00,0xef,0xf5,0x4b,0xad,0xbd,0xa5,0x2c,0x77,0x0a,0x37,0x04,0x22,0x95,0xeb,0x7b,0xc1,0x3c,0x20,0x0a,0x44,0xdf,0xa2,0x23,0xc9,0xfc,0x85,0xf3,0x5b,0x9b,0x0f,0x40,0x2a,0xe3,0xc7,0x5a,0xa1,0xf6,0xe4,0x39,0x2a,0xfe,0xd7,0xe7 +.byte 0x33,0xd8,0xbc,0xd6,0x1f,0xef,0xac,0xa9,0x3f,0x2d,0x55,0xb0,0x85,0x74,0xef,0xeb,0xcd,0x9b,0x23,0xa3,0xe6,0x19,0xde,0xea,0x7c,0x9c,0x83,0x48,0x4b,0x12,0xfd,0xe3,0xcb,0x1b,0x70,0x2d,0x9f,0x2c,0x13,0x82,0x87,0x68,0xca,0x60,0x5e,0xc0,0x2e,0x60,0xde,0xf2,0x6b,0x78,0x0a,0x63,0xaa,0x9c,0x9b,0x61,0x63,0xc7,0x0c,0x98,0x92,0x68 +.byte 0xc7,0x44,0x00,0x6a,0x76,0x43,0xa0,0x61,0x7c,0x37,0x62,0x1a,0xd4,0x9b,0x58,0x59,0xe5,0xae,0x78,0x79,0x80,0xf0,0x75,0x68,0x9e,0xab,0x02,0xb8,0x00,0xc5,0x33,0x0d,0xea,0xb1,0x91,0x0f,0x17,0x57,0x96,0x23,0x8d,0x36,0x4d,0x89,0x94,0x42,0xc9,0x61,0x6e,0xf6,0x9f,0x37,0xee,0xa5,0x4b,0x3d,0x06,0x08,0xee,0x9a,0x7c,0x73,0xa9,0x58 +.byte 0xcd,0xcb,0x78,0xa9,0x3d,0x5c,0x11,0x0e,0x5a,0xd9,0xb0,0x7b,0xc4,0x3e,0x83,0xdc,0xe2,0x11,0xe9,0x6d,0x8a,0x8b,0x24,0x28,0x1d,0x7e,0x45,0x1b,0x05,0x5a,0x6b,0x97,0x1c,0x25,0x15,0x84,0x5c,0x3f,0x95,0x44,0xd5,0x4f,0x3c,0x4b,0x52,0xb1,0x0b,0x6a,0xb3,0xae,0x4e,0x1b,0x12,0xcf,0x16,0x78,0xd7,0xcb,0x32,0x43,0x39,0x88,0xf4,0x5e +.byte 0x26,0x29,0xe7,0x93,0x08,0x19,0x14,0x88,0x8f,0x54,0x91,0x13,0xb6,0x57,0xd1,0x87,0xd4,0x9d,0xf7,0xec,0x9b,0x22,0x6b,0x91,0x79,0x9d,0x6c,0x32,0x47,0x4a,0x79,0x55,0x7d,0xac,0x87,0x98,0x59,0x97,0xa5,0x71,0xbc,0xbf,0x1b,0xf0,0x6f,0xbb,0x81,0x8e,0xc2,0xef,0x7c,0x63,0x2f,0x80,0x37,0xb6,0xc5,0xae,0x59,0x5e,0x57,0x5e,0x1f,0x3a +.byte 0xe5,0x6b,0x6b,0x5e,0xdb,0x8e,0xd2,0x87,0xf7,0x94,0x7b,0x11,0x0e,0x4b,0xa6,0x9f,0x49,0xc6,0x68,0xc7,0x52,0x5f,0x28,0x87,0x33,0x84,0x52,0x5f,0xc8,0x5f,0x81,0x85,0x10,0xe8,0x92,0xce,0x13,0x6c,0x01,0x28,0x5e,0x59,0x8f,0xbb,0xa9,0x9c,0xdc,0x85,0xd3,0x73,0xa0,0x5a,0xbf,0x5b,0x04,0x80,0x99,0x90,0xc8,0x16,0x44,0x0d,0x09,0x01 +.byte 0xcd,0x24,0xe7,0x59,0xe7,0x42,0xe0,0xdd,0x01,0x93,0x1f,0x9e,0x1f,0x36,0xdb,0xcd,0x49,0xdb,0xea,0xa9,0x63,0x71,0xb9,0x2c,0xcd,0xca,0x1a,0x64,0xe1,0x95,0xbe,0xe1,0x64,0x2e,0xc7,0x59,0x15,0x61,0xe1,0xf9,0x45,0x0f,0x2a,0x3a,0x85,0xf8,0x7c,0x06,0xae,0x53,0x84,0xd2,0xe7,0xee,0x8b,0xbf,0x7a,0x72,0xa3,0x57,0xf1,0xc2,0x12,0x40 +.byte 0x9c,0x93,0xe1,0x04,0x81,0xde,0xc6,0xa8,0xae,0x4f,0x5c,0x31,0x93,0xc7,0x11,0x1d,0x89,0x70,0x85,0xd5,0x6f,0xab,0x58,0x1f,0x3f,0x76,0x45,0x7e,0x19,0xd0,0x6c,0xc1,0x41,0xa9,0x64,0x0a,0x79,0xb5,0xe0,0x9e,0xbc,0x4f,0x10,0x0c,0xac,0xfc,0x54,0xad,0xcf,0xb8,0xd0,0xfd,0x9b,0xed,0xea,0x54,0x05,0xbf,0x4f,0x91,0xbd,0x16,0x4a,0x57 +.byte 0xa9,0xda,0x38,0xb9,0x40,0x0d,0x63,0x68,0x83,0x7d,0xec,0x1c,0xe6,0x7f,0x9c,0xec,0x16,0x4e,0x0b,0xd0,0x91,0xb4,0x2c,0x04,0x65,0xb8,0x12,0xdf,0x3f,0xff,0x6a,0x08,0x4e,0x65,0xdf,0x09,0xa5,0xea,0xb1,0xac,0xa9,0x67,0xd2,0xbb,0x73,0x51,0xd2,0x37,0x72,0xfc,0x3f,0x69,0xe2,0x3f,0x01,0x94,0x3a,0xf7,0x23,0x0e,0x5d,0x23,0x44,0x82 +.byte 0xc7,0x38,0x35,0x9f,0xfa,0x13,0x15,0x47,0x0d,0x18,0xab,0x02,0x39,0x6e,0xb2,0x7c,0x29,0x11,0x9a,0x5a,0x01,0x2d,0xb2,0x10,0xea,0x9d,0xb7,0x37,0x4b,0xf2,0x2b,0x76,0x22,0xf7,0xaf,0x8a,0x5f,0x1d,0x6b,0xb2,0x13,0x9e,0x84,0xf5,0xbc,0x6e,0xad,0x66,0x5c,0x1b,0x5d,0x12,0xb0,0xe1,0x48,0x94,0x83,0xa0,0x26,0x54,0xd2,0xfd,0x3c,0x8d +.byte 0x81,0xac,0x31,0x9a,0x15,0xc6,0xd8,0xd5,0x07,0x1b,0x21,0x3f,0x04,0x40,0x3a,0x60,0x80,0x5f,0x1f,0x42,0x3e,0xd7,0x2b,0x7a,0x5f,0x71,0x93,0xb4,0x9d,0xf0,0x8b,0x5e,0xf1,0xc6,0x19,0x0a,0xa9,0x43,0xac,0xb2,0xc1,0x73,0x0d,0x44,0x6a,0x92,0x22,0xd0,0xda,0x40,0x14,0x7d,0x88,0xd1,0x5e,0x10,0xc9,0xa4,0x4d,0xd8,0xe0,0x7d,0x74,0x1b +.byte 0x2b,0xcb,0x50,0x24,0xbd,0x50,0x4a,0xe4,0xed,0x0e,0xe8,0xc0,0x5b,0x50,0x6d,0xf5,0x68,0x59,0xd1,0xc3,0x6f,0x32,0x86,0x29,0xe0,0x32,0x3f,0x05,0x86,0xa2,0x7f,0x93,0xd8,0xb7,0x02,0x68,0xb3,0x16,0xaa,0x0c,0xd3,0x4d,0xec,0x9a,0x66,0x06,0x7c,0x74,0x35,0x6f,0xde,0x8b,0xd9,0xdb,0x79,0x0a,0x15,0x84,0xc4,0x63,0xba,0x42,0xa2,0x3c +.byte 0x29,0xc8,0x65,0xdc,0x06,0x60,0x0a,0x08,0x4e,0x80,0x33,0x5c,0xfa,0x4b,0x91,0xdb,0xf6,0x57,0xd6,0x25,0x7d,0x70,0x80,0x09,0xb2,0x27,0xdb,0x80,0x4c,0xa7,0xe8,0x35,0xf5,0x18,0x2d,0x10,0x62,0x22,0xf9,0xb1,0x22,0xf3,0x9b,0x74,0xa0,0xc5,0x25,0xd3,0x44,0xc9,0x27,0x7c,0xba,0x01,0xfe,0x32,0x23,0xf7,0x90,0x90,0xbc,0x0d,0xad,0x9e +.byte 0x22,0x77,0xc5,0xfb,0xf2,0x0e,0xda,0xe5,0x7c,0xb4,0xbb,0xed,0xd4,0xfd,0xb0,0xfb,0x4a,0x4c,0x2a,0x32,0x2d,0x81,0xcd,0xef,0x74,0x3c,0x6a,0x9a,0x0c,0x95,0x58,0x25,0xd0,0x3a,0xb4,0x84,0x8f,0xa5,0xef,0xad,0x91,0xd7,0x2d,0xae,0x61,0xaf,0x9d,0x3f,0x03,0xa8,0xab,0xa4,0x66,0xd4,0x73,0x3a,0x84,0x0d,0x4c,0x6a,0xca,0xbd,0x0c,0x3c +.byte 0xdc,0x1d,0x37,0xea,0xe6,0x5a,0x7f,0x15,0xbe,0x9d,0xc7,0xce,0xbd,0x46,0x97,0xd3,0x07,0x19,0x82,0xaf,0x58,0x39,0x39,0x95,0x5d,0x4b,0x8e,0x1b,0xe9,0xf1,0xf6,0xa9,0xb3,0xfc,0xe6,0xe0,0x68,0x2c,0xbb,0xfa,0xd9,0x9b,0xc1,0x69,0xf3,0x5a,0x8f,0x67,0xd5,0x9c,0x11,0x1e,0x02,0x20,0x20,0xfe,0x4b,0xc9,0x8b,0x62,0x17,0x9a,0xfa,0x47 +.byte 0x7f,0xa2,0x8b,0xc1,0x3b,0x02,0x78,0x38,0xff,0xce,0xe1,0x54,0x40,0x3f,0x27,0x5c,0x9d,0xdd,0x56,0x38,0x48,0xea,0x39,0xbe,0xa0,0x76,0x43,0x82,0xef,0x74,0x50,0xdf,0xda,0x4c,0xca,0x47,0x46,0x7e,0xc5,0xff,0xce,0x66,0xdf,0xeb,0x5b,0x6e,0x45,0x77,0x19,0xac,0x01,0x1f,0x20,0xa1,0xad,0x01,0x5f,0x87,0x3e,0x3a,0xd0,0x83,0x13,0x17 +.byte 0x53,0x40,0xfe,0x26,0x99,0x42,0xfa,0x54,0xa8,0x82,0x79,0xa7,0x44,0xd0,0x9e,0x59,0x64,0x77,0xec,0x70,0x0e,0xcd,0xb9,0xb1,0xc2,0xe2,0x39,0x93,0xb7,0xd1,0xd5,0x67,0x9f,0xb0,0x5b,0xd9,0x50,0x8b,0x17,0xec,0xbc,0x83,0x64,0x35,0xaa,0x43,0x3f,0x4c,0x8c,0x56,0x83,0x76,0xa2,0x72,0x30,0xe7,0xe8,0x9f,0x88,0x35,0x8e,0x8d,0x11,0x31 +.byte 0x8e,0xb5,0x71,0x75,0x31,0xc8,0x28,0x15,0x50,0xe6,0x0a,0x00,0x4d,0x75,0x51,0x7c,0x33,0x14,0x96,0xff,0xe8,0xf3,0xa0,0xb1,0x9c,0xeb,0x9d,0x8a,0x45,0xcf,0x62,0x82,0xeb,0xce,0xea,0xa5,0xb9,0x10,0x83,0x54,0x79,0xf8,0xcf,0x67,0x82,0x1d,0xea,0xce,0x86,0xcf,0xc3,0x94,0xf0,0xe8,0xf4,0x80,0x8b,0x84,0x96,0x06,0x2e,0xe4,0x58,0x21 +.byte 0x98,0x42,0x1a,0xb7,0x8c,0x5d,0x30,0x15,0x83,0xe8,0x17,0xd4,0xb8,0x7b,0x90,0x57,0x35,0x72,0x6d,0x1b,0x7c,0xc0,0x88,0x0a,0xa2,0xea,0xcd,0x58,0xcc,0xf1,0xb4,0x8b,0xcd,0x66,0x3c,0xa5,0xb0,0xd4,0xc9,0xcc,0x42,0x1d,0xef,0x3b,0x42,0x22,0x9b,0xfb,0x45,0x24,0xcc,0x66,0xd7,0x67,0x73,0xb2,0x12,0x03,0xf6,0xa3,0x06,0x61,0xe2,0xab +.byte 0x91,0x8e,0x33,0x0b,0x9f,0x6a,0x80,0x5e,0x0f,0x68,0x41,0x5a,0x7e,0xd8,0xe2,0x32,0x50,0xc2,0x88,0x60,0xca,0xe3,0x23,0x86,0xff,0xdc,0x0c,0x19,0xbb,0xba,0x01,0xa3,0x41,0x89,0xf0,0x79,0x55,0x79,0xa6,0xa4,0x66,0x7b,0x46,0xde,0xac,0xae,0xb1,0xde,0xe1,0x1e,0x8d,0x62,0xc1,0xd6,0xeb,0x39,0x2f,0x1d,0x50,0x27,0x53,0xc9,0xea,0xb6 +.byte 0xd3,0x91,0x9b,0xdd,0xc1,0x68,0x8c,0xb6,0xe1,0x5e,0x9f,0xea,0xbe,0x98,0x88,0xeb,0xa8,0x77,0xf6,0x69,0x64,0xab,0x99,0xf3,0x7a,0x08,0xff,0x8c,0xa6,0x17,0x1b,0x2e,0x6e,0xcc,0xd8,0x33,0x30,0xef,0x5a,0x86,0x07,0x49,0xa5,0x13,0x08,0xbc,0xd6,0x88,0x7e,0x19,0xe0,0x1c,0x23,0xa9,0xe5,0x0a,0xa7,0xaf,0x8a,0xe9,0x81,0x3f,0xd8,0x99 +.byte 0xa6,0x01,0x6b,0xec,0x14,0x08,0x90,0xb1,0x76,0x16,0x3a,0xcb,0x34,0x0b,0x91,0x26,0xe9,0xec,0xe5,0xbc,0xd6,0xdc,0xf0,0xa9,0xfd,0xf2,0xe9,0xcc,0xa1,0x9d,0x7f,0x32,0x0d,0x0a,0x2a,0x92,0xff,0xc4,0x38,0xf8,0x9e,0x31,0x78,0x47,0xbf,0x3f,0x27,0x71,0xe1,0x7a,0x33,0x48,0x91,0xe8,0x8e,0x1a,0x66,0xcf,0xa1,0x61,0xc2,0x62,0x30,0x7c +.byte 0x69,0x35,0x21,0x67,0x9b,0xa7,0x1c,0x72,0x06,0xd8,0x28,0x94,0x6e,0x6d,0xf0,0x22,0x85,0xb4,0x6c,0x89,0xe8,0x2e,0x3a,0xc5,0xdc,0xe3,0xe3,0x0c,0x8a,0xba,0x1c,0x57,0x86,0xef,0x55,0x6a,0x24,0x59,0x5e,0x6e,0x47,0xb8,0xad,0xc5,0x10,0xff,0xbe,0x2d,0x93,0x09,0xfe,0x17,0x03,0x16,0x4d,0x4a,0x9a,0x15,0x38,0x94,0x38,0x18,0x45,0xa7 +.byte 0xcf,0xe4,0x16,0xd3,0x26,0x72,0x49,0xe7,0x89,0x9a,0xb4,0xc7,0x78,0xc3,0x18,0x3b,0xc8,0x08,0x9d,0x66,0x0f,0x48,0xc8,0x23,0x91,0x57,0x61,0xf1,0xf3,0x01,0x3e,0x0a,0xa3,0x4c,0x6c,0x34,0x5b,0x98,0x40,0x47,0x42,0xc1,0xeb,0x58,0x58,0xff,0x1f,0x4b,0x5f,0xf1,0x29,0x2e,0x7e,0x76,0x15,0x56,0x17,0x9c,0xe7,0x55,0x09,0x22,0x0a,0xa2 +.byte 0xd8,0xbf,0xd9,0x44,0x49,0xa9,0x24,0xd7,0x4f,0x12,0x04,0xa2,0x18,0x1c,0xdc,0x54,0xc0,0x22,0x27,0x3c,0xeb,0x1f,0x02,0xae,0xb3,0x33,0xb2,0xa2,0x84,0x23,0x76,0xc6,0x2b,0x94,0x53,0xae,0x7b,0xee,0xbb,0x81,0x64,0x8a,0x3f,0xe0,0x75,0x6b,0x2c,0xd5,0x60,0xad,0x49,0x0c,0xf8,0x65,0x64,0x1a,0x83,0xc7,0xb9,0xd9,0x01,0x5b,0xde,0xb0 +.byte 0x76,0x9b,0x1c,0x0d,0x89,0x2d,0xd5,0x09,0xc7,0xa9,0xbb,0x0a,0x54,0x5c,0xd4,0x5b,0xbf,0xbc,0x5e,0x00,0x29,0x0b,0x30,0x19,0x73,0x66,0xfd,0x3f,0xdb,0xd4,0x1b,0xd4,0xc0,0x27,0xde,0x49,0x90,0x5f,0x65,0x87,0x3c,0xc4,0x43,0xd0,0x49,0x76,0x64,0x39,0x88,0xd7,0x0e,0xfc,0x27,0x52,0xb1,0x8d,0xd0,0x27,0x29,0x84,0xe3,0x49,0xb9,0x0c +.byte 0x2d,0x4e,0x73,0x95,0x57,0xa8,0x07,0xa0,0xe1,0x5b,0x5a,0xb6,0xbc,0xa1,0x7f,0xfd,0x4b,0x9c,0x4d,0x7d,0x0c,0x5c,0x4c,0x4b,0x42,0x70,0xc3,0x0a,0xc1,0x89,0x12,0xb5,0x46,0x04,0x3c,0x56,0x25,0xc6,0x8f,0x49,0x7d,0x3b,0xf1,0xcd,0xfc,0xb8,0xa6,0x66,0xb1,0xc2,0xa3,0xa7,0x98,0x93,0x0e,0xdb,0xcd,0xce,0xdf,0x7f,0x68,0x5e,0xea,0xf2 +.byte 0x85,0x61,0x8f,0xd6,0x23,0xb4,0x5f,0x2f,0xf8,0x78,0x47,0x15,0x59,0x2d,0xca,0x35,0x0f,0xf5,0x91,0x74,0x3b,0x32,0xe1,0xcf,0x54,0x1b,0xf4,0x9d,0xdb,0x20,0x5e,0xf8,0x71,0x10,0xa3,0x31,0xf1,0xb8,0x98,0x8d,0x76,0x70,0xce,0x4c,0xed,0xd3,0x81,0x6b,0xd5,0x8d,0x73,0x5f,0x8c,0x66,0x7c,0x87,0x73,0xfa,0x20,0xbe,0xcd,0xba,0x41,0x88 +.byte 0x46,0xc3,0x38,0xc0,0xd9,0x08,0x79,0x30,0xda,0x7f,0x2a,0xc0,0x72,0x47,0xb0,0xc9,0x41,0x68,0xb1,0xe8,0xb4,0x86,0xcb,0x5d,0xb0,0x5b,0x7a,0x26,0xfd,0xf2,0x1b,0x4e,0x1f,0x4c,0x6a,0x8a,0x84,0xd4,0x07,0x2f,0xf4,0x06,0x73,0x3d,0x1c,0x55,0x04,0x6a,0xa5,0x8a,0xbb,0xaa,0x8a,0x8d,0x8f,0x05,0xcc,0x63,0x04,0xe0,0xc6,0x6f,0x6b,0xf8 +.byte 0x24,0x56,0xbb,0x9d,0xa9,0xe5,0x4c,0xac,0x9d,0xbe,0xfd,0x70,0x9d,0x1f,0x98,0xc4,0xfc,0xdb,0x3c,0x45,0xe7,0xbb,0xea,0x51,0xb6,0x56,0xe0,0x2c,0xb2,0x77,0x1b,0x80,0x9b,0x43,0xa7,0xb2,0x9a,0x40,0x8f,0xdb,0x2d,0x51,0x7b,0x2c,0x89,0xfd,0x14,0xf5,0x77,0xbf,0x40,0x3d,0x32,0xe0,0x10,0x32,0xcd,0xc4,0x3f,0xe2,0xe8,0xb4,0xdf,0xc2 +.byte 0x43,0x7a,0x0b,0x17,0x72,0xa1,0x0e,0xd6,0x66,0x35,0x8f,0xf4,0x21,0xf1,0xe3,0x46,0x13,0xd7,0xcd,0xc7,0x7b,0xb4,0x9b,0x39,0x1e,0x33,0x3c,0x18,0x15,0x7a,0xea,0x77,0xc5,0x57,0x4d,0xf9,0x35,0x8a,0xc1,0xb5,0x78,0x5d,0xc3,0x3e,0xd5,0xfd,0xb5,0x50,0xee,0x44,0x24,0xa2,0x55,0xb6,0xd8,0x3d,0x5d,0x75,0x2a,0x26,0x37,0xe7,0x85,0xb3 +.byte 0xff,0x70,0x5d,0x99,0x8d,0x99,0xba,0x9d,0x09,0x97,0xf2,0x67,0xe5,0xa3,0x86,0x06,0x21,0xb4,0x03,0x9b,0x63,0x76,0x1f,0xf8,0x09,0xd8,0x4e,0x22,0xcb,0x48,0xcf,0x79,0x72,0xc9,0x3f,0x84,0x5e,0xb8,0x39,0x87,0x27,0x92,0x1e,0x59,0xdf,0xc2,0xe6,0xd2,0xc4,0x5f,0xad,0x6e,0x9c,0xa4,0xec,0xd5,0x7d,0xf6,0x2b,0x9b,0x93,0x56,0xcd,0xa3 +.byte 0xc5,0xfa,0x82,0x39,0x46,0x29,0x57,0x43,0x08,0xe2,0xe1,0x3e,0x80,0x3b,0x8e,0x08,0xe5,0xc5,0xfe,0x05,0x17,0xaf,0xe0,0xf0,0xb7,0x5b,0x34,0x33,0x59,0xfa,0x93,0xbf,0x6a,0xb3,0x6c,0xbc,0x99,0x62,0x34,0x2c,0xf2,0x3b,0x62,0xf2,0x1c,0x48,0x07,0xc9,0x60,0x03,0xa5,0xe1,0x66,0x8d,0x84,0x36,0xc7,0xf9,0xc6,0x3b,0xa9,0xee,0x0f,0x48 +.byte 0xff,0xff,0xad,0x95,0x21,0xb5,0x12,0x63,0x7d,0x0f,0x0d,0x09,0x63,0x51,0x64,0x69,0xb4,0x95,0xd3,0x25,0xf0,0x3b,0x6d,0xc4,0xdd,0x8c,0x80,0x0d,0x3b,0xd2,0x4b,0xe0,0x67,0xcb,0xcd,0x7d,0x2e,0xbd,0x61,0x4b,0x0c,0x32,0x1f,0xfd,0xd2,0x31,0xed,0xa8,0xaa,0x98,0xf4,0x85,0x21,0xbc,0x08,0x14,0x2f,0xbb,0xbf,0x01,0xba,0x24,0x5e,0x5c +.byte 0xf3,0x72,0xed,0x05,0xec,0xf3,0xd1,0x9b,0xb0,0x63,0x8a,0x14,0xd1,0x9e,0xae,0x9b,0xce,0x4d,0x6c,0xb6,0x7a,0x78,0x9e,0x1d,0xcd,0x1e,0x50,0x66,0x26,0x70,0x74,0x2b,0x43,0x6a,0xc7,0xd7,0xe9,0xa2,0xcf,0xf3,0x09,0x9a,0x81,0x80,0x04,0xb8,0x5a,0x4f,0x2e,0x10,0x35,0xb2,0xb0,0xc6,0x40,0x97,0xa5,0x6a,0x24,0x5a,0x6b,0x97,0xc7,0xc0 +.byte 0x24,0x50,0x8d,0x65,0x21,0x25,0xce,0xb9,0x19,0xfc,0x40,0x08,0xcf,0xfd,0x1c,0xc4,0x30,0xd4,0x06,0x70,0xac,0x8a,0x3c,0x3f,0xfc,0xc3,0xeb,0xdd,0x43,0x56,0x4a,0xf6,0x50,0x92,0x9d,0xce,0x9c,0xea,0x15,0xdd,0x7c,0x5e,0x40,0xf5,0x7e,0x41,0x70,0xdd,0xc7,0x62,0x21,0x5a,0x20,0xc8,0x71,0x10,0x97,0xd5,0x12,0xfa,0x31,0x96,0xfb,0x38 +.byte 0x17,0x66,0x73,0x32,0x7a,0x93,0xf0,0x82,0xb9,0xf1,0x24,0xc5,0x64,0x0b,0xa9,0x24,0x4a,0x47,0xac,0xfb,0xf1,0x55,0xd7,0xb3,0x9a,0x64,0x63,0x0b,0x2e,0x13,0x9e,0x1a,0xee,0x21,0xd0,0x70,0x5c,0x0c,0x25,0xe7,0x38,0x23,0xd7,0x2f,0x6a,0x20,0x59,0xef,0x70,0xb2,0x8e,0xb4,0x15,0xee,0x6f,0x70,0xd0,0x75,0x19,0x9d,0x42,0xa7,0x17,0xad +.byte 0x99,0xaa,0x0d,0xa3,0x87,0x3d,0xf1,0x7b,0x0e,0xfa,0x62,0x9a,0x20,0x64,0x17,0x64,0x07,0xc2,0x84,0x13,0xb2,0x59,0x81,0x66,0x45,0xab,0x47,0x6d,0xfc,0x7b,0x60,0x05,0xac,0x30,0xb2,0x86,0x7e,0x34,0x6b,0xaf,0x37,0x00,0xa6,0x47,0x4c,0xb9,0x10,0xbd,0x9e,0xce,0x47,0x9e,0xc2,0x0e,0xfd,0x47,0xfa,0xd8,0x08,0xd1,0xc2,0xaa,0x6d,0x8c +.byte 0x91,0x2c,0x18,0x32,0x52,0x84,0x47,0x71,0x3b,0xc9,0xa1,0xf5,0xfc,0x90,0xb8,0x79,0xbf,0xe5,0x59,0x1b,0x91,0x22,0xcb,0xd3,0x87,0x7e,0xd4,0xb5,0x33,0xb2,0xfc,0x7c,0xee,0x22,0xfb,0xe8,0xb0,0x3c,0xa7,0x8b,0x05,0xd7,0x7f,0x17,0x52,0xbe,0xb6,0xe0,0x1e,0x47,0xce,0xfd,0x79,0xdf,0x16,0x5f,0x01,0x70,0x0c,0x47,0x5a,0x01,0x96,0x08 +.byte 0x3e,0x9b,0xc4,0xb2,0x58,0x73,0xc4,0x38,0xd6,0xf2,0x1b,0x0a,0x2c,0xb9,0x2a,0x96,0xb5,0x89,0x2d,0x33,0xdf,0xa4,0x5f,0x24,0x1b,0x79,0x0e,0xb6,0x9f,0xec,0x46,0xd3,0x27,0x4a,0xc1,0x26,0x94,0x95,0x41,0xd5,0xb3,0x84,0x74,0x62,0x47,0xc5,0x4d,0xb4,0xe2,0xe7,0xdb,0xc3,0xc3,0x7b,0x33,0x2a,0xbf,0x69,0xf6,0x5e,0xdc,0xfe,0xa4,0x81 +.byte 0x91,0xf3,0xa8,0x26,0x82,0x44,0x37,0xea,0xe1,0x20,0xff,0x52,0x33,0x5b,0x0b,0x6f,0xf8,0x33,0x4e,0x02,0x4d,0x38,0x93,0xcd,0xc0,0xfc,0x73,0x1a,0xf9,0xf6,0x9f,0x53,0xfc,0xf7,0xe2,0x4b,0x25,0xdd,0xa7,0x4d,0x1e,0x5c,0x17,0xc3,0xa0,0x41,0x1d,0x67,0x45,0xff,0xcb,0x41,0x49,0xc4,0x18,0x68,0x7e,0x7f,0xb6,0x6f,0xdb,0xbc,0x73,0x2f +.byte 0xc7,0x9a,0x46,0x8c,0x0b,0x57,0xa3,0xd3,0x0a,0x34,0xb7,0x27,0x67,0xbb,0xe1,0x64,0xa7,0x7e,0x79,0xac,0x4f,0x09,0x54,0x9b,0x43,0x5e,0x9a,0x33,0x02,0x45,0xdc,0x85,0x0b,0x59,0x8d,0x78,0xe8,0xd8,0xb5,0xd3,0x31,0x9d,0x2a,0x60,0x5b,0x91,0xed,0xf1,0xf1,0x37,0x3f,0xdb,0xda,0xd6,0xd1,0x8f,0x14,0x7e,0xe1,0xfc,0x92,0x60,0xa5,0x33 +.byte 0x86,0xef,0x29,0xbf,0x94,0x84,0x2b,0x24,0x20,0xb4,0x5e,0x23,0x34,0x08,0x63,0xc9,0xe6,0x80,0xa0,0x27,0x27,0x2f,0xab,0xc0,0x52,0x44,0x66,0x29,0x32,0x2e,0x91,0x96,0x02,0x1c,0x3b,0xb4,0x6e,0x33,0x49,0x5b,0x60,0x6f,0x14,0x93,0x65,0x0d,0x97,0x01,0xfb,0xf9,0x42,0x74,0xb6,0x21,0xf7,0xc2,0x5d,0xbf,0x91,0x2b,0xf5,0xb1,0x4e,0xe2 +.byte 0xd6,0x24,0x57,0x41,0x7a,0xcb,0xdd,0xb6,0x96,0x8b,0xfc,0x42,0x19,0x21,0x7f,0x41,0x32,0x3d,0x69,0x9b,0xee,0xda,0x97,0x45,0x26,0x71,0x0d,0x12,0xf0,0x20,0x7f,0x44,0x0f,0x4c,0xd2,0xd3,0x34,0x93,0xc7,0xe5,0xe7,0x83,0x62,0x13,0x0b,0x7d,0xc6,0xe4,0xd2,0xae,0x53,0x2e,0xd1,0x18,0x81,0xd0,0x81,0xf6,0xc0,0x98,0xaf,0x1d,0xb2,0x8a +.byte 0xcb,0xd3,0xde,0x1d,0x53,0x71,0x92,0x0e,0x4b,0x8c,0x7c,0x8e,0x65,0xf6,0xe2,0xc2,0x5a,0x4f,0x8c,0x59,0x0f,0x35,0x5e,0xe4,0x43,0x50,0xab,0xb7,0xdd,0xfc,0x66,0xf9,0xb1,0x9b,0x6b,0x1b,0xaf,0x2e,0x85,0xe6,0x3e,0x4c,0xa2,0xd4,0x55,0x47,0xb9,0x66,0x66,0x7b,0xa3,0xb2,0xd5,0x8a,0x8e,0x88,0x0e,0xfb,0x4e,0xad,0xf4,0x39,0xd2,0xd6 +.byte 0x39,0xef,0xe0,0xee,0x0f,0xf3,0x94,0x47,0xa7,0x32,0x24,0x9a,0xb0,0x82,0x08,0x67,0x00,0x3f,0xe6,0x95,0x76,0x84,0x0a,0x5c,0xb7,0x74,0xc1,0x64,0x5e,0x7c,0xba,0x0b,0x2e,0x6f,0x26,0xc3,0x20,0x2e,0x95,0xc1,0xf0,0x8c,0x55,0x4a,0x45,0x26,0xe6,0xf3,0x55,0x78,0xbd,0xd4,0xdb,0x07,0xbd,0xff,0x61,0x51,0xde,0x7f,0xdb,0x56,0x73,0x6b +.byte 0x9c,0xa4,0xb0,0x72,0xa7,0xd0,0x93,0x4d,0x1d,0x3a,0x92,0x78,0xde,0x77,0x65,0xe8,0x07,0x41,0x92,0xc1,0xbb,0x69,0x79,0x20,0x43,0xab,0x21,0x2e,0x6d,0xdf,0x43,0xeb,0x73,0x49,0x12,0x1f,0x53,0x75,0x01,0xed,0xce,0xf4,0x05,0x05,0x2b,0xc7,0x2a,0x65,0x29,0xe8,0xcf,0x5b,0xf0,0xc1,0x5b,0xd8,0xa8,0xac,0xbb,0xe3,0xac,0x29,0x0a,0x90 +.byte 0x79,0x2f,0x5b,0x92,0x14,0xf2,0xc7,0x2d,0xe5,0x33,0x6e,0x5e,0x31,0xe2,0xab,0xdf,0x21,0x71,0x4a,0x44,0xaa,0xc6,0xe9,0xb8,0x51,0x1d,0xe2,0xf3,0x07,0x19,0xa1,0x98,0x9e,0x8a,0xed,0xe4,0x9e,0x52,0x16,0x1f,0x2f,0xd3,0x4c,0x97,0x1e,0x38,0x49,0x84,0x2e,0x45,0xb5,0x4b,0x4f,0xfe,0xdb,0x25,0x3e,0xa9,0x6e,0x7d,0x60,0x3b,0xa7,0x7e +.byte 0xda,0x32,0x1a,0xd6,0x04,0xbe,0x0c,0x92,0x4e,0x6d,0x85,0xf9,0x9c,0x26,0x9a,0x88,0xf5,0x50,0x95,0x7b,0x9e,0x43,0x07,0x97,0xd4,0xdb,0xa0,0x6e,0x30,0x5d,0x44,0xa9,0x41,0xc2,0xdf,0xdf,0x37,0x35,0xc4,0x85,0x83,0x08,0xea,0x22,0xfa,0xae,0xdd,0x95,0xe5,0x35,0x47,0x23,0x86,0x27,0xfa,0x71,0x88,0xa0,0x12,0x00,0xe0,0xa7,0xd1,0x1b +.byte 0x5e,0x78,0x6f,0x38,0x30,0xa9,0x80,0x75,0xd7,0x61,0xcc,0xfd,0x33,0xd2,0xb8,0xf8,0xd7,0x12,0xf5,0x03,0xf9,0x53,0x6d,0x3b,0x6b,0xff,0x24,0x0a,0x3b,0xe8,0x2a,0xe9,0xae,0xb7,0xc3,0xe3,0x0f,0x26,0x71,0x55,0xc5,0x03,0x60,0xf4,0x47,0x01,0xa3,0x69,0xb2,0x98,0x75,0x5b,0x90,0x4a,0xf9,0x61,0x49,0xd6,0xc4,0xdb,0xab,0x04,0x0c,0x47 +.byte 0x1e,0x31,0x75,0xfa,0xa2,0xc5,0xfa,0x66,0x0c,0x4a,0x93,0xa0,0xea,0x56,0xf9,0x49,0xd4,0xc7,0xcc,0x2c,0xe5,0xdc,0xab,0x61,0x8e,0x0c,0xf3,0x2f,0xb5,0x9f,0x36,0xa1,0x05,0xab,0xb6,0xbc,0x4a,0x6d,0x97,0xe7,0x19,0xe5,0xfe,0x92,0xa5,0x94,0xd5,0xc0,0xf5,0x31,0xf6,0x8a,0xf7,0x24,0x62,0xdd,0x56,0x12,0x84,0xf5,0xc6,0xa0,0x37,0xa3 +.byte 0xfc,0xbd,0x16,0x2a,0xa6,0x36,0x8e,0xd4,0x29,0xfe,0xc4,0xc5,0xcb,0xdd,0xdd,0x8b,0x7e,0xa6,0x9d,0x08,0x28,0x10,0x6b,0xff,0xd7,0x79,0x48,0x35,0x2f,0xbe,0x34,0x9a,0xfb,0xd0,0x7d,0x5c,0xad,0xf0,0xde,0x96,0xea,0x2d,0xc5,0x8b,0xa9,0x7a,0x8b,0xbe,0x97,0xde,0x7a,0x95,0xc7,0x95,0xd9,0x86,0xde,0x3c,0x8d,0x15,0x8e,0x45,0x69,0x27 +.byte 0xd4,0x27,0xa8,0xe3,0xa9,0x1e,0xa0,0x95,0x74,0xf1,0x8b,0xbe,0x3b,0xff,0xa3,0xf6,0x23,0x78,0xd9,0xbd,0xc2,0x44,0x3a,0x93,0xb5,0xa6,0x87,0x7c,0x65,0xd1,0xd8,0xd5,0x43,0x2a,0xb2,0xc8,0x65,0x86,0x83,0x06,0xf7,0x33,0x88,0x3b,0xc0,0x2c,0xb3,0x3b,0x23,0xa3,0x67,0x15,0x49,0x09,0x02,0xbb,0x11,0x08,0xe3,0x37,0x9a,0x9b,0x67,0x8e +.byte 0x63,0xc3,0x8b,0xff,0x21,0xa6,0xbe,0x3b,0xa6,0x57,0xc1,0x56,0x2a,0x02,0xdb,0x24,0x50,0x4a,0x4f,0x60,0x49,0x03,0xcf,0xba,0x55,0x1c,0x64,0xfe,0x0c,0x58,0xb4,0xb0,0x89,0x91,0xd5,0xbc,0xbc,0x85,0xe6,0x96,0x32,0x89,0x1f,0xa0,0x48,0xd1,0x6e,0xa7,0x03,0x86,0x8a,0xf2,0x5f,0xc3,0x5a,0x57,0x8a,0xa3,0x4a,0x61,0x90,0x18,0xb2,0x0d +.byte 0xc7,0x94,0xb9,0x3e,0x40,0x8b,0x1d,0x54,0xd0,0x4c,0xe7,0x2a,0xd5,0x85,0xa7,0x93,0x07,0x10,0x58,0xc4,0x8a,0x18,0x0a,0x49,0x30,0x87,0x93,0x0e,0xcf,0xc7,0x95,0x9f,0xd1,0x3f,0x9b,0x06,0xe3,0xf9,0x4f,0x16,0x58,0x04,0xb4,0xf0,0xf0,0xf3,0x3a,0xab,0x4a,0x35,0xf1,0xec,0x23,0x15,0x0c,0x24,0xba,0x90,0xdc,0xd1,0xfe,0x47,0xca,0xb2 +.byte 0x95,0x33,0x30,0x45,0xba,0x18,0x15,0xec,0x58,0x36,0x02,0xdf,0x28,0x09,0x74,0x4b,0x09,0x01,0x24,0x0f,0x00,0x7b,0xb3,0x65,0x45,0x42,0x63,0x15,0xf8,0x50,0x8b,0x4f,0x28,0x73,0x03,0x3a,0x31,0xe5,0x0d,0x56,0x8f,0x6b,0x4b,0x9e,0xda,0x71,0xee,0x68,0xba,0x85,0x81,0x3d,0x5d,0x74,0x5e,0xda,0x60,0x87,0xf4,0x5a,0x38,0xad,0xc5,0x3f +.byte 0xb5,0x15,0x02,0x59,0x1c,0xd2,0x93,0x66,0x54,0x65,0xf1,0xe7,0x9b,0xf0,0x30,0x2d,0x9e,0xba,0xc5,0x86,0xf4,0xf6,0xc7,0x92,0x73,0x12,0x3b,0x28,0x21,0x1b,0x3d,0x84,0xc0,0x1a,0x7d,0x35,0x8b,0xd4,0x35,0x39,0x35,0xa6,0x51,0xd9,0x19,0x8b,0x92,0xa3,0xea,0x8c,0x7e,0x25,0x05,0x1f,0x1d,0x8f,0x4d,0xba,0xdf,0x20,0x8c,0x8d,0xe2,0xac +.byte 0xdd,0x3d,0xf1,0x04,0x3f,0x77,0x4b,0x8f,0x39,0x7d,0x01,0xb7,0x71,0x4b,0x7b,0xe1,0x6f,0xd4,0x28,0x1a,0x57,0x96,0x4d,0xe2,0x84,0xf6,0x64,0x10,0xbb,0x0f,0xbc,0xe0,0x19,0xed,0x92,0x9e,0x60,0x15,0x78,0xd1,0x30,0xc0,0x53,0x4b,0x94,0xca,0x4b,0x5a,0x44,0x8b,0xa9,0xda,0x2f,0x08,0x70,0x94,0xe4,0x54,0xe1,0x28,0x6e,0xdd,0x34,0x56 +.byte 0x54,0xb0,0xd4,0x87,0x00,0x72,0x1e,0x46,0x10,0x3a,0x27,0x5d,0xc6,0xb5,0x72,0x20,0x2b,0xbe,0x17,0x01,0xbb,0x04,0x11,0x16,0x7d,0xbf,0x91,0xd3,0x7b,0x44,0x58,0x13,0x2a,0x9c,0xda,0x9d,0x26,0x46,0xf5,0x5f,0x51,0xef,0x6c,0xf6,0x36,0xdb,0xb7,0x21,0xde,0xdb,0x87,0xa0,0xd8,0x60,0x24,0x86,0x6d,0x64,0x85,0x9e,0x94,0xd9,0x21,0x0d +.byte 0xed,0xda,0x33,0xea,0x3c,0xdf,0x74,0xe3,0xa5,0xc7,0xc7,0x9e,0xe5,0xb1,0x29,0xdf,0xfa,0x20,0x25,0xcd,0x13,0x08,0xee,0xe6,0xba,0xf1,0x62,0x39,0xcf,0xe3,0x29,0xb8,0xaa,0x65,0x43,0x8a,0x48,0xb5,0xb5,0x70,0x35,0x66,0x42,0xf4,0x32,0x70,0x0b,0x0c,0xa7,0x46,0x79,0xdf,0xb2,0x80,0x13,0x72,0x7a,0xeb,0xf9,0x52,0xcb,0xb8,0x9f,0x4b +.byte 0x4f,0x29,0x2b,0xb3,0x94,0x02,0x0a,0xe1,0x20,0xe5,0x91,0x15,0x6a,0xa1,0x0c,0x71,0x96,0x77,0x01,0x80,0xf7,0x51,0x0b,0xaf,0x54,0x9b,0x3c,0x7b,0x91,0xd2,0xbd,0xaf,0x13,0xa5,0x32,0x17,0x7c,0xca,0xd0,0x22,0xd5,0xe5,0x83,0x44,0x24,0x5c,0xcc,0x24,0x31,0xcd,0x81,0x4e,0x96,0xcd,0x60,0x9f,0x7a,0xe7,0x2e,0x89,0x16,0xd5,0x66,0x6b +.byte 0xac,0x31,0x11,0x7c,0x76,0xc6,0xde,0xbe,0x46,0x55,0x20,0xdf,0x9d,0x2c,0x33,0xa5,0x80,0x76,0xb1,0xc9,0x1c,0x84,0x17,0x4d,0x15,0xe6,0x6d,0xce,0xed,0xea,0xc7,0xe6,0xff,0x01,0x10,0x60,0x26,0xf7,0x63,0x5f,0x91,0x89,0x7e,0xc1,0x7c,0x76,0x67,0x7b,0x7e,0xfa,0x28,0xa0,0xa7,0x82,0x1b,0x28,0x82,0x6a,0x4f,0x78,0x61,0x48,0xbf,0x13 +.byte 0x0b,0x71,0x0c,0xad,0xee,0xd7,0xf8,0xcc,0x0f,0x77,0x74,0x7d,0x2b,0x8a,0x09,0xd8,0x47,0xa0,0xfc,0x45,0x40,0x24,0xf3,0xce,0xdb,0x81,0xa1,0x50,0x9e,0x0a,0xd0,0x58,0xf7,0xaf,0xf1,0x09,0x12,0xa8,0x24,0xb2,0x34,0x99,0x67,0x17,0x53,0x1f,0x9d,0x09,0x7b,0xcb,0x83,0x6e,0x6a,0x0b,0xbf,0x8f,0x6e,0x3d,0xdb,0x29,0xe5,0xd0,0x06,0xdb +.byte 0xb8,0xf2,0xf3,0x43,0x4e,0xa7,0xf3,0x73,0x93,0xe8,0xab,0x2f,0xc8,0x75,0xce,0x62,0xda,0x74,0x39,0x57,0xe4,0xe4,0xb1,0x41,0x8f,0x9d,0xda,0x43,0xb4,0x2c,0x4b,0xd5,0x1c,0x10,0xf0,0x29,0x6b,0x94,0x15,0x04,0x3c,0xd3,0x45,0x73,0x29,0xb3,0x60,0x87,0x93,0xdb,0xbf,0x60,0x4e,0xdf,0x4d,0xbb,0xde,0xb2,0x57,0x67,0x14,0x0d,0x0b,0x60 +.byte 0x63,0xd5,0xc6,0x81,0x82,0xd6,0x0c,0xe6,0x4c,0x43,0x13,0x02,0x74,0x56,0x20,0x6b,0x21,0x28,0xe6,0xe2,0x0b,0xc1,0x7a,0xc3,0x08,0x60,0x82,0xe0,0x4f,0xbf,0x1e,0x3f,0xf0,0xa9,0xb2,0x2e,0x0c,0xbf,0xd6,0x03,0x1d,0x0d,0xd6,0x1c,0x36,0xb5,0xb2,0x14,0x56,0x21,0xc2,0xe0,0x1e,0xff,0xee,0x8a,0x70,0xae,0x3f,0x1e,0xe5,0xac,0x05,0x46 +.byte 0x6b,0x81,0x32,0xce,0x50,0xbb,0x82,0x66,0x32,0x93,0x46,0xf7,0xee,0x77,0x1c,0x9a,0x2f,0x31,0x60,0xa2,0x09,0x7c,0x14,0xd9,0x81,0xe9,0x19,0x27,0x31,0x5e,0xa0,0x98,0x71,0x42,0x2f,0x30,0x71,0xd6,0x31,0x94,0xe0,0x61,0xed,0x50,0x66,0xfa,0xba,0x12,0x5e,0xc6,0xc8,0x67,0xe5,0x8e,0xfd,0x34,0xa9,0xeb,0xde,0x25,0x43,0xbf,0xe7,0xb5 +.byte 0x16,0xf5,0x62,0x66,0x5d,0x0b,0x13,0x9a,0xd4,0x8c,0x2b,0x8f,0xe6,0x91,0x33,0xcb,0xa0,0x70,0x48,0x3e,0x22,0x7d,0xe4,0xf3,0x75,0xc9,0x49,0x82,0x50,0xc9,0x90,0x04,0x32,0xab,0x99,0x6e,0xf1,0xf0,0x0b,0x60,0x80,0x35,0x25,0x45,0x88,0xe9,0x82,0x06,0xe1,0xbb,0x85,0x11,0x40,0xf8,0x0e,0xbd,0x19,0x7a,0xdd,0x78,0xf9,0xc2,0x46,0xe4 +.byte 0xb5,0x27,0xfb,0xb6,0xba,0xbc,0x7d,0xb8,0x27,0xe7,0xbf,0xfe,0x8e,0xfe,0x7e,0x83,0x63,0x43,0x92,0x26,0xf0,0xbb,0xde,0xb6,0x93,0x4f,0x55,0x0c,0x07,0x99,0x3c,0x98,0xa1,0x8c,0x73,0xc1,0x4c,0x9a,0x09,0xa8,0xea,0x16,0x0b,0x49,0x2a,0x43,0xee,0x90,0x61,0x6f,0x09,0x1b,0xc3,0x2d,0x62,0x4b,0xfc,0x90,0xa1,0x8e,0x84,0x2e,0x90,0x8d +.byte 0x5f,0x80,0xff,0x6a,0x3c,0x61,0x0f,0xf2,0xac,0x70,0x20,0xc1,0xf2,0x85,0xcf,0x94,0xc8,0x94,0xe7,0xa0,0x04,0xdf,0xaf,0xef,0x26,0xd2,0xbc,0x07,0x70,0xc1,0x48,0xd6,0x87,0xd6,0xbe,0xea,0x95,0x6a,0xce,0xa2,0x48,0xac,0x46,0x46,0xb1,0x74,0x70,0x96,0x6c,0x26,0x58,0x75,0x9d,0x84,0xd7,0xd9,0x17,0x9a,0x46,0xe9,0xd7,0x3d,0xde,0xfd +.byte 0x7e,0xf4,0xd8,0x7e,0xf8,0x8f,0x1c,0xb5,0xfb,0xe9,0xc4,0xca,0xba,0x52,0x5f,0x17,0xee,0x75,0x7d,0x1d,0x50,0x16,0x9f,0x16,0x1e,0x00,0x8b,0xc1,0x2f,0xab,0x73,0x65,0x88,0x7b,0x80,0xa6,0x71,0xb7,0xfb,0xb0,0xda,0xd1,0x96,0x18,0x5c,0x48,0x6e,0x18,0x45,0x59,0x45,0xef,0x5c,0x65,0x35,0x99,0x5e,0xb9,0xd4,0x1a,0x07,0x7d,0x1e,0xa6 +.byte 0x69,0x42,0x9d,0xfa,0xec,0x02,0xdc,0xc4,0x19,0x6b,0x9c,0xb1,0x5e,0xa3,0xb4,0x6d,0xb4,0xa6,0x25,0xa8,0xe4,0x3f,0x3d,0x6e,0x2c,0x95,0xf7,0xcd,0xa5,0x4e,0x32,0xca,0x7e,0xe0,0x7b,0x11,0xf9,0x0a,0xe1,0x61,0x41,0x60,0xec,0xb3,0xb1,0x92,0x89,0x33,0x17,0xe9,0xaf,0x70,0x7f,0x1c,0x07,0xb5,0x24,0x3a,0x37,0x84,0x38,0xf5,0xb6,0x11 +.byte 0xfc,0x0c,0x12,0xc1,0xfc,0xa9,0x82,0x67,0x4d,0x17,0xe8,0xea,0xd0,0x62,0x17,0xb2,0x9c,0x59,0x01,0x87,0xfb,0x54,0x8e,0xa7,0xa5,0x85,0xa9,0x8a,0xec,0xfe,0x29,0xc0,0x73,0xc6,0xa0,0xbf,0x66,0x9a,0xc5,0xf8,0xee,0xa4,0xcb,0x09,0x44,0x74,0xfe,0x32,0xf5,0x42,0xea,0xf0,0xa6,0xec,0x74,0xea,0x14,0x5c,0x43,0x51,0xfa,0x3a,0x48,0x1e +.byte 0xa0,0x2e,0x59,0x2e,0xdb,0x3a,0x19,0xfe,0x1f,0x95,0x25,0xee,0x27,0x2b,0x99,0xb4,0xe1,0xd0,0xe6,0x33,0x91,0xa1,0xaf,0x30,0xa0,0x89,0x00,0x3c,0x13,0x31,0x18,0x70,0x90,0x42,0x55,0x0a,0xc9,0xc5,0x0c,0x43,0xa5,0xee,0xd6,0x90,0x07,0xae,0xc4,0x8c,0xdc,0xe4,0x07,0xbb,0x61,0x70,0xd1,0x10,0xe4,0x68,0x96,0x70,0x78,0xab,0xe9,0x3a +.byte 0x6e,0xc7,0x75,0x93,0xa0,0xba,0xff,0x6a,0x2d,0x57,0xaa,0x93,0x09,0xc3,0x6b,0x81,0xf3,0xde,0xc2,0xee,0xac,0x86,0x0a,0xfb,0xad,0xdb,0x6f,0x2a,0xa0,0x15,0x7b,0x96,0x77,0x38,0xf8,0x86,0x51,0x33,0x7a,0x6f,0x1c,0xf8,0xd5,0x15,0xcd,0x76,0x7f,0x37,0x68,0x82,0xdf,0xab,0xc3,0xdb,0xbe,0xeb,0x2b,0xa8,0x34,0x72,0x20,0x34,0xfb,0x12 +.byte 0x64,0x17,0x05,0x64,0xc0,0xa1,0xca,0xd3,0xac,0x27,0xc2,0x68,0x28,0x40,0x42,0xe2,0x0a,0xdd,0xd7,0xd6,0xf6,0x92,0x95,0x3c,0x10,0x17,0x4e,0xef,0x75,0xae,0x98,0x2d,0x10,0xc8,0xa8,0xac,0x15,0xf7,0x5b,0x81,0xc1,0xdf,0x5e,0xbe,0x88,0x49,0xe3,0xd1,0x88,0x1c,0xcb,0xce,0x20,0x01,0x12,0x60,0x57,0x0b,0xf6,0x32,0x57,0xaf,0x59,0xef +.byte 0xc9,0xe7,0xbf,0x62,0xf3,0xb6,0xe6,0x5c,0xee,0x36,0x7e,0x11,0x90,0xd1,0xeb,0xfa,0x62,0x0b,0xc6,0xf3,0x1a,0xd5,0x8b,0x95,0xec,0xb4,0x38,0xfe,0x45,0xb0,0xb5,0xff,0x84,0x0a,0x27,0x3a,0xa2,0x5a,0x2a,0xc9,0xa4,0xc0,0x11,0xc6,0x61,0x13,0xb7,0x53,0xa3,0x47,0x45,0x6d,0xc6,0xa9,0x00,0xd1,0x40,0xf4,0x77,0xac,0xb3,0xd3,0x26,0x99 +.byte 0xf1,0x36,0x59,0x28,0xb4,0xd0,0xdd,0x0e,0xed,0x53,0x33,0x45,0x71,0x9c,0x5c,0x11,0x27,0x2c,0x2f,0x10,0x9e,0x5b,0x8a,0x5b,0xc5,0x1f,0x36,0xc9,0x2a,0xba,0xc7,0xa5,0x31,0xd7,0x9f,0x2b,0x0a,0x09,0xcb,0x7c,0x4f,0xa2,0xdc,0xc5,0x64,0x0d,0xe6,0xfe,0xb0,0x9d,0x3b,0xf0,0xa7,0x19,0x8c,0x84,0x21,0x6b,0x9e,0x1c,0xb5,0x7b,0x66,0x77 +.byte 0xd0,0x85,0xb4,0x22,0x93,0x6e,0x84,0x29,0x9b,0x60,0x90,0x37,0x9d,0x8c,0x94,0x95,0x95,0x3b,0xf1,0x2d,0x56,0x5b,0x53,0x60,0x2d,0xe5,0x7f,0x80,0x71,0x56,0xa7,0x6e,0x66,0x76,0x1f,0xaa,0x0d,0xba,0xfb,0x0e,0xcf,0x20,0x68,0x74,0x2b,0x99,0x13,0xe1,0xa8,0x33,0xc9,0xf6,0xbc,0xd3,0xf4,0x46,0x01,0x02,0x85,0x27,0xf4,0x20,0x97,0xa3 +.byte 0xba,0xbc,0x47,0x30,0x48,0xed,0x60,0xe6,0xca,0xbf,0x76,0x8c,0x2c,0x6a,0x43,0x32,0xfd,0x90,0x04,0x95,0xc2,0x42,0xcb,0xca,0xc4,0x33,0xe1,0xd3,0x23,0x92,0xa1,0xde,0x09,0x38,0xce,0x00,0x93,0xb3,0xed,0x82,0x8e,0xfb,0xce,0x4c,0x9a,0x10,0x6e,0xce,0x4a,0x37,0x05,0x75,0x37,0x58,0xc3,0x8e,0x57,0x50,0xa0,0x7d,0x80,0x2d,0x51,0xea +.byte 0x08,0xcd,0x1b,0xd2,0x81,0x85,0x19,0xc1,0xe8,0xce,0x31,0x18,0xcf,0x54,0x37,0x96,0x77,0x3d,0x64,0xfb,0xc2,0xa9,0xdb,0xb8,0x37,0x03,0x83,0x34,0x3c,0x25,0x6a,0x22,0x33,0xfa,0x27,0x70,0xc7,0x0a,0x27,0x12,0x1e,0xb3,0xd0,0x59,0x6f,0xa3,0xc5,0x73,0x95,0x4c,0x1f,0xf1,0x3c,0xb3,0xc2,0xa2,0xc6,0x45,0x17,0x53,0xa8,0xfc,0x00,0xff +.byte 0x77,0x40,0x28,0xd2,0x53,0x90,0x92,0xe9,0x86,0x6c,0xa5,0x40,0xce,0xbc,0x79,0x6f,0x8f,0x12,0xef,0x1b,0x38,0x1f,0xb3,0x24,0xf0,0x75,0x17,0x20,0x9e,0x03,0x9c,0x2b,0x51,0x57,0x93,0x44,0xce,0x74,0xc9,0x12,0xe7,0xcb,0x2f,0x5e,0x1b,0x95,0xf2,0x4d,0x2e,0x51,0x8d,0x52,0xd5,0x21,0xe3,0x1b,0x33,0xe7,0xf2,0x18,0x61,0xa2,0x53,0xdb +.byte 0x73,0xaa,0x6a,0x6c,0xf9,0xf4,0xef,0x3d,0x40,0xa3,0x00,0x80,0x82,0xed,0xe6,0x66,0xd1,0xd6,0xe9,0x93,0xd8,0x92,0xfa,0xdf,0xf9,0x9c,0x7a,0xfb,0x2b,0xc7,0xa7,0x73,0x67,0x2b,0xed,0x76,0xb1,0x52,0xaa,0xcf,0x34,0x84,0xa1,0x6d,0x56,0x85,0xef,0xcb,0xbc,0xa3,0xc6,0xf3,0x5a,0x88,0x04,0xd5,0xd8,0xf1,0x7b,0xf8,0x11,0x6f,0xa0,0x44 +.byte 0xa5,0x0f,0x76,0xed,0xd7,0x98,0xe3,0xda,0xb8,0x1b,0xc7,0xe6,0x89,0x08,0x19,0x1f,0xf8,0xe3,0x32,0x32,0xa5,0x3c,0x71,0x9f,0x11,0xde,0x50,0x29,0xb0,0x54,0x7e,0x3b,0x5e,0xeb,0xf7,0xab,0xa8,0xa0,0x35,0x96,0xc7,0xc5,0xea,0x60,0xc0,0x37,0xca,0x61,0x55,0x96,0xac,0xb4,0xd0,0x29,0x9a,0x1a,0x3f,0x9e,0xf5,0xf5,0x3d,0xed,0xc5,0x7c +.byte 0x2c,0x9d,0x67,0xf8,0x4d,0x82,0x6e,0x2a,0x9a,0xfc,0x5f,0xdc,0x02,0xb0,0x3d,0xa5,0x1c,0x08,0x5d,0x4a,0xaa,0xd0,0x38,0xfb,0xbc,0xbb,0x7f,0x37,0xfb,0xec,0xc0,0x62,0x79,0xaa,0xde,0xfd,0x23,0x9c,0x4c,0x4a,0xe1,0x48,0x40,0x36,0xc0,0x0a,0x6f,0x43,0xb7,0xad,0x4c,0xf6,0x56,0xb5,0x44,0xf4,0x72,0xcd,0x13,0x10,0xea,0x0d,0x24,0xc1 +.byte 0xa9,0x36,0x3b,0x36,0xf2,0x6e,0xf9,0x0a,0x67,0xcd,0x02,0x67,0xb3,0x5c,0x63,0x3a,0x7c,0xc1,0x3b,0xf2,0x1d,0x3d,0xf1,0xff,0xbf,0xf7,0x97,0x9f,0x30,0x1f,0xaa,0xd8,0xdb,0x53,0x9b,0x0a,0xbd,0x38,0xd8,0xb6,0xf1,0x4a,0x78,0x1a,0xc2,0x46,0xd2,0x0c,0xa8,0xcd,0x7b,0x39,0xc7,0x42,0x55,0xc8,0x3e,0x02,0x1d,0xf4,0xad,0x55,0x01,0x6a +.byte 0x11,0x2d,0xfa,0x67,0x48,0xae,0x45,0x31,0x9b,0x09,0x7d,0xd9,0xdd,0xaf,0x5c,0xd5,0x40,0x51,0x2a,0xa1,0x0f,0xb3,0x6e,0xc2,0x94,0xfe,0xde,0x70,0xaf,0x6c,0xea,0x5f,0x7d,0x3c,0x72,0x85,0x86,0x24,0x20,0x0a,0x7a,0xe7,0x69,0x32,0x66,0x7d,0x34,0x13,0x60,0x62,0xc7,0x68,0x32,0xde,0x34,0x30,0x36,0xc8,0x8e,0xb7,0x13,0x66,0xf1,0xce +.byte 0x5f,0x7a,0x3a,0xfe,0x62,0xd6,0x72,0xb6,0x1b,0x80,0x43,0x8a,0x3e,0x13,0x15,0xe4,0x1c,0x7b,0x08,0x70,0x0b,0x6e,0xb3,0xfe,0x07,0x91,0x23,0x21,0x57,0x48,0xc6,0xa9,0xa3,0xa8,0xc7,0x19,0x89,0x8a,0x49,0x12,0x25,0x88,0xd2,0x11,0xa5,0xa8,0x9e,0x0e,0xa7,0x71,0xfe,0xaf,0x88,0xee,0xa7,0x1c,0x3b,0x27,0x27,0x7e,0x79,0x92,0xed,0x77 +.byte 0x74,0x65,0xbd,0x46,0x41,0x25,0xd9,0x8b,0x21,0x73,0x9f,0xaa,0x35,0xa0,0x22,0xb3,0xc8,0x71,0x28,0x72,0xd2,0xcb,0xf4,0x2a,0x06,0x0a,0x63,0x96,0x55,0x2e,0x83,0x0b,0xe8,0x07,0x99,0x9d,0x59,0xde,0xde,0x62,0xbd,0xb4,0x3e,0x70,0x15,0xed,0x95,0xa8,0x2f,0xb7,0xa2,0xb6,0x65,0x56,0x9d,0xe5,0x81,0xa0,0x05,0x5b,0xce,0x00,0xd4,0xb9 +.byte 0x28,0x5a,0xc1,0x9a,0x74,0xc6,0xd7,0x27,0xdd,0x7c,0xbe,0xe8,0x0d,0x47,0xfc,0x81,0x05,0x6b,0x4f,0x68,0xc7,0xcc,0x5d,0xd5,0x66,0x83,0x34,0x72,0x35,0xab,0x39,0x64,0x19,0x67,0xbd,0xff,0x15,0x44,0x20,0x18,0x2a,0xaf,0xbc,0x58,0x94,0xdb,0x18,0x50,0x55,0x11,0x6a,0xc4,0x1d,0xee,0xe2,0xe0,0x75,0x73,0xf1,0xa1,0x83,0xf4,0xcb,0x40 +.byte 0x96,0xf4,0x77,0x45,0x61,0x8b,0x1a,0x8c,0x0c,0xfc,0xd2,0x7e,0x0b,0x1e,0x18,0xd2,0x95,0xa5,0x4c,0x5b,0xd6,0x9d,0x40,0x8b,0xc0,0x51,0xe8,0x2d,0xe5,0x16,0xbf,0xd7,0x98,0x8a,0xa0,0x46,0x1f,0xc4,0xe9,0x12,0x31,0x40,0xc5,0x2d,0x59,0xf8,0x9b,0x5f,0xe3,0x3a,0x10,0xdf,0xda,0x72,0x9e,0xab,0x13,0x7b,0x8f,0xc8,0x52,0x9f,0x58,0x45 +.byte 0x7a,0xe6,0x3a,0xbb,0xdd,0x1d,0xc7,0x3b,0xc4,0x26,0xdc,0x99,0x29,0xf2,0x74,0x16,0x84,0xe9,0x8a,0x86,0xc0,0x1e,0x49,0x96,0x2f,0x5c,0x2a,0x49,0x71,0x88,0xe6,0x82,0xb2,0x18,0x88,0xc1,0x86,0xcb,0x26,0x3c,0xa5,0x50,0x31,0x22,0x9a,0x8f,0x45,0x2b,0xde,0xf0,0x86,0x8e,0x13,0x86,0xc4,0x4a,0x9b,0x35,0x27,0x93,0x0b,0x13,0xc8,0xef +.byte 0x96,0x74,0x97,0x85,0x09,0xc0,0xa0,0x32,0xfe,0xc3,0xe3,0x92,0x2e,0xe8,0x54,0xbd,0xc2,0x23,0xeb,0x4b,0x02,0xf5,0x5a,0x0b,0x0d,0x58,0x50,0x45,0xe7,0x01,0xd4,0x17,0x00,0xdb,0x0d,0xd4,0x2e,0xa0,0xde,0x38,0xf4,0xb1,0x1e,0xd0,0xf0,0xa3,0x6b,0x21,0x0c,0xbd,0xae,0x84,0x7e,0x42,0x36,0x4f,0x2e,0x46,0xae,0x23,0x91,0xb9,0x06,0xac +.byte 0x86,0x7f,0x29,0xca,0xfb,0xe9,0xde,0xdb,0x90,0xfe,0x6f,0xbc,0xdb,0x3c,0x48,0x3d,0x6e,0x06,0x68,0x49,0xbb,0x43,0x8d,0x9d,0xc4,0x5f,0x45,0xcb,0x77,0x28,0xe0,0x35,0xd1,0xb4,0x25,0xb2,0x45,0x6d,0xb4,0x89,0x53,0x26,0x33,0x98,0x83,0x45,0x9d,0xf5,0xad,0xf9,0xa7,0x59,0xb6,0x6e,0xa8,0x25,0xa5,0xef,0xee,0xf6,0x6a,0xd5,0x6c,0x60 +.byte 0x9a,0xea,0x78,0x9e,0xe4,0xa2,0x29,0x0b,0x70,0xb3,0x6e,0x3a,0xfd,0x07,0xc7,0x7f,0x1b,0x07,0xc7,0xca,0x1b,0xb8,0x08,0xe1,0xc9,0x94,0xb2,0x62,0x7c,0x04,0x96,0xa6,0xda,0x65,0x28,0xfd,0xf9,0x70,0x22,0xb7,0x21,0xd3,0xa6,0x38,0x0f,0x1e,0x88,0x7e,0x73,0xec,0x04,0x99,0x8b,0x23,0x91,0x13,0xe6,0x4f,0x74,0x81,0xcc,0x1f,0xdd,0xaf +.byte 0x58,0xc4,0x80,0x00,0x4d,0x1d,0xbe,0x84,0x7d,0xfe,0x85,0xe7,0x77,0x20,0x3c,0x65,0x4e,0x0e,0x2e,0x5d,0xc1,0xd9,0xcb,0xf7,0xbb,0xc8,0x8d,0xbf,0x16,0xa8,0x1e,0x63,0xf5,0x10,0x5e,0xa5,0x9c,0x63,0xb6,0x9a,0xeb,0x98,0xa8,0xb1,0x59,0x82,0x66,0x51,0xae,0x3c,0xfc,0xa8,0x11,0x92,0xf4,0x45,0x88,0x7c,0x03,0x6f,0xe6,0x87,0xe4,0xa8 +.byte 0x79,0xbf,0xb3,0x0d,0xd6,0x0b,0x8d,0xa3,0x16,0x2a,0xfb,0x79,0xb9,0xe7,0xdb,0xa7,0xdb,0x94,0xd3,0xe6,0x3a,0xdd,0xe9,0x5f,0x30,0x7d,0x68,0x90,0x35,0xfd,0x18,0x91,0x8e,0xc5,0x12,0xd6,0xf9,0x98,0xa0,0x5b,0xcd,0x81,0x76,0x84,0x08,0xd0,0xab,0x59,0x2d,0x3b,0x8a,0xf9,0xd9,0x95,0xde,0x8b,0xbb,0x92,0xef,0x35,0xc3,0x3e,0x46,0x73 +.byte 0xf3,0x3b,0x09,0xbf,0x22,0x2b,0x9c,0x0f,0x70,0x9a,0x16,0x0e,0x4b,0xa7,0x1a,0x96,0x98,0xb7,0x5a,0x40,0x06,0x81,0xf4,0xac,0xa6,0xe6,0xab,0xf2,0xda,0x87,0x18,0x61,0xcb,0xc1,0x67,0xbd,0x2f,0x6f,0x06,0x21,0xaf,0x73,0x98,0xe1,0x3f,0x7a,0x17,0x7f,0x44,0xcb,0x1d,0xdd,0x60,0xb3,0x2c,0x58,0x20,0x8a,0x04,0x74,0x56,0x9b,0x26,0x51 +.byte 0x61,0xb0,0x07,0x50,0x53,0x83,0x31,0x42,0x59,0xb3,0x33,0xfa,0xfe,0xbc,0xad,0x7f,0x99,0x9b,0x86,0xf1,0xaa,0x85,0xf1,0xbb,0xc0,0x0c,0x91,0x8d,0x1a,0x0f,0x8f,0x9f,0xfe,0x62,0x2b,0x35,0xae,0xcc,0x8c,0x09,0xe3,0x29,0x96,0xd1,0xbe,0x7f,0x25,0xd6,0x03,0xf0,0x4c,0x53,0xad,0x5b,0x56,0x66,0x68,0x9a,0xa3,0xc4,0x07,0x71,0xde,0x49 +.byte 0x82,0xbb,0xf7,0x9a,0x2b,0x96,0xcf,0x50,0xf6,0x00,0xf7,0x0b,0x27,0xdd,0xf5,0xf6,0xc5,0xc8,0xbd,0x2a,0xa2,0x06,0x2c,0x42,0x3f,0xa0,0xf8,0xcc,0x1d,0x64,0xcf,0xbc,0xb4,0xc4,0x63,0xde,0x6b,0xd3,0xb4,0x61,0xdf,0xbd,0x73,0x50,0x34,0xc3,0x20,0x45,0x06,0x73,0x9b,0xf0,0xfb,0xa6,0x2b,0xec,0x92,0x32,0xa9,0x1f,0x4f,0x1e,0x38,0x78 +.byte 0x2a,0xd2,0x7c,0x1d,0x89,0xf9,0x70,0xbc,0xef,0x09,0x77,0xd3,0x6a,0x56,0xa1,0x8b,0x4b,0x23,0x1b,0xb1,0x2f,0xec,0x84,0xe5,0x59,0xc5,0x20,0x23,0xbc,0x3f,0x0a,0x43,0x97,0x1c,0x5e,0xf7,0xee,0xfe,0x0b,0x2a,0x42,0x08,0x2a,0x39,0x91,0xce,0x8a,0x33,0x9f,0x63,0x77,0x6d,0xf6,0xf3,0x0e,0x1d,0xb3,0xfb,0xcf,0x2f,0x7f,0x95,0xc2,0x71 +.byte 0x1c,0xa0,0x0b,0xc6,0xb8,0xde,0x4d,0xd8,0xcc,0x4c,0x4f,0xaf,0x07,0x87,0x6d,0x3b,0xab,0x95,0xab,0xa1,0x6a,0x50,0x9f,0x7c,0x35,0xb6,0x65,0xdd,0xe3,0x06,0xe5,0xb3,0x42,0x5f,0x4d,0xe5,0x3e,0xfa,0x6c,0xdf,0x19,0x58,0xd1,0xf6,0xc6,0x94,0x1c,0xce,0x30,0x90,0xd3,0xeb,0xa3,0x7c,0xe5,0x3f,0x57,0x99,0x2e,0x22,0x0a,0x94,0x2f,0xfe +.byte 0x39,0x16,0xe6,0xfa,0xd0,0xb5,0xf9,0xb4,0x88,0x61,0xa4,0xa8,0xc3,0xb8,0xb7,0x52,0xaf,0x90,0xc1,0xe0,0x19,0x78,0x04,0x2b,0x71,0x04,0x03,0x2f,0x63,0xbe,0x40,0xf5,0x82,0x3b,0x1b,0x6b,0xde,0x6d,0x1e,0x86,0x87,0x82,0xc3,0x31,0x97,0x20,0xdd,0xdd,0xce,0x61,0x64,0x99,0xf6,0xbe,0xbf,0xec,0x37,0x54,0x8b,0x92,0x29,0xda,0xc5,0x7b +.byte 0x4d,0xc5,0xaf,0xb8,0x4e,0x4b,0x4a,0x2b,0x35,0x30,0xf5,0x19,0x9e,0x32,0xd8,0x2e,0xc1,0x19,0xfe,0xd1,0x61,0xb0,0xaa,0x05,0x58,0x15,0xd9,0x0e,0x4e,0xca,0x4e,0x10,0x83,0xe6,0xe6,0x57,0xe8,0x8d,0x13,0xb4,0x6f,0x85,0x59,0xf2,0x83,0xc8,0x37,0xaa,0xa2,0xe5,0xc8,0x77,0x06,0x82,0x21,0x5d,0x84,0x58,0x67,0x9b,0xcc,0x9c,0xfc,0x1b +.byte 0x28,0x2f,0xac,0xc8,0x96,0x91,0x26,0x46,0x42,0x2b,0x68,0x57,0xb0,0x79,0x1e,0xb1,0x9b,0x92,0x2c,0xeb,0x67,0x00,0xd4,0x26,0x7d,0xca,0x45,0x97,0x55,0xea,0x2a,0x20,0x70,0x7c,0x20,0x14,0x38,0x40,0x3d,0x4f,0xf5,0x3a,0x1f,0x0a,0xe3,0x9a,0x48,0xcc,0xb2,0x7d,0xee,0x5b,0x48,0x90,0x0d,0x12,0x77,0xd8,0xd3,0xb6,0xd7,0x66,0x9e,0x48 +.byte 0xbb,0x92,0xc1,0x7c,0x4e,0x90,0x4d,0xd5,0x96,0x99,0xea,0x86,0x2d,0xb9,0x5a,0x50,0x05,0xc2,0x6b,0xa7,0x0c,0x43,0x44,0x22,0x09,0xb9,0xc0,0x56,0x47,0x5f,0xdf,0xaf,0x6b,0x91,0xe2,0xd7,0x45,0x77,0x17,0x7a,0x71,0x6d,0x27,0x93,0xe2,0xc6,0x10,0x2f,0xc8,0x3b,0x75,0x78,0x11,0xae,0x07,0xe6,0xba,0x64,0xd4,0x06,0xfa,0xf9,0x1d,0x74 +.byte 0x9e,0x4f,0x6d,0x02,0xfc,0x40,0x80,0x9a,0x2e,0xd4,0x15,0x32,0x15,0xe8,0x97,0x0a,0xd4,0x65,0x6a,0x87,0xd3,0x66,0x4b,0xb8,0x66,0x84,0x8e,0xb9,0x4b,0xa7,0xcf,0x58,0x13,0x66,0x3a,0x4e,0xa5,0x76,0x17,0x13,0x92,0x79,0x42,0x67,0x6d,0xb6,0x65,0xec,0xc8,0xb5,0x5f,0x17,0x2a,0x2d,0x4b,0x19,0xe9,0x00,0x6e,0x38,0xaf,0xe9,0x06,0xb6 +.byte 0xe8,0x99,0x69,0x8a,0x74,0xe7,0x7e,0x70,0x69,0x4b,0xbc,0xce,0x5d,0x61,0x94,0x1b,0x47,0x41,0x38,0x5f,0x2e,0xcf,0x2b,0xe1,0xcd,0xa3,0x98,0x71,0xf7,0x09,0x65,0xfe,0x5f,0x62,0x4b,0x9e,0x91,0x88,0x35,0xa2,0x66,0x02,0x1d,0xc9,0x93,0x0c,0x19,0x50,0x4b,0x95,0x71,0x79,0xdd,0x74,0xe1,0xda,0x5a,0xb7,0x38,0x70,0x61,0x18,0x3f,0x68 +.byte 0x08,0x34,0xd8,0xfe,0xbb,0xd1,0xbf,0x57,0xed,0xc2,0x52,0x6d,0x54,0x3e,0xcb,0x0c,0x32,0xc7,0x09,0xa9,0x31,0x10,0xe8,0xbd,0x70,0xe3,0x0e,0xe9,0x4f,0x7a,0xd6,0x42,0x45,0x2e,0x1b,0x3c,0x0d,0x15,0x6d,0xb4,0xad,0xe9,0xc5,0xa2,0x12,0x77,0x34,0x43,0x20,0x95,0xc1,0xb7,0x51,0x72,0xed,0x78,0xa0,0xae,0x3c,0xae,0xb4,0xd4,0xda,0x58 +.byte 0x83,0x62,0xa9,0xc6,0x01,0x3d,0x14,0x19,0x07,0x00,0x3c,0x82,0x16,0x7e,0x8a,0x91,0x78,0xa1,0x65,0x0b,0x5b,0x3a,0x40,0x72,0xe5,0xf0,0xd4,0x82,0x04,0xe4,0x01,0xf1,0x84,0x87,0x96,0x26,0x91,0x66,0x77,0xf7,0x59,0xd6,0xc2,0xca,0x29,0x3b,0x68,0x2a,0x27,0x99,0x64,0x86,0xc2,0x96,0xbf,0x11,0x3c,0xa8,0x0c,0xf7,0x86,0xb8,0xc1,0x40 +.byte 0x15,0x1a,0x84,0xe3,0x93,0x23,0x73,0xa9,0x8b,0xbd,0xb4,0x8a,0xe4,0xf1,0xa5,0x8f,0x56,0xa3,0xdc,0x77,0xbd,0x7d,0x15,0x74,0x2b,0x18,0x92,0x56,0x45,0xbc,0xaf,0xf2,0x55,0xce,0x9d,0xc2,0xab,0x39,0x90,0xec,0x78,0x3f,0xa5,0x14,0xeb,0x40,0x2f,0x01,0xca,0xeb,0xad,0x73,0x85,0xbc,0xe1,0x91,0xaa,0x77,0xa9,0x6c,0x02,0x66,0x6a,0x65 +.byte 0x63,0x6c,0x50,0x62,0x83,0x83,0xef,0x16,0x4f,0x21,0xfd,0x28,0x8e,0x52,0x66,0x5b,0x6f,0x8f,0xbe,0x8d,0x17,0xb9,0xd5,0x99,0xf7,0x39,0xd1,0xbc,0xa2,0x43,0xd7,0x0a,0x80,0xea,0x42,0xf8,0x38,0x53,0x95,0x07,0x6f,0xb7,0x7c,0xc1,0x16,0x88,0xc8,0xb7,0x59,0xde,0x76,0x51,0x2f,0x92,0xd0,0x40,0xfd,0xd9,0x2d,0xca,0x9e,0x8d,0x28,0xae +.byte 0x48,0xc1,0x0a,0xe0,0x76,0x9c,0x02,0x0b,0xc5,0xd1,0xf9,0x83,0x90,0x86,0xa4,0xeb,0x5c,0x64,0x65,0xf8,0x98,0x38,0xc5,0xce,0xef,0x6f,0xc3,0x88,0xb6,0x2f,0x8a,0x40,0x55,0x52,0x47,0x06,0x75,0x16,0x46,0x9c,0xff,0x3c,0x68,0x97,0xc3,0xfb,0x10,0x11,0x7b,0xba,0x04,0xcc,0xad,0xba,0xcf,0xf0,0xae,0xba,0xe6,0x59,0x9c,0xf5,0x27,0xeb +.byte 0xdd,0x5c,0x86,0x25,0xa1,0xb6,0xb8,0x1c,0x94,0x98,0xa5,0x79,0x82,0x4e,0xdf,0x09,0x3f,0x2f,0x8a,0x4e,0x1b,0x5a,0xab,0xd4,0xe6,0x21,0xb3,0x02,0x19,0x39,0xa9,0x2e,0x0e,0xae,0x86,0x30,0xc7,0xa0,0x00,0xed,0x72,0xdc,0x71,0x77,0x42,0x76,0x54,0x68,0xb2,0x8d,0x5d,0xc3,0x5c,0x86,0xf8,0xb1,0x6c,0x67,0xdf,0x24,0x40,0x6a,0x2b,0x1d +.byte 0xbc,0x0d,0x25,0x7d,0x9e,0x1c,0xbd,0x18,0x85,0xda,0x7a,0x86,0x5e,0xed,0x10,0x80,0x83,0xa6,0xef,0x1e,0x93,0xac,0xce,0xe6,0x32,0x35,0xdf,0xb8,0xc7,0x9b,0xf0,0x0f,0x9d,0x37,0xbd,0xd9,0x58,0x33,0x19,0xa1,0x23,0x51,0x5f,0xa7,0x5a,0x99,0x7e,0x2a,0xfd,0x85,0x3c,0x26,0xad,0xcc,0x7e,0x07,0x32,0x7b,0x24,0x5a,0x6b,0x4b,0x71,0x4e +.byte 0xca,0x8b,0xc4,0x03,0x26,0x76,0x02,0x68,0x0d,0xa1,0x09,0xe0,0x2e,0xa4,0x82,0x88,0x05,0x5a,0xc4,0xcb,0x31,0x9d,0x56,0xda,0x0d,0x00,0x04,0xbc,0x07,0xca,0x1f,0xdf,0x9e,0x44,0xed,0x36,0xbd,0xa0,0x22,0xff,0x78,0xd1,0xcb,0x62,0xe0,0x0d,0x2e,0xdc,0x2e,0x36,0x28,0x8e,0xd3,0xa9,0xe0,0x38,0xd4,0xc5,0x2b,0xee,0xaf,0xa4,0x08,0x7d +.byte 0xed,0x2c,0x8a,0xf5,0x86,0x5e,0xed,0x2a,0x0d,0xbf,0xe6,0xfb,0x6f,0xc4,0x02,0x75,0x36,0xe5,0x7b,0xe9,0x4a,0xb3,0xf1,0xf4,0x86,0x6c,0x9a,0x6e,0xaa,0x7a,0xbe,0x4b,0xd6,0xf2,0x6b,0xcb,0x78,0x6f,0xf9,0x42,0x1a,0x19,0x7b,0x7e,0xba,0x59,0x02,0x8b,0xe3,0x5c,0x44,0xa4,0x84,0xa8,0x4a,0x67,0x93,0xee,0xc4,0x17,0x07,0x26,0xfe,0x86 +.byte 0xf1,0xc6,0xba,0xbf,0xc4,0x3d,0x33,0x41,0x4d,0xc4,0xf0,0xa8,0x6d,0xe1,0x06,0x16,0x2d,0xc9,0x5d,0x2a,0xf5,0x4a,0xc6,0xd2,0x8c,0x98,0x55,0xe8,0x8d,0xd0,0x31,0x5f,0xc7,0x05,0xd1,0xca,0xd2,0x72,0xe6,0xd0,0xcb,0x62,0x79,0xac,0x60,0x59,0x94,0x59,0x48,0x9e,0x91,0x17,0xa7,0xa0,0xac,0x4a,0xe5,0x08,0xe5,0x52,0xa4,0xd4,0x83,0x8c +.byte 0x83,0x57,0xe7,0xe5,0xfc,0x9b,0x43,0x78,0xc8,0x7e,0x94,0xc4,0x35,0x3e,0xac,0x4a,0x8d,0x60,0x80,0xdc,0x72,0xe3,0x15,0x09,0x2a,0xbd,0xcc,0x9a,0xe4,0x1a,0x18,0xa8,0xf1,0x29,0x9b,0xca,0x58,0x0b,0x6d,0x7b,0x33,0x91,0x05,0x27,0x6a,0x48,0xbe,0xac,0x08,0xa5,0x2a,0x64,0xf5,0xae,0x2a,0x90,0xf1,0x2d,0x3f,0xa8,0xff,0x17,0x92,0xc4 +.byte 0xec,0x3a,0x09,0xbf,0xae,0xd3,0xe2,0x1c,0x3c,0xc8,0x6f,0x91,0x72,0x99,0xe3,0x82,0x30,0x4f,0x40,0x5c,0x0c,0x8d,0xfd,0xbe,0x10,0xbc,0xce,0x1e,0x0a,0x09,0xbf,0xde,0xdc,0x72,0x7e,0x4c,0xbc,0xec,0x34,0xe2,0x96,0x8a,0xc6,0xee,0x19,0x6c,0xa8,0xf1,0xa5,0xb2,0x71,0x88,0x13,0xe8,0x11,0xda,0x3b,0x77,0x10,0x9c,0x9f,0x74,0x49,0x21 +.byte 0x16,0xcf,0x6f,0x05,0xc5,0xc1,0x4d,0xfe,0xe7,0x4d,0x67,0xe8,0x12,0x14,0xf7,0xaf,0x66,0x8d,0x55,0x34,0x00,0x18,0x10,0x6e,0x6a,0xd2,0x4c,0xd9,0xd3,0x15,0x40,0xbf,0xce,0x7b,0x10,0x69,0xbd,0x15,0x0e,0x60,0x2b,0x76,0x50,0x80,0x92,0x02,0x3c,0x0f,0xea,0x47,0x03,0xd9,0xf6,0x2c,0x00,0xde,0x29,0xb9,0x2e,0xf6,0x80,0x10,0x81,0x28 +.byte 0x6f,0x41,0xfc,0x88,0x65,0xe9,0xb5,0xd4,0x78,0x53,0xff,0x04,0xc4,0xdd,0xd7,0x35,0x34,0x59,0x85,0x33,0x01,0x33,0x67,0xe1,0x4e,0xc2,0xac,0xe6,0x24,0x24,0xb6,0x83,0x48,0x08,0x0c,0x73,0xe5,0x9c,0x98,0xe4,0x4c,0x3c,0x1f,0x6e,0x77,0xea,0x8c,0x76,0x23,0xbb,0x41,0x5e,0xc1,0x8a,0xba,0x3e,0xe5,0x3e,0x86,0x89,0xab,0x32,0x65,0x1b +.byte 0x00,0x92,0x56,0xe0,0x62,0xc1,0x8f,0xeb,0x15,0x7f,0x86,0xdf,0xa2,0xc2,0x8d,0xf5,0xb5,0x88,0x72,0x8c,0xba,0x92,0x30,0x53,0x58,0x3e,0x0b,0xe6,0x4f,0xd4,0xef,0x34,0xab,0xbb,0x61,0xe0,0x31,0x3c,0xe7,0xb2,0x5f,0x64,0xcb,0x52,0xc7,0x1d,0x95,0x96,0xd2,0x8c,0x87,0x34,0x92,0xf2,0xad,0xd9,0x78,0x1d,0xa1,0x67,0x58,0xfa,0xfb,0x06 +.byte 0xc8,0x7f,0x9e,0xf7,0x02,0x12,0xd9,0x8c,0x68,0xbc,0x2b,0xd3,0xe1,0x0e,0x1e,0xbd,0x33,0x7a,0xfd,0x03,0x41,0xb9,0x72,0x2e,0x63,0xfe,0xb1,0x39,0xc3,0x0f,0xa0,0xa9,0x76,0x4f,0x7b,0xab,0xae,0xda,0x22,0xec,0x83,0x32,0xb0,0xec,0xd1,0xfd,0xc2,0x28,0x1e,0x42,0x29,0x31,0xd5,0xb3,0x33,0xcd,0x13,0x1d,0x9f,0xac,0x73,0x27,0xf7,0xea +.byte 0xc6,0x66,0xd2,0x32,0x91,0x60,0x35,0xf4,0x28,0x34,0x43,0x6a,0x74,0x8c,0x05,0x2a,0x84,0x34,0xfd,0x84,0xa5,0xcb,0x1d,0x2b,0x41,0x28,0xa6,0x19,0xed,0xcd,0xad,0xea,0x6e,0xf7,0x14,0x18,0xac,0x56,0x9a,0xf5,0xaa,0x7d,0x4e,0x8a,0x99,0xd1,0xda,0x41,0xaf,0xe8,0xfc,0xef,0x66,0x88,0xd0,0xed,0xfd,0xae,0x2a,0x85,0xc0,0x60,0xa2,0x30 +.byte 0x5d,0x1b,0x48,0xf6,0x3e,0xcf,0x56,0xdf,0x53,0xdc,0x2d,0xf5,0xfd,0x7f,0x2a,0x2a,0x4d,0x4f,0x11,0xcc,0xea,0x72,0xdb,0xb9,0xeb,0x92,0x0e,0x9f,0xc1,0x26,0xe9,0xbf,0x25,0x6a,0x27,0xe1,0x63,0x9b,0xdd,0x62,0x38,0xad,0xd3,0xb2,0x75,0x62,0x45,0xbf,0xbf,0xf4,0xe2,0xd6,0x97,0xe9,0xeb,0xeb,0x98,0xab,0x73,0xdc,0x8a,0xde,0xaa,0x3b +.byte 0x69,0xfd,0x61,0x6f,0xbb,0xfc,0x28,0xc0,0xff,0x37,0x2e,0xeb,0x31,0x59,0x57,0xfb,0xd3,0x0e,0xed,0x01,0x66,0x50,0x63,0x53,0xa2,0xd1,0x24,0x8c,0xc8,0x8d,0x80,0x03,0x2a,0x1e,0x11,0x3a,0xb9,0x6c,0xf4,0x5f,0x58,0xa2,0xd6,0x58,0x6b,0x85,0x61,0xd1,0xe7,0xdc,0x90,0x07,0x34,0x6e,0xb9,0x0b,0x0d,0xcb,0xd5,0xe3,0xc6,0x9d,0xb8,0x51 +.byte 0x37,0x61,0xd0,0x6c,0x2e,0xed,0xe0,0xbc,0x55,0x74,0x63,0x1b,0x42,0x17,0x6a,0x9c,0x91,0x1b,0x96,0x76,0xc8,0xe4,0x2b,0x2e,0x90,0xd9,0xe5,0x3f,0x56,0x1b,0x2f,0x93,0x81,0x86,0x2a,0xb4,0xdf,0x93,0xcb,0xfa,0x01,0x85,0xd9,0x26,0x46,0x46,0x97,0x2a,0x2e,0xb3,0x91,0xe4,0xcf,0xd9,0x01,0x5a,0x37,0xa6,0xca,0x5e,0xed,0xa9,0x94,0x35 +.byte 0x2c,0x69,0x5b,0x1e,0xf8,0x38,0x61,0x41,0x10,0xf6,0xe9,0x6e,0x96,0xee,0xe6,0x5f,0x78,0x14,0x93,0x12,0xd2,0x57,0xe5,0xf4,0x58,0x46,0xca,0xc8,0x75,0x59,0xbd,0xd0,0xe4,0x70,0x35,0xa5,0x4a,0xfd,0x54,0xe2,0x91,0x76,0x0e,0xe6,0xe3,0xbb,0x31,0x65,0x4b,0x18,0xa8,0xb4,0xfa,0xa6,0x7d,0x7a,0xa9,0x47,0x3d,0x2b,0x2e,0x66,0xac,0x5b +.byte 0x3e,0x5e,0x8c,0x27,0x0c,0x33,0x04,0x03,0x4e,0x5f,0xcd,0x6b,0x9c,0xaa,0x13,0x83,0x38,0xe9,0x38,0xcf,0x03,0x70,0x5a,0x0f,0x18,0xf5,0xec,0x64,0xf3,0x0c,0xe8,0xb1,0xa9,0x07,0x70,0xf7,0xde,0x0c,0x35,0xf5,0xe2,0xcd,0xed,0xe6,0x4d,0xac,0x5c,0x4d,0x3e,0x03,0x96,0x90,0x7b,0x4c,0x3e,0x18,0x42,0xc0,0xa7,0x23,0x12,0x8e,0x54,0xc1 +.byte 0xa1,0x2f,0x82,0x13,0xe6,0x1f,0x74,0xae,0x7b,0x4a,0xa4,0xbb,0xdc,0xc0,0x68,0x0f,0x83,0xbc,0xda,0xce,0xa2,0xe7,0xbe,0x18,0xcd,0x8b,0x35,0x05,0xa3,0x4b,0x6f,0xf0,0x53,0x12,0x42,0x2f,0x3c,0x09,0x87,0xb7,0xe3,0x36,0x29,0xe1,0xa2,0xb6,0x60,0x05,0xb9,0x66,0x80,0xe9,0xec,0x40,0x2a,0x55,0x78,0x5f,0x1c,0x5f,0xc3,0xc7,0x49,0x69 +.byte 0x87,0x97,0x5f,0xa5,0x31,0xa8,0x83,0x66,0x5a,0xd7,0xaf,0xf0,0x15,0xf3,0x01,0x62,0x9a,0x88,0x76,0x0f,0xb3,0xdf,0xf1,0xc6,0x34,0xc3,0xac,0x68,0x60,0x9a,0x91,0x03,0x13,0xea,0x0e,0x36,0x9c,0xf5,0x51,0xb7,0x0c,0xa4,0xeb,0xf0,0x41,0x85,0x54,0x05,0xed,0x7a,0xc2,0xba,0x3b,0xb8,0x1c,0x41,0x0d,0xbb,0xad,0x16,0x7e,0x64,0x4f,0x88 +.byte 0x7a,0x17,0xae,0x76,0x55,0x78,0x93,0xe8,0x99,0xa1,0x70,0x1f,0xf6,0x8a,0xb9,0xeb,0x41,0xb9,0x08,0xb8,0x9d,0x78,0x57,0xa1,0xe1,0x23,0xa0,0x03,0xd3,0x16,0xbc,0x16,0x24,0xed,0xc5,0x12,0x16,0x0a,0x8a,0x23,0x11,0x22,0xc2,0xfe,0x49,0x9d,0x3d,0x10,0x3d,0x4b,0xeb,0xab,0xcb,0x21,0x9d,0x9d,0xb1,0x64,0x87,0xe5,0x4d,0xb9,0xe7,0x10 +.byte 0x05,0xa0,0x55,0x2f,0xdf,0x53,0x5e,0x03,0xec,0x7e,0xe4,0x1f,0x9b,0x16,0x0c,0xfc,0xd9,0xf9,0x66,0x39,0x93,0x9e,0x49,0x34,0x97,0xd6,0xa5,0x56,0x00,0xf1,0xaf,0x08,0xeb,0x58,0xcf,0x87,0x02,0xc4,0xf1,0x24,0xe8,0x29,0x83,0xc9,0x5d,0x56,0x68,0xa2,0xaa,0xba,0xb3,0x86,0x23,0x59,0x8d,0x32,0x96,0x4a,0xbb,0xe9,0xf2,0x53,0xb2,0x87 +.byte 0x4a,0xf5,0xdc,0x23,0xd4,0x2f,0x36,0x70,0xb5,0x1d,0xee,0x47,0x51,0x6c,0x35,0x2a,0xad,0x35,0x74,0x1b,0x98,0xb5,0x33,0x2c,0x6d,0x4c,0xf8,0x39,0x07,0x92,0x6c,0xc7,0x65,0x10,0x64,0xcd,0x53,0xa3,0xcb,0xcc,0xe4,0xb2,0x46,0xb3,0xb7,0x44,0x01,0x92,0x44,0x12,0x23,0x25,0x3e,0x00,0xe3,0xeb,0x5f,0xe5,0x76,0x48,0x4e,0x4a,0x7f,0x36 +.byte 0xf0,0x0b,0x5e,0xc0,0x97,0x0d,0xc8,0xcf,0xd5,0xb8,0xc0,0x11,0x8d,0xb9,0x1e,0x31,0x0f,0x84,0x36,0x2e,0xe0,0x42,0xe6,0x02,0x9d,0xa4,0xdb,0xa2,0x76,0xfd,0xa1,0x95,0xe0,0x49,0xe6,0xf1,0xd2,0xae,0x27,0x6b,0x11,0x05,0x47,0xb0,0xaa,0x61,0x01,0xd4,0xe6,0xcd,0x9d,0x7e,0x33,0x5d,0xec,0x22,0x96,0x59,0xb7,0xc5,0x50,0x83,0xa4,0x66 +.byte 0x56,0xc7,0x43,0xa6,0xf7,0x5d,0xb2,0x45,0xc0,0x96,0xa0,0x5b,0xb8,0xed,0xae,0x29,0xb3,0x7d,0xbd,0x01,0xde,0xc0,0xe7,0xcc,0xe9,0x55,0x32,0x32,0xbf,0xdd,0x03,0x1b,0xb0,0x4e,0xff,0x53,0x1f,0x4b,0xc6,0xec,0x16,0x9d,0x5b,0x78,0x74,0xc4,0x75,0x51,0x8a,0x1c,0xae,0x6b,0xcd,0x9c,0x77,0x47,0xbf,0xd1,0x38,0x3e,0x9e,0xc0,0xad,0x16 +.byte 0xb7,0x15,0x6b,0xdc,0xad,0xe9,0x13,0xbc,0x48,0xc1,0xaf,0x69,0xce,0xc4,0xcc,0x9b,0x73,0xf9,0xd5,0x7c,0xab,0xf0,0xf1,0x9b,0xea,0xc6,0x0b,0x19,0x47,0x42,0xc1,0xa0,0x02,0x64,0x17,0xce,0x88,0x4f,0x16,0xa6,0xed,0xdb,0xfe,0x61,0xd3,0xd6,0xc0,0x11,0x30,0x16,0xd2,0x45,0xb3,0x7e,0x52,0xd0,0x94,0x77,0xf0,0x0e,0xbf,0x16,0xc0,0x4a +.byte 0x2a,0x5c,0xac,0x55,0x57,0xb1,0x41,0xb6,0xa3,0x68,0x8c,0x0a,0x66,0x15,0xb4,0xf5,0xd9,0x9a,0xa9,0x68,0xf2,0xbc,0x06,0xc5,0x7c,0xd1,0x18,0x55,0x9a,0x2d,0x94,0x2e,0x04,0x4b,0x7d,0x3c,0xb1,0xe3,0x03,0x7a,0xa7,0xe3,0xe5,0x63,0x49,0x7c,0x3f,0x0a,0xc5,0xbd,0xd3,0x0f,0x04,0xfd,0x99,0xf7,0xe6,0x05,0x35,0x66,0x17,0x05,0x85,0x3b +.byte 0x98,0x92,0x11,0x26,0xe2,0x21,0x52,0x1b,0x54,0x08,0xc8,0xf0,0x4e,0x75,0x22,0x3f,0xe8,0xb6,0x35,0xa4,0x02,0x52,0x70,0xc2,0xce,0x5a,0x00,0xe2,0xe2,0x92,0x8c,0x97,0xa7,0x1d,0x42,0x52,0x8b,0xf1,0x81,0xa7,0xce,0x60,0x46,0xbe,0xf0,0x1d,0x34,0xdf,0x73,0x2a,0xd6,0x9a,0x2d,0xf9,0xe3,0x91,0x05,0xe4,0x1f,0x31,0x11,0x30,0xb0,0xff +.byte 0x8f,0x61,0x74,0xf4,0xef,0xcd,0xf6,0xa4,0x9a,0xd2,0x5e,0xba,0x27,0xe8,0x78,0x38,0xfc,0x75,0xff,0x3b,0x6c,0xde,0x4a,0x46,0x47,0x8e,0x97,0x28,0xe4,0x23,0xe0,0x10,0x07,0xca,0xcb,0x6d,0xed,0x29,0xc0,0xee,0x98,0x96,0x7c,0x90,0x1f,0x89,0x12,0x0f,0xd5,0x28,0xcf,0x6e,0x4b,0x9b,0x2d,0xb3,0xcd,0x97,0xb8,0xeb,0x58,0x23,0x26,0xb1 +.byte 0xb4,0x95,0x11,0x1e,0xee,0x00,0xde,0x24,0x28,0xa6,0x3f,0x15,0xa2,0x9a,0xcb,0x9d,0xe3,0x04,0x5d,0xc3,0x60,0x97,0x14,0x2c,0x84,0x2b,0x69,0x9c,0x2a,0xbf,0x08,0xba,0xc4,0x38,0x36,0xaa,0x89,0x11,0x32,0x63,0x01,0xa2,0x44,0x5f,0x50,0xf0,0x5b,0x11,0x15,0xc8,0x80,0xc9,0xa6,0xe7,0x5d,0x70,0xa8,0x34,0x42,0x97,0x2a,0x60,0x99,0x20 +.byte 0xa6,0x60,0xc0,0x70,0x8d,0x2f,0x3f,0x8a,0x14,0x80,0x8a,0xbe,0x05,0xb3,0x50,0x16,0xaf,0x32,0xb4,0x35,0x3e,0x1d,0x31,0x42,0xdd,0x50,0xeb,0x04,0x82,0x4c,0x83,0x3d,0x8f,0xb6,0x1e,0xc2,0xa9,0xd2,0x30,0xba,0x33,0xdb,0x97,0x6d,0x2d,0x97,0x59,0x33,0xc0,0xf8,0xa5,0x59,0xc5,0x44,0x9c,0xf1,0x06,0xc4,0xf2,0x31,0x3e,0xff,0xb8,0x12 +.byte 0x00,0x4d,0x6c,0x2d,0xa1,0xc7,0x83,0xea,0x55,0x93,0x0e,0x89,0x76,0xbf,0x56,0x2a,0x99,0x62,0x54,0xad,0x2c,0xe8,0xf0,0xf9,0x70,0x18,0xa5,0x2b,0x24,0xac,0x59,0xc9,0x84,0xe3,0x1a,0x9d,0xa0,0xdb,0x1b,0x7f,0xd5,0x7e,0xb5,0xe0,0x86,0x36,0xc5,0x71,0x6a,0xab,0xdb,0xa5,0x84,0xf1,0x9e,0x9e,0xf6,0x1b,0xab,0x47,0x94,0x38,0x8e,0x5d +.byte 0x55,0xb4,0xf5,0xc3,0x59,0xc2,0x2c,0x6d,0x9d,0x28,0x7d,0x33,0xcd,0xc7,0xd6,0xdf,0x10,0xda,0x7c,0xd0,0x6c,0x91,0x88,0xd6,0x6b,0xe7,0x72,0x75,0x18,0xb1,0x87,0xe4,0xbb,0x10,0xe0,0xa3,0x0f,0xea,0x65,0x0a,0x70,0xc8,0xee,0x52,0x05,0x0a,0x27,0x39,0x66,0xda,0xd6,0xa6,0xfe,0x97,0x24,0x09,0x9d,0x20,0x76,0x4e,0x97,0x9d,0xa9,0x9f +.byte 0x76,0x20,0x27,0x57,0x5b,0xf4,0x76,0x1a,0x4b,0xcf,0x13,0x6c,0x9e,0x63,0x53,0x97,0xca,0x10,0xd6,0x90,0x7d,0xfc,0xe3,0x03,0x2c,0x6c,0x79,0x93,0x1a,0xae,0x0f,0x43,0xdb,0x75,0xde,0x56,0xa6,0x69,0x93,0xce,0x2d,0x94,0x56,0x77,0x90,0x19,0x71,0x7f,0x7a,0x99,0xbd,0x9c,0x79,0x62,0x00,0x49,0x3a,0x62,0x49,0x4b,0x92,0x65,0x8b,0xe2 +.byte 0xa8,0x3d,0xa5,0x89,0x23,0xac,0xea,0xf1,0xbf,0x38,0x84,0xd7,0xe2,0x65,0xb6,0xc7,0xbc,0x02,0x11,0xfd,0xe3,0x4c,0x57,0x38,0xd4,0x36,0x54,0xe8,0xbb,0x63,0x17,0xe9,0xda,0x82,0x50,0xf1,0x8c,0x34,0x4d,0x75,0x2a,0x64,0x49,0xaf,0x98,0xc3,0x1d,0xad,0x31,0xf3,0x90,0x23,0x39,0xf5,0xb5,0xf4,0x37,0x88,0x67,0x12,0x5d,0xfc,0xee,0xe5 +.byte 0x44,0x52,0x2c,0x78,0xb1,0x90,0xc1,0xc2,0x77,0x6e,0x31,0x3e,0xa0,0x36,0x87,0xb0,0xc6,0x6c,0x94,0xc2,0x43,0x4a,0x7b,0xa2,0x73,0xe7,0xa0,0xc3,0x4c,0xaf,0x4f,0xa6,0x92,0x1c,0x9a,0x6d,0xee,0xe8,0x4d,0xe1,0xe0,0xc7,0x67,0xcf,0xcf,0x7d,0x7f,0x0f,0x07,0x0d,0x6c,0x06,0x06,0xc2,0xc9,0x28,0xfc,0x8d,0xcd,0x23,0x01,0x97,0x5b,0x4d +.byte 0x1c,0xdb,0x34,0x51,0x6e,0xe2,0x56,0x24,0xd7,0xbd,0x12,0xc4,0x2f,0xb4,0x3b,0x02,0xaa,0x47,0xda,0x61,0xf6,0xca,0x44,0xa8,0x02,0xbf,0xbc,0x58,0xfb,0xa2,0xff,0xf3,0x54,0x59,0x5f,0xd7,0xa0,0x7c,0x83,0xa6,0xef,0xeb,0x71,0x51,0x74,0xa1,0x27,0x10,0x97,0x13,0x1f,0x42,0x91,0xdd,0xa8,0xf8,0xc7,0x60,0x90,0xca,0x2e,0xc8,0xaf,0x9f +.byte 0x65,0x1f,0x24,0x0a,0x30,0x5f,0xb9,0x4c,0xfb,0xcb,0xa3,0x96,0x5e,0xad,0xab,0xac,0x09,0x91,0xf5,0x96,0x1f,0xe0,0x96,0x14,0xc5,0xa0,0x26,0xa1,0xf1,0x91,0x80,0x38,0x7f,0x38,0xdc,0x98,0x96,0x20,0x46,0x50,0x20,0xd2,0x20,0xce,0x79,0xd5,0x81,0x60,0x97,0xb2,0xb0,0xeb,0x58,0x75,0x3c,0x99,0xf0,0xe0,0xfd,0xfc,0x90,0xc5,0xd1,0x3d +.byte 0x68,0x07,0xfd,0xa1,0x3f,0xeb,0x47,0xd0,0x58,0xe3,0xfa,0xbe,0xbf,0x20,0xdf,0x66,0x08,0x91,0xa4,0x5c,0x52,0x3e,0xdf,0x5c,0xb8,0xee,0xca,0xa6,0x89,0x06,0x97,0xb4,0x8d,0x60,0x35,0xb1,0xff,0x1e,0x39,0xf2,0x67,0xbc,0x71,0xee,0xeb,0x48,0x94,0x19,0x1a,0xee,0xc5,0xe2,0x7e,0x0d,0xf1,0xca,0xe8,0x2c,0xb0,0xaa,0x02,0x58,0x23,0x23 +.byte 0xce,0x37,0x5e,0xcb,0x58,0x40,0x2e,0x1a,0xa6,0x09,0x11,0x95,0xc4,0x6f,0x10,0xb0,0x15,0x22,0x48,0x67,0x74,0x6c,0x2f,0x4f,0x4a,0xb4,0x01,0xe5,0xa3,0x77,0xab,0xad,0xa4,0x04,0x22,0x71,0x58,0x4a,0x71,0xb1,0xe8,0xdf,0x43,0x18,0x0e,0x95,0x7c,0x8c,0x23,0x3a,0xf3,0x9c,0x20,0x60,0x20,0x69,0x51,0x28,0x7e,0x13,0x67,0x5c,0x7d,0x35 +.byte 0xfa,0x1b,0x04,0x8b,0xcf,0x42,0x6e,0x15,0x55,0xcd,0x04,0xdb,0x73,0xdb,0x47,0x5f,0x83,0x6e,0xd1,0x5a,0x15,0xa2,0xbb,0xf7,0xbb,0x84,0x58,0xce,0x75,0xe8,0xd2,0x92,0xd5,0xb7,0x76,0xf2,0x94,0x67,0x27,0x5f,0x32,0x91,0x3a,0xaf,0xd4,0x31,0xf8,0x92,0xce,0x63,0xb7,0x45,0x27,0xb4,0xb8,0x7a,0x1e,0x4e,0xde,0xcb,0xc8,0x5e,0xd3,0xbb +.byte 0x52,0x91,0xd5,0x72,0xad,0x98,0xec,0x07,0xa1,0x56,0xb4,0x8e,0x04,0xfa,0x48,0x3f,0x17,0x07,0xf7,0xef,0x92,0x61,0x69,0xaf,0xdd,0xfc,0x76,0x03,0xe2,0xe9,0xe2,0xbe,0x5c,0xf2,0x8a,0xc5,0x99,0x51,0x7f,0xa4,0xf1,0xac,0x16,0xec,0x16,0xf5,0xb8,0x95,0x88,0x87,0xdb,0x27,0x2e,0x63,0x12,0x31,0x7d,0x6b,0x2b,0xa0,0x9b,0xb5,0xf9,0x82 +.byte 0x42,0x04,0x94,0xee,0x60,0x6e,0x4e,0x54,0x9b,0xfd,0xeb,0x01,0x3a,0xad,0x42,0xeb,0x08,0x3c,0x6a,0xa3,0xf2,0x46,0xfb,0x18,0x59,0x2c,0xa3,0x0b,0x22,0x1d,0x5d,0x47,0xa6,0x8c,0x06,0x9c,0xa1,0xcc,0x20,0x67,0xbd,0xf0,0x5b,0x94,0x9f,0xc6,0x10,0x8c,0xc8,0x15,0x52,0xe3,0x19,0xa1,0x89,0xfd,0x99,0xad,0x4f,0x10,0x51,0x0a,0xe4,0x4b +.byte 0x02,0x7b,0x0d,0x73,0x2d,0xae,0xa4,0x68,0x1d,0xb6,0xcf,0x58,0x67,0xc0,0xd0,0xca,0x11,0x34,0x31,0x9e,0xa3,0xbc,0x12,0x28,0x1e,0x8e,0x5a,0x63,0xf5,0xda,0xf2,0x36,0x94,0x63,0x2c,0x39,0x3d,0xf9,0x80,0x9f,0xbf,0x8d,0xef,0x1f,0x15,0xc8,0xdb,0x62,0x58,0x7d,0xdc,0x0a,0x7f,0x87,0xaf,0x6d,0x2e,0xac,0x92,0x4f,0x51,0xdf,0x5e,0x75 +.byte 0x5e,0x0f,0x7c,0x51,0x49,0x88,0x0f,0x7b,0x49,0xa5,0x7c,0x41,0x4e,0x2a,0x0f,0xd0,0x0f,0x78,0xeb,0x42,0xfc,0x07,0x8a,0x8b,0x4e,0x3e,0xf2,0x42,0xc5,0x21,0x01,0x66,0xe2,0x50,0xf6,0x3d,0x28,0x1e,0xbf,0xdc,0x71,0x7f,0xc5,0x6e,0xc1,0xab,0x1a,0x33,0x49,0xdd,0xa2,0xb9,0x52,0xbe,0x93,0x97,0x97,0x7a,0xf0,0x22,0xa8,0xc5,0x01,0xc6 +.byte 0x76,0x6f,0xb6,0x2c,0x09,0x80,0x62,0x5b,0x84,0x05,0x7f,0x79,0x28,0x04,0x67,0xa2,0x0f,0xfc,0xbb,0x17,0xe2,0x85,0xe3,0xa0,0xf3,0x44,0x47,0x96,0x68,0x80,0xb2,0xbf,0xba,0x63,0x53,0x38,0x6c,0x3b,0xcd,0x3c,0xa4,0x10,0x48,0x80,0xd8,0x49,0x5a,0xf0,0x5c,0x38,0x02,0x02,0x5b,0xf2,0x77,0xa4,0xfd,0x16,0xfd,0x13,0xc8,0x8b,0x9b,0xcd +.byte 0xe1,0x8d,0x70,0xb6,0x3d,0x24,0x65,0xda,0x1a,0x42,0x6f,0x90,0x64,0x9a,0x9b,0xda,0x54,0x44,0xc0,0xe0,0xd7,0xfb,0x73,0x10,0x3c,0xcf,0xa6,0x04,0x99,0xd9,0x45,0xe5,0x74,0xfe,0xdf,0x81,0xac,0xc8,0x30,0xe5,0x66,0x45,0x02,0xca,0xcd,0xd7,0xe6,0x7b,0x0d,0xda,0xe1,0xa0,0xa1,0xa1,0x87,0x34,0x63,0x0b,0xa7,0x82,0x39,0x83,0xba,0x18 +.byte 0x0b,0x16,0x35,0x11,0x53,0x8d,0xbe,0x7d,0xa8,0x7e,0x3f,0xf4,0x71,0xc9,0x37,0x6f,0x1a,0xd9,0x3f,0x8e,0xc4,0xc1,0xd3,0x80,0xdf,0xee,0x0e,0x6b,0x23,0xf7,0xbc,0x42,0x93,0x7a,0x36,0x6f,0x03,0x24,0xb4,0x9c,0x62,0xa0,0xed,0xed,0x0b,0x66,0xa8,0x25,0xe6,0x1a,0xd4,0x13,0xd1,0x16,0x14,0x2b,0x90,0x7d,0x2e,0xa4,0xda,0xb2,0xf9,0x33 +.byte 0x54,0xf9,0x0a,0x04,0x27,0x03,0x14,0xd2,0xd7,0xe2,0xc1,0xaa,0xb6,0xe8,0xe5,0x4c,0xf2,0xdb,0x4c,0xc8,0xb3,0xa4,0xeb,0xbf,0x12,0x5c,0x9d,0x65,0xaa,0x9a,0x66,0x77,0x42,0xb4,0xd5,0x5b,0x1f,0x3b,0xd7,0x91,0x89,0x57,0x2f,0xd0,0x86,0x99,0xb2,0xc8,0xc1,0x31,0xde,0x33,0x43,0x36,0x81,0xdb,0x97,0x7b,0x17,0x3b,0xa5,0x99,0xdb,0x63 +.byte 0x2b,0x48,0x4c,0xa6,0x5c,0x6c,0xd8,0xc9,0x6e,0x72,0x39,0xbe,0x6e,0x55,0x7e,0x9d,0xb7,0x20,0x8d,0x8f,0x81,0x20,0x78,0xae,0xc6,0x1d,0xe0,0x2d,0xb1,0xe7,0x64,0xbb,0xd4,0xc8,0x08,0x61,0x14,0x29,0x08,0xbc,0x1a,0xeb,0xfa,0x64,0x33,0x91,0x7d,0x91,0x41,0x65,0x8e,0x4c,0x0c,0xb2,0x79,0xc3,0x01,0x68,0xfc,0xd6,0xbb,0x50,0xcc,0x07 +.byte 0xa5,0xf6,0x2c,0x5e,0x10,0xd6,0xa3,0x62,0x18,0xec,0xa2,0xf2,0x6b,0xad,0xcd,0x02,0x01,0x75,0xbb,0x36,0x27,0x56,0x0f,0x55,0x03,0xe0,0x57,0xe1,0x72,0xeb,0x66,0x00,0x21,0xff,0x9a,0xbc,0xc1,0x1e,0x2c,0x93,0xe6,0x4d,0x93,0x28,0x10,0x7d,0x67,0x6c,0xf1,0xa4,0xe6,0x3a,0xa6,0x30,0xc8,0x50,0x1d,0x8b,0x6e,0x7b,0x76,0x98,0x14,0x4e +.byte 0xed,0x84,0x67,0x2a,0x5f,0xac,0x0b,0x7b,0x47,0x40,0xb3,0x2d,0x7a,0xc1,0x23,0xdc,0x62,0xf8,0x8e,0x90,0x77,0xd4,0xf9,0x00,0x4b,0x67,0x04,0x72,0xf8,0xc9,0x2c,0x2d,0x0e,0x3c,0x3c,0xf3,0xfc,0xa8,0xe2,0x49,0xa4,0x00,0x82,0x98,0x72,0xa9,0xec,0xea,0xbd,0x3a,0x4e,0xd7,0x32,0xf1,0x11,0xf0,0x0d,0x9e,0xa2,0xe8,0xfe,0xcc,0x67,0xec +.byte 0xfc,0xd6,0xfe,0x83,0x5e,0x7c,0x2b,0xb3,0x42,0xf4,0x2d,0x9a,0xbe,0x20,0xd1,0x81,0x62,0xe9,0x59,0x19,0x28,0xdf,0x97,0x10,0x54,0xf7,0xde,0x60,0x51,0x6a,0xce,0x32,0x03,0x75,0x5c,0x25,0x25,0x82,0x9c,0x07,0xf7,0x2d,0xa8,0x1b,0x9f,0xd3,0x32,0x46,0x25,0x1f,0xb1,0xc5,0xbb,0x28,0x14,0x3e,0xed,0xa8,0x83,0x20,0xf4,0x9c,0x75,0xf4 +.byte 0xe6,0xc4,0x2d,0x05,0x88,0x31,0xfd,0x48,0xca,0x6c,0x7f,0xab,0xb4,0x77,0x93,0x1d,0x87,0xc3,0x4e,0xb8,0xad,0xb4,0x3d,0x37,0x7a,0xd2,0x77,0xff,0xc2,0xcb,0x9c,0xc7,0xbf,0x02,0x02,0x70,0xc9,0x9f,0x77,0x8a,0x7d,0xa7,0x9a,0x10,0xd1,0x0e,0xb7,0xec,0x61,0xee,0x77,0x24,0xe9,0x3d,0xcd,0x12,0xca,0xee,0x50,0xb0,0x27,0x5d,0xe5,0xac +.byte 0xa3,0x92,0xc7,0xd0,0x23,0x54,0xb1,0xe5,0x50,0xc3,0x15,0xd7,0x66,0x32,0x38,0x34,0xb1,0x59,0x1b,0xc3,0x59,0xe8,0xad,0x59,0x90,0x58,0x6e,0x02,0x40,0xb1,0x51,0x65,0x78,0x25,0x26,0x01,0xdd,0xcf,0x04,0xa2,0xfe,0xc3,0xbb,0x80,0x1c,0xb0,0x4e,0x9c,0x49,0x48,0xa3,0xe2,0xcc,0x81,0xc5,0xa8,0xd4,0xd5,0xe4,0xab,0x39,0xe7,0xe8,0x97 +.byte 0xc7,0x51,0xb4,0x5e,0x3f,0xe6,0xa7,0xcc,0x45,0x18,0xa2,0x6a,0xb3,0xa8,0x0b,0x7d,0xce,0x1a,0x97,0x4a,0x67,0xe1,0x3c,0x7c,0x4e,0xad,0x90,0xcf,0x2a,0x8f,0xb8,0xb6,0x96,0xaa,0x9a,0xc3,0x73,0xe6,0x71,0xdb,0x11,0x9b,0xd9,0xd9,0xfe,0xba,0x4a,0xf0,0x77,0xa4,0x15,0xb5,0xca,0xe1,0xb4,0x16,0x06,0x46,0xdf,0xc5,0x49,0x07,0x66,0xb3 +.byte 0xf5,0x30,0xe3,0xfb,0x44,0xac,0x80,0x3a,0x21,0xd9,0x5b,0x22,0x54,0x3a,0xae,0xbe,0xbd,0xf0,0x99,0x8d,0xb5,0x2a,0xf7,0xc9,0xf2,0xd3,0xfb,0x07,0x7c,0xd7,0x75,0x30,0x2a,0xcd,0x80,0xa8,0x2a,0x6a,0xb9,0x47,0xe2,0xa1,0xb0,0x76,0x6a,0x0f,0x9f,0x4a,0x56,0x3e,0xde,0xb3,0x89,0x12,0x25,0x63,0x1a,0x9d,0xea,0x64,0x08,0xc5,0x78,0xa7 +.byte 0x53,0xce,0xf8,0xb2,0xe5,0x97,0x3a,0xeb,0xd1,0x92,0xe1,0x4d,0xe0,0xf5,0x93,0x39,0x73,0xad,0x67,0xc9,0x0e,0x6b,0x16,0x4a,0x00,0xaa,0xb4,0xe6,0xa6,0xa5,0x67,0x95,0x90,0x04,0x5e,0x4d,0xc3,0x7f,0x6b,0xa1,0x50,0xb0,0x3b,0x72,0x0d,0xb3,0xec,0x9a,0x18,0x92,0x65,0x0c,0x2d,0x0f,0x94,0xd6,0x0f,0x95,0xba,0x4b,0xe6,0xc3,0x07,0x22 +.byte 0x0d,0x40,0xd4,0x0d,0x97,0x44,0xba,0x54,0x8c,0xf8,0x97,0x52,0x1f,0xa7,0xb2,0xe8,0x1b,0x0a,0xd5,0xde,0xff,0x1b,0x33,0x60,0x6a,0x28,0x68,0x36,0xb9,0x5a,0x3e,0x43,0x84,0x9a,0xb1,0x3d,0x3d,0xdb,0x1b,0xa2,0xc5,0x0e,0x2d,0xb5,0x5a,0xa5,0x36,0xe7,0xbf,0x7e,0xc3,0x76,0xad,0x1e,0xb5,0x49,0xc2,0xd5,0xa2,0x69,0x97,0x45,0x43,0x3e +.byte 0xeb,0xcd,0xdf,0x4f,0xab,0xb3,0xe8,0x49,0xaa,0x9c,0x9c,0x58,0x1e,0xc8,0x1c,0x79,0xe9,0x16,0x1d,0xfe,0x54,0xac,0x55,0x18,0x10,0x73,0x97,0xdc,0xbe,0x45,0x63,0xfb,0x48,0x41,0x88,0xb4,0x0b,0x3a,0x1d,0x65,0x40,0x1b,0x10,0x66,0xeb,0xbe,0xed,0xc7,0x6c,0xd5,0x0c,0x19,0x85,0x23,0xb1,0x38,0xb3,0x4b,0xcd,0xc7,0xc5,0x06,0x18,0x40 +.byte 0xbd,0xef,0x9f,0x2e,0x3a,0x71,0x33,0x05,0x30,0x71,0xca,0xe9,0x7a,0x2c,0xe7,0x83,0x4e,0x3d,0x4b,0xc8,0xc7,0xcb,0x74,0x9c,0xa2,0xc7,0xbb,0x8c,0x44,0x0d,0xd8,0xb3,0x01,0x7c,0xdf,0x79,0xee,0x47,0xcb,0x91,0x6f,0xc3,0xfd,0x0f,0xfb,0xf8,0x6b,0x9b,0x00,0xaf,0xf6,0x69,0x82,0xa5,0x58,0x54,0x22,0x7f,0x4b,0xee,0xa7,0x03,0xdb,0xb6 +.byte 0x5f,0x12,0xe1,0x04,0x43,0x17,0xec,0xd4,0xdd,0x39,0x28,0xfa,0xa3,0x09,0x5e,0x14,0xaf,0x6b,0xfe,0x0c,0x65,0x01,0x13,0x75,0x3d,0xe7,0x6d,0xd9,0xda,0x1d,0x13,0xc1,0x56,0x40,0x50,0x95,0x65,0x8f,0xad,0x51,0x3f,0x13,0x05,0x2f,0x83,0xcd,0xca,0x8b,0x75,0xa2,0x39,0x61,0xde,0xd7,0x36,0xf9,0x1d,0x43,0x5b,0xc4,0x9a,0xc9,0xfc,0xa8 +.byte 0xf4,0x76,0x90,0x91,0xe8,0x52,0x5b,0x84,0xe7,0xc9,0x8e,0x7d,0x84,0xba,0xb1,0x32,0x12,0xce,0x06,0x9e,0x98,0x83,0x1f,0x7f,0x31,0xd7,0xf0,0x8a,0xa2,0xca,0xae,0xb3,0x50,0x51,0x93,0xfb,0x2f,0x43,0x0a,0xee,0x06,0x85,0xec,0xb8,0xf1,0x73,0xb1,0x65,0x37,0x05,0x8e,0x68,0xf7,0x7a,0xff,0xe7,0x17,0x08,0x5e,0x19,0x75,0x3d,0xf9,0x5e +.byte 0xd5,0x25,0xf6,0x3b,0x99,0xb9,0x96,0x42,0x7a,0x37,0x8f,0x0d,0xde,0x22,0x83,0x89,0xf0,0x77,0x1f,0x22,0x42,0xc7,0xb5,0x70,0xcb,0xfd,0xf0,0xa9,0x87,0x8e,0x1f,0x01,0x9a,0x26,0xa6,0x8c,0x41,0xb9,0x12,0xd6,0xf2,0x5b,0xe5,0xfd,0xdc,0x74,0xbd,0xa1,0xc8,0xf7,0x3b,0x8c,0xe1,0x1d,0x42,0xb4,0x07,0x24,0x18,0x84,0x94,0x8a,0xce,0x00 +.byte 0xbd,0xd7,0xb0,0xfd,0x8f,0x0a,0xd3,0x75,0xa4,0xe8,0xfc,0x09,0xa9,0xa3,0x57,0x68,0x79,0x0e,0xef,0x37,0x46,0xd5,0x3b,0x8c,0x0d,0x67,0xbc,0x2c,0x5d,0x3e,0xf7,0xcc,0x9c,0x9e,0x81,0x62,0xc8,0xec,0x38,0x20,0x07,0x66,0xe4,0x83,0x15,0x13,0x3b,0x47,0x23,0xd9,0x46,0xaf,0x65,0xe1,0x40,0x2d,0x14,0x84,0x72,0xc1,0xbf,0xbe,0x81,0xc4 +.byte 0xcb,0x04,0x16,0x5e,0x2f,0x60,0x3a,0x8e,0x1a,0xd3,0xa2,0x00,0x25,0x6c,0xb7,0xdb,0x0d,0x20,0x99,0xb8,0x45,0x54,0xbf,0xc4,0x52,0x52,0x92,0x7d,0xcd,0xa1,0x9a,0x12,0x5e,0x27,0xe9,0xcf,0x79,0x9d,0xa8,0x6c,0xcd,0x37,0x20,0x08,0x09,0xc6,0x94,0x53,0x00,0x04,0xf5,0x3b,0xea,0x00,0x1b,0xc3,0x02,0xff,0xbc,0x18,0x1f,0xb7,0xf7,0x26 +.byte 0xe8,0x8b,0xc4,0x5f,0xf7,0xbe,0x9b,0xb3,0xba,0xae,0xbd,0x9c,0x3f,0x95,0xf7,0xcd,0x2b,0x40,0xf4,0x1c,0x6f,0xd7,0x52,0xe1,0xa7,0xdc,0x79,0xa4,0x88,0xff,0xfc,0xcf,0xfb,0xbb,0xe6,0xef,0xb6,0x31,0xac,0x24,0xa7,0x40,0xea,0x76,0xa2,0x34,0x6c,0xb1,0xfb,0x96,0x6b,0xfa,0xdd,0x60,0x70,0x73,0xb8,0xfd,0x66,0x3d,0xf9,0x63,0xc9,0x04 +.byte 0x70,0x20,0x35,0xca,0x04,0xb8,0xb3,0x4f,0x24,0x64,0x54,0xc2,0xd9,0x4d,0x8b,0xad,0x07,0xad,0xc5,0xb9,0x84,0xac,0x7c,0x65,0x4b,0x98,0x1d,0x09,0x23,0x95,0x5c,0x85,0x26,0xe5,0x8e,0xec,0xeb,0xc3,0xd5,0x15,0x9c,0x37,0x4e,0xf3,0x3c,0x97,0x92,0x75,0x99,0x48,0x48,0x52,0x4b,0x7b,0x93,0x54,0xd7,0x4f,0x7f,0xe5,0x51,0xdc,0x74,0x85 +.byte 0x9a,0xae,0xbd,0xf8,0xe6,0xe8,0x3f,0x1b,0xee,0x8b,0xf4,0xd8,0x5c,0x6c,0x46,0x6e,0x1d,0xaf,0x67,0x27,0x9a,0x39,0x4e,0x6b,0x99,0xcc,0xc0,0x66,0x54,0xbf,0x60,0xf6,0x24,0x64,0xfd,0x16,0xbf,0x56,0xb2,0x07,0x87,0x46,0xa6,0xef,0x40,0x67,0x78,0x2f,0x78,0x49,0x81,0x25,0xbd,0xa1,0xcf,0x78,0x68,0x25,0x8e,0x93,0x0a,0x4b,0xe1,0x92 +.byte 0x33,0x9c,0x13,0x70,0xd4,0xdf,0x74,0x34,0x8f,0x21,0xb9,0x51,0xd7,0x74,0xa9,0x02,0x6e,0xdd,0xb2,0xb4,0x6e,0x2a,0x95,0xdb,0xe4,0xaf,0x17,0xf5,0x9b,0xa5,0xc1,0x72,0x36,0x35,0x02,0x37,0x1c,0x38,0xaa,0x81,0x76,0xc6,0x1c,0xc3,0x2c,0xc5,0x45,0xaf,0x03,0xea,0xe6,0x14,0x51,0x44,0x84,0x9e,0x32,0xfe,0x4b,0x47,0xe9,0xb4,0x12,0x96 +.byte 0x13,0x6f,0x4c,0xed,0xe4,0xb0,0x79,0x7b,0xe5,0xc0,0x37,0x87,0x78,0x28,0x42,0xf7,0xd4,0xde,0xfc,0xd2,0x23,0x11,0x09,0xa5,0x11,0xc3,0xc4,0xf5,0xe0,0x2b,0x47,0x01,0x63,0xf2,0x85,0x1f,0x45,0x28,0xae,0xd3,0x29,0x04,0x1a,0x4b,0x83,0xab,0xf2,0x35,0x3a,0x40,0x2c,0x8d,0xb3,0xc7,0x47,0x0d,0xd1,0x3c,0xd0,0x1c,0x6b,0x5d,0x9b,0x4e +.byte 0xdf,0x36,0x8d,0xc6,0x54,0x9e,0x61,0x51,0xf1,0xd2,0xa4,0x39,0xad,0x4a,0x14,0xa1,0x0b,0xd3,0xae,0x91,0x1a,0x29,0xeb,0xc5,0x75,0x88,0x13,0x1e,0x96,0xdd,0x6f,0x86,0x92,0xaa,0x37,0x16,0x95,0x86,0xbc,0xb1,0x35,0xbf,0x5f,0x75,0x40,0x46,0xe1,0x6f,0x2f,0x33,0x2d,0x13,0x35,0xef,0xca,0x09,0x04,0xe4,0x42,0xef,0x69,0x66,0xda,0xa6 +.byte 0x01,0xda,0x09,0xfd,0xb1,0x40,0x8d,0xaa,0xdd,0x08,0x0d,0xf5,0xf1,0xd6,0xc6,0x11,0x3b,0xbd,0xd3,0x04,0x70,0x76,0xaf,0xec,0x9b,0xcc,0x6a,0x1d,0xeb,0x95,0x4a,0x01,0x0a,0x03,0x62,0x00,0x32,0xb3,0xe0,0xd1,0x36,0xb6,0xeb,0xde,0x4b,0x5f,0x35,0x79,0x07,0x4a,0x0d,0xa1,0x8c,0xde,0x6b,0xd2,0xca,0x71,0x64,0x73,0xf7,0x9c,0x1d,0x95 +.byte 0x5c,0xdc,0xb9,0x4f,0x00,0x2e,0x86,0x3d,0x81,0x7b,0x05,0xa5,0x9e,0x03,0xa3,0x62,0xcf,0x22,0x78,0x0b,0xfe,0x09,0x3e,0x62,0x93,0x19,0x6e,0x47,0x7d,0x92,0x4a,0x0b,0xae,0xcb,0x37,0x4d,0x5a,0x3a,0x7a,0x68,0xde,0xb2,0x7e,0xd7,0xda,0x5c,0x45,0xd2,0x0f,0x1d,0x03,0xbc,0xed,0xd8,0xe5,0x2e,0x26,0x10,0x82,0x46,0x5a,0xe0,0x13,0x32 +.byte 0xf8,0xb9,0x18,0x8c,0xbd,0xb4,0xb3,0x8c,0x2f,0xb0,0x5d,0x0b,0xf3,0x8f,0x5a,0xda,0x8b,0xda,0x39,0xfe,0xe6,0x66,0x95,0x3f,0xfe,0x49,0x89,0xbf,0x43,0x36,0x77,0xc7,0x6d,0xea,0x92,0x5c,0x71,0xa6,0x29,0x50,0xb0,0x2f,0xed,0x89,0x9f,0x2c,0xd6,0x6b,0xfa,0xbe,0x62,0x9f,0x62,0xc7,0xe3,0x2e,0xd4,0xf2,0x2c,0x9c,0x98,0x37,0x38,0x5e +.byte 0x81,0x6c,0x9e,0xcc,0xff,0x0f,0xfa,0xfa,0xe8,0xdd,0x2e,0x2d,0xb5,0x92,0x44,0x5e,0x2f,0xe1,0xd0,0x6c,0xc3,0xb9,0x11,0x95,0x70,0x4b,0x01,0xa0,0xc1,0x5e,0xe8,0x1d,0x40,0x16,0x9b,0x6e,0x29,0x1b,0x13,0xb9,0xda,0x39,0xbd,0x40,0x42,0xe2,0x06,0x35,0x57,0x2f,0xa8,0xf5,0xa7,0x00,0x60,0x07,0x26,0x21,0x6b,0xe6,0x23,0xa2,0x2a,0x70 +.byte 0xeb,0x85,0xcb,0xa9,0x73,0x31,0x62,0xf7,0xb0,0x90,0xd7,0x26,0xc1,0xd3,0xd7,0xcc,0x15,0x72,0x86,0xa6,0x0f,0x4a,0x24,0x14,0x5d,0xcd,0xbe,0xad,0x7d,0xf0,0x05,0x39,0x0c,0x10,0xbe,0x11,0x9a,0x36,0x9f,0x60,0x41,0xc6,0x7c,0xab,0x54,0x8a,0xac,0xc4,0xea,0xbd,0x43,0xeb,0x19,0x5a,0x8d,0x05,0xd1,0x83,0x58,0x92,0xb8,0xc6,0x75,0x56 +.byte 0x2c,0x58,0xb8,0x2d,0xe1,0x42,0xb4,0x0b,0xc9,0x97,0x79,0xb8,0x62,0xd0,0x15,0xd1,0x5d,0x0d,0x57,0x83,0xe4,0xba,0x73,0xa2,0x27,0xb8,0x56,0x64,0x28,0xaf,0xd2,0x58,0xe3,0xe6,0x12,0x01,0x6e,0x6a,0xfb,0x81,0x57,0xcd,0x32,0xc2,0x42,0x2a,0xe2,0x51,0x4a,0x4c,0xf8,0x69,0x0e,0xc0,0xe6,0x9f,0xf4,0x46,0x4b,0x60,0xcc,0x41,0x03,0xa4 +.byte 0x14,0xf0,0x15,0xb5,0xe5,0x39,0xfd,0x69,0xee,0xce,0x23,0x3a,0x50,0x66,0xdb,0xf4,0xe4,0x31,0x23,0xe9,0x06,0x93,0xdd,0x38,0xbc,0x2d,0xb9,0xf2,0x64,0x39,0x2f,0x1b,0xa9,0x71,0x0c,0x68,0xf7,0xb0,0x5b,0x74,0xe5,0x08,0xc6,0x5d,0xbe,0xb8,0xf7,0x40,0x0e,0xb4,0xe6,0x76,0x0c,0x14,0x8f,0x9d,0x25,0x95,0x6c,0x05,0x78,0x68,0x8a,0xa6 +.byte 0x80,0x24,0x8a,0x0b,0x6a,0xd7,0xfc,0xec,0x36,0xba,0x57,0xdd,0x49,0x82,0x3c,0x5f,0x9d,0xf4,0x57,0xac,0x16,0x99,0xed,0x73,0xa6,0xb0,0x2c,0x23,0xdb,0xf8,0x45,0x22,0xf4,0x82,0x16,0xc4,0x68,0x2f,0xe7,0x8c,0x85,0x6e,0x3c,0x43,0xdd,0x3d,0xea,0x90,0xeb,0xf4,0xef,0xf1,0x36,0x48,0x15,0x29,0x07,0x96,0x51,0xb5,0x78,0xa1,0xa3,0x59 +.byte 0x18,0x4d,0x11,0x5d,0x5e,0x67,0x69,0x28,0x29,0xcb,0xeb,0xbc,0x8f,0x17,0x12,0x57,0xaf,0xda,0xb5,0x86,0xef,0x59,0xdf,0xb1,0x6b,0x6a,0x33,0x66,0x67,0xd1,0x42,0xee,0xec,0x65,0xf2,0xeb,0x97,0x17,0x4e,0x01,0x3f,0x4d,0xb4,0x06,0x8e,0xf9,0xa8,0x79,0xb6,0xf1,0x67,0x8b,0xff,0x0b,0x5f,0x93,0x70,0x76,0x54,0xae,0x7b,0x0d,0x4a,0xbc +.byte 0xf7,0xdc,0x11,0x64,0xb3,0x6a,0xd1,0x69,0x45,0x1b,0x57,0xfc,0xb5,0xfe,0x86,0xb2,0xd6,0xde,0x82,0x23,0x86,0x6b,0x21,0x78,0x8b,0x2e,0x96,0xf8,0x04,0x8b,0xba,0x15,0xae,0x33,0x91,0x27,0x88,0xe3,0xc1,0xe7,0xf8,0xc3,0xa6,0xb6,0x73,0xec,0x84,0x95,0x22,0x45,0x58,0xb1,0x50,0x99,0xde,0x8a,0x37,0x41,0x9f,0xb8,0x27,0xd6,0xd8,0xaa +.byte 0x0f,0x0e,0xac,0xe4,0xd0,0x38,0xcf,0x2f,0x03,0x6f,0x3d,0x8a,0xd7,0x51,0xd6,0xf3,0x17,0x76,0xb5,0x0f,0xc5,0xf8,0xa7,0x0a,0x91,0xaa,0x8d,0xbc,0x15,0xd6,0x46,0xb9,0xdc,0x18,0x47,0x9c,0xd9,0x13,0xa5,0xb1,0xb5,0x45,0x2f,0x03,0x32,0x5c,0x8b,0xac,0x42,0x5b,0xd9,0x1a,0x41,0x1e,0x27,0xf9,0x92,0x72,0xc1,0xc7,0xc1,0x50,0x25,0x22 +.byte 0x7a,0x00,0x41,0x1f,0x2d,0x28,0xaf,0x41,0x96,0x8e,0x97,0x3b,0x36,0x80,0x16,0xe6,0x51,0x8f,0x07,0x13,0xd9,0x81,0x79,0x94,0x92,0xaa,0xb9,0xb6,0x39,0xf2,0x4d,0x24,0x6b,0x77,0x25,0x7e,0x47,0x6c,0xc7,0x62,0x3d,0x96,0x21,0xac,0x1a,0xf0,0x5f,0x5d,0x5a,0x7e,0x17,0xdd,0x47,0xd5,0x19,0x0a,0x85,0x3e,0xd5,0x6b,0x52,0x12,0xe2,0xbc +.byte 0x43,0x79,0x28,0x1d,0x72,0xcc,0xa6,0x6c,0xea,0x9b,0xe9,0x04,0x34,0x2c,0x41,0x3a,0x64,0xe8,0xcb,0x12,0xfa,0xd5,0x45,0xad,0xe8,0x3e,0xa2,0x5c,0xb8,0x83,0x52,0xdb,0x0c,0x98,0x24,0x76,0xd2,0x00,0x62,0xff,0xac,0xd7,0x11,0xee,0xcf,0xfb,0xdd,0x65,0xd2,0x75,0xb0,0x25,0x4e,0x76,0x3f,0xa2,0x1a,0xae,0xee,0xc1,0x59,0x1b,0x0c,0x42 +.byte 0x70,0x42,0x06,0x00,0x64,0x31,0xe0,0xce,0x3a,0x91,0x5e,0x9d,0x56,0x83,0xab,0xa7,0x73,0xc2,0x15,0x29,0xba,0xf9,0x1d,0xc8,0x4b,0xc6,0x3a,0x9e,0xab,0xd7,0xfd,0x17,0x8d,0x80,0xf0,0xa1,0x8a,0x5a,0x7a,0x80,0xd8,0x1f,0xa9,0x5b,0xec,0x68,0x99,0x3a,0x66,0xcc,0x5a,0xdf,0x5f,0xe9,0xd5,0x6a,0xf2,0x2c,0x7e,0xf8,0xa7,0xdf,0x0c,0x59 +.byte 0xbd,0x85,0xf0,0xc9,0x91,0x44,0x9c,0x86,0x24,0x60,0xfb,0xe9,0xff,0x3c,0xa7,0xa7,0x6d,0x4b,0x17,0xb3,0x24,0x99,0x14,0xbc,0x64,0xd0,0x41,0xaa,0xcd,0x26,0xd3,0xa3,0x51,0xeb,0x25,0x1d,0xb2,0x7d,0xf1,0xf3,0xf3,0xf0,0x3a,0xe0,0xb5,0xa9,0x24,0xc3,0x78,0x4a,0xef,0x9b,0x34,0x93,0xf8,0x0c,0x71,0x10,0x5b,0xf0,0xe7,0x08,0x4d,0x5f +.byte 0x74,0xbf,0x18,0x8b,0x48,0x8d,0xd7,0x23,0x81,0xed,0xa2,0x29,0xa9,0xdb,0x91,0xf6,0x61,0x7c,0xca,0x1e,0xe0,0xa7,0x21,0x9d,0xfc,0x04,0x3a,0x87,0xbb,0xf9,0xa4,0x3b,0xbb,0xc4,0x89,0xa1,0x7f,0xdc,0x83,0xfa,0x5e,0x0f,0xcf,0xdf,0xf6,0x41,0xd3,0xa3,0x76,0x76,0x44,0x3e,0x01,0xee,0xce,0xf6,0xc3,0xb9,0x49,0x43,0x6e,0xee,0x09,0x4c +.byte 0x87,0xe6,0xa3,0xf5,0xa0,0x8d,0x99,0xb3,0x3b,0xd6,0xeb,0x27,0xf9,0x34,0x68,0xc8,0x04,0x80,0xb2,0x4d,0xb6,0xde,0x98,0x81,0xe0,0xec,0xc9,0x06,0xde,0x86,0xee,0xf0,0x87,0xb8,0x67,0x0e,0xce,0xf8,0xc5,0xb1,0xd2,0xe1,0xe3,0x53,0x1d,0xbe,0x6c,0xdd,0x5e,0x83,0x02,0xf5,0xc8,0xda,0xcf,0x3c,0xcb,0x88,0x2c,0xca,0x65,0x65,0x9e,0x71 +.byte 0x4e,0xf2,0x98,0x96,0xb2,0x54,0xb4,0x96,0xdc,0x84,0xb5,0x39,0x74,0x9b,0x61,0xcf,0x52,0xef,0xb3,0x0c,0x62,0xc9,0x92,0xe1,0xe5,0x6f,0x2f,0x0c,0x61,0x0d,0x6f,0xfd,0xd8,0x84,0x25,0xba,0x20,0x59,0x00,0xf5,0xa9,0xf1,0x77,0x6e,0x9a,0x3d,0x93,0x69,0xde,0xaf,0x9a,0xe6,0xe3,0xfd,0xb9,0xd3,0x04,0x82,0x18,0xa1,0x5b,0x9b,0xe0,0x29 +.byte 0x4c,0x64,0xf5,0x95,0x57,0x25,0xd3,0x04,0x8b,0x4a,0xe9,0x57,0x6f,0xd1,0x8c,0x40,0x73,0x49,0x32,0x93,0x3f,0x26,0xb4,0x6b,0xd3,0xd4,0x90,0xb7,0xe1,0xaf,0xa0,0x9a,0xc0,0x86,0xb7,0x5e,0xec,0x29,0xaa,0x03,0x4e,0x56,0xb5,0xcd,0x46,0x7d,0xe0,0x26,0x3d,0x5f,0xd3,0x55,0x86,0x68,0x4a,0xc5,0x42,0x5d,0x60,0x3a,0x39,0x6f,0x45,0xb9 +.byte 0x6a,0xea,0xf4,0x05,0xc8,0x24,0xf8,0xcd,0xe5,0xeb,0xca,0x3a,0xe7,0xb4,0x59,0x83,0x5a,0xa5,0x1d,0xe4,0x6a,0xaa,0x35,0x00,0x42,0x32,0xa5,0x6c,0x3e,0xc1,0xc2,0xc4,0x9d,0x2e,0x43,0x57,0x79,0x52,0xf6,0x1e,0x02,0xb8,0x9b,0xcd,0xf0,0x3d,0x57,0xa3,0x6f,0xf7,0x12,0x54,0x6c,0x63,0x0d,0xb2,0xba,0xff,0xa1,0xf6,0xf5,0xdf,0xa5,0xed +.byte 0xda,0xdf,0x56,0x72,0x1e,0xc5,0x3f,0xad,0xd0,0xf9,0x38,0x94,0x51,0xe3,0xa4,0xb4,0xbf,0xd5,0x24,0x2a,0x90,0xfe,0xd4,0x34,0x6c,0xa8,0xc8,0x1c,0x9a,0xaf,0xac,0xff,0x5b,0x67,0x44,0x4c,0x4d,0xa7,0x59,0x2c,0x9f,0x67,0x07,0x25,0xe1,0x7f,0x4e,0x4a,0xaa,0x8f,0x5d,0xd1,0x26,0x0d,0x73,0x9b,0x69,0x5d,0xdf,0xb2,0xa5,0x89,0xbb,0x82 +.byte 0x0b,0x09,0xf3,0x11,0x76,0x5d,0x2d,0xad,0xc3,0xc1,0x15,0xbc,0xaf,0xa2,0xe6,0xd5,0xb0,0x6d,0x80,0xa6,0xda,0xfa,0x3b,0x9c,0xaf,0xff,0x98,0x40,0x83,0x3a,0xe1,0xb8,0x98,0x0e,0x97,0x00,0x89,0xfb,0x37,0xcb,0x81,0x36,0x34,0x33,0xbb,0x5c,0xd0,0x51,0x37,0xd6,0xb5,0x6c,0x3a,0x61,0x0a,0x27,0x23,0x96,0xa9,0x79,0x8d,0xf0,0xbe,0x31 +.byte 0xba,0xdc,0x89,0x4e,0x88,0x98,0xe4,0x10,0x15,0x8a,0xe1,0xae,0xe8,0x6d,0xa4,0x61,0x56,0x14,0x84,0x59,0x64,0xc2,0xaa,0xd8,0xfd,0x19,0xfc,0x17,0xf1,0xfc,0x6d,0x17,0xcb,0xea,0x7a,0x47,0x00,0x75,0x17,0xf3,0x62,0xfe,0x3a,0xbc,0x28,0x1a,0x0e,0x88,0x48,0x63,0x4a,0xcb,0x20,0x46,0xa4,0x75,0xf8,0xf1,0x7a,0xd6,0x92,0x7f,0x92,0xfa +.byte 0x91,0x95,0x2f,0xbc,0x5b,0x42,0xf1,0x55,0xaf,0x91,0xa2,0x3b,0x29,0x5c,0xc8,0x5e,0x97,0x91,0xa2,0x2e,0xd2,0xa8,0x1c,0xf6,0x16,0xc5,0x15,0xf2,0x42,0xb3,0x41,0x59,0x52,0x8d,0x94,0x52,0xc4,0xc6,0x2c,0xdd,0x6f,0x01,0xea,0x62,0x42,0x83,0x7e,0x2e,0xf8,0xb8,0xc1,0xf3,0x71,0xd1,0x11,0x14,0x7a,0x3d,0xcd,0xec,0xe0,0x79,0x8b,0xbd +.byte 0x28,0x12,0x60,0xf0,0x66,0xf1,0x1c,0x1c,0x19,0x07,0x8c,0x26,0xff,0xcc,0x72,0x9a,0xbd,0x12,0xe6,0x2b,0x2b,0xb1,0x32,0x04,0x98,0x92,0xd9,0x24,0x97,0x59,0x46,0xc6,0x11,0xe1,0x31,0x14,0x46,0x27,0x96,0xb1,0x06,0x81,0xd5,0xe8,0xff,0x45,0x3d,0x3c,0x04,0x9a,0xd8,0x0b,0x1f,0x41,0x03,0xba,0x1b,0x3e,0x4e,0xd5,0x7d,0x48,0x00,0x68 +.byte 0xb3,0xe8,0xe0,0xc8,0x3c,0xcf,0xdc,0xbe,0x29,0x90,0x64,0x51,0x18,0xdc,0xcd,0x87,0xcb,0xa8,0x3d,0xf8,0xb4,0x73,0x11,0xdc,0x7a,0xcb,0xa4,0x81,0x9e,0x3a,0x72,0xde,0x18,0x36,0x86,0x15,0x91,0xbc,0xeb,0x7f,0xe2,0xfb,0x6b,0xf1,0x5a,0x3d,0x05,0x50,0xeb,0xcf,0xd2,0xcc,0xf2,0x62,0xb1,0x32,0x46,0x14,0x95,0x4e,0xdf,0x73,0x64,0x61 +.byte 0x5f,0x3d,0xbf,0x52,0x3e,0xa7,0x55,0x01,0x9a,0xd8,0x01,0xef,0xf7,0x60,0x6f,0x83,0x43,0x6b,0x4c,0xa2,0xc8,0x04,0x34,0x70,0x70,0xa1,0x99,0xc9,0xa7,0x54,0x1e,0x87,0x99,0xb3,0xec,0xfe,0xe9,0x2d,0x39,0xef,0x6f,0x4d,0x8c,0xf2,0x4b,0xd2,0x12,0x5d,0xb6,0xa7,0x0b,0x04,0x3b,0x69,0xdd,0x9a,0x18,0x2d,0xd9,0x22,0x00,0x38,0x15,0x9a +.byte 0x6e,0x6c,0x0c,0x84,0x32,0x32,0xb2,0xf9,0x61,0xef,0x74,0x35,0xec,0xcc,0xd7,0xbc,0x9d,0xe9,0xcd,0xe3,0xa0,0xa5,0x15,0x0a,0xfe,0x1f,0x37,0x35,0x2b,0x7c,0x42,0x50,0x81,0x67,0x52,0xb7,0xa7,0x9e,0x8f,0xda,0x64,0xc0,0xc0,0xc3,0x93,0xc7,0x9d,0x41,0xb8,0x4b,0x69,0x80,0x13,0x88,0x8a,0x07,0xf9,0x47,0xad,0xc9,0x4f,0x3d,0xc7,0xba +.byte 0xd2,0xf2,0x7a,0xa0,0x38,0xbe,0xe1,0xfa,0x83,0xda,0x79,0x29,0x7f,0x4c,0xfa,0x0e,0x9b,0x59,0x1e,0x89,0x76,0x05,0x60,0x84,0x13,0x63,0x11,0x14,0x20,0xa9,0x2b,0xd0,0xc3,0x58,0xcc,0x73,0x3e,0x2c,0xa8,0xa7,0xa5,0xd0,0x2f,0x03,0xfc,0xa9,0x5d,0xdd,0xcd,0x40,0x91,0x90,0x1f,0xda,0x0a,0x73,0x58,0xd8,0x84,0x05,0x45,0x01,0x84,0x52 +.byte 0x8b,0x9b,0x17,0x98,0xa8,0xc4,0xc3,0xb5,0x94,0xd5,0x32,0x86,0xe9,0x10,0xe5,0xa5,0x99,0x8d,0x57,0x3e,0x32,0x25,0xfa,0xb4,0x5c,0x3a,0x5f,0xa6,0x2d,0x7d,0x4e,0xd3,0x7b,0xee,0x41,0x23,0x5e,0xc2,0xc9,0x91,0xf4,0x21,0xe0,0x4f,0x0d,0x87,0x30,0x53,0xf1,0x0e,0x63,0xe8,0x5b,0x3d,0xee,0x4a,0xc8,0x78,0x38,0xa2,0xa4,0xe8,0x72,0x41 +.byte 0xf1,0x37,0x30,0xe3,0x3d,0x93,0xc6,0x4b,0x10,0x0d,0xf6,0x20,0x15,0x0a,0x77,0x41,0xd5,0x7d,0xcb,0xf9,0xda,0x3b,0x17,0xa6,0xf1,0xe4,0x56,0xd4,0x65,0x7b,0x33,0xe4,0xef,0x34,0xfb,0x8c,0x9f,0x87,0x86,0xfc,0xce,0x90,0x60,0x77,0x57,0xc0,0xe4,0x37,0x2c,0xdf,0x41,0x95,0x85,0x89,0x4e,0x77,0x3f,0xa0,0xc7,0x55,0x4c,0x3f,0xa8,0x10 +.byte 0xd2,0x87,0x7e,0xd2,0x97,0xa1,0x6c,0xe7,0xec,0xaa,0xf6,0x93,0x13,0x2e,0x10,0xed,0x5b,0x7a,0xed,0x53,0xb4,0x55,0xaa,0xb4,0x67,0x78,0x07,0x5f,0xc2,0xd2,0xf1,0x7b,0x98,0xf0,0x82,0xf6,0x7c,0xb2,0xd4,0xa8,0xc2,0x53,0x39,0x21,0x7f,0xa0,0x76,0x37,0x1a,0x69,0xb3,0x49,0xd4,0xc3,0xd1,0xcb,0x31,0x76,0xec,0xaf,0x75,0x66,0x31,0x65 +.byte 0xeb,0x44,0x63,0xa0,0x13,0xf5,0x9e,0x67,0x40,0x41,0x76,0xce,0xd3,0xd6,0x91,0xb1,0x3a,0x07,0xff,0x38,0x1e,0xaf,0x55,0x57,0x55,0xd1,0x94,0x63,0xd3,0x81,0x16,0x59,0x68,0x01,0xe8,0x6d,0x7d,0x7a,0xa1,0x39,0xb9,0xa2,0xba,0x79,0x9d,0x69,0x00,0x13,0x59,0x2f,0x3d,0xef,0x10,0xe7,0x3c,0x02,0x7d,0xa3,0xa8,0xee,0x31,0x1a,0xad,0xa6 +.byte 0xdb,0x1b,0xe3,0x4a,0xdd,0x60,0xfb,0x4e,0xa6,0x49,0xbb,0xea,0x34,0x5d,0x21,0xac,0x83,0xa4,0xb5,0x23,0x8e,0x69,0xb3,0x25,0x14,0x8d,0xc2,0x89,0x8d,0xcf,0x38,0x46,0x18,0xb6,0x0c,0xce,0x45,0x22,0xeb,0xb5,0xb2,0xed,0xe5,0x0f,0x35,0x8f,0xdd,0xa1,0x15,0xd6,0x50,0x5b,0xe1,0x04,0xa7,0x32,0xc0,0xc9,0x03,0x56,0xc2,0x33,0xe8,0x16 +.byte 0x1c,0xd4,0x7a,0xfd,0x6b,0x4d,0x04,0xc0,0x9e,0xf8,0x32,0x9f,0x52,0x24,0xac,0xc5,0xb0,0xa1,0x63,0x77,0xc9,0x14,0xaf,0x46,0x60,0x67,0x52,0x81,0xbb,0x3f,0xf5,0x7f,0xad,0xef,0x7c,0x3a,0x71,0xc1,0x1e,0xea,0x4a,0xe0,0xd7,0xdd,0x31,0xf2,0x4b,0xdf,0x53,0x8a,0xc9,0x59,0x7a,0xb2,0x6f,0x7e,0xc0,0x00,0xa4,0x0d,0x09,0x9c,0xf7,0x22 +.byte 0x22,0xa9,0x37,0xde,0x3b,0xe1,0x74,0x85,0xcf,0xc5,0xb7,0x7b,0x0a,0xfd,0x6b,0xfa,0x98,0x49,0xa9,0x7f,0x52,0x23,0x0e,0xc0,0x4a,0xb3,0x81,0xa6,0x96,0x46,0x24,0xe7,0x01,0xd1,0xf2,0xac,0x31,0xb2,0x5e,0x61,0xe3,0xab,0xf8,0x1b,0x28,0xca,0xa2,0x78,0x3c,0xdf,0x8a,0xc1,0x17,0x46,0x9d,0xbd,0x69,0x31,0x41,0x8b,0xc1,0xc8,0xaa,0x68 +.byte 0xd5,0x35,0x65,0x49,0xfe,0xc6,0xa4,0x99,0xcc,0x62,0x4b,0x81,0x1c,0x21,0xa4,0xd8,0xe3,0xb3,0xe9,0x7c,0xf8,0x33,0x2f,0x21,0xa5,0x88,0xf2,0x8e,0x7d,0xee,0x00,0x00,0x62,0xcf,0x07,0x37,0x00,0x68,0x6c,0xb5,0x2d,0xc6,0x1b,0xcc,0x86,0x71,0xf0,0x4f,0x68,0xaf,0x0c,0x9a,0x25,0x69,0x71,0x2d,0xb5,0x87,0x90,0x02,0xd3,0xfc,0xbb,0x63 +.byte 0xa9,0xf1,0x13,0x4f,0xda,0x71,0x69,0x5c,0x0b,0xfd,0x3f,0x6c,0x2f,0x0b,0x4f,0x07,0x72,0x2d,0x2f,0x77,0xcb,0xa4,0xe4,0xbd,0x30,0xc7,0xe4,0xd9,0xf9,0x5d,0x2f,0x65,0xe4,0x41,0x5c,0xbc,0x03,0xa2,0x01,0xf9,0xfa,0x06,0x14,0x52,0x08,0x44,0x67,0x75,0x4e,0xbd,0x66,0x4a,0x26,0x3a,0x49,0xc4,0xba,0x02,0xb3,0x8e,0xa2,0x42,0xe7,0x92 +.byte 0x03,0x6d,0x61,0x10,0x73,0xd0,0x6f,0xe1,0x6e,0x67,0xff,0xb0,0x29,0x62,0x70,0x3c,0xeb,0x80,0xed,0x11,0x06,0xd6,0x18,0x60,0xe1,0x3d,0x21,0xa9,0xe9,0xd2,0x92,0x00,0x9e,0x13,0xf2,0x5d,0x38,0x71,0xdf,0xf3,0x5f,0x8a,0x90,0x45,0xf0,0x47,0x1f,0x0b,0x2d,0x12,0xf7,0x10,0x07,0x6a,0x52,0xe8,0xe2,0x26,0x9b,0x4b,0x7a,0x5f,0x97,0xb6 +.byte 0xf1,0x6d,0x47,0x3a,0x1e,0xc8,0x1d,0x78,0x5b,0x0a,0xb8,0x03,0xb1,0xe1,0xe7,0xc8,0xf0,0xe7,0x00,0xac,0xfc,0xd7,0x4a,0xde,0xaa,0xcd,0x0f,0xaf,0xf7,0x56,0x8e,0xed,0xfb,0xbe,0x7e,0xfe,0x62,0x75,0x7a,0x07,0x96,0xff,0xc3,0x21,0x35,0x71,0xb9,0x73,0x41,0xc2,0xb0,0xa8,0x6a,0x65,0x48,0xc4,0x50,0x31,0xe2,0xba,0xf4,0xe9,0x6c,0x03 +.byte 0x26,0x2c,0x77,0xfe,0x1a,0xd5,0x96,0xf6,0x6d,0xe4,0x14,0xfc,0xe2,0x1d,0x20,0x0c,0x14,0xa2,0x39,0x63,0xe5,0x16,0xef,0x6a,0xeb,0xe1,0x69,0xb8,0x67,0xa0,0x91,0xc1,0x8f,0xed,0xff,0xdf,0x26,0x1f,0xc3,0xb7,0x5d,0xe9,0xd2,0x72,0xe2,0x54,0x27,0x46,0x4f,0x33,0x25,0x59,0xaf,0xfa,0x87,0x4b,0x5a,0xda,0x7d,0x15,0x71,0x5d,0xb4,0x8d +.byte 0x95,0xb6,0x09,0x5b,0x8b,0xeb,0xe6,0xba,0xc8,0x2f,0x8f,0x9e,0xa8,0xab,0x6a,0xa6,0x26,0xb6,0xf5,0x80,0xd0,0x7d,0xe7,0x4c,0x18,0x5a,0x72,0x8f,0x3e,0x90,0xe5,0xa1,0x16,0x33,0x66,0xc3,0x7b,0xf6,0xb6,0xdd,0x15,0x94,0x6d,0xca,0x8b,0xd7,0xa5,0x05,0xfb,0x5f,0x4e,0x94,0x6a,0xcc,0x54,0xed,0xeb,0xc0,0xb1,0xe1,0xc9,0x7f,0xc4,0x90 +.byte 0x2f,0x50,0x34,0x81,0x3c,0x83,0x47,0x3c,0x5a,0xb2,0x33,0x63,0xb6,0xa7,0xfb,0x59,0x70,0x87,0xea,0x7f,0x30,0x22,0xb4,0x54,0x48,0xfb,0x40,0xd2,0x7b,0xc9,0x49,0x80,0x18,0x27,0xc2,0x75,0x09,0x06,0x0a,0x83,0x1e,0x7a,0xf1,0x97,0xa1,0xc2,0x34,0x3f,0x6d,0xd6,0x2d,0xfe,0x5d,0x8b,0xfd,0x64,0x5d,0x6f,0x7f,0xbf,0x4e,0x01,0xb7,0x46 +.byte 0xfb,0xf7,0xd5,0x6f,0x5f,0x74,0xc8,0xca,0x9a,0x2e,0x74,0x08,0xe9,0x3d,0x8b,0xfd,0x97,0x38,0x72,0x67,0xbb,0x8a,0x34,0xee,0xf5,0x3a,0x2b,0x5e,0x64,0x64,0x06,0x7c,0x60,0x0f,0x7a,0x88,0x45,0x1b,0x69,0x90,0xb8,0xb0,0x4d,0x71,0x80,0x77,0xa8,0xaa,0x9f,0xd3,0xc6,0xfb,0xb8,0x12,0x1e,0x0c,0xf4,0x94,0x67,0x44,0xdc,0xb1,0x95,0x0e +.byte 0x51,0xd1,0x06,0x69,0x92,0xbf,0xe6,0x67,0xe3,0xcd,0x0b,0x87,0x03,0x12,0x2e,0xa7,0x23,0x72,0x13,0xe9,0x89,0xcf,0x15,0x43,0xc0,0xa7,0x68,0xbd,0xce,0xec,0x28,0xb6,0x85,0x36,0xbe,0x52,0x5d,0x57,0xfa,0x7d,0x72,0xd1,0x4b,0x88,0xc9,0x64,0xbc,0x7a,0x18,0xe5,0x0e,0xab,0x19,0x81,0xee,0x11,0xbe,0xe0,0x68,0x44,0x81,0x49,0x3f,0xd8 +.byte 0x12,0xd1,0x8b,0xc1,0xe0,0x51,0xf7,0xc3,0x64,0xa7,0xc5,0x61,0x9b,0x32,0x6d,0xf0,0x6c,0xa6,0xaf,0xf9,0x4a,0xdf,0x94,0xaf,0xc8,0xf2,0x86,0xb1,0x4e,0x2e,0xa9,0xb4,0x35,0x82,0x15,0x8a,0x58,0xf3,0x03,0x2f,0x78,0x07,0x8f,0xb9,0x16,0x7c,0x42,0xfa,0x36,0xaa,0xa5,0x66,0x62,0x44,0xca,0xa6,0x55,0x95,0x27,0xdb,0x48,0xea,0x0a,0x1d +.byte 0x5a,0xae,0x5c,0xad,0x99,0xfe,0x00,0xf1,0xb9,0x94,0xda,0x09,0x48,0x52,0x9d,0xfc,0xb4,0xb2,0x80,0x19,0x16,0xf8,0xcd,0x68,0x10,0xec,0x1c,0x16,0x3f,0xbb,0x42,0xb4,0x10,0xe3,0xdb,0xaa,0xe4,0x3f,0x2e,0x8e,0xb5,0xce,0xba,0x8f,0xf2,0xb5,0x76,0x98,0x15,0xa7,0x77,0x4b,0x1c,0x30,0xb7,0x6f,0xc9,0xa9,0xa4,0x64,0x59,0xab,0x3a,0x43 +.byte 0x74,0x33,0xab,0xe1,0x3e,0x5e,0x79,0x1c,0xa5,0xb4,0x87,0xe1,0xcb,0xea,0x0e,0x02,0x4b,0x01,0x84,0xbc,0xdc,0x75,0xf4,0x2c,0x2b,0x8d,0xc8,0x5f,0xb5,0xba,0x6b,0xb2,0x4a,0x7c,0xe7,0xaa,0x61,0xa5,0x0c,0xf8,0x02,0x73,0xec,0x11,0x13,0x6b,0x31,0x07,0xaa,0x79,0x78,0x86,0x01,0x77,0x5e,0xa3,0x09,0xd1,0xec,0xaf,0x7d,0xb7,0x65,0xa9 +.byte 0xd8,0x99,0xd2,0xd7,0x6d,0x32,0x97,0x0f,0x0e,0x51,0x0d,0x69,0x81,0x7a,0x94,0x48,0x31,0xe1,0xff,0x26,0x4d,0x30,0x49,0x93,0xfb,0x6e,0xdb,0xea,0xaf,0xcb,0xb4,0xa9,0xc9,0x9f,0xeb,0xca,0x52,0x36,0x26,0xac,0x47,0xda,0x02,0x3d,0xd0,0x93,0x8b,0x61,0x78,0x26,0x54,0x32,0xe8,0x14,0xac,0xf3,0xd2,0x46,0x04,0x12,0x89,0x9f,0xf6,0x11 +.byte 0xf5,0x64,0x83,0x66,0x00,0x50,0x55,0x05,0xb5,0xf6,0x58,0x9f,0xbf,0x4b,0x95,0xf1,0x7f,0x0b,0xb4,0xf7,0x63,0xea,0x6f,0xf7,0xb0,0x20,0x53,0xfe,0x95,0xbc,0xc4,0xe2,0xff,0x75,0xbd,0xab,0x73,0x68,0x44,0x18,0xf7,0x6b,0x04,0x46,0xde,0x6c,0x65,0xb2,0x22,0x4e,0x25,0x8e,0xba,0x7c,0x3a,0x6f,0x80,0x99,0xb4,0xe7,0xf9,0x97,0x68,0x40 +.byte 0xa9,0x96,0xfc,0x6b,0xcf,0x08,0x75,0xe4,0xda,0x6f,0xaf,0x71,0x4f,0x31,0x62,0x31,0x18,0xbf,0xb9,0xa0,0xcc,0x9e,0xa7,0xa2,0x27,0x2a,0xb8,0x6b,0xc0,0x93,0xf5,0x1f,0x41,0x25,0xa7,0x4d,0x9f,0xb4,0x12,0x5c,0x27,0x38,0x5d,0x80,0x88,0xa3,0xb8,0xb2,0xc3,0xd2,0xfb,0x1d,0xba,0x7b,0xac,0x51,0x0b,0x71,0x58,0x3f,0xe5,0xfa,0x36,0xb8 +.byte 0xc7,0x90,0x46,0xd0,0x5a,0x94,0xf0,0x7d,0x6e,0x6c,0x4c,0xb1,0xfa,0xdb,0x97,0x1e,0x19,0xf2,0x1f,0x4e,0x05,0x25,0x0e,0xbd,0x47,0x94,0x2a,0xd3,0x1a,0xbe,0x4a,0x04,0xaa,0x57,0x02,0xc9,0x42,0xc1,0x74,0xcd,0xe1,0x78,0x8b,0xff,0xc1,0xc6,0x17,0x4e,0x71,0xc4,0x2c,0x00,0x23,0x56,0x57,0x1f,0x47,0xd8,0x93,0x80,0xc1,0xc5,0x7b,0xd9 +.byte 0x25,0x30,0xac,0x72,0x37,0x00,0xd2,0xbc,0xc7,0x33,0x73,0xf9,0x14,0x86,0x7c,0xb0,0x28,0x14,0x5d,0xbf,0xbd,0x98,0x1c,0x00,0x05,0x19,0x2b,0x0a,0x55,0xad,0xb4,0x06,0x28,0x58,0x03,0xa1,0xe6,0x27,0xa3,0x32,0x5f,0x41,0xd5,0x6a,0x0b,0xbc,0x0f,0xaa,0xf5,0xc1,0xa7,0x09,0x2f,0x86,0xda,0x56,0xb0,0x04,0x49,0xd4,0x20,0xc6,0xa2,0x6c +.byte 0x27,0x56,0x4e,0xcd,0x22,0x46,0xac,0x0f,0xd3,0x99,0x69,0x83,0xc4,0xae,0x9f,0x88,0xed,0x9c,0xba,0xfb,0xf3,0x66,0xc7,0x3d,0x65,0x55,0xd0,0xe3,0x04,0x03,0x6a,0x02,0x5c,0xbf,0x9f,0x23,0x34,0x79,0xe1,0xbe,0x7d,0xad,0xb4,0xc7,0x9e,0x4d,0x80,0x73,0x6d,0xe5,0x37,0x03,0xac,0xa3,0xf4,0x93,0xad,0x1e,0xf3,0xcd,0xb8,0xe2,0xeb,0x30 +.byte 0xc7,0x50,0xfe,0x0a,0x63,0x5e,0x0f,0xc9,0xd0,0x06,0x58,0xc1,0x6e,0x65,0x54,0x54,0x5d,0xaf,0xf1,0xe8,0x3e,0x95,0xe3,0x70,0x40,0x8e,0xb8,0x4d,0x76,0xda,0xa8,0xe8,0x9e,0x88,0xd8,0xaf,0x67,0x83,0x3b,0x77,0x65,0x58,0x00,0xbb,0xf7,0xe9,0x52,0xf0,0xba,0x0d,0x0a,0x59,0x28,0xe4,0xa7,0xfb,0x06,0xe5,0x34,0xbe,0xcf,0x10,0x7c,0x73 +.byte 0xa8,0xf3,0xa2,0x93,0x96,0x9e,0x4f,0x9b,0x3c,0xd1,0x9f,0x64,0x5b,0x8c,0xc1,0x89,0x66,0x67,0x13,0x52,0xb2,0xaa,0x6b,0x8e,0xea,0x97,0x27,0x20,0x2e,0x64,0xec,0xf0,0x72,0xc9,0x54,0x8a,0xed,0x78,0x3a,0xd7,0x4f,0xc2,0xba,0xc3,0xb8,0x64,0x7f,0xe4,0x5f,0x3d,0xf7,0xe5,0xd9,0xf1,0x8d,0xb1,0xd2,0xf6,0xcc,0x34,0xd8,0x7d,0x16,0xca +.byte 0x47,0xaf,0x85,0xe5,0x4a,0x57,0xb9,0x5a,0x9e,0xff,0xb8,0x83,0xec,0x7c,0xb8,0x07,0xf5,0xd3,0x31,0x31,0x2b,0xf0,0x40,0x46,0xc3,0x63,0x27,0xe4,0xb0,0x3b,0x84,0x0d,0x50,0x05,0x80,0x0c,0xfa,0x8b,0x0e,0x33,0x6b,0x10,0xd4,0xf5,0x4f,0x8b,0x2d,0x9e,0xc5,0x01,0x92,0x52,0x62,0x1a,0x89,0x1e,0xca,0x48,0xc3,0xd6,0xfa,0xd2,0x94,0x7c +.byte 0x77,0x6e,0xa7,0xeb,0xd7,0x4f,0xe8,0xc8,0xc2,0x71,0xb2,0x9e,0x86,0x30,0x18,0xfd,0x4c,0x56,0x4c,0xd0,0xa4,0x84,0x37,0x02,0x02,0x6a,0x8d,0x57,0x6b,0xc2,0x06,0xd1,0x8a,0xdb,0xa0,0xcc,0x31,0xf9,0xcf,0xbf,0xf2,0x29,0x7c,0x26,0xac,0x1f,0x03,0x20,0x26,0x76,0x03,0x6f,0xa5,0xb5,0x33,0xfb,0x02,0xe8,0xf6,0xe9,0x5e,0xb1,0x36,0x7c +.byte 0x96,0x56,0xb1,0x98,0x2d,0x9c,0x38,0x9b,0xd4,0x56,0x28,0xcc,0xdb,0x08,0xd3,0x42,0x00,0x35,0x24,0xd9,0x74,0xa2,0x0d,0x55,0x21,0x06,0xb7,0xf9,0x6a,0xa0,0x81,0xc1,0x2d,0xb6,0x67,0x91,0x92,0x24,0x36,0xfd,0x2e,0xd8,0xc0,0xcb,0xc8,0x87,0x1a,0x41,0x11,0x70,0xbf,0xd2,0xe7,0x82,0x10,0x74,0xdf,0x65,0x46,0x19,0x6b,0xb4,0x89,0xeb +.byte 0x9e,0xcf,0x79,0x35,0xba,0x25,0x75,0x32,0x64,0x6a,0xfb,0xaf,0xe5,0xed,0x85,0x98,0x34,0x75,0x31,0x40,0xbb,0xd8,0xe3,0xf5,0xa7,0xa2,0x9a,0x9e,0xcd,0xc4,0xf8,0xd8,0x15,0x6c,0x64,0x0c,0x6c,0x16,0x60,0xe9,0x40,0xf4,0x7a,0x14,0x37,0x7b,0x45,0x9b,0x0e,0x29,0x7a,0x1a,0x88,0x10,0xb9,0x2b,0xee,0x13,0xbd,0x8a,0xde,0x7a,0xe9,0x30 +.byte 0xe8,0x39,0x77,0x74,0xf5,0x2f,0xe3,0x10,0x19,0x89,0x28,0x21,0x3a,0x68,0x38,0xb4,0x4d,0x20,0x8d,0x7d,0xec,0x3f,0xf7,0x61,0xbf,0x53,0x32,0x3b,0xb8,0x6a,0xc9,0x58,0xeb,0xd4,0x33,0x0e,0xee,0xc7,0xb9,0x5e,0x3d,0x17,0x7e,0x36,0xa2,0xa6,0x94,0xb1,0x56,0xb6,0x8e,0x94,0x05,0x50,0x69,0x52,0x4f,0x31,0xe5,0x97,0x18,0xde,0x8f,0xb7 +.byte 0xff,0x2e,0x6f,0x1b,0x6a,0xda,0xfd,0xa1,0xd1,0x9a,0x4e,0x6a,0x1b,0x46,0x71,0x52,0x76,0x66,0xf9,0x70,0x8d,0x7d,0x97,0xb0,0xc3,0x8d,0xbc,0x35,0x26,0xe8,0x0b,0x80,0xc7,0x58,0x19,0x22,0x70,0x33,0x06,0xeb,0xcf,0x26,0x22,0xe0,0x97,0x91,0xbf,0xd6,0x94,0x05,0xe1,0x84,0xe2,0x31,0x66,0x57,0xc7,0x1e,0x36,0x30,0x50,0xaf,0x72,0xb3 +.byte 0x31,0xad,0x84,0xcc,0xb5,0x76,0x03,0xe1,0x56,0x97,0x87,0x36,0xf5,0xaa,0x97,0x99,0x38,0xa5,0xf5,0xb7,0x42,0x86,0x3b,0x2f,0x8a,0xb9,0x8e,0x6a,0x0b,0xe0,0xca,0xbc,0x4c,0x6c,0xc1,0x3f,0xbe,0x45,0xef,0xd2,0x57,0xcd,0x29,0xfb,0xfb,0xa5,0x79,0xf2,0xb1,0xbb,0x4b,0x55,0x26,0x2f,0x5c,0x84,0x5e,0x6a,0xc6,0xa9,0xd5,0x23,0xe4,0xd1 +.byte 0xe5,0xf0,0xbc,0x50,0x6a,0x2a,0xaf,0xa2,0x7c,0xcc,0x36,0x95,0xf9,0x5c,0x04,0x6d,0x04,0x31,0xbe,0x1d,0xb2,0x50,0x97,0x8f,0xdf,0x8a,0xed,0x4e,0x4e,0x0a,0x0b,0xfc,0xfc,0x1d,0xa9,0x6a,0x76,0x6a,0x33,0xd7,0x0a,0xcf,0xd5,0xdd,0xc6,0x62,0xe5,0x59,0x02,0xba,0x9c,0x43,0x32,0x8a,0x0e,0x47,0x91,0x00,0x07,0x47,0x93,0xc4,0xad,0x29 +.byte 0x33,0x57,0x15,0x45,0x44,0xb9,0xf3,0xc4,0xe6,0xd2,0xb9,0x3a,0x44,0x16,0x32,0x8d,0x57,0x78,0xac,0xf5,0xdb,0xa2,0x93,0x97,0x64,0x08,0x9b,0x66,0x4b,0xa0,0x64,0xab,0xa0,0xd6,0x0e,0x2c,0xa1,0x25,0x16,0x5c,0x6f,0x82,0xff,0x8e,0x89,0xfb,0xca,0x03,0xa6,0xf8,0xa1,0xf6,0x87,0x02,0x5c,0x90,0xcb,0x33,0xa0,0xc0,0x90,0xc2,0x1f,0xdd +.byte 0x5c,0x50,0x93,0xf2,0x8b,0x87,0xa1,0x73,0xda,0x5f,0xa3,0x20,0xd4,0xe7,0x45,0xd7,0xea,0x4b,0x5d,0xd6,0x80,0xfc,0x2d,0xdc,0x45,0x6a,0xf6,0xaf,0xd4,0x7a,0x91,0x64,0x15,0x17,0xbf,0xc7,0x58,0x54,0x7c,0x08,0x42,0x4f,0x8d,0xab,0x9b,0xd0,0x1d,0x57,0x71,0x50,0xa7,0xe3,0xb4,0xf2,0x14,0x0c,0xd7,0x2f,0x7c,0x8b,0x17,0x61,0x98,0xfa +.byte 0x19,0x34,0xb9,0x65,0xc5,0x5c,0xfe,0xa3,0x80,0x6f,0x99,0xec,0xfa,0x06,0x22,0x71,0xa9,0x10,0x2a,0xcf,0x12,0xb3,0x17,0xe5,0x59,0x3a,0xaa,0xcb,0x55,0x5f,0x45,0x9d,0xe9,0x29,0x56,0x34,0x11,0x62,0x6e,0x0a,0x95,0x12,0x5d,0xd4,0xa2,0x28,0x05,0xf1,0x0f,0x2d,0xa0,0x1e,0xe1,0x2b,0x42,0x6c,0xf0,0xe6,0x47,0xe0,0xb2,0xbd,0x89,0x20 +.byte 0x5e,0x24,0x05,0xec,0xf1,0x33,0xfc,0xa9,0x2f,0xef,0x3a,0x1f,0xfe,0x39,0xfe,0x01,0x09,0x0a,0x2a,0xe0,0x96,0x1e,0xde,0xad,0x96,0xaa,0x48,0xeb,0x8a,0xe6,0x54,0xbb,0x5d,0x7a,0xbe,0x4a,0xbf,0x96,0xf6,0x15,0x7a,0x70,0x6f,0xee,0xe7,0xf5,0x53,0xaf,0xe1,0xbb,0xaf,0x58,0x51,0xd4,0xa0,0xc6,0x44,0x03,0x47,0x33,0xce,0x58,0x62,0xd3 +.byte 0x93,0x21,0xa5,0xa5,0xb4,0xef,0x1d,0x93,0xcc,0x8c,0xf7,0x14,0xe3,0xec,0x40,0x52,0x47,0xe6,0xbc,0xe6,0x85,0x69,0xd0,0x15,0xad,0x24,0x21,0x4f,0x26,0x01,0x60,0x0f,0x0f,0xcb,0x7e,0x14,0x01,0xe1,0x90,0x11,0x06,0x17,0x38,0x2d,0xd8,0x26,0xe2,0x7c,0xd6,0xef,0xe0,0x59,0xf0,0x8c,0x2a,0xbd,0xba,0xe5,0x8b,0x07,0x56,0xd3,0x35,0xb3 +.byte 0x64,0x83,0x9e,0xb9,0xb9,0xeb,0x88,0x03,0xff,0x14,0xf3,0x8b,0x14,0xd3,0xa4,0xac,0x08,0xd9,0x75,0xf6,0x2c,0x9d,0x7f,0xc8,0x9d,0x11,0x3b,0xd1,0x71,0x14,0x4b,0x2a,0x6d,0x20,0x83,0x32,0x35,0x7e,0x1f,0x20,0xa6,0x69,0xbf,0xcf,0x22,0xd9,0xa2,0x57,0x4b,0x66,0xb1,0x9f,0x5a,0xa8,0xaa,0xb8,0x11,0x1d,0x45,0x28,0xac,0x86,0x09,0x37 +.byte 0xe9,0x1f,0xef,0xb4,0xe0,0x6f,0x75,0xad,0xe5,0xd8,0x25,0x06,0x19,0xb4,0xa8,0x07,0x78,0x79,0x43,0x63,0x40,0x26,0xbd,0x28,0x50,0x2d,0x29,0x26,0xf9,0xfc,0x5c,0x71,0x8f,0xfd,0x62,0x12,0x7c,0xd0,0x67,0xb3,0x65,0xef,0x31,0xc0,0x99,0xc1,0x54,0xfc,0x32,0x6e,0x25,0x56,0x77,0x6e,0xc1,0x6b,0x11,0x50,0x7c,0xa1,0x0b,0x97,0x8a,0xfe +.byte 0x0f,0x5b,0x16,0x93,0x83,0xe0,0xd8,0xb7,0xbf,0xa8,0x90,0x6d,0xd6,0x8b,0x4b,0xd9,0x17,0xbb,0xe8,0xd9,0xbb,0x5f,0x39,0x4a,0x33,0x7c,0xb3,0x12,0x99,0x1e,0xfc,0xb2,0x05,0x91,0x67,0xdf,0x8d,0x0b,0x55,0xfb,0xd1,0x8d,0x0c,0x9b,0x80,0x81,0xee,0x8c,0x05,0xe2,0x16,0x30,0xad,0x1f,0x88,0x04,0x75,0xc1,0xe5,0xec,0x32,0xf8,0xa0,0x5b +.byte 0x21,0xf6,0xd8,0x13,0x26,0xe4,0xa1,0x32,0xa8,0x93,0x91,0x5d,0x33,0x45,0x83,0x72,0x52,0x59,0x23,0x84,0xf6,0x7b,0xe2,0x90,0x20,0xc6,0x40,0x33,0xa9,0x94,0xcd,0xb9,0xab,0xe4,0x44,0x0b,0x06,0xbb,0x4c,0x2c,0x2a,0x5e,0x4d,0x57,0xb7,0xe0,0xb8,0x86,0x74,0xab,0xea,0x37,0x1c,0xa0,0xa6,0x21,0x33,0xc7,0xf5,0x24,0x7d,0x14,0xc8,0x8b +.byte 0x9d,0x8f,0x31,0x23,0x29,0x9d,0x11,0x42,0x07,0xe8,0x2c,0xec,0x7d,0x70,0x8d,0xb5,0xa4,0xca,0x33,0x30,0x03,0x75,0x17,0xa1,0x10,0xe7,0x6b,0x87,0xf9,0x0b,0xef,0x43,0xef,0xf8,0x24,0xc2,0xf1,0x7a,0x1a,0x70,0x7e,0x2f,0xd4,0xeb,0x97,0x40,0xa6,0xe6,0x2d,0xc1,0xd8,0x3b,0xee,0xa4,0xda,0xd3,0x50,0x41,0x18,0xbf,0xad,0x66,0x02,0x85 +.byte 0x60,0x14,0xcf,0xce,0x50,0x88,0x5e,0xb6,0x73,0x11,0xbb,0x6a,0xca,0xb1,0x46,0x8e,0xbb,0x58,0x2c,0x63,0x61,0x20,0xec,0xc9,0x98,0x0c,0xdb,0x5c,0xe5,0x47,0xb5,0x89,0xe9,0x14,0xc8,0xbc,0x35,0xf2,0xa7,0x2d,0x84,0xcc,0x61,0xc8,0xb6,0x9d,0xeb,0xcb,0x8b,0x73,0x90,0x6d,0x06,0xc9,0x42,0xcf,0xd2,0x15,0x80,0x2d,0x39,0xeb,0x71,0x83 +.byte 0x27,0x0d,0x85,0xf9,0xa3,0xce,0xef,0x29,0x3b,0x10,0xb7,0xe9,0xd0,0x86,0x6e,0x88,0x1e,0x3b,0xdd,0xaf,0x52,0xde,0xa2,0xa4,0x13,0x3c,0x1f,0xcb,0x84,0x74,0x12,0x04,0x91,0x40,0xb8,0x1b,0x15,0xfd,0xdb,0xe8,0x74,0xcc,0x4d,0x41,0xb5,0x5a,0x92,0xd3,0x71,0xf7,0x57,0xa5,0xf7,0x18,0x5a,0x57,0x36,0xde,0x8f,0xb2,0x81,0x59,0xc8,0x5c +.byte 0x22,0xcf,0xdc,0x7d,0xff,0x83,0xf2,0xad,0x8c,0x7b,0xd5,0x04,0xc4,0xb9,0x79,0x4a,0x12,0xa7,0xb1,0x7e,0x57,0xa5,0x6b,0x56,0x8a,0x11,0x96,0x57,0xde,0x35,0xdd,0xef,0x9b,0x03,0x41,0xde,0x61,0x5b,0x73,0x8c,0x6a,0x0c,0x6f,0xae,0x45,0x4b,0x56,0x4d,0xbe,0x8a,0x3f,0xdb,0x79,0x58,0x88,0xad,0xcb,0xfa,0x66,0x06,0x0e,0x74,0x21,0x1d +.byte 0xe1,0x94,0xd7,0x06,0xea,0x60,0xe2,0x7d,0x70,0xcf,0xa9,0x4f,0xe6,0x9b,0xba,0x19,0x71,0x69,0x94,0x66,0x5a,0xb8,0x49,0x0c,0xd1,0x9a,0xc4,0x5f,0xa7,0xf4,0x9e,0x3d,0x9e,0xc2,0xd8,0x0e,0xd2,0x6d,0xc6,0xc8,0x99,0xc3,0x5e,0x3b,0xb9,0xd8,0x48,0xc0,0x38,0x48,0x95,0x89,0xff,0x7e,0x1d,0x80,0x53,0xac,0x7b,0xd7,0xfc,0x6f,0x5d,0x25 +.byte 0x2f,0xcf,0x15,0xdb,0x1a,0x64,0xc1,0x16,0x91,0x65,0x84,0x99,0x0a,0xc1,0xbf,0x4d,0x11,0xa5,0x55,0x55,0x35,0x93,0x6f,0x47,0xf1,0x75,0xb8,0xb6,0x11,0x9d,0x6e,0x3b,0xd1,0x11,0x20,0xa2,0xa2,0x5c,0x33,0x85,0x09,0xb8,0x13,0xc9,0xdd,0xf2,0xd4,0x32,0x37,0xf2,0xef,0x47,0xfa,0x25,0x1a,0xcc,0xdf,0xf4,0xe4,0x2c,0x2c,0x7f,0x23,0xb6 +.byte 0xa8,0xd4,0x6a,0xd4,0xb4,0x06,0x2e,0xb0,0xaa,0xa1,0x18,0x8a,0x5c,0xc6,0xb2,0x4c,0x71,0x92,0x4a,0xdc,0x81,0x20,0x51,0x8d,0x3f,0x71,0x7d,0x8c,0x25,0x79,0x07,0x14,0xa9,0x7a,0x8b,0xda,0x00,0xfc,0x51,0xdb,0xa0,0x50,0x2b,0x15,0x39,0xf6,0xad,0xdc,0x9e,0x22,0x93,0x2f,0x43,0xd8,0x5c,0xa2,0x5e,0xfa,0x70,0x8c,0xe0,0x6b,0x0e,0x93 +.byte 0x6c,0x89,0xfe,0x22,0x4c,0xec,0xb0,0x7e,0xc1,0x06,0x69,0xf7,0x2f,0x3e,0xe5,0xa4,0x45,0x53,0xab,0x9c,0xf5,0x40,0x05,0x53,0x64,0xc6,0xa7,0xf9,0xc4,0xd6,0x89,0xd9,0x47,0x72,0x8e,0x42,0xf9,0x64,0x12,0xeb,0xd9,0x25,0xdc,0x4c,0xc6,0xea,0x9c,0x4b,0x93,0xb4,0xa2,0xa6,0xae,0x95,0xc1,0x84,0x75,0xc9,0x22,0xe3,0x22,0x81,0x31,0xd1 +.byte 0xfd,0x2e,0x91,0x4a,0xc3,0x00,0xa6,0x57,0xbb,0x89,0x9f,0x2d,0xc3,0x2e,0x1f,0xa2,0x47,0xc4,0xa3,0xcd,0x2b,0xc2,0x29,0xaf,0x89,0xce,0x2e,0x87,0x8e,0xd8,0xfc,0xee,0xab,0x8a,0xbd,0x2f,0xee,0xcf,0x94,0xe0,0x74,0x70,0x86,0x00,0x42,0x11,0x8b,0x6c,0x81,0xd4,0x82,0xf2,0x29,0x3e,0x9c,0x68,0x71,0xaa,0x20,0x0a,0x51,0x5d,0x80,0x4c +.byte 0xca,0x04,0x23,0x23,0xe2,0x69,0xb3,0xf5,0x65,0x98,0x19,0xee,0xa9,0x4d,0xd8,0xe0,0x06,0x4b,0x17,0xed,0xfa,0xf2,0xe3,0xd3,0x69,0x48,0xe4,0x4e,0xc0,0x5a,0x16,0x90,0xdb,0xb6,0x32,0x6e,0x6b,0xd7,0x7a,0xb6,0xd4,0x82,0xe4,0xcc,0x31,0x31,0x5c,0x18,0x84,0xef,0x75,0x9f,0xda,0xf6,0x62,0x2d,0x96,0x4d,0xa1,0x3c,0xb5,0x4a,0xbb,0xbf +.byte 0x9d,0xb3,0x33,0x00,0xc1,0x73,0xc5,0xb2,0xeb,0x85,0x74,0xb0,0x68,0xed,0x16,0x66,0x71,0xc9,0x7e,0x6f,0x74,0xa6,0xe7,0xed,0xf0,0xfa,0xab,0x41,0xdd,0x10,0xf9,0xff,0x4c,0xb6,0x4f,0x15,0xe3,0x77,0x31,0x17,0x5c,0x5a,0xef,0xb2,0xa9,0x44,0xbe,0x97,0xa9,0x75,0x5a,0xb7,0xe0,0x16,0x17,0x37,0x1b,0x71,0x03,0xb9,0xaa,0x7b,0x7b,0x52 +.byte 0x46,0x58,0x6b,0x9b,0x87,0x27,0xa6,0x8a,0x0e,0x84,0x03,0x45,0x95,0x04,0xf1,0x7e,0xb6,0xf6,0x79,0xd5,0x66,0x6d,0x50,0x8c,0x5a,0x67,0xe0,0xdd,0x69,0xd8,0x92,0x75,0x15,0xcb,0xa5,0x05,0xfe,0x7a,0xc1,0xd6,0x11,0x57,0x10,0xa3,0xc3,0xb6,0xe9,0xe3,0x97,0xa5,0x46,0xc9,0xe9,0x9b,0x68,0xb6,0x55,0x0b,0xf2,0x17,0x9d,0x0e,0x7f,0xd9 +.byte 0x26,0x0c,0x01,0xff,0x95,0xe1,0x05,0xb7,0xbf,0x0d,0x77,0x12,0x96,0x03,0x71,0x01,0xc9,0x98,0xb4,0x44,0x94,0xc0,0xad,0x3d,0xfc,0x6f,0xe5,0x0c,0xa4,0x65,0xd7,0xe7,0x76,0x7c,0xb8,0xa0,0x0a,0xcd,0xe8,0x01,0x26,0x8e,0x94,0xec,0x94,0x65,0x86,0xee,0x4d,0x3b,0xc5,0xb5,0x2e,0x51,0xb7,0xa9,0x68,0xcd,0x14,0x90,0xd8,0x36,0xfb,0x52 +.byte 0x04,0x52,0xb4,0xca,0x9b,0xbf,0xc6,0x94,0x28,0xc5,0x7e,0x27,0x73,0xae,0x6d,0xba,0xe7,0x56,0xce,0x2e,0x00,0xeb,0x36,0x19,0xd7,0x4f,0x20,0x5e,0xfd,0x0f,0xd4,0x4c,0x02,0xaf,0xdb,0x74,0xef,0xf0,0x73,0x1e,0x2a,0x1a,0xe7,0x3a,0xe0,0xa5,0x89,0xcf,0x1a,0x66,0xbd,0x72,0x65,0xb4,0xf4,0x86,0x33,0x44,0xee,0x35,0xf6,0x09,0xbe,0x13 +.byte 0x96,0x84,0x04,0x95,0x3f,0x35,0xbb,0x01,0x2c,0x78,0x25,0xe8,0x1e,0x46,0xdb,0xd9,0xb1,0xe8,0xfb,0x2b,0xa8,0x59,0x72,0x5f,0x91,0xd3,0x7c,0x21,0x95,0xa9,0x50,0xa2,0x45,0x6f,0x48,0x0c,0xf2,0x51,0x10,0x3c,0xcd,0xea,0xeb,0x5d,0xc7,0xf9,0x0e,0xae,0x1a,0x02,0x05,0x15,0x12,0x10,0xc0,0x35,0x12,0x97,0xcd,0x5b,0x61,0x4f,0xd1,0xd3 +.byte 0x5b,0xec,0x2b,0xa0,0x20,0x03,0x2b,0xf3,0xe6,0x71,0x23,0xca,0x1d,0x48,0x64,0x3f,0x7e,0x52,0x8b,0xf9,0x96,0x33,0x31,0xbc,0xbd,0x73,0x2f,0xa6,0x80,0xb8,0x0b,0x3a,0xd7,0xf8,0x05,0xf0,0x06,0xc7,0xa5,0xce,0x6a,0x6a,0x62,0xae,0x06,0x93,0xa4,0x5f,0x0b,0x5d,0x4d,0xb8,0xa4,0xfa,0x2e,0xfc,0xb6,0x58,0x8c,0x2a,0x46,0xa4,0x55,0x1f +.byte 0x9b,0x9b,0x13,0xdd,0x17,0x2a,0x3d,0x04,0x51,0xb6,0xbe,0x9c,0xca,0xf3,0x23,0xb6,0x7b,0x7a,0x92,0xb7,0x2f,0xf9,0x69,0x9a,0xee,0xb3,0xa1,0x60,0x56,0xcf,0x9d,0xab,0xfe,0x86,0x7a,0x41,0x94,0x15,0xbe,0xa3,0xa5,0x85,0x09,0xfb,0x7b,0x89,0xbd,0xc3,0x09,0x10,0xa6,0xfc,0x41,0x8e,0x57,0x27,0xdc,0x58,0xf4,0x01,0x7c,0x31,0x5e,0xca +.byte 0xaf,0x31,0x2f,0x98,0x8b,0xbe,0x19,0x16,0xa1,0x81,0x7e,0xb3,0xa9,0xc5,0x15,0xd2,0xad,0x51,0xa1,0x73,0x56,0xd3,0x6a,0x15,0x35,0xe3,0xb1,0xdb,0x83,0x4c,0xe2,0x85,0x8c,0x03,0x12,0xc4,0x64,0x69,0xc0,0x23,0x16,0x7b,0x68,0x46,0x44,0x22,0x84,0xa6,0xb5,0xe4,0x90,0x91,0xc1,0xdd,0x25,0x7c,0x54,0x0e,0xce,0x5b,0x11,0xe4,0x50,0x1c +.byte 0x3c,0x0d,0xc7,0xc1,0x0c,0x10,0x2d,0x8b,0xb7,0xde,0xe2,0x4f,0x7e,0x22,0x53,0xfc,0x07,0x55,0x19,0x14,0x3b,0x33,0xf5,0xf3,0xd8,0x7b,0x5e,0x40,0xa2,0x81,0x6d,0x40,0x0d,0x20,0x36,0x4b,0xa1,0x34,0x34,0xac,0x43,0x59,0xb5,0xb1,0x90,0x8b,0x48,0xcf,0x15,0x57,0x17,0x0e,0xd0,0xbf,0x28,0xcd,0xa4,0x77,0x4d,0xae,0x09,0x4c,0x67,0x51 +.byte 0x18,0xaa,0xb4,0xc9,0x35,0x41,0x0b,0x34,0x4d,0xb3,0xef,0x3f,0x46,0x97,0x6e,0xae,0x75,0xd7,0x6a,0x2b,0x22,0x9c,0xef,0x8e,0xaf,0x72,0xb0,0x14,0x90,0xbd,0x11,0x90,0xde,0x9a,0x02,0x8c,0x20,0xf5,0xc7,0x33,0x4d,0x94,0x88,0x9a,0x6c,0x18,0xb4,0xc0,0xa9,0x94,0x07,0x9a,0x4b,0x10,0x8f,0xe8,0x25,0xcd,0x9b,0xf5,0xfa,0x91,0x8a,0xc0 +.byte 0x93,0x61,0x1c,0x00,0xd1,0x34,0x9a,0x29,0xa3,0x35,0x38,0xe4,0xa7,0x9f,0xb6,0x88,0x0f,0xad,0x88,0x96,0xa0,0x73,0xe7,0x10,0xea,0x36,0xe8,0x88,0x6c,0x7f,0x03,0xbc,0xfe,0xe0,0xb2,0x4b,0x24,0x98,0xf6,0x73,0x6f,0xab,0x00,0x1e,0x26,0x83,0x0d,0x86,0x5b,0xa6,0x51,0x8f,0x5f,0xa9,0x8f,0xf4,0xa0,0x51,0xff,0xe0,0x64,0x09,0x95,0xfb +.byte 0x56,0x53,0x18,0x61,0xea,0xc5,0x33,0xe8,0x6f,0x8a,0x07,0x97,0x1a,0x6c,0xb5,0xf8,0x73,0xae,0xe4,0x4e,0x6d,0xb2,0x83,0x20,0xfa,0xfd,0x79,0xa6,0x6c,0xaa,0x9b,0x7b,0x2c,0xfe,0x63,0x73,0xbc,0x87,0xd4,0x56,0xd1,0xb1,0xf1,0x0f,0x72,0x2c,0x2f,0xf0,0xf0,0x53,0xe2,0x6c,0x19,0x0d,0x9c,0xad,0xc8,0x0a,0x62,0x72,0xcb,0xc3,0x12,0x90 +.byte 0x4c,0x26,0xe3,0xa0,0x07,0x35,0xee,0xaf,0x81,0x35,0x07,0xa9,0x31,0xa0,0x59,0xc8,0x40,0xa5,0x45,0xb6,0x6d,0x3e,0xa2,0x5f,0x6a,0x79,0x74,0x65,0xa1,0xe3,0x1c,0xca,0xae,0xcc,0xa6,0xb6,0x0a,0x12,0x99,0x8e,0xc3,0xef,0x43,0xcf,0x42,0x92,0xa4,0x12,0xa3,0x8b,0x97,0x7d,0x6f,0xe0,0x35,0xed,0xac,0x69,0xae,0x8c,0xe1,0x32,0x11,0xa4 +.byte 0xe0,0x76,0x7f,0x75,0x92,0xda,0xfe,0x94,0x33,0xeb,0xe1,0xa4,0x3c,0x95,0x7c,0xc6,0xbc,0x3d,0xf2,0x39,0xa1,0x29,0x39,0x24,0x09,0xd4,0x52,0x68,0xfb,0x80,0xd0,0xd4,0x57,0xc6,0x4c,0xa5,0xa6,0x90,0xa6,0x61,0x15,0x2f,0xd3,0x35,0x36,0xf5,0x16,0xb3,0x65,0x0a,0xc4,0xcb,0x7f,0x73,0xe4,0xba,0x9a,0xd8,0x8b,0xc3,0x01,0xa0,0x08,0x57 +.byte 0x9e,0x26,0x54,0xbc,0x55,0xd1,0x5f,0xaa,0xb5,0x0d,0x42,0x75,0x04,0x76,0x8c,0xef,0xcf,0x64,0x3a,0x2e,0x4c,0x78,0xe5,0x37,0x8d,0x55,0xec,0xc1,0x7b,0xce,0x5f,0x5f,0x43,0x8b,0xdd,0x46,0x43,0xf5,0xa8,0x41,0xa6,0x82,0x1b,0x12,0xcb,0xcb,0x6d,0xa1,0x6c,0xb6,0x79,0x46,0x12,0x89,0x12,0x61,0xd6,0x4f,0xf9,0x43,0x2d,0x27,0xa9,0x61 +.byte 0x2e,0x2a,0x29,0x1b,0x6d,0xad,0x32,0x0b,0x6c,0x7c,0xf4,0xb8,0x98,0x91,0xbb,0x78,0xda,0x85,0xe8,0xfb,0x4e,0x11,0xc4,0x2a,0x07,0x54,0xa0,0x67,0x73,0x1b,0xa4,0x60,0x15,0x5c,0x83,0xbf,0x3f,0xd9,0x61,0x30,0x02,0xbb,0xa6,0x67,0xcd,0x0c,0xd1,0xb4,0x11,0x7e,0xca,0xf4,0x1e,0xed,0x83,0x34,0x66,0x54,0x23,0x39,0x36,0x8c,0xa0,0xc6 +.byte 0xef,0xad,0xa1,0x95,0x04,0x20,0x46,0x42,0xa8,0x99,0xd2,0x98,0xc6,0x0a,0x92,0x11,0xd1,0x84,0x4a,0xbf,0x25,0xe5,0xcf,0x78,0x98,0x81,0x80,0xaa,0x31,0x0a,0xa4,0xfb,0xef,0x35,0xfa,0xa4,0xac,0x5f,0x01,0x6b,0xb7,0x8e,0x86,0xc1,0x46,0x97,0x88,0xe2,0xaa,0x3b,0x1f,0xb5,0xf8,0xa9,0x90,0xf0,0x45,0x6d,0xdd,0xa3,0xdd,0xd8,0xef,0x36 +.byte 0x6f,0x87,0x55,0xf6,0x96,0xcd,0x88,0x43,0x03,0x97,0x82,0xea,0x5a,0x1c,0xa1,0x1a,0x7b,0x1b,0xa7,0xfc,0xaa,0x86,0xb4,0x71,0xde,0x0d,0x0a,0x52,0x98,0xd2,0x65,0x5d,0xa4,0xea,0x91,0xc9,0xe4,0x8b,0xd0,0xdb,0x85,0xe3,0x86,0x85,0x50,0xe1,0x41,0x1f,0x48,0x97,0x64,0xec,0x34,0xe4,0x54,0x42,0xf4,0x01,0xed,0x6f,0x4d,0xe3,0x1f,0x86 +.byte 0x14,0xbc,0x01,0x9c,0x7f,0x02,0x0c,0x65,0x94,0xd2,0x90,0x2c,0x1b,0xab,0x41,0x88,0xad,0x58,0xb5,0x71,0xd3,0xd6,0xe1,0x3f,0xf3,0x3c,0xb6,0xab,0x22,0x08,0x17,0xc7,0xf5,0x7e,0x34,0x56,0xae,0x1d,0x1e,0x7e,0xdb,0x24,0xe2,0xc2,0x38,0xf3,0x4d,0x46,0xe4,0x45,0xcb,0xb7,0x2f,0x0f,0x96,0x72,0x7e,0x31,0x89,0x17,0x9c,0xed,0x85,0xb9 +.byte 0xc8,0x8f,0x65,0x93,0xfb,0xb8,0x9e,0x41,0xa2,0xc1,0xcf,0xdb,0xe2,0x4c,0x26,0x4a,0xc7,0x2a,0x72,0xf6,0x28,0xbc,0x18,0x22,0xde,0xa1,0xfa,0x46,0xbe,0x95,0xc8,0xe2,0x19,0xbb,0x20,0x7b,0xd5,0xf8,0x34,0x15,0xaa,0xec,0xe2,0x9e,0xa9,0x3d,0xa1,0xd9,0xaa,0xc9,0x18,0x39,0x07,0x5c,0x81,0x61,0xe7,0x00,0xc5,0x57,0x3e,0xca,0x4d,0x89 +.byte 0x33,0x02,0xa6,0xc8,0x15,0xb7,0x24,0xdd,0x5c,0x55,0x56,0x11,0x5c,0x17,0x1b,0xda,0xc6,0xd5,0x46,0x6e,0x9f,0x70,0xe7,0x1e,0x41,0xee,0x91,0x1a,0xa0,0xad,0x35,0x64,0xdf,0x4a,0x18,0x03,0xa7,0xa8,0x88,0x8f,0x65,0xbc,0x76,0x34,0x08,0xab,0x50,0xc6,0xd3,0x08,0x7c,0xc1,0x4f,0x77,0xcd,0x1a,0xc6,0xed,0x35,0xea,0x4e,0x8a,0x6a,0x38 +.byte 0xa3,0xa3,0xd8,0xa9,0xa2,0x68,0xa7,0xd8,0xe0,0xc8,0x3f,0xfe,0xe7,0x73,0xc6,0x6b,0xd8,0x0c,0xd5,0x8f,0x81,0xe7,0x37,0x08,0x93,0x28,0x73,0xef,0xc4,0x91,0x52,0xa5,0x30,0xff,0x47,0x95,0x02,0x0d,0x8c,0xfd,0xc9,0x28,0x60,0xa9,0xad,0x30,0x00,0xcc,0x3a,0x00,0xbb,0x25,0xab,0xd0,0xf8,0x25,0x46,0x20,0xc0,0x67,0x9b,0xd6,0x10,0xa6 +.byte 0x84,0x6f,0x66,0x60,0x66,0x75,0xb6,0xfb,0x39,0x3a,0x9f,0x7d,0x32,0x7f,0x12,0x6f,0x8c,0xed,0x79,0x40,0x47,0xa3,0x27,0x17,0xa8,0xa4,0x02,0x93,0xb9,0x32,0x03,0x34,0x06,0x76,0x71,0x40,0x90,0x2b,0xe7,0xd0,0x3f,0x59,0xa7,0xfb,0x3a,0x7b,0xc8,0xa5,0x86,0x21,0x0d,0xf6,0xc6,0x49,0x07,0x56,0xe9,0xfc,0xac,0x61,0x30,0xa5,0x7e,0x90 +.byte 0x10,0xc8,0xdb,0x15,0x2b,0x75,0x27,0x77,0x51,0x42,0xcf,0x50,0xe8,0x6c,0x0b,0xb7,0x17,0x1a,0x89,0x7d,0xfe,0xd2,0x75,0xfa,0xb7,0xe5,0x68,0x10,0x1c,0x27,0x85,0x8b,0x52,0x7d,0x87,0x57,0x50,0x77,0x25,0x9d,0xcc,0x08,0x6a,0xad,0x63,0xf8,0x8e,0xe0,0x21,0x62,0x56,0x48,0x29,0xed,0x81,0x1d,0x6b,0x60,0x55,0x78,0x6a,0xce,0xd6,0x79 +.byte 0xe1,0x66,0x18,0x9f,0x71,0xf7,0x0c,0xec,0x35,0x53,0xef,0x39,0xfe,0x57,0x71,0xc0,0x49,0x4b,0x55,0xe8,0x3d,0x9b,0xe3,0x9a,0xbb,0xf8,0x61,0x31,0xa1,0x94,0x94,0x8a,0xb1,0xd2,0x0f,0x01,0xe0,0xd4,0x26,0xa0,0x59,0x70,0xd0,0x5e,0xb8,0x6f,0x63,0x7b,0x71,0x49,0xe1,0x98,0xfb,0xdb,0x22,0x26,0x18,0x16,0x31,0x08,0x90,0x32,0xd5,0x7a +.byte 0xc0,0xd8,0xeb,0xae,0x93,0x3d,0x46,0xeb,0x0e,0xdd,0x08,0xa2,0xde,0x4e,0xc1,0x88,0x26,0xc2,0xf8,0xc6,0x5e,0x8a,0x9b,0x0d,0x9f,0x2b,0xcf,0x4e,0x13,0x43,0x4a,0x65,0xf6,0x47,0x1a,0x0a,0xae,0xf9,0x9f,0x7c,0xc5,0x18,0x65,0x09,0xcb,0x85,0x7d,0x33,0x36,0x43,0x19,0x99,0x20,0xa2,0x64,0xb2,0xf5,0x20,0xd2,0x74,0xc6,0x2c,0x29,0x46 +.byte 0xde,0xa7,0x4a,0x7f,0x3b,0x05,0x3e,0x11,0xb6,0xc1,0x98,0xfb,0xf5,0x9d,0x93,0x95,0x76,0x11,0x80,0x41,0x44,0xd3,0x2f,0xf4,0xfd,0x92,0x1e,0xd7,0xa7,0x5f,0x02,0x4a,0xbc,0xb7,0x96,0x33,0xc0,0x0d,0x2d,0x97,0xb8,0xd4,0x67,0x7a,0x4c,0x74,0x93,0xa7,0x8d,0x68,0x78,0xed,0xc8,0xc9,0x02,0x6e,0xae,0x10,0x97,0x7c,0x56,0x11,0x2a,0x29 +.byte 0x87,0x5c,0x21,0xec,0x75,0x9c,0x17,0x17,0x8d,0x45,0x08,0x31,0x36,0x64,0xc0,0xf7,0x95,0xb6,0x72,0xcf,0xac,0xd8,0x52,0x02,0x6f,0x3b,0x14,0x34,0x30,0xcc,0x39,0x7c,0xe4,0x1f,0x38,0x23,0xcf,0x1f,0xb7,0x7e,0x92,0x66,0xf7,0xda,0x9f,0x27,0xbb,0x83,0x45,0x71,0x67,0x63,0x6c,0x85,0x64,0x34,0xa8,0x93,0x5a,0x13,0x0c,0xff,0x8b,0x3a +.byte 0x2a,0x10,0x1d,0xb6,0x43,0xef,0x57,0xf3,0xf0,0x29,0x2e,0x59,0x72,0x2e,0xc3,0xb6,0xd3,0xd0,0xdd,0x17,0x19,0x82,0x49,0x05,0xd4,0xfc,0xd6,0x2e,0x5d,0xd7,0x0c,0xb6,0x18,0xd5,0x08,0xbb,0xe5,0x3b,0x2e,0x85,0x62,0xc0,0x1e,0xa3,0xb8,0x92,0x21,0x06,0xfa,0xf1,0x2d,0xab,0x62,0x67,0x62,0xee,0x13,0x7f,0x07,0xb6,0x24,0x64,0x94,0x4f +.byte 0x69,0xb9,0x7a,0xdc,0x23,0x5e,0x19,0x96,0xc5,0x4d,0xcb,0xee,0x2d,0x4a,0x7d,0x1d,0xd2,0x72,0x18,0x8f,0x43,0x8f,0x76,0xbf,0x30,0xd8,0xf1,0xfe,0x9c,0xe7,0x63,0x38,0xff,0x1a,0x3f,0x40,0xbd,0x73,0x66,0xf7,0xa9,0xd9,0x17,0x4a,0x8a,0x79,0x04,0x0e,0x20,0xe1,0x39,0x49,0xd9,0x30,0x9c,0x52,0xf9,0x14,0x8f,0xdc,0x9d,0x52,0xd5,0x34 +.byte 0xaa,0x58,0xfe,0x5d,0x68,0xcb,0xab,0x3b,0x3c,0x9e,0x25,0xde,0x6d,0xdd,0x58,0x0d,0x1b,0x99,0xa9,0xcc,0x26,0x4e,0xc0,0x3c,0x8b,0x1e,0xaa,0x52,0x3d,0x4d,0xb8,0x27,0xc1,0xd1,0xa2,0xaa,0x78,0xb9,0xee,0x5f,0x26,0x46,0x5f,0x41,0x0d,0xe1,0x70,0x7d,0xcd,0x3f,0x4a,0xca,0xb2,0xca,0x2f,0x36,0x1f,0x68,0xe6,0x66,0x8a,0xf6,0xe3,0x94 +.byte 0xe5,0xab,0x90,0xeb,0x2f,0xe8,0xb2,0x6c,0xa9,0x69,0xd2,0xe0,0x5f,0x4a,0x65,0xa8,0x6b,0xc1,0xfb,0x03,0x51,0x17,0x3b,0xf8,0xe0,0x67,0xc3,0x5a,0xe8,0x18,0xdf,0xc1,0xf8,0x7f,0x44,0x68,0x4a,0x01,0xbe,0xf8,0xa5,0x7a,0xb9,0x3b,0x0f,0x05,0x8e,0x4b,0x28,0x14,0x61,0x2f,0x2e,0xc7,0xf2,0x96,0xc7,0x60,0x99,0xc4,0xbf,0xe8,0x37,0x98 +.byte 0x00,0x34,0xf7,0x5a,0xd7,0x6f,0x90,0xc4,0x19,0xb5,0x07,0xd1,0x76,0x6e,0x65,0xcc,0xf6,0x51,0x88,0x5c,0x81,0x91,0xa8,0x4d,0xb7,0x33,0x53,0xb6,0x93,0x42,0x52,0x82,0xfa,0x2b,0xca,0xa0,0xbd,0xf3,0x09,0x2b,0x0f,0x09,0x02,0xdd,0x29,0x5f,0xa6,0x49,0x7b,0x97,0xe8,0x96,0xbf,0x6f,0x76,0xb7,0xa2,0x76,0x58,0xda,0x1d,0xb2,0xdb,0x6d +.byte 0x9d,0x3b,0x32,0x6e,0x9c,0xea,0x45,0xfd,0x33,0xeb,0x41,0x91,0x91,0x52,0x2b,0x68,0xa3,0xf3,0xc6,0x92,0x43,0x13,0x49,0x8a,0x10,0xb1,0x2f,0x9a,0x0f,0xe1,0x94,0x21,0x18,0x76,0x87,0xaf,0x50,0xe4,0x71,0x5d,0x0a,0xba,0x75,0xaa,0x17,0xf5,0x37,0xf2,0x84,0x9b,0x29,0xdf,0x44,0x60,0xd0,0xac,0xcf,0x25,0x87,0x66,0x64,0x1f,0x0d,0xba +.byte 0xb3,0xdb,0x14,0xb6,0x1f,0x00,0x70,0x98,0x83,0x1d,0x9e,0xbd,0xf9,0x17,0xf4,0x57,0xae,0xa8,0xae,0x7b,0xa7,0xde,0x1f,0x31,0xc6,0x29,0xb2,0xf7,0xef,0x36,0x31,0xe7,0x50,0x33,0x69,0x4e,0x8c,0xb5,0xe4,0xdd,0x74,0x87,0xc8,0xf5,0x22,0x1b,0x4b,0xec,0xc4,0xe1,0x5a,0x7d,0x5a,0xe8,0xb9,0x2f,0xf4,0xd1,0x83,0xa2,0xb7,0x97,0xe0,0x1e +.byte 0xf7,0x3a,0x74,0xef,0x5f,0xb3,0x30,0xce,0xfa,0x23,0xd5,0x98,0x56,0x19,0x24,0xb5,0xc7,0x60,0x8b,0x03,0x8e,0xe7,0xdf,0x2c,0x36,0x4c,0x3b,0x3b,0x84,0x45,0x97,0x40,0x29,0x30,0x98,0xc3,0xc0,0xa2,0xf0,0xdf,0x69,0x47,0x95,0x26,0xdb,0x6c,0xcc,0xff,0x2d,0x32,0xaa,0xa7,0xb8,0x6b,0x24,0xec,0xff,0x94,0x4d,0x36,0xdd,0x7b,0x4d,0xc5 +.byte 0x8d,0xe2,0x3c,0x14,0x5a,0x37,0x75,0x1f,0xd6,0x98,0x7d,0xd3,0xdc,0xb0,0x24,0x69,0xe7,0x65,0x60,0x2a,0xe7,0x00,0x5b,0x68,0x99,0xa0,0x9e,0x10,0xf0,0x5c,0xa8,0x39,0x85,0x59,0xde,0xe4,0x46,0xf3,0xde,0xda,0xc0,0xb1,0xd2,0xf1,0xd2,0x05,0xd5,0xd4,0x2c,0x2e,0x7e,0x44,0x5c,0x52,0x80,0x85,0xbb,0x54,0x97,0xb6,0xad,0x6d,0x57,0x49 +.byte 0xed,0x67,0xaf,0x27,0xb4,0x5b,0xce,0x0f,0x3c,0x58,0xa2,0x24,0x22,0xa2,0xcb,0xfc,0x4e,0x8e,0xc2,0x3c,0x32,0xc6,0x07,0xc4,0xc6,0xc0,0x50,0xc3,0xe3,0x1b,0x96,0x76,0x62,0xf9,0xea,0x5e,0xdc,0xc5,0x96,0xe8,0xaa,0x20,0x26,0xac,0x44,0xfb,0xf2,0x16,0x72,0x72,0x4c,0x5c,0xee,0x51,0x07,0xb0,0x74,0xf6,0xde,0xd7,0x5d,0x73,0xf4,0xe9 +.byte 0x0d,0x29,0x06,0x5f,0xca,0xe2,0xbb,0xa4,0x3e,0xdc,0xf7,0x74,0x99,0x53,0x7a,0x52,0x60,0x46,0xaa,0xf0,0x34,0x97,0x0c,0x81,0x5b,0xd8,0x95,0x52,0x76,0x55,0xcb,0xc4,0x6d,0x50,0x26,0x3f,0x7e,0xc2,0x93,0x6e,0x14,0x0c,0xd7,0x49,0x5f,0x52,0x8f,0x34,0x49,0xb4,0xe7,0x12,0xfe,0xae,0xd1,0xfa,0xfc,0xc5,0x80,0x38,0x26,0x9c,0xf1,0x81 +.byte 0x01,0x58,0x15,0x99,0x29,0x8d,0x1b,0x2d,0x74,0xca,0xf1,0xf4,0xfa,0xcd,0xae,0xfa,0xa9,0x1d,0xbb,0xf1,0x55,0x2e,0x69,0x46,0x6e,0xe4,0x91,0xa3,0x48,0xb5,0xaa,0xb3,0x85,0xab,0x14,0xd2,0x84,0x8c,0xb1,0xb6,0x0c,0xa5,0x4a,0x90,0xed,0x6e,0xdf,0x1e,0x15,0x36,0x7b,0xa3,0x59,0xd6,0x8d,0x7d,0x7b,0x12,0x7c,0x9a,0x40,0x8a,0x28,0xde +.byte 0xb5,0xbc,0xc4,0x52,0x96,0xfb,0x62,0x1f,0xc9,0xe0,0xc9,0x1d,0xc7,0xc4,0xcb,0x8a,0x96,0x21,0x42,0x7c,0x0a,0xdd,0x42,0x74,0xcf,0xc4,0x57,0x8f,0x28,0x0a,0x7c,0x4f,0x49,0x5a,0xc6,0x21,0xb2,0xd4,0xd0,0x61,0xa5,0x35,0xbd,0x4a,0x0c,0x16,0x68,0x1f,0xe3,0xff,0x3f,0x72,0xf0,0x1d,0x50,0x26,0x48,0x91,0x27,0x1b,0x2b,0x0d,0x8b,0xf2 +.byte 0xa0,0xc0,0xa0,0x5d,0xdb,0xcf,0x71,0x41,0x83,0x00,0xb9,0x3c,0xe0,0x4a,0x96,0x43,0xf8,0x64,0x0f,0x42,0xc5,0x75,0xec,0x26,0x62,0x99,0x13,0xeb,0xf9,0xa6,0x86,0xe4,0xc9,0xaf,0x3c,0x2c,0xc9,0x4f,0x89,0xf4,0xc0,0x46,0x99,0xb8,0xd1,0x9e,0x7b,0xb7,0x41,0x0a,0x5f,0x40,0x98,0x65,0x29,0xdd,0x60,0x6b,0x27,0xbf,0x66,0x08,0x32,0xc2 +.byte 0xcf,0xea,0x91,0x44,0x45,0x49,0x1c,0xb4,0x16,0x7f,0x11,0x1a,0x8c,0xb4,0x59,0x54,0xc6,0xcf,0x40,0xd2,0xe9,0xc1,0x54,0x9c,0xe2,0x6e,0xd5,0xfe,0xfb,0x4a,0xa3,0x98,0x63,0xef,0x86,0xe0,0x63,0x30,0x32,0x5a,0xbd,0xd4,0x7c,0xe8,0xbe,0xf1,0xed,0xa2,0x19,0x98,0xc8,0x34,0x65,0x4c,0xef,0x1a,0xb3,0xbc,0x87,0xbe,0x6b,0x75,0x2c,0xe5 +.byte 0x54,0xcc,0xe5,0x69,0xb2,0xc8,0xdb,0x57,0xf8,0xa7,0x82,0x07,0xf7,0x20,0x95,0x7f,0x6d,0x7b,0x33,0x66,0x67,0xa1,0x38,0x0e,0x9c,0x3b,0x22,0xab,0xc1,0xd3,0xed,0x87,0x32,0xfb,0x4a,0x5d,0xad,0x3a,0xe1,0x90,0xa6,0xe3,0x4d,0x6b,0x00,0xe4,0x5c,0x66,0x59,0x90,0x63,0x24,0x5b,0xe1,0x3b,0x69,0xb6,0xc9,0x05,0x83,0x3a,0x7b,0xf4,0xa5 +.byte 0xc8,0x47,0xf9,0x8e,0xab,0x92,0xbd,0xd3,0x41,0xc7,0x61,0xf4,0xce,0x30,0xdb,0xae,0x27,0x69,0x0f,0xcc,0x69,0x50,0xe8,0x18,0xf2,0x39,0x04,0x5a,0x29,0x12,0x61,0x46,0x5c,0x1b,0x2e,0x15,0x9c,0xfa,0x73,0x50,0xe3,0x51,0xda,0x4d,0x88,0x25,0xb2,0xff,0x55,0x27,0xce,0x86,0xca,0xe6,0x2a,0xb8,0x0c,0xa7,0xd0,0x06,0xbf,0x70,0xb5,0x6b +.byte 0x80,0x44,0x65,0x5d,0x23,0xfa,0x0d,0x74,0x5c,0xfc,0xc7,0x86,0x5e,0x23,0x8a,0xf1,0xff,0x80,0xf0,0x19,0xaa,0x98,0xae,0x56,0xcf,0x12,0x74,0x6c,0x70,0xb2,0x39,0xbe,0x66,0x71,0xee,0xe3,0x43,0x3b,0xfa,0x79,0xa9,0x7e,0x69,0x6a,0x19,0x42,0xd5,0x0e,0x1e,0x92,0xfe,0x8a,0x0f,0xca,0x74,0xf2,0x68,0x71,0xf5,0xcb,0x05,0x94,0xc1,0x06 +.byte 0x1b,0xae,0x55,0xe9,0x16,0x03,0xa9,0x97,0xad,0x49,0xaf,0x88,0x8c,0x26,0x33,0x4d,0x46,0x75,0xb3,0x9c,0xee,0x70,0xe1,0x57,0x43,0xeb,0x59,0xff,0x77,0x89,0x8a,0x77,0x3f,0x7e,0xe6,0xbe,0xa2,0x05,0xb1,0xe3,0x41,0x5e,0xc7,0xd4,0x14,0xda,0xc0,0x84,0xd0,0x05,0x50,0xdd,0x62,0xdb,0x4c,0x3b,0x16,0xb0,0xe0,0xf5,0x2b,0xf1,0x83,0xea +.byte 0x7b,0x89,0xbb,0xde,0x57,0xdb,0xc0,0xb9,0x7d,0xdf,0x53,0x0f,0x6c,0xc5,0x5a,0x0b,0x36,0xeb,0xa3,0xc3,0xe6,0xc5,0x80,0x98,0xf3,0x87,0x29,0x97,0xc9,0x2e,0xd6,0x3b,0x43,0x2a,0x36,0x3b,0xba,0x43,0x85,0xf5,0x0d,0x18,0x2e,0x78,0x43,0xae,0xa4,0x24,0x6d,0xdc,0xab,0x05,0x94,0x09,0x94,0x27,0x17,0xef,0xbc,0x7e,0x52,0xa4,0x80,0xda +.byte 0x28,0xf5,0xc3,0x20,0x99,0xbb,0x5d,0xb6,0x7e,0x0e,0x59,0x3b,0x5e,0x1d,0x1b,0x4f,0xd1,0x91,0xe4,0xe4,0xc7,0x35,0xc7,0x2e,0xc1,0xba,0x60,0x05,0xa4,0xd5,0xca,0x5f,0x09,0xbf,0x79,0x06,0xcb,0xa7,0x32,0x7c,0xf4,0xdc,0xa8,0xb3,0x8b,0x26,0x59,0x6d,0xcb,0x74,0x37,0x56,0x51,0x96,0x0b,0x44,0xf1,0x95,0x16,0xe3,0x9b,0x9b,0x3b,0xb3 +.byte 0xea,0x6a,0x1b,0x76,0x99,0x69,0xd6,0x5b,0x10,0x5a,0x91,0x23,0xb5,0xc3,0xf9,0x6a,0xba,0xc4,0xe6,0x18,0x28,0x50,0x9d,0x09,0x14,0xbe,0xed,0x73,0xd2,0x51,0xff,0xf8,0x14,0x2b,0x8b,0xdd,0x2a,0x1a,0x8e,0x48,0xae,0xd8,0xdf,0xb9,0x5b,0xcb,0x8f,0xc2,0x8c,0xd6,0xb3,0xfb,0x40,0x2f,0xb0,0x6c,0x9a,0xea,0xd0,0x14,0x8c,0xc5,0xc7,0xc7 +.byte 0xf8,0xf5,0x4f,0xe2,0xd7,0x41,0xcd,0xb6,0x34,0x3e,0x81,0x19,0x09,0xa2,0x51,0xb4,0x60,0xfb,0xf2,0x6c,0xe6,0xae,0x68,0x47,0xb9,0x93,0x7b,0xc9,0xe7,0x00,0xc4,0xa7,0xf2,0xef,0x8b,0xd8,0xfc,0x9f,0xe5,0x6d,0x48,0xe2,0x6c,0x32,0x73,0x5c,0x30,0x7c,0x12,0x13,0xca,0xc3,0x31,0xc3,0xa2,0xb4,0xf7,0x23,0xc4,0xd0,0x47,0x39,0x93,0xc8 +.byte 0xa0,0x7b,0xb4,0x09,0x3f,0xe8,0x15,0x15,0x9c,0xa7,0xe6,0xa8,0xbe,0xba,0x60,0xf9,0x28,0x88,0x66,0x7b,0x62,0x32,0x17,0x18,0x68,0x87,0x53,0xf5,0xbc,0xf5,0x77,0x17,0xa1,0x3f,0x62,0xd1,0x10,0x0a,0x54,0x96,0x9c,0x31,0xc3,0xb7,0x1d,0xaf,0xc7,0xb3,0x27,0x9e,0x46,0xfe,0x7e,0x9b,0x88,0xf2,0x9e,0x6e,0x19,0x0f,0xb1,0x88,0xe4,0x08 +.byte 0x76,0x7c,0x77,0x46,0x09,0xa7,0x9e,0xf4,0xd9,0xbf,0x67,0xe8,0x9d,0x6a,0x75,0xa7,0xf5,0xee,0x29,0xba,0x84,0xa0,0x44,0x46,0x35,0x4c,0x22,0xef,0xb3,0xea,0xb0,0xf2,0xd6,0x78,0x20,0x97,0x28,0x5c,0x7e,0x90,0x06,0x80,0x19,0x63,0xa4,0x8a,0xef,0x0a,0xea,0x88,0xa9,0xa2,0xae,0x23,0x2e,0x40,0xce,0xc5,0xc2,0xbf,0xfe,0x5a,0x8f,0x14 +.byte 0xb8,0x66,0x1a,0x2d,0xdb,0x43,0x39,0xbd,0xe7,0x7b,0xbc,0x41,0x58,0x74,0x56,0xd1,0xe7,0xd0,0xba,0x24,0xd2,0x41,0xbf,0xd0,0x4e,0x97,0x38,0x8f,0x6b,0x6f,0xe2,0x7d,0x6d,0x32,0x94,0x43,0xa7,0x66,0xf7,0x90,0x21,0xe0,0xdd,0x19,0x48,0x72,0xc1,0xa5,0xbc,0x9c,0xe2,0xdd,0x2c,0x6e,0x50,0x45,0x2c,0xa0,0x95,0xcb,0x1d,0x2c,0x1d,0xa6 +.byte 0xbe,0x9c,0xd4,0x6c,0x07,0x2e,0x5e,0xc8,0xc1,0x05,0x61,0x7d,0x44,0x28,0xe6,0xad,0xf0,0x9d,0x2d,0x3d,0xce,0x90,0x7d,0x79,0x2e,0xf3,0x08,0xbe,0x7a,0xa9,0x58,0x04,0xa7,0x39,0x05,0xdd,0xb4,0x87,0x6c,0x7b,0xd5,0xb3,0x2d,0x6b,0x43,0xf4,0x37,0xd9,0x6f,0x5c,0xa2,0x23,0x92,0x53,0xb9,0xd7,0x1b,0x2d,0x5d,0xcd,0x6d,0x3f,0xef,0xc8 +.byte 0x66,0x91,0x10,0x1b,0xc5,0x24,0x50,0x87,0x70,0x93,0x03,0x3f,0x7b,0x40,0xc8,0x0c,0x9b,0xec,0x3d,0x82,0x27,0x96,0x2a,0xbe,0xca,0xaf,0x1b,0xbf,0xef,0x14,0x0c,0xdc,0xa6,0xc7,0x48,0x18,0xce,0x8e,0x43,0x58,0x97,0xb3,0x5e,0xd6,0xc9,0x70,0x65,0xd0,0x0e,0x17,0xac,0xa0,0x6b,0xc9,0x55,0x30,0x12,0x7c,0xbe,0xe5,0x46,0xfc,0xd8,0x3f +.byte 0x0e,0xd7,0x96,0x16,0x32,0x8e,0xb7,0x2d,0x07,0xd1,0x26,0x98,0x70,0x4c,0xb1,0x6f,0x92,0x32,0x75,0x4f,0x57,0x6b,0x78,0xe0,0xc5,0x9b,0xf0,0x08,0x59,0x0b,0xfa,0x2d,0x79,0xbe,0xde,0x44,0x3d,0x65,0x77,0x27,0x3b,0xd9,0xea,0x55,0x79,0x22,0xe8,0xf7,0x62,0xb1,0xe3,0x32,0x4e,0x03,0x17,0x65,0xd3,0x5d,0xee,0xa0,0x9b,0xc2,0xbd,0x9f +.byte 0xcd,0xdc,0xde,0xd7,0x6c,0x95,0x7a,0xf1,0x09,0x4c,0x14,0xb9,0x37,0x1d,0xd0,0xdd,0x4b,0x2e,0x93,0x0b,0xfa,0x08,0x40,0x01,0x36,0xdf,0x89,0x46,0xa6,0xbb,0x19,0xd9,0x4f,0xf9,0xe1,0x7b,0x03,0xc9,0xef,0x01,0x25,0xe9,0x6d,0x95,0x84,0x7f,0xf8,0x8e,0x02,0xfd,0x6f,0x30,0xed,0x1b,0x98,0xd0,0xb3,0xdd,0x92,0x65,0x46,0x49,0x61,0xde +.byte 0x76,0xf5,0x4b,0x29,0x03,0x6f,0x79,0xee,0xbe,0x7a,0x07,0x6e,0xa8,0x29,0xb8,0x03,0xb4,0x6c,0x50,0x1f,0x4a,0xa2,0xaf,0xbd,0xde,0x18,0x72,0x90,0xa2,0x12,0xa9,0x59,0x7b,0xf6,0x96,0x2d,0xda,0x3d,0x90,0xba,0x7c,0x79,0x3e,0x6e,0xef,0x94,0x37,0xe2,0xef,0x6b,0x2a,0x74,0x6b,0x52,0xa0,0xc2,0x1e,0xa1,0x24,0x59,0x84,0xeb,0xdc,0xd0 +.byte 0x34,0x60,0xa8,0x81,0xaf,0xdd,0x57,0xc2,0xa6,0x02,0x7f,0xcf,0x9e,0x64,0x28,0x18,0x7c,0x95,0x98,0x90,0x7a,0x76,0x3f,0x78,0x16,0x2c,0xe0,0xa7,0xdf,0x0d,0x4d,0x5e,0xcc,0x0d,0x73,0x12,0x26,0xd7,0xe9,0x32,0x3e,0xa1,0xa9,0xde,0x29,0xb2,0x3b,0x6f,0x3b,0x6e,0x12,0x0c,0x10,0x34,0x86,0xf2,0xa0,0xd4,0x9c,0xf6,0x14,0x5a,0x41,0x06 +.byte 0x31,0xb1,0xe4,0x31,0x52,0xf4,0xcb,0xe3,0x39,0xcd,0x0b,0xc2,0xca,0x90,0xba,0xb3,0x21,0xbf,0x94,0x13,0x75,0x3b,0x0e,0x0a,0xc0,0x05,0x35,0xe6,0x28,0x74,0x63,0xc5,0x34,0x44,0xd8,0x9a,0x0e,0xec,0xb3,0x1b,0x30,0x58,0xfc,0xa0,0xc4,0xd1,0x26,0x50,0x6b,0x22,0x88,0xfc,0xad,0xa9,0xb4,0x3e,0x36,0xb6,0xb1,0x6d,0x62,0x7e,0x60,0x8f +.byte 0xf5,0x17,0x65,0x1c,0xf6,0x51,0x4d,0x89,0x4a,0x7e,0x5d,0x23,0x3b,0x83,0x1f,0xa6,0xc8,0xd2,0x1a,0x90,0xd3,0x53,0xfc,0x48,0x64,0x94,0x6e,0x1c,0x72,0xef,0x5d,0xd4,0x23,0xa2,0x3a,0x93,0xe4,0x29,0x33,0x8a,0xbd,0xe5,0x17,0xc2,0xe9,0x18,0x6a,0x81,0x1e,0x5b,0x03,0x41,0x45,0x35,0x14,0xe7,0xc8,0x45,0x5c,0x37,0x69,0x77,0x62,0xf8 +.byte 0xd7,0xec,0x9d,0x62,0x2e,0xfa,0x43,0x3a,0xdc,0x8b,0x86,0x86,0x1b,0x31,0x71,0x0e,0x92,0x59,0xf7,0xef,0x96,0xfd,0x04,0x1e,0x1d,0x74,0x7d,0x08,0x06,0x21,0x54,0x39,0xd3,0x9f,0x30,0xa1,0x19,0x7f,0xc8,0x19,0x16,0xd1,0x21,0x2a,0xf3,0x21,0xce,0x19,0x1a,0xde,0x70,0x1b,0x87,0x05,0x9e,0xe8,0xf3,0xfd,0x1d,0xaa,0x61,0x6c,0xfb,0xdf +.byte 0x50,0x9a,0xa0,0x32,0x4e,0xe4,0x68,0xda,0x0e,0x2f,0x2a,0x70,0xe1,0x51,0x66,0xb4,0x2d,0x5b,0xb6,0x32,0x3f,0xcb,0xc0,0xaf,0x01,0x03,0xcd,0xd6,0xb8,0x4e,0x3d,0x24,0x17,0xe2,0x30,0x3b,0xa4,0x08,0x0e,0x6a,0xcf,0xbe,0xc2,0x5c,0x79,0x5d,0x25,0xe2,0xae,0xa7,0x7f,0x42,0xff,0xa9,0xa5,0x05,0xbf,0xf4,0x92,0x30,0xaa,0x1d,0x96,0x7a +.byte 0x49,0xbc,0x1c,0xaa,0x5c,0x8d,0xe8,0xf3,0xd3,0x1a,0x67,0x7f,0x47,0x09,0x90,0x35,0x82,0x4e,0xcc,0x2e,0x50,0xfe,0x2c,0xb9,0x29,0x39,0xff,0x49,0x8f,0x7e,0x89,0x8d,0x4a,0x15,0xd1,0xd6,0x83,0xdb,0x25,0xac,0xc1,0x81,0x23,0x70,0x3f,0xb9,0xce,0x7f,0x03,0x46,0xa8,0x39,0xab,0xff,0x71,0xc9,0x7b,0x3c,0xb3,0x5e,0x9f,0xfe,0x8a,0x0a +.byte 0x39,0xad,0x6a,0xc1,0x8e,0x5a,0xa8,0x71,0xb7,0x01,0x25,0x28,0x15,0xd9,0x0a,0xae,0xc1,0xf9,0x23,0x1c,0xc1,0xe8,0x86,0x1d,0xb8,0x71,0x6e,0xa2,0xa4,0x67,0x22,0x4d,0x0e,0xd2,0xaa,0x70,0x26,0x23,0xfc,0x15,0xed,0x67,0x11,0x87,0x69,0x6f,0xc6,0x4c,0xe1,0x4b,0x04,0x86,0xe9,0x56,0x40,0xea,0x07,0xb1,0x6f,0xe9,0x8f,0xdd,0x2f,0xce +.byte 0x8d,0xca,0x0a,0x58,0x01,0x44,0x2c,0x74,0xd0,0x14,0x07,0x9a,0xb7,0x5a,0xc1,0xea,0xa9,0xdd,0xa4,0x94,0x84,0xc2,0x11,0xa5,0xe2,0x00,0xd8,0xfc,0x77,0xb9,0x5e,0xe6,0x72,0xef,0xc5,0x38,0xe0,0x90,0x11,0x16,0xfd,0xa7,0x77,0xbd,0x4c,0x1d,0xeb,0x32,0x54,0xdb,0x2a,0x43,0xa1,0x87,0xbb,0x2e,0x79,0x22,0x4d,0xb3,0xdf,0x1a,0xee,0x75 +.byte 0xb0,0xdd,0xf2,0x09,0x05,0xf4,0x6a,0x3c,0x86,0xc6,0xe7,0x60,0x2a,0xee,0xb6,0x55,0xae,0xdc,0xce,0xf8,0xe4,0xd7,0xdf,0x72,0x42,0x91,0x6d,0xc4,0xd8,0x60,0xf1,0xe8,0x06,0x71,0x38,0xa3,0x03,0x3e,0x1b,0x14,0x47,0x74,0x93,0xb5,0x61,0x28,0xde,0x23,0x8f,0xbe,0x88,0x5e,0xdf,0x87,0x47,0xd4,0x5f,0x91,0x40,0xeb,0x02,0xda,0x27,0x3b +.byte 0x65,0x9f,0xd8,0xf1,0x78,0x7f,0xba,0x9b,0x35,0xb3,0x10,0xaf,0x7f,0x51,0x37,0xa5,0x63,0x64,0x1f,0xf1,0xc3,0x1b,0x9e,0xe4,0xdd,0x93,0x8c,0x3a,0x98,0x20,0x9a,0x75,0x22,0x7b,0x48,0x0a,0x9d,0x55,0xed,0x07,0x1a,0x79,0x3b,0x98,0xe3,0x16,0x9b,0x16,0x2c,0xb2,0x03,0xc1,0xf5,0x6c,0xac,0x00,0x6a,0xb6,0xc1,0xc2,0x49,0x4d,0x9d,0xf5 +.byte 0x0e,0x7b,0x60,0x09,0xcc,0xa7,0x35,0xbb,0x70,0x34,0x18,0x49,0x2c,0xf1,0x41,0x4f,0xce,0x68,0x03,0x60,0x14,0xa7,0x2e,0x59,0x0f,0xa2,0xc4,0x2f,0x33,0xf0,0xb6,0xa4,0x31,0x75,0xdc,0xb4,0x88,0xe4,0xe3,0x0e,0x4b,0x3f,0x58,0xd0,0xa4,0xea,0x9a,0xef,0x47,0xb7,0xf7,0x20,0x71,0x52,0xd3,0x8a,0x1c,0xd9,0x2d,0x88,0x05,0x03,0x8a,0x1c +.byte 0x3d,0x69,0xf0,0x39,0xf0,0x25,0xad,0x95,0xd4,0x47,0x3c,0xbb,0xfa,0x48,0xd7,0x8e,0xf5,0xdc,0x33,0x43,0x0a,0xbb,0xf0,0xd3,0xb1,0xc3,0x94,0x81,0xcd,0x22,0x79,0xdc,0xd0,0x92,0x8b,0xd3,0xc3,0xac,0x73,0x72,0x83,0xaa,0xa2,0x52,0x13,0x27,0x0e,0xc5,0x8c,0xa5,0x69,0x21,0x6e,0x9c,0x9d,0x9b,0xeb,0x7a,0x19,0xfe,0xb6,0xdb,0x4e,0xc1 +.byte 0xa6,0xec,0x42,0xb0,0x86,0x69,0x60,0xde,0x36,0x11,0x6a,0x86,0xd7,0xbf,0x15,0x48,0xa2,0x73,0x8f,0x68,0xde,0xd6,0xb2,0x6d,0xe0,0xc5,0x1f,0x1f,0xd5,0xc5,0xef,0xce,0xa1,0x90,0x5c,0xe6,0x6c,0x15,0x73,0xa7,0xcc,0x2d,0xe8,0xcf,0x4c,0xc8,0x17,0x3c,0xfa,0x5e,0xdb,0x4f,0x54,0xf3,0xa3,0xff,0x50,0x3e,0x42,0x60,0x0d,0xf3,0xf7,0xbb +.byte 0xc6,0xf5,0xe7,0x63,0x50,0x49,0xc1,0x94,0x60,0x68,0xbd,0x62,0xc0,0x81,0x80,0x16,0xfd,0x65,0xfb,0x2e,0x23,0x67,0xb3,0xb6,0xf8,0x95,0xfa,0x00,0x3f,0x1d,0x10,0x16,0xd5,0xd9,0x66,0xf8,0x25,0xb4,0xce,0xf2,0x2e,0x4f,0xa2,0x21,0x14,0xbd,0x2c,0x63,0xec,0x44,0x57,0x07,0x87,0x3c,0x2f,0x22,0xcf,0x48,0xd3,0x20,0x51,0xfc,0x5d,0xd5 +.byte 0x9f,0x67,0x9c,0xaf,0xe3,0x89,0x36,0xc5,0xfa,0x7c,0xca,0x07,0xdc,0x56,0x2a,0x4e,0xa5,0x76,0xe6,0x09,0x99,0xfb,0xb7,0xba,0xaa,0x0b,0x9c,0xe2,0x0f,0x73,0xab,0x9b,0xbe,0x6f,0x50,0xe3,0xf7,0x28,0x32,0xf2,0xab,0x86,0xa3,0x89,0x3a,0xea,0xd7,0x52,0x52,0x6e,0xed,0x1b,0x94,0xf0,0x59,0x9d,0xbb,0x7a,0x88,0x6f,0xbf,0xaf,0x6a,0x87 +.byte 0x47,0x34,0x7f,0xf4,0x8b,0x0d,0x33,0x12,0x2b,0x67,0x6b,0xc9,0x1d,0x18,0x23,0x2e,0x54,0xee,0x07,0x28,0xbd,0x9d,0xa1,0xaf,0x85,0x7a,0x0f,0xe5,0x5d,0xf7,0x8b,0xca,0xd9,0x3d,0x8f,0x4f,0xcc,0xce,0xc3,0x6e,0x3a,0x40,0x08,0xd2,0x14,0xf0,0x28,0x9b,0xc0,0x4a,0x7a,0x3c,0xc2,0xed,0xe0,0x20,0x04,0xf5,0xf9,0xee,0xb8,0x35,0x94,0xbc +.byte 0x53,0x46,0xf2,0x1a,0xab,0xe9,0xde,0xd8,0x27,0x67,0x0d,0x63,0x2a,0x7b,0x3a,0x38,0x91,0xbc,0x48,0x2c,0x38,0x09,0xa0,0xe3,0x66,0xe3,0xeb,0xb9,0x02,0x2d,0x80,0x87,0x81,0x4f,0x5c,0x1c,0xfd,0x2b,0x0f,0x99,0x37,0x3a,0xfa,0x0f,0x8e,0x8c,0x87,0x76,0x72,0xd3,0xcf,0xc8,0x1e,0x8a,0x3b,0x97,0xa0,0xe6,0x32,0x66,0x3c,0x55,0x2c,0xfb +.byte 0xa9,0x41,0xfd,0xf9,0xd4,0x50,0xe0,0x5b,0x03,0xb7,0x1e,0x49,0xfa,0x59,0xeb,0x55,0xb1,0x21,0xd0,0x52,0xeb,0xe6,0x0f,0x21,0x81,0x4f,0x82,0x9a,0x8f,0x67,0x3d,0x0d,0x1d,0x11,0x1f,0x70,0x59,0x09,0x87,0x99,0xe5,0xf2,0x89,0xa6,0x56,0x8d,0x52,0x55,0xa8,0x91,0x5d,0x51,0x48,0xec,0x66,0x05,0xd6,0x18,0xd1,0x61,0x02,0x5a,0x80,0xcc +.byte 0xee,0xf3,0x3b,0x8e,0x73,0x2a,0xb1,0x22,0xda,0x1d,0xca,0xb2,0xd6,0x7f,0xd7,0x7d,0xaf,0x23,0x8d,0xff,0x24,0x8e,0x5e,0x38,0x29,0x23,0x1f,0xbc,0xfd,0xe4,0x3d,0xcd,0x66,0xe3,0xe1,0x0f,0x85,0xe3,0xda,0x34,0xc6,0xba,0x60,0x5f,0xaf,0x32,0x79,0x34,0xc0,0x01,0x93,0xae,0x1e,0x72,0x7f,0xd2,0x32,0xa1,0xdc,0x0b,0xca,0xee,0x5a,0x7a +.byte 0x09,0x98,0x2a,0x46,0x0a,0xe7,0xfd,0x0f,0x76,0xa0,0x3b,0x2b,0x3d,0xe5,0xcd,0x04,0xa2,0x5e,0x9b,0xba,0x4a,0xd5,0x0a,0xce,0x94,0x77,0xbb,0x24,0xa4,0x12,0xbc,0x24,0xb6,0x60,0x40,0x62,0xd2,0x70,0x0e,0x3f,0x62,0x72,0x2f,0xa1,0xc9,0x12,0x03,0x0f,0x39,0x57,0x77,0x7c,0x5c,0x31,0x13,0xcb,0x8c,0x2c,0x84,0xfd,0x7b,0x6f,0x60,0xbb +.byte 0x1a,0x0b,0x65,0x8c,0xc1,0xe6,0x4b,0x60,0x8c,0xe7,0x3e,0x94,0x2a,0xcc,0x70,0x9f,0xd0,0xfd,0x00,0x0e,0x36,0xb2,0xf1,0x62,0x78,0x6a,0xc8,0x9b,0xbe,0x8b,0x54,0xa7,0xad,0xee,0x3e,0x8e,0x1c,0x23,0xbe,0xa2,0x73,0x43,0xbe,0x15,0x32,0x84,0xdd,0x22,0x75,0xd5,0x9a,0xfb,0x93,0x38,0x55,0x2f,0xa4,0x34,0x4c,0x33,0xc3,0xd7,0x7c,0x9f +.byte 0x42,0x2f,0x9f,0xf6,0x27,0x90,0x15,0x6b,0x14,0x4f,0xbc,0x4b,0x07,0x42,0x24,0x98,0xa6,0xc4,0x4c,0x2f,0x22,0xd9,0x80,0x99,0x97,0x6b,0x7d,0xe8,0x2b,0x31,0x37,0xfe,0xd1,0x8b,0xbd,0xbf,0x08,0x4a,0x56,0x3d,0xff,0xb5,0x12,0x6d,0xc4,0xcf,0xbc,0x75,0xe9,0xe6,0x6f,0x1a,0x30,0x34,0x5b,0x2c,0x1d,0x8f,0x85,0xa0,0xe8,0xfd,0xfd,0xe2 +.byte 0xe7,0x13,0x73,0xcd,0x63,0x63,0x90,0xa5,0xa4,0x3f,0x91,0x65,0x77,0xd4,0xed,0x0c,0x1d,0x06,0x95,0x93,0x74,0x85,0xec,0x31,0xde,0xc9,0xb9,0x2e,0x7c,0x6d,0x2c,0x0d,0x15,0xb7,0x6b,0x0c,0xd2,0xe8,0xa8,0xcb,0x90,0x5c,0x11,0x53,0xc5,0x9d,0x54,0xf4,0x90,0xf7,0xc8,0x17,0x65,0xc0,0x3f,0xea,0xf6,0x28,0x8e,0xf0,0x1c,0x51,0xcc,0xfd +.byte 0x99,0x67,0x3d,0xa5,0x82,0x1f,0xb3,0x75,0x08,0x27,0x85,0xa9,0x7b,0x54,0x91,0x6e,0x80,0x9a,0xdb,0x6c,0x17,0x4a,0x36,0x73,0x0e,0x61,0x2e,0x01,0xae,0x32,0xf8,0x54,0xdb,0xcf,0x24,0xa5,0x13,0xb1,0x7e,0x0b,0xf5,0xe7,0x0e,0x27,0x9a,0xef,0x01,0x0b,0x34,0x4f,0x91,0xc2,0x93,0xe0,0xe6,0x14,0x64,0xf8,0x7b,0x41,0x37,0x22,0x39,0xad +.byte 0xf4,0xa9,0x3b,0xfb,0x7e,0x2b,0xd8,0x2b,0x0f,0x7e,0x40,0x55,0x5a,0x48,0x61,0x2f,0x95,0x5e,0x5c,0x25,0xe5,0x06,0x89,0x17,0x23,0xb6,0x1b,0x38,0x2e,0x7b,0x45,0xa5,0x11,0x0a,0x8d,0xd3,0x8d,0xb6,0x8d,0x47,0xc5,0x4f,0x8f,0x8b,0xe2,0x03,0x85,0xa1,0x5a,0xa2,0x8d,0xca,0x4d,0xef,0xc9,0xde,0x7d,0x06,0xa1,0x3f,0x21,0xb9,0x38,0x7b +.byte 0x91,0xf7,0x5c,0x9f,0x97,0xe3,0xeb,0x5d,0xea,0x5e,0xc1,0xa5,0x30,0xb0,0x7f,0xe0,0x4c,0xef,0xe5,0xe3,0xa0,0x2d,0x23,0xb6,0x08,0x21,0xe6,0x67,0x35,0x82,0x07,0x59,0x02,0xd4,0x68,0xa5,0xf1,0x42,0x70,0xb4,0x5e,0x54,0xed,0x1e,0x99,0xb2,0x55,0xf1,0x69,0x2e,0x7c,0xaa,0x6c,0x5e,0xd4,0xfa,0x16,0xa7,0x1f,0xdb,0x46,0x70,0x65,0x26 +.byte 0x98,0xf1,0xb6,0x42,0xb3,0x48,0x99,0x7c,0x07,0xbe,0x2b,0xee,0xb4,0xc1,0xf0,0xb7,0x47,0xf8,0xcf,0xe4,0x8d,0x34,0xa6,0xe5,0x17,0x9a,0xb7,0x2c,0x2e,0x03,0x30,0xfd,0xfb,0x42,0xe7,0xa1,0xe0,0x34,0x49,0x64,0xd8,0x0c,0xd5,0xb8,0x77,0x9f,0x0e,0xe2,0x73,0x0d,0x20,0x0c,0x21,0x07,0xaf,0x0f,0x93,0x94,0xd6,0xdc,0xe3,0xac,0x8d,0x8e +.byte 0xae,0x87,0xbd,0x2c,0x19,0x66,0xef,0x90,0x4a,0xd9,0xb0,0xf6,0xac,0x3a,0xe2,0xb5,0x2e,0xb4,0x63,0x91,0xf1,0x8b,0xac,0xce,0x51,0xc2,0xe0,0x02,0x7d,0xf8,0xab,0xe4,0xd6,0x85,0xd6,0xbb,0xd7,0x72,0xd0,0x5f,0x4e,0x90,0x09,0xcc,0x51,0xee,0x5b,0xad,0xb2,0xf6,0x16,0x37,0x09,0xa8,0xfc,0x74,0xa5,0x2e,0x26,0x27,0xff,0x53,0xd4,0x45 +.byte 0x82,0xb1,0xb6,0x16,0x65,0xc6,0xbb,0x54,0x0b,0x89,0xa1,0x0e,0x09,0x7c,0xc9,0xc9,0x48,0xa7,0x51,0x78,0x1d,0x3a,0x30,0xc5,0xe7,0x02,0x9e,0x91,0xd6,0x39,0xc8,0x35,0xf0,0x33,0xab,0xf6,0x0f,0xf9,0xce,0xef,0x26,0x46,0x48,0x56,0xbc,0x45,0x44,0xe2,0xd7,0xfc,0xdf,0xb2,0x95,0x20,0x07,0xeb,0x47,0x1c,0xde,0x88,0x5e,0x08,0xee,0xa1 +.byte 0x56,0x9a,0x5d,0x8f,0x35,0xc5,0xb3,0xd3,0x7d,0xe3,0x25,0x82,0xcc,0xcb,0xad,0xd8,0xef,0x83,0x76,0x08,0x55,0x9e,0xf4,0x00,0x1f,0x92,0x24,0x0e,0xf6,0x96,0x98,0x34,0x10,0x10,0x93,0x27,0x3b,0x96,0xbd,0x75,0x45,0x9d,0xad,0xc1,0x79,0xa7,0x09,0x68,0x0a,0xbc,0x14,0xe9,0x62,0xf6,0x5e,0x4e,0x6d,0xfb,0xf2,0x25,0x20,0x8b,0x53,0xa6 +.byte 0xc2,0x31,0x71,0xaa,0xfa,0xa2,0x1c,0xa1,0xb3,0xa2,0xd7,0x22,0x5a,0x72,0x61,0x5c,0x30,0x75,0xcc,0x82,0xb0,0xd0,0x07,0x8c,0x95,0x11,0x57,0xa4,0xe2,0x42,0xf3,0x3d,0x87,0x56,0x45,0x38,0xd6,0x1b,0x2b,0x26,0x11,0x99,0xce,0xcc,0x2e,0x96,0x1b,0xa1,0x06,0xa1,0xa9,0x65,0xe1,0x1f,0x53,0xb6,0x1e,0x5c,0x44,0x40,0xa2,0xf2,0x03,0xe7 +.byte 0x39,0x24,0x59,0x5f,0xdd,0x30,0xf0,0x78,0x9f,0x34,0xf1,0xd3,0x5d,0x9a,0xdd,0xf9,0x02,0x16,0x4b,0xfa,0x8d,0xab,0x2f,0x96,0xdb,0x67,0xf6,0x1e,0x7a,0xf8,0xd8,0xe6,0x71,0xdc,0x1a,0xbf,0x44,0xd2,0xbd,0xb3,0x6d,0x47,0x69,0xe0,0x14,0xef,0xe5,0x5e,0x0a,0xe9,0x1a,0x8b,0x3f,0x67,0x1e,0x1c,0x37,0x86,0x25,0x02,0x52,0x3f,0xf5,0xde +.byte 0xe0,0xbe,0x1d,0x61,0x44,0x3d,0xd2,0xe9,0x26,0x3d,0x4b,0xa4,0xb1,0xb9,0x62,0xc5,0x70,0xfb,0x1d,0xaf,0xe6,0x19,0x97,0x0f,0x6e,0x6d,0x4e,0xdf,0x5f,0xc9,0xb2,0xb0,0xb9,0x4b,0x72,0xc7,0x60,0x5d,0xf8,0x7d,0x3b,0xd8,0x74,0x29,0xf2,0x56,0x25,0xd9,0xd9,0x12,0x3a,0x50,0x01,0x54,0xd3,0x0e,0x4c,0xbd,0xc9,0xf5,0x66,0xc4,0x4b,0xa2 +.byte 0x68,0x31,0xb1,0x9d,0x47,0xd8,0x28,0xce,0x6b,0xe4,0x5f,0x78,0x75,0x22,0x7d,0x44,0x08,0x71,0xfb,0xd8,0xa0,0x6e,0xd1,0xbd,0x64,0x4e,0x00,0x99,0xf7,0x85,0xad,0x31,0xde,0x5c,0x4c,0x7c,0xc3,0x89,0x49,0x9f,0xea,0x22,0x86,0xa0,0x48,0x48,0xcf,0x47,0xfb,0x68,0x04,0x4c,0x05,0x62,0x57,0x60,0x9b,0xa0,0x37,0x41,0x77,0xe4,0x7d,0x3e +.byte 0x36,0xda,0xd5,0xfd,0x68,0x47,0x8c,0x68,0x61,0x4c,0xea,0x38,0x20,0xa5,0xe4,0x12,0x6e,0xd5,0x14,0x37,0x01,0xcf,0xbd,0xdd,0x55,0x97,0xb4,0x30,0xf0,0x65,0x15,0xee,0x1f,0xc8,0x5b,0x07,0x82,0xae,0x43,0xad,0x11,0xda,0x0e,0x61,0x23,0x0a,0x5f,0x52,0xf9,0x9d,0xc5,0x98,0x4e,0xaf,0x77,0x21,0xc8,0x9f,0x6d,0x25,0x94,0x4f,0x91,0x1a +.byte 0xb4,0x2d,0xe3,0x15,0xe5,0xe6,0x25,0xb8,0x8e,0xd8,0x33,0xe3,0x05,0x01,0x7b,0x6b,0xa8,0x39,0x44,0x4b,0x58,0x3c,0x17,0x53,0x17,0x5c,0xbc,0xd5,0xcd,0xd4,0x29,0xe7,0x17,0x7a,0x69,0xa6,0x75,0x8e,0x0a,0x00,0x41,0xbe,0xb4,0x8d,0x79,0x1d,0xac,0x2a,0x0f,0x9b,0x7b,0x5a,0xe8,0x17,0xe2,0xb3,0x1d,0x03,0xde,0x5a,0x7c,0x31,0x18,0x8c +.byte 0x1c,0xf9,0x19,0x7b,0x37,0x1f,0x53,0x77,0xce,0x1f,0xad,0xb6,0x0d,0x21,0xe1,0xb0,0xf9,0x42,0x52,0x99,0x02,0xa8,0x58,0xab,0x94,0xf8,0x9f,0x99,0x2d,0x1e,0x68,0x4f,0x5a,0x91,0x2b,0xdf,0xe8,0xe6,0x34,0xb6,0x80,0x9b,0xb1,0x0e,0x87,0xec,0x29,0x17,0x4d,0x98,0x2d,0x40,0xd0,0xf7,0xca,0x55,0x9d,0x56,0x19,0xd5,0x7c,0x4e,0x2e,0x75 +.byte 0x5d,0xe7,0x3e,0xed,0x47,0xdc,0xb1,0x04,0xe5,0x61,0x0f,0xe7,0xc4,0x16,0x71,0xf4,0xf8,0x8a,0xf1,0xfc,0xd5,0xdb,0xeb,0x0b,0x82,0x0f,0xfe,0x64,0xa2,0xb0,0x53,0xab,0xf5,0x01,0xc2,0x8f,0xa0,0x4d,0x5d,0x1b,0x54,0x32,0x48,0xca,0x8a,0x42,0x59,0x4a,0x85,0x68,0x75,0xd1,0x1b,0x03,0x11,0xfe,0x28,0xd7,0xd5,0x37,0x81,0x7a,0xfb,0x84 +.byte 0xfd,0xa8,0x98,0x54,0xf7,0x81,0xb0,0x2d,0x2d,0x5d,0x95,0x0a,0x5b,0x80,0x13,0x95,0xad,0x8f,0x88,0xaa,0x38,0x7e,0xbc,0x88,0xc2,0xf6,0xa6,0x1e,0x6d,0x78,0xc9,0x4f,0xa9,0xb3,0xaa,0x23,0x0c,0x62,0x19,0x6f,0x26,0x5d,0xca,0x36,0x23,0xf8,0xd1,0x76,0x80,0x32,0x59,0xa0,0x47,0x86,0xee,0xc9,0x0f,0x1d,0x37,0xd9,0xc9,0x4e,0x65,0x22 +.byte 0x17,0x95,0x88,0x85,0xb3,0x8a,0x5d,0xb9,0xe6,0x3b,0x6c,0x02,0x81,0x61,0xe0,0xab,0x19,0x6c,0x9a,0x29,0x33,0xf1,0x7b,0x0c,0x22,0x16,0x0c,0xd6,0xfa,0xc2,0x84,0xe5,0x74,0x9e,0x8e,0xf8,0xdb,0x44,0x68,0xa0,0x58,0x52,0x9f,0xad,0xe6,0x2b,0x23,0x70,0xf3,0x6e,0xdc,0xf1,0x2d,0xa5,0xc2,0x7f,0xef,0x5f,0x58,0xc2,0x96,0x66,0x67,0x4b +.byte 0x7c,0xe0,0xd7,0x96,0xda,0xf7,0xd7,0x7a,0x7d,0xb4,0x4f,0x48,0xbd,0x87,0x6b,0xf4,0xbd,0xd1,0x45,0xdc,0xba,0x4f,0xd2,0x00,0x7f,0xde,0x3c,0x57,0xd7,0x3b,0x5b,0xa9,0xf3,0x17,0x76,0x47,0x0c,0xcf,0x48,0x07,0xa8,0xc3,0x30,0x60,0xc6,0x98,0x20,0x29,0xba,0x5f,0x76,0x6d,0x63,0x5f,0x87,0x7e,0x36,0xbc,0xa3,0xe4,0xd6,0x6a,0x55,0x73 +.byte 0x8b,0x8b,0x62,0x40,0xc5,0x7e,0xa3,0x33,0x04,0xce,0xe2,0x9d,0x9f,0x67,0x1c,0xf0,0xa1,0x78,0xd2,0x0b,0x58,0xc1,0x2e,0xec,0x78,0x0a,0xc9,0x0b,0x1d,0xfb,0xcc,0x72,0xd8,0xe4,0x15,0xcb,0x09,0x8b,0xd9,0x33,0xa9,0xb6,0x24,0x7e,0x59,0x48,0xbf,0xda,0xdb,0x5c,0x99,0xd1,0x92,0x1b,0xb6,0xf6,0x75,0x78,0x53,0x69,0x89,0x27,0x6b,0x3c +.byte 0xfb,0xd2,0xa7,0xeb,0xc5,0xf7,0xea,0x8b,0x38,0x59,0x8e,0x02,0xc7,0x6e,0x96,0x8a,0x85,0x1c,0x91,0x1b,0x97,0x97,0x9e,0xa7,0x9d,0x10,0xa4,0x4a,0x6e,0xa8,0x51,0x05,0xbe,0x5f,0x9a,0x5b,0x94,0xf2,0x2c,0xa1,0x1e,0x33,0xc5,0xe8,0x92,0xb8,0xd2,0xfa,0x27,0x07,0x12,0xa1,0xdc,0x24,0x43,0x28,0x06,0xe5,0x43,0x57,0x8f,0x66,0x72,0x2f +.byte 0x26,0xf7,0xea,0xa1,0xcf,0x57,0xd6,0xa6,0xf7,0x37,0x1d,0x6e,0xd9,0xde,0x1a,0x8c,0xf5,0x01,0x76,0xc3,0x56,0x40,0x57,0x3d,0x4a,0x14,0x04,0xf2,0xfc,0xba,0x3b,0x60,0xf1,0x88,0x1e,0x16,0x08,0x99,0x90,0xfe,0x27,0xaa,0x04,0x53,0xd8,0x7e,0x0c,0x58,0x6a,0xd9,0x5a,0xe4,0x11,0xd4,0xcc,0x48,0xbe,0x03,0x08,0xbc,0x61,0x47,0xdd,0xde +.byte 0x5f,0x03,0xc7,0x8f,0x9c,0x08,0x93,0xe3,0xaa,0xee,0x9c,0xe3,0xc6,0x06,0x78,0xda,0x0a,0xdd,0xb0,0xc3,0xf3,0x0b,0xe5,0xa0,0x5f,0x1e,0x3e,0xb3,0x15,0x7f,0xf1,0xf4,0x38,0xb2,0xed,0xf2,0xa6,0x8b,0x1d,0x78,0xb6,0x03,0x19,0xcd,0x17,0xb4,0x18,0x17,0x49,0x61,0x17,0xbd,0xbe,0x4b,0x04,0x00,0xce,0x4b,0xcc,0x47,0x61,0x76,0x85,0xdc +.byte 0x2b,0x85,0x48,0x82,0xf4,0x9b,0xb4,0x62,0x53,0xc7,0x06,0x50,0xf2,0x3e,0xba,0x6d,0xf2,0x19,0x0f,0x7f,0x84,0xce,0xa6,0x4d,0x96,0x97,0x94,0x12,0xb6,0xd0,0xd6,0xa4,0xc1,0xcc,0x14,0x54,0xf6,0x7a,0xf1,0x94,0x62,0xa1,0xc7,0x22,0x9b,0x0d,0x0e,0x69,0xcf,0x38,0x5c,0xda,0x9f,0xc0,0xfa,0x93,0x81,0x24,0xce,0x9f,0xf3,0xc2,0x66,0xad +.byte 0x06,0x21,0xf2,0x48,0x6c,0x4a,0x0d,0xb8,0x41,0x86,0xaf,0xb7,0x6c,0x65,0xcb,0x83,0xd8,0x75,0x11,0x60,0xfa,0x06,0xe5,0xd2,0x11,0x87,0x29,0xb8,0x41,0xcb,0x17,0xb5,0xbd,0xbd,0xf9,0xd5,0xbc,0x89,0xb6,0x60,0x65,0x59,0xbb,0x38,0x9d,0x70,0xf9,0x81,0x6b,0xe6,0x12,0x80,0x08,0x73,0x9f,0xfb,0x2f,0x72,0x4e,0x18,0xff,0x65,0xab,0xa6 +.byte 0xaa,0x78,0xf1,0xa4,0xe9,0x1a,0x7d,0xa5,0xdd,0x91,0x77,0xa9,0xa3,0xf3,0xe3,0xe5,0x5a,0xa2,0x0d,0x3a,0x2a,0x4a,0x11,0x9a,0x8d,0xc3,0x00,0x6e,0xd4,0x4f,0xb9,0xe7,0x39,0x78,0x89,0x64,0xb2,0xc8,0xfd,0x1f,0xe6,0xa9,0x54,0x17,0x83,0x3f,0xeb,0x97,0x77,0xac,0xc8,0xba,0x0e,0x77,0x02,0xb0,0x29,0xbe,0x51,0x62,0xef,0xa5,0xd5,0xab +.byte 0x79,0x98,0xab,0x7a,0x1e,0x13,0xe8,0x87,0x4f,0x61,0xa3,0x37,0xdf,0xe6,0xda,0xb9,0xf5,0x69,0xf7,0x7a,0xee,0xd6,0x5f,0x6a,0xb3,0x95,0x55,0x59,0xd1,0x6c,0x5b,0xd5,0xba,0x8b,0x74,0x85,0xbf,0x1e,0xe5,0xb3,0x24,0x28,0x4b,0xc8,0x4a,0xec,0xa1,0x1d,0xda,0x99,0x3f,0xdf,0xfc,0xe6,0x2e,0x1b,0xa4,0xba,0x1a,0x03,0x89,0xb7,0x93,0x4e +.byte 0xaf,0x40,0xb0,0x7e,0x3f,0x34,0x0d,0x94,0x75,0x8c,0x8a,0xfb,0x88,0xcd,0xd3,0xc2,0x61,0x95,0x63,0x51,0xaa,0x78,0x1f,0x24,0x95,0x5a,0xb5,0x98,0x9a,0xd4,0xb8,0x34,0xe1,0x47,0x1c,0x68,0x0f,0x08,0xf1,0x69,0xe6,0xd4,0xaf,0x23,0xf6,0x32,0x71,0x51,0x01,0xa9,0xf2,0xa1,0x45,0x0b,0x75,0x82,0x09,0xe4,0x9c,0x2a,0x1d,0x0b,0xd6,0xd2 +.byte 0x26,0xe8,0x30,0x44,0xdf,0xa3,0x2b,0x97,0x11,0xc7,0xe7,0x47,0xfd,0xc7,0xbf,0x59,0xf3,0x28,0x32,0x46,0xc0,0xc4,0x7a,0x96,0x08,0x0d,0x2c,0xa1,0x82,0x6c,0x0a,0x33,0x82,0x55,0xd7,0xcf,0x3e,0x08,0xbb,0x22,0x15,0x96,0x12,0x66,0xd2,0xae,0x21,0x3a,0x54,0x6a,0xe0,0x33,0x0c,0xa4,0x96,0x4b,0x5d,0xf2,0x86,0xb9,0x70,0xe4,0x65,0x45 +.byte 0xe4,0x2f,0xa7,0xb4,0xc1,0xd5,0x9a,0x02,0xa1,0x5b,0x4e,0x58,0xca,0xf8,0x63,0xae,0x45,0x1c,0xf4,0xa7,0xc8,0xa5,0x84,0x23,0x87,0xcb,0x3e,0x88,0xca,0xe9,0xa9,0x49,0xc5,0xc6,0x63,0x37,0x99,0xe0,0x27,0x03,0x96,0x7b,0x73,0x8c,0x36,0xde,0x89,0x80,0x30,0x2c,0x00,0x94,0x0b,0xfb,0x1f,0x39,0xe0,0xed,0xb6,0x31,0x21,0x90,0xfe,0xa4 +.byte 0xee,0xa5,0xe5,0x7b,0x9a,0x11,0x41,0x51,0xab,0x89,0x54,0xe0,0x8d,0x5f,0x10,0x1b,0x76,0x27,0x77,0x3d,0xb0,0x58,0x86,0x7b,0xb7,0x45,0xfb,0xd0,0x81,0xa8,0xcd,0xc0,0xc8,0x5f,0xfb,0xfe,0x8c,0x0a,0x3d,0x5d,0x61,0x4b,0x9b,0x32,0x75,0x66,0xa9,0xac,0x32,0x35,0xe9,0x1a,0xdf,0x06,0x8d,0x13,0x5d,0x40,0xcb,0x7d,0x50,0x3e,0x54,0xab +.byte 0x04,0xbc,0x83,0x32,0x8f,0xf5,0x93,0x1d,0x9b,0x5a,0xe1,0x19,0x70,0x4a,0xba,0xfc,0x4c,0x6a,0xf3,0xd6,0xd1,0xfd,0x48,0xd0,0x7c,0xa4,0xab,0x0b,0xb6,0x5f,0xe1,0x31,0xce,0x99,0x10,0x98,0xfc,0x6e,0x1c,0xaa,0x9c,0x34,0xa2,0x55,0xdc,0xe0,0x81,0x1b,0x9e,0xff,0x75,0x2e,0x25,0xe9,0x2c,0x20,0x83,0xf6,0x66,0xf9,0x63,0x31,0xfe,0xa7 +.byte 0xbf,0x4d,0xfd,0xff,0x0b,0x93,0x84,0xd4,0xb4,0x72,0x13,0x38,0x90,0x75,0xc9,0xff,0x61,0x4b,0xf9,0x55,0x62,0x58,0xf0,0x60,0xce,0x2d,0xec,0x94,0x06,0x0a,0xde,0x48,0xc0,0x46,0x89,0xfb,0x5c,0xf7,0x9f,0x37,0xad,0xd2,0xff,0xbe,0xfb,0x81,0x21,0xe0,0x20,0x43,0x88,0xad,0x40,0x47,0x7a,0xa9,0x30,0x88,0x10,0x16,0x41,0xf8,0x25,0xe0 +.byte 0x8f,0xc2,0xe3,0x9f,0x48,0xd3,0xfe,0x61,0x70,0xb9,0xa1,0x9e,0xaa,0xa6,0x73,0xcf,0xc3,0xd6,0xab,0x69,0x65,0x4a,0x3c,0xec,0x28,0x02,0x63,0x62,0xa1,0xb6,0xa3,0xd5,0x8c,0x9e,0x11,0x81,0x98,0x12,0x4f,0xec,0xb6,0xe5,0x3a,0x96,0xa1,0x11,0x13,0x77,0x5f,0x0f,0x19,0x40,0x14,0x28,0xcc,0xf1,0x3e,0x19,0x1d,0x78,0x31,0xac,0x5c,0xce +.byte 0xd7,0x29,0xfa,0x02,0x3b,0x29,0xd8,0x3a,0x37,0xcb,0x94,0xb2,0x38,0xc7,0x7f,0x3a,0x46,0xd2,0xb7,0xfe,0xfb,0x54,0x7c,0x01,0xa2,0x9b,0x53,0x57,0x04,0x73,0x4e,0x06,0x90,0xe5,0x78,0x0a,0x45,0x67,0x12,0x83,0xd7,0x31,0x59,0xa4,0x76,0xaa,0x7c,0xde,0x72,0x92,0x11,0x94,0x4c,0x6a,0xe4,0x35,0x35,0x3a,0x2e,0xef,0x7c,0xc1,0x91,0x76 +.byte 0xd0,0xfe,0x84,0xd1,0xa1,0xf9,0x03,0xc3,0xba,0x09,0xbb,0x2c,0xe2,0xb5,0x06,0x7e,0x23,0xb7,0xe0,0xc1,0xd3,0xfd,0x55,0x01,0xf3,0xba,0xc5,0x1b,0xf8,0x02,0x60,0x92,0x0a,0x93,0x1c,0xc4,0x19,0x03,0x88,0xf5,0x45,0xe5,0x8f,0x7d,0xce,0x2c,0x87,0x2e,0xf6,0x55,0x8c,0xf9,0xb0,0xd2,0x72,0x2d,0x93,0x6d,0x28,0x6e,0x8e,0x3a,0xed,0x68 +.byte 0x02,0xda,0x80,0xd0,0x71,0x4a,0x8f,0x06,0x59,0x38,0x89,0x81,0xcb,0x1a,0x74,0x1e,0x62,0xa3,0xa5,0xb8,0x85,0xc3,0xd2,0x04,0x3d,0x3b,0x93,0x36,0x0c,0x12,0x55,0xfb,0x7b,0xc8,0xa3,0x25,0xa7,0x93,0xb0,0x3e,0x49,0x86,0xbf,0x76,0x8f,0xc4,0x4c,0xfe,0xce,0x4a,0xf6,0x2f,0x15,0x33,0x06,0x3a,0x35,0x49,0xe7,0x08,0xff,0x99,0xac,0xf6 +.byte 0x20,0x6d,0xab,0xb2,0x05,0xa9,0xe4,0x06,0x57,0x9c,0xf4,0x76,0x8c,0x82,0x64,0xd5,0x67,0xe0,0xad,0xe1,0x69,0xdc,0x9e,0x2c,0x59,0x92,0x3a,0xc8,0xc1,0x0a,0x61,0x89,0x45,0x9f,0x8b,0xf8,0x64,0x0a,0x5a,0x75,0x55,0x37,0x24,0xe1,0x42,0x43,0x7c,0x9c,0xcd,0x4e,0x9e,0x19,0xfb,0xd9,0x15,0x29,0x30,0x52,0x33,0xf3,0xc8,0x88,0xdb,0xaa +.byte 0x07,0x27,0xfb,0x2b,0x0c,0xc0,0xa1,0x5f,0x51,0xf1,0x54,0xf8,0x90,0x0a,0x35,0x07,0x6e,0x9c,0x64,0xd8,0x4f,0x2d,0xb3,0x61,0xbc,0x18,0x1f,0x22,0x84,0x94,0x4b,0x85,0xfc,0x4a,0xf9,0xe5,0xfc,0xdd,0x7a,0x07,0xa2,0xbb,0xbe,0x7e,0x1f,0x4e,0xf9,0x29,0xb8,0xde,0x56,0xe9,0x04,0xc1,0xc2,0xb6,0xa8,0xc7,0xb6,0x83,0xf2,0x85,0x3d,0x35 +.byte 0xe3,0xeb,0x2f,0x2f,0x3c,0x1a,0x3a,0xf1,0x61,0x1f,0xe8,0xf0,0xce,0xa2,0x29,0xda,0x3f,0x38,0xf5,0x82,0x7a,0xb8,0x55,0xf1,0x1a,0x6e,0x5b,0x5c,0xd0,0xc8,0xc8,0x3a,0xe2,0xaf,0xb4,0x6f,0xba,0xe4,0x03,0x78,0x5f,0x47,0x4b,0xaf,0xfe,0x2a,0x7e,0x27,0xba,0x17,0xb4,0x92,0x27,0x70,0x13,0xd9,0xbb,0x6b,0x1c,0x9a,0x3e,0x29,0x85,0x9a +.byte 0xb7,0x64,0x5b,0x6d,0x7b,0xec,0xb2,0x26,0x3a,0x4b,0xb7,0x17,0xaf,0xb5,0xa1,0xbc,0x4d,0x67,0x4c,0x86,0xd1,0x53,0x2e,0x5d,0x64,0xe8,0x55,0xd9,0xbb,0xae,0xc1,0x55,0x41,0x99,0x8e,0x4d,0xed,0x3d,0x9e,0xea,0xe3,0xf2,0x76,0x45,0x6d,0xaa,0xbb,0x89,0x0b,0xc0,0x13,0xfe,0x99,0x2c,0xb0,0xd2,0xa9,0xeb,0x58,0x57,0x4d,0x88,0x2e,0x04 +.byte 0x4f,0x7a,0x76,0xaa,0x3a,0xa6,0x08,0x93,0x42,0x74,0x2f,0x3a,0x35,0xb0,0x36,0xcc,0x77,0xec,0x54,0x41,0x2e,0x81,0xf6,0x9f,0xf3,0xe7,0x23,0xc0,0x3f,0xa4,0x52,0x83,0x38,0xe2,0x12,0xed,0xdb,0x23,0xa0,0x0b,0xbf,0x61,0x98,0x89,0xb0,0xa4,0x3d,0xa9,0x6a,0x73,0xa1,0x99,0xc9,0x9e,0x68,0x45,0x37,0x4b,0x6c,0x87,0xfb,0x93,0xf2,0xaa +.byte 0xe8,0x1d,0x53,0x6c,0x4b,0xda,0xc5,0x6f,0xaa,0xde,0x99,0xd2,0xba,0x7c,0x27,0xc2,0x4e,0xd5,0x5b,0xc8,0x13,0x9e,0xa2,0x10,0x6a,0xbb,0x39,0xf9,0xa7,0x55,0x0a,0x65,0x88,0x3c,0x9b,0xff,0x83,0x4e,0xf7,0x9c,0x99,0x69,0xbd,0x64,0x0d,0xd1,0xc0,0xb0,0x43,0xd6,0x63,0x50,0x13,0x68,0x8d,0xd1,0x7e,0x56,0x93,0xb5,0x8e,0x8f,0x12,0xe5 +.byte 0x37,0x96,0x21,0x64,0xd5,0x0b,0xf6,0x27,0xf8,0xaa,0x34,0x8e,0xc4,0x2b,0x7b,0x6a,0x7c,0x89,0x4e,0x15,0x15,0x3d,0x17,0x93,0xd4,0x99,0xfe,0x97,0x95,0x20,0x85,0xcc,0xd4,0xcd,0x73,0x67,0x80,0x22,0x06,0xed,0x5e,0xce,0x90,0x59,0x01,0x31,0x24,0x17,0x37,0x4a,0x63,0x96,0xc2,0xf3,0xe0,0x21,0x0a,0x3b,0x9f,0x94,0xad,0xd6,0xa4,0xa9 +.byte 0xa2,0x54,0x0d,0x2a,0xb3,0x5c,0xfa,0xbe,0xeb,0x21,0xd6,0x13,0x22,0xa5,0x95,0x5e,0x25,0x72,0xf9,0x18,0x1f,0x50,0x64,0x04,0x5b,0xe8,0x0e,0x1f,0x6c,0xe1,0x4e,0xf5,0x7f,0xf0,0x13,0x4f,0xda,0x75,0xab,0x5a,0x98,0xd3,0x07,0x32,0x96,0x2a,0xc7,0x1e,0x0f,0x14,0xdb,0x96,0x5f,0xac,0xc1,0xef,0x5b,0x2d,0xd6,0x6d,0x13,0x01,0xd9,0x04 +.byte 0x9c,0xcd,0xe5,0x5e,0xbe,0x3a,0x47,0x14,0x09,0xbe,0x11,0xad,0x87,0x3f,0x0e,0xe1,0xcb,0x97,0xd0,0x6e,0x1f,0x49,0x07,0xd1,0x8c,0x2b,0xe0,0xf0,0xb2,0xaa,0x8b,0x70,0x18,0x7f,0x29,0xcc,0xc4,0x23,0x66,0x48,0xc4,0xb5,0x5e,0xf1,0x10,0xd7,0x1d,0x2a,0xba,0xe4,0x12,0x64,0x1d,0xf5,0x03,0x35,0x71,0x57,0x5d,0xf4,0xa4,0xb5,0x99,0x0b +.byte 0x4c,0x80,0x65,0x07,0x2f,0xbc,0xf7,0x28,0x8b,0xc0,0x8f,0x84,0x63,0x7e,0xf5,0x01,0x23,0x8c,0xaf,0x71,0x35,0xd4,0xe1,0x70,0xc7,0xef,0x1f,0x66,0xa9,0x34,0x57,0xaa,0x9a,0xbb,0x80,0x43,0x15,0x96,0xc4,0x03,0xd9,0xae,0xbe,0x89,0x1c,0xa1,0x9f,0x65,0x61,0xe5,0x90,0x9f,0xa6,0xf4,0x3b,0xde,0xa1,0xd1,0xf1,0xf9,0x2d,0xd7,0xa7,0x7e +.byte 0x3d,0x42,0x3d,0x1b,0x99,0xed,0x49,0x2e,0x92,0x6b,0x47,0x0e,0x0b,0x90,0x56,0xe0,0x1b,0x6b,0xfe,0x97,0xfe,0x9b,0xa2,0x50,0xcc,0xbf,0xea,0xae,0xe8,0xf0,0xc4,0xe5,0x81,0x20,0x4a,0xb0,0xf7,0xa5,0x23,0x24,0xf6,0x3f,0x9e,0x9c,0xcc,0xce,0xe4,0x95,0x49,0xea,0x66,0x4a,0x35,0x31,0xf3,0x03,0xc3,0x08,0xf9,0x5f,0x95,0x4c,0xbc,0x84 +.byte 0x13,0xbe,0x7f,0x35,0xbb,0xd7,0x35,0x3c,0xfb,0x05,0x43,0x95,0xbf,0x87,0xf2,0xc3,0x2d,0xef,0x13,0x1d,0x65,0x17,0x82,0x75,0x3d,0x67,0x51,0xcd,0x6e,0x42,0x5f,0x49,0x53,0x8b,0xaf,0x34,0x7d,0xa8,0xc1,0x45,0xcd,0x3d,0x29,0x00,0xa3,0xf3,0xbb,0x44,0x00,0x05,0x57,0xa5,0xeb,0xfd,0x98,0xa6,0xae,0xc6,0xc4,0x6c,0x6d,0x7d,0xf6,0x3e +.byte 0x82,0x1d,0x12,0xe7,0xcd,0xd2,0xd5,0xfe,0x41,0xf8,0xa4,0xb3,0x6a,0x04,0x13,0x28,0x10,0x40,0x27,0xc9,0x43,0x74,0xcf,0xaf,0x9b,0x60,0x17,0x43,0x8f,0xd7,0xb7,0x56,0x72,0xf3,0x48,0x0a,0xe6,0x36,0xf2,0x3f,0x51,0xf9,0x6e,0xc8,0xa3,0x04,0x8c,0x01,0x86,0x6e,0x83,0x27,0xe2,0xba,0xf2,0x8f,0x8f,0xa1,0x39,0xe7,0x17,0xdd,0x06,0x10 +.byte 0x0c,0x7f,0xfa,0x22,0x5d,0x88,0x35,0xc6,0xcd,0x60,0xa2,0xf0,0xfd,0xc9,0xed,0x85,0xac,0x88,0xfd,0x7d,0xc0,0x77,0x1b,0x80,0x3d,0x21,0x1e,0x8e,0x4d,0xdb,0x20,0xe2,0x38,0xad,0xd4,0xb5,0x2b,0x2b,0x31,0xbc,0x7b,0x02,0xa2,0x25,0x50,0xc0,0x01,0x20,0x76,0x6f,0x98,0x0b,0x3d,0x46,0xed,0xbb,0x2b,0x39,0x74,0x30,0xce,0x3e,0x6d,0x91 +.byte 0xa1,0x89,0x83,0xde,0x69,0x93,0x1a,0x14,0xa1,0xb0,0xaa,0x80,0xb0,0x1c,0x02,0x3f,0x13,0x9a,0x15,0x7f,0xb4,0x02,0x8f,0x30,0x0b,0xee,0xd9,0x72,0xcb,0x74,0x95,0x4a,0x39,0xb3,0x4e,0x78,0x12,0xb1,0x77,0x89,0xc0,0xaf,0x17,0xfd,0xc1,0x68,0x65,0xd1,0x08,0xae,0x56,0x5c,0xe0,0xe7,0x6f,0xb3,0x1e,0x10,0xce,0xd8,0xdf,0xee,0x67,0xad +.byte 0xd8,0x08,0xe0,0x79,0x36,0xe4,0x57,0x1c,0x45,0x22,0xa7,0x44,0xa8,0x12,0x37,0x92,0x85,0x9f,0x3a,0x48,0xd0,0xfd,0xb3,0x40,0x20,0x10,0xed,0x11,0xe0,0x9a,0xa6,0x09,0x5b,0xe9,0x21,0x95,0xe1,0x45,0x19,0x39,0xcc,0x85,0x5f,0xa5,0x6b,0x46,0x37,0xe1,0xa1,0x17,0x3f,0xb6,0xe9,0xb0,0x81,0x25,0xf6,0xd1,0xb8,0x22,0x5a,0x27,0x48,0x83 +.byte 0x01,0x36,0xd4,0xb8,0xc0,0x9f,0x37,0x52,0x22,0xd2,0x69,0x7b,0x3d,0xfb,0x31,0xc1,0xa3,0xb4,0xa1,0x1d,0x0e,0x24,0x9a,0xda,0x02,0x15,0x4b,0x46,0x24,0x0e,0xb1,0x79,0xc2,0x5b,0x01,0x60,0x4a,0x24,0x8a,0xbb,0x70,0xaa,0xf4,0x45,0xc1,0x0d,0x04,0x26,0x3f,0x74,0xbd,0xdd,0x33,0xaa,0xd6,0x62,0x56,0xb1,0xe7,0x2d,0x7b,0x66,0xa2,0x40 +.byte 0xb4,0xe4,0xbd,0x8e,0x35,0xba,0xf1,0x2f,0x59,0xa7,0x01,0x6d,0x5a,0xa7,0xa6,0x3b,0x82,0xa3,0xb4,0x54,0x51,0x33,0x6b,0xfb,0x78,0x4a,0x74,0x88,0x7f,0x55,0xea,0x08,0x8e,0x19,0x78,0xbc,0x80,0x19,0x2f,0x41,0x97,0x20,0xa0,0x9e,0xbf,0x44,0xae,0x2e,0x26,0x66,0xe3,0x25,0xa0,0x92,0xa9,0xbe,0x8c,0x0d,0x96,0xec,0x93,0x99,0xe2,0xe7 +.byte 0x81,0xd5,0x10,0x62,0x3a,0x97,0x38,0x51,0x36,0x11,0x00,0xe0,0xc1,0x3a,0xc5,0xd4,0xa5,0x19,0xf4,0x82,0x66,0x0c,0xf9,0xb3,0x04,0x3e,0x57,0xc3,0x43,0xab,0xc6,0x52,0x95,0x8f,0xd3,0xf1,0xde,0xd9,0x57,0x6d,0x32,0x4f,0xc7,0x8c,0x1b,0x7a,0x53,0x6a,0xcf,0x56,0xea,0x61,0xb4,0xe5,0x64,0x2d,0x02,0x26,0x5b,0xcf,0x1c,0xc7,0x37,0xc3 +.byte 0x41,0xd2,0x1b,0x6c,0x5b,0x47,0xb8,0x73,0x89,0xfe,0x0e,0x7a,0x35,0x05,0xfc,0xea,0x6a,0x34,0x74,0x69,0xf0,0x12,0x29,0xa9,0x33,0xce,0x93,0x15,0xa0,0x68,0xb3,0x46,0x43,0xdb,0x8d,0xfa,0xef,0x93,0x66,0x72,0x18,0xae,0xe4,0xab,0xf4,0x8a,0xd1,0xb5,0x42,0xbd,0x2d,0xda,0xcb,0xf6,0x44,0x25,0xb1,0x01,0x8a,0xff,0xd5,0x34,0x16,0xec +.byte 0x7e,0x38,0x7b,0x50,0x41,0x61,0xf9,0xdf,0x4c,0x3e,0x02,0xd6,0xc3,0xce,0x19,0x9f,0x12,0x45,0x0c,0x99,0xb1,0xd9,0xeb,0xb9,0xe3,0xd5,0xb6,0x2b,0x25,0x8c,0x0b,0x04,0xf8,0x8d,0x41,0x41,0x3d,0x39,0x1b,0x7f,0x88,0xa7,0x8f,0x61,0x30,0xfe,0x67,0x75,0x35,0xd1,0x41,0x90,0xda,0x73,0x80,0xcf,0xc9,0xf6,0x44,0x00,0x67,0xcd,0xca,0xaf +.byte 0x6d,0x84,0x39,0x9a,0xb2,0xbb,0xfc,0xac,0x9b,0xb2,0x95,0x2f,0xc9,0x06,0x3a,0xa4,0x7b,0x9a,0x25,0xc6,0xe5,0xdb,0x7a,0xc6,0x8b,0x84,0x6a,0xb7,0x1e,0x22,0xaa,0x10,0x96,0xd3,0x55,0x50,0xa2,0x02,0x04,0x69,0x92,0xd7,0x6b,0x1f,0x9b,0x45,0x07,0x71,0xda,0xdc,0x76,0xc5,0xb8,0x34,0xa2,0x32,0x33,0x16,0x2e,0xb0,0x2a,0x90,0x43,0x40 +.byte 0x92,0x77,0x74,0x4e,0xdc,0xb4,0xe2,0x7d,0xc1,0x57,0xaf,0xf4,0x2c,0x20,0x65,0x77,0x88,0xc9,0x6e,0x69,0x38,0xc8,0x19,0x95,0x32,0x54,0x59,0x7f,0x37,0xd7,0x3c,0x07,0x05,0x87,0x2b,0xf9,0x58,0x74,0xc7,0x61,0x13,0x3d,0xc2,0xd9,0xec,0x3b,0x36,0x9f,0x8e,0xae,0x52,0xdd,0x5c,0xaa,0x29,0x6b,0x31,0x34,0x48,0x61,0x34,0x62,0x56,0xce +.byte 0x25,0xa8,0xc0,0x62,0xf5,0x35,0x58,0x4d,0x8e,0x61,0xd4,0xae,0x25,0x50,0xee,0x45,0xdd,0x14,0x7d,0x46,0x81,0x47,0xc3,0x3f,0x3f,0x81,0xdb,0x9a,0x59,0x56,0x4f,0x45,0xed,0x9c,0xe2,0xfc,0x96,0xff,0x5d,0x37,0x70,0xad,0xd2,0xeb,0xd9,0x2d,0x2a,0xaf,0xb9,0x16,0x4a,0x79,0x5d,0x76,0xb5,0x8f,0x74,0x19,0x6f,0x74,0x7d,0x4a,0xee,0x83 +.byte 0xa5,0x81,0xf3,0xd5,0xa0,0x43,0x5e,0x46,0xba,0xbe,0x49,0xa8,0xce,0x72,0x36,0x32,0xcd,0x8c,0x9b,0xa0,0xf9,0x5d,0xb7,0xb9,0xc7,0x8c,0xb2,0x59,0xb4,0x44,0xc1,0x90,0x53,0x92,0xd2,0xa8,0x4c,0xf9,0x35,0x40,0x32,0xd1,0xf0,0x2f,0xcb,0x6a,0x0b,0xe0,0xbe,0x34,0xc9,0x82,0x18,0x8d,0xfb,0xfc,0x50,0x8d,0x67,0xd5,0x86,0xd4,0xf1,0xb1 +.byte 0xaa,0x2f,0x9c,0xbc,0x52,0xbb,0x9f,0x17,0x1c,0x74,0x1d,0xdf,0x2d,0x1a,0x94,0x43,0x9b,0x80,0xb9,0x48,0xa3,0xaf,0x4b,0x30,0x0d,0xd9,0x3f,0x11,0x48,0x79,0x60,0xcc,0x25,0x6a,0xdb,0x8a,0xda,0xab,0xda,0x09,0x7c,0x9c,0x4a,0xaf,0xf9,0x0d,0xfb,0x7a,0x92,0x61,0xa5,0x17,0xf8,0x79,0x1b,0x00,0x52,0x56,0x5e,0x27,0x22,0x37,0xf4,0xbe +.byte 0x52,0x36,0xd3,0xdc,0x9a,0x33,0xf5,0x44,0x0e,0x53,0x0b,0xf6,0x9b,0xb0,0xb6,0x11,0xe4,0xd5,0x45,0x2e,0xdc,0xdb,0x46,0x18,0x9a,0x90,0x8b,0xcc,0xfe,0xc6,0x94,0x4f,0x97,0xb9,0x42,0xb6,0xd3,0x8f,0x7c,0x20,0xd1,0xa8,0xe6,0x85,0xce,0x65,0xeb,0x95,0x38,0x11,0x5c,0x1a,0x9d,0x34,0x25,0xc2,0xf0,0x33,0xbb,0x2c,0xc9,0x8d,0x0a,0x7a +.byte 0xb1,0x90,0x9f,0x24,0xed,0x35,0x3c,0x7e,0x71,0x82,0x12,0x3a,0x79,0x29,0xc8,0xa7,0x3e,0xa2,0x4e,0x50,0x03,0x94,0x7a,0x94,0xb7,0x2b,0x61,0x95,0x3d,0x5e,0x60,0x1c,0x68,0x51,0x82,0x73,0xe0,0x4a,0x2a,0x48,0x26,0xda,0xa3,0x53,0x8c,0x83,0xba,0x9f,0x95,0x37,0x5e,0x68,0x54,0x19,0x21,0xf8,0x31,0xaf,0x6b,0xfc,0x3a,0x3e,0xe3,0x3f +.byte 0xdb,0x16,0xb5,0x7e,0x13,0xf8,0xfd,0x7f,0x36,0xd6,0x8e,0x33,0xaa,0xe9,0xa4,0xa7,0xfd,0xf0,0x32,0xa6,0xdf,0xfa,0x22,0x7d,0xff,0x2a,0xe6,0x0d,0x6f,0xe2,0x21,0x54,0x6c,0x1a,0x99,0x17,0x56,0xad,0xce,0x39,0x6b,0x1a,0xe8,0x27,0x13,0x12,0x9c,0x4b,0x84,0x69,0x73,0xde,0x44,0x14,0xb2,0x7c,0x44,0x54,0x91,0x4f,0xeb,0x83,0xec,0x04 +.byte 0x73,0x85,0xb1,0xa8,0x44,0x72,0xa7,0x77,0xaf,0x0c,0xe0,0x52,0x65,0x04,0xe7,0x2a,0xee,0x0c,0x20,0x83,0x32,0x34,0x17,0x00,0x61,0xf9,0xf5,0x42,0x03,0xa4,0xb8,0x02,0x6f,0xb2,0xd3,0x65,0x51,0x2a,0x8e,0xdf,0x28,0x78,0x8a,0x8a,0x00,0xfb,0x24,0xd6,0xd5,0x86,0xaa,0xfb,0x86,0x93,0x5d,0x11,0xa4,0xf3,0xfd,0x36,0x18,0xf3,0x61,0xea +.byte 0x33,0xa8,0x0c,0xf0,0xb4,0x68,0xee,0xd3,0xe3,0x4f,0x22,0x24,0xde,0x1f,0x29,0x84,0x8b,0x5b,0x73,0x15,0xd6,0x62,0xa3,0x71,0x7d,0xf0,0x65,0x36,0xca,0x68,0x8a,0x6d,0x61,0x9c,0x0d,0x53,0xdd,0xf4,0x12,0xb3,0x5f,0xf0,0xb1,0x86,0xd6,0xe2,0xd6,0x80,0x4a,0x01,0x09,0x99,0x65,0xdb,0xae,0xe6,0xfc,0x68,0x5b,0xf9,0x10,0x99,0x8b,0x9f +.byte 0x08,0x52,0x09,0xae,0x59,0x4d,0x6c,0xf9,0x91,0x2b,0x57,0xea,0xf0,0xa3,0xdb,0xb8,0x99,0x29,0x2f,0xab,0x95,0x01,0x7d,0xec,0xd8,0x77,0x73,0x75,0x4f,0x88,0x44,0x69,0x76,0xc9,0x3c,0xf0,0x2d,0x7b,0x0d,0xbe,0xd4,0x88,0x0d,0xbc,0xa0,0x52,0xf4,0x2a,0xd1,0x62,0x2a,0xa9,0xe2,0x41,0x2f,0x52,0xce,0x96,0x7d,0x65,0x9b,0x74,0x82,0xde +.byte 0x43,0x4d,0xf8,0x8e,0x77,0x1c,0x18,0xf5,0x7e,0xab,0x94,0x3e,0xe7,0x90,0x2b,0xa1,0x16,0x00,0x7f,0x9c,0x9d,0x86,0xd1,0x74,0x7e,0xf7,0xbd,0x5a,0xa7,0x2f,0x0f,0xb0,0x5c,0xfc,0xfb,0x59,0x00,0xf3,0x84,0x09,0x77,0x66,0x17,0xf6,0x5d,0x0e,0xe2,0xe2,0xd4,0xb3,0x9e,0x79,0x88,0x66,0xa5,0x8e,0x30,0xae,0xca,0x7e,0x2b,0x32,0xa2,0x89 +.byte 0xe9,0x7e,0x59,0x21,0xd5,0x99,0xc7,0x10,0xa8,0x6f,0x95,0x8d,0x84,0xb4,0xcf,0x61,0xe7,0x5c,0x09,0xf3,0xbc,0xeb,0xf6,0x0c,0x84,0x1a,0x8d,0x13,0xf8,0x49,0x22,0xeb,0x09,0x55,0xef,0x56,0x12,0x21,0xcb,0x61,0x87,0xbf,0xef,0x43,0x5b,0x82,0xa8,0xc2,0xa2,0x5e,0xad,0x54,0x9a,0xcc,0x95,0xa2,0x01,0x05,0xb2,0xbb,0x26,0xa8,0xfd,0x6b +.byte 0x66,0x95,0x9c,0x0b,0x7b,0x23,0x32,0xff,0xdd,0x6c,0x18,0x1e,0x77,0x01,0x3c,0x82,0xaa,0x97,0x28,0x0f,0x93,0xa5,0x6c,0x85,0xe5,0x94,0x40,0xe0,0xa3,0x01,0x57,0x56,0x43,0x40,0xdd,0xa9,0xaf,0x21,0x79,0x10,0x8b,0xff,0x4b,0x51,0xe4,0xa2,0xe5,0xd7,0x0c,0xe2,0x9e,0x1e,0x38,0xdb,0x64,0xe1,0xb1,0x5b,0xe5,0x40,0xab,0xf6,0x05,0xd2 +.byte 0xba,0x85,0x78,0x61,0x2d,0x2e,0x07,0x06,0x6d,0x86,0x59,0xaa,0xd9,0x2c,0xfb,0x83,0x34,0xd0,0x2d,0x1d,0xad,0x5f,0xe4,0xac,0x05,0x46,0x3a,0x7b,0xd9,0xef,0x9f,0x2b,0x0c,0x18,0x21,0xf1,0x24,0x8a,0xb4,0x6e,0xd2,0x98,0x75,0x08,0x96,0x0c,0x7b,0x41,0xb7,0xf7,0x1f,0xcd,0xa8,0x1f,0x44,0xb1,0xed,0xdc,0x0e,0xcb,0x94,0xa0,0xb8,0x62 +.byte 0x67,0xdc,0x24,0xde,0x9e,0xe9,0x89,0xcd,0x92,0x7c,0x91,0x15,0xff,0xbd,0xfd,0xee,0xf8,0x29,0xd7,0xf9,0xe8,0x51,0xe7,0xc8,0x21,0xc5,0x20,0xe4,0xb8,0xa6,0xdb,0xfb,0x09,0x65,0x1c,0x3b,0x9e,0x39,0x44,0xcf,0xf5,0xc2,0x7b,0xf3,0x14,0x7d,0x69,0xf2,0xd0,0x97,0x63,0xf1,0xa7,0x81,0x56,0xfb,0xdf,0x4d,0x83,0x55,0x4f,0xde,0x50,0x7d +.byte 0xfe,0xb0,0xc0,0xc8,0x3b,0x3d,0x78,0x74,0x58,0x74,0x5e,0xfc,0xb7,0x0d,0x9a,0x26,0x3b,0x39,0xb6,0xf7,0xe0,0xe4,0x12,0x3c,0xd6,0x88,0x1c,0x9b,0x51,0x89,0xe7,0x53,0xcd,0x24,0x2e,0x34,0xa2,0xee,0xfa,0x5a,0x87,0xe5,0x7e,0xd5,0xf2,0x2f,0x15,0x99,0x57,0x5d,0x31,0x02,0xf8,0x08,0x38,0xea,0x8c,0x30,0x21,0xb0,0xff,0x94,0x51,0xcf +.byte 0x23,0xb7,0x02,0x5d,0xa3,0x75,0x7f,0x9d,0x66,0x49,0xe5,0xbe,0xc7,0x06,0x5e,0x1d,0xc9,0xe2,0x82,0x8a,0xc4,0x17,0x83,0x7e,0x65,0x6d,0x85,0x26,0x66,0xc0,0xf4,0xa5,0x1c,0x6e,0xba,0x32,0xfa,0x41,0x7b,0x2b,0x64,0x98,0x58,0x8c,0xce,0x2f,0xf3,0x56,0xf0,0x67,0xef,0x73,0x79,0xc4,0xc2,0x07,0xd7,0x85,0x1d,0x75,0x38,0x1e,0x15,0x82 +.byte 0x9d,0xf3,0xdd,0x3a,0x72,0xa3,0x23,0x0e,0x4a,0x1a,0x3a,0x97,0xc8,0xf1,0xf1,0x58,0x5d,0x1f,0xae,0x6d,0xc8,0x03,0xe0,0x7b,0x0f,0xf5,0x6f,0x35,0x41,0x8d,0xd5,0x03,0x85,0xdd,0xeb,0x3d,0x73,0xb1,0x93,0x35,0xc0,0x0f,0xfb,0x42,0xd4,0xf1,0x6b,0x35,0xe2,0x96,0xc5,0xd9,0xf2,0x69,0xbb,0x70,0x5e,0xf0,0x0c,0xe6,0xb5,0x81,0x94,0xc9 +.byte 0x29,0xa1,0x34,0x89,0xd9,0x9c,0x49,0x01,0x37,0x56,0x16,0x30,0x47,0x6f,0xe4,0x7c,0x5b,0xdd,0xfb,0x80,0x7f,0x0c,0x38,0x53,0x3d,0x57,0xf7,0xc4,0x80,0xf9,0x12,0x3a,0x9f,0xf9,0xb0,0xb6,0x94,0x6d,0xde,0x41,0x4e,0x30,0xac,0x1f,0x25,0x34,0xa0,0x95,0xe8,0x00,0x86,0x32,0x40,0xbb,0xc1,0x49,0x2d,0x07,0x49,0xb8,0x5f,0xcd,0x1b,0xd3 +.byte 0x0e,0x0c,0x54,0x0f,0xe4,0x20,0xe5,0xa1,0xed,0x98,0x65,0x5a,0xe7,0xce,0x68,0x9c,0x4c,0x48,0x03,0x9c,0x5b,0x68,0x4b,0x75,0x71,0x11,0x40,0x69,0xca,0x9a,0x3a,0xb2,0x3d,0x35,0x2c,0x70,0x35,0x8b,0x80,0x53,0x86,0x30,0x7d,0x4c,0xe9,0xc0,0x30,0x60,0xd0,0x06,0xbe,0xc2,0xad,0x39,0xcc,0xb2,0xec,0x90,0xcc,0xbd,0x7c,0xb5,0x57,0x20 +.byte 0x34,0x2e,0xfc,0xce,0xff,0xe3,0xd9,0xac,0xb8,0x62,0x6b,0x45,0x22,0x34,0xdf,0x8e,0x4b,0xf1,0x80,0x28,0x8d,0x0f,0xd5,0x3b,0x61,0x3e,0x91,0xa1,0xb1,0x85,0x27,0x78,0x88,0xbc,0xc4,0xb1,0xa1,0xbe,0x4f,0xc3,0xfd,0x1f,0xb9,0x30,0x31,0x2f,0xc1,0x9d,0xa3,0xb6,0x29,0xa4,0x60,0x82,0x73,0x93,0x74,0xea,0x97,0x67,0xf2,0xa3,0x97,0x50 +.byte 0x2f,0x9f,0x7b,0x23,0x18,0xb6,0xb4,0xee,0x15,0xa0,0xa4,0x07,0x1a,0xe9,0xb6,0x63,0x7e,0x88,0x40,0x57,0x86,0x79,0x6b,0x75,0xbe,0x57,0x8f,0xfe,0x0d,0xdf,0x4c,0x7f,0x39,0x9a,0x97,0xa6,0x87,0xc5,0xfd,0x52,0x77,0x36,0xc9,0x66,0x63,0xcf,0xc7,0x34,0x3b,0xf4,0x7a,0x12,0x56,0xf0,0xbc,0x7a,0x1a,0xa2,0xa2,0x51,0xb8,0xc1,0x70,0x81 +.byte 0xcf,0x1d,0xb5,0xe2,0x82,0xbb,0xfc,0xa3,0x80,0x18,0xf8,0x4b,0x76,0x9c,0xdf,0x9d,0x6c,0xf1,0xd8,0x2a,0xab,0x0c,0x12,0x02,0x29,0x09,0xfd,0x28,0xfb,0x57,0x38,0x05,0x2c,0xc5,0x67,0xd1,0xaa,0xbc,0x98,0xe6,0x22,0x78,0x06,0x4f,0x69,0x6a,0x63,0x1a,0x13,0x0b,0xa5,0xd2,0x61,0xc7,0x45,0x5b,0x21,0xab,0xbf,0x7b,0x7f,0x8c,0x2c,0xba +.byte 0x93,0x9f,0x41,0x67,0xc4,0x5f,0x53,0xac,0x90,0x05,0x86,0xb5,0x80,0x1f,0x5b,0x35,0x4f,0x92,0xf5,0xa8,0x5f,0xfb,0x56,0xdd,0x2d,0x9b,0xea,0xcb,0x0f,0x98,0x3c,0x4e,0xf1,0xa5,0x2c,0x37,0x70,0xe3,0x5c,0xaf,0x96,0x36,0xa8,0x2a,0xec,0xe0,0x2c,0x00,0xcd,0xaf,0x03,0x1d,0x05,0x2f,0x8c,0xe7,0xfe,0x4d,0xe9,0x97,0x6d,0xe1,0xf9,0x23 +.byte 0x60,0x08,0xea,0xfb,0x27,0xc8,0xf9,0xdf,0x49,0xfe,0xd9,0x48,0x35,0x6b,0x43,0xc5,0x19,0x90,0xb1,0xf1,0xee,0x84,0x7a,0x57,0xfa,0xa5,0xd6,0xd8,0xc9,0xf0,0x8a,0xe7,0x13,0x84,0xfc,0x28,0x54,0xae,0x99,0xfd,0x91,0xbe,0x91,0x27,0x98,0x28,0xdc,0xd7,0x2e,0xc1,0x21,0xcb,0x31,0xf8,0x47,0xe6,0x77,0x6d,0xee,0x7b,0x12,0xe4,0x9e,0x9d +.byte 0x07,0x46,0xa9,0x15,0x0b,0x3c,0xbe,0xc7,0x2d,0xe5,0xd6,0x25,0x4c,0xea,0x61,0xdc,0x18,0xb2,0x9d,0xb0,0x9a,0xff,0xa3,0x5f,0x2b,0xab,0x52,0x7d,0x1b,0xc3,0xa3,0x41,0x8f,0x5a,0x29,0xbd,0xc4,0x56,0x54,0x43,0x2d,0x61,0x07,0xed,0xd1,0x81,0x45,0xdb,0x61,0x0f,0xda,0xea,0xa6,0x1e,0xf9,0x9c,0xc0,0x8c,0xc4,0x8e,0xc7,0xca,0x38,0xe2 +.byte 0x45,0xde,0xdc,0xc5,0xc6,0xb0,0x43,0x17,0x8b,0xb1,0x58,0xd1,0x10,0x8e,0xa5,0x17,0x37,0x85,0xca,0x61,0x67,0x5c,0xd0,0x72,0x22,0x6b,0xd3,0x3b,0x53,0xbc,0xfb,0xe1,0x1e,0xa4,0x1b,0xd3,0xc3,0x8a,0x50,0x03,0x39,0xf5,0x36,0xdf,0x51,0x2e,0x05,0x4a,0xa8,0xdb,0x91,0x87,0xae,0xfe,0x3f,0x5c,0x35,0x5e,0xf9,0x8f,0x43,0x9e,0x92,0x36 +.byte 0x91,0x27,0x90,0xe8,0x7c,0xcc,0xc4,0x9c,0x13,0xbb,0x61,0x40,0xec,0x4f,0x49,0xcf,0x04,0x38,0x77,0x3b,0xb5,0xf8,0x69,0x8d,0xbb,0xb2,0x30,0x32,0x42,0x4d,0x7d,0x6c,0x56,0xdc,0xf4,0x8f,0xfc,0xb8,0x53,0xc5,0x11,0x17,0x23,0x94,0xf9,0x6d,0x6f,0xee,0xee,0x31,0xbf,0xce,0x11,0x8b,0x9e,0xd7,0xa5,0x09,0x36,0x89,0x72,0x25,0x18,0x1f +.byte 0x13,0xa7,0xdf,0xc5,0x91,0x7e,0xd6,0x2b,0xb8,0x08,0x9c,0x12,0x83,0x21,0x97,0x3d,0xad,0xac,0x1c,0x54,0xf3,0x65,0x04,0x2f,0x09,0xd1,0xd2,0xe5,0xce,0x24,0xb1,0xd9,0xe4,0x38,0x1f,0xb4,0xce,0xea,0x27,0x7f,0x5f,0x16,0x52,0xa4,0x2f,0x2f,0xaf,0x91,0xec,0x7a,0x21,0xf7,0xa1,0x38,0x78,0x78,0xc5,0xa9,0x94,0x63,0x87,0xf8,0x95,0x9e +.byte 0xf9,0x82,0x98,0x6d,0x9d,0x48,0x80,0xaa,0x7a,0x36,0xf9,0x5f,0xfb,0x39,0x3d,0xae,0xbc,0xcd,0xfc,0x67,0x46,0x07,0x7e,0xdf,0xef,0xff,0x8d,0x67,0xe7,0xd9,0x60,0x90,0x7b,0x49,0x10,0x65,0x3a,0x60,0x87,0x7a,0xed,0x9a,0x44,0x48,0x81,0xcc,0xad,0xe4,0x6a,0x62,0xf8,0x02,0x6f,0x41,0x8a,0x8d,0x44,0x28,0x1a,0xb8,0x52,0x60,0x4b,0x3f +.byte 0xfc,0xdd,0x33,0xad,0x14,0xb1,0x34,0x63,0x1f,0xdc,0xeb,0x9a,0x3f,0x99,0x82,0x28,0x36,0x6f,0x8e,0xd7,0x39,0x2e,0xc0,0x37,0xfb,0xad,0x57,0x6c,0x82,0x1a,0xc6,0xe4,0x4b,0xca,0x00,0x68,0x57,0x34,0xf0,0x57,0x6a,0xcb,0x50,0x5d,0x8d,0xfa,0xcd,0x89,0x41,0x91,0x23,0x98,0x1f,0x4f,0x18,0xb6,0xd2,0x9d,0xde,0x2f,0x5c,0xe6,0x08,0x76 +.byte 0x97,0xba,0x24,0x4e,0x84,0xd7,0xeb,0x80,0xde,0xec,0xee,0x51,0x5a,0x0e,0x5f,0xb7,0x37,0xda,0xa5,0x94,0x2b,0x6d,0x73,0xb7,0x6c,0x22,0x95,0x3a,0xaa,0x5c,0x6f,0x89,0x90,0xec,0xb3,0x31,0x00,0x37,0x28,0x18,0xbb,0x98,0x23,0xfc,0x3e,0x21,0x7c,0xaa,0x44,0x54,0x7b,0xe6,0xa0,0x17,0x58,0xef,0x11,0x3f,0x48,0xb8,0xa8,0x15,0x4a,0x92 +.byte 0xa9,0x39,0xe2,0xa6,0x38,0x03,0xa6,0xd3,0x79,0x8b,0x38,0x06,0xaf,0x4b,0xd4,0xab,0x0a,0x13,0xff,0x2d,0xfa,0xab,0x4b,0x64,0x9e,0xb0,0x3d,0xba,0x18,0x01,0xfd,0xc3,0x6a,0x6f,0x21,0x9c,0xf5,0x2f,0xab,0x2d,0x42,0x12,0xc9,0x72,0xde,0x83,0x42,0x6a,0xf0,0xd4,0x96,0x73,0xf1,0x93,0xa3,0x2d,0x9b,0xb4,0x94,0x51,0x0c,0x6e,0x8e,0xf0 +.byte 0x5e,0xbf,0x98,0xbf,0x08,0x0f,0xd8,0x6c,0x65,0x4e,0xb5,0x47,0xeb,0x7c,0x1b,0x73,0xe0,0xe6,0x2c,0x03,0xd2,0x2a,0x32,0xff,0xa7,0x03,0x6d,0x38,0x47,0x56,0x4b,0x25,0x0b,0x39,0x73,0x87,0x4b,0xa5,0x12,0x79,0x79,0xf3,0x88,0x37,0xe2,0x4f,0xb8,0xbf,0x70,0x0e,0xf7,0x8c,0xe6,0xa3,0xbc,0x35,0x10,0xcd,0x72,0x56,0xd6,0x83,0xc1,0x0b +.byte 0x5b,0xf3,0xa8,0x74,0xc7,0xb9,0x84,0xc8,0x6c,0xff,0x66,0xad,0x95,0x6f,0xbc,0x82,0x84,0x2a,0x11,0x40,0xf9,0xa8,0x3f,0x05,0xf9,0xab,0x19,0x55,0xce,0x80,0x90,0x65,0x49,0x3d,0xe1,0x54,0x2c,0x1a,0xdb,0xf3,0xaa,0x2f,0xeb,0xf5,0x10,0x1f,0x8c,0x35,0x46,0x68,0xb1,0x4c,0x52,0xe7,0xe9,0x58,0x78,0x33,0xfd,0xc6,0x13,0x0e,0x69,0xae +.byte 0xf4,0x1a,0x8a,0x77,0x8f,0xcc,0x98,0x74,0x88,0x20,0x84,0x5b,0x83,0x54,0xa9,0xee,0xc2,0x0f,0x8a,0x46,0xb1,0xc7,0xfb,0xfd,0xf2,0x2c,0xaf,0xfa,0x72,0x34,0x7a,0x79,0x50,0x10,0xc6,0x04,0xfd,0x0a,0x1e,0x4a,0xb5,0xf5,0xe7,0x4d,0x98,0x80,0x5d,0x0b,0x81,0x23,0xc3,0x6e,0xbf,0xc8,0xcd,0x35,0x96,0x5a,0x58,0xec,0xef,0x6a,0x8d,0x48 +.byte 0xda,0x48,0xbb,0x8f,0xcc,0x1f,0x86,0xff,0x7a,0x27,0xef,0xe6,0xb7,0xc7,0x2a,0x47,0x8d,0x6c,0x4a,0xc6,0x0a,0x32,0x67,0x1d,0x2f,0x83,0x3d,0x46,0x41,0x46,0x1c,0x75,0x7b,0x29,0x89,0xa2,0x65,0x9b,0x53,0x3d,0xd9,0x90,0x83,0xce,0xab,0x07,0xbb,0x46,0x61,0xb1,0x54,0xbd,0xc9,0x98,0xf7,0x96,0x76,0x03,0xdc,0x1f,0x1b,0xf2,0x5c,0x07 +.byte 0xdd,0x24,0x94,0x72,0x1e,0x94,0xb1,0x14,0x0b,0x40,0x77,0xde,0x3d,0x3f,0x1c,0xf0,0x8f,0xa4,0xcb,0x34,0xb5,0x2b,0x72,0x53,0x78,0xf3,0x3f,0x8e,0x47,0x30,0xb2,0x7e,0x73,0x3f,0x9a,0xef,0x19,0xb1,0xef,0x82,0x99,0xd4,0x17,0x60,0x94,0xf6,0x15,0x75,0x50,0x1f,0xb3,0xdd,0xae,0x1f,0xf8,0x63,0x9a,0x30,0x2c,0xf0,0xdd,0xbf,0x49,0x70 +.byte 0xd7,0x86,0x4a,0x5c,0x46,0x10,0x48,0x46,0x02,0x18,0xa4,0x39,0xb6,0x75,0x11,0x21,0xae,0x62,0x64,0xd8,0x85,0xc8,0xda,0xd2,0xd6,0x69,0xcc,0x37,0x57,0x49,0x73,0x1a,0x10,0x7b,0xd7,0x58,0xdd,0x0b,0xf3,0x16,0xe7,0x62,0x2c,0x32,0x92,0x0e,0x70,0x6f,0x77,0x74,0x0d,0xff,0xc2,0x8d,0x3b,0x3f,0x29,0x28,0x8f,0x88,0xb8,0x02,0x5b,0x3a +.byte 0x8b,0x65,0x89,0x92,0x2f,0xc7,0x30,0x73,0xc3,0x20,0xbc,0xa4,0xe4,0x5e,0xea,0xf8,0x21,0xb6,0xc5,0x47,0x56,0x35,0x8f,0xf6,0xd5,0xdd,0x77,0x1d,0xdf,0xd0,0x27,0xa3,0x04,0xb9,0xd0,0xc4,0x28,0x16,0xa5,0xaf,0x47,0x55,0x85,0x93,0x38,0xf4,0xac,0x13,0x30,0x7d,0x77,0x1f,0x3d,0xd5,0xd7,0x22,0xbe,0xe2,0x4e,0x6d,0x4b,0x0e,0xbe,0x1d +.byte 0x43,0x79,0x34,0x95,0x6f,0x38,0xa1,0xb3,0xa0,0xed,0xf6,0x17,0xf4,0x24,0x70,0x26,0x18,0x3e,0x1c,0xde,0xdc,0xa9,0x67,0x12,0xd3,0xc8,0xd7,0x70,0x13,0xa5,0xb3,0x25,0xe1,0x0a,0xe9,0xf6,0x4e,0x56,0x82,0x17,0xdc,0xbc,0x96,0x2f,0x59,0x03,0x9b,0xf4,0xc3,0x66,0xd2,0x90,0x95,0x1d,0xe0,0x99,0xfb,0xd8,0xa8,0x14,0xc7,0xa6,0x12,0x6b +.byte 0x08,0x6a,0xc8,0x0f,0x34,0x2a,0xb6,0xc4,0x9a,0xcd,0x61,0xf7,0x61,0xa3,0x59,0x29,0x11,0x30,0x76,0xb5,0x97,0xbc,0x2f,0x87,0xd8,0x12,0xb3,0x1d,0x99,0x8d,0x5d,0x57,0x0c,0xda,0xb0,0x9f,0x51,0x1a,0xb5,0xc6,0x94,0xc3,0xe9,0x5a,0x72,0x0c,0x37,0x76,0xb6,0x3c,0x00,0x02,0x69,0xad,0x8e,0x66,0x8b,0x5c,0x13,0x48,0xb7,0x9e,0xc5,0x7e +.byte 0xe0,0x35,0x07,0xd2,0x04,0x9c,0x35,0x95,0x8b,0x55,0x87,0x03,0x32,0x36,0xeb,0x11,0x88,0x54,0x8d,0x3e,0x88,0x46,0xc2,0xfe,0x24,0xa4,0x4b,0x92,0x19,0x44,0x6c,0xc9,0x69,0x32,0x22,0x95,0x5b,0xda,0x58,0xa4,0x00,0x33,0x83,0x2d,0xa4,0x17,0x2e,0x00,0x4d,0x9a,0x7d,0xef,0x04,0xa8,0x8b,0xf2,0x7c,0xb9,0xdb,0x54,0xcf,0x63,0x14,0x52 +.byte 0x5b,0x79,0xf6,0x89,0x5c,0xfa,0x8a,0x85,0x88,0x7f,0xca,0xed,0xfb,0x62,0xbc,0x1d,0x0d,0x90,0x51,0x27,0x45,0x74,0xa0,0x55,0xfc,0x60,0xea,0xef,0x6e,0x40,0xeb,0x0b,0x61,0x45,0x44,0xee,0xb6,0x20,0x4c,0xe1,0x08,0x62,0x29,0xdd,0xd0,0xa1,0xd5,0x7f,0x42,0xb9,0x0f,0x12,0xef,0xfb,0x13,0xa2,0xf1,0x85,0xaa,0x56,0x18,0x6c,0x70,0x7a +.byte 0x4d,0x52,0x76,0xce,0xa9,0xed,0x0a,0xcc,0x55,0xf0,0x01,0x99,0x44,0xe9,0xc4,0x74,0x33,0x2a,0xce,0x53,0xf3,0x4f,0x8f,0x1c,0x67,0x39,0x2b,0x0e,0x46,0xe2,0x49,0x06,0x52,0xbf,0xc4,0x3f,0x93,0x84,0x46,0x0a,0x9b,0xcb,0x1d,0xa5,0x66,0x9c,0x3e,0x3d,0xd1,0x92,0xda,0xe2,0x11,0x5b,0x89,0x7a,0xc4,0x33,0xba,0xa9,0x19,0xfd,0x3c,0xe3 +.byte 0xf0,0xa0,0x9b,0x83,0x50,0xce,0xa9,0x62,0xe3,0x85,0xc6,0xc4,0xe5,0x22,0xbb,0x1a,0x8e,0x04,0xb5,0x4d,0xca,0x18,0x7d,0xb0,0x99,0x50,0x78,0x88,0x69,0x43,0xe0,0xfd,0x90,0xa6,0xbf,0xdc,0xe3,0x03,0xf2,0x5d,0xa1,0xa2,0x88,0xc7,0xab,0xa9,0xc2,0xda,0x3f,0xff,0x79,0xa6,0x07,0xfd,0xc4,0xb1,0xfb,0x47,0x3d,0x75,0x82,0x26,0x52,0x85 +.byte 0x3f,0xf9,0xc9,0x85,0x46,0x24,0xe9,0x0f,0x96,0x8c,0xbb,0x02,0x83,0x60,0x69,0x49,0x8c,0x38,0xd1,0x4e,0xd0,0x63,0x2c,0xb6,0x12,0xb2,0x8e,0x4b,0xd3,0xe3,0xdf,0x20,0x00,0x99,0xf1,0x06,0x93,0xbf,0x27,0x42,0x8b,0xe3,0x8d,0x4c,0x3b,0x05,0x62,0x64,0x21,0xb1,0xfe,0xce,0x08,0xd2,0x23,0x69,0x11,0x74,0x31,0x3a,0x90,0x10,0x07,0x1a +.byte 0xd5,0xf5,0xc2,0x09,0x61,0x67,0x65,0x99,0x3a,0xf3,0x9e,0x4a,0xd8,0xa1,0xb2,0x50,0xf4,0x07,0xf0,0x7b,0x89,0x6d,0x4d,0x6a,0xd4,0x54,0xb9,0x3c,0xd5,0x4e,0x1c,0x12,0x0f,0x19,0x92,0x97,0x21,0x65,0x83,0x33,0x20,0x92,0x95,0xd4,0x0e,0x78,0xf4,0x92,0x16,0x36,0xd8,0x1b,0xd8,0xbf,0x41,0xe4,0xfb,0xb9,0x81,0x26,0x72,0x7e,0x1b,0x58 +.byte 0x05,0x45,0x97,0x66,0xf2,0x23,0x16,0xca,0x4e,0x95,0xc2,0x6c,0x60,0x84,0x5f,0x77,0x82,0x44,0x0e,0xf7,0x30,0xaa,0x51,0xa9,0x85,0x8b,0x03,0xfc,0x3d,0x6d,0x66,0x91,0x37,0xa5,0x1c,0xf8,0xcf,0x9d,0xd8,0xcd,0x8c,0xa1,0x29,0xbd,0xb5,0x4f,0x47,0xba,0xd1,0x55,0x3b,0x4e,0xc9,0xce,0x4c,0xcf,0x2e,0x19,0xa0,0x95,0xe6,0xcb,0x36,0x97 +.byte 0x3e,0x23,0xbe,0x09,0xfd,0x38,0x47,0x00,0x03,0xec,0x49,0xbb,0x49,0x1f,0x45,0x84,0x0f,0x1e,0x74,0xab,0xc9,0x07,0x00,0x04,0x70,0xe9,0xbd,0x61,0xb1,0x92,0xee,0x67,0x9a,0x5e,0x90,0xdc,0xe7,0x99,0x36,0xd0,0x58,0x15,0xe5,0x15,0xa2,0x1d,0x61,0x18,0x39,0x5f,0x6c,0xc7,0xbe,0xd0,0x23,0x1e,0x41,0xc8,0xaa,0x8e,0xbf,0xb8,0xdb,0x90 +.byte 0x8c,0x60,0x07,0x1e,0xe9,0x6c,0xe4,0xde,0xec,0x73,0x34,0x94,0x54,0xa4,0x6b,0x49,0xcf,0x87,0xb5,0x88,0x98,0xe6,0x2c,0xce,0xb7,0x76,0xa5,0x29,0xf1,0x29,0x50,0xc5,0x9e,0x13,0xe4,0x61,0x6a,0x54,0xb2,0x26,0xfa,0xfa,0x4a,0x41,0x3b,0x0a,0xf5,0x9a,0x60,0xbb,0xfc,0x1e,0x5d,0x21,0x7e,0x91,0x51,0xd6,0x5e,0x92,0xf9,0x21,0x80,0xa8 +.byte 0x35,0xc0,0xbb,0x7a,0xeb,0x75,0xb4,0xa3,0xd3,0x8d,0xaf,0x07,0x53,0x65,0x36,0x11,0xf9,0xb6,0x69,0x29,0x1e,0x5d,0x8f,0x57,0x5d,0xed,0x42,0xf9,0xd5,0xf6,0xc3,0x1e,0x29,0xc4,0x49,0x04,0xe4,0xfb,0xbf,0x9b,0x4a,0x7b,0xdd,0x57,0x51,0xfe,0xc4,0xd1,0xd9,0xe9,0x8f,0x94,0x78,0xbc,0x5c,0xeb,0xb6,0xbc,0x51,0xb0,0x82,0x87,0x47,0xb4 +.byte 0xf7,0xf9,0x02,0xd7,0xac,0x23,0xc0,0xe5,0x9a,0xc3,0x2f,0xd2,0xb8,0xb2,0x62,0xb9,0xdb,0x49,0x85,0x77,0x92,0xa6,0xe5,0x24,0x43,0x4d,0x0d,0x67,0x94,0x01,0x29,0xd6,0x2e,0xee,0xd9,0x2e,0x97,0x0e,0x20,0x7f,0x84,0x19,0x3c,0x3a,0x6f,0xa5,0xb0,0x8b,0x8f,0x8d,0x96,0xbb,0x76,0x61,0x97,0xc2,0x65,0x83,0xd8,0xda,0xab,0x42,0xfa,0xe5 +.byte 0x1e,0x42,0x93,0xa7,0x66,0x03,0x06,0x3b,0xbe,0xb8,0xae,0x71,0xee,0xdb,0x5d,0xdf,0x40,0x64,0x17,0x17,0x2e,0x03,0xca,0x37,0x2a,0x71,0x92,0x0a,0x01,0xa3,0x0f,0x0b,0x09,0xf2,0x0e,0x4b,0x4d,0x18,0xf3,0xc4,0xf2,0x51,0x7b,0x53,0x30,0xab,0x24,0xa2,0x47,0x38,0xc9,0x2c,0xdf,0x0d,0x32,0x3e,0x3f,0x57,0x2d,0xfc,0x44,0x19,0x64,0x8b +.byte 0xe9,0x9a,0xc2,0xf2,0xf6,0x2d,0x30,0x0c,0x0f,0xc3,0xc3,0xfe,0xc2,0xd1,0xbc,0xe0,0xbf,0xaf,0xeb,0x40,0x64,0x28,0xe2,0xd9,0x3c,0x7e,0x24,0x94,0x8f,0xe8,0x54,0x8b,0x26,0x6b,0xe1,0x4e,0x44,0x5a,0x7d,0x7b,0x12,0x36,0x2c,0x12,0xad,0x26,0xbc,0xa7,0xa3,0x2b,0x25,0xb9,0xde,0xe6,0x64,0x2d,0xab,0x7f,0x15,0x22,0x51,0x26,0x1c,0x15 +.byte 0x5d,0x13,0x18,0x93,0xc1,0x19,0x65,0xca,0xf3,0x8b,0xe0,0xcf,0x8c,0x43,0xe9,0xfd,0xa1,0xbd,0xe9,0xde,0x78,0x26,0xcb,0x7c,0xdc,0x68,0x06,0x98,0xf6,0x90,0x44,0x40,0xf0,0x5e,0xe1,0x16,0xf5,0x5d,0x4d,0x9b,0x85,0xe6,0x26,0xbd,0xab,0xcc,0x46,0x62,0x18,0x51,0xd5,0x3c,0x9f,0x6e,0xfa,0xe7,0x94,0xfc,0xc2,0x1a,0x9d,0x63,0x2c,0xdc +.byte 0xc3,0x89,0x67,0x94,0x37,0x58,0x0d,0x13,0xb8,0xdf,0x41,0x3d,0x70,0x78,0x1e,0x61,0x75,0x77,0xcc,0xbf,0x5f,0xa8,0xd3,0x89,0xcc,0xd3,0x40,0x4e,0x65,0xbd,0xce,0x3c,0xf0,0x5a,0x8f,0xe2,0xe1,0x24,0xaa,0xed,0x0f,0xd1,0x03,0x0d,0xf5,0x36,0x98,0xcd,0xa5,0x77,0x40,0x24,0x0a,0x82,0x68,0x79,0x82,0x38,0x68,0x6f,0x2b,0x0b,0xce,0x0f +.byte 0xcd,0x0f,0xba,0xdb,0xb5,0x22,0x38,0xd2,0xb0,0x9f,0x0f,0x08,0x0d,0xd8,0x5e,0xa7,0xd0,0xa9,0x39,0x66,0x4c,0x46,0xce,0x2a,0xc3,0x67,0x8c,0x91,0xdc,0xf1,0xc0,0x3a,0x58,0x50,0x1f,0xb0,0xa4,0x4d,0xbf,0x99,0x57,0xcf,0xae,0xb2,0xaf,0x6a,0x42,0xd2,0x7f,0x85,0x8c,0x40,0xc6,0x9a,0x93,0x57,0x54,0xf5,0xb4,0x83,0x59,0xb5,0x19,0x52 +.byte 0x7c,0x8b,0x76,0xee,0x35,0x90,0xbf,0xbe,0x65,0x58,0x3b,0x25,0x52,0x18,0xd8,0x7f,0x1f,0xe6,0x70,0xce,0x56,0x1a,0x45,0xa0,0x81,0xee,0x95,0x6f,0x55,0x43,0xaa,0x6e,0x87,0xa9,0xab,0x7d,0xe9,0xa1,0xa3,0x63,0xe7,0x1b,0x6b,0xa6,0x2c,0xe5,0x4a,0xb2,0x1e,0x73,0x5e,0xb5,0xae,0x83,0xe6,0x54,0x0b,0xc5,0x6b,0xb6,0xc4,0x73,0x62,0x1a +.byte 0xbf,0x1a,0x65,0xa2,0x5e,0x3a,0x45,0xd9,0xba,0x5b,0xef,0xf7,0x13,0x0c,0x7c,0x68,0xa1,0x98,0x71,0xb7,0x39,0x7c,0xbc,0x69,0xdb,0xd4,0xac,0x3f,0x82,0x63,0x9b,0x71,0x25,0x3a,0x06,0x73,0x60,0x71,0xc3,0x30,0xd3,0x96,0x02,0x4b,0x46,0xbd,0xd4,0x6e,0xc6,0x29,0xcc,0xd0,0xe1,0x0b,0x66,0x62,0xea,0x29,0xc7,0xcf,0x35,0x9e,0x2f,0x1f +.byte 0xa0,0xfc,0x8c,0x4a,0x83,0x8e,0x3b,0xf5,0x7a,0x6f,0x52,0xaf,0x99,0x9c,0x86,0xab,0xe5,0x1b,0x82,0xb3,0x18,0x35,0x77,0x9b,0xa3,0x94,0xc8,0x39,0x30,0x3f,0xad,0xa9,0x0f,0x93,0xb8,0xc8,0xed,0x04,0xf2,0x0b,0x9a,0xb1,0xd1,0xc9,0x9e,0x40,0x4f,0x71,0x21,0x63,0x2a,0x05,0x26,0x53,0xa3,0x3f,0x43,0xe4,0xf8,0x7c,0x2f,0xa3,0x5a,0x6e +.byte 0xc1,0x40,0xa8,0x4d,0xbc,0x03,0xae,0xe9,0x36,0xb6,0x37,0xdc,0x5f,0xef,0xb0,0x35,0x33,0xdf,0x33,0x71,0xaf,0x80,0xf2,0x69,0xd9,0xb5,0xfc,0xff,0xd2,0x5b,0x6a,0xeb,0xdc,0xe0,0x26,0x43,0x38,0x7b,0x24,0xb2,0x79,0x53,0x52,0x57,0xc4,0x1f,0x6d,0xc9,0x50,0xf2,0x63,0x9d,0xc1,0x22,0x5f,0x11,0x82,0x38,0xdb,0xd3,0xb4,0x1d,0x10,0x72 +.byte 0x9e,0x4d,0x03,0x30,0xba,0x5e,0xe9,0x8c,0x21,0x12,0xe6,0x3a,0xd6,0x4c,0x18,0xa4,0x27,0xc9,0xf5,0x50,0xbd,0xbe,0xf0,0x86,0xd8,0x00,0x56,0xf0,0x10,0x81,0xec,0xeb,0xfc,0x5b,0x29,0x88,0xff,0x73,0x60,0x6b,0xf5,0x8c,0x0b,0x30,0x04,0x53,0x85,0x61,0x0c,0xfc,0xff,0x8f,0x21,0xd2,0xa1,0xcb,0xf7,0x90,0x53,0x3b,0xf4,0xf0,0x2c,0x7d +.byte 0xb6,0x84,0xe7,0x4c,0x88,0xea,0x4f,0xdf,0xff,0x0f,0x5d,0x0f,0xd3,0x2d,0x4f,0x7e,0xdc,0xd1,0x22,0x71,0x0d,0xae,0xa8,0xcf,0x05,0x7b,0xfc,0xfe,0x87,0x40,0xa5,0xe8,0xfd,0x3f,0xdb,0x2f,0x00,0x21,0xb9,0x70,0x02,0x2c,0x96,0x24,0xaf,0x35,0xe2,0x87,0xcb,0x50,0xcf,0x7e,0xfa,0xaf,0x39,0x82,0x0c,0xd5,0xa6,0x3f,0x9c,0x77,0x60,0x16 +.byte 0xbf,0x42,0xcc,0x97,0xd1,0x19,0x0d,0x8a,0x50,0x98,0x7d,0x19,0x7b,0x40,0x1c,0x22,0xde,0x50,0x90,0x32,0x9a,0x3d,0x07,0x35,0xc0,0x48,0x4c,0x0a,0xcd,0x91,0xab,0xf7,0xf3,0x06,0x77,0x80,0x96,0x7b,0x59,0x33,0xe6,0xbf,0x93,0xb8,0x59,0xd0,0x3a,0x1f,0xcc,0xe7,0x1d,0xd4,0xb5,0x58,0xee,0xe7,0x95,0xfa,0x75,0xdb,0x37,0x74,0xb0,0x7d +.byte 0x4d,0xee,0xef,0x20,0x13,0xe5,0x82,0x07,0x8e,0xdd,0x57,0x75,0x33,0x56,0xc4,0x80,0xb0,0x06,0x9f,0x6b,0x72,0x31,0xcf,0xac,0x5f,0x96,0x13,0xeb,0xf4,0x34,0xb6,0x6b,0x55,0xef,0x55,0x26,0x4e,0xdb,0x6c,0x2f,0x64,0x29,0x91,0x3c,0x6d,0x29,0xd2,0x94,0xbd,0x2c,0x99,0xb9,0x97,0x76,0xee,0x7d,0xfd,0xb2,0x8d,0x14,0x4f,0x09,0x81,0xb3 +.byte 0x68,0x3e,0x79,0x28,0x56,0x50,0x3f,0x86,0x4c,0x95,0x6c,0xad,0xf6,0xc5,0x43,0x25,0xea,0xbc,0xe2,0xba,0x77,0x18,0xc6,0x82,0x65,0x73,0x38,0x90,0x9d,0xc9,0x57,0xcd,0xa2,0x7c,0xd3,0x26,0x59,0x44,0xd9,0x79,0xae,0xdd,0x6f,0xe9,0xdc,0x16,0x73,0xba,0x05,0x8a,0x40,0x9f,0xe7,0xcf,0x29,0xa4,0xdf,0x49,0x7f,0x1d,0x73,0xc7,0x8b,0x8d +.byte 0xad,0xb5,0x3d,0x1b,0x64,0xb1,0x8f,0x78,0x06,0xbe,0xaa,0x2c,0x08,0x73,0xc7,0x2c,0xdc,0xd8,0x3f,0x9f,0x1b,0xd2,0xe1,0x4f,0x9d,0x87,0xb8,0xa9,0xdc,0xef,0xbc,0x31,0x9f,0xf7,0x84,0x09,0xe7,0xbc,0xec,0x2a,0xcb,0x3b,0x3a,0x30,0xe2,0x5b,0xbc,0xcd,0xa8,0xdb,0x46,0x80,0xec,0xaa,0x06,0x8e,0xd8,0x6c,0x35,0x65,0x52,0xb8,0xc3,0xf9 +.byte 0x97,0x68,0x06,0x2d,0x3e,0x91,0x71,0x44,0x6e,0x01,0x51,0x10,0x5b,0x74,0xb9,0x3f,0xd7,0xf9,0x5c,0x98,0xe6,0xf8,0x98,0x32,0x26,0x9b,0x5e,0x9c,0x88,0xfb,0xaa,0x70,0xd2,0x2e,0xc2,0xf6,0x02,0x92,0x33,0x55,0x92,0xba,0xfb,0x0e,0x0b,0x08,0xdf,0x5d,0xdd,0x47,0x28,0xae,0x32,0xb3,0x27,0x8d,0xd4,0x18,0x43,0x64,0xc4,0x7f,0x60,0x62 +.byte 0xd9,0x63,0xd1,0x28,0xc9,0x75,0x3b,0x44,0xb4,0x8e,0x2a,0x93,0xf9,0x4c,0x4f,0x7e,0x6b,0x98,0xc9,0x1a,0x82,0x51,0x9a,0xb2,0x80,0x70,0x2e,0xff,0x19,0x66,0x1b,0xb6,0xbc,0x15,0x8e,0xe6,0x0f,0x8e,0x04,0x10,0x94,0x44,0x6c,0x32,0x4b,0x61,0xbc,0x4a,0x16,0x7b,0x25,0x2a,0x27,0x96,0xa9,0xa9,0x61,0x10,0xc1,0x46,0xdd,0xf5,0xe3,0xe8 +.byte 0x1f,0x5b,0xa0,0x77,0xe1,0x42,0x9a,0xd4,0x04,0x33,0x68,0x72,0x1c,0x44,0x29,0xce,0x98,0xe0,0xc7,0x3a,0x9e,0x3c,0xb9,0xb4,0x29,0xef,0x57,0xee,0x8c,0x8f,0x7c,0xe6,0xe1,0x43,0x6e,0x45,0x0e,0xdd,0x4e,0x11,0x4b,0x28,0x69,0xde,0xb8,0xfa,0x32,0xbe,0xc6,0x4f,0x11,0x99,0xe5,0xe3,0xe2,0x1f,0x03,0xbe,0x4a,0xad,0x60,0x68,0xc8,0x13 +.byte 0x80,0x4e,0xb6,0xc0,0xc5,0xc7,0x97,0x5c,0x0b,0x0e,0x64,0x43,0x78,0x70,0x95,0x91,0x8e,0x36,0x6b,0xad,0x57,0xc7,0x1e,0x9c,0x54,0xc9,0x89,0xf0,0x13,0xde,0x0a,0xbe,0xc0,0xa9,0x35,0x77,0x0a,0x01,0x7f,0x98,0x51,0x82,0x92,0x14,0xe0,0x9a,0x08,0xa3,0x0c,0x6c,0x67,0xf2,0x05,0xaa,0xa9,0x4e,0xce,0x3b,0xb1,0xb6,0x8c,0x82,0x5d,0x11 +.byte 0xf2,0xe5,0xd7,0xda,0x3a,0x65,0xa0,0xe3,0xa4,0x09,0x01,0x1c,0xb2,0x08,0x90,0x94,0xb5,0x51,0x56,0x24,0x22,0xfd,0x12,0xad,0x7a,0x75,0xcf,0x0f,0x0f,0x23,0xc3,0xa6,0x1f,0xf8,0x39,0xbc,0x2f,0x18,0x53,0x14,0xef,0xdf,0x90,0x6a,0x50,0x2b,0x8c,0x8b,0xa8,0xd4,0x8c,0x59,0x8f,0xd8,0x81,0x86,0x57,0xc1,0xd1,0xfb,0xe7,0xa6,0x20,0x6e +.byte 0x7c,0xbf,0xce,0xe3,0xce,0x28,0x35,0x7c,0x8e,0x1a,0x66,0xea,0x7d,0x81,0x09,0xdb,0xa8,0x64,0xba,0x3c,0x07,0x3f,0x23,0xd3,0x05,0x97,0x4c,0x92,0xc2,0xa4,0xe8,0x6c,0xfb,0xa0,0x9d,0x8b,0x4d,0xcb,0x3a,0x96,0xe7,0x04,0x0f,0x48,0x87,0x2c,0xdd,0x51,0xf3,0x46,0x7e,0x61,0x89,0xbe,0xb8,0xb0,0x9e,0x9c,0xc4,0x37,0x55,0xe6,0x4f,0x78 +.byte 0x7e,0xb0,0x59,0x42,0xca,0xba,0x4a,0xb2,0x50,0xbd,0x16,0x68,0x99,0x42,0xb4,0x8b,0x60,0x3d,0x54,0x41,0x17,0x11,0x39,0x42,0x5d,0x41,0xec,0xc2,0x53,0x82,0x7c,0x32,0xc9,0xd1,0x34,0x49,0xd8,0x4f,0x29,0x21,0xeb,0x97,0x98,0x4c,0xeb,0x21,0xce,0x50,0xd6,0x53,0xd9,0xf1,0x6e,0x26,0xfa,0xe4,0x71,0x34,0xd8,0x38,0xac,0x39,0x4f,0x02 +.byte 0x36,0x93,0xf2,0x08,0x88,0xdc,0x24,0xdd,0x1f,0xf5,0xe9,0x7f,0x83,0xa0,0xa4,0x6b,0xc5,0xef,0x8e,0x82,0xf9,0x92,0xbc,0x82,0x3f,0xce,0x86,0xa6,0x34,0xf8,0x16,0xa7,0xdb,0x97,0xca,0x54,0x43,0xd8,0xfc,0x31,0xde,0x73,0xd0,0x79,0x1a,0xac,0x61,0x15,0xbd,0x38,0x64,0x3b,0xc6,0xb5,0x95,0xeb,0x2e,0x68,0xe4,0x1d,0x6b,0x18,0xab,0x88 +.byte 0xb0,0x96,0x51,0x8c,0xbe,0x41,0x63,0xd6,0x9a,0x21,0x60,0xe8,0x26,0x37,0xb3,0x10,0x76,0x46,0x31,0x90,0xb0,0x9f,0x17,0xab,0x0f,0x93,0xcc,0x12,0x78,0xee,0x17,0x1c,0xd8,0xc7,0x76,0x0a,0x5a,0xb4,0x8b,0xb1,0x67,0x11,0xde,0x48,0x14,0x8a,0x2a,0xc7,0x71,0x46,0x94,0x15,0x29,0x44,0x9e,0x35,0x03,0x10,0xf7,0x51,0x8a,0xaa,0x9c,0x4a +.byte 0x9a,0x44,0xd5,0xc7,0x37,0x9d,0xb4,0xad,0x41,0xd0,0xda,0xd2,0x1a,0xf9,0x93,0xee,0x28,0x32,0x65,0x0b,0x9c,0x12,0xe3,0xad,0x9f,0x82,0xeb,0x3f,0x03,0xe7,0x6a,0x58,0x83,0x3f,0xbe,0x9f,0x27,0xd3,0xd6,0xe2,0x45,0xbf,0x90,0xe2,0x12,0x61,0x0b,0x57,0xd7,0x06,0x72,0x39,0x2c,0x3e,0x65,0xb2,0xf4,0xf7,0x54,0xef,0x32,0x99,0x44,0x0d +.byte 0xf0,0x5c,0xde,0x4c,0x2e,0x22,0xcd,0x3c,0x25,0x02,0xa5,0x0d,0x79,0x16,0xb0,0x51,0x3f,0x3c,0x84,0x56,0xfa,0x00,0xae,0x7a,0x36,0x45,0x3a,0xcc,0x1d,0x66,0xff,0xf4,0x49,0xce,0xb5,0x5c,0x51,0xf4,0x3e,0x07,0xf2,0x83,0x84,0x4d,0x4e,0xb7,0xce,0x03,0x7b,0x23,0x63,0xdf,0x64,0xa2,0x55,0x92,0xf9,0x2e,0xa5,0x21,0x89,0x29,0x42,0x48 +.byte 0x36,0xc5,0xab,0xd6,0x82,0xe3,0xff,0x45,0xfc,0x61,0xa6,0x4f,0xb9,0x51,0xba,0xd5,0x03,0xa9,0x0b,0xe7,0x73,0x83,0x97,0x1d,0xb2,0xc6,0x75,0xa0,0x52,0x99,0xfc,0x1b,0x27,0x7a,0x10,0xc1,0xed,0x70,0x21,0x4b,0x93,0xa4,0x20,0xed,0x16,0x76,0x97,0x82,0xab,0x21,0xfe,0xa4,0x3f,0xd9,0xbd,0x9c,0x2f,0x19,0x42,0xbc,0xb3,0x4f,0x44,0xf3 +.byte 0x9e,0xd0,0xe7,0xc9,0x7e,0x31,0xaa,0xbc,0x4b,0xba,0x73,0xe1,0xc3,0xbf,0x5d,0xa2,0xd8,0xb7,0xb6,0xfc,0x0a,0x32,0xb9,0xff,0x80,0xb6,0x2a,0x8b,0xea,0x81,0xa0,0xeb,0x1e,0x9e,0x69,0xdd,0xbe,0xc1,0x8a,0x5d,0xfb,0x66,0x21,0x98,0x5c,0x6f,0xd8,0xb4,0xcf,0x8a,0x1a,0x4b,0xde,0xa2,0x20,0xe8,0x5a,0x5a,0xee,0x14,0x09,0xcb,0x63,0x1c +.byte 0x14,0x7d,0x9b,0x47,0xf8,0xfa,0xda,0xb7,0x0e,0xc6,0xbd,0xb2,0x13,0xb8,0x10,0xe2,0x71,0x04,0x36,0x78,0x6d,0x3a,0x8b,0x45,0xd3,0x05,0xec,0x8a,0x2d,0xfa,0x85,0x7c,0xdd,0x75,0xb3,0x2d,0xd1,0xae,0xfc,0xdd,0x02,0x2e,0xcc,0x43,0xc5,0xed,0xe4,0x3f,0xee,0x2c,0xd7,0x37,0x81,0x3a,0x44,0xe6,0xed,0x8c,0x9d,0x9d,0xfa,0xb5,0xdc,0xde +.byte 0xb2,0x7c,0x51,0x58,0xa4,0x21,0xac,0xe2,0x79,0x96,0x90,0xe2,0x0b,0xbf,0x51,0x66,0x77,0x02,0xff,0x67,0x0a,0x70,0x1f,0x04,0x6c,0xb0,0x5b,0x2d,0x26,0x23,0x5a,0x85,0x73,0x66,0x6e,0x7c,0xb3,0xeb,0x36,0x73,0x0f,0xcd,0xb2,0x07,0xee,0x78,0xd1,0xbd,0x5e,0xfa,0x31,0xf6,0x82,0x67,0x94,0xaa,0xff,0xef,0xd2,0x23,0xfc,0x82,0xaa,0xe2 +.byte 0xef,0xc3,0x74,0x79,0x6c,0xe9,0x3f,0x8d,0xe1,0x1b,0xc8,0xb4,0xff,0x15,0xf4,0x60,0xe8,0x84,0x3f,0xaa,0xc6,0x53,0x51,0x1a,0x9b,0x04,0x9b,0xab,0xc5,0xee,0x9a,0x98,0x80,0x89,0x8d,0x5b,0xef,0x0a,0x69,0x71,0xd2,0xf3,0x49,0xc1,0xc1,0x87,0xb3,0x18,0x4b,0x82,0x02,0x87,0xb0,0xf1,0x76,0x4b,0x3e,0xad,0x95,0x51,0xb1,0x64,0xb1,0x03 +.byte 0x5b,0xd2,0x10,0x7b,0x4e,0xd4,0x08,0xf8,0xfd,0xea,0xf0,0xc7,0x16,0x43,0x86,0xa6,0xdb,0xcd,0x75,0xce,0xa9,0xfd,0xa8,0x7c,0x51,0xf7,0xa5,0x29,0x6f,0x0d,0xee,0x66,0x8f,0xc6,0xcd,0x9e,0x3f,0x00,0x24,0x21,0xca,0x69,0x79,0x27,0x03,0x62,0xdf,0xad,0xb9,0x8c,0xd8,0x08,0x88,0x0d,0x0c,0xa1,0x29,0xf9,0xba,0x92,0xb5,0xdd,0xb8,0x1a +.byte 0xbb,0xab,0x44,0xb2,0xda,0x1b,0x8b,0xc1,0x3c,0x61,0x9f,0x7a,0x8b,0x89,0x99,0x09,0xc3,0xb4,0xe4,0x24,0xf5,0x3b,0x36,0xa6,0x61,0x0a,0xec,0x2a,0x1c,0x92,0x7c,0xb1,0x7c,0xd8,0x0b,0x98,0x48,0x8d,0x52,0xa2,0x57,0xc1,0x28,0x89,0xbb,0x60,0x5c,0x58,0x62,0x41,0x1c,0xd6,0xfb,0x69,0x09,0x93,0x90,0x31,0xc4,0x72,0x71,0xf0,0x4f,0xcf +.byte 0x10,0xbb,0xb7,0x6c,0x3b,0x53,0xa3,0x0b,0xff,0x44,0x4c,0x37,0xd5,0x26,0x83,0x7e,0x5c,0xb9,0xa5,0xe8,0x8b,0xc4,0x15,0xf6,0xc7,0xd1,0x39,0x67,0x01,0xb7,0xca,0xa7,0x71,0xa8,0x04,0x95,0x0f,0xfc,0x0a,0x9e,0x52,0xb2,0xfb,0x48,0x47,0xb6,0xa5,0x14,0xc2,0x4f,0xa8,0xd5,0x0f,0x10,0x76,0x39,0x23,0x74,0x2e,0xe5,0x17,0xcb,0xad,0x8a +.byte 0x4a,0x25,0xc8,0x9b,0x25,0x94,0x34,0xbc,0x4b,0x2f,0xdc,0x0a,0xcd,0xc1,0x02,0x72,0x7d,0xa0,0x10,0xa7,0x32,0x68,0xe8,0xd5,0x23,0xe8,0xc9,0xbc,0x05,0x05,0x1e,0xac,0x55,0x45,0xfb,0x42,0x2f,0x0f,0x51,0x8d,0x31,0xb1,0xbc,0x10,0xa1,0x03,0xc3,0x6f,0x35,0x08,0xa5,0x2f,0x91,0x4e,0x43,0x6b,0x62,0x3b,0x00,0x4c,0xd0,0xb8,0x33,0xbc +.byte 0xca,0x57,0xb8,0x1b,0xb4,0x52,0x1a,0xa7,0x03,0x78,0xa0,0x4f,0xda,0x86,0xb9,0xd8,0xc6,0x69,0xe6,0x61,0x2e,0x62,0x96,0x60,0x0d,0x76,0xdc,0x5d,0x0e,0xa8,0xf3,0x86,0xde,0xcf,0x39,0x34,0xc7,0x69,0xed,0xcb,0x9a,0xf5,0xc3,0xce,0x6d,0xa5,0x7f,0xae,0x73,0xb9,0xa6,0xbf,0x88,0x93,0x2b,0x0e,0x8b,0x4b,0xa5,0xeb,0x62,0xc6,0x1a,0xc7 +.byte 0x63,0x63,0x58,0x62,0x37,0xc6,0xbc,0x00,0x72,0xac,0x3d,0x7c,0x22,0xa5,0x59,0xf1,0x6e,0x60,0x45,0x3e,0x99,0x76,0x40,0x82,0xa7,0x52,0xf3,0x48,0x8e,0x4a,0xa3,0xe1,0x3b,0xea,0x77,0xa7,0x7d,0x13,0xe7,0xc4,0xc6,0xa6,0x6e,0xda,0xe8,0x50,0xc8,0x39,0x30,0xab,0x8a,0xe1,0x08,0xa9,0xe3,0xbd,0x8d,0xbd,0x83,0x3c,0xbc,0x6c,0x92,0xed +.byte 0xf1,0xa9,0xd3,0x50,0xf2,0x29,0x8b,0x39,0x46,0xaf,0x08,0x7e,0x00,0x64,0x2f,0xa8,0x18,0xab,0x7e,0x07,0xd3,0x63,0x2a,0xd3,0xd3,0xbb,0xf9,0xdd,0x2b,0xec,0x70,0x35,0x1a,0x94,0x6b,0x87,0xe4,0x1a,0x0a,0x44,0x46,0x08,0xa6,0xce,0x1b,0xf7,0xd7,0x20,0x87,0x1a,0x96,0x6c,0xbe,0xdf,0x73,0x3b,0xc9,0xaf,0x89,0x1c,0x2f,0x47,0xe9,0xd8 +.byte 0x03,0xa6,0x03,0x6c,0x73,0xa9,0x65,0x20,0x36,0xea,0x6f,0xe7,0x96,0x7c,0x01,0x87,0xb0,0x21,0xba,0xb4,0xed,0x1f,0x81,0x65,0x97,0x36,0xda,0x68,0x80,0x64,0x99,0xe6,0xda,0x95,0x04,0xdf,0x5d,0xfd,0x86,0xd1,0xfd,0xfa,0x1c,0xd7,0x89,0xbf,0xe6,0x99,0x6c,0xf5,0x01,0x56,0x20,0x88,0x79,0xa7,0x8d,0x88,0x82,0xe5,0x32,0x38,0xe0,0xf0 +.byte 0x98,0x63,0xa9,0xab,0xeb,0x09,0x8d,0xaf,0x3f,0xa8,0x57,0x98,0xde,0xc8,0x9c,0x8d,0x1d,0x18,0xc5,0xa8,0x82,0x51,0x9b,0x6f,0xc6,0xb8,0x09,0xd3,0xea,0xd4,0xe3,0xac,0xd1,0x0e,0x88,0xda,0xdf,0x38,0x53,0x14,0x87,0x28,0x6f,0x13,0x35,0xdb,0xfe,0xa1,0xe7,0x43,0xb5,0x02,0x46,0x08,0x1a,0x31,0x0d,0x9e,0x3d,0x3b,0xbf,0xbb,0x82,0x9c +.byte 0x09,0xf3,0xd9,0x22,0x0a,0x82,0x07,0xd3,0xe8,0x19,0x6e,0x21,0xd2,0xa2,0xa8,0x14,0xbc,0x42,0xb6,0xeb,0x8c,0x40,0x9b,0xb2,0xa9,0x17,0xad,0x2c,0x19,0xaa,0x4b,0x22,0xf9,0x4e,0xde,0x8f,0xbe,0x78,0x9b,0xab,0xb9,0xfa,0xb1,0x3e,0x68,0x86,0x1a,0x4a,0x61,0xba,0x63,0x51,0x25,0x11,0x59,0xd0,0xb7,0x0c,0xb7,0xcc,0x45,0x05,0x6d,0x5a +.byte 0xe2,0xd7,0x10,0x80,0x19,0xd3,0xa9,0xab,0xb6,0x9f,0x53,0x7a,0xaa,0x19,0x74,0x01,0xc9,0xd6,0x45,0x42,0x2c,0xe5,0xc0,0xcf,0x62,0xe6,0x95,0x6f,0x4c,0x90,0x50,0x97,0x61,0x83,0x73,0xd0,0xc2,0xd5,0xf0,0x05,0xca,0xe9,0x6f,0x67,0xa9,0x51,0xb8,0xb4,0x9d,0x30,0x8e,0xe3,0x29,0xf9,0x3b,0x3d,0x17,0x25,0xad,0xbb,0xb0,0x34,0x68,0x29 +.byte 0x06,0xad,0x0e,0xdf,0x41,0xa6,0xf1,0xa6,0x25,0xc4,0xf0,0x0d,0x57,0x84,0x34,0x2c,0x3b,0xb1,0x41,0xd6,0x83,0x00,0x3a,0x91,0x98,0x8e,0xd0,0x59,0x0b,0x2d,0xc9,0x65,0x03,0x91,0xcb,0x03,0x97,0x57,0xde,0x11,0x8b,0x4b,0x1b,0x85,0x0b,0xb6,0x68,0x25,0x3c,0x1a,0x04,0x7d,0xd5,0x2b,0x16,0x69,0x1f,0x64,0x8b,0x47,0x60,0x17,0xaa,0x68 +.byte 0x45,0xf2,0x0b,0xf8,0xa2,0x27,0xf8,0x47,0x86,0x41,0x94,0x3f,0x92,0xc3,0x02,0xab,0x80,0x2b,0x0e,0x3c,0xd0,0x13,0x59,0x08,0xfc,0x13,0x33,0x52,0xbb,0x2d,0x6b,0x22,0xa2,0x8b,0x9f,0x7c,0x8e,0x40,0x35,0xa4,0xc7,0x45,0xb7,0xf8,0x10,0x22,0x95,0xc5,0x48,0xc1,0x50,0x4d,0x4a,0x36,0xe1,0xec,0x1e,0x07,0xf7,0x68,0x63,0xcb,0x13,0x03 +.byte 0x70,0x63,0xb1,0x9b,0xf3,0x60,0x01,0x6e,0x63,0x5c,0x4d,0x2c,0x5c,0x5c,0x58,0x8b,0xbb,0x6e,0xd1,0x69,0xdd,0x19,0xfe,0xfb,0xd6,0xdc,0x68,0x97,0x9c,0x46,0x0d,0xdd,0x4d,0xbd,0x52,0xe4,0xd9,0xc2,0x03,0x4e,0x4c,0xe2,0x66,0x6b,0x4d,0xbe,0x6b,0xf3,0xd6,0xbe,0x2d,0xba,0xdd,0x1b,0x4f,0x60,0x02,0x74,0xa1,0xf0,0xd0,0xfa,0x23,0x33 +.byte 0x29,0x7e,0x00,0x09,0x47,0x15,0xa8,0xd8,0xdb,0xb8,0xe1,0x20,0xd5,0xe2,0x91,0xd0,0xe8,0xfa,0xa1,0x0d,0x80,0xbd,0x7d,0x62,0x9d,0xf2,0xbc,0x03,0xa1,0x44,0x9f,0x8d,0x3d,0xe3,0xb4,0xec,0x32,0xd9,0x66,0xb0,0xc7,0x75,0x11,0xaa,0xab,0xb7,0x84,0x1d,0x5b,0x4f,0x25,0x5c,0x53,0xed,0xbb,0x6d,0x06,0x1f,0x12,0x5f,0xc0,0xeb,0x55,0x3e +.byte 0xd0,0x5b,0x4d,0x07,0xf7,0x84,0x12,0xbc,0xc8,0xd4,0xf4,0x69,0xdb,0x71,0x8a,0x00,0x58,0xf5,0x84,0xff,0xc3,0xbc,0x13,0x6e,0x5f,0xac,0xd6,0x72,0x1b,0x2d,0xbb,0x27,0xfd,0x8d,0xcc,0x59,0x79,0xb9,0x63,0xe8,0x0a,0xf3,0x7f,0xa4,0x9f,0x4c,0x35,0x9a,0xdc,0xff,0x11,0x42,0xf3,0x1c,0x86,0xd0,0x22,0x7e,0x81,0x79,0x04,0x93,0x5c,0xf2 +.byte 0xab,0xdf,0xb7,0x1d,0x84,0xbd,0xde,0xfb,0xd2,0x75,0x43,0xb8,0x19,0x63,0x97,0xfe,0x0e,0x91,0x9d,0x38,0x50,0xc5,0x7a,0xd6,0x51,0xd4,0xfc,0x8d,0xec,0xd5,0xe2,0x07,0xce,0x21,0x03,0x02,0xa1,0x61,0x8d,0xf1,0xf5,0x1f,0xb3,0xaf,0x9f,0x13,0xd8,0x81,0xd2,0xf7,0xe9,0xe2,0x62,0x49,0xca,0x1c,0x15,0x07,0x39,0xe6,0x01,0xec,0x6c,0x7d +.byte 0x3b,0xf1,0x52,0xda,0xf2,0x97,0x55,0xef,0x6f,0x88,0x82,0x0e,0xe6,0xf4,0x3e,0x33,0xf6,0x61,0x6d,0xef,0xbf,0xa8,0x9a,0x91,0x2f,0xb3,0xd2,0x3d,0xaa,0x7a,0x4e,0x80,0xe1,0x04,0xbe,0xc7,0xf8,0xc3,0xc9,0xd8,0xa2,0x01,0x5d,0x30,0xae,0x6d,0x39,0x52,0x60,0x9d,0x07,0xd5,0xa2,0x86,0xf0,0x88,0x00,0xec,0x18,0x11,0x2d,0x69,0x86,0xa9 +.byte 0x5a,0x73,0xda,0x4e,0x4c,0xdb,0xb8,0x02,0xad,0x53,0xec,0x20,0x0f,0x35,0xe0,0x4f,0x6e,0xd5,0x04,0xcc,0xa0,0xf5,0x8c,0x7d,0x31,0x04,0xa4,0xcf,0xf0,0x27,0xd2,0xb6,0x7d,0x8c,0x26,0x5f,0x19,0xba,0x79,0x80,0xec,0x6d,0xfe,0xaf,0xc1,0x3a,0xc2,0x3d,0x14,0x3c,0xa0,0xc5,0x77,0xf4,0x96,0x56,0x51,0x8b,0x7c,0x7e,0xe5,0x23,0x5d,0x46 +.byte 0x1b,0x2e,0x28,0xc0,0x80,0x6b,0x6a,0x85,0x6c,0xcf,0xaa,0x28,0xf3,0x83,0x2d,0x42,0x6f,0xf3,0x5e,0x5d,0xa2,0x7b,0xba,0x5c,0x12,0xb0,0xda,0xa0,0xeb,0xdf,0xad,0x1d,0x4c,0x54,0xcf,0xad,0x02,0x68,0xcd,0xfe,0x5c,0x5b,0x65,0x6d,0xa5,0xcc,0xd3,0xed,0x32,0x74,0x6c,0x58,0x83,0x3a,0xc1,0x71,0xbf,0xb5,0xa2,0xbd,0x10,0xe5,0x46,0xc5 +.byte 0x00,0x82,0xb1,0xeb,0x6f,0x73,0xf9,0x12,0x23,0xe4,0xda,0xff,0xa3,0xc4,0x9c,0xf1,0xcc,0x0e,0x1a,0x7a,0x10,0x62,0x8f,0xa5,0xb2,0x35,0x51,0x67,0xb5,0x95,0xbe,0x4c,0x81,0x53,0xfc,0xdd,0x27,0x26,0x97,0x42,0x01,0xec,0x08,0x91,0xb8,0xf0,0xaf,0x57,0x54,0x73,0x52,0x8f,0xde,0xca,0xed,0x1b,0xca,0x8d,0x97,0x1e,0xdc,0xe7,0xfa,0x68 +.byte 0xaf,0x37,0xb0,0x62,0xa3,0x9f,0xbc,0xac,0x9f,0x28,0x1e,0xb7,0xaa,0xb0,0x91,0xe4,0x95,0xad,0xf9,0xe5,0xd4,0xcc,0x23,0x0f,0x4a,0x2d,0xdd,0xea,0x64,0xd1,0x04,0x3c,0xd0,0xca,0xfe,0xd3,0x19,0x9d,0x28,0xa5,0x1c,0xff,0x3e,0xae,0xe9,0xfb,0x12,0x03,0x6d,0xcf,0xbc,0x5f,0x27,0xce,0x1a,0xb9,0xc0,0x31,0x88,0x6e,0x2e,0xaf,0x35,0x5f +.byte 0xf0,0xce,0x92,0xf8,0x6f,0xd6,0x67,0x1c,0xc6,0x5c,0xee,0x59,0xaa,0xd6,0x8c,0xa8,0x13,0xe6,0xf7,0xe2,0x82,0x2f,0x82,0x1e,0x4c,0x0d,0xab,0x3e,0xdb,0x4d,0xc5,0x90,0x32,0xe4,0xf0,0x74,0xc1,0x92,0x1b,0xdd,0xf3,0xa7,0xf6,0x6b,0x01,0x9d,0x8d,0x78,0x3d,0x5a,0x46,0x74,0x16,0x93,0x44,0xca,0xbe,0x31,0xea,0xb4,0x65,0xcd,0xe6,0xdd +.byte 0x56,0x9d,0x63,0x48,0xf0,0xf3,0x15,0x91,0x6c,0x27,0xf9,0xf7,0x3b,0x9f,0x04,0x6d,0x4d,0x1d,0xf1,0x7c,0xd1,0x81,0x06,0xef,0x04,0x47,0x98,0x5d,0x21,0xf4,0xe0,0xa0,0x13,0xaf,0x1d,0xb0,0xd5,0x45,0x64,0x92,0x46,0x99,0xff,0xb4,0xbf,0x36,0x01,0x2d,0x23,0x6a,0xc4,0x6b,0x3f,0x91,0x10,0x03,0xaf,0x6e,0x79,0x86,0xdb,0x15,0xde,0xfa +.byte 0x0d,0x71,0x04,0x16,0x12,0x31,0x9b,0x69,0xb9,0xe0,0xe7,0x4e,0xfd,0x0e,0xd5,0x71,0xa0,0xc7,0xd7,0x46,0xdb,0xda,0xbd,0xcd,0xdc,0x77,0xe5,0x71,0x9d,0xa1,0xf4,0x02,0x10,0xc6,0x27,0x76,0x4e,0xa6,0x35,0xe6,0x9e,0xda,0xbe,0xd8,0xc0,0x21,0x15,0xd4,0xcc,0xd5,0x4b,0xdf,0x38,0xc5,0x15,0x4b,0xfa,0x4e,0x83,0xf4,0x27,0xdb,0x8a,0xb1 +.byte 0x0e,0x1f,0xc9,0x3c,0x1c,0x36,0x35,0x54,0x8b,0x54,0xf8,0x31,0x1e,0x0e,0x1c,0x4e,0x44,0x29,0x90,0xad,0x28,0x85,0xb4,0x72,0x2d,0x1b,0x8b,0x26,0x2f,0xb6,0xc2,0x14,0x0e,0x81,0xd0,0x37,0x29,0x5c,0x0f,0xdc,0x21,0x62,0x10,0x7a,0xeb,0xa3,0x6e,0xd4,0x5b,0xb4,0x13,0x2e,0xd6,0x8f,0xd9,0x57,0x0d,0x9b,0xfd,0x1e,0x66,0xb7,0x6e,0xac +.byte 0x88,0xb9,0x75,0x60,0x62,0x83,0x72,0x96,0xc6,0x2e,0xdc,0xfe,0x88,0xee,0x07,0x9a,0x62,0x19,0xde,0xf1,0xa5,0xfb,0xcc,0xdb,0x4a,0xeb,0x16,0x60,0x34,0x46,0xfc,0xf2,0x6d,0xee,0xfc,0xa0,0x3a,0xb1,0x11,0x03,0x8b,0xae,0x26,0xef,0x86,0x91,0x20,0x7a,0x19,0x35,0xd6,0x12,0xfc,0x73,0x5a,0xb3,0x13,0xf8,0x65,0x04,0xec,0x35,0xee,0xf8 +.byte 0x70,0xb2,0x0b,0xe1,0xfc,0x16,0x35,0xec,0x6b,0xdd,0x8b,0xdc,0x0d,0xe8,0x91,0xcf,0x18,0xff,0x44,0x1d,0xd9,0x29,0xae,0x33,0x83,0xfe,0x8d,0xe6,0x70,0xbb,0x77,0x48,0xaa,0xe6,0xbc,0x51,0xa7,0x25,0x01,0xcf,0x88,0xc4,0x8b,0xfc,0xb1,0x71,0x01,0xc7,0xfc,0xd6,0x96,0x63,0xee,0x2d,0x04,0x1d,0x80,0x24,0xd0,0x80,0x03,0xd9,0x18,0x96 +.byte 0xec,0x6a,0x98,0xed,0x6e,0x9a,0xe0,0x42,0x5a,0x9d,0xec,0xed,0x46,0x3c,0xb5,0xf0,0xd6,0x88,0x92,0x89,0x38,0x5f,0xd6,0xba,0xfd,0x32,0x31,0x81,0xe9,0xf1,0x56,0x89,0xa3,0x56,0xa6,0x03,0x00,0x60,0xe1,0xa8,0x59,0xdb,0xbe,0x72,0x39,0x6c,0x08,0x4d,0x26,0x57,0xa6,0xf6,0x13,0x7d,0x4a,0x2f,0x64,0xb8,0xa7,0x23,0x2c,0xa4,0x4a,0xad +.byte 0xcf,0xa1,0xa2,0x32,0xbb,0xd1,0x98,0x02,0xe4,0x1a,0x41,0x26,0x23,0xba,0xa2,0x17,0x62,0xaa,0xa6,0xc7,0x74,0x9d,0xea,0xc7,0xa0,0x08,0x0a,0x1a,0x4e,0x71,0xd9,0x45,0xf7,0xe8,0x57,0x79,0x12,0xd0,0x38,0x2f,0xdb,0xbd,0x5a,0x84,0xe1,0xb2,0x62,0x7e,0x56,0xb3,0x50,0x2a,0xa0,0x32,0x1f,0x86,0x71,0xc4,0xa5,0xba,0x93,0x5b,0x22,0x97 +.byte 0xf4,0xe5,0x44,0x27,0x6b,0x06,0x84,0x55,0x19,0x45,0x12,0x75,0x4b,0xf0,0x76,0x6d,0x3c,0x0a,0x17,0xc2,0x9d,0x96,0x72,0xe7,0x5e,0x79,0x84,0x0a,0x39,0x64,0x09,0x6e,0x7e,0xd7,0x77,0x40,0x75,0x2c,0xbd,0x98,0xae,0x3e,0x34,0x08,0x4d,0xda,0x2c,0xcf,0x0c,0xa2,0x8c,0x40,0xfa,0x34,0x43,0x15,0xed,0x4f,0x69,0xa6,0xef,0x2d,0x3c,0x55 +.byte 0x7a,0xe1,0x67,0xd1,0x0a,0x89,0xe0,0x2d,0x02,0x35,0x57,0xc8,0x9a,0x4b,0xc4,0x46,0xa7,0x57,0x03,0x89,0x7d,0x3f,0x70,0x47,0x03,0x06,0xd9,0x81,0x1f,0x8d,0x7e,0x36,0x9b,0xfd,0xad,0x20,0x9d,0x5a,0x29,0xe9,0x40,0x6a,0xb8,0x07,0x6b,0xc7,0x2b,0x58,0xd2,0x1d,0xef,0x88,0xa5,0xfb,0x3b,0xd6,0x9f,0xfd,0x89,0x0e,0x50,0xd4,0xbc,0x89 +.byte 0x3f,0x3c,0x6c,0x50,0xc6,0xe3,0x8b,0x7e,0x34,0x8b,0x26,0x99,0x2a,0xfa,0xa5,0x19,0x53,0xb5,0x5e,0xfd,0x94,0xe8,0x33,0xb2,0x6d,0x9c,0x3c,0x0c,0x14,0x90,0xc4,0xa2,0x4a,0x3a,0xca,0x07,0x72,0x46,0x37,0xfc,0x02,0x5d,0xf4,0x97,0xca,0x8e,0xc6,0xc4,0x63,0xda,0x5c,0x89,0xc3,0x6c,0xb1,0x1a,0xf5,0x2a,0xbc,0x2e,0xe3,0xcd,0x2f,0xe2 +.byte 0x91,0x16,0xf9,0x94,0x0e,0x1b,0xe6,0x01,0x73,0x61,0x1e,0xcf,0x5e,0x21,0x70,0xcb,0x5b,0x87,0xc1,0x46,0x39,0x59,0xa6,0x74,0x82,0x7f,0xa2,0x6c,0x4a,0x50,0x5f,0xbd,0x1c,0x1a,0x65,0x80,0x01,0x44,0x19,0xcf,0xcd,0xef,0x3d,0x5e,0x1b,0x71,0x82,0x4f,0x8b,0xc1,0xa0,0x9a,0x77,0xee,0xac,0x06,0xdc,0x6a,0xa0,0x34,0x50,0xa4,0xe0,0xda +.byte 0x3d,0xa0,0xf7,0x9a,0xb8,0xd5,0x59,0xe0,0x7f,0x05,0x04,0xd5,0x32,0x8c,0x49,0xf5,0x0a,0x0e,0x99,0x83,0xf5,0x47,0x2b,0x7c,0x7b,0x65,0x25,0x02,0xc4,0x88,0xbb,0x6a,0x4f,0x89,0x31,0x60,0xc2,0x47,0x8b,0x22,0xfc,0x4a,0xde,0xb3,0xb9,0xed,0xb8,0xdf,0xd7,0xd5,0x09,0x98,0xcc,0x5f,0xaf,0xbb,0x02,0xc3,0x62,0x62,0xee,0x99,0x42,0x1b +.byte 0xbe,0x5b,0xa8,0x5c,0x40,0x03,0x86,0x29,0x29,0x06,0x0b,0x53,0x46,0x29,0x03,0x3b,0x11,0x64,0xf1,0x09,0xca,0x69,0x69,0xfa,0xcc,0x85,0x23,0x14,0x1b,0xfd,0x65,0xb9,0xf5,0x6b,0xbb,0x2a,0x9d,0x6e,0x64,0x1a,0xe1,0x37,0x39,0xd4,0x85,0x40,0xa3,0xf9,0x04,0xec,0x9e,0x3b,0x74,0x97,0xa4,0x64,0x8a,0x48,0xb2,0x62,0xc1,0x1c,0xed,0x67 +.byte 0x6f,0x23,0xae,0x0f,0x64,0x2e,0xe5,0x92,0xb6,0xb5,0x71,0x24,0xc0,0x60,0x9a,0x10,0x23,0x6b,0x4a,0x22,0xe9,0x0a,0xaa,0x09,0x62,0x39,0xe0,0x40,0xee,0x13,0x27,0x14,0x73,0xeb,0x75,0x7b,0x4a,0xe1,0x42,0x65,0x37,0xae,0x80,0x08,0x26,0xf9,0x53,0x98,0x58,0xdd,0xf5,0xed,0x26,0x37,0x37,0x85,0xb5,0x88,0x91,0x05,0x2d,0x04,0xa6,0xd5 +.byte 0xa6,0x98,0xb0,0x0e,0x4b,0x4c,0x53,0x76,0x79,0xad,0x82,0xc5,0x16,0xba,0xd8,0x20,0x5f,0x4c,0x1d,0x69,0xa0,0xe0,0xe9,0xbc,0xb8,0x5c,0x10,0x4a,0x0a,0xd3,0x52,0x9c,0x2e,0x1b,0x6c,0xf7,0x43,0x83,0x6f,0xa9,0xcc,0x00,0xed,0x16,0x4c,0xc3,0x24,0x79,0x59,0x68,0xfb,0xf9,0xf6,0xb0,0xb4,0x01,0xc2,0xdd,0xf7,0xe5,0x3b,0x60,0x48,0x49 +.byte 0x32,0x48,0x05,0xa8,0x62,0xa3,0x03,0x9f,0x3d,0x91,0xdb,0x84,0x64,0x6f,0x1e,0x50,0x8e,0xdf,0x1a,0xa0,0xb1,0xf4,0x34,0x7c,0xe6,0xb7,0x7c,0x14,0xa1,0x65,0x1a,0xb4,0xdb,0x67,0x78,0xb1,0x88,0x3c,0xc2,0x5e,0x0e,0xea,0x32,0x15,0xc7,0xda,0xe4,0x9a,0x44,0xde,0x61,0x90,0x3b,0x97,0x11,0x5b,0x6d,0xa5,0x9a,0x2f,0x1b,0x8b,0xd7,0xdd +.byte 0x73,0xe4,0xc3,0x19,0x5d,0x68,0xcf,0x0e,0xe4,0x69,0xa5,0xeb,0x50,0x6f,0x79,0xff,0x91,0xc6,0x95,0x83,0xe8,0x72,0x6a,0x01,0x49,0x2b,0xcf,0x8f,0x93,0x1e,0xef,0x31,0x17,0x8f,0xa8,0x2b,0x5f,0x4b,0x79,0x8b,0xe5,0x6c,0xb7,0x61,0xd5,0x9e,0xe0,0xd4,0x25,0xc3,0x93,0x31,0x8f,0x66,0x6c,0x48,0x30,0x65,0xf4,0xd7,0xde,0x64,0xee,0xbd +.byte 0xbd,0xad,0x32,0xfc,0xf3,0xd8,0x7c,0x85,0x7c,0x24,0x40,0xb6,0xd4,0xe0,0x4b,0xc0,0xab,0xcc,0xeb,0x77,0x7c,0xb7,0x33,0x3c,0x90,0x04,0xaf,0x85,0xaa,0xb4,0xaa,0x90,0x67,0x29,0xd9,0x85,0x6a,0x34,0xf4,0xc4,0x6c,0xbc,0xb4,0x86,0x54,0x83,0xd5,0x5e,0xf3,0xdd,0x1a,0x56,0x5e,0xa5,0xd8,0x06,0xc0,0xa7,0x27,0xd4,0x0d,0x5b,0x08,0xf4 +.byte 0xb4,0x15,0xf9,0xb4,0x56,0x1c,0x80,0x98,0xc9,0xcd,0xf0,0x38,0x18,0xbe,0x99,0xec,0x7e,0x0c,0x3d,0xc1,0x98,0x26,0x9d,0x50,0xe4,0x00,0xcf,0x0f,0x0b,0x77,0x86,0x31,0x55,0x38,0xa4,0x31,0x50,0x51,0x64,0x88,0x81,0x05,0x32,0x99,0x38,0xd1,0x62,0x20,0x8e,0xf0,0x29,0x31,0xf5,0x79,0xbb,0x1e,0x0f,0xba,0x51,0x94,0xa9,0x54,0xcd,0x43 +.byte 0xce,0xe5,0x2c,0x29,0xa5,0x51,0x23,0x97,0x5d,0x36,0xff,0x51,0x5c,0x66,0xb7,0x62,0x1b,0x5f,0xd7,0x2f,0x19,0x07,0xff,0x0a,0xfc,0xf6,0x6e,0xb5,0xfd,0xa9,0x92,0x40,0xd3,0xe6,0x99,0x15,0x6f,0x1e,0x91,0xad,0x1f,0x4d,0x1c,0xe2,0xd9,0xcf,0x01,0x71,0xec,0x1a,0xa3,0xba,0x48,0x40,0xfd,0x18,0xb1,0x24,0x2b,0xd2,0x37,0xb5,0x74,0xdd +.byte 0x7e,0xf6,0x18,0xb4,0x7b,0x0e,0x7d,0x65,0x46,0x7b,0xe3,0x51,0x03,0xae,0xe1,0xd0,0x74,0xc6,0xc9,0xda,0x0e,0x79,0x6f,0xf5,0x62,0xc0,0x7e,0x76,0x3e,0x13,0x8b,0xe0,0x4c,0xfa,0x7e,0xe1,0xa2,0xee,0x9d,0x3f,0x91,0x9d,0x21,0xdd,0xc2,0xd0,0xa5,0x1d,0x17,0xd6,0xdc,0xeb,0xa3,0xc0,0x71,0xa0,0xfe,0xf0,0xaf,0x31,0xdc,0xa3,0xd4,0x21 +.byte 0x4a,0x32,0x1d,0x54,0x25,0x3b,0xc8,0x8f,0x68,0xcd,0x99,0xce,0x76,0x39,0x42,0xd8,0xca,0xf2,0x46,0x72,0xfe,0x52,0xc2,0x90,0x83,0xed,0xa0,0x6d,0x1b,0xf5,0xb1,0x09,0xae,0x2b,0x34,0x4f,0xd3,0x78,0x19,0x7f,0xad,0x8d,0x50,0x26,0x9c,0x36,0xa3,0xb5,0x3d,0x0b,0xa6,0x87,0x65,0xa0,0xdb,0x88,0x20,0xff,0xb6,0xfd,0xc5,0xbd,0x0a,0x28 +.byte 0xc8,0x9c,0x42,0x7f,0x24,0x58,0xe9,0x07,0x53,0x4b,0x9a,0x2a,0x1e,0x7b,0x90,0x97,0x78,0x74,0x80,0x5d,0xe5,0x6e,0xae,0x15,0x68,0xd4,0x2a,0x3a,0xd3,0x00,0x4f,0x4b,0xff,0x8f,0x1e,0x8f,0x9f,0x75,0xe5,0xea,0x9d,0xb9,0xed,0x8f,0xa9,0x2b,0x70,0xa8,0xcb,0x08,0x85,0xd3,0x8f,0x5d,0xc7,0x49,0x66,0xcc,0xa8,0x6d,0xbd,0x01,0x93,0xd5 +.byte 0xe6,0x75,0x2e,0x25,0x07,0x59,0x86,0x3f,0x44,0x8b,0x0b,0xb5,0x38,0xd5,0xbd,0xcf,0x48,0x8a,0xf7,0x71,0xd6,0x6b,0x2e,0x93,0x3d,0x0b,0xc0,0x75,0xee,0xa8,0x5d,0x9c,0x3d,0xa5,0xdb,0xc5,0x8d,0xac,0xda,0xf4,0xcd,0x5f,0x24,0xfe,0x86,0x14,0x44,0x65,0x3f,0x89,0x7f,0xd3,0x61,0x48,0xb0,0x43,0xf0,0x1e,0xde,0xbc,0xb7,0x51,0x0f,0xfc +.byte 0x32,0xf2,0x04,0xe2,0x4b,0xcb,0xbb,0x63,0x7d,0x5b,0x9a,0xb1,0x91,0x57,0x89,0xdc,0xed,0xde,0x91,0x2d,0xdd,0x42,0xc8,0x3c,0xb0,0xd7,0xa5,0xbc,0xa7,0x33,0x14,0x32,0xaf,0xf7,0xe9,0x25,0xd2,0x1a,0x64,0xf7,0x1b,0xab,0x0e,0xbc,0x50,0xbc,0x85,0x44,0xe0,0xa6,0xf1,0x4a,0x32,0x2f,0x30,0x27,0x48,0x4f,0xfc,0x8a,0x5a,0x78,0xe7,0x16 +.byte 0x55,0xcf,0xca,0x15,0xa8,0xa8,0xa2,0xef,0x9a,0x16,0x02,0xf4,0xb0,0x44,0xfd,0xc4,0x51,0x01,0x4f,0x1d,0x9d,0x09,0x62,0x42,0xe9,0x8b,0x18,0xa4,0x65,0xef,0x8b,0xfe,0x71,0x9f,0x4b,0x47,0x48,0x41,0x73,0x5c,0x0c,0x52,0x7d,0x79,0xbc,0x93,0x2a,0xaa,0x81,0x99,0x21,0xa5,0x9e,0xac,0xcd,0x57,0x51,0x50,0xbc,0xc9,0x96,0xaf,0xdf,0x1a +.byte 0x8f,0xee,0x36,0x05,0x20,0x32,0xe8,0x51,0x94,0x72,0x12,0xa3,0x17,0x25,0x7f,0x0a,0x3e,0xcc,0x22,0xcf,0x05,0xb2,0x2b,0xaa,0x36,0x01,0xdf,0xd4,0x4e,0xe1,0x02,0x43,0x4e,0xac,0x50,0x64,0xcd,0x2f,0xc2,0xa9,0xb0,0xf2,0xf2,0x4c,0xdf,0x16,0xa6,0x54,0xf7,0xbf,0x1a,0x69,0xeb,0xa1,0x5a,0xc7,0xcf,0x46,0x2d,0xc2,0x3a,0x7f,0x4a,0x14 +.byte 0x22,0x15,0x46,0x46,0x2d,0xc1,0x98,0xf7,0x0b,0xf3,0x27,0xfc,0x78,0x67,0x05,0xd8,0xe0,0xf6,0xb8,0xb6,0x0b,0xdb,0x4d,0x6b,0x7e,0x9b,0xbf,0x5c,0x15,0x97,0x49,0x9f,0x6f,0x11,0x6c,0x6e,0x1d,0x1e,0x65,0x5b,0xb9,0x60,0x8f,0xa3,0xa9,0x99,0x17,0x92,0xb8,0x65,0x25,0xc4,0xef,0xea,0xa6,0xc0,0x57,0xa9,0x4c,0x78,0xe3,0xd6,0xf2,0x19 +.byte 0x9c,0x86,0x9e,0x45,0x3e,0xfd,0x21,0x4c,0x2a,0x56,0x7c,0x23,0xf2,0x22,0xa1,0x81,0xdb,0xe6,0xfa,0x85,0x19,0x3b,0x1d,0x61,0xb3,0x21,0xb5,0x64,0x1d,0x07,0x66,0xd2,0xe5,0x9c,0xb0,0x76,0x9d,0xc9,0x02,0x6a,0x8d,0xd5,0x84,0xd5,0xa7,0x7c,0x70,0x64,0x46,0xd6,0xff,0xc7,0x9f,0x2f,0xed,0xc1,0x5a,0xcb,0x56,0x12,0x31,0x9d,0xff,0x66 +.byte 0x9a,0xf8,0x50,0xc6,0x54,0xfd,0x8d,0x49,0x32,0x8c,0xdd,0x8c,0xbe,0x30,0x79,0xaf,0x1a,0xd5,0x28,0x1d,0x03,0x87,0x12,0x60,0x7a,0xcc,0xe6,0xe8,0x4e,0x21,0x5d,0xa3,0x06,0xfb,0xdf,0xf6,0x31,0xd6,0x10,0x3e,0xec,0x23,0x69,0xc7,0x7b,0xf6,0x78,0xa6,0xd1,0x8a,0x48,0xd9,0xdc,0x35,0x1f,0xd4,0xd5,0xf2,0xe1,0xa2,0x13,0x8a,0xec,0x12 +.byte 0xa7,0xf1,0x5d,0xb2,0xc3,0x6b,0x72,0xd4,0xea,0x4f,0x21,0xff,0x68,0x51,0x51,0xd9,0xd7,0x2f,0x28,0xd7,0xdf,0xbc,0x35,0x4f,0x49,0x7e,0xe7,0x21,0x82,0xd7,0x0c,0x7c,0xf4,0x86,0x86,0x62,0xcd,0xf5,0x23,0x77,0xc1,0x14,0x8a,0xc4,0x2a,0x82,0x74,0x0e,0x90,0x93,0xd5,0x5a,0xc0,0x57,0x93,0x1a,0xe1,0x1c,0x13,0x17,0x72,0xc3,0xa6,0x54 +.byte 0xc4,0xe2,0xfc,0xd3,0xa0,0xce,0x08,0x87,0x9e,0x2a,0xaf,0xa7,0xbb,0x2d,0xaf,0xc0,0x38,0x97,0xc8,0x6d,0xb8,0x7b,0x75,0xc5,0xf2,0x79,0x62,0xdc,0x7c,0xa9,0xfd,0x19,0xa2,0xb1,0xee,0xdf,0x90,0x18,0x5a,0xdb,0x3c,0xba,0x0d,0x84,0xd6,0xaf,0x15,0xee,0xb6,0xa5,0x78,0x38,0x87,0xdf,0x42,0xd6,0xd1,0xa2,0xe9,0xe0,0xa6,0xf2,0x4e,0xa4 +.byte 0xed,0xa5,0xf6,0x66,0x7f,0x99,0xbc,0xfb,0x4b,0x37,0xca,0x5a,0xb3,0x29,0x8e,0x80,0x30,0x8b,0x74,0x7b,0xac,0x61,0xfb,0xca,0x62,0xfe,0x24,0xc4,0x6e,0xac,0x66,0x97,0xaa,0x9a,0x99,0xe6,0xa8,0xa4,0xd8,0x62,0x58,0x7c,0xd1,0xeb,0xee,0xc8,0x08,0xa0,0x54,0xde,0xb1,0xef,0x57,0x2c,0xb6,0x2c,0x78,0x22,0x10,0xbb,0xfe,0x4b,0x77,0xa5 +.byte 0x5a,0xed,0xbb,0xf8,0x97,0x96,0x20,0xa9,0x8c,0x78,0xb5,0xb9,0x55,0xc9,0xaf,0xb9,0xa1,0x1f,0x13,0x52,0xf9,0xbb,0xaa,0x98,0x01,0x57,0xa6,0x88,0xaa,0x5c,0xf0,0x62,0x5b,0x3e,0xe1,0x5f,0xf4,0x98,0x95,0x8b,0x8f,0x48,0xd6,0xd5,0x8b,0xc2,0x1d,0x45,0x7d,0xe2,0x03,0x66,0x84,0xfc,0xbd,0x8e,0x95,0x9f,0x58,0x99,0x7b,0x4c,0xb6,0xe5 +.byte 0xe2,0xf9,0x2e,0x92,0x58,0xca,0xa9,0x24,0x9c,0x7c,0x46,0xdf,0xea,0xb4,0x6e,0x0e,0xa5,0x9c,0x14,0xbf,0x25,0x5b,0x39,0x4a,0xaf,0x31,0xaa,0xd1,0x2c,0xe6,0x06,0x3d,0xc4,0x60,0xc7,0xcd,0x49,0x8d,0xe1,0x50,0x55,0xe4,0x72,0x68,0xed,0x43,0xb8,0x85,0xa3,0xc3,0xf1,0xf5,0xd1,0xcf,0xcb,0x57,0xac,0x04,0x16,0x22,0xe4,0xfc,0x4a,0x13 +.byte 0x60,0x3f,0x09,0xa4,0xf2,0x9b,0x34,0xeb,0x0c,0x10,0x57,0xc3,0x3f,0x15,0xb5,0x1b,0x6a,0xb3,0x7d,0x37,0x02,0x4c,0x0f,0x6f,0x8b,0x4d,0x5d,0x57,0x7d,0xbf,0x00,0x8a,0x74,0xb4,0x4c,0x5f,0x90,0x27,0x76,0x09,0x8c,0x18,0x3f,0x26,0x3a,0x09,0x06,0xdd,0x8b,0xff,0x0e,0xa4,0xae,0xef,0x0c,0x81,0xf2,0xf3,0x1f,0xe0,0x33,0x33,0x37,0xc6 +.byte 0xc3,0xfb,0x14,0xdd,0xa1,0x16,0x84,0x80,0xcb,0x37,0xe7,0x97,0x6d,0x21,0xa7,0x71,0x19,0x2b,0x2d,0x30,0xf5,0x89,0x2d,0x23,0x98,0xfc,0x60,0x64,0x4a,0x26,0x65,0x4a,0xef,0x12,0x59,0xa3,0x8c,0xd9,0xbd,0xdc,0xb7,0x67,0xc9,0x8d,0x51,0x72,0x56,0x6a,0xe5,0x59,0xa2,0x53,0x4f,0xb6,0x53,0xff,0xb0,0xd4,0x06,0x7f,0x79,0x23,0xf9,0xcb +.byte 0xbf,0x9a,0x93,0xde,0x88,0x33,0x58,0x70,0xa7,0xcc,0x07,0xb1,0x44,0xb9,0x99,0x1f,0x0d,0xb9,0xc9,0x18,0xdc,0x3e,0x50,0x22,0xfb,0x4e,0x86,0x0d,0xc0,0xe7,0x7f,0xc6,0xa1,0x52,0x0d,0x8d,0x37,0xe6,0xaf,0xe3,0x13,0xbe,0xa6,0xf9,0x59,0x39,0x0f,0x17,0x66,0xce,0xb1,0x7d,0x7f,0x19,0x1a,0xf8,0x30,0x3a,0xa5,0x72,0x33,0xa4,0x03,0xb6 +.byte 0xb6,0x9b,0xde,0x7a,0x7a,0x62,0x3d,0x85,0x98,0x8e,0x5d,0x8a,0xca,0x03,0xc8,0x2c,0xae,0xf0,0xf7,0x43,0x3f,0x53,0xb2,0xbb,0x1d,0xd0,0xd4,0xa7,0xa9,0x48,0xfa,0x46,0x5e,0x44,0x35,0x50,0x55,0xdc,0xd5,0x30,0xf9,0x94,0xe6,0x5f,0x4a,0x72,0xc2,0x77,0x59,0x68,0x93,0x49,0xb8,0xba,0xb4,0x67,0xd8,0x27,0xda,0x6a,0x97,0x8b,0x37,0x7e +.byte 0xe9,0x59,0x89,0xc7,0x5e,0xd9,0x32,0xe2,0xaa,0xd1,0xe9,0x2b,0x23,0xca,0x9d,0x89,0x7a,0xf5,0xe4,0xfb,0x29,0xcc,0x88,0xfb,0x82,0x0f,0xbf,0x47,0x54,0xca,0x2b,0x4b,0xd8,0x47,0x7f,0x65,0x38,0x5a,0xb3,0xe8,0x0b,0xd7,0xe1,0x8b,0x89,0x57,0x32,0xdb,0xa3,0x85,0xba,0xf9,0xbc,0x52,0x92,0x20,0x10,0x66,0x54,0x81,0xe1,0x49,0x3f,0xe1 +.byte 0x8c,0x2e,0x0b,0x3b,0xe7,0x49,0xb4,0x60,0x5a,0x20,0x33,0xc4,0x4e,0x81,0xef,0x96,0xda,0x73,0x90,0x2b,0xb4,0x86,0xa1,0x5c,0xcd,0xa0,0xc7,0xf3,0x06,0x0d,0x2a,0x5a,0x41,0x96,0xf5,0x40,0x1b,0x0a,0x3a,0xb7,0x38,0xe1,0xbb,0xe3,0x42,0xf9,0x52,0xe5,0x98,0xe2,0x17,0xd4,0xb0,0x09,0x73,0x75,0xc1,0x00,0x18,0x0f,0xa7,0x0b,0x58,0xc1 +.byte 0x78,0x5c,0x0c,0x05,0xd8,0xfb,0xc5,0xfd,0x5c,0x66,0xbe,0x54,0x68,0xd1,0x16,0x54,0xfb,0xc5,0x97,0xd7,0x03,0x82,0x47,0xbb,0x47,0xea,0x9e,0x8b,0x90,0x07,0xb2,0xd2,0x06,0x14,0x79,0xeb,0xb6,0xe1,0x10,0x55,0xa9,0x13,0xea,0x65,0x7a,0xd0,0xe5,0x66,0x5d,0xe7,0x7b,0x10,0x5f,0x7c,0x25,0x7d,0x4e,0x77,0xb3,0x19,0x02,0xb1,0x45,0x1c +.byte 0x1a,0x51,0x24,0x72,0xd4,0xaa,0x03,0x0c,0x37,0x2a,0x78,0x81,0x05,0xca,0x73,0xb9,0xb5,0xd8,0xf5,0x25,0x2b,0x30,0x59,0x00,0x66,0xbd,0x6c,0x38,0xa2,0xc3,0xfb,0x43,0x85,0x6d,0xab,0xca,0xd8,0x73,0xa8,0x76,0xda,0x6e,0x00,0x19,0xd0,0xb9,0x1e,0x9b,0x33,0xe4,0x57,0x68,0xf4,0xb8,0x35,0x44,0xe6,0x74,0xd2,0x33,0x64,0xa1,0x41,0xa6 +.byte 0x5a,0xf6,0x8e,0x29,0xb5,0xa6,0x21,0x8e,0xc4,0x0c,0x0c,0x16,0x81,0x08,0xef,0x0a,0x41,0x08,0x34,0xc7,0xe1,0xd8,0xa8,0x68,0xb1,0xf3,0x9a,0x7a,0xaa,0x90,0xc0,0x77,0x32,0x70,0x50,0x5c,0x92,0xfc,0x38,0x31,0xaf,0x3e,0xd8,0xd8,0x4b,0x90,0x99,0xc4,0x17,0xde,0xa6,0xb5,0x29,0xc0,0x82,0x45,0x20,0x08,0x0c,0x4f,0x76,0x36,0x56,0x7e +.byte 0x07,0x17,0x42,0x78,0xa1,0x2d,0x62,0x48,0x81,0x57,0xc4,0xcf,0xf4,0x89,0x34,0x78,0x10,0xe6,0x98,0x78,0xb0,0x69,0x15,0x06,0xdb,0x2b,0xbb,0x8b,0xa5,0x72,0x50,0x24,0xae,0x6b,0x33,0x49,0x7b,0x9d,0x69,0x74,0xc8,0x7c,0xca,0x7a,0x31,0x39,0x0d,0x72,0x78,0xc1,0x6b,0x97,0x50,0x97,0xea,0x90,0xab,0xe7,0xdf,0x29,0x2e,0xf7,0x6e,0x49 +.byte 0x95,0xab,0xbd,0xea,0x1f,0xd4,0x93,0x4d,0x30,0x6b,0x6d,0xb0,0x86,0x38,0x2c,0xc8,0x77,0x2c,0xb5,0xb5,0x5c,0xd9,0xbb,0xe9,0x7d,0xb2,0xb7,0x6b,0xd1,0x1c,0xd3,0xd0,0x66,0x51,0x63,0x8c,0xf3,0x13,0xad,0xcf,0xeb,0x82,0x12,0x1a,0x6d,0xf5,0x75,0x66,0xa2,0x55,0x30,0x64,0x1d,0x68,0x46,0x50,0x5a,0x93,0xf1,0xc2,0x13,0x68,0x95,0x55 +.byte 0x51,0xe0,0x56,0x3a,0x96,0x86,0x8e,0xfb,0x5f,0x3b,0x1f,0x49,0x9c,0x3d,0xe5,0xf2,0x8c,0x3f,0xd6,0x6d,0x17,0xc7,0x18,0x59,0x1a,0x8a,0x72,0xa8,0xb3,0x39,0xda,0xc4,0xfa,0xc5,0xca,0xdf,0x48,0x48,0xd1,0xd2,0xba,0x14,0x5d,0x28,0x3b,0x4c,0xb3,0xcb,0x8d,0x1b,0x91,0x46,0x6b,0x2d,0x21,0x21,0x99,0x98,0x6d,0xcc,0x6b,0x8e,0x91,0x1d +.byte 0x42,0xc2,0x72,0x1a,0xc6,0xd2,0xaf,0xed,0x10,0xff,0x1e,0xa5,0xae,0x16,0xc0,0x05,0xdf,0x37,0xe2,0x1e,0x2e,0x15,0x21,0x0c,0x33,0x6f,0xfd,0xed,0x3f,0x7e,0xd7,0x69,0xfb,0x76,0x79,0x65,0xe9,0xd9,0x8d,0xf6,0xc0,0x6c,0xf7,0x15,0x7f,0x04,0xd7,0x71,0xcc,0xaa,0x85,0x73,0x23,0xf1,0xc8,0x62,0xd0,0x8e,0x01,0x35,0xff,0x4f,0x4f,0x13 +.byte 0xe6,0x28,0xf1,0xc1,0x7a,0x04,0xc0,0x7b,0x75,0xac,0x1c,0x55,0xb4,0x7c,0x00,0xb9,0xe0,0x14,0x67,0xb6,0xc5,0x69,0x62,0x0b,0xe6,0xb5,0x46,0x86,0x6f,0x09,0xdf,0x84,0x2c,0xa8,0x30,0x89,0x5b,0x24,0x47,0xfa,0x43,0x24,0xd5,0x07,0xf7,0xba,0xab,0x1b,0xfd,0x60,0xad,0x89,0x5f,0x60,0x87,0x78,0x48,0xbb,0xc0,0x63,0xf4,0x27,0x86,0x33 +.byte 0xf4,0x49,0x64,0x4c,0x5c,0x94,0x9a,0xb8,0x0f,0x45,0xe2,0x92,0x7d,0x9a,0x86,0xdb,0xb7,0x05,0xe8,0xd7,0x64,0x44,0xfa,0x74,0x60,0x72,0x89,0x13,0x8f,0x2e,0x96,0x33,0xa9,0x12,0x4a,0x62,0x6b,0xc3,0xcb,0x55,0xd3,0xef,0x17,0x11,0x82,0x4a,0x51,0x77,0xbf,0x63,0xa0,0x21,0xfc,0xbc,0x0c,0x6f,0x9a,0xfd,0xde,0xbe,0x9f,0x2e,0x50,0xd5 +.byte 0x32,0xa4,0xf0,0x1b,0xed,0xfa,0xbf,0xcd,0xc9,0xd8,0xf8,0x06,0xf2,0x17,0x8a,0x92,0x18,0xb8,0xc3,0xe5,0xbf,0xc2,0xf4,0x77,0xb9,0x71,0xfb,0x60,0x6e,0xe7,0xad,0xe4,0x7d,0xd4,0x59,0xa9,0xbd,0x21,0xd5,0x03,0x69,0xb5,0xf1,0xce,0xb5,0x88,0xd9,0x1d,0xc7,0xb3,0x14,0xa6,0xb1,0x30,0x8d,0xaa,0xcd,0xe5,0x50,0xc5,0x0d,0x4b,0x6d,0xde +.byte 0x17,0x4d,0xd2,0x93,0xf3,0xc2,0x8d,0x59,0xf1,0xd0,0x2f,0xb5,0x62,0x18,0x81,0x07,0xb3,0xfb,0x08,0xb3,0xa8,0x15,0xe0,0x9a,0x4c,0xa5,0x24,0xcd,0x47,0x69,0xf9,0xf7,0xda,0xa9,0xff,0xe1,0xe2,0x43,0xe3,0x69,0xf1,0x26,0xac,0xc6,0x42,0xf2,0x32,0x42,0xfb,0x7c,0xa2,0x94,0xc6,0xaa,0xd9,0x05,0x29,0xc6,0x3d,0x45,0x44,0x1d,0x52,0x7e +.byte 0x48,0x47,0x93,0x34,0x08,0xa0,0x93,0xc2,0x5e,0x9b,0x22,0xc1,0x2a,0xaa,0xfe,0xa2,0x26,0x00,0xa8,0xbb,0xd0,0x58,0xfd,0x5a,0x09,0x4f,0xa1,0x0c,0xff,0x66,0xcc,0x88,0x3a,0x69,0x9a,0x12,0xb6,0x05,0x6e,0xdf,0x54,0x5d,0xe7,0x03,0x8e,0x95,0x86,0x68,0x83,0x83,0x6f,0x04,0x0b,0x9c,0x05,0x05,0x77,0x14,0x83,0x47,0x98,0x5f,0x22,0xaf +.byte 0xa8,0xfd,0xf3,0xe7,0x73,0xec,0xef,0xd7,0x57,0xd9,0xef,0xe7,0x1b,0x18,0x24,0x09,0xd9,0x14,0xf9,0x60,0xba,0x05,0x0f,0x8f,0x33,0x48,0xb1,0x06,0x41,0x2e,0x95,0x3d,0xf5,0xcf,0x14,0x50,0x5d,0xb6,0x93,0xeb,0xd5,0xf8,0x9f,0x7c,0x8f,0x23,0x35,0x39,0x30,0xc8,0xf6,0x74,0x07,0xc4,0x4c,0xcf,0xe1,0xdb,0x3e,0x9f,0x0a,0xfd,0x48,0x9e +.byte 0x56,0xe4,0xa7,0xa3,0x07,0x06,0x18,0xbb,0x50,0x75,0x33,0x48,0xb9,0xa1,0x4e,0x63,0x65,0xd3,0xf4,0x40,0xc3,0x2d,0x52,0x9a,0xad,0x56,0x7f,0xff,0xb0,0x46,0x24,0xa1,0x78,0x5f,0xb6,0xa8,0x72,0x28,0xb3,0x6c,0x61,0x6e,0xa0,0xfc,0xcb,0xe8,0xfe,0x07,0x28,0x97,0x1c,0xda,0x76,0xc7,0x98,0x2f,0x00,0x1d,0xf2,0x17,0xbe,0x48,0x3f,0xd3 +.byte 0xc7,0xbe,0x89,0x89,0xe1,0x96,0x75,0x1e,0xee,0xf9,0x78,0x67,0xbf,0x12,0x1e,0xe2,0x14,0xbf,0xd4,0xfd,0x49,0xaa,0xbf,0xc6,0xb8,0x4f,0x84,0xcd,0x5d,0x3c,0x45,0xb3,0xb0,0x14,0x6f,0x2d,0x6f,0x35,0xfa,0x60,0x7f,0x64,0x40,0xc8,0xde,0xa8,0x2b,0x56,0x75,0x74,0xc9,0xe1,0x2c,0xe2,0x2f,0xc2,0x3e,0xba,0xa3,0x20,0xd8,0xa3,0xbc,0x69 +.byte 0x9d,0x1c,0xcf,0x5e,0xe3,0xc0,0x66,0x72,0xce,0x22,0x96,0xad,0x47,0xc9,0x5b,0xac,0x45,0xdc,0x4f,0x8e,0xf6,0xa6,0x2e,0x4a,0x1e,0x01,0xe4,0xb7,0x83,0x68,0x92,0x2b,0x98,0xdf,0x22,0x0f,0xd9,0x4f,0x6f,0x72,0x37,0x56,0xfa,0x1b,0xbb,0x5a,0x4d,0xd8,0x5b,0xc6,0x65,0xf8,0xd4,0x4e,0xa5,0xc0,0x0f,0x2d,0xc2,0x38,0xa4,0x6c,0x33,0x2f +.byte 0x7a,0x52,0x14,0xbb,0xfb,0xb3,0xf2,0xa9,0xbf,0xa0,0xad,0xcb,0x8c,0x81,0x47,0x26,0xe9,0xfb,0xc1,0x8e,0xc6,0xe5,0x39,0x48,0xa5,0xb3,0xbc,0xb2,0xe4,0xac,0xf9,0x49,0xbb,0x34,0x2b,0xc4,0x4d,0x06,0xe4,0xd6,0x0b,0xdd,0x55,0x36,0xe6,0xaf,0x64,0xea,0x84,0xf2,0xa5,0x68,0xe3,0x4e,0x4c,0x77,0x46,0x6c,0x17,0x6e,0x08,0x99,0x96,0x1b +.byte 0xb5,0x44,0x3b,0x94,0x2d,0x0f,0xcd,0x90,0x17,0x8f,0x80,0xcb,0xc2,0x30,0xbe,0xe1,0x36,0xdc,0x1e,0x48,0xe3,0x2c,0xe5,0xc9,0xbc,0xbd,0xff,0x3f,0x95,0x59,0x35,0x58,0x2f,0x9c,0xa6,0x1c,0x45,0xa7,0x61,0xde,0xf2,0x9c,0xa3,0x04,0x0f,0xa0,0x93,0xaf,0x69,0x2b,0x0d,0x1c,0xfc,0xff,0x97,0x1c,0x69,0x7e,0x30,0x06,0x88,0x01,0xa4,0xf1 +.byte 0x32,0x36,0xed,0x56,0x89,0xff,0xa9,0x63,0x3a,0x17,0x91,0xc5,0xba,0x6e,0x38,0x84,0xb1,0xaf,0x28,0xac,0x8a,0xb2,0x60,0xbe,0x1b,0x0a,0xd8,0x05,0x22,0x25,0x56,0xbe,0x75,0x47,0x59,0xcf,0x8c,0x2e,0xb3,0xc3,0x5f,0x06,0x81,0x65,0x39,0x78,0xed,0xe3,0xc9,0x5a,0x99,0x01,0xae,0xfb,0xf6,0xed,0x55,0xf5,0xbd,0x2f,0x93,0xf1,0x62,0x6a +.byte 0x54,0x4f,0xe1,0x9f,0x0a,0x23,0x83,0xbc,0xc2,0xba,0xb4,0x6f,0xd9,0x88,0xc5,0x06,0x7a,0x83,0xd5,0xdb,0xeb,0x49,0x48,0xd6,0xc9,0x45,0xa2,0xd0,0xc4,0x06,0xd9,0x01,0xec,0x2d,0x6d,0xc1,0x95,0x69,0x22,0xd0,0xae,0x88,0x75,0x8b,0xd2,0x02,0x98,0x83,0xd9,0x10,0x27,0x8d,0x68,0x97,0x5e,0x6b,0xdd,0x51,0xbb,0x92,0x38,0xa8,0x12,0xde +.byte 0x0f,0xa4,0x1e,0x2e,0xec,0xd5,0x73,0x55,0x5f,0x46,0x6a,0x0f,0xc9,0x50,0x0d,0xb3,0x55,0x20,0xe0,0x01,0xef,0x92,0x29,0x04,0x38,0x60,0xbd,0xc7,0x0b,0x1e,0x94,0x10,0x37,0xb7,0x02,0x94,0xbc,0xde,0xdb,0xb3,0xe3,0x1e,0xd5,0xe2,0xa8,0xed,0x46,0xe8,0xd4,0x8a,0x6c,0x93,0x4e,0xb7,0x73,0xa6,0x20,0x86,0xd2,0x82,0x2f,0x78,0x80,0x34 +.byte 0x44,0x79,0x84,0x2e,0x54,0xd0,0x30,0xa8,0x06,0x0c,0xcf,0x78,0xb4,0xd7,0xe2,0xc9,0x6e,0xfb,0x37,0x47,0x8f,0xe5,0x9f,0xf8,0xca,0x58,0x9c,0xb6,0x8b,0xbe,0xf4,0x3a,0xfe,0x75,0xec,0x1b,0x22,0xfd,0x93,0x92,0x07,0x09,0xcd,0xe6,0x2f,0xe6,0x51,0x0f,0x19,0x43,0x9c,0x6a,0x32,0x38,0x7d,0xf0,0x0c,0x78,0x81,0xb7,0x5c,0xbe,0x3c,0xf4 +.byte 0xc0,0x12,0x57,0x51,0x8a,0x69,0x84,0x0d,0x1e,0x0a,0xed,0x75,0xde,0x9e,0x31,0x8a,0x9b,0x18,0x82,0x01,0x5a,0xee,0x0e,0x33,0x3c,0x8c,0x95,0xb1,0x0b,0x05,0x3b,0xb2,0x85,0xab,0xaf,0x47,0xa2,0x03,0xb6,0xbb,0xda,0xf5,0xc8,0xbe,0x0e,0x4d,0xf8,0x84,0xe4,0xfb,0xd4,0x54,0x44,0x72,0xe5,0x30,0x57,0xa3,0xb6,0x47,0x8f,0xd3,0x32,0xc2 +.byte 0x83,0x07,0x4f,0x17,0x20,0x88,0xa1,0x0b,0xb3,0xef,0x4b,0x27,0x60,0xe0,0x9d,0xec,0xc2,0xdf,0xaf,0x2e,0x74,0xae,0xa4,0x2b,0x59,0x94,0x75,0xbe,0x54,0xf5,0x18,0x62,0xd9,0xe2,0x35,0xee,0x37,0x2e,0xdf,0x48,0xf8,0x80,0x32,0xcb,0xf1,0x83,0x78,0x03,0x68,0x06,0xd7,0x82,0xc6,0x76,0x2a,0x10,0x2a,0xdb,0x73,0xe6,0x65,0x24,0x9f,0x73 +.byte 0x1f,0x55,0x55,0xb6,0x10,0x65,0x80,0x70,0x5a,0x8e,0x8a,0xc8,0x4c,0xca,0x74,0x47,0x63,0x3f,0xee,0x49,0xc3,0x86,0x0f,0x66,0x56,0x08,0xee,0x9f,0xf5,0x5a,0x89,0x4c,0xb4,0x97,0x6e,0x75,0x61,0xc0,0xa7,0x92,0xa8,0x38,0x99,0x08,0x01,0x12,0x82,0x77,0x80,0x20,0x9d,0x62,0x46,0x92,0xdd,0x39,0x4d,0xcf,0xc0,0x8a,0x3e,0x30,0x9a,0xfa +.byte 0x28,0xe8,0xd8,0xf8,0x07,0x0d,0xab,0x4c,0xd4,0x02,0x4c,0xd7,0xc3,0x16,0x89,0x24,0x84,0x52,0x7c,0xa4,0x1b,0x54,0x7f,0xc4,0x74,0x4f,0x88,0x0a,0x14,0x03,0xd9,0x1a,0x48,0xff,0x2c,0xfb,0xbf,0x33,0xf1,0xf8,0x0e,0xdd,0xc4,0x98,0xf2,0xbd,0x32,0x99,0x03,0x8e,0x56,0xc1,0x84,0x5d,0xa6,0xd7,0x21,0xf2,0x43,0xfb,0x3b,0xf5,0x6a,0x75 +.byte 0x20,0xfb,0x08,0x7b,0x66,0x15,0x47,0x31,0xb6,0xb6,0x7a,0xc9,0xe6,0xf5,0xd6,0x0a,0x14,0xb3,0x68,0x0a,0x32,0x13,0xb5,0xe6,0x56,0xbd,0xa5,0x24,0xe2,0xa3,0x7b,0x3d,0x01,0x23,0xed,0x08,0x09,0xb5,0xdb,0x7c,0xa9,0x4b,0x23,0xdb,0xa2,0x25,0x0c,0xc6,0xa4,0x0d,0xbb,0x1a,0x5d,0x1b,0x42,0x0b,0x86,0x72,0xc3,0xca,0x5b,0x14,0x04,0xa3 +.byte 0xd7,0x01,0xe7,0x17,0x78,0xd0,0x54,0xde,0xd4,0x76,0x3d,0xe1,0x7d,0x26,0x3e,0xb4,0x71,0x42,0x84,0x36,0x58,0x78,0x22,0x32,0x26,0x0e,0xc8,0x99,0x05,0xe3,0x4a,0xa6,0x5a,0x1a,0x06,0x0a,0x88,0x47,0x51,0x5c,0xa8,0x72,0x70,0x0c,0x62,0x5f,0xf3,0x1e,0x02,0x50,0x20,0xc6,0x5c,0x50,0x30,0x1f,0x4e,0x5a,0x3a,0x02,0xc9,0xca,0x3f,0xa4 +.byte 0xf1,0x66,0x05,0xf3,0x19,0xe5,0xaa,0xdb,0x75,0x51,0xc1,0xb8,0x94,0xfa,0x2d,0xb6,0x8b,0x42,0xdc,0x9a,0xa3,0x13,0xeb,0x95,0x8d,0xf0,0x65,0x87,0xc9,0xa1,0x43,0xb4,0xfe,0x76,0xf4,0xc8,0xbb,0x19,0x96,0x84,0x9d,0x2f,0x92,0xe8,0x22,0x9a,0xf0,0xd5,0xf4,0xc4,0x8d,0x19,0x59,0x21,0xbf,0x15,0xfd,0xa6,0xc4,0xde,0x77,0x58,0xae,0x93 +.byte 0xb3,0xff,0x44,0x49,0x6e,0x37,0x94,0x04,0xd2,0x96,0xe9,0x80,0xd8,0xe3,0x93,0xd8,0xb4,0x7f,0x5f,0xcf,0xe5,0x9d,0x51,0x92,0xac,0x5d,0x9f,0x23,0x3a,0x3e,0xdf,0x96,0x68,0x9a,0x46,0x9b,0x1a,0x06,0x44,0x54,0xc4,0x2e,0x19,0x0f,0x50,0xee,0x73,0xda,0x39,0x7e,0xec,0xcb,0x1d,0x39,0xf7,0x9f,0xbc,0xe0,0x6d,0x49,0x56,0xf8,0xa7,0x24 +.byte 0x70,0xab,0xe1,0xc3,0x82,0x99,0x0a,0x4d,0x64,0x41,0x37,0xab,0x92,0x76,0xeb,0x6a,0x2a,0xa5,0xab,0x75,0xd7,0xe3,0x6a,0x72,0x4a,0x2b,0x57,0x02,0xc7,0xbe,0xd5,0x35,0xce,0xdf,0xee,0xf1,0xc6,0xe6,0x69,0xb7,0x76,0x99,0x22,0xb0,0xb9,0xe1,0x18,0x91,0x9a,0x35,0xd9,0x3a,0x19,0xc7,0x77,0xf2,0x2d,0xae,0x04,0x2e,0xb7,0x35,0x97,0xa5 +.byte 0xc6,0x97,0x4e,0x5d,0xbe,0xa9,0x35,0x2b,0x53,0x1a,0x6b,0x4e,0xa8,0xa6,0x22,0x48,0x2c,0x81,0x25,0xac,0x30,0x89,0x7b,0xb3,0x38,0x34,0x42,0x0b,0xa5,0x5f,0x02,0xe8,0xee,0x12,0x9b,0xce,0xe7,0x10,0xf9,0x65,0xb6,0xc5,0x74,0x06,0xef,0xc8,0x95,0xb3,0x40,0x30,0xec,0x1f,0x8e,0xeb,0x93,0x31,0x91,0x5a,0x2f,0xc2,0x90,0x85,0xaa,0x4c +.byte 0x51,0xc4,0xd0,0x3e,0xc8,0xc9,0x61,0x46,0x96,0xd4,0x60,0x56,0x7d,0x91,0xc4,0x24,0x76,0xfb,0x09,0x08,0x48,0x2f,0x4a,0x73,0x90,0x8e,0x9d,0xb2,0x38,0xa8,0x95,0x3e,0x6d,0x10,0x57,0x91,0x8d,0x55,0x62,0x1f,0x21,0xc7,0x01,0x15,0xb0,0x71,0x0b,0x26,0xbc,0x10,0x33,0x3e,0x79,0x37,0x64,0x85,0x98,0x42,0x21,0xcc,0xff,0x51,0x9a,0xc2 +.byte 0xe0,0x51,0xc3,0xff,0xf2,0x14,0x3d,0xe8,0x89,0x12,0xe7,0xcd,0x58,0x2f,0x87,0xfb,0x4a,0x50,0x6c,0x4d,0xdf,0x6f,0x64,0x9c,0x64,0x93,0x49,0x89,0xb6,0x0d,0x10,0x3f,0x13,0x9d,0x9a,0x35,0xf1,0xc0,0xe7,0xf0,0x9b,0xe8,0x39,0xd3,0x32,0xb2,0x23,0x67,0x77,0xdb,0xbc,0x0d,0x19,0x77,0x7a,0xbe,0x54,0x56,0x64,0xec,0xb6,0x2e,0x03,0xc5 +.byte 0x35,0xda,0xf1,0xc7,0x7d,0x0c,0x5a,0x32,0xec,0x86,0xdf,0xdb,0x94,0x73,0x4e,0xe3,0x45,0xf6,0xb2,0x63,0xc4,0xb7,0x80,0x59,0x4b,0x82,0x0b,0x61,0xa0,0xd5,0x43,0x18,0x78,0x35,0x93,0xde,0x46,0xa3,0xa2,0xd5,0xa2,0x71,0xec,0x3e,0xee,0x7a,0x89,0x7f,0xe9,0x70,0xff,0xad,0xae,0xa3,0x64,0xde,0x61,0xea,0x71,0xc2,0x37,0x98,0x8a,0x33 +.byte 0xd1,0x5f,0x03,0x08,0x23,0x24,0xc7,0x6c,0x62,0x24,0x6d,0x3f,0x44,0x8e,0x7c,0x9f,0x64,0x87,0xa5,0x79,0x0b,0x16,0x7e,0x4e,0xc0,0x0e,0xb8,0x77,0x56,0x9c,0xa5,0x7d,0x2d,0x5d,0x7d,0x81,0x13,0x2c,0x08,0xd5,0x83,0x84,0x38,0xfe,0x50,0x6f,0xa7,0x30,0x1f,0x06,0xee,0xab,0x13,0xc2,0x19,0xe6,0xcf,0x7b,0x85,0xfc,0x31,0x5b,0xdf,0xb8 +.byte 0x0e,0xe8,0x72,0xba,0x97,0x03,0x25,0xbc,0xad,0x74,0x7c,0xe1,0x59,0xf7,0x08,0xc1,0xe3,0x2d,0xb1,0x05,0xe7,0x1f,0xb9,0x0f,0x09,0xcd,0xe6,0x4f,0x5a,0xf6,0xcc,0xea,0xc7,0x92,0x35,0xf5,0xbc,0x3f,0xef,0xc9,0x2b,0xb4,0xd7,0x66,0x50,0xaa,0x80,0xb9,0xaf,0x5d,0x02,0x9c,0x77,0xdf,0xc0,0xc7,0xe2,0xbf,0x7d,0xff,0x69,0x63,0x3e,0x7c +.byte 0x91,0x94,0xae,0xa4,0x0a,0x25,0xa3,0x1f,0xf3,0xc6,0x88,0xda,0x82,0xac,0xbc,0x1f,0x8d,0x53,0xd6,0xfd,0x2b,0x5c,0x33,0x6d,0x03,0x68,0x92,0x38,0x07,0xeb,0x85,0x7f,0x55,0x89,0x17,0x58,0x7f,0xc7,0xb4,0x7a,0xff,0x15,0xe5,0xe0,0xea,0xce,0xac,0x3f,0x0f,0x09,0x25,0xfa,0x80,0xe3,0x07,0x89,0x4e,0xbf,0x7e,0xc2,0x42,0xf1,0x18,0x78 +.byte 0x05,0xe3,0x6a,0x2e,0xf7,0x2e,0xe5,0xbf,0x63,0x9e,0x48,0x69,0xe6,0x3c,0x4b,0x12,0x73,0x58,0xde,0x0c,0x73,0x27,0x9a,0x95,0xfa,0x51,0x8c,0xbb,0x74,0x31,0x53,0x4e,0x9a,0x13,0xda,0x49,0xf0,0x8b,0xb4,0xcd,0xc1,0xe9,0xaf,0xd6,0x59,0x59,0xa8,0x24,0x94,0xd9,0x4b,0xf8,0x20,0x79,0xa0,0x79,0x01,0x08,0x84,0x9b,0x04,0xe7,0xda,0x06 +.byte 0x22,0x3e,0x85,0x23,0x0c,0xa9,0xe5,0xcd,0xd3,0xc4,0x27,0x8c,0x4e,0x75,0xe4,0x60,0xb5,0xe9,0xc5,0xb7,0xb1,0x3a,0x84,0x68,0x40,0x3e,0x36,0x1b,0x9a,0x64,0x50,0x45,0x6f,0xc6,0x58,0x70,0x46,0x1a,0xca,0xf6,0x81,0x02,0xa8,0x17,0x4d,0x92,0x0d,0xae,0x88,0x1a,0xbd,0x52,0xc0,0x32,0xb1,0x2d,0x2d,0x12,0x9c,0x29,0xfa,0xa6,0x70,0x5f +.byte 0xe7,0x0b,0xd5,0x5d,0xa5,0x49,0x9e,0x9e,0x5b,0x55,0xbc,0xce,0x5b,0xb4,0xef,0x3f,0xe4,0x7c,0x50,0xef,0x58,0xf5,0xfe,0xcc,0xf6,0xd0,0xf1,0x3a,0x0b,0xf2,0x3e,0x1c,0xce,0x22,0x7e,0x88,0x1c,0x8f,0x9a,0x69,0x76,0xa9,0xf0,0x18,0xa8,0x76,0x7f,0x0c,0xa6,0xfd,0x67,0x43,0xc7,0x43,0x67,0x98,0x6e,0x37,0xd4,0x82,0x29,0x62,0xa6,0xcf +.byte 0x2b,0x7c,0xee,0x14,0x4d,0x2d,0x1a,0xfc,0xc6,0xaf,0x5b,0xea,0x8a,0xa8,0x9a,0x3b,0xab,0x7d,0x76,0x15,0x50,0xe8,0x95,0x31,0xc8,0x5d,0x5d,0x19,0x68,0x07,0xf5,0xb0,0x29,0x5f,0x79,0x4f,0x0d,0x2b,0xba,0x1d,0xd2,0xf2,0x83,0x50,0x89,0x0b,0x96,0x16,0xde,0x7c,0x04,0xea,0x9c,0x75,0x97,0x7e,0xd7,0x2c,0xee,0x82,0x7c,0xbf,0x0b,0x71 +.byte 0x05,0x59,0xd7,0x11,0x70,0x8e,0x41,0x62,0x91,0x38,0x3a,0x69,0x3f,0x3d,0xde,0x8e,0x03,0x0a,0xea,0xfb,0xea,0x36,0xf0,0x5c,0xb6,0xdf,0x9a,0x66,0x9e,0x64,0x43,0xaf,0xb7,0x83,0xd1,0xef,0x7c,0xb6,0x9b,0x40,0xd8,0x0f,0x0e,0x0b,0xa7,0xd0,0x98,0xca,0x8e,0x3b,0xed,0xb7,0xa5,0x19,0xca,0x67,0x30,0x87,0x17,0x0e,0xc4,0xe1,0xaa,0x6e +.byte 0xdb,0x67,0xbd,0xf5,0xed,0x10,0x68,0xb1,0x43,0x73,0xaa,0x99,0x1a,0x83,0x0d,0x1a,0x5a,0x8b,0xc8,0xff,0xe9,0xe0,0x1c,0x15,0xda,0xb0,0x99,0x90,0xce,0x1f,0xfd,0x17,0xd2,0xfa,0x8f,0x3a,0xe8,0x1b,0xd3,0x96,0x2a,0x0d,0xa9,0x4d,0x6d,0x77,0x53,0xe8,0x8f,0xc7,0x6b,0xb4,0x3b,0x6d,0x0c,0x8e,0x35,0x67,0x09,0x6e,0x43,0x36,0x52,0x3e +.byte 0x0e,0xf6,0x4f,0x16,0x40,0x45,0x7f,0xab,0x39,0xf2,0x23,0xfb,0x4e,0xea,0x6e,0xcf,0xa0,0xb6,0xec,0x6d,0x93,0x1b,0x6f,0x9f,0xd6,0xce,0xcd,0x1e,0x90,0x5c,0x7d,0x61,0xc4,0xae,0x02,0xb2,0x7a,0xb2,0x25,0x59,0xac,0x0a,0xcb,0xc6,0x28,0xa2,0x9c,0x7b,0x4b,0x05,0x5a,0x23,0x55,0xc8,0x9a,0x72,0xe6,0x3b,0x91,0xa2,0x9b,0x12,0x1c,0x1f +.byte 0x4b,0x85,0x42,0x9d,0x73,0xf9,0x50,0x3e,0x12,0xc4,0x51,0xb4,0xe1,0x2a,0x08,0xfc,0xf9,0xc8,0x5a,0x53,0x79,0xcc,0xd1,0x24,0x4c,0xc1,0xf6,0xe7,0x10,0x9d,0xe6,0xce,0xcc,0xc7,0x04,0xf8,0x7a,0xd4,0x2f,0x0a,0x97,0x32,0xaf,0x38,0x77,0x97,0x78,0xc8,0xa9,0x9a,0xca,0x65,0xee,0x2b,0x07,0x0e,0xb1,0xaa,0x3c,0xee,0x03,0x85,0xf7,0x09 +.byte 0xd1,0x03,0xe5,0x4f,0x8a,0x6b,0xba,0x83,0xd2,0x6a,0x05,0xe6,0x4e,0x59,0x21,0x26,0xcc,0x8d,0x4a,0x91,0x21,0x6b,0xe5,0x7a,0x83,0xed,0x4e,0x95,0x4b,0x16,0x98,0x3f,0x2d,0x51,0xc5,0x67,0x56,0x58,0xc9,0xc3,0x32,0xff,0x91,0x9d,0x7f,0x6d,0xc7,0x8a,0x40,0x58,0x56,0x35,0xca,0xc1,0xa9,0x07,0xe2,0xc6,0xe1,0x8f,0x7b,0x7c,0x68,0x4e +.byte 0xde,0x19,0xc8,0x9c,0x41,0x65,0x74,0x33,0xb5,0x5b,0xf7,0x47,0x91,0x51,0x41,0x56,0x54,0xaa,0x8e,0xa5,0x1f,0xdb,0x50,0xa4,0x97,0x7a,0xea,0x86,0x2e,0xfd,0xdd,0x64,0x23,0x6e,0x44,0x28,0xfb,0xae,0xe8,0xc2,0x38,0x96,0x56,0x2e,0xd8,0x7e,0x3a,0xc8,0xc6,0x7f,0x20,0x15,0xad,0x9f,0xfa,0x5c,0x55,0xf5,0xe1,0x9a,0x07,0x84,0x5b,0x81 +.byte 0x39,0x4b,0x70,0xc3,0xfd,0x2b,0xc5,0xb7,0x47,0x36,0x74,0x5a,0x85,0xaa,0x45,0x94,0x8e,0xbe,0x7f,0x6c,0x45,0xf5,0x02,0x4e,0x5f,0x16,0x04,0x7e,0xfa,0xb8,0xa9,0x38,0xc4,0xd9,0xca,0x5f,0x7a,0xe3,0x96,0x78,0x82,0xa0,0xac,0xef,0xc4,0x2a,0xb5,0xf4,0x7d,0x28,0x8c,0x25,0xba,0x4e,0xd5,0xd5,0xd1,0x24,0xc6,0x05,0xb2,0x18,0x2d,0x66 +.byte 0xea,0xe3,0x42,0x79,0x33,0x9e,0x70,0x3a,0x1b,0x5a,0x8e,0xcb,0x03,0xa8,0x43,0xf3,0xd5,0x66,0x41,0x10,0xd7,0x09,0xf0,0x28,0xe5,0x25,0xe6,0xac,0x9a,0xe6,0x34,0x36,0xfb,0xc4,0xa6,0x9a,0xd0,0x24,0x4d,0x18,0xf9,0xd1,0x8e,0xca,0x92,0x83,0x0f,0x55,0x54,0x6d,0x72,0x81,0x81,0xdb,0x72,0x1f,0xd6,0x32,0xb9,0x32,0x45,0x84,0x9c,0x66 +.byte 0x68,0x7e,0xab,0xb3,0xca,0xf5,0x4f,0xdd,0xb4,0xee,0xbb,0x05,0x70,0xbe,0x4f,0xd1,0x27,0x01,0xcc,0x7c,0x4f,0x47,0x55,0xce,0x91,0x73,0x6f,0xff,0x8d,0xfc,0x0c,0x4c,0xaa,0xfc,0xce,0x9f,0xf3,0x4a,0x46,0x92,0x89,0x84,0x8f,0x4d,0x94,0x37,0xda,0xe3,0x11,0x0d,0x63,0x60,0xcb,0x40,0x8f,0xe8,0x0f,0xf9,0xa1,0x89,0x64,0x44,0x45,0x74 +.byte 0xc5,0xa2,0x73,0x33,0x08,0xa2,0x59,0xb0,0xeb,0x7b,0x7b,0xa7,0x28,0x4c,0x13,0x6a,0x04,0x15,0x14,0xd0,0x3e,0x5e,0xec,0xe1,0x3f,0xe5,0x93,0x06,0x6b,0x60,0x50,0x1c,0x90,0xc0,0x5c,0xea,0x7e,0x58,0xf1,0xed,0xba,0x43,0x0b,0x84,0xf7,0xa4,0xbd,0x4c,0xed,0x88,0x5b,0xae,0xa2,0x0a,0xf6,0x06,0xfd,0x43,0x63,0xfe,0x8a,0x03,0x21,0x8b +.byte 0x27,0xc6,0xef,0xa3,0xa9,0x3a,0xc1,0x8b,0x65,0x62,0x25,0x85,0xaa,0x2f,0xff,0x22,0x96,0xb7,0x5c,0x82,0xde,0x21,0x4e,0x0d,0x8d,0xd9,0x7f,0x97,0x79,0x95,0x6c,0xe6,0xfd,0xb1,0x7c,0x84,0xc8,0x73,0xbc,0x50,0x2f,0x87,0x03,0x56,0xcf,0xea,0x7f,0xed,0x17,0x7d,0xf7,0x61,0x6b,0x6f,0x5b,0xd3,0xe4,0x83,0xbd,0x8b,0xd3,0x8e,0x51,0x57 +.byte 0x3d,0xcc,0xe4,0x09,0xb9,0x73,0x1f,0xb4,0x47,0x5e,0xf2,0x10,0x3e,0xf4,0x9c,0x86,0x02,0xdf,0x3e,0x75,0x1c,0x9b,0xb5,0x0f,0x31,0xc6,0xbb,0x00,0xb4,0x8a,0x1a,0xe5,0x0d,0x9c,0x3e,0x93,0x61,0x5a,0x61,0x86,0x12,0x64,0xaa,0xfd,0xa2,0x6e,0x8f,0xcc,0xcd,0x60,0xa1,0xad,0x6d,0xdc,0xa2,0x7b,0x5a,0xe0,0xee,0x27,0x5d,0xc5,0xfe,0x1f +.byte 0x7b,0x9f,0x33,0xf1,0xee,0x2a,0x58,0x39,0x56,0x14,0x4f,0x2f,0x11,0x26,0x6b,0x56,0x7c,0x75,0xb7,0xc3,0xa7,0xf6,0x54,0xd8,0xa7,0xbb,0x73,0xb5,0xa5,0x83,0x1e,0x65,0x7e,0xa7,0x85,0x74,0xa4,0x04,0x0e,0x26,0x01,0x88,0xbc,0x8b,0x98,0x0c,0x9b,0x74,0x22,0x44,0x16,0x16,0xed,0x94,0x81,0x81,0x13,0x26,0xc9,0x27,0xa9,0xa7,0xe0,0x45 +.byte 0x69,0x6e,0x33,0xcc,0xa3,0x15,0x10,0x99,0x84,0x06,0x95,0x00,0xbb,0xc6,0x8e,0x4e,0x37,0x1b,0x23,0xb2,0xf7,0x4d,0xd7,0x24,0x68,0x6b,0xaa,0x2e,0x57,0x8d,0xd6,0x4e,0xa2,0x69,0xd8,0x8d,0x84,0xb2,0x85,0x91,0x30,0xbf,0x41,0xab,0xcf,0x5c,0xa6,0x51,0x1e,0xf5,0x79,0x5a,0x20,0xfa,0x3d,0x0a,0xc5,0xd7,0x3f,0xa6,0xcc,0xf6,0x9b,0x76 +.byte 0xe0,0xec,0x9e,0x0b,0x23,0xe4,0x74,0x36,0x14,0x6f,0x24,0x9d,0xe7,0xb2,0x41,0xd7,0x68,0x37,0x67,0xdc,0x01,0xb1,0x20,0xf9,0x8b,0x0b,0xf5,0xa7,0x95,0x78,0xa0,0x6c,0x4b,0xc0,0x44,0x92,0x4a,0x75,0x0f,0x61,0xde,0xc3,0xc2,0x3d,0x17,0xa0,0x4d,0x57,0x8b,0x11,0x35,0xbd,0x49,0x87,0x05,0xba,0x5d,0x1f,0x76,0xd4,0x0f,0xb0,0x5b,0x5f +.byte 0xb7,0xf8,0xcf,0x12,0x54,0x19,0x9a,0x49,0x6a,0x42,0xad,0x93,0x85,0x0b,0xe7,0x8c,0x30,0x59,0x82,0x82,0x2d,0xd9,0x89,0xf5,0x8c,0x39,0x9c,0xf5,0xcd,0x25,0x22,0x74,0xcf,0x56,0xa2,0x15,0x40,0xa6,0xa8,0xfc,0xdc,0x85,0x9e,0xab,0xd6,0x94,0x5d,0xd6,0x73,0x07,0xed,0x7b,0x76,0x11,0x67,0xf5,0x52,0xac,0x1a,0x69,0x1f,0x4a,0xa2,0xaa +.byte 0x4d,0x11,0xe0,0xc4,0x4c,0x6e,0x9e,0x8e,0x13,0x46,0x0b,0x95,0x40,0x53,0x35,0x53,0x58,0x7f,0x81,0x5f,0x17,0xd7,0x5e,0x53,0x86,0xf3,0x1b,0x70,0xf1,0x95,0x8f,0xf6,0xd4,0x6f,0x55,0x92,0xa2,0x38,0xd3,0x43,0x6c,0x7e,0xa2,0x21,0x5b,0x18,0x11,0xdd,0x03,0x52,0xe6,0xe5,0xc0,0xc5,0x4e,0x8e,0xda,0xdb,0x91,0xcf,0xf7,0x75,0xc2,0x33 +.byte 0x69,0xd1,0xd1,0x29,0x9d,0x51,0x79,0x91,0xe4,0x58,0x05,0xa5,0xf6,0x54,0x16,0x3e,0x42,0xf3,0xc4,0x1f,0x88,0x94,0xfc,0x6b,0x53,0xb1,0xd5,0x17,0xe6,0xab,0x77,0x33,0x8a,0xd0,0x93,0x74,0x02,0xe0,0x81,0x5e,0xbe,0x2f,0x4d,0xcd,0x25,0x0b,0xd0,0x06,0xd8,0xc9,0xf9,0xcf,0x8e,0xf8,0xc3,0xe2,0x33,0x60,0xe5,0xfa,0x89,0x68,0xf8,0xb7 +.byte 0xef,0x9d,0xfc,0x9d,0x76,0x13,0x2d,0x9d,0x18,0x7d,0x05,0xb4,0xa7,0xa3,0x8a,0x91,0xe0,0x73,0x65,0x89,0xb4,0xc1,0x53,0x7c,0xdc,0xf2,0xab,0x39,0x94,0xc7,0x3d,0xf8,0x1c,0x8f,0x49,0x37,0xee,0xc1,0x19,0x84,0x15,0x3b,0x36,0xb2,0xc2,0xe1,0x16,0xe2,0xfb,0xde,0x1f,0x0e,0xa4,0xea,0x59,0x67,0x2d,0xea,0x47,0xe5,0x2c,0xd1,0xb5,0xa9 +.byte 0xbd,0x5c,0x92,0x34,0x8b,0xc5,0xab,0x4f,0x2b,0x6b,0xc4,0x8b,0xdb,0xbb,0xcb,0x86,0x34,0x35,0xa0,0x5c,0x29,0x1a,0x8b,0xce,0xdc,0xd7,0x46,0x2b,0x20,0x9d,0xea,0xa8,0x97,0x68,0x37,0x56,0x03,0x7d,0x4f,0xb6,0xfc,0x30,0x82,0x68,0xb4,0x56,0xf3,0xbe,0x58,0xcc,0x20,0xc1,0x53,0x9f,0xbb,0x0b,0x2b,0x6e,0xa0,0x2d,0xc0,0x61,0x02,0x0b +.byte 0xf9,0x0e,0x55,0xb8,0xb8,0x23,0x6e,0x50,0xc0,0x36,0xb8,0xf6,0x5e,0xb3,0xa7,0x8f,0xf8,0x7f,0xd0,0x5d,0x0a,0xc4,0x2b,0xa9,0xd3,0x76,0xcf,0x4d,0x27,0xda,0xac,0xf3,0xb0,0xca,0x00,0xa0,0x94,0x12,0x20,0x89,0x22,0xa9,0x89,0xe4,0x23,0x71,0xe0,0xdb,0xec,0xb0,0xa9,0x2e,0x45,0xf6,0x8d,0x1e,0x4b,0x0e,0xc7,0xf8,0x40,0xd6,0xf4,0x2f +.byte 0x80,0x3e,0xf8,0xfb,0xcf,0x7b,0x54,0xb5,0xbd,0x55,0xf2,0x37,0x46,0x9f,0x32,0x45,0x87,0xa3,0x6a,0x51,0x25,0x43,0x54,0xa2,0x92,0xc6,0xbe,0xa4,0x33,0x54,0x82,0xc7,0xf1,0xe4,0x52,0xf9,0x09,0xac,0xc3,0xb1,0x25,0x86,0xc7,0x89,0x83,0x2c,0xf6,0x35,0x9e,0xd1,0xd8,0xb1,0x71,0xed,0xfa,0xae,0x09,0x83,0xb3,0xf0,0xde,0x24,0xed,0x3c +.byte 0xc6,0x60,0xe8,0x15,0x49,0x93,0x29,0x82,0xbf,0x1d,0x23,0x17,0x11,0xea,0xa7,0x53,0x83,0xa5,0xc1,0x9e,0x02,0x17,0x08,0x99,0xa6,0x72,0xaf,0x82,0x3f,0x0b,0x69,0xca,0xb8,0x72,0xa9,0x31,0x71,0x20,0x32,0x57,0x89,0x9b,0x16,0x92,0x54,0xc0,0x99,0x6d,0xa4,0xbf,0x5a,0xb5,0x53,0xa7,0x4c,0x69,0xd8,0xf7,0xe7,0x4c,0xc0,0x76,0xb6,0x35 +.byte 0xdd,0xe7,0xb2,0xd9,0x1c,0xd5,0xf7,0x39,0x32,0x44,0x48,0x02,0x85,0x69,0x02,0xad,0xe6,0xfc,0xbb,0x07,0x9e,0x7f,0xee,0x6d,0x07,0x12,0x21,0xeb,0x67,0x4d,0x74,0x90,0x8f,0x79,0x51,0x9d,0x8a,0x63,0x24,0xab,0x6f,0x8f,0x73,0xd3,0x91,0x68,0x15,0xa9,0x6a,0x84,0x92,0xc2,0xd4,0x4d,0xa8,0xe1,0x4f,0xa2,0x1e,0x34,0xa3,0x9a,0x04,0xf2 +.byte 0xfc,0xc4,0xe7,0xd0,0x52,0xc4,0x49,0x51,0x8e,0x7d,0xaa,0x74,0xaa,0x08,0xbe,0x08,0xf6,0xe4,0xc1,0x61,0xff,0x2e,0x9c,0x17,0x61,0xb6,0x01,0x44,0x18,0xe8,0x5e,0xa9,0xfb,0x02,0x21,0xbb,0x08,0x5c,0xe0,0xd3,0x0c,0x98,0xc5,0x93,0x2a,0x1c,0x69,0xf3,0xe8,0x8b,0x36,0xa0,0x9d,0x1e,0xda,0x18,0x14,0x06,0x7f,0x75,0x3d,0x42,0x92,0x5a +.byte 0xb9,0xb7,0xc0,0xc0,0xb0,0xc5,0xa9,0xb2,0x67,0x24,0xc2,0x28,0x29,0xcb,0x78,0x8e,0xf3,0xd1,0x37,0x63,0xca,0xc8,0x9a,0x1b,0x38,0xa5,0x9f,0x0e,0x0d,0x26,0x5b,0xfe,0x2f,0xdf,0x4f,0xb9,0x21,0x8c,0xc8,0xe0,0x9f,0x71,0xb9,0xc3,0x6c,0xd8,0xd3,0x2f,0xe4,0x3c,0x67,0x35,0x45,0x74,0x7f,0xcb,0x13,0xda,0x64,0x47,0xff,0x6f,0x05,0xf0 +.byte 0x87,0x8d,0x0d,0x1f,0x10,0x47,0x0e,0xf6,0x9d,0x89,0x6d,0x79,0x04,0x77,0x8a,0x6c,0xeb,0x7d,0x9b,0xd7,0x65,0x82,0xa8,0x95,0xa2,0x8c,0x02,0x91,0x0d,0xf2,0xe8,0x65,0x60,0x0d,0xb6,0x1d,0xf4,0xf3,0x41,0x75,0x33,0x21,0x13,0x22,0x93,0x01,0x2f,0x11,0xe7,0xed,0x45,0x56,0x90,0xec,0x0b,0x99,0x8e,0x84,0xc8,0x76,0x31,0x1d,0xb9,0xcb +.byte 0x87,0x3f,0x5f,0x39,0xeb,0xe8,0x9e,0x5e,0x96,0x9e,0x42,0x64,0xf3,0xef,0x00,0x1f,0x2a,0x6c,0x18,0x67,0xbd,0xdd,0xf9,0x65,0x11,0x1b,0x9c,0xd7,0xf3,0x3d,0xb2,0x6f,0x88,0xf7,0xd2,0x26,0x06,0xef,0xc8,0x23,0x3f,0x46,0x5d,0xf0,0x96,0x40,0xb1,0xdd,0xad,0xe4,0xee,0xb6,0xc2,0x67,0x18,0x46,0x67,0xc4,0xa5,0x7e,0x3e,0xce,0x72,0x47 +.byte 0xca,0xc3,0xa7,0x94,0x56,0xe2,0x23,0x03,0xcf,0xd0,0x18,0x55,0x30,0xe3,0x14,0x00,0xda,0x0f,0xaa,0x7f,0x20,0xaf,0x3b,0x24,0x43,0x7a,0xaa,0xd4,0x12,0x42,0x10,0xe4,0x44,0x8a,0x7f,0xf1,0x74,0x9d,0xe0,0x28,0x60,0xce,0xdd,0x04,0x96,0x03,0x80,0xcb,0xaa,0xa9,0xb5,0xc7,0xb4,0xbb,0xc7,0x9a,0x93,0xd8,0xff,0x3b,0x8f,0x1f,0xb7,0xce +.byte 0xed,0xbc,0xde,0x9f,0x9e,0x56,0x96,0x65,0xba,0xe7,0x89,0x03,0xb2,0xbd,0xfe,0xa7,0x02,0xeb,0x33,0x9a,0x8b,0x5b,0x36,0x64,0x17,0x9f,0xd2,0xe4,0x75,0xb5,0xfb,0x21,0x03,0xa4,0xe7,0xb4,0x49,0x72,0xfd,0xf3,0x1e,0x5f,0xdb,0xe5,0x6c,0x92,0x51,0xe7,0x91,0x55,0xb7,0x82,0x18,0x05,0xc3,0x2c,0xf1,0x23,0x61,0x36,0xad,0x80,0x1b,0xde +.byte 0xe1,0x51,0x4e,0x51,0xa1,0xf6,0x5a,0xb9,0x03,0x48,0xa7,0x12,0x88,0x63,0x30,0xff,0x48,0xfc,0x92,0x30,0x9a,0xca,0x08,0x1b,0x64,0xa9,0x74,0x2a,0x64,0x42,0x7d,0xa9,0xa4,0x9d,0xcb,0x59,0x71,0x53,0xc1,0xa8,0xa6,0xb5,0x47,0xf9,0x87,0xb5,0x41,0x58,0x92,0x14,0xf7,0xbd,0x10,0x45,0x37,0x20,0x1d,0x5b,0x42,0x04,0xed,0x69,0x4c,0xa5 +.byte 0xdc,0x2a,0x58,0xba,0x00,0x1e,0x05,0x9c,0x3c,0xbf,0x65,0x76,0xd1,0x11,0xe0,0x15,0x22,0xb0,0x2a,0x53,0x32,0x0f,0x6e,0x08,0x4e,0x27,0xc2,0x71,0x14,0x20,0xee,0xb0,0x0b,0x60,0xef,0x54,0xae,0x2c,0xe0,0x1d,0x30,0xac,0x0d,0x3a,0x93,0x15,0x0a,0xe7,0x14,0xf3,0x1a,0x67,0xb1,0x43,0x85,0xbd,0x06,0x53,0xab,0x6d,0x5d,0xe7,0xe3,0x82 +.byte 0xb8,0x39,0x35,0x10,0x87,0xe7,0x90,0x4d,0x9c,0x6f,0x83,0xad,0xa2,0x43,0x7a,0x5d,0xc1,0x8a,0x39,0xa3,0xa6,0xda,0x48,0x5c,0x9b,0xe1,0x0d,0x69,0xfc,0x87,0x18,0xdd,0x34,0x9a,0xb4,0x9c,0x04,0x0d,0x49,0x18,0x3e,0x38,0xd8,0x01,0x67,0xb1,0x7f,0x6b,0xb5,0xfe,0x58,0x1c,0x64,0x11,0x10,0x6b,0xc1,0xca,0x56,0xe3,0x12,0x8c,0xb4,0xac +.byte 0x03,0xbd,0xc1,0x54,0xbe,0x5c,0x70,0x6f,0xdd,0x73,0xa3,0x84,0xcd,0x0b,0x1b,0xbf,0x05,0xac,0x27,0x11,0xe8,0x5f,0xc3,0xb9,0x68,0xc2,0xe9,0x3f,0x5a,0x9b,0x28,0xca,0x65,0x5e,0x66,0x4e,0x50,0xa9,0x81,0xb1,0x10,0xc1,0x2c,0xa5,0x62,0xc8,0x52,0x07,0xa5,0xa1,0x99,0x16,0x7b,0x08,0xa4,0x1e,0xf4,0x50,0x8f,0xb2,0x42,0xa5,0x19,0xa2 +.byte 0x34,0x91,0xcf,0xa7,0x5e,0x73,0x6b,0xc2,0xa3,0x4d,0xdd,0x7c,0x26,0x46,0x34,0xe6,0x5d,0x54,0x52,0xe3,0x1e,0xc1,0x10,0x36,0x7c,0xc9,0xd2,0x1e,0xca,0xeb,0x80,0xc5,0x3c,0x04,0xf6,0xb7,0x09,0xd4,0x3e,0x67,0xc3,0xf6,0x6b,0xd4,0x60,0x00,0xc9,0x68,0x17,0x39,0xbc,0xcd,0x14,0x32,0xfc,0x33,0xa4,0xb0,0x6f,0x12,0x6b,0x5f,0xe2,0x15 +.byte 0x1c,0x9a,0x15,0x4f,0x0b,0x7d,0x4c,0xa0,0x89,0x40,0xb3,0x0e,0x84,0x90,0xb3,0xc6,0x3e,0xa5,0x0b,0x81,0x66,0x14,0x5f,0x8d,0xe0,0xbf,0xf7,0x9d,0xa4,0x4e,0x69,0xd5,0xac,0x0f,0x6c,0x29,0x94,0x8f,0x3b,0x4b,0xed,0x5b,0x6e,0xe1,0x58,0x5d,0x32,0x19,0xe6,0xbd,0xfb,0xd5,0xb7,0x0f,0x72,0x0e,0x5b,0x14,0xd3,0xf3,0x09,0xa8,0xea,0xf7 +.byte 0x98,0x2f,0x42,0x07,0x8e,0x72,0x27,0x53,0x8d,0x0b,0xea,0x74,0x38,0xbc,0xaf,0xb8,0x76,0x65,0x97,0xda,0xa7,0x06,0x37,0x29,0x09,0xbe,0xaa,0xe6,0xf7,0xb6,0xb1,0x5f,0x71,0x1f,0x5d,0x14,0x47,0xdf,0x20,0xa3,0x94,0x93,0x7d,0x21,0xe6,0x22,0x7e,0x38,0x1a,0x26,0x83,0xc7,0x32,0xdf,0x58,0xcd,0xab,0x67,0xae,0x94,0xa5,0x68,0xcb,0xe3 +.byte 0x51,0x70,0xc0,0xc4,0x41,0x9f,0xca,0x05,0xc9,0x51,0x2a,0x8e,0x53,0x89,0x3f,0x52,0x6b,0x29,0x64,0xa8,0xb8,0xdf,0x02,0xb1,0x41,0x4e,0x36,0x42,0x32,0xa8,0xc0,0x91,0xf0,0x69,0x69,0x55,0x99,0xb7,0x78,0x4f,0x79,0x5b,0xc5,0xab,0xc6,0xed,0x15,0x88,0x6b,0x94,0x0a,0xdd,0xea,0x47,0xf9,0x0e,0xb8,0x89,0x15,0x68,0x3e,0xc0,0x50,0xf8 +.byte 0xa1,0x2d,0x2a,0x11,0x8a,0xc5,0xb0,0x09,0x4f,0x7d,0x90,0x5f,0x49,0x35,0xe9,0xdd,0xfc,0xac,0xea,0x1b,0x20,0xad,0xd2,0xe6,0xb6,0xbf,0x3c,0x0e,0x7b,0xdf,0x2f,0x55,0x58,0x0e,0x25,0x53,0x62,0xd3,0x73,0xb8,0x3e,0x12,0x91,0xcb,0x23,0xf2,0xc0,0x5d,0x74,0x2b,0x51,0xcc,0xa2,0xb1,0x5a,0xd2,0xf4,0x9b,0xc9,0xa5,0x83,0x2b,0x5a,0x8a +.byte 0x0b,0xe9,0x09,0x59,0xb5,0x44,0xc9,0x55,0xcc,0xbd,0xb6,0x69,0x66,0x9a,0x0c,0x15,0xae,0x76,0x35,0xbe,0xe9,0x37,0x70,0x9e,0xdc,0x97,0x5a,0x82,0x97,0xf6,0x1a,0x45,0xd7,0x27,0xfe,0x1f,0xc3,0x7c,0x3a,0x52,0x85,0x12,0x73,0x8a,0x8e,0x07,0xec,0x1f,0x59,0x3f,0xb0,0x32,0x07,0x92,0x3e,0x81,0xe0,0x7a,0x9a,0xc9,0x91,0xca,0x84,0xf1 +.byte 0xe1,0x32,0x57,0x0a,0x3c,0x9a,0x20,0xa8,0xbe,0x84,0x91,0x44,0x66,0x81,0xdd,0x12,0xa8,0x46,0x15,0x18,0xfc,0xae,0x5e,0x9a,0xf3,0xd9,0xb9,0x6a,0xbb,0x90,0x1c,0x61,0x7f,0x61,0x2c,0xa7,0x12,0x1e,0x05,0xee,0x0c,0x66,0x9e,0xc2,0xc8,0xb9,0xe0,0xc9,0xc4,0xb9,0xee,0x3a,0x6f,0x97,0x2a,0x5e,0xcb,0xd9,0xff,0xd1,0x37,0x5e,0xa0,0x03 +.byte 0x70,0xc1,0x2f,0x15,0xf9,0xf7,0x90,0xbe,0x23,0xe7,0x7c,0x90,0x4b,0xe4,0x5a,0x01,0x65,0x27,0x2d,0x4b,0xd3,0xa8,0x8c,0x1d,0x2d,0x5d,0x48,0xac,0x6b,0x59,0xc9,0x78,0xb2,0xee,0xda,0x6e,0xa8,0x68,0x08,0x99,0x22,0x25,0xfe,0xc2,0xb8,0x83,0xa8,0x08,0xbb,0x6e,0x64,0xae,0x2e,0xbb,0x93,0xaf,0xdc,0xeb,0xa3,0x11,0xa7,0x5d,0x3f,0x22 +.byte 0xf1,0x95,0x27,0xf6,0xd6,0xa6,0xc3,0x56,0x0a,0xd0,0x17,0x43,0x35,0xd2,0xe7,0xa4,0x8f,0x6c,0x1c,0xc4,0x4d,0xa7,0x3b,0xb8,0x7f,0x0c,0xa0,0xd6,0x56,0x82,0xf4,0x16,0x96,0xcd,0xcf,0x6f,0x78,0xec,0xbb,0xb2,0xdb,0x67,0xcf,0x78,0x0c,0x22,0x1d,0x72,0x21,0x8e,0x40,0x85,0xa5,0x07,0x3b,0x0e,0xfa,0x44,0xb0,0xfe,0xbf,0x54,0x80,0x41 +.byte 0xdc,0xa7,0xc7,0xdb,0xaa,0x04,0x42,0x0d,0x42,0x03,0x17,0xc8,0x57,0xd7,0x08,0x34,0x37,0xf5,0x9a,0x90,0x30,0x43,0x54,0x5b,0x58,0x50,0x4e,0xc4,0x56,0x57,0xff,0xf0,0x05,0x82,0xca,0x2e,0x20,0xb0,0xbd,0xd0,0x00,0x7d,0x60,0x3f,0xdb,0x9c,0x08,0x7e,0x21,0x63,0xbc,0x89,0xbf,0xcb,0xcc,0x36,0xb5,0x36,0x41,0xb4,0x9c,0x5c,0x9d,0xa6 +.byte 0x74,0xa4,0x4f,0x6a,0xcb,0x63,0x51,0xb1,0x92,0xa0,0x03,0x9b,0x88,0x03,0xd5,0x82,0x30,0xfb,0x69,0x49,0x20,0xb0,0x37,0x50,0xe4,0x02,0x9e,0x11,0x09,0x20,0x1a,0x41,0x8d,0xdd,0xa0,0x18,0xb4,0x74,0x04,0x1e,0x3a,0xea,0xb4,0x28,0x01,0x7f,0x0b,0x73,0x27,0x5f,0x76,0x2e,0x71,0xfa,0x50,0x1b,0x43,0x8d,0x0d,0x6c,0x87,0xc3,0x10,0x7b +.byte 0x42,0x7d,0x17,0xa6,0x00,0x5b,0x83,0x6c,0x7b,0x7f,0x72,0xd8,0x90,0x4d,0x7f,0x54,0x72,0x17,0x21,0xe4,0x45,0x74,0x20,0x53,0x30,0x46,0x90,0xbf,0x2f,0xac,0x01,0xbd,0x40,0xa9,0xc5,0xbe,0xbd,0x9b,0x59,0x62,0x03,0x30,0x80,0xe3,0x8e,0x23,0x7b,0x2d,0x63,0x4f,0x30,0xe3,0xb8,0x56,0x87,0x57,0x43,0xdc,0x6a,0x3c,0x13,0xed,0x93,0xc9 +.byte 0x1a,0x1b,0xea,0x38,0x67,0x33,0x7f,0x11,0x5c,0x96,0x20,0x4d,0xf6,0x82,0x51,0x45,0xca,0x20,0xfd,0x59,0xef,0x4c,0xb4,0xb0,0xb2,0x0f,0xdb,0x4c,0x00,0x7a,0x18,0x58,0xb0,0xd3,0x65,0x73,0x42,0xe5,0x05,0x76,0xd7,0xa2,0x1e,0x9f,0x59,0xc0,0xd0,0x76,0x29,0x1b,0x12,0x29,0x9b,0xe4,0x7d,0x45,0x13,0xb4,0x57,0xf2,0x0b,0xd1,0xb5,0x60 +.byte 0x6d,0x15,0x0b,0xca,0x5e,0xe4,0x80,0xda,0x56,0x95,0x41,0x18,0x54,0xa7,0xad,0x40,0xe5,0xd7,0xa7,0x3e,0xf7,0x73,0x40,0x70,0xb3,0x23,0xdb,0x22,0x62,0xc7,0x44,0xfb,0x64,0x18,0x18,0x05,0x84,0x07,0x68,0x06,0x7f,0xb9,0xc3,0xf9,0x55,0xe2,0x0d,0x37,0x51,0x34,0xc3,0x55,0x3c,0x29,0x5d,0x1d,0x27,0x77,0xd3,0xe1,0x6a,0x60,0x9f,0x10 +.byte 0xef,0xb1,0x93,0xbf,0x2a,0xb7,0xe8,0x42,0x4d,0xfd,0xa9,0xa9,0x2f,0xb6,0x07,0x5b,0xe8,0xf7,0xd7,0x10,0x47,0x71,0x56,0xba,0x11,0x11,0x32,0xc4,0x22,0xf4,0x12,0x6f,0xc3,0xef,0x81,0xc5,0x82,0xb4,0x1b,0x99,0xbb,0x1a,0x63,0x6b,0x3a,0x70,0x4f,0xec,0x2c,0xf9,0xde,0x1a,0x2e,0x62,0x27,0x1c,0x81,0x21,0x30,0x08,0x30,0xf6,0xf5,0xc1 +.byte 0x6d,0x0b,0xeb,0x34,0xd9,0x3a,0xa2,0xa2,0xc6,0x17,0x60,0x85,0x65,0x43,0xd6,0x3d,0x71,0xac,0xc2,0xaf,0x2b,0x9e,0x62,0xf2,0x08,0x47,0x6f,0x42,0xa8,0x21,0xad,0x42,0x98,0xa0,0xef,0xdf,0xd8,0xda,0x10,0xad,0xf7,0xe5,0xf9,0x22,0x89,0x44,0xbf,0x86,0x86,0x2b,0x02,0xd1,0x9e,0x8f,0xb7,0x10,0x63,0xb1,0xcc,0x40,0x6b,0xa3,0x8e,0x09 +.byte 0xb8,0xe3,0x77,0x3c,0xde,0x36,0x7a,0xb7,0x78,0x4f,0x99,0x5d,0x9a,0x9e,0x19,0x2d,0xb5,0xd9,0x9c,0x95,0x1f,0xa1,0xcc,0x61,0x31,0x1c,0x96,0xe5,0xca,0xeb,0x26,0x34,0xa4,0x63,0x5c,0x7c,0x0f,0x23,0xd1,0xe1,0x09,0xf4,0xab,0xf6,0x73,0x2f,0x8a,0x62,0xf0,0xd3,0x8c,0x44,0xe5,0xe9,0x9d,0x58,0x71,0xfa,0xf5,0x39,0xa5,0x6f,0xf7,0x04 +.byte 0x43,0x0a,0x78,0x54,0xfb,0xa7,0x66,0x57,0x1f,0x61,0xd6,0xda,0xff,0x4f,0x32,0x9d,0x80,0x6b,0x77,0xed,0xda,0xaf,0xbc,0x9e,0xea,0x77,0x04,0xf3,0x47,0x96,0xd1,0x44,0x8e,0xca,0xfe,0xb0,0xa3,0xa6,0x1d,0x8d,0xa4,0xb5,0x8c,0x35,0x28,0xf3,0xaa,0xab,0x28,0x1e,0xc9,0x94,0x12,0x07,0xc6,0xea,0x23,0xf9,0x69,0xc3,0x14,0x27,0xcc,0x55 +.byte 0x27,0x0b,0x27,0x64,0x23,0x38,0x05,0xd9,0xb4,0xf7,0x00,0xf3,0x02,0xae,0xc8,0x5a,0xbd,0x2f,0x20,0xd5,0x45,0xa6,0x09,0x6f,0x1a,0x09,0xb7,0xe7,0x6f,0xf6,0xa6,0x6f,0xc7,0x03,0x4e,0xa3,0x72,0xb5,0xfc,0x17,0xcf,0x1e,0x64,0x8b,0xc4,0xa2,0xba,0x83,0x0e,0x2a,0x11,0xba,0x71,0xe0,0x1c,0x9f,0x70,0x6e,0xf4,0xd9,0x47,0x31,0xf7,0xaf +.byte 0xf7,0x1a,0xe7,0xc1,0xe9,0x66,0xa4,0x48,0xd4,0x25,0x8b,0xf7,0x6f,0x33,0x72,0xff,0x93,0x2e,0xcd,0xc7,0xae,0x3b,0x71,0x3f,0x84,0x7f,0xe6,0xb5,0x58,0x4f,0x95,0x34,0xe7,0x89,0x10,0xd3,0x2b,0x5c,0x30,0x9b,0xd3,0xef,0x98,0xf3,0x33,0x0e,0x6d,0x5f,0x7e,0xba,0x55,0x7a,0xb6,0xf3,0xb6,0xcd,0xa8,0x10,0x68,0x85,0x6f,0xea,0x54,0xc3 +.byte 0x66,0x51,0x5a,0xfc,0x11,0x83,0x9e,0x68,0x95,0xdb,0xec,0x74,0xf0,0x86,0x4a,0x90,0x24,0x66,0xf2,0x61,0x40,0x2e,0x3b,0x53,0xea,0xc1,0x3e,0x1c,0x69,0xaf,0x5f,0x04,0xb5,0xbd,0x3d,0x44,0x1c,0xc6,0x49,0x65,0xf6,0x78,0xfd,0x69,0x49,0x95,0x96,0xa1,0xa0,0xa9,0x78,0x1a,0xf6,0x0f,0xe9,0x52,0x93,0x9c,0x96,0x6c,0x5e,0x67,0x63,0x2d +.byte 0x18,0x22,0x2a,0xcc,0x7f,0x2f,0xd3,0x72,0x82,0x98,0xae,0xb0,0x2b,0xa6,0x96,0x41,0x25,0x47,0x3c,0x92,0xc5,0x0f,0x2c,0xd4,0x43,0x09,0x0b,0x94,0x73,0x73,0x29,0xc2,0x8a,0xa3,0xcc,0x8d,0xed,0x40,0x6d,0x40,0x18,0x7c,0x32,0x1e,0xe1,0x4e,0x26,0xa7,0xa4,0xd5,0xcb,0xfa,0x90,0xba,0xb2,0x04,0x1d,0x5d,0xbe,0x32,0x6c,0x71,0x09,0x51 +.byte 0xdb,0xe3,0xb0,0xe1,0x34,0x74,0xa3,0x2b,0xf2,0xcb,0x9e,0xc0,0xae,0x88,0x40,0x90,0xb6,0x22,0xc8,0xac,0xff,0x45,0xc6,0xfa,0xce,0x0f,0x03,0x9d,0xc0,0xb2,0x2e,0xdb,0x1e,0x6c,0xa5,0xbe,0xb5,0xb3,0xaa,0xd5,0x2d,0x06,0x4d,0x29,0xa3,0xbe,0x25,0x5f,0x21,0x42,0x8d,0x27,0xaa,0x6f,0x59,0x88,0x61,0x4d,0x72,0x9f,0x64,0xfc,0x07,0xaf +.byte 0xeb,0x02,0x5e,0xb9,0x1f,0xfe,0x1a,0x67,0x10,0x35,0xe9,0x9f,0x5f,0x9c,0x8d,0x4a,0xb3,0x10,0x99,0x8d,0x5b,0x9c,0x8b,0x8a,0x0c,0x02,0x8b,0x44,0x1a,0xaa,0xe7,0x14,0x05,0x3d,0x9e,0x62,0xfc,0x76,0x49,0x56,0x46,0xae,0xcc,0x0e,0x47,0x58,0x4d,0x94,0x33,0x4d,0x23,0x24,0x44,0x52,0x2e,0x18,0xf7,0x53,0x6b,0x24,0x67,0xb8,0x88,0x46 +.byte 0x70,0xc8,0xcb,0x60,0xac,0x70,0x85,0xdd,0x00,0xa1,0x5d,0xbb,0x94,0x07,0x0a,0xb6,0x1c,0x88,0x59,0xa7,0x88,0x7e,0x1e,0xc9,0x1d,0x7c,0xa0,0x1c,0xad,0xe4,0xa5,0x36,0xa5,0x35,0xe8,0xda,0x27,0x15,0xbc,0x7b,0x1e,0x8a,0x33,0x74,0x4b,0xc1,0xc7,0x9d,0xa9,0x21,0x98,0x02,0xe5,0xf4,0x8b,0x8e,0x2d,0x64,0x81,0xea,0xa6,0xbe,0xe2,0x05 +.byte 0x16,0xba,0xac,0x75,0x79,0xa4,0xc0,0xd3,0x9d,0xe0,0x25,0x63,0x22,0xb3,0x9c,0xee,0x04,0x8f,0x60,0xab,0x52,0x43,0x05,0x16,0xd4,0xb3,0x88,0xe8,0x68,0xc3,0x81,0x94,0xc4,0xee,0x13,0xaf,0xdd,0x36,0x23,0xe6,0x78,0xc9,0xf6,0x42,0xf0,0xf7,0x89,0x64,0x79,0x13,0xe8,0xed,0x50,0x03,0x16,0x78,0x6d,0xf4,0xdf,0x85,0x2e,0x4e,0x8f,0x2c +.byte 0x5b,0xfe,0x4c,0xf2,0x49,0xde,0xf2,0xa4,0x96,0xe0,0x8a,0x25,0xc8,0x6d,0x22,0xff,0xab,0xfc,0x18,0xe8,0x7f,0xd5,0xc1,0x7e,0x44,0x8e,0x21,0xb4,0xc8,0x79,0xc0,0x55,0xaa,0xb7,0x28,0xa1,0x3a,0xbd,0xc2,0x1d,0xf8,0x87,0xf9,0x35,0x30,0x25,0xb2,0xaa,0x8f,0x3c,0x0d,0x64,0xf2,0xd1,0xa0,0x51,0xbf,0x9b,0x9a,0x9a,0x9c,0x18,0x43,0xea +.byte 0xd2,0x54,0x50,0xe0,0xca,0x1a,0x29,0x16,0x9f,0x49,0x47,0x56,0x65,0x21,0x0f,0xb0,0x53,0x41,0xe3,0xec,0xe0,0x15,0xcb,0xd0,0x61,0x05,0x67,0xd6,0x02,0x1a,0x31,0x80,0xa4,0x9f,0xf5,0x9b,0x28,0xcd,0x43,0xd5,0x70,0x05,0x67,0xe8,0x76,0xb7,0x99,0x98,0x0a,0xd6,0x27,0xe9,0xfb,0x62,0xff,0x66,0x47,0xf7,0xbe,0x5e,0x35,0xa0,0x3b,0x56 +.byte 0x58,0x78,0x9b,0x9c,0x5b,0x9f,0xf5,0x6b,0x1a,0x6a,0xfd,0x8e,0xe3,0xd9,0xa2,0x8b,0x2e,0xef,0xc7,0xd3,0x74,0xb1,0xea,0x6a,0x03,0x8b,0xe2,0x78,0xbe,0xf1,0x75,0x7f,0x02,0x03,0xbc,0xd3,0x15,0x2c,0x87,0x01,0x95,0xa6,0x87,0x2d,0xf8,0x63,0xfe,0x33,0x8f,0xc5,0xc9,0x0a,0x06,0x79,0x93,0x46,0xd7,0x0b,0x61,0x06,0x68,0xae,0x9b,0x46 +.byte 0x6f,0x9e,0x1b,0x21,0x58,0xc1,0x72,0xa9,0x05,0xa7,0xaa,0x88,0xee,0xed,0x8d,0x7f,0x55,0x3b,0xb8,0xb8,0xf8,0x42,0x26,0x4a,0x78,0xe3,0x17,0xe8,0xac,0xb3,0xdb,0x9b,0x90,0x7d,0x8d,0x65,0x00,0x39,0x40,0xc2,0xe2,0x9c,0xc6,0x16,0x35,0x54,0x64,0x09,0xc8,0xc7,0x08,0x77,0x90,0x9d,0xb4,0xd4,0xe1,0x36,0xd4,0x5e,0x63,0xb0,0xba,0x81 +.byte 0x0c,0x4e,0x24,0x20,0xc0,0x7f,0xfc,0x02,0x3d,0x83,0x60,0x8a,0xf5,0xff,0x87,0x60,0x9c,0xd5,0xc0,0x94,0x64,0xe2,0x3f,0xeb,0x9a,0xe5,0xb6,0x50,0x13,0x36,0xf4,0x96,0x5d,0xf4,0xb5,0xab,0xa4,0x28,0x17,0x38,0x7f,0xca,0xf7,0x0c,0xcf,0xae,0xf8,0xef,0x41,0x6d,0x9c,0xa1,0x53,0x33,0xcb,0x8d,0x21,0xab,0x3a,0x8c,0x72,0x8d,0xf3,0xf2 +.byte 0x05,0x69,0xf5,0xe8,0x6b,0x5b,0x42,0x85,0xb1,0x2e,0x6f,0xf8,0x62,0x00,0x1c,0x48,0x6c,0x85,0x72,0x93,0x34,0x67,0x80,0xe7,0x2a,0xfe,0xcf,0x54,0xc6,0x94,0xf2,0x5a,0x48,0xab,0x40,0x52,0x66,0x7d,0x7a,0x75,0x68,0x77,0xfd,0xb2,0xdd,0xb1,0xdb,0x72,0x50,0x31,0x53,0x24,0xbd,0xb0,0x6e,0x1f,0xbd,0xa6,0x90,0x67,0x07,0x1d,0x31,0xf3 +.byte 0x8c,0x82,0xf7,0x53,0x85,0x54,0x64,0x7c,0x76,0x7b,0x5f,0xaa,0xe0,0xe0,0x36,0xa4,0x13,0xb3,0x0b,0x99,0x09,0xfe,0xed,0xbb,0x81,0x4b,0xb3,0x16,0x45,0x2e,0x3a,0xfe,0x60,0x9c,0xdc,0xcb,0x00,0x5a,0x41,0xc4,0x80,0x3c,0x9d,0x15,0x05,0xfa,0x5e,0x37,0x64,0x89,0x9c,0x2d,0xb8,0xf7,0xbc,0x35,0x8c,0x49,0xfe,0x0a,0x43,0x1a,0x59,0xaf +.byte 0x1e,0x50,0x08,0x0f,0x2d,0xb8,0x5d,0x63,0x7f,0x95,0x6a,0xe6,0xad,0x88,0xc3,0xac,0x05,0x14,0x44,0xb0,0x70,0x83,0x5f,0x94,0x45,0x3d,0xe5,0xbd,0xb8,0x92,0x28,0x20,0xd5,0xa0,0x83,0xd2,0xe2,0x41,0x71,0x27,0x29,0x1b,0x2a,0x3a,0x08,0xca,0x75,0xec,0x16,0x4a,0xcf,0x39,0xed,0xbe,0x2a,0x26,0x9b,0xa3,0x26,0xc6,0x89,0xf2,0xc6,0x8d +.byte 0x49,0x3a,0xfe,0xda,0x16,0x54,0x55,0x7e,0x7f,0x65,0x65,0xd2,0x16,0xdd,0xe2,0xa3,0x86,0x7a,0x69,0x82,0x99,0x58,0x45,0x16,0x4c,0x69,0xff,0x72,0xf2,0xbc,0xbb,0xdd,0xe1,0xb4,0x56,0xcf,0xc0,0x84,0xd6,0x2c,0xd8,0xce,0xf4,0x67,0xd8,0x1d,0xb7,0x77,0x6d,0x96,0xf4,0x28,0x7a,0x33,0x03,0x97,0x72,0x37,0xd9,0x35,0xcf,0x20,0x28,0xc2 +.byte 0xc4,0xea,0xf9,0x99,0x89,0xe0,0xcc,0x3d,0xec,0x2c,0xbf,0x06,0x78,0x91,0x1b,0x55,0x1b,0x51,0x9b,0xbe,0xf7,0x4a,0xf8,0x9f,0x46,0xab,0xee,0x5d,0x4e,0x29,0x36,0xf3,0xb9,0xa7,0x85,0x9b,0xf7,0xa1,0x9e,0x2a,0xbb,0xb3,0x0a,0x61,0xb5,0x0f,0x79,0xf4,0xe2,0xd2,0x2c,0x15,0xf7,0x4f,0xca,0xa9,0x46,0x25,0x1c,0xdc,0xfa,0x0f,0x9e,0xfa +.byte 0xf5,0xb8,0x54,0x7a,0xe3,0x98,0x3c,0x3b,0x85,0xf8,0xb3,0x7c,0x70,0x40,0x86,0x2a,0x66,0xd1,0x4d,0x83,0x38,0xc2,0x24,0x8e,0x30,0xc0,0x9e,0x54,0x4c,0x7a,0x62,0x9a,0x55,0x8e,0x11,0x02,0xef,0x30,0x08,0x5c,0xf3,0x57,0xa7,0xbe,0x32,0x04,0xab,0xb1,0x3a,0x51,0x6e,0xcd,0x6f,0xc1,0xd8,0xd0,0x7d,0x4f,0x1b,0xa9,0x1e,0x12,0x92,0x94 +.byte 0xd7,0x40,0xa9,0x99,0x70,0x06,0xcb,0x46,0xa5,0xe0,0x77,0xbe,0x6d,0x48,0xab,0x67,0x4e,0xa7,0x0e,0xfe,0x1f,0x53,0x24,0xbc,0x89,0xcb,0x70,0xac,0x05,0xa2,0xf4,0xa3,0x44,0xde,0xcb,0x18,0x95,0x78,0x70,0x0f,0x69,0xf0,0x5e,0xbd,0xe7,0xfc,0xd3,0x17,0x3e,0x18,0xb0,0x2f,0xa6,0xfe,0x82,0x81,0xe7,0x74,0x44,0xfb,0x43,0x5e,0xda,0xf4 +.byte 0xfb,0xfe,0x5c,0xb4,0x3c,0x1d,0xea,0x0d,0x2d,0xdb,0xee,0x1f,0xc5,0xbd,0xb2,0xa0,0x52,0x76,0x9e,0xad,0xfa,0x19,0x37,0xb0,0x15,0x53,0x82,0x25,0x86,0xd9,0xce,0x99,0x84,0x67,0x5f,0x57,0xb2,0x6f,0x99,0xa4,0x56,0xb5,0x01,0x4f,0xdf,0xa2,0xca,0x8c,0x23,0x51,0xd3,0xc7,0x72,0x9b,0x90,0x72,0x29,0x0c,0xca,0x86,0xff,0xc3,0xd9,0x9e +.byte 0x87,0xe4,0x8d,0xc6,0xac,0xba,0xfb,0x73,0xa9,0xcd,0x5d,0x16,0xfc,0x12,0xea,0x30,0xd5,0x7d,0x7b,0x16,0xa6,0x2c,0xeb,0x3c,0x3e,0x46,0x7c,0xee,0x03,0xd6,0x7a,0xe8,0x88,0x1c,0x17,0xa9,0x08,0xe9,0xd5,0x38,0x59,0x54,0x0b,0xb0,0x77,0x1b,0x76,0x09,0x53,0xca,0x38,0x12,0xd1,0xb5,0x2c,0xe3,0xd6,0xa0,0xca,0x9f,0x65,0x56,0xea,0x95 +.byte 0xab,0xc1,0xf4,0x98,0xaf,0x1a,0xe7,0x2b,0x1e,0x8d,0x75,0x43,0x43,0x9f,0x42,0x5c,0x2c,0xa5,0xd7,0x9a,0xcd,0xc2,0xab,0xd9,0x1f,0x1f,0xde,0x8a,0x3e,0xf8,0x0f,0x56,0x8a,0x01,0xde,0x47,0x41,0xd8,0xa0,0xc8,0x32,0x4d,0xa3,0x75,0x80,0x87,0xb1,0x1e,0x05,0x06,0x5e,0x2c,0x9a,0x7b,0xd3,0x22,0xe0,0x53,0x8f,0x4f,0x35,0x5f,0x46,0x3a +.byte 0xb2,0xfe,0x62,0x44,0x54,0x38,0xe0,0x03,0x5e,0xda,0xcb,0x86,0xdf,0xda,0x67,0x66,0x40,0x27,0x97,0xf0,0xc2,0xbd,0xce,0xce,0x37,0xeb,0x47,0xe2,0x56,0x7e,0x54,0xe9,0x51,0xda,0xec,0xd5,0xe6,0xc1,0x69,0x6e,0x4c,0x3d,0x92,0xdc,0xa0,0x51,0xe2,0x2b,0xb8,0x96,0xb6,0xce,0xdf,0x35,0xdb,0xd0,0xd4,0x42,0xe3,0x94,0x89,0x09,0x1b,0xb4 +.byte 0xe2,0x8f,0xfb,0x23,0x62,0x35,0x56,0xc7,0x94,0x40,0xd7,0x2d,0xdb,0x80,0xc9,0xbd,0x4d,0xe3,0x14,0x30,0x44,0x43,0xad,0xeb,0x3d,0x89,0xe9,0x61,0xd7,0x80,0x15,0x59,0xcd,0xda,0x38,0x11,0x3b,0x84,0x14,0x85,0xef,0x55,0xf2,0x01,0x2c,0xed,0x74,0xf5,0x71,0x75,0x0c,0x52,0x0c,0x41,0x86,0xbe,0x84,0xc5,0x89,0x8b,0xa5,0x6d,0xc3,0xfa +.byte 0x2b,0xe5,0xe7,0xe8,0xdd,0xf9,0xe8,0x27,0x08,0x5d,0xdf,0x61,0xdc,0xb2,0xe0,0x8c,0xe8,0xda,0xa8,0x68,0x22,0x51,0x6b,0xdf,0xd0,0x92,0x87,0x6a,0x43,0xff,0xd1,0x9d,0x9a,0x4c,0x03,0xdf,0x3e,0xc1,0x31,0x33,0x6e,0x2a,0x55,0xc1,0x58,0x59,0x69,0x66,0x05,0xd1,0xa7,0xa1,0x3b,0x98,0x1d,0x44,0x74,0xc7,0x7e,0xc0,0x07,0xd9,0x9c,0x87 +.byte 0x5f,0xc3,0x44,0x25,0x7b,0x96,0xbc,0x20,0x5d,0x14,0x08,0x34,0xe9,0xad,0x34,0xa3,0xc3,0x95,0x1a,0xc1,0xd1,0x37,0x43,0x49,0x66,0xff,0x39,0x70,0x27,0xa0,0x2b,0x39,0x9d,0x1b,0x78,0x52,0x55,0x77,0x30,0xe8,0x72,0x65,0x8a,0xc8,0xa4,0xe6,0xb7,0xd6,0x66,0x82,0xa7,0x1d,0xde,0x3e,0xc2,0x23,0x5a,0x8b,0x51,0xe4,0x44,0x03,0xf3,0x89 +.byte 0x10,0xb0,0x9a,0x09,0x5d,0xe3,0xe9,0x4a,0x0b,0xe3,0x86,0x58,0xf8,0xe3,0x1a,0x3f,0x7f,0x42,0xa5,0xd7,0xb0,0x24,0xb7,0xbc,0x1d,0x40,0xe7,0x2f,0x42,0x8c,0xa8,0x3c,0x33,0xee,0x9f,0xaf,0xd1,0x51,0x8e,0x34,0x82,0xc5,0x16,0xef,0xb1,0xa6,0xa8,0x0e,0xae,0xe6,0xc3,0x2f,0xb3,0x06,0xd4,0x4c,0xec,0xee,0x9e,0xff,0x88,0x82,0x4b,0xb8 +.byte 0xc5,0xef,0x94,0xe2,0x68,0x48,0x23,0xa2,0xc8,0xe4,0xdb,0x33,0xf9,0xee,0x73,0xc2,0xe6,0xa1,0x64,0xf9,0xf6,0xab,0x5a,0xdc,0xa5,0xb3,0xd8,0xae,0xf4,0x1f,0x47,0xfe,0xa0,0xee,0xf5,0xee,0x41,0x30,0xa6,0xbe,0x34,0x2c,0x1a,0x24,0x8a,0x80,0xb1,0x79,0x7e,0x2c,0xc0,0x65,0x68,0x46,0xae,0x0a,0x01,0x77,0xce,0xa2,0x5f,0xc3,0x00,0x8f +.byte 0xd4,0x0f,0xbe,0xbf,0x81,0x20,0x4e,0xb8,0x21,0x5f,0xfa,0xb2,0xf2,0x02,0x83,0x41,0xa8,0xf1,0xe8,0x2c,0x7e,0x0e,0xe6,0xf0,0x6e,0xd5,0x7b,0xcb,0x4e,0xed,0x06,0xc4,0x18,0xfb,0x0e,0x0d,0x8e,0x22,0x8a,0x40,0x4d,0x66,0xa5,0x0c,0x74,0xf3,0x9e,0xd9,0x90,0xf8,0x71,0xe4,0x92,0x05,0x3d,0x2d,0xa0,0xed,0x42,0x88,0x18,0x9a,0xc7,0xe4 +.byte 0x41,0x5d,0xde,0x44,0x2e,0x26,0x30,0xfe,0x51,0xa8,0x91,0xa3,0xa6,0xfd,0x3e,0x04,0x7f,0x3a,0xa9,0x1c,0x21,0x98,0xab,0xaa,0x39,0x9d,0xe4,0x51,0x75,0xeb,0x90,0x6b,0xab,0x11,0x89,0xa9,0x22,0xa8,0xc5,0x92,0x16,0x51,0xe1,0x77,0x09,0x53,0x7f,0xb6,0x80,0x4b,0xf5,0xf5,0xa2,0x0e,0x36,0x24,0x7f,0xe7,0xcc,0x67,0xfb,0x2c,0x6e,0xc2 +.byte 0x16,0x47,0x41,0xc2,0x77,0xf4,0xcf,0x49,0x37,0x17,0x67,0x34,0x14,0x92,0x7d,0x0f,0x14,0xe8,0x4b,0x4c,0xc3,0xbb,0x78,0xf7,0xa0,0x59,0xbe,0x06,0x10,0x38,0xe6,0x2c,0x08,0x15,0xba,0xc6,0x49,0x38,0x9a,0x91,0x2b,0x4d,0x82,0x42,0x0e,0xe4,0x02,0xef,0x2b,0xa2,0x06,0xcc,0x3a,0x3c,0xb9,0xc5,0xb5,0x71,0x1e,0x17,0x5d,0x65,0x35,0x91 +.byte 0x89,0x54,0x97,0xa8,0x7b,0x02,0x24,0xf9,0xdb,0xb5,0x52,0xf7,0xd0,0xa0,0x42,0x48,0x01,0xf4,0x47,0x7c,0x84,0x7c,0x8a,0xb4,0xf4,0x30,0xec,0xb9,0x21,0x44,0x87,0xb2,0x96,0xa4,0x3b,0x0d,0x93,0x26,0x09,0xc8,0xfa,0x28,0x6f,0x09,0xb7,0x03,0x85,0x66,0x21,0x2d,0xf1,0xaa,0x3f,0x0b,0x59,0x15,0xfe,0x8b,0x2b,0xe0,0x81,0x38,0x63,0x70 +.byte 0x09,0x37,0x38,0x62,0x04,0x8e,0x3f,0x23,0x65,0xf8,0xf7,0xc0,0x30,0xb8,0x04,0xb4,0x17,0xd7,0x21,0xcc,0x8b,0x31,0xd3,0x7b,0x11,0xea,0xc5,0x51,0x01,0x93,0x5f,0xe3,0xf3,0x1e,0x0d,0x41,0x52,0x2a,0xfd,0x27,0x02,0x00,0x58,0x0d,0x1f,0x16,0xd7,0x50,0x09,0xea,0x3f,0x9f,0x72,0xae,0x7a,0x79,0x4b,0x69,0x61,0xfc,0xac,0x5c,0x4d,0x6a +.byte 0x65,0x5d,0xa5,0x67,0x76,0xe4,0x24,0x3f,0xa0,0x6f,0xf6,0x60,0xd2,0x70,0x8e,0x2e,0xbe,0xf9,0x8b,0xab,0x22,0xc8,0x9c,0x5b,0x26,0xc5,0x75,0xeb,0x96,0xa2,0x4f,0xdf,0x6c,0x05,0x9a,0x15,0xef,0xbf,0x3e,0x35,0x6d,0x8d,0x48,0xa4,0x33,0xc2,0xe8,0x3b,0x89,0xe4,0x0c,0xb2,0x9a,0xc6,0x89,0x52,0xba,0xc7,0x2a,0xa5,0xfb,0xe5,0xde,0x06 +.byte 0xbd,0xc3,0x4f,0xe8,0xa9,0x9d,0x36,0xa5,0xcc,0x90,0xcd,0x68,0x49,0x52,0x6e,0x9a,0x85,0xd4,0x1b,0xe5,0x3f,0x54,0xc8,0xb4,0x7a,0x76,0xbf,0xa8,0xf4,0x25,0x05,0xeb,0x43,0x0c,0x2b,0x1c,0x59,0x5b,0x51,0x7f,0xd5,0x13,0x54,0x37,0x44,0x37,0x2f,0x79,0x1c,0x1f,0x18,0x57,0x60,0xab,0xf7,0xcc,0x5d,0xd5,0xdd,0x69,0xab,0x7f,0xc7,0x9d +.byte 0x7f,0xd7,0x6a,0xdc,0x34,0x3d,0x6e,0x2c,0x1e,0xb8,0x74,0xef,0xec,0x14,0x83,0x98,0x20,0x85,0x8a,0x95,0x93,0x26,0xed,0xbb,0x7d,0xfe,0x63,0xaa,0x20,0xbb,0x40,0x7b,0x35,0x1d,0xe5,0x64,0xc0,0x64,0x83,0x90,0x59,0xb4,0xae,0xf7,0xfe,0x14,0xb2,0xaa,0x72,0xf7,0x34,0x61,0xe0,0x61,0x06,0xb3,0xdc,0x09,0x5f,0xe1,0x57,0x65,0x83,0x8a +.byte 0x6d,0x46,0x54,0x8f,0xbf,0x38,0x12,0xf5,0xa3,0xfc,0x7b,0x90,0x4f,0x30,0xed,0xc1,0xab,0xb2,0x6e,0xee,0x7c,0x5e,0x35,0x70,0x80,0xb0,0xae,0x93,0xdc,0x4e,0x8f,0x6c,0x37,0xef,0xc9,0x4c,0x3a,0x41,0x14,0x91,0x99,0x0d,0x48,0xbe,0x5e,0x9b,0xc5,0xa6,0x4d,0x07,0x0d,0xd5,0xe6,0x5d,0x26,0x6b,0xa0,0xf3,0xb2,0x28,0x15,0x57,0xdb,0x7b +.byte 0x8e,0x6b,0x88,0xc3,0x81,0xb6,0x16,0xd1,0x3c,0xd0,0x2d,0x5a,0x23,0x35,0x8e,0xb0,0x8b,0x5c,0x99,0x6a,0x7a,0x55,0xb1,0xf9,0x45,0x97,0x94,0x05,0x6e,0x58,0xd4,0x53,0x8d,0x73,0x43,0x02,0x68,0xdf,0x7c,0x37,0x1a,0x6b,0x71,0x04,0xa0,0x31,0x77,0xbc,0xe0,0x16,0x5a,0x2a,0x9a,0xb2,0x40,0xe4,0xbb,0xd0,0xfd,0x35,0xcb,0x7f,0xf4,0x13 +.byte 0x0f,0xb5,0x93,0x9a,0x7d,0x50,0xf8,0xfe,0x56,0x34,0x83,0x20,0xce,0x3d,0x02,0x2e,0x0b,0x95,0x76,0x88,0x47,0x8c,0x75,0x51,0x14,0x52,0x49,0xbc,0xed,0x66,0x0e,0x81,0x65,0x5e,0x64,0xfb,0x45,0x59,0x3d,0x2b,0xd6,0x3a,0xc6,0xfd,0x50,0xe4,0xeb,0x0c,0x68,0x38,0x0f,0xdd,0xa2,0xdc,0xaa,0x26,0xf5,0x7b,0x40,0x6a,0x90,0xf8,0x08,0x2c +.byte 0xe8,0x8f,0x8e,0xc1,0xf2,0x6b,0x87,0xeb,0x7a,0x02,0x9e,0x26,0x3e,0x6b,0xb9,0x71,0x2e,0x6f,0x26,0x20,0xa9,0xc0,0x7c,0xe5,0x6c,0x6b,0xd4,0xc4,0x7b,0x54,0x8e,0x4a,0x7a,0xef,0xfc,0x03,0x02,0x1d,0x6a,0x16,0x99,0x35,0x12,0x49,0xba,0x86,0x37,0x7a,0xb0,0x8d,0x58,0x6f,0x1c,0xba,0xa9,0x5d,0x93,0xdf,0x98,0x50,0x7e,0xea,0x0a,0x88 +.byte 0x1a,0xd4,0x63,0x91,0x23,0x43,0x43,0x17,0x2e,0xe6,0x04,0x95,0x96,0xa8,0x2b,0xb4,0x9e,0x91,0x6c,0x13,0x52,0x8c,0xbf,0x7d,0x50,0xfc,0x79,0xef,0xa1,0x3e,0x90,0xba,0xac,0xd1,0x0d,0xb0,0x4d,0xd5,0x7a,0xc7,0xbd,0x82,0xb7,0x03,0x9c,0x0b,0xbc,0xa7,0x3c,0x05,0x8f,0xbd,0x0d,0x7f,0x80,0xeb,0xe9,0xbd,0x8f,0xdc,0xcd,0x86,0x23,0x26 +.byte 0xb0,0xa4,0xdc,0x63,0xef,0xad,0x61,0x53,0x7e,0x23,0x34,0x0d,0xd9,0x75,0x7c,0xa7,0x57,0xba,0x28,0x0c,0x82,0x7f,0x68,0xe5,0x24,0xdc,0x23,0x99,0xcd,0x6f,0x03,0x59,0x4f,0x35,0x47,0xc4,0x11,0xc0,0x0c,0x2b,0x16,0x94,0xb8,0x28,0xf2,0x0a,0x91,0x2e,0x1c,0xde,0x75,0x50,0x52,0x00,0x0a,0x92,0x80,0xca,0x39,0x3a,0xdf,0x16,0xb7,0xe2 +.byte 0xbd,0x98,0x7b,0x70,0x48,0x85,0x6d,0x48,0xa0,0x1b,0x0a,0xbb,0xa8,0xb6,0xca,0x9c,0x4e,0xda,0x0a,0x17,0x0b,0x30,0xf5,0xa2,0x9b,0x5a,0x89,0xf4,0x53,0x89,0x38,0x34,0x2b,0x7d,0x14,0x04,0x44,0xa3,0x8f,0x70,0x29,0xa5,0x3e,0xdd,0x5a,0x61,0xa1,0x04,0xac,0xd8,0xd3,0xec,0x42,0xc4,0xd9,0x2c,0x13,0x80,0xf8,0xc9,0xec,0x54,0xa7,0xa0 +.byte 0xe6,0x37,0x04,0x38,0x5f,0x1e,0x0b,0xfb,0x38,0x06,0xb9,0xe2,0x05,0x12,0x12,0xa2,0x28,0xff,0x12,0xae,0x44,0xd8,0x0d,0x2c,0x5a,0x8f,0xfb,0x1d,0x98,0x69,0x85,0x69,0x99,0xc0,0x63,0xc5,0x88,0xa7,0x2d,0x56,0x76,0x32,0x23,0x4c,0xf7,0x29,0xd6,0x3e,0x45,0xfa,0xd7,0x61,0xf4,0x9a,0xa6,0x9e,0x4a,0xe7,0xe7,0xf9,0xbf,0x1f,0x09,0x82 +.byte 0xbe,0x36,0xa0,0xdd,0x91,0x47,0x3b,0xbc,0x52,0xf2,0xc2,0x04,0x96,0x85,0xb6,0x93,0xac,0x99,0x94,0xbe,0xfd,0xe6,0x53,0x9f,0x75,0xab,0x38,0xdd,0x81,0xc0,0x79,0x25,0xcd,0x73,0x72,0x5b,0x4d,0xc0,0xba,0xa9,0x18,0xaa,0x76,0x51,0x15,0xef,0xb9,0x22,0xdd,0x5f,0x22,0x62,0x6c,0x36,0xf6,0xc0,0x72,0x34,0x01,0x7a,0xaf,0xe2,0x87,0x1b +.byte 0x5f,0x33,0x9c,0xd5,0xe2,0x81,0x03,0xbe,0x4e,0xac,0xcc,0x17,0xc5,0xc6,0xf8,0x0f,0x24,0xe0,0x26,0x56,0x8a,0x20,0x2e,0xe4,0x05,0xc8,0x0f,0x89,0x24,0x0e,0xd4,0xb7,0x07,0xd1,0x99,0x8c,0x55,0xfd,0x75,0xc1,0xdb,0xaa,0xd1,0xd2,0xa6,0xf2,0xf0,0x3c,0xae,0x62,0x0e,0x1f,0xaa,0xc9,0xa5,0x16,0x09,0x2c,0xc0,0x61,0x55,0x72,0x70,0x63 +.byte 0x22,0xb6,0x41,0xa5,0x08,0x34,0x6a,0x1b,0xfc,0x42,0x81,0xe7,0x25,0x98,0xcf,0xba,0x18,0xb0,0x36,0x90,0x72,0x65,0x75,0xf3,0x57,0x68,0xd0,0x86,0xe4,0xaf,0x33,0xb6,0x2b,0xef,0x96,0x97,0x17,0x42,0x6b,0x8e,0x19,0xaa,0x4b,0x9d,0xc7,0x73,0x34,0x5f,0x41,0x24,0x12,0xfb,0x66,0xa2,0x1e,0x91,0x41,0xc2,0x78,0x08,0x66,0xc4,0xb2,0x86 +.byte 0x67,0x70,0xe6,0x96,0x76,0x8d,0xa4,0x69,0x6f,0xe5,0x35,0x8b,0x20,0x3d,0x6a,0xcb,0x65,0x7b,0x82,0x7b,0xf6,0x2d,0xd8,0xd0,0xda,0x69,0x8b,0xcd,0xdf,0x15,0xf6,0x3a,0x2c,0xfe,0xc7,0x84,0x20,0x11,0xcc,0x18,0x4f,0xc7,0x2e,0x1c,0x46,0x41,0x6b,0x91,0x79,0xa0,0xbb,0xf4,0x48,0xd7,0x0c,0x9a,0x88,0x01,0xda,0xa1,0xd1,0x8f,0x27,0x49 +.byte 0x9d,0xa0,0x3f,0x5a,0xc2,0xf7,0x26,0x9b,0xe5,0xff,0xa4,0xcb,0x86,0x32,0xb3,0x3c,0xd5,0xe5,0x7c,0xbb,0x5e,0xfe,0x3d,0xcf,0x60,0x1c,0x16,0x8e,0x0c,0xc4,0xa9,0xf2,0xb2,0x42,0x1d,0x13,0xb0,0xa8,0xff,0x90,0xbc,0xd9,0x9a,0x6d,0x78,0x7a,0x46,0x1a,0xa8,0x35,0x4e,0xa4,0x79,0xd5,0xb4,0x36,0x47,0x62,0x3c,0x0e,0x23,0x56,0xca,0xa2 +.byte 0x60,0xe6,0xca,0xf6,0xc3,0xd6,0x7c,0x5d,0x54,0x9c,0x0c,0xfa,0x9a,0x0f,0x3a,0x8c,0x64,0x52,0xdb,0x62,0x5e,0x93,0x82,0xef,0x9e,0x8d,0x30,0xa5,0xe7,0x3d,0x52,0x11,0xd4,0x93,0xb1,0x77,0x8f,0xee,0x54,0x9c,0x80,0x47,0xa9,0x21,0xa8,0xf7,0x16,0x4b,0xbb,0xab,0x75,0x52,0xed,0x0c,0x85,0xf8,0x04,0xf4,0x80,0x08,0x4a,0xb5,0x2d,0x2d +.byte 0xd8,0x98,0x57,0x24,0xd5,0xc8,0x77,0xa0,0xd8,0xb5,0xb1,0x83,0x92,0xb4,0xc7,0x42,0x36,0xd1,0xa5,0xd6,0xbd,0x89,0xc6,0x76,0x31,0x92,0x31,0x67,0x2c,0xa4,0xb2,0x2b,0xcf,0x94,0x20,0x6a,0x17,0x63,0xb9,0x76,0xac,0x9c,0x1c,0x95,0x3e,0x57,0xf8,0x87,0x0d,0xef,0x36,0xcd,0x87,0xd1,0x58,0x2c,0x9a,0x5e,0x54,0x0e,0xac,0x97,0xbd,0x15 +.byte 0xc4,0xdb,0xea,0xd3,0x21,0x05,0x2d,0x78,0xce,0x4c,0x60,0xf3,0xf8,0xeb,0xd9,0x19,0x89,0xb0,0x83,0xc0,0xe4,0x42,0x08,0x5c,0x1a,0x1c,0x53,0xf3,0x1e,0x5a,0x28,0x92,0x0d,0x32,0xbe,0x4a,0x9a,0x70,0x78,0x93,0xc1,0x66,0x81,0xda,0xe7,0x3d,0x05,0xc5,0xaa,0xdc,0x51,0x6b,0xaf,0x67,0x4d,0x18,0xfe,0x29,0xe0,0xfa,0x5c,0xe5,0x9a,0x18 +.byte 0x7f,0x8f,0xaa,0x21,0xa5,0xd0,0x8b,0x62,0x32,0x6b,0x93,0x02,0x19,0x62,0xd3,0xd6,0x74,0xea,0x83,0xdb,0x6c,0x57,0xe3,0x1f,0x1f,0x90,0xd0,0x22,0xf7,0x9a,0x4a,0x14,0xf4,0x8a,0xb3,0x86,0xa5,0x4c,0x1e,0xdf,0x49,0xa5,0x78,0x30,0x5e,0xf0,0x9a,0x69,0x0d,0xaa,0xe9,0x47,0x01,0xae,0x51,0xcf,0x32,0x4c,0xec,0x03,0x08,0xe7,0xcb,0x35 +.byte 0x59,0xd2,0x48,0xd4,0xfa,0x6a,0x45,0x6b,0x66,0x1f,0xb8,0x1e,0x45,0x85,0xef,0x14,0x25,0x34,0x48,0x50,0x59,0xf3,0x76,0x09,0x32,0xf5,0xe4,0xa8,0x98,0xb0,0x9a,0x70,0xec,0x0a,0x17,0x87,0xcf,0x6d,0x96,0x7d,0x50,0x5e,0x3a,0xff,0x57,0xa7,0xaf,0x04,0x0d,0xdc,0xcc,0xad,0xe3,0x09,0xd3,0x92,0xab,0xd8,0x3a,0x61,0x1f,0x9c,0xc4,0x36 +.byte 0x3b,0xf3,0xf6,0x87,0x43,0xea,0xc8,0xff,0x29,0x19,0x9e,0x87,0x44,0xc7,0xe5,0x5c,0x43,0x30,0x9a,0xb2,0xd8,0x47,0x4a,0x87,0xcc,0xc7,0x8e,0x99,0x32,0xdd,0x3c,0x37,0xda,0xa0,0x39,0x04,0x55,0xca,0xcf,0x2f,0xce,0x8b,0x22,0x35,0x2c,0x29,0x89,0xef,0x5c,0x05,0x82,0x55,0xf3,0x8d,0x64,0x7f,0x69,0xf7,0x3d,0x43,0x27,0xf3,0x4c,0xd7 +.byte 0x43,0x89,0x47,0xd5,0x0b,0x01,0x1b,0x17,0x6c,0x7e,0x63,0x18,0x87,0x8b,0x8f,0x20,0x0d,0xa4,0x1e,0xa5,0x3b,0xf1,0x5c,0xe5,0xc8,0x23,0xd4,0xee,0x79,0x3e,0xd1,0xbc,0x83,0x30,0x03,0x64,0x80,0x7e,0xda,0x13,0x7c,0x52,0x88,0xc1,0x7c,0xa7,0x8a,0x5d,0x8d,0x7b,0x57,0x4e,0x59,0x97,0x83,0x52,0x03,0x04,0x6b,0xd2,0xf3,0xff,0x1c,0x4e +.byte 0x3b,0xae,0x70,0x61,0x3b,0x8b,0xaf,0x56,0x3d,0x28,0x73,0x24,0x39,0x4b,0xb8,0x6e,0x89,0x28,0xe6,0xc8,0x5c,0xe9,0xf8,0xec,0x8f,0xf7,0x75,0x1a,0x13,0xc1,0x8e,0x53,0x4e,0xe5,0xef,0x37,0xce,0xa1,0x54,0xca,0xcc,0xf5,0x01,0x29,0x2a,0x8f,0x00,0x1c,0xde,0xcd,0x5e,0x24,0x0b,0xa5,0x94,0x0c,0x8a,0xab,0x54,0x1e,0x80,0x2a,0x0d,0x84 +.byte 0x38,0x4c,0x17,0xea,0x84,0x07,0x9c,0xbd,0x85,0xd8,0x1b,0x57,0x6a,0xde,0xb3,0x86,0xa3,0xf8,0x6d,0x03,0x3e,0xf1,0x37,0xae,0x7d,0x02,0x33,0xc5,0x7b,0xf6,0x64,0xdb,0x3e,0xb0,0x48,0xda,0x49,0xec,0x89,0xb4,0x83,0xff,0xe1,0x6f,0x9a,0x7e,0x0a,0xda,0x6e,0xec,0x70,0x0b,0x51,0xac,0x82,0xac,0xb8,0xce,0x16,0xe7,0x47,0xab,0xe8,0xc7 +.byte 0x56,0xd1,0xab,0x73,0x72,0x5c,0xe7,0x9e,0xb8,0x77,0xa7,0xc1,0x47,0x9c,0x4e,0x16,0x68,0xce,0x21,0x23,0x2d,0x6c,0xcf,0x79,0xd6,0xd4,0xdf,0x74,0x30,0xb8,0x0f,0x60,0xea,0xbf,0x39,0x77,0x45,0xdc,0xaf,0x25,0xbd,0xc5,0x8d,0x0b,0x44,0x21,0xc1,0xc1,0x2e,0x54,0x2a,0x32,0x6c,0xea,0x51,0xe0,0x7d,0xa8,0x09,0x94,0x2f,0x4e,0xfe,0x27 +.byte 0xe8,0x63,0xfb,0x71,0xca,0x01,0x7d,0xc9,0x70,0xd8,0xe4,0x82,0xbf,0x3f,0xea,0x64,0x5e,0xa9,0x84,0x1d,0x2c,0xfd,0x8a,0x7d,0x33,0x73,0x5c,0x82,0xbe,0x9e,0x46,0xfc,0x39,0x5e,0x38,0x2a,0x20,0xd9,0xa9,0x20,0x46,0x23,0xc1,0x8b,0x0a,0x9c,0x42,0xb6,0x50,0x9f,0xc8,0x7d,0x4a,0x85,0x98,0xed,0x92,0x13,0xd3,0xd6,0xe6,0x6d,0x50,0x6e +.byte 0x93,0x63,0x41,0xa3,0x63,0x97,0x52,0xe3,0xaf,0x09,0xe1,0x40,0x12,0x41,0xed,0xb3,0xc5,0xb8,0x9f,0xc1,0xf2,0xd2,0xe6,0x16,0x94,0x97,0xdb,0xae,0xdb,0xd4,0x1f,0x5a,0x2f,0xf1,0xb1,0x22,0xf6,0x60,0xa4,0x0e,0xd8,0x2f,0xf7,0xf7,0x3f,0x6c,0x7d,0x73,0xe3,0x1d,0x99,0x04,0x7f,0x4f,0x70,0x2a,0x8c,0x43,0x80,0xa3,0xd0,0x25,0x75,0xd8 +.byte 0xb6,0xc8,0x90,0xa2,0x26,0xee,0xba,0xc5,0x1a,0xdc,0x1f,0x81,0x65,0x54,0xc6,0x57,0x6e,0xa2,0x03,0x32,0xf5,0x14,0xb2,0xdd,0x4d,0x21,0xaa,0xb9,0x78,0x4f,0x76,0xab,0xbe,0xfe,0x5d,0xc6,0xaf,0xed,0x6f,0xf9,0xaa,0x31,0x21,0x08,0xa4,0x6e,0xfb,0x78,0xdc,0xed,0x0c,0x05,0xff,0x1e,0x60,0x38,0x60,0x94,0xa9,0x92,0xa7,0x07,0x6e,0x6f +.byte 0x6d,0x89,0x8a,0x73,0xfb,0xaf,0x01,0x34,0x7d,0x7d,0x33,0x76,0xff,0x1f,0x6b,0x79,0x5e,0xff,0x50,0x14,0x80,0x7d,0x55,0x0e,0x2d,0xc3,0x77,0x85,0x30,0x20,0xf6,0xc8,0xc7,0xb7,0x73,0x1b,0xd1,0x87,0x69,0x44,0xeb,0x02,0x5e,0x45,0x66,0x6f,0x28,0x00,0x1f,0xf8,0x58,0x93,0xe5,0x21,0xbc,0x19,0x8d,0x72,0x19,0xaa,0x9a,0xbb,0xc6,0x47 +.byte 0xe6,0x0b,0xe4,0x76,0x13,0xc7,0xc4,0x1b,0x9d,0x85,0xba,0x17,0xb6,0x30,0x2a,0xdb,0x7c,0x36,0xd7,0xd8,0x8b,0x9c,0x99,0x92,0x64,0x03,0x4f,0xd4,0x1f,0x04,0x2e,0x45,0x34,0x55,0x92,0x99,0x77,0xb8,0x45,0xce,0x59,0x22,0x3c,0x6e,0xe5,0x18,0xb0,0x83,0x42,0x42,0x75,0x1c,0x34,0x0f,0x2e,0x59,0x06,0x94,0x17,0xea,0xc3,0xdb,0x0b,0x2f +.byte 0x44,0x97,0x54,0xe8,0x76,0xd3,0x25,0x24,0xe9,0x21,0x4f,0xd7,0x01,0x7d,0xbe,0x90,0x8a,0x0a,0x7d,0x4e,0x91,0x5f,0x4c,0x32,0x83,0x42,0x55,0x95,0x3c,0x7a,0x3e,0x46,0x8a,0x5d,0x0c,0x05,0xcd,0x0b,0xf6,0x3e,0x4d,0xf3,0x55,0xea,0x42,0x3e,0x19,0x0e,0xda,0xd4,0x22,0x88,0xe2,0x29,0x06,0x9e,0xea,0x1c,0x27,0x96,0x7f,0x3a,0x8a,0x28 +.byte 0x2f,0x7d,0xa2,0x65,0x37,0xae,0xb6,0x6a,0x59,0x41,0x19,0x73,0x91,0x64,0x77,0x4e,0x5a,0x1a,0x85,0x9f,0xc5,0xb0,0x85,0xc1,0x96,0x47,0x69,0x9c,0x36,0x70,0x36,0xa3,0x2e,0x1a,0x7d,0x11,0x59,0x55,0xec,0x4c,0x49,0xa1,0x86,0x3c,0x3d,0x24,0xb8,0x7a,0x84,0xca,0x4c,0x3f,0x7e,0x81,0x95,0x39,0x41,0xfe,0xc4,0x74,0xe5,0x89,0x7e,0xdc +.byte 0x86,0xd2,0xdb,0x8b,0xb8,0xa2,0xbb,0x15,0x64,0x89,0xf9,0x00,0x7d,0x56,0xec,0x8b,0xc8,0x05,0xcd,0x76,0x6c,0xcb,0xaf,0x7e,0xd2,0xdd,0x67,0xb3,0x99,0x16,0x63,0xf2,0x6d,0x49,0x7d,0xeb,0x67,0x24,0x98,0xf1,0x28,0xa3,0xb2,0x14,0xfc,0x95,0xf6,0x55,0xa0,0xb5,0x8c,0x26,0x2f,0xc6,0x08,0x49,0x57,0x4c,0x20,0xbc,0x48,0xab,0x24,0xef +.byte 0xe9,0xab,0x6b,0x77,0x4d,0x3b,0x61,0x84,0x68,0x67,0x72,0xc2,0xcf,0xab,0x8e,0xac,0x39,0xec,0x43,0x03,0xbb,0x4f,0x32,0x7d,0x7d,0x51,0x69,0x30,0xee,0x4f,0xd0,0xb9,0xa5,0x22,0xdd,0x47,0x06,0xad,0xac,0x62,0x20,0xff,0x7b,0x8c,0x90,0x91,0xb3,0xd8,0x89,0xd3,0xea,0x81,0xdc,0xca,0x31,0xc3,0x65,0xca,0x4c,0x50,0x0a,0x85,0xf7,0xaf +.byte 0xe3,0x67,0x57,0x53,0x1d,0x4e,0x42,0x17,0x2d,0x14,0x80,0x29,0x09,0x2b,0x48,0x45,0x43,0xb9,0xad,0x1f,0xb7,0x2d,0xab,0xfa,0x6a,0x1b,0x3c,0x7d,0x76,0xd7,0x36,0x20,0xb0,0xd3,0xc0,0x5e,0xc7,0x20,0x06,0x0c,0xa9,0x6a,0xb2,0x67,0xad,0x91,0x49,0xfc,0x4d,0xb2,0x15,0x61,0x61,0xfa,0x33,0x6c,0x94,0x92,0x58,0xef,0x46,0x82,0x9c,0x04 +.byte 0x52,0x21,0x28,0x08,0xb4,0xa9,0xd4,0x2e,0xd9,0x8c,0x93,0xd0,0xd8,0x4f,0x33,0x1d,0x0b,0x7e,0x07,0x12,0x40,0x64,0x3d,0xa2,0x8f,0xa3,0x96,0x45,0x0e,0xfc,0x9b,0x55,0x5f,0x3c,0xa2,0x57,0x3e,0x51,0x40,0x69,0xdc,0x7a,0x51,0xd2,0x3b,0x79,0x2f,0xd2,0x01,0x18,0xbf,0xd5,0xd2,0xd1,0x0e,0x08,0xcf,0xac,0x07,0x4d,0xd1,0x92,0xc7,0xca +.byte 0x92,0x75,0x0b,0x80,0x29,0xf1,0x46,0x24,0xba,0x47,0x6b,0x4a,0x64,0xfb,0x31,0x69,0xe9,0x40,0x0d,0x69,0x50,0xd0,0xdf,0xf8,0xcb,0x6a,0xe8,0xd4,0xc2,0xbd,0x0b,0x23,0x00,0xe0,0x29,0x0a,0x0a,0x8e,0x19,0xec,0xa9,0x14,0xe4,0x5d,0x4c,0x30,0xc9,0x85,0x42,0xd6,0x9f,0x83,0x8f,0x2a,0x5b,0x22,0x37,0xe4,0x71,0x3b,0x19,0x86,0xd4,0xda +.byte 0xb5,0x81,0x8e,0x84,0x57,0xcd,0x13,0x64,0xc3,0x23,0xfd,0x91,0x8a,0xe4,0xb9,0x32,0x12,0x17,0x02,0xa6,0x8d,0xec,0x44,0x9d,0xa5,0x7c,0x96,0x14,0xd1,0xd5,0x93,0x02,0x0c,0x9d,0xfc,0x26,0xa0,0xd2,0x41,0xaa,0x75,0xe8,0x82,0x6f,0x47,0x1d,0xe8,0xcf,0x94,0xe3,0x35,0xa9,0x76,0x1e,0xdb,0x92,0x5f,0x32,0x49,0xf4,0xd5,0x59,0x9c,0x4e +.byte 0xf7,0x89,0xda,0x23,0x7f,0x46,0x0e,0xfc,0xaf,0x1c,0x6f,0xcc,0x59,0xa5,0x43,0x04,0xbf,0x55,0xab,0x7d,0x36,0xa3,0xa5,0x03,0x7f,0xdf,0x33,0x6c,0x6d,0xd0,0x53,0xaa,0xef,0x54,0xc1,0x62,0xa0,0xd6,0x3a,0x67,0x87,0xe3,0x76,0x17,0x45,0xbe,0x7f,0x55,0xc8,0x8b,0xe8,0x1c,0xa8,0xe6,0xa6,0xb2,0xbf,0xe5,0x45,0xc0,0x88,0x22,0x36,0xa0 +.byte 0xec,0x21,0xdc,0x3e,0x6b,0xd2,0xc7,0xdf,0x5b,0xa4,0x32,0x28,0xca,0x23,0xe1,0x50,0x55,0x72,0x59,0x28,0x1c,0xf7,0x93,0x91,0x07,0x3c,0x4e,0x81,0x20,0x58,0x9b,0x07,0x38,0x37,0x68,0x2c,0x29,0xba,0x20,0x11,0xa9,0xa0,0x29,0x65,0x57,0xb1,0xe3,0xb1,0xfb,0xe2,0x70,0xee,0x1f,0xcd,0xf5,0x61,0xea,0x7a,0x08,0xb4,0x1e,0xfe,0xe7,0x4d +.byte 0x32,0xa0,0xfd,0xb4,0x52,0xa1,0x4b,0x67,0xba,0x5e,0x90,0xe7,0x56,0xec,0x06,0x03,0xb6,0xe6,0xc6,0x98,0xa1,0x41,0xf4,0xaf,0xde,0xe2,0x67,0xef,0xaa,0x05,0x97,0xc5,0x80,0x32,0xd0,0x43,0xc2,0x02,0x7a,0xcc,0x4c,0xdd,0xe9,0x1e,0xd0,0x4f,0xad,0xf3,0x4b,0x2c,0x5e,0xb8,0xd8,0x84,0xc2,0x43,0xc7,0xa9,0x86,0x4d,0x10,0xae,0xb7,0xe3 +.byte 0x5c,0xd5,0x2a,0xba,0x3b,0xd3,0x7b,0x5d,0xc8,0xe0,0x67,0x87,0xbe,0xbf,0x71,0x4e,0x22,0x68,0x12,0x53,0x95,0x73,0x5c,0x30,0x7b,0x2b,0xfd,0xc1,0x3c,0xfc,0xc4,0x0f,0xdd,0x5b,0x3e,0x1b,0x72,0x71,0xa6,0xe3,0x1f,0x2d,0x51,0xe2,0x61,0x3d,0xa0,0x60,0xc2,0x6b,0x41,0x8f,0x94,0x83,0x29,0xa3,0xb6,0xa7,0xc7,0x11,0x8f,0x1c,0xb5,0x19 +.byte 0x66,0x44,0xc7,0x05,0x58,0x83,0x28,0x69,0x0c,0xb6,0x65,0xe5,0x93,0x1c,0xb1,0xf6,0xf9,0xea,0xda,0x84,0x26,0x8e,0xa2,0xbb,0x9b,0x55,0xd3,0xbc,0x42,0x56,0x8f,0xce,0x6e,0x74,0x40,0xf2,0x02,0xa6,0x22,0x22,0x6e,0x20,0x0e,0x4b,0x8b,0x15,0xa5,0x04,0xf0,0xe0,0x7b,0x27,0x0a,0x38,0xe3,0x99,0x04,0xd0,0x5b,0x64,0xd2,0x04,0x92,0x61 +.byte 0x57,0x74,0xbc,0x1e,0x98,0x01,0x4b,0x2f,0x46,0x56,0x1c,0xeb,0x49,0x2d,0x66,0xac,0x85,0x96,0x48,0xfd,0xa1,0xf0,0xf5,0xc0,0xdb,0x7a,0xf2,0x0b,0x57,0x86,0xac,0x4c,0x6a,0x02,0x97,0x13,0xef,0x08,0xf6,0x18,0xe1,0x5c,0xb3,0x18,0x3d,0x70,0xc0,0x76,0x5e,0xd0,0xb8,0x44,0x32,0x25,0x75,0x62,0xa2,0x80,0x78,0x8c,0xc4,0x2a,0x84,0xbc +.byte 0x51,0xd4,0xee,0x44,0x48,0xe5,0xc4,0x48,0xbf,0xc0,0x27,0xc1,0x77,0x25,0xf5,0x59,0x6b,0x60,0xae,0xa5,0x42,0xfe,0xc3,0x06,0x91,0xe3,0xdb,0xa9,0x4b,0xe2,0x73,0x95,0x1f,0xf6,0xb6,0x66,0x71,0x63,0xb3,0x14,0x4a,0x3d,0x36,0x84,0xbe,0x2a,0x7c,0x7c,0xba,0x0e,0x8d,0x9a,0x73,0x52,0x21,0x89,0x02,0x8f,0x94,0xa5,0x9a,0x11,0x2e,0x6e +.byte 0x78,0xf7,0x07,0xf8,0xb1,0x42,0x96,0x06,0x78,0xf0,0x53,0x86,0xec,0x2b,0x1f,0xa7,0x84,0x79,0x37,0xc7,0x61,0x83,0x8e,0x62,0x65,0x49,0xdd,0xfe,0xee,0x97,0x70,0xa2,0x73,0xb5,0x85,0xaf,0x10,0xed,0xb8,0x74,0xec,0x42,0xd0,0x14,0x47,0xa6,0x90,0x7c,0x07,0x22,0xb4,0x4e,0xfc,0x12,0xa1,0x9d,0xd4,0x73,0x8f,0x6a,0x55,0xf8,0x56,0x25 +.byte 0xdb,0x9b,0xe8,0x10,0x87,0x7a,0x4b,0x42,0x9c,0xbb,0x6e,0xf1,0xd7,0x1d,0xf4,0x07,0x31,0x9c,0x94,0x3a,0xb6,0xad,0x4b,0xf4,0x57,0x3d,0x2f,0xba,0x23,0x36,0x34,0x52,0x62,0xf7,0x64,0xc7,0x47,0xeb,0x41,0xad,0x07,0xfb,0x3e,0x08,0x74,0x92,0x58,0x0f,0x73,0xe2,0x53,0x35,0xda,0xae,0x64,0x3c,0x47,0x89,0xaf,0xce,0x59,0x35,0x75,0x8b +.byte 0x50,0xee,0xbf,0xbe,0xd1,0xf4,0x2f,0x11,0xa3,0xfe,0xce,0xfd,0x15,0x0d,0x32,0x17,0x00,0xfb,0xad,0x02,0x70,0x5c,0xeb,0x59,0xfb,0x87,0xe5,0xed,0x0e,0xde,0x97,0xe7,0x75,0xb6,0xdc,0xe9,0xb0,0x08,0x26,0x0e,0x11,0xd4,0x4f,0xc4,0x92,0x71,0x7c,0x63,0xef,0xc0,0x14,0x64,0xe1,0x0f,0x7e,0xe6,0xcb,0x5b,0x4c,0xd4,0x16,0x8b,0x7b,0x8b +.byte 0x2f,0x2a,0x77,0xef,0xd3,0xdf,0x56,0xc0,0x5a,0x94,0x72,0xd5,0x36,0x12,0xfa,0x25,0xd7,0x77,0x52,0xdd,0xea,0x11,0x2f,0x6b,0x16,0x6e,0xe3,0xa2,0x84,0xba,0x55,0xc2,0xb0,0xe2,0x3b,0x53,0xb6,0xa4,0xc6,0xa5,0x3f,0x1b,0xb3,0x38,0xc0,0x2f,0x1a,0x80,0xe0,0xa4,0x60,0x49,0x8c,0xe3,0x23,0x5f,0x59,0xfd,0x2a,0x0f,0xe8,0x4c,0xaf,0xd7 +.byte 0x36,0xc7,0x25,0x21,0xad,0x41,0x54,0x27,0x95,0x15,0x42,0xbc,0xb3,0x77,0x4e,0x97,0xf4,0x3c,0x54,0xcc,0x19,0x63,0x62,0x67,0x97,0x5a,0xd0,0x59,0xfb,0xce,0xcd,0xe1,0x3c,0xb6,0xc9,0x49,0xc4,0xff,0xde,0xf9,0x89,0x87,0x9c,0xdf,0x4e,0x8c,0x9d,0xe5,0xbd,0x0d,0x0c,0x6e,0x93,0xfd,0xea,0x90,0xf2,0x80,0x7e,0x00,0x9a,0x06,0x02,0x87 +.byte 0xae,0xca,0xf4,0x46,0xbb,0xb5,0x52,0xee,0x18,0xb0,0xf1,0x61,0xcb,0xe1,0x65,0x9c,0x0b,0xfb,0xe6,0x3b,0xeb,0x3a,0x1a,0x22,0x41,0x0b,0x99,0xa4,0x8e,0x01,0x5e,0x7c,0x4e,0x1a,0xaa,0xab,0xd3,0x8b,0x99,0x7f,0xba,0x6b,0xec,0xe7,0x3a,0xd6,0x55,0x46,0x20,0x1b,0x10,0x39,0x06,0xcc,0x90,0xc1,0x6a,0xa5,0x27,0x7c,0xca,0xa5,0x58,0x07 +.byte 0xd7,0xaf,0x6d,0x12,0xa6,0x68,0xc7,0x0e,0x19,0x53,0x44,0x22,0x85,0xbb,0x72,0x9c,0x4d,0xfb,0xeb,0x94,0x3a,0xa0,0x64,0xf5,0x25,0xe8,0xee,0x7a,0x3b,0x71,0x0e,0xbb,0x40,0xa2,0xb3,0xc9,0x6b,0x14,0x0f,0xc3,0x75,0xac,0x1b,0x5c,0xf1,0x34,0x51,0xcb,0xeb,0x5f,0x40,0x0f,0x82,0xe9,0xd2,0x6d,0x95,0x88,0x84,0xea,0xe9,0xe3,0xa0,0xe9 +.byte 0xef,0x3b,0x33,0xfe,0x32,0x52,0x93,0xce,0x95,0x4b,0x64,0x3c,0x97,0x76,0x91,0xd8,0xce,0xb5,0xc2,0xda,0x58,0x23,0x27,0xe2,0x3d,0xbe,0xf6,0x31,0x79,0x73,0x0e,0x31,0xd7,0xa3,0xaa,0xac,0xcf,0x31,0x1e,0x75,0x58,0x14,0x21,0x52,0x1c,0x3e,0x4f,0x2a,0x2b,0x9a,0x22,0xbc,0x42,0x68,0x5b,0x83,0xc2,0x8c,0xd4,0xe8,0xd9,0x02,0x0d,0x13 +.byte 0x2f,0x08,0xd3,0x11,0xb7,0x4b,0x84,0x67,0x43,0xda,0x20,0xdb,0x89,0xd5,0x9e,0x14,0x54,0x3d,0x49,0xda,0xac,0x3f,0x8f,0xf5,0x17,0xfe,0xb8,0x5f,0xc3,0x20,0x38,0x27,0x21,0x32,0xbf,0xf3,0x9b,0x2c,0x0b,0x9b,0xeb,0x64,0x87,0xf7,0x9d,0xed,0x15,0x05,0x21,0x69,0xcf,0x2d,0xf8,0xfb,0xf2,0x81,0x51,0x08,0xc7,0x18,0x81,0xdf,0xed,0xa4 +.byte 0x70,0xb3,0x07,0xfa,0x00,0xd5,0x65,0xb9,0x5a,0x82,0x67,0x6f,0x10,0xfc,0x46,0x05,0x9a,0x85,0x64,0x14,0x60,0x64,0x4d,0x1f,0x13,0x57,0xbb,0x7c,0x4a,0x10,0x84,0x8c,0x57,0x36,0x13,0x22,0x00,0x04,0x2d,0xcf,0x27,0x3d,0xf4,0x27,0x3e,0x32,0xb3,0x87,0xda,0x82,0xaa,0xad,0xd7,0xa7,0xc5,0x3c,0x45,0xec,0x28,0x82,0x79,0x95,0x8f,0x56 +.byte 0x50,0x5f,0xc2,0x15,0xab,0x18,0x58,0x4f,0x69,0x46,0xce,0x29,0x33,0x42,0x53,0xe9,0xea,0xe5,0xa8,0x5b,0x90,0xc4,0xf4,0xbf,0x8a,0x20,0x62,0xad,0xa5,0xea,0x6a,0x4e,0xb4,0x20,0x2d,0xca,0x90,0xdf,0xbd,0xab,0x5b,0xc3,0x33,0x7c,0x53,0x1f,0xf5,0x2e,0xc0,0xbf,0x19,0xe1,0xa1,0x5a,0x63,0xf3,0x13,0x4d,0x6e,0xef,0x4f,0x3a,0x94,0x18 +.byte 0xbe,0x79,0xdb,0xbf,0xc2,0x2c,0xb3,0x36,0x59,0xab,0x21,0x1d,0x98,0x60,0x70,0xdd,0x95,0x51,0x19,0x07,0xd6,0x68,0x0e,0x2a,0xd4,0x4c,0x30,0x18,0x1c,0xe4,0xe1,0x89,0x15,0x25,0xea,0x27,0xcf,0x51,0x56,0xc9,0xa9,0xa7,0x31,0x08,0x17,0xfb,0xfc,0xf6,0x0c,0x5d,0xf1,0x7c,0x36,0xcb,0xad,0xef,0x29,0xf5,0x2e,0x23,0x09,0xcf,0x31,0x6f +.byte 0x74,0x12,0xd2,0xc2,0xc7,0x19,0xa5,0x6e,0x20,0x09,0x67,0xdc,0x41,0x69,0xbe,0x15,0xd6,0xeb,0x7b,0xba,0x63,0xae,0x65,0xd8,0x67,0xec,0x6e,0xcc,0x1d,0x04,0x08,0xfb,0x7c,0x34,0x1d,0x5f,0x1e,0x51,0x1c,0x30,0x72,0xd3,0x0c,0x48,0x60,0x3d,0x52,0xae,0xe6,0x78,0x44,0x6d,0xb8,0x40,0x08,0xb7,0x7a,0xa9,0xfc,0xa0,0x86,0xff,0x32,0xd6 +.byte 0x5a,0x31,0x4e,0xe2,0x65,0xab,0xb0,0x84,0xb6,0x74,0x3e,0xa6,0x67,0x7c,0xa2,0x0f,0x23,0x22,0xab,0x72,0x7e,0xeb,0x45,0xa9,0x2a,0xb4,0xd3,0xcc,0x27,0x5c,0x12,0xdb,0x14,0x68,0x73,0x0f,0x36,0xbf,0x9f,0x14,0x12,0xe9,0xef,0x04,0x2a,0x63,0x41,0x4b,0x04,0x9b,0x4c,0xc4,0xb2,0xb9,0x1c,0xc0,0xb8,0xcc,0x23,0x61,0xc4,0xed,0x27,0x1e +.byte 0x1d,0x97,0x3d,0x40,0x4c,0x1f,0xeb,0x6e,0xc4,0xfb,0x5c,0x2d,0xf5,0xf1,0xbb,0x05,0x47,0xa2,0x1a,0x9c,0x2b,0x8f,0xce,0x98,0x09,0x6b,0x86,0x22,0xf8,0x3a,0xae,0xf3,0xb4,0x66,0x2f,0xdb,0x20,0xa5,0xc6,0xb6,0x35,0xb5,0x5a,0x68,0xb5,0x37,0x2c,0xab,0x13,0x3d,0x2d,0xcb,0x38,0xed,0x3c,0x7a,0x1f,0x26,0x08,0x58,0x94,0x52,0x30,0xec +.byte 0x06,0x9f,0x90,0x97,0x4d,0x90,0x49,0x23,0xaf,0x00,0x90,0x6b,0x96,0x37,0x02,0x4c,0x35,0xc0,0x3e,0x66,0x2c,0x52,0xbc,0x75,0x28,0xd7,0x8f,0x25,0xbe,0x91,0x10,0x22,0x67,0xbf,0x4a,0x4d,0x62,0xc4,0xe9,0xda,0xe2,0x79,0xcc,0x76,0xeb,0x99,0x87,0xac,0x39,0x7d,0xf6,0x5a,0x37,0x85,0x30,0x33,0x65,0x3f,0xd9,0xd6,0x17,0xf8,0xf0,0x86 +.byte 0xee,0x5c,0x2f,0xb0,0xb3,0x4f,0x83,0x6c,0x4a,0x8f,0xfc,0x80,0x91,0xaf,0x4b,0x21,0x9c,0x9b,0x44,0x3c,0xed,0x67,0xfb,0xa3,0x31,0x7f,0xd4,0x73,0x72,0xb9,0xc1,0x31,0x96,0x47,0x8e,0x99,0x8e,0x62,0x1a,0xfd,0xc7,0x9d,0x2f,0x4c,0xda,0xe5,0xae,0x17,0xb6,0x40,0x5f,0x9e,0xa8,0xf2,0xcc,0xd7,0xd5,0x40,0x33,0x88,0x57,0x63,0x9b,0xde +.byte 0x82,0x71,0x68,0xfe,0xaf,0x29,0x6c,0xc1,0x2c,0x2f,0x02,0x42,0xd7,0xa5,0x28,0x05,0xca,0xa0,0xb6,0x8c,0x43,0x90,0x05,0xe2,0x1c,0xb7,0x76,0x79,0x39,0xd3,0x23,0xe1,0xe7,0xbb,0x19,0x65,0x1a,0xb4,0xbb,0x5a,0xcf,0x43,0x70,0x26,0x1a,0x2f,0x61,0x78,0x75,0x08,0xb0,0x88,0xe5,0x4a,0x46,0x0a,0xfc,0xcb,0x46,0x18,0xb0,0x8d,0x9b,0xeb +.byte 0xf5,0xe1,0x83,0x04,0x84,0x4f,0xd6,0xa0,0x4f,0xb2,0x4c,0x44,0x08,0xde,0xd6,0x82,0xb5,0x9a,0x45,0x15,0xb8,0x21,0xc7,0xf5,0xe2,0xfd,0x02,0x27,0x18,0x13,0x24,0x18,0x01,0xd1,0x2a,0xff,0x63,0xf2,0xa4,0x97,0xc8,0x4b,0x3b,0xae,0x49,0x47,0x54,0xe8,0x75,0xe7,0x16,0x77,0x22,0x10,0x7b,0x3c,0xf0,0xdb,0x49,0x6e,0xd6,0x55,0x9d,0x43 +.byte 0x6f,0x6e,0x2d,0x97,0xea,0x16,0x2e,0x0c,0x85,0x89,0x67,0xe1,0x7b,0x38,0xa6,0x2b,0x89,0xf0,0xcd,0x90,0xcd,0xba,0x9a,0x70,0xa9,0xe3,0xff,0xe0,0xbd,0x15,0x3e,0x4b,0x13,0x62,0x7b,0x59,0x64,0x18,0x96,0xe9,0x6a,0xf3,0x69,0x2d,0x2d,0x25,0xe7,0x91,0xd3,0xbc,0x74,0x58,0x66,0x2f,0x5e,0x8b,0x52,0xf6,0x91,0x24,0xa8,0x6f,0xa5,0xce +.byte 0xa1,0x4e,0x3b,0xe9,0xc5,0x30,0x7e,0xa5,0xc7,0xe2,0xb3,0x71,0x3b,0x25,0xb9,0x5f,0xe5,0x9c,0xf8,0x46,0x23,0xc5,0xa2,0xc1,0x1f,0x3f,0x43,0xa6,0xaa,0xf1,0x36,0x27,0xc6,0xa8,0xed,0x0d,0x50,0x71,0xf1,0x38,0x27,0xb7,0x16,0x43,0x7c,0x7f,0x77,0x5b,0x25,0x59,0xb7,0x08,0x0d,0xc8,0x84,0xe4,0xc2,0x03,0x95,0xe5,0xf3,0x0a,0x9c,0x1f +.byte 0xde,0x98,0x7c,0xa9,0xe2,0x70,0x9e,0xde,0xf6,0x80,0xd0,0xf8,0x86,0x4a,0x7a,0x0d,0x16,0xaa,0xde,0xba,0x02,0x30,0x8a,0xe6,0x03,0x0f,0xa1,0xf1,0xe8,0xd6,0xf8,0xce,0x7b,0xba,0x74,0xa8,0x25,0xb0,0x49,0x22,0xa6,0x81,0x7e,0x71,0xc5,0x97,0x9e,0xa8,0x46,0xa7,0xe9,0x8b,0x7c,0x7c,0x4c,0xc5,0x3c,0x93,0x08,0xb9,0x8b,0x3c,0x33,0xd6 +.byte 0xc4,0x37,0xc8,0x05,0xe7,0xfe,0xc2,0x7c,0x02,0xe6,0xda,0x09,0x52,0x2c,0xc6,0xa8,0x6e,0x44,0x7e,0x55,0xf0,0x32,0x10,0xcb,0x1e,0xa7,0x77,0x8d,0xc7,0xfe,0xb5,0xf6,0x3b,0x49,0xf2,0xfb,0xe0,0x41,0x98,0xd3,0x17,0xa6,0x5d,0x3f,0x4c,0x95,0xb0,0x02,0x8d,0xab,0x36,0xb7,0xa0,0x92,0x40,0x5e,0x15,0xfb,0xa9,0xb4,0xa3,0x04,0x8b,0x6b +.byte 0x81,0x44,0x59,0x22,0x10,0xcb,0xc5,0x52,0x3f,0x78,0x70,0x00,0xe2,0xa2,0xf7,0x76,0x62,0x72,0x06,0x8b,0xbb,0x56,0x0f,0x8c,0x67,0x2f,0x52,0x3f,0x3b,0xdc,0x15,0x79,0x55,0x89,0x6c,0x61,0x23,0xcc,0x6b,0x41,0x77,0xe5,0xc4,0x90,0x51,0xc3,0x87,0x22,0x1e,0x89,0xf5,0x5b,0x41,0xd7,0x34,0x22,0x3c,0xbd,0x29,0xaa,0x54,0xed,0x5a,0x90 +.byte 0x17,0x24,0xba,0x7a,0x46,0x5f,0x54,0x33,0x56,0x7e,0x2d,0x03,0x59,0xcb,0xbb,0x7a,0xce,0xbb,0x8d,0xf7,0xb6,0x38,0x00,0x18,0x6a,0xa1,0x6c,0xdf,0x42,0x49,0x4d,0x9b,0x4f,0xd6,0x85,0x54,0x1f,0xad,0x17,0xdd,0x66,0x0e,0x7c,0x30,0x86,0x82,0x1c,0x5a,0x81,0x08,0x55,0x51,0x5b,0x06,0x54,0x52,0x3e,0x8b,0x6e,0x72,0x92,0xd2,0x05,0x5d +.byte 0xe4,0xe8,0x0e,0x62,0x1d,0xec,0xb1,0x7f,0x42,0x05,0xd5,0xd3,0x60,0xd4,0xdc,0xa4,0x48,0xc0,0xf0,0x89,0xef,0x5b,0xae,0x5f,0xcd,0xf0,0x62,0xaa,0x3e,0xd5,0x1a,0xbe,0xe3,0x08,0xd5,0xe8,0x00,0x21,0x8c,0x0b,0x0c,0x8e,0x24,0xac,0xb2,0xea,0x44,0x9f,0xce,0x53,0x45,0x9a,0x85,0x67,0x99,0x85,0xea,0x92,0xa7,0x1d,0x86,0xb4,0x3b,0x22 +.byte 0xa2,0xcd,0x35,0x65,0xb5,0xa6,0xdb,0x6d,0x48,0xd1,0xa4,0x76,0x0c,0x00,0x30,0x62,0x86,0x06,0xda,0xa8,0xfe,0xec,0x70,0x87,0x4a,0xe8,0x2e,0x4d,0xe3,0x94,0x0b,0xdf,0x81,0xcd,0xfe,0x23,0x79,0x2c,0x2b,0xae,0xf7,0x75,0x49,0x47,0x24,0x46,0x09,0x10,0x62,0x39,0x3b,0x50,0xf1,0xfa,0xf7,0x5f,0xe4,0x7c,0xa5,0xc0,0x25,0x9e,0x20,0x4d +.byte 0xc8,0x6b,0x93,0xc5,0x4a,0x6b,0x62,0xb8,0x3b,0xe5,0x0d,0x92,0x70,0x26,0xa5,0x2b,0xd0,0x9f,0x03,0x8b,0xd3,0x1a,0xc4,0xb0,0xa3,0xc7,0xf4,0x35,0xe5,0x1d,0xe0,0xaa,0x43,0xab,0x64,0x10,0x2b,0xa4,0x09,0x42,0xee,0xba,0xb7,0xbf,0xfd,0xa6,0xff,0x76,0xe5,0x12,0xd6,0x50,0x9a,0x26,0x6b,0x3a,0xd3,0xe6,0x7d,0x3e,0x0e,0x9b,0x95,0xd7 +.byte 0xbf,0xb6,0x7e,0xfb,0x3c,0x24,0xa4,0x26,0x98,0x88,0x81,0xf4,0x56,0xa4,0xf7,0xe8,0x87,0x15,0x5e,0x9f,0x84,0xdd,0x04,0x66,0x43,0xd8,0x76,0xc2,0xa3,0xfd,0x4b,0x58,0x09,0x06,0xa6,0x60,0x5c,0x3f,0x75,0x80,0xd7,0xc4,0x29,0xf9,0x0b,0x1e,0x4d,0xe5,0x26,0xf6,0xae,0x7a,0xc1,0x05,0xf3,0xf1,0x6c,0xee,0xed,0x56,0x0b,0x51,0x66,0xbe +.byte 0x99,0xec,0x9c,0xc2,0x97,0xe2,0xed,0x09,0x1d,0xa8,0x18,0xaa,0x1c,0x9e,0x20,0x62,0xb1,0x80,0x68,0x3e,0x28,0x1f,0x4f,0x50,0x0e,0x41,0xaf,0x17,0x44,0x79,0x16,0xca,0x17,0xe9,0x13,0x66,0x0a,0x04,0x68,0x41,0xe2,0x1d,0xc7,0x00,0x1e,0x66,0xa3,0x6c,0x2d,0x52,0x8c,0x0b,0x7c,0x03,0x48,0x73,0x3b,0xa9,0x84,0xe5,0x31,0x12,0x0f,0xe8 +.byte 0x1e,0x58,0x4d,0xd0,0x1b,0xb7,0xcf,0x75,0xd5,0x2c,0xca,0x33,0x17,0x95,0x9c,0x30,0xc7,0x7f,0xe9,0xde,0xae,0x19,0x72,0x00,0x2a,0xf5,0xde,0x93,0x3f,0xf5,0x44,0xe5,0xf8,0xc7,0xeb,0x1a,0x5d,0x5b,0x11,0x30,0x09,0xf5,0x49,0x66,0x70,0x1a,0xd5,0xe6,0xfc,0xe6,0x59,0x3d,0x17,0x6c,0xb5,0x0c,0xdf,0x1e,0x9c,0x48,0xd1,0xde,0x12,0xd6 +.byte 0xc8,0x48,0xc8,0x73,0x6d,0xfc,0xec,0x07,0xce,0x02,0xe5,0xb3,0x18,0xb9,0x55,0x4d,0x64,0x07,0xf3,0xaa,0x3c,0xf1,0x71,0x22,0x31,0xbb,0x74,0x2c,0x9f,0x7b,0x68,0x9d,0x80,0x49,0x32,0x48,0x9b,0x54,0xf3,0x74,0x37,0xac,0x4e,0xb2,0x96,0xdf,0x9d,0xeb,0x43,0xe0,0xd0,0xa0,0xe3,0x77,0xbd,0x8b,0x92,0x95,0x9d,0x63,0x8d,0xa8,0x23,0x07 +.byte 0xb0,0xcb,0x9d,0x8d,0x3f,0xe2,0xd5,0x81,0x6a,0xe5,0xc2,0xfe,0xda,0x1c,0x25,0x25,0x5b,0xa8,0xad,0x06,0xec,0x0d,0x4b,0x68,0xc3,0x45,0x81,0x38,0xb0,0x22,0x71,0xa4,0x2b,0xf3,0xa6,0x05,0xae,0x0c,0x48,0x94,0x0d,0x3d,0x48,0x51,0x76,0xdf,0x79,0x66,0x0e,0x28,0xc0,0xc1,0x6f,0xc8,0x8f,0xf7,0x7d,0x37,0x06,0xa2,0x8a,0x3a,0x6b,0xab +.byte 0xe0,0x55,0x8e,0xec,0x89,0xe2,0xca,0xc4,0x01,0x03,0x5d,0xa1,0x84,0x21,0x44,0xbb,0x6b,0x36,0x63,0x57,0x4f,0x54,0x88,0x81,0xbe,0xf8,0x53,0xf7,0x57,0xee,0x30,0x85,0x03,0x11,0x86,0xff,0xe4,0xd6,0xc4,0xf0,0x3c,0xcf,0xfd,0x38,0xd8,0xcb,0xd0,0x96,0x03,0xf2,0xc7,0xfa,0x18,0xc8,0x1b,0xe6,0x77,0x3c,0x61,0xa9,0x14,0xdb,0xb4,0x5c +.byte 0x2d,0xee,0xd7,0xe8,0xc4,0x0c,0x69,0x0c,0x55,0xe2,0x99,0x4b,0xc4,0x89,0xc8,0xee,0x48,0x0e,0x16,0xd7,0xa4,0x78,0x25,0xda,0xd3,0xa8,0xac,0x89,0x66,0x67,0x0d,0x51,0x21,0x0e,0x91,0xfb,0xb5,0xab,0x33,0xcb,0x3e,0xc7,0x0f,0x03,0x22,0x51,0x71,0x03,0xa0,0x3c,0xa9,0x35,0xcb,0x40,0xa7,0xbe,0xe7,0xc3,0x51,0x43,0xd8,0x9a,0x24,0xb7 +.byte 0x7e,0xfb,0x26,0x8d,0xa5,0x1a,0x6b,0xe7,0x97,0xe4,0xdd,0xc0,0x3e,0x98,0x67,0x55,0x79,0x56,0xb9,0x7e,0x25,0x4c,0x5c,0x5a,0x47,0x0a,0xce,0xb6,0x4d,0x2c,0x69,0x73,0xaa,0xf0,0x12,0xbb,0x9d,0xe1,0x60,0xc4,0x5b,0x10,0x32,0x6d,0x89,0x54,0xb1,0xfe,0x36,0xbe,0xb2,0x60,0x9a,0x91,0x73,0x9c,0x32,0x61,0xad,0x9a,0xf7,0x56,0x5f,0x5a +.byte 0x54,0xaf,0xb2,0x0c,0x5b,0x1a,0xe6,0x98,0x94,0xed,0x69,0x0b,0x8d,0x06,0x87,0xc9,0x20,0xdc,0x92,0x2d,0x5e,0xba,0xbb,0x15,0xef,0xc1,0x07,0x18,0x44,0x3f,0xf4,0x48,0x3e,0x7b,0xa4,0x9e,0x14,0x6b,0x97,0xdd,0x68,0x33,0x18,0xdd,0x47,0x08,0xa6,0x3b,0x8d,0x79,0x58,0x92,0xd9,0xda,0x82,0x34,0xa7,0x99,0xbc,0x43,0xa3,0x0a,0x7e,0x85 +.byte 0x0b,0xab,0x0e,0xc2,0x94,0x22,0x2d,0x05,0x99,0x9d,0x5c,0xc7,0xb2,0x7b,0x18,0x3e,0xb2,0xdd,0x47,0xb3,0xd7,0xcf,0x19,0xc7,0x55,0x5e,0x64,0xd8,0x7b,0xb4,0xf6,0x11,0x72,0xed,0xbd,0xfc,0xd8,0xe9,0x9f,0xcd,0x9a,0xeb,0xb2,0x6c,0x04,0xb9,0x88,0xf7,0x60,0x68,0xc3,0xf2,0xfd,0xa0,0x8c,0x82,0xc5,0xf7,0x5d,0xc3,0x9a,0x1e,0x49,0x27 +.byte 0x69,0x35,0xb0,0x8f,0xe9,0xb3,0xe4,0x09,0xd8,0x1a,0x73,0x9e,0x56,0x41,0xfa,0xe0,0x94,0x9e,0x0e,0x65,0xe6,0x5b,0xe2,0x12,0x39,0xca,0x86,0x0c,0xae,0xee,0x24,0x58,0xfd,0x85,0x09,0x7a,0xad,0x54,0xde,0xda,0x06,0x73,0x7d,0x11,0x7e,0x91,0x44,0xf3,0x4b,0x61,0xce,0x8a,0xff,0x76,0x92,0x2e,0x43,0x52,0xcf,0x63,0x3f,0xc4,0x1f,0x7f +.byte 0x4d,0x67,0x21,0xed,0xd7,0x88,0xdb,0x36,0x56,0x11,0xb2,0x3b,0xee,0x5f,0x2d,0x5f,0x17,0x98,0xa1,0xd5,0xcc,0x82,0xfd,0xc2,0x56,0x69,0xaa,0x68,0x86,0xaf,0x48,0x77,0xba,0xe9,0xd9,0x42,0xcd,0xaa,0xe3,0xad,0x2b,0x17,0xef,0xd3,0x54,0xc5,0x4e,0x31,0x0b,0x14,0xb7,0x73,0xc1,0x6f,0xc3,0x06,0x41,0x1a,0x11,0x19,0x9f,0xe9,0x9f,0x61 +.byte 0x4f,0x13,0x9b,0x3e,0xcd,0x7c,0xd6,0x2a,0xb3,0x87,0x84,0x58,0x58,0x10,0x1f,0xa0,0x2e,0x5c,0x15,0x8b,0x5e,0x37,0xd4,0x22,0x93,0xd9,0x67,0xe1,0xa8,0x35,0xe2,0x95,0xd8,0x4c,0x2c,0x65,0xc9,0x21,0xaf,0xf9,0xdd,0x3d,0x2c,0x0e,0x0c,0xcc,0x6b,0xad,0xb3,0x6d,0xd2,0x3e,0x65,0x8e,0x82,0x70,0x41,0xd6,0xaa,0x97,0xab,0x38,0x78,0xe4 +.byte 0x62,0x7c,0x5f,0x22,0xa3,0x1e,0xf2,0x6c,0xfe,0x3c,0xa9,0xb5,0x57,0xcd,0x96,0x11,0xd0,0x8b,0xcf,0x6d,0x06,0xcf,0x7c,0xda,0x1d,0xe4,0x22,0x5c,0x5d,0x9f,0xa8,0x24,0x55,0x45,0x93,0xc6,0xeb,0xfc,0xb5,0x71,0x5a,0x1d,0x52,0x40,0x95,0xc7,0x76,0x32,0xfb,0x2b,0x0c,0x7d,0x64,0xfa,0x5b,0x5e,0x7a,0x3b,0x0b,0xa0,0x99,0x5d,0x19,0x16 +.byte 0xe4,0x8e,0xae,0x49,0xee,0xc5,0xb2,0x24,0xd7,0x0b,0xa4,0x20,0xa6,0x74,0xc4,0x36,0x1d,0x43,0x25,0xd6,0x71,0x54,0x69,0x79,0xea,0xa3,0xd5,0xe9,0x75,0x53,0xcf,0x99,0x4e,0x3b,0xc0,0x52,0x28,0x80,0xe5,0x07,0x65,0x83,0xb3,0x24,0xfe,0x13,0x92,0xd6,0x18,0xf7,0xa3,0xeb,0x9e,0xf0,0xd5,0x69,0x93,0x79,0xda,0xb7,0x2e,0xe2,0x01,0xdd +.byte 0x9a,0xc3,0x7b,0x3b,0x17,0x88,0xe5,0xe9,0x9b,0x46,0x5c,0x5f,0x0e,0x1e,0x80,0x9b,0x11,0x1f,0xa4,0x08,0x90,0x14,0x08,0xb4,0x73,0x32,0x72,0xbe,0x43,0x4f,0x70,0x90,0xe7,0x80,0xdd,0xfd,0xa7,0xea,0x13,0xd9,0x5d,0xae,0x93,0x24,0x2b,0x1e,0xc7,0xf4,0x81,0xbb,0x5f,0xb0,0xb9,0xe4,0x35,0x39,0xf4,0x9a,0x49,0xb5,0xc0,0x47,0x18,0xc3 +.byte 0xcc,0xbe,0x26,0x36,0x44,0x2d,0x65,0x24,0xa3,0x09,0xde,0x69,0x3b,0xb8,0xdc,0x52,0x98,0x2e,0x38,0x5f,0xf7,0xb1,0x84,0xdd,0xea,0xe2,0xe5,0xec,0x96,0x31,0xb1,0x93,0xc0,0x5b,0xc4,0x87,0x4a,0x51,0x58,0x2d,0xea,0x47,0xab,0xfd,0xd3,0x76,0xf1,0xbc,0x52,0xa7,0x94,0x6c,0x74,0x1e,0x84,0x07,0x1f,0x5c,0x18,0xb9,0x06,0x37,0xf0,0xfb +.byte 0xbd,0x5d,0xaf,0xa8,0x06,0xc9,0x86,0xf0,0xd1,0x78,0x84,0x95,0x01,0xdd,0x70,0x9d,0x71,0x51,0xb7,0x80,0x69,0xbe,0xe8,0xfb,0x8f,0x43,0x72,0xd9,0xa9,0xf1,0x90,0xbb,0xf1,0xb5,0xc0,0x75,0x93,0x4e,0x14,0xc5,0x14,0x77,0x59,0xf8,0xe5,0x81,0x11,0x25,0x48,0x51,0x46,0x2a,0x69,0x59,0x92,0xe7,0xa7,0x39,0x96,0xad,0x67,0x30,0xaa,0xb2 +.byte 0x5d,0x95,0x94,0x83,0x83,0x93,0xf3,0x52,0x81,0x1c,0x27,0x78,0x1d,0x19,0x35,0x6e,0x8f,0x16,0xe5,0x3b,0xce,0x80,0x2a,0x3a,0x89,0xb7,0x51,0xfc,0x34,0x24,0xa2,0x61,0x95,0x9e,0xd4,0x69,0xa1,0x2f,0x49,0x16,0x2d,0x12,0x05,0xfe,0x69,0x62,0x12,0xa4,0x2c,0x04,0x7b,0xce,0x3f,0x34,0xc4,0x48,0x1a,0xe6,0x64,0x4b,0x8a,0xbf,0x68,0xdd +.byte 0x54,0x15,0xd3,0x25,0x49,0xdd,0xed,0x5e,0x2c,0x0e,0x25,0xbe,0x77,0xcf,0x94,0xf4,0xe9,0xf3,0xcc,0xe6,0x94,0xf9,0xb2,0x5d,0x24,0x53,0x63,0xbb,0x66,0x8d,0x73,0xef,0x79,0x5c,0x95,0x1a,0x64,0xc3,0xfd,0xc0,0xd3,0x71,0xf4,0x79,0x19,0x79,0xa5,0x30,0xf8,0x2c,0x28,0xc2,0xc2,0x9d,0x12,0x50,0x95,0x38,0xec,0xd5,0xc6,0x28,0x94,0xaa +.byte 0x83,0x66,0x3b,0xe3,0x51,0xc7,0x6a,0x75,0x2a,0x9b,0xb9,0xb0,0xa2,0xe1,0xfd,0xaf,0x58,0xd2,0x4b,0xf4,0x22,0xef,0x77,0x1e,0xa0,0x00,0xd7,0x9e,0x20,0x63,0x87,0x1d,0x98,0xab,0x0e,0x57,0x31,0x4b,0xda,0x90,0x3a,0xe6,0x6e,0x5e,0xd4,0x17,0x06,0x83,0x4f,0x90,0x33,0x1c,0xe5,0xea,0xf7,0x8d,0x95,0xa2,0x1e,0x7d,0x27,0x15,0x49,0x68 +.byte 0x3a,0x54,0xe3,0x1e,0x60,0x72,0x42,0xa6,0x8c,0x5b,0x63,0x1d,0x7d,0xb1,0xe2,0x7e,0x8b,0x19,0xf4,0x25,0x6c,0x77,0x64,0x15,0x5e,0x4c,0xfa,0x35,0x68,0xd2,0x54,0x11,0x5a,0xac,0x85,0xb0,0xb3,0xe8,0xa8,0x70,0x36,0xa8,0xe5,0x04,0xd1,0x82,0xdc,0x62,0x63,0xe6,0x3f,0x86,0x46,0x77,0x08,0x6b,0xa8,0x09,0xd0,0x56,0x09,0x87,0x9c,0x65 +.byte 0x8e,0x53,0xae,0xa6,0x2b,0x59,0x23,0xca,0xe9,0xc7,0xc4,0xb5,0xb9,0xca,0x20,0xf6,0xcc,0x62,0xfd,0xb5,0x66,0x66,0x86,0x99,0xb2,0x5a,0xeb,0xac,0xff,0x22,0xf4,0x94,0x9c,0x6d,0xc9,0xce,0xf3,0x8d,0x26,0x7f,0x06,0x40,0x71,0x8b,0x3e,0x5c,0x3e,0xe6,0x11,0x64,0x91,0x79,0xbe,0x66,0x80,0xd2,0xf6,0x2d,0x28,0x4b,0x6c,0x8d,0x9c,0x5b +.byte 0x1e,0xd1,0x15,0xb0,0xdf,0xfb,0x57,0xaf,0x4a,0xab,0xde,0x12,0xe9,0xb8,0x41,0x3d,0xc3,0xff,0xb2,0xc1,0x86,0xb0,0x06,0x5b,0xaf,0xa4,0x30,0x62,0xd0,0xd8,0x91,0x36,0x28,0xc1,0xc2,0xef,0x60,0x5d,0x42,0x04,0xd5,0x6b,0x10,0xa9,0x6c,0x88,0x5c,0x56,0x59,0x4a,0x87,0xdc,0x7c,0x41,0x03,0xb3,0x7c,0x35,0x8c,0x52,0x0e,0xc1,0xd5,0xdf +.byte 0x9b,0x8a,0x2e,0xc2,0x6b,0x06,0x7f,0xb4,0x93,0xc9,0x52,0xd0,0xc5,0x57,0x78,0x9e,0xf9,0x08,0x36,0xbc,0x4b,0xc1,0xbd,0x71,0x35,0xf8,0x73,0xae,0x9c,0xbc,0xf1,0xd1,0xba,0xe3,0x7f,0x49,0x9b,0x9b,0xb3,0xe2,0x7d,0x7d,0x18,0x6d,0x0d,0x96,0xe3,0x50,0x28,0xf2,0x7c,0x7a,0x71,0x27,0x33,0x3c,0xd3,0xeb,0x3d,0x5a,0x79,0xb5,0x69,0xed +.byte 0x40,0x38,0xbe,0xc9,0xad,0x11,0x7b,0x9d,0xe6,0x71,0xc8,0x89,0x54,0x51,0xf0,0x8f,0xdc,0xad,0x96,0xc3,0x04,0x60,0x5f,0x6d,0xa0,0x37,0xba,0x1c,0x69,0xca,0x42,0x26,0xeb,0x31,0x34,0x8d,0xae,0x25,0xe2,0x29,0x8d,0x19,0x9f,0xfa,0x75,0x91,0x4b,0x51,0xcd,0x76,0xd6,0x8f,0xa2,0x40,0x79,0xc3,0xbb,0x61,0xaf,0xc4,0x69,0xf5,0x8b,0x8a +.byte 0xb6,0x2c,0x25,0xb9,0x3c,0x8e,0x13,0xa4,0x0f,0x52,0x72,0x11,0x4b,0x89,0x63,0x01,0x05,0x54,0xd5,0x0d,0x5f,0x91,0x59,0x84,0x64,0xac,0xf7,0x9c,0xa3,0x48,0x31,0x4a,0x2e,0xea,0xf8,0xf8,0x0e,0xf0,0xd9,0x4d,0x06,0x60,0x11,0x4a,0x72,0x6f,0x93,0x93,0x85,0xf0,0x20,0x55,0x8b,0x37,0xf1,0x29,0x92,0x2d,0x1f,0xa1,0x6c,0x7c,0x90,0x4f +.byte 0xdb,0x78,0xcc,0x6c,0xb2,0x14,0x85,0x07,0x34,0xc8,0x98,0x18,0x52,0x2d,0x6b,0x13,0x63,0xc5,0x31,0x20,0x8e,0xa9,0x88,0x6b,0xb3,0x3f,0x1a,0x68,0x2f,0xf9,0xf3,0x97,0x29,0x68,0x22,0x89,0xb0,0x45,0xc4,0xf4,0x1f,0x31,0xba,0x97,0x14,0x59,0xae,0x05,0xe0,0x99,0x5b,0x29,0xcf,0xe3,0xf0,0x2a,0x0c,0xca,0x5f,0xc1,0xe7,0xe7,0x11,0x48 +.byte 0x73,0xc0,0x86,0x0b,0x59,0xc2,0x8a,0xfa,0x44,0x51,0x1c,0x84,0xdf,0x2f,0x4d,0xab,0xca,0xea,0xe1,0x48,0x9a,0xa1,0x86,0x60,0x47,0x7a,0x86,0x30,0x6a,0xba,0xbe,0x6a,0x9b,0x34,0xf4,0x52,0x0e,0xae,0x7f,0xbd,0xe0,0xf4,0x5f,0xfd,0xbc,0x57,0x02,0x95,0x6f,0xad,0x78,0x2e,0xa7,0x46,0x1c,0x2d,0x98,0x40,0xb7,0xfa,0xb5,0x08,0xee,0xb5 +.byte 0x25,0x51,0xaa,0x1a,0x14,0x41,0x48,0xe0,0x8f,0xe7,0x2f,0xfc,0xfd,0x47,0x10,0x55,0x90,0x02,0xeb,0x7f,0x0d,0x40,0xa8,0x4b,0x82,0xdc,0xab,0x43,0x35,0x62,0xa1,0x1d,0x5a,0xb0,0xc0,0x93,0x75,0x3d,0x68,0xd9,0xf8,0x31,0x22,0xfd,0x30,0xda,0xea,0xea,0x7c,0x30,0xf8,0x6f,0x75,0x5f,0x07,0x39,0xfe,0x69,0x93,0x73,0x22,0xa2,0x72,0xed +.byte 0x39,0x2f,0x00,0x5c,0xc3,0x14,0x86,0x90,0xda,0xc9,0x09,0x43,0x80,0x85,0x22,0x98,0xb0,0x4e,0x05,0x47,0x8f,0xc7,0xba,0x2e,0x4c,0x8f,0x57,0x8a,0xe9,0xb0,0x97,0x3b,0x51,0x12,0xcb,0x88,0xfd,0x5e,0x7f,0xa6,0xc6,0x00,0xd0,0x3a,0x3a,0x70,0x9e,0x56,0x28,0xa0,0x08,0x76,0x58,0x57,0x4a,0x0f,0xff,0x31,0x44,0x08,0x6c,0x23,0x79,0xad +.byte 0x35,0x95,0xc5,0xc8,0x26,0x0f,0xb3,0x17,0x04,0x1d,0xde,0x16,0x5d,0xb8,0x71,0x76,0x89,0x0b,0xd6,0xd8,0x9d,0xa1,0xdf,0xcb,0xb5,0x1c,0x86,0xc3,0x15,0x8d,0xaa,0x25,0x82,0xbf,0x6b,0x06,0xfb,0x1b,0xf5,0x11,0xaa,0x14,0x0e,0x67,0x7f,0xbd,0x46,0x21,0x8f,0x6d,0xbd,0x63,0xe6,0x14,0x05,0xa2,0xee,0x56,0xee,0xe6,0x37,0xf9,0xc0,0x2f +.byte 0xc9,0xe0,0x8e,0xdb,0xf7,0xf6,0xcb,0x83,0x79,0xcc,0xe3,0xf6,0x30,0x9d,0x56,0x31,0x40,0xd2,0x50,0x25,0xb6,0x89,0x16,0x97,0x65,0xd8,0x8d,0x1a,0xa5,0xf4,0x47,0xfc,0x4c,0x73,0x07,0x42,0x9c,0x8f,0x7f,0x10,0xb4,0x96,0x33,0x1e,0xe2,0xff,0x0c,0x33,0x35,0xbc,0x37,0x01,0x2b,0x67,0xda,0xca,0xcf,0x87,0xa2,0x38,0x71,0x6b,0xf4,0xcf +.byte 0xa6,0xc6,0x6a,0x90,0x5c,0xa0,0x8b,0x66,0x44,0xc7,0xc2,0x05,0x24,0xee,0x53,0x99,0xf3,0x07,0x78,0xb0,0x17,0xf8,0x11,0xf9,0x52,0x20,0x41,0xc5,0xdb,0x4e,0x92,0xd3,0xeb,0xd2,0x86,0xea,0x9b,0xc3,0x4c,0x1b,0x75,0xcd,0x15,0x0c,0xe0,0x28,0xe9,0xe1,0x99,0x98,0x96,0x33,0x06,0xea,0xa8,0x4e,0xde,0xc1,0x1c,0xfe,0x6c,0xca,0xac,0x6d +.byte 0xc4,0x3a,0x7d,0xd2,0x41,0xf5,0xb3,0x7d,0x1c,0x28,0x93,0x72,0xf8,0x08,0xc1,0x71,0x72,0x4c,0x41,0x68,0x38,0x80,0x2e,0x4b,0xa6,0xc5,0xc7,0xb4,0x24,0x29,0xd0,0xce,0xb2,0x3d,0xc4,0x60,0x5b,0xeb,0x2d,0x80,0x13,0xee,0x95,0x41,0xfe,0x49,0x6d,0x89,0xc0,0x7a,0x61,0x51,0x3f,0xbb,0x24,0x7c,0x64,0x5e,0x9f,0xf7,0x60,0x88,0x95,0xe8 +.byte 0x60,0xc5,0xf6,0xc3,0xc3,0xd4,0x43,0xce,0xf9,0x4e,0x35,0xf2,0xfa,0xb0,0x2b,0xe3,0xfe,0xb8,0x88,0x19,0xf2,0x89,0xc0,0xb5,0x00,0x61,0xc8,0xe5,0xaa,0xde,0x18,0xb4,0xd4,0x21,0xbe,0xcc,0x61,0xc7,0xc9,0xfe,0x22,0xcc,0x65,0xf6,0x79,0xe8,0x4d,0x1c,0x30,0x31,0x7a,0xd4,0xbc,0x98,0x2d,0x72,0x5e,0x5c,0x4f,0x7e,0x52,0x9c,0x95,0x20 +.byte 0x29,0xa4,0x0b,0xf7,0xb2,0x7d,0xcc,0xc3,0x8c,0x94,0xb0,0x09,0xf4,0x6f,0x59,0x63,0x91,0x2a,0x06,0x80,0x09,0x01,0x3c,0x73,0x83,0x42,0xa1,0x5c,0x0f,0x42,0xf4,0x74,0x3c,0x24,0x8c,0xbe,0x91,0x73,0xdf,0xf1,0xea,0x21,0xbd,0xc9,0x36,0x17,0xca,0x81,0x28,0xd9,0x4a,0xc4,0x2e,0xdf,0x4c,0x4f,0xbd,0x1e,0xbc,0xe9,0x32,0x12,0xd3,0x8f +.byte 0x48,0x9b,0x4f,0x49,0x23,0x54,0x15,0x15,0x14,0x8b,0x18,0x64,0x7d,0x08,0x7f,0xc4,0x56,0x01,0x94,0x4e,0x50,0xe8,0xf2,0x4a,0xb5,0x3c,0xa0,0xb5,0xaf,0x55,0x70,0x44,0x41,0x5c,0xe6,0x61,0x5a,0xbb,0xf2,0xe6,0xc9,0x05,0x33,0x45,0x8f,0xbc,0xe5,0x59,0x7f,0x66,0xc5,0x61,0x4d,0x1b,0xc7,0xee,0x45,0x7d,0x57,0x8f,0x6c,0x9d,0x8b,0x87 +.byte 0x98,0xa8,0x58,0xac,0x4a,0x31,0x79,0xd6,0x26,0x08,0x2f,0x28,0x3f,0x31,0x77,0xad,0xff,0xe1,0x9d,0xa8,0xf7,0xe0,0x76,0x66,0x48,0x00,0x52,0xe8,0x9a,0xb2,0x47,0x5e,0x0a,0x87,0x86,0xaf,0xf6,0x7d,0x46,0x78,0x66,0x68,0xf7,0x68,0x0c,0x6f,0x5c,0xd7,0x09,0xc0,0xd7,0x90,0x98,0xe2,0x5c,0x07,0xe9,0xd1,0x58,0x48,0x57,0x9f,0x48,0x99 +.byte 0x87,0xdf,0x06,0xc1,0x35,0x0f,0xd8,0xb0,0xa9,0xfa,0xdc,0x31,0x76,0xd1,0xad,0x47,0x80,0xe4,0x74,0xe0,0xda,0x4b,0x77,0x8b,0x71,0xab,0x9a,0x8e,0xd7,0x6b,0x91,0xb1,0xdb,0x78,0xd2,0x86,0xf7,0x61,0x1b,0xdc,0x34,0x57,0x32,0x51,0xee,0xd3,0xff,0xb2,0x6c,0x6a,0x79,0x90,0x9c,0x1f,0x6b,0xe7,0x43,0x20,0x05,0x4f,0x66,0x83,0xd0,0x56 +.byte 0xe1,0x21,0x63,0xf4,0xd6,0x96,0x91,0xcb,0x51,0x3c,0x13,0x88,0x97,0x26,0x88,0xda,0x7c,0xd4,0x0d,0xcb,0xdf,0xc2,0x7d,0xcd,0x2c,0x0e,0x28,0x23,0x21,0x5f,0xbe,0x5d,0x62,0x58,0x6c,0xa7,0x45,0xae,0x1f,0xac,0x35,0x53,0xdb,0x2c,0xa6,0x71,0xe4,0x11,0x5e,0x59,0xbe,0xd5,0x20,0x2a,0xc4,0xcd,0x4c,0x1b,0xe0,0x38,0xef,0x02,0x0c,0x5f +.byte 0x5a,0x1b,0xf9,0x1e,0x32,0x63,0xd7,0xa6,0x0f,0x1d,0x98,0xd5,0x3a,0x0f,0xf6,0xcc,0xfc,0xd6,0xb4,0x87,0xc5,0x76,0xd8,0x3e,0x72,0xb0,0x20,0xfe,0xb3,0xfc,0x48,0x4c,0xd1,0x71,0xcd,0x13,0xef,0xe8,0x40,0xd9,0x0d,0xf6,0x1d,0x5b,0xa4,0x26,0x56,0x8c,0x66,0xcb,0x18,0x5a,0x5f,0x86,0x43,0x2c,0xa4,0x1e,0x00,0x3f,0x09,0xbf,0x8e,0x61 +.byte 0xad,0x2a,0x44,0x97,0x35,0xb2,0xf3,0x50,0x5f,0xfa,0x01,0x74,0xbf,0x70,0x46,0x38,0xf1,0x15,0xaa,0x04,0xfe,0xe9,0x3f,0x43,0x2f,0x53,0xcb,0xea,0x5c,0x04,0x8e,0xe6,0x43,0xeb,0xc0,0xd9,0xbf,0x4a,0xc1,0xbc,0xf9,0x11,0xd5,0x33,0xdc,0x41,0x8e,0xfe,0x5e,0xf3,0x8c,0x80,0x47,0x46,0x01,0x9e,0xa9,0x2c,0x2d,0xd2,0x90,0x7f,0xce,0x7c +.byte 0x59,0x78,0xaa,0xbb,0x96,0x52,0x0a,0xf3,0x18,0x1f,0x0b,0x41,0xc1,0xd5,0x12,0x14,0x1a,0xe1,0x4e,0xac,0xf8,0x2a,0x56,0xfe,0x66,0x34,0x21,0xdf,0x1f,0x6a,0x02,0x85,0xd2,0x38,0xc0,0x39,0x5c,0xa7,0x3f,0xcc,0x2b,0x6f,0x69,0xe7,0xa7,0x0a,0x36,0xf1,0xa9,0x77,0x59,0x2c,0x44,0x8b,0x72,0xc9,0xc2,0x74,0x32,0x48,0x76,0x19,0x1e,0x49 +.byte 0x10,0xe6,0x46,0xdf,0x82,0x9b,0xad,0x4e,0x40,0x20,0xd7,0xd3,0xf5,0x5c,0xbc,0x25,0x94,0xd1,0x68,0xaf,0x29,0xc5,0xcd,0x1b,0x86,0x4b,0x88,0x21,0x6e,0xeb,0x06,0x14,0xb5,0x15,0xe7,0x26,0x01,0x05,0x4e,0x3a,0x2a,0x24,0xbe,0xf2,0x64,0x6e,0xf4,0x9c,0x60,0xf8,0xd4,0xfd,0x4b,0xc0,0x0e,0x68,0x0d,0x19,0x26,0x87,0xa5,0xbf,0xe1,0x16 +.byte 0xf0,0x27,0x58,0xa8,0x3a,0xed,0x27,0x5b,0x73,0x4f,0x19,0x40,0x58,0x36,0xf6,0xfd,0x60,0x37,0x09,0x74,0x3c,0xb9,0x76,0x9a,0x32,0xfd,0x98,0x79,0x53,0xb3,0xea,0x3a,0x98,0x21,0xf9,0xb2,0x97,0xe4,0x00,0xb6,0xed,0x67,0xc4,0x76,0x8f,0x1e,0x4d,0xc8,0x2e,0xf4,0x54,0xd9,0x09,0xd7,0xcb,0xa0,0x91,0x1e,0x5a,0x60,0x53,0xbc,0x3e,0x35 +.byte 0x69,0xa6,0xca,0xf3,0xce,0x41,0x84,0x71,0xee,0xf3,0x75,0xd4,0x7a,0x71,0x36,0x62,0xe3,0x08,0xae,0x40,0x05,0xde,0x01,0x34,0x92,0x5f,0x71,0xa9,0x08,0xb3,0x43,0xcd,0xe7,0x2f,0x42,0x7e,0x9c,0x1e,0xfe,0x9a,0x40,0x99,0x58,0x31,0xd9,0x8d,0x5d,0xda,0x75,0x14,0x3f,0xae,0x45,0x27,0x85,0x47,0x7d,0x41,0x0e,0x94,0x20,0xee,0x11,0xd0 +.byte 0x1e,0xcd,0x00,0x56,0xb7,0x59,0xe6,0x58,0xab,0x2c,0xa6,0x44,0x14,0x8c,0xff,0x49,0x7b,0xe5,0xf7,0x93,0xd5,0x78,0x1a,0xe0,0x16,0xd8,0x24,0x08,0x1e,0x70,0xce,0x1a,0x84,0x87,0x6b,0xe5,0xf2,0x43,0x5f,0xb3,0x34,0xaa,0x85,0x3e,0x9e,0x2e,0x86,0x22,0x74,0xe2,0x1a,0x87,0xfb,0x1b,0x6c,0x08,0x8c,0x43,0xb4,0x85,0x75,0x2c,0x13,0xc2 +.byte 0x18,0x94,0xe8,0x0d,0x09,0xd5,0x8f,0xd4,0xca,0x50,0x93,0x9f,0xa3,0x9f,0x3b,0x3c,0x54,0x68,0xa9,0xb1,0xdd,0x0a,0x0b,0xe2,0x15,0x92,0x9c,0x6f,0xfa,0x45,0x6f,0x0a,0xb4,0x6b,0xcb,0xdc,0xa4,0xf3,0xf0,0xa6,0x1c,0x8a,0x60,0x42,0x35,0xa8,0xe3,0xdf,0xc8,0xdc,0xbb,0xbe,0x95,0xa7,0xac,0x08,0x08,0xbc,0x56,0x1a,0xa4,0xc2,0xd2,0x53 +.byte 0xfa,0xb2,0x89,0x4f,0xb8,0xe4,0xb9,0x90,0x95,0x91,0x2f,0x0f,0x93,0xa9,0x8c,0xc6,0xf8,0x01,0x34,0x08,0xe6,0x8c,0x58,0x43,0x57,0x40,0xf9,0x78,0x83,0xea,0x92,0x70,0xa8,0xa5,0xc8,0x9e,0xf8,0xc6,0x39,0x4c,0xb4,0xe9,0xbb,0xdf,0xd2,0x52,0x43,0x6b,0x6c,0x8b,0x2c,0x47,0xd7,0x11,0x42,0x3d,0xc7,0x3f,0xce,0xd1,0xd9,0x28,0x5b,0xce +.byte 0xec,0xb6,0x31,0x3a,0xc9,0xad,0x0c,0x93,0x82,0x2b,0xf6,0xdc,0xd4,0xcd,0x80,0xe1,0x75,0x45,0xeb,0x3b,0xbf,0x12,0x42,0xeb,0x71,0xc1,0x8b,0x27,0xd5,0xcb,0xd9,0xb6,0xe8,0xe9,0xc6,0x79,0xff,0x38,0x88,0x87,0x72,0xf2,0x71,0x4a,0x44,0x55,0x0f,0x9c,0x93,0xcf,0x15,0x18,0x44,0x62,0x2a,0xc5,0x0a,0x80,0x69,0x91,0x6e,0x4b,0x30,0x4e +.byte 0x3f,0x2f,0xb5,0x65,0x9e,0x65,0x07,0x36,0x9b,0xba,0x5f,0x81,0xd9,0x60,0xbe,0x1f,0xf5,0x98,0x20,0xf9,0x9e,0x53,0xf7,0x5d,0x57,0x7f,0x22,0xaf,0x8e,0x82,0x9e,0x0f,0x33,0x74,0x37,0x26,0x61,0x67,0xf6,0xfd,0x2c,0xab,0xd8,0x18,0x1d,0x10,0x48,0x7a,0x1d,0xed,0xbb,0x57,0x83,0xf9,0x82,0xf5,0xe3,0xf9,0x98,0x5c,0xc0,0x3e,0xee,0x38 +.byte 0x0a,0x57,0x10,0x22,0xc4,0xe8,0x1d,0xe3,0x46,0xa3,0x81,0x5e,0x92,0xba,0xcc,0x53,0x48,0x85,0x33,0x58,0xa2,0x3e,0xea,0x0a,0xfb,0x72,0x5c,0xcd,0xd9,0xa4,0x3f,0x56,0x99,0x35,0x92,0x6c,0xe8,0xf2,0x59,0x0f,0xc8,0x6a,0x21,0xb2,0x9f,0xa2,0xf6,0xf3,0x1b,0xec,0x38,0x95,0xed,0xef,0x00,0x09,0x16,0x6e,0xf7,0xf8,0x1a,0xef,0x0d,0x2b +.byte 0xef,0x83,0x8a,0xc2,0x22,0x3d,0x50,0xa3,0x70,0x52,0xe8,0xad,0x11,0x44,0x83,0x80,0xfe,0x88,0x7e,0x40,0x02,0x8f,0x4a,0x5d,0xd3,0x28,0x66,0x75,0x5a,0xf2,0x38,0xb5,0xdc,0x54,0xa8,0xb3,0xaa,0x76,0xdb,0x73,0xe0,0xd1,0xd7,0x51,0x20,0x8c,0x38,0x18,0x46,0x25,0x2e,0x0d,0x5b,0x61,0x9d,0x36,0x9a,0x14,0xfb,0xc8,0x4e,0x5a,0xba,0xa1 +.byte 0x98,0x34,0xfd,0x05,0x2c,0x87,0x58,0x8d,0xe3,0x5d,0x79,0x5a,0x45,0xff,0x75,0x25,0x98,0xbd,0xe4,0x9d,0x1a,0x70,0x79,0xaa,0x44,0x1a,0x10,0x7f,0xfb,0xe9,0x30,0x81,0xc7,0xa2,0x81,0x41,0x49,0x41,0x4e,0x42,0x5f,0x8a,0x9b,0x10,0xe2,0xdc,0xd9,0xdf,0xbd,0x61,0x29,0x72,0xa5,0x39,0xb7,0xf6,0x9f,0x4e,0x98,0xb8,0x04,0xae,0xd7,0xda +.byte 0x9a,0x9f,0x08,0xb8,0x2c,0x40,0x14,0x6d,0x01,0xb7,0x86,0x58,0x55,0x42,0xe5,0xdb,0x5f,0x4a,0xef,0xd8,0xed,0xdf,0x3b,0x24,0x1c,0xe4,0xb1,0x73,0xd1,0xce,0x29,0x96,0xde,0x8e,0xf3,0x1d,0x8d,0x75,0x57,0xd3,0x9a,0xf8,0xff,0x1a,0x4c,0x0c,0x47,0x82,0x83,0x73,0x34,0x43,0x55,0xfa,0xf2,0xd4,0x38,0xed,0xde,0x6d,0x24,0x55,0x90,0x06 +.byte 0xd6,0x03,0x52,0x28,0xc7,0x38,0x4a,0x16,0x95,0x4d,0xf4,0x46,0x56,0xf7,0x63,0x1f,0xe4,0xa9,0x51,0xc6,0x0b,0x85,0x42,0x40,0x8e,0x49,0x1e,0xc2,0xab,0xeb,0xda,0x99,0x26,0xf6,0x6e,0x00,0x8f,0x26,0x82,0xef,0x03,0xb0,0xd4,0xdb,0x54,0x46,0xdf,0xdc,0x23,0xaf,0xa8,0x6a,0x9f,0xb7,0xf9,0x41,0x07,0x5e,0x2d,0xcf,0x85,0xfd,0x9c,0x46 +.byte 0x30,0xb9,0x14,0xca,0xe2,0x30,0x12,0x06,0x88,0x08,0x05,0x2c,0x9a,0x4b,0x52,0x98,0xa9,0x99,0xd7,0xca,0xb5,0x1e,0x60,0x44,0xd9,0x5c,0x19,0x42,0xbe,0xa5,0x04,0xfd,0x7a,0xfc,0xb9,0xdf,0xd6,0xe3,0x6d,0x02,0xe3,0x96,0xf6,0xae,0xf3,0x78,0x1d,0x90,0x6d,0x86,0x17,0xf7,0xb7,0x6b,0x1d,0x52,0x32,0x5b,0xc0,0x31,0xaf,0x09,0x90,0x5e +.byte 0x81,0x75,0x17,0x47,0x6b,0x5e,0x9a,0x40,0xa5,0xa8,0x84,0x60,0xdc,0xdb,0xd2,0x89,0xcd,0xb2,0x72,0xf4,0x74,0xda,0x5d,0x34,0xf8,0xc6,0x1b,0x26,0x3e,0x8b,0xc7,0x73,0xf9,0x0c,0x93,0xf4,0x40,0x02,0xe0,0xed,0xe5,0xa0,0xae,0x91,0x03,0x85,0xa8,0x2f,0xe2,0x72,0xfe,0x17,0x7d,0x2b,0xa6,0x39,0x10,0x80,0x4c,0x58,0xaa,0xd8,0x22,0x7d +.byte 0x2f,0xbf,0x0c,0x40,0x48,0xfa,0xbe,0x40,0x4c,0x32,0x96,0x69,0xa5,0xab,0x0b,0x1e,0x33,0x9b,0xcf,0xe6,0x4e,0x2b,0x41,0x5a,0x21,0x23,0xa1,0xbb,0xd3,0xd6,0xd1,0xfd,0xbd,0x55,0xfc,0x92,0x92,0xcb,0x4b,0x72,0x39,0x8b,0xeb,0x72,0xdd,0xf7,0x77,0x43,0x52,0x2f,0x99,0x14,0x6e,0x41,0xce,0x1d,0x57,0x2c,0x09,0xd2,0x18,0xec,0x1b,0x89 +.byte 0xa0,0xe9,0xfe,0x1e,0x41,0xda,0x0f,0x76,0x02,0x38,0xec,0x9a,0x30,0xb7,0x5a,0x54,0x70,0xbc,0xe8,0xfa,0x06,0xd0,0x80,0xfb,0x27,0xd2,0xd8,0x00,0x80,0x65,0x9d,0x23,0xfd,0xad,0x26,0xb8,0xdc,0x09,0x4f,0xfb,0x52,0xcd,0xe4,0x41,0x68,0xca,0xdd,0xbc,0x2a,0x62,0xeb,0xa6,0x32,0x71,0xb0,0x08,0xb6,0x9f,0x3e,0x74,0xfe,0xb0,0xd4,0x9d +.byte 0x9e,0x6c,0x50,0x96,0x8a,0xde,0xd6,0xe9,0xde,0x2c,0xa6,0xf0,0x9f,0x67,0x00,0x50,0x0a,0x8c,0xe5,0xc2,0x37,0xcc,0xf0,0x53,0xeb,0x72,0xf2,0x87,0x77,0xee,0x80,0xe8,0xb2,0xa1,0x13,0x52,0x70,0xe6,0x8f,0x70,0x17,0x90,0x60,0xcb,0xac,0xb2,0x72,0xef,0xd9,0xb5,0xc3,0x68,0x57,0xdf,0x2d,0xcb,0x5a,0x35,0xf9,0x2e,0xfb,0xef,0x6e,0x77 +.byte 0x5d,0x21,0x37,0x4b,0x36,0x9b,0x3f,0x03,0x65,0xc9,0x84,0xb1,0x12,0x99,0xd1,0x6b,0x00,0x71,0x37,0xc7,0x57,0x82,0x44,0x7f,0xe1,0x81,0x24,0x70,0x96,0xd5,0x27,0xba,0x36,0xf7,0x25,0xc6,0x1c,0x7c,0x1b,0xdb,0xa3,0x6a,0x3e,0xb9,0x69,0x78,0xf7,0x51,0x46,0xe2,0x74,0xd3,0xfc,0xef,0x58,0x63,0x53,0x1d,0xd7,0xd0,0x8a,0x6a,0xd3,0xb0 +.byte 0xb9,0xbb,0xba,0x43,0xbf,0x8b,0x6b,0x04,0xd2,0xb1,0xe8,0xd1,0x72,0x3f,0xdc,0x2b,0x01,0xa6,0x2f,0x9c,0x7d,0x65,0xa1,0x9f,0x9b,0x4d,0x70,0x26,0x11,0x4c,0xb2,0xe1,0x01,0x0e,0x78,0xf2,0x32,0x87,0x2d,0x8e,0x95,0x02,0x76,0xca,0xe5,0x71,0x5f,0x36,0x35,0xb9,0xbb,0xc3,0xdf,0xf3,0x1e,0x1a,0x7a,0xe4,0x2c,0xdf,0x64,0x5d,0x96,0x12 +.byte 0xea,0x5c,0x14,0x73,0xa0,0xf1,0xbc,0xa9,0x6e,0x30,0x8a,0x47,0xf0,0x4b,0x9b,0x4c,0xc5,0xb0,0xbe,0x15,0x32,0x1b,0xde,0x0c,0x39,0x6a,0x6d,0x4e,0x3b,0x69,0x4c,0xb4,0x1f,0x56,0xf0,0xa1,0xb1,0x8c,0x29,0x5c,0x87,0x54,0xf2,0x5b,0x51,0x03,0x20,0x70,0x90,0x38,0x66,0x07,0xcc,0xd7,0xde,0x96,0x40,0x82,0xee,0xb5,0x87,0x2a,0x86,0xec +.byte 0x66,0x09,0xb7,0x4a,0xfe,0x4e,0x92,0x89,0x07,0xde,0x35,0xc4,0x6e,0x91,0x25,0xfd,0x18,0xfa,0xd9,0x8f,0xa7,0xa6,0xa7,0x6b,0x32,0xba,0xd3,0x1c,0x90,0xb9,0x8a,0x6c,0x9f,0x3f,0xb5,0x16,0x81,0x81,0xee,0xd7,0x55,0xc1,0x41,0x62,0xfd,0xe9,0x4c,0x5d,0xd7,0x70,0xdd,0xc6,0x4a,0x2b,0x42,0x77,0xe7,0x74,0xed,0x02,0x80,0x0d,0x7c,0x73 +.byte 0x8e,0xf0,0xd3,0xb0,0x20,0xbb,0xc8,0x82,0x06,0xdd,0x56,0x64,0xcb,0x9c,0xda,0xa1,0xa9,0x92,0xbc,0x8c,0x65,0x03,0xcd,0x68,0x87,0xa2,0x94,0x41,0x3c,0x36,0x96,0x1f,0xa4,0xd2,0x6d,0x5d,0x9f,0x2d,0x0c,0xf9,0x8a,0x82,0x19,0x93,0x47,0x62,0x71,0x8e,0x59,0xaa,0xf1,0x87,0xe0,0xb8,0xab,0x10,0x7f,0x4e,0xa8,0xa3,0xe2,0x32,0x58,0xb0 +.byte 0xcf,0x12,0xc0,0xf8,0x94,0x4a,0x61,0x36,0xdc,0x2d,0xb5,0x91,0xf9,0x0f,0x7d,0x91,0xd3,0xc7,0x03,0x8a,0xae,0x5c,0x22,0x8c,0x60,0x30,0xf4,0x71,0x51,0x00,0xf5,0x5d,0xe9,0x37,0x6c,0xae,0x64,0xff,0x45,0x35,0x4b,0x47,0x08,0xca,0xda,0x7b,0xe9,0xef,0xcb,0x27,0xcb,0x7e,0x3c,0xa6,0xd2,0x38,0x54,0x74,0xc3,0x7c,0xf8,0x71,0xb7,0x47 +.byte 0xe9,0xe0,0x43,0x03,0x3b,0x41,0x57,0xc3,0xda,0xa1,0xcb,0x64,0xb1,0x31,0x0d,0x12,0x45,0x3a,0xa0,0xad,0x6b,0xc7,0x26,0x62,0x50,0xcf,0x94,0x5a,0x30,0x8d,0xf6,0x91,0x49,0x9e,0xd5,0x84,0x0e,0x0c,0xe3,0x47,0x08,0x7f,0xa1,0x54,0x78,0x1b,0xa8,0x2c,0xbc,0x12,0x4f,0x7e,0x53,0x1b,0xca,0xfb,0x09,0x35,0xe0,0x9c,0x15,0xea,0xf6,0x3e +.byte 0xb2,0x20,0x9e,0x2c,0x81,0x6f,0xa4,0xb5,0x6b,0x04,0x6d,0xd1,0x90,0x66,0x46,0xdc,0x4b,0x71,0x7e,0x4b,0x3f,0xd6,0xe1,0xa8,0xc0,0xa7,0x45,0x85,0xe3,0x98,0x30,0xda,0x23,0x68,0x55,0xd8,0x96,0xb1,0xcc,0xeb,0xe1,0x95,0x0b,0x20,0xf3,0x4c,0xf2,0xc5,0xfa,0x0e,0xca,0xf5,0xc9,0xb3,0xd7,0xb4,0x1b,0x9f,0xef,0x82,0x56,0x4c,0xc5,0xa5 +.byte 0x21,0xda,0xcc,0x19,0x69,0x68,0xcb,0x37,0xb2,0x0c,0x73,0xb1,0x13,0x61,0x6b,0xca,0xda,0xfc,0xf7,0x1c,0xbc,0xd1,0x72,0x56,0xb8,0x7d,0xa1,0xef,0xc4,0x32,0x38,0xa3,0xdb,0x8b,0x2d,0x0a,0xce,0xcb,0x86,0x51,0x60,0xd2,0x47,0xf0,0x97,0x58,0xd8,0xa5,0x12,0x77,0xfc,0x32,0x04,0x29,0x61,0xfc,0xab,0xc2,0x42,0x86,0xd9,0x57,0x80,0xad +.byte 0x00,0xf0,0x9a,0x2a,0xac,0x52,0x27,0xd6,0xf8,0xd6,0x38,0xc8,0xfc,0xc1,0xab,0x4f,0x41,0xbf,0x8e,0x60,0x20,0xeb,0x24,0x36,0xd8,0xd8,0x25,0x6f,0xc8,0x5d,0x6b,0x00,0xdd,0x7a,0xe2,0x37,0xe4,0x13,0xd0,0xaa,0x5c,0x56,0x32,0x98,0x00,0x4b,0x8a,0x81,0xb1,0xfa,0xe8,0xf3,0xfa,0x0d,0xbb,0x66,0x6e,0x24,0xfd,0x3c,0x50,0x63,0x3a,0xf1 +.byte 0x72,0x63,0x18,0x71,0x6d,0xee,0x6f,0xf1,0x0e,0x1f,0x9e,0x9d,0x87,0x12,0x5c,0xdf,0x1d,0x9e,0xc0,0x0b,0x39,0x0e,0xd6,0x56,0x79,0x30,0xcb,0x07,0x7b,0x88,0xa5,0xbe,0xfd,0xd4,0x49,0xcc,0x92,0x6a,0xcc,0x78,0x1e,0xaf,0xee,0x89,0xc8,0x51,0x08,0x98,0x14,0x20,0xe5,0x52,0x93,0x18,0x6f,0xbb,0xdc,0xb2,0x68,0x14,0xd1,0xdb,0xe8,0x56 +.byte 0x24,0xd0,0x34,0xab,0xa6,0xfa,0xfe,0x72,0x5a,0xe3,0xe1,0x87,0x0d,0xf4,0xfa,0xa6,0xa6,0x6c,0xb6,0xcb,0xf8,0xfc,0x59,0xac,0xd9,0xb0,0xcd,0x15,0xa4,0x37,0x73,0x6e,0x70,0xc9,0x74,0xef,0x87,0x78,0x61,0xc2,0xd0,0x52,0x51,0xa9,0x2c,0xdb,0x9d,0xd9,0x3d,0xac,0xcd,0x52,0x39,0x69,0x2d,0x2a,0x4f,0xf3,0xb2,0x69,0xb9,0x01,0x3c,0x57 +.byte 0xeb,0x1b,0x0e,0x87,0xe9,0x42,0x58,0x83,0x6b,0xbc,0x72,0xc8,0x46,0x32,0x42,0x17,0x6a,0x19,0xa0,0xb3,0xf1,0x1c,0x96,0x9c,0x11,0x09,0x8b,0xc1,0x9e,0xe9,0x7f,0x18,0x8e,0xca,0xea,0x24,0x1b,0xce,0x12,0x57,0x1d,0x34,0xbe,0x60,0x60,0x2c,0xd8,0xa0,0x61,0x73,0xd6,0xf8,0xaf,0x15,0x26,0x84,0xd7,0xec,0xc0,0xbe,0x7e,0xa1,0xa8,0xba +.byte 0x2b,0xcc,0x20,0x67,0x6e,0xea,0x48,0x79,0x23,0xea,0x14,0x36,0x85,0x0a,0x56,0x3a,0xcd,0x5b,0x51,0xa4,0xf5,0x92,0x49,0xc2,0x55,0x62,0xed,0x88,0xde,0xd0,0x0c,0x01,0x36,0xb9,0x2e,0x94,0x80,0x75,0x8a,0x21,0x0a,0x07,0x45,0x68,0xd8,0x9d,0x49,0x7b,0xa7,0xb2,0x84,0xfa,0x3c,0xc4,0xd5,0x59,0xf9,0xc3,0xff,0xcf,0xe4,0x5f,0xea,0xbb +.byte 0x0f,0xae,0x7d,0x96,0xd3,0xe9,0x38,0xd1,0xb1,0x02,0xf6,0x4b,0x95,0x43,0x1c,0x69,0xa6,0x99,0xf5,0xdb,0x46,0x62,0xea,0x69,0x5a,0x08,0x2d,0x01,0x11,0xed,0x70,0x03,0x60,0x54,0xba,0x32,0x2c,0x0e,0x44,0x1f,0x8d,0xee,0x2e,0x39,0xab,0xc0,0xd4,0x88,0x11,0xef,0x07,0x3a,0x47,0xb9,0x6e,0x0c,0x22,0x9a,0xf3,0x89,0x01,0xfb,0xb8,0x2d +.byte 0x52,0xa0,0x42,0x4c,0xb3,0x9e,0xf5,0x4b,0x0c,0x78,0x0a,0x3b,0x29,0xae,0x4a,0xc0,0xb2,0xa3,0xc0,0x0d,0x38,0x07,0x49,0x9c,0xda,0x7c,0x48,0x81,0xba,0x53,0x0d,0x0d,0x78,0x8c,0xac,0x9b,0x3d,0x1f,0xaa,0xc1,0x32,0x54,0xca,0x54,0xe1,0xef,0x46,0x82,0x61,0xd0,0x88,0x04,0x53,0xb0,0x34,0xc2,0x23,0x9a,0x90,0xe3,0x73,0x9c,0x0d,0x46 +.byte 0x61,0xe5,0xc0,0x42,0x87,0x4a,0x3b,0x3a,0xf9,0xab,0xbe,0x4c,0xba,0x2f,0x88,0x03,0x6b,0x52,0x25,0x8c,0x9b,0xc0,0x13,0xb6,0x80,0x09,0x85,0x97,0x64,0x6d,0x65,0xcd,0x18,0x42,0x00,0xdf,0x76,0x4d,0x67,0xbf,0x04,0x7a,0x5f,0x7e,0x3a,0x5c,0x6f,0x1d,0x12,0x5b,0xbe,0xd2,0xc8,0xe5,0x09,0x45,0x4d,0xae,0xed,0xd8,0x77,0xc5,0x6f,0xb6 +.byte 0x43,0x09,0xe2,0xee,0xc9,0x5a,0x76,0xc5,0xeb,0xdd,0x96,0x23,0xb9,0xe5,0xfc,0xf2,0x3c,0xe1,0x67,0x5f,0x1b,0x10,0x39,0x47,0x67,0x8b,0x48,0x32,0xd0,0xbc,0xa0,0xa8,0x3e,0xc3,0x30,0x21,0x18,0x54,0x49,0xfe,0x8a,0x14,0x7a,0xe5,0x6e,0xbe,0x70,0xec,0xf6,0x97,0xa0,0xa4,0xf4,0xdd,0xaf,0xf2,0xde,0x50,0x1a,0x68,0xb9,0x1a,0x4b,0x37 +.byte 0xf8,0x29,0x16,0x4f,0x8c,0xa5,0x9e,0xd2,0x72,0x7f,0xf6,0x6b,0x7d,0xac,0xe4,0x17,0x93,0x39,0x8f,0xd9,0xdf,0x50,0x1f,0xce,0xf5,0x58,0xdd,0xcd,0xc2,0xb9,0x64,0xfc,0xad,0x8a,0x3c,0x2e,0x52,0x58,0x91,0x3b,0x78,0xb4,0xfd,0x4a,0x3b,0x13,0x5d,0x20,0xd5,0xdf,0xe7,0x52,0x3d,0x4c,0x2f,0x02,0x30,0xfc,0x24,0x17,0x99,0x6e,0x4b,0xfe +.byte 0x1d,0xf0,0xe6,0x86,0x32,0x37,0xb5,0xd5,0x09,0xa3,0xa5,0x3b,0xc1,0x88,0x9f,0x01,0x57,0x12,0x03,0x1d,0x60,0xd8,0x57,0xba,0xc6,0xfc,0xda,0xab,0x02,0xbe,0xab,0x89,0xf9,0x08,0x63,0xbd,0x42,0x11,0xf7,0xbf,0xd3,0x45,0x2b,0xa5,0x34,0x91,0x18,0xb9,0xb3,0x79,0xb4,0x15,0xa1,0x01,0x1a,0xf9,0x74,0x91,0x08,0x94,0xb2,0xf3,0xb2,0xca +.byte 0x0a,0x3a,0x4f,0x42,0x8a,0x16,0xf7,0x9e,0xbf,0x27,0x72,0x7b,0xff,0xd3,0xb9,0x4e,0xf5,0x8e,0x68,0xb5,0x91,0x23,0xef,0xeb,0x5d,0x7d,0xd8,0xc9,0xda,0x07,0x33,0xc9,0x1c,0x4a,0x7a,0xf2,0x72,0x64,0xb3,0x35,0x2e,0x54,0xec,0xc4,0xd9,0xee,0xea,0xda,0xfe,0x8b,0x1c,0x21,0x93,0x52,0x95,0x7c,0x2d,0xfe,0x56,0x05,0xdd,0x57,0x37,0xf2 +.byte 0x54,0x1c,0xe2,0x6c,0xc0,0xaa,0x71,0x67,0xdd,0x73,0x43,0x17,0x3e,0x76,0xdb,0x60,0xb4,0x66,0x62,0xc7,0x74,0x08,0x91,0x1f,0xd5,0x4c,0xa9,0xd0,0x34,0x33,0xea,0xb0,0x2c,0x0a,0x88,0xda,0xf7,0xca,0x91,0xf6,0x5f,0x9e,0x72,0xf6,0x18,0xf9,0x19,0x9d,0x84,0xf8,0x4c,0xe1,0xeb,0x45,0x29,0xaa,0xf2,0xa6,0xfd,0x64,0xf9,0x0b,0xfe,0x09 +.byte 0x1c,0xc2,0xde,0x19,0xdd,0x0f,0x02,0x16,0x65,0x70,0x33,0xd4,0x32,0x67,0x7b,0xc4,0xbb,0x11,0x60,0x4f,0xc3,0x4d,0x29,0x23,0x7e,0x84,0x58,0x51,0x43,0x7e,0x25,0x4f,0x3d,0xd4,0xe0,0x20,0x79,0xfd,0xce,0x59,0x49,0xf8,0xd1,0x53,0xca,0x2d,0x66,0xec,0xe5,0x7f,0xc8,0x14,0x06,0xc1,0x96,0x40,0xf2,0x61,0xa7,0x1b,0xf9,0x5e,0x97,0xfe +.byte 0x62,0x57,0x05,0xcc,0x6f,0x26,0x4b,0xa6,0x40,0x33,0x72,0x20,0xd3,0x1e,0x2b,0xb2,0x60,0xe7,0x56,0xda,0x87,0xd3,0xb4,0x5a,0x73,0x04,0xc9,0xc2,0x68,0xe3,0x18,0x74,0xd9,0x46,0x74,0x31,0xf4,0xf4,0xab,0xc4,0x0a,0xbc,0x66,0x4e,0x23,0x5f,0x92,0x7c,0x0a,0x81,0xdd,0xcc,0x79,0xee,0xb3,0x3d,0xc0,0x91,0x81,0xd0,0x79,0x39,0xd2,0x69 +.byte 0x5d,0xdc,0xc1,0x5c,0x61,0xb9,0x5e,0x87,0x32,0x73,0x70,0xd0,0xa8,0x7d,0xb5,0xd0,0xfc,0xf4,0xb6,0x55,0x9f,0x1f,0x8a,0xec,0xf4,0xb0,0x47,0xeb,0x3b,0x68,0x80,0x0b,0x79,0xd0,0x71,0x99,0xb1,0xd0,0xed,0x1f,0x9f,0x6c,0x2d,0x9d,0xae,0x1c,0x62,0x3b,0xec,0x3e,0x2f,0xb4,0x6f,0xbb,0x2e,0x1e,0xa9,0x7c,0xe8,0x5d,0x14,0x7d,0x0d,0x17 +.byte 0x6d,0x9c,0x54,0xce,0x64,0x93,0x8e,0x3b,0xa4,0xa9,0xfb,0xd9,0x44,0x06,0xbb,0xb8,0x7f,0xdf,0xd3,0xc2,0xa2,0xcf,0x5a,0xa2,0xa7,0xbb,0xb5,0x08,0xe2,0x67,0xdf,0x0e,0x4e,0xc6,0xcf,0x0a,0x79,0x1e,0xa5,0x60,0x1a,0x81,0xb1,0x8e,0x1b,0x27,0x7f,0x8d,0x28,0x50,0xa7,0x4a,0xe4,0x4b,0x61,0x6b,0xa9,0xfa,0xaf,0x82,0x83,0xfb,0x1f,0x2e +.byte 0xfa,0xce,0x18,0x0e,0x32,0x5f,0x5a,0xcf,0xac,0xaf,0x22,0x30,0x16,0xd7,0x97,0x99,0x0d,0xb8,0x92,0xa5,0x1d,0x44,0xb2,0xa5,0xc7,0x74,0xd2,0x81,0x8d,0x5c,0x38,0xda,0x9f,0x76,0xcb,0x47,0x6c,0xb7,0x08,0xd9,0xc1,0x52,0xd0,0x64,0x0a,0xf9,0xdd,0x3e,0xe8,0x99,0x15,0x4d,0xcb,0x7b,0x25,0x53,0x8c,0x13,0xb1,0xbf,0xb7,0xca,0x2d,0xce +.byte 0x71,0x48,0xee,0x5b,0x3a,0x01,0x5b,0xfd,0x22,0xfa,0x6f,0x17,0xcb,0x52,0xcc,0x0a,0x2b,0xbb,0x6d,0xce,0x2d,0x00,0xf5,0x9e,0x0d,0x58,0xf1,0xf4,0xa4,0x9f,0x13,0xf9,0x68,0x15,0xd7,0x02,0x41,0x6c,0x19,0x6b,0x66,0x9a,0x74,0xee,0xb4,0xb3,0xc7,0xec,0x60,0x19,0xbd,0xbb,0x97,0x22,0x7c,0x4e,0xe6,0xc6,0x00,0x03,0xa5,0x36,0x52,0xec +.byte 0x21,0xcf,0xc8,0xda,0x2c,0x14,0xa9,0xd8,0x75,0xab,0xea,0x05,0x8c,0x24,0x28,0x63,0xbd,0x58,0x35,0xd7,0x95,0xcb,0x14,0x89,0x04,0x99,0x7e,0x67,0x0d,0x07,0x35,0xdb,0x17,0x7c,0x72,0x2d,0xbc,0x89,0x9b,0xb4,0x16,0x21,0x2f,0x90,0xe8,0x8f,0xeb,0xc3,0x8d,0x86,0x0d,0x92,0xf6,0x4b,0x80,0x36,0x96,0x6b,0xd8,0x95,0x7b,0xad,0xe8,0xbf +.byte 0x77,0x9e,0xf4,0x93,0xcd,0xa5,0x06,0xbc,0x38,0xf2,0x57,0x25,0x54,0xfa,0x8e,0x19,0x8e,0x25,0x8e,0x3c,0x28,0xaa,0xf2,0x02,0x30,0xd4,0x47,0x89,0x36,0xb9,0xb7,0x01,0x5f,0x0c,0xd1,0x8d,0x93,0x7e,0xf0,0xf0,0xff,0x2f,0x8f,0xb5,0x97,0xa7,0x02,0xe8,0x9b,0xf2,0x51,0xe6,0x51,0x62,0xa5,0x27,0x26,0xc6,0x7a,0x39,0x7a,0xa9,0xaf,0x1e +.byte 0x03,0xd5,0x25,0xbe,0x3b,0x19,0x46,0xc4,0xdd,0xd6,0x5e,0x6a,0x18,0xc0,0x41,0x5f,0x53,0x89,0xd3,0x16,0xfb,0x3a,0x10,0xce,0x0d,0x8c,0x04,0x4c,0xcf,0xab,0xb9,0x0d,0x6c,0x45,0x6c,0x29,0xed,0x77,0x37,0x1f,0xd8,0x10,0x8a,0xfe,0x07,0xbd,0x7e,0xd7,0xa6,0x6b,0x80,0xde,0x3e,0x2c,0xa8,0xb1,0x38,0xcc,0xab,0x10,0x69,0x8f,0x58,0x3d +.byte 0x12,0xc7,0x9c,0xc1,0x0a,0xeb,0x3d,0x5e,0xf1,0x65,0xc6,0x09,0xcb,0x4b,0x09,0x24,0xa7,0x56,0x1d,0x1d,0x4c,0xd7,0x06,0xbd,0xe2,0x72,0x70,0xae,0x7e,0xe9,0xaa,0x97,0x6d,0xec,0xcb,0x55,0x0b,0x5d,0x45,0x3a,0x25,0x3d,0x52,0x0f,0x48,0x2f,0xe4,0xd0,0x5e,0x85,0x87,0xb6,0xa7,0x70,0x2f,0x9c,0x19,0x89,0x95,0x45,0x76,0x00,0xfe,0x27 +.byte 0xff,0xf8,0x73,0x59,0xba,0x98,0x92,0x4e,0x76,0x1a,0x90,0x1d,0xbc,0x1b,0xae,0x44,0xb6,0x63,0x86,0x4c,0x3c,0x8a,0x8f,0x3e,0x03,0x95,0x50,0x30,0xd8,0x0f,0x7f,0x6f,0xb6,0xe9,0xbe,0x2e,0xc9,0x55,0xe7,0x73,0xd6,0x77,0xdc,0xbc,0x67,0x54,0x31,0x47,0x30,0x46,0xe1,0xa4,0xf8,0xf3,0x90,0x4f,0x68,0x5a,0x52,0xe2,0xe7,0xdb,0xd9,0xfd +.byte 0xf6,0x36,0x2a,0xc1,0xdb,0x35,0x82,0x69,0xff,0xf9,0xea,0x53,0xff,0xcd,0x21,0x2c,0x26,0x79,0xd6,0x8c,0x74,0xe7,0x9e,0x85,0x1a,0x04,0xf5,0xed,0x89,0x16,0xf5,0xd7,0xf1,0x89,0xf1,0xb3,0x5b,0x47,0x42,0xcb,0x92,0x2e,0x70,0xf6,0x3e,0xfc,0x20,0x87,0x70,0xec,0x30,0x16,0xcc,0x88,0x64,0x13,0x58,0xf1,0x0d,0x17,0x90,0xc4,0xdb,0x07 +.byte 0xf5,0xe3,0x34,0x31,0x10,0x9c,0xa4,0x6a,0x4a,0xe6,0x6c,0x80,0x49,0x07,0x23,0x21,0xd6,0xf1,0xcb,0x4a,0xd1,0xb5,0xb7,0x63,0x94,0x4c,0x0a,0xce,0x90,0xf2,0x63,0x31,0x4f,0x96,0x6c,0x5d,0x3e,0xaa,0x10,0x20,0xd6,0xb6,0xbe,0xfa,0x3f,0x83,0xbc,0xa8,0x08,0x38,0xec,0x38,0xe4,0xe9,0xf5,0xb3,0x8e,0x32,0x31,0xcd,0x7c,0x08,0x98,0xf6 +.byte 0x0f,0x8a,0x8f,0xc1,0xd8,0x9e,0x05,0xb6,0x74,0x11,0x94,0xef,0x4f,0x8f,0xa1,0xc6,0x8c,0xdb,0xc3,0x27,0x4e,0xa3,0x30,0x94,0xf5,0xe8,0x2a,0x18,0x0a,0x51,0x9b,0x79,0xb2,0x1f,0xc3,0xa0,0x26,0xa9,0xf5,0xc4,0x9e,0x39,0xda,0x6a,0x53,0x8f,0x8c,0x4c,0x54,0x50,0x81,0xa0,0x0a,0xd3,0x7c,0x99,0x91,0xc7,0x3e,0x56,0x7d,0x53,0x8c,0x3c +.byte 0x51,0x44,0xa5,0x22,0x9d,0xd2,0x9b,0x13,0xcf,0xb8,0x0c,0xb8,0xd4,0xaa,0xb4,0xaa,0x8d,0xab,0x7c,0x06,0xca,0xbb,0x85,0xac,0x01,0xee,0xef,0xe7,0x74,0xd5,0x0d,0x64,0x91,0x1c,0xde,0x6c,0x05,0x37,0x1e,0x23,0x05,0x7e,0x38,0xdc,0x17,0xaf,0xa7,0x95,0x85,0x1f,0xaf,0xc8,0xe1,0xc2,0xda,0xda,0xf1,0x14,0x56,0x66,0x68,0x70,0x36,0x38 +.byte 0x7b,0xb8,0x22,0x9f,0xc4,0xeb,0x5d,0x76,0x97,0xc5,0xa3,0xb9,0x06,0x86,0x4f,0x20,0xab,0x7d,0xce,0x7d,0x78,0x59,0xc5,0x1f,0x73,0x81,0xf6,0x6d,0xb4,0xcc,0x10,0xc5,0x4d,0xe3,0x81,0xaf,0xbc,0x37,0x42,0x28,0x5f,0x51,0x1e,0xaa,0xc7,0x81,0x20,0xc3,0x89,0x35,0xf1,0x74,0x3a,0xe8,0x04,0x24,0xef,0x8b,0x70,0xe1,0x74,0xdf,0x87,0xd5 +.byte 0x3c,0x32,0x32,0x7d,0x03,0xd7,0xda,0x6d,0x8b,0x25,0x8d,0x11,0xa3,0xc2,0x27,0xdc,0xa3,0xfc,0xdf,0x70,0xa4,0x41,0xad,0xda,0xce,0x12,0x45,0x14,0xa1,0x96,0x16,0xd8,0x54,0x89,0x9e,0x78,0x7f,0x23,0x12,0xd1,0x15,0x08,0x7f,0xbd,0xf0,0x9a,0xf1,0x5b,0x07,0xd5,0xbc,0xab,0xab,0x15,0xae,0xda,0xf1,0x26,0x12,0x4e,0xd6,0x6c,0x35,0xc1 +.byte 0x6e,0x27,0x4d,0xa8,0x71,0x51,0x1e,0xae,0xa8,0x35,0x26,0x06,0x18,0x03,0xd8,0xae,0x9e,0x8b,0x07,0x30,0x10,0xfb,0x47,0x05,0x02,0xcc,0x0a,0xbd,0x57,0x43,0x15,0x0a,0x7a,0xb5,0x30,0x0b,0xa6,0x3c,0xa8,0xc9,0xf5,0x68,0xe1,0xfb,0xd1,0xe0,0xe7,0x44,0x6c,0xb4,0x44,0xb6,0xd1,0x2b,0x30,0x5e,0x17,0x89,0x40,0xcc,0x10,0x8f,0x97,0x8a +.byte 0xf3,0xf4,0x52,0x55,0xc4,0x8e,0x46,0xe5,0x24,0x0b,0x2a,0x5d,0x84,0xc1,0x4e,0xa8,0x5a,0x53,0xa8,0xce,0xc6,0x3f,0xa2,0xaa,0x3a,0x8f,0x51,0xed,0x4c,0xa6,0x34,0x6a,0x8c,0x18,0x9b,0x36,0x49,0x40,0x34,0xa3,0xe4,0xd8,0x3c,0x8a,0xfc,0x41,0xc9,0x35,0xfe,0x6e,0x3e,0x29,0xbc,0x04,0x61,0xaf,0x04,0x03,0x43,0x79,0xb5,0x77,0x27,0x25 +.byte 0xbe,0x85,0xc9,0x56,0xa4,0x17,0xc4,0x27,0x3d,0x53,0x1b,0x49,0x86,0xb2,0xb6,0x52,0x62,0x12,0x5d,0xe9,0x47,0x6f,0x65,0x78,0xf8,0x95,0x63,0xbc,0x73,0x6d,0xa6,0xb9,0xcd,0x17,0x39,0x56,0xb0,0xab,0x3a,0x15,0x5f,0x9a,0x98,0xfb,0xcd,0x51,0x4a,0x35,0x21,0xaf,0x07,0x4a,0x3d,0xfd,0x39,0x11,0x42,0xed,0xfc,0x7e,0x10,0x24,0xa5,0x0c +.byte 0xb2,0x4f,0x27,0xe4,0x78,0x32,0xfe,0xfc,0x8e,0x46,0x68,0xbb,0x2e,0x85,0x87,0x0f,0x01,0xde,0x1c,0x02,0xdd,0x82,0xa0,0x9e,0x30,0x31,0x8d,0x86,0x36,0x33,0xa6,0x59,0x16,0x78,0xae,0x1f,0x1d,0x27,0x0b,0x29,0x42,0x16,0x93,0x3b,0xe6,0xfb,0x8d,0xd5,0x48,0x42,0x61,0x39,0x5b,0xf7,0xea,0xd0,0x6f,0x67,0xd9,0x03,0x72,0xed,0x54,0xe1 +.byte 0xab,0x3f,0xa0,0xdc,0x4b,0x19,0xe6,0xe3,0xfe,0x5f,0x65,0x64,0x4c,0xa9,0x5c,0x52,0x36,0xb3,0x65,0x28,0x3e,0xe5,0x07,0x50,0xed,0xec,0x2f,0xc9,0xff,0x47,0x27,0xf6,0xfe,0xb8,0x60,0x60,0x52,0xe5,0xec,0x3c,0x4f,0x69,0x9f,0xaa,0x06,0x8a,0x99,0x9f,0xac,0xfc,0x0a,0x6f,0x8a,0xa4,0x0e,0x5c,0x58,0xb4,0x09,0xba,0x93,0x95,0x94,0x12 +.byte 0x9b,0x23,0x4f,0x93,0x28,0x6d,0xd0,0x76,0xfd,0xc9,0x87,0x3b,0xf1,0x8c,0x7d,0x56,0x84,0x5a,0x04,0x08,0x30,0xf7,0xf6,0x52,0x15,0xba,0xd6,0x7a,0x39,0x8c,0x5a,0xbf,0xeb,0x02,0x6d,0x31,0x30,0x92,0xbc,0xe2,0x07,0x21,0x16,0x96,0x70,0x66,0x00,0xe0,0x04,0xc5,0xa8,0xe4,0x08,0x6d,0x08,0x69,0x35,0xe2,0xb1,0x83,0x03,0x37,0xca,0xff +.byte 0x06,0x37,0x80,0xd5,0x1a,0xc5,0x31,0xfc,0x9a,0xb0,0x8a,0x4b,0x58,0xf3,0x00,0x4e,0xa4,0xfe,0x9e,0xe0,0x60,0xc7,0x3d,0x2c,0x52,0xb5,0x39,0xf0,0xa4,0x88,0x39,0x37,0xa5,0x26,0x8a,0xa3,0xe6,0x31,0xce,0xf3,0xa1,0x54,0x73,0xe7,0x69,0x38,0xef,0xa2,0xab,0x52,0x50,0x1a,0x45,0xcc,0x29,0x9c,0xb6,0xf4,0xde,0xc2,0xfe,0x7a,0x26,0xf7 +.byte 0x7a,0x6e,0x07,0xb6,0xd8,0x3f,0x77,0x60,0x35,0xae,0x6a,0x90,0xd6,0xb8,0x37,0xed,0x73,0x59,0x54,0xd9,0x0c,0x87,0x0e,0x81,0xef,0x69,0xc7,0xd4,0x8f,0x00,0x74,0x57,0x12,0xcf,0xa1,0x76,0xe8,0x45,0xf5,0x9a,0x4f,0xe2,0x5d,0x8a,0x89,0xb1,0x8b,0xea,0x9c,0x0a,0x1e,0x00,0x61,0x3b,0x66,0xbd,0xb5,0xd6,0xff,0xa3,0xff,0x52,0xc2,0x35 +.byte 0x81,0x05,0x08,0x2b,0xf9,0x52,0xda,0x74,0xd1,0x76,0x13,0xba,0x28,0x4c,0xb1,0xb1,0x82,0x5b,0x4e,0x79,0x39,0x22,0xf9,0x96,0x91,0x07,0x4f,0xf9,0xf2,0x25,0x25,0xb1,0x3e,0xda,0x07,0x5c,0x01,0x7b,0xfa,0x3e,0x95,0x92,0x1d,0xf8,0x44,0x06,0xc1,0xed,0x64,0x74,0x14,0x84,0x25,0xee,0x75,0xaf,0xe3,0x7c,0xd3,0xbe,0x7a,0x51,0x6b,0x80 +.byte 0x20,0x43,0x20,0x10,0x5f,0xf5,0xfc,0xd5,0xe8,0x06,0x43,0xad,0x10,0x6b,0x67,0x48,0xca,0xca,0x6e,0x3e,0x1c,0xdf,0x8f,0x7a,0x65,0xc8,0x5d,0xba,0x3b,0x67,0xeb,0x1f,0xc4,0x37,0xad,0xef,0x73,0x9e,0x18,0x8e,0xc1,0x99,0xaf,0x75,0xd3,0x91,0x73,0xc3,0x3a,0xb2,0xfe,0xff,0x30,0x81,0xc4,0x4f,0x37,0x37,0x23,0x96,0x17,0xf1,0xa2,0x9b +.byte 0x55,0x6e,0xd6,0xb3,0xc4,0x98,0xa3,0x32,0xb6,0xff,0x86,0x87,0x77,0xf4,0xad,0x16,0x3e,0xf0,0x24,0x01,0xb4,0x8e,0x1e,0x0f,0x10,0xa4,0x2e,0xe4,0x79,0xe6,0x88,0xe7,0x09,0x58,0x5e,0x97,0xad,0x0d,0x72,0x05,0xbf,0x2f,0x3f,0x99,0xee,0x8a,0x84,0xc3,0x62,0x43,0x52,0x6d,0xab,0x66,0xcf,0x9f,0x4e,0xf2,0x0d,0x13,0x15,0x49,0x84,0x5e +.byte 0x6c,0x8d,0x2d,0xef,0x53,0x16,0xa0,0x63,0xbe,0x05,0xb8,0x9b,0x23,0xca,0xca,0xb8,0xdd,0xbc,0x96,0x68,0x35,0x43,0x63,0x30,0x8e,0xaf,0x53,0x98,0xe2,0x76,0xe8,0x89,0x00,0x29,0x11,0x70,0xd5,0x94,0xbd,0x78,0xff,0xf6,0x88,0x4a,0x3d,0x99,0xd9,0x7e,0xdf,0xa8,0x33,0x92,0xa2,0xc0,0x32,0x42,0x73,0x08,0xd4,0x55,0x5d,0x18,0x93,0xca +.byte 0x7e,0x33,0xe3,0x51,0xc7,0xb7,0x24,0x62,0x69,0xf4,0xab,0x36,0xe3,0x22,0x10,0x9b,0xe0,0xbd,0x48,0x65,0x30,0x9c,0xfe,0xeb,0x3f,0x7f,0x22,0x67,0xcc,0x87,0x5a,0x71,0xb0,0xd1,0x19,0x82,0x1c,0xb2,0xf1,0x73,0xd2,0xd6,0x3f,0xef,0xe3,0x2f,0x25,0xf3,0x8b,0x21,0x4e,0xbf,0x0e,0xc1,0xd2,0x8a,0xbb,0x04,0xde,0xcf,0xd1,0x77,0xba,0xaa +.byte 0xc7,0x41,0x68,0xce,0xc4,0x64,0xf9,0x3a,0x2f,0x1c,0x0b,0x22,0xf8,0x60,0x09,0x76,0x31,0x88,0x62,0x3a,0xf3,0x49,0xe6,0xda,0x4b,0xd3,0xf3,0x35,0xaa,0x56,0x4c,0x2f,0x7f,0x03,0x3e,0xf8,0xcb,0x5e,0xed,0x37,0xa1,0x29,0xe8,0x20,0xf5,0x4a,0x32,0x73,0x30,0xfd,0xd1,0xf6,0xb4,0xa1,0x30,0x87,0xcb,0x21,0x63,0xf5,0x3a,0xad,0x05,0x1a +.byte 0x34,0xf5,0x32,0xf6,0x02,0xf3,0x10,0x52,0xfd,0x86,0x37,0x1f,0x5d,0xe4,0x2e,0x31,0xcb,0xb8,0x4c,0xeb,0xdd,0xea,0x01,0x0d,0x94,0x13,0xa8,0x8f,0xf0,0x52,0x4e,0x0d,0x4f,0xd1,0x24,0xeb,0x0f,0x2b,0xb1,0xaa,0xc5,0xc8,0x52,0xb9,0xbe,0x21,0x48,0x2a,0x53,0x98,0xe4,0x00,0x72,0x64,0xdb,0x44,0x48,0x36,0x60,0xe7,0x81,0xdc,0x25,0x85 +.byte 0x4d,0xaf,0xa8,0x0d,0xfb,0x07,0x76,0x4f,0x6a,0x30,0x3c,0x7c,0x3b,0x36,0xa9,0xf8,0xae,0x81,0x03,0xe9,0x19,0xdf,0xdb,0xd9,0x7f,0x59,0xe0,0xd7,0x50,0x14,0x9f,0x67,0x3d,0xc7,0xdf,0xa8,0x44,0x86,0x29,0x81,0x65,0x44,0x9e,0x37,0x27,0xdd,0x2f,0x33,0x59,0xf7,0xaa,0x17,0x34,0x8c,0x1c,0xa7,0x8e,0x06,0x46,0xf1,0x43,0x87,0xa9,0xb7 +.byte 0x85,0xec,0x92,0x0d,0xdd,0x78,0x55,0x99,0xfb,0x1c,0x66,0x85,0x0d,0x59,0x31,0x00,0xbc,0xd9,0x9b,0xbb,0xfb,0xfc,0xb2,0x36,0x3c,0x34,0x8f,0x4a,0xb6,0x74,0x9c,0x32,0x6f,0x69,0x6c,0x3e,0x68,0x7e,0xec,0xeb,0x58,0x6a,0xf5,0xa2,0xbb,0x04,0x68,0xdb,0x8c,0xf0,0x04,0xba,0xf7,0xf7,0x50,0xd0,0x60,0xba,0x45,0x73,0x0f,0x2c,0x2f,0x97 +.byte 0x58,0xcc,0xa2,0xbe,0xfe,0x5e,0xf9,0x44,0x03,0x8b,0x99,0x56,0xb0,0x4f,0xe1,0xd0,0xa5,0x9f,0xd1,0xfc,0x95,0x44,0x4b,0x01,0x24,0xc0,0x4c,0x91,0xc1,0xb5,0x99,0xe7,0x5f,0x2f,0xcf,0x5d,0x4f,0x64,0x6e,0x54,0x51,0x0c,0x35,0x5f,0xa8,0x7b,0x27,0xa0,0x7d,0xb1,0x90,0xc2,0xdd,0x50,0xef,0x09,0x6f,0xed,0x25,0x6b,0xf5,0x6f,0xc1,0x97 +.byte 0xea,0xd5,0x49,0xf5,0x40,0x60,0xc3,0xbb,0x0d,0x82,0x15,0xa5,0xf7,0xfe,0xa1,0x20,0x13,0x9e,0xbb,0x43,0x58,0xba,0xd2,0xe8,0x89,0xaa,0xfc,0xe0,0x47,0x6b,0xac,0x91,0x8b,0xeb,0x4f,0xf5,0xda,0xf5,0xc8,0x11,0x64,0x7c,0x8d,0x43,0x92,0xf2,0x84,0xeb,0xfb,0x5c,0x1b,0x6b,0x68,0x8e,0x3c,0x66,0xb2,0xd1,0x8e,0x67,0x44,0xbf,0x69,0x3b +.byte 0xb9,0x41,0x78,0x8d,0xc8,0x7b,0x81,0x61,0x70,0x6e,0xe2,0xfc,0xd2,0x96,0x31,0x31,0x2f,0x27,0x90,0xf2,0xc4,0xed,0xbd,0xb5,0x0e,0x91,0x7d,0xd0,0xec,0x3c,0xe9,0xcf,0xf2,0x07,0xac,0x54,0x44,0x9a,0x24,0x41,0xcb,0x2a,0x86,0x30,0x18,0xba,0x65,0x59,0x41,0x00,0x59,0xbf,0x3d,0x01,0x8a,0x51,0xe5,0xd2,0x90,0x8c,0x7d,0xd7,0xad,0x71 +.byte 0xdc,0x45,0x62,0x95,0xf9,0x9f,0xe8,0x55,0x6d,0x48,0x22,0x32,0xcb,0x9a,0x55,0x65,0xe5,0xdf,0xee,0x22,0x99,0x91,0xd7,0xed,0x33,0x04,0x72,0xc7,0xc5,0xb2,0x56,0x5e,0x8f,0x38,0x4b,0xd0,0x61,0x4b,0x4b,0x04,0x4c,0x4c,0x2b,0x23,0x00,0xd4,0x5c,0xdd,0x84,0x8d,0x73,0xf4,0xf7,0xef,0xd5,0xdb,0x2b,0xec,0x54,0x86,0x37,0x01,0x64,0x56 +.byte 0xef,0x73,0x9f,0xb4,0xb6,0xd2,0xf4,0x33,0x93,0xbd,0xd7,0xd9,0x6e,0x8f,0x60,0x85,0xbc,0xa6,0x16,0x3f,0x3f,0xc3,0xd7,0xfc,0xb6,0x82,0xf0,0xe5,0x1e,0x2c,0x51,0x48,0x27,0x50,0x3e,0xdb,0xe6,0x86,0x3b,0xa1,0xfa,0x09,0x39,0x04,0x6f,0xb1,0x85,0xbd,0xda,0x4d,0x2f,0xd1,0x40,0x6f,0x2e,0x2b,0xf2,0x9a,0x4d,0x8e,0xb2,0xc5,0x6e,0x21 +.byte 0xf9,0xdd,0xc9,0x2e,0x81,0x18,0x7b,0x88,0xb9,0x86,0x36,0xe5,0xb2,0xdd,0x19,0xb4,0x7f,0x5d,0xc0,0x20,0x34,0xdc,0x63,0x7d,0x8c,0x80,0x0f,0xe6,0x85,0x14,0xbb,0x87,0x6c,0x3e,0x39,0x53,0x60,0x3d,0xc5,0x46,0x11,0xa3,0x96,0x60,0x6f,0xe9,0xfe,0x59,0xcc,0xed,0x4d,0xdb,0xa3,0xa1,0xf1,0x71,0x0b,0xb0,0x1f,0x89,0x4c,0x32,0x59,0xa5 +.byte 0x7d,0xf7,0x3e,0x5b,0xca,0xa4,0xe1,0xc3,0x50,0xac,0xdf,0x00,0xad,0x45,0x59,0x9e,0x23,0x5f,0x52,0xbd,0x36,0x78,0x55,0xcf,0x90,0x91,0x41,0x14,0xdb,0x76,0x3a,0x43,0x39,0x89,0xe1,0x93,0xc8,0x66,0x91,0xc7,0x42,0x06,0x6f,0xbb,0x35,0x1e,0x07,0x52,0x5a,0xe4,0x41,0x9f,0x65,0xe0,0xdc,0x49,0x8c,0xd3,0x5f,0x16,0x21,0xc9,0xb8,0x8a +.byte 0xc2,0x56,0x91,0xcb,0x18,0x6b,0x38,0x7b,0x3a,0xeb,0x91,0x3c,0x0d,0x6a,0x1f,0xd6,0xc6,0xd7,0x56,0x8d,0xd3,0x76,0x1c,0x9d,0xed,0x3d,0xb6,0x92,0x71,0x6e,0x73,0xc6,0xb8,0xa2,0x1c,0x25,0xb9,0x3c,0xd4,0x41,0xf7,0x8f,0x39,0x60,0xe6,0x27,0xf2,0xc6,0x5f,0x56,0x08,0x7c,0xd3,0x16,0x9d,0x06,0xc0,0xca,0x3d,0xc6,0x61,0xb0,0x21,0x51 +.byte 0x6d,0xca,0x82,0x59,0xe6,0xbb,0x99,0xa2,0x4f,0xfc,0x71,0x66,0x2b,0x4e,0x40,0x62,0x97,0x34,0x73,0x4a,0xe5,0xf0,0x4f,0x4c,0x36,0x4c,0xdb,0x03,0xa9,0x87,0x29,0x21,0x5d,0x91,0x5b,0x89,0xb8,0x3d,0x65,0xc7,0x58,0x0a,0x81,0xb5,0x3e,0x22,0xa1,0x57,0x95,0xbe,0x60,0xf5,0xeb,0xb3,0x49,0xdf,0xd9,0xa2,0x31,0x36,0x5f,0xb2,0xa6,0xf6 +.byte 0x66,0x88,0x88,0x8e,0xa3,0x2c,0xac,0x5e,0xa1,0x33,0x16,0x64,0x08,0x47,0xc8,0xbc,0xc2,0xe9,0xdb,0x73,0x57,0x50,0xd4,0x24,0x01,0x26,0x26,0x04,0x4f,0x8a,0xc0,0x7a,0x97,0x14,0xf2,0xd0,0xbe,0x03,0xea,0x8a,0x25,0xcb,0x98,0xe7,0xbd,0x67,0xff,0x32,0xfd,0x8a,0x7d,0x11,0xe1,0xb2,0x91,0xb5,0xa0,0xb6,0x3c,0x2c,0xb3,0x6e,0x35,0x61 +.byte 0x86,0xbc,0x37,0x15,0xf8,0x3b,0x0d,0x84,0x83,0x69,0x76,0xb0,0xaa,0x8f,0x4f,0xca,0xba,0x54,0xfe,0x42,0xc8,0xba,0x9a,0xd5,0x53,0x69,0x67,0x29,0x23,0x3a,0x6a,0x75,0x97,0xb4,0x29,0x2e,0x62,0xe3,0x95,0x82,0xb3,0xa0,0xa1,0xb7,0xdf,0xc2,0x66,0x4d,0xdd,0x0d,0xda,0xda,0xc2,0x42,0xe0,0x69,0xb1,0xab,0x3c,0x44,0x39,0x11,0x3b,0x0a +.byte 0xd6,0x96,0x2c,0x36,0xb0,0xa0,0xed,0x3d,0x0c,0x63,0x8b,0x90,0xe4,0xb9,0x5f,0x4c,0x27,0x70,0x87,0xb3,0x54,0xe2,0x36,0x74,0x6f,0x3e,0x22,0xb1,0x3b,0x1b,0xba,0xdb,0x1c,0xbd,0x9c,0x6d,0x84,0xbd,0x33,0xfb,0xc0,0x98,0x4c,0xcf,0x7a,0xe8,0x41,0xdb,0x32,0x1f,0xb7,0x64,0x19,0xdb,0x87,0xe7,0xf9,0x52,0x40,0x8c,0xc6,0x89,0x98,0x15 +.byte 0x69,0xde,0xfa,0x29,0x9a,0x0f,0xaf,0xb0,0xad,0x71,0x35,0xab,0xab,0x34,0xe0,0xf4,0x03,0x24,0x6f,0x94,0x38,0x87,0xba,0x68,0xd5,0x1f,0x58,0x88,0x3e,0x12,0x20,0x57,0x43,0xde,0xd0,0xbc,0xaa,0x31,0x8f,0xbc,0x88,0xa0,0xdf,0x5a,0xcc,0xd1,0xba,0x9c,0x18,0x80,0x4e,0x8f,0x68,0x91,0x9c,0x57,0x3b,0x5a,0x62,0xc7,0x29,0x3e,0x49,0xc7 +.byte 0x23,0x26,0xfd,0x9e,0xd0,0xb0,0x4f,0xd4,0xb2,0xa9,0xa8,0x4c,0x66,0x54,0x52,0x75,0x6b,0xbf,0x63,0x76,0x49,0x3b,0xa3,0xb2,0x8f,0x87,0x9d,0xb4,0x8f,0x07,0x3c,0x8e,0xae,0xe1,0x0e,0x9a,0x86,0x90,0x58,0x73,0x8a,0xb3,0xa9,0xab,0xe6,0x27,0xd7,0x70,0x94,0x77,0x12,0xdc,0x71,0xdf,0xcf,0xba,0xdd,0x85,0xfe,0x28,0xaa,0xcd,0xcc,0xe8 +.byte 0x5f,0xd4,0xd8,0x45,0x6f,0x20,0xa8,0x5e,0x40,0x91,0x3b,0xd7,0x59,0x92,0xb8,0x7d,0x2b,0x8b,0x38,0xbd,0xfe,0x7b,0xae,0x5c,0xee,0x47,0x9b,0x20,0xb7,0xf3,0xad,0x75,0xa9,0xe1,0x96,0xc8,0xb2,0x30,0xfe,0x0c,0x36,0xa2,0x02,0xf4,0x3b,0x30,0xfd,0x91,0xfa,0x5f,0xd6,0x18,0x1a,0xcb,0xd2,0x26,0xbb,0x67,0xbe,0x1c,0x99,0xa5,0x4f,0x57 +.byte 0x40,0xb5,0xed,0xd6,0x84,0xfd,0x6b,0x00,0xc8,0xe7,0x18,0x1a,0x9f,0xf7,0x3b,0xd1,0xcc,0x12,0xeb,0x9d,0x61,0xf0,0x8d,0x64,0x08,0x93,0x61,0xc4,0x3e,0xdb,0xda,0x15,0xb1,0xd6,0x2c,0x84,0x2a,0xd8,0xd2,0xa1,0x66,0x4e,0xc9,0xd6,0xbf,0x7e,0xb6,0x22,0xfa,0x35,0x5e,0xdc,0xc0,0x31,0x02,0xb8,0x17,0x46,0x9e,0x67,0xd3,0x6a,0x8f,0x33 +.byte 0x85,0xc3,0xfe,0x36,0xbc,0x6f,0x18,0x8a,0xef,0x47,0xf1,0xf2,0x6e,0x15,0x6c,0xb1,0x4a,0x4b,0x13,0x84,0xd5,0x1b,0xf9,0xa2,0x69,0xcd,0xc7,0x49,0xce,0x36,0x8e,0xe5,0xd5,0x35,0x05,0x7c,0x7f,0xc6,0x15,0x29,0x2e,0x64,0xa6,0x91,0x9d,0xe5,0x9d,0x90,0xe7,0x26,0xec,0x75,0x19,0x58,0x57,0xf2,0x19,0x7b,0x24,0x7d,0x19,0xd3,0x72,0x69 +.byte 0xaa,0xa2,0x8c,0xe3,0x3d,0x38,0xb9,0xf0,0x5b,0xe9,0x3b,0xaa,0x96,0xef,0x2c,0xfc,0xf5,0x13,0xa6,0xa9,0x57,0x8c,0xa9,0x3a,0xc1,0xf0,0x2d,0x57,0x06,0x08,0xe3,0x9c,0xfe,0x82,0x8a,0x6a,0x79,0x5b,0xef,0x2b,0x81,0x83,0x01,0x53,0xac,0xdc,0x79,0x93,0x9b,0x23,0xd4,0xae,0x17,0x6f,0x62,0xaa,0x33,0x41,0xa6,0x31,0x1c,0x7b,0x46,0x2b +.byte 0x17,0xd3,0x6f,0x66,0x73,0x54,0xee,0xa1,0x08,0xee,0x8f,0x0f,0x0e,0x53,0xa7,0x49,0x17,0xdb,0x35,0xaf,0x4e,0x94,0x87,0x8e,0xff,0xf4,0x2b,0x29,0x01,0x45,0xa3,0x0a,0xd9,0x13,0x38,0x09,0x46,0x2c,0x56,0x97,0xd7,0xee,0x24,0x43,0xd1,0x20,0xed,0x38,0xde,0x52,0x13,0x38,0x06,0xd3,0x97,0xc7,0x48,0x8b,0x72,0x0a,0xc5,0xca,0x75,0x2c +.byte 0x04,0x9e,0xee,0x14,0xe7,0xda,0x59,0xc2,0x54,0x7a,0x72,0x55,0x35,0x00,0x93,0xb7,0xb9,0x81,0x01,0x46,0xae,0x43,0x81,0x34,0xd7,0xb4,0x7a,0xfc,0xfc,0x98,0x2b,0x29,0xe5,0x5e,0x9d,0x8e,0xef,0xd4,0x44,0x9d,0x9a,0xbe,0xdb,0x83,0x33,0x18,0x9e,0xbd,0x0f,0x34,0x4d,0xd9,0x34,0xe0,0x2c,0x1f,0x10,0xaa,0x06,0x5e,0x54,0x51,0x72,0xec +.byte 0xbf,0x6b,0x3e,0xb9,0xdd,0x37,0xc3,0xe1,0xbe,0xbe,0x1d,0x86,0xde,0x12,0xca,0x82,0xc5,0xe5,0x47,0xf8,0xbe,0xef,0xb6,0x79,0xd5,0x3c,0x69,0x0a,0x35,0x3e,0xd3,0xf8,0xaf,0x5b,0x8e,0x69,0xff,0xb2,0xf7,0x91,0xc2,0x70,0x22,0x97,0x1c,0x5c,0x56,0x25,0x5a,0xcf,0x31,0x7a,0x37,0xce,0xc7,0xf2,0x98,0xdc,0xb5,0x58,0x71,0x5a,0x60,0xe2 +.byte 0xfe,0x4f,0xf3,0xe2,0x2a,0xca,0x22,0x3e,0x07,0xc2,0xea,0x23,0xc8,0x04,0x97,0x7f,0xca,0xf6,0xf8,0x12,0x06,0x88,0x81,0xee,0xb7,0xdd,0x56,0x9e,0x0f,0x36,0xd3,0x09,0xa8,0x74,0x4d,0x8b,0x8f,0x31,0x64,0xbe,0x9d,0x7b,0x68,0x50,0xc8,0x64,0x40,0x3b,0x0c,0x04,0xb9,0x4b,0x9e,0xff,0x7e,0x5d,0xd8,0x57,0xa0,0xe5,0x6d,0xc2,0x37,0xe7 +.byte 0xd1,0xd9,0x96,0xaa,0x16,0x3e,0xa2,0x9d,0x32,0xe7,0x1e,0x11,0x6e,0x41,0xe2,0xa0,0xe1,0x6f,0x32,0x6d,0xd5,0x38,0x0c,0x27,0x27,0xa9,0xc2,0x04,0xc6,0xe7,0x8d,0x7d,0x7b,0x30,0xbe,0x54,0x6b,0x82,0x37,0x39,0x53,0x54,0xc9,0xac,0xcb,0xd1,0x31,0x79,0xd4,0x7b,0x85,0x07,0xf4,0xf4,0x5d,0x33,0xc7,0x91,0x4e,0xe5,0x13,0x78,0x09,0x42 +.byte 0x29,0x48,0xaf,0x82,0xb1,0x88,0xd4,0xd3,0x57,0x50,0x38,0xa7,0x66,0x41,0x63,0x34,0x2a,0x3c,0x5e,0x8f,0xc4,0xc1,0x00,0xa1,0x22,0xbe,0x5e,0x64,0xb0,0x60,0x9b,0x42,0x9d,0xc6,0x59,0x5c,0xcc,0x29,0x6f,0x64,0x5b,0x5c,0x0f,0xb2,0xae,0x21,0x0c,0x9a,0x6a,0x19,0xb9,0xa6,0x32,0xf8,0xdc,0x82,0xea,0xba,0x27,0xcf,0x42,0xd3,0xde,0x78 +.byte 0xfe,0x9c,0xa5,0x36,0xb6,0x24,0xb6,0x0d,0x5b,0x67,0x6c,0xf5,0x16,0xbf,0x67,0x54,0x4f,0xe4,0x83,0x29,0x75,0x42,0x9a,0xbb,0xd5,0xe7,0x01,0x1f,0xbd,0x80,0x1a,0x7a,0xb6,0xe1,0x2b,0x5d,0x71,0x93,0x00,0xad,0xf6,0x11,0x8d,0x67,0xdc,0x9c,0x8f,0xf0,0x09,0x3f,0xf9,0xa4,0xd6,0xe0,0xdd,0x95,0xea,0xfb,0x71,0x76,0x21,0x31,0x6d,0x48 +.byte 0x0a,0x27,0xa8,0xa6,0x3a,0x7f,0x42,0x6b,0x7e,0xd7,0x6e,0xd5,0x42,0x97,0xad,0x55,0xae,0x26,0x3c,0xde,0x3f,0xaf,0xfd,0x1d,0x6d,0xd3,0xeb,0x84,0xad,0x6d,0xd1,0x4a,0x85,0x1a,0xf7,0x99,0xa4,0xd0,0x48,0xfb,0xf6,0xfe,0xc6,0xea,0x61,0x77,0xe2,0x56,0x87,0xc1,0x36,0x44,0xb4,0xe3,0xd7,0xd9,0x6d,0x3e,0x1b,0xf4,0x72,0x3e,0xfe,0xa5 +.byte 0x47,0xf8,0x3f,0x1a,0x6e,0x43,0xf5,0x67,0xfe,0x90,0x96,0x9b,0x52,0xde,0xab,0xfb,0x45,0x7d,0x93,0xea,0xc3,0x40,0xe1,0x5f,0xcd,0xad,0x3b,0xe9,0x4e,0x36,0xc5,0x38,0xf4,0x66,0xde,0x4b,0xc8,0x2a,0xc3,0xa2,0x3a,0x2a,0xf1,0xd1,0xe8,0x01,0x07,0x37,0xca,0x42,0xbf,0x4f,0xd8,0xc5,0x50,0x93,0x1a,0x01,0x1d,0x51,0x41,0x6e,0xbf,0x68 +.byte 0x93,0x2e,0xdc,0x41,0x23,0xf3,0x13,0xe7,0x09,0xfa,0x39,0x6d,0xee,0x41,0x49,0xbb,0x78,0x04,0xcf,0xc9,0xbb,0x11,0xaa,0x57,0xb5,0x3e,0x4c,0x3a,0x77,0xb7,0x0b,0x38,0x34,0x48,0xd0,0x99,0x20,0x55,0xcd,0x43,0x2f,0x68,0x66,0xb0,0xe6,0x75,0x41,0xe4,0xae,0xfd,0x96,0xe8,0x01,0x4c,0x0b,0x5c,0xbc,0x4f,0x45,0x70,0x08,0x9e,0xf7,0x68 +.byte 0x9e,0xbb,0xe5,0x39,0x20,0x3f,0xbe,0xd3,0xe3,0x95,0xba,0x98,0xd5,0x12,0x2e,0x87,0xd4,0xf4,0x12,0xa2,0xcb,0xd4,0x51,0x53,0x93,0x67,0x06,0xf1,0x21,0x0e,0x92,0x8f,0x9f,0x9e,0x6c,0x16,0xa4,0x2c,0x6d,0xb0,0xd0,0xe1,0x87,0x2f,0x09,0x2c,0x8f,0x4b,0x89,0x1f,0xab,0x66,0xf1,0xcd,0x6e,0x67,0xaf,0x07,0x99,0x18,0x1b,0xda,0xc8,0x65 +.byte 0x81,0xa3,0x37,0x8a,0xad,0xe4,0x1d,0xfd,0x82,0xa0,0xf1,0xe1,0x1e,0x8d,0x0b,0xf7,0x07,0x7c,0xb3,0x10,0xc8,0x5a,0xa9,0xcc,0xc8,0xd0,0x2e,0x5a,0x71,0x45,0x4c,0x30,0xf0,0x10,0xe0,0xf6,0x0d,0x0d,0x11,0xb4,0x83,0x40,0x75,0xee,0xb9,0x24,0x04,0xe3,0xba,0xb3,0xd3,0x00,0x57,0x71,0x98,0xf0,0x4b,0x35,0x8d,0xd8,0x71,0xa0,0xcc,0xaf +.byte 0x46,0x54,0x67,0x65,0x70,0x0b,0x9c,0x61,0xf8,0xd4,0xb2,0x35,0xfd,0xcf,0x2b,0x3a,0x48,0x5b,0x03,0x86,0xd8,0x13,0x48,0x8a,0x55,0xa5,0x4d,0xef,0x42,0x41,0xbb,0x6a,0x8c,0x92,0x46,0x87,0x82,0x09,0x43,0xf3,0x94,0x1d,0x23,0x36,0xfe,0x6f,0xb8,0x9f,0xfa,0xf9,0x92,0x27,0x3c,0xcc,0x47,0x89,0x5c,0x7f,0x81,0x42,0x74,0x12,0x14,0xff +.byte 0x98,0x63,0xc0,0xfb,0x70,0xff,0xc7,0x65,0x5a,0xc3,0xb9,0x74,0x1b,0x71,0x3c,0x2c,0x47,0x79,0x07,0xb9,0x3c,0xc2,0x5f,0x48,0x4f,0xbd,0xaf,0x03,0x05,0x57,0xa9,0x84,0x33,0xc8,0x0d,0xd5,0xac,0x42,0xdb,0x4b,0x57,0x46,0x41,0xf0,0xe4,0x08,0x0d,0xf3,0x43,0x41,0xa5,0x14,0xb7,0xcd,0x64,0x23,0xc9,0xfe,0xff,0x12,0x97,0xc6,0x2f,0x8d +.byte 0x9e,0xf2,0x1d,0x33,0x26,0x3c,0x57,0x17,0xe1,0x7b,0x92,0x3f,0xb6,0xf4,0xd9,0xf8,0xe0,0x37,0xe6,0x18,0x7d,0xa7,0x8a,0x1e,0xe8,0xd8,0x56,0xa6,0x63,0xdf,0xa3,0x99,0x16,0x74,0x48,0x01,0xaf,0x95,0x55,0x40,0xce,0xa8,0x0d,0x30,0x01,0x09,0x40,0xc9,0x9d,0x3d,0xdf,0x4e,0x00,0xe0,0x2a,0xe6,0xdb,0xa2,0x79,0x42,0x57,0xd0,0x3d,0x81 +.byte 0x7f,0x67,0x3a,0xa9,0x63,0xb3,0xd4,0x60,0xa7,0xab,0x54,0x46,0xb0,0xbe,0xb0,0x83,0x72,0xec,0x47,0x0f,0xc7,0xd1,0xed,0x16,0x96,0xbc,0xa5,0x62,0x38,0xdb,0x88,0x2b,0x25,0x26,0x27,0x56,0x7f,0x46,0x39,0xe8,0x4e,0xc0,0x6c,0x62,0xf8,0x80,0x68,0x56,0x8a,0x93,0x51,0x95,0x77,0xe3,0x11,0x7b,0xaf,0xc4,0xcf,0x34,0x5a,0xd5,0x26,0xfc +.byte 0xa2,0x18,0xb0,0xc0,0xa5,0x8b,0x25,0x70,0x40,0x70,0x29,0xc3,0xda,0x80,0x3d,0xe2,0x59,0x49,0x7f,0xdd,0x62,0x6e,0x5a,0xe6,0x27,0x73,0xce,0xb6,0x32,0x37,0x5f,0x73,0x12,0x2b,0x34,0x84,0xff,0x85,0xe3,0xb5,0x93,0x41,0x47,0xc5,0xf5,0x0e,0x21,0xfb,0x24,0x0f,0xdf,0x7b,0xb4,0x29,0x7f,0x67,0x2a,0x38,0x79,0xf0,0x54,0x8a,0x94,0x68 +.byte 0xe2,0x0b,0xb0,0xd4,0xb2,0xa4,0xe4,0xfb,0x3b,0xe6,0xe7,0x59,0x41,0xbd,0xed,0x62,0xce,0x50,0x1a,0x47,0x92,0x92,0x8d,0x80,0xa6,0x05,0x7a,0xb0,0xce,0x48,0x9c,0xb0,0x64,0xea,0xe0,0xa5,0x77,0xff,0xc1,0x82,0x99,0x7b,0xfb,0x74,0x53,0xfa,0x41,0x9a,0x2c,0xb4,0xbb,0xd2,0x26,0xa1,0x80,0x68,0x17,0xaa,0x8f,0x14,0x52,0xb6,0x5d,0xe0 +.byte 0x69,0x5b,0x31,0xc5,0xf5,0x32,0x0d,0xff,0xa4,0x7b,0x28,0x38,0x9b,0x61,0xfc,0xd0,0x92,0xb8,0x6e,0x23,0x8a,0xf3,0xc7,0x85,0x11,0xb8,0xd0,0x19,0xaf,0xca,0xa7,0xb4,0xcc,0xeb,0x5d,0xf6,0xa1,0x1c,0x56,0xdf,0x78,0x7a,0xe3,0x6a,0xa4,0x07,0x71,0xce,0xf1,0xb2,0xd5,0x38,0x3c,0xfa,0xf7,0x7a,0xbf,0x4b,0x43,0xa6,0xb3,0x4d,0xff,0x82 +.byte 0x96,0x46,0xb5,0xec,0xda,0xb4,0x5e,0x35,0x78,0xeb,0x4a,0x7e,0xc5,0x7b,0x05,0xd4,0xdd,0xf7,0xb7,0xf3,0xf0,0x04,0x26,0x7e,0x5e,0xc1,0x23,0xca,0x7f,0x14,0x27,0xac,0xda,0xe7,0xdb,0x31,0x05,0x9d,0xd4,0xda,0x20,0xc7,0x6d,0x9a,0x47,0x14,0x38,0xbd,0x7c,0xfe,0xbe,0x8d,0x42,0x7c,0xba,0x36,0xe2,0x2c,0x26,0xd2,0x46,0xa5,0x6b,0xbd +.byte 0x6a,0x75,0x6b,0x52,0x8c,0x10,0xc6,0x0e,0x76,0x60,0x46,0xcc,0x93,0x54,0xc4,0x6e,0xc7,0x70,0x5b,0xb4,0x81,0x51,0x56,0x03,0x22,0x33,0x21,0xe4,0x36,0xee,0x01,0xc3,0x0d,0x17,0x23,0x15,0xae,0x79,0xbc,0xe6,0x13,0x0f,0xfc,0x77,0xa2,0x06,0xed,0x76,0x4a,0xf7,0x2d,0x99,0xc8,0x5c,0xfd,0xac,0xd0,0x11,0xe8,0xfa,0x55,0x17,0x56,0x63 +.byte 0x3e,0xd5,0x23,0x71,0xf8,0xe9,0x1f,0x62,0x95,0xae,0x7c,0x2d,0xcd,0xb8,0x6e,0xb0,0xfe,0xf3,0xd0,0xba,0x72,0x8e,0xe3,0x95,0x82,0x00,0x85,0xdb,0x25,0xe4,0xf2,0xaa,0xbc,0x8d,0xb9,0x4d,0x69,0xa4,0xcd,0x39,0x52,0x9e,0x10,0xae,0x90,0xf0,0x74,0x2f,0xc6,0x5e,0x01,0x99,0x03,0xd5,0x88,0x59,0xfd,0x1b,0x80,0x56,0x0a,0x04,0x27,0xd9 +.byte 0x04,0x51,0xb0,0xb7,0x7a,0x65,0x79,0xa8,0xe2,0x6d,0x7f,0xb2,0xba,0x37,0x40,0xa0,0xbb,0xaf,0x15,0x46,0x23,0x5f,0x22,0xd0,0x2c,0x6c,0x7a,0x58,0x76,0x6f,0xb8,0x19,0xfe,0xb5,0x3d,0xf0,0x77,0x00,0x6b,0x4c,0x83,0x36,0x90,0xe6,0x57,0x29,0x6e,0x27,0x76,0xd4,0x7d,0x9a,0x6a,0xf1,0xf6,0x1b,0x1a,0x45,0xf5,0xf6,0x2d,0xb8,0x30,0x33 +.byte 0x65,0x51,0x37,0x26,0xbc,0xf7,0xb7,0xf9,0x56,0x05,0x6b,0xd4,0xd6,0x00,0x1d,0x13,0x15,0x45,0x24,0x0d,0x28,0x69,0xc6,0x50,0xe1,0x48,0x48,0x34,0x69,0x31,0x3c,0x58,0x71,0xd6,0x4a,0xd9,0xda,0x0d,0x28,0xbd,0xe9,0x5d,0x5d,0x8a,0x6e,0x71,0xc0,0x8b,0x7a,0xba,0x17,0x8e,0x82,0xcb,0xe9,0x95,0xc4,0x43,0x37,0xd0,0x58,0xed,0xec,0x77 +.byte 0x1e,0x22,0xf0,0xf0,0x7c,0x9d,0xeb,0x64,0x30,0x7b,0xb2,0x7b,0x86,0xdb,0xef,0x92,0x79,0xd9,0x9c,0x1c,0x1a,0xf6,0x98,0x26,0x18,0xa2,0x83,0x45,0x08,0xd4,0x1d,0x84,0xd4,0x28,0x6d,0x1f,0xb5,0x1f,0xab,0x97,0xc9,0x0d,0x1f,0x83,0x34,0x18,0xa3,0x20,0x63,0x60,0x6c,0xf3,0xd8,0xb2,0x0a,0xd9,0x35,0xa6,0xce,0x44,0x50,0xc6,0xf3,0x91 +.byte 0xe3,0x95,0x89,0x49,0x99,0x32,0x1d,0xf2,0x54,0x39,0x09,0xca,0xd1,0xc4,0x7f,0xa1,0x1d,0xce,0x94,0x67,0xf1,0x88,0x04,0x29,0xcb,0x5d,0xf7,0xfa,0xcd,0x69,0x16,0x17,0x05,0xc3,0x93,0x45,0xbf,0xd3,0x74,0x63,0xdc,0xe2,0x84,0xab,0x27,0x60,0x56,0x61,0x72,0x5d,0xdf,0xb4,0xa4,0x0f,0xb0,0x21,0x82,0x9b,0x73,0x0a,0x11,0x22,0x2d,0x65 +.byte 0xa2,0xff,0x29,0x8a,0x19,0x28,0x4f,0x4f,0xdd,0x64,0x0a,0x48,0x35,0x70,0x30,0x9f,0x41,0x4d,0x0c,0x7b,0xa6,0xcb,0x63,0x83,0xd1,0x79,0xfa,0x5f,0xc9,0x9b,0x6e,0x09,0x12,0x87,0xcd,0x1e,0x39,0xd6,0x40,0x08,0x0f,0xfd,0x79,0xc8,0xcb,0x77,0x8f,0x7a,0x52,0x42,0xc0,0xb2,0xc8,0xa0,0x2a,0xff,0xbc,0x60,0x13,0xbc,0x41,0x4a,0xc6,0x8b +.byte 0x08,0xb0,0x9f,0x75,0x87,0xa1,0x75,0x42,0x4b,0x3a,0xf7,0xf7,0x84,0x39,0xa5,0x88,0x25,0x2d,0x4f,0x73,0x4e,0x30,0x27,0x92,0xea,0x93,0x70,0x5c,0xb5,0xeb,0xb0,0x10,0xda,0x0f,0xaa,0xb3,0x3f,0xb5,0x55,0x64,0x65,0xae,0xb5,0xf8,0x0a,0xe4,0x9f,0x86,0x02,0x6f,0x63,0x8a,0x0b,0x6b,0x82,0x85,0x3c,0x6a,0xdf,0x68,0x4c,0x1e,0xe9,0x5c +.byte 0xd0,0x99,0xe5,0x0c,0xfc,0x63,0xfb,0xce,0x2d,0x63,0xd5,0x7d,0x8a,0x7d,0x14,0x22,0xbd,0x71,0x5e,0x79,0x3f,0x44,0x95,0xe5,0x6c,0x58,0x94,0x84,0x41,0x65,0x52,0x94,0x50,0xec,0xd3,0x2a,0x16,0x88,0xdb,0x71,0xb9,0xe4,0xb6,0xbf,0xc5,0x3c,0x48,0x37,0x62,0x32,0x79,0xbe,0x1d,0xdb,0xc9,0x79,0x37,0x40,0x65,0x20,0x62,0x45,0xb4,0xda +.byte 0x24,0xef,0x33,0xf1,0x05,0x49,0xef,0x36,0x17,0x17,0x0f,0xdc,0x65,0xb4,0xdc,0x57,0xc3,0xc6,0x82,0x57,0x08,0xf2,0x20,0x57,0x5c,0x25,0x0e,0x46,0x75,0xa7,0x4f,0x9e,0xa4,0x00,0xf7,0x79,0xb9,0x0a,0xef,0x4f,0x50,0x79,0xf8,0x59,0x01,0xf2,0x74,0x9f,0x16,0x27,0xa5,0xc1,0x32,0xcc,0x58,0xa7,0x40,0xa1,0xa1,0x26,0x80,0x00,0xb5,0x64 +.byte 0x0a,0xd8,0x53,0x1f,0x72,0xf7,0x60,0xf7,0x0a,0xaa,0xdf,0x31,0x95,0xff,0xfc,0xb4,0xca,0xbc,0xf8,0x2a,0x33,0x20,0x04,0x16,0x1a,0xe7,0xeb,0x22,0xd1,0x25,0xa6,0x03,0xc9,0x9e,0x9e,0xca,0x7a,0x46,0x7c,0xcb,0x8a,0x63,0x4a,0xf0,0x1b,0xd0,0x34,0xc3,0xbb,0x89,0xcf,0x16,0x38,0xcb,0xe0,0xce,0xd5,0x0b,0xfd,0x4e,0xbc,0xce,0xba,0x28 +.byte 0x68,0x00,0x2a,0x31,0x52,0xe6,0xaf,0x81,0x3c,0x12,0x09,0x2f,0x11,0x0d,0x96,0xc7,0x07,0x42,0xd6,0xa4,0x2e,0xc1,0xa5,0x82,0xa5,0xbe,0xb3,0x67,0x7a,0x38,0xf0,0x5e,0xd8,0xff,0x09,0xf6,0xab,0x6b,0x5d,0xec,0x2b,0x9f,0xf4,0xe6,0xcc,0x9b,0x71,0x72,0xd1,0xcf,0x29,0x10,0xe6,0xe3,0x27,0x1c,0x41,0xc8,0x21,0xdf,0x55,0x27,0xa6,0x73 +.byte 0xb7,0x45,0xa1,0x09,0x66,0x2f,0x08,0x26,0xf1,0x50,0xe0,0xec,0x9d,0xf2,0x08,0xf3,0x49,0x56,0x50,0xe0,0xba,0x73,0x3a,0x93,0xf5,0xab,0x64,0xb6,0x50,0xf4,0xfa,0xce,0x8d,0x79,0x0b,0xad,0x73,0xf2,0x8c,0x1e,0xe4,0xdd,0x24,0x38,0x1a,0xde,0x77,0x99,0xb8,0x92,0xca,0xc0,0xc0,0xbc,0x3d,0x01,0x6f,0x93,0x3a,0x6e,0xc5,0x28,0x6e,0x24 +.byte 0x9c,0xf9,0xd9,0xcb,0x4b,0xbe,0x9e,0xda,0x0d,0x10,0xfb,0x9d,0x15,0xfe,0x28,0xdc,0xd9,0x09,0x72,0xd3,0x9f,0x6d,0x77,0x14,0x84,0x86,0x56,0x10,0xdc,0x8e,0x6a,0xa7,0x62,0xf0,0x0b,0x65,0x2c,0xa2,0xd1,0x7f,0xae,0x32,0xfa,0x9b,0x46,0x0f,0x12,0x08,0x22,0x8c,0x87,0x15,0x4b,0xc4,0x6d,0x85,0xfb,0x69,0xfe,0xce,0xfb,0xb4,0x3e,0x7b +.byte 0xcf,0x88,0xa7,0x97,0x52,0x56,0xd0,0x9f,0xb4,0x33,0xf9,0x08,0xd2,0x28,0x46,0x5e,0xc4,0xec,0x22,0xc6,0x1e,0x7b,0x34,0x99,0x0c,0x5b,0x04,0x19,0xe2,0xca,0x09,0x11,0x50,0x45,0xcc,0xb2,0x90,0x25,0x51,0x68,0xc9,0x20,0x6c,0x99,0x2e,0xdb,0x5b,0x07,0x91,0xb2,0x69,0xbf,0x3c,0x05,0x50,0xfb,0x21,0x33,0x4f,0x6e,0x18,0x19,0xd5,0xff +.byte 0xce,0x9d,0xb5,0x7f,0xd4,0xd5,0x8f,0x41,0x26,0x1f,0xa1,0x4c,0x34,0xd3,0x98,0x08,0x5d,0xb5,0x56,0xa7,0x04,0x63,0x76,0x7d,0xae,0xee,0xea,0xbf,0x69,0x8d,0xff,0xa1,0x62,0x86,0x19,0x7b,0xe5,0x08,0x7a,0xe5,0x9e,0xe5,0x44,0xca,0x24,0xde,0x00,0x43,0xc7,0xcd,0xc8,0x5b,0x21,0x00,0xb9,0x56,0x3f,0xba,0xef,0xcd,0xc4,0xe0,0xd7,0x90 +.byte 0xa7,0xe1,0xf9,0x83,0x2c,0x1d,0x8d,0xc3,0x1b,0xa2,0xab,0xcd,0x7d,0xbc,0xd1,0x2b,0xf8,0x30,0x9e,0xb6,0x95,0xe0,0xd1,0xe6,0x81,0x89,0xa7,0xda,0xf0,0x54,0xc1,0xcb,0x3a,0x85,0x85,0xb5,0x03,0xb4,0x8c,0x7d,0x98,0x16,0xa8,0x83,0x29,0xbb,0x1c,0x1d,0xe1,0x7e,0x0e,0xb5,0x04,0xba,0xbf,0x89,0x30,0x3c,0x44,0xa2,0xc5,0xbf,0xf1,0x70 +.byte 0xdb,0xf3,0x13,0xf4,0x44,0xac,0x63,0xc4,0x9c,0x93,0xa9,0x13,0x1b,0xf1,0xcc,0x16,0x66,0xdf,0x56,0x10,0x88,0x0c,0x76,0xab,0x43,0xcb,0x75,0xf8,0x4f,0x04,0x26,0x95,0x4c,0x6d,0x55,0xc8,0xbd,0xf8,0x94,0x0f,0xca,0x29,0x2b,0xcd,0xce,0x05,0x1e,0xea,0xae,0x02,0x01,0x8b,0x60,0x6a,0x6a,0x03,0x14,0xe5,0xa7,0xdf,0x9e,0x9f,0x94,0x92 +.byte 0x41,0x2c,0xf0,0x1a,0xa7,0xc2,0xc1,0xfc,0x11,0xf3,0x00,0xe1,0xfc,0x7a,0x97,0xc0,0xe1,0x81,0x90,0x3f,0xea,0x1e,0x7f,0xf8,0xb0,0xd8,0x4c,0x2d,0xdc,0x83,0xfa,0x27,0x8b,0xf2,0xef,0x3b,0x3a,0x44,0xdc,0xa5,0xa9,0xd5,0x24,0x5f,0xb1,0xdd,0x1d,0x3f,0x03,0x76,0x3b,0x92,0x0d,0xb4,0x84,0xa4,0x5b,0xef,0x9f,0x89,0x9d,0xef,0xff,0xcf +.byte 0xc2,0x28,0x3b,0x9d,0xd2,0x28,0x75,0x3e,0xdc,0x14,0x79,0x7c,0x0c,0xaa,0x6c,0xf2,0x05,0x9d,0x27,0x01,0x15,0x19,0x60,0x48,0x5a,0x7d,0x04,0x27,0x2d,0x82,0x92,0x3e,0x0b,0x62,0xd7,0x5a,0xfb,0x72,0xfb,0xdd,0x43,0xfa,0xf4,0x6f,0x16,0xd2,0x8f,0x8f,0x21,0xdc,0x81,0x48,0x7a,0xe8,0x39,0xd5,0xdf,0x54,0x0f,0xe1,0xbe,0x65,0xc9,0x49 +.byte 0x98,0xb1,0xff,0x8d,0x52,0x31,0x6a,0xcd,0x5e,0x83,0x17,0x41,0x93,0xcd,0x23,0x76,0x18,0xe9,0x82,0x71,0x15,0xb7,0xd8,0xde,0x0d,0x57,0x8b,0x90,0xe6,0xf4,0x57,0xc1,0xfd,0x3d,0x0d,0x6a,0xae,0xd1,0xd6,0x02,0x3e,0xb9,0x82,0xb2,0x82,0x80,0x48,0xa4,0x14,0x29,0x80,0x55,0x1d,0xaf,0x3e,0xf8,0x7e,0x36,0x5f,0x77,0x4c,0x73,0x6c,0x35 +.byte 0xd2,0x7c,0x36,0xca,0x2f,0xec,0x1e,0x3f,0x74,0xee,0xa5,0xe7,0x7d,0xce,0x81,0xf1,0xd5,0xc1,0xb3,0xaf,0x90,0x2c,0xc6,0x5b,0x81,0x37,0x85,0x98,0x78,0x3c,0x4f,0x2a,0x55,0xea,0x06,0x30,0x77,0x73,0x97,0x39,0x75,0xcf,0x4a,0x9b,0x55,0xb8,0x64,0x5c,0x86,0xfd,0x26,0x3e,0x8d,0x68,0xd2,0x70,0xe8,0xd7,0x99,0x57,0x6f,0x96,0x47,0x6d +.byte 0xa7,0x1a,0x0e,0x85,0xcd,0x00,0xa5,0x3e,0x11,0xec,0x76,0xd2,0x47,0x26,0x71,0xda,0x5c,0xf4,0xb1,0xd5,0x23,0xe1,0x62,0x71,0x43,0x30,0xa7,0x95,0xf6,0xc1,0xcf,0x8a,0x1b,0x75,0x53,0x39,0x6d,0x9d,0x18,0x7c,0xe3,0x48,0x27,0x33,0x1c,0x38,0x45,0xdf,0x75,0x22,0x05,0x6d,0x81,0x5d,0xfc,0xeb,0x0e,0x05,0x26,0x45,0x81,0x9f,0xce,0x0f +.byte 0xc9,0xdd,0x95,0x11,0x04,0x47,0x40,0xa4,0x07,0x3b,0x52,0x92,0xe0,0x91,0xdb,0xdd,0x3c,0x9f,0xd3,0xa1,0xb7,0xf9,0xeb,0xd6,0x6d,0x64,0x88,0xe9,0xf5,0x4e,0x98,0x8e,0x7b,0xd3,0xec,0xc0,0x22,0xe0,0xf2,0x14,0xf2,0x20,0xa2,0xa3,0xb3,0x0d,0x75,0x1a,0xbb,0xde,0x4a,0x41,0x04,0x43,0x0d,0xd9,0xd0,0x1d,0x73,0xc8,0x67,0x8e,0x58,0xe5 +.byte 0x4b,0x28,0x4d,0x8f,0x2f,0xab,0x1a,0x4a,0xfc,0x7c,0xd1,0x27,0x3e,0x4a,0x10,0x6a,0x5f,0x55,0x3a,0xf7,0x63,0x14,0xe9,0xad,0xb4,0x95,0xef,0x3d,0x5c,0xc3,0x7d,0xe4,0xb7,0x15,0xd7,0x0b,0x68,0xf0,0x23,0xa8,0xd4,0x8e,0x27,0xf6,0x55,0x11,0xbc,0xc0,0xff,0x3e,0x2c,0x24,0x59,0xb7,0xb7,0xb5,0x0b,0xd2,0x99,0xa5,0xd5,0xe2,0x24,0x33 +.byte 0x21,0xb8,0x96,0x48,0x18,0x94,0xb5,0xb2,0x50,0x5e,0x04,0x24,0x86,0x17,0x62,0x1e,0xc9,0xf8,0x22,0x6a,0xd0,0xec,0xc5,0xbc,0x90,0xf7,0x55,0xcf,0x3f,0x4c,0x7c,0xf7,0x51,0x19,0x95,0xa4,0x81,0x38,0x0c,0xa5,0x58,0x22,0xf3,0x10,0x05,0x05,0x44,0xbf,0x7e,0x2a,0xbd,0x5f,0x79,0x56,0x08,0xd5,0x68,0xea,0x85,0xa1,0xeb,0x0b,0xe1,0xd4 +.byte 0xfd,0x3a,0x38,0xd2,0x5a,0x49,0x17,0x9a,0x58,0x8f,0x52,0xf5,0xf4,0x7b,0x1f,0x58,0xa8,0xc0,0x1c,0x46,0x38,0xa6,0xe4,0x7d,0xcc,0x88,0x97,0x10,0x2b,0x5e,0x61,0xf5,0x73,0x7d,0x79,0x1b,0x53,0xf1,0xac,0xb4,0x3f,0xbd,0x9d,0xb6,0xc2,0x57,0xd5,0x84,0x4d,0x60,0xd6,0x45,0x56,0xa1,0x36,0x28,0xf5,0x74,0xc6,0x29,0xd7,0xc9,0x63,0x5e +.byte 0x7c,0x97,0x46,0xde,0x56,0x3f,0xd8,0x8e,0x75,0x29,0x87,0xe7,0xd1,0x24,0x78,0x26,0xdc,0x17,0x97,0xc9,0xf0,0x8e,0x95,0xbc,0xe5,0xfe,0xe3,0x3a,0x75,0x70,0x52,0xa9,0x31,0x97,0x79,0x3a,0xc2,0x53,0x6a,0x73,0xe2,0x76,0xf8,0x85,0xe6,0x0d,0x85,0x9b,0xfc,0x72,0x08,0x2a,0xa5,0x8e,0x42,0xb2,0x7c,0x8d,0x8b,0x28,0x4b,0xf5,0xcb,0x66 +.byte 0x80,0x46,0xb3,0x87,0xdf,0x38,0xa7,0x08,0xc8,0xea,0x85,0x0e,0x6f,0x13,0xe0,0x57,0x99,0xc6,0xb8,0xed,0x9c,0xb0,0xa9,0x89,0xd7,0xc5,0xa9,0x71,0xfd,0x8a,0x21,0xb1,0xec,0xc8,0x65,0x78,0x72,0xc6,0x77,0x69,0xd4,0x0b,0x47,0x4d,0x79,0x93,0xcf,0x2a,0x34,0xf1,0x1b,0x0e,0x6f,0x0d,0xd1,0xbb,0xe7,0xd7,0xb5,0x6f,0x57,0x01,0xd4,0xcd +.byte 0x56,0xbe,0xf0,0xd9,0xe2,0x8e,0x0e,0xb8,0x3d,0xdb,0xf6,0x97,0x39,0x0b,0x3e,0xe2,0xb2,0xa3,0x93,0x0b,0x74,0xe5,0x6a,0x21,0x04,0x29,0x5a,0x3e,0x07,0x9c,0x11,0x4e,0xfe,0x01,0x6e,0x96,0x1e,0x8f,0xe0,0xfe,0x24,0x24,0x7e,0x04,0x2f,0x65,0xf4,0xe2,0x1f,0x36,0x56,0x43,0x3a,0x6c,0xeb,0xd7,0x20,0x13,0x71,0x45,0x6a,0xe8,0xc6,0xfa +.byte 0xba,0x26,0x6f,0x7d,0x9a,0x62,0x76,0x34,0x7d,0xed,0x47,0x71,0xd1,0x0e,0x5b,0x04,0x39,0xd6,0xc0,0xe5,0xa5,0xd8,0xf5,0x73,0xf9,0xf4,0xc2,0x2a,0x54,0x25,0x67,0xdf,0x83,0xa3,0xcd,0xfd,0x1e,0x46,0x87,0x06,0x17,0x6d,0x78,0x8e,0x0c,0x7b,0x08,0x06,0x1b,0xd9,0x5d,0x3d,0x03,0x40,0xbc,0xe7,0x02,0xc4,0xe0,0xe0,0x49,0xb2,0x6c,0x6f +.byte 0x97,0x76,0x0f,0xc7,0x14,0xd8,0x7c,0xc0,0xad,0x8a,0xbb,0xbc,0x2a,0x7e,0x68,0x46,0xcd,0xa7,0x26,0x16,0x77,0x1b,0x89,0x38,0xd8,0x2a,0x69,0x43,0xc4,0xaa,0x0d,0xf6,0xd1,0x65,0xda,0x41,0x75,0x77,0xcd,0xf7,0xd2,0x38,0x9c,0xdb,0x81,0x17,0x27,0x2f,0xba,0x2e,0xa5,0xb5,0xbe,0x05,0xe8,0xdd,0x5f,0xa9,0xad,0xbe,0xb2,0x0e,0x0b,0x69 +.byte 0xb6,0x8d,0xd2,0xf2,0xde,0x76,0x32,0x26,0xd9,0x06,0x1d,0x42,0x26,0x8c,0xf7,0xca,0x4c,0xe1,0x59,0x82,0x6c,0xea,0x96,0x70,0x39,0xb8,0x0d,0xf3,0x67,0x9d,0x5e,0x94,0x99,0x77,0xf2,0x0a,0x9a,0xde,0xa5,0xd2,0xe1,0xaa,0x91,0x85,0xc7,0x0f,0x92,0x35,0x04,0xd3,0x7a,0x13,0xfa,0xf2,0x86,0x5a,0x38,0xd1,0x7f,0x10,0xd8,0x30,0x0e,0x33 +.byte 0xe3,0xa0,0x8a,0xad,0x4f,0x6c,0x24,0xdd,0x9d,0x1c,0x4e,0xff,0x4c,0xfc,0x74,0x01,0xab,0x08,0x6c,0xe6,0x4c,0x78,0x75,0xc9,0x67,0x83,0x1f,0x75,0x22,0xb0,0x7c,0x44,0xa0,0xa1,0xee,0x4e,0xf6,0x3e,0xd3,0x35,0x70,0xbe,0x36,0x1e,0x90,0xa6,0xaa,0x64,0x67,0x7f,0x52,0x84,0xd9,0x27,0xab,0x37,0x30,0x68,0x46,0xcc,0x0e,0x57,0x58,0x6f +.byte 0xdb,0xb2,0x5f,0x24,0xf7,0xeb,0x97,0xea,0x64,0xec,0x6c,0x1e,0xe1,0xc4,0x72,0xfb,0x00,0xa7,0x62,0xa0,0x59,0xb9,0x17,0x8a,0x33,0x32,0x59,0xb8,0xbe,0x84,0xd4,0x62,0xb7,0xf6,0x35,0xd4,0xf1,0x1c,0xdb,0x7e,0xa6,0xbc,0x2c,0x54,0x3c,0xf5,0x63,0x4a,0x22,0x26,0x58,0xa0,0x35,0x98,0xa7,0x32,0xb2,0xa0,0x2b,0xd5,0xfa,0x2f,0x9b,0xb4 +.byte 0xea,0xd6,0x58,0x61,0xb2,0x24,0x45,0x46,0x1e,0xac,0x79,0xa4,0xf7,0xc1,0x13,0x2f,0xf5,0x6b,0xfa,0x70,0x50,0x2b,0x83,0xee,0x7c,0xc1,0x55,0x27,0x7b,0x4f,0xa6,0x0a,0x72,0x26,0x82,0xcd,0x4d,0xe2,0xe8,0x45,0xe6,0xd7,0x39,0x7e,0xed,0x35,0xdf,0x9e,0xb1,0x41,0x55,0xa2,0x5d,0x68,0x4b,0x0b,0xd1,0x73,0x5a,0x2b,0x81,0x35,0x28,0xfc +.byte 0x64,0x08,0xd7,0xc4,0x9f,0x30,0x77,0x3d,0x9d,0x80,0x15,0x67,0x9a,0x84,0xe4,0x34,0xea,0x8c,0xf7,0x73,0x9e,0x33,0xb4,0x09,0x33,0xbd,0xd8,0x82,0x43,0x7d,0xc5,0x1f,0x0e,0x7b,0xa0,0x53,0x59,0x20,0x12,0x57,0xed,0xda,0xc7,0x19,0x8e,0x62,0xe4,0x09,0xc1,0x4b,0x20,0x32,0x9e,0x18,0x11,0x1c,0x42,0x49,0x62,0x76,0xa8,0x83,0x72,0x11 +.byte 0x45,0xe7,0xb5,0x60,0xa7,0xc0,0x07,0xbd,0xb4,0x7c,0xc6,0x5c,0x03,0x34,0xa3,0x85,0x47,0x24,0x75,0xd2,0xab,0x46,0xbb,0xc7,0x0d,0xcd,0x40,0xe2,0x5e,0x5b,0xa7,0x98,0x67,0xe4,0xe2,0x02,0xe9,0xdc,0xd7,0xc2,0xaf,0x90,0x43,0x94,0xfe,0xf3,0x53,0xc1,0x10,0x28,0xa7,0x90,0xba,0x73,0x57,0x0c,0x4d,0x6d,0xbd,0xda,0x81,0xd5,0x90,0xce +.byte 0x02,0x40,0xb3,0xf0,0xec,0x50,0x82,0xc9,0xfb,0xf1,0x22,0x6d,0xc8,0xd2,0x7b,0xed,0x0b,0x43,0x7e,0x0b,0x60,0x9b,0x69,0x9e,0x58,0x26,0xc3,0x9f,0x6b,0xd0,0x31,0xeb,0xb7,0x0a,0xf3,0x9a,0x9a,0xf5,0x72,0xcf,0x29,0xc8,0x19,0x08,0x4d,0x67,0xd5,0xa1,0x8f,0x68,0x0e,0xee,0x59,0x14,0xf8,0x86,0xc0,0x08,0x5a,0x56,0xfe,0x6a,0xb7,0xac +.byte 0x78,0x8d,0x77,0x39,0x5e,0xb1,0x01,0x4d,0x31,0x81,0x56,0xdc,0x5b,0x10,0xda,0x4d,0xd2,0xfd,0xfc,0xa3,0xe3,0xaa,0x46,0x29,0x1a,0xea,0x9c,0x47,0x1b,0xd0,0xa6,0x84,0x1f,0x71,0x1a,0xd3,0x35,0x59,0x7f,0xef,0xf7,0x81,0x39,0x7a,0x9f,0x4a,0x01,0x4d,0x46,0xcf,0xa4,0x6a,0x9c,0x7e,0x07,0x8b,0x98,0x17,0x49,0x5c,0x46,0xac,0xc8,0xfd +.byte 0x1c,0xaf,0x91,0x30,0x0c,0x36,0x63,0xef,0x69,0xd3,0x47,0xf4,0x76,0xc1,0xf7,0x40,0x03,0x98,0x9e,0xcb,0x61,0x65,0x46,0x45,0x1c,0x1b,0xfd,0x13,0x36,0xe9,0x19,0xbf,0x2b,0x59,0x51,0xe8,0x04,0x44,0xe3,0xc2,0x4b,0x66,0x78,0x69,0x66,0xa3,0x1a,0xe5,0x2a,0xad,0xf8,0xc5,0x0f,0xb7,0x3e,0xe8,0xab,0xe0,0xe4,0xd9,0xc2,0xb8,0x61,0x5b +.byte 0xef,0x6b,0x4d,0x5f,0xb8,0xdc,0x06,0xa5,0xce,0x08,0x5b,0x1f,0xf4,0x29,0x4d,0x0a,0x3e,0xb3,0x60,0xf4,0x63,0x3c,0x70,0x5d,0x02,0x9c,0x55,0x5e,0x5e,0xd1,0x9b,0xed,0x20,0x75,0x54,0xa1,0x8e,0xae,0xce,0x5a,0xb2,0x2d,0xe4,0xc3,0x9b,0x7d,0x72,0xce,0x7c,0x0c,0xa9,0x99,0xa4,0x12,0xaa,0x31,0xe9,0x61,0x47,0x8a,0x41,0x93,0xd5,0x69 +.byte 0xc5,0xf3,0x9f,0xf4,0x97,0x69,0x64,0x6f,0xf9,0x5b,0xbf,0x58,0xf6,0x3b,0x3e,0xd6,0x93,0x94,0x89,0xcc,0xc0,0x25,0x7d,0xf8,0x40,0x9e,0xb2,0xc8,0x75,0x9d,0x4d,0xf0,0x5f,0xa5,0x3d,0x38,0x67,0xea,0x8d,0x1b,0x60,0x5e,0xfe,0xa8,0x26,0xb9,0xed,0xc0,0xe9,0xc8,0xec,0xb1,0x77,0x0f,0xf2,0xaa,0x77,0x2a,0xcd,0xa8,0x70,0xb7,0xda,0x60 +.byte 0x49,0xb3,0x01,0x95,0xc8,0xac,0x71,0x6a,0xd0,0x49,0x67,0x2a,0x04,0xfc,0x55,0x38,0x08,0x37,0xd9,0x21,0x37,0xce,0x41,0xaf,0x7c,0x33,0xdd,0xcd,0xe0,0x92,0x27,0x38,0x63,0x77,0xea,0x86,0x04,0x99,0x4e,0x61,0x8b,0x8f,0xfe,0x4e,0xc1,0x16,0x6c,0x89,0xac,0x1f,0x0b,0x67,0x75,0x49,0xf4,0xdb,0x6d,0xd3,0xb8,0x1d,0x9c,0xb2,0xe6,0x98 +.byte 0x81,0xae,0x3f,0xe0,0xdd,0xda,0xfa,0x4c,0x8b,0x30,0x18,0x88,0xa1,0x1d,0xa1,0x18,0xb8,0x28,0xc2,0x04,0x6a,0x80,0x02,0x5a,0xe6,0x04,0x85,0xfa,0x54,0x38,0x45,0x64,0xe1,0x50,0x4a,0x38,0x4c,0x85,0xf7,0x00,0x0c,0xd3,0x16,0xcb,0xfa,0x38,0xb4,0x1b,0x6a,0x95,0x3d,0xc3,0x24,0x79,0x0e,0x3e,0x81,0xe6,0xc3,0xd9,0xdb,0x05,0x19,0x7c +.byte 0xb4,0x4d,0xef,0x71,0x22,0x53,0x97,0x8a,0xc9,0xe3,0x69,0x20,0x5b,0x83,0xb1,0x44,0xd7,0xd1,0x1e,0x87,0xa7,0xbf,0xe4,0x84,0x68,0x9c,0x77,0xfe,0x83,0xdb,0x7a,0x53,0xa8,0x53,0x1f,0xc7,0xd1,0x6a,0x26,0x87,0x71,0x06,0x23,0xa7,0xe0,0x18,0x5d,0xfa,0x8c,0xa7,0x24,0xee,0xf6,0x74,0xab,0x17,0xd3,0x46,0x33,0xe9,0xc3,0xcd,0xa6,0xaf +.byte 0xcf,0xa1,0x60,0x75,0x7b,0x77,0xc3,0x58,0xa2,0xe8,0x87,0x7b,0x4b,0x57,0xb1,0x96,0xc1,0x91,0x6d,0xbf,0x71,0xb3,0xbf,0xe2,0x62,0x86,0x72,0xa9,0x01,0x64,0x62,0x32,0x33,0xc8,0xa4,0x26,0x7d,0xfa,0x0d,0xd4,0xd8,0xc3,0xaa,0xc0,0xc8,0x7c,0x51,0xe8,0x10,0x08,0x6f,0xf6,0xc1,0x46,0x89,0xc4,0xd2,0x00,0x1d,0x14,0x05,0x89,0x64,0x52 +.byte 0xcd,0x1f,0x97,0x0b,0x1d,0x94,0xbe,0x9d,0xa0,0x6b,0x03,0x9b,0x83,0x87,0x38,0x0f,0x65,0xdd,0x6a,0xaf,0xf1,0x22,0x74,0x7e,0x11,0xa0,0xdf,0x1e,0x95,0xef,0x1a,0xdc,0x8b,0x29,0x4a,0xbe,0xfd,0x2f,0xc7,0x48,0x94,0x3f,0xb9,0x8c,0x8e,0xe1,0x0c,0x54,0xa6,0x2f,0xa5,0x2b,0x71,0xdd,0x16,0x68,0x91,0x35,0xd0,0x22,0x48,0x1f,0xf2,0xe2 +.byte 0xe8,0x57,0x83,0xd7,0x49,0x43,0xfd,0xf9,0x77,0xb5,0xfa,0x70,0x19,0xeb,0xae,0xf6,0x31,0xfe,0xd6,0x81,0x6c,0xcc,0x14,0x28,0xa6,0x9f,0x74,0x56,0xc5,0xf6,0x51,0xba,0xc8,0xbd,0x32,0x80,0x5f,0xdb,0x28,0x3f,0x4a,0x55,0x01,0xe1,0x39,0xf5,0x9c,0xda,0xb3,0x42,0xee,0x43,0x17,0xc3,0xc7,0xf5,0xd1,0xda,0xd2,0x2e,0x56,0xcf,0x77,0x0e +.byte 0xdd,0x72,0xcf,0xe5,0xab,0xfb,0xd6,0xa2,0x6c,0x03,0xa6,0x77,0x25,0xf8,0x2a,0x8c,0xfa,0x6f,0x45,0x79,0x59,0x84,0x92,0xd1,0x00,0x58,0xc7,0xb8,0x95,0x4d,0xc8,0x49,0xad,0xe0,0x1e,0x64,0x47,0x00,0xfb,0x93,0x7f,0x3e,0xf1,0x65,0x70,0x47,0x64,0xbb,0x36,0x63,0xe3,0x09,0xcb,0xdb,0x5a,0xd1,0x72,0x83,0xfd,0x15,0x91,0xa2,0x03,0x81 +.byte 0x04,0x98,0x45,0x0f,0x7f,0x23,0x48,0x6c,0xb1,0x2d,0xd0,0x2c,0x61,0x52,0x1b,0x4a,0x52,0x08,0x92,0xe1,0x7a,0xf1,0x8c,0x1f,0x1f,0xdf,0x1c,0xfd,0xd9,0x46,0x99,0x71,0x05,0x58,0x71,0x82,0x5c,0x05,0xa0,0xb2,0x6a,0x50,0xd2,0x6e,0x35,0xf4,0x6c,0xfb,0x50,0x99,0xb3,0xc1,0x2b,0x05,0xaf,0x02,0xe5,0x18,0xfa,0x74,0x09,0xcc,0xa5,0x2c +.byte 0x26,0xfd,0xc5,0xe7,0x2c,0x96,0x0f,0xa4,0x7c,0x88,0xc6,0x7f,0xf9,0x74,0x9d,0x1c,0xe5,0xd2,0x27,0xf0,0xae,0x5b,0x4c,0xbf,0x0a,0x99,0x2e,0xaa,0x54,0xba,0x0d,0x75,0xd9,0x48,0x76,0xf3,0xe9,0xd9,0x01,0xbe,0xaa,0x97,0x09,0xfe,0xb2,0x4a,0xcb,0x55,0xd0,0xe1,0x58,0xec,0x31,0x0c,0xd9,0xdf,0xd9,0x01,0xf9,0x3c,0x28,0x40,0x91,0xbb +.byte 0x4d,0x2d,0x88,0x60,0x31,0xc7,0xc9,0x1d,0xaf,0x22,0x44,0x21,0x05,0x06,0xdd,0x07,0x60,0x29,0x7d,0x49,0x30,0x9d,0x35,0x1d,0x9f,0x37,0xbd,0x32,0xb2,0x21,0xa6,0x4f,0x89,0xd8,0xe6,0x85,0x44,0xcf,0x13,0x12,0x4f,0x5f,0x50,0x71,0x01,0x39,0xff,0x6e,0xa0,0x07,0xff,0xf0,0xa6,0x3b,0x39,0x59,0x17,0xae,0x93,0xb2,0x86,0xcc,0xe5,0x59 +.byte 0x5a,0xf2,0x82,0x62,0xc6,0x8d,0x13,0x2f,0x6b,0x92,0x28,0xbe,0xd1,0xc0,0xf6,0xc9,0xe1,0xd6,0x98,0x94,0x65,0xd4,0x2a,0xdb,0x37,0xb1,0xd3,0x83,0xf2,0xaa,0xa5,0x00,0xf9,0x08,0xe6,0x22,0x38,0x30,0xb6,0x49,0x8d,0x9d,0x1c,0xa4,0xf7,0xdb,0x3c,0x6f,0x75,0x08,0xa0,0xda,0xe9,0xc0,0x01,0x54,0x09,0x68,0xc6,0x7c,0x5b,0x4d,0x88,0x71 +.byte 0xa7,0x2f,0xb3,0x50,0x18,0x4a,0xfb,0x55,0x29,0xf2,0x56,0x1d,0x4c,0x12,0x22,0x1c,0x54,0xd2,0x63,0x67,0xfa,0xe9,0x5b,0x74,0x3b,0x38,0xf6,0xa0,0x85,0x63,0x1c,0x41,0x6a,0x6d,0x71,0x1d,0xb1,0x39,0x28,0x88,0x96,0x9b,0x9c,0x50,0x9e,0x57,0x4e,0xf5,0xa7,0xf4,0x17,0xc6,0xca,0x42,0x84,0x83,0xca,0xa4,0x28,0x72,0x08,0x74,0x62,0xe1 +.byte 0xf0,0x73,0xc5,0x86,0x6c,0x76,0x9d,0xd3,0xa6,0xb8,0x5d,0x73,0x1b,0x02,0xe2,0x69,0x8b,0x59,0xd6,0x6a,0x53,0xe9,0x13,0x88,0x41,0x95,0xe9,0x97,0x5f,0x07,0x62,0xa5,0x21,0x97,0x7e,0x5e,0xc2,0x2c,0xc7,0xaf,0x0a,0xdb,0x9e,0x4f,0x44,0x4b,0xd6,0x3d,0xc0,0x24,0x38,0x50,0x47,0x98,0xa3,0xfc,0xda,0xfc,0xae,0x0e,0x2b,0x9b,0x53,0x0f +.byte 0x6b,0xb1,0x2f,0xd5,0xd7,0x68,0xc9,0xab,0xb9,0xff,0x7f,0x54,0xd6,0x2f,0x88,0xbc,0x5e,0x6a,0x22,0x49,0x0f,0x98,0xbe,0x1f,0xef,0x3e,0xcc,0xa2,0x72,0x6b,0x16,0xbe,0xe8,0x5f,0x0e,0x36,0xa2,0x68,0xe0,0x65,0xd9,0x7c,0xdc,0x8c,0x6a,0x66,0xf0,0x6a,0xfc,0x2b,0x85,0x28,0x2a,0x1a,0xfc,0x92,0x64,0x3d,0x38,0x5b,0xc1,0x0c,0x68,0x45 +.byte 0x94,0x85,0x58,0x82,0x99,0xfc,0x20,0xdd,0x62,0xae,0xed,0x35,0x7c,0x02,0x16,0x9b,0x00,0x8a,0x44,0x02,0x80,0x00,0xca,0x7d,0x95,0x03,0x5d,0xa6,0xec,0xe1,0x0c,0x50,0x34,0x61,0x55,0xee,0xb5,0x11,0xff,0xc3,0xaa,0xf2,0xbc,0xa3,0xa9,0xc7,0x6b,0x16,0xab,0x56,0x7b,0x55,0x54,0x95,0x88,0x15,0x15,0x6a,0x2c,0x97,0xd7,0x7c,0x26,0x65 +.byte 0xaf,0x8d,0xd1,0x05,0x57,0xb2,0x63,0xd1,0x22,0xf7,0x7d,0x77,0x54,0x6c,0x87,0x03,0x1f,0x0e,0x2b,0xae,0xa6,0xa4,0xb5,0xd6,0x95,0x34,0xd0,0x62,0x4e,0xfb,0xcb,0xee,0x01,0xc1,0xf7,0x36,0x94,0xa6,0x54,0x94,0x90,0x0e,0x45,0x9c,0x95,0x89,0x96,0x88,0x32,0x90,0x27,0x48,0xc5,0x96,0xf0,0x7e,0x7f,0x69,0x99,0xdf,0x7b,0xfb,0x2b,0x7b +.byte 0x38,0x10,0x6b,0xd1,0x1a,0xfb,0xf2,0xcd,0x2d,0x8b,0x47,0x21,0xca,0x92,0x64,0x28,0xd1,0x53,0x1d,0xed,0xa7,0x7d,0xa4,0x88,0xab,0xd0,0xfe,0x9b,0x2b,0xf8,0x48,0x94,0x8d,0xd5,0xfa,0x5c,0xef,0x12,0x43,0xdf,0xb6,0x5b,0x83,0x43,0xf3,0xf7,0x1d,0x6f,0x3e,0x44,0xe6,0x20,0xd8,0xbc,0x4a,0x9a,0xed,0xa0,0x79,0x66,0x8d,0x23,0xca,0x35 +.byte 0x15,0x87,0x11,0x50,0xa4,0x40,0x6e,0xfa,0xf7,0xaf,0xa2,0xb7,0x3b,0x9b,0x8b,0x44,0x19,0x90,0xb3,0x47,0x92,0x08,0x2f,0x0c,0xe2,0x95,0x5d,0x80,0xb5,0x93,0x5e,0x1c,0xb5,0xce,0x52,0x0b,0x12,0xc1,0x72,0x2e,0x66,0x8c,0xd1,0x13,0x94,0x36,0xf7,0x17,0xe3,0xad,0x69,0xc9,0x2d,0x21,0x64,0xcd,0x8f,0x2d,0x8f,0x0c,0x85,0xa5,0x23,0x8b +.byte 0x6c,0x00,0x13,0xf7,0x6a,0xb4,0x68,0x1a,0xcc,0xc4,0x03,0x5b,0xd6,0x7b,0x5b,0x34,0x90,0x34,0x3e,0x0a,0x07,0x19,0x81,0x99,0xe9,0xd2,0xa8,0x73,0x2c,0xa2,0xcf,0xdf,0x29,0x69,0xbf,0xec,0xdd,0xa5,0xd3,0x16,0xb0,0xd2,0x9c,0x2f,0xeb,0x70,0x50,0x20,0x3c,0x22,0x1a,0x5b,0x55,0x79,0x76,0x0f,0x1f,0xd0,0x34,0xa9,0x55,0xad,0x75,0x75 +.byte 0x7f,0xa7,0x9b,0xa7,0x3d,0x5d,0x73,0xce,0x91,0xf6,0x9b,0xcd,0xa5,0xee,0x48,0x44,0xba,0xd5,0xad,0xbe,0x1e,0xc6,0xd2,0x8b,0x05,0x21,0x20,0xb5,0x7d,0x78,0x88,0x10,0x20,0x85,0x90,0x8f,0x47,0x74,0x68,0xe6,0x32,0x2a,0x13,0x7a,0xb3,0x5d,0xfe,0x24,0x97,0xd1,0x65,0x55,0x60,0xb3,0x88,0xfb,0x59,0xc9,0x29,0x70,0xf1,0x45,0xbd,0xbe +.byte 0x4d,0x01,0x4e,0x5e,0x5f,0x99,0x52,0xf8,0x5f,0x38,0xcf,0xa8,0x5d,0x69,0x54,0x87,0x72,0x41,0xca,0xc4,0x63,0xc1,0x52,0x58,0x66,0x8b,0xda,0x8b,0x61,0xd1,0xab,0x7d,0x8d,0xfe,0x51,0x8d,0xf6,0xd0,0x21,0x4d,0x0b,0xc5,0xea,0x74,0xcd,0x21,0x93,0x4a,0x91,0xe5,0x3f,0xce,0x35,0x3b,0x3f,0xc0,0xab,0xa4,0x23,0x76,0xd1,0x8c,0xa7,0xbe +.byte 0x15,0xab,0x8e,0xd7,0x0d,0x86,0xac,0xc3,0x06,0xff,0x33,0xf2,0x41,0x6f,0x69,0x58,0x49,0xd1,0x73,0xcf,0x5e,0x4e,0x1e,0x46,0x12,0xfa,0x30,0x0d,0x4b,0xb1,0xfb,0xc6,0xe6,0x0d,0xcd,0x8d,0xca,0x34,0x28,0x5a,0xed,0x85,0x55,0x31,0xee,0xba,0xbf,0xa4,0x6f,0x9c,0x7d,0xeb,0x4b,0x1b,0x73,0xea,0x4e,0xb9,0x62,0x5d,0xac,0xe3,0x53,0xdf +.byte 0x27,0x87,0x2f,0x39,0xca,0x5b,0xd6,0x72,0xcf,0x95,0xc6,0x2a,0xa5,0x3f,0x57,0xfd,0xdc,0xa9,0x4a,0x86,0x0f,0xcd,0xd5,0xea,0xfe,0x85,0xeb,0x9b,0x84,0xc6,0xf7,0xba,0xc2,0x37,0xbc,0x18,0x85,0x49,0xa6,0x7f,0xd9,0x3e,0xfb,0xf0,0x0c,0x39,0xe3,0x1c,0x06,0xfe,0xb6,0x49,0xa3,0x8b,0x72,0x2b,0x39,0xa1,0x48,0xfd,0x1f,0xfe,0xa4,0xf7 +.byte 0xcc,0x7a,0xef,0x64,0xa0,0x0d,0xeb,0x78,0x71,0x8c,0xd6,0x59,0x7c,0xf4,0xaa,0x81,0x7a,0x89,0xe6,0x22,0xc9,0x57,0xe8,0x13,0x9c,0xca,0xc4,0x6f,0xb5,0xbf,0x08,0x31,0x93,0x56,0x2a,0x82,0x00,0x95,0xdc,0x4b,0xfd,0x9b,0xc7,0x8b,0x31,0x72,0xa0,0xff,0xbe,0xb4,0xd6,0x07,0x16,0x0a,0x4a,0x0a,0x96,0x02,0x83,0x53,0x2a,0x4d,0x33,0x72 +.byte 0x1f,0x20,0x20,0xc3,0x63,0xee,0x4e,0x05,0x90,0x7d,0x21,0xd0,0xf1,0xda,0xde,0x0d,0x4a,0x59,0xb9,0xca,0x81,0xe3,0x1f,0x83,0x19,0xdc,0x09,0x03,0x5f,0xaa,0xee,0xbc,0x5a,0xfa,0xc6,0x4d,0x3d,0xfe,0xfe,0xf3,0xdb,0xc3,0x77,0x31,0x74,0xb4,0x94,0xb5,0x09,0xb1,0xb5,0x13,0x47,0x2e,0x4f,0x3b,0x38,0x83,0xf5,0xfc,0xe9,0xcc,0x45,0xea +.byte 0x5b,0x88,0x21,0xba,0x53,0xc5,0xf6,0xd4,0x63,0xc5,0x37,0x1d,0xa1,0x42,0x2e,0x9c,0x9a,0x50,0x2c,0xfe,0xdb,0xf6,0x31,0x36,0x5f,0x9d,0xed,0x63,0x42,0x20,0xdd,0x27,0xe5,0x34,0x3c,0x0f,0x06,0x8b,0x8f,0x32,0xb6,0x47,0xce,0x07,0xcb,0x27,0xc1,0xb7,0xfe,0xb2,0x69,0x81,0x79,0x20,0xd7,0x47,0xbb,0xab,0x61,0x5f,0x09,0x99,0xdf,0x9f +.byte 0xde,0x59,0x33,0x75,0xd1,0xcc,0xfe,0x92,0x79,0x1f,0x2d,0x59,0x88,0xef,0x4b,0x80,0x0c,0x38,0xa3,0xb1,0xef,0xae,0x53,0x84,0x2f,0xbd,0xd3,0x0c,0xcf,0xd5,0xf7,0xb7,0x6f,0xa7,0x22,0x1f,0xf1,0x56,0x76,0x0c,0x78,0x52,0xa3,0xc0,0xd0,0x2f,0xbc,0xdf,0x29,0x0d,0xa8,0x54,0x0d,0x2b,0x65,0x1b,0x7f,0xeb,0x21,0x22,0xaf,0x10,0xc1,0xd6 +.byte 0x30,0xa8,0x2f,0xb1,0x25,0xbf,0xdc,0xee,0xe9,0x35,0x40,0x69,0xa0,0xa0,0x27,0x85,0x2e,0x18,0xc1,0x36,0x24,0xc5,0x96,0x9a,0x85,0x3f,0xbb,0xfd,0xf5,0x02,0xa2,0xa1,0x92,0x3c,0x16,0x48,0x9f,0xc5,0x00,0x7c,0x7b,0xaf,0x31,0xba,0x68,0x0e,0x58,0x88,0xf4,0x10,0xb9,0xa6,0xe0,0x46,0x2a,0xb8,0x8d,0xc7,0x8e,0xad,0x7c,0xec,0xd2,0x74 +.byte 0x92,0xfe,0x1b,0xd0,0x73,0x79,0x0b,0x4e,0xcc,0x2d,0x5c,0xe7,0x80,0x2d,0x21,0x1c,0x97,0xfc,0x2a,0xc9,0x9c,0x07,0x10,0x64,0x8b,0xf7,0xf5,0x1c,0x54,0xb6,0x6c,0x73,0x1c,0x50,0xd3,0x1a,0x2a,0x63,0xcb,0xba,0xd3,0x95,0xe2,0xa6,0xc3,0xca,0x45,0xfd,0x5e,0x1b,0xbb,0x6b,0x4d,0xb3,0xf7,0xfd,0xaa,0xf9,0x73,0xb8,0x74,0x4d,0x36,0x7e +.byte 0xcc,0xaa,0x1e,0xf3,0x20,0x68,0xa5,0x0c,0x03,0xe3,0xbe,0xee,0x82,0x03,0x8d,0x10,0xa6,0xf6,0x6c,0x73,0xc2,0x9d,0x74,0xba,0x57,0x17,0xd7,0xfa,0x85,0xf5,0x1e,0x3d,0xf8,0xc7,0x80,0xef,0xcd,0xf0,0xf4,0x46,0xfc,0x07,0xb5,0xc4,0x5f,0xd2,0x04,0x6a,0x90,0xf5,0x76,0xb6,0xf9,0x73,0x22,0xa6,0x09,0x2f,0xbf,0xb5,0x93,0x9a,0x95,0x05 +.byte 0x95,0xaa,0xf9,0x8c,0x71,0xd6,0xc6,0xd9,0x72,0x50,0xf6,0x58,0x77,0x09,0x47,0x97,0x21,0x42,0xf0,0x30,0x5c,0x3c,0xec,0x60,0x67,0xdf,0x5e,0xd2,0xed,0x0f,0xab,0x25,0x11,0xbb,0xf8,0x34,0x1e,0xbd,0x7f,0xc6,0x52,0x19,0xf5,0x53,0x28,0x46,0x75,0x93,0xce,0xc2,0x0b,0xdf,0xfd,0xa5,0xf1,0xb0,0xa2,0x0b,0x97,0xb5,0x76,0xb4,0x8a,0x2b +.byte 0x82,0x55,0x23,0x29,0xc2,0xd3,0x32,0x94,0x2f,0xf0,0xe6,0x77,0x2c,0xe4,0x6a,0x7f,0xd7,0xee,0x84,0xfb,0xba,0xb8,0x4b,0xae,0x13,0x34,0xbd,0xa8,0x12,0x7a,0x3c,0x28,0x40,0x74,0x5d,0x9a,0x11,0x1a,0xe9,0x74,0x31,0x28,0x3d,0x3d,0x64,0xb7,0x54,0xa0,0x51,0x0d,0xed,0x97,0x94,0x56,0x7a,0x48,0x8e,0x36,0xc9,0xae,0x5f,0xc6,0x79,0x45 +.byte 0x4f,0x07,0xdd,0x13,0x52,0x8b,0xfc,0x3b,0x73,0x44,0x68,0x64,0x51,0x0d,0x95,0x6f,0x0f,0x94,0xba,0xf8,0x40,0x64,0x51,0x43,0x49,0x63,0xc1,0xbd,0xf3,0x39,0x7f,0x6e,0x6f,0x45,0xeb,0xd2,0x33,0x44,0x2d,0x10,0xb4,0x68,0xcb,0xcb,0x8c,0x84,0xc5,0xd4,0x63,0x1d,0x23,0x85,0x30,0x4d,0x6c,0xfc,0xc9,0xa4,0x8c,0xd2,0x42,0x69,0x2f,0x17 +.byte 0x86,0xf0,0x17,0xd0,0xb2,0xaa,0xfd,0x62,0xcb,0xb4,0xfd,0xba,0x29,0xf8,0x85,0x45,0x84,0x9d,0xae,0xf8,0x9c,0x8f,0x64,0xd5,0xb8,0xb6,0xa9,0x64,0xf9,0x39,0x86,0x68,0x29,0xac,0x32,0x87,0x84,0x6c,0xb0,0x09,0xd2,0xdd,0xf2,0xec,0xa1,0x3a,0xfd,0x11,0x37,0x54,0x67,0x29,0x62,0x25,0x62,0xe8,0x6a,0x4b,0x5e,0xde,0x9a,0xf0,0x97,0x73 +.byte 0x66,0x69,0x2a,0x21,0xbe,0x95,0x86,0xca,0xf9,0x17,0xe9,0x4b,0x23,0x83,0x1e,0x8c,0x37,0x47,0x91,0x03,0x3f,0x9f,0xb8,0x60,0x2c,0xdd,0x82,0xbd,0x2a,0xc3,0xe7,0x30,0x8f,0x91,0x2b,0xa4,0x23,0x01,0x03,0xb2,0x8b,0xbd,0xd2,0x1d,0x16,0xf7,0x6a,0x86,0xa8,0xe4,0x54,0x6f,0x9c,0x47,0xa5,0x0f,0xbe,0x94,0x56,0xfa,0x18,0x69,0xbe,0x92 +.byte 0xe9,0xf8,0x24,0x4d,0x65,0x42,0x81,0x1f,0x85,0x52,0xb7,0xc9,0x49,0xde,0xa5,0x4c,0x8f,0x0d,0x5f,0x12,0x68,0x68,0x35,0xce,0x29,0x22,0x5c,0x55,0x3e,0xbd,0xce,0xf2,0x2a,0xec,0x7e,0xe1,0x29,0x0a,0x88,0xf3,0x5e,0xeb,0x27,0xe5,0x52,0xee,0x72,0x37,0xba,0xff,0x82,0x97,0xa9,0x5d,0x77,0x6f,0xb9,0xc3,0xa7,0x73,0xba,0x7f,0x2f,0x7a +.byte 0x19,0x32,0x87,0x56,0xa2,0x89,0xb2,0xb4,0x48,0xbe,0x2e,0x30,0x89,0x0a,0x8f,0x75,0x25,0x25,0x5c,0x46,0xe8,0x02,0x45,0xcb,0x03,0xd1,0xa3,0xeb,0x70,0x71,0x08,0x1c,0x46,0xf1,0x2c,0x43,0xe2,0x44,0x30,0x6a,0x61,0x31,0x45,0x3e,0xbb,0x47,0x33,0x24,0x25,0x13,0xeb,0xf7,0x24,0x66,0x15,0x4c,0xf3,0x07,0x2f,0xff,0xdc,0x37,0x0f,0x71 +.byte 0x85,0xc8,0x56,0xa7,0x2a,0x22,0x87,0x8b,0xae,0x35,0x31,0x29,0x96,0xf0,0x81,0xfb,0x2c,0xbf,0x44,0x69,0x69,0x9a,0x77,0xfd,0xc0,0x2b,0x42,0x16,0x67,0xd6,0xbd,0xd0,0xf1,0xb9,0x40,0x8f,0xd2,0x9a,0x1b,0x2c,0x64,0x78,0x6b,0xda,0x37,0x26,0xae,0x4c,0xee,0x36,0xaf,0x84,0x61,0xe4,0x93,0x22,0x64,0xaf,0xee,0x6d,0x69,0x5c,0xe5,0x85 +.byte 0xd8,0xcc,0xcf,0xf3,0xe8,0x05,0xcd,0xd2,0x09,0x66,0xaf,0xbb,0xc4,0x79,0xb2,0xa7,0xa5,0x09,0xd9,0xf5,0xa2,0x83,0x4f,0xd5,0xf5,0xf3,0x7d,0x7a,0xab,0x94,0x83,0xb3,0x15,0xfb,0x0d,0x1a,0x1d,0x77,0xc5,0x63,0x0b,0x54,0xde,0xa8,0x0d,0xc4,0x16,0xe3,0x89,0xeb,0xa3,0x1b,0xd4,0x77,0x13,0xe3,0x55,0x98,0x15,0xab,0x3b,0x32,0xc8,0xd4 +.byte 0x0c,0x91,0x80,0x57,0xf7,0x1e,0x24,0xd0,0x56,0x78,0x29,0xd2,0x03,0xe7,0xc4,0xd2,0x09,0xca,0xee,0x9b,0x60,0x5f,0xa1,0xfd,0xaa,0x85,0x4b,0x68,0x35,0xa4,0x3b,0xef,0x29,0xb8,0x49,0x85,0xee,0xbb,0x39,0xc0,0xc6,0x99,0x97,0xc6,0x86,0x6c,0x27,0xf9,0x1a,0x19,0x6e,0x7c,0xae,0x75,0x41,0x0d,0x08,0x1e,0xf0,0xb4,0xc3,0x9e,0xdb,0x40 +.byte 0x86,0x94,0x9d,0x90,0x09,0x3f,0xdc,0xb9,0xfc,0x59,0x41,0xc5,0x5b,0x89,0x97,0x49,0x4a,0x1a,0x06,0x68,0x83,0xd8,0x7e,0x09,0x51,0xe1,0x86,0xd8,0x88,0xbe,0x8a,0x36,0x48,0xb3,0x83,0x7b,0x57,0xdd,0x8f,0x18,0x67,0x4a,0x7d,0x68,0xab,0xb9,0x05,0xf0,0xe4,0x27,0x4e,0x33,0x44,0xa7,0x13,0x04,0x94,0xc5,0x57,0xaf,0x36,0x03,0xe8,0x09 +.byte 0x36,0x5b,0xe8,0x92,0xad,0x0a,0x79,0x02,0x24,0x43,0x62,0xc7,0xa5,0xce,0x7c,0xac,0x6d,0x0a,0xf2,0x83,0x33,0x05,0x3b,0x6f,0x9d,0xda,0x96,0x9f,0x8b,0x79,0x3e,0x6c,0xd6,0xba,0x7f,0xea,0x84,0xd8,0x23,0xb6,0x92,0xc3,0x9c,0x7f,0x0d,0xcb,0x7b,0x9f,0xbd,0xc2,0xf5,0x6f,0x71,0x67,0x5f,0x0b,0xd1,0x73,0xb5,0x8c,0x46,0x07,0xcd,0xd8 +.byte 0xee,0x28,0xcf,0x8f,0x8e,0x5c,0xde,0x14,0x78,0xc7,0x60,0xd5,0xf4,0x49,0x97,0x46,0x5f,0x49,0x4a,0xb4,0x8f,0xc9,0xd1,0x52,0x34,0x01,0x29,0xa1,0x46,0x55,0xf8,0x29,0x53,0xbb,0x32,0x1e,0x4b,0x89,0x96,0x53,0x0b,0xf2,0x16,0xf9,0xa7,0x70,0x93,0x59,0x78,0xc0,0x77,0x78,0x9f,0x6c,0xb3,0x0e,0x3f,0x6f,0x40,0x09,0x1d,0xd6,0x66,0x4e +.byte 0xe8,0xb0,0xa1,0x14,0x65,0xc8,0xc7,0x3f,0xd2,0xf0,0x1f,0xfd,0x51,0xe0,0x29,0xd6,0x39,0x26,0x60,0xfe,0x62,0xc2,0xe4,0x45,0x6d,0x01,0xdb,0xd3,0x7c,0xdf,0x48,0x10,0x2f,0xf2,0x8e,0x6c,0xc6,0x58,0xc3,0x7d,0x26,0xb1,0x9d,0x52,0x02,0x2a,0x5f,0x2b,0x57,0xca,0x84,0x9d,0x74,0x31,0x01,0x0f,0xda,0x3d,0x7c,0xbb,0xdc,0x71,0x82,0x8b +.byte 0x42,0xaf,0x49,0x9e,0x2c,0xe8,0xdc,0xa1,0xfb,0x23,0x6d,0xdb,0xdc,0x36,0x01,0xc9,0xb3,0x93,0xd4,0x2e,0x8b,0xd1,0xe4,0xed,0x1b,0xd0,0x4c,0xeb,0xaf,0x96,0x57,0xde,0xee,0x90,0xf4,0xa7,0x58,0x46,0x8a,0xd4,0xa9,0x44,0xe0,0xb3,0x13,0x96,0xb2,0x8a,0xb0,0xd3,0xbe,0x71,0x38,0xb7,0x35,0xa9,0xa8,0x48,0x37,0xa3,0x11,0x0e,0x61,0x36 +.byte 0x6c,0xaf,0x6c,0xf2,0x3f,0xd6,0x55,0xb3,0xa5,0xe0,0xaf,0x18,0x6a,0xf5,0x78,0xb5,0x7c,0xc7,0x48,0x24,0x6c,0xea,0x1e,0x7f,0x52,0xb4,0xe8,0x72,0x46,0xd2,0xbd,0x1c,0x9e,0xe6,0x5b,0x3e,0x9c,0x6c,0x6c,0x6b,0x45,0x0c,0x3a,0xb7,0x67,0x3c,0x8e,0x77,0x77,0xbf,0x50,0xb6,0x30,0x6e,0xe1,0x28,0x0d,0x2a,0x85,0x44,0xf8,0xbb,0xf1,0x14 +.byte 0x89,0xaa,0xc2,0x27,0xf5,0x8e,0xa1,0xd3,0x07,0xba,0xe8,0x03,0xcf,0x27,0x1c,0xa6,0xc4,0x63,0x70,0x40,0xe7,0xca,0x1e,0x05,0xb7,0xb7,0xdc,0xc0,0x07,0x4c,0x0d,0x21,0x12,0x60,0x02,0xe3,0x86,0x65,0xe7,0x1c,0x42,0x86,0xdd,0xdb,0x7f,0x26,0x60,0x01,0x3d,0xd8,0x18,0xcd,0x7a,0x9f,0xf8,0xb2,0xf6,0x6d,0xd3,0xe0,0x57,0x1f,0x80,0x30 +.byte 0x2d,0x5e,0x71,0xdf,0x4d,0x7f,0xcd,0x63,0x77,0x19,0x5e,0x2d,0xd5,0xb5,0xfa,0xa9,0x26,0x02,0xb9,0x62,0x2b,0x57,0x80,0x0a,0xe9,0xbc,0xa4,0x3b,0xa7,0xf1,0xf3,0x77,0x2b,0x6b,0x41,0x5e,0xf7,0xe8,0x66,0x23,0x63,0xac,0xcd,0x58,0xfc,0xa9,0x97,0x6b,0x5a,0x1e,0xe5,0x7d,0xfd,0xb1,0x42,0x7f,0x99,0xdd,0x60,0xaf,0x39,0x46,0x36,0xdd +.byte 0xc2,0x70,0x83,0x53,0xd1,0xc3,0x69,0xc8,0x90,0x0e,0x2b,0x34,0xb2,0x0c,0xb9,0x7a,0xb8,0x6b,0x7c,0xc2,0xf3,0xae,0x41,0x24,0xb8,0x94,0x5f,0xdd,0xce,0xda,0x95,0xda,0x49,0x81,0xb6,0xf8,0xa9,0x8e,0xb3,0x79,0xf8,0x55,0xf9,0xcf,0x8c,0x24,0x99,0xfc,0x6b,0x15,0x0f,0x39,0xac,0xd0,0x3e,0x89,0x9d,0xc2,0x46,0x8c,0x99,0x45,0xfd,0xce +.byte 0x13,0x4c,0x9c,0xc8,0x80,0x87,0x8f,0x7b,0x28,0xe3,0x5e,0x2b,0xe3,0x89,0x7e,0x13,0x52,0x52,0xe9,0x3a,0xed,0x33,0xe7,0x28,0xc7,0x7a,0x48,0x8d,0x0e,0xee,0x24,0xc4,0x61,0x04,0x3c,0xd4,0x7e,0xf3,0x30,0x22,0x07,0x58,0xae,0x02,0xc5,0xd1,0x7d,0x04,0x18,0xca,0xd6,0x04,0xd4,0xc5,0xa4,0xff,0x8d,0x0d,0x68,0xd4,0x1a,0x3a,0x72,0x6f +.byte 0x41,0x1e,0xda,0xc0,0x97,0x7c,0x55,0x2c,0x13,0x20,0x9a,0x07,0x35,0xcc,0xc5,0x83,0xee,0x41,0x77,0x51,0x28,0x07,0xe0,0x81,0xe3,0x9b,0x1f,0xdb,0x73,0x5c,0x8d,0x82,0xa2,0x8b,0xf4,0x92,0x4f,0x70,0xa8,0x6a,0xcf,0xbf,0xcf,0x0b,0x71,0xbc,0xeb,0x81,0xb4,0xc9,0x65,0xe7,0x43,0xef,0x25,0x45,0x27,0xea,0xcd,0x60,0x68,0xcd,0x2d,0x7a +.byte 0xfd,0x88,0x6d,0x06,0xd5,0x92,0x32,0xc3,0x18,0x88,0x64,0xa7,0xde,0x39,0xeb,0x0b,0x5c,0x9c,0xf6,0xf6,0x93,0x90,0x24,0x0c,0x9e,0x0b,0x89,0x1c,0xcb,0xc8,0x96,0x72,0x17,0xae,0x46,0x61,0x69,0x6e,0xbe,0x6c,0xf1,0xa4,0xa4,0x50,0xa9,0x2a,0x47,0xd7,0x80,0xe4,0x72,0xd2,0x3f,0x1a,0xdd,0x82,0xdc,0x12,0x66,0x10,0x26,0x15,0x80,0x56 +.byte 0x4d,0xbe,0x02,0xae,0xe1,0x24,0x8a,0x41,0x52,0xc8,0x5d,0x8d,0x62,0x85,0xbe,0x7c,0x35,0xdd,0x88,0xd3,0xf5,0xf7,0x9b,0xf1,0x5a,0x4e,0x70,0x48,0x31,0x5a,0xaa,0x96,0x1e,0xf8,0x73,0xb4,0x0f,0xb2,0x82,0xf4,0x13,0xac,0xba,0x3b,0x12,0x36,0x1e,0x23,0xbf,0x09,0x8a,0x1c,0x96,0x47,0x56,0x2d,0x16,0x24,0xc3,0x23,0x65,0xe2,0x99,0xd0 +.byte 0xf0,0xa0,0x2c,0x64,0x35,0xad,0x16,0x34,0x67,0x52,0xbc,0x8f,0x17,0x90,0xf9,0xc7,0x4f,0x64,0x6c,0x75,0x3f,0xd7,0x48,0xa4,0x6b,0x43,0xe6,0x2e,0x7a,0xe3,0x79,0xe8,0x47,0x51,0xe9,0x52,0x36,0x30,0xa4,0x24,0x89,0x00,0xd5,0x77,0xbd,0x34,0x2e,0xa9,0x74,0x02,0x25,0xc0,0x0c,0x10,0x31,0xf0,0xa7,0xcb,0x01,0xed,0x43,0x70,0x15,0xe6 +.byte 0xda,0x01,0xb4,0x7a,0x13,0xbc,0xf1,0x57,0x34,0xb1,0xb7,0xb3,0x26,0x18,0x5f,0x42,0x6b,0xcb,0x78,0x25,0x48,0xe9,0xe6,0xe8,0xf5,0x45,0xa2,0x61,0x97,0x10,0xa5,0x7e,0x7a,0x48,0xf3,0x23,0xa5,0x88,0xc0,0xc4,0xc7,0x3b,0x5c,0x0c,0xfc,0xe0,0xf4,0x68,0x64,0xc6,0x9f,0xd9,0x17,0xcb,0xe5,0xba,0x4a,0xa4,0xe0,0x27,0xf8,0x2b,0x4e,0x67 +.byte 0x13,0xab,0xd2,0xce,0xbc,0x8d,0xdf,0x6e,0x49,0xaf,0x72,0x8a,0x51,0xa1,0x78,0x38,0x0a,0x58,0x2e,0x72,0xec,0x94,0x70,0x8d,0xdf,0x0b,0x5a,0x52,0x81,0xb1,0x9b,0xda,0x2c,0xd2,0x85,0xbb,0x8f,0xb0,0x99,0x64,0x24,0xbe,0x03,0xd9,0x92,0x8d,0x29,0xf3,0x41,0x9c,0xd6,0xef,0xef,0xb2,0x5c,0x22,0x90,0xff,0x27,0x4d,0xb3,0x91,0x72,0x9f +.byte 0x42,0xca,0x66,0xc5,0x66,0xb7,0x50,0x3e,0x83,0x6f,0x2d,0xe3,0x7b,0x2a,0xc4,0x5a,0x93,0x92,0x80,0xdb,0x1a,0xdd,0xef,0xfd,0x96,0xcb,0x6a,0xd8,0x4a,0xc5,0x6e,0x36,0x4a,0xe4,0x10,0x15,0xb3,0x12,0xb4,0xd9,0x9e,0x37,0x48,0x96,0xcb,0xe5,0x3a,0x4f,0x57,0xa6,0x46,0x2f,0xd3,0x06,0xb8,0x61,0x1c,0x17,0x3a,0xb8,0xad,0x40,0x50,0x57 +.byte 0x10,0xd9,0xd0,0xe9,0x1b,0xe3,0x18,0x8c,0xc4,0xfa,0x08,0x8d,0x82,0x3c,0x22,0x22,0x1b,0x97,0x64,0xa6,0x8b,0x7c,0x70,0x2b,0xa0,0xd8,0x4c,0x64,0xcf,0xbc,0x49,0x78,0xcb,0x92,0x0f,0xe1,0x60,0x12,0x4e,0x92,0x0d,0xaf,0xa4,0x1f,0xe0,0x2a,0xa5,0x69,0xc6,0xa1,0x91,0x5c,0xdd,0xb8,0xae,0xfa,0xc5,0xb9,0x18,0x31,0x81,0x32,0x6e,0x97 +.byte 0x44,0x2a,0xda,0x58,0xcd,0x9e,0x0d,0x57,0xe0,0xe3,0x5f,0x7b,0x04,0xd8,0xc8,0x68,0xf5,0xa2,0xac,0x0c,0x29,0xf0,0x7e,0xff,0x32,0xfb,0x53,0x1a,0xc2,0xe3,0xae,0xa5,0xe4,0x9c,0x50,0xaf,0xf4,0xde,0x0b,0xdd,0x4d,0xfa,0x65,0x3c,0xbe,0x3c,0xb8,0xda,0x88,0xd9,0x6c,0x55,0x58,0xe1,0x4d,0x00,0xa8,0x1e,0xe2,0x3a,0x9c,0x53,0x9b,0xca +.byte 0xb7,0x5d,0x3a,0x83,0xe0,0xbb,0x95,0xc4,0xd5,0x45,0x48,0xdc,0x12,0xab,0x24,0xfc,0x5d,0x91,0xe1,0xc8,0x0a,0x5c,0x10,0xc4,0xc9,0xaf,0xb6,0x54,0x80,0xfd,0xa0,0x70,0xb9,0xab,0xdf,0x34,0x9f,0x5c,0xff,0xde,0x8e,0xa0,0x0b,0x21,0xcf,0x28,0xc4,0xdf,0x67,0xb5,0xc0,0x20,0x49,0x0c,0x7e,0xe6,0xf7,0x41,0x6b,0x75,0xd9,0x1d,0x3b,0x49 +.byte 0xb7,0x4f,0x01,0xd1,0x20,0x62,0x15,0x1e,0x9f,0x16,0xb0,0xbd,0x30,0x09,0x05,0x00,0x0f,0x25,0x5a,0x37,0xe9,0xa6,0xc6,0xef,0xe5,0x39,0x2b,0xd7,0x6b,0xc5,0x96,0xd2,0xad,0x46,0xaf,0xd3,0xc0,0xfd,0xea,0xff,0x4c,0xaa,0x44,0x48,0x9a,0xdb,0x99,0x44,0x3f,0x4a,0xf0,0x3f,0x81,0x75,0xf2,0x79,0x31,0x3c,0xed,0x56,0xc6,0xf0,0xf1,0x8c +.byte 0xdb,0x1d,0x6c,0x6c,0xcc,0xfb,0xc2,0x30,0xf6,0x24,0x14,0x69,0xc4,0x89,0x4d,0xd0,0x10,0x77,0x37,0x00,0xe8,0xc9,0xf2,0x32,0xf1,0x43,0x8b,0xe1,0x09,0xc4,0x59,0x17,0xf9,0x20,0x2b,0x01,0x76,0x20,0xb8,0x03,0x84,0xf6,0xd7,0x2e,0xef,0x20,0xa6,0xfa,0x8b,0x74,0x7f,0x4a,0x14,0x33,0xad,0xac,0x45,0x66,0x18,0x2b,0x6b,0xd2,0xb8,0x20 +.byte 0x1a,0xff,0xca,0x25,0x69,0xfd,0xba,0x4b,0x5b,0x9c,0x38,0x35,0x4c,0x30,0xa2,0x24,0x3d,0xbb,0xd4,0xf3,0x67,0x24,0xa5,0x93,0xc6,0xf5,0xb2,0xb4,0xa5,0x04,0x53,0xb6,0xe4,0xc7,0xdc,0xf1,0xe5,0x43,0xb7,0x73,0xaa,0xab,0x5c,0xea,0xcb,0xf1,0xeb,0x5b,0x04,0x7a,0xff,0x0f,0x5e,0xb4,0xd3,0x2a,0x39,0x50,0x1b,0x54,0x1f,0x32,0xd7,0x7c +.byte 0xea,0x3f,0xee,0xa5,0xc8,0x46,0x48,0x7e,0x75,0x60,0x7a,0x42,0x42,0xd3,0x15,0x07,0x69,0x46,0x1c,0xe2,0x21,0x31,0x94,0x31,0x24,0x9e,0x39,0xab,0x7a,0xf9,0xc2,0x0b,0x2d,0x6b,0x55,0xa3,0x36,0xb2,0x65,0xf2,0x17,0x08,0xde,0x15,0x83,0x07,0x36,0x12,0x54,0x8f,0x0b,0x23,0xa8,0x7e,0xb5,0x57,0x1c,0x9e,0x29,0xd7,0xd4,0x9b,0xc1,0xf6 +.byte 0x94,0x23,0xf3,0x92,0xbf,0xba,0xc8,0xf5,0x78,0x3e,0x67,0x48,0x14,0x3b,0xd4,0xe9,0x8f,0x78,0xc1,0x4b,0x9a,0x59,0x08,0xaa,0x50,0xf4,0x9d,0xc4,0xc3,0x2c,0xbc,0x56,0x2c,0x13,0x30,0x75,0xfb,0xed,0x48,0xab,0x90,0xec,0x64,0x18,0xb5,0xd5,0xb5,0x7f,0xc1,0x7f,0x83,0xf2,0xdb,0xae,0xde,0xf5,0xb5,0x29,0x03,0xbe,0x80,0xb1,0x5d,0x97 +.byte 0xd3,0x7a,0xa4,0xd0,0xe0,0xce,0x04,0xda,0xaa,0x82,0x19,0xc9,0x02,0xb7,0x1c,0xe1,0x66,0xd9,0x3e,0x86,0x6d,0xb5,0xd1,0x35,0x63,0x8e,0x4b,0xc6,0x58,0x41,0xf9,0xb7,0xba,0xf3,0x06,0x91,0xb7,0xa2,0xfb,0xb5,0x5f,0x53,0xf3,0xe0,0xc1,0xf6,0x91,0x66,0xc7,0x93,0x3a,0x0a,0x72,0xb1,0xed,0x36,0x9d,0xde,0x21,0xdd,0x7d,0x0a,0x7b,0x35 +.byte 0x1f,0xc3,0x56,0xde,0xbb,0xcb,0xb2,0x0a,0xb6,0x84,0xce,0xa1,0xc6,0x1a,0x46,0x2f,0x9f,0x48,0xd5,0x98,0x73,0xa4,0xbd,0xbd,0xa3,0xe9,0xc9,0xc4,0x64,0x89,0xb7,0x9c,0x97,0x7c,0x2f,0x88,0x22,0xe4,0x4b,0x71,0x3d,0x2a,0x47,0xee,0xf8,0xfe,0xe0,0xf7,0x03,0x14,0xe6,0x7c,0x9e,0x57,0xbb,0x8e,0xf5,0xea,0x63,0xfc,0x5b,0x18,0x3b,0xa2 +.byte 0xa1,0x4a,0x28,0x82,0x37,0x77,0x5b,0xc4,0xd3,0xc1,0xf2,0x87,0x13,0x2b,0x2a,0xc8,0xac,0x70,0xe1,0x82,0x38,0x9c,0x12,0xa0,0xc4,0x9e,0x6b,0xac,0x33,0x8a,0xe9,0x31,0x6f,0xa1,0x76,0x94,0x48,0xcf,0xbc,0x78,0x22,0x82,0x6a,0xb0,0xb9,0x49,0x71,0xdb,0xde,0x8b,0x90,0x09,0x82,0x4d,0x79,0x17,0xe8,0xcf,0xd8,0x50,0xc3,0x08,0x07,0x81 +.byte 0x5f,0x9a,0x72,0xce,0x0a,0xe4,0x29,0xc9,0xdd,0x95,0x67,0x58,0xa1,0x14,0xec,0xcf,0x2f,0x29,0xcf,0xce,0xb3,0x35,0x54,0x77,0x67,0x56,0xec,0x95,0x68,0xee,0xbf,0x9c,0x9f,0x74,0x78,0x12,0xd5,0x30,0x83,0x28,0xd5,0x36,0x96,0x57,0xa0,0x8d,0x1c,0x99,0x19,0x04,0xaf,0x25,0xe5,0x71,0x83,0x88,0xb0,0x74,0x38,0xdd,0x8a,0xff,0x39,0x7a +.byte 0xfd,0x34,0x8f,0x9c,0x67,0xa8,0xc8,0x6f,0x13,0x5d,0xf2,0x5b,0x22,0xd3,0x8e,0x63,0x51,0x58,0x9b,0xfc,0xaa,0x89,0x65,0x4e,0x36,0xc4,0xa7,0xef,0x98,0xf9,0xaf,0xcd,0x35,0x8c,0x16,0xbc,0x70,0x4f,0xcd,0x71,0x2a,0xf4,0x13,0xb3,0x3d,0xa3,0x92,0x71,0x45,0xe5,0x9a,0x45,0xbd,0xc5,0x1d,0x82,0x60,0x3a,0x97,0xf3,0x0f,0x96,0x21,0x3d +.byte 0xe5,0x6e,0xfb,0x9d,0x9b,0xeb,0x15,0xc2,0xa6,0x73,0x76,0xf2,0xcd,0xec,0xfd,0x0f,0xf4,0x3f,0x46,0xc9,0x9c,0x73,0xa1,0x21,0x08,0xdc,0x31,0x00,0xaa,0x95,0x07,0xf0,0x3d,0x51,0x57,0xfa,0x6b,0xc3,0x8e,0xe9,0xa4,0x65,0xdc,0xff,0x57,0xb9,0x1f,0x4f,0xc6,0x6d,0x03,0x00,0xa7,0x19,0xb8,0x24,0xb5,0x3d,0x87,0xcb,0x84,0xb7,0xf5,0xfe +.byte 0x51,0x16,0x5b,0xc7,0xed,0x4b,0xff,0xa3,0x66,0x17,0x93,0x60,0x69,0x84,0x8c,0x95,0x74,0xa7,0x30,0x2d,0x09,0xf7,0x4e,0x0e,0x2f,0x99,0xda,0x46,0x34,0x0f,0x93,0x90,0x97,0x4c,0xa6,0x25,0x15,0xb8,0x6f,0x1d,0xd5,0xe1,0xc1,0x39,0x50,0xfd,0xd5,0x79,0x4f,0x04,0x2f,0x76,0x50,0x3f,0x67,0x56,0xad,0x02,0x82,0x30,0x1a,0xaa,0x6e,0xe2 +.byte 0x05,0x6a,0x93,0xb7,0xbe,0xde,0x84,0xce,0xd8,0x53,0xed,0xad,0x95,0xab,0x45,0x1f,0x4c,0x3b,0x22,0x36,0x27,0x45,0x19,0xa4,0x7f,0x12,0x20,0x6c,0x9d,0xeb,0xd2,0xfe,0xd6,0x7d,0x25,0xf9,0xe3,0x64,0x77,0x56,0x89,0x12,0x57,0x80,0xd5,0x40,0xbb,0x2a,0xcc,0xac,0x34,0x8e,0x87,0xfd,0x58,0xc3,0xbd,0x92,0x48,0xd8,0x7f,0xc4,0x39,0x6a +.byte 0x4e,0x1c,0x50,0x93,0xef,0xae,0x81,0x93,0x50,0x95,0x6e,0x46,0x7c,0xf5,0x27,0x44,0x6c,0x21,0x06,0x49,0x89,0x7e,0xf4,0xfa,0x08,0xa5,0xbc,0x0a,0xbd,0xb6,0x7b,0x55,0xac,0x87,0x19,0x33,0xfa,0xab,0xf3,0x15,0xc9,0x1b,0x83,0xf2,0x41,0xf1,0x26,0x6f,0xdf,0x15,0x60,0xdb,0xa6,0x03,0x43,0x3e,0x34,0x7a,0xa9,0xb1,0x38,0x57,0xe4,0x09 +.byte 0x1a,0x4a,0xd8,0x6e,0x28,0xee,0x7d,0x74,0x54,0x03,0xb3,0x29,0x24,0xb3,0xf0,0xc6,0x20,0x7c,0x47,0x01,0x66,0x36,0x7a,0x14,0x18,0x09,0xd6,0xaa,0xa6,0x82,0x5b,0xe4,0x0a,0xf9,0x41,0x52,0x3b,0x56,0xa2,0xf8,0xa2,0xa1,0x2b,0xe0,0x0d,0x1f,0x5b,0xe4,0x0e,0xe1,0x94,0x84,0x6f,0xed,0x2e,0x11,0xfa,0x4a,0xbd,0x41,0xf4,0x3c,0x8c,0x7e +.byte 0x94,0x46,0xec,0x79,0x81,0xb0,0x36,0xfd,0x9c,0x73,0x0f,0x84,0x1a,0x59,0x4e,0x1b,0xd5,0xd1,0x0d,0xff,0xfd,0xb7,0xfb,0x73,0x35,0x8a,0x66,0xed,0xf3,0xee,0x6d,0xf7,0x86,0x0a,0xb9,0xc0,0xf1,0xa3,0xb7,0x32,0x49,0x01,0xe8,0xcd,0xfe,0x82,0x7b,0xf6,0x46,0xd8,0x73,0x47,0x8b,0x7b,0x6e,0x31,0x92,0x0f,0x4b,0x16,0x11,0x86,0x1d,0x02 +.byte 0x5d,0x12,0x79,0x59,0xdc,0x8c,0xaa,0x1b,0xc1,0x75,0x63,0xb2,0xd6,0xbf,0x19,0xb0,0x81,0x70,0x34,0x12,0xd2,0x09,0xbe,0x6d,0xa1,0x31,0x77,0xd2,0x9b,0x59,0xdc,0xcb,0x67,0xb5,0x14,0xcd,0x37,0x31,0x2c,0xa6,0x17,0x58,0x2b,0x24,0xfc,0x2a,0x9e,0x8f,0x38,0x38,0x7a,0x80,0xda,0x8b,0x54,0x1d,0xc9,0x99,0xc7,0x1f,0x98,0x7a,0x1f,0x32 +.byte 0x23,0x1c,0xb5,0x6e,0x53,0xd3,0x61,0xe7,0x78,0x19,0x6c,0xd5,0x2f,0x85,0xde,0xd1,0x67,0x6b,0x9b,0xa1,0x09,0x87,0x5e,0x89,0x5e,0x89,0x21,0x36,0xf2,0x94,0xc1,0xfd,0x6c,0x4e,0xd9,0x6b,0xd2,0xb1,0x1b,0x48,0x37,0x9a,0x7b,0xc9,0x52,0xfd,0xe2,0x6d,0x07,0x19,0xf2,0xa5,0x69,0xdc,0x0b,0x52,0x8f,0xb3,0x87,0x03,0x1a,0xd8,0x43,0x20 +.byte 0x68,0xcf,0x08,0xcc,0xce,0x37,0xf6,0x96,0x7f,0x03,0x62,0xb2,0xce,0x6a,0xfb,0x22,0x54,0xd6,0xfc,0x84,0x5c,0xf5,0x55,0x32,0x36,0x77,0x1d,0x15,0x6a,0x2c,0x3a,0x01,0x34,0xff,0x5b,0x7f,0x3f,0xab,0x97,0x8f,0xbd,0x1d,0x07,0xb9,0x47,0xb1,0xcc,0xc0,0xdf,0x17,0x38,0x54,0x07,0xc0,0x1b,0xb9,0xa2,0x29,0xa6,0x25,0x73,0x32,0x4d,0x5e +.byte 0x51,0x60,0xb3,0x27,0xe5,0xb6,0xdb,0x56,0x81,0x95,0x03,0x7e,0xca,0xc6,0x15,0x8f,0x48,0xd4,0xac,0x71,0x41,0xdc,0x9c,0x86,0x5d,0xd8,0x90,0x90,0x54,0xdd,0x3d,0xf3,0xa8,0xbb,0xe5,0x55,0x69,0x26,0xdf,0xd1,0x8e,0x75,0x2a,0xe4,0xfe,0xe0,0x80,0x1d,0x6b,0xd2,0x8a,0x06,0x49,0x4e,0x60,0xf8,0xbd,0x3d,0x99,0x27,0x80,0x27,0x42,0x66 +.byte 0x01,0x32,0xe1,0x9e,0xa6,0xde,0x7b,0x14,0xa4,0x49,0x68,0x70,0xbe,0xa4,0xe1,0x44,0x2e,0xce,0xa3,0xe9,0x1d,0x7a,0xbd,0xf1,0xe4,0x25,0x11,0x47,0xd8,0xaa,0x32,0x34,0xf8,0xca,0x3d,0xec,0xf3,0x5d,0x8a,0x55,0xe7,0xd4,0x7c,0xfb,0xcf,0xe7,0xa6,0x13,0xaa,0x16,0x5f,0xaa,0x02,0x19,0xdd,0xf1,0xf8,0x5c,0xb2,0x1e,0x68,0x9a,0x21,0x93 +.byte 0xd1,0x38,0x31,0xbb,0x26,0x76,0x44,0xf8,0x84,0x3b,0xf5,0xd1,0x52,0xbe,0x1b,0x8e,0x4d,0xa0,0xb4,0x4a,0x5a,0x7e,0x89,0xe5,0x36,0xb0,0x76,0x77,0xc5,0xc2,0x22,0x73,0xc2,0x19,0x12,0x7f,0xdf,0x9c,0xb8,0xc0,0xf5,0x0e,0xd5,0xa3,0x55,0xae,0x61,0xf8,0xf1,0x6b,0x79,0xc8,0x2e,0xbc,0xa5,0xef,0xd4,0xb1,0x84,0x0c,0x15,0xc4,0xed,0xb3 +.byte 0x18,0x29,0xd6,0x31,0x83,0x79,0x30,0x1a,0x8f,0xf0,0x3b,0xe9,0xd1,0xf2,0x1d,0xec,0xcb,0xe8,0xc5,0x1c,0xb5,0xcb,0x8e,0x01,0xd1,0xb2,0x86,0x43,0x33,0x95,0x70,0x7e,0x75,0xa9,0xa1,0xe7,0xcb,0xd9,0xf4,0xd3,0xe1,0xe2,0xe9,0x46,0x21,0x20,0x3b,0xe9,0x48,0x1c,0x3f,0x93,0x57,0x31,0xeb,0x15,0x9c,0xa7,0xa6,0xcb,0xb5,0xb7,0xa7,0x24 +.byte 0xbe,0x66,0x4c,0x92,0x7c,0xe8,0x8e,0x3f,0x9c,0xa9,0xd7,0xad,0x73,0x68,0x19,0x19,0xd4,0xb5,0x57,0x82,0xdc,0x67,0x3c,0xec,0xac,0x06,0xec,0x86,0x9b,0x65,0xff,0xbb,0xc3,0x90,0x48,0xdb,0x52,0xcc,0xa4,0xf5,0xdf,0x2c,0xc5,0x5a,0xe3,0x30,0xed,0xad,0x37,0x40,0x8c,0xaa,0x32,0x4f,0x94,0x1e,0x14,0x59,0x48,0x1d,0xd3,0xaf,0x80,0xe7 +.byte 0xcf,0x6b,0xa7,0x70,0xe7,0x98,0x22,0x4b,0x40,0x02,0x0c,0x29,0x09,0x0a,0x53,0xf7,0xd4,0xeb,0xbb,0x75,0xb4,0x30,0x1c,0x67,0xea,0xd2,0xb5,0x40,0xfe,0x57,0x2c,0x3c,0x44,0x8d,0x8d,0x02,0x78,0xf0,0x76,0x8f,0x92,0xab,0xb4,0xc9,0xc0,0x2f,0xf5,0xde,0xa7,0x09,0x14,0xf1,0xe5,0x34,0xeb,0x86,0xfa,0xcf,0xcc,0x85,0x1c,0x9c,0xa6,0xe1 +.byte 0x72,0x9e,0xc1,0xe4,0x74,0xc4,0x96,0x5d,0xf4,0x4b,0x23,0x4f,0xa5,0x32,0xff,0x38,0x21,0x8f,0x43,0xe5,0x96,0x20,0x3c,0x78,0xb8,0xb4,0xcd,0x29,0x62,0x84,0x59,0xb5,0xb4,0x57,0x07,0xa8,0x79,0x77,0x21,0xf4,0x82,0xa7,0xb1,0x36,0xee,0x16,0x8e,0xb5,0x9a,0xf7,0x03,0xac,0x64,0x03,0x20,0x48,0x24,0xbc,0xbb,0xec,0x50,0xed,0xa1,0xf3 +.byte 0x67,0xd9,0x34,0xe1,0x0c,0x0b,0xc3,0xd0,0x46,0x0b,0x55,0x85,0x59,0x3c,0xb4,0x7d,0xd0,0xc2,0xe7,0x95,0x24,0x1f,0x53,0x76,0xf1,0x81,0x4a,0x61,0x6a,0x2e,0x3b,0x3f,0x92,0x14,0x7c,0xe0,0x33,0x7f,0xb4,0x85,0x92,0x78,0x0c,0x0b,0xe7,0xbd,0x7a,0x08,0x31,0x7d,0x47,0x3b,0xfa,0xdd,0x90,0x9e,0xf0,0xa9,0xd1,0xa7,0x7c,0x2a,0x37,0xb1 +.byte 0x23,0x71,0x34,0xa0,0x63,0xfb,0x9e,0x8f,0x39,0x00,0xa0,0x09,0xd4,0x1f,0xf4,0xba,0x2d,0xc1,0xac,0x6c,0x94,0x18,0x56,0x3e,0x89,0x92,0x63,0x10,0x5e,0xfe,0x76,0xec,0x4e,0xb6,0x5d,0x59,0xf9,0x94,0x46,0x4f,0xda,0xd5,0x3e,0x6c,0x48,0x49,0x7e,0x7c,0x77,0xe7,0x7e,0x22,0x31,0xb5,0x9d,0x15,0xd3,0x08,0x24,0xdb,0x67,0x98,0x6b,0xfc +.byte 0x45,0x54,0x85,0x29,0x9a,0x47,0xa5,0x60,0xe2,0x46,0x36,0x45,0x16,0x54,0xd6,0xb1,0x5c,0x38,0x45,0xf8,0x43,0x28,0x58,0x81,0xc9,0x57,0x10,0xda,0x3b,0xfc,0x3e,0xe4,0xf4,0xb2,0x16,0xb6,0x16,0x1d,0xa4,0x68,0xa6,0xe0,0x36,0xdb,0xe2,0x19,0x1c,0xce,0x9f,0x94,0xa9,0x94,0xad,0x20,0xcb,0x17,0xd0,0x92,0x37,0x75,0x88,0x0d,0xaf,0xdf +.byte 0x98,0x6d,0x19,0x9e,0x8e,0x61,0xe4,0x8c,0xfc,0x27,0x27,0x6a,0xa7,0xa4,0x66,0x7f,0x08,0x03,0xef,0x5c,0x4a,0xb7,0x89,0xa1,0xae,0xe8,0x70,0x3f,0x13,0x27,0x0a,0x7d,0x5d,0x5e,0x2b,0x69,0xb5,0x98,0x1f,0x25,0x1e,0x41,0xff,0x46,0x5a,0x25,0x1f,0xb4,0x90,0x8e,0x81,0x91,0x19,0x63,0x10,0xd4,0xa9,0xdf,0x3b,0xae,0xe6,0x63,0x1a,0xdc +.byte 0x09,0x5f,0xac,0xaa,0xb8,0x6b,0xbd,0x6a,0x90,0x70,0xce,0x2c,0x63,0x6d,0x48,0x78,0xca,0xc1,0x59,0x94,0xe2,0xc7,0x89,0x17,0x73,0xfa,0x73,0x34,0xb7,0xd3,0x9c,0x4e,0xd8,0xac,0x18,0x80,0x25,0xbf,0xbe,0x75,0x0a,0x9a,0x05,0x5e,0x54,0xcb,0xba,0xab,0xca,0x7f,0x96,0xf7,0x26,0x8c,0x82,0xe0,0x23,0xa5,0x86,0xb5,0xdf,0x31,0xd0,0x2f +.byte 0xe3,0x66,0x96,0x83,0xd2,0x04,0x43,0x8a,0x28,0x59,0x49,0xdc,0x11,0x38,0xd9,0x5f,0xc2,0x31,0xaa,0xa8,0x1a,0xff,0x57,0xf1,0x84,0x18,0x28,0xe8,0x04,0xae,0x98,0xa4,0x17,0xc4,0x35,0x75,0xf5,0x37,0xf5,0x27,0x3e,0x7e,0x32,0xa4,0xcb,0xd4,0x43,0x59,0x02,0x63,0x7b,0x7c,0x9d,0xa7,0x61,0x12,0xf7,0xdc,0x12,0xe0,0x07,0xac,0x96,0xf3 +.byte 0x71,0x43,0xe5,0x30,0xe0,0x4c,0x51,0x2a,0x19,0xf5,0x79,0x59,0x5a,0xc5,0x74,0xfa,0x54,0x18,0xb4,0xb1,0xfb,0x4b,0x9b,0xf8,0xe4,0xa4,0x63,0x25,0xc3,0x84,0xeb,0x2e,0xa1,0xf8,0xf8,0x7b,0x25,0x6a,0x7d,0x14,0x38,0x06,0xeb,0xae,0x9f,0xa5,0x80,0x9a,0x8a,0xb6,0x46,0x95,0xdf,0x52,0x11,0xd4,0x30,0xcc,0x11,0x8f,0x4a,0x5e,0x56,0x26 +.byte 0x60,0x3d,0x5f,0x0b,0x04,0x94,0xcd,0xca,0x1d,0x6b,0x83,0x51,0x83,0x8d,0xf8,0x33,0x4a,0x91,0x00,0xa4,0xf5,0x44,0x5b,0xad,0xa0,0x4a,0x72,0xaf,0xe6,0x4a,0x0d,0x1e,0x9f,0x18,0x6b,0xb4,0xdf,0x85,0x61,0x2a,0x3b,0xe1,0x4c,0xaa,0xc3,0x17,0xef,0x51,0x9f,0xae,0xb5,0xca,0xaa,0x6c,0xd9,0xa1,0xf5,0xa3,0x6f,0x1c,0xca,0xb3,0x37,0xda +.byte 0x27,0xea,0xcb,0xb7,0x36,0xb2,0x11,0xda,0x9f,0x07,0x78,0xaa,0x6c,0xad,0x63,0x9b,0x49,0x6b,0xfe,0x1f,0x93,0x82,0x73,0xc9,0xc8,0xf6,0x68,0x54,0x50,0x77,0xba,0x78,0xc7,0x82,0xee,0xbd,0x97,0x66,0xb9,0x22,0x49,0x0d,0x7a,0x1f,0x0f,0x4e,0xe5,0x02,0x8b,0xa6,0x1b,0x11,0xfc,0xa6,0x37,0x2a,0x5c,0x66,0xaf,0xac,0xa5,0x9f,0xbf,0x26 +.byte 0x98,0x9b,0x25,0x44,0x48,0x09,0xe6,0x76,0xb9,0x08,0xf1,0x37,0xcf,0x86,0xc9,0xdf,0xa8,0xf3,0x88,0x2f,0xc1,0x33,0x15,0x95,0x59,0xf7,0x9b,0xf2,0x48,0x76,0xcb,0xd0,0x31,0xe4,0x27,0x74,0x2d,0x6e,0xd2,0xc3,0x29,0xea,0xef,0xff,0x4e,0x3d,0xda,0x3e,0xef,0x94,0x94,0x40,0xcd,0x93,0xcf,0xb8,0x56,0x29,0xf8,0x20,0x20,0xa3,0x66,0x83 +.byte 0xba,0xc8,0x4f,0xe6,0x22,0x96,0xb5,0xb2,0x44,0x75,0x55,0x98,0xed,0x11,0xd0,0x58,0x50,0x26,0xf1,0x4a,0xf6,0x80,0x5c,0x17,0x92,0xba,0xc2,0xd6,0x68,0xd4,0x7a,0x4f,0xdf,0x16,0x97,0xbd,0xad,0xd7,0x1b,0x0c,0xe5,0x23,0xa9,0xaa,0xf4,0x1c,0x8d,0xec,0xbf,0xf0,0xb5,0xaa,0x49,0xfd,0xf1,0x31,0x9b,0xf9,0xe9,0x21,0xa1,0x20,0xab,0xbe +.byte 0x56,0x8c,0xf2,0x85,0xdc,0x1f,0xea,0x25,0xce,0xf5,0x6c,0x18,0x7d,0xc4,0x1a,0x01,0x08,0x01,0xed,0x02,0xa8,0xac,0x7f,0x74,0x2c,0xd7,0x28,0x25,0x6e,0x68,0x19,0x38,0x8d,0x20,0x51,0x8f,0x38,0x8b,0x03,0x36,0xae,0x50,0x35,0x28,0x65,0x7e,0x15,0x2a,0x80,0x2c,0xae,0xcd,0xb3,0xb6,0x91,0xf1,0x8c,0xf2,0x8c,0xc5,0xce,0x3e,0x3a,0x97 +.byte 0x5a,0xff,0xe1,0x37,0x13,0xf7,0x6b,0x07,0xb2,0xaa,0xaa,0x57,0x18,0xb7,0xb2,0x19,0x52,0xbf,0x59,0x0b,0x6f,0xba,0x56,0x54,0x14,0xac,0x21,0xfd,0x7d,0x03,0x4b,0x0b,0x39,0x54,0xba,0xf9,0xba,0x73,0xcd,0x67,0x13,0x30,0xca,0x19,0x80,0x4f,0x18,0xb4,0x75,0x2a,0xec,0x78,0xa7,0xd0,0x5c,0x53,0xe2,0x43,0x2c,0x08,0x5f,0x5c,0xe6,0x60 +.byte 0xde,0x04,0xf6,0x75,0xca,0x35,0x3b,0xf6,0x68,0x53,0x60,0xc0,0xed,0xb0,0x15,0xa1,0xa4,0x89,0x23,0x34,0x49,0x35,0xd2,0x78,0x4b,0x8f,0x7c,0x8d,0x59,0x22,0x9f,0xad,0x72,0x47,0x5b,0xde,0xf2,0x09,0x08,0xa0,0x8d,0x5f,0x4d,0xc3,0xd1,0x83,0x17,0xbc,0x39,0x8e,0xa5,0x53,0xaa,0xe3,0x31,0x03,0x93,0x14,0xb4,0x57,0xf0,0xdf,0x54,0x1d +.byte 0x79,0x4d,0x21,0x1a,0x8f,0x3f,0x6e,0x07,0x41,0xcc,0x2d,0x94,0x55,0x4e,0x50,0xfd,0xac,0xe3,0xef,0xa7,0x50,0x3b,0x3c,0xda,0x32,0x25,0xee,0xd9,0x01,0x37,0x8e,0xb3,0x23,0xc5,0x5e,0x12,0x88,0x6d,0xd5,0x41,0xfd,0x3f,0xfa,0x75,0xb8,0xcb,0x82,0x10,0x81,0x38,0x1b,0x10,0x2d,0x2c,0x6b,0x62,0xa1,0x7c,0xd1,0x75,0xd8,0x8c,0x0c,0x2f +.byte 0xe8,0x97,0xff,0x18,0xb3,0x12,0xa2,0xef,0x6c,0xc5,0x79,0x9f,0x64,0xf3,0xc7,0xdc,0xdb,0x54,0xa4,0x25,0xc7,0x30,0xfb,0x6c,0x5a,0x50,0x24,0xf9,0xb6,0xc9,0xe7,0xda,0x78,0xcc,0x1b,0x5e,0xf3,0xe7,0x32,0xd8,0x36,0x47,0x10,0xe5,0x2c,0xeb,0xea,0xf7,0x25,0x30,0x93,0x64,0x88,0xc8,0x59,0xf8,0x5c,0x02,0x43,0x4c,0x23,0x8e,0x1c,0x42 +.byte 0xe4,0x36,0x39,0xbf,0xba,0x8b,0xe3,0x53,0x01,0x32,0x0d,0x89,0xc2,0xea,0x35,0x94,0xf1,0x0d,0x29,0x45,0x08,0x07,0x15,0xcb,0xd7,0x3e,0x4d,0x9f,0x04,0xd8,0x18,0x8a,0x56,0xa3,0xb1,0x1c,0x46,0x19,0x8b,0xd0,0x51,0x30,0xf3,0xca,0x52,0x2a,0x16,0xc4,0x90,0xc1,0x00,0x50,0x87,0x8b,0x4c,0x71,0x61,0x48,0x69,0xb2,0xf1,0x33,0xaa,0x79 +.byte 0x81,0x8b,0x36,0x33,0x19,0x41,0x6b,0xc1,0x91,0x40,0xf2,0xcc,0x1d,0x83,0x09,0xab,0xcc,0x6f,0x6c,0x54,0x91,0x62,0x80,0xac,0xe6,0x1f,0xcd,0x5d,0x05,0x2b,0xe5,0xac,0xbc,0xd6,0x1b,0x8b,0xef,0x95,0xa0,0xf3,0xfe,0x8e,0x4d,0x32,0x77,0xe8,0x02,0x8f,0x44,0xad,0xc4,0x40,0xc3,0x99,0x68,0x81,0x47,0x15,0xbd,0x3b,0x8f,0x0b,0x9b,0x3a +.byte 0xb3,0x9d,0x8f,0x3d,0x86,0xd1,0x89,0x5f,0x67,0x19,0x33,0x2d,0x18,0x64,0x0e,0x3a,0x13,0xa4,0xe9,0xb4,0xc9,0x90,0x09,0x6a,0xcb,0x5d,0x0d,0x83,0x13,0x04,0x29,0xe5,0xa5,0xf4,0x00,0x56,0xf4,0x80,0x96,0x33,0x93,0xe4,0x9b,0xc4,0x6e,0x38,0xbf,0x0a,0xe0,0xee,0x8c,0x89,0x5d,0x60,0x36,0x7e,0x69,0xc2,0xc7,0x28,0x6f,0x2b,0x97,0xfb +.byte 0xb3,0x5b,0x82,0xe8,0x9a,0x36,0x44,0xd7,0x1f,0x9b,0x1b,0xd0,0x14,0xe4,0xd4,0x0d,0x35,0xcd,0xee,0x88,0x50,0x37,0x5c,0x88,0x09,0xa5,0x16,0x4d,0xe1,0xbc,0xe8,0x79,0x8f,0xa9,0x18,0xb8,0x43,0xb4,0xd7,0x32,0xcd,0x26,0xdd,0x78,0x29,0x59,0xad,0x29,0xe3,0xe0,0xe7,0xcf,0x16,0x03,0xc6,0x8a,0xb6,0xa2,0x09,0x9a,0x6e,0x90,0x7b,0x0c +.byte 0x9d,0x20,0xb6,0xc4,0x28,0x3f,0x44,0x06,0xa9,0x45,0x72,0x27,0xa7,0x56,0x3f,0x07,0xff,0x13,0xd9,0x80,0xda,0xbd,0x25,0xad,0xd3,0x74,0x2c,0xd8,0xd2,0x93,0xa5,0xda,0xbc,0x5f,0xa5,0xde,0xb7,0x3a,0xf0,0xd2,0x17,0xb1,0xc3,0x70,0x2a,0x85,0xde,0xf0,0x97,0x7b,0x96,0xb2,0x0e,0x45,0x7f,0x63,0xd4,0x94,0xd8,0x78,0x05,0xcf,0xea,0xb3 +.byte 0xfb,0x7a,0x79,0xb5,0x91,0x53,0xb8,0x8c,0xa2,0x03,0xf4,0xc3,0xed,0xf0,0xab,0x33,0x5c,0x6e,0xcd,0xbd,0x73,0xe3,0xe9,0xd0,0x83,0x2a,0x2a,0x68,0x32,0xf1,0x69,0x4f,0xd0,0x8b,0xe8,0xa1,0x7d,0x5b,0x0f,0x69,0xc2,0x33,0xbf,0xc1,0x54,0x29,0x47,0xed,0x9f,0xdb,0x35,0x0a,0x3d,0x2b,0x9d,0x8b,0x91,0xb6,0xe0,0xbc,0x53,0xba,0xb7,0xcd +.byte 0x2c,0xd9,0xeb,0x81,0xa0,0x2e,0x14,0x6e,0xdc,0xe1,0x90,0x36,0x14,0x9d,0xa8,0x8b,0x6b,0x1b,0xac,0x4c,0x09,0x8b,0x1a,0x87,0xf4,0x66,0xf6,0xfb,0x62,0x92,0x13,0xcf,0xb2,0x96,0xf0,0xc9,0x8b,0x12,0x99,0xf1,0x16,0xae,0x5c,0x27,0x24,0xa8,0xfd,0xb3,0x4c,0xc2,0xe6,0x3f,0xd2,0xc6,0x0c,0xf2,0x65,0x4e,0xdf,0xf1,0x06,0xb8,0x99,0xc4 +.byte 0x3a,0x35,0xba,0xed,0x18,0x3e,0xfa,0x03,0x51,0x8d,0x45,0x68,0x12,0x7b,0xb6,0xac,0x63,0x99,0x47,0xee,0x6f,0x8b,0xcb,0xc1,0x0a,0xf9,0x23,0xf0,0x05,0xe1,0x03,0x4a,0xb5,0xe0,0x65,0x71,0xc8,0x64,0x7e,0x0d,0x39,0xe7,0x96,0xdb,0x34,0x63,0x2e,0x1a,0x27,0x85,0x52,0x63,0x8e,0x44,0xfb,0x61,0xca,0x79,0xe5,0x91,0x99,0x83,0x2d,0xe0 +.byte 0x26,0x04,0xad,0x43,0x26,0xf2,0x7e,0x56,0xae,0x35,0x6a,0xfb,0xec,0xc6,0x27,0xe4,0x3a,0xa3,0x6b,0x63,0x72,0xba,0x98,0x03,0x9f,0x2a,0x4c,0xb1,0x33,0x22,0x9d,0x53,0xf6,0x00,0xa3,0x1e,0x32,0xcb,0xbe,0xe0,0xc2,0xf8,0x71,0xcd,0x3f,0xe3,0x4d,0x83,0xf2,0x9f,0x1c,0x91,0x35,0x97,0x52,0x95,0xba,0x24,0x04,0x04,0xca,0x32,0x6d,0xd7 +.byte 0x4b,0xd4,0x9e,0x8b,0x73,0x42,0xfb,0x9f,0xfc,0x93,0xea,0xc2,0x41,0x56,0xa9,0xe5,0xdd,0xd0,0x37,0x8a,0xe2,0x92,0x9f,0x45,0x4f,0xd8,0xef,0xe6,0x6f,0x58,0x41,0x5f,0x7b,0xe7,0x0f,0x32,0xce,0x06,0x02,0x7f,0xe2,0x37,0x87,0xb7,0x35,0x72,0x68,0x87,0xc9,0x35,0xa8,0x51,0xce,0xd8,0xde,0xc3,0x8c,0xb4,0xab,0xf4,0xa7,0x3b,0xcd,0xc8 +.byte 0x0a,0x56,0x5b,0x48,0xb1,0xa4,0x27,0xa8,0x9e,0x3e,0x04,0xbc,0xb3,0x63,0x3e,0xd5,0xf7,0xae,0xec,0x0c,0x6e,0x4a,0x73,0xb6,0xed,0x66,0xea,0xc1,0x7a,0xc4,0xaa,0x21,0x27,0x62,0xef,0x3d,0x1d,0x51,0x8b,0x63,0xe6,0xe2,0x8a,0xed,0x7a,0x4b,0x90,0xc3,0x9f,0x91,0xb4,0x8f,0x78,0x65,0x9c,0xdd,0x0a,0x7a,0x50,0x36,0x33,0x30,0x3b,0xb4 +.byte 0xdf,0x67,0xbd,0xfd,0x71,0xfc,0x40,0x49,0xaa,0x01,0xdf,0x68,0x67,0x73,0x31,0x2c,0x98,0x2f,0x8c,0x9e,0x2d,0xce,0x4a,0x71,0xbc,0x6f,0x90,0x1d,0xc0,0x37,0x07,0x30,0x0c,0xa3,0x04,0xfb,0xd1,0xd0,0x0e,0xcb,0xdc,0x94,0x06,0x7f,0x83,0xe5,0x45,0x47,0xd0,0x71,0x06,0x94,0x23,0x7c,0x03,0x80,0x46,0xa5,0x10,0x08,0xd1,0xdb,0xfb,0x9d +.byte 0xd4,0x05,0x01,0x5e,0x66,0x4d,0xf9,0x32,0x9b,0x5b,0xfe,0x7a,0x60,0x63,0x77,0x9a,0x31,0x34,0xe5,0x9a,0x82,0x2d,0x2b,0xb7,0xe0,0x04,0x8f,0x86,0xf3,0xb2,0x16,0x86,0x50,0x37,0x9d,0x80,0xe7,0x62,0xdf,0x77,0xda,0xf4,0xfc,0xb7,0x42,0x9d,0xac,0xcb,0x11,0xff,0x0c,0x6f,0x4e,0x16,0x0c,0x59,0x04,0x05,0x8f,0x88,0x64,0x37,0xe6,0x6c +.byte 0xee,0x64,0x58,0x79,0x60,0xd4,0x2f,0xb7,0x90,0x59,0xfb,0x82,0x3b,0x20,0x2e,0x2b,0xba,0x15,0xfb,0xf7,0x5b,0x1d,0x81,0x8a,0x8a,0x8f,0xe3,0x39,0x92,0x34,0xfc,0x3a,0x67,0xce,0xb6,0xa0,0x9b,0x56,0x78,0x96,0x4d,0x32,0xbf,0x9c,0x83,0x9e,0x19,0x66,0x20,0x42,0xb2,0x78,0x62,0x42,0xdd,0xdf,0x98,0xab,0x0c,0x3d,0x41,0xb5,0x74,0xc1 +.byte 0x2d,0xf0,0x02,0x58,0x6e,0xb3,0x4d,0x7b,0x41,0x1c,0xf1,0x09,0xc1,0xbb,0x84,0x67,0xf8,0x24,0x77,0x32,0xcd,0x7a,0x63,0x87,0x0d,0xf2,0xc5,0xaf,0xe4,0xb5,0xc6,0x3b,0xad,0x66,0x5e,0xae,0x90,0xc2,0x24,0x27,0x7a,0x0b,0xed,0x1b,0x86,0x5d,0x02,0x19,0x85,0x78,0xc8,0xb1,0xce,0xe7,0xc9,0x5c,0xce,0x43,0x58,0xac,0x1c,0x4e,0xcd,0xb8 +.byte 0x3a,0xb8,0x7a,0xf3,0x79,0x4b,0x97,0xcf,0xbe,0x88,0x24,0xd0,0x9a,0x5a,0x55,0x43,0x0c,0x48,0xa2,0x7f,0xaf,0x4b,0xd8,0x16,0x02,0xfb,0xe6,0x0c,0x6b,0x85,0xb4,0xb8,0x5e,0x40,0x60,0x5d,0x93,0x51,0xc6,0x32,0xb9,0x4a,0x23,0x96,0x71,0xeb,0xe8,0xe8,0x01,0x1e,0x85,0xb0,0x47,0xde,0x86,0x15,0x52,0x3a,0xb2,0xd3,0x86,0x4b,0x78,0x09 +.byte 0x9c,0x6e,0x9d,0xd9,0xef,0xe8,0x64,0x2d,0x2a,0xec,0x21,0x5a,0x60,0xa5,0xe4,0x26,0xbb,0x79,0x0c,0xdb,0x48,0xd6,0x4b,0x5c,0x5b,0xe3,0x34,0xc9,0x96,0xf0,0xcb,0x68,0x8a,0x2d,0xee,0xa3,0x37,0x34,0x5f,0x3e,0x65,0x40,0xce,0xe1,0xc8,0x2e,0x11,0xca,0x42,0x51,0x53,0x72,0x3d,0xa9,0x68,0x54,0xb4,0xd8,0xd7,0x72,0x84,0x8d,0xcd,0x6d +.byte 0x1f,0x0e,0x0c,0x0f,0x32,0x3a,0x7d,0xdd,0xc1,0xd3,0xe7,0x2d,0x1f,0x52,0x8b,0x73,0x86,0x70,0x2a,0xcb,0x71,0x37,0xa1,0xab,0xe3,0x94,0x5a,0xd7,0x9d,0x68,0xc1,0x6e,0x5d,0x72,0x25,0x81,0xe8,0x45,0xad,0x6c,0xf8,0xdb,0x9b,0x70,0x31,0xb9,0xf0,0x4f,0x23,0xd7,0x03,0xc8,0x87,0x43,0x51,0x7a,0x55,0xfe,0x6f,0x2d,0x40,0xbc,0xfe,0xdf +.byte 0xe6,0x21,0x4b,0x4d,0xc6,0x02,0x48,0xe7,0x7a,0x2a,0xef,0x91,0xdf,0xbc,0x98,0x91,0x6f,0x59,0xc4,0x47,0x77,0x2e,0x45,0x45,0x23,0x47,0x5d,0xf8,0x50,0x41,0x84,0x75,0x8a,0xe7,0x4d,0xfb,0xeb,0x58,0x00,0xcf,0x42,0xca,0x02,0x05,0xc7,0xfa,0x11,0xfb,0x6e,0x90,0x7d,0x53,0xa0,0x19,0x23,0x24,0x8f,0x89,0x17,0x40,0xbe,0x11,0xfb,0xd9 +.byte 0x04,0xf8,0x84,0xeb,0x90,0x7c,0x84,0x45,0x9c,0x53,0x45,0x5e,0x45,0x51,0x55,0xfc,0xf1,0x6b,0x02,0x24,0xfd,0x95,0x4a,0x40,0x80,0xdc,0xa6,0x94,0x15,0x2c,0x1d,0x85,0xa0,0x07,0x8d,0xf8,0xf2,0x95,0x0c,0xa0,0x4e,0x5a,0x5b,0x29,0x09,0xcc,0xf3,0x4e,0x8e,0xea,0xe8,0x26,0xb8,0xbe,0xb2,0x6f,0x76,0x6f,0xa4,0xe5,0x6a,0x50,0xcf,0xc8 +.byte 0x7d,0xb6,0x1e,0x9d,0x90,0x6b,0xde,0xe2,0x55,0x49,0x97,0x00,0xa5,0xc5,0x1f,0x1c,0x41,0x66,0xe7,0x6b,0x20,0xb2,0x1e,0xc7,0xb3,0xd4,0xa9,0x75,0xbb,0x83,0x24,0xd0,0xdf,0xbd,0xba,0x2c,0x2f,0xa4,0x03,0x1d,0x17,0xc5,0x74,0xc2,0x6a,0x20,0x71,0x18,0xd1,0xc5,0xb0,0x78,0xfe,0xda,0x55,0xd2,0x43,0x2a,0xd8,0x88,0x74,0x75,0x86,0x07 +.byte 0xe9,0x8b,0x0d,0x0f,0xe5,0x8d,0xe8,0x3d,0xf4,0x93,0xde,0x4c,0x97,0x98,0xe2,0x9b,0x22,0xde,0x13,0x18,0x8b,0xc5,0xe1,0x6f,0x6d,0xb4,0x19,0x46,0xff,0xbd,0xa6,0x2e,0xe6,0x48,0xcd,0x66,0x22,0x7d,0xf4,0x0e,0xeb,0x74,0x25,0x5c,0x90,0x0e,0x26,0xce,0x17,0xe9,0xdb,0x30,0xb9,0x25,0x99,0x96,0x46,0x3a,0x78,0xa3,0x76,0x2d,0x9e,0x42 +.byte 0x06,0x8a,0x1e,0x62,0x46,0xa4,0xd0,0x1d,0xe2,0x4c,0x3c,0xb4,0x4c,0xc0,0xd1,0xf7,0x05,0x5b,0xe4,0xd4,0x71,0x73,0x31,0xfc,0x98,0x2a,0x55,0xb0,0x78,0x92,0x59,0x8b,0x25,0x97,0x15,0xf2,0xf9,0x57,0x8b,0x7c,0xd4,0xc4,0x47,0x2f,0x10,0x3b,0x76,0xde,0x5f,0xb1,0xdf,0xdc,0xb0,0x15,0xd5,0x4a,0xd2,0x54,0xad,0x5e,0x32,0xf4,0x5a,0x1a +.byte 0x8d,0xe8,0xa0,0x4a,0x4e,0x04,0xdc,0xdd,0xd2,0x57,0xe5,0x24,0x4b,0x93,0x51,0xef,0xd4,0xba,0x3f,0x77,0xfc,0x0a,0x5c,0x7d,0x6e,0xa7,0x86,0xe5,0x88,0xd1,0xac,0x74,0x46,0x9a,0x39,0xb6,0x98,0x3d,0xae,0x89,0x4e,0xea,0x8d,0xdc,0xc7,0xb9,0x0c,0xd7,0xa6,0x06,0x4d,0x28,0x2b,0x51,0x2b,0xdb,0x30,0x4a,0x91,0x1c,0x40,0x89,0xe4,0xba +.byte 0x72,0xd5,0xed,0x16,0x66,0xb8,0xef,0x81,0xd9,0x51,0xf8,0x1b,0xff,0xab,0x8b,0x52,0xb8,0xf3,0x11,0xb3,0xe5,0x04,0x5a,0xb0,0x60,0xa3,0x35,0x12,0x6a,0xa0,0x75,0x5c,0x21,0xa9,0x5a,0xe8,0xd3,0xd7,0x8a,0x1f,0xe0,0x9b,0xb7,0x1e,0x7d,0xbe,0x81,0xaa,0x56,0x5a,0xd8,0x2d,0x7e,0x0c,0x60,0xb2,0x68,0x26,0x6d,0xaa,0x8b,0xcc,0x11,0x40 +.byte 0x25,0xea,0xc9,0x94,0xfb,0x3b,0x9b,0xa7,0x3a,0xde,0xd9,0xfe,0x6b,0x4b,0xfc,0x3f,0xbf,0xdd,0x51,0x9b,0xa1,0xca,0x2f,0xed,0x33,0xd8,0x3d,0x92,0xa4,0x1d,0xee,0xb2,0x47,0xd0,0x72,0x6a,0x96,0x33,0x0f,0xdd,0x0a,0xd9,0xbd,0x86,0xdb,0x25,0x53,0x0e,0x3c,0x31,0xad,0x05,0xb9,0x24,0x13,0x00,0xdf,0xc2,0x7c,0x3d,0x03,0x9b,0xf6,0x6d +.byte 0x93,0xd9,0xdf,0x73,0xf8,0x1c,0x98,0xe2,0x77,0x46,0x46,0xdc,0x07,0xe6,0xbb,0xc1,0xa7,0xb6,0xbe,0x21,0x07,0xae,0xdb,0xca,0x69,0x2d,0x8a,0x2b,0x59,0x27,0xe0,0x7c,0xf0,0xf1,0x34,0x69,0x97,0x44,0xba,0xbb,0x48,0x9f,0xd9,0xd8,0x16,0x1a,0xef,0x11,0x68,0xb6,0xaf,0x3a,0x10,0xc6,0x7c,0xd1,0x12,0xc7,0x89,0x47,0xe3,0xd1,0x24,0xc6 +.byte 0x44,0x9f,0x7e,0x6a,0x66,0x43,0x48,0xd6,0x9f,0x7b,0xf0,0x1f,0xd2,0x5f,0x2b,0xa7,0x13,0x6a,0x7c,0x70,0x08,0x38,0xb0,0x00,0xbc,0x7c,0xd3,0x01,0x9b,0xf6,0x29,0xd3,0x9c,0xa4,0x11,0x90,0xe4,0x9f,0x04,0xd6,0x21,0xec,0xfd,0xcb,0xb8,0xe6,0xb6,0x49,0x2b,0xfa,0x4b,0x90,0x9e,0xc6,0x0c,0x87,0xff,0x5e,0x2e,0xcc,0xf8,0x09,0x70,0x52 +.byte 0x42,0xec,0x88,0xac,0x1e,0x76,0x2b,0xeb,0xfc,0xb3,0x65,0x81,0x34,0xb1,0x06,0x90,0xde,0xb2,0xc4,0xd3,0xfd,0xd4,0x9c,0x78,0x1a,0x5c,0x8f,0x65,0x0a,0xbd,0x88,0xe5,0x95,0x06,0xb5,0x94,0xe5,0xbf,0x90,0x31,0xbb,0xcb,0xce,0x19,0x51,0x25,0x4a,0x47,0x35,0x26,0x93,0xdb,0xe2,0x93,0x36,0x47,0x7d,0xdd,0x4e,0xd5,0xeb,0xdd,0x63,0x1c +.byte 0xbc,0x2d,0x75,0xdb,0xd4,0xfa,0x60,0x4b,0x51,0x45,0x32,0x0f,0x01,0xf9,0x73,0x9b,0xd8,0xbc,0xee,0xaa,0x7d,0x2e,0xfe,0xbf,0x9d,0x45,0xae,0xe2,0x01,0xe3,0xbf,0x58,0xdc,0xc0,0xb8,0xe8,0x44,0x16,0x3b,0xd8,0xaa,0x3b,0x13,0xca,0xfb,0x5f,0x8d,0xb3,0x2a,0x83,0x66,0x49,0xae,0x54,0x02,0x4e,0xd8,0x68,0xee,0x21,0x1a,0xbb,0xf4,0xf7 +.byte 0xdf,0xf1,0x51,0x7b,0x62,0xa8,0xb2,0xdc,0x4b,0xd4,0x04,0xd2,0x05,0x49,0xdd,0xa4,0x75,0xe6,0x64,0x82,0xe7,0x25,0x55,0x60,0x2c,0x9f,0x8a,0x7a,0x11,0xe9,0xf2,0x72,0xfe,0x89,0xe1,0xaf,0xca,0x0c,0xb9,0xf5,0xcc,0xcf,0x07,0xef,0x8f,0xbb,0xef,0x53,0x1e,0xe2,0xfb,0x98,0xe8,0x05,0xab,0x4e,0x7e,0x38,0x56,0x24,0xd5,0x74,0x1c,0x95 +.byte 0x1a,0x0e,0x62,0x92,0x80,0x16,0x45,0x78,0x2f,0xb1,0xe1,0x83,0x24,0x2b,0x16,0x5c,0x05,0x52,0x17,0xe9,0xe8,0x9e,0x5d,0x63,0x8f,0x77,0xc4,0x89,0x22,0x76,0x43,0x31,0xfd,0x09,0xc0,0x51,0x70,0x57,0x2d,0x51,0x91,0xe5,0x61,0x3f,0x77,0xff,0x17,0xfc,0xa6,0x19,0x9d,0x82,0x46,0x11,0x0c,0x77,0x19,0x2a,0xf5,0x19,0xb4,0x3d,0xa6,0xd4 +.byte 0x8b,0x07,0x4b,0xc6,0xa3,0x1e,0x8c,0xf5,0xe8,0x2d,0xe7,0xcc,0xa1,0x38,0x57,0x66,0x76,0x1d,0xdd,0xe3,0xb9,0x0a,0x1e,0x2c,0xad,0x09,0x07,0x26,0xff,0x7a,0xc0,0xb0,0x51,0x71,0x44,0x6d,0x2c,0x39,0x3d,0xa6,0x14,0x4e,0x74,0x2c,0x54,0x3d,0xfa,0xdc,0x2e,0x0c,0xc4,0x88,0x32,0xda,0xb0,0x9d,0xf4,0x2c,0x0a,0x1b,0xb7,0xb4,0x78,0x6f +.byte 0x1b,0x6a,0x21,0x03,0x4e,0xe0,0x87,0xa0,0x1c,0xd8,0xe6,0x0c,0x97,0x47,0xde,0x98,0x81,0x3d,0x39,0x93,0x3d,0xcb,0x29,0xa3,0x93,0x8d,0x27,0x5d,0x29,0xb5,0x85,0xc4,0x32,0xd8,0xdc,0x19,0xb1,0x63,0xdc,0x76,0x32,0xc3,0x52,0x9a,0xfd,0x3d,0xff,0xf9,0x94,0x55,0x72,0xbb,0x4d,0xe2,0x42,0xd2,0xf7,0xb2,0xac,0xac,0x5d,0x50,0x95,0xda +.byte 0x3a,0x87,0xb6,0x0f,0x27,0x72,0x34,0xe7,0xe8,0x9f,0xc7,0xba,0xca,0x8d,0xf3,0xb9,0xa1,0xdd,0xd7,0xa5,0x70,0x3b,0xcc,0x72,0x0e,0x9d,0x85,0x75,0x01,0x11,0xe1,0xc2,0xca,0xcb,0x40,0x3a,0x31,0xf2,0x5d,0x0c,0x63,0xc8,0xbf,0x38,0xde,0x09,0x3b,0x32,0xaa,0x6c,0x07,0xd2,0x2b,0x3b,0x94,0x37,0xd0,0xd9,0xe0,0x4c,0x25,0xa3,0x22,0x64 +.byte 0x05,0xcc,0x69,0x9e,0x73,0xd4,0x46,0x2c,0x73,0x23,0xd0,0x6f,0x09,0xff,0x8b,0xef,0x7a,0x08,0x3e,0xa2,0xa7,0x9d,0xf5,0xc9,0x40,0xd1,0x06,0xd6,0xe3,0x89,0xa5,0xcc,0x9f,0x40,0x67,0x80,0x11,0xec,0x5d,0x23,0x19,0xf3,0x66,0xaf,0x06,0xcc,0xe4,0xb6,0x5e,0x20,0xf7,0x19,0xce,0x1a,0xb6,0x86,0x0d,0x39,0x1d,0xc8,0x0a,0xdb,0x50,0x52 +.byte 0x7e,0x3b,0x96,0x9f,0x05,0xdd,0xd8,0xdf,0x40,0xdf,0xe4,0x66,0x14,0x4d,0x4e,0xb3,0x9f,0x86,0x7b,0xc2,0x99,0xc3,0x8f,0xb9,0xe7,0xc3,0x50,0xa4,0xab,0xb8,0x8e,0xc5,0x28,0xce,0x8b,0x51,0xcb,0xad,0xd8,0x1a,0x23,0x7d,0x12,0xc2,0xaf,0x1a,0x93,0x4c,0x57,0xe9,0x59,0x6a,0x03,0x65,0x81,0x07,0x40,0x84,0x92,0x9d,0x22,0x8a,0x3d,0x27 +.byte 0x39,0x05,0xdd,0xf7,0x20,0xad,0xc2,0x03,0x27,0x87,0x8e,0xc1,0x23,0xad,0xe5,0x59,0x16,0xe7,0xde,0xe4,0x44,0x6b,0x06,0xb5,0x1d,0xaf,0xda,0x08,0x4a,0xfa,0x75,0x1a,0x0b,0x35,0xe8,0x6e,0x29,0xd3,0x79,0x19,0x80,0xb9,0x5f,0x36,0xec,0x43,0x25,0x3c,0xbc,0xcf,0x70,0x0c,0xc7,0x2c,0xbc,0x2e,0x72,0x40,0x73,0x98,0x11,0xc9,0x72,0x9f +.byte 0xd9,0x95,0x9f,0x8d,0x4a,0x52,0xbb,0x89,0x30,0x5b,0xa2,0x7e,0x0c,0x21,0x11,0xda,0x4e,0xa1,0x7c,0xc1,0x0f,0x95,0x1b,0x5b,0x2e,0xbd,0xae,0x8a,0x56,0x82,0x8f,0x84,0x43,0xdf,0x24,0xac,0x99,0xaa,0x8a,0xaf,0x82,0x33,0xf7,0x0a,0xbf,0x5e,0xfd,0xf2,0x91,0xf0,0xe1,0x5d,0x4e,0xa5,0x16,0x6e,0xb4,0x39,0x8b,0x99,0x32,0x6b,0xc8,0x16 +.byte 0xc1,0x84,0x10,0xc2,0x74,0x54,0xfc,0x02,0x71,0x44,0xfc,0x52,0xfa,0xc2,0x3c,0x8d,0xf7,0x8b,0x1e,0xcc,0x5e,0x43,0x66,0x29,0x29,0x93,0xe7,0xf6,0x9f,0xa8,0xa3,0x35,0xc9,0xde,0xb0,0xbe,0x4d,0xdf,0x8c,0x61,0x5a,0x6b,0x16,0x88,0x33,0x65,0x47,0x98,0xd2,0xf8,0x71,0x09,0x9f,0x00,0xb6,0x9e,0x21,0x37,0x2a,0x0b,0xb4,0x74,0x6b,0x0e +.byte 0x6e,0x4d,0x14,0x45,0x6c,0x1b,0xa8,0x4c,0xa7,0xc6,0xc3,0x36,0x6e,0x9e,0x63,0x5a,0x36,0x76,0x04,0x06,0x7f,0xdd,0x74,0x24,0x19,0xd8,0xb7,0xbc,0x6c,0x52,0x82,0x67,0x6b,0xd5,0xcb,0x81,0xdf,0xd7,0xe4,0xdd,0x14,0x33,0x71,0xcf,0x6b,0x7f,0xaf,0x66,0x27,0x8a,0x70,0xb8,0x45,0xae,0x8c,0x1a,0x65,0xd3,0x16,0x5c,0x05,0x65,0xd0,0xfb +.byte 0x07,0xe3,0x98,0xa9,0x94,0x27,0x6c,0xac,0xfc,0xee,0x1b,0x35,0x43,0xd6,0x3b,0x41,0x1c,0x86,0xc0,0x4f,0xf3,0x63,0xf4,0xba,0x4d,0xdf,0x6a,0xda,0xcf,0xb5,0x9f,0x69,0x3f,0x3d,0x0c,0x80,0x79,0x02,0x34,0x4a,0x9a,0xfd,0xb6,0xea,0x0b,0x61,0x32,0x67,0x2d,0x6a,0x6b,0xcb,0xcf,0xa6,0xee,0x6a,0x93,0x11,0x00,0xb8,0x6e,0x27,0x88,0x62 +.byte 0xf7,0x4c,0x7b,0xe1,0x13,0xe1,0x47,0xaf,0x96,0x24,0x3b,0x46,0x8c,0xf4,0xbe,0x13,0xed,0x65,0xe1,0xf2,0x36,0x2d,0xa4,0x6d,0x5e,0xa6,0x93,0xfb,0x64,0x0e,0xbd,0x50,0xdc,0x29,0x4f,0x90,0x8e,0xe1,0x7f,0x5e,0x47,0x08,0x9b,0x1c,0xb7,0xce,0x06,0x80,0x52,0xc0,0xb5,0x82,0x77,0x49,0x3c,0xe0,0x70,0x1f,0x84,0x75,0x9e,0x19,0xb2,0x83 +.byte 0xda,0x40,0xf8,0xd7,0x27,0x1e,0xbc,0x39,0xb5,0x1d,0x25,0x75,0x63,0x7d,0x85,0x2f,0x09,0x07,0xe9,0x73,0x8e,0x2b,0xb8,0x9a,0xbe,0xd6,0x90,0x91,0x6e,0xdb,0x7c,0x9d,0x9b,0x43,0x1d,0x21,0x88,0x76,0xb0,0xaa,0x7b,0x68,0xe4,0xa7,0x92,0x64,0xe4,0x1f,0xff,0x53,0x1d,0xf7,0xc0,0x44,0x5c,0x0a,0x1e,0xcd,0xa7,0x6e,0x41,0x1c,0x8c,0x7d +.byte 0x66,0xa7,0xf6,0xfc,0xa9,0x0d,0x3f,0x9c,0xfb,0x15,0x87,0x14,0x20,0x43,0x1b,0x05,0xf5,0xea,0x5c,0x07,0x61,0xb3,0x0e,0x7c,0x52,0x57,0x1c,0x09,0x33,0xb4,0xd8,0x3d,0x9d,0x17,0xee,0x86,0x25,0xdc,0x6b,0xcd,0x58,0xb7,0x18,0xbd,0x85,0x39,0x0b,0xb9,0xb8,0x35,0x3a,0x86,0xbb,0x88,0xb5,0x5e,0x4b,0x0a,0x7e,0x9c,0x02,0xb5,0x45,0xe5 +.byte 0xc7,0x38,0x56,0x1e,0xe4,0xe7,0xf7,0x88,0xac,0x75,0x9a,0x97,0xa8,0x15,0xb6,0x2d,0xcf,0x2a,0x59,0x65,0x0e,0x00,0x9f,0x8e,0xa9,0x94,0x23,0x1c,0x40,0xe4,0xb9,0x6b,0xcf,0xf0,0x53,0x7f,0x98,0xd1,0xa7,0x72,0xd7,0xe3,0x22,0xfd,0x5f,0x3d,0x3f,0xd6,0x21,0xb4,0x84,0x0c,0x1b,0x1d,0x00,0x2d,0x8f,0x72,0x22,0x2d,0x2c,0x8c,0x54,0x46 +.byte 0xe5,0x53,0xca,0x66,0x67,0x5e,0xb3,0x62,0x6f,0xaf,0x33,0x81,0xc1,0xf6,0x77,0x92,0x3e,0xdb,0x74,0x68,0x93,0xca,0x38,0xf8,0x18,0x50,0xef,0xe4,0xc9,0x45,0x40,0xc9,0xf0,0xc5,0x7a,0x4b,0xf2,0xd8,0xca,0x72,0x62,0x5f,0x67,0x10,0x10,0xcc,0xff,0x1a,0xc7,0x9c,0x3a,0x7f,0xca,0x11,0x67,0x3e,0xca,0xa6,0x9c,0x48,0x15,0xaf,0x68,0xb7 +.byte 0x2b,0xa7,0xa2,0x68,0x7b,0x40,0xb2,0xe3,0x27,0x18,0x7e,0x94,0x4c,0xca,0x0e,0x5b,0x3a,0x30,0xcb,0xc3,0x72,0x31,0x6b,0xe6,0x3e,0xa7,0x09,0x3e,0xf2,0x53,0xda,0x7d,0x6f,0x55,0x08,0xd2,0x26,0xc3,0x07,0x52,0x38,0x90,0x04,0xc6,0x3c,0xb6,0xb5,0x2a,0x7b,0x38,0x07,0x9e,0xb4,0xa5,0x48,0x36,0xf5,0x5e,0xac,0xa8,0x97,0x4e,0x37,0xc2 +.byte 0xee,0x12,0x88,0x28,0xd0,0x7d,0xd1,0xae,0xc0,0xc7,0x84,0x69,0x25,0x79,0x9a,0x8a,0x16,0x49,0x50,0x72,0x69,0x1a,0x02,0xc9,0xfe,0xd5,0x2c,0x40,0xc6,0xc8,0x8b,0x7d,0xe3,0xab,0x89,0xe3,0x78,0xf1,0xe9,0xbd,0x3c,0xbd,0x02,0x96,0xfe,0x0c,0x5c,0xc4,0x9e,0x89,0x3a,0x4b,0xe9,0xcd,0x41,0x1c,0x59,0x71,0x52,0xb0,0xc9,0x36,0xf1,0x80 +.byte 0xab,0x5e,0xbc,0xf1,0x20,0x99,0xc0,0xab,0x0c,0x59,0x43,0xc2,0xcd,0x09,0xa6,0x30,0x91,0xfa,0x12,0x23,0xbe,0x18,0x24,0xa6,0xbf,0x55,0x4c,0xe8,0x22,0xff,0x01,0xbd,0xde,0x2c,0x72,0x3c,0x0a,0x36,0xd5,0x7e,0xed,0x6a,0xe3,0x63,0x14,0x60,0xa3,0x0a,0x6f,0x04,0x90,0x64,0xc1,0xd1,0x78,0x54,0xae,0x19,0x74,0xe2,0xea,0xec,0x86,0x22 +.byte 0xc7,0xdb,0xf6,0x48,0x0e,0x75,0x43,0x04,0xf7,0x62,0xe6,0xa9,0x46,0x65,0xcc,0xa5,0xa4,0x1a,0xb2,0x94,0x7b,0x7a,0x8c,0x9a,0x80,0x62,0x32,0x17,0x80,0xc3,0xc6,0x54,0x0e,0x4e,0xe3,0x46,0x74,0xa8,0xae,0xcd,0xd0,0xc1,0x19,0x84,0x61,0xb4,0x1d,0x18,0x4d,0x80,0xf1,0x70,0x40,0xbe,0xa2,0xa3,0x38,0xcc,0x21,0x1c,0x2f,0x72,0x85,0x72 +.byte 0x0a,0xa1,0x0d,0xa3,0xdc,0xa2,0xf4,0x64,0x84,0x3c,0x43,0x6d,0xfb,0x45,0x11,0xf9,0x40,0xdc,0x25,0x85,0x80,0x41,0x84,0xa7,0x06,0x2e,0x79,0xbf,0x0c,0xa7,0x8f,0x17,0xea,0xa2,0xc4,0x6f,0xd8,0xc6,0x9e,0xab,0xdc,0x45,0x6f,0xaa,0xda,0xe9,0xe6,0x84,0xf0,0x5f,0x8a,0x90,0x99,0x33,0x9b,0xcf,0x03,0xe6,0xce,0x19,0x0c,0xad,0x2f,0xad +.byte 0x81,0xb8,0x17,0xff,0x6b,0xff,0xc8,0x14,0xa6,0xf4,0x37,0x55,0xdc,0xbb,0x09,0x3c,0x3c,0xe7,0x29,0x95,0x23,0x5c,0x58,0x92,0x2e,0x95,0xe8,0x3b,0x8b,0x81,0x2d,0xfd,0x58,0x8a,0x1f,0xdf,0xf1,0x54,0xa3,0xd0,0x01,0xaa,0x3d,0x32,0x61,0xe5,0x8e,0x62,0xa7,0xf6,0x3b,0x2d,0x0e,0xff,0xf4,0xe9,0x08,0xe7,0xef,0x3a,0x63,0x10,0x34,0x49 +.byte 0x14,0xe1,0x88,0xd0,0xb2,0x1d,0xb7,0x31,0xc9,0xa4,0x48,0xa8,0xaf,0x64,0x29,0xab,0x1f,0x14,0x13,0xa7,0xb8,0xb8,0xa4,0x24,0x1d,0xf9,0xb6,0x3e,0x62,0xa6,0x5e,0x10,0xcb,0x44,0x5c,0x9d,0x2c,0x58,0x3a,0x36,0xa3,0x81,0x9f,0xa9,0xa4,0xa1,0x06,0x1d,0xbf,0x97,0x03,0x88,0xf2,0xf4,0x81,0x3e,0x1b,0x35,0xea,0xd0,0xb6,0x96,0xa1,0xf7 +.byte 0x1e,0x49,0xb7,0xe8,0x23,0x6f,0x05,0x7c,0x9f,0xc4,0x53,0xb1,0x63,0xdc,0x07,0xbb,0xd6,0x57,0x85,0x4d,0x77,0x33,0x21,0xbf,0x77,0xfe,0xfe,0x34,0x52,0x02,0xe7,0xe4,0x87,0x11,0xa0,0xfd,0x11,0x4a,0x34,0x36,0x88,0x69,0xdf,0x77,0xfd,0x83,0x71,0xa8,0x68,0xed,0x49,0x39,0xb4,0x06,0x32,0x48,0xf1,0xd2,0x4e,0x61,0x47,0x65,0x26,0x87 +.byte 0xba,0x2b,0x2e,0xf4,0x12,0xfc,0xd0,0x84,0x81,0xa1,0x59,0xdc,0xe3,0x13,0x51,0x9e,0xea,0x57,0x56,0x3b,0x7c,0x71,0x6b,0xff,0xe9,0xf8,0xec,0x3e,0xe7,0xbe,0x65,0x47,0xe1,0x6f,0x8f,0x7c,0x3a,0x77,0xdb,0x75,0x4a,0x43,0x43,0x39,0x37,0xb2,0x68,0x16,0x72,0xdb,0x49,0xf7,0x13,0x3c,0x09,0x93,0xef,0xc1,0x2a,0x99,0xff,0xc7,0xdb,0xd9 +.byte 0x80,0xd2,0xfe,0x7c,0x39,0x50,0x21,0xdc,0x1d,0xae,0x9b,0xfc,0xd4,0x5f,0x56,0xae,0x6a,0xd9,0x35,0xa1,0x2b,0xd6,0x53,0x90,0xe8,0x8c,0x31,0x73,0x0f,0xa3,0x9e,0xa1,0x2f,0x76,0xa8,0x72,0x4d,0x5e,0x58,0xca,0x9f,0x8f,0xdf,0xf0,0xf9,0x6a,0x54,0xb1,0x5f,0x39,0x03,0x7a,0x26,0x06,0x71,0x74,0x6f,0x42,0xee,0x63,0x76,0x13,0xb9,0xed +.byte 0x74,0xad,0xf9,0xe0,0xa7,0x35,0x9c,0x18,0xe0,0xf7,0xc5,0xb2,0x27,0x14,0x0f,0xd7,0xaa,0x17,0x1c,0x8f,0x50,0xc8,0xb0,0xc2,0x63,0xff,0x38,0x65,0x87,0x69,0xb3,0xd5,0x3f,0xb4,0xf2,0xe8,0x8b,0x7b,0x24,0xdc,0x1f,0x62,0x2f,0x0a,0xd7,0x2d,0x0f,0x6f,0x48,0x1d,0xf0,0x3c,0xb1,0xb4,0x10,0x8d,0xc6,0x5c,0x79,0x30,0xde,0x20,0x9e,0x7b +.byte 0xf1,0xa5,0x73,0x38,0x05,0x1b,0x13,0x78,0xb1,0x02,0x2f,0x32,0x2a,0x07,0x59,0xa4,0xfc,0x88,0x08,0x0c,0xff,0x42,0x72,0x6a,0xb0,0x8a,0xc9,0x3d,0xdb,0x04,0x90,0xdd,0x0b,0xbc,0x3a,0x4e,0xfa,0xd4,0x57,0xd8,0x2f,0x7b,0xcb,0xd9,0x6a,0xe7,0xfd,0x32,0x17,0x99,0x20,0x64,0x1e,0x76,0x07,0xb9,0xa3,0x58,0x7f,0x79,0xda,0x0c,0xe0,0xec +.byte 0x30,0xbf,0xa4,0x85,0x0a,0x39,0xc0,0xe9,0xf7,0xbe,0xd1,0xa7,0x94,0x1f,0xa6,0x6d,0xe8,0xc5,0x1b,0x04,0x27,0xf4,0xdc,0xc2,0x4d,0x9a,0x0e,0x9b,0xe8,0xec,0x56,0x99,0x90,0x5f,0x8b,0x28,0x0a,0x92,0xaf,0x0b,0xa1,0xd2,0x85,0x86,0x26,0xc7,0x8a,0x01,0xa4,0x08,0x29,0x32,0x7d,0x3d,0xa5,0x74,0x9c,0x90,0x63,0x83,0x1f,0xd4,0xee,0x98 +.byte 0xf5,0x14,0xff,0x39,0xeb,0xbf,0x40,0xa4,0xc9,0x70,0x4f,0x81,0x03,0x19,0xef,0xf5,0xdf,0xf7,0x00,0x75,0xcb,0x2e,0x81,0x41,0xc5,0xda,0xfb,0x67,0x6a,0xf0,0xa3,0xd3,0x5a,0x60,0xaf,0x72,0x27,0x3e,0xad,0x37,0x3e,0x3d,0xe6,0x85,0x4c,0xa1,0xb0,0xe9,0xab,0xc5,0xd3,0x8b,0x04,0x0d,0x64,0x7f,0xa2,0xb9,0x6d,0x6d,0x28,0xf8,0x4b,0x43 +.byte 0x78,0x51,0xf4,0x84,0xf1,0x3c,0x67,0xd8,0xdd,0xd7,0x0b,0x67,0xc3,0xd9,0x95,0x7b,0xfc,0x7d,0xc4,0x33,0x05,0x90,0xec,0x0a,0x98,0xfb,0x6b,0x0d,0xe9,0x8c,0x74,0x94,0x20,0xf8,0xcb,0xca,0xb6,0x72,0x07,0x7c,0xef,0xfa,0xd0,0x3f,0x51,0xc5,0x6e,0xf8,0x3f,0x37,0xe3,0xfe,0xb9,0x9a,0x9c,0xb3,0xf6,0x96,0x4e,0x65,0x77,0x21,0xcf,0xaf +.byte 0xe7,0x20,0x06,0xc2,0x93,0xc5,0x2e,0xc0,0x7f,0xe5,0x0a,0x42,0xad,0x89,0x64,0x6e,0x95,0xbf,0x95,0x1d,0x24,0x47,0xf8,0xd5,0xec,0x7c,0x1f,0x98,0x67,0x9c,0x5f,0x6e,0xaf,0x74,0x95,0x65,0x4c,0xb6,0xe0,0xd3,0xb7,0x5b,0xc7,0x76,0xe6,0x87,0x19,0xf5,0xc7,0xb0,0x2d,0xe0,0x8b,0xaf,0x6d,0x3c,0x31,0x6e,0x84,0xc8,0x86,0x51,0xff,0x29 +.byte 0x2a,0x1f,0xea,0xd4,0x2d,0x1a,0x8f,0x04,0xb4,0xc0,0x6a,0x93,0xc2,0xc5,0xe7,0x98,0x8c,0xc7,0xff,0xbf,0xb8,0x8e,0x5b,0x29,0x5b,0xa6,0x87,0xc7,0x02,0x88,0x51,0x29,0x66,0xd8,0xf3,0x68,0x38,0xd4,0xa6,0xbd,0xa2,0x5c,0x1b,0xb7,0x13,0xd7,0x64,0xed,0x68,0x21,0x88,0x2b,0x59,0xba,0x95,0x84,0xda,0xce,0x61,0x3b,0x51,0x04,0x3e,0xc2 +.byte 0xdd,0xec,0x0c,0x6b,0xbe,0x35,0x51,0x63,0x29,0x40,0xcb,0xa5,0x62,0xe4,0x27,0x35,0x15,0x1f,0x7c,0x8b,0xe5,0xd0,0x2e,0xde,0x8c,0x3d,0xa0,0xd2,0xbe,0x51,0x3d,0x65,0xed,0x94,0x8b,0x8c,0x00,0xda,0x0e,0x78,0x4d,0x25,0xef,0x8e,0x3c,0x55,0x77,0xeb,0x58,0x06,0x7d,0xd1,0xfc,0x73,0xad,0x76,0x0a,0x81,0xbe,0xda,0x50,0x30,0xf3,0xfd +.byte 0x58,0x25,0x0a,0x4b,0x1b,0x1e,0x0b,0xd0,0x9b,0xbc,0xb9,0x31,0x26,0xbc,0x4c,0x7b,0x05,0xd7,0x5c,0xe4,0x7a,0xdd,0xff,0x04,0xac,0x5d,0xcb,0xfd,0x91,0x34,0x68,0x26,0x1e,0xb4,0x86,0xcc,0xe3,0x90,0xaf,0x6a,0x65,0xda,0x6b,0x3e,0xec,0x44,0x90,0x72,0x7a,0x34,0xfc,0x7b,0x65,0x83,0x34,0x93,0xbc,0x85,0x50,0xdf,0x03,0x89,0x35,0xb8 +.byte 0x6a,0x39,0xd3,0xb6,0x38,0x66,0x5b,0xa7,0x9e,0x93,0xa2,0x3b,0xb6,0xe7,0xee,0x1e,0x5c,0xd6,0xa8,0xd9,0x1f,0xf7,0xd1,0x0a,0x2f,0x87,0x63,0xf4,0xf9,0x8c,0xd4,0x7c,0x02,0xaf,0x7e,0xb6,0xc7,0xfc,0xc9,0x4d,0x35,0x0c,0x8c,0x3c,0x13,0x9d,0xe6,0xd7,0x2e,0x4b,0x91,0xcc,0x88,0xdb,0xfc,0x68,0x3a,0xd1,0x15,0x07,0x16,0x66,0x11,0x9b +.byte 0x66,0x9f,0x3f,0x37,0xae,0x11,0xba,0x5f,0xc7,0x3a,0x1a,0x49,0xbc,0x14,0x21,0x75,0xdc,0xcc,0xbb,0x5c,0xed,0xdc,0x8b,0x21,0x9a,0x8f,0x5f,0x91,0x6a,0x9b,0x26,0x33,0x64,0x45,0xa0,0xdf,0xc4,0xa1,0x32,0xc4,0x4c,0xc2,0x42,0x1b,0x59,0x37,0x1f,0xdb,0x01,0x6d,0xed,0xd8,0x05,0x5b,0x90,0x59,0x32,0x45,0x50,0x5d,0xf1,0x34,0xc4,0xb7 +.byte 0x52,0x97,0xbb,0x42,0x12,0xf1,0xa5,0x76,0xe4,0x1a,0xbc,0x4a,0x64,0xd3,0x08,0xac,0xe1,0x49,0x70,0x61,0xc8,0xcf,0xb1,0xd3,0xc4,0x7f,0x38,0x31,0x6b,0xd3,0xe1,0xe1,0xe9,0x5b,0xaa,0x7a,0xec,0x26,0x81,0x44,0xd3,0xb9,0x63,0xea,0x37,0x98,0x15,0x41,0xf1,0xa1,0x72,0x87,0xcc,0x3b,0x6a,0x27,0x9b,0x85,0xa8,0x7b,0xb6,0x25,0xf9,0xd4 +.byte 0x84,0x3e,0x66,0x12,0xce,0x24,0xee,0x22,0x51,0x73,0x7e,0xba,0x1e,0x95,0x64,0xc5,0xbf,0x4e,0x4f,0x73,0xc1,0xc3,0x98,0xb9,0x6b,0x90,0x1f,0x39,0xfc,0x03,0x55,0x76,0x8c,0x57,0xea,0xe8,0xc1,0x25,0x09,0x69,0xc0,0xe8,0x54,0x91,0xc1,0x7c,0x52,0x8e,0x82,0x6d,0xf2,0x0e,0x3f,0xa9,0x98,0x04,0x40,0xda,0x1c,0xc0,0xbb,0x42,0xf0,0x7d +.byte 0xed,0x78,0xb0,0x4f,0x94,0xba,0x0d,0xbf,0x60,0xbe,0x09,0x67,0x42,0xc5,0x41,0x4c,0x80,0x8d,0x30,0x10,0xa9,0xd2,0x07,0x8c,0xa8,0x40,0xc6,0xe2,0x08,0x42,0x7f,0x99,0xad,0xc5,0x66,0x1f,0xfd,0xd2,0xc5,0x79,0x77,0x9b,0x60,0x7d,0x25,0x2d,0x69,0x14,0x94,0xa5,0xf0,0x0a,0x14,0xb6,0xf9,0xbe,0x3a,0x4a,0x3d,0xc6,0x45,0x2e,0x27,0x4a +.byte 0xd1,0x1d,0xcf,0x08,0xee,0x93,0x3c,0xb5,0x8a,0xee,0xdd,0xf3,0x33,0xa6,0x35,0x9d,0xd8,0xb4,0x68,0xc5,0x98,0x09,0x78,0xcc,0xb3,0xeb,0x0f,0xcd,0x25,0xf8,0x17,0x9c,0x45,0x77,0xc7,0x06,0x40,0x44,0x90,0xec,0x6a,0xd9,0xf5,0x05,0xd4,0x88,0x17,0x47,0xeb,0x29,0x85,0x32,0x76,0x7b,0xa4,0xe3,0x65,0x30,0x50,0x9a,0x99,0x26,0x91,0x60 +.byte 0xb0,0xb8,0xe5,0x8d,0x35,0x9e,0x9a,0x13,0x65,0x82,0xb2,0x4b,0xf1,0xed,0x1f,0xb7,0xb4,0xc0,0x03,0xe6,0x1d,0x2b,0xaa,0x1e,0x01,0x92,0x0b,0xcb,0x34,0x77,0x80,0x94,0xc2,0x4e,0x3b,0x73,0xd8,0x2e,0xd8,0x95,0x33,0x05,0x65,0xa2,0x99,0x29,0x7a,0xd1,0xb3,0xed,0x5a,0x8d,0x4d,0x6a,0x6d,0x69,0x2b,0x5a,0xa1,0x3a,0xc0,0x81,0x96,0xf1 +.byte 0xc2,0xa7,0x4e,0x07,0x90,0x04,0x99,0x70,0xea,0x1a,0x3a,0x26,0xb5,0xed,0x92,0xbd,0x57,0x80,0x11,0x06,0xf2,0xb4,0x05,0x69,0x7a,0xbf,0x27,0xa1,0xbd,0xdb,0x09,0xe5,0xb3,0x2d,0x86,0x41,0xcc,0x5d,0x68,0x37,0x9e,0x98,0xa5,0x4a,0x20,0x8a,0x5f,0x54,0xae,0x4f,0x73,0xd0,0x22,0x18,0x8d,0x2b,0x91,0xcb,0xbb,0x83,0x1e,0x04,0x93,0xc8 +.byte 0xc3,0x89,0x35,0xfd,0xda,0xeb,0x52,0x53,0x9f,0xdc,0x33,0xf0,0xe0,0x99,0x19,0x11,0xeb,0x55,0xd3,0x3c,0x5f,0xca,0x29,0x52,0xe7,0x6b,0xd1,0xad,0xeb,0xed,0x8e,0x68,0x82,0x91,0x85,0x81,0x68,0x70,0x78,0x61,0x1e,0x0c,0x09,0x3a,0x82,0xdc,0xdb,0x26,0x66,0x1c,0xa3,0x80,0x99,0x23,0x8a,0x45,0xd7,0xb8,0x10,0x97,0x80,0x70,0x49,0x78 +.byte 0xa9,0x4c,0xf0,0xec,0xcc,0x05,0xd0,0x6a,0x6a,0x1a,0xa0,0xf7,0xde,0x78,0xc6,0x42,0xbe,0xbd,0xa0,0x24,0x1d,0x3f,0xdd,0xfb,0x92,0xc2,0xbd,0xd6,0x5c,0x25,0x74,0x3d,0x2b,0xb8,0x60,0x67,0xdb,0x70,0x1e,0xe8,0x9f,0xcd,0xb4,0x82,0x90,0x9e,0x2a,0x94,0xa5,0xa2,0xd4,0xd2,0x24,0xa7,0xca,0xbf,0xe1,0x8b,0xab,0xf3,0xd2,0x7c,0xa6,0xc8 +.byte 0xe6,0xaf,0xef,0xe3,0x86,0xb1,0x42,0x1d,0xc6,0xa2,0x37,0x9b,0x26,0x46,0x0b,0xfd,0xee,0x88,0xa4,0xf1,0xa8,0x72,0xaf,0xda,0x30,0x56,0x22,0xd3,0x1b,0x31,0x76,0xd7,0x03,0xef,0xf3,0x98,0x16,0x4d,0x36,0x57,0x1b,0xd5,0x90,0xb8,0x67,0x50,0x7f,0x22,0xa8,0xdc,0x9c,0xf1,0x6e,0xa4,0x65,0x45,0xf0,0x73,0xd8,0x7e,0x41,0xb0,0x68,0x52 +.byte 0x00,0x0a,0xda,0x99,0x6c,0x84,0xce,0xf0,0x73,0x65,0x93,0x52,0xc8,0x4b,0xb4,0x72,0xda,0x2c,0xa1,0x47,0xb5,0xe3,0x00,0x63,0xc0,0x4e,0x84,0x16,0x00,0xe6,0x1f,0xbd,0xba,0x49,0xcb,0xd3,0x7d,0xd2,0xeb,0x4a,0xb2,0xd5,0xb2,0x53,0x96,0xfb,0x04,0x73,0xc0,0x09,0x31,0xf3,0xf2,0xc0,0xd3,0xa6,0xe1,0xea,0xe1,0x58,0xbe,0x90,0xc9,0xfb +.byte 0x6e,0x13,0x69,0xbe,0x17,0xd4,0x16,0x5b,0xcb,0xf4,0x93,0x0a,0x38,0x46,0xea,0x64,0xad,0xb0,0x0d,0xc0,0x3b,0xfc,0xe3,0xd4,0x20,0x75,0x0c,0x3e,0x71,0x1b,0x5f,0xde,0xff,0xd6,0xfa,0x6f,0xe4,0x10,0xb0,0x14,0x05,0xaa,0x05,0x70,0x5e,0xbd,0x58,0x9f,0x3c,0x9d,0x4f,0xa7,0x5a,0x65,0x57,0x02,0x05,0x44,0xe0,0x95,0x9d,0xa2,0x60,0x06 +.byte 0xcb,0xfd,0x91,0x8e,0x7f,0xce,0xa1,0x80,0x94,0xbb,0x88,0xf2,0xa6,0xe7,0x83,0xf9,0x38,0x8f,0x09,0x8e,0xe4,0xa9,0xc2,0xc7,0x84,0x9d,0x25,0x09,0x52,0x8b,0x32,0xaa,0x3b,0xde,0xb6,0x82,0x9f,0x6d,0xc4,0xdf,0x11,0xf7,0x72,0x1a,0xe4,0x00,0x51,0x41,0x01,0xba,0x21,0xea,0x0a,0xda,0xf2,0xbb,0x66,0xae,0x51,0x2b,0xb0,0x6d,0x1d,0xe8 +.byte 0x4b,0x1e,0x42,0x68,0x3a,0xed,0xe6,0x59,0x13,0x42,0x07,0x54,0xae,0x2e,0x15,0x93,0xd7,0xff,0xad,0x49,0x09,0x41,0x52,0x6b,0x3b,0x9c,0x41,0x43,0x0d,0xed,0xed,0x6f,0xb8,0xe9,0x0d,0xcc,0xde,0x0d,0xaa,0x91,0xef,0x89,0x2f,0x2d,0x94,0xd0,0x03,0x2b,0x51,0x7f,0x85,0x9b,0x7b,0x08,0xc8,0xb6,0xe2,0x82,0x22,0xa9,0x57,0x71,0xf2,0xae +.byte 0x08,0xfa,0x6c,0xd8,0xca,0x78,0x42,0x98,0x23,0xfd,0x38,0x4b,0x6c,0xd3,0x9f,0xc6,0xa3,0xb2,0xc1,0x8c,0x4a,0xa3,0xcd,0x9f,0x56,0xe7,0xc2,0x06,0xd7,0xc5,0xc2,0xd9,0x98,0x57,0xc8,0x5a,0xaa,0xf4,0xaa,0x44,0x02,0x83,0x11,0x1e,0xf6,0x64,0x8d,0xf7,0x3b,0x86,0x3c,0x04,0x53,0x5f,0x62,0xc8,0x7a,0x0e,0x1c,0x4f,0xa8,0xe3,0x5c,0xe8 +.byte 0x64,0xf7,0xe3,0x5d,0xea,0xb5,0x2d,0xdb,0x7b,0x0e,0xdb,0x91,0x34,0xd5,0x87,0x4f,0xe6,0x73,0xee,0x3d,0x79,0x7c,0x67,0x48,0xb5,0xbb,0x42,0x96,0x0d,0x9d,0xbd,0x68,0x98,0xe5,0x59,0x51,0x16,0x45,0x15,0xac,0x80,0x41,0xae,0x45,0xdb,0xe4,0x2a,0x44,0x0d,0xe4,0x25,0xc7,0xd3,0x06,0xf7,0x98,0x15,0xe1,0xc5,0x9b,0x34,0x0e,0x87,0xb8 +.byte 0x90,0x1b,0x24,0x84,0x06,0x24,0xb0,0x80,0xbe,0x03,0xa0,0x95,0x10,0x1e,0x72,0xde,0x0f,0xd4,0x15,0x7b,0xa0,0xf5,0x42,0xc3,0x6f,0x10,0xe9,0x76,0x44,0xe3,0xa9,0xb7,0xef,0xf6,0xc2,0x80,0xe2,0x0c,0x2d,0xad,0xe0,0xb9,0x45,0xca,0x67,0x6f,0xb6,0xc5,0xc0,0x8d,0x25,0xee,0x50,0xeb,0x51,0xc6,0x87,0x87,0x61,0x3a,0x75,0x95,0x41,0x47 +.byte 0x26,0xfd,0x35,0xf6,0x46,0xf4,0xe9,0x42,0xc6,0xef,0x37,0x97,0xb3,0x0a,0x1d,0xc8,0xdf,0x07,0x24,0xb1,0x0d,0x07,0x43,0x67,0x7d,0x81,0x09,0x58,0xdd,0xf6,0xcf,0xf1,0x47,0x42,0xbd,0x3c,0xa3,0xd7,0xe8,0x73,0xf9,0x5b,0xff,0x2c,0xcd,0xe6,0xd1,0xe9,0x47,0x6d,0x19,0x9b,0x6a,0x63,0x69,0xf4,0x4a,0xdf,0x69,0xab,0xa9,0xb7,0xe5,0x8d +.byte 0x1c,0x44,0x52,0x0c,0x7e,0xa1,0xfe,0x9d,0xd5,0xa4,0x71,0x62,0x0b,0x3c,0xf6,0xd2,0xd3,0xe9,0x70,0x09,0x68,0xf7,0xd6,0x0a,0x00,0x61,0xf1,0xf3,0xd0,0x41,0x4a,0x14,0xc6,0xf5,0x49,0xb1,0xde,0x10,0xd3,0x20,0x8b,0xfe,0x78,0x6a,0x87,0x79,0x15,0xd3,0x43,0x00,0xbe,0x71,0x40,0xaa,0xca,0x1a,0x64,0xe3,0x96,0x34,0x2f,0xea,0x0c,0x11 +.byte 0x41,0x21,0xf8,0xa7,0x65,0x9b,0x75,0xe2,0x1e,0x6f,0x5e,0xe0,0x68,0x42,0xca,0xd3,0x19,0x35,0xe8,0x88,0x0f,0x05,0xa3,0xb1,0x73,0xea,0x53,0x79,0x40,0x24,0x00,0x86,0x20,0xbb,0x25,0x58,0x89,0x6b,0xde,0xd6,0xd0,0x36,0xbb,0x33,0x30,0x59,0x4b,0x30,0x92,0xac,0xe5,0x95,0x94,0x22,0xab,0xc1,0x10,0x35,0x9c,0xa1,0x20,0x11,0x5d,0x4f +.byte 0x57,0x5c,0x9c,0xb8,0x3a,0xdc,0x97,0xa5,0xf3,0x0b,0xf5,0x96,0xe7,0xef,0x90,0x72,0x01,0x52,0x70,0x5a,0xf0,0xd9,0x7e,0x59,0x05,0x8c,0xd1,0x45,0x47,0xbf,0x16,0x15,0xa2,0xc9,0xdd,0xe7,0x5f,0x4b,0x94,0x5f,0xe6,0xf9,0x78,0xbb,0x8f,0xf9,0x79,0x9f,0x5e,0xd7,0x1f,0x0b,0xef,0x8d,0xfe,0x75,0xd4,0x8a,0x12,0x28,0xa5,0xf9,0x6e,0x14 +.byte 0x3c,0x52,0x80,0x57,0xc6,0x96,0xae,0x67,0x27,0xc1,0x1c,0xb6,0xd6,0x1c,0x74,0x8c,0x6f,0xc7,0x71,0x3e,0xd5,0x73,0xf2,0x3e,0x02,0x15,0x67,0x18,0xb8,0x5b,0x61,0x9e,0xfa,0x7e,0xba,0x00,0xe9,0xd9,0x51,0x91,0x63,0x7e,0xf7,0xab,0xc0,0xc6,0xee,0x66,0xdd,0x66,0x88,0x7a,0x8a,0xc5,0xc2,0x08,0x45,0x62,0xde,0xe1,0xfb,0x35,0x65,0x34 +.byte 0x00,0x9e,0x1d,0x25,0xdf,0x69,0xb6,0xe3,0xfe,0xbb,0x13,0xac,0xd3,0x13,0xb2,0x64,0x5a,0xf3,0x47,0xf1,0x36,0x55,0x5f,0x1b,0x87,0xea,0x5d,0x5c,0xfd,0x8a,0x68,0x69,0x8a,0x00,0x9f,0x83,0xbe,0x79,0x7d,0x01,0x9e,0xf2,0xb2,0x5d,0x56,0xe0,0xe6,0x49,0xe5,0xe1,0x76,0x57,0x7a,0x85,0xac,0x94,0x16,0xe3,0x68,0x05,0x14,0xb5,0x33,0x54 +.byte 0x64,0x5a,0xbe,0xa3,0x04,0x90,0x5c,0x1c,0xf8,0x97,0x16,0x36,0xce,0x76,0xe7,0xf0,0xaf,0x8a,0xea,0x65,0xa8,0x15,0x5b,0x1e,0x0a,0x91,0xad,0x62,0x62,0x67,0xb4,0xf0,0x94,0x1f,0x64,0x50,0xa8,0xc0,0x6b,0x38,0x80,0xd7,0x53,0xbb,0x70,0xbd,0x54,0x01,0xb0,0xa5,0xbc,0x00,0xe0,0xd6,0x23,0x37,0xe6,0x9f,0x0f,0x2f,0x96,0x21,0xc2,0x90 +.byte 0x55,0x26,0x55,0xa4,0xcd,0x3e,0x54,0x6b,0xa6,0xb0,0x2c,0xf2,0xd4,0xcc,0x6a,0x44,0xea,0x18,0x61,0xc5,0x1a,0x8e,0x60,0x64,0xf4,0x5f,0x21,0x36,0x01,0x5d,0x9f,0xc4,0x2c,0x67,0x1c,0x48,0x94,0x16,0xae,0xa8,0x13,0x5c,0xee,0x18,0x88,0x61,0xe4,0x54,0x6b,0xa2,0xe8,0x7f,0xf0,0x15,0xc3,0xce,0xbc,0x5b,0x91,0x25,0x7b,0x1d,0xd3,0x9f +.byte 0x13,0x1b,0x01,0x5d,0x43,0xe8,0xa1,0x77,0x5a,0x87,0x79,0x8b,0xd5,0x69,0xf7,0xdf,0x66,0xa2,0x84,0x0c,0x66,0xac,0x15,0x65,0xbf,0x74,0xc0,0xd2,0x78,0x6a,0x3a,0x9c,0x98,0x62,0x04,0x41,0x95,0xb2,0x23,0x59,0xc6,0xb0,0xc5,0x22,0xc0,0xfa,0xaa,0xc8,0x94,0x73,0x91,0x5b,0x64,0x1b,0x74,0xbe,0xcb,0xa1,0x81,0xb1,0xc1,0x26,0xa1,0x94 +.byte 0x55,0x04,0xb3,0x9c,0x80,0xb7,0x00,0x6f,0x36,0xc7,0x7f,0x6d,0x97,0xea,0xf3,0xf5,0x55,0xc5,0xfe,0x61,0xd9,0xb1,0x6d,0x8c,0xa1,0x02,0x08,0xb3,0x41,0xe6,0xe6,0x57,0xc6,0xff,0x6e,0x47,0xa4,0x22,0x2e,0x2d,0x21,0x53,0xbe,0xe3,0xbe,0x15,0xec,0x23,0x9d,0x87,0xe0,0x2e,0xcc,0x6c,0xd0,0xc7,0xb7,0x3d,0xa4,0x07,0x5f,0x69,0x4e,0x2b +.byte 0x07,0x69,0x4f,0xc5,0xa3,0x66,0x52,0x91,0x8f,0xa4,0x48,0xb9,0x40,0x76,0xd9,0xcb,0x6e,0x1a,0x35,0x9e,0x50,0x9f,0xd1,0x78,0xb2,0xb8,0x0d,0xa8,0xf8,0x6e,0x07,0xa5,0x3a,0xdf,0x3c,0x32,0xa6,0x10,0xbd,0x73,0x2f,0x07,0x45,0x66,0x0f,0x61,0xce,0xc2,0x08,0x19,0x98,0x33,0x4b,0x59,0x81,0xb5,0x78,0x4f,0x46,0x88,0xae,0x29,0xf8,0xf5 +.byte 0xc2,0x29,0x6f,0x8f,0xe5,0x8f,0xb0,0x53,0xc8,0x7a,0x48,0xda,0x6f,0x7e,0x8a,0x69,0x68,0xab,0xba,0xd9,0x20,0x0f,0x96,0x69,0x41,0xa6,0x92,0x94,0x8e,0x0f,0x86,0xdf,0x8d,0x70,0xaf,0xfe,0xf1,0x20,0x50,0x01,0xff,0xca,0x30,0x24,0x67,0x4a,0x04,0xa2,0xde,0x06,0xdc,0x26,0x1e,0x17,0xbc,0x52,0x9a,0x62,0x72,0xc1,0xd8,0xd7,0xe0,0xed +.byte 0xcf,0x4b,0x13,0x80,0x9a,0xbf,0x72,0x4f,0xf4,0x24,0x26,0xcd,0xe0,0x21,0x99,0x7b,0x5c,0x4f,0xbf,0x5c,0x41,0x08,0x8b,0x17,0x69,0x62,0x60,0x2c,0x74,0xb0,0x2d,0x22,0x7e,0x25,0x95,0x6a,0x84,0x0f,0x45,0x8f,0x9a,0x92,0xa1,0xcd,0xa5,0x50,0xf0,0x52,0x7f,0x60,0xd8,0x91,0xe1,0x17,0xe1,0x66,0x8f,0xd3,0x1f,0x41,0x7f,0x6f,0xf1,0x72 +.byte 0xa3,0xb6,0x12,0x62,0x46,0x16,0xea,0x26,0x9e,0xda,0x61,0x13,0x0b,0x17,0xf7,0xe1,0xec,0xc0,0x38,0xfe,0x40,0x31,0x6b,0x38,0x2a,0x4b,0xa5,0x8e,0xfb,0x99,0x60,0xd6,0x4a,0xbd,0xfb,0x75,0x2b,0x41,0xd4,0x33,0x5d,0x35,0xfe,0x2d,0xfc,0x1a,0xac,0x02,0xb3,0xf0,0xa2,0x6d,0xfa,0x8b,0x12,0x99,0xdd,0x54,0xf2,0x1c,0x35,0xd3,0x60,0x5a +.byte 0xdb,0x65,0xa7,0x58,0x1b,0x82,0xb4,0xf6,0x49,0x77,0xf2,0xea,0xa3,0xa9,0x57,0x94,0xb7,0x6e,0x19,0xda,0x7e,0xa5,0x70,0xb8,0xff,0x39,0x81,0x7d,0xfa,0xea,0xd6,0xc6,0x12,0x84,0x0a,0x8a,0x16,0xde,0x99,0xa6,0xe7,0xe0,0x77,0x76,0xb8,0xa3,0x6f,0xfb,0xb4,0x8f,0xc3,0xbd,0x90,0xd8,0x2a,0x04,0xed,0x42,0x91,0x9b,0x84,0x40,0x2d,0x01 +.byte 0x94,0xdb,0xbb,0x58,0x25,0xed,0xa3,0xdd,0xaa,0x0c,0xce,0x25,0x12,0xcd,0x11,0xbf,0xd0,0x57,0xe9,0x51,0x74,0xa7,0x45,0x6c,0x58,0xe7,0x4d,0x43,0xc6,0xd0,0x09,0x93,0x2d,0xe0,0xe3,0xae,0x7b,0x8f,0x53,0xa0,0x80,0xa1,0xef,0xcb,0xf5,0xfe,0x38,0x4d,0x31,0xa2,0x5c,0xd3,0x4a,0x66,0x1a,0x5c,0x07,0xbe,0x25,0xba,0x30,0xb6,0x00,0x27 +.byte 0x52,0xb9,0x1f,0xa3,0xed,0xd7,0x31,0x33,0x4a,0xf6,0x3f,0xed,0x75,0xe7,0xa4,0xf4,0xdf,0x97,0xc1,0x78,0x90,0x9b,0x4b,0xbd,0x06,0xc6,0x72,0x5c,0xdf,0x57,0x60,0xbe,0xbc,0x88,0x02,0xb6,0x5a,0x65,0xea,0x3a,0x3a,0x74,0x03,0xc8,0x66,0xef,0xf0,0x63,0xc7,0x9d,0x58,0x8e,0xa1,0xb2,0x25,0x4f,0xc4,0x14,0x5f,0x80,0x78,0x08,0x06,0x21 +.byte 0x50,0x34,0x01,0x2b,0x15,0xf4,0x7d,0x1f,0x1f,0x32,0x36,0x0a,0x52,0x1f,0x50,0xa2,0x50,0xbc,0x9a,0xdf,0x4e,0x84,0x49,0x2d,0x08,0xaa,0x46,0xc0,0x0e,0xcf,0x27,0x17,0x91,0x78,0x8c,0xb9,0x72,0xc5,0x8e,0x25,0x85,0x11,0xff,0x2f,0x4a,0x71,0x7c,0x14,0xfe,0x86,0xfe,0xb4,0x3a,0xd0,0x67,0xfd,0xaa,0x9b,0xee,0x89,0x66,0x03,0x59,0x4e +.byte 0x1c,0x96,0xaf,0x2b,0x8d,0x4d,0x6f,0xf6,0x72,0xc6,0x13,0xc7,0x14,0xce,0x19,0x0c,0x0b,0xa3,0x01,0x12,0x7c,0x8e,0x10,0xb8,0x63,0x41,0x57,0xb9,0xfe,0x6e,0x3e,0xda,0x20,0xfb,0x92,0x08,0x7d,0x66,0x31,0x9d,0x4f,0xdb,0x14,0xf4,0xb6,0xb8,0xea,0xee,0x54,0x0f,0xaf,0xc1,0x99,0xf0,0x8f,0x55,0x44,0x20,0x44,0xd0,0xa6,0x98,0xa3,0xa8 +.byte 0x8b,0x8e,0x26,0x03,0xec,0x2d,0x50,0x4f,0xb0,0x8d,0xd0,0xf2,0x96,0xcc,0x18,0xa9,0xb1,0x0f,0x79,0xe3,0x9f,0x08,0xb3,0x53,0x0b,0x9c,0x9f,0x22,0xdb,0x45,0x57,0xd6,0xaa,0x3b,0x6a,0xcb,0xdc,0xc9,0xda,0x57,0x75,0x65,0x0a,0xc1,0x17,0xb3,0x97,0xa9,0x07,0x40,0x20,0xfb,0x72,0x2d,0xc6,0x37,0x1e,0x44,0xb7,0x7e,0x0b,0x38,0xcc,0xfc +.byte 0xa0,0xed,0x48,0xa9,0x9b,0x87,0xbc,0x71,0x0f,0x8b,0xda,0x4f,0x09,0x27,0x1e,0x3d,0x9c,0x03,0x62,0x81,0xa8,0x7c,0x7b,0x8a,0x14,0xa7,0x22,0x69,0xa8,0xba,0x0e,0xcc,0x1f,0x2b,0xb3,0x0f,0x7d,0xce,0x3f,0xec,0xb5,0x9d,0xe0,0x3a,0x67,0x56,0x08,0x5d,0x03,0x8b,0x71,0x01,0x44,0x11,0x1b,0x7b,0xcf,0xcc,0x2e,0xfc,0xa5,0x52,0x9b,0xeb +.byte 0x1e,0x8a,0xa1,0x86,0x64,0xcf,0x32,0x03,0x6b,0x3e,0x29,0xe7,0x9a,0x16,0x7e,0xe2,0x21,0x2f,0x5f,0xe2,0x86,0x7f,0xf8,0x22,0x36,0x10,0x99,0xc8,0x27,0x43,0xa1,0xb9,0xf4,0xb4,0xb8,0xe1,0xa3,0x1d,0x80,0x9c,0x81,0x92,0xef,0x1f,0x28,0x54,0x51,0xf3,0x62,0x9c,0x7a,0x24,0xd4,0x5a,0xdc,0x38,0x4f,0xa5,0x57,0xdd,0x4d,0xa1,0x52,0xf3 +.byte 0xd3,0x9d,0xa1,0x93,0x5e,0xbe,0x9b,0xd1,0x2a,0x52,0xf1,0xbb,0xa5,0x3f,0x3a,0x94,0x7c,0x7d,0x41,0x61,0x36,0x14,0x25,0x5f,0xab,0xef,0x32,0xf3,0x0f,0x6c,0xc5,0xf5,0x5f,0xe5,0x88,0x51,0x17,0x60,0x8b,0xd5,0xa6,0xea,0x8b,0x21,0xec,0x1a,0xa7,0x69,0xa0,0x59,0xf9,0xeb,0x51,0x94,0x70,0x2b,0x96,0x2e,0x71,0xa9,0x8c,0x12,0x15,0xce +.byte 0x7d,0x59,0x6b,0xf2,0xca,0x2c,0xbd,0x85,0xfb,0x23,0xab,0xcb,0x89,0x89,0xda,0x28,0x49,0x7e,0xfc,0x90,0x2a,0x9a,0x3d,0x6d,0x24,0x57,0xba,0xd9,0x30,0xe0,0x10,0x04,0xb1,0x7f,0x8a,0xcf,0xc8,0x27,0x63,0xd6,0xbd,0xea,0xef,0x90,0x6f,0xc2,0xfc,0x78,0xfd,0xc4,0x5b,0x45,0x0c,0x41,0x8a,0x53,0x5b,0xbc,0x62,0x32,0x86,0x7f,0x19,0xb7 +.byte 0x8b,0x03,0x50,0xed,0xca,0x8e,0x8b,0xa0,0xe3,0xc2,0x0e,0x81,0xe5,0x8a,0xe8,0xf1,0x6a,0x0b,0x1a,0xa7,0xb6,0xed,0x74,0x23,0x34,0xad,0x5b,0xd8,0xf7,0x17,0x8d,0xa5,0x05,0xf3,0x00,0x4a,0xad,0x7e,0x91,0xc9,0x6b,0x13,0xff,0x76,0x78,0xf0,0xd1,0xf4,0x99,0x43,0x73,0xd9,0xba,0x59,0xbe,0xb5,0xa3,0xbd,0x5e,0xc5,0xd3,0x88,0x06,0x9c +.byte 0x86,0x32,0xb4,0xd5,0x30,0x77,0x78,0x8e,0xd5,0x6a,0x1d,0xeb,0xfd,0x6b,0xe6,0xf8,0x4b,0xe8,0xf3,0xba,0xbb,0x86,0x8e,0xe6,0x63,0x83,0x92,0x23,0x05,0x58,0x2e,0x61,0xdd,0x38,0xad,0x8d,0x19,0x7d,0xfa,0x7c,0x3e,0xc8,0x9f,0xae,0xea,0x6d,0x12,0xf0,0xa4,0x08,0xed,0x12,0x0c,0x97,0x87,0x58,0xd8,0xbc,0x3f,0xde,0x7c,0xee,0x0c,0xc0 +.byte 0xa2,0x2e,0xf0,0x25,0x6d,0xf3,0x30,0x23,0xa7,0xc2,0xc8,0x09,0x67,0x01,0xe1,0x25,0x26,0x46,0x38,0xf5,0x5e,0x55,0x8b,0xd6,0x43,0x6a,0xb8,0xe4,0xdf,0x0f,0x5d,0x6c,0xc3,0xb2,0x56,0x38,0xda,0xbc,0xbf,0x5e,0x85,0x8c,0xd5,0x2a,0x6a,0xe2,0xff,0x4f,0x36,0xf7,0x52,0x2c,0xe2,0xae,0x65,0x65,0xd1,0xfc,0xd3,0xc6,0xf7,0x26,0xa6,0xd0 +.byte 0x0b,0xc8,0xf0,0x68,0x5d,0x07,0x89,0x06,0xb3,0xfb,0x39,0x1d,0xd8,0xd8,0xd7,0x53,0xd0,0xc9,0x76,0x56,0xc0,0xd3,0xf5,0x66,0x80,0x5b,0xff,0x4a,0xdf,0xae,0x52,0x86,0x54,0x24,0x53,0xcf,0xcf,0xd2,0x89,0xde,0x71,0x62,0x9c,0x31,0xa5,0x3d,0x62,0x07,0xa1,0x33,0x49,0xbb,0x06,0x88,0xd8,0xa1,0xdd,0x0e,0x47,0x8d,0x72,0x00,0x2d,0x51 +.byte 0xa3,0x35,0x6e,0xb6,0x1f,0xbf,0xe5,0x42,0x68,0x6f,0x62,0xfa,0xf3,0x12,0xa9,0x1a,0xbd,0xe8,0xa4,0xf1,0x6d,0x07,0xe7,0x70,0x87,0x44,0xb7,0x3d,0xea,0xdc,0x3a,0x24,0xbd,0xa0,0x9b,0xb8,0xc5,0xa8,0xd9,0x06,0xde,0x02,0x68,0x7e,0xd5,0x2d,0x3b,0x5f,0x12,0x31,0x72,0x35,0x77,0xf6,0x10,0x6e,0x81,0x7d,0x3c,0xac,0x95,0x5b,0xbe,0x90 +.byte 0x74,0xf3,0x3e,0x9b,0x07,0x54,0x97,0xe3,0x1d,0xcf,0xe2,0xc5,0x80,0x6b,0x5f,0x0b,0x96,0x00,0x0f,0x0e,0x53,0x36,0x76,0x6e,0x99,0x0c,0x32,0xa2,0xc9,0xaa,0xa0,0xa1,0xb7,0xee,0x9d,0xd6,0x46,0xe7,0x2d,0x10,0x7a,0xf2,0x22,0x50,0x52,0xbf,0xec,0xcc,0xbc,0x0d,0x81,0x55,0x2d,0xac,0x2e,0xf7,0x99,0xbe,0x68,0x09,0xb0,0x11,0xc3,0xc8 +.byte 0xca,0x63,0xa7,0xc2,0x0f,0x37,0x2a,0x9e,0x85,0x79,0x6b,0x44,0xc1,0x4f,0xb9,0xd6,0x6c,0x56,0x0e,0x59,0x33,0xc3,0x00,0x53,0xe2,0xf4,0x30,0x90,0x4e,0x4b,0x09,0x4d,0x6f,0x9a,0x9e,0xb9,0x8d,0x0b,0xa1,0x80,0xfd,0xfb,0xde,0x74,0x49,0x53,0x04,0x3a,0x35,0xcb,0x45,0xe2,0x67,0x2c,0x4d,0x6e,0x39,0x7b,0xbd,0x68,0xaa,0x93,0x1e,0xee +.byte 0x1e,0x35,0xae,0x1e,0xf2,0xe7,0xb1,0x80,0x92,0x45,0x27,0x85,0xd0,0xc7,0x26,0x17,0x54,0x30,0xba,0x0c,0x8e,0x48,0xf3,0x08,0x51,0xa6,0x41,0x70,0xba,0x5b,0x90,0x69,0x7c,0x64,0x1d,0x61,0xb5,0x23,0x4a,0xef,0x97,0xe4,0x9a,0xd0,0xff,0x47,0x7a,0x93,0x1a,0x28,0xb3,0x8a,0x32,0x29,0xf8,0xe9,0x08,0xc3,0xf3,0x24,0xd7,0x2e,0x18,0x6d +.byte 0x99,0x40,0x77,0x43,0x9f,0x98,0xe4,0xe5,0x3a,0x34,0x9d,0x46,0x52,0x9f,0x84,0x79,0x8c,0x70,0xbc,0x88,0x30,0xaf,0x87,0x69,0x57,0x6e,0xde,0x2e,0xfe,0x0f,0x3b,0x8d,0xc8,0x95,0xcf,0x69,0x78,0xff,0xa1,0xb1,0x81,0x49,0x1e,0x45,0xc0,0x83,0x1b,0xa3,0x5a,0xee,0x3e,0x9a,0x15,0x7c,0xf0,0xa2,0xfd,0x04,0x22,0x55,0x2d,0x74,0x61,0x29 +.byte 0x0e,0x4f,0x31,0xdb,0x35,0x99,0x37,0xb7,0x7d,0x11,0xde,0x87,0x4f,0x84,0xeb,0x6c,0x14,0xcc,0xbb,0x71,0x47,0xab,0x5b,0x61,0x51,0xeb,0xa1,0xc1,0x5f,0xe4,0x5c,0x3c,0xab,0x04,0xf1,0x60,0x50,0xe1,0xd0,0x58,0xdf,0x42,0xed,0x73,0x5f,0x31,0xdf,0x8d,0xb8,0xb8,0xdc,0x4e,0x2f,0xe3,0x7f,0x89,0x9e,0x62,0xc9,0xef,0xfd,0x60,0xae,0x58 +.byte 0xa9,0xa5,0x8b,0xa8,0x3b,0xd8,0x5f,0xd4,0x09,0xff,0x61,0x8c,0x25,0xde,0x84,0x7f,0x35,0xc9,0x5c,0x2b,0xe8,0x46,0xe4,0x1c,0xbd,0x77,0x51,0x31,0x55,0x3d,0xb4,0x35,0xf3,0xdc,0xa5,0x55,0xd3,0xe3,0x24,0xf9,0x41,0xe2,0xf0,0xbd,0xf5,0xff,0x81,0x87,0x64,0xc9,0xe7,0x69,0x29,0x86,0xaf,0x98,0x33,0x33,0x62,0x9c,0x7b,0x16,0xbb,0xfe +.byte 0x0b,0xa7,0x92,0xa5,0x7b,0x81,0xbc,0x50,0x88,0xf6,0xe7,0xfc,0x73,0xd6,0x37,0x43,0x09,0xa5,0xc6,0xd6,0x4d,0x28,0xb5,0xaa,0x53,0x52,0x8c,0x2c,0x06,0x64,0x6c,0x21,0x6b,0xe7,0x67,0x4a,0xa5,0xcc,0xa1,0x32,0xf0,0xd9,0x78,0xb9,0xc3,0xdb,0x41,0xee,0x10,0x11,0x81,0x04,0x03,0x73,0x48,0xc6,0x3e,0x60,0x6d,0x82,0xef,0xe2,0xa8,0xe8 +.byte 0xd7,0xda,0xd9,0xb5,0x34,0x42,0xc8,0x1c,0xa7,0xa4,0x8e,0x88,0x2e,0xbc,0x96,0x0a,0xfc,0x40,0x36,0x80,0xdf,0x60,0xe9,0x03,0x02,0x0c,0x51,0xf7,0x7d,0x01,0xd2,0x21,0x38,0x44,0x4b,0x34,0x80,0xbf,0x5e,0xc1,0x86,0xf2,0x35,0xeb,0xa8,0x21,0x15,0x74,0x7c,0x99,0x55,0x64,0xf4,0x48,0xd6,0xd1,0x47,0x1f,0x4d,0xbf,0x0c,0x20,0x5d,0x86 +.byte 0xb9,0xab,0x4e,0xc8,0x86,0x08,0x71,0x1d,0x13,0xf6,0xd3,0x17,0xac,0x61,0x10,0x5d,0x2a,0xb4,0x48,0xa1,0xb9,0x79,0x5a,0x09,0x3a,0x65,0x4c,0xbd,0x97,0xbe,0x48,0xc6,0x66,0xd8,0xce,0x0c,0x19,0xb5,0x44,0x02,0xfa,0xb7,0xa8,0x3f,0x9b,0x86,0xec,0xd1,0xef,0x1d,0x7d,0xb3,0x82,0x5c,0x92,0x48,0x02,0x2c,0x56,0x0f,0xff,0xf7,0x19,0x74 +.byte 0xc2,0x38,0x24,0x8d,0xb2,0x87,0xb6,0xeb,0x49,0x50,0x6a,0x33,0x74,0x4e,0x2a,0xcb,0xf4,0x13,0x2c,0xfa,0x3b,0x0e,0x3d,0x98,0x3e,0x33,0xd9,0x55,0xfa,0xb9,0x74,0xb8,0x6f,0xc1,0xd8,0xfd,0x8f,0xff,0xb9,0x1a,0x17,0xf8,0xb6,0x21,0xc4,0x9d,0x47,0x5e,0x84,0xf6,0xe5,0xbf,0x93,0x98,0xac,0x8f,0x68,0x85,0xf8,0xe8,0x79,0x7f,0x6f,0x0d +.byte 0x62,0x2c,0xaa,0x1e,0xe4,0xab,0x73,0xf8,0x6f,0x02,0xda,0x6b,0x3c,0x14,0x2e,0xc9,0xdb,0xb0,0x4e,0x39,0xb5,0xcf,0x05,0xae,0x9c,0x63,0x2f,0x6a,0x25,0x61,0x9d,0x40,0xeb,0x7e,0xd8,0x97,0x97,0x33,0x67,0x5c,0x78,0x84,0x68,0xc2,0x7a,0x26,0x58,0xe3,0x6c,0x0a,0x2e,0x6a,0x82,0xd6,0x43,0xed,0x79,0xa5,0x8d,0x4e,0x7c,0xf7,0x80,0x01 +.byte 0xe7,0x02,0x5e,0x3a,0xf7,0x8a,0x4a,0x85,0xe9,0x98,0x1e,0x69,0x33,0xf3,0x54,0x96,0x79,0xc8,0x03,0x0a,0x9f,0x0c,0x5d,0x66,0x44,0x88,0x3c,0xd7,0x9e,0xd1,0xde,0x01,0xfd,0x5e,0xa5,0x6a,0x82,0x00,0x36,0xe6,0x12,0xe3,0x62,0x46,0x45,0x69,0xfb,0x4f,0x44,0x8e,0xe5,0x8d,0x21,0x57,0x6a,0x61,0x8e,0x56,0xcb,0x5b,0x2c,0x5f,0x65,0x41 +.byte 0x2c,0xad,0xf2,0x98,0x34,0xbb,0x06,0x0d,0x8a,0x3c,0x34,0x0d,0xa3,0xe2,0x6e,0x86,0xfa,0xa9,0xfb,0x6f,0xbb,0x32,0xd6,0x0d,0x76,0x6b,0x77,0xf3,0x83,0x41,0xc0,0x80,0x63,0x55,0x47,0xb8,0x13,0x6b,0x99,0x96,0x08,0x9b,0xc0,0x82,0xae,0x49,0x4a,0x51,0x63,0x74,0xf2,0xec,0xfa,0x0d,0xbc,0x3a,0xde,0xf5,0x4b,0x4f,0x08,0x41,0x23,0x88 +.byte 0x14,0x88,0x6a,0x3a,0xf0,0x5f,0x0c,0x45,0x7f,0x65,0x7a,0x67,0xd8,0x17,0xed,0x04,0x47,0x60,0x0e,0x74,0x8f,0xfd,0x48,0xda,0xcd,0xe9,0xfe,0xf5,0x6f,0x43,0xcd,0xa5,0x05,0xa2,0x2e,0x78,0x5b,0xff,0xb8,0x6f,0x2e,0xfd,0x3e,0x4b,0xef,0xcf,0xe0,0x06,0x57,0x28,0xf4,0x2e,0x3b,0xb5,0x9e,0x3c,0xbd,0x63,0xa6,0x78,0x8e,0xd5,0xb8,0x81 +.byte 0x4e,0xf0,0xbf,0x14,0x65,0xc8,0x00,0x9f,0x0e,0x25,0x6a,0x7a,0x63,0x58,0xe4,0xe7,0xa9,0x82,0x16,0xc9,0x86,0x20,0x94,0x71,0x5b,0x9f,0x9b,0xc3,0xc5,0x32,0xb0,0x6c,0x2b,0x8c,0x54,0x67,0x36,0x94,0xb1,0x47,0x33,0xfd,0x9f,0x7c,0x7f,0x7e,0x08,0x51,0x1f,0x7e,0xbf,0x09,0x57,0xf3,0xaa,0x77,0x94,0xf3,0x20,0x1b,0x95,0xf6,0x04,0xb2 +.byte 0x09,0x9d,0xe2,0xbb,0x4d,0xfe,0x6b,0x99,0x06,0x58,0x40,0x84,0x90,0xfa,0x0e,0x9b,0x58,0x6d,0x02,0xbe,0x53,0x73,0xd1,0xc9,0xc7,0x31,0x2a,0x4a,0x12,0x2c,0xb6,0x1c,0xfb,0x49,0xc6,0x1a,0x93,0x33,0x1f,0x29,0x8b,0x94,0xe9,0x20,0xa7,0xe6,0x20,0xe6,0xbf,0xcd,0x5c,0xb6,0x52,0x42,0xf0,0x9c,0x6c,0x21,0x61,0x10,0xe7,0x0e,0x9f,0x33 +.byte 0x5f,0xc8,0xd0,0x20,0xe0,0x3e,0xc5,0x7a,0x10,0xf1,0xe5,0x19,0x52,0xcd,0xe1,0xa8,0x62,0x43,0x20,0x79,0xc3,0xac,0x93,0x27,0x02,0x8e,0x21,0x06,0xb9,0x66,0xd9,0xc8,0x40,0xe0,0xd1,0xf0,0x64,0x81,0xa6,0xc4,0x87,0x85,0x2b,0x92,0x1c,0xd6,0x48,0x85,0xb1,0xbe,0x78,0xf3,0x89,0xa2,0xf0,0xe5,0x39,0xac,0xbf,0x59,0x5d,0xf8,0x4f,0x74 +.byte 0x44,0x85,0x98,0x03,0x81,0x4b,0x7e,0x6f,0x5c,0xa1,0x11,0xd2,0xfd,0x30,0x7f,0xcd,0xd0,0xe2,0xcc,0xd4,0x80,0x16,0x46,0xa6,0x64,0x8b,0x9e,0xfc,0x2a,0x1a,0x65,0x5c,0x90,0x82,0xf9,0x23,0x48,0x11,0xf6,0xf2,0x50,0x3f,0xed,0x44,0xf2,0x9a,0x5a,0xca,0x1c,0x9a,0xd2,0x71,0x1b,0xd6,0x4c,0x51,0xf6,0x89,0x6f,0x65,0xe4,0x97,0x41,0x47 +.byte 0x1b,0x86,0xbd,0x83,0xa0,0xfe,0xac,0x16,0xe8,0xab,0x28,0x96,0x2f,0xa2,0x12,0x5f,0x7c,0xb3,0x18,0x2b,0x05,0x51,0x49,0xba,0xb4,0x1f,0x1e,0xe6,0x8a,0x82,0xca,0x33,0x7d,0xe6,0x8c,0x95,0xba,0x08,0x60,0x47,0x6d,0x79,0xac,0x0f,0xba,0x46,0xff,0xed,0xe0,0x34,0x03,0xfe,0xa7,0x85,0xe5,0x61,0xe3,0xe4,0x6c,0x5c,0x1b,0x9d,0x8a,0x54 +.byte 0x17,0xaf,0x08,0x4c,0x44,0x7f,0xb7,0xb0,0x6a,0x3a,0xff,0xb7,0xf6,0x10,0xc4,0x8f,0x31,0xd6,0x1a,0x25,0x27,0x35,0xca,0x87,0xa9,0x61,0x0b,0x35,0x96,0x89,0x0f,0x1a,0xbd,0x1e,0xf6,0xee,0xaa,0x95,0x16,0xe4,0x38,0x7b,0xb2,0xbe,0xea,0xc9,0x5a,0xcd,0x3b,0xb8,0x9e,0xd7,0x20,0xcd,0x3f,0x90,0xaa,0x8b,0x2a,0x42,0xed,0xab,0xc1,0x53 +.byte 0x83,0xc7,0xb8,0x3f,0xa1,0xb9,0xf4,0xf4,0xb0,0xe0,0x1f,0xb0,0xeb,0xa9,0x81,0x9f,0x31,0x67,0x1e,0x6c,0x96,0x9f,0x09,0xea,0x04,0xfe,0x37,0x22,0x87,0x60,0xb9,0x91,0x8f,0xa9,0x11,0xa3,0x68,0x5e,0x29,0x21,0x41,0xa3,0x02,0x08,0x82,0xd0,0x2b,0x66,0x6d,0x3c,0x46,0xc7,0x23,0x09,0x86,0x7f,0x53,0x11,0x3e,0x83,0x52,0x0a,0x4a,0xe4 +.byte 0x93,0xc6,0xc1,0x96,0x17,0x94,0x51,0x17,0x69,0xea,0x72,0xb8,0x85,0xde,0x7e,0x13,0x4a,0x08,0x26,0xae,0x31,0x19,0x0f,0x6f,0x48,0xa1,0xf2,0x57,0xa2,0x01,0x8e,0x84,0xee,0x63,0x23,0xc0,0x97,0x84,0xa2,0xf5,0x3f,0xeb,0x30,0x9e,0xdd,0xd2,0x43,0x24,0xa2,0x57,0xb7,0x57,0x86,0x26,0xa3,0xe6,0x6e,0xf2,0xcd,0xfb,0x7b,0x34,0x74,0x53 +.byte 0x07,0x95,0x51,0xb7,0xfd,0xf3,0xd1,0x83,0xbd,0x25,0xd6,0x2c,0x69,0x73,0x02,0x8e,0x76,0x19,0xea,0xb0,0x83,0x60,0x8c,0x53,0x9d,0x77,0x86,0x1e,0x65,0xc7,0x57,0x31,0x29,0xd9,0xa9,0x3a,0xb2,0x0d,0xd8,0xf4,0xf9,0x48,0x49,0xfb,0x3c,0x40,0x3d,0x1b,0xc4,0x8b,0x94,0x0e,0x50,0x7f,0xd5,0x39,0x5e,0x57,0x86,0xd1,0xba,0x0c,0x38,0x10 +.byte 0x01,0x5f,0x44,0xf3,0xe5,0xb0,0xf8,0xae,0x17,0xdf,0xd2,0xb3,0x10,0xc5,0x3b,0xfd,0xd9,0x68,0x90,0x9c,0x6c,0x26,0xdf,0x12,0x50,0xfa,0xbf,0x8b,0xce,0x68,0x80,0x8c,0x04,0x60,0xbf,0x34,0x81,0xbd,0x29,0xa3,0xa2,0xe4,0xe0,0x2d,0x25,0xb2,0xff,0x9f,0xd1,0x20,0x07,0xd5,0x8c,0x19,0xfa,0x3f,0x47,0xec,0xc1,0x8d,0xc9,0x36,0xf8,0x51 +.byte 0x4c,0xaa,0x40,0xe3,0x6a,0x21,0xd5,0xe6,0xa6,0xcf,0x8c,0xd9,0x10,0x47,0x66,0xfd,0x32,0x48,0x36,0x8f,0x14,0xed,0x09,0x80,0x50,0x27,0xaa,0xd5,0x1f,0x69,0xb8,0xe4,0x96,0x27,0x56,0x78,0xd6,0xd5,0x2d,0xf0,0x4f,0x14,0x30,0x17,0x9e,0x5b,0x69,0x8c,0x7c,0x1c,0x97,0x38,0x65,0x77,0x75,0x49,0xac,0x4b,0x06,0xda,0x74,0x11,0x86,0xbc +.byte 0xad,0x01,0xf2,0x03,0x29,0x5d,0xa7,0x74,0xd3,0x44,0xae,0x1d,0xbf,0xf9,0xc5,0x5b,0x83,0x8c,0xd6,0x84,0x8a,0x8e,0xe9,0xa6,0x08,0xf4,0x88,0x13,0xcb,0x16,0x45,0x13,0x9c,0xc7,0x75,0xa9,0xa7,0x55,0x04,0x91,0xd6,0xe9,0xd4,0xe5,0x65,0xa0,0x3a,0x53,0xa0,0xfc,0x62,0xce,0x91,0x01,0xb4,0x06,0x8b,0x10,0x79,0x6f,0x2c,0xd6,0x0a,0xa2 +.byte 0x31,0x8f,0x75,0x32,0x0e,0xfa,0x0d,0xec,0xfd,0x71,0x7f,0x74,0x97,0x30,0xe9,0xee,0x9f,0x04,0x21,0xb5,0xc9,0xd1,0x52,0x2a,0x0f,0x18,0xbe,0x3e,0xbb,0x98,0xaf,0x59,0x9b,0x85,0x79,0x5e,0x52,0x93,0x1c,0x42,0x67,0x67,0x6b,0xd5,0x41,0xaf,0xba,0x09,0x3a,0xb4,0x0e,0x97,0x22,0xe6,0xbb,0xe1,0x27,0xa1,0xf9,0xf0,0xcd,0xa2,0x3d,0xdb +.byte 0x81,0x2f,0x65,0x90,0xb7,0xe5,0xe5,0xce,0x1d,0x3b,0xfe,0x34,0x57,0xcd,0x3a,0xbd,0x19,0x59,0x23,0x12,0xf1,0xb6,0xf2,0xf7,0xc1,0xf5,0x1d,0x0b,0x46,0x8f,0x16,0x6a,0x81,0xfe,0xc1,0x97,0x8d,0x69,0x55,0x60,0xdd,0xf0,0x61,0xe9,0x22,0x30,0x72,0x1a,0x24,0x30,0xd7,0xbc,0x1c,0xfa,0x02,0x55,0xfc,0xb9,0x4b,0x0a,0xe4,0x90,0x90,0x3a +.byte 0xe3,0xce,0xd4,0xa0,0x7d,0x21,0x5a,0xf7,0x79,0x6e,0x03,0x4f,0x4e,0x93,0xad,0xc4,0x8e,0x9d,0x9f,0x8a,0x39,0x59,0x20,0xc1,0x5d,0x6a,0x4d,0x8f,0x69,0x78,0xea,0xba,0xde,0xc0,0x87,0xb2,0xf2,0x20,0xd6,0x7a,0x9c,0xf9,0x09,0x03,0x2a,0x4d,0xb9,0x10,0xfc,0xe5,0x05,0x90,0xed,0x45,0x4f,0x5f,0x7c,0x5d,0xfa,0xe6,0x0d,0x07,0xae,0xcc +.byte 0x21,0xc8,0x1c,0x7a,0xfb,0x1d,0xb9,0xe3,0x69,0xa1,0xb7,0x5f,0xb5,0x6a,0xb9,0x58,0x9d,0xcd,0x99,0xf8,0x38,0xbb,0xa0,0xfe,0xf8,0x41,0x51,0x72,0xce,0x76,0x89,0x59,0xa2,0xab,0xef,0xea,0xab,0x79,0xbc,0xda,0x73,0xdb,0x18,0xda,0x60,0x1b,0xc4,0xb7,0x4f,0xb3,0x86,0x21,0x2a,0xc3,0xec,0x7f,0x0e,0x89,0x16,0x0e,0xd2,0xbd,0xea,0x0e +.byte 0xcf,0xc1,0x4b,0x2c,0x97,0x69,0xce,0xd3,0x94,0xad,0x81,0xe9,0x70,0xf4,0xf8,0xe5,0x77,0xe6,0x92,0xe0,0x23,0x38,0xd3,0xc1,0xdd,0x2e,0x58,0x77,0xc5,0xc3,0x29,0x34,0x66,0x48,0xf9,0x75,0x3c,0x8a,0x6a,0xb8,0xbf,0xf8,0xba,0xf0,0xb9,0xa1,0x81,0x0b,0xa1,0xaa,0x17,0x34,0x1a,0xbb,0xa3,0xa2,0xba,0x21,0x45,0xc0,0x1d,0x57,0x11,0x4d +.byte 0x9b,0xd4,0x64,0x84,0xd7,0x0b,0xd6,0xfb,0x72,0x2c,0xdb,0xc3,0xe6,0x24,0xa9,0xf3,0x30,0x9f,0x21,0x05,0x1e,0xcc,0x48,0x58,0xed,0xfd,0xb2,0x34,0xe3,0xf7,0x7e,0x56,0xee,0xdf,0xa4,0xbb,0xb1,0xcc,0x7f,0x81,0x40,0xe9,0xdf,0x3f,0x82,0xc4,0x0d,0x14,0x9b,0x3b,0x80,0x15,0x24,0x6e,0xa4,0xce,0xfa,0x28,0xa7,0x7f,0x89,0xfb,0xc6,0x83 +.byte 0xe8,0x2a,0x70,0xfb,0x9c,0x75,0xb8,0xfd,0xec,0xbc,0xbb,0xf5,0xef,0x0a,0xa5,0x77,0x0b,0x38,0xa0,0x63,0xa5,0x71,0x12,0xc9,0xaa,0xc3,0xf9,0x72,0x30,0x45,0x4e,0x19,0x44,0x2d,0x09,0xf4,0xf1,0xa8,0xe8,0xde,0x58,0x87,0x70,0xa8,0x91,0x86,0xef,0x5d,0x02,0x90,0x55,0x63,0x99,0xde,0xd7,0xb7,0x5f,0x07,0x01,0xdf,0xb1,0xe5,0x55,0xf5 +.byte 0x87,0x69,0xd2,0x7a,0x71,0xbc,0x0e,0x4b,0x8b,0x98,0xf7,0xf6,0x0a,0x01,0xbb,0x9f,0x1b,0x15,0xb6,0x76,0xe0,0xc0,0x4b,0x5d,0x08,0xba,0xba,0x73,0x3f,0x36,0x5a,0x29,0xd7,0x7c,0xc2,0x87,0x03,0x75,0xff,0x26,0x21,0xae,0xbe,0x66,0x70,0xa2,0x99,0x11,0x35,0x49,0x78,0x7b,0x3a,0xfe,0x94,0xf7,0x37,0xe0,0x69,0x56,0x39,0xf7,0x3f,0x71 +.byte 0x39,0x74,0x75,0x32,0x1f,0xfb,0x3a,0x87,0x07,0xab,0xf1,0xed,0xe3,0xe2,0xbf,0x3f,0xb1,0x73,0x11,0xc9,0x34,0x4b,0xb1,0x1e,0x62,0x4e,0xc1,0x8a,0xae,0xcc,0xc7,0xb3,0xa7,0x70,0x01,0x73,0xad,0xb3,0xc3,0x59,0x70,0x14,0x31,0x94,0x9f,0x6b,0x18,0x11,0x50,0x52,0xc9,0xf0,0xf8,0x12,0x9d,0x7c,0x90,0x64,0x9d,0xd9,0x41,0xa6,0x45,0xe3 +.byte 0xc9,0x25,0x73,0xe7,0x48,0x9d,0xdc,0xe0,0x2c,0x71,0xd3,0x68,0xc5,0xab,0xac,0xe3,0x16,0x95,0xe3,0xa5,0xae,0x2f,0x57,0x60,0x4b,0x11,0x90,0xaa,0xe7,0x48,0xca,0xc7,0xde,0x2e,0x56,0x10,0x8e,0xc3,0x0a,0x7d,0x66,0xf1,0xc3,0xf7,0x2d,0xdd,0xfa,0x5e,0xb2,0xcb,0x99,0x4d,0xaa,0x4e,0x91,0xc1,0x94,0x60,0x27,0x33,0x82,0xa6,0x2a,0xba +.byte 0x05,0x32,0x33,0x0a,0x30,0x47,0xb0,0xac,0x68,0x7d,0xef,0x25,0x09,0xcf,0x51,0xf4,0x06,0x28,0x14,0xb2,0xb4,0x1f,0xaf,0x37,0xdc,0x70,0x88,0x4d,0xb9,0xfc,0x2d,0x61,0x25,0x13,0x1f,0x32,0x48,0x6d,0xeb,0x46,0x05,0x66,0x44,0xa1,0xec,0xce,0xe9,0x51,0xa9,0xba,0xf8,0xde,0x95,0x1b,0x20,0xe1,0x21,0x75,0x4b,0x25,0x7f,0x3c,0x16,0xf7 +.byte 0xe2,0xbe,0xeb,0xca,0x2b,0x77,0x92,0x16,0x32,0xe2,0x74,0x21,0x52,0x3f,0x08,0xba,0x41,0xb0,0xd3,0xd2,0xf7,0xf3,0x29,0xb6,0x10,0xfa,0xa5,0x29,0x35,0x29,0x21,0x0d,0xec,0xba,0x5a,0xf3,0x63,0x0f,0x9d,0xbc,0x42,0x02,0x46,0xe9,0x07,0x4a,0x9a,0xe8,0xd3,0x78,0x92,0xa2,0xe5,0x03,0xec,0xd4,0xe2,0xc8,0x8f,0x92,0x4a,0xae,0xbc,0xd7 +.byte 0xdf,0x4b,0x07,0x22,0x47,0xbd,0xb4,0xb5,0xa0,0x7e,0xfb,0x21,0x40,0x62,0xb1,0x6c,0x07,0x00,0x64,0xf6,0xb2,0x75,0x5c,0x29,0x84,0xff,0x38,0x0c,0xc8,0x08,0x38,0x92,0xf9,0xad,0xd7,0xcc,0xc3,0x1c,0x03,0x80,0x49,0x39,0x1c,0xdb,0xae,0x60,0x87,0x8a,0x5c,0xe9,0x17,0xbd,0x2b,0x0f,0xa5,0xa1,0xf9,0x0d,0x4b,0x8c,0x4d,0x39,0xda,0x15 +.byte 0x8c,0xc4,0x69,0xaf,0x2b,0xb0,0xa1,0xfd,0xd9,0x65,0x3c,0x87,0x4b,0xf2,0x5a,0xd7,0xd8,0xb9,0xef,0x78,0x67,0x30,0x4c,0x6c,0x92,0xc5,0x1e,0x15,0xf8,0xd9,0x74,0x1b,0x54,0x0c,0x10,0x1b,0xb5,0x11,0x13,0xd6,0xb4,0xc0,0x53,0x03,0x2c,0x4b,0xee,0xac,0xf9,0x87,0x17,0x51,0x35,0xb8,0x1a,0xdc,0x16,0x61,0x5b,0xe9,0x5a,0x43,0x94,0x42 +.byte 0x8f,0x68,0xbd,0xb6,0x52,0x00,0x63,0xa3,0x52,0x6e,0x5d,0x8e,0xe9,0x4f,0xf5,0x69,0xd8,0x4f,0xf5,0x5c,0x89,0x7e,0x1c,0xb9,0xdc,0x7b,0x92,0x8a,0x2b,0xfc,0xb8,0xad,0xbb,0xff,0x61,0x2e,0xc0,0xdc,0xfb,0x2f,0x78,0x2a,0x50,0x32,0x9b,0x4c,0xfd,0x9e,0xab,0x80,0x5c,0x7d,0xc8,0x6b,0xb3,0x2d,0x0a,0xfe,0x43,0xa2,0x10,0x10,0x79,0xbc +.byte 0x8c,0xa0,0x86,0x09,0x8c,0x8b,0x28,0xf3,0x8a,0xc9,0xeb,0xcb,0xb5,0x0e,0x56,0x19,0xae,0xe0,0xa1,0x22,0x72,0xc5,0xad,0x01,0x12,0x69,0xb6,0x52,0xb8,0xdd,0x36,0x25,0x21,0xae,0x73,0x06,0xc1,0xe0,0x23,0x20,0xe1,0x8e,0xe4,0x99,0xcd,0x86,0xca,0xf5,0x93,0x0e,0x6b,0xb8,0xba,0x18,0x4a,0x36,0xed,0xd0,0x37,0xc8,0xc7,0x8a,0xb2,0x63 +.byte 0x2e,0xa4,0x22,0x76,0x6f,0xf7,0xdd,0x81,0xd6,0x6f,0xcd,0xb9,0x65,0xf0,0x95,0x77,0xae,0xca,0x54,0x62,0xce,0x5d,0x47,0x9e,0x10,0x89,0xb9,0xfa,0x72,0x0a,0xef,0x24,0x17,0x45,0xb0,0xb0,0xc7,0x51,0x85,0xa1,0xb1,0x6a,0xd2,0xea,0x48,0xe2,0x6a,0x03,0x2a,0xdf,0xa8,0x0e,0x62,0xa2,0x1e,0xe2,0xa7,0x20,0x57,0xbd,0x73,0xeb,0xef,0x86 +.byte 0xc9,0xd4,0xfa,0x96,0xfe,0xfa,0xb3,0xc6,0xbf,0x7a,0x16,0xa2,0x43,0x73,0x56,0x71,0x78,0x32,0x3b,0xc1,0xd8,0x26,0xbf,0xde,0x39,0x5d,0xbd,0x3b,0xff,0xd7,0x4f,0xa0,0x67,0xa6,0x09,0x9a,0x81,0xfd,0xec,0x34,0x73,0xcd,0x90,0x15,0x8b,0x3e,0x2d,0x6f,0x7d,0xcc,0xf5,0x20,0x15,0x07,0xa8,0x2f,0xa5,0x5b,0x2b,0x4f,0xb8,0x2f,0x14,0x6c +.byte 0x52,0x78,0xbd,0x92,0x98,0xda,0x69,0x19,0x58,0x4c,0x76,0xe4,0x20,0xb2,0x48,0xa4,0x9f,0x2f,0x4c,0x9b,0x45,0x7f,0x7d,0x1c,0x46,0xe9,0x1e,0x43,0x26,0x49,0x39,0xb6,0x42,0x3a,0x4c,0x59,0x95,0x6b,0x28,0xd5,0xbe,0xa7,0x2e,0xd0,0x0c,0x00,0xa0,0x67,0x06,0x4e,0xee,0xae,0x7f,0xc2,0xb5,0x12,0x46,0x3f,0xb4,0x35,0x16,0x2a,0xda,0xbf +.byte 0x41,0x34,0xbe,0x30,0x2a,0x0f,0x7b,0x60,0xa6,0x8b,0xcd,0xae,0x7a,0x8c,0xd6,0x97,0xab,0x06,0x1e,0x14,0x87,0x45,0xa3,0x3c,0x9c,0xc4,0xa0,0x1d,0xee,0xf0,0xca,0xb8,0xa6,0x8d,0x37,0x92,0xad,0xbc,0xe6,0x1f,0x65,0x75,0xd3,0xbc,0x72,0x66,0xe2,0xff,0xbc,0x19,0x93,0xae,0xee,0xd0,0x63,0x6d,0x97,0x6f,0x57,0xf3,0x77,0xcd,0xe3,0x57 +.byte 0x3f,0x00,0xc8,0xe1,0x63,0x83,0x15,0x84,0xc6,0x08,0xdb,0x03,0xc9,0x27,0x47,0x4c,0x17,0x12,0x40,0x6e,0xac,0x74,0x6f,0x3c,0x22,0x57,0x36,0x29,0xbb,0x6a,0xc7,0x5a,0xfe,0x60,0x1c,0x0f,0x32,0x95,0x1b,0xf2,0x3c,0xed,0x04,0x87,0x4c,0x48,0xc7,0x63,0x79,0x24,0xb3,0x12,0xbf,0x55,0x3b,0x32,0xbf,0x52,0x4e,0x1e,0xc1,0x1f,0xf2,0xfd +.byte 0xe6,0xb8,0x56,0x38,0x0e,0xd2,0x75,0x3d,0x41,0x99,0x0c,0x7a,0x12,0x3f,0xa7,0x3a,0x79,0xa0,0xd7,0x6f,0x47,0x97,0x7e,0x9e,0xf6,0xfe,0x29,0xc0,0x16,0x34,0x38,0x80,0x2f,0xde,0x65,0x79,0xc9,0xfd,0xa0,0x84,0xc3,0x39,0xbc,0x0b,0xbe,0x18,0xba,0x0d,0xe3,0x35,0x11,0xba,0x9f,0xde,0x5d,0x0c,0xae,0x8e,0x0c,0x0f,0x66,0x9c,0xe6,0xfc +.byte 0x3d,0xdb,0x46,0xf1,0x84,0x57,0x62,0xb0,0x00,0xd4,0x8c,0xaa,0x93,0xeb,0xf7,0xa7,0x8e,0x82,0xba,0x89,0x67,0xbb,0x38,0xb0,0xb6,0x13,0x0c,0x96,0x22,0x9c,0x6a,0x86,0xea,0x83,0xad,0x5f,0x7b,0x3a,0x28,0xd8,0x53,0x90,0x2d,0xab,0xc9,0xbe,0x99,0xfb,0x68,0x42,0x27,0xf6,0xe3,0x5a,0xaf,0xf3,0xd6,0xee,0xb6,0xa2,0xe0,0x32,0x3c,0x1d +.byte 0xd4,0x3c,0x2b,0x58,0xc2,0x4f,0x3d,0x20,0x39,0xdb,0x80,0x89,0x20,0x20,0x7b,0xe6,0x1d,0xd0,0xa2,0x1a,0xd4,0x88,0xc9,0xe0,0xb9,0xf6,0xb2,0xa1,0xcd,0xf2,0x67,0x60,0x44,0xd8,0xce,0x6a,0xe2,0x52,0xc3,0xf3,0x61,0xa3,0x14,0x58,0xd6,0xe5,0x43,0x4a,0x8d,0xcc,0x4f,0xf8,0x17,0xdd,0xd2,0x5d,0xd5,0x5a,0x86,0x8e,0xc4,0x74,0xdc,0x1b +.byte 0xad,0xca,0x63,0x75,0xf0,0x43,0x41,0x16,0x02,0x49,0x6a,0x3a,0xe3,0xb9,0xa9,0xdc,0xfb,0x99,0xbc,0x60,0x0d,0xdb,0xa0,0xcf,0x27,0xaa,0xd5,0xc5,0x42,0x0b,0x02,0x00,0x43,0xaf,0xb5,0x4f,0xe1,0x88,0xa1,0x9d,0xca,0xfb,0x9f,0x1f,0x08,0x9c,0x66,0x23,0xca,0x4b,0x88,0xb4,0x40,0xdc,0xd3,0xd3,0x1a,0x64,0xe3,0x9b,0x43,0xea,0x20,0x90 +.byte 0x30,0x2e,0xc4,0x75,0xc5,0x52,0xc5,0x7c,0x0e,0x35,0x56,0xf5,0x1f,0x50,0x2b,0xf6,0x28,0x93,0x6f,0xde,0x10,0xc6,0x49,0x2b,0x77,0xb1,0x6d,0xce,0xfd,0x37,0xd4,0x8d,0x11,0xed,0x88,0x1e,0xca,0x68,0x0c,0x4e,0x38,0x7f,0x0f,0xab,0x6f,0x8d,0x1c,0x7d,0xd4,0x7d,0xd8,0xa9,0x5c,0x24,0x5a,0x7d,0xf4,0x5b,0xb6,0xb7,0x28,0xc7,0x93,0xd6 +.byte 0xa9,0xe5,0xac,0x62,0x16,0x9c,0x4e,0x5c,0x24,0xa0,0x2a,0x76,0xce,0x7d,0x5c,0x4b,0xbe,0xbc,0x83,0x5c,0x9a,0xc8,0x06,0x7b,0x1e,0xac,0x98,0x67,0x17,0x32,0x94,0xda,0xd1,0x8b,0x58,0xad,0x8e,0x26,0x03,0x81,0x7c,0x48,0xd1,0x83,0x03,0xba,0x6c,0x51,0xe9,0x25,0x82,0xd2,0xb9,0x7f,0xd8,0x33,0x3f,0x77,0x29,0x45,0x41,0xa9,0x17,0x3d +.byte 0x62,0xc6,0xd2,0xfb,0xd1,0x24,0xc7,0xee,0x10,0xc0,0x64,0xc3,0x46,0xc6,0x2b,0xe8,0x9c,0xc8,0x99,0x23,0x77,0xa9,0xb5,0x12,0xc4,0x53,0xde,0xbc,0x20,0xb2,0xc4,0x12,0xdb,0xc2,0x0b,0x63,0x70,0x6a,0x41,0x31,0x65,0x48,0xa0,0xfc,0xbc,0xd6,0x3f,0x55,0x18,0x17,0x65,0x35,0x58,0xe3,0x33,0xac,0xaf,0xca,0xb2,0x51,0xc1,0xcc,0x60,0x38 +.byte 0x94,0x8f,0x13,0xb8,0xcc,0x8c,0xc4,0x12,0xea,0xd5,0x39,0xd3,0x46,0x55,0x17,0x27,0x7a,0x07,0x01,0x02,0x74,0xa6,0xe7,0xc8,0xa7,0xd0,0x76,0xc8,0x5e,0x57,0x50,0xc5,0x19,0xf1,0x95,0xa3,0x52,0x10,0xa3,0x1e,0xcd,0xb1,0x05,0x64,0xe5,0x69,0xd9,0x5e,0xfc,0x71,0xef,0xe1,0xf6,0xb3,0xa7,0xf7,0xf9,0x71,0xfd,0xbb,0x5b,0x2b,0x7a,0xd2 +.byte 0x72,0x7c,0xc7,0x73,0x89,0xf7,0xe2,0x0b,0xcd,0x05,0x4f,0x0c,0x10,0xed,0xcc,0xda,0xb6,0x81,0x19,0xe6,0x2b,0x06,0x66,0xef,0xc5,0xfd,0xd5,0xc6,0x66,0x20,0x86,0x2a,0x4f,0x05,0x49,0xf1,0x54,0x4a,0x6e,0x1d,0xcd,0xad,0x18,0xeb,0x6c,0x58,0xd6,0x75,0x3e,0x62,0x48,0xab,0xea,0x1f,0x7f,0x05,0x45,0x6e,0x75,0x2a,0x5e,0x97,0x5b,0xde +.byte 0x5a,0x99,0x42,0xc1,0x62,0xab,0xc7,0x01,0x4d,0xac,0xd6,0xdc,0xc9,0x71,0x24,0xd1,0x33,0xe2,0x4b,0x1f,0x09,0x04,0x1f,0x0d,0x42,0x45,0xcf,0x7c,0xa0,0xee,0x48,0xfd,0x8b,0x1f,0xaa,0x50,0x48,0x6d,0x8e,0x34,0x76,0x09,0x23,0x8a,0x40,0x0d,0x5d,0xc1,0x2a,0xba,0x5f,0x9c,0x86,0xfb,0x37,0xdf,0x24,0xff,0x27,0x88,0xbf,0xf6,0xa4,0xc3 +.byte 0xf0,0xd3,0x02,0xa8,0x7c,0x6d,0xc4,0xc5,0x14,0xc3,0x64,0x28,0xa8,0x05,0x33,0xc2,0xda,0x12,0xfc,0xbe,0x0d,0x8e,0xf4,0xf5,0x48,0x5a,0x8e,0x8a,0xd2,0x50,0x7c,0xc0,0xbc,0xde,0xdb,0x9a,0xf6,0xa0,0x92,0x8d,0x19,0xbc,0x5a,0xdc,0xbf,0xfb,0x13,0x8f,0x41,0x09,0xba,0xd9,0x0b,0x91,0x7a,0xdb,0x92,0x10,0xac,0xf2,0xb5,0x76,0xb5,0x7d +.byte 0x80,0x04,0xd6,0xec,0x98,0x09,0x5f,0x63,0x0d,0x58,0x00,0x8a,0x07,0x76,0xfa,0xe6,0x6e,0xdf,0xbf,0x73,0xe5,0xc9,0xe5,0x12,0x44,0x58,0xf9,0x2e,0xb1,0xe6,0x2c,0xf5,0x0d,0x94,0xa9,0x51,0x0d,0x01,0x03,0xab,0x79,0xf9,0xee,0x7e,0x10,0x4b,0xcb,0x20,0xbb,0x01,0x19,0xd6,0x12,0xd1,0xac,0x96,0xe9,0x0e,0xde,0xbf,0x7e,0x80,0xf6,0x58 +.byte 0xc9,0xec,0xaf,0xf7,0x2d,0x98,0xbc,0x2b,0xb1,0xf1,0x34,0x94,0x39,0x8e,0xbc,0x13,0x13,0x41,0x8f,0xf3,0x4e,0x4e,0x6b,0x2a,0xaa,0xea,0x70,0x5c,0xf8,0x42,0xf7,0xbc,0xfd,0xbd,0x6f,0x62,0x1b,0xcb,0xb9,0x39,0xdc,0x6a,0x47,0x81,0xaf,0xff,0x5b,0x7e,0x80,0xb9,0xbf,0xfa,0x15,0x7e,0xd1,0xc3,0xb2,0x80,0x99,0xbd,0xb9,0x30,0x8d,0xb5 +.byte 0x43,0x6b,0x7a,0x31,0xaf,0x45,0xf7,0xdd,0x21,0x8f,0x54,0xb1,0xf6,0x2d,0x7d,0x96,0x63,0x4a,0x93,0x98,0x37,0x7f,0x48,0x02,0x4b,0x0f,0x71,0xe4,0x70,0xce,0x66,0x6a,0x36,0xde,0x58,0x84,0x69,0xd6,0xbd,0x1a,0x9a,0x8b,0xc5,0xda,0x97,0xc5,0xe1,0x4e,0xec,0x9b,0x7a,0x65,0xe0,0xa5,0xdd,0x39,0x3c,0x9f,0xfd,0x45,0x17,0x4c,0x2f,0xb4 +.byte 0xb1,0xb1,0x42,0xe8,0x88,0x75,0x9f,0xb4,0xc1,0xdf,0x44,0xf9,0x4f,0x9a,0xf7,0x3d,0x35,0xc5,0x32,0xbe,0x43,0xd0,0x0d,0x71,0x4e,0x21,0xbf,0x31,0x99,0x73,0x5a,0x84,0x45,0x2e,0x00,0x8b,0x42,0x2b,0x14,0x86,0x51,0xcb,0xa0,0x98,0xa9,0x68,0x8d,0xdb,0x58,0x3d,0x73,0x9d,0xf9,0x2d,0x86,0x76,0x62,0xcb,0x93,0x29,0x48,0x92,0x38,0xfb +.byte 0xeb,0x1d,0xda,0xc3,0x10,0x1f,0x32,0x68,0xee,0xcb,0xb7,0x8a,0xcb,0xcb,0xe0,0x37,0x31,0xe8,0xad,0x7b,0x4a,0x29,0x2c,0x10,0x9e,0xdf,0x86,0xeb,0x13,0x0c,0xab,0xa4,0x30,0x36,0xf0,0xe0,0xac,0x14,0x41,0xa4,0xf4,0xf8,0x44,0x95,0xe8,0x8f,0x28,0xc2,0x35,0x0a,0x44,0x61,0xc7,0x60,0xc5,0x3b,0xc4,0x1d,0x67,0xfd,0xac,0x0b,0x2e,0x49 +.byte 0x62,0xea,0x17,0x3c,0xf5,0x4b,0xbe,0xba,0xba,0x42,0x02,0x0d,0x13,0xf1,0x15,0xff,0x2e,0x47,0x46,0xd1,0x27,0x64,0xb7,0x35,0x28,0x31,0xb5,0xde,0x1e,0xf9,0x26,0x6c,0x04,0x3c,0x0e,0x06,0x9d,0x4d,0xc7,0x1c,0x97,0x67,0x2c,0x6d,0x36,0x0d,0x4c,0x61,0x08,0xe9,0xbd,0x04,0x1d,0x8d,0xfb,0x0c,0x03,0x3d,0xb4,0x40,0xd5,0x1b,0x69,0x3b +.byte 0x68,0xcf,0x46,0x27,0xcf,0xb3,0xda,0x1e,0xdc,0x85,0x6f,0x4f,0x6b,0x09,0x9d,0xe9,0x6c,0x73,0x40,0x27,0xc9,0x8b,0x12,0x97,0xea,0x34,0xd7,0x51,0x32,0x90,0x4e,0xd7,0x91,0x41,0x3a,0xee,0xbc,0x97,0xb0,0x4a,0x39,0xdb,0xe3,0xe5,0x12,0x73,0xbf,0x5d,0x68,0xe0,0xc6,0x7c,0x6f,0x0d,0x14,0x1c,0xaa,0xde,0x29,0xb7,0xc7,0xa5,0x90,0x62 +.byte 0xe9,0xc5,0x75,0x16,0xe6,0xc0,0x9d,0xc5,0xb8,0xd6,0xfa,0xb0,0x72,0xb7,0x27,0xa6,0xa8,0x3f,0xbf,0x18,0x8b,0xaa,0x94,0xb3,0x47,0x50,0x2f,0x1c,0x49,0xab,0x46,0x38,0x7f,0x3e,0xf3,0xf1,0xb8,0xb3,0x44,0xaa,0x1f,0x76,0xb4,0x67,0xff,0xcf,0x7c,0x4b,0xa9,0xe1,0x62,0x93,0x4d,0x3e,0x96,0xdb,0x56,0xf6,0x26,0x5d,0x95,0x4c,0xfa,0x5f +.byte 0x06,0x2b,0x5c,0x33,0x2d,0xf8,0xfa,0x68,0x8a,0xed,0x28,0x2a,0x6e,0x95,0x86,0x59,0x71,0xef,0x86,0x47,0x60,0xec,0x35,0x79,0xa9,0x98,0x2d,0x6e,0x20,0x26,0x3a,0x21,0xec,0x59,0x15,0x65,0xcd,0xb9,0x91,0x19,0x6e,0x74,0x89,0x3b,0x10,0x00,0xab,0x8a,0x45,0x23,0x20,0x94,0x03,0x02,0x77,0xb7,0xcf,0x9c,0x71,0x18,0x0c,0x5b,0x40,0x62 +.byte 0x3b,0x8f,0xc9,0xf6,0x4c,0x8f,0x60,0x66,0x05,0x87,0x05,0x90,0xd4,0x08,0x76,0xd7,0xa3,0xb6,0x37,0xa8,0x83,0x05,0xb2,0x48,0xe9,0x24,0xc4,0xfb,0x79,0xa1,0xce,0xac,0x29,0x13,0x4e,0x72,0xdf,0xad,0x9e,0x5b,0xcd,0x9c,0x39,0x1d,0x3e,0x57,0x9d,0xf2,0x96,0x13,0xa4,0x79,0x4c,0x76,0x40,0x03,0xb3,0x18,0xcf,0xd7,0x45,0x2a,0x2d,0x07 +.byte 0xe5,0x2e,0xb7,0x74,0xda,0x94,0xea,0x32,0x74,0xb0,0xca,0xf4,0xd1,0x09,0x97,0x3c,0x69,0x17,0xf6,0x5b,0x13,0x7b,0xb8,0xb1,0xd9,0x0e,0x12,0x44,0x29,0xea,0x26,0xd8,0xaa,0x9d,0x26,0x87,0x0c,0x89,0x4e,0xec,0x29,0x48,0x43,0x66,0x21,0x0b,0xab,0xce,0x40,0x57,0x4c,0xa7,0xdd,0x56,0xde,0xac,0x5c,0x62,0xea,0xc4,0x54,0x4a,0xe0,0x8d +.byte 0x54,0xc8,0x65,0x44,0xcc,0x6f,0x2a,0xcd,0x0e,0xb3,0xad,0xa3,0x30,0xd1,0xb7,0x19,0x70,0x51,0xd3,0x9a,0xcf,0xe5,0x42,0x6c,0xa1,0xc1,0x0f,0xe2,0xda,0x86,0xb4,0x51,0x50,0x62,0xdc,0x51,0x3f,0xd2,0xff,0xde,0x7f,0x38,0x5a,0xff,0x2d,0x21,0x1d,0x59,0xb9,0xdd,0xde,0x83,0x13,0xb0,0x25,0xf5,0xbb,0x11,0x47,0x4a,0xaf,0x81,0x15,0xa0 +.byte 0x39,0x5b,0x30,0x17,0x2b,0xbf,0x5a,0x03,0x60,0xb6,0xbb,0x86,0x9f,0x50,0x45,0x15,0x0b,0xba,0x42,0xf4,0x3d,0x05,0x62,0xcd,0x9b,0x8c,0xcf,0x93,0x5c,0x33,0x6c,0xea,0x4b,0xd0,0x1d,0x91,0x3e,0xbf,0xa4,0x9d,0x7c,0x2c,0x87,0x9c,0x42,0x9f,0x03,0x98,0x03,0x1b,0x98,0x66,0x4f,0x8f,0x29,0x12,0xc5,0xb5,0xec,0x81,0xf8,0xb2,0x5e,0x44 +.byte 0x4f,0xb0,0x31,0xe4,0x2a,0x73,0x83,0xac,0x5a,0x3f,0xfa,0xcf,0x8b,0x7c,0xa3,0xf1,0x01,0x14,0xa1,0xca,0x60,0x8d,0x6a,0x6c,0x04,0x31,0xcc,0xba,0x12,0xe0,0x4e,0xaf,0x01,0x8d,0xf5,0x60,0x23,0x79,0x8a,0x80,0xcc,0x32,0x31,0x69,0x83,0xb6,0x83,0xaa,0xd9,0x3b,0x86,0x4a,0xd8,0x10,0x28,0x09,0x82,0x36,0xee,0x6a,0xc0,0x80,0x3f,0xfd +.byte 0xb1,0xd2,0xde,0x34,0xf9,0x4c,0x87,0x5b,0xdd,0xd0,0xb6,0x2d,0x99,0x69,0xd3,0x2c,0xb7,0x0b,0xfc,0x16,0x88,0x7b,0x80,0x21,0xbc,0x30,0x7b,0x56,0xe5,0x7b,0x41,0x43,0x4d,0xaf,0x40,0x5e,0x74,0x14,0x17,0x66,0x32,0xd6,0x81,0x53,0x94,0x35,0xf0,0x0f,0x4f,0x99,0x54,0x9a,0x38,0xc0,0x2a,0xa9,0xd3,0x53,0xdd,0x9a,0xc5,0x29,0x18,0x62 +.byte 0xf6,0x93,0xa3,0x02,0xf0,0x13,0xcb,0xcb,0xcc,0x64,0x0b,0x00,0xf4,0x43,0x03,0x26,0xe6,0x2f,0x39,0xa1,0x83,0xea,0x94,0x2f,0xde,0x61,0xbd,0xe1,0xbe,0x08,0xf8,0xd4,0x01,0x6e,0x61,0x98,0x01,0x39,0x4b,0x93,0x39,0x38,0x34,0x58,0x24,0xc1,0xf5,0x03,0x05,0x15,0x9c,0xf0,0x30,0x20,0x24,0xd4,0x7e,0x73,0xb2,0x60,0x06,0x3b,0xd3,0xb7 +.byte 0x2c,0x47,0x17,0xc4,0x79,0x4e,0x45,0x0b,0x89,0xf0,0xfc,0x42,0xa0,0x0d,0x80,0xd2,0x44,0x36,0x70,0xaa,0x9e,0x72,0x85,0xa8,0xc8,0x1d,0x35,0x28,0xc3,0x5a,0x72,0x4c,0x06,0x6d,0xf4,0xae,0x54,0x86,0x9a,0x32,0x3c,0xa5,0x06,0x63,0xc1,0x37,0xbb,0xaf,0xa6,0xae,0xce,0x94,0xea,0x9c,0x4a,0x9e,0x56,0xb1,0xc3,0x84,0x84,0xef,0x3d,0xe9 +.byte 0x24,0xf4,0xbf,0xc3,0xf6,0x45,0x74,0x4e,0xbb,0x86,0xd3,0x7f,0xab,0x19,0xe3,0x63,0x67,0x81,0xb6,0x18,0xc8,0x78,0x8e,0xf8,0x83,0x5f,0xfb,0x2e,0x49,0x97,0x2b,0x34,0xbb,0x76,0x2e,0x93,0xec,0xe9,0x7f,0x4d,0x7e,0x52,0x0c,0x92,0xbc,0x6d,0x3a,0x34,0x9b,0x5e,0x61,0x6f,0xea,0x45,0xe7,0x5c,0x34,0x6b,0xcb,0xc0,0x31,0x61,0x64,0x9d +.byte 0xad,0x7f,0x98,0xca,0xfe,0x3d,0xad,0xf7,0x21,0xf6,0x4c,0x2a,0x21,0x07,0x80,0x25,0xa2,0xea,0x26,0x85,0xc3,0xb1,0x74,0x04,0x7f,0xd1,0x1c,0x1b,0xa5,0x7e,0x96,0x45,0xfe,0x6f,0xa6,0x34,0xdf,0x94,0x1f,0x7e,0xfb,0xcf,0xfd,0x29,0xeb,0x3a,0xb0,0xfc,0xb6,0xd5,0x80,0x8b,0x37,0x71,0xfb,0x70,0x19,0x30,0xc4,0x6f,0xa0,0x5b,0xae,0x5b +.byte 0x75,0x51,0x98,0x89,0x9e,0xf0,0xf5,0x79,0xaf,0x1c,0x07,0xb6,0x5e,0xcf,0x34,0x70,0x0f,0x0b,0xbc,0x0a,0xa6,0x40,0xc7,0xf8,0xe4,0xef,0xe6,0xb7,0x94,0x6e,0x98,0x75,0x22,0x73,0x5c,0xca,0xcc,0xfb,0x09,0x2f,0x9c,0xfe,0x49,0x0f,0xd3,0x65,0xfe,0xd4,0xf0,0x9b,0xeb,0x8c,0xd7,0x8c,0xff,0x4b,0x18,0x3e,0xf3,0x9d,0x3f,0xf5,0x83,0xd6 +.byte 0x1d,0x3d,0x23,0x79,0x0f,0xae,0x17,0x62,0x33,0x07,0xc3,0xac,0x98,0x07,0x72,0x9b,0xd9,0x26,0x5c,0x1a,0x9d,0xf1,0x35,0x92,0xf9,0x38,0x17,0xf8,0xee,0x26,0xf9,0x64,0xfc,0x5e,0x8b,0x80,0xce,0xdb,0x64,0xf7,0xde,0x20,0x19,0x5c,0x26,0xf6,0x23,0xd6,0x99,0x8e,0x75,0x77,0x3d,0x17,0x0f,0xea,0x31,0x5a,0x65,0x32,0x1b,0x78,0x78,0xe4 +.byte 0xfe,0x76,0xf8,0xa7,0x81,0x34,0xf1,0x2a,0x13,0x22,0xe4,0x8a,0xe1,0x42,0x5a,0x3f,0x44,0x22,0xeb,0x7e,0xcd,0x20,0xcd,0xf7,0x44,0x1a,0x87,0xb9,0x7a,0x0e,0xf8,0xcb,0xb5,0x0a,0x1f,0x6a,0xe6,0x0b,0x70,0x59,0x38,0xa3,0x6b,0x64,0x7b,0x61,0xfe,0xbd,0xa4,0xb7,0x89,0x7a,0x28,0x70,0xfe,0x9d,0x64,0x2c,0xe9,0xc4,0xc9,0x2f,0xc8,0x3e +.byte 0xfa,0x70,0xce,0x21,0x9b,0xa8,0x10,0x6a,0x16,0xdd,0x28,0xce,0x4e,0xd4,0x6c,0x8c,0x47,0x83,0x13,0x8b,0xec,0x1c,0x76,0xdc,0x4d,0x81,0x25,0x08,0xd8,0xf9,0xde,0x66,0x1d,0xe2,0xf3,0xe7,0xdc,0x3e,0x3c,0x6b,0x98,0x25,0x55,0x88,0xe8,0xda,0x7f,0x16,0xe5,0x7d,0xad,0x8a,0x36,0x00,0xf0,0x68,0xc5,0xe4,0xfc,0xe9,0xe3,0x54,0xeb,0x4c +.byte 0xd1,0xff,0x07,0x1a,0x5c,0x5e,0xd4,0xb1,0xff,0x7d,0xfc,0x5b,0x34,0x42,0x95,0x89,0x01,0x24,0x8e,0x30,0xec,0xfe,0x67,0xf8,0xe2,0xaa,0xd5,0x6a,0x9f,0xe3,0xc3,0xa5,0x53,0x7f,0xd3,0xf4,0x98,0xa5,0x47,0x11,0xad,0xac,0xea,0xba,0x20,0x34,0x03,0x65,0x8c,0xec,0xb6,0xa3,0x2b,0xf6,0x93,0xe1,0xc8,0xad,0x34,0x30,0x8f,0x0e,0x3b,0xf6 +.byte 0x63,0xc6,0x58,0xc3,0xe8,0xa3,0x85,0xf8,0x24,0x8e,0x21,0xb9,0x36,0x7c,0xe0,0x11,0x64,0x31,0x6a,0x6a,0xa2,0xad,0xd3,0x94,0xbb,0x13,0x5b,0xb4,0xe9,0xee,0x09,0xdc,0xfe,0xb2,0xad,0xa8,0x43,0x02,0xba,0x85,0x1f,0x56,0xcb,0xb5,0x95,0x32,0xcc,0x7e,0xe0,0x00,0xde,0xfa,0x3f,0x91,0x71,0xde,0x21,0x19,0xff,0xc9,0x97,0x43,0x95,0xd8 +.byte 0x0d,0xc2,0x8a,0xde,0xcc,0x34,0x48,0xf4,0x35,0x41,0xb8,0x56,0x52,0xce,0x06,0xb3,0xcf,0xd4,0xae,0x7a,0xcb,0xe9,0xed,0x37,0xd6,0x76,0xa0,0x77,0x04,0xfb,0xb7,0x41,0x25,0x38,0xe1,0xd1,0xb5,0xde,0x21,0xe0,0x64,0xd8,0x83,0x13,0x7b,0x4b,0xb8,0xc9,0x12,0x02,0x51,0x56,0x52,0xe9,0x1c,0x49,0x48,0x83,0xd0,0x99,0x73,0x60,0x4a,0x4c +.byte 0x7d,0x8d,0x43,0xf9,0x06,0xa4,0xbb,0x0e,0xb6,0xdd,0x5f,0xc7,0x5e,0x35,0xcb,0xa0,0xc1,0x66,0x4a,0xe3,0x4a,0xa9,0xec,0xa4,0x5a,0xd7,0xd6,0xea,0xa5,0x20,0xa6,0xc3,0x1b,0xc0,0xa8,0xd1,0xf1,0x08,0x05,0xab,0x40,0x14,0x35,0xf2,0xdd,0x0f,0xc5,0xda,0xb3,0xa6,0xb1,0x07,0x36,0x17,0x5d,0xe9,0x96,0x23,0x96,0x46,0xd4,0xa7,0x71,0x64 +.byte 0x13,0x72,0x4e,0x83,0xe0,0x65,0x40,0x41,0xaf,0xb6,0x5b,0x00,0xa2,0xab,0x09,0x7f,0xa5,0xd5,0xc2,0xd9,0xc0,0x68,0x2a,0x44,0xdc,0x43,0x37,0x81,0xb8,0x88,0x4c,0x85,0x1b,0xb1,0x83,0xb2,0x56,0xa3,0x91,0x0f,0xa6,0x70,0x3f,0xbd,0xe9,0xda,0x40,0x9b,0xf5,0x9e,0x53,0xed,0x5f,0x84,0x70,0xd2,0x4c,0x1c,0xb6,0x87,0xd6,0xbb,0x3b,0xec +.byte 0xe5,0x35,0x1b,0x2c,0x9b,0xf1,0xe5,0xf8,0x0e,0x07,0x98,0xcc,0x58,0x38,0x57,0x74,0xdb,0x0e,0x08,0xd9,0x56,0xe8,0x08,0x63,0x3d,0x94,0x4a,0xdc,0x59,0xfc,0x3d,0xc1,0xa4,0x36,0xc3,0xe8,0xbe,0x4b,0xd7,0x47,0x69,0x33,0xb8,0x72,0x30,0x59,0x28,0x4e,0xf1,0xc1,0x25,0xa3,0xa4,0xe3,0x12,0xcf,0x31,0xf6,0xf8,0xae,0x31,0x06,0x76,0x92 +.byte 0x64,0x87,0x8e,0xb0,0x9f,0x1d,0xf4,0x56,0x73,0xc5,0x5d,0xbb,0x80,0x0d,0x19,0x3f,0x56,0x8c,0xe4,0xd6,0x8a,0x9a,0x62,0x26,0x4e,0x8a,0x21,0x7d,0x72,0x34,0x87,0xb6,0x7e,0x49,0xdc,0xfd,0x27,0x95,0xba,0x25,0xdd,0xf4,0x58,0x2b,0x11,0x3f,0xd1,0xd7,0x13,0x1d,0xb0,0xec,0xe2,0x55,0x5e,0x72,0xea,0x36,0xc9,0xd8,0x61,0xc0,0xee,0xc4 +.byte 0x9f,0x35,0x7e,0x73,0xd3,0xf6,0xd7,0x6a,0xce,0xd6,0xd2,0x80,0xe6,0x10,0x4b,0x65,0x18,0x6f,0xab,0xd3,0x41,0xbb,0x39,0x36,0x95,0x84,0x3c,0x99,0x9a,0xfd,0xf0,0xa3,0x46,0xdf,0x48,0x7c,0xd5,0x57,0x9d,0x10,0x59,0xca,0x70,0xc4,0xb5,0xbe,0x47,0x9e,0xca,0x2b,0x49,0x54,0xbb,0x34,0x8e,0x39,0xf4,0xf8,0x8c,0xa5,0xa1,0xab,0xf6,0x51 +.byte 0xd8,0x22,0x9a,0xd5,0xc2,0x12,0xf8,0x26,0xc6,0x19,0x2a,0xa6,0x6e,0xab,0xd3,0xac,0xd1,0x21,0x97,0x67,0x3e,0x39,0x90,0x5c,0x37,0x65,0x7b,0x06,0x54,0x1a,0xb8,0x2a,0x56,0x02,0xa3,0x92,0xee,0xf3,0x38,0x53,0x25,0x4d,0x5d,0x0a,0x37,0x9e,0xbb,0xf4,0xb2,0x13,0x77,0xbb,0x93,0xa9,0x85,0xf2,0x15,0xfd,0x71,0x17,0x00,0x89,0xe7,0x7b +.byte 0xa9,0xdc,0x10,0xd9,0xc7,0x44,0xa5,0x7b,0x3f,0x2f,0x1e,0x6d,0xa7,0xfe,0x0c,0x0e,0x83,0x3e,0x38,0x27,0xa7,0x4e,0x85,0x3c,0x84,0xfe,0x95,0x48,0x85,0x09,0x75,0x62,0x1d,0xa4,0x64,0x54,0xed,0x89,0xd5,0x28,0x62,0x52,0x18,0xef,0xf0,0x57,0x05,0x30,0xf0,0xce,0x87,0x05,0x0d,0x81,0xe8,0x2a,0x3c,0x8c,0x22,0xe1,0x4b,0x32,0x42,0x9d +.byte 0x02,0xc5,0xe4,0x6a,0xa4,0x4d,0x9b,0xc4,0x82,0x47,0xdc,0x61,0xbd,0x82,0x01,0xcd,0x5e,0x64,0x9f,0x4c,0xe3,0x31,0xe9,0x48,0x53,0x85,0x07,0xc7,0x47,0x49,0x35,0xd8,0x6a,0xab,0x4f,0x73,0x3f,0xd3,0xde,0x87,0x29,0xac,0xbc,0x35,0x0a,0xb4,0x74,0xc2,0xa7,0x0b,0xb1,0x93,0x92,0x29,0x3b,0x3e,0xa8,0xde,0x12,0x49,0x75,0xda,0x16,0x27 +.byte 0x52,0x2f,0x93,0x23,0xd6,0xf7,0x10,0xfe,0x1e,0x93,0x97,0x06,0x9d,0xef,0x4f,0xe4,0x3d,0x5d,0xde,0x30,0x70,0x3d,0x78,0x3a,0x30,0x00,0x9b,0x77,0x12,0x90,0x62,0xda,0x32,0x9b,0x6a,0x47,0xd7,0x0f,0xee,0x75,0x18,0xdd,0x4d,0x8a,0xe2,0x35,0x5b,0x60,0xb8,0xf9,0xa4,0x6c,0x93,0x3e,0x47,0x23,0xed,0x7a,0xe2,0x58,0x42,0xd6,0x3f,0x90 +.byte 0xc0,0x12,0x38,0x8b,0x70,0xe0,0xf8,0x1a,0xb5,0x8d,0xe1,0x39,0xdf,0x93,0x25,0x72,0x2e,0xa9,0x3f,0x58,0x12,0x40,0xc4,0x92,0x46,0x08,0xf0,0x64,0xdd,0x34,0x42,0xfe,0x74,0x35,0x0c,0xda,0xef,0x06,0x0b,0x33,0x59,0xd9,0xee,0x4c,0xf9,0x02,0x3a,0x93,0x40,0xa3,0x99,0x0e,0x64,0x11,0x2f,0x52,0x9d,0x28,0x4d,0xe8,0x45,0xd0,0x22,0xd7 +.byte 0x8f,0xd6,0x28,0x8c,0x0e,0x18,0x87,0x24,0xf9,0x88,0xd2,0xc0,0xe8,0xd4,0x9d,0xa2,0x5a,0x79,0x83,0x37,0x18,0x84,0x12,0xca,0xc7,0x10,0xd5,0x5a,0xa8,0xe5,0xa8,0xe7,0x79,0xb6,0x2c,0xb3,0x90,0x6c,0xc5,0xa4,0x99,0x1b,0x85,0x29,0x78,0x0b,0x09,0x77,0x05,0xf4,0x23,0x79,0x5c,0x91,0xf3,0xe0,0xe4,0x6f,0x82,0x33,0x4e,0xa2,0x2e,0xa2 +.byte 0x65,0x79,0xad,0x98,0x36,0x34,0x72,0x97,0xd7,0x39,0x89,0x5e,0x82,0x9f,0x4c,0xe2,0xea,0x51,0x85,0x62,0x0c,0x39,0xf6,0xdc,0xc6,0x80,0x48,0xcf,0x98,0x93,0x64,0x7d,0xf9,0x63,0xf4,0xf5,0x18,0x2a,0xb6,0x04,0xb7,0x44,0xc4,0x60,0xc0,0xcf,0x3d,0x88,0xa8,0xb6,0x81,0xa3,0x99,0x2a,0xf0,0x1a,0x8d,0x76,0x20,0x1d,0xcc,0x10,0x50,0x58 +.byte 0x09,0xf9,0xda,0x65,0x60,0xc3,0xb1,0xc1,0xc0,0x4d,0x62,0x52,0x22,0x45,0x32,0xbc,0x11,0x93,0x15,0xb6,0x25,0x8f,0x65,0xa0,0x4c,0x88,0xc9,0x83,0xe1,0x5c,0xbb,0xfb,0x1a,0xab,0xdb,0x35,0x40,0x66,0xc0,0x2f,0xdc,0xf5,0x92,0x08,0x4c,0xc7,0xb8,0x49,0x05,0xe0,0xe1,0x61,0x2b,0xde,0xc7,0x6a,0x04,0x05,0x4d,0x9f,0xe9,0x59,0x22,0x56 +.byte 0x63,0x77,0x9d,0xe3,0x1e,0x36,0xdf,0x87,0x4a,0xeb,0xba,0x42,0x3d,0x1b,0xa5,0xd0,0xc5,0x44,0x07,0xbe,0x37,0x37,0x70,0x10,0x2d,0x02,0x9b,0xf6,0x52,0xf3,0x54,0x6d,0x50,0xdb,0xdb,0x57,0x01,0x0b,0x9b,0xd5,0x99,0x99,0x69,0x9b,0x10,0x76,0x48,0xea,0x28,0x27,0x06,0x30,0x63,0x3b,0xdf,0x06,0x30,0x37,0x28,0x75,0xcf,0x9c,0xe7,0x52 +.byte 0x43,0xe2,0xd5,0x7b,0xfa,0x88,0x98,0x9c,0x3e,0x27,0x30,0x21,0xcc,0x11,0x71,0x14,0x24,0x04,0x1a,0x8c,0xe9,0xfe,0x2f,0x9d,0xec,0xb1,0x10,0x33,0x05,0x31,0x01,0x1b,0xde,0x6b,0x30,0x20,0x6d,0xf4,0x7c,0xbf,0x41,0x04,0x5f,0xb9,0x9c,0x24,0x63,0x74,0x98,0x3e,0x60,0xc7,0xf1,0xb1,0xc6,0x94,0xf3,0x6f,0x95,0x24,0xdf,0x97,0xd5,0xc7 +.byte 0x50,0x19,0xaf,0xa5,0xae,0x51,0xde,0x6d,0x44,0x0c,0x90,0x72,0x11,0x82,0x04,0xf9,0xda,0x17,0xd8,0xf3,0x03,0xf2,0x03,0x3f,0x65,0x7f,0xd7,0x66,0x84,0x9a,0x02,0x90,0x2b,0x65,0x00,0xd9,0x9c,0xfb,0xaa,0xe2,0xde,0x5f,0x1e,0x19,0x1e,0x6d,0x20,0x1e,0x01,0xf1,0xca,0x7b,0x90,0x06,0x96,0x1d,0x7a,0x34,0x0c,0x66,0x57,0xd7,0x61,0x1f +.byte 0x74,0x03,0xcb,0xae,0xea,0xaf,0x65,0x8e,0x32,0xbe,0xb8,0xe6,0xd8,0x6d,0xf7,0x51,0x6d,0xec,0x7e,0xc6,0x9d,0x20,0x01,0xbf,0xd7,0xbc,0xcb,0x34,0x7c,0xe5,0x1f,0x92,0x72,0x2f,0x6f,0xa3,0x1f,0xe8,0x4d,0x7e,0xa5,0x85,0x3b,0xed,0xc7,0x25,0x53,0xe3,0x77,0x90,0x1f,0xda,0xb7,0x48,0x7d,0xbe,0x20,0x48,0x9f,0xb4,0x05,0x5d,0x41,0xc5 +.byte 0x48,0xd0,0xc9,0x83,0xbe,0xf8,0xd8,0x6b,0x0d,0x26,0x66,0x2e,0xef,0x6b,0x13,0x58,0x6b,0x5f,0x0e,0x8b,0x4e,0x57,0xb2,0x6b,0x3d,0x4d,0xcd,0xcb,0x9a,0x9b,0xda,0x4d,0x7f,0xea,0x17,0x06,0x7f,0xcd,0xaf,0x18,0xda,0x3d,0xf0,0x30,0x2e,0xbb,0xc2,0x1d,0xcf,0xde,0xf7,0xee,0xda,0xd6,0x3d,0x75,0xcf,0x19,0xcf,0xfc,0xdf,0x7a,0xb6,0x1f +.byte 0x89,0xf5,0x0c,0xe9,0xd5,0xf1,0xd0,0x40,0xbd,0xae,0xb5,0x16,0xf6,0x05,0x1e,0xba,0xcd,0x18,0x80,0x4a,0xb3,0x87,0x93,0x6b,0x19,0xfc,0x47,0xa8,0x45,0x4b,0x75,0xe8,0x06,0xc0,0xbd,0x86,0xf7,0xcf,0x2c,0x39,0xc6,0x0b,0x3f,0x32,0xcd,0x1c,0x02,0xec,0x4b,0xd5,0x90,0x84,0xaf,0xc9,0x5c,0x9e,0x64,0x82,0x13,0x81,0x05,0x03,0xe4,0xed +.byte 0x48,0x23,0xc3,0x53,0x2c,0x5a,0x22,0x0a,0x27,0x7e,0x55,0x79,0xdc,0x46,0xf5,0x4b,0x04,0xcc,0x43,0x87,0x6c,0xb5,0xa4,0x2d,0x78,0x70,0x02,0x43,0x0e,0x76,0x62,0x99,0x86,0x40,0x2a,0xe4,0x62,0xe6,0xee,0x4e,0x03,0x64,0x83,0x9c,0x38,0x6d,0x62,0xa6,0x85,0xb8,0xce,0xd7,0xf8,0xcb,0x78,0x00,0x7a,0x48,0x72,0x75,0x4e,0x9c,0x6f,0x0c +.byte 0x61,0xc7,0x93,0x4e,0x6d,0x65,0xa3,0x1b,0x17,0x84,0xc6,0xd2,0x29,0xc3,0x4d,0xe3,0x14,0x21,0x5f,0x9e,0xa9,0x28,0x11,0xf3,0xb2,0xe8,0xe7,0x60,0x9e,0x24,0xab,0x88,0x9c,0x9c,0x5e,0x17,0xe4,0xe1,0xa7,0x74,0xb4,0x82,0xd5,0xaa,0x92,0x08,0xa7,0xa2,0x04,0x6f,0x77,0x14,0x54,0x44,0x5d,0x13,0x10,0xa2,0x40,0x1d,0xf0,0x44,0x16,0x17 +.byte 0xda,0x8c,0x80,0x83,0x2b,0x19,0xb8,0xab,0xf2,0xb8,0xb1,0x92,0xb5,0xc5,0x05,0x3e,0xd2,0x1a,0xfc,0xfd,0x21,0xa6,0xb2,0xbd,0x89,0xee,0x9c,0x3c,0x90,0xd9,0xf1,0xd2,0xe8,0xc3,0x21,0xb9,0x0e,0x0c,0x98,0xbc,0x5e,0xa1,0x0d,0x89,0xfe,0x0f,0x3c,0x45,0xea,0xe1,0x6e,0x06,0x59,0xff,0x79,0xf4,0x7e,0xf4,0x82,0xc0,0x6b,0xd9,0x53,0x30 +.byte 0x98,0xed,0x8d,0x6f,0x3d,0x0e,0xfb,0x42,0x66,0xab,0x41,0xa8,0x4a,0xef,0x73,0xa4,0x54,0x99,0x4f,0xb6,0x65,0x44,0xf9,0xd9,0x3c,0x6b,0x59,0x36,0xb0,0xe3,0x7c,0x4a,0x85,0x80,0x6c,0x77,0x6f,0x34,0x4e,0x9e,0x54,0xfd,0x0c,0x25,0x72,0xc3,0x5a,0xb6,0x3b,0xad,0x2b,0xd5,0x29,0x55,0x31,0xab,0x62,0xe4,0x15,0xed,0xef,0x16,0xef,0x43 +.byte 0xd5,0xdd,0x3d,0x64,0x8c,0x13,0xbc,0xcd,0x4d,0xfb,0x4f,0x86,0x3b,0x73,0x1e,0xc4,0xe8,0x54,0xb4,0xcc,0x49,0xba,0x4f,0x81,0xcd,0xe8,0x30,0x92,0x4b,0x57,0xd1,0x7c,0x0c,0x65,0x7d,0xe1,0x59,0xc6,0x8c,0x7d,0xad,0xd5,0xcf,0x6c,0xc4,0x9d,0xc5,0x3f,0x23,0x1f,0xb0,0x6d,0x1c,0x07,0xbf,0x38,0xc9,0x16,0xdc,0x5b,0x51,0xa1,0xdb,0x8f +.byte 0xf8,0x25,0xc6,0x4d,0xc0,0x4d,0xa1,0x02,0xd9,0xd3,0xb5,0x63,0xda,0xe1,0x91,0x60,0x71,0x39,0x46,0x1a,0x13,0xe0,0xf2,0xca,0xcc,0xd3,0xbb,0x6b,0xd0,0x64,0xaa,0x0e,0xc0,0x89,0xa3,0xc6,0x14,0x56,0xe4,0x44,0x97,0xa9,0xcc,0x17,0x68,0xe6,0xfc,0xe5,0xfd,0xf0,0xa6,0x69,0xcd,0xac,0x20,0xc7,0xeb,0x53,0x1b,0x4f,0xdd,0xd3,0xb0,0xed +.byte 0x30,0x4e,0x36,0x73,0x63,0xef,0x51,0x3e,0x9a,0x3e,0x41,0x2b,0x9c,0xda,0x67,0x96,0x46,0x33,0xe3,0x3f,0x87,0x01,0xd8,0xc5,0x26,0x80,0xe4,0x7e,0xf4,0x78,0x8c,0x2b,0x81,0x2a,0x01,0x7c,0xe3,0xfc,0x8d,0x6b,0xdc,0x84,0xb9,0xff,0x43,0x37,0x57,0xce,0x3f,0x5e,0x63,0xd3,0xbe,0xb6,0x4a,0x31,0xbf,0xb8,0x74,0x64,0x9c,0xf3,0xc5,0x8a +.byte 0xae,0xe8,0x5f,0x68,0xcf,0xce,0xff,0x3f,0xc5,0xb5,0xfd,0x13,0x08,0x11,0x9d,0x1a,0x0f,0x06,0x08,0x4d,0x7c,0xf9,0xd4,0x20,0xdf,0x82,0xf9,0x86,0xfc,0xf3,0x67,0xa0,0x14,0x99,0xe5,0x47,0xf0,0x02,0x7b,0x16,0xca,0xcf,0xb9,0x0f,0x68,0x08,0x5d,0x1d,0x65,0xee,0x23,0x56,0xeb,0x11,0x5b,0xca,0xf1,0xa7,0xad,0x50,0xb2,0xd1,0x37,0x65 +.byte 0xe9,0x7e,0xf6,0xe9,0x64,0x42,0x49,0x80,0x40,0x17,0xe3,0x43,0x00,0xda,0xe1,0x7a,0x1c,0xb3,0xde,0xd9,0xf7,0x33,0xeb,0xb3,0xb8,0xf5,0x40,0x1b,0xcd,0x71,0x97,0x30,0xf9,0x9c,0x4d,0xac,0x7e,0x8e,0xd9,0x36,0x92,0x39,0xb5,0x56,0x0f,0x4f,0xbf,0x58,0xb8,0xba,0xc3,0xbd,0x79,0xb0,0xd7,0x6c,0x45,0x49,0xe2,0xde,0x94,0x04,0x9d,0x3e +.byte 0x91,0x0a,0xb2,0x9b,0x90,0x57,0x2e,0x69,0xa4,0x4f,0x61,0xbf,0xdb,0xfb,0xe3,0xe9,0x81,0x26,0xe0,0x48,0x90,0x8c,0x32,0x95,0x8d,0x38,0xec,0x8e,0xa7,0x5e,0xc3,0x36,0xc6,0xd1,0xbc,0x9a,0xb3,0xba,0xdb,0x2c,0xe4,0xa0,0x50,0x74,0xef,0x98,0x48,0x14,0xc9,0x38,0x4d,0xa9,0x48,0x13,0xd4,0x08,0x60,0xfd,0xcf,0x5e,0xf2,0xcd,0xc7,0xeb +.byte 0xaf,0x88,0x32,0x30,0x6f,0x19,0x01,0xec,0x87,0xae,0x6d,0x63,0xa3,0xa7,0x7b,0xcd,0x53,0xa7,0xf2,0xf2,0x9f,0x43,0xcb,0x0a,0x3f,0x8c,0xd2,0x55,0x8d,0xa7,0x95,0xcf,0x5b,0xae,0x64,0x23,0xda,0xb4,0xbd,0x32,0x34,0x95,0x8a,0x03,0xe7,0x6e,0xef,0x3f,0xb4,0xcf,0xc6,0x8a,0x2f,0xc6,0x59,0x99,0xdf,0xad,0x3c,0x15,0xed,0x83,0x0b,0x59 +.byte 0x8b,0xcd,0x0d,0xa6,0xcf,0x3a,0xc3,0xdb,0xc3,0x01,0xa9,0x32,0x38,0x45,0x5c,0xc8,0x56,0x81,0xef,0x21,0x7f,0x52,0xc4,0xb5,0x48,0x97,0x6a,0x60,0x75,0x3a,0x1a,0xd3,0xb0,0x60,0x9a,0x83,0x61,0xad,0x3b,0x4b,0x65,0xaa,0x9e,0x77,0x47,0x6f,0x3b,0x48,0xb0,0xc6,0x36,0x9a,0x59,0x5e,0x26,0xc4,0xb9,0xed,0x04,0xf3,0xc7,0x09,0x33,0xda +.byte 0x81,0x63,0xa6,0x5d,0xe1,0x54,0x6b,0x04,0x17,0x2b,0xb9,0x2f,0xbd,0x55,0xdb,0xa1,0x69,0x00,0xcd,0xba,0xfa,0x36,0xaa,0x47,0x5a,0x7c,0xf4,0x1f,0x53,0x94,0x95,0x2f,0xf8,0x2a,0x4b,0xa8,0xcc,0x73,0xab,0xfd,0x25,0xb2,0x4e,0xd6,0x62,0x90,0x8c,0x8f,0x02,0xe4,0xdc,0x22,0x79,0x04,0x34,0x9b,0x54,0x5c,0x54,0xca,0x9b,0x8a,0xf8,0x05 +.byte 0xd1,0xb0,0x9e,0x8f,0xa3,0x0b,0x53,0xa8,0x6f,0x1b,0x2e,0xf2,0x71,0x78,0x28,0xce,0xa9,0xdb,0x4c,0x5b,0x83,0xfe,0xaa,0xff,0x99,0x2f,0x03,0x14,0xb2,0xe0,0x5f,0xaa,0x65,0x15,0x1f,0xd2,0x31,0x95,0x70,0x3c,0x8b,0x55,0x8e,0x87,0xed,0xbb,0x0c,0x91,0x87,0xaa,0xbe,0x49,0xdb,0x18,0x7b,0x1d,0x26,0xa7,0xdf,0x00,0xff,0x73,0x70,0x2e +.byte 0x10,0xaf,0x46,0xea,0x7f,0xca,0xfa,0x09,0x13,0x02,0xac,0x3f,0xa0,0x02,0xa6,0x67,0xb7,0xec,0x18,0x73,0x91,0x25,0xa0,0x28,0xe3,0xd8,0xfa,0x11,0x6d,0x34,0x79,0x1d,0xe4,0x8f,0x7c,0x73,0x66,0x77,0x3e,0x43,0x23,0xb0,0xee,0x84,0xb5,0x75,0xc9,0x23,0x87,0x6a,0x4f,0x59,0x3d,0xb5,0xf1,0xd6,0x06,0xf8,0xa6,0x5d,0x0c,0x24,0xed,0x94 +.byte 0xd7,0xa8,0x31,0x37,0x10,0x60,0xb6,0x03,0x33,0x27,0x38,0xdd,0xd3,0x74,0x02,0xa3,0xa6,0x01,0x94,0xa9,0x56,0x11,0x23,0x0e,0xdb,0xfd,0x25,0x92,0xa8,0xfb,0x79,0xc8,0x8e,0x0e,0x10,0x1f,0xca,0x95,0xf6,0xad,0x28,0xe7,0xaa,0x2b,0xf1,0x40,0xf6,0xef,0x7b,0x40,0x28,0x57,0xbb,0x4c,0xac,0x0b,0x8b,0xb3,0xe3,0xec,0x53,0xf2,0x15,0x61 +.byte 0x2e,0x91,0xdf,0x91,0xfb,0x55,0xb6,0x7f,0x6c,0xfc,0xb7,0x4b,0x91,0xdc,0xf7,0xe5,0x91,0xd8,0x70,0x92,0x94,0xea,0x3f,0x62,0x98,0x14,0xc3,0x43,0x34,0x02,0x87,0xc7,0xca,0x60,0x4a,0xfb,0x50,0xe4,0xa9,0x92,0x10,0x04,0x7c,0x55,0xd3,0x9a,0x89,0xba,0x8e,0x6f,0x02,0xd6,0xc7,0x6f,0x91,0xb5,0x87,0xb9,0x0e,0xbe,0xe4,0x9f,0x01,0x0b +.byte 0x20,0x60,0xc8,0x16,0xe6,0x23,0x1d,0x5f,0x4d,0x82,0xf4,0x42,0x25,0xe6,0x05,0xe3,0x5b,0xbb,0xd1,0xb0,0xad,0x0b,0x05,0x71,0x3a,0x7b,0xee,0x0e,0xe1,0xe4,0x08,0x9f,0xda,0xdf,0x59,0x57,0x4f,0x05,0x5a,0x51,0x9a,0x60,0xfd,0x85,0x21,0xd1,0x0a,0x3b,0x0a,0x15,0x61,0x28,0x98,0x0a,0x8f,0x1e,0x33,0x15,0xb3,0x5f,0xf3,0xbb,0x89,0x22 +.byte 0x0c,0xaf,0x91,0xce,0x44,0xb1,0x54,0xd0,0x80,0x86,0x43,0xa1,0xb9,0x07,0xde,0xab,0x1f,0x9b,0xae,0xef,0x07,0xf2,0x40,0x33,0x31,0x4d,0xf9,0x45,0x97,0xf6,0xcc,0xe5,0x3c,0x49,0xcd,0x83,0x6e,0x38,0x81,0xab,0x40,0x18,0xda,0xf6,0xfe,0xe7,0x96,0xd1,0x17,0x98,0xae,0xec,0xe9,0x93,0x37,0xbc,0x0b,0xa8,0x12,0xe7,0x65,0xca,0x27,0x37 +.byte 0x6a,0x74,0x81,0xf1,0xe0,0x6c,0x0d,0xba,0x86,0x48,0x94,0xd0,0x72,0xd5,0x4d,0x71,0xcf,0xa8,0x5e,0xd1,0x97,0xd1,0xed,0xf0,0xd3,0xe4,0xe3,0x41,0xc9,0x8f,0xfc,0x89,0xe8,0xbf,0x96,0x8b,0x86,0xb0,0x97,0x79,0x95,0xdf,0x69,0x56,0x6d,0x61,0x0a,0x37,0xcb,0x36,0xe1,0x95,0x88,0xf5,0xf0,0xe2,0x5c,0xb2,0x44,0x73,0xda,0x83,0xa7,0xdc +.byte 0x8b,0x35,0x3e,0xc1,0xd5,0x88,0x17,0x3b,0xeb,0xcf,0x36,0x9c,0xef,0x40,0xb2,0x72,0xde,0x4f,0x16,0x6c,0x8c,0x9d,0x15,0xce,0x7d,0x0d,0xc3,0x2f,0xea,0xab,0x50,0xdf,0x02,0xe0,0x24,0xcc,0xf4,0xa7,0x25,0xba,0x85,0x0d,0x62,0x9a,0x39,0xc7,0x5a,0xd1,0x9a,0xd1,0xa7,0x45,0x5f,0xc2,0x44,0xf5,0xa9,0x8d,0xd8,0xbc,0xd3,0xc8,0x75,0x0d +.byte 0x06,0xc6,0x4b,0x24,0xc6,0xe5,0x72,0xf7,0xd5,0x87,0xca,0x3c,0xc0,0x1c,0x18,0xa9,0x40,0xc6,0x7b,0xe5,0x4c,0xe6,0xb7,0x01,0x57,0xc1,0xcf,0x63,0x83,0x58,0x63,0x47,0xcf,0xa4,0xd3,0xf6,0x1d,0x2c,0xbf,0x17,0xe6,0x0a,0x7b,0x2d,0xa9,0x34,0x23,0xfc,0x1f,0x06,0x31,0x47,0x7b,0x31,0x34,0x8c,0x3c,0x15,0x9b,0xac,0xfd,0x38,0xe6,0xa3 +.byte 0x9e,0xa7,0xdf,0xa6,0x37,0x61,0xfd,0x85,0xb8,0x2e,0x67,0x73,0x7f,0x60,0x12,0x8b,0x62,0xb0,0x38,0xd0,0xaa,0xc4,0xad,0x3b,0xa9,0x04,0x66,0xdd,0xbb,0x9c,0xb1,0x95,0xe1,0x9c,0x0a,0x72,0x80,0x12,0xaa,0xa8,0x0c,0x3f,0x90,0x20,0x33,0xb4,0x76,0xdd,0x26,0xfe,0x1e,0x8f,0x6a,0x2d,0xea,0x4a,0xdc,0x28,0x47,0x66,0x36,0x5b,0x50,0x60 +.byte 0x7e,0x3e,0x93,0xf3,0xe9,0x37,0x31,0x3b,0x43,0x46,0x85,0xb3,0xa9,0xb2,0x14,0x95,0x96,0x49,0xf9,0x2a,0xe7,0x9e,0x3a,0x3e,0xd8,0x12,0xf7,0xbc,0x43,0x8c,0x35,0x31,0x44,0x08,0x7f,0x25,0x39,0x86,0x98,0x6a,0xe8,0xe3,0x2e,0x73,0x2d,0x3b,0xac,0x2d,0x75,0x4c,0xc8,0xca,0x21,0x2d,0x96,0x9b,0x4f,0x56,0xff,0x2d,0xc2,0xe2,0x98,0x3d +.byte 0xe2,0x3f,0xee,0x10,0xb7,0xc3,0x3d,0xa8,0x50,0x88,0x7f,0xd5,0x4e,0xbd,0xc7,0x9d,0xdc,0x01,0x49,0x27,0xf2,0xae,0xea,0x93,0x72,0xdf,0x00,0xcd,0xe6,0xa1,0xdd,0xd1,0x18,0xeb,0xa7,0xe1,0x4a,0x7b,0x38,0x72,0x73,0x29,0x46,0xa3,0xb3,0x25,0x23,0x6d,0x26,0xab,0x86,0xdc,0x67,0x52,0xe5,0x4a,0x5e,0x8f,0x16,0x67,0x8a,0x28,0x13,0xba +.byte 0x44,0x42,0xb5,0x21,0x9f,0x30,0x66,0x7f,0xc9,0x87,0x40,0xcb,0x75,0x58,0x2e,0xcd,0x09,0xb9,0x8a,0x84,0xa3,0xbd,0x63,0x53,0x75,0x2f,0x77,0x8b,0x7e,0x19,0x31,0x33,0x3b,0x9a,0xfb,0x86,0x39,0xa6,0xd9,0xeb,0x9b,0x43,0xc6,0xd9,0xc2,0x10,0xab,0x42,0xe5,0xc6,0x4a,0xe6,0x3e,0xde,0x9d,0xac,0x8e,0x95,0xf0,0xdb,0x48,0x95,0xc2,0x87 +.byte 0x6b,0x7f,0xde,0x09,0xdb,0xed,0x49,0x19,0x73,0x2d,0xa4,0x5c,0xdf,0xfa,0x2e,0x15,0xd0,0xb6,0x46,0x32,0xc9,0x7f,0x7e,0x01,0xd3,0x25,0x45,0x0e,0x5b,0x0d,0xf0,0x67,0xe3,0xd9,0xdf,0x4f,0x3b,0x6f,0xb3,0x15,0xc5,0x6b,0x91,0x75,0xa2,0xaf,0x42,0x3a,0x14,0x50,0xd9,0x4f,0x19,0x65,0x12,0x83,0x5d,0x8f,0x8a,0x01,0x0b,0x89,0xcc,0x7f +.byte 0x1a,0xde,0x5b,0x44,0x34,0x98,0x0f,0x8e,0x5a,0x5e,0x03,0x41,0x3e,0x66,0x9b,0x16,0xf5,0x91,0x7c,0xb0,0xc1,0xbf,0xa2,0x10,0x0b,0x60,0x3a,0x63,0x0c,0xcf,0xd8,0x49,0xdb,0x42,0x88,0x1f,0x36,0x8e,0x15,0xdb,0x5d,0x3f,0xe7,0xf1,0x9a,0x73,0x2b,0x74,0x0c,0xd5,0x09,0xab,0x01,0x2e,0x52,0x6f,0x03,0xf6,0xc9,0x0b,0xeb,0xa5,0xce,0x2e +.byte 0x1c,0x02,0x35,0xca,0xce,0xfe,0x4b,0xad,0x67,0x21,0xf8,0x44,0xea,0x70,0xf2,0x3d,0xfc,0x43,0x77,0x05,0x26,0xbe,0xaf,0x99,0xab,0x41,0xd4,0xcc,0x53,0x33,0x33,0xcd,0xb4,0x2d,0x76,0xfb,0xae,0x0c,0xac,0xc1,0xd0,0x42,0xfb,0x45,0x4a,0x6e,0x55,0xd2,0x93,0xef,0xb9,0x06,0xbc,0x38,0xce,0x94,0xc2,0x01,0xdf,0x27,0xc8,0x47,0xff,0x74 +.byte 0xfb,0x84,0xc5,0xa2,0x78,0x1f,0x4f,0x73,0x12,0xec,0x2d,0x82,0x5b,0xeb,0x3c,0xb6,0x1c,0x5a,0x29,0x9c,0xba,0x9e,0xa4,0x85,0x94,0x84,0x68,0x01,0xd7,0xb1,0x27,0x84,0x4a,0x7d,0x62,0x9c,0x32,0x12,0x89,0xd8,0x66,0xb5,0xe9,0x07,0xf4,0x5f,0x6b,0x0e,0x90,0x87,0xe5,0xc1,0x8b,0xaf,0x8f,0xf7,0xca,0x54,0xe0,0xc6,0x5f,0xa5,0xec,0xd1 +.byte 0xdc,0xdc,0x17,0x9e,0xca,0x4b,0x72,0x72,0x03,0x96,0x62,0xaa,0xc1,0xfe,0x23,0x7e,0xd2,0x06,0x61,0xb6,0xc9,0x0d,0x7e,0xbf,0x72,0x1c,0x66,0x46,0x0b,0x31,0x96,0x81,0x11,0x3d,0xac,0x5e,0xd0,0x35,0xaf,0xac,0x4c,0x74,0xce,0xf9,0x9c,0x64,0x3d,0xe5,0x9d,0xfe,0xc7,0x05,0x09,0xe1,0x70,0xc5,0x37,0xd5,0x4e,0xd8,0x7d,0xdb,0xfa,0x1c +.byte 0x28,0xfc,0x10,0x2a,0xe8,0x62,0x18,0x09,0x97,0xe0,0x98,0x2e,0x9f,0x1d,0x18,0xff,0x22,0xe9,0x5d,0x37,0xd2,0x74,0xf1,0x81,0x08,0x8a,0x55,0xc0,0x40,0x0f,0x70,0xbe,0x82,0x23,0x78,0x35,0xc8,0xf8,0x59,0x6e,0x0d,0x2e,0xd5,0xe7,0xf5,0x2e,0xbd,0xcd,0x1a,0xcf,0x76,0x43,0x1f,0xca,0x15,0x6c,0x4a,0xb7,0xc7,0xb9,0xaf,0x68,0xd7,0x31 +.byte 0x1e,0x0c,0x9c,0x78,0x74,0x66,0x80,0xc6,0x74,0xbe,0x86,0x59,0x0c,0x12,0xdc,0xf3,0x1b,0xaf,0x63,0x74,0xce,0x1e,0xac,0xf0,0x65,0xa0,0xab,0x7f,0x96,0x08,0x32,0xb2,0xca,0x9c,0xfb,0x9d,0x66,0x63,0x76,0xf9,0x69,0x08,0x6e,0xd3,0x46,0xde,0xdf,0x54,0x06,0x0d,0x25,0x81,0xd9,0x5a,0x45,0xeb,0xe5,0xc0,0xf6,0x86,0x0f,0xe9,0x27,0x7c +.byte 0xdc,0x52,0x28,0xb5,0xd0,0x7d,0x07,0xc1,0xb6,0x9b,0xdc,0xea,0xd3,0x2a,0xba,0xb0,0xd5,0xa3,0xd8,0x25,0x07,0x9c,0x6c,0xd6,0x16,0xa5,0x93,0x43,0x52,0xa7,0x5c,0x2b,0xe2,0xfa,0x8e,0x6e,0xaa,0x04,0x84,0x63,0x80,0x0f,0x90,0x10,0x41,0x1c,0xf6,0x67,0xea,0x39,0xb0,0x16,0xfc,0x6f,0x85,0x28,0x8c,0x8e,0xfb,0x79,0x39,0xdf,0xf6,0x6e +.byte 0x57,0xa1,0xaa,0xf1,0x0b,0x99,0xde,0xad,0x69,0xe2,0xf4,0x74,0x8e,0x8c,0x2d,0x20,0xdb,0xf3,0x2d,0xc2,0x75,0xe7,0xd6,0xc8,0x9d,0x46,0x3b,0x8b,0x8b,0x18,0xd8,0x41,0xfd,0xc2,0x7d,0xec,0x66,0x78,0xe7,0xbe,0xee,0x2b,0x07,0xd8,0x7e,0x13,0x61,0x7e,0xab,0x7d,0x2b,0x3f,0x83,0x96,0xf5,0xab,0x0b,0x20,0xd2,0x5b,0xb0,0xeb,0xf7,0x1b +.byte 0xac,0x1a,0x16,0x46,0x21,0x90,0xdb,0x67,0x66,0x42,0xe2,0x54,0x34,0xae,0x34,0xae,0x21,0x33,0x8c,0x48,0x19,0xdb,0x1f,0xa8,0x25,0x76,0xe0,0x03,0x1c,0x35,0x8d,0xd3,0xab,0x6b,0x93,0xf3,0xad,0x7d,0x3c,0x76,0x1d,0xaa,0x43,0x80,0x0f,0x5f,0x20,0xd9,0xf0,0xff,0x8b,0xf4,0xdb,0xbc,0xf2,0xff,0xf2,0x8a,0xfc,0xf5,0x0e,0x4e,0xd9,0xb0 +.byte 0xd6,0xb3,0x86,0x5b,0x3e,0x10,0x87,0x50,0xf1,0xd2,0x8f,0x8d,0xa4,0x39,0x85,0xf5,0x90,0xd6,0x53,0x69,0x40,0x42,0xc1,0xc3,0x7c,0xc1,0x3e,0x97,0xb4,0x08,0x49,0x93,0x4e,0x4c,0x67,0xd9,0x2e,0x05,0x70,0x04,0x98,0x0a,0xed,0xd0,0xff,0x0c,0x13,0xe4,0xde,0x75,0x81,0x24,0xb1,0x27,0x79,0xeb,0x80,0x68,0x52,0x50,0x66,0x77,0x4f,0xf6 +.byte 0x64,0x2f,0x85,0x9e,0xc1,0xbf,0x9f,0x0e,0x31,0x9a,0x36,0x24,0xcd,0xa8,0xe8,0xce,0x41,0x86,0xd1,0x02,0x96,0xdc,0x1a,0xa0,0x48,0xca,0x61,0xd5,0x87,0xdb,0x0a,0xeb,0x69,0x95,0xca,0xf8,0xe5,0xa0,0x5b,0x91,0x8f,0xb9,0x59,0x5f,0x68,0x60,0x58,0xc5,0xe0,0xc7,0x02,0x68,0xa5,0x67,0x1e,0xfc,0xa9,0x27,0x9f,0x83,0x4c,0x05,0x60,0xee +.byte 0xcb,0x79,0x31,0x73,0x36,0xf4,0x39,0x44,0xdb,0xea,0x62,0x89,0x97,0x69,0xd1,0x0d,0xf6,0x27,0xcf,0x47,0xfe,0x3d,0x5c,0xe9,0x92,0x54,0x0a,0x66,0xaf,0x82,0xb1,0x49,0x87,0x3f,0xa2,0x95,0x91,0x0e,0x72,0x1e,0x7b,0xde,0x32,0x31,0x51,0x40,0x24,0x4f,0x30,0x59,0x7d,0x97,0x28,0x30,0x7e,0x93,0xcd,0x1e,0x16,0xef,0xe1,0xb5,0xa8,0xff +.byte 0x3a,0xd0,0x62,0x94,0x8b,0x72,0xe7,0x97,0x8f,0x2f,0x58,0x3e,0x62,0x43,0x6b,0x28,0x05,0xc9,0x0d,0xf0,0x09,0xbd,0x12,0x3b,0xd8,0x15,0xd3,0x7c,0x97,0x96,0x5a,0xf4,0x9f,0x8d,0x25,0xb7,0xc5,0x66,0xf7,0xf7,0x5f,0x7e,0xca,0x2f,0xcd,0x9a,0xf2,0xa3,0x9b,0x4f,0x6f,0xc3,0xd9,0x64,0x38,0xda,0x87,0x97,0x8a,0x49,0x2d,0x80,0x16,0x73 +.byte 0x88,0x62,0xd2,0xdf,0x4f,0xf7,0x79,0xc0,0x83,0xeb,0x2b,0x66,0x5a,0x21,0x3a,0xa2,0x2a,0xed,0x8c,0xe7,0x91,0x6d,0x56,0x18,0xfc,0x59,0x68,0xea,0x9f,0x5c,0x3c,0xd5,0x0f,0x64,0x70,0x89,0x22,0x83,0xed,0xfa,0xc9,0x21,0x68,0x3c,0x69,0xb8,0x3e,0x89,0xb5,0x9d,0x8b,0xc8,0xf7,0x57,0x17,0x27,0x90,0x12,0xa7,0xd2,0x4d,0x2c,0x30,0x64 +.byte 0x42,0xbe,0xa6,0x49,0x4e,0xa3,0x3b,0xdb,0xdb,0x64,0x0e,0x89,0x66,0x87,0x72,0x90,0x86,0x1d,0x0b,0x61,0x32,0x47,0x3d,0x55,0x81,0xb2,0x50,0x5a,0x76,0x6c,0xa3,0x46,0x12,0x1b,0xaf,0x6e,0xbf,0xfd,0x98,0x2f,0xb7,0xd2,0x31,0x92,0xb5,0x26,0x1a,0x3d,0xfa,0x5d,0xc0,0x24,0x44,0xd2,0x6b,0x1c,0x81,0xf5,0x5d,0x50,0xb0,0x33,0x18,0xe0 +.byte 0xc5,0xb3,0x6b,0xf4,0xfd,0xde,0xf7,0x2f,0x69,0x1d,0x5a,0xfe,0x03,0x6d,0xca,0xad,0x29,0xe0,0x6e,0x70,0xcd,0xe3,0x6d,0x38,0xef,0xf1,0x3a,0x76,0x2b,0x2c,0xb6,0xcd,0xff,0xeb,0xbc,0xe7,0xd9,0x40,0xbe,0x23,0x61,0x20,0xd5,0xb8,0x66,0x77,0x65,0xc9,0x33,0xf5,0x75,0x8e,0x15,0x98,0x3f,0xb1,0x4a,0xb8,0x1c,0x47,0x73,0x45,0x0f,0x73 +.byte 0x2a,0xa1,0xb7,0x73,0x76,0x94,0x16,0x45,0xcf,0xd6,0x8f,0xe3,0x62,0x8a,0x42,0xfd,0xe3,0x1e,0xe0,0x7d,0xb5,0x99,0xbd,0x1c,0xf2,0x60,0xb2,0x72,0xa8,0x4b,0x19,0xd6,0xd0,0xdb,0x0b,0x1f,0xc9,0x68,0xc0,0xf3,0x65,0x04,0x50,0x41,0xf0,0xb3,0x0e,0x0a,0x9d,0x7f,0x0b,0x1f,0xeb,0x5b,0x4c,0x58,0x6a,0xf2,0x02,0x95,0xd2,0xf3,0xac,0xe5 +.byte 0x69,0x81,0xb1,0x3f,0x08,0xfc,0xba,0xcb,0x36,0xcd,0x54,0x28,0xac,0x65,0xd8,0x81,0xab,0xc1,0x6a,0x51,0x97,0x21,0xe4,0xc6,0xaf,0xd8,0x76,0x76,0xa4,0xc4,0xd0,0x58,0x63,0xdf,0x32,0xf5,0x04,0xfb,0x11,0xeb,0x76,0x39,0xda,0x55,0xf4,0x7e,0x1c,0x7b,0x04,0x07,0x4d,0x5a,0xeb,0x74,0x0a,0x57,0xcf,0x10,0xf6,0x0e,0x73,0x02,0x25,0x67 +.byte 0x4f,0x8f,0x37,0x75,0x8f,0x44,0x2a,0x1a,0x6d,0x05,0xda,0xe0,0xa0,0xaa,0xd2,0x78,0xaa,0x7e,0x76,0x0a,0xde,0x2a,0x54,0xae,0x1e,0x39,0xcc,0x3c,0x1c,0xa6,0xd5,0x8a,0xca,0xb4,0xcc,0x76,0xb9,0x30,0xd2,0xe2,0x46,0x31,0xb6,0x51,0xcf,0xe2,0x24,0x77,0xc9,0x9b,0x57,0x3c,0xa3,0x84,0x60,0x59,0x28,0x5f,0x23,0x74,0x17,0x79,0x42,0xbe +.byte 0x60,0x3f,0x09,0x6a,0x43,0x8e,0x40,0x25,0x79,0xb5,0xbb,0xbb,0x72,0x50,0xad,0x4f,0xaa,0xa2,0xd4,0xb2,0xc6,0x7d,0x50,0x7b,0x98,0x59,0x22,0x06,0x7d,0x2c,0x35,0xdd,0x44,0x34,0x9c,0x28,0x98,0xf3,0xe5,0xd0,0x7e,0x09,0xbe,0xc4,0x00,0x72,0xd5,0xa6,0x3b,0x0e,0xb1,0x18,0x91,0x0a,0x4d,0x5d,0xe2,0x0a,0x98,0x79,0x30,0x9b,0xaa,0x38 +.byte 0x03,0x2b,0x6c,0xb2,0x8e,0x0a,0x1d,0x30,0x59,0x8a,0xe8,0x6c,0x6d,0xb5,0xd4,0x91,0xc5,0x28,0x1d,0x5e,0x49,0xe0,0xfc,0x26,0x7f,0x40,0xc0,0x6a,0x81,0x0d,0xb9,0xc6,0x05,0xc6,0x18,0x82,0x70,0xf6,0xea,0x0e,0xb4,0x85,0xba,0x5d,0xfa,0xfd,0xe3,0xd6,0x08,0x7c,0x3d,0x99,0x03,0xd4,0xdc,0x9b,0x50,0x12,0xc8,0xbd,0x8c,0x47,0x67,0x28 +.byte 0x83,0x97,0xca,0xef,0xc3,0x1c,0x2b,0x6e,0x3b,0xf7,0xca,0x7a,0x68,0x6e,0x39,0x25,0x58,0xf7,0xa4,0x11,0x9d,0x8d,0x49,0x29,0xd6,0x6e,0x0b,0x0a,0xcf,0xa7,0x04,0x14,0x6f,0xc4,0x4c,0x36,0x1a,0x16,0x3e,0x8f,0x99,0x69,0x94,0x1d,0xa8,0x66,0x93,0xeb,0x1d,0x82,0xfd,0x3f,0x84,0xb0,0x9d,0xa4,0xe1,0xb0,0xd4,0x9d,0xb2,0x60,0x20,0xfb +.byte 0xd3,0xa0,0xdc,0x79,0x83,0xb0,0xfc,0x50,0x18,0x57,0xe1,0xeb,0x44,0x25,0x05,0xab,0x27,0xfb,0x5f,0x83,0xcd,0x51,0xd0,0x3b,0x80,0x4a,0xce,0xbf,0xe9,0xfe,0x46,0xd2,0x5f,0xea,0x8c,0x89,0x48,0xc8,0x65,0xdd,0x2a,0xa4,0xda,0x54,0xc2,0x37,0x7e,0xd7,0xff,0x80,0x5b,0xf0,0xc3,0x40,0x44,0x40,0x72,0x63,0x23,0xc6,0x9a,0x48,0xf3,0x4b +.byte 0x91,0x64,0x26,0xfc,0xf3,0xa0,0xb9,0x06,0x0c,0x88,0xbb,0xc0,0x93,0x73,0x63,0xf6,0x9c,0x0d,0xe2,0xf6,0xee,0xe0,0x51,0xfd,0xae,0x4d,0x21,0xb9,0x6b,0x7d,0x1e,0x34,0xa0,0x4d,0xe4,0x25,0x30,0xe6,0x81,0x2e,0x32,0xef,0xb9,0x9e,0xaf,0xa0,0x22,0xe0,0x67,0xe6,0x07,0x55,0x3a,0xed,0xef,0x4f,0x87,0x2f,0x44,0xd2,0xef,0xc1,0xfb,0xc4 +.byte 0x7b,0x27,0x20,0x44,0xd2,0xd6,0xf9,0xf3,0x67,0xc1,0xbf,0xaa,0xd5,0x9c,0xd9,0x2c,0xd5,0xf1,0x42,0x2d,0xec,0x39,0xb5,0xc1,0x18,0xed,0x6c,0x47,0x80,0xf8,0x6f,0x66,0x10,0xee,0x1d,0xd6,0x79,0x01,0x4e,0x2a,0xd0,0x83,0xa7,0x9d,0x1d,0x81,0xce,0xf5,0x6f,0x26,0x86,0xd2,0xd7,0x56,0x15,0x65,0x48,0x4c,0xf1,0xf9,0x21,0x77,0xd1,0x84 +.byte 0x22,0xce,0x4d,0x8d,0x83,0xda,0x8c,0x50,0x56,0xc8,0x3b,0xc5,0xb6,0xcf,0x3e,0x0d,0x50,0xe5,0x9d,0x6c,0xb5,0x2a,0x5a,0x58,0x28,0xf5,0x0a,0x05,0xf3,0x0e,0x40,0x8e,0xb6,0xb4,0xdf,0x11,0x1b,0x34,0x81,0xc5,0x0e,0x09,0xa6,0xfc,0x46,0x14,0x02,0x78,0x94,0xbb,0x63,0x9d,0x3e,0x25,0x2c,0xc8,0x1b,0x5c,0xef,0x64,0x77,0x0c,0x04,0x40 +.byte 0xe1,0x45,0x85,0xf8,0x07,0xbf,0x14,0x65,0xe9,0xfc,0xba,0xe4,0x9c,0xa7,0x91,0x56,0x2a,0x3a,0x8e,0x33,0xae,0x56,0x04,0x9d,0x35,0xbc,0xad,0x64,0x0e,0x99,0x8e,0xb5,0x84,0x72,0xcf,0xcc,0x81,0x14,0x11,0x9e,0xe6,0xac,0x0d,0x41,0x43,0x4e,0x2a,0x0d,0xda,0x98,0x42,0xfa,0x8c,0x21,0x79,0x93,0xa3,0xdf,0x84,0x88,0x76,0x14,0x5b,0xb9 +.byte 0xff,0xe1,0xab,0x94,0xc3,0xcd,0x10,0x69,0xee,0x53,0xea,0xfe,0xfb,0xaa,0x43,0x8f,0xdd,0x55,0x88,0x34,0x5d,0x55,0x0f,0x42,0x4d,0x1d,0x93,0xce,0x96,0x67,0xf8,0x33,0xc7,0xca,0x34,0x11,0x28,0xb2,0xed,0x0f,0x00,0x40,0x84,0xee,0x51,0x26,0x6e,0x7b,0x2d,0x77,0xeb,0x18,0xb8,0x9a,0xad,0x28,0xb6,0x6c,0x5e,0xde,0x10,0x4c,0x29,0x1d +.byte 0x79,0x3c,0x2e,0x1c,0xf0,0xc8,0xb3,0xee,0x19,0x7a,0x10,0xe1,0xe3,0x05,0x1e,0x63,0xe9,0x00,0xd7,0xfe,0x83,0xe7,0x54,0xff,0x65,0x9a,0x27,0xa3,0x86,0x72,0x5c,0xb6,0xef,0xf5,0x84,0x68,0x1e,0xae,0xe6,0xf8,0x66,0x9c,0x1b,0x86,0xab,0xfa,0x1a,0xe3,0xb8,0x97,0x16,0xb1,0xb7,0x42,0xfa,0x85,0xa3,0x3a,0x0d,0x21,0xd2,0x35,0xb1,0x89 +.byte 0xf0,0x4f,0x1a,0x1d,0x45,0x34,0x2f,0x31,0x12,0x8c,0x19,0xe7,0x4b,0x14,0xa7,0xcf,0x0f,0xf9,0xcd,0x77,0x40,0xbe,0x09,0xeb,0xc3,0x3e,0x4a,0x37,0x55,0xab,0xbb,0x9c,0xe5,0x22,0x56,0x8a,0x66,0xfa,0xb1,0xff,0x73,0x29,0x52,0xb1,0x89,0xf7,0xab,0xa6,0x58,0x53,0x97,0xfd,0x44,0xda,0xbd,0x0b,0x1f,0xc8,0x88,0x01,0xcc,0x5e,0xf7,0x05 +.byte 0xbd,0xf7,0x0a,0x4d,0xcb,0xef,0xbf,0xd9,0x8e,0x15,0xc3,0x40,0xb9,0xc9,0x14,0xe5,0x05,0x3c,0x20,0x67,0xfe,0xdc,0xa6,0xb8,0x92,0xbd,0xf5,0x33,0xb5,0x77,0x11,0x28,0x47,0x21,0x28,0x18,0x61,0xf8,0x1c,0xdb,0x65,0xad,0x89,0x0d,0x98,0x79,0xca,0x2b,0xa3,0x4f,0x16,0xa6,0xb3,0xb9,0xcc,0x47,0x5b,0x13,0x96,0x2e,0x39,0x78,0x24,0xc5 +.byte 0xf9,0xf5,0xae,0xdc,0x34,0x3c,0xf7,0x48,0x0d,0x75,0xaf,0x51,0x75,0x48,0xbe,0x4d,0x73,0x89,0x5a,0xfc,0xd7,0x51,0xd3,0x93,0xa8,0xbc,0xc3,0xa6,0x6b,0x63,0xc1,0xc3,0x7b,0x48,0xf1,0x57,0xe4,0xb4,0xce,0x5f,0x18,0xae,0xdc,0x61,0x99,0xaa,0x7e,0x49,0xd6,0xb5,0x2c,0x62,0xb8,0x8c,0x4a,0x94,0xc1,0xc2,0x13,0x23,0xdc,0x7c,0x48,0xc2 +.byte 0xaa,0xc4,0xd9,0xc0,0x09,0x11,0x6e,0x35,0x07,0x14,0x77,0x7e,0xeb,0x87,0x00,0x05,0x30,0xec,0xb2,0xc6,0xde,0x6e,0x42,0x0b,0x2a,0xb6,0xca,0xb1,0xdc,0x69,0x57,0x1b,0xad,0x52,0xa8,0x22,0x1e,0xb5,0x2b,0xb5,0x8e,0x39,0x4b,0xbf,0x38,0xf4,0xb2,0xf5,0xa1,0x9c,0x7b,0x7f,0x6c,0x14,0x48,0x37,0xa9,0xf9,0xcd,0x85,0x50,0x53,0xb0,0xc1 +.byte 0x15,0x28,0x19,0x3b,0xb1,0x04,0x44,0x93,0x7a,0x16,0x76,0x69,0xa1,0x5c,0x67,0xcc,0x8d,0x02,0x56,0xcd,0xd9,0x91,0x49,0x8c,0x1b,0xc9,0x89,0x98,0x09,0x2e,0x5b,0xf8,0x7c,0xe6,0x0f,0x46,0xb0,0xcc,0xe5,0x75,0x63,0xaf,0x40,0xd5,0xa3,0x45,0x4a,0x76,0x67,0x1d,0x81,0xc2,0x25,0x85,0x7f,0x52,0xc5,0xf8,0x6d,0xd9,0xb6,0xa8,0xa4,0x96 +.byte 0x63,0xcc,0x15,0xc5,0xec,0x40,0x0e,0x08,0xf7,0x6f,0x85,0xa5,0xe7,0x2e,0xbe,0x3f,0xf4,0xc8,0x74,0xc7,0xed,0x86,0x85,0xc0,0x44,0x9e,0x80,0xc8,0x89,0xdc,0x16,0x47,0xb1,0x68,0x0e,0x65,0x66,0x0f,0xbc,0x33,0xb1,0x78,0x1e,0x5e,0xd7,0xde,0x97,0x96,0xb8,0x74,0x5c,0x90,0x7a,0xed,0x36,0xf4,0x10,0x91,0x5a,0x42,0x92,0x81,0x11,0x73 +.byte 0x3e,0xf1,0x5e,0xfb,0xc2,0x38,0xe6,0xe5,0x41,0xce,0x96,0xed,0x44,0x14,0x9c,0xc0,0x1f,0x83,0x5f,0xdd,0x50,0x87,0x90,0x86,0x50,0x61,0x87,0x99,0x7c,0x64,0x2d,0x50,0x17,0xa3,0xb0,0x7e,0x69,0xd3,0x86,0xb4,0x7c,0xe7,0x15,0x34,0x9e,0x3b,0x17,0xc0,0x2d,0x08,0x60,0x8b,0xae,0xec,0xa2,0xf6,0xf1,0xa4,0xbc,0x7b,0xc2,0x75,0x91,0x13 +.byte 0xf6,0xd0,0x71,0xf0,0x3c,0x9c,0x51,0xb3,0x33,0x53,0x57,0x47,0x8b,0x47,0xb0,0x0b,0x95,0x9a,0x39,0x70,0x63,0x91,0xcc,0xd8,0xd0,0x23,0x32,0xc0,0xb6,0x0f,0x91,0x30,0x29,0x45,0xf1,0xfc,0xa1,0x83,0x10,0x9a,0xa4,0x05,0x05,0x9f,0x33,0xbd,0xaf,0x16,0x3e,0x53,0x39,0xb1,0x4b,0x76,0x55,0x3e,0x6f,0x47,0x23,0x59,0x4c,0xbb,0x82,0x31 +.byte 0x19,0xe2,0xb1,0x49,0x20,0x91,0x2d,0xb0,0xfe,0xa6,0xae,0x7f,0x6e,0xd1,0x5b,0xb9,0x84,0x18,0x0f,0x68,0xc6,0x56,0x8a,0x22,0x81,0x3f,0x38,0x42,0x7a,0x31,0xa1,0xc1,0xf7,0x10,0x6a,0xc3,0xb1,0xaf,0x19,0xad,0x06,0x3a,0x53,0x9d,0x44,0x9f,0xe7,0x25,0xac,0x59,0x06,0xb9,0xd2,0xf6,0xce,0xb6,0x1e,0x4d,0x65,0x2e,0x05,0xb4,0x14,0x91 +.byte 0xfb,0x5b,0x26,0xd0,0xee,0xfa,0x45,0x5b,0x0c,0xd5,0x5c,0x1f,0x0c,0xe0,0xf6,0x50,0x78,0x77,0x7e,0x83,0x04,0xec,0x3b,0x53,0x28,0x97,0x56,0x61,0xeb,0xa0,0x78,0xe5,0xc0,0xb2,0x3c,0xcd,0x6f,0x4b,0xda,0x11,0x00,0x93,0x49,0x9f,0x03,0x22,0x39,0x3a,0xc8,0xef,0x01,0x91,0x12,0x36,0x15,0x0c,0x47,0xd5,0x8b,0x77,0x5e,0x5f,0x91,0x4b +.byte 0x44,0x98,0xa0,0xa0,0x46,0x0f,0x17,0xef,0xf9,0x52,0x0b,0x92,0xc1,0xe0,0xfc,0x63,0x9b,0x6d,0xe2,0xde,0x88,0x89,0x32,0x89,0x93,0x44,0x6d,0x69,0xe7,0x26,0xfd,0x77,0xc0,0x18,0x58,0xdb,0x74,0xec,0x04,0x0c,0x60,0x51,0x74,0xca,0x49,0x3e,0x4f,0x5f,0xaa,0x53,0xf2,0xc1,0xcb,0x89,0x1f,0x69,0xaa,0xbb,0x97,0x17,0x04,0x49,0x5e,0x44 +.byte 0xf3,0xf3,0xc4,0x98,0x9d,0x49,0x1e,0xb0,0x27,0x7d,0xff,0x54,0xa5,0xed,0xbe,0xb0,0x52,0xf6,0x00,0x87,0x67,0x2d,0x28,0xdb,0x09,0x4e,0xa2,0xee,0x4f,0x81,0xeb,0xa1,0xca,0x2b,0x07,0x2f,0x54,0x6d,0x5a,0x2e,0x13,0xa4,0xd0,0xac,0x21,0x7c,0x44,0xc0,0x98,0xac,0xe4,0x6e,0x94,0xd1,0x5b,0x5e,0xd6,0xf1,0x3c,0x45,0x88,0xe1,0xbd,0x58 +.byte 0xf1,0xc7,0xba,0x36,0x2c,0x15,0xb9,0xf4,0xa3,0xea,0x73,0xb4,0x91,0x53,0xd8,0x18,0x86,0x23,0x87,0x0b,0x7a,0x4a,0x2d,0x2d,0x3d,0x73,0xcb,0x05,0x11,0x4c,0x19,0x26,0xf2,0x05,0x89,0xc8,0x29,0x26,0xa7,0xe4,0xcb,0x43,0xd0,0xf6,0xbc,0x76,0xbd,0x9a,0x17,0x4a,0xf1,0x39,0xe3,0xde,0x05,0x10,0x8a,0xd3,0x11,0x53,0x61,0xef,0x33,0xd9 +.byte 0x65,0x0d,0x99,0x0b,0x39,0xa4,0x1b,0x4f,0x0b,0xa5,0xf1,0x37,0xa3,0x4f,0x54,0xa7,0x29,0xc1,0xae,0x88,0x5c,0x13,0x2f,0xb2,0xbf,0xcf,0x1b,0x0d,0xa0,0x68,0x21,0xe2,0x20,0x3f,0x02,0x9f,0x08,0x39,0xc6,0x20,0x2d,0x08,0x01,0x5d,0xf1,0x47,0xde,0x88,0xad,0x49,0x09,0xf7,0x1a,0x0c,0xa7,0x29,0x91,0xe5,0xfc,0xc5,0xde,0xd7,0x92,0x3f +.byte 0xe5,0x0c,0x91,0xea,0x24,0xfb,0x02,0x9a,0x13,0x3a,0x61,0x01,0x9d,0x7e,0x9d,0x11,0xf8,0xbd,0xe0,0x05,0xbb,0x13,0xf0,0x00,0x67,0x90,0x6f,0x80,0xe7,0x2e,0xfc,0xe0,0xea,0x8a,0x9d,0x2c,0x13,0x57,0x4c,0x78,0x1c,0x44,0xe2,0xa6,0x62,0x01,0x46,0xf8,0xbe,0xf4,0x51,0x32,0x15,0xd4,0x3c,0x7d,0x3b,0xcc,0xfd,0xc3,0x46,0x43,0xf1,0xfa +.byte 0x9e,0xee,0xad,0x47,0x8f,0x32,0x31,0x94,0x70,0x92,0xea,0x45,0xe3,0x63,0xd6,0x28,0x23,0xa5,0xdf,0x61,0xee,0x19,0x1a,0x5e,0xb0,0xe7,0x17,0xab,0xac,0xb4,0x03,0xed,0xf6,0x9e,0xba,0xdf,0x52,0x88,0xb7,0xca,0x7c,0x27,0xcd,0x7b,0xf8,0x1e,0x54,0x4b,0xe6,0xa3,0x91,0xf7,0xeb,0x22,0x65,0x95,0x13,0xe1,0xac,0xb6,0x22,0x80,0xe3,0xeb +.byte 0xf9,0xde,0xf1,0xb7,0x6a,0xfd,0xc7,0xb8,0x9b,0x9c,0x49,0x4f,0x84,0x7f,0x68,0x93,0x6c,0x3c,0xea,0xb1,0x8a,0xeb,0x23,0xca,0x2d,0x5e,0x29,0xb5,0x52,0x49,0x98,0x12,0x3f,0xed,0xf0,0xb7,0xbc,0x22,0x14,0x73,0x92,0x84,0x1b,0x3e,0x2f,0xed,0x24,0x1e,0x62,0xcc,0x09,0xe8,0x7c,0x5a,0x08,0xd4,0xc6,0xd9,0xd1,0x55,0x66,0x18,0x2c,0x6a +.byte 0x99,0xc3,0x0e,0x1e,0x7b,0xb7,0xd4,0xbd,0x0e,0x1f,0x22,0x85,0x09,0x2c,0xcf,0xff,0x79,0x9f,0x93,0xbe,0xec,0xed,0x63,0xb7,0x97,0xbb,0xeb,0xd6,0x70,0x76,0xa9,0x4f,0xb7,0x9a,0x60,0x5b,0x50,0xdf,0x85,0x46,0x69,0xa0,0x9a,0x86,0xe3,0xe2,0x13,0x2b,0x8c,0x0f,0x3b,0xab,0xa8,0xce,0xa3,0xb0,0x78,0x72,0x40,0xfb,0xd1,0x26,0x72,0xc1 +.byte 0x91,0x25,0x7b,0x29,0xde,0xcf,0x99,0xf3,0x8e,0x87,0x39,0x81,0x04,0xad,0x3b,0x11,0x6a,0xda,0x00,0xdd,0xe9,0x41,0xc1,0xd8,0xcc,0xf9,0x59,0xac,0x9b,0xb1,0x64,0x6f,0xb8,0xf4,0x9f,0x20,0xde,0x67,0x09,0x1b,0xdf,0x11,0xa5,0x94,0x56,0xab,0x76,0xba,0xc5,0xda,0x6c,0x86,0xe6,0xa4,0x73,0x59,0xa9,0xe3,0x68,0xb9,0xc0,0x50,0x1b,0x55 +.byte 0x21,0x9e,0xea,0x8d,0xcc,0x5d,0xee,0x88,0xe1,0x18,0x7c,0xcd,0x8f,0xff,0x18,0xbd,0x13,0xea,0x95,0xc4,0x8e,0xd3,0x92,0xfe,0x3d,0xda,0x6f,0xa5,0xbc,0xa0,0x77,0x5a,0x1d,0x61,0xff,0x7b,0x77,0xc4,0x06,0x25,0xc5,0xa7,0x76,0x36,0x55,0xe7,0xc0,0xf0,0x46,0x7e,0xca,0xe7,0xc1,0xe8,0x88,0x65,0xff,0xa7,0xb6,0x9c,0x83,0x1d,0x2e,0x6e +.byte 0xd6,0xd3,0x07,0x22,0x65,0x79,0x4f,0x3c,0x0a,0x5c,0x4f,0x95,0xb3,0x14,0x37,0x9b,0x0b,0x97,0x69,0xd9,0x5b,0x37,0x09,0xc3,0x70,0x5b,0x4f,0x11,0xcb,0xce,0xc0,0x06,0xf2,0xb9,0x32,0xdd,0x24,0x7b,0x8c,0xe6,0x0c,0x91,0x3b,0xa8,0xb0,0x82,0x56,0x4d,0xde,0xa0,0x5c,0x0b,0x5b,0x70,0x53,0x64,0x9d,0xab,0xbb,0x51,0x6b,0x8c,0x8f,0xe5 +.byte 0x1f,0xc0,0xb8,0xfe,0x1b,0xf6,0x24,0x26,0x62,0xcb,0x78,0x84,0x90,0x76,0x67,0x30,0x18,0x37,0xa9,0xca,0xb7,0x0d,0xac,0x17,0x86,0xb1,0x87,0x59,0x18,0xc3,0x9e,0x62,0x1b,0xb1,0x04,0x52,0xfc,0x7c,0x86,0xa0,0x37,0xb9,0x8b,0x7a,0x85,0x79,0x21,0xe0,0x0f,0x87,0x28,0x91,0xd0,0xe5,0x24,0x63,0x5c,0x7c,0xe8,0x47,0xfa,0x42,0x55,0xe9 +.byte 0x66,0xad,0xdf,0xc3,0x43,0x90,0x47,0x83,0x24,0x09,0x54,0x5f,0x14,0x27,0x53,0xb3,0x22,0x15,0x52,0x84,0x2f,0x61,0x8c,0x01,0x9e,0x34,0x61,0x3f,0x76,0x44,0x1c,0xca,0x79,0x2c,0x40,0x4e,0xa0,0x36,0x11,0xe0,0x23,0x0f,0xa7,0x78,0xf9,0xf9,0x2a,0x2c,0x98,0x5c,0xa9,0x2d,0x66,0xb9,0x87,0x43,0xd5,0xbc,0x64,0xe5,0x52,0x2f,0x1d,0xdc +.byte 0x1d,0xf4,0xb3,0x18,0x6b,0xd1,0x3b,0x8b,0xa3,0x47,0x65,0x62,0xcc,0xca,0x5f,0x00,0xbb,0x78,0x9d,0x35,0xd4,0x79,0x45,0x33,0xc7,0xa8,0x29,0x96,0x98,0xa4,0x23,0x2c,0x23,0x7f,0x5a,0x1d,0x09,0xb4,0xcf,0xac,0x54,0xcd,0x27,0xda,0x88,0x21,0xe2,0xb4,0x85,0xdc,0xc9,0x4a,0x6b,0xc4,0xfa,0x48,0xc5,0x91,0xc1,0x53,0x4b,0xa1,0x7a,0x9c +.byte 0x8a,0x7d,0x35,0x52,0xf1,0x58,0x9d,0x20,0x36,0xc2,0x78,0xdb,0x37,0xf8,0xa4,0x2f,0x50,0x98,0xb0,0x34,0x51,0x66,0x93,0xcf,0xe7,0xf0,0x06,0xf1,0xcd,0x0e,0x4f,0x33,0xcc,0x9b,0x73,0x3b,0xc9,0x51,0x63,0x6d,0x29,0x6b,0xf4,0x9d,0x2c,0x76,0x59,0xcd,0xfc,0x11,0x35,0x52,0xbd,0x3b,0x2e,0x7d,0x8a,0x0d,0xb0,0xbb,0x90,0x9b,0x9c,0xac +.byte 0x1c,0x80,0x89,0xd6,0x6f,0xaf,0xea,0x89,0x38,0x74,0xef,0x83,0x82,0x91,0xf7,0x74,0x96,0x30,0x40,0xe2,0x18,0x2b,0xb4,0xf6,0x15,0xf0,0x8e,0x63,0xe1,0x82,0x55,0x7b,0x65,0x70,0x33,0x14,0xef,0x7a,0x7c,0x2d,0xa9,0x17,0x1b,0x53,0x1e,0xf8,0x98,0x1b,0xbe,0xc8,0x00,0xf5,0xbf,0x79,0xe7,0x8e,0xf2,0xdb,0x59,0x0d,0x46,0xab,0x43,0xd0 +.byte 0xe4,0xa0,0xeb,0x29,0x6a,0x8b,0xc1,0x99,0xa6,0xcc,0x8e,0xe5,0xde,0x67,0xdf,0x49,0x09,0x62,0x8d,0x4b,0xa1,0x1c,0x3b,0x01,0xe2,0x95,0x65,0x10,0xa5,0x91,0xd0,0x48,0x35,0x96,0xcf,0xe4,0x51,0xd2,0x7f,0x93,0x49,0xab,0x1a,0xba,0x08,0x33,0x54,0x34,0xd7,0x00,0xc9,0xa0,0x07,0x03,0xc7,0x8a,0x65,0xa2,0x84,0x60,0xcd,0xaa,0xa2,0x46 +.byte 0x8c,0x67,0xd9,0xc1,0xe7,0x58,0xc5,0x1d,0xc0,0xb3,0xc6,0xb2,0x2a,0xfb,0x70,0x04,0xa2,0x25,0x7f,0x75,0x3c,0xd5,0x8e,0x9c,0x33,0xa2,0xdc,0x20,0x4c,0x26,0x5b,0xbe,0xd9,0x00,0x5d,0xa2,0xbd,0x42,0xbd,0x0d,0xd6,0x52,0x79,0xb5,0x67,0xf6,0x27,0x62,0xc8,0x64,0x05,0xc5,0x0f,0xae,0xe1,0x78,0x39,0xd1,0xb5,0x28,0xe9,0xd4,0x2a,0xaa +.byte 0xd4,0xc4,0x3e,0x43,0x27,0x83,0xfa,0xdb,0x46,0x73,0x20,0xcd,0x2c,0xba,0x33,0xb4,0x77,0x10,0x32,0x3d,0x8e,0x56,0x88,0x81,0xe1,0x4c,0x8b,0x46,0x60,0xcb,0xb7,0x67,0xd7,0x7b,0xc2,0x47,0x7d,0xd8,0x2d,0x4c,0x09,0x9f,0x07,0x8e,0x34,0x45,0xf4,0x50,0x69,0xfd,0x35,0x0a,0x09,0x9e,0xac,0x49,0x5f,0xdf,0x72,0x84,0x97,0x93,0x30,0x2c +.byte 0xc6,0x20,0x6f,0xb5,0x18,0x03,0xb6,0x30,0x23,0xc8,0xcd,0xa1,0x43,0xbd,0xbb,0x6f,0xde,0xb3,0xcb,0x1c,0xdd,0x41,0x71,0xfa,0x37,0xa7,0xa9,0x57,0x5a,0xf7,0xee,0xcd,0xb1,0xc1,0xb6,0x78,0x1c,0xe3,0xde,0x5c,0x02,0xc8,0xce,0xb7,0x8e,0x72,0xce,0xfd,0x79,0xcf,0x1a,0xef,0xcb,0x5b,0x5d,0x3c,0x1d,0xc8,0x1e,0x9f,0x67,0x26,0x86,0xd3 +.byte 0x3b,0x98,0x49,0x04,0xcd,0x1b,0x48,0x7c,0xa6,0xbe,0x37,0x0b,0x19,0xb1,0xb7,0x8a,0x74,0x0a,0xd9,0x4f,0x7b,0xbb,0x8e,0xc6,0x9b,0xdd,0xbc,0x61,0xfd,0xdd,0x86,0x7e,0x70,0x2e,0xe4,0x94,0xb4,0x62,0x47,0x6b,0x7c,0x92,0x41,0xda,0x05,0xdc,0xaf,0x5c,0x93,0xbc,0x7d,0xad,0xce,0x44,0x9e,0x27,0x1c,0x74,0x30,0x01,0xf2,0x8a,0x22,0xce +.byte 0x88,0x61,0xf5,0xb8,0xe2,0xf0,0xca,0x14,0x21,0x53,0xd3,0xbe,0x95,0x8f,0x52,0x10,0x21,0xc5,0x25,0x16,0xa1,0x4f,0xef,0x9a,0x6f,0xce,0xe9,0xee,0x06,0xa8,0x32,0xa4,0xac,0xee,0xd8,0x95,0x0b,0x65,0x10,0xbc,0xb3,0x15,0x48,0xf9,0x96,0xee,0xde,0x5d,0xf6,0x38,0x5f,0x32,0x70,0xd1,0x29,0xa8,0x1d,0xdc,0xf4,0x34,0x2d,0x0c,0x93,0x48 +.byte 0x8c,0x40,0xed,0x35,0x41,0xfe,0x4b,0xab,0x20,0x7d,0x95,0x74,0x02,0xe5,0x71,0x76,0x7e,0x59,0x35,0xb3,0xd7,0x43,0x1f,0xd4,0xe6,0x02,0x86,0xba,0x4f,0x53,0xd9,0xc3,0x7d,0x7f,0x3d,0xb6,0xd8,0x92,0x07,0x89,0x99,0x46,0xf8,0x09,0xcd,0x19,0x43,0x93,0xa7,0xc1,0xb2,0x5d,0xec,0xbf,0x09,0xf4,0xba,0xfc,0xf7,0xf1,0xa7,0x2e,0xfe,0x71 +.byte 0x04,0x58,0xab,0x16,0xd7,0xc0,0xf7,0x03,0xd4,0xc4,0xb9,0xe4,0xd8,0xfc,0x5b,0x66,0xa6,0xb3,0x6a,0x94,0x0e,0xba,0x8c,0x54,0x5c,0x8c,0x02,0x0a,0x33,0xcb,0xde,0x1c,0xad,0x6d,0xef,0x48,0x05,0xa6,0xca,0x9a,0x27,0xd6,0x1c,0xc3,0xea,0x3a,0x46,0x20,0xec,0x72,0xc4,0x94,0x89,0x7e,0xba,0xa9,0x2f,0xe5,0xec,0x1a,0xe4,0x50,0x54,0xeb +.byte 0xd9,0x5a,0x08,0xc5,0x84,0xc1,0x9a,0xdf,0xb0,0xd4,0x9a,0x6d,0xa2,0x93,0x52,0xd2,0x4d,0x69,0x88,0xc8,0x40,0x2d,0x26,0xbd,0x7a,0x37,0x04,0x21,0xe1,0x9d,0xc9,0xed,0xda,0x7a,0x4c,0x11,0x49,0x14,0x42,0xa1,0xdb,0x6e,0xed,0x1b,0x37,0xbf,0x09,0xac,0x35,0xda,0x80,0xf6,0x75,0xd4,0x32,0x54,0xb5,0x18,0xe8,0x79,0x25,0xc4,0x95,0xe8 +.byte 0x74,0xcf,0x6d,0xac,0x34,0x1f,0xea,0xd4,0x2e,0xd1,0x77,0x5e,0x90,0x8f,0x12,0x51,0xbb,0x3c,0xdf,0xe6,0xf4,0x49,0x8c,0x0f,0x9a,0x8e,0xe3,0x96,0xbd,0xba,0xe6,0x47,0x4b,0x50,0xc7,0xa9,0x29,0xea,0x09,0x5d,0xef,0x3c,0x91,0x48,0xc6,0x37,0xfd,0xac,0x7b,0xe5,0x04,0x25,0x93,0x0b,0xe3,0xce,0x32,0x46,0x38,0x81,0x97,0x57,0xbe,0x1f +.byte 0x3c,0x61,0x2d,0xd1,0x4e,0xca,0xbb,0x44,0xc6,0xfd,0xdf,0xdd,0x11,0xbf,0xbf,0xa8,0xc0,0x32,0x67,0xc1,0x2e,0xd7,0xbe,0x3c,0xe3,0xcb,0x57,0xa5,0x6d,0xbb,0x8e,0x0f,0x69,0x22,0x42,0xef,0x53,0x0f,0xce,0x09,0x6a,0xda,0xbf,0xd6,0xed,0x61,0x67,0x82,0x83,0x13,0x63,0x97,0x7d,0x1a,0xad,0x34,0x77,0x37,0xa6,0xe0,0x89,0xaa,0xd4,0xb6 +.byte 0x8f,0x93,0xff,0xb8,0x8f,0x63,0x14,0xfd,0x17,0xff,0xe5,0x7c,0x83,0x23,0xaa,0xe0,0xb9,0xd9,0x94,0x3a,0x1a,0xe7,0xa5,0xbd,0xa6,0x2b,0xd3,0x49,0xca,0xeb,0x7d,0x87,0x1d,0x54,0x16,0x93,0xec,0x14,0x8b,0x77,0x3c,0xb4,0xbe,0x33,0x76,0x5e,0xcb,0x33,0x27,0xd3,0x20,0xd6,0xed,0x0c,0x66,0xb8,0xe0,0x00,0xa6,0x76,0xcd,0x8b,0xb4,0xef +.byte 0x11,0xbc,0xe5,0x59,0xcf,0x1d,0xf5,0x15,0x58,0x4a,0xe1,0xfd,0x87,0x8c,0x7b,0xb9,0xa4,0x42,0x5a,0xed,0x51,0x7e,0x8d,0xa6,0x19,0xaa,0xc4,0xa6,0x14,0x74,0x45,0xb1,0xda,0x87,0x0f,0xd7,0xe7,0x66,0x3b,0xcd,0x04,0x02,0x14,0x20,0x41,0x15,0x4c,0x33,0x79,0x80,0x7d,0xd4,0x44,0x2c,0xab,0x6c,0xf4,0xa8,0xd4,0x31,0x43,0x7b,0xa7,0xc7 +.byte 0x65,0x0e,0x32,0xc8,0xc8,0x6d,0xf5,0x65,0x1b,0x26,0xf1,0xe4,0x68,0x15,0x88,0x1b,0x00,0x60,0x23,0x31,0xd7,0x4b,0x57,0xda,0xf1,0x19,0xa9,0xd9,0xaf,0xe6,0xa9,0x1e,0x2c,0x0d,0x23,0xe4,0x5b,0xcb,0x43,0x38,0xf0,0x93,0xd3,0xfb,0x6a,0x9b,0x83,0x30,0x55,0x96,0x9f,0x53,0x06,0x3f,0xaf,0x40,0x69,0xef,0x9a,0x47,0x6b,0xba,0x7c,0x10 +.byte 0x10,0x44,0x89,0xfa,0xb9,0x9e,0x70,0xed,0x25,0x59,0x68,0xae,0x9b,0x17,0xcf,0x80,0x6f,0x34,0xb8,0x07,0x40,0xe5,0x27,0x6d,0xcd,0x46,0x2c,0x36,0x90,0xf3,0x83,0x74,0x68,0x35,0xf2,0x05,0xa8,0xdf,0x4e,0x34,0xc5,0xb4,0xeb,0x5a,0x7d,0xe6,0x10,0x8a,0x23,0x54,0xeb,0x9b,0x27,0xf2,0x07,0xee,0xf9,0x05,0xc2,0x5a,0x88,0xbd,0x49,0x2e +.byte 0x1b,0x00,0x31,0x68,0x4a,0xc9,0x3a,0xc5,0x93,0x82,0xa8,0x39,0xba,0x55,0xcd,0xc1,0xda,0x49,0xc2,0x4c,0xf4,0x93,0x00,0xcf,0x61,0xa4,0xbb,0x8c,0x64,0x33,0x90,0x14,0x6d,0x1d,0xad,0x75,0x97,0xd9,0x1d,0xfb,0x27,0x67,0x43,0x04,0xdc,0x4e,0xdf,0x0e,0x0c,0x7e,0x1c,0x89,0xfe,0x31,0xb7,0x9b,0x07,0x5e,0x99,0x08,0x22,0xef,0x6e,0x4d +.byte 0x8b,0xd6,0x27,0xe6,0x24,0x1a,0x28,0xb0,0x22,0xa5,0x69,0x17,0x82,0x46,0xe3,0x90,0xe8,0x04,0xae,0x90,0x66,0x14,0xec,0xa2,0x1b,0x7e,0x09,0x13,0x32,0x9d,0xec,0x8b,0x51,0x5f,0xa8,0x96,0x8f,0x4c,0xc6,0xbd,0x5c,0x70,0x29,0x21,0xac,0xe9,0x6e,0xb0,0x0c,0x61,0x50,0xba,0xcc,0x55,0x71,0xda,0x2a,0x92,0x86,0x0c,0xff,0xaf,0x7a,0xcf +.byte 0xaf,0x2a,0xbd,0xd6,0x15,0xa4,0x4c,0x2e,0x76,0x0d,0xcf,0x10,0x11,0x4a,0xd1,0x89,0xdd,0x46,0x5f,0x6b,0x5a,0x02,0x05,0x49,0x6f,0x98,0x6a,0xa7,0x8a,0x66,0x87,0x59,0x23,0xb5,0x3f,0x2e,0x95,0x73,0xfe,0x48,0xe9,0x0d,0x17,0xa6,0xa5,0x4e,0x40,0x98,0x79,0x40,0x1a,0x10,0x1d,0x84,0xdd,0x6f,0x17,0xa7,0xb7,0xfb,0x49,0xbd,0x54,0x97 +.byte 0x0f,0x42,0x25,0x95,0x83,0xf0,0x97,0xe7,0x4c,0x24,0xb5,0xe8,0x23,0x0a,0xd6,0xbf,0xef,0x2c,0x03,0x4f,0x87,0x59,0xe8,0x80,0x87,0xcc,0x51,0x1b,0x94,0xd8,0x60,0xe7,0x10,0x4d,0x01,0xfd,0x83,0xf2,0xd8,0x8d,0x1b,0x33,0xbf,0xaf,0x36,0x41,0x47,0x51,0xe0,0x45,0x2a,0x05,0x5f,0xe1,0x92,0xf8,0xa5,0x15,0x46,0x35,0xd8,0x9b,0xe0,0xff +.byte 0xee,0xa6,0x4e,0x7d,0xfd,0x96,0xa5,0x75,0xdf,0x7e,0xb0,0x7d,0x14,0x73,0xdd,0xbe,0x17,0x6d,0xdd,0xec,0xac,0x9a,0x92,0x68,0xe3,0x44,0x16,0x63,0x22,0xa8,0x15,0x58,0x8c,0x11,0x23,0x46,0x18,0xae,0x47,0x39,0x87,0xc7,0x4c,0x30,0x09,0xce,0xe5,0xc4,0xd8,0x82,0xc6,0xc6,0x3d,0x31,0xf6,0x0f,0xb5,0x69,0x61,0x63,0x88,0xd6,0xb8,0xda +.byte 0x89,0x29,0x87,0x69,0x6e,0x3f,0x55,0x2f,0xbc,0x91,0x91,0x43,0x7d,0xb3,0x7b,0x99,0x5a,0x5a,0xb0,0x7d,0x90,0xa7,0xe7,0x30,0x0d,0x32,0xb2,0x43,0x43,0x78,0x59,0x6e,0xbb,0xd7,0x76,0xd4,0x5b,0x4d,0xc4,0xa9,0x99,0xdd,0xd3,0xce,0x3d,0x13,0x41,0x38,0x33,0xed,0xb8,0x76,0x1a,0xbb,0xfd,0x26,0xcd,0x69,0x89,0x22,0x16,0x9a,0x21,0x35 +.byte 0x38,0x77,0x14,0x10,0x42,0x17,0x1f,0xa1,0xbf,0x55,0xb4,0x51,0x62,0x15,0xac,0xd0,0xa2,0x71,0xe4,0x32,0x89,0x33,0x8b,0x74,0xc6,0x61,0x38,0xd0,0xfe,0x28,0x69,0xe6,0x88,0x1b,0x11,0x7e,0x46,0x39,0xba,0x24,0xdd,0x1f,0x61,0xf4,0x74,0xad,0x58,0x94,0xa9,0x3e,0xc7,0x2a,0x9e,0xc0,0xe1,0x1c,0xee,0x21,0xab,0x3e,0x65,0x0c,0xe8,0xd8 +.byte 0x71,0x52,0xf3,0x6c,0x64,0x53,0x75,0x17,0x87,0x55,0x14,0x42,0x25,0x7f,0xe7,0x0d,0x89,0x1b,0x77,0x26,0xc4,0xaa,0xcc,0x91,0x47,0xe5,0x54,0xae,0x1a,0x0d,0x04,0x99,0xeb,0x56,0xd8,0xb4,0x6d,0xeb,0xec,0x2f,0x6c,0xc5,0x8e,0x76,0xe1,0xa0,0xa7,0x42,0x06,0xc9,0xc3,0x03,0xee,0xa9,0x9b,0x1e,0xfc,0x11,0xf5,0x2f,0x2b,0x14,0xb8,0x9f +.byte 0x87,0x61,0x9b,0xc7,0x38,0x0e,0x58,0xf1,0xd4,0x36,0xca,0x82,0x85,0x9c,0xde,0xec,0xd3,0x1e,0x29,0x4e,0x70,0x9e,0x9a,0xe0,0x8b,0x6f,0xfe,0xd0,0xe9,0x95,0x51,0xcf,0x36,0x31,0x9c,0xff,0x63,0xc6,0x04,0x8e,0x61,0xc2,0xcb,0x3a,0xfa,0xd0,0xd7,0x29,0xbd,0xe7,0x8a,0x2b,0x8e,0xa0,0xac,0x58,0x93,0xb3,0x52,0xca,0x80,0x17,0xd2,0x2d +.byte 0x93,0x5f,0xe0,0x8a,0x47,0x3c,0x67,0x95,0x64,0x91,0xa4,0x76,0xa4,0x5f,0xfa,0x93,0x4d,0xc7,0x6e,0x5d,0x23,0x9f,0xe1,0x4a,0x16,0xff,0xa5,0xf0,0x94,0xa8,0x02,0xcc,0x9a,0x84,0xd5,0x9d,0xb6,0xe5,0x7c,0x76,0x3f,0xc9,0xfd,0xdc,0x8e,0x59,0x9a,0x22,0x18,0x3c,0xe6,0x90,0x85,0x10,0x73,0x2d,0x65,0xa7,0xa7,0xe1,0xeb,0xc5,0x05,0x24 +.byte 0x1e,0x0b,0x31,0x19,0xb5,0xb0,0x8d,0xc0,0xb5,0x04,0xfe,0x9d,0xfa,0xf7,0xcd,0x71,0x29,0x40,0x19,0x23,0xed,0x2c,0xdb,0x89,0x89,0x8d,0x69,0x22,0x4c,0x9c,0xa7,0xf7,0xb1,0x56,0x87,0xa3,0x44,0xa9,0xa3,0x16,0x28,0xce,0x94,0x40,0x6f,0x71,0x77,0x0e,0x6d,0xe9,0x78,0xa2,0x2a,0x17,0x45,0x03,0xeb,0x1e,0xf1,0xfa,0x56,0x3e,0xa7,0x6b +.byte 0x08,0x06,0x6a,0xcb,0x8f,0x5e,0x0f,0xd3,0x6e,0x4b,0x21,0x31,0x73,0x50,0x94,0x56,0xf9,0xb9,0xc7,0x38,0x69,0xe8,0x09,0x3f,0x03,0xb3,0xb5,0xe8,0x2a,0x5e,0xf6,0xad,0xae,0x6f,0xab,0x6a,0x49,0xdd,0x93,0x6d,0xfb,0x8b,0xde,0xea,0x8b,0xb0,0xa1,0x44,0xf0,0xb3,0xf6,0xaa,0xe3,0xc8,0x04,0x87,0x9f,0x8b,0xee,0xab,0x13,0x1d,0x2d,0xeb +.byte 0x09,0x62,0x21,0x49,0x5f,0xb6,0x95,0xab,0xc4,0xee,0x69,0xfb,0x31,0xff,0xbf,0x1a,0xa6,0x4c,0x67,0x66,0x84,0xe6,0x0c,0xb7,0xb2,0x3e,0x3f,0xa4,0xb3,0x52,0xde,0x15,0xc9,0xa7,0xa9,0xb5,0x0d,0xe5,0x0b,0x99,0xa6,0xb6,0x8f,0x69,0xc5,0x6d,0x6c,0xbb,0x83,0x89,0x4e,0xfc,0x49,0x79,0x4d,0x46,0x31,0xa0,0x09,0x5f,0x5d,0xd0,0x5b,0x80 +.byte 0xa1,0xf4,0x36,0x48,0x97,0x6a,0xfd,0x34,0xcb,0x20,0xa8,0x01,0x25,0x04,0xe7,0x13,0x12,0x87,0x66,0x27,0x96,0x36,0xba,0x92,0xbd,0xda,0x94,0x11,0xef,0x90,0xbd,0xbc,0x9e,0xf9,0x63,0xb3,0xa6,0xc1,0xbb,0x46,0xe8,0x86,0x3f,0x2d,0xf9,0x11,0x3a,0x23,0xa8,0x7a,0x33,0x41,0x3e,0x2e,0x5d,0xde,0xc0,0xd2,0x23,0xca,0x41,0xa0,0xb9,0x70 +.byte 0x6d,0x31,0xf3,0x89,0x87,0x9b,0x72,0xd9,0x15,0x4d,0x8b,0x51,0xdd,0x56,0xa1,0xb4,0x68,0x52,0x65,0x81,0x12,0x46,0xea,0x24,0xb4,0x34,0xcc,0xa0,0xdb,0x7d,0x96,0xd9,0x8e,0x64,0x61,0x10,0x7c,0x2a,0x00,0x4d,0x82,0x61,0x54,0xa4,0x70,0x3d,0x9c,0xa5,0x0b,0xd2,0x08,0x71,0xa8,0x94,0xb1,0xb4,0x30,0x61,0x59,0x9f,0x72,0x61,0x56,0x2d +.byte 0xa3,0xf4,0x9d,0x1c,0xfc,0x49,0x9d,0x39,0x27,0xcb,0x54,0xb2,0xce,0x3c,0xb6,0x76,0xe5,0x8e,0xa5,0xe7,0x08,0xd4,0xc7,0x2c,0xa6,0x28,0xc8,0x3e,0x22,0x14,0x06,0x75,0x68,0x0d,0x6b,0xb5,0xa3,0x68,0x14,0x17,0xfe,0xb8,0xcc,0x26,0x5b,0x9d,0x0b,0xcc,0x3e,0xd7,0x6c,0xe0,0xec,0x5e,0x1e,0x1e,0xb8,0x9a,0xbe,0x91,0xb5,0xa6,0xb5,0x83 +.byte 0x28,0xc2,0x35,0x65,0xd3,0xde,0xdd,0x71,0x29,0x13,0xc1,0xee,0x78,0x22,0x34,0x0b,0x77,0x3a,0x48,0x98,0x26,0x43,0xc2,0xce,0x03,0xe8,0x75,0xf8,0x8a,0xdf,0x6a,0xb0,0xb4,0x8c,0x11,0x8c,0xe5,0x95,0x96,0x17,0xfb,0x06,0x5e,0x8f,0x36,0x10,0xc5,0x04,0x43,0x1b,0xed,0xd3,0xad,0xd4,0xa4,0xe0,0x17,0x85,0xed,0x9b,0xd8,0xae,0x98,0x46 +.byte 0x58,0x57,0x0e,0x46,0xea,0x3f,0x07,0x6d,0x0e,0x46,0xda,0x2f,0x68,0x2b,0xd6,0xe7,0x0d,0x4b,0xbe,0x32,0xee,0x10,0x73,0x18,0x7d,0x6b,0x2d,0x04,0x27,0x72,0xb1,0xe1,0xbf,0x89,0xaa,0x4d,0x1a,0xfc,0xbd,0xf2,0xc3,0x9f,0xf0,0x01,0x85,0x62,0x09,0x4d,0x08,0x2c,0x57,0x9a,0x7b,0xad,0x0b,0x79,0xff,0x14,0xa1,0x45,0xde,0x21,0x8f,0xe2 +.byte 0x93,0xd0,0x35,0x26,0xc3,0xbc,0x8c,0xb7,0x57,0x6a,0xdf,0x98,0xa7,0x75,0xc6,0xf6,0x4b,0x5f,0x91,0x6e,0x71,0x3a,0x5c,0x5f,0x57,0x63,0x34,0x87,0xf8,0x20,0x6a,0xa1,0xbf,0xf8,0xca,0x8e,0xf9,0xa9,0x10,0x8b,0xab,0x0b,0xc2,0xcc,0x71,0x89,0x7c,0xef,0x70,0x3a,0xb0,0xf6,0x90,0xcc,0x6b,0x2c,0xcc,0x8b,0x2a,0x21,0x78,0x23,0xa0,0x71 +.byte 0x8c,0x7b,0xc1,0x0f,0x27,0x72,0x40,0xe4,0x9e,0x35,0xf3,0x0a,0xc0,0x7e,0x7f,0xe5,0x9b,0xdb,0x93,0x49,0x08,0xc3,0x6b,0xb7,0xea,0xea,0xd4,0x5a,0x96,0x97,0x3c,0xdf,0xc7,0x02,0x39,0x9f,0xa3,0xca,0xdd,0x62,0xf3,0x68,0xc7,0xae,0x37,0xc1,0x35,0x73,0xb2,0x5d,0x99,0xe4,0xae,0x27,0x55,0x5e,0x6a,0xae,0x6f,0x1a,0x95,0x51,0xb1,0x3b +.byte 0xd7,0xb4,0x4d,0x3d,0x88,0x54,0x01,0xbe,0x2c,0x12,0x17,0x29,0x4f,0xf3,0xed,0x5a,0x1f,0xa9,0xf0,0x67,0xbd,0x7c,0xad,0xe5,0x58,0x52,0xd4,0xd1,0xfe,0x1e,0x1b,0xd6,0xce,0x7c,0xc3,0xa2,0xa9,0x72,0x9b,0x6a,0xe5,0xf9,0x39,0x22,0xaa,0x7f,0x2e,0xa2,0x53,0x75,0xf0,0x99,0x2e,0x36,0x86,0x83,0x10,0x63,0xd7,0xac,0xa3,0x52,0xa6,0x23 +.byte 0x80,0x46,0xe4,0xa9,0x07,0x79,0xe1,0x61,0x75,0xbf,0x08,0x31,0x6c,0xdd,0xe1,0x30,0xd0,0x35,0xc2,0xbd,0x30,0xb8,0x85,0xf3,0xd2,0x2c,0x90,0x7a,0xf0,0xd3,0x80,0xe5,0xf1,0xc2,0x58,0x3d,0xf7,0x3c,0xbc,0xff,0x03,0x4d,0xf7,0xad,0x2f,0xa6,0xfe,0x73,0xde,0xa8,0x60,0xd7,0x89,0x4a,0xcf,0x3d,0xf3,0xab,0x62,0xfa,0x9d,0x46,0xad,0xd0 +.byte 0x97,0x6f,0x89,0x84,0x16,0x9b,0x84,0xb2,0x6c,0x63,0x6d,0x29,0xee,0x8e,0x97,0x3c,0x48,0x19,0x92,0x62,0xdc,0x1d,0x35,0x9d,0xec,0x01,0x00,0x64,0xbf,0x4d,0x8b,0xa3,0x13,0x48,0x9f,0xb4,0x01,0x0d,0xb1,0xc4,0xf2,0xf2,0x6a,0x84,0x1a,0x07,0x3c,0x46,0xa6,0xb5,0x41,0x9a,0x32,0x7e,0xc3,0x4f,0x87,0x95,0x71,0x7a,0xbf,0x74,0xf8,0x0b +.byte 0xfb,0xa5,0xde,0xa8,0x35,0xf1,0xcb,0x04,0x8d,0x8b,0xd3,0xb0,0xc8,0x1d,0x6c,0xaf,0xb4,0x21,0x79,0x1c,0x34,0x71,0x2f,0xf5,0xc4,0xbe,0xad,0xbc,0xaf,0x2f,0x54,0x81,0xd9,0xf8,0xff,0x59,0xf9,0x4e,0x62,0x9f,0x7d,0x7c,0xe9,0xdc,0x67,0xae,0xa3,0x32,0x4b,0xf7,0x4e,0x53,0x4c,0x55,0x7d,0xc5,0xdd,0xd4,0x5d,0x93,0xb8,0x98,0x3e,0xd3 +.byte 0x15,0x65,0x52,0x78,0x5a,0xd2,0x21,0x84,0x5d,0x28,0xaf,0x44,0x7d,0x18,0xf8,0xdd,0x5c,0xc3,0x6e,0xc8,0x05,0x05,0x30,0xd0,0x82,0xf8,0x00,0x0f,0x3d,0x5c,0x62,0x7e,0xa6,0xd5,0x7b,0x9f,0xb1,0x44,0xb7,0x0d,0x22,0x81,0xe1,0x4a,0x2b,0x79,0x7e,0x39,0x4d,0x8a,0x9a,0xfd,0x94,0x0c,0xf7,0x23,0x10,0x99,0xd2,0xd2,0x8b,0x98,0xe5,0x9d +.byte 0xb0,0xbf,0xcf,0x06,0x08,0x80,0x32,0x69,0xfd,0x81,0x5f,0xb3,0x66,0x11,0x63,0xeb,0x30,0x1d,0xcd,0x5b,0x5b,0xec,0x0c,0xca,0x30,0x37,0xa0,0x82,0x79,0x75,0x87,0xc1,0xfa,0x5b,0x38,0x4b,0xe3,0xea,0x46,0x49,0x36,0x92,0x92,0xf0,0xc9,0x15,0xa5,0xec,0x9e,0x21,0xb6,0x9f,0xb4,0x6d,0xf6,0xef,0x5c,0x2f,0x7d,0xa4,0xb3,0x25,0xfb,0x13 +.byte 0x40,0xe1,0xa0,0x20,0x4a,0x3a,0xe2,0x3e,0xf5,0xe0,0x68,0x61,0x11,0x9a,0xfb,0x1e,0xe8,0x1b,0xe0,0x17,0x9c,0x8a,0xe5,0x53,0x74,0xdd,0xec,0xc6,0x03,0xc6,0xd0,0x9b,0xc2,0x0b,0x77,0x4c,0x36,0x2b,0xac,0x4e,0x4d,0xd2,0x26,0x70,0x39,0x96,0xb4,0x11,0x1a,0x5b,0xcc,0x3f,0xb9,0xcf,0x0d,0x04,0x55,0x05,0x00,0x66,0x8f,0xa9,0xec,0x31 +.byte 0xe5,0x47,0x4c,0x9b,0xb7,0x6e,0xa5,0xe7,0x9e,0x70,0xf4,0x02,0x2a,0x3c,0xa2,0x03,0x04,0x30,0x9e,0x3f,0x7c,0xaa,0x0a,0x8f,0x55,0x61,0xca,0x50,0x35,0xe6,0xa4,0x24,0x61,0x26,0x31,0x9e,0x9e,0x77,0x0d,0x15,0x3a,0xc0,0x88,0x32,0xb5,0xbb,0x3d,0x3e,0x59,0x25,0x52,0x81,0x2e,0x4b,0xc6,0x5d,0x9f,0x87,0x0f,0x1f,0x5e,0xec,0xdd,0xbe +.byte 0x32,0x6c,0x71,0xef,0xd2,0x9c,0xfd,0x70,0xc8,0xf6,0x1f,0xb9,0xc9,0xdd,0x4d,0x39,0x61,0x92,0xbd,0x0c,0x48,0x63,0x4b,0xd2,0x2b,0x8c,0x4b,0x35,0xb1,0x8e,0x04,0x44,0x3c,0xe1,0xde,0xfd,0x6e,0xde,0xeb,0x94,0x51,0xea,0x36,0x7b,0xc6,0x87,0x15,0x34,0x68,0xa0,0xb8,0x94,0xb6,0x56,0x33,0xf4,0xab,0x84,0xed,0x1c,0x36,0x91,0xa7,0x1b +.byte 0x03,0xca,0x48,0x64,0x16,0x5b,0x4b,0x69,0x47,0xae,0xd7,0xc9,0xcf,0x74,0xd2,0xbd,0x60,0x04,0x7c,0x66,0xe9,0x12,0x92,0x40,0x78,0x23,0x0b,0x5b,0xa0,0xda,0xf7,0xe4,0x9a,0xad,0x9c,0x31,0xe7,0xaa,0xad,0x5a,0xc3,0x45,0x00,0x6c,0xd3,0x4d,0x93,0xdf,0xb6,0x68,0x11,0x3f,0x2a,0xbc,0x9a,0x8d,0xeb,0x0f,0xb5,0xa9,0x8e,0xa5,0x2c,0x99 +.byte 0x94,0x8d,0x21,0xa9,0x41,0x6b,0x11,0x2e,0x02,0x21,0xd8,0xc1,0xbc,0xf0,0x2a,0x87,0xae,0x35,0xa9,0x78,0x5c,0x43,0xb8,0xb7,0x63,0x2d,0x09,0x31,0xae,0x6f,0xfc,0x39,0x7b,0x18,0xc3,0xce,0xe3,0xfa,0x51,0x70,0xc7,0x6b,0x5e,0xc3,0xce,0xc8,0xa2,0x3a,0x66,0x9e,0xfe,0x45,0xb4,0xa2,0xaf,0x81,0x03,0x74,0xbf,0x0c,0x65,0x4c,0x30,0x27 +.byte 0xd5,0x34,0x29,0x2d,0x83,0xa8,0xb9,0x1d,0xf8,0x12,0x09,0x51,0xdd,0x0e,0x66,0x95,0xf3,0x94,0xaa,0x83,0x3a,0x6f,0x8a,0x7c,0x3a,0x29,0x82,0xbb,0x80,0xa1,0x37,0x8c,0x79,0xf4,0x4a,0xa8,0xe4,0x17,0x72,0x77,0xee,0xc4,0xaa,0x25,0xd3,0x8f,0x2e,0xaf,0xb9,0xb2,0x3c,0xa6,0xd5,0x72,0x97,0x07,0x23,0x38,0xae,0x9e,0x22,0x08,0x85,0x70 +.byte 0xfa,0xff,0x38,0xe6,0x96,0x9f,0x2c,0x11,0x14,0x16,0x9a,0xfa,0x5a,0x7b,0x05,0x31,0x3e,0x20,0xbf,0x4d,0x87,0xaa,0xba,0x94,0xcd,0xdb,0xeb,0xec,0x29,0x58,0x4e,0x43,0x12,0xe8,0xf9,0x01,0x50,0xc8,0x51,0x7a,0x61,0x12,0xe9,0xed,0xc2,0xd6,0x2e,0xd3,0xed,0x54,0x72,0xf7,0x1b,0x0c,0x8c,0xb4,0x65,0xea,0x22,0x31,0x22,0xeb,0xcd,0x53 +.byte 0x66,0xf1,0xa5,0x34,0xe9,0x81,0x74,0xcb,0xb5,0x6b,0x45,0x71,0x69,0x6d,0x84,0xe8,0xc6,0x86,0xc9,0xdd,0x0c,0xa4,0x30,0x12,0x08,0x42,0x10,0x6b,0xcd,0x65,0x6c,0xfd,0x9c,0xde,0x77,0x3c,0x32,0x09,0xef,0x99,0x27,0x0e,0x4a,0x72,0x03,0x8d,0xb5,0x68,0xa0,0x67,0xf7,0xc2,0xae,0xb8,0xce,0x41,0x70,0x4e,0xdd,0x13,0xcb,0x3f,0x05,0x4e +.byte 0xf4,0xbc,0x88,0x98,0x2f,0x42,0x4e,0x5f,0x3e,0xcb,0x2c,0xd3,0x2f,0xb8,0x92,0xbb,0xd8,0x95,0xc8,0xaf,0xa9,0x44,0x8b,0xf0,0x2f,0x81,0xd4,0xe7,0x06,0x19,0xf7,0xa7,0x0a,0x73,0x3e,0x30,0xd9,0x00,0xe4,0x2d,0x76,0xb1,0x0d,0xfa,0x12,0x1f,0xbe,0x59,0x4f,0xf7,0xc8,0x5b,0xab,0xd7,0x16,0x3d,0x7e,0x97,0x9e,0xec,0xf8,0xcb,0x31,0x2e +.byte 0xe0,0x41,0x0b,0x00,0xa6,0x6d,0xe9,0x5e,0xd5,0x4a,0xc5,0xbf,0x1c,0xcc,0xa5,0x71,0x94,0x29,0x3d,0x17,0x43,0x27,0x63,0xc4,0xc7,0x8f,0x1b,0xb7,0x5f,0xcf,0xdf,0x8e,0x6a,0x69,0x87,0xc1,0x29,0xab,0x7b,0x8d,0xdf,0x07,0x95,0x50,0xa3,0x1c,0x8e,0xdc,0x7f,0x8a,0x21,0x37,0x1e,0x26,0xa7,0x67,0x28,0xb2,0xc8,0x23,0x5a,0x1d,0x94,0x46 +.byte 0x1b,0x3e,0x72,0x87,0x73,0x08,0xe2,0x3b,0x46,0x51,0xbe,0x5b,0xa9,0x72,0xb9,0xf8,0x45,0x6d,0x0c,0x89,0x80,0x0d,0x7a,0xfb,0x4c,0x3f,0x7f,0x3d,0x29,0xff,0xef,0xb2,0xec,0x23,0xc2,0x26,0xcf,0x8c,0x2e,0x28,0xbf,0xc5,0x68,0x47,0xd9,0x49,0x95,0xf1,0x67,0x7e,0x3a,0x48,0xe2,0x43,0x5c,0xc8,0x95,0x5b,0xb2,0xf3,0x22,0xc9,0x73,0x91 +.byte 0xb5,0x78,0x96,0x1b,0x9a,0x75,0x5f,0xb2,0x6b,0x8c,0x66,0x8c,0x8e,0xc1,0xe1,0xde,0xd6,0x64,0x31,0xe1,0x7b,0x12,0xd2,0x85,0x8f,0x52,0x68,0xec,0x80,0x26,0x3d,0xcc,0x9b,0xe3,0x57,0xbe,0x19,0x42,0xb9,0xdd,0x7d,0x2b,0x5b,0x6d,0x1b,0x9e,0x96,0xd7,0x75,0x83,0x82,0x3c,0x3e,0x5f,0xf8,0xa9,0x36,0xbe,0x14,0xc7,0xce,0x9d,0x05,0x7e +.byte 0xd7,0x38,0x37,0x35,0xc9,0x37,0x8b,0x9f,0xc6,0x2d,0xff,0x00,0x41,0xff,0x1b,0x09,0xea,0xd2,0xb0,0x04,0x48,0xff,0xfc,0xb5,0x67,0x54,0x39,0x3d,0x23,0x68,0x0b,0x7d,0x97,0xf3,0x65,0x20,0xa2,0xf8,0x33,0x96,0xd1,0xf4,0xc7,0xba,0x6f,0x00,0x95,0x36,0xf6,0x33,0xd1,0x8d,0xde,0xee,0x1e,0xfa,0x60,0x8e,0x5e,0x4c,0x70,0xbb,0x53,0x79 +.byte 0xc9,0x9a,0xdf,0x3c,0x53,0xe4,0x35,0x87,0xc3,0xe6,0x8e,0x0e,0x1a,0xd0,0xf8,0x57,0x2b,0x33,0x51,0x4d,0x7d,0x43,0x17,0x3e,0x6f,0x0e,0xca,0x86,0xb2,0xc6,0x09,0xf3,0x2f,0xc1,0x5f,0x0e,0x9a,0x5e,0x7d,0x9d,0xf7,0xff,0x09,0x46,0xe5,0x30,0x91,0x61,0x93,0xb5,0x2f,0xc5,0x7f,0x09,0x0b,0x55,0x94,0x17,0x25,0x19,0x9b,0xa9,0x0e,0x68 +.byte 0x71,0x18,0x1b,0x4b,0x1b,0xa3,0x75,0x90,0x56,0x96,0x5e,0x33,0x71,0xf2,0x06,0x69,0x07,0x04,0xcb,0x8c,0x79,0x9b,0xa5,0x17,0xd8,0xd8,0x77,0xc7,0xca,0x95,0x58,0x12,0xec,0xdd,0x41,0xc9,0x12,0x16,0x9a,0xc4,0xf0,0x27,0x7a,0x8e,0xeb,0x19,0x79,0x27,0x7b,0x2e,0x55,0x96,0x57,0x19,0xbe,0x55,0x8c,0x7f,0x97,0x90,0x80,0x40,0x5d,0x5a +.byte 0xf6,0x07,0xd6,0xb4,0xc5,0xe8,0x0e,0x54,0xde,0x78,0x23,0xca,0x39,0x90,0x42,0xb6,0x8b,0x14,0x22,0x06,0x71,0x77,0xd5,0xf7,0x8d,0x05,0x9d,0xbf,0xfe,0x38,0x91,0xba,0x79,0x85,0x30,0x47,0x25,0xf0,0xa2,0x72,0x55,0x94,0x2a,0x8a,0xc8,0x28,0xc8,0xa9,0x23,0xab,0xf0,0x4e,0x49,0x2f,0x58,0x53,0x35,0xd1,0xb6,0x16,0x81,0xc2,0x25,0x18 +.byte 0xd9,0x71,0x91,0xc4,0x81,0x3e,0xf4,0xd7,0x87,0x9e,0x57,0x78,0xf7,0x7d,0x4b,0xb2,0xfd,0x91,0x9f,0xa8,0x0e,0x77,0xb3,0xc7,0xe5,0x6a,0x95,0x17,0xc3,0xf4,0xcb,0x7f,0x96,0xc1,0xa8,0xee,0x6a,0x0f,0x1f,0x5d,0x20,0x28,0x93,0xe5,0xf3,0x13,0x46,0x53,0x47,0x9f,0x98,0xc6,0xf5,0x29,0x69,0xb9,0x83,0x36,0x03,0xa1,0x9a,0xb4,0xa9,0x4e +.byte 0xd6,0xda,0x25,0xe2,0x5b,0xbb,0x95,0xdf,0x0f,0x37,0x0b,0x02,0x51,0x03,0xd1,0x0e,0x84,0xef,0xdd,0x85,0xdd,0xae,0x10,0x32,0x65,0x03,0x65,0xf0,0x8e,0x0c,0x69,0x90,0x35,0x26,0x36,0xe8,0x05,0x46,0xe6,0xce,0x52,0x4d,0xb5,0x93,0x9f,0xe3,0xe5,0xb0,0x43,0x57,0x32,0x5d,0xca,0xd4,0xc9,0x89,0x2e,0x5b,0x03,0x8a,0x82,0x78,0x21,0x6b +.byte 0x41,0xa9,0x0a,0x9f,0xe0,0x50,0xec,0x72,0x01,0x67,0xe7,0x1c,0x92,0xe3,0xe4,0x83,0x4d,0x4b,0xcf,0x01,0x37,0x2f,0x34,0x86,0xcf,0x36,0xf7,0x3a,0x57,0xa3,0x89,0x73,0x0f,0x9c,0x06,0x82,0x75,0x7a,0x4b,0xd8,0x44,0x40,0xf2,0xc5,0xc4,0x22,0xa6,0x99,0x1b,0x73,0x2f,0xad,0x09,0xe9,0x84,0x6f,0xc3,0xca,0x72,0x3a,0x8a,0x55,0x55,0x0a +.byte 0xcd,0x33,0x51,0xef,0x5b,0x36,0x77,0x6c,0xb4,0x4a,0xae,0xdd,0xbd,0xec,0x65,0x99,0x43,0xd6,0x8a,0x16,0xba,0x89,0x4d,0x0c,0x11,0xb4,0x0d,0x5d,0x3e,0x76,0xcb,0x48,0x9d,0x31,0x40,0x71,0xe2,0xe4,0xa9,0xd9,0x6e,0x3c,0x3d,0xd1,0x6e,0xaf,0xb9,0x28,0x71,0x5a,0x07,0x6f,0xab,0xdb,0xf8,0x4f,0x11,0xbc,0xe0,0x14,0x01,0x43,0x4d,0xe2 +.byte 0xad,0x5d,0x2a,0xb2,0x58,0x66,0x05,0x50,0x66,0xf6,0x2f,0x66,0x11,0xd1,0xd7,0x05,0x85,0xb0,0x7f,0xa8,0x89,0xbd,0x41,0xda,0x35,0x1e,0xbb,0xff,0x70,0x1a,0xe8,0x65,0x96,0xe9,0x50,0x18,0x7f,0x4c,0xb2,0xe2,0x95,0x26,0xf6,0x37,0x09,0x8c,0x8d,0x7b,0x02,0xb0,0x7f,0x32,0xb5,0x70,0x22,0xd6,0x83,0x0b,0x85,0x25,0x00,0xc5,0x55,0x3f +.byte 0xfa,0x7a,0xc9,0xaf,0x87,0xc1,0x1c,0x11,0x96,0x71,0x18,0xd8,0xdb,0xab,0x86,0x57,0x0a,0x16,0x23,0x32,0x40,0xd3,0xaf,0x17,0x55,0xe3,0xe7,0x01,0x65,0x1f,0x87,0xda,0xb5,0x46,0x67,0x18,0x34,0xcc,0x28,0x77,0xc3,0x12,0x62,0x6c,0x8b,0x8a,0x11,0x7a,0x5a,0xd1,0xdf,0xb3,0x13,0x6b,0x29,0xce,0xf8,0x03,0xba,0xad,0x7c,0x14,0x60,0x42 +.byte 0x17,0xf6,0x7b,0x0c,0xb7,0x5f,0xd6,0xc1,0xb5,0xa5,0x2b,0xb1,0x9f,0x6c,0x65,0x29,0xe5,0xf4,0x84,0x85,0x11,0x82,0xf1,0x4c,0xcd,0xff,0x99,0x29,0x53,0x7b,0x43,0x04,0x60,0xc4,0x6c,0x01,0x5c,0xcb,0x33,0x4f,0xdb,0xc4,0xad,0x8c,0xea,0xff,0xd6,0xcd,0x8e,0x85,0x6e,0x54,0xd5,0x18,0x63,0x84,0x78,0xea,0xff,0x08,0x95,0xdc,0x2a,0x07 +.byte 0xac,0xea,0x44,0x79,0x52,0x07,0xf3,0xf1,0x03,0x7f,0x71,0x53,0xd8,0x85,0xdb,0x70,0xde,0x5e,0xd5,0x9a,0x18,0x9f,0xcc,0x3f,0xc0,0xc0,0x49,0x82,0x70,0x09,0xce,0x29,0x04,0x0a,0x19,0x81,0xd9,0x81,0x22,0x71,0x48,0x8e,0x79,0x08,0x1c,0xb4,0xc8,0x7e,0x60,0x43,0x4a,0xe3,0xd5,0x6b,0x09,0x5c,0x01,0x6e,0x20,0x9e,0xd2,0xaf,0x80,0xb7 +.byte 0xa2,0x0a,0x5b,0x26,0x08,0x32,0x73,0xbc,0xc6,0xfd,0x06,0xaa,0x2e,0x55,0xa0,0x5b,0xa9,0x3c,0x85,0xb2,0x04,0xdc,0x9a,0x94,0x02,0x93,0x96,0x6b,0x3e,0xc3,0x5e,0x37,0x9b,0x6f,0xef,0xb9,0x65,0x52,0x42,0x1c,0xa7,0x84,0x09,0x0c,0x49,0x3a,0x95,0x06,0x94,0xd7,0xc7,0x40,0xf5,0xf1,0x69,0x41,0xfb,0xf8,0x57,0xb5,0x1e,0x0c,0xf3,0xd9 +.byte 0xb1,0x2e,0x58,0x33,0xbe,0xb1,0x3d,0x61,0xc6,0xca,0x01,0xe5,0xda,0x60,0x8f,0x87,0xf7,0x9a,0xb5,0x92,0xb4,0x8c,0x2a,0xaf,0xd4,0x1e,0x9c,0x97,0x39,0x83,0x99,0x4a,0x07,0x54,0x75,0x7d,0xde,0x72,0x06,0xc1,0x8f,0xb4,0xde,0x12,0x43,0xf2,0x62,0xae,0xe7,0xec,0xfe,0xb2,0xe5,0x63,0x35,0xb7,0xee,0xaa,0xf0,0x09,0xb8,0x61,0xf2,0x42 +.byte 0x28,0x87,0xd7,0x47,0xa8,0xfc,0x51,0x85,0x6f,0xa2,0xb1,0xa6,0x82,0xd6,0x0e,0x1b,0x3f,0xea,0xa1,0xe1,0x91,0xc9,0xd2,0x5b,0x3e,0xff,0x18,0x39,0x14,0xe0,0x44,0xda,0x3d,0xd8,0xca,0xdb,0xd9,0xbf,0x3f,0xa4,0xdb,0x99,0x2e,0x31,0x32,0x7c,0xf4,0x61,0x2f,0xa1,0xf9,0xa9,0xbe,0x26,0x94,0xea,0xb4,0xe3,0x25,0x8d,0x93,0x3b,0xa1,0x7e +.byte 0x1e,0x99,0x87,0x6c,0xaf,0x14,0x54,0xd0,0xc0,0x37,0x39,0x76,0x3c,0x07,0x2e,0xce,0x98,0x25,0x81,0xe4,0x01,0x0c,0x07,0x79,0x4e,0xcd,0x82,0x44,0x83,0x04,0x07,0xa6,0x52,0xb7,0x96,0x7c,0x43,0x12,0xe1,0xc5,0x12,0x18,0x25,0x47,0xe4,0x19,0x6d,0x26,0x1e,0x55,0x66,0xca,0x28,0x4c,0xfa,0xd2,0xd9,0xcc,0x7e,0xad,0x9f,0x2a,0x2f,0xc6 +.byte 0x6c,0x77,0xaa,0x0f,0x5b,0xeb,0x15,0x97,0x62,0x52,0x3c,0x6f,0x4b,0xf3,0xcc,0x80,0x7b,0x1f,0x1d,0x58,0xf8,0xfe,0xc1,0x8c,0x3b,0xe3,0xd7,0x05,0xc3,0xd6,0xa9,0xda,0xcf,0x85,0x1c,0x68,0xd6,0x6d,0x2b,0x06,0x30,0x5f,0x58,0x39,0xea,0xfa,0x99,0xaa,0x04,0x10,0x05,0xaf,0xb0,0xf7,0x32,0x60,0x8d,0xe4,0xd1,0x40,0x32,0xd6,0xa3,0xf2 +.byte 0xba,0x5a,0x79,0x58,0x92,0x75,0xf0,0x3a,0xce,0xb2,0xee,0x66,0x3e,0xe3,0xbe,0x4d,0x53,0x9d,0xbb,0xdb,0x45,0xf0,0x09,0xeb,0xd5,0x83,0x39,0x20,0x06,0xa9,0x44,0x35,0xeb,0x6d,0x9b,0xd9,0xa4,0xda,0x4b,0x9d,0xde,0x3d,0x26,0xa2,0x2d,0xcf,0x8e,0x3e,0xbc,0xb4,0x8c,0x3a,0xbf,0x56,0x7c,0x48,0x50,0xb5,0xc5,0xbe,0x84,0x5e,0x63,0x82 +.byte 0x5f,0x87,0x77,0x4a,0xa7,0xf6,0x66,0x07,0x42,0x6a,0xb0,0xcf,0x19,0xaf,0x6c,0x16,0x85,0x78,0x88,0x3b,0xa5,0xbc,0x42,0xd2,0x4c,0xdf,0x51,0x3b,0xc4,0x0e,0xf5,0xc5,0x70,0x57,0x40,0xf6,0xed,0xd2,0x37,0x3e,0x14,0x0c,0x31,0xda,0x94,0x87,0x6b,0xd9,0x8c,0x15,0x41,0xa9,0xc0,0x2a,0x61,0xd3,0x52,0xe0,0xb6,0x0a,0x83,0x6b,0x75,0x1b +.byte 0x1e,0xd1,0x7f,0x26,0x19,0x34,0x9b,0x70,0xc9,0xba,0xdc,0xa2,0x03,0x6d,0xc7,0xac,0xbd,0x2c,0x63,0x8a,0x7b,0xb1,0x62,0x51,0xc1,0x1d,0x54,0x0d,0x34,0x0e,0xfb,0xa6,0xb8,0x9d,0x79,0x4f,0xc3,0xaa,0x8d,0xa0,0xcc,0x80,0x96,0x86,0x37,0xd6,0x80,0x9c,0x3d,0x91,0xd0,0xe7,0xe2,0xb4,0x00,0xba,0x86,0xe9,0xeb,0x86,0xea,0x84,0x78,0x81 +.byte 0x20,0x29,0x28,0x02,0x4d,0xd8,0x1b,0x5e,0x4f,0x41,0xfc,0x13,0x3e,0x4c,0x7f,0x64,0x55,0x35,0x41,0x0d,0x74,0xc5,0x6a,0x7c,0x37,0x82,0x41,0xbd,0x67,0x39,0xd9,0x83,0xfa,0x7f,0x8c,0xe1,0x9f,0x23,0x0d,0xe4,0x1d,0x40,0xe6,0x6e,0x94,0x5d,0xec,0x77,0xf7,0x5e,0xb4,0xa1,0x03,0xfb,0xa0,0x0e,0xba,0xf8,0x28,0x50,0x3c,0x38,0x47,0xf7 +.byte 0xed,0x2d,0xe5,0x0b,0xa8,0x7a,0xbd,0xbf,0x7e,0x38,0xc0,0x60,0xe7,0x7e,0xb1,0x03,0xef,0x4a,0x8c,0xc7,0x98,0xf1,0x94,0xf6,0xa0,0x50,0xb2,0x0b,0x7c,0x66,0x0a,0x62,0x10,0x24,0xb0,0xa1,0x69,0x02,0x33,0x79,0xbf,0xd0,0xb5,0xcb,0x17,0x20,0x55,0x02,0x70,0x44,0x5b,0xac,0x20,0x35,0xea,0x05,0x2d,0x68,0x51,0xe7,0x5f,0x1b,0xcd,0x4c +.byte 0x33,0x4d,0x04,0x21,0xfd,0x06,0x67,0x82,0x60,0x98,0x1f,0x79,0xf4,0x28,0xe0,0xa8,0x18,0xeb,0xf5,0x86,0x58,0xe6,0x9f,0xb5,0x29,0x0f,0xe8,0x37,0xeb,0x09,0xf4,0xc6,0x08,0xf2,0xde,0x4d,0x96,0x48,0x62,0x36,0x63,0x10,0x3f,0x63,0xeb,0x44,0x84,0xc8,0xf5,0x74,0x19,0x03,0x50,0xf7,0x7c,0xd2,0x06,0x20,0x6e,0x9b,0xa2,0x37,0xb0,0x68 +.byte 0x78,0x31,0xb6,0x05,0xfa,0xc9,0xcd,0x1d,0x4c,0xbd,0x33,0xb7,0xf3,0x93,0x38,0x7d,0x5f,0x00,0x85,0x5b,0x10,0x7f,0xc4,0x3f,0x3e,0xfe,0x62,0xca,0x51,0x83,0x95,0xcf,0x00,0x65,0x83,0x0e,0xd3,0x78,0xd0,0x51,0xcb,0x70,0x34,0x42,0xc6,0x3a,0x04,0xb9,0x10,0x92,0xe0,0x09,0x06,0xb0,0x66,0x9b,0x37,0x02,0x8d,0x0d,0x3e,0x2f,0xc5,0x17 +.byte 0x6a,0x87,0x7d,0x48,0xa4,0xcc,0x55,0x20,0x7b,0x77,0x07,0xcf,0x44,0x2f,0x88,0x8a,0xcc,0xf2,0x5d,0xa6,0x3e,0x5f,0xda,0xe2,0xde,0xd2,0x7f,0x7f,0xb7,0x90,0x53,0x64,0x6b,0x79,0x42,0x52,0x69,0xc6,0xd6,0xaa,0x9f,0xf9,0x19,0xbe,0x65,0x10,0x99,0x49,0xaf,0x36,0x49,0x1b,0x8a,0x3d,0x7f,0xdb,0xa2,0x1a,0xb5,0xd6,0x34,0x51,0xc8,0xc8 +.byte 0x06,0xca,0xf6,0xb8,0x76,0xa8,0x9d,0x43,0xae,0xf0,0x51,0xe5,0x9a,0x42,0xa2,0x83,0xed,0x20,0x8d,0xe8,0x1c,0xca,0x15,0x4e,0x37,0x3f,0xd8,0x06,0xa0,0xe1,0xf8,0x05,0xfd,0x42,0xf3,0x7a,0x96,0x44,0x36,0x02,0xca,0x11,0x2a,0xc3,0x24,0x58,0xdd,0x85,0x55,0xb2,0xe5,0x1d,0x92,0xc2,0x2d,0x5f,0x7c,0xb5,0x02,0x37,0x7c,0x07,0x35,0x25 +.byte 0x2b,0x33,0x80,0xe2,0xd4,0xfd,0xc7,0xa7,0x19,0x7e,0xba,0x36,0xaf,0xa0,0x4e,0xab,0x8b,0x28,0x4f,0x3b,0x92,0x72,0x42,0x49,0xaa,0x3b,0x08,0x0f,0x1e,0xff,0x2d,0xbf,0x9c,0x48,0x16,0x72,0xbe,0x28,0x05,0x8b,0x3a,0x20,0x6b,0x38,0x43,0xa2,0x35,0xea,0xf7,0x4e,0x50,0xa0,0x43,0x40,0x5c,0xbf,0xe5,0x75,0x13,0x4c,0x36,0x61,0xa1,0x5d +.byte 0x46,0xd7,0x7a,0x94,0x06,0x2f,0x63,0x32,0x9c,0x6e,0x54,0x18,0x31,0x79,0xf2,0x83,0xcf,0xb4,0x47,0x40,0xe5,0x9a,0xd6,0x99,0x12,0xb3,0x61,0x3d,0x0f,0x5e,0xc8,0x95,0xa3,0x5f,0xc3,0xd5,0x6b,0x6e,0xa0,0xf2,0x2f,0xeb,0x66,0xd0,0x68,0x67,0x10,0x85,0x64,0x27,0xd8,0xb8,0x68,0x00,0x36,0xa5,0xab,0x3e,0xe1,0x43,0x65,0x81,0x2d,0xb9 +.byte 0x0f,0x87,0xfe,0xa1,0x52,0xe9,0x8d,0x82,0x3a,0xd1,0x10,0x52,0x34,0x48,0x7c,0x1c,0xc6,0xd0,0xfe,0xa0,0x1a,0x92,0x07,0x88,0x57,0x9e,0xd7,0x5e,0x9f,0xc8,0xb0,0x93,0x73,0x03,0x28,0x36,0x8c,0x25,0x8c,0x0f,0x4e,0x0f,0x5b,0x26,0x58,0xed,0x5c,0x33,0x75,0x20,0x08,0x11,0x47,0xe1,0x47,0x85,0x47,0xeb,0x54,0xbf,0x58,0xe3,0xd4,0x5b +.byte 0xf9,0xc6,0x5e,0x42,0x58,0xe6,0xaf,0x79,0x66,0x3c,0xa5,0xa3,0x30,0x33,0xe3,0xbe,0x21,0x4b,0x42,0x98,0x6e,0x44,0xd7,0x68,0xc0,0xff,0xbe,0x7f,0xc5,0xb3,0x4f,0x4a,0x93,0xb0,0x11,0x88,0xcf,0x36,0xb2,0x03,0xbe,0x30,0x52,0x71,0x20,0x0d,0x16,0xc5,0xbb,0xf5,0x92,0x12,0x67,0x6a,0x35,0x66,0x00,0x09,0xd7,0xc6,0x67,0xb0,0x6a,0x04 +.byte 0x19,0x3e,0xbf,0xe2,0x82,0x74,0x78,0x2f,0x77,0x44,0xdc,0xad,0x0f,0x66,0x2a,0x23,0x62,0x2c,0x5a,0x4e,0x3a,0x82,0x2a,0x75,0x16,0x0d,0x74,0x64,0x35,0x53,0xc5,0xf6,0xda,0x36,0x44,0xba,0xe2,0xfa,0x1e,0xc2,0xcf,0x29,0x01,0x36,0x66,0xc3,0xca,0x40,0xf7,0xc4,0xba,0x67,0xac,0xf6,0x17,0xcc,0xa3,0x96,0x2d,0x08,0x5f,0x0a,0xea,0x5e +.byte 0x97,0xdc,0xc8,0xf9,0x59,0x24,0x6e,0xc5,0x0b,0x02,0xb9,0x1a,0xde,0xac,0x60,0x1d,0xaf,0x9f,0x5a,0x6f,0xe1,0xa6,0xdf,0x75,0xc5,0x9b,0xb7,0xde,0xa4,0xf7,0xf6,0xa4,0xdc,0xb6,0x96,0x08,0xde,0x2a,0x0e,0xb3,0x9d,0xf5,0x75,0x7d,0x7e,0x96,0x91,0x79,0xd4,0xa7,0x30,0x97,0x3a,0xbd,0x7c,0xe0,0xc5,0x87,0x24,0xb0,0x65,0xb7,0x58,0x00 +.byte 0xd9,0x0e,0x97,0xa6,0xa4,0x6a,0xe8,0x0a,0xac,0xac,0x9f,0x3a,0xe3,0x2a,0x9a,0x43,0x41,0x92,0x6e,0x0e,0xc4,0x63,0xc3,0x18,0xb6,0xe1,0xef,0x3d,0xe8,0x0b,0xb0,0x9f,0x2e,0x19,0xa0,0x98,0x98,0x34,0xf8,0x86,0x6d,0xc5,0x8c,0x41,0x26,0xb7,0xf2,0x1d,0xd4,0x72,0x39,0xeb,0x79,0x06,0xaf,0x53,0xaa,0x34,0x80,0x53,0xf8,0x1b,0xf4,0x53 +.byte 0x19,0xfa,0x16,0x8b,0x39,0xea,0x63,0x7f,0x38,0xc4,0x66,0x1d,0xd1,0x90,0xe4,0x2f,0x20,0x43,0x0d,0x5f,0x98,0xcc,0xae,0xef,0x86,0xc8,0xe5,0xf6,0xd2,0xa5,0x49,0xd0,0x3f,0xb5,0x7e,0x42,0xb5,0x6e,0x5e,0x13,0xa5,0xb4,0x71,0x2c,0x5d,0x57,0x24,0x06,0xd2,0x29,0x7c,0x4c,0x90,0xb6,0xea,0xdb,0x62,0xa4,0x2c,0x6c,0x38,0x57,0x97,0xbd +.byte 0xfd,0x41,0x6e,0x26,0xc1,0xe1,0x6b,0xbb,0xf0,0xe7,0x71,0xf1,0xcf,0x6a,0x7f,0xfa,0xe7,0xfb,0x17,0xe7,0x81,0x19,0x9a,0xf2,0xf6,0x86,0x22,0x4f,0x62,0x59,0xd6,0xc2,0x33,0xbd,0x11,0xe7,0x07,0x3a,0xfe,0x74,0x0d,0xf8,0xd9,0xdb,0xbd,0x05,0xf4,0xf4,0xb1,0x41,0xc9,0xb3,0xf8,0x6a,0x7b,0x98,0x08,0x6c,0xce,0x4c,0x28,0xbf,0x8c,0x77 +.byte 0x68,0xdc,0xee,0xf7,0x11,0xde,0xfc,0x5a,0x58,0x4f,0xf4,0x74,0x9d,0x5b,0x78,0xc3,0x78,0xe5,0x5e,0x26,0x83,0x40,0x17,0x80,0x2a,0x02,0xa4,0xf1,0x0f,0xa0,0xc8,0x22,0xe6,0x09,0x3a,0x52,0x74,0xf0,0xb9,0xb9,0x60,0xaf,0x20,0xa6,0x7e,0x88,0xf4,0xc2,0x38,0xa2,0x21,0x73,0xa9,0x18,0x3f,0x7a,0x04,0x7b,0xc4,0xcd,0x68,0xd9,0x83,0xa4 +.byte 0x8e,0x54,0x0d,0xbc,0xee,0x8b,0x39,0x93,0x66,0xa2,0xd6,0x76,0x4a,0xb2,0x33,0x4f,0x61,0x53,0xde,0x3b,0xff,0x47,0xcb,0x87,0xd9,0x21,0xd0,0x82,0x64,0x54,0xdf,0xf2,0x67,0x62,0x40,0x33,0xc7,0x0d,0xea,0x98,0xaa,0x95,0xfb,0xa9,0x0e,0x90,0xa5,0xd9,0x54,0x81,0x86,0xad,0x9e,0xa4,0x4d,0x36,0xe1,0x77,0xf2,0xe3,0x0a,0x54,0x1a,0x57 +.byte 0x9d,0x62,0x5e,0x0e,0x00,0xc8,0xa6,0x1e,0xf3,0x43,0xe6,0x20,0x0d,0x6a,0x8e,0x90,0x1d,0x4d,0xac,0x2f,0x9f,0x1c,0xb7,0x30,0xec,0x5c,0x99,0x78,0x6f,0x3b,0xe7,0xe0,0x28,0xb9,0x97,0xc5,0x6a,0xf2,0x17,0xc2,0x11,0xac,0x1a,0xe2,0xca,0x57,0x49,0x64,0xc8,0xc7,0x66,0x43,0x8d,0xc8,0xa7,0x0e,0xfc,0xcf,0x05,0x2f,0xae,0x4b,0xfe,0xe4 +.byte 0xbe,0x9c,0xe7,0xe6,0xa8,0x36,0x49,0x0d,0x9c,0x60,0x39,0x0c,0xfd,0x41,0x5b,0xc7,0xa4,0xa5,0x30,0x89,0xe5,0x10,0xf6,0xea,0xf8,0x2c,0xf2,0x3e,0xb1,0x96,0x81,0xa7,0x32,0x8b,0x39,0x14,0x15,0x36,0xfc,0x55,0x3c,0x22,0xcf,0xa3,0x98,0x90,0x68,0x13,0xd8,0x3f,0xf2,0x53,0x19,0x3e,0x9a,0x0c,0x1f,0xc6,0x29,0x43,0x46,0x23,0x58,0xea +.byte 0x49,0x49,0x15,0x46,0x8e,0x63,0x30,0x1f,0x3e,0x2a,0xa0,0x18,0xfd,0x28,0xc5,0x32,0x77,0x75,0xac,0x6e,0x5d,0x39,0xa9,0x44,0xce,0xfe,0x39,0xa6,0xec,0xde,0x69,0xde,0xfa,0xc8,0x40,0x44,0x34,0x29,0x15,0x19,0xa7,0xbe,0xd6,0x5b,0xfd,0x1f,0x7b,0xb9,0x88,0xf1,0x14,0xcf,0x42,0xc5,0xa7,0xa7,0x0e,0x6b,0x6e,0x86,0xb2,0x7c,0x23,0x8e +.byte 0xf6,0xae,0xde,0x3c,0xd7,0x26,0x5e,0xde,0x31,0x94,0xc1,0x19,0x65,0x55,0x03,0x73,0xba,0xdc,0x69,0x95,0x9c,0x9d,0x8e,0x59,0xd8,0x51,0x61,0x9f,0x8f,0xf4,0x29,0x43,0x4b,0x6a,0x75,0xb3,0x4b,0x9d,0xcc,0x46,0xd2,0x6e,0x00,0x49,0x4f,0xf0,0xac,0x80,0x55,0xc0,0x0c,0xbf,0x18,0x52,0x75,0x76,0x3b,0xac,0x92,0x83,0x69,0x1b,0xb4,0x15 +.byte 0xe5,0x9e,0xde,0x10,0x30,0x30,0x0e,0x85,0xc7,0xf9,0xae,0xbc,0x9e,0xaf,0x4b,0xee,0x27,0x6b,0xa5,0x6d,0xe4,0x8e,0xed,0xdd,0x95,0xaa,0x85,0xe2,0xf5,0x38,0x15,0x50,0xd3,0xcd,0x2c,0x88,0x6c,0x2b,0x14,0x37,0x74,0x2d,0x6d,0x30,0xec,0x96,0x78,0xae,0x80,0xb3,0xd9,0x84,0xc1,0xd6,0x71,0x90,0xe4,0x8d,0x3a,0x7c,0x9c,0xc4,0xf5,0xa0 +.byte 0x20,0x7e,0xa2,0x0e,0x75,0x7c,0x25,0x7a,0x7e,0x2b,0x2e,0xdb,0x12,0x23,0x73,0x6a,0x8e,0xe3,0xd7,0x47,0x94,0xfb,0xcc,0xe4,0x5a,0x8c,0xfb,0xdc,0x46,0xb3,0x4a,0x42,0x15,0xe0,0xaf,0x6e,0x81,0x72,0x72,0x04,0x52,0x09,0xc5,0x8b,0x6e,0xdd,0x7d,0xff,0x27,0xa8,0xc1,0x94,0xb5,0x33,0x59,0xc2,0x7d,0x59,0x6c,0x3c,0xaa,0xd9,0xd8,0x05 +.byte 0x43,0x7e,0x8a,0x47,0xdd,0x76,0x36,0xe3,0x05,0x49,0xd1,0x8f,0xdf,0x45,0x46,0x63,0xff,0x17,0xb4,0x52,0xc8,0xee,0x4d,0xf5,0x74,0x65,0xc6,0xca,0x19,0xfd,0xb9,0x51,0xc8,0xc9,0x96,0xd4,0x06,0xd4,0x09,0x1e,0xab,0x6d,0x1b,0x26,0x61,0x80,0x5b,0xa8,0xcb,0x62,0x92,0x5a,0x1a,0x8e,0xa4,0xb7,0x25,0x19,0x96,0x63,0xd5,0xc3,0xc9,0xdc +.byte 0x04,0x83,0x62,0x31,0xe3,0x76,0x00,0x4d,0xf8,0xb3,0x98,0xae,0x4d,0x1a,0x38,0xe3,0xa1,0x27,0x52,0x87,0xbe,0x2c,0x93,0x45,0xd1,0xab,0x56,0xc6,0xf5,0xbc,0xb5,0xe6,0x9c,0xe1,0x1b,0x37,0x42,0x08,0xe7,0x71,0xb5,0xa4,0x67,0xf9,0x48,0xd4,0xc4,0x10,0x25,0x53,0x9c,0x03,0xfc,0x6d,0x5e,0x62,0x5e,0x6d,0x56,0xbc,0x78,0x11,0x0a,0x6d +.byte 0x1b,0x7a,0xdc,0x62,0xb5,0x58,0x86,0x15,0x71,0xff,0x11,0x33,0x94,0x2b,0xa6,0xc7,0x68,0xd5,0x68,0xda,0x5b,0xd5,0xb7,0x38,0x6c,0x1c,0xf4,0x07,0x39,0xef,0x1f,0x72,0x0a,0xb3,0x12,0x13,0x25,0x86,0xd3,0xf8,0x9f,0xb5,0x40,0x58,0xe7,0x5e,0x9f,0xa0,0xbc,0xd7,0xab,0x4f,0xf3,0x94,0xcf,0x0f,0x5a,0x4c,0x98,0xb4,0x70,0x35,0x62,0xee +.byte 0x33,0x24,0x72,0x31,0xd4,0x06,0xd9,0xb4,0x1c,0x1e,0x0f,0xa7,0x48,0xc7,0x75,0x45,0x40,0x02,0xd0,0x60,0x32,0x29,0x4d,0x61,0x7a,0xee,0x65,0x35,0x2b,0xe5,0x50,0xac,0x82,0xdb,0xf7,0x9c,0x8f,0x82,0xe4,0xf0,0xbd,0xdb,0x00,0x3d,0x3a,0x3d,0xa2,0xc3,0x2d,0x0e,0x51,0x20,0xdb,0xdb,0x8d,0x15,0x03,0xbd,0xcb,0xcb,0x24,0x81,0xc5,0xdb +.byte 0x05,0x39,0x48,0xb8,0x3c,0x93,0x35,0x10,0xef,0x19,0xba,0x09,0x9e,0xff,0xf9,0x3f,0x0c,0xdc,0x96,0x98,0x32,0x26,0x76,0xe7,0xfa,0xaa,0xdf,0xdc,0xb9,0x15,0x44,0x42,0x9a,0x8c,0x6c,0x88,0xea,0x43,0x63,0xb5,0x79,0xb6,0x50,0x30,0x78,0xea,0x70,0xba,0x33,0x36,0x8f,0x8c,0xe5,0x78,0xfd,0xbc,0xc0,0xbd,0xde,0x3a,0x3d,0xe6,0xe6,0x57 +.byte 0x0f,0x29,0xf2,0x82,0x05,0xf2,0x5c,0xfd,0x33,0xc1,0xb2,0x2e,0xc2,0xc0,0x42,0xa2,0xc8,0xa5,0xf9,0x70,0x05,0xff,0x7b,0x8d,0xb9,0x68,0xc3,0xf6,0x74,0x00,0xcd,0x9d,0x70,0xfa,0x62,0x34,0xe5,0x05,0xe8,0x5f,0x53,0x9b,0x69,0x01,0x86,0xb9,0x1d,0x68,0x80,0x89,0x51,0x52,0x0d,0xe8,0x28,0xa1,0xdd,0x62,0x2b,0xf3,0x53,0x74,0xaa,0x98 +.byte 0xdb,0x7e,0x74,0x44,0xeb,0x25,0xe7,0xde,0xc4,0x29,0x14,0x11,0x7b,0xc6,0xef,0x14,0xe4,0x04,0xd0,0xf4,0x11,0xca,0xdc,0xdc,0xe6,0x3f,0x9a,0xc9,0xe2,0x0e,0x67,0x30,0x78,0x65,0x94,0x5a,0xa1,0x24,0xd6,0x90,0x2f,0x1c,0x13,0x46,0xf5,0xb5,0xf9,0x74,0x56,0x3e,0xd5,0x1b,0x09,0xb3,0x04,0xbe,0x89,0x00,0xbd,0xe0,0xba,0x13,0x05,0xd1 +.byte 0x98,0xa7,0x93,0x09,0xc5,0x96,0x46,0xb5,0x5a,0x05,0xac,0x1e,0x66,0x03,0xf0,0xaa,0x3d,0xc2,0x54,0xa3,0xc4,0x2b,0x0d,0xa3,0xe4,0x92,0xd6,0xd0,0x44,0xa6,0x37,0x30,0xa5,0xac,0xc2,0xc8,0x58,0x2a,0x2c,0x18,0x68,0x8d,0x9b,0x4f,0x99,0xd0,0x55,0x41,0xf4,0x84,0x3c,0x69,0xda,0x3c,0x6d,0x43,0xb3,0x85,0x15,0x1f,0xdb,0x58,0x0b,0x71 +.byte 0x33,0x24,0xbb,0x21,0x43,0x19,0x16,0xeb,0x83,0xde,0xe5,0xb7,0x68,0x9e,0xb9,0xd9,0xf6,0x2e,0xae,0xdd,0x88,0x2c,0x18,0xd7,0xc3,0x72,0x8b,0xbe,0xaf,0x8d,0xfd,0xcd,0x2f,0x8e,0x3e,0x2b,0xa4,0x20,0x11,0x9d,0x00,0x4f,0xea,0xf0,0xaa,0x2d,0xf3,0x9d,0xfd,0x11,0x7b,0xac,0x2c,0x66,0x74,0x03,0xe5,0xcc,0x70,0x9f,0xfb,0xb7,0x5a,0x16 +.byte 0xc3,0x05,0x61,0x7c,0x8c,0x73,0xcc,0x9c,0x6a,0x2f,0xee,0xae,0x85,0xc9,0x51,0x91,0x13,0xa4,0x09,0x82,0x4d,0x62,0x09,0x24,0x25,0x35,0x1f,0x82,0x88,0xbb,0xdd,0x16,0x5e,0x8d,0x98,0x5f,0x07,0x49,0x32,0x96,0xb7,0xee,0x85,0xb0,0x7b,0xfd,0xf5,0x35,0x4b,0xa9,0xd4,0xee,0xf2,0x37,0xd1,0xfe,0x62,0xf5,0x52,0x13,0xb4,0xb2,0xce,0xc4 +.byte 0xe0,0x09,0x78,0x48,0xd5,0xc6,0x5d,0x36,0x1b,0x90,0x3a,0x6a,0x3c,0x21,0x50,0xf0,0x0a,0xe9,0x46,0x24,0x45,0xc1,0x5e,0x76,0xa3,0xf9,0x70,0xb8,0x62,0x4d,0x0e,0x92,0x87,0x4a,0x6a,0xf9,0x46,0x91,0x64,0xfe,0x7f,0x53,0x24,0x7e,0xc7,0x3e,0xb0,0x37,0x1a,0xc8,0xd6,0x33,0x0b,0x5f,0xa5,0x30,0x03,0x0e,0x85,0x3d,0x7b,0xc1,0xa1,0x18 +.byte 0xb3,0x8c,0xfe,0xca,0x3e,0x71,0xd8,0x92,0x46,0x49,0x60,0x54,0xd9,0x7b,0xf7,0xc3,0x99,0x2f,0xb5,0x79,0xcc,0x32,0x40,0x7d,0x3d,0x0b,0xc6,0x6f,0x04,0xd9,0xf1,0xdd,0x64,0xf5,0xc4,0x60,0x14,0x04,0x5c,0x3a,0xa4,0xda,0xdc,0xad,0x8f,0xc2,0x44,0x37,0x96,0x63,0x00,0xf7,0xb1,0xc0,0x7c,0x8c,0x12,0xb5,0x3a,0xec,0xc0,0x16,0xd8,0x24 +.byte 0xe9,0xc0,0xc4,0xfa,0xb1,0x85,0x5b,0xe3,0x62,0x24,0xa1,0x75,0x92,0x82,0x04,0x59,0x10,0x50,0x4b,0x51,0x51,0x3e,0x39,0xba,0x6d,0xa0,0x65,0x2d,0xfc,0x23,0x1c,0x9d,0x69,0x22,0xe7,0x15,0xfa,0xba,0x76,0xbf,0x53,0x62,0xb0,0x0d,0x0d,0x5d,0x55,0x00,0xbc,0x58,0x01,0xed,0x37,0x53,0xb9,0xa6,0x0d,0x71,0xab,0xec,0x42,0xbf,0x3b,0x52 +.byte 0xfd,0xae,0xe9,0x6d,0x65,0x07,0xf3,0xd9,0x32,0x66,0xc1,0x66,0x1a,0x18,0x73,0x86,0x01,0xaf,0x1d,0xd1,0xd0,0xcf,0xb1,0xea,0x54,0x23,0xdf,0xf2,0x4d,0x7d,0xc7,0xfe,0xfe,0x7d,0x1d,0x2c,0x1b,0xb6,0xa7,0x7a,0x9e,0x90,0x3a,0x3b,0xb0,0x6c,0xb0,0xd2,0xd1,0xd0,0x6a,0x94,0x4c,0x84,0x1c,0x45,0xae,0xda,0x16,0xa9,0x2e,0x63,0x19,0x26 +.byte 0xf6,0x74,0xd3,0x6f,0x9b,0x9c,0x0c,0xb8,0x85,0x9f,0xeb,0x99,0xbc,0xab,0xff,0xc3,0x75,0x86,0xe5,0x3a,0xa0,0xf9,0xfc,0x6b,0x3d,0x5a,0xad,0x46,0x7f,0x17,0x0e,0x94,0xb7,0xa4,0x43,0x61,0x54,0x76,0x29,0x78,0xe4,0x41,0x91,0xbe,0xa5,0x36,0x39,0xdf,0xdc,0xcc,0x8e,0x42,0x40,0x08,0x51,0x26,0xb0,0x53,0x5d,0xb4,0x7a,0x18,0x8e,0xb3 +.byte 0xae,0xf2,0xe0,0xef,0x63,0x51,0x3a,0xbe,0x4c,0x2d,0xce,0xc7,0xe2,0x1b,0xc2,0x40,0xf3,0x82,0x61,0xf0,0x1b,0x05,0xdd,0x1e,0xae,0xed,0x87,0x2c,0xe5,0xad,0xc7,0xec,0xb5,0x63,0xf7,0x3a,0xf9,0xb7,0xd8,0x4e,0xa7,0xef,0xac,0x6d,0x9c,0x27,0xd9,0xcc,0x66,0xf4,0x75,0x40,0x94,0x8b,0x78,0x4f,0x61,0x4f,0x31,0x49,0x5c,0x96,0x72,0x58 +.byte 0xcf,0x55,0xb2,0x66,0x16,0x29,0x27,0x24,0x39,0xc3,0x64,0xb1,0xdf,0x69,0x87,0x85,0x46,0xe3,0xd0,0x82,0x53,0x1a,0xc2,0xf1,0x3a,0xab,0xdf,0xe5,0x29,0x17,0xdd,0xfe,0xbf,0xf9,0x3d,0x7a,0xfb,0xe7,0x74,0x49,0xa9,0xef,0x61,0x93,0x4c,0xfa,0x30,0xea,0x65,0xa7,0x61,0x32,0x88,0x74,0x12,0xc1,0x91,0xf1,0xc2,0x1f,0x38,0x6a,0xfd,0x0d +.byte 0xc8,0x6f,0x87,0xe6,0x15,0x55,0x26,0x13,0x86,0x13,0xb9,0x01,0x98,0x34,0x1c,0x2d,0x1d,0x30,0xae,0x7d,0x8e,0x07,0x7d,0x4d,0xe9,0xfd,0x58,0x18,0xc3,0xa6,0x8e,0x87,0x98,0x33,0xcc,0x80,0xd7,0x70,0x07,0x6a,0x4a,0x97,0xef,0x56,0xf3,0x9d,0xf9,0xef,0x6f,0xa8,0x71,0x7f,0x61,0x07,0x1d,0x9d,0x51,0x06,0x86,0x4a,0x35,0x9e,0xab,0x2c +.byte 0x66,0x8d,0x61,0x62,0xbd,0xed,0x6c,0x76,0x7c,0x67,0xe0,0xe1,0x6e,0x90,0x74,0xb1,0xa6,0x26,0x0d,0x01,0x1f,0xe9,0xb4,0x30,0x9a,0x7e,0x37,0xd1,0xea,0x97,0x9a,0x0f,0x9e,0x8d,0x52,0xd4,0x96,0x36,0x5b,0x6f,0x40,0xbb,0x9e,0x44,0xb4,0x6e,0xee,0x15,0x70,0xef,0x66,0x81,0xf5,0xb4,0xe7,0x69,0xb0,0x40,0x44,0xdc,0x70,0x1e,0x4d,0x3c +.byte 0x9b,0x19,0x2a,0x97,0xbd,0xb2,0xd2,0x9b,0x98,0xac,0x36,0xf1,0x05,0x48,0xdc,0x5d,0x21,0xfb,0x17,0xe3,0x9c,0x3c,0xbf,0xfd,0x1d,0x39,0x1e,0x5b,0x2a,0xa2,0xb3,0x7d,0x4f,0xdf,0x3a,0x41,0x7a,0x31,0x01,0xc2,0xe5,0xd0,0x06,0x50,0x29,0x05,0xce,0xb8,0x28,0xb7,0xdd,0x83,0xc8,0xaa,0x39,0x78,0xc7,0x7d,0x9e,0xcd,0x9a,0x07,0x71,0x7e +.byte 0x20,0x92,0x82,0xce,0x49,0x90,0xce,0xef,0x53,0xa7,0x48,0x2a,0x69,0x86,0xa1,0x5e,0x35,0xe8,0x7d,0x10,0xb8,0x5e,0xa6,0x9a,0x69,0x6f,0x32,0x75,0xf3,0x4a,0xee,0x9c,0x06,0x5c,0xdd,0x84,0x7e,0x38,0x00,0x67,0x39,0x42,0xed,0x72,0xda,0xe3,0x6b,0x5a,0xf4,0xc9,0x80,0x3e,0x0e,0xda,0x39,0xfa,0x83,0x2c,0x60,0x69,0x87,0x85,0x05,0xfc +.byte 0xf4,0x2b,0xd4,0x0a,0xad,0x86,0xca,0xd5,0xf0,0x92,0x1f,0x43,0x3c,0x0e,0xac,0x99,0xf3,0x67,0xa3,0x41,0x6d,0xb9,0x29,0x70,0x57,0x62,0x9f,0x45,0x91,0x72,0xe5,0x53,0xcc,0x89,0x80,0x3f,0xbc,0x1c,0x66,0x21,0xdd,0x90,0x2b,0xa4,0xca,0x2f,0xf0,0x0f,0x9f,0xd0,0xe9,0x28,0xe2,0xd9,0x36,0xaf,0xf9,0x01,0x81,0xce,0xb4,0xe7,0x71,0xfd +.byte 0x92,0xf8,0x56,0x2e,0xc3,0xc8,0x8b,0x54,0xc8,0xc7,0x40,0x79,0x27,0x06,0x18,0x4a,0x7b,0x88,0x3f,0xd6,0x4f,0xd4,0x66,0x1e,0x1f,0x9a,0x14,0x1a,0x0a,0x98,0xc7,0xd6,0x25,0x83,0x37,0x8a,0x5d,0xb2,0x88,0x39,0x68,0x7b,0x1f,0x4e,0x0a,0xed,0x11,0x1a,0x77,0x9b,0xcb,0xb6,0x7d,0x5c,0x36,0xac,0x07,0x07,0x9f,0x05,0xcf,0x90,0x8f,0x3f +.byte 0x4b,0xc5,0xf9,0x42,0x90,0xb4,0x42,0x26,0xa1,0x2c,0x66,0xc6,0xb8,0x98,0x80,0x8a,0xbb,0x9b,0x41,0xe4,0x44,0x8c,0x5e,0x56,0x33,0xe3,0xba,0xcf,0x31,0x8e,0x28,0xd7,0xc5,0xd1,0x3b,0x68,0x47,0x10,0xae,0xda,0xc3,0xbd,0x20,0xe7,0xac,0xe2,0xe1,0xe0,0x7a,0x4b,0x83,0xb1,0xab,0x72,0xf4,0xc4,0xe7,0x0d,0x02,0xaf,0x5b,0x74,0xac,0xda +.byte 0x9d,0xce,0x26,0x1f,0x79,0x05,0x67,0x7e,0xc4,0x98,0x3f,0xde,0xa6,0xf3,0xfe,0x59,0x65,0x88,0xfb,0x14,0x3a,0x43,0x91,0x04,0x1a,0x78,0x7e,0x08,0xba,0x55,0x50,0xc7,0x65,0xd3,0x8e,0xda,0x0a,0xee,0x8e,0x11,0xa9,0xf6,0x9e,0xd3,0x23,0x97,0x05,0x0c,0x98,0x2a,0x36,0x25,0xec,0x5e,0x0b,0xf9,0x31,0x80,0x00,0x8a,0x70,0xf1,0xaa,0x7c +.byte 0x73,0x02,0x98,0x8d,0x42,0x27,0x53,0xf1,0x83,0x37,0xd0,0x2d,0xfa,0xc7,0x4b,0xa5,0xb3,0xc9,0xb8,0xd4,0x56,0x94,0x5a,0x17,0x2e,0x9d,0x1b,0x46,0xaa,0xb6,0xd9,0x2a,0x3a,0x6c,0xaf,0x24,0x59,0xfd,0x08,0xc5,0xca,0x0c,0x79,0x3f,0xe7,0x91,0x8d,0x9d,0x59,0x91,0xd8,0x5f,0xda,0x6d,0x35,0x7b,0x52,0x47,0x35,0xf9,0x81,0x86,0x2c,0xee +.byte 0x1a,0x14,0xc5,0x1f,0xb6,0x85,0xb5,0x74,0xe9,0xb7,0x4f,0xde,0xcd,0x93,0x2d,0xf3,0x10,0xbe,0x34,0xfa,0xca,0x15,0x9f,0x02,0x9d,0x19,0x72,0x7c,0xd6,0xfd,0x81,0x43,0x49,0xb5,0x2b,0x52,0x31,0xd6,0x2c,0x28,0x2e,0x83,0x6d,0xd3,0x0f,0x6e,0x03,0x65,0xf0,0x8a,0xdd,0x0a,0xec,0x58,0x10,0x45,0x5d,0xac,0xda,0xf5,0x32,0x5d,0x18,0x26 +.byte 0xcc,0x2e,0xcf,0xd3,0x41,0x2d,0x1d,0xba,0xdf,0xd8,0x96,0x8f,0x18,0x0f,0xa7,0xec,0x8e,0x6e,0x84,0x2c,0xd6,0x1f,0x4e,0x76,0xfe,0xf3,0x14,0x27,0x4b,0x5b,0x3d,0x7c,0x1c,0x59,0x46,0x97,0x1b,0x59,0x5a,0x2d,0x57,0x80,0x17,0x98,0x7d,0x92,0x5d,0x2f,0x98,0x53,0x10,0x59,0x8e,0x7f,0x55,0x64,0x15,0x62,0x2c,0x16,0x0b,0x8d,0x48,0x54 +.byte 0xaf,0x96,0x17,0xa9,0x8e,0x2c,0xcf,0x41,0x8c,0x8a,0x37,0x55,0xe4,0xf9,0x20,0x3b,0x21,0x5c,0x86,0x8d,0x3f,0xa6,0x5e,0x43,0xf3,0x3b,0xf7,0x7c,0x27,0x88,0x8e,0xa5,0x15,0xca,0x0e,0x9e,0x85,0x30,0x17,0x0d,0xcf,0xf0,0x82,0x87,0xd6,0xe8,0xd2,0xad,0xe9,0x4d,0x3f,0xc9,0x58,0x19,0xf9,0x99,0x4d,0xf9,0x6b,0x1b,0xd3,0xf9,0xdd,0x52 +.byte 0xd1,0x3c,0x64,0x46,0xfd,0x4f,0x2e,0x63,0x39,0xd8,0xe4,0xeb,0xfc,0x07,0xf1,0xa5,0xff,0x84,0xa8,0x92,0xfe,0xbc,0xc5,0x36,0x91,0x2b,0xec,0x2c,0xad,0xf0,0xac,0xc5,0xb0,0xad,0x8a,0x0d,0x6a,0xd9,0x29,0x7a,0xb0,0x87,0x0c,0xaf,0xda,0x75,0x84,0x25,0xbe,0xee,0x0d,0xfd,0x4c,0xf5,0x2d,0x46,0xe9,0x17,0xb9,0x9d,0x3d,0x4b,0x8f,0x3a +.byte 0xe9,0x49,0xb6,0x32,0x99,0x27,0xe2,0x4d,0xff,0x2f,0x2e,0xd5,0x69,0x52,0x56,0x20,0x0a,0xbf,0x62,0x14,0x34,0xfb,0xbf,0x95,0xe8,0xfe,0xb1,0x9f,0x43,0x30,0x02,0x03,0x9e,0xa8,0xe2,0x68,0x64,0xdd,0x37,0xfc,0xb9,0x0f,0x85,0x8c,0x36,0x45,0xdb,0x7c,0x8b,0x97,0x50,0xc3,0x75,0xa1,0xcf,0xf4,0xc2,0x46,0xd8,0xa1,0x8c,0xab,0x8d,0x3a +.byte 0xde,0xe7,0x9e,0xd2,0x1e,0x2d,0x8b,0xe4,0x31,0xe3,0x12,0x3f,0x9f,0x0b,0x2c,0x95,0x75,0x8d,0xf1,0x24,0xb9,0xdf,0x1e,0x64,0x35,0x45,0x2a,0xc2,0xf9,0x96,0x5d,0x10,0x64,0x32,0xae,0xe9,0xf8,0x71,0xd4,0x2d,0x6b,0xc6,0xde,0x08,0x1e,0x5d,0x51,0xf1,0xe7,0xfd,0x3c,0x22,0x43,0x59,0x82,0x83,0x13,0x75,0x36,0xef,0x81,0xe4,0xcf,0xa8 +.byte 0xb8,0x30,0x16,0x44,0xae,0x55,0x06,0xdd,0xb9,0x60,0x3f,0x75,0xc6,0xd1,0x73,0xa9,0xea,0xc9,0x64,0x2b,0x8a,0xde,0x44,0x4b,0x3d,0xc3,0x31,0x12,0x84,0x9a,0xe3,0xda,0x24,0x82,0x99,0x00,0x6d,0x8e,0xb8,0x26,0x82,0xa6,0xc2,0x37,0x6c,0x2a,0x1d,0xcf,0x6d,0x18,0xc7,0xee,0x27,0xca,0xe7,0xad,0x95,0xed,0x7d,0xe0,0xe0,0x6f,0x45,0xc3 +.byte 0x8a,0x2f,0x08,0x49,0x7e,0x09,0x9e,0xc1,0xb7,0x1e,0x8f,0x57,0x61,0xf8,0x3e,0xea,0xd7,0x47,0xfb,0xd0,0xda,0xaa,0x04,0xf9,0x06,0xbb,0xa3,0x80,0x68,0x89,0xb0,0x7f,0x18,0xf3,0xd2,0xeb,0xee,0x48,0x30,0x6a,0x24,0xc8,0x71,0x43,0xc3,0x50,0xcc,0x85,0x68,0xf5,0xca,0x44,0x34,0x43,0xaa,0x2e,0x4f,0x02,0x1b,0x23,0x4f,0xe9,0x07,0x02 +.byte 0xa2,0xfa,0x24,0x57,0x70,0x4e,0x1a,0x78,0x03,0xa2,0xdd,0x53,0x50,0x82,0x05,0xb1,0x0f,0xcb,0x9e,0x2e,0x58,0x04,0x62,0xc8,0xac,0x71,0x31,0x56,0x0f,0xc7,0x70,0x32,0x53,0xda,0x51,0xc3,0x15,0x78,0x82,0xb6,0xe8,0x6e,0x32,0xeb,0x39,0xab,0xba,0x67,0xcc,0xbc,0x99,0x58,0x88,0xc4,0x60,0x0d,0x0b,0xc1,0xfa,0x6f,0x40,0x85,0x04,0xdf +.byte 0x5f,0x17,0x69,0xf1,0xbd,0x44,0x97,0xc8,0x62,0x19,0x49,0x1f,0x23,0xcb,0x3d,0x17,0x04,0xf2,0xbd,0x58,0x15,0xa6,0x37,0x3a,0x3f,0x77,0x98,0x32,0x40,0x8a,0x72,0xf0,0x41,0x0b,0xad,0x88,0xba,0xd3,0xae,0xdc,0x3b,0x9a,0x37,0x89,0xa5,0x09,0xe5,0xbb,0xf2,0xf8,0x5d,0xa5,0xed,0xe8,0x39,0x7b,0xed,0x2b,0x90,0xd6,0x6c,0xd3,0xfa,0x69 +.byte 0xa7,0xca,0x09,0x83,0x15,0x8d,0xd8,0xe3,0x81,0x03,0x4e,0x2d,0xd8,0x96,0x3b,0x4b,0x18,0x91,0xac,0x5f,0x22,0xe6,0x9d,0x4b,0x09,0xaf,0xf0,0xdf,0x16,0xa2,0xf1,0x2c,0xd9,0x35,0x8a,0x6e,0x85,0x7a,0xbc,0xc7,0x10,0xd1,0x5f,0x8a,0x53,0x9c,0x8e,0xbc,0x8c,0x15,0xb3,0x8a,0xb0,0x0b,0x74,0x40,0x2a,0x5f,0x46,0x71,0x1c,0x0b,0xee,0x08 +.byte 0xae,0x17,0x26,0x1e,0xcf,0xbf,0x3d,0xa0,0x5e,0x3a,0xdb,0x39,0x6b,0x4a,0x82,0x53,0x02,0xf4,0xa2,0x15,0x5c,0xb6,0xdb,0x20,0x30,0xa2,0x7d,0xcb,0x9a,0xf7,0x88,0x69,0xb5,0xc8,0xe6,0xcd,0x9e,0xa4,0xaf,0x27,0x0e,0x61,0x41,0xcd,0x8e,0x71,0x83,0x11,0xce,0x5e,0x6c,0xaf,0xa4,0x50,0x81,0xb6,0xf2,0x36,0x05,0xbb,0x36,0x4e,0x4a,0x1b +.byte 0x09,0x9f,0xca,0x1b,0x12,0xb0,0x01,0xc0,0xbf,0x7e,0x3f,0x81,0x60,0x9f,0xfd,0x56,0x81,0x54,0x99,0x2b,0x7f,0x1e,0xb1,0xbf,0xd4,0xb7,0xe1,0x7c,0x71,0xf9,0x00,0x72,0x5f,0x10,0xab,0x60,0x03,0x9d,0x13,0xf1,0xba,0x48,0x93,0x1c,0x1d,0x11,0x04,0x40,0xf6,0xde,0x3b,0xef,0x6c,0x47,0xb3,0x0d,0xcf,0x53,0xbd,0x45,0x7e,0xd7,0x8c,0x34 +.byte 0xd0,0xcb,0x85,0x4b,0x1e,0xd1,0xc5,0xfd,0x5b,0x1a,0x18,0x8a,0x27,0xe3,0x16,0x3c,0x25,0x12,0xf2,0xf1,0xa1,0x40,0x53,0x68,0x27,0x2c,0x81,0x0e,0x20,0x12,0xe3,0xde,0xe2,0x9f,0x08,0x75,0xc0,0x25,0x79,0xf0,0xc4,0xaa,0x10,0xad,0x41,0x3f,0x0b,0xc7,0xb2,0xe0,0x50,0xde,0xec,0x24,0x09,0xeb,0xb5,0xd3,0xbc,0xd3,0xdf,0x44,0x6d,0xc8 +.byte 0xf1,0x79,0xf8,0x33,0xb7,0x75,0x09,0x18,0x04,0x59,0x0f,0x15,0x5e,0xf9,0xca,0xe0,0xa9,0x2a,0xe1,0x1b,0xf0,0x49,0x5f,0xca,0xa3,0x80,0xd5,0x9b,0x1e,0xc1,0x1f,0x98,0x18,0x0a,0x24,0xc3,0x3f,0xfb,0x43,0xfd,0xa3,0x01,0x59,0x50,0xea,0x21,0xe0,0x92,0xfd,0xe1,0xd5,0xe4,0x38,0x24,0x88,0xf3,0xb0,0xc9,0x79,0xfd,0x4e,0xd3,0x3e,0xbf +.byte 0xc6,0xb8,0x9e,0x7f,0xab,0x65,0x79,0xd9,0xb9,0x83,0x38,0xe1,0xf7,0xd0,0x37,0x04,0xb3,0x0c,0x48,0x82,0x74,0xe1,0x0c,0x80,0x13,0x59,0xc4,0x72,0xf9,0x2d,0x88,0x06,0x46,0x08,0x7a,0x6b,0xb4,0xfc,0x5f,0x63,0x31,0x2f,0x4f,0xfd,0x4b,0x1f,0x8e,0x21,0x3c,0x67,0x83,0xdd,0xa9,0x65,0x68,0xc6,0xd0,0xb8,0x1d,0xcd,0x60,0xc5,0xb9,0x3b +.byte 0xea,0xe9,0xc7,0xa5,0x1a,0x98,0x8a,0x87,0xb7,0x73,0x29,0x3a,0x6a,0x3a,0x75,0xbf,0xa4,0x79,0x64,0xcb,0x94,0x68,0x93,0x56,0x55,0x1e,0xd5,0x61,0xda,0x87,0xe1,0x28,0xf0,0xa5,0x64,0x9a,0xd7,0xa0,0x91,0xfd,0x46,0x20,0x6c,0x87,0x1f,0xe8,0x9e,0x7e,0x95,0xc4,0x60,0xdb,0xf4,0xe2,0x3e,0xb2,0x6a,0x4a,0xe7,0x46,0x3f,0xca,0xf3,0x72 +.byte 0xb5,0xe8,0x06,0x3a,0x1b,0xeb,0xcb,0x81,0x46,0x44,0xf6,0x97,0xa0,0x79,0xe4,0xa4,0x8a,0xba,0x5e,0x1b,0x6d,0xf4,0xcf,0x7c,0x12,0x7a,0xec,0xdd,0xf6,0xc8,0xab,0x5f,0x30,0xb3,0xf9,0x8e,0x31,0xfd,0x51,0x95,0x8b,0xa1,0xe9,0xe8,0x2d,0xec,0x86,0x12,0x4a,0xf8,0x8b,0xa5,0xdd,0xb2,0xe4,0xad,0xdd,0xcb,0xf5,0xcd,0x9c,0x9f,0x0a,0x42 +.byte 0x5f,0x83,0x9d,0xa6,0x4f,0xbe,0x11,0x75,0x3c,0xde,0x67,0x6b,0x95,0xcd,0xcf,0xdc,0xfd,0x1f,0x1a,0x14,0x01,0x27,0x68,0xaf,0x9b,0x82,0xd6,0xae,0x29,0x8a,0x1f,0xc8,0xf1,0x1f,0xb8,0xa9,0xa2,0x1d,0x81,0xbb,0x19,0xda,0x06,0xe3,0x34,0x7b,0xce,0x99,0x3c,0x5b,0x0c,0x9b,0x8b,0x35,0xc0,0x6c,0x88,0xef,0xeb,0x9f,0x64,0xe3,0xc3,0xbf +.byte 0x37,0xd7,0xf6,0xdf,0xad,0x28,0xf4,0xd7,0x19,0xb0,0xf2,0xa7,0xd4,0x71,0xbc,0xd3,0xa3,0x09,0x5c,0x1a,0x45,0x30,0x2d,0x53,0xa5,0x19,0x2f,0xb0,0x5d,0xae,0x04,0x28,0xe6,0x16,0x3e,0x75,0x9f,0xcc,0x76,0xc4,0xc2,0xa0,0xfb,0xff,0xdd,0x4c,0xa3,0x8b,0xad,0x05,0x73,0x26,0xf0,0xef,0x48,0xd5,0x25,0x22,0x90,0x78,0x21,0xfd,0xc6,0x23 +.byte 0x14,0xbc,0xed,0x13,0x29,0x76,0x17,0xa6,0x93,0x09,0x6e,0xa7,0x42,0xdd,0x11,0x9e,0x05,0xa3,0xb7,0x48,0x84,0x85,0xf8,0x4e,0xed,0x3d,0xdb,0xfc,0x68,0xd2,0xec,0xec,0x69,0x2b,0x60,0x38,0xd1,0x99,0x44,0xf9,0x60,0xd3,0x5a,0x9e,0xe4,0x26,0x9d,0x12,0xf8,0x6a,0x53,0xde,0x76,0x78,0xa7,0x68,0xb0,0xb4,0xdc,0x33,0x7b,0x8a,0x73,0xa0 +.byte 0xa5,0x5f,0x8f,0x81,0x0e,0x51,0x06,0x13,0x6b,0x56,0x16,0x91,0x1f,0xf5,0x6b,0x68,0xe6,0x8b,0x69,0xda,0x0a,0x9c,0xb1,0x74,0x8f,0x1c,0xb3,0xbf,0x52,0x59,0xaa,0xb1,0xb6,0x3a,0x81,0xc2,0x04,0x54,0x12,0x46,0xa2,0xd5,0x21,0xdf,0xe0,0x57,0x1f,0xe8,0x36,0x56,0x87,0xbf,0xcb,0x7d,0x06,0x6c,0xd5,0xc9,0x4e,0xca,0x47,0x47,0x11,0x91 +.byte 0x7a,0x14,0x13,0x5d,0x5d,0x46,0xd5,0x3a,0xe4,0xa4,0x4d,0x99,0x3a,0x54,0x99,0x62,0xb4,0x70,0xa0,0xf5,0x8a,0xda,0x05,0x75,0xf1,0xa5,0xa1,0x5d,0x9d,0xc4,0x7f,0x83,0x8a,0x5b,0x09,0x54,0x0e,0x69,0x28,0xef,0x66,0xfb,0xe4,0xc4,0xe4,0xc4,0xda,0xb0,0xda,0xe2,0x19,0x33,0x3c,0x76,0xa0,0x35,0xdc,0x31,0x4e,0x40,0xfe,0xb8,0x20,0x26 +.byte 0x8f,0x6f,0x7d,0x02,0x54,0x86,0x1d,0xca,0xa6,0x10,0xa6,0x89,0x87,0x3a,0x5a,0xd5,0x3d,0x0f,0xb5,0x81,0x7d,0xab,0xb6,0xc6,0x36,0x87,0xce,0xd7,0xe4,0xc3,0x9e,0xc2,0x9c,0xf6,0x75,0xd5,0x9a,0x69,0xd2,0x13,0x89,0x5a,0xe9,0x29,0xc9,0xf5,0x6e,0xcc,0x05,0x87,0x0a,0x61,0x49,0xd7,0xa5,0x76,0xd0,0xaf,0x96,0xe0,0x2f,0x91,0xf4,0x45 +.byte 0x70,0x5a,0xdc,0x9f,0x07,0x7f,0x86,0x02,0xa4,0x83,0x8d,0x4a,0x6d,0xfc,0x1b,0xd8,0x9b,0xc2,0x42,0x4f,0xcb,0xdf,0xcb,0xe0,0x55,0xb4,0x8f,0xf7,0x27,0x73,0xd9,0x7e,0xf8,0x3a,0x5c,0x4f,0x29,0x64,0xd8,0x39,0xfa,0xf2,0xc4,0x6b,0xeb,0x55,0xc3,0x13,0x22,0x15,0xdf,0xc5,0x91,0x6d,0xd7,0xf3,0x11,0x34,0x08,0xce,0xe5,0xbd,0x16,0x14 +.byte 0x60,0x14,0x8a,0xed,0x4d,0x38,0x98,0x15,0x5d,0xee,0x70,0xff,0x05,0xd2,0x74,0x3a,0x5f,0x78,0x1a,0x70,0x61,0x2a,0x42,0x4a,0xf3,0x15,0x6f,0x9e,0x33,0xca,0xb8,0x46,0x22,0x64,0xd6,0x24,0xe8,0x10,0x1a,0x89,0xab,0x74,0xdf,0x56,0x35,0x41,0x57,0xe1,0xd9,0x4b,0x67,0x60,0x89,0x6f,0xbf,0x73,0xac,0x6b,0xf9,0x78,0x3f,0xbc,0xf3,0x2a +.byte 0xb5,0x8c,0x1f,0xda,0xe7,0xe2,0xac,0x60,0xbf,0x41,0x96,0xbb,0xd5,0x35,0x9c,0x56,0xe7,0xfd,0x95,0xc7,0x4d,0x32,0xa1,0x07,0x34,0xbc,0x99,0xca,0xcc,0x42,0x71,0xfb,0xec,0x5c,0x1e,0xf9,0x8b,0xde,0x43,0x65,0x84,0x16,0x52,0x0a,0x5e,0x92,0x20,0xd8,0x26,0x4b,0x97,0x71,0xde,0xd2,0x1f,0x2e,0xd1,0xb2,0xb6,0x29,0x6a,0x6d,0x41,0x00 +.byte 0x20,0x3d,0x03,0xf8,0x43,0x7b,0x57,0x87,0x4e,0xf1,0x8e,0x6f,0xd3,0xf4,0x6c,0x6c,0x29,0xf6,0x99,0xe3,0xd3,0x1d,0xd3,0x26,0x21,0x3b,0x02,0xa2,0xc1,0x06,0xcf,0x31,0xec,0x7f,0xc6,0x80,0xbc,0xab,0x86,0x01,0xff,0x11,0x8a,0x24,0xfd,0x1b,0x41,0x49,0xd4,0xbe,0x15,0x34,0x82,0xc5,0x02,0x51,0x67,0x5c,0x41,0x8e,0xbf,0x94,0x12,0x15 +.byte 0x64,0xea,0x00,0x0c,0x51,0x40,0x57,0x66,0x1e,0x6d,0x3e,0x41,0x8e,0x84,0xdf,0x71,0xb8,0xd7,0xfa,0x12,0x17,0x22,0x17,0x05,0xdc,0x82,0xfd,0x7c,0x5e,0xfa,0x62,0x23,0xa8,0xbe,0x14,0xdc,0x84,0x42,0xf0,0x90,0xc5,0xb0,0x68,0xbe,0x64,0x74,0xc3,0xa5,0xd1,0x10,0xcf,0xe3,0xd1,0x09,0x98,0x3b,0xb9,0x19,0xf2,0x9b,0x5d,0x90,0x99,0x3d +.byte 0x30,0x67,0x55,0x34,0x50,0x78,0x3b,0xd2,0x70,0xb1,0xd2,0x91,0x4e,0xfa,0x98,0x7d,0x93,0xad,0x7f,0xb1,0x89,0xb0,0x61,0x4c,0x95,0x3f,0x51,0x95,0xd7,0xc6,0x87,0x7a,0xc5,0x53,0xb6,0x6d,0x61,0xec,0xbe,0x40,0x1f,0xa5,0x7f,0x73,0x4a,0x78,0xd2,0x58,0x1e,0x41,0x8e,0x9a,0x08,0x49,0xce,0x39,0x52,0xf9,0xd1,0xcd,0x41,0xb6,0x39,0x99 +.byte 0xfa,0xfb,0x1c,0x38,0xe1,0xe5,0xe1,0xd6,0x16,0x0f,0xc8,0x12,0x0b,0x88,0xdc,0x00,0xd4,0x7b,0x24,0x69,0x16,0x27,0x37,0xa3,0xd5,0x39,0x27,0x34,0xda,0x23,0x24,0x50,0x13,0xd8,0x02,0x48,0x14,0xd7,0xc9,0x28,0x1b,0xba,0x66,0xa8,0xc8,0x9a,0x7b,0xed,0x92,0x5b,0x78,0x46,0x79,0x5a,0xd1,0xf2,0x75,0xf0,0x98,0xd3,0x9f,0x4c,0x72,0x51 +.byte 0xed,0xe5,0xce,0x83,0xac,0xe1,0xc8,0x2b,0x7f,0x77,0x6a,0x70,0xdd,0x80,0x88,0x62,0x58,0x94,0x15,0x72,0x53,0x34,0x48,0x17,0xb2,0xe8,0x4a,0xab,0x2d,0x4e,0xef,0x93,0xb7,0xba,0xd1,0x1c,0x53,0x69,0xd5,0xac,0xa1,0x61,0x7c,0x44,0xec,0x81,0x72,0xcc,0xe8,0x6f,0x5d,0x67,0x1f,0x65,0x9a,0x34,0xf5,0x95,0x89,0x1c,0x2e,0x54,0x42,0xc0 +.byte 0x85,0x79,0xb0,0xfa,0x44,0x0d,0x28,0xc4,0x20,0x2f,0x2e,0x85,0x73,0xfb,0xf6,0x44,0x0e,0xbc,0xab,0x4f,0x42,0x5c,0xdb,0x1f,0x11,0x6f,0x9a,0x23,0x75,0x70,0x78,0x1a,0xd2,0xb8,0x83,0x72,0xf5,0xf6,0x40,0x48,0x3f,0xc8,0xd5,0xe3,0x2c,0x08,0x5c,0x0c,0x2a,0xb0,0x8e,0x69,0xe6,0xdf,0x4b,0x4a,0x95,0x9c,0x4c,0x5e,0x09,0x24,0xc3,0xd0 +.byte 0x4c,0x20,0x0c,0x9a,0xce,0x95,0x53,0x6a,0x7b,0x54,0x0a,0x7e,0x73,0xa7,0x95,0xe7,0x7c,0x67,0x9d,0x05,0xbc,0x26,0x3a,0xa1,0x43,0x99,0x7a,0xee,0x04,0xcf,0x94,0x02,0x36,0x26,0xb3,0x81,0x74,0x22,0xee,0x1e,0x9e,0xe2,0x82,0xd4,0xe0,0xca,0xf2,0xec,0xd2,0x9e,0xf8,0x3f,0x9f,0xc4,0x5b,0xe8,0xfc,0xbd,0x93,0xaa,0xc3,0x2f,0xce,0xf2 +.byte 0x32,0xa9,0x23,0xf3,0xe1,0x06,0xae,0x7d,0x87,0xe9,0xe7,0xe0,0xc1,0x7c,0x74,0x9c,0xdf,0x86,0x6d,0x5c,0x8a,0x51,0x45,0x9d,0x43,0x49,0x87,0x45,0x75,0xfb,0x40,0x55,0xab,0x9a,0x52,0xf1,0x32,0x5e,0xde,0x8b,0x52,0x50,0x9f,0xb8,0x7a,0xe5,0x1c,0x40,0x4f,0xc7,0xb1,0x29,0x90,0xcc,0x98,0x99,0xa0,0x4e,0x1c,0x43,0x6e,0x91,0x61,0x9c +.byte 0xf7,0xa7,0xf7,0x43,0x89,0x15,0x8c,0x56,0x22,0x9d,0x66,0xac,0x71,0x19,0xdc,0xb9,0xf8,0xd3,0xaf,0x2e,0xd7,0x7b,0xc3,0xe4,0x25,0x0d,0x2c,0xaf,0x15,0x8c,0xea,0x2b,0xdb,0x8c,0x71,0xff,0x55,0x29,0x11,0x35,0x11,0xef,0xb0,0x97,0xb2,0x95,0xab,0xeb,0x4a,0x40,0x1c,0x92,0xc4,0x13,0x36,0x74,0x53,0x78,0x51,0x6c,0xca,0x37,0xcb,0xda +.byte 0x5e,0x6b,0x8c,0x69,0xc5,0xd0,0xf9,0xdb,0xbe,0xd9,0x30,0x42,0x16,0xcf,0x40,0x63,0x87,0x10,0x28,0x7d,0xae,0xa9,0x8c,0x14,0x99,0xe1,0x4f,0x11,0x98,0x7e,0xe9,0x14,0x9c,0x2e,0xe2,0xed,0x20,0x15,0x7c,0xb5,0xf4,0xc9,0x16,0x30,0x8d,0x7c,0x61,0x45,0xf4,0x23,0xf5,0xdb,0x81,0x8f,0x6b,0x41,0xaf,0xa9,0xf8,0x51,0xbe,0xc4,0x5d,0x8c +.byte 0xda,0x5e,0x07,0x62,0x7c,0xc6,0xd1,0xae,0x91,0x5e,0x05,0xa8,0xc6,0xc5,0xfc,0xb7,0x12,0x2e,0x7f,0x85,0xef,0xbd,0x2b,0x56,0x57,0x32,0xad,0x3d,0x97,0x5b,0x26,0xcf,0xd3,0xe7,0x48,0x4e,0x9b,0x15,0x98,0x77,0xb4,0x3e,0xf1,0x3e,0x1c,0x21,0xb0,0x98,0xe2,0x69,0xee,0xd8,0x29,0x10,0x93,0xd5,0xc9,0x71,0x8f,0x28,0xbd,0xe3,0xd9,0x54 +.byte 0xf3,0x72,0xb6,0x85,0xe9,0x2b,0xdc,0x96,0x52,0x53,0x5c,0x61,0x54,0x96,0x4a,0xf5,0x3f,0xee,0x53,0xc3,0x63,0xc9,0x67,0x14,0xdf,0x3a,0xfe,0x46,0x8a,0xa6,0xec,0x06,0x0c,0xea,0xb8,0x82,0x49,0xb5,0xed,0x94,0xf2,0xac,0x76,0xd5,0x87,0x79,0x15,0x4f,0xa1,0x34,0x90,0x8e,0x7b,0x02,0xf7,0x02,0xb0,0x07,0xa5,0x7c,0x6b,0xc2,0x34,0x84 +.byte 0xd4,0xaa,0xbf,0x32,0x81,0xf7,0xed,0x1f,0x61,0xd7,0x6e,0x40,0xa0,0xdc,0x4c,0xb5,0xb7,0x36,0x3a,0x87,0x09,0x82,0xd5,0x5a,0xc8,0x1f,0xe6,0x77,0xa6,0xaa,0xcf,0x3c,0x7b,0x23,0x46,0x58,0x95,0x7f,0x84,0xba,0x4a,0x05,0x0b,0x36,0xdb,0x58,0xf9,0xa4,0x2b,0x24,0xd4,0x8a,0xbc,0xb2,0xb7,0x04,0xac,0x64,0x0e,0x88,0x25,0x9a,0x69,0xe7 +.byte 0x87,0x70,0x0b,0xa6,0x43,0xe9,0xb2,0xbb,0x4e,0x4c,0x10,0x19,0x44,0x4d,0x12,0x4c,0x58,0x2a,0x49,0xe2,0x01,0xd2,0x65,0x23,0xee,0xe9,0xca,0x0b,0xa1,0x28,0x02,0x8d,0xcf,0x37,0x06,0xbc,0x5d,0x35,0xba,0xec,0x97,0x95,0xcc,0xfe,0x7b,0xc9,0x1c,0x0d,0x89,0x4e,0xe1,0x8d,0x9b,0x5e,0x5b,0xb9,0x6c,0x24,0x73,0x9a,0x62,0xd7,0xc5,0xfa +.byte 0x54,0xeb,0x05,0x22,0xd9,0xe7,0xc4,0x68,0x88,0x20,0x43,0xd9,0x14,0x47,0xd7,0xa5,0xd0,0xce,0x10,0x77,0xe8,0x5c,0x85,0x39,0x99,0x3f,0x72,0x88,0x4f,0x22,0x15,0x87,0xa0,0xa3,0x47,0x10,0x81,0x64,0xff,0x94,0x77,0x5d,0xce,0x6d,0xd8,0x29,0xb1,0x9c,0x8e,0xce,0xa8,0x39,0x4f,0xfc,0x36,0x3c,0x50,0xb2,0xf1,0x08,0x66,0x1a,0xf0,0x22 +.byte 0x65,0x1f,0x4d,0x17,0xd3,0x63,0x10,0x64,0xd1,0xc6,0x5a,0x3e,0x82,0x72,0x0c,0x48,0x5e,0x07,0x9c,0x07,0xa0,0x40,0x60,0xab,0x74,0x9a,0x00,0xdf,0xd7,0x7d,0xd4,0x11,0x4e,0xce,0x5a,0xaf,0x12,0x4f,0xe7,0x12,0x36,0x1a,0x12,0x11,0x16,0xb7,0xad,0x4b,0x28,0x84,0x7b,0xd8,0x30,0x0d,0x85,0xb8,0x76,0xde,0xa3,0x78,0x8c,0xb7,0x7c,0xbc +.byte 0x97,0x33,0x53,0x95,0xf8,0x14,0x5f,0xf8,0x0d,0xc1,0x6b,0x79,0xa2,0x42,0x49,0xab,0xae,0x8e,0x78,0xf3,0x51,0x01,0xcc,0x20,0x36,0x80,0xbd,0x32,0x0b,0x1b,0xd2,0xcd,0x27,0x52,0x69,0x1b,0x4a,0x37,0xba,0x31,0xe4,0xc2,0x03,0x8d,0x00,0x48,0x4b,0xcd,0x39,0x2e,0xec,0x94,0x2e,0xe0,0x81,0xfd,0x94,0xd9,0x86,0x39,0x23,0x87,0x3c,0x2f +.byte 0x25,0xe1,0x5b,0x22,0xe0,0x2e,0x37,0x6d,0x9b,0x97,0x9c,0x94,0x37,0x01,0x26,0xb8,0xb1,0x73,0x7c,0xfc,0x0a,0x64,0xe7,0x54,0xf1,0x0f,0x71,0xa1,0xd6,0xc7,0xc8,0xb4,0x86,0x2d,0xfe,0x30,0x8b,0xca,0xb2,0x18,0x21,0xc0,0xc7,0x7d,0x60,0xcf,0x2e,0x25,0xb0,0xa4,0x1a,0x28,0x19,0xa9,0xa9,0x15,0x32,0x5e,0x21,0x89,0x3a,0x99,0x5f,0x50 +.byte 0x86,0x37,0x3b,0x10,0xb8,0xa5,0xad,0x8e,0xbf,0xfc,0x8c,0x85,0xf1,0x76,0x5c,0xe7,0x4d,0xac,0xe7,0x21,0xb3,0x45,0x87,0x3b,0x05,0xc8,0x41,0xf4,0x99,0x83,0x28,0x40,0x6b,0x30,0x37,0x31,0xd2,0xb3,0xdd,0x43,0x3b,0x3f,0xec,0x50,0x58,0x7d,0x20,0xc6,0xb2,0xa9,0x3c,0x22,0x38,0xea,0x16,0x32,0x01,0xc4,0xb0,0x9f,0x7d,0x12,0x91,0x82 +.byte 0x0c,0xd8,0x36,0xfc,0xa4,0xec,0x06,0xb2,0xc2,0xce,0x9b,0xa4,0x53,0x71,0x77,0xdd,0xc3,0xfc,0x34,0x6f,0xd9,0x5c,0xfc,0x36,0xdd,0x63,0x19,0x06,0xfb,0x3c,0xf3,0x3f,0x82,0x28,0x6d,0x00,0xf9,0xfd,0x8d,0x6b,0x79,0x06,0x8a,0xe7,0x6f,0xcc,0x39,0x12,0x80,0x71,0xcb,0x71,0xb3,0xb6,0xa4,0xa8,0xbe,0x61,0x9d,0x1f,0x48,0xa2,0x15,0xa1 +.byte 0xb5,0xf5,0x16,0x70,0xc5,0x39,0xce,0x43,0xa3,0x09,0xe5,0xf4,0x8b,0x77,0x18,0x5e,0xa0,0x77,0xa3,0xa4,0x17,0x2c,0x3e,0x50,0x73,0x2f,0xaa,0x5d,0x58,0x5e,0xdc,0xec,0xaf,0xca,0x6e,0x57,0x80,0xa3,0xd5,0x94,0x30,0x7c,0x11,0x75,0xc4,0xbb,0x9d,0x18,0xc1,0x5a,0x58,0xc7,0x04,0x56,0xb1,0x3a,0x21,0x55,0x02,0xea,0xad,0x58,0x19,0x72 +.byte 0xdc,0x7d,0x0e,0x41,0x62,0x1b,0x5c,0x48,0x97,0x3f,0xed,0xd7,0x4e,0x30,0x1f,0xf5,0xde,0xc5,0x23,0xf2,0xd7,0x22,0xde,0x2f,0x3e,0x80,0x06,0x81,0xf6,0x24,0xb7,0x91,0x09,0x56,0x91,0x00,0x1a,0xea,0xaa,0xa6,0xc2,0x8b,0xc9,0x78,0xd7,0xde,0xf6,0x87,0xb1,0x04,0xcc,0xbb,0xc1,0xc6,0x48,0x43,0xc8,0x03,0xb2,0xdd,0x70,0xc0,0xe3,0xf5 +.byte 0xc0,0xf5,0x13,0xd5,0x11,0x41,0x7f,0x1a,0xdc,0x48,0xf5,0xd6,0x1b,0x0a,0x84,0xd2,0x84,0xcd,0x10,0x4f,0x0a,0xd7,0xcb,0x41,0x61,0x1c,0xcc,0x5c,0xa9,0xbd,0x6e,0x6a,0xf3,0x81,0xd8,0xaa,0x3a,0xff,0x39,0x90,0x8e,0x33,0xe6,0x58,0x13,0x5f,0xec,0x58,0x74,0x35,0xe0,0x06,0x38,0x0f,0xd0,0xbf,0x8d,0xf7,0x26,0x99,0xea,0xdd,0xfb,0xdf +.byte 0x5b,0xcc,0xf1,0x3d,0x9b,0x84,0x8b,0x5b,0xe8,0xc4,0xc6,0x3e,0x0a,0x55,0xec,0x73,0xf7,0x70,0xb1,0xc8,0xfa,0xf8,0xd6,0x72,0x2c,0x6d,0x8d,0xc1,0xa3,0xb2,0x9a,0xe7,0x80,0x6d,0x09,0xa6,0x76,0x06,0x71,0xf9,0x95,0x9a,0xa9,0x2f,0x4b,0x7c,0xad,0x64,0x01,0x01,0x91,0xe4,0x87,0x1d,0xe1,0x46,0xf5,0x4a,0x96,0xc6,0x58,0xd9,0xe0,0xa9 +.byte 0x2f,0x80,0x1e,0xd6,0xe9,0xa6,0xeb,0xfe,0x5a,0xb6,0xd3,0xe8,0x76,0xd2,0x51,0xc6,0x68,0x34,0xc9,0xed,0x76,0x29,0x7e,0x63,0xb1,0x09,0xdf,0x23,0x47,0x41,0x2f,0x70,0x46,0x4d,0xbb,0x36,0xc8,0x84,0xe9,0x58,0x20,0x6b,0x04,0xb2,0xa4,0x1c,0x4d,0xe0,0xa5,0xa2,0x59,0xc9,0xed,0x63,0x25,0x5f,0x3f,0x24,0x18,0x59,0x29,0xe3,0x79,0xbd +.byte 0x35,0x50,0xee,0x81,0x59,0xff,0xd4,0x0e,0x62,0xd3,0x52,0x30,0x81,0xa2,0xe6,0x9e,0xc3,0xc9,0x7a,0x10,0x57,0x36,0x27,0xb7,0x3c,0x61,0x38,0x89,0x70,0xa0,0xc5,0xdf,0x78,0x05,0xa5,0x81,0xe2,0x8a,0x93,0xda,0x7c,0xaf,0xbf,0x6d,0x42,0x09,0x1b,0x43,0x9d,0xf9,0x26,0x87,0xc3,0x84,0x6c,0xb7,0x25,0x31,0x50,0x00,0xd8,0x13,0xc0,0xc0 +.byte 0x6c,0x21,0x82,0x6d,0xf9,0x2f,0xef,0x40,0xe8,0xf8,0xae,0x4d,0x9e,0x1d,0x4a,0xda,0xa0,0x0d,0x77,0x36,0x8b,0xed,0xaf,0x6e,0x2a,0x3d,0xa8,0x36,0xe4,0xff,0x37,0xc2,0xa3,0x11,0x5e,0x68,0x58,0xa8,0xa3,0x19,0xf3,0xc1,0x33,0xea,0x39,0x49,0xfe,0x51,0x87,0xb6,0x31,0x6a,0x61,0x47,0xe7,0xb1,0x46,0xde,0x5a,0xf7,0x93,0x06,0xa7,0x72 +.byte 0xa9,0x2e,0x9e,0x2e,0xc9,0x7f,0xe1,0xb2,0x86,0xb4,0xc9,0xff,0x3b,0xf7,0xaf,0xef,0x91,0x47,0xc2,0xfa,0x42,0x0a,0x4e,0xbb,0x10,0x0d,0xea,0xa4,0x11,0x54,0xa9,0x53,0xde,0xc4,0x01,0xde,0xc7,0x2d,0x1f,0x18,0x40,0x79,0xd1,0x44,0x7d,0x51,0x1d,0xf6,0xdc,0x6f,0xad,0xa2,0x5d,0xd9,0xbe,0x5d,0x11,0x57,0xb7,0x68,0x0d,0x96,0xad,0xb3 +.byte 0x32,0xf7,0x99,0xcc,0x0e,0x03,0xa2,0x79,0x9b,0x63,0xce,0xee,0xf9,0x0c,0xfd,0xfa,0x9a,0x82,0xc9,0x43,0xd3,0xd5,0x23,0xfa,0xac,0x75,0xbe,0x61,0x85,0x18,0xb6,0x75,0x72,0x8d,0x17,0xdd,0xde,0x3f,0x6d,0xb4,0xe8,0x47,0x09,0xe1,0xa7,0xe0,0x4c,0xce,0x93,0x7b,0xc3,0xa3,0x3f,0xc0,0x81,0x21,0x6f,0xe8,0xce,0x68,0x61,0xde,0x1a,0x58 +.byte 0x48,0x7f,0xb4,0xae,0xfd,0x7c,0x80,0x63,0x43,0x5a,0xfc,0xf9,0xf9,0x4d,0xb4,0x8c,0x85,0x27,0x12,0x4f,0x7d,0xe8,0x69,0xc3,0x7d,0x57,0x63,0x0d,0x5f,0xd2,0x85,0x4e,0x0c,0x9a,0x0d,0x1c,0x4d,0xdf,0x3f,0x9a,0x16,0x2f,0x34,0x43,0xc3,0xf0,0xf1,0x16,0x16,0xd2,0x9f,0x2e,0x78,0xd8,0x3c,0x63,0xa0,0x7e,0x02,0x8e,0x65,0xd2,0xb0,0x61 +.byte 0xb0,0x1d,0x7a,0x8f,0xf7,0x30,0x45,0x05,0xf7,0x15,0xc3,0x69,0x24,0x98,0xc3,0x74,0x20,0x16,0x09,0x57,0x39,0x16,0x68,0x23,0x33,0x62,0x4c,0xf5,0xd6,0x34,0xe3,0xad,0x7a,0x14,0x64,0x8c,0x2b,0x48,0x96,0xf9,0x85,0x39,0x19,0x73,0x27,0x04,0xa6,0x55,0x66,0x15,0x8c,0xf1,0x47,0xcd,0x53,0xaf,0x31,0x3a,0xd9,0xfa,0xf9,0xac,0xbd,0xb8 +.byte 0x27,0xe0,0xaa,0xa5,0x62,0x85,0x9f,0xbb,0x4e,0xaf,0xa5,0x72,0x42,0x98,0xa6,0x7f,0xa1,0xb6,0xac,0x17,0xc2,0x2c,0xf3,0xd6,0xc0,0x14,0x4b,0xb3,0x86,0x88,0x89,0x81,0x83,0x7d,0x9d,0xf7,0xe3,0xe4,0x27,0xba,0xa8,0x03,0xb4,0xe3,0x97,0x74,0x1c,0x0d,0xab,0xb4,0x6e,0xc6,0x9e,0x58,0xdd,0x15,0x95,0x2f,0xa6,0xd6,0xaa,0x5a,0x96,0x71 +.byte 0x69,0xca,0xe0,0x5f,0xd2,0x3c,0x66,0x1b,0x58,0x25,0xd6,0xec,0xc0,0x46,0x3e,0x56,0xd0,0xe1,0x36,0x44,0x56,0xc0,0xf2,0x15,0x48,0x9e,0x07,0xce,0x5d,0xb9,0xd4,0x4e,0xcc,0x31,0x26,0xaa,0xdb,0x6a,0x87,0x98,0x0e,0x37,0xfc,0xc5,0x91,0x28,0x1b,0xf8,0x70,0xbf,0x30,0x71,0xbe,0xa0,0x81,0x1e,0x30,0x33,0x37,0x37,0xc8,0x07,0x08,0x9b +.byte 0x8f,0xe4,0x27,0x9f,0x90,0x67,0xb4,0x96,0x08,0xd7,0x30,0x9e,0xa6,0x53,0x39,0xd1,0x9b,0xde,0x02,0x35,0xf3,0xb1,0x19,0x7b,0xd2,0x28,0x5a,0xc3,0x1f,0x69,0x0e,0x48,0xbf,0xa3,0xb4,0x55,0xd1,0x10,0x3d,0x30,0x71,0xc6,0x82,0x2d,0xb8,0x6f,0xe6,0x99,0x6b,0xef,0x9f,0x86,0xed,0x93,0x13,0xb6,0xb0,0x87,0x91,0x77,0x4a,0x00,0xe4,0x5f +.byte 0x4c,0x7d,0x41,0x3b,0xc9,0xda,0x99,0x6b,0xff,0xec,0xef,0x05,0x3c,0xc6,0x0d,0xec,0x68,0x12,0x44,0x31,0xac,0xc9,0x0b,0x9c,0xf5,0xea,0xed,0xda,0x88,0xec,0x6e,0x6e,0x73,0xda,0x85,0x52,0x69,0xa1,0x13,0x52,0xcf,0xc3,0x4d,0x95,0x88,0xec,0x1f,0x53,0x81,0x6f,0xac,0x53,0x60,0x48,0x20,0x9a,0x4d,0x88,0x2c,0x4b,0xb0,0x69,0x5f,0x07 +.byte 0xf9,0xa7,0x2c,0x9a,0x13,0x91,0x86,0xa2,0x98,0x20,0xa9,0x80,0x1e,0xaa,0x8e,0xbc,0x3c,0x3d,0x51,0x34,0x3d,0x5b,0x80,0xe4,0x39,0xfe,0xc8,0xb1,0x6d,0xfe,0x36,0x9d,0x9b,0xde,0x22,0x39,0x41,0xe9,0xff,0xda,0x67,0x67,0xd4,0xeb,0x60,0x44,0xd5,0xc1,0x74,0xcd,0xa0,0x98,0x06,0x34,0x76,0xf8,0xe5,0x0d,0xc8,0x52,0xca,0x83,0xd2,0xdd +.byte 0xf2,0x12,0x36,0x7d,0x3e,0x7f,0xbd,0xa6,0xd8,0x1e,0xc0,0x9d,0x67,0x2a,0x33,0x87,0x86,0x79,0x7a,0x70,0x3a,0x63,0x0b,0x74,0x77,0x89,0xce,0x8f,0x5a,0x3b,0xf3,0x2e,0x52,0x4d,0x1d,0xc6,0xc3,0xc8,0x69,0x98,0xdc,0x81,0x45,0x99,0xfd,0xcd,0x6b,0x6d,0x05,0x33,0x40,0xde,0xb3,0xbd,0x4a,0x27,0xc2,0x9e,0x8b,0xf1,0x4c,0xac,0x92,0x82 +.byte 0x55,0x04,0x79,0xe7,0x28,0x74,0x5b,0x70,0xdc,0xc0,0x4f,0x0c,0xcf,0x3a,0x7f,0x08,0xcc,0x2e,0x1d,0xfd,0x8d,0xd9,0x5c,0xe2,0xa7,0x98,0xc1,0xe8,0x4b,0x96,0xbe,0x27,0xd6,0xfd,0x0a,0x59,0x30,0x33,0x85,0x41,0xc5,0x63,0xab,0xe7,0xda,0x26,0xbd,0xce,0xe7,0x9d,0x50,0xd7,0x2d,0x67,0x7a,0xa1,0x05,0x2b,0x74,0x60,0x5e,0x6c,0x04,0x2b +.byte 0xba,0xe6,0x2d,0x25,0xc9,0x00,0xd0,0xf0,0xa5,0x4f,0x22,0x59,0x34,0xb8,0x43,0x6b,0xb7,0x67,0x25,0x99,0xff,0x75,0x17,0xb1,0x13,0x7e,0x34,0x1d,0x42,0xa3,0x6b,0xb5,0x9d,0xfe,0xa1,0x71,0x0d,0x90,0x81,0x58,0xfc,0xc7,0x85,0xe6,0xbd,0xc2,0xcc,0xc9,0xc9,0x23,0x6e,0xd6,0xbe,0x4a,0x61,0xd4,0xf5,0x9e,0x37,0x6a,0xb1,0x8b,0x91,0x59 +.byte 0xe1,0x3e,0xac,0x87,0x54,0xa6,0xf9,0xf5,0x90,0xd2,0x7c,0xba,0x4b,0x37,0x33,0x1b,0x88,0x5e,0xbd,0x78,0x3f,0xed,0x43,0x40,0x4f,0x16,0x59,0x29,0xbc,0x27,0x98,0x87,0xfe,0x62,0x56,0x93,0x21,0x0a,0xca,0xc1,0x21,0x99,0xb3,0x32,0xbb,0x5a,0x79,0x40,0xab,0xea,0x00,0xf8,0xe9,0x90,0x0d,0x59,0xbd,0x6e,0x7f,0x74,0x01,0x50,0x67,0x3a +.byte 0x8e,0x24,0x1d,0x6c,0xc8,0xd6,0x93,0xca,0x71,0x95,0xec,0xac,0x78,0xe9,0x1f,0x38,0x0d,0xa2,0xe5,0x32,0x90,0xa2,0xaf,0xef,0x15,0x06,0xd6,0x52,0xa4,0xd2,0x94,0x0f,0xbd,0x86,0x81,0x82,0x12,0x9b,0x3a,0xc4,0x0b,0xdf,0x8a,0x5f,0xc6,0x3b,0xb4,0x13,0x9b,0xeb,0xed,0x2d,0x06,0x46,0xa3,0xbe,0xbb,0xe1,0xe1,0x93,0xa1,0xab,0x46,0xf3 +.byte 0xd0,0xd9,0xce,0xb6,0xfb,0xd0,0xd5,0xb6,0xde,0x0c,0xed,0x90,0x18,0x6c,0x1e,0x46,0xb0,0x36,0xa7,0xf1,0x29,0xbe,0x9a,0xa0,0xcf,0xed,0xd6,0xaf,0xb8,0x89,0x9b,0x83,0xa8,0xa0,0x8d,0x26,0xaf,0x8f,0x48,0x66,0xfc,0x22,0x1a,0xc0,0xcf,0xf8,0x90,0x57,0x7e,0x25,0x5f,0xe4,0x0c,0x68,0xd2,0xaa,0x59,0x09,0x2f,0x6d,0x3f,0x80,0x8d,0xe0 +.byte 0xfa,0x25,0xb0,0xe0,0x85,0xe9,0x13,0x39,0x3d,0x1f,0xed,0xd1,0x94,0x9b,0xb5,0xc2,0x65,0xda,0xec,0x7a,0x1f,0x2f,0xe2,0x0a,0x42,0x09,0xbd,0x79,0x7d,0xcb,0xb8,0x4a,0x02,0x2b,0x72,0xaf,0x33,0x85,0x72,0x1b,0x18,0x0c,0xa3,0xec,0x39,0x0e,0x30,0x21,0x41,0xf8,0x2e,0xc7,0x8e,0x5c,0x4c,0xda,0x22,0x49,0x8c,0xa7,0xfb,0x89,0x76,0x2e +.byte 0x45,0x90,0x6c,0xeb,0x70,0x78,0x6d,0x6e,0xee,0x12,0x6c,0xb9,0xb9,0x8d,0xe7,0xf3,0x4d,0x86,0xc4,0x58,0x49,0x55,0xa6,0x86,0xaf,0x39,0x03,0x21,0xfa,0xa7,0xdd,0x51,0x80,0x79,0x6d,0x5b,0xa5,0x58,0x0f,0xfd,0x57,0xb3,0x83,0xe6,0x0d,0x25,0xec,0x55,0xdc,0x0a,0x6f,0xbc,0x7d,0xfd,0x94,0x16,0xdd,0x60,0x9f,0x2a,0x4b,0x6c,0x82,0x03 +.byte 0x4b,0x44,0xbb,0x84,0xdc,0xcb,0x97,0x8e,0x58,0xe7,0xc1,0x79,0xa9,0xf3,0x53,0x78,0x1f,0xf1,0x3e,0xdd,0x94,0x24,0x6d,0xb1,0xd2,0x99,0xbc,0xa1,0xbe,0x7d,0xdd,0xff,0xa8,0x5d,0xd2,0xc2,0xba,0xad,0x60,0x6b,0x40,0x5d,0x7b,0x99,0xd2,0xea,0x45,0x66,0x80,0x6c,0x47,0xf2,0xeb,0x94,0xb8,0xe8,0xe8,0xa0,0x46,0x05,0xe1,0x4f,0x40,0x23 +.byte 0x34,0xdf,0x91,0x63,0xae,0xc9,0xe7,0x32,0x20,0x9a,0x95,0x1e,0xcd,0x5a,0x60,0xe1,0x3d,0xe0,0xf1,0x16,0x3d,0x6e,0x8b,0x96,0x23,0xe0,0xaa,0x1d,0x1a,0xde,0xed,0xc6,0x63,0xb5,0x46,0x8b,0x78,0x71,0x9a,0x14,0x88,0x79,0x61,0x68,0x6b,0xcf,0x80,0xd8,0x9c,0xaa,0xfb,0xb1,0xc0,0xf3,0x39,0x07,0x26,0x56,0x80,0xba,0x9d,0xf5,0xe7,0x95 +.byte 0x99,0xac,0x90,0xea,0xe7,0xe1,0xc9,0x0d,0x40,0x94,0x83,0x58,0xd2,0xc3,0x2b,0xce,0x1e,0xae,0x2a,0xa6,0xfa,0xc7,0x89,0x44,0xcb,0xe2,0x9e,0x74,0x33,0xaa,0x70,0xe5,0x28,0x3a,0x51,0x74,0x53,0xe2,0xfb,0x7c,0x47,0x76,0x22,0xdf,0x46,0xa6,0x01,0x17,0xef,0x88,0x43,0x46,0x3f,0x1a,0x26,0x0c,0xad,0xf4,0x31,0x55,0xf2,0xe7,0xc9,0x35 +.byte 0x6f,0x7c,0x0c,0x5c,0xfd,0x43,0xa4,0x6c,0x6c,0x74,0xf0,0xa4,0xec,0x1d,0x83,0x97,0xc1,0x6c,0x9c,0xd7,0x97,0x90,0x7c,0x07,0x88,0xc0,0xb4,0x79,0x2c,0x7a,0x9c,0x93,0xa2,0x15,0x6c,0xd2,0xa9,0x45,0xa5,0xc1,0x16,0xfe,0x72,0xf4,0x01,0x32,0xe4,0x51,0xdd,0xdb,0x50,0xe3,0x61,0x4e,0x29,0x1e,0x27,0x10,0xe9,0x5e,0x30,0x2b,0x30,0x27 +.byte 0x99,0xff,0x92,0x23,0x04,0x8d,0x28,0x68,0x28,0xd3,0x0f,0xec,0xbb,0xf9,0xfb,0x44,0x1c,0xaa,0x8b,0x38,0x95,0x67,0x1e,0xf5,0x42,0xc9,0xec,0x05,0xeb,0x94,0xe5,0x1c,0x8a,0x2a,0xef,0x3b,0x74,0x46,0x89,0x4f,0xd5,0x6f,0xa0,0xe5,0x74,0xae,0x24,0x8d,0x81,0xae,0x9d,0x3c,0x3e,0x3d,0x41,0x54,0x8f,0xd9,0xc2,0x98,0xf4,0x84,0xeb,0x30 +.byte 0x6a,0x06,0x67,0x11,0x2d,0xb0,0x55,0x70,0x26,0xdf,0x19,0x5f,0x81,0xe9,0x39,0x69,0x3a,0xd6,0x09,0xa4,0x40,0x22,0x1f,0x5c,0xbf,0xd5,0xa6,0xea,0x69,0x99,0x0d,0xea,0x70,0xed,0xfe,0x3a,0xba,0x23,0x8b,0xab,0x08,0xfe,0xfb,0xe9,0x1a,0x88,0x80,0x13,0x45,0x9c,0xca,0x2e,0xda,0x4a,0xc8,0x5d,0x15,0x52,0x87,0x36,0x9b,0x87,0x8a,0x76 +.byte 0x5d,0x31,0x24,0x4a,0xcb,0xf5,0xd3,0xd3,0xc1,0xec,0xde,0x1e,0x48,0x99,0xd5,0xcb,0x93,0xf7,0xca,0x2d,0xa4,0x66,0x5e,0xa4,0xcf,0xc6,0x15,0x20,0x10,0xb1,0xe2,0x8e,0xb9,0x44,0xa7,0xc3,0x54,0x14,0x86,0x08,0xb7,0x89,0x52,0xd5,0x72,0xc5,0x62,0x4d,0x82,0x96,0x23,0xcf,0x6e,0x52,0x3a,0x92,0x53,0x48,0xa2,0xa5,0x9d,0xa4,0xcc,0x32 +.byte 0x45,0x5a,0xdf,0xe2,0xbe,0xce,0x28,0xc8,0xb1,0xb7,0x0f,0x6a,0x38,0x28,0x14,0x66,0x55,0x7a,0xab,0x35,0x56,0xd0,0xc7,0xe5,0xa1,0x8a,0x84,0xf7,0xc5,0xa9,0xdb,0x2a,0x45,0xe9,0x34,0x2d,0xf2,0xed,0x2b,0xa9,0x9e,0x49,0x1b,0x23,0x10,0xeb,0x0e,0x01,0x46,0x6f,0x7a,0x50,0x09,0x5f,0xc3,0xb6,0x1e,0x2f,0x1a,0x3e,0x89,0x32,0xaa,0x5a +.byte 0xaa,0xef,0x23,0x45,0xdc,0xb5,0x7e,0x5f,0x87,0x77,0xde,0x50,0xab,0xbf,0x9e,0x62,0xa8,0xe0,0xf0,0xc8,0x4a,0xf1,0x4e,0xaf,0xe4,0x50,0x8a,0xfe,0xc9,0x68,0xdd,0x19,0x1d,0xc6,0x54,0xe5,0x38,0x0a,0x6f,0x36,0xe4,0x85,0xe8,0xab,0xc4,0x06,0xef,0x07,0x29,0xce,0xea,0x9d,0x2e,0x22,0x97,0x18,0x7e,0x59,0x89,0x92,0x31,0xc5,0x87,0x50 +.byte 0xa8,0x23,0x22,0x58,0x47,0x27,0x1c,0x89,0x5f,0xec,0x94,0x1d,0xb2,0xc8,0x61,0x1e,0x0a,0x80,0xd3,0xe9,0xbf,0x65,0xb9,0x66,0x32,0x56,0xde,0xd2,0x13,0xee,0xea,0xc4,0xc9,0xbf,0x4c,0xb7,0xa4,0x1c,0xc0,0xbf,0xcf,0xa4,0x58,0x1f,0x98,0x1d,0x25,0x4e,0x51,0xd9,0xbe,0x89,0x32,0xdb,0x7a,0xa6,0x39,0xa9,0xbf,0xed,0x65,0x6b,0x92,0xc4 +.byte 0x8d,0xcd,0x63,0x18,0x65,0x44,0x95,0xcf,0x17,0x72,0x8f,0x27,0x79,0x83,0xda,0xe3,0xe7,0xd9,0xca,0x57,0xff,0xa3,0x15,0xbf,0xb6,0xd8,0xc2,0x8c,0xe8,0xdb,0x8c,0xdc,0x54,0x6a,0xc8,0x57,0x6e,0x24,0xc3,0x3c,0x1f,0x33,0xdd,0x68,0xbd,0x7a,0xa3,0xbc,0xa9,0x9a,0xe8,0xfc,0x97,0xa5,0xbe,0x59,0xfb,0x77,0xcd,0x22,0xc6,0x3d,0x95,0x21 +.byte 0xcb,0xf7,0x8d,0xc1,0x77,0xc6,0xe0,0x06,0xb2,0xdb,0xec,0x54,0x19,0xad,0x02,0x25,0xe0,0x0f,0xda,0x4c,0xa5,0xf2,0x47,0x3f,0xc9,0xa0,0x91,0x21,0x39,0xe9,0x74,0x2a,0x9a,0xc1,0x57,0x86,0x3c,0x32,0x27,0x4c,0xc2,0x2d,0x50,0xbd,0x7a,0x04,0x9c,0x45,0x0d,0x7e,0x06,0x1d,0x3e,0xc1,0x6f,0x06,0x7f,0xd4,0x71,0xd3,0x5c,0x66,0x74,0xa7 +.byte 0x33,0x75,0x64,0xa8,0x7d,0xc0,0x23,0xda,0xb0,0x6d,0x12,0xbe,0x83,0x98,0xe7,0x65,0x38,0x4d,0x39,0xc3,0xd7,0x33,0xfb,0x58,0x64,0xfc,0xde,0xd7,0xbf,0x9e,0xdb,0xcc,0x7a,0x35,0xac,0xdf,0x13,0x08,0xbc,0x0a,0x55,0x82,0x5f,0xc3,0x74,0xc5,0xb2,0xdb,0x89,0xdc,0x9c,0x60,0xfa,0x02,0x1c,0xba,0x5b,0x7e,0x0f,0xb1,0x0f,0xad,0x43,0xe1 +.byte 0xe1,0xbe,0x1e,0x06,0x05,0x0f,0x39,0x80,0x3d,0x7d,0xbe,0x8f,0x38,0x25,0x46,0x5e,0xea,0x47,0x36,0x65,0x4c,0x3c,0x6c,0xd6,0xaa,0x46,0xaa,0xb0,0x95,0x1d,0xff,0x67,0x6c,0x70,0x9d,0xec,0x3d,0x3d,0x4c,0x2f,0xd9,0x2b,0xb0,0xbd,0x8c,0x6a,0xca,0xac,0x0c,0x53,0xa1,0xda,0xd8,0xc1,0x3c,0xaa,0xcc,0x50,0x85,0x41,0xa1,0xa7,0xe9,0x7f +.byte 0xf7,0xa8,0x28,0xb1,0x5f,0xd6,0x77,0xc9,0xb5,0xae,0x33,0xa7,0x2d,0x16,0xe0,0x13,0xe8,0xd4,0xf9,0x4e,0x62,0x2e,0xc2,0x9a,0xf3,0x83,0xe0,0x45,0x43,0x68,0x40,0x5a,0x56,0xf3,0x31,0xc8,0x5b,0x46,0x0b,0x38,0x1f,0xa5,0xff,0xe6,0xa1,0x81,0xc0,0x91,0xe5,0x5a,0x63,0x8f,0x47,0x9a,0xe7,0x26,0x0d,0x78,0x8d,0x11,0x7d,0xc8,0xd4,0x9f +.byte 0xc1,0xf7,0x8f,0x93,0xfa,0x2f,0xb5,0xfd,0x6d,0xa4,0x34,0xcf,0x3c,0x6c,0xf6,0x64,0xae,0x5c,0x60,0xa2,0xb4,0xcc,0x18,0x3e,0x08,0x8e,0x36,0x88,0xab,0xc3,0xea,0x53,0x4f,0x1c,0x9e,0xe6,0xef,0x2d,0x9c,0x78,0x4a,0x3a,0x5a,0x60,0x8e,0xf7,0xeb,0x0b,0x36,0xb1,0xbb,0x59,0xe2,0x5e,0x64,0x60,0xe5,0xd6,0x3d,0x2a,0xe1,0x1b,0x03,0x40 +.byte 0x8d,0xde,0x2e,0xd0,0x76,0x0a,0x6b,0x63,0x2a,0x53,0x2d,0x39,0xe0,0x53,0xee,0x7d,0xc4,0x8a,0x39,0xc5,0xda,0xfc,0x31,0x7e,0xa2,0x1b,0x11,0x1d,0x8a,0x8e,0x66,0xf4,0x00,0x17,0xd3,0x78,0x1b,0x94,0xad,0xcf,0xdd,0x56,0xce,0xaf,0xf6,0x34,0xe4,0xb6,0x47,0xe0,0xda,0x1b,0x36,0x4f,0x86,0x26,0xc1,0x65,0xec,0x85,0x8c,0xa9,0xfe,0x96 +.byte 0x75,0x0d,0xe3,0xeb,0x9a,0xa6,0x3f,0xb3,0x10,0x03,0x85,0x24,0xf2,0xb5,0xcd,0x69,0x7d,0xba,0xa2,0x5c,0x8a,0x6d,0x45,0xf4,0xc8,0x4f,0x69,0x8e,0xd4,0x69,0x82,0x42,0xfd,0x00,0x59,0xfd,0x20,0x7a,0x63,0x58,0x56,0x30,0x21,0x73,0xbd,0xd4,0x49,0x84,0x3f,0x51,0x0e,0xfb,0xd3,0xfc,0x93,0x17,0x7f,0x23,0x75,0x25,0xea,0x78,0x79,0xf7 +.byte 0xec,0x22,0xef,0x86,0x91,0x0a,0x90,0x10,0x71,0x3b,0xb8,0x8e,0xb7,0xc9,0xd1,0x26,0x98,0x7d,0x1a,0xab,0x74,0x3e,0x5f,0x10,0xa8,0x47,0xdf,0xc9,0x0a,0x03,0xbb,0xe2,0xbb,0x34,0xbe,0x87,0x1a,0x3e,0x13,0x4b,0xd5,0xdd,0x53,0xb7,0x65,0xb4,0x16,0x38,0xd3,0xfd,0x01,0xde,0xe8,0xba,0x1d,0x33,0x5b,0x7b,0x9b,0x9f,0xfb,0xe7,0x8d,0x82 +.byte 0x21,0x78,0x9e,0xb2,0xf5,0x16,0x37,0x88,0x47,0x9d,0x1a,0x2c,0xfe,0x6a,0xac,0xde,0x3e,0xc4,0xa8,0xed,0x64,0x46,0xdd,0x05,0x07,0x60,0xef,0x99,0x96,0xf0,0x84,0x27,0x38,0x58,0xe5,0xc0,0x53,0x7d,0x07,0xe3,0xa5,0x31,0xb5,0x8a,0xe7,0x50,0x94,0xbb,0x29,0xf9,0x58,0x13,0x91,0x5b,0x54,0x77,0xf6,0x91,0xb8,0x75,0x05,0x3d,0x70,0x3e +.byte 0x07,0x95,0x7d,0x37,0xbd,0x1d,0x29,0x4d,0x33,0x07,0x13,0x2b,0x54,0x70,0x9c,0x31,0xf1,0xcd,0x2d,0x28,0x09,0x43,0x90,0x24,0x8c,0x82,0xb0,0x08,0x71,0x08,0x97,0x7e,0x1a,0xbc,0x82,0xd8,0x31,0x0a,0x13,0xe9,0x22,0xf0,0x8d,0x2b,0x91,0xe5,0x2e,0x34,0x56,0x97,0x86,0xc9,0xbd,0x45,0x1e,0x32,0x03,0xcb,0xa1,0x29,0x00,0x81,0xd4,0x6e +.byte 0x5d,0xbc,0x0f,0x01,0x8d,0x5c,0xb9,0x80,0xcc,0xfe,0x0d,0xa3,0xef,0x8e,0x85,0x59,0x37,0xf7,0x64,0xa7,0xe5,0x2a,0xd5,0x44,0xee,0x91,0xcf,0x6c,0xf5,0x0a,0x9b,0xc7,0xdf,0xb6,0x02,0x2d,0xa4,0xf1,0x22,0x2a,0x97,0xfe,0x1d,0xb7,0x4c,0xc7,0x4f,0x2f,0x0b,0x38,0xd2,0xbf,0xfe,0xe3,0x94,0x55,0xae,0x85,0x0c,0x34,0x59,0x67,0x23,0x7b +.byte 0x4a,0x87,0xd9,0xd2,0xca,0xd5,0x38,0xd2,0x9d,0x05,0x2e,0xd8,0xe3,0x26,0x51,0xa4,0x14,0x66,0xfb,0x38,0x40,0x18,0x3b,0xda,0x43,0x85,0xc9,0xf5,0xf4,0xe7,0x22,0x82,0x45,0xa1,0xdf,0x98,0xa0,0xab,0x5f,0x7a,0x50,0x84,0x75,0x7a,0x70,0xa6,0x3b,0x04,0x20,0xed,0xa8,0x68,0x6d,0x3f,0x43,0xf8,0xb8,0xac,0xc7,0x32,0xa0,0xff,0x47,0xd5 +.byte 0xb3,0x92,0x6a,0x15,0x5a,0xf1,0x7c,0x32,0x30,0xda,0x1e,0x5d,0xab,0xcc,0xd0,0x3a,0xdc,0xcf,0x70,0xd8,0x4d,0xa3,0x50,0xac,0x50,0x42,0x53,0xc6,0xe0,0x3a,0x26,0xdc,0x77,0x30,0x31,0x59,0xa1,0xfc,0x4d,0x48,0x00,0x0d,0xe0,0x66,0xb3,0x9b,0xd3,0x38,0x45,0xbb,0x0c,0x57,0xc5,0x78,0xee,0x8c,0x96,0xea,0xa2,0x16,0xa3,0x12,0xb1,0x06 +.byte 0xd0,0x2a,0x70,0xf7,0xce,0x42,0xae,0x17,0x64,0xbf,0x13,0xa0,0xe9,0x62,0x57,0x1d,0x55,0x78,0xfa,0x72,0x19,0x58,0x15,0xea,0xe5,0xdf,0x72,0x0e,0xc6,0xd3,0xb4,0x3d,0x60,0xee,0x32,0x2a,0xce,0xdc,0xad,0xd0,0x34,0xe6,0xb4,0xcf,0xce,0x5a,0x4a,0x9f,0xaf,0x01,0xb3,0x2a,0xed,0x46,0xa0,0xad,0xaa,0x62,0x8b,0xa4,0xf7,0x4b,0xce,0x32 +.byte 0x35,0x29,0x1e,0x7a,0xda,0x74,0xf8,0xe5,0xda,0x52,0x66,0xaf,0x3d,0x1a,0xff,0x42,0xc0,0xcc,0xb1,0x32,0x36,0x10,0x44,0x34,0x6a,0x16,0xc2,0x5b,0x9a,0x35,0x3f,0xd2,0x29,0xc5,0x76,0x3c,0x24,0xc7,0x2b,0x92,0xae,0xe0,0xe2,0x04,0x6c,0x3b,0x97,0xda,0xfd,0x49,0x43,0x6d,0x35,0xf5,0xc3,0xc1,0x93,0xf8,0x2f,0x25,0xef,0x3e,0xd8,0xf2 +.byte 0xc0,0xb3,0xb5,0x71,0x01,0xe0,0x07,0x11,0xd5,0xf1,0xd3,0x54,0x59,0x93,0x77,0x2e,0x77,0xdc,0x57,0xd7,0x9b,0x0a,0xe2,0xde,0x29,0x04,0x81,0xa1,0x81,0x6f,0x94,0x86,0x39,0xd7,0x29,0x69,0x3f,0xfa,0xe4,0x02,0x01,0x85,0x04,0x21,0xd3,0x17,0xf5,0x68,0x85,0x6e,0x74,0x15,0x56,0xe6,0x5e,0x12,0x1c,0x0d,0x2f,0x7a,0x8d,0xe1,0xc8,0x47 +.byte 0x7b,0xdc,0x35,0x64,0xf1,0x00,0xc0,0x7b,0xd8,0x2c,0x8c,0x60,0x10,0x53,0x11,0x2c,0x5c,0xa2,0xb6,0x05,0xa3,0xcd,0x14,0xb6,0xd0,0x36,0xe9,0x74,0x78,0xc3,0x84,0x6b,0x51,0xa9,0xf9,0xf1,0x05,0xe2,0xd4,0xa3,0x57,0xec,0xb1,0x5e,0xd5,0x75,0x64,0xe3,0xb0,0xf9,0x8f,0x88,0x60,0xdf,0x8e,0x75,0xf9,0x32,0xfc,0x58,0x5b,0x4b,0x17,0xdb +.byte 0x41,0x04,0x6f,0x17,0x7a,0xf8,0xd0,0x47,0x8e,0xeb,0xd1,0xf9,0xa6,0xa8,0x52,0x7e,0x07,0x6b,0x5b,0x4d,0xb9,0xda,0x91,0x40,0x51,0x25,0x67,0x4b,0xf1,0x95,0x12,0x07,0xa9,0xa5,0x33,0x96,0x92,0x5e,0xb4,0x0e,0xf0,0x85,0x2e,0x70,0xd8,0xaf,0xae,0x9a,0x3d,0x0c,0xb0,0xee,0xe1,0x80,0x5a,0xb9,0x17,0xe6,0x00,0xa8,0x82,0xd0,0x9b,0xf5 +.byte 0xe3,0xa0,0x12,0xc4,0x15,0xd6,0x5e,0x57,0x5c,0xd2,0xb9,0xa7,0x8e,0xfd,0x09,0xc3,0xd2,0x66,0xfd,0x86,0xb4,0xdc,0xa3,0xc2,0xfe,0x16,0x86,0xc4,0x98,0xa3,0x2e,0x4c,0xc9,0x2c,0xd6,0x87,0x83,0x1b,0x6f,0xe2,0x44,0xd6,0x72,0x94,0x1d,0xba,0xaf,0x34,0x1f,0xf2,0x40,0x40,0x33,0x24,0x63,0xc1,0x26,0xef,0xbc,0x0f,0x3b,0x3c,0x65,0x2b +.byte 0xa7,0xc7,0xdf,0x96,0x67,0xab,0x92,0x0e,0x04,0x8c,0x82,0x9e,0xbe,0x52,0x61,0x40,0xdf,0x77,0x00,0xc5,0x01,0x9a,0xe9,0xde,0xe1,0xe2,0x45,0xb8,0xed,0x94,0xd5,0xf0,0x28,0x29,0xef,0x0d,0x91,0x07,0x9b,0xfe,0x69,0x78,0x26,0xd7,0xf9,0x51,0xf1,0x9c,0xf2,0xbb,0x83,0x2d,0x79,0x1e,0xff,0x97,0x13,0xdc,0x28,0x93,0x26,0x7c,0x54,0x52 +.byte 0xc0,0x92,0xeb,0x4a,0xa2,0xe3,0x01,0xfc,0x07,0xb9,0x26,0x11,0x03,0xe0,0x19,0xa8,0x9c,0xff,0x3a,0x95,0x26,0x3a,0x17,0xf1,0x7d,0x6a,0x6a,0xb2,0xb5,0x5a,0x07,0x43,0x2b,0xb7,0xdd,0x19,0x14,0xe0,0x05,0x91,0xc5,0xee,0x49,0x35,0x7b,0x1a,0x2d,0x34,0xda,0xa2,0x45,0x7e,0x0d,0x64,0x98,0xb6,0x2e,0x47,0xaa,0x6c,0x73,0x66,0x55,0x01 +.byte 0x27,0xb0,0xa9,0x13,0xa6,0xe0,0x74,0x38,0xb3,0x97,0xfe,0xaf,0xdc,0xc0,0x6a,0x4f,0xd8,0xdb,0x07,0x62,0x61,0x05,0xbb,0xa0,0xa8,0xc5,0xb3,0x89,0x13,0xbb,0x09,0x01,0x6f,0x09,0xcb,0x47,0x62,0x46,0xf0,0x4b,0xf0,0xb7,0x7c,0x39,0x8d,0xe5,0x7b,0x64,0x49,0x32,0x93,0x1e,0x94,0x0a,0x98,0xe0,0xca,0xc6,0x67,0x5b,0xdf,0x88,0x0a,0x26 +.byte 0x83,0x77,0xc3,0xd0,0x11,0x66,0x3d,0x25,0x91,0x61,0x80,0xfc,0x9c,0x50,0xfb,0xe8,0x81,0x6f,0xd8,0xfa,0x77,0x78,0x4c,0x2b,0x44,0xd0,0x92,0x52,0xa4,0x50,0x50,0x7e,0xa2,0xb9,0xe7,0x79,0x33,0x95,0xfe,0x29,0x1c,0x1d,0x43,0x9d,0xa7,0x12,0xfe,0xa1,0x45,0xf4,0xd9,0x1c,0x7e,0x5a,0x67,0x99,0x7f,0x22,0x7c,0xa3,0xb1,0x2d,0xb7,0x1d +.byte 0x6b,0xf6,0xb4,0x94,0xf2,0xd1,0x5c,0x28,0x56,0xe9,0x4f,0x21,0x81,0x96,0x37,0x7c,0x25,0x74,0x0f,0xf9,0xc5,0xf5,0xc6,0xe8,0x8f,0xbb,0xfb,0xe4,0xaf,0x23,0xac,0x4c,0x20,0x35,0x7d,0xb4,0x4a,0xde,0x90,0xec,0x16,0x30,0x95,0x1b,0x79,0xf6,0x77,0xfe,0x80,0x10,0xba,0xd2,0x49,0xda,0xca,0x9e,0x6b,0x63,0x2f,0x24,0x38,0xf9,0xee,0x20 +.byte 0x38,0x5c,0xeb,0xf5,0xbc,0x07,0x7a,0xeb,0xde,0xc4,0x97,0xcf,0x48,0x9b,0x80,0x40,0xfa,0x81,0xf5,0x24,0xa7,0xf3,0xf7,0x16,0xe9,0xba,0xae,0x9f,0xde,0xa1,0x00,0x34,0x74,0x36,0x9f,0x47,0xce,0xcf,0x35,0xdb,0x30,0x7e,0x72,0x81,0xc5,0xe1,0x59,0x07,0x3e,0xc7,0x5b,0x7b,0xd3,0xc6,0xeb,0x4e,0x71,0x9c,0xeb,0x41,0x37,0xd9,0x9e,0x34 +.byte 0x0b,0xc1,0x9c,0xf7,0xfd,0x56,0xb0,0xd6,0xa6,0xe4,0x1d,0xdf,0x43,0xc6,0xf3,0x26,0x0f,0x01,0x07,0x29,0x57,0x9c,0x8f,0xe1,0x31,0xc9,0xa6,0x98,0x0f,0x0e,0x27,0xfd,0xa0,0x59,0xdf,0x92,0x7b,0x0a,0x4c,0x42,0x4b,0x03,0x98,0x2a,0xea,0xcb,0xd8,0x0f,0x6d,0x19,0x0b,0x22,0x69,0x8b,0xaa,0x3b,0xc8,0x41,0x66,0x81,0xc3,0xaa,0x64,0x6d +.byte 0x44,0xdd,0xb9,0xe2,0xc4,0x47,0x6d,0xdf,0x61,0xe0,0xf3,0x26,0x40,0x23,0x2f,0xf9,0x2a,0xb3,0xfa,0xe2,0xe8,0x36,0xc0,0xd9,0x89,0xb0,0x05,0x47,0x36,0x20,0x3b,0x03,0x0c,0xd1,0x46,0x9b,0xc9,0x65,0xfa,0x14,0xba,0x68,0x49,0xfc,0x2a,0xb9,0x04,0x47,0xbb,0x64,0xe1,0x7f,0x5a,0xd3,0x70,0x19,0x0f,0x14,0x09,0xc0,0xbe,0xc3,0x9b,0x2f +.byte 0xd1,0x05,0x90,0x56,0x09,0x47,0xb3,0xc5,0x08,0x6f,0x89,0x59,0x8c,0xf3,0xd4,0x1c,0xaf,0x68,0x00,0x32,0x58,0xe2,0x66,0x55,0xe2,0xc3,0x46,0x73,0xfd,0x4b,0x63,0xc5,0xdd,0x48,0xa8,0x14,0xe9,0x07,0x94,0x8f,0x51,0x6e,0x2d,0x7c,0x62,0x97,0x73,0xa5,0x42,0x7d,0xad,0x43,0xcb,0x65,0x56,0xf0,0x23,0x28,0x72,0xdb,0x1f,0xcf,0x34,0x9a +.byte 0x62,0x06,0x8d,0xc9,0x86,0x40,0x6d,0xee,0x58,0x72,0x02,0xbb,0xce,0x33,0x6a,0xe4,0xcb,0x46,0x25,0xda,0x2f,0x8d,0xc9,0x8e,0xfe,0xcf,0xbb,0xfc,0xb0,0xe8,0xec,0xf2,0xf9,0xff,0x5d,0x70,0x9e,0x2e,0x22,0x0e,0x9a,0x4d,0xb8,0x26,0x7a,0x48,0x3f,0xba,0x5c,0xcd,0x10,0xf4,0x6d,0x89,0x3d,0x5d,0x87,0xd4,0x69,0xb8,0x4a,0x20,0xc6,0xf8 +.byte 0x03,0x6c,0x60,0x1e,0x9c,0xc6,0xe3,0x39,0x9b,0xa1,0x16,0x64,0xed,0xc6,0xd7,0x54,0xfd,0x8d,0xa0,0x2f,0xcf,0xc6,0xde,0x43,0xe4,0xc5,0xb7,0xd6,0x00,0xaf,0x95,0x7a,0xc6,0xde,0x26,0x59,0x39,0xb0,0x12,0x6b,0xe1,0x3c,0xa9,0x09,0xb6,0x15,0xb0,0x62,0xad,0xa9,0x11,0x4f,0x86,0xde,0xc6,0xe8,0x32,0x46,0x78,0xeb,0x60,0x81,0x6b,0x8f +.byte 0xac,0x80,0xbf,0xa4,0xc4,0xb7,0x5f,0x3b,0x2f,0xf8,0xe4,0x05,0xcf,0xbf,0xa3,0x14,0x6f,0x16,0xbc,0x6c,0x4e,0x31,0xd7,0x79,0x09,0xcf,0x9c,0x58,0xa3,0x0b,0x1a,0x31,0x4b,0xda,0xcb,0x11,0x35,0xb1,0xf5,0xbb,0xfb,0x00,0x46,0x6d,0x70,0x5e,0x4a,0x85,0x19,0xdf,0xb5,0xd0,0x03,0x2e,0x5d,0x01,0x95,0x4e,0x5a,0x59,0x99,0x24,0xac,0x3f +.byte 0x2d,0x64,0xaf,0xef,0x40,0x16,0x2a,0xcc,0x6a,0x6c,0x0f,0xe3,0x45,0x15,0x74,0x3d,0xea,0xdb,0xa7,0x3f,0xd2,0x50,0x4d,0xc7,0xc6,0x19,0x36,0x84,0xf4,0xbd,0x09,0xff,0xe7,0xf3,0xc0,0xa5,0x34,0x49,0x8a,0xfe,0x83,0xcd,0xe4,0x80,0x7d,0xe3,0xff,0xc9,0x8a,0xb9,0xd6,0x34,0x01,0xd1,0x47,0x16,0x5e,0x7c,0x16,0xf5,0x7c,0xf8,0xb5,0x53 +.byte 0x26,0x84,0x89,0x73,0xf3,0x7f,0x9c,0xb0,0x2f,0x07,0x9e,0xf2,0x12,0xdf,0xba,0xc0,0x15,0xd0,0x3a,0x59,0x9d,0xde,0x67,0x5e,0x1c,0x2b,0x4b,0x84,0xb8,0x89,0xfb,0x62,0x90,0xe9,0x89,0xd9,0xdb,0xb7,0x21,0x4a,0x9f,0xbd,0xc0,0x02,0x01,0xda,0xb3,0x4c,0x9d,0xfb,0x46,0xa1,0xd0,0x3c,0xf5,0x27,0x6f,0x70,0xb5,0xa9,0x74,0xdc,0xa0,0x76 +.byte 0xb7,0x3a,0x53,0x18,0xdd,0x80,0x5e,0x43,0xb5,0x35,0xe4,0x0e,0x26,0x27,0x0a,0xab,0xe8,0x4d,0x2e,0x89,0x20,0xc3,0xff,0xe4,0x7f,0x03,0x2c,0x5f,0x25,0xc7,0x70,0x53,0x27,0x4c,0xc8,0xb9,0xb1,0x81,0x10,0x7a,0xa2,0x65,0xe4,0x0b,0x65,0x8e,0x3d,0x2f,0x96,0xa0,0xa5,0x7b,0x4f,0x09,0xe9,0x9d,0x10,0x06,0xf7,0x18,0xad,0x2d,0x7f,0xb8 +.byte 0x8f,0x08,0xa7,0x2c,0xda,0x82,0xbe,0x5c,0xd6,0x1d,0xb6,0xe2,0x9b,0xa2,0xfc,0x18,0x8c,0x8d,0xf7,0x81,0xf4,0xc6,0x1e,0xcb,0xe5,0x73,0xa6,0x74,0x06,0x20,0xf3,0xa9,0xcb,0x80,0x01,0x55,0x7e,0xc0,0x6a,0x1f,0x5a,0x5b,0xb1,0x56,0x5d,0xd8,0x2a,0xd5,0xf5,0x57,0xe8,0x48,0x6c,0xfb,0x9e,0x93,0xa7,0x0e,0x13,0x2b,0x68,0xc5,0x6b,0x17 +.byte 0x43,0xb0,0x58,0x04,0x65,0x3d,0x46,0x57,0xa7,0x3d,0x99,0xb8,0xa1,0x48,0x17,0x44,0x67,0x2a,0x0d,0x44,0x87,0x9f,0x63,0xd7,0x92,0x56,0x7b,0xab,0xd3,0x6a,0xbd,0x4f,0xc0,0xc3,0xd2,0xee,0xd1,0x3d,0xd1,0x18,0x2e,0x6a,0xf5,0x3b,0x67,0xa0,0x0a,0xf3,0x11,0x49,0xc5,0x4b,0xef,0xcf,0x00,0xfd,0x22,0x8f,0xa0,0x9c,0x99,0x32,0x2f,0x58 +.byte 0xf9,0x97,0x98,0x13,0x4a,0x88,0x50,0xcc,0x58,0x1e,0x27,0x02,0x34,0x7d,0xec,0xf6,0x88,0x3a,0x74,0xb5,0x34,0x6d,0x6f,0x52,0x2d,0x20,0x02,0x70,0x22,0x27,0xdf,0x7a,0xff,0x30,0x36,0x66,0x1a,0xa0,0x51,0xc3,0x75,0x9a,0x06,0xe5,0x3f,0x6c,0x74,0x0d,0x15,0xa2,0xb6,0xe5,0xcd,0x55,0x4d,0xea,0x65,0x8f,0xbb,0xb2,0xd4,0x95,0x73,0xa4 +.byte 0xcd,0xb9,0xc8,0x82,0x60,0x49,0xe9,0x36,0xc9,0xb1,0xe9,0xcb,0x52,0xae,0xa7,0x7a,0x64,0xab,0x75,0x84,0x03,0x4b,0x37,0xf7,0x07,0x75,0xf7,0x1c,0x32,0x19,0xb6,0x8b,0xca,0x7c,0x43,0x15,0xe8,0xec,0x57,0x89,0x1d,0xe2,0xa0,0x80,0xc5,0xb6,0x02,0x29,0xfd,0xda,0xe0,0x14,0x93,0xb4,0xb3,0x44,0x2e,0x17,0x2f,0xed,0x3b,0x38,0x6e,0x8f +.byte 0xe0,0x3d,0xc6,0x77,0xe9,0xa7,0x76,0xcb,0x98,0x2d,0x08,0x61,0xcf,0x1b,0x25,0x3f,0xfb,0x1d,0x99,0xb1,0x5a,0x3c,0x53,0x96,0x4e,0x09,0x11,0xf6,0x5b,0x09,0x31,0xe1,0xad,0xb0,0xaf,0x7b,0xec,0xf9,0xa8,0x68,0xb7,0x93,0x57,0xf7,0x17,0x77,0x87,0x2b,0xdb,0x00,0x28,0xc6,0x48,0xac,0xff,0xcd,0x26,0x4a,0x8a,0x76,0x9a,0x2a,0x1d,0x37 +.byte 0x4c,0x70,0x4f,0xf6,0x52,0xe3,0x7a,0x78,0x94,0x5b,0x0b,0x50,0xb4,0x48,0x03,0xcd,0x78,0xd0,0x5d,0x89,0x6d,0x76,0xaf,0x9d,0x67,0xc3,0x75,0x6f,0x6a,0x2d,0xe2,0xb7,0x58,0x51,0x10,0x0d,0xef,0xa0,0x1a,0x74,0x28,0x3a,0x97,0x19,0x4f,0x3c,0x8a,0x86,0x3d,0xe4,0x66,0x3d,0x57,0xb4,0x66,0xb3,0x0b,0x4f,0x57,0x57,0x34,0x2e,0xc7,0x0c +.byte 0x11,0xdf,0x3c,0xb4,0x9f,0xe1,0xd5,0x27,0x41,0x08,0xec,0xca,0x18,0x88,0x48,0x5e,0x88,0x55,0x89,0x71,0xe6,0xa5,0x90,0x7c,0x3b,0xe5,0xf3,0x2a,0xd7,0xf5,0x0b,0x3d,0xbb,0x47,0xad,0xd7,0x78,0x41,0xa8,0xef,0xd4,0x36,0x31,0xd1,0xe4,0x9c,0x87,0x9e,0xb1,0x11,0x0e,0xff,0x8f,0x4d,0x79,0x65,0xc4,0x83,0x75,0x33,0xc9,0x89,0xe2,0xc3 +.byte 0x41,0x68,0x11,0xe7,0xe4,0x58,0xb9,0xf1,0xee,0x06,0x48,0x4d,0xc3,0xc7,0x76,0x60,0x42,0x94,0x8f,0x0d,0xb9,0x53,0x46,0x78,0x06,0x97,0x94,0x36,0xf4,0x3e,0xf3,0xdd,0x5b,0x46,0xe1,0x9d,0x3f,0x9e,0x78,0x00,0x9e,0xe7,0xcb,0x9e,0xc8,0x30,0x87,0x4a,0x52,0x91,0xd5,0xe2,0xa3,0x65,0x98,0xb2,0xc9,0x6c,0xfb,0x4e,0x54,0x5a,0x9f,0x57 +.byte 0x2c,0x4a,0x76,0xe4,0x97,0x88,0xd5,0x6a,0x0e,0x6c,0x7c,0xef,0x78,0x2a,0x7c,0x26,0xa3,0x25,0xf6,0x33,0x82,0x46,0x6d,0x91,0x0d,0xe4,0x83,0xec,0xf1,0x24,0xf8,0x0a,0x34,0xec,0xfc,0x7e,0x47,0xda,0x9a,0x17,0x1b,0x33,0xd0,0xf1,0x70,0xe4,0x0b,0xc7,0x70,0x58,0x1d,0x76,0x20,0x89,0xce,0x4f,0xd1,0xcb,0x3b,0x26,0xd1,0x98,0xd9,0x51 +.byte 0xb1,0xd0,0xaa,0x4a,0xd5,0x10,0xf2,0xae,0xaa,0x14,0xa7,0x72,0x99,0x3d,0xc8,0xbf,0xfb,0xec,0x6a,0x14,0xdd,0x97,0x7b,0x2f,0x16,0x96,0x0f,0x41,0xb8,0x33,0x15,0x1b,0xa2,0x6a,0x7e,0x64,0x0d,0xab,0xe7,0x62,0xf5,0x6c,0x56,0x69,0x09,0x46,0x32,0x24,0x60,0x4e,0x21,0xc7,0x5b,0xee,0x0a,0xe2,0x94,0x7c,0x20,0xe2,0x06,0xa0,0xa2,0x36 +.byte 0xa0,0x7d,0xb5,0x37,0x2a,0xee,0x20,0x25,0x4c,0xba,0x9a,0x06,0x4c,0x07,0x9b,0xea,0x55,0xac,0x2a,0xf7,0xb9,0x5c,0x23,0xac,0x43,0xda,0x9d,0xad,0x76,0xe2,0x5f,0xe0,0x27,0xaf,0x0a,0x5e,0x3d,0x54,0x84,0xfc,0x19,0x75,0x8c,0x62,0x4d,0x37,0x17,0x1a,0x90,0x55,0xb8,0x7e,0xa1,0xad,0x31,0x1a,0xc0,0x91,0x96,0x51,0xa9,0x5f,0xbb,0xb9 +.byte 0x95,0xbf,0xe2,0xd5,0x7e,0x31,0xba,0xc4,0x1e,0x63,0x98,0xd3,0xe2,0x7d,0x87,0xa5,0x46,0xe3,0xae,0xe1,0xe8,0x4e,0x74,0x29,0x0e,0x4b,0x10,0xa8,0x7f,0x3a,0xe5,0x60,0x0f,0x49,0x6a,0xcd,0x3d,0x5a,0x8e,0xf1,0x48,0xd0,0x80,0x7b,0xa3,0x7f,0x06,0x47,0x2b,0x60,0xf2,0x17,0xc3,0xe1,0x26,0x1e,0xb7,0x0f,0x2b,0x7c,0xc7,0xb8,0x3a,0x4f +.byte 0xad,0x05,0x97,0x88,0x93,0x82,0x8e,0x06,0x77,0x44,0xd1,0x65,0xfd,0x18,0x48,0xd6,0x88,0xcd,0x5c,0xbd,0xe4,0xaa,0xea,0xf1,0xed,0x16,0x5f,0xb3,0x58,0xe2,0x69,0x82,0xbe,0x9e,0xfc,0xcb,0xf6,0x17,0xa9,0x70,0xeb,0x08,0xd7,0x06,0x86,0xf6,0x5a,0x43,0x68,0x7b,0xcf,0xa3,0xfa,0x26,0x5e,0xe5,0x42,0xd3,0x5a,0xc8,0x1c,0x3b,0x8d,0x2d +.byte 0xf1,0x45,0xb0,0x97,0x90,0x0b,0xe7,0x2d,0xab,0xd7,0xd8,0x8a,0x16,0xf9,0x5f,0xa6,0xcf,0xc5,0x60,0x2c,0x34,0x5a,0x2e,0x2b,0xb9,0xb4,0x9c,0xa7,0x09,0x77,0xd2,0x3f,0x8c,0xf3,0xf6,0xf7,0xe0,0x27,0x79,0xc3,0x4e,0x61,0x7d,0x09,0x50,0x05,0x01,0x35,0x1b,0x33,0x54,0x6f,0x90,0x9a,0x19,0xcd,0x86,0x45,0x23,0xcd,0x6f,0x1b,0x62,0xc5 +.byte 0xce,0x4e,0x8e,0xff,0xe7,0x12,0x32,0x85,0x9a,0xc4,0x11,0x83,0xcf,0x78,0xd7,0x41,0x99,0x64,0x20,0xa6,0x69,0xdd,0xe3,0x53,0x98,0x6b,0xc7,0x98,0x51,0xc5,0xf8,0x3e,0xa3,0x5f,0x0d,0x78,0x2f,0xa7,0x05,0xff,0xe5,0x3a,0x0f,0x7c,0x09,0x58,0x3f,0xaa,0x0d,0x9a,0x9d,0x8d,0xe7,0xbf,0x6b,0x7d,0xfe,0x3a,0x4f,0x5c,0x50,0xb2,0xe7,0xc5 +.byte 0xa5,0x13,0xde,0xc8,0xe8,0x59,0xac,0xb0,0xdd,0xc0,0x81,0xa7,0x0b,0x78,0x32,0x23,0x76,0x85,0x11,0xef,0xe3,0x88,0x6f,0x7f,0xa9,0x09,0x7b,0x0c,0x6f,0x34,0xb2,0x67,0x5e,0xd6,0x11,0xad,0xd7,0x3b,0xf2,0xbb,0x66,0x5b,0xde,0x22,0xfc,0x55,0x26,0xa1,0x89,0x80,0x2e,0xb8,0xf3,0x3c,0xf8,0x1e,0xba,0x99,0x1c,0x24,0x33,0xb4,0xe6,0x17 +.byte 0x2b,0x9c,0x80,0xe5,0x9b,0x58,0x54,0x70,0xcd,0x15,0x81,0xcd,0x51,0x48,0x75,0x24,0x27,0xf5,0x30,0x79,0xc1,0x16,0xff,0x89,0x70,0x12,0x74,0x07,0x9d,0x39,0xf2,0x9c,0xc6,0x89,0x8d,0x94,0x41,0x01,0x04,0xf5,0x16,0x99,0xf3,0xf0,0xd1,0xf5,0x6d,0xd3,0x11,0x19,0x29,0x36,0xfb,0x41,0xf9,0x32,0xb9,0x0f,0x13,0xaf,0xac,0xfb,0x30,0x75 +.byte 0x62,0x8c,0x04,0x5b,0xf1,0xce,0x52,0x9b,0xbe,0x8c,0xf9,0x86,0x5d,0x7d,0xc1,0x8e,0x41,0x76,0x42,0x63,0xd7,0x74,0x8e,0x2c,0x46,0xa1,0x0a,0x51,0xb5,0xec,0xe9,0x91,0x56,0xbc,0xdc,0x32,0xfc,0x10,0xb5,0xca,0x5b,0x4b,0x72,0x99,0x07,0xff,0x01,0x11,0x2c,0xa4,0x60,0xf5,0x6b,0xd4,0xa8,0x96,0x21,0xee,0xbe,0x14,0x8f,0x69,0x99,0xdc +.byte 0x43,0x7f,0x13,0x3d,0x17,0x1e,0xa3,0x1b,0x21,0x23,0x26,0x7e,0xff,0x80,0x6b,0x66,0x3e,0xb2,0x48,0x1a,0x77,0x3c,0x50,0xe2,0xca,0x4d,0xc6,0xdb,0xfd,0xd1,0x23,0xcc,0xcb,0x01,0x25,0xc0,0x62,0x8d,0xe5,0x9c,0xb7,0x13,0x97,0xf5,0x49,0x01,0x19,0x45,0x45,0x83,0x17,0xff,0x8e,0x94,0x8c,0xb0,0xc0,0xaf,0x46,0x62,0x0e,0x62,0xb7,0x8c +.byte 0xd5,0xcf,0xb9,0x82,0x6e,0x8a,0xb9,0x22,0xbc,0x30,0xf9,0x65,0xc2,0x7f,0xce,0x6b,0x4d,0xad,0x87,0xcb,0x23,0xab,0x57,0x36,0x6a,0xb7,0x8c,0x63,0x17,0x60,0x13,0xa1,0x1f,0x3d,0xa4,0xd4,0xab,0x5d,0x97,0xc7,0x18,0xaf,0xf8,0xae,0x13,0x64,0x2a,0x19,0x34,0xe2,0x28,0x28,0x4f,0x32,0x2a,0xd8,0x43,0x79,0xaf,0x1e,0x56,0xfc,0x97,0x51 +.byte 0x67,0x8c,0x63,0x80,0x32,0x63,0x71,0x5c,0x78,0x00,0xeb,0xfd,0xa2,0x96,0x58,0x21,0x36,0x13,0x02,0xe5,0xa4,0xb7,0xcd,0x5a,0x30,0xa0,0x5b,0x7b,0x23,0xa4,0xcc,0x54,0x64,0x6f,0x6d,0x9b,0xaf,0xea,0x49,0x69,0x9e,0x2f,0x51,0x5c,0xe7,0xa3,0xa3,0xb8,0xac,0xed,0x47,0x23,0x7a,0x37,0x38,0xe3,0x15,0x98,0x6f,0x50,0x6c,0x8d,0xa7,0xe6 +.byte 0xa8,0x39,0xcc,0x63,0x08,0xeb,0x8f,0x8c,0xfd,0x83,0xaa,0x34,0x75,0x19,0xc0,0xf4,0xd6,0x25,0x18,0x94,0x9d,0xa1,0x7e,0xc8,0x6b,0x19,0x76,0xc0,0x8d,0xaf,0x51,0xe5,0x7c,0x8a,0x98,0x17,0x80,0x90,0xc0,0xb6,0xed,0x5c,0x8f,0x33,0x56,0xba,0xce,0xbe,0x83,0x87,0x5d,0x51,0x2e,0x64,0x84,0xa6,0x9d,0x49,0x27,0x5b,0x92,0xe0,0xe7,0xac +.byte 0x37,0x3d,0x22,0x5e,0x25,0xe7,0xca,0x2f,0x5d,0x2f,0xa0,0xd5,0xcb,0xe9,0xac,0x84,0x5b,0x19,0x72,0x1c,0x2c,0x0a,0xd1,0xb7,0x73,0x24,0x8a,0x0f,0xe0,0x07,0xd8,0x49,0x4d,0x23,0x1b,0xac,0xb8,0xd1,0x42,0xd4,0xdf,0xf8,0x4d,0x85,0xa2,0x37,0x30,0x46,0x38,0x88,0x55,0x1d,0xea,0x37,0x54,0x8c,0x43,0xb0,0xed,0x01,0x53,0x75,0xe6,0xf7 +.byte 0x9b,0xe6,0x10,0x91,0x6e,0x80,0x11,0xf9,0x96,0x29,0x4f,0x08,0x77,0x2b,0x7e,0xdb,0x5b,0x14,0xbd,0x77,0x37,0xe8,0x36,0x07,0x4a,0xe4,0xd8,0xa2,0x4e,0x38,0xea,0xeb,0xc2,0xd6,0x43,0x59,0x20,0x0c,0x12,0x31,0x6c,0x27,0xc5,0x7b,0xfc,0xfc,0x54,0x94,0x1d,0x5f,0x82,0x73,0xd7,0x1f,0x43,0x3a,0x73,0xc4,0xf3,0xb3,0xbb,0x53,0xfe,0x22 +.byte 0xc0,0xa4,0x7e,0x2b,0x84,0x1b,0xef,0x6d,0x83,0x9d,0xb3,0x8b,0x2a,0x6c,0xea,0x1e,0xfa,0x77,0x01,0x35,0xd2,0x5b,0xc4,0xd3,0xe7,0x1e,0xca,0x73,0x8b,0xb9,0x1f,0xfb,0x67,0xf2,0xdd,0x03,0xe6,0xca,0xfe,0x3b,0x61,0xd7,0xb5,0x96,0xe0,0x85,0xc2,0x23,0xa7,0xea,0x38,0xbf,0x6e,0x29,0x9e,0x8e,0x18,0xd4,0xbf,0x16,0x73,0xf9,0x18,0xef +.byte 0xc9,0xaf,0x6c,0xe2,0xdc,0xa4,0x58,0x9c,0xf5,0x6d,0x4a,0xc8,0xb4,0x8f,0x16,0x02,0xb7,0x65,0xd3,0x32,0x3b,0x83,0xfe,0xf3,0xc7,0xba,0x68,0xf4,0x95,0xa4,0xf6,0x33,0x57,0x43,0xbe,0xae,0x83,0xa9,0xe4,0x0d,0x0b,0x23,0xaa,0xbc,0x15,0x53,0x18,0x4d,0xb4,0x35,0xe3,0x8e,0x86,0xfe,0xe4,0x98,0x5d,0x63,0x23,0xce,0x44,0xea,0x4d,0x64 +.byte 0x86,0xf8,0x06,0x8f,0xc0,0x73,0xa6,0x6d,0x04,0x53,0x47,0x95,0x0f,0x6d,0x6c,0x01,0x1c,0x3f,0x7b,0x83,0xe4,0xc2,0x40,0xb8,0x97,0x26,0x9e,0x35,0xb0,0x76,0xee,0xe4,0xc7,0xd8,0xaa,0x22,0x83,0x96,0xe1,0x34,0x7b,0x78,0x31,0xee,0xd3,0x9a,0x50,0xd4,0x05,0xfd,0xd6,0x15,0xca,0x83,0x2f,0x49,0xfd,0x00,0x23,0x82,0x39,0xac,0x46,0x7a +.byte 0xe4,0xb5,0xcc,0xee,0xbb,0xaa,0x98,0x82,0xb5,0x27,0x45,0xd5,0x96,0x6e,0x89,0x01,0x1e,0x30,0xe4,0x1c,0x3a,0x65,0xcc,0x9f,0xda,0x38,0xf0,0x4c,0x68,0xfa,0xe5,0xf2,0xe2,0xce,0x34,0xc2,0x15,0xfd,0x21,0xf6,0xe2,0x33,0xbd,0xef,0xfd,0x49,0x15,0xdc,0x38,0x3b,0x24,0xba,0x3a,0x80,0x35,0x60,0xbe,0x50,0x17,0x38,0x3e,0xe2,0x96,0x84 +.byte 0x01,0x41,0x6c,0xb2,0x0b,0xc6,0xff,0xce,0xb3,0x37,0xa2,0x46,0x27,0x33,0x8e,0x04,0x44,0x8a,0x7c,0x64,0x0e,0xbc,0xed,0x74,0x4f,0x40,0x58,0xf4,0x8c,0xf8,0xd9,0x92,0xa9,0x0b,0x18,0x7c,0x93,0x95,0xca,0xa7,0x3e,0x1d,0xad,0x68,0x80,0xd9,0xdb,0x81,0x78,0x50,0x37,0x49,0xbc,0x64,0xc2,0x52,0x5c,0x70,0x7e,0x0a,0x26,0x7e,0xc6,0xbf +.byte 0xd2,0x7f,0x05,0x55,0x7a,0x5a,0x3e,0x9e,0xe3,0x8b,0xf5,0x95,0x2b,0xd8,0xb4,0xb8,0xc6,0x5d,0x91,0xb8,0xc7,0x7c,0xe1,0x75,0xf2,0x43,0x6b,0x73,0xb7,0xb1,0x10,0xf2,0xa7,0x1e,0xab,0xaf,0xc9,0xc0,0x3b,0xab,0xbe,0xf7,0x4a,0x43,0x9c,0xca,0x3d,0x00,0x5b,0x02,0xf8,0xa2,0x4f,0x57,0x81,0xb0,0xde,0x1e,0xd1,0x60,0xbe,0x6c,0x0d,0xe6 +.byte 0xcd,0x51,0xb6,0xc7,0x00,0x52,0x37,0x4f,0xfc,0xee,0xe2,0x43,0x5c,0x61,0x76,0xed,0x80,0x72,0x38,0x26,0x94,0xfe,0x28,0x06,0xfb,0x62,0xa6,0x21,0x9b,0x53,0x60,0x1b,0xf0,0x56,0xae,0xba,0x6b,0x52,0x27,0x2a,0xd5,0xed,0x11,0x92,0xa2,0xe2,0xab,0xdd,0x05,0x38,0x38,0xae,0xeb,0x72,0xcb,0x6c,0xa5,0x2a,0x73,0xc5,0xfc,0xb0,0x36,0x83 +.byte 0xd6,0xe6,0xda,0x6b,0x38,0x72,0x5e,0x8d,0xaf,0x11,0x5f,0x5b,0x89,0x58,0x21,0x36,0xf6,0x7d,0x42,0x48,0xdc,0xce,0xaa,0x94,0xf0,0xc3,0xc5,0x2c,0x08,0x2a,0x36,0x35,0x25,0x95,0xc4,0x11,0x09,0xea,0x7a,0xbc,0x2e,0xc6,0x0a,0x5b,0x4f,0x86,0xeb,0xc2,0x38,0x71,0x48,0x8c,0x63,0x79,0x3b,0xe4,0xba,0x14,0x44,0x31,0x28,0x4f,0x9d,0xb4 +.byte 0x26,0xa6,0x3b,0xea,0x3f,0xcb,0x30,0x6c,0x02,0x13,0xdb,0x4c,0x9c,0x76,0xc8,0xd8,0x01,0x52,0x3d,0x2f,0x51,0x70,0x15,0x91,0xec,0x8f,0x80,0xed,0x88,0xb7,0xfa,0x91,0x2c,0x10,0xcd,0x3b,0x92,0x85,0xe7,0xe8,0x11,0xfa,0x50,0x15,0xe2,0xdf,0xf7,0xbe,0xa4,0x2d,0x13,0x75,0xa6,0x00,0x25,0x8d,0xe1,0xb6,0x9b,0xbb,0x64,0xfb,0x5c,0xde +.byte 0x97,0xcc,0x00,0x51,0xd6,0xac,0x67,0xc3,0x91,0x1e,0x56,0x36,0x2b,0x43,0xed,0x8c,0x67,0x7b,0xf6,0x54,0x6f,0x91,0x44,0x28,0x93,0x60,0xac,0xca,0xb9,0x91,0x7e,0xeb,0x49,0xd8,0xfc,0x12,0x6c,0x40,0x9d,0x0a,0x4d,0xb4,0xab,0xe6,0xad,0x5b,0x8e,0x2d,0x3e,0x53,0xa1,0x88,0xf7,0x41,0x71,0xa7,0xff,0x05,0x46,0x04,0x34,0x1f,0x12,0x89 +.byte 0x92,0xc1,0xf9,0x26,0x16,0x23,0xb6,0x59,0x82,0xdc,0xa7,0xb8,0xa4,0x8a,0x0f,0x1d,0x7d,0x8f,0x44,0xe8,0x4f,0x70,0xbb,0xdb,0x8d,0xe6,0x7e,0x9d,0xd9,0x44,0x10,0x41,0x6c,0x3f,0xb7,0xe8,0x6f,0x39,0x93,0xe1,0xde,0xb8,0x6c,0xba,0x99,0x95,0xb7,0xc8,0xb2,0x2a,0xcd,0x81,0x53,0xc3,0xb5,0x2a,0x8a,0xd6,0x62,0x1e,0x74,0x4d,0xde,0xfa +.byte 0xff,0x7b,0xed,0x11,0x1e,0x44,0x3e,0x93,0x1c,0xae,0x7c,0x5c,0xed,0x52,0x75,0x5e,0x0a,0xf3,0x95,0xce,0x47,0x86,0x1b,0x7f,0x17,0x09,0x12,0xcc,0x08,0xca,0x16,0x11,0xf1,0xa1,0x39,0x78,0x89,0x5c,0x11,0x25,0xc7,0x39,0x5f,0x97,0x74,0xbc,0xa9,0x2a,0x25,0x5d,0xdd,0x93,0x0d,0x8c,0x74,0x07,0x1e,0xd9,0x9f,0xc1,0x38,0x9c,0xbf,0xe0 +.byte 0x42,0xad,0xb2,0xe7,0xb1,0x84,0x82,0xb4,0x56,0xbe,0x3c,0x42,0xb0,0xce,0x2c,0x94,0xb7,0xe6,0x78,0xc8,0x04,0x06,0x58,0x15,0x3e,0xdc,0xf6,0x9a,0x58,0xc3,0xe3,0x85,0x16,0xc8,0x84,0xba,0x8f,0xbc,0x94,0xa7,0x44,0x04,0x29,0xc4,0xd8,0xec,0x63,0xc4,0x47,0x58,0x22,0x02,0x08,0x20,0x44,0x39,0x52,0xa5,0x33,0xfe,0x1c,0x30,0x27,0x92 +.byte 0xbf,0x42,0x44,0x4c,0x3f,0x3d,0x00,0x7b,0x21,0xef,0xbb,0x25,0x75,0x4c,0xb2,0xe7,0x66,0xc9,0xc1,0xfb,0x1e,0x13,0x04,0xd0,0xcb,0x69,0x51,0x9d,0x9a,0xb0,0xb0,0xec,0xb0,0x12,0x24,0x84,0x57,0x9f,0xef,0xb4,0x19,0x50,0xa6,0xf5,0x03,0xa3,0x93,0x0f,0x77,0xaf,0xe0,0x4c,0xa5,0xd3,0xb0,0xd8,0x5e,0xc3,0x78,0x94,0xd5,0x6e,0x48,0x58 +.byte 0x7a,0x93,0xb1,0x62,0x60,0xea,0xa1,0xba,0x7a,0x86,0x6e,0x87,0xe9,0x97,0xe0,0x7c,0x1e,0xb6,0x63,0x94,0x76,0x5f,0x9c,0x95,0x65,0x00,0xd4,0x14,0x0e,0x4c,0x87,0xe7,0xcd,0x9e,0xb1,0xe2,0x13,0x1b,0xb1,0x8a,0x83,0xaa,0xaa,0x34,0xcd,0xb2,0xf6,0x7f,0x12,0xb0,0x79,0xff,0x1e,0x04,0xc8,0x9a,0xfc,0x41,0x88,0xbb,0x28,0x42,0xeb,0x45 +.byte 0x47,0x8b,0xcb,0x57,0x03,0xcd,0xe5,0x9a,0x84,0xea,0x0a,0xb5,0x0c,0xb8,0x30,0x33,0xd6,0xde,0x66,0xa8,0x57,0xf9,0x76,0x4f,0x0f,0x8f,0x53,0x56,0x57,0x91,0xd4,0x55,0xf5,0x78,0xde,0xa6,0xa2,0x59,0xc8,0xb0,0xf2,0xb9,0xfa,0x6d,0x4a,0x70,0x86,0x3d,0x24,0x1b,0xc6,0xb8,0x06,0xf5,0xea,0x09,0x63,0x9b,0x1e,0x61,0x18,0x85,0xba,0x08 +.byte 0x20,0xaa,0x33,0x66,0xcf,0xa7,0xff,0xf5,0x30,0xfe,0xf8,0x39,0xd3,0x88,0x9a,0x5b,0x3f,0x55,0xa6,0x00,0x4c,0x57,0x0d,0xd1,0xa4,0x0c,0xe7,0x8a,0x95,0xd8,0x64,0xc7,0x93,0x51,0x84,0xa6,0x41,0x2c,0xfc,0xb0,0xfb,0x99,0x9a,0xcd,0x2c,0x62,0x3a,0xca,0x43,0x15,0xf2,0x5a,0x22,0x25,0xa4,0x91,0xa3,0x7c,0x42,0x69,0xc1,0x67,0xe3,0xf5 +.byte 0xd4,0x92,0x54,0xbd,0xb3,0x57,0xe5,0x19,0xca,0x1b,0x9c,0x19,0x79,0x9d,0xbf,0x89,0xfc,0xaa,0x72,0xcd,0xcb,0xc5,0xbc,0xdd,0x0c,0x7c,0x31,0x42,0xb0,0xc2,0x76,0xe5,0x8b,0x9b,0x7c,0x92,0x13,0x20,0x5c,0xdc,0x94,0xfc,0xa1,0x90,0x34,0x27,0x88,0x9f,0xe5,0x97,0x5f,0xc3,0xa3,0x83,0xca,0x8b,0xf8,0xac,0x36,0x33,0x47,0xc6,0x20,0x2f +.byte 0x04,0x2d,0x13,0xc1,0x3c,0x07,0x6e,0xf0,0xe2,0x3d,0x32,0x5c,0x50,0x41,0xf2,0x92,0x3f,0x25,0x2c,0x80,0x34,0xa5,0x90,0x2b,0x97,0x6e,0xd1,0xa2,0xa6,0xf4,0x4a,0xe0,0x20,0xd9,0xb9,0x2b,0x66,0xe5,0x06,0x73,0x97,0xfe,0x80,0x70,0x28,0xf9,0xb6,0xae,0x93,0x27,0x7a,0x65,0xff,0x23,0xc1,0x78,0x18,0x92,0xc9,0x0b,0x05,0x82,0x93,0xbc +.byte 0x73,0x3f,0x98,0xe9,0xa0,0x6d,0x20,0x8d,0x13,0xb1,0xf0,0x7e,0xe4,0x07,0x21,0x7d,0x6d,0xea,0x03,0x59,0xf8,0x29,0xc0,0xc8,0x7d,0xce,0xd1,0xf8,0x67,0x82,0x7f,0x84,0xe8,0x77,0xa9,0x9c,0xa2,0x34,0xdf,0xa9,0xac,0xec,0x6d,0x54,0xe5,0x0f,0xcb,0xdb,0x86,0xbc,0x01,0x44,0x91,0x3b,0xc8,0x85,0x4e,0x1d,0xe4,0x74,0x19,0xc6,0x39,0x2e +.byte 0xdf,0xf2,0x8f,0x3a,0x7f,0xe3,0x1e,0x55,0x45,0xcb,0x7e,0xde,0xcd,0xa6,0x1c,0xef,0x20,0xf7,0x07,0x31,0x94,0x9a,0x3d,0x04,0xd7,0x5e,0x65,0x20,0x6a,0x4d,0x31,0x1e,0x6f,0x89,0x40,0x45,0x1f,0x37,0xc1,0x7e,0x07,0xd5,0xa6,0x38,0x4a,0xf1,0x39,0xae,0x72,0x26,0x60,0xb0,0xb5,0xc7,0xd3,0x9a,0xaf,0x57,0x12,0xe9,0x34,0x28,0x8b,0xaf +.byte 0xd8,0x62,0x24,0x58,0xe2,0xcd,0xa2,0x9e,0x74,0x23,0x2d,0x52,0xc7,0x09,0xe5,0xb5,0xf5,0xc1,0xd3,0xa3,0x19,0xe5,0x1d,0x8d,0x0c,0xdf,0x13,0x8d,0xa4,0xa7,0xc1,0x41,0xea,0x9e,0x6d,0x61,0xd4,0xa4,0x74,0xe5,0xf8,0x5f,0x9e,0xfd,0x6d,0xf6,0x6e,0x87,0x0f,0xb5,0xa3,0x82,0xac,0x64,0xb4,0xda,0x07,0x49,0x51,0xc2,0xfd,0xcb,0x55,0xa3 +.byte 0x59,0x34,0xdf,0xa1,0xd6,0x90,0x62,0x43,0x1a,0xf9,0xae,0x85,0x5c,0x11,0x40,0xb2,0xbe,0xa5,0x03,0x04,0x4f,0xec,0x2c,0x58,0x2d,0xe9,0xda,0xcf,0xaa,0x2f,0xcf,0x60,0xc3,0x2c,0x6c,0x81,0x4d,0xf2,0x71,0x41,0xe4,0xae,0x4c,0xfa,0x8e,0x05,0x10,0xff,0x40,0xfa,0xea,0x96,0x78,0x6e,0xfc,0x35,0x35,0xec,0x84,0xf6,0x1d,0x24,0x60,0xcd +.byte 0x96,0x21,0x21,0xa7,0x32,0x90,0x3d,0x51,0x72,0x13,0xa4,0x9b,0x7e,0x94,0x3a,0x9d,0x97,0xf6,0x68,0xd8,0x08,0x42,0x54,0x7a,0xbb,0x9a,0x95,0x83,0xac,0xb8,0xb4,0x68,0xe3,0x31,0xdb,0xe2,0x32,0x8b,0x7d,0x57,0x62,0x1d,0x61,0x81,0xa1,0x36,0x7a,0x25,0x00,0x72,0x24,0x4c,0xa7,0x96,0x3b,0xa5,0x82,0xba,0x8e,0x89,0x1e,0x1b,0x8e,0xf4 +.byte 0xab,0x91,0x85,0x7a,0x32,0x4a,0x47,0x9f,0xce,0xd2,0x51,0x77,0xcd,0xc9,0x02,0x54,0xf2,0x7b,0xcb,0xb8,0x83,0xe0,0xe0,0x1b,0x4a,0xa2,0xe0,0xd9,0x15,0xb6,0x02,0x19,0x75,0xa6,0xba,0xa6,0x98,0xd9,0x61,0x74,0xc6,0x48,0xa5,0x59,0x3d,0xc8,0x47,0xc9,0xe8,0x6b,0xbb,0x6d,0xcf,0x0e,0x8d,0x6b,0x58,0x8b,0x7d,0x4e,0x0b,0x3d,0x67,0xc4 +.byte 0x8e,0x78,0x59,0x40,0x88,0x82,0x33,0x27,0x2c,0xfe,0x2a,0x6c,0xe4,0x80,0xee,0x5a,0xd4,0x5f,0xc8,0xf7,0x82,0x02,0x67,0xfd,0xcb,0x55,0x3e,0xd8,0x41,0xb3,0xce,0x93,0xfe,0xe7,0x56,0xf5,0x63,0xba,0xfa,0x2e,0x79,0xfc,0x11,0x5d,0xb0,0xc6,0x32,0x54,0xed,0x71,0x9b,0x15,0xce,0x62,0x09,0xd4,0x28,0x7f,0x7b,0xa1,0x50,0x5b,0x46,0x24 +.byte 0x0e,0x40,0xa2,0xe2,0x7d,0x93,0xa6,0x2b,0x0b,0x9b,0x40,0x25,0xc9,0xca,0x7a,0x01,0x8b,0x7d,0x68,0xeb,0xd7,0x84,0xc1,0x9d,0xf9,0xfb,0xd0,0x1a,0xec,0xef,0x6b,0x4c,0x78,0x31,0x62,0x8e,0x9d,0xdc,0x78,0x8f,0xcb,0xf8,0xf9,0x41,0xdc,0x9f,0x6d,0x0a,0x27,0x67,0xce,0xbd,0xeb,0x87,0xb3,0x26,0xf3,0x51,0xe1,0xd6,0xd1,0x57,0x46,0xfe +.byte 0x21,0xb9,0x88,0x7c,0xdd,0xa2,0x49,0x71,0x24,0xfb,0xc4,0xc0,0x6a,0x6b,0x05,0x7f,0x80,0xb0,0x09,0x3b,0x9e,0x6c,0x59,0x31,0x3e,0xac,0x7a,0x2e,0x5c,0x04,0x03,0xa3,0x6e,0xf5,0x66,0xee,0xc2,0x9b,0x65,0x88,0x06,0xbf,0xf5,0xe3,0x23,0x73,0x38,0x88,0x99,0xf1,0x64,0x68,0xdf,0x7d,0x04,0x06,0x72,0x92,0x0b,0x62,0x5d,0x12,0x1e,0x4e +.byte 0xff,0x60,0x35,0xe3,0x0f,0xd9,0x8c,0xac,0x38,0x5b,0x91,0xc1,0x51,0xbb,0xa5,0x19,0x7d,0xfb,0x79,0xfa,0x42,0x3b,0xaa,0xf8,0xd3,0x0f,0xc3,0xf2,0xb2,0x68,0x91,0xae,0x28,0x83,0x4f,0x75,0xbd,0x20,0x5f,0x20,0xba,0xc2,0x75,0x85,0x74,0x23,0xf3,0x36,0x33,0x99,0x9c,0x64,0x4c,0xd1,0x5d,0xbd,0x06,0x46,0xbd,0x49,0xf0,0x86,0xc0,0xcb +.byte 0x1b,0xbd,0xec,0x98,0x5b,0xb1,0x80,0xba,0x12,0x42,0x22,0x09,0x9a,0x62,0x3c,0xa8,0x33,0xbf,0xce,0x92,0xd4,0x07,0xef,0x34,0x33,0x8f,0x67,0x1d,0x25,0x60,0xeb,0xd3,0xe4,0x31,0x63,0xa8,0xab,0xe3,0xab,0x70,0x50,0xd8,0x44,0x9f,0x39,0x51,0xd2,0xb9,0x4b,0x16,0xe4,0xfa,0xc5,0x47,0xf3,0xae,0xb5,0xfe,0x7d,0x5d,0x43,0x28,0xa6,0x3d +.byte 0xcf,0x71,0x23,0x6d,0x8e,0xd7,0x74,0xa4,0x86,0x9f,0x92,0x86,0x3c,0x1e,0x51,0xd4,0xe0,0xe6,0xd5,0xc4,0x53,0x3c,0x96,0x55,0xb9,0xac,0x63,0x5b,0xee,0x5a,0x03,0x84,0xb9,0x43,0x2c,0x0f,0x6d,0xbb,0xb5,0xca,0xf0,0x4f,0x3e,0x8b,0x3b,0x14,0x01,0x0e,0x81,0x0d,0xe6,0x62,0xa9,0x34,0x4e,0x03,0xc9,0x85,0x9f,0xc8,0x4f,0x52,0x3f,0x84 +.byte 0x1b,0xab,0x7e,0xaf,0x93,0x22,0xe2,0x0d,0x41,0x79,0x50,0xb2,0x17,0xa7,0x9a,0x80,0xd5,0x65,0x40,0x3b,0x56,0x9b,0xc9,0x00,0xcf,0x03,0xf1,0xff,0xcd,0x72,0x27,0xdb,0x74,0x94,0x70,0x02,0xdc,0x3a,0xee,0x00,0xcc,0x08,0x0a,0xab,0x40,0x87,0x24,0xaf,0x7d,0x67,0x18,0xd0,0x7c,0xeb,0x91,0x1f,0x7e,0x9e,0x41,0x7b,0x39,0xf2,0xfe,0xaf +.byte 0xb7,0x6c,0x58,0xe0,0xdb,0xf7,0xf1,0x23,0x0b,0x98,0x08,0xfa,0xde,0xfa,0xf9,0x24,0x23,0xd1,0x7f,0x69,0xd3,0xb1,0x82,0x68,0x03,0x06,0x86,0x7a,0xf4,0x90,0x8d,0xa5,0xbd,0xbe,0x14,0x2f,0xa2,0x5e,0xaf,0x5c,0x1e,0x07,0x68,0x19,0x5a,0xd3,0x53,0x7d,0xe8,0x13,0x6b,0xe3,0x02,0x49,0x0d,0xd2,0x96,0x56,0xae,0x67,0x8a,0x27,0x61,0xa0 +.byte 0x60,0x20,0x2c,0xb4,0x5d,0xdf,0xc3,0x24,0x50,0xa9,0xbc,0x3d,0x5c,0xf3,0x2e,0xb6,0xba,0x71,0xf0,0x04,0x43,0x84,0x4d,0x80,0xe9,0xa5,0xdd,0xb3,0x1e,0x5e,0x56,0x32,0x1a,0xd4,0xe3,0x10,0x57,0x35,0xa8,0xf1,0xe5,0x96,0xc1,0x27,0xef,0xcc,0x21,0x71,0x10,0xd1,0x07,0x7e,0xb3,0xab,0x95,0x64,0x86,0xaf,0xc9,0x15,0xe6,0x98,0x5e,0xb1 +.byte 0xbd,0xde,0x99,0x38,0xfc,0x8d,0xb2,0x5a,0xa4,0x44,0x5b,0x74,0x31,0x31,0x07,0x93,0xf5,0x86,0x78,0xc5,0x82,0x26,0xfc,0x95,0x1f,0x33,0xd8,0xfe,0x70,0x42,0x2a,0xa7,0x3a,0xb1,0xb2,0x63,0xd6,0x5b,0x54,0x9c,0x54,0x45,0x4f,0x1b,0x4a,0xc2,0xb4,0x0e,0x99,0x48,0xde,0x8d,0xa6,0x5d,0xd3,0xdc,0x31,0xa4,0x2b,0x0d,0x44,0x6e,0x1a,0x10 +.byte 0x3f,0x6c,0xa0,0xab,0xcb,0xb4,0xf6,0x18,0xba,0x11,0xd4,0xd4,0x70,0xc4,0xab,0x04,0x4c,0xe7,0xe9,0x53,0xe5,0xd9,0xe7,0xeb,0x21,0xa2,0x2c,0xc4,0xc6,0xc3,0xe7,0x73,0xd9,0xd3,0x84,0xb0,0x12,0x94,0x3b,0xfd,0xd9,0x32,0xba,0xe3,0x37,0xc1,0xb9,0x4d,0xea,0x3e,0x3d,0x31,0x4e,0xa0,0xe7,0x73,0x9d,0x4e,0x26,0xd1,0xdf,0xe6,0x26,0xcd +.byte 0xd7,0x17,0xd7,0x28,0x2c,0x04,0xe9,0x55,0xd5,0x70,0xaf,0xab,0xc1,0x07,0xbc,0xc4,0xd2,0x89,0xdc,0x22,0x59,0x19,0x0e,0xd8,0x8b,0xdd,0x46,0x7f,0xe4,0xad,0xa5,0x70,0xd7,0x18,0x51,0x30,0xd7,0xbc,0x26,0x45,0xe7,0xea,0xce,0xc7,0xf2,0xca,0xb1,0x9c,0x57,0x1e,0x10,0x5f,0x44,0x8d,0x3d,0xe8,0x55,0xa1,0x22,0x68,0x97,0xe8,0x03,0x9c +.byte 0x8b,0x63,0x81,0xd9,0xcd,0x4c,0x6c,0xe3,0x68,0xc9,0x35,0xee,0x94,0x13,0x25,0x0b,0x12,0x61,0xbd,0xee,0x6f,0xc7,0xe8,0xb5,0x01,0x7a,0x9e,0xd0,0x5a,0x46,0xc6,0x19,0x1b,0xc2,0xf1,0x2d,0xaa,0x53,0x29,0xcf,0x23,0x1a,0x4d,0x94,0x0a,0x50,0x64,0xf5,0x3b,0x52,0x55,0xac,0xa5,0x21,0x15,0x47,0xd9,0x14,0x8c,0x7f,0x4d,0x79,0x6b,0xc1 +.byte 0x43,0x0a,0xf2,0x42,0xd2,0xb0,0x95,0x19,0x99,0xdd,0x1d,0x8e,0x84,0x8c,0x7e,0x59,0x69,0x93,0x86,0xae,0xf1,0x67,0x35,0x55,0x7c,0x5b,0x38,0x11,0x56,0xec,0x6c,0xbb,0xe8,0xc0,0x54,0xec,0x5f,0x65,0x13,0xe3,0x86,0xa0,0xb1,0xc1,0x5e,0x34,0x4f,0xdd,0x4d,0x00,0xc6,0x29,0x05,0x78,0x64,0x8c,0x19,0xb0,0xfc,0x8a,0xb2,0xc7,0x86,0x57 +.byte 0xa2,0xdd,0xed,0x43,0xc1,0x7f,0xab,0x89,0x19,0xe8,0xa6,0xf5,0x7a,0x15,0xfe,0xd5,0x4f,0x53,0xde,0x78,0x42,0x76,0xf7,0x8a,0x54,0xe8,0x37,0xfd,0xee,0x82,0x20,0xd5,0xe2,0x32,0xb9,0x32,0x67,0xc7,0xff,0xdc,0xf0,0x40,0x07,0x28,0x55,0x16,0x56,0x84,0xe9,0x17,0x25,0x17,0x8e,0x10,0xef,0x9f,0xed,0x33,0x83,0x6d,0x9e,0x87,0x82,0xb8 +.byte 0xa9,0x6b,0xcb,0xe5,0x04,0xfb,0x87,0x51,0x05,0x1a,0x64,0x64,0x51,0x34,0xa3,0x61,0x4a,0xe3,0xa6,0x35,0xa5,0xc9,0xe3,0xde,0xb0,0xcf,0x5f,0x68,0x49,0xbc,0x98,0xf9,0x0b,0x82,0xde,0xb1,0xf9,0x77,0x16,0x7c,0x1f,0x80,0x0c,0xfc,0xbb,0x6d,0x8e,0x92,0x93,0x00,0xc2,0xa5,0xbe,0xde,0x55,0x09,0x9d,0x83,0xa5,0x6c,0x0a,0xb5,0xc4,0x53 +.byte 0xde,0xbc,0x07,0xca,0x0f,0x43,0xea,0x50,0x25,0xee,0x51,0x3b,0xfb,0x7a,0xcf,0x31,0x8a,0x19,0x1c,0xa2,0x2d,0x72,0x79,0x81,0xc6,0xb8,0xe6,0xe1,0xd8,0x3e,0x0f,0xc0,0xae,0x73,0x40,0x30,0x15,0xaa,0xe3,0x72,0xc3,0x36,0xc1,0x42,0x11,0xc5,0x3f,0xf5,0x69,0x78,0xea,0x95,0x54,0x36,0xe8,0x7e,0x9c,0xad,0xbd,0xcd,0x19,0xfe,0x4a,0x04 +.byte 0xb4,0x54,0x14,0x98,0x58,0x6f,0x06,0x8f,0x8c,0x95,0xa8,0xc9,0xe8,0xc4,0x2b,0x03,0xaa,0x42,0x75,0x74,0xa2,0x63,0xdb,0xca,0xd1,0xf0,0x60,0xc3,0x63,0x84,0xfb,0xd7,0x5a,0x7b,0xca,0x45,0x8d,0x14,0xdc,0xf8,0x71,0x40,0x71,0xbb,0xa1,0x1a,0xd3,0x8c,0xfb,0xf6,0xf7,0xfc,0x82,0x72,0x50,0xc9,0xe3,0xc5,0xe2,0xb1,0x57,0xb1,0x24,0x3e +.byte 0x11,0x4d,0x96,0x1c,0x3a,0xe1,0xb6,0xb7,0x0e,0x55,0x35,0x6c,0xd8,0x2b,0xe3,0x78,0xcd,0xac,0x8f,0x24,0x70,0xc6,0x35,0x5b,0x6e,0x75,0x7a,0xf1,0x7d,0x87,0x53,0xcf,0x0a,0x24,0xb6,0x6a,0xfd,0xef,0x90,0x07,0xcf,0xde,0x30,0xbc,0x8c,0xec,0xda,0x6f,0x45,0xad,0x92,0xb6,0x8d,0x6b,0xb8,0x8e,0xdc,0xe5,0xbf,0x57,0x67,0x5e,0x2f,0x4d +.byte 0x5d,0xee,0x38,0x0a,0xaf,0xeb,0x62,0x84,0x2b,0x4c,0x30,0x7b,0x91,0x99,0x40,0x6f,0x09,0x2b,0x36,0xcd,0x04,0xeb,0x7c,0x8d,0xa5,0xbd,0xd6,0xb0,0xfc,0x27,0xcf,0x6b,0xdd,0xe1,0x94,0xbc,0x21,0xc6,0xc9,0x55,0x24,0xd4,0xa1,0x6f,0x1e,0xa2,0x81,0x31,0x22,0xb7,0x75,0x9e,0xa7,0x01,0x26,0x01,0x6c,0x12,0x91,0x02,0x87,0x40,0x5c,0x91 +.byte 0x1f,0x0c,0x55,0x07,0x12,0xa7,0x48,0xdd,0xed,0xb6,0xfe,0x38,0x05,0xbc,0xe1,0x2e,0x3b,0x89,0x4f,0x98,0x65,0x22,0x93,0xda,0x09,0x9f,0x04,0x90,0x66,0x81,0xd1,0x56,0x27,0x8b,0x26,0x99,0xbe,0x93,0x08,0xf1,0xfb,0x80,0x5b,0xaa,0xc4,0x96,0x88,0x93,0xb6,0x01,0xae,0xf6,0x69,0xaa,0x6f,0x4d,0xde,0x2f,0xc7,0x24,0xbf,0xe9,0xb8,0xeb +.byte 0xcd,0xb2,0x0a,0x50,0x5c,0xd2,0x0b,0xfc,0x57,0x3b,0x96,0xf8,0xd9,0xbe,0xd2,0xb5,0x16,0xac,0x7c,0xe4,0x2f,0x46,0x93,0x86,0x48,0x91,0xfa,0xae,0xca,0x05,0x9e,0xfe,0x6e,0xae,0xa5,0x58,0x94,0xc0,0x58,0x1e,0xc5,0x69,0x28,0xe0,0x99,0x12,0x83,0xcf,0x35,0xe4,0x72,0x7d,0x4e,0x8b,0x66,0x56,0xb3,0xa6,0x2a,0x72,0x06,0x03,0x45,0xd1 +.byte 0x95,0xc9,0x93,0xb7,0xf4,0x8a,0x83,0xce,0x17,0x8b,0xf0,0x8e,0x8f,0x4a,0x68,0x55,0xd8,0xfc,0x54,0x8d,0xb5,0x62,0x17,0xa8,0xe6,0x18,0x03,0x53,0x04,0xb8,0xbe,0xd2,0xd0,0x7a,0x84,0xe1,0x39,0x31,0xc5,0x74,0xf2,0x64,0x1c,0x3b,0xd5,0x52,0x9b,0x81,0x8a,0x8f,0x36,0xc8,0xab,0x3d,0xe1,0xa8,0x2a,0xf2,0x84,0x9a,0xca,0x0c,0xcf,0xc9 +.byte 0x45,0x54,0x06,0xe8,0xd2,0x62,0x61,0x4d,0xeb,0x0b,0x38,0x4e,0x43,0x59,0x85,0x3a,0xe4,0xa3,0x25,0x15,0xc2,0xb5,0x7b,0x5e,0x2f,0xe6,0xc1,0x5d,0x2a,0xb7,0x57,0xb8,0x7e,0x61,0x51,0xc3,0x81,0x53,0x45,0x8a,0x6e,0x4c,0x89,0x84,0x2a,0x6b,0xca,0x15,0xff,0x97,0xfc,0x1f,0x8a,0x44,0xbd,0xcd,0x5e,0x32,0x6b,0x5f,0x78,0x7b,0xdf,0xdd +.byte 0x9d,0x2f,0x21,0xf2,0x14,0x40,0x5f,0x5a,0xd5,0x21,0x27,0x3d,0x0b,0x9f,0x9f,0xb0,0x8e,0xab,0x9e,0x68,0x96,0x02,0xfd,0x4d,0xcc,0x03,0xf0,0x03,0xfb,0x4c,0xac,0xfa,0x00,0x3b,0xea,0x1a,0x53,0x80,0x77,0xec,0x53,0xc3,0x3c,0x6c,0xf8,0xa5,0x3e,0x52,0x34,0xd4,0xa1,0x52,0xb8,0xd6,0x19,0x8c,0xdf,0x85,0x27,0x61,0x22,0xe7,0x43,0xeb +.byte 0x85,0xc0,0xbe,0x58,0xe6,0x60,0x81,0x4c,0xc6,0xbb,0xc0,0xbf,0x63,0x39,0x9d,0xad,0x2e,0xa8,0x2a,0x83,0x3d,0xfa,0xdb,0x0b,0x98,0x16,0x78,0x18,0x43,0xc7,0x17,0x82,0xb8,0xec,0x32,0x45,0x75,0x0c,0xc1,0x4c,0x84,0xbf,0xce,0x83,0x3b,0xb4,0x91,0xf4,0x0d,0x5d,0x83,0xf6,0xd6,0x10,0xab,0xc6,0x26,0x9b,0x68,0x59,0xec,0x48,0x4b,0x1d +.byte 0x35,0x2a,0x5b,0x23,0x83,0x22,0x8e,0x7d,0xfa,0xce,0xde,0xb1,0xd9,0x78,0xf6,0x9e,0x08,0xba,0xfb,0xda,0xf2,0x04,0xc5,0x2a,0xac,0xbf,0xb4,0x04,0x05,0x1f,0x0b,0xeb,0xe8,0x2a,0x3c,0x3f,0x4f,0xb6,0xc8,0x6b,0x97,0x5a,0x9e,0xdb,0x4b,0x3c,0x93,0xc1,0x20,0x1c,0x62,0x91,0x74,0x76,0x49,0x92,0xc2,0xd8,0x0d,0xd8,0xfe,0xb5,0x68,0x77 +.byte 0x48,0x9f,0xbe,0xe0,0x78,0x20,0xe7,0xa4,0x3d,0x3e,0xa1,0x4c,0xc7,0xeb,0xd3,0x30,0xd3,0xf0,0x65,0xcf,0x18,0x3c,0xf8,0x25,0xc2,0x99,0xf4,0xec,0xef,0xdd,0xef,0xf3,0x6b,0x28,0x00,0xaa,0xfd,0x76,0xec,0x19,0x67,0xd6,0x79,0xa6,0x01,0x6e,0x20,0x3a,0x7f,0xd4,0xd0,0x05,0xb4,0xea,0xd4,0xde,0x11,0x06,0x44,0x4a,0x6f,0x15,0x2f,0x62 +.byte 0x9a,0xaa,0xeb,0xaf,0xb5,0xb5,0x46,0xb2,0x28,0x2e,0x74,0x26,0x06,0x91,0xeb,0x15,0xef,0xd4,0xfd,0xc7,0x1b,0x65,0x25,0x01,0x24,0xd2,0x44,0x05,0x18,0x1c,0x71,0x36,0x58,0xc4,0x37,0xfe,0x22,0x29,0xc0,0x2f,0xd2,0x4e,0xeb,0x43,0xb9,0xf9,0x4e,0x87,0xd7,0x92,0x77,0xa8,0x4f,0xa5,0x6e,0x5c,0x4d,0x3a,0xe9,0x16,0x62,0x30,0x51,0xbb +.byte 0x32,0xd8,0x0d,0x86,0x20,0xbf,0x68,0x0f,0x3e,0xef,0x8b,0x0d,0xc5,0xa6,0x94,0x81,0xe9,0x6f,0x85,0xf5,0x22,0x6e,0x9e,0x0a,0x56,0xa3,0x43,0x79,0x50,0xd9,0x45,0x5f,0x5a,0x3f,0x53,0x53,0xb7,0xfe,0xb6,0x1c,0x63,0xab,0x7c,0xed,0x2f,0xc4,0x2b,0xa8,0x53,0xfb,0xad,0x46,0xf0,0x63,0xca,0x7a,0x6e,0xce,0xf4,0xb9,0x34,0xd0,0x9a,0xc8 +.byte 0x0d,0xd2,0x32,0xce,0x26,0x3f,0xcd,0xd9,0xbc,0xa9,0x46,0x65,0x45,0xfe,0x45,0xeb,0x0d,0xab,0xe6,0x31,0xb6,0xb9,0x41,0x53,0x7d,0x55,0xc3,0xfb,0x10,0x46,0x37,0x77,0x1f,0x15,0xf0,0x5f,0xcb,0x8f,0xea,0xc5,0xc0,0xb8,0xc6,0xb1,0x3a,0x06,0x42,0xec,0x38,0xec,0x06,0xd1,0x37,0x3b,0xe1,0x8d,0xad,0xc2,0xce,0x96,0x0b,0xf0,0xab,0xde +.byte 0x9c,0x3c,0x09,0xef,0x59,0xcd,0x67,0xa7,0x6e,0x0e,0xc7,0xee,0x51,0x6d,0x90,0x40,0x0e,0xdf,0xb1,0x13,0xe3,0x0c,0xb6,0xe8,0xcb,0xf5,0x57,0x50,0xeb,0xdf,0x09,0x45,0x72,0x40,0xff,0xdc,0x5c,0x51,0x42,0x47,0xb2,0x9e,0xca,0xf3,0x1b,0x06,0xb1,0x3e,0x04,0x55,0x96,0x63,0x24,0x16,0xdb,0x3e,0xab,0x98,0x33,0x70,0x6f,0xfd,0x8f,0x7b +.byte 0x56,0xb0,0x7f,0x28,0x26,0xc4,0x2a,0x9e,0xf5,0xa7,0xba,0x61,0x75,0xa4,0xb1,0x25,0x60,0xe5,0x9c,0x7e,0xb4,0xaa,0x04,0xa1,0x33,0x5a,0x8d,0x88,0x1d,0xc4,0x38,0x58,0x28,0x23,0xc7,0xac,0x20,0xf8,0xaa,0x18,0xf8,0xc7,0x27,0x05,0x07,0xf7,0x12,0xfe,0xe1,0xa5,0x99,0xaa,0x55,0x79,0x72,0xc4,0x14,0x08,0x14,0x4a,0xfb,0xf7,0x66,0x81 +.byte 0x6e,0xed,0x81,0x12,0x5f,0xb6,0x08,0x00,0x37,0xf9,0xdc,0xdf,0x4d,0xcb,0xfa,0xc6,0xf3,0xc2,0x17,0x17,0x52,0x39,0x7b,0xa0,0x3e,0x25,0xc9,0x48,0xd8,0xa6,0x1b,0x8b,0xdb,0xf8,0x74,0xac,0x6b,0x16,0xec,0xa6,0x4a,0x1e,0x7e,0x5c,0x50,0xbf,0x81,0xef,0x3c,0x7d,0x9d,0x21,0x38,0xa9,0x26,0x3c,0x30,0x7a,0xfb,0xab,0xd8,0x6a,0x0a,0xaa +.byte 0xbb,0x6e,0x91,0x92,0x7c,0x04,0x02,0x0e,0xa2,0x71,0xc7,0xde,0x7d,0x42,0xaf,0xe5,0x92,0xc1,0xb9,0xd7,0x52,0xaa,0x32,0xea,0x39,0x84,0x17,0x40,0xb0,0x83,0x18,0xff,0x46,0xb8,0x59,0xd9,0xa3,0xce,0x82,0x7e,0x65,0x54,0xe0,0xa4,0x6d,0x8a,0xbc,0x6a,0x65,0xb2,0xd5,0x96,0x5b,0x1c,0x9a,0x32,0x72,0xf7,0x81,0x57,0xcd,0xb3,0x22,0xc5 +.byte 0x7d,0x20,0x24,0xea,0xbe,0x51,0x4c,0xb3,0x48,0x36,0x4f,0x73,0xf4,0x3f,0x07,0x92,0x01,0xe2,0x1e,0x78,0x3f,0x8e,0x1f,0x35,0x1a,0xf1,0xe1,0x14,0xd1,0xe7,0xd9,0xfd,0xd8,0xf7,0x20,0xc2,0xf3,0x7a,0x59,0xc9,0x1d,0x13,0x41,0x01,0xf6,0x77,0x69,0xfb,0x0f,0xc7,0xe4,0x58,0x04,0xce,0xe8,0x73,0x87,0x2f,0xef,0xe6,0x36,0x38,0xc7,0x91 +.byte 0x2d,0x17,0xb5,0x56,0x68,0xb1,0x9f,0xbf,0x2e,0x4b,0xe7,0x09,0x7b,0x35,0x33,0x5a,0x6c,0xc1,0x6f,0xb3,0xac,0x6c,0x1e,0xfe,0xc0,0xc9,0xd8,0x77,0xf5,0xcb,0x5e,0xcc,0xd1,0x2f,0xdd,0x23,0x8b,0x3b,0xb5,0x43,0x96,0x1f,0xa9,0xe4,0x84,0x41,0x92,0xe9,0x68,0x47,0x50,0xf7,0xd4,0x85,0x22,0xa1,0x43,0xaa,0xde,0xf7,0xea,0xe0,0x54,0xaa +.byte 0x0d,0xe6,0xa5,0xb8,0x7e,0xec,0x13,0x9a,0x1e,0x6c,0x10,0x9d,0xa8,0xfb,0x97,0xde,0x24,0xda,0x33,0xbb,0xab,0x17,0x7a,0xb4,0x72,0xaf,0xed,0xc9,0xa4,0x62,0x65,0x0c,0x99,0x3d,0x74,0x7f,0xff,0x59,0xa9,0x8e,0x37,0xb9,0x10,0x30,0x26,0x3f,0x2f,0xfc,0x1e,0xe2,0xc6,0xb8,0xff,0x41,0xb3,0x35,0x3f,0x41,0xf4,0x47,0xbc,0x76,0xc6,0x77 +.byte 0x0f,0xf8,0xff,0xb8,0xd2,0x34,0x40,0xac,0x43,0xcb,0xcf,0x1f,0x57,0xaa,0x1a,0xa7,0xe1,0x4a,0x69,0xd7,0x05,0xa7,0x9d,0xff,0x13,0x43,0x91,0xe3,0x09,0x1c,0xb2,0xb2,0x82,0x06,0xa3,0x3c,0x35,0x85,0x9e,0xd0,0xcf,0x1c,0xb9,0x13,0x09,0x7d,0x3d,0x17,0x0f,0xf8,0x2f,0x61,0x97,0x7e,0x02,0xe0,0x78,0x07,0x69,0x8c,0x91,0xbe,0x96,0x92 +.byte 0x4a,0x03,0xa7,0x31,0x5f,0x6c,0xfe,0x55,0xb2,0x17,0xe8,0x4c,0x64,0x48,0x18,0xde,0x4f,0x5a,0xce,0xd2,0xcb,0x83,0x4d,0x1b,0x2a,0x1f,0xce,0x85,0xf7,0xdc,0x74,0x8c,0x42,0xc6,0x5a,0x3a,0x51,0x22,0x79,0x70,0xa0,0xe0,0x29,0x2a,0x73,0xe4,0x53,0xb4,0x47,0x5f,0x54,0xa8,0x65,0xe4,0x89,0x78,0xf9,0xb9,0x5f,0x5f,0x9d,0xa8,0xf7,0x82 +.byte 0x4e,0x34,0x60,0xfc,0xe3,0x88,0x65,0x73,0x99,0x1f,0x53,0xed,0xe8,0xf0,0xf4,0x5a,0x0a,0x49,0x42,0x6e,0x02,0x3f,0xa8,0x63,0x21,0x02,0x2e,0x8f,0x33,0xba,0x0e,0x10,0xd3,0x4c,0x1a,0x8b,0xf5,0x84,0x8e,0x2b,0x37,0x12,0x23,0x77,0x02,0x45,0xc7,0xc3,0x79,0x06,0xc2,0x8c,0xaa,0x32,0x53,0x7c,0x19,0xa2,0x92,0x7e,0x47,0x40,0x8f,0xae +.byte 0x8a,0x64,0x51,0x67,0xe1,0xc1,0xc3,0xd2,0x14,0x1d,0x63,0x0c,0x80,0x04,0x30,0x3d,0xee,0x58,0x44,0xe4,0x14,0x63,0xfc,0x95,0x05,0x3e,0xc1,0x8d,0xd3,0xcb,0x5d,0xc1,0x8e,0xf9,0xd7,0xe5,0x9d,0x97,0xef,0x8a,0xaa,0x50,0x31,0xa3,0x01,0x3a,0xb2,0x8d,0x63,0xb6,0xe7,0x34,0xec,0xa1,0x7a,0xff,0x57,0x95,0xbb,0x1d,0xbe,0x0c,0xa5,0x91 +.byte 0x92,0x08,0x06,0x1c,0x67,0x03,0x2e,0xee,0xf6,0x6f,0xa0,0xb7,0x9a,0x7c,0xe3,0x6a,0x8e,0xd8,0x50,0xc1,0xd6,0xa1,0x8d,0xe9,0x66,0x9a,0x1f,0x62,0x15,0x04,0x93,0x74,0xe8,0x04,0x0d,0x27,0x55,0x2b,0x07,0xb1,0xbd,0x69,0xe4,0xc1,0x34,0x8e,0xe7,0xfb,0xa0,0x3f,0x40,0x31,0x47,0xba,0xcb,0x80,0x88,0xf7,0x4f,0x46,0x05,0x31,0xaf,0x23 +.byte 0xdf,0x93,0x09,0x0a,0x15,0xc9,0x95,0x74,0x52,0x72,0xf4,0xbf,0x0d,0x07,0xb6,0xcc,0x4b,0x40,0x12,0xf3,0x87,0xea,0x29,0xd8,0x29,0x31,0x23,0xac,0x29,0x1a,0x89,0x83,0x5b,0x33,0x4b,0x6b,0x69,0xbe,0xb6,0x15,0x7e,0xfd,0xf2,0x95,0xc4,0xbe,0xeb,0xee,0x59,0x01,0x2a,0xce,0xca,0x80,0xda,0xf8,0x1a,0x01,0x23,0xf7,0xa1,0x4f,0xf5,0x83 +.byte 0x5e,0x16,0xd9,0x12,0xa9,0x4e,0xcb,0x59,0x23,0x4f,0x40,0xd7,0xbf,0xaf,0x76,0xf0,0x50,0x31,0x27,0x3a,0x8b,0x1d,0x9b,0xb1,0x1c,0x41,0xb0,0xed,0xe6,0xf3,0xa8,0x5f,0x6b,0x58,0x54,0x92,0xaf,0xcc,0x44,0x5c,0xea,0xdb,0x09,0xc5,0x26,0x5e,0xbe,0x46,0xbd,0x72,0x49,0x5a,0x4e,0x65,0x7e,0x75,0xcf,0xfc,0xf6,0xd0,0x3c,0x4a,0x7e,0xd6 +.byte 0x8e,0x8e,0xb4,0x19,0x45,0x75,0xbf,0xc3,0x5e,0x46,0xff,0xc9,0x46,0x65,0x8d,0x31,0x01,0x5e,0x1c,0x13,0x93,0x56,0x6f,0x28,0xec,0xf3,0x77,0xfa,0x6e,0xb9,0x0e,0xb6,0x8e,0x0e,0x38,0xf8,0x28,0x64,0xa2,0xa1,0x42,0x9a,0xb4,0xf3,0x14,0x8d,0x17,0x80,0x05,0x82,0x7c,0xf1,0xea,0x8b,0x4b,0x62,0xa0,0xde,0xf6,0xd7,0x36,0xb0,0x70,0x8d +.byte 0x03,0xf6,0xc8,0x2a,0x9e,0xc0,0xbb,0x2f,0xcb,0xef,0x35,0xf7,0x16,0xcd,0xd6,0xd6,0x90,0xd7,0x5d,0x61,0x00,0x33,0x9f,0xd8,0xd1,0xda,0x17,0x67,0x90,0xd1,0xf8,0x59,0xcb,0xf1,0x76,0xc2,0xbe,0x1f,0x5d,0x0d,0xb2,0x02,0xbd,0x19,0x9f,0x5a,0xa0,0x91,0xac,0x51,0xb5,0xf5,0x0a,0x64,0x67,0xf2,0x49,0x30,0x6c,0x57,0x83,0xda,0x90,0xf1 +.byte 0xc6,0xc7,0xe6,0x05,0x13,0x30,0x52,0xfd,0x2a,0x47,0xea,0xae,0xd3,0xed,0xe4,0x64,0x1f,0x6c,0xb1,0xdf,0xca,0x20,0x97,0x2a,0xc8,0xdc,0x00,0x0e,0x5b,0x59,0xc8,0x16,0x95,0x68,0x9a,0x2e,0x44,0xab,0xf6,0x93,0x7c,0x8f,0x66,0x4f,0x07,0x42,0x3f,0xa5,0x81,0xe7,0xab,0x59,0xbb,0xae,0xb1,0x3e,0x9a,0x25,0xf1,0xde,0xac,0x4c,0x1d,0x7a +.byte 0x54,0xb9,0xa9,0x59,0xaf,0xb0,0xab,0xaf,0x6b,0x76,0x66,0x1e,0xbe,0x1a,0xc1,0x61,0x1b,0x81,0x6b,0xe8,0xe4,0x73,0x6a,0x87,0xe9,0x39,0xcb,0x2c,0xab,0x64,0x36,0x9a,0x11,0x46,0xec,0x9f,0x30,0xb6,0x2c,0x14,0xe0,0xec,0xbe,0x33,0xde,0x60,0xc6,0x00,0x29,0x3c,0x55,0xda,0xfc,0x64,0xff,0xaa,0xbf,0x99,0x58,0xe2,0xe3,0xec,0xde,0xca +.byte 0xd1,0x3d,0xd2,0xad,0xaa,0xca,0x36,0x8f,0x93,0xa2,0xdd,0xde,0xaa,0x49,0x7f,0xdd,0x39,0x91,0xa0,0x7b,0x33,0xdf,0x36,0xcd,0xc3,0x3a,0xbc,0x53,0xf0,0x07,0x99,0x78,0x4e,0x63,0x47,0x79,0xbf,0x21,0xfc,0x05,0x47,0x69,0xec,0xee,0xf4,0x21,0x97,0x94,0x0c,0x7a,0x9f,0xa6,0xeb,0x5b,0x23,0xed,0x9d,0xc1,0xe1,0x5e,0x10,0xca,0xe0,0x84 +.byte 0x5a,0xdd,0xf6,0xae,0xd8,0x23,0x98,0xea,0x6c,0x43,0x77,0x41,0xf3,0x84,0x5a,0xe8,0xda,0xb3,0x11,0x0e,0x19,0x33,0xe9,0xf9,0x7a,0x90,0x07,0x68,0xf1,0xe4,0x52,0x0c,0x03,0x67,0xb9,0x42,0x41,0x24,0xa3,0x61,0x67,0x75,0xc9,0xb5,0xdd,0x10,0xf1,0x20,0x93,0x54,0xdb,0x0d,0xc7,0x0d,0x25,0x3e,0xda,0xb3,0xe7,0xce,0x97,0x7e,0xdb,0x1a +.byte 0x8f,0x92,0xff,0xe3,0x44,0x2d,0x6b,0xdb,0xe0,0x69,0x8b,0x16,0xce,0xe8,0xc7,0x93,0xf1,0x19,0xb9,0xd3,0x41,0x45,0x8d,0x95,0xb3,0x03,0xb2,0x66,0x96,0x95,0x91,0x33,0x1c,0xee,0xde,0xd7,0x9d,0xab,0x32,0x2f,0xb8,0x3c,0x7a,0x44,0x8f,0xa6,0xca,0x02,0x03,0x2f,0xa8,0x44,0x85,0x0e,0xf5,0x27,0x90,0x84,0xd9,0x80,0x06,0xf4,0x4f,0xc7 +.byte 0x21,0xc5,0x92,0xa4,0x2d,0x08,0x42,0x4c,0xa7,0x84,0xfa,0x7e,0x2b,0x66,0xfb,0x7c,0x81,0xea,0x5c,0x7d,0xdd,0x86,0xf1,0xf5,0x04,0xef,0xf2,0x50,0x12,0x72,0x42,0x22,0x23,0x74,0x7f,0xe7,0xed,0xd9,0xce,0x78,0x10,0x83,0x37,0xd0,0x81,0x97,0x4a,0xac,0xc2,0xe5,0x13,0x91,0x83,0xe2,0x6e,0xff,0x5a,0x0b,0xc3,0x4d,0xc1,0x3e,0x97,0x16 +.byte 0x96,0x69,0x39,0x9e,0x1d,0x6b,0x16,0x82,0xa2,0x94,0x0d,0x50,0xdd,0xa3,0xda,0x9d,0xda,0x3f,0x46,0xce,0x6c,0xd0,0xdf,0x6e,0x1b,0x17,0x47,0x51,0x74,0x6f,0xe9,0xa4,0x6b,0xae,0xd2,0x6e,0x5b,0xc0,0x26,0xc6,0x0b,0x84,0xb1,0x39,0xcf,0x9e,0x7c,0x18,0x52,0xd7,0x8f,0x33,0xae,0x3d,0xaf,0x3d,0x1a,0xba,0x3f,0x09,0x76,0x22,0x1d,0xf3 +.byte 0x42,0x14,0x4f,0x06,0xc7,0x33,0xc1,0x2d,0x58,0x1b,0x4c,0xc0,0x3a,0x29,0xa6,0x5e,0x19,0x26,0xdf,0x36,0x18,0xa9,0xc5,0xe9,0xd3,0xb1,0xae,0x86,0xa8,0x7f,0xd9,0xb4,0x18,0xef,0x9c,0x46,0xb6,0xf2,0xb2,0xb6,0x6e,0xe2,0xf8,0x5f,0x27,0xea,0x76,0xd3,0x40,0x68,0x94,0x66,0x8a,0xf5,0x9f,0xee,0x0c,0xe5,0xae,0xb6,0xba,0x87,0x42,0x40 +.byte 0xc9,0x83,0xac,0xb4,0x2c,0xec,0x74,0xb7,0x55,0x17,0x0b,0x1e,0x45,0x1a,0x87,0x9d,0x52,0xce,0xb7,0x58,0x2f,0x45,0xc7,0x7d,0xf3,0xd3,0x11,0x2e,0xf4,0xd8,0xc0,0xb8,0xc3,0x31,0x45,0x68,0x40,0xe8,0x8a,0x33,0x20,0x9a,0x06,0xa8,0x18,0x53,0xb2,0x73,0xa1,0x57,0xac,0x8f,0x56,0xeb,0x8e,0xa4,0xfc,0xd6,0x76,0x7e,0x81,0x62,0x2c,0x17 +.byte 0x49,0xb4,0xcc,0x15,0x66,0xcb,0xa2,0x3c,0x29,0xf0,0x73,0x0e,0x9a,0x34,0x16,0x6d,0x43,0x62,0x20,0x89,0x14,0xae,0x8b,0x5d,0x61,0x54,0xa1,0x82,0x49,0x73,0xb9,0x2b,0x48,0xd4,0xe3,0x21,0x37,0x5e,0x4d,0xbf,0xd0,0x72,0xa4,0x23,0xdb,0x7c,0xd9,0x45,0x77,0x8a,0x24,0x23,0x56,0xcd,0x84,0x80,0x44,0x12,0xce,0x99,0x39,0xbd,0x77,0xff +.byte 0x8c,0x62,0x8d,0x56,0x77,0x24,0x40,0x11,0x22,0xab,0x28,0xd6,0x75,0x2b,0xbb,0xc1,0x51,0xd6,0x5e,0x61,0x1c,0xe9,0xac,0x36,0x99,0x52,0x44,0xa5,0x20,0xdb,0xe0,0x12,0x9a,0x45,0x8f,0x7f,0x47,0xf9,0xa3,0x91,0x18,0x2b,0x51,0x9a,0x9f,0x3f,0x7d,0x36,0xde,0x71,0xae,0xca,0x62,0x62,0x16,0xda,0x19,0x9c,0x84,0xce,0xde,0x93,0x22,0xde +.byte 0xaf,0xe7,0x91,0x09,0xe8,0xf0,0x0e,0x07,0x71,0xdf,0x48,0xcd,0x8a,0x77,0x19,0x3c,0xd6,0xef,0x8e,0xe0,0x49,0xdf,0xcb,0xd6,0x34,0x78,0x7f,0x42,0xc2,0x6e,0x7a,0x50,0x53,0xee,0xbf,0x73,0x4b,0xd4,0x4f,0x06,0x18,0x26,0x67,0x51,0x54,0xa3,0x40,0xe6,0xb3,0x61,0x4b,0xfd,0xee,0x62,0x00,0x44,0x6c,0x0d,0x8b,0x2f,0x4d,0x06,0x17,0x41 +.byte 0xee,0x8b,0xde,0x1f,0x80,0x36,0x58,0x3e,0x0a,0x53,0x0a,0x83,0xf9,0xba,0xbd,0x91,0x6a,0x20,0x32,0x42,0x6c,0x85,0xdc,0x84,0xfd,0xce,0x57,0xbe,0xf8,0xa5,0x2c,0x7e,0xf9,0x1b,0x07,0xf4,0x32,0x13,0x32,0x79,0xdc,0x91,0xfc,0xc0,0x18,0xe6,0x1e,0xb2,0x67,0x9d,0x08,0xd2,0x89,0xa2,0xb1,0xbf,0x37,0xe1,0x3f,0x9e,0xb5,0x17,0xf7,0x2f +.byte 0x9a,0x4f,0x3c,0xea,0x5d,0x48,0x56,0x48,0x35,0x17,0xe9,0x5a,0x99,0xa7,0x2e,0x25,0x4f,0x96,0xa6,0x3d,0x3c,0xf8,0xdc,0xe7,0xe5,0x98,0x46,0xf7,0x10,0x16,0x4f,0xb0,0x7b,0x48,0x06,0xbb,0x9a,0x5a,0xad,0x32,0x49,0x92,0x39,0xb2,0xfe,0x01,0x1a,0x5e,0xcc,0xf7,0x0d,0x65,0x1c,0xf5,0x3d,0xb3,0x40,0x28,0x06,0x6e,0xbb,0x74,0x2a,0x95 +.byte 0xe9,0x62,0x2a,0xe2,0x19,0x38,0xc6,0x0d,0x46,0x30,0x6d,0x90,0xa5,0x68,0x4d,0x89,0xf0,0xf4,0xaf,0x52,0x11,0x8a,0x47,0x65,0xc0,0x6d,0xee,0xde,0xbc,0xed,0xf2,0x94,0xf3,0xfb,0xfd,0x2f,0xea,0xd5,0x36,0x89,0x8a,0x22,0xb8,0x75,0x3c,0xda,0x8d,0x3f,0x71,0xe5,0x50,0xb8,0xef,0xfc,0xa1,0x34,0x4a,0xb0,0x56,0x64,0xaf,0x28,0x0c,0x7a +.byte 0x28,0x3e,0xc8,0x83,0xc2,0xbb,0x89,0xc4,0x29,0x7f,0xc9,0xe7,0x4e,0xcb,0xdc,0x8f,0xe8,0xa4,0xdc,0x0d,0xcc,0xa0,0x16,0xda,0xa9,0x34,0x61,0xec,0x64,0xa7,0xf4,0x47,0xe9,0xee,0xbf,0xc6,0x4b,0xc5,0x01,0x65,0xe4,0xe0,0x12,0xd6,0x27,0xda,0x30,0xb5,0x60,0x72,0xe1,0xee,0x38,0x23,0x6c,0x9d,0xbb,0x83,0x01,0x4b,0x26,0x9a,0x68,0xb3 +.byte 0x89,0xb3,0xe0,0x10,0x22,0x58,0xef,0x2d,0xd4,0x86,0xab,0xab,0xc4,0xd8,0x9c,0x56,0xe8,0x54,0x40,0x86,0x11,0xd2,0x6b,0xc0,0xaf,0xfc,0x4a,0xef,0x24,0x38,0x79,0x32,0x54,0x26,0x8b,0x7e,0x02,0xad,0x86,0x9d,0x40,0x65,0x28,0x28,0xa3,0xa6,0xe4,0x07,0x29,0x3a,0xbb,0x81,0xed,0x17,0x54,0x51,0x35,0xc6,0x88,0x9c,0x63,0x7e,0x73,0x02 +.byte 0x28,0x13,0x4b,0x33,0xc0,0x68,0xbc,0xae,0x8c,0x59,0xd4,0x84,0x1d,0x41,0x86,0x5a,0xf6,0x14,0x50,0x13,0x88,0xca,0xc8,0xb8,0xfc,0x61,0xeb,0xe6,0x69,0x70,0x4a,0xa5,0xa5,0x36,0x4b,0xac,0xca,0x00,0x28,0xae,0xb0,0x03,0xef,0xe3,0x92,0xad,0x97,0x32,0x05,0x8c,0x93,0x95,0x45,0xd5,0x75,0x66,0x11,0xd3,0x6f,0x7f,0x5f,0x35,0x44,0xb7 +.byte 0xd7,0x34,0xcf,0x8c,0x4a,0x61,0x68,0x63,0x3f,0x92,0x54,0x01,0x3c,0x25,0x2d,0x6f,0x4a,0x2d,0x55,0xff,0x3f,0x86,0x85,0x9f,0xc2,0xa1,0xde,0x6b,0xbf,0x7e,0xb4,0x7c,0xc1,0x80,0x73,0xf5,0x3b,0x85,0xae,0x36,0x1a,0xdf,0x00,0x52,0xb7,0x70,0xa9,0x42,0x79,0xd2,0x26,0xf8,0x3b,0xeb,0x9f,0x2e,0x15,0x33,0xc8,0x85,0x2d,0x63,0xb2,0x89 +.byte 0x24,0x8e,0xfd,0xe6,0xdf,0x01,0x80,0x8b,0x27,0xe3,0x7e,0x17,0xc2,0x4e,0x26,0xa2,0xe1,0x95,0x81,0x3a,0xdd,0x2a,0xf4,0x75,0x21,0x64,0x11,0x04,0x5e,0x00,0x39,0xf0,0x08,0x68,0x67,0x09,0xa8,0x9b,0xbe,0xb7,0x62,0x0e,0xa8,0x69,0xcd,0x4e,0xaf,0xc8,0x4f,0x92,0x3d,0x8e,0x35,0x60,0x70,0xb3,0xda,0x2f,0x38,0x80,0x6f,0x5e,0xcc,0x3b +.byte 0x6e,0x05,0x26,0x14,0x9d,0x36,0x72,0x7d,0x09,0xb8,0xb7,0xa1,0xf7,0x5f,0xb3,0xe1,0xd6,0xc5,0x54,0x4e,0x80,0x4d,0x06,0x8f,0x84,0xbb,0xb6,0x65,0x87,0x2c,0x19,0x4a,0x74,0x3c,0x34,0x62,0x32,0xad,0x4c,0x06,0xa3,0xbb,0xfb,0x4f,0x4f,0x9d,0x91,0x84,0x63,0x75,0x34,0xcc,0x6b,0x00,0xa1,0x5a,0x63,0x03,0x8d,0x1e,0xdb,0xa4,0x0c,0xe6 +.byte 0x3d,0xd1,0x94,0x77,0xd8,0x77,0x8c,0x39,0x48,0x78,0xb1,0xb5,0xa2,0x41,0xd0,0x6d,0x27,0x20,0x4a,0x41,0x88,0xa5,0x78,0x3f,0x51,0x72,0x8c,0x80,0xe7,0x37,0x81,0x8b,0x06,0x46,0x58,0xab,0x23,0x85,0x47,0x89,0x39,0xf9,0x14,0xfe,0xbf,0x07,0x7c,0x47,0x8e,0xcc,0xd7,0x08,0xfe,0x5d,0xee,0xf9,0x94,0xa2,0x83,0x81,0x8a,0xfd,0x0f,0x9a +.byte 0xa7,0xe4,0x59,0xad,0xe6,0x1f,0xed,0x5d,0xe4,0x20,0xd6,0x2f,0xa7,0xd3,0xcf,0x5b,0x18,0x6d,0x24,0x79,0x66,0xd9,0xaa,0x44,0xfa,0x8d,0x74,0x60,0xcc,0x7e,0xbf,0x4f,0x0e,0xe3,0x9c,0xa5,0xe4,0xff,0x14,0x05,0xff,0x24,0x62,0x94,0x00,0x7a,0x58,0xe5,0x0b,0x3b,0xe8,0xee,0xe1,0x4d,0x4e,0x34,0x26,0xba,0x70,0x10,0x5e,0x14,0x4f,0xa5 +.byte 0x7a,0x9e,0x7b,0x28,0x99,0xbe,0x94,0x4a,0xcb,0x8d,0x65,0x60,0xa0,0x6e,0xc7,0xbc,0x51,0xba,0xb5,0x07,0x97,0x25,0x42,0xb7,0x2c,0x0e,0x9b,0xfc,0xfb,0x35,0x6f,0x74,0x10,0xce,0x25,0xdb,0xa9,0x7c,0x11,0x61,0x43,0xf9,0x19,0xbf,0xe2,0x21,0xa3,0x57,0x3c,0x41,0x0a,0x15,0x4e,0x7f,0x6b,0x38,0xb6,0x73,0x41,0xa2,0x4e,0x8e,0xb9,0x44 +.byte 0xee,0x2a,0x2e,0x0a,0x9e,0x85,0xf1,0x6e,0x93,0x72,0x42,0x50,0x55,0xe1,0xc6,0x18,0x11,0x92,0xf7,0xbf,0x05,0xd8,0xb6,0xbc,0x2b,0xd5,0xe0,0xd3,0x9b,0x64,0xc4,0xdd,0xb0,0xb3,0x46,0xd8,0xfb,0x73,0xea,0xed,0x06,0x96,0x16,0x9e,0xf6,0xc6,0xe8,0xbe,0xae,0x00,0x2f,0x5a,0xf4,0x1f,0xb5,0x28,0x7c,0x75,0x76,0x68,0x74,0xa2,0x57,0x0e +.byte 0x6c,0xfa,0x2d,0xbe,0x34,0xf1,0xc9,0x2b,0x83,0x58,0xe7,0x2a,0x87,0xdb,0x47,0xae,0xc7,0xc2,0x78,0x50,0xed,0x20,0xdf,0x30,0x38,0xdd,0x84,0xa9,0x6b,0x00,0xb1,0x7b,0xbb,0x69,0xd3,0xbe,0xed,0x3d,0x99,0x6e,0x39,0x42,0x75,0x8a,0x6c,0x7c,0xa5,0xcf,0xc9,0xcf,0x11,0x14,0xb3,0xaf,0x72,0x00,0x3b,0x58,0xdd,0x2a,0xe1,0x44,0xa7,0x51 +.byte 0x15,0x05,0x1b,0x18,0x49,0x07,0x90,0x4c,0xbc,0x99,0x88,0x64,0xf6,0x14,0x0b,0x99,0xc0,0x84,0xc9,0x06,0x32,0xf0,0xec,0x19,0x8d,0x4a,0xb8,0xdb,0x32,0xb4,0x5e,0xc9,0x0c,0x24,0xf0,0xad,0xdc,0xf4,0x32,0x3b,0xf6,0x68,0x28,0x4a,0xa5,0x5b,0xb7,0xd5,0x00,0x35,0xf8,0x56,0x03,0xa3,0x86,0xa0,0x8a,0x1b,0x53,0xb5,0x58,0x73,0x8c,0xf9 +.byte 0x2b,0xd8,0xcb,0x88,0xe7,0x7e,0x79,0x68,0x13,0x5d,0x7d,0x23,0xc4,0xec,0x9c,0xf4,0x95,0x97,0xbf,0xb2,0xd9,0xdf,0x38,0xe8,0xa2,0x79,0xf7,0xe8,0x36,0x80,0x59,0x3f,0x58,0x2f,0xf7,0xf9,0x32,0x73,0xdd,0xd6,0x9e,0x20,0x1a,0x29,0xab,0xc1,0x77,0x14,0x71,0x3c,0xde,0x90,0xe9,0xea,0xdb,0x78,0x14,0xa3,0x89,0x43,0xf1,0x42,0x43,0x3f +.byte 0xe7,0x67,0x32,0x3d,0x65,0xdc,0xa4,0x79,0x8f,0x81,0xa5,0xb0,0x94,0x0f,0x96,0xf5,0x82,0xcc,0x47,0xc1,0x29,0x39,0x70,0x7a,0xf3,0x49,0xf5,0x09,0x43,0x50,0x56,0xd6,0xea,0xc4,0x35,0xa5,0xa2,0x8a,0xbe,0xc0,0xe3,0xfe,0x4c,0xa2,0x83,0x09,0xab,0x72,0x8a,0x96,0x7c,0x01,0x70,0xb2,0xd5,0x62,0xb7,0x67,0x59,0x36,0xcf,0x56,0x2d,0x14 +.byte 0xc2,0x69,0x49,0x52,0x4e,0x7c,0x45,0x4b,0xef,0xcd,0x79,0xcd,0xe6,0xa6,0xd0,0xbe,0x10,0x1e,0x18,0xca,0xe7,0x8d,0x65,0xb1,0x17,0xc7,0x2c,0xc8,0x2a,0x5b,0xe8,0x08,0x11,0x15,0xea,0xa9,0x43,0x7b,0x70,0x04,0x0c,0xc8,0xca,0x67,0x18,0x18,0x12,0x16,0xc2,0xd3,0xf2,0x0a,0xc7,0x01,0xa9,0x97,0x61,0xf6,0xa7,0x44,0x9a,0xb3,0x67,0xdc +.byte 0x07,0x63,0x02,0x02,0x2e,0x58,0x80,0xa9,0x95,0xa0,0x8e,0x86,0xb6,0xf6,0x14,0x13,0x0a,0xea,0xf1,0x6d,0xd9,0x98,0x37,0x12,0xdb,0x67,0x1b,0x13,0x8e,0xd1,0xfa,0x2f,0x98,0x53,0x3c,0xd7,0x56,0x55,0x42,0x2f,0x64,0x59,0xd5,0xb7,0x6e,0xa8,0x6c,0xc2,0x40,0x11,0xb5,0xa1,0xc0,0x5c,0x45,0x87,0x91,0xb1,0x1c,0x4e,0xa9,0xf6,0x72,0x57 +.byte 0x50,0x8e,0xc5,0xfc,0x64,0x59,0x52,0x82,0xb0,0x75,0xc3,0x98,0xff,0x32,0xce,0xa4,0x39,0xb8,0xa4,0x61,0xb4,0x53,0x3f,0xc7,0x80,0x35,0x48,0xaf,0xa8,0x67,0xfe,0xa1,0x1d,0x3c,0x95,0xb5,0x63,0x1c,0x3a,0x2c,0x68,0xfa,0x98,0x8b,0xa7,0x19,0x29,0x79,0xe4,0x9b,0xff,0x8f,0x15,0x9c,0x65,0x60,0xd2,0xa9,0x4f,0xd5,0xb2,0x57,0xff,0x32 +.byte 0x4c,0x96,0x82,0x6b,0x09,0x6c,0x74,0x55,0x00,0x5c,0x68,0x68,0xd5,0x9b,0xd4,0xdf,0x3d,0x2d,0xb9,0x0b,0xf5,0x2c,0x87,0x35,0x2a,0xc0,0xc0,0xc9,0xd7,0xa1,0x76,0x30,0x82,0x46,0xd8,0x24,0x6e,0x27,0x02,0x71,0x57,0x5c,0x43,0xf2,0x54,0xd6,0xea,0xd7,0x67,0x7d,0xac,0x76,0x91,0xf1,0x26,0x6e,0xaf,0x87,0x05,0x06,0x48,0x57,0xbd,0x67 +.byte 0x1d,0xd7,0x07,0xcd,0x41,0x02,0x49,0x6c,0x8c,0xe1,0xe3,0x00,0x78,0xbe,0x28,0x84,0x16,0x44,0xb1,0x0d,0x6d,0x40,0xfe,0xab,0x7e,0xf6,0x6b,0xff,0xfa,0xe1,0xc7,0x9d,0x56,0x62,0xf1,0x68,0xba,0x76,0x34,0x8f,0x54,0x20,0x49,0xf5,0xa2,0x54,0x52,0xca,0x42,0xed,0x4f,0x9b,0xdf,0xcf,0xfb,0xf6,0xee,0x12,0x29,0x43,0x8f,0xf9,0xfd,0xf4 +.byte 0x8a,0xbf,0xae,0x50,0xf2,0x8f,0x46,0xa2,0x97,0x3b,0x2d,0xfb,0x84,0x98,0x61,0xae,0xba,0x36,0x25,0x30,0x8b,0xdc,0xd3,0x08,0x8e,0x7e,0xfa,0x91,0xac,0x4b,0x29,0x6d,0x0c,0x81,0x0f,0xc7,0xc8,0xc4,0x5c,0x48,0x68,0xa7,0x83,0xf3,0x6a,0xc8,0x0d,0x3a,0x9b,0x46,0xb9,0xe1,0x31,0xac,0x3c,0x12,0xa2,0xae,0x74,0xb8,0x91,0xed,0x63,0xba +.byte 0x40,0xb8,0x57,0x58,0x1f,0x1d,0x1a,0x2d,0x98,0x60,0xe8,0xe1,0x84,0x16,0xe5,0xf0,0x1e,0x35,0x58,0x31,0xc3,0x0c,0x49,0x6e,0x13,0x2c,0xac,0x14,0xc2,0xde,0x5f,0x62,0xe5,0x37,0x5b,0x1d,0x71,0x8b,0xc3,0x3d,0xd8,0xaf,0x3d,0x0a,0xef,0x80,0x3c,0x9a,0x4b,0x0a,0x3f,0x0e,0x8f,0x90,0x8f,0x73,0x2e,0xff,0x8e,0x8e,0x87,0xf8,0x46,0x52 +.byte 0xed,0x7d,0x76,0xf3,0xff,0xaf,0x5e,0x62,0x87,0x16,0x9c,0xa6,0x12,0x39,0x13,0xc3,0x62,0x4b,0xd2,0x21,0xa2,0x43,0xfa,0x4c,0x5d,0x75,0x61,0x64,0x5b,0x23,0xcd,0x76,0x86,0x81,0xd6,0xa6,0x25,0xe1,0xc1,0xc6,0x04,0x5e,0x65,0xfe,0x89,0x0e,0x67,0x02,0xeb,0xb9,0x26,0x88,0x81,0x97,0x1e,0x62,0x4e,0xf4,0x4e,0x0d,0xef,0xac,0xcf,0xd7 +.byte 0xc5,0x9b,0x9d,0x3a,0xa2,0x71,0xd7,0xd4,0x72,0xa6,0x66,0x90,0xe2,0xf7,0xb7,0xec,0xe4,0xca,0x9f,0xd1,0xd8,0x5a,0x65,0xff,0x39,0x65,0x78,0x47,0x1c,0x64,0xab,0x1a,0x35,0x2e,0xe2,0xf7,0x67,0xa4,0x7f,0xd5,0xea,0x04,0xee,0x4d,0xf6,0x29,0xe4,0xcd,0x1b,0xcf,0x0a,0xef,0xa1,0x14,0x90,0x0e,0xed,0x1a,0x10,0x63,0xa0,0x56,0x11,0x05 +.byte 0x57,0x94,0x3a,0x11,0xff,0xe0,0xc7,0x33,0x19,0x67,0xd7,0xd0,0xcc,0x76,0x52,0x5d,0x9e,0x10,0xe7,0xd6,0xaa,0x13,0xe8,0x8d,0xa5,0x60,0x66,0x98,0x26,0x11,0x66,0x0f,0x2d,0x4d,0xec,0x28,0x93,0x17,0x3a,0x6f,0x99,0x70,0x00,0x2b,0x66,0xb3,0x49,0x69,0x3c,0x3b,0x03,0xb8,0xc0,0x9b,0x1c,0x96,0xd9,0xd1,0xe1,0x6d,0x8f,0x45,0xce,0x22 +.byte 0xcf,0x48,0x61,0x85,0x10,0x1b,0x3f,0x2b,0x74,0x48,0x61,0x68,0x63,0xe3,0xa3,0x83,0xe2,0xcc,0xa0,0x6d,0x82,0x8b,0xe5,0x42,0xab,0xa7,0x62,0x6c,0x05,0xb4,0x7b,0x65,0xf5,0xd8,0x0b,0x7d,0x61,0xd6,0x5c,0xf0,0xc0,0x03,0x0c,0x51,0xec,0x06,0xad,0x79,0x8c,0x62,0x0c,0xf5,0x8e,0xcb,0x97,0x62,0xf9,0x3e,0x39,0x8d,0x3c,0x2e,0xd1,0xc0 +.byte 0x5f,0x98,0xea,0xb5,0x26,0x19,0xf5,0x93,0xbb,0xf8,0xd4,0xd5,0x35,0xee,0x1f,0xf8,0x71,0x81,0x0e,0xe6,0xe9,0xf3,0x2c,0x80,0xa8,0x15,0x35,0x1e,0xda,0x07,0x41,0x39,0x8a,0x19,0x1f,0x70,0x99,0xbe,0x3d,0x5c,0x1f,0xf6,0x72,0x85,0x73,0xea,0xb5,0x61,0xbb,0x77,0xaa,0xef,0xc7,0x2c,0xed,0x1e,0xa6,0xfd,0xc9,0xde,0xa9,0x82,0xba,0x19 +.byte 0x04,0x17,0xf7,0xa1,0x59,0x5c,0x7d,0x8d,0xe7,0x1c,0x89,0x7f,0xe1,0x02,0xd3,0xb0,0x46,0x6c,0xcf,0xde,0xf0,0x0b,0x00,0x43,0x8d,0xd6,0xe6,0xf7,0xc8,0x83,0x20,0x77,0x8b,0x9f,0x14,0xea,0x2b,0xb2,0xd2,0x41,0xfd,0x96,0x7c,0x0d,0x05,0xb9,0x5a,0xa0,0x83,0x50,0xde,0x0e,0xc6,0xa6,0x29,0x55,0x12,0x8e,0x2f,0x0a,0x5c,0xcd,0xae,0x92 +.byte 0x76,0x84,0xc9,0x8a,0x81,0xe5,0x3e,0xf0,0xe6,0x5b,0xe4,0x21,0xfb,0x4c,0xb6,0x0a,0x7b,0x7f,0x7e,0xab,0xdc,0x15,0x44,0xf8,0xeb,0x23,0x21,0x31,0xef,0x98,0xec,0x84,0x69,0x34,0x29,0x99,0x03,0x8a,0x12,0x8e,0x28,0xdd,0x00,0x6a,0xa3,0xe7,0x08,0x17,0x35,0x2a,0x42,0x8a,0xcb,0x4a,0x7b,0x1c,0xd2,0x74,0x4f,0x6a,0x8c,0x85,0x1c,0xd6 +.byte 0x05,0x3a,0xfd,0xdf,0x1c,0xa5,0x59,0xbb,0xdb,0xe3,0xa7,0x59,0xb1,0x67,0x3d,0xa4,0x71,0x4d,0x6c,0x99,0xe0,0xa7,0x8c,0xfa,0x96,0x1f,0x8d,0x0c,0xa7,0xc8,0xce,0xa3,0xbf,0x4d,0xc7,0xa9,0xb7,0xfd,0x04,0x58,0xcd,0xd7,0x20,0xb1,0xb9,0xf5,0x06,0x70,0x1b,0xdd,0xf4,0x1c,0xdc,0x32,0xa0,0x90,0x0d,0xb2,0x91,0x14,0x05,0xa2,0xf7,0xb7 +.byte 0xb6,0xd2,0xf1,0x30,0x75,0xcc,0x78,0x0d,0x56,0x70,0x64,0x02,0xe7,0x83,0x97,0x65,0x63,0x4b,0x64,0xff,0x8b,0x62,0xc9,0xa4,0x6e,0x96,0xbf,0xd3,0xeb,0x74,0xc5,0x1f,0xdb,0x1c,0xf3,0xca,0x54,0x7d,0x8d,0xd9,0xec,0x18,0xd8,0x99,0xd1,0xa5,0x70,0x8a,0xc5,0xdc,0xa0,0xcb,0xb7,0x52,0xe3,0xe6,0x88,0x0c,0x5a,0x42,0xde,0xe6,0xd8,0xc4 +.byte 0x39,0xe5,0x6c,0x0b,0xd4,0xa5,0x9b,0x51,0xa2,0x3d,0xc5,0xc7,0x17,0x17,0xb8,0xd8,0x09,0xad,0xeb,0x67,0x47,0xe0,0x88,0xef,0x1d,0x22,0x18,0x25,0xdc,0x32,0xb2,0xf7,0x47,0xc5,0xb3,0x0b,0x57,0x01,0x67,0xac,0xc3,0x9e,0xb0,0xa8,0xd7,0xce,0xb2,0xcd,0xea,0x3b,0x61,0xbb,0x24,0xad,0x91,0x7b,0xa2,0x9a,0xb3,0x63,0x56,0xe2,0x9d,0x69 +.byte 0x9e,0xd7,0x5f,0x5f,0x47,0x9f,0xae,0xf6,0x09,0xb1,0x9e,0x22,0x35,0xaa,0x55,0x0b,0xfc,0x70,0x96,0xfd,0x53,0x8a,0x37,0xaf,0x2d,0xa2,0xc5,0x49,0x5b,0x1e,0x32,0x47,0x9d,0xc3,0xb4,0x46,0xf3,0x54,0xdb,0x3f,0xb9,0x69,0x9e,0x8b,0xad,0x11,0xb2,0x68,0xe8,0x27,0x0d,0xca,0x33,0x1c,0x86,0xb2,0x2c,0xaa,0xc2,0x15,0xf9,0x6e,0xed,0x30 +.byte 0x71,0x08,0xeb,0x93,0x1d,0x16,0xc5,0x34,0x73,0x65,0x7a,0x19,0x2b,0xa7,0x3d,0xe6,0x88,0xb5,0x0f,0xa0,0x92,0x91,0x22,0x9d,0x01,0xf3,0xf4,0x57,0x9f,0xd9,0x23,0x1b,0xbd,0xd7,0xd5,0x11,0xc9,0x24,0xf6,0x36,0x30,0x30,0x69,0x95,0x17,0x48,0xf9,0x76,0x71,0xef,0xef,0xc0,0x00,0x9c,0x7d,0x87,0xdc,0xdc,0x1a,0x32,0x82,0x7a,0x13,0xc2 +.byte 0x9f,0x53,0xc2,0x7d,0x4d,0xbf,0xbe,0xf5,0x9d,0xc8,0x81,0x5b,0x81,0xe9,0x38,0xb6,0xa5,0x40,0xa5,0xd4,0x6f,0x0c,0xea,0xf1,0x52,0x59,0x37,0x3b,0xc2,0xb2,0x5f,0x10,0xdf,0x22,0xf7,0x77,0xe8,0x66,0xb0,0x97,0x91,0x5f,0xc2,0x18,0x8d,0x17,0x40,0xd1,0x6d,0xde,0x6e,0xf0,0x6c,0x1f,0x4e,0x9b,0x15,0x83,0x9b,0x70,0x21,0x2b,0x98,0x46 +.byte 0xbf,0xa5,0x82,0xac,0x63,0xac,0xd7,0x52,0xec,0x2c,0xf2,0xe4,0xe0,0x2a,0xbf,0x7e,0xa2,0xd2,0x9d,0x0d,0xf2,0x9b,0x79,0x5f,0x22,0xb0,0x6d,0x22,0x2e,0xed,0xe2,0x4f,0x73,0xc5,0x89,0xcc,0x4a,0xaa,0x9a,0x7e,0xab,0x95,0x25,0xa7,0x9d,0xf4,0xc2,0xe8,0x42,0x6e,0xd3,0xf9,0x25,0x54,0xb9,0x1f,0xa9,0x16,0x9c,0x22,0x7a,0xf0,0xa6,0xac +.byte 0x8b,0x9d,0xe6,0xe3,0x93,0x4e,0x65,0x3a,0x39,0x3e,0xf5,0x41,0x38,0x02,0xb7,0x37,0xd4,0xdc,0xea,0xc5,0x53,0x0e,0x52,0x85,0x96,0xc0,0xa7,0x21,0xbf,0xe7,0xca,0x12,0x1c,0x59,0x33,0xe4,0xd5,0x70,0x6b,0x25,0x54,0x24,0x58,0x48,0x1b,0x65,0x6e,0x7e,0xe6,0x84,0x39,0x38,0xbc,0xdf,0x96,0xbc,0x39,0xdf,0x8f,0x36,0x9e,0x3a,0xda,0x02 +.byte 0x86,0xe2,0x9f,0xb7,0x3a,0xd0,0xdb,0xc2,0x5d,0xb0,0xde,0x31,0x73,0x43,0xe5,0x4b,0x6a,0xa1,0x6d,0xaa,0xca,0x34,0xfa,0xa9,0xaf,0xec,0x05,0x2a,0xdb,0x82,0xa1,0xdc,0xdc,0x3d,0xb5,0x92,0x42,0x28,0xdc,0x93,0xec,0xab,0x9b,0x75,0xae,0x7c,0xbf,0x9b,0x25,0x01,0xb1,0xc8,0x3b,0x47,0xb6,0xfd,0x11,0x6f,0x4b,0xaa,0x6f,0xdf,0x1f,0x15 +.byte 0xc2,0xf3,0x87,0x4a,0xaf,0xf7,0x41,0x64,0x5a,0x19,0xa0,0xc4,0x4f,0x58,0xe8,0x19,0xe0,0x84,0x44,0xc7,0x65,0x0c,0xf1,0xff,0xcb,0x73,0xb2,0xac,0x25,0x28,0xe1,0xd4,0x03,0x16,0x3c,0x1c,0x24,0x3a,0xfc,0x2b,0x7e,0xcb,0xa3,0xba,0xb7,0x78,0x87,0xbe,0x95,0x06,0x27,0xb8,0x16,0x72,0xe4,0x24,0xa6,0x5d,0xe7,0x5e,0x93,0xa9,0x96,0xfd +.byte 0x01,0x1d,0xb8,0x7c,0x85,0x3c,0xe3,0xc9,0x56,0x68,0xcd,0xd9,0x79,0x97,0x50,0x39,0xfe,0x96,0x93,0x50,0xae,0xde,0xcd,0x8d,0xa0,0x38,0x31,0xba,0xca,0x21,0xff,0x19,0xea,0x44,0x95,0x4d,0xba,0xae,0xe2,0x62,0xd2,0x82,0x60,0x0c,0xb9,0x10,0x40,0x9a,0xaf,0x9b,0x17,0xcd,0xf3,0x26,0xec,0x38,0x13,0x18,0xd3,0xf2,0xd2,0x11,0xa6,0xc3 +.byte 0x3c,0x3b,0xe8,0xa0,0x49,0xba,0x4e,0x07,0xec,0x44,0x75,0x1c,0xc9,0x2f,0x68,0x64,0x02,0x1d,0x14,0x35,0x80,0xd8,0xa8,0x53,0xde,0x44,0x65,0x72,0x37,0x28,0x61,0x5f,0xa1,0x58,0xea,0x17,0xb3,0x89,0x25,0xf7,0xcb,0x87,0xe6,0x43,0xc5,0xc3,0xf3,0xd1,0xf5,0x1f,0x18,0xe9,0xd1,0x05,0xd9,0x85,0x38,0xf0,0x5e,0x26,0x35,0xf2,0x72,0x92 +.byte 0x34,0x2f,0xea,0xdd,0x7b,0x64,0xac,0x1d,0x78,0x41,0x56,0x83,0x7d,0x83,0x83,0x59,0xbe,0x9f,0x81,0x90,0x00,0x1f,0x04,0xd8,0xd8,0x8e,0xd9,0xeb,0x12,0x16,0x96,0x81,0x61,0x96,0xe8,0x7b,0x36,0x7b,0x26,0x9b,0x43,0x1e,0x0e,0xc2,0x59,0xdf,0x8f,0xb4,0x91,0x74,0x2e,0x1e,0x6d,0x20,0x70,0xe7,0x3c,0x39,0xe3,0xa8,0x62,0x66,0x32,0x63 +.byte 0x7d,0x89,0xb6,0xad,0x69,0x38,0x2c,0x21,0xe5,0x02,0xcc,0x93,0x8a,0x65,0x71,0x65,0x02,0x5c,0xeb,0xc9,0x70,0xf3,0x81,0xce,0x65,0x37,0x22,0xb7,0x47,0x3c,0xd6,0x3d,0x29,0x65,0x29,0xba,0xf9,0xae,0xd9,0x1f,0xd7,0x38,0x88,0x95,0xa9,0x66,0xa8,0x77,0x75,0x4a,0xf9,0x2e,0xd9,0x63,0x75,0x80,0x90,0x82,0x39,0x8b,0x21,0x58,0xf4,0x2e +.byte 0x2d,0x1f,0x7f,0xcb,0x33,0xdb,0x9b,0x9b,0x31,0x21,0x4e,0x6e,0xdb,0x0f,0x1f,0x69,0x22,0x97,0x69,0xd7,0x7f,0x2e,0xd7,0xce,0x6c,0xe4,0xc0,0xe7,0x27,0x82,0xe6,0x8a,0xf8,0xae,0x46,0x2d,0x5a,0x45,0x82,0xce,0xb6,0x49,0x84,0x15,0x4a,0x54,0xa6,0x76,0xf3,0x29,0x28,0xc0,0x05,0x82,0xae,0x7d,0x85,0x41,0xb0,0x87,0x67,0x44,0x37,0x46 +.byte 0x3e,0x47,0xbc,0x00,0x7c,0x05,0xd3,0xdc,0x9a,0x31,0x49,0xf8,0x48,0x99,0x57,0x4a,0x2b,0xe7,0xcf,0xb2,0xa7,0xf0,0xcf,0xc7,0xf5,0xfd,0x73,0x59,0xf1,0xe4,0x86,0xb5,0x5d,0xce,0x6d,0xbf,0xc6,0xe5,0xa9,0xca,0x75,0xe9,0x69,0xe6,0x09,0xab,0x66,0x17,0x09,0xe9,0xbc,0x14,0xd8,0x6f,0xe9,0xc2,0x87,0x39,0x2f,0x87,0x1e,0xb8,0x16,0x08 +.byte 0x10,0xee,0x1c,0x2f,0x47,0x7d,0xa3,0x5b,0x1f,0x1f,0x5d,0x95,0xd0,0xa4,0xbb,0x08,0xc2,0x47,0xab,0x46,0x3c,0xbb,0xbe,0x3a,0x64,0x82,0x40,0x08,0x75,0x03,0x02,0x6e,0x6a,0xab,0x6b,0xd4,0x90,0xa7,0x28,0x7a,0xb4,0x8b,0x1f,0x6b,0xcc,0x16,0x30,0x16,0xf5,0xc6,0xd8,0x4a,0xed,0xc9,0xc7,0xac,0x0f,0x75,0x1b,0x13,0xe3,0x45,0x6d,0x22 +.byte 0x7e,0x3d,0x59,0x55,0x87,0x8d,0x04,0xee,0x85,0xac,0x98,0x0c,0x52,0x5b,0xe6,0x92,0x04,0x31,0xdf,0x7c,0x44,0x4d,0x06,0xbe,0xb2,0x5a,0x95,0xef,0x29,0x75,0x9b,0xb2,0xe7,0xb8,0x83,0x18,0x82,0x23,0x4e,0x66,0xe5,0xdd,0x47,0xa1,0x6b,0x33,0x4e,0x9c,0x13,0x0e,0x0a,0x8a,0x5c,0xba,0x7b,0x2f,0x6c,0x72,0x78,0x86,0xd2,0xf8,0xbd,0x1b +.byte 0x4b,0x9e,0xe0,0x99,0x46,0x7f,0x24,0x0f,0x1b,0xda,0x85,0x87,0xe9,0xda,0x96,0x25,0xc6,0x81,0x77,0x8b,0x56,0xae,0x7a,0x9c,0x47,0x34,0xe1,0xac,0xf2,0xba,0x52,0x95,0xf8,0x56,0x26,0x66,0xf0,0x53,0xcc,0xc4,0x6f,0x46,0x94,0x10,0x22,0x69,0xb1,0x93,0x7b,0x51,0xb7,0xb8,0xdd,0x42,0x67,0x51,0x6d,0x9c,0xb2,0xbd,0xdb,0xdd,0x19,0xa2 +.byte 0x25,0x13,0xfe,0x42,0xca,0x36,0xeb,0xce,0x15,0x41,0xe7,0x35,0xce,0xa8,0x45,0x56,0x58,0x9f,0x46,0xcf,0x11,0xe7,0xcc,0x40,0x54,0xe4,0x85,0x0d,0x73,0x36,0x7e,0xae,0x38,0x8c,0x56,0xab,0xf0,0x5f,0x5c,0xff,0x14,0x9b,0x46,0x1b,0x35,0xbd,0x03,0x0e,0x2f,0x9e,0xde,0xd8,0x82,0xfe,0xa0,0x09,0xb4,0xb4,0xbd,0x58,0xc0,0xe2,0x01,0xb1 +.byte 0xca,0x5c,0x3d,0xc3,0x18,0x5e,0xc1,0xee,0x61,0x60,0x00,0xca,0x1e,0xf3,0x71,0xd8,0x15,0x37,0xf0,0x2e,0x13,0xa0,0xf7,0xac,0x73,0x4b,0xfb,0x6a,0x27,0x6b,0xde,0x69,0x3d,0x19,0x36,0x4b,0x63,0x55,0xae,0xd1,0x2b,0x66,0x69,0x0d,0x64,0xa7,0x86,0xfd,0x3a,0xb8,0xe6,0x87,0xaa,0x32,0x5f,0xbc,0xa7,0x67,0xde,0x7a,0xe0,0xdd,0xff,0x57 +.byte 0x2c,0xc9,0x25,0x92,0x03,0x91,0xa8,0x0e,0x39,0xe4,0x9a,0xdf,0x21,0x29,0xc7,0xbc,0x93,0x01,0x2a,0x02,0xd8,0xaf,0xbc,0x20,0x57,0xc7,0x37,0x77,0xa7,0xad,0x5e,0x15,0x20,0xcf,0x4a,0x3c,0x22,0x1b,0x92,0xa9,0x05,0x91,0x70,0xb3,0x88,0x4e,0x97,0x58,0xf7,0x33,0x1a,0x05,0x33,0x57,0xdc,0xbb,0x2a,0xba,0xd0,0x22,0xac,0x40,0xbe,0x60 +.byte 0xa2,0x89,0xe6,0x6c,0xf3,0x5d,0xef,0x58,0xb4,0x7c,0x4a,0x28,0xb8,0x16,0xd2,0xe0,0x49,0xf5,0xe8,0xaf,0x84,0x39,0xae,0x1e,0xa2,0x34,0x67,0x42,0x26,0x31,0x93,0x87,0x7a,0xd5,0xde,0x79,0xdb,0x4c,0x7e,0xcf,0x1f,0xef,0x9a,0x4c,0xb9,0x70,0xe2,0x72,0x9b,0xcd,0x30,0xe5,0xf1,0x84,0x44,0x5a,0xff,0x36,0xa2,0x37,0xe7,0x49,0x78,0x63 +.byte 0xbe,0xe0,0x90,0xdf,0xef,0x9e,0xf3,0x55,0x9e,0x8a,0x51,0xe8,0xa3,0x32,0x2d,0xed,0xc8,0x99,0xf6,0x92,0xf9,0x62,0x74,0xa7,0x8d,0xcf,0xa5,0x09,0xb3,0x43,0xb9,0x18,0x70,0x59,0x4f,0xd2,0x7f,0x7e,0xce,0x1e,0x7d,0xe8,0xa9,0xb7,0x29,0x0f,0x86,0x8a,0xac,0x22,0x41,0x98,0xb2,0xc3,0x48,0x3b,0x60,0xcb,0x7b,0x1d,0xc3,0x5e,0x19,0x5b +.byte 0x31,0x57,0x12,0x09,0x41,0x54,0xf8,0x01,0x70,0x02,0x03,0x8a,0x6e,0x8e,0x5b,0x23,0xf3,0xd4,0x13,0xbf,0x51,0xba,0xf9,0x2d,0x6c,0xb9,0xb3,0x90,0xd0,0xa3,0x76,0xfb,0xef,0x85,0x17,0x8b,0x2c,0x05,0xa3,0x06,0x0a,0xaa,0xdd,0xbf,0xd4,0xcc,0xe4,0x96,0x19,0x7f,0x51,0xf6,0x7e,0xa1,0x2c,0x14,0x1c,0x21,0x99,0x28,0x3a,0x0e,0x36,0x1b +.byte 0xf1,0xd7,0x3e,0x29,0x94,0xa6,0x03,0xf7,0xe5,0x6f,0x1b,0x56,0xc8,0xfb,0x2d,0x4f,0x12,0x2b,0xc7,0x3a,0xec,0x5e,0xc8,0x88,0x1b,0xd8,0x65,0x21,0x04,0x0e,0xe2,0x95,0x6d,0x62,0xea,0xeb,0xee,0xbe,0x47,0x0a,0x90,0x26,0xe3,0x85,0xd7,0x1d,0xb5,0xd5,0x56,0x8b,0xc0,0x2f,0x7f,0x01,0xc8,0xac,0x90,0xc3,0x2d,0x10,0xf2,0x11,0x30,0x0c +.byte 0xa9,0x4d,0x13,0xde,0x65,0x6d,0x34,0x68,0x5d,0xad,0x3f,0x7a,0x56,0x3a,0x1f,0xb9,0xd6,0x7b,0x8f,0xe8,0x42,0x2a,0x16,0xb6,0x3f,0xf2,0x4f,0x14,0x8e,0x8e,0x29,0x88,0x68,0x1b,0x10,0x80,0x80,0x47,0x36,0xaa,0x82,0xf5,0xa8,0x97,0xc4,0xcb,0xc2,0xef,0xaa,0x9f,0xdc,0x96,0x4f,0x1f,0xaf,0x39,0x71,0x55,0x8f,0x3c,0xbf,0x26,0x91,0x46 +.byte 0x38,0x59,0xa7,0xd1,0xb5,0x87,0xd6,0x81,0x71,0x17,0x83,0x05,0x40,0x9c,0xf3,0x33,0x4b,0x09,0x06,0xb1,0x69,0xfb,0x43,0x1f,0xef,0x9a,0xfe,0xc3,0x4e,0x4e,0x25,0xe1,0x3a,0xfb,0xf9,0xc9,0x97,0xe2,0x1c,0xa1,0x9a,0x06,0x6e,0xbb,0x16,0x4a,0x9f,0xf4,0x87,0x31,0x38,0x78,0xae,0x77,0x4c,0x42,0x28,0xc4,0x63,0xc0,0x49,0x37,0x4f,0xf9 +.byte 0xeb,0x31,0x0d,0x3e,0x0c,0x8a,0xb7,0x17,0xa7,0x90,0x26,0xc2,0xea,0xa5,0x9d,0xe4,0x4d,0xc6,0x3a,0x33,0x2d,0x47,0x42,0x8c,0xeb,0x50,0xea,0xfe,0x74,0x43,0x06,0xcd,0xa5,0xb1,0x49,0xf0,0x98,0x91,0x25,0xf4,0x8d,0x06,0xd1,0xeb,0x56,0x2c,0xf9,0xc4,0x84,0x02,0x9e,0xf2,0x3a,0xfe,0xb4,0x39,0xce,0xee,0x85,0xb6,0x64,0x6c,0xbc,0x1f +.byte 0xe6,0x86,0x00,0xc3,0xa9,0xb4,0x53,0xdf,0x2d,0x7c,0xc6,0xde,0x2e,0x79,0x25,0x5c,0xbb,0xe5,0xbe,0x33,0xe9,0x58,0x49,0x35,0xbe,0xae,0xbc,0x06,0xdc,0x48,0x9d,0xc3,0x08,0x6f,0xe8,0xb8,0x48,0x67,0xea,0x1c,0x05,0xb4,0xf7,0xe3,0xcc,0xc1,0xb3,0xa8,0x61,0xcb,0xa8,0xf6,0x12,0x52,0x68,0x06,0x36,0x2b,0x15,0x43,0xc9,0x98,0xfe,0xe5 +.byte 0x43,0x11,0x0d,0xc3,0x37,0x38,0x7a,0xcb,0x98,0x14,0xc1,0xaf,0x29,0x36,0x35,0x63,0x74,0x98,0xcf,0x0f,0x44,0xe4,0x6e,0xf7,0x3f,0x6e,0x15,0xe8,0xe9,0x93,0x7b,0x96,0x1b,0x84,0xe7,0x8b,0x83,0x30,0xa1,0xdc,0xc3,0xb8,0x18,0x2f,0xc5,0x34,0xd1,0xa5,0xb9,0xee,0x4a,0x04,0xbf,0x26,0x63,0x29,0xba,0x90,0xb5,0x7c,0x83,0x2b,0x1f,0xe8 +.byte 0x5c,0x9f,0x23,0x40,0x7f,0x9c,0x2f,0x76,0x96,0xd6,0xd5,0x13,0xda,0x5c,0x81,0xa4,0x60,0x60,0xbd,0x5e,0xb3,0xd2,0x2c,0xaa,0x48,0x04,0x74,0x31,0x5d,0xbd,0x46,0xd8,0x8d,0x3f,0x62,0x2d,0x1e,0x17,0x97,0x08,0x71,0x06,0x1b,0x96,0x1b,0xd5,0x80,0xa6,0x41,0x06,0x10,0x6e,0x36,0xd4,0xfb,0x36,0x6d,0x96,0xb8,0x86,0x22,0x34,0xda,0x7e +.byte 0x6c,0x5f,0x3b,0x95,0x35,0x1b,0x42,0x3c,0xf2,0x9d,0xe3,0xe9,0x3f,0x44,0xd5,0x4c,0x60,0x55,0xae,0xbe,0x4f,0xf2,0xb3,0x84,0xa1,0x79,0xdf,0x86,0xf0,0x8f,0xad,0xa5,0xa3,0x4a,0xea,0x5d,0x68,0x34,0x17,0x4c,0xb7,0xd8,0x6f,0x67,0x22,0x85,0xe2,0x16,0xcf,0xba,0xee,0x92,0xeb,0x95,0x8e,0x67,0xb1,0xf0,0xbb,0xb0,0x34,0x2f,0x58,0x49 +.byte 0x56,0x3e,0x81,0x31,0xb6,0xc3,0x2c,0xee,0x2b,0x85,0x72,0xbc,0xe9,0x20,0xaa,0x4e,0x34,0xb9,0x8b,0x32,0x2f,0x9e,0xd7,0x98,0x63,0x9d,0xfd,0x3a,0xe9,0x30,0x49,0x23,0x4a,0xb4,0xcb,0xc5,0xe5,0x78,0xcd,0x22,0x90,0xce,0x9f,0x35,0x13,0xda,0x8f,0x14,0xdb,0x36,0x0f,0x66,0x87,0x62,0x50,0xde,0x52,0x15,0x10,0x67,0x8a,0x5c,0xdb,0x76 +.byte 0x51,0x7f,0x72,0x9b,0x8e,0x91,0x39,0xc8,0x3c,0x34,0x0f,0x3d,0x92,0x07,0xb8,0xef,0x2a,0x8b,0x59,0xbd,0x82,0xc1,0x5c,0x95,0x93,0x0d,0x3d,0x9b,0x51,0x53,0x38,0x6b,0xd0,0xe3,0x5b,0xbb,0xe5,0x6c,0xc0,0xb5,0x71,0xa8,0xd8,0x7d,0x5d,0xbd,0xfc,0x69,0xcf,0xcc,0xa1,0xcd,0x83,0x9d,0x8f,0x46,0x47,0xe7,0x36,0x19,0x9f,0x4d,0xda,0x9c +.byte 0xcb,0x2a,0x47,0x58,0x93,0xbb,0x64,0xa3,0x89,0x53,0xbf,0xc7,0xc2,0xe2,0x65,0x0f,0x4f,0x17,0xc6,0x4c,0x15,0xfe,0x4b,0x95,0xb2,0x79,0x4a,0xb8,0xf6,0xae,0xcc,0xba,0xc3,0x5d,0x18,0xb2,0x8e,0xd8,0x6b,0x43,0x1b,0x2f,0xe1,0x36,0xb2,0xa5,0x22,0xa0,0xc7,0xc0,0x26,0x8e,0x48,0x77,0x0c,0x14,0xdd,0xdc,0xde,0x71,0x98,0xce,0xdd,0x61 +.byte 0x85,0xd9,0x23,0x42,0x7f,0x85,0xc8,0x06,0x81,0x3e,0xa2,0x0f,0x1e,0x3e,0xcf,0x33,0xef,0x43,0x6a,0xc7,0xee,0x3f,0x91,0x68,0x32,0x89,0xd9,0xed,0xdf,0x45,0x33,0x10,0xbb,0xd5,0xef,0x1d,0x3c,0x1e,0x26,0x21,0x4d,0x1a,0x06,0x98,0x60,0x71,0x7f,0xce,0x45,0x4e,0xe3,0x3f,0xfa,0xff,0xcd,0xe2,0x92,0x82,0x2e,0x83,0x69,0x9c,0xc6,0x5c +.byte 0x6e,0xb6,0xec,0x28,0xdc,0x7b,0xdb,0xf3,0x02,0x3a,0xf7,0xad,0x9b,0x7a,0x73,0xb2,0x07,0x70,0x76,0x9d,0xa2,0x11,0xcf,0x89,0xea,0xaf,0x6a,0xd2,0x15,0xeb,0x5a,0x99,0x1a,0x17,0x1d,0xce,0xc0,0x7f,0x50,0x26,0x84,0x07,0xd7,0x7e,0x33,0x27,0x74,0x84,0x18,0x32,0x86,0x32,0x34,0x28,0xe8,0x45,0x21,0xb7,0x26,0x3b,0x11,0xbb,0x9a,0x8b +.byte 0x46,0x8e,0x27,0xf8,0x62,0xb5,0x98,0x6e,0x03,0xee,0x9e,0xcb,0xbc,0x74,0xbe,0x63,0x7a,0x86,0xe5,0x75,0xeb,0x7f,0x14,0xa6,0x96,0x76,0x5a,0x46,0xa9,0xda,0xf1,0x4e,0x0e,0x90,0x59,0x56,0x4a,0x48,0x2d,0x91,0xbe,0x78,0x5b,0xfb,0xf7,0xea,0xab,0x1c,0xc0,0x0c,0x5d,0xba,0xb4,0x7b,0xc7,0x21,0xb1,0xc9,0xa3,0x20,0xe6,0xae,0xee,0x0e +.byte 0xf0,0x3b,0x44,0xd6,0xaa,0x57,0x88,0x1f,0x76,0xc8,0x43,0x07,0x91,0x71,0xa5,0xcc,0x04,0x38,0x01,0x13,0xa6,0xea,0x18,0x48,0x8f,0x09,0x8d,0x37,0x8b,0x6f,0x35,0x36,0x51,0xc6,0x30,0xca,0x9e,0xe2,0xaf,0x0c,0x26,0x14,0xe3,0xbf,0xea,0x0e,0x14,0x88,0x97,0xcc,0xf6,0xc1,0x8f,0xad,0xef,0x2d,0xc1,0x0f,0xad,0x45,0x12,0x7a,0xe6,0x37 +.byte 0x97,0xcb,0x34,0x83,0xd8,0xef,0x34,0x2a,0xce,0xd0,0x21,0x8a,0x7d,0x87,0x7a,0x66,0xf7,0x1c,0xdf,0xa0,0x3f,0xa0,0xf6,0xb3,0x24,0xee,0x6e,0x21,0xe9,0xc3,0x73,0xe4,0xd9,0xc6,0xf6,0xf6,0xac,0x25,0xb7,0xb5,0x64,0x7f,0xcc,0x88,0x3e,0x98,0xe1,0xef,0xa9,0xd2,0x03,0x10,0x4b,0xa3,0xbc,0x3c,0x24,0xfc,0x41,0x36,0x30,0x2d,0xca,0x17 +.byte 0x35,0xd6,0x17,0xa2,0x2b,0x48,0xed,0xd3,0xd7,0x18,0x4f,0x45,0xe9,0x59,0x03,0x35,0xa0,0x80,0x75,0x17,0x48,0xd5,0xea,0x07,0x7a,0x6c,0x3f,0x7a,0x2c,0x02,0x0a,0x7f,0xb5,0x17,0xea,0xf4,0xf6,0xb5,0xf4,0x81,0xba,0x69,0x44,0x81,0x6b,0xff,0xb2,0x43,0xae,0x3d,0x37,0x81,0x91,0x3f,0x6a,0x70,0x35,0x2d,0x06,0x9d,0xa8,0xb5,0xb8,0xc7 +.byte 0x19,0x3a,0x5f,0x59,0x79,0x0b,0x62,0x23,0xa4,0x5b,0x46,0x7b,0x17,0x82,0x19,0x87,0xe8,0xdf,0x09,0xb7,0x50,0x7e,0x40,0xe3,0x71,0x2d,0x09,0xde,0x69,0x2e,0x6c,0x35,0x5c,0x44,0xae,0xb7,0x05,0xb8,0x7e,0xb4,0xe4,0x34,0x05,0x1f,0xd2,0x1f,0xe5,0x79,0x2a,0x15,0xf8,0x8f,0x02,0xc7,0xc8,0x1e,0xe6,0x12,0x83,0x08,0x9c,0x7a,0x2f,0xc6 +.byte 0xc9,0x15,0x0f,0x0f,0x0f,0xa9,0x53,0x16,0x19,0x5b,0x74,0x58,0x6c,0xac,0x21,0x72,0x7f,0xa1,0xae,0xbc,0x34,0x76,0xa6,0x9b,0xbe,0x0f,0x13,0x55,0x50,0x5a,0x8b,0x9e,0xb3,0xf3,0x9e,0x8b,0x61,0xbe,0xb4,0x09,0x71,0x61,0xf0,0xd6,0xaa,0x8c,0x0d,0x0c,0x66,0x31,0x88,0xe3,0x71,0x6a,0xb5,0xaa,0xc0,0x9b,0xce,0x0d,0x79,0x90,0xc1,0x0a +.byte 0xf9,0xfe,0x4d,0x49,0xd0,0x5a,0x63,0xf1,0xfc,0x47,0x71,0x9e,0xbb,0xd1,0x2c,0xef,0xfe,0x90,0x28,0x75,0x82,0xf6,0xa5,0x95,0xea,0x65,0xfa,0xe8,0x04,0xcd,0xb4,0xe1,0x0d,0xb2,0xac,0xd5,0x12,0xf5,0x17,0xbb,0x3b,0x2e,0x52,0x9e,0x7b,0xe7,0x8e,0x86,0x03,0xce,0x77,0x01,0xf0,0x4f,0xb5,0xf7,0xef,0x8b,0x37,0x5e,0x97,0x80,0xbb,0x2b +.byte 0xcf,0x9a,0x63,0x18,0xc5,0x0c,0xfb,0x3c,0x91,0x9c,0x37,0x90,0x76,0x71,0x62,0xbc,0x80,0x40,0x1a,0x74,0xb8,0x1b,0x61,0xb1,0x89,0x4d,0xf7,0x8d,0xd4,0x46,0xef,0x1f,0x3b,0xac,0xe8,0x41,0x62,0x8e,0xea,0x2b,0x56,0x22,0x25,0x37,0x70,0x53,0xcd,0x8f,0x57,0xfa,0xad,0x00,0xc5,0x0c,0x9e,0x57,0xde,0x50,0x07,0x8d,0x80,0xbf,0x22,0x5d +.byte 0x4a,0xbd,0x6a,0xcb,0xfc,0x6f,0xd1,0x56,0x8f,0xd5,0x34,0x8a,0xe6,0xe9,0xa0,0x00,0x06,0x12,0xd8,0xb1,0x49,0x0a,0xbb,0x87,0xe5,0xca,0x75,0x11,0x4c,0x85,0x60,0x77,0xc0,0x90,0x1c,0x14,0x38,0x38,0x3e,0x4f,0xff,0xbf,0xfc,0xa1,0xa1,0xe7,0xb0,0x5d,0xd8,0x1f,0x33,0x07,0x5f,0x04,0x4f,0xc7,0x93,0xc6,0xcc,0xe3,0x01,0xd0,0x43,0xe1 +.byte 0xd9,0x00,0xc5,0x9f,0x79,0xab,0xfc,0xe9,0x55,0x51,0x03,0x0c,0xe1,0x73,0xd6,0x09,0xe3,0xb9,0x76,0x72,0x77,0x4c,0x1b,0x7c,0x57,0x1e,0x7f,0x5f,0x02,0x83,0xa3,0xc6,0xde,0x23,0x85,0x76,0x1a,0xbf,0x48,0xc8,0x02,0xdb,0x31,0x30,0x95,0x85,0x68,0x8a,0xf6,0xe9,0x48,0x7f,0xc9,0x26,0xab,0x68,0x36,0x9f,0x1c,0xf0,0x90,0xbc,0x4a,0x68 +.byte 0x94,0xf8,0x7f,0xae,0xa9,0x3b,0x5b,0x63,0x9a,0xcd,0xe3,0xf0,0xac,0x9f,0x6f,0x78,0xa0,0x67,0x58,0xd8,0x2c,0x71,0x8a,0x14,0x31,0x07,0x95,0x0c,0x38,0xa4,0x53,0x33,0x60,0x23,0x21,0x87,0x6b,0x4f,0xf9,0xa8,0xb8,0xfc,0x8e,0xf1,0x3a,0x03,0x0b,0x03,0x02,0x33,0xbc,0x6a,0xb9,0x8e,0x41,0xc8,0x38,0xd8,0x83,0x30,0x6a,0x61,0x5c,0xcf +.byte 0x49,0xdd,0xd7,0xda,0x2c,0xaf,0xc4,0x68,0xad,0x07,0x9c,0xd4,0xaf,0x94,0x64,0xcf,0xe1,0x9b,0x37,0x50,0x65,0x03,0x20,0x3c,0x34,0x43,0xe9,0xb0,0x9b,0xba,0xb1,0x9a,0x3e,0x10,0x99,0x8f,0x93,0xb7,0x3d,0xac,0xbd,0xab,0xa8,0xfa,0x74,0x90,0xe1,0x38,0xe4,0xf3,0x47,0xfc,0xad,0x8b,0xb4,0x98,0xe4,0x65,0xe9,0xd9,0x8a,0x21,0x81,0x4f +.byte 0x0c,0xd7,0xb1,0x84,0xb9,0x69,0x68,0x64,0xa3,0x1f,0x25,0x84,0x5f,0xf7,0x3f,0xca,0x52,0xff,0xda,0xc9,0x3d,0x5e,0x8b,0x57,0xd3,0x9a,0x1d,0xb7,0xae,0x90,0xa4,0xc3,0x78,0x68,0xfd,0x80,0x3f,0xfd,0x5c,0x09,0x83,0x5d,0xc2,0x48,0xd8,0x84,0xeb,0x8a,0xfe,0xbe,0x30,0x12,0x79,0x54,0x5f,0x7f,0x6e,0x4b,0x8a,0x1e,0xcb,0xcd,0xed,0xb6 +.byte 0xe9,0x6d,0x8a,0x1f,0xdc,0xb1,0x46,0xab,0xdc,0x0d,0xbf,0xda,0xd9,0x39,0x3b,0xd2,0x81,0x00,0x83,0x77,0x32,0xf7,0xdf,0x0e,0x31,0x5d,0x1d,0x6c,0xa7,0x4e,0x54,0xa8,0xac,0x81,0x8c,0xb6,0xa5,0x89,0x02,0xd7,0x2e,0xfd,0x26,0xa3,0x9e,0xcf,0xdb,0x1f,0x5a,0xf3,0x54,0xac,0xe5,0xd0,0x1f,0x9b,0xa7,0xab,0x28,0xcc,0x66,0xd3,0xbc,0x4c +.byte 0x54,0x1a,0x54,0x73,0x78,0xde,0x08,0xd5,0xa5,0x08,0xdc,0x00,0x09,0xc5,0x37,0x61,0x1a,0x98,0x12,0x84,0x2d,0xff,0xc3,0x25,0x62,0x93,0x83,0x05,0x66,0x3d,0xfb,0x1d,0x54,0x08,0x8a,0x50,0x03,0xc4,0xc4,0x6e,0xfa,0x16,0x83,0xbb,0x27,0xf1,0xb7,0x31,0x92,0x64,0x76,0xbc,0xf0,0x44,0x62,0xe9,0x5e,0x15,0x94,0xdc,0xe9,0xf3,0xf8,0x20 +.byte 0x93,0x4d,0x11,0xa2,0xc8,0xde,0x83,0xe6,0x75,0x63,0xfe,0x13,0x75,0x0f,0x79,0xd1,0x3d,0x75,0xb7,0x43,0x62,0x57,0x8d,0x96,0x9c,0xa3,0xc4,0xb2,0x84,0x6a,0x14,0x6e,0x17,0x32,0x09,0x76,0x95,0xbb,0xd6,0xc1,0x2e,0xdc,0x8c,0x73,0xd7,0xad,0x5a,0x41,0x8b,0xb3,0x7e,0x8d,0x90,0xec,0xf5,0xa0,0x46,0x90,0x4c,0x52,0xec,0x97,0xc6,0x98 +.byte 0x7d,0x19,0x77,0xa0,0x99,0x85,0x11,0x26,0x77,0x26,0xf9,0xac,0xe3,0x81,0xcf,0x7d,0x22,0xc8,0x00,0x3d,0x5b,0xee,0xa5,0xf8,0x6d,0xfe,0x47,0xe4,0xef,0x60,0xcc,0xd0,0x33,0xf7,0x5b,0xed,0xbd,0x82,0xc9,0xa8,0x41,0xb8,0x47,0x34,0x9f,0x62,0xb2,0x67,0x62,0xb0,0x3a,0x27,0x95,0xe1,0x22,0x76,0x98,0x0f,0x35,0xaf,0xfc,0x4d,0xc7,0x92 +.byte 0x92,0x7e,0xaf,0x3b,0x3a,0x36,0x5e,0x5c,0xbf,0x43,0x02,0x66,0x5a,0x30,0x78,0x82,0x52,0x20,0x98,0xd6,0xa1,0xe9,0x9a,0x61,0x54,0x0b,0x74,0x85,0xb5,0x99,0x69,0x9f,0x9b,0x3b,0x2f,0x49,0xec,0xb3,0x18,0x0c,0x4a,0x53,0x20,0xd7,0x80,0x7b,0xd4,0x20,0x21,0x32,0x89,0x08,0x81,0x50,0x2b,0x16,0x8d,0xbb,0xe6,0xbb,0xc7,0x74,0x80,0x67 +.byte 0x47,0xf1,0x06,0x68,0x02,0x37,0x31,0x00,0x50,0x8b,0xe2,0x44,0x85,0x2e,0x39,0x54,0xda,0x26,0x7b,0xe1,0xb0,0x23,0xd7,0x0c,0x3c,0x3b,0x81,0x9b,0xa6,0xbe,0x24,0xfd,0x09,0x73,0xbe,0xc3,0x2f,0xa0,0x7b,0x85,0x5b,0x1b,0x55,0x4e,0x9e,0x38,0x80,0x61,0xd7,0xe8,0x9b,0xec,0x88,0x00,0x6a,0x64,0x1b,0xd5,0x65,0x20,0x2a,0x62,0x64,0xbc +.byte 0x21,0xca,0xce,0xc3,0xeb,0x2d,0x2b,0x5c,0x4d,0xb8,0x7c,0xb5,0xbe,0x98,0x0d,0x5b,0x88,0x23,0x60,0xff,0xbe,0x0a,0xb6,0xdd,0xdf,0x28,0xd5,0x2c,0xe5,0x9d,0xb5,0x29,0xea,0x6c,0x3a,0xf4,0x78,0x91,0xa3,0xb2,0xab,0x12,0xf9,0x90,0x96,0xc9,0xa4,0xfc,0x4d,0x28,0x2b,0x0c,0x28,0x8b,0xb7,0x8b,0x36,0xd6,0x80,0xbf,0x07,0x09,0xf9,0x62 +.byte 0x32,0xc0,0x50,0x60,0xd9,0x73,0xe3,0xbe,0xfa,0xa6,0x78,0x48,0x47,0xd7,0xb5,0x39,0xd8,0x04,0x6d,0x79,0x98,0x2e,0xd6,0x3a,0xe5,0xc9,0x01,0xd0,0x00,0x2e,0xd2,0x8b,0xd7,0x1f,0xf1,0xba,0xd4,0x0e,0x9f,0x9d,0xab,0xbf,0x2c,0xe1,0x75,0xf6,0x9c,0xc0,0xae,0x73,0x2b,0x58,0xcb,0x6d,0x46,0x6d,0x11,0xb7,0xce,0xc7,0xef,0x34,0x2c,0x11 +.byte 0x93,0x3c,0x17,0xd9,0x3e,0xad,0xc9,0x4c,0xb3,0xd0,0x0a,0xd0,0xfe,0xf3,0x9d,0xc5,0x43,0x03,0xa9,0x78,0x4a,0x42,0x7f,0xfb,0x75,0xd2,0x85,0xfb,0xe7,0xe6,0xa9,0x48,0x2f,0xa6,0xc3,0x16,0xe2,0x2a,0x9d,0x0d,0xcb,0x2e,0x8b,0x75,0xa8,0x14,0x3a,0x2e,0xb1,0xff,0x58,0x1d,0xa8,0xa6,0xc0,0xf6,0x17,0xda,0xc1,0xce,0xaf,0x08,0xa9,0xc2 +.byte 0xa3,0xc1,0xab,0xb6,0xe8,0x10,0x57,0x8a,0xce,0xc0,0x03,0x5c,0x53,0x5c,0x02,0x5d,0xcf,0x5c,0x65,0xc6,0x47,0x3c,0x62,0x0e,0xa3,0xfc,0xe2,0xae,0x10,0x55,0x4a,0xb4,0x27,0xe8,0x59,0x5e,0x45,0xa9,0xbb,0x21,0x10,0x91,0x46,0x1f,0x50,0x3b,0xc6,0x8c,0xa1,0x8a,0xee,0x5e,0x6e,0x32,0xe6,0x42,0x40,0x79,0x7f,0xbb,0xb3,0x5b,0x05,0xde +.byte 0xe0,0xf6,0x7f,0x3d,0x37,0xe6,0xc3,0x3b,0x40,0xc9,0xe0,0x42,0x36,0xd0,0x0e,0x13,0x32,0x3e,0x48,0xce,0xd8,0xa2,0xef,0xae,0x93,0x66,0x7d,0xde,0xb9,0xdd,0x60,0x15,0x53,0xf2,0xd9,0x90,0x3d,0x38,0x8c,0xa6,0x34,0x44,0xb5,0x6c,0x74,0x7d,0x9d,0xe7,0xd0,0xef,0x6c,0xd6,0xfe,0x9b,0x79,0x4e,0x79,0x5e,0x48,0xef,0x93,0xb2,0x81,0x0b +.byte 0x2b,0xee,0x83,0x69,0x3d,0x15,0x8c,0x27,0x69,0x6f,0xca,0xbf,0x75,0x29,0x37,0xc6,0xe6,0xca,0xb2,0x70,0xd0,0xaf,0xc8,0x5e,0x69,0xf1,0x6b,0x2d,0x0d,0xe7,0xe9,0xbf,0x07,0x52,0xe5,0xac,0x98,0xcf,0xcf,0xd6,0xdd,0x7c,0x2b,0xfc,0x8f,0xd2,0x5f,0x81,0x4b,0x1b,0x7b,0x2d,0x84,0xe2,0x69,0x96,0xcb,0xa2,0x59,0x10,0xba,0xda,0x51,0x11 +.byte 0xeb,0xc3,0x4f,0x10,0xbf,0x8e,0x5b,0xbb,0xa3,0x29,0xe9,0xd8,0x0e,0x71,0xa0,0x1b,0xff,0xee,0x36,0x8c,0x00,0x83,0x6b,0x32,0xfe,0x05,0xeb,0x89,0x8f,0xed,0x48,0x22,0xe1,0x76,0x0a,0xac,0xae,0x3c,0x24,0x54,0x84,0xc2,0x0f,0x79,0x33,0x2b,0x49,0x35,0x1c,0x84,0x5a,0xca,0x92,0x6c,0x1f,0x78,0x15,0x5a,0x36,0xad,0xd5,0x1d,0x9d,0x10 +.byte 0xc1,0x5f,0x7c,0x61,0x60,0xba,0x2e,0xe6,0x9b,0x34,0x02,0xe9,0x68,0x1c,0xfb,0xbf,0x02,0xdc,0x79,0x57,0x1c,0x0f,0xc8,0x8c,0x2a,0x66,0x2a,0x50,0xaa,0x81,0x4e,0x1f,0xa8,0x2d,0xe4,0x61,0xe8,0x43,0x84,0xcb,0xda,0x96,0xf9,0x4a,0xd0,0x8f,0xe1,0xd7,0xc4,0x05,0xf5,0x76,0xfa,0x47,0x7a,0x07,0x1a,0x77,0xbb,0x63,0xb3,0x3a,0x85,0x3b +.byte 0x0d,0x32,0x4f,0x14,0x15,0x02,0x5b,0x9c,0xbc,0xc2,0x12,0x90,0x0f,0x7b,0x94,0x27,0x5f,0x70,0x23,0xd8,0x5d,0x54,0xc4,0xca,0x6a,0x69,0x9e,0xd1,0xb3,0x2a,0x75,0x1a,0x07,0x9c,0x20,0xf6,0x76,0x22,0x4d,0x09,0x30,0x24,0x3f,0x3b,0xe5,0xcb,0x4b,0x5a,0x03,0x2d,0xe8,0xbe,0xed,0xf0,0xe3,0x91,0xf2,0x6c,0xb8,0x02,0x2d,0x6c,0x7a,0xa6 +.byte 0xc1,0x8e,0xa7,0xbb,0x73,0xdf,0x40,0xa5,0x60,0x91,0xbf,0xbe,0x28,0x0b,0x37,0x2e,0x5f,0x4b,0xcd,0x14,0x4d,0x2d,0xfc,0x5e,0x43,0xb5,0x78,0x8d,0xea,0xa0,0x86,0x54,0x4f,0xb6,0x25,0x40,0x39,0x3f,0x9c,0x7a,0x26,0x74,0x88,0x42,0x53,0xb0,0x3b,0x81,0x75,0x04,0x67,0x41,0x65,0x66,0x2c,0xdc,0xe9,0xf0,0xb3,0xab,0x2a,0xa5,0xf3,0xef +.byte 0xfa,0xc5,0x10,0x63,0xe2,0x70,0xb5,0x29,0x60,0x86,0x9e,0xb9,0x0b,0xe2,0xc4,0x05,0xa9,0x3c,0x1b,0x60,0x15,0x6b,0x2f,0x74,0x93,0x5e,0x70,0x9a,0x56,0x6a,0xc4,0x92,0x49,0xaa,0x95,0x51,0xc4,0xba,0xfd,0xf6,0x2d,0x36,0x3e,0x66,0xbd,0x74,0xbc,0x2e,0xb3,0xad,0xa1,0x41,0x50,0x33,0x79,0x84,0xac,0x21,0x7a,0xfc,0x3a,0x8e,0xdb,0xcc +.byte 0x27,0xf6,0x2c,0x5c,0x23,0x38,0x73,0xd5,0xaf,0xc9,0x2d,0x9c,0x18,0x58,0xdf,0x8f,0x89,0x9d,0xdd,0x00,0x3c,0x5f,0x23,0x00,0x6e,0x66,0x1d,0xf3,0x1c,0x40,0x9d,0x43,0xb0,0x74,0xf1,0x41,0xa5,0x77,0xcb,0x8d,0x5b,0x94,0x68,0x95,0xb6,0x0e,0xd4,0x4d,0x47,0x9b,0xd2,0xcd,0x9b,0x94,0xa4,0x28,0xf9,0xf0,0x3d,0xcf,0x89,0xb1,0xc3,0x73 +.byte 0x84,0x15,0xb6,0xc8,0x6b,0xf1,0xb1,0xdc,0x1b,0x1a,0x6f,0xb5,0x73,0x87,0x8b,0x63,0xbf,0x4b,0x25,0x9b,0xe4,0xdd,0x44,0xed,0xe7,0x0e,0x6f,0x03,0xae,0xa1,0x5e,0x1f,0x5f,0xa7,0xa4,0xed,0x69,0x7a,0x91,0x6d,0x55,0xac,0xce,0x18,0x32,0x17,0x78,0x49,0x9f,0x1e,0x9c,0xd2,0x7b,0x1f,0x74,0x60,0xa5,0x64,0xb1,0x99,0xe6,0xc5,0x0d,0x69 +.byte 0xfa,0xb2,0xd9,0x05,0x61,0x71,0xa4,0x6f,0xc2,0xb6,0x91,0x0e,0x6c,0xf2,0xa6,0x6c,0xea,0x8e,0x94,0x8b,0xac,0xa7,0xfe,0x70,0x8e,0x8d,0xc2,0x85,0xa6,0xa7,0x8e,0xe8,0xfa,0xbc,0xa1,0xaf,0x0e,0xa9,0x06,0xa4,0x9a,0xb0,0x23,0x93,0xbc,0x93,0x2d,0x97,0x42,0xe2,0x0d,0x3a,0x65,0xb4,0x60,0x5b,0xeb,0xa1,0x20,0x8a,0xdc,0x17,0x6b,0xc5 +.byte 0x19,0xc3,0x67,0xbf,0xae,0xf7,0xb9,0xb1,0x88,0x7f,0xe5,0x1b,0xc2,0x61,0x97,0xa0,0xd3,0x64,0x74,0x6b,0x7a,0x46,0x39,0x3f,0xc8,0xd3,0x53,0x79,0x74,0x4e,0x1e,0x63,0x91,0xc5,0x4a,0x70,0xb0,0x05,0x35,0x19,0xc2,0x26,0x54,0x44,0x3b,0xa9,0x12,0x40,0xd0,0x21,0x19,0xf3,0x8d,0xc7,0x2b,0x88,0x9a,0xec,0x41,0x8f,0x4f,0x23,0x19,0x1a +.byte 0xf3,0x1d,0x0a,0x88,0x0f,0xa7,0x02,0xd4,0x78,0x88,0xe6,0x43,0xb6,0x9e,0x07,0xdf,0x6a,0x1f,0x41,0xbb,0x3e,0xea,0x15,0xff,0x66,0x4c,0x7a,0x8b,0xee,0x27,0x47,0x81,0x81,0x95,0xa2,0x22,0xb4,0x9f,0x1c,0x09,0x1c,0xfc,0x0a,0xef,0x88,0x7f,0x59,0x60,0x91,0x6a,0xe4,0x92,0x8c,0x02,0x54,0xc9,0xee,0xc7,0x5e,0xd1,0xbf,0xc9,0x41,0xde +.byte 0x2f,0xa3,0x22,0x07,0x1d,0x8c,0xe1,0x04,0x59,0x94,0x75,0x3e,0xee,0x56,0x62,0x07,0x80,0x18,0x60,0x78,0x0e,0x55,0x06,0xec,0xe1,0xa5,0xf6,0x21,0x7e,0xf9,0x37,0xab,0x6a,0xed,0x07,0xcb,0xbf,0xa2,0xab,0x50,0xee,0x1f,0x2f,0x54,0x2b,0x82,0x93,0x59,0x03,0x35,0xd9,0xe8,0x2b,0xa6,0x03,0xc2,0xef,0x37,0x85,0xfc,0x89,0x06,0x30,0xe0 +.byte 0xc2,0x00,0xc4,0xaf,0x59,0xb6,0x31,0x52,0x37,0xa4,0x6c,0xdb,0x1b,0x20,0x87,0xf0,0xa4,0x15,0x4b,0xa8,0xd9,0x7e,0x1b,0x96,0x00,0x07,0xf4,0x86,0x07,0x14,0x55,0x70,0x37,0xe3,0xe3,0xf0,0xeb,0xd6,0xf1,0xe0,0xe9,0x6c,0xdf,0x3d,0xaf,0x86,0xb8,0x00,0x9b,0xdf,0xc6,0x5c,0xd2,0x53,0xcb,0xcf,0x63,0xcc,0x3e,0x6d,0x62,0xeb,0xe6,0x97 +.byte 0xd8,0x54,0xed,0x36,0xe4,0xed,0x69,0xaa,0x10,0x83,0xde,0x16,0xfd,0xcc,0xd6,0x24,0xb9,0x3c,0x4f,0x99,0x81,0xc2,0x23,0x16,0x91,0x5d,0x9f,0x46,0xa5,0xdd,0xb4,0x8a,0xe1,0x07,0x89,0x84,0x2e,0x62,0x48,0xf6,0x1a,0x17,0x7b,0xc8,0xf7,0xb4,0x3d,0x9e,0x82,0xe3,0xe3,0xcf,0x0b,0xd9,0x52,0x90,0x61,0xd8,0xdf,0x9e,0xc4,0xc7,0x7c,0xfa +.byte 0xcf,0x09,0xd2,0x94,0x86,0x37,0x94,0xaf,0x7e,0x0a,0x9d,0x16,0xee,0xad,0xfb,0xa2,0x9e,0x2d,0x2f,0xad,0xd5,0xc2,0xf9,0x91,0xf8,0x7e,0x2b,0xb8,0xb2,0x60,0x3c,0x0a,0x89,0x53,0x07,0x87,0x3b,0x83,0x70,0xee,0x71,0xa3,0x94,0x0b,0x77,0x50,0xeb,0xcc,0x23,0xf0,0xbe,0x95,0x51,0x54,0xd2,0xd6,0xd2,0x09,0xa5,0x19,0x3d,0x4e,0xec,0xe3 +.byte 0x88,0x71,0xa7,0xb1,0x10,0x03,0x7e,0xc4,0x92,0x2a,0xe7,0x99,0x75,0xff,0xae,0x10,0x3d,0xbb,0x33,0xc9,0x7f,0xc2,0xe6,0x3c,0xc4,0xe7,0xba,0x37,0xba,0x68,0x69,0x92,0x4a,0xfb,0x32,0x3b,0xb5,0xde,0xdb,0x91,0xd0,0x8e,0x77,0xf2,0x1e,0x2d,0x25,0xb4,0xa0,0x42,0xef,0x78,0x6c,0x75,0xcb,0xa0,0x73,0xdf,0xde,0xd8,0x26,0xfe,0xe3,0xf9 +.byte 0x74,0xe7,0xa0,0xd2,0xbd,0x6c,0x99,0x8d,0x07,0xf2,0xf8,0xff,0x36,0x2d,0x8e,0xda,0x5e,0x5c,0x47,0x06,0xf8,0x08,0x33,0x1d,0x93,0xcf,0xc3,0x1a,0x20,0x86,0xb6,0x8e,0x44,0x10,0xbc,0xba,0x89,0xfc,0xa3,0x57,0x92,0x2c,0x28,0xa1,0xd0,0xab,0xdc,0xba,0x0a,0x7e,0x9d,0xd2,0xfd,0x09,0xd3,0x87,0x6c,0x06,0x44,0x17,0x73,0xfe,0xc9,0x8b +.byte 0x52,0xd3,0x09,0x60,0x14,0x03,0xb1,0x79,0x4c,0x9c,0xc4,0xec,0x42,0x4c,0xd3,0x21,0xe5,0x34,0x21,0x38,0xdd,0x12,0x95,0xd4,0x20,0x50,0xef,0x5f,0x46,0x4f,0x37,0x65,0xd5,0xf1,0xb2,0x2c,0x6c,0x9a,0x06,0x28,0x77,0xbf,0xe3,0xec,0xec,0x2b,0xcb,0x2c,0x8b,0x62,0x2e,0x39,0xaa,0x28,0x0b,0x51,0x01,0xa5,0x02,0x06,0x66,0x4a,0x67,0x0c +.byte 0x96,0xa3,0x12,0x74,0x94,0x2c,0x0f,0x23,0xa3,0xea,0xda,0x1a,0x6d,0x54,0x30,0x33,0xc8,0x33,0x0a,0xfb,0x25,0x2a,0x8b,0x9a,0x87,0xd9,0x9d,0x37,0x4c,0x41,0x3b,0xe5,0x4a,0x81,0x92,0x40,0x38,0x18,0x82,0x13,0x54,0xde,0x56,0x11,0x63,0xf3,0x09,0x61,0x3b,0xdd,0x0c,0x71,0xe8,0x4f,0xc2,0x9a,0x77,0x2f,0xeb,0xf1,0x39,0x1c,0x10,0x0e +.byte 0x01,0xaf,0x92,0x34,0x9a,0xb6,0x7b,0x79,0x86,0x0c,0xf1,0x53,0xb6,0x59,0xbd,0x6d,0x79,0x6e,0x37,0x11,0x25,0x67,0x95,0x31,0x4f,0x43,0xdf,0xb7,0x4b,0x80,0x8d,0x07,0x3c,0x49,0x73,0x8a,0x72,0x61,0x02,0x0f,0x2f,0x13,0xed,0x91,0x10,0xf6,0x08,0xf3,0x50,0x4a,0xd4,0x36,0xcb,0x52,0xb3,0x3b,0xe6,0xef,0x85,0xe9,0xe0,0xad,0x0d,0x3d +.byte 0x84,0x07,0x70,0xdf,0x16,0x47,0xeb,0x26,0x19,0x27,0xaf,0x7a,0x9f,0x2f,0x2b,0x6d,0xbb,0x37,0x68,0x8e,0x19,0x46,0x5a,0x65,0x0d,0x0a,0x67,0xd8,0xe2,0xc2,0xcd,0x49,0xf6,0xc2,0x27,0xac,0x12,0xea,0x1f,0x81,0x60,0xac,0x8b,0x5d,0xcc,0x9a,0x5b,0xec,0xc3,0xcb,0x85,0x0d,0xef,0xa6,0xd5,0x33,0xb3,0x67,0x73,0x3f,0xc9,0x90,0x25,0x3e +.byte 0xe6,0x7c,0x41,0x59,0x83,0xf7,0x90,0x4a,0xbf,0x14,0x72,0x11,0xf2,0x3a,0x38,0x58,0x17,0xd8,0x3d,0x00,0xc6,0x42,0xf2,0xbc,0xfd,0x05,0x37,0x6d,0x11,0xb0,0xd7,0xb2,0xb7,0x73,0x69,0x80,0x47,0x30,0x64,0x13,0x8c,0x24,0xb2,0x42,0x12,0x8c,0xc0,0x8a,0x45,0x0b,0x71,0x23,0xeb,0xac,0x65,0xda,0x44,0x13,0x85,0x77,0xdf,0xb8,0x4b,0x69 +.byte 0xd4,0x8e,0x40,0x54,0x24,0xac,0xc8,0x62,0x36,0x51,0x20,0xaa,0xcd,0x5d,0xa5,0x73,0x2c,0x81,0x92,0x99,0x44,0x6b,0x04,0xac,0x8e,0xee,0x96,0x29,0xca,0xdc,0x2f,0xd1,0x13,0x5c,0x9e,0xc2,0x67,0x6a,0xaf,0xf6,0x3e,0xe2,0xa1,0x6d,0xda,0xbe,0x8a,0x55,0x50,0x27,0xee,0x6d,0xb8,0x35,0x5f,0xb4,0xa8,0x76,0xa1,0xe2,0x52,0x87,0xf6,0xfb +.byte 0xe2,0x16,0x1c,0x90,0x78,0xe4,0x17,0xb0,0xd9,0x56,0xf5,0xd3,0xa4,0xb0,0x3f,0xe9,0x01,0xf9,0xd0,0x67,0x2b,0xeb,0x1d,0x73,0x24,0x90,0x36,0x36,0x0d,0xcf,0xfb,0x3f,0xa1,0xa0,0x25,0x3b,0xf1,0x7f,0x9e,0x90,0xcf,0xb6,0xd0,0x83,0x90,0xcd,0x3f,0xff,0x5f,0xa3,0x33,0x95,0xd7,0xbe,0x78,0xfe,0xcc,0x9a,0xb9,0x64,0x88,0xb7,0xd9,0x5e +.byte 0x46,0x2d,0xf0,0xb1,0xa1,0x81,0x2b,0xab,0x80,0xf5,0x4d,0x3b,0xd8,0x53,0x64,0x8f,0xac,0x7a,0x03,0xb3,0x39,0x7a,0x85,0xef,0x61,0xb5,0x2c,0x8e,0xf4,0x27,0x07,0x9b,0x7b,0xc9,0x8b,0x1a,0xe4,0x4f,0xce,0x8b,0x35,0x32,0xac,0xcf,0x47,0xb8,0x2f,0x9e,0xe5,0x11,0x48,0xc1,0x07,0xea,0x0c,0xee,0x06,0xc6,0xa3,0x48,0xb6,0x1a,0xd8,0xb4 +.byte 0xa7,0xae,0x59,0x7d,0x9e,0x4e,0x66,0x7f,0xe9,0x02,0x40,0xdc,0x21,0x5e,0x74,0x2c,0x1d,0x29,0x22,0xca,0x97,0x4f,0xc8,0xc7,0xea,0x69,0x02,0x89,0xd1,0x43,0xff,0x83,0x89,0x58,0x66,0x92,0xbc,0x11,0xf6,0x02,0x8b,0xa8,0x34,0x8d,0xbe,0x3a,0x70,0xc3,0x10,0xe7,0xb5,0xc4,0xda,0xdb,0xc6,0x87,0xee,0xee,0xe0,0x48,0x62,0x80,0x8d,0xfc +.byte 0xaa,0xc7,0xce,0x1a,0xea,0xb9,0x1b,0x30,0x4a,0x48,0x9b,0xf4,0x58,0xff,0x5d,0x15,0xc8,0xf2,0x84,0x44,0xae,0x63,0xe8,0xb1,0xe0,0x2e,0x38,0x8e,0x47,0xf9,0x09,0xec,0xb9,0x94,0x18,0x37,0x68,0xef,0xbd,0xd5,0x67,0x72,0x01,0x9a,0x15,0xb9,0x7c,0x36,0xc0,0x22,0x80,0x12,0xb1,0x4e,0xab,0x3c,0xea,0x81,0xcf,0x70,0xf3,0xde,0x1f,0xd4 +.byte 0x67,0x94,0xfa,0xe1,0xf0,0xb6,0xd6,0x6b,0xc3,0xa2,0xbb,0x59,0x6b,0x9f,0x58,0x26,0x99,0x0c,0xdc,0xcd,0xb8,0xae,0x49,0xf0,0x8f,0xd3,0x0d,0xb7,0x4c,0x22,0xcf,0xb6,0x6c,0xa3,0x19,0x09,0x42,0x59,0x25,0xf8,0xdc,0xf3,0xc2,0x00,0xc3,0xc3,0xd3,0x9e,0x98,0xd3,0xa3,0xd0,0x96,0xfd,0x4f,0x15,0x57,0x5b,0xa7,0x08,0x3a,0x0e,0x3d,0xd2 +.byte 0x7d,0xa1,0xa0,0x94,0xc0,0x76,0x83,0xf6,0xc1,0xe8,0x7e,0xd3,0x97,0xc1,0xbf,0x38,0x74,0x9b,0xfb,0x35,0xeb,0xf7,0x34,0x20,0xea,0xda,0xd3,0xb1,0x2e,0x10,0x16,0x9c,0x09,0x1c,0x67,0x46,0xa2,0x05,0xf9,0x47,0xde,0x35,0x53,0x18,0x58,0xb0,0xbb,0x7a,0x88,0x58,0xc5,0x3e,0x98,0x29,0x43,0x98,0x07,0x76,0xa3,0xe1,0x95,0x92,0x21,0xe9 +.byte 0x06,0x17,0x15,0xe0,0x6b,0xd5,0x5a,0x6d,0x10,0xa6,0x08,0x92,0xa9,0xf5,0xcf,0x57,0x1a,0x28,0x5d,0x14,0x33,0x99,0xf9,0xa0,0xb3,0xeb,0xee,0xd4,0x6e,0x0b,0x5e,0xf7,0xe9,0xe3,0xc6,0x71,0x34,0x55,0xf3,0xde,0xd5,0xc2,0x52,0xc3,0x7b,0x06,0x87,0xef,0x26,0x81,0xc9,0xbd,0xaf,0x12,0x61,0x95,0x2b,0xa4,0x8e,0xe8,0x08,0x9a,0x13,0x48 +.byte 0x2e,0x84,0x98,0xf6,0x95,0x21,0x22,0xe5,0xcf,0x30,0x8d,0xaf,0x70,0x16,0x27,0x0c,0xcd,0x26,0x7f,0xe8,0xa0,0x35,0x0c,0x01,0x0e,0xdd,0x9d,0x2c,0x89,0x41,0x34,0xc4,0xa2,0xaa,0xf6,0x3f,0xca,0x3b,0x86,0xce,0xd7,0x4c,0xe3,0xb5,0x69,0xe9,0x41,0xbe,0x3c,0x9a,0x4c,0x1a,0xb3,0x88,0xea,0x78,0x12,0x4c,0x1b,0x79,0xc7,0xcd,0x32,0x72 +.byte 0xfa,0x3f,0x0b,0x73,0x1b,0xd9,0xec,0x85,0xd4,0x52,0x6c,0x91,0x2d,0xbe,0x76,0x8b,0xfd,0xb6,0x49,0xcf,0x67,0xd1,0x18,0x7b,0xae,0x86,0x47,0x47,0xfd,0xff,0x63,0xf2,0x88,0x1b,0x58,0xd5,0x30,0x69,0xf9,0x9a,0x03,0x52,0xae,0xe5,0xe2,0x55,0xbf,0x35,0x12,0xb0,0x84,0xa9,0xed,0xb6,0x8d,0x5f,0x6c,0xed,0x1a,0x00,0x7a,0xdc,0xf2,0x03 +.byte 0x9e,0xef,0x59,0x27,0x4c,0xf4,0x83,0xa2,0x36,0x3d,0x3d,0x8c,0x75,0x8c,0x37,0x68,0x93,0x0b,0x30,0x48,0xea,0x91,0x14,0x37,0x88,0x87,0x7f,0xe6,0xd8,0xbd,0x04,0x34,0x1e,0xe8,0x2a,0x41,0x48,0x5c,0x66,0xf9,0xc2,0xd1,0x56,0x25,0x29,0x45,0xfa,0x71,0xe1,0x59,0xa8,0x52,0x99,0x0b,0x92,0xe0,0x33,0x52,0x91,0xd6,0x5f,0x0a,0x70,0x83 +.byte 0x4f,0xa3,0x47,0x6e,0xfa,0x85,0x5e,0xb1,0x0a,0x1d,0xe7,0x35,0xc9,0x88,0x27,0xc9,0x8c,0x3e,0x7f,0x6d,0x34,0x1e,0x11,0x7b,0xcd,0xe7,0x09,0x82,0x3a,0xa1,0x46,0xc6,0x15,0xde,0x0b,0xde,0x35,0x71,0x92,0x5c,0x72,0x50,0x08,0x6b,0x62,0xa7,0xec,0xa2,0xca,0x53,0x6e,0x47,0x7d,0x50,0x32,0xa7,0x32,0x7b,0x49,0x0c,0x97,0xcc,0x98,0x8d +.byte 0xc3,0x29,0x72,0x1e,0x85,0x47,0x1b,0xa7,0x89,0x19,0x85,0xaa,0x3f,0x11,0x6a,0xea,0x61,0x84,0x07,0x9a,0xc8,0xb3,0x25,0xfe,0x72,0xca,0x83,0xa9,0xf0,0x9e,0x01,0xe4,0x9a,0xd6,0x1b,0x87,0xfc,0xd4,0x3a,0x04,0x34,0x8c,0x0b,0x46,0xbc,0xe9,0x3c,0x3f,0xd9,0x93,0xf1,0xca,0x41,0x0b,0xdb,0x28,0xe8,0x28,0x1b,0x84,0x36,0x16,0x84,0x22 +.byte 0x1e,0x1e,0x2b,0xb0,0xfb,0xa6,0xcc,0x95,0x31,0x46,0xd7,0xca,0xc2,0x8b,0xa3,0x3a,0xa5,0xb0,0xaf,0x52,0x66,0x53,0x39,0x5f,0x58,0xb5,0xdf,0x01,0x52,0x07,0xb4,0x82,0xdc,0xb7,0xf9,0x88,0xd8,0x77,0xf8,0x12,0x9d,0xe8,0x21,0xd7,0x0b,0x0f,0x57,0x90,0x40,0xb2,0x64,0x3f,0xce,0xa0,0xa3,0xfa,0x12,0x16,0xec,0x6d,0xcc,0xc7,0x2a,0x43 +.byte 0xc9,0xe7,0xb7,0x90,0x52,0x35,0x22,0x6d,0x46,0x99,0x1e,0x44,0x12,0xd6,0x0f,0xaf,0x5c,0x16,0xd3,0x7a,0xd6,0xb4,0xfe,0x20,0x26,0x11,0xe1,0xc6,0xa5,0x10,0xfd,0x9f,0x0c,0x47,0xae,0x32,0x08,0x15,0x8f,0xef,0xef,0x4c,0x83,0xbc,0xbf,0x6a,0xe5,0xf5,0x69,0x11,0x4d,0x7d,0x47,0x1f,0x10,0x58,0x61,0xb0,0x0d,0x98,0x67,0xc0,0x99,0x3a +.byte 0x2d,0x9a,0x5b,0xd5,0x37,0xe7,0xe5,0xd4,0x56,0x96,0x69,0xf8,0x53,0x7e,0x24,0x70,0x51,0x01,0x83,0x8d,0x49,0x01,0x32,0x7d,0x4f,0x41,0x92,0x54,0x9c,0x15,0xf1,0x3c,0x05,0x32,0x28,0x0d,0x0f,0x67,0xbe,0x65,0xfa,0x1b,0xa3,0xd0,0x28,0x18,0xb8,0x84,0xfe,0x6a,0x30,0xea,0xb9,0x00,0xb1,0x10,0x7c,0xa2,0x94,0x4f,0x86,0x18,0xdd,0xb4 +.byte 0x80,0x18,0x48,0x18,0xe1,0x56,0x70,0x7d,0x5c,0x3b,0xe5,0xd7,0x88,0x66,0x57,0xe3,0xe1,0x04,0x4c,0x68,0x5b,0x64,0x4d,0x0d,0x30,0x76,0x26,0xaa,0x84,0x0e,0xe0,0xed,0x53,0x62,0x20,0x33,0xaf,0x45,0x42,0x40,0x47,0x01,0x15,0xc9,0x0b,0x27,0x7c,0x68,0x4d,0x55,0xc4,0x6a,0x5f,0x96,0x9f,0x96,0x67,0xae,0x13,0x1c,0x84,0x52,0x33,0x41 +.byte 0x80,0xfc,0xae,0xb6,0xb1,0x8c,0xc3,0x19,0x80,0xa8,0x5f,0xe5,0x8c,0xd0,0xa8,0xb4,0x58,0xc9,0x48,0x29,0xab,0x11,0xd1,0x09,0xc6,0x20,0x98,0x4c,0xdb,0xa4,0x83,0x5c,0x26,0x51,0xce,0x80,0xe5,0xc4,0x9b,0xae,0xba,0x8e,0x99,0x4e,0xa4,0xff,0xdc,0x99,0x4c,0x02,0xa0,0x42,0x80,0xca,0xd7,0xea,0x6a,0x58,0x31,0xdb,0x16,0xd8,0x4d,0xab +.byte 0x03,0x2e,0x3a,0xdc,0xe9,0x07,0xfb,0xfb,0x5b,0x57,0x67,0x2a,0x7b,0xdc,0xc1,0x66,0xd1,0x31,0x3a,0x03,0x87,0xd8,0x66,0xda,0xa1,0x24,0x00,0x26,0xc0,0x26,0x78,0xf8,0x59,0x13,0x3f,0x34,0x08,0x35,0x45,0xbd,0x45,0x4f,0x89,0x65,0x97,0xdb,0xe6,0x1e,0x09,0x6e,0x23,0x2a,0xc4,0xf5,0x6a,0x74,0x28,0xb0,0xae,0x8c,0xfb,0x49,0x35,0x99 +.byte 0x06,0x30,0xc6,0xb2,0x8c,0xcd,0x8b,0x41,0xea,0xf2,0x04,0x18,0x29,0x25,0x1b,0x32,0x42,0x45,0xb5,0x92,0x42,0xb4,0x33,0xd2,0x90,0x31,0x08,0xcd,0x35,0x5d,0x50,0x64,0xa8,0x93,0xfd,0xa5,0xfd,0x32,0xbd,0xe8,0x13,0x1c,0x48,0x5c,0x14,0x70,0x03,0x92,0x0f,0x12,0x86,0xf6,0x6c,0xcd,0xc6,0xec,0xbf,0x8e,0x85,0x28,0x1d,0x1c,0x63,0x3f +.byte 0x81,0x93,0xd4,0x80,0x3c,0x29,0x0b,0x63,0xfe,0x87,0xa6,0x24,0xd6,0x3e,0x62,0xb6,0xd9,0xb0,0x58,0xf1,0x41,0x36,0xc7,0x47,0x8b,0xfd,0x4b,0x91,0x4e,0x5d,0x41,0x44,0xb0,0x65,0x3d,0x9e,0x3b,0x70,0x01,0xcc,0x7d,0x77,0xf0,0x23,0xd9,0xca,0x5f,0xda,0xa1,0x8c,0x71,0x11,0x91,0x7d,0x36,0xf5,0xc9,0xcd,0xf4,0x34,0x5f,0x69,0x57,0xd6 +.byte 0x33,0x4c,0xb2,0xe1,0x38,0x5f,0x86,0x3c,0x57,0x7b,0x2e,0x99,0x05,0x80,0x63,0xc4,0x77,0x69,0x06,0xc2,0x47,0x44,0xca,0x17,0x27,0x1d,0x55,0x34,0x02,0xd0,0x89,0x3a,0x3b,0x79,0xf0,0x86,0xd7,0x6b,0x01,0x9c,0xc7,0xa8,0xde,0xdb,0xdf,0x49,0xd1,0xb9,0x11,0xaf,0x7e,0x22,0x8b,0x5d,0xb5,0x0b,0xdc,0xd0,0x36,0xe6,0x9d,0x85,0x41,0x4a +.byte 0x35,0xf0,0xe1,0xcd,0xce,0x7b,0xd1,0xd6,0x00,0xdd,0xb6,0xe4,0x06,0x3e,0x66,0xe9,0x2b,0xa8,0x44,0x0d,0x18,0xd4,0xbc,0xfb,0x3c,0x58,0x6c,0x11,0xe9,0xdc,0x19,0x14,0x08,0x27,0x23,0x0c,0xd0,0xf9,0x97,0xaf,0x97,0x07,0x02,0x1a,0x5e,0xcd,0xae,0xd2,0x80,0x96,0x16,0x49,0xc3,0xfc,0xda,0x25,0x12,0x20,0xe1,0xc0,0x68,0x90,0x4b,0x30 +.byte 0x2d,0x06,0x53,0x2c,0x57,0x63,0x4a,0x7a,0xf6,0xc8,0x5a,0xb7,0x58,0x8c,0x13,0xfe,0x43,0xb3,0xf8,0x25,0x3e,0x7a,0x25,0x3e,0x1d,0x7f,0x8f,0x5e,0xdb,0xad,0x99,0x83,0xfc,0xd9,0x0a,0xdf,0xb5,0x19,0x1c,0x2c,0xf6,0xe8,0x06,0xbe,0xc0,0x9f,0x7e,0x0f,0x95,0xaa,0xac,0x09,0xdc,0x8c,0x37,0xcf,0x35,0x35,0x95,0x62,0xf1,0xff,0x96,0x1c +.byte 0x77,0xe9,0x53,0x7e,0x12,0x56,0x2d,0x4e,0x3e,0x1f,0xdb,0x1d,0x71,0x0e,0xdc,0xf7,0x65,0xb1,0x78,0x7f,0xe4,0xba,0xbf,0x7f,0x6c,0xcb,0x73,0xd3,0xe8,0xd9,0xce,0xfb,0xdb,0x48,0x87,0xe0,0x10,0x00,0x74,0xcb,0xdf,0x32,0xa8,0xdd,0x83,0x24,0x49,0xda,0x86,0x38,0x1c,0x2c,0x93,0x09,0x8a,0x26,0xbb,0x34,0x21,0x1d,0xac,0xb5,0x16,0xae +.byte 0xd8,0xcb,0x94,0x04,0xd6,0xbc,0xde,0x9c,0x70,0x28,0xa5,0x1a,0x15,0x5e,0x35,0xe4,0xe6,0x53,0xea,0x9c,0x3b,0x0c,0x36,0x3b,0x80,0x13,0x28,0x1d,0xc7,0x1a,0xa8,0x8e,0x9e,0x09,0xce,0x5d,0x50,0xd3,0xc7,0x6f,0x3a,0x75,0xa5,0x84,0x1c,0x08,0x66,0xe6,0x05,0xda,0x8b,0xf1,0x4b,0x5c,0xe2,0xc7,0x0f,0xa1,0xf1,0x47,0x02,0xf4,0xa7,0x24 +.byte 0xf3,0x0e,0x2c,0xa9,0xae,0x67,0xdf,0xce,0x30,0x88,0x4a,0x9a,0x39,0x4a,0x97,0x64,0xa8,0x30,0x53,0xf9,0x47,0x66,0x5c,0x19,0x1c,0xfb,0x2f,0x05,0x89,0x4f,0xfe,0x25,0xe7,0xed,0xed,0x17,0x5a,0x86,0xeb,0x25,0xee,0xe4,0x09,0x88,0x05,0x49,0x20,0x54,0x4b,0x7f,0x3e,0xb5,0x23,0x85,0xa9,0x66,0x61,0x73,0xe0,0x61,0x94,0xc6,0xe5,0x29 +.byte 0xb4,0xe1,0x6f,0xa4,0x4d,0x50,0x56,0x2e,0x30,0x75,0x51,0x5d,0xdd,0xa2,0x68,0x56,0x67,0xd8,0xec,0x2d,0x2a,0xfd,0x49,0xc5,0xbc,0xae,0x2f,0x6b,0xc7,0x8d,0x2e,0xca,0x91,0x35,0xe8,0xea,0x65,0xe9,0x9c,0x65,0xaf,0x8e,0xd5,0x16,0xdf,0xac,0x44,0x1e,0xb6,0x16,0xf0,0xb6,0x33,0x6a,0xe6,0x96,0x0f,0x85,0x2e,0xa1,0xaa,0x6a,0xe0,0x12 +.byte 0x0c,0xaa,0x7d,0xae,0xf7,0xe3,0xb2,0x4c,0x3c,0x10,0xc6,0x87,0x8e,0x87,0xfb,0xac,0xf7,0xd7,0x7a,0x2e,0x9a,0x7a,0xa7,0x4f,0xf0,0x75,0xce,0xbd,0xc3,0xe6,0x79,0x1d,0x56,0xab,0xff,0x56,0xfe,0x69,0xbd,0xcf,0x15,0x27,0x64,0x3c,0x83,0x1c,0x08,0xb0,0x91,0x60,0x67,0xe7,0x27,0x44,0x49,0x22,0x78,0xd5,0x1a,0xc8,0x3b,0x35,0x9b,0xa5 +.byte 0x53,0xce,0xde,0x04,0xd2,0x3e,0x67,0x48,0xaf,0x54,0xdf,0x9c,0xf7,0xb9,0xd4,0xe3,0xb6,0x85,0x02,0x68,0x21,0x10,0xdb,0xb5,0xca,0x11,0xa2,0x7c,0xcf,0x13,0x41,0x7a,0xfd,0xe9,0x0a,0x3c,0x53,0xd6,0x07,0xf2,0xdd,0xe2,0x7c,0x16,0xf0,0x44,0x3f,0x5d,0x34,0x09,0x7c,0x7b,0x21,0x8c,0x8e,0xdb,0x0d,0xc5,0x73,0xce,0x61,0xce,0x17,0x46 +.byte 0x6c,0x14,0x07,0xb5,0x70,0x80,0xf0,0x29,0x7c,0x13,0x41,0x2d,0x8e,0xdc,0x53,0xc2,0xbf,0xf0,0xc2,0xfb,0x59,0xa0,0x66,0x5f,0x25,0xda,0x17,0x5f,0xac,0xab,0x75,0x1b,0xc7,0x61,0x87,0x53,0x80,0x2e,0x11,0x4e,0x04,0x48,0xf9,0xee,0x54,0xe6,0x69,0x69,0x57,0xc2,0x46,0xd8,0xb3,0x2e,0x7b,0xc8,0xa5,0xd0,0xb2,0x5e,0xd4,0x6b,0x9b,0x1a +.byte 0xd6,0x79,0x9d,0x99,0xa6,0xbb,0x4d,0xca,0x74,0x2c,0x3d,0xd4,0x86,0xd0,0x64,0xd4,0x81,0x49,0x76,0x42,0xb8,0xf9,0x2c,0x52,0xe7,0x77,0x37,0x31,0xbb,0x2e,0x5b,0x38,0x81,0x01,0x2c,0x27,0x28,0xcb,0x0c,0xba,0xfa,0x8a,0x9a,0x45,0x51,0xa2,0xde,0xf2,0x7b,0xe6,0x65,0xec,0x5b,0x2d,0xe8,0x55,0x8e,0xb4,0x7f,0xf8,0x1a,0x66,0x3a,0x5f +.byte 0x06,0x10,0x15,0xb2,0x3d,0xb2,0x36,0x6e,0x9f,0x8e,0xe2,0x4c,0x78,0xe5,0x3a,0xac,0x21,0x16,0x20,0x30,0x0f,0x51,0x56,0xcb,0x53,0xca,0x70,0x3c,0xa2,0x3f,0x37,0x06,0x6c,0x70,0xec,0xf4,0x3d,0x7c,0x77,0xa0,0x61,0xc7,0x0e,0x26,0x9f,0x25,0xc0,0xf2,0x28,0xdb,0x57,0xbe,0xe6,0x4e,0x9c,0x4d,0x2e,0x48,0x50,0xc2,0xd4,0xfd,0x5e,0x52 +.byte 0x3f,0xd0,0x82,0xd1,0xd4,0x53,0xad,0x42,0x38,0xb1,0x02,0xd6,0xa0,0x34,0x7a,0xb4,0xb3,0xdd,0x91,0x12,0xf4,0x91,0xc9,0xa2,0x35,0x2d,0xdc,0x97,0xa1,0xdb,0x82,0xe7,0x92,0x99,0x66,0x13,0x99,0x20,0x95,0x1f,0x47,0x64,0x80,0x5e,0x5f,0x74,0x6b,0xa6,0xca,0x47,0x0b,0x24,0x72,0xa6,0x27,0xe7,0x56,0x61,0xa7,0x8e,0x62,0xa4,0xff,0x8e +.byte 0x29,0xf8,0x09,0xa4,0xbb,0x70,0x97,0x8a,0x39,0xe8,0x65,0xc8,0x52,0x23,0x9d,0xbf,0x10,0xe8,0x7d,0xbc,0x3c,0xc4,0x8b,0x1e,0x5c,0x75,0x94,0x24,0x62,0x3f,0x5b,0x2b,0x9a,0x08,0x00,0x78,0xfd,0x28,0x44,0x12,0x62,0x2a,0x6f,0x47,0x9d,0x57,0xb0,0x4e,0x3b,0xcd,0x01,0x7d,0x6e,0x62,0xe3,0x99,0x9c,0xae,0x6e,0xe2,0x70,0x7a,0x32,0xb4 +.byte 0xc1,0x19,0xb1,0x03,0x6b,0x92,0x89,0x4f,0x37,0xaf,0x36,0xee,0x5e,0x03,0x31,0x8c,0x41,0x27,0x17,0x21,0xdf,0xe4,0x34,0x97,0x8d,0xe7,0x41,0x47,0xf2,0x80,0x51,0x41,0x01,0xe4,0x0c,0x1a,0x09,0xfc,0x07,0xc3,0x94,0x07,0x6f,0xa7,0x6c,0xff,0x32,0x21,0xa5,0x01,0x8c,0xa2,0x88,0x3c,0xc8,0x57,0xe8,0x68,0x19,0x4a,0x46,0x7a,0x36,0xd2 +.byte 0x75,0x8e,0xc5,0xa4,0x84,0x91,0x13,0x7f,0xdd,0x2b,0x3c,0x2e,0xc4,0x92,0x29,0xb3,0x60,0x74,0xc8,0x81,0x58,0x0e,0xad,0x6a,0x9d,0xaa,0x81,0x49,0x26,0x0f,0xd4,0x2a,0x39,0xdd,0x4d,0x2b,0x13,0xdb,0x2e,0x72,0xe6,0x45,0x99,0xeb,0xe6,0xe5,0xd5,0x76,0xd4,0x19,0xd8,0xd7,0xa9,0x1f,0xce,0x7f,0xc4,0x1c,0x9e,0x6f,0x68,0x32,0xb1,0x26 +.byte 0xc4,0xb6,0x4e,0x9f,0xbf,0xdc,0xe0,0xde,0x54,0x9b,0xe0,0x04,0x03,0xae,0xc9,0xce,0x3a,0xcb,0x93,0xad,0xcc,0x1f,0x46,0xf6,0xbb,0xff,0x40,0x52,0x9c,0x64,0x97,0x5a,0x6f,0x8d,0x28,0x45,0x1c,0xf6,0x8b,0xcb,0xb9,0x38,0xb8,0x00,0xee,0xec,0xac,0x68,0x3f,0x50,0xcb,0x36,0x6e,0x97,0xfd,0xa5,0x1d,0x29,0x6e,0xfa,0x9f,0x4b,0x83,0xcd +.byte 0x0d,0x34,0xf3,0x1e,0x3f,0x0f,0x2e,0x89,0xeb,0xf7,0x8e,0x5f,0xe0,0x3b,0x39,0xd2,0xe8,0x87,0xe3,0xe7,0xe9,0xd0,0x1b,0x32,0x03,0x6b,0x3c,0x75,0x7d,0xe2,0x5c,0x3c,0x42,0xb4,0x46,0x69,0x0b,0xaf,0x0a,0x5d,0x1a,0x83,0x0b,0x0e,0x3c,0x5a,0x36,0xbd,0x5d,0xb6,0xad,0x4c,0xdd,0xf1,0x8d,0xbf,0x2b,0x70,0x8e,0xbc,0x92,0x95,0x1b,0x0f +.byte 0xed,0x3f,0xae,0x9e,0xa2,0x5a,0x50,0xe4,0xda,0xde,0x04,0x51,0x31,0xac,0xa4,0x0b,0x94,0xcc,0x14,0x87,0x59,0xa8,0x30,0x09,0xe6,0x46,0xb9,0x07,0x3e,0x1a,0xbf,0x5a,0x23,0x32,0xfb,0x60,0x63,0x24,0x25,0x12,0xf6,0x3e,0x2d,0xd0,0x8b,0x88,0x9b,0xe9,0x2d,0xab,0xf5,0xaf,0xba,0xbc,0xfe,0xab,0xb2,0x61,0x7a,0x7c,0xbb,0x28,0x6b,0x86 +.byte 0xe5,0xa2,0x9c,0x2c,0x5a,0x23,0x12,0x11,0xe5,0x72,0xe8,0x7b,0x6b,0x40,0xf1,0x91,0x37,0x3b,0x47,0x75,0x65,0xac,0x4d,0x22,0x59,0x75,0x13,0xb0,0x73,0xff,0x59,0xd1,0x1b,0xcc,0x05,0x1f,0xf2,0xc8,0x50,0x83,0xf1,0x28,0x38,0x0b,0xc3,0xa0,0x3b,0xe3,0x86,0xbb,0x9c,0x7e,0xc1,0xe9,0xcc,0xd9,0xb8,0x2b,0x05,0xf3,0x6f,0xc7,0x9d,0xaf +.byte 0x7b,0xb7,0x38,0x41,0xa3,0x50,0x8f,0x92,0xe0,0x63,0x35,0xb3,0x95,0x9f,0x80,0xf8,0x75,0xbb,0xf3,0x2b,0x0e,0xaf,0x32,0x6e,0xff,0xeb,0x79,0xca,0xbf,0x1c,0x4f,0x6c,0x9c,0x06,0xb2,0xeb,0x99,0x57,0x1f,0xf6,0x64,0x0b,0x81,0x57,0xba,0xf4,0x32,0x1e,0x77,0x37,0x55,0xb7,0xbc,0xba,0x70,0x0b,0x0d,0xdd,0x95,0x41,0xb5,0x17,0x5b,0x14 +.byte 0x10,0x9d,0x14,0x52,0x83,0x65,0x0a,0xf4,0x55,0xca,0xf8,0xbe,0xa6,0x3a,0xa0,0x6e,0xcc,0x83,0x84,0x65,0xb4,0x1c,0x7e,0x40,0xdd,0x32,0x36,0x5a,0x23,0x17,0x7d,0xb5,0xb9,0x38,0x48,0x5c,0x6f,0x23,0x54,0x0e,0x93,0x74,0x27,0x0f,0xfd,0x58,0xc1,0x97,0x26,0x78,0x9a,0xd3,0x85,0xc5,0xb2,0xb3,0x44,0xb7,0x36,0x85,0x69,0xde,0x3b,0xa1 +.byte 0x2b,0x11,0xef,0x75,0xfc,0xaa,0x92,0xf1,0xf1,0x72,0xa0,0x5f,0x33,0xf6,0x0b,0x72,0xdb,0xce,0x6c,0x2a,0x15,0x76,0x40,0xd4,0x85,0xff,0x96,0xe1,0x48,0xe1,0x27,0x8f,0x74,0xf3,0xfa,0xa1,0xb7,0x2a,0xb6,0x41,0x90,0x92,0x7e,0xfa,0xfc,0xad,0xa3,0x94,0x91,0x77,0xf1,0x8f,0xee,0xa2,0x64,0x47,0x01,0xb3,0x01,0x99,0x05,0xe7,0x31,0x4a +.byte 0xe8,0xd2,0x65,0x40,0x21,0xc4,0x83,0x8e,0xc9,0x89,0xda,0x16,0x7b,0xe0,0xcb,0xc0,0xc0,0x3d,0x37,0x18,0x66,0xe9,0x70,0x86,0x0b,0x6c,0xe8,0x65,0x44,0xce,0x3a,0xcd,0x84,0x1e,0xce,0x0e,0xe3,0xf9,0x77,0x12,0xfb,0xe6,0x92,0x8b,0x0d,0x7e,0x15,0x7a,0x34,0x94,0x2a,0xa7,0xc5,0x35,0xa4,0xfc,0xbe,0xa3,0x13,0x70,0xe4,0x6b,0x2f,0x71 +.byte 0x31,0xef,0xdb,0x79,0x44,0xf2,0x77,0xc7,0xc9,0x0d,0x1a,0x7b,0xff,0x34,0xf8,0xc9,0xe8,0xc9,0xc2,0xe0,0x0c,0x9e,0xd6,0xb4,0x7a,0xdb,0x1f,0x65,0xb8,0xd4,0x92,0xbf,0x7f,0x06,0x44,0xe3,0xb4,0xd8,0x14,0xe3,0x9b,0x49,0x81,0x12,0xec,0x7d,0x01,0xe2,0x50,0x2c,0x0e,0xfd,0x4b,0x84,0x3b,0x4d,0x89,0x1d,0x2e,0x4b,0xe9,0xda,0xa5,0x3f +.byte 0x19,0xc2,0x53,0x36,0x5d,0xd8,0xdc,0x6e,0xc3,0x48,0x8f,0x09,0xd5,0x95,0x4b,0x0c,0x7c,0x00,0x15,0x33,0x8e,0x1d,0x0c,0xdf,0x32,0x3b,0x93,0x1f,0xf5,0x49,0x4f,0xfd,0x8b,0x64,0xe7,0x96,0xaf,0x2f,0xc8,0xea,0xab,0x91,0x53,0x29,0xe3,0x31,0x0a,0x1c,0x6e,0xe0,0xbb,0x81,0x11,0x83,0xe0,0x07,0xfb,0x29,0x11,0x0f,0x0d,0x85,0xd4,0x61 +.byte 0x3c,0x75,0xbb,0x8a,0x23,0xb6,0xa0,0x7f,0xa4,0xbb,0x11,0xd4,0x75,0xde,0x27,0xe5,0xeb,0x11,0x5d,0x02,0xfe,0x5c,0x62,0x60,0x0f,0x6f,0x45,0x9b,0xfb,0xb7,0x32,0xa8,0x1c,0xd6,0xff,0x43,0x7b,0x53,0xee,0xa4,0x1f,0xf2,0xba,0xb6,0xb7,0xb7,0x39,0x18,0x85,0x79,0x77,0x27,0x30,0x26,0xe4,0xef,0xd1,0x39,0xc9,0xa2,0x0d,0x50,0xd7,0xef +.byte 0x9e,0xd8,0x8e,0xd2,0x74,0x1a,0x3f,0x99,0x24,0xf4,0x8b,0x4d,0x02,0x63,0x18,0x3a,0xaf,0x26,0xef,0xfc,0x1d,0xfe,0x46,0xc1,0x55,0xd7,0x92,0x65,0x2f,0xe7,0x4f,0x47,0xa8,0x2f,0x5d,0x47,0x67,0xeb,0x62,0x1d,0x69,0xa6,0x0e,0x51,0x1d,0x2c,0xed,0x6e,0x94,0xe9,0x48,0x4c,0x22,0xc2,0x93,0x79,0x6f,0x1b,0xc2,0x93,0x61,0x3d,0x8b,0xba +.byte 0xcb,0xe9,0x4a,0x88,0x5e,0x19,0x50,0x14,0xfe,0xda,0x3f,0x4d,0x47,0x54,0xfc,0x1c,0x09,0x77,0x37,0x30,0xfe,0x75,0x9f,0xdd,0xa4,0x74,0x04,0x04,0x88,0xe0,0xac,0x93,0x64,0x6f,0xbf,0x50,0xd8,0xf0,0xf7,0xa0,0xfa,0x98,0x49,0xfa,0xf7,0x6e,0xcf,0xa2,0xbf,0xb6,0x07,0x15,0x0e,0x4e,0x21,0x74,0x0a,0xa6,0xa3,0x67,0xce,0xf9,0x3b,0xd6 +.byte 0x4c,0xc8,0x43,0xe3,0x3b,0x3b,0x6a,0x86,0x62,0x3f,0x5a,0xf3,0x3f,0xf9,0xeb,0xbf,0xa3,0x2a,0x83,0x8a,0x70,0x8f,0x01,0x65,0x17,0x9a,0xa6,0x26,0x3b,0x09,0x06,0x22,0x19,0xed,0xd7,0x25,0x4b,0xd2,0x9a,0x30,0xfe,0x1c,0x82,0x68,0x16,0x04,0x0e,0x04,0x8f,0xc6,0x92,0xbe,0xe4,0x43,0x98,0x1d,0x3b,0x10,0x15,0x5b,0xef,0x4e,0x60,0x5e +.byte 0x6b,0xc9,0xde,0xb8,0x47,0x02,0x86,0x45,0x39,0x7a,0x1a,0xef,0x67,0x28,0xc5,0x40,0x73,0x2a,0xa7,0x12,0x9d,0x58,0x3a,0x34,0xc2,0xda,0x34,0xb0,0x48,0xd9,0x34,0xcd,0x18,0xe9,0x76,0x41,0x78,0x8f,0xe5,0xe8,0x3d,0xb2,0x01,0x3b,0x84,0xd1,0xca,0x5e,0x26,0x1d,0x8c,0xea,0xe1,0x46,0xa3,0xf9,0x11,0xac,0x0d,0x98,0x9f,0xd3,0x46,0x79 +.byte 0xff,0xad,0x99,0x32,0x63,0x96,0xbc,0x57,0x39,0x16,0xce,0x06,0x7e,0x63,0x78,0x7b,0x86,0x92,0x1a,0xe1,0x45,0xc0,0x73,0xe1,0xec,0xfc,0x88,0x8f,0xf8,0x36,0x0f,0x54,0x76,0x02,0x98,0x49,0x40,0xb9,0xef,0xd8,0x13,0x68,0xf5,0x1d,0x0a,0x98,0x65,0x21,0xc5,0x1a,0x22,0x4e,0x8e,0xad,0xa9,0x52,0x57,0xc4,0xc6,0xa8,0x48,0x01,0x7a,0x78 +.byte 0xc9,0xfc,0xdd,0xf3,0xc3,0x83,0xc0,0x06,0xb5,0x56,0x84,0xe2,0x0c,0x6b,0x80,0xd9,0x59,0xa1,0x3d,0xe3,0x56,0xf0,0xe3,0x3f,0x93,0x61,0xf7,0x8c,0x6b,0x40,0x65,0x6e,0x01,0xc2,0xa1,0xc1,0xb8,0x9b,0x15,0x6c,0xa1,0x18,0x4a,0x6c,0x8b,0x18,0x2d,0x8e,0x71,0x7a,0xa1,0x26,0xc1,0x4b,0xac,0x0c,0xca,0x08,0x33,0xef,0x35,0x33,0x63,0xeb +.byte 0x57,0x6e,0x7e,0x36,0xe0,0x31,0xad,0x10,0x76,0xb7,0x45,0xd9,0x3a,0x92,0x66,0x69,0x13,0x61,0x59,0x87,0xfd,0x6b,0xf1,0x46,0x0a,0x7a,0x3f,0x29,0x88,0x5b,0x7d,0xef,0x07,0x02,0xa8,0xa1,0xdc,0xd4,0x0e,0x77,0x8f,0x68,0x32,0xbd,0x8e,0xd6,0x0b,0xe4,0xd1,0x75,0xc1,0xb0,0x74,0x6c,0x0e,0xc3,0x46,0x79,0x36,0x3b,0x5f,0x0e,0xa0,0xad +.byte 0x28,0x8c,0xcb,0x01,0x8e,0x58,0x14,0x09,0xf1,0xd4,0x3b,0x2e,0xdc,0xbf,0x37,0x95,0x26,0xda,0xb6,0xcf,0xc8,0xa1,0xd4,0xec,0x72,0xf3,0x44,0xf5,0x4e,0x27,0x9b,0x2e,0x7c,0xfa,0x37,0x16,0x1d,0x7f,0x90,0x86,0xae,0x96,0x3b,0xe1,0xda,0xf7,0xc4,0x54,0x0b,0x51,0x7e,0x83,0xbe,0xed,0xd6,0x5f,0xd2,0x6d,0xbb,0xd3,0xc6,0x53,0x95,0x65 +.byte 0x3d,0x19,0xc2,0xc5,0xdf,0x47,0x00,0x2c,0x4b,0x2d,0xec,0x32,0xd5,0x28,0xb5,0x30,0xe0,0x79,0x15,0x2e,0xab,0x97,0xa8,0xcf,0xc5,0x40,0x98,0x30,0x22,0x9f,0xbc,0xdb,0x65,0x06,0xfc,0x58,0xe5,0x55,0x5b,0xe2,0xf8,0x6e,0xc6,0xfc,0xec,0x6c,0x14,0xd2,0xe3,0x9a,0x71,0x8a,0x61,0xea,0x39,0xc6,0x77,0x94,0xdf,0x7b,0x99,0x71,0xdd,0x18 +.byte 0xc6,0x03,0x2d,0x49,0xf6,0xc3,0xe8,0x2b,0x7e,0x3f,0x28,0xfc,0xc8,0xa1,0xb0,0x15,0x31,0x7e,0x83,0xb8,0x14,0x34,0x0e,0x7f,0xde,0x74,0x7b,0xbf,0xb7,0x8e,0xd9,0x31,0x90,0x16,0xb6,0x57,0x14,0x4a,0xc6,0x67,0x3d,0xb9,0x46,0x92,0xf2,0xf9,0x94,0x36,0x2b,0xd6,0x1f,0x84,0xa5,0x8c,0x0f,0xd9,0x8c,0x5f,0x97,0x7a,0x7b,0xff,0xc9,0xf5 +.byte 0x5e,0x13,0x5f,0x19,0x58,0xba,0xa6,0xe8,0x29,0xf4,0xb8,0x7e,0x98,0xb7,0xef,0x1b,0x00,0xe8,0x90,0x8f,0x86,0x4c,0xe0,0x51,0x13,0x8b,0xa1,0x37,0x40,0x38,0x51,0x2f,0x5a,0x9b,0x63,0x8f,0xce,0x9a,0x97,0x07,0x0d,0x8e,0xce,0xb1,0x66,0x89,0x78,0xca,0xa6,0x0c,0x20,0xc4,0xf1,0xe3,0xab,0xe2,0x1c,0x83,0x2b,0x46,0x97,0xe8,0x8f,0x94 +.byte 0xb4,0x71,0x40,0xde,0xa1,0x05,0x4b,0xed,0xbf,0x0c,0x46,0xe1,0x25,0xf1,0xd0,0x5a,0xdb,0x9c,0x2a,0x09,0x03,0x80,0x24,0xc1,0x22,0x02,0xa5,0xde,0xf6,0x4c,0xbc,0x93,0x37,0xa9,0x28,0xb3,0x92,0x19,0xa8,0x3f,0x71,0x90,0x62,0x78,0xaa,0x9a,0x0c,0xab,0x50,0xaf,0x89,0x2b,0xf1,0xf4,0x12,0xbd,0xc9,0xd5,0xee,0x64,0x8b,0x48,0x21,0xd6 +.byte 0xa1,0xa1,0xf2,0x68,0x4a,0xf8,0x06,0x3e,0x20,0x31,0x66,0xb7,0x2f,0x64,0x01,0x5a,0x46,0x14,0x85,0xfb,0xde,0x04,0xc3,0xe4,0xd6,0x25,0x14,0xa0,0xbe,0x4d,0x39,0xd8,0xe0,0x9b,0xb7,0x6b,0x00,0xe6,0x46,0xfb,0xcc,0xa8,0xad,0x67,0x12,0x2c,0x53,0x2c,0xb6,0x9f,0x6e,0xfe,0xbc,0xcc,0x2c,0xa8,0x09,0x17,0x00,0x8e,0xf1,0xf4,0x3e,0xa9 +.byte 0x92,0x4d,0x83,0xe6,0x3c,0xf0,0xd3,0x1c,0xaf,0x84,0x2c,0x59,0x7e,0xda,0x1e,0xfd,0x7d,0xf3,0xef,0x93,0x05,0x03,0xb0,0x76,0x69,0xb5,0x51,0xa8,0x65,0x8f,0x8a,0xf8,0x55,0x92,0x08,0xfe,0xbf,0xc1,0x95,0x98,0x58,0xb1,0xd3,0xb6,0x78,0x4f,0x2f,0x25,0xcb,0x9d,0x32,0x4f,0xa6,0xcc,0xf8,0x36,0xff,0x72,0xb3,0x93,0x3d,0xd8,0x0b,0xe6 +.byte 0xc6,0xf6,0xed,0xcc,0x2a,0xa5,0x44,0x6e,0xe2,0x2d,0x6e,0x02,0xb4,0x7c,0x24,0x7f,0x57,0x02,0x84,0x61,0x8e,0xbd,0x32,0x4e,0x41,0x92,0x01,0x1b,0x8b,0x1d,0xd1,0x1e,0x31,0xc1,0x4c,0x5b,0x0c,0xa7,0x48,0x52,0x67,0xc2,0xd9,0xdc,0x86,0x9d,0xbd,0x6c,0x19,0x95,0x00,0xf0,0xd4,0x47,0xaf,0xfe,0x5d,0xa5,0x81,0xbd,0x1b,0x42,0x62,0xce +.byte 0x18,0x1b,0xa3,0x6f,0xf5,0x0b,0xb7,0x6a,0x3d,0xe3,0xcc,0x41,0x27,0xcd,0x49,0x4b,0xe5,0x2b,0xc4,0x28,0xfa,0xbe,0xd5,0x7e,0xb7,0xac,0xab,0x64,0x3b,0xe3,0x87,0xb1,0x33,0x8b,0xa8,0xe5,0x75,0xce,0x61,0x57,0x89,0xad,0x5f,0x61,0xdd,0x7c,0x06,0x2a,0x3f,0x50,0xb8,0x7e,0xd2,0xfb,0x32,0x83,0x07,0xd4,0xc5,0x3f,0xad,0x64,0x59,0x1f +.byte 0x21,0x59,0x6f,0x1b,0xd7,0x40,0x89,0x28,0x18,0xac,0xca,0xee,0x92,0x1c,0x0d,0x88,0x98,0x7a,0x75,0x68,0xe0,0xe2,0x96,0xda,0x88,0xb3,0xc6,0x21,0x02,0x34,0xfa,0xae,0x0b,0x38,0xcf,0x1c,0x6c,0x7a,0xc9,0xd9,0x5f,0xf0,0x4c,0x73,0xfd,0xe6,0x14,0xf3,0x39,0xed,0xbc,0x28,0x2f,0xf8,0x79,0x02,0x39,0x05,0xf3,0x6a,0x88,0xd9,0x03,0xe2 +.byte 0xb9,0x65,0x81,0x3a,0x34,0x80,0x3f,0x17,0x37,0x1e,0xe8,0x7d,0x41,0x49,0xfb,0x70,0x5d,0x58,0x3a,0x71,0x7b,0x3e,0xd3,0x83,0x0b,0x1b,0x11,0xfc,0x53,0xce,0xc6,0xc4,0x39,0x55,0xbe,0xbe,0x32,0xa5,0x88,0xab,0xcd,0x38,0x78,0x3e,0x52,0xaf,0x64,0x42,0x10,0xc3,0x70,0x81,0x76,0xe9,0x7d,0x8e,0x46,0x41,0xca,0x2c,0x0c,0x4c,0x30,0xd3 +.byte 0xca,0x38,0xa3,0x97,0x2e,0x0f,0xa5,0x18,0x3b,0xaa,0x0f,0x00,0x75,0x35,0x9c,0xcd,0x28,0x83,0xd4,0xa7,0x7c,0xb9,0xcd,0xb5,0x55,0x29,0x4c,0x14,0xcd,0xfc,0x8f,0xaf,0x7d,0x69,0x4f,0xf7,0x0f,0xed,0x7c,0xa5,0x79,0x9d,0x36,0xbb,0x72,0xbc,0xf2,0x14,0xfd,0xf0,0x04,0x2a,0x89,0x1e,0xf7,0x80,0x4c,0x5e,0xb8,0xc1,0xdb,0xfa,0x3c,0x27 +.byte 0xbb,0x30,0x08,0x2b,0xd2,0xf8,0xdb,0xe0,0x8c,0x00,0xe4,0xca,0xa9,0xde,0xb0,0x14,0x5b,0xec,0x6b,0xe6,0x5c,0x90,0x17,0x02,0x59,0x5f,0x5f,0x51,0xf8,0x30,0x10,0x11,0xc4,0xdf,0x37,0x30,0x32,0xb1,0x4d,0x49,0xfe,0x82,0x87,0xd2,0x42,0xf5,0x38,0x76,0xf9,0xa5,0x28,0xfc,0x14,0xb2,0xe0,0x72,0x82,0xde,0xc8,0x47,0x9e,0x8f,0x8a,0xb5 +.byte 0x85,0x44,0x42,0x12,0xc6,0xc0,0xa5,0x60,0x5a,0x27,0xd0,0x36,0x14,0x7b,0x2a,0x83,0x98,0x92,0x08,0xe9,0x03,0xc9,0xc3,0xd3,0x36,0x97,0xba,0x5e,0xd5,0x51,0xcc,0x44,0xeb,0x81,0x76,0xae,0x28,0x94,0x0b,0xf6,0xc7,0xeb,0xae,0x61,0x6f,0x7b,0x34,0xb5,0x8c,0x5f,0x31,0xb6,0x23,0xe3,0xe7,0x4b,0x60,0xe6,0xba,0x8d,0x0e,0xd1,0xb2,0x37 +.byte 0x72,0x3d,0xc1,0x75,0x9b,0x5e,0xcb,0x0f,0xf9,0xe4,0xdb,0x82,0x4c,0xc4,0x37,0xef,0x9d,0xde,0x16,0x85,0xe9,0xc2,0x03,0xd8,0x5b,0xa1,0xff,0xfa,0xd4,0xd7,0x5c,0x34,0xb6,0x1e,0x25,0x96,0xf5,0x8b,0xc3,0xee,0x16,0x1f,0xf8,0x55,0x4e,0x1c,0x83,0x80,0x77,0x1d,0x4f,0xb6,0x95,0x1c,0x91,0x7d,0x50,0x25,0xf4,0x2a,0x5d,0x2e,0xc7,0x8a +.byte 0x14,0xf8,0xb9,0xbc,0xab,0x5b,0xcd,0x47,0xb5,0xaf,0x85,0xc0,0x34,0x27,0x7d,0x6a,0x8c,0x84,0x8a,0xae,0x68,0x60,0x0e,0xa1,0x45,0xf7,0x83,0x66,0x91,0x69,0x30,0xed,0x26,0x5e,0xf5,0x48,0x6b,0x20,0xb3,0x11,0x50,0xf7,0x70,0x9d,0x10,0x50,0x44,0x87,0xfe,0x96,0x5c,0xc6,0xa4,0xa4,0xed,0x5e,0x7f,0x3d,0x90,0x19,0xbe,0x31,0xa3,0xdd +.byte 0x44,0xbb,0x9b,0x51,0x5a,0x06,0x1d,0x2e,0xd7,0xef,0xd1,0x81,0xb6,0xec,0xc6,0x89,0xfb,0x13,0xc5,0x21,0xef,0x9a,0x1a,0x48,0xf2,0xf8,0xb3,0xa3,0xec,0x7f,0x85,0xc1,0xc6,0x8c,0x5f,0xa9,0x30,0x38,0x25,0x1e,0x8d,0xcf,0x18,0x24,0xef,0x5a,0x9a,0x14,0x31,0xc0,0x2c,0x88,0xa5,0x3f,0x50,0x8b,0xb1,0xda,0x5d,0x26,0xd9,0xd3,0x81,0xb1 +.byte 0xec,0xf0,0x42,0x88,0xd0,0x81,0x51,0xf9,0x1b,0xbc,0x43,0xa4,0x37,0xf1,0xd7,0x90,0x21,0x7e,0xa0,0x3e,0x63,0xfb,0x21,0xfa,0x12,0xfb,0xde,0xc7,0xbf,0xb3,0x58,0xe7,0x76,0x42,0x20,0x01,0x3d,0x66,0x80,0xf1,0xb8,0xaf,0xfa,0x7d,0x96,0x89,0x36,0x48,0x95,0xd9,0x6e,0x6d,0xe6,0x4f,0xff,0x2a,0x47,0x61,0xf2,0x04,0xb7,0x83,0x14,0xce +.byte 0x0a,0x3c,0x73,0x17,0x50,0x88,0x03,0x25,0x4a,0xe3,0x13,0x55,0x8b,0x7e,0x50,0x38,0xfc,0x14,0x0b,0x04,0x8e,0xa8,0x5b,0xd6,0x72,0x20,0x60,0xe9,0xaa,0x22,0x82,0x11,0xc6,0xc4,0xd7,0xb9,0xc8,0x0c,0x7e,0x05,0xfb,0x90,0xe4,0x9c,0x28,0x89,0x29,0x99,0x63,0x4d,0xec,0x7b,0x50,0xbd,0xd8,0xa3,0x5b,0x50,0x77,0x19,0x81,0x92,0xce,0x82 +.size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed +.align 5 +.Lpoly: +.quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 +.LRR: // 2^512 mod P precomputed for NIST P256 polynomial +.quad 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd +.Lone_mont: +.quad 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe +.Lone: +.quad 1,0,0,0 +.Lord: +.quad 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000 +.LordK: +.quad 0xccd1c8aaee00bc4f +.byte 69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 + +// void ecp_nistz256_to_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_to_mont +.type ecp_nistz256_to_mont,%function +.align 6 +ecp_nistz256_to_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr x3,.LRR // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + adr x2,.LRR // &bp[0] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont + +// void ecp_nistz256_from_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_from_mont +.type ecp_nistz256_from_mont,%function +.align 4 +ecp_nistz256_from_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + mov x3,#1 // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + adr x2,.Lone // &bp[0] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_from_mont,.-ecp_nistz256_from_mont + +// void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_mul_mont +.type ecp_nistz256_mul_mont,%function +.align 4 +ecp_nistz256_mul_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont + +// void ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_sqr_mont +.type ecp_nistz256_sqr_mont,%function +.align 4 +ecp_nistz256_sqr_mont: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_sqr_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont + +// void ecp_nistz256_add(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_add +.type ecp_nistz256_add,%function +.align 4 +ecp_nistz256_add: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x8,x9,[x2] + ldp x16,x17,[x1,#16] + ldp x10,x11,[x2,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_add + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_add,.-ecp_nistz256_add + +// void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_div_by_2 +.type ecp_nistz256_div_by_2,%function +.align 4 +ecp_nistz256_div_by_2: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_div_by_2 + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 + +// void ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_2 +.type ecp_nistz256_mul_by_2,%function +.align 4 +ecp_nistz256_mul_by_2: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + + bl __ecp_nistz256_add // ret = a+a // 2*a + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2 + +// void ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_3 +.type ecp_nistz256_mul_by_3,%function +.align 4 +ecp_nistz256_mul_by_3: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + + bl __ecp_nistz256_add // ret = a+a // 2*a + + mov x8,x4 + mov x9,x5 + mov x10,x6 + mov x11,x7 + + bl __ecp_nistz256_add // ret += a // 2*a+a=3*a + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 + +// void ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_sub +.type ecp_nistz256_sub,%function +.align 4 +ecp_nistz256_sub: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_sub,.-ecp_nistz256_sub + +// void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_neg +.type ecp_nistz256_neg,%function +.align 4 +ecp_nistz256_neg: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov x2,x1 + mov x14,xzr // a = 0 + mov x15,xzr + mov x16,xzr + mov x17,xzr + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_neg,.-ecp_nistz256_neg + +// note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded +// to x4-x7 and b[0] - to x3 +.type __ecp_nistz256_mul_mont,%function +.align 4 +__ecp_nistz256_mul_mont: + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x11,x7,x3 + ldr x3,[x2,#8] // b[1] + + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adc x19,xzr,x11 + mov x20,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(1+1)] // b[1+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(2+1)] // b[2+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + // last reduction + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adcs x17,x19,x11 + adc x19,x20,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont + +// note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded +// to x4-x7 +.type __ecp_nistz256_sqr_mont,%function +.align 4 +__ecp_nistz256_sqr_mont: + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x2,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + lsl x8,x14,#32 + adcs x1,x1,x11 + lsr x9,x14,#32 + adc x2,x2,x7 + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adc x17,x11,xzr // can't overflow + + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x2 + adc x19,xzr,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sqr_mont,.-__ecp_nistz256_sqr_mont + +// Note that __ecp_nistz256_add expects both input vectors pre-loaded to +// x4-x7 and x8-x11. This is done because it's used in multiple +// contexts, e.g. in multiplication by 2 and 3... +.type __ecp_nistz256_add,%function +.align 4 +__ecp_nistz256_add: + adds x14,x14,x8 // ret = a+b + adcs x15,x15,x9 + adcs x16,x16,x10 + adcs x17,x17,x11 + adc x1,xzr,xzr // zap x1 + + adds x8,x14,#1 // subs x8,x4,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x1,xzr // did subtraction borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_add,.-__ecp_nistz256_add + +.type __ecp_nistz256_sub_from,%function +.align 4 +__ecp_nistz256_sub_from: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x14,x8 // ret = a-b + sbcs x15,x15,x9 + sbcs x16,x16,x10 + sbcs x17,x17,x11 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from + +.type __ecp_nistz256_sub_morf,%function +.align 4 +__ecp_nistz256_sub_morf: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x8,x14 // ret = b-a + sbcs x15,x9,x15 + sbcs x16,x10,x16 + sbcs x17,x11,x17 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf + +.type __ecp_nistz256_div_by_2,%function +.align 4 +__ecp_nistz256_div_by_2: + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = a+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adcs x11,x17,x13 + adc x1,xzr,xzr // zap x1 + tst x14,#1 // is a even? + + csel x14,x14,x8,eq // ret = even ? a : a+modulus + csel x15,x15,x9,eq + csel x16,x16,x10,eq + csel x17,x17,x11,eq + csel x1,xzr,x1,eq + + lsr x14,x14,#1 // ret >>= 1 + orr x14,x14,x15,lsl#63 + lsr x15,x15,#1 + orr x15,x15,x16,lsl#63 + lsr x16,x16,#1 + orr x16,x16,x17,lsl#63 + lsr x17,x17,#1 + stp x14,x15,[x0] + orr x17,x17,x1,lsl#63 + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2 +.globl ecp_nistz256_point_double +.type ecp_nistz256_point_double,%function +.align 5 +ecp_nistz256_point_double: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + sub sp,sp,#32*4 + +.Ldouble_shortcut: + ldp x14,x15,[x1,#32] + mov x21,x0 + ldp x16,x17,[x1,#48] + mov x22,x1 + ldr x12,.Lpoly+8 + mov x8,x14 + ldr x13,.Lpoly+24 + mov x9,x15 + ldp x4,x5,[x22,#64] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[x22,#64+16] + add x0,sp,#0 + bl __ecp_nistz256_add // p256_mul_by_2(S, in_y); + + add x0,sp,#64 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Zsqr, in_z); + + ldp x8,x9,[x22] + ldp x10,x11,[x22,#16] + mov x4,x14 // put Zsqr aside for p256_sub + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add // p256_add(M, Zsqr, in_x); + + add x2,x22,#0 + mov x14,x4 // restore Zsqr + mov x15,x5 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x16,x6 + mov x17,x7 + ldp x6,x7,[sp,#0+16] + add x0,sp,#64 + bl __ecp_nistz256_sub_morf // p256_sub(Zsqr, in_x, Zsqr); + + add x0,sp,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(S, S); + + ldr x3,[x22,#32] + ldp x4,x5,[x22,#64] + ldp x6,x7,[x22,#64+16] + add x2,x22,#32 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(tmp0, in_z, in_y); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#0+16] + add x0,x21,#64 + bl __ecp_nistz256_add // p256_mul_by_2(res_z, tmp0); + + add x0,sp,#96 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(tmp0, S); + + ldr x3,[sp,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x0,x21,#32 + bl __ecp_nistz256_div_by_2 // p256_div_by_2(res_y, tmp0); + + add x2,sp,#64 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(M, M, Zsqr); + + mov x8,x14 // duplicate M + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 // put M aside + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add + mov x8,x4 // restore M + mov x9,x5 + ldr x3,[x22] // forward load for p256_mul_mont + mov x10,x6 + ldp x4,x5,[sp,#0] + mov x11,x7 + ldp x6,x7,[sp,#0+16] + bl __ecp_nistz256_add // p256_mul_by_3(M, M); + + add x2,x22,#0 + add x0,sp,#0 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, in_x); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#32] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#32+16] + add x0,sp,#96 + bl __ecp_nistz256_add // p256_mul_by_2(tmp0, S); + + add x0,x21,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(res_x, M); + + add x2,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, tmp0); + + add x2,sp,#0 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(S, S, res_x); + + ldr x3,[sp,#32] + mov x4,x14 // copy S + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x2,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, M); + + add x2,x21,#32 + add x0,x21,#32 + bl __ecp_nistz256_sub_from // p256_sub(res_y, S, res_y); + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x29,x30,[sp],#96 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_point_double,.-ecp_nistz256_point_double +.globl ecp_nistz256_point_add +.type ecp_nistz256_point_add,%function +.align 5 +ecp_nistz256_point_add: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#32*12 + + ldp x4,x5,[x2,#64] // in2_z + ldp x6,x7,[x2,#64+16] + mov x21,x0 + mov x22,x1 + mov x23,x2 + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + orr x8,x4,x5 + orr x10,x6,x7 + orr x25,x8,x10 + cmp x25,#0 + csetm x25,ne // ~in2infty + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z); + + ldp x4,x5,[x22,#64] // in1_z + ldp x6,x7,[x22,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x2,x23,#64 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, Z2sqr, in2_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x22,#64 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#32] + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x2,x22,#32 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, S1, in1_y); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#352] + ldp x6,x7,[sp,#352+16] + add x2,x23,#32 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,sp,#320 + ldr x3,[sp,#192] // forward load for p256_mul_mont + ldp x4,x5,[x22] + ldp x6,x7,[x22,#16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, S1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x26,x14,x16 // ~is_equal(S1,S2) + + add x2,sp,#192 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U1, in1_x, Z2sqr); + + ldr x3,[sp,#128] + ldp x4,x5,[x23] + ldp x6,x7,[x23,#16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in2_x, Z1sqr); + + add x2,sp,#256 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, U1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x14,x14,x16 // ~is_equal(U1,U2) + + mvn x27,x24 // -1/0 -> 0/-1 + mvn x28,x25 // -1/0 -> 0/-1 + orr x14,x14,x27 + orr x14,x14,x28 + orr x14,x14,x26 + cbnz x14,.Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) + +.Ladd_double: + mov x1,x22 + mov x0,x21 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + add sp,sp,#32*(12-4) // difference in stack frames + b .Ldouble_shortcut + +.align 4 +.Ladd_proceed: + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#64] + ldp x6,x7,[sp,#64+16] + add x2,x23,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, res_z, in2_z); + + ldr x3,[sp,#96] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,sp,#96 + add x0,sp,#224 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[sp,#128] + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, U1, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#128 + bl __ecp_nistz256_add // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#192 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#224 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#288 + ldr x3,[sp,#224] // forward load for p256_mul_mont + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,sp,#224 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S1, Hcub); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#160 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#352 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + +.Ladd_done: + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_point_add,.-ecp_nistz256_point_add +.globl ecp_nistz256_point_add_affine +.type ecp_nistz256_point_add_affine,%function +.align 5 +ecp_nistz256_point_add_affine: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + sub sp,sp,#32*10 + + mov x21,x0 + mov x22,x1 + mov x23,x2 + ldr x12,.Lpoly+8 + ldr x13,.Lpoly+24 + + ldp x4,x5,[x1,#64] // in1_z + ldp x6,x7,[x1,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + + ldp x14,x15,[x2] // in2_x + ldp x16,x17,[x2,#16] + ldp x8,x9,[x2,#32] // in2_y + ldp x10,x11,[x2,#48] + orr x14,x14,x15 + orr x16,x16,x17 + orr x8,x8,x9 + orr x10,x10,x11 + orr x14,x14,x16 + orr x8,x8,x10 + orr x25,x14,x8 + cmp x25,#0 + csetm x25,ne // ~in2infty + + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + ldr x3,[x23] + add x2,x23,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, Z1sqr, in2_x); + + add x2,x22,#0 + ldr x3,[x22,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, in1_x); + + add x2,x22,#64 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#160] + ldp x6,x7,[sp,#160+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x23,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,x22,#32 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#192 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, in1_y); + + add x0,sp,#224 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x0,sp,#288 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,sp,#160 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[x22] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,x22,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in1_x, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#224 + bl __ecp_nistz256_add // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#288 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#256 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#96 + ldr x3,[x22,#32] // forward load for p256_mul_mont + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,x22,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, in1_y, Hcub); + + ldr x3,[sp,#192] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#192 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#128 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + adr x23,.Lone_mont-64 + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x29,x30,[sp],#80 +.inst 0xd50323bf // autiasp + ret +.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4], +// uint64_t b[4]); +.globl ecp_nistz256_ord_mul_mont +.type ecp_nistz256_ord_mul_mont,%function +.align 4 +ecp_nistz256_ord_mul_mont: + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adr x23,.Lord + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x19,x7,x3 + + mul x24,x14,x23 + + adds x15,x15,x8 // accumulate high parts of multiplication + adcs x16,x16,x9 + adcs x17,x17,x10 + adc x19,x19,xzr + mov x20,xzr + ldr x3,[x2,#8*1] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*2] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*3] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + lsl x8,x24,#32 // last reduction + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret +.size ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], +// uint64_t rep); +.globl ecp_nistz256_ord_sqr_mont +.type ecp_nistz256_ord_sqr_mont,%function +.align 4 +ecp_nistz256_ord_sqr_mont: + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adr x23,.Lord + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + b .Loop_ord_sqr + +.align 4 +.Loop_ord_sqr: + sub x2,x2,#1 + //////////////////////////////////////////////////////////////// + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x3,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + mul x24,x14,x23 + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + adcs x1,x1,x11 + adc x3,x3,x7 + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + mul x24,x14,x23 + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x3 + adc x19,xzr,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x4,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x5,x15,x9,lo + csel x6,x16,x10,lo + csel x7,x17,x11,lo + + cbnz x2,.Loop_ord_sqr + + stp x4,x5,[x0] + stp x6,x7,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret +.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont +// void ecp_nistz256_scatter_w5(void *x0,const P256_POINT *x1, +// int x2); +.globl ecp_nistz256_scatter_w5 +.type ecp_nistz256_scatter_w5,%function +.align 4 +ecp_nistz256_scatter_w5: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + add x0,x0,x2,lsl#2 + + ldp x4,x5,[x1] // X + ldp x6,x7,[x1,#16] + stur w4,[x0,#64*0-4] + lsr x4,x4,#32 + str w5,[x0,#64*1-4] + lsr x5,x5,#32 + str w6,[x0,#64*2-4] + lsr x6,x6,#32 + str w7,[x0,#64*3-4] + lsr x7,x7,#32 + str w4,[x0,#64*4-4] + str w5,[x0,#64*5-4] + str w6,[x0,#64*6-4] + str w7,[x0,#64*7-4] + add x0,x0,#64*8 + + ldp x4,x5,[x1,#32] // Y + ldp x6,x7,[x1,#48] + stur w4,[x0,#64*0-4] + lsr x4,x4,#32 + str w5,[x0,#64*1-4] + lsr x5,x5,#32 + str w6,[x0,#64*2-4] + lsr x6,x6,#32 + str w7,[x0,#64*3-4] + lsr x7,x7,#32 + str w4,[x0,#64*4-4] + str w5,[x0,#64*5-4] + str w6,[x0,#64*6-4] + str w7,[x0,#64*7-4] + add x0,x0,#64*8 + + ldp x4,x5,[x1,#64] // Z + ldp x6,x7,[x1,#80] + stur w4,[x0,#64*0-4] + lsr x4,x4,#32 + str w5,[x0,#64*1-4] + lsr x5,x5,#32 + str w6,[x0,#64*2-4] + lsr x6,x6,#32 + str w7,[x0,#64*3-4] + lsr x7,x7,#32 + str w4,[x0,#64*4-4] + str w5,[x0,#64*5-4] + str w6,[x0,#64*6-4] + str w7,[x0,#64*7-4] + + ldr x29,[sp],#16 + ret +.size ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5 + +// void ecp_nistz256_gather_w5(P256_POINT *x0,const void *x1, +// int x2); +.globl ecp_nistz256_gather_w5 +.type ecp_nistz256_gather_w5,%function +.align 4 +ecp_nistz256_gather_w5: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + cmp x2,xzr + csetm x3,ne + add x2,x2,x3 + add x1,x1,x2,lsl#2 + + ldr w4,[x1,#64*0] + ldr w5,[x1,#64*1] + ldr w6,[x1,#64*2] + ldr w7,[x1,#64*3] + ldr w8,[x1,#64*4] + ldr w9,[x1,#64*5] + ldr w10,[x1,#64*6] + ldr w11,[x1,#64*7] + add x1,x1,#64*8 + orr x4,x4,x8,lsl#32 + orr x5,x5,x9,lsl#32 + orr x6,x6,x10,lsl#32 + orr x7,x7,x11,lsl#32 + csel x4,x4,xzr,ne + csel x5,x5,xzr,ne + csel x6,x6,xzr,ne + csel x7,x7,xzr,ne + stp x4,x5,[x0] // X + stp x6,x7,[x0,#16] + + ldr w4,[x1,#64*0] + ldr w5,[x1,#64*1] + ldr w6,[x1,#64*2] + ldr w7,[x1,#64*3] + ldr w8,[x1,#64*4] + ldr w9,[x1,#64*5] + ldr w10,[x1,#64*6] + ldr w11,[x1,#64*7] + add x1,x1,#64*8 + orr x4,x4,x8,lsl#32 + orr x5,x5,x9,lsl#32 + orr x6,x6,x10,lsl#32 + orr x7,x7,x11,lsl#32 + csel x4,x4,xzr,ne + csel x5,x5,xzr,ne + csel x6,x6,xzr,ne + csel x7,x7,xzr,ne + stp x4,x5,[x0,#32] // Y + stp x6,x7,[x0,#48] + + ldr w4,[x1,#64*0] + ldr w5,[x1,#64*1] + ldr w6,[x1,#64*2] + ldr w7,[x1,#64*3] + ldr w8,[x1,#64*4] + ldr w9,[x1,#64*5] + ldr w10,[x1,#64*6] + ldr w11,[x1,#64*7] + orr x4,x4,x8,lsl#32 + orr x5,x5,x9,lsl#32 + orr x6,x6,x10,lsl#32 + orr x7,x7,x11,lsl#32 + csel x4,x4,xzr,ne + csel x5,x5,xzr,ne + csel x6,x6,xzr,ne + csel x7,x7,xzr,ne + stp x4,x5,[x0,#64] // Z + stp x6,x7,[x0,#80] + + ldr x29,[sp],#16 + ret +.size ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5 + +// void ecp_nistz256_scatter_w7(void *x0,const P256_POINT_AFFINE *x1, +// int x2); +.globl ecp_nistz256_scatter_w7 +.type ecp_nistz256_scatter_w7,%function +.align 4 +ecp_nistz256_scatter_w7: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + add x0,x0,x2 + mov x2,#64/8 +.Loop_scatter_w7: + ldr x3,[x1],#8 + subs x2,x2,#1 + prfm pstl1strm,[x0,#4096+64*0] + prfm pstl1strm,[x0,#4096+64*1] + prfm pstl1strm,[x0,#4096+64*2] + prfm pstl1strm,[x0,#4096+64*3] + prfm pstl1strm,[x0,#4096+64*4] + prfm pstl1strm,[x0,#4096+64*5] + prfm pstl1strm,[x0,#4096+64*6] + prfm pstl1strm,[x0,#4096+64*7] + strb w3,[x0,#64*0] + lsr x3,x3,#8 + strb w3,[x0,#64*1] + lsr x3,x3,#8 + strb w3,[x0,#64*2] + lsr x3,x3,#8 + strb w3,[x0,#64*3] + lsr x3,x3,#8 + strb w3,[x0,#64*4] + lsr x3,x3,#8 + strb w3,[x0,#64*5] + lsr x3,x3,#8 + strb w3,[x0,#64*6] + lsr x3,x3,#8 + strb w3,[x0,#64*7] + add x0,x0,#64*8 + b.ne .Loop_scatter_w7 + + ldr x29,[sp],#16 + ret +.size ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7 + +// void ecp_nistz256_gather_w7(P256_POINT_AFFINE *x0,const void *x1, +// int x2); +.globl ecp_nistz256_gather_w7 +.type ecp_nistz256_gather_w7,%function +.align 4 +ecp_nistz256_gather_w7: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + cmp x2,xzr + csetm x3,ne + add x2,x2,x3 + add x1,x1,x2 + mov x2,#64/8 + nop +.Loop_gather_w7: + ldrb w4,[x1,#64*0] + prfm pldl1strm,[x1,#4096+64*0] + subs x2,x2,#1 + ldrb w5,[x1,#64*1] + prfm pldl1strm,[x1,#4096+64*1] + ldrb w6,[x1,#64*2] + prfm pldl1strm,[x1,#4096+64*2] + ldrb w7,[x1,#64*3] + prfm pldl1strm,[x1,#4096+64*3] + ldrb w8,[x1,#64*4] + prfm pldl1strm,[x1,#4096+64*4] + ldrb w9,[x1,#64*5] + prfm pldl1strm,[x1,#4096+64*5] + ldrb w10,[x1,#64*6] + prfm pldl1strm,[x1,#4096+64*6] + ldrb w11,[x1,#64*7] + prfm pldl1strm,[x1,#4096+64*7] + add x1,x1,#64*8 + orr x4,x4,x5,lsl#8 + orr x6,x6,x7,lsl#8 + orr x8,x8,x9,lsl#8 + orr x4,x4,x6,lsl#16 + orr x10,x10,x11,lsl#8 + orr x4,x4,x8,lsl#32 + orr x4,x4,x10,lsl#48 + and x4,x4,x3 + str x4,[x0],#8 + b.ne .Loop_gather_w7 + + ldr x29,[sp],#16 + ret +.size ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7 diff --git a/crypto/openssl/crypto/ec/ecp_nistz256-x86.S b/crypto/openssl/crypto/ec/ecp_nistz256-x86.S new file mode 100644 index 000000000000..f822079f8a9f --- /dev/null +++ b/crypto/openssl/crypto/ec/ecp_nistz256-x86.S @@ -0,0 +1,5290 @@ +.text +.globl ecp_nistz256_precomputed +.align 4096 +ecp_nistz256_precomputed: +.byte 0x3c,0x4d,0x27,0xcc,0xf5,0x4a,0x4f,0x8f,0xe8,0xc8,0x04,0x68,0x09,0x4a,0x5b,0x80,0x9d,0x7a,0xe8,0x31,0x08,0x76,0x68,0x19,0x9f,0x08,0xb4,0x1f,0x32,0x43,0x89,0xd8,0x34,0xd3,0xf5,0xb7,0xb5,0xee,0x42,0x3e,0x91,0x01,0x06,0x7c,0xbf,0xd9,0x97,0x12,0xd3,0x1a,0xc9,0x04,0x8d,0x53,0x83,0x14,0x28,0xf0,0x8e,0x19,0xcc,0x91,0xe5,0x80 +.byte 0x14,0xd6,0xc1,0x8d,0x61,0x66,0x3b,0xa7,0x20,0x1e,0xe4,0x77,0xd7,0x66,0x05,0xfb,0x5c,0xa9,0x9a,0x7a,0xb2,0x30,0x50,0x28,0x87,0x80,0xfe,0xcd,0xe1,0xb3,0xff,0xa3,0x45,0x3c,0x7e,0x9b,0x08,0xc0,0xc1,0x9f,0x2e,0xad,0x7d,0x89,0x79,0x90,0x60,0xc6,0xac,0x17,0x64,0x59,0x4d,0xcf,0x56,0x7a,0xca,0x82,0xaa,0x6e,0x04,0x2f,0x1f,0x8b +.byte 0xa9,0xdd,0xeb,0x91,0x5c,0x77,0x17,0x99,0x4e,0xc2,0x45,0x69,0x2e,0xcf,0x60,0xc6,0x3c,0xad,0x65,0x33,0x35,0x6f,0xe4,0xd0,0x37,0x1f,0xe2,0x2c,0x66,0x98,0x55,0xe3,0x66,0xa2,0xc6,0x21,0xce,0x63,0x59,0x2e,0xd2,0x2b,0x8a,0x5a,0xcd,0xee,0xa7,0xad,0xf6,0x8c,0x3f,0x44,0x6c,0x12,0x30,0x8d,0xca,0xea,0x46,0x8a,0x4c,0x96,0xf9,0x96 +.byte 0x18,0x10,0x4e,0x46,0xc4,0x3e,0xa0,0x94,0x26,0x9d,0x62,0xd2,0x4b,0xb0,0xbc,0x0b,0xd5,0x56,0xa5,0xd2,0xc1,0x2f,0x2d,0x15,0xd8,0xed,0x97,0x17,0xcb,0x32,0x67,0xc5,0x0f,0x7c,0xde,0xa8,0x8c,0x4d,0xa0,0xb8,0x2e,0xed,0x24,0xd5,0xd5,0x49,0xca,0x77,0x1f,0x48,0x3b,0x83,0x54,0xb2,0xe7,0x7e,0x7a,0xa7,0x5c,0xed,0x7f,0xa1,0x9f,0x05 +.byte 0xd4,0xd4,0x90,0x0d,0xae,0x37,0x4e,0xd1,0x8f,0xd1,0x0a,0xa7,0x63,0x5b,0xb7,0x65,0xcb,0xc8,0xba,0x29,0xec,0x35,0x53,0xb2,0xac,0x32,0xf4,0xb7,0x6a,0xb1,0x69,0xcf,0x56,0x14,0x7f,0xd6,0xc5,0xca,0x88,0x1d,0x49,0xcf,0xfd,0x1f,0xcc,0xb1,0x13,0x30,0x42,0xd0,0x1c,0x6e,0x38,0x8e,0xf9,0x40,0xe7,0xe8,0xd6,0x28,0x1a,0x75,0x31,0xf3 +.byte 0x30,0x46,0x3f,0xb5,0x8a,0x47,0x35,0x4c,0x6e,0xdb,0x26,0x1a,0x25,0xa3,0xd8,0x0b,0x1d,0x51,0x12,0x91,0x4c,0x11,0x76,0x83,0x19,0xad,0x2a,0x3e,0xb4,0x1c,0x3c,0xfc,0x14,0x20,0x84,0x58,0x7b,0xc3,0x94,0x68,0x60,0x5c,0x3f,0x7c,0x26,0xb5,0x75,0x41,0x0b,0xc2,0xec,0xf3,0x96,0x5b,0xbb,0x41,0x32,0x00,0x4e,0x68,0xeb,0xf1,0xd9,0x96 +.byte 0xe7,0x00,0xac,0xb0,0x1b,0x39,0x46,0xf1,0xc9,0x18,0x7d,0xb7,0xc4,0x42,0xbc,0x8b,0x09,0x3e,0xa9,0x97,0x2e,0xc6,0xf8,0x38,0xa3,0xe4,0x2c,0x52,0x5d,0x24,0xf7,0xc5,0x15,0xab,0x16,0x5e,0x46,0x2c,0xd8,0xd7,0x4d,0xb3,0xf2,0xfd,0xe4,0x75,0x3c,0x34,0x95,0xb9,0x8c,0x92,0x35,0x42,0x8b,0xc4,0xc8,0x6c,0xd4,0x1e,0x67,0x35,0xd3,0x6d +.byte 0x79,0x85,0xff,0x74,0xbe,0x40,0x07,0x27,0x75,0x2c,0xea,0x04,0xcc,0xa2,0x72,0x80,0x97,0x5f,0xfe,0x8a,0x56,0x0f,0xf4,0x6d,0xa4,0x61,0x04,0x4b,0x5e,0xb4,0xe2,0xd8,0x87,0xb6,0xfd,0x3d,0x00,0x8a,0xa9,0xe4,0x62,0x5f,0x4f,0xec,0x1e,0x40,0x28,0x6b,0x21,0x0f,0x50,0x26,0x97,0xa0,0x25,0x8f,0x3e,0xf2,0x69,0xdc,0x36,0xe5,0xb8,0xdb +.byte 0x01,0x7d,0xfb,0x73,0x7d,0x3e,0xf7,0x55,0x41,0x39,0xe0,0x33,0x0d,0xe3,0x4b,0x6b,0x7b,0x3e,0x6e,0xdc,0x7d,0x9a,0x6e,0x35,0xb0,0x38,0x13,0x92,0x80,0xa1,0xe6,0xbf,0x03,0x9d,0xb7,0x7f,0x55,0xce,0x46,0x3c,0x22,0xc7,0xfa,0xfb,0x18,0xba,0x06,0xa0,0x09,0x78,0x3f,0xc0,0x79,0x5f,0xe6,0x6a,0x29,0xaf,0xd1,0xc7,0x84,0xa7,0xed,0xb9 +.byte 0xb6,0x82,0x81,0xc1,0x53,0xee,0x00,0x34,0xa8,0x81,0xdf,0x5a,0xd3,0x07,0x7e,0x2e,0x17,0x40,0xa1,0x2b,0xf4,0x2a,0x1f,0x9a,0x67,0x75,0x73,0xa8,0x58,0x65,0x17,0xdf,0xf1,0x84,0x76,0xc5,0x8d,0x48,0x93,0xe1,0x28,0xa5,0x73,0x10,0x6e,0x9e,0x39,0x03,0x69,0x52,0xdf,0xf9,0x46,0x7c,0x5b,0xf3,0x5b,0x9a,0x63,0xd9,0x4f,0xf5,0x8e,0x73 +.byte 0xed,0x33,0x7d,0x23,0xb9,0x6c,0x3c,0x9b,0xa7,0xcf,0x7f,0x34,0x6f,0x97,0xe2,0xfe,0x0a,0x8b,0xe1,0x86,0x83,0x91,0x2e,0xdd,0x6b,0xb1,0xbf,0xa6,0x92,0x4f,0x30,0x79,0x68,0x91,0x3e,0x06,0x17,0xe9,0x0b,0x25,0x07,0xa6,0x88,0x91,0x6c,0x6e,0xc8,0xd8,0xdc,0x68,0x5e,0x45,0xf2,0x55,0xef,0x56,0x38,0x29,0xd0,0x89,0x40,0x58,0x51,0x9f +.byte 0x5f,0xa4,0x08,0xc6,0x94,0x34,0xd2,0x6f,0x59,0x0f,0x6e,0xca,0x85,0x7f,0x56,0x3f,0xac,0x8f,0x25,0x0f,0x47,0xe3,0x9e,0x40,0xed,0xd8,0xae,0x30,0x0d,0xb4,0x47,0x40,0x4b,0xa3,0x23,0x1b,0x7f,0x0f,0xff,0xdf,0x6f,0x1d,0x87,0xb2,0x94,0xa0,0x36,0xbb,0x53,0x13,0x1e,0xaf,0x92,0xf8,0x07,0x95,0xc7,0xe4,0xa8,0x41,0xa9,0xed,0xf0,0x08 +.byte 0xfc,0xc1,0x4a,0xed,0x9a,0x4f,0x13,0xc5,0xed,0x8a,0x95,0xf5,0x69,0xf7,0xee,0x75,0xb6,0x4d,0xba,0x8f,0x65,0x23,0xe8,0x50,0x9e,0x7a,0xd7,0x28,0x3a,0x49,0xe7,0x4c,0x7c,0xc6,0x64,0xbd,0x8c,0x17,0x14,0x0b,0xb5,0xe3,0xb4,0xab,0x0b,0x9a,0xa9,0x29,0x84,0xaa,0xba,0x69,0xc4,0x2e,0xbf,0xca,0x57,0x0d,0xd3,0x36,0x21,0x61,0x00,0x13 +.byte 0x95,0xe3,0xf8,0xa6,0x64,0x74,0x02,0xb5,0xbf,0x86,0x07,0xde,0x67,0x48,0x23,0xe0,0x24,0x96,0x3a,0x86,0xb2,0xfa,0xa7,0x75,0xb4,0x26,0x42,0xcb,0x96,0x4e,0xf7,0x90,0xae,0xa5,0xe4,0xd0,0x45,0x31,0xe7,0x0f,0xe0,0xcb,0xbf,0x94,0x94,0x33,0x4f,0x65,0x04,0xfb,0xc0,0xc4,0x3f,0x51,0xa5,0xf3,0xea,0xc8,0xd5,0x23,0x66,0xe0,0x48,0x09 +.byte 0xba,0x6a,0x27,0x50,0xec,0xae,0xd2,0x2a,0xe6,0xf9,0xe4,0xde,0x35,0x6e,0xcc,0x82,0x76,0xfc,0x36,0x16,0xe1,0x9f,0xc7,0x0d,0xc1,0xc9,0x6a,0x23,0xbe,0xa1,0x3c,0xfd,0xce,0xa7,0x2e,0x91,0x36,0x23,0x5a,0x20,0xdf,0x55,0xc5,0x91,0x32,0x5c,0x62,0x49,0xe7,0x8b,0x0b,0x0e,0x9c,0x2e,0xee,0x1f,0xfe,0xca,0x00,0xfc,0x55,0xd7,0x9c,0x0a +.byte 0x75,0xaa,0xb0,0x46,0x90,0x55,0x2b,0x46,0xab,0x98,0x9d,0xab,0x0e,0x12,0x03,0x58,0xf1,0x4a,0x68,0x59,0x74,0xc9,0x37,0x6d,0x6f,0xe6,0xd3,0x73,0xf1,0xa3,0xdd,0xbe,0x85,0xca,0x74,0xc6,0xb6,0x51,0x6f,0x83,0x6f,0xa1,0x80,0x00,0x00,0x78,0x0a,0xa7,0xff,0xa7,0xe2,0x2e,0x5f,0x4f,0x31,0xbb,0x1b,0x99,0x21,0x33,0x59,0x6e,0x03,0x38 +.byte 0x10,0xd9,0x98,0xf2,0x0c,0xad,0x08,0x6b,0x00,0x49,0xb5,0x5e,0x11,0x60,0x70,0x49,0xff,0x79,0xac,0xba,0x30,0x3d,0x69,0x9f,0xaf,0xfb,0xd7,0xeb,0xe2,0xcd,0x0d,0x97,0xb9,0x94,0xc8,0x6e,0x06,0x3b,0x64,0x80,0x71,0x8f,0x81,0xb0,0x58,0xe0,0xc7,0xbd,0x27,0x6a,0xd4,0xb7,0xd9,0x6c,0xc1,0x44,0x38,0xe1,0x36,0xbc,0x0a,0x33,0x26,0x01 +.byte 0x25,0x90,0xbc,0x0a,0xc2,0xa3,0xbb,0xfc,0xeb,0x0b,0x1a,0x38,0x98,0x26,0x93,0xf5,0x2d,0x29,0x41,0x83,0x3b,0xba,0x40,0x46,0xf3,0xf6,0xfd,0x53,0xb9,0x7a,0x60,0x01,0x8a,0x8d,0xb4,0x57,0xd8,0xf3,0x36,0x72,0x22,0x2f,0x59,0xd3,0x7f,0x25,0xf2,0x05,0x61,0xfa,0x18,0x28,0xac,0xd5,0x14,0x00,0xaf,0x8b,0x7c,0x39,0xb5,0xa2,0xcb,0x1e +.byte 0x62,0x14,0xcb,0x10,0x76,0x17,0x23,0x2c,0xc8,0x25,0xac,0x37,0x9e,0x83,0x81,0x83,0xfe,0x2e,0x2c,0xd2,0x3f,0xf8,0x58,0x2b,0xf1,0x7f,0x4f,0xe1,0x17,0xc7,0xf7,0xad,0x57,0x67,0xc2,0x57,0x77,0x2e,0xfb,0xf2,0xce,0xa9,0x74,0x81,0x47,0xf8,0x5a,0x88,0x76,0xb1,0x43,0x75,0xc8,0xc4,0xc8,0x60,0x1e,0xd7,0xd1,0x1c,0xce,0x89,0x82,0xc6 +.byte 0x77,0x8d,0x87,0xe8,0xd0,0x5b,0x0c,0xf0,0x44,0x48,0x8d,0xee,0x55,0xc6,0xe4,0x2c,0x2c,0x41,0x75,0x5d,0x5a,0xd2,0xa3,0x1d,0x32,0x85,0x08,0xcf,0x03,0x3a,0x3c,0xfe,0x65,0x75,0xef,0xd2,0xa6,0x22,0x16,0x66,0x39,0x30,0x05,0xe3,0x57,0xab,0x71,0x6d,0x28,0xd5,0x2f,0xc6,0xa8,0x25,0x46,0x14,0xfd,0x7e,0xa2,0x67,0x7e,0x20,0x91,0xc2 +.byte 0x2b,0x03,0xdd,0xac,0xaa,0x1a,0xb5,0x2a,0x04,0xd6,0x15,0x9d,0x3f,0x54,0x24,0x7c,0x75,0xab,0x77,0xd9,0x6c,0x85,0xa2,0xf9,0x33,0xeb,0xeb,0xc0,0x27,0xcd,0x9d,0x58,0xae,0xa3,0x34,0x10,0xae,0x85,0x7d,0x4c,0x15,0x4c,0x90,0x46,0xe0,0x5b,0xec,0xa7,0xb2,0x68,0x85,0x01,0xed,0xf9,0x4a,0x85,0xe3,0xb6,0xea,0xe2,0x53,0xc0,0x32,0x83 +.byte 0x73,0x05,0x77,0xac,0xb5,0x96,0xaa,0xf0,0x9c,0x2c,0xa4,0xd2,0xd4,0xbf,0x74,0x2f,0x39,0x47,0x22,0x99,0x50,0x06,0x5f,0xcb,0x99,0xc5,0xc9,0x2e,0x70,0xd6,0x68,0x6a,0xc4,0x73,0x41,0xcb,0x8b,0xfd,0x23,0x98,0x11,0x59,0xad,0x20,0x8a,0x0d,0xaf,0xaa,0xd0,0xe2,0xeb,0x32,0x8b,0x6f,0x0e,0x43,0x12,0xe3,0x27,0x8f,0xf6,0xa4,0x76,0x0b +.byte 0xfb,0x22,0xad,0xda,0x1c,0x0a,0x3e,0x90,0xc0,0x7d,0xf3,0x09,0xbc,0x17,0x33,0xef,0xf1,0xf2,0x84,0x80,0x2a,0x0b,0x82,0xd7,0x95,0xc7,0xd2,0x08,0x4a,0xf4,0xf5,0x6d,0x09,0x06,0x8e,0xe4,0x74,0x63,0x8f,0x09,0xca,0xe2,0xd9,0x0e,0x1e,0x03,0x20,0x1b,0x4c,0xfb,0x1d,0x5a,0x2e,0x28,0xeb,0x84,0x82,0x6f,0x97,0x6f,0xcd,0x7a,0xc3,0xa7 +.byte 0x79,0x73,0x66,0x0c,0x94,0xd5,0xf4,0x8f,0x2c,0x73,0x1f,0x24,0xbc,0x17,0xee,0xd5,0xb0,0xa6,0xb8,0x04,0x6d,0x6a,0xd0,0x61,0xe3,0x1a,0x49,0x97,0x94,0xc5,0x8e,0xbc,0xac,0x5b,0x0b,0x0a,0xc5,0x74,0x06,0x89,0xee,0xc2,0xb7,0x5f,0x1b,0xa1,0x6b,0x1a,0xff,0xed,0xda,0x90,0x91,0xc1,0x0d,0x6a,0x06,0xd6,0xcb,0x02,0x71,0x17,0x95,0x7d +.byte 0xc6,0x3b,0x7e,0x6b,0xc8,0x73,0x03,0x0d,0x6b,0x8f,0x73,0x56,0x59,0x2e,0x09,0x23,0x4e,0xda,0xfc,0x4e,0xfc,0xa4,0x42,0x15,0x2e,0x10,0x6a,0x97,0x48,0x3c,0xb4,0xa4,0x0c,0x64,0x21,0xc3,0xeb,0x6c,0xac,0x27,0x4f,0x43,0x94,0x91,0x78,0xdc,0xfd,0xad,0x2b,0xa7,0x43,0x42,0xb0,0x51,0xdd,0x63,0xcc,0xcd,0xb7,0x15,0xfa,0x13,0x8d,0xc7 +.byte 0x55,0x3a,0x74,0x17,0x23,0x36,0x3e,0x23,0xe1,0x42,0x90,0xe1,0xb7,0xc7,0xda,0xb7,0x57,0xeb,0xc3,0xfb,0x62,0x58,0xbf,0x31,0x2a,0xfb,0xc7,0xdb,0x3d,0xfc,0x87,0x32,0xb1,0x3e,0xe5,0x3d,0x94,0x3d,0x86,0x32,0x61,0xfe,0x19,0xd2,0x32,0x31,0x8b,0x43,0xdb,0xab,0xa4,0xe5,0x34,0xc8,0x30,0xae,0x8c,0x02,0x53,0x99,0x35,0xb4,0x56,0x38 +.byte 0x37,0xcf,0xff,0xb0,0x05,0x21,0x12,0x65,0xc4,0xb3,0x9c,0x83,0x95,0x12,0xd3,0x03,0x7a,0x80,0x97,0x5b,0x67,0x33,0x27,0xfc,0x43,0xf2,0xf7,0xaa,0x60,0xb6,0xfc,0x55,0x44,0x30,0xa3,0x4a,0xa3,0x60,0x31,0xf7,0x01,0xfa,0xb0,0x8d,0x82,0x29,0xa7,0x03,0xb7,0x7e,0x3f,0xe5,0x66,0x26,0xb7,0x51,0xcf,0x8d,0xdd,0x6f,0x83,0x39,0xfc,0x9b +.byte 0xa5,0x3d,0xb6,0x41,0x89,0x54,0xc3,0xb2,0xf0,0x24,0x64,0xcb,0x53,0xfd,0x0a,0x91,0x6c,0x6f,0x28,0xfe,0xc1,0xe9,0x17,0x2e,0x65,0x55,0x2e,0xf2,0x48,0x52,0xb1,0x69,0xf0,0xdd,0x42,0xd5,0xdf,0x7c,0x36,0x75,0xdb,0x5b,0x3d,0xa9,0x6d,0xa4,0xeb,0x47,0x4f,0x2b,0x5c,0xd0,0x30,0xee,0xa7,0x74,0x6a,0x64,0x8a,0xbc,0x9b,0xe5,0x82,0x56 +.byte 0x76,0xe4,0x3f,0xf5,0x05,0x59,0x19,0x1e,0x80,0x47,0xf1,0x77,0xac,0x32,0x43,0x80,0x0a,0x1b,0x28,0xb6,0xf4,0xe8,0x7c,0x2f,0xeb,0xa8,0x4b,0x6a,0x59,0xb5,0xf8,0x77,0x68,0xd4,0x86,0x6c,0x87,0xdc,0xc4,0x00,0x4f,0xce,0xdb,0xf6,0x34,0xc3,0x74,0x02,0x08,0xdb,0x0d,0x34,0x8d,0xea,0x49,0x4a,0x30,0x5f,0x1b,0xcd,0xa6,0x3a,0x34,0x94 +.byte 0x5f,0x32,0x6a,0x62,0x96,0x4b,0x51,0x89,0x30,0xc9,0x90,0xdf,0x77,0x73,0x0e,0x3c,0x5c,0xbd,0x5c,0xee,0xd9,0x77,0xea,0x23,0x42,0xaa,0xa5,0x6b,0xf9,0x8c,0xc4,0x70,0x68,0xdd,0x0b,0x65,0xa3,0xc7,0xe4,0x7b,0x0a,0x89,0x85,0x25,0x7d,0x84,0x99,0x39,0xe6,0xb8,0xbe,0x7f,0x31,0x0f,0x84,0x0c,0x98,0x72,0xab,0x4c,0x44,0xb0,0xa4,0x83 +.byte 0x90,0xbb,0x93,0x73,0x07,0x07,0xba,0x63,0x5b,0x61,0x70,0xe1,0x84,0xae,0xaa,0xd6,0xa3,0x5a,0x54,0xd1,0xea,0xc7,0x2c,0x7b,0x67,0x4b,0x8a,0x7f,0x66,0x28,0x8d,0x22,0xec,0x82,0x64,0x69,0x63,0xf0,0x53,0x2d,0x10,0x9c,0x9c,0x34,0x4f,0xc6,0x96,0x40,0xdb,0xce,0x0e,0xf7,0x3a,0x8a,0xee,0x3f,0x32,0x5f,0x2b,0x0c,0x4a,0xbc,0x63,0xfb +.byte 0x18,0xf6,0x26,0x57,0xc9,0x13,0x13,0xb7,0xe0,0xcc,0x3e,0x4e,0x73,0xfa,0xe2,0x54,0xc1,0x67,0xfe,0xe2,0xec,0xfd,0xaf,0xf9,0x96,0x99,0x9f,0xe9,0xe2,0xd0,0x94,0x39,0x33,0xc9,0xca,0x35,0x27,0xad,0x58,0x46,0x98,0x64,0x17,0x5f,0xe9,0xce,0x4b,0xc8,0xab,0x0d,0xd2,0x88,0xec,0xbb,0x5c,0xba,0xc1,0x30,0x4c,0xd4,0x99,0x0d,0x07,0x95 +.byte 0x0a,0xa5,0xeb,0xa6,0x10,0x4b,0x4d,0x77,0x14,0x76,0x88,0x43,0x7f,0x6b,0x5d,0x9b,0x87,0x1d,0x6b,0x5d,0xb9,0x04,0xa9,0xc7,0x28,0x18,0x70,0xa1,0x99,0xbc,0x99,0xf5,0xf1,0x71,0xa9,0x3a,0xb6,0xe5,0x98,0x98,0x8f,0x7a,0x6c,0xda,0x1a,0x63,0x0e,0xf1,0xe8,0x10,0xa3,0x7c,0x64,0x7e,0xde,0x2a,0x59,0x1b,0x04,0xca,0x69,0x8e,0xba,0x2f +.byte 0x56,0xe1,0xa7,0xab,0x4f,0xe4,0x9d,0x49,0x33,0x9e,0x4e,0x5b,0xe1,0x58,0xc4,0x3f,0x99,0x5a,0x69,0x00,0xe5,0x5f,0x85,0xcb,0x62,0x80,0x5e,0x3d,0x88,0x0a,0x32,0x42,0xc1,0xf9,0x6a,0xa0,0xeb,0x65,0x2f,0x17,0x62,0x25,0x96,0x50,0xa2,0x6e,0xd6,0xdf,0x09,0xb7,0x1e,0x68,0xb2,0x10,0x2b,0xf3,0x9e,0xb2,0x67,0x75,0x9b,0xe3,0x76,0xfe +.byte 0x95,0xbe,0x83,0xcb,0xba,0x77,0x5b,0x2d,0x5f,0xdd,0x94,0xbb,0x0e,0x5d,0x83,0xa2,0xe7,0x48,0x4c,0x84,0x86,0x41,0x47,0x4b,0x96,0x24,0x89,0xa8,0x20,0x04,0xa5,0xef,0x8e,0xb6,0xeb,0xcd,0x3c,0x77,0xc5,0x65,0x5c,0xff,0xa6,0x0d,0x2b,0x58,0x21,0x5a,0x11,0xe2,0x24,0x64,0x1c,0xd6,0x18,0x9a,0xac,0x3f,0x42,0x0e,0xeb,0x32,0x3e,0xed +.byte 0xce,0x61,0xc9,0xe4,0xe7,0xd3,0x3f,0x53,0xa4,0x80,0x2b,0x1c,0xc0,0x99,0x63,0x52,0x93,0x5e,0xdc,0x78,0xe2,0x35,0x9e,0xb2,0xb4,0x1d,0x09,0xd1,0x5c,0x1c,0x4e,0xdb,0x3a,0x5d,0x8c,0x94,0x7d,0xfe,0x63,0xf2,0xa3,0xe9,0x61,0x73,0x78,0xc1,0xd9,0x17,0x5e,0x9a,0x73,0x58,0xc3,0xe7,0xa0,0x1f,0x2a,0x62,0x15,0xf8,0xdb,0xbb,0x38,0x80 +.byte 0x57,0xd3,0x1f,0x4c,0x4a,0x20,0x30,0xa9,0x7a,0x78,0x61,0xd9,0x90,0xb7,0x4f,0xd6,0x46,0x72,0xe7,0x41,0xb2,0xbb,0xfb,0x50,0xfe,0xe1,0xba,0x3e,0x73,0x2f,0x81,0x6d,0x2b,0x0b,0x90,0xbd,0x8a,0x3b,0x23,0x88,0xa2,0x7d,0x62,0x87,0x96,0xc9,0xcc,0x66,0x28,0x89,0xa7,0x29,0x41,0xd2,0xc5,0x5b,0xdb,0xc4,0x0c,0xbb,0x19,0x4e,0xd5,0x12 +.byte 0x53,0x48,0x5c,0xf2,0x9b,0x62,0xd0,0xa3,0x77,0x40,0x85,0x12,0x2b,0x2d,0x52,0x1b,0x31,0xbd,0xe9,0x1c,0xd4,0x87,0xa4,0xd7,0xc9,0x14,0xb7,0x39,0x66,0x8c,0xfe,0x3e,0x83,0x00,0x01,0xae,0x44,0x2d,0x7d,0xa1,0xda,0x66,0xb0,0x66,0xcb,0x62,0x55,0x9f,0x92,0x80,0x4e,0x8d,0x7f,0x70,0x95,0xc2,0xf2,0x1b,0xe9,0x35,0xf8,0x42,0x04,0x65 +.byte 0xf2,0x36,0x4c,0x96,0x30,0xd3,0x47,0x9d,0xb7,0x2b,0x76,0xac,0x75,0xb5,0xb8,0xf1,0x7d,0xa2,0x36,0xef,0x9d,0xa7,0x60,0x51,0x8d,0xcf,0x00,0x3d,0xdb,0xcc,0xe9,0xe2,0xc4,0x7b,0x3a,0xeb,0x2b,0xc3,0xd8,0x0b,0xb0,0x58,0x41,0xa0,0x47,0xab,0x07,0xf5,0x7c,0x9e,0x0b,0x7a,0x16,0x8f,0xb4,0xca,0x09,0xed,0x84,0xa1,0xfa,0xdc,0x7c,0x3c +.byte 0xdd,0x2f,0xb0,0x2d,0xeb,0x93,0x28,0xf5,0x1e,0x0c,0x1a,0x0c,0x35,0x27,0x40,0xf2,0x22,0x66,0x2d,0x82,0xf2,0x94,0x03,0xa5,0x4b,0x84,0x92,0x1d,0x98,0xd5,0xd9,0x09,0x6a,0xfd,0x65,0xe5,0xa1,0x0e,0xe2,0xd9,0xb6,0xd1,0xba,0xbf,0xc7,0x42,0x22,0x39,0x83,0xbf,0x37,0xf6,0x80,0xc2,0xea,0xdf,0xb9,0x33,0xa0,0xaf,0xd7,0xe3,0x70,0x9a +.byte 0x5c,0xf8,0x1a,0x47,0x2b,0xb5,0xdd,0x15,0xe3,0x08,0xc8,0x37,0xe3,0xc2,0x25,0x87,0x0e,0x3c,0xc5,0xae,0x61,0xa4,0x4a,0x56,0x50,0x08,0x58,0x68,0xa3,0x4a,0x28,0x08,0xef,0x92,0xd5,0x13,0x50,0x09,0x76,0x34,0x47,0xae,0xa8,0x7f,0xa5,0x2b,0x13,0xb7,0x5a,0x96,0x65,0x62,0xf2,0xaa,0xb4,0x4b,0x2a,0xad,0xea,0x2c,0x0d,0x1e,0x97,0x82 +.byte 0xe4,0x6f,0xfe,0xf4,0x88,0x14,0x7b,0xba,0x45,0xbe,0x61,0x56,0xd2,0x37,0x1b,0x65,0xb8,0x0b,0x77,0xcb,0x3c,0xfe,0x9f,0xe3,0x39,0xc5,0xfb,0x2a,0x18,0x9b,0x60,0x99,0xd5,0x6f,0x52,0xfe,0xd8,0x04,0x88,0x1c,0x9a,0x50,0xe5,0x3b,0x33,0x3f,0xca,0xc5,0x5b,0x9c,0x5f,0x35,0x13,0x65,0xa6,0x21,0x78,0x19,0xeb,0xff,0x35,0x70,0x81,0xaf +.byte 0x19,0x23,0x61,0xd6,0xeb,0xff,0xa6,0x9e,0x5d,0x3f,0x7f,0x89,0x2e,0x22,0xa4,0x0b,0x9c,0x4f,0xa9,0xff,0xbb,0x23,0x29,0xa1,0xf4,0x8a,0xb7,0x4b,0xfb,0xbf,0xeb,0x0a,0x47,0x87,0x78,0x2b,0x20,0x38,0x82,0xab,0x7e,0x2c,0xdc,0x08,0x2b,0xb4,0xae,0xd8,0x64,0x44,0x1a,0xdf,0x21,0x62,0x27,0xf2,0x61,0x63,0x37,0xad,0xd4,0x06,0x4e,0xae +.byte 0xba,0xeb,0x08,0xfa,0xe5,0xad,0x5d,0xcf,0xce,0x38,0xe5,0xca,0x74,0x83,0x42,0x4b,0xe8,0x8f,0xfb,0xff,0x83,0x4d,0x27,0x88,0x43,0x62,0xdd,0x80,0xa2,0x06,0x98,0x48,0x58,0x6f,0x54,0x16,0x6f,0xbf,0x81,0x36,0xc8,0xf3,0xea,0x4b,0xf7,0x5a,0x7b,0xb7,0xf4,0xa4,0x5e,0x22,0x52,0xe7,0x9e,0xb1,0xb6,0x7a,0xa8,0x22,0xee,0x68,0x82,0x8f +.byte 0xe4,0xcb,0xad,0x71,0xef,0x53,0xf2,0x7d,0xed,0x91,0x9e,0xf6,0x90,0x9e,0x54,0x19,0x30,0xaf,0x4a,0x17,0xc0,0x6a,0x9c,0x49,0x12,0x8b,0x6f,0xc7,0x47,0x1e,0xa2,0x64,0x28,0x1f,0x0c,0xd3,0x3e,0x59,0x66,0x8c,0x2e,0x11,0x52,0x6c,0x69,0x66,0x10,0xfb,0x27,0xe6,0x1c,0xae,0x6f,0x44,0x87,0x86,0x0d,0x3e,0xd3,0xa0,0x80,0xef,0x30,0xb9 +.byte 0xb8,0xd7,0x47,0x84,0x68,0x2b,0xf2,0x32,0x7b,0x89,0x93,0xd2,0x83,0x56,0x35,0xc3,0xbf,0x5c,0x24,0xec,0xad,0x2d,0xa4,0x49,0x63,0x89,0xc6,0xf9,0x24,0x51,0x1c,0x9b,0xd1,0xcb,0x30,0x82,0xda,0xb3,0xa7,0xe1,0x4d,0x96,0xd0,0x44,0x44,0x1d,0x4e,0xd7,0x7d,0x7a,0x51,0x2e,0x2f,0xc4,0x9f,0xdb,0x06,0x53,0xfc,0x51,0x56,0xe5,0xb9,0x6b +.byte 0x4a,0x2c,0x3e,0x62,0xc5,0x9c,0x42,0xe3,0xaf,0x3a,0x0f,0x0e,0x74,0x29,0x66,0x70,0x75,0x2a,0x06,0xd4,0x0f,0x0c,0xfd,0xea,0xcc,0x39,0xd0,0xa7,0x47,0x75,0x92,0x44,0x09,0xa2,0x3c,0x4e,0xad,0xaa,0xc4,0xc6,0xf9,0x35,0x82,0x23,0x25,0x43,0x94,0x26,0x14,0xde,0xf1,0xb9,0xb8,0xe0,0x75,0xe0,0x48,0x70,0x8a,0xc6,0x3c,0x72,0x98,0x72 +.byte 0x8b,0x15,0x58,0x17,0x73,0x29,0x67,0x21,0x56,0xc4,0x25,0x17,0x68,0xbe,0xd7,0x36,0x05,0x4b,0x58,0xa2,0x1b,0x64,0xe5,0x11,0x96,0x5a,0x3b,0xa6,0x90,0xb6,0x2d,0x7e,0x55,0xbb,0x31,0x93,0xe7,0xcc,0x2e,0x74,0xb6,0x9b,0x4d,0x04,0xc5,0x45,0x9b,0x0b,0x26,0xef,0x61,0x23,0x3d,0x7e,0xee,0x01,0x57,0xfa,0x77,0x12,0x47,0x64,0xac,0x8f +.byte 0x25,0xbe,0x8e,0x2e,0x68,0x11,0x95,0xf0,0x1a,0xd2,0x3d,0x66,0xc1,0xdb,0x97,0x9e,0xbb,0xba,0xc1,0x66,0xa4,0xb5,0x71,0x01,0xee,0xf5,0xbb,0x1e,0x9f,0x41,0xfc,0x40,0x74,0x26,0xf7,0xc6,0x2c,0x9c,0x1c,0x59,0xce,0xcf,0x18,0x17,0x81,0x5d,0xd4,0xe3,0xd8,0x46,0x62,0x9e,0x97,0xb1,0xca,0xac,0x01,0x3e,0xf8,0x96,0xa2,0xee,0xe0,0xf8 +.byte 0xf3,0x2d,0xe9,0xd2,0x1f,0x9f,0x41,0xbb,0x2f,0xe5,0x64,0x6d,0x5b,0xe7,0x47,0x0e,0x83,0x7b,0x08,0x5e,0x29,0x35,0x2f,0x75,0x31,0x44,0x4c,0xb7,0x61,0xa4,0x03,0x2e,0x15,0x94,0x7a,0xa0,0x46,0x31,0x7b,0x43,0xd9,0x14,0xa3,0x34,0x0c,0x83,0x93,0x75,0x8e,0x3a,0x1c,0xc3,0xe1,0x36,0x18,0x96,0x7a,0xfb,0x77,0xad,0xbb,0xe9,0x0d,0x4b +.byte 0x21,0x04,0x2e,0xdd,0x7a,0x63,0xc9,0x60,0xb1,0x9b,0xad,0xde,0x1f,0x65,0x8a,0x58,0x18,0x84,0x95,0xa9,0xac,0x3a,0xac,0xcb,0xb7,0xa9,0xeb,0x0c,0x7c,0x3a,0x98,0x9a,0x3f,0x56,0x23,0x51,0x58,0x59,0x4e,0xf5,0x57,0x60,0xe6,0x9d,0xf8,0xf7,0xed,0x9d,0x81,0x14,0x68,0xbe,0xaf,0x19,0xe5,0xb5,0x9b,0x5f,0xe4,0x51,0x44,0x4b,0x23,0x42 +.byte 0xdd,0x92,0x1a,0xe5,0x7e,0xef,0x77,0xbe,0x88,0x77,0x1e,0x8a,0xbd,0x2a,0x77,0xb1,0x0d,0x1b,0xe3,0x8a,0x7f,0x15,0x71,0x93,0xc9,0x5f,0x78,0x2d,0x77,0x9b,0x0c,0xad,0x76,0x3c,0x6b,0xe2,0x15,0x8e,0xe1,0x5e,0x1d,0x90,0xa5,0xd6,0xc7,0x55,0x5d,0x52,0xf7,0xcc,0x82,0x9b,0xdc,0x1d,0x80,0xa4,0xc7,0xbe,0x7c,0x4f,0xda,0x81,0x91,0x78 +.byte 0x88,0x0e,0x31,0xde,0x87,0x4c,0xdc,0x84,0x9a,0x65,0x89,0xfa,0x22,0x3e,0xde,0x3b,0x7f,0x7f,0x9b,0x3f,0x3e,0xda,0x13,0x31,0x59,0x7b,0x08,0x48,0x39,0x37,0xfd,0x1a,0x4f,0xa3,0x12,0xba,0xe5,0xd6,0xfa,0xa3,0x59,0x0b,0x3b,0x7d,0xde,0xc0,0x51,0xce,0x92,0x6b,0x3d,0x4b,0xd2,0xa4,0x68,0xc2,0x32,0x2d,0x01,0xbd,0x66,0x98,0x8f,0xa0 +.byte 0x86,0xfb,0x08,0x36,0xa9,0xd4,0x3b,0x7b,0x01,0x2d,0xaa,0x8c,0x64,0x19,0xa6,0x62,0x24,0x92,0x5e,0xc5,0x02,0x17,0x8e,0xf0,0x88,0xe9,0xd1,0x8b,0x69,0xda,0xed,0x9c,0x60,0x32,0xab,0xc0,0xbc,0x84,0x64,0x6e,0x32,0xb2,0xcd,0x24,0xf6,0xb2,0x9d,0xf5,0xf5,0x71,0xe2,0x01,0xbc,0x77,0x6a,0x5b,0x26,0x56,0xf7,0x04,0x84,0xff,0x7c,0xa4 +.byte 0xe8,0xa8,0x82,0x6c,0x40,0x24,0x93,0x3c,0x6e,0x7d,0x0d,0x22,0xd0,0xe4,0xef,0xc4,0x4e,0x26,0x66,0x61,0x75,0xe9,0x06,0x69,0x06,0xfd,0x97,0x68,0x96,0x67,0xec,0x96,0x09,0x73,0xe4,0x0a,0x3e,0xaa,0xb8,0x25,0x77,0x00,0x91,0x7a,0x2e,0xc8,0x81,0x75,0x78,0xb7,0xa5,0x27,0x55,0xf2,0xcf,0x9a,0xab,0xab,0x51,0x0a,0x65,0x47,0xbf,0x10 +.byte 0xd2,0x19,0x78,0x6b,0x35,0xf4,0xef,0x12,0x2b,0x5f,0x0c,0x28,0x7c,0xe8,0x64,0x55,0x2f,0x26,0x85,0x91,0x7a,0x9d,0x48,0x76,0x12,0x14,0x2d,0x4a,0x8a,0xd6,0xfa,0x7b,0xf9,0xc7,0x24,0x45,0xf6,0xbd,0x47,0xab,0xc6,0x4b,0x9e,0x39,0x77,0x57,0x04,0xa8,0x4d,0x43,0x99,0x5c,0xb1,0x3d,0xc2,0x4e,0xc5,0x17,0x66,0xc4,0xb6,0xdd,0x92,0x80 +.byte 0x85,0x3b,0x07,0x63,0x16,0x5f,0x67,0x76,0x9b,0xb5,0x8e,0xca,0x97,0xbb,0xf4,0x20,0xd0,0x4d,0x7b,0xd0,0xa3,0x74,0x6f,0x8a,0x68,0xc7,0x31,0x78,0x1b,0x72,0x45,0xa4,0xc4,0xf8,0xf8,0x26,0xa8,0x4d,0x08,0x2f,0x7b,0x3d,0xa0,0x2a,0xb5,0x65,0x27,0xc2,0x36,0x13,0x2d,0x8d,0x83,0xeb,0xf4,0x08,0x26,0x41,0x8b,0x32,0xf3,0x09,0x70,0x70 +.byte 0x5d,0x8a,0xcc,0xb8,0xe9,0xf7,0x08,0xdf,0x5f,0x4a,0xb8,0x8a,0xb7,0x1b,0xad,0xe2,0xc3,0x39,0x59,0xe0,0x7f,0xd0,0x66,0x7b,0x99,0x5a,0xde,0x52,0xe2,0x1f,0x47,0xc2,0x63,0x74,0x7a,0xa5,0x88,0xc3,0x24,0x70,0x4a,0x7d,0xdd,0xa4,0xe6,0xf8,0xfd,0x5c,0xfa,0x8c,0x4c,0x0f,0x52,0x95,0xf3,0x2c,0x76,0x47,0x7a,0xe8,0xdb,0xe0,0x9b,0x49 +.byte 0x88,0x5b,0x87,0x5a,0xd1,0x07,0x24,0x06,0x83,0x3b,0x25,0x23,0xe7,0xaa,0x79,0xef,0x74,0x02,0x12,0xfe,0x47,0x5c,0x77,0x73,0xf7,0x2e,0x4b,0x58,0x3b,0x60,0x7b,0x91,0x2f,0x0d,0xb4,0x6d,0x00,0x80,0x19,0xaa,0x88,0xbc,0xb2,0x7b,0xd9,0xb7,0xdd,0x32,0x47,0x62,0xf5,0x0f,0x46,0x95,0x4c,0x6c,0x01,0x67,0xfb,0xe4,0x2b,0xac,0x95,0x84 +.byte 0x25,0x0a,0xe5,0x4c,0x2d,0x4a,0x6e,0x77,0xfd,0xeb,0xe1,0x53,0xc9,0x2e,0x70,0x01,0x32,0x05,0x6d,0xc5,0xc9,0x5d,0x90,0xca,0x56,0xd1,0xd8,0x40,0x2a,0x51,0x4d,0x95,0xc3,0x57,0x8b,0xdd,0x62,0x9c,0x69,0xd1,0x03,0x89,0x95,0x38,0x2c,0xc1,0x6d,0x41,0xf2,0xc3,0xa2,0x9c,0x43,0xea,0xf1,0x02,0x00,0x56,0x46,0xbb,0x87,0x35,0x40,0x0e +.byte 0x18,0x51,0x29,0x39,0xbb,0x6d,0x15,0xf2,0xcd,0x54,0x23,0x95,0x69,0xdc,0x0a,0xb2,0x26,0xd9,0x25,0xe1,0xf1,0x07,0x7b,0x5e,0xc3,0x30,0x68,0x5f,0x2a,0xce,0x91,0x92,0x03,0x0c,0x62,0x11,0x43,0x80,0xe5,0x12,0xec,0xe3,0x4f,0x90,0xfe,0x38,0x6e,0xe9,0x7e,0x94,0x83,0x26,0x59,0x3f,0x3f,0x81,0xc6,0x94,0x98,0x09,0x80,0xff,0x01,0x44 +.byte 0xff,0x77,0x6a,0x4c,0x76,0x91,0xd9,0x12,0x59,0x9a,0x00,0x7c,0x87,0x06,0x17,0xf7,0x12,0xc7,0xee,0x04,0xd5,0x8d,0x68,0xc5,0x8d,0x80,0x10,0xcc,0x14,0x45,0xe8,0xd7,0x43,0x10,0x01,0x9e,0x61,0xc2,0xc0,0x66,0xfe,0xcf,0x5f,0x9f,0xcb,0xa3,0xf8,0xc7,0x07,0x41,0xe3,0xf2,0xda,0x6e,0x01,0x76,0xc6,0x49,0x49,0x01,0xc7,0xcf,0x6a,0x20 +.byte 0x71,0xc5,0xf0,0xb1,0xa0,0xc9,0xed,0xec,0x66,0x71,0x93,0xf5,0xc0,0x27,0x42,0xed,0xd5,0x6f,0x20,0xe1,0x86,0x3e,0xd0,0x5d,0x94,0x17,0x43,0xb4,0x98,0x0d,0x8a,0x31,0x6c,0x59,0xa9,0x0b,0xb3,0xa4,0x0b,0x46,0x0b,0xa8,0x79,0x62,0x3a,0x3d,0xbf,0xef,0x94,0xd3,0x31,0xf2,0xa1,0x55,0xe8,0x92,0x44,0x37,0x62,0x82,0x1b,0x60,0x87,0x67 +.byte 0x85,0x78,0xd5,0x84,0x73,0xa4,0xea,0x56,0x08,0x78,0x68,0x7f,0xfb,0x15,0x20,0x64,0xeb,0x6c,0xf7,0x5e,0xc0,0x79,0x83,0x59,0x7b,0xed,0x2d,0xa9,0x37,0x46,0xf3,0x62,0xb1,0xa1,0x2b,0x48,0x58,0xd9,0x0c,0x03,0xf7,0xf3,0x47,0xeb,0xd7,0x03,0x9b,0x85,0xd3,0xd7,0xd7,0x7e,0xfb,0x1a,0x25,0x83,0xda,0x06,0xa0,0x04,0x0d,0x6b,0x90,0x29 +.byte 0x2a,0xfc,0xcd,0x96,0xe9,0x17,0x4f,0xdd,0x2c,0x90,0xdf,0xf1,0xe3,0x08,0x0a,0xb8,0x0c,0x59,0x2a,0x83,0x62,0x94,0x00,0xd3,0x80,0x1a,0x31,0xd7,0x17,0x70,0xc7,0xa2,0x20,0x17,0x65,0x88,0xae,0x11,0x25,0xc9,0xba,0x76,0xa7,0x61,0x60,0xd1,0x59,0x50,0x22,0xdd,0xaa,0xcf,0x9d,0xc1,0x36,0x7d,0xf9,0x7b,0x69,0xc0,0x98,0xba,0x40,0xd5 +.byte 0xd6,0x46,0x93,0x92,0x7d,0x37,0x3f,0x3a,0x04,0x9a,0x84,0xaf,0x8e,0x61,0x04,0x26,0x54,0x33,0x84,0xc0,0xac,0x21,0x51,0xd7,0x9a,0x93,0x6e,0xf2,0x09,0x87,0xc5,0x35,0xa8,0x96,0xb0,0x64,0x90,0x35,0x52,0xed,0x0e,0xbc,0xdb,0xa6,0x06,0x3e,0xe7,0xea,0x57,0x4b,0xd7,0xc5,0x1c,0x76,0x3d,0x0d,0xc3,0x1f,0x8e,0x4f,0x12,0xdb,0x3a,0x21 +.byte 0x2a,0x69,0xc2,0x94,0xda,0x4c,0x91,0xcc,0xa8,0x36,0x89,0xd7,0x78,0xa8,0x74,0x79,0x63,0x92,0xeb,0x39,0x3b,0x84,0x8c,0xe5,0xc6,0x26,0xf0,0xef,0xcc,0xc1,0x72,0x4b,0x8e,0xcd,0xe4,0xd9,0x00,0x80,0xbc,0xdf,0xe2,0x61,0x53,0x04,0x81,0xb0,0x13,0xc5,0x6c,0x77,0x74,0xa3,0x0c,0x5b,0xef,0xef,0xea,0xc7,0x5b,0xeb,0xbf,0xee,0x54,0xd7 +.byte 0x7a,0x69,0x6e,0x39,0xc2,0xed,0x08,0x44,0x82,0x08,0x16,0x8b,0xf1,0x74,0x5f,0xeb,0x60,0xd5,0x46,0x63,0x80,0x39,0xe9,0x91,0x0a,0x17,0x8b,0xd4,0x09,0xdc,0xa6,0xab,0x6a,0xbc,0xf8,0xe9,0x09,0x19,0xc1,0x83,0x9f,0xdf,0xad,0x6c,0x31,0x94,0xb9,0xc5,0x77,0x83,0xd1,0xd8,0x76,0xeb,0x12,0x3c,0x00,0x31,0xea,0xac,0x97,0x39,0x16,0xd5 +.byte 0x81,0xfa,0x6d,0x10,0x5b,0x3e,0x20,0xe1,0x88,0x5c,0x4b,0xf3,0x04,0xd4,0xc3,0xb9,0xec,0xe5,0xb0,0x13,0xf5,0x09,0x5c,0xe8,0x27,0xe2,0xde,0x9b,0xac,0x2e,0xf2,0xe5,0x2c,0x33,0x4b,0x4f,0xec,0xc7,0x08,0xf9,0xc2,0xd3,0x1b,0x4d,0x81,0x69,0x14,0xa1,0xc5,0x0f,0xb2,0x57,0x8b,0xcc,0xca,0x3b,0xc9,0x9c,0x1f,0xee,0x06,0x4d,0xc7,0x62 +.byte 0xcb,0x8f,0x49,0x81,0xfb,0xa5,0x68,0x81,0x36,0x38,0x33,0x6b,0x9e,0x58,0xd4,0x24,0x67,0xf1,0x30,0xd6,0x08,0x61,0x5a,0x7f,0x2e,0x4e,0xf1,0xd6,0x64,0x75,0x72,0xb0,0xdf,0xcd,0xae,0x04,0x41,0xbd,0x04,0x2c,0x96,0x36,0x34,0x32,0xec,0xbd,0xd0,0xbf,0x8e,0xe8,0x47,0xe3,0x22,0xdd,0x79,0x53,0xcc,0x6a,0x25,0xf1,0x5e,0x63,0x09,0x98 +.byte 0xc5,0x6d,0x0a,0xe3,0x30,0xd6,0x52,0x70,0x21,0xb2,0xef,0x15,0x66,0x4a,0x2d,0x2b,0x5c,0xcb,0x39,0x1b,0x91,0x10,0xa6,0x02,0x22,0xd0,0xcc,0x32,0x50,0x5c,0x70,0x72,0xd1,0x03,0xb3,0x2d,0x2e,0x33,0xed,0xae,0x7a,0x07,0x3f,0x70,0x38,0x35,0xfc,0xcf,0xdb,0xfe,0x7b,0x26,0xd9,0x38,0x1e,0x52,0x07,0x2f,0x72,0x81,0xcc,0xd3,0x21,0x00 +.byte 0x63,0x48,0x38,0x44,0xb8,0x35,0xf2,0x4f,0xe5,0x33,0x8c,0xb3,0x07,0x0c,0xac,0x3d,0x73,0xe8,0xe3,0xb3,0x43,0xc5,0xb4,0x32,0xf4,0x41,0xdf,0x7b,0x06,0x3a,0xb8,0x67,0x17,0xc5,0xec,0x46,0x30,0xc0,0xa4,0x29,0x40,0xe4,0x8a,0xa3,0x14,0x84,0xa6,0x84,0xc7,0x5d,0x4b,0x57,0x37,0x9c,0x42,0xe6,0xa4,0x20,0xf7,0x5d,0xef,0x21,0xe2,0x80 +.byte 0x54,0x6d,0xf5,0xb5,0xbe,0xa3,0x95,0xcf,0x98,0xf8,0x38,0x46,0xa2,0x90,0x57,0x09,0x8f,0xb0,0x6d,0x01,0x5f,0x95,0x5a,0x78,0xf6,0xfd,0x01,0x0f,0xfd,0xa5,0xe2,0xcf,0x54,0xa3,0x2b,0xc1,0x30,0xbe,0x6d,0x1a,0xd3,0xdb,0x5a,0x17,0x43,0x46,0x93,0x81,0x0c,0x85,0x04,0x13,0xda,0xb4,0xde,0x81,0x48,0x5c,0xbc,0x42,0x9e,0x6d,0x6c,0x82 +.byte 0xff,0xa5,0x51,0xb1,0xd3,0xd2,0x3d,0x82,0x82,0xb4,0x96,0xb1,0x38,0x5d,0xc9,0x55,0xcb,0x9f,0xe5,0x47,0xd4,0x52,0x0f,0x76,0x54,0xec,0x39,0xb6,0x40,0xc3,0xc5,0xaa,0xc2,0x30,0x02,0xa0,0x68,0xc3,0x22,0x63,0x5a,0x8c,0x62,0x6d,0x40,0xc5,0xde,0x06,0x29,0x44,0x5d,0x2b,0x18,0x0a,0xa5,0x43,0x47,0xfe,0x5f,0x0f,0x63,0xa4,0x3c,0xa1 +.byte 0x62,0xcb,0x70,0x1d,0xf8,0x0e,0xc9,0xbe,0x27,0x0e,0x87,0x81,0x69,0x4c,0xea,0xbe,0xf9,0x9b,0xda,0xb6,0x9b,0xd0,0xdd,0xa0,0x1e,0x60,0x38,0x88,0x85,0x25,0x53,0xee,0x2c,0x77,0x53,0x82,0xb0,0x88,0x19,0x87,0x2a,0x77,0x7b,0x37,0x4b,0x4c,0xf4,0x96,0x5f,0x73,0xa1,0xbb,0x5c,0xfc,0x7e,0xbb,0xed,0x6f,0xb7,0x6f,0x9d,0x55,0xde,0xd3 +.byte 0xac,0xb9,0x8e,0x36,0x0f,0x3d,0xea,0x87,0xcd,0x19,0x33,0x1d,0xa8,0xee,0xfc,0xcd,0xe5,0x53,0x7b,0xdf,0x37,0x49,0x2d,0x73,0xf5,0x36,0xdd,0x42,0xc6,0x88,0x0d,0xf5,0xf2,0xba,0x2e,0x81,0xed,0x88,0x27,0x8d,0xe5,0x3f,0x83,0x5e,0xde,0x63,0x8f,0x67,0x2b,0x85,0xf3,0x2a,0x9b,0x26,0x3e,0x2b,0xe2,0x29,0xc5,0x5e,0x21,0x04,0xfe,0x5b +.byte 0xb9,0xd8,0xa7,0x7b,0xdf,0xcf,0x61,0xd6,0xaf,0x9b,0x17,0xcb,0xaf,0x8f,0x71,0xb3,0xc2,0x9d,0x9a,0x55,0x1d,0x3e,0x1d,0x17,0x25,0xc8,0x44,0x71,0x29,0x2f,0xc8,0x01,0x3b,0xe4,0xc4,0x2e,0xcc,0x3b,0xdb,0x34,0xbb,0xc0,0xcc,0xb6,0x07,0xe3,0x86,0x4c,0x62,0x02,0xe8,0xc3,0x11,0x85,0x6c,0x18,0x80,0xa3,0xbd,0x02,0x30,0x68,0x36,0xa3 +.byte 0xb6,0xc6,0xbd,0x82,0x43,0x40,0xed,0xa1,0xcf,0xc5,0xce,0xe4,0x27,0x8a,0xeb,0x8c,0x59,0xea,0x4a,0x81,0xd9,0x35,0x87,0x7d,0x6d,0xb2,0x8f,0x67,0x37,0x1f,0x11,0x60,0x0d,0xed,0x34,0xd5,0xa0,0x7b,0x46,0x71,0x68,0x19,0x69,0xd3,0x65,0x1d,0x47,0xf1,0x7e,0x16,0xd8,0xec,0xbb,0x52,0xc3,0x7b,0x62,0x5a,0xb3,0x60,0x67,0x2e,0xfd,0x57 +.byte 0xf2,0xfb,0x3d,0x63,0xe6,0x82,0x20,0xff,0x31,0x90,0x1d,0x5e,0x4f,0x04,0x9a,0xf8,0xb2,0x0c,0x84,0xff,0x7d,0xe2,0xec,0x4b,0x09,0xbb,0xdf,0xae,0xc5,0xaf,0xcb,0x8b,0xb5,0x5d,0xa8,0x53,0x78,0xf9,0xb9,0x43,0x71,0xa6,0xc2,0x10,0xfa,0xad,0xda,0xba,0x46,0x13,0x72,0x97,0xef,0x6f,0xe3,0x4f,0x5f,0xf9,0xec,0x25,0xdb,0xcd,0xca,0x33 +.byte 0x7e,0x50,0x73,0x5b,0xd0,0x9f,0xea,0xd5,0xd9,0x29,0xe8,0x1b,0xc1,0xf8,0x40,0xbf,0x50,0xdb,0x8e,0x39,0x0b,0xb7,0x6c,0xf1,0x34,0x0b,0x1f,0x88,0x27,0x4b,0xea,0x1d,0xb2,0x36,0x07,0x4b,0x22,0xa9,0xd0,0xf8,0xf2,0x13,0x8e,0x97,0x9d,0xd9,0x53,0xd3,0xdc,0x63,0x40,0x11,0xc7,0x74,0x9e,0xd9,0x83,0x01,0xae,0x36,0xcb,0x35,0x9a,0x0c +.byte 0xb5,0x15,0x0a,0xf5,0x41,0xa5,0x6c,0x72,0x40,0x80,0xf0,0x15,0xc0,0x80,0x23,0x0b,0xab,0x98,0xfc,0xab,0x81,0xe0,0x8b,0x61,0x91,0x18,0xd2,0x23,0x71,0xed,0x32,0x80,0x26,0x86,0x96,0xe9,0x90,0x5e,0x43,0xd2,0x89,0x8f,0x89,0x57,0x73,0xca,0xe1,0x42,0xa9,0xa9,0xed,0xdd,0xc5,0x9f,0xf7,0x00,0x0d,0xa3,0xe5,0xc8,0x6f,0x0c,0x14,0xa4 +.byte 0x9d,0x5a,0x14,0xaf,0x96,0x3a,0xb2,0x64,0xa7,0xac,0x20,0xa9,0x01,0x4c,0xec,0x64,0xc6,0x9b,0xfd,0x04,0xc5,0x2e,0xe7,0xdd,0xa5,0x8e,0xe7,0xe7,0x76,0x53,0x59,0x95,0x14,0x07,0xed,0xe9,0x96,0xd0,0x2d,0xc8,0x9d,0xa2,0x11,0xe3,0x02,0x20,0x68,0x09,0x25,0x69,0x07,0x88,0xdb,0x26,0x36,0xf5,0x8e,0xc3,0xf0,0x70,0x8c,0xeb,0xe6,0xcd +.byte 0xad,0xf3,0x49,0x6e,0x8a,0x54,0xa6,0xdd,0x97,0x8e,0x37,0x28,0x3a,0x6d,0xc4,0xdd,0x99,0x85,0xf7,0x96,0x63,0xb4,0xa2,0xdf,0xff,0x81,0x17,0xa1,0x22,0xb1,0x43,0x5b,0x29,0xdb,0x92,0x91,0xc9,0xc6,0x8d,0x29,0x1d,0x6e,0xe3,0x44,0x3e,0xe4,0x20,0xd5,0xf4,0x4a,0xfa,0xae,0xf6,0x2c,0xff,0x80,0xc9,0xce,0x7f,0x13,0x1e,0xd7,0x24,0xa2 +.byte 0xb3,0x90,0xb8,0x20,0x18,0xe5,0x6c,0x0e,0xf5,0xc6,0x26,0xd6,0xe9,0xe8,0x55,0xe4,0x3f,0x49,0x13,0xe2,0xca,0xef,0x9b,0xc0,0x8f,0x24,0x50,0x37,0xef,0x21,0xff,0x79,0xb7,0x5d,0x86,0x03,0xfb,0x85,0x75,0x74,0xbf,0xc5,0x3a,0x30,0xcc,0x00,0xc3,0x0d,0x4f,0x91,0xd6,0x31,0x19,0xd6,0xcd,0x0e,0x1c,0x53,0x88,0x75,0xb8,0xf9,0x68,0x7a +.byte 0xa4,0x3e,0x8d,0xed,0xba,0x05,0xb4,0x6c,0xe0,0x45,0x9c,0x41,0x34,0x24,0x82,0xaf,0x9a,0xcf,0x9e,0xd2,0x27,0x5c,0x7f,0xb3,0xcb,0xe5,0xad,0xb4,0x8e,0x74,0x9d,0xe4,0xba,0x55,0xb3,0xd3,0x32,0xbc,0x62,0x11,0xb3,0xa4,0x82,0xf0,0xd8,0xfc,0x79,0x03,0x70,0xae,0x7f,0x7f,0xc8,0x50,0xb5,0xbe,0x47,0x14,0x31,0xd7,0x16,0x65,0x52,0x3b +.byte 0xbb,0x42,0x38,0x23,0x77,0x4d,0x38,0x0b,0x0a,0x61,0x94,0xac,0xa3,0xc9,0xd7,0x99,0x4f,0x34,0x3a,0x88,0xe8,0x1d,0x0b,0x97,0x48,0x6d,0x5c,0x61,0x4c,0x3f,0xc2,0x7c,0x6c,0x63,0x00,0xdd,0x59,0xae,0xcd,0x17,0x0a,0x21,0x27,0x98,0x15,0x23,0x6d,0x84,0x7e,0x24,0xd4,0x7f,0x1b,0x3a,0x98,0x52,0xc3,0x60,0x33,0xd6,0xc1,0xfe,0x68,0xa8 +.byte 0x49,0x3d,0x7e,0x53,0xee,0x0d,0xed,0x89,0x9a,0x9a,0xe6,0xa1,0x47,0xc7,0xba,0xf3,0x73,0x5b,0xef,0x33,0x51,0x8c,0x1f,0x84,0xa6,0xef,0x77,0x94,0x2d,0xd6,0xda,0x8f,0x85,0x8c,0xd3,0xb6,0x02,0x68,0x9e,0x57,0xb6,0xd9,0x1a,0x8c,0xb5,0xf4,0x61,0x39,0x29,0xb5,0xb7,0x0d,0x0d,0xa6,0x81,0x87,0x54,0xc0,0xca,0x67,0x09,0xca,0x20,0xf3 +.byte 0x37,0x7e,0x03,0x3e,0x31,0x8c,0x51,0x89,0x06,0x81,0xf6,0x7b,0x8b,0xe3,0x4f,0xd0,0xb8,0x0c,0x34,0x7c,0xd6,0xfc,0x25,0xf8,0x00,0xa6,0x10,0x15,0x0d,0xeb,0x22,0x72,0x03,0x79,0x1c,0x84,0x1d,0x3d,0x10,0xaf,0x43,0x6d,0xd7,0xed,0x10,0x2c,0x14,0x26,0xd4,0xa1,0xee,0x6c,0x7f,0x52,0xe4,0x83,0xcc,0x5f,0x1a,0x4b,0xd0,0xc8,0xfb,0x27 +.byte 0x17,0x2c,0xf6,0x90,0x02,0xb4,0xb0,0x63,0x7c,0x14,0xec,0x9e,0x08,0x60,0xec,0x45,0x85,0xc6,0x76,0x42,0x4f,0x1c,0x5f,0x48,0x7f,0x87,0xef,0x8c,0x04,0x23,0x3c,0xda,0x39,0xbc,0xec,0x09,0xda,0xeb,0x9b,0x72,0x7a,0xb4,0x20,0x1c,0xb2,0xdd,0x2e,0x63,0x72,0xd7,0xb1,0xfe,0x5b,0x21,0x28,0xfb,0xeb,0x45,0x31,0x89,0xe5,0x3e,0xa0,0x85 +.byte 0xa6,0x96,0xdb,0x42,0xd5,0xb4,0x27,0x78,0x10,0xa0,0xcb,0x69,0x68,0x1e,0x76,0xed,0xbc,0x3c,0xa1,0x04,0x10,0x81,0x2a,0x4f,0x52,0x78,0x1e,0xae,0x5a,0x47,0x69,0x81,0xee,0xd3,0x14,0x1a,0x68,0x19,0x75,0x92,0x72,0x47,0x61,0x70,0xcf,0x96,0x35,0xa6,0xbb,0x00,0xaf,0x3e,0x90,0x86,0x22,0x9b,0x72,0x8a,0xa1,0x05,0xe2,0xfb,0xdc,0x30 +.byte 0xd5,0xdd,0x46,0x1f,0xf6,0x33,0x43,0xd1,0x59,0xc4,0x93,0x89,0x36,0x6a,0x7b,0x76,0xa7,0x40,0x6c,0xb1,0x9c,0xce,0x3a,0x8c,0xb6,0xd5,0xd1,0x0a,0x78,0xf6,0x08,0xfb,0xf5,0x9c,0xee,0x74,0x0d,0x39,0x51,0x6d,0x0e,0xa6,0xe9,0x22,0xd8,0x30,0xdf,0x16,0xf7,0xe3,0xbd,0xbb,0xe6,0x45,0xb8,0x9c,0xb5,0x49,0xf0,0xe8,0x7c,0xce,0x25,0xf8 +.byte 0x46,0xc0,0x59,0xc2,0xbc,0xdd,0xea,0x3e,0xeb,0x2e,0xf5,0xfd,0xd9,0x05,0x8a,0x2f,0xa3,0xa4,0x63,0xa6,0x50,0x08,0xce,0x2a,0x69,0xe7,0x58,0x57,0xa1,0xb2,0x44,0x41,0x04,0xfc,0x61,0xb1,0xb8,0x19,0x27,0x14,0x71,0x2f,0x55,0x64,0x28,0xa0,0xcc,0x47,0x0c,0xd4,0xed,0xfd,0x07,0x99,0xc6,0x9e,0xdc,0x5f,0x19,0x03,0x1a,0x00,0xda,0xf6 +.byte 0x2c,0x95,0xb0,0xd2,0xaa,0xfb,0xbc,0x1a,0xf3,0x62,0xaf,0x9c,0x38,0xde,0x61,0x30,0xd5,0x56,0x82,0x4b,0xf6,0xeb,0x34,0xc0,0xdc,0x51,0x97,0x89,0x80,0x47,0x9d,0x2a,0xae,0x0e,0x92,0x48,0xd2,0x9d,0x5a,0x67,0xef,0x33,0xa3,0xbe,0xdd,0x80,0x64,0x9c,0xc1,0xaf,0xf9,0x1a,0x4b,0x55,0x67,0x88,0x37,0x37,0xff,0x98,0xe3,0x9e,0xa9,0x4e +.byte 0x1f,0xa1,0x32,0x70,0xa3,0xbb,0xdc,0x6e,0xb3,0x6d,0xfe,0x8f,0x74,0x89,0xed,0xe1,0x13,0x3c,0x8f,0x08,0x75,0x84,0x84,0xee,0xac,0xcc,0xa5,0x47,0x9f,0x3e,0xb9,0xed,0x26,0x20,0xf7,0x7b,0xfb,0x8a,0x48,0x58,0x51,0x24,0xf9,0xeb,0x66,0x6d,0xd6,0x83,0x24,0xff,0x9f,0x0d,0x38,0x9c,0xf9,0x24,0x99,0x12,0x49,0xb6,0xdd,0xce,0x44,0xe7 +.byte 0x31,0x3d,0x4b,0x23,0x8a,0xd5,0x62,0xa2,0xdb,0x78,0x56,0x3a,0x62,0xc8,0x59,0x5f,0xcc,0x58,0x76,0x19,0x5d,0x48,0x4a,0xc2,0x87,0x21,0xc3,0x3d,0x3a,0x38,0xbd,0x20,0xfd,0xc3,0xa6,0xab,0x32,0xb8,0xc8,0xd1,0x5c,0xa5,0xb4,0x64,0x60,0xd2,0x87,0xb7,0xe9,0xc2,0x2b,0xb2,0x75,0x04,0xf4,0x6e,0x96,0x99,0x5d,0x08,0xff,0xa3,0x45,0x8a +.byte 0xad,0x7c,0xee,0x94,0x4e,0x45,0x86,0xad,0x0a,0x7a,0x5c,0x8f,0xff,0x28,0xb3,0x3c,0xf8,0x5e,0xb3,0x1e,0x5c,0xe0,0x22,0xf7,0x4e,0xe4,0xdf,0x1f,0xd2,0xa2,0x37,0x4a,0x87,0xa6,0x16,0x80,0x0c,0xc3,0x75,0x18,0xe4,0x76,0x8f,0xc3,0x1b,0xee,0xb1,0xe4,0x4b,0xeb,0x6f,0x15,0x48,0x60,0xaf,0x8e,0x0e,0xeb,0xbe,0x26,0xa3,0xbd,0x2a,0xb5 +.byte 0x6d,0x8b,0xd1,0xa1,0x0f,0x8e,0xaa,0xaa,0xb8,0x8d,0x84,0xe7,0x65,0x40,0x60,0x3d,0x59,0xb7,0x1c,0xef,0x08,0x0e,0x6f,0x21,0xb4,0xe6,0x10,0xda,0x59,0x9a,0x0f,0xe6,0xba,0xfd,0xed,0x7f,0xc1,0xe3,0x7a,0xb7,0x21,0x5d,0xcf,0x1c,0xbd,0xd2,0x59,0xc0,0x31,0xa5,0x8a,0x39,0x86,0x9e,0x7e,0x6a,0xcb,0x87,0x6f,0x01,0xba,0xa4,0x06,0x6b +.byte 0x3b,0x5d,0x68,0x85,0x11,0xd2,0x2a,0x3c,0x8e,0x3a,0x8c,0x8b,0x59,0xa0,0x4a,0xfb,0x76,0x85,0xe6,0x47,0xc3,0xf4,0xc4,0xe6,0xcc,0x7b,0xff,0x71,0x03,0xd1,0xc2,0x01,0xe4,0x5e,0x49,0x31,0xa6,0x0e,0x17,0x9b,0x42,0xdc,0x75,0xd6,0xfe,0x09,0x0b,0x6d,0x21,0x46,0xfe,0x40,0xcd,0x7c,0xdb,0xca,0xc9,0xba,0x64,0x83,0xd3,0xf7,0x0b,0xad +.byte 0xff,0xfd,0xe3,0xd9,0x49,0x7f,0x5d,0x48,0xaa,0xac,0xe5,0x74,0x2a,0x14,0x6f,0x64,0x21,0x81,0x09,0xcd,0x2d,0x19,0xf5,0x56,0x85,0xa8,0xec,0x98,0x65,0x46,0x99,0xec,0xbe,0xe3,0x86,0xd3,0x41,0x8b,0xe4,0x76,0x9b,0x5b,0x98,0x33,0x9e,0xdb,0xc9,0xde,0x89,0xfa,0x60,0x58,0xa8,0x2f,0x7a,0xca,0x30,0x91,0xc8,0x26,0x14,0x9c,0xd6,0x6d +.byte 0xc2,0x3c,0xca,0xe0,0x9a,0x13,0x72,0x63,0x5e,0x20,0xfd,0xa0,0xca,0xb2,0xed,0x37,0xc5,0xd4,0x4e,0xec,0x1f,0x74,0x25,0x37,0xe2,0xbe,0xb1,0x7f,0x52,0x26,0x28,0x4f,0x02,0xe5,0x6a,0x27,0xf3,0xc4,0x9c,0x69,0x09,0xac,0xff,0x77,0x9c,0xa4,0x1d,0xe7,0xa1,0x7c,0x37,0x70,0x3b,0x3c,0xc4,0x16,0x8f,0x5d,0xe5,0x05,0xa9,0x2c,0x91,0x2e +.byte 0x87,0xb0,0xa9,0x2e,0x32,0x73,0x5c,0x15,0x1e,0xbe,0x01,0xc9,0xd8,0x2e,0x26,0xf4,0x05,0x2d,0xe0,0xc0,0x38,0x81,0x61,0xf4,0x37,0x08,0xa0,0xc0,0x28,0x0a,0xb6,0xd4,0xcc,0x2c,0xc6,0xd4,0xda,0x48,0x49,0xcf,0x76,0x91,0x23,0x51,0x91,0xe7,0x50,0x94,0xae,0xb7,0x15,0x26,0xaa,0x82,0xd0,0x97,0xe8,0x5e,0xaa,0xfc,0xaa,0x60,0x62,0x81 +.byte 0x80,0xfd,0xfd,0xaf,0x65,0xcc,0x29,0x27,0x95,0xad,0x56,0xb9,0x85,0x66,0x49,0x62,0xb3,0x1a,0xf4,0x54,0xc7,0x5d,0x7f,0x73,0xe0,0xd2,0xc8,0x18,0x95,0x62,0x2f,0x5c,0x96,0xfb,0x63,0x15,0x46,0x07,0x5f,0x3e,0x52,0x18,0xf8,0x5d,0x45,0x0b,0xb6,0xf7,0xc5,0x3d,0x16,0xaa,0x0b,0x8f,0x9d,0x16,0xc8,0x93,0x13,0xd2,0xba,0x7a,0x52,0x1a +.byte 0x7a,0x73,0xc4,0xca,0xfb,0x04,0xaf,0x6f,0x3e,0xfa,0xff,0x29,0x09,0xe2,0x74,0x35,0xc1,0xfc,0x21,0xcf,0x5f,0xf7,0x82,0x55,0x75,0x27,0xc9,0x91,0xc5,0xbf,0xe6,0x68,0xb6,0x0f,0x10,0x0e,0x91,0x30,0xb7,0x05,0xca,0x59,0x4a,0x7f,0xb0,0xf6,0xaf,0xf1,0x5d,0xc9,0xc5,0x06,0xc5,0xf4,0xe1,0x75,0x16,0x9a,0x2c,0xc0,0x3f,0xc1,0x98,0x91 +.byte 0xb7,0xe6,0xb1,0xf2,0xf9,0xfa,0x6d,0x27,0x98,0x33,0x8b,0x73,0x7a,0x57,0x12,0x6f,0x80,0x11,0x28,0x17,0x7d,0xf1,0x26,0xaa,0x05,0xf1,0x6e,0x86,0x98,0xe7,0xf6,0x9f,0x9c,0x06,0x8f,0xec,0xd7,0x2d,0xb0,0x83,0xdf,0x23,0x80,0x34,0xd3,0xd7,0xf7,0xd5,0x0d,0x52,0x18,0xcd,0xc7,0xe7,0x15,0xc9,0x1b,0xae,0x58,0xcf,0xc5,0xdd,0x25,0x2a +.byte 0xff,0xa5,0xf3,0x6d,0x20,0xfd,0xda,0xfd,0x78,0x30,0x14,0x1f,0xb3,0x47,0xe3,0x2d,0x54,0x87,0xdc,0x30,0xbe,0x41,0xc0,0x48,0x52,0x82,0x49,0x78,0xad,0xfd,0x24,0xad,0xd6,0xc1,0x14,0x1e,0xa0,0xc1,0x3d,0x82,0x59,0x01,0x9b,0xc3,0xf4,0xf7,0x26,0xce,0x92,0x50,0x13,0x47,0xe0,0xf3,0xfa,0xd9,0x61,0x19,0x80,0x12,0xee,0x73,0x45,0x5b +.byte 0x34,0xfc,0xb2,0x84,0xb2,0x3f,0xdc,0x77,0x8e,0x2d,0xb3,0x62,0xb9,0x03,0x2d,0xb6,0x2a,0x17,0xcd,0xfb,0x54,0xc2,0x5e,0xb9,0xcf,0xd6,0x05,0xe2,0xac,0x3f,0xce,0x50,0x0f,0xa1,0x3e,0x67,0x68,0x46,0x0c,0xab,0xa1,0xdc,0x2a,0x26,0x1f,0x22,0x1b,0xa7,0xc9,0x3b,0x6c,0x97,0x5d,0x5c,0x7d,0x1a,0x46,0x4a,0x99,0x92,0x85,0x87,0x35,0x6c +.byte 0x78,0x9d,0xb0,0x39,0xd6,0x3b,0x52,0x60,0xb4,0xba,0xcc,0x2e,0xe9,0xe1,0x91,0x51,0xc1,0x52,0xc7,0x5d,0x84,0x95,0x54,0x25,0xdd,0xcd,0x40,0x35,0xa1,0xc8,0x7e,0xff,0x82,0x55,0x9f,0x64,0xef,0xa7,0xc1,0x79,0x57,0xc7,0x44,0xa8,0x1c,0x06,0xaa,0x2a,0x05,0x65,0x6c,0xdc,0x90,0x7d,0x2e,0x53,0x3c,0x56,0xe1,0x30,0xdf,0xcb,0x75,0x3d +.byte 0x36,0x88,0xfd,0x72,0x2d,0xc7,0x8e,0x2f,0x11,0x5a,0x2e,0xa9,0xd6,0x37,0x4b,0x31,0x4e,0x6e,0xa0,0x4a,0xd9,0xa9,0x48,0x18,0x50,0xb1,0x28,0xf6,0x74,0x03,0x44,0xa7,0x06,0x55,0x86,0x1a,0x1b,0x07,0x79,0xc4,0x25,0xba,0x5d,0xce,0xa2,0x96,0x7d,0x62,0xa7,0x21,0xf0,0xa7,0xc2,0x91,0x03,0x38,0x37,0x0b,0x20,0x40,0x88,0x7b,0x28,0xf4 +.byte 0xf3,0xc2,0xb0,0x4b,0xf6,0xef,0x2f,0xd9,0xb5,0x81,0x17,0x95,0x42,0x98,0x7f,0x18,0xd4,0x7e,0xa1,0x85,0xbf,0x62,0xdc,0x40,0xe4,0xd3,0xcc,0x78,0x01,0xec,0x12,0xcc,0x04,0x5b,0xfe,0xdb,0x39,0x7c,0x1e,0x56,0x7c,0x72,0x57,0xb9,0xdf,0x9d,0x43,0xd4,0xe3,0x1f,0xbf,0x69,0xfb,0x43,0x23,0xd8,0x75,0x81,0xe8,0x39,0x0f,0xe4,0xe9,0x51 +.byte 0xea,0xb7,0xa7,0xc6,0x17,0xc6,0x75,0x4c,0xa8,0x17,0x41,0x1c,0x55,0x8e,0x8d,0xf3,0x64,0xbc,0xc3,0x33,0xa7,0xc1,0xbe,0xa2,0x89,0x75,0xd6,0xda,0xad,0x44,0xd5,0xdd,0x18,0xe2,0xfc,0x1d,0xa1,0xbc,0x1a,0xb8,0x40,0x1a,0x4f,0x44,0x4b,0x56,0xe9,0xf4,0xa8,0x16,0xe6,0xc9,0x40,0x90,0x9b,0x49,0xae,0x62,0x12,0x3d,0x50,0x2e,0x7b,0x60 +.byte 0x6f,0x04,0x01,0x2c,0x83,0x2a,0xd2,0x92,0x63,0xa2,0xe2,0x39,0x9a,0xc4,0x1e,0x5a,0x53,0x3f,0x4d,0x69,0xfa,0x0a,0x22,0x13,0x80,0xa4,0x6e,0xfb,0x09,0xcb,0x35,0xd7,0x12,0xa4,0xcd,0xfc,0x0b,0x06,0xa6,0x5e,0xc6,0x4a,0x22,0x56,0x5d,0x7f,0x70,0xd0,0xf8,0xe6,0x96,0x77,0xce,0xd9,0x69,0x6c,0x06,0xac,0xaa,0x94,0x6d,0x57,0x1b,0x28 +.byte 0xb4,0x07,0x50,0x19,0xd1,0x86,0xba,0xe6,0xe6,0x31,0x74,0x1d,0x3d,0xe8,0xe2,0x7b,0xfe,0xc9,0x41,0x89,0x20,0x5b,0x6a,0xc0,0x18,0x16,0xee,0x35,0xfa,0x56,0x35,0x3e,0x53,0x99,0xfb,0x8d,0xae,0x75,0x4f,0xc5,0x8d,0xff,0x23,0xd5,0x42,0xf4,0x81,0x5c,0x8b,0x71,0x7a,0x22,0xb0,0x6b,0x45,0x86,0xa6,0xc6,0xdb,0xa6,0x83,0x01,0x28,0xde +.byte 0x38,0xaa,0x6e,0xf8,0x5a,0xf2,0xcc,0x3c,0xc5,0x65,0x78,0x37,0xe8,0x8a,0x59,0xf3,0xfe,0x8b,0xcd,0xf6,0x31,0x46,0xdc,0x72,0x19,0xf7,0x73,0xac,0x5c,0xf1,0xe3,0xfd,0x85,0x51,0xec,0x92,0x3a,0xf3,0xd7,0xb2,0x95,0x53,0x79,0x48,0xd3,0x29,0x84,0xec,0xc5,0x0a,0x71,0x15,0x52,0x69,0x6a,0xe1,0xab,0x69,0x94,0xc2,0x51,0xdf,0x27,0xd8 +.byte 0xb1,0x05,0xc4,0x12,0xea,0x1e,0xda,0x6e,0xf2,0xf5,0x8a,0xa8,0x72,0x74,0x5a,0xe5,0x45,0x5b,0x5f,0xf9,0xb0,0x56,0x5c,0x85,0xf7,0x63,0x8d,0x1d,0xbf,0xe9,0x7c,0x97,0xe9,0x37,0xb3,0x5b,0x4b,0x57,0xfc,0xf4,0x58,0x84,0x26,0x55,0x07,0xc7,0x0a,0xfe,0x5a,0x58,0xd0,0xd8,0x19,0xf4,0x02,0xad,0x2c,0x4e,0xbd,0xe1,0x07,0x48,0x3b,0xc4 +.byte 0xd6,0x23,0x3a,0x63,0xc3,0xf5,0x17,0x46,0x03,0xa4,0x9a,0x10,0xf9,0xac,0x70,0x9c,0x13,0x10,0x94,0xda,0x17,0xc5,0xbb,0x87,0x0f,0x9b,0x4f,0x54,0x55,0x6b,0x57,0x2d,0x12,0x0b,0xa7,0x9c,0x77,0x6d,0x67,0xb0,0x03,0xdf,0xc6,0xa2,0x76,0x96,0x0c,0xac,0x30,0xbc,0xa2,0x55,0x23,0x01,0xae,0x51,0x50,0xd4,0xab,0xd0,0xee,0x75,0xf1,0x96 +.byte 0x75,0xf5,0x2e,0xae,0x52,0x31,0x0b,0x0a,0x8a,0xdb,0x4c,0x4d,0x4c,0x80,0xfc,0xd7,0x68,0x05,0x54,0x47,0xa5,0xc4,0xb1,0x63,0x87,0x43,0x1b,0xe1,0x0b,0x4f,0xff,0x0c,0x02,0xf7,0x00,0xd4,0x8d,0x6e,0xa1,0x21,0x91,0x62,0xec,0x55,0xd5,0x72,0x70,0x59,0x7a,0xa4,0x0e,0x78,0x7a,0x87,0x1f,0x71,0x35,0x3b,0xf7,0x1f,0x66,0x8c,0x90,0xf9 +.byte 0x6d,0x1f,0x74,0x47,0x41,0xf5,0x21,0x98,0x0d,0x42,0x61,0x21,0x0b,0x62,0x59,0xc7,0x5e,0x58,0x37,0xfb,0xee,0xbb,0xa0,0x45,0xa8,0x84,0xae,0x41,0x29,0xc9,0x88,0x64,0x69,0x75,0xc1,0x5f,0x63,0x7c,0x00,0x1c,0x35,0x61,0x9e,0xad,0x19,0xd7,0xd8,0xf1,0x64,0x57,0x10,0x87,0x73,0xa8,0x8b,0x39,0x9b,0x1c,0x1a,0xc2,0x1b,0x01,0x1a,0x41 +.byte 0x26,0x58,0x93,0x8f,0xed,0xf9,0xe7,0xfe,0xcc,0x27,0x1b,0x6b,0xb8,0x28,0x5a,0x0b,0x04,0xa0,0x94,0x23,0x4b,0x21,0x5f,0xb3,0xc9,0xb6,0x7b,0x36,0x5a,0x67,0x6b,0xd2,0xc2,0x53,0x97,0x5d,0xa5,0x43,0xd3,0x79,0x83,0xe2,0x3b,0xe0,0xaf,0x5f,0xbd,0xf3,0xb0,0xfc,0x04,0x95,0x06,0x17,0x0c,0xe2,0x68,0xe8,0xf3,0x90,0xc7,0x2b,0x7b,0xcc +.byte 0xaa,0xce,0xf5,0x0b,0x3c,0x3f,0x10,0xa7,0x31,0x9d,0xf0,0x1e,0x3e,0x74,0x57,0xbd,0x87,0xe7,0x37,0xd0,0x37,0x09,0xae,0x03,0x96,0xb1,0xad,0x8f,0x2d,0x72,0xdc,0x0f,0xdf,0xd9,0xfb,0xcc,0xb8,0x48,0x62,0xf7,0xad,0x05,0x4d,0xc6,0xe5,0x92,0xe3,0x95,0xa0,0x74,0x7a,0xa6,0x84,0x13,0x68,0x17,0xaa,0x8f,0x40,0x2a,0x8d,0x2b,0x66,0xdc +.byte 0xf8,0xf6,0x6d,0x7c,0x7e,0x40,0x22,0x05,0x16,0x20,0xbc,0xe5,0xc2,0x87,0xe2,0xd5,0xbd,0x47,0xd5,0x69,0x95,0x12,0x25,0x1c,0xaa,0x9d,0xb5,0x73,0x08,0xaf,0xfb,0x46,0xa5,0x11,0x2c,0x93,0xc6,0xfc,0xc0,0x5e,0x0e,0x99,0x1c,0x80,0x5f,0xe5,0xc8,0x52,0x73,0x35,0x4d,0xbc,0x70,0xeb,0x40,0xc9,0x47,0x8a,0x8f,0x19,0xd9,0xa9,0xec,0x4b +.byte 0x88,0x53,0x56,0x08,0x4a,0xa2,0x32,0x1f,0xe2,0xbb,0x68,0x35,0xfd,0xf2,0x0e,0x0f,0x7f,0xc8,0xf1,0x59,0xac,0x97,0x8f,0x84,0x69,0xb6,0xb9,0x5f,0x84,0xe9,0xf2,0xf9,0x09,0xf6,0xf1,0x31,0xd7,0x1a,0xa8,0x25,0x32,0x5f,0xb1,0xa7,0x84,0x15,0xfa,0x07,0xa8,0x53,0xce,0x2a,0x26,0xe0,0x4d,0x07,0x4f,0x45,0x63,0x76,0xfd,0xe3,0xb4,0x4e +.byte 0x81,0x5e,0xe6,0x01,0x9c,0xf5,0x82,0x2d,0x71,0x0f,0x98,0xb4,0x72,0x06,0xbc,0x89,0x89,0x60,0x5f,0xd9,0x92,0xcf,0xb9,0x41,0xe3,0x13,0xaa,0xe4,0x80,0xb5,0x75,0xf4,0x9a,0x1b,0xc2,0xa3,0xa4,0xa9,0x0f,0x15,0xdc,0x26,0xdd,0x20,0x10,0x27,0xbd,0x06,0x77,0x12,0xa5,0xb3,0xde,0x9f,0xbf,0xc4,0xb6,0x1d,0x76,0xdc,0x16,0x00,0x2e,0xe2 +.byte 0x00,0x4d,0xb3,0x62,0x57,0x73,0x1e,0x90,0xe2,0xaa,0x4c,0x47,0xdf,0x6b,0x2d,0x66,0x2f,0x82,0x55,0x91,0x26,0x33,0xb9,0x3a,0xc7,0xf1,0x0a,0xda,0x9b,0x6b,0x05,0x82,0x0f,0x0e,0x30,0x74,0x0b,0xea,0x0f,0x49,0x55,0x3b,0xe7,0x42,0x48,0xca,0x82,0x3e,0x8c,0xbc,0xe2,0x88,0x43,0x44,0x0d,0x37,0x9b,0xd1,0xfc,0xf1,0x45,0x46,0x0e,0xe1 +.byte 0xec,0x91,0x39,0x96,0x7d,0xbc,0xd5,0xb1,0x11,0x55,0x54,0x49,0x4f,0x18,0xed,0xec,0x58,0xdb,0xb3,0x7d,0x64,0x8d,0xfc,0x65,0x1f,0xf0,0xe0,0xc0,0x41,0xc0,0x19,0xeb,0x16,0x16,0x71,0x36,0x88,0xcf,0x75,0x3d,0x9c,0xe6,0xa0,0x84,0x54,0x26,0x64,0x95,0x9a,0xe1,0x0b,0x51,0xcf,0x9a,0x55,0x60,0x4d,0x9d,0x1d,0x37,0x71,0xa8,0x94,0x0a +.byte 0x20,0xeb,0xf2,0x91,0x14,0xfc,0x12,0xb0,0x1e,0xe3,0x5e,0x3a,0xbb,0x22,0xde,0x20,0xb1,0x58,0xef,0x0b,0xb1,0xc2,0x2f,0xea,0xd8,0xdb,0x1d,0x3a,0x67,0x7b,0xbd,0x26,0xfa,0x4a,0x3c,0x3d,0xbd,0x87,0x4c,0xba,0x57,0xdf,0xfb,0x1d,0xf7,0x26,0x5f,0x52,0x4e,0xdd,0x9b,0x38,0x62,0xed,0x48,0xc1,0xae,0x7f,0xa8,0x13,0x05,0x09,0xff,0xc0 +.byte 0xd3,0x49,0x75,0x1f,0x6a,0xe0,0x79,0x94,0xc1,0xe9,0xe3,0xf5,0x33,0x40,0xd4,0x6b,0xfe,0x4d,0x6e,0x84,0xb9,0x20,0x68,0x2b,0x6c,0xb3,0xf1,0xb1,0x1c,0xfd,0x93,0x14,0x7f,0x35,0x9b,0xd5,0x07,0x15,0x87,0x56,0xb9,0x45,0x22,0x64,0x73,0xdb,0x34,0x35,0xca,0x15,0x4e,0xa2,0xa2,0xe2,0x7a,0x6e,0x14,0x46,0xf5,0xf1,0x70,0xd3,0x3a,0x2e +.byte 0x38,0x9d,0xf6,0xc6,0x29,0xd5,0x7f,0xc7,0x77,0x2c,0x33,0x55,0x1c,0xc2,0xf1,0xaf,0x8e,0x4d,0x1b,0x22,0x36,0x35,0x93,0x47,0xa5,0x59,0xb4,0x94,0x0f,0x2d,0x66,0x24,0x6f,0x57,0xa4,0x95,0xf3,0xd7,0xf3,0x59,0x9d,0xc0,0xda,0xa7,0xf7,0xf2,0x8d,0x93,0xc9,0x90,0x91,0x9e,0x12,0x3f,0x34,0x01,0x90,0x8b,0x13,0x09,0x3d,0x2f,0xa8,0x31 +.byte 0xfa,0x39,0x4a,0x7d,0x0d,0x34,0xa3,0xf1,0x75,0xdb,0xa2,0xd2,0x5c,0xf1,0x72,0xfd,0x7f,0x7b,0x15,0x92,0xf0,0x71,0xd6,0xa0,0x74,0x53,0x61,0x67,0xa4,0x8b,0x72,0x3a,0x66,0x0a,0xce,0xc9,0x1c,0x5b,0x4d,0xaa,0x0a,0x3a,0x91,0x0a,0xbb,0xef,0x6e,0x8d,0x00,0xc0,0xa1,0x89,0xa9,0xbd,0x5a,0x2d,0xf8,0x7c,0x1f,0xb2,0x5a,0x73,0x33,0xe7 +.byte 0xb3,0xfd,0xd4,0xe3,0x81,0x69,0x30,0xc1,0xf8,0x97,0x7b,0xf3,0x63,0xaa,0xd5,0x5a,0x98,0x95,0xb3,0x65,0x2d,0xf9,0x68,0x2e,0x2c,0x26,0xe6,0x77,0x8f,0x76,0x7a,0x02,0xc7,0x50,0x28,0x40,0xcf,0x44,0x66,0x18,0x54,0x52,0xef,0x79,0x26,0xc2,0x76,0x5b,0x71,0x92,0x49,0xba,0xe1,0xd7,0xf2,0xdd,0x57,0xe0,0x78,0x6e,0xb6,0xdd,0x0d,0x20 +.byte 0x85,0xf9,0x34,0x9e,0x65,0x6b,0x9f,0x41,0x24,0xe2,0xb1,0x2a,0xef,0x8b,0xd2,0x19,0x81,0x73,0x56,0x5a,0x84,0xd3,0x46,0xf8,0x74,0xe3,0x1f,0x3d,0xd9,0x16,0x86,0x38,0xf6,0x7c,0x04,0xab,0x9a,0x64,0x0e,0x48,0x06,0x4c,0x61,0xcd,0x2d,0x4d,0xef,0x6f,0xd6,0x7d,0x31,0x1c,0x56,0x65,0xc4,0xf1,0xa7,0x15,0xac,0xa4,0xe2,0x8b,0x83,0x5e +.byte 0x64,0x36,0x2e,0x77,0x94,0x2e,0x2e,0xa3,0x62,0xcf,0x6e,0x7a,0x6d,0x39,0xaf,0xf7,0x96,0x88,0x31,0x14,0x58,0x46,0x30,0x0c,0x36,0x3a,0x4c,0x53,0xe0,0xa7,0x24,0x76,0x84,0x0f,0xfb,0x7e,0x55,0xa0,0x0f,0x63,0xfc,0xd6,0x1f,0x58,0x68,0xb5,0xcc,0x77,0x4f,0x16,0x91,0xa7,0xfd,0x62,0xb3,0x88,0x13,0x7c,0xcb,0x63,0x6d,0xe4,0x38,0x4c +.byte 0x6e,0x3b,0xf7,0xe3,0x8d,0x52,0x84,0x61,0x19,0x12,0x51,0xbe,0xed,0x32,0x3d,0x77,0xdd,0xa1,0xc3,0x59,0x65,0x79,0xa1,0x6b,0xbc,0x65,0x6c,0xe3,0x7e,0x60,0x49,0xbd,0xcf,0x6f,0x61,0x97,0x98,0xbe,0x74,0x38,0xd1,0x09,0xc1,0x59,0xe5,0x7f,0xfe,0xbf,0xfd,0x60,0x1b,0x96,0x00,0x46,0x56,0x4d,0x81,0x4c,0x70,0x59,0x39,0x66,0x13,0x58 +.byte 0xe7,0x62,0x3a,0xfc,0x1b,0xe5,0xf9,0x03,0xd4,0x4b,0xab,0x1d,0x56,0x22,0x4a,0x09,0xa5,0xdd,0xac,0x39,0xbe,0x27,0x39,0xb3,0xe8,0xad,0xe0,0x07,0x86,0x10,0xce,0xa9,0x4e,0x8b,0x47,0x8d,0xb8,0x63,0x2f,0x61,0x1a,0x8b,0xd4,0xd3,0xfe,0x73,0x82,0x5a,0xd6,0xa9,0x46,0x56,0xa7,0x81,0xe9,0xda,0xb9,0x17,0xa7,0xc8,0x0f,0x24,0x16,0x6a +.byte 0x12,0xfe,0xc3,0x65,0x85,0x77,0xab,0x89,0x44,0x1b,0xa3,0x8b,0xfd,0x07,0xf4,0x77,0xaa,0xe1,0x71,0x33,0x74,0x93,0xdc,0x90,0x53,0x39,0x47,0x8c,0xea,0x18,0xe1,0x6a,0xed,0x8c,0x56,0x08,0x2f,0xa1,0x1f,0x22,0xf2,0xc0,0x12,0xcd,0xb7,0xdf,0xb6,0x3c,0xd6,0x22,0x6c,0x5b,0x00,0x0f,0xdb,0x66,0x5b,0x54,0x35,0x48,0x37,0x8c,0x79,0x74 +.byte 0xd1,0xb0,0x15,0x01,0x22,0x3a,0x7c,0x17,0x8c,0x20,0x06,0x9b,0x13,0x6e,0xee,0xbf,0xb4,0xac,0x01,0x61,0xb9,0x28,0x65,0x8e,0x53,0x12,0x4f,0xe0,0x5f,0xfc,0xdb,0x40,0x6c,0xa2,0x19,0x64,0x49,0x7a,0xc7,0xc5,0xc8,0x53,0x6e,0xd5,0x68,0xe1,0x61,0xe5,0x87,0xc2,0x99,0x59,0x4c,0x27,0xc8,0xd0,0xd0,0x10,0xce,0x9f,0x09,0xff,0xf5,0xa8 +.byte 0xf8,0x79,0xf6,0x0f,0x73,0xda,0x8a,0x36,0x8e,0x48,0x7e,0xbd,0x98,0x76,0x57,0xfa,0x5c,0xec,0xa5,0x3d,0x30,0xfe,0xa3,0xe5,0x27,0x87,0xcf,0x26,0xfe,0x61,0xe4,0xed,0xd1,0xfb,0xfc,0x91,0x5d,0xb6,0x70,0x2c,0x2c,0x59,0x14,0xd5,0x1d,0x9a,0xb9,0x2c,0xef,0x24,0x7b,0x10,0x8d,0x99,0x63,0xaa,0x82,0xf0,0x1c,0xe8,0xa0,0x00,0xa5,0xa7 +.byte 0xf8,0xc0,0x35,0x9e,0x12,0x18,0xaf,0x42,0x9d,0xe5,0x2b,0x72,0x6c,0x31,0xd8,0x8f,0x6c,0xde,0x2e,0x37,0xa6,0x73,0x06,0xe7,0x90,0x43,0x79,0x99,0x64,0xd1,0x17,0xa1,0x43,0x6d,0xd4,0x90,0x50,0xf2,0xcc,0x0b,0x73,0x49,0x9e,0x14,0x7c,0x49,0x92,0x05,0x0e,0x8c,0xda,0xb7,0x18,0xf0,0xcc,0xea,0xe4,0x32,0x58,0xc7,0xbd,0x8e,0xca,0x35 +.byte 0x52,0x9f,0xec,0x5d,0xa0,0x6c,0x83,0x61,0x07,0x74,0x37,0x4a,0x10,0xa0,0x98,0x83,0x3a,0x65,0x17,0x63,0xd0,0x22,0x96,0xb5,0xed,0xbb,0xbb,0x1c,0x18,0x8a,0x49,0x3d,0x0f,0xcc,0x24,0xb3,0x9b,0xb6,0x23,0x2e,0x9d,0x97,0xe7,0x31,0xf8,0x36,0x6d,0x7b,0xa1,0xf1,0x02,0xde,0x7c,0xad,0x77,0x5d,0x85,0x7c,0x39,0x61,0xc7,0xd7,0x3f,0x70 +.byte 0x1c,0xe1,0x0e,0x49,0xf4,0xcd,0xab,0xfd,0x4d,0x2f,0xc7,0xb7,0x53,0xfc,0xed,0xeb,0x41,0x2a,0x80,0x40,0xf3,0x47,0xf8,0x15,0xa0,0x4c,0x8b,0x34,0xf6,0x6a,0xb8,0x30,0x09,0x4d,0xe6,0x60,0xb7,0x24,0x6b,0x4c,0x26,0xdf,0x83,0x37,0xc7,0x96,0xba,0x35,0xda,0x29,0x4e,0xca,0x52,0xf7,0x41,0xd3,0x98,0x27,0xb2,0x9e,0xec,0xcc,0x12,0xdc +.byte 0x77,0xfd,0x11,0xbd,0xbd,0xbb,0x5e,0x0c,0x37,0x29,0xd2,0x4f,0x7d,0x5c,0x97,0xad,0x72,0x93,0x4a,0xfa,0x17,0x07,0x07,0x26,0xee,0xa7,0x29,0x2e,0xdb,0xf6,0x60,0x65,0x2d,0x85,0xbe,0x27,0x4d,0xf7,0x2b,0xb4,0x81,0xf5,0x3a,0x1d,0xae,0x25,0x8b,0x60,0xc2,0x75,0x3a,0xfd,0xf9,0x4d,0x90,0x7a,0x8a,0x3a,0xf6,0xa9,0xf0,0x11,0xd2,0xb9 +.byte 0xdb,0x23,0x40,0x9d,0x33,0xc3,0xbf,0x60,0x95,0x9c,0x6f,0xa9,0x82,0x42,0xe5,0x67,0x52,0x36,0xea,0x68,0x64,0x24,0x85,0x46,0x7e,0x2a,0x1a,0x6a,0x4b,0xa8,0xb0,0xa0,0x9c,0xb8,0x4a,0xb6,0x2e,0xb2,0x6b,0xf4,0x63,0x9f,0x54,0xb5,0x6f,0x1b,0xf5,0x71,0x7e,0xf8,0xef,0xb2,0x92,0xe2,0xcf,0x65,0xb4,0x02,0x9b,0x75,0x4b,0xf9,0x6b,0xa1 +.byte 0x24,0x3b,0xea,0x7f,0x31,0x08,0xd4,0xdc,0xab,0x12,0xc0,0xca,0x64,0xee,0xfa,0x61,0x1c,0x0f,0x24,0xc3,0x8c,0xbd,0xc8,0xd2,0x42,0xf7,0x1f,0x2e,0xd3,0xd1,0x51,0x86,0xfb,0xa2,0x95,0xc5,0x8c,0x5b,0x61,0x14,0xc9,0xe4,0x07,0xa1,0xf7,0x39,0x11,0x40,0x68,0xd6,0xe2,0x38,0x96,0x6f,0x99,0xf1,0xd2,0xfb,0x8e,0xb8,0x3d,0xf2,0x8a,0x4e +.byte 0x3e,0x54,0xd9,0x0e,0xd1,0xc9,0x31,0x04,0xa4,0xee,0xbe,0x51,0xcf,0x5f,0xd1,0xc8,0x13,0x96,0x9d,0x9b,0xdf,0x32,0xa9,0x38,0x8f,0xbc,0x7e,0x22,0x1a,0x52,0x5f,0x14,0x61,0xeb,0x78,0xf4,0x01,0xe9,0x5c,0x18,0x1c,0xb5,0xe1,0x80,0x06,0x3e,0x8e,0x72,0x33,0xf9,0xaa,0x49,0xec,0x5b,0x7a,0x04,0xf2,0x9b,0x48,0x8a,0x58,0x14,0x4b,0x7e +.byte 0x4d,0x26,0x0b,0xe0,0xf0,0x69,0xa3,0x36,0x75,0x3e,0x73,0xec,0x53,0x20,0x35,0x8e,0xfa,0x40,0xf0,0xcd,0x70,0xe1,0xe4,0x64,0x89,0x14,0x55,0xd7,0x20,0xe8,0xbd,0xc2,0x85,0xa8,0x4d,0x51,0x96,0x27,0x54,0x50,0xc7,0xa1,0x9c,0x35,0x52,0x1f,0x8b,0x6f,0xa2,0x62,0x36,0x94,0x02,0xb1,0x01,0xc6,0x4e,0x53,0x83,0x65,0x98,0x25,0x6d,0x26 +.byte 0x6d,0xef,0x4e,0x7a,0xe0,0x56,0x6a,0x6c,0x23,0xe8,0xa6,0x97,0xc1,0xf2,0xb1,0x2d,0x03,0x29,0xef,0xa0,0x6d,0x86,0x8d,0x5a,0x00,0x83,0x14,0xed,0xd4,0x1e,0x79,0xc4,0xb4,0x42,0xfd,0x53,0xaa,0xab,0xd7,0xa3,0xf9,0x7d,0x15,0x26,0xab,0x81,0xc4,0x7a,0x96,0x14,0x94,0x71,0xe1,0x7f,0xc1,0x67,0x5f,0x5f,0x11,0xb4,0x72,0x03,0xf8,0x9b +.byte 0x2f,0x82,0xa3,0x4e,0xda,0xfd,0x2a,0x31,0xf1,0x74,0x6d,0x96,0x7a,0x9c,0xf9,0x01,0xd9,0x55,0x8e,0x52,0xe4,0xae,0x22,0x14,0x7b,0xc0,0x5a,0xc4,0x31,0x23,0x9a,0x2e,0x9d,0x86,0x86,0xd5,0x66,0xc8,0x8b,0xdb,0x49,0x5f,0xca,0x57,0x51,0x50,0x75,0x3f,0xeb,0xb1,0xe5,0x84,0x42,0x8f,0x0f,0xca,0x86,0xcf,0xb0,0x17,0x06,0x06,0x46,0x8c +.byte 0x4a,0x84,0xde,0x28,0x84,0x24,0x7f,0x33,0x48,0xe8,0x89,0x87,0x1f,0x02,0x07,0x4f,0x36,0xa9,0xdc,0x8a,0x42,0xb6,0xc7,0x9c,0x47,0xd4,0xd4,0x2d,0xc0,0x17,0xb0,0xe6,0x23,0xb7,0xae,0x0d,0x9f,0x38,0x0a,0xdf,0x7f,0x73,0xbf,0x93,0x19,0x05,0x23,0xbf,0xc0,0x53,0x2d,0xcd,0x3e,0x73,0x01,0x78,0xa7,0xdc,0x6c,0x85,0x1d,0x25,0xc5,0x54 +.byte 0x68,0x95,0xc1,0x20,0x65,0xd9,0x01,0x85,0x7d,0xc9,0xba,0x63,0x43,0x7a,0x23,0xbb,0x95,0x3a,0x76,0x2d,0x75,0x1e,0xac,0x66,0x3e,0x20,0x30,0x8d,0x37,0x64,0x3c,0xc7,0x6f,0x36,0xb8,0x34,0x60,0xd2,0xb4,0x54,0x07,0x52,0x6c,0xfa,0x04,0xfe,0x2b,0x71,0x03,0x03,0x97,0xfc,0x4a,0xf9,0x4d,0x44,0x1a,0xf9,0xd7,0x4b,0xe5,0xe1,0xf9,0xb9 +.byte 0x41,0xa0,0x5b,0xa2,0x69,0x48,0xba,0xeb,0xcc,0x4e,0x55,0x4b,0xbd,0x41,0x09,0xa8,0x90,0x5c,0xc6,0xe3,0x20,0x0c,0x8f,0xfc,0x7e,0x0e,0x4f,0x3d,0x47,0x65,0x40,0x1e,0x79,0x9a,0xe0,0x8f,0x8f,0xe9,0xcb,0xaa,0x04,0xb8,0xd9,0x91,0x30,0x2a,0x4c,0x17,0x44,0xc0,0x03,0x4c,0x37,0xd3,0xdb,0x20,0xe5,0x8e,0x70,0x87,0x57,0x4f,0x8a,0xcf +.byte 0xee,0x64,0xbc,0xef,0x0f,0x9e,0xcf,0x95,0x5e,0x11,0x4f,0x7a,0x35,0x53,0x8c,0x85,0x6a,0xff,0x72,0x1b,0x35,0x51,0x89,0xf8,0x94,0x65,0x97,0xec,0xfe,0xbd,0x00,0x29,0x3d,0xe8,0x96,0x23,0xa4,0xe3,0xcf,0x81,0xb2,0x8f,0x73,0x4c,0x05,0xc3,0xcc,0x37,0x22,0x97,0xa0,0xda,0x49,0xb2,0xbd,0x07,0x2b,0x26,0xa0,0x6f,0x6b,0x1f,0xa6,0x15 +.byte 0xe3,0x6e,0x12,0xa4,0x51,0x1b,0x72,0x22,0x08,0xfe,0xf7,0x93,0x1a,0x9f,0x62,0x12,0xd4,0x11,0x1f,0xd1,0x80,0xeb,0xa4,0xb1,0xf4,0x37,0x3b,0x60,0xd8,0x2b,0x53,0xae,0x69,0xf8,0x48,0x38,0xf4,0x20,0x28,0xe1,0xfb,0x6a,0xec,0x6e,0x11,0x2e,0x2c,0x59,0x62,0x23,0x8a,0x82,0xc4,0x33,0x7b,0xdc,0x33,0x99,0x41,0x29,0x4f,0xa1,0x6e,0x3a +.byte 0x48,0x13,0x1c,0x1f,0xa3,0x1f,0xd2,0x02,0x79,0xe1,0xe4,0xb9,0x99,0xa4,0x50,0xea,0x53,0x96,0x4e,0x82,0x7c,0xee,0x65,0x07,0x26,0x87,0xf9,0x9d,0x45,0x17,0x37,0x61,0x7e,0x5f,0xb9,0xd2,0x55,0x3c,0x45,0xf7,0xec,0x33,0x08,0xa3,0x41,0x24,0x8f,0xb2,0x75,0x41,0xb6,0xa2,0x21,0xfe,0x94,0x7e,0x1e,0xe6,0x03,0x6e,0xf4,0xeb,0x23,0x59 +.byte 0x51,0x25,0x99,0x19,0x6d,0xf7,0xe3,0x22,0xd8,0x41,0x0f,0xd5,0xaf,0x0d,0xc6,0x3f,0x8e,0x36,0xee,0x90,0x23,0x67,0x03,0xcb,0xe3,0xaf,0xc4,0xf8,0x22,0x1f,0xd8,0x3e,0x94,0xdf,0x13,0xc9,0x4f,0x17,0x22,0x8c,0x93,0x6b,0x3f,0x60,0x1a,0xbd,0xfa,0x9f,0xe6,0x43,0x45,0xe1,0x0a,0x95,0x21,0x06,0x52,0xbd,0x58,0x56,0x84,0x56,0x36,0xf3 +.byte 0x55,0x58,0x46,0x62,0x6c,0xb3,0xa0,0x29,0x5a,0xfc,0xb4,0x87,0x5f,0x89,0xa5,0xab,0x6d,0x5a,0x44,0xc5,0xc8,0x50,0x83,0xe1,0x41,0xd4,0x97,0x6c,0x08,0xb1,0x43,0x33,0x0d,0x3a,0x8b,0x31,0xa1,0xae,0x77,0x71,0xb7,0x67,0x65,0xd7,0xa7,0xc9,0x6c,0x4a,0x9b,0x80,0xd5,0xbf,0xae,0x0f,0x9b,0xce,0x1a,0xa3,0x26,0xc6,0x19,0xa1,0x8d,0x12 +.byte 0xd9,0x09,0xae,0xac,0x9f,0x4b,0xab,0xaf,0xf6,0xc5,0x9e,0x26,0xe6,0x23,0xcb,0x3e,0x60,0x1e,0x3d,0xa1,0xec,0x59,0xca,0xf1,0x87,0x0e,0xaf,0x47,0x5f,0xab,0x17,0x99,0xbd,0x87,0x1c,0x1d,0x00,0xd6,0xb2,0x59,0x56,0xdd,0x49,0x20,0xb5,0x91,0xf8,0x0c,0xf1,0x80,0xc6,0x37,0x92,0xd7,0x2c,0x02,0x0d,0x47,0x1b,0x1b,0x6b,0x3f,0x60,0xd0 +.byte 0x21,0x9b,0x49,0x47,0x3c,0xaa,0x83,0x44,0x1b,0x92,0x8e,0xec,0x63,0x40,0xd6,0x9a,0x48,0x7c,0x5e,0x97,0xe4,0xf0,0x84,0x36,0x30,0x11,0x0b,0x7c,0x79,0x3b,0xff,0xdf,0x77,0xf6,0xc9,0xdb,0x49,0xdd,0x2a,0xe7,0xca,0x9a,0x5b,0xef,0xd4,0x84,0xe2,0x44,0x8b,0xef,0x4e,0x0d,0x13,0xd6,0xbb,0xba,0x29,0x02,0xae,0xfc,0x55,0x24,0xfa,0x4b +.byte 0x7d,0x71,0xc9,0xde,0x71,0x36,0xbc,0xac,0x31,0x5c,0xf8,0x20,0xdd,0xb8,0xae,0x03,0xd3,0xb0,0xdc,0x27,0x7f,0xc5,0xff,0xda,0x8a,0x36,0x2d,0x8f,0xae,0xbd,0xf8,0x92,0x28,0x8e,0x0c,0xc3,0xaf,0x4e,0x33,0xf0,0x71,0xdb,0xad,0x4d,0xc1,0xef,0x52,0x1c,0x84,0xdc,0x0d,0xf3,0xab,0xb9,0x0b,0xe0,0x18,0xa5,0x06,0xdc,0x78,0x41,0x73,0x35 +.byte 0x95,0x37,0x84,0xba,0xc1,0x4e,0x0a,0xe4,0x4d,0x05,0xfe,0x9d,0x74,0x68,0x4a,0x35,0xf0,0x15,0xaa,0x7b,0xfe,0x08,0x47,0xb2,0x84,0x65,0x1d,0x0d,0x9f,0xe7,0xe0,0x04,0xf9,0x1c,0xac,0x66,0xb3,0x75,0x96,0x8f,0x25,0xb6,0x29,0x53,0x52,0x50,0x7a,0x50,0xd1,0x89,0xc7,0x05,0xfb,0x3a,0xb0,0xfa,0x6b,0x96,0x9d,0xfc,0xb0,0xcd,0x68,0x21 +.byte 0x61,0xf6,0x65,0x64,0xa7,0xc6,0x56,0xbd,0xf0,0x9b,0x4a,0x9a,0xe2,0x8c,0xd8,0x88,0x70,0x82,0x0c,0x87,0x51,0x77,0x23,0xd8,0xd8,0xf8,0x4a,0xfe,0xf4,0x6d,0x3f,0x2a,0x36,0x0c,0x67,0x85,0x43,0x13,0x83,0xd5,0xe9,0x32,0xff,0x8c,0xec,0xd4,0x7f,0xd2,0x32,0x4d,0x4e,0xec,0x76,0x55,0xf9,0x0d,0xb7,0x57,0x6c,0xc4,0xd6,0x22,0xd3,0x6e +.byte 0x71,0x23,0x68,0x45,0x03,0x37,0x27,0x3d,0x56,0x89,0xbb,0x7c,0xf1,0xa8,0x09,0xd6,0xb2,0xc5,0xe6,0xf6,0x72,0x77,0x3e,0xb0,0x8a,0x3d,0x17,0xbd,0xd5,0x0d,0xdb,0x62,0xa7,0x07,0x66,0x35,0x19,0x12,0xff,0xcf,0xdd,0xb3,0x09,0xa3,0x58,0x5b,0x0d,0x87,0x76,0x33,0x28,0x98,0x91,0x48,0xac,0xa1,0x22,0x9f,0xda,0x36,0x03,0x8a,0xc1,0x5e +.byte 0x6c,0x2e,0x42,0x8e,0x1a,0x7d,0x75,0x69,0xb2,0xcf,0xb0,0x14,0x80,0xa8,0x91,0xc2,0xbc,0x24,0x8f,0x25,0x9a,0x9e,0xa3,0x4d,0x46,0x55,0x53,0x05,0x0c,0xf8,0xdb,0xe0,0xee,0xe4,0x32,0xff,0x39,0x74,0x9a,0xa8,0xf7,0xa4,0x6e,0x5b,0x9a,0x89,0x33,0x40,0xf4,0xce,0x54,0x4a,0x18,0xdb,0x11,0xe4,0x83,0x69,0x52,0xef,0x12,0xc6,0x13,0x6e +.byte 0x2a,0x14,0xb9,0x8e,0x38,0x8d,0x6b,0xef,0x02,0xc8,0x66,0xf0,0x78,0xaa,0xa6,0x04,0xa3,0xa5,0x1d,0xdb,0xac,0x02,0x23,0x4c,0x2a,0xa5,0xbf,0x66,0xa4,0x47,0xa9,0x8e,0x50,0xd2,0xf8,0xf5,0x0d,0x0f,0xc9,0x07,0xd8,0x1a,0x94,0x84,0xcf,0xb3,0x56,0x53,0x5f,0x83,0x1d,0x30,0xb6,0x94,0x36,0xf4,0x16,0x72,0x8c,0x6d,0x49,0xe4,0x6d,0x93 +.byte 0xb1,0xa1,0x97,0x70,0x75,0x47,0x3a,0x7e,0xa6,0x39,0x1d,0xf5,0xcc,0x37,0xaa,0x90,0x53,0xe1,0x9b,0xcb,0x9a,0x97,0x7d,0x18,0x4a,0x3c,0x1f,0x05,0xf4,0xe3,0x6f,0x7a,0x19,0x84,0xbc,0x68,0xa4,0x6e,0x5a,0xb5,0x7a,0x51,0xda,0xf5,0x75,0x1e,0xfe,0xb0,0x73,0x43,0x39,0x98,0xb7,0x1e,0x17,0x36,0x35,0x15,0x64,0x90,0xb6,0x83,0x43,0x8f +.byte 0xcd,0xb6,0x8c,0xc4,0xe4,0xee,0x0e,0x1c,0xbd,0x3a,0xe6,0x6e,0x44,0x73,0x88,0x30,0xa0,0xf0,0x97,0xf5,0x5e,0x12,0xea,0xd9,0xd7,0xb5,0xc5,0x1d,0xc7,0xc8,0x55,0xbb,0x2c,0x64,0x43,0x50,0x15,0x71,0x02,0xd3,0xf9,0xb4,0xe7,0x2f,0x0f,0x98,0x9e,0x87,0x40,0x2a,0x61,0x06,0x44,0xc2,0x47,0xaf,0x44,0x4f,0xdd,0xa3,0xb0,0xb2,0x8d,0x8c +.byte 0x83,0x96,0xd3,0x2a,0x38,0xdf,0x87,0x5d,0x1c,0x64,0xc8,0x4f,0x3c,0x41,0xc7,0xf8,0x64,0x58,0xa6,0x9b,0xcb,0xcd,0x77,0xdb,0x38,0xe7,0x30,0xb6,0x91,0x88,0xd8,0x9d,0x29,0x71,0x12,0x9e,0xdf,0x20,0xd9,0x14,0xa3,0xa0,0xbd,0x0a,0x99,0x67,0x0a,0xe1,0xe9,0xba,0xd0,0x1b,0xba,0xc8,0x8d,0x76,0x10,0xe8,0x30,0xa1,0x93,0xf4,0x95,0x6a +.byte 0x12,0xd5,0x95,0x31,0x7f,0xdb,0x33,0xfc,0xbf,0x7a,0xbe,0xe4,0xfa,0x50,0x1b,0x24,0x75,0x9b,0xf8,0x81,0x34,0xc8,0xfb,0xda,0x3c,0x6f,0x3b,0x9a,0xb2,0x6f,0x94,0x0c,0xd9,0xc3,0x05,0xd6,0x96,0x10,0x27,0xdb,0xd6,0x88,0x72,0xe4,0x8f,0xfc,0xd3,0x52,0xf8,0x63,0xb2,0xce,0xf1,0x2a,0xbc,0x1c,0x23,0x9d,0xfb,0x27,0xdd,0x8d,0xe4,0xcc +.byte 0x63,0xcf,0xad,0xe6,0xe9,0x4f,0xb8,0x8a,0x20,0x47,0x75,0x73,0x3f,0x27,0x07,0x5d,0x8c,0x8c,0x6e,0x7a,0x91,0xe2,0xf6,0xd5,0x70,0xd8,0x00,0xe5,0x0f,0xde,0x78,0xd8,0xb4,0xd3,0x18,0x5a,0x24,0x43,0x91,0x0c,0xbe,0x8b,0x1b,0x88,0x48,0x7e,0x94,0x05,0xd0,0xec,0xd2,0x71,0x26,0xc7,0x70,0xeb,0x8a,0x83,0x01,0x52,0xdb,0xe5,0x76,0x31 +.byte 0x19,0x14,0x13,0x90,0x5b,0x5a,0x94,0x89,0xe2,0x4e,0x2d,0x17,0xf6,0xbc,0x67,0xee,0x51,0xd4,0x00,0x83,0xe5,0x18,0xa5,0x54,0x6c,0xd2,0x7a,0x1f,0xdb,0x6f,0xed,0x7f,0x07,0xbb,0x9f,0x3a,0xc2,0x8c,0x04,0xf9,0x9a,0x55,0xe3,0x70,0xf3,0x36,0xfd,0x44,0x05,0xd9,0xf3,0xe1,0x87,0x2c,0x29,0xec,0x30,0x8b,0xb7,0xde,0x27,0xa4,0xcd,0xdf +.byte 0x64,0x0b,0x62,0xdf,0x34,0xa0,0xf5,0xa1,0x69,0xc9,0x0b,0x00,0x81,0xf4,0x03,0x5e,0xef,0xb8,0x26,0x49,0x71,0x5e,0xcd,0x76,0xa2,0x38,0x25,0x1f,0x92,0xc3,0xbf,0xdb,0xb3,0x29,0x37,0x06,0xc5,0xc2,0x3b,0xd8,0xbd,0x55,0xf2,0x7f,0xd5,0xd5,0x34,0x32,0xf1,0xa0,0x92,0x9b,0x1c,0xee,0x6f,0x48,0x40,0x6b,0xd1,0x45,0x09,0x3f,0xaf,0xdc +.byte 0xe1,0xac,0x75,0x9a,0x33,0xf7,0x50,0x4f,0x2c,0x3c,0x30,0x69,0x69,0x84,0xcb,0xe9,0xca,0xdf,0x8d,0x02,0x5d,0x30,0x71,0x99,0x7b,0xd5,0xb2,0x55,0xdd,0x9c,0x2f,0xae,0x11,0x41,0x01,0x6b,0xf7,0x95,0xe3,0xda,0xe3,0xcc,0xa4,0x17,0xd0,0x50,0xf9,0x4c,0x31,0x2b,0x4e,0xf7,0x49,0xbb,0x75,0x8f,0x28,0x19,0x9f,0x89,0x7b,0x78,0x80,0x41 +.byte 0x50,0x5a,0x5c,0x1e,0x82,0x93,0x9f,0x4f,0x61,0x96,0x29,0x0c,0x25,0xb3,0xe6,0xff,0x86,0x90,0x78,0x09,0x04,0xf9,0x2a,0x3d,0xa1,0xd5,0x68,0xa8,0x0d,0xd9,0x41,0x01,0xdc,0x41,0x01,0xff,0x20,0xc0,0x63,0x0b,0x4d,0xd5,0x80,0x78,0x82,0x05,0x51,0x62,0x09,0xf9,0x11,0xbd,0xde,0xc0,0x7d,0x3f,0xf2,0x30,0xfb,0x41,0x68,0x39,0xb0,0xc2 +.byte 0x2e,0x33,0x4e,0xa7,0x85,0x01,0x6b,0xd1,0xf9,0x78,0xef,0xe9,0x7c,0x0e,0xaf,0x13,0x1a,0xf5,0x97,0xde,0xf0,0xbb,0x67,0xf9,0x9b,0xab,0xee,0x86,0x73,0x9b,0x23,0x6c,0x56,0x0d,0xa0,0xda,0x4c,0xff,0x2b,0xc5,0x92,0xdb,0xee,0xbd,0xba,0x3a,0x54,0x21,0xc0,0x5c,0xfe,0x21,0xf1,0xbd,0xac,0xaf,0xa3,0x7a,0x52,0x62,0x15,0x8b,0x8f,0xb5 +.byte 0x82,0xc6,0x1a,0xfb,0x22,0xbc,0xa2,0x05,0x42,0xfe,0xb4,0x12,0x6b,0xad,0xa9,0x76,0xb7,0x6b,0x1c,0xd8,0x34,0x5c,0x7d,0xd5,0xa9,0x0d,0x91,0xf6,0xc1,0x47,0x69,0xbc,0x43,0x8f,0xb7,0xfc,0x84,0x2e,0xa0,0x8e,0x3f,0x52,0x3b,0xbd,0x1f,0x28,0x6b,0xc8,0x13,0x37,0xd6,0x44,0xe9,0x8d,0x08,0x92,0x96,0xe5,0x2c,0x57,0x34,0x59,0x21,0x04 +.byte 0xa8,0xaa,0x56,0x25,0xa4,0xc8,0xae,0x68,0x17,0x9e,0xa4,0xf4,0x42,0x64,0x57,0x4b,0x54,0x85,0x8a,0xd1,0x09,0x09,0x25,0x18,0x05,0xb0,0x09,0x9d,0xd9,0x75,0x21,0xd3,0x75,0x31,0xf8,0x35,0x46,0xc8,0xd4,0x47,0x9d,0x87,0xeb,0x40,0x95,0x19,0x24,0x7c,0x6e,0xe9,0xd5,0x14,0xaa,0xc3,0xbe,0x22,0x18,0xc1,0xa0,0x5f,0x34,0x98,0xc2,0x4d +.byte 0x3f,0xa6,0x09,0x57,0x1b,0x75,0xc6,0x89,0xee,0xf0,0xbd,0xbc,0x1a,0xd3,0xea,0x6e,0x82,0x06,0x90,0x4f,0xbb,0x61,0xac,0xbb,0x3e,0x8c,0x94,0xea,0x69,0x58,0x26,0x2e,0x17,0x78,0xad,0x14,0xa4,0x79,0x14,0xbd,0xc1,0x78,0xf9,0xbb,0x11,0x7e,0x8d,0xbf,0x3e,0xc8,0xc5,0x69,0xd7,0x5a,0x4c,0x4b,0x86,0x25,0x4c,0xe9,0x3a,0xc2,0xd9,0xf8 +.byte 0xbf,0x5e,0x46,0x4f,0xca,0xba,0x25,0x58,0x73,0x82,0x02,0x8a,0x41,0x9e,0x2d,0xa9,0x08,0xb4,0x60,0x2a,0x11,0x2c,0x2f,0x3d,0x5e,0x68,0xd8,0xa9,0x2e,0x1c,0xfa,0xdc,0xda,0xfb,0xfb,0xf3,0xb2,0x66,0xd3,0x57,0xe6,0x09,0xeb,0xe5,0xf4,0xed,0x2d,0xb7,0x3a,0xce,0x69,0x2d,0xb4,0x79,0x1a,0x99,0x9d,0xc8,0x99,0x9f,0x9b,0x78,0xd4,0x8a +.byte 0x73,0xd5,0x89,0x9f,0xda,0xdf,0xd0,0xca,0x6b,0x63,0x5a,0x1e,0xe0,0x2f,0x01,0xa4,0xd0,0x62,0xc0,0x5f,0x4e,0xd9,0xd3,0x47,0xe4,0x68,0x73,0x8c,0x87,0x50,0x91,0xec,0x8e,0x0b,0xa7,0xf0,0x4c,0x32,0x19,0xaa,0x00,0xbd,0xe4,0x20,0xab,0x5c,0x00,0xdb,0x18,0xc0,0xff,0xc1,0xc0,0x8f,0xa2,0x8c,0x47,0x91,0x86,0xde,0xa9,0x09,0xb5,0x86 +.byte 0xcc,0x1d,0x7f,0x4b,0x7d,0x16,0xf6,0x21,0xd0,0xf8,0xaa,0x16,0x20,0xa9,0xac,0x3e,0xef,0x56,0xee,0x0e,0x1d,0xd6,0x44,0x7d,0xa9,0x84,0x41,0x8d,0x69,0x69,0x92,0x74,0x87,0x3b,0x8a,0xbf,0x40,0x29,0x45,0xf9,0xa8,0x52,0x8c,0x99,0x95,0xe7,0x6a,0xcd,0x3f,0x74,0x2d,0xde,0x82,0x47,0x41,0xa6,0xd9,0x5a,0x30,0x6c,0x20,0x98,0x3f,0xfb +.byte 0x66,0x08,0x73,0x68,0xe1,0xcd,0xfd,0x3c,0x4f,0x33,0x6b,0x42,0xa4,0xab,0x78,0x22,0xb5,0xd9,0x6f,0x99,0xcb,0x85,0x6a,0x14,0xb9,0xd3,0x0f,0xfb,0xd7,0x07,0x7b,0xbe,0x6a,0xd9,0xba,0xde,0x98,0xac,0xd8,0xe5,0x40,0xcd,0x59,0x7f,0x88,0x3c,0x4e,0xfa,0xfe,0xbe,0x48,0x21,0xb5,0x40,0xd5,0xc8,0x1e,0x8a,0x56,0xd9,0xec,0x25,0xad,0x5e +.byte 0x31,0xf3,0xf2,0x3d,0x0b,0x56,0xb5,0x20,0x08,0xd3,0x02,0x81,0x93,0x29,0x3d,0xbd,0x0a,0x9c,0x26,0x74,0xdb,0x6b,0x7e,0xd1,0x4a,0x1a,0x1c,0x47,0x49,0x34,0xba,0x08,0x7a,0x6a,0xb3,0xd6,0x3b,0xd0,0x28,0x50,0xa1,0xd8,0x17,0x85,0x61,0xab,0x24,0x22,0xda,0xc8,0xb4,0x1b,0x07,0x2e,0x67,0x77,0x84,0xdc,0x6f,0xfd,0x51,0xa5,0xe8,0x34 +.byte 0x63,0xbd,0xae,0xae,0xc7,0x84,0x1d,0x60,0xc8,0x8f,0xde,0x22,0xfd,0x85,0xb4,0x12,0xb4,0x04,0x5b,0xe7,0xb5,0x58,0xf8,0x56,0x66,0xa3,0xb7,0x1e,0x54,0xd0,0xdb,0x12,0xaa,0x9c,0x89,0x5b,0xfa,0xf4,0xe7,0xe2,0xf4,0x9c,0x08,0xa8,0xbe,0x6b,0xe3,0xce,0x6a,0x88,0xb5,0x74,0xb9,0x49,0xaa,0x7b,0xcd,0xbc,0x17,0x81,0x61,0xe2,0x28,0x6f +.byte 0x4b,0xe8,0xa4,0x55,0xc5,0x1e,0x69,0x21,0x8f,0xfd,0xa8,0xd0,0xb9,0x6f,0x1b,0xfe,0x8c,0x5e,0xf9,0x7d,0xd9,0xc2,0xbe,0x0f,0x6f,0xbd,0xa7,0x94,0x10,0x4e,0xe0,0x5a,0xbb,0xa3,0x40,0x9a,0x5a,0xad,0x10,0x97,0x92,0x3b,0xbd,0xa7,0x75,0x77,0xc6,0xa6,0xde,0x42,0x00,0x3b,0xf7,0xe4,0xf4,0xd7,0xdd,0xaa,0x31,0x1e,0x64,0xae,0x17,0x0a +.byte 0x25,0xa0,0x94,0x5f,0x3c,0xbc,0x3d,0x00,0x00,0xd3,0xba,0x7b,0x98,0x81,0xe1,0xdf,0xba,0x60,0x08,0x2a,0xe5,0x66,0x08,0x3e,0xfa,0x81,0x0a,0x89,0x4e,0xe5,0x3b,0xc3,0xdf,0x21,0x9b,0x54,0xa3,0xb3,0xc3,0xc1,0xce,0xb4,0xaa,0x06,0xee,0x2e,0x34,0x55,0xcc,0x8b,0x0f,0xcd,0x1d,0x1b,0xd9,0x9e,0x59,0xf0,0x93,0xc9,0xba,0x35,0x5c,0x99 +.byte 0xf6,0x86,0x9e,0xe9,0xf8,0x84,0x80,0x05,0x76,0x6f,0x8b,0x38,0xb6,0xe0,0xdf,0x0c,0xb3,0xc7,0x6e,0x62,0x53,0xe4,0x69,0x0a,0xc1,0xcf,0x5b,0x84,0x75,0x78,0x56,0x35,0xa5,0x26,0xc6,0xae,0x76,0x2e,0xc8,0x29,0x8d,0x16,0xd1,0x4f,0x27,0x36,0x22,0x41,0x31,0xfb,0xbe,0xd0,0xf9,0x0a,0x06,0xbf,0x59,0x6e,0x06,0x20,0x0d,0x52,0x66,0x63 +.byte 0x38,0x2a,0xb6,0x15,0x0f,0x51,0x14,0x0b,0xd1,0x63,0x40,0x2a,0xfe,0x88,0x51,0x53,0x5d,0x82,0x4e,0x1b,0x91,0x30,0x7a,0x09,0xec,0xb6,0x53,0x10,0x87,0xba,0x34,0x1f,0x8a,0xf7,0x85,0x31,0x77,0x76,0xba,0x55,0x07,0x6b,0x80,0x5d,0x14,0x23,0x50,0xef,0x07,0x91,0xc5,0x71,0x3a,0x55,0x44,0x9d,0xbf,0xe6,0xab,0xde,0x7c,0xdd,0xe0,0xcb +.byte 0xcc,0xc1,0x78,0xb4,0x8c,0xd1,0x35,0x73,0x80,0x9c,0x44,0xff,0xf8,0x8a,0xaa,0x9a,0x94,0xcf,0xc9,0x51,0xfc,0xa5,0x3d,0x86,0xd6,0x67,0x71,0x1b,0xdb,0x83,0xb2,0x67,0xb0,0x17,0xce,0x13,0x1b,0x7a,0x84,0xc8,0xaf,0x69,0x7e,0xf0,0xab,0xc5,0x8c,0x37,0x12,0x43,0x33,0x5f,0xaa,0xde,0xcf,0x4c,0x73,0x7f,0x6b,0x80,0x18,0x27,0x72,0x62 +.byte 0xe8,0x3d,0x1c,0x94,0x91,0xfa,0x33,0xef,0x13,0x94,0x7f,0xb6,0x53,0xe3,0xd7,0x73,0x05,0x3e,0xe8,0x45,0xde,0x1e,0x1d,0xa4,0x41,0x11,0x0a,0x7f,0x62,0x6e,0x9f,0x9f,0xec,0xe9,0x87,0xe0,0x5d,0xbb,0xbc,0x0b,0x37,0xa2,0xf3,0x68,0x8a,0x24,0xec,0x98,0xe5,0x5d,0xbf,0xa1,0x60,0x2b,0xc2,0x74,0x4b,0x8b,0x85,0x44,0x28,0x02,0xd5,0xb9 +.byte 0xae,0x00,0x37,0x1e,0x0b,0x46,0xe6,0x40,0xf1,0xdc,0xa0,0xfc,0xae,0x04,0x7f,0xb6,0x46,0xa3,0x22,0x79,0x92,0xda,0x89,0xa0,0x38,0xf0,0xa2,0x4a,0x76,0x79,0x0c,0x46,0x4d,0xa9,0xe6,0x75,0xff,0x01,0xb3,0xe4,0x13,0xc2,0x53,0xe9,0x6d,0x1f,0xdd,0x88,0xcf,0x10,0xf5,0x16,0xef,0x05,0x59,0x51,0x15,0x49,0x17,0xda,0xff,0x0e,0xb3,0xb9 +.byte 0xae,0x79,0xc6,0xb1,0x94,0x08,0x09,0x30,0x9f,0x2a,0xfd,0x55,0xc0,0x41,0x8c,0xe5,0x0e,0xee,0xc2,0xa0,0x05,0x36,0x66,0x8d,0x9a,0xcc,0xc9,0xeb,0x1d,0x34,0xc0,0x1a,0x29,0xc2,0xcd,0xb7,0x25,0xd3,0x83,0xf8,0x1e,0xa0,0xf4,0x50,0xd4,0x08,0x0d,0xcb,0x6a,0x2f,0xa5,0x8b,0x30,0x94,0x89,0xea,0x94,0x6c,0x00,0x7e,0x7f,0xb5,0x4d,0x61 +.byte 0xa7,0x9d,0x94,0xcc,0x14,0x8f,0x75,0x1f,0xef,0x2b,0xbe,0x37,0xdd,0x19,0x41,0x2e,0x90,0x36,0x27,0xa5,0xa9,0x6c,0x75,0x8c,0x2d,0xe3,0x97,0x74,0x91,0xf3,0xb8,0xcb,0xcb,0x74,0xba,0xf0,0x57,0x70,0x89,0xee,0x4d,0xc5,0xfe,0x3e,0x60,0xe3,0x5b,0x28,0x36,0x91,0x6f,0xcd,0x6c,0x33,0xb6,0x44,0x0c,0xce,0x81,0xe4,0xdb,0x84,0xbe,0x4e +.byte 0xef,0xb8,0x75,0xf7,0x8b,0xb0,0xb7,0x0d,0x00,0x13,0x54,0x39,0xfd,0x9e,0x86,0x5c,0x59,0xd0,0x84,0x0f,0x97,0xc0,0xf8,0xfa,0x4a,0xcf,0x57,0xb8,0x24,0xf0,0xa8,0x40,0x70,0x9d,0xc4,0xe5,0xc7,0xc9,0xcb,0xb6,0xf4,0x0b,0xb5,0xcc,0xe0,0x90,0x2b,0x42,0x81,0xd6,0x59,0x2e,0x11,0xbd,0xe8,0xf5,0xef,0xa8,0x2b,0xdb,0x93,0x62,0x1e,0xef +.byte 0x3a,0x5f,0xf5,0x47,0x15,0x1f,0x03,0x6f,0x40,0x85,0xff,0x50,0x89,0x2e,0x72,0x8f,0x5c,0x0d,0x61,0x84,0x8d,0x8a,0x8f,0x2a,0x47,0x7c,0x97,0xfe,0x8a,0x97,0x6c,0xd5,0x1c,0x97,0xfa,0x59,0xbe,0x2c,0x0f,0x4d,0x85,0x7f,0x18,0xe3,0xea,0xe8,0xde,0x5a,0xf3,0x67,0xe1,0x71,0x7e,0x81,0xa3,0x74,0x0d,0xf4,0x3d,0x5a,0xec,0xc1,0xcf,0x6f +.byte 0x08,0x0f,0x5a,0x63,0x72,0x0b,0x46,0x5d,0x38,0x80,0xea,0xb7,0x12,0x5d,0xce,0x37,0x26,0xaa,0xd3,0x0d,0x93,0x4a,0x34,0x20,0xd5,0x51,0x54,0x1c,0x5e,0x53,0xa9,0xed,0x26,0x3c,0x29,0xaf,0xbe,0x73,0x34,0xa5,0xc3,0xbf,0x8c,0x8a,0xc3,0x30,0x89,0xaf,0xa9,0x2d,0x28,0x35,0x7d,0x6b,0x84,0x23,0x22,0xee,0x8c,0x82,0x04,0xbd,0x26,0x52 +.byte 0x26,0x73,0x76,0x05,0x35,0x0c,0xec,0xf7,0x54,0xb2,0x17,0x68,0xe9,0x68,0x67,0xbb,0x0d,0x98,0x19,0x32,0xa7,0xdb,0xf9,0xef,0x42,0xe7,0xc2,0xe2,0x39,0x9c,0xae,0xbb,0xdb,0x91,0x28,0x82,0x88,0x23,0x61,0x50,0x6d,0x61,0x39,0x73,0xf8,0x6a,0xee,0xf3,0xa9,0x2c,0x78,0x0d,0x5a,0xed,0xb1,0x08,0x8f,0x24,0xe5,0xb7,0xa4,0xdf,0x65,0x9a +.byte 0x72,0x3a,0x39,0x9c,0xf4,0x43,0xdc,0x8a,0xa3,0x3d,0xb5,0x1e,0x7b,0xe5,0x83,0x11,0x07,0xab,0x62,0x7e,0xac,0xab,0x52,0x94,0x0b,0xaf,0xdf,0x54,0x18,0xf1,0xc0,0x9f,0x1c,0x33,0x02,0xd9,0x62,0xc3,0xcc,0xaf,0x32,0x09,0x35,0x77,0xad,0x72,0xd6,0xb5,0x2d,0xaf,0xf9,0x39,0xfb,0x95,0xbb,0xf9,0x84,0x80,0x84,0xc8,0xc6,0x6d,0xb5,0x79 +.byte 0x25,0xf4,0x6c,0x71,0x26,0xda,0x74,0x86,0xad,0x52,0x47,0x8b,0x46,0x32,0xf6,0x2c,0x89,0xdb,0x93,0x1f,0x46,0x83,0x91,0x19,0xd2,0x0c,0x29,0x97,0x5f,0xa9,0x2b,0x87,0x0c,0x87,0x89,0xe6,0x63,0xa1,0x36,0xfb,0xfa,0xb4,0xb8,0x8e,0x5f,0xe9,0x8f,0x62,0xd2,0x81,0x1d,0x7b,0xc6,0x14,0x37,0x56,0x73,0x64,0x3d,0x0a,0xfd,0xe5,0x94,0x01 +.byte 0x09,0xc8,0x0d,0xa8,0x92,0xda,0x43,0xc4,0x41,0xca,0x3c,0x27,0x2c,0xbb,0xc4,0xb2,0x77,0x13,0xa6,0xb0,0x0e,0x97,0x6a,0xb2,0x83,0xe5,0x5e,0xa3,0xc0,0xe8,0x5e,0x0b,0xe6,0x00,0x04,0x6c,0x1b,0xac,0x84,0xab,0xd3,0xac,0x5f,0x39,0xc2,0xf8,0xfd,0x66,0xf7,0x97,0xd7,0xb9,0x6b,0xd8,0x2a,0x49,0xf7,0x67,0xd8,0xd5,0xa4,0x89,0x57,0xa6 +.byte 0x8f,0x7c,0xcf,0xaf,0xfe,0x3c,0x92,0xc8,0x23,0x2c,0x26,0x83,0x86,0x16,0x97,0x34,0x71,0x3e,0x82,0x2b,0xc7,0x75,0x5a,0x59,0xb3,0x44,0xdd,0x4e,0xd4,0x6d,0x1b,0x9f,0x3c,0x35,0xc4,0xe4,0xf2,0x95,0xb6,0x90,0x95,0xa7,0xc4,0x03,0x10,0x7d,0x3d,0xeb,0x74,0x29,0xaa,0x0c,0xd3,0x27,0xcd,0x3a,0x85,0x3c,0x88,0xd5,0x9a,0x46,0x84,0x8e +.byte 0x36,0xde,0xe3,0x6a,0x27,0xbf,0xc3,0xd0,0x3e,0xa3,0x0e,0x62,0x1f,0xdf,0x4c,0x02,0xa7,0x11,0x91,0xb0,0x6b,0x50,0xc1,0xe0,0x18,0x5a,0xc0,0x10,0xc7,0x1c,0xb6,0x36,0xac,0xe7,0x7d,0xad,0x34,0x63,0x4f,0x17,0xcc,0x41,0x30,0xec,0xd7,0x14,0xb9,0xfe,0x07,0x5c,0x3d,0xbe,0x08,0x77,0x5b,0xdf,0xa3,0x20,0x56,0x55,0xa2,0x8a,0xe7,0x0d +.byte 0xf6,0xfc,0x91,0x37,0xb8,0x92,0x6c,0xd9,0x5c,0xb0,0xc2,0xf7,0xc0,0x38,0xfa,0x54,0xc6,0xa1,0xd3,0x4d,0xae,0x49,0x0d,0xd1,0xc0,0xef,0xbe,0x27,0xce,0x23,0x8e,0xf2,0x9b,0x68,0x02,0x67,0x8f,0x53,0x9d,0xf6,0x23,0x57,0x85,0xdd,0x8d,0xd7,0xcb,0x47,0xf1,0xd8,0x17,0xd8,0x46,0x72,0x28,0x4b,0xac,0x94,0xd3,0x5d,0x53,0x4f,0x06,0x19 +.byte 0xc6,0x0e,0x0b,0x9f,0x58,0xc6,0x3f,0xea,0x4e,0x83,0x5e,0xd3,0xcc,0x44,0x55,0xa3,0xc7,0x24,0x19,0xea,0x1b,0x18,0xc1,0x18,0x5f,0x21,0x67,0x73,0x32,0x4e,0x31,0x69,0x05,0x40,0x79,0x7c,0x05,0x13,0xdd,0x50,0xea,0xfa,0xc2,0x26,0xe2,0x33,0xff,0x34,0x0d,0xda,0x77,0x27,0xe0,0xe7,0xa6,0x7b,0x8e,0xcd,0xdb,0x92,0x48,0x3a,0x2d,0x52 +.byte 0xf5,0x59,0xca,0xc7,0x47,0xda,0xb7,0xc7,0x8c,0x37,0x5e,0x29,0x30,0xf5,0x57,0x74,0x8b,0x10,0xcb,0x20,0x31,0x4b,0x12,0xe3,0x84,0xd2,0xb2,0xc3,0xd0,0xe3,0x94,0x18,0xa2,0xdc,0x8f,0x4d,0xc3,0x0a,0x43,0x07,0x2c,0x6b,0x41,0x64,0xc0,0x35,0x8f,0x37,0x9b,0xd7,0x78,0xab,0xd0,0xdc,0x1f,0x77,0x55,0xab,0x71,0xc8,0x99,0x98,0x00,0x29 +.byte 0x1c,0xab,0x3c,0x5f,0x82,0x96,0xc2,0xc8,0x9b,0xd4,0x68,0x3f,0x3d,0xe6,0x5a,0x4c,0x1c,0x7b,0x51,0xa3,0x79,0xe8,0x0e,0x8a,0x78,0xdc,0x98,0x63,0x80,0x74,0x32,0x9d,0x7c,0x3a,0x79,0x54,0xa7,0x4c,0xa4,0x4e,0xfc,0xa5,0x8a,0xa4,0x19,0xce,0x84,0xbb,0x8a,0xb9,0x93,0x4a,0x2d,0x82,0x5d,0x1d,0xf8,0x2f,0x85,0xb3,0x90,0x32,0x61,0x6d +.byte 0x13,0x33,0xac,0xbc,0x5d,0x3a,0x54,0x45,0x04,0x50,0x30,0x30,0xc7,0x58,0xbe,0xed,0xdd,0xa1,0xae,0x6d,0xe5,0xde,0xed,0x63,0x9f,0xd4,0x2b,0x8d,0x1f,0x69,0xde,0xda,0x55,0x3f,0x3b,0xe7,0xc8,0x73,0xc0,0x68,0x18,0x6a,0xb3,0xfb,0xce,0xaf,0x46,0x0a,0xcc,0x81,0xa8,0x96,0x6d,0xb6,0xa4,0x74,0xf3,0x8c,0x95,0x2d,0xa1,0xfe,0x09,0xb8 +.byte 0xdb,0x3c,0xcd,0xdc,0x5b,0x0e,0x2d,0xff,0x89,0x8a,0xfd,0x7a,0xe9,0x69,0x0b,0xdd,0x4e,0x9b,0x94,0x64,0xe4,0xb6,0x5d,0x69,0xef,0x9c,0xf6,0xe6,0x44,0x73,0xd5,0x86,0x47,0x63,0x77,0x3e,0x74,0xaa,0xf3,0x6b,0x1f,0x37,0xbf,0xef,0xa2,0xff,0x86,0x61,0x78,0xc4,0xb5,0xbd,0x5a,0x43,0x49,0x80,0x16,0xf2,0x4c,0xec,0x1e,0x07,0x0f,0x41 +.byte 0x60,0x6f,0x3a,0xd2,0xab,0x85,0xc0,0x5c,0xfc,0x9f,0x48,0xad,0x5e,0xe0,0x7d,0x66,0x8e,0x46,0xf1,0xc3,0xb0,0xbc,0x5e,0x3b,0x10,0x7c,0xfc,0xa3,0x27,0xbd,0x8f,0xae,0xd9,0x61,0x39,0xbf,0xca,0x27,0xbb,0xe7,0xda,0x59,0xa8,0x63,0x38,0x16,0xd9,0xb5,0xa6,0xd9,0x1c,0x2b,0xa1,0x42,0xec,0x50,0xd7,0x63,0x09,0x22,0xe0,0x0c,0xb8,0xec +.byte 0x12,0x9b,0xdb,0x8a,0xd3,0x02,0xcf,0x32,0xa9,0x88,0xa4,0x31,0xc8,0xa9,0xf4,0x03,0xf2,0x9d,0xe1,0x41,0xf0,0x0f,0x23,0x65,0xa8,0x99,0x55,0x87,0xf2,0x17,0x66,0xf0,0x94,0xe8,0xe9,0xb6,0xfd,0x10,0xb9,0x55,0xf4,0xda,0x06,0x7a,0xbe,0xe2,0xd3,0xfa,0xb8,0xf7,0x85,0xdf,0xee,0x39,0xdc,0x0f,0xda,0x87,0xf5,0x66,0xd8,0x1b,0x5c,0x0c +.byte 0x13,0xe8,0xa2,0xcd,0xdf,0x47,0x33,0xd7,0xf4,0x5c,0x79,0xc7,0xf4,0x68,0xe4,0x2d,0xa1,0xde,0x5c,0x06,0x1c,0x85,0xf1,0x2a,0xf9,0x73,0x44,0xbc,0xd3,0x57,0x4f,0x0f,0xcd,0xcc,0x40,0xeb,0x9d,0x35,0x8e,0xdf,0x1d,0x4a,0x61,0xd0,0x66,0xb5,0x16,0xce,0x45,0xc0,0xbf,0x01,0xe3,0xb2,0x51,0xba,0x53,0x18,0x2a,0xff,0x19,0xea,0x41,0xa2 +.byte 0xac,0x0b,0x50,0xd3,0xc1,0x6a,0x9c,0xb0,0x34,0x6f,0xa0,0xcb,0xc7,0xc6,0x79,0x5d,0x17,0x3a,0x4c,0xa3,0x16,0xdc,0xac,0x10,0xf0,0x24,0xad,0x9a,0x5b,0xa9,0x7e,0x45,0xcd,0xe9,0xad,0x87,0x04,0xbc,0x2a,0x05,0x59,0xd1,0xdb,0x86,0x22,0x40,0xdf,0xb1,0xff,0x8d,0x3c,0xf8,0x6a,0xf3,0xcb,0x60,0xf9,0x35,0xa6,0x42,0x81,0xcb,0x0f,0x7c +.byte 0xf7,0x24,0x3b,0x0c,0x94,0x32,0xd9,0xec,0xcf,0xd1,0x31,0x3e,0x3e,0xeb,0xa9,0xf2,0x1f,0x2d,0xa7,0x89,0xf7,0x67,0x7d,0x90,0x9d,0x40,0xf2,0xdb,0x07,0x8f,0xb8,0x6f,0xfd,0x78,0x6e,0xd0,0x9e,0xd5,0x7d,0xb0,0x7d,0x65,0xdc,0x6e,0x50,0xec,0x7a,0x5c,0x2c,0x3e,0x6f,0x64,0xa3,0x10,0x34,0xf7,0x71,0xc8,0x82,0xb6,0x96,0xb8,0xb1,0x2a +.byte 0xb4,0x03,0x95,0x75,0x90,0xac,0x6c,0x81,0x17,0x97,0x06,0xd0,0xb8,0xc5,0x98,0xc5,0x9e,0x46,0x07,0x13,0x02,0x9e,0x47,0x69,0xba,0x85,0x2d,0x09,0x86,0x50,0xe4,0x76,0xb1,0xa2,0xbe,0x8b,0x91,0x6b,0x3b,0x76,0xa3,0xb7,0xf5,0x7f,0xfe,0xf1,0xa4,0xf3,0xc3,0x53,0x64,0xef,0x97,0x86,0x96,0x8b,0xc4,0xae,0x06,0x8b,0xe8,0x3c,0xdc,0xff +.byte 0xfa,0xad,0xcb,0xcb,0x53,0x15,0xf2,0xcc,0x9f,0x48,0xf9,0x57,0x6a,0xcd,0xb2,0xee,0x46,0xc0,0xbf,0x82,0x58,0x60,0xda,0x2f,0xbd,0xde,0xc7,0x41,0xcb,0xf1,0x38,0x56,0x9d,0x38,0x38,0x3d,0xea,0x5e,0x38,0xf1,0xd0,0x02,0x35,0xee,0x4c,0x2f,0x1d,0x19,0xbd,0x08,0x01,0xc3,0x8f,0x75,0xe2,0xf3,0x93,0xbb,0x76,0x6b,0xd7,0x87,0x76,0x7f +.byte 0x3b,0x29,0x08,0x9f,0x3a,0xa5,0x44,0x96,0x5a,0xb3,0x78,0xa9,0xbe,0xf7,0x5d,0xda,0x06,0x37,0x98,0x5d,0xbe,0x6e,0xec,0x58,0x53,0xd1,0xa5,0xd7,0x7a,0x16,0xb1,0x59,0x98,0x42,0x37,0x76,0x1b,0xd6,0x2e,0xa7,0xdc,0x45,0xa6,0x9c,0x9c,0x99,0x24,0x0e,0x22,0xae,0x94,0x65,0xeb,0x4e,0x64,0xc3,0xb0,0xac,0x19,0x41,0xf1,0x62,0x65,0xb2 +.byte 0x35,0xf5,0x2f,0xdb,0xd2,0xf0,0x78,0x19,0x35,0x04,0x6f,0x9c,0xf4,0xaf,0x81,0x68,0x4f,0x8b,0x85,0xfa,0x31,0x23,0x06,0xeb,0x37,0x86,0x43,0x51,0xb3,0xd2,0x2a,0xd7,0xd5,0xa9,0x33,0xba,0xfd,0xb5,0x0e,0x6d,0x9a,0x91,0xf9,0xe7,0x27,0xb7,0xff,0xe6,0xe7,0x34,0xc5,0x1a,0xa3,0x45,0x3b,0x71,0x34,0x87,0x7e,0xe7,0xab,0x74,0xc5,0xff +.byte 0xeb,0x23,0x8f,0x3f,0x5d,0x1c,0x91,0x47,0xeb,0x3e,0x5f,0x5a,0xa6,0x5a,0xde,0xa9,0x5f,0xf4,0x8f,0x95,0xc6,0x25,0x3c,0xd5,0xaf,0xfd,0x4d,0x33,0x68,0xe1,0xa3,0x51,0x1b,0x07,0xad,0xb9,0xec,0xf1,0x50,0x51,0xbf,0xeb,0xe8,0x58,0x2a,0x50,0x0e,0x9d,0xc2,0x8a,0x83,0x8c,0xb0,0xb8,0xde,0x1d,0x7b,0x0f,0xff,0xfc,0xfc,0x31,0xe5,0x62 +.byte 0x40,0xc8,0x28,0x30,0x31,0xc9,0x82,0xab,0xbe,0x50,0xe5,0xfe,0x1f,0x49,0x17,0xf9,0xea,0x23,0xc7,0x6d,0x8d,0x63,0xc3,0x70,0x40,0x32,0x0b,0x48,0x7a,0xd9,0x03,0x52,0x1b,0xf4,0x90,0xd6,0x6d,0xd2,0xfc,0xec,0x24,0x7f,0x21,0x2e,0xd4,0xb5,0x60,0x44,0xd9,0x83,0xb0,0x3e,0x75,0x8a,0x6a,0x09,0xab,0xa8,0x4f,0x48,0x3c,0x2b,0x89,0x30 +.byte 0x29,0xdb,0x1a,0x8e,0x68,0xe4,0x89,0xed,0x10,0xe8,0x46,0xa7,0xf9,0x5f,0x7d,0x42,0xe0,0x8d,0xbc,0x3d,0x4d,0xd8,0x06,0x4a,0xf9,0xbb,0x97,0xa7,0xdb,0x24,0x0b,0xfc,0x49,0x92,0x5d,0x80,0xf8,0xed,0x57,0xc7,0x1e,0x82,0xed,0x41,0xb8,0xfd,0x71,0xb9,0xa5,0x11,0x52,0xdd,0x1e,0xa4,0xf1,0x02,0xc7,0x54,0x7c,0xdc,0x37,0x9f,0xfe,0x37 +.byte 0xe8,0xa5,0xcf,0xb0,0x3d,0x25,0x3f,0x24,0xfe,0xf2,0x63,0x97,0x3c,0x13,0xdc,0x31,0x78,0x07,0xf1,0x8e,0xee,0xc6,0x00,0xf8,0xfd,0x84,0x53,0x4d,0x92,0xa1,0xef,0xd0,0xb1,0x12,0x0a,0x12,0x91,0xeb,0x52,0xdd,0x6e,0x15,0x98,0xd2,0xe1,0x53,0x7a,0x0e,0x02,0x83,0xd3,0xd1,0xde,0x72,0x6e,0x5b,0x4b,0x8d,0x40,0xe3,0x2d,0x22,0x59,0x9d +.byte 0xee,0xbe,0x43,0x18,0x62,0x8c,0x77,0x18,0x91,0xf5,0x9e,0xbc,0x3e,0x8b,0x77,0xb6,0xdb,0x5c,0xcb,0xcd,0xdb,0x36,0xea,0xf5,0x1d,0x9b,0xa7,0x13,0xef,0xda,0xd0,0xe8,0xd8,0xb2,0x4c,0xc6,0x19,0x3d,0x77,0x2d,0x0d,0xad,0xe4,0x32,0x24,0xe9,0xd4,0x7f,0x72,0x1d,0xc6,0x6e,0x83,0x7d,0xb8,0x62,0x64,0x9d,0x9a,0xd7,0x13,0x93,0x92,0xf1 +.byte 0x37,0x98,0xcf,0x44,0x66,0xab,0xd1,0x61,0x6c,0x08,0xa7,0x41,0x4e,0x37,0xc1,0x67,0xfb,0x7c,0x22,0x8f,0xbd,0x93,0xb2,0x09,0x13,0xa0,0x48,0x60,0xaf,0xda,0x73,0x2b,0xa3,0x2a,0xf3,0x4d,0x8e,0x22,0x5b,0x7a,0x32,0xe6,0xca,0xff,0x0e,0xa1,0x0a,0x15,0x33,0x31,0x50,0x71,0x1c,0x85,0x26,0x9b,0x19,0xf2,0xe3,0x69,0x4e,0x2d,0xff,0x79 +.byte 0x80,0xfe,0x2c,0x2f,0x7a,0x49,0x95,0xf3,0x0e,0x78,0xb1,0x0c,0x1c,0x45,0x59,0x68,0x2a,0x37,0xf2,0x48,0x6f,0xd9,0x32,0xf7,0xfc,0xdc,0xbe,0xe3,0xdd,0x61,0x17,0xc0,0x08,0x9d,0xbc,0x2d,0x8d,0x24,0x1c,0xbb,0x53,0xbe,0x37,0x59,0x30,0x87,0xa0,0x14,0xf5,0x08,0xcf,0xd1,0xcc,0x84,0xa7,0x0f,0x69,0xe0,0x77,0x8c,0x0d,0xdc,0x82,0xe5 +.byte 0x88,0x9a,0x58,0x05,0xe3,0x4f,0xdd,0x55,0x1e,0x6e,0x90,0xd5,0x3c,0xa6,0xa6,0x10,0x24,0xe5,0x58,0x97,0xdc,0x31,0x87,0x39,0xdc,0x3a,0xe6,0x24,0x64,0x23,0x45,0xd8,0x01,0x1b,0xf6,0x38,0x68,0x9e,0x62,0x53,0x00,0x97,0x71,0x04,0xb5,0x3b,0x54,0xdb,0xb5,0xcb,0x30,0x91,0x14,0xce,0x94,0xd5,0xe0,0x96,0x70,0x99,0xa5,0xed,0x69,0x32 +.byte 0xc7,0xb7,0x14,0xff,0xc0,0xde,0x19,0x5d,0x31,0xdb,0xa7,0xc0,0x7a,0x94,0xec,0x60,0xfc,0x52,0x71,0x69,0x9b,0xd8,0xbe,0x97,0x0b,0xb5,0x70,0xa7,0x47,0x11,0x37,0x84,0xda,0x3c,0x23,0xfe,0xf2,0x53,0xad,0x55,0x71,0x1e,0x70,0x9b,0x7b,0x61,0x97,0xf8,0x71,0xc4,0xad,0x72,0x98,0x43,0x0c,0x33,0x30,0x2c,0xb2,0xd6,0x21,0x8d,0xbb,0x1b +.byte 0x85,0x82,0x24,0x14,0x85,0x95,0x88,0xff,0x3f,0x8c,0x88,0x96,0xa0,0xf8,0xd7,0x36,0x78,0x37,0x6d,0x92,0x09,0x04,0x76,0x27,0xb9,0xd5,0xea,0x0f,0x07,0x9f,0xe1,0x49,0x0e,0xd1,0x9c,0x46,0xcd,0x2b,0x7a,0x57,0xb6,0x56,0x39,0xe5,0x59,0x6b,0x1b,0x39,0xbf,0x15,0x3b,0x56,0xf5,0xc2,0x08,0x96,0xf5,0x63,0x4c,0x31,0x33,0x65,0x8b,0x74 +.byte 0x4e,0xde,0xa8,0x20,0xe0,0x7c,0x27,0xee,0x91,0x74,0xe8,0x24,0xb3,0xcf,0xa3,0xd4,0xf1,0xb9,0x18,0x43,0x05,0x5d,0x13,0x36,0x82,0xd1,0xbf,0x16,0x89,0x48,0x83,0xf0,0xcc,0x5c,0xbb,0x75,0x7e,0x71,0xc0,0x73,0xd1,0xf5,0x00,0x38,0x7f,0x10,0x98,0xd6,0xb9,0x14,0xea,0xd3,0x3f,0x0f,0xe3,0x61,0x1a,0x5e,0x21,0xd0,0x11,0x58,0x68,0x47 +.byte 0xf2,0xe5,0xe9,0x65,0x9a,0xc1,0xf4,0xa0,0x98,0x8e,0x9f,0x7f,0xbe,0x7e,0xd0,0xb6,0x88,0x4e,0xce,0xc1,0x8b,0xd4,0xd3,0x93,0xb7,0xd8,0xf3,0x0b,0xf3,0x73,0xc9,0x08,0x2f,0xcf,0xd8,0xbd,0xa6,0x1d,0x7c,0xfa,0x44,0x82,0x9f,0x03,0xca,0x56,0x3b,0xbf,0x4d,0x1e,0xbc,0x06,0xc2,0x37,0xfb,0xde,0xd3,0xa9,0xe3,0xae,0x61,0xef,0x26,0x7d +.byte 0xbd,0x2f,0xee,0x2d,0xe1,0x65,0x71,0x77,0xab,0x9c,0x96,0x4f,0x00,0xe2,0xde,0xd7,0x05,0x54,0x00,0xb6,0xaf,0x12,0x0c,0x79,0x1a,0xed,0x20,0x72,0xc7,0x3b,0x3a,0x10,0x15,0x74,0xff,0xbd,0xf8,0xaa,0x8f,0x3a,0x83,0x39,0x24,0xfa,0x53,0x2d,0xc3,0x61,0xfc,0x12,0x6b,0x54,0x33,0xbf,0x83,0xc9,0x59,0x00,0xf0,0xdc,0xa8,0x64,0xbc,0xb5 +.byte 0xc3,0x96,0x60,0x3e,0x7b,0xe2,0x08,0x19,0x92,0x17,0x80,0x9b,0x0c,0x09,0x49,0x68,0x8b,0x15,0xe3,0xce,0x0c,0xfa,0x0c,0x8b,0xf0,0xdc,0x58,0xb0,0x7b,0x82,0x85,0xd2,0x56,0x1c,0xfb,0xb5,0xd0,0x0e,0x0a,0x55,0x61,0xda,0xd8,0x20,0xc1,0x79,0x70,0x3c,0x69,0x8e,0x49,0x5f,0x1c,0xdb,0x22,0xb8,0xdd,0x4c,0x4f,0xca,0xe9,0x0f,0x9a,0x4e +.byte 0xff,0x56,0xbc,0xcf,0x72,0x09,0xa6,0x41,0x38,0xf0,0x7d,0xe7,0x45,0x0a,0x71,0x2c,0x92,0xdd,0x21,0x17,0xb2,0x3b,0x31,0x3c,0x91,0x11,0x69,0x29,0x50,0x31,0xe6,0xa6,0x10,0xc7,0x35,0xe8,0x44,0xec,0x74,0xa3,0x7e,0xb6,0x34,0xe5,0xb7,0xba,0xdf,0x5b,0x2f,0x85,0x02,0x6c,0xb0,0x71,0xb1,0x43,0xff,0x0e,0x47,0x04,0x63,0x4d,0x5b,0x81 +.byte 0x81,0x28,0x8b,0x84,0x79,0xad,0x2a,0x45,0x00,0x1c,0x0c,0x9f,0xef,0x35,0xbb,0x6d,0xc5,0x6a,0x6b,0xef,0x2b,0xae,0x78,0x66,0x05,0x7a,0x61,0x4c,0xe9,0x5e,0xf7,0x95,0x66,0x7e,0x1a,0xa7,0xdf,0x4c,0x4d,0x7c,0x66,0xa5,0x38,0x84,0x86,0x8d,0x66,0xcc,0x7f,0x32,0xb2,0x9c,0xc5,0x0d,0x3d,0xb7,0xb1,0xa6,0xc5,0x80,0x68,0xaf,0x79,0x81 +.byte 0x15,0x8f,0xec,0x50,0x5c,0x1b,0x57,0x31,0xd2,0xb9,0x16,0x66,0xf8,0x16,0xfd,0xcd,0xc7,0xa8,0x84,0x6f,0x35,0xea,0x3f,0xa4,0x72,0x8d,0xad,0xf4,0xd1,0x14,0x46,0xcc,0x06,0xed,0x71,0x39,0x07,0x99,0x28,0xc8,0xf9,0xc4,0xc2,0xec,0xde,0xb8,0x92,0xae,0xc5,0xf8,0xb2,0x49,0xc9,0x32,0x58,0xec,0x9f,0xb0,0x59,0xaf,0x49,0xef,0xe8,0x0d +.byte 0x4c,0x56,0x8d,0xf7,0x57,0xb0,0x09,0xbe,0xc2,0x6a,0x62,0xc4,0x87,0xf3,0x20,0x07,0xc9,0xe3,0x3b,0x31,0xcc,0x8d,0xcf,0x5d,0x18,0x00,0x2a,0x9f,0xde,0x80,0x1a,0x7e,0x95,0x93,0xd1,0xbd,0xe6,0xd4,0x69,0x37,0x96,0xbb,0x70,0xc5,0x3c,0x87,0x8f,0xff,0x95,0x97,0xfe,0x95,0x56,0x7b,0xba,0x03,0x3d,0x29,0x0f,0xdb,0xd0,0x65,0x4f,0xf8 +.byte 0xa8,0xf3,0x42,0x09,0xb5,0x81,0x34,0xc6,0xa9,0x60,0xb9,0xef,0x3e,0x9d,0xc5,0x42,0x1e,0x79,0x5d,0x2b,0xf2,0x46,0x0d,0xeb,0x88,0x84,0x8f,0xad,0x60,0x69,0x57,0x49,0x33,0xb4,0xdd,0xfe,0x10,0x65,0x65,0x51,0xaf,0x68,0xa0,0xce,0xbd,0xe1,0x6e,0x03,0xe1,0x5f,0xba,0x3f,0x36,0xca,0xed,0x20,0x95,0xfa,0xff,0x3c,0x65,0xa8,0xb1,0x6b +.byte 0xc5,0x91,0xa0,0xd5,0x36,0x38,0x1c,0x38,0xe9,0x1d,0x1b,0x67,0x4c,0x17,0xd3,0x29,0x92,0xa2,0x27,0x76,0x3d,0xe2,0x26,0x37,0x2a,0x2c,0xf6,0xee,0x64,0x40,0x8a,0x1c,0x2b,0xc1,0xd3,0x28,0xd0,0xcf,0x2d,0xc2,0x45,0xf4,0x37,0x5a,0x63,0xfb,0x18,0x67,0x01,0x0a,0xe8,0xe2,0x41,0xf7,0x15,0x47,0xa7,0xe9,0xc8,0x05,0xbc,0xc7,0x8f,0xf0 +.byte 0xc3,0xc5,0x9a,0x4e,0x0d,0x7b,0xf0,0x20,0x8c,0x21,0x49,0x99,0x0d,0xf7,0x34,0x84,0x35,0xfb,0x11,0x33,0xd6,0x46,0x14,0x3c,0xf1,0xb3,0x37,0xac,0x75,0x63,0xe7,0x1a,0x19,0xa4,0x49,0xf2,0x58,0x1d,0x56,0x55,0x64,0x46,0x25,0xff,0x7d,0x90,0x34,0x21,0x5d,0x00,0xa1,0xa8,0xaa,0xe0,0x93,0xe7,0xda,0x11,0x34,0x1d,0xa3,0x0c,0x67,0xae +.byte 0xf5,0x60,0x72,0x14,0xdf,0x08,0xf6,0x72,0x3e,0x48,0x41,0x3d,0x00,0x58,0xfb,0x0c,0x15,0x80,0x2d,0xd9,0x72,0x47,0xa6,0x20,0x6a,0x74,0x9e,0x06,0xb9,0xac,0x68,0x3a,0xe7,0xf1,0x19,0xb8,0x0b,0x66,0x07,0x4d,0xa0,0xb5,0xab,0xea,0x70,0xa1,0xdf,0x41,0x76,0x85,0x18,0x5b,0x6f,0x78,0x5a,0x5d,0x08,0xe0,0x1b,0xd8,0x06,0x73,0x1e,0x16 +.byte 0xcb,0xdb,0x02,0xf8,0x96,0x64,0x65,0xc5,0xc1,0x52,0xd4,0xd8,0xb3,0x1e,0xd4,0x09,0xfd,0xa7,0x30,0x41,0x5a,0xce,0x53,0x4d,0x11,0xc8,0xdd,0x13,0x50,0xd5,0x2e,0xa0,0xe6,0x48,0x49,0x31,0x4b,0x1d,0xce,0xfc,0x42,0xed,0x8f,0xc8,0xb3,0x0a,0xae,0x1d,0x4c,0x1e,0x4f,0x39,0xa4,0x37,0xc8,0x54,0xdf,0x40,0xa6,0x42,0x61,0x7d,0x34,0xd4 +.byte 0x75,0x0a,0x9f,0xf0,0x33,0x54,0xf3,0xc4,0xdc,0x4e,0x2f,0x81,0xc2,0x20,0xaa,0x4f,0xa0,0xae,0xa6,0xb8,0x50,0xf8,0x45,0xf1,0xf2,0xd1,0xd2,0xcf,0xc8,0xf0,0xf4,0x54,0x37,0xdc,0xfb,0x13,0xdf,0x38,0xc2,0x3f,0xe0,0x59,0xb5,0x9a,0x0f,0x27,0x87,0xd4,0xd3,0xdc,0xfd,0xda,0x1d,0xfa,0xdd,0x12,0xe0,0x7f,0x34,0x01,0xde,0x28,0xf5,0x0e +.byte 0xff,0x59,0xc7,0xbd,0x6a,0xe4,0x0c,0x85,0x7b,0x87,0xf9,0xd7,0xe2,0xed,0xb2,0xf7,0xb7,0x13,0xfb,0xfc,0x4d,0x25,0x52,0xfd,0x23,0x6b,0x10,0xd0,0x80,0xd8,0xbd,0xbd,0xf0,0x87,0xfc,0x38,0x85,0x83,0x20,0x5f,0x7c,0x26,0x14,0x93,0xd3,0xe1,0xdc,0xa4,0xda,0xa7,0xf9,0xfd,0x6c,0x9a,0x2b,0x75,0x82,0xf1,0x9f,0x1b,0x0c,0x43,0xd4,0x2d +.byte 0x5b,0x0c,0x54,0x7e,0x61,0x24,0x8e,0x50,0x25,0xd8,0x54,0xfd,0x30,0xec,0x4c,0xa8,0xb6,0xf0,0x35,0x67,0xf7,0xe4,0x3c,0xfd,0xc8,0x40,0xf4,0x2d,0xc5,0x4d,0xc3,0x29,0xc2,0x88,0x60,0xab,0xd9,0x2a,0xe8,0x31,0xcc,0x0c,0x9f,0x97,0xa8,0x2e,0xaa,0xa5,0xb6,0xee,0x3c,0x71,0xa9,0xff,0x90,0xb4,0x43,0x2e,0x16,0x80,0x8c,0xfe,0xb5,0x7a +.byte 0x40,0x58,0xd5,0x98,0x7e,0xca,0xaf,0x95,0xee,0x00,0x26,0x8d,0x5b,0xba,0x33,0xee,0x35,0xb5,0x9b,0xf8,0x08,0x1e,0x15,0x2d,0x01,0xb1,0x83,0xa6,0x57,0x58,0xd1,0xf3,0xa4,0xf1,0x3a,0x00,0xf4,0x40,0xee,0x35,0x3a,0x20,0xc2,0x13,0x1e,0xda,0x32,0xc2,0x35,0x74,0x29,0xce,0x51,0x3f,0xec,0xb2,0xd7,0x23,0xa7,0xc6,0xef,0x70,0xb9,0x88 +.byte 0x6f,0xa8,0xf5,0x5b,0xff,0xc5,0xf5,0xb4,0x3b,0x12,0x75,0x20,0xbf,0x61,0x8a,0xb1,0xae,0x01,0x9b,0x17,0xf4,0xf3,0x2d,0xfb,0x44,0xe8,0xac,0x29,0x81,0xc2,0x6d,0x50,0x05,0x11,0xd9,0x43,0xf8,0xc7,0x58,0x5d,0xbc,0x2d,0xc0,0x83,0xd2,0x81,0x41,0x1c,0x46,0x62,0x60,0x6e,0x65,0x52,0x4b,0x1c,0x88,0x72,0x1b,0x0e,0x8e,0x7d,0xa2,0xb5 +.byte 0x4e,0x28,0x32,0xf2,0xb1,0xfa,0xf1,0x4b,0xc5,0x85,0x95,0x2c,0x08,0x78,0x85,0x68,0xe5,0x20,0x23,0x8b,0xc4,0xf5,0xb2,0xdb,0xc1,0xdd,0xe5,0x69,0xa4,0x97,0xa9,0x6c,0x2e,0x3a,0x25,0x1c,0x24,0x54,0x97,0x3e,0x8d,0x61,0x61,0xa3,0x60,0xf5,0xd2,0x4e,0x90,0x25,0x06,0x09,0x31,0x7b,0x96,0xce,0xcc,0xb7,0xbc,0x63,0x9f,0x04,0x7d,0xec +.byte 0xa1,0x4a,0x65,0xd3,0x26,0xe1,0xbf,0xf9,0x88,0xea,0x5c,0x5d,0xfe,0xe9,0x60,0x77,0xbd,0xf2,0xa0,0x11,0x91,0x24,0xca,0xa1,0x0d,0x05,0x7b,0xe2,0x7d,0x22,0x2e,0xd2,0xc9,0x4b,0x78,0xce,0x0c,0x7b,0x49,0xaf,0xd6,0x59,0x5f,0xb4,0xbd,0x2e,0x4a,0x22,0xcb,0x5d,0x1c,0xd5,0xde,0xea,0x86,0x74,0xd5,0x15,0x52,0x59,0xfc,0x3d,0x7b,0x1c +.byte 0x3f,0x14,0xec,0xf2,0xc8,0x3c,0x88,0xbf,0x89,0xd5,0x23,0xc3,0x94,0x3c,0x28,0x04,0x91,0x6c,0x36,0x35,0x4b,0x75,0xf8,0xdc,0xf3,0xff,0xba,0x8c,0xa4,0xc7,0x85,0xc5,0x1a,0x30,0x4b,0x7c,0xc5,0x2f,0xb9,0x2a,0x14,0xaa,0x65,0xe3,0x92,0xdc,0xe1,0xed,0x3f,0xb6,0xff,0x0e,0x74,0xe0,0xb3,0xc9,0x4b,0xd1,0x96,0xfc,0x49,0x72,0xbe,0xb0 +.byte 0xc8,0x4a,0xd5,0xf0,0xb3,0x58,0x29,0x35,0x97,0xd4,0x5c,0xc7,0x0b,0x27,0x1d,0x14,0xdb,0xb7,0x5c,0x7e,0x6d,0xc1,0x56,0xa9,0x80,0x72,0x7d,0x75,0xc2,0x2f,0x07,0x28,0xb4,0xff,0xef,0xa7,0x34,0xed,0x31,0x44,0x85,0xe6,0xc3,0xa4,0x5f,0xe2,0xe8,0xab,0xd1,0x59,0xe7,0x32,0x20,0xd1,0xcc,0xef,0x6f,0xe1,0x10,0x89,0x6c,0x0c,0xf3,0x5f +.byte 0xe8,0xc7,0x1c,0x3b,0xeb,0x3e,0xa5,0x53,0x2d,0x48,0x64,0x92,0xa0,0xec,0xf3,0x75,0x5b,0x5b,0xe2,0x83,0x87,0x04,0xa7,0xd8,0x1b,0x44,0xfb,0x42,0xee,0xd8,0xf2,0x98,0xff,0x30,0xc8,0x09,0xf8,0x1a,0x95,0x46,0x2d,0xe7,0x43,0x10,0x90,0xf4,0x2c,0x8f,0x0b,0x60,0x6d,0xeb,0xbf,0x19,0xc1,0x9d,0x5c,0xc0,0xff,0xb1,0x86,0xbc,0x01,0x73 +.byte 0x35,0x1f,0xd8,0xf4,0xa1,0xd4,0x7f,0x2d,0x1b,0xf9,0xa6,0x78,0x1a,0x2e,0x2c,0xe2,0xcc,0x8b,0x5f,0xbb,0xb9,0x80,0x31,0x32,0xa5,0x5d,0x70,0x59,0xae,0xe3,0xac,0xab,0xde,0x38,0x09,0x07,0x57,0x5f,0xbf,0xe8,0xa0,0xb8,0xd0,0x03,0xac,0x02,0x0d,0x7f,0x7e,0x0c,0xd2,0xcf,0x46,0x01,0x07,0x9f,0x16,0xf6,0x2b,0x94,0xaf,0xae,0x66,0x09 +.byte 0xca,0x4c,0x5f,0x37,0x53,0xa6,0x50,0x82,0x3a,0x0a,0x7b,0xb3,0x52,0x2e,0x0f,0xe4,0x64,0xab,0x40,0x21,0x2d,0xb7,0x20,0x9b,0xe3,0x2f,0xec,0x2b,0xb3,0x31,0x60,0x51,0x2e,0xb6,0x68,0xac,0xae,0xee,0x2d,0x28,0x5b,0xe0,0xa7,0x85,0xab,0x95,0xba,0x53,0x8c,0xc0,0xf8,0x16,0x8f,0x42,0x01,0xef,0x00,0x32,0x44,0x8e,0x41,0xc9,0x05,0x5b +.byte 0xe0,0x3f,0xe1,0xd8,0xd4,0x97,0x8e,0xa0,0x14,0x84,0xce,0x5c,0xef,0xbe,0xa4,0xae,0x18,0x91,0xd9,0x48,0x9b,0xc3,0x7a,0x8f,0xfb,0xb3,0x3e,0xa9,0x87,0x74,0x84,0xd2,0xc6,0x7c,0xc9,0xce,0x01,0xa5,0xcc,0xff,0x5a,0xe8,0x94,0x98,0x54,0x2a,0x6e,0xd9,0x58,0x75,0xd4,0xdd,0x6c,0x7d,0x83,0x32,0xc9,0x4e,0x35,0x2c,0x51,0x26,0x68,0x1f +.byte 0x95,0x20,0x82,0x54,0x0a,0xad,0x5e,0xe2,0xba,0xf9,0xa3,0x54,0x24,0x93,0x4a,0x62,0xff,0x28,0x05,0xd2,0x22,0x62,0x82,0xd4,0x2d,0xe2,0xec,0x66,0xc5,0xee,0x63,0xd0,0xf6,0x93,0xa8,0x37,0xbf,0xdd,0xe0,0x95,0x0b,0x19,0xa1,0x9d,0x9a,0xf8,0x94,0x1a,0x3a,0x50,0x9e,0x66,0x75,0x8c,0x25,0xbd,0x18,0xb0,0x58,0x76,0x7f,0x2d,0x3d,0x06 +.byte 0x02,0xb3,0xcf,0xa3,0x14,0x6e,0xe7,0xc8,0xcd,0xe6,0xbe,0xae,0x92,0xd6,0xa2,0xfe,0x12,0xf0,0xdf,0x9f,0x9e,0xad,0x77,0x77,0xfb,0xfc,0x36,0xb7,0x82,0x9c,0xf1,0x51,0xc2,0x58,0xa0,0xf3,0xa0,0xd6,0x6e,0x64,0x28,0xac,0x09,0x8f,0x7b,0xef,0x19,0x87,0x76,0xb9,0x4e,0xca,0x1f,0x05,0xb6,0x00,0x4a,0x14,0x83,0xaf,0xff,0xd9,0xa1,0xc6 +.byte 0x0f,0x98,0x3a,0xcf,0x85,0x18,0xea,0xa6,0x9a,0x1e,0xae,0x7c,0xaa,0xae,0xef,0x89,0x5e,0x14,0x5d,0x2f,0x73,0x8f,0xd1,0xf0,0x77,0xcd,0x45,0x92,0x7f,0xee,0xb9,0x7c,0xc2,0x3c,0xff,0x56,0x56,0xa5,0xa5,0x49,0xe4,0x20,0xd6,0xa2,0xb6,0xe4,0xfc,0x86,0x53,0xce,0x9e,0x2b,0x7b,0xcb,0xcf,0x6a,0xd5,0x62,0xb7,0x34,0x0e,0x39,0xe2,0xaa +.byte 0x1c,0x24,0x30,0x71,0x94,0xb3,0x57,0xd8,0xe8,0xd4,0xc5,0x4f,0x33,0x2c,0x73,0x7e,0x48,0xba,0xb3,0x55,0x84,0x6d,0x10,0xcf,0x8f,0xf2,0xb6,0xdb,0x4e,0xcf,0x49,0x08,0xf6,0x5a,0x3c,0x7e,0xef,0x3f,0x5c,0x11,0x09,0xfe,0x26,0xfb,0xff,0x30,0xcb,0x81,0x12,0xea,0x1e,0xa9,0x6e,0xf8,0xea,0x4f,0x92,0x2c,0x23,0x99,0x35,0xa5,0x59,0xca +.byte 0x1d,0x66,0x72,0xad,0x5b,0x7c,0xb3,0x4a,0x7c,0x76,0x4c,0xf6,0xc1,0xec,0x68,0x5f,0x2c,0x17,0xbe,0x92,0xe1,0xa1,0xee,0x40,0x24,0x25,0x6b,0xc5,0x0b,0x6f,0x06,0xc0,0x05,0x8c,0x23,0x24,0x76,0xea,0xe9,0xb9,0xa1,0x3d,0x59,0x15,0xe7,0x65,0x47,0x5a,0x75,0x9b,0xc8,0x7b,0x86,0x97,0xf4,0x4a,0xa3,0xec,0x54,0x0e,0x66,0xef,0xda,0x41 +.byte 0xb8,0x3b,0xa6,0x86,0x63,0xe1,0x4e,0x89,0x92,0x40,0xf4,0x8b,0x32,0x47,0x3b,0x4b,0xb4,0xe6,0xd8,0x4b,0x1c,0xac,0x03,0xab,0xde,0x2e,0x63,0x96,0x3f,0x27,0xa1,0x32,0x11,0x35,0x24,0x6a,0xe9,0x0b,0x73,0x61,0x4e,0xd8,0xdc,0x91,0x98,0x01,0x8a,0x0d,0x61,0xec,0x39,0xbe,0x3b,0xb9,0x78,0x77,0xea,0xaa,0xa2,0x12,0x20,0x92,0x98,0x16 +.byte 0x27,0x3b,0xd1,0xfa,0x59,0xef,0x81,0x38,0x9f,0x42,0xe8,0xb4,0xab,0x4f,0x26,0x9a,0xe7,0x0b,0x05,0x03,0xfa,0xe1,0xe1,0x3d,0x45,0xac,0x7d,0x40,0xcc,0x2f,0xf2,0xb0,0x33,0x42,0x14,0xbd,0x91,0x3e,0xe1,0xb7,0x17,0x25,0xc3,0x92,0xcb,0x9e,0x44,0x1e,0x13,0x93,0x98,0x1f,0x96,0x64,0x3a,0xaa,0x53,0x9a,0x18,0xc0,0x34,0x3c,0x47,0x94 +.byte 0x14,0x70,0x67,0x76,0x2a,0x82,0xd3,0x6a,0x18,0x13,0xe7,0x01,0x8d,0x97,0x52,0x51,0x8e,0x08,0xde,0x44,0xb0,0x74,0x07,0x58,0x35,0xc2,0x29,0xb5,0xd7,0x00,0x46,0x31,0x34,0xd7,0x1f,0xdd,0xaa,0x5c,0x27,0xc7,0x37,0x71,0xe8,0xbe,0xad,0x89,0xf1,0xb2,0xd1,0x46,0x33,0x0c,0x2f,0x26,0x21,0x5e,0xc9,0xda,0x25,0xcd,0xd0,0x17,0x23,0x87 +.byte 0x15,0xc2,0xa0,0x1a,0x9f,0x6e,0xfb,0x63,0xe9,0x69,0xdf,0x79,0x18,0x33,0x2f,0x47,0xca,0x54,0x23,0x7e,0x4f,0x6e,0x38,0x06,0x99,0xfb,0xcd,0x22,0xdb,0x4b,0x3f,0x8a,0x05,0x2e,0x5c,0x56,0x65,0xb7,0xab,0x57,0x8b,0xdd,0x28,0xab,0x7e,0x77,0x32,0x0f,0xc6,0x3c,0xf3,0xde,0x43,0xb0,0x13,0x3b,0xbd,0x28,0x3a,0x8b,0xd5,0x6b,0x1d,0x5d +.byte 0x20,0x1a,0x5f,0xa6,0x01,0xed,0x88,0x7f,0x87,0x55,0x38,0xc2,0x0d,0x03,0x6c,0x41,0x6a,0x43,0xdf,0x09,0xf3,0x58,0x69,0x13,0xa1,0xd6,0x39,0x0c,0x8e,0x8f,0x40,0x67,0xe8,0x0e,0x9b,0x9b,0x42,0x30,0xd7,0xae,0x04,0x75,0x66,0xfb,0x4a,0xa7,0xe0,0xe9,0xea,0x6d,0x28,0x4f,0xc0,0x5c,0xd4,0xd4,0xb7,0x60,0x5a,0x35,0xc1,0xe8,0x5f,0xc3 +.byte 0x4f,0x7a,0x5d,0x8d,0xc2,0x29,0x6e,0x36,0x50,0x5b,0x82,0x63,0xf2,0xda,0x8d,0x02,0x61,0x09,0x69,0x0a,0x47,0x9d,0x58,0xf3,0xf6,0xe0,0xc0,0x09,0xd9,0x3b,0x8d,0xf5,0xba,0xf6,0xc4,0xf0,0x65,0x89,0x7b,0xdd,0x93,0x6b,0x6e,0x21,0xa1,0x2a,0x66,0xe0,0x8f,0x62,0xb0,0x49,0x60,0xa3,0x48,0x42,0x62,0xcc,0x26,0x1f,0x59,0x3a,0x7b,0xa7 +.byte 0x82,0x10,0x5f,0xc6,0xf8,0xa2,0xc0,0x07,0x7b,0x26,0x26,0x11,0xe2,0x5b,0xb8,0x86,0xb7,0x66,0xcf,0x0a,0xcc,0x6f,0xe8,0x02,0x22,0x4c,0x13,0x75,0xdc,0x68,0xf0,0x7c,0x0c,0x46,0x9a,0xa2,0x4c,0xf5,0x50,0x3f,0xf9,0xbc,0x01,0xb1,0xa1,0x28,0x90,0x07,0x6b,0x17,0x69,0x89,0x7b,0xe5,0x0a,0xf7,0x7b,0xe1,0x94,0x30,0xfc,0xd3,0x8d,0xd3 +.byte 0x99,0x37,0x91,0xd5,0xdf,0x59,0x2a,0x4f,0xfe,0x6c,0x37,0x4b,0x78,0x2c,0xa9,0x28,0x6a,0x5c,0xd6,0xe1,0x0b,0xad,0xae,0x62,0x7c,0x09,0xb8,0x90,0x3f,0x29,0x37,0x7b,0x79,0xee,0x55,0x02,0x05,0xef,0x28,0xa2,0xc7,0x07,0x2b,0xe6,0xab,0x87,0x9d,0x8f,0x4c,0x0f,0xc1,0x75,0x5d,0x88,0x7f,0x26,0xe0,0x1e,0xf8,0x3f,0xb5,0x2a,0x6c,0xe6 +.byte 0x7f,0x85,0xae,0x55,0x7b,0x58,0x34,0x4c,0x81,0x05,0x21,0xa1,0x5e,0xd7,0xb6,0x20,0x6e,0xf9,0x60,0x15,0xa4,0xb2,0x8f,0x68,0xd2,0x23,0x9f,0xbf,0xfa,0x6a,0xcb,0x87,0x7d,0x41,0x4a,0xae,0x28,0x4f,0x9e,0xbb,0x69,0x1c,0x37,0xb2,0xc9,0xd2,0x21,0xa1,0x2b,0x6b,0x5d,0xff,0xd6,0xdb,0x8f,0x21,0xd9,0x17,0xd6,0xe6,0x74,0xf2,0x20,0x0e +.byte 0x06,0xb5,0x0c,0xdc,0x74,0x4e,0x93,0xcb,0x27,0xc7,0x4b,0xf3,0xef,0x46,0xa8,0xf0,0x58,0x1c,0xa0,0x65,0x09,0x84,0xc7,0x2e,0xba,0x51,0xd9,0xd4,0x53,0x20,0xc7,0x20,0x85,0x93,0x2b,0xf3,0x42,0x93,0x7b,0x22,0x1c,0x8d,0x22,0x76,0xcf,0xde,0x6a,0xa1,0x76,0xea,0x65,0x20,0x2f,0x2e,0xdb,0x85,0xdd,0x73,0x43,0xf8,0xe0,0xe3,0x3a,0xe5 +.byte 0x02,0x57,0x96,0x54,0xbc,0xaf,0xa4,0xd5,0xda,0x9d,0x9d,0x8b,0x85,0x01,0x7c,0x72,0x03,0xfe,0x39,0x46,0xab,0x04,0xcc,0x62,0x71,0xf5,0xa5,0x67,0xd7,0xfc,0xc0,0xb6,0x95,0x74,0xdf,0x1c,0xfe,0x1c,0x5b,0x25,0xae,0x42,0x75,0x00,0x71,0x3c,0xec,0xfc,0x3c,0x7b,0x0f,0xec,0x44,0xc7,0xec,0x9b,0x86,0xf5,0x3d,0x47,0x15,0xf0,0x25,0xba +.byte 0x43,0xc8,0x68,0x15,0x4f,0xeb,0x35,0x76,0x2d,0x04,0xb7,0x9b,0xb8,0xa7,0x0d,0xb3,0xb4,0xf2,0x93,0x85,0xb1,0xb8,0x81,0x7c,0xd6,0x5f,0xbd,0xc2,0xcc,0xf4,0x0e,0x98,0x2c,0x06,0x54,0x2f,0x5e,0x49,0x94,0x93,0x78,0xa0,0x0a,0x33,0x2e,0x3f,0xb2,0xa7,0x81,0xed,0xe9,0xb6,0xb5,0x86,0x4b,0xa5,0xc0,0x51,0x30,0x9d,0xe2,0x9f,0xc2,0x56 +.byte 0x92,0x6b,0x96,0xca,0xcb,0x65,0x5c,0x0e,0xf4,0x91,0x2b,0x89,0xf4,0x27,0x55,0x26,0xd7,0x7b,0x00,0x19,0x1f,0x67,0x4e,0x43,0x24,0x81,0x05,0xb7,0xc6,0x41,0x1a,0x39,0x3d,0x40,0x3e,0x8a,0x03,0x94,0x63,0x1b,0xb1,0x87,0xb6,0xe1,0x52,0xd0,0xe8,0xbb,0x0e,0x37,0x72,0xe5,0xde,0x86,0xc0,0xdf,0x5b,0xc2,0xc6,0x0a,0x67,0xa7,0x4c,0x03 +.byte 0xb6,0xd8,0x7f,0x1d,0xb3,0xe3,0x84,0xb7,0x5c,0x04,0x15,0xe0,0xd0,0xae,0x44,0xac,0x39,0xa5,0xa2,0x86,0xc8,0xad,0x27,0xa0,0x36,0xa1,0x6e,0xaa,0x87,0x7a,0x43,0xae,0xa0,0x45,0x1a,0xac,0x04,0xe2,0x55,0xf2,0x9a,0x97,0x67,0xfb,0x01,0x8f,0xb8,0x80,0x9c,0x27,0x1d,0xbe,0xa3,0xf1,0x6d,0x66,0xf2,0x1a,0x99,0x99,0xf6,0xa5,0xba,0x58 +.byte 0x28,0x58,0xb5,0x44,0x5b,0x38,0x4a,0x3f,0x37,0x85,0x7e,0x36,0x8e,0x16,0xb9,0x1e,0x0b,0xbf,0x7d,0x0a,0x0c,0x83,0x53,0x0d,0xcc,0x37,0xe1,0x42,0xbb,0x0d,0xfc,0x01,0x25,0x10,0xbe,0xb5,0x83,0x2f,0xa5,0x42,0x98,0xbc,0xd6,0x50,0x75,0xda,0x32,0x2b,0x3f,0xd6,0xc1,0x1a,0xe7,0x0b,0x80,0x07,0x6f,0xfe,0x77,0x9e,0xe9,0x1e,0x45,0x65 +.byte 0x68,0x92,0x34,0x8b,0xce,0xf3,0xcd,0x94,0x17,0xe0,0x41,0x92,0x96,0xb5,0xd1,0x98,0xd1,0x25,0xd1,0x3d,0x76,0x88,0x86,0xb1,0x01,0x80,0xc7,0xde,0x60,0x20,0xb8,0x03,0xe7,0x3f,0x44,0x39,0xb1,0xb8,0x19,0x53,0x5a,0xc6,0xa0,0x18,0x8e,0x0e,0xb6,0xfd,0x7e,0xe7,0x7e,0x8a,0xeb,0x4c,0x35,0x4a,0x0f,0x52,0x81,0x68,0x12,0xe4,0x46,0x2e +.byte 0x20,0xb4,0x41,0x59,0xb3,0x16,0x02,0x9f,0xdb,0xe8,0xea,0xfd,0xe3,0x5d,0x14,0xd0,0x97,0x52,0x66,0xcb,0xb4,0x48,0xa3,0x05,0xab,0x73,0x8e,0x2c,0x46,0xc2,0x94,0xd5,0xc8,0x57,0xc4,0x13,0xa4,0x0b,0x7c,0x34,0xbf,0xb4,0x07,0x28,0x92,0xe2,0x1d,0x00,0xa6,0xf0,0xb0,0xbf,0xdd,0x5d,0x20,0x05,0x9f,0x53,0xcf,0x07,0xf7,0xe8,0x79,0x04 +.byte 0x57,0xd1,0xac,0x9c,0xdd,0xae,0xcd,0x8b,0x04,0x0a,0x2d,0x0a,0x0f,0x21,0x09,0xc8,0x0d,0xfa,0x23,0x26,0xe3,0xdb,0x84,0xc8,0x8e,0x9c,0x96,0x93,0x4f,0xcc,0x2f,0x96,0xed,0x04,0x91,0x0d,0xc7,0xbb,0x27,0xa3,0x6b,0x9d,0xe2,0x15,0x83,0x31,0x78,0xb5,0xb9,0x6d,0xb1,0x6c,0xa2,0x3e,0xf5,0x45,0x77,0xf4,0x96,0x3a,0xe6,0x10,0x08,0xfd +.byte 0x23,0xcc,0xda,0x27,0x73,0x67,0xbb,0x8b,0x59,0xe2,0xcf,0xda,0x57,0xf9,0x17,0xeb,0xeb,0x98,0x39,0x48,0xbf,0x3d,0x5b,0x7b,0xc2,0x11,0x4b,0xd6,0xb6,0x8a,0x14,0xb3,0xf5,0xc3,0x18,0xff,0xde,0x62,0x98,0x4a,0x1d,0x6b,0x4e,0x00,0x4f,0x7d,0x2f,0x67,0xf4,0x22,0x1e,0xdb,0x69,0xd5,0x87,0xfd,0xee,0x97,0x56,0xd4,0x00,0x0c,0x9e,0x22 +.byte 0x11,0xda,0x8e,0x3b,0x91,0xad,0xf1,0xb6,0x0a,0xba,0xe7,0xc6,0x14,0x0e,0xc4,0x85,0x5f,0x7d,0x69,0x7d,0x73,0x9c,0x83,0x6a,0x69,0xef,0x10,0xb0,0xe6,0x33,0x32,0x0f,0xd8,0x54,0xa4,0x9d,0x39,0xaf,0xfc,0x6d,0x4f,0xeb,0x34,0x89,0x2e,0xb0,0xa1,0xcd,0xe1,0x5b,0xab,0xe1,0xff,0x82,0x85,0x6b,0x5e,0xa9,0x9e,0x43,0x02,0x0d,0x38,0x33 +.byte 0xe1,0xbc,0xa4,0x77,0x8a,0x5e,0x54,0xa8,0xcf,0xc9,0x76,0xcb,0x73,0x21,0x1f,0xa7,0x1e,0x5c,0x0a,0xd6,0xa2,0x36,0x6f,0x07,0xa1,0x6b,0x0d,0x5a,0x21,0x3a,0xc3,0xc0,0xcd,0x9d,0xed,0x83,0x96,0x89,0xaa,0x55,0x56,0xfd,0x0a,0x97,0x3a,0x50,0xfd,0x95,0x3f,0xb7,0xfa,0x87,0x7d,0xa6,0x5d,0x12,0x65,0x3f,0x61,0x4f,0x86,0xdd,0x58,0x64 +.byte 0xd7,0xde,0xd6,0xb9,0x68,0x87,0xde,0xba,0x96,0xf5,0x1c,0xec,0x8e,0x81,0xfc,0xca,0x77,0xe2,0x85,0x11,0x93,0xc7,0xf2,0x0f,0x77,0xbb,0x7c,0xed,0x20,0x7a,0xe3,0xc5,0x76,0xff,0x04,0xc7,0xe6,0x7a,0xa1,0xfe,0x58,0x52,0x1b,0xec,0x27,0xbb,0xd4,0x27,0x7c,0xc7,0x4a,0xfb,0x07,0x62,0x99,0x36,0xff,0x6e,0x71,0x2f,0xbd,0x25,0xff,0x8d +.byte 0x97,0x14,0x56,0x23,0x7f,0x13,0x89,0x10,0xd8,0x29,0x1f,0x91,0x56,0x52,0x85,0xa7,0xd3,0x04,0xc9,0xe2,0x09,0xa2,0x0f,0xaa,0x28,0xb1,0x79,0xf9,0x08,0xf4,0x14,0x57,0xc4,0x54,0xd7,0x69,0xb0,0x37,0xf0,0x80,0x90,0xce,0x75,0x81,0xe7,0x75,0x0f,0x7f,0x71,0x58,0x3b,0x78,0x53,0x9b,0x4a,0x5e,0xcc,0x23,0x04,0x9e,0x0c,0xd7,0xd8,0x69 +.byte 0x90,0xdf,0x36,0x99,0x90,0xd3,0xfa,0x35,0xf7,0x13,0x64,0xb0,0xc0,0x70,0x0c,0xd4,0x87,0xc0,0xca,0xd8,0xca,0x8a,0xc3,0x9a,0xfa,0x73,0x34,0x18,0xe9,0x3a,0x85,0x42,0xc5,0xe1,0xaa,0xb5,0x87,0xac,0x43,0x9c,0xfa,0x7e,0x05,0x35,0xed,0x7e,0x0d,0x38,0x82,0x17,0x7f,0x22,0xa2,0x3d,0xd3,0x0d,0xd1,0xff,0x0a,0x68,0x52,0xd2,0x17,0x59 +.byte 0xaa,0x57,0xbd,0xd3,0xea,0x0c,0xe8,0xb0,0x22,0x13,0x59,0x42,0x46,0x34,0x58,0xa9,0x16,0xc5,0x9f,0x88,0x8f,0x75,0x02,0xbf,0x63,0xda,0x28,0xba,0x9a,0xcf,0xbb,0x73,0x58,0xb1,0x13,0xf2,0x68,0xd8,0x6b,0xfd,0x49,0x50,0xcf,0x09,0xea,0x6a,0xff,0x20,0x39,0xc5,0xae,0x70,0x79,0xea,0xec,0x9d,0x09,0xf8,0x51,0x1f,0xfd,0x01,0xd5,0x9f +.byte 0xec,0x29,0x36,0xfc,0x39,0xb4,0x4c,0x1f,0xe6,0xb4,0xcc,0x97,0x21,0xe5,0x19,0xe9,0x7a,0x60,0x6d,0x39,0x3c,0x31,0xd4,0x43,0x76,0xba,0x10,0xd9,0x3f,0x75,0x7a,0xa6,0x1d,0x02,0x88,0x3d,0xa5,0x9f,0x91,0x61,0x4e,0x32,0xec,0xf5,0xd3,0xe4,0x65,0xf7,0x0e,0x3b,0x8a,0x8f,0x22,0x31,0x71,0x8f,0xf1,0x5f,0x7b,0x04,0x88,0xf9,0x88,0x67 +.byte 0x14,0x85,0x74,0x9e,0x54,0x0b,0xed,0x7a,0x48,0xcd,0xcf,0xd2,0x05,0x38,0xd5,0x58,0xa2,0xaf,0x6a,0x28,0x21,0xfd,0x38,0x4e,0x83,0x06,0x15,0x60,0xfb,0x89,0x2a,0x72,0xfe,0x75,0xc7,0xa4,0xae,0xe4,0x5b,0xbb,0xde,0x54,0xde,0x77,0xbb,0x9d,0xd2,0x07,0x05,0x61,0x53,0x65,0x31,0xd4,0x3a,0x8a,0x7d,0x9d,0x30,0x09,0x25,0x28,0x72,0x19 +.byte 0xe4,0xae,0x1d,0xbf,0xa7,0xef,0x75,0xd0,0xe3,0xdc,0x0b,0xd1,0x17,0x9c,0xc6,0xdf,0x65,0x9a,0x7c,0x9d,0x0b,0x9a,0x3d,0x8f,0xb0,0xf5,0x51,0x46,0x6b,0x12,0x0d,0xe6,0xa9,0x3a,0xb5,0xe9,0x52,0x85,0xa5,0x25,0x1f,0xc9,0x8b,0xff,0xe3,0x37,0x25,0x97,0xd8,0x91,0x17,0xed,0xcf,0x2a,0x6d,0x4f,0xef,0x74,0x5e,0x92,0xa2,0x2d,0x84,0xa6 +.byte 0x09,0xc4,0xfc,0x36,0x95,0x54,0x25,0x9e,0xeb,0xd9,0xea,0x5a,0x01,0x0c,0x54,0xdb,0x82,0x01,0xed,0x0b,0xf7,0x9f,0x0d,0x8f,0x2e,0xee,0x7c,0x6e,0xb3,0xe7,0xe8,0x04,0xef,0x8d,0x5e,0xfe,0x3d,0x96,0x3a,0x65,0xd3,0xb2,0x11,0x75,0x1c,0x6f,0x2a,0xd3,0x26,0x1f,0x5f,0x35,0x02,0x0b,0x9f,0x38,0x5b,0xa5,0x3a,0x90,0x3e,0x03,0x9f,0x50 +.byte 0xf2,0xd7,0xe4,0x3c,0xd3,0x28,0x67,0x0a,0x5a,0xe8,0x59,0x6f,0x38,0x8f,0x8b,0x0d,0xe4,0x1c,0xfc,0x6e,0x07,0x69,0x7b,0xfb,0x04,0x30,0xe7,0xa6,0x13,0xfb,0x33,0xa0,0x52,0x6a,0xec,0x64,0xad,0x90,0xbd,0xba,0x15,0x12,0x48,0xed,0xd1,0x94,0x2d,0xe7,0x19,0x28,0x5e,0x7a,0x94,0xf4,0x79,0xd7,0x79,0xc9,0xf6,0x16,0xb4,0x88,0xee,0x15 +.byte 0xa2,0x68,0xe3,0x1d,0xd0,0xd2,0x63,0x78,0x7c,0xb3,0x30,0xac,0x63,0x7a,0x36,0xc5,0x50,0xbf,0x57,0xf6,0xfe,0x4e,0x43,0x4e,0xf9,0xc4,0xa2,0x2a,0xa7,0xa4,0x2c,0x18,0xb9,0x43,0x7b,0xe8,0xf6,0x14,0x4f,0x07,0x6e,0x65,0x9a,0xdd,0x10,0x2a,0x4c,0xa4,0x58,0x86,0x19,0xad,0x6d,0x5e,0x30,0xfb,0x5f,0xb6,0x9f,0x2a,0xac,0x90,0x0d,0xae +.byte 0xf9,0xab,0xc1,0x33,0xd3,0x73,0x1d,0x46,0xe5,0xc8,0x1e,0x1d,0x61,0xf1,0xda,0x53,0x3e,0x61,0xf0,0x9a,0xe4,0xb7,0x04,0xe9,0x5e,0xf6,0x11,0xa6,0x56,0x39,0xed,0xfb,0x06,0xd0,0x92,0xb9,0xb8,0xb5,0x3b,0x39,0xec,0xa5,0xc0,0xb1,0x7e,0x7e,0xfb,0x89,0x86,0xa8,0x70,0x47,0xa5,0x60,0x8c,0xf8,0x47,0x31,0x04,0x54,0x29,0xf3,0xa2,0x79 +.byte 0xac,0x24,0xda,0x33,0x6c,0x1c,0x34,0xc2,0xa0,0x96,0x27,0xbb,0x31,0xbf,0xc1,0xd9,0xc8,0x35,0xbc,0xb3,0x13,0x8a,0xb6,0x25,0x92,0xdc,0xcc,0x3b,0x8a,0x65,0xf3,0xf9,0xd1,0x2a,0xcd,0xb0,0xf4,0xd7,0x44,0xa0,0x27,0xfc,0x0e,0x69,0x46,0x0b,0x56,0x5b,0x58,0x40,0xd9,0xc4,0x37,0x9b,0x4d,0xa1,0x45,0xd8,0xab,0x4d,0x02,0x31,0x4f,0x93 +.byte 0x56,0xd0,0x26,0x99,0x1c,0xc7,0x2b,0xc2,0x80,0xb4,0xbd,0x6e,0xfe,0xa1,0xf7,0x8f,0x13,0x74,0x2c,0xa8,0x63,0xb1,0x3d,0x6d,0x32,0x4a,0x80,0x6a,0x7f,0xcf,0x6c,0x51,0xa9,0x21,0x34,0x4e,0x13,0x19,0x8f,0x33,0xfc,0x06,0x46,0x05,0xf0,0xcf,0xf1,0xce,0x20,0xe0,0x40,0xf2,0x0a,0xd0,0xf6,0xcc,0xcc,0xc2,0xc7,0x07,0x2e,0x9e,0x0a,0x1e +.byte 0x53,0x59,0xbb,0xe3,0x02,0xc8,0x20,0x9f,0x3c,0xe6,0xec,0xf7,0x8a,0x6d,0x3c,0x0f,0xb3,0x14,0x66,0x5c,0x51,0xbe,0x82,0xc2,0x0b,0x10,0x63,0xa9,0xd4,0x7f,0x12,0x88,0x13,0x81,0x8a,0x06,0x8a,0x7f,0xc8,0x89,0xe7,0xbd,0xce,0x51,0xdc,0x93,0x03,0x07,0x6f,0x8c,0xe6,0xcc,0x0d,0x45,0xa8,0xfc,0x02,0xe2,0x3e,0xa7,0xc8,0x83,0x77,0x98 +.byte 0x91,0x4e,0x1f,0x8d,0xed,0xa5,0x38,0x54,0x0e,0x4e,0x53,0x1c,0x0c,0x47,0x11,0x59,0x54,0x15,0xb5,0x47,0xb0,0x21,0xa1,0x3d,0xaa,0xef,0xee,0x9e,0x26,0x3c,0x39,0x75,0xff,0x1a,0x8c,0xbb,0x1a,0x49,0x62,0x21,0x76,0xe8,0x3d,0x10,0x55,0xf5,0x5a,0x44,0xf0,0xb3,0x81,0xd0,0x35,0x96,0x95,0x63,0xf7,0x50,0xb1,0xa0,0xf0,0x29,0x97,0xc9 +.byte 0x27,0x73,0xd8,0x29,0xef,0x74,0xd2,0x6d,0xf4,0xfb,0x72,0xa9,0x4f,0x12,0xd5,0xfd,0xc9,0xba,0xf0,0xbd,0xfd,0x5e,0x5c,0xfa,0x53,0xe3,0x96,0xab,0x57,0xc3,0xb6,0xe8,0x0e,0x43,0xe4,0x77,0x97,0x04,0x69,0xff,0x72,0xd0,0xd8,0xab,0xb9,0x19,0x25,0x89,0xf7,0xbb,0x01,0x03,0xf2,0xc6,0x8d,0xd5,0x86,0xe3,0xfe,0x9c,0xff,0x78,0xd7,0xfc +.byte 0xda,0xd4,0x69,0x8e,0xd6,0x31,0xfb,0x15,0xd3,0x38,0xfd,0x53,0xe2,0x4e,0xce,0xcc,0xfe,0x17,0xc5,0x88,0x92,0x28,0x98,0xb7,0xcf,0x7b,0x53,0x7b,0x96,0x14,0xaf,0xeb,0x5b,0x2d,0x16,0x41,0xcc,0x7b,0x65,0xe1,0x73,0x81,0x4e,0x8f,0xc3,0xad,0xe1,0x3f,0x0c,0xa7,0xbe,0x38,0xed,0x02,0x67,0xf5,0xfa,0x1d,0xb0,0xd5,0x4c,0xe1,0xd8,0x62 +.byte 0xc9,0xb5,0xf8,0x84,0xc4,0x51,0x57,0x14,0x11,0xf8,0x7d,0x1d,0xe7,0x81,0x85,0x61,0xa9,0x9f,0xc8,0x45,0xb9,0x2d,0x8a,0xc9,0xa3,0xfe,0x5a,0xf9,0xe0,0x1c,0x80,0xd8,0x77,0xaa,0x85,0xca,0x93,0x9a,0x2e,0x10,0x03,0x71,0x3d,0xb1,0x2a,0x64,0x2e,0xad,0x64,0xba,0x5c,0xaa,0x8a,0xc2,0x2a,0x80,0x28,0x2e,0xf9,0x93,0xe1,0x71,0x72,0xae +.byte 0xda,0xd8,0x4f,0x4c,0xec,0xb5,0xe3,0x05,0x10,0x5f,0x4c,0xe6,0xe1,0xf4,0x07,0x63,0x75,0x6f,0xc5,0xf9,0xcd,0xfc,0xfc,0x35,0x2f,0xe4,0xca,0x4b,0xfc,0xc3,0x20,0x8b,0x5c,0x4a,0x3c,0xf8,0x92,0xca,0x2b,0xb0,0xce,0xd9,0x4b,0xf0,0x44,0xcb,0x4e,0x83,0xf3,0x9d,0xb0,0xd4,0xab,0xba,0x2a,0x76,0xaa,0x87,0xcd,0xa2,0xd1,0x3f,0xa0,0xb9 +.byte 0xdb,0x7e,0x67,0x2d,0x92,0x4c,0xeb,0x3c,0xa6,0x8c,0x62,0x80,0x18,0x78,0x2b,0x9d,0x8f,0x5e,0xc3,0xa5,0x3b,0x10,0xb3,0x8a,0x3b,0x00,0x96,0xb2,0xab,0xce,0x8d,0xff,0x3c,0xee,0xeb,0x4f,0xfb,0xab,0x96,0x38,0x4c,0x15,0x6e,0x7c,0xf3,0x31,0x5f,0x8f,0x99,0x88,0x52,0x48,0x8b,0x71,0x1b,0x31,0x3f,0x7c,0xe4,0xae,0x9c,0x7b,0xeb,0x64 +.byte 0xe3,0x80,0xd4,0x56,0x9a,0x6a,0xd9,0xca,0xc5,0xf0,0x86,0xe7,0xda,0x80,0x8f,0x17,0x61,0xca,0x24,0x0b,0xb6,0xf9,0x24,0xc5,0x7a,0x28,0x42,0x32,0x7f,0x2b,0xde,0x44,0x30,0xed,0x69,0x63,0x07,0x3f,0xca,0x7b,0x02,0xea,0x6e,0xef,0x27,0x1d,0x76,0x32,0xc2,0x81,0x3d,0x03,0x9a,0xe7,0x0d,0x28,0x07,0x03,0x0c,0x65,0x73,0x58,0x26,0xc6 +.byte 0xfe,0xcc,0x33,0x7f,0x33,0xad,0xea,0x81,0x05,0xcc,0x61,0x1e,0x78,0x69,0x70,0xc9,0x1f,0x6e,0x4f,0xb8,0x19,0x42,0x03,0x03,0x9d,0x56,0x87,0x0e,0x9a,0x32,0x3a,0xba,0xb9,0x11,0x66,0x9f,0x4d,0xd1,0xb0,0x11,0xbf,0x46,0xfc,0xcf,0xe5,0xef,0xf1,0x61,0xeb,0xad,0x31,0x7c,0x0d,0x66,0x0d,0xa9,0x1f,0xe4,0xf9,0x80,0x9e,0xae,0x9e,0x34 +.byte 0x1e,0x95,0x6c,0xa2,0x77,0x69,0x84,0x77,0xb7,0xe8,0xca,0x1f,0xea,0xc1,0x34,0xe6,0x0d,0x4f,0xba,0x77,0x2b,0x8c,0xbe,0xff,0xc4,0x06,0xa3,0xb6,0x1a,0xbe,0x55,0x99,0x57,0x6f,0x54,0x24,0x93,0x7a,0x0d,0x52,0xd6,0xbb,0xd2,0x9c,0xd5,0x76,0x6a,0x22,0x66,0xdc,0x43,0x9a,0x7b,0x1b,0x11,0x80,0x02,0x0c,0x8f,0xc6,0xc6,0x02,0x42,0x29 +.byte 0x00,0xc4,0xb2,0xa1,0x6a,0x7f,0xa9,0x60,0x8d,0x41,0x4f,0xd3,0xde,0x33,0x5a,0x44,0x31,0xb0,0xdc,0xc0,0x0c,0x31,0x03,0x96,0x71,0x0a,0xce,0xe3,0x0b,0xc7,0xe3,0x5d,0xe0,0x88,0x4b,0xfd,0x4c,0x1a,0xce,0xaa,0x89,0xc6,0x99,0xa8,0xd3,0x1e,0xe9,0x6c,0x2a,0xbd,0x26,0x81,0x03,0x6a,0xf2,0xf2,0x0f,0x1e,0x9d,0x8a,0x59,0x45,0xbf,0x6d +.byte 0xb7,0xc8,0xec,0x77,0xb0,0x70,0x1a,0x31,0x21,0xeb,0x25,0x12,0xff,0x13,0x33,0x6b,0x47,0x34,0xd8,0x66,0x11,0x8a,0xc9,0x93,0x5b,0x2c,0x55,0x42,0xb2,0x9b,0x60,0xc6,0xba,0xab,0x12,0x12,0x5d,0x0a,0xd4,0x54,0x79,0x17,0x6d,0x31,0x7d,0x4f,0xf2,0x94,0x16,0x65,0x62,0x38,0x76,0x3a,0x7d,0x55,0x05,0xd9,0x17,0x45,0x62,0xb4,0x1d,0x31 +.byte 0x34,0x40,0xd3,0x8e,0xf9,0x29,0x4d,0x3f,0x93,0x9a,0x2e,0xa4,0x75,0x66,0xf6,0x62,0x8f,0xf9,0x8d,0x79,0x4b,0x51,0x7e,0xfb,0xeb,0x9a,0x86,0x96,0x01,0x79,0xbe,0xe4,0x42,0xb3,0xc8,0x28,0x9e,0xed,0xa8,0xb6,0x6d,0xd3,0x31,0xed,0x30,0x9e,0x6a,0x5b,0x02,0x4b,0xbd,0xb3,0xf2,0xf0,0x9d,0x50,0x09,0x40,0x71,0xfe,0x4b,0x91,0xc9,0xd6 +.byte 0x07,0x87,0x9e,0xdb,0xa9,0xcd,0x0b,0x95,0x18,0x5a,0x55,0x10,0xaa,0xe1,0x70,0xe9,0x2e,0xc2,0x31,0x6b,0x48,0x84,0x2f,0xe5,0x7b,0xdd,0x4c,0x03,0xed,0xb6,0xb6,0x64,0x24,0x38,0x7a,0x5a,0x15,0x35,0x9d,0x66,0x08,0x4d,0xa6,0x3c,0x96,0x1a,0xcd,0x02,0x61,0x40,0xde,0xac,0xc3,0x15,0x8c,0xca,0xe6,0x62,0xe9,0x61,0x68,0xf6,0x60,0xd3 +.byte 0x7e,0x5f,0x44,0xcf,0x09,0x01,0x60,0xc2,0xb1,0xfc,0x2f,0x41,0x4c,0xc1,0x06,0x72,0xcc,0xde,0x25,0xe0,0x8c,0x34,0xb8,0xe0,0xb2,0xeb,0x05,0x5d,0x9e,0x7e,0xf7,0x1e,0x24,0xcd,0x1b,0x14,0x3f,0x1b,0x13,0xc0,0x64,0x38,0x43,0x95,0xba,0x7b,0x61,0xa0,0xdc,0xe0,0xf5,0x80,0x13,0xa1,0xc5,0x48,0x92,0xc5,0xd5,0xd0,0x87,0x0c,0x73,0xae +.byte 0xe2,0xb3,0xe8,0x70,0x4a,0x7e,0xa0,0x13,0xc3,0xc6,0x9c,0x77,0x51,0xca,0x88,0xcf,0xe0,0x1e,0xff,0x6c,0xe2,0xc3,0x33,0xce,0x7f,0x3e,0x7d,0xd5,0x37,0x23,0x09,0xb7,0xbd,0xb7,0xec,0x9a,0x29,0xd6,0x4f,0xea,0x79,0x24,0x4c,0x09,0x74,0x9c,0x97,0x3b,0x08,0x1f,0x82,0xcc,0xae,0xc4,0x3f,0xcf,0xc6,0xcb,0xaf,0x8c,0x89,0x15,0x79,0xeb +.byte 0x88,0xb9,0x03,0xab,0xc6,0xf8,0x6e,0x54,0xde,0x50,0x6e,0xcf,0x8a,0x4b,0x3f,0x64,0xd0,0xcb,0x69,0xc2,0xe3,0x40,0x4a,0x94,0xe2,0x04,0xfa,0x9b,0x4a,0xf6,0x2b,0x93,0x0c,0x0e,0xf8,0x68,0xbc,0x6e,0x6c,0xe6,0xd9,0xb6,0x04,0x40,0xf4,0x60,0xbc,0xc1,0x1e,0x67,0x1f,0xce,0x5c,0x4d,0xba,0x78,0xa8,0xf5,0x96,0x00,0xb9,0x61,0x82,0x65 +.byte 0xb2,0x1d,0x42,0xb8,0x88,0x66,0x43,0xd9,0xfe,0xe0,0x86,0xef,0x5d,0x4d,0xcc,0xeb,0x57,0x9a,0x2b,0x27,0xf2,0xcf,0x68,0xc3,0x05,0x92,0x4d,0x4d,0xb7,0x46,0x7e,0xfd,0xb7,0x4a,0x4d,0x6f,0xac,0xc8,0x8d,0xf2,0xcd,0x52,0xcf,0x91,0x77,0x2d,0x68,0x06,0x7a,0xc9,0xf3,0x17,0xc6,0x8f,0x8f,0xb5,0x8f,0x74,0xfa,0x90,0xcc,0xfc,0xaf,0x4e +.byte 0xd2,0x29,0xd9,0x57,0x71,0xe9,0x52,0xd8,0x50,0xfa,0x4d,0x13,0x7c,0x42,0x15,0x22,0x65,0x26,0x08,0xda,0xaa,0x53,0xcf,0xeb,0xd1,0x87,0xd5,0x7c,0x4e,0x66,0x1c,0x7d,0xc9,0x03,0x59,0xf8,0x09,0x3e,0x1b,0x94,0x4c,0x39,0x56,0xeb,0xfd,0xb6,0xd0,0xf9,0x76,0x8b,0x5d,0x6e,0x44,0x15,0xcf,0x27,0x7f,0x69,0x9a,0x00,0x96,0xbe,0x80,0x5e +.byte 0xbb,0x5a,0x05,0xea,0x15,0xdd,0x44,0x69,0x9e,0x64,0xcd,0xba,0xf2,0x6f,0x67,0x10,0xc5,0xa1,0x75,0x85,0x5f,0xdc,0x61,0x43,0x34,0xc3,0x52,0x06,0xd4,0xe9,0x9f,0xdf,0xd4,0xa6,0x96,0xac,0xb1,0x21,0xdd,0x20,0x46,0x20,0x89,0x5f,0x0e,0x9d,0xa8,0xc7,0x75,0x3a,0x54,0x9e,0x7c,0x3a,0xd5,0xb2,0x68,0x77,0x06,0x1b,0x1c,0xbd,0xb3,0x02 +.byte 0xb5,0xdd,0x87,0x55,0x6b,0x00,0x9f,0x2c,0x30,0xb7,0x4e,0xc3,0x67,0x38,0x37,0x61,0x81,0x68,0xcb,0x14,0x81,0x27,0xd7,0x38,0x18,0x81,0x68,0x45,0xca,0xf4,0xaa,0xae,0x58,0x9e,0xf8,0xbe,0xe9,0x1e,0x05,0x19,0xf0,0xea,0x89,0xf8,0xa1,0x9c,0x7b,0x63,0xc1,0xcd,0x81,0xc8,0x95,0x56,0x81,0x81,0x29,0xb0,0x4d,0xbf,0xe6,0x8d,0xa3,0xb3 +.byte 0xfa,0xae,0x13,0xc8,0xca,0x4d,0x5c,0x5e,0xd9,0x17,0xf8,0x87,0xdb,0x5b,0xe2,0xd9,0xba,0xe3,0xe8,0xdb,0xcb,0x74,0x36,0x7e,0x0e,0x3a,0x94,0x6a,0xe9,0x9e,0x50,0x8e,0xf4,0xd4,0x15,0xb7,0x50,0x60,0x3f,0x14,0x72,0x41,0x9d,0x51,0x63,0x8c,0x31,0x95,0xf2,0xbc,0x14,0xc7,0x64,0x2c,0xee,0x0b,0xe6,0xde,0xf6,0x33,0x85,0x65,0x00,0x54 +.byte 0x54,0x84,0x85,0x94,0x87,0xa0,0xc3,0x95,0x4e,0x74,0xcb,0x2d,0x82,0x9e,0x46,0x7f,0xf5,0x64,0x60,0xfe,0x1a,0x37,0xee,0xa7,0xb6,0x85,0xb5,0x4e,0x30,0x11,0x39,0x4b,0xe9,0x57,0x18,0x3a,0x2c,0x6b,0xb9,0x8e,0x5a,0x54,0xa9,0x31,0xf7,0xe1,0xe0,0xc7,0x52,0xfe,0x76,0x9b,0xc6,0xfe,0xde,0xe0,0xe9,0xf9,0xf6,0x10,0xda,0xef,0x72,0x24 +.byte 0x9c,0xbe,0x4a,0xba,0x58,0x21,0x1b,0xe3,0x1d,0x80,0x10,0x76,0x70,0xde,0x8f,0xf3,0x07,0x93,0x01,0xe0,0xb4,0xd9,0x7d,0x60,0x0d,0x08,0x07,0xa4,0x6d,0x9b,0x2b,0x8c,0x9a,0x58,0x65,0x5e,0x29,0xf1,0x24,0xb2,0x31,0xfb,0xb7,0xad,0xf0,0x50,0x8e,0x25,0x1b,0x75,0xc5,0x82,0x88,0x8c,0x68,0x14,0x2c,0x28,0xa2,0xb6,0x93,0x14,0xe3,0x28 +.byte 0xd0,0x95,0x6f,0x79,0x91,0x03,0x75,0x82,0x5c,0x20,0x46,0x0d,0x53,0x40,0x2c,0x88,0x62,0xa4,0x8c,0xd5,0xf1,0xc1,0xbf,0xde,0x57,0x91,0xb2,0xa6,0x66,0x29,0xf0,0x6b,0xb8,0x5e,0x78,0x5f,0xd1,0x76,0x98,0xf2,0x56,0xc2,0x5f,0x48,0x1f,0xa6,0x98,0xb0,0x87,0x53,0x13,0x1d,0x1a,0xa7,0xdf,0xa5,0xea,0x37,0x12,0x6d,0x64,0x53,0xdc,0x04 +.byte 0x2d,0xb9,0xeb,0x78,0x89,0x7b,0x70,0xd2,0x6d,0x45,0x8d,0x45,0x50,0x57,0xc7,0xb2,0xaf,0xdd,0x72,0x0f,0x9f,0x1b,0x29,0x61,0x68,0xb5,0x4a,0xd4,0xe9,0xd7,0x10,0xe7,0xcd,0xe8,0x22,0xd3,0x54,0x0c,0x0b,0x32,0x77,0x7d,0x3e,0xed,0x6e,0x79,0x4b,0x7b,0x99,0x1f,0x9e,0xbe,0xe7,0x12,0x7c,0x94,0x36,0x1c,0x20,0x8a,0xd0,0xab,0xda,0x95 +.byte 0xf6,0x4f,0xbe,0x6f,0x44,0x0b,0xa3,0x7b,0x4d,0x00,0xf6,0xdf,0x6f,0xc8,0x50,0x9e,0x3e,0x0c,0x1e,0xfe,0xb8,0x39,0x9f,0x83,0x4f,0xb3,0x1f,0x7e,0x53,0x54,0x64,0x04,0xa3,0xf7,0x79,0x01,0x71,0xce,0x18,0x0d,0x47,0x4e,0xae,0x88,0x6a,0xe7,0x26,0x4e,0x59,0xee,0x3a,0x03,0xc2,0x4d,0x0c,0x29,0xf0,0x96,0x9d,0xc0,0xa3,0xb3,0x82,0xf9 +.byte 0xc4,0xf8,0x8b,0xae,0x68,0x47,0x39,0xdc,0x10,0xd7,0x09,0xb4,0x86,0x87,0xfa,0x7e,0x0c,0xe4,0xee,0x3a,0x35,0x1a,0x0e,0x95,0x88,0xce,0xe7,0x9e,0xcc,0xa5,0x58,0x98,0x48,0xbd,0x9c,0x27,0xe6,0xb9,0xf7,0xca,0x66,0xee,0x54,0x87,0xd0,0x6d,0xab,0x31,0x1a,0x57,0x33,0x8b,0x89,0xa0,0xc0,0x18,0x9a,0x87,0x5e,0x58,0x02,0xe5,0x50,0x47 +.byte 0x0f,0x60,0x53,0x9d,0x99,0xe4,0x0a,0xfa,0x4a,0xc3,0x77,0x4b,0x4d,0x4e,0x0c,0xbb,0x68,0xd9,0xb3,0xd3,0x59,0x78,0xdf,0x65,0x97,0x6e,0x22,0x5b,0x24,0x26,0xf9,0x2a,0x14,0x73,0xa7,0xec,0x65,0xfc,0xdf,0x7d,0x35,0x0d,0x44,0x1b,0x4b,0xad,0x6b,0x8f,0x0e,0xa3,0x3b,0x6b,0x40,0xb3,0xe3,0xd9,0x41,0xba,0xbf,0x95,0xbb,0x6e,0x91,0xf6 +.byte 0x63,0xb3,0xde,0xdb,0xc2,0x6f,0xfe,0x00,0xf1,0x53,0x96,0x37,0xa4,0x27,0x48,0x3e,0xf9,0x32,0x23,0x90,0x90,0xe0,0x01,0xde,0x08,0xad,0xc4,0x6c,0x25,0x7a,0x7f,0x2f,0xb7,0xb7,0xc6,0xaf,0xeb,0x91,0x9c,0xa2,0x9c,0xf7,0x7f,0x9f,0x74,0x9b,0x7d,0x54,0x66,0xf9,0xe0,0x73,0xb4,0x15,0x2b,0xaa,0x71,0x50,0xd0,0x74,0x5d,0xcd,0x1c,0x09 +.byte 0x4c,0x80,0xcc,0xdc,0x10,0xd9,0x96,0xb3,0xdc,0x09,0x73,0x1f,0x36,0x4c,0x1b,0x86,0x25,0x13,0x7c,0xd2,0xc6,0x9d,0x5a,0xce,0xd6,0x22,0x97,0x66,0x7b,0x7b,0x84,0xba,0x69,0xd2,0x87,0x9b,0x08,0xda,0x77,0x66,0x90,0xbc,0x7c,0x3c,0x5d,0x43,0x92,0x5f,0x05,0xfb,0x23,0x46,0x88,0xf7,0xa4,0x10,0xbd,0x7d,0x00,0x29,0x2d,0xa5,0x6a,0xab +.byte 0xcc,0xdd,0xcf,0x1e,0x2b,0x9b,0x5f,0xa9,0x94,0x14,0x99,0x6e,0x3b,0x41,0x52,0x61,0x16,0x17,0x44,0xcf,0x5b,0x34,0x5c,0x27,0x29,0x4a,0xc3,0xba,0x9a,0x0c,0x20,0x17,0x2b,0x92,0xd9,0xf1,0x76,0x51,0xd8,0xa5,0x4a,0x4b,0x4a,0x0b,0xe4,0x6b,0x93,0x61,0xc7,0xb3,0x23,0x7a,0x24,0xfa,0x5e,0xee,0x80,0x10,0x65,0x44,0xa5,0xed,0x72,0xd9 +.byte 0x8a,0x06,0x2a,0x86,0xa9,0x26,0x50,0xa1,0xb2,0xb2,0x8b,0x7b,0x4a,0x29,0xf1,0x18,0xef,0xff,0x61,0xf1,0xa1,0x48,0x0f,0x84,0x8c,0xef,0xd8,0x02,0x65,0x44,0x11,0xf2,0xe1,0xba,0x98,0x03,0xbe,0x5a,0x5d,0xb8,0x0a,0x88,0xd8,0x4a,0x49,0x4c,0x70,0xa6,0x98,0x81,0x36,0x56,0x92,0xde,0xcb,0xaf,0x33,0xf5,0x1c,0x0a,0xce,0x7a,0xc0,0xff +.byte 0x24,0x54,0xd3,0x9a,0x0f,0x82,0x76,0xe5,0x0e,0x82,0xb4,0xfe,0xc2,0xac,0xe4,0xba,0xa3,0x4c,0x8a,0x0d,0xa7,0x3e,0x2b,0x71,0x73,0x5f,0xd2,0x35,0xd3,0xae,0xc0,0x3e,0x6f,0x67,0x98,0x51,0xa6,0xdf,0xb2,0xf4,0xd2,0xc1,0x43,0xe2,0x0a,0x7c,0xa0,0xb6,0xff,0xfc,0xc0,0x88,0xe5,0x34,0x20,0x79,0x50,0xc3,0x06,0x5b,0x20,0x9f,0x05,0x33 +.byte 0x22,0x30,0xaf,0xc4,0xc3,0x17,0x09,0xbb,0x30,0x0f,0x42,0xb7,0xc1,0xe0,0x4c,0x71,0xc5,0xf7,0x96,0xb4,0xd4,0x0f,0x44,0x47,0xa3,0x06,0x17,0xbd,0x0f,0x7c,0xc6,0x53,0x07,0x34,0x9a,0x9a,0x2f,0x3f,0x01,0xea,0xdf,0x1c,0x06,0x33,0x15,0x9c,0x5a,0xe3,0x33,0x29,0xce,0x40,0x4b,0xb1,0x99,0xe0,0x80,0x6e,0x0c,0xa1,0x4c,0x34,0x01,0x21 +.byte 0x12,0xbe,0x67,0x26,0xe6,0xdb,0xab,0x8d,0x45,0xdd,0x12,0x60,0x02,0x1a,0xdd,0x85,0xd6,0x33,0x78,0x23,0xe1,0x58,0x2a,0x46,0xf0,0xc2,0x4d,0x71,0x59,0x5b,0x8d,0x65,0xa7,0x97,0xf4,0x71,0x88,0x7d,0x60,0xe0,0x2d,0x2d,0x09,0x2f,0x26,0x15,0xa7,0xbf,0x30,0x0b,0x99,0x08,0xd7,0x85,0xfc,0x0c,0x19,0x31,0xde,0x5e,0x55,0x91,0x13,0x45 +.byte 0x3a,0x6d,0xd0,0x61,0x02,0x81,0xa0,0x42,0x7d,0xd8,0x7d,0x41,0x11,0xd2,0x25,0xb7,0x15,0xa1,0x16,0x3e,0x70,0x77,0x1b,0x80,0xb7,0xf1,0x24,0x8e,0x70,0x8d,0x73,0x6d,0xba,0xf1,0x46,0x32,0x60,0xe4,0xc8,0x4d,0x69,0xc8,0x10,0xf8,0x2d,0x53,0xe1,0x81,0x96,0x20,0x9d,0x59,0x74,0xae,0x93,0x92,0x44,0x5a,0x09,0x79,0x20,0xcb,0xff,0xb2 +.byte 0x08,0x7a,0x81,0xee,0x98,0x83,0x0b,0xa4,0x15,0xb0,0xaa,0x55,0xb0,0xb5,0x60,0x09,0x21,0xeb,0xe2,0x9b,0x57,0x41,0xb9,0xb4,0xd9,0xbe,0x7d,0x60,0x5d,0x25,0xde,0x9f,0x9e,0x5b,0x7c,0xee,0xeb,0x87,0x54,0x6a,0xc3,0xcf,0xec,0x57,0xce,0x97,0x2e,0x47,0x84,0x4c,0x15,0xf4,0xf5,0xe9,0xd4,0x45,0x23,0x20,0xf0,0x0f,0xda,0x97,0xc2,0xb9 +.byte 0xb2,0xe2,0x44,0xea,0xbd,0x95,0x73,0xcc,0x94,0x03,0x0b,0x97,0xeb,0x03,0xc1,0x51,0xc8,0x14,0xa6,0x7d,0x18,0x30,0xa1,0xda,0xa3,0xcd,0x78,0x67,0xb0,0xc1,0x6c,0x88,0xdd,0xd6,0x52,0x4b,0x85,0x1d,0x4a,0xaa,0x44,0xec,0x3b,0xff,0x00,0xd8,0x9e,0x18,0xf8,0xac,0x4f,0x73,0x6d,0xc7,0x4b,0x59,0x15,0x85,0x87,0x02,0xd8,0xf1,0xe6,0xfb +.byte 0x66,0x57,0xcf,0x06,0x84,0x50,0xc5,0x67,0x94,0xc6,0x96,0xb2,0x1a,0x37,0x06,0x3d,0x21,0xf2,0x1e,0xb4,0xe7,0xcb,0x36,0x8b,0xa3,0xe3,0x84,0xa0,0x9a,0x31,0xdb,0x87,0xf9,0xb0,0xef,0x06,0xfe,0xb0,0x8a,0x32,0x53,0xb4,0x41,0x79,0x6b,0xf7,0x7c,0xf7,0x9c,0xc1,0xea,0x61,0xf3,0x75,0xac,0x1f,0x92,0x75,0x44,0x58,0x9a,0x20,0xa4,0x20 +.byte 0xe3,0x19,0x1c,0x0d,0x27,0xe5,0x2e,0xbd,0x14,0xcb,0x40,0x3f,0x1c,0x19,0x7c,0xf9,0x92,0x13,0x1a,0x71,0x87,0xaf,0x77,0x0f,0x50,0x92,0x06,0x75,0x2d,0x75,0xe0,0x2e,0x37,0x54,0xcd,0xac,0xcb,0xca,0x7c,0x0e,0x66,0x53,0x10,0x50,0x70,0x9a,0xa4,0x79,0x76,0x87,0x71,0x4a,0x55,0xd4,0xa3,0x83,0xb3,0x04,0xed,0xa9,0xd6,0x84,0x7d,0x1a +.byte 0x64,0x5d,0xf7,0x4f,0x55,0x97,0x5e,0x26,0x9c,0x03,0x42,0x0a,0x16,0xd3,0xdf,0xc8,0x07,0xb8,0xb3,0xe9,0xac,0xa9,0x99,0x83,0x32,0x5b,0x83,0xde,0x7f,0x2b,0x70,0xca,0x15,0x09,0x33,0x0e,0x28,0xc9,0x89,0xc6,0xa6,0x47,0xd1,0x56,0x04,0x40,0x5d,0xd2,0x17,0x1d,0x32,0x21,0x6d,0xb2,0xc7,0x89,0x14,0x98,0xc6,0x58,0xc4,0xca,0xda,0x0f +.byte 0x32,0xdd,0xe1,0xe1,0x9a,0x25,0x09,0x31,0x16,0xf1,0x48,0x40,0x1c,0xc2,0xf9,0xd0,0xba,0xec,0x07,0x94,0xea,0x17,0xcf,0x6e,0xbc,0xfd,0x70,0xb4,0xbb,0x40,0xae,0xc3,0xae,0xf7,0x56,0xf5,0x13,0x55,0xfb,0x4b,0x81,0x5d,0xab,0xf2,0x3f,0xd7,0xa7,0xe6,0xcf,0x17,0xef,0x1f,0x71,0x1b,0x92,0x67,0xd3,0xd2,0xed,0x89,0x14,0x8f,0x8d,0x83 +.byte 0xef,0x7f,0xca,0x65,0x6d,0x79,0x13,0x5f,0x6e,0xf9,0x5d,0x9a,0x68,0x54,0x71,0x5c,0x9d,0x03,0x7c,0x73,0x7a,0xc2,0x17,0x9b,0x5a,0x7d,0x45,0x24,0x0c,0x41,0x13,0xe4,0xcb,0xdb,0x7b,0xc6,0xfb,0x93,0x48,0xca,0xd3,0x01,0x68,0x3f,0x36,0xc0,0x4b,0x1d,0xfa,0x9f,0x25,0x0e,0xcc,0xd0,0xf7,0xa0,0x7a,0x14,0xac,0xd7,0x6e,0x00,0x9f,0xf1 +.byte 0xc0,0xdc,0xfc,0x3b,0xd9,0xbf,0x68,0xfd,0x65,0x34,0x66,0x18,0xe5,0x02,0x9a,0x2d,0xff,0xaa,0xf7,0x73,0x58,0x21,0xe3,0xff,0x23,0x0f,0x63,0x1f,0xf3,0x8b,0x08,0xc7,0x00,0x46,0xe7,0xef,0x85,0x5f,0x7f,0xd9,0x5f,0xc2,0x36,0xe2,0xb6,0xa3,0x00,0xcb,0xff,0xe0,0x22,0x28,0x8c,0xb1,0xb1,0x17,0x91,0x4a,0x4a,0xc8,0x77,0x5a,0xa9,0xb2 +.byte 0x6e,0xb7,0xf0,0x4f,0x70,0x34,0x7f,0x87,0x2a,0x0c,0xcb,0x16,0x24,0x9b,0x41,0xb2,0x3e,0x0a,0xc1,0x33,0xf3,0xbb,0x48,0x17,0x2f,0xe6,0xfc,0xf4,0x27,0xc0,0xdb,0x58,0x24,0x9b,0x99,0x43,0x25,0xfb,0xd3,0xcf,0x1c,0x5a,0x5f,0xbe,0x28,0x3a,0x84,0x51,0x19,0xc3,0x53,0x6b,0xc8,0x73,0x44,0x6e,0x3d,0x7e,0x01,0x37,0xc2,0x2b,0xf7,0xa8 +.byte 0x1f,0x8e,0xd8,0x02,0x5a,0xae,0x56,0x81,0x2b,0x46,0x1b,0x7d,0xca,0x27,0x1f,0x48,0x99,0x24,0x54,0x59,0x08,0xfd,0xb7,0xdf,0x0a,0x77,0xef,0x4e,0x89,0x21,0x71,0x71,0x3f,0x8c,0xd7,0x52,0x89,0x7a,0x0d,0x68,0x09,0xc8,0x88,0x9c,0x0c,0x60,0xca,0x77,0x96,0xeb,0x05,0xeb,0xeb,0x60,0x5b,0x68,0x51,0x2c,0xcb,0x8f,0xca,0x3b,0x18,0x39 +.byte 0x28,0x8f,0xda,0x17,0x9b,0x53,0x71,0x26,0xa9,0x19,0xfb,0x1e,0x4a,0xd0,0x14,0x93,0x1c,0xee,0xe1,0x21,0xea,0xb3,0x16,0x47,0xaf,0x50,0xe5,0xe5,0xd3,0x21,0x8c,0x67,0x46,0x5d,0x97,0x19,0xda,0x6e,0xd9,0x70,0x7d,0x9f,0xd6,0x25,0xd0,0xfb,0x01,0x62,0x0a,0x9e,0x49,0x3d,0x33,0x0d,0x35,0xe5,0xae,0xfd,0xeb,0xb5,0x9b,0xd8,0xc1,0x2a +.byte 0xee,0x4d,0xf2,0xfc,0x16,0x51,0xab,0x58,0x7a,0x9e,0x5c,0xca,0x0a,0x92,0xbb,0xbb,0xa8,0x5b,0xfb,0xf9,0x33,0x67,0x0e,0x13,0x4c,0x83,0x3a,0x25,0x84,0x23,0xe1,0x41,0xfb,0xf1,0x42,0xc1,0x8d,0x58,0x0c,0x5e,0x75,0x09,0x34,0x58,0x96,0x32,0x54,0xb6,0xd8,0xaa,0x48,0xc1,0xed,0xc0,0x92,0x5a,0xec,0xeb,0xb1,0x75,0x59,0xf6,0x35,0xf5 +.byte 0xfd,0x7d,0x96,0x9b,0x83,0x38,0x31,0x10,0xa4,0xd7,0xfb,0x28,0xf0,0xc9,0xe4,0x33,0x5d,0x66,0x81,0x9c,0x31,0x9a,0xe9,0x9a,0x5e,0x70,0xf7,0x61,0xf9,0x93,0xaf,0x2b,0xbd,0x78,0x9e,0xdc,0x61,0xe0,0xa9,0xd1,0xa0,0x8e,0x3a,0x5f,0xb1,0x71,0xe7,0x9e,0xfd,0x81,0xee,0xf0,0xd6,0x63,0xec,0x4a,0xca,0x30,0xaf,0xb6,0x2d,0xaa,0x2d,0xa1 +.byte 0x5a,0x38,0xb5,0xc6,0x3f,0x5f,0x63,0x48,0xd3,0x18,0xeb,0xe3,0x36,0xca,0x91,0x86,0x4b,0x6f,0x57,0x66,0x47,0x2f,0xce,0xe4,0x44,0x26,0xe4,0xfd,0x8c,0xde,0x74,0xdc,0x17,0x0e,0x7d,0x6a,0xcf,0x89,0x0e,0x7f,0x09,0x65,0xf8,0xeb,0x58,0x00,0x3d,0xc5,0x1b,0x14,0xc5,0xca,0xca,0x28,0xbc,0xb7,0x63,0x6f,0x3b,0xa4,0x62,0x23,0x0e,0xd5 +.byte 0x04,0x76,0x0c,0xe8,0xea,0x64,0x10,0x3a,0x76,0x03,0xd6,0xea,0x69,0x52,0x14,0xa7,0x5e,0x40,0x7e,0x14,0xdb,0x7f,0xbf,0xe8,0xf6,0xf0,0xdd,0x5e,0xac,0x55,0x44,0xfb,0x28,0xf3,0x16,0xcb,0xed,0x8f,0x10,0x01,0x91,0xac,0x2c,0x27,0x46,0x0c,0x51,0xd6,0xf6,0x30,0xa3,0x34,0xd0,0x5e,0x93,0xe8,0x4e,0xc0,0xb4,0x9b,0xc1,0xe8,0x20,0x7d +.byte 0xb7,0x68,0xdd,0xf1,0xc4,0x60,0x20,0x97,0xdd,0x5c,0x7c,0x9b,0xea,0xc0,0x22,0x84,0x2c,0x65,0x78,0xbd,0x18,0xa1,0x62,0x7e,0x06,0x49,0x96,0xde,0xd1,0x89,0x06,0x0d,0x35,0xa0,0xcc,0x22,0xd3,0xf5,0xa6,0x4b,0xb6,0xca,0x43,0x34,0x5a,0x3d,0x39,0x95,0x0b,0x95,0xbe,0xdc,0xe6,0x61,0x72,0xbe,0x2f,0x19,0x1c,0xe8,0x22,0x5e,0x18,0xc9 +.byte 0x59,0x4a,0x08,0xa3,0x85,0x5c,0x06,0x36,0x00,0x2e,0x84,0x3e,0x3e,0x07,0x5b,0xfa,0xda,0xbb,0xbb,0x57,0x20,0x6f,0x1b,0x8d,0xe5,0xc5,0xdb,0x8d,0x23,0x1a,0xfc,0x67,0xa9,0xc8,0xea,0xe1,0x54,0xbb,0x8a,0x8a,0x0b,0xa6,0x02,0x35,0xd6,0xd5,0x4d,0xff,0x09,0x79,0x31,0x9a,0xc2,0xad,0xa7,0x66,0xb5,0x3c,0xbd,0xb7,0xcb,0x17,0x30,0x4b +.byte 0x56,0xf5,0xd2,0x51,0x90,0xbb,0x47,0x00,0xc0,0xf3,0x8b,0xd7,0x10,0x33,0x6d,0xe8,0xe4,0xcf,0xd6,0xbf,0x35,0x75,0x8d,0x40,0x55,0xd7,0x5d,0xb0,0x40,0xf6,0x95,0xfb,0x1a,0x97,0x24,0xb8,0xc1,0x91,0x5f,0x66,0x6c,0xc7,0xdb,0x16,0xba,0xb8,0x07,0xf8,0xf8,0x91,0xb2,0x8c,0x26,0xb9,0xa2,0x59,0xb0,0xde,0x49,0x63,0xcc,0x7c,0x4c,0x48 +.byte 0xb5,0xe4,0xf9,0x81,0x28,0x48,0x9f,0xa0,0xa4,0xf8,0x0d,0xcc,0x7b,0xf3,0xce,0x08,0x85,0x73,0x4a,0x64,0xfc,0xa8,0xc0,0xae,0x7a,0xbf,0xa5,0x3f,0x45,0xaf,0xe7,0x7f,0x41,0x61,0x34,0x08,0x6e,0x09,0x0d,0x9d,0xea,0x90,0xbe,0x62,0x7c,0x38,0x92,0xa7,0x63,0xfa,0x03,0x80,0x10,0xc4,0x53,0x46,0x0b,0x44,0x88,0xea,0x50,0xb6,0x82,0xf8 +.byte 0x0b,0x2d,0x93,0x63,0x82,0x80,0x2b,0x61,0x3e,0x17,0xd1,0xd8,0x6c,0xb1,0xb4,0xbd,0xfd,0xad,0x1c,0x10,0x30,0xc1,0x78,0xd4,0x5f,0x21,0x49,0x54,0x7a,0x08,0x2b,0x25,0x3b,0xc9,0xb7,0x0a,0xf2,0x37,0x83,0xc0,0x43,0x73,0xee,0xd6,0x8b,0x92,0x15,0xde,0xfe,0x14,0xf1,0xfb,0x8b,0x4a,0x85,0x8d,0x78,0xe6,0x36,0x1a,0xbb,0x32,0x6c,0xdd +.byte 0x43,0x76,0xad,0x68,0x90,0x08,0xd2,0xbd,0x24,0x41,0xd4,0x93,0x17,0xa8,0x9f,0xeb,0x33,0x25,0x1f,0x1a,0xfd,0x45,0x20,0xc1,0x47,0xf1,0x25,0x09,0x89,0x14,0x9e,0x4c,0x88,0xa4,0x1c,0xb8,0xba,0x84,0xd5,0x7d,0x73,0xb2,0x9c,0x48,0x9f,0x84,0x31,0xd3,0x2c,0xe1,0x94,0x61,0x3e,0x5f,0x37,0x25,0xc7,0xb7,0x2d,0xc3,0xa9,0xaf,0xcc,0x0e +.byte 0xe6,0xc7,0x9a,0xa7,0x06,0xe3,0x41,0xb8,0xa6,0xa8,0x9a,0xe7,0x76,0xef,0x83,0x5a,0x80,0xa4,0xe3,0x0c,0x04,0xa2,0x0b,0x91,0x33,0x34,0x17,0xa4,0x02,0x2d,0x12,0x84,0x67,0x85,0x6b,0xc0,0x3a,0x0d,0x16,0xf2,0x66,0x04,0x71,0xe9,0xec,0xa6,0xbb,0x58,0x42,0x92,0x70,0xf5,0x0d,0x52,0xcd,0x1e,0x2d,0xd4,0x28,0x0f,0x68,0x35,0xd9,0xa4 +.byte 0x40,0x09,0x30,0xe9,0xbb,0xaf,0x77,0x63,0x4f,0xba,0x56,0x97,0xe8,0x92,0xcc,0xba,0xdb,0xe4,0xe0,0xdf,0x19,0x21,0x71,0x23,0x3d,0xd0,0xb1,0x25,0xd3,0xf8,0x53,0x01,0x30,0x9a,0xea,0x84,0x1b,0x18,0x68,0x4a,0xb9,0x9e,0x60,0xc4,0xfc,0xf7,0x56,0xb7,0x49,0xe1,0x50,0x38,0x7d,0x3d,0x87,0xa2,0xad,0x38,0x5c,0x0c,0x53,0x21,0xa0,0x56 +.byte 0x3a,0x94,0xd7,0xa8,0x23,0x96,0xa9,0x66,0x4e,0x88,0xae,0x4b,0x6e,0xcb,0xc6,0xa6,0xdb,0x1f,0x2e,0xae,0xe7,0x24,0xe2,0x1e,0xf7,0x3a,0x14,0x48,0x5e,0xfa,0x90,0x0a,0x84,0xa6,0x1c,0xaa,0x60,0xc0,0x2c,0x69,0xe8,0x36,0xb3,0xee,0x55,0x2a,0xf7,0x90,0xa1,0x92,0x4f,0x29,0x1e,0x49,0x6e,0x73,0x22,0x1f,0x8b,0x0c,0xb6,0xf4,0x3c,0xbf +.byte 0x82,0x47,0x49,0xc3,0x94,0x0e,0xcf,0x9b,0x86,0x88,0xc2,0xd0,0xd7,0xa7,0x43,0xfb,0x89,0x4b,0xbd,0x5d,0x4c,0x6b,0x7a,0xc7,0x74,0x1b,0xfb,0x48,0x12,0x68,0x61,0x91,0xf9,0xf3,0xb6,0x7f,0x4f,0x72,0x89,0xf0,0x72,0x46,0xf7,0x6f,0x84,0xd1,0x38,0x6d,0xd9,0x1b,0xa5,0xd1,0xe2,0x29,0xe0,0xa6,0xbf,0x1c,0xbd,0xfb,0xdd,0xdc,0xa5,0xae +.byte 0x7a,0x9c,0xd0,0xc3,0xfa,0x6f,0x72,0xa3,0xa2,0x8b,0x87,0x0d,0x9a,0x6a,0xfc,0x53,0x9a,0x08,0x61,0x86,0x67,0x2a,0x90,0x6a,0x09,0x20,0x8e,0xde,0x32,0x35,0x34,0x75,0xc0,0xa8,0xab,0x1b,0xc4,0x7c,0xc8,0xd9,0x90,0xcf,0x32,0x27,0x6c,0x68,0xf9,0x18,0x14,0x05,0x57,0x39,0xc6,0x9e,0x5e,0x38,0x07,0xdb,0x81,0xb4,0xa4,0x54,0x06,0xd6 +.byte 0x79,0x78,0x0e,0xc8,0xb9,0x56,0xda,0x08,0x2e,0x77,0x26,0xcc,0xf7,0xa5,0x2d,0xd8,0x91,0xa6,0xfc,0x25,0x0e,0x91,0xdd,0x3c,0xa8,0x14,0x7a,0x95,0x05,0x5b,0x15,0x7d,0x1d,0x9b,0x3c,0x8c,0xfd,0xdc,0xa5,0xcd,0xec,0xea,0x7a,0x2b,0x7e,0x79,0x21,0x54,0xea,0x7f,0x52,0xb4,0xbb,0x4f,0x07,0x95,0x39,0x4a,0xaf,0x2e,0xb4,0x1e,0x9e,0xc6 +.byte 0x0a,0x07,0x58,0xd4,0xa5,0x44,0x73,0xa8,0x84,0x26,0x67,0xb8,0x0f,0xc7,0x6b,0xa7,0x28,0xf6,0x05,0x91,0x3e,0x22,0xcd,0xd7,0xf5,0xfc,0xae,0x22,0x42,0x96,0x3b,0x57,0x91,0xce,0x44,0xd0,0xfd,0xc3,0x4c,0x8b,0x8b,0x67,0xfe,0x03,0x86,0x92,0x34,0xf7,0xf9,0x53,0xb3,0xdf,0x36,0xcf,0x16,0x1c,0x68,0x36,0x17,0x1f,0x41,0x56,0x1d,0xda +.byte 0x90,0xb3,0xab,0x03,0x97,0x88,0x23,0x65,0x89,0x72,0xe3,0x6d,0x8e,0x37,0x5d,0xee,0x89,0x81,0x11,0x27,0x8b,0xf0,0x9b,0xef,0xa2,0x34,0x45,0xcc,0x41,0xcf,0x2a,0x88,0x70,0xe4,0x78,0xfc,0xe1,0xb5,0x51,0x70,0x84,0x64,0xd1,0x10,0x71,0x5d,0xa4,0xb4,0x6d,0xb5,0x98,0x6e,0xcc,0x9a,0x62,0x14,0x30,0xce,0x1a,0xff,0x49,0xd6,0xaa,0xcc +.byte 0xe1,0x99,0x42,0xb1,0xfe,0x77,0x8a,0x2d,0xdb,0xc0,0x0d,0x50,0x53,0x0d,0x92,0xe5,0x2b,0xd0,0x78,0x83,0x08,0x4a,0x0c,0x1d,0x5b,0x03,0x22,0x65,0x3d,0x9e,0xdb,0xcf,0x01,0x61,0xf7,0x6d,0x2b,0x99,0xef,0xba,0x80,0x50,0xda,0xda,0x2d,0xbf,0x00,0xdf,0x6f,0xec,0x95,0xbc,0x5b,0x4e,0xda,0x83,0xe4,0x5d,0xf0,0xa7,0x1b,0x27,0xf1,0x76 +.byte 0x04,0x5d,0x3d,0x2c,0x12,0x15,0xad,0xef,0x47,0xdc,0x22,0x9b,0xc2,0x80,0x91,0xf3,0xbf,0x16,0xe9,0xd3,0x35,0x94,0x4b,0xfd,0xa3,0xa1,0xee,0x98,0xad,0x99,0xea,0x07,0xe1,0x0f,0xa7,0xbd,0x0b,0xfb,0xc0,0xd5,0xb0,0x49,0x37,0xc6,0x5f,0xe7,0x18,0xc1,0x60,0xe9,0x1d,0x5e,0x0e,0xea,0x73,0xf2,0xa1,0x75,0x7e,0x39,0x51,0x07,0x1e,0xcb +.byte 0x2a,0x5b,0x26,0x75,0xbe,0x02,0x5e,0xde,0x6c,0x37,0xb1,0x3c,0x1f,0x25,0x65,0x7d,0x9e,0x5d,0xa1,0x0b,0x98,0x27,0x53,0xb9,0xbb,0xc2,0x3e,0x8d,0x2d,0x5e,0x5c,0xbf,0xed,0x66,0xe8,0xd1,0x7d,0xaa,0xef,0xca,0x0e,0xd0,0x78,0x2b,0x89,0x07,0x76,0xb6,0xc3,0x92,0x42,0x3a,0x84,0x1d,0x81,0xc1,0xe8,0x1a,0xb8,0xe6,0xf1,0x43,0xcc,0x7a +.byte 0x59,0x4d,0x9f,0x00,0xfe,0x6a,0xe5,0x42,0x71,0x3c,0xcb,0xc8,0x45,0x18,0xf0,0xf2,0x81,0x9d,0x5a,0xb7,0x8d,0xbe,0x31,0xcb,0x7d,0xca,0xb7,0x19,0x57,0xb1,0x61,0x36,0x90,0x42,0xe2,0xc3,0xf5,0xa5,0x4b,0xc3,0xd4,0xe7,0x6c,0xb6,0x0c,0x06,0x19,0x4b,0x54,0x8f,0x2d,0xdc,0xc5,0x2b,0xff,0x1c,0x61,0x29,0xda,0x95,0x4f,0xa1,0x21,0x25 +.byte 0x24,0xbe,0xc7,0x34,0x2f,0xbf,0x33,0x6d,0x82,0x8f,0xf1,0xa9,0x97,0x5a,0x49,0x7f,0x60,0x00,0xf2,0x3e,0x7b,0x64,0xdf,0xc8,0xd3,0x5f,0x6e,0x1f,0xfb,0x71,0x80,0xf3,0x55,0x42,0xbe,0x32,0x7b,0xa9,0xeb,0xf6,0x31,0xe2,0xf0,0xd1,0xe9,0xbe,0x96,0x0e,0xb3,0xdf,0x3e,0xb2,0x2c,0xc3,0xce,0xbd,0xe7,0xfe,0x1c,0xed,0x2c,0x0b,0xaa,0x32 +.byte 0x76,0x82,0xb4,0x6b,0x18,0xa7,0x68,0x19,0xb7,0x27,0x21,0x4c,0xb0,0x22,0x98,0x58,0xd5,0x90,0x80,0xab,0xa1,0xfe,0x83,0xc5,0x66,0xf6,0x3e,0xa2,0xa9,0x6f,0x73,0xce,0x7f,0x0c,0xe6,0xde,0xee,0xb0,0xe6,0x2a,0xcc,0xcc,0xb0,0x53,0x8c,0xce,0xc8,0xdc,0xea,0x83,0xb4,0x0e,0x69,0x8d,0x90,0x86,0xaa,0xe3,0x3b,0xfb,0x88,0xe2,0xe8,0x27 +.byte 0x65,0x36,0x07,0xb3,0x91,0x0e,0x5a,0x6b,0x9f,0x0f,0xbd,0x81,0xb3,0x54,0x65,0x71,0xa4,0x2c,0x8e,0xda,0x47,0x04,0xce,0xfe,0x00,0x52,0xf1,0xdf,0x82,0x27,0x70,0x2a,0xb1,0x79,0x2f,0x27,0x7f,0xae,0x9e,0x5c,0x36,0xec,0xa0,0x2a,0xf3,0x74,0x78,0x01,0x17,0x74,0x2a,0x21,0x4f,0xb8,0xd2,0xe4,0xfe,0x5b,0x06,0x14,0xa5,0xb1,0xb1,0xff +.byte 0xee,0x79,0xf7,0x18,0xb9,0x31,0xa4,0x63,0x47,0x1c,0xdf,0x38,0x04,0x2d,0x18,0xca,0x14,0xf8,0x2f,0xec,0x0d,0x58,0xad,0xbb,0xf4,0x45,0x11,0x0e,0xfa,0x17,0x4c,0x5e,0xd4,0xa6,0xde,0xe4,0x13,0x44,0x2c,0xb9,0xfd,0xcd,0x41,0xe7,0xf9,0xda,0xbc,0x28,0x8f,0x0c,0x41,0x4d,0xa7,0x0d,0xf5,0x96,0xd7,0x8f,0x10,0x96,0xfb,0x75,0x75,0x86 +.byte 0xc9,0x6e,0x23,0x92,0x71,0x69,0x7b,0x94,0x61,0x1c,0x3f,0xcf,0x66,0x34,0x62,0x68,0x5d,0xee,0x7b,0x34,0x5d,0x2a,0x39,0xbb,0x6a,0x34,0xea,0x6e,0xe3,0xe9,0xdb,0xe4,0x34,0x6e,0x29,0x0b,0x21,0x38,0xe7,0x5b,0x79,0x37,0x54,0xf0,0xed,0xaa,0x07,0x2b,0x21,0x29,0x67,0xfe,0x7d,0xa5,0x99,0x0e,0x5d,0x05,0xe7,0x61,0x6e,0xd1,0x4a,0x15 +.byte 0x4a,0x56,0xb1,0x13,0x49,0x8c,0xf4,0x4f,0xd7,0xe9,0x68,0xae,0x09,0x37,0xd3,0x96,0x21,0xe8,0x1f,0x9f,0xa9,0xc6,0x54,0x57,0x63,0x09,0x1e,0x71,0xf2,0x48,0x9e,0x50,0xbb,0xb3,0xf1,0x4e,0x2d,0x1d,0x79,0x69,0x0a,0xa2,0xa9,0xdd,0x1b,0x55,0x62,0x6b,0x0d,0xcc,0x9c,0xb1,0x5e,0xc8,0x4c,0x4f,0x62,0x3c,0xc4,0xa3,0xb4,0xe4,0x34,0xec +.byte 0x9d,0x0c,0x1b,0x46,0x60,0x68,0xd5,0x04,0xd7,0x1b,0x3c,0x7a,0x98,0x0c,0xd9,0x87,0x2b,0x4f,0x97,0x5b,0x56,0x65,0xb0,0x06,0x6e,0x9e,0x06,0x37,0x0e,0xd2,0xa1,0x52,0xf5,0xaa,0x2b,0xec,0xbd,0x0f,0xb6,0xba,0x48,0x63,0x57,0x51,0xe3,0x00,0x53,0xf5,0x77,0xb2,0xa4,0xb1,0x44,0x01,0x3e,0xcf,0xe9,0x2a,0x7a,0xf5,0x19,0x5e,0x43,0x36 +.byte 0xe0,0x38,0x41,0xbc,0xda,0xb5,0xd0,0x69,0xdf,0xd2,0x04,0xd4,0xf8,0x38,0x37,0x1c,0x90,0x30,0xf2,0x3d,0x03,0xe4,0x3f,0x84,0x2c,0x9a,0xa4,0x8a,0x00,0x4e,0x49,0x24,0x62,0x06,0xb4,0x9d,0x33,0x8a,0x8e,0xd2,0xbd,0x1b,0xa1,0x83,0x0b,0xa5,0xa2,0x5c,0xcf,0xb1,0x65,0x85,0x92,0x1f,0xb0,0x2e,0x3b,0xb2,0xf3,0x80,0xff,0x9d,0x41,0x4d +.byte 0xcd,0x25,0x09,0x02,0x85,0xb3,0xa8,0x49,0x12,0x10,0xe7,0x5c,0x94,0x13,0x4b,0x52,0x53,0x35,0x9c,0xbc,0x7a,0xad,0x04,0x19,0x54,0x8a,0xbc,0x42,0x73,0xf1,0x0a,0x22,0x75,0xbf,0x3b,0x12,0xa8,0xa4,0x47,0x5c,0x95,0x48,0x60,0x71,0x5c,0x9a,0x39,0x5c,0xdb,0x44,0xe8,0x74,0x92,0x3e,0x2b,0x3b,0x1b,0xb7,0x21,0x98,0xe1,0x87,0x32,0xaf +.byte 0x4a,0xe3,0xda,0x4a,0x46,0xde,0x15,0x4c,0xdc,0xc6,0x60,0xe6,0xd7,0x92,0x29,0x05,0x21,0x22,0x9b,0xaf,0xc4,0xd7,0x6a,0xea,0x2c,0x82,0x5d,0xc7,0x81,0xe2,0x67,0x85,0xd2,0x16,0x6f,0x83,0xa8,0x82,0x5f,0x8f,0xf5,0x3a,0x50,0xba,0x04,0xcb,0x76,0x4d,0x80,0x16,0x12,0x72,0xa8,0x6c,0xac,0x78,0xf1,0x8c,0x93,0xab,0xe0,0xb5,0xdc,0xd1 +.byte 0xa5,0x40,0x0e,0x50,0x88,0xd2,0x9d,0x56,0xf6,0xa0,0xd4,0x45,0xcf,0xef,0x16,0x1a,0xa4,0xaa,0x91,0x5c,0xa3,0x8f,0x84,0xf8,0x3e,0x30,0x1f,0x5f,0x55,0xf9,0xd3,0x3d,0xb8,0x64,0xbb,0x3c,0x91,0xe4,0x0d,0xa5,0x43,0x14,0x75,0xe7,0xec,0x8c,0x12,0x56,0x34,0xb0,0xa9,0xae,0x93,0x91,0x34,0xfc,0x78,0xa3,0x81,0x51,0x45,0x7d,0x9f,0x7d +.byte 0x5e,0xc7,0x5e,0x51,0x17,0xfa,0x02,0x5d,0xb2,0xf7,0x79,0x4b,0x49,0xd2,0x1b,0x6f,0xfd,0x9e,0xff,0x75,0x74,0xf0,0x26,0x7e,0xd7,0x65,0xb0,0xf3,0x0a,0x0c,0xd2,0xa2,0x26,0x98,0x03,0x26,0xb5,0x67,0xc4,0xc0,0xed,0x80,0xd4,0x20,0xf6,0x7e,0x17,0x54,0xeb,0xde,0xc3,0x86,0x51,0xda,0xf7,0xe5,0xc7,0xfe,0xfc,0x71,0x83,0x80,0xbe,0xde +.byte 0x4b,0xda,0x83,0x76,0x63,0x04,0x03,0xdd,0xe0,0xe0,0x4e,0xb6,0x32,0xd5,0xd0,0xce,0xd7,0xaa,0xcd,0x5f,0x64,0xa6,0xd8,0x9e,0xc5,0x97,0x30,0xad,0xf1,0x82,0x8f,0x7c,0x18,0xec,0x30,0x1d,0x2d,0xb6,0xdb,0x33,0x65,0xed,0xe2,0x24,0xd8,0xba,0x0a,0x1f,0x79,0x2a,0x1c,0xe1,0x4e,0x04,0xa6,0x74,0x74,0x37,0x42,0x94,0xc4,0x99,0x0e,0xf8 +.byte 0x3f,0xf3,0xff,0xeb,0x7f,0x95,0x9c,0x47,0x56,0x68,0x6a,0x0d,0x6e,0x66,0x71,0x3b,0x51,0xd5,0x12,0x7e,0x59,0x39,0x43,0xb5,0x53,0xd3,0x1d,0xa2,0xe9,0xa1,0xc8,0x8d,0xf2,0x8e,0xa1,0x9c,0x36,0xdd,0xda,0xd3,0x61,0xd8,0xe9,0x76,0x5e,0xcb,0x0a,0x52,0xc8,0x5a,0x25,0x00,0x21,0xea,0x6a,0x96,0xde,0x02,0x76,0x02,0x63,0x73,0x28,0x63 +.byte 0x46,0x37,0xe1,0x75,0x2f,0x42,0x8f,0xee,0x2c,0x84,0x82,0x43,0x43,0x2d,0xa9,0x13,0x50,0x46,0x54,0xed,0x76,0xbd,0x10,0x1c,0x9b,0xa1,0x42,0x97,0x68,0xca,0x84,0x2e,0x1d,0x6f,0x86,0x67,0xaf,0xb7,0x20,0xc1,0x7c,0xab,0x70,0x20,0xa1,0x79,0x71,0xe4,0xb7,0x45,0x8a,0x04,0xd3,0x70,0x10,0xa8,0x28,0xc3,0x56,0xff,0x43,0x36,0x13,0x88 +.byte 0xb6,0x2d,0xfd,0x7f,0xbc,0xc9,0x1d,0x11,0x9a,0x7c,0xd0,0xfc,0x11,0xac,0x54,0xd5,0xc3,0x03,0xd1,0xe3,0x9e,0xff,0x03,0xdb,0xd9,0xd8,0x77,0x96,0x08,0xf4,0x1b,0xd9,0xfa,0x70,0xed,0xab,0x53,0x78,0xca,0x28,0xa7,0x29,0x49,0x45,0x37,0x10,0x8f,0x61,0x7d,0x11,0x99,0x2e,0xe8,0x5d,0x45,0x3a,0xe7,0xd2,0x6c,0xb6,0x03,0xc4,0x6d,0xaa +.byte 0x52,0x60,0x8c,0xc6,0x9c,0x17,0xba,0xf6,0x3b,0xd4,0x4b,0x26,0x63,0x92,0x8c,0xb9,0x6a,0xf2,0x26,0x91,0x9d,0x8d,0x99,0x39,0x26,0x7d,0xb5,0x4f,0x4c,0xc6,0x0e,0x2e,0xe1,0xc6,0xcb,0x98,0x93,0x71,0x9b,0xaa,0x01,0x40,0x70,0x93,0x2a,0xe8,0x27,0xc5,0x20,0xa7,0xd2,0x06,0x8b,0xb0,0x29,0xcd,0x4f,0x2c,0x5a,0xde,0x35,0xc7,0x2a,0x8e +.byte 0xa7,0xae,0x02,0xfa,0x8e,0x4d,0xf3,0x77,0x67,0xe0,0xcb,0x84,0x69,0xc6,0x05,0xe4,0x84,0xe3,0x6e,0x02,0x6c,0x3b,0x93,0x30,0x3e,0x89,0x2c,0xc7,0xa5,0x7e,0xaa,0x58,0x59,0x25,0xf6,0xff,0x56,0x9a,0x4a,0x70,0xbf,0x88,0x20,0x8d,0x51,0x5e,0x08,0x13,0x26,0x2c,0x5d,0x88,0x13,0x3e,0x32,0x7a,0xf6,0x17,0x5c,0xdb,0xc4,0xcd,0x5a,0x16 +.byte 0x65,0xe4,0x34,0xeb,0x21,0x6d,0xb9,0x30,0x5d,0xc0,0xa2,0xea,0x4f,0x63,0x0e,0xbe,0x32,0x91,0x89,0x6f,0x96,0x40,0xf3,0x5f,0xa3,0xf2,0x15,0xc3,0x3c,0x3c,0xb8,0x2f,0x0d,0xc2,0xcd,0x4e,0xa0,0xa5,0xf6,0x78,0x40,0x0b,0x90,0x11,0x52,0xff,0x8f,0x7f,0x6a,0x0c,0xd6,0x3b,0x64,0x80,0x47,0xfa,0x70,0xbe,0x01,0xdc,0xdf,0x5b,0x75,0x7c +.byte 0xca,0x66,0xf0,0x2a,0x53,0x89,0x55,0x87,0xf8,0xec,0xd1,0x18,0x22,0x0c,0xd5,0x0e,0xc8,0x1c,0xbc,0x1e,0x66,0x14,0x44,0x10,0x3c,0xd4,0x2e,0xca,0x0b,0xd8,0x3f,0x81,0xd8,0x9f,0x81,0xf6,0x62,0x23,0xe4,0xc7,0x0d,0xb0,0x1b,0x00,0xd8,0xf4,0x1a,0xdd,0x9b,0xa1,0x74,0xeb,0xf0,0x65,0x5c,0x82,0x00,0x17,0xa6,0x68,0x29,0xd5,0xa4,0x64 +.byte 0xd3,0x15,0x90,0xd0,0x91,0x17,0xfc,0xd2,0xd7,0xad,0x4b,0xd8,0x41,0x03,0x51,0xfd,0x61,0xac,0x34,0xd4,0xff,0xaa,0xb1,0x64,0x6c,0x79,0x78,0xf7,0x6b,0x18,0x03,0x2b,0x6b,0x9a,0xd7,0xce,0x55,0x6e,0xdd,0xab,0x2e,0xbc,0x27,0x3a,0x8c,0xa5,0x8d,0xf0,0x55,0x81,0x0c,0x6e,0x8d,0xd8,0xd2,0x24,0x5e,0x2e,0x56,0xa8,0x1e,0x9c,0x98,0x88 +.byte 0xd3,0xbe,0x90,0x56,0x70,0xe5,0xcc,0x49,0x2a,0x13,0x98,0x99,0xbd,0xc9,0x9f,0x53,0x85,0x07,0xbe,0x54,0xa7,0x4c,0xd6,0x96,0x7d,0x8f,0x24,0x79,0x67,0xb2,0x62,0x4c,0x6a,0xc1,0x6c,0xb7,0xdc,0xe9,0x21,0xe3,0x27,0xc7,0x53,0xff,0xe7,0xd1,0xea,0x60,0xa8,0x56,0x08,0x5c,0x29,0x0a,0x04,0x0c,0xda,0x7a,0x70,0x8c,0x3d,0x55,0x3f,0xcf +.byte 0x9e,0xea,0x74,0x8b,0xbc,0xf0,0xf1,0x3a,0x86,0x22,0xe5,0x54,0xa7,0x70,0xc2,0xcd,0xb8,0x9f,0x4e,0x9f,0x48,0xa8,0xc0,0x82,0x0d,0x73,0x8b,0x3c,0xfc,0x20,0xf4,0xbe,0x79,0xde,0x8e,0x3c,0x26,0x85,0xde,0x74,0xd1,0xe3,0xd5,0x8f,0x39,0x71,0x46,0x8c,0xbd,0x68,0x28,0x2d,0x36,0x0d,0x66,0xc1,0x0b,0x96,0x3e,0x11,0x2e,0x44,0x17,0xd5 +.byte 0xfe,0x0d,0x70,0x84,0x96,0x20,0x34,0x2f,0xbe,0xf0,0xf5,0x9b,0xb4,0x5a,0xa9,0x50,0x6a,0xda,0xdb,0x69,0xea,0xef,0xa9,0xaa,0x06,0xc0,0x68,0xa4,0x61,0x1b,0x4b,0xf8,0x0b,0x56,0x91,0xc8,0x6f,0x39,0x15,0xe2,0xcc,0xbf,0x2b,0x36,0x96,0x0c,0x84,0xfb,0x3d,0x4b,0x09,0xe3,0xc2,0x4b,0x05,0x5e,0xfa,0x30,0x75,0xc5,0x54,0xa5,0xbd,0x45 +.byte 0x1e,0x14,0x72,0xd6,0xfd,0xe0,0x8f,0x7b,0x46,0x9b,0x11,0x07,0x27,0x03,0xe1,0x2d,0xcc,0x0a,0x01,0x49,0x61,0xc4,0x61,0x78,0x06,0x5f,0xaa,0x01,0x5b,0x68,0xd7,0x29,0xb4,0x9e,0xd3,0xaf,0xc7,0x45,0xf0,0x23,0xaf,0x28,0xcd,0x96,0x23,0x61,0xb2,0xb4,0x21,0x96,0x5d,0x91,0x3e,0x71,0xb5,0x41,0xf1,0x29,0xf4,0x5b,0x45,0x77,0x16,0x00 +.byte 0x9d,0x39,0x2a,0x1c,0x38,0x6d,0x36,0x97,0x98,0x4c,0x84,0xfc,0xf5,0xf1,0x59,0x7a,0x8c,0x21,0xfb,0xbc,0x9b,0x0c,0x8d,0x60,0xb6,0xc4,0xe3,0x4b,0x33,0x4f,0x04,0x4c,0x27,0xd2,0xa0,0xe1,0x71,0x0b,0x6d,0x40,0x8d,0xba,0xb3,0x11,0x9b,0x07,0x97,0x82,0x01,0x47,0xaa,0x2a,0xd4,0xcc,0x02,0xd3,0x86,0x86,0xb5,0xd7,0x5d,0xbc,0xd0,0x0f +.byte 0x97,0x5c,0xe5,0xac,0xc6,0x53,0xb3,0x39,0x09,0x68,0x2e,0xcc,0xf3,0x43,0xba,0xed,0x15,0x90,0xbe,0x9d,0xeb,0xa4,0xfb,0x4a,0x20,0xcf,0x10,0xb9,0x47,0x99,0xb0,0x89,0x26,0xb9,0xbd,0x4b,0xf6,0xa5,0xbd,0x2f,0xad,0x1a,0x75,0xe8,0xff,0xc6,0x6b,0x6a,0x31,0xbe,0xec,0xd2,0xc4,0x39,0x9e,0x3b,0x05,0x3f,0x24,0xba,0xf1,0x4d,0x0c,0x0c +.byte 0x05,0x60,0x60,0x22,0x0c,0x1b,0x0b,0x6c,0x80,0xd5,0xe8,0x8f,0x81,0xee,0x80,0x41,0x4a,0x69,0x47,0xc6,0x4c,0xeb,0xf6,0x2b,0x91,0x7c,0x9f,0x22,0x74,0x7b,0x43,0x95,0x56,0x55,0xba,0x85,0x23,0xb3,0xc3,0xee,0x6a,0xcc,0x49,0x2c,0x6c,0x86,0x6d,0x60,0x5d,0x84,0x0c,0x3c,0x88,0x61,0x58,0x1d,0xfc,0x00,0x2c,0x84,0x49,0x4d,0x95,0x75 +.byte 0xc0,0x03,0x02,0x59,0xc0,0xe9,0x84,0xea,0xce,0x3f,0x8b,0x76,0xbf,0x19,0xaa,0x13,0x1b,0x8d,0x9f,0xb2,0xeb,0xb3,0x02,0x87,0xee,0xfe,0x73,0xdb,0xc4,0x19,0x27,0xaf,0x15,0x8d,0xf4,0x58,0x97,0x43,0xb9,0x45,0x32,0x5f,0x24,0x2d,0x08,0xfe,0xec,0xf2,0xf1,0x34,0x99,0x7a,0x66,0x44,0x3d,0xd4,0xf7,0x82,0xcf,0xca,0x6f,0x53,0x9f,0x0a +.byte 0x74,0x79,0x9b,0x45,0x5b,0x07,0x92,0x35,0xc6,0xf4,0xd1,0x90,0x2b,0x62,0xec,0x93,0x7b,0x05,0x90,0x75,0xb7,0xb6,0xd9,0x6c,0x30,0xdd,0x9b,0x2a,0x32,0xb1,0xba,0xab,0x1a,0x6c,0x2b,0xd8,0xfb,0x39,0x8e,0x80,0x98,0x6c,0xd0,0xb3,0xf3,0x76,0xe2,0xe6,0x5e,0xee,0xd0,0x29,0xd7,0x57,0x8f,0xc3,0x13,0xcb,0x45,0x90,0x3e,0xa2,0x54,0x88 +.byte 0xd5,0x50,0xd3,0x75,0xed,0x2d,0xa6,0x50,0x11,0x6b,0xb0,0xb6,0xf0,0x1d,0xc9,0x3d,0x1d,0x2a,0xda,0x5e,0x43,0x44,0xf4,0xef,0x3e,0xc7,0xa9,0xe0,0x6d,0x3c,0x38,0xbf,0x84,0x72,0xaf,0xea,0x60,0x15,0x03,0x14,0x77,0xb7,0xb3,0x15,0x4c,0xbc,0xbf,0x55,0x86,0x24,0x73,0x97,0x22,0x9d,0x59,0xa0,0x39,0x76,0x38,0xd1,0x1f,0x25,0xb0,0x64 +.byte 0xf3,0x10,0x67,0xf2,0x7c,0x11,0xf2,0xce,0xbe,0xaf,0x5e,0x2e,0xc5,0xc1,0x01,0xfa,0x80,0xf9,0x87,0xfc,0x5c,0xfd,0x66,0x50,0x01,0xc2,0x00,0x92,0x84,0x0f,0xdc,0xfc,0x10,0xa5,0x6e,0x45,0xf5,0xff,0x58,0x78,0x45,0x5e,0x50,0xbe,0xe3,0xc7,0x25,0x1e,0xdf,0x7f,0x68,0x6f,0xa5,0xb8,0xf8,0x69,0x89,0x5a,0x55,0x65,0xf4,0x96,0xe5,0x7a +.byte 0xa6,0x89,0x69,0x8d,0xdd,0x4f,0x24,0x5a,0x29,0x92,0x1e,0xca,0x74,0x65,0x7f,0xb8,0x32,0x75,0xb5,0x7b,0x15,0xea,0xeb,0xcc,0xf1,0x23,0x69,0xc7,0x58,0x1c,0x3a,0xaa,0x27,0x0a,0x11,0x79,0xcf,0xc9,0xb6,0xbd,0x9d,0x56,0x47,0x36,0x6b,0x7f,0x82,0xb5,0xa7,0x9f,0x79,0x72,0x16,0xba,0x50,0xef,0x37,0x68,0xdf,0xe0,0xd8,0x0c,0x16,0xcc +.byte 0x50,0x6c,0x25,0x63,0xc2,0xd6,0x7b,0xef,0xd9,0xa1,0xef,0x62,0x81,0x97,0x51,0x49,0x69,0xe3,0x13,0x6c,0x1a,0xd0,0x64,0x1b,0x3e,0x48,0x25,0x5b,0x34,0xe9,0xee,0x41,0x34,0xfb,0x8e,0x9d,0x3c,0xbc,0xc8,0xcf,0xe7,0xf8,0x72,0x21,0x0f,0x95,0xde,0x57,0xd7,0x2f,0x80,0x97,0xbd,0x8f,0x2c,0xde,0x19,0xa3,0xba,0x5c,0x92,0xa3,0x75,0x83 +.byte 0xe3,0xc9,0x33,0x3f,0x8f,0x09,0xfa,0x0b,0x60,0x0a,0x2f,0xb3,0x45,0x9d,0x8e,0x9d,0xa3,0x66,0x2d,0xda,0x37,0xe0,0x21,0x52,0x74,0x9d,0x59,0xa4,0x9e,0xea,0x15,0x22,0xb0,0xbf,0x3c,0xd4,0x59,0xef,0x27,0x60,0xf7,0xbf,0x5d,0x1d,0x36,0x9a,0xa5,0xfb,0x53,0x90,0x40,0x83,0x3a,0x20,0x3d,0x6b,0x47,0xbc,0xc3,0xe6,0x07,0xfe,0xd0,0x8e +.byte 0x40,0x42,0x65,0x2b,0x27,0xba,0x69,0x61,0x03,0x36,0x58,0x35,0x7e,0x82,0x53,0xb5,0xe2,0x25,0x31,0xc3,0x77,0xc1,0x91,0x13,0xa4,0x92,0x52,0xea,0x9f,0x43,0x44,0x6b,0x43,0xe9,0x11,0xd4,0x3d,0x53,0xba,0x6b,0x96,0xb5,0x96,0x29,0xa3,0x2a,0x0a,0xf2,0xb5,0x0c,0x5d,0x62,0x37,0xe0,0xd6,0xa2,0xbf,0xcd,0xf9,0x58,0x7f,0xa2,0xfd,0x54 +.byte 0x6a,0xa1,0x90,0xa5,0x61,0x9e,0xa6,0xc2,0xb9,0x80,0x7a,0xb8,0xaf,0x60,0x68,0xa7,0x27,0x77,0x41,0x03,0x4e,0xc1,0x96,0x46,0x23,0x1b,0xff,0xa1,0x37,0x28,0x33,0x27,0xc2,0x99,0xf7,0xcb,0x7f,0x1a,0xfb,0x41,0xc3,0x59,0x11,0xf8,0x39,0x50,0xbd,0x90,0x61,0x4a,0x67,0x4a,0x07,0x5f,0xb1,0x07,0x66,0x0b,0x52,0xad,0x90,0xc2,0xd7,0x4e +.byte 0x42,0x9e,0xcc,0x5c,0xeb,0xf2,0xdc,0xaa,0x52,0xcf,0x0e,0x7d,0xae,0x3e,0x1a,0x2c,0x9e,0x79,0xfb,0x29,0x10,0x29,0x61,0xa4,0x93,0x9d,0xa9,0xe9,0x71,0xc5,0xf7,0x07,0x13,0xe9,0xbd,0x2e,0x2d,0x0c,0xd6,0xaf,0x54,0x48,0x58,0xc2,0x91,0x37,0xf4,0x61,0x3a,0x96,0x81,0xdc,0x82,0x02,0xff,0xc9,0xf7,0xf7,0x9f,0x9f,0x28,0xd1,0xb1,0xe3 +.byte 0x2b,0x3d,0x85,0xef,0x15,0x82,0x3b,0x9a,0x17,0xee,0x7f,0xd3,0xa5,0x7c,0x41,0x27,0xc9,0x4c,0xe9,0x7a,0x30,0x9f,0xc5,0x34,0xaf,0xc8,0x1c,0x8a,0x7c,0xa6,0xf4,0xdc,0xa6,0xdb,0x68,0xc1,0xa1,0x13,0xb0,0x54,0x49,0x25,0x43,0xc0,0xd4,0x93,0xd6,0x70,0x53,0x3e,0x5f,0xd5,0x42,0x6e,0x78,0xb8,0x15,0x07,0x6a,0x91,0xe8,0xf1,0x2f,0xcf +.byte 0x07,0x84,0x25,0xb3,0x20,0xb9,0x35,0x25,0xbb,0x26,0x96,0x02,0x25,0xd5,0x83,0x23,0x71,0x6d,0x62,0xa7,0x99,0x73,0x63,0x2a,0x51,0x25,0x34,0x3d,0x51,0x95,0xc7,0x9b,0x01,0x0a,0xab,0x11,0xb2,0x32,0xcd,0xe3,0xef,0x63,0xa4,0x6d,0xdb,0x7b,0xf6,0x5f,0xc5,0xf3,0xe5,0x8c,0x6b,0x0a,0x04,0x33,0x53,0x0d,0xf6,0x13,0x8c,0xb8,0xc7,0xba +.byte 0xc2,0xf0,0xd4,0xa7,0x1a,0xce,0x7c,0x54,0x72,0x2b,0x89,0xf4,0x05,0x5c,0x30,0x42,0xe5,0x58,0x65,0x3a,0x2e,0xf9,0x40,0xab,0x2b,0xf9,0xc3,0x99,0x40,0x3c,0xb1,0x7b,0x2c,0xdc,0xfe,0x41,0x21,0x71,0x00,0x75,0xbd,0xea,0xf3,0x84,0x88,0x6b,0x9c,0xe2,0x80,0x2f,0xad,0x9f,0x9d,0x0a,0xdf,0xb5,0x38,0x61,0x89,0xfb,0x67,0x45,0x9c,0x39 +.byte 0xf9,0x84,0x54,0xc4,0xd6,0x6f,0x00,0x39,0x90,0x82,0xfa,0xce,0xae,0xe8,0xaf,0xa4,0x97,0x3a,0xfe,0x71,0xaf,0x5e,0x00,0xd1,0x9e,0x33,0x41,0x63,0xca,0xa5,0x5a,0x8b,0x09,0x2a,0x26,0xef,0x96,0xb7,0x5d,0xc4,0x92,0xfa,0x51,0xdb,0x1d,0x63,0x5f,0x7c,0x94,0x53,0x84,0xed,0xa3,0x99,0x07,0x9f,0xdc,0x55,0xb3,0x31,0x67,0x1a,0x63,0x05 +.byte 0xec,0x36,0x79,0x57,0xf8,0x39,0xc3,0xdd,0xd5,0x6a,0x21,0xfc,0x54,0xe6,0x28,0xc4,0xf1,0xd2,0xce,0x02,0x43,0x50,0x30,0x15,0x4d,0x3c,0xd0,0x1c,0xf6,0x7e,0xd0,0xa4,0x86,0xe7,0xf5,0xc2,0x06,0xc5,0xc4,0xa8,0xe2,0xd3,0xc7,0xcf,0xbd,0xab,0x9f,0xe3,0x42,0xc4,0xcd,0x65,0xfa,0xd3,0xcd,0xdf,0x55,0xc4,0xce,0x6e,0xe8,0xfc,0x96,0x0f +.byte 0xe2,0x92,0xca,0xde,0x37,0x7c,0xc9,0x80,0x4a,0x54,0xe9,0xfd,0x3c,0x4b,0x81,0xb8,0xd9,0x1a,0xf1,0x91,0x5d,0x9d,0xef,0x3e,0xd1,0x78,0xe2,0x1e,0x0e,0x09,0x62,0xdd,0xc6,0xb9,0xde,0x29,0xba,0xb0,0x62,0x49,0x53,0xb6,0x8d,0x9f,0xbf,0x4d,0x77,0xa4,0xd1,0x0b,0xf0,0x31,0x2e,0xe5,0x71,0x2e,0x18,0xa4,0xa7,0xcb,0xa6,0x30,0x24,0x11 +.byte 0x8d,0x16,0x21,0x71,0x6a,0x19,0xde,0x3c,0x5a,0x00,0xa6,0xe2,0x43,0x98,0xe8,0x83,0x10,0x76,0xef,0xca,0x67,0x61,0x80,0x98,0x48,0x06,0xa9,0xcd,0x13,0xa6,0x1e,0x5b,0x2b,0xef,0xb7,0x3a,0x24,0xf7,0x10,0x8d,0xc2,0xaa,0x9c,0x78,0x0d,0xd1,0x54,0xb1,0x4e,0x5a,0x21,0xc2,0xb4,0x11,0x15,0xdb,0xb3,0x9c,0xe4,0xf1,0xfc,0xa5,0x66,0x0c +.byte 0x56,0x34,0x05,0x14,0x88,0x2c,0xfc,0x3f,0x97,0x30,0xd5,0xd0,0xba,0xa3,0xf1,0x47,0xc0,0xf1,0x59,0x3c,0xda,0x1a,0xc1,0x90,0xae,0x4b,0x26,0xd3,0x5f,0xc9,0x8f,0x62,0x56,0x9c,0x64,0xec,0xda,0x63,0x37,0xa1,0xa2,0x87,0x74,0xcb,0xcc,0x27,0xcb,0x2a,0x97,0x57,0xa3,0xb9,0xac,0xe2,0xbd,0x97,0x93,0x21,0xb9,0x8b,0x82,0xa1,0xe7,0x76 +.byte 0xc1,0x49,0xd6,0xb2,0x52,0x7b,0xd6,0xbb,0x31,0x0f,0x87,0xc0,0xaa,0x91,0x70,0x19,0x76,0xa5,0xea,0xf0,0x87,0x47,0x50,0xc1,0xff,0xf7,0xa6,0x6c,0x65,0xff,0xdf,0x83,0x5c,0x54,0xf0,0xb1,0x18,0xe0,0x13,0x58,0x74,0xc0,0x67,0x0e,0xb8,0xdc,0x59,0x6c,0x19,0xf4,0xee,0x3a,0x07,0x63,0x68,0x1d,0x62,0x60,0xb5,0x71,0xce,0x21,0x61,0x8c +.byte 0xa5,0x74,0x9b,0x77,0x8e,0x15,0x20,0x18,0x19,0x96,0xf6,0xfa,0xd2,0x6c,0x03,0xcb,0xcb,0x8c,0x91,0x0d,0x29,0x91,0x70,0xc5,0x96,0x60,0x18,0xad,0x65,0x66,0x43,0xf9,0x13,0x97,0xe3,0xe3,0xcb,0xbf,0x68,0x0b,0xb2,0x87,0x9c,0xfa,0x96,0x48,0x14,0xef,0x6e,0xbd,0x45,0xb9,0x2f,0xbb,0x80,0x80,0xc5,0xf6,0x22,0x41,0x9a,0xec,0xdd,0x41 +.byte 0xfc,0xf3,0x0d,0x8e,0x2e,0x3c,0xda,0xef,0x2c,0xbd,0xbc,0x0e,0x88,0xd2,0x97,0x3d,0x40,0x37,0xa6,0xde,0x1d,0x00,0xeb,0x39,0xea,0x44,0xee,0x8a,0x2f,0x77,0xea,0xea,0x1d,0x90,0xd1,0xec,0xe4,0x31,0x0c,0xde,0x6f,0x55,0x17,0x5c,0x1e,0x19,0x91,0xac,0x36,0x00,0x26,0x17,0xa6,0xcd,0x8b,0xe2,0x72,0x6f,0x8f,0x3c,0xc6,0x76,0x6e,0x3d +.byte 0x4e,0x93,0xb3,0x8b,0xad,0x24,0x17,0x39,0xc0,0xfe,0xba,0x90,0xc5,0xbd,0x4b,0xe4,0xae,0xac,0xf6,0x55,0x72,0x3e,0xf0,0x12,0x32,0x5a,0xdd,0x8a,0x3f,0x67,0xb6,0xdf,0xf6,0x11,0x02,0xf5,0x84,0xcc,0x7d,0x36,0xe7,0x1b,0xf0,0x9a,0x52,0xbe,0xf3,0x06,0xd6,0xdb,0x02,0xd4,0x80,0x0b,0xcd,0xf0,0xfe,0xec,0x86,0x3f,0x89,0x34,0xcb,0x88 +.byte 0x34,0x28,0x57,0x00,0x33,0xeb,0x4f,0xfa,0xdb,0xd8,0x09,0xd9,0x56,0x53,0xc1,0x02,0xc0,0xa8,0x4c,0xdc,0xfd,0x26,0xb3,0x55,0x1d,0x47,0x0d,0x68,0x50,0xb8,0xa3,0xb4,0xf1,0x31,0xfa,0x16,0x33,0x94,0x40,0x95,0x53,0x9c,0x9f,0x5b,0x25,0x47,0xb1,0x27,0xbc,0x38,0x7d,0x23,0x01,0x7f,0x70,0x7a,0x61,0x0e,0x46,0x5c,0xcc,0xd7,0xcc,0x15 +.byte 0x15,0x0a,0xed,0x4c,0x99,0x66,0x3a,0xc3,0xc1,0x9a,0x7a,0x38,0x6a,0x0c,0xde,0x13,0x67,0x65,0xfc,0x06,0x99,0x7c,0xa5,0x90,0x8a,0x90,0x58,0xce,0xf3,0x23,0x76,0xfc,0x03,0xfb,0xb3,0x36,0x54,0xa9,0x33,0x35,0xfe,0xe3,0x3d,0x53,0x7e,0xe0,0xae,0xcf,0xc0,0xa2,0xe1,0x28,0xb9,0x97,0x96,0x87,0x90,0xa1,0x13,0xd0,0x1d,0x5b,0x43,0xf1 +.byte 0xa5,0xfa,0x81,0x83,0xe7,0x7b,0xa1,0x5f,0x9f,0xf5,0xd3,0xb6,0x80,0x8b,0x91,0xed,0x31,0x14,0x05,0x78,0x85,0x9d,0xea,0x59,0x69,0xa5,0x29,0xc5,0xf1,0xd7,0x9d,0xa3,0x8b,0x9d,0xe0,0x8d,0xc3,0x4e,0x2d,0xfa,0x1c,0x6c,0xd2,0xd7,0xcb,0xda,0x86,0x5d,0xb3,0x1a,0xb4,0x12,0xe3,0xa8,0xd7,0xe1,0x84,0xce,0x0e,0x06,0xd0,0x9e,0xf0,0xb1 +.byte 0x5b,0x2f,0x77,0x10,0x6f,0x41,0x2f,0x5b,0x48,0x43,0xf3,0xef,0xdb,0x09,0xdb,0x01,0x89,0xfc,0x7a,0x4a,0xc0,0x96,0x33,0xdf,0xbe,0x49,0x85,0xa7,0x88,0x93,0x05,0xf2,0x15,0x12,0x85,0x04,0x20,0x7d,0x8c,0xe2,0x0a,0xea,0xfe,0xed,0xbf,0x98,0xdb,0x9d,0x1f,0xaf,0x0f,0xbf,0xf7,0x12,0x4f,0x69,0x4e,0x87,0x09,0xf0,0xae,0x2a,0x4d,0x4c +.byte 0xbf,0xaa,0x08,0x2c,0x78,0x2d,0xbe,0xb9,0xf5,0x3c,0x4c,0xcd,0x75,0x93,0xc3,0x3c,0xc2,0x86,0x47,0xca,0xc1,0x9c,0x1c,0xe5,0x0d,0x8d,0x36,0x9c,0x44,0x40,0x89,0xfa,0x17,0x57,0x08,0xd4,0x22,0x9a,0x5b,0x94,0xbf,0x39,0xcd,0xbe,0xf7,0xd1,0xcd,0x35,0x74,0xdf,0xfa,0x5d,0x00,0xaa,0xaa,0x82,0x6d,0x9b,0xf8,0x69,0x51,0x9c,0xaa,0xaa +.byte 0xc8,0x2c,0xa2,0x68,0x57,0x3c,0x5f,0x10,0xa2,0x7b,0xee,0xc9,0x97,0x8d,0x5c,0x41,0x08,0x0d,0x30,0xd5,0x2b,0x5f,0x8d,0xdd,0xdc,0x2c,0xa8,0x52,0x6e,0xea,0x61,0x77,0xca,0x75,0xc3,0x56,0x6e,0x17,0x51,0x0e,0x00,0xb6,0x18,0xa0,0xe5,0x9d,0x49,0x4e,0x20,0x78,0x1e,0x5f,0x3e,0xec,0xc3,0x4a,0x41,0xf3,0xfe,0x89,0x64,0xac,0x4c,0x4d +.byte 0xa8,0x73,0x4f,0x31,0xc4,0xe2,0x62,0x69,0x2b,0x40,0xdf,0xef,0xed,0xf0,0x62,0x4e,0xc3,0x65,0xcc,0xcb,0xef,0xc1,0x28,0x61,0x71,0xac,0xa5,0x89,0x52,0x7b,0x32,0x59,0xc2,0x16,0x1a,0x63,0x18,0xb0,0xd8,0xe4,0x28,0x92,0xff,0x45,0xc1,0x24,0x56,0x86,0x66,0x23,0x7a,0xff,0xf7,0x33,0x30,0xdc,0xd1,0x7d,0xaf,0x68,0x10,0x4b,0xde,0x3e +.byte 0x4a,0x70,0xbe,0x31,0x1a,0x37,0x28,0xee,0xe0,0xba,0x65,0x8b,0x7d,0xea,0x07,0xce,0xf2,0x51,0x3d,0xcb,0xb2,0x33,0xd8,0xf3,0xa4,0xa0,0xcd,0x53,0x76,0xf9,0x46,0x5b,0x82,0xf9,0x9d,0x0e,0x29,0x5b,0xcf,0x76,0xd4,0x5c,0x47,0xf1,0x98,0x02,0x5a,0x16,0x18,0xf2,0x61,0x6d,0x3e,0x64,0x7f,0xbe,0x13,0x18,0xc2,0x45,0xd2,0x87,0x17,0xff +.byte 0xf1,0x01,0x0b,0x5d,0x21,0x0d,0x73,0x9a,0xeb,0x82,0xc4,0x9a,0xb3,0xe4,0x31,0x44,0x58,0xa2,0xfd,0x76,0xf6,0xbe,0x6f,0x75,0xcc,0xbb,0xe3,0xa2,0xa9,0x78,0x0f,0x4b,0x1d,0x47,0x2d,0x32,0x2c,0x45,0x5e,0xcd,0x8f,0x13,0xe2,0x9a,0x9d,0xa2,0xce,0x73,0x54,0x20,0xc0,0x44,0x1c,0x26,0xde,0x0d,0x72,0xb2,0xfa,0x4d,0x32,0x35,0xac,0x69 +.byte 0x4d,0x16,0x4a,0xd5,0x51,0x33,0xc1,0xe0,0x90,0x9c,0x93,0x66,0xed,0x16,0xac,0x7e,0x79,0x2b,0x0f,0xb4,0x42,0xaf,0x80,0x22,0x80,0x07,0x7d,0x72,0xe4,0xb3,0x3a,0x2c,0xb8,0x68,0x14,0x4d,0x31,0x5f,0xbb,0xac,0x43,0x3b,0x28,0xd6,0x81,0x81,0x26,0xe5,0xc4,0x67,0x7c,0x4a,0x42,0xc4,0x1a,0x59,0x04,0x2d,0xb8,0x26,0xfc,0x4e,0xc7,0xfc +.byte 0x11,0x61,0xe3,0x4b,0x2c,0x3f,0xdb,0x43,0xe4,0x24,0xb4,0xd1,0xc0,0xc0,0x01,0xe1,0xeb,0x84,0x0b,0x6d,0x93,0x83,0x07,0x9f,0x01,0xb8,0x9d,0xe5,0x7e,0x4d,0xa2,0x05,0x3e,0xf2,0x40,0x59,0x88,0xc8,0x8c,0x62,0x44,0x95,0x20,0x96,0x28,0xa9,0x3f,0x7c,0xed,0x85,0x03,0x65,0x49,0xf7,0x94,0x3d,0x51,0xe2,0x8e,0x21,0x19,0x7b,0x55,0x5f +.byte 0x55,0x70,0xf8,0xf0,0xce,0xd9,0x1a,0x10,0xbb,0xfe,0x65,0x72,0x8a,0x5b,0x6c,0x27,0xd3,0x57,0x61,0x07,0x7b,0x85,0xd6,0x21,0xd2,0x07,0x81,0xaa,0x17,0x73,0xb5,0xef,0x2d,0x84,0x7b,0x8f,0xe0,0xb3,0x9e,0x9f,0x31,0x82,0x33,0x07,0x14,0x84,0x79,0x18,0xc4,0xec,0x20,0xb5,0xec,0x21,0x4b,0x51,0x78,0x96,0xc6,0xe7,0xf0,0x6a,0x7a,0xb5 +.byte 0xe5,0xc2,0xef,0x24,0x4c,0x57,0xb6,0xf5,0xee,0xe5,0x69,0x2b,0x73,0x9e,0x66,0x91,0x9d,0xd4,0x24,0x58,0x4b,0x72,0x68,0xf6,0x62,0xb4,0x0c,0xe3,0xbd,0x1f,0x0b,0x42,0x6c,0xf9,0x6e,0x6a,0x64,0x64,0x69,0xa5,0x6d,0xe7,0x38,0x9f,0xb2,0x65,0x35,0x6b,0xd9,0x20,0x84,0xe4,0x5f,0x8b,0xfd,0x58,0xab,0x5f,0xe1,0x4c,0xf7,0xd7,0xf5,0xe7 +.byte 0xae,0xe8,0xc1,0x68,0xfe,0x0c,0xb1,0xe2,0xe4,0xca,0xf0,0xf1,0x20,0xbc,0xf9,0x99,0xef,0x4e,0x63,0xca,0x89,0xe4,0x7c,0x17,0x49,0x40,0x47,0xce,0x67,0x8e,0xbd,0xd0,0x96,0x8b,0x5a,0x0d,0x2f,0xd0,0x8f,0x4f,0x42,0x06,0x01,0x8e,0x47,0x35,0x13,0x9e,0xd1,0x24,0x85,0xe4,0x17,0x59,0xe8,0x1c,0xb3,0x25,0x53,0xf9,0xb4,0x96,0xb1,0x33 +.byte 0x97,0xb2,0x60,0xc7,0xb3,0x48,0xa2,0xfc,0x7f,0x86,0x94,0x2a,0xd3,0x94,0xfe,0x6d,0xa6,0x7a,0xa1,0xe1,0x96,0x5b,0xe8,0xe4,0x91,0xfb,0xf3,0x2c,0x84,0xb4,0x2f,0xbe,0xc9,0xdd,0x1c,0x9f,0x72,0x12,0xcb,0xbd,0x22,0x07,0xc4,0xec,0x05,0xe8,0x32,0x47,0x21,0x27,0xf6,0xc1,0x36,0x59,0x25,0x6c,0xbe,0xb9,0x3e,0xd4,0x1b,0x59,0x11,0x27 +.byte 0x6b,0xa3,0x64,0x71,0x98,0xeb,0x21,0x65,0xc0,0x4c,0x30,0xbd,0x51,0x2b,0xc3,0xfb,0xb1,0x33,0x56,0x1e,0xf0,0x92,0x0f,0x4b,0x63,0x3a,0x9c,0xfb,0xd1,0xac,0x8c,0xf0,0x3e,0xb7,0x0b,0xd2,0x52,0x62,0xd8,0x37,0x9a,0xef,0x79,0xdc,0xcb,0x87,0x1e,0x3d,0x9d,0x91,0x12,0xba,0x78,0x8a,0x11,0x57,0x96,0x44,0x8e,0x2b,0xd2,0xe3,0x4d,0x27 +.byte 0xec,0xba,0xef,0x1c,0x04,0x8d,0x56,0x56,0x11,0x74,0xc0,0xcc,0x1f,0x3d,0x7a,0xad,0x79,0x49,0x59,0xa3,0x71,0xe0,0xf5,0x89,0x89,0x8f,0xcf,0x1e,0x63,0x77,0x91,0x91,0xf1,0x0c,0x1c,0xcc,0x77,0x00,0xd7,0x28,0x9f,0x68,0xbc,0xb6,0x9d,0x33,0x43,0xb2,0x4a,0x72,0x3e,0x57,0x26,0xd0,0x00,0x93,0xc9,0x4c,0xc9,0x53,0x52,0xd9,0xe2,0x31 +.byte 0xc5,0x7f,0xf6,0xb6,0xc2,0x10,0x51,0x67,0xae,0x63,0x35,0x74,0xcc,0xd4,0x05,0xb3,0x08,0x23,0x35,0x37,0x8e,0xf1,0xbb,0x1d,0x56,0xff,0x62,0xa2,0x13,0x7b,0x01,0x75,0x6d,0xb3,0x92,0x51,0xdc,0x6e,0x08,0x76,0x25,0x52,0xbf,0x9a,0xea,0x89,0x0f,0x96,0xcc,0x79,0xd4,0x72,0xcf,0x65,0x79,0x4e,0x40,0xa3,0xae,0x67,0x0c,0x82,0x85,0x05 +.byte 0xfd,0x43,0x84,0x17,0x24,0x79,0xa9,0xa7,0x7f,0x24,0x76,0x57,0x66,0x11,0xd5,0x33,0x30,0x42,0x5b,0x5f,0x7c,0x04,0x4b,0x45,0xc3,0x69,0x20,0x02,0x92,0xe3,0x6a,0x06,0x8f,0xdf,0x30,0xf6,0x17,0x8f,0xc6,0x8c,0x5e,0x42,0xf3,0x59,0x7a,0x3a,0x55,0x3a,0xc1,0x96,0xd5,0x67,0x3d,0xab,0x32,0xee,0xf0,0x08,0x28,0x73,0xb0,0x11,0x1a,0x92 +.byte 0x4d,0xcc,0x0c,0x86,0xb2,0xa1,0xbf,0x9f,0xcd,0xc7,0x1c,0xbc,0xee,0x39,0x77,0x75,0xfc,0xe6,0x3b,0x62,0xf2,0xaf,0xd5,0xb6,0x77,0x2d,0x86,0x38,0x13,0x00,0xdb,0x71,0x4a,0x87,0x03,0x6d,0x99,0x28,0xf8,0x6a,0x23,0x2e,0xe2,0xb8,0x9c,0x18,0x02,0x00,0x9e,0x5b,0xf0,0x6f,0x9b,0x32,0xdc,0x6b,0x61,0xeb,0xeb,0xe9,0xfc,0xee,0x44,0xbc +.byte 0x4a,0x88,0x04,0xc0,0x10,0xc8,0x65,0x6c,0xa4,0xae,0x9a,0x36,0xb6,0x68,0xd5,0xbf,0x6d,0xe3,0x6f,0x5d,0xad,0xd6,0xf9,0xc8,0x06,0x36,0x25,0x64,0xc9,0x5b,0x71,0x7f,0xbf,0xe3,0x56,0x31,0x2a,0x93,0x47,0x46,0x39,0x91,0x80,0xc5,0xdd,0xdd,0xa1,0x25,0x85,0xd9,0x05,0x49,0x4f,0x1b,0xeb,0x2f,0x6e,0xd9,0xe4,0x65,0x3d,0xcd,0xbd,0x47 +.byte 0x37,0x27,0xb0,0xd1,0x9b,0xa4,0x89,0xd5,0xa0,0x0f,0x8b,0xc5,0xfd,0x91,0xa8,0x86,0x22,0x65,0xf1,0xe1,0x1e,0xb6,0xf7,0x50,0xe6,0x1e,0xf0,0x2b,0x9d,0x02,0xc9,0xe8,0x2a,0xb8,0x9b,0x89,0x28,0x25,0x43,0xcf,0x23,0x08,0xe2,0xa7,0x70,0x31,0x89,0xab,0x5b,0xd9,0x2e,0xa9,0xe4,0xe9,0x1d,0x63,0x7f,0xc6,0xc1,0xfb,0x63,0x45,0x9c,0xf1 +.byte 0xd4,0xc3,0x56,0xb6,0xad,0xb3,0x00,0xce,0x12,0x9e,0x63,0x33,0x25,0xd3,0xb2,0xee,0xa7,0x6b,0xa1,0xfd,0x20,0xa3,0xb2,0x07,0x1a,0x9d,0xed,0xe0,0x1d,0x70,0x5b,0x9f,0xc0,0xbc,0x83,0x09,0x94,0x47,0x8c,0x05,0xef,0x73,0x96,0x31,0xc7,0x35,0xc2,0x2c,0x00,0x2a,0x68,0xd1,0xc4,0xb3,0x3d,0x84,0x44,0x8c,0x93,0xfd,0x64,0x00,0x77,0x46 +.byte 0x18,0xac,0x83,0x9d,0xe5,0xe5,0x46,0x61,0x37,0x72,0x9f,0x0e,0x76,0x55,0xf7,0xca,0x36,0x57,0x24,0x16,0xfc,0x11,0x27,0xaa,0x44,0xa4,0xb0,0x58,0x41,0x46,0x94,0xc7,0x3b,0x9c,0xa3,0xe4,0x89,0xd9,0xdb,0x7b,0x64,0x69,0x84,0x9f,0xc8,0x09,0x6f,0xf7,0xf0,0x58,0x10,0x56,0x9f,0x26,0xf0,0x74,0x0c,0x76,0xcb,0x9d,0x45,0x3d,0xe7,0x94 +.byte 0x54,0xa3,0x84,0x08,0xb5,0x9c,0xff,0xdb,0xba,0x62,0x5e,0x87,0x0d,0x11,0x5d,0x96,0x06,0xd6,0xec,0xf4,0x3e,0x9d,0x66,0xbd,0xc4,0x64,0xed,0x03,0xe0,0xad,0x3f,0x4e,0xb4,0xef,0x16,0xdd,0xee,0xd6,0x00,0x27,0x62,0x74,0x0a,0xe0,0x68,0x72,0x4c,0x6d,0x62,0x15,0x87,0x6a,0xf0,0x25,0x9f,0x33,0x1d,0x92,0x3b,0xa3,0xa4,0xf1,0x81,0xdf +.byte 0xa8,0xed,0xaf,0xa5,0x8d,0x19,0x20,0x72,0x03,0x91,0xf0,0x34,0x60,0x70,0xbe,0xaa,0xdf,0xaa,0x24,0x1a,0x1f,0x1a,0x8d,0xb0,0x7b,0xef,0x10,0x43,0x69,0x24,0x74,0xf2,0x72,0x71,0xa1,0x8f,0x85,0x75,0x3e,0x8c,0xf6,0x0e,0x88,0xe2,0x1d,0x5c,0xb8,0xf1,0xc4,0x8a,0x21,0x76,0x20,0x50,0x3f,0xb3,0x8b,0x9f,0xa4,0x45,0x9e,0x07,0x60,0x22 +.byte 0x2c,0xa6,0xb1,0xc2,0xd2,0xcb,0xc6,0xd8,0xe9,0x94,0x66,0xfb,0x10,0x73,0x92,0x25,0x7e,0x31,0x42,0xf4,0x4a,0x75,0xac,0x78,0x43,0xcb,0xc0,0xc9,0xb0,0xaf,0xb4,0x22,0x8f,0x51,0x36,0x0f,0x5a,0xb8,0xbb,0x44,0x03,0x09,0xd0,0xf9,0x04,0xc8,0x73,0x8e,0xa1,0x76,0x27,0xde,0x72,0xf4,0x3a,0x79,0x63,0x85,0x32,0x09,0xad,0x12,0xe4,0xd7 +.byte 0x8f,0x8e,0x24,0x03,0x4f,0xde,0x39,0xac,0x81,0xe8,0x64,0x09,0x17,0xd7,0x99,0xe6,0x62,0xb7,0x53,0x20,0x9f,0xb9,0x3a,0xb9,0xb1,0x81,0xfa,0x6e,0x33,0xe7,0x4a,0xca,0xd7,0xa7,0xfa,0x7a,0xbf,0x0b,0x0a,0x99,0x3c,0xc7,0xbd,0xef,0xc7,0x90,0xda,0x62,0x30,0xc6,0x94,0x94,0x6b,0xee,0xbd,0xb7,0x0d,0x86,0xc5,0xb1,0x9a,0xb9,0x86,0x34 +.byte 0xc2,0x81,0x2b,0x09,0x7a,0x88,0x09,0x65,0xcf,0x51,0x78,0x19,0x1d,0x5a,0x62,0x2f,0xb3,0x43,0x8d,0xf5,0x9d,0x26,0x2f,0x4a,0x27,0x96,0x22,0x1b,0x4c,0xc8,0xd9,0x73,0x4b,0x32,0x01,0x11,0x7b,0x59,0x85,0xda,0x50,0x92,0x17,0x45,0xd4,0x1f,0xcf,0x98,0xf6,0x2c,0x69,0xba,0x43,0x22,0xdc,0x36,0x31,0xfb,0x1e,0xe8,0x54,0x24,0x0f,0x24 +.byte 0x4c,0xcd,0xbe,0xdb,0xd8,0x23,0x69,0xe2,0x97,0xf5,0x66,0xb2,0x66,0x6c,0xf2,0x90,0xd0,0x15,0x14,0x9a,0x47,0x65,0x97,0xb0,0xf2,0x3e,0x35,0x09,0xd2,0x3d,0x01,0x9c,0xb3,0xfd,0xf3,0x32,0x46,0x4e,0x11,0xab,0x88,0x9e,0x04,0x6d,0xf0,0xe1,0x9d,0x48,0x01,0x24,0xc3,0x87,0xdf,0x58,0xb6,0x6d,0x6d,0x4f,0xb9,0x1b,0x13,0xee,0x03,0x5b +.byte 0x75,0x39,0x28,0x31,0x90,0x70,0x49,0x10,0x71,0x87,0x76,0x30,0xac,0x88,0xb0,0xf6,0x6c,0xaf,0x5b,0xf4,0xf3,0xe7,0x25,0x75,0x8c,0xa3,0xf4,0xa7,0xd8,0x94,0x78,0xc8,0x77,0xc1,0x48,0x6c,0x62,0xf6,0x2c,0xb5,0x41,0x59,0xf6,0xd3,0xae,0x1b,0x55,0xed,0xdf,0xd1,0x59,0x63,0x76,0x03,0x65,0xd3,0xd0,0xcd,0xb6,0x5b,0x8f,0x1a,0x78,0x88 +.byte 0x78,0x07,0x14,0x3f,0xc3,0xd4,0x1c,0x69,0xd8,0x15,0x25,0xca,0x76,0x15,0x24,0x7d,0xed,0x69,0x2a,0xb5,0x04,0xd2,0x3b,0xbd,0x7a,0xb2,0xae,0x04,0x51,0x85,0x2b,0x1b,0xb0,0x3f,0x6d,0xbc,0xa0,0xc7,0x19,0x40,0xab,0x75,0x51,0x4b,0xa8,0x5a,0xd7,0xb5,0xc7,0xa8,0xfc,0x4a,0xcf,0xa9,0x9c,0xe6,0x2e,0x35,0x51,0x3b,0x05,0x41,0x43,0x7c +.byte 0x1f,0x2e,0x16,0x5d,0x2f,0xa8,0xe9,0xce,0x6d,0x06,0xa7,0x5a,0xed,0x07,0x39,0xe4,0x7e,0xc3,0x01,0x2d,0x97,0xe4,0xc1,0x89,0x2c,0xb4,0xb1,0xb5,0x7f,0x0a,0xe2,0x9f,0x82,0x36,0xee,0x9b,0x76,0xbc,0x9d,0x37,0xdf,0x5e,0x81,0x95,0x9b,0x2b,0xc4,0x58,0x20,0x6a,0xd2,0xc7,0xb6,0x82,0xe6,0xa2,0x52,0x73,0x4a,0xaf,0x37,0x5a,0xf6,0x6b +.byte 0xc4,0x2b,0x53,0x4e,0xca,0x44,0x17,0x9f,0x1c,0xeb,0x4d,0xf2,0xd1,0xb0,0x35,0xaa,0xc3,0xfe,0x77,0x34,0x2a,0x4a,0xe8,0x85,0x96,0x2f,0xa4,0x7d,0xdf,0xd0,0x6a,0x4a,0x0c,0x9b,0xd9,0x6a,0x00,0x92,0xb4,0xb1,0x9f,0xc3,0x56,0xee,0xcb,0xa5,0x3a,0x37,0x68,0xc8,0x7c,0x1e,0xa8,0x0a,0x3d,0xbc,0xd1,0xd0,0xd7,0x8b,0x32,0x34,0x20,0xfc +.byte 0xd3,0x9e,0xf5,0x18,0x3a,0xb9,0x87,0xae,0xde,0x6c,0xc0,0x7d,0xbd,0x20,0x00,0xe5,0x7b,0xcb,0xf9,0x7d,0x70,0x9a,0x10,0x45,0xc9,0x33,0x13,0x9d,0x2c,0x16,0x67,0xe6,0x36,0x38,0xcf,0xa2,0xf1,0xad,0xec,0x48,0x7f,0x9b,0x2a,0xdc,0x13,0xe2,0xee,0xef,0xf2,0x5c,0x3f,0x52,0x3a,0x72,0x79,0x9b,0xba,0x50,0xb2,0x2b,0xfb,0x97,0x8e,0xe6 +.byte 0x27,0x39,0x63,0x72,0x05,0x11,0x7d,0x2e,0xa8,0x44,0x08,0xf7,0xf3,0x26,0xe5,0xe4,0x6c,0x98,0x7b,0xb1,0x42,0x6d,0x74,0xd4,0x3b,0xfa,0x35,0xfa,0x0a,0xac,0x5e,0x9e,0x8f,0xc7,0x07,0xc5,0x50,0x25,0xfd,0xbf,0x13,0x52,0x3d,0xf1,0x18,0x1e,0x19,0x8c,0xf3,0x8b,0x4d,0xc8,0xfb,0x76,0xa4,0xe3,0x3f,0xb2,0x47,0x9c,0x50,0x97,0x32,0x65 +.byte 0x9e,0x42,0x81,0x21,0xd1,0x92,0xd2,0x81,0x4a,0x93,0x68,0xa2,0xc1,0x76,0xc8,0x40,0xce,0xfe,0x4e,0xc5,0xa7,0xb2,0x77,0x9f,0xc8,0xe5,0x41,0xb1,0xda,0x15,0xf6,0xfa,0x21,0x3f,0x11,0x5c,0xc6,0x62,0xda,0x01,0x7f,0x0f,0x9f,0x9e,0x98,0xfe,0x38,0x53,0x6c,0x7f,0xba,0x8b,0x55,0x01,0x36,0x33,0x41,0x5e,0xa9,0x78,0xbf,0x2e,0x60,0x4f +.byte 0xcb,0xe9,0x27,0x09,0x8c,0x01,0x2d,0x82,0x7d,0x3f,0xaf,0x8f,0x1e,0x37,0x79,0x35,0xfb,0xce,0x83,0xc5,0xf8,0xc5,0x54,0xfd,0x50,0xec,0x31,0xd1,0xb5,0x8a,0x4d,0x37,0xf6,0x7f,0x0e,0xbe,0x35,0xdd,0xa8,0x9e,0x5e,0xb9,0x3c,0xf4,0x2b,0xd2,0x97,0x56,0xd0,0x28,0xcb,0x60,0x27,0xcf,0x27,0x68,0x8a,0xa1,0xbf,0x9f,0xa3,0x45,0x4a,0x44 +.byte 0x71,0xe2,0xb2,0x9c,0x69,0x0b,0x18,0x69,0xcf,0x03,0xcc,0xc3,0x93,0xe0,0xf5,0xb7,0x4e,0xa4,0xdc,0x96,0xe0,0x2e,0xf8,0x3b,0xc6,0x67,0x30,0x06,0x5e,0xb9,0xb9,0x7d,0xaf,0x97,0x38,0x9a,0xf4,0x22,0x20,0x5a,0x9e,0x83,0x26,0x3c,0xcc,0x93,0x84,0x20,0x15,0x2e,0x85,0x23,0x17,0x1d,0x28,0xb4,0xe2,0x8f,0x2d,0x22,0x99,0x66,0xfd,0x6a +.byte 0xa8,0xe6,0xb7,0x19,0x18,0xec,0xbd,0x54,0xc2,0xcc,0xb7,0xb4,0x6b,0x10,0xdd,0xb5,0xe3,0x3b,0xb7,0x77,0xbf,0x66,0x65,0x82,0x6a,0xc6,0x0d,0x26,0xe6,0xe8,0xe1,0x96,0xe4,0x0b,0x3c,0xe3,0xf2,0xfb,0xd6,0x91,0x5d,0xb6,0x08,0x15,0x67,0x10,0xfa,0xf8,0xdc,0x72,0x84,0xca,0x48,0x29,0x75,0x98,0x62,0x30,0x43,0xa9,0xf1,0xde,0x58,0xb5 +.byte 0x6e,0x67,0x53,0x62,0x0d,0x06,0xa8,0x97,0x35,0x04,0x02,0x34,0x3f,0xd7,0x77,0x38,0xed,0x51,0x32,0x7c,0x6f,0x25,0x94,0x04,0x30,0xa5,0xfc,0xf1,0xb0,0x65,0x77,0x16,0xec,0xb0,0xf9,0x6d,0xaf,0xbc,0x75,0x6e,0x29,0x44,0x20,0x86,0x36,0xbe,0x22,0xe0,0xe1,0xc4,0x0c,0x97,0x10,0x45,0x3e,0x06,0xc3,0xee,0xa5,0x1f,0x97,0xc7,0xde,0xdb +.byte 0xf1,0x05,0xe3,0xb7,0x24,0xc5,0xa5,0xca,0x4e,0x8e,0x9e,0x44,0x7e,0x98,0xb1,0x3c,0xe9,0xa6,0xe5,0xa6,0x08,0xcb,0x08,0xd7,0xf6,0x38,0x37,0xa4,0x46,0xd1,0xdc,0x53,0x6f,0x6c,0x3f,0xca,0xa1,0x9b,0x7c,0xa6,0x44,0xd4,0x08,0x33,0xd2,0xf8,0x32,0xd2,0x4f,0x60,0x75,0x0f,0x49,0xf1,0x70,0x52,0x56,0x16,0x5b,0x3e,0x34,0x0e,0xe4,0x94 +.byte 0xc3,0xa9,0xd4,0x1c,0x9e,0xa4,0x10,0xce,0xc1,0x69,0x5b,0x3a,0xc9,0xd5,0xab,0x98,0x81,0x78,0x42,0x7e,0xf2,0x76,0x10,0xad,0x97,0x85,0x98,0x2f,0xe2,0x3f,0xb1,0x1d,0xc0,0x4d,0xa4,0x0b,0x54,0x7e,0x19,0x16,0x0a,0x71,0x74,0x37,0xfd,0x67,0x23,0x86,0xb2,0x3b,0x1e,0x49,0x92,0x92,0x1b,0x5f,0x65,0x56,0x76,0x6d,0x97,0x3b,0x91,0xc0 +.byte 0x5a,0x7e,0xf1,0x5b,0xe9,0x83,0xb9,0x67,0x2f,0xe1,0x0c,0xcf,0xe9,0x51,0x26,0x45,0x03,0x06,0x63,0xa4,0xb2,0x06,0xe0,0x8e,0xa3,0xbf,0xf5,0x7c,0x19,0xdf,0xfe,0x38,0x28,0x98,0xa1,0x23,0x16,0x69,0xc4,0x9f,0x20,0xe4,0x42,0x27,0x4e,0x7b,0xc9,0x42,0x5e,0xd2,0xb9,0xbf,0x33,0x03,0xbb,0x96,0x6d,0x80,0x65,0x90,0x3b,0x82,0x5b,0x68 +.byte 0x46,0x4f,0xe3,0xe0,0x0e,0xc5,0x90,0x91,0x80,0xf8,0xf4,0x9c,0xfe,0x03,0xaf,0x31,0x44,0xb7,0xfc,0x1f,0x65,0xc8,0x65,0x68,0xcc,0x27,0xb4,0x0d,0x81,0x14,0x9e,0x52,0xab,0xdd,0x71,0xf6,0xd9,0xcf,0x29,0x04,0xcd,0xae,0x6f,0xd6,0x41,0xb5,0xfd,0x1d,0x0f,0xbf,0x71,0xc2,0x60,0x98,0xb9,0xc0,0x6e,0x8a,0x2c,0x7d,0xec,0x31,0xa5,0xea +.byte 0x1a,0xb1,0xe4,0xc2,0x36,0xcb,0xf0,0xf4,0x3f,0x1d,0x03,0x01,0xcd,0xac,0xd0,0x9d,0x2e,0xa3,0xc4,0x54,0x49,0x75,0x90,0xac,0x7e,0x1e,0xc3,0x90,0xab,0x55,0xb0,0x34,0x0d,0xd6,0x99,0xb5,0x40,0xda,0xdd,0x30,0x57,0x61,0x15,0xec,0x8f,0x8c,0xc7,0xda,0xfc,0xf5,0x0a,0x86,0xd8,0x6b,0x0f,0x6e,0x09,0xb8,0x50,0x2a,0xea,0x51,0x84,0x33 +.byte 0x7a,0x97,0x0c,0x56,0x61,0x2c,0xd9,0x83,0xb9,0xb1,0x53,0x31,0x72,0x20,0x79,0x85,0x7f,0xdc,0xb8,0xfe,0xfa,0x9a,0xd4,0x6a,0x3c,0xc7,0xcc,0x75,0x20,0xba,0x9c,0xb9,0x1a,0xff,0x9c,0xbe,0xfd,0x87,0xb4,0xd7,0xe8,0x5e,0x22,0x6a,0x1b,0x91,0x52,0x6a,0x58,0xbc,0xf4,0xde,0xcc,0x18,0x37,0x0e,0xf5,0x22,0x91,0xd2,0x4f,0x08,0x91,0x62 +.byte 0x1c,0xb7,0xa0,0x7e,0x66,0x97,0xda,0xa0,0x3c,0xc8,0xe8,0xdc,0x61,0xa4,0x64,0x8b,0x0a,0x43,0x90,0x0c,0x78,0xd9,0x96,0x8a,0xb0,0x17,0x0f,0x32,0x17,0x11,0x82,0x69,0x9d,0x7c,0xa9,0xfd,0x9b,0xe3,0xeb,0x0d,0x44,0x1d,0xcb,0xf6,0xee,0x26,0x6b,0xd5,0x4c,0x49,0x69,0x18,0xd7,0xf3,0x63,0xd9,0x7e,0x83,0xdd,0xa3,0x2d,0xdf,0x88,0x10 +.byte 0xd1,0x5c,0xb0,0x7e,0x44,0xfe,0x64,0x39,0x33,0x05,0x04,0x54,0x74,0x4d,0xd5,0xbc,0xdf,0x19,0x52,0x81,0x60,0x92,0xc5,0x4e,0xa4,0xff,0xf0,0xa2,0xfd,0x88,0x96,0xde,0xb4,0x8d,0x58,0x06,0xfb,0x96,0x6f,0x0e,0xb0,0x4a,0x2b,0xed,0x15,0xa7,0xfb,0x9f,0xf2,0x30,0xc4,0xce,0x02,0x4d,0x83,0xb8,0x5d,0x10,0x60,0xb8,0xbc,0x05,0xa2,0xd4 +.byte 0xf1,0xae,0x46,0x56,0xb9,0xac,0x68,0x79,0x41,0x90,0xee,0x79,0xda,0x3a,0x91,0x7a,0xf6,0xdb,0xe3,0xea,0x91,0x48,0x77,0x4a,0xa3,0xab,0x9c,0x99,0x49,0x1f,0xc9,0xcd,0xe7,0x2e,0xe3,0xe7,0x78,0x6d,0x07,0x1b,0xc6,0x08,0x48,0xd8,0x20,0xff,0x19,0x8a,0x73,0x1d,0xc6,0xa1,0xd4,0x95,0x33,0xf7,0x45,0xab,0xea,0x05,0x3e,0xdf,0xde,0x68 +.byte 0xb2,0xb6,0xef,0x71,0xb4,0xd1,0x09,0x4b,0x43,0x16,0x35,0x1a,0xb6,0xcb,0x78,0x63,0xca,0x9e,0x9a,0xe3,0x86,0xb2,0x8e,0x7b,0x68,0x89,0xa7,0x5c,0xd3,0x06,0x21,0x88,0x94,0xde,0xa1,0xb1,0x3a,0xe8,0xb7,0xfa,0x58,0xc5,0xc8,0x01,0xfa,0x56,0xe4,0x0e,0x6b,0xeb,0x5d,0x67,0xf4,0x63,0xd4,0x44,0xe2,0xe7,0x42,0xfe,0x09,0x58,0xdf,0xd9 +.byte 0x1d,0xb7,0x14,0x91,0xac,0x88,0x49,0xf6,0x7c,0x03,0x92,0x11,0xb4,0x66,0x68,0x6c,0x94,0x2a,0x22,0xaf,0xa6,0xb1,0x29,0x2a,0xae,0xdd,0xa8,0x65,0xe4,0xa9,0x39,0x00,0x1e,0xca,0x17,0x99,0xba,0xd6,0xf2,0x20,0x21,0xbf,0x1a,0xab,0xca,0x7c,0x92,0x22,0xee,0x3c,0x0c,0xc6,0x63,0xcc,0x86,0xfe,0xc0,0x8f,0xac,0x18,0x4e,0x2b,0xa5,0x2e +.byte 0x46,0x57,0x8a,0xbf,0xdc,0xd1,0xd2,0x2c,0x5b,0xe2,0x96,0x81,0xca,0x41,0xb5,0x17,0x38,0x4a,0xa4,0xd2,0x0e,0xac,0x5d,0xe9,0x44,0x63,0x1b,0xb8,0x81,0xd6,0x69,0x1c,0x99,0xc5,0xdb,0xdd,0x18,0xc1,0x6d,0x28,0x7d,0x36,0x52,0x82,0xaa,0x1a,0x10,0x01,0x9d,0xf1,0x7b,0x09,0x69,0x56,0xb1,0x31,0xa3,0x54,0x3c,0x56,0xf9,0x82,0x8c,0x06 +.byte 0x5a,0x32,0x2d,0xc0,0x7c,0x7e,0x91,0x6d,0x73,0x7b,0x7c,0x45,0x0b,0x2c,0x2a,0x4f,0x3c,0xea,0x6b,0x2b,0x84,0x76,0xab,0x8d,0x4c,0x5c,0x64,0xa3,0x97,0x9f,0x56,0x20,0x05,0xf9,0xc2,0x20,0xf3,0xd0,0x6a,0x7f,0x7d,0x12,0xfc,0x20,0x52,0x5d,0xff,0x92,0xaf,0x4e,0x7f,0x8f,0x2f,0xd0,0x73,0x06,0x23,0x09,0xce,0x11,0xc0,0x1b,0x48,0x7d +.byte 0x11,0x51,0x06,0x0e,0x05,0x95,0xca,0x42,0x71,0x87,0xa3,0xa3,0xc1,0x27,0xf8,0xb1,0x24,0x92,0x38,0x95,0xf6,0x8f,0x3b,0x70,0x74,0x19,0x9b,0x08,0xb3,0x49,0xe9,0x57,0xd4,0xce,0x5b,0xdd,0xab,0x95,0x26,0xe9,0x70,0x21,0xef,0x16,0xdd,0x36,0x89,0xe5,0x9e,0xaf,0xc5,0x28,0x0c,0xd3,0x67,0x64,0xbc,0xfb,0x18,0x17,0x15,0x1e,0xa7,0xb7 +.byte 0x72,0x3d,0xfd,0x10,0x5c,0xa2,0xc1,0xbf,0x62,0x79,0x2b,0xa7,0xb9,0x1f,0x73,0xe6,0x11,0xd8,0xbc,0x74,0x6c,0x45,0x95,0xef,0xa2,0xda,0x90,0xc3,0x00,0x00,0xbb,0xc7,0x28,0x36,0x82,0xd4,0x5e,0x5c,0x11,0xea,0x7c,0xf6,0x79,0x66,0xff,0x93,0x77,0x49,0x05,0xc9,0xc1,0x8d,0x5c,0xf6,0xff,0xb9,0xf9,0xcd,0xb3,0x01,0x83,0x83,0x43,0x2d +.byte 0xa1,0x90,0x73,0xc9,0x32,0xae,0xdb,0xd0,0xf3,0x61,0x63,0x72,0x06,0xde,0x21,0x7b,0x3b,0x2d,0xec,0xd3,0x1d,0xfe,0xbd,0x6e,0xd8,0xe3,0x39,0xe0,0xa1,0x9f,0x67,0xaf,0xab,0x79,0xbc,0x59,0xf9,0xa7,0xdf,0x28,0x75,0xea,0x34,0x6b,0x25,0xde,0x49,0x1b,0x07,0x95,0x19,0x47,0x86,0x46,0x7b,0x68,0x30,0x70,0xec,0x9c,0x05,0xb6,0xc9,0x00 +.byte 0x68,0x10,0x4b,0xc4,0xe5,0xf1,0x67,0x3f,0xd4,0x3c,0xd6,0x49,0x98,0x71,0x23,0xff,0x07,0x6e,0x01,0x01,0x08,0x08,0x3d,0x8a,0xa1,0x71,0xdf,0x25,0x1a,0xef,0x60,0x86,0x6d,0x1c,0xd9,0x90,0x29,0x95,0xf2,0x4c,0x96,0xd3,0x17,0xe8,0x96,0x32,0x25,0x8c,0x65,0x38,0xbc,0x44,0x6a,0x5a,0xef,0x5a,0x72,0x12,0x43,0x2b,0xaf,0xc3,0xdc,0xb3 +.byte 0x6c,0x9f,0x57,0x61,0x2f,0x12,0x3f,0x72,0x16,0x4f,0x34,0xe3,0xb5,0xca,0x72,0xca,0x1c,0xdb,0xd2,0x8d,0x70,0x1f,0x19,0x75,0xb3,0x1b,0xdf,0xdb,0xb3,0xbf,0x6c,0x9a,0x70,0x64,0xa8,0xac,0x30,0x2d,0x4b,0x30,0xf5,0x4f,0x12,0x19,0xbd,0x65,0x25,0x70,0x33,0xe1,0x6f,0x18,0xdf,0x17,0xec,0xa3,0x80,0x51,0x6e,0xbb,0x33,0xa5,0xa8,0x58 +.byte 0x95,0x3c,0xab,0x86,0xd1,0x33,0xbe,0x55,0x04,0x8c,0x20,0x0d,0xfc,0x1a,0xa9,0x9d,0xb1,0x16,0x42,0x56,0x20,0xcc,0xa6,0x73,0xa0,0x85,0x3d,0xbf,0x1e,0xe0,0x01,0x51,0xd2,0xd7,0x2e,0x9d,0xd8,0x3c,0xea,0x03,0xf9,0x9a,0xbf,0x19,0x17,0x04,0x99,0xaf,0x8b,0xfc,0x9c,0x86,0xdf,0x58,0x78,0xfc,0x54,0x0d,0xac,0x26,0x27,0x2f,0x2e,0xbc +.byte 0xdd,0x4a,0xd5,0x6f,0x7c,0xd8,0x93,0xe3,0x51,0x9e,0xcc,0xc8,0xd2,0xfe,0x68,0xfb,0x5b,0x22,0xda,0xef,0x76,0xb9,0xc3,0xdd,0x13,0x52,0x24,0xb6,0x23,0x1f,0x69,0x22,0xb6,0xf5,0x86,0xff,0x2e,0x6e,0xd0,0xe0,0x21,0xbc,0x31,0x81,0xb5,0xc5,0xdb,0x36,0x58,0x44,0xe7,0xb8,0xf7,0xfd,0xd3,0x34,0xee,0xab,0xe6,0x99,0xf2,0x84,0x86,0x9b +.byte 0x67,0x45,0x08,0x07,0x66,0xae,0x6a,0x55,0xa2,0x74,0x46,0xda,0x02,0x82,0x67,0x93,0x60,0x64,0x5d,0x1f,0xac,0xe7,0x36,0xb6,0xcd,0x31,0x28,0x78,0x93,0xcd,0x54,0xe9,0x42,0xbb,0xb4,0xb3,0x15,0x72,0x12,0x31,0x85,0x15,0x68,0x3a,0x31,0x35,0xd6,0xc9,0x0d,0x3f,0xa0,0x4b,0x36,0x03,0xda,0xfd,0x7a,0xd6,0xce,0x0c,0xf5,0x14,0x23,0x71 +.byte 0x47,0x85,0x64,0xe7,0xe7,0x8b,0x8e,0x25,0x03,0x32,0x5f,0xa9,0x3b,0xdb,0x2b,0x27,0x7c,0x02,0xfb,0x79,0xd7,0x7a,0x76,0x75,0x69,0xfd,0x74,0x24,0xd2,0x72,0x8c,0xdd,0xc5,0xa1,0x45,0x90,0x50,0x65,0x95,0x41,0xae,0x7e,0x5c,0x83,0x3e,0x24,0x3c,0x02,0xa9,0x37,0x49,0x36,0x63,0x2f,0x18,0x92,0x3a,0x8a,0xe5,0x2a,0x6a,0x5c,0xa7,0x3e +.byte 0x98,0x24,0xfd,0xd9,0x3b,0x2d,0x4c,0xe2,0x8e,0x05,0x5b,0xdd,0x47,0x0f,0x19,0x5a,0x62,0x94,0xd6,0x6e,0x45,0xd8,0x99,0x43,0x78,0xa0,0xb1,0xdf,0x68,0x8a,0x56,0xa8,0xfb,0x2e,0x52,0x4e,0xfa,0x21,0xec,0x62,0x14,0xf5,0x90,0xdb,0x8c,0x02,0xa7,0xff,0x29,0x22,0xb8,0x40,0x87,0x58,0xda,0x4e,0xfd,0xab,0xeb,0xa2,0x40,0xce,0xfc,0x58 +.byte 0x46,0x37,0x3f,0x04,0x4e,0x36,0x76,0x44,0x3c,0xfc,0x54,0xb8,0x6f,0x4b,0x66,0x6a,0x4a,0x78,0x8f,0x33,0x86,0x07,0xe4,0x3c,0xb5,0x0f,0x86,0x2e,0x21,0x7e,0x44,0xce,0x18,0x77,0xe0,0xcc,0xd7,0x7f,0xc9,0xac,0xb7,0x2b,0x94,0xb5,0x91,0xcd,0x2c,0xfa,0xc7,0x98,0xbd,0xb0,0x2a,0x85,0x77,0xcf,0x82,0xd9,0xae,0x76,0x33,0x34,0xc0,0x9d +.byte 0x3a,0xbc,0x27,0xbc,0x97,0x25,0xf4,0xf1,0x43,0x53,0xac,0xf6,0xde,0xf5,0x1f,0xa6,0x6a,0xd5,0xe3,0x11,0x32,0x49,0x46,0x5b,0x56,0x68,0x07,0xdb,0x03,0xad,0xc2,0x35,0x16,0x8f,0x01,0xcc,0x8a,0xd2,0x0c,0x6b,0xb2,0x62,0x73,0x99,0xb5,0x74,0xf1,0x4b,0x2e,0xbc,0x8e,0xed,0xc0,0x55,0x56,0x40,0xae,0x24,0xf2,0x7e,0x1f,0xba,0x9d,0xc4 +.byte 0xd1,0x69,0xd3,0xba,0x21,0x83,0xf5,0xc4,0xbf,0x78,0x96,0x74,0xa1,0xd8,0x8c,0x35,0xba,0x9f,0xa0,0x0f,0xb5,0x6a,0xb2,0x72,0x52,0xfa,0x02,0x71,0xbb,0x79,0x61,0xbd,0xa9,0xee,0x22,0x7c,0xc5,0xac,0x6b,0x52,0x67,0xab,0xc4,0xd2,0x8d,0x26,0x1c,0x2b,0xaf,0x0c,0xa4,0xce,0xb5,0x11,0x99,0x4d,0x22,0x69,0x68,0xe0,0xc6,0x3e,0x84,0x3d +.byte 0xeb,0xad,0xc9,0x5b,0xb5,0xb4,0xba,0x06,0x9b,0x0a,0xb2,0x54,0x89,0xf2,0xb0,0x5f,0x41,0xb4,0x8b,0x21,0x31,0x29,0x94,0x52,0x1e,0xa7,0xc4,0xc2,0x97,0xb9,0x74,0x95,0xa3,0x30,0xfb,0x02,0x77,0x01,0x4f,0x32,0x03,0x34,0x8f,0x51,0x2d,0x10,0x61,0xee,0xc5,0x2f,0x89,0x42,0x3c,0xbe,0xed,0x66,0xa6,0x7a,0x10,0xc6,0x06,0x7e,0xb2,0x3d +.byte 0xf2,0xc9,0xd1,0x08,0x97,0x6c,0x6f,0x6d,0x06,0x9d,0x72,0xd0,0x5e,0x79,0x3b,0xa5,0xa5,0xd0,0xdc,0xc6,0xda,0x73,0xd2,0xf3,0x0a,0xfd,0x94,0xc2,0x9c,0x4b,0x85,0x38,0x8d,0xb2,0xfb,0x29,0xdd,0x90,0xc2,0xb7,0x8f,0x2c,0x52,0xa2,0x32,0x5e,0xa1,0x0f,0x62,0x38,0x58,0xfa,0x46,0x4e,0x87,0x4b,0xcf,0xc5,0xe9,0xfc,0xf2,0x97,0x62,0xdd +.byte 0x92,0xd2,0x41,0x7b,0xa2,0x2a,0xae,0x6e,0x4d,0xbc,0xef,0x43,0x18,0x6e,0xbb,0xe5,0x06,0x45,0x53,0xa1,0x00,0xef,0xf5,0x4b,0xad,0xbd,0xa5,0x2c,0x77,0x0a,0x37,0x04,0x22,0x95,0xeb,0x7b,0xc1,0x3c,0x20,0x0a,0x44,0xdf,0xa2,0x23,0xc9,0xfc,0x85,0xf3,0x5b,0x9b,0x0f,0x40,0x2a,0xe3,0xc7,0x5a,0xa1,0xf6,0xe4,0x39,0x2a,0xfe,0xd7,0xe7 +.byte 0x33,0xd8,0xbc,0xd6,0x1f,0xef,0xac,0xa9,0x3f,0x2d,0x55,0xb0,0x85,0x74,0xef,0xeb,0xcd,0x9b,0x23,0xa3,0xe6,0x19,0xde,0xea,0x7c,0x9c,0x83,0x48,0x4b,0x12,0xfd,0xe3,0xcb,0x1b,0x70,0x2d,0x9f,0x2c,0x13,0x82,0x87,0x68,0xca,0x60,0x5e,0xc0,0x2e,0x60,0xde,0xf2,0x6b,0x78,0x0a,0x63,0xaa,0x9c,0x9b,0x61,0x63,0xc7,0x0c,0x98,0x92,0x68 +.byte 0xc7,0x44,0x00,0x6a,0x76,0x43,0xa0,0x61,0x7c,0x37,0x62,0x1a,0xd4,0x9b,0x58,0x59,0xe5,0xae,0x78,0x79,0x80,0xf0,0x75,0x68,0x9e,0xab,0x02,0xb8,0x00,0xc5,0x33,0x0d,0xea,0xb1,0x91,0x0f,0x17,0x57,0x96,0x23,0x8d,0x36,0x4d,0x89,0x94,0x42,0xc9,0x61,0x6e,0xf6,0x9f,0x37,0xee,0xa5,0x4b,0x3d,0x06,0x08,0xee,0x9a,0x7c,0x73,0xa9,0x58 +.byte 0xcd,0xcb,0x78,0xa9,0x3d,0x5c,0x11,0x0e,0x5a,0xd9,0xb0,0x7b,0xc4,0x3e,0x83,0xdc,0xe2,0x11,0xe9,0x6d,0x8a,0x8b,0x24,0x28,0x1d,0x7e,0x45,0x1b,0x05,0x5a,0x6b,0x97,0x1c,0x25,0x15,0x84,0x5c,0x3f,0x95,0x44,0xd5,0x4f,0x3c,0x4b,0x52,0xb1,0x0b,0x6a,0xb3,0xae,0x4e,0x1b,0x12,0xcf,0x16,0x78,0xd7,0xcb,0x32,0x43,0x39,0x88,0xf4,0x5e +.byte 0x26,0x29,0xe7,0x93,0x08,0x19,0x14,0x88,0x8f,0x54,0x91,0x13,0xb6,0x57,0xd1,0x87,0xd4,0x9d,0xf7,0xec,0x9b,0x22,0x6b,0x91,0x79,0x9d,0x6c,0x32,0x47,0x4a,0x79,0x55,0x7d,0xac,0x87,0x98,0x59,0x97,0xa5,0x71,0xbc,0xbf,0x1b,0xf0,0x6f,0xbb,0x81,0x8e,0xc2,0xef,0x7c,0x63,0x2f,0x80,0x37,0xb6,0xc5,0xae,0x59,0x5e,0x57,0x5e,0x1f,0x3a +.byte 0xe5,0x6b,0x6b,0x5e,0xdb,0x8e,0xd2,0x87,0xf7,0x94,0x7b,0x11,0x0e,0x4b,0xa6,0x9f,0x49,0xc6,0x68,0xc7,0x52,0x5f,0x28,0x87,0x33,0x84,0x52,0x5f,0xc8,0x5f,0x81,0x85,0x10,0xe8,0x92,0xce,0x13,0x6c,0x01,0x28,0x5e,0x59,0x8f,0xbb,0xa9,0x9c,0xdc,0x85,0xd3,0x73,0xa0,0x5a,0xbf,0x5b,0x04,0x80,0x99,0x90,0xc8,0x16,0x44,0x0d,0x09,0x01 +.byte 0xcd,0x24,0xe7,0x59,0xe7,0x42,0xe0,0xdd,0x01,0x93,0x1f,0x9e,0x1f,0x36,0xdb,0xcd,0x49,0xdb,0xea,0xa9,0x63,0x71,0xb9,0x2c,0xcd,0xca,0x1a,0x64,0xe1,0x95,0xbe,0xe1,0x64,0x2e,0xc7,0x59,0x15,0x61,0xe1,0xf9,0x45,0x0f,0x2a,0x3a,0x85,0xf8,0x7c,0x06,0xae,0x53,0x84,0xd2,0xe7,0xee,0x8b,0xbf,0x7a,0x72,0xa3,0x57,0xf1,0xc2,0x12,0x40 +.byte 0x9c,0x93,0xe1,0x04,0x81,0xde,0xc6,0xa8,0xae,0x4f,0x5c,0x31,0x93,0xc7,0x11,0x1d,0x89,0x70,0x85,0xd5,0x6f,0xab,0x58,0x1f,0x3f,0x76,0x45,0x7e,0x19,0xd0,0x6c,0xc1,0x41,0xa9,0x64,0x0a,0x79,0xb5,0xe0,0x9e,0xbc,0x4f,0x10,0x0c,0xac,0xfc,0x54,0xad,0xcf,0xb8,0xd0,0xfd,0x9b,0xed,0xea,0x54,0x05,0xbf,0x4f,0x91,0xbd,0x16,0x4a,0x57 +.byte 0xa9,0xda,0x38,0xb9,0x40,0x0d,0x63,0x68,0x83,0x7d,0xec,0x1c,0xe6,0x7f,0x9c,0xec,0x16,0x4e,0x0b,0xd0,0x91,0xb4,0x2c,0x04,0x65,0xb8,0x12,0xdf,0x3f,0xff,0x6a,0x08,0x4e,0x65,0xdf,0x09,0xa5,0xea,0xb1,0xac,0xa9,0x67,0xd2,0xbb,0x73,0x51,0xd2,0x37,0x72,0xfc,0x3f,0x69,0xe2,0x3f,0x01,0x94,0x3a,0xf7,0x23,0x0e,0x5d,0x23,0x44,0x82 +.byte 0xc7,0x38,0x35,0x9f,0xfa,0x13,0x15,0x47,0x0d,0x18,0xab,0x02,0x39,0x6e,0xb2,0x7c,0x29,0x11,0x9a,0x5a,0x01,0x2d,0xb2,0x10,0xea,0x9d,0xb7,0x37,0x4b,0xf2,0x2b,0x76,0x22,0xf7,0xaf,0x8a,0x5f,0x1d,0x6b,0xb2,0x13,0x9e,0x84,0xf5,0xbc,0x6e,0xad,0x66,0x5c,0x1b,0x5d,0x12,0xb0,0xe1,0x48,0x94,0x83,0xa0,0x26,0x54,0xd2,0xfd,0x3c,0x8d +.byte 0x81,0xac,0x31,0x9a,0x15,0xc6,0xd8,0xd5,0x07,0x1b,0x21,0x3f,0x04,0x40,0x3a,0x60,0x80,0x5f,0x1f,0x42,0x3e,0xd7,0x2b,0x7a,0x5f,0x71,0x93,0xb4,0x9d,0xf0,0x8b,0x5e,0xf1,0xc6,0x19,0x0a,0xa9,0x43,0xac,0xb2,0xc1,0x73,0x0d,0x44,0x6a,0x92,0x22,0xd0,0xda,0x40,0x14,0x7d,0x88,0xd1,0x5e,0x10,0xc9,0xa4,0x4d,0xd8,0xe0,0x7d,0x74,0x1b +.byte 0x2b,0xcb,0x50,0x24,0xbd,0x50,0x4a,0xe4,0xed,0x0e,0xe8,0xc0,0x5b,0x50,0x6d,0xf5,0x68,0x59,0xd1,0xc3,0x6f,0x32,0x86,0x29,0xe0,0x32,0x3f,0x05,0x86,0xa2,0x7f,0x93,0xd8,0xb7,0x02,0x68,0xb3,0x16,0xaa,0x0c,0xd3,0x4d,0xec,0x9a,0x66,0x06,0x7c,0x74,0x35,0x6f,0xde,0x8b,0xd9,0xdb,0x79,0x0a,0x15,0x84,0xc4,0x63,0xba,0x42,0xa2,0x3c +.byte 0x29,0xc8,0x65,0xdc,0x06,0x60,0x0a,0x08,0x4e,0x80,0x33,0x5c,0xfa,0x4b,0x91,0xdb,0xf6,0x57,0xd6,0x25,0x7d,0x70,0x80,0x09,0xb2,0x27,0xdb,0x80,0x4c,0xa7,0xe8,0x35,0xf5,0x18,0x2d,0x10,0x62,0x22,0xf9,0xb1,0x22,0xf3,0x9b,0x74,0xa0,0xc5,0x25,0xd3,0x44,0xc9,0x27,0x7c,0xba,0x01,0xfe,0x32,0x23,0xf7,0x90,0x90,0xbc,0x0d,0xad,0x9e +.byte 0x22,0x77,0xc5,0xfb,0xf2,0x0e,0xda,0xe5,0x7c,0xb4,0xbb,0xed,0xd4,0xfd,0xb0,0xfb,0x4a,0x4c,0x2a,0x32,0x2d,0x81,0xcd,0xef,0x74,0x3c,0x6a,0x9a,0x0c,0x95,0x58,0x25,0xd0,0x3a,0xb4,0x84,0x8f,0xa5,0xef,0xad,0x91,0xd7,0x2d,0xae,0x61,0xaf,0x9d,0x3f,0x03,0xa8,0xab,0xa4,0x66,0xd4,0x73,0x3a,0x84,0x0d,0x4c,0x6a,0xca,0xbd,0x0c,0x3c +.byte 0xdc,0x1d,0x37,0xea,0xe6,0x5a,0x7f,0x15,0xbe,0x9d,0xc7,0xce,0xbd,0x46,0x97,0xd3,0x07,0x19,0x82,0xaf,0x58,0x39,0x39,0x95,0x5d,0x4b,0x8e,0x1b,0xe9,0xf1,0xf6,0xa9,0xb3,0xfc,0xe6,0xe0,0x68,0x2c,0xbb,0xfa,0xd9,0x9b,0xc1,0x69,0xf3,0x5a,0x8f,0x67,0xd5,0x9c,0x11,0x1e,0x02,0x20,0x20,0xfe,0x4b,0xc9,0x8b,0x62,0x17,0x9a,0xfa,0x47 +.byte 0x7f,0xa2,0x8b,0xc1,0x3b,0x02,0x78,0x38,0xff,0xce,0xe1,0x54,0x40,0x3f,0x27,0x5c,0x9d,0xdd,0x56,0x38,0x48,0xea,0x39,0xbe,0xa0,0x76,0x43,0x82,0xef,0x74,0x50,0xdf,0xda,0x4c,0xca,0x47,0x46,0x7e,0xc5,0xff,0xce,0x66,0xdf,0xeb,0x5b,0x6e,0x45,0x77,0x19,0xac,0x01,0x1f,0x20,0xa1,0xad,0x01,0x5f,0x87,0x3e,0x3a,0xd0,0x83,0x13,0x17 +.byte 0x53,0x40,0xfe,0x26,0x99,0x42,0xfa,0x54,0xa8,0x82,0x79,0xa7,0x44,0xd0,0x9e,0x59,0x64,0x77,0xec,0x70,0x0e,0xcd,0xb9,0xb1,0xc2,0xe2,0x39,0x93,0xb7,0xd1,0xd5,0x67,0x9f,0xb0,0x5b,0xd9,0x50,0x8b,0x17,0xec,0xbc,0x83,0x64,0x35,0xaa,0x43,0x3f,0x4c,0x8c,0x56,0x83,0x76,0xa2,0x72,0x30,0xe7,0xe8,0x9f,0x88,0x35,0x8e,0x8d,0x11,0x31 +.byte 0x8e,0xb5,0x71,0x75,0x31,0xc8,0x28,0x15,0x50,0xe6,0x0a,0x00,0x4d,0x75,0x51,0x7c,0x33,0x14,0x96,0xff,0xe8,0xf3,0xa0,0xb1,0x9c,0xeb,0x9d,0x8a,0x45,0xcf,0x62,0x82,0xeb,0xce,0xea,0xa5,0xb9,0x10,0x83,0x54,0x79,0xf8,0xcf,0x67,0x82,0x1d,0xea,0xce,0x86,0xcf,0xc3,0x94,0xf0,0xe8,0xf4,0x80,0x8b,0x84,0x96,0x06,0x2e,0xe4,0x58,0x21 +.byte 0x98,0x42,0x1a,0xb7,0x8c,0x5d,0x30,0x15,0x83,0xe8,0x17,0xd4,0xb8,0x7b,0x90,0x57,0x35,0x72,0x6d,0x1b,0x7c,0xc0,0x88,0x0a,0xa2,0xea,0xcd,0x58,0xcc,0xf1,0xb4,0x8b,0xcd,0x66,0x3c,0xa5,0xb0,0xd4,0xc9,0xcc,0x42,0x1d,0xef,0x3b,0x42,0x22,0x9b,0xfb,0x45,0x24,0xcc,0x66,0xd7,0x67,0x73,0xb2,0x12,0x03,0xf6,0xa3,0x06,0x61,0xe2,0xab +.byte 0x91,0x8e,0x33,0x0b,0x9f,0x6a,0x80,0x5e,0x0f,0x68,0x41,0x5a,0x7e,0xd8,0xe2,0x32,0x50,0xc2,0x88,0x60,0xca,0xe3,0x23,0x86,0xff,0xdc,0x0c,0x19,0xbb,0xba,0x01,0xa3,0x41,0x89,0xf0,0x79,0x55,0x79,0xa6,0xa4,0x66,0x7b,0x46,0xde,0xac,0xae,0xb1,0xde,0xe1,0x1e,0x8d,0x62,0xc1,0xd6,0xeb,0x39,0x2f,0x1d,0x50,0x27,0x53,0xc9,0xea,0xb6 +.byte 0xd3,0x91,0x9b,0xdd,0xc1,0x68,0x8c,0xb6,0xe1,0x5e,0x9f,0xea,0xbe,0x98,0x88,0xeb,0xa8,0x77,0xf6,0x69,0x64,0xab,0x99,0xf3,0x7a,0x08,0xff,0x8c,0xa6,0x17,0x1b,0x2e,0x6e,0xcc,0xd8,0x33,0x30,0xef,0x5a,0x86,0x07,0x49,0xa5,0x13,0x08,0xbc,0xd6,0x88,0x7e,0x19,0xe0,0x1c,0x23,0xa9,0xe5,0x0a,0xa7,0xaf,0x8a,0xe9,0x81,0x3f,0xd8,0x99 +.byte 0xa6,0x01,0x6b,0xec,0x14,0x08,0x90,0xb1,0x76,0x16,0x3a,0xcb,0x34,0x0b,0x91,0x26,0xe9,0xec,0xe5,0xbc,0xd6,0xdc,0xf0,0xa9,0xfd,0xf2,0xe9,0xcc,0xa1,0x9d,0x7f,0x32,0x0d,0x0a,0x2a,0x92,0xff,0xc4,0x38,0xf8,0x9e,0x31,0x78,0x47,0xbf,0x3f,0x27,0x71,0xe1,0x7a,0x33,0x48,0x91,0xe8,0x8e,0x1a,0x66,0xcf,0xa1,0x61,0xc2,0x62,0x30,0x7c +.byte 0x69,0x35,0x21,0x67,0x9b,0xa7,0x1c,0x72,0x06,0xd8,0x28,0x94,0x6e,0x6d,0xf0,0x22,0x85,0xb4,0x6c,0x89,0xe8,0x2e,0x3a,0xc5,0xdc,0xe3,0xe3,0x0c,0x8a,0xba,0x1c,0x57,0x86,0xef,0x55,0x6a,0x24,0x59,0x5e,0x6e,0x47,0xb8,0xad,0xc5,0x10,0xff,0xbe,0x2d,0x93,0x09,0xfe,0x17,0x03,0x16,0x4d,0x4a,0x9a,0x15,0x38,0x94,0x38,0x18,0x45,0xa7 +.byte 0xcf,0xe4,0x16,0xd3,0x26,0x72,0x49,0xe7,0x89,0x9a,0xb4,0xc7,0x78,0xc3,0x18,0x3b,0xc8,0x08,0x9d,0x66,0x0f,0x48,0xc8,0x23,0x91,0x57,0x61,0xf1,0xf3,0x01,0x3e,0x0a,0xa3,0x4c,0x6c,0x34,0x5b,0x98,0x40,0x47,0x42,0xc1,0xeb,0x58,0x58,0xff,0x1f,0x4b,0x5f,0xf1,0x29,0x2e,0x7e,0x76,0x15,0x56,0x17,0x9c,0xe7,0x55,0x09,0x22,0x0a,0xa2 +.byte 0xd8,0xbf,0xd9,0x44,0x49,0xa9,0x24,0xd7,0x4f,0x12,0x04,0xa2,0x18,0x1c,0xdc,0x54,0xc0,0x22,0x27,0x3c,0xeb,0x1f,0x02,0xae,0xb3,0x33,0xb2,0xa2,0x84,0x23,0x76,0xc6,0x2b,0x94,0x53,0xae,0x7b,0xee,0xbb,0x81,0x64,0x8a,0x3f,0xe0,0x75,0x6b,0x2c,0xd5,0x60,0xad,0x49,0x0c,0xf8,0x65,0x64,0x1a,0x83,0xc7,0xb9,0xd9,0x01,0x5b,0xde,0xb0 +.byte 0x76,0x9b,0x1c,0x0d,0x89,0x2d,0xd5,0x09,0xc7,0xa9,0xbb,0x0a,0x54,0x5c,0xd4,0x5b,0xbf,0xbc,0x5e,0x00,0x29,0x0b,0x30,0x19,0x73,0x66,0xfd,0x3f,0xdb,0xd4,0x1b,0xd4,0xc0,0x27,0xde,0x49,0x90,0x5f,0x65,0x87,0x3c,0xc4,0x43,0xd0,0x49,0x76,0x64,0x39,0x88,0xd7,0x0e,0xfc,0x27,0x52,0xb1,0x8d,0xd0,0x27,0x29,0x84,0xe3,0x49,0xb9,0x0c +.byte 0x2d,0x4e,0x73,0x95,0x57,0xa8,0x07,0xa0,0xe1,0x5b,0x5a,0xb6,0xbc,0xa1,0x7f,0xfd,0x4b,0x9c,0x4d,0x7d,0x0c,0x5c,0x4c,0x4b,0x42,0x70,0xc3,0x0a,0xc1,0x89,0x12,0xb5,0x46,0x04,0x3c,0x56,0x25,0xc6,0x8f,0x49,0x7d,0x3b,0xf1,0xcd,0xfc,0xb8,0xa6,0x66,0xb1,0xc2,0xa3,0xa7,0x98,0x93,0x0e,0xdb,0xcd,0xce,0xdf,0x7f,0x68,0x5e,0xea,0xf2 +.byte 0x85,0x61,0x8f,0xd6,0x23,0xb4,0x5f,0x2f,0xf8,0x78,0x47,0x15,0x59,0x2d,0xca,0x35,0x0f,0xf5,0x91,0x74,0x3b,0x32,0xe1,0xcf,0x54,0x1b,0xf4,0x9d,0xdb,0x20,0x5e,0xf8,0x71,0x10,0xa3,0x31,0xf1,0xb8,0x98,0x8d,0x76,0x70,0xce,0x4c,0xed,0xd3,0x81,0x6b,0xd5,0x8d,0x73,0x5f,0x8c,0x66,0x7c,0x87,0x73,0xfa,0x20,0xbe,0xcd,0xba,0x41,0x88 +.byte 0x46,0xc3,0x38,0xc0,0xd9,0x08,0x79,0x30,0xda,0x7f,0x2a,0xc0,0x72,0x47,0xb0,0xc9,0x41,0x68,0xb1,0xe8,0xb4,0x86,0xcb,0x5d,0xb0,0x5b,0x7a,0x26,0xfd,0xf2,0x1b,0x4e,0x1f,0x4c,0x6a,0x8a,0x84,0xd4,0x07,0x2f,0xf4,0x06,0x73,0x3d,0x1c,0x55,0x04,0x6a,0xa5,0x8a,0xbb,0xaa,0x8a,0x8d,0x8f,0x05,0xcc,0x63,0x04,0xe0,0xc6,0x6f,0x6b,0xf8 +.byte 0x24,0x56,0xbb,0x9d,0xa9,0xe5,0x4c,0xac,0x9d,0xbe,0xfd,0x70,0x9d,0x1f,0x98,0xc4,0xfc,0xdb,0x3c,0x45,0xe7,0xbb,0xea,0x51,0xb6,0x56,0xe0,0x2c,0xb2,0x77,0x1b,0x80,0x9b,0x43,0xa7,0xb2,0x9a,0x40,0x8f,0xdb,0x2d,0x51,0x7b,0x2c,0x89,0xfd,0x14,0xf5,0x77,0xbf,0x40,0x3d,0x32,0xe0,0x10,0x32,0xcd,0xc4,0x3f,0xe2,0xe8,0xb4,0xdf,0xc2 +.byte 0x43,0x7a,0x0b,0x17,0x72,0xa1,0x0e,0xd6,0x66,0x35,0x8f,0xf4,0x21,0xf1,0xe3,0x46,0x13,0xd7,0xcd,0xc7,0x7b,0xb4,0x9b,0x39,0x1e,0x33,0x3c,0x18,0x15,0x7a,0xea,0x77,0xc5,0x57,0x4d,0xf9,0x35,0x8a,0xc1,0xb5,0x78,0x5d,0xc3,0x3e,0xd5,0xfd,0xb5,0x50,0xee,0x44,0x24,0xa2,0x55,0xb6,0xd8,0x3d,0x5d,0x75,0x2a,0x26,0x37,0xe7,0x85,0xb3 +.byte 0xff,0x70,0x5d,0x99,0x8d,0x99,0xba,0x9d,0x09,0x97,0xf2,0x67,0xe5,0xa3,0x86,0x06,0x21,0xb4,0x03,0x9b,0x63,0x76,0x1f,0xf8,0x09,0xd8,0x4e,0x22,0xcb,0x48,0xcf,0x79,0x72,0xc9,0x3f,0x84,0x5e,0xb8,0x39,0x87,0x27,0x92,0x1e,0x59,0xdf,0xc2,0xe6,0xd2,0xc4,0x5f,0xad,0x6e,0x9c,0xa4,0xec,0xd5,0x7d,0xf6,0x2b,0x9b,0x93,0x56,0xcd,0xa3 +.byte 0xc5,0xfa,0x82,0x39,0x46,0x29,0x57,0x43,0x08,0xe2,0xe1,0x3e,0x80,0x3b,0x8e,0x08,0xe5,0xc5,0xfe,0x05,0x17,0xaf,0xe0,0xf0,0xb7,0x5b,0x34,0x33,0x59,0xfa,0x93,0xbf,0x6a,0xb3,0x6c,0xbc,0x99,0x62,0x34,0x2c,0xf2,0x3b,0x62,0xf2,0x1c,0x48,0x07,0xc9,0x60,0x03,0xa5,0xe1,0x66,0x8d,0x84,0x36,0xc7,0xf9,0xc6,0x3b,0xa9,0xee,0x0f,0x48 +.byte 0xff,0xff,0xad,0x95,0x21,0xb5,0x12,0x63,0x7d,0x0f,0x0d,0x09,0x63,0x51,0x64,0x69,0xb4,0x95,0xd3,0x25,0xf0,0x3b,0x6d,0xc4,0xdd,0x8c,0x80,0x0d,0x3b,0xd2,0x4b,0xe0,0x67,0xcb,0xcd,0x7d,0x2e,0xbd,0x61,0x4b,0x0c,0x32,0x1f,0xfd,0xd2,0x31,0xed,0xa8,0xaa,0x98,0xf4,0x85,0x21,0xbc,0x08,0x14,0x2f,0xbb,0xbf,0x01,0xba,0x24,0x5e,0x5c +.byte 0xf3,0x72,0xed,0x05,0xec,0xf3,0xd1,0x9b,0xb0,0x63,0x8a,0x14,0xd1,0x9e,0xae,0x9b,0xce,0x4d,0x6c,0xb6,0x7a,0x78,0x9e,0x1d,0xcd,0x1e,0x50,0x66,0x26,0x70,0x74,0x2b,0x43,0x6a,0xc7,0xd7,0xe9,0xa2,0xcf,0xf3,0x09,0x9a,0x81,0x80,0x04,0xb8,0x5a,0x4f,0x2e,0x10,0x35,0xb2,0xb0,0xc6,0x40,0x97,0xa5,0x6a,0x24,0x5a,0x6b,0x97,0xc7,0xc0 +.byte 0x24,0x50,0x8d,0x65,0x21,0x25,0xce,0xb9,0x19,0xfc,0x40,0x08,0xcf,0xfd,0x1c,0xc4,0x30,0xd4,0x06,0x70,0xac,0x8a,0x3c,0x3f,0xfc,0xc3,0xeb,0xdd,0x43,0x56,0x4a,0xf6,0x50,0x92,0x9d,0xce,0x9c,0xea,0x15,0xdd,0x7c,0x5e,0x40,0xf5,0x7e,0x41,0x70,0xdd,0xc7,0x62,0x21,0x5a,0x20,0xc8,0x71,0x10,0x97,0xd5,0x12,0xfa,0x31,0x96,0xfb,0x38 +.byte 0x17,0x66,0x73,0x32,0x7a,0x93,0xf0,0x82,0xb9,0xf1,0x24,0xc5,0x64,0x0b,0xa9,0x24,0x4a,0x47,0xac,0xfb,0xf1,0x55,0xd7,0xb3,0x9a,0x64,0x63,0x0b,0x2e,0x13,0x9e,0x1a,0xee,0x21,0xd0,0x70,0x5c,0x0c,0x25,0xe7,0x38,0x23,0xd7,0x2f,0x6a,0x20,0x59,0xef,0x70,0xb2,0x8e,0xb4,0x15,0xee,0x6f,0x70,0xd0,0x75,0x19,0x9d,0x42,0xa7,0x17,0xad +.byte 0x99,0xaa,0x0d,0xa3,0x87,0x3d,0xf1,0x7b,0x0e,0xfa,0x62,0x9a,0x20,0x64,0x17,0x64,0x07,0xc2,0x84,0x13,0xb2,0x59,0x81,0x66,0x45,0xab,0x47,0x6d,0xfc,0x7b,0x60,0x05,0xac,0x30,0xb2,0x86,0x7e,0x34,0x6b,0xaf,0x37,0x00,0xa6,0x47,0x4c,0xb9,0x10,0xbd,0x9e,0xce,0x47,0x9e,0xc2,0x0e,0xfd,0x47,0xfa,0xd8,0x08,0xd1,0xc2,0xaa,0x6d,0x8c +.byte 0x91,0x2c,0x18,0x32,0x52,0x84,0x47,0x71,0x3b,0xc9,0xa1,0xf5,0xfc,0x90,0xb8,0x79,0xbf,0xe5,0x59,0x1b,0x91,0x22,0xcb,0xd3,0x87,0x7e,0xd4,0xb5,0x33,0xb2,0xfc,0x7c,0xee,0x22,0xfb,0xe8,0xb0,0x3c,0xa7,0x8b,0x05,0xd7,0x7f,0x17,0x52,0xbe,0xb6,0xe0,0x1e,0x47,0xce,0xfd,0x79,0xdf,0x16,0x5f,0x01,0x70,0x0c,0x47,0x5a,0x01,0x96,0x08 +.byte 0x3e,0x9b,0xc4,0xb2,0x58,0x73,0xc4,0x38,0xd6,0xf2,0x1b,0x0a,0x2c,0xb9,0x2a,0x96,0xb5,0x89,0x2d,0x33,0xdf,0xa4,0x5f,0x24,0x1b,0x79,0x0e,0xb6,0x9f,0xec,0x46,0xd3,0x27,0x4a,0xc1,0x26,0x94,0x95,0x41,0xd5,0xb3,0x84,0x74,0x62,0x47,0xc5,0x4d,0xb4,0xe2,0xe7,0xdb,0xc3,0xc3,0x7b,0x33,0x2a,0xbf,0x69,0xf6,0x5e,0xdc,0xfe,0xa4,0x81 +.byte 0x91,0xf3,0xa8,0x26,0x82,0x44,0x37,0xea,0xe1,0x20,0xff,0x52,0x33,0x5b,0x0b,0x6f,0xf8,0x33,0x4e,0x02,0x4d,0x38,0x93,0xcd,0xc0,0xfc,0x73,0x1a,0xf9,0xf6,0x9f,0x53,0xfc,0xf7,0xe2,0x4b,0x25,0xdd,0xa7,0x4d,0x1e,0x5c,0x17,0xc3,0xa0,0x41,0x1d,0x67,0x45,0xff,0xcb,0x41,0x49,0xc4,0x18,0x68,0x7e,0x7f,0xb6,0x6f,0xdb,0xbc,0x73,0x2f +.byte 0xc7,0x9a,0x46,0x8c,0x0b,0x57,0xa3,0xd3,0x0a,0x34,0xb7,0x27,0x67,0xbb,0xe1,0x64,0xa7,0x7e,0x79,0xac,0x4f,0x09,0x54,0x9b,0x43,0x5e,0x9a,0x33,0x02,0x45,0xdc,0x85,0x0b,0x59,0x8d,0x78,0xe8,0xd8,0xb5,0xd3,0x31,0x9d,0x2a,0x60,0x5b,0x91,0xed,0xf1,0xf1,0x37,0x3f,0xdb,0xda,0xd6,0xd1,0x8f,0x14,0x7e,0xe1,0xfc,0x92,0x60,0xa5,0x33 +.byte 0x86,0xef,0x29,0xbf,0x94,0x84,0x2b,0x24,0x20,0xb4,0x5e,0x23,0x34,0x08,0x63,0xc9,0xe6,0x80,0xa0,0x27,0x27,0x2f,0xab,0xc0,0x52,0x44,0x66,0x29,0x32,0x2e,0x91,0x96,0x02,0x1c,0x3b,0xb4,0x6e,0x33,0x49,0x5b,0x60,0x6f,0x14,0x93,0x65,0x0d,0x97,0x01,0xfb,0xf9,0x42,0x74,0xb6,0x21,0xf7,0xc2,0x5d,0xbf,0x91,0x2b,0xf5,0xb1,0x4e,0xe2 +.byte 0xd6,0x24,0x57,0x41,0x7a,0xcb,0xdd,0xb6,0x96,0x8b,0xfc,0x42,0x19,0x21,0x7f,0x41,0x32,0x3d,0x69,0x9b,0xee,0xda,0x97,0x45,0x26,0x71,0x0d,0x12,0xf0,0x20,0x7f,0x44,0x0f,0x4c,0xd2,0xd3,0x34,0x93,0xc7,0xe5,0xe7,0x83,0x62,0x13,0x0b,0x7d,0xc6,0xe4,0xd2,0xae,0x53,0x2e,0xd1,0x18,0x81,0xd0,0x81,0xf6,0xc0,0x98,0xaf,0x1d,0xb2,0x8a +.byte 0xcb,0xd3,0xde,0x1d,0x53,0x71,0x92,0x0e,0x4b,0x8c,0x7c,0x8e,0x65,0xf6,0xe2,0xc2,0x5a,0x4f,0x8c,0x59,0x0f,0x35,0x5e,0xe4,0x43,0x50,0xab,0xb7,0xdd,0xfc,0x66,0xf9,0xb1,0x9b,0x6b,0x1b,0xaf,0x2e,0x85,0xe6,0x3e,0x4c,0xa2,0xd4,0x55,0x47,0xb9,0x66,0x66,0x7b,0xa3,0xb2,0xd5,0x8a,0x8e,0x88,0x0e,0xfb,0x4e,0xad,0xf4,0x39,0xd2,0xd6 +.byte 0x39,0xef,0xe0,0xee,0x0f,0xf3,0x94,0x47,0xa7,0x32,0x24,0x9a,0xb0,0x82,0x08,0x67,0x00,0x3f,0xe6,0x95,0x76,0x84,0x0a,0x5c,0xb7,0x74,0xc1,0x64,0x5e,0x7c,0xba,0x0b,0x2e,0x6f,0x26,0xc3,0x20,0x2e,0x95,0xc1,0xf0,0x8c,0x55,0x4a,0x45,0x26,0xe6,0xf3,0x55,0x78,0xbd,0xd4,0xdb,0x07,0xbd,0xff,0x61,0x51,0xde,0x7f,0xdb,0x56,0x73,0x6b +.byte 0x9c,0xa4,0xb0,0x72,0xa7,0xd0,0x93,0x4d,0x1d,0x3a,0x92,0x78,0xde,0x77,0x65,0xe8,0x07,0x41,0x92,0xc1,0xbb,0x69,0x79,0x20,0x43,0xab,0x21,0x2e,0x6d,0xdf,0x43,0xeb,0x73,0x49,0x12,0x1f,0x53,0x75,0x01,0xed,0xce,0xf4,0x05,0x05,0x2b,0xc7,0x2a,0x65,0x29,0xe8,0xcf,0x5b,0xf0,0xc1,0x5b,0xd8,0xa8,0xac,0xbb,0xe3,0xac,0x29,0x0a,0x90 +.byte 0x79,0x2f,0x5b,0x92,0x14,0xf2,0xc7,0x2d,0xe5,0x33,0x6e,0x5e,0x31,0xe2,0xab,0xdf,0x21,0x71,0x4a,0x44,0xaa,0xc6,0xe9,0xb8,0x51,0x1d,0xe2,0xf3,0x07,0x19,0xa1,0x98,0x9e,0x8a,0xed,0xe4,0x9e,0x52,0x16,0x1f,0x2f,0xd3,0x4c,0x97,0x1e,0x38,0x49,0x84,0x2e,0x45,0xb5,0x4b,0x4f,0xfe,0xdb,0x25,0x3e,0xa9,0x6e,0x7d,0x60,0x3b,0xa7,0x7e +.byte 0xda,0x32,0x1a,0xd6,0x04,0xbe,0x0c,0x92,0x4e,0x6d,0x85,0xf9,0x9c,0x26,0x9a,0x88,0xf5,0x50,0x95,0x7b,0x9e,0x43,0x07,0x97,0xd4,0xdb,0xa0,0x6e,0x30,0x5d,0x44,0xa9,0x41,0xc2,0xdf,0xdf,0x37,0x35,0xc4,0x85,0x83,0x08,0xea,0x22,0xfa,0xae,0xdd,0x95,0xe5,0x35,0x47,0x23,0x86,0x27,0xfa,0x71,0x88,0xa0,0x12,0x00,0xe0,0xa7,0xd1,0x1b +.byte 0x5e,0x78,0x6f,0x38,0x30,0xa9,0x80,0x75,0xd7,0x61,0xcc,0xfd,0x33,0xd2,0xb8,0xf8,0xd7,0x12,0xf5,0x03,0xf9,0x53,0x6d,0x3b,0x6b,0xff,0x24,0x0a,0x3b,0xe8,0x2a,0xe9,0xae,0xb7,0xc3,0xe3,0x0f,0x26,0x71,0x55,0xc5,0x03,0x60,0xf4,0x47,0x01,0xa3,0x69,0xb2,0x98,0x75,0x5b,0x90,0x4a,0xf9,0x61,0x49,0xd6,0xc4,0xdb,0xab,0x04,0x0c,0x47 +.byte 0x1e,0x31,0x75,0xfa,0xa2,0xc5,0xfa,0x66,0x0c,0x4a,0x93,0xa0,0xea,0x56,0xf9,0x49,0xd4,0xc7,0xcc,0x2c,0xe5,0xdc,0xab,0x61,0x8e,0x0c,0xf3,0x2f,0xb5,0x9f,0x36,0xa1,0x05,0xab,0xb6,0xbc,0x4a,0x6d,0x97,0xe7,0x19,0xe5,0xfe,0x92,0xa5,0x94,0xd5,0xc0,0xf5,0x31,0xf6,0x8a,0xf7,0x24,0x62,0xdd,0x56,0x12,0x84,0xf5,0xc6,0xa0,0x37,0xa3 +.byte 0xfc,0xbd,0x16,0x2a,0xa6,0x36,0x8e,0xd4,0x29,0xfe,0xc4,0xc5,0xcb,0xdd,0xdd,0x8b,0x7e,0xa6,0x9d,0x08,0x28,0x10,0x6b,0xff,0xd7,0x79,0x48,0x35,0x2f,0xbe,0x34,0x9a,0xfb,0xd0,0x7d,0x5c,0xad,0xf0,0xde,0x96,0xea,0x2d,0xc5,0x8b,0xa9,0x7a,0x8b,0xbe,0x97,0xde,0x7a,0x95,0xc7,0x95,0xd9,0x86,0xde,0x3c,0x8d,0x15,0x8e,0x45,0x69,0x27 +.byte 0xd4,0x27,0xa8,0xe3,0xa9,0x1e,0xa0,0x95,0x74,0xf1,0x8b,0xbe,0x3b,0xff,0xa3,0xf6,0x23,0x78,0xd9,0xbd,0xc2,0x44,0x3a,0x93,0xb5,0xa6,0x87,0x7c,0x65,0xd1,0xd8,0xd5,0x43,0x2a,0xb2,0xc8,0x65,0x86,0x83,0x06,0xf7,0x33,0x88,0x3b,0xc0,0x2c,0xb3,0x3b,0x23,0xa3,0x67,0x15,0x49,0x09,0x02,0xbb,0x11,0x08,0xe3,0x37,0x9a,0x9b,0x67,0x8e +.byte 0x63,0xc3,0x8b,0xff,0x21,0xa6,0xbe,0x3b,0xa6,0x57,0xc1,0x56,0x2a,0x02,0xdb,0x24,0x50,0x4a,0x4f,0x60,0x49,0x03,0xcf,0xba,0x55,0x1c,0x64,0xfe,0x0c,0x58,0xb4,0xb0,0x89,0x91,0xd5,0xbc,0xbc,0x85,0xe6,0x96,0x32,0x89,0x1f,0xa0,0x48,0xd1,0x6e,0xa7,0x03,0x86,0x8a,0xf2,0x5f,0xc3,0x5a,0x57,0x8a,0xa3,0x4a,0x61,0x90,0x18,0xb2,0x0d +.byte 0xc7,0x94,0xb9,0x3e,0x40,0x8b,0x1d,0x54,0xd0,0x4c,0xe7,0x2a,0xd5,0x85,0xa7,0x93,0x07,0x10,0x58,0xc4,0x8a,0x18,0x0a,0x49,0x30,0x87,0x93,0x0e,0xcf,0xc7,0x95,0x9f,0xd1,0x3f,0x9b,0x06,0xe3,0xf9,0x4f,0x16,0x58,0x04,0xb4,0xf0,0xf0,0xf3,0x3a,0xab,0x4a,0x35,0xf1,0xec,0x23,0x15,0x0c,0x24,0xba,0x90,0xdc,0xd1,0xfe,0x47,0xca,0xb2 +.byte 0x95,0x33,0x30,0x45,0xba,0x18,0x15,0xec,0x58,0x36,0x02,0xdf,0x28,0x09,0x74,0x4b,0x09,0x01,0x24,0x0f,0x00,0x7b,0xb3,0x65,0x45,0x42,0x63,0x15,0xf8,0x50,0x8b,0x4f,0x28,0x73,0x03,0x3a,0x31,0xe5,0x0d,0x56,0x8f,0x6b,0x4b,0x9e,0xda,0x71,0xee,0x68,0xba,0x85,0x81,0x3d,0x5d,0x74,0x5e,0xda,0x60,0x87,0xf4,0x5a,0x38,0xad,0xc5,0x3f +.byte 0xb5,0x15,0x02,0x59,0x1c,0xd2,0x93,0x66,0x54,0x65,0xf1,0xe7,0x9b,0xf0,0x30,0x2d,0x9e,0xba,0xc5,0x86,0xf4,0xf6,0xc7,0x92,0x73,0x12,0x3b,0x28,0x21,0x1b,0x3d,0x84,0xc0,0x1a,0x7d,0x35,0x8b,0xd4,0x35,0x39,0x35,0xa6,0x51,0xd9,0x19,0x8b,0x92,0xa3,0xea,0x8c,0x7e,0x25,0x05,0x1f,0x1d,0x8f,0x4d,0xba,0xdf,0x20,0x8c,0x8d,0xe2,0xac +.byte 0xdd,0x3d,0xf1,0x04,0x3f,0x77,0x4b,0x8f,0x39,0x7d,0x01,0xb7,0x71,0x4b,0x7b,0xe1,0x6f,0xd4,0x28,0x1a,0x57,0x96,0x4d,0xe2,0x84,0xf6,0x64,0x10,0xbb,0x0f,0xbc,0xe0,0x19,0xed,0x92,0x9e,0x60,0x15,0x78,0xd1,0x30,0xc0,0x53,0x4b,0x94,0xca,0x4b,0x5a,0x44,0x8b,0xa9,0xda,0x2f,0x08,0x70,0x94,0xe4,0x54,0xe1,0x28,0x6e,0xdd,0x34,0x56 +.byte 0x54,0xb0,0xd4,0x87,0x00,0x72,0x1e,0x46,0x10,0x3a,0x27,0x5d,0xc6,0xb5,0x72,0x20,0x2b,0xbe,0x17,0x01,0xbb,0x04,0x11,0x16,0x7d,0xbf,0x91,0xd3,0x7b,0x44,0x58,0x13,0x2a,0x9c,0xda,0x9d,0x26,0x46,0xf5,0x5f,0x51,0xef,0x6c,0xf6,0x36,0xdb,0xb7,0x21,0xde,0xdb,0x87,0xa0,0xd8,0x60,0x24,0x86,0x6d,0x64,0x85,0x9e,0x94,0xd9,0x21,0x0d +.byte 0xed,0xda,0x33,0xea,0x3c,0xdf,0x74,0xe3,0xa5,0xc7,0xc7,0x9e,0xe5,0xb1,0x29,0xdf,0xfa,0x20,0x25,0xcd,0x13,0x08,0xee,0xe6,0xba,0xf1,0x62,0x39,0xcf,0xe3,0x29,0xb8,0xaa,0x65,0x43,0x8a,0x48,0xb5,0xb5,0x70,0x35,0x66,0x42,0xf4,0x32,0x70,0x0b,0x0c,0xa7,0x46,0x79,0xdf,0xb2,0x80,0x13,0x72,0x7a,0xeb,0xf9,0x52,0xcb,0xb8,0x9f,0x4b +.byte 0x4f,0x29,0x2b,0xb3,0x94,0x02,0x0a,0xe1,0x20,0xe5,0x91,0x15,0x6a,0xa1,0x0c,0x71,0x96,0x77,0x01,0x80,0xf7,0x51,0x0b,0xaf,0x54,0x9b,0x3c,0x7b,0x91,0xd2,0xbd,0xaf,0x13,0xa5,0x32,0x17,0x7c,0xca,0xd0,0x22,0xd5,0xe5,0x83,0x44,0x24,0x5c,0xcc,0x24,0x31,0xcd,0x81,0x4e,0x96,0xcd,0x60,0x9f,0x7a,0xe7,0x2e,0x89,0x16,0xd5,0x66,0x6b +.byte 0xac,0x31,0x11,0x7c,0x76,0xc6,0xde,0xbe,0x46,0x55,0x20,0xdf,0x9d,0x2c,0x33,0xa5,0x80,0x76,0xb1,0xc9,0x1c,0x84,0x17,0x4d,0x15,0xe6,0x6d,0xce,0xed,0xea,0xc7,0xe6,0xff,0x01,0x10,0x60,0x26,0xf7,0x63,0x5f,0x91,0x89,0x7e,0xc1,0x7c,0x76,0x67,0x7b,0x7e,0xfa,0x28,0xa0,0xa7,0x82,0x1b,0x28,0x82,0x6a,0x4f,0x78,0x61,0x48,0xbf,0x13 +.byte 0x0b,0x71,0x0c,0xad,0xee,0xd7,0xf8,0xcc,0x0f,0x77,0x74,0x7d,0x2b,0x8a,0x09,0xd8,0x47,0xa0,0xfc,0x45,0x40,0x24,0xf3,0xce,0xdb,0x81,0xa1,0x50,0x9e,0x0a,0xd0,0x58,0xf7,0xaf,0xf1,0x09,0x12,0xa8,0x24,0xb2,0x34,0x99,0x67,0x17,0x53,0x1f,0x9d,0x09,0x7b,0xcb,0x83,0x6e,0x6a,0x0b,0xbf,0x8f,0x6e,0x3d,0xdb,0x29,0xe5,0xd0,0x06,0xdb +.byte 0xb8,0xf2,0xf3,0x43,0x4e,0xa7,0xf3,0x73,0x93,0xe8,0xab,0x2f,0xc8,0x75,0xce,0x62,0xda,0x74,0x39,0x57,0xe4,0xe4,0xb1,0x41,0x8f,0x9d,0xda,0x43,0xb4,0x2c,0x4b,0xd5,0x1c,0x10,0xf0,0x29,0x6b,0x94,0x15,0x04,0x3c,0xd3,0x45,0x73,0x29,0xb3,0x60,0x87,0x93,0xdb,0xbf,0x60,0x4e,0xdf,0x4d,0xbb,0xde,0xb2,0x57,0x67,0x14,0x0d,0x0b,0x60 +.byte 0x63,0xd5,0xc6,0x81,0x82,0xd6,0x0c,0xe6,0x4c,0x43,0x13,0x02,0x74,0x56,0x20,0x6b,0x21,0x28,0xe6,0xe2,0x0b,0xc1,0x7a,0xc3,0x08,0x60,0x82,0xe0,0x4f,0xbf,0x1e,0x3f,0xf0,0xa9,0xb2,0x2e,0x0c,0xbf,0xd6,0x03,0x1d,0x0d,0xd6,0x1c,0x36,0xb5,0xb2,0x14,0x56,0x21,0xc2,0xe0,0x1e,0xff,0xee,0x8a,0x70,0xae,0x3f,0x1e,0xe5,0xac,0x05,0x46 +.byte 0x6b,0x81,0x32,0xce,0x50,0xbb,0x82,0x66,0x32,0x93,0x46,0xf7,0xee,0x77,0x1c,0x9a,0x2f,0x31,0x60,0xa2,0x09,0x7c,0x14,0xd9,0x81,0xe9,0x19,0x27,0x31,0x5e,0xa0,0x98,0x71,0x42,0x2f,0x30,0x71,0xd6,0x31,0x94,0xe0,0x61,0xed,0x50,0x66,0xfa,0xba,0x12,0x5e,0xc6,0xc8,0x67,0xe5,0x8e,0xfd,0x34,0xa9,0xeb,0xde,0x25,0x43,0xbf,0xe7,0xb5 +.byte 0x16,0xf5,0x62,0x66,0x5d,0x0b,0x13,0x9a,0xd4,0x8c,0x2b,0x8f,0xe6,0x91,0x33,0xcb,0xa0,0x70,0x48,0x3e,0x22,0x7d,0xe4,0xf3,0x75,0xc9,0x49,0x82,0x50,0xc9,0x90,0x04,0x32,0xab,0x99,0x6e,0xf1,0xf0,0x0b,0x60,0x80,0x35,0x25,0x45,0x88,0xe9,0x82,0x06,0xe1,0xbb,0x85,0x11,0x40,0xf8,0x0e,0xbd,0x19,0x7a,0xdd,0x78,0xf9,0xc2,0x46,0xe4 +.byte 0xb5,0x27,0xfb,0xb6,0xba,0xbc,0x7d,0xb8,0x27,0xe7,0xbf,0xfe,0x8e,0xfe,0x7e,0x83,0x63,0x43,0x92,0x26,0xf0,0xbb,0xde,0xb6,0x93,0x4f,0x55,0x0c,0x07,0x99,0x3c,0x98,0xa1,0x8c,0x73,0xc1,0x4c,0x9a,0x09,0xa8,0xea,0x16,0x0b,0x49,0x2a,0x43,0xee,0x90,0x61,0x6f,0x09,0x1b,0xc3,0x2d,0x62,0x4b,0xfc,0x90,0xa1,0x8e,0x84,0x2e,0x90,0x8d +.byte 0x5f,0x80,0xff,0x6a,0x3c,0x61,0x0f,0xf2,0xac,0x70,0x20,0xc1,0xf2,0x85,0xcf,0x94,0xc8,0x94,0xe7,0xa0,0x04,0xdf,0xaf,0xef,0x26,0xd2,0xbc,0x07,0x70,0xc1,0x48,0xd6,0x87,0xd6,0xbe,0xea,0x95,0x6a,0xce,0xa2,0x48,0xac,0x46,0x46,0xb1,0x74,0x70,0x96,0x6c,0x26,0x58,0x75,0x9d,0x84,0xd7,0xd9,0x17,0x9a,0x46,0xe9,0xd7,0x3d,0xde,0xfd +.byte 0x7e,0xf4,0xd8,0x7e,0xf8,0x8f,0x1c,0xb5,0xfb,0xe9,0xc4,0xca,0xba,0x52,0x5f,0x17,0xee,0x75,0x7d,0x1d,0x50,0x16,0x9f,0x16,0x1e,0x00,0x8b,0xc1,0x2f,0xab,0x73,0x65,0x88,0x7b,0x80,0xa6,0x71,0xb7,0xfb,0xb0,0xda,0xd1,0x96,0x18,0x5c,0x48,0x6e,0x18,0x45,0x59,0x45,0xef,0x5c,0x65,0x35,0x99,0x5e,0xb9,0xd4,0x1a,0x07,0x7d,0x1e,0xa6 +.byte 0x69,0x42,0x9d,0xfa,0xec,0x02,0xdc,0xc4,0x19,0x6b,0x9c,0xb1,0x5e,0xa3,0xb4,0x6d,0xb4,0xa6,0x25,0xa8,0xe4,0x3f,0x3d,0x6e,0x2c,0x95,0xf7,0xcd,0xa5,0x4e,0x32,0xca,0x7e,0xe0,0x7b,0x11,0xf9,0x0a,0xe1,0x61,0x41,0x60,0xec,0xb3,0xb1,0x92,0x89,0x33,0x17,0xe9,0xaf,0x70,0x7f,0x1c,0x07,0xb5,0x24,0x3a,0x37,0x84,0x38,0xf5,0xb6,0x11 +.byte 0xfc,0x0c,0x12,0xc1,0xfc,0xa9,0x82,0x67,0x4d,0x17,0xe8,0xea,0xd0,0x62,0x17,0xb2,0x9c,0x59,0x01,0x87,0xfb,0x54,0x8e,0xa7,0xa5,0x85,0xa9,0x8a,0xec,0xfe,0x29,0xc0,0x73,0xc6,0xa0,0xbf,0x66,0x9a,0xc5,0xf8,0xee,0xa4,0xcb,0x09,0x44,0x74,0xfe,0x32,0xf5,0x42,0xea,0xf0,0xa6,0xec,0x74,0xea,0x14,0x5c,0x43,0x51,0xfa,0x3a,0x48,0x1e +.byte 0xa0,0x2e,0x59,0x2e,0xdb,0x3a,0x19,0xfe,0x1f,0x95,0x25,0xee,0x27,0x2b,0x99,0xb4,0xe1,0xd0,0xe6,0x33,0x91,0xa1,0xaf,0x30,0xa0,0x89,0x00,0x3c,0x13,0x31,0x18,0x70,0x90,0x42,0x55,0x0a,0xc9,0xc5,0x0c,0x43,0xa5,0xee,0xd6,0x90,0x07,0xae,0xc4,0x8c,0xdc,0xe4,0x07,0xbb,0x61,0x70,0xd1,0x10,0xe4,0x68,0x96,0x70,0x78,0xab,0xe9,0x3a +.byte 0x6e,0xc7,0x75,0x93,0xa0,0xba,0xff,0x6a,0x2d,0x57,0xaa,0x93,0x09,0xc3,0x6b,0x81,0xf3,0xde,0xc2,0xee,0xac,0x86,0x0a,0xfb,0xad,0xdb,0x6f,0x2a,0xa0,0x15,0x7b,0x96,0x77,0x38,0xf8,0x86,0x51,0x33,0x7a,0x6f,0x1c,0xf8,0xd5,0x15,0xcd,0x76,0x7f,0x37,0x68,0x82,0xdf,0xab,0xc3,0xdb,0xbe,0xeb,0x2b,0xa8,0x34,0x72,0x20,0x34,0xfb,0x12 +.byte 0x64,0x17,0x05,0x64,0xc0,0xa1,0xca,0xd3,0xac,0x27,0xc2,0x68,0x28,0x40,0x42,0xe2,0x0a,0xdd,0xd7,0xd6,0xf6,0x92,0x95,0x3c,0x10,0x17,0x4e,0xef,0x75,0xae,0x98,0x2d,0x10,0xc8,0xa8,0xac,0x15,0xf7,0x5b,0x81,0xc1,0xdf,0x5e,0xbe,0x88,0x49,0xe3,0xd1,0x88,0x1c,0xcb,0xce,0x20,0x01,0x12,0x60,0x57,0x0b,0xf6,0x32,0x57,0xaf,0x59,0xef +.byte 0xc9,0xe7,0xbf,0x62,0xf3,0xb6,0xe6,0x5c,0xee,0x36,0x7e,0x11,0x90,0xd1,0xeb,0xfa,0x62,0x0b,0xc6,0xf3,0x1a,0xd5,0x8b,0x95,0xec,0xb4,0x38,0xfe,0x45,0xb0,0xb5,0xff,0x84,0x0a,0x27,0x3a,0xa2,0x5a,0x2a,0xc9,0xa4,0xc0,0x11,0xc6,0x61,0x13,0xb7,0x53,0xa3,0x47,0x45,0x6d,0xc6,0xa9,0x00,0xd1,0x40,0xf4,0x77,0xac,0xb3,0xd3,0x26,0x99 +.byte 0xf1,0x36,0x59,0x28,0xb4,0xd0,0xdd,0x0e,0xed,0x53,0x33,0x45,0x71,0x9c,0x5c,0x11,0x27,0x2c,0x2f,0x10,0x9e,0x5b,0x8a,0x5b,0xc5,0x1f,0x36,0xc9,0x2a,0xba,0xc7,0xa5,0x31,0xd7,0x9f,0x2b,0x0a,0x09,0xcb,0x7c,0x4f,0xa2,0xdc,0xc5,0x64,0x0d,0xe6,0xfe,0xb0,0x9d,0x3b,0xf0,0xa7,0x19,0x8c,0x84,0x21,0x6b,0x9e,0x1c,0xb5,0x7b,0x66,0x77 +.byte 0xd0,0x85,0xb4,0x22,0x93,0x6e,0x84,0x29,0x9b,0x60,0x90,0x37,0x9d,0x8c,0x94,0x95,0x95,0x3b,0xf1,0x2d,0x56,0x5b,0x53,0x60,0x2d,0xe5,0x7f,0x80,0x71,0x56,0xa7,0x6e,0x66,0x76,0x1f,0xaa,0x0d,0xba,0xfb,0x0e,0xcf,0x20,0x68,0x74,0x2b,0x99,0x13,0xe1,0xa8,0x33,0xc9,0xf6,0xbc,0xd3,0xf4,0x46,0x01,0x02,0x85,0x27,0xf4,0x20,0x97,0xa3 +.byte 0xba,0xbc,0x47,0x30,0x48,0xed,0x60,0xe6,0xca,0xbf,0x76,0x8c,0x2c,0x6a,0x43,0x32,0xfd,0x90,0x04,0x95,0xc2,0x42,0xcb,0xca,0xc4,0x33,0xe1,0xd3,0x23,0x92,0xa1,0xde,0x09,0x38,0xce,0x00,0x93,0xb3,0xed,0x82,0x8e,0xfb,0xce,0x4c,0x9a,0x10,0x6e,0xce,0x4a,0x37,0x05,0x75,0x37,0x58,0xc3,0x8e,0x57,0x50,0xa0,0x7d,0x80,0x2d,0x51,0xea +.byte 0x08,0xcd,0x1b,0xd2,0x81,0x85,0x19,0xc1,0xe8,0xce,0x31,0x18,0xcf,0x54,0x37,0x96,0x77,0x3d,0x64,0xfb,0xc2,0xa9,0xdb,0xb8,0x37,0x03,0x83,0x34,0x3c,0x25,0x6a,0x22,0x33,0xfa,0x27,0x70,0xc7,0x0a,0x27,0x12,0x1e,0xb3,0xd0,0x59,0x6f,0xa3,0xc5,0x73,0x95,0x4c,0x1f,0xf1,0x3c,0xb3,0xc2,0xa2,0xc6,0x45,0x17,0x53,0xa8,0xfc,0x00,0xff +.byte 0x77,0x40,0x28,0xd2,0x53,0x90,0x92,0xe9,0x86,0x6c,0xa5,0x40,0xce,0xbc,0x79,0x6f,0x8f,0x12,0xef,0x1b,0x38,0x1f,0xb3,0x24,0xf0,0x75,0x17,0x20,0x9e,0x03,0x9c,0x2b,0x51,0x57,0x93,0x44,0xce,0x74,0xc9,0x12,0xe7,0xcb,0x2f,0x5e,0x1b,0x95,0xf2,0x4d,0x2e,0x51,0x8d,0x52,0xd5,0x21,0xe3,0x1b,0x33,0xe7,0xf2,0x18,0x61,0xa2,0x53,0xdb +.byte 0x73,0xaa,0x6a,0x6c,0xf9,0xf4,0xef,0x3d,0x40,0xa3,0x00,0x80,0x82,0xed,0xe6,0x66,0xd1,0xd6,0xe9,0x93,0xd8,0x92,0xfa,0xdf,0xf9,0x9c,0x7a,0xfb,0x2b,0xc7,0xa7,0x73,0x67,0x2b,0xed,0x76,0xb1,0x52,0xaa,0xcf,0x34,0x84,0xa1,0x6d,0x56,0x85,0xef,0xcb,0xbc,0xa3,0xc6,0xf3,0x5a,0x88,0x04,0xd5,0xd8,0xf1,0x7b,0xf8,0x11,0x6f,0xa0,0x44 +.byte 0xa5,0x0f,0x76,0xed,0xd7,0x98,0xe3,0xda,0xb8,0x1b,0xc7,0xe6,0x89,0x08,0x19,0x1f,0xf8,0xe3,0x32,0x32,0xa5,0x3c,0x71,0x9f,0x11,0xde,0x50,0x29,0xb0,0x54,0x7e,0x3b,0x5e,0xeb,0xf7,0xab,0xa8,0xa0,0x35,0x96,0xc7,0xc5,0xea,0x60,0xc0,0x37,0xca,0x61,0x55,0x96,0xac,0xb4,0xd0,0x29,0x9a,0x1a,0x3f,0x9e,0xf5,0xf5,0x3d,0xed,0xc5,0x7c +.byte 0x2c,0x9d,0x67,0xf8,0x4d,0x82,0x6e,0x2a,0x9a,0xfc,0x5f,0xdc,0x02,0xb0,0x3d,0xa5,0x1c,0x08,0x5d,0x4a,0xaa,0xd0,0x38,0xfb,0xbc,0xbb,0x7f,0x37,0xfb,0xec,0xc0,0x62,0x79,0xaa,0xde,0xfd,0x23,0x9c,0x4c,0x4a,0xe1,0x48,0x40,0x36,0xc0,0x0a,0x6f,0x43,0xb7,0xad,0x4c,0xf6,0x56,0xb5,0x44,0xf4,0x72,0xcd,0x13,0x10,0xea,0x0d,0x24,0xc1 +.byte 0xa9,0x36,0x3b,0x36,0xf2,0x6e,0xf9,0x0a,0x67,0xcd,0x02,0x67,0xb3,0x5c,0x63,0x3a,0x7c,0xc1,0x3b,0xf2,0x1d,0x3d,0xf1,0xff,0xbf,0xf7,0x97,0x9f,0x30,0x1f,0xaa,0xd8,0xdb,0x53,0x9b,0x0a,0xbd,0x38,0xd8,0xb6,0xf1,0x4a,0x78,0x1a,0xc2,0x46,0xd2,0x0c,0xa8,0xcd,0x7b,0x39,0xc7,0x42,0x55,0xc8,0x3e,0x02,0x1d,0xf4,0xad,0x55,0x01,0x6a +.byte 0x11,0x2d,0xfa,0x67,0x48,0xae,0x45,0x31,0x9b,0x09,0x7d,0xd9,0xdd,0xaf,0x5c,0xd5,0x40,0x51,0x2a,0xa1,0x0f,0xb3,0x6e,0xc2,0x94,0xfe,0xde,0x70,0xaf,0x6c,0xea,0x5f,0x7d,0x3c,0x72,0x85,0x86,0x24,0x20,0x0a,0x7a,0xe7,0x69,0x32,0x66,0x7d,0x34,0x13,0x60,0x62,0xc7,0x68,0x32,0xde,0x34,0x30,0x36,0xc8,0x8e,0xb7,0x13,0x66,0xf1,0xce +.byte 0x5f,0x7a,0x3a,0xfe,0x62,0xd6,0x72,0xb6,0x1b,0x80,0x43,0x8a,0x3e,0x13,0x15,0xe4,0x1c,0x7b,0x08,0x70,0x0b,0x6e,0xb3,0xfe,0x07,0x91,0x23,0x21,0x57,0x48,0xc6,0xa9,0xa3,0xa8,0xc7,0x19,0x89,0x8a,0x49,0x12,0x25,0x88,0xd2,0x11,0xa5,0xa8,0x9e,0x0e,0xa7,0x71,0xfe,0xaf,0x88,0xee,0xa7,0x1c,0x3b,0x27,0x27,0x7e,0x79,0x92,0xed,0x77 +.byte 0x74,0x65,0xbd,0x46,0x41,0x25,0xd9,0x8b,0x21,0x73,0x9f,0xaa,0x35,0xa0,0x22,0xb3,0xc8,0x71,0x28,0x72,0xd2,0xcb,0xf4,0x2a,0x06,0x0a,0x63,0x96,0x55,0x2e,0x83,0x0b,0xe8,0x07,0x99,0x9d,0x59,0xde,0xde,0x62,0xbd,0xb4,0x3e,0x70,0x15,0xed,0x95,0xa8,0x2f,0xb7,0xa2,0xb6,0x65,0x56,0x9d,0xe5,0x81,0xa0,0x05,0x5b,0xce,0x00,0xd4,0xb9 +.byte 0x28,0x5a,0xc1,0x9a,0x74,0xc6,0xd7,0x27,0xdd,0x7c,0xbe,0xe8,0x0d,0x47,0xfc,0x81,0x05,0x6b,0x4f,0x68,0xc7,0xcc,0x5d,0xd5,0x66,0x83,0x34,0x72,0x35,0xab,0x39,0x64,0x19,0x67,0xbd,0xff,0x15,0x44,0x20,0x18,0x2a,0xaf,0xbc,0x58,0x94,0xdb,0x18,0x50,0x55,0x11,0x6a,0xc4,0x1d,0xee,0xe2,0xe0,0x75,0x73,0xf1,0xa1,0x83,0xf4,0xcb,0x40 +.byte 0x96,0xf4,0x77,0x45,0x61,0x8b,0x1a,0x8c,0x0c,0xfc,0xd2,0x7e,0x0b,0x1e,0x18,0xd2,0x95,0xa5,0x4c,0x5b,0xd6,0x9d,0x40,0x8b,0xc0,0x51,0xe8,0x2d,0xe5,0x16,0xbf,0xd7,0x98,0x8a,0xa0,0x46,0x1f,0xc4,0xe9,0x12,0x31,0x40,0xc5,0x2d,0x59,0xf8,0x9b,0x5f,0xe3,0x3a,0x10,0xdf,0xda,0x72,0x9e,0xab,0x13,0x7b,0x8f,0xc8,0x52,0x9f,0x58,0x45 +.byte 0x7a,0xe6,0x3a,0xbb,0xdd,0x1d,0xc7,0x3b,0xc4,0x26,0xdc,0x99,0x29,0xf2,0x74,0x16,0x84,0xe9,0x8a,0x86,0xc0,0x1e,0x49,0x96,0x2f,0x5c,0x2a,0x49,0x71,0x88,0xe6,0x82,0xb2,0x18,0x88,0xc1,0x86,0xcb,0x26,0x3c,0xa5,0x50,0x31,0x22,0x9a,0x8f,0x45,0x2b,0xde,0xf0,0x86,0x8e,0x13,0x86,0xc4,0x4a,0x9b,0x35,0x27,0x93,0x0b,0x13,0xc8,0xef +.byte 0x96,0x74,0x97,0x85,0x09,0xc0,0xa0,0x32,0xfe,0xc3,0xe3,0x92,0x2e,0xe8,0x54,0xbd,0xc2,0x23,0xeb,0x4b,0x02,0xf5,0x5a,0x0b,0x0d,0x58,0x50,0x45,0xe7,0x01,0xd4,0x17,0x00,0xdb,0x0d,0xd4,0x2e,0xa0,0xde,0x38,0xf4,0xb1,0x1e,0xd0,0xf0,0xa3,0x6b,0x21,0x0c,0xbd,0xae,0x84,0x7e,0x42,0x36,0x4f,0x2e,0x46,0xae,0x23,0x91,0xb9,0x06,0xac +.byte 0x86,0x7f,0x29,0xca,0xfb,0xe9,0xde,0xdb,0x90,0xfe,0x6f,0xbc,0xdb,0x3c,0x48,0x3d,0x6e,0x06,0x68,0x49,0xbb,0x43,0x8d,0x9d,0xc4,0x5f,0x45,0xcb,0x77,0x28,0xe0,0x35,0xd1,0xb4,0x25,0xb2,0x45,0x6d,0xb4,0x89,0x53,0x26,0x33,0x98,0x83,0x45,0x9d,0xf5,0xad,0xf9,0xa7,0x59,0xb6,0x6e,0xa8,0x25,0xa5,0xef,0xee,0xf6,0x6a,0xd5,0x6c,0x60 +.byte 0x9a,0xea,0x78,0x9e,0xe4,0xa2,0x29,0x0b,0x70,0xb3,0x6e,0x3a,0xfd,0x07,0xc7,0x7f,0x1b,0x07,0xc7,0xca,0x1b,0xb8,0x08,0xe1,0xc9,0x94,0xb2,0x62,0x7c,0x04,0x96,0xa6,0xda,0x65,0x28,0xfd,0xf9,0x70,0x22,0xb7,0x21,0xd3,0xa6,0x38,0x0f,0x1e,0x88,0x7e,0x73,0xec,0x04,0x99,0x8b,0x23,0x91,0x13,0xe6,0x4f,0x74,0x81,0xcc,0x1f,0xdd,0xaf +.byte 0x58,0xc4,0x80,0x00,0x4d,0x1d,0xbe,0x84,0x7d,0xfe,0x85,0xe7,0x77,0x20,0x3c,0x65,0x4e,0x0e,0x2e,0x5d,0xc1,0xd9,0xcb,0xf7,0xbb,0xc8,0x8d,0xbf,0x16,0xa8,0x1e,0x63,0xf5,0x10,0x5e,0xa5,0x9c,0x63,0xb6,0x9a,0xeb,0x98,0xa8,0xb1,0x59,0x82,0x66,0x51,0xae,0x3c,0xfc,0xa8,0x11,0x92,0xf4,0x45,0x88,0x7c,0x03,0x6f,0xe6,0x87,0xe4,0xa8 +.byte 0x79,0xbf,0xb3,0x0d,0xd6,0x0b,0x8d,0xa3,0x16,0x2a,0xfb,0x79,0xb9,0xe7,0xdb,0xa7,0xdb,0x94,0xd3,0xe6,0x3a,0xdd,0xe9,0x5f,0x30,0x7d,0x68,0x90,0x35,0xfd,0x18,0x91,0x8e,0xc5,0x12,0xd6,0xf9,0x98,0xa0,0x5b,0xcd,0x81,0x76,0x84,0x08,0xd0,0xab,0x59,0x2d,0x3b,0x8a,0xf9,0xd9,0x95,0xde,0x8b,0xbb,0x92,0xef,0x35,0xc3,0x3e,0x46,0x73 +.byte 0xf3,0x3b,0x09,0xbf,0x22,0x2b,0x9c,0x0f,0x70,0x9a,0x16,0x0e,0x4b,0xa7,0x1a,0x96,0x98,0xb7,0x5a,0x40,0x06,0x81,0xf4,0xac,0xa6,0xe6,0xab,0xf2,0xda,0x87,0x18,0x61,0xcb,0xc1,0x67,0xbd,0x2f,0x6f,0x06,0x21,0xaf,0x73,0x98,0xe1,0x3f,0x7a,0x17,0x7f,0x44,0xcb,0x1d,0xdd,0x60,0xb3,0x2c,0x58,0x20,0x8a,0x04,0x74,0x56,0x9b,0x26,0x51 +.byte 0x61,0xb0,0x07,0x50,0x53,0x83,0x31,0x42,0x59,0xb3,0x33,0xfa,0xfe,0xbc,0xad,0x7f,0x99,0x9b,0x86,0xf1,0xaa,0x85,0xf1,0xbb,0xc0,0x0c,0x91,0x8d,0x1a,0x0f,0x8f,0x9f,0xfe,0x62,0x2b,0x35,0xae,0xcc,0x8c,0x09,0xe3,0x29,0x96,0xd1,0xbe,0x7f,0x25,0xd6,0x03,0xf0,0x4c,0x53,0xad,0x5b,0x56,0x66,0x68,0x9a,0xa3,0xc4,0x07,0x71,0xde,0x49 +.byte 0x82,0xbb,0xf7,0x9a,0x2b,0x96,0xcf,0x50,0xf6,0x00,0xf7,0x0b,0x27,0xdd,0xf5,0xf6,0xc5,0xc8,0xbd,0x2a,0xa2,0x06,0x2c,0x42,0x3f,0xa0,0xf8,0xcc,0x1d,0x64,0xcf,0xbc,0xb4,0xc4,0x63,0xde,0x6b,0xd3,0xb4,0x61,0xdf,0xbd,0x73,0x50,0x34,0xc3,0x20,0x45,0x06,0x73,0x9b,0xf0,0xfb,0xa6,0x2b,0xec,0x92,0x32,0xa9,0x1f,0x4f,0x1e,0x38,0x78 +.byte 0x2a,0xd2,0x7c,0x1d,0x89,0xf9,0x70,0xbc,0xef,0x09,0x77,0xd3,0x6a,0x56,0xa1,0x8b,0x4b,0x23,0x1b,0xb1,0x2f,0xec,0x84,0xe5,0x59,0xc5,0x20,0x23,0xbc,0x3f,0x0a,0x43,0x97,0x1c,0x5e,0xf7,0xee,0xfe,0x0b,0x2a,0x42,0x08,0x2a,0x39,0x91,0xce,0x8a,0x33,0x9f,0x63,0x77,0x6d,0xf6,0xf3,0x0e,0x1d,0xb3,0xfb,0xcf,0x2f,0x7f,0x95,0xc2,0x71 +.byte 0x1c,0xa0,0x0b,0xc6,0xb8,0xde,0x4d,0xd8,0xcc,0x4c,0x4f,0xaf,0x07,0x87,0x6d,0x3b,0xab,0x95,0xab,0xa1,0x6a,0x50,0x9f,0x7c,0x35,0xb6,0x65,0xdd,0xe3,0x06,0xe5,0xb3,0x42,0x5f,0x4d,0xe5,0x3e,0xfa,0x6c,0xdf,0x19,0x58,0xd1,0xf6,0xc6,0x94,0x1c,0xce,0x30,0x90,0xd3,0xeb,0xa3,0x7c,0xe5,0x3f,0x57,0x99,0x2e,0x22,0x0a,0x94,0x2f,0xfe +.byte 0x39,0x16,0xe6,0xfa,0xd0,0xb5,0xf9,0xb4,0x88,0x61,0xa4,0xa8,0xc3,0xb8,0xb7,0x52,0xaf,0x90,0xc1,0xe0,0x19,0x78,0x04,0x2b,0x71,0x04,0x03,0x2f,0x63,0xbe,0x40,0xf5,0x82,0x3b,0x1b,0x6b,0xde,0x6d,0x1e,0x86,0x87,0x82,0xc3,0x31,0x97,0x20,0xdd,0xdd,0xce,0x61,0x64,0x99,0xf6,0xbe,0xbf,0xec,0x37,0x54,0x8b,0x92,0x29,0xda,0xc5,0x7b +.byte 0x4d,0xc5,0xaf,0xb8,0x4e,0x4b,0x4a,0x2b,0x35,0x30,0xf5,0x19,0x9e,0x32,0xd8,0x2e,0xc1,0x19,0xfe,0xd1,0x61,0xb0,0xaa,0x05,0x58,0x15,0xd9,0x0e,0x4e,0xca,0x4e,0x10,0x83,0xe6,0xe6,0x57,0xe8,0x8d,0x13,0xb4,0x6f,0x85,0x59,0xf2,0x83,0xc8,0x37,0xaa,0xa2,0xe5,0xc8,0x77,0x06,0x82,0x21,0x5d,0x84,0x58,0x67,0x9b,0xcc,0x9c,0xfc,0x1b +.byte 0x28,0x2f,0xac,0xc8,0x96,0x91,0x26,0x46,0x42,0x2b,0x68,0x57,0xb0,0x79,0x1e,0xb1,0x9b,0x92,0x2c,0xeb,0x67,0x00,0xd4,0x26,0x7d,0xca,0x45,0x97,0x55,0xea,0x2a,0x20,0x70,0x7c,0x20,0x14,0x38,0x40,0x3d,0x4f,0xf5,0x3a,0x1f,0x0a,0xe3,0x9a,0x48,0xcc,0xb2,0x7d,0xee,0x5b,0x48,0x90,0x0d,0x12,0x77,0xd8,0xd3,0xb6,0xd7,0x66,0x9e,0x48 +.byte 0xbb,0x92,0xc1,0x7c,0x4e,0x90,0x4d,0xd5,0x96,0x99,0xea,0x86,0x2d,0xb9,0x5a,0x50,0x05,0xc2,0x6b,0xa7,0x0c,0x43,0x44,0x22,0x09,0xb9,0xc0,0x56,0x47,0x5f,0xdf,0xaf,0x6b,0x91,0xe2,0xd7,0x45,0x77,0x17,0x7a,0x71,0x6d,0x27,0x93,0xe2,0xc6,0x10,0x2f,0xc8,0x3b,0x75,0x78,0x11,0xae,0x07,0xe6,0xba,0x64,0xd4,0x06,0xfa,0xf9,0x1d,0x74 +.byte 0x9e,0x4f,0x6d,0x02,0xfc,0x40,0x80,0x9a,0x2e,0xd4,0x15,0x32,0x15,0xe8,0x97,0x0a,0xd4,0x65,0x6a,0x87,0xd3,0x66,0x4b,0xb8,0x66,0x84,0x8e,0xb9,0x4b,0xa7,0xcf,0x58,0x13,0x66,0x3a,0x4e,0xa5,0x76,0x17,0x13,0x92,0x79,0x42,0x67,0x6d,0xb6,0x65,0xec,0xc8,0xb5,0x5f,0x17,0x2a,0x2d,0x4b,0x19,0xe9,0x00,0x6e,0x38,0xaf,0xe9,0x06,0xb6 +.byte 0xe8,0x99,0x69,0x8a,0x74,0xe7,0x7e,0x70,0x69,0x4b,0xbc,0xce,0x5d,0x61,0x94,0x1b,0x47,0x41,0x38,0x5f,0x2e,0xcf,0x2b,0xe1,0xcd,0xa3,0x98,0x71,0xf7,0x09,0x65,0xfe,0x5f,0x62,0x4b,0x9e,0x91,0x88,0x35,0xa2,0x66,0x02,0x1d,0xc9,0x93,0x0c,0x19,0x50,0x4b,0x95,0x71,0x79,0xdd,0x74,0xe1,0xda,0x5a,0xb7,0x38,0x70,0x61,0x18,0x3f,0x68 +.byte 0x08,0x34,0xd8,0xfe,0xbb,0xd1,0xbf,0x57,0xed,0xc2,0x52,0x6d,0x54,0x3e,0xcb,0x0c,0x32,0xc7,0x09,0xa9,0x31,0x10,0xe8,0xbd,0x70,0xe3,0x0e,0xe9,0x4f,0x7a,0xd6,0x42,0x45,0x2e,0x1b,0x3c,0x0d,0x15,0x6d,0xb4,0xad,0xe9,0xc5,0xa2,0x12,0x77,0x34,0x43,0x20,0x95,0xc1,0xb7,0x51,0x72,0xed,0x78,0xa0,0xae,0x3c,0xae,0xb4,0xd4,0xda,0x58 +.byte 0x83,0x62,0xa9,0xc6,0x01,0x3d,0x14,0x19,0x07,0x00,0x3c,0x82,0x16,0x7e,0x8a,0x91,0x78,0xa1,0x65,0x0b,0x5b,0x3a,0x40,0x72,0xe5,0xf0,0xd4,0x82,0x04,0xe4,0x01,0xf1,0x84,0x87,0x96,0x26,0x91,0x66,0x77,0xf7,0x59,0xd6,0xc2,0xca,0x29,0x3b,0x68,0x2a,0x27,0x99,0x64,0x86,0xc2,0x96,0xbf,0x11,0x3c,0xa8,0x0c,0xf7,0x86,0xb8,0xc1,0x40 +.byte 0x15,0x1a,0x84,0xe3,0x93,0x23,0x73,0xa9,0x8b,0xbd,0xb4,0x8a,0xe4,0xf1,0xa5,0x8f,0x56,0xa3,0xdc,0x77,0xbd,0x7d,0x15,0x74,0x2b,0x18,0x92,0x56,0x45,0xbc,0xaf,0xf2,0x55,0xce,0x9d,0xc2,0xab,0x39,0x90,0xec,0x78,0x3f,0xa5,0x14,0xeb,0x40,0x2f,0x01,0xca,0xeb,0xad,0x73,0x85,0xbc,0xe1,0x91,0xaa,0x77,0xa9,0x6c,0x02,0x66,0x6a,0x65 +.byte 0x63,0x6c,0x50,0x62,0x83,0x83,0xef,0x16,0x4f,0x21,0xfd,0x28,0x8e,0x52,0x66,0x5b,0x6f,0x8f,0xbe,0x8d,0x17,0xb9,0xd5,0x99,0xf7,0x39,0xd1,0xbc,0xa2,0x43,0xd7,0x0a,0x80,0xea,0x42,0xf8,0x38,0x53,0x95,0x07,0x6f,0xb7,0x7c,0xc1,0x16,0x88,0xc8,0xb7,0x59,0xde,0x76,0x51,0x2f,0x92,0xd0,0x40,0xfd,0xd9,0x2d,0xca,0x9e,0x8d,0x28,0xae +.byte 0x48,0xc1,0x0a,0xe0,0x76,0x9c,0x02,0x0b,0xc5,0xd1,0xf9,0x83,0x90,0x86,0xa4,0xeb,0x5c,0x64,0x65,0xf8,0x98,0x38,0xc5,0xce,0xef,0x6f,0xc3,0x88,0xb6,0x2f,0x8a,0x40,0x55,0x52,0x47,0x06,0x75,0x16,0x46,0x9c,0xff,0x3c,0x68,0x97,0xc3,0xfb,0x10,0x11,0x7b,0xba,0x04,0xcc,0xad,0xba,0xcf,0xf0,0xae,0xba,0xe6,0x59,0x9c,0xf5,0x27,0xeb +.byte 0xdd,0x5c,0x86,0x25,0xa1,0xb6,0xb8,0x1c,0x94,0x98,0xa5,0x79,0x82,0x4e,0xdf,0x09,0x3f,0x2f,0x8a,0x4e,0x1b,0x5a,0xab,0xd4,0xe6,0x21,0xb3,0x02,0x19,0x39,0xa9,0x2e,0x0e,0xae,0x86,0x30,0xc7,0xa0,0x00,0xed,0x72,0xdc,0x71,0x77,0x42,0x76,0x54,0x68,0xb2,0x8d,0x5d,0xc3,0x5c,0x86,0xf8,0xb1,0x6c,0x67,0xdf,0x24,0x40,0x6a,0x2b,0x1d +.byte 0xbc,0x0d,0x25,0x7d,0x9e,0x1c,0xbd,0x18,0x85,0xda,0x7a,0x86,0x5e,0xed,0x10,0x80,0x83,0xa6,0xef,0x1e,0x93,0xac,0xce,0xe6,0x32,0x35,0xdf,0xb8,0xc7,0x9b,0xf0,0x0f,0x9d,0x37,0xbd,0xd9,0x58,0x33,0x19,0xa1,0x23,0x51,0x5f,0xa7,0x5a,0x99,0x7e,0x2a,0xfd,0x85,0x3c,0x26,0xad,0xcc,0x7e,0x07,0x32,0x7b,0x24,0x5a,0x6b,0x4b,0x71,0x4e +.byte 0xca,0x8b,0xc4,0x03,0x26,0x76,0x02,0x68,0x0d,0xa1,0x09,0xe0,0x2e,0xa4,0x82,0x88,0x05,0x5a,0xc4,0xcb,0x31,0x9d,0x56,0xda,0x0d,0x00,0x04,0xbc,0x07,0xca,0x1f,0xdf,0x9e,0x44,0xed,0x36,0xbd,0xa0,0x22,0xff,0x78,0xd1,0xcb,0x62,0xe0,0x0d,0x2e,0xdc,0x2e,0x36,0x28,0x8e,0xd3,0xa9,0xe0,0x38,0xd4,0xc5,0x2b,0xee,0xaf,0xa4,0x08,0x7d +.byte 0xed,0x2c,0x8a,0xf5,0x86,0x5e,0xed,0x2a,0x0d,0xbf,0xe6,0xfb,0x6f,0xc4,0x02,0x75,0x36,0xe5,0x7b,0xe9,0x4a,0xb3,0xf1,0xf4,0x86,0x6c,0x9a,0x6e,0xaa,0x7a,0xbe,0x4b,0xd6,0xf2,0x6b,0xcb,0x78,0x6f,0xf9,0x42,0x1a,0x19,0x7b,0x7e,0xba,0x59,0x02,0x8b,0xe3,0x5c,0x44,0xa4,0x84,0xa8,0x4a,0x67,0x93,0xee,0xc4,0x17,0x07,0x26,0xfe,0x86 +.byte 0xf1,0xc6,0xba,0xbf,0xc4,0x3d,0x33,0x41,0x4d,0xc4,0xf0,0xa8,0x6d,0xe1,0x06,0x16,0x2d,0xc9,0x5d,0x2a,0xf5,0x4a,0xc6,0xd2,0x8c,0x98,0x55,0xe8,0x8d,0xd0,0x31,0x5f,0xc7,0x05,0xd1,0xca,0xd2,0x72,0xe6,0xd0,0xcb,0x62,0x79,0xac,0x60,0x59,0x94,0x59,0x48,0x9e,0x91,0x17,0xa7,0xa0,0xac,0x4a,0xe5,0x08,0xe5,0x52,0xa4,0xd4,0x83,0x8c +.byte 0x83,0x57,0xe7,0xe5,0xfc,0x9b,0x43,0x78,0xc8,0x7e,0x94,0xc4,0x35,0x3e,0xac,0x4a,0x8d,0x60,0x80,0xdc,0x72,0xe3,0x15,0x09,0x2a,0xbd,0xcc,0x9a,0xe4,0x1a,0x18,0xa8,0xf1,0x29,0x9b,0xca,0x58,0x0b,0x6d,0x7b,0x33,0x91,0x05,0x27,0x6a,0x48,0xbe,0xac,0x08,0xa5,0x2a,0x64,0xf5,0xae,0x2a,0x90,0xf1,0x2d,0x3f,0xa8,0xff,0x17,0x92,0xc4 +.byte 0xec,0x3a,0x09,0xbf,0xae,0xd3,0xe2,0x1c,0x3c,0xc8,0x6f,0x91,0x72,0x99,0xe3,0x82,0x30,0x4f,0x40,0x5c,0x0c,0x8d,0xfd,0xbe,0x10,0xbc,0xce,0x1e,0x0a,0x09,0xbf,0xde,0xdc,0x72,0x7e,0x4c,0xbc,0xec,0x34,0xe2,0x96,0x8a,0xc6,0xee,0x19,0x6c,0xa8,0xf1,0xa5,0xb2,0x71,0x88,0x13,0xe8,0x11,0xda,0x3b,0x77,0x10,0x9c,0x9f,0x74,0x49,0x21 +.byte 0x16,0xcf,0x6f,0x05,0xc5,0xc1,0x4d,0xfe,0xe7,0x4d,0x67,0xe8,0x12,0x14,0xf7,0xaf,0x66,0x8d,0x55,0x34,0x00,0x18,0x10,0x6e,0x6a,0xd2,0x4c,0xd9,0xd3,0x15,0x40,0xbf,0xce,0x7b,0x10,0x69,0xbd,0x15,0x0e,0x60,0x2b,0x76,0x50,0x80,0x92,0x02,0x3c,0x0f,0xea,0x47,0x03,0xd9,0xf6,0x2c,0x00,0xde,0x29,0xb9,0x2e,0xf6,0x80,0x10,0x81,0x28 +.byte 0x6f,0x41,0xfc,0x88,0x65,0xe9,0xb5,0xd4,0x78,0x53,0xff,0x04,0xc4,0xdd,0xd7,0x35,0x34,0x59,0x85,0x33,0x01,0x33,0x67,0xe1,0x4e,0xc2,0xac,0xe6,0x24,0x24,0xb6,0x83,0x48,0x08,0x0c,0x73,0xe5,0x9c,0x98,0xe4,0x4c,0x3c,0x1f,0x6e,0x77,0xea,0x8c,0x76,0x23,0xbb,0x41,0x5e,0xc1,0x8a,0xba,0x3e,0xe5,0x3e,0x86,0x89,0xab,0x32,0x65,0x1b +.byte 0x00,0x92,0x56,0xe0,0x62,0xc1,0x8f,0xeb,0x15,0x7f,0x86,0xdf,0xa2,0xc2,0x8d,0xf5,0xb5,0x88,0x72,0x8c,0xba,0x92,0x30,0x53,0x58,0x3e,0x0b,0xe6,0x4f,0xd4,0xef,0x34,0xab,0xbb,0x61,0xe0,0x31,0x3c,0xe7,0xb2,0x5f,0x64,0xcb,0x52,0xc7,0x1d,0x95,0x96,0xd2,0x8c,0x87,0x34,0x92,0xf2,0xad,0xd9,0x78,0x1d,0xa1,0x67,0x58,0xfa,0xfb,0x06 +.byte 0xc8,0x7f,0x9e,0xf7,0x02,0x12,0xd9,0x8c,0x68,0xbc,0x2b,0xd3,0xe1,0x0e,0x1e,0xbd,0x33,0x7a,0xfd,0x03,0x41,0xb9,0x72,0x2e,0x63,0xfe,0xb1,0x39,0xc3,0x0f,0xa0,0xa9,0x76,0x4f,0x7b,0xab,0xae,0xda,0x22,0xec,0x83,0x32,0xb0,0xec,0xd1,0xfd,0xc2,0x28,0x1e,0x42,0x29,0x31,0xd5,0xb3,0x33,0xcd,0x13,0x1d,0x9f,0xac,0x73,0x27,0xf7,0xea +.byte 0xc6,0x66,0xd2,0x32,0x91,0x60,0x35,0xf4,0x28,0x34,0x43,0x6a,0x74,0x8c,0x05,0x2a,0x84,0x34,0xfd,0x84,0xa5,0xcb,0x1d,0x2b,0x41,0x28,0xa6,0x19,0xed,0xcd,0xad,0xea,0x6e,0xf7,0x14,0x18,0xac,0x56,0x9a,0xf5,0xaa,0x7d,0x4e,0x8a,0x99,0xd1,0xda,0x41,0xaf,0xe8,0xfc,0xef,0x66,0x88,0xd0,0xed,0xfd,0xae,0x2a,0x85,0xc0,0x60,0xa2,0x30 +.byte 0x5d,0x1b,0x48,0xf6,0x3e,0xcf,0x56,0xdf,0x53,0xdc,0x2d,0xf5,0xfd,0x7f,0x2a,0x2a,0x4d,0x4f,0x11,0xcc,0xea,0x72,0xdb,0xb9,0xeb,0x92,0x0e,0x9f,0xc1,0x26,0xe9,0xbf,0x25,0x6a,0x27,0xe1,0x63,0x9b,0xdd,0x62,0x38,0xad,0xd3,0xb2,0x75,0x62,0x45,0xbf,0xbf,0xf4,0xe2,0xd6,0x97,0xe9,0xeb,0xeb,0x98,0xab,0x73,0xdc,0x8a,0xde,0xaa,0x3b +.byte 0x69,0xfd,0x61,0x6f,0xbb,0xfc,0x28,0xc0,0xff,0x37,0x2e,0xeb,0x31,0x59,0x57,0xfb,0xd3,0x0e,0xed,0x01,0x66,0x50,0x63,0x53,0xa2,0xd1,0x24,0x8c,0xc8,0x8d,0x80,0x03,0x2a,0x1e,0x11,0x3a,0xb9,0x6c,0xf4,0x5f,0x58,0xa2,0xd6,0x58,0x6b,0x85,0x61,0xd1,0xe7,0xdc,0x90,0x07,0x34,0x6e,0xb9,0x0b,0x0d,0xcb,0xd5,0xe3,0xc6,0x9d,0xb8,0x51 +.byte 0x37,0x61,0xd0,0x6c,0x2e,0xed,0xe0,0xbc,0x55,0x74,0x63,0x1b,0x42,0x17,0x6a,0x9c,0x91,0x1b,0x96,0x76,0xc8,0xe4,0x2b,0x2e,0x90,0xd9,0xe5,0x3f,0x56,0x1b,0x2f,0x93,0x81,0x86,0x2a,0xb4,0xdf,0x93,0xcb,0xfa,0x01,0x85,0xd9,0x26,0x46,0x46,0x97,0x2a,0x2e,0xb3,0x91,0xe4,0xcf,0xd9,0x01,0x5a,0x37,0xa6,0xca,0x5e,0xed,0xa9,0x94,0x35 +.byte 0x2c,0x69,0x5b,0x1e,0xf8,0x38,0x61,0x41,0x10,0xf6,0xe9,0x6e,0x96,0xee,0xe6,0x5f,0x78,0x14,0x93,0x12,0xd2,0x57,0xe5,0xf4,0x58,0x46,0xca,0xc8,0x75,0x59,0xbd,0xd0,0xe4,0x70,0x35,0xa5,0x4a,0xfd,0x54,0xe2,0x91,0x76,0x0e,0xe6,0xe3,0xbb,0x31,0x65,0x4b,0x18,0xa8,0xb4,0xfa,0xa6,0x7d,0x7a,0xa9,0x47,0x3d,0x2b,0x2e,0x66,0xac,0x5b +.byte 0x3e,0x5e,0x8c,0x27,0x0c,0x33,0x04,0x03,0x4e,0x5f,0xcd,0x6b,0x9c,0xaa,0x13,0x83,0x38,0xe9,0x38,0xcf,0x03,0x70,0x5a,0x0f,0x18,0xf5,0xec,0x64,0xf3,0x0c,0xe8,0xb1,0xa9,0x07,0x70,0xf7,0xde,0x0c,0x35,0xf5,0xe2,0xcd,0xed,0xe6,0x4d,0xac,0x5c,0x4d,0x3e,0x03,0x96,0x90,0x7b,0x4c,0x3e,0x18,0x42,0xc0,0xa7,0x23,0x12,0x8e,0x54,0xc1 +.byte 0xa1,0x2f,0x82,0x13,0xe6,0x1f,0x74,0xae,0x7b,0x4a,0xa4,0xbb,0xdc,0xc0,0x68,0x0f,0x83,0xbc,0xda,0xce,0xa2,0xe7,0xbe,0x18,0xcd,0x8b,0x35,0x05,0xa3,0x4b,0x6f,0xf0,0x53,0x12,0x42,0x2f,0x3c,0x09,0x87,0xb7,0xe3,0x36,0x29,0xe1,0xa2,0xb6,0x60,0x05,0xb9,0x66,0x80,0xe9,0xec,0x40,0x2a,0x55,0x78,0x5f,0x1c,0x5f,0xc3,0xc7,0x49,0x69 +.byte 0x87,0x97,0x5f,0xa5,0x31,0xa8,0x83,0x66,0x5a,0xd7,0xaf,0xf0,0x15,0xf3,0x01,0x62,0x9a,0x88,0x76,0x0f,0xb3,0xdf,0xf1,0xc6,0x34,0xc3,0xac,0x68,0x60,0x9a,0x91,0x03,0x13,0xea,0x0e,0x36,0x9c,0xf5,0x51,0xb7,0x0c,0xa4,0xeb,0xf0,0x41,0x85,0x54,0x05,0xed,0x7a,0xc2,0xba,0x3b,0xb8,0x1c,0x41,0x0d,0xbb,0xad,0x16,0x7e,0x64,0x4f,0x88 +.byte 0x7a,0x17,0xae,0x76,0x55,0x78,0x93,0xe8,0x99,0xa1,0x70,0x1f,0xf6,0x8a,0xb9,0xeb,0x41,0xb9,0x08,0xb8,0x9d,0x78,0x57,0xa1,0xe1,0x23,0xa0,0x03,0xd3,0x16,0xbc,0x16,0x24,0xed,0xc5,0x12,0x16,0x0a,0x8a,0x23,0x11,0x22,0xc2,0xfe,0x49,0x9d,0x3d,0x10,0x3d,0x4b,0xeb,0xab,0xcb,0x21,0x9d,0x9d,0xb1,0x64,0x87,0xe5,0x4d,0xb9,0xe7,0x10 +.byte 0x05,0xa0,0x55,0x2f,0xdf,0x53,0x5e,0x03,0xec,0x7e,0xe4,0x1f,0x9b,0x16,0x0c,0xfc,0xd9,0xf9,0x66,0x39,0x93,0x9e,0x49,0x34,0x97,0xd6,0xa5,0x56,0x00,0xf1,0xaf,0x08,0xeb,0x58,0xcf,0x87,0x02,0xc4,0xf1,0x24,0xe8,0x29,0x83,0xc9,0x5d,0x56,0x68,0xa2,0xaa,0xba,0xb3,0x86,0x23,0x59,0x8d,0x32,0x96,0x4a,0xbb,0xe9,0xf2,0x53,0xb2,0x87 +.byte 0x4a,0xf5,0xdc,0x23,0xd4,0x2f,0x36,0x70,0xb5,0x1d,0xee,0x47,0x51,0x6c,0x35,0x2a,0xad,0x35,0x74,0x1b,0x98,0xb5,0x33,0x2c,0x6d,0x4c,0xf8,0x39,0x07,0x92,0x6c,0xc7,0x65,0x10,0x64,0xcd,0x53,0xa3,0xcb,0xcc,0xe4,0xb2,0x46,0xb3,0xb7,0x44,0x01,0x92,0x44,0x12,0x23,0x25,0x3e,0x00,0xe3,0xeb,0x5f,0xe5,0x76,0x48,0x4e,0x4a,0x7f,0x36 +.byte 0xf0,0x0b,0x5e,0xc0,0x97,0x0d,0xc8,0xcf,0xd5,0xb8,0xc0,0x11,0x8d,0xb9,0x1e,0x31,0x0f,0x84,0x36,0x2e,0xe0,0x42,0xe6,0x02,0x9d,0xa4,0xdb,0xa2,0x76,0xfd,0xa1,0x95,0xe0,0x49,0xe6,0xf1,0xd2,0xae,0x27,0x6b,0x11,0x05,0x47,0xb0,0xaa,0x61,0x01,0xd4,0xe6,0xcd,0x9d,0x7e,0x33,0x5d,0xec,0x22,0x96,0x59,0xb7,0xc5,0x50,0x83,0xa4,0x66 +.byte 0x56,0xc7,0x43,0xa6,0xf7,0x5d,0xb2,0x45,0xc0,0x96,0xa0,0x5b,0xb8,0xed,0xae,0x29,0xb3,0x7d,0xbd,0x01,0xde,0xc0,0xe7,0xcc,0xe9,0x55,0x32,0x32,0xbf,0xdd,0x03,0x1b,0xb0,0x4e,0xff,0x53,0x1f,0x4b,0xc6,0xec,0x16,0x9d,0x5b,0x78,0x74,0xc4,0x75,0x51,0x8a,0x1c,0xae,0x6b,0xcd,0x9c,0x77,0x47,0xbf,0xd1,0x38,0x3e,0x9e,0xc0,0xad,0x16 +.byte 0xb7,0x15,0x6b,0xdc,0xad,0xe9,0x13,0xbc,0x48,0xc1,0xaf,0x69,0xce,0xc4,0xcc,0x9b,0x73,0xf9,0xd5,0x7c,0xab,0xf0,0xf1,0x9b,0xea,0xc6,0x0b,0x19,0x47,0x42,0xc1,0xa0,0x02,0x64,0x17,0xce,0x88,0x4f,0x16,0xa6,0xed,0xdb,0xfe,0x61,0xd3,0xd6,0xc0,0x11,0x30,0x16,0xd2,0x45,0xb3,0x7e,0x52,0xd0,0x94,0x77,0xf0,0x0e,0xbf,0x16,0xc0,0x4a +.byte 0x2a,0x5c,0xac,0x55,0x57,0xb1,0x41,0xb6,0xa3,0x68,0x8c,0x0a,0x66,0x15,0xb4,0xf5,0xd9,0x9a,0xa9,0x68,0xf2,0xbc,0x06,0xc5,0x7c,0xd1,0x18,0x55,0x9a,0x2d,0x94,0x2e,0x04,0x4b,0x7d,0x3c,0xb1,0xe3,0x03,0x7a,0xa7,0xe3,0xe5,0x63,0x49,0x7c,0x3f,0x0a,0xc5,0xbd,0xd3,0x0f,0x04,0xfd,0x99,0xf7,0xe6,0x05,0x35,0x66,0x17,0x05,0x85,0x3b +.byte 0x98,0x92,0x11,0x26,0xe2,0x21,0x52,0x1b,0x54,0x08,0xc8,0xf0,0x4e,0x75,0x22,0x3f,0xe8,0xb6,0x35,0xa4,0x02,0x52,0x70,0xc2,0xce,0x5a,0x00,0xe2,0xe2,0x92,0x8c,0x97,0xa7,0x1d,0x42,0x52,0x8b,0xf1,0x81,0xa7,0xce,0x60,0x46,0xbe,0xf0,0x1d,0x34,0xdf,0x73,0x2a,0xd6,0x9a,0x2d,0xf9,0xe3,0x91,0x05,0xe4,0x1f,0x31,0x11,0x30,0xb0,0xff +.byte 0x8f,0x61,0x74,0xf4,0xef,0xcd,0xf6,0xa4,0x9a,0xd2,0x5e,0xba,0x27,0xe8,0x78,0x38,0xfc,0x75,0xff,0x3b,0x6c,0xde,0x4a,0x46,0x47,0x8e,0x97,0x28,0xe4,0x23,0xe0,0x10,0x07,0xca,0xcb,0x6d,0xed,0x29,0xc0,0xee,0x98,0x96,0x7c,0x90,0x1f,0x89,0x12,0x0f,0xd5,0x28,0xcf,0x6e,0x4b,0x9b,0x2d,0xb3,0xcd,0x97,0xb8,0xeb,0x58,0x23,0x26,0xb1 +.byte 0xb4,0x95,0x11,0x1e,0xee,0x00,0xde,0x24,0x28,0xa6,0x3f,0x15,0xa2,0x9a,0xcb,0x9d,0xe3,0x04,0x5d,0xc3,0x60,0x97,0x14,0x2c,0x84,0x2b,0x69,0x9c,0x2a,0xbf,0x08,0xba,0xc4,0x38,0x36,0xaa,0x89,0x11,0x32,0x63,0x01,0xa2,0x44,0x5f,0x50,0xf0,0x5b,0x11,0x15,0xc8,0x80,0xc9,0xa6,0xe7,0x5d,0x70,0xa8,0x34,0x42,0x97,0x2a,0x60,0x99,0x20 +.byte 0xa6,0x60,0xc0,0x70,0x8d,0x2f,0x3f,0x8a,0x14,0x80,0x8a,0xbe,0x05,0xb3,0x50,0x16,0xaf,0x32,0xb4,0x35,0x3e,0x1d,0x31,0x42,0xdd,0x50,0xeb,0x04,0x82,0x4c,0x83,0x3d,0x8f,0xb6,0x1e,0xc2,0xa9,0xd2,0x30,0xba,0x33,0xdb,0x97,0x6d,0x2d,0x97,0x59,0x33,0xc0,0xf8,0xa5,0x59,0xc5,0x44,0x9c,0xf1,0x06,0xc4,0xf2,0x31,0x3e,0xff,0xb8,0x12 +.byte 0x00,0x4d,0x6c,0x2d,0xa1,0xc7,0x83,0xea,0x55,0x93,0x0e,0x89,0x76,0xbf,0x56,0x2a,0x99,0x62,0x54,0xad,0x2c,0xe8,0xf0,0xf9,0x70,0x18,0xa5,0x2b,0x24,0xac,0x59,0xc9,0x84,0xe3,0x1a,0x9d,0xa0,0xdb,0x1b,0x7f,0xd5,0x7e,0xb5,0xe0,0x86,0x36,0xc5,0x71,0x6a,0xab,0xdb,0xa5,0x84,0xf1,0x9e,0x9e,0xf6,0x1b,0xab,0x47,0x94,0x38,0x8e,0x5d +.byte 0x55,0xb4,0xf5,0xc3,0x59,0xc2,0x2c,0x6d,0x9d,0x28,0x7d,0x33,0xcd,0xc7,0xd6,0xdf,0x10,0xda,0x7c,0xd0,0x6c,0x91,0x88,0xd6,0x6b,0xe7,0x72,0x75,0x18,0xb1,0x87,0xe4,0xbb,0x10,0xe0,0xa3,0x0f,0xea,0x65,0x0a,0x70,0xc8,0xee,0x52,0x05,0x0a,0x27,0x39,0x66,0xda,0xd6,0xa6,0xfe,0x97,0x24,0x09,0x9d,0x20,0x76,0x4e,0x97,0x9d,0xa9,0x9f +.byte 0x76,0x20,0x27,0x57,0x5b,0xf4,0x76,0x1a,0x4b,0xcf,0x13,0x6c,0x9e,0x63,0x53,0x97,0xca,0x10,0xd6,0x90,0x7d,0xfc,0xe3,0x03,0x2c,0x6c,0x79,0x93,0x1a,0xae,0x0f,0x43,0xdb,0x75,0xde,0x56,0xa6,0x69,0x93,0xce,0x2d,0x94,0x56,0x77,0x90,0x19,0x71,0x7f,0x7a,0x99,0xbd,0x9c,0x79,0x62,0x00,0x49,0x3a,0x62,0x49,0x4b,0x92,0x65,0x8b,0xe2 +.byte 0xa8,0x3d,0xa5,0x89,0x23,0xac,0xea,0xf1,0xbf,0x38,0x84,0xd7,0xe2,0x65,0xb6,0xc7,0xbc,0x02,0x11,0xfd,0xe3,0x4c,0x57,0x38,0xd4,0x36,0x54,0xe8,0xbb,0x63,0x17,0xe9,0xda,0x82,0x50,0xf1,0x8c,0x34,0x4d,0x75,0x2a,0x64,0x49,0xaf,0x98,0xc3,0x1d,0xad,0x31,0xf3,0x90,0x23,0x39,0xf5,0xb5,0xf4,0x37,0x88,0x67,0x12,0x5d,0xfc,0xee,0xe5 +.byte 0x44,0x52,0x2c,0x78,0xb1,0x90,0xc1,0xc2,0x77,0x6e,0x31,0x3e,0xa0,0x36,0x87,0xb0,0xc6,0x6c,0x94,0xc2,0x43,0x4a,0x7b,0xa2,0x73,0xe7,0xa0,0xc3,0x4c,0xaf,0x4f,0xa6,0x92,0x1c,0x9a,0x6d,0xee,0xe8,0x4d,0xe1,0xe0,0xc7,0x67,0xcf,0xcf,0x7d,0x7f,0x0f,0x07,0x0d,0x6c,0x06,0x06,0xc2,0xc9,0x28,0xfc,0x8d,0xcd,0x23,0x01,0x97,0x5b,0x4d +.byte 0x1c,0xdb,0x34,0x51,0x6e,0xe2,0x56,0x24,0xd7,0xbd,0x12,0xc4,0x2f,0xb4,0x3b,0x02,0xaa,0x47,0xda,0x61,0xf6,0xca,0x44,0xa8,0x02,0xbf,0xbc,0x58,0xfb,0xa2,0xff,0xf3,0x54,0x59,0x5f,0xd7,0xa0,0x7c,0x83,0xa6,0xef,0xeb,0x71,0x51,0x74,0xa1,0x27,0x10,0x97,0x13,0x1f,0x42,0x91,0xdd,0xa8,0xf8,0xc7,0x60,0x90,0xca,0x2e,0xc8,0xaf,0x9f +.byte 0x65,0x1f,0x24,0x0a,0x30,0x5f,0xb9,0x4c,0xfb,0xcb,0xa3,0x96,0x5e,0xad,0xab,0xac,0x09,0x91,0xf5,0x96,0x1f,0xe0,0x96,0x14,0xc5,0xa0,0x26,0xa1,0xf1,0x91,0x80,0x38,0x7f,0x38,0xdc,0x98,0x96,0x20,0x46,0x50,0x20,0xd2,0x20,0xce,0x79,0xd5,0x81,0x60,0x97,0xb2,0xb0,0xeb,0x58,0x75,0x3c,0x99,0xf0,0xe0,0xfd,0xfc,0x90,0xc5,0xd1,0x3d +.byte 0x68,0x07,0xfd,0xa1,0x3f,0xeb,0x47,0xd0,0x58,0xe3,0xfa,0xbe,0xbf,0x20,0xdf,0x66,0x08,0x91,0xa4,0x5c,0x52,0x3e,0xdf,0x5c,0xb8,0xee,0xca,0xa6,0x89,0x06,0x97,0xb4,0x8d,0x60,0x35,0xb1,0xff,0x1e,0x39,0xf2,0x67,0xbc,0x71,0xee,0xeb,0x48,0x94,0x19,0x1a,0xee,0xc5,0xe2,0x7e,0x0d,0xf1,0xca,0xe8,0x2c,0xb0,0xaa,0x02,0x58,0x23,0x23 +.byte 0xce,0x37,0x5e,0xcb,0x58,0x40,0x2e,0x1a,0xa6,0x09,0x11,0x95,0xc4,0x6f,0x10,0xb0,0x15,0x22,0x48,0x67,0x74,0x6c,0x2f,0x4f,0x4a,0xb4,0x01,0xe5,0xa3,0x77,0xab,0xad,0xa4,0x04,0x22,0x71,0x58,0x4a,0x71,0xb1,0xe8,0xdf,0x43,0x18,0x0e,0x95,0x7c,0x8c,0x23,0x3a,0xf3,0x9c,0x20,0x60,0x20,0x69,0x51,0x28,0x7e,0x13,0x67,0x5c,0x7d,0x35 +.byte 0xfa,0x1b,0x04,0x8b,0xcf,0x42,0x6e,0x15,0x55,0xcd,0x04,0xdb,0x73,0xdb,0x47,0x5f,0x83,0x6e,0xd1,0x5a,0x15,0xa2,0xbb,0xf7,0xbb,0x84,0x58,0xce,0x75,0xe8,0xd2,0x92,0xd5,0xb7,0x76,0xf2,0x94,0x67,0x27,0x5f,0x32,0x91,0x3a,0xaf,0xd4,0x31,0xf8,0x92,0xce,0x63,0xb7,0x45,0x27,0xb4,0xb8,0x7a,0x1e,0x4e,0xde,0xcb,0xc8,0x5e,0xd3,0xbb +.byte 0x52,0x91,0xd5,0x72,0xad,0x98,0xec,0x07,0xa1,0x56,0xb4,0x8e,0x04,0xfa,0x48,0x3f,0x17,0x07,0xf7,0xef,0x92,0x61,0x69,0xaf,0xdd,0xfc,0x76,0x03,0xe2,0xe9,0xe2,0xbe,0x5c,0xf2,0x8a,0xc5,0x99,0x51,0x7f,0xa4,0xf1,0xac,0x16,0xec,0x16,0xf5,0xb8,0x95,0x88,0x87,0xdb,0x27,0x2e,0x63,0x12,0x31,0x7d,0x6b,0x2b,0xa0,0x9b,0xb5,0xf9,0x82 +.byte 0x42,0x04,0x94,0xee,0x60,0x6e,0x4e,0x54,0x9b,0xfd,0xeb,0x01,0x3a,0xad,0x42,0xeb,0x08,0x3c,0x6a,0xa3,0xf2,0x46,0xfb,0x18,0x59,0x2c,0xa3,0x0b,0x22,0x1d,0x5d,0x47,0xa6,0x8c,0x06,0x9c,0xa1,0xcc,0x20,0x67,0xbd,0xf0,0x5b,0x94,0x9f,0xc6,0x10,0x8c,0xc8,0x15,0x52,0xe3,0x19,0xa1,0x89,0xfd,0x99,0xad,0x4f,0x10,0x51,0x0a,0xe4,0x4b +.byte 0x02,0x7b,0x0d,0x73,0x2d,0xae,0xa4,0x68,0x1d,0xb6,0xcf,0x58,0x67,0xc0,0xd0,0xca,0x11,0x34,0x31,0x9e,0xa3,0xbc,0x12,0x28,0x1e,0x8e,0x5a,0x63,0xf5,0xda,0xf2,0x36,0x94,0x63,0x2c,0x39,0x3d,0xf9,0x80,0x9f,0xbf,0x8d,0xef,0x1f,0x15,0xc8,0xdb,0x62,0x58,0x7d,0xdc,0x0a,0x7f,0x87,0xaf,0x6d,0x2e,0xac,0x92,0x4f,0x51,0xdf,0x5e,0x75 +.byte 0x5e,0x0f,0x7c,0x51,0x49,0x88,0x0f,0x7b,0x49,0xa5,0x7c,0x41,0x4e,0x2a,0x0f,0xd0,0x0f,0x78,0xeb,0x42,0xfc,0x07,0x8a,0x8b,0x4e,0x3e,0xf2,0x42,0xc5,0x21,0x01,0x66,0xe2,0x50,0xf6,0x3d,0x28,0x1e,0xbf,0xdc,0x71,0x7f,0xc5,0x6e,0xc1,0xab,0x1a,0x33,0x49,0xdd,0xa2,0xb9,0x52,0xbe,0x93,0x97,0x97,0x7a,0xf0,0x22,0xa8,0xc5,0x01,0xc6 +.byte 0x76,0x6f,0xb6,0x2c,0x09,0x80,0x62,0x5b,0x84,0x05,0x7f,0x79,0x28,0x04,0x67,0xa2,0x0f,0xfc,0xbb,0x17,0xe2,0x85,0xe3,0xa0,0xf3,0x44,0x47,0x96,0x68,0x80,0xb2,0xbf,0xba,0x63,0x53,0x38,0x6c,0x3b,0xcd,0x3c,0xa4,0x10,0x48,0x80,0xd8,0x49,0x5a,0xf0,0x5c,0x38,0x02,0x02,0x5b,0xf2,0x77,0xa4,0xfd,0x16,0xfd,0x13,0xc8,0x8b,0x9b,0xcd +.byte 0xe1,0x8d,0x70,0xb6,0x3d,0x24,0x65,0xda,0x1a,0x42,0x6f,0x90,0x64,0x9a,0x9b,0xda,0x54,0x44,0xc0,0xe0,0xd7,0xfb,0x73,0x10,0x3c,0xcf,0xa6,0x04,0x99,0xd9,0x45,0xe5,0x74,0xfe,0xdf,0x81,0xac,0xc8,0x30,0xe5,0x66,0x45,0x02,0xca,0xcd,0xd7,0xe6,0x7b,0x0d,0xda,0xe1,0xa0,0xa1,0xa1,0x87,0x34,0x63,0x0b,0xa7,0x82,0x39,0x83,0xba,0x18 +.byte 0x0b,0x16,0x35,0x11,0x53,0x8d,0xbe,0x7d,0xa8,0x7e,0x3f,0xf4,0x71,0xc9,0x37,0x6f,0x1a,0xd9,0x3f,0x8e,0xc4,0xc1,0xd3,0x80,0xdf,0xee,0x0e,0x6b,0x23,0xf7,0xbc,0x42,0x93,0x7a,0x36,0x6f,0x03,0x24,0xb4,0x9c,0x62,0xa0,0xed,0xed,0x0b,0x66,0xa8,0x25,0xe6,0x1a,0xd4,0x13,0xd1,0x16,0x14,0x2b,0x90,0x7d,0x2e,0xa4,0xda,0xb2,0xf9,0x33 +.byte 0x54,0xf9,0x0a,0x04,0x27,0x03,0x14,0xd2,0xd7,0xe2,0xc1,0xaa,0xb6,0xe8,0xe5,0x4c,0xf2,0xdb,0x4c,0xc8,0xb3,0xa4,0xeb,0xbf,0x12,0x5c,0x9d,0x65,0xaa,0x9a,0x66,0x77,0x42,0xb4,0xd5,0x5b,0x1f,0x3b,0xd7,0x91,0x89,0x57,0x2f,0xd0,0x86,0x99,0xb2,0xc8,0xc1,0x31,0xde,0x33,0x43,0x36,0x81,0xdb,0x97,0x7b,0x17,0x3b,0xa5,0x99,0xdb,0x63 +.byte 0x2b,0x48,0x4c,0xa6,0x5c,0x6c,0xd8,0xc9,0x6e,0x72,0x39,0xbe,0x6e,0x55,0x7e,0x9d,0xb7,0x20,0x8d,0x8f,0x81,0x20,0x78,0xae,0xc6,0x1d,0xe0,0x2d,0xb1,0xe7,0x64,0xbb,0xd4,0xc8,0x08,0x61,0x14,0x29,0x08,0xbc,0x1a,0xeb,0xfa,0x64,0x33,0x91,0x7d,0x91,0x41,0x65,0x8e,0x4c,0x0c,0xb2,0x79,0xc3,0x01,0x68,0xfc,0xd6,0xbb,0x50,0xcc,0x07 +.byte 0xa5,0xf6,0x2c,0x5e,0x10,0xd6,0xa3,0x62,0x18,0xec,0xa2,0xf2,0x6b,0xad,0xcd,0x02,0x01,0x75,0xbb,0x36,0x27,0x56,0x0f,0x55,0x03,0xe0,0x57,0xe1,0x72,0xeb,0x66,0x00,0x21,0xff,0x9a,0xbc,0xc1,0x1e,0x2c,0x93,0xe6,0x4d,0x93,0x28,0x10,0x7d,0x67,0x6c,0xf1,0xa4,0xe6,0x3a,0xa6,0x30,0xc8,0x50,0x1d,0x8b,0x6e,0x7b,0x76,0x98,0x14,0x4e +.byte 0xed,0x84,0x67,0x2a,0x5f,0xac,0x0b,0x7b,0x47,0x40,0xb3,0x2d,0x7a,0xc1,0x23,0xdc,0x62,0xf8,0x8e,0x90,0x77,0xd4,0xf9,0x00,0x4b,0x67,0x04,0x72,0xf8,0xc9,0x2c,0x2d,0x0e,0x3c,0x3c,0xf3,0xfc,0xa8,0xe2,0x49,0xa4,0x00,0x82,0x98,0x72,0xa9,0xec,0xea,0xbd,0x3a,0x4e,0xd7,0x32,0xf1,0x11,0xf0,0x0d,0x9e,0xa2,0xe8,0xfe,0xcc,0x67,0xec +.byte 0xfc,0xd6,0xfe,0x83,0x5e,0x7c,0x2b,0xb3,0x42,0xf4,0x2d,0x9a,0xbe,0x20,0xd1,0x81,0x62,0xe9,0x59,0x19,0x28,0xdf,0x97,0x10,0x54,0xf7,0xde,0x60,0x51,0x6a,0xce,0x32,0x03,0x75,0x5c,0x25,0x25,0x82,0x9c,0x07,0xf7,0x2d,0xa8,0x1b,0x9f,0xd3,0x32,0x46,0x25,0x1f,0xb1,0xc5,0xbb,0x28,0x14,0x3e,0xed,0xa8,0x83,0x20,0xf4,0x9c,0x75,0xf4 +.byte 0xe6,0xc4,0x2d,0x05,0x88,0x31,0xfd,0x48,0xca,0x6c,0x7f,0xab,0xb4,0x77,0x93,0x1d,0x87,0xc3,0x4e,0xb8,0xad,0xb4,0x3d,0x37,0x7a,0xd2,0x77,0xff,0xc2,0xcb,0x9c,0xc7,0xbf,0x02,0x02,0x70,0xc9,0x9f,0x77,0x8a,0x7d,0xa7,0x9a,0x10,0xd1,0x0e,0xb7,0xec,0x61,0xee,0x77,0x24,0xe9,0x3d,0xcd,0x12,0xca,0xee,0x50,0xb0,0x27,0x5d,0xe5,0xac +.byte 0xa3,0x92,0xc7,0xd0,0x23,0x54,0xb1,0xe5,0x50,0xc3,0x15,0xd7,0x66,0x32,0x38,0x34,0xb1,0x59,0x1b,0xc3,0x59,0xe8,0xad,0x59,0x90,0x58,0x6e,0x02,0x40,0xb1,0x51,0x65,0x78,0x25,0x26,0x01,0xdd,0xcf,0x04,0xa2,0xfe,0xc3,0xbb,0x80,0x1c,0xb0,0x4e,0x9c,0x49,0x48,0xa3,0xe2,0xcc,0x81,0xc5,0xa8,0xd4,0xd5,0xe4,0xab,0x39,0xe7,0xe8,0x97 +.byte 0xc7,0x51,0xb4,0x5e,0x3f,0xe6,0xa7,0xcc,0x45,0x18,0xa2,0x6a,0xb3,0xa8,0x0b,0x7d,0xce,0x1a,0x97,0x4a,0x67,0xe1,0x3c,0x7c,0x4e,0xad,0x90,0xcf,0x2a,0x8f,0xb8,0xb6,0x96,0xaa,0x9a,0xc3,0x73,0xe6,0x71,0xdb,0x11,0x9b,0xd9,0xd9,0xfe,0xba,0x4a,0xf0,0x77,0xa4,0x15,0xb5,0xca,0xe1,0xb4,0x16,0x06,0x46,0xdf,0xc5,0x49,0x07,0x66,0xb3 +.byte 0xf5,0x30,0xe3,0xfb,0x44,0xac,0x80,0x3a,0x21,0xd9,0x5b,0x22,0x54,0x3a,0xae,0xbe,0xbd,0xf0,0x99,0x8d,0xb5,0x2a,0xf7,0xc9,0xf2,0xd3,0xfb,0x07,0x7c,0xd7,0x75,0x30,0x2a,0xcd,0x80,0xa8,0x2a,0x6a,0xb9,0x47,0xe2,0xa1,0xb0,0x76,0x6a,0x0f,0x9f,0x4a,0x56,0x3e,0xde,0xb3,0x89,0x12,0x25,0x63,0x1a,0x9d,0xea,0x64,0x08,0xc5,0x78,0xa7 +.byte 0x53,0xce,0xf8,0xb2,0xe5,0x97,0x3a,0xeb,0xd1,0x92,0xe1,0x4d,0xe0,0xf5,0x93,0x39,0x73,0xad,0x67,0xc9,0x0e,0x6b,0x16,0x4a,0x00,0xaa,0xb4,0xe6,0xa6,0xa5,0x67,0x95,0x90,0x04,0x5e,0x4d,0xc3,0x7f,0x6b,0xa1,0x50,0xb0,0x3b,0x72,0x0d,0xb3,0xec,0x9a,0x18,0x92,0x65,0x0c,0x2d,0x0f,0x94,0xd6,0x0f,0x95,0xba,0x4b,0xe6,0xc3,0x07,0x22 +.byte 0x0d,0x40,0xd4,0x0d,0x97,0x44,0xba,0x54,0x8c,0xf8,0x97,0x52,0x1f,0xa7,0xb2,0xe8,0x1b,0x0a,0xd5,0xde,0xff,0x1b,0x33,0x60,0x6a,0x28,0x68,0x36,0xb9,0x5a,0x3e,0x43,0x84,0x9a,0xb1,0x3d,0x3d,0xdb,0x1b,0xa2,0xc5,0x0e,0x2d,0xb5,0x5a,0xa5,0x36,0xe7,0xbf,0x7e,0xc3,0x76,0xad,0x1e,0xb5,0x49,0xc2,0xd5,0xa2,0x69,0x97,0x45,0x43,0x3e +.byte 0xeb,0xcd,0xdf,0x4f,0xab,0xb3,0xe8,0x49,0xaa,0x9c,0x9c,0x58,0x1e,0xc8,0x1c,0x79,0xe9,0x16,0x1d,0xfe,0x54,0xac,0x55,0x18,0x10,0x73,0x97,0xdc,0xbe,0x45,0x63,0xfb,0x48,0x41,0x88,0xb4,0x0b,0x3a,0x1d,0x65,0x40,0x1b,0x10,0x66,0xeb,0xbe,0xed,0xc7,0x6c,0xd5,0x0c,0x19,0x85,0x23,0xb1,0x38,0xb3,0x4b,0xcd,0xc7,0xc5,0x06,0x18,0x40 +.byte 0xbd,0xef,0x9f,0x2e,0x3a,0x71,0x33,0x05,0x30,0x71,0xca,0xe9,0x7a,0x2c,0xe7,0x83,0x4e,0x3d,0x4b,0xc8,0xc7,0xcb,0x74,0x9c,0xa2,0xc7,0xbb,0x8c,0x44,0x0d,0xd8,0xb3,0x01,0x7c,0xdf,0x79,0xee,0x47,0xcb,0x91,0x6f,0xc3,0xfd,0x0f,0xfb,0xf8,0x6b,0x9b,0x00,0xaf,0xf6,0x69,0x82,0xa5,0x58,0x54,0x22,0x7f,0x4b,0xee,0xa7,0x03,0xdb,0xb6 +.byte 0x5f,0x12,0xe1,0x04,0x43,0x17,0xec,0xd4,0xdd,0x39,0x28,0xfa,0xa3,0x09,0x5e,0x14,0xaf,0x6b,0xfe,0x0c,0x65,0x01,0x13,0x75,0x3d,0xe7,0x6d,0xd9,0xda,0x1d,0x13,0xc1,0x56,0x40,0x50,0x95,0x65,0x8f,0xad,0x51,0x3f,0x13,0x05,0x2f,0x83,0xcd,0xca,0x8b,0x75,0xa2,0x39,0x61,0xde,0xd7,0x36,0xf9,0x1d,0x43,0x5b,0xc4,0x9a,0xc9,0xfc,0xa8 +.byte 0xf4,0x76,0x90,0x91,0xe8,0x52,0x5b,0x84,0xe7,0xc9,0x8e,0x7d,0x84,0xba,0xb1,0x32,0x12,0xce,0x06,0x9e,0x98,0x83,0x1f,0x7f,0x31,0xd7,0xf0,0x8a,0xa2,0xca,0xae,0xb3,0x50,0x51,0x93,0xfb,0x2f,0x43,0x0a,0xee,0x06,0x85,0xec,0xb8,0xf1,0x73,0xb1,0x65,0x37,0x05,0x8e,0x68,0xf7,0x7a,0xff,0xe7,0x17,0x08,0x5e,0x19,0x75,0x3d,0xf9,0x5e +.byte 0xd5,0x25,0xf6,0x3b,0x99,0xb9,0x96,0x42,0x7a,0x37,0x8f,0x0d,0xde,0x22,0x83,0x89,0xf0,0x77,0x1f,0x22,0x42,0xc7,0xb5,0x70,0xcb,0xfd,0xf0,0xa9,0x87,0x8e,0x1f,0x01,0x9a,0x26,0xa6,0x8c,0x41,0xb9,0x12,0xd6,0xf2,0x5b,0xe5,0xfd,0xdc,0x74,0xbd,0xa1,0xc8,0xf7,0x3b,0x8c,0xe1,0x1d,0x42,0xb4,0x07,0x24,0x18,0x84,0x94,0x8a,0xce,0x00 +.byte 0xbd,0xd7,0xb0,0xfd,0x8f,0x0a,0xd3,0x75,0xa4,0xe8,0xfc,0x09,0xa9,0xa3,0x57,0x68,0x79,0x0e,0xef,0x37,0x46,0xd5,0x3b,0x8c,0x0d,0x67,0xbc,0x2c,0x5d,0x3e,0xf7,0xcc,0x9c,0x9e,0x81,0x62,0xc8,0xec,0x38,0x20,0x07,0x66,0xe4,0x83,0x15,0x13,0x3b,0x47,0x23,0xd9,0x46,0xaf,0x65,0xe1,0x40,0x2d,0x14,0x84,0x72,0xc1,0xbf,0xbe,0x81,0xc4 +.byte 0xcb,0x04,0x16,0x5e,0x2f,0x60,0x3a,0x8e,0x1a,0xd3,0xa2,0x00,0x25,0x6c,0xb7,0xdb,0x0d,0x20,0x99,0xb8,0x45,0x54,0xbf,0xc4,0x52,0x52,0x92,0x7d,0xcd,0xa1,0x9a,0x12,0x5e,0x27,0xe9,0xcf,0x79,0x9d,0xa8,0x6c,0xcd,0x37,0x20,0x08,0x09,0xc6,0x94,0x53,0x00,0x04,0xf5,0x3b,0xea,0x00,0x1b,0xc3,0x02,0xff,0xbc,0x18,0x1f,0xb7,0xf7,0x26 +.byte 0xe8,0x8b,0xc4,0x5f,0xf7,0xbe,0x9b,0xb3,0xba,0xae,0xbd,0x9c,0x3f,0x95,0xf7,0xcd,0x2b,0x40,0xf4,0x1c,0x6f,0xd7,0x52,0xe1,0xa7,0xdc,0x79,0xa4,0x88,0xff,0xfc,0xcf,0xfb,0xbb,0xe6,0xef,0xb6,0x31,0xac,0x24,0xa7,0x40,0xea,0x76,0xa2,0x34,0x6c,0xb1,0xfb,0x96,0x6b,0xfa,0xdd,0x60,0x70,0x73,0xb8,0xfd,0x66,0x3d,0xf9,0x63,0xc9,0x04 +.byte 0x70,0x20,0x35,0xca,0x04,0xb8,0xb3,0x4f,0x24,0x64,0x54,0xc2,0xd9,0x4d,0x8b,0xad,0x07,0xad,0xc5,0xb9,0x84,0xac,0x7c,0x65,0x4b,0x98,0x1d,0x09,0x23,0x95,0x5c,0x85,0x26,0xe5,0x8e,0xec,0xeb,0xc3,0xd5,0x15,0x9c,0x37,0x4e,0xf3,0x3c,0x97,0x92,0x75,0x99,0x48,0x48,0x52,0x4b,0x7b,0x93,0x54,0xd7,0x4f,0x7f,0xe5,0x51,0xdc,0x74,0x85 +.byte 0x9a,0xae,0xbd,0xf8,0xe6,0xe8,0x3f,0x1b,0xee,0x8b,0xf4,0xd8,0x5c,0x6c,0x46,0x6e,0x1d,0xaf,0x67,0x27,0x9a,0x39,0x4e,0x6b,0x99,0xcc,0xc0,0x66,0x54,0xbf,0x60,0xf6,0x24,0x64,0xfd,0x16,0xbf,0x56,0xb2,0x07,0x87,0x46,0xa6,0xef,0x40,0x67,0x78,0x2f,0x78,0x49,0x81,0x25,0xbd,0xa1,0xcf,0x78,0x68,0x25,0x8e,0x93,0x0a,0x4b,0xe1,0x92 +.byte 0x33,0x9c,0x13,0x70,0xd4,0xdf,0x74,0x34,0x8f,0x21,0xb9,0x51,0xd7,0x74,0xa9,0x02,0x6e,0xdd,0xb2,0xb4,0x6e,0x2a,0x95,0xdb,0xe4,0xaf,0x17,0xf5,0x9b,0xa5,0xc1,0x72,0x36,0x35,0x02,0x37,0x1c,0x38,0xaa,0x81,0x76,0xc6,0x1c,0xc3,0x2c,0xc5,0x45,0xaf,0x03,0xea,0xe6,0x14,0x51,0x44,0x84,0x9e,0x32,0xfe,0x4b,0x47,0xe9,0xb4,0x12,0x96 +.byte 0x13,0x6f,0x4c,0xed,0xe4,0xb0,0x79,0x7b,0xe5,0xc0,0x37,0x87,0x78,0x28,0x42,0xf7,0xd4,0xde,0xfc,0xd2,0x23,0x11,0x09,0xa5,0x11,0xc3,0xc4,0xf5,0xe0,0x2b,0x47,0x01,0x63,0xf2,0x85,0x1f,0x45,0x28,0xae,0xd3,0x29,0x04,0x1a,0x4b,0x83,0xab,0xf2,0x35,0x3a,0x40,0x2c,0x8d,0xb3,0xc7,0x47,0x0d,0xd1,0x3c,0xd0,0x1c,0x6b,0x5d,0x9b,0x4e +.byte 0xdf,0x36,0x8d,0xc6,0x54,0x9e,0x61,0x51,0xf1,0xd2,0xa4,0x39,0xad,0x4a,0x14,0xa1,0x0b,0xd3,0xae,0x91,0x1a,0x29,0xeb,0xc5,0x75,0x88,0x13,0x1e,0x96,0xdd,0x6f,0x86,0x92,0xaa,0x37,0x16,0x95,0x86,0xbc,0xb1,0x35,0xbf,0x5f,0x75,0x40,0x46,0xe1,0x6f,0x2f,0x33,0x2d,0x13,0x35,0xef,0xca,0x09,0x04,0xe4,0x42,0xef,0x69,0x66,0xda,0xa6 +.byte 0x01,0xda,0x09,0xfd,0xb1,0x40,0x8d,0xaa,0xdd,0x08,0x0d,0xf5,0xf1,0xd6,0xc6,0x11,0x3b,0xbd,0xd3,0x04,0x70,0x76,0xaf,0xec,0x9b,0xcc,0x6a,0x1d,0xeb,0x95,0x4a,0x01,0x0a,0x03,0x62,0x00,0x32,0xb3,0xe0,0xd1,0x36,0xb6,0xeb,0xde,0x4b,0x5f,0x35,0x79,0x07,0x4a,0x0d,0xa1,0x8c,0xde,0x6b,0xd2,0xca,0x71,0x64,0x73,0xf7,0x9c,0x1d,0x95 +.byte 0x5c,0xdc,0xb9,0x4f,0x00,0x2e,0x86,0x3d,0x81,0x7b,0x05,0xa5,0x9e,0x03,0xa3,0x62,0xcf,0x22,0x78,0x0b,0xfe,0x09,0x3e,0x62,0x93,0x19,0x6e,0x47,0x7d,0x92,0x4a,0x0b,0xae,0xcb,0x37,0x4d,0x5a,0x3a,0x7a,0x68,0xde,0xb2,0x7e,0xd7,0xda,0x5c,0x45,0xd2,0x0f,0x1d,0x03,0xbc,0xed,0xd8,0xe5,0x2e,0x26,0x10,0x82,0x46,0x5a,0xe0,0x13,0x32 +.byte 0xf8,0xb9,0x18,0x8c,0xbd,0xb4,0xb3,0x8c,0x2f,0xb0,0x5d,0x0b,0xf3,0x8f,0x5a,0xda,0x8b,0xda,0x39,0xfe,0xe6,0x66,0x95,0x3f,0xfe,0x49,0x89,0xbf,0x43,0x36,0x77,0xc7,0x6d,0xea,0x92,0x5c,0x71,0xa6,0x29,0x50,0xb0,0x2f,0xed,0x89,0x9f,0x2c,0xd6,0x6b,0xfa,0xbe,0x62,0x9f,0x62,0xc7,0xe3,0x2e,0xd4,0xf2,0x2c,0x9c,0x98,0x37,0x38,0x5e +.byte 0x81,0x6c,0x9e,0xcc,0xff,0x0f,0xfa,0xfa,0xe8,0xdd,0x2e,0x2d,0xb5,0x92,0x44,0x5e,0x2f,0xe1,0xd0,0x6c,0xc3,0xb9,0x11,0x95,0x70,0x4b,0x01,0xa0,0xc1,0x5e,0xe8,0x1d,0x40,0x16,0x9b,0x6e,0x29,0x1b,0x13,0xb9,0xda,0x39,0xbd,0x40,0x42,0xe2,0x06,0x35,0x57,0x2f,0xa8,0xf5,0xa7,0x00,0x60,0x07,0x26,0x21,0x6b,0xe6,0x23,0xa2,0x2a,0x70 +.byte 0xeb,0x85,0xcb,0xa9,0x73,0x31,0x62,0xf7,0xb0,0x90,0xd7,0x26,0xc1,0xd3,0xd7,0xcc,0x15,0x72,0x86,0xa6,0x0f,0x4a,0x24,0x14,0x5d,0xcd,0xbe,0xad,0x7d,0xf0,0x05,0x39,0x0c,0x10,0xbe,0x11,0x9a,0x36,0x9f,0x60,0x41,0xc6,0x7c,0xab,0x54,0x8a,0xac,0xc4,0xea,0xbd,0x43,0xeb,0x19,0x5a,0x8d,0x05,0xd1,0x83,0x58,0x92,0xb8,0xc6,0x75,0x56 +.byte 0x2c,0x58,0xb8,0x2d,0xe1,0x42,0xb4,0x0b,0xc9,0x97,0x79,0xb8,0x62,0xd0,0x15,0xd1,0x5d,0x0d,0x57,0x83,0xe4,0xba,0x73,0xa2,0x27,0xb8,0x56,0x64,0x28,0xaf,0xd2,0x58,0xe3,0xe6,0x12,0x01,0x6e,0x6a,0xfb,0x81,0x57,0xcd,0x32,0xc2,0x42,0x2a,0xe2,0x51,0x4a,0x4c,0xf8,0x69,0x0e,0xc0,0xe6,0x9f,0xf4,0x46,0x4b,0x60,0xcc,0x41,0x03,0xa4 +.byte 0x14,0xf0,0x15,0xb5,0xe5,0x39,0xfd,0x69,0xee,0xce,0x23,0x3a,0x50,0x66,0xdb,0xf4,0xe4,0x31,0x23,0xe9,0x06,0x93,0xdd,0x38,0xbc,0x2d,0xb9,0xf2,0x64,0x39,0x2f,0x1b,0xa9,0x71,0x0c,0x68,0xf7,0xb0,0x5b,0x74,0xe5,0x08,0xc6,0x5d,0xbe,0xb8,0xf7,0x40,0x0e,0xb4,0xe6,0x76,0x0c,0x14,0x8f,0x9d,0x25,0x95,0x6c,0x05,0x78,0x68,0x8a,0xa6 +.byte 0x80,0x24,0x8a,0x0b,0x6a,0xd7,0xfc,0xec,0x36,0xba,0x57,0xdd,0x49,0x82,0x3c,0x5f,0x9d,0xf4,0x57,0xac,0x16,0x99,0xed,0x73,0xa6,0xb0,0x2c,0x23,0xdb,0xf8,0x45,0x22,0xf4,0x82,0x16,0xc4,0x68,0x2f,0xe7,0x8c,0x85,0x6e,0x3c,0x43,0xdd,0x3d,0xea,0x90,0xeb,0xf4,0xef,0xf1,0x36,0x48,0x15,0x29,0x07,0x96,0x51,0xb5,0x78,0xa1,0xa3,0x59 +.byte 0x18,0x4d,0x11,0x5d,0x5e,0x67,0x69,0x28,0x29,0xcb,0xeb,0xbc,0x8f,0x17,0x12,0x57,0xaf,0xda,0xb5,0x86,0xef,0x59,0xdf,0xb1,0x6b,0x6a,0x33,0x66,0x67,0xd1,0x42,0xee,0xec,0x65,0xf2,0xeb,0x97,0x17,0x4e,0x01,0x3f,0x4d,0xb4,0x06,0x8e,0xf9,0xa8,0x79,0xb6,0xf1,0x67,0x8b,0xff,0x0b,0x5f,0x93,0x70,0x76,0x54,0xae,0x7b,0x0d,0x4a,0xbc +.byte 0xf7,0xdc,0x11,0x64,0xb3,0x6a,0xd1,0x69,0x45,0x1b,0x57,0xfc,0xb5,0xfe,0x86,0xb2,0xd6,0xde,0x82,0x23,0x86,0x6b,0x21,0x78,0x8b,0x2e,0x96,0xf8,0x04,0x8b,0xba,0x15,0xae,0x33,0x91,0x27,0x88,0xe3,0xc1,0xe7,0xf8,0xc3,0xa6,0xb6,0x73,0xec,0x84,0x95,0x22,0x45,0x58,0xb1,0x50,0x99,0xde,0x8a,0x37,0x41,0x9f,0xb8,0x27,0xd6,0xd8,0xaa +.byte 0x0f,0x0e,0xac,0xe4,0xd0,0x38,0xcf,0x2f,0x03,0x6f,0x3d,0x8a,0xd7,0x51,0xd6,0xf3,0x17,0x76,0xb5,0x0f,0xc5,0xf8,0xa7,0x0a,0x91,0xaa,0x8d,0xbc,0x15,0xd6,0x46,0xb9,0xdc,0x18,0x47,0x9c,0xd9,0x13,0xa5,0xb1,0xb5,0x45,0x2f,0x03,0x32,0x5c,0x8b,0xac,0x42,0x5b,0xd9,0x1a,0x41,0x1e,0x27,0xf9,0x92,0x72,0xc1,0xc7,0xc1,0x50,0x25,0x22 +.byte 0x7a,0x00,0x41,0x1f,0x2d,0x28,0xaf,0x41,0x96,0x8e,0x97,0x3b,0x36,0x80,0x16,0xe6,0x51,0x8f,0x07,0x13,0xd9,0x81,0x79,0x94,0x92,0xaa,0xb9,0xb6,0x39,0xf2,0x4d,0x24,0x6b,0x77,0x25,0x7e,0x47,0x6c,0xc7,0x62,0x3d,0x96,0x21,0xac,0x1a,0xf0,0x5f,0x5d,0x5a,0x7e,0x17,0xdd,0x47,0xd5,0x19,0x0a,0x85,0x3e,0xd5,0x6b,0x52,0x12,0xe2,0xbc +.byte 0x43,0x79,0x28,0x1d,0x72,0xcc,0xa6,0x6c,0xea,0x9b,0xe9,0x04,0x34,0x2c,0x41,0x3a,0x64,0xe8,0xcb,0x12,0xfa,0xd5,0x45,0xad,0xe8,0x3e,0xa2,0x5c,0xb8,0x83,0x52,0xdb,0x0c,0x98,0x24,0x76,0xd2,0x00,0x62,0xff,0xac,0xd7,0x11,0xee,0xcf,0xfb,0xdd,0x65,0xd2,0x75,0xb0,0x25,0x4e,0x76,0x3f,0xa2,0x1a,0xae,0xee,0xc1,0x59,0x1b,0x0c,0x42 +.byte 0x70,0x42,0x06,0x00,0x64,0x31,0xe0,0xce,0x3a,0x91,0x5e,0x9d,0x56,0x83,0xab,0xa7,0x73,0xc2,0x15,0x29,0xba,0xf9,0x1d,0xc8,0x4b,0xc6,0x3a,0x9e,0xab,0xd7,0xfd,0x17,0x8d,0x80,0xf0,0xa1,0x8a,0x5a,0x7a,0x80,0xd8,0x1f,0xa9,0x5b,0xec,0x68,0x99,0x3a,0x66,0xcc,0x5a,0xdf,0x5f,0xe9,0xd5,0x6a,0xf2,0x2c,0x7e,0xf8,0xa7,0xdf,0x0c,0x59 +.byte 0xbd,0x85,0xf0,0xc9,0x91,0x44,0x9c,0x86,0x24,0x60,0xfb,0xe9,0xff,0x3c,0xa7,0xa7,0x6d,0x4b,0x17,0xb3,0x24,0x99,0x14,0xbc,0x64,0xd0,0x41,0xaa,0xcd,0x26,0xd3,0xa3,0x51,0xeb,0x25,0x1d,0xb2,0x7d,0xf1,0xf3,0xf3,0xf0,0x3a,0xe0,0xb5,0xa9,0x24,0xc3,0x78,0x4a,0xef,0x9b,0x34,0x93,0xf8,0x0c,0x71,0x10,0x5b,0xf0,0xe7,0x08,0x4d,0x5f +.byte 0x74,0xbf,0x18,0x8b,0x48,0x8d,0xd7,0x23,0x81,0xed,0xa2,0x29,0xa9,0xdb,0x91,0xf6,0x61,0x7c,0xca,0x1e,0xe0,0xa7,0x21,0x9d,0xfc,0x04,0x3a,0x87,0xbb,0xf9,0xa4,0x3b,0xbb,0xc4,0x89,0xa1,0x7f,0xdc,0x83,0xfa,0x5e,0x0f,0xcf,0xdf,0xf6,0x41,0xd3,0xa3,0x76,0x76,0x44,0x3e,0x01,0xee,0xce,0xf6,0xc3,0xb9,0x49,0x43,0x6e,0xee,0x09,0x4c +.byte 0x87,0xe6,0xa3,0xf5,0xa0,0x8d,0x99,0xb3,0x3b,0xd6,0xeb,0x27,0xf9,0x34,0x68,0xc8,0x04,0x80,0xb2,0x4d,0xb6,0xde,0x98,0x81,0xe0,0xec,0xc9,0x06,0xde,0x86,0xee,0xf0,0x87,0xb8,0x67,0x0e,0xce,0xf8,0xc5,0xb1,0xd2,0xe1,0xe3,0x53,0x1d,0xbe,0x6c,0xdd,0x5e,0x83,0x02,0xf5,0xc8,0xda,0xcf,0x3c,0xcb,0x88,0x2c,0xca,0x65,0x65,0x9e,0x71 +.byte 0x4e,0xf2,0x98,0x96,0xb2,0x54,0xb4,0x96,0xdc,0x84,0xb5,0x39,0x74,0x9b,0x61,0xcf,0x52,0xef,0xb3,0x0c,0x62,0xc9,0x92,0xe1,0xe5,0x6f,0x2f,0x0c,0x61,0x0d,0x6f,0xfd,0xd8,0x84,0x25,0xba,0x20,0x59,0x00,0xf5,0xa9,0xf1,0x77,0x6e,0x9a,0x3d,0x93,0x69,0xde,0xaf,0x9a,0xe6,0xe3,0xfd,0xb9,0xd3,0x04,0x82,0x18,0xa1,0x5b,0x9b,0xe0,0x29 +.byte 0x4c,0x64,0xf5,0x95,0x57,0x25,0xd3,0x04,0x8b,0x4a,0xe9,0x57,0x6f,0xd1,0x8c,0x40,0x73,0x49,0x32,0x93,0x3f,0x26,0xb4,0x6b,0xd3,0xd4,0x90,0xb7,0xe1,0xaf,0xa0,0x9a,0xc0,0x86,0xb7,0x5e,0xec,0x29,0xaa,0x03,0x4e,0x56,0xb5,0xcd,0x46,0x7d,0xe0,0x26,0x3d,0x5f,0xd3,0x55,0x86,0x68,0x4a,0xc5,0x42,0x5d,0x60,0x3a,0x39,0x6f,0x45,0xb9 +.byte 0x6a,0xea,0xf4,0x05,0xc8,0x24,0xf8,0xcd,0xe5,0xeb,0xca,0x3a,0xe7,0xb4,0x59,0x83,0x5a,0xa5,0x1d,0xe4,0x6a,0xaa,0x35,0x00,0x42,0x32,0xa5,0x6c,0x3e,0xc1,0xc2,0xc4,0x9d,0x2e,0x43,0x57,0x79,0x52,0xf6,0x1e,0x02,0xb8,0x9b,0xcd,0xf0,0x3d,0x57,0xa3,0x6f,0xf7,0x12,0x54,0x6c,0x63,0x0d,0xb2,0xba,0xff,0xa1,0xf6,0xf5,0xdf,0xa5,0xed +.byte 0xda,0xdf,0x56,0x72,0x1e,0xc5,0x3f,0xad,0xd0,0xf9,0x38,0x94,0x51,0xe3,0xa4,0xb4,0xbf,0xd5,0x24,0x2a,0x90,0xfe,0xd4,0x34,0x6c,0xa8,0xc8,0x1c,0x9a,0xaf,0xac,0xff,0x5b,0x67,0x44,0x4c,0x4d,0xa7,0x59,0x2c,0x9f,0x67,0x07,0x25,0xe1,0x7f,0x4e,0x4a,0xaa,0x8f,0x5d,0xd1,0x26,0x0d,0x73,0x9b,0x69,0x5d,0xdf,0xb2,0xa5,0x89,0xbb,0x82 +.byte 0x0b,0x09,0xf3,0x11,0x76,0x5d,0x2d,0xad,0xc3,0xc1,0x15,0xbc,0xaf,0xa2,0xe6,0xd5,0xb0,0x6d,0x80,0xa6,0xda,0xfa,0x3b,0x9c,0xaf,0xff,0x98,0x40,0x83,0x3a,0xe1,0xb8,0x98,0x0e,0x97,0x00,0x89,0xfb,0x37,0xcb,0x81,0x36,0x34,0x33,0xbb,0x5c,0xd0,0x51,0x37,0xd6,0xb5,0x6c,0x3a,0x61,0x0a,0x27,0x23,0x96,0xa9,0x79,0x8d,0xf0,0xbe,0x31 +.byte 0xba,0xdc,0x89,0x4e,0x88,0x98,0xe4,0x10,0x15,0x8a,0xe1,0xae,0xe8,0x6d,0xa4,0x61,0x56,0x14,0x84,0x59,0x64,0xc2,0xaa,0xd8,0xfd,0x19,0xfc,0x17,0xf1,0xfc,0x6d,0x17,0xcb,0xea,0x7a,0x47,0x00,0x75,0x17,0xf3,0x62,0xfe,0x3a,0xbc,0x28,0x1a,0x0e,0x88,0x48,0x63,0x4a,0xcb,0x20,0x46,0xa4,0x75,0xf8,0xf1,0x7a,0xd6,0x92,0x7f,0x92,0xfa +.byte 0x91,0x95,0x2f,0xbc,0x5b,0x42,0xf1,0x55,0xaf,0x91,0xa2,0x3b,0x29,0x5c,0xc8,0x5e,0x97,0x91,0xa2,0x2e,0xd2,0xa8,0x1c,0xf6,0x16,0xc5,0x15,0xf2,0x42,0xb3,0x41,0x59,0x52,0x8d,0x94,0x52,0xc4,0xc6,0x2c,0xdd,0x6f,0x01,0xea,0x62,0x42,0x83,0x7e,0x2e,0xf8,0xb8,0xc1,0xf3,0x71,0xd1,0x11,0x14,0x7a,0x3d,0xcd,0xec,0xe0,0x79,0x8b,0xbd +.byte 0x28,0x12,0x60,0xf0,0x66,0xf1,0x1c,0x1c,0x19,0x07,0x8c,0x26,0xff,0xcc,0x72,0x9a,0xbd,0x12,0xe6,0x2b,0x2b,0xb1,0x32,0x04,0x98,0x92,0xd9,0x24,0x97,0x59,0x46,0xc6,0x11,0xe1,0x31,0x14,0x46,0x27,0x96,0xb1,0x06,0x81,0xd5,0xe8,0xff,0x45,0x3d,0x3c,0x04,0x9a,0xd8,0x0b,0x1f,0x41,0x03,0xba,0x1b,0x3e,0x4e,0xd5,0x7d,0x48,0x00,0x68 +.byte 0xb3,0xe8,0xe0,0xc8,0x3c,0xcf,0xdc,0xbe,0x29,0x90,0x64,0x51,0x18,0xdc,0xcd,0x87,0xcb,0xa8,0x3d,0xf8,0xb4,0x73,0x11,0xdc,0x7a,0xcb,0xa4,0x81,0x9e,0x3a,0x72,0xde,0x18,0x36,0x86,0x15,0x91,0xbc,0xeb,0x7f,0xe2,0xfb,0x6b,0xf1,0x5a,0x3d,0x05,0x50,0xeb,0xcf,0xd2,0xcc,0xf2,0x62,0xb1,0x32,0x46,0x14,0x95,0x4e,0xdf,0x73,0x64,0x61 +.byte 0x5f,0x3d,0xbf,0x52,0x3e,0xa7,0x55,0x01,0x9a,0xd8,0x01,0xef,0xf7,0x60,0x6f,0x83,0x43,0x6b,0x4c,0xa2,0xc8,0x04,0x34,0x70,0x70,0xa1,0x99,0xc9,0xa7,0x54,0x1e,0x87,0x99,0xb3,0xec,0xfe,0xe9,0x2d,0x39,0xef,0x6f,0x4d,0x8c,0xf2,0x4b,0xd2,0x12,0x5d,0xb6,0xa7,0x0b,0x04,0x3b,0x69,0xdd,0x9a,0x18,0x2d,0xd9,0x22,0x00,0x38,0x15,0x9a +.byte 0x6e,0x6c,0x0c,0x84,0x32,0x32,0xb2,0xf9,0x61,0xef,0x74,0x35,0xec,0xcc,0xd7,0xbc,0x9d,0xe9,0xcd,0xe3,0xa0,0xa5,0x15,0x0a,0xfe,0x1f,0x37,0x35,0x2b,0x7c,0x42,0x50,0x81,0x67,0x52,0xb7,0xa7,0x9e,0x8f,0xda,0x64,0xc0,0xc0,0xc3,0x93,0xc7,0x9d,0x41,0xb8,0x4b,0x69,0x80,0x13,0x88,0x8a,0x07,0xf9,0x47,0xad,0xc9,0x4f,0x3d,0xc7,0xba +.byte 0xd2,0xf2,0x7a,0xa0,0x38,0xbe,0xe1,0xfa,0x83,0xda,0x79,0x29,0x7f,0x4c,0xfa,0x0e,0x9b,0x59,0x1e,0x89,0x76,0x05,0x60,0x84,0x13,0x63,0x11,0x14,0x20,0xa9,0x2b,0xd0,0xc3,0x58,0xcc,0x73,0x3e,0x2c,0xa8,0xa7,0xa5,0xd0,0x2f,0x03,0xfc,0xa9,0x5d,0xdd,0xcd,0x40,0x91,0x90,0x1f,0xda,0x0a,0x73,0x58,0xd8,0x84,0x05,0x45,0x01,0x84,0x52 +.byte 0x8b,0x9b,0x17,0x98,0xa8,0xc4,0xc3,0xb5,0x94,0xd5,0x32,0x86,0xe9,0x10,0xe5,0xa5,0x99,0x8d,0x57,0x3e,0x32,0x25,0xfa,0xb4,0x5c,0x3a,0x5f,0xa6,0x2d,0x7d,0x4e,0xd3,0x7b,0xee,0x41,0x23,0x5e,0xc2,0xc9,0x91,0xf4,0x21,0xe0,0x4f,0x0d,0x87,0x30,0x53,0xf1,0x0e,0x63,0xe8,0x5b,0x3d,0xee,0x4a,0xc8,0x78,0x38,0xa2,0xa4,0xe8,0x72,0x41 +.byte 0xf1,0x37,0x30,0xe3,0x3d,0x93,0xc6,0x4b,0x10,0x0d,0xf6,0x20,0x15,0x0a,0x77,0x41,0xd5,0x7d,0xcb,0xf9,0xda,0x3b,0x17,0xa6,0xf1,0xe4,0x56,0xd4,0x65,0x7b,0x33,0xe4,0xef,0x34,0xfb,0x8c,0x9f,0x87,0x86,0xfc,0xce,0x90,0x60,0x77,0x57,0xc0,0xe4,0x37,0x2c,0xdf,0x41,0x95,0x85,0x89,0x4e,0x77,0x3f,0xa0,0xc7,0x55,0x4c,0x3f,0xa8,0x10 +.byte 0xd2,0x87,0x7e,0xd2,0x97,0xa1,0x6c,0xe7,0xec,0xaa,0xf6,0x93,0x13,0x2e,0x10,0xed,0x5b,0x7a,0xed,0x53,0xb4,0x55,0xaa,0xb4,0x67,0x78,0x07,0x5f,0xc2,0xd2,0xf1,0x7b,0x98,0xf0,0x82,0xf6,0x7c,0xb2,0xd4,0xa8,0xc2,0x53,0x39,0x21,0x7f,0xa0,0x76,0x37,0x1a,0x69,0xb3,0x49,0xd4,0xc3,0xd1,0xcb,0x31,0x76,0xec,0xaf,0x75,0x66,0x31,0x65 +.byte 0xeb,0x44,0x63,0xa0,0x13,0xf5,0x9e,0x67,0x40,0x41,0x76,0xce,0xd3,0xd6,0x91,0xb1,0x3a,0x07,0xff,0x38,0x1e,0xaf,0x55,0x57,0x55,0xd1,0x94,0x63,0xd3,0x81,0x16,0x59,0x68,0x01,0xe8,0x6d,0x7d,0x7a,0xa1,0x39,0xb9,0xa2,0xba,0x79,0x9d,0x69,0x00,0x13,0x59,0x2f,0x3d,0xef,0x10,0xe7,0x3c,0x02,0x7d,0xa3,0xa8,0xee,0x31,0x1a,0xad,0xa6 +.byte 0xdb,0x1b,0xe3,0x4a,0xdd,0x60,0xfb,0x4e,0xa6,0x49,0xbb,0xea,0x34,0x5d,0x21,0xac,0x83,0xa4,0xb5,0x23,0x8e,0x69,0xb3,0x25,0x14,0x8d,0xc2,0x89,0x8d,0xcf,0x38,0x46,0x18,0xb6,0x0c,0xce,0x45,0x22,0xeb,0xb5,0xb2,0xed,0xe5,0x0f,0x35,0x8f,0xdd,0xa1,0x15,0xd6,0x50,0x5b,0xe1,0x04,0xa7,0x32,0xc0,0xc9,0x03,0x56,0xc2,0x33,0xe8,0x16 +.byte 0x1c,0xd4,0x7a,0xfd,0x6b,0x4d,0x04,0xc0,0x9e,0xf8,0x32,0x9f,0x52,0x24,0xac,0xc5,0xb0,0xa1,0x63,0x77,0xc9,0x14,0xaf,0x46,0x60,0x67,0x52,0x81,0xbb,0x3f,0xf5,0x7f,0xad,0xef,0x7c,0x3a,0x71,0xc1,0x1e,0xea,0x4a,0xe0,0xd7,0xdd,0x31,0xf2,0x4b,0xdf,0x53,0x8a,0xc9,0x59,0x7a,0xb2,0x6f,0x7e,0xc0,0x00,0xa4,0x0d,0x09,0x9c,0xf7,0x22 +.byte 0x22,0xa9,0x37,0xde,0x3b,0xe1,0x74,0x85,0xcf,0xc5,0xb7,0x7b,0x0a,0xfd,0x6b,0xfa,0x98,0x49,0xa9,0x7f,0x52,0x23,0x0e,0xc0,0x4a,0xb3,0x81,0xa6,0x96,0x46,0x24,0xe7,0x01,0xd1,0xf2,0xac,0x31,0xb2,0x5e,0x61,0xe3,0xab,0xf8,0x1b,0x28,0xca,0xa2,0x78,0x3c,0xdf,0x8a,0xc1,0x17,0x46,0x9d,0xbd,0x69,0x31,0x41,0x8b,0xc1,0xc8,0xaa,0x68 +.byte 0xd5,0x35,0x65,0x49,0xfe,0xc6,0xa4,0x99,0xcc,0x62,0x4b,0x81,0x1c,0x21,0xa4,0xd8,0xe3,0xb3,0xe9,0x7c,0xf8,0x33,0x2f,0x21,0xa5,0x88,0xf2,0x8e,0x7d,0xee,0x00,0x00,0x62,0xcf,0x07,0x37,0x00,0x68,0x6c,0xb5,0x2d,0xc6,0x1b,0xcc,0x86,0x71,0xf0,0x4f,0x68,0xaf,0x0c,0x9a,0x25,0x69,0x71,0x2d,0xb5,0x87,0x90,0x02,0xd3,0xfc,0xbb,0x63 +.byte 0xa9,0xf1,0x13,0x4f,0xda,0x71,0x69,0x5c,0x0b,0xfd,0x3f,0x6c,0x2f,0x0b,0x4f,0x07,0x72,0x2d,0x2f,0x77,0xcb,0xa4,0xe4,0xbd,0x30,0xc7,0xe4,0xd9,0xf9,0x5d,0x2f,0x65,0xe4,0x41,0x5c,0xbc,0x03,0xa2,0x01,0xf9,0xfa,0x06,0x14,0x52,0x08,0x44,0x67,0x75,0x4e,0xbd,0x66,0x4a,0x26,0x3a,0x49,0xc4,0xba,0x02,0xb3,0x8e,0xa2,0x42,0xe7,0x92 +.byte 0x03,0x6d,0x61,0x10,0x73,0xd0,0x6f,0xe1,0x6e,0x67,0xff,0xb0,0x29,0x62,0x70,0x3c,0xeb,0x80,0xed,0x11,0x06,0xd6,0x18,0x60,0xe1,0x3d,0x21,0xa9,0xe9,0xd2,0x92,0x00,0x9e,0x13,0xf2,0x5d,0x38,0x71,0xdf,0xf3,0x5f,0x8a,0x90,0x45,0xf0,0x47,0x1f,0x0b,0x2d,0x12,0xf7,0x10,0x07,0x6a,0x52,0xe8,0xe2,0x26,0x9b,0x4b,0x7a,0x5f,0x97,0xb6 +.byte 0xf1,0x6d,0x47,0x3a,0x1e,0xc8,0x1d,0x78,0x5b,0x0a,0xb8,0x03,0xb1,0xe1,0xe7,0xc8,0xf0,0xe7,0x00,0xac,0xfc,0xd7,0x4a,0xde,0xaa,0xcd,0x0f,0xaf,0xf7,0x56,0x8e,0xed,0xfb,0xbe,0x7e,0xfe,0x62,0x75,0x7a,0x07,0x96,0xff,0xc3,0x21,0x35,0x71,0xb9,0x73,0x41,0xc2,0xb0,0xa8,0x6a,0x65,0x48,0xc4,0x50,0x31,0xe2,0xba,0xf4,0xe9,0x6c,0x03 +.byte 0x26,0x2c,0x77,0xfe,0x1a,0xd5,0x96,0xf6,0x6d,0xe4,0x14,0xfc,0xe2,0x1d,0x20,0x0c,0x14,0xa2,0x39,0x63,0xe5,0x16,0xef,0x6a,0xeb,0xe1,0x69,0xb8,0x67,0xa0,0x91,0xc1,0x8f,0xed,0xff,0xdf,0x26,0x1f,0xc3,0xb7,0x5d,0xe9,0xd2,0x72,0xe2,0x54,0x27,0x46,0x4f,0x33,0x25,0x59,0xaf,0xfa,0x87,0x4b,0x5a,0xda,0x7d,0x15,0x71,0x5d,0xb4,0x8d +.byte 0x95,0xb6,0x09,0x5b,0x8b,0xeb,0xe6,0xba,0xc8,0x2f,0x8f,0x9e,0xa8,0xab,0x6a,0xa6,0x26,0xb6,0xf5,0x80,0xd0,0x7d,0xe7,0x4c,0x18,0x5a,0x72,0x8f,0x3e,0x90,0xe5,0xa1,0x16,0x33,0x66,0xc3,0x7b,0xf6,0xb6,0xdd,0x15,0x94,0x6d,0xca,0x8b,0xd7,0xa5,0x05,0xfb,0x5f,0x4e,0x94,0x6a,0xcc,0x54,0xed,0xeb,0xc0,0xb1,0xe1,0xc9,0x7f,0xc4,0x90 +.byte 0x2f,0x50,0x34,0x81,0x3c,0x83,0x47,0x3c,0x5a,0xb2,0x33,0x63,0xb6,0xa7,0xfb,0x59,0x70,0x87,0xea,0x7f,0x30,0x22,0xb4,0x54,0x48,0xfb,0x40,0xd2,0x7b,0xc9,0x49,0x80,0x18,0x27,0xc2,0x75,0x09,0x06,0x0a,0x83,0x1e,0x7a,0xf1,0x97,0xa1,0xc2,0x34,0x3f,0x6d,0xd6,0x2d,0xfe,0x5d,0x8b,0xfd,0x64,0x5d,0x6f,0x7f,0xbf,0x4e,0x01,0xb7,0x46 +.byte 0xfb,0xf7,0xd5,0x6f,0x5f,0x74,0xc8,0xca,0x9a,0x2e,0x74,0x08,0xe9,0x3d,0x8b,0xfd,0x97,0x38,0x72,0x67,0xbb,0x8a,0x34,0xee,0xf5,0x3a,0x2b,0x5e,0x64,0x64,0x06,0x7c,0x60,0x0f,0x7a,0x88,0x45,0x1b,0x69,0x90,0xb8,0xb0,0x4d,0x71,0x80,0x77,0xa8,0xaa,0x9f,0xd3,0xc6,0xfb,0xb8,0x12,0x1e,0x0c,0xf4,0x94,0x67,0x44,0xdc,0xb1,0x95,0x0e +.byte 0x51,0xd1,0x06,0x69,0x92,0xbf,0xe6,0x67,0xe3,0xcd,0x0b,0x87,0x03,0x12,0x2e,0xa7,0x23,0x72,0x13,0xe9,0x89,0xcf,0x15,0x43,0xc0,0xa7,0x68,0xbd,0xce,0xec,0x28,0xb6,0x85,0x36,0xbe,0x52,0x5d,0x57,0xfa,0x7d,0x72,0xd1,0x4b,0x88,0xc9,0x64,0xbc,0x7a,0x18,0xe5,0x0e,0xab,0x19,0x81,0xee,0x11,0xbe,0xe0,0x68,0x44,0x81,0x49,0x3f,0xd8 +.byte 0x12,0xd1,0x8b,0xc1,0xe0,0x51,0xf7,0xc3,0x64,0xa7,0xc5,0x61,0x9b,0x32,0x6d,0xf0,0x6c,0xa6,0xaf,0xf9,0x4a,0xdf,0x94,0xaf,0xc8,0xf2,0x86,0xb1,0x4e,0x2e,0xa9,0xb4,0x35,0x82,0x15,0x8a,0x58,0xf3,0x03,0x2f,0x78,0x07,0x8f,0xb9,0x16,0x7c,0x42,0xfa,0x36,0xaa,0xa5,0x66,0x62,0x44,0xca,0xa6,0x55,0x95,0x27,0xdb,0x48,0xea,0x0a,0x1d +.byte 0x5a,0xae,0x5c,0xad,0x99,0xfe,0x00,0xf1,0xb9,0x94,0xda,0x09,0x48,0x52,0x9d,0xfc,0xb4,0xb2,0x80,0x19,0x16,0xf8,0xcd,0x68,0x10,0xec,0x1c,0x16,0x3f,0xbb,0x42,0xb4,0x10,0xe3,0xdb,0xaa,0xe4,0x3f,0x2e,0x8e,0xb5,0xce,0xba,0x8f,0xf2,0xb5,0x76,0x98,0x15,0xa7,0x77,0x4b,0x1c,0x30,0xb7,0x6f,0xc9,0xa9,0xa4,0x64,0x59,0xab,0x3a,0x43 +.byte 0x74,0x33,0xab,0xe1,0x3e,0x5e,0x79,0x1c,0xa5,0xb4,0x87,0xe1,0xcb,0xea,0x0e,0x02,0x4b,0x01,0x84,0xbc,0xdc,0x75,0xf4,0x2c,0x2b,0x8d,0xc8,0x5f,0xb5,0xba,0x6b,0xb2,0x4a,0x7c,0xe7,0xaa,0x61,0xa5,0x0c,0xf8,0x02,0x73,0xec,0x11,0x13,0x6b,0x31,0x07,0xaa,0x79,0x78,0x86,0x01,0x77,0x5e,0xa3,0x09,0xd1,0xec,0xaf,0x7d,0xb7,0x65,0xa9 +.byte 0xd8,0x99,0xd2,0xd7,0x6d,0x32,0x97,0x0f,0x0e,0x51,0x0d,0x69,0x81,0x7a,0x94,0x48,0x31,0xe1,0xff,0x26,0x4d,0x30,0x49,0x93,0xfb,0x6e,0xdb,0xea,0xaf,0xcb,0xb4,0xa9,0xc9,0x9f,0xeb,0xca,0x52,0x36,0x26,0xac,0x47,0xda,0x02,0x3d,0xd0,0x93,0x8b,0x61,0x78,0x26,0x54,0x32,0xe8,0x14,0xac,0xf3,0xd2,0x46,0x04,0x12,0x89,0x9f,0xf6,0x11 +.byte 0xf5,0x64,0x83,0x66,0x00,0x50,0x55,0x05,0xb5,0xf6,0x58,0x9f,0xbf,0x4b,0x95,0xf1,0x7f,0x0b,0xb4,0xf7,0x63,0xea,0x6f,0xf7,0xb0,0x20,0x53,0xfe,0x95,0xbc,0xc4,0xe2,0xff,0x75,0xbd,0xab,0x73,0x68,0x44,0x18,0xf7,0x6b,0x04,0x46,0xde,0x6c,0x65,0xb2,0x22,0x4e,0x25,0x8e,0xba,0x7c,0x3a,0x6f,0x80,0x99,0xb4,0xe7,0xf9,0x97,0x68,0x40 +.byte 0xa9,0x96,0xfc,0x6b,0xcf,0x08,0x75,0xe4,0xda,0x6f,0xaf,0x71,0x4f,0x31,0x62,0x31,0x18,0xbf,0xb9,0xa0,0xcc,0x9e,0xa7,0xa2,0x27,0x2a,0xb8,0x6b,0xc0,0x93,0xf5,0x1f,0x41,0x25,0xa7,0x4d,0x9f,0xb4,0x12,0x5c,0x27,0x38,0x5d,0x80,0x88,0xa3,0xb8,0xb2,0xc3,0xd2,0xfb,0x1d,0xba,0x7b,0xac,0x51,0x0b,0x71,0x58,0x3f,0xe5,0xfa,0x36,0xb8 +.byte 0xc7,0x90,0x46,0xd0,0x5a,0x94,0xf0,0x7d,0x6e,0x6c,0x4c,0xb1,0xfa,0xdb,0x97,0x1e,0x19,0xf2,0x1f,0x4e,0x05,0x25,0x0e,0xbd,0x47,0x94,0x2a,0xd3,0x1a,0xbe,0x4a,0x04,0xaa,0x57,0x02,0xc9,0x42,0xc1,0x74,0xcd,0xe1,0x78,0x8b,0xff,0xc1,0xc6,0x17,0x4e,0x71,0xc4,0x2c,0x00,0x23,0x56,0x57,0x1f,0x47,0xd8,0x93,0x80,0xc1,0xc5,0x7b,0xd9 +.byte 0x25,0x30,0xac,0x72,0x37,0x00,0xd2,0xbc,0xc7,0x33,0x73,0xf9,0x14,0x86,0x7c,0xb0,0x28,0x14,0x5d,0xbf,0xbd,0x98,0x1c,0x00,0x05,0x19,0x2b,0x0a,0x55,0xad,0xb4,0x06,0x28,0x58,0x03,0xa1,0xe6,0x27,0xa3,0x32,0x5f,0x41,0xd5,0x6a,0x0b,0xbc,0x0f,0xaa,0xf5,0xc1,0xa7,0x09,0x2f,0x86,0xda,0x56,0xb0,0x04,0x49,0xd4,0x20,0xc6,0xa2,0x6c +.byte 0x27,0x56,0x4e,0xcd,0x22,0x46,0xac,0x0f,0xd3,0x99,0x69,0x83,0xc4,0xae,0x9f,0x88,0xed,0x9c,0xba,0xfb,0xf3,0x66,0xc7,0x3d,0x65,0x55,0xd0,0xe3,0x04,0x03,0x6a,0x02,0x5c,0xbf,0x9f,0x23,0x34,0x79,0xe1,0xbe,0x7d,0xad,0xb4,0xc7,0x9e,0x4d,0x80,0x73,0x6d,0xe5,0x37,0x03,0xac,0xa3,0xf4,0x93,0xad,0x1e,0xf3,0xcd,0xb8,0xe2,0xeb,0x30 +.byte 0xc7,0x50,0xfe,0x0a,0x63,0x5e,0x0f,0xc9,0xd0,0x06,0x58,0xc1,0x6e,0x65,0x54,0x54,0x5d,0xaf,0xf1,0xe8,0x3e,0x95,0xe3,0x70,0x40,0x8e,0xb8,0x4d,0x76,0xda,0xa8,0xe8,0x9e,0x88,0xd8,0xaf,0x67,0x83,0x3b,0x77,0x65,0x58,0x00,0xbb,0xf7,0xe9,0x52,0xf0,0xba,0x0d,0x0a,0x59,0x28,0xe4,0xa7,0xfb,0x06,0xe5,0x34,0xbe,0xcf,0x10,0x7c,0x73 +.byte 0xa8,0xf3,0xa2,0x93,0x96,0x9e,0x4f,0x9b,0x3c,0xd1,0x9f,0x64,0x5b,0x8c,0xc1,0x89,0x66,0x67,0x13,0x52,0xb2,0xaa,0x6b,0x8e,0xea,0x97,0x27,0x20,0x2e,0x64,0xec,0xf0,0x72,0xc9,0x54,0x8a,0xed,0x78,0x3a,0xd7,0x4f,0xc2,0xba,0xc3,0xb8,0x64,0x7f,0xe4,0x5f,0x3d,0xf7,0xe5,0xd9,0xf1,0x8d,0xb1,0xd2,0xf6,0xcc,0x34,0xd8,0x7d,0x16,0xca +.byte 0x47,0xaf,0x85,0xe5,0x4a,0x57,0xb9,0x5a,0x9e,0xff,0xb8,0x83,0xec,0x7c,0xb8,0x07,0xf5,0xd3,0x31,0x31,0x2b,0xf0,0x40,0x46,0xc3,0x63,0x27,0xe4,0xb0,0x3b,0x84,0x0d,0x50,0x05,0x80,0x0c,0xfa,0x8b,0x0e,0x33,0x6b,0x10,0xd4,0xf5,0x4f,0x8b,0x2d,0x9e,0xc5,0x01,0x92,0x52,0x62,0x1a,0x89,0x1e,0xca,0x48,0xc3,0xd6,0xfa,0xd2,0x94,0x7c +.byte 0x77,0x6e,0xa7,0xeb,0xd7,0x4f,0xe8,0xc8,0xc2,0x71,0xb2,0x9e,0x86,0x30,0x18,0xfd,0x4c,0x56,0x4c,0xd0,0xa4,0x84,0x37,0x02,0x02,0x6a,0x8d,0x57,0x6b,0xc2,0x06,0xd1,0x8a,0xdb,0xa0,0xcc,0x31,0xf9,0xcf,0xbf,0xf2,0x29,0x7c,0x26,0xac,0x1f,0x03,0x20,0x26,0x76,0x03,0x6f,0xa5,0xb5,0x33,0xfb,0x02,0xe8,0xf6,0xe9,0x5e,0xb1,0x36,0x7c +.byte 0x96,0x56,0xb1,0x98,0x2d,0x9c,0x38,0x9b,0xd4,0x56,0x28,0xcc,0xdb,0x08,0xd3,0x42,0x00,0x35,0x24,0xd9,0x74,0xa2,0x0d,0x55,0x21,0x06,0xb7,0xf9,0x6a,0xa0,0x81,0xc1,0x2d,0xb6,0x67,0x91,0x92,0x24,0x36,0xfd,0x2e,0xd8,0xc0,0xcb,0xc8,0x87,0x1a,0x41,0x11,0x70,0xbf,0xd2,0xe7,0x82,0x10,0x74,0xdf,0x65,0x46,0x19,0x6b,0xb4,0x89,0xeb +.byte 0x9e,0xcf,0x79,0x35,0xba,0x25,0x75,0x32,0x64,0x6a,0xfb,0xaf,0xe5,0xed,0x85,0x98,0x34,0x75,0x31,0x40,0xbb,0xd8,0xe3,0xf5,0xa7,0xa2,0x9a,0x9e,0xcd,0xc4,0xf8,0xd8,0x15,0x6c,0x64,0x0c,0x6c,0x16,0x60,0xe9,0x40,0xf4,0x7a,0x14,0x37,0x7b,0x45,0x9b,0x0e,0x29,0x7a,0x1a,0x88,0x10,0xb9,0x2b,0xee,0x13,0xbd,0x8a,0xde,0x7a,0xe9,0x30 +.byte 0xe8,0x39,0x77,0x74,0xf5,0x2f,0xe3,0x10,0x19,0x89,0x28,0x21,0x3a,0x68,0x38,0xb4,0x4d,0x20,0x8d,0x7d,0xec,0x3f,0xf7,0x61,0xbf,0x53,0x32,0x3b,0xb8,0x6a,0xc9,0x58,0xeb,0xd4,0x33,0x0e,0xee,0xc7,0xb9,0x5e,0x3d,0x17,0x7e,0x36,0xa2,0xa6,0x94,0xb1,0x56,0xb6,0x8e,0x94,0x05,0x50,0x69,0x52,0x4f,0x31,0xe5,0x97,0x18,0xde,0x8f,0xb7 +.byte 0xff,0x2e,0x6f,0x1b,0x6a,0xda,0xfd,0xa1,0xd1,0x9a,0x4e,0x6a,0x1b,0x46,0x71,0x52,0x76,0x66,0xf9,0x70,0x8d,0x7d,0x97,0xb0,0xc3,0x8d,0xbc,0x35,0x26,0xe8,0x0b,0x80,0xc7,0x58,0x19,0x22,0x70,0x33,0x06,0xeb,0xcf,0x26,0x22,0xe0,0x97,0x91,0xbf,0xd6,0x94,0x05,0xe1,0x84,0xe2,0x31,0x66,0x57,0xc7,0x1e,0x36,0x30,0x50,0xaf,0x72,0xb3 +.byte 0x31,0xad,0x84,0xcc,0xb5,0x76,0x03,0xe1,0x56,0x97,0x87,0x36,0xf5,0xaa,0x97,0x99,0x38,0xa5,0xf5,0xb7,0x42,0x86,0x3b,0x2f,0x8a,0xb9,0x8e,0x6a,0x0b,0xe0,0xca,0xbc,0x4c,0x6c,0xc1,0x3f,0xbe,0x45,0xef,0xd2,0x57,0xcd,0x29,0xfb,0xfb,0xa5,0x79,0xf2,0xb1,0xbb,0x4b,0x55,0x26,0x2f,0x5c,0x84,0x5e,0x6a,0xc6,0xa9,0xd5,0x23,0xe4,0xd1 +.byte 0xe5,0xf0,0xbc,0x50,0x6a,0x2a,0xaf,0xa2,0x7c,0xcc,0x36,0x95,0xf9,0x5c,0x04,0x6d,0x04,0x31,0xbe,0x1d,0xb2,0x50,0x97,0x8f,0xdf,0x8a,0xed,0x4e,0x4e,0x0a,0x0b,0xfc,0xfc,0x1d,0xa9,0x6a,0x76,0x6a,0x33,0xd7,0x0a,0xcf,0xd5,0xdd,0xc6,0x62,0xe5,0x59,0x02,0xba,0x9c,0x43,0x32,0x8a,0x0e,0x47,0x91,0x00,0x07,0x47,0x93,0xc4,0xad,0x29 +.byte 0x33,0x57,0x15,0x45,0x44,0xb9,0xf3,0xc4,0xe6,0xd2,0xb9,0x3a,0x44,0x16,0x32,0x8d,0x57,0x78,0xac,0xf5,0xdb,0xa2,0x93,0x97,0x64,0x08,0x9b,0x66,0x4b,0xa0,0x64,0xab,0xa0,0xd6,0x0e,0x2c,0xa1,0x25,0x16,0x5c,0x6f,0x82,0xff,0x8e,0x89,0xfb,0xca,0x03,0xa6,0xf8,0xa1,0xf6,0x87,0x02,0x5c,0x90,0xcb,0x33,0xa0,0xc0,0x90,0xc2,0x1f,0xdd +.byte 0x5c,0x50,0x93,0xf2,0x8b,0x87,0xa1,0x73,0xda,0x5f,0xa3,0x20,0xd4,0xe7,0x45,0xd7,0xea,0x4b,0x5d,0xd6,0x80,0xfc,0x2d,0xdc,0x45,0x6a,0xf6,0xaf,0xd4,0x7a,0x91,0x64,0x15,0x17,0xbf,0xc7,0x58,0x54,0x7c,0x08,0x42,0x4f,0x8d,0xab,0x9b,0xd0,0x1d,0x57,0x71,0x50,0xa7,0xe3,0xb4,0xf2,0x14,0x0c,0xd7,0x2f,0x7c,0x8b,0x17,0x61,0x98,0xfa +.byte 0x19,0x34,0xb9,0x65,0xc5,0x5c,0xfe,0xa3,0x80,0x6f,0x99,0xec,0xfa,0x06,0x22,0x71,0xa9,0x10,0x2a,0xcf,0x12,0xb3,0x17,0xe5,0x59,0x3a,0xaa,0xcb,0x55,0x5f,0x45,0x9d,0xe9,0x29,0x56,0x34,0x11,0x62,0x6e,0x0a,0x95,0x12,0x5d,0xd4,0xa2,0x28,0x05,0xf1,0x0f,0x2d,0xa0,0x1e,0xe1,0x2b,0x42,0x6c,0xf0,0xe6,0x47,0xe0,0xb2,0xbd,0x89,0x20 +.byte 0x5e,0x24,0x05,0xec,0xf1,0x33,0xfc,0xa9,0x2f,0xef,0x3a,0x1f,0xfe,0x39,0xfe,0x01,0x09,0x0a,0x2a,0xe0,0x96,0x1e,0xde,0xad,0x96,0xaa,0x48,0xeb,0x8a,0xe6,0x54,0xbb,0x5d,0x7a,0xbe,0x4a,0xbf,0x96,0xf6,0x15,0x7a,0x70,0x6f,0xee,0xe7,0xf5,0x53,0xaf,0xe1,0xbb,0xaf,0x58,0x51,0xd4,0xa0,0xc6,0x44,0x03,0x47,0x33,0xce,0x58,0x62,0xd3 +.byte 0x93,0x21,0xa5,0xa5,0xb4,0xef,0x1d,0x93,0xcc,0x8c,0xf7,0x14,0xe3,0xec,0x40,0x52,0x47,0xe6,0xbc,0xe6,0x85,0x69,0xd0,0x15,0xad,0x24,0x21,0x4f,0x26,0x01,0x60,0x0f,0x0f,0xcb,0x7e,0x14,0x01,0xe1,0x90,0x11,0x06,0x17,0x38,0x2d,0xd8,0x26,0xe2,0x7c,0xd6,0xef,0xe0,0x59,0xf0,0x8c,0x2a,0xbd,0xba,0xe5,0x8b,0x07,0x56,0xd3,0x35,0xb3 +.byte 0x64,0x83,0x9e,0xb9,0xb9,0xeb,0x88,0x03,0xff,0x14,0xf3,0x8b,0x14,0xd3,0xa4,0xac,0x08,0xd9,0x75,0xf6,0x2c,0x9d,0x7f,0xc8,0x9d,0x11,0x3b,0xd1,0x71,0x14,0x4b,0x2a,0x6d,0x20,0x83,0x32,0x35,0x7e,0x1f,0x20,0xa6,0x69,0xbf,0xcf,0x22,0xd9,0xa2,0x57,0x4b,0x66,0xb1,0x9f,0x5a,0xa8,0xaa,0xb8,0x11,0x1d,0x45,0x28,0xac,0x86,0x09,0x37 +.byte 0xe9,0x1f,0xef,0xb4,0xe0,0x6f,0x75,0xad,0xe5,0xd8,0x25,0x06,0x19,0xb4,0xa8,0x07,0x78,0x79,0x43,0x63,0x40,0x26,0xbd,0x28,0x50,0x2d,0x29,0x26,0xf9,0xfc,0x5c,0x71,0x8f,0xfd,0x62,0x12,0x7c,0xd0,0x67,0xb3,0x65,0xef,0x31,0xc0,0x99,0xc1,0x54,0xfc,0x32,0x6e,0x25,0x56,0x77,0x6e,0xc1,0x6b,0x11,0x50,0x7c,0xa1,0x0b,0x97,0x8a,0xfe +.byte 0x0f,0x5b,0x16,0x93,0x83,0xe0,0xd8,0xb7,0xbf,0xa8,0x90,0x6d,0xd6,0x8b,0x4b,0xd9,0x17,0xbb,0xe8,0xd9,0xbb,0x5f,0x39,0x4a,0x33,0x7c,0xb3,0x12,0x99,0x1e,0xfc,0xb2,0x05,0x91,0x67,0xdf,0x8d,0x0b,0x55,0xfb,0xd1,0x8d,0x0c,0x9b,0x80,0x81,0xee,0x8c,0x05,0xe2,0x16,0x30,0xad,0x1f,0x88,0x04,0x75,0xc1,0xe5,0xec,0x32,0xf8,0xa0,0x5b +.byte 0x21,0xf6,0xd8,0x13,0x26,0xe4,0xa1,0x32,0xa8,0x93,0x91,0x5d,0x33,0x45,0x83,0x72,0x52,0x59,0x23,0x84,0xf6,0x7b,0xe2,0x90,0x20,0xc6,0x40,0x33,0xa9,0x94,0xcd,0xb9,0xab,0xe4,0x44,0x0b,0x06,0xbb,0x4c,0x2c,0x2a,0x5e,0x4d,0x57,0xb7,0xe0,0xb8,0x86,0x74,0xab,0xea,0x37,0x1c,0xa0,0xa6,0x21,0x33,0xc7,0xf5,0x24,0x7d,0x14,0xc8,0x8b +.byte 0x9d,0x8f,0x31,0x23,0x29,0x9d,0x11,0x42,0x07,0xe8,0x2c,0xec,0x7d,0x70,0x8d,0xb5,0xa4,0xca,0x33,0x30,0x03,0x75,0x17,0xa1,0x10,0xe7,0x6b,0x87,0xf9,0x0b,0xef,0x43,0xef,0xf8,0x24,0xc2,0xf1,0x7a,0x1a,0x70,0x7e,0x2f,0xd4,0xeb,0x97,0x40,0xa6,0xe6,0x2d,0xc1,0xd8,0x3b,0xee,0xa4,0xda,0xd3,0x50,0x41,0x18,0xbf,0xad,0x66,0x02,0x85 +.byte 0x60,0x14,0xcf,0xce,0x50,0x88,0x5e,0xb6,0x73,0x11,0xbb,0x6a,0xca,0xb1,0x46,0x8e,0xbb,0x58,0x2c,0x63,0x61,0x20,0xec,0xc9,0x98,0x0c,0xdb,0x5c,0xe5,0x47,0xb5,0x89,0xe9,0x14,0xc8,0xbc,0x35,0xf2,0xa7,0x2d,0x84,0xcc,0x61,0xc8,0xb6,0x9d,0xeb,0xcb,0x8b,0x73,0x90,0x6d,0x06,0xc9,0x42,0xcf,0xd2,0x15,0x80,0x2d,0x39,0xeb,0x71,0x83 +.byte 0x27,0x0d,0x85,0xf9,0xa3,0xce,0xef,0x29,0x3b,0x10,0xb7,0xe9,0xd0,0x86,0x6e,0x88,0x1e,0x3b,0xdd,0xaf,0x52,0xde,0xa2,0xa4,0x13,0x3c,0x1f,0xcb,0x84,0x74,0x12,0x04,0x91,0x40,0xb8,0x1b,0x15,0xfd,0xdb,0xe8,0x74,0xcc,0x4d,0x41,0xb5,0x5a,0x92,0xd3,0x71,0xf7,0x57,0xa5,0xf7,0x18,0x5a,0x57,0x36,0xde,0x8f,0xb2,0x81,0x59,0xc8,0x5c +.byte 0x22,0xcf,0xdc,0x7d,0xff,0x83,0xf2,0xad,0x8c,0x7b,0xd5,0x04,0xc4,0xb9,0x79,0x4a,0x12,0xa7,0xb1,0x7e,0x57,0xa5,0x6b,0x56,0x8a,0x11,0x96,0x57,0xde,0x35,0xdd,0xef,0x9b,0x03,0x41,0xde,0x61,0x5b,0x73,0x8c,0x6a,0x0c,0x6f,0xae,0x45,0x4b,0x56,0x4d,0xbe,0x8a,0x3f,0xdb,0x79,0x58,0x88,0xad,0xcb,0xfa,0x66,0x06,0x0e,0x74,0x21,0x1d +.byte 0xe1,0x94,0xd7,0x06,0xea,0x60,0xe2,0x7d,0x70,0xcf,0xa9,0x4f,0xe6,0x9b,0xba,0x19,0x71,0x69,0x94,0x66,0x5a,0xb8,0x49,0x0c,0xd1,0x9a,0xc4,0x5f,0xa7,0xf4,0x9e,0x3d,0x9e,0xc2,0xd8,0x0e,0xd2,0x6d,0xc6,0xc8,0x99,0xc3,0x5e,0x3b,0xb9,0xd8,0x48,0xc0,0x38,0x48,0x95,0x89,0xff,0x7e,0x1d,0x80,0x53,0xac,0x7b,0xd7,0xfc,0x6f,0x5d,0x25 +.byte 0x2f,0xcf,0x15,0xdb,0x1a,0x64,0xc1,0x16,0x91,0x65,0x84,0x99,0x0a,0xc1,0xbf,0x4d,0x11,0xa5,0x55,0x55,0x35,0x93,0x6f,0x47,0xf1,0x75,0xb8,0xb6,0x11,0x9d,0x6e,0x3b,0xd1,0x11,0x20,0xa2,0xa2,0x5c,0x33,0x85,0x09,0xb8,0x13,0xc9,0xdd,0xf2,0xd4,0x32,0x37,0xf2,0xef,0x47,0xfa,0x25,0x1a,0xcc,0xdf,0xf4,0xe4,0x2c,0x2c,0x7f,0x23,0xb6 +.byte 0xa8,0xd4,0x6a,0xd4,0xb4,0x06,0x2e,0xb0,0xaa,0xa1,0x18,0x8a,0x5c,0xc6,0xb2,0x4c,0x71,0x92,0x4a,0xdc,0x81,0x20,0x51,0x8d,0x3f,0x71,0x7d,0x8c,0x25,0x79,0x07,0x14,0xa9,0x7a,0x8b,0xda,0x00,0xfc,0x51,0xdb,0xa0,0x50,0x2b,0x15,0x39,0xf6,0xad,0xdc,0x9e,0x22,0x93,0x2f,0x43,0xd8,0x5c,0xa2,0x5e,0xfa,0x70,0x8c,0xe0,0x6b,0x0e,0x93 +.byte 0x6c,0x89,0xfe,0x22,0x4c,0xec,0xb0,0x7e,0xc1,0x06,0x69,0xf7,0x2f,0x3e,0xe5,0xa4,0x45,0x53,0xab,0x9c,0xf5,0x40,0x05,0x53,0x64,0xc6,0xa7,0xf9,0xc4,0xd6,0x89,0xd9,0x47,0x72,0x8e,0x42,0xf9,0x64,0x12,0xeb,0xd9,0x25,0xdc,0x4c,0xc6,0xea,0x9c,0x4b,0x93,0xb4,0xa2,0xa6,0xae,0x95,0xc1,0x84,0x75,0xc9,0x22,0xe3,0x22,0x81,0x31,0xd1 +.byte 0xfd,0x2e,0x91,0x4a,0xc3,0x00,0xa6,0x57,0xbb,0x89,0x9f,0x2d,0xc3,0x2e,0x1f,0xa2,0x47,0xc4,0xa3,0xcd,0x2b,0xc2,0x29,0xaf,0x89,0xce,0x2e,0x87,0x8e,0xd8,0xfc,0xee,0xab,0x8a,0xbd,0x2f,0xee,0xcf,0x94,0xe0,0x74,0x70,0x86,0x00,0x42,0x11,0x8b,0x6c,0x81,0xd4,0x82,0xf2,0x29,0x3e,0x9c,0x68,0x71,0xaa,0x20,0x0a,0x51,0x5d,0x80,0x4c +.byte 0xca,0x04,0x23,0x23,0xe2,0x69,0xb3,0xf5,0x65,0x98,0x19,0xee,0xa9,0x4d,0xd8,0xe0,0x06,0x4b,0x17,0xed,0xfa,0xf2,0xe3,0xd3,0x69,0x48,0xe4,0x4e,0xc0,0x5a,0x16,0x90,0xdb,0xb6,0x32,0x6e,0x6b,0xd7,0x7a,0xb6,0xd4,0x82,0xe4,0xcc,0x31,0x31,0x5c,0x18,0x84,0xef,0x75,0x9f,0xda,0xf6,0x62,0x2d,0x96,0x4d,0xa1,0x3c,0xb5,0x4a,0xbb,0xbf +.byte 0x9d,0xb3,0x33,0x00,0xc1,0x73,0xc5,0xb2,0xeb,0x85,0x74,0xb0,0x68,0xed,0x16,0x66,0x71,0xc9,0x7e,0x6f,0x74,0xa6,0xe7,0xed,0xf0,0xfa,0xab,0x41,0xdd,0x10,0xf9,0xff,0x4c,0xb6,0x4f,0x15,0xe3,0x77,0x31,0x17,0x5c,0x5a,0xef,0xb2,0xa9,0x44,0xbe,0x97,0xa9,0x75,0x5a,0xb7,0xe0,0x16,0x17,0x37,0x1b,0x71,0x03,0xb9,0xaa,0x7b,0x7b,0x52 +.byte 0x46,0x58,0x6b,0x9b,0x87,0x27,0xa6,0x8a,0x0e,0x84,0x03,0x45,0x95,0x04,0xf1,0x7e,0xb6,0xf6,0x79,0xd5,0x66,0x6d,0x50,0x8c,0x5a,0x67,0xe0,0xdd,0x69,0xd8,0x92,0x75,0x15,0xcb,0xa5,0x05,0xfe,0x7a,0xc1,0xd6,0x11,0x57,0x10,0xa3,0xc3,0xb6,0xe9,0xe3,0x97,0xa5,0x46,0xc9,0xe9,0x9b,0x68,0xb6,0x55,0x0b,0xf2,0x17,0x9d,0x0e,0x7f,0xd9 +.byte 0x26,0x0c,0x01,0xff,0x95,0xe1,0x05,0xb7,0xbf,0x0d,0x77,0x12,0x96,0x03,0x71,0x01,0xc9,0x98,0xb4,0x44,0x94,0xc0,0xad,0x3d,0xfc,0x6f,0xe5,0x0c,0xa4,0x65,0xd7,0xe7,0x76,0x7c,0xb8,0xa0,0x0a,0xcd,0xe8,0x01,0x26,0x8e,0x94,0xec,0x94,0x65,0x86,0xee,0x4d,0x3b,0xc5,0xb5,0x2e,0x51,0xb7,0xa9,0x68,0xcd,0x14,0x90,0xd8,0x36,0xfb,0x52 +.byte 0x04,0x52,0xb4,0xca,0x9b,0xbf,0xc6,0x94,0x28,0xc5,0x7e,0x27,0x73,0xae,0x6d,0xba,0xe7,0x56,0xce,0x2e,0x00,0xeb,0x36,0x19,0xd7,0x4f,0x20,0x5e,0xfd,0x0f,0xd4,0x4c,0x02,0xaf,0xdb,0x74,0xef,0xf0,0x73,0x1e,0x2a,0x1a,0xe7,0x3a,0xe0,0xa5,0x89,0xcf,0x1a,0x66,0xbd,0x72,0x65,0xb4,0xf4,0x86,0x33,0x44,0xee,0x35,0xf6,0x09,0xbe,0x13 +.byte 0x96,0x84,0x04,0x95,0x3f,0x35,0xbb,0x01,0x2c,0x78,0x25,0xe8,0x1e,0x46,0xdb,0xd9,0xb1,0xe8,0xfb,0x2b,0xa8,0x59,0x72,0x5f,0x91,0xd3,0x7c,0x21,0x95,0xa9,0x50,0xa2,0x45,0x6f,0x48,0x0c,0xf2,0x51,0x10,0x3c,0xcd,0xea,0xeb,0x5d,0xc7,0xf9,0x0e,0xae,0x1a,0x02,0x05,0x15,0x12,0x10,0xc0,0x35,0x12,0x97,0xcd,0x5b,0x61,0x4f,0xd1,0xd3 +.byte 0x5b,0xec,0x2b,0xa0,0x20,0x03,0x2b,0xf3,0xe6,0x71,0x23,0xca,0x1d,0x48,0x64,0x3f,0x7e,0x52,0x8b,0xf9,0x96,0x33,0x31,0xbc,0xbd,0x73,0x2f,0xa6,0x80,0xb8,0x0b,0x3a,0xd7,0xf8,0x05,0xf0,0x06,0xc7,0xa5,0xce,0x6a,0x6a,0x62,0xae,0x06,0x93,0xa4,0x5f,0x0b,0x5d,0x4d,0xb8,0xa4,0xfa,0x2e,0xfc,0xb6,0x58,0x8c,0x2a,0x46,0xa4,0x55,0x1f +.byte 0x9b,0x9b,0x13,0xdd,0x17,0x2a,0x3d,0x04,0x51,0xb6,0xbe,0x9c,0xca,0xf3,0x23,0xb6,0x7b,0x7a,0x92,0xb7,0x2f,0xf9,0x69,0x9a,0xee,0xb3,0xa1,0x60,0x56,0xcf,0x9d,0xab,0xfe,0x86,0x7a,0x41,0x94,0x15,0xbe,0xa3,0xa5,0x85,0x09,0xfb,0x7b,0x89,0xbd,0xc3,0x09,0x10,0xa6,0xfc,0x41,0x8e,0x57,0x27,0xdc,0x58,0xf4,0x01,0x7c,0x31,0x5e,0xca +.byte 0xaf,0x31,0x2f,0x98,0x8b,0xbe,0x19,0x16,0xa1,0x81,0x7e,0xb3,0xa9,0xc5,0x15,0xd2,0xad,0x51,0xa1,0x73,0x56,0xd3,0x6a,0x15,0x35,0xe3,0xb1,0xdb,0x83,0x4c,0xe2,0x85,0x8c,0x03,0x12,0xc4,0x64,0x69,0xc0,0x23,0x16,0x7b,0x68,0x46,0x44,0x22,0x84,0xa6,0xb5,0xe4,0x90,0x91,0xc1,0xdd,0x25,0x7c,0x54,0x0e,0xce,0x5b,0x11,0xe4,0x50,0x1c +.byte 0x3c,0x0d,0xc7,0xc1,0x0c,0x10,0x2d,0x8b,0xb7,0xde,0xe2,0x4f,0x7e,0x22,0x53,0xfc,0x07,0x55,0x19,0x14,0x3b,0x33,0xf5,0xf3,0xd8,0x7b,0x5e,0x40,0xa2,0x81,0x6d,0x40,0x0d,0x20,0x36,0x4b,0xa1,0x34,0x34,0xac,0x43,0x59,0xb5,0xb1,0x90,0x8b,0x48,0xcf,0x15,0x57,0x17,0x0e,0xd0,0xbf,0x28,0xcd,0xa4,0x77,0x4d,0xae,0x09,0x4c,0x67,0x51 +.byte 0x18,0xaa,0xb4,0xc9,0x35,0x41,0x0b,0x34,0x4d,0xb3,0xef,0x3f,0x46,0x97,0x6e,0xae,0x75,0xd7,0x6a,0x2b,0x22,0x9c,0xef,0x8e,0xaf,0x72,0xb0,0x14,0x90,0xbd,0x11,0x90,0xde,0x9a,0x02,0x8c,0x20,0xf5,0xc7,0x33,0x4d,0x94,0x88,0x9a,0x6c,0x18,0xb4,0xc0,0xa9,0x94,0x07,0x9a,0x4b,0x10,0x8f,0xe8,0x25,0xcd,0x9b,0xf5,0xfa,0x91,0x8a,0xc0 +.byte 0x93,0x61,0x1c,0x00,0xd1,0x34,0x9a,0x29,0xa3,0x35,0x38,0xe4,0xa7,0x9f,0xb6,0x88,0x0f,0xad,0x88,0x96,0xa0,0x73,0xe7,0x10,0xea,0x36,0xe8,0x88,0x6c,0x7f,0x03,0xbc,0xfe,0xe0,0xb2,0x4b,0x24,0x98,0xf6,0x73,0x6f,0xab,0x00,0x1e,0x26,0x83,0x0d,0x86,0x5b,0xa6,0x51,0x8f,0x5f,0xa9,0x8f,0xf4,0xa0,0x51,0xff,0xe0,0x64,0x09,0x95,0xfb +.byte 0x56,0x53,0x18,0x61,0xea,0xc5,0x33,0xe8,0x6f,0x8a,0x07,0x97,0x1a,0x6c,0xb5,0xf8,0x73,0xae,0xe4,0x4e,0x6d,0xb2,0x83,0x20,0xfa,0xfd,0x79,0xa6,0x6c,0xaa,0x9b,0x7b,0x2c,0xfe,0x63,0x73,0xbc,0x87,0xd4,0x56,0xd1,0xb1,0xf1,0x0f,0x72,0x2c,0x2f,0xf0,0xf0,0x53,0xe2,0x6c,0x19,0x0d,0x9c,0xad,0xc8,0x0a,0x62,0x72,0xcb,0xc3,0x12,0x90 +.byte 0x4c,0x26,0xe3,0xa0,0x07,0x35,0xee,0xaf,0x81,0x35,0x07,0xa9,0x31,0xa0,0x59,0xc8,0x40,0xa5,0x45,0xb6,0x6d,0x3e,0xa2,0x5f,0x6a,0x79,0x74,0x65,0xa1,0xe3,0x1c,0xca,0xae,0xcc,0xa6,0xb6,0x0a,0x12,0x99,0x8e,0xc3,0xef,0x43,0xcf,0x42,0x92,0xa4,0x12,0xa3,0x8b,0x97,0x7d,0x6f,0xe0,0x35,0xed,0xac,0x69,0xae,0x8c,0xe1,0x32,0x11,0xa4 +.byte 0xe0,0x76,0x7f,0x75,0x92,0xda,0xfe,0x94,0x33,0xeb,0xe1,0xa4,0x3c,0x95,0x7c,0xc6,0xbc,0x3d,0xf2,0x39,0xa1,0x29,0x39,0x24,0x09,0xd4,0x52,0x68,0xfb,0x80,0xd0,0xd4,0x57,0xc6,0x4c,0xa5,0xa6,0x90,0xa6,0x61,0x15,0x2f,0xd3,0x35,0x36,0xf5,0x16,0xb3,0x65,0x0a,0xc4,0xcb,0x7f,0x73,0xe4,0xba,0x9a,0xd8,0x8b,0xc3,0x01,0xa0,0x08,0x57 +.byte 0x9e,0x26,0x54,0xbc,0x55,0xd1,0x5f,0xaa,0xb5,0x0d,0x42,0x75,0x04,0x76,0x8c,0xef,0xcf,0x64,0x3a,0x2e,0x4c,0x78,0xe5,0x37,0x8d,0x55,0xec,0xc1,0x7b,0xce,0x5f,0x5f,0x43,0x8b,0xdd,0x46,0x43,0xf5,0xa8,0x41,0xa6,0x82,0x1b,0x12,0xcb,0xcb,0x6d,0xa1,0x6c,0xb6,0x79,0x46,0x12,0x89,0x12,0x61,0xd6,0x4f,0xf9,0x43,0x2d,0x27,0xa9,0x61 +.byte 0x2e,0x2a,0x29,0x1b,0x6d,0xad,0x32,0x0b,0x6c,0x7c,0xf4,0xb8,0x98,0x91,0xbb,0x78,0xda,0x85,0xe8,0xfb,0x4e,0x11,0xc4,0x2a,0x07,0x54,0xa0,0x67,0x73,0x1b,0xa4,0x60,0x15,0x5c,0x83,0xbf,0x3f,0xd9,0x61,0x30,0x02,0xbb,0xa6,0x67,0xcd,0x0c,0xd1,0xb4,0x11,0x7e,0xca,0xf4,0x1e,0xed,0x83,0x34,0x66,0x54,0x23,0x39,0x36,0x8c,0xa0,0xc6 +.byte 0xef,0xad,0xa1,0x95,0x04,0x20,0x46,0x42,0xa8,0x99,0xd2,0x98,0xc6,0x0a,0x92,0x11,0xd1,0x84,0x4a,0xbf,0x25,0xe5,0xcf,0x78,0x98,0x81,0x80,0xaa,0x31,0x0a,0xa4,0xfb,0xef,0x35,0xfa,0xa4,0xac,0x5f,0x01,0x6b,0xb7,0x8e,0x86,0xc1,0x46,0x97,0x88,0xe2,0xaa,0x3b,0x1f,0xb5,0xf8,0xa9,0x90,0xf0,0x45,0x6d,0xdd,0xa3,0xdd,0xd8,0xef,0x36 +.byte 0x6f,0x87,0x55,0xf6,0x96,0xcd,0x88,0x43,0x03,0x97,0x82,0xea,0x5a,0x1c,0xa1,0x1a,0x7b,0x1b,0xa7,0xfc,0xaa,0x86,0xb4,0x71,0xde,0x0d,0x0a,0x52,0x98,0xd2,0x65,0x5d,0xa4,0xea,0x91,0xc9,0xe4,0x8b,0xd0,0xdb,0x85,0xe3,0x86,0x85,0x50,0xe1,0x41,0x1f,0x48,0x97,0x64,0xec,0x34,0xe4,0x54,0x42,0xf4,0x01,0xed,0x6f,0x4d,0xe3,0x1f,0x86 +.byte 0x14,0xbc,0x01,0x9c,0x7f,0x02,0x0c,0x65,0x94,0xd2,0x90,0x2c,0x1b,0xab,0x41,0x88,0xad,0x58,0xb5,0x71,0xd3,0xd6,0xe1,0x3f,0xf3,0x3c,0xb6,0xab,0x22,0x08,0x17,0xc7,0xf5,0x7e,0x34,0x56,0xae,0x1d,0x1e,0x7e,0xdb,0x24,0xe2,0xc2,0x38,0xf3,0x4d,0x46,0xe4,0x45,0xcb,0xb7,0x2f,0x0f,0x96,0x72,0x7e,0x31,0x89,0x17,0x9c,0xed,0x85,0xb9 +.byte 0xc8,0x8f,0x65,0x93,0xfb,0xb8,0x9e,0x41,0xa2,0xc1,0xcf,0xdb,0xe2,0x4c,0x26,0x4a,0xc7,0x2a,0x72,0xf6,0x28,0xbc,0x18,0x22,0xde,0xa1,0xfa,0x46,0xbe,0x95,0xc8,0xe2,0x19,0xbb,0x20,0x7b,0xd5,0xf8,0x34,0x15,0xaa,0xec,0xe2,0x9e,0xa9,0x3d,0xa1,0xd9,0xaa,0xc9,0x18,0x39,0x07,0x5c,0x81,0x61,0xe7,0x00,0xc5,0x57,0x3e,0xca,0x4d,0x89 +.byte 0x33,0x02,0xa6,0xc8,0x15,0xb7,0x24,0xdd,0x5c,0x55,0x56,0x11,0x5c,0x17,0x1b,0xda,0xc6,0xd5,0x46,0x6e,0x9f,0x70,0xe7,0x1e,0x41,0xee,0x91,0x1a,0xa0,0xad,0x35,0x64,0xdf,0x4a,0x18,0x03,0xa7,0xa8,0x88,0x8f,0x65,0xbc,0x76,0x34,0x08,0xab,0x50,0xc6,0xd3,0x08,0x7c,0xc1,0x4f,0x77,0xcd,0x1a,0xc6,0xed,0x35,0xea,0x4e,0x8a,0x6a,0x38 +.byte 0xa3,0xa3,0xd8,0xa9,0xa2,0x68,0xa7,0xd8,0xe0,0xc8,0x3f,0xfe,0xe7,0x73,0xc6,0x6b,0xd8,0x0c,0xd5,0x8f,0x81,0xe7,0x37,0x08,0x93,0x28,0x73,0xef,0xc4,0x91,0x52,0xa5,0x30,0xff,0x47,0x95,0x02,0x0d,0x8c,0xfd,0xc9,0x28,0x60,0xa9,0xad,0x30,0x00,0xcc,0x3a,0x00,0xbb,0x25,0xab,0xd0,0xf8,0x25,0x46,0x20,0xc0,0x67,0x9b,0xd6,0x10,0xa6 +.byte 0x84,0x6f,0x66,0x60,0x66,0x75,0xb6,0xfb,0x39,0x3a,0x9f,0x7d,0x32,0x7f,0x12,0x6f,0x8c,0xed,0x79,0x40,0x47,0xa3,0x27,0x17,0xa8,0xa4,0x02,0x93,0xb9,0x32,0x03,0x34,0x06,0x76,0x71,0x40,0x90,0x2b,0xe7,0xd0,0x3f,0x59,0xa7,0xfb,0x3a,0x7b,0xc8,0xa5,0x86,0x21,0x0d,0xf6,0xc6,0x49,0x07,0x56,0xe9,0xfc,0xac,0x61,0x30,0xa5,0x7e,0x90 +.byte 0x10,0xc8,0xdb,0x15,0x2b,0x75,0x27,0x77,0x51,0x42,0xcf,0x50,0xe8,0x6c,0x0b,0xb7,0x17,0x1a,0x89,0x7d,0xfe,0xd2,0x75,0xfa,0xb7,0xe5,0x68,0x10,0x1c,0x27,0x85,0x8b,0x52,0x7d,0x87,0x57,0x50,0x77,0x25,0x9d,0xcc,0x08,0x6a,0xad,0x63,0xf8,0x8e,0xe0,0x21,0x62,0x56,0x48,0x29,0xed,0x81,0x1d,0x6b,0x60,0x55,0x78,0x6a,0xce,0xd6,0x79 +.byte 0xe1,0x66,0x18,0x9f,0x71,0xf7,0x0c,0xec,0x35,0x53,0xef,0x39,0xfe,0x57,0x71,0xc0,0x49,0x4b,0x55,0xe8,0x3d,0x9b,0xe3,0x9a,0xbb,0xf8,0x61,0x31,0xa1,0x94,0x94,0x8a,0xb1,0xd2,0x0f,0x01,0xe0,0xd4,0x26,0xa0,0x59,0x70,0xd0,0x5e,0xb8,0x6f,0x63,0x7b,0x71,0x49,0xe1,0x98,0xfb,0xdb,0x22,0x26,0x18,0x16,0x31,0x08,0x90,0x32,0xd5,0x7a +.byte 0xc0,0xd8,0xeb,0xae,0x93,0x3d,0x46,0xeb,0x0e,0xdd,0x08,0xa2,0xde,0x4e,0xc1,0x88,0x26,0xc2,0xf8,0xc6,0x5e,0x8a,0x9b,0x0d,0x9f,0x2b,0xcf,0x4e,0x13,0x43,0x4a,0x65,0xf6,0x47,0x1a,0x0a,0xae,0xf9,0x9f,0x7c,0xc5,0x18,0x65,0x09,0xcb,0x85,0x7d,0x33,0x36,0x43,0x19,0x99,0x20,0xa2,0x64,0xb2,0xf5,0x20,0xd2,0x74,0xc6,0x2c,0x29,0x46 +.byte 0xde,0xa7,0x4a,0x7f,0x3b,0x05,0x3e,0x11,0xb6,0xc1,0x98,0xfb,0xf5,0x9d,0x93,0x95,0x76,0x11,0x80,0x41,0x44,0xd3,0x2f,0xf4,0xfd,0x92,0x1e,0xd7,0xa7,0x5f,0x02,0x4a,0xbc,0xb7,0x96,0x33,0xc0,0x0d,0x2d,0x97,0xb8,0xd4,0x67,0x7a,0x4c,0x74,0x93,0xa7,0x8d,0x68,0x78,0xed,0xc8,0xc9,0x02,0x6e,0xae,0x10,0x97,0x7c,0x56,0x11,0x2a,0x29 +.byte 0x87,0x5c,0x21,0xec,0x75,0x9c,0x17,0x17,0x8d,0x45,0x08,0x31,0x36,0x64,0xc0,0xf7,0x95,0xb6,0x72,0xcf,0xac,0xd8,0x52,0x02,0x6f,0x3b,0x14,0x34,0x30,0xcc,0x39,0x7c,0xe4,0x1f,0x38,0x23,0xcf,0x1f,0xb7,0x7e,0x92,0x66,0xf7,0xda,0x9f,0x27,0xbb,0x83,0x45,0x71,0x67,0x63,0x6c,0x85,0x64,0x34,0xa8,0x93,0x5a,0x13,0x0c,0xff,0x8b,0x3a +.byte 0x2a,0x10,0x1d,0xb6,0x43,0xef,0x57,0xf3,0xf0,0x29,0x2e,0x59,0x72,0x2e,0xc3,0xb6,0xd3,0xd0,0xdd,0x17,0x19,0x82,0x49,0x05,0xd4,0xfc,0xd6,0x2e,0x5d,0xd7,0x0c,0xb6,0x18,0xd5,0x08,0xbb,0xe5,0x3b,0x2e,0x85,0x62,0xc0,0x1e,0xa3,0xb8,0x92,0x21,0x06,0xfa,0xf1,0x2d,0xab,0x62,0x67,0x62,0xee,0x13,0x7f,0x07,0xb6,0x24,0x64,0x94,0x4f +.byte 0x69,0xb9,0x7a,0xdc,0x23,0x5e,0x19,0x96,0xc5,0x4d,0xcb,0xee,0x2d,0x4a,0x7d,0x1d,0xd2,0x72,0x18,0x8f,0x43,0x8f,0x76,0xbf,0x30,0xd8,0xf1,0xfe,0x9c,0xe7,0x63,0x38,0xff,0x1a,0x3f,0x40,0xbd,0x73,0x66,0xf7,0xa9,0xd9,0x17,0x4a,0x8a,0x79,0x04,0x0e,0x20,0xe1,0x39,0x49,0xd9,0x30,0x9c,0x52,0xf9,0x14,0x8f,0xdc,0x9d,0x52,0xd5,0x34 +.byte 0xaa,0x58,0xfe,0x5d,0x68,0xcb,0xab,0x3b,0x3c,0x9e,0x25,0xde,0x6d,0xdd,0x58,0x0d,0x1b,0x99,0xa9,0xcc,0x26,0x4e,0xc0,0x3c,0x8b,0x1e,0xaa,0x52,0x3d,0x4d,0xb8,0x27,0xc1,0xd1,0xa2,0xaa,0x78,0xb9,0xee,0x5f,0x26,0x46,0x5f,0x41,0x0d,0xe1,0x70,0x7d,0xcd,0x3f,0x4a,0xca,0xb2,0xca,0x2f,0x36,0x1f,0x68,0xe6,0x66,0x8a,0xf6,0xe3,0x94 +.byte 0xe5,0xab,0x90,0xeb,0x2f,0xe8,0xb2,0x6c,0xa9,0x69,0xd2,0xe0,0x5f,0x4a,0x65,0xa8,0x6b,0xc1,0xfb,0x03,0x51,0x17,0x3b,0xf8,0xe0,0x67,0xc3,0x5a,0xe8,0x18,0xdf,0xc1,0xf8,0x7f,0x44,0x68,0x4a,0x01,0xbe,0xf8,0xa5,0x7a,0xb9,0x3b,0x0f,0x05,0x8e,0x4b,0x28,0x14,0x61,0x2f,0x2e,0xc7,0xf2,0x96,0xc7,0x60,0x99,0xc4,0xbf,0xe8,0x37,0x98 +.byte 0x00,0x34,0xf7,0x5a,0xd7,0x6f,0x90,0xc4,0x19,0xb5,0x07,0xd1,0x76,0x6e,0x65,0xcc,0xf6,0x51,0x88,0x5c,0x81,0x91,0xa8,0x4d,0xb7,0x33,0x53,0xb6,0x93,0x42,0x52,0x82,0xfa,0x2b,0xca,0xa0,0xbd,0xf3,0x09,0x2b,0x0f,0x09,0x02,0xdd,0x29,0x5f,0xa6,0x49,0x7b,0x97,0xe8,0x96,0xbf,0x6f,0x76,0xb7,0xa2,0x76,0x58,0xda,0x1d,0xb2,0xdb,0x6d +.byte 0x9d,0x3b,0x32,0x6e,0x9c,0xea,0x45,0xfd,0x33,0xeb,0x41,0x91,0x91,0x52,0x2b,0x68,0xa3,0xf3,0xc6,0x92,0x43,0x13,0x49,0x8a,0x10,0xb1,0x2f,0x9a,0x0f,0xe1,0x94,0x21,0x18,0x76,0x87,0xaf,0x50,0xe4,0x71,0x5d,0x0a,0xba,0x75,0xaa,0x17,0xf5,0x37,0xf2,0x84,0x9b,0x29,0xdf,0x44,0x60,0xd0,0xac,0xcf,0x25,0x87,0x66,0x64,0x1f,0x0d,0xba +.byte 0xb3,0xdb,0x14,0xb6,0x1f,0x00,0x70,0x98,0x83,0x1d,0x9e,0xbd,0xf9,0x17,0xf4,0x57,0xae,0xa8,0xae,0x7b,0xa7,0xde,0x1f,0x31,0xc6,0x29,0xb2,0xf7,0xef,0x36,0x31,0xe7,0x50,0x33,0x69,0x4e,0x8c,0xb5,0xe4,0xdd,0x74,0x87,0xc8,0xf5,0x22,0x1b,0x4b,0xec,0xc4,0xe1,0x5a,0x7d,0x5a,0xe8,0xb9,0x2f,0xf4,0xd1,0x83,0xa2,0xb7,0x97,0xe0,0x1e +.byte 0xf7,0x3a,0x74,0xef,0x5f,0xb3,0x30,0xce,0xfa,0x23,0xd5,0x98,0x56,0x19,0x24,0xb5,0xc7,0x60,0x8b,0x03,0x8e,0xe7,0xdf,0x2c,0x36,0x4c,0x3b,0x3b,0x84,0x45,0x97,0x40,0x29,0x30,0x98,0xc3,0xc0,0xa2,0xf0,0xdf,0x69,0x47,0x95,0x26,0xdb,0x6c,0xcc,0xff,0x2d,0x32,0xaa,0xa7,0xb8,0x6b,0x24,0xec,0xff,0x94,0x4d,0x36,0xdd,0x7b,0x4d,0xc5 +.byte 0x8d,0xe2,0x3c,0x14,0x5a,0x37,0x75,0x1f,0xd6,0x98,0x7d,0xd3,0xdc,0xb0,0x24,0x69,0xe7,0x65,0x60,0x2a,0xe7,0x00,0x5b,0x68,0x99,0xa0,0x9e,0x10,0xf0,0x5c,0xa8,0x39,0x85,0x59,0xde,0xe4,0x46,0xf3,0xde,0xda,0xc0,0xb1,0xd2,0xf1,0xd2,0x05,0xd5,0xd4,0x2c,0x2e,0x7e,0x44,0x5c,0x52,0x80,0x85,0xbb,0x54,0x97,0xb6,0xad,0x6d,0x57,0x49 +.byte 0xed,0x67,0xaf,0x27,0xb4,0x5b,0xce,0x0f,0x3c,0x58,0xa2,0x24,0x22,0xa2,0xcb,0xfc,0x4e,0x8e,0xc2,0x3c,0x32,0xc6,0x07,0xc4,0xc6,0xc0,0x50,0xc3,0xe3,0x1b,0x96,0x76,0x62,0xf9,0xea,0x5e,0xdc,0xc5,0x96,0xe8,0xaa,0x20,0x26,0xac,0x44,0xfb,0xf2,0x16,0x72,0x72,0x4c,0x5c,0xee,0x51,0x07,0xb0,0x74,0xf6,0xde,0xd7,0x5d,0x73,0xf4,0xe9 +.byte 0x0d,0x29,0x06,0x5f,0xca,0xe2,0xbb,0xa4,0x3e,0xdc,0xf7,0x74,0x99,0x53,0x7a,0x52,0x60,0x46,0xaa,0xf0,0x34,0x97,0x0c,0x81,0x5b,0xd8,0x95,0x52,0x76,0x55,0xcb,0xc4,0x6d,0x50,0x26,0x3f,0x7e,0xc2,0x93,0x6e,0x14,0x0c,0xd7,0x49,0x5f,0x52,0x8f,0x34,0x49,0xb4,0xe7,0x12,0xfe,0xae,0xd1,0xfa,0xfc,0xc5,0x80,0x38,0x26,0x9c,0xf1,0x81 +.byte 0x01,0x58,0x15,0x99,0x29,0x8d,0x1b,0x2d,0x74,0xca,0xf1,0xf4,0xfa,0xcd,0xae,0xfa,0xa9,0x1d,0xbb,0xf1,0x55,0x2e,0x69,0x46,0x6e,0xe4,0x91,0xa3,0x48,0xb5,0xaa,0xb3,0x85,0xab,0x14,0xd2,0x84,0x8c,0xb1,0xb6,0x0c,0xa5,0x4a,0x90,0xed,0x6e,0xdf,0x1e,0x15,0x36,0x7b,0xa3,0x59,0xd6,0x8d,0x7d,0x7b,0x12,0x7c,0x9a,0x40,0x8a,0x28,0xde +.byte 0xb5,0xbc,0xc4,0x52,0x96,0xfb,0x62,0x1f,0xc9,0xe0,0xc9,0x1d,0xc7,0xc4,0xcb,0x8a,0x96,0x21,0x42,0x7c,0x0a,0xdd,0x42,0x74,0xcf,0xc4,0x57,0x8f,0x28,0x0a,0x7c,0x4f,0x49,0x5a,0xc6,0x21,0xb2,0xd4,0xd0,0x61,0xa5,0x35,0xbd,0x4a,0x0c,0x16,0x68,0x1f,0xe3,0xff,0x3f,0x72,0xf0,0x1d,0x50,0x26,0x48,0x91,0x27,0x1b,0x2b,0x0d,0x8b,0xf2 +.byte 0xa0,0xc0,0xa0,0x5d,0xdb,0xcf,0x71,0x41,0x83,0x00,0xb9,0x3c,0xe0,0x4a,0x96,0x43,0xf8,0x64,0x0f,0x42,0xc5,0x75,0xec,0x26,0x62,0x99,0x13,0xeb,0xf9,0xa6,0x86,0xe4,0xc9,0xaf,0x3c,0x2c,0xc9,0x4f,0x89,0xf4,0xc0,0x46,0x99,0xb8,0xd1,0x9e,0x7b,0xb7,0x41,0x0a,0x5f,0x40,0x98,0x65,0x29,0xdd,0x60,0x6b,0x27,0xbf,0x66,0x08,0x32,0xc2 +.byte 0xcf,0xea,0x91,0x44,0x45,0x49,0x1c,0xb4,0x16,0x7f,0x11,0x1a,0x8c,0xb4,0x59,0x54,0xc6,0xcf,0x40,0xd2,0xe9,0xc1,0x54,0x9c,0xe2,0x6e,0xd5,0xfe,0xfb,0x4a,0xa3,0x98,0x63,0xef,0x86,0xe0,0x63,0x30,0x32,0x5a,0xbd,0xd4,0x7c,0xe8,0xbe,0xf1,0xed,0xa2,0x19,0x98,0xc8,0x34,0x65,0x4c,0xef,0x1a,0xb3,0xbc,0x87,0xbe,0x6b,0x75,0x2c,0xe5 +.byte 0x54,0xcc,0xe5,0x69,0xb2,0xc8,0xdb,0x57,0xf8,0xa7,0x82,0x07,0xf7,0x20,0x95,0x7f,0x6d,0x7b,0x33,0x66,0x67,0xa1,0x38,0x0e,0x9c,0x3b,0x22,0xab,0xc1,0xd3,0xed,0x87,0x32,0xfb,0x4a,0x5d,0xad,0x3a,0xe1,0x90,0xa6,0xe3,0x4d,0x6b,0x00,0xe4,0x5c,0x66,0x59,0x90,0x63,0x24,0x5b,0xe1,0x3b,0x69,0xb6,0xc9,0x05,0x83,0x3a,0x7b,0xf4,0xa5 +.byte 0xc8,0x47,0xf9,0x8e,0xab,0x92,0xbd,0xd3,0x41,0xc7,0x61,0xf4,0xce,0x30,0xdb,0xae,0x27,0x69,0x0f,0xcc,0x69,0x50,0xe8,0x18,0xf2,0x39,0x04,0x5a,0x29,0x12,0x61,0x46,0x5c,0x1b,0x2e,0x15,0x9c,0xfa,0x73,0x50,0xe3,0x51,0xda,0x4d,0x88,0x25,0xb2,0xff,0x55,0x27,0xce,0x86,0xca,0xe6,0x2a,0xb8,0x0c,0xa7,0xd0,0x06,0xbf,0x70,0xb5,0x6b +.byte 0x80,0x44,0x65,0x5d,0x23,0xfa,0x0d,0x74,0x5c,0xfc,0xc7,0x86,0x5e,0x23,0x8a,0xf1,0xff,0x80,0xf0,0x19,0xaa,0x98,0xae,0x56,0xcf,0x12,0x74,0x6c,0x70,0xb2,0x39,0xbe,0x66,0x71,0xee,0xe3,0x43,0x3b,0xfa,0x79,0xa9,0x7e,0x69,0x6a,0x19,0x42,0xd5,0x0e,0x1e,0x92,0xfe,0x8a,0x0f,0xca,0x74,0xf2,0x68,0x71,0xf5,0xcb,0x05,0x94,0xc1,0x06 +.byte 0x1b,0xae,0x55,0xe9,0x16,0x03,0xa9,0x97,0xad,0x49,0xaf,0x88,0x8c,0x26,0x33,0x4d,0x46,0x75,0xb3,0x9c,0xee,0x70,0xe1,0x57,0x43,0xeb,0x59,0xff,0x77,0x89,0x8a,0x77,0x3f,0x7e,0xe6,0xbe,0xa2,0x05,0xb1,0xe3,0x41,0x5e,0xc7,0xd4,0x14,0xda,0xc0,0x84,0xd0,0x05,0x50,0xdd,0x62,0xdb,0x4c,0x3b,0x16,0xb0,0xe0,0xf5,0x2b,0xf1,0x83,0xea +.byte 0x7b,0x89,0xbb,0xde,0x57,0xdb,0xc0,0xb9,0x7d,0xdf,0x53,0x0f,0x6c,0xc5,0x5a,0x0b,0x36,0xeb,0xa3,0xc3,0xe6,0xc5,0x80,0x98,0xf3,0x87,0x29,0x97,0xc9,0x2e,0xd6,0x3b,0x43,0x2a,0x36,0x3b,0xba,0x43,0x85,0xf5,0x0d,0x18,0x2e,0x78,0x43,0xae,0xa4,0x24,0x6d,0xdc,0xab,0x05,0x94,0x09,0x94,0x27,0x17,0xef,0xbc,0x7e,0x52,0xa4,0x80,0xda +.byte 0x28,0xf5,0xc3,0x20,0x99,0xbb,0x5d,0xb6,0x7e,0x0e,0x59,0x3b,0x5e,0x1d,0x1b,0x4f,0xd1,0x91,0xe4,0xe4,0xc7,0x35,0xc7,0x2e,0xc1,0xba,0x60,0x05,0xa4,0xd5,0xca,0x5f,0x09,0xbf,0x79,0x06,0xcb,0xa7,0x32,0x7c,0xf4,0xdc,0xa8,0xb3,0x8b,0x26,0x59,0x6d,0xcb,0x74,0x37,0x56,0x51,0x96,0x0b,0x44,0xf1,0x95,0x16,0xe3,0x9b,0x9b,0x3b,0xb3 +.byte 0xea,0x6a,0x1b,0x76,0x99,0x69,0xd6,0x5b,0x10,0x5a,0x91,0x23,0xb5,0xc3,0xf9,0x6a,0xba,0xc4,0xe6,0x18,0x28,0x50,0x9d,0x09,0x14,0xbe,0xed,0x73,0xd2,0x51,0xff,0xf8,0x14,0x2b,0x8b,0xdd,0x2a,0x1a,0x8e,0x48,0xae,0xd8,0xdf,0xb9,0x5b,0xcb,0x8f,0xc2,0x8c,0xd6,0xb3,0xfb,0x40,0x2f,0xb0,0x6c,0x9a,0xea,0xd0,0x14,0x8c,0xc5,0xc7,0xc7 +.byte 0xf8,0xf5,0x4f,0xe2,0xd7,0x41,0xcd,0xb6,0x34,0x3e,0x81,0x19,0x09,0xa2,0x51,0xb4,0x60,0xfb,0xf2,0x6c,0xe6,0xae,0x68,0x47,0xb9,0x93,0x7b,0xc9,0xe7,0x00,0xc4,0xa7,0xf2,0xef,0x8b,0xd8,0xfc,0x9f,0xe5,0x6d,0x48,0xe2,0x6c,0x32,0x73,0x5c,0x30,0x7c,0x12,0x13,0xca,0xc3,0x31,0xc3,0xa2,0xb4,0xf7,0x23,0xc4,0xd0,0x47,0x39,0x93,0xc8 +.byte 0xa0,0x7b,0xb4,0x09,0x3f,0xe8,0x15,0x15,0x9c,0xa7,0xe6,0xa8,0xbe,0xba,0x60,0xf9,0x28,0x88,0x66,0x7b,0x62,0x32,0x17,0x18,0x68,0x87,0x53,0xf5,0xbc,0xf5,0x77,0x17,0xa1,0x3f,0x62,0xd1,0x10,0x0a,0x54,0x96,0x9c,0x31,0xc3,0xb7,0x1d,0xaf,0xc7,0xb3,0x27,0x9e,0x46,0xfe,0x7e,0x9b,0x88,0xf2,0x9e,0x6e,0x19,0x0f,0xb1,0x88,0xe4,0x08 +.byte 0x76,0x7c,0x77,0x46,0x09,0xa7,0x9e,0xf4,0xd9,0xbf,0x67,0xe8,0x9d,0x6a,0x75,0xa7,0xf5,0xee,0x29,0xba,0x84,0xa0,0x44,0x46,0x35,0x4c,0x22,0xef,0xb3,0xea,0xb0,0xf2,0xd6,0x78,0x20,0x97,0x28,0x5c,0x7e,0x90,0x06,0x80,0x19,0x63,0xa4,0x8a,0xef,0x0a,0xea,0x88,0xa9,0xa2,0xae,0x23,0x2e,0x40,0xce,0xc5,0xc2,0xbf,0xfe,0x5a,0x8f,0x14 +.byte 0xb8,0x66,0x1a,0x2d,0xdb,0x43,0x39,0xbd,0xe7,0x7b,0xbc,0x41,0x58,0x74,0x56,0xd1,0xe7,0xd0,0xba,0x24,0xd2,0x41,0xbf,0xd0,0x4e,0x97,0x38,0x8f,0x6b,0x6f,0xe2,0x7d,0x6d,0x32,0x94,0x43,0xa7,0x66,0xf7,0x90,0x21,0xe0,0xdd,0x19,0x48,0x72,0xc1,0xa5,0xbc,0x9c,0xe2,0xdd,0x2c,0x6e,0x50,0x45,0x2c,0xa0,0x95,0xcb,0x1d,0x2c,0x1d,0xa6 +.byte 0xbe,0x9c,0xd4,0x6c,0x07,0x2e,0x5e,0xc8,0xc1,0x05,0x61,0x7d,0x44,0x28,0xe6,0xad,0xf0,0x9d,0x2d,0x3d,0xce,0x90,0x7d,0x79,0x2e,0xf3,0x08,0xbe,0x7a,0xa9,0x58,0x04,0xa7,0x39,0x05,0xdd,0xb4,0x87,0x6c,0x7b,0xd5,0xb3,0x2d,0x6b,0x43,0xf4,0x37,0xd9,0x6f,0x5c,0xa2,0x23,0x92,0x53,0xb9,0xd7,0x1b,0x2d,0x5d,0xcd,0x6d,0x3f,0xef,0xc8 +.byte 0x66,0x91,0x10,0x1b,0xc5,0x24,0x50,0x87,0x70,0x93,0x03,0x3f,0x7b,0x40,0xc8,0x0c,0x9b,0xec,0x3d,0x82,0x27,0x96,0x2a,0xbe,0xca,0xaf,0x1b,0xbf,0xef,0x14,0x0c,0xdc,0xa6,0xc7,0x48,0x18,0xce,0x8e,0x43,0x58,0x97,0xb3,0x5e,0xd6,0xc9,0x70,0x65,0xd0,0x0e,0x17,0xac,0xa0,0x6b,0xc9,0x55,0x30,0x12,0x7c,0xbe,0xe5,0x46,0xfc,0xd8,0x3f +.byte 0x0e,0xd7,0x96,0x16,0x32,0x8e,0xb7,0x2d,0x07,0xd1,0x26,0x98,0x70,0x4c,0xb1,0x6f,0x92,0x32,0x75,0x4f,0x57,0x6b,0x78,0xe0,0xc5,0x9b,0xf0,0x08,0x59,0x0b,0xfa,0x2d,0x79,0xbe,0xde,0x44,0x3d,0x65,0x77,0x27,0x3b,0xd9,0xea,0x55,0x79,0x22,0xe8,0xf7,0x62,0xb1,0xe3,0x32,0x4e,0x03,0x17,0x65,0xd3,0x5d,0xee,0xa0,0x9b,0xc2,0xbd,0x9f +.byte 0xcd,0xdc,0xde,0xd7,0x6c,0x95,0x7a,0xf1,0x09,0x4c,0x14,0xb9,0x37,0x1d,0xd0,0xdd,0x4b,0x2e,0x93,0x0b,0xfa,0x08,0x40,0x01,0x36,0xdf,0x89,0x46,0xa6,0xbb,0x19,0xd9,0x4f,0xf9,0xe1,0x7b,0x03,0xc9,0xef,0x01,0x25,0xe9,0x6d,0x95,0x84,0x7f,0xf8,0x8e,0x02,0xfd,0x6f,0x30,0xed,0x1b,0x98,0xd0,0xb3,0xdd,0x92,0x65,0x46,0x49,0x61,0xde +.byte 0x76,0xf5,0x4b,0x29,0x03,0x6f,0x79,0xee,0xbe,0x7a,0x07,0x6e,0xa8,0x29,0xb8,0x03,0xb4,0x6c,0x50,0x1f,0x4a,0xa2,0xaf,0xbd,0xde,0x18,0x72,0x90,0xa2,0x12,0xa9,0x59,0x7b,0xf6,0x96,0x2d,0xda,0x3d,0x90,0xba,0x7c,0x79,0x3e,0x6e,0xef,0x94,0x37,0xe2,0xef,0x6b,0x2a,0x74,0x6b,0x52,0xa0,0xc2,0x1e,0xa1,0x24,0x59,0x84,0xeb,0xdc,0xd0 +.byte 0x34,0x60,0xa8,0x81,0xaf,0xdd,0x57,0xc2,0xa6,0x02,0x7f,0xcf,0x9e,0x64,0x28,0x18,0x7c,0x95,0x98,0x90,0x7a,0x76,0x3f,0x78,0x16,0x2c,0xe0,0xa7,0xdf,0x0d,0x4d,0x5e,0xcc,0x0d,0x73,0x12,0x26,0xd7,0xe9,0x32,0x3e,0xa1,0xa9,0xde,0x29,0xb2,0x3b,0x6f,0x3b,0x6e,0x12,0x0c,0x10,0x34,0x86,0xf2,0xa0,0xd4,0x9c,0xf6,0x14,0x5a,0x41,0x06 +.byte 0x31,0xb1,0xe4,0x31,0x52,0xf4,0xcb,0xe3,0x39,0xcd,0x0b,0xc2,0xca,0x90,0xba,0xb3,0x21,0xbf,0x94,0x13,0x75,0x3b,0x0e,0x0a,0xc0,0x05,0x35,0xe6,0x28,0x74,0x63,0xc5,0x34,0x44,0xd8,0x9a,0x0e,0xec,0xb3,0x1b,0x30,0x58,0xfc,0xa0,0xc4,0xd1,0x26,0x50,0x6b,0x22,0x88,0xfc,0xad,0xa9,0xb4,0x3e,0x36,0xb6,0xb1,0x6d,0x62,0x7e,0x60,0x8f +.byte 0xf5,0x17,0x65,0x1c,0xf6,0x51,0x4d,0x89,0x4a,0x7e,0x5d,0x23,0x3b,0x83,0x1f,0xa6,0xc8,0xd2,0x1a,0x90,0xd3,0x53,0xfc,0x48,0x64,0x94,0x6e,0x1c,0x72,0xef,0x5d,0xd4,0x23,0xa2,0x3a,0x93,0xe4,0x29,0x33,0x8a,0xbd,0xe5,0x17,0xc2,0xe9,0x18,0x6a,0x81,0x1e,0x5b,0x03,0x41,0x45,0x35,0x14,0xe7,0xc8,0x45,0x5c,0x37,0x69,0x77,0x62,0xf8 +.byte 0xd7,0xec,0x9d,0x62,0x2e,0xfa,0x43,0x3a,0xdc,0x8b,0x86,0x86,0x1b,0x31,0x71,0x0e,0x92,0x59,0xf7,0xef,0x96,0xfd,0x04,0x1e,0x1d,0x74,0x7d,0x08,0x06,0x21,0x54,0x39,0xd3,0x9f,0x30,0xa1,0x19,0x7f,0xc8,0x19,0x16,0xd1,0x21,0x2a,0xf3,0x21,0xce,0x19,0x1a,0xde,0x70,0x1b,0x87,0x05,0x9e,0xe8,0xf3,0xfd,0x1d,0xaa,0x61,0x6c,0xfb,0xdf +.byte 0x50,0x9a,0xa0,0x32,0x4e,0xe4,0x68,0xda,0x0e,0x2f,0x2a,0x70,0xe1,0x51,0x66,0xb4,0x2d,0x5b,0xb6,0x32,0x3f,0xcb,0xc0,0xaf,0x01,0x03,0xcd,0xd6,0xb8,0x4e,0x3d,0x24,0x17,0xe2,0x30,0x3b,0xa4,0x08,0x0e,0x6a,0xcf,0xbe,0xc2,0x5c,0x79,0x5d,0x25,0xe2,0xae,0xa7,0x7f,0x42,0xff,0xa9,0xa5,0x05,0xbf,0xf4,0x92,0x30,0xaa,0x1d,0x96,0x7a +.byte 0x49,0xbc,0x1c,0xaa,0x5c,0x8d,0xe8,0xf3,0xd3,0x1a,0x67,0x7f,0x47,0x09,0x90,0x35,0x82,0x4e,0xcc,0x2e,0x50,0xfe,0x2c,0xb9,0x29,0x39,0xff,0x49,0x8f,0x7e,0x89,0x8d,0x4a,0x15,0xd1,0xd6,0x83,0xdb,0x25,0xac,0xc1,0x81,0x23,0x70,0x3f,0xb9,0xce,0x7f,0x03,0x46,0xa8,0x39,0xab,0xff,0x71,0xc9,0x7b,0x3c,0xb3,0x5e,0x9f,0xfe,0x8a,0x0a +.byte 0x39,0xad,0x6a,0xc1,0x8e,0x5a,0xa8,0x71,0xb7,0x01,0x25,0x28,0x15,0xd9,0x0a,0xae,0xc1,0xf9,0x23,0x1c,0xc1,0xe8,0x86,0x1d,0xb8,0x71,0x6e,0xa2,0xa4,0x67,0x22,0x4d,0x0e,0xd2,0xaa,0x70,0x26,0x23,0xfc,0x15,0xed,0x67,0x11,0x87,0x69,0x6f,0xc6,0x4c,0xe1,0x4b,0x04,0x86,0xe9,0x56,0x40,0xea,0x07,0xb1,0x6f,0xe9,0x8f,0xdd,0x2f,0xce +.byte 0x8d,0xca,0x0a,0x58,0x01,0x44,0x2c,0x74,0xd0,0x14,0x07,0x9a,0xb7,0x5a,0xc1,0xea,0xa9,0xdd,0xa4,0x94,0x84,0xc2,0x11,0xa5,0xe2,0x00,0xd8,0xfc,0x77,0xb9,0x5e,0xe6,0x72,0xef,0xc5,0x38,0xe0,0x90,0x11,0x16,0xfd,0xa7,0x77,0xbd,0x4c,0x1d,0xeb,0x32,0x54,0xdb,0x2a,0x43,0xa1,0x87,0xbb,0x2e,0x79,0x22,0x4d,0xb3,0xdf,0x1a,0xee,0x75 +.byte 0xb0,0xdd,0xf2,0x09,0x05,0xf4,0x6a,0x3c,0x86,0xc6,0xe7,0x60,0x2a,0xee,0xb6,0x55,0xae,0xdc,0xce,0xf8,0xe4,0xd7,0xdf,0x72,0x42,0x91,0x6d,0xc4,0xd8,0x60,0xf1,0xe8,0x06,0x71,0x38,0xa3,0x03,0x3e,0x1b,0x14,0x47,0x74,0x93,0xb5,0x61,0x28,0xde,0x23,0x8f,0xbe,0x88,0x5e,0xdf,0x87,0x47,0xd4,0x5f,0x91,0x40,0xeb,0x02,0xda,0x27,0x3b +.byte 0x65,0x9f,0xd8,0xf1,0x78,0x7f,0xba,0x9b,0x35,0xb3,0x10,0xaf,0x7f,0x51,0x37,0xa5,0x63,0x64,0x1f,0xf1,0xc3,0x1b,0x9e,0xe4,0xdd,0x93,0x8c,0x3a,0x98,0x20,0x9a,0x75,0x22,0x7b,0x48,0x0a,0x9d,0x55,0xed,0x07,0x1a,0x79,0x3b,0x98,0xe3,0x16,0x9b,0x16,0x2c,0xb2,0x03,0xc1,0xf5,0x6c,0xac,0x00,0x6a,0xb6,0xc1,0xc2,0x49,0x4d,0x9d,0xf5 +.byte 0x0e,0x7b,0x60,0x09,0xcc,0xa7,0x35,0xbb,0x70,0x34,0x18,0x49,0x2c,0xf1,0x41,0x4f,0xce,0x68,0x03,0x60,0x14,0xa7,0x2e,0x59,0x0f,0xa2,0xc4,0x2f,0x33,0xf0,0xb6,0xa4,0x31,0x75,0xdc,0xb4,0x88,0xe4,0xe3,0x0e,0x4b,0x3f,0x58,0xd0,0xa4,0xea,0x9a,0xef,0x47,0xb7,0xf7,0x20,0x71,0x52,0xd3,0x8a,0x1c,0xd9,0x2d,0x88,0x05,0x03,0x8a,0x1c +.byte 0x3d,0x69,0xf0,0x39,0xf0,0x25,0xad,0x95,0xd4,0x47,0x3c,0xbb,0xfa,0x48,0xd7,0x8e,0xf5,0xdc,0x33,0x43,0x0a,0xbb,0xf0,0xd3,0xb1,0xc3,0x94,0x81,0xcd,0x22,0x79,0xdc,0xd0,0x92,0x8b,0xd3,0xc3,0xac,0x73,0x72,0x83,0xaa,0xa2,0x52,0x13,0x27,0x0e,0xc5,0x8c,0xa5,0x69,0x21,0x6e,0x9c,0x9d,0x9b,0xeb,0x7a,0x19,0xfe,0xb6,0xdb,0x4e,0xc1 +.byte 0xa6,0xec,0x42,0xb0,0x86,0x69,0x60,0xde,0x36,0x11,0x6a,0x86,0xd7,0xbf,0x15,0x48,0xa2,0x73,0x8f,0x68,0xde,0xd6,0xb2,0x6d,0xe0,0xc5,0x1f,0x1f,0xd5,0xc5,0xef,0xce,0xa1,0x90,0x5c,0xe6,0x6c,0x15,0x73,0xa7,0xcc,0x2d,0xe8,0xcf,0x4c,0xc8,0x17,0x3c,0xfa,0x5e,0xdb,0x4f,0x54,0xf3,0xa3,0xff,0x50,0x3e,0x42,0x60,0x0d,0xf3,0xf7,0xbb +.byte 0xc6,0xf5,0xe7,0x63,0x50,0x49,0xc1,0x94,0x60,0x68,0xbd,0x62,0xc0,0x81,0x80,0x16,0xfd,0x65,0xfb,0x2e,0x23,0x67,0xb3,0xb6,0xf8,0x95,0xfa,0x00,0x3f,0x1d,0x10,0x16,0xd5,0xd9,0x66,0xf8,0x25,0xb4,0xce,0xf2,0x2e,0x4f,0xa2,0x21,0x14,0xbd,0x2c,0x63,0xec,0x44,0x57,0x07,0x87,0x3c,0x2f,0x22,0xcf,0x48,0xd3,0x20,0x51,0xfc,0x5d,0xd5 +.byte 0x9f,0x67,0x9c,0xaf,0xe3,0x89,0x36,0xc5,0xfa,0x7c,0xca,0x07,0xdc,0x56,0x2a,0x4e,0xa5,0x76,0xe6,0x09,0x99,0xfb,0xb7,0xba,0xaa,0x0b,0x9c,0xe2,0x0f,0x73,0xab,0x9b,0xbe,0x6f,0x50,0xe3,0xf7,0x28,0x32,0xf2,0xab,0x86,0xa3,0x89,0x3a,0xea,0xd7,0x52,0x52,0x6e,0xed,0x1b,0x94,0xf0,0x59,0x9d,0xbb,0x7a,0x88,0x6f,0xbf,0xaf,0x6a,0x87 +.byte 0x47,0x34,0x7f,0xf4,0x8b,0x0d,0x33,0x12,0x2b,0x67,0x6b,0xc9,0x1d,0x18,0x23,0x2e,0x54,0xee,0x07,0x28,0xbd,0x9d,0xa1,0xaf,0x85,0x7a,0x0f,0xe5,0x5d,0xf7,0x8b,0xca,0xd9,0x3d,0x8f,0x4f,0xcc,0xce,0xc3,0x6e,0x3a,0x40,0x08,0xd2,0x14,0xf0,0x28,0x9b,0xc0,0x4a,0x7a,0x3c,0xc2,0xed,0xe0,0x20,0x04,0xf5,0xf9,0xee,0xb8,0x35,0x94,0xbc +.byte 0x53,0x46,0xf2,0x1a,0xab,0xe9,0xde,0xd8,0x27,0x67,0x0d,0x63,0x2a,0x7b,0x3a,0x38,0x91,0xbc,0x48,0x2c,0x38,0x09,0xa0,0xe3,0x66,0xe3,0xeb,0xb9,0x02,0x2d,0x80,0x87,0x81,0x4f,0x5c,0x1c,0xfd,0x2b,0x0f,0x99,0x37,0x3a,0xfa,0x0f,0x8e,0x8c,0x87,0x76,0x72,0xd3,0xcf,0xc8,0x1e,0x8a,0x3b,0x97,0xa0,0xe6,0x32,0x66,0x3c,0x55,0x2c,0xfb +.byte 0xa9,0x41,0xfd,0xf9,0xd4,0x50,0xe0,0x5b,0x03,0xb7,0x1e,0x49,0xfa,0x59,0xeb,0x55,0xb1,0x21,0xd0,0x52,0xeb,0xe6,0x0f,0x21,0x81,0x4f,0x82,0x9a,0x8f,0x67,0x3d,0x0d,0x1d,0x11,0x1f,0x70,0x59,0x09,0x87,0x99,0xe5,0xf2,0x89,0xa6,0x56,0x8d,0x52,0x55,0xa8,0x91,0x5d,0x51,0x48,0xec,0x66,0x05,0xd6,0x18,0xd1,0x61,0x02,0x5a,0x80,0xcc +.byte 0xee,0xf3,0x3b,0x8e,0x73,0x2a,0xb1,0x22,0xda,0x1d,0xca,0xb2,0xd6,0x7f,0xd7,0x7d,0xaf,0x23,0x8d,0xff,0x24,0x8e,0x5e,0x38,0x29,0x23,0x1f,0xbc,0xfd,0xe4,0x3d,0xcd,0x66,0xe3,0xe1,0x0f,0x85,0xe3,0xda,0x34,0xc6,0xba,0x60,0x5f,0xaf,0x32,0x79,0x34,0xc0,0x01,0x93,0xae,0x1e,0x72,0x7f,0xd2,0x32,0xa1,0xdc,0x0b,0xca,0xee,0x5a,0x7a +.byte 0x09,0x98,0x2a,0x46,0x0a,0xe7,0xfd,0x0f,0x76,0xa0,0x3b,0x2b,0x3d,0xe5,0xcd,0x04,0xa2,0x5e,0x9b,0xba,0x4a,0xd5,0x0a,0xce,0x94,0x77,0xbb,0x24,0xa4,0x12,0xbc,0x24,0xb6,0x60,0x40,0x62,0xd2,0x70,0x0e,0x3f,0x62,0x72,0x2f,0xa1,0xc9,0x12,0x03,0x0f,0x39,0x57,0x77,0x7c,0x5c,0x31,0x13,0xcb,0x8c,0x2c,0x84,0xfd,0x7b,0x6f,0x60,0xbb +.byte 0x1a,0x0b,0x65,0x8c,0xc1,0xe6,0x4b,0x60,0x8c,0xe7,0x3e,0x94,0x2a,0xcc,0x70,0x9f,0xd0,0xfd,0x00,0x0e,0x36,0xb2,0xf1,0x62,0x78,0x6a,0xc8,0x9b,0xbe,0x8b,0x54,0xa7,0xad,0xee,0x3e,0x8e,0x1c,0x23,0xbe,0xa2,0x73,0x43,0xbe,0x15,0x32,0x84,0xdd,0x22,0x75,0xd5,0x9a,0xfb,0x93,0x38,0x55,0x2f,0xa4,0x34,0x4c,0x33,0xc3,0xd7,0x7c,0x9f +.byte 0x42,0x2f,0x9f,0xf6,0x27,0x90,0x15,0x6b,0x14,0x4f,0xbc,0x4b,0x07,0x42,0x24,0x98,0xa6,0xc4,0x4c,0x2f,0x22,0xd9,0x80,0x99,0x97,0x6b,0x7d,0xe8,0x2b,0x31,0x37,0xfe,0xd1,0x8b,0xbd,0xbf,0x08,0x4a,0x56,0x3d,0xff,0xb5,0x12,0x6d,0xc4,0xcf,0xbc,0x75,0xe9,0xe6,0x6f,0x1a,0x30,0x34,0x5b,0x2c,0x1d,0x8f,0x85,0xa0,0xe8,0xfd,0xfd,0xe2 +.byte 0xe7,0x13,0x73,0xcd,0x63,0x63,0x90,0xa5,0xa4,0x3f,0x91,0x65,0x77,0xd4,0xed,0x0c,0x1d,0x06,0x95,0x93,0x74,0x85,0xec,0x31,0xde,0xc9,0xb9,0x2e,0x7c,0x6d,0x2c,0x0d,0x15,0xb7,0x6b,0x0c,0xd2,0xe8,0xa8,0xcb,0x90,0x5c,0x11,0x53,0xc5,0x9d,0x54,0xf4,0x90,0xf7,0xc8,0x17,0x65,0xc0,0x3f,0xea,0xf6,0x28,0x8e,0xf0,0x1c,0x51,0xcc,0xfd +.byte 0x99,0x67,0x3d,0xa5,0x82,0x1f,0xb3,0x75,0x08,0x27,0x85,0xa9,0x7b,0x54,0x91,0x6e,0x80,0x9a,0xdb,0x6c,0x17,0x4a,0x36,0x73,0x0e,0x61,0x2e,0x01,0xae,0x32,0xf8,0x54,0xdb,0xcf,0x24,0xa5,0x13,0xb1,0x7e,0x0b,0xf5,0xe7,0x0e,0x27,0x9a,0xef,0x01,0x0b,0x34,0x4f,0x91,0xc2,0x93,0xe0,0xe6,0x14,0x64,0xf8,0x7b,0x41,0x37,0x22,0x39,0xad +.byte 0xf4,0xa9,0x3b,0xfb,0x7e,0x2b,0xd8,0x2b,0x0f,0x7e,0x40,0x55,0x5a,0x48,0x61,0x2f,0x95,0x5e,0x5c,0x25,0xe5,0x06,0x89,0x17,0x23,0xb6,0x1b,0x38,0x2e,0x7b,0x45,0xa5,0x11,0x0a,0x8d,0xd3,0x8d,0xb6,0x8d,0x47,0xc5,0x4f,0x8f,0x8b,0xe2,0x03,0x85,0xa1,0x5a,0xa2,0x8d,0xca,0x4d,0xef,0xc9,0xde,0x7d,0x06,0xa1,0x3f,0x21,0xb9,0x38,0x7b +.byte 0x91,0xf7,0x5c,0x9f,0x97,0xe3,0xeb,0x5d,0xea,0x5e,0xc1,0xa5,0x30,0xb0,0x7f,0xe0,0x4c,0xef,0xe5,0xe3,0xa0,0x2d,0x23,0xb6,0x08,0x21,0xe6,0x67,0x35,0x82,0x07,0x59,0x02,0xd4,0x68,0xa5,0xf1,0x42,0x70,0xb4,0x5e,0x54,0xed,0x1e,0x99,0xb2,0x55,0xf1,0x69,0x2e,0x7c,0xaa,0x6c,0x5e,0xd4,0xfa,0x16,0xa7,0x1f,0xdb,0x46,0x70,0x65,0x26 +.byte 0x98,0xf1,0xb6,0x42,0xb3,0x48,0x99,0x7c,0x07,0xbe,0x2b,0xee,0xb4,0xc1,0xf0,0xb7,0x47,0xf8,0xcf,0xe4,0x8d,0x34,0xa6,0xe5,0x17,0x9a,0xb7,0x2c,0x2e,0x03,0x30,0xfd,0xfb,0x42,0xe7,0xa1,0xe0,0x34,0x49,0x64,0xd8,0x0c,0xd5,0xb8,0x77,0x9f,0x0e,0xe2,0x73,0x0d,0x20,0x0c,0x21,0x07,0xaf,0x0f,0x93,0x94,0xd6,0xdc,0xe3,0xac,0x8d,0x8e +.byte 0xae,0x87,0xbd,0x2c,0x19,0x66,0xef,0x90,0x4a,0xd9,0xb0,0xf6,0xac,0x3a,0xe2,0xb5,0x2e,0xb4,0x63,0x91,0xf1,0x8b,0xac,0xce,0x51,0xc2,0xe0,0x02,0x7d,0xf8,0xab,0xe4,0xd6,0x85,0xd6,0xbb,0xd7,0x72,0xd0,0x5f,0x4e,0x90,0x09,0xcc,0x51,0xee,0x5b,0xad,0xb2,0xf6,0x16,0x37,0x09,0xa8,0xfc,0x74,0xa5,0x2e,0x26,0x27,0xff,0x53,0xd4,0x45 +.byte 0x82,0xb1,0xb6,0x16,0x65,0xc6,0xbb,0x54,0x0b,0x89,0xa1,0x0e,0x09,0x7c,0xc9,0xc9,0x48,0xa7,0x51,0x78,0x1d,0x3a,0x30,0xc5,0xe7,0x02,0x9e,0x91,0xd6,0x39,0xc8,0x35,0xf0,0x33,0xab,0xf6,0x0f,0xf9,0xce,0xef,0x26,0x46,0x48,0x56,0xbc,0x45,0x44,0xe2,0xd7,0xfc,0xdf,0xb2,0x95,0x20,0x07,0xeb,0x47,0x1c,0xde,0x88,0x5e,0x08,0xee,0xa1 +.byte 0x56,0x9a,0x5d,0x8f,0x35,0xc5,0xb3,0xd3,0x7d,0xe3,0x25,0x82,0xcc,0xcb,0xad,0xd8,0xef,0x83,0x76,0x08,0x55,0x9e,0xf4,0x00,0x1f,0x92,0x24,0x0e,0xf6,0x96,0x98,0x34,0x10,0x10,0x93,0x27,0x3b,0x96,0xbd,0x75,0x45,0x9d,0xad,0xc1,0x79,0xa7,0x09,0x68,0x0a,0xbc,0x14,0xe9,0x62,0xf6,0x5e,0x4e,0x6d,0xfb,0xf2,0x25,0x20,0x8b,0x53,0xa6 +.byte 0xc2,0x31,0x71,0xaa,0xfa,0xa2,0x1c,0xa1,0xb3,0xa2,0xd7,0x22,0x5a,0x72,0x61,0x5c,0x30,0x75,0xcc,0x82,0xb0,0xd0,0x07,0x8c,0x95,0x11,0x57,0xa4,0xe2,0x42,0xf3,0x3d,0x87,0x56,0x45,0x38,0xd6,0x1b,0x2b,0x26,0x11,0x99,0xce,0xcc,0x2e,0x96,0x1b,0xa1,0x06,0xa1,0xa9,0x65,0xe1,0x1f,0x53,0xb6,0x1e,0x5c,0x44,0x40,0xa2,0xf2,0x03,0xe7 +.byte 0x39,0x24,0x59,0x5f,0xdd,0x30,0xf0,0x78,0x9f,0x34,0xf1,0xd3,0x5d,0x9a,0xdd,0xf9,0x02,0x16,0x4b,0xfa,0x8d,0xab,0x2f,0x96,0xdb,0x67,0xf6,0x1e,0x7a,0xf8,0xd8,0xe6,0x71,0xdc,0x1a,0xbf,0x44,0xd2,0xbd,0xb3,0x6d,0x47,0x69,0xe0,0x14,0xef,0xe5,0x5e,0x0a,0xe9,0x1a,0x8b,0x3f,0x67,0x1e,0x1c,0x37,0x86,0x25,0x02,0x52,0x3f,0xf5,0xde +.byte 0xe0,0xbe,0x1d,0x61,0x44,0x3d,0xd2,0xe9,0x26,0x3d,0x4b,0xa4,0xb1,0xb9,0x62,0xc5,0x70,0xfb,0x1d,0xaf,0xe6,0x19,0x97,0x0f,0x6e,0x6d,0x4e,0xdf,0x5f,0xc9,0xb2,0xb0,0xb9,0x4b,0x72,0xc7,0x60,0x5d,0xf8,0x7d,0x3b,0xd8,0x74,0x29,0xf2,0x56,0x25,0xd9,0xd9,0x12,0x3a,0x50,0x01,0x54,0xd3,0x0e,0x4c,0xbd,0xc9,0xf5,0x66,0xc4,0x4b,0xa2 +.byte 0x68,0x31,0xb1,0x9d,0x47,0xd8,0x28,0xce,0x6b,0xe4,0x5f,0x78,0x75,0x22,0x7d,0x44,0x08,0x71,0xfb,0xd8,0xa0,0x6e,0xd1,0xbd,0x64,0x4e,0x00,0x99,0xf7,0x85,0xad,0x31,0xde,0x5c,0x4c,0x7c,0xc3,0x89,0x49,0x9f,0xea,0x22,0x86,0xa0,0x48,0x48,0xcf,0x47,0xfb,0x68,0x04,0x4c,0x05,0x62,0x57,0x60,0x9b,0xa0,0x37,0x41,0x77,0xe4,0x7d,0x3e +.byte 0x36,0xda,0xd5,0xfd,0x68,0x47,0x8c,0x68,0x61,0x4c,0xea,0x38,0x20,0xa5,0xe4,0x12,0x6e,0xd5,0x14,0x37,0x01,0xcf,0xbd,0xdd,0x55,0x97,0xb4,0x30,0xf0,0x65,0x15,0xee,0x1f,0xc8,0x5b,0x07,0x82,0xae,0x43,0xad,0x11,0xda,0x0e,0x61,0x23,0x0a,0x5f,0x52,0xf9,0x9d,0xc5,0x98,0x4e,0xaf,0x77,0x21,0xc8,0x9f,0x6d,0x25,0x94,0x4f,0x91,0x1a +.byte 0xb4,0x2d,0xe3,0x15,0xe5,0xe6,0x25,0xb8,0x8e,0xd8,0x33,0xe3,0x05,0x01,0x7b,0x6b,0xa8,0x39,0x44,0x4b,0x58,0x3c,0x17,0x53,0x17,0x5c,0xbc,0xd5,0xcd,0xd4,0x29,0xe7,0x17,0x7a,0x69,0xa6,0x75,0x8e,0x0a,0x00,0x41,0xbe,0xb4,0x8d,0x79,0x1d,0xac,0x2a,0x0f,0x9b,0x7b,0x5a,0xe8,0x17,0xe2,0xb3,0x1d,0x03,0xde,0x5a,0x7c,0x31,0x18,0x8c +.byte 0x1c,0xf9,0x19,0x7b,0x37,0x1f,0x53,0x77,0xce,0x1f,0xad,0xb6,0x0d,0x21,0xe1,0xb0,0xf9,0x42,0x52,0x99,0x02,0xa8,0x58,0xab,0x94,0xf8,0x9f,0x99,0x2d,0x1e,0x68,0x4f,0x5a,0x91,0x2b,0xdf,0xe8,0xe6,0x34,0xb6,0x80,0x9b,0xb1,0x0e,0x87,0xec,0x29,0x17,0x4d,0x98,0x2d,0x40,0xd0,0xf7,0xca,0x55,0x9d,0x56,0x19,0xd5,0x7c,0x4e,0x2e,0x75 +.byte 0x5d,0xe7,0x3e,0xed,0x47,0xdc,0xb1,0x04,0xe5,0x61,0x0f,0xe7,0xc4,0x16,0x71,0xf4,0xf8,0x8a,0xf1,0xfc,0xd5,0xdb,0xeb,0x0b,0x82,0x0f,0xfe,0x64,0xa2,0xb0,0x53,0xab,0xf5,0x01,0xc2,0x8f,0xa0,0x4d,0x5d,0x1b,0x54,0x32,0x48,0xca,0x8a,0x42,0x59,0x4a,0x85,0x68,0x75,0xd1,0x1b,0x03,0x11,0xfe,0x28,0xd7,0xd5,0x37,0x81,0x7a,0xfb,0x84 +.byte 0xfd,0xa8,0x98,0x54,0xf7,0x81,0xb0,0x2d,0x2d,0x5d,0x95,0x0a,0x5b,0x80,0x13,0x95,0xad,0x8f,0x88,0xaa,0x38,0x7e,0xbc,0x88,0xc2,0xf6,0xa6,0x1e,0x6d,0x78,0xc9,0x4f,0xa9,0xb3,0xaa,0x23,0x0c,0x62,0x19,0x6f,0x26,0x5d,0xca,0x36,0x23,0xf8,0xd1,0x76,0x80,0x32,0x59,0xa0,0x47,0x86,0xee,0xc9,0x0f,0x1d,0x37,0xd9,0xc9,0x4e,0x65,0x22 +.byte 0x17,0x95,0x88,0x85,0xb3,0x8a,0x5d,0xb9,0xe6,0x3b,0x6c,0x02,0x81,0x61,0xe0,0xab,0x19,0x6c,0x9a,0x29,0x33,0xf1,0x7b,0x0c,0x22,0x16,0x0c,0xd6,0xfa,0xc2,0x84,0xe5,0x74,0x9e,0x8e,0xf8,0xdb,0x44,0x68,0xa0,0x58,0x52,0x9f,0xad,0xe6,0x2b,0x23,0x70,0xf3,0x6e,0xdc,0xf1,0x2d,0xa5,0xc2,0x7f,0xef,0x5f,0x58,0xc2,0x96,0x66,0x67,0x4b +.byte 0x7c,0xe0,0xd7,0x96,0xda,0xf7,0xd7,0x7a,0x7d,0xb4,0x4f,0x48,0xbd,0x87,0x6b,0xf4,0xbd,0xd1,0x45,0xdc,0xba,0x4f,0xd2,0x00,0x7f,0xde,0x3c,0x57,0xd7,0x3b,0x5b,0xa9,0xf3,0x17,0x76,0x47,0x0c,0xcf,0x48,0x07,0xa8,0xc3,0x30,0x60,0xc6,0x98,0x20,0x29,0xba,0x5f,0x76,0x6d,0x63,0x5f,0x87,0x7e,0x36,0xbc,0xa3,0xe4,0xd6,0x6a,0x55,0x73 +.byte 0x8b,0x8b,0x62,0x40,0xc5,0x7e,0xa3,0x33,0x04,0xce,0xe2,0x9d,0x9f,0x67,0x1c,0xf0,0xa1,0x78,0xd2,0x0b,0x58,0xc1,0x2e,0xec,0x78,0x0a,0xc9,0x0b,0x1d,0xfb,0xcc,0x72,0xd8,0xe4,0x15,0xcb,0x09,0x8b,0xd9,0x33,0xa9,0xb6,0x24,0x7e,0x59,0x48,0xbf,0xda,0xdb,0x5c,0x99,0xd1,0x92,0x1b,0xb6,0xf6,0x75,0x78,0x53,0x69,0x89,0x27,0x6b,0x3c +.byte 0xfb,0xd2,0xa7,0xeb,0xc5,0xf7,0xea,0x8b,0x38,0x59,0x8e,0x02,0xc7,0x6e,0x96,0x8a,0x85,0x1c,0x91,0x1b,0x97,0x97,0x9e,0xa7,0x9d,0x10,0xa4,0x4a,0x6e,0xa8,0x51,0x05,0xbe,0x5f,0x9a,0x5b,0x94,0xf2,0x2c,0xa1,0x1e,0x33,0xc5,0xe8,0x92,0xb8,0xd2,0xfa,0x27,0x07,0x12,0xa1,0xdc,0x24,0x43,0x28,0x06,0xe5,0x43,0x57,0x8f,0x66,0x72,0x2f +.byte 0x26,0xf7,0xea,0xa1,0xcf,0x57,0xd6,0xa6,0xf7,0x37,0x1d,0x6e,0xd9,0xde,0x1a,0x8c,0xf5,0x01,0x76,0xc3,0x56,0x40,0x57,0x3d,0x4a,0x14,0x04,0xf2,0xfc,0xba,0x3b,0x60,0xf1,0x88,0x1e,0x16,0x08,0x99,0x90,0xfe,0x27,0xaa,0x04,0x53,0xd8,0x7e,0x0c,0x58,0x6a,0xd9,0x5a,0xe4,0x11,0xd4,0xcc,0x48,0xbe,0x03,0x08,0xbc,0x61,0x47,0xdd,0xde +.byte 0x5f,0x03,0xc7,0x8f,0x9c,0x08,0x93,0xe3,0xaa,0xee,0x9c,0xe3,0xc6,0x06,0x78,0xda,0x0a,0xdd,0xb0,0xc3,0xf3,0x0b,0xe5,0xa0,0x5f,0x1e,0x3e,0xb3,0x15,0x7f,0xf1,0xf4,0x38,0xb2,0xed,0xf2,0xa6,0x8b,0x1d,0x78,0xb6,0x03,0x19,0xcd,0x17,0xb4,0x18,0x17,0x49,0x61,0x17,0xbd,0xbe,0x4b,0x04,0x00,0xce,0x4b,0xcc,0x47,0x61,0x76,0x85,0xdc +.byte 0x2b,0x85,0x48,0x82,0xf4,0x9b,0xb4,0x62,0x53,0xc7,0x06,0x50,0xf2,0x3e,0xba,0x6d,0xf2,0x19,0x0f,0x7f,0x84,0xce,0xa6,0x4d,0x96,0x97,0x94,0x12,0xb6,0xd0,0xd6,0xa4,0xc1,0xcc,0x14,0x54,0xf6,0x7a,0xf1,0x94,0x62,0xa1,0xc7,0x22,0x9b,0x0d,0x0e,0x69,0xcf,0x38,0x5c,0xda,0x9f,0xc0,0xfa,0x93,0x81,0x24,0xce,0x9f,0xf3,0xc2,0x66,0xad +.byte 0x06,0x21,0xf2,0x48,0x6c,0x4a,0x0d,0xb8,0x41,0x86,0xaf,0xb7,0x6c,0x65,0xcb,0x83,0xd8,0x75,0x11,0x60,0xfa,0x06,0xe5,0xd2,0x11,0x87,0x29,0xb8,0x41,0xcb,0x17,0xb5,0xbd,0xbd,0xf9,0xd5,0xbc,0x89,0xb6,0x60,0x65,0x59,0xbb,0x38,0x9d,0x70,0xf9,0x81,0x6b,0xe6,0x12,0x80,0x08,0x73,0x9f,0xfb,0x2f,0x72,0x4e,0x18,0xff,0x65,0xab,0xa6 +.byte 0xaa,0x78,0xf1,0xa4,0xe9,0x1a,0x7d,0xa5,0xdd,0x91,0x77,0xa9,0xa3,0xf3,0xe3,0xe5,0x5a,0xa2,0x0d,0x3a,0x2a,0x4a,0x11,0x9a,0x8d,0xc3,0x00,0x6e,0xd4,0x4f,0xb9,0xe7,0x39,0x78,0x89,0x64,0xb2,0xc8,0xfd,0x1f,0xe6,0xa9,0x54,0x17,0x83,0x3f,0xeb,0x97,0x77,0xac,0xc8,0xba,0x0e,0x77,0x02,0xb0,0x29,0xbe,0x51,0x62,0xef,0xa5,0xd5,0xab +.byte 0x79,0x98,0xab,0x7a,0x1e,0x13,0xe8,0x87,0x4f,0x61,0xa3,0x37,0xdf,0xe6,0xda,0xb9,0xf5,0x69,0xf7,0x7a,0xee,0xd6,0x5f,0x6a,0xb3,0x95,0x55,0x59,0xd1,0x6c,0x5b,0xd5,0xba,0x8b,0x74,0x85,0xbf,0x1e,0xe5,0xb3,0x24,0x28,0x4b,0xc8,0x4a,0xec,0xa1,0x1d,0xda,0x99,0x3f,0xdf,0xfc,0xe6,0x2e,0x1b,0xa4,0xba,0x1a,0x03,0x89,0xb7,0x93,0x4e +.byte 0xaf,0x40,0xb0,0x7e,0x3f,0x34,0x0d,0x94,0x75,0x8c,0x8a,0xfb,0x88,0xcd,0xd3,0xc2,0x61,0x95,0x63,0x51,0xaa,0x78,0x1f,0x24,0x95,0x5a,0xb5,0x98,0x9a,0xd4,0xb8,0x34,0xe1,0x47,0x1c,0x68,0x0f,0x08,0xf1,0x69,0xe6,0xd4,0xaf,0x23,0xf6,0x32,0x71,0x51,0x01,0xa9,0xf2,0xa1,0x45,0x0b,0x75,0x82,0x09,0xe4,0x9c,0x2a,0x1d,0x0b,0xd6,0xd2 +.byte 0x26,0xe8,0x30,0x44,0xdf,0xa3,0x2b,0x97,0x11,0xc7,0xe7,0x47,0xfd,0xc7,0xbf,0x59,0xf3,0x28,0x32,0x46,0xc0,0xc4,0x7a,0x96,0x08,0x0d,0x2c,0xa1,0x82,0x6c,0x0a,0x33,0x82,0x55,0xd7,0xcf,0x3e,0x08,0xbb,0x22,0x15,0x96,0x12,0x66,0xd2,0xae,0x21,0x3a,0x54,0x6a,0xe0,0x33,0x0c,0xa4,0x96,0x4b,0x5d,0xf2,0x86,0xb9,0x70,0xe4,0x65,0x45 +.byte 0xe4,0x2f,0xa7,0xb4,0xc1,0xd5,0x9a,0x02,0xa1,0x5b,0x4e,0x58,0xca,0xf8,0x63,0xae,0x45,0x1c,0xf4,0xa7,0xc8,0xa5,0x84,0x23,0x87,0xcb,0x3e,0x88,0xca,0xe9,0xa9,0x49,0xc5,0xc6,0x63,0x37,0x99,0xe0,0x27,0x03,0x96,0x7b,0x73,0x8c,0x36,0xde,0x89,0x80,0x30,0x2c,0x00,0x94,0x0b,0xfb,0x1f,0x39,0xe0,0xed,0xb6,0x31,0x21,0x90,0xfe,0xa4 +.byte 0xee,0xa5,0xe5,0x7b,0x9a,0x11,0x41,0x51,0xab,0x89,0x54,0xe0,0x8d,0x5f,0x10,0x1b,0x76,0x27,0x77,0x3d,0xb0,0x58,0x86,0x7b,0xb7,0x45,0xfb,0xd0,0x81,0xa8,0xcd,0xc0,0xc8,0x5f,0xfb,0xfe,0x8c,0x0a,0x3d,0x5d,0x61,0x4b,0x9b,0x32,0x75,0x66,0xa9,0xac,0x32,0x35,0xe9,0x1a,0xdf,0x06,0x8d,0x13,0x5d,0x40,0xcb,0x7d,0x50,0x3e,0x54,0xab +.byte 0x04,0xbc,0x83,0x32,0x8f,0xf5,0x93,0x1d,0x9b,0x5a,0xe1,0x19,0x70,0x4a,0xba,0xfc,0x4c,0x6a,0xf3,0xd6,0xd1,0xfd,0x48,0xd0,0x7c,0xa4,0xab,0x0b,0xb6,0x5f,0xe1,0x31,0xce,0x99,0x10,0x98,0xfc,0x6e,0x1c,0xaa,0x9c,0x34,0xa2,0x55,0xdc,0xe0,0x81,0x1b,0x9e,0xff,0x75,0x2e,0x25,0xe9,0x2c,0x20,0x83,0xf6,0x66,0xf9,0x63,0x31,0xfe,0xa7 +.byte 0xbf,0x4d,0xfd,0xff,0x0b,0x93,0x84,0xd4,0xb4,0x72,0x13,0x38,0x90,0x75,0xc9,0xff,0x61,0x4b,0xf9,0x55,0x62,0x58,0xf0,0x60,0xce,0x2d,0xec,0x94,0x06,0x0a,0xde,0x48,0xc0,0x46,0x89,0xfb,0x5c,0xf7,0x9f,0x37,0xad,0xd2,0xff,0xbe,0xfb,0x81,0x21,0xe0,0x20,0x43,0x88,0xad,0x40,0x47,0x7a,0xa9,0x30,0x88,0x10,0x16,0x41,0xf8,0x25,0xe0 +.byte 0x8f,0xc2,0xe3,0x9f,0x48,0xd3,0xfe,0x61,0x70,0xb9,0xa1,0x9e,0xaa,0xa6,0x73,0xcf,0xc3,0xd6,0xab,0x69,0x65,0x4a,0x3c,0xec,0x28,0x02,0x63,0x62,0xa1,0xb6,0xa3,0xd5,0x8c,0x9e,0x11,0x81,0x98,0x12,0x4f,0xec,0xb6,0xe5,0x3a,0x96,0xa1,0x11,0x13,0x77,0x5f,0x0f,0x19,0x40,0x14,0x28,0xcc,0xf1,0x3e,0x19,0x1d,0x78,0x31,0xac,0x5c,0xce +.byte 0xd7,0x29,0xfa,0x02,0x3b,0x29,0xd8,0x3a,0x37,0xcb,0x94,0xb2,0x38,0xc7,0x7f,0x3a,0x46,0xd2,0xb7,0xfe,0xfb,0x54,0x7c,0x01,0xa2,0x9b,0x53,0x57,0x04,0x73,0x4e,0x06,0x90,0xe5,0x78,0x0a,0x45,0x67,0x12,0x83,0xd7,0x31,0x59,0xa4,0x76,0xaa,0x7c,0xde,0x72,0x92,0x11,0x94,0x4c,0x6a,0xe4,0x35,0x35,0x3a,0x2e,0xef,0x7c,0xc1,0x91,0x76 +.byte 0xd0,0xfe,0x84,0xd1,0xa1,0xf9,0x03,0xc3,0xba,0x09,0xbb,0x2c,0xe2,0xb5,0x06,0x7e,0x23,0xb7,0xe0,0xc1,0xd3,0xfd,0x55,0x01,0xf3,0xba,0xc5,0x1b,0xf8,0x02,0x60,0x92,0x0a,0x93,0x1c,0xc4,0x19,0x03,0x88,0xf5,0x45,0xe5,0x8f,0x7d,0xce,0x2c,0x87,0x2e,0xf6,0x55,0x8c,0xf9,0xb0,0xd2,0x72,0x2d,0x93,0x6d,0x28,0x6e,0x8e,0x3a,0xed,0x68 +.byte 0x02,0xda,0x80,0xd0,0x71,0x4a,0x8f,0x06,0x59,0x38,0x89,0x81,0xcb,0x1a,0x74,0x1e,0x62,0xa3,0xa5,0xb8,0x85,0xc3,0xd2,0x04,0x3d,0x3b,0x93,0x36,0x0c,0x12,0x55,0xfb,0x7b,0xc8,0xa3,0x25,0xa7,0x93,0xb0,0x3e,0x49,0x86,0xbf,0x76,0x8f,0xc4,0x4c,0xfe,0xce,0x4a,0xf6,0x2f,0x15,0x33,0x06,0x3a,0x35,0x49,0xe7,0x08,0xff,0x99,0xac,0xf6 +.byte 0x20,0x6d,0xab,0xb2,0x05,0xa9,0xe4,0x06,0x57,0x9c,0xf4,0x76,0x8c,0x82,0x64,0xd5,0x67,0xe0,0xad,0xe1,0x69,0xdc,0x9e,0x2c,0x59,0x92,0x3a,0xc8,0xc1,0x0a,0x61,0x89,0x45,0x9f,0x8b,0xf8,0x64,0x0a,0x5a,0x75,0x55,0x37,0x24,0xe1,0x42,0x43,0x7c,0x9c,0xcd,0x4e,0x9e,0x19,0xfb,0xd9,0x15,0x29,0x30,0x52,0x33,0xf3,0xc8,0x88,0xdb,0xaa +.byte 0x07,0x27,0xfb,0x2b,0x0c,0xc0,0xa1,0x5f,0x51,0xf1,0x54,0xf8,0x90,0x0a,0x35,0x07,0x6e,0x9c,0x64,0xd8,0x4f,0x2d,0xb3,0x61,0xbc,0x18,0x1f,0x22,0x84,0x94,0x4b,0x85,0xfc,0x4a,0xf9,0xe5,0xfc,0xdd,0x7a,0x07,0xa2,0xbb,0xbe,0x7e,0x1f,0x4e,0xf9,0x29,0xb8,0xde,0x56,0xe9,0x04,0xc1,0xc2,0xb6,0xa8,0xc7,0xb6,0x83,0xf2,0x85,0x3d,0x35 +.byte 0xe3,0xeb,0x2f,0x2f,0x3c,0x1a,0x3a,0xf1,0x61,0x1f,0xe8,0xf0,0xce,0xa2,0x29,0xda,0x3f,0x38,0xf5,0x82,0x7a,0xb8,0x55,0xf1,0x1a,0x6e,0x5b,0x5c,0xd0,0xc8,0xc8,0x3a,0xe2,0xaf,0xb4,0x6f,0xba,0xe4,0x03,0x78,0x5f,0x47,0x4b,0xaf,0xfe,0x2a,0x7e,0x27,0xba,0x17,0xb4,0x92,0x27,0x70,0x13,0xd9,0xbb,0x6b,0x1c,0x9a,0x3e,0x29,0x85,0x9a +.byte 0xb7,0x64,0x5b,0x6d,0x7b,0xec,0xb2,0x26,0x3a,0x4b,0xb7,0x17,0xaf,0xb5,0xa1,0xbc,0x4d,0x67,0x4c,0x86,0xd1,0x53,0x2e,0x5d,0x64,0xe8,0x55,0xd9,0xbb,0xae,0xc1,0x55,0x41,0x99,0x8e,0x4d,0xed,0x3d,0x9e,0xea,0xe3,0xf2,0x76,0x45,0x6d,0xaa,0xbb,0x89,0x0b,0xc0,0x13,0xfe,0x99,0x2c,0xb0,0xd2,0xa9,0xeb,0x58,0x57,0x4d,0x88,0x2e,0x04 +.byte 0x4f,0x7a,0x76,0xaa,0x3a,0xa6,0x08,0x93,0x42,0x74,0x2f,0x3a,0x35,0xb0,0x36,0xcc,0x77,0xec,0x54,0x41,0x2e,0x81,0xf6,0x9f,0xf3,0xe7,0x23,0xc0,0x3f,0xa4,0x52,0x83,0x38,0xe2,0x12,0xed,0xdb,0x23,0xa0,0x0b,0xbf,0x61,0x98,0x89,0xb0,0xa4,0x3d,0xa9,0x6a,0x73,0xa1,0x99,0xc9,0x9e,0x68,0x45,0x37,0x4b,0x6c,0x87,0xfb,0x93,0xf2,0xaa +.byte 0xe8,0x1d,0x53,0x6c,0x4b,0xda,0xc5,0x6f,0xaa,0xde,0x99,0xd2,0xba,0x7c,0x27,0xc2,0x4e,0xd5,0x5b,0xc8,0x13,0x9e,0xa2,0x10,0x6a,0xbb,0x39,0xf9,0xa7,0x55,0x0a,0x65,0x88,0x3c,0x9b,0xff,0x83,0x4e,0xf7,0x9c,0x99,0x69,0xbd,0x64,0x0d,0xd1,0xc0,0xb0,0x43,0xd6,0x63,0x50,0x13,0x68,0x8d,0xd1,0x7e,0x56,0x93,0xb5,0x8e,0x8f,0x12,0xe5 +.byte 0x37,0x96,0x21,0x64,0xd5,0x0b,0xf6,0x27,0xf8,0xaa,0x34,0x8e,0xc4,0x2b,0x7b,0x6a,0x7c,0x89,0x4e,0x15,0x15,0x3d,0x17,0x93,0xd4,0x99,0xfe,0x97,0x95,0x20,0x85,0xcc,0xd4,0xcd,0x73,0x67,0x80,0x22,0x06,0xed,0x5e,0xce,0x90,0x59,0x01,0x31,0x24,0x17,0x37,0x4a,0x63,0x96,0xc2,0xf3,0xe0,0x21,0x0a,0x3b,0x9f,0x94,0xad,0xd6,0xa4,0xa9 +.byte 0xa2,0x54,0x0d,0x2a,0xb3,0x5c,0xfa,0xbe,0xeb,0x21,0xd6,0x13,0x22,0xa5,0x95,0x5e,0x25,0x72,0xf9,0x18,0x1f,0x50,0x64,0x04,0x5b,0xe8,0x0e,0x1f,0x6c,0xe1,0x4e,0xf5,0x7f,0xf0,0x13,0x4f,0xda,0x75,0xab,0x5a,0x98,0xd3,0x07,0x32,0x96,0x2a,0xc7,0x1e,0x0f,0x14,0xdb,0x96,0x5f,0xac,0xc1,0xef,0x5b,0x2d,0xd6,0x6d,0x13,0x01,0xd9,0x04 +.byte 0x9c,0xcd,0xe5,0x5e,0xbe,0x3a,0x47,0x14,0x09,0xbe,0x11,0xad,0x87,0x3f,0x0e,0xe1,0xcb,0x97,0xd0,0x6e,0x1f,0x49,0x07,0xd1,0x8c,0x2b,0xe0,0xf0,0xb2,0xaa,0x8b,0x70,0x18,0x7f,0x29,0xcc,0xc4,0x23,0x66,0x48,0xc4,0xb5,0x5e,0xf1,0x10,0xd7,0x1d,0x2a,0xba,0xe4,0x12,0x64,0x1d,0xf5,0x03,0x35,0x71,0x57,0x5d,0xf4,0xa4,0xb5,0x99,0x0b +.byte 0x4c,0x80,0x65,0x07,0x2f,0xbc,0xf7,0x28,0x8b,0xc0,0x8f,0x84,0x63,0x7e,0xf5,0x01,0x23,0x8c,0xaf,0x71,0x35,0xd4,0xe1,0x70,0xc7,0xef,0x1f,0x66,0xa9,0x34,0x57,0xaa,0x9a,0xbb,0x80,0x43,0x15,0x96,0xc4,0x03,0xd9,0xae,0xbe,0x89,0x1c,0xa1,0x9f,0x65,0x61,0xe5,0x90,0x9f,0xa6,0xf4,0x3b,0xde,0xa1,0xd1,0xf1,0xf9,0x2d,0xd7,0xa7,0x7e +.byte 0x3d,0x42,0x3d,0x1b,0x99,0xed,0x49,0x2e,0x92,0x6b,0x47,0x0e,0x0b,0x90,0x56,0xe0,0x1b,0x6b,0xfe,0x97,0xfe,0x9b,0xa2,0x50,0xcc,0xbf,0xea,0xae,0xe8,0xf0,0xc4,0xe5,0x81,0x20,0x4a,0xb0,0xf7,0xa5,0x23,0x24,0xf6,0x3f,0x9e,0x9c,0xcc,0xce,0xe4,0x95,0x49,0xea,0x66,0x4a,0x35,0x31,0xf3,0x03,0xc3,0x08,0xf9,0x5f,0x95,0x4c,0xbc,0x84 +.byte 0x13,0xbe,0x7f,0x35,0xbb,0xd7,0x35,0x3c,0xfb,0x05,0x43,0x95,0xbf,0x87,0xf2,0xc3,0x2d,0xef,0x13,0x1d,0x65,0x17,0x82,0x75,0x3d,0x67,0x51,0xcd,0x6e,0x42,0x5f,0x49,0x53,0x8b,0xaf,0x34,0x7d,0xa8,0xc1,0x45,0xcd,0x3d,0x29,0x00,0xa3,0xf3,0xbb,0x44,0x00,0x05,0x57,0xa5,0xeb,0xfd,0x98,0xa6,0xae,0xc6,0xc4,0x6c,0x6d,0x7d,0xf6,0x3e +.byte 0x82,0x1d,0x12,0xe7,0xcd,0xd2,0xd5,0xfe,0x41,0xf8,0xa4,0xb3,0x6a,0x04,0x13,0x28,0x10,0x40,0x27,0xc9,0x43,0x74,0xcf,0xaf,0x9b,0x60,0x17,0x43,0x8f,0xd7,0xb7,0x56,0x72,0xf3,0x48,0x0a,0xe6,0x36,0xf2,0x3f,0x51,0xf9,0x6e,0xc8,0xa3,0x04,0x8c,0x01,0x86,0x6e,0x83,0x27,0xe2,0xba,0xf2,0x8f,0x8f,0xa1,0x39,0xe7,0x17,0xdd,0x06,0x10 +.byte 0x0c,0x7f,0xfa,0x22,0x5d,0x88,0x35,0xc6,0xcd,0x60,0xa2,0xf0,0xfd,0xc9,0xed,0x85,0xac,0x88,0xfd,0x7d,0xc0,0x77,0x1b,0x80,0x3d,0x21,0x1e,0x8e,0x4d,0xdb,0x20,0xe2,0x38,0xad,0xd4,0xb5,0x2b,0x2b,0x31,0xbc,0x7b,0x02,0xa2,0x25,0x50,0xc0,0x01,0x20,0x76,0x6f,0x98,0x0b,0x3d,0x46,0xed,0xbb,0x2b,0x39,0x74,0x30,0xce,0x3e,0x6d,0x91 +.byte 0xa1,0x89,0x83,0xde,0x69,0x93,0x1a,0x14,0xa1,0xb0,0xaa,0x80,0xb0,0x1c,0x02,0x3f,0x13,0x9a,0x15,0x7f,0xb4,0x02,0x8f,0x30,0x0b,0xee,0xd9,0x72,0xcb,0x74,0x95,0x4a,0x39,0xb3,0x4e,0x78,0x12,0xb1,0x77,0x89,0xc0,0xaf,0x17,0xfd,0xc1,0x68,0x65,0xd1,0x08,0xae,0x56,0x5c,0xe0,0xe7,0x6f,0xb3,0x1e,0x10,0xce,0xd8,0xdf,0xee,0x67,0xad +.byte 0xd8,0x08,0xe0,0x79,0x36,0xe4,0x57,0x1c,0x45,0x22,0xa7,0x44,0xa8,0x12,0x37,0x92,0x85,0x9f,0x3a,0x48,0xd0,0xfd,0xb3,0x40,0x20,0x10,0xed,0x11,0xe0,0x9a,0xa6,0x09,0x5b,0xe9,0x21,0x95,0xe1,0x45,0x19,0x39,0xcc,0x85,0x5f,0xa5,0x6b,0x46,0x37,0xe1,0xa1,0x17,0x3f,0xb6,0xe9,0xb0,0x81,0x25,0xf6,0xd1,0xb8,0x22,0x5a,0x27,0x48,0x83 +.byte 0x01,0x36,0xd4,0xb8,0xc0,0x9f,0x37,0x52,0x22,0xd2,0x69,0x7b,0x3d,0xfb,0x31,0xc1,0xa3,0xb4,0xa1,0x1d,0x0e,0x24,0x9a,0xda,0x02,0x15,0x4b,0x46,0x24,0x0e,0xb1,0x79,0xc2,0x5b,0x01,0x60,0x4a,0x24,0x8a,0xbb,0x70,0xaa,0xf4,0x45,0xc1,0x0d,0x04,0x26,0x3f,0x74,0xbd,0xdd,0x33,0xaa,0xd6,0x62,0x56,0xb1,0xe7,0x2d,0x7b,0x66,0xa2,0x40 +.byte 0xb4,0xe4,0xbd,0x8e,0x35,0xba,0xf1,0x2f,0x59,0xa7,0x01,0x6d,0x5a,0xa7,0xa6,0x3b,0x82,0xa3,0xb4,0x54,0x51,0x33,0x6b,0xfb,0x78,0x4a,0x74,0x88,0x7f,0x55,0xea,0x08,0x8e,0x19,0x78,0xbc,0x80,0x19,0x2f,0x41,0x97,0x20,0xa0,0x9e,0xbf,0x44,0xae,0x2e,0x26,0x66,0xe3,0x25,0xa0,0x92,0xa9,0xbe,0x8c,0x0d,0x96,0xec,0x93,0x99,0xe2,0xe7 +.byte 0x81,0xd5,0x10,0x62,0x3a,0x97,0x38,0x51,0x36,0x11,0x00,0xe0,0xc1,0x3a,0xc5,0xd4,0xa5,0x19,0xf4,0x82,0x66,0x0c,0xf9,0xb3,0x04,0x3e,0x57,0xc3,0x43,0xab,0xc6,0x52,0x95,0x8f,0xd3,0xf1,0xde,0xd9,0x57,0x6d,0x32,0x4f,0xc7,0x8c,0x1b,0x7a,0x53,0x6a,0xcf,0x56,0xea,0x61,0xb4,0xe5,0x64,0x2d,0x02,0x26,0x5b,0xcf,0x1c,0xc7,0x37,0xc3 +.byte 0x41,0xd2,0x1b,0x6c,0x5b,0x47,0xb8,0x73,0x89,0xfe,0x0e,0x7a,0x35,0x05,0xfc,0xea,0x6a,0x34,0x74,0x69,0xf0,0x12,0x29,0xa9,0x33,0xce,0x93,0x15,0xa0,0x68,0xb3,0x46,0x43,0xdb,0x8d,0xfa,0xef,0x93,0x66,0x72,0x18,0xae,0xe4,0xab,0xf4,0x8a,0xd1,0xb5,0x42,0xbd,0x2d,0xda,0xcb,0xf6,0x44,0x25,0xb1,0x01,0x8a,0xff,0xd5,0x34,0x16,0xec +.byte 0x7e,0x38,0x7b,0x50,0x41,0x61,0xf9,0xdf,0x4c,0x3e,0x02,0xd6,0xc3,0xce,0x19,0x9f,0x12,0x45,0x0c,0x99,0xb1,0xd9,0xeb,0xb9,0xe3,0xd5,0xb6,0x2b,0x25,0x8c,0x0b,0x04,0xf8,0x8d,0x41,0x41,0x3d,0x39,0x1b,0x7f,0x88,0xa7,0x8f,0x61,0x30,0xfe,0x67,0x75,0x35,0xd1,0x41,0x90,0xda,0x73,0x80,0xcf,0xc9,0xf6,0x44,0x00,0x67,0xcd,0xca,0xaf +.byte 0x6d,0x84,0x39,0x9a,0xb2,0xbb,0xfc,0xac,0x9b,0xb2,0x95,0x2f,0xc9,0x06,0x3a,0xa4,0x7b,0x9a,0x25,0xc6,0xe5,0xdb,0x7a,0xc6,0x8b,0x84,0x6a,0xb7,0x1e,0x22,0xaa,0x10,0x96,0xd3,0x55,0x50,0xa2,0x02,0x04,0x69,0x92,0xd7,0x6b,0x1f,0x9b,0x45,0x07,0x71,0xda,0xdc,0x76,0xc5,0xb8,0x34,0xa2,0x32,0x33,0x16,0x2e,0xb0,0x2a,0x90,0x43,0x40 +.byte 0x92,0x77,0x74,0x4e,0xdc,0xb4,0xe2,0x7d,0xc1,0x57,0xaf,0xf4,0x2c,0x20,0x65,0x77,0x88,0xc9,0x6e,0x69,0x38,0xc8,0x19,0x95,0x32,0x54,0x59,0x7f,0x37,0xd7,0x3c,0x07,0x05,0x87,0x2b,0xf9,0x58,0x74,0xc7,0x61,0x13,0x3d,0xc2,0xd9,0xec,0x3b,0x36,0x9f,0x8e,0xae,0x52,0xdd,0x5c,0xaa,0x29,0x6b,0x31,0x34,0x48,0x61,0x34,0x62,0x56,0xce +.byte 0x25,0xa8,0xc0,0x62,0xf5,0x35,0x58,0x4d,0x8e,0x61,0xd4,0xae,0x25,0x50,0xee,0x45,0xdd,0x14,0x7d,0x46,0x81,0x47,0xc3,0x3f,0x3f,0x81,0xdb,0x9a,0x59,0x56,0x4f,0x45,0xed,0x9c,0xe2,0xfc,0x96,0xff,0x5d,0x37,0x70,0xad,0xd2,0xeb,0xd9,0x2d,0x2a,0xaf,0xb9,0x16,0x4a,0x79,0x5d,0x76,0xb5,0x8f,0x74,0x19,0x6f,0x74,0x7d,0x4a,0xee,0x83 +.byte 0xa5,0x81,0xf3,0xd5,0xa0,0x43,0x5e,0x46,0xba,0xbe,0x49,0xa8,0xce,0x72,0x36,0x32,0xcd,0x8c,0x9b,0xa0,0xf9,0x5d,0xb7,0xb9,0xc7,0x8c,0xb2,0x59,0xb4,0x44,0xc1,0x90,0x53,0x92,0xd2,0xa8,0x4c,0xf9,0x35,0x40,0x32,0xd1,0xf0,0x2f,0xcb,0x6a,0x0b,0xe0,0xbe,0x34,0xc9,0x82,0x18,0x8d,0xfb,0xfc,0x50,0x8d,0x67,0xd5,0x86,0xd4,0xf1,0xb1 +.byte 0xaa,0x2f,0x9c,0xbc,0x52,0xbb,0x9f,0x17,0x1c,0x74,0x1d,0xdf,0x2d,0x1a,0x94,0x43,0x9b,0x80,0xb9,0x48,0xa3,0xaf,0x4b,0x30,0x0d,0xd9,0x3f,0x11,0x48,0x79,0x60,0xcc,0x25,0x6a,0xdb,0x8a,0xda,0xab,0xda,0x09,0x7c,0x9c,0x4a,0xaf,0xf9,0x0d,0xfb,0x7a,0x92,0x61,0xa5,0x17,0xf8,0x79,0x1b,0x00,0x52,0x56,0x5e,0x27,0x22,0x37,0xf4,0xbe +.byte 0x52,0x36,0xd3,0xdc,0x9a,0x33,0xf5,0x44,0x0e,0x53,0x0b,0xf6,0x9b,0xb0,0xb6,0x11,0xe4,0xd5,0x45,0x2e,0xdc,0xdb,0x46,0x18,0x9a,0x90,0x8b,0xcc,0xfe,0xc6,0x94,0x4f,0x97,0xb9,0x42,0xb6,0xd3,0x8f,0x7c,0x20,0xd1,0xa8,0xe6,0x85,0xce,0x65,0xeb,0x95,0x38,0x11,0x5c,0x1a,0x9d,0x34,0x25,0xc2,0xf0,0x33,0xbb,0x2c,0xc9,0x8d,0x0a,0x7a +.byte 0xb1,0x90,0x9f,0x24,0xed,0x35,0x3c,0x7e,0x71,0x82,0x12,0x3a,0x79,0x29,0xc8,0xa7,0x3e,0xa2,0x4e,0x50,0x03,0x94,0x7a,0x94,0xb7,0x2b,0x61,0x95,0x3d,0x5e,0x60,0x1c,0x68,0x51,0x82,0x73,0xe0,0x4a,0x2a,0x48,0x26,0xda,0xa3,0x53,0x8c,0x83,0xba,0x9f,0x95,0x37,0x5e,0x68,0x54,0x19,0x21,0xf8,0x31,0xaf,0x6b,0xfc,0x3a,0x3e,0xe3,0x3f +.byte 0xdb,0x16,0xb5,0x7e,0x13,0xf8,0xfd,0x7f,0x36,0xd6,0x8e,0x33,0xaa,0xe9,0xa4,0xa7,0xfd,0xf0,0x32,0xa6,0xdf,0xfa,0x22,0x7d,0xff,0x2a,0xe6,0x0d,0x6f,0xe2,0x21,0x54,0x6c,0x1a,0x99,0x17,0x56,0xad,0xce,0x39,0x6b,0x1a,0xe8,0x27,0x13,0x12,0x9c,0x4b,0x84,0x69,0x73,0xde,0x44,0x14,0xb2,0x7c,0x44,0x54,0x91,0x4f,0xeb,0x83,0xec,0x04 +.byte 0x73,0x85,0xb1,0xa8,0x44,0x72,0xa7,0x77,0xaf,0x0c,0xe0,0x52,0x65,0x04,0xe7,0x2a,0xee,0x0c,0x20,0x83,0x32,0x34,0x17,0x00,0x61,0xf9,0xf5,0x42,0x03,0xa4,0xb8,0x02,0x6f,0xb2,0xd3,0x65,0x51,0x2a,0x8e,0xdf,0x28,0x78,0x8a,0x8a,0x00,0xfb,0x24,0xd6,0xd5,0x86,0xaa,0xfb,0x86,0x93,0x5d,0x11,0xa4,0xf3,0xfd,0x36,0x18,0xf3,0x61,0xea +.byte 0x33,0xa8,0x0c,0xf0,0xb4,0x68,0xee,0xd3,0xe3,0x4f,0x22,0x24,0xde,0x1f,0x29,0x84,0x8b,0x5b,0x73,0x15,0xd6,0x62,0xa3,0x71,0x7d,0xf0,0x65,0x36,0xca,0x68,0x8a,0x6d,0x61,0x9c,0x0d,0x53,0xdd,0xf4,0x12,0xb3,0x5f,0xf0,0xb1,0x86,0xd6,0xe2,0xd6,0x80,0x4a,0x01,0x09,0x99,0x65,0xdb,0xae,0xe6,0xfc,0x68,0x5b,0xf9,0x10,0x99,0x8b,0x9f +.byte 0x08,0x52,0x09,0xae,0x59,0x4d,0x6c,0xf9,0x91,0x2b,0x57,0xea,0xf0,0xa3,0xdb,0xb8,0x99,0x29,0x2f,0xab,0x95,0x01,0x7d,0xec,0xd8,0x77,0x73,0x75,0x4f,0x88,0x44,0x69,0x76,0xc9,0x3c,0xf0,0x2d,0x7b,0x0d,0xbe,0xd4,0x88,0x0d,0xbc,0xa0,0x52,0xf4,0x2a,0xd1,0x62,0x2a,0xa9,0xe2,0x41,0x2f,0x52,0xce,0x96,0x7d,0x65,0x9b,0x74,0x82,0xde +.byte 0x43,0x4d,0xf8,0x8e,0x77,0x1c,0x18,0xf5,0x7e,0xab,0x94,0x3e,0xe7,0x90,0x2b,0xa1,0x16,0x00,0x7f,0x9c,0x9d,0x86,0xd1,0x74,0x7e,0xf7,0xbd,0x5a,0xa7,0x2f,0x0f,0xb0,0x5c,0xfc,0xfb,0x59,0x00,0xf3,0x84,0x09,0x77,0x66,0x17,0xf6,0x5d,0x0e,0xe2,0xe2,0xd4,0xb3,0x9e,0x79,0x88,0x66,0xa5,0x8e,0x30,0xae,0xca,0x7e,0x2b,0x32,0xa2,0x89 +.byte 0xe9,0x7e,0x59,0x21,0xd5,0x99,0xc7,0x10,0xa8,0x6f,0x95,0x8d,0x84,0xb4,0xcf,0x61,0xe7,0x5c,0x09,0xf3,0xbc,0xeb,0xf6,0x0c,0x84,0x1a,0x8d,0x13,0xf8,0x49,0x22,0xeb,0x09,0x55,0xef,0x56,0x12,0x21,0xcb,0x61,0x87,0xbf,0xef,0x43,0x5b,0x82,0xa8,0xc2,0xa2,0x5e,0xad,0x54,0x9a,0xcc,0x95,0xa2,0x01,0x05,0xb2,0xbb,0x26,0xa8,0xfd,0x6b +.byte 0x66,0x95,0x9c,0x0b,0x7b,0x23,0x32,0xff,0xdd,0x6c,0x18,0x1e,0x77,0x01,0x3c,0x82,0xaa,0x97,0x28,0x0f,0x93,0xa5,0x6c,0x85,0xe5,0x94,0x40,0xe0,0xa3,0x01,0x57,0x56,0x43,0x40,0xdd,0xa9,0xaf,0x21,0x79,0x10,0x8b,0xff,0x4b,0x51,0xe4,0xa2,0xe5,0xd7,0x0c,0xe2,0x9e,0x1e,0x38,0xdb,0x64,0xe1,0xb1,0x5b,0xe5,0x40,0xab,0xf6,0x05,0xd2 +.byte 0xba,0x85,0x78,0x61,0x2d,0x2e,0x07,0x06,0x6d,0x86,0x59,0xaa,0xd9,0x2c,0xfb,0x83,0x34,0xd0,0x2d,0x1d,0xad,0x5f,0xe4,0xac,0x05,0x46,0x3a,0x7b,0xd9,0xef,0x9f,0x2b,0x0c,0x18,0x21,0xf1,0x24,0x8a,0xb4,0x6e,0xd2,0x98,0x75,0x08,0x96,0x0c,0x7b,0x41,0xb7,0xf7,0x1f,0xcd,0xa8,0x1f,0x44,0xb1,0xed,0xdc,0x0e,0xcb,0x94,0xa0,0xb8,0x62 +.byte 0x67,0xdc,0x24,0xde,0x9e,0xe9,0x89,0xcd,0x92,0x7c,0x91,0x15,0xff,0xbd,0xfd,0xee,0xf8,0x29,0xd7,0xf9,0xe8,0x51,0xe7,0xc8,0x21,0xc5,0x20,0xe4,0xb8,0xa6,0xdb,0xfb,0x09,0x65,0x1c,0x3b,0x9e,0x39,0x44,0xcf,0xf5,0xc2,0x7b,0xf3,0x14,0x7d,0x69,0xf2,0xd0,0x97,0x63,0xf1,0xa7,0x81,0x56,0xfb,0xdf,0x4d,0x83,0x55,0x4f,0xde,0x50,0x7d +.byte 0xfe,0xb0,0xc0,0xc8,0x3b,0x3d,0x78,0x74,0x58,0x74,0x5e,0xfc,0xb7,0x0d,0x9a,0x26,0x3b,0x39,0xb6,0xf7,0xe0,0xe4,0x12,0x3c,0xd6,0x88,0x1c,0x9b,0x51,0x89,0xe7,0x53,0xcd,0x24,0x2e,0x34,0xa2,0xee,0xfa,0x5a,0x87,0xe5,0x7e,0xd5,0xf2,0x2f,0x15,0x99,0x57,0x5d,0x31,0x02,0xf8,0x08,0x38,0xea,0x8c,0x30,0x21,0xb0,0xff,0x94,0x51,0xcf +.byte 0x23,0xb7,0x02,0x5d,0xa3,0x75,0x7f,0x9d,0x66,0x49,0xe5,0xbe,0xc7,0x06,0x5e,0x1d,0xc9,0xe2,0x82,0x8a,0xc4,0x17,0x83,0x7e,0x65,0x6d,0x85,0x26,0x66,0xc0,0xf4,0xa5,0x1c,0x6e,0xba,0x32,0xfa,0x41,0x7b,0x2b,0x64,0x98,0x58,0x8c,0xce,0x2f,0xf3,0x56,0xf0,0x67,0xef,0x73,0x79,0xc4,0xc2,0x07,0xd7,0x85,0x1d,0x75,0x38,0x1e,0x15,0x82 +.byte 0x9d,0xf3,0xdd,0x3a,0x72,0xa3,0x23,0x0e,0x4a,0x1a,0x3a,0x97,0xc8,0xf1,0xf1,0x58,0x5d,0x1f,0xae,0x6d,0xc8,0x03,0xe0,0x7b,0x0f,0xf5,0x6f,0x35,0x41,0x8d,0xd5,0x03,0x85,0xdd,0xeb,0x3d,0x73,0xb1,0x93,0x35,0xc0,0x0f,0xfb,0x42,0xd4,0xf1,0x6b,0x35,0xe2,0x96,0xc5,0xd9,0xf2,0x69,0xbb,0x70,0x5e,0xf0,0x0c,0xe6,0xb5,0x81,0x94,0xc9 +.byte 0x29,0xa1,0x34,0x89,0xd9,0x9c,0x49,0x01,0x37,0x56,0x16,0x30,0x47,0x6f,0xe4,0x7c,0x5b,0xdd,0xfb,0x80,0x7f,0x0c,0x38,0x53,0x3d,0x57,0xf7,0xc4,0x80,0xf9,0x12,0x3a,0x9f,0xf9,0xb0,0xb6,0x94,0x6d,0xde,0x41,0x4e,0x30,0xac,0x1f,0x25,0x34,0xa0,0x95,0xe8,0x00,0x86,0x32,0x40,0xbb,0xc1,0x49,0x2d,0x07,0x49,0xb8,0x5f,0xcd,0x1b,0xd3 +.byte 0x0e,0x0c,0x54,0x0f,0xe4,0x20,0xe5,0xa1,0xed,0x98,0x65,0x5a,0xe7,0xce,0x68,0x9c,0x4c,0x48,0x03,0x9c,0x5b,0x68,0x4b,0x75,0x71,0x11,0x40,0x69,0xca,0x9a,0x3a,0xb2,0x3d,0x35,0x2c,0x70,0x35,0x8b,0x80,0x53,0x86,0x30,0x7d,0x4c,0xe9,0xc0,0x30,0x60,0xd0,0x06,0xbe,0xc2,0xad,0x39,0xcc,0xb2,0xec,0x90,0xcc,0xbd,0x7c,0xb5,0x57,0x20 +.byte 0x34,0x2e,0xfc,0xce,0xff,0xe3,0xd9,0xac,0xb8,0x62,0x6b,0x45,0x22,0x34,0xdf,0x8e,0x4b,0xf1,0x80,0x28,0x8d,0x0f,0xd5,0x3b,0x61,0x3e,0x91,0xa1,0xb1,0x85,0x27,0x78,0x88,0xbc,0xc4,0xb1,0xa1,0xbe,0x4f,0xc3,0xfd,0x1f,0xb9,0x30,0x31,0x2f,0xc1,0x9d,0xa3,0xb6,0x29,0xa4,0x60,0x82,0x73,0x93,0x74,0xea,0x97,0x67,0xf2,0xa3,0x97,0x50 +.byte 0x2f,0x9f,0x7b,0x23,0x18,0xb6,0xb4,0xee,0x15,0xa0,0xa4,0x07,0x1a,0xe9,0xb6,0x63,0x7e,0x88,0x40,0x57,0x86,0x79,0x6b,0x75,0xbe,0x57,0x8f,0xfe,0x0d,0xdf,0x4c,0x7f,0x39,0x9a,0x97,0xa6,0x87,0xc5,0xfd,0x52,0x77,0x36,0xc9,0x66,0x63,0xcf,0xc7,0x34,0x3b,0xf4,0x7a,0x12,0x56,0xf0,0xbc,0x7a,0x1a,0xa2,0xa2,0x51,0xb8,0xc1,0x70,0x81 +.byte 0xcf,0x1d,0xb5,0xe2,0x82,0xbb,0xfc,0xa3,0x80,0x18,0xf8,0x4b,0x76,0x9c,0xdf,0x9d,0x6c,0xf1,0xd8,0x2a,0xab,0x0c,0x12,0x02,0x29,0x09,0xfd,0x28,0xfb,0x57,0x38,0x05,0x2c,0xc5,0x67,0xd1,0xaa,0xbc,0x98,0xe6,0x22,0x78,0x06,0x4f,0x69,0x6a,0x63,0x1a,0x13,0x0b,0xa5,0xd2,0x61,0xc7,0x45,0x5b,0x21,0xab,0xbf,0x7b,0x7f,0x8c,0x2c,0xba +.byte 0x93,0x9f,0x41,0x67,0xc4,0x5f,0x53,0xac,0x90,0x05,0x86,0xb5,0x80,0x1f,0x5b,0x35,0x4f,0x92,0xf5,0xa8,0x5f,0xfb,0x56,0xdd,0x2d,0x9b,0xea,0xcb,0x0f,0x98,0x3c,0x4e,0xf1,0xa5,0x2c,0x37,0x70,0xe3,0x5c,0xaf,0x96,0x36,0xa8,0x2a,0xec,0xe0,0x2c,0x00,0xcd,0xaf,0x03,0x1d,0x05,0x2f,0x8c,0xe7,0xfe,0x4d,0xe9,0x97,0x6d,0xe1,0xf9,0x23 +.byte 0x60,0x08,0xea,0xfb,0x27,0xc8,0xf9,0xdf,0x49,0xfe,0xd9,0x48,0x35,0x6b,0x43,0xc5,0x19,0x90,0xb1,0xf1,0xee,0x84,0x7a,0x57,0xfa,0xa5,0xd6,0xd8,0xc9,0xf0,0x8a,0xe7,0x13,0x84,0xfc,0x28,0x54,0xae,0x99,0xfd,0x91,0xbe,0x91,0x27,0x98,0x28,0xdc,0xd7,0x2e,0xc1,0x21,0xcb,0x31,0xf8,0x47,0xe6,0x77,0x6d,0xee,0x7b,0x12,0xe4,0x9e,0x9d +.byte 0x07,0x46,0xa9,0x15,0x0b,0x3c,0xbe,0xc7,0x2d,0xe5,0xd6,0x25,0x4c,0xea,0x61,0xdc,0x18,0xb2,0x9d,0xb0,0x9a,0xff,0xa3,0x5f,0x2b,0xab,0x52,0x7d,0x1b,0xc3,0xa3,0x41,0x8f,0x5a,0x29,0xbd,0xc4,0x56,0x54,0x43,0x2d,0x61,0x07,0xed,0xd1,0x81,0x45,0xdb,0x61,0x0f,0xda,0xea,0xa6,0x1e,0xf9,0x9c,0xc0,0x8c,0xc4,0x8e,0xc7,0xca,0x38,0xe2 +.byte 0x45,0xde,0xdc,0xc5,0xc6,0xb0,0x43,0x17,0x8b,0xb1,0x58,0xd1,0x10,0x8e,0xa5,0x17,0x37,0x85,0xca,0x61,0x67,0x5c,0xd0,0x72,0x22,0x6b,0xd3,0x3b,0x53,0xbc,0xfb,0xe1,0x1e,0xa4,0x1b,0xd3,0xc3,0x8a,0x50,0x03,0x39,0xf5,0x36,0xdf,0x51,0x2e,0x05,0x4a,0xa8,0xdb,0x91,0x87,0xae,0xfe,0x3f,0x5c,0x35,0x5e,0xf9,0x8f,0x43,0x9e,0x92,0x36 +.byte 0x91,0x27,0x90,0xe8,0x7c,0xcc,0xc4,0x9c,0x13,0xbb,0x61,0x40,0xec,0x4f,0x49,0xcf,0x04,0x38,0x77,0x3b,0xb5,0xf8,0x69,0x8d,0xbb,0xb2,0x30,0x32,0x42,0x4d,0x7d,0x6c,0x56,0xdc,0xf4,0x8f,0xfc,0xb8,0x53,0xc5,0x11,0x17,0x23,0x94,0xf9,0x6d,0x6f,0xee,0xee,0x31,0xbf,0xce,0x11,0x8b,0x9e,0xd7,0xa5,0x09,0x36,0x89,0x72,0x25,0x18,0x1f +.byte 0x13,0xa7,0xdf,0xc5,0x91,0x7e,0xd6,0x2b,0xb8,0x08,0x9c,0x12,0x83,0x21,0x97,0x3d,0xad,0xac,0x1c,0x54,0xf3,0x65,0x04,0x2f,0x09,0xd1,0xd2,0xe5,0xce,0x24,0xb1,0xd9,0xe4,0x38,0x1f,0xb4,0xce,0xea,0x27,0x7f,0x5f,0x16,0x52,0xa4,0x2f,0x2f,0xaf,0x91,0xec,0x7a,0x21,0xf7,0xa1,0x38,0x78,0x78,0xc5,0xa9,0x94,0x63,0x87,0xf8,0x95,0x9e +.byte 0xf9,0x82,0x98,0x6d,0x9d,0x48,0x80,0xaa,0x7a,0x36,0xf9,0x5f,0xfb,0x39,0x3d,0xae,0xbc,0xcd,0xfc,0x67,0x46,0x07,0x7e,0xdf,0xef,0xff,0x8d,0x67,0xe7,0xd9,0x60,0x90,0x7b,0x49,0x10,0x65,0x3a,0x60,0x87,0x7a,0xed,0x9a,0x44,0x48,0x81,0xcc,0xad,0xe4,0x6a,0x62,0xf8,0x02,0x6f,0x41,0x8a,0x8d,0x44,0x28,0x1a,0xb8,0x52,0x60,0x4b,0x3f +.byte 0xfc,0xdd,0x33,0xad,0x14,0xb1,0x34,0x63,0x1f,0xdc,0xeb,0x9a,0x3f,0x99,0x82,0x28,0x36,0x6f,0x8e,0xd7,0x39,0x2e,0xc0,0x37,0xfb,0xad,0x57,0x6c,0x82,0x1a,0xc6,0xe4,0x4b,0xca,0x00,0x68,0x57,0x34,0xf0,0x57,0x6a,0xcb,0x50,0x5d,0x8d,0xfa,0xcd,0x89,0x41,0x91,0x23,0x98,0x1f,0x4f,0x18,0xb6,0xd2,0x9d,0xde,0x2f,0x5c,0xe6,0x08,0x76 +.byte 0x97,0xba,0x24,0x4e,0x84,0xd7,0xeb,0x80,0xde,0xec,0xee,0x51,0x5a,0x0e,0x5f,0xb7,0x37,0xda,0xa5,0x94,0x2b,0x6d,0x73,0xb7,0x6c,0x22,0x95,0x3a,0xaa,0x5c,0x6f,0x89,0x90,0xec,0xb3,0x31,0x00,0x37,0x28,0x18,0xbb,0x98,0x23,0xfc,0x3e,0x21,0x7c,0xaa,0x44,0x54,0x7b,0xe6,0xa0,0x17,0x58,0xef,0x11,0x3f,0x48,0xb8,0xa8,0x15,0x4a,0x92 +.byte 0xa9,0x39,0xe2,0xa6,0x38,0x03,0xa6,0xd3,0x79,0x8b,0x38,0x06,0xaf,0x4b,0xd4,0xab,0x0a,0x13,0xff,0x2d,0xfa,0xab,0x4b,0x64,0x9e,0xb0,0x3d,0xba,0x18,0x01,0xfd,0xc3,0x6a,0x6f,0x21,0x9c,0xf5,0x2f,0xab,0x2d,0x42,0x12,0xc9,0x72,0xde,0x83,0x42,0x6a,0xf0,0xd4,0x96,0x73,0xf1,0x93,0xa3,0x2d,0x9b,0xb4,0x94,0x51,0x0c,0x6e,0x8e,0xf0 +.byte 0x5e,0xbf,0x98,0xbf,0x08,0x0f,0xd8,0x6c,0x65,0x4e,0xb5,0x47,0xeb,0x7c,0x1b,0x73,0xe0,0xe6,0x2c,0x03,0xd2,0x2a,0x32,0xff,0xa7,0x03,0x6d,0x38,0x47,0x56,0x4b,0x25,0x0b,0x39,0x73,0x87,0x4b,0xa5,0x12,0x79,0x79,0xf3,0x88,0x37,0xe2,0x4f,0xb8,0xbf,0x70,0x0e,0xf7,0x8c,0xe6,0xa3,0xbc,0x35,0x10,0xcd,0x72,0x56,0xd6,0x83,0xc1,0x0b +.byte 0x5b,0xf3,0xa8,0x74,0xc7,0xb9,0x84,0xc8,0x6c,0xff,0x66,0xad,0x95,0x6f,0xbc,0x82,0x84,0x2a,0x11,0x40,0xf9,0xa8,0x3f,0x05,0xf9,0xab,0x19,0x55,0xce,0x80,0x90,0x65,0x49,0x3d,0xe1,0x54,0x2c,0x1a,0xdb,0xf3,0xaa,0x2f,0xeb,0xf5,0x10,0x1f,0x8c,0x35,0x46,0x68,0xb1,0x4c,0x52,0xe7,0xe9,0x58,0x78,0x33,0xfd,0xc6,0x13,0x0e,0x69,0xae +.byte 0xf4,0x1a,0x8a,0x77,0x8f,0xcc,0x98,0x74,0x88,0x20,0x84,0x5b,0x83,0x54,0xa9,0xee,0xc2,0x0f,0x8a,0x46,0xb1,0xc7,0xfb,0xfd,0xf2,0x2c,0xaf,0xfa,0x72,0x34,0x7a,0x79,0x50,0x10,0xc6,0x04,0xfd,0x0a,0x1e,0x4a,0xb5,0xf5,0xe7,0x4d,0x98,0x80,0x5d,0x0b,0x81,0x23,0xc3,0x6e,0xbf,0xc8,0xcd,0x35,0x96,0x5a,0x58,0xec,0xef,0x6a,0x8d,0x48 +.byte 0xda,0x48,0xbb,0x8f,0xcc,0x1f,0x86,0xff,0x7a,0x27,0xef,0xe6,0xb7,0xc7,0x2a,0x47,0x8d,0x6c,0x4a,0xc6,0x0a,0x32,0x67,0x1d,0x2f,0x83,0x3d,0x46,0x41,0x46,0x1c,0x75,0x7b,0x29,0x89,0xa2,0x65,0x9b,0x53,0x3d,0xd9,0x90,0x83,0xce,0xab,0x07,0xbb,0x46,0x61,0xb1,0x54,0xbd,0xc9,0x98,0xf7,0x96,0x76,0x03,0xdc,0x1f,0x1b,0xf2,0x5c,0x07 +.byte 0xdd,0x24,0x94,0x72,0x1e,0x94,0xb1,0x14,0x0b,0x40,0x77,0xde,0x3d,0x3f,0x1c,0xf0,0x8f,0xa4,0xcb,0x34,0xb5,0x2b,0x72,0x53,0x78,0xf3,0x3f,0x8e,0x47,0x30,0xb2,0x7e,0x73,0x3f,0x9a,0xef,0x19,0xb1,0xef,0x82,0x99,0xd4,0x17,0x60,0x94,0xf6,0x15,0x75,0x50,0x1f,0xb3,0xdd,0xae,0x1f,0xf8,0x63,0x9a,0x30,0x2c,0xf0,0xdd,0xbf,0x49,0x70 +.byte 0xd7,0x86,0x4a,0x5c,0x46,0x10,0x48,0x46,0x02,0x18,0xa4,0x39,0xb6,0x75,0x11,0x21,0xae,0x62,0x64,0xd8,0x85,0xc8,0xda,0xd2,0xd6,0x69,0xcc,0x37,0x57,0x49,0x73,0x1a,0x10,0x7b,0xd7,0x58,0xdd,0x0b,0xf3,0x16,0xe7,0x62,0x2c,0x32,0x92,0x0e,0x70,0x6f,0x77,0x74,0x0d,0xff,0xc2,0x8d,0x3b,0x3f,0x29,0x28,0x8f,0x88,0xb8,0x02,0x5b,0x3a +.byte 0x8b,0x65,0x89,0x92,0x2f,0xc7,0x30,0x73,0xc3,0x20,0xbc,0xa4,0xe4,0x5e,0xea,0xf8,0x21,0xb6,0xc5,0x47,0x56,0x35,0x8f,0xf6,0xd5,0xdd,0x77,0x1d,0xdf,0xd0,0x27,0xa3,0x04,0xb9,0xd0,0xc4,0x28,0x16,0xa5,0xaf,0x47,0x55,0x85,0x93,0x38,0xf4,0xac,0x13,0x30,0x7d,0x77,0x1f,0x3d,0xd5,0xd7,0x22,0xbe,0xe2,0x4e,0x6d,0x4b,0x0e,0xbe,0x1d +.byte 0x43,0x79,0x34,0x95,0x6f,0x38,0xa1,0xb3,0xa0,0xed,0xf6,0x17,0xf4,0x24,0x70,0x26,0x18,0x3e,0x1c,0xde,0xdc,0xa9,0x67,0x12,0xd3,0xc8,0xd7,0x70,0x13,0xa5,0xb3,0x25,0xe1,0x0a,0xe9,0xf6,0x4e,0x56,0x82,0x17,0xdc,0xbc,0x96,0x2f,0x59,0x03,0x9b,0xf4,0xc3,0x66,0xd2,0x90,0x95,0x1d,0xe0,0x99,0xfb,0xd8,0xa8,0x14,0xc7,0xa6,0x12,0x6b +.byte 0x08,0x6a,0xc8,0x0f,0x34,0x2a,0xb6,0xc4,0x9a,0xcd,0x61,0xf7,0x61,0xa3,0x59,0x29,0x11,0x30,0x76,0xb5,0x97,0xbc,0x2f,0x87,0xd8,0x12,0xb3,0x1d,0x99,0x8d,0x5d,0x57,0x0c,0xda,0xb0,0x9f,0x51,0x1a,0xb5,0xc6,0x94,0xc3,0xe9,0x5a,0x72,0x0c,0x37,0x76,0xb6,0x3c,0x00,0x02,0x69,0xad,0x8e,0x66,0x8b,0x5c,0x13,0x48,0xb7,0x9e,0xc5,0x7e +.byte 0xe0,0x35,0x07,0xd2,0x04,0x9c,0x35,0x95,0x8b,0x55,0x87,0x03,0x32,0x36,0xeb,0x11,0x88,0x54,0x8d,0x3e,0x88,0x46,0xc2,0xfe,0x24,0xa4,0x4b,0x92,0x19,0x44,0x6c,0xc9,0x69,0x32,0x22,0x95,0x5b,0xda,0x58,0xa4,0x00,0x33,0x83,0x2d,0xa4,0x17,0x2e,0x00,0x4d,0x9a,0x7d,0xef,0x04,0xa8,0x8b,0xf2,0x7c,0xb9,0xdb,0x54,0xcf,0x63,0x14,0x52 +.byte 0x5b,0x79,0xf6,0x89,0x5c,0xfa,0x8a,0x85,0x88,0x7f,0xca,0xed,0xfb,0x62,0xbc,0x1d,0x0d,0x90,0x51,0x27,0x45,0x74,0xa0,0x55,0xfc,0x60,0xea,0xef,0x6e,0x40,0xeb,0x0b,0x61,0x45,0x44,0xee,0xb6,0x20,0x4c,0xe1,0x08,0x62,0x29,0xdd,0xd0,0xa1,0xd5,0x7f,0x42,0xb9,0x0f,0x12,0xef,0xfb,0x13,0xa2,0xf1,0x85,0xaa,0x56,0x18,0x6c,0x70,0x7a +.byte 0x4d,0x52,0x76,0xce,0xa9,0xed,0x0a,0xcc,0x55,0xf0,0x01,0x99,0x44,0xe9,0xc4,0x74,0x33,0x2a,0xce,0x53,0xf3,0x4f,0x8f,0x1c,0x67,0x39,0x2b,0x0e,0x46,0xe2,0x49,0x06,0x52,0xbf,0xc4,0x3f,0x93,0x84,0x46,0x0a,0x9b,0xcb,0x1d,0xa5,0x66,0x9c,0x3e,0x3d,0xd1,0x92,0xda,0xe2,0x11,0x5b,0x89,0x7a,0xc4,0x33,0xba,0xa9,0x19,0xfd,0x3c,0xe3 +.byte 0xf0,0xa0,0x9b,0x83,0x50,0xce,0xa9,0x62,0xe3,0x85,0xc6,0xc4,0xe5,0x22,0xbb,0x1a,0x8e,0x04,0xb5,0x4d,0xca,0x18,0x7d,0xb0,0x99,0x50,0x78,0x88,0x69,0x43,0xe0,0xfd,0x90,0xa6,0xbf,0xdc,0xe3,0x03,0xf2,0x5d,0xa1,0xa2,0x88,0xc7,0xab,0xa9,0xc2,0xda,0x3f,0xff,0x79,0xa6,0x07,0xfd,0xc4,0xb1,0xfb,0x47,0x3d,0x75,0x82,0x26,0x52,0x85 +.byte 0x3f,0xf9,0xc9,0x85,0x46,0x24,0xe9,0x0f,0x96,0x8c,0xbb,0x02,0x83,0x60,0x69,0x49,0x8c,0x38,0xd1,0x4e,0xd0,0x63,0x2c,0xb6,0x12,0xb2,0x8e,0x4b,0xd3,0xe3,0xdf,0x20,0x00,0x99,0xf1,0x06,0x93,0xbf,0x27,0x42,0x8b,0xe3,0x8d,0x4c,0x3b,0x05,0x62,0x64,0x21,0xb1,0xfe,0xce,0x08,0xd2,0x23,0x69,0x11,0x74,0x31,0x3a,0x90,0x10,0x07,0x1a +.byte 0xd5,0xf5,0xc2,0x09,0x61,0x67,0x65,0x99,0x3a,0xf3,0x9e,0x4a,0xd8,0xa1,0xb2,0x50,0xf4,0x07,0xf0,0x7b,0x89,0x6d,0x4d,0x6a,0xd4,0x54,0xb9,0x3c,0xd5,0x4e,0x1c,0x12,0x0f,0x19,0x92,0x97,0x21,0x65,0x83,0x33,0x20,0x92,0x95,0xd4,0x0e,0x78,0xf4,0x92,0x16,0x36,0xd8,0x1b,0xd8,0xbf,0x41,0xe4,0xfb,0xb9,0x81,0x26,0x72,0x7e,0x1b,0x58 +.byte 0x05,0x45,0x97,0x66,0xf2,0x23,0x16,0xca,0x4e,0x95,0xc2,0x6c,0x60,0x84,0x5f,0x77,0x82,0x44,0x0e,0xf7,0x30,0xaa,0x51,0xa9,0x85,0x8b,0x03,0xfc,0x3d,0x6d,0x66,0x91,0x37,0xa5,0x1c,0xf8,0xcf,0x9d,0xd8,0xcd,0x8c,0xa1,0x29,0xbd,0xb5,0x4f,0x47,0xba,0xd1,0x55,0x3b,0x4e,0xc9,0xce,0x4c,0xcf,0x2e,0x19,0xa0,0x95,0xe6,0xcb,0x36,0x97 +.byte 0x3e,0x23,0xbe,0x09,0xfd,0x38,0x47,0x00,0x03,0xec,0x49,0xbb,0x49,0x1f,0x45,0x84,0x0f,0x1e,0x74,0xab,0xc9,0x07,0x00,0x04,0x70,0xe9,0xbd,0x61,0xb1,0x92,0xee,0x67,0x9a,0x5e,0x90,0xdc,0xe7,0x99,0x36,0xd0,0x58,0x15,0xe5,0x15,0xa2,0x1d,0x61,0x18,0x39,0x5f,0x6c,0xc7,0xbe,0xd0,0x23,0x1e,0x41,0xc8,0xaa,0x8e,0xbf,0xb8,0xdb,0x90 +.byte 0x8c,0x60,0x07,0x1e,0xe9,0x6c,0xe4,0xde,0xec,0x73,0x34,0x94,0x54,0xa4,0x6b,0x49,0xcf,0x87,0xb5,0x88,0x98,0xe6,0x2c,0xce,0xb7,0x76,0xa5,0x29,0xf1,0x29,0x50,0xc5,0x9e,0x13,0xe4,0x61,0x6a,0x54,0xb2,0x26,0xfa,0xfa,0x4a,0x41,0x3b,0x0a,0xf5,0x9a,0x60,0xbb,0xfc,0x1e,0x5d,0x21,0x7e,0x91,0x51,0xd6,0x5e,0x92,0xf9,0x21,0x80,0xa8 +.byte 0x35,0xc0,0xbb,0x7a,0xeb,0x75,0xb4,0xa3,0xd3,0x8d,0xaf,0x07,0x53,0x65,0x36,0x11,0xf9,0xb6,0x69,0x29,0x1e,0x5d,0x8f,0x57,0x5d,0xed,0x42,0xf9,0xd5,0xf6,0xc3,0x1e,0x29,0xc4,0x49,0x04,0xe4,0xfb,0xbf,0x9b,0x4a,0x7b,0xdd,0x57,0x51,0xfe,0xc4,0xd1,0xd9,0xe9,0x8f,0x94,0x78,0xbc,0x5c,0xeb,0xb6,0xbc,0x51,0xb0,0x82,0x87,0x47,0xb4 +.byte 0xf7,0xf9,0x02,0xd7,0xac,0x23,0xc0,0xe5,0x9a,0xc3,0x2f,0xd2,0xb8,0xb2,0x62,0xb9,0xdb,0x49,0x85,0x77,0x92,0xa6,0xe5,0x24,0x43,0x4d,0x0d,0x67,0x94,0x01,0x29,0xd6,0x2e,0xee,0xd9,0x2e,0x97,0x0e,0x20,0x7f,0x84,0x19,0x3c,0x3a,0x6f,0xa5,0xb0,0x8b,0x8f,0x8d,0x96,0xbb,0x76,0x61,0x97,0xc2,0x65,0x83,0xd8,0xda,0xab,0x42,0xfa,0xe5 +.byte 0x1e,0x42,0x93,0xa7,0x66,0x03,0x06,0x3b,0xbe,0xb8,0xae,0x71,0xee,0xdb,0x5d,0xdf,0x40,0x64,0x17,0x17,0x2e,0x03,0xca,0x37,0x2a,0x71,0x92,0x0a,0x01,0xa3,0x0f,0x0b,0x09,0xf2,0x0e,0x4b,0x4d,0x18,0xf3,0xc4,0xf2,0x51,0x7b,0x53,0x30,0xab,0x24,0xa2,0x47,0x38,0xc9,0x2c,0xdf,0x0d,0x32,0x3e,0x3f,0x57,0x2d,0xfc,0x44,0x19,0x64,0x8b +.byte 0xe9,0x9a,0xc2,0xf2,0xf6,0x2d,0x30,0x0c,0x0f,0xc3,0xc3,0xfe,0xc2,0xd1,0xbc,0xe0,0xbf,0xaf,0xeb,0x40,0x64,0x28,0xe2,0xd9,0x3c,0x7e,0x24,0x94,0x8f,0xe8,0x54,0x8b,0x26,0x6b,0xe1,0x4e,0x44,0x5a,0x7d,0x7b,0x12,0x36,0x2c,0x12,0xad,0x26,0xbc,0xa7,0xa3,0x2b,0x25,0xb9,0xde,0xe6,0x64,0x2d,0xab,0x7f,0x15,0x22,0x51,0x26,0x1c,0x15 +.byte 0x5d,0x13,0x18,0x93,0xc1,0x19,0x65,0xca,0xf3,0x8b,0xe0,0xcf,0x8c,0x43,0xe9,0xfd,0xa1,0xbd,0xe9,0xde,0x78,0x26,0xcb,0x7c,0xdc,0x68,0x06,0x98,0xf6,0x90,0x44,0x40,0xf0,0x5e,0xe1,0x16,0xf5,0x5d,0x4d,0x9b,0x85,0xe6,0x26,0xbd,0xab,0xcc,0x46,0x62,0x18,0x51,0xd5,0x3c,0x9f,0x6e,0xfa,0xe7,0x94,0xfc,0xc2,0x1a,0x9d,0x63,0x2c,0xdc +.byte 0xc3,0x89,0x67,0x94,0x37,0x58,0x0d,0x13,0xb8,0xdf,0x41,0x3d,0x70,0x78,0x1e,0x61,0x75,0x77,0xcc,0xbf,0x5f,0xa8,0xd3,0x89,0xcc,0xd3,0x40,0x4e,0x65,0xbd,0xce,0x3c,0xf0,0x5a,0x8f,0xe2,0xe1,0x24,0xaa,0xed,0x0f,0xd1,0x03,0x0d,0xf5,0x36,0x98,0xcd,0xa5,0x77,0x40,0x24,0x0a,0x82,0x68,0x79,0x82,0x38,0x68,0x6f,0x2b,0x0b,0xce,0x0f +.byte 0xcd,0x0f,0xba,0xdb,0xb5,0x22,0x38,0xd2,0xb0,0x9f,0x0f,0x08,0x0d,0xd8,0x5e,0xa7,0xd0,0xa9,0x39,0x66,0x4c,0x46,0xce,0x2a,0xc3,0x67,0x8c,0x91,0xdc,0xf1,0xc0,0x3a,0x58,0x50,0x1f,0xb0,0xa4,0x4d,0xbf,0x99,0x57,0xcf,0xae,0xb2,0xaf,0x6a,0x42,0xd2,0x7f,0x85,0x8c,0x40,0xc6,0x9a,0x93,0x57,0x54,0xf5,0xb4,0x83,0x59,0xb5,0x19,0x52 +.byte 0x7c,0x8b,0x76,0xee,0x35,0x90,0xbf,0xbe,0x65,0x58,0x3b,0x25,0x52,0x18,0xd8,0x7f,0x1f,0xe6,0x70,0xce,0x56,0x1a,0x45,0xa0,0x81,0xee,0x95,0x6f,0x55,0x43,0xaa,0x6e,0x87,0xa9,0xab,0x7d,0xe9,0xa1,0xa3,0x63,0xe7,0x1b,0x6b,0xa6,0x2c,0xe5,0x4a,0xb2,0x1e,0x73,0x5e,0xb5,0xae,0x83,0xe6,0x54,0x0b,0xc5,0x6b,0xb6,0xc4,0x73,0x62,0x1a +.byte 0xbf,0x1a,0x65,0xa2,0x5e,0x3a,0x45,0xd9,0xba,0x5b,0xef,0xf7,0x13,0x0c,0x7c,0x68,0xa1,0x98,0x71,0xb7,0x39,0x7c,0xbc,0x69,0xdb,0xd4,0xac,0x3f,0x82,0x63,0x9b,0x71,0x25,0x3a,0x06,0x73,0x60,0x71,0xc3,0x30,0xd3,0x96,0x02,0x4b,0x46,0xbd,0xd4,0x6e,0xc6,0x29,0xcc,0xd0,0xe1,0x0b,0x66,0x62,0xea,0x29,0xc7,0xcf,0x35,0x9e,0x2f,0x1f +.byte 0xa0,0xfc,0x8c,0x4a,0x83,0x8e,0x3b,0xf5,0x7a,0x6f,0x52,0xaf,0x99,0x9c,0x86,0xab,0xe5,0x1b,0x82,0xb3,0x18,0x35,0x77,0x9b,0xa3,0x94,0xc8,0x39,0x30,0x3f,0xad,0xa9,0x0f,0x93,0xb8,0xc8,0xed,0x04,0xf2,0x0b,0x9a,0xb1,0xd1,0xc9,0x9e,0x40,0x4f,0x71,0x21,0x63,0x2a,0x05,0x26,0x53,0xa3,0x3f,0x43,0xe4,0xf8,0x7c,0x2f,0xa3,0x5a,0x6e +.byte 0xc1,0x40,0xa8,0x4d,0xbc,0x03,0xae,0xe9,0x36,0xb6,0x37,0xdc,0x5f,0xef,0xb0,0x35,0x33,0xdf,0x33,0x71,0xaf,0x80,0xf2,0x69,0xd9,0xb5,0xfc,0xff,0xd2,0x5b,0x6a,0xeb,0xdc,0xe0,0x26,0x43,0x38,0x7b,0x24,0xb2,0x79,0x53,0x52,0x57,0xc4,0x1f,0x6d,0xc9,0x50,0xf2,0x63,0x9d,0xc1,0x22,0x5f,0x11,0x82,0x38,0xdb,0xd3,0xb4,0x1d,0x10,0x72 +.byte 0x9e,0x4d,0x03,0x30,0xba,0x5e,0xe9,0x8c,0x21,0x12,0xe6,0x3a,0xd6,0x4c,0x18,0xa4,0x27,0xc9,0xf5,0x50,0xbd,0xbe,0xf0,0x86,0xd8,0x00,0x56,0xf0,0x10,0x81,0xec,0xeb,0xfc,0x5b,0x29,0x88,0xff,0x73,0x60,0x6b,0xf5,0x8c,0x0b,0x30,0x04,0x53,0x85,0x61,0x0c,0xfc,0xff,0x8f,0x21,0xd2,0xa1,0xcb,0xf7,0x90,0x53,0x3b,0xf4,0xf0,0x2c,0x7d +.byte 0xb6,0x84,0xe7,0x4c,0x88,0xea,0x4f,0xdf,0xff,0x0f,0x5d,0x0f,0xd3,0x2d,0x4f,0x7e,0xdc,0xd1,0x22,0x71,0x0d,0xae,0xa8,0xcf,0x05,0x7b,0xfc,0xfe,0x87,0x40,0xa5,0xe8,0xfd,0x3f,0xdb,0x2f,0x00,0x21,0xb9,0x70,0x02,0x2c,0x96,0x24,0xaf,0x35,0xe2,0x87,0xcb,0x50,0xcf,0x7e,0xfa,0xaf,0x39,0x82,0x0c,0xd5,0xa6,0x3f,0x9c,0x77,0x60,0x16 +.byte 0xbf,0x42,0xcc,0x97,0xd1,0x19,0x0d,0x8a,0x50,0x98,0x7d,0x19,0x7b,0x40,0x1c,0x22,0xde,0x50,0x90,0x32,0x9a,0x3d,0x07,0x35,0xc0,0x48,0x4c,0x0a,0xcd,0x91,0xab,0xf7,0xf3,0x06,0x77,0x80,0x96,0x7b,0x59,0x33,0xe6,0xbf,0x93,0xb8,0x59,0xd0,0x3a,0x1f,0xcc,0xe7,0x1d,0xd4,0xb5,0x58,0xee,0xe7,0x95,0xfa,0x75,0xdb,0x37,0x74,0xb0,0x7d +.byte 0x4d,0xee,0xef,0x20,0x13,0xe5,0x82,0x07,0x8e,0xdd,0x57,0x75,0x33,0x56,0xc4,0x80,0xb0,0x06,0x9f,0x6b,0x72,0x31,0xcf,0xac,0x5f,0x96,0x13,0xeb,0xf4,0x34,0xb6,0x6b,0x55,0xef,0x55,0x26,0x4e,0xdb,0x6c,0x2f,0x64,0x29,0x91,0x3c,0x6d,0x29,0xd2,0x94,0xbd,0x2c,0x99,0xb9,0x97,0x76,0xee,0x7d,0xfd,0xb2,0x8d,0x14,0x4f,0x09,0x81,0xb3 +.byte 0x68,0x3e,0x79,0x28,0x56,0x50,0x3f,0x86,0x4c,0x95,0x6c,0xad,0xf6,0xc5,0x43,0x25,0xea,0xbc,0xe2,0xba,0x77,0x18,0xc6,0x82,0x65,0x73,0x38,0x90,0x9d,0xc9,0x57,0xcd,0xa2,0x7c,0xd3,0x26,0x59,0x44,0xd9,0x79,0xae,0xdd,0x6f,0xe9,0xdc,0x16,0x73,0xba,0x05,0x8a,0x40,0x9f,0xe7,0xcf,0x29,0xa4,0xdf,0x49,0x7f,0x1d,0x73,0xc7,0x8b,0x8d +.byte 0xad,0xb5,0x3d,0x1b,0x64,0xb1,0x8f,0x78,0x06,0xbe,0xaa,0x2c,0x08,0x73,0xc7,0x2c,0xdc,0xd8,0x3f,0x9f,0x1b,0xd2,0xe1,0x4f,0x9d,0x87,0xb8,0xa9,0xdc,0xef,0xbc,0x31,0x9f,0xf7,0x84,0x09,0xe7,0xbc,0xec,0x2a,0xcb,0x3b,0x3a,0x30,0xe2,0x5b,0xbc,0xcd,0xa8,0xdb,0x46,0x80,0xec,0xaa,0x06,0x8e,0xd8,0x6c,0x35,0x65,0x52,0xb8,0xc3,0xf9 +.byte 0x97,0x68,0x06,0x2d,0x3e,0x91,0x71,0x44,0x6e,0x01,0x51,0x10,0x5b,0x74,0xb9,0x3f,0xd7,0xf9,0x5c,0x98,0xe6,0xf8,0x98,0x32,0x26,0x9b,0x5e,0x9c,0x88,0xfb,0xaa,0x70,0xd2,0x2e,0xc2,0xf6,0x02,0x92,0x33,0x55,0x92,0xba,0xfb,0x0e,0x0b,0x08,0xdf,0x5d,0xdd,0x47,0x28,0xae,0x32,0xb3,0x27,0x8d,0xd4,0x18,0x43,0x64,0xc4,0x7f,0x60,0x62 +.byte 0xd9,0x63,0xd1,0x28,0xc9,0x75,0x3b,0x44,0xb4,0x8e,0x2a,0x93,0xf9,0x4c,0x4f,0x7e,0x6b,0x98,0xc9,0x1a,0x82,0x51,0x9a,0xb2,0x80,0x70,0x2e,0xff,0x19,0x66,0x1b,0xb6,0xbc,0x15,0x8e,0xe6,0x0f,0x8e,0x04,0x10,0x94,0x44,0x6c,0x32,0x4b,0x61,0xbc,0x4a,0x16,0x7b,0x25,0x2a,0x27,0x96,0xa9,0xa9,0x61,0x10,0xc1,0x46,0xdd,0xf5,0xe3,0xe8 +.byte 0x1f,0x5b,0xa0,0x77,0xe1,0x42,0x9a,0xd4,0x04,0x33,0x68,0x72,0x1c,0x44,0x29,0xce,0x98,0xe0,0xc7,0x3a,0x9e,0x3c,0xb9,0xb4,0x29,0xef,0x57,0xee,0x8c,0x8f,0x7c,0xe6,0xe1,0x43,0x6e,0x45,0x0e,0xdd,0x4e,0x11,0x4b,0x28,0x69,0xde,0xb8,0xfa,0x32,0xbe,0xc6,0x4f,0x11,0x99,0xe5,0xe3,0xe2,0x1f,0x03,0xbe,0x4a,0xad,0x60,0x68,0xc8,0x13 +.byte 0x80,0x4e,0xb6,0xc0,0xc5,0xc7,0x97,0x5c,0x0b,0x0e,0x64,0x43,0x78,0x70,0x95,0x91,0x8e,0x36,0x6b,0xad,0x57,0xc7,0x1e,0x9c,0x54,0xc9,0x89,0xf0,0x13,0xde,0x0a,0xbe,0xc0,0xa9,0x35,0x77,0x0a,0x01,0x7f,0x98,0x51,0x82,0x92,0x14,0xe0,0x9a,0x08,0xa3,0x0c,0x6c,0x67,0xf2,0x05,0xaa,0xa9,0x4e,0xce,0x3b,0xb1,0xb6,0x8c,0x82,0x5d,0x11 +.byte 0xf2,0xe5,0xd7,0xda,0x3a,0x65,0xa0,0xe3,0xa4,0x09,0x01,0x1c,0xb2,0x08,0x90,0x94,0xb5,0x51,0x56,0x24,0x22,0xfd,0x12,0xad,0x7a,0x75,0xcf,0x0f,0x0f,0x23,0xc3,0xa6,0x1f,0xf8,0x39,0xbc,0x2f,0x18,0x53,0x14,0xef,0xdf,0x90,0x6a,0x50,0x2b,0x8c,0x8b,0xa8,0xd4,0x8c,0x59,0x8f,0xd8,0x81,0x86,0x57,0xc1,0xd1,0xfb,0xe7,0xa6,0x20,0x6e +.byte 0x7c,0xbf,0xce,0xe3,0xce,0x28,0x35,0x7c,0x8e,0x1a,0x66,0xea,0x7d,0x81,0x09,0xdb,0xa8,0x64,0xba,0x3c,0x07,0x3f,0x23,0xd3,0x05,0x97,0x4c,0x92,0xc2,0xa4,0xe8,0x6c,0xfb,0xa0,0x9d,0x8b,0x4d,0xcb,0x3a,0x96,0xe7,0x04,0x0f,0x48,0x87,0x2c,0xdd,0x51,0xf3,0x46,0x7e,0x61,0x89,0xbe,0xb8,0xb0,0x9e,0x9c,0xc4,0x37,0x55,0xe6,0x4f,0x78 +.byte 0x7e,0xb0,0x59,0x42,0xca,0xba,0x4a,0xb2,0x50,0xbd,0x16,0x68,0x99,0x42,0xb4,0x8b,0x60,0x3d,0x54,0x41,0x17,0x11,0x39,0x42,0x5d,0x41,0xec,0xc2,0x53,0x82,0x7c,0x32,0xc9,0xd1,0x34,0x49,0xd8,0x4f,0x29,0x21,0xeb,0x97,0x98,0x4c,0xeb,0x21,0xce,0x50,0xd6,0x53,0xd9,0xf1,0x6e,0x26,0xfa,0xe4,0x71,0x34,0xd8,0x38,0xac,0x39,0x4f,0x02 +.byte 0x36,0x93,0xf2,0x08,0x88,0xdc,0x24,0xdd,0x1f,0xf5,0xe9,0x7f,0x83,0xa0,0xa4,0x6b,0xc5,0xef,0x8e,0x82,0xf9,0x92,0xbc,0x82,0x3f,0xce,0x86,0xa6,0x34,0xf8,0x16,0xa7,0xdb,0x97,0xca,0x54,0x43,0xd8,0xfc,0x31,0xde,0x73,0xd0,0x79,0x1a,0xac,0x61,0x15,0xbd,0x38,0x64,0x3b,0xc6,0xb5,0x95,0xeb,0x2e,0x68,0xe4,0x1d,0x6b,0x18,0xab,0x88 +.byte 0xb0,0x96,0x51,0x8c,0xbe,0x41,0x63,0xd6,0x9a,0x21,0x60,0xe8,0x26,0x37,0xb3,0x10,0x76,0x46,0x31,0x90,0xb0,0x9f,0x17,0xab,0x0f,0x93,0xcc,0x12,0x78,0xee,0x17,0x1c,0xd8,0xc7,0x76,0x0a,0x5a,0xb4,0x8b,0xb1,0x67,0x11,0xde,0x48,0x14,0x8a,0x2a,0xc7,0x71,0x46,0x94,0x15,0x29,0x44,0x9e,0x35,0x03,0x10,0xf7,0x51,0x8a,0xaa,0x9c,0x4a +.byte 0x9a,0x44,0xd5,0xc7,0x37,0x9d,0xb4,0xad,0x41,0xd0,0xda,0xd2,0x1a,0xf9,0x93,0xee,0x28,0x32,0x65,0x0b,0x9c,0x12,0xe3,0xad,0x9f,0x82,0xeb,0x3f,0x03,0xe7,0x6a,0x58,0x83,0x3f,0xbe,0x9f,0x27,0xd3,0xd6,0xe2,0x45,0xbf,0x90,0xe2,0x12,0x61,0x0b,0x57,0xd7,0x06,0x72,0x39,0x2c,0x3e,0x65,0xb2,0xf4,0xf7,0x54,0xef,0x32,0x99,0x44,0x0d +.byte 0xf0,0x5c,0xde,0x4c,0x2e,0x22,0xcd,0x3c,0x25,0x02,0xa5,0x0d,0x79,0x16,0xb0,0x51,0x3f,0x3c,0x84,0x56,0xfa,0x00,0xae,0x7a,0x36,0x45,0x3a,0xcc,0x1d,0x66,0xff,0xf4,0x49,0xce,0xb5,0x5c,0x51,0xf4,0x3e,0x07,0xf2,0x83,0x84,0x4d,0x4e,0xb7,0xce,0x03,0x7b,0x23,0x63,0xdf,0x64,0xa2,0x55,0x92,0xf9,0x2e,0xa5,0x21,0x89,0x29,0x42,0x48 +.byte 0x36,0xc5,0xab,0xd6,0x82,0xe3,0xff,0x45,0xfc,0x61,0xa6,0x4f,0xb9,0x51,0xba,0xd5,0x03,0xa9,0x0b,0xe7,0x73,0x83,0x97,0x1d,0xb2,0xc6,0x75,0xa0,0x52,0x99,0xfc,0x1b,0x27,0x7a,0x10,0xc1,0xed,0x70,0x21,0x4b,0x93,0xa4,0x20,0xed,0x16,0x76,0x97,0x82,0xab,0x21,0xfe,0xa4,0x3f,0xd9,0xbd,0x9c,0x2f,0x19,0x42,0xbc,0xb3,0x4f,0x44,0xf3 +.byte 0x9e,0xd0,0xe7,0xc9,0x7e,0x31,0xaa,0xbc,0x4b,0xba,0x73,0xe1,0xc3,0xbf,0x5d,0xa2,0xd8,0xb7,0xb6,0xfc,0x0a,0x32,0xb9,0xff,0x80,0xb6,0x2a,0x8b,0xea,0x81,0xa0,0xeb,0x1e,0x9e,0x69,0xdd,0xbe,0xc1,0x8a,0x5d,0xfb,0x66,0x21,0x98,0x5c,0x6f,0xd8,0xb4,0xcf,0x8a,0x1a,0x4b,0xde,0xa2,0x20,0xe8,0x5a,0x5a,0xee,0x14,0x09,0xcb,0x63,0x1c +.byte 0x14,0x7d,0x9b,0x47,0xf8,0xfa,0xda,0xb7,0x0e,0xc6,0xbd,0xb2,0x13,0xb8,0x10,0xe2,0x71,0x04,0x36,0x78,0x6d,0x3a,0x8b,0x45,0xd3,0x05,0xec,0x8a,0x2d,0xfa,0x85,0x7c,0xdd,0x75,0xb3,0x2d,0xd1,0xae,0xfc,0xdd,0x02,0x2e,0xcc,0x43,0xc5,0xed,0xe4,0x3f,0xee,0x2c,0xd7,0x37,0x81,0x3a,0x44,0xe6,0xed,0x8c,0x9d,0x9d,0xfa,0xb5,0xdc,0xde +.byte 0xb2,0x7c,0x51,0x58,0xa4,0x21,0xac,0xe2,0x79,0x96,0x90,0xe2,0x0b,0xbf,0x51,0x66,0x77,0x02,0xff,0x67,0x0a,0x70,0x1f,0x04,0x6c,0xb0,0x5b,0x2d,0x26,0x23,0x5a,0x85,0x73,0x66,0x6e,0x7c,0xb3,0xeb,0x36,0x73,0x0f,0xcd,0xb2,0x07,0xee,0x78,0xd1,0xbd,0x5e,0xfa,0x31,0xf6,0x82,0x67,0x94,0xaa,0xff,0xef,0xd2,0x23,0xfc,0x82,0xaa,0xe2 +.byte 0xef,0xc3,0x74,0x79,0x6c,0xe9,0x3f,0x8d,0xe1,0x1b,0xc8,0xb4,0xff,0x15,0xf4,0x60,0xe8,0x84,0x3f,0xaa,0xc6,0x53,0x51,0x1a,0x9b,0x04,0x9b,0xab,0xc5,0xee,0x9a,0x98,0x80,0x89,0x8d,0x5b,0xef,0x0a,0x69,0x71,0xd2,0xf3,0x49,0xc1,0xc1,0x87,0xb3,0x18,0x4b,0x82,0x02,0x87,0xb0,0xf1,0x76,0x4b,0x3e,0xad,0x95,0x51,0xb1,0x64,0xb1,0x03 +.byte 0x5b,0xd2,0x10,0x7b,0x4e,0xd4,0x08,0xf8,0xfd,0xea,0xf0,0xc7,0x16,0x43,0x86,0xa6,0xdb,0xcd,0x75,0xce,0xa9,0xfd,0xa8,0x7c,0x51,0xf7,0xa5,0x29,0x6f,0x0d,0xee,0x66,0x8f,0xc6,0xcd,0x9e,0x3f,0x00,0x24,0x21,0xca,0x69,0x79,0x27,0x03,0x62,0xdf,0xad,0xb9,0x8c,0xd8,0x08,0x88,0x0d,0x0c,0xa1,0x29,0xf9,0xba,0x92,0xb5,0xdd,0xb8,0x1a +.byte 0xbb,0xab,0x44,0xb2,0xda,0x1b,0x8b,0xc1,0x3c,0x61,0x9f,0x7a,0x8b,0x89,0x99,0x09,0xc3,0xb4,0xe4,0x24,0xf5,0x3b,0x36,0xa6,0x61,0x0a,0xec,0x2a,0x1c,0x92,0x7c,0xb1,0x7c,0xd8,0x0b,0x98,0x48,0x8d,0x52,0xa2,0x57,0xc1,0x28,0x89,0xbb,0x60,0x5c,0x58,0x62,0x41,0x1c,0xd6,0xfb,0x69,0x09,0x93,0x90,0x31,0xc4,0x72,0x71,0xf0,0x4f,0xcf +.byte 0x10,0xbb,0xb7,0x6c,0x3b,0x53,0xa3,0x0b,0xff,0x44,0x4c,0x37,0xd5,0x26,0x83,0x7e,0x5c,0xb9,0xa5,0xe8,0x8b,0xc4,0x15,0xf6,0xc7,0xd1,0x39,0x67,0x01,0xb7,0xca,0xa7,0x71,0xa8,0x04,0x95,0x0f,0xfc,0x0a,0x9e,0x52,0xb2,0xfb,0x48,0x47,0xb6,0xa5,0x14,0xc2,0x4f,0xa8,0xd5,0x0f,0x10,0x76,0x39,0x23,0x74,0x2e,0xe5,0x17,0xcb,0xad,0x8a +.byte 0x4a,0x25,0xc8,0x9b,0x25,0x94,0x34,0xbc,0x4b,0x2f,0xdc,0x0a,0xcd,0xc1,0x02,0x72,0x7d,0xa0,0x10,0xa7,0x32,0x68,0xe8,0xd5,0x23,0xe8,0xc9,0xbc,0x05,0x05,0x1e,0xac,0x55,0x45,0xfb,0x42,0x2f,0x0f,0x51,0x8d,0x31,0xb1,0xbc,0x10,0xa1,0x03,0xc3,0x6f,0x35,0x08,0xa5,0x2f,0x91,0x4e,0x43,0x6b,0x62,0x3b,0x00,0x4c,0xd0,0xb8,0x33,0xbc +.byte 0xca,0x57,0xb8,0x1b,0xb4,0x52,0x1a,0xa7,0x03,0x78,0xa0,0x4f,0xda,0x86,0xb9,0xd8,0xc6,0x69,0xe6,0x61,0x2e,0x62,0x96,0x60,0x0d,0x76,0xdc,0x5d,0x0e,0xa8,0xf3,0x86,0xde,0xcf,0x39,0x34,0xc7,0x69,0xed,0xcb,0x9a,0xf5,0xc3,0xce,0x6d,0xa5,0x7f,0xae,0x73,0xb9,0xa6,0xbf,0x88,0x93,0x2b,0x0e,0x8b,0x4b,0xa5,0xeb,0x62,0xc6,0x1a,0xc7 +.byte 0x63,0x63,0x58,0x62,0x37,0xc6,0xbc,0x00,0x72,0xac,0x3d,0x7c,0x22,0xa5,0x59,0xf1,0x6e,0x60,0x45,0x3e,0x99,0x76,0x40,0x82,0xa7,0x52,0xf3,0x48,0x8e,0x4a,0xa3,0xe1,0x3b,0xea,0x77,0xa7,0x7d,0x13,0xe7,0xc4,0xc6,0xa6,0x6e,0xda,0xe8,0x50,0xc8,0x39,0x30,0xab,0x8a,0xe1,0x08,0xa9,0xe3,0xbd,0x8d,0xbd,0x83,0x3c,0xbc,0x6c,0x92,0xed +.byte 0xf1,0xa9,0xd3,0x50,0xf2,0x29,0x8b,0x39,0x46,0xaf,0x08,0x7e,0x00,0x64,0x2f,0xa8,0x18,0xab,0x7e,0x07,0xd3,0x63,0x2a,0xd3,0xd3,0xbb,0xf9,0xdd,0x2b,0xec,0x70,0x35,0x1a,0x94,0x6b,0x87,0xe4,0x1a,0x0a,0x44,0x46,0x08,0xa6,0xce,0x1b,0xf7,0xd7,0x20,0x87,0x1a,0x96,0x6c,0xbe,0xdf,0x73,0x3b,0xc9,0xaf,0x89,0x1c,0x2f,0x47,0xe9,0xd8 +.byte 0x03,0xa6,0x03,0x6c,0x73,0xa9,0x65,0x20,0x36,0xea,0x6f,0xe7,0x96,0x7c,0x01,0x87,0xb0,0x21,0xba,0xb4,0xed,0x1f,0x81,0x65,0x97,0x36,0xda,0x68,0x80,0x64,0x99,0xe6,0xda,0x95,0x04,0xdf,0x5d,0xfd,0x86,0xd1,0xfd,0xfa,0x1c,0xd7,0x89,0xbf,0xe6,0x99,0x6c,0xf5,0x01,0x56,0x20,0x88,0x79,0xa7,0x8d,0x88,0x82,0xe5,0x32,0x38,0xe0,0xf0 +.byte 0x98,0x63,0xa9,0xab,0xeb,0x09,0x8d,0xaf,0x3f,0xa8,0x57,0x98,0xde,0xc8,0x9c,0x8d,0x1d,0x18,0xc5,0xa8,0x82,0x51,0x9b,0x6f,0xc6,0xb8,0x09,0xd3,0xea,0xd4,0xe3,0xac,0xd1,0x0e,0x88,0xda,0xdf,0x38,0x53,0x14,0x87,0x28,0x6f,0x13,0x35,0xdb,0xfe,0xa1,0xe7,0x43,0xb5,0x02,0x46,0x08,0x1a,0x31,0x0d,0x9e,0x3d,0x3b,0xbf,0xbb,0x82,0x9c +.byte 0x09,0xf3,0xd9,0x22,0x0a,0x82,0x07,0xd3,0xe8,0x19,0x6e,0x21,0xd2,0xa2,0xa8,0x14,0xbc,0x42,0xb6,0xeb,0x8c,0x40,0x9b,0xb2,0xa9,0x17,0xad,0x2c,0x19,0xaa,0x4b,0x22,0xf9,0x4e,0xde,0x8f,0xbe,0x78,0x9b,0xab,0xb9,0xfa,0xb1,0x3e,0x68,0x86,0x1a,0x4a,0x61,0xba,0x63,0x51,0x25,0x11,0x59,0xd0,0xb7,0x0c,0xb7,0xcc,0x45,0x05,0x6d,0x5a +.byte 0xe2,0xd7,0x10,0x80,0x19,0xd3,0xa9,0xab,0xb6,0x9f,0x53,0x7a,0xaa,0x19,0x74,0x01,0xc9,0xd6,0x45,0x42,0x2c,0xe5,0xc0,0xcf,0x62,0xe6,0x95,0x6f,0x4c,0x90,0x50,0x97,0x61,0x83,0x73,0xd0,0xc2,0xd5,0xf0,0x05,0xca,0xe9,0x6f,0x67,0xa9,0x51,0xb8,0xb4,0x9d,0x30,0x8e,0xe3,0x29,0xf9,0x3b,0x3d,0x17,0x25,0xad,0xbb,0xb0,0x34,0x68,0x29 +.byte 0x06,0xad,0x0e,0xdf,0x41,0xa6,0xf1,0xa6,0x25,0xc4,0xf0,0x0d,0x57,0x84,0x34,0x2c,0x3b,0xb1,0x41,0xd6,0x83,0x00,0x3a,0x91,0x98,0x8e,0xd0,0x59,0x0b,0x2d,0xc9,0x65,0x03,0x91,0xcb,0x03,0x97,0x57,0xde,0x11,0x8b,0x4b,0x1b,0x85,0x0b,0xb6,0x68,0x25,0x3c,0x1a,0x04,0x7d,0xd5,0x2b,0x16,0x69,0x1f,0x64,0x8b,0x47,0x60,0x17,0xaa,0x68 +.byte 0x45,0xf2,0x0b,0xf8,0xa2,0x27,0xf8,0x47,0x86,0x41,0x94,0x3f,0x92,0xc3,0x02,0xab,0x80,0x2b,0x0e,0x3c,0xd0,0x13,0x59,0x08,0xfc,0x13,0x33,0x52,0xbb,0x2d,0x6b,0x22,0xa2,0x8b,0x9f,0x7c,0x8e,0x40,0x35,0xa4,0xc7,0x45,0xb7,0xf8,0x10,0x22,0x95,0xc5,0x48,0xc1,0x50,0x4d,0x4a,0x36,0xe1,0xec,0x1e,0x07,0xf7,0x68,0x63,0xcb,0x13,0x03 +.byte 0x70,0x63,0xb1,0x9b,0xf3,0x60,0x01,0x6e,0x63,0x5c,0x4d,0x2c,0x5c,0x5c,0x58,0x8b,0xbb,0x6e,0xd1,0x69,0xdd,0x19,0xfe,0xfb,0xd6,0xdc,0x68,0x97,0x9c,0x46,0x0d,0xdd,0x4d,0xbd,0x52,0xe4,0xd9,0xc2,0x03,0x4e,0x4c,0xe2,0x66,0x6b,0x4d,0xbe,0x6b,0xf3,0xd6,0xbe,0x2d,0xba,0xdd,0x1b,0x4f,0x60,0x02,0x74,0xa1,0xf0,0xd0,0xfa,0x23,0x33 +.byte 0x29,0x7e,0x00,0x09,0x47,0x15,0xa8,0xd8,0xdb,0xb8,0xe1,0x20,0xd5,0xe2,0x91,0xd0,0xe8,0xfa,0xa1,0x0d,0x80,0xbd,0x7d,0x62,0x9d,0xf2,0xbc,0x03,0xa1,0x44,0x9f,0x8d,0x3d,0xe3,0xb4,0xec,0x32,0xd9,0x66,0xb0,0xc7,0x75,0x11,0xaa,0xab,0xb7,0x84,0x1d,0x5b,0x4f,0x25,0x5c,0x53,0xed,0xbb,0x6d,0x06,0x1f,0x12,0x5f,0xc0,0xeb,0x55,0x3e +.byte 0xd0,0x5b,0x4d,0x07,0xf7,0x84,0x12,0xbc,0xc8,0xd4,0xf4,0x69,0xdb,0x71,0x8a,0x00,0x58,0xf5,0x84,0xff,0xc3,0xbc,0x13,0x6e,0x5f,0xac,0xd6,0x72,0x1b,0x2d,0xbb,0x27,0xfd,0x8d,0xcc,0x59,0x79,0xb9,0x63,0xe8,0x0a,0xf3,0x7f,0xa4,0x9f,0x4c,0x35,0x9a,0xdc,0xff,0x11,0x42,0xf3,0x1c,0x86,0xd0,0x22,0x7e,0x81,0x79,0x04,0x93,0x5c,0xf2 +.byte 0xab,0xdf,0xb7,0x1d,0x84,0xbd,0xde,0xfb,0xd2,0x75,0x43,0xb8,0x19,0x63,0x97,0xfe,0x0e,0x91,0x9d,0x38,0x50,0xc5,0x7a,0xd6,0x51,0xd4,0xfc,0x8d,0xec,0xd5,0xe2,0x07,0xce,0x21,0x03,0x02,0xa1,0x61,0x8d,0xf1,0xf5,0x1f,0xb3,0xaf,0x9f,0x13,0xd8,0x81,0xd2,0xf7,0xe9,0xe2,0x62,0x49,0xca,0x1c,0x15,0x07,0x39,0xe6,0x01,0xec,0x6c,0x7d +.byte 0x3b,0xf1,0x52,0xda,0xf2,0x97,0x55,0xef,0x6f,0x88,0x82,0x0e,0xe6,0xf4,0x3e,0x33,0xf6,0x61,0x6d,0xef,0xbf,0xa8,0x9a,0x91,0x2f,0xb3,0xd2,0x3d,0xaa,0x7a,0x4e,0x80,0xe1,0x04,0xbe,0xc7,0xf8,0xc3,0xc9,0xd8,0xa2,0x01,0x5d,0x30,0xae,0x6d,0x39,0x52,0x60,0x9d,0x07,0xd5,0xa2,0x86,0xf0,0x88,0x00,0xec,0x18,0x11,0x2d,0x69,0x86,0xa9 +.byte 0x5a,0x73,0xda,0x4e,0x4c,0xdb,0xb8,0x02,0xad,0x53,0xec,0x20,0x0f,0x35,0xe0,0x4f,0x6e,0xd5,0x04,0xcc,0xa0,0xf5,0x8c,0x7d,0x31,0x04,0xa4,0xcf,0xf0,0x27,0xd2,0xb6,0x7d,0x8c,0x26,0x5f,0x19,0xba,0x79,0x80,0xec,0x6d,0xfe,0xaf,0xc1,0x3a,0xc2,0x3d,0x14,0x3c,0xa0,0xc5,0x77,0xf4,0x96,0x56,0x51,0x8b,0x7c,0x7e,0xe5,0x23,0x5d,0x46 +.byte 0x1b,0x2e,0x28,0xc0,0x80,0x6b,0x6a,0x85,0x6c,0xcf,0xaa,0x28,0xf3,0x83,0x2d,0x42,0x6f,0xf3,0x5e,0x5d,0xa2,0x7b,0xba,0x5c,0x12,0xb0,0xda,0xa0,0xeb,0xdf,0xad,0x1d,0x4c,0x54,0xcf,0xad,0x02,0x68,0xcd,0xfe,0x5c,0x5b,0x65,0x6d,0xa5,0xcc,0xd3,0xed,0x32,0x74,0x6c,0x58,0x83,0x3a,0xc1,0x71,0xbf,0xb5,0xa2,0xbd,0x10,0xe5,0x46,0xc5 +.byte 0x00,0x82,0xb1,0xeb,0x6f,0x73,0xf9,0x12,0x23,0xe4,0xda,0xff,0xa3,0xc4,0x9c,0xf1,0xcc,0x0e,0x1a,0x7a,0x10,0x62,0x8f,0xa5,0xb2,0x35,0x51,0x67,0xb5,0x95,0xbe,0x4c,0x81,0x53,0xfc,0xdd,0x27,0x26,0x97,0x42,0x01,0xec,0x08,0x91,0xb8,0xf0,0xaf,0x57,0x54,0x73,0x52,0x8f,0xde,0xca,0xed,0x1b,0xca,0x8d,0x97,0x1e,0xdc,0xe7,0xfa,0x68 +.byte 0xaf,0x37,0xb0,0x62,0xa3,0x9f,0xbc,0xac,0x9f,0x28,0x1e,0xb7,0xaa,0xb0,0x91,0xe4,0x95,0xad,0xf9,0xe5,0xd4,0xcc,0x23,0x0f,0x4a,0x2d,0xdd,0xea,0x64,0xd1,0x04,0x3c,0xd0,0xca,0xfe,0xd3,0x19,0x9d,0x28,0xa5,0x1c,0xff,0x3e,0xae,0xe9,0xfb,0x12,0x03,0x6d,0xcf,0xbc,0x5f,0x27,0xce,0x1a,0xb9,0xc0,0x31,0x88,0x6e,0x2e,0xaf,0x35,0x5f +.byte 0xf0,0xce,0x92,0xf8,0x6f,0xd6,0x67,0x1c,0xc6,0x5c,0xee,0x59,0xaa,0xd6,0x8c,0xa8,0x13,0xe6,0xf7,0xe2,0x82,0x2f,0x82,0x1e,0x4c,0x0d,0xab,0x3e,0xdb,0x4d,0xc5,0x90,0x32,0xe4,0xf0,0x74,0xc1,0x92,0x1b,0xdd,0xf3,0xa7,0xf6,0x6b,0x01,0x9d,0x8d,0x78,0x3d,0x5a,0x46,0x74,0x16,0x93,0x44,0xca,0xbe,0x31,0xea,0xb4,0x65,0xcd,0xe6,0xdd +.byte 0x56,0x9d,0x63,0x48,0xf0,0xf3,0x15,0x91,0x6c,0x27,0xf9,0xf7,0x3b,0x9f,0x04,0x6d,0x4d,0x1d,0xf1,0x7c,0xd1,0x81,0x06,0xef,0x04,0x47,0x98,0x5d,0x21,0xf4,0xe0,0xa0,0x13,0xaf,0x1d,0xb0,0xd5,0x45,0x64,0x92,0x46,0x99,0xff,0xb4,0xbf,0x36,0x01,0x2d,0x23,0x6a,0xc4,0x6b,0x3f,0x91,0x10,0x03,0xaf,0x6e,0x79,0x86,0xdb,0x15,0xde,0xfa +.byte 0x0d,0x71,0x04,0x16,0x12,0x31,0x9b,0x69,0xb9,0xe0,0xe7,0x4e,0xfd,0x0e,0xd5,0x71,0xa0,0xc7,0xd7,0x46,0xdb,0xda,0xbd,0xcd,0xdc,0x77,0xe5,0x71,0x9d,0xa1,0xf4,0x02,0x10,0xc6,0x27,0x76,0x4e,0xa6,0x35,0xe6,0x9e,0xda,0xbe,0xd8,0xc0,0x21,0x15,0xd4,0xcc,0xd5,0x4b,0xdf,0x38,0xc5,0x15,0x4b,0xfa,0x4e,0x83,0xf4,0x27,0xdb,0x8a,0xb1 +.byte 0x0e,0x1f,0xc9,0x3c,0x1c,0x36,0x35,0x54,0x8b,0x54,0xf8,0x31,0x1e,0x0e,0x1c,0x4e,0x44,0x29,0x90,0xad,0x28,0x85,0xb4,0x72,0x2d,0x1b,0x8b,0x26,0x2f,0xb6,0xc2,0x14,0x0e,0x81,0xd0,0x37,0x29,0x5c,0x0f,0xdc,0x21,0x62,0x10,0x7a,0xeb,0xa3,0x6e,0xd4,0x5b,0xb4,0x13,0x2e,0xd6,0x8f,0xd9,0x57,0x0d,0x9b,0xfd,0x1e,0x66,0xb7,0x6e,0xac +.byte 0x88,0xb9,0x75,0x60,0x62,0x83,0x72,0x96,0xc6,0x2e,0xdc,0xfe,0x88,0xee,0x07,0x9a,0x62,0x19,0xde,0xf1,0xa5,0xfb,0xcc,0xdb,0x4a,0xeb,0x16,0x60,0x34,0x46,0xfc,0xf2,0x6d,0xee,0xfc,0xa0,0x3a,0xb1,0x11,0x03,0x8b,0xae,0x26,0xef,0x86,0x91,0x20,0x7a,0x19,0x35,0xd6,0x12,0xfc,0x73,0x5a,0xb3,0x13,0xf8,0x65,0x04,0xec,0x35,0xee,0xf8 +.byte 0x70,0xb2,0x0b,0xe1,0xfc,0x16,0x35,0xec,0x6b,0xdd,0x8b,0xdc,0x0d,0xe8,0x91,0xcf,0x18,0xff,0x44,0x1d,0xd9,0x29,0xae,0x33,0x83,0xfe,0x8d,0xe6,0x70,0xbb,0x77,0x48,0xaa,0xe6,0xbc,0x51,0xa7,0x25,0x01,0xcf,0x88,0xc4,0x8b,0xfc,0xb1,0x71,0x01,0xc7,0xfc,0xd6,0x96,0x63,0xee,0x2d,0x04,0x1d,0x80,0x24,0xd0,0x80,0x03,0xd9,0x18,0x96 +.byte 0xec,0x6a,0x98,0xed,0x6e,0x9a,0xe0,0x42,0x5a,0x9d,0xec,0xed,0x46,0x3c,0xb5,0xf0,0xd6,0x88,0x92,0x89,0x38,0x5f,0xd6,0xba,0xfd,0x32,0x31,0x81,0xe9,0xf1,0x56,0x89,0xa3,0x56,0xa6,0x03,0x00,0x60,0xe1,0xa8,0x59,0xdb,0xbe,0x72,0x39,0x6c,0x08,0x4d,0x26,0x57,0xa6,0xf6,0x13,0x7d,0x4a,0x2f,0x64,0xb8,0xa7,0x23,0x2c,0xa4,0x4a,0xad +.byte 0xcf,0xa1,0xa2,0x32,0xbb,0xd1,0x98,0x02,0xe4,0x1a,0x41,0x26,0x23,0xba,0xa2,0x17,0x62,0xaa,0xa6,0xc7,0x74,0x9d,0xea,0xc7,0xa0,0x08,0x0a,0x1a,0x4e,0x71,0xd9,0x45,0xf7,0xe8,0x57,0x79,0x12,0xd0,0x38,0x2f,0xdb,0xbd,0x5a,0x84,0xe1,0xb2,0x62,0x7e,0x56,0xb3,0x50,0x2a,0xa0,0x32,0x1f,0x86,0x71,0xc4,0xa5,0xba,0x93,0x5b,0x22,0x97 +.byte 0xf4,0xe5,0x44,0x27,0x6b,0x06,0x84,0x55,0x19,0x45,0x12,0x75,0x4b,0xf0,0x76,0x6d,0x3c,0x0a,0x17,0xc2,0x9d,0x96,0x72,0xe7,0x5e,0x79,0x84,0x0a,0x39,0x64,0x09,0x6e,0x7e,0xd7,0x77,0x40,0x75,0x2c,0xbd,0x98,0xae,0x3e,0x34,0x08,0x4d,0xda,0x2c,0xcf,0x0c,0xa2,0x8c,0x40,0xfa,0x34,0x43,0x15,0xed,0x4f,0x69,0xa6,0xef,0x2d,0x3c,0x55 +.byte 0x7a,0xe1,0x67,0xd1,0x0a,0x89,0xe0,0x2d,0x02,0x35,0x57,0xc8,0x9a,0x4b,0xc4,0x46,0xa7,0x57,0x03,0x89,0x7d,0x3f,0x70,0x47,0x03,0x06,0xd9,0x81,0x1f,0x8d,0x7e,0x36,0x9b,0xfd,0xad,0x20,0x9d,0x5a,0x29,0xe9,0x40,0x6a,0xb8,0x07,0x6b,0xc7,0x2b,0x58,0xd2,0x1d,0xef,0x88,0xa5,0xfb,0x3b,0xd6,0x9f,0xfd,0x89,0x0e,0x50,0xd4,0xbc,0x89 +.byte 0x3f,0x3c,0x6c,0x50,0xc6,0xe3,0x8b,0x7e,0x34,0x8b,0x26,0x99,0x2a,0xfa,0xa5,0x19,0x53,0xb5,0x5e,0xfd,0x94,0xe8,0x33,0xb2,0x6d,0x9c,0x3c,0x0c,0x14,0x90,0xc4,0xa2,0x4a,0x3a,0xca,0x07,0x72,0x46,0x37,0xfc,0x02,0x5d,0xf4,0x97,0xca,0x8e,0xc6,0xc4,0x63,0xda,0x5c,0x89,0xc3,0x6c,0xb1,0x1a,0xf5,0x2a,0xbc,0x2e,0xe3,0xcd,0x2f,0xe2 +.byte 0x91,0x16,0xf9,0x94,0x0e,0x1b,0xe6,0x01,0x73,0x61,0x1e,0xcf,0x5e,0x21,0x70,0xcb,0x5b,0x87,0xc1,0x46,0x39,0x59,0xa6,0x74,0x82,0x7f,0xa2,0x6c,0x4a,0x50,0x5f,0xbd,0x1c,0x1a,0x65,0x80,0x01,0x44,0x19,0xcf,0xcd,0xef,0x3d,0x5e,0x1b,0x71,0x82,0x4f,0x8b,0xc1,0xa0,0x9a,0x77,0xee,0xac,0x06,0xdc,0x6a,0xa0,0x34,0x50,0xa4,0xe0,0xda +.byte 0x3d,0xa0,0xf7,0x9a,0xb8,0xd5,0x59,0xe0,0x7f,0x05,0x04,0xd5,0x32,0x8c,0x49,0xf5,0x0a,0x0e,0x99,0x83,0xf5,0x47,0x2b,0x7c,0x7b,0x65,0x25,0x02,0xc4,0x88,0xbb,0x6a,0x4f,0x89,0x31,0x60,0xc2,0x47,0x8b,0x22,0xfc,0x4a,0xde,0xb3,0xb9,0xed,0xb8,0xdf,0xd7,0xd5,0x09,0x98,0xcc,0x5f,0xaf,0xbb,0x02,0xc3,0x62,0x62,0xee,0x99,0x42,0x1b +.byte 0xbe,0x5b,0xa8,0x5c,0x40,0x03,0x86,0x29,0x29,0x06,0x0b,0x53,0x46,0x29,0x03,0x3b,0x11,0x64,0xf1,0x09,0xca,0x69,0x69,0xfa,0xcc,0x85,0x23,0x14,0x1b,0xfd,0x65,0xb9,0xf5,0x6b,0xbb,0x2a,0x9d,0x6e,0x64,0x1a,0xe1,0x37,0x39,0xd4,0x85,0x40,0xa3,0xf9,0x04,0xec,0x9e,0x3b,0x74,0x97,0xa4,0x64,0x8a,0x48,0xb2,0x62,0xc1,0x1c,0xed,0x67 +.byte 0x6f,0x23,0xae,0x0f,0x64,0x2e,0xe5,0x92,0xb6,0xb5,0x71,0x24,0xc0,0x60,0x9a,0x10,0x23,0x6b,0x4a,0x22,0xe9,0x0a,0xaa,0x09,0x62,0x39,0xe0,0x40,0xee,0x13,0x27,0x14,0x73,0xeb,0x75,0x7b,0x4a,0xe1,0x42,0x65,0x37,0xae,0x80,0x08,0x26,0xf9,0x53,0x98,0x58,0xdd,0xf5,0xed,0x26,0x37,0x37,0x85,0xb5,0x88,0x91,0x05,0x2d,0x04,0xa6,0xd5 +.byte 0xa6,0x98,0xb0,0x0e,0x4b,0x4c,0x53,0x76,0x79,0xad,0x82,0xc5,0x16,0xba,0xd8,0x20,0x5f,0x4c,0x1d,0x69,0xa0,0xe0,0xe9,0xbc,0xb8,0x5c,0x10,0x4a,0x0a,0xd3,0x52,0x9c,0x2e,0x1b,0x6c,0xf7,0x43,0x83,0x6f,0xa9,0xcc,0x00,0xed,0x16,0x4c,0xc3,0x24,0x79,0x59,0x68,0xfb,0xf9,0xf6,0xb0,0xb4,0x01,0xc2,0xdd,0xf7,0xe5,0x3b,0x60,0x48,0x49 +.byte 0x32,0x48,0x05,0xa8,0x62,0xa3,0x03,0x9f,0x3d,0x91,0xdb,0x84,0x64,0x6f,0x1e,0x50,0x8e,0xdf,0x1a,0xa0,0xb1,0xf4,0x34,0x7c,0xe6,0xb7,0x7c,0x14,0xa1,0x65,0x1a,0xb4,0xdb,0x67,0x78,0xb1,0x88,0x3c,0xc2,0x5e,0x0e,0xea,0x32,0x15,0xc7,0xda,0xe4,0x9a,0x44,0xde,0x61,0x90,0x3b,0x97,0x11,0x5b,0x6d,0xa5,0x9a,0x2f,0x1b,0x8b,0xd7,0xdd +.byte 0x73,0xe4,0xc3,0x19,0x5d,0x68,0xcf,0x0e,0xe4,0x69,0xa5,0xeb,0x50,0x6f,0x79,0xff,0x91,0xc6,0x95,0x83,0xe8,0x72,0x6a,0x01,0x49,0x2b,0xcf,0x8f,0x93,0x1e,0xef,0x31,0x17,0x8f,0xa8,0x2b,0x5f,0x4b,0x79,0x8b,0xe5,0x6c,0xb7,0x61,0xd5,0x9e,0xe0,0xd4,0x25,0xc3,0x93,0x31,0x8f,0x66,0x6c,0x48,0x30,0x65,0xf4,0xd7,0xde,0x64,0xee,0xbd +.byte 0xbd,0xad,0x32,0xfc,0xf3,0xd8,0x7c,0x85,0x7c,0x24,0x40,0xb6,0xd4,0xe0,0x4b,0xc0,0xab,0xcc,0xeb,0x77,0x7c,0xb7,0x33,0x3c,0x90,0x04,0xaf,0x85,0xaa,0xb4,0xaa,0x90,0x67,0x29,0xd9,0x85,0x6a,0x34,0xf4,0xc4,0x6c,0xbc,0xb4,0x86,0x54,0x83,0xd5,0x5e,0xf3,0xdd,0x1a,0x56,0x5e,0xa5,0xd8,0x06,0xc0,0xa7,0x27,0xd4,0x0d,0x5b,0x08,0xf4 +.byte 0xb4,0x15,0xf9,0xb4,0x56,0x1c,0x80,0x98,0xc9,0xcd,0xf0,0x38,0x18,0xbe,0x99,0xec,0x7e,0x0c,0x3d,0xc1,0x98,0x26,0x9d,0x50,0xe4,0x00,0xcf,0x0f,0x0b,0x77,0x86,0x31,0x55,0x38,0xa4,0x31,0x50,0x51,0x64,0x88,0x81,0x05,0x32,0x99,0x38,0xd1,0x62,0x20,0x8e,0xf0,0x29,0x31,0xf5,0x79,0xbb,0x1e,0x0f,0xba,0x51,0x94,0xa9,0x54,0xcd,0x43 +.byte 0xce,0xe5,0x2c,0x29,0xa5,0x51,0x23,0x97,0x5d,0x36,0xff,0x51,0x5c,0x66,0xb7,0x62,0x1b,0x5f,0xd7,0x2f,0x19,0x07,0xff,0x0a,0xfc,0xf6,0x6e,0xb5,0xfd,0xa9,0x92,0x40,0xd3,0xe6,0x99,0x15,0x6f,0x1e,0x91,0xad,0x1f,0x4d,0x1c,0xe2,0xd9,0xcf,0x01,0x71,0xec,0x1a,0xa3,0xba,0x48,0x40,0xfd,0x18,0xb1,0x24,0x2b,0xd2,0x37,0xb5,0x74,0xdd +.byte 0x7e,0xf6,0x18,0xb4,0x7b,0x0e,0x7d,0x65,0x46,0x7b,0xe3,0x51,0x03,0xae,0xe1,0xd0,0x74,0xc6,0xc9,0xda,0x0e,0x79,0x6f,0xf5,0x62,0xc0,0x7e,0x76,0x3e,0x13,0x8b,0xe0,0x4c,0xfa,0x7e,0xe1,0xa2,0xee,0x9d,0x3f,0x91,0x9d,0x21,0xdd,0xc2,0xd0,0xa5,0x1d,0x17,0xd6,0xdc,0xeb,0xa3,0xc0,0x71,0xa0,0xfe,0xf0,0xaf,0x31,0xdc,0xa3,0xd4,0x21 +.byte 0x4a,0x32,0x1d,0x54,0x25,0x3b,0xc8,0x8f,0x68,0xcd,0x99,0xce,0x76,0x39,0x42,0xd8,0xca,0xf2,0x46,0x72,0xfe,0x52,0xc2,0x90,0x83,0xed,0xa0,0x6d,0x1b,0xf5,0xb1,0x09,0xae,0x2b,0x34,0x4f,0xd3,0x78,0x19,0x7f,0xad,0x8d,0x50,0x26,0x9c,0x36,0xa3,0xb5,0x3d,0x0b,0xa6,0x87,0x65,0xa0,0xdb,0x88,0x20,0xff,0xb6,0xfd,0xc5,0xbd,0x0a,0x28 +.byte 0xc8,0x9c,0x42,0x7f,0x24,0x58,0xe9,0x07,0x53,0x4b,0x9a,0x2a,0x1e,0x7b,0x90,0x97,0x78,0x74,0x80,0x5d,0xe5,0x6e,0xae,0x15,0x68,0xd4,0x2a,0x3a,0xd3,0x00,0x4f,0x4b,0xff,0x8f,0x1e,0x8f,0x9f,0x75,0xe5,0xea,0x9d,0xb9,0xed,0x8f,0xa9,0x2b,0x70,0xa8,0xcb,0x08,0x85,0xd3,0x8f,0x5d,0xc7,0x49,0x66,0xcc,0xa8,0x6d,0xbd,0x01,0x93,0xd5 +.byte 0xe6,0x75,0x2e,0x25,0x07,0x59,0x86,0x3f,0x44,0x8b,0x0b,0xb5,0x38,0xd5,0xbd,0xcf,0x48,0x8a,0xf7,0x71,0xd6,0x6b,0x2e,0x93,0x3d,0x0b,0xc0,0x75,0xee,0xa8,0x5d,0x9c,0x3d,0xa5,0xdb,0xc5,0x8d,0xac,0xda,0xf4,0xcd,0x5f,0x24,0xfe,0x86,0x14,0x44,0x65,0x3f,0x89,0x7f,0xd3,0x61,0x48,0xb0,0x43,0xf0,0x1e,0xde,0xbc,0xb7,0x51,0x0f,0xfc +.byte 0x32,0xf2,0x04,0xe2,0x4b,0xcb,0xbb,0x63,0x7d,0x5b,0x9a,0xb1,0x91,0x57,0x89,0xdc,0xed,0xde,0x91,0x2d,0xdd,0x42,0xc8,0x3c,0xb0,0xd7,0xa5,0xbc,0xa7,0x33,0x14,0x32,0xaf,0xf7,0xe9,0x25,0xd2,0x1a,0x64,0xf7,0x1b,0xab,0x0e,0xbc,0x50,0xbc,0x85,0x44,0xe0,0xa6,0xf1,0x4a,0x32,0x2f,0x30,0x27,0x48,0x4f,0xfc,0x8a,0x5a,0x78,0xe7,0x16 +.byte 0x55,0xcf,0xca,0x15,0xa8,0xa8,0xa2,0xef,0x9a,0x16,0x02,0xf4,0xb0,0x44,0xfd,0xc4,0x51,0x01,0x4f,0x1d,0x9d,0x09,0x62,0x42,0xe9,0x8b,0x18,0xa4,0x65,0xef,0x8b,0xfe,0x71,0x9f,0x4b,0x47,0x48,0x41,0x73,0x5c,0x0c,0x52,0x7d,0x79,0xbc,0x93,0x2a,0xaa,0x81,0x99,0x21,0xa5,0x9e,0xac,0xcd,0x57,0x51,0x50,0xbc,0xc9,0x96,0xaf,0xdf,0x1a +.byte 0x8f,0xee,0x36,0x05,0x20,0x32,0xe8,0x51,0x94,0x72,0x12,0xa3,0x17,0x25,0x7f,0x0a,0x3e,0xcc,0x22,0xcf,0x05,0xb2,0x2b,0xaa,0x36,0x01,0xdf,0xd4,0x4e,0xe1,0x02,0x43,0x4e,0xac,0x50,0x64,0xcd,0x2f,0xc2,0xa9,0xb0,0xf2,0xf2,0x4c,0xdf,0x16,0xa6,0x54,0xf7,0xbf,0x1a,0x69,0xeb,0xa1,0x5a,0xc7,0xcf,0x46,0x2d,0xc2,0x3a,0x7f,0x4a,0x14 +.byte 0x22,0x15,0x46,0x46,0x2d,0xc1,0x98,0xf7,0x0b,0xf3,0x27,0xfc,0x78,0x67,0x05,0xd8,0xe0,0xf6,0xb8,0xb6,0x0b,0xdb,0x4d,0x6b,0x7e,0x9b,0xbf,0x5c,0x15,0x97,0x49,0x9f,0x6f,0x11,0x6c,0x6e,0x1d,0x1e,0x65,0x5b,0xb9,0x60,0x8f,0xa3,0xa9,0x99,0x17,0x92,0xb8,0x65,0x25,0xc4,0xef,0xea,0xa6,0xc0,0x57,0xa9,0x4c,0x78,0xe3,0xd6,0xf2,0x19 +.byte 0x9c,0x86,0x9e,0x45,0x3e,0xfd,0x21,0x4c,0x2a,0x56,0x7c,0x23,0xf2,0x22,0xa1,0x81,0xdb,0xe6,0xfa,0x85,0x19,0x3b,0x1d,0x61,0xb3,0x21,0xb5,0x64,0x1d,0x07,0x66,0xd2,0xe5,0x9c,0xb0,0x76,0x9d,0xc9,0x02,0x6a,0x8d,0xd5,0x84,0xd5,0xa7,0x7c,0x70,0x64,0x46,0xd6,0xff,0xc7,0x9f,0x2f,0xed,0xc1,0x5a,0xcb,0x56,0x12,0x31,0x9d,0xff,0x66 +.byte 0x9a,0xf8,0x50,0xc6,0x54,0xfd,0x8d,0x49,0x32,0x8c,0xdd,0x8c,0xbe,0x30,0x79,0xaf,0x1a,0xd5,0x28,0x1d,0x03,0x87,0x12,0x60,0x7a,0xcc,0xe6,0xe8,0x4e,0x21,0x5d,0xa3,0x06,0xfb,0xdf,0xf6,0x31,0xd6,0x10,0x3e,0xec,0x23,0x69,0xc7,0x7b,0xf6,0x78,0xa6,0xd1,0x8a,0x48,0xd9,0xdc,0x35,0x1f,0xd4,0xd5,0xf2,0xe1,0xa2,0x13,0x8a,0xec,0x12 +.byte 0xa7,0xf1,0x5d,0xb2,0xc3,0x6b,0x72,0xd4,0xea,0x4f,0x21,0xff,0x68,0x51,0x51,0xd9,0xd7,0x2f,0x28,0xd7,0xdf,0xbc,0x35,0x4f,0x49,0x7e,0xe7,0x21,0x82,0xd7,0x0c,0x7c,0xf4,0x86,0x86,0x62,0xcd,0xf5,0x23,0x77,0xc1,0x14,0x8a,0xc4,0x2a,0x82,0x74,0x0e,0x90,0x93,0xd5,0x5a,0xc0,0x57,0x93,0x1a,0xe1,0x1c,0x13,0x17,0x72,0xc3,0xa6,0x54 +.byte 0xc4,0xe2,0xfc,0xd3,0xa0,0xce,0x08,0x87,0x9e,0x2a,0xaf,0xa7,0xbb,0x2d,0xaf,0xc0,0x38,0x97,0xc8,0x6d,0xb8,0x7b,0x75,0xc5,0xf2,0x79,0x62,0xdc,0x7c,0xa9,0xfd,0x19,0xa2,0xb1,0xee,0xdf,0x90,0x18,0x5a,0xdb,0x3c,0xba,0x0d,0x84,0xd6,0xaf,0x15,0xee,0xb6,0xa5,0x78,0x38,0x87,0xdf,0x42,0xd6,0xd1,0xa2,0xe9,0xe0,0xa6,0xf2,0x4e,0xa4 +.byte 0xed,0xa5,0xf6,0x66,0x7f,0x99,0xbc,0xfb,0x4b,0x37,0xca,0x5a,0xb3,0x29,0x8e,0x80,0x30,0x8b,0x74,0x7b,0xac,0x61,0xfb,0xca,0x62,0xfe,0x24,0xc4,0x6e,0xac,0x66,0x97,0xaa,0x9a,0x99,0xe6,0xa8,0xa4,0xd8,0x62,0x58,0x7c,0xd1,0xeb,0xee,0xc8,0x08,0xa0,0x54,0xde,0xb1,0xef,0x57,0x2c,0xb6,0x2c,0x78,0x22,0x10,0xbb,0xfe,0x4b,0x77,0xa5 +.byte 0x5a,0xed,0xbb,0xf8,0x97,0x96,0x20,0xa9,0x8c,0x78,0xb5,0xb9,0x55,0xc9,0xaf,0xb9,0xa1,0x1f,0x13,0x52,0xf9,0xbb,0xaa,0x98,0x01,0x57,0xa6,0x88,0xaa,0x5c,0xf0,0x62,0x5b,0x3e,0xe1,0x5f,0xf4,0x98,0x95,0x8b,0x8f,0x48,0xd6,0xd5,0x8b,0xc2,0x1d,0x45,0x7d,0xe2,0x03,0x66,0x84,0xfc,0xbd,0x8e,0x95,0x9f,0x58,0x99,0x7b,0x4c,0xb6,0xe5 +.byte 0xe2,0xf9,0x2e,0x92,0x58,0xca,0xa9,0x24,0x9c,0x7c,0x46,0xdf,0xea,0xb4,0x6e,0x0e,0xa5,0x9c,0x14,0xbf,0x25,0x5b,0x39,0x4a,0xaf,0x31,0xaa,0xd1,0x2c,0xe6,0x06,0x3d,0xc4,0x60,0xc7,0xcd,0x49,0x8d,0xe1,0x50,0x55,0xe4,0x72,0x68,0xed,0x43,0xb8,0x85,0xa3,0xc3,0xf1,0xf5,0xd1,0xcf,0xcb,0x57,0xac,0x04,0x16,0x22,0xe4,0xfc,0x4a,0x13 +.byte 0x60,0x3f,0x09,0xa4,0xf2,0x9b,0x34,0xeb,0x0c,0x10,0x57,0xc3,0x3f,0x15,0xb5,0x1b,0x6a,0xb3,0x7d,0x37,0x02,0x4c,0x0f,0x6f,0x8b,0x4d,0x5d,0x57,0x7d,0xbf,0x00,0x8a,0x74,0xb4,0x4c,0x5f,0x90,0x27,0x76,0x09,0x8c,0x18,0x3f,0x26,0x3a,0x09,0x06,0xdd,0x8b,0xff,0x0e,0xa4,0xae,0xef,0x0c,0x81,0xf2,0xf3,0x1f,0xe0,0x33,0x33,0x37,0xc6 +.byte 0xc3,0xfb,0x14,0xdd,0xa1,0x16,0x84,0x80,0xcb,0x37,0xe7,0x97,0x6d,0x21,0xa7,0x71,0x19,0x2b,0x2d,0x30,0xf5,0x89,0x2d,0x23,0x98,0xfc,0x60,0x64,0x4a,0x26,0x65,0x4a,0xef,0x12,0x59,0xa3,0x8c,0xd9,0xbd,0xdc,0xb7,0x67,0xc9,0x8d,0x51,0x72,0x56,0x6a,0xe5,0x59,0xa2,0x53,0x4f,0xb6,0x53,0xff,0xb0,0xd4,0x06,0x7f,0x79,0x23,0xf9,0xcb +.byte 0xbf,0x9a,0x93,0xde,0x88,0x33,0x58,0x70,0xa7,0xcc,0x07,0xb1,0x44,0xb9,0x99,0x1f,0x0d,0xb9,0xc9,0x18,0xdc,0x3e,0x50,0x22,0xfb,0x4e,0x86,0x0d,0xc0,0xe7,0x7f,0xc6,0xa1,0x52,0x0d,0x8d,0x37,0xe6,0xaf,0xe3,0x13,0xbe,0xa6,0xf9,0x59,0x39,0x0f,0x17,0x66,0xce,0xb1,0x7d,0x7f,0x19,0x1a,0xf8,0x30,0x3a,0xa5,0x72,0x33,0xa4,0x03,0xb6 +.byte 0xb6,0x9b,0xde,0x7a,0x7a,0x62,0x3d,0x85,0x98,0x8e,0x5d,0x8a,0xca,0x03,0xc8,0x2c,0xae,0xf0,0xf7,0x43,0x3f,0x53,0xb2,0xbb,0x1d,0xd0,0xd4,0xa7,0xa9,0x48,0xfa,0x46,0x5e,0x44,0x35,0x50,0x55,0xdc,0xd5,0x30,0xf9,0x94,0xe6,0x5f,0x4a,0x72,0xc2,0x77,0x59,0x68,0x93,0x49,0xb8,0xba,0xb4,0x67,0xd8,0x27,0xda,0x6a,0x97,0x8b,0x37,0x7e +.byte 0xe9,0x59,0x89,0xc7,0x5e,0xd9,0x32,0xe2,0xaa,0xd1,0xe9,0x2b,0x23,0xca,0x9d,0x89,0x7a,0xf5,0xe4,0xfb,0x29,0xcc,0x88,0xfb,0x82,0x0f,0xbf,0x47,0x54,0xca,0x2b,0x4b,0xd8,0x47,0x7f,0x65,0x38,0x5a,0xb3,0xe8,0x0b,0xd7,0xe1,0x8b,0x89,0x57,0x32,0xdb,0xa3,0x85,0xba,0xf9,0xbc,0x52,0x92,0x20,0x10,0x66,0x54,0x81,0xe1,0x49,0x3f,0xe1 +.byte 0x8c,0x2e,0x0b,0x3b,0xe7,0x49,0xb4,0x60,0x5a,0x20,0x33,0xc4,0x4e,0x81,0xef,0x96,0xda,0x73,0x90,0x2b,0xb4,0x86,0xa1,0x5c,0xcd,0xa0,0xc7,0xf3,0x06,0x0d,0x2a,0x5a,0x41,0x96,0xf5,0x40,0x1b,0x0a,0x3a,0xb7,0x38,0xe1,0xbb,0xe3,0x42,0xf9,0x52,0xe5,0x98,0xe2,0x17,0xd4,0xb0,0x09,0x73,0x75,0xc1,0x00,0x18,0x0f,0xa7,0x0b,0x58,0xc1 +.byte 0x78,0x5c,0x0c,0x05,0xd8,0xfb,0xc5,0xfd,0x5c,0x66,0xbe,0x54,0x68,0xd1,0x16,0x54,0xfb,0xc5,0x97,0xd7,0x03,0x82,0x47,0xbb,0x47,0xea,0x9e,0x8b,0x90,0x07,0xb2,0xd2,0x06,0x14,0x79,0xeb,0xb6,0xe1,0x10,0x55,0xa9,0x13,0xea,0x65,0x7a,0xd0,0xe5,0x66,0x5d,0xe7,0x7b,0x10,0x5f,0x7c,0x25,0x7d,0x4e,0x77,0xb3,0x19,0x02,0xb1,0x45,0x1c +.byte 0x1a,0x51,0x24,0x72,0xd4,0xaa,0x03,0x0c,0x37,0x2a,0x78,0x81,0x05,0xca,0x73,0xb9,0xb5,0xd8,0xf5,0x25,0x2b,0x30,0x59,0x00,0x66,0xbd,0x6c,0x38,0xa2,0xc3,0xfb,0x43,0x85,0x6d,0xab,0xca,0xd8,0x73,0xa8,0x76,0xda,0x6e,0x00,0x19,0xd0,0xb9,0x1e,0x9b,0x33,0xe4,0x57,0x68,0xf4,0xb8,0x35,0x44,0xe6,0x74,0xd2,0x33,0x64,0xa1,0x41,0xa6 +.byte 0x5a,0xf6,0x8e,0x29,0xb5,0xa6,0x21,0x8e,0xc4,0x0c,0x0c,0x16,0x81,0x08,0xef,0x0a,0x41,0x08,0x34,0xc7,0xe1,0xd8,0xa8,0x68,0xb1,0xf3,0x9a,0x7a,0xaa,0x90,0xc0,0x77,0x32,0x70,0x50,0x5c,0x92,0xfc,0x38,0x31,0xaf,0x3e,0xd8,0xd8,0x4b,0x90,0x99,0xc4,0x17,0xde,0xa6,0xb5,0x29,0xc0,0x82,0x45,0x20,0x08,0x0c,0x4f,0x76,0x36,0x56,0x7e +.byte 0x07,0x17,0x42,0x78,0xa1,0x2d,0x62,0x48,0x81,0x57,0xc4,0xcf,0xf4,0x89,0x34,0x78,0x10,0xe6,0x98,0x78,0xb0,0x69,0x15,0x06,0xdb,0x2b,0xbb,0x8b,0xa5,0x72,0x50,0x24,0xae,0x6b,0x33,0x49,0x7b,0x9d,0x69,0x74,0xc8,0x7c,0xca,0x7a,0x31,0x39,0x0d,0x72,0x78,0xc1,0x6b,0x97,0x50,0x97,0xea,0x90,0xab,0xe7,0xdf,0x29,0x2e,0xf7,0x6e,0x49 +.byte 0x95,0xab,0xbd,0xea,0x1f,0xd4,0x93,0x4d,0x30,0x6b,0x6d,0xb0,0x86,0x38,0x2c,0xc8,0x77,0x2c,0xb5,0xb5,0x5c,0xd9,0xbb,0xe9,0x7d,0xb2,0xb7,0x6b,0xd1,0x1c,0xd3,0xd0,0x66,0x51,0x63,0x8c,0xf3,0x13,0xad,0xcf,0xeb,0x82,0x12,0x1a,0x6d,0xf5,0x75,0x66,0xa2,0x55,0x30,0x64,0x1d,0x68,0x46,0x50,0x5a,0x93,0xf1,0xc2,0x13,0x68,0x95,0x55 +.byte 0x51,0xe0,0x56,0x3a,0x96,0x86,0x8e,0xfb,0x5f,0x3b,0x1f,0x49,0x9c,0x3d,0xe5,0xf2,0x8c,0x3f,0xd6,0x6d,0x17,0xc7,0x18,0x59,0x1a,0x8a,0x72,0xa8,0xb3,0x39,0xda,0xc4,0xfa,0xc5,0xca,0xdf,0x48,0x48,0xd1,0xd2,0xba,0x14,0x5d,0x28,0x3b,0x4c,0xb3,0xcb,0x8d,0x1b,0x91,0x46,0x6b,0x2d,0x21,0x21,0x99,0x98,0x6d,0xcc,0x6b,0x8e,0x91,0x1d +.byte 0x42,0xc2,0x72,0x1a,0xc6,0xd2,0xaf,0xed,0x10,0xff,0x1e,0xa5,0xae,0x16,0xc0,0x05,0xdf,0x37,0xe2,0x1e,0x2e,0x15,0x21,0x0c,0x33,0x6f,0xfd,0xed,0x3f,0x7e,0xd7,0x69,0xfb,0x76,0x79,0x65,0xe9,0xd9,0x8d,0xf6,0xc0,0x6c,0xf7,0x15,0x7f,0x04,0xd7,0x71,0xcc,0xaa,0x85,0x73,0x23,0xf1,0xc8,0x62,0xd0,0x8e,0x01,0x35,0xff,0x4f,0x4f,0x13 +.byte 0xe6,0x28,0xf1,0xc1,0x7a,0x04,0xc0,0x7b,0x75,0xac,0x1c,0x55,0xb4,0x7c,0x00,0xb9,0xe0,0x14,0x67,0xb6,0xc5,0x69,0x62,0x0b,0xe6,0xb5,0x46,0x86,0x6f,0x09,0xdf,0x84,0x2c,0xa8,0x30,0x89,0x5b,0x24,0x47,0xfa,0x43,0x24,0xd5,0x07,0xf7,0xba,0xab,0x1b,0xfd,0x60,0xad,0x89,0x5f,0x60,0x87,0x78,0x48,0xbb,0xc0,0x63,0xf4,0x27,0x86,0x33 +.byte 0xf4,0x49,0x64,0x4c,0x5c,0x94,0x9a,0xb8,0x0f,0x45,0xe2,0x92,0x7d,0x9a,0x86,0xdb,0xb7,0x05,0xe8,0xd7,0x64,0x44,0xfa,0x74,0x60,0x72,0x89,0x13,0x8f,0x2e,0x96,0x33,0xa9,0x12,0x4a,0x62,0x6b,0xc3,0xcb,0x55,0xd3,0xef,0x17,0x11,0x82,0x4a,0x51,0x77,0xbf,0x63,0xa0,0x21,0xfc,0xbc,0x0c,0x6f,0x9a,0xfd,0xde,0xbe,0x9f,0x2e,0x50,0xd5 +.byte 0x32,0xa4,0xf0,0x1b,0xed,0xfa,0xbf,0xcd,0xc9,0xd8,0xf8,0x06,0xf2,0x17,0x8a,0x92,0x18,0xb8,0xc3,0xe5,0xbf,0xc2,0xf4,0x77,0xb9,0x71,0xfb,0x60,0x6e,0xe7,0xad,0xe4,0x7d,0xd4,0x59,0xa9,0xbd,0x21,0xd5,0x03,0x69,0xb5,0xf1,0xce,0xb5,0x88,0xd9,0x1d,0xc7,0xb3,0x14,0xa6,0xb1,0x30,0x8d,0xaa,0xcd,0xe5,0x50,0xc5,0x0d,0x4b,0x6d,0xde +.byte 0x17,0x4d,0xd2,0x93,0xf3,0xc2,0x8d,0x59,0xf1,0xd0,0x2f,0xb5,0x62,0x18,0x81,0x07,0xb3,0xfb,0x08,0xb3,0xa8,0x15,0xe0,0x9a,0x4c,0xa5,0x24,0xcd,0x47,0x69,0xf9,0xf7,0xda,0xa9,0xff,0xe1,0xe2,0x43,0xe3,0x69,0xf1,0x26,0xac,0xc6,0x42,0xf2,0x32,0x42,0xfb,0x7c,0xa2,0x94,0xc6,0xaa,0xd9,0x05,0x29,0xc6,0x3d,0x45,0x44,0x1d,0x52,0x7e +.byte 0x48,0x47,0x93,0x34,0x08,0xa0,0x93,0xc2,0x5e,0x9b,0x22,0xc1,0x2a,0xaa,0xfe,0xa2,0x26,0x00,0xa8,0xbb,0xd0,0x58,0xfd,0x5a,0x09,0x4f,0xa1,0x0c,0xff,0x66,0xcc,0x88,0x3a,0x69,0x9a,0x12,0xb6,0x05,0x6e,0xdf,0x54,0x5d,0xe7,0x03,0x8e,0x95,0x86,0x68,0x83,0x83,0x6f,0x04,0x0b,0x9c,0x05,0x05,0x77,0x14,0x83,0x47,0x98,0x5f,0x22,0xaf +.byte 0xa8,0xfd,0xf3,0xe7,0x73,0xec,0xef,0xd7,0x57,0xd9,0xef,0xe7,0x1b,0x18,0x24,0x09,0xd9,0x14,0xf9,0x60,0xba,0x05,0x0f,0x8f,0x33,0x48,0xb1,0x06,0x41,0x2e,0x95,0x3d,0xf5,0xcf,0x14,0x50,0x5d,0xb6,0x93,0xeb,0xd5,0xf8,0x9f,0x7c,0x8f,0x23,0x35,0x39,0x30,0xc8,0xf6,0x74,0x07,0xc4,0x4c,0xcf,0xe1,0xdb,0x3e,0x9f,0x0a,0xfd,0x48,0x9e +.byte 0x56,0xe4,0xa7,0xa3,0x07,0x06,0x18,0xbb,0x50,0x75,0x33,0x48,0xb9,0xa1,0x4e,0x63,0x65,0xd3,0xf4,0x40,0xc3,0x2d,0x52,0x9a,0xad,0x56,0x7f,0xff,0xb0,0x46,0x24,0xa1,0x78,0x5f,0xb6,0xa8,0x72,0x28,0xb3,0x6c,0x61,0x6e,0xa0,0xfc,0xcb,0xe8,0xfe,0x07,0x28,0x97,0x1c,0xda,0x76,0xc7,0x98,0x2f,0x00,0x1d,0xf2,0x17,0xbe,0x48,0x3f,0xd3 +.byte 0xc7,0xbe,0x89,0x89,0xe1,0x96,0x75,0x1e,0xee,0xf9,0x78,0x67,0xbf,0x12,0x1e,0xe2,0x14,0xbf,0xd4,0xfd,0x49,0xaa,0xbf,0xc6,0xb8,0x4f,0x84,0xcd,0x5d,0x3c,0x45,0xb3,0xb0,0x14,0x6f,0x2d,0x6f,0x35,0xfa,0x60,0x7f,0x64,0x40,0xc8,0xde,0xa8,0x2b,0x56,0x75,0x74,0xc9,0xe1,0x2c,0xe2,0x2f,0xc2,0x3e,0xba,0xa3,0x20,0xd8,0xa3,0xbc,0x69 +.byte 0x9d,0x1c,0xcf,0x5e,0xe3,0xc0,0x66,0x72,0xce,0x22,0x96,0xad,0x47,0xc9,0x5b,0xac,0x45,0xdc,0x4f,0x8e,0xf6,0xa6,0x2e,0x4a,0x1e,0x01,0xe4,0xb7,0x83,0x68,0x92,0x2b,0x98,0xdf,0x22,0x0f,0xd9,0x4f,0x6f,0x72,0x37,0x56,0xfa,0x1b,0xbb,0x5a,0x4d,0xd8,0x5b,0xc6,0x65,0xf8,0xd4,0x4e,0xa5,0xc0,0x0f,0x2d,0xc2,0x38,0xa4,0x6c,0x33,0x2f +.byte 0x7a,0x52,0x14,0xbb,0xfb,0xb3,0xf2,0xa9,0xbf,0xa0,0xad,0xcb,0x8c,0x81,0x47,0x26,0xe9,0xfb,0xc1,0x8e,0xc6,0xe5,0x39,0x48,0xa5,0xb3,0xbc,0xb2,0xe4,0xac,0xf9,0x49,0xbb,0x34,0x2b,0xc4,0x4d,0x06,0xe4,0xd6,0x0b,0xdd,0x55,0x36,0xe6,0xaf,0x64,0xea,0x84,0xf2,0xa5,0x68,0xe3,0x4e,0x4c,0x77,0x46,0x6c,0x17,0x6e,0x08,0x99,0x96,0x1b +.byte 0xb5,0x44,0x3b,0x94,0x2d,0x0f,0xcd,0x90,0x17,0x8f,0x80,0xcb,0xc2,0x30,0xbe,0xe1,0x36,0xdc,0x1e,0x48,0xe3,0x2c,0xe5,0xc9,0xbc,0xbd,0xff,0x3f,0x95,0x59,0x35,0x58,0x2f,0x9c,0xa6,0x1c,0x45,0xa7,0x61,0xde,0xf2,0x9c,0xa3,0x04,0x0f,0xa0,0x93,0xaf,0x69,0x2b,0x0d,0x1c,0xfc,0xff,0x97,0x1c,0x69,0x7e,0x30,0x06,0x88,0x01,0xa4,0xf1 +.byte 0x32,0x36,0xed,0x56,0x89,0xff,0xa9,0x63,0x3a,0x17,0x91,0xc5,0xba,0x6e,0x38,0x84,0xb1,0xaf,0x28,0xac,0x8a,0xb2,0x60,0xbe,0x1b,0x0a,0xd8,0x05,0x22,0x25,0x56,0xbe,0x75,0x47,0x59,0xcf,0x8c,0x2e,0xb3,0xc3,0x5f,0x06,0x81,0x65,0x39,0x78,0xed,0xe3,0xc9,0x5a,0x99,0x01,0xae,0xfb,0xf6,0xed,0x55,0xf5,0xbd,0x2f,0x93,0xf1,0x62,0x6a +.byte 0x54,0x4f,0xe1,0x9f,0x0a,0x23,0x83,0xbc,0xc2,0xba,0xb4,0x6f,0xd9,0x88,0xc5,0x06,0x7a,0x83,0xd5,0xdb,0xeb,0x49,0x48,0xd6,0xc9,0x45,0xa2,0xd0,0xc4,0x06,0xd9,0x01,0xec,0x2d,0x6d,0xc1,0x95,0x69,0x22,0xd0,0xae,0x88,0x75,0x8b,0xd2,0x02,0x98,0x83,0xd9,0x10,0x27,0x8d,0x68,0x97,0x5e,0x6b,0xdd,0x51,0xbb,0x92,0x38,0xa8,0x12,0xde +.byte 0x0f,0xa4,0x1e,0x2e,0xec,0xd5,0x73,0x55,0x5f,0x46,0x6a,0x0f,0xc9,0x50,0x0d,0xb3,0x55,0x20,0xe0,0x01,0xef,0x92,0x29,0x04,0x38,0x60,0xbd,0xc7,0x0b,0x1e,0x94,0x10,0x37,0xb7,0x02,0x94,0xbc,0xde,0xdb,0xb3,0xe3,0x1e,0xd5,0xe2,0xa8,0xed,0x46,0xe8,0xd4,0x8a,0x6c,0x93,0x4e,0xb7,0x73,0xa6,0x20,0x86,0xd2,0x82,0x2f,0x78,0x80,0x34 +.byte 0x44,0x79,0x84,0x2e,0x54,0xd0,0x30,0xa8,0x06,0x0c,0xcf,0x78,0xb4,0xd7,0xe2,0xc9,0x6e,0xfb,0x37,0x47,0x8f,0xe5,0x9f,0xf8,0xca,0x58,0x9c,0xb6,0x8b,0xbe,0xf4,0x3a,0xfe,0x75,0xec,0x1b,0x22,0xfd,0x93,0x92,0x07,0x09,0xcd,0xe6,0x2f,0xe6,0x51,0x0f,0x19,0x43,0x9c,0x6a,0x32,0x38,0x7d,0xf0,0x0c,0x78,0x81,0xb7,0x5c,0xbe,0x3c,0xf4 +.byte 0xc0,0x12,0x57,0x51,0x8a,0x69,0x84,0x0d,0x1e,0x0a,0xed,0x75,0xde,0x9e,0x31,0x8a,0x9b,0x18,0x82,0x01,0x5a,0xee,0x0e,0x33,0x3c,0x8c,0x95,0xb1,0x0b,0x05,0x3b,0xb2,0x85,0xab,0xaf,0x47,0xa2,0x03,0xb6,0xbb,0xda,0xf5,0xc8,0xbe,0x0e,0x4d,0xf8,0x84,0xe4,0xfb,0xd4,0x54,0x44,0x72,0xe5,0x30,0x57,0xa3,0xb6,0x47,0x8f,0xd3,0x32,0xc2 +.byte 0x83,0x07,0x4f,0x17,0x20,0x88,0xa1,0x0b,0xb3,0xef,0x4b,0x27,0x60,0xe0,0x9d,0xec,0xc2,0xdf,0xaf,0x2e,0x74,0xae,0xa4,0x2b,0x59,0x94,0x75,0xbe,0x54,0xf5,0x18,0x62,0xd9,0xe2,0x35,0xee,0x37,0x2e,0xdf,0x48,0xf8,0x80,0x32,0xcb,0xf1,0x83,0x78,0x03,0x68,0x06,0xd7,0x82,0xc6,0x76,0x2a,0x10,0x2a,0xdb,0x73,0xe6,0x65,0x24,0x9f,0x73 +.byte 0x1f,0x55,0x55,0xb6,0x10,0x65,0x80,0x70,0x5a,0x8e,0x8a,0xc8,0x4c,0xca,0x74,0x47,0x63,0x3f,0xee,0x49,0xc3,0x86,0x0f,0x66,0x56,0x08,0xee,0x9f,0xf5,0x5a,0x89,0x4c,0xb4,0x97,0x6e,0x75,0x61,0xc0,0xa7,0x92,0xa8,0x38,0x99,0x08,0x01,0x12,0x82,0x77,0x80,0x20,0x9d,0x62,0x46,0x92,0xdd,0x39,0x4d,0xcf,0xc0,0x8a,0x3e,0x30,0x9a,0xfa +.byte 0x28,0xe8,0xd8,0xf8,0x07,0x0d,0xab,0x4c,0xd4,0x02,0x4c,0xd7,0xc3,0x16,0x89,0x24,0x84,0x52,0x7c,0xa4,0x1b,0x54,0x7f,0xc4,0x74,0x4f,0x88,0x0a,0x14,0x03,0xd9,0x1a,0x48,0xff,0x2c,0xfb,0xbf,0x33,0xf1,0xf8,0x0e,0xdd,0xc4,0x98,0xf2,0xbd,0x32,0x99,0x03,0x8e,0x56,0xc1,0x84,0x5d,0xa6,0xd7,0x21,0xf2,0x43,0xfb,0x3b,0xf5,0x6a,0x75 +.byte 0x20,0xfb,0x08,0x7b,0x66,0x15,0x47,0x31,0xb6,0xb6,0x7a,0xc9,0xe6,0xf5,0xd6,0x0a,0x14,0xb3,0x68,0x0a,0x32,0x13,0xb5,0xe6,0x56,0xbd,0xa5,0x24,0xe2,0xa3,0x7b,0x3d,0x01,0x23,0xed,0x08,0x09,0xb5,0xdb,0x7c,0xa9,0x4b,0x23,0xdb,0xa2,0x25,0x0c,0xc6,0xa4,0x0d,0xbb,0x1a,0x5d,0x1b,0x42,0x0b,0x86,0x72,0xc3,0xca,0x5b,0x14,0x04,0xa3 +.byte 0xd7,0x01,0xe7,0x17,0x78,0xd0,0x54,0xde,0xd4,0x76,0x3d,0xe1,0x7d,0x26,0x3e,0xb4,0x71,0x42,0x84,0x36,0x58,0x78,0x22,0x32,0x26,0x0e,0xc8,0x99,0x05,0xe3,0x4a,0xa6,0x5a,0x1a,0x06,0x0a,0x88,0x47,0x51,0x5c,0xa8,0x72,0x70,0x0c,0x62,0x5f,0xf3,0x1e,0x02,0x50,0x20,0xc6,0x5c,0x50,0x30,0x1f,0x4e,0x5a,0x3a,0x02,0xc9,0xca,0x3f,0xa4 +.byte 0xf1,0x66,0x05,0xf3,0x19,0xe5,0xaa,0xdb,0x75,0x51,0xc1,0xb8,0x94,0xfa,0x2d,0xb6,0x8b,0x42,0xdc,0x9a,0xa3,0x13,0xeb,0x95,0x8d,0xf0,0x65,0x87,0xc9,0xa1,0x43,0xb4,0xfe,0x76,0xf4,0xc8,0xbb,0x19,0x96,0x84,0x9d,0x2f,0x92,0xe8,0x22,0x9a,0xf0,0xd5,0xf4,0xc4,0x8d,0x19,0x59,0x21,0xbf,0x15,0xfd,0xa6,0xc4,0xde,0x77,0x58,0xae,0x93 +.byte 0xb3,0xff,0x44,0x49,0x6e,0x37,0x94,0x04,0xd2,0x96,0xe9,0x80,0xd8,0xe3,0x93,0xd8,0xb4,0x7f,0x5f,0xcf,0xe5,0x9d,0x51,0x92,0xac,0x5d,0x9f,0x23,0x3a,0x3e,0xdf,0x96,0x68,0x9a,0x46,0x9b,0x1a,0x06,0x44,0x54,0xc4,0x2e,0x19,0x0f,0x50,0xee,0x73,0xda,0x39,0x7e,0xec,0xcb,0x1d,0x39,0xf7,0x9f,0xbc,0xe0,0x6d,0x49,0x56,0xf8,0xa7,0x24 +.byte 0x70,0xab,0xe1,0xc3,0x82,0x99,0x0a,0x4d,0x64,0x41,0x37,0xab,0x92,0x76,0xeb,0x6a,0x2a,0xa5,0xab,0x75,0xd7,0xe3,0x6a,0x72,0x4a,0x2b,0x57,0x02,0xc7,0xbe,0xd5,0x35,0xce,0xdf,0xee,0xf1,0xc6,0xe6,0x69,0xb7,0x76,0x99,0x22,0xb0,0xb9,0xe1,0x18,0x91,0x9a,0x35,0xd9,0x3a,0x19,0xc7,0x77,0xf2,0x2d,0xae,0x04,0x2e,0xb7,0x35,0x97,0xa5 +.byte 0xc6,0x97,0x4e,0x5d,0xbe,0xa9,0x35,0x2b,0x53,0x1a,0x6b,0x4e,0xa8,0xa6,0x22,0x48,0x2c,0x81,0x25,0xac,0x30,0x89,0x7b,0xb3,0x38,0x34,0x42,0x0b,0xa5,0x5f,0x02,0xe8,0xee,0x12,0x9b,0xce,0xe7,0x10,0xf9,0x65,0xb6,0xc5,0x74,0x06,0xef,0xc8,0x95,0xb3,0x40,0x30,0xec,0x1f,0x8e,0xeb,0x93,0x31,0x91,0x5a,0x2f,0xc2,0x90,0x85,0xaa,0x4c +.byte 0x51,0xc4,0xd0,0x3e,0xc8,0xc9,0x61,0x46,0x96,0xd4,0x60,0x56,0x7d,0x91,0xc4,0x24,0x76,0xfb,0x09,0x08,0x48,0x2f,0x4a,0x73,0x90,0x8e,0x9d,0xb2,0x38,0xa8,0x95,0x3e,0x6d,0x10,0x57,0x91,0x8d,0x55,0x62,0x1f,0x21,0xc7,0x01,0x15,0xb0,0x71,0x0b,0x26,0xbc,0x10,0x33,0x3e,0x79,0x37,0x64,0x85,0x98,0x42,0x21,0xcc,0xff,0x51,0x9a,0xc2 +.byte 0xe0,0x51,0xc3,0xff,0xf2,0x14,0x3d,0xe8,0x89,0x12,0xe7,0xcd,0x58,0x2f,0x87,0xfb,0x4a,0x50,0x6c,0x4d,0xdf,0x6f,0x64,0x9c,0x64,0x93,0x49,0x89,0xb6,0x0d,0x10,0x3f,0x13,0x9d,0x9a,0x35,0xf1,0xc0,0xe7,0xf0,0x9b,0xe8,0x39,0xd3,0x32,0xb2,0x23,0x67,0x77,0xdb,0xbc,0x0d,0x19,0x77,0x7a,0xbe,0x54,0x56,0x64,0xec,0xb6,0x2e,0x03,0xc5 +.byte 0x35,0xda,0xf1,0xc7,0x7d,0x0c,0x5a,0x32,0xec,0x86,0xdf,0xdb,0x94,0x73,0x4e,0xe3,0x45,0xf6,0xb2,0x63,0xc4,0xb7,0x80,0x59,0x4b,0x82,0x0b,0x61,0xa0,0xd5,0x43,0x18,0x78,0x35,0x93,0xde,0x46,0xa3,0xa2,0xd5,0xa2,0x71,0xec,0x3e,0xee,0x7a,0x89,0x7f,0xe9,0x70,0xff,0xad,0xae,0xa3,0x64,0xde,0x61,0xea,0x71,0xc2,0x37,0x98,0x8a,0x33 +.byte 0xd1,0x5f,0x03,0x08,0x23,0x24,0xc7,0x6c,0x62,0x24,0x6d,0x3f,0x44,0x8e,0x7c,0x9f,0x64,0x87,0xa5,0x79,0x0b,0x16,0x7e,0x4e,0xc0,0x0e,0xb8,0x77,0x56,0x9c,0xa5,0x7d,0x2d,0x5d,0x7d,0x81,0x13,0x2c,0x08,0xd5,0x83,0x84,0x38,0xfe,0x50,0x6f,0xa7,0x30,0x1f,0x06,0xee,0xab,0x13,0xc2,0x19,0xe6,0xcf,0x7b,0x85,0xfc,0x31,0x5b,0xdf,0xb8 +.byte 0x0e,0xe8,0x72,0xba,0x97,0x03,0x25,0xbc,0xad,0x74,0x7c,0xe1,0x59,0xf7,0x08,0xc1,0xe3,0x2d,0xb1,0x05,0xe7,0x1f,0xb9,0x0f,0x09,0xcd,0xe6,0x4f,0x5a,0xf6,0xcc,0xea,0xc7,0x92,0x35,0xf5,0xbc,0x3f,0xef,0xc9,0x2b,0xb4,0xd7,0x66,0x50,0xaa,0x80,0xb9,0xaf,0x5d,0x02,0x9c,0x77,0xdf,0xc0,0xc7,0xe2,0xbf,0x7d,0xff,0x69,0x63,0x3e,0x7c +.byte 0x91,0x94,0xae,0xa4,0x0a,0x25,0xa3,0x1f,0xf3,0xc6,0x88,0xda,0x82,0xac,0xbc,0x1f,0x8d,0x53,0xd6,0xfd,0x2b,0x5c,0x33,0x6d,0x03,0x68,0x92,0x38,0x07,0xeb,0x85,0x7f,0x55,0x89,0x17,0x58,0x7f,0xc7,0xb4,0x7a,0xff,0x15,0xe5,0xe0,0xea,0xce,0xac,0x3f,0x0f,0x09,0x25,0xfa,0x80,0xe3,0x07,0x89,0x4e,0xbf,0x7e,0xc2,0x42,0xf1,0x18,0x78 +.byte 0x05,0xe3,0x6a,0x2e,0xf7,0x2e,0xe5,0xbf,0x63,0x9e,0x48,0x69,0xe6,0x3c,0x4b,0x12,0x73,0x58,0xde,0x0c,0x73,0x27,0x9a,0x95,0xfa,0x51,0x8c,0xbb,0x74,0x31,0x53,0x4e,0x9a,0x13,0xda,0x49,0xf0,0x8b,0xb4,0xcd,0xc1,0xe9,0xaf,0xd6,0x59,0x59,0xa8,0x24,0x94,0xd9,0x4b,0xf8,0x20,0x79,0xa0,0x79,0x01,0x08,0x84,0x9b,0x04,0xe7,0xda,0x06 +.byte 0x22,0x3e,0x85,0x23,0x0c,0xa9,0xe5,0xcd,0xd3,0xc4,0x27,0x8c,0x4e,0x75,0xe4,0x60,0xb5,0xe9,0xc5,0xb7,0xb1,0x3a,0x84,0x68,0x40,0x3e,0x36,0x1b,0x9a,0x64,0x50,0x45,0x6f,0xc6,0x58,0x70,0x46,0x1a,0xca,0xf6,0x81,0x02,0xa8,0x17,0x4d,0x92,0x0d,0xae,0x88,0x1a,0xbd,0x52,0xc0,0x32,0xb1,0x2d,0x2d,0x12,0x9c,0x29,0xfa,0xa6,0x70,0x5f +.byte 0xe7,0x0b,0xd5,0x5d,0xa5,0x49,0x9e,0x9e,0x5b,0x55,0xbc,0xce,0x5b,0xb4,0xef,0x3f,0xe4,0x7c,0x50,0xef,0x58,0xf5,0xfe,0xcc,0xf6,0xd0,0xf1,0x3a,0x0b,0xf2,0x3e,0x1c,0xce,0x22,0x7e,0x88,0x1c,0x8f,0x9a,0x69,0x76,0xa9,0xf0,0x18,0xa8,0x76,0x7f,0x0c,0xa6,0xfd,0x67,0x43,0xc7,0x43,0x67,0x98,0x6e,0x37,0xd4,0x82,0x29,0x62,0xa6,0xcf +.byte 0x2b,0x7c,0xee,0x14,0x4d,0x2d,0x1a,0xfc,0xc6,0xaf,0x5b,0xea,0x8a,0xa8,0x9a,0x3b,0xab,0x7d,0x76,0x15,0x50,0xe8,0x95,0x31,0xc8,0x5d,0x5d,0x19,0x68,0x07,0xf5,0xb0,0x29,0x5f,0x79,0x4f,0x0d,0x2b,0xba,0x1d,0xd2,0xf2,0x83,0x50,0x89,0x0b,0x96,0x16,0xde,0x7c,0x04,0xea,0x9c,0x75,0x97,0x7e,0xd7,0x2c,0xee,0x82,0x7c,0xbf,0x0b,0x71 +.byte 0x05,0x59,0xd7,0x11,0x70,0x8e,0x41,0x62,0x91,0x38,0x3a,0x69,0x3f,0x3d,0xde,0x8e,0x03,0x0a,0xea,0xfb,0xea,0x36,0xf0,0x5c,0xb6,0xdf,0x9a,0x66,0x9e,0x64,0x43,0xaf,0xb7,0x83,0xd1,0xef,0x7c,0xb6,0x9b,0x40,0xd8,0x0f,0x0e,0x0b,0xa7,0xd0,0x98,0xca,0x8e,0x3b,0xed,0xb7,0xa5,0x19,0xca,0x67,0x30,0x87,0x17,0x0e,0xc4,0xe1,0xaa,0x6e +.byte 0xdb,0x67,0xbd,0xf5,0xed,0x10,0x68,0xb1,0x43,0x73,0xaa,0x99,0x1a,0x83,0x0d,0x1a,0x5a,0x8b,0xc8,0xff,0xe9,0xe0,0x1c,0x15,0xda,0xb0,0x99,0x90,0xce,0x1f,0xfd,0x17,0xd2,0xfa,0x8f,0x3a,0xe8,0x1b,0xd3,0x96,0x2a,0x0d,0xa9,0x4d,0x6d,0x77,0x53,0xe8,0x8f,0xc7,0x6b,0xb4,0x3b,0x6d,0x0c,0x8e,0x35,0x67,0x09,0x6e,0x43,0x36,0x52,0x3e +.byte 0x0e,0xf6,0x4f,0x16,0x40,0x45,0x7f,0xab,0x39,0xf2,0x23,0xfb,0x4e,0xea,0x6e,0xcf,0xa0,0xb6,0xec,0x6d,0x93,0x1b,0x6f,0x9f,0xd6,0xce,0xcd,0x1e,0x90,0x5c,0x7d,0x61,0xc4,0xae,0x02,0xb2,0x7a,0xb2,0x25,0x59,0xac,0x0a,0xcb,0xc6,0x28,0xa2,0x9c,0x7b,0x4b,0x05,0x5a,0x23,0x55,0xc8,0x9a,0x72,0xe6,0x3b,0x91,0xa2,0x9b,0x12,0x1c,0x1f +.byte 0x4b,0x85,0x42,0x9d,0x73,0xf9,0x50,0x3e,0x12,0xc4,0x51,0xb4,0xe1,0x2a,0x08,0xfc,0xf9,0xc8,0x5a,0x53,0x79,0xcc,0xd1,0x24,0x4c,0xc1,0xf6,0xe7,0x10,0x9d,0xe6,0xce,0xcc,0xc7,0x04,0xf8,0x7a,0xd4,0x2f,0x0a,0x97,0x32,0xaf,0x38,0x77,0x97,0x78,0xc8,0xa9,0x9a,0xca,0x65,0xee,0x2b,0x07,0x0e,0xb1,0xaa,0x3c,0xee,0x03,0x85,0xf7,0x09 +.byte 0xd1,0x03,0xe5,0x4f,0x8a,0x6b,0xba,0x83,0xd2,0x6a,0x05,0xe6,0x4e,0x59,0x21,0x26,0xcc,0x8d,0x4a,0x91,0x21,0x6b,0xe5,0x7a,0x83,0xed,0x4e,0x95,0x4b,0x16,0x98,0x3f,0x2d,0x51,0xc5,0x67,0x56,0x58,0xc9,0xc3,0x32,0xff,0x91,0x9d,0x7f,0x6d,0xc7,0x8a,0x40,0x58,0x56,0x35,0xca,0xc1,0xa9,0x07,0xe2,0xc6,0xe1,0x8f,0x7b,0x7c,0x68,0x4e +.byte 0xde,0x19,0xc8,0x9c,0x41,0x65,0x74,0x33,0xb5,0x5b,0xf7,0x47,0x91,0x51,0x41,0x56,0x54,0xaa,0x8e,0xa5,0x1f,0xdb,0x50,0xa4,0x97,0x7a,0xea,0x86,0x2e,0xfd,0xdd,0x64,0x23,0x6e,0x44,0x28,0xfb,0xae,0xe8,0xc2,0x38,0x96,0x56,0x2e,0xd8,0x7e,0x3a,0xc8,0xc6,0x7f,0x20,0x15,0xad,0x9f,0xfa,0x5c,0x55,0xf5,0xe1,0x9a,0x07,0x84,0x5b,0x81 +.byte 0x39,0x4b,0x70,0xc3,0xfd,0x2b,0xc5,0xb7,0x47,0x36,0x74,0x5a,0x85,0xaa,0x45,0x94,0x8e,0xbe,0x7f,0x6c,0x45,0xf5,0x02,0x4e,0x5f,0x16,0x04,0x7e,0xfa,0xb8,0xa9,0x38,0xc4,0xd9,0xca,0x5f,0x7a,0xe3,0x96,0x78,0x82,0xa0,0xac,0xef,0xc4,0x2a,0xb5,0xf4,0x7d,0x28,0x8c,0x25,0xba,0x4e,0xd5,0xd5,0xd1,0x24,0xc6,0x05,0xb2,0x18,0x2d,0x66 +.byte 0xea,0xe3,0x42,0x79,0x33,0x9e,0x70,0x3a,0x1b,0x5a,0x8e,0xcb,0x03,0xa8,0x43,0xf3,0xd5,0x66,0x41,0x10,0xd7,0x09,0xf0,0x28,0xe5,0x25,0xe6,0xac,0x9a,0xe6,0x34,0x36,0xfb,0xc4,0xa6,0x9a,0xd0,0x24,0x4d,0x18,0xf9,0xd1,0x8e,0xca,0x92,0x83,0x0f,0x55,0x54,0x6d,0x72,0x81,0x81,0xdb,0x72,0x1f,0xd6,0x32,0xb9,0x32,0x45,0x84,0x9c,0x66 +.byte 0x68,0x7e,0xab,0xb3,0xca,0xf5,0x4f,0xdd,0xb4,0xee,0xbb,0x05,0x70,0xbe,0x4f,0xd1,0x27,0x01,0xcc,0x7c,0x4f,0x47,0x55,0xce,0x91,0x73,0x6f,0xff,0x8d,0xfc,0x0c,0x4c,0xaa,0xfc,0xce,0x9f,0xf3,0x4a,0x46,0x92,0x89,0x84,0x8f,0x4d,0x94,0x37,0xda,0xe3,0x11,0x0d,0x63,0x60,0xcb,0x40,0x8f,0xe8,0x0f,0xf9,0xa1,0x89,0x64,0x44,0x45,0x74 +.byte 0xc5,0xa2,0x73,0x33,0x08,0xa2,0x59,0xb0,0xeb,0x7b,0x7b,0xa7,0x28,0x4c,0x13,0x6a,0x04,0x15,0x14,0xd0,0x3e,0x5e,0xec,0xe1,0x3f,0xe5,0x93,0x06,0x6b,0x60,0x50,0x1c,0x90,0xc0,0x5c,0xea,0x7e,0x58,0xf1,0xed,0xba,0x43,0x0b,0x84,0xf7,0xa4,0xbd,0x4c,0xed,0x88,0x5b,0xae,0xa2,0x0a,0xf6,0x06,0xfd,0x43,0x63,0xfe,0x8a,0x03,0x21,0x8b +.byte 0x27,0xc6,0xef,0xa3,0xa9,0x3a,0xc1,0x8b,0x65,0x62,0x25,0x85,0xaa,0x2f,0xff,0x22,0x96,0xb7,0x5c,0x82,0xde,0x21,0x4e,0x0d,0x8d,0xd9,0x7f,0x97,0x79,0x95,0x6c,0xe6,0xfd,0xb1,0x7c,0x84,0xc8,0x73,0xbc,0x50,0x2f,0x87,0x03,0x56,0xcf,0xea,0x7f,0xed,0x17,0x7d,0xf7,0x61,0x6b,0x6f,0x5b,0xd3,0xe4,0x83,0xbd,0x8b,0xd3,0x8e,0x51,0x57 +.byte 0x3d,0xcc,0xe4,0x09,0xb9,0x73,0x1f,0xb4,0x47,0x5e,0xf2,0x10,0x3e,0xf4,0x9c,0x86,0x02,0xdf,0x3e,0x75,0x1c,0x9b,0xb5,0x0f,0x31,0xc6,0xbb,0x00,0xb4,0x8a,0x1a,0xe5,0x0d,0x9c,0x3e,0x93,0x61,0x5a,0x61,0x86,0x12,0x64,0xaa,0xfd,0xa2,0x6e,0x8f,0xcc,0xcd,0x60,0xa1,0xad,0x6d,0xdc,0xa2,0x7b,0x5a,0xe0,0xee,0x27,0x5d,0xc5,0xfe,0x1f +.byte 0x7b,0x9f,0x33,0xf1,0xee,0x2a,0x58,0x39,0x56,0x14,0x4f,0x2f,0x11,0x26,0x6b,0x56,0x7c,0x75,0xb7,0xc3,0xa7,0xf6,0x54,0xd8,0xa7,0xbb,0x73,0xb5,0xa5,0x83,0x1e,0x65,0x7e,0xa7,0x85,0x74,0xa4,0x04,0x0e,0x26,0x01,0x88,0xbc,0x8b,0x98,0x0c,0x9b,0x74,0x22,0x44,0x16,0x16,0xed,0x94,0x81,0x81,0x13,0x26,0xc9,0x27,0xa9,0xa7,0xe0,0x45 +.byte 0x69,0x6e,0x33,0xcc,0xa3,0x15,0x10,0x99,0x84,0x06,0x95,0x00,0xbb,0xc6,0x8e,0x4e,0x37,0x1b,0x23,0xb2,0xf7,0x4d,0xd7,0x24,0x68,0x6b,0xaa,0x2e,0x57,0x8d,0xd6,0x4e,0xa2,0x69,0xd8,0x8d,0x84,0xb2,0x85,0x91,0x30,0xbf,0x41,0xab,0xcf,0x5c,0xa6,0x51,0x1e,0xf5,0x79,0x5a,0x20,0xfa,0x3d,0x0a,0xc5,0xd7,0x3f,0xa6,0xcc,0xf6,0x9b,0x76 +.byte 0xe0,0xec,0x9e,0x0b,0x23,0xe4,0x74,0x36,0x14,0x6f,0x24,0x9d,0xe7,0xb2,0x41,0xd7,0x68,0x37,0x67,0xdc,0x01,0xb1,0x20,0xf9,0x8b,0x0b,0xf5,0xa7,0x95,0x78,0xa0,0x6c,0x4b,0xc0,0x44,0x92,0x4a,0x75,0x0f,0x61,0xde,0xc3,0xc2,0x3d,0x17,0xa0,0x4d,0x57,0x8b,0x11,0x35,0xbd,0x49,0x87,0x05,0xba,0x5d,0x1f,0x76,0xd4,0x0f,0xb0,0x5b,0x5f +.byte 0xb7,0xf8,0xcf,0x12,0x54,0x19,0x9a,0x49,0x6a,0x42,0xad,0x93,0x85,0x0b,0xe7,0x8c,0x30,0x59,0x82,0x82,0x2d,0xd9,0x89,0xf5,0x8c,0x39,0x9c,0xf5,0xcd,0x25,0x22,0x74,0xcf,0x56,0xa2,0x15,0x40,0xa6,0xa8,0xfc,0xdc,0x85,0x9e,0xab,0xd6,0x94,0x5d,0xd6,0x73,0x07,0xed,0x7b,0x76,0x11,0x67,0xf5,0x52,0xac,0x1a,0x69,0x1f,0x4a,0xa2,0xaa +.byte 0x4d,0x11,0xe0,0xc4,0x4c,0x6e,0x9e,0x8e,0x13,0x46,0x0b,0x95,0x40,0x53,0x35,0x53,0x58,0x7f,0x81,0x5f,0x17,0xd7,0x5e,0x53,0x86,0xf3,0x1b,0x70,0xf1,0x95,0x8f,0xf6,0xd4,0x6f,0x55,0x92,0xa2,0x38,0xd3,0x43,0x6c,0x7e,0xa2,0x21,0x5b,0x18,0x11,0xdd,0x03,0x52,0xe6,0xe5,0xc0,0xc5,0x4e,0x8e,0xda,0xdb,0x91,0xcf,0xf7,0x75,0xc2,0x33 +.byte 0x69,0xd1,0xd1,0x29,0x9d,0x51,0x79,0x91,0xe4,0x58,0x05,0xa5,0xf6,0x54,0x16,0x3e,0x42,0xf3,0xc4,0x1f,0x88,0x94,0xfc,0x6b,0x53,0xb1,0xd5,0x17,0xe6,0xab,0x77,0x33,0x8a,0xd0,0x93,0x74,0x02,0xe0,0x81,0x5e,0xbe,0x2f,0x4d,0xcd,0x25,0x0b,0xd0,0x06,0xd8,0xc9,0xf9,0xcf,0x8e,0xf8,0xc3,0xe2,0x33,0x60,0xe5,0xfa,0x89,0x68,0xf8,0xb7 +.byte 0xef,0x9d,0xfc,0x9d,0x76,0x13,0x2d,0x9d,0x18,0x7d,0x05,0xb4,0xa7,0xa3,0x8a,0x91,0xe0,0x73,0x65,0x89,0xb4,0xc1,0x53,0x7c,0xdc,0xf2,0xab,0x39,0x94,0xc7,0x3d,0xf8,0x1c,0x8f,0x49,0x37,0xee,0xc1,0x19,0x84,0x15,0x3b,0x36,0xb2,0xc2,0xe1,0x16,0xe2,0xfb,0xde,0x1f,0x0e,0xa4,0xea,0x59,0x67,0x2d,0xea,0x47,0xe5,0x2c,0xd1,0xb5,0xa9 +.byte 0xbd,0x5c,0x92,0x34,0x8b,0xc5,0xab,0x4f,0x2b,0x6b,0xc4,0x8b,0xdb,0xbb,0xcb,0x86,0x34,0x35,0xa0,0x5c,0x29,0x1a,0x8b,0xce,0xdc,0xd7,0x46,0x2b,0x20,0x9d,0xea,0xa8,0x97,0x68,0x37,0x56,0x03,0x7d,0x4f,0xb6,0xfc,0x30,0x82,0x68,0xb4,0x56,0xf3,0xbe,0x58,0xcc,0x20,0xc1,0x53,0x9f,0xbb,0x0b,0x2b,0x6e,0xa0,0x2d,0xc0,0x61,0x02,0x0b +.byte 0xf9,0x0e,0x55,0xb8,0xb8,0x23,0x6e,0x50,0xc0,0x36,0xb8,0xf6,0x5e,0xb3,0xa7,0x8f,0xf8,0x7f,0xd0,0x5d,0x0a,0xc4,0x2b,0xa9,0xd3,0x76,0xcf,0x4d,0x27,0xda,0xac,0xf3,0xb0,0xca,0x00,0xa0,0x94,0x12,0x20,0x89,0x22,0xa9,0x89,0xe4,0x23,0x71,0xe0,0xdb,0xec,0xb0,0xa9,0x2e,0x45,0xf6,0x8d,0x1e,0x4b,0x0e,0xc7,0xf8,0x40,0xd6,0xf4,0x2f +.byte 0x80,0x3e,0xf8,0xfb,0xcf,0x7b,0x54,0xb5,0xbd,0x55,0xf2,0x37,0x46,0x9f,0x32,0x45,0x87,0xa3,0x6a,0x51,0x25,0x43,0x54,0xa2,0x92,0xc6,0xbe,0xa4,0x33,0x54,0x82,0xc7,0xf1,0xe4,0x52,0xf9,0x09,0xac,0xc3,0xb1,0x25,0x86,0xc7,0x89,0x83,0x2c,0xf6,0x35,0x9e,0xd1,0xd8,0xb1,0x71,0xed,0xfa,0xae,0x09,0x83,0xb3,0xf0,0xde,0x24,0xed,0x3c +.byte 0xc6,0x60,0xe8,0x15,0x49,0x93,0x29,0x82,0xbf,0x1d,0x23,0x17,0x11,0xea,0xa7,0x53,0x83,0xa5,0xc1,0x9e,0x02,0x17,0x08,0x99,0xa6,0x72,0xaf,0x82,0x3f,0x0b,0x69,0xca,0xb8,0x72,0xa9,0x31,0x71,0x20,0x32,0x57,0x89,0x9b,0x16,0x92,0x54,0xc0,0x99,0x6d,0xa4,0xbf,0x5a,0xb5,0x53,0xa7,0x4c,0x69,0xd8,0xf7,0xe7,0x4c,0xc0,0x76,0xb6,0x35 +.byte 0xdd,0xe7,0xb2,0xd9,0x1c,0xd5,0xf7,0x39,0x32,0x44,0x48,0x02,0x85,0x69,0x02,0xad,0xe6,0xfc,0xbb,0x07,0x9e,0x7f,0xee,0x6d,0x07,0x12,0x21,0xeb,0x67,0x4d,0x74,0x90,0x8f,0x79,0x51,0x9d,0x8a,0x63,0x24,0xab,0x6f,0x8f,0x73,0xd3,0x91,0x68,0x15,0xa9,0x6a,0x84,0x92,0xc2,0xd4,0x4d,0xa8,0xe1,0x4f,0xa2,0x1e,0x34,0xa3,0x9a,0x04,0xf2 +.byte 0xfc,0xc4,0xe7,0xd0,0x52,0xc4,0x49,0x51,0x8e,0x7d,0xaa,0x74,0xaa,0x08,0xbe,0x08,0xf6,0xe4,0xc1,0x61,0xff,0x2e,0x9c,0x17,0x61,0xb6,0x01,0x44,0x18,0xe8,0x5e,0xa9,0xfb,0x02,0x21,0xbb,0x08,0x5c,0xe0,0xd3,0x0c,0x98,0xc5,0x93,0x2a,0x1c,0x69,0xf3,0xe8,0x8b,0x36,0xa0,0x9d,0x1e,0xda,0x18,0x14,0x06,0x7f,0x75,0x3d,0x42,0x92,0x5a +.byte 0xb9,0xb7,0xc0,0xc0,0xb0,0xc5,0xa9,0xb2,0x67,0x24,0xc2,0x28,0x29,0xcb,0x78,0x8e,0xf3,0xd1,0x37,0x63,0xca,0xc8,0x9a,0x1b,0x38,0xa5,0x9f,0x0e,0x0d,0x26,0x5b,0xfe,0x2f,0xdf,0x4f,0xb9,0x21,0x8c,0xc8,0xe0,0x9f,0x71,0xb9,0xc3,0x6c,0xd8,0xd3,0x2f,0xe4,0x3c,0x67,0x35,0x45,0x74,0x7f,0xcb,0x13,0xda,0x64,0x47,0xff,0x6f,0x05,0xf0 +.byte 0x87,0x8d,0x0d,0x1f,0x10,0x47,0x0e,0xf6,0x9d,0x89,0x6d,0x79,0x04,0x77,0x8a,0x6c,0xeb,0x7d,0x9b,0xd7,0x65,0x82,0xa8,0x95,0xa2,0x8c,0x02,0x91,0x0d,0xf2,0xe8,0x65,0x60,0x0d,0xb6,0x1d,0xf4,0xf3,0x41,0x75,0x33,0x21,0x13,0x22,0x93,0x01,0x2f,0x11,0xe7,0xed,0x45,0x56,0x90,0xec,0x0b,0x99,0x8e,0x84,0xc8,0x76,0x31,0x1d,0xb9,0xcb +.byte 0x87,0x3f,0x5f,0x39,0xeb,0xe8,0x9e,0x5e,0x96,0x9e,0x42,0x64,0xf3,0xef,0x00,0x1f,0x2a,0x6c,0x18,0x67,0xbd,0xdd,0xf9,0x65,0x11,0x1b,0x9c,0xd7,0xf3,0x3d,0xb2,0x6f,0x88,0xf7,0xd2,0x26,0x06,0xef,0xc8,0x23,0x3f,0x46,0x5d,0xf0,0x96,0x40,0xb1,0xdd,0xad,0xe4,0xee,0xb6,0xc2,0x67,0x18,0x46,0x67,0xc4,0xa5,0x7e,0x3e,0xce,0x72,0x47 +.byte 0xca,0xc3,0xa7,0x94,0x56,0xe2,0x23,0x03,0xcf,0xd0,0x18,0x55,0x30,0xe3,0x14,0x00,0xda,0x0f,0xaa,0x7f,0x20,0xaf,0x3b,0x24,0x43,0x7a,0xaa,0xd4,0x12,0x42,0x10,0xe4,0x44,0x8a,0x7f,0xf1,0x74,0x9d,0xe0,0x28,0x60,0xce,0xdd,0x04,0x96,0x03,0x80,0xcb,0xaa,0xa9,0xb5,0xc7,0xb4,0xbb,0xc7,0x9a,0x93,0xd8,0xff,0x3b,0x8f,0x1f,0xb7,0xce +.byte 0xed,0xbc,0xde,0x9f,0x9e,0x56,0x96,0x65,0xba,0xe7,0x89,0x03,0xb2,0xbd,0xfe,0xa7,0x02,0xeb,0x33,0x9a,0x8b,0x5b,0x36,0x64,0x17,0x9f,0xd2,0xe4,0x75,0xb5,0xfb,0x21,0x03,0xa4,0xe7,0xb4,0x49,0x72,0xfd,0xf3,0x1e,0x5f,0xdb,0xe5,0x6c,0x92,0x51,0xe7,0x91,0x55,0xb7,0x82,0x18,0x05,0xc3,0x2c,0xf1,0x23,0x61,0x36,0xad,0x80,0x1b,0xde +.byte 0xe1,0x51,0x4e,0x51,0xa1,0xf6,0x5a,0xb9,0x03,0x48,0xa7,0x12,0x88,0x63,0x30,0xff,0x48,0xfc,0x92,0x30,0x9a,0xca,0x08,0x1b,0x64,0xa9,0x74,0x2a,0x64,0x42,0x7d,0xa9,0xa4,0x9d,0xcb,0x59,0x71,0x53,0xc1,0xa8,0xa6,0xb5,0x47,0xf9,0x87,0xb5,0x41,0x58,0x92,0x14,0xf7,0xbd,0x10,0x45,0x37,0x20,0x1d,0x5b,0x42,0x04,0xed,0x69,0x4c,0xa5 +.byte 0xdc,0x2a,0x58,0xba,0x00,0x1e,0x05,0x9c,0x3c,0xbf,0x65,0x76,0xd1,0x11,0xe0,0x15,0x22,0xb0,0x2a,0x53,0x32,0x0f,0x6e,0x08,0x4e,0x27,0xc2,0x71,0x14,0x20,0xee,0xb0,0x0b,0x60,0xef,0x54,0xae,0x2c,0xe0,0x1d,0x30,0xac,0x0d,0x3a,0x93,0x15,0x0a,0xe7,0x14,0xf3,0x1a,0x67,0xb1,0x43,0x85,0xbd,0x06,0x53,0xab,0x6d,0x5d,0xe7,0xe3,0x82 +.byte 0xb8,0x39,0x35,0x10,0x87,0xe7,0x90,0x4d,0x9c,0x6f,0x83,0xad,0xa2,0x43,0x7a,0x5d,0xc1,0x8a,0x39,0xa3,0xa6,0xda,0x48,0x5c,0x9b,0xe1,0x0d,0x69,0xfc,0x87,0x18,0xdd,0x34,0x9a,0xb4,0x9c,0x04,0x0d,0x49,0x18,0x3e,0x38,0xd8,0x01,0x67,0xb1,0x7f,0x6b,0xb5,0xfe,0x58,0x1c,0x64,0x11,0x10,0x6b,0xc1,0xca,0x56,0xe3,0x12,0x8c,0xb4,0xac +.byte 0x03,0xbd,0xc1,0x54,0xbe,0x5c,0x70,0x6f,0xdd,0x73,0xa3,0x84,0xcd,0x0b,0x1b,0xbf,0x05,0xac,0x27,0x11,0xe8,0x5f,0xc3,0xb9,0x68,0xc2,0xe9,0x3f,0x5a,0x9b,0x28,0xca,0x65,0x5e,0x66,0x4e,0x50,0xa9,0x81,0xb1,0x10,0xc1,0x2c,0xa5,0x62,0xc8,0x52,0x07,0xa5,0xa1,0x99,0x16,0x7b,0x08,0xa4,0x1e,0xf4,0x50,0x8f,0xb2,0x42,0xa5,0x19,0xa2 +.byte 0x34,0x91,0xcf,0xa7,0x5e,0x73,0x6b,0xc2,0xa3,0x4d,0xdd,0x7c,0x26,0x46,0x34,0xe6,0x5d,0x54,0x52,0xe3,0x1e,0xc1,0x10,0x36,0x7c,0xc9,0xd2,0x1e,0xca,0xeb,0x80,0xc5,0x3c,0x04,0xf6,0xb7,0x09,0xd4,0x3e,0x67,0xc3,0xf6,0x6b,0xd4,0x60,0x00,0xc9,0x68,0x17,0x39,0xbc,0xcd,0x14,0x32,0xfc,0x33,0xa4,0xb0,0x6f,0x12,0x6b,0x5f,0xe2,0x15 +.byte 0x1c,0x9a,0x15,0x4f,0x0b,0x7d,0x4c,0xa0,0x89,0x40,0xb3,0x0e,0x84,0x90,0xb3,0xc6,0x3e,0xa5,0x0b,0x81,0x66,0x14,0x5f,0x8d,0xe0,0xbf,0xf7,0x9d,0xa4,0x4e,0x69,0xd5,0xac,0x0f,0x6c,0x29,0x94,0x8f,0x3b,0x4b,0xed,0x5b,0x6e,0xe1,0x58,0x5d,0x32,0x19,0xe6,0xbd,0xfb,0xd5,0xb7,0x0f,0x72,0x0e,0x5b,0x14,0xd3,0xf3,0x09,0xa8,0xea,0xf7 +.byte 0x98,0x2f,0x42,0x07,0x8e,0x72,0x27,0x53,0x8d,0x0b,0xea,0x74,0x38,0xbc,0xaf,0xb8,0x76,0x65,0x97,0xda,0xa7,0x06,0x37,0x29,0x09,0xbe,0xaa,0xe6,0xf7,0xb6,0xb1,0x5f,0x71,0x1f,0x5d,0x14,0x47,0xdf,0x20,0xa3,0x94,0x93,0x7d,0x21,0xe6,0x22,0x7e,0x38,0x1a,0x26,0x83,0xc7,0x32,0xdf,0x58,0xcd,0xab,0x67,0xae,0x94,0xa5,0x68,0xcb,0xe3 +.byte 0x51,0x70,0xc0,0xc4,0x41,0x9f,0xca,0x05,0xc9,0x51,0x2a,0x8e,0x53,0x89,0x3f,0x52,0x6b,0x29,0x64,0xa8,0xb8,0xdf,0x02,0xb1,0x41,0x4e,0x36,0x42,0x32,0xa8,0xc0,0x91,0xf0,0x69,0x69,0x55,0x99,0xb7,0x78,0x4f,0x79,0x5b,0xc5,0xab,0xc6,0xed,0x15,0x88,0x6b,0x94,0x0a,0xdd,0xea,0x47,0xf9,0x0e,0xb8,0x89,0x15,0x68,0x3e,0xc0,0x50,0xf8 +.byte 0xa1,0x2d,0x2a,0x11,0x8a,0xc5,0xb0,0x09,0x4f,0x7d,0x90,0x5f,0x49,0x35,0xe9,0xdd,0xfc,0xac,0xea,0x1b,0x20,0xad,0xd2,0xe6,0xb6,0xbf,0x3c,0x0e,0x7b,0xdf,0x2f,0x55,0x58,0x0e,0x25,0x53,0x62,0xd3,0x73,0xb8,0x3e,0x12,0x91,0xcb,0x23,0xf2,0xc0,0x5d,0x74,0x2b,0x51,0xcc,0xa2,0xb1,0x5a,0xd2,0xf4,0x9b,0xc9,0xa5,0x83,0x2b,0x5a,0x8a +.byte 0x0b,0xe9,0x09,0x59,0xb5,0x44,0xc9,0x55,0xcc,0xbd,0xb6,0x69,0x66,0x9a,0x0c,0x15,0xae,0x76,0x35,0xbe,0xe9,0x37,0x70,0x9e,0xdc,0x97,0x5a,0x82,0x97,0xf6,0x1a,0x45,0xd7,0x27,0xfe,0x1f,0xc3,0x7c,0x3a,0x52,0x85,0x12,0x73,0x8a,0x8e,0x07,0xec,0x1f,0x59,0x3f,0xb0,0x32,0x07,0x92,0x3e,0x81,0xe0,0x7a,0x9a,0xc9,0x91,0xca,0x84,0xf1 +.byte 0xe1,0x32,0x57,0x0a,0x3c,0x9a,0x20,0xa8,0xbe,0x84,0x91,0x44,0x66,0x81,0xdd,0x12,0xa8,0x46,0x15,0x18,0xfc,0xae,0x5e,0x9a,0xf3,0xd9,0xb9,0x6a,0xbb,0x90,0x1c,0x61,0x7f,0x61,0x2c,0xa7,0x12,0x1e,0x05,0xee,0x0c,0x66,0x9e,0xc2,0xc8,0xb9,0xe0,0xc9,0xc4,0xb9,0xee,0x3a,0x6f,0x97,0x2a,0x5e,0xcb,0xd9,0xff,0xd1,0x37,0x5e,0xa0,0x03 +.byte 0x70,0xc1,0x2f,0x15,0xf9,0xf7,0x90,0xbe,0x23,0xe7,0x7c,0x90,0x4b,0xe4,0x5a,0x01,0x65,0x27,0x2d,0x4b,0xd3,0xa8,0x8c,0x1d,0x2d,0x5d,0x48,0xac,0x6b,0x59,0xc9,0x78,0xb2,0xee,0xda,0x6e,0xa8,0x68,0x08,0x99,0x22,0x25,0xfe,0xc2,0xb8,0x83,0xa8,0x08,0xbb,0x6e,0x64,0xae,0x2e,0xbb,0x93,0xaf,0xdc,0xeb,0xa3,0x11,0xa7,0x5d,0x3f,0x22 +.byte 0xf1,0x95,0x27,0xf6,0xd6,0xa6,0xc3,0x56,0x0a,0xd0,0x17,0x43,0x35,0xd2,0xe7,0xa4,0x8f,0x6c,0x1c,0xc4,0x4d,0xa7,0x3b,0xb8,0x7f,0x0c,0xa0,0xd6,0x56,0x82,0xf4,0x16,0x96,0xcd,0xcf,0x6f,0x78,0xec,0xbb,0xb2,0xdb,0x67,0xcf,0x78,0x0c,0x22,0x1d,0x72,0x21,0x8e,0x40,0x85,0xa5,0x07,0x3b,0x0e,0xfa,0x44,0xb0,0xfe,0xbf,0x54,0x80,0x41 +.byte 0xdc,0xa7,0xc7,0xdb,0xaa,0x04,0x42,0x0d,0x42,0x03,0x17,0xc8,0x57,0xd7,0x08,0x34,0x37,0xf5,0x9a,0x90,0x30,0x43,0x54,0x5b,0x58,0x50,0x4e,0xc4,0x56,0x57,0xff,0xf0,0x05,0x82,0xca,0x2e,0x20,0xb0,0xbd,0xd0,0x00,0x7d,0x60,0x3f,0xdb,0x9c,0x08,0x7e,0x21,0x63,0xbc,0x89,0xbf,0xcb,0xcc,0x36,0xb5,0x36,0x41,0xb4,0x9c,0x5c,0x9d,0xa6 +.byte 0x74,0xa4,0x4f,0x6a,0xcb,0x63,0x51,0xb1,0x92,0xa0,0x03,0x9b,0x88,0x03,0xd5,0x82,0x30,0xfb,0x69,0x49,0x20,0xb0,0x37,0x50,0xe4,0x02,0x9e,0x11,0x09,0x20,0x1a,0x41,0x8d,0xdd,0xa0,0x18,0xb4,0x74,0x04,0x1e,0x3a,0xea,0xb4,0x28,0x01,0x7f,0x0b,0x73,0x27,0x5f,0x76,0x2e,0x71,0xfa,0x50,0x1b,0x43,0x8d,0x0d,0x6c,0x87,0xc3,0x10,0x7b +.byte 0x42,0x7d,0x17,0xa6,0x00,0x5b,0x83,0x6c,0x7b,0x7f,0x72,0xd8,0x90,0x4d,0x7f,0x54,0x72,0x17,0x21,0xe4,0x45,0x74,0x20,0x53,0x30,0x46,0x90,0xbf,0x2f,0xac,0x01,0xbd,0x40,0xa9,0xc5,0xbe,0xbd,0x9b,0x59,0x62,0x03,0x30,0x80,0xe3,0x8e,0x23,0x7b,0x2d,0x63,0x4f,0x30,0xe3,0xb8,0x56,0x87,0x57,0x43,0xdc,0x6a,0x3c,0x13,0xed,0x93,0xc9 +.byte 0x1a,0x1b,0xea,0x38,0x67,0x33,0x7f,0x11,0x5c,0x96,0x20,0x4d,0xf6,0x82,0x51,0x45,0xca,0x20,0xfd,0x59,0xef,0x4c,0xb4,0xb0,0xb2,0x0f,0xdb,0x4c,0x00,0x7a,0x18,0x58,0xb0,0xd3,0x65,0x73,0x42,0xe5,0x05,0x76,0xd7,0xa2,0x1e,0x9f,0x59,0xc0,0xd0,0x76,0x29,0x1b,0x12,0x29,0x9b,0xe4,0x7d,0x45,0x13,0xb4,0x57,0xf2,0x0b,0xd1,0xb5,0x60 +.byte 0x6d,0x15,0x0b,0xca,0x5e,0xe4,0x80,0xda,0x56,0x95,0x41,0x18,0x54,0xa7,0xad,0x40,0xe5,0xd7,0xa7,0x3e,0xf7,0x73,0x40,0x70,0xb3,0x23,0xdb,0x22,0x62,0xc7,0x44,0xfb,0x64,0x18,0x18,0x05,0x84,0x07,0x68,0x06,0x7f,0xb9,0xc3,0xf9,0x55,0xe2,0x0d,0x37,0x51,0x34,0xc3,0x55,0x3c,0x29,0x5d,0x1d,0x27,0x77,0xd3,0xe1,0x6a,0x60,0x9f,0x10 +.byte 0xef,0xb1,0x93,0xbf,0x2a,0xb7,0xe8,0x42,0x4d,0xfd,0xa9,0xa9,0x2f,0xb6,0x07,0x5b,0xe8,0xf7,0xd7,0x10,0x47,0x71,0x56,0xba,0x11,0x11,0x32,0xc4,0x22,0xf4,0x12,0x6f,0xc3,0xef,0x81,0xc5,0x82,0xb4,0x1b,0x99,0xbb,0x1a,0x63,0x6b,0x3a,0x70,0x4f,0xec,0x2c,0xf9,0xde,0x1a,0x2e,0x62,0x27,0x1c,0x81,0x21,0x30,0x08,0x30,0xf6,0xf5,0xc1 +.byte 0x6d,0x0b,0xeb,0x34,0xd9,0x3a,0xa2,0xa2,0xc6,0x17,0x60,0x85,0x65,0x43,0xd6,0x3d,0x71,0xac,0xc2,0xaf,0x2b,0x9e,0x62,0xf2,0x08,0x47,0x6f,0x42,0xa8,0x21,0xad,0x42,0x98,0xa0,0xef,0xdf,0xd8,0xda,0x10,0xad,0xf7,0xe5,0xf9,0x22,0x89,0x44,0xbf,0x86,0x86,0x2b,0x02,0xd1,0x9e,0x8f,0xb7,0x10,0x63,0xb1,0xcc,0x40,0x6b,0xa3,0x8e,0x09 +.byte 0xb8,0xe3,0x77,0x3c,0xde,0x36,0x7a,0xb7,0x78,0x4f,0x99,0x5d,0x9a,0x9e,0x19,0x2d,0xb5,0xd9,0x9c,0x95,0x1f,0xa1,0xcc,0x61,0x31,0x1c,0x96,0xe5,0xca,0xeb,0x26,0x34,0xa4,0x63,0x5c,0x7c,0x0f,0x23,0xd1,0xe1,0x09,0xf4,0xab,0xf6,0x73,0x2f,0x8a,0x62,0xf0,0xd3,0x8c,0x44,0xe5,0xe9,0x9d,0x58,0x71,0xfa,0xf5,0x39,0xa5,0x6f,0xf7,0x04 +.byte 0x43,0x0a,0x78,0x54,0xfb,0xa7,0x66,0x57,0x1f,0x61,0xd6,0xda,0xff,0x4f,0x32,0x9d,0x80,0x6b,0x77,0xed,0xda,0xaf,0xbc,0x9e,0xea,0x77,0x04,0xf3,0x47,0x96,0xd1,0x44,0x8e,0xca,0xfe,0xb0,0xa3,0xa6,0x1d,0x8d,0xa4,0xb5,0x8c,0x35,0x28,0xf3,0xaa,0xab,0x28,0x1e,0xc9,0x94,0x12,0x07,0xc6,0xea,0x23,0xf9,0x69,0xc3,0x14,0x27,0xcc,0x55 +.byte 0x27,0x0b,0x27,0x64,0x23,0x38,0x05,0xd9,0xb4,0xf7,0x00,0xf3,0x02,0xae,0xc8,0x5a,0xbd,0x2f,0x20,0xd5,0x45,0xa6,0x09,0x6f,0x1a,0x09,0xb7,0xe7,0x6f,0xf6,0xa6,0x6f,0xc7,0x03,0x4e,0xa3,0x72,0xb5,0xfc,0x17,0xcf,0x1e,0x64,0x8b,0xc4,0xa2,0xba,0x83,0x0e,0x2a,0x11,0xba,0x71,0xe0,0x1c,0x9f,0x70,0x6e,0xf4,0xd9,0x47,0x31,0xf7,0xaf +.byte 0xf7,0x1a,0xe7,0xc1,0xe9,0x66,0xa4,0x48,0xd4,0x25,0x8b,0xf7,0x6f,0x33,0x72,0xff,0x93,0x2e,0xcd,0xc7,0xae,0x3b,0x71,0x3f,0x84,0x7f,0xe6,0xb5,0x58,0x4f,0x95,0x34,0xe7,0x89,0x10,0xd3,0x2b,0x5c,0x30,0x9b,0xd3,0xef,0x98,0xf3,0x33,0x0e,0x6d,0x5f,0x7e,0xba,0x55,0x7a,0xb6,0xf3,0xb6,0xcd,0xa8,0x10,0x68,0x85,0x6f,0xea,0x54,0xc3 +.byte 0x66,0x51,0x5a,0xfc,0x11,0x83,0x9e,0x68,0x95,0xdb,0xec,0x74,0xf0,0x86,0x4a,0x90,0x24,0x66,0xf2,0x61,0x40,0x2e,0x3b,0x53,0xea,0xc1,0x3e,0x1c,0x69,0xaf,0x5f,0x04,0xb5,0xbd,0x3d,0x44,0x1c,0xc6,0x49,0x65,0xf6,0x78,0xfd,0x69,0x49,0x95,0x96,0xa1,0xa0,0xa9,0x78,0x1a,0xf6,0x0f,0xe9,0x52,0x93,0x9c,0x96,0x6c,0x5e,0x67,0x63,0x2d +.byte 0x18,0x22,0x2a,0xcc,0x7f,0x2f,0xd3,0x72,0x82,0x98,0xae,0xb0,0x2b,0xa6,0x96,0x41,0x25,0x47,0x3c,0x92,0xc5,0x0f,0x2c,0xd4,0x43,0x09,0x0b,0x94,0x73,0x73,0x29,0xc2,0x8a,0xa3,0xcc,0x8d,0xed,0x40,0x6d,0x40,0x18,0x7c,0x32,0x1e,0xe1,0x4e,0x26,0xa7,0xa4,0xd5,0xcb,0xfa,0x90,0xba,0xb2,0x04,0x1d,0x5d,0xbe,0x32,0x6c,0x71,0x09,0x51 +.byte 0xdb,0xe3,0xb0,0xe1,0x34,0x74,0xa3,0x2b,0xf2,0xcb,0x9e,0xc0,0xae,0x88,0x40,0x90,0xb6,0x22,0xc8,0xac,0xff,0x45,0xc6,0xfa,0xce,0x0f,0x03,0x9d,0xc0,0xb2,0x2e,0xdb,0x1e,0x6c,0xa5,0xbe,0xb5,0xb3,0xaa,0xd5,0x2d,0x06,0x4d,0x29,0xa3,0xbe,0x25,0x5f,0x21,0x42,0x8d,0x27,0xaa,0x6f,0x59,0x88,0x61,0x4d,0x72,0x9f,0x64,0xfc,0x07,0xaf +.byte 0xeb,0x02,0x5e,0xb9,0x1f,0xfe,0x1a,0x67,0x10,0x35,0xe9,0x9f,0x5f,0x9c,0x8d,0x4a,0xb3,0x10,0x99,0x8d,0x5b,0x9c,0x8b,0x8a,0x0c,0x02,0x8b,0x44,0x1a,0xaa,0xe7,0x14,0x05,0x3d,0x9e,0x62,0xfc,0x76,0x49,0x56,0x46,0xae,0xcc,0x0e,0x47,0x58,0x4d,0x94,0x33,0x4d,0x23,0x24,0x44,0x52,0x2e,0x18,0xf7,0x53,0x6b,0x24,0x67,0xb8,0x88,0x46 +.byte 0x70,0xc8,0xcb,0x60,0xac,0x70,0x85,0xdd,0x00,0xa1,0x5d,0xbb,0x94,0x07,0x0a,0xb6,0x1c,0x88,0x59,0xa7,0x88,0x7e,0x1e,0xc9,0x1d,0x7c,0xa0,0x1c,0xad,0xe4,0xa5,0x36,0xa5,0x35,0xe8,0xda,0x27,0x15,0xbc,0x7b,0x1e,0x8a,0x33,0x74,0x4b,0xc1,0xc7,0x9d,0xa9,0x21,0x98,0x02,0xe5,0xf4,0x8b,0x8e,0x2d,0x64,0x81,0xea,0xa6,0xbe,0xe2,0x05 +.byte 0x16,0xba,0xac,0x75,0x79,0xa4,0xc0,0xd3,0x9d,0xe0,0x25,0x63,0x22,0xb3,0x9c,0xee,0x04,0x8f,0x60,0xab,0x52,0x43,0x05,0x16,0xd4,0xb3,0x88,0xe8,0x68,0xc3,0x81,0x94,0xc4,0xee,0x13,0xaf,0xdd,0x36,0x23,0xe6,0x78,0xc9,0xf6,0x42,0xf0,0xf7,0x89,0x64,0x79,0x13,0xe8,0xed,0x50,0x03,0x16,0x78,0x6d,0xf4,0xdf,0x85,0x2e,0x4e,0x8f,0x2c +.byte 0x5b,0xfe,0x4c,0xf2,0x49,0xde,0xf2,0xa4,0x96,0xe0,0x8a,0x25,0xc8,0x6d,0x22,0xff,0xab,0xfc,0x18,0xe8,0x7f,0xd5,0xc1,0x7e,0x44,0x8e,0x21,0xb4,0xc8,0x79,0xc0,0x55,0xaa,0xb7,0x28,0xa1,0x3a,0xbd,0xc2,0x1d,0xf8,0x87,0xf9,0x35,0x30,0x25,0xb2,0xaa,0x8f,0x3c,0x0d,0x64,0xf2,0xd1,0xa0,0x51,0xbf,0x9b,0x9a,0x9a,0x9c,0x18,0x43,0xea +.byte 0xd2,0x54,0x50,0xe0,0xca,0x1a,0x29,0x16,0x9f,0x49,0x47,0x56,0x65,0x21,0x0f,0xb0,0x53,0x41,0xe3,0xec,0xe0,0x15,0xcb,0xd0,0x61,0x05,0x67,0xd6,0x02,0x1a,0x31,0x80,0xa4,0x9f,0xf5,0x9b,0x28,0xcd,0x43,0xd5,0x70,0x05,0x67,0xe8,0x76,0xb7,0x99,0x98,0x0a,0xd6,0x27,0xe9,0xfb,0x62,0xff,0x66,0x47,0xf7,0xbe,0x5e,0x35,0xa0,0x3b,0x56 +.byte 0x58,0x78,0x9b,0x9c,0x5b,0x9f,0xf5,0x6b,0x1a,0x6a,0xfd,0x8e,0xe3,0xd9,0xa2,0x8b,0x2e,0xef,0xc7,0xd3,0x74,0xb1,0xea,0x6a,0x03,0x8b,0xe2,0x78,0xbe,0xf1,0x75,0x7f,0x02,0x03,0xbc,0xd3,0x15,0x2c,0x87,0x01,0x95,0xa6,0x87,0x2d,0xf8,0x63,0xfe,0x33,0x8f,0xc5,0xc9,0x0a,0x06,0x79,0x93,0x46,0xd7,0x0b,0x61,0x06,0x68,0xae,0x9b,0x46 +.byte 0x6f,0x9e,0x1b,0x21,0x58,0xc1,0x72,0xa9,0x05,0xa7,0xaa,0x88,0xee,0xed,0x8d,0x7f,0x55,0x3b,0xb8,0xb8,0xf8,0x42,0x26,0x4a,0x78,0xe3,0x17,0xe8,0xac,0xb3,0xdb,0x9b,0x90,0x7d,0x8d,0x65,0x00,0x39,0x40,0xc2,0xe2,0x9c,0xc6,0x16,0x35,0x54,0x64,0x09,0xc8,0xc7,0x08,0x77,0x90,0x9d,0xb4,0xd4,0xe1,0x36,0xd4,0x5e,0x63,0xb0,0xba,0x81 +.byte 0x0c,0x4e,0x24,0x20,0xc0,0x7f,0xfc,0x02,0x3d,0x83,0x60,0x8a,0xf5,0xff,0x87,0x60,0x9c,0xd5,0xc0,0x94,0x64,0xe2,0x3f,0xeb,0x9a,0xe5,0xb6,0x50,0x13,0x36,0xf4,0x96,0x5d,0xf4,0xb5,0xab,0xa4,0x28,0x17,0x38,0x7f,0xca,0xf7,0x0c,0xcf,0xae,0xf8,0xef,0x41,0x6d,0x9c,0xa1,0x53,0x33,0xcb,0x8d,0x21,0xab,0x3a,0x8c,0x72,0x8d,0xf3,0xf2 +.byte 0x05,0x69,0xf5,0xe8,0x6b,0x5b,0x42,0x85,0xb1,0x2e,0x6f,0xf8,0x62,0x00,0x1c,0x48,0x6c,0x85,0x72,0x93,0x34,0x67,0x80,0xe7,0x2a,0xfe,0xcf,0x54,0xc6,0x94,0xf2,0x5a,0x48,0xab,0x40,0x52,0x66,0x7d,0x7a,0x75,0x68,0x77,0xfd,0xb2,0xdd,0xb1,0xdb,0x72,0x50,0x31,0x53,0x24,0xbd,0xb0,0x6e,0x1f,0xbd,0xa6,0x90,0x67,0x07,0x1d,0x31,0xf3 +.byte 0x8c,0x82,0xf7,0x53,0x85,0x54,0x64,0x7c,0x76,0x7b,0x5f,0xaa,0xe0,0xe0,0x36,0xa4,0x13,0xb3,0x0b,0x99,0x09,0xfe,0xed,0xbb,0x81,0x4b,0xb3,0x16,0x45,0x2e,0x3a,0xfe,0x60,0x9c,0xdc,0xcb,0x00,0x5a,0x41,0xc4,0x80,0x3c,0x9d,0x15,0x05,0xfa,0x5e,0x37,0x64,0x89,0x9c,0x2d,0xb8,0xf7,0xbc,0x35,0x8c,0x49,0xfe,0x0a,0x43,0x1a,0x59,0xaf +.byte 0x1e,0x50,0x08,0x0f,0x2d,0xb8,0x5d,0x63,0x7f,0x95,0x6a,0xe6,0xad,0x88,0xc3,0xac,0x05,0x14,0x44,0xb0,0x70,0x83,0x5f,0x94,0x45,0x3d,0xe5,0xbd,0xb8,0x92,0x28,0x20,0xd5,0xa0,0x83,0xd2,0xe2,0x41,0x71,0x27,0x29,0x1b,0x2a,0x3a,0x08,0xca,0x75,0xec,0x16,0x4a,0xcf,0x39,0xed,0xbe,0x2a,0x26,0x9b,0xa3,0x26,0xc6,0x89,0xf2,0xc6,0x8d +.byte 0x49,0x3a,0xfe,0xda,0x16,0x54,0x55,0x7e,0x7f,0x65,0x65,0xd2,0x16,0xdd,0xe2,0xa3,0x86,0x7a,0x69,0x82,0x99,0x58,0x45,0x16,0x4c,0x69,0xff,0x72,0xf2,0xbc,0xbb,0xdd,0xe1,0xb4,0x56,0xcf,0xc0,0x84,0xd6,0x2c,0xd8,0xce,0xf4,0x67,0xd8,0x1d,0xb7,0x77,0x6d,0x96,0xf4,0x28,0x7a,0x33,0x03,0x97,0x72,0x37,0xd9,0x35,0xcf,0x20,0x28,0xc2 +.byte 0xc4,0xea,0xf9,0x99,0x89,0xe0,0xcc,0x3d,0xec,0x2c,0xbf,0x06,0x78,0x91,0x1b,0x55,0x1b,0x51,0x9b,0xbe,0xf7,0x4a,0xf8,0x9f,0x46,0xab,0xee,0x5d,0x4e,0x29,0x36,0xf3,0xb9,0xa7,0x85,0x9b,0xf7,0xa1,0x9e,0x2a,0xbb,0xb3,0x0a,0x61,0xb5,0x0f,0x79,0xf4,0xe2,0xd2,0x2c,0x15,0xf7,0x4f,0xca,0xa9,0x46,0x25,0x1c,0xdc,0xfa,0x0f,0x9e,0xfa +.byte 0xf5,0xb8,0x54,0x7a,0xe3,0x98,0x3c,0x3b,0x85,0xf8,0xb3,0x7c,0x70,0x40,0x86,0x2a,0x66,0xd1,0x4d,0x83,0x38,0xc2,0x24,0x8e,0x30,0xc0,0x9e,0x54,0x4c,0x7a,0x62,0x9a,0x55,0x8e,0x11,0x02,0xef,0x30,0x08,0x5c,0xf3,0x57,0xa7,0xbe,0x32,0x04,0xab,0xb1,0x3a,0x51,0x6e,0xcd,0x6f,0xc1,0xd8,0xd0,0x7d,0x4f,0x1b,0xa9,0x1e,0x12,0x92,0x94 +.byte 0xd7,0x40,0xa9,0x99,0x70,0x06,0xcb,0x46,0xa5,0xe0,0x77,0xbe,0x6d,0x48,0xab,0x67,0x4e,0xa7,0x0e,0xfe,0x1f,0x53,0x24,0xbc,0x89,0xcb,0x70,0xac,0x05,0xa2,0xf4,0xa3,0x44,0xde,0xcb,0x18,0x95,0x78,0x70,0x0f,0x69,0xf0,0x5e,0xbd,0xe7,0xfc,0xd3,0x17,0x3e,0x18,0xb0,0x2f,0xa6,0xfe,0x82,0x81,0xe7,0x74,0x44,0xfb,0x43,0x5e,0xda,0xf4 +.byte 0xfb,0xfe,0x5c,0xb4,0x3c,0x1d,0xea,0x0d,0x2d,0xdb,0xee,0x1f,0xc5,0xbd,0xb2,0xa0,0x52,0x76,0x9e,0xad,0xfa,0x19,0x37,0xb0,0x15,0x53,0x82,0x25,0x86,0xd9,0xce,0x99,0x84,0x67,0x5f,0x57,0xb2,0x6f,0x99,0xa4,0x56,0xb5,0x01,0x4f,0xdf,0xa2,0xca,0x8c,0x23,0x51,0xd3,0xc7,0x72,0x9b,0x90,0x72,0x29,0x0c,0xca,0x86,0xff,0xc3,0xd9,0x9e +.byte 0x87,0xe4,0x8d,0xc6,0xac,0xba,0xfb,0x73,0xa9,0xcd,0x5d,0x16,0xfc,0x12,0xea,0x30,0xd5,0x7d,0x7b,0x16,0xa6,0x2c,0xeb,0x3c,0x3e,0x46,0x7c,0xee,0x03,0xd6,0x7a,0xe8,0x88,0x1c,0x17,0xa9,0x08,0xe9,0xd5,0x38,0x59,0x54,0x0b,0xb0,0x77,0x1b,0x76,0x09,0x53,0xca,0x38,0x12,0xd1,0xb5,0x2c,0xe3,0xd6,0xa0,0xca,0x9f,0x65,0x56,0xea,0x95 +.byte 0xab,0xc1,0xf4,0x98,0xaf,0x1a,0xe7,0x2b,0x1e,0x8d,0x75,0x43,0x43,0x9f,0x42,0x5c,0x2c,0xa5,0xd7,0x9a,0xcd,0xc2,0xab,0xd9,0x1f,0x1f,0xde,0x8a,0x3e,0xf8,0x0f,0x56,0x8a,0x01,0xde,0x47,0x41,0xd8,0xa0,0xc8,0x32,0x4d,0xa3,0x75,0x80,0x87,0xb1,0x1e,0x05,0x06,0x5e,0x2c,0x9a,0x7b,0xd3,0x22,0xe0,0x53,0x8f,0x4f,0x35,0x5f,0x46,0x3a +.byte 0xb2,0xfe,0x62,0x44,0x54,0x38,0xe0,0x03,0x5e,0xda,0xcb,0x86,0xdf,0xda,0x67,0x66,0x40,0x27,0x97,0xf0,0xc2,0xbd,0xce,0xce,0x37,0xeb,0x47,0xe2,0x56,0x7e,0x54,0xe9,0x51,0xda,0xec,0xd5,0xe6,0xc1,0x69,0x6e,0x4c,0x3d,0x92,0xdc,0xa0,0x51,0xe2,0x2b,0xb8,0x96,0xb6,0xce,0xdf,0x35,0xdb,0xd0,0xd4,0x42,0xe3,0x94,0x89,0x09,0x1b,0xb4 +.byte 0xe2,0x8f,0xfb,0x23,0x62,0x35,0x56,0xc7,0x94,0x40,0xd7,0x2d,0xdb,0x80,0xc9,0xbd,0x4d,0xe3,0x14,0x30,0x44,0x43,0xad,0xeb,0x3d,0x89,0xe9,0x61,0xd7,0x80,0x15,0x59,0xcd,0xda,0x38,0x11,0x3b,0x84,0x14,0x85,0xef,0x55,0xf2,0x01,0x2c,0xed,0x74,0xf5,0x71,0x75,0x0c,0x52,0x0c,0x41,0x86,0xbe,0x84,0xc5,0x89,0x8b,0xa5,0x6d,0xc3,0xfa +.byte 0x2b,0xe5,0xe7,0xe8,0xdd,0xf9,0xe8,0x27,0x08,0x5d,0xdf,0x61,0xdc,0xb2,0xe0,0x8c,0xe8,0xda,0xa8,0x68,0x22,0x51,0x6b,0xdf,0xd0,0x92,0x87,0x6a,0x43,0xff,0xd1,0x9d,0x9a,0x4c,0x03,0xdf,0x3e,0xc1,0x31,0x33,0x6e,0x2a,0x55,0xc1,0x58,0x59,0x69,0x66,0x05,0xd1,0xa7,0xa1,0x3b,0x98,0x1d,0x44,0x74,0xc7,0x7e,0xc0,0x07,0xd9,0x9c,0x87 +.byte 0x5f,0xc3,0x44,0x25,0x7b,0x96,0xbc,0x20,0x5d,0x14,0x08,0x34,0xe9,0xad,0x34,0xa3,0xc3,0x95,0x1a,0xc1,0xd1,0x37,0x43,0x49,0x66,0xff,0x39,0x70,0x27,0xa0,0x2b,0x39,0x9d,0x1b,0x78,0x52,0x55,0x77,0x30,0xe8,0x72,0x65,0x8a,0xc8,0xa4,0xe6,0xb7,0xd6,0x66,0x82,0xa7,0x1d,0xde,0x3e,0xc2,0x23,0x5a,0x8b,0x51,0xe4,0x44,0x03,0xf3,0x89 +.byte 0x10,0xb0,0x9a,0x09,0x5d,0xe3,0xe9,0x4a,0x0b,0xe3,0x86,0x58,0xf8,0xe3,0x1a,0x3f,0x7f,0x42,0xa5,0xd7,0xb0,0x24,0xb7,0xbc,0x1d,0x40,0xe7,0x2f,0x42,0x8c,0xa8,0x3c,0x33,0xee,0x9f,0xaf,0xd1,0x51,0x8e,0x34,0x82,0xc5,0x16,0xef,0xb1,0xa6,0xa8,0x0e,0xae,0xe6,0xc3,0x2f,0xb3,0x06,0xd4,0x4c,0xec,0xee,0x9e,0xff,0x88,0x82,0x4b,0xb8 +.byte 0xc5,0xef,0x94,0xe2,0x68,0x48,0x23,0xa2,0xc8,0xe4,0xdb,0x33,0xf9,0xee,0x73,0xc2,0xe6,0xa1,0x64,0xf9,0xf6,0xab,0x5a,0xdc,0xa5,0xb3,0xd8,0xae,0xf4,0x1f,0x47,0xfe,0xa0,0xee,0xf5,0xee,0x41,0x30,0xa6,0xbe,0x34,0x2c,0x1a,0x24,0x8a,0x80,0xb1,0x79,0x7e,0x2c,0xc0,0x65,0x68,0x46,0xae,0x0a,0x01,0x77,0xce,0xa2,0x5f,0xc3,0x00,0x8f +.byte 0xd4,0x0f,0xbe,0xbf,0x81,0x20,0x4e,0xb8,0x21,0x5f,0xfa,0xb2,0xf2,0x02,0x83,0x41,0xa8,0xf1,0xe8,0x2c,0x7e,0x0e,0xe6,0xf0,0x6e,0xd5,0x7b,0xcb,0x4e,0xed,0x06,0xc4,0x18,0xfb,0x0e,0x0d,0x8e,0x22,0x8a,0x40,0x4d,0x66,0xa5,0x0c,0x74,0xf3,0x9e,0xd9,0x90,0xf8,0x71,0xe4,0x92,0x05,0x3d,0x2d,0xa0,0xed,0x42,0x88,0x18,0x9a,0xc7,0xe4 +.byte 0x41,0x5d,0xde,0x44,0x2e,0x26,0x30,0xfe,0x51,0xa8,0x91,0xa3,0xa6,0xfd,0x3e,0x04,0x7f,0x3a,0xa9,0x1c,0x21,0x98,0xab,0xaa,0x39,0x9d,0xe4,0x51,0x75,0xeb,0x90,0x6b,0xab,0x11,0x89,0xa9,0x22,0xa8,0xc5,0x92,0x16,0x51,0xe1,0x77,0x09,0x53,0x7f,0xb6,0x80,0x4b,0xf5,0xf5,0xa2,0x0e,0x36,0x24,0x7f,0xe7,0xcc,0x67,0xfb,0x2c,0x6e,0xc2 +.byte 0x16,0x47,0x41,0xc2,0x77,0xf4,0xcf,0x49,0x37,0x17,0x67,0x34,0x14,0x92,0x7d,0x0f,0x14,0xe8,0x4b,0x4c,0xc3,0xbb,0x78,0xf7,0xa0,0x59,0xbe,0x06,0x10,0x38,0xe6,0x2c,0x08,0x15,0xba,0xc6,0x49,0x38,0x9a,0x91,0x2b,0x4d,0x82,0x42,0x0e,0xe4,0x02,0xef,0x2b,0xa2,0x06,0xcc,0x3a,0x3c,0xb9,0xc5,0xb5,0x71,0x1e,0x17,0x5d,0x65,0x35,0x91 +.byte 0x89,0x54,0x97,0xa8,0x7b,0x02,0x24,0xf9,0xdb,0xb5,0x52,0xf7,0xd0,0xa0,0x42,0x48,0x01,0xf4,0x47,0x7c,0x84,0x7c,0x8a,0xb4,0xf4,0x30,0xec,0xb9,0x21,0x44,0x87,0xb2,0x96,0xa4,0x3b,0x0d,0x93,0x26,0x09,0xc8,0xfa,0x28,0x6f,0x09,0xb7,0x03,0x85,0x66,0x21,0x2d,0xf1,0xaa,0x3f,0x0b,0x59,0x15,0xfe,0x8b,0x2b,0xe0,0x81,0x38,0x63,0x70 +.byte 0x09,0x37,0x38,0x62,0x04,0x8e,0x3f,0x23,0x65,0xf8,0xf7,0xc0,0x30,0xb8,0x04,0xb4,0x17,0xd7,0x21,0xcc,0x8b,0x31,0xd3,0x7b,0x11,0xea,0xc5,0x51,0x01,0x93,0x5f,0xe3,0xf3,0x1e,0x0d,0x41,0x52,0x2a,0xfd,0x27,0x02,0x00,0x58,0x0d,0x1f,0x16,0xd7,0x50,0x09,0xea,0x3f,0x9f,0x72,0xae,0x7a,0x79,0x4b,0x69,0x61,0xfc,0xac,0x5c,0x4d,0x6a +.byte 0x65,0x5d,0xa5,0x67,0x76,0xe4,0x24,0x3f,0xa0,0x6f,0xf6,0x60,0xd2,0x70,0x8e,0x2e,0xbe,0xf9,0x8b,0xab,0x22,0xc8,0x9c,0x5b,0x26,0xc5,0x75,0xeb,0x96,0xa2,0x4f,0xdf,0x6c,0x05,0x9a,0x15,0xef,0xbf,0x3e,0x35,0x6d,0x8d,0x48,0xa4,0x33,0xc2,0xe8,0x3b,0x89,0xe4,0x0c,0xb2,0x9a,0xc6,0x89,0x52,0xba,0xc7,0x2a,0xa5,0xfb,0xe5,0xde,0x06 +.byte 0xbd,0xc3,0x4f,0xe8,0xa9,0x9d,0x36,0xa5,0xcc,0x90,0xcd,0x68,0x49,0x52,0x6e,0x9a,0x85,0xd4,0x1b,0xe5,0x3f,0x54,0xc8,0xb4,0x7a,0x76,0xbf,0xa8,0xf4,0x25,0x05,0xeb,0x43,0x0c,0x2b,0x1c,0x59,0x5b,0x51,0x7f,0xd5,0x13,0x54,0x37,0x44,0x37,0x2f,0x79,0x1c,0x1f,0x18,0x57,0x60,0xab,0xf7,0xcc,0x5d,0xd5,0xdd,0x69,0xab,0x7f,0xc7,0x9d +.byte 0x7f,0xd7,0x6a,0xdc,0x34,0x3d,0x6e,0x2c,0x1e,0xb8,0x74,0xef,0xec,0x14,0x83,0x98,0x20,0x85,0x8a,0x95,0x93,0x26,0xed,0xbb,0x7d,0xfe,0x63,0xaa,0x20,0xbb,0x40,0x7b,0x35,0x1d,0xe5,0x64,0xc0,0x64,0x83,0x90,0x59,0xb4,0xae,0xf7,0xfe,0x14,0xb2,0xaa,0x72,0xf7,0x34,0x61,0xe0,0x61,0x06,0xb3,0xdc,0x09,0x5f,0xe1,0x57,0x65,0x83,0x8a +.byte 0x6d,0x46,0x54,0x8f,0xbf,0x38,0x12,0xf5,0xa3,0xfc,0x7b,0x90,0x4f,0x30,0xed,0xc1,0xab,0xb2,0x6e,0xee,0x7c,0x5e,0x35,0x70,0x80,0xb0,0xae,0x93,0xdc,0x4e,0x8f,0x6c,0x37,0xef,0xc9,0x4c,0x3a,0x41,0x14,0x91,0x99,0x0d,0x48,0xbe,0x5e,0x9b,0xc5,0xa6,0x4d,0x07,0x0d,0xd5,0xe6,0x5d,0x26,0x6b,0xa0,0xf3,0xb2,0x28,0x15,0x57,0xdb,0x7b +.byte 0x8e,0x6b,0x88,0xc3,0x81,0xb6,0x16,0xd1,0x3c,0xd0,0x2d,0x5a,0x23,0x35,0x8e,0xb0,0x8b,0x5c,0x99,0x6a,0x7a,0x55,0xb1,0xf9,0x45,0x97,0x94,0x05,0x6e,0x58,0xd4,0x53,0x8d,0x73,0x43,0x02,0x68,0xdf,0x7c,0x37,0x1a,0x6b,0x71,0x04,0xa0,0x31,0x77,0xbc,0xe0,0x16,0x5a,0x2a,0x9a,0xb2,0x40,0xe4,0xbb,0xd0,0xfd,0x35,0xcb,0x7f,0xf4,0x13 +.byte 0x0f,0xb5,0x93,0x9a,0x7d,0x50,0xf8,0xfe,0x56,0x34,0x83,0x20,0xce,0x3d,0x02,0x2e,0x0b,0x95,0x76,0x88,0x47,0x8c,0x75,0x51,0x14,0x52,0x49,0xbc,0xed,0x66,0x0e,0x81,0x65,0x5e,0x64,0xfb,0x45,0x59,0x3d,0x2b,0xd6,0x3a,0xc6,0xfd,0x50,0xe4,0xeb,0x0c,0x68,0x38,0x0f,0xdd,0xa2,0xdc,0xaa,0x26,0xf5,0x7b,0x40,0x6a,0x90,0xf8,0x08,0x2c +.byte 0xe8,0x8f,0x8e,0xc1,0xf2,0x6b,0x87,0xeb,0x7a,0x02,0x9e,0x26,0x3e,0x6b,0xb9,0x71,0x2e,0x6f,0x26,0x20,0xa9,0xc0,0x7c,0xe5,0x6c,0x6b,0xd4,0xc4,0x7b,0x54,0x8e,0x4a,0x7a,0xef,0xfc,0x03,0x02,0x1d,0x6a,0x16,0x99,0x35,0x12,0x49,0xba,0x86,0x37,0x7a,0xb0,0x8d,0x58,0x6f,0x1c,0xba,0xa9,0x5d,0x93,0xdf,0x98,0x50,0x7e,0xea,0x0a,0x88 +.byte 0x1a,0xd4,0x63,0x91,0x23,0x43,0x43,0x17,0x2e,0xe6,0x04,0x95,0x96,0xa8,0x2b,0xb4,0x9e,0x91,0x6c,0x13,0x52,0x8c,0xbf,0x7d,0x50,0xfc,0x79,0xef,0xa1,0x3e,0x90,0xba,0xac,0xd1,0x0d,0xb0,0x4d,0xd5,0x7a,0xc7,0xbd,0x82,0xb7,0x03,0x9c,0x0b,0xbc,0xa7,0x3c,0x05,0x8f,0xbd,0x0d,0x7f,0x80,0xeb,0xe9,0xbd,0x8f,0xdc,0xcd,0x86,0x23,0x26 +.byte 0xb0,0xa4,0xdc,0x63,0xef,0xad,0x61,0x53,0x7e,0x23,0x34,0x0d,0xd9,0x75,0x7c,0xa7,0x57,0xba,0x28,0x0c,0x82,0x7f,0x68,0xe5,0x24,0xdc,0x23,0x99,0xcd,0x6f,0x03,0x59,0x4f,0x35,0x47,0xc4,0x11,0xc0,0x0c,0x2b,0x16,0x94,0xb8,0x28,0xf2,0x0a,0x91,0x2e,0x1c,0xde,0x75,0x50,0x52,0x00,0x0a,0x92,0x80,0xca,0x39,0x3a,0xdf,0x16,0xb7,0xe2 +.byte 0xbd,0x98,0x7b,0x70,0x48,0x85,0x6d,0x48,0xa0,0x1b,0x0a,0xbb,0xa8,0xb6,0xca,0x9c,0x4e,0xda,0x0a,0x17,0x0b,0x30,0xf5,0xa2,0x9b,0x5a,0x89,0xf4,0x53,0x89,0x38,0x34,0x2b,0x7d,0x14,0x04,0x44,0xa3,0x8f,0x70,0x29,0xa5,0x3e,0xdd,0x5a,0x61,0xa1,0x04,0xac,0xd8,0xd3,0xec,0x42,0xc4,0xd9,0x2c,0x13,0x80,0xf8,0xc9,0xec,0x54,0xa7,0xa0 +.byte 0xe6,0x37,0x04,0x38,0x5f,0x1e,0x0b,0xfb,0x38,0x06,0xb9,0xe2,0x05,0x12,0x12,0xa2,0x28,0xff,0x12,0xae,0x44,0xd8,0x0d,0x2c,0x5a,0x8f,0xfb,0x1d,0x98,0x69,0x85,0x69,0x99,0xc0,0x63,0xc5,0x88,0xa7,0x2d,0x56,0x76,0x32,0x23,0x4c,0xf7,0x29,0xd6,0x3e,0x45,0xfa,0xd7,0x61,0xf4,0x9a,0xa6,0x9e,0x4a,0xe7,0xe7,0xf9,0xbf,0x1f,0x09,0x82 +.byte 0xbe,0x36,0xa0,0xdd,0x91,0x47,0x3b,0xbc,0x52,0xf2,0xc2,0x04,0x96,0x85,0xb6,0x93,0xac,0x99,0x94,0xbe,0xfd,0xe6,0x53,0x9f,0x75,0xab,0x38,0xdd,0x81,0xc0,0x79,0x25,0xcd,0x73,0x72,0x5b,0x4d,0xc0,0xba,0xa9,0x18,0xaa,0x76,0x51,0x15,0xef,0xb9,0x22,0xdd,0x5f,0x22,0x62,0x6c,0x36,0xf6,0xc0,0x72,0x34,0x01,0x7a,0xaf,0xe2,0x87,0x1b +.byte 0x5f,0x33,0x9c,0xd5,0xe2,0x81,0x03,0xbe,0x4e,0xac,0xcc,0x17,0xc5,0xc6,0xf8,0x0f,0x24,0xe0,0x26,0x56,0x8a,0x20,0x2e,0xe4,0x05,0xc8,0x0f,0x89,0x24,0x0e,0xd4,0xb7,0x07,0xd1,0x99,0x8c,0x55,0xfd,0x75,0xc1,0xdb,0xaa,0xd1,0xd2,0xa6,0xf2,0xf0,0x3c,0xae,0x62,0x0e,0x1f,0xaa,0xc9,0xa5,0x16,0x09,0x2c,0xc0,0x61,0x55,0x72,0x70,0x63 +.byte 0x22,0xb6,0x41,0xa5,0x08,0x34,0x6a,0x1b,0xfc,0x42,0x81,0xe7,0x25,0x98,0xcf,0xba,0x18,0xb0,0x36,0x90,0x72,0x65,0x75,0xf3,0x57,0x68,0xd0,0x86,0xe4,0xaf,0x33,0xb6,0x2b,0xef,0x96,0x97,0x17,0x42,0x6b,0x8e,0x19,0xaa,0x4b,0x9d,0xc7,0x73,0x34,0x5f,0x41,0x24,0x12,0xfb,0x66,0xa2,0x1e,0x91,0x41,0xc2,0x78,0x08,0x66,0xc4,0xb2,0x86 +.byte 0x67,0x70,0xe6,0x96,0x76,0x8d,0xa4,0x69,0x6f,0xe5,0x35,0x8b,0x20,0x3d,0x6a,0xcb,0x65,0x7b,0x82,0x7b,0xf6,0x2d,0xd8,0xd0,0xda,0x69,0x8b,0xcd,0xdf,0x15,0xf6,0x3a,0x2c,0xfe,0xc7,0x84,0x20,0x11,0xcc,0x18,0x4f,0xc7,0x2e,0x1c,0x46,0x41,0x6b,0x91,0x79,0xa0,0xbb,0xf4,0x48,0xd7,0x0c,0x9a,0x88,0x01,0xda,0xa1,0xd1,0x8f,0x27,0x49 +.byte 0x9d,0xa0,0x3f,0x5a,0xc2,0xf7,0x26,0x9b,0xe5,0xff,0xa4,0xcb,0x86,0x32,0xb3,0x3c,0xd5,0xe5,0x7c,0xbb,0x5e,0xfe,0x3d,0xcf,0x60,0x1c,0x16,0x8e,0x0c,0xc4,0xa9,0xf2,0xb2,0x42,0x1d,0x13,0xb0,0xa8,0xff,0x90,0xbc,0xd9,0x9a,0x6d,0x78,0x7a,0x46,0x1a,0xa8,0x35,0x4e,0xa4,0x79,0xd5,0xb4,0x36,0x47,0x62,0x3c,0x0e,0x23,0x56,0xca,0xa2 +.byte 0x60,0xe6,0xca,0xf6,0xc3,0xd6,0x7c,0x5d,0x54,0x9c,0x0c,0xfa,0x9a,0x0f,0x3a,0x8c,0x64,0x52,0xdb,0x62,0x5e,0x93,0x82,0xef,0x9e,0x8d,0x30,0xa5,0xe7,0x3d,0x52,0x11,0xd4,0x93,0xb1,0x77,0x8f,0xee,0x54,0x9c,0x80,0x47,0xa9,0x21,0xa8,0xf7,0x16,0x4b,0xbb,0xab,0x75,0x52,0xed,0x0c,0x85,0xf8,0x04,0xf4,0x80,0x08,0x4a,0xb5,0x2d,0x2d +.byte 0xd8,0x98,0x57,0x24,0xd5,0xc8,0x77,0xa0,0xd8,0xb5,0xb1,0x83,0x92,0xb4,0xc7,0x42,0x36,0xd1,0xa5,0xd6,0xbd,0x89,0xc6,0x76,0x31,0x92,0x31,0x67,0x2c,0xa4,0xb2,0x2b,0xcf,0x94,0x20,0x6a,0x17,0x63,0xb9,0x76,0xac,0x9c,0x1c,0x95,0x3e,0x57,0xf8,0x87,0x0d,0xef,0x36,0xcd,0x87,0xd1,0x58,0x2c,0x9a,0x5e,0x54,0x0e,0xac,0x97,0xbd,0x15 +.byte 0xc4,0xdb,0xea,0xd3,0x21,0x05,0x2d,0x78,0xce,0x4c,0x60,0xf3,0xf8,0xeb,0xd9,0x19,0x89,0xb0,0x83,0xc0,0xe4,0x42,0x08,0x5c,0x1a,0x1c,0x53,0xf3,0x1e,0x5a,0x28,0x92,0x0d,0x32,0xbe,0x4a,0x9a,0x70,0x78,0x93,0xc1,0x66,0x81,0xda,0xe7,0x3d,0x05,0xc5,0xaa,0xdc,0x51,0x6b,0xaf,0x67,0x4d,0x18,0xfe,0x29,0xe0,0xfa,0x5c,0xe5,0x9a,0x18 +.byte 0x7f,0x8f,0xaa,0x21,0xa5,0xd0,0x8b,0x62,0x32,0x6b,0x93,0x02,0x19,0x62,0xd3,0xd6,0x74,0xea,0x83,0xdb,0x6c,0x57,0xe3,0x1f,0x1f,0x90,0xd0,0x22,0xf7,0x9a,0x4a,0x14,0xf4,0x8a,0xb3,0x86,0xa5,0x4c,0x1e,0xdf,0x49,0xa5,0x78,0x30,0x5e,0xf0,0x9a,0x69,0x0d,0xaa,0xe9,0x47,0x01,0xae,0x51,0xcf,0x32,0x4c,0xec,0x03,0x08,0xe7,0xcb,0x35 +.byte 0x59,0xd2,0x48,0xd4,0xfa,0x6a,0x45,0x6b,0x66,0x1f,0xb8,0x1e,0x45,0x85,0xef,0x14,0x25,0x34,0x48,0x50,0x59,0xf3,0x76,0x09,0x32,0xf5,0xe4,0xa8,0x98,0xb0,0x9a,0x70,0xec,0x0a,0x17,0x87,0xcf,0x6d,0x96,0x7d,0x50,0x5e,0x3a,0xff,0x57,0xa7,0xaf,0x04,0x0d,0xdc,0xcc,0xad,0xe3,0x09,0xd3,0x92,0xab,0xd8,0x3a,0x61,0x1f,0x9c,0xc4,0x36 +.byte 0x3b,0xf3,0xf6,0x87,0x43,0xea,0xc8,0xff,0x29,0x19,0x9e,0x87,0x44,0xc7,0xe5,0x5c,0x43,0x30,0x9a,0xb2,0xd8,0x47,0x4a,0x87,0xcc,0xc7,0x8e,0x99,0x32,0xdd,0x3c,0x37,0xda,0xa0,0x39,0x04,0x55,0xca,0xcf,0x2f,0xce,0x8b,0x22,0x35,0x2c,0x29,0x89,0xef,0x5c,0x05,0x82,0x55,0xf3,0x8d,0x64,0x7f,0x69,0xf7,0x3d,0x43,0x27,0xf3,0x4c,0xd7 +.byte 0x43,0x89,0x47,0xd5,0x0b,0x01,0x1b,0x17,0x6c,0x7e,0x63,0x18,0x87,0x8b,0x8f,0x20,0x0d,0xa4,0x1e,0xa5,0x3b,0xf1,0x5c,0xe5,0xc8,0x23,0xd4,0xee,0x79,0x3e,0xd1,0xbc,0x83,0x30,0x03,0x64,0x80,0x7e,0xda,0x13,0x7c,0x52,0x88,0xc1,0x7c,0xa7,0x8a,0x5d,0x8d,0x7b,0x57,0x4e,0x59,0x97,0x83,0x52,0x03,0x04,0x6b,0xd2,0xf3,0xff,0x1c,0x4e +.byte 0x3b,0xae,0x70,0x61,0x3b,0x8b,0xaf,0x56,0x3d,0x28,0x73,0x24,0x39,0x4b,0xb8,0x6e,0x89,0x28,0xe6,0xc8,0x5c,0xe9,0xf8,0xec,0x8f,0xf7,0x75,0x1a,0x13,0xc1,0x8e,0x53,0x4e,0xe5,0xef,0x37,0xce,0xa1,0x54,0xca,0xcc,0xf5,0x01,0x29,0x2a,0x8f,0x00,0x1c,0xde,0xcd,0x5e,0x24,0x0b,0xa5,0x94,0x0c,0x8a,0xab,0x54,0x1e,0x80,0x2a,0x0d,0x84 +.byte 0x38,0x4c,0x17,0xea,0x84,0x07,0x9c,0xbd,0x85,0xd8,0x1b,0x57,0x6a,0xde,0xb3,0x86,0xa3,0xf8,0x6d,0x03,0x3e,0xf1,0x37,0xae,0x7d,0x02,0x33,0xc5,0x7b,0xf6,0x64,0xdb,0x3e,0xb0,0x48,0xda,0x49,0xec,0x89,0xb4,0x83,0xff,0xe1,0x6f,0x9a,0x7e,0x0a,0xda,0x6e,0xec,0x70,0x0b,0x51,0xac,0x82,0xac,0xb8,0xce,0x16,0xe7,0x47,0xab,0xe8,0xc7 +.byte 0x56,0xd1,0xab,0x73,0x72,0x5c,0xe7,0x9e,0xb8,0x77,0xa7,0xc1,0x47,0x9c,0x4e,0x16,0x68,0xce,0x21,0x23,0x2d,0x6c,0xcf,0x79,0xd6,0xd4,0xdf,0x74,0x30,0xb8,0x0f,0x60,0xea,0xbf,0x39,0x77,0x45,0xdc,0xaf,0x25,0xbd,0xc5,0x8d,0x0b,0x44,0x21,0xc1,0xc1,0x2e,0x54,0x2a,0x32,0x6c,0xea,0x51,0xe0,0x7d,0xa8,0x09,0x94,0x2f,0x4e,0xfe,0x27 +.byte 0xe8,0x63,0xfb,0x71,0xca,0x01,0x7d,0xc9,0x70,0xd8,0xe4,0x82,0xbf,0x3f,0xea,0x64,0x5e,0xa9,0x84,0x1d,0x2c,0xfd,0x8a,0x7d,0x33,0x73,0x5c,0x82,0xbe,0x9e,0x46,0xfc,0x39,0x5e,0x38,0x2a,0x20,0xd9,0xa9,0x20,0x46,0x23,0xc1,0x8b,0x0a,0x9c,0x42,0xb6,0x50,0x9f,0xc8,0x7d,0x4a,0x85,0x98,0xed,0x92,0x13,0xd3,0xd6,0xe6,0x6d,0x50,0x6e +.byte 0x93,0x63,0x41,0xa3,0x63,0x97,0x52,0xe3,0xaf,0x09,0xe1,0x40,0x12,0x41,0xed,0xb3,0xc5,0xb8,0x9f,0xc1,0xf2,0xd2,0xe6,0x16,0x94,0x97,0xdb,0xae,0xdb,0xd4,0x1f,0x5a,0x2f,0xf1,0xb1,0x22,0xf6,0x60,0xa4,0x0e,0xd8,0x2f,0xf7,0xf7,0x3f,0x6c,0x7d,0x73,0xe3,0x1d,0x99,0x04,0x7f,0x4f,0x70,0x2a,0x8c,0x43,0x80,0xa3,0xd0,0x25,0x75,0xd8 +.byte 0xb6,0xc8,0x90,0xa2,0x26,0xee,0xba,0xc5,0x1a,0xdc,0x1f,0x81,0x65,0x54,0xc6,0x57,0x6e,0xa2,0x03,0x32,0xf5,0x14,0xb2,0xdd,0x4d,0x21,0xaa,0xb9,0x78,0x4f,0x76,0xab,0xbe,0xfe,0x5d,0xc6,0xaf,0xed,0x6f,0xf9,0xaa,0x31,0x21,0x08,0xa4,0x6e,0xfb,0x78,0xdc,0xed,0x0c,0x05,0xff,0x1e,0x60,0x38,0x60,0x94,0xa9,0x92,0xa7,0x07,0x6e,0x6f +.byte 0x6d,0x89,0x8a,0x73,0xfb,0xaf,0x01,0x34,0x7d,0x7d,0x33,0x76,0xff,0x1f,0x6b,0x79,0x5e,0xff,0x50,0x14,0x80,0x7d,0x55,0x0e,0x2d,0xc3,0x77,0x85,0x30,0x20,0xf6,0xc8,0xc7,0xb7,0x73,0x1b,0xd1,0x87,0x69,0x44,0xeb,0x02,0x5e,0x45,0x66,0x6f,0x28,0x00,0x1f,0xf8,0x58,0x93,0xe5,0x21,0xbc,0x19,0x8d,0x72,0x19,0xaa,0x9a,0xbb,0xc6,0x47 +.byte 0xe6,0x0b,0xe4,0x76,0x13,0xc7,0xc4,0x1b,0x9d,0x85,0xba,0x17,0xb6,0x30,0x2a,0xdb,0x7c,0x36,0xd7,0xd8,0x8b,0x9c,0x99,0x92,0x64,0x03,0x4f,0xd4,0x1f,0x04,0x2e,0x45,0x34,0x55,0x92,0x99,0x77,0xb8,0x45,0xce,0x59,0x22,0x3c,0x6e,0xe5,0x18,0xb0,0x83,0x42,0x42,0x75,0x1c,0x34,0x0f,0x2e,0x59,0x06,0x94,0x17,0xea,0xc3,0xdb,0x0b,0x2f +.byte 0x44,0x97,0x54,0xe8,0x76,0xd3,0x25,0x24,0xe9,0x21,0x4f,0xd7,0x01,0x7d,0xbe,0x90,0x8a,0x0a,0x7d,0x4e,0x91,0x5f,0x4c,0x32,0x83,0x42,0x55,0x95,0x3c,0x7a,0x3e,0x46,0x8a,0x5d,0x0c,0x05,0xcd,0x0b,0xf6,0x3e,0x4d,0xf3,0x55,0xea,0x42,0x3e,0x19,0x0e,0xda,0xd4,0x22,0x88,0xe2,0x29,0x06,0x9e,0xea,0x1c,0x27,0x96,0x7f,0x3a,0x8a,0x28 +.byte 0x2f,0x7d,0xa2,0x65,0x37,0xae,0xb6,0x6a,0x59,0x41,0x19,0x73,0x91,0x64,0x77,0x4e,0x5a,0x1a,0x85,0x9f,0xc5,0xb0,0x85,0xc1,0x96,0x47,0x69,0x9c,0x36,0x70,0x36,0xa3,0x2e,0x1a,0x7d,0x11,0x59,0x55,0xec,0x4c,0x49,0xa1,0x86,0x3c,0x3d,0x24,0xb8,0x7a,0x84,0xca,0x4c,0x3f,0x7e,0x81,0x95,0x39,0x41,0xfe,0xc4,0x74,0xe5,0x89,0x7e,0xdc +.byte 0x86,0xd2,0xdb,0x8b,0xb8,0xa2,0xbb,0x15,0x64,0x89,0xf9,0x00,0x7d,0x56,0xec,0x8b,0xc8,0x05,0xcd,0x76,0x6c,0xcb,0xaf,0x7e,0xd2,0xdd,0x67,0xb3,0x99,0x16,0x63,0xf2,0x6d,0x49,0x7d,0xeb,0x67,0x24,0x98,0xf1,0x28,0xa3,0xb2,0x14,0xfc,0x95,0xf6,0x55,0xa0,0xb5,0x8c,0x26,0x2f,0xc6,0x08,0x49,0x57,0x4c,0x20,0xbc,0x48,0xab,0x24,0xef +.byte 0xe9,0xab,0x6b,0x77,0x4d,0x3b,0x61,0x84,0x68,0x67,0x72,0xc2,0xcf,0xab,0x8e,0xac,0x39,0xec,0x43,0x03,0xbb,0x4f,0x32,0x7d,0x7d,0x51,0x69,0x30,0xee,0x4f,0xd0,0xb9,0xa5,0x22,0xdd,0x47,0x06,0xad,0xac,0x62,0x20,0xff,0x7b,0x8c,0x90,0x91,0xb3,0xd8,0x89,0xd3,0xea,0x81,0xdc,0xca,0x31,0xc3,0x65,0xca,0x4c,0x50,0x0a,0x85,0xf7,0xaf +.byte 0xe3,0x67,0x57,0x53,0x1d,0x4e,0x42,0x17,0x2d,0x14,0x80,0x29,0x09,0x2b,0x48,0x45,0x43,0xb9,0xad,0x1f,0xb7,0x2d,0xab,0xfa,0x6a,0x1b,0x3c,0x7d,0x76,0xd7,0x36,0x20,0xb0,0xd3,0xc0,0x5e,0xc7,0x20,0x06,0x0c,0xa9,0x6a,0xb2,0x67,0xad,0x91,0x49,0xfc,0x4d,0xb2,0x15,0x61,0x61,0xfa,0x33,0x6c,0x94,0x92,0x58,0xef,0x46,0x82,0x9c,0x04 +.byte 0x52,0x21,0x28,0x08,0xb4,0xa9,0xd4,0x2e,0xd9,0x8c,0x93,0xd0,0xd8,0x4f,0x33,0x1d,0x0b,0x7e,0x07,0x12,0x40,0x64,0x3d,0xa2,0x8f,0xa3,0x96,0x45,0x0e,0xfc,0x9b,0x55,0x5f,0x3c,0xa2,0x57,0x3e,0x51,0x40,0x69,0xdc,0x7a,0x51,0xd2,0x3b,0x79,0x2f,0xd2,0x01,0x18,0xbf,0xd5,0xd2,0xd1,0x0e,0x08,0xcf,0xac,0x07,0x4d,0xd1,0x92,0xc7,0xca +.byte 0x92,0x75,0x0b,0x80,0x29,0xf1,0x46,0x24,0xba,0x47,0x6b,0x4a,0x64,0xfb,0x31,0x69,0xe9,0x40,0x0d,0x69,0x50,0xd0,0xdf,0xf8,0xcb,0x6a,0xe8,0xd4,0xc2,0xbd,0x0b,0x23,0x00,0xe0,0x29,0x0a,0x0a,0x8e,0x19,0xec,0xa9,0x14,0xe4,0x5d,0x4c,0x30,0xc9,0x85,0x42,0xd6,0x9f,0x83,0x8f,0x2a,0x5b,0x22,0x37,0xe4,0x71,0x3b,0x19,0x86,0xd4,0xda +.byte 0xb5,0x81,0x8e,0x84,0x57,0xcd,0x13,0x64,0xc3,0x23,0xfd,0x91,0x8a,0xe4,0xb9,0x32,0x12,0x17,0x02,0xa6,0x8d,0xec,0x44,0x9d,0xa5,0x7c,0x96,0x14,0xd1,0xd5,0x93,0x02,0x0c,0x9d,0xfc,0x26,0xa0,0xd2,0x41,0xaa,0x75,0xe8,0x82,0x6f,0x47,0x1d,0xe8,0xcf,0x94,0xe3,0x35,0xa9,0x76,0x1e,0xdb,0x92,0x5f,0x32,0x49,0xf4,0xd5,0x59,0x9c,0x4e +.byte 0xf7,0x89,0xda,0x23,0x7f,0x46,0x0e,0xfc,0xaf,0x1c,0x6f,0xcc,0x59,0xa5,0x43,0x04,0xbf,0x55,0xab,0x7d,0x36,0xa3,0xa5,0x03,0x7f,0xdf,0x33,0x6c,0x6d,0xd0,0x53,0xaa,0xef,0x54,0xc1,0x62,0xa0,0xd6,0x3a,0x67,0x87,0xe3,0x76,0x17,0x45,0xbe,0x7f,0x55,0xc8,0x8b,0xe8,0x1c,0xa8,0xe6,0xa6,0xb2,0xbf,0xe5,0x45,0xc0,0x88,0x22,0x36,0xa0 +.byte 0xec,0x21,0xdc,0x3e,0x6b,0xd2,0xc7,0xdf,0x5b,0xa4,0x32,0x28,0xca,0x23,0xe1,0x50,0x55,0x72,0x59,0x28,0x1c,0xf7,0x93,0x91,0x07,0x3c,0x4e,0x81,0x20,0x58,0x9b,0x07,0x38,0x37,0x68,0x2c,0x29,0xba,0x20,0x11,0xa9,0xa0,0x29,0x65,0x57,0xb1,0xe3,0xb1,0xfb,0xe2,0x70,0xee,0x1f,0xcd,0xf5,0x61,0xea,0x7a,0x08,0xb4,0x1e,0xfe,0xe7,0x4d +.byte 0x32,0xa0,0xfd,0xb4,0x52,0xa1,0x4b,0x67,0xba,0x5e,0x90,0xe7,0x56,0xec,0x06,0x03,0xb6,0xe6,0xc6,0x98,0xa1,0x41,0xf4,0xaf,0xde,0xe2,0x67,0xef,0xaa,0x05,0x97,0xc5,0x80,0x32,0xd0,0x43,0xc2,0x02,0x7a,0xcc,0x4c,0xdd,0xe9,0x1e,0xd0,0x4f,0xad,0xf3,0x4b,0x2c,0x5e,0xb8,0xd8,0x84,0xc2,0x43,0xc7,0xa9,0x86,0x4d,0x10,0xae,0xb7,0xe3 +.byte 0x5c,0xd5,0x2a,0xba,0x3b,0xd3,0x7b,0x5d,0xc8,0xe0,0x67,0x87,0xbe,0xbf,0x71,0x4e,0x22,0x68,0x12,0x53,0x95,0x73,0x5c,0x30,0x7b,0x2b,0xfd,0xc1,0x3c,0xfc,0xc4,0x0f,0xdd,0x5b,0x3e,0x1b,0x72,0x71,0xa6,0xe3,0x1f,0x2d,0x51,0xe2,0x61,0x3d,0xa0,0x60,0xc2,0x6b,0x41,0x8f,0x94,0x83,0x29,0xa3,0xb6,0xa7,0xc7,0x11,0x8f,0x1c,0xb5,0x19 +.byte 0x66,0x44,0xc7,0x05,0x58,0x83,0x28,0x69,0x0c,0xb6,0x65,0xe5,0x93,0x1c,0xb1,0xf6,0xf9,0xea,0xda,0x84,0x26,0x8e,0xa2,0xbb,0x9b,0x55,0xd3,0xbc,0x42,0x56,0x8f,0xce,0x6e,0x74,0x40,0xf2,0x02,0xa6,0x22,0x22,0x6e,0x20,0x0e,0x4b,0x8b,0x15,0xa5,0x04,0xf0,0xe0,0x7b,0x27,0x0a,0x38,0xe3,0x99,0x04,0xd0,0x5b,0x64,0xd2,0x04,0x92,0x61 +.byte 0x57,0x74,0xbc,0x1e,0x98,0x01,0x4b,0x2f,0x46,0x56,0x1c,0xeb,0x49,0x2d,0x66,0xac,0x85,0x96,0x48,0xfd,0xa1,0xf0,0xf5,0xc0,0xdb,0x7a,0xf2,0x0b,0x57,0x86,0xac,0x4c,0x6a,0x02,0x97,0x13,0xef,0x08,0xf6,0x18,0xe1,0x5c,0xb3,0x18,0x3d,0x70,0xc0,0x76,0x5e,0xd0,0xb8,0x44,0x32,0x25,0x75,0x62,0xa2,0x80,0x78,0x8c,0xc4,0x2a,0x84,0xbc +.byte 0x51,0xd4,0xee,0x44,0x48,0xe5,0xc4,0x48,0xbf,0xc0,0x27,0xc1,0x77,0x25,0xf5,0x59,0x6b,0x60,0xae,0xa5,0x42,0xfe,0xc3,0x06,0x91,0xe3,0xdb,0xa9,0x4b,0xe2,0x73,0x95,0x1f,0xf6,0xb6,0x66,0x71,0x63,0xb3,0x14,0x4a,0x3d,0x36,0x84,0xbe,0x2a,0x7c,0x7c,0xba,0x0e,0x8d,0x9a,0x73,0x52,0x21,0x89,0x02,0x8f,0x94,0xa5,0x9a,0x11,0x2e,0x6e +.byte 0x78,0xf7,0x07,0xf8,0xb1,0x42,0x96,0x06,0x78,0xf0,0x53,0x86,0xec,0x2b,0x1f,0xa7,0x84,0x79,0x37,0xc7,0x61,0x83,0x8e,0x62,0x65,0x49,0xdd,0xfe,0xee,0x97,0x70,0xa2,0x73,0xb5,0x85,0xaf,0x10,0xed,0xb8,0x74,0xec,0x42,0xd0,0x14,0x47,0xa6,0x90,0x7c,0x07,0x22,0xb4,0x4e,0xfc,0x12,0xa1,0x9d,0xd4,0x73,0x8f,0x6a,0x55,0xf8,0x56,0x25 +.byte 0xdb,0x9b,0xe8,0x10,0x87,0x7a,0x4b,0x42,0x9c,0xbb,0x6e,0xf1,0xd7,0x1d,0xf4,0x07,0x31,0x9c,0x94,0x3a,0xb6,0xad,0x4b,0xf4,0x57,0x3d,0x2f,0xba,0x23,0x36,0x34,0x52,0x62,0xf7,0x64,0xc7,0x47,0xeb,0x41,0xad,0x07,0xfb,0x3e,0x08,0x74,0x92,0x58,0x0f,0x73,0xe2,0x53,0x35,0xda,0xae,0x64,0x3c,0x47,0x89,0xaf,0xce,0x59,0x35,0x75,0x8b +.byte 0x50,0xee,0xbf,0xbe,0xd1,0xf4,0x2f,0x11,0xa3,0xfe,0xce,0xfd,0x15,0x0d,0x32,0x17,0x00,0xfb,0xad,0x02,0x70,0x5c,0xeb,0x59,0xfb,0x87,0xe5,0xed,0x0e,0xde,0x97,0xe7,0x75,0xb6,0xdc,0xe9,0xb0,0x08,0x26,0x0e,0x11,0xd4,0x4f,0xc4,0x92,0x71,0x7c,0x63,0xef,0xc0,0x14,0x64,0xe1,0x0f,0x7e,0xe6,0xcb,0x5b,0x4c,0xd4,0x16,0x8b,0x7b,0x8b +.byte 0x2f,0x2a,0x77,0xef,0xd3,0xdf,0x56,0xc0,0x5a,0x94,0x72,0xd5,0x36,0x12,0xfa,0x25,0xd7,0x77,0x52,0xdd,0xea,0x11,0x2f,0x6b,0x16,0x6e,0xe3,0xa2,0x84,0xba,0x55,0xc2,0xb0,0xe2,0x3b,0x53,0xb6,0xa4,0xc6,0xa5,0x3f,0x1b,0xb3,0x38,0xc0,0x2f,0x1a,0x80,0xe0,0xa4,0x60,0x49,0x8c,0xe3,0x23,0x5f,0x59,0xfd,0x2a,0x0f,0xe8,0x4c,0xaf,0xd7 +.byte 0x36,0xc7,0x25,0x21,0xad,0x41,0x54,0x27,0x95,0x15,0x42,0xbc,0xb3,0x77,0x4e,0x97,0xf4,0x3c,0x54,0xcc,0x19,0x63,0x62,0x67,0x97,0x5a,0xd0,0x59,0xfb,0xce,0xcd,0xe1,0x3c,0xb6,0xc9,0x49,0xc4,0xff,0xde,0xf9,0x89,0x87,0x9c,0xdf,0x4e,0x8c,0x9d,0xe5,0xbd,0x0d,0x0c,0x6e,0x93,0xfd,0xea,0x90,0xf2,0x80,0x7e,0x00,0x9a,0x06,0x02,0x87 +.byte 0xae,0xca,0xf4,0x46,0xbb,0xb5,0x52,0xee,0x18,0xb0,0xf1,0x61,0xcb,0xe1,0x65,0x9c,0x0b,0xfb,0xe6,0x3b,0xeb,0x3a,0x1a,0x22,0x41,0x0b,0x99,0xa4,0x8e,0x01,0x5e,0x7c,0x4e,0x1a,0xaa,0xab,0xd3,0x8b,0x99,0x7f,0xba,0x6b,0xec,0xe7,0x3a,0xd6,0x55,0x46,0x20,0x1b,0x10,0x39,0x06,0xcc,0x90,0xc1,0x6a,0xa5,0x27,0x7c,0xca,0xa5,0x58,0x07 +.byte 0xd7,0xaf,0x6d,0x12,0xa6,0x68,0xc7,0x0e,0x19,0x53,0x44,0x22,0x85,0xbb,0x72,0x9c,0x4d,0xfb,0xeb,0x94,0x3a,0xa0,0x64,0xf5,0x25,0xe8,0xee,0x7a,0x3b,0x71,0x0e,0xbb,0x40,0xa2,0xb3,0xc9,0x6b,0x14,0x0f,0xc3,0x75,0xac,0x1b,0x5c,0xf1,0x34,0x51,0xcb,0xeb,0x5f,0x40,0x0f,0x82,0xe9,0xd2,0x6d,0x95,0x88,0x84,0xea,0xe9,0xe3,0xa0,0xe9 +.byte 0xef,0x3b,0x33,0xfe,0x32,0x52,0x93,0xce,0x95,0x4b,0x64,0x3c,0x97,0x76,0x91,0xd8,0xce,0xb5,0xc2,0xda,0x58,0x23,0x27,0xe2,0x3d,0xbe,0xf6,0x31,0x79,0x73,0x0e,0x31,0xd7,0xa3,0xaa,0xac,0xcf,0x31,0x1e,0x75,0x58,0x14,0x21,0x52,0x1c,0x3e,0x4f,0x2a,0x2b,0x9a,0x22,0xbc,0x42,0x68,0x5b,0x83,0xc2,0x8c,0xd4,0xe8,0xd9,0x02,0x0d,0x13 +.byte 0x2f,0x08,0xd3,0x11,0xb7,0x4b,0x84,0x67,0x43,0xda,0x20,0xdb,0x89,0xd5,0x9e,0x14,0x54,0x3d,0x49,0xda,0xac,0x3f,0x8f,0xf5,0x17,0xfe,0xb8,0x5f,0xc3,0x20,0x38,0x27,0x21,0x32,0xbf,0xf3,0x9b,0x2c,0x0b,0x9b,0xeb,0x64,0x87,0xf7,0x9d,0xed,0x15,0x05,0x21,0x69,0xcf,0x2d,0xf8,0xfb,0xf2,0x81,0x51,0x08,0xc7,0x18,0x81,0xdf,0xed,0xa4 +.byte 0x70,0xb3,0x07,0xfa,0x00,0xd5,0x65,0xb9,0x5a,0x82,0x67,0x6f,0x10,0xfc,0x46,0x05,0x9a,0x85,0x64,0x14,0x60,0x64,0x4d,0x1f,0x13,0x57,0xbb,0x7c,0x4a,0x10,0x84,0x8c,0x57,0x36,0x13,0x22,0x00,0x04,0x2d,0xcf,0x27,0x3d,0xf4,0x27,0x3e,0x32,0xb3,0x87,0xda,0x82,0xaa,0xad,0xd7,0xa7,0xc5,0x3c,0x45,0xec,0x28,0x82,0x79,0x95,0x8f,0x56 +.byte 0x50,0x5f,0xc2,0x15,0xab,0x18,0x58,0x4f,0x69,0x46,0xce,0x29,0x33,0x42,0x53,0xe9,0xea,0xe5,0xa8,0x5b,0x90,0xc4,0xf4,0xbf,0x8a,0x20,0x62,0xad,0xa5,0xea,0x6a,0x4e,0xb4,0x20,0x2d,0xca,0x90,0xdf,0xbd,0xab,0x5b,0xc3,0x33,0x7c,0x53,0x1f,0xf5,0x2e,0xc0,0xbf,0x19,0xe1,0xa1,0x5a,0x63,0xf3,0x13,0x4d,0x6e,0xef,0x4f,0x3a,0x94,0x18 +.byte 0xbe,0x79,0xdb,0xbf,0xc2,0x2c,0xb3,0x36,0x59,0xab,0x21,0x1d,0x98,0x60,0x70,0xdd,0x95,0x51,0x19,0x07,0xd6,0x68,0x0e,0x2a,0xd4,0x4c,0x30,0x18,0x1c,0xe4,0xe1,0x89,0x15,0x25,0xea,0x27,0xcf,0x51,0x56,0xc9,0xa9,0xa7,0x31,0x08,0x17,0xfb,0xfc,0xf6,0x0c,0x5d,0xf1,0x7c,0x36,0xcb,0xad,0xef,0x29,0xf5,0x2e,0x23,0x09,0xcf,0x31,0x6f +.byte 0x74,0x12,0xd2,0xc2,0xc7,0x19,0xa5,0x6e,0x20,0x09,0x67,0xdc,0x41,0x69,0xbe,0x15,0xd6,0xeb,0x7b,0xba,0x63,0xae,0x65,0xd8,0x67,0xec,0x6e,0xcc,0x1d,0x04,0x08,0xfb,0x7c,0x34,0x1d,0x5f,0x1e,0x51,0x1c,0x30,0x72,0xd3,0x0c,0x48,0x60,0x3d,0x52,0xae,0xe6,0x78,0x44,0x6d,0xb8,0x40,0x08,0xb7,0x7a,0xa9,0xfc,0xa0,0x86,0xff,0x32,0xd6 +.byte 0x5a,0x31,0x4e,0xe2,0x65,0xab,0xb0,0x84,0xb6,0x74,0x3e,0xa6,0x67,0x7c,0xa2,0x0f,0x23,0x22,0xab,0x72,0x7e,0xeb,0x45,0xa9,0x2a,0xb4,0xd3,0xcc,0x27,0x5c,0x12,0xdb,0x14,0x68,0x73,0x0f,0x36,0xbf,0x9f,0x14,0x12,0xe9,0xef,0x04,0x2a,0x63,0x41,0x4b,0x04,0x9b,0x4c,0xc4,0xb2,0xb9,0x1c,0xc0,0xb8,0xcc,0x23,0x61,0xc4,0xed,0x27,0x1e +.byte 0x1d,0x97,0x3d,0x40,0x4c,0x1f,0xeb,0x6e,0xc4,0xfb,0x5c,0x2d,0xf5,0xf1,0xbb,0x05,0x47,0xa2,0x1a,0x9c,0x2b,0x8f,0xce,0x98,0x09,0x6b,0x86,0x22,0xf8,0x3a,0xae,0xf3,0xb4,0x66,0x2f,0xdb,0x20,0xa5,0xc6,0xb6,0x35,0xb5,0x5a,0x68,0xb5,0x37,0x2c,0xab,0x13,0x3d,0x2d,0xcb,0x38,0xed,0x3c,0x7a,0x1f,0x26,0x08,0x58,0x94,0x52,0x30,0xec +.byte 0x06,0x9f,0x90,0x97,0x4d,0x90,0x49,0x23,0xaf,0x00,0x90,0x6b,0x96,0x37,0x02,0x4c,0x35,0xc0,0x3e,0x66,0x2c,0x52,0xbc,0x75,0x28,0xd7,0x8f,0x25,0xbe,0x91,0x10,0x22,0x67,0xbf,0x4a,0x4d,0x62,0xc4,0xe9,0xda,0xe2,0x79,0xcc,0x76,0xeb,0x99,0x87,0xac,0x39,0x7d,0xf6,0x5a,0x37,0x85,0x30,0x33,0x65,0x3f,0xd9,0xd6,0x17,0xf8,0xf0,0x86 +.byte 0xee,0x5c,0x2f,0xb0,0xb3,0x4f,0x83,0x6c,0x4a,0x8f,0xfc,0x80,0x91,0xaf,0x4b,0x21,0x9c,0x9b,0x44,0x3c,0xed,0x67,0xfb,0xa3,0x31,0x7f,0xd4,0x73,0x72,0xb9,0xc1,0x31,0x96,0x47,0x8e,0x99,0x8e,0x62,0x1a,0xfd,0xc7,0x9d,0x2f,0x4c,0xda,0xe5,0xae,0x17,0xb6,0x40,0x5f,0x9e,0xa8,0xf2,0xcc,0xd7,0xd5,0x40,0x33,0x88,0x57,0x63,0x9b,0xde +.byte 0x82,0x71,0x68,0xfe,0xaf,0x29,0x6c,0xc1,0x2c,0x2f,0x02,0x42,0xd7,0xa5,0x28,0x05,0xca,0xa0,0xb6,0x8c,0x43,0x90,0x05,0xe2,0x1c,0xb7,0x76,0x79,0x39,0xd3,0x23,0xe1,0xe7,0xbb,0x19,0x65,0x1a,0xb4,0xbb,0x5a,0xcf,0x43,0x70,0x26,0x1a,0x2f,0x61,0x78,0x75,0x08,0xb0,0x88,0xe5,0x4a,0x46,0x0a,0xfc,0xcb,0x46,0x18,0xb0,0x8d,0x9b,0xeb +.byte 0xf5,0xe1,0x83,0x04,0x84,0x4f,0xd6,0xa0,0x4f,0xb2,0x4c,0x44,0x08,0xde,0xd6,0x82,0xb5,0x9a,0x45,0x15,0xb8,0x21,0xc7,0xf5,0xe2,0xfd,0x02,0x27,0x18,0x13,0x24,0x18,0x01,0xd1,0x2a,0xff,0x63,0xf2,0xa4,0x97,0xc8,0x4b,0x3b,0xae,0x49,0x47,0x54,0xe8,0x75,0xe7,0x16,0x77,0x22,0x10,0x7b,0x3c,0xf0,0xdb,0x49,0x6e,0xd6,0x55,0x9d,0x43 +.byte 0x6f,0x6e,0x2d,0x97,0xea,0x16,0x2e,0x0c,0x85,0x89,0x67,0xe1,0x7b,0x38,0xa6,0x2b,0x89,0xf0,0xcd,0x90,0xcd,0xba,0x9a,0x70,0xa9,0xe3,0xff,0xe0,0xbd,0x15,0x3e,0x4b,0x13,0x62,0x7b,0x59,0x64,0x18,0x96,0xe9,0x6a,0xf3,0x69,0x2d,0x2d,0x25,0xe7,0x91,0xd3,0xbc,0x74,0x58,0x66,0x2f,0x5e,0x8b,0x52,0xf6,0x91,0x24,0xa8,0x6f,0xa5,0xce +.byte 0xa1,0x4e,0x3b,0xe9,0xc5,0x30,0x7e,0xa5,0xc7,0xe2,0xb3,0x71,0x3b,0x25,0xb9,0x5f,0xe5,0x9c,0xf8,0x46,0x23,0xc5,0xa2,0xc1,0x1f,0x3f,0x43,0xa6,0xaa,0xf1,0x36,0x27,0xc6,0xa8,0xed,0x0d,0x50,0x71,0xf1,0x38,0x27,0xb7,0x16,0x43,0x7c,0x7f,0x77,0x5b,0x25,0x59,0xb7,0x08,0x0d,0xc8,0x84,0xe4,0xc2,0x03,0x95,0xe5,0xf3,0x0a,0x9c,0x1f +.byte 0xde,0x98,0x7c,0xa9,0xe2,0x70,0x9e,0xde,0xf6,0x80,0xd0,0xf8,0x86,0x4a,0x7a,0x0d,0x16,0xaa,0xde,0xba,0x02,0x30,0x8a,0xe6,0x03,0x0f,0xa1,0xf1,0xe8,0xd6,0xf8,0xce,0x7b,0xba,0x74,0xa8,0x25,0xb0,0x49,0x22,0xa6,0x81,0x7e,0x71,0xc5,0x97,0x9e,0xa8,0x46,0xa7,0xe9,0x8b,0x7c,0x7c,0x4c,0xc5,0x3c,0x93,0x08,0xb9,0x8b,0x3c,0x33,0xd6 +.byte 0xc4,0x37,0xc8,0x05,0xe7,0xfe,0xc2,0x7c,0x02,0xe6,0xda,0x09,0x52,0x2c,0xc6,0xa8,0x6e,0x44,0x7e,0x55,0xf0,0x32,0x10,0xcb,0x1e,0xa7,0x77,0x8d,0xc7,0xfe,0xb5,0xf6,0x3b,0x49,0xf2,0xfb,0xe0,0x41,0x98,0xd3,0x17,0xa6,0x5d,0x3f,0x4c,0x95,0xb0,0x02,0x8d,0xab,0x36,0xb7,0xa0,0x92,0x40,0x5e,0x15,0xfb,0xa9,0xb4,0xa3,0x04,0x8b,0x6b +.byte 0x81,0x44,0x59,0x22,0x10,0xcb,0xc5,0x52,0x3f,0x78,0x70,0x00,0xe2,0xa2,0xf7,0x76,0x62,0x72,0x06,0x8b,0xbb,0x56,0x0f,0x8c,0x67,0x2f,0x52,0x3f,0x3b,0xdc,0x15,0x79,0x55,0x89,0x6c,0x61,0x23,0xcc,0x6b,0x41,0x77,0xe5,0xc4,0x90,0x51,0xc3,0x87,0x22,0x1e,0x89,0xf5,0x5b,0x41,0xd7,0x34,0x22,0x3c,0xbd,0x29,0xaa,0x54,0xed,0x5a,0x90 +.byte 0x17,0x24,0xba,0x7a,0x46,0x5f,0x54,0x33,0x56,0x7e,0x2d,0x03,0x59,0xcb,0xbb,0x7a,0xce,0xbb,0x8d,0xf7,0xb6,0x38,0x00,0x18,0x6a,0xa1,0x6c,0xdf,0x42,0x49,0x4d,0x9b,0x4f,0xd6,0x85,0x54,0x1f,0xad,0x17,0xdd,0x66,0x0e,0x7c,0x30,0x86,0x82,0x1c,0x5a,0x81,0x08,0x55,0x51,0x5b,0x06,0x54,0x52,0x3e,0x8b,0x6e,0x72,0x92,0xd2,0x05,0x5d +.byte 0xe4,0xe8,0x0e,0x62,0x1d,0xec,0xb1,0x7f,0x42,0x05,0xd5,0xd3,0x60,0xd4,0xdc,0xa4,0x48,0xc0,0xf0,0x89,0xef,0x5b,0xae,0x5f,0xcd,0xf0,0x62,0xaa,0x3e,0xd5,0x1a,0xbe,0xe3,0x08,0xd5,0xe8,0x00,0x21,0x8c,0x0b,0x0c,0x8e,0x24,0xac,0xb2,0xea,0x44,0x9f,0xce,0x53,0x45,0x9a,0x85,0x67,0x99,0x85,0xea,0x92,0xa7,0x1d,0x86,0xb4,0x3b,0x22 +.byte 0xa2,0xcd,0x35,0x65,0xb5,0xa6,0xdb,0x6d,0x48,0xd1,0xa4,0x76,0x0c,0x00,0x30,0x62,0x86,0x06,0xda,0xa8,0xfe,0xec,0x70,0x87,0x4a,0xe8,0x2e,0x4d,0xe3,0x94,0x0b,0xdf,0x81,0xcd,0xfe,0x23,0x79,0x2c,0x2b,0xae,0xf7,0x75,0x49,0x47,0x24,0x46,0x09,0x10,0x62,0x39,0x3b,0x50,0xf1,0xfa,0xf7,0x5f,0xe4,0x7c,0xa5,0xc0,0x25,0x9e,0x20,0x4d +.byte 0xc8,0x6b,0x93,0xc5,0x4a,0x6b,0x62,0xb8,0x3b,0xe5,0x0d,0x92,0x70,0x26,0xa5,0x2b,0xd0,0x9f,0x03,0x8b,0xd3,0x1a,0xc4,0xb0,0xa3,0xc7,0xf4,0x35,0xe5,0x1d,0xe0,0xaa,0x43,0xab,0x64,0x10,0x2b,0xa4,0x09,0x42,0xee,0xba,0xb7,0xbf,0xfd,0xa6,0xff,0x76,0xe5,0x12,0xd6,0x50,0x9a,0x26,0x6b,0x3a,0xd3,0xe6,0x7d,0x3e,0x0e,0x9b,0x95,0xd7 +.byte 0xbf,0xb6,0x7e,0xfb,0x3c,0x24,0xa4,0x26,0x98,0x88,0x81,0xf4,0x56,0xa4,0xf7,0xe8,0x87,0x15,0x5e,0x9f,0x84,0xdd,0x04,0x66,0x43,0xd8,0x76,0xc2,0xa3,0xfd,0x4b,0x58,0x09,0x06,0xa6,0x60,0x5c,0x3f,0x75,0x80,0xd7,0xc4,0x29,0xf9,0x0b,0x1e,0x4d,0xe5,0x26,0xf6,0xae,0x7a,0xc1,0x05,0xf3,0xf1,0x6c,0xee,0xed,0x56,0x0b,0x51,0x66,0xbe +.byte 0x99,0xec,0x9c,0xc2,0x97,0xe2,0xed,0x09,0x1d,0xa8,0x18,0xaa,0x1c,0x9e,0x20,0x62,0xb1,0x80,0x68,0x3e,0x28,0x1f,0x4f,0x50,0x0e,0x41,0xaf,0x17,0x44,0x79,0x16,0xca,0x17,0xe9,0x13,0x66,0x0a,0x04,0x68,0x41,0xe2,0x1d,0xc7,0x00,0x1e,0x66,0xa3,0x6c,0x2d,0x52,0x8c,0x0b,0x7c,0x03,0x48,0x73,0x3b,0xa9,0x84,0xe5,0x31,0x12,0x0f,0xe8 +.byte 0x1e,0x58,0x4d,0xd0,0x1b,0xb7,0xcf,0x75,0xd5,0x2c,0xca,0x33,0x17,0x95,0x9c,0x30,0xc7,0x7f,0xe9,0xde,0xae,0x19,0x72,0x00,0x2a,0xf5,0xde,0x93,0x3f,0xf5,0x44,0xe5,0xf8,0xc7,0xeb,0x1a,0x5d,0x5b,0x11,0x30,0x09,0xf5,0x49,0x66,0x70,0x1a,0xd5,0xe6,0xfc,0xe6,0x59,0x3d,0x17,0x6c,0xb5,0x0c,0xdf,0x1e,0x9c,0x48,0xd1,0xde,0x12,0xd6 +.byte 0xc8,0x48,0xc8,0x73,0x6d,0xfc,0xec,0x07,0xce,0x02,0xe5,0xb3,0x18,0xb9,0x55,0x4d,0x64,0x07,0xf3,0xaa,0x3c,0xf1,0x71,0x22,0x31,0xbb,0x74,0x2c,0x9f,0x7b,0x68,0x9d,0x80,0x49,0x32,0x48,0x9b,0x54,0xf3,0x74,0x37,0xac,0x4e,0xb2,0x96,0xdf,0x9d,0xeb,0x43,0xe0,0xd0,0xa0,0xe3,0x77,0xbd,0x8b,0x92,0x95,0x9d,0x63,0x8d,0xa8,0x23,0x07 +.byte 0xb0,0xcb,0x9d,0x8d,0x3f,0xe2,0xd5,0x81,0x6a,0xe5,0xc2,0xfe,0xda,0x1c,0x25,0x25,0x5b,0xa8,0xad,0x06,0xec,0x0d,0x4b,0x68,0xc3,0x45,0x81,0x38,0xb0,0x22,0x71,0xa4,0x2b,0xf3,0xa6,0x05,0xae,0x0c,0x48,0x94,0x0d,0x3d,0x48,0x51,0x76,0xdf,0x79,0x66,0x0e,0x28,0xc0,0xc1,0x6f,0xc8,0x8f,0xf7,0x7d,0x37,0x06,0xa2,0x8a,0x3a,0x6b,0xab +.byte 0xe0,0x55,0x8e,0xec,0x89,0xe2,0xca,0xc4,0x01,0x03,0x5d,0xa1,0x84,0x21,0x44,0xbb,0x6b,0x36,0x63,0x57,0x4f,0x54,0x88,0x81,0xbe,0xf8,0x53,0xf7,0x57,0xee,0x30,0x85,0x03,0x11,0x86,0xff,0xe4,0xd6,0xc4,0xf0,0x3c,0xcf,0xfd,0x38,0xd8,0xcb,0xd0,0x96,0x03,0xf2,0xc7,0xfa,0x18,0xc8,0x1b,0xe6,0x77,0x3c,0x61,0xa9,0x14,0xdb,0xb4,0x5c +.byte 0x2d,0xee,0xd7,0xe8,0xc4,0x0c,0x69,0x0c,0x55,0xe2,0x99,0x4b,0xc4,0x89,0xc8,0xee,0x48,0x0e,0x16,0xd7,0xa4,0x78,0x25,0xda,0xd3,0xa8,0xac,0x89,0x66,0x67,0x0d,0x51,0x21,0x0e,0x91,0xfb,0xb5,0xab,0x33,0xcb,0x3e,0xc7,0x0f,0x03,0x22,0x51,0x71,0x03,0xa0,0x3c,0xa9,0x35,0xcb,0x40,0xa7,0xbe,0xe7,0xc3,0x51,0x43,0xd8,0x9a,0x24,0xb7 +.byte 0x7e,0xfb,0x26,0x8d,0xa5,0x1a,0x6b,0xe7,0x97,0xe4,0xdd,0xc0,0x3e,0x98,0x67,0x55,0x79,0x56,0xb9,0x7e,0x25,0x4c,0x5c,0x5a,0x47,0x0a,0xce,0xb6,0x4d,0x2c,0x69,0x73,0xaa,0xf0,0x12,0xbb,0x9d,0xe1,0x60,0xc4,0x5b,0x10,0x32,0x6d,0x89,0x54,0xb1,0xfe,0x36,0xbe,0xb2,0x60,0x9a,0x91,0x73,0x9c,0x32,0x61,0xad,0x9a,0xf7,0x56,0x5f,0x5a +.byte 0x54,0xaf,0xb2,0x0c,0x5b,0x1a,0xe6,0x98,0x94,0xed,0x69,0x0b,0x8d,0x06,0x87,0xc9,0x20,0xdc,0x92,0x2d,0x5e,0xba,0xbb,0x15,0xef,0xc1,0x07,0x18,0x44,0x3f,0xf4,0x48,0x3e,0x7b,0xa4,0x9e,0x14,0x6b,0x97,0xdd,0x68,0x33,0x18,0xdd,0x47,0x08,0xa6,0x3b,0x8d,0x79,0x58,0x92,0xd9,0xda,0x82,0x34,0xa7,0x99,0xbc,0x43,0xa3,0x0a,0x7e,0x85 +.byte 0x0b,0xab,0x0e,0xc2,0x94,0x22,0x2d,0x05,0x99,0x9d,0x5c,0xc7,0xb2,0x7b,0x18,0x3e,0xb2,0xdd,0x47,0xb3,0xd7,0xcf,0x19,0xc7,0x55,0x5e,0x64,0xd8,0x7b,0xb4,0xf6,0x11,0x72,0xed,0xbd,0xfc,0xd8,0xe9,0x9f,0xcd,0x9a,0xeb,0xb2,0x6c,0x04,0xb9,0x88,0xf7,0x60,0x68,0xc3,0xf2,0xfd,0xa0,0x8c,0x82,0xc5,0xf7,0x5d,0xc3,0x9a,0x1e,0x49,0x27 +.byte 0x69,0x35,0xb0,0x8f,0xe9,0xb3,0xe4,0x09,0xd8,0x1a,0x73,0x9e,0x56,0x41,0xfa,0xe0,0x94,0x9e,0x0e,0x65,0xe6,0x5b,0xe2,0x12,0x39,0xca,0x86,0x0c,0xae,0xee,0x24,0x58,0xfd,0x85,0x09,0x7a,0xad,0x54,0xde,0xda,0x06,0x73,0x7d,0x11,0x7e,0x91,0x44,0xf3,0x4b,0x61,0xce,0x8a,0xff,0x76,0x92,0x2e,0x43,0x52,0xcf,0x63,0x3f,0xc4,0x1f,0x7f +.byte 0x4d,0x67,0x21,0xed,0xd7,0x88,0xdb,0x36,0x56,0x11,0xb2,0x3b,0xee,0x5f,0x2d,0x5f,0x17,0x98,0xa1,0xd5,0xcc,0x82,0xfd,0xc2,0x56,0x69,0xaa,0x68,0x86,0xaf,0x48,0x77,0xba,0xe9,0xd9,0x42,0xcd,0xaa,0xe3,0xad,0x2b,0x17,0xef,0xd3,0x54,0xc5,0x4e,0x31,0x0b,0x14,0xb7,0x73,0xc1,0x6f,0xc3,0x06,0x41,0x1a,0x11,0x19,0x9f,0xe9,0x9f,0x61 +.byte 0x4f,0x13,0x9b,0x3e,0xcd,0x7c,0xd6,0x2a,0xb3,0x87,0x84,0x58,0x58,0x10,0x1f,0xa0,0x2e,0x5c,0x15,0x8b,0x5e,0x37,0xd4,0x22,0x93,0xd9,0x67,0xe1,0xa8,0x35,0xe2,0x95,0xd8,0x4c,0x2c,0x65,0xc9,0x21,0xaf,0xf9,0xdd,0x3d,0x2c,0x0e,0x0c,0xcc,0x6b,0xad,0xb3,0x6d,0xd2,0x3e,0x65,0x8e,0x82,0x70,0x41,0xd6,0xaa,0x97,0xab,0x38,0x78,0xe4 +.byte 0x62,0x7c,0x5f,0x22,0xa3,0x1e,0xf2,0x6c,0xfe,0x3c,0xa9,0xb5,0x57,0xcd,0x96,0x11,0xd0,0x8b,0xcf,0x6d,0x06,0xcf,0x7c,0xda,0x1d,0xe4,0x22,0x5c,0x5d,0x9f,0xa8,0x24,0x55,0x45,0x93,0xc6,0xeb,0xfc,0xb5,0x71,0x5a,0x1d,0x52,0x40,0x95,0xc7,0x76,0x32,0xfb,0x2b,0x0c,0x7d,0x64,0xfa,0x5b,0x5e,0x7a,0x3b,0x0b,0xa0,0x99,0x5d,0x19,0x16 +.byte 0xe4,0x8e,0xae,0x49,0xee,0xc5,0xb2,0x24,0xd7,0x0b,0xa4,0x20,0xa6,0x74,0xc4,0x36,0x1d,0x43,0x25,0xd6,0x71,0x54,0x69,0x79,0xea,0xa3,0xd5,0xe9,0x75,0x53,0xcf,0x99,0x4e,0x3b,0xc0,0x52,0x28,0x80,0xe5,0x07,0x65,0x83,0xb3,0x24,0xfe,0x13,0x92,0xd6,0x18,0xf7,0xa3,0xeb,0x9e,0xf0,0xd5,0x69,0x93,0x79,0xda,0xb7,0x2e,0xe2,0x01,0xdd +.byte 0x9a,0xc3,0x7b,0x3b,0x17,0x88,0xe5,0xe9,0x9b,0x46,0x5c,0x5f,0x0e,0x1e,0x80,0x9b,0x11,0x1f,0xa4,0x08,0x90,0x14,0x08,0xb4,0x73,0x32,0x72,0xbe,0x43,0x4f,0x70,0x90,0xe7,0x80,0xdd,0xfd,0xa7,0xea,0x13,0xd9,0x5d,0xae,0x93,0x24,0x2b,0x1e,0xc7,0xf4,0x81,0xbb,0x5f,0xb0,0xb9,0xe4,0x35,0x39,0xf4,0x9a,0x49,0xb5,0xc0,0x47,0x18,0xc3 +.byte 0xcc,0xbe,0x26,0x36,0x44,0x2d,0x65,0x24,0xa3,0x09,0xde,0x69,0x3b,0xb8,0xdc,0x52,0x98,0x2e,0x38,0x5f,0xf7,0xb1,0x84,0xdd,0xea,0xe2,0xe5,0xec,0x96,0x31,0xb1,0x93,0xc0,0x5b,0xc4,0x87,0x4a,0x51,0x58,0x2d,0xea,0x47,0xab,0xfd,0xd3,0x76,0xf1,0xbc,0x52,0xa7,0x94,0x6c,0x74,0x1e,0x84,0x07,0x1f,0x5c,0x18,0xb9,0x06,0x37,0xf0,0xfb +.byte 0xbd,0x5d,0xaf,0xa8,0x06,0xc9,0x86,0xf0,0xd1,0x78,0x84,0x95,0x01,0xdd,0x70,0x9d,0x71,0x51,0xb7,0x80,0x69,0xbe,0xe8,0xfb,0x8f,0x43,0x72,0xd9,0xa9,0xf1,0x90,0xbb,0xf1,0xb5,0xc0,0x75,0x93,0x4e,0x14,0xc5,0x14,0x77,0x59,0xf8,0xe5,0x81,0x11,0x25,0x48,0x51,0x46,0x2a,0x69,0x59,0x92,0xe7,0xa7,0x39,0x96,0xad,0x67,0x30,0xaa,0xb2 +.byte 0x5d,0x95,0x94,0x83,0x83,0x93,0xf3,0x52,0x81,0x1c,0x27,0x78,0x1d,0x19,0x35,0x6e,0x8f,0x16,0xe5,0x3b,0xce,0x80,0x2a,0x3a,0x89,0xb7,0x51,0xfc,0x34,0x24,0xa2,0x61,0x95,0x9e,0xd4,0x69,0xa1,0x2f,0x49,0x16,0x2d,0x12,0x05,0xfe,0x69,0x62,0x12,0xa4,0x2c,0x04,0x7b,0xce,0x3f,0x34,0xc4,0x48,0x1a,0xe6,0x64,0x4b,0x8a,0xbf,0x68,0xdd +.byte 0x54,0x15,0xd3,0x25,0x49,0xdd,0xed,0x5e,0x2c,0x0e,0x25,0xbe,0x77,0xcf,0x94,0xf4,0xe9,0xf3,0xcc,0xe6,0x94,0xf9,0xb2,0x5d,0x24,0x53,0x63,0xbb,0x66,0x8d,0x73,0xef,0x79,0x5c,0x95,0x1a,0x64,0xc3,0xfd,0xc0,0xd3,0x71,0xf4,0x79,0x19,0x79,0xa5,0x30,0xf8,0x2c,0x28,0xc2,0xc2,0x9d,0x12,0x50,0x95,0x38,0xec,0xd5,0xc6,0x28,0x94,0xaa +.byte 0x83,0x66,0x3b,0xe3,0x51,0xc7,0x6a,0x75,0x2a,0x9b,0xb9,0xb0,0xa2,0xe1,0xfd,0xaf,0x58,0xd2,0x4b,0xf4,0x22,0xef,0x77,0x1e,0xa0,0x00,0xd7,0x9e,0x20,0x63,0x87,0x1d,0x98,0xab,0x0e,0x57,0x31,0x4b,0xda,0x90,0x3a,0xe6,0x6e,0x5e,0xd4,0x17,0x06,0x83,0x4f,0x90,0x33,0x1c,0xe5,0xea,0xf7,0x8d,0x95,0xa2,0x1e,0x7d,0x27,0x15,0x49,0x68 +.byte 0x3a,0x54,0xe3,0x1e,0x60,0x72,0x42,0xa6,0x8c,0x5b,0x63,0x1d,0x7d,0xb1,0xe2,0x7e,0x8b,0x19,0xf4,0x25,0x6c,0x77,0x64,0x15,0x5e,0x4c,0xfa,0x35,0x68,0xd2,0x54,0x11,0x5a,0xac,0x85,0xb0,0xb3,0xe8,0xa8,0x70,0x36,0xa8,0xe5,0x04,0xd1,0x82,0xdc,0x62,0x63,0xe6,0x3f,0x86,0x46,0x77,0x08,0x6b,0xa8,0x09,0xd0,0x56,0x09,0x87,0x9c,0x65 +.byte 0x8e,0x53,0xae,0xa6,0x2b,0x59,0x23,0xca,0xe9,0xc7,0xc4,0xb5,0xb9,0xca,0x20,0xf6,0xcc,0x62,0xfd,0xb5,0x66,0x66,0x86,0x99,0xb2,0x5a,0xeb,0xac,0xff,0x22,0xf4,0x94,0x9c,0x6d,0xc9,0xce,0xf3,0x8d,0x26,0x7f,0x06,0x40,0x71,0x8b,0x3e,0x5c,0x3e,0xe6,0x11,0x64,0x91,0x79,0xbe,0x66,0x80,0xd2,0xf6,0x2d,0x28,0x4b,0x6c,0x8d,0x9c,0x5b +.byte 0x1e,0xd1,0x15,0xb0,0xdf,0xfb,0x57,0xaf,0x4a,0xab,0xde,0x12,0xe9,0xb8,0x41,0x3d,0xc3,0xff,0xb2,0xc1,0x86,0xb0,0x06,0x5b,0xaf,0xa4,0x30,0x62,0xd0,0xd8,0x91,0x36,0x28,0xc1,0xc2,0xef,0x60,0x5d,0x42,0x04,0xd5,0x6b,0x10,0xa9,0x6c,0x88,0x5c,0x56,0x59,0x4a,0x87,0xdc,0x7c,0x41,0x03,0xb3,0x7c,0x35,0x8c,0x52,0x0e,0xc1,0xd5,0xdf +.byte 0x9b,0x8a,0x2e,0xc2,0x6b,0x06,0x7f,0xb4,0x93,0xc9,0x52,0xd0,0xc5,0x57,0x78,0x9e,0xf9,0x08,0x36,0xbc,0x4b,0xc1,0xbd,0x71,0x35,0xf8,0x73,0xae,0x9c,0xbc,0xf1,0xd1,0xba,0xe3,0x7f,0x49,0x9b,0x9b,0xb3,0xe2,0x7d,0x7d,0x18,0x6d,0x0d,0x96,0xe3,0x50,0x28,0xf2,0x7c,0x7a,0x71,0x27,0x33,0x3c,0xd3,0xeb,0x3d,0x5a,0x79,0xb5,0x69,0xed +.byte 0x40,0x38,0xbe,0xc9,0xad,0x11,0x7b,0x9d,0xe6,0x71,0xc8,0x89,0x54,0x51,0xf0,0x8f,0xdc,0xad,0x96,0xc3,0x04,0x60,0x5f,0x6d,0xa0,0x37,0xba,0x1c,0x69,0xca,0x42,0x26,0xeb,0x31,0x34,0x8d,0xae,0x25,0xe2,0x29,0x8d,0x19,0x9f,0xfa,0x75,0x91,0x4b,0x51,0xcd,0x76,0xd6,0x8f,0xa2,0x40,0x79,0xc3,0xbb,0x61,0xaf,0xc4,0x69,0xf5,0x8b,0x8a +.byte 0xb6,0x2c,0x25,0xb9,0x3c,0x8e,0x13,0xa4,0x0f,0x52,0x72,0x11,0x4b,0x89,0x63,0x01,0x05,0x54,0xd5,0x0d,0x5f,0x91,0x59,0x84,0x64,0xac,0xf7,0x9c,0xa3,0x48,0x31,0x4a,0x2e,0xea,0xf8,0xf8,0x0e,0xf0,0xd9,0x4d,0x06,0x60,0x11,0x4a,0x72,0x6f,0x93,0x93,0x85,0xf0,0x20,0x55,0x8b,0x37,0xf1,0x29,0x92,0x2d,0x1f,0xa1,0x6c,0x7c,0x90,0x4f +.byte 0xdb,0x78,0xcc,0x6c,0xb2,0x14,0x85,0x07,0x34,0xc8,0x98,0x18,0x52,0x2d,0x6b,0x13,0x63,0xc5,0x31,0x20,0x8e,0xa9,0x88,0x6b,0xb3,0x3f,0x1a,0x68,0x2f,0xf9,0xf3,0x97,0x29,0x68,0x22,0x89,0xb0,0x45,0xc4,0xf4,0x1f,0x31,0xba,0x97,0x14,0x59,0xae,0x05,0xe0,0x99,0x5b,0x29,0xcf,0xe3,0xf0,0x2a,0x0c,0xca,0x5f,0xc1,0xe7,0xe7,0x11,0x48 +.byte 0x73,0xc0,0x86,0x0b,0x59,0xc2,0x8a,0xfa,0x44,0x51,0x1c,0x84,0xdf,0x2f,0x4d,0xab,0xca,0xea,0xe1,0x48,0x9a,0xa1,0x86,0x60,0x47,0x7a,0x86,0x30,0x6a,0xba,0xbe,0x6a,0x9b,0x34,0xf4,0x52,0x0e,0xae,0x7f,0xbd,0xe0,0xf4,0x5f,0xfd,0xbc,0x57,0x02,0x95,0x6f,0xad,0x78,0x2e,0xa7,0x46,0x1c,0x2d,0x98,0x40,0xb7,0xfa,0xb5,0x08,0xee,0xb5 +.byte 0x25,0x51,0xaa,0x1a,0x14,0x41,0x48,0xe0,0x8f,0xe7,0x2f,0xfc,0xfd,0x47,0x10,0x55,0x90,0x02,0xeb,0x7f,0x0d,0x40,0xa8,0x4b,0x82,0xdc,0xab,0x43,0x35,0x62,0xa1,0x1d,0x5a,0xb0,0xc0,0x93,0x75,0x3d,0x68,0xd9,0xf8,0x31,0x22,0xfd,0x30,0xda,0xea,0xea,0x7c,0x30,0xf8,0x6f,0x75,0x5f,0x07,0x39,0xfe,0x69,0x93,0x73,0x22,0xa2,0x72,0xed +.byte 0x39,0x2f,0x00,0x5c,0xc3,0x14,0x86,0x90,0xda,0xc9,0x09,0x43,0x80,0x85,0x22,0x98,0xb0,0x4e,0x05,0x47,0x8f,0xc7,0xba,0x2e,0x4c,0x8f,0x57,0x8a,0xe9,0xb0,0x97,0x3b,0x51,0x12,0xcb,0x88,0xfd,0x5e,0x7f,0xa6,0xc6,0x00,0xd0,0x3a,0x3a,0x70,0x9e,0x56,0x28,0xa0,0x08,0x76,0x58,0x57,0x4a,0x0f,0xff,0x31,0x44,0x08,0x6c,0x23,0x79,0xad +.byte 0x35,0x95,0xc5,0xc8,0x26,0x0f,0xb3,0x17,0x04,0x1d,0xde,0x16,0x5d,0xb8,0x71,0x76,0x89,0x0b,0xd6,0xd8,0x9d,0xa1,0xdf,0xcb,0xb5,0x1c,0x86,0xc3,0x15,0x8d,0xaa,0x25,0x82,0xbf,0x6b,0x06,0xfb,0x1b,0xf5,0x11,0xaa,0x14,0x0e,0x67,0x7f,0xbd,0x46,0x21,0x8f,0x6d,0xbd,0x63,0xe6,0x14,0x05,0xa2,0xee,0x56,0xee,0xe6,0x37,0xf9,0xc0,0x2f +.byte 0xc9,0xe0,0x8e,0xdb,0xf7,0xf6,0xcb,0x83,0x79,0xcc,0xe3,0xf6,0x30,0x9d,0x56,0x31,0x40,0xd2,0x50,0x25,0xb6,0x89,0x16,0x97,0x65,0xd8,0x8d,0x1a,0xa5,0xf4,0x47,0xfc,0x4c,0x73,0x07,0x42,0x9c,0x8f,0x7f,0x10,0xb4,0x96,0x33,0x1e,0xe2,0xff,0x0c,0x33,0x35,0xbc,0x37,0x01,0x2b,0x67,0xda,0xca,0xcf,0x87,0xa2,0x38,0x71,0x6b,0xf4,0xcf +.byte 0xa6,0xc6,0x6a,0x90,0x5c,0xa0,0x8b,0x66,0x44,0xc7,0xc2,0x05,0x24,0xee,0x53,0x99,0xf3,0x07,0x78,0xb0,0x17,0xf8,0x11,0xf9,0x52,0x20,0x41,0xc5,0xdb,0x4e,0x92,0xd3,0xeb,0xd2,0x86,0xea,0x9b,0xc3,0x4c,0x1b,0x75,0xcd,0x15,0x0c,0xe0,0x28,0xe9,0xe1,0x99,0x98,0x96,0x33,0x06,0xea,0xa8,0x4e,0xde,0xc1,0x1c,0xfe,0x6c,0xca,0xac,0x6d +.byte 0xc4,0x3a,0x7d,0xd2,0x41,0xf5,0xb3,0x7d,0x1c,0x28,0x93,0x72,0xf8,0x08,0xc1,0x71,0x72,0x4c,0x41,0x68,0x38,0x80,0x2e,0x4b,0xa6,0xc5,0xc7,0xb4,0x24,0x29,0xd0,0xce,0xb2,0x3d,0xc4,0x60,0x5b,0xeb,0x2d,0x80,0x13,0xee,0x95,0x41,0xfe,0x49,0x6d,0x89,0xc0,0x7a,0x61,0x51,0x3f,0xbb,0x24,0x7c,0x64,0x5e,0x9f,0xf7,0x60,0x88,0x95,0xe8 +.byte 0x60,0xc5,0xf6,0xc3,0xc3,0xd4,0x43,0xce,0xf9,0x4e,0x35,0xf2,0xfa,0xb0,0x2b,0xe3,0xfe,0xb8,0x88,0x19,0xf2,0x89,0xc0,0xb5,0x00,0x61,0xc8,0xe5,0xaa,0xde,0x18,0xb4,0xd4,0x21,0xbe,0xcc,0x61,0xc7,0xc9,0xfe,0x22,0xcc,0x65,0xf6,0x79,0xe8,0x4d,0x1c,0x30,0x31,0x7a,0xd4,0xbc,0x98,0x2d,0x72,0x5e,0x5c,0x4f,0x7e,0x52,0x9c,0x95,0x20 +.byte 0x29,0xa4,0x0b,0xf7,0xb2,0x7d,0xcc,0xc3,0x8c,0x94,0xb0,0x09,0xf4,0x6f,0x59,0x63,0x91,0x2a,0x06,0x80,0x09,0x01,0x3c,0x73,0x83,0x42,0xa1,0x5c,0x0f,0x42,0xf4,0x74,0x3c,0x24,0x8c,0xbe,0x91,0x73,0xdf,0xf1,0xea,0x21,0xbd,0xc9,0x36,0x17,0xca,0x81,0x28,0xd9,0x4a,0xc4,0x2e,0xdf,0x4c,0x4f,0xbd,0x1e,0xbc,0xe9,0x32,0x12,0xd3,0x8f +.byte 0x48,0x9b,0x4f,0x49,0x23,0x54,0x15,0x15,0x14,0x8b,0x18,0x64,0x7d,0x08,0x7f,0xc4,0x56,0x01,0x94,0x4e,0x50,0xe8,0xf2,0x4a,0xb5,0x3c,0xa0,0xb5,0xaf,0x55,0x70,0x44,0x41,0x5c,0xe6,0x61,0x5a,0xbb,0xf2,0xe6,0xc9,0x05,0x33,0x45,0x8f,0xbc,0xe5,0x59,0x7f,0x66,0xc5,0x61,0x4d,0x1b,0xc7,0xee,0x45,0x7d,0x57,0x8f,0x6c,0x9d,0x8b,0x87 +.byte 0x98,0xa8,0x58,0xac,0x4a,0x31,0x79,0xd6,0x26,0x08,0x2f,0x28,0x3f,0x31,0x77,0xad,0xff,0xe1,0x9d,0xa8,0xf7,0xe0,0x76,0x66,0x48,0x00,0x52,0xe8,0x9a,0xb2,0x47,0x5e,0x0a,0x87,0x86,0xaf,0xf6,0x7d,0x46,0x78,0x66,0x68,0xf7,0x68,0x0c,0x6f,0x5c,0xd7,0x09,0xc0,0xd7,0x90,0x98,0xe2,0x5c,0x07,0xe9,0xd1,0x58,0x48,0x57,0x9f,0x48,0x99 +.byte 0x87,0xdf,0x06,0xc1,0x35,0x0f,0xd8,0xb0,0xa9,0xfa,0xdc,0x31,0x76,0xd1,0xad,0x47,0x80,0xe4,0x74,0xe0,0xda,0x4b,0x77,0x8b,0x71,0xab,0x9a,0x8e,0xd7,0x6b,0x91,0xb1,0xdb,0x78,0xd2,0x86,0xf7,0x61,0x1b,0xdc,0x34,0x57,0x32,0x51,0xee,0xd3,0xff,0xb2,0x6c,0x6a,0x79,0x90,0x9c,0x1f,0x6b,0xe7,0x43,0x20,0x05,0x4f,0x66,0x83,0xd0,0x56 +.byte 0xe1,0x21,0x63,0xf4,0xd6,0x96,0x91,0xcb,0x51,0x3c,0x13,0x88,0x97,0x26,0x88,0xda,0x7c,0xd4,0x0d,0xcb,0xdf,0xc2,0x7d,0xcd,0x2c,0x0e,0x28,0x23,0x21,0x5f,0xbe,0x5d,0x62,0x58,0x6c,0xa7,0x45,0xae,0x1f,0xac,0x35,0x53,0xdb,0x2c,0xa6,0x71,0xe4,0x11,0x5e,0x59,0xbe,0xd5,0x20,0x2a,0xc4,0xcd,0x4c,0x1b,0xe0,0x38,0xef,0x02,0x0c,0x5f +.byte 0x5a,0x1b,0xf9,0x1e,0x32,0x63,0xd7,0xa6,0x0f,0x1d,0x98,0xd5,0x3a,0x0f,0xf6,0xcc,0xfc,0xd6,0xb4,0x87,0xc5,0x76,0xd8,0x3e,0x72,0xb0,0x20,0xfe,0xb3,0xfc,0x48,0x4c,0xd1,0x71,0xcd,0x13,0xef,0xe8,0x40,0xd9,0x0d,0xf6,0x1d,0x5b,0xa4,0x26,0x56,0x8c,0x66,0xcb,0x18,0x5a,0x5f,0x86,0x43,0x2c,0xa4,0x1e,0x00,0x3f,0x09,0xbf,0x8e,0x61 +.byte 0xad,0x2a,0x44,0x97,0x35,0xb2,0xf3,0x50,0x5f,0xfa,0x01,0x74,0xbf,0x70,0x46,0x38,0xf1,0x15,0xaa,0x04,0xfe,0xe9,0x3f,0x43,0x2f,0x53,0xcb,0xea,0x5c,0x04,0x8e,0xe6,0x43,0xeb,0xc0,0xd9,0xbf,0x4a,0xc1,0xbc,0xf9,0x11,0xd5,0x33,0xdc,0x41,0x8e,0xfe,0x5e,0xf3,0x8c,0x80,0x47,0x46,0x01,0x9e,0xa9,0x2c,0x2d,0xd2,0x90,0x7f,0xce,0x7c +.byte 0x59,0x78,0xaa,0xbb,0x96,0x52,0x0a,0xf3,0x18,0x1f,0x0b,0x41,0xc1,0xd5,0x12,0x14,0x1a,0xe1,0x4e,0xac,0xf8,0x2a,0x56,0xfe,0x66,0x34,0x21,0xdf,0x1f,0x6a,0x02,0x85,0xd2,0x38,0xc0,0x39,0x5c,0xa7,0x3f,0xcc,0x2b,0x6f,0x69,0xe7,0xa7,0x0a,0x36,0xf1,0xa9,0x77,0x59,0x2c,0x44,0x8b,0x72,0xc9,0xc2,0x74,0x32,0x48,0x76,0x19,0x1e,0x49 +.byte 0x10,0xe6,0x46,0xdf,0x82,0x9b,0xad,0x4e,0x40,0x20,0xd7,0xd3,0xf5,0x5c,0xbc,0x25,0x94,0xd1,0x68,0xaf,0x29,0xc5,0xcd,0x1b,0x86,0x4b,0x88,0x21,0x6e,0xeb,0x06,0x14,0xb5,0x15,0xe7,0x26,0x01,0x05,0x4e,0x3a,0x2a,0x24,0xbe,0xf2,0x64,0x6e,0xf4,0x9c,0x60,0xf8,0xd4,0xfd,0x4b,0xc0,0x0e,0x68,0x0d,0x19,0x26,0x87,0xa5,0xbf,0xe1,0x16 +.byte 0xf0,0x27,0x58,0xa8,0x3a,0xed,0x27,0x5b,0x73,0x4f,0x19,0x40,0x58,0x36,0xf6,0xfd,0x60,0x37,0x09,0x74,0x3c,0xb9,0x76,0x9a,0x32,0xfd,0x98,0x79,0x53,0xb3,0xea,0x3a,0x98,0x21,0xf9,0xb2,0x97,0xe4,0x00,0xb6,0xed,0x67,0xc4,0x76,0x8f,0x1e,0x4d,0xc8,0x2e,0xf4,0x54,0xd9,0x09,0xd7,0xcb,0xa0,0x91,0x1e,0x5a,0x60,0x53,0xbc,0x3e,0x35 +.byte 0x69,0xa6,0xca,0xf3,0xce,0x41,0x84,0x71,0xee,0xf3,0x75,0xd4,0x7a,0x71,0x36,0x62,0xe3,0x08,0xae,0x40,0x05,0xde,0x01,0x34,0x92,0x5f,0x71,0xa9,0x08,0xb3,0x43,0xcd,0xe7,0x2f,0x42,0x7e,0x9c,0x1e,0xfe,0x9a,0x40,0x99,0x58,0x31,0xd9,0x8d,0x5d,0xda,0x75,0x14,0x3f,0xae,0x45,0x27,0x85,0x47,0x7d,0x41,0x0e,0x94,0x20,0xee,0x11,0xd0 +.byte 0x1e,0xcd,0x00,0x56,0xb7,0x59,0xe6,0x58,0xab,0x2c,0xa6,0x44,0x14,0x8c,0xff,0x49,0x7b,0xe5,0xf7,0x93,0xd5,0x78,0x1a,0xe0,0x16,0xd8,0x24,0x08,0x1e,0x70,0xce,0x1a,0x84,0x87,0x6b,0xe5,0xf2,0x43,0x5f,0xb3,0x34,0xaa,0x85,0x3e,0x9e,0x2e,0x86,0x22,0x74,0xe2,0x1a,0x87,0xfb,0x1b,0x6c,0x08,0x8c,0x43,0xb4,0x85,0x75,0x2c,0x13,0xc2 +.byte 0x18,0x94,0xe8,0x0d,0x09,0xd5,0x8f,0xd4,0xca,0x50,0x93,0x9f,0xa3,0x9f,0x3b,0x3c,0x54,0x68,0xa9,0xb1,0xdd,0x0a,0x0b,0xe2,0x15,0x92,0x9c,0x6f,0xfa,0x45,0x6f,0x0a,0xb4,0x6b,0xcb,0xdc,0xa4,0xf3,0xf0,0xa6,0x1c,0x8a,0x60,0x42,0x35,0xa8,0xe3,0xdf,0xc8,0xdc,0xbb,0xbe,0x95,0xa7,0xac,0x08,0x08,0xbc,0x56,0x1a,0xa4,0xc2,0xd2,0x53 +.byte 0xfa,0xb2,0x89,0x4f,0xb8,0xe4,0xb9,0x90,0x95,0x91,0x2f,0x0f,0x93,0xa9,0x8c,0xc6,0xf8,0x01,0x34,0x08,0xe6,0x8c,0x58,0x43,0x57,0x40,0xf9,0x78,0x83,0xea,0x92,0x70,0xa8,0xa5,0xc8,0x9e,0xf8,0xc6,0x39,0x4c,0xb4,0xe9,0xbb,0xdf,0xd2,0x52,0x43,0x6b,0x6c,0x8b,0x2c,0x47,0xd7,0x11,0x42,0x3d,0xc7,0x3f,0xce,0xd1,0xd9,0x28,0x5b,0xce +.byte 0xec,0xb6,0x31,0x3a,0xc9,0xad,0x0c,0x93,0x82,0x2b,0xf6,0xdc,0xd4,0xcd,0x80,0xe1,0x75,0x45,0xeb,0x3b,0xbf,0x12,0x42,0xeb,0x71,0xc1,0x8b,0x27,0xd5,0xcb,0xd9,0xb6,0xe8,0xe9,0xc6,0x79,0xff,0x38,0x88,0x87,0x72,0xf2,0x71,0x4a,0x44,0x55,0x0f,0x9c,0x93,0xcf,0x15,0x18,0x44,0x62,0x2a,0xc5,0x0a,0x80,0x69,0x91,0x6e,0x4b,0x30,0x4e +.byte 0x3f,0x2f,0xb5,0x65,0x9e,0x65,0x07,0x36,0x9b,0xba,0x5f,0x81,0xd9,0x60,0xbe,0x1f,0xf5,0x98,0x20,0xf9,0x9e,0x53,0xf7,0x5d,0x57,0x7f,0x22,0xaf,0x8e,0x82,0x9e,0x0f,0x33,0x74,0x37,0x26,0x61,0x67,0xf6,0xfd,0x2c,0xab,0xd8,0x18,0x1d,0x10,0x48,0x7a,0x1d,0xed,0xbb,0x57,0x83,0xf9,0x82,0xf5,0xe3,0xf9,0x98,0x5c,0xc0,0x3e,0xee,0x38 +.byte 0x0a,0x57,0x10,0x22,0xc4,0xe8,0x1d,0xe3,0x46,0xa3,0x81,0x5e,0x92,0xba,0xcc,0x53,0x48,0x85,0x33,0x58,0xa2,0x3e,0xea,0x0a,0xfb,0x72,0x5c,0xcd,0xd9,0xa4,0x3f,0x56,0x99,0x35,0x92,0x6c,0xe8,0xf2,0x59,0x0f,0xc8,0x6a,0x21,0xb2,0x9f,0xa2,0xf6,0xf3,0x1b,0xec,0x38,0x95,0xed,0xef,0x00,0x09,0x16,0x6e,0xf7,0xf8,0x1a,0xef,0x0d,0x2b +.byte 0xef,0x83,0x8a,0xc2,0x22,0x3d,0x50,0xa3,0x70,0x52,0xe8,0xad,0x11,0x44,0x83,0x80,0xfe,0x88,0x7e,0x40,0x02,0x8f,0x4a,0x5d,0xd3,0x28,0x66,0x75,0x5a,0xf2,0x38,0xb5,0xdc,0x54,0xa8,0xb3,0xaa,0x76,0xdb,0x73,0xe0,0xd1,0xd7,0x51,0x20,0x8c,0x38,0x18,0x46,0x25,0x2e,0x0d,0x5b,0x61,0x9d,0x36,0x9a,0x14,0xfb,0xc8,0x4e,0x5a,0xba,0xa1 +.byte 0x98,0x34,0xfd,0x05,0x2c,0x87,0x58,0x8d,0xe3,0x5d,0x79,0x5a,0x45,0xff,0x75,0x25,0x98,0xbd,0xe4,0x9d,0x1a,0x70,0x79,0xaa,0x44,0x1a,0x10,0x7f,0xfb,0xe9,0x30,0x81,0xc7,0xa2,0x81,0x41,0x49,0x41,0x4e,0x42,0x5f,0x8a,0x9b,0x10,0xe2,0xdc,0xd9,0xdf,0xbd,0x61,0x29,0x72,0xa5,0x39,0xb7,0xf6,0x9f,0x4e,0x98,0xb8,0x04,0xae,0xd7,0xda +.byte 0x9a,0x9f,0x08,0xb8,0x2c,0x40,0x14,0x6d,0x01,0xb7,0x86,0x58,0x55,0x42,0xe5,0xdb,0x5f,0x4a,0xef,0xd8,0xed,0xdf,0x3b,0x24,0x1c,0xe4,0xb1,0x73,0xd1,0xce,0x29,0x96,0xde,0x8e,0xf3,0x1d,0x8d,0x75,0x57,0xd3,0x9a,0xf8,0xff,0x1a,0x4c,0x0c,0x47,0x82,0x83,0x73,0x34,0x43,0x55,0xfa,0xf2,0xd4,0x38,0xed,0xde,0x6d,0x24,0x55,0x90,0x06 +.byte 0xd6,0x03,0x52,0x28,0xc7,0x38,0x4a,0x16,0x95,0x4d,0xf4,0x46,0x56,0xf7,0x63,0x1f,0xe4,0xa9,0x51,0xc6,0x0b,0x85,0x42,0x40,0x8e,0x49,0x1e,0xc2,0xab,0xeb,0xda,0x99,0x26,0xf6,0x6e,0x00,0x8f,0x26,0x82,0xef,0x03,0xb0,0xd4,0xdb,0x54,0x46,0xdf,0xdc,0x23,0xaf,0xa8,0x6a,0x9f,0xb7,0xf9,0x41,0x07,0x5e,0x2d,0xcf,0x85,0xfd,0x9c,0x46 +.byte 0x30,0xb9,0x14,0xca,0xe2,0x30,0x12,0x06,0x88,0x08,0x05,0x2c,0x9a,0x4b,0x52,0x98,0xa9,0x99,0xd7,0xca,0xb5,0x1e,0x60,0x44,0xd9,0x5c,0x19,0x42,0xbe,0xa5,0x04,0xfd,0x7a,0xfc,0xb9,0xdf,0xd6,0xe3,0x6d,0x02,0xe3,0x96,0xf6,0xae,0xf3,0x78,0x1d,0x90,0x6d,0x86,0x17,0xf7,0xb7,0x6b,0x1d,0x52,0x32,0x5b,0xc0,0x31,0xaf,0x09,0x90,0x5e +.byte 0x81,0x75,0x17,0x47,0x6b,0x5e,0x9a,0x40,0xa5,0xa8,0x84,0x60,0xdc,0xdb,0xd2,0x89,0xcd,0xb2,0x72,0xf4,0x74,0xda,0x5d,0x34,0xf8,0xc6,0x1b,0x26,0x3e,0x8b,0xc7,0x73,0xf9,0x0c,0x93,0xf4,0x40,0x02,0xe0,0xed,0xe5,0xa0,0xae,0x91,0x03,0x85,0xa8,0x2f,0xe2,0x72,0xfe,0x17,0x7d,0x2b,0xa6,0x39,0x10,0x80,0x4c,0x58,0xaa,0xd8,0x22,0x7d +.byte 0x2f,0xbf,0x0c,0x40,0x48,0xfa,0xbe,0x40,0x4c,0x32,0x96,0x69,0xa5,0xab,0x0b,0x1e,0x33,0x9b,0xcf,0xe6,0x4e,0x2b,0x41,0x5a,0x21,0x23,0xa1,0xbb,0xd3,0xd6,0xd1,0xfd,0xbd,0x55,0xfc,0x92,0x92,0xcb,0x4b,0x72,0x39,0x8b,0xeb,0x72,0xdd,0xf7,0x77,0x43,0x52,0x2f,0x99,0x14,0x6e,0x41,0xce,0x1d,0x57,0x2c,0x09,0xd2,0x18,0xec,0x1b,0x89 +.byte 0xa0,0xe9,0xfe,0x1e,0x41,0xda,0x0f,0x76,0x02,0x38,0xec,0x9a,0x30,0xb7,0x5a,0x54,0x70,0xbc,0xe8,0xfa,0x06,0xd0,0x80,0xfb,0x27,0xd2,0xd8,0x00,0x80,0x65,0x9d,0x23,0xfd,0xad,0x26,0xb8,0xdc,0x09,0x4f,0xfb,0x52,0xcd,0xe4,0x41,0x68,0xca,0xdd,0xbc,0x2a,0x62,0xeb,0xa6,0x32,0x71,0xb0,0x08,0xb6,0x9f,0x3e,0x74,0xfe,0xb0,0xd4,0x9d +.byte 0x9e,0x6c,0x50,0x96,0x8a,0xde,0xd6,0xe9,0xde,0x2c,0xa6,0xf0,0x9f,0x67,0x00,0x50,0x0a,0x8c,0xe5,0xc2,0x37,0xcc,0xf0,0x53,0xeb,0x72,0xf2,0x87,0x77,0xee,0x80,0xe8,0xb2,0xa1,0x13,0x52,0x70,0xe6,0x8f,0x70,0x17,0x90,0x60,0xcb,0xac,0xb2,0x72,0xef,0xd9,0xb5,0xc3,0x68,0x57,0xdf,0x2d,0xcb,0x5a,0x35,0xf9,0x2e,0xfb,0xef,0x6e,0x77 +.byte 0x5d,0x21,0x37,0x4b,0x36,0x9b,0x3f,0x03,0x65,0xc9,0x84,0xb1,0x12,0x99,0xd1,0x6b,0x00,0x71,0x37,0xc7,0x57,0x82,0x44,0x7f,0xe1,0x81,0x24,0x70,0x96,0xd5,0x27,0xba,0x36,0xf7,0x25,0xc6,0x1c,0x7c,0x1b,0xdb,0xa3,0x6a,0x3e,0xb9,0x69,0x78,0xf7,0x51,0x46,0xe2,0x74,0xd3,0xfc,0xef,0x58,0x63,0x53,0x1d,0xd7,0xd0,0x8a,0x6a,0xd3,0xb0 +.byte 0xb9,0xbb,0xba,0x43,0xbf,0x8b,0x6b,0x04,0xd2,0xb1,0xe8,0xd1,0x72,0x3f,0xdc,0x2b,0x01,0xa6,0x2f,0x9c,0x7d,0x65,0xa1,0x9f,0x9b,0x4d,0x70,0x26,0x11,0x4c,0xb2,0xe1,0x01,0x0e,0x78,0xf2,0x32,0x87,0x2d,0x8e,0x95,0x02,0x76,0xca,0xe5,0x71,0x5f,0x36,0x35,0xb9,0xbb,0xc3,0xdf,0xf3,0x1e,0x1a,0x7a,0xe4,0x2c,0xdf,0x64,0x5d,0x96,0x12 +.byte 0xea,0x5c,0x14,0x73,0xa0,0xf1,0xbc,0xa9,0x6e,0x30,0x8a,0x47,0xf0,0x4b,0x9b,0x4c,0xc5,0xb0,0xbe,0x15,0x32,0x1b,0xde,0x0c,0x39,0x6a,0x6d,0x4e,0x3b,0x69,0x4c,0xb4,0x1f,0x56,0xf0,0xa1,0xb1,0x8c,0x29,0x5c,0x87,0x54,0xf2,0x5b,0x51,0x03,0x20,0x70,0x90,0x38,0x66,0x07,0xcc,0xd7,0xde,0x96,0x40,0x82,0xee,0xb5,0x87,0x2a,0x86,0xec +.byte 0x66,0x09,0xb7,0x4a,0xfe,0x4e,0x92,0x89,0x07,0xde,0x35,0xc4,0x6e,0x91,0x25,0xfd,0x18,0xfa,0xd9,0x8f,0xa7,0xa6,0xa7,0x6b,0x32,0xba,0xd3,0x1c,0x90,0xb9,0x8a,0x6c,0x9f,0x3f,0xb5,0x16,0x81,0x81,0xee,0xd7,0x55,0xc1,0x41,0x62,0xfd,0xe9,0x4c,0x5d,0xd7,0x70,0xdd,0xc6,0x4a,0x2b,0x42,0x77,0xe7,0x74,0xed,0x02,0x80,0x0d,0x7c,0x73 +.byte 0x8e,0xf0,0xd3,0xb0,0x20,0xbb,0xc8,0x82,0x06,0xdd,0x56,0x64,0xcb,0x9c,0xda,0xa1,0xa9,0x92,0xbc,0x8c,0x65,0x03,0xcd,0x68,0x87,0xa2,0x94,0x41,0x3c,0x36,0x96,0x1f,0xa4,0xd2,0x6d,0x5d,0x9f,0x2d,0x0c,0xf9,0x8a,0x82,0x19,0x93,0x47,0x62,0x71,0x8e,0x59,0xaa,0xf1,0x87,0xe0,0xb8,0xab,0x10,0x7f,0x4e,0xa8,0xa3,0xe2,0x32,0x58,0xb0 +.byte 0xcf,0x12,0xc0,0xf8,0x94,0x4a,0x61,0x36,0xdc,0x2d,0xb5,0x91,0xf9,0x0f,0x7d,0x91,0xd3,0xc7,0x03,0x8a,0xae,0x5c,0x22,0x8c,0x60,0x30,0xf4,0x71,0x51,0x00,0xf5,0x5d,0xe9,0x37,0x6c,0xae,0x64,0xff,0x45,0x35,0x4b,0x47,0x08,0xca,0xda,0x7b,0xe9,0xef,0xcb,0x27,0xcb,0x7e,0x3c,0xa6,0xd2,0x38,0x54,0x74,0xc3,0x7c,0xf8,0x71,0xb7,0x47 +.byte 0xe9,0xe0,0x43,0x03,0x3b,0x41,0x57,0xc3,0xda,0xa1,0xcb,0x64,0xb1,0x31,0x0d,0x12,0x45,0x3a,0xa0,0xad,0x6b,0xc7,0x26,0x62,0x50,0xcf,0x94,0x5a,0x30,0x8d,0xf6,0x91,0x49,0x9e,0xd5,0x84,0x0e,0x0c,0xe3,0x47,0x08,0x7f,0xa1,0x54,0x78,0x1b,0xa8,0x2c,0xbc,0x12,0x4f,0x7e,0x53,0x1b,0xca,0xfb,0x09,0x35,0xe0,0x9c,0x15,0xea,0xf6,0x3e +.byte 0xb2,0x20,0x9e,0x2c,0x81,0x6f,0xa4,0xb5,0x6b,0x04,0x6d,0xd1,0x90,0x66,0x46,0xdc,0x4b,0x71,0x7e,0x4b,0x3f,0xd6,0xe1,0xa8,0xc0,0xa7,0x45,0x85,0xe3,0x98,0x30,0xda,0x23,0x68,0x55,0xd8,0x96,0xb1,0xcc,0xeb,0xe1,0x95,0x0b,0x20,0xf3,0x4c,0xf2,0xc5,0xfa,0x0e,0xca,0xf5,0xc9,0xb3,0xd7,0xb4,0x1b,0x9f,0xef,0x82,0x56,0x4c,0xc5,0xa5 +.byte 0x21,0xda,0xcc,0x19,0x69,0x68,0xcb,0x37,0xb2,0x0c,0x73,0xb1,0x13,0x61,0x6b,0xca,0xda,0xfc,0xf7,0x1c,0xbc,0xd1,0x72,0x56,0xb8,0x7d,0xa1,0xef,0xc4,0x32,0x38,0xa3,0xdb,0x8b,0x2d,0x0a,0xce,0xcb,0x86,0x51,0x60,0xd2,0x47,0xf0,0x97,0x58,0xd8,0xa5,0x12,0x77,0xfc,0x32,0x04,0x29,0x61,0xfc,0xab,0xc2,0x42,0x86,0xd9,0x57,0x80,0xad +.byte 0x00,0xf0,0x9a,0x2a,0xac,0x52,0x27,0xd6,0xf8,0xd6,0x38,0xc8,0xfc,0xc1,0xab,0x4f,0x41,0xbf,0x8e,0x60,0x20,0xeb,0x24,0x36,0xd8,0xd8,0x25,0x6f,0xc8,0x5d,0x6b,0x00,0xdd,0x7a,0xe2,0x37,0xe4,0x13,0xd0,0xaa,0x5c,0x56,0x32,0x98,0x00,0x4b,0x8a,0x81,0xb1,0xfa,0xe8,0xf3,0xfa,0x0d,0xbb,0x66,0x6e,0x24,0xfd,0x3c,0x50,0x63,0x3a,0xf1 +.byte 0x72,0x63,0x18,0x71,0x6d,0xee,0x6f,0xf1,0x0e,0x1f,0x9e,0x9d,0x87,0x12,0x5c,0xdf,0x1d,0x9e,0xc0,0x0b,0x39,0x0e,0xd6,0x56,0x79,0x30,0xcb,0x07,0x7b,0x88,0xa5,0xbe,0xfd,0xd4,0x49,0xcc,0x92,0x6a,0xcc,0x78,0x1e,0xaf,0xee,0x89,0xc8,0x51,0x08,0x98,0x14,0x20,0xe5,0x52,0x93,0x18,0x6f,0xbb,0xdc,0xb2,0x68,0x14,0xd1,0xdb,0xe8,0x56 +.byte 0x24,0xd0,0x34,0xab,0xa6,0xfa,0xfe,0x72,0x5a,0xe3,0xe1,0x87,0x0d,0xf4,0xfa,0xa6,0xa6,0x6c,0xb6,0xcb,0xf8,0xfc,0x59,0xac,0xd9,0xb0,0xcd,0x15,0xa4,0x37,0x73,0x6e,0x70,0xc9,0x74,0xef,0x87,0x78,0x61,0xc2,0xd0,0x52,0x51,0xa9,0x2c,0xdb,0x9d,0xd9,0x3d,0xac,0xcd,0x52,0x39,0x69,0x2d,0x2a,0x4f,0xf3,0xb2,0x69,0xb9,0x01,0x3c,0x57 +.byte 0xeb,0x1b,0x0e,0x87,0xe9,0x42,0x58,0x83,0x6b,0xbc,0x72,0xc8,0x46,0x32,0x42,0x17,0x6a,0x19,0xa0,0xb3,0xf1,0x1c,0x96,0x9c,0x11,0x09,0x8b,0xc1,0x9e,0xe9,0x7f,0x18,0x8e,0xca,0xea,0x24,0x1b,0xce,0x12,0x57,0x1d,0x34,0xbe,0x60,0x60,0x2c,0xd8,0xa0,0x61,0x73,0xd6,0xf8,0xaf,0x15,0x26,0x84,0xd7,0xec,0xc0,0xbe,0x7e,0xa1,0xa8,0xba +.byte 0x2b,0xcc,0x20,0x67,0x6e,0xea,0x48,0x79,0x23,0xea,0x14,0x36,0x85,0x0a,0x56,0x3a,0xcd,0x5b,0x51,0xa4,0xf5,0x92,0x49,0xc2,0x55,0x62,0xed,0x88,0xde,0xd0,0x0c,0x01,0x36,0xb9,0x2e,0x94,0x80,0x75,0x8a,0x21,0x0a,0x07,0x45,0x68,0xd8,0x9d,0x49,0x7b,0xa7,0xb2,0x84,0xfa,0x3c,0xc4,0xd5,0x59,0xf9,0xc3,0xff,0xcf,0xe4,0x5f,0xea,0xbb +.byte 0x0f,0xae,0x7d,0x96,0xd3,0xe9,0x38,0xd1,0xb1,0x02,0xf6,0x4b,0x95,0x43,0x1c,0x69,0xa6,0x99,0xf5,0xdb,0x46,0x62,0xea,0x69,0x5a,0x08,0x2d,0x01,0x11,0xed,0x70,0x03,0x60,0x54,0xba,0x32,0x2c,0x0e,0x44,0x1f,0x8d,0xee,0x2e,0x39,0xab,0xc0,0xd4,0x88,0x11,0xef,0x07,0x3a,0x47,0xb9,0x6e,0x0c,0x22,0x9a,0xf3,0x89,0x01,0xfb,0xb8,0x2d +.byte 0x52,0xa0,0x42,0x4c,0xb3,0x9e,0xf5,0x4b,0x0c,0x78,0x0a,0x3b,0x29,0xae,0x4a,0xc0,0xb2,0xa3,0xc0,0x0d,0x38,0x07,0x49,0x9c,0xda,0x7c,0x48,0x81,0xba,0x53,0x0d,0x0d,0x78,0x8c,0xac,0x9b,0x3d,0x1f,0xaa,0xc1,0x32,0x54,0xca,0x54,0xe1,0xef,0x46,0x82,0x61,0xd0,0x88,0x04,0x53,0xb0,0x34,0xc2,0x23,0x9a,0x90,0xe3,0x73,0x9c,0x0d,0x46 +.byte 0x61,0xe5,0xc0,0x42,0x87,0x4a,0x3b,0x3a,0xf9,0xab,0xbe,0x4c,0xba,0x2f,0x88,0x03,0x6b,0x52,0x25,0x8c,0x9b,0xc0,0x13,0xb6,0x80,0x09,0x85,0x97,0x64,0x6d,0x65,0xcd,0x18,0x42,0x00,0xdf,0x76,0x4d,0x67,0xbf,0x04,0x7a,0x5f,0x7e,0x3a,0x5c,0x6f,0x1d,0x12,0x5b,0xbe,0xd2,0xc8,0xe5,0x09,0x45,0x4d,0xae,0xed,0xd8,0x77,0xc5,0x6f,0xb6 +.byte 0x43,0x09,0xe2,0xee,0xc9,0x5a,0x76,0xc5,0xeb,0xdd,0x96,0x23,0xb9,0xe5,0xfc,0xf2,0x3c,0xe1,0x67,0x5f,0x1b,0x10,0x39,0x47,0x67,0x8b,0x48,0x32,0xd0,0xbc,0xa0,0xa8,0x3e,0xc3,0x30,0x21,0x18,0x54,0x49,0xfe,0x8a,0x14,0x7a,0xe5,0x6e,0xbe,0x70,0xec,0xf6,0x97,0xa0,0xa4,0xf4,0xdd,0xaf,0xf2,0xde,0x50,0x1a,0x68,0xb9,0x1a,0x4b,0x37 +.byte 0xf8,0x29,0x16,0x4f,0x8c,0xa5,0x9e,0xd2,0x72,0x7f,0xf6,0x6b,0x7d,0xac,0xe4,0x17,0x93,0x39,0x8f,0xd9,0xdf,0x50,0x1f,0xce,0xf5,0x58,0xdd,0xcd,0xc2,0xb9,0x64,0xfc,0xad,0x8a,0x3c,0x2e,0x52,0x58,0x91,0x3b,0x78,0xb4,0xfd,0x4a,0x3b,0x13,0x5d,0x20,0xd5,0xdf,0xe7,0x52,0x3d,0x4c,0x2f,0x02,0x30,0xfc,0x24,0x17,0x99,0x6e,0x4b,0xfe +.byte 0x1d,0xf0,0xe6,0x86,0x32,0x37,0xb5,0xd5,0x09,0xa3,0xa5,0x3b,0xc1,0x88,0x9f,0x01,0x57,0x12,0x03,0x1d,0x60,0xd8,0x57,0xba,0xc6,0xfc,0xda,0xab,0x02,0xbe,0xab,0x89,0xf9,0x08,0x63,0xbd,0x42,0x11,0xf7,0xbf,0xd3,0x45,0x2b,0xa5,0x34,0x91,0x18,0xb9,0xb3,0x79,0xb4,0x15,0xa1,0x01,0x1a,0xf9,0x74,0x91,0x08,0x94,0xb2,0xf3,0xb2,0xca +.byte 0x0a,0x3a,0x4f,0x42,0x8a,0x16,0xf7,0x9e,0xbf,0x27,0x72,0x7b,0xff,0xd3,0xb9,0x4e,0xf5,0x8e,0x68,0xb5,0x91,0x23,0xef,0xeb,0x5d,0x7d,0xd8,0xc9,0xda,0x07,0x33,0xc9,0x1c,0x4a,0x7a,0xf2,0x72,0x64,0xb3,0x35,0x2e,0x54,0xec,0xc4,0xd9,0xee,0xea,0xda,0xfe,0x8b,0x1c,0x21,0x93,0x52,0x95,0x7c,0x2d,0xfe,0x56,0x05,0xdd,0x57,0x37,0xf2 +.byte 0x54,0x1c,0xe2,0x6c,0xc0,0xaa,0x71,0x67,0xdd,0x73,0x43,0x17,0x3e,0x76,0xdb,0x60,0xb4,0x66,0x62,0xc7,0x74,0x08,0x91,0x1f,0xd5,0x4c,0xa9,0xd0,0x34,0x33,0xea,0xb0,0x2c,0x0a,0x88,0xda,0xf7,0xca,0x91,0xf6,0x5f,0x9e,0x72,0xf6,0x18,0xf9,0x19,0x9d,0x84,0xf8,0x4c,0xe1,0xeb,0x45,0x29,0xaa,0xf2,0xa6,0xfd,0x64,0xf9,0x0b,0xfe,0x09 +.byte 0x1c,0xc2,0xde,0x19,0xdd,0x0f,0x02,0x16,0x65,0x70,0x33,0xd4,0x32,0x67,0x7b,0xc4,0xbb,0x11,0x60,0x4f,0xc3,0x4d,0x29,0x23,0x7e,0x84,0x58,0x51,0x43,0x7e,0x25,0x4f,0x3d,0xd4,0xe0,0x20,0x79,0xfd,0xce,0x59,0x49,0xf8,0xd1,0x53,0xca,0x2d,0x66,0xec,0xe5,0x7f,0xc8,0x14,0x06,0xc1,0x96,0x40,0xf2,0x61,0xa7,0x1b,0xf9,0x5e,0x97,0xfe +.byte 0x62,0x57,0x05,0xcc,0x6f,0x26,0x4b,0xa6,0x40,0x33,0x72,0x20,0xd3,0x1e,0x2b,0xb2,0x60,0xe7,0x56,0xda,0x87,0xd3,0xb4,0x5a,0x73,0x04,0xc9,0xc2,0x68,0xe3,0x18,0x74,0xd9,0x46,0x74,0x31,0xf4,0xf4,0xab,0xc4,0x0a,0xbc,0x66,0x4e,0x23,0x5f,0x92,0x7c,0x0a,0x81,0xdd,0xcc,0x79,0xee,0xb3,0x3d,0xc0,0x91,0x81,0xd0,0x79,0x39,0xd2,0x69 +.byte 0x5d,0xdc,0xc1,0x5c,0x61,0xb9,0x5e,0x87,0x32,0x73,0x70,0xd0,0xa8,0x7d,0xb5,0xd0,0xfc,0xf4,0xb6,0x55,0x9f,0x1f,0x8a,0xec,0xf4,0xb0,0x47,0xeb,0x3b,0x68,0x80,0x0b,0x79,0xd0,0x71,0x99,0xb1,0xd0,0xed,0x1f,0x9f,0x6c,0x2d,0x9d,0xae,0x1c,0x62,0x3b,0xec,0x3e,0x2f,0xb4,0x6f,0xbb,0x2e,0x1e,0xa9,0x7c,0xe8,0x5d,0x14,0x7d,0x0d,0x17 +.byte 0x6d,0x9c,0x54,0xce,0x64,0x93,0x8e,0x3b,0xa4,0xa9,0xfb,0xd9,0x44,0x06,0xbb,0xb8,0x7f,0xdf,0xd3,0xc2,0xa2,0xcf,0x5a,0xa2,0xa7,0xbb,0xb5,0x08,0xe2,0x67,0xdf,0x0e,0x4e,0xc6,0xcf,0x0a,0x79,0x1e,0xa5,0x60,0x1a,0x81,0xb1,0x8e,0x1b,0x27,0x7f,0x8d,0x28,0x50,0xa7,0x4a,0xe4,0x4b,0x61,0x6b,0xa9,0xfa,0xaf,0x82,0x83,0xfb,0x1f,0x2e +.byte 0xfa,0xce,0x18,0x0e,0x32,0x5f,0x5a,0xcf,0xac,0xaf,0x22,0x30,0x16,0xd7,0x97,0x99,0x0d,0xb8,0x92,0xa5,0x1d,0x44,0xb2,0xa5,0xc7,0x74,0xd2,0x81,0x8d,0x5c,0x38,0xda,0x9f,0x76,0xcb,0x47,0x6c,0xb7,0x08,0xd9,0xc1,0x52,0xd0,0x64,0x0a,0xf9,0xdd,0x3e,0xe8,0x99,0x15,0x4d,0xcb,0x7b,0x25,0x53,0x8c,0x13,0xb1,0xbf,0xb7,0xca,0x2d,0xce +.byte 0x71,0x48,0xee,0x5b,0x3a,0x01,0x5b,0xfd,0x22,0xfa,0x6f,0x17,0xcb,0x52,0xcc,0x0a,0x2b,0xbb,0x6d,0xce,0x2d,0x00,0xf5,0x9e,0x0d,0x58,0xf1,0xf4,0xa4,0x9f,0x13,0xf9,0x68,0x15,0xd7,0x02,0x41,0x6c,0x19,0x6b,0x66,0x9a,0x74,0xee,0xb4,0xb3,0xc7,0xec,0x60,0x19,0xbd,0xbb,0x97,0x22,0x7c,0x4e,0xe6,0xc6,0x00,0x03,0xa5,0x36,0x52,0xec +.byte 0x21,0xcf,0xc8,0xda,0x2c,0x14,0xa9,0xd8,0x75,0xab,0xea,0x05,0x8c,0x24,0x28,0x63,0xbd,0x58,0x35,0xd7,0x95,0xcb,0x14,0x89,0x04,0x99,0x7e,0x67,0x0d,0x07,0x35,0xdb,0x17,0x7c,0x72,0x2d,0xbc,0x89,0x9b,0xb4,0x16,0x21,0x2f,0x90,0xe8,0x8f,0xeb,0xc3,0x8d,0x86,0x0d,0x92,0xf6,0x4b,0x80,0x36,0x96,0x6b,0xd8,0x95,0x7b,0xad,0xe8,0xbf +.byte 0x77,0x9e,0xf4,0x93,0xcd,0xa5,0x06,0xbc,0x38,0xf2,0x57,0x25,0x54,0xfa,0x8e,0x19,0x8e,0x25,0x8e,0x3c,0x28,0xaa,0xf2,0x02,0x30,0xd4,0x47,0x89,0x36,0xb9,0xb7,0x01,0x5f,0x0c,0xd1,0x8d,0x93,0x7e,0xf0,0xf0,0xff,0x2f,0x8f,0xb5,0x97,0xa7,0x02,0xe8,0x9b,0xf2,0x51,0xe6,0x51,0x62,0xa5,0x27,0x26,0xc6,0x7a,0x39,0x7a,0xa9,0xaf,0x1e +.byte 0x03,0xd5,0x25,0xbe,0x3b,0x19,0x46,0xc4,0xdd,0xd6,0x5e,0x6a,0x18,0xc0,0x41,0x5f,0x53,0x89,0xd3,0x16,0xfb,0x3a,0x10,0xce,0x0d,0x8c,0x04,0x4c,0xcf,0xab,0xb9,0x0d,0x6c,0x45,0x6c,0x29,0xed,0x77,0x37,0x1f,0xd8,0x10,0x8a,0xfe,0x07,0xbd,0x7e,0xd7,0xa6,0x6b,0x80,0xde,0x3e,0x2c,0xa8,0xb1,0x38,0xcc,0xab,0x10,0x69,0x8f,0x58,0x3d +.byte 0x12,0xc7,0x9c,0xc1,0x0a,0xeb,0x3d,0x5e,0xf1,0x65,0xc6,0x09,0xcb,0x4b,0x09,0x24,0xa7,0x56,0x1d,0x1d,0x4c,0xd7,0x06,0xbd,0xe2,0x72,0x70,0xae,0x7e,0xe9,0xaa,0x97,0x6d,0xec,0xcb,0x55,0x0b,0x5d,0x45,0x3a,0x25,0x3d,0x52,0x0f,0x48,0x2f,0xe4,0xd0,0x5e,0x85,0x87,0xb6,0xa7,0x70,0x2f,0x9c,0x19,0x89,0x95,0x45,0x76,0x00,0xfe,0x27 +.byte 0xff,0xf8,0x73,0x59,0xba,0x98,0x92,0x4e,0x76,0x1a,0x90,0x1d,0xbc,0x1b,0xae,0x44,0xb6,0x63,0x86,0x4c,0x3c,0x8a,0x8f,0x3e,0x03,0x95,0x50,0x30,0xd8,0x0f,0x7f,0x6f,0xb6,0xe9,0xbe,0x2e,0xc9,0x55,0xe7,0x73,0xd6,0x77,0xdc,0xbc,0x67,0x54,0x31,0x47,0x30,0x46,0xe1,0xa4,0xf8,0xf3,0x90,0x4f,0x68,0x5a,0x52,0xe2,0xe7,0xdb,0xd9,0xfd +.byte 0xf6,0x36,0x2a,0xc1,0xdb,0x35,0x82,0x69,0xff,0xf9,0xea,0x53,0xff,0xcd,0x21,0x2c,0x26,0x79,0xd6,0x8c,0x74,0xe7,0x9e,0x85,0x1a,0x04,0xf5,0xed,0x89,0x16,0xf5,0xd7,0xf1,0x89,0xf1,0xb3,0x5b,0x47,0x42,0xcb,0x92,0x2e,0x70,0xf6,0x3e,0xfc,0x20,0x87,0x70,0xec,0x30,0x16,0xcc,0x88,0x64,0x13,0x58,0xf1,0x0d,0x17,0x90,0xc4,0xdb,0x07 +.byte 0xf5,0xe3,0x34,0x31,0x10,0x9c,0xa4,0x6a,0x4a,0xe6,0x6c,0x80,0x49,0x07,0x23,0x21,0xd6,0xf1,0xcb,0x4a,0xd1,0xb5,0xb7,0x63,0x94,0x4c,0x0a,0xce,0x90,0xf2,0x63,0x31,0x4f,0x96,0x6c,0x5d,0x3e,0xaa,0x10,0x20,0xd6,0xb6,0xbe,0xfa,0x3f,0x83,0xbc,0xa8,0x08,0x38,0xec,0x38,0xe4,0xe9,0xf5,0xb3,0x8e,0x32,0x31,0xcd,0x7c,0x08,0x98,0xf6 +.byte 0x0f,0x8a,0x8f,0xc1,0xd8,0x9e,0x05,0xb6,0x74,0x11,0x94,0xef,0x4f,0x8f,0xa1,0xc6,0x8c,0xdb,0xc3,0x27,0x4e,0xa3,0x30,0x94,0xf5,0xe8,0x2a,0x18,0x0a,0x51,0x9b,0x79,0xb2,0x1f,0xc3,0xa0,0x26,0xa9,0xf5,0xc4,0x9e,0x39,0xda,0x6a,0x53,0x8f,0x8c,0x4c,0x54,0x50,0x81,0xa0,0x0a,0xd3,0x7c,0x99,0x91,0xc7,0x3e,0x56,0x7d,0x53,0x8c,0x3c +.byte 0x51,0x44,0xa5,0x22,0x9d,0xd2,0x9b,0x13,0xcf,0xb8,0x0c,0xb8,0xd4,0xaa,0xb4,0xaa,0x8d,0xab,0x7c,0x06,0xca,0xbb,0x85,0xac,0x01,0xee,0xef,0xe7,0x74,0xd5,0x0d,0x64,0x91,0x1c,0xde,0x6c,0x05,0x37,0x1e,0x23,0x05,0x7e,0x38,0xdc,0x17,0xaf,0xa7,0x95,0x85,0x1f,0xaf,0xc8,0xe1,0xc2,0xda,0xda,0xf1,0x14,0x56,0x66,0x68,0x70,0x36,0x38 +.byte 0x7b,0xb8,0x22,0x9f,0xc4,0xeb,0x5d,0x76,0x97,0xc5,0xa3,0xb9,0x06,0x86,0x4f,0x20,0xab,0x7d,0xce,0x7d,0x78,0x59,0xc5,0x1f,0x73,0x81,0xf6,0x6d,0xb4,0xcc,0x10,0xc5,0x4d,0xe3,0x81,0xaf,0xbc,0x37,0x42,0x28,0x5f,0x51,0x1e,0xaa,0xc7,0x81,0x20,0xc3,0x89,0x35,0xf1,0x74,0x3a,0xe8,0x04,0x24,0xef,0x8b,0x70,0xe1,0x74,0xdf,0x87,0xd5 +.byte 0x3c,0x32,0x32,0x7d,0x03,0xd7,0xda,0x6d,0x8b,0x25,0x8d,0x11,0xa3,0xc2,0x27,0xdc,0xa3,0xfc,0xdf,0x70,0xa4,0x41,0xad,0xda,0xce,0x12,0x45,0x14,0xa1,0x96,0x16,0xd8,0x54,0x89,0x9e,0x78,0x7f,0x23,0x12,0xd1,0x15,0x08,0x7f,0xbd,0xf0,0x9a,0xf1,0x5b,0x07,0xd5,0xbc,0xab,0xab,0x15,0xae,0xda,0xf1,0x26,0x12,0x4e,0xd6,0x6c,0x35,0xc1 +.byte 0x6e,0x27,0x4d,0xa8,0x71,0x51,0x1e,0xae,0xa8,0x35,0x26,0x06,0x18,0x03,0xd8,0xae,0x9e,0x8b,0x07,0x30,0x10,0xfb,0x47,0x05,0x02,0xcc,0x0a,0xbd,0x57,0x43,0x15,0x0a,0x7a,0xb5,0x30,0x0b,0xa6,0x3c,0xa8,0xc9,0xf5,0x68,0xe1,0xfb,0xd1,0xe0,0xe7,0x44,0x6c,0xb4,0x44,0xb6,0xd1,0x2b,0x30,0x5e,0x17,0x89,0x40,0xcc,0x10,0x8f,0x97,0x8a +.byte 0xf3,0xf4,0x52,0x55,0xc4,0x8e,0x46,0xe5,0x24,0x0b,0x2a,0x5d,0x84,0xc1,0x4e,0xa8,0x5a,0x53,0xa8,0xce,0xc6,0x3f,0xa2,0xaa,0x3a,0x8f,0x51,0xed,0x4c,0xa6,0x34,0x6a,0x8c,0x18,0x9b,0x36,0x49,0x40,0x34,0xa3,0xe4,0xd8,0x3c,0x8a,0xfc,0x41,0xc9,0x35,0xfe,0x6e,0x3e,0x29,0xbc,0x04,0x61,0xaf,0x04,0x03,0x43,0x79,0xb5,0x77,0x27,0x25 +.byte 0xbe,0x85,0xc9,0x56,0xa4,0x17,0xc4,0x27,0x3d,0x53,0x1b,0x49,0x86,0xb2,0xb6,0x52,0x62,0x12,0x5d,0xe9,0x47,0x6f,0x65,0x78,0xf8,0x95,0x63,0xbc,0x73,0x6d,0xa6,0xb9,0xcd,0x17,0x39,0x56,0xb0,0xab,0x3a,0x15,0x5f,0x9a,0x98,0xfb,0xcd,0x51,0x4a,0x35,0x21,0xaf,0x07,0x4a,0x3d,0xfd,0x39,0x11,0x42,0xed,0xfc,0x7e,0x10,0x24,0xa5,0x0c +.byte 0xb2,0x4f,0x27,0xe4,0x78,0x32,0xfe,0xfc,0x8e,0x46,0x68,0xbb,0x2e,0x85,0x87,0x0f,0x01,0xde,0x1c,0x02,0xdd,0x82,0xa0,0x9e,0x30,0x31,0x8d,0x86,0x36,0x33,0xa6,0x59,0x16,0x78,0xae,0x1f,0x1d,0x27,0x0b,0x29,0x42,0x16,0x93,0x3b,0xe6,0xfb,0x8d,0xd5,0x48,0x42,0x61,0x39,0x5b,0xf7,0xea,0xd0,0x6f,0x67,0xd9,0x03,0x72,0xed,0x54,0xe1 +.byte 0xab,0x3f,0xa0,0xdc,0x4b,0x19,0xe6,0xe3,0xfe,0x5f,0x65,0x64,0x4c,0xa9,0x5c,0x52,0x36,0xb3,0x65,0x28,0x3e,0xe5,0x07,0x50,0xed,0xec,0x2f,0xc9,0xff,0x47,0x27,0xf6,0xfe,0xb8,0x60,0x60,0x52,0xe5,0xec,0x3c,0x4f,0x69,0x9f,0xaa,0x06,0x8a,0x99,0x9f,0xac,0xfc,0x0a,0x6f,0x8a,0xa4,0x0e,0x5c,0x58,0xb4,0x09,0xba,0x93,0x95,0x94,0x12 +.byte 0x9b,0x23,0x4f,0x93,0x28,0x6d,0xd0,0x76,0xfd,0xc9,0x87,0x3b,0xf1,0x8c,0x7d,0x56,0x84,0x5a,0x04,0x08,0x30,0xf7,0xf6,0x52,0x15,0xba,0xd6,0x7a,0x39,0x8c,0x5a,0xbf,0xeb,0x02,0x6d,0x31,0x30,0x92,0xbc,0xe2,0x07,0x21,0x16,0x96,0x70,0x66,0x00,0xe0,0x04,0xc5,0xa8,0xe4,0x08,0x6d,0x08,0x69,0x35,0xe2,0xb1,0x83,0x03,0x37,0xca,0xff +.byte 0x06,0x37,0x80,0xd5,0x1a,0xc5,0x31,0xfc,0x9a,0xb0,0x8a,0x4b,0x58,0xf3,0x00,0x4e,0xa4,0xfe,0x9e,0xe0,0x60,0xc7,0x3d,0x2c,0x52,0xb5,0x39,0xf0,0xa4,0x88,0x39,0x37,0xa5,0x26,0x8a,0xa3,0xe6,0x31,0xce,0xf3,0xa1,0x54,0x73,0xe7,0x69,0x38,0xef,0xa2,0xab,0x52,0x50,0x1a,0x45,0xcc,0x29,0x9c,0xb6,0xf4,0xde,0xc2,0xfe,0x7a,0x26,0xf7 +.byte 0x7a,0x6e,0x07,0xb6,0xd8,0x3f,0x77,0x60,0x35,0xae,0x6a,0x90,0xd6,0xb8,0x37,0xed,0x73,0x59,0x54,0xd9,0x0c,0x87,0x0e,0x81,0xef,0x69,0xc7,0xd4,0x8f,0x00,0x74,0x57,0x12,0xcf,0xa1,0x76,0xe8,0x45,0xf5,0x9a,0x4f,0xe2,0x5d,0x8a,0x89,0xb1,0x8b,0xea,0x9c,0x0a,0x1e,0x00,0x61,0x3b,0x66,0xbd,0xb5,0xd6,0xff,0xa3,0xff,0x52,0xc2,0x35 +.byte 0x81,0x05,0x08,0x2b,0xf9,0x52,0xda,0x74,0xd1,0x76,0x13,0xba,0x28,0x4c,0xb1,0xb1,0x82,0x5b,0x4e,0x79,0x39,0x22,0xf9,0x96,0x91,0x07,0x4f,0xf9,0xf2,0x25,0x25,0xb1,0x3e,0xda,0x07,0x5c,0x01,0x7b,0xfa,0x3e,0x95,0x92,0x1d,0xf8,0x44,0x06,0xc1,0xed,0x64,0x74,0x14,0x84,0x25,0xee,0x75,0xaf,0xe3,0x7c,0xd3,0xbe,0x7a,0x51,0x6b,0x80 +.byte 0x20,0x43,0x20,0x10,0x5f,0xf5,0xfc,0xd5,0xe8,0x06,0x43,0xad,0x10,0x6b,0x67,0x48,0xca,0xca,0x6e,0x3e,0x1c,0xdf,0x8f,0x7a,0x65,0xc8,0x5d,0xba,0x3b,0x67,0xeb,0x1f,0xc4,0x37,0xad,0xef,0x73,0x9e,0x18,0x8e,0xc1,0x99,0xaf,0x75,0xd3,0x91,0x73,0xc3,0x3a,0xb2,0xfe,0xff,0x30,0x81,0xc4,0x4f,0x37,0x37,0x23,0x96,0x17,0xf1,0xa2,0x9b +.byte 0x55,0x6e,0xd6,0xb3,0xc4,0x98,0xa3,0x32,0xb6,0xff,0x86,0x87,0x77,0xf4,0xad,0x16,0x3e,0xf0,0x24,0x01,0xb4,0x8e,0x1e,0x0f,0x10,0xa4,0x2e,0xe4,0x79,0xe6,0x88,0xe7,0x09,0x58,0x5e,0x97,0xad,0x0d,0x72,0x05,0xbf,0x2f,0x3f,0x99,0xee,0x8a,0x84,0xc3,0x62,0x43,0x52,0x6d,0xab,0x66,0xcf,0x9f,0x4e,0xf2,0x0d,0x13,0x15,0x49,0x84,0x5e +.byte 0x6c,0x8d,0x2d,0xef,0x53,0x16,0xa0,0x63,0xbe,0x05,0xb8,0x9b,0x23,0xca,0xca,0xb8,0xdd,0xbc,0x96,0x68,0x35,0x43,0x63,0x30,0x8e,0xaf,0x53,0x98,0xe2,0x76,0xe8,0x89,0x00,0x29,0x11,0x70,0xd5,0x94,0xbd,0x78,0xff,0xf6,0x88,0x4a,0x3d,0x99,0xd9,0x7e,0xdf,0xa8,0x33,0x92,0xa2,0xc0,0x32,0x42,0x73,0x08,0xd4,0x55,0x5d,0x18,0x93,0xca +.byte 0x7e,0x33,0xe3,0x51,0xc7,0xb7,0x24,0x62,0x69,0xf4,0xab,0x36,0xe3,0x22,0x10,0x9b,0xe0,0xbd,0x48,0x65,0x30,0x9c,0xfe,0xeb,0x3f,0x7f,0x22,0x67,0xcc,0x87,0x5a,0x71,0xb0,0xd1,0x19,0x82,0x1c,0xb2,0xf1,0x73,0xd2,0xd6,0x3f,0xef,0xe3,0x2f,0x25,0xf3,0x8b,0x21,0x4e,0xbf,0x0e,0xc1,0xd2,0x8a,0xbb,0x04,0xde,0xcf,0xd1,0x77,0xba,0xaa +.byte 0xc7,0x41,0x68,0xce,0xc4,0x64,0xf9,0x3a,0x2f,0x1c,0x0b,0x22,0xf8,0x60,0x09,0x76,0x31,0x88,0x62,0x3a,0xf3,0x49,0xe6,0xda,0x4b,0xd3,0xf3,0x35,0xaa,0x56,0x4c,0x2f,0x7f,0x03,0x3e,0xf8,0xcb,0x5e,0xed,0x37,0xa1,0x29,0xe8,0x20,0xf5,0x4a,0x32,0x73,0x30,0xfd,0xd1,0xf6,0xb4,0xa1,0x30,0x87,0xcb,0x21,0x63,0xf5,0x3a,0xad,0x05,0x1a +.byte 0x34,0xf5,0x32,0xf6,0x02,0xf3,0x10,0x52,0xfd,0x86,0x37,0x1f,0x5d,0xe4,0x2e,0x31,0xcb,0xb8,0x4c,0xeb,0xdd,0xea,0x01,0x0d,0x94,0x13,0xa8,0x8f,0xf0,0x52,0x4e,0x0d,0x4f,0xd1,0x24,0xeb,0x0f,0x2b,0xb1,0xaa,0xc5,0xc8,0x52,0xb9,0xbe,0x21,0x48,0x2a,0x53,0x98,0xe4,0x00,0x72,0x64,0xdb,0x44,0x48,0x36,0x60,0xe7,0x81,0xdc,0x25,0x85 +.byte 0x4d,0xaf,0xa8,0x0d,0xfb,0x07,0x76,0x4f,0x6a,0x30,0x3c,0x7c,0x3b,0x36,0xa9,0xf8,0xae,0x81,0x03,0xe9,0x19,0xdf,0xdb,0xd9,0x7f,0x59,0xe0,0xd7,0x50,0x14,0x9f,0x67,0x3d,0xc7,0xdf,0xa8,0x44,0x86,0x29,0x81,0x65,0x44,0x9e,0x37,0x27,0xdd,0x2f,0x33,0x59,0xf7,0xaa,0x17,0x34,0x8c,0x1c,0xa7,0x8e,0x06,0x46,0xf1,0x43,0x87,0xa9,0xb7 +.byte 0x85,0xec,0x92,0x0d,0xdd,0x78,0x55,0x99,0xfb,0x1c,0x66,0x85,0x0d,0x59,0x31,0x00,0xbc,0xd9,0x9b,0xbb,0xfb,0xfc,0xb2,0x36,0x3c,0x34,0x8f,0x4a,0xb6,0x74,0x9c,0x32,0x6f,0x69,0x6c,0x3e,0x68,0x7e,0xec,0xeb,0x58,0x6a,0xf5,0xa2,0xbb,0x04,0x68,0xdb,0x8c,0xf0,0x04,0xba,0xf7,0xf7,0x50,0xd0,0x60,0xba,0x45,0x73,0x0f,0x2c,0x2f,0x97 +.byte 0x58,0xcc,0xa2,0xbe,0xfe,0x5e,0xf9,0x44,0x03,0x8b,0x99,0x56,0xb0,0x4f,0xe1,0xd0,0xa5,0x9f,0xd1,0xfc,0x95,0x44,0x4b,0x01,0x24,0xc0,0x4c,0x91,0xc1,0xb5,0x99,0xe7,0x5f,0x2f,0xcf,0x5d,0x4f,0x64,0x6e,0x54,0x51,0x0c,0x35,0x5f,0xa8,0x7b,0x27,0xa0,0x7d,0xb1,0x90,0xc2,0xdd,0x50,0xef,0x09,0x6f,0xed,0x25,0x6b,0xf5,0x6f,0xc1,0x97 +.byte 0xea,0xd5,0x49,0xf5,0x40,0x60,0xc3,0xbb,0x0d,0x82,0x15,0xa5,0xf7,0xfe,0xa1,0x20,0x13,0x9e,0xbb,0x43,0x58,0xba,0xd2,0xe8,0x89,0xaa,0xfc,0xe0,0x47,0x6b,0xac,0x91,0x8b,0xeb,0x4f,0xf5,0xda,0xf5,0xc8,0x11,0x64,0x7c,0x8d,0x43,0x92,0xf2,0x84,0xeb,0xfb,0x5c,0x1b,0x6b,0x68,0x8e,0x3c,0x66,0xb2,0xd1,0x8e,0x67,0x44,0xbf,0x69,0x3b +.byte 0xb9,0x41,0x78,0x8d,0xc8,0x7b,0x81,0x61,0x70,0x6e,0xe2,0xfc,0xd2,0x96,0x31,0x31,0x2f,0x27,0x90,0xf2,0xc4,0xed,0xbd,0xb5,0x0e,0x91,0x7d,0xd0,0xec,0x3c,0xe9,0xcf,0xf2,0x07,0xac,0x54,0x44,0x9a,0x24,0x41,0xcb,0x2a,0x86,0x30,0x18,0xba,0x65,0x59,0x41,0x00,0x59,0xbf,0x3d,0x01,0x8a,0x51,0xe5,0xd2,0x90,0x8c,0x7d,0xd7,0xad,0x71 +.byte 0xdc,0x45,0x62,0x95,0xf9,0x9f,0xe8,0x55,0x6d,0x48,0x22,0x32,0xcb,0x9a,0x55,0x65,0xe5,0xdf,0xee,0x22,0x99,0x91,0xd7,0xed,0x33,0x04,0x72,0xc7,0xc5,0xb2,0x56,0x5e,0x8f,0x38,0x4b,0xd0,0x61,0x4b,0x4b,0x04,0x4c,0x4c,0x2b,0x23,0x00,0xd4,0x5c,0xdd,0x84,0x8d,0x73,0xf4,0xf7,0xef,0xd5,0xdb,0x2b,0xec,0x54,0x86,0x37,0x01,0x64,0x56 +.byte 0xef,0x73,0x9f,0xb4,0xb6,0xd2,0xf4,0x33,0x93,0xbd,0xd7,0xd9,0x6e,0x8f,0x60,0x85,0xbc,0xa6,0x16,0x3f,0x3f,0xc3,0xd7,0xfc,0xb6,0x82,0xf0,0xe5,0x1e,0x2c,0x51,0x48,0x27,0x50,0x3e,0xdb,0xe6,0x86,0x3b,0xa1,0xfa,0x09,0x39,0x04,0x6f,0xb1,0x85,0xbd,0xda,0x4d,0x2f,0xd1,0x40,0x6f,0x2e,0x2b,0xf2,0x9a,0x4d,0x8e,0xb2,0xc5,0x6e,0x21 +.byte 0xf9,0xdd,0xc9,0x2e,0x81,0x18,0x7b,0x88,0xb9,0x86,0x36,0xe5,0xb2,0xdd,0x19,0xb4,0x7f,0x5d,0xc0,0x20,0x34,0xdc,0x63,0x7d,0x8c,0x80,0x0f,0xe6,0x85,0x14,0xbb,0x87,0x6c,0x3e,0x39,0x53,0x60,0x3d,0xc5,0x46,0x11,0xa3,0x96,0x60,0x6f,0xe9,0xfe,0x59,0xcc,0xed,0x4d,0xdb,0xa3,0xa1,0xf1,0x71,0x0b,0xb0,0x1f,0x89,0x4c,0x32,0x59,0xa5 +.byte 0x7d,0xf7,0x3e,0x5b,0xca,0xa4,0xe1,0xc3,0x50,0xac,0xdf,0x00,0xad,0x45,0x59,0x9e,0x23,0x5f,0x52,0xbd,0x36,0x78,0x55,0xcf,0x90,0x91,0x41,0x14,0xdb,0x76,0x3a,0x43,0x39,0x89,0xe1,0x93,0xc8,0x66,0x91,0xc7,0x42,0x06,0x6f,0xbb,0x35,0x1e,0x07,0x52,0x5a,0xe4,0x41,0x9f,0x65,0xe0,0xdc,0x49,0x8c,0xd3,0x5f,0x16,0x21,0xc9,0xb8,0x8a +.byte 0xc2,0x56,0x91,0xcb,0x18,0x6b,0x38,0x7b,0x3a,0xeb,0x91,0x3c,0x0d,0x6a,0x1f,0xd6,0xc6,0xd7,0x56,0x8d,0xd3,0x76,0x1c,0x9d,0xed,0x3d,0xb6,0x92,0x71,0x6e,0x73,0xc6,0xb8,0xa2,0x1c,0x25,0xb9,0x3c,0xd4,0x41,0xf7,0x8f,0x39,0x60,0xe6,0x27,0xf2,0xc6,0x5f,0x56,0x08,0x7c,0xd3,0x16,0x9d,0x06,0xc0,0xca,0x3d,0xc6,0x61,0xb0,0x21,0x51 +.byte 0x6d,0xca,0x82,0x59,0xe6,0xbb,0x99,0xa2,0x4f,0xfc,0x71,0x66,0x2b,0x4e,0x40,0x62,0x97,0x34,0x73,0x4a,0xe5,0xf0,0x4f,0x4c,0x36,0x4c,0xdb,0x03,0xa9,0x87,0x29,0x21,0x5d,0x91,0x5b,0x89,0xb8,0x3d,0x65,0xc7,0x58,0x0a,0x81,0xb5,0x3e,0x22,0xa1,0x57,0x95,0xbe,0x60,0xf5,0xeb,0xb3,0x49,0xdf,0xd9,0xa2,0x31,0x36,0x5f,0xb2,0xa6,0xf6 +.byte 0x66,0x88,0x88,0x8e,0xa3,0x2c,0xac,0x5e,0xa1,0x33,0x16,0x64,0x08,0x47,0xc8,0xbc,0xc2,0xe9,0xdb,0x73,0x57,0x50,0xd4,0x24,0x01,0x26,0x26,0x04,0x4f,0x8a,0xc0,0x7a,0x97,0x14,0xf2,0xd0,0xbe,0x03,0xea,0x8a,0x25,0xcb,0x98,0xe7,0xbd,0x67,0xff,0x32,0xfd,0x8a,0x7d,0x11,0xe1,0xb2,0x91,0xb5,0xa0,0xb6,0x3c,0x2c,0xb3,0x6e,0x35,0x61 +.byte 0x86,0xbc,0x37,0x15,0xf8,0x3b,0x0d,0x84,0x83,0x69,0x76,0xb0,0xaa,0x8f,0x4f,0xca,0xba,0x54,0xfe,0x42,0xc8,0xba,0x9a,0xd5,0x53,0x69,0x67,0x29,0x23,0x3a,0x6a,0x75,0x97,0xb4,0x29,0x2e,0x62,0xe3,0x95,0x82,0xb3,0xa0,0xa1,0xb7,0xdf,0xc2,0x66,0x4d,0xdd,0x0d,0xda,0xda,0xc2,0x42,0xe0,0x69,0xb1,0xab,0x3c,0x44,0x39,0x11,0x3b,0x0a +.byte 0xd6,0x96,0x2c,0x36,0xb0,0xa0,0xed,0x3d,0x0c,0x63,0x8b,0x90,0xe4,0xb9,0x5f,0x4c,0x27,0x70,0x87,0xb3,0x54,0xe2,0x36,0x74,0x6f,0x3e,0x22,0xb1,0x3b,0x1b,0xba,0xdb,0x1c,0xbd,0x9c,0x6d,0x84,0xbd,0x33,0xfb,0xc0,0x98,0x4c,0xcf,0x7a,0xe8,0x41,0xdb,0x32,0x1f,0xb7,0x64,0x19,0xdb,0x87,0xe7,0xf9,0x52,0x40,0x8c,0xc6,0x89,0x98,0x15 +.byte 0x69,0xde,0xfa,0x29,0x9a,0x0f,0xaf,0xb0,0xad,0x71,0x35,0xab,0xab,0x34,0xe0,0xf4,0x03,0x24,0x6f,0x94,0x38,0x87,0xba,0x68,0xd5,0x1f,0x58,0x88,0x3e,0x12,0x20,0x57,0x43,0xde,0xd0,0xbc,0xaa,0x31,0x8f,0xbc,0x88,0xa0,0xdf,0x5a,0xcc,0xd1,0xba,0x9c,0x18,0x80,0x4e,0x8f,0x68,0x91,0x9c,0x57,0x3b,0x5a,0x62,0xc7,0x29,0x3e,0x49,0xc7 +.byte 0x23,0x26,0xfd,0x9e,0xd0,0xb0,0x4f,0xd4,0xb2,0xa9,0xa8,0x4c,0x66,0x54,0x52,0x75,0x6b,0xbf,0x63,0x76,0x49,0x3b,0xa3,0xb2,0x8f,0x87,0x9d,0xb4,0x8f,0x07,0x3c,0x8e,0xae,0xe1,0x0e,0x9a,0x86,0x90,0x58,0x73,0x8a,0xb3,0xa9,0xab,0xe6,0x27,0xd7,0x70,0x94,0x77,0x12,0xdc,0x71,0xdf,0xcf,0xba,0xdd,0x85,0xfe,0x28,0xaa,0xcd,0xcc,0xe8 +.byte 0x5f,0xd4,0xd8,0x45,0x6f,0x20,0xa8,0x5e,0x40,0x91,0x3b,0xd7,0x59,0x92,0xb8,0x7d,0x2b,0x8b,0x38,0xbd,0xfe,0x7b,0xae,0x5c,0xee,0x47,0x9b,0x20,0xb7,0xf3,0xad,0x75,0xa9,0xe1,0x96,0xc8,0xb2,0x30,0xfe,0x0c,0x36,0xa2,0x02,0xf4,0x3b,0x30,0xfd,0x91,0xfa,0x5f,0xd6,0x18,0x1a,0xcb,0xd2,0x26,0xbb,0x67,0xbe,0x1c,0x99,0xa5,0x4f,0x57 +.byte 0x40,0xb5,0xed,0xd6,0x84,0xfd,0x6b,0x00,0xc8,0xe7,0x18,0x1a,0x9f,0xf7,0x3b,0xd1,0xcc,0x12,0xeb,0x9d,0x61,0xf0,0x8d,0x64,0x08,0x93,0x61,0xc4,0x3e,0xdb,0xda,0x15,0xb1,0xd6,0x2c,0x84,0x2a,0xd8,0xd2,0xa1,0x66,0x4e,0xc9,0xd6,0xbf,0x7e,0xb6,0x22,0xfa,0x35,0x5e,0xdc,0xc0,0x31,0x02,0xb8,0x17,0x46,0x9e,0x67,0xd3,0x6a,0x8f,0x33 +.byte 0x85,0xc3,0xfe,0x36,0xbc,0x6f,0x18,0x8a,0xef,0x47,0xf1,0xf2,0x6e,0x15,0x6c,0xb1,0x4a,0x4b,0x13,0x84,0xd5,0x1b,0xf9,0xa2,0x69,0xcd,0xc7,0x49,0xce,0x36,0x8e,0xe5,0xd5,0x35,0x05,0x7c,0x7f,0xc6,0x15,0x29,0x2e,0x64,0xa6,0x91,0x9d,0xe5,0x9d,0x90,0xe7,0x26,0xec,0x75,0x19,0x58,0x57,0xf2,0x19,0x7b,0x24,0x7d,0x19,0xd3,0x72,0x69 +.byte 0xaa,0xa2,0x8c,0xe3,0x3d,0x38,0xb9,0xf0,0x5b,0xe9,0x3b,0xaa,0x96,0xef,0x2c,0xfc,0xf5,0x13,0xa6,0xa9,0x57,0x8c,0xa9,0x3a,0xc1,0xf0,0x2d,0x57,0x06,0x08,0xe3,0x9c,0xfe,0x82,0x8a,0x6a,0x79,0x5b,0xef,0x2b,0x81,0x83,0x01,0x53,0xac,0xdc,0x79,0x93,0x9b,0x23,0xd4,0xae,0x17,0x6f,0x62,0xaa,0x33,0x41,0xa6,0x31,0x1c,0x7b,0x46,0x2b +.byte 0x17,0xd3,0x6f,0x66,0x73,0x54,0xee,0xa1,0x08,0xee,0x8f,0x0f,0x0e,0x53,0xa7,0x49,0x17,0xdb,0x35,0xaf,0x4e,0x94,0x87,0x8e,0xff,0xf4,0x2b,0x29,0x01,0x45,0xa3,0x0a,0xd9,0x13,0x38,0x09,0x46,0x2c,0x56,0x97,0xd7,0xee,0x24,0x43,0xd1,0x20,0xed,0x38,0xde,0x52,0x13,0x38,0x06,0xd3,0x97,0xc7,0x48,0x8b,0x72,0x0a,0xc5,0xca,0x75,0x2c +.byte 0x04,0x9e,0xee,0x14,0xe7,0xda,0x59,0xc2,0x54,0x7a,0x72,0x55,0x35,0x00,0x93,0xb7,0xb9,0x81,0x01,0x46,0xae,0x43,0x81,0x34,0xd7,0xb4,0x7a,0xfc,0xfc,0x98,0x2b,0x29,0xe5,0x5e,0x9d,0x8e,0xef,0xd4,0x44,0x9d,0x9a,0xbe,0xdb,0x83,0x33,0x18,0x9e,0xbd,0x0f,0x34,0x4d,0xd9,0x34,0xe0,0x2c,0x1f,0x10,0xaa,0x06,0x5e,0x54,0x51,0x72,0xec +.byte 0xbf,0x6b,0x3e,0xb9,0xdd,0x37,0xc3,0xe1,0xbe,0xbe,0x1d,0x86,0xde,0x12,0xca,0x82,0xc5,0xe5,0x47,0xf8,0xbe,0xef,0xb6,0x79,0xd5,0x3c,0x69,0x0a,0x35,0x3e,0xd3,0xf8,0xaf,0x5b,0x8e,0x69,0xff,0xb2,0xf7,0x91,0xc2,0x70,0x22,0x97,0x1c,0x5c,0x56,0x25,0x5a,0xcf,0x31,0x7a,0x37,0xce,0xc7,0xf2,0x98,0xdc,0xb5,0x58,0x71,0x5a,0x60,0xe2 +.byte 0xfe,0x4f,0xf3,0xe2,0x2a,0xca,0x22,0x3e,0x07,0xc2,0xea,0x23,0xc8,0x04,0x97,0x7f,0xca,0xf6,0xf8,0x12,0x06,0x88,0x81,0xee,0xb7,0xdd,0x56,0x9e,0x0f,0x36,0xd3,0x09,0xa8,0x74,0x4d,0x8b,0x8f,0x31,0x64,0xbe,0x9d,0x7b,0x68,0x50,0xc8,0x64,0x40,0x3b,0x0c,0x04,0xb9,0x4b,0x9e,0xff,0x7e,0x5d,0xd8,0x57,0xa0,0xe5,0x6d,0xc2,0x37,0xe7 +.byte 0xd1,0xd9,0x96,0xaa,0x16,0x3e,0xa2,0x9d,0x32,0xe7,0x1e,0x11,0x6e,0x41,0xe2,0xa0,0xe1,0x6f,0x32,0x6d,0xd5,0x38,0x0c,0x27,0x27,0xa9,0xc2,0x04,0xc6,0xe7,0x8d,0x7d,0x7b,0x30,0xbe,0x54,0x6b,0x82,0x37,0x39,0x53,0x54,0xc9,0xac,0xcb,0xd1,0x31,0x79,0xd4,0x7b,0x85,0x07,0xf4,0xf4,0x5d,0x33,0xc7,0x91,0x4e,0xe5,0x13,0x78,0x09,0x42 +.byte 0x29,0x48,0xaf,0x82,0xb1,0x88,0xd4,0xd3,0x57,0x50,0x38,0xa7,0x66,0x41,0x63,0x34,0x2a,0x3c,0x5e,0x8f,0xc4,0xc1,0x00,0xa1,0x22,0xbe,0x5e,0x64,0xb0,0x60,0x9b,0x42,0x9d,0xc6,0x59,0x5c,0xcc,0x29,0x6f,0x64,0x5b,0x5c,0x0f,0xb2,0xae,0x21,0x0c,0x9a,0x6a,0x19,0xb9,0xa6,0x32,0xf8,0xdc,0x82,0xea,0xba,0x27,0xcf,0x42,0xd3,0xde,0x78 +.byte 0xfe,0x9c,0xa5,0x36,0xb6,0x24,0xb6,0x0d,0x5b,0x67,0x6c,0xf5,0x16,0xbf,0x67,0x54,0x4f,0xe4,0x83,0x29,0x75,0x42,0x9a,0xbb,0xd5,0xe7,0x01,0x1f,0xbd,0x80,0x1a,0x7a,0xb6,0xe1,0x2b,0x5d,0x71,0x93,0x00,0xad,0xf6,0x11,0x8d,0x67,0xdc,0x9c,0x8f,0xf0,0x09,0x3f,0xf9,0xa4,0xd6,0xe0,0xdd,0x95,0xea,0xfb,0x71,0x76,0x21,0x31,0x6d,0x48 +.byte 0x0a,0x27,0xa8,0xa6,0x3a,0x7f,0x42,0x6b,0x7e,0xd7,0x6e,0xd5,0x42,0x97,0xad,0x55,0xae,0x26,0x3c,0xde,0x3f,0xaf,0xfd,0x1d,0x6d,0xd3,0xeb,0x84,0xad,0x6d,0xd1,0x4a,0x85,0x1a,0xf7,0x99,0xa4,0xd0,0x48,0xfb,0xf6,0xfe,0xc6,0xea,0x61,0x77,0xe2,0x56,0x87,0xc1,0x36,0x44,0xb4,0xe3,0xd7,0xd9,0x6d,0x3e,0x1b,0xf4,0x72,0x3e,0xfe,0xa5 +.byte 0x47,0xf8,0x3f,0x1a,0x6e,0x43,0xf5,0x67,0xfe,0x90,0x96,0x9b,0x52,0xde,0xab,0xfb,0x45,0x7d,0x93,0xea,0xc3,0x40,0xe1,0x5f,0xcd,0xad,0x3b,0xe9,0x4e,0x36,0xc5,0x38,0xf4,0x66,0xde,0x4b,0xc8,0x2a,0xc3,0xa2,0x3a,0x2a,0xf1,0xd1,0xe8,0x01,0x07,0x37,0xca,0x42,0xbf,0x4f,0xd8,0xc5,0x50,0x93,0x1a,0x01,0x1d,0x51,0x41,0x6e,0xbf,0x68 +.byte 0x93,0x2e,0xdc,0x41,0x23,0xf3,0x13,0xe7,0x09,0xfa,0x39,0x6d,0xee,0x41,0x49,0xbb,0x78,0x04,0xcf,0xc9,0xbb,0x11,0xaa,0x57,0xb5,0x3e,0x4c,0x3a,0x77,0xb7,0x0b,0x38,0x34,0x48,0xd0,0x99,0x20,0x55,0xcd,0x43,0x2f,0x68,0x66,0xb0,0xe6,0x75,0x41,0xe4,0xae,0xfd,0x96,0xe8,0x01,0x4c,0x0b,0x5c,0xbc,0x4f,0x45,0x70,0x08,0x9e,0xf7,0x68 +.byte 0x9e,0xbb,0xe5,0x39,0x20,0x3f,0xbe,0xd3,0xe3,0x95,0xba,0x98,0xd5,0x12,0x2e,0x87,0xd4,0xf4,0x12,0xa2,0xcb,0xd4,0x51,0x53,0x93,0x67,0x06,0xf1,0x21,0x0e,0x92,0x8f,0x9f,0x9e,0x6c,0x16,0xa4,0x2c,0x6d,0xb0,0xd0,0xe1,0x87,0x2f,0x09,0x2c,0x8f,0x4b,0x89,0x1f,0xab,0x66,0xf1,0xcd,0x6e,0x67,0xaf,0x07,0x99,0x18,0x1b,0xda,0xc8,0x65 +.byte 0x81,0xa3,0x37,0x8a,0xad,0xe4,0x1d,0xfd,0x82,0xa0,0xf1,0xe1,0x1e,0x8d,0x0b,0xf7,0x07,0x7c,0xb3,0x10,0xc8,0x5a,0xa9,0xcc,0xc8,0xd0,0x2e,0x5a,0x71,0x45,0x4c,0x30,0xf0,0x10,0xe0,0xf6,0x0d,0x0d,0x11,0xb4,0x83,0x40,0x75,0xee,0xb9,0x24,0x04,0xe3,0xba,0xb3,0xd3,0x00,0x57,0x71,0x98,0xf0,0x4b,0x35,0x8d,0xd8,0x71,0xa0,0xcc,0xaf +.byte 0x46,0x54,0x67,0x65,0x70,0x0b,0x9c,0x61,0xf8,0xd4,0xb2,0x35,0xfd,0xcf,0x2b,0x3a,0x48,0x5b,0x03,0x86,0xd8,0x13,0x48,0x8a,0x55,0xa5,0x4d,0xef,0x42,0x41,0xbb,0x6a,0x8c,0x92,0x46,0x87,0x82,0x09,0x43,0xf3,0x94,0x1d,0x23,0x36,0xfe,0x6f,0xb8,0x9f,0xfa,0xf9,0x92,0x27,0x3c,0xcc,0x47,0x89,0x5c,0x7f,0x81,0x42,0x74,0x12,0x14,0xff +.byte 0x98,0x63,0xc0,0xfb,0x70,0xff,0xc7,0x65,0x5a,0xc3,0xb9,0x74,0x1b,0x71,0x3c,0x2c,0x47,0x79,0x07,0xb9,0x3c,0xc2,0x5f,0x48,0x4f,0xbd,0xaf,0x03,0x05,0x57,0xa9,0x84,0x33,0xc8,0x0d,0xd5,0xac,0x42,0xdb,0x4b,0x57,0x46,0x41,0xf0,0xe4,0x08,0x0d,0xf3,0x43,0x41,0xa5,0x14,0xb7,0xcd,0x64,0x23,0xc9,0xfe,0xff,0x12,0x97,0xc6,0x2f,0x8d +.byte 0x9e,0xf2,0x1d,0x33,0x26,0x3c,0x57,0x17,0xe1,0x7b,0x92,0x3f,0xb6,0xf4,0xd9,0xf8,0xe0,0x37,0xe6,0x18,0x7d,0xa7,0x8a,0x1e,0xe8,0xd8,0x56,0xa6,0x63,0xdf,0xa3,0x99,0x16,0x74,0x48,0x01,0xaf,0x95,0x55,0x40,0xce,0xa8,0x0d,0x30,0x01,0x09,0x40,0xc9,0x9d,0x3d,0xdf,0x4e,0x00,0xe0,0x2a,0xe6,0xdb,0xa2,0x79,0x42,0x57,0xd0,0x3d,0x81 +.byte 0x7f,0x67,0x3a,0xa9,0x63,0xb3,0xd4,0x60,0xa7,0xab,0x54,0x46,0xb0,0xbe,0xb0,0x83,0x72,0xec,0x47,0x0f,0xc7,0xd1,0xed,0x16,0x96,0xbc,0xa5,0x62,0x38,0xdb,0x88,0x2b,0x25,0x26,0x27,0x56,0x7f,0x46,0x39,0xe8,0x4e,0xc0,0x6c,0x62,0xf8,0x80,0x68,0x56,0x8a,0x93,0x51,0x95,0x77,0xe3,0x11,0x7b,0xaf,0xc4,0xcf,0x34,0x5a,0xd5,0x26,0xfc +.byte 0xa2,0x18,0xb0,0xc0,0xa5,0x8b,0x25,0x70,0x40,0x70,0x29,0xc3,0xda,0x80,0x3d,0xe2,0x59,0x49,0x7f,0xdd,0x62,0x6e,0x5a,0xe6,0x27,0x73,0xce,0xb6,0x32,0x37,0x5f,0x73,0x12,0x2b,0x34,0x84,0xff,0x85,0xe3,0xb5,0x93,0x41,0x47,0xc5,0xf5,0x0e,0x21,0xfb,0x24,0x0f,0xdf,0x7b,0xb4,0x29,0x7f,0x67,0x2a,0x38,0x79,0xf0,0x54,0x8a,0x94,0x68 +.byte 0xe2,0x0b,0xb0,0xd4,0xb2,0xa4,0xe4,0xfb,0x3b,0xe6,0xe7,0x59,0x41,0xbd,0xed,0x62,0xce,0x50,0x1a,0x47,0x92,0x92,0x8d,0x80,0xa6,0x05,0x7a,0xb0,0xce,0x48,0x9c,0xb0,0x64,0xea,0xe0,0xa5,0x77,0xff,0xc1,0x82,0x99,0x7b,0xfb,0x74,0x53,0xfa,0x41,0x9a,0x2c,0xb4,0xbb,0xd2,0x26,0xa1,0x80,0x68,0x17,0xaa,0x8f,0x14,0x52,0xb6,0x5d,0xe0 +.byte 0x69,0x5b,0x31,0xc5,0xf5,0x32,0x0d,0xff,0xa4,0x7b,0x28,0x38,0x9b,0x61,0xfc,0xd0,0x92,0xb8,0x6e,0x23,0x8a,0xf3,0xc7,0x85,0x11,0xb8,0xd0,0x19,0xaf,0xca,0xa7,0xb4,0xcc,0xeb,0x5d,0xf6,0xa1,0x1c,0x56,0xdf,0x78,0x7a,0xe3,0x6a,0xa4,0x07,0x71,0xce,0xf1,0xb2,0xd5,0x38,0x3c,0xfa,0xf7,0x7a,0xbf,0x4b,0x43,0xa6,0xb3,0x4d,0xff,0x82 +.byte 0x96,0x46,0xb5,0xec,0xda,0xb4,0x5e,0x35,0x78,0xeb,0x4a,0x7e,0xc5,0x7b,0x05,0xd4,0xdd,0xf7,0xb7,0xf3,0xf0,0x04,0x26,0x7e,0x5e,0xc1,0x23,0xca,0x7f,0x14,0x27,0xac,0xda,0xe7,0xdb,0x31,0x05,0x9d,0xd4,0xda,0x20,0xc7,0x6d,0x9a,0x47,0x14,0x38,0xbd,0x7c,0xfe,0xbe,0x8d,0x42,0x7c,0xba,0x36,0xe2,0x2c,0x26,0xd2,0x46,0xa5,0x6b,0xbd +.byte 0x6a,0x75,0x6b,0x52,0x8c,0x10,0xc6,0x0e,0x76,0x60,0x46,0xcc,0x93,0x54,0xc4,0x6e,0xc7,0x70,0x5b,0xb4,0x81,0x51,0x56,0x03,0x22,0x33,0x21,0xe4,0x36,0xee,0x01,0xc3,0x0d,0x17,0x23,0x15,0xae,0x79,0xbc,0xe6,0x13,0x0f,0xfc,0x77,0xa2,0x06,0xed,0x76,0x4a,0xf7,0x2d,0x99,0xc8,0x5c,0xfd,0xac,0xd0,0x11,0xe8,0xfa,0x55,0x17,0x56,0x63 +.byte 0x3e,0xd5,0x23,0x71,0xf8,0xe9,0x1f,0x62,0x95,0xae,0x7c,0x2d,0xcd,0xb8,0x6e,0xb0,0xfe,0xf3,0xd0,0xba,0x72,0x8e,0xe3,0x95,0x82,0x00,0x85,0xdb,0x25,0xe4,0xf2,0xaa,0xbc,0x8d,0xb9,0x4d,0x69,0xa4,0xcd,0x39,0x52,0x9e,0x10,0xae,0x90,0xf0,0x74,0x2f,0xc6,0x5e,0x01,0x99,0x03,0xd5,0x88,0x59,0xfd,0x1b,0x80,0x56,0x0a,0x04,0x27,0xd9 +.byte 0x04,0x51,0xb0,0xb7,0x7a,0x65,0x79,0xa8,0xe2,0x6d,0x7f,0xb2,0xba,0x37,0x40,0xa0,0xbb,0xaf,0x15,0x46,0x23,0x5f,0x22,0xd0,0x2c,0x6c,0x7a,0x58,0x76,0x6f,0xb8,0x19,0xfe,0xb5,0x3d,0xf0,0x77,0x00,0x6b,0x4c,0x83,0x36,0x90,0xe6,0x57,0x29,0x6e,0x27,0x76,0xd4,0x7d,0x9a,0x6a,0xf1,0xf6,0x1b,0x1a,0x45,0xf5,0xf6,0x2d,0xb8,0x30,0x33 +.byte 0x65,0x51,0x37,0x26,0xbc,0xf7,0xb7,0xf9,0x56,0x05,0x6b,0xd4,0xd6,0x00,0x1d,0x13,0x15,0x45,0x24,0x0d,0x28,0x69,0xc6,0x50,0xe1,0x48,0x48,0x34,0x69,0x31,0x3c,0x58,0x71,0xd6,0x4a,0xd9,0xda,0x0d,0x28,0xbd,0xe9,0x5d,0x5d,0x8a,0x6e,0x71,0xc0,0x8b,0x7a,0xba,0x17,0x8e,0x82,0xcb,0xe9,0x95,0xc4,0x43,0x37,0xd0,0x58,0xed,0xec,0x77 +.byte 0x1e,0x22,0xf0,0xf0,0x7c,0x9d,0xeb,0x64,0x30,0x7b,0xb2,0x7b,0x86,0xdb,0xef,0x92,0x79,0xd9,0x9c,0x1c,0x1a,0xf6,0x98,0x26,0x18,0xa2,0x83,0x45,0x08,0xd4,0x1d,0x84,0xd4,0x28,0x6d,0x1f,0xb5,0x1f,0xab,0x97,0xc9,0x0d,0x1f,0x83,0x34,0x18,0xa3,0x20,0x63,0x60,0x6c,0xf3,0xd8,0xb2,0x0a,0xd9,0x35,0xa6,0xce,0x44,0x50,0xc6,0xf3,0x91 +.byte 0xe3,0x95,0x89,0x49,0x99,0x32,0x1d,0xf2,0x54,0x39,0x09,0xca,0xd1,0xc4,0x7f,0xa1,0x1d,0xce,0x94,0x67,0xf1,0x88,0x04,0x29,0xcb,0x5d,0xf7,0xfa,0xcd,0x69,0x16,0x17,0x05,0xc3,0x93,0x45,0xbf,0xd3,0x74,0x63,0xdc,0xe2,0x84,0xab,0x27,0x60,0x56,0x61,0x72,0x5d,0xdf,0xb4,0xa4,0x0f,0xb0,0x21,0x82,0x9b,0x73,0x0a,0x11,0x22,0x2d,0x65 +.byte 0xa2,0xff,0x29,0x8a,0x19,0x28,0x4f,0x4f,0xdd,0x64,0x0a,0x48,0x35,0x70,0x30,0x9f,0x41,0x4d,0x0c,0x7b,0xa6,0xcb,0x63,0x83,0xd1,0x79,0xfa,0x5f,0xc9,0x9b,0x6e,0x09,0x12,0x87,0xcd,0x1e,0x39,0xd6,0x40,0x08,0x0f,0xfd,0x79,0xc8,0xcb,0x77,0x8f,0x7a,0x52,0x42,0xc0,0xb2,0xc8,0xa0,0x2a,0xff,0xbc,0x60,0x13,0xbc,0x41,0x4a,0xc6,0x8b +.byte 0x08,0xb0,0x9f,0x75,0x87,0xa1,0x75,0x42,0x4b,0x3a,0xf7,0xf7,0x84,0x39,0xa5,0x88,0x25,0x2d,0x4f,0x73,0x4e,0x30,0x27,0x92,0xea,0x93,0x70,0x5c,0xb5,0xeb,0xb0,0x10,0xda,0x0f,0xaa,0xb3,0x3f,0xb5,0x55,0x64,0x65,0xae,0xb5,0xf8,0x0a,0xe4,0x9f,0x86,0x02,0x6f,0x63,0x8a,0x0b,0x6b,0x82,0x85,0x3c,0x6a,0xdf,0x68,0x4c,0x1e,0xe9,0x5c +.byte 0xd0,0x99,0xe5,0x0c,0xfc,0x63,0xfb,0xce,0x2d,0x63,0xd5,0x7d,0x8a,0x7d,0x14,0x22,0xbd,0x71,0x5e,0x79,0x3f,0x44,0x95,0xe5,0x6c,0x58,0x94,0x84,0x41,0x65,0x52,0x94,0x50,0xec,0xd3,0x2a,0x16,0x88,0xdb,0x71,0xb9,0xe4,0xb6,0xbf,0xc5,0x3c,0x48,0x37,0x62,0x32,0x79,0xbe,0x1d,0xdb,0xc9,0x79,0x37,0x40,0x65,0x20,0x62,0x45,0xb4,0xda +.byte 0x24,0xef,0x33,0xf1,0x05,0x49,0xef,0x36,0x17,0x17,0x0f,0xdc,0x65,0xb4,0xdc,0x57,0xc3,0xc6,0x82,0x57,0x08,0xf2,0x20,0x57,0x5c,0x25,0x0e,0x46,0x75,0xa7,0x4f,0x9e,0xa4,0x00,0xf7,0x79,0xb9,0x0a,0xef,0x4f,0x50,0x79,0xf8,0x59,0x01,0xf2,0x74,0x9f,0x16,0x27,0xa5,0xc1,0x32,0xcc,0x58,0xa7,0x40,0xa1,0xa1,0x26,0x80,0x00,0xb5,0x64 +.byte 0x0a,0xd8,0x53,0x1f,0x72,0xf7,0x60,0xf7,0x0a,0xaa,0xdf,0x31,0x95,0xff,0xfc,0xb4,0xca,0xbc,0xf8,0x2a,0x33,0x20,0x04,0x16,0x1a,0xe7,0xeb,0x22,0xd1,0x25,0xa6,0x03,0xc9,0x9e,0x9e,0xca,0x7a,0x46,0x7c,0xcb,0x8a,0x63,0x4a,0xf0,0x1b,0xd0,0x34,0xc3,0xbb,0x89,0xcf,0x16,0x38,0xcb,0xe0,0xce,0xd5,0x0b,0xfd,0x4e,0xbc,0xce,0xba,0x28 +.byte 0x68,0x00,0x2a,0x31,0x52,0xe6,0xaf,0x81,0x3c,0x12,0x09,0x2f,0x11,0x0d,0x96,0xc7,0x07,0x42,0xd6,0xa4,0x2e,0xc1,0xa5,0x82,0xa5,0xbe,0xb3,0x67,0x7a,0x38,0xf0,0x5e,0xd8,0xff,0x09,0xf6,0xab,0x6b,0x5d,0xec,0x2b,0x9f,0xf4,0xe6,0xcc,0x9b,0x71,0x72,0xd1,0xcf,0x29,0x10,0xe6,0xe3,0x27,0x1c,0x41,0xc8,0x21,0xdf,0x55,0x27,0xa6,0x73 +.byte 0xb7,0x45,0xa1,0x09,0x66,0x2f,0x08,0x26,0xf1,0x50,0xe0,0xec,0x9d,0xf2,0x08,0xf3,0x49,0x56,0x50,0xe0,0xba,0x73,0x3a,0x93,0xf5,0xab,0x64,0xb6,0x50,0xf4,0xfa,0xce,0x8d,0x79,0x0b,0xad,0x73,0xf2,0x8c,0x1e,0xe4,0xdd,0x24,0x38,0x1a,0xde,0x77,0x99,0xb8,0x92,0xca,0xc0,0xc0,0xbc,0x3d,0x01,0x6f,0x93,0x3a,0x6e,0xc5,0x28,0x6e,0x24 +.byte 0x9c,0xf9,0xd9,0xcb,0x4b,0xbe,0x9e,0xda,0x0d,0x10,0xfb,0x9d,0x15,0xfe,0x28,0xdc,0xd9,0x09,0x72,0xd3,0x9f,0x6d,0x77,0x14,0x84,0x86,0x56,0x10,0xdc,0x8e,0x6a,0xa7,0x62,0xf0,0x0b,0x65,0x2c,0xa2,0xd1,0x7f,0xae,0x32,0xfa,0x9b,0x46,0x0f,0x12,0x08,0x22,0x8c,0x87,0x15,0x4b,0xc4,0x6d,0x85,0xfb,0x69,0xfe,0xce,0xfb,0xb4,0x3e,0x7b +.byte 0xcf,0x88,0xa7,0x97,0x52,0x56,0xd0,0x9f,0xb4,0x33,0xf9,0x08,0xd2,0x28,0x46,0x5e,0xc4,0xec,0x22,0xc6,0x1e,0x7b,0x34,0x99,0x0c,0x5b,0x04,0x19,0xe2,0xca,0x09,0x11,0x50,0x45,0xcc,0xb2,0x90,0x25,0x51,0x68,0xc9,0x20,0x6c,0x99,0x2e,0xdb,0x5b,0x07,0x91,0xb2,0x69,0xbf,0x3c,0x05,0x50,0xfb,0x21,0x33,0x4f,0x6e,0x18,0x19,0xd5,0xff +.byte 0xce,0x9d,0xb5,0x7f,0xd4,0xd5,0x8f,0x41,0x26,0x1f,0xa1,0x4c,0x34,0xd3,0x98,0x08,0x5d,0xb5,0x56,0xa7,0x04,0x63,0x76,0x7d,0xae,0xee,0xea,0xbf,0x69,0x8d,0xff,0xa1,0x62,0x86,0x19,0x7b,0xe5,0x08,0x7a,0xe5,0x9e,0xe5,0x44,0xca,0x24,0xde,0x00,0x43,0xc7,0xcd,0xc8,0x5b,0x21,0x00,0xb9,0x56,0x3f,0xba,0xef,0xcd,0xc4,0xe0,0xd7,0x90 +.byte 0xa7,0xe1,0xf9,0x83,0x2c,0x1d,0x8d,0xc3,0x1b,0xa2,0xab,0xcd,0x7d,0xbc,0xd1,0x2b,0xf8,0x30,0x9e,0xb6,0x95,0xe0,0xd1,0xe6,0x81,0x89,0xa7,0xda,0xf0,0x54,0xc1,0xcb,0x3a,0x85,0x85,0xb5,0x03,0xb4,0x8c,0x7d,0x98,0x16,0xa8,0x83,0x29,0xbb,0x1c,0x1d,0xe1,0x7e,0x0e,0xb5,0x04,0xba,0xbf,0x89,0x30,0x3c,0x44,0xa2,0xc5,0xbf,0xf1,0x70 +.byte 0xdb,0xf3,0x13,0xf4,0x44,0xac,0x63,0xc4,0x9c,0x93,0xa9,0x13,0x1b,0xf1,0xcc,0x16,0x66,0xdf,0x56,0x10,0x88,0x0c,0x76,0xab,0x43,0xcb,0x75,0xf8,0x4f,0x04,0x26,0x95,0x4c,0x6d,0x55,0xc8,0xbd,0xf8,0x94,0x0f,0xca,0x29,0x2b,0xcd,0xce,0x05,0x1e,0xea,0xae,0x02,0x01,0x8b,0x60,0x6a,0x6a,0x03,0x14,0xe5,0xa7,0xdf,0x9e,0x9f,0x94,0x92 +.byte 0x41,0x2c,0xf0,0x1a,0xa7,0xc2,0xc1,0xfc,0x11,0xf3,0x00,0xe1,0xfc,0x7a,0x97,0xc0,0xe1,0x81,0x90,0x3f,0xea,0x1e,0x7f,0xf8,0xb0,0xd8,0x4c,0x2d,0xdc,0x83,0xfa,0x27,0x8b,0xf2,0xef,0x3b,0x3a,0x44,0xdc,0xa5,0xa9,0xd5,0x24,0x5f,0xb1,0xdd,0x1d,0x3f,0x03,0x76,0x3b,0x92,0x0d,0xb4,0x84,0xa4,0x5b,0xef,0x9f,0x89,0x9d,0xef,0xff,0xcf +.byte 0xc2,0x28,0x3b,0x9d,0xd2,0x28,0x75,0x3e,0xdc,0x14,0x79,0x7c,0x0c,0xaa,0x6c,0xf2,0x05,0x9d,0x27,0x01,0x15,0x19,0x60,0x48,0x5a,0x7d,0x04,0x27,0x2d,0x82,0x92,0x3e,0x0b,0x62,0xd7,0x5a,0xfb,0x72,0xfb,0xdd,0x43,0xfa,0xf4,0x6f,0x16,0xd2,0x8f,0x8f,0x21,0xdc,0x81,0x48,0x7a,0xe8,0x39,0xd5,0xdf,0x54,0x0f,0xe1,0xbe,0x65,0xc9,0x49 +.byte 0x98,0xb1,0xff,0x8d,0x52,0x31,0x6a,0xcd,0x5e,0x83,0x17,0x41,0x93,0xcd,0x23,0x76,0x18,0xe9,0x82,0x71,0x15,0xb7,0xd8,0xde,0x0d,0x57,0x8b,0x90,0xe6,0xf4,0x57,0xc1,0xfd,0x3d,0x0d,0x6a,0xae,0xd1,0xd6,0x02,0x3e,0xb9,0x82,0xb2,0x82,0x80,0x48,0xa4,0x14,0x29,0x80,0x55,0x1d,0xaf,0x3e,0xf8,0x7e,0x36,0x5f,0x77,0x4c,0x73,0x6c,0x35 +.byte 0xd2,0x7c,0x36,0xca,0x2f,0xec,0x1e,0x3f,0x74,0xee,0xa5,0xe7,0x7d,0xce,0x81,0xf1,0xd5,0xc1,0xb3,0xaf,0x90,0x2c,0xc6,0x5b,0x81,0x37,0x85,0x98,0x78,0x3c,0x4f,0x2a,0x55,0xea,0x06,0x30,0x77,0x73,0x97,0x39,0x75,0xcf,0x4a,0x9b,0x55,0xb8,0x64,0x5c,0x86,0xfd,0x26,0x3e,0x8d,0x68,0xd2,0x70,0xe8,0xd7,0x99,0x57,0x6f,0x96,0x47,0x6d +.byte 0xa7,0x1a,0x0e,0x85,0xcd,0x00,0xa5,0x3e,0x11,0xec,0x76,0xd2,0x47,0x26,0x71,0xda,0x5c,0xf4,0xb1,0xd5,0x23,0xe1,0x62,0x71,0x43,0x30,0xa7,0x95,0xf6,0xc1,0xcf,0x8a,0x1b,0x75,0x53,0x39,0x6d,0x9d,0x18,0x7c,0xe3,0x48,0x27,0x33,0x1c,0x38,0x45,0xdf,0x75,0x22,0x05,0x6d,0x81,0x5d,0xfc,0xeb,0x0e,0x05,0x26,0x45,0x81,0x9f,0xce,0x0f +.byte 0xc9,0xdd,0x95,0x11,0x04,0x47,0x40,0xa4,0x07,0x3b,0x52,0x92,0xe0,0x91,0xdb,0xdd,0x3c,0x9f,0xd3,0xa1,0xb7,0xf9,0xeb,0xd6,0x6d,0x64,0x88,0xe9,0xf5,0x4e,0x98,0x8e,0x7b,0xd3,0xec,0xc0,0x22,0xe0,0xf2,0x14,0xf2,0x20,0xa2,0xa3,0xb3,0x0d,0x75,0x1a,0xbb,0xde,0x4a,0x41,0x04,0x43,0x0d,0xd9,0xd0,0x1d,0x73,0xc8,0x67,0x8e,0x58,0xe5 +.byte 0x4b,0x28,0x4d,0x8f,0x2f,0xab,0x1a,0x4a,0xfc,0x7c,0xd1,0x27,0x3e,0x4a,0x10,0x6a,0x5f,0x55,0x3a,0xf7,0x63,0x14,0xe9,0xad,0xb4,0x95,0xef,0x3d,0x5c,0xc3,0x7d,0xe4,0xb7,0x15,0xd7,0x0b,0x68,0xf0,0x23,0xa8,0xd4,0x8e,0x27,0xf6,0x55,0x11,0xbc,0xc0,0xff,0x3e,0x2c,0x24,0x59,0xb7,0xb7,0xb5,0x0b,0xd2,0x99,0xa5,0xd5,0xe2,0x24,0x33 +.byte 0x21,0xb8,0x96,0x48,0x18,0x94,0xb5,0xb2,0x50,0x5e,0x04,0x24,0x86,0x17,0x62,0x1e,0xc9,0xf8,0x22,0x6a,0xd0,0xec,0xc5,0xbc,0x90,0xf7,0x55,0xcf,0x3f,0x4c,0x7c,0xf7,0x51,0x19,0x95,0xa4,0x81,0x38,0x0c,0xa5,0x58,0x22,0xf3,0x10,0x05,0x05,0x44,0xbf,0x7e,0x2a,0xbd,0x5f,0x79,0x56,0x08,0xd5,0x68,0xea,0x85,0xa1,0xeb,0x0b,0xe1,0xd4 +.byte 0xfd,0x3a,0x38,0xd2,0x5a,0x49,0x17,0x9a,0x58,0x8f,0x52,0xf5,0xf4,0x7b,0x1f,0x58,0xa8,0xc0,0x1c,0x46,0x38,0xa6,0xe4,0x7d,0xcc,0x88,0x97,0x10,0x2b,0x5e,0x61,0xf5,0x73,0x7d,0x79,0x1b,0x53,0xf1,0xac,0xb4,0x3f,0xbd,0x9d,0xb6,0xc2,0x57,0xd5,0x84,0x4d,0x60,0xd6,0x45,0x56,0xa1,0x36,0x28,0xf5,0x74,0xc6,0x29,0xd7,0xc9,0x63,0x5e +.byte 0x7c,0x97,0x46,0xde,0x56,0x3f,0xd8,0x8e,0x75,0x29,0x87,0xe7,0xd1,0x24,0x78,0x26,0xdc,0x17,0x97,0xc9,0xf0,0x8e,0x95,0xbc,0xe5,0xfe,0xe3,0x3a,0x75,0x70,0x52,0xa9,0x31,0x97,0x79,0x3a,0xc2,0x53,0x6a,0x73,0xe2,0x76,0xf8,0x85,0xe6,0x0d,0x85,0x9b,0xfc,0x72,0x08,0x2a,0xa5,0x8e,0x42,0xb2,0x7c,0x8d,0x8b,0x28,0x4b,0xf5,0xcb,0x66 +.byte 0x80,0x46,0xb3,0x87,0xdf,0x38,0xa7,0x08,0xc8,0xea,0x85,0x0e,0x6f,0x13,0xe0,0x57,0x99,0xc6,0xb8,0xed,0x9c,0xb0,0xa9,0x89,0xd7,0xc5,0xa9,0x71,0xfd,0x8a,0x21,0xb1,0xec,0xc8,0x65,0x78,0x72,0xc6,0x77,0x69,0xd4,0x0b,0x47,0x4d,0x79,0x93,0xcf,0x2a,0x34,0xf1,0x1b,0x0e,0x6f,0x0d,0xd1,0xbb,0xe7,0xd7,0xb5,0x6f,0x57,0x01,0xd4,0xcd +.byte 0x56,0xbe,0xf0,0xd9,0xe2,0x8e,0x0e,0xb8,0x3d,0xdb,0xf6,0x97,0x39,0x0b,0x3e,0xe2,0xb2,0xa3,0x93,0x0b,0x74,0xe5,0x6a,0x21,0x04,0x29,0x5a,0x3e,0x07,0x9c,0x11,0x4e,0xfe,0x01,0x6e,0x96,0x1e,0x8f,0xe0,0xfe,0x24,0x24,0x7e,0x04,0x2f,0x65,0xf4,0xe2,0x1f,0x36,0x56,0x43,0x3a,0x6c,0xeb,0xd7,0x20,0x13,0x71,0x45,0x6a,0xe8,0xc6,0xfa +.byte 0xba,0x26,0x6f,0x7d,0x9a,0x62,0x76,0x34,0x7d,0xed,0x47,0x71,0xd1,0x0e,0x5b,0x04,0x39,0xd6,0xc0,0xe5,0xa5,0xd8,0xf5,0x73,0xf9,0xf4,0xc2,0x2a,0x54,0x25,0x67,0xdf,0x83,0xa3,0xcd,0xfd,0x1e,0x46,0x87,0x06,0x17,0x6d,0x78,0x8e,0x0c,0x7b,0x08,0x06,0x1b,0xd9,0x5d,0x3d,0x03,0x40,0xbc,0xe7,0x02,0xc4,0xe0,0xe0,0x49,0xb2,0x6c,0x6f +.byte 0x97,0x76,0x0f,0xc7,0x14,0xd8,0x7c,0xc0,0xad,0x8a,0xbb,0xbc,0x2a,0x7e,0x68,0x46,0xcd,0xa7,0x26,0x16,0x77,0x1b,0x89,0x38,0xd8,0x2a,0x69,0x43,0xc4,0xaa,0x0d,0xf6,0xd1,0x65,0xda,0x41,0x75,0x77,0xcd,0xf7,0xd2,0x38,0x9c,0xdb,0x81,0x17,0x27,0x2f,0xba,0x2e,0xa5,0xb5,0xbe,0x05,0xe8,0xdd,0x5f,0xa9,0xad,0xbe,0xb2,0x0e,0x0b,0x69 +.byte 0xb6,0x8d,0xd2,0xf2,0xde,0x76,0x32,0x26,0xd9,0x06,0x1d,0x42,0x26,0x8c,0xf7,0xca,0x4c,0xe1,0x59,0x82,0x6c,0xea,0x96,0x70,0x39,0xb8,0x0d,0xf3,0x67,0x9d,0x5e,0x94,0x99,0x77,0xf2,0x0a,0x9a,0xde,0xa5,0xd2,0xe1,0xaa,0x91,0x85,0xc7,0x0f,0x92,0x35,0x04,0xd3,0x7a,0x13,0xfa,0xf2,0x86,0x5a,0x38,0xd1,0x7f,0x10,0xd8,0x30,0x0e,0x33 +.byte 0xe3,0xa0,0x8a,0xad,0x4f,0x6c,0x24,0xdd,0x9d,0x1c,0x4e,0xff,0x4c,0xfc,0x74,0x01,0xab,0x08,0x6c,0xe6,0x4c,0x78,0x75,0xc9,0x67,0x83,0x1f,0x75,0x22,0xb0,0x7c,0x44,0xa0,0xa1,0xee,0x4e,0xf6,0x3e,0xd3,0x35,0x70,0xbe,0x36,0x1e,0x90,0xa6,0xaa,0x64,0x67,0x7f,0x52,0x84,0xd9,0x27,0xab,0x37,0x30,0x68,0x46,0xcc,0x0e,0x57,0x58,0x6f +.byte 0xdb,0xb2,0x5f,0x24,0xf7,0xeb,0x97,0xea,0x64,0xec,0x6c,0x1e,0xe1,0xc4,0x72,0xfb,0x00,0xa7,0x62,0xa0,0x59,0xb9,0x17,0x8a,0x33,0x32,0x59,0xb8,0xbe,0x84,0xd4,0x62,0xb7,0xf6,0x35,0xd4,0xf1,0x1c,0xdb,0x7e,0xa6,0xbc,0x2c,0x54,0x3c,0xf5,0x63,0x4a,0x22,0x26,0x58,0xa0,0x35,0x98,0xa7,0x32,0xb2,0xa0,0x2b,0xd5,0xfa,0x2f,0x9b,0xb4 +.byte 0xea,0xd6,0x58,0x61,0xb2,0x24,0x45,0x46,0x1e,0xac,0x79,0xa4,0xf7,0xc1,0x13,0x2f,0xf5,0x6b,0xfa,0x70,0x50,0x2b,0x83,0xee,0x7c,0xc1,0x55,0x27,0x7b,0x4f,0xa6,0x0a,0x72,0x26,0x82,0xcd,0x4d,0xe2,0xe8,0x45,0xe6,0xd7,0x39,0x7e,0xed,0x35,0xdf,0x9e,0xb1,0x41,0x55,0xa2,0x5d,0x68,0x4b,0x0b,0xd1,0x73,0x5a,0x2b,0x81,0x35,0x28,0xfc +.byte 0x64,0x08,0xd7,0xc4,0x9f,0x30,0x77,0x3d,0x9d,0x80,0x15,0x67,0x9a,0x84,0xe4,0x34,0xea,0x8c,0xf7,0x73,0x9e,0x33,0xb4,0x09,0x33,0xbd,0xd8,0x82,0x43,0x7d,0xc5,0x1f,0x0e,0x7b,0xa0,0x53,0x59,0x20,0x12,0x57,0xed,0xda,0xc7,0x19,0x8e,0x62,0xe4,0x09,0xc1,0x4b,0x20,0x32,0x9e,0x18,0x11,0x1c,0x42,0x49,0x62,0x76,0xa8,0x83,0x72,0x11 +.byte 0x45,0xe7,0xb5,0x60,0xa7,0xc0,0x07,0xbd,0xb4,0x7c,0xc6,0x5c,0x03,0x34,0xa3,0x85,0x47,0x24,0x75,0xd2,0xab,0x46,0xbb,0xc7,0x0d,0xcd,0x40,0xe2,0x5e,0x5b,0xa7,0x98,0x67,0xe4,0xe2,0x02,0xe9,0xdc,0xd7,0xc2,0xaf,0x90,0x43,0x94,0xfe,0xf3,0x53,0xc1,0x10,0x28,0xa7,0x90,0xba,0x73,0x57,0x0c,0x4d,0x6d,0xbd,0xda,0x81,0xd5,0x90,0xce +.byte 0x02,0x40,0xb3,0xf0,0xec,0x50,0x82,0xc9,0xfb,0xf1,0x22,0x6d,0xc8,0xd2,0x7b,0xed,0x0b,0x43,0x7e,0x0b,0x60,0x9b,0x69,0x9e,0x58,0x26,0xc3,0x9f,0x6b,0xd0,0x31,0xeb,0xb7,0x0a,0xf3,0x9a,0x9a,0xf5,0x72,0xcf,0x29,0xc8,0x19,0x08,0x4d,0x67,0xd5,0xa1,0x8f,0x68,0x0e,0xee,0x59,0x14,0xf8,0x86,0xc0,0x08,0x5a,0x56,0xfe,0x6a,0xb7,0xac +.byte 0x78,0x8d,0x77,0x39,0x5e,0xb1,0x01,0x4d,0x31,0x81,0x56,0xdc,0x5b,0x10,0xda,0x4d,0xd2,0xfd,0xfc,0xa3,0xe3,0xaa,0x46,0x29,0x1a,0xea,0x9c,0x47,0x1b,0xd0,0xa6,0x84,0x1f,0x71,0x1a,0xd3,0x35,0x59,0x7f,0xef,0xf7,0x81,0x39,0x7a,0x9f,0x4a,0x01,0x4d,0x46,0xcf,0xa4,0x6a,0x9c,0x7e,0x07,0x8b,0x98,0x17,0x49,0x5c,0x46,0xac,0xc8,0xfd +.byte 0x1c,0xaf,0x91,0x30,0x0c,0x36,0x63,0xef,0x69,0xd3,0x47,0xf4,0x76,0xc1,0xf7,0x40,0x03,0x98,0x9e,0xcb,0x61,0x65,0x46,0x45,0x1c,0x1b,0xfd,0x13,0x36,0xe9,0x19,0xbf,0x2b,0x59,0x51,0xe8,0x04,0x44,0xe3,0xc2,0x4b,0x66,0x78,0x69,0x66,0xa3,0x1a,0xe5,0x2a,0xad,0xf8,0xc5,0x0f,0xb7,0x3e,0xe8,0xab,0xe0,0xe4,0xd9,0xc2,0xb8,0x61,0x5b +.byte 0xef,0x6b,0x4d,0x5f,0xb8,0xdc,0x06,0xa5,0xce,0x08,0x5b,0x1f,0xf4,0x29,0x4d,0x0a,0x3e,0xb3,0x60,0xf4,0x63,0x3c,0x70,0x5d,0x02,0x9c,0x55,0x5e,0x5e,0xd1,0x9b,0xed,0x20,0x75,0x54,0xa1,0x8e,0xae,0xce,0x5a,0xb2,0x2d,0xe4,0xc3,0x9b,0x7d,0x72,0xce,0x7c,0x0c,0xa9,0x99,0xa4,0x12,0xaa,0x31,0xe9,0x61,0x47,0x8a,0x41,0x93,0xd5,0x69 +.byte 0xc5,0xf3,0x9f,0xf4,0x97,0x69,0x64,0x6f,0xf9,0x5b,0xbf,0x58,0xf6,0x3b,0x3e,0xd6,0x93,0x94,0x89,0xcc,0xc0,0x25,0x7d,0xf8,0x40,0x9e,0xb2,0xc8,0x75,0x9d,0x4d,0xf0,0x5f,0xa5,0x3d,0x38,0x67,0xea,0x8d,0x1b,0x60,0x5e,0xfe,0xa8,0x26,0xb9,0xed,0xc0,0xe9,0xc8,0xec,0xb1,0x77,0x0f,0xf2,0xaa,0x77,0x2a,0xcd,0xa8,0x70,0xb7,0xda,0x60 +.byte 0x49,0xb3,0x01,0x95,0xc8,0xac,0x71,0x6a,0xd0,0x49,0x67,0x2a,0x04,0xfc,0x55,0x38,0x08,0x37,0xd9,0x21,0x37,0xce,0x41,0xaf,0x7c,0x33,0xdd,0xcd,0xe0,0x92,0x27,0x38,0x63,0x77,0xea,0x86,0x04,0x99,0x4e,0x61,0x8b,0x8f,0xfe,0x4e,0xc1,0x16,0x6c,0x89,0xac,0x1f,0x0b,0x67,0x75,0x49,0xf4,0xdb,0x6d,0xd3,0xb8,0x1d,0x9c,0xb2,0xe6,0x98 +.byte 0x81,0xae,0x3f,0xe0,0xdd,0xda,0xfa,0x4c,0x8b,0x30,0x18,0x88,0xa1,0x1d,0xa1,0x18,0xb8,0x28,0xc2,0x04,0x6a,0x80,0x02,0x5a,0xe6,0x04,0x85,0xfa,0x54,0x38,0x45,0x64,0xe1,0x50,0x4a,0x38,0x4c,0x85,0xf7,0x00,0x0c,0xd3,0x16,0xcb,0xfa,0x38,0xb4,0x1b,0x6a,0x95,0x3d,0xc3,0x24,0x79,0x0e,0x3e,0x81,0xe6,0xc3,0xd9,0xdb,0x05,0x19,0x7c +.byte 0xb4,0x4d,0xef,0x71,0x22,0x53,0x97,0x8a,0xc9,0xe3,0x69,0x20,0x5b,0x83,0xb1,0x44,0xd7,0xd1,0x1e,0x87,0xa7,0xbf,0xe4,0x84,0x68,0x9c,0x77,0xfe,0x83,0xdb,0x7a,0x53,0xa8,0x53,0x1f,0xc7,0xd1,0x6a,0x26,0x87,0x71,0x06,0x23,0xa7,0xe0,0x18,0x5d,0xfa,0x8c,0xa7,0x24,0xee,0xf6,0x74,0xab,0x17,0xd3,0x46,0x33,0xe9,0xc3,0xcd,0xa6,0xaf +.byte 0xcf,0xa1,0x60,0x75,0x7b,0x77,0xc3,0x58,0xa2,0xe8,0x87,0x7b,0x4b,0x57,0xb1,0x96,0xc1,0x91,0x6d,0xbf,0x71,0xb3,0xbf,0xe2,0x62,0x86,0x72,0xa9,0x01,0x64,0x62,0x32,0x33,0xc8,0xa4,0x26,0x7d,0xfa,0x0d,0xd4,0xd8,0xc3,0xaa,0xc0,0xc8,0x7c,0x51,0xe8,0x10,0x08,0x6f,0xf6,0xc1,0x46,0x89,0xc4,0xd2,0x00,0x1d,0x14,0x05,0x89,0x64,0x52 +.byte 0xcd,0x1f,0x97,0x0b,0x1d,0x94,0xbe,0x9d,0xa0,0x6b,0x03,0x9b,0x83,0x87,0x38,0x0f,0x65,0xdd,0x6a,0xaf,0xf1,0x22,0x74,0x7e,0x11,0xa0,0xdf,0x1e,0x95,0xef,0x1a,0xdc,0x8b,0x29,0x4a,0xbe,0xfd,0x2f,0xc7,0x48,0x94,0x3f,0xb9,0x8c,0x8e,0xe1,0x0c,0x54,0xa6,0x2f,0xa5,0x2b,0x71,0xdd,0x16,0x68,0x91,0x35,0xd0,0x22,0x48,0x1f,0xf2,0xe2 +.byte 0xe8,0x57,0x83,0xd7,0x49,0x43,0xfd,0xf9,0x77,0xb5,0xfa,0x70,0x19,0xeb,0xae,0xf6,0x31,0xfe,0xd6,0x81,0x6c,0xcc,0x14,0x28,0xa6,0x9f,0x74,0x56,0xc5,0xf6,0x51,0xba,0xc8,0xbd,0x32,0x80,0x5f,0xdb,0x28,0x3f,0x4a,0x55,0x01,0xe1,0x39,0xf5,0x9c,0xda,0xb3,0x42,0xee,0x43,0x17,0xc3,0xc7,0xf5,0xd1,0xda,0xd2,0x2e,0x56,0xcf,0x77,0x0e +.byte 0xdd,0x72,0xcf,0xe5,0xab,0xfb,0xd6,0xa2,0x6c,0x03,0xa6,0x77,0x25,0xf8,0x2a,0x8c,0xfa,0x6f,0x45,0x79,0x59,0x84,0x92,0xd1,0x00,0x58,0xc7,0xb8,0x95,0x4d,0xc8,0x49,0xad,0xe0,0x1e,0x64,0x47,0x00,0xfb,0x93,0x7f,0x3e,0xf1,0x65,0x70,0x47,0x64,0xbb,0x36,0x63,0xe3,0x09,0xcb,0xdb,0x5a,0xd1,0x72,0x83,0xfd,0x15,0x91,0xa2,0x03,0x81 +.byte 0x04,0x98,0x45,0x0f,0x7f,0x23,0x48,0x6c,0xb1,0x2d,0xd0,0x2c,0x61,0x52,0x1b,0x4a,0x52,0x08,0x92,0xe1,0x7a,0xf1,0x8c,0x1f,0x1f,0xdf,0x1c,0xfd,0xd9,0x46,0x99,0x71,0x05,0x58,0x71,0x82,0x5c,0x05,0xa0,0xb2,0x6a,0x50,0xd2,0x6e,0x35,0xf4,0x6c,0xfb,0x50,0x99,0xb3,0xc1,0x2b,0x05,0xaf,0x02,0xe5,0x18,0xfa,0x74,0x09,0xcc,0xa5,0x2c +.byte 0x26,0xfd,0xc5,0xe7,0x2c,0x96,0x0f,0xa4,0x7c,0x88,0xc6,0x7f,0xf9,0x74,0x9d,0x1c,0xe5,0xd2,0x27,0xf0,0xae,0x5b,0x4c,0xbf,0x0a,0x99,0x2e,0xaa,0x54,0xba,0x0d,0x75,0xd9,0x48,0x76,0xf3,0xe9,0xd9,0x01,0xbe,0xaa,0x97,0x09,0xfe,0xb2,0x4a,0xcb,0x55,0xd0,0xe1,0x58,0xec,0x31,0x0c,0xd9,0xdf,0xd9,0x01,0xf9,0x3c,0x28,0x40,0x91,0xbb +.byte 0x4d,0x2d,0x88,0x60,0x31,0xc7,0xc9,0x1d,0xaf,0x22,0x44,0x21,0x05,0x06,0xdd,0x07,0x60,0x29,0x7d,0x49,0x30,0x9d,0x35,0x1d,0x9f,0x37,0xbd,0x32,0xb2,0x21,0xa6,0x4f,0x89,0xd8,0xe6,0x85,0x44,0xcf,0x13,0x12,0x4f,0x5f,0x50,0x71,0x01,0x39,0xff,0x6e,0xa0,0x07,0xff,0xf0,0xa6,0x3b,0x39,0x59,0x17,0xae,0x93,0xb2,0x86,0xcc,0xe5,0x59 +.byte 0x5a,0xf2,0x82,0x62,0xc6,0x8d,0x13,0x2f,0x6b,0x92,0x28,0xbe,0xd1,0xc0,0xf6,0xc9,0xe1,0xd6,0x98,0x94,0x65,0xd4,0x2a,0xdb,0x37,0xb1,0xd3,0x83,0xf2,0xaa,0xa5,0x00,0xf9,0x08,0xe6,0x22,0x38,0x30,0xb6,0x49,0x8d,0x9d,0x1c,0xa4,0xf7,0xdb,0x3c,0x6f,0x75,0x08,0xa0,0xda,0xe9,0xc0,0x01,0x54,0x09,0x68,0xc6,0x7c,0x5b,0x4d,0x88,0x71 +.byte 0xa7,0x2f,0xb3,0x50,0x18,0x4a,0xfb,0x55,0x29,0xf2,0x56,0x1d,0x4c,0x12,0x22,0x1c,0x54,0xd2,0x63,0x67,0xfa,0xe9,0x5b,0x74,0x3b,0x38,0xf6,0xa0,0x85,0x63,0x1c,0x41,0x6a,0x6d,0x71,0x1d,0xb1,0x39,0x28,0x88,0x96,0x9b,0x9c,0x50,0x9e,0x57,0x4e,0xf5,0xa7,0xf4,0x17,0xc6,0xca,0x42,0x84,0x83,0xca,0xa4,0x28,0x72,0x08,0x74,0x62,0xe1 +.byte 0xf0,0x73,0xc5,0x86,0x6c,0x76,0x9d,0xd3,0xa6,0xb8,0x5d,0x73,0x1b,0x02,0xe2,0x69,0x8b,0x59,0xd6,0x6a,0x53,0xe9,0x13,0x88,0x41,0x95,0xe9,0x97,0x5f,0x07,0x62,0xa5,0x21,0x97,0x7e,0x5e,0xc2,0x2c,0xc7,0xaf,0x0a,0xdb,0x9e,0x4f,0x44,0x4b,0xd6,0x3d,0xc0,0x24,0x38,0x50,0x47,0x98,0xa3,0xfc,0xda,0xfc,0xae,0x0e,0x2b,0x9b,0x53,0x0f +.byte 0x6b,0xb1,0x2f,0xd5,0xd7,0x68,0xc9,0xab,0xb9,0xff,0x7f,0x54,0xd6,0x2f,0x88,0xbc,0x5e,0x6a,0x22,0x49,0x0f,0x98,0xbe,0x1f,0xef,0x3e,0xcc,0xa2,0x72,0x6b,0x16,0xbe,0xe8,0x5f,0x0e,0x36,0xa2,0x68,0xe0,0x65,0xd9,0x7c,0xdc,0x8c,0x6a,0x66,0xf0,0x6a,0xfc,0x2b,0x85,0x28,0x2a,0x1a,0xfc,0x92,0x64,0x3d,0x38,0x5b,0xc1,0x0c,0x68,0x45 +.byte 0x94,0x85,0x58,0x82,0x99,0xfc,0x20,0xdd,0x62,0xae,0xed,0x35,0x7c,0x02,0x16,0x9b,0x00,0x8a,0x44,0x02,0x80,0x00,0xca,0x7d,0x95,0x03,0x5d,0xa6,0xec,0xe1,0x0c,0x50,0x34,0x61,0x55,0xee,0xb5,0x11,0xff,0xc3,0xaa,0xf2,0xbc,0xa3,0xa9,0xc7,0x6b,0x16,0xab,0x56,0x7b,0x55,0x54,0x95,0x88,0x15,0x15,0x6a,0x2c,0x97,0xd7,0x7c,0x26,0x65 +.byte 0xaf,0x8d,0xd1,0x05,0x57,0xb2,0x63,0xd1,0x22,0xf7,0x7d,0x77,0x54,0x6c,0x87,0x03,0x1f,0x0e,0x2b,0xae,0xa6,0xa4,0xb5,0xd6,0x95,0x34,0xd0,0x62,0x4e,0xfb,0xcb,0xee,0x01,0xc1,0xf7,0x36,0x94,0xa6,0x54,0x94,0x90,0x0e,0x45,0x9c,0x95,0x89,0x96,0x88,0x32,0x90,0x27,0x48,0xc5,0x96,0xf0,0x7e,0x7f,0x69,0x99,0xdf,0x7b,0xfb,0x2b,0x7b +.byte 0x38,0x10,0x6b,0xd1,0x1a,0xfb,0xf2,0xcd,0x2d,0x8b,0x47,0x21,0xca,0x92,0x64,0x28,0xd1,0x53,0x1d,0xed,0xa7,0x7d,0xa4,0x88,0xab,0xd0,0xfe,0x9b,0x2b,0xf8,0x48,0x94,0x8d,0xd5,0xfa,0x5c,0xef,0x12,0x43,0xdf,0xb6,0x5b,0x83,0x43,0xf3,0xf7,0x1d,0x6f,0x3e,0x44,0xe6,0x20,0xd8,0xbc,0x4a,0x9a,0xed,0xa0,0x79,0x66,0x8d,0x23,0xca,0x35 +.byte 0x15,0x87,0x11,0x50,0xa4,0x40,0x6e,0xfa,0xf7,0xaf,0xa2,0xb7,0x3b,0x9b,0x8b,0x44,0x19,0x90,0xb3,0x47,0x92,0x08,0x2f,0x0c,0xe2,0x95,0x5d,0x80,0xb5,0x93,0x5e,0x1c,0xb5,0xce,0x52,0x0b,0x12,0xc1,0x72,0x2e,0x66,0x8c,0xd1,0x13,0x94,0x36,0xf7,0x17,0xe3,0xad,0x69,0xc9,0x2d,0x21,0x64,0xcd,0x8f,0x2d,0x8f,0x0c,0x85,0xa5,0x23,0x8b +.byte 0x6c,0x00,0x13,0xf7,0x6a,0xb4,0x68,0x1a,0xcc,0xc4,0x03,0x5b,0xd6,0x7b,0x5b,0x34,0x90,0x34,0x3e,0x0a,0x07,0x19,0x81,0x99,0xe9,0xd2,0xa8,0x73,0x2c,0xa2,0xcf,0xdf,0x29,0x69,0xbf,0xec,0xdd,0xa5,0xd3,0x16,0xb0,0xd2,0x9c,0x2f,0xeb,0x70,0x50,0x20,0x3c,0x22,0x1a,0x5b,0x55,0x79,0x76,0x0f,0x1f,0xd0,0x34,0xa9,0x55,0xad,0x75,0x75 +.byte 0x7f,0xa7,0x9b,0xa7,0x3d,0x5d,0x73,0xce,0x91,0xf6,0x9b,0xcd,0xa5,0xee,0x48,0x44,0xba,0xd5,0xad,0xbe,0x1e,0xc6,0xd2,0x8b,0x05,0x21,0x20,0xb5,0x7d,0x78,0x88,0x10,0x20,0x85,0x90,0x8f,0x47,0x74,0x68,0xe6,0x32,0x2a,0x13,0x7a,0xb3,0x5d,0xfe,0x24,0x97,0xd1,0x65,0x55,0x60,0xb3,0x88,0xfb,0x59,0xc9,0x29,0x70,0xf1,0x45,0xbd,0xbe +.byte 0x4d,0x01,0x4e,0x5e,0x5f,0x99,0x52,0xf8,0x5f,0x38,0xcf,0xa8,0x5d,0x69,0x54,0x87,0x72,0x41,0xca,0xc4,0x63,0xc1,0x52,0x58,0x66,0x8b,0xda,0x8b,0x61,0xd1,0xab,0x7d,0x8d,0xfe,0x51,0x8d,0xf6,0xd0,0x21,0x4d,0x0b,0xc5,0xea,0x74,0xcd,0x21,0x93,0x4a,0x91,0xe5,0x3f,0xce,0x35,0x3b,0x3f,0xc0,0xab,0xa4,0x23,0x76,0xd1,0x8c,0xa7,0xbe +.byte 0x15,0xab,0x8e,0xd7,0x0d,0x86,0xac,0xc3,0x06,0xff,0x33,0xf2,0x41,0x6f,0x69,0x58,0x49,0xd1,0x73,0xcf,0x5e,0x4e,0x1e,0x46,0x12,0xfa,0x30,0x0d,0x4b,0xb1,0xfb,0xc6,0xe6,0x0d,0xcd,0x8d,0xca,0x34,0x28,0x5a,0xed,0x85,0x55,0x31,0xee,0xba,0xbf,0xa4,0x6f,0x9c,0x7d,0xeb,0x4b,0x1b,0x73,0xea,0x4e,0xb9,0x62,0x5d,0xac,0xe3,0x53,0xdf +.byte 0x27,0x87,0x2f,0x39,0xca,0x5b,0xd6,0x72,0xcf,0x95,0xc6,0x2a,0xa5,0x3f,0x57,0xfd,0xdc,0xa9,0x4a,0x86,0x0f,0xcd,0xd5,0xea,0xfe,0x85,0xeb,0x9b,0x84,0xc6,0xf7,0xba,0xc2,0x37,0xbc,0x18,0x85,0x49,0xa6,0x7f,0xd9,0x3e,0xfb,0xf0,0x0c,0x39,0xe3,0x1c,0x06,0xfe,0xb6,0x49,0xa3,0x8b,0x72,0x2b,0x39,0xa1,0x48,0xfd,0x1f,0xfe,0xa4,0xf7 +.byte 0xcc,0x7a,0xef,0x64,0xa0,0x0d,0xeb,0x78,0x71,0x8c,0xd6,0x59,0x7c,0xf4,0xaa,0x81,0x7a,0x89,0xe6,0x22,0xc9,0x57,0xe8,0x13,0x9c,0xca,0xc4,0x6f,0xb5,0xbf,0x08,0x31,0x93,0x56,0x2a,0x82,0x00,0x95,0xdc,0x4b,0xfd,0x9b,0xc7,0x8b,0x31,0x72,0xa0,0xff,0xbe,0xb4,0xd6,0x07,0x16,0x0a,0x4a,0x0a,0x96,0x02,0x83,0x53,0x2a,0x4d,0x33,0x72 +.byte 0x1f,0x20,0x20,0xc3,0x63,0xee,0x4e,0x05,0x90,0x7d,0x21,0xd0,0xf1,0xda,0xde,0x0d,0x4a,0x59,0xb9,0xca,0x81,0xe3,0x1f,0x83,0x19,0xdc,0x09,0x03,0x5f,0xaa,0xee,0xbc,0x5a,0xfa,0xc6,0x4d,0x3d,0xfe,0xfe,0xf3,0xdb,0xc3,0x77,0x31,0x74,0xb4,0x94,0xb5,0x09,0xb1,0xb5,0x13,0x47,0x2e,0x4f,0x3b,0x38,0x83,0xf5,0xfc,0xe9,0xcc,0x45,0xea +.byte 0x5b,0x88,0x21,0xba,0x53,0xc5,0xf6,0xd4,0x63,0xc5,0x37,0x1d,0xa1,0x42,0x2e,0x9c,0x9a,0x50,0x2c,0xfe,0xdb,0xf6,0x31,0x36,0x5f,0x9d,0xed,0x63,0x42,0x20,0xdd,0x27,0xe5,0x34,0x3c,0x0f,0x06,0x8b,0x8f,0x32,0xb6,0x47,0xce,0x07,0xcb,0x27,0xc1,0xb7,0xfe,0xb2,0x69,0x81,0x79,0x20,0xd7,0x47,0xbb,0xab,0x61,0x5f,0x09,0x99,0xdf,0x9f +.byte 0xde,0x59,0x33,0x75,0xd1,0xcc,0xfe,0x92,0x79,0x1f,0x2d,0x59,0x88,0xef,0x4b,0x80,0x0c,0x38,0xa3,0xb1,0xef,0xae,0x53,0x84,0x2f,0xbd,0xd3,0x0c,0xcf,0xd5,0xf7,0xb7,0x6f,0xa7,0x22,0x1f,0xf1,0x56,0x76,0x0c,0x78,0x52,0xa3,0xc0,0xd0,0x2f,0xbc,0xdf,0x29,0x0d,0xa8,0x54,0x0d,0x2b,0x65,0x1b,0x7f,0xeb,0x21,0x22,0xaf,0x10,0xc1,0xd6 +.byte 0x30,0xa8,0x2f,0xb1,0x25,0xbf,0xdc,0xee,0xe9,0x35,0x40,0x69,0xa0,0xa0,0x27,0x85,0x2e,0x18,0xc1,0x36,0x24,0xc5,0x96,0x9a,0x85,0x3f,0xbb,0xfd,0xf5,0x02,0xa2,0xa1,0x92,0x3c,0x16,0x48,0x9f,0xc5,0x00,0x7c,0x7b,0xaf,0x31,0xba,0x68,0x0e,0x58,0x88,0xf4,0x10,0xb9,0xa6,0xe0,0x46,0x2a,0xb8,0x8d,0xc7,0x8e,0xad,0x7c,0xec,0xd2,0x74 +.byte 0x92,0xfe,0x1b,0xd0,0x73,0x79,0x0b,0x4e,0xcc,0x2d,0x5c,0xe7,0x80,0x2d,0x21,0x1c,0x97,0xfc,0x2a,0xc9,0x9c,0x07,0x10,0x64,0x8b,0xf7,0xf5,0x1c,0x54,0xb6,0x6c,0x73,0x1c,0x50,0xd3,0x1a,0x2a,0x63,0xcb,0xba,0xd3,0x95,0xe2,0xa6,0xc3,0xca,0x45,0xfd,0x5e,0x1b,0xbb,0x6b,0x4d,0xb3,0xf7,0xfd,0xaa,0xf9,0x73,0xb8,0x74,0x4d,0x36,0x7e +.byte 0xcc,0xaa,0x1e,0xf3,0x20,0x68,0xa5,0x0c,0x03,0xe3,0xbe,0xee,0x82,0x03,0x8d,0x10,0xa6,0xf6,0x6c,0x73,0xc2,0x9d,0x74,0xba,0x57,0x17,0xd7,0xfa,0x85,0xf5,0x1e,0x3d,0xf8,0xc7,0x80,0xef,0xcd,0xf0,0xf4,0x46,0xfc,0x07,0xb5,0xc4,0x5f,0xd2,0x04,0x6a,0x90,0xf5,0x76,0xb6,0xf9,0x73,0x22,0xa6,0x09,0x2f,0xbf,0xb5,0x93,0x9a,0x95,0x05 +.byte 0x95,0xaa,0xf9,0x8c,0x71,0xd6,0xc6,0xd9,0x72,0x50,0xf6,0x58,0x77,0x09,0x47,0x97,0x21,0x42,0xf0,0x30,0x5c,0x3c,0xec,0x60,0x67,0xdf,0x5e,0xd2,0xed,0x0f,0xab,0x25,0x11,0xbb,0xf8,0x34,0x1e,0xbd,0x7f,0xc6,0x52,0x19,0xf5,0x53,0x28,0x46,0x75,0x93,0xce,0xc2,0x0b,0xdf,0xfd,0xa5,0xf1,0xb0,0xa2,0x0b,0x97,0xb5,0x76,0xb4,0x8a,0x2b +.byte 0x82,0x55,0x23,0x29,0xc2,0xd3,0x32,0x94,0x2f,0xf0,0xe6,0x77,0x2c,0xe4,0x6a,0x7f,0xd7,0xee,0x84,0xfb,0xba,0xb8,0x4b,0xae,0x13,0x34,0xbd,0xa8,0x12,0x7a,0x3c,0x28,0x40,0x74,0x5d,0x9a,0x11,0x1a,0xe9,0x74,0x31,0x28,0x3d,0x3d,0x64,0xb7,0x54,0xa0,0x51,0x0d,0xed,0x97,0x94,0x56,0x7a,0x48,0x8e,0x36,0xc9,0xae,0x5f,0xc6,0x79,0x45 +.byte 0x4f,0x07,0xdd,0x13,0x52,0x8b,0xfc,0x3b,0x73,0x44,0x68,0x64,0x51,0x0d,0x95,0x6f,0x0f,0x94,0xba,0xf8,0x40,0x64,0x51,0x43,0x49,0x63,0xc1,0xbd,0xf3,0x39,0x7f,0x6e,0x6f,0x45,0xeb,0xd2,0x33,0x44,0x2d,0x10,0xb4,0x68,0xcb,0xcb,0x8c,0x84,0xc5,0xd4,0x63,0x1d,0x23,0x85,0x30,0x4d,0x6c,0xfc,0xc9,0xa4,0x8c,0xd2,0x42,0x69,0x2f,0x17 +.byte 0x86,0xf0,0x17,0xd0,0xb2,0xaa,0xfd,0x62,0xcb,0xb4,0xfd,0xba,0x29,0xf8,0x85,0x45,0x84,0x9d,0xae,0xf8,0x9c,0x8f,0x64,0xd5,0xb8,0xb6,0xa9,0x64,0xf9,0x39,0x86,0x68,0x29,0xac,0x32,0x87,0x84,0x6c,0xb0,0x09,0xd2,0xdd,0xf2,0xec,0xa1,0x3a,0xfd,0x11,0x37,0x54,0x67,0x29,0x62,0x25,0x62,0xe8,0x6a,0x4b,0x5e,0xde,0x9a,0xf0,0x97,0x73 +.byte 0x66,0x69,0x2a,0x21,0xbe,0x95,0x86,0xca,0xf9,0x17,0xe9,0x4b,0x23,0x83,0x1e,0x8c,0x37,0x47,0x91,0x03,0x3f,0x9f,0xb8,0x60,0x2c,0xdd,0x82,0xbd,0x2a,0xc3,0xe7,0x30,0x8f,0x91,0x2b,0xa4,0x23,0x01,0x03,0xb2,0x8b,0xbd,0xd2,0x1d,0x16,0xf7,0x6a,0x86,0xa8,0xe4,0x54,0x6f,0x9c,0x47,0xa5,0x0f,0xbe,0x94,0x56,0xfa,0x18,0x69,0xbe,0x92 +.byte 0xe9,0xf8,0x24,0x4d,0x65,0x42,0x81,0x1f,0x85,0x52,0xb7,0xc9,0x49,0xde,0xa5,0x4c,0x8f,0x0d,0x5f,0x12,0x68,0x68,0x35,0xce,0x29,0x22,0x5c,0x55,0x3e,0xbd,0xce,0xf2,0x2a,0xec,0x7e,0xe1,0x29,0x0a,0x88,0xf3,0x5e,0xeb,0x27,0xe5,0x52,0xee,0x72,0x37,0xba,0xff,0x82,0x97,0xa9,0x5d,0x77,0x6f,0xb9,0xc3,0xa7,0x73,0xba,0x7f,0x2f,0x7a +.byte 0x19,0x32,0x87,0x56,0xa2,0x89,0xb2,0xb4,0x48,0xbe,0x2e,0x30,0x89,0x0a,0x8f,0x75,0x25,0x25,0x5c,0x46,0xe8,0x02,0x45,0xcb,0x03,0xd1,0xa3,0xeb,0x70,0x71,0x08,0x1c,0x46,0xf1,0x2c,0x43,0xe2,0x44,0x30,0x6a,0x61,0x31,0x45,0x3e,0xbb,0x47,0x33,0x24,0x25,0x13,0xeb,0xf7,0x24,0x66,0x15,0x4c,0xf3,0x07,0x2f,0xff,0xdc,0x37,0x0f,0x71 +.byte 0x85,0xc8,0x56,0xa7,0x2a,0x22,0x87,0x8b,0xae,0x35,0x31,0x29,0x96,0xf0,0x81,0xfb,0x2c,0xbf,0x44,0x69,0x69,0x9a,0x77,0xfd,0xc0,0x2b,0x42,0x16,0x67,0xd6,0xbd,0xd0,0xf1,0xb9,0x40,0x8f,0xd2,0x9a,0x1b,0x2c,0x64,0x78,0x6b,0xda,0x37,0x26,0xae,0x4c,0xee,0x36,0xaf,0x84,0x61,0xe4,0x93,0x22,0x64,0xaf,0xee,0x6d,0x69,0x5c,0xe5,0x85 +.byte 0xd8,0xcc,0xcf,0xf3,0xe8,0x05,0xcd,0xd2,0x09,0x66,0xaf,0xbb,0xc4,0x79,0xb2,0xa7,0xa5,0x09,0xd9,0xf5,0xa2,0x83,0x4f,0xd5,0xf5,0xf3,0x7d,0x7a,0xab,0x94,0x83,0xb3,0x15,0xfb,0x0d,0x1a,0x1d,0x77,0xc5,0x63,0x0b,0x54,0xde,0xa8,0x0d,0xc4,0x16,0xe3,0x89,0xeb,0xa3,0x1b,0xd4,0x77,0x13,0xe3,0x55,0x98,0x15,0xab,0x3b,0x32,0xc8,0xd4 +.byte 0x0c,0x91,0x80,0x57,0xf7,0x1e,0x24,0xd0,0x56,0x78,0x29,0xd2,0x03,0xe7,0xc4,0xd2,0x09,0xca,0xee,0x9b,0x60,0x5f,0xa1,0xfd,0xaa,0x85,0x4b,0x68,0x35,0xa4,0x3b,0xef,0x29,0xb8,0x49,0x85,0xee,0xbb,0x39,0xc0,0xc6,0x99,0x97,0xc6,0x86,0x6c,0x27,0xf9,0x1a,0x19,0x6e,0x7c,0xae,0x75,0x41,0x0d,0x08,0x1e,0xf0,0xb4,0xc3,0x9e,0xdb,0x40 +.byte 0x86,0x94,0x9d,0x90,0x09,0x3f,0xdc,0xb9,0xfc,0x59,0x41,0xc5,0x5b,0x89,0x97,0x49,0x4a,0x1a,0x06,0x68,0x83,0xd8,0x7e,0x09,0x51,0xe1,0x86,0xd8,0x88,0xbe,0x8a,0x36,0x48,0xb3,0x83,0x7b,0x57,0xdd,0x8f,0x18,0x67,0x4a,0x7d,0x68,0xab,0xb9,0x05,0xf0,0xe4,0x27,0x4e,0x33,0x44,0xa7,0x13,0x04,0x94,0xc5,0x57,0xaf,0x36,0x03,0xe8,0x09 +.byte 0x36,0x5b,0xe8,0x92,0xad,0x0a,0x79,0x02,0x24,0x43,0x62,0xc7,0xa5,0xce,0x7c,0xac,0x6d,0x0a,0xf2,0x83,0x33,0x05,0x3b,0x6f,0x9d,0xda,0x96,0x9f,0x8b,0x79,0x3e,0x6c,0xd6,0xba,0x7f,0xea,0x84,0xd8,0x23,0xb6,0x92,0xc3,0x9c,0x7f,0x0d,0xcb,0x7b,0x9f,0xbd,0xc2,0xf5,0x6f,0x71,0x67,0x5f,0x0b,0xd1,0x73,0xb5,0x8c,0x46,0x07,0xcd,0xd8 +.byte 0xee,0x28,0xcf,0x8f,0x8e,0x5c,0xde,0x14,0x78,0xc7,0x60,0xd5,0xf4,0x49,0x97,0x46,0x5f,0x49,0x4a,0xb4,0x8f,0xc9,0xd1,0x52,0x34,0x01,0x29,0xa1,0x46,0x55,0xf8,0x29,0x53,0xbb,0x32,0x1e,0x4b,0x89,0x96,0x53,0x0b,0xf2,0x16,0xf9,0xa7,0x70,0x93,0x59,0x78,0xc0,0x77,0x78,0x9f,0x6c,0xb3,0x0e,0x3f,0x6f,0x40,0x09,0x1d,0xd6,0x66,0x4e +.byte 0xe8,0xb0,0xa1,0x14,0x65,0xc8,0xc7,0x3f,0xd2,0xf0,0x1f,0xfd,0x51,0xe0,0x29,0xd6,0x39,0x26,0x60,0xfe,0x62,0xc2,0xe4,0x45,0x6d,0x01,0xdb,0xd3,0x7c,0xdf,0x48,0x10,0x2f,0xf2,0x8e,0x6c,0xc6,0x58,0xc3,0x7d,0x26,0xb1,0x9d,0x52,0x02,0x2a,0x5f,0x2b,0x57,0xca,0x84,0x9d,0x74,0x31,0x01,0x0f,0xda,0x3d,0x7c,0xbb,0xdc,0x71,0x82,0x8b +.byte 0x42,0xaf,0x49,0x9e,0x2c,0xe8,0xdc,0xa1,0xfb,0x23,0x6d,0xdb,0xdc,0x36,0x01,0xc9,0xb3,0x93,0xd4,0x2e,0x8b,0xd1,0xe4,0xed,0x1b,0xd0,0x4c,0xeb,0xaf,0x96,0x57,0xde,0xee,0x90,0xf4,0xa7,0x58,0x46,0x8a,0xd4,0xa9,0x44,0xe0,0xb3,0x13,0x96,0xb2,0x8a,0xb0,0xd3,0xbe,0x71,0x38,0xb7,0x35,0xa9,0xa8,0x48,0x37,0xa3,0x11,0x0e,0x61,0x36 +.byte 0x6c,0xaf,0x6c,0xf2,0x3f,0xd6,0x55,0xb3,0xa5,0xe0,0xaf,0x18,0x6a,0xf5,0x78,0xb5,0x7c,0xc7,0x48,0x24,0x6c,0xea,0x1e,0x7f,0x52,0xb4,0xe8,0x72,0x46,0xd2,0xbd,0x1c,0x9e,0xe6,0x5b,0x3e,0x9c,0x6c,0x6c,0x6b,0x45,0x0c,0x3a,0xb7,0x67,0x3c,0x8e,0x77,0x77,0xbf,0x50,0xb6,0x30,0x6e,0xe1,0x28,0x0d,0x2a,0x85,0x44,0xf8,0xbb,0xf1,0x14 +.byte 0x89,0xaa,0xc2,0x27,0xf5,0x8e,0xa1,0xd3,0x07,0xba,0xe8,0x03,0xcf,0x27,0x1c,0xa6,0xc4,0x63,0x70,0x40,0xe7,0xca,0x1e,0x05,0xb7,0xb7,0xdc,0xc0,0x07,0x4c,0x0d,0x21,0x12,0x60,0x02,0xe3,0x86,0x65,0xe7,0x1c,0x42,0x86,0xdd,0xdb,0x7f,0x26,0x60,0x01,0x3d,0xd8,0x18,0xcd,0x7a,0x9f,0xf8,0xb2,0xf6,0x6d,0xd3,0xe0,0x57,0x1f,0x80,0x30 +.byte 0x2d,0x5e,0x71,0xdf,0x4d,0x7f,0xcd,0x63,0x77,0x19,0x5e,0x2d,0xd5,0xb5,0xfa,0xa9,0x26,0x02,0xb9,0x62,0x2b,0x57,0x80,0x0a,0xe9,0xbc,0xa4,0x3b,0xa7,0xf1,0xf3,0x77,0x2b,0x6b,0x41,0x5e,0xf7,0xe8,0x66,0x23,0x63,0xac,0xcd,0x58,0xfc,0xa9,0x97,0x6b,0x5a,0x1e,0xe5,0x7d,0xfd,0xb1,0x42,0x7f,0x99,0xdd,0x60,0xaf,0x39,0x46,0x36,0xdd +.byte 0xc2,0x70,0x83,0x53,0xd1,0xc3,0x69,0xc8,0x90,0x0e,0x2b,0x34,0xb2,0x0c,0xb9,0x7a,0xb8,0x6b,0x7c,0xc2,0xf3,0xae,0x41,0x24,0xb8,0x94,0x5f,0xdd,0xce,0xda,0x95,0xda,0x49,0x81,0xb6,0xf8,0xa9,0x8e,0xb3,0x79,0xf8,0x55,0xf9,0xcf,0x8c,0x24,0x99,0xfc,0x6b,0x15,0x0f,0x39,0xac,0xd0,0x3e,0x89,0x9d,0xc2,0x46,0x8c,0x99,0x45,0xfd,0xce +.byte 0x13,0x4c,0x9c,0xc8,0x80,0x87,0x8f,0x7b,0x28,0xe3,0x5e,0x2b,0xe3,0x89,0x7e,0x13,0x52,0x52,0xe9,0x3a,0xed,0x33,0xe7,0x28,0xc7,0x7a,0x48,0x8d,0x0e,0xee,0x24,0xc4,0x61,0x04,0x3c,0xd4,0x7e,0xf3,0x30,0x22,0x07,0x58,0xae,0x02,0xc5,0xd1,0x7d,0x04,0x18,0xca,0xd6,0x04,0xd4,0xc5,0xa4,0xff,0x8d,0x0d,0x68,0xd4,0x1a,0x3a,0x72,0x6f +.byte 0x41,0x1e,0xda,0xc0,0x97,0x7c,0x55,0x2c,0x13,0x20,0x9a,0x07,0x35,0xcc,0xc5,0x83,0xee,0x41,0x77,0x51,0x28,0x07,0xe0,0x81,0xe3,0x9b,0x1f,0xdb,0x73,0x5c,0x8d,0x82,0xa2,0x8b,0xf4,0x92,0x4f,0x70,0xa8,0x6a,0xcf,0xbf,0xcf,0x0b,0x71,0xbc,0xeb,0x81,0xb4,0xc9,0x65,0xe7,0x43,0xef,0x25,0x45,0x27,0xea,0xcd,0x60,0x68,0xcd,0x2d,0x7a +.byte 0xfd,0x88,0x6d,0x06,0xd5,0x92,0x32,0xc3,0x18,0x88,0x64,0xa7,0xde,0x39,0xeb,0x0b,0x5c,0x9c,0xf6,0xf6,0x93,0x90,0x24,0x0c,0x9e,0x0b,0x89,0x1c,0xcb,0xc8,0x96,0x72,0x17,0xae,0x46,0x61,0x69,0x6e,0xbe,0x6c,0xf1,0xa4,0xa4,0x50,0xa9,0x2a,0x47,0xd7,0x80,0xe4,0x72,0xd2,0x3f,0x1a,0xdd,0x82,0xdc,0x12,0x66,0x10,0x26,0x15,0x80,0x56 +.byte 0x4d,0xbe,0x02,0xae,0xe1,0x24,0x8a,0x41,0x52,0xc8,0x5d,0x8d,0x62,0x85,0xbe,0x7c,0x35,0xdd,0x88,0xd3,0xf5,0xf7,0x9b,0xf1,0x5a,0x4e,0x70,0x48,0x31,0x5a,0xaa,0x96,0x1e,0xf8,0x73,0xb4,0x0f,0xb2,0x82,0xf4,0x13,0xac,0xba,0x3b,0x12,0x36,0x1e,0x23,0xbf,0x09,0x8a,0x1c,0x96,0x47,0x56,0x2d,0x16,0x24,0xc3,0x23,0x65,0xe2,0x99,0xd0 +.byte 0xf0,0xa0,0x2c,0x64,0x35,0xad,0x16,0x34,0x67,0x52,0xbc,0x8f,0x17,0x90,0xf9,0xc7,0x4f,0x64,0x6c,0x75,0x3f,0xd7,0x48,0xa4,0x6b,0x43,0xe6,0x2e,0x7a,0xe3,0x79,0xe8,0x47,0x51,0xe9,0x52,0x36,0x30,0xa4,0x24,0x89,0x00,0xd5,0x77,0xbd,0x34,0x2e,0xa9,0x74,0x02,0x25,0xc0,0x0c,0x10,0x31,0xf0,0xa7,0xcb,0x01,0xed,0x43,0x70,0x15,0xe6 +.byte 0xda,0x01,0xb4,0x7a,0x13,0xbc,0xf1,0x57,0x34,0xb1,0xb7,0xb3,0x26,0x18,0x5f,0x42,0x6b,0xcb,0x78,0x25,0x48,0xe9,0xe6,0xe8,0xf5,0x45,0xa2,0x61,0x97,0x10,0xa5,0x7e,0x7a,0x48,0xf3,0x23,0xa5,0x88,0xc0,0xc4,0xc7,0x3b,0x5c,0x0c,0xfc,0xe0,0xf4,0x68,0x64,0xc6,0x9f,0xd9,0x17,0xcb,0xe5,0xba,0x4a,0xa4,0xe0,0x27,0xf8,0x2b,0x4e,0x67 +.byte 0x13,0xab,0xd2,0xce,0xbc,0x8d,0xdf,0x6e,0x49,0xaf,0x72,0x8a,0x51,0xa1,0x78,0x38,0x0a,0x58,0x2e,0x72,0xec,0x94,0x70,0x8d,0xdf,0x0b,0x5a,0x52,0x81,0xb1,0x9b,0xda,0x2c,0xd2,0x85,0xbb,0x8f,0xb0,0x99,0x64,0x24,0xbe,0x03,0xd9,0x92,0x8d,0x29,0xf3,0x41,0x9c,0xd6,0xef,0xef,0xb2,0x5c,0x22,0x90,0xff,0x27,0x4d,0xb3,0x91,0x72,0x9f +.byte 0x42,0xca,0x66,0xc5,0x66,0xb7,0x50,0x3e,0x83,0x6f,0x2d,0xe3,0x7b,0x2a,0xc4,0x5a,0x93,0x92,0x80,0xdb,0x1a,0xdd,0xef,0xfd,0x96,0xcb,0x6a,0xd8,0x4a,0xc5,0x6e,0x36,0x4a,0xe4,0x10,0x15,0xb3,0x12,0xb4,0xd9,0x9e,0x37,0x48,0x96,0xcb,0xe5,0x3a,0x4f,0x57,0xa6,0x46,0x2f,0xd3,0x06,0xb8,0x61,0x1c,0x17,0x3a,0xb8,0xad,0x40,0x50,0x57 +.byte 0x10,0xd9,0xd0,0xe9,0x1b,0xe3,0x18,0x8c,0xc4,0xfa,0x08,0x8d,0x82,0x3c,0x22,0x22,0x1b,0x97,0x64,0xa6,0x8b,0x7c,0x70,0x2b,0xa0,0xd8,0x4c,0x64,0xcf,0xbc,0x49,0x78,0xcb,0x92,0x0f,0xe1,0x60,0x12,0x4e,0x92,0x0d,0xaf,0xa4,0x1f,0xe0,0x2a,0xa5,0x69,0xc6,0xa1,0x91,0x5c,0xdd,0xb8,0xae,0xfa,0xc5,0xb9,0x18,0x31,0x81,0x32,0x6e,0x97 +.byte 0x44,0x2a,0xda,0x58,0xcd,0x9e,0x0d,0x57,0xe0,0xe3,0x5f,0x7b,0x04,0xd8,0xc8,0x68,0xf5,0xa2,0xac,0x0c,0x29,0xf0,0x7e,0xff,0x32,0xfb,0x53,0x1a,0xc2,0xe3,0xae,0xa5,0xe4,0x9c,0x50,0xaf,0xf4,0xde,0x0b,0xdd,0x4d,0xfa,0x65,0x3c,0xbe,0x3c,0xb8,0xda,0x88,0xd9,0x6c,0x55,0x58,0xe1,0x4d,0x00,0xa8,0x1e,0xe2,0x3a,0x9c,0x53,0x9b,0xca +.byte 0xb7,0x5d,0x3a,0x83,0xe0,0xbb,0x95,0xc4,0xd5,0x45,0x48,0xdc,0x12,0xab,0x24,0xfc,0x5d,0x91,0xe1,0xc8,0x0a,0x5c,0x10,0xc4,0xc9,0xaf,0xb6,0x54,0x80,0xfd,0xa0,0x70,0xb9,0xab,0xdf,0x34,0x9f,0x5c,0xff,0xde,0x8e,0xa0,0x0b,0x21,0xcf,0x28,0xc4,0xdf,0x67,0xb5,0xc0,0x20,0x49,0x0c,0x7e,0xe6,0xf7,0x41,0x6b,0x75,0xd9,0x1d,0x3b,0x49 +.byte 0xb7,0x4f,0x01,0xd1,0x20,0x62,0x15,0x1e,0x9f,0x16,0xb0,0xbd,0x30,0x09,0x05,0x00,0x0f,0x25,0x5a,0x37,0xe9,0xa6,0xc6,0xef,0xe5,0x39,0x2b,0xd7,0x6b,0xc5,0x96,0xd2,0xad,0x46,0xaf,0xd3,0xc0,0xfd,0xea,0xff,0x4c,0xaa,0x44,0x48,0x9a,0xdb,0x99,0x44,0x3f,0x4a,0xf0,0x3f,0x81,0x75,0xf2,0x79,0x31,0x3c,0xed,0x56,0xc6,0xf0,0xf1,0x8c +.byte 0xdb,0x1d,0x6c,0x6c,0xcc,0xfb,0xc2,0x30,0xf6,0x24,0x14,0x69,0xc4,0x89,0x4d,0xd0,0x10,0x77,0x37,0x00,0xe8,0xc9,0xf2,0x32,0xf1,0x43,0x8b,0xe1,0x09,0xc4,0x59,0x17,0xf9,0x20,0x2b,0x01,0x76,0x20,0xb8,0x03,0x84,0xf6,0xd7,0x2e,0xef,0x20,0xa6,0xfa,0x8b,0x74,0x7f,0x4a,0x14,0x33,0xad,0xac,0x45,0x66,0x18,0x2b,0x6b,0xd2,0xb8,0x20 +.byte 0x1a,0xff,0xca,0x25,0x69,0xfd,0xba,0x4b,0x5b,0x9c,0x38,0x35,0x4c,0x30,0xa2,0x24,0x3d,0xbb,0xd4,0xf3,0x67,0x24,0xa5,0x93,0xc6,0xf5,0xb2,0xb4,0xa5,0x04,0x53,0xb6,0xe4,0xc7,0xdc,0xf1,0xe5,0x43,0xb7,0x73,0xaa,0xab,0x5c,0xea,0xcb,0xf1,0xeb,0x5b,0x04,0x7a,0xff,0x0f,0x5e,0xb4,0xd3,0x2a,0x39,0x50,0x1b,0x54,0x1f,0x32,0xd7,0x7c +.byte 0xea,0x3f,0xee,0xa5,0xc8,0x46,0x48,0x7e,0x75,0x60,0x7a,0x42,0x42,0xd3,0x15,0x07,0x69,0x46,0x1c,0xe2,0x21,0x31,0x94,0x31,0x24,0x9e,0x39,0xab,0x7a,0xf9,0xc2,0x0b,0x2d,0x6b,0x55,0xa3,0x36,0xb2,0x65,0xf2,0x17,0x08,0xde,0x15,0x83,0x07,0x36,0x12,0x54,0x8f,0x0b,0x23,0xa8,0x7e,0xb5,0x57,0x1c,0x9e,0x29,0xd7,0xd4,0x9b,0xc1,0xf6 +.byte 0x94,0x23,0xf3,0x92,0xbf,0xba,0xc8,0xf5,0x78,0x3e,0x67,0x48,0x14,0x3b,0xd4,0xe9,0x8f,0x78,0xc1,0x4b,0x9a,0x59,0x08,0xaa,0x50,0xf4,0x9d,0xc4,0xc3,0x2c,0xbc,0x56,0x2c,0x13,0x30,0x75,0xfb,0xed,0x48,0xab,0x90,0xec,0x64,0x18,0xb5,0xd5,0xb5,0x7f,0xc1,0x7f,0x83,0xf2,0xdb,0xae,0xde,0xf5,0xb5,0x29,0x03,0xbe,0x80,0xb1,0x5d,0x97 +.byte 0xd3,0x7a,0xa4,0xd0,0xe0,0xce,0x04,0xda,0xaa,0x82,0x19,0xc9,0x02,0xb7,0x1c,0xe1,0x66,0xd9,0x3e,0x86,0x6d,0xb5,0xd1,0x35,0x63,0x8e,0x4b,0xc6,0x58,0x41,0xf9,0xb7,0xba,0xf3,0x06,0x91,0xb7,0xa2,0xfb,0xb5,0x5f,0x53,0xf3,0xe0,0xc1,0xf6,0x91,0x66,0xc7,0x93,0x3a,0x0a,0x72,0xb1,0xed,0x36,0x9d,0xde,0x21,0xdd,0x7d,0x0a,0x7b,0x35 +.byte 0x1f,0xc3,0x56,0xde,0xbb,0xcb,0xb2,0x0a,0xb6,0x84,0xce,0xa1,0xc6,0x1a,0x46,0x2f,0x9f,0x48,0xd5,0x98,0x73,0xa4,0xbd,0xbd,0xa3,0xe9,0xc9,0xc4,0x64,0x89,0xb7,0x9c,0x97,0x7c,0x2f,0x88,0x22,0xe4,0x4b,0x71,0x3d,0x2a,0x47,0xee,0xf8,0xfe,0xe0,0xf7,0x03,0x14,0xe6,0x7c,0x9e,0x57,0xbb,0x8e,0xf5,0xea,0x63,0xfc,0x5b,0x18,0x3b,0xa2 +.byte 0xa1,0x4a,0x28,0x82,0x37,0x77,0x5b,0xc4,0xd3,0xc1,0xf2,0x87,0x13,0x2b,0x2a,0xc8,0xac,0x70,0xe1,0x82,0x38,0x9c,0x12,0xa0,0xc4,0x9e,0x6b,0xac,0x33,0x8a,0xe9,0x31,0x6f,0xa1,0x76,0x94,0x48,0xcf,0xbc,0x78,0x22,0x82,0x6a,0xb0,0xb9,0x49,0x71,0xdb,0xde,0x8b,0x90,0x09,0x82,0x4d,0x79,0x17,0xe8,0xcf,0xd8,0x50,0xc3,0x08,0x07,0x81 +.byte 0x5f,0x9a,0x72,0xce,0x0a,0xe4,0x29,0xc9,0xdd,0x95,0x67,0x58,0xa1,0x14,0xec,0xcf,0x2f,0x29,0xcf,0xce,0xb3,0x35,0x54,0x77,0x67,0x56,0xec,0x95,0x68,0xee,0xbf,0x9c,0x9f,0x74,0x78,0x12,0xd5,0x30,0x83,0x28,0xd5,0x36,0x96,0x57,0xa0,0x8d,0x1c,0x99,0x19,0x04,0xaf,0x25,0xe5,0x71,0x83,0x88,0xb0,0x74,0x38,0xdd,0x8a,0xff,0x39,0x7a +.byte 0xfd,0x34,0x8f,0x9c,0x67,0xa8,0xc8,0x6f,0x13,0x5d,0xf2,0x5b,0x22,0xd3,0x8e,0x63,0x51,0x58,0x9b,0xfc,0xaa,0x89,0x65,0x4e,0x36,0xc4,0xa7,0xef,0x98,0xf9,0xaf,0xcd,0x35,0x8c,0x16,0xbc,0x70,0x4f,0xcd,0x71,0x2a,0xf4,0x13,0xb3,0x3d,0xa3,0x92,0x71,0x45,0xe5,0x9a,0x45,0xbd,0xc5,0x1d,0x82,0x60,0x3a,0x97,0xf3,0x0f,0x96,0x21,0x3d +.byte 0xe5,0x6e,0xfb,0x9d,0x9b,0xeb,0x15,0xc2,0xa6,0x73,0x76,0xf2,0xcd,0xec,0xfd,0x0f,0xf4,0x3f,0x46,0xc9,0x9c,0x73,0xa1,0x21,0x08,0xdc,0x31,0x00,0xaa,0x95,0x07,0xf0,0x3d,0x51,0x57,0xfa,0x6b,0xc3,0x8e,0xe9,0xa4,0x65,0xdc,0xff,0x57,0xb9,0x1f,0x4f,0xc6,0x6d,0x03,0x00,0xa7,0x19,0xb8,0x24,0xb5,0x3d,0x87,0xcb,0x84,0xb7,0xf5,0xfe +.byte 0x51,0x16,0x5b,0xc7,0xed,0x4b,0xff,0xa3,0x66,0x17,0x93,0x60,0x69,0x84,0x8c,0x95,0x74,0xa7,0x30,0x2d,0x09,0xf7,0x4e,0x0e,0x2f,0x99,0xda,0x46,0x34,0x0f,0x93,0x90,0x97,0x4c,0xa6,0x25,0x15,0xb8,0x6f,0x1d,0xd5,0xe1,0xc1,0x39,0x50,0xfd,0xd5,0x79,0x4f,0x04,0x2f,0x76,0x50,0x3f,0x67,0x56,0xad,0x02,0x82,0x30,0x1a,0xaa,0x6e,0xe2 +.byte 0x05,0x6a,0x93,0xb7,0xbe,0xde,0x84,0xce,0xd8,0x53,0xed,0xad,0x95,0xab,0x45,0x1f,0x4c,0x3b,0x22,0x36,0x27,0x45,0x19,0xa4,0x7f,0x12,0x20,0x6c,0x9d,0xeb,0xd2,0xfe,0xd6,0x7d,0x25,0xf9,0xe3,0x64,0x77,0x56,0x89,0x12,0x57,0x80,0xd5,0x40,0xbb,0x2a,0xcc,0xac,0x34,0x8e,0x87,0xfd,0x58,0xc3,0xbd,0x92,0x48,0xd8,0x7f,0xc4,0x39,0x6a +.byte 0x4e,0x1c,0x50,0x93,0xef,0xae,0x81,0x93,0x50,0x95,0x6e,0x46,0x7c,0xf5,0x27,0x44,0x6c,0x21,0x06,0x49,0x89,0x7e,0xf4,0xfa,0x08,0xa5,0xbc,0x0a,0xbd,0xb6,0x7b,0x55,0xac,0x87,0x19,0x33,0xfa,0xab,0xf3,0x15,0xc9,0x1b,0x83,0xf2,0x41,0xf1,0x26,0x6f,0xdf,0x15,0x60,0xdb,0xa6,0x03,0x43,0x3e,0x34,0x7a,0xa9,0xb1,0x38,0x57,0xe4,0x09 +.byte 0x1a,0x4a,0xd8,0x6e,0x28,0xee,0x7d,0x74,0x54,0x03,0xb3,0x29,0x24,0xb3,0xf0,0xc6,0x20,0x7c,0x47,0x01,0x66,0x36,0x7a,0x14,0x18,0x09,0xd6,0xaa,0xa6,0x82,0x5b,0xe4,0x0a,0xf9,0x41,0x52,0x3b,0x56,0xa2,0xf8,0xa2,0xa1,0x2b,0xe0,0x0d,0x1f,0x5b,0xe4,0x0e,0xe1,0x94,0x84,0x6f,0xed,0x2e,0x11,0xfa,0x4a,0xbd,0x41,0xf4,0x3c,0x8c,0x7e +.byte 0x94,0x46,0xec,0x79,0x81,0xb0,0x36,0xfd,0x9c,0x73,0x0f,0x84,0x1a,0x59,0x4e,0x1b,0xd5,0xd1,0x0d,0xff,0xfd,0xb7,0xfb,0x73,0x35,0x8a,0x66,0xed,0xf3,0xee,0x6d,0xf7,0x86,0x0a,0xb9,0xc0,0xf1,0xa3,0xb7,0x32,0x49,0x01,0xe8,0xcd,0xfe,0x82,0x7b,0xf6,0x46,0xd8,0x73,0x47,0x8b,0x7b,0x6e,0x31,0x92,0x0f,0x4b,0x16,0x11,0x86,0x1d,0x02 +.byte 0x5d,0x12,0x79,0x59,0xdc,0x8c,0xaa,0x1b,0xc1,0x75,0x63,0xb2,0xd6,0xbf,0x19,0xb0,0x81,0x70,0x34,0x12,0xd2,0x09,0xbe,0x6d,0xa1,0x31,0x77,0xd2,0x9b,0x59,0xdc,0xcb,0x67,0xb5,0x14,0xcd,0x37,0x31,0x2c,0xa6,0x17,0x58,0x2b,0x24,0xfc,0x2a,0x9e,0x8f,0x38,0x38,0x7a,0x80,0xda,0x8b,0x54,0x1d,0xc9,0x99,0xc7,0x1f,0x98,0x7a,0x1f,0x32 +.byte 0x23,0x1c,0xb5,0x6e,0x53,0xd3,0x61,0xe7,0x78,0x19,0x6c,0xd5,0x2f,0x85,0xde,0xd1,0x67,0x6b,0x9b,0xa1,0x09,0x87,0x5e,0x89,0x5e,0x89,0x21,0x36,0xf2,0x94,0xc1,0xfd,0x6c,0x4e,0xd9,0x6b,0xd2,0xb1,0x1b,0x48,0x37,0x9a,0x7b,0xc9,0x52,0xfd,0xe2,0x6d,0x07,0x19,0xf2,0xa5,0x69,0xdc,0x0b,0x52,0x8f,0xb3,0x87,0x03,0x1a,0xd8,0x43,0x20 +.byte 0x68,0xcf,0x08,0xcc,0xce,0x37,0xf6,0x96,0x7f,0x03,0x62,0xb2,0xce,0x6a,0xfb,0x22,0x54,0xd6,0xfc,0x84,0x5c,0xf5,0x55,0x32,0x36,0x77,0x1d,0x15,0x6a,0x2c,0x3a,0x01,0x34,0xff,0x5b,0x7f,0x3f,0xab,0x97,0x8f,0xbd,0x1d,0x07,0xb9,0x47,0xb1,0xcc,0xc0,0xdf,0x17,0x38,0x54,0x07,0xc0,0x1b,0xb9,0xa2,0x29,0xa6,0x25,0x73,0x32,0x4d,0x5e +.byte 0x51,0x60,0xb3,0x27,0xe5,0xb6,0xdb,0x56,0x81,0x95,0x03,0x7e,0xca,0xc6,0x15,0x8f,0x48,0xd4,0xac,0x71,0x41,0xdc,0x9c,0x86,0x5d,0xd8,0x90,0x90,0x54,0xdd,0x3d,0xf3,0xa8,0xbb,0xe5,0x55,0x69,0x26,0xdf,0xd1,0x8e,0x75,0x2a,0xe4,0xfe,0xe0,0x80,0x1d,0x6b,0xd2,0x8a,0x06,0x49,0x4e,0x60,0xf8,0xbd,0x3d,0x99,0x27,0x80,0x27,0x42,0x66 +.byte 0x01,0x32,0xe1,0x9e,0xa6,0xde,0x7b,0x14,0xa4,0x49,0x68,0x70,0xbe,0xa4,0xe1,0x44,0x2e,0xce,0xa3,0xe9,0x1d,0x7a,0xbd,0xf1,0xe4,0x25,0x11,0x47,0xd8,0xaa,0x32,0x34,0xf8,0xca,0x3d,0xec,0xf3,0x5d,0x8a,0x55,0xe7,0xd4,0x7c,0xfb,0xcf,0xe7,0xa6,0x13,0xaa,0x16,0x5f,0xaa,0x02,0x19,0xdd,0xf1,0xf8,0x5c,0xb2,0x1e,0x68,0x9a,0x21,0x93 +.byte 0xd1,0x38,0x31,0xbb,0x26,0x76,0x44,0xf8,0x84,0x3b,0xf5,0xd1,0x52,0xbe,0x1b,0x8e,0x4d,0xa0,0xb4,0x4a,0x5a,0x7e,0x89,0xe5,0x36,0xb0,0x76,0x77,0xc5,0xc2,0x22,0x73,0xc2,0x19,0x12,0x7f,0xdf,0x9c,0xb8,0xc0,0xf5,0x0e,0xd5,0xa3,0x55,0xae,0x61,0xf8,0xf1,0x6b,0x79,0xc8,0x2e,0xbc,0xa5,0xef,0xd4,0xb1,0x84,0x0c,0x15,0xc4,0xed,0xb3 +.byte 0x18,0x29,0xd6,0x31,0x83,0x79,0x30,0x1a,0x8f,0xf0,0x3b,0xe9,0xd1,0xf2,0x1d,0xec,0xcb,0xe8,0xc5,0x1c,0xb5,0xcb,0x8e,0x01,0xd1,0xb2,0x86,0x43,0x33,0x95,0x70,0x7e,0x75,0xa9,0xa1,0xe7,0xcb,0xd9,0xf4,0xd3,0xe1,0xe2,0xe9,0x46,0x21,0x20,0x3b,0xe9,0x48,0x1c,0x3f,0x93,0x57,0x31,0xeb,0x15,0x9c,0xa7,0xa6,0xcb,0xb5,0xb7,0xa7,0x24 +.byte 0xbe,0x66,0x4c,0x92,0x7c,0xe8,0x8e,0x3f,0x9c,0xa9,0xd7,0xad,0x73,0x68,0x19,0x19,0xd4,0xb5,0x57,0x82,0xdc,0x67,0x3c,0xec,0xac,0x06,0xec,0x86,0x9b,0x65,0xff,0xbb,0xc3,0x90,0x48,0xdb,0x52,0xcc,0xa4,0xf5,0xdf,0x2c,0xc5,0x5a,0xe3,0x30,0xed,0xad,0x37,0x40,0x8c,0xaa,0x32,0x4f,0x94,0x1e,0x14,0x59,0x48,0x1d,0xd3,0xaf,0x80,0xe7 +.byte 0xcf,0x6b,0xa7,0x70,0xe7,0x98,0x22,0x4b,0x40,0x02,0x0c,0x29,0x09,0x0a,0x53,0xf7,0xd4,0xeb,0xbb,0x75,0xb4,0x30,0x1c,0x67,0xea,0xd2,0xb5,0x40,0xfe,0x57,0x2c,0x3c,0x44,0x8d,0x8d,0x02,0x78,0xf0,0x76,0x8f,0x92,0xab,0xb4,0xc9,0xc0,0x2f,0xf5,0xde,0xa7,0x09,0x14,0xf1,0xe5,0x34,0xeb,0x86,0xfa,0xcf,0xcc,0x85,0x1c,0x9c,0xa6,0xe1 +.byte 0x72,0x9e,0xc1,0xe4,0x74,0xc4,0x96,0x5d,0xf4,0x4b,0x23,0x4f,0xa5,0x32,0xff,0x38,0x21,0x8f,0x43,0xe5,0x96,0x20,0x3c,0x78,0xb8,0xb4,0xcd,0x29,0x62,0x84,0x59,0xb5,0xb4,0x57,0x07,0xa8,0x79,0x77,0x21,0xf4,0x82,0xa7,0xb1,0x36,0xee,0x16,0x8e,0xb5,0x9a,0xf7,0x03,0xac,0x64,0x03,0x20,0x48,0x24,0xbc,0xbb,0xec,0x50,0xed,0xa1,0xf3 +.byte 0x67,0xd9,0x34,0xe1,0x0c,0x0b,0xc3,0xd0,0x46,0x0b,0x55,0x85,0x59,0x3c,0xb4,0x7d,0xd0,0xc2,0xe7,0x95,0x24,0x1f,0x53,0x76,0xf1,0x81,0x4a,0x61,0x6a,0x2e,0x3b,0x3f,0x92,0x14,0x7c,0xe0,0x33,0x7f,0xb4,0x85,0x92,0x78,0x0c,0x0b,0xe7,0xbd,0x7a,0x08,0x31,0x7d,0x47,0x3b,0xfa,0xdd,0x90,0x9e,0xf0,0xa9,0xd1,0xa7,0x7c,0x2a,0x37,0xb1 +.byte 0x23,0x71,0x34,0xa0,0x63,0xfb,0x9e,0x8f,0x39,0x00,0xa0,0x09,0xd4,0x1f,0xf4,0xba,0x2d,0xc1,0xac,0x6c,0x94,0x18,0x56,0x3e,0x89,0x92,0x63,0x10,0x5e,0xfe,0x76,0xec,0x4e,0xb6,0x5d,0x59,0xf9,0x94,0x46,0x4f,0xda,0xd5,0x3e,0x6c,0x48,0x49,0x7e,0x7c,0x77,0xe7,0x7e,0x22,0x31,0xb5,0x9d,0x15,0xd3,0x08,0x24,0xdb,0x67,0x98,0x6b,0xfc +.byte 0x45,0x54,0x85,0x29,0x9a,0x47,0xa5,0x60,0xe2,0x46,0x36,0x45,0x16,0x54,0xd6,0xb1,0x5c,0x38,0x45,0xf8,0x43,0x28,0x58,0x81,0xc9,0x57,0x10,0xda,0x3b,0xfc,0x3e,0xe4,0xf4,0xb2,0x16,0xb6,0x16,0x1d,0xa4,0x68,0xa6,0xe0,0x36,0xdb,0xe2,0x19,0x1c,0xce,0x9f,0x94,0xa9,0x94,0xad,0x20,0xcb,0x17,0xd0,0x92,0x37,0x75,0x88,0x0d,0xaf,0xdf +.byte 0x98,0x6d,0x19,0x9e,0x8e,0x61,0xe4,0x8c,0xfc,0x27,0x27,0x6a,0xa7,0xa4,0x66,0x7f,0x08,0x03,0xef,0x5c,0x4a,0xb7,0x89,0xa1,0xae,0xe8,0x70,0x3f,0x13,0x27,0x0a,0x7d,0x5d,0x5e,0x2b,0x69,0xb5,0x98,0x1f,0x25,0x1e,0x41,0xff,0x46,0x5a,0x25,0x1f,0xb4,0x90,0x8e,0x81,0x91,0x19,0x63,0x10,0xd4,0xa9,0xdf,0x3b,0xae,0xe6,0x63,0x1a,0xdc +.byte 0x09,0x5f,0xac,0xaa,0xb8,0x6b,0xbd,0x6a,0x90,0x70,0xce,0x2c,0x63,0x6d,0x48,0x78,0xca,0xc1,0x59,0x94,0xe2,0xc7,0x89,0x17,0x73,0xfa,0x73,0x34,0xb7,0xd3,0x9c,0x4e,0xd8,0xac,0x18,0x80,0x25,0xbf,0xbe,0x75,0x0a,0x9a,0x05,0x5e,0x54,0xcb,0xba,0xab,0xca,0x7f,0x96,0xf7,0x26,0x8c,0x82,0xe0,0x23,0xa5,0x86,0xb5,0xdf,0x31,0xd0,0x2f +.byte 0xe3,0x66,0x96,0x83,0xd2,0x04,0x43,0x8a,0x28,0x59,0x49,0xdc,0x11,0x38,0xd9,0x5f,0xc2,0x31,0xaa,0xa8,0x1a,0xff,0x57,0xf1,0x84,0x18,0x28,0xe8,0x04,0xae,0x98,0xa4,0x17,0xc4,0x35,0x75,0xf5,0x37,0xf5,0x27,0x3e,0x7e,0x32,0xa4,0xcb,0xd4,0x43,0x59,0x02,0x63,0x7b,0x7c,0x9d,0xa7,0x61,0x12,0xf7,0xdc,0x12,0xe0,0x07,0xac,0x96,0xf3 +.byte 0x71,0x43,0xe5,0x30,0xe0,0x4c,0x51,0x2a,0x19,0xf5,0x79,0x59,0x5a,0xc5,0x74,0xfa,0x54,0x18,0xb4,0xb1,0xfb,0x4b,0x9b,0xf8,0xe4,0xa4,0x63,0x25,0xc3,0x84,0xeb,0x2e,0xa1,0xf8,0xf8,0x7b,0x25,0x6a,0x7d,0x14,0x38,0x06,0xeb,0xae,0x9f,0xa5,0x80,0x9a,0x8a,0xb6,0x46,0x95,0xdf,0x52,0x11,0xd4,0x30,0xcc,0x11,0x8f,0x4a,0x5e,0x56,0x26 +.byte 0x60,0x3d,0x5f,0x0b,0x04,0x94,0xcd,0xca,0x1d,0x6b,0x83,0x51,0x83,0x8d,0xf8,0x33,0x4a,0x91,0x00,0xa4,0xf5,0x44,0x5b,0xad,0xa0,0x4a,0x72,0xaf,0xe6,0x4a,0x0d,0x1e,0x9f,0x18,0x6b,0xb4,0xdf,0x85,0x61,0x2a,0x3b,0xe1,0x4c,0xaa,0xc3,0x17,0xef,0x51,0x9f,0xae,0xb5,0xca,0xaa,0x6c,0xd9,0xa1,0xf5,0xa3,0x6f,0x1c,0xca,0xb3,0x37,0xda +.byte 0x27,0xea,0xcb,0xb7,0x36,0xb2,0x11,0xda,0x9f,0x07,0x78,0xaa,0x6c,0xad,0x63,0x9b,0x49,0x6b,0xfe,0x1f,0x93,0x82,0x73,0xc9,0xc8,0xf6,0x68,0x54,0x50,0x77,0xba,0x78,0xc7,0x82,0xee,0xbd,0x97,0x66,0xb9,0x22,0x49,0x0d,0x7a,0x1f,0x0f,0x4e,0xe5,0x02,0x8b,0xa6,0x1b,0x11,0xfc,0xa6,0x37,0x2a,0x5c,0x66,0xaf,0xac,0xa5,0x9f,0xbf,0x26 +.byte 0x98,0x9b,0x25,0x44,0x48,0x09,0xe6,0x76,0xb9,0x08,0xf1,0x37,0xcf,0x86,0xc9,0xdf,0xa8,0xf3,0x88,0x2f,0xc1,0x33,0x15,0x95,0x59,0xf7,0x9b,0xf2,0x48,0x76,0xcb,0xd0,0x31,0xe4,0x27,0x74,0x2d,0x6e,0xd2,0xc3,0x29,0xea,0xef,0xff,0x4e,0x3d,0xda,0x3e,0xef,0x94,0x94,0x40,0xcd,0x93,0xcf,0xb8,0x56,0x29,0xf8,0x20,0x20,0xa3,0x66,0x83 +.byte 0xba,0xc8,0x4f,0xe6,0x22,0x96,0xb5,0xb2,0x44,0x75,0x55,0x98,0xed,0x11,0xd0,0x58,0x50,0x26,0xf1,0x4a,0xf6,0x80,0x5c,0x17,0x92,0xba,0xc2,0xd6,0x68,0xd4,0x7a,0x4f,0xdf,0x16,0x97,0xbd,0xad,0xd7,0x1b,0x0c,0xe5,0x23,0xa9,0xaa,0xf4,0x1c,0x8d,0xec,0xbf,0xf0,0xb5,0xaa,0x49,0xfd,0xf1,0x31,0x9b,0xf9,0xe9,0x21,0xa1,0x20,0xab,0xbe +.byte 0x56,0x8c,0xf2,0x85,0xdc,0x1f,0xea,0x25,0xce,0xf5,0x6c,0x18,0x7d,0xc4,0x1a,0x01,0x08,0x01,0xed,0x02,0xa8,0xac,0x7f,0x74,0x2c,0xd7,0x28,0x25,0x6e,0x68,0x19,0x38,0x8d,0x20,0x51,0x8f,0x38,0x8b,0x03,0x36,0xae,0x50,0x35,0x28,0x65,0x7e,0x15,0x2a,0x80,0x2c,0xae,0xcd,0xb3,0xb6,0x91,0xf1,0x8c,0xf2,0x8c,0xc5,0xce,0x3e,0x3a,0x97 +.byte 0x5a,0xff,0xe1,0x37,0x13,0xf7,0x6b,0x07,0xb2,0xaa,0xaa,0x57,0x18,0xb7,0xb2,0x19,0x52,0xbf,0x59,0x0b,0x6f,0xba,0x56,0x54,0x14,0xac,0x21,0xfd,0x7d,0x03,0x4b,0x0b,0x39,0x54,0xba,0xf9,0xba,0x73,0xcd,0x67,0x13,0x30,0xca,0x19,0x80,0x4f,0x18,0xb4,0x75,0x2a,0xec,0x78,0xa7,0xd0,0x5c,0x53,0xe2,0x43,0x2c,0x08,0x5f,0x5c,0xe6,0x60 +.byte 0xde,0x04,0xf6,0x75,0xca,0x35,0x3b,0xf6,0x68,0x53,0x60,0xc0,0xed,0xb0,0x15,0xa1,0xa4,0x89,0x23,0x34,0x49,0x35,0xd2,0x78,0x4b,0x8f,0x7c,0x8d,0x59,0x22,0x9f,0xad,0x72,0x47,0x5b,0xde,0xf2,0x09,0x08,0xa0,0x8d,0x5f,0x4d,0xc3,0xd1,0x83,0x17,0xbc,0x39,0x8e,0xa5,0x53,0xaa,0xe3,0x31,0x03,0x93,0x14,0xb4,0x57,0xf0,0xdf,0x54,0x1d +.byte 0x79,0x4d,0x21,0x1a,0x8f,0x3f,0x6e,0x07,0x41,0xcc,0x2d,0x94,0x55,0x4e,0x50,0xfd,0xac,0xe3,0xef,0xa7,0x50,0x3b,0x3c,0xda,0x32,0x25,0xee,0xd9,0x01,0x37,0x8e,0xb3,0x23,0xc5,0x5e,0x12,0x88,0x6d,0xd5,0x41,0xfd,0x3f,0xfa,0x75,0xb8,0xcb,0x82,0x10,0x81,0x38,0x1b,0x10,0x2d,0x2c,0x6b,0x62,0xa1,0x7c,0xd1,0x75,0xd8,0x8c,0x0c,0x2f +.byte 0xe8,0x97,0xff,0x18,0xb3,0x12,0xa2,0xef,0x6c,0xc5,0x79,0x9f,0x64,0xf3,0xc7,0xdc,0xdb,0x54,0xa4,0x25,0xc7,0x30,0xfb,0x6c,0x5a,0x50,0x24,0xf9,0xb6,0xc9,0xe7,0xda,0x78,0xcc,0x1b,0x5e,0xf3,0xe7,0x32,0xd8,0x36,0x47,0x10,0xe5,0x2c,0xeb,0xea,0xf7,0x25,0x30,0x93,0x64,0x88,0xc8,0x59,0xf8,0x5c,0x02,0x43,0x4c,0x23,0x8e,0x1c,0x42 +.byte 0xe4,0x36,0x39,0xbf,0xba,0x8b,0xe3,0x53,0x01,0x32,0x0d,0x89,0xc2,0xea,0x35,0x94,0xf1,0x0d,0x29,0x45,0x08,0x07,0x15,0xcb,0xd7,0x3e,0x4d,0x9f,0x04,0xd8,0x18,0x8a,0x56,0xa3,0xb1,0x1c,0x46,0x19,0x8b,0xd0,0x51,0x30,0xf3,0xca,0x52,0x2a,0x16,0xc4,0x90,0xc1,0x00,0x50,0x87,0x8b,0x4c,0x71,0x61,0x48,0x69,0xb2,0xf1,0x33,0xaa,0x79 +.byte 0x81,0x8b,0x36,0x33,0x19,0x41,0x6b,0xc1,0x91,0x40,0xf2,0xcc,0x1d,0x83,0x09,0xab,0xcc,0x6f,0x6c,0x54,0x91,0x62,0x80,0xac,0xe6,0x1f,0xcd,0x5d,0x05,0x2b,0xe5,0xac,0xbc,0xd6,0x1b,0x8b,0xef,0x95,0xa0,0xf3,0xfe,0x8e,0x4d,0x32,0x77,0xe8,0x02,0x8f,0x44,0xad,0xc4,0x40,0xc3,0x99,0x68,0x81,0x47,0x15,0xbd,0x3b,0x8f,0x0b,0x9b,0x3a +.byte 0xb3,0x9d,0x8f,0x3d,0x86,0xd1,0x89,0x5f,0x67,0x19,0x33,0x2d,0x18,0x64,0x0e,0x3a,0x13,0xa4,0xe9,0xb4,0xc9,0x90,0x09,0x6a,0xcb,0x5d,0x0d,0x83,0x13,0x04,0x29,0xe5,0xa5,0xf4,0x00,0x56,0xf4,0x80,0x96,0x33,0x93,0xe4,0x9b,0xc4,0x6e,0x38,0xbf,0x0a,0xe0,0xee,0x8c,0x89,0x5d,0x60,0x36,0x7e,0x69,0xc2,0xc7,0x28,0x6f,0x2b,0x97,0xfb +.byte 0xb3,0x5b,0x82,0xe8,0x9a,0x36,0x44,0xd7,0x1f,0x9b,0x1b,0xd0,0x14,0xe4,0xd4,0x0d,0x35,0xcd,0xee,0x88,0x50,0x37,0x5c,0x88,0x09,0xa5,0x16,0x4d,0xe1,0xbc,0xe8,0x79,0x8f,0xa9,0x18,0xb8,0x43,0xb4,0xd7,0x32,0xcd,0x26,0xdd,0x78,0x29,0x59,0xad,0x29,0xe3,0xe0,0xe7,0xcf,0x16,0x03,0xc6,0x8a,0xb6,0xa2,0x09,0x9a,0x6e,0x90,0x7b,0x0c +.byte 0x9d,0x20,0xb6,0xc4,0x28,0x3f,0x44,0x06,0xa9,0x45,0x72,0x27,0xa7,0x56,0x3f,0x07,0xff,0x13,0xd9,0x80,0xda,0xbd,0x25,0xad,0xd3,0x74,0x2c,0xd8,0xd2,0x93,0xa5,0xda,0xbc,0x5f,0xa5,0xde,0xb7,0x3a,0xf0,0xd2,0x17,0xb1,0xc3,0x70,0x2a,0x85,0xde,0xf0,0x97,0x7b,0x96,0xb2,0x0e,0x45,0x7f,0x63,0xd4,0x94,0xd8,0x78,0x05,0xcf,0xea,0xb3 +.byte 0xfb,0x7a,0x79,0xb5,0x91,0x53,0xb8,0x8c,0xa2,0x03,0xf4,0xc3,0xed,0xf0,0xab,0x33,0x5c,0x6e,0xcd,0xbd,0x73,0xe3,0xe9,0xd0,0x83,0x2a,0x2a,0x68,0x32,0xf1,0x69,0x4f,0xd0,0x8b,0xe8,0xa1,0x7d,0x5b,0x0f,0x69,0xc2,0x33,0xbf,0xc1,0x54,0x29,0x47,0xed,0x9f,0xdb,0x35,0x0a,0x3d,0x2b,0x9d,0x8b,0x91,0xb6,0xe0,0xbc,0x53,0xba,0xb7,0xcd +.byte 0x2c,0xd9,0xeb,0x81,0xa0,0x2e,0x14,0x6e,0xdc,0xe1,0x90,0x36,0x14,0x9d,0xa8,0x8b,0x6b,0x1b,0xac,0x4c,0x09,0x8b,0x1a,0x87,0xf4,0x66,0xf6,0xfb,0x62,0x92,0x13,0xcf,0xb2,0x96,0xf0,0xc9,0x8b,0x12,0x99,0xf1,0x16,0xae,0x5c,0x27,0x24,0xa8,0xfd,0xb3,0x4c,0xc2,0xe6,0x3f,0xd2,0xc6,0x0c,0xf2,0x65,0x4e,0xdf,0xf1,0x06,0xb8,0x99,0xc4 +.byte 0x3a,0x35,0xba,0xed,0x18,0x3e,0xfa,0x03,0x51,0x8d,0x45,0x68,0x12,0x7b,0xb6,0xac,0x63,0x99,0x47,0xee,0x6f,0x8b,0xcb,0xc1,0x0a,0xf9,0x23,0xf0,0x05,0xe1,0x03,0x4a,0xb5,0xe0,0x65,0x71,0xc8,0x64,0x7e,0x0d,0x39,0xe7,0x96,0xdb,0x34,0x63,0x2e,0x1a,0x27,0x85,0x52,0x63,0x8e,0x44,0xfb,0x61,0xca,0x79,0xe5,0x91,0x99,0x83,0x2d,0xe0 +.byte 0x26,0x04,0xad,0x43,0x26,0xf2,0x7e,0x56,0xae,0x35,0x6a,0xfb,0xec,0xc6,0x27,0xe4,0x3a,0xa3,0x6b,0x63,0x72,0xba,0x98,0x03,0x9f,0x2a,0x4c,0xb1,0x33,0x22,0x9d,0x53,0xf6,0x00,0xa3,0x1e,0x32,0xcb,0xbe,0xe0,0xc2,0xf8,0x71,0xcd,0x3f,0xe3,0x4d,0x83,0xf2,0x9f,0x1c,0x91,0x35,0x97,0x52,0x95,0xba,0x24,0x04,0x04,0xca,0x32,0x6d,0xd7 +.byte 0x4b,0xd4,0x9e,0x8b,0x73,0x42,0xfb,0x9f,0xfc,0x93,0xea,0xc2,0x41,0x56,0xa9,0xe5,0xdd,0xd0,0x37,0x8a,0xe2,0x92,0x9f,0x45,0x4f,0xd8,0xef,0xe6,0x6f,0x58,0x41,0x5f,0x7b,0xe7,0x0f,0x32,0xce,0x06,0x02,0x7f,0xe2,0x37,0x87,0xb7,0x35,0x72,0x68,0x87,0xc9,0x35,0xa8,0x51,0xce,0xd8,0xde,0xc3,0x8c,0xb4,0xab,0xf4,0xa7,0x3b,0xcd,0xc8 +.byte 0x0a,0x56,0x5b,0x48,0xb1,0xa4,0x27,0xa8,0x9e,0x3e,0x04,0xbc,0xb3,0x63,0x3e,0xd5,0xf7,0xae,0xec,0x0c,0x6e,0x4a,0x73,0xb6,0xed,0x66,0xea,0xc1,0x7a,0xc4,0xaa,0x21,0x27,0x62,0xef,0x3d,0x1d,0x51,0x8b,0x63,0xe6,0xe2,0x8a,0xed,0x7a,0x4b,0x90,0xc3,0x9f,0x91,0xb4,0x8f,0x78,0x65,0x9c,0xdd,0x0a,0x7a,0x50,0x36,0x33,0x30,0x3b,0xb4 +.byte 0xdf,0x67,0xbd,0xfd,0x71,0xfc,0x40,0x49,0xaa,0x01,0xdf,0x68,0x67,0x73,0x31,0x2c,0x98,0x2f,0x8c,0x9e,0x2d,0xce,0x4a,0x71,0xbc,0x6f,0x90,0x1d,0xc0,0x37,0x07,0x30,0x0c,0xa3,0x04,0xfb,0xd1,0xd0,0x0e,0xcb,0xdc,0x94,0x06,0x7f,0x83,0xe5,0x45,0x47,0xd0,0x71,0x06,0x94,0x23,0x7c,0x03,0x80,0x46,0xa5,0x10,0x08,0xd1,0xdb,0xfb,0x9d +.byte 0xd4,0x05,0x01,0x5e,0x66,0x4d,0xf9,0x32,0x9b,0x5b,0xfe,0x7a,0x60,0x63,0x77,0x9a,0x31,0x34,0xe5,0x9a,0x82,0x2d,0x2b,0xb7,0xe0,0x04,0x8f,0x86,0xf3,0xb2,0x16,0x86,0x50,0x37,0x9d,0x80,0xe7,0x62,0xdf,0x77,0xda,0xf4,0xfc,0xb7,0x42,0x9d,0xac,0xcb,0x11,0xff,0x0c,0x6f,0x4e,0x16,0x0c,0x59,0x04,0x05,0x8f,0x88,0x64,0x37,0xe6,0x6c +.byte 0xee,0x64,0x58,0x79,0x60,0xd4,0x2f,0xb7,0x90,0x59,0xfb,0x82,0x3b,0x20,0x2e,0x2b,0xba,0x15,0xfb,0xf7,0x5b,0x1d,0x81,0x8a,0x8a,0x8f,0xe3,0x39,0x92,0x34,0xfc,0x3a,0x67,0xce,0xb6,0xa0,0x9b,0x56,0x78,0x96,0x4d,0x32,0xbf,0x9c,0x83,0x9e,0x19,0x66,0x20,0x42,0xb2,0x78,0x62,0x42,0xdd,0xdf,0x98,0xab,0x0c,0x3d,0x41,0xb5,0x74,0xc1 +.byte 0x2d,0xf0,0x02,0x58,0x6e,0xb3,0x4d,0x7b,0x41,0x1c,0xf1,0x09,0xc1,0xbb,0x84,0x67,0xf8,0x24,0x77,0x32,0xcd,0x7a,0x63,0x87,0x0d,0xf2,0xc5,0xaf,0xe4,0xb5,0xc6,0x3b,0xad,0x66,0x5e,0xae,0x90,0xc2,0x24,0x27,0x7a,0x0b,0xed,0x1b,0x86,0x5d,0x02,0x19,0x85,0x78,0xc8,0xb1,0xce,0xe7,0xc9,0x5c,0xce,0x43,0x58,0xac,0x1c,0x4e,0xcd,0xb8 +.byte 0x3a,0xb8,0x7a,0xf3,0x79,0x4b,0x97,0xcf,0xbe,0x88,0x24,0xd0,0x9a,0x5a,0x55,0x43,0x0c,0x48,0xa2,0x7f,0xaf,0x4b,0xd8,0x16,0x02,0xfb,0xe6,0x0c,0x6b,0x85,0xb4,0xb8,0x5e,0x40,0x60,0x5d,0x93,0x51,0xc6,0x32,0xb9,0x4a,0x23,0x96,0x71,0xeb,0xe8,0xe8,0x01,0x1e,0x85,0xb0,0x47,0xde,0x86,0x15,0x52,0x3a,0xb2,0xd3,0x86,0x4b,0x78,0x09 +.byte 0x9c,0x6e,0x9d,0xd9,0xef,0xe8,0x64,0x2d,0x2a,0xec,0x21,0x5a,0x60,0xa5,0xe4,0x26,0xbb,0x79,0x0c,0xdb,0x48,0xd6,0x4b,0x5c,0x5b,0xe3,0x34,0xc9,0x96,0xf0,0xcb,0x68,0x8a,0x2d,0xee,0xa3,0x37,0x34,0x5f,0x3e,0x65,0x40,0xce,0xe1,0xc8,0x2e,0x11,0xca,0x42,0x51,0x53,0x72,0x3d,0xa9,0x68,0x54,0xb4,0xd8,0xd7,0x72,0x84,0x8d,0xcd,0x6d +.byte 0x1f,0x0e,0x0c,0x0f,0x32,0x3a,0x7d,0xdd,0xc1,0xd3,0xe7,0x2d,0x1f,0x52,0x8b,0x73,0x86,0x70,0x2a,0xcb,0x71,0x37,0xa1,0xab,0xe3,0x94,0x5a,0xd7,0x9d,0x68,0xc1,0x6e,0x5d,0x72,0x25,0x81,0xe8,0x45,0xad,0x6c,0xf8,0xdb,0x9b,0x70,0x31,0xb9,0xf0,0x4f,0x23,0xd7,0x03,0xc8,0x87,0x43,0x51,0x7a,0x55,0xfe,0x6f,0x2d,0x40,0xbc,0xfe,0xdf +.byte 0xe6,0x21,0x4b,0x4d,0xc6,0x02,0x48,0xe7,0x7a,0x2a,0xef,0x91,0xdf,0xbc,0x98,0x91,0x6f,0x59,0xc4,0x47,0x77,0x2e,0x45,0x45,0x23,0x47,0x5d,0xf8,0x50,0x41,0x84,0x75,0x8a,0xe7,0x4d,0xfb,0xeb,0x58,0x00,0xcf,0x42,0xca,0x02,0x05,0xc7,0xfa,0x11,0xfb,0x6e,0x90,0x7d,0x53,0xa0,0x19,0x23,0x24,0x8f,0x89,0x17,0x40,0xbe,0x11,0xfb,0xd9 +.byte 0x04,0xf8,0x84,0xeb,0x90,0x7c,0x84,0x45,0x9c,0x53,0x45,0x5e,0x45,0x51,0x55,0xfc,0xf1,0x6b,0x02,0x24,0xfd,0x95,0x4a,0x40,0x80,0xdc,0xa6,0x94,0x15,0x2c,0x1d,0x85,0xa0,0x07,0x8d,0xf8,0xf2,0x95,0x0c,0xa0,0x4e,0x5a,0x5b,0x29,0x09,0xcc,0xf3,0x4e,0x8e,0xea,0xe8,0x26,0xb8,0xbe,0xb2,0x6f,0x76,0x6f,0xa4,0xe5,0x6a,0x50,0xcf,0xc8 +.byte 0x7d,0xb6,0x1e,0x9d,0x90,0x6b,0xde,0xe2,0x55,0x49,0x97,0x00,0xa5,0xc5,0x1f,0x1c,0x41,0x66,0xe7,0x6b,0x20,0xb2,0x1e,0xc7,0xb3,0xd4,0xa9,0x75,0xbb,0x83,0x24,0xd0,0xdf,0xbd,0xba,0x2c,0x2f,0xa4,0x03,0x1d,0x17,0xc5,0x74,0xc2,0x6a,0x20,0x71,0x18,0xd1,0xc5,0xb0,0x78,0xfe,0xda,0x55,0xd2,0x43,0x2a,0xd8,0x88,0x74,0x75,0x86,0x07 +.byte 0xe9,0x8b,0x0d,0x0f,0xe5,0x8d,0xe8,0x3d,0xf4,0x93,0xde,0x4c,0x97,0x98,0xe2,0x9b,0x22,0xde,0x13,0x18,0x8b,0xc5,0xe1,0x6f,0x6d,0xb4,0x19,0x46,0xff,0xbd,0xa6,0x2e,0xe6,0x48,0xcd,0x66,0x22,0x7d,0xf4,0x0e,0xeb,0x74,0x25,0x5c,0x90,0x0e,0x26,0xce,0x17,0xe9,0xdb,0x30,0xb9,0x25,0x99,0x96,0x46,0x3a,0x78,0xa3,0x76,0x2d,0x9e,0x42 +.byte 0x06,0x8a,0x1e,0x62,0x46,0xa4,0xd0,0x1d,0xe2,0x4c,0x3c,0xb4,0x4c,0xc0,0xd1,0xf7,0x05,0x5b,0xe4,0xd4,0x71,0x73,0x31,0xfc,0x98,0x2a,0x55,0xb0,0x78,0x92,0x59,0x8b,0x25,0x97,0x15,0xf2,0xf9,0x57,0x8b,0x7c,0xd4,0xc4,0x47,0x2f,0x10,0x3b,0x76,0xde,0x5f,0xb1,0xdf,0xdc,0xb0,0x15,0xd5,0x4a,0xd2,0x54,0xad,0x5e,0x32,0xf4,0x5a,0x1a +.byte 0x8d,0xe8,0xa0,0x4a,0x4e,0x04,0xdc,0xdd,0xd2,0x57,0xe5,0x24,0x4b,0x93,0x51,0xef,0xd4,0xba,0x3f,0x77,0xfc,0x0a,0x5c,0x7d,0x6e,0xa7,0x86,0xe5,0x88,0xd1,0xac,0x74,0x46,0x9a,0x39,0xb6,0x98,0x3d,0xae,0x89,0x4e,0xea,0x8d,0xdc,0xc7,0xb9,0x0c,0xd7,0xa6,0x06,0x4d,0x28,0x2b,0x51,0x2b,0xdb,0x30,0x4a,0x91,0x1c,0x40,0x89,0xe4,0xba +.byte 0x72,0xd5,0xed,0x16,0x66,0xb8,0xef,0x81,0xd9,0x51,0xf8,0x1b,0xff,0xab,0x8b,0x52,0xb8,0xf3,0x11,0xb3,0xe5,0x04,0x5a,0xb0,0x60,0xa3,0x35,0x12,0x6a,0xa0,0x75,0x5c,0x21,0xa9,0x5a,0xe8,0xd3,0xd7,0x8a,0x1f,0xe0,0x9b,0xb7,0x1e,0x7d,0xbe,0x81,0xaa,0x56,0x5a,0xd8,0x2d,0x7e,0x0c,0x60,0xb2,0x68,0x26,0x6d,0xaa,0x8b,0xcc,0x11,0x40 +.byte 0x25,0xea,0xc9,0x94,0xfb,0x3b,0x9b,0xa7,0x3a,0xde,0xd9,0xfe,0x6b,0x4b,0xfc,0x3f,0xbf,0xdd,0x51,0x9b,0xa1,0xca,0x2f,0xed,0x33,0xd8,0x3d,0x92,0xa4,0x1d,0xee,0xb2,0x47,0xd0,0x72,0x6a,0x96,0x33,0x0f,0xdd,0x0a,0xd9,0xbd,0x86,0xdb,0x25,0x53,0x0e,0x3c,0x31,0xad,0x05,0xb9,0x24,0x13,0x00,0xdf,0xc2,0x7c,0x3d,0x03,0x9b,0xf6,0x6d +.byte 0x93,0xd9,0xdf,0x73,0xf8,0x1c,0x98,0xe2,0x77,0x46,0x46,0xdc,0x07,0xe6,0xbb,0xc1,0xa7,0xb6,0xbe,0x21,0x07,0xae,0xdb,0xca,0x69,0x2d,0x8a,0x2b,0x59,0x27,0xe0,0x7c,0xf0,0xf1,0x34,0x69,0x97,0x44,0xba,0xbb,0x48,0x9f,0xd9,0xd8,0x16,0x1a,0xef,0x11,0x68,0xb6,0xaf,0x3a,0x10,0xc6,0x7c,0xd1,0x12,0xc7,0x89,0x47,0xe3,0xd1,0x24,0xc6 +.byte 0x44,0x9f,0x7e,0x6a,0x66,0x43,0x48,0xd6,0x9f,0x7b,0xf0,0x1f,0xd2,0x5f,0x2b,0xa7,0x13,0x6a,0x7c,0x70,0x08,0x38,0xb0,0x00,0xbc,0x7c,0xd3,0x01,0x9b,0xf6,0x29,0xd3,0x9c,0xa4,0x11,0x90,0xe4,0x9f,0x04,0xd6,0x21,0xec,0xfd,0xcb,0xb8,0xe6,0xb6,0x49,0x2b,0xfa,0x4b,0x90,0x9e,0xc6,0x0c,0x87,0xff,0x5e,0x2e,0xcc,0xf8,0x09,0x70,0x52 +.byte 0x42,0xec,0x88,0xac,0x1e,0x76,0x2b,0xeb,0xfc,0xb3,0x65,0x81,0x34,0xb1,0x06,0x90,0xde,0xb2,0xc4,0xd3,0xfd,0xd4,0x9c,0x78,0x1a,0x5c,0x8f,0x65,0x0a,0xbd,0x88,0xe5,0x95,0x06,0xb5,0x94,0xe5,0xbf,0x90,0x31,0xbb,0xcb,0xce,0x19,0x51,0x25,0x4a,0x47,0x35,0x26,0x93,0xdb,0xe2,0x93,0x36,0x47,0x7d,0xdd,0x4e,0xd5,0xeb,0xdd,0x63,0x1c +.byte 0xbc,0x2d,0x75,0xdb,0xd4,0xfa,0x60,0x4b,0x51,0x45,0x32,0x0f,0x01,0xf9,0x73,0x9b,0xd8,0xbc,0xee,0xaa,0x7d,0x2e,0xfe,0xbf,0x9d,0x45,0xae,0xe2,0x01,0xe3,0xbf,0x58,0xdc,0xc0,0xb8,0xe8,0x44,0x16,0x3b,0xd8,0xaa,0x3b,0x13,0xca,0xfb,0x5f,0x8d,0xb3,0x2a,0x83,0x66,0x49,0xae,0x54,0x02,0x4e,0xd8,0x68,0xee,0x21,0x1a,0xbb,0xf4,0xf7 +.byte 0xdf,0xf1,0x51,0x7b,0x62,0xa8,0xb2,0xdc,0x4b,0xd4,0x04,0xd2,0x05,0x49,0xdd,0xa4,0x75,0xe6,0x64,0x82,0xe7,0x25,0x55,0x60,0x2c,0x9f,0x8a,0x7a,0x11,0xe9,0xf2,0x72,0xfe,0x89,0xe1,0xaf,0xca,0x0c,0xb9,0xf5,0xcc,0xcf,0x07,0xef,0x8f,0xbb,0xef,0x53,0x1e,0xe2,0xfb,0x98,0xe8,0x05,0xab,0x4e,0x7e,0x38,0x56,0x24,0xd5,0x74,0x1c,0x95 +.byte 0x1a,0x0e,0x62,0x92,0x80,0x16,0x45,0x78,0x2f,0xb1,0xe1,0x83,0x24,0x2b,0x16,0x5c,0x05,0x52,0x17,0xe9,0xe8,0x9e,0x5d,0x63,0x8f,0x77,0xc4,0x89,0x22,0x76,0x43,0x31,0xfd,0x09,0xc0,0x51,0x70,0x57,0x2d,0x51,0x91,0xe5,0x61,0x3f,0x77,0xff,0x17,0xfc,0xa6,0x19,0x9d,0x82,0x46,0x11,0x0c,0x77,0x19,0x2a,0xf5,0x19,0xb4,0x3d,0xa6,0xd4 +.byte 0x8b,0x07,0x4b,0xc6,0xa3,0x1e,0x8c,0xf5,0xe8,0x2d,0xe7,0xcc,0xa1,0x38,0x57,0x66,0x76,0x1d,0xdd,0xe3,0xb9,0x0a,0x1e,0x2c,0xad,0x09,0x07,0x26,0xff,0x7a,0xc0,0xb0,0x51,0x71,0x44,0x6d,0x2c,0x39,0x3d,0xa6,0x14,0x4e,0x74,0x2c,0x54,0x3d,0xfa,0xdc,0x2e,0x0c,0xc4,0x88,0x32,0xda,0xb0,0x9d,0xf4,0x2c,0x0a,0x1b,0xb7,0xb4,0x78,0x6f +.byte 0x1b,0x6a,0x21,0x03,0x4e,0xe0,0x87,0xa0,0x1c,0xd8,0xe6,0x0c,0x97,0x47,0xde,0x98,0x81,0x3d,0x39,0x93,0x3d,0xcb,0x29,0xa3,0x93,0x8d,0x27,0x5d,0x29,0xb5,0x85,0xc4,0x32,0xd8,0xdc,0x19,0xb1,0x63,0xdc,0x76,0x32,0xc3,0x52,0x9a,0xfd,0x3d,0xff,0xf9,0x94,0x55,0x72,0xbb,0x4d,0xe2,0x42,0xd2,0xf7,0xb2,0xac,0xac,0x5d,0x50,0x95,0xda +.byte 0x3a,0x87,0xb6,0x0f,0x27,0x72,0x34,0xe7,0xe8,0x9f,0xc7,0xba,0xca,0x8d,0xf3,0xb9,0xa1,0xdd,0xd7,0xa5,0x70,0x3b,0xcc,0x72,0x0e,0x9d,0x85,0x75,0x01,0x11,0xe1,0xc2,0xca,0xcb,0x40,0x3a,0x31,0xf2,0x5d,0x0c,0x63,0xc8,0xbf,0x38,0xde,0x09,0x3b,0x32,0xaa,0x6c,0x07,0xd2,0x2b,0x3b,0x94,0x37,0xd0,0xd9,0xe0,0x4c,0x25,0xa3,0x22,0x64 +.byte 0x05,0xcc,0x69,0x9e,0x73,0xd4,0x46,0x2c,0x73,0x23,0xd0,0x6f,0x09,0xff,0x8b,0xef,0x7a,0x08,0x3e,0xa2,0xa7,0x9d,0xf5,0xc9,0x40,0xd1,0x06,0xd6,0xe3,0x89,0xa5,0xcc,0x9f,0x40,0x67,0x80,0x11,0xec,0x5d,0x23,0x19,0xf3,0x66,0xaf,0x06,0xcc,0xe4,0xb6,0x5e,0x20,0xf7,0x19,0xce,0x1a,0xb6,0x86,0x0d,0x39,0x1d,0xc8,0x0a,0xdb,0x50,0x52 +.byte 0x7e,0x3b,0x96,0x9f,0x05,0xdd,0xd8,0xdf,0x40,0xdf,0xe4,0x66,0x14,0x4d,0x4e,0xb3,0x9f,0x86,0x7b,0xc2,0x99,0xc3,0x8f,0xb9,0xe7,0xc3,0x50,0xa4,0xab,0xb8,0x8e,0xc5,0x28,0xce,0x8b,0x51,0xcb,0xad,0xd8,0x1a,0x23,0x7d,0x12,0xc2,0xaf,0x1a,0x93,0x4c,0x57,0xe9,0x59,0x6a,0x03,0x65,0x81,0x07,0x40,0x84,0x92,0x9d,0x22,0x8a,0x3d,0x27 +.byte 0x39,0x05,0xdd,0xf7,0x20,0xad,0xc2,0x03,0x27,0x87,0x8e,0xc1,0x23,0xad,0xe5,0x59,0x16,0xe7,0xde,0xe4,0x44,0x6b,0x06,0xb5,0x1d,0xaf,0xda,0x08,0x4a,0xfa,0x75,0x1a,0x0b,0x35,0xe8,0x6e,0x29,0xd3,0x79,0x19,0x80,0xb9,0x5f,0x36,0xec,0x43,0x25,0x3c,0xbc,0xcf,0x70,0x0c,0xc7,0x2c,0xbc,0x2e,0x72,0x40,0x73,0x98,0x11,0xc9,0x72,0x9f +.byte 0xd9,0x95,0x9f,0x8d,0x4a,0x52,0xbb,0x89,0x30,0x5b,0xa2,0x7e,0x0c,0x21,0x11,0xda,0x4e,0xa1,0x7c,0xc1,0x0f,0x95,0x1b,0x5b,0x2e,0xbd,0xae,0x8a,0x56,0x82,0x8f,0x84,0x43,0xdf,0x24,0xac,0x99,0xaa,0x8a,0xaf,0x82,0x33,0xf7,0x0a,0xbf,0x5e,0xfd,0xf2,0x91,0xf0,0xe1,0x5d,0x4e,0xa5,0x16,0x6e,0xb4,0x39,0x8b,0x99,0x32,0x6b,0xc8,0x16 +.byte 0xc1,0x84,0x10,0xc2,0x74,0x54,0xfc,0x02,0x71,0x44,0xfc,0x52,0xfa,0xc2,0x3c,0x8d,0xf7,0x8b,0x1e,0xcc,0x5e,0x43,0x66,0x29,0x29,0x93,0xe7,0xf6,0x9f,0xa8,0xa3,0x35,0xc9,0xde,0xb0,0xbe,0x4d,0xdf,0x8c,0x61,0x5a,0x6b,0x16,0x88,0x33,0x65,0x47,0x98,0xd2,0xf8,0x71,0x09,0x9f,0x00,0xb6,0x9e,0x21,0x37,0x2a,0x0b,0xb4,0x74,0x6b,0x0e +.byte 0x6e,0x4d,0x14,0x45,0x6c,0x1b,0xa8,0x4c,0xa7,0xc6,0xc3,0x36,0x6e,0x9e,0x63,0x5a,0x36,0x76,0x04,0x06,0x7f,0xdd,0x74,0x24,0x19,0xd8,0xb7,0xbc,0x6c,0x52,0x82,0x67,0x6b,0xd5,0xcb,0x81,0xdf,0xd7,0xe4,0xdd,0x14,0x33,0x71,0xcf,0x6b,0x7f,0xaf,0x66,0x27,0x8a,0x70,0xb8,0x45,0xae,0x8c,0x1a,0x65,0xd3,0x16,0x5c,0x05,0x65,0xd0,0xfb +.byte 0x07,0xe3,0x98,0xa9,0x94,0x27,0x6c,0xac,0xfc,0xee,0x1b,0x35,0x43,0xd6,0x3b,0x41,0x1c,0x86,0xc0,0x4f,0xf3,0x63,0xf4,0xba,0x4d,0xdf,0x6a,0xda,0xcf,0xb5,0x9f,0x69,0x3f,0x3d,0x0c,0x80,0x79,0x02,0x34,0x4a,0x9a,0xfd,0xb6,0xea,0x0b,0x61,0x32,0x67,0x2d,0x6a,0x6b,0xcb,0xcf,0xa6,0xee,0x6a,0x93,0x11,0x00,0xb8,0x6e,0x27,0x88,0x62 +.byte 0xf7,0x4c,0x7b,0xe1,0x13,0xe1,0x47,0xaf,0x96,0x24,0x3b,0x46,0x8c,0xf4,0xbe,0x13,0xed,0x65,0xe1,0xf2,0x36,0x2d,0xa4,0x6d,0x5e,0xa6,0x93,0xfb,0x64,0x0e,0xbd,0x50,0xdc,0x29,0x4f,0x90,0x8e,0xe1,0x7f,0x5e,0x47,0x08,0x9b,0x1c,0xb7,0xce,0x06,0x80,0x52,0xc0,0xb5,0x82,0x77,0x49,0x3c,0xe0,0x70,0x1f,0x84,0x75,0x9e,0x19,0xb2,0x83 +.byte 0xda,0x40,0xf8,0xd7,0x27,0x1e,0xbc,0x39,0xb5,0x1d,0x25,0x75,0x63,0x7d,0x85,0x2f,0x09,0x07,0xe9,0x73,0x8e,0x2b,0xb8,0x9a,0xbe,0xd6,0x90,0x91,0x6e,0xdb,0x7c,0x9d,0x9b,0x43,0x1d,0x21,0x88,0x76,0xb0,0xaa,0x7b,0x68,0xe4,0xa7,0x92,0x64,0xe4,0x1f,0xff,0x53,0x1d,0xf7,0xc0,0x44,0x5c,0x0a,0x1e,0xcd,0xa7,0x6e,0x41,0x1c,0x8c,0x7d +.byte 0x66,0xa7,0xf6,0xfc,0xa9,0x0d,0x3f,0x9c,0xfb,0x15,0x87,0x14,0x20,0x43,0x1b,0x05,0xf5,0xea,0x5c,0x07,0x61,0xb3,0x0e,0x7c,0x52,0x57,0x1c,0x09,0x33,0xb4,0xd8,0x3d,0x9d,0x17,0xee,0x86,0x25,0xdc,0x6b,0xcd,0x58,0xb7,0x18,0xbd,0x85,0x39,0x0b,0xb9,0xb8,0x35,0x3a,0x86,0xbb,0x88,0xb5,0x5e,0x4b,0x0a,0x7e,0x9c,0x02,0xb5,0x45,0xe5 +.byte 0xc7,0x38,0x56,0x1e,0xe4,0xe7,0xf7,0x88,0xac,0x75,0x9a,0x97,0xa8,0x15,0xb6,0x2d,0xcf,0x2a,0x59,0x65,0x0e,0x00,0x9f,0x8e,0xa9,0x94,0x23,0x1c,0x40,0xe4,0xb9,0x6b,0xcf,0xf0,0x53,0x7f,0x98,0xd1,0xa7,0x72,0xd7,0xe3,0x22,0xfd,0x5f,0x3d,0x3f,0xd6,0x21,0xb4,0x84,0x0c,0x1b,0x1d,0x00,0x2d,0x8f,0x72,0x22,0x2d,0x2c,0x8c,0x54,0x46 +.byte 0xe5,0x53,0xca,0x66,0x67,0x5e,0xb3,0x62,0x6f,0xaf,0x33,0x81,0xc1,0xf6,0x77,0x92,0x3e,0xdb,0x74,0x68,0x93,0xca,0x38,0xf8,0x18,0x50,0xef,0xe4,0xc9,0x45,0x40,0xc9,0xf0,0xc5,0x7a,0x4b,0xf2,0xd8,0xca,0x72,0x62,0x5f,0x67,0x10,0x10,0xcc,0xff,0x1a,0xc7,0x9c,0x3a,0x7f,0xca,0x11,0x67,0x3e,0xca,0xa6,0x9c,0x48,0x15,0xaf,0x68,0xb7 +.byte 0x2b,0xa7,0xa2,0x68,0x7b,0x40,0xb2,0xe3,0x27,0x18,0x7e,0x94,0x4c,0xca,0x0e,0x5b,0x3a,0x30,0xcb,0xc3,0x72,0x31,0x6b,0xe6,0x3e,0xa7,0x09,0x3e,0xf2,0x53,0xda,0x7d,0x6f,0x55,0x08,0xd2,0x26,0xc3,0x07,0x52,0x38,0x90,0x04,0xc6,0x3c,0xb6,0xb5,0x2a,0x7b,0x38,0x07,0x9e,0xb4,0xa5,0x48,0x36,0xf5,0x5e,0xac,0xa8,0x97,0x4e,0x37,0xc2 +.byte 0xee,0x12,0x88,0x28,0xd0,0x7d,0xd1,0xae,0xc0,0xc7,0x84,0x69,0x25,0x79,0x9a,0x8a,0x16,0x49,0x50,0x72,0x69,0x1a,0x02,0xc9,0xfe,0xd5,0x2c,0x40,0xc6,0xc8,0x8b,0x7d,0xe3,0xab,0x89,0xe3,0x78,0xf1,0xe9,0xbd,0x3c,0xbd,0x02,0x96,0xfe,0x0c,0x5c,0xc4,0x9e,0x89,0x3a,0x4b,0xe9,0xcd,0x41,0x1c,0x59,0x71,0x52,0xb0,0xc9,0x36,0xf1,0x80 +.byte 0xab,0x5e,0xbc,0xf1,0x20,0x99,0xc0,0xab,0x0c,0x59,0x43,0xc2,0xcd,0x09,0xa6,0x30,0x91,0xfa,0x12,0x23,0xbe,0x18,0x24,0xa6,0xbf,0x55,0x4c,0xe8,0x22,0xff,0x01,0xbd,0xde,0x2c,0x72,0x3c,0x0a,0x36,0xd5,0x7e,0xed,0x6a,0xe3,0x63,0x14,0x60,0xa3,0x0a,0x6f,0x04,0x90,0x64,0xc1,0xd1,0x78,0x54,0xae,0x19,0x74,0xe2,0xea,0xec,0x86,0x22 +.byte 0xc7,0xdb,0xf6,0x48,0x0e,0x75,0x43,0x04,0xf7,0x62,0xe6,0xa9,0x46,0x65,0xcc,0xa5,0xa4,0x1a,0xb2,0x94,0x7b,0x7a,0x8c,0x9a,0x80,0x62,0x32,0x17,0x80,0xc3,0xc6,0x54,0x0e,0x4e,0xe3,0x46,0x74,0xa8,0xae,0xcd,0xd0,0xc1,0x19,0x84,0x61,0xb4,0x1d,0x18,0x4d,0x80,0xf1,0x70,0x40,0xbe,0xa2,0xa3,0x38,0xcc,0x21,0x1c,0x2f,0x72,0x85,0x72 +.byte 0x0a,0xa1,0x0d,0xa3,0xdc,0xa2,0xf4,0x64,0x84,0x3c,0x43,0x6d,0xfb,0x45,0x11,0xf9,0x40,0xdc,0x25,0x85,0x80,0x41,0x84,0xa7,0x06,0x2e,0x79,0xbf,0x0c,0xa7,0x8f,0x17,0xea,0xa2,0xc4,0x6f,0xd8,0xc6,0x9e,0xab,0xdc,0x45,0x6f,0xaa,0xda,0xe9,0xe6,0x84,0xf0,0x5f,0x8a,0x90,0x99,0x33,0x9b,0xcf,0x03,0xe6,0xce,0x19,0x0c,0xad,0x2f,0xad +.byte 0x81,0xb8,0x17,0xff,0x6b,0xff,0xc8,0x14,0xa6,0xf4,0x37,0x55,0xdc,0xbb,0x09,0x3c,0x3c,0xe7,0x29,0x95,0x23,0x5c,0x58,0x92,0x2e,0x95,0xe8,0x3b,0x8b,0x81,0x2d,0xfd,0x58,0x8a,0x1f,0xdf,0xf1,0x54,0xa3,0xd0,0x01,0xaa,0x3d,0x32,0x61,0xe5,0x8e,0x62,0xa7,0xf6,0x3b,0x2d,0x0e,0xff,0xf4,0xe9,0x08,0xe7,0xef,0x3a,0x63,0x10,0x34,0x49 +.byte 0x14,0xe1,0x88,0xd0,0xb2,0x1d,0xb7,0x31,0xc9,0xa4,0x48,0xa8,0xaf,0x64,0x29,0xab,0x1f,0x14,0x13,0xa7,0xb8,0xb8,0xa4,0x24,0x1d,0xf9,0xb6,0x3e,0x62,0xa6,0x5e,0x10,0xcb,0x44,0x5c,0x9d,0x2c,0x58,0x3a,0x36,0xa3,0x81,0x9f,0xa9,0xa4,0xa1,0x06,0x1d,0xbf,0x97,0x03,0x88,0xf2,0xf4,0x81,0x3e,0x1b,0x35,0xea,0xd0,0xb6,0x96,0xa1,0xf7 +.byte 0x1e,0x49,0xb7,0xe8,0x23,0x6f,0x05,0x7c,0x9f,0xc4,0x53,0xb1,0x63,0xdc,0x07,0xbb,0xd6,0x57,0x85,0x4d,0x77,0x33,0x21,0xbf,0x77,0xfe,0xfe,0x34,0x52,0x02,0xe7,0xe4,0x87,0x11,0xa0,0xfd,0x11,0x4a,0x34,0x36,0x88,0x69,0xdf,0x77,0xfd,0x83,0x71,0xa8,0x68,0xed,0x49,0x39,0xb4,0x06,0x32,0x48,0xf1,0xd2,0x4e,0x61,0x47,0x65,0x26,0x87 +.byte 0xba,0x2b,0x2e,0xf4,0x12,0xfc,0xd0,0x84,0x81,0xa1,0x59,0xdc,0xe3,0x13,0x51,0x9e,0xea,0x57,0x56,0x3b,0x7c,0x71,0x6b,0xff,0xe9,0xf8,0xec,0x3e,0xe7,0xbe,0x65,0x47,0xe1,0x6f,0x8f,0x7c,0x3a,0x77,0xdb,0x75,0x4a,0x43,0x43,0x39,0x37,0xb2,0x68,0x16,0x72,0xdb,0x49,0xf7,0x13,0x3c,0x09,0x93,0xef,0xc1,0x2a,0x99,0xff,0xc7,0xdb,0xd9 +.byte 0x80,0xd2,0xfe,0x7c,0x39,0x50,0x21,0xdc,0x1d,0xae,0x9b,0xfc,0xd4,0x5f,0x56,0xae,0x6a,0xd9,0x35,0xa1,0x2b,0xd6,0x53,0x90,0xe8,0x8c,0x31,0x73,0x0f,0xa3,0x9e,0xa1,0x2f,0x76,0xa8,0x72,0x4d,0x5e,0x58,0xca,0x9f,0x8f,0xdf,0xf0,0xf9,0x6a,0x54,0xb1,0x5f,0x39,0x03,0x7a,0x26,0x06,0x71,0x74,0x6f,0x42,0xee,0x63,0x76,0x13,0xb9,0xed +.byte 0x74,0xad,0xf9,0xe0,0xa7,0x35,0x9c,0x18,0xe0,0xf7,0xc5,0xb2,0x27,0x14,0x0f,0xd7,0xaa,0x17,0x1c,0x8f,0x50,0xc8,0xb0,0xc2,0x63,0xff,0x38,0x65,0x87,0x69,0xb3,0xd5,0x3f,0xb4,0xf2,0xe8,0x8b,0x7b,0x24,0xdc,0x1f,0x62,0x2f,0x0a,0xd7,0x2d,0x0f,0x6f,0x48,0x1d,0xf0,0x3c,0xb1,0xb4,0x10,0x8d,0xc6,0x5c,0x79,0x30,0xde,0x20,0x9e,0x7b +.byte 0xf1,0xa5,0x73,0x38,0x05,0x1b,0x13,0x78,0xb1,0x02,0x2f,0x32,0x2a,0x07,0x59,0xa4,0xfc,0x88,0x08,0x0c,0xff,0x42,0x72,0x6a,0xb0,0x8a,0xc9,0x3d,0xdb,0x04,0x90,0xdd,0x0b,0xbc,0x3a,0x4e,0xfa,0xd4,0x57,0xd8,0x2f,0x7b,0xcb,0xd9,0x6a,0xe7,0xfd,0x32,0x17,0x99,0x20,0x64,0x1e,0x76,0x07,0xb9,0xa3,0x58,0x7f,0x79,0xda,0x0c,0xe0,0xec +.byte 0x30,0xbf,0xa4,0x85,0x0a,0x39,0xc0,0xe9,0xf7,0xbe,0xd1,0xa7,0x94,0x1f,0xa6,0x6d,0xe8,0xc5,0x1b,0x04,0x27,0xf4,0xdc,0xc2,0x4d,0x9a,0x0e,0x9b,0xe8,0xec,0x56,0x99,0x90,0x5f,0x8b,0x28,0x0a,0x92,0xaf,0x0b,0xa1,0xd2,0x85,0x86,0x26,0xc7,0x8a,0x01,0xa4,0x08,0x29,0x32,0x7d,0x3d,0xa5,0x74,0x9c,0x90,0x63,0x83,0x1f,0xd4,0xee,0x98 +.byte 0xf5,0x14,0xff,0x39,0xeb,0xbf,0x40,0xa4,0xc9,0x70,0x4f,0x81,0x03,0x19,0xef,0xf5,0xdf,0xf7,0x00,0x75,0xcb,0x2e,0x81,0x41,0xc5,0xda,0xfb,0x67,0x6a,0xf0,0xa3,0xd3,0x5a,0x60,0xaf,0x72,0x27,0x3e,0xad,0x37,0x3e,0x3d,0xe6,0x85,0x4c,0xa1,0xb0,0xe9,0xab,0xc5,0xd3,0x8b,0x04,0x0d,0x64,0x7f,0xa2,0xb9,0x6d,0x6d,0x28,0xf8,0x4b,0x43 +.byte 0x78,0x51,0xf4,0x84,0xf1,0x3c,0x67,0xd8,0xdd,0xd7,0x0b,0x67,0xc3,0xd9,0x95,0x7b,0xfc,0x7d,0xc4,0x33,0x05,0x90,0xec,0x0a,0x98,0xfb,0x6b,0x0d,0xe9,0x8c,0x74,0x94,0x20,0xf8,0xcb,0xca,0xb6,0x72,0x07,0x7c,0xef,0xfa,0xd0,0x3f,0x51,0xc5,0x6e,0xf8,0x3f,0x37,0xe3,0xfe,0xb9,0x9a,0x9c,0xb3,0xf6,0x96,0x4e,0x65,0x77,0x21,0xcf,0xaf +.byte 0xe7,0x20,0x06,0xc2,0x93,0xc5,0x2e,0xc0,0x7f,0xe5,0x0a,0x42,0xad,0x89,0x64,0x6e,0x95,0xbf,0x95,0x1d,0x24,0x47,0xf8,0xd5,0xec,0x7c,0x1f,0x98,0x67,0x9c,0x5f,0x6e,0xaf,0x74,0x95,0x65,0x4c,0xb6,0xe0,0xd3,0xb7,0x5b,0xc7,0x76,0xe6,0x87,0x19,0xf5,0xc7,0xb0,0x2d,0xe0,0x8b,0xaf,0x6d,0x3c,0x31,0x6e,0x84,0xc8,0x86,0x51,0xff,0x29 +.byte 0x2a,0x1f,0xea,0xd4,0x2d,0x1a,0x8f,0x04,0xb4,0xc0,0x6a,0x93,0xc2,0xc5,0xe7,0x98,0x8c,0xc7,0xff,0xbf,0xb8,0x8e,0x5b,0x29,0x5b,0xa6,0x87,0xc7,0x02,0x88,0x51,0x29,0x66,0xd8,0xf3,0x68,0x38,0xd4,0xa6,0xbd,0xa2,0x5c,0x1b,0xb7,0x13,0xd7,0x64,0xed,0x68,0x21,0x88,0x2b,0x59,0xba,0x95,0x84,0xda,0xce,0x61,0x3b,0x51,0x04,0x3e,0xc2 +.byte 0xdd,0xec,0x0c,0x6b,0xbe,0x35,0x51,0x63,0x29,0x40,0xcb,0xa5,0x62,0xe4,0x27,0x35,0x15,0x1f,0x7c,0x8b,0xe5,0xd0,0x2e,0xde,0x8c,0x3d,0xa0,0xd2,0xbe,0x51,0x3d,0x65,0xed,0x94,0x8b,0x8c,0x00,0xda,0x0e,0x78,0x4d,0x25,0xef,0x8e,0x3c,0x55,0x77,0xeb,0x58,0x06,0x7d,0xd1,0xfc,0x73,0xad,0x76,0x0a,0x81,0xbe,0xda,0x50,0x30,0xf3,0xfd +.byte 0x58,0x25,0x0a,0x4b,0x1b,0x1e,0x0b,0xd0,0x9b,0xbc,0xb9,0x31,0x26,0xbc,0x4c,0x7b,0x05,0xd7,0x5c,0xe4,0x7a,0xdd,0xff,0x04,0xac,0x5d,0xcb,0xfd,0x91,0x34,0x68,0x26,0x1e,0xb4,0x86,0xcc,0xe3,0x90,0xaf,0x6a,0x65,0xda,0x6b,0x3e,0xec,0x44,0x90,0x72,0x7a,0x34,0xfc,0x7b,0x65,0x83,0x34,0x93,0xbc,0x85,0x50,0xdf,0x03,0x89,0x35,0xb8 +.byte 0x6a,0x39,0xd3,0xb6,0x38,0x66,0x5b,0xa7,0x9e,0x93,0xa2,0x3b,0xb6,0xe7,0xee,0x1e,0x5c,0xd6,0xa8,0xd9,0x1f,0xf7,0xd1,0x0a,0x2f,0x87,0x63,0xf4,0xf9,0x8c,0xd4,0x7c,0x02,0xaf,0x7e,0xb6,0xc7,0xfc,0xc9,0x4d,0x35,0x0c,0x8c,0x3c,0x13,0x9d,0xe6,0xd7,0x2e,0x4b,0x91,0xcc,0x88,0xdb,0xfc,0x68,0x3a,0xd1,0x15,0x07,0x16,0x66,0x11,0x9b +.byte 0x66,0x9f,0x3f,0x37,0xae,0x11,0xba,0x5f,0xc7,0x3a,0x1a,0x49,0xbc,0x14,0x21,0x75,0xdc,0xcc,0xbb,0x5c,0xed,0xdc,0x8b,0x21,0x9a,0x8f,0x5f,0x91,0x6a,0x9b,0x26,0x33,0x64,0x45,0xa0,0xdf,0xc4,0xa1,0x32,0xc4,0x4c,0xc2,0x42,0x1b,0x59,0x37,0x1f,0xdb,0x01,0x6d,0xed,0xd8,0x05,0x5b,0x90,0x59,0x32,0x45,0x50,0x5d,0xf1,0x34,0xc4,0xb7 +.byte 0x52,0x97,0xbb,0x42,0x12,0xf1,0xa5,0x76,0xe4,0x1a,0xbc,0x4a,0x64,0xd3,0x08,0xac,0xe1,0x49,0x70,0x61,0xc8,0xcf,0xb1,0xd3,0xc4,0x7f,0x38,0x31,0x6b,0xd3,0xe1,0xe1,0xe9,0x5b,0xaa,0x7a,0xec,0x26,0x81,0x44,0xd3,0xb9,0x63,0xea,0x37,0x98,0x15,0x41,0xf1,0xa1,0x72,0x87,0xcc,0x3b,0x6a,0x27,0x9b,0x85,0xa8,0x7b,0xb6,0x25,0xf9,0xd4 +.byte 0x84,0x3e,0x66,0x12,0xce,0x24,0xee,0x22,0x51,0x73,0x7e,0xba,0x1e,0x95,0x64,0xc5,0xbf,0x4e,0x4f,0x73,0xc1,0xc3,0x98,0xb9,0x6b,0x90,0x1f,0x39,0xfc,0x03,0x55,0x76,0x8c,0x57,0xea,0xe8,0xc1,0x25,0x09,0x69,0xc0,0xe8,0x54,0x91,0xc1,0x7c,0x52,0x8e,0x82,0x6d,0xf2,0x0e,0x3f,0xa9,0x98,0x04,0x40,0xda,0x1c,0xc0,0xbb,0x42,0xf0,0x7d +.byte 0xed,0x78,0xb0,0x4f,0x94,0xba,0x0d,0xbf,0x60,0xbe,0x09,0x67,0x42,0xc5,0x41,0x4c,0x80,0x8d,0x30,0x10,0xa9,0xd2,0x07,0x8c,0xa8,0x40,0xc6,0xe2,0x08,0x42,0x7f,0x99,0xad,0xc5,0x66,0x1f,0xfd,0xd2,0xc5,0x79,0x77,0x9b,0x60,0x7d,0x25,0x2d,0x69,0x14,0x94,0xa5,0xf0,0x0a,0x14,0xb6,0xf9,0xbe,0x3a,0x4a,0x3d,0xc6,0x45,0x2e,0x27,0x4a +.byte 0xd1,0x1d,0xcf,0x08,0xee,0x93,0x3c,0xb5,0x8a,0xee,0xdd,0xf3,0x33,0xa6,0x35,0x9d,0xd8,0xb4,0x68,0xc5,0x98,0x09,0x78,0xcc,0xb3,0xeb,0x0f,0xcd,0x25,0xf8,0x17,0x9c,0x45,0x77,0xc7,0x06,0x40,0x44,0x90,0xec,0x6a,0xd9,0xf5,0x05,0xd4,0x88,0x17,0x47,0xeb,0x29,0x85,0x32,0x76,0x7b,0xa4,0xe3,0x65,0x30,0x50,0x9a,0x99,0x26,0x91,0x60 +.byte 0xb0,0xb8,0xe5,0x8d,0x35,0x9e,0x9a,0x13,0x65,0x82,0xb2,0x4b,0xf1,0xed,0x1f,0xb7,0xb4,0xc0,0x03,0xe6,0x1d,0x2b,0xaa,0x1e,0x01,0x92,0x0b,0xcb,0x34,0x77,0x80,0x94,0xc2,0x4e,0x3b,0x73,0xd8,0x2e,0xd8,0x95,0x33,0x05,0x65,0xa2,0x99,0x29,0x7a,0xd1,0xb3,0xed,0x5a,0x8d,0x4d,0x6a,0x6d,0x69,0x2b,0x5a,0xa1,0x3a,0xc0,0x81,0x96,0xf1 +.byte 0xc2,0xa7,0x4e,0x07,0x90,0x04,0x99,0x70,0xea,0x1a,0x3a,0x26,0xb5,0xed,0x92,0xbd,0x57,0x80,0x11,0x06,0xf2,0xb4,0x05,0x69,0x7a,0xbf,0x27,0xa1,0xbd,0xdb,0x09,0xe5,0xb3,0x2d,0x86,0x41,0xcc,0x5d,0x68,0x37,0x9e,0x98,0xa5,0x4a,0x20,0x8a,0x5f,0x54,0xae,0x4f,0x73,0xd0,0x22,0x18,0x8d,0x2b,0x91,0xcb,0xbb,0x83,0x1e,0x04,0x93,0xc8 +.byte 0xc3,0x89,0x35,0xfd,0xda,0xeb,0x52,0x53,0x9f,0xdc,0x33,0xf0,0xe0,0x99,0x19,0x11,0xeb,0x55,0xd3,0x3c,0x5f,0xca,0x29,0x52,0xe7,0x6b,0xd1,0xad,0xeb,0xed,0x8e,0x68,0x82,0x91,0x85,0x81,0x68,0x70,0x78,0x61,0x1e,0x0c,0x09,0x3a,0x82,0xdc,0xdb,0x26,0x66,0x1c,0xa3,0x80,0x99,0x23,0x8a,0x45,0xd7,0xb8,0x10,0x97,0x80,0x70,0x49,0x78 +.byte 0xa9,0x4c,0xf0,0xec,0xcc,0x05,0xd0,0x6a,0x6a,0x1a,0xa0,0xf7,0xde,0x78,0xc6,0x42,0xbe,0xbd,0xa0,0x24,0x1d,0x3f,0xdd,0xfb,0x92,0xc2,0xbd,0xd6,0x5c,0x25,0x74,0x3d,0x2b,0xb8,0x60,0x67,0xdb,0x70,0x1e,0xe8,0x9f,0xcd,0xb4,0x82,0x90,0x9e,0x2a,0x94,0xa5,0xa2,0xd4,0xd2,0x24,0xa7,0xca,0xbf,0xe1,0x8b,0xab,0xf3,0xd2,0x7c,0xa6,0xc8 +.byte 0xe6,0xaf,0xef,0xe3,0x86,0xb1,0x42,0x1d,0xc6,0xa2,0x37,0x9b,0x26,0x46,0x0b,0xfd,0xee,0x88,0xa4,0xf1,0xa8,0x72,0xaf,0xda,0x30,0x56,0x22,0xd3,0x1b,0x31,0x76,0xd7,0x03,0xef,0xf3,0x98,0x16,0x4d,0x36,0x57,0x1b,0xd5,0x90,0xb8,0x67,0x50,0x7f,0x22,0xa8,0xdc,0x9c,0xf1,0x6e,0xa4,0x65,0x45,0xf0,0x73,0xd8,0x7e,0x41,0xb0,0x68,0x52 +.byte 0x00,0x0a,0xda,0x99,0x6c,0x84,0xce,0xf0,0x73,0x65,0x93,0x52,0xc8,0x4b,0xb4,0x72,0xda,0x2c,0xa1,0x47,0xb5,0xe3,0x00,0x63,0xc0,0x4e,0x84,0x16,0x00,0xe6,0x1f,0xbd,0xba,0x49,0xcb,0xd3,0x7d,0xd2,0xeb,0x4a,0xb2,0xd5,0xb2,0x53,0x96,0xfb,0x04,0x73,0xc0,0x09,0x31,0xf3,0xf2,0xc0,0xd3,0xa6,0xe1,0xea,0xe1,0x58,0xbe,0x90,0xc9,0xfb +.byte 0x6e,0x13,0x69,0xbe,0x17,0xd4,0x16,0x5b,0xcb,0xf4,0x93,0x0a,0x38,0x46,0xea,0x64,0xad,0xb0,0x0d,0xc0,0x3b,0xfc,0xe3,0xd4,0x20,0x75,0x0c,0x3e,0x71,0x1b,0x5f,0xde,0xff,0xd6,0xfa,0x6f,0xe4,0x10,0xb0,0x14,0x05,0xaa,0x05,0x70,0x5e,0xbd,0x58,0x9f,0x3c,0x9d,0x4f,0xa7,0x5a,0x65,0x57,0x02,0x05,0x44,0xe0,0x95,0x9d,0xa2,0x60,0x06 +.byte 0xcb,0xfd,0x91,0x8e,0x7f,0xce,0xa1,0x80,0x94,0xbb,0x88,0xf2,0xa6,0xe7,0x83,0xf9,0x38,0x8f,0x09,0x8e,0xe4,0xa9,0xc2,0xc7,0x84,0x9d,0x25,0x09,0x52,0x8b,0x32,0xaa,0x3b,0xde,0xb6,0x82,0x9f,0x6d,0xc4,0xdf,0x11,0xf7,0x72,0x1a,0xe4,0x00,0x51,0x41,0x01,0xba,0x21,0xea,0x0a,0xda,0xf2,0xbb,0x66,0xae,0x51,0x2b,0xb0,0x6d,0x1d,0xe8 +.byte 0x4b,0x1e,0x42,0x68,0x3a,0xed,0xe6,0x59,0x13,0x42,0x07,0x54,0xae,0x2e,0x15,0x93,0xd7,0xff,0xad,0x49,0x09,0x41,0x52,0x6b,0x3b,0x9c,0x41,0x43,0x0d,0xed,0xed,0x6f,0xb8,0xe9,0x0d,0xcc,0xde,0x0d,0xaa,0x91,0xef,0x89,0x2f,0x2d,0x94,0xd0,0x03,0x2b,0x51,0x7f,0x85,0x9b,0x7b,0x08,0xc8,0xb6,0xe2,0x82,0x22,0xa9,0x57,0x71,0xf2,0xae +.byte 0x08,0xfa,0x6c,0xd8,0xca,0x78,0x42,0x98,0x23,0xfd,0x38,0x4b,0x6c,0xd3,0x9f,0xc6,0xa3,0xb2,0xc1,0x8c,0x4a,0xa3,0xcd,0x9f,0x56,0xe7,0xc2,0x06,0xd7,0xc5,0xc2,0xd9,0x98,0x57,0xc8,0x5a,0xaa,0xf4,0xaa,0x44,0x02,0x83,0x11,0x1e,0xf6,0x64,0x8d,0xf7,0x3b,0x86,0x3c,0x04,0x53,0x5f,0x62,0xc8,0x7a,0x0e,0x1c,0x4f,0xa8,0xe3,0x5c,0xe8 +.byte 0x64,0xf7,0xe3,0x5d,0xea,0xb5,0x2d,0xdb,0x7b,0x0e,0xdb,0x91,0x34,0xd5,0x87,0x4f,0xe6,0x73,0xee,0x3d,0x79,0x7c,0x67,0x48,0xb5,0xbb,0x42,0x96,0x0d,0x9d,0xbd,0x68,0x98,0xe5,0x59,0x51,0x16,0x45,0x15,0xac,0x80,0x41,0xae,0x45,0xdb,0xe4,0x2a,0x44,0x0d,0xe4,0x25,0xc7,0xd3,0x06,0xf7,0x98,0x15,0xe1,0xc5,0x9b,0x34,0x0e,0x87,0xb8 +.byte 0x90,0x1b,0x24,0x84,0x06,0x24,0xb0,0x80,0xbe,0x03,0xa0,0x95,0x10,0x1e,0x72,0xde,0x0f,0xd4,0x15,0x7b,0xa0,0xf5,0x42,0xc3,0x6f,0x10,0xe9,0x76,0x44,0xe3,0xa9,0xb7,0xef,0xf6,0xc2,0x80,0xe2,0x0c,0x2d,0xad,0xe0,0xb9,0x45,0xca,0x67,0x6f,0xb6,0xc5,0xc0,0x8d,0x25,0xee,0x50,0xeb,0x51,0xc6,0x87,0x87,0x61,0x3a,0x75,0x95,0x41,0x47 +.byte 0x26,0xfd,0x35,0xf6,0x46,0xf4,0xe9,0x42,0xc6,0xef,0x37,0x97,0xb3,0x0a,0x1d,0xc8,0xdf,0x07,0x24,0xb1,0x0d,0x07,0x43,0x67,0x7d,0x81,0x09,0x58,0xdd,0xf6,0xcf,0xf1,0x47,0x42,0xbd,0x3c,0xa3,0xd7,0xe8,0x73,0xf9,0x5b,0xff,0x2c,0xcd,0xe6,0xd1,0xe9,0x47,0x6d,0x19,0x9b,0x6a,0x63,0x69,0xf4,0x4a,0xdf,0x69,0xab,0xa9,0xb7,0xe5,0x8d +.byte 0x1c,0x44,0x52,0x0c,0x7e,0xa1,0xfe,0x9d,0xd5,0xa4,0x71,0x62,0x0b,0x3c,0xf6,0xd2,0xd3,0xe9,0x70,0x09,0x68,0xf7,0xd6,0x0a,0x00,0x61,0xf1,0xf3,0xd0,0x41,0x4a,0x14,0xc6,0xf5,0x49,0xb1,0xde,0x10,0xd3,0x20,0x8b,0xfe,0x78,0x6a,0x87,0x79,0x15,0xd3,0x43,0x00,0xbe,0x71,0x40,0xaa,0xca,0x1a,0x64,0xe3,0x96,0x34,0x2f,0xea,0x0c,0x11 +.byte 0x41,0x21,0xf8,0xa7,0x65,0x9b,0x75,0xe2,0x1e,0x6f,0x5e,0xe0,0x68,0x42,0xca,0xd3,0x19,0x35,0xe8,0x88,0x0f,0x05,0xa3,0xb1,0x73,0xea,0x53,0x79,0x40,0x24,0x00,0x86,0x20,0xbb,0x25,0x58,0x89,0x6b,0xde,0xd6,0xd0,0x36,0xbb,0x33,0x30,0x59,0x4b,0x30,0x92,0xac,0xe5,0x95,0x94,0x22,0xab,0xc1,0x10,0x35,0x9c,0xa1,0x20,0x11,0x5d,0x4f +.byte 0x57,0x5c,0x9c,0xb8,0x3a,0xdc,0x97,0xa5,0xf3,0x0b,0xf5,0x96,0xe7,0xef,0x90,0x72,0x01,0x52,0x70,0x5a,0xf0,0xd9,0x7e,0x59,0x05,0x8c,0xd1,0x45,0x47,0xbf,0x16,0x15,0xa2,0xc9,0xdd,0xe7,0x5f,0x4b,0x94,0x5f,0xe6,0xf9,0x78,0xbb,0x8f,0xf9,0x79,0x9f,0x5e,0xd7,0x1f,0x0b,0xef,0x8d,0xfe,0x75,0xd4,0x8a,0x12,0x28,0xa5,0xf9,0x6e,0x14 +.byte 0x3c,0x52,0x80,0x57,0xc6,0x96,0xae,0x67,0x27,0xc1,0x1c,0xb6,0xd6,0x1c,0x74,0x8c,0x6f,0xc7,0x71,0x3e,0xd5,0x73,0xf2,0x3e,0x02,0x15,0x67,0x18,0xb8,0x5b,0x61,0x9e,0xfa,0x7e,0xba,0x00,0xe9,0xd9,0x51,0x91,0x63,0x7e,0xf7,0xab,0xc0,0xc6,0xee,0x66,0xdd,0x66,0x88,0x7a,0x8a,0xc5,0xc2,0x08,0x45,0x62,0xde,0xe1,0xfb,0x35,0x65,0x34 +.byte 0x00,0x9e,0x1d,0x25,0xdf,0x69,0xb6,0xe3,0xfe,0xbb,0x13,0xac,0xd3,0x13,0xb2,0x64,0x5a,0xf3,0x47,0xf1,0x36,0x55,0x5f,0x1b,0x87,0xea,0x5d,0x5c,0xfd,0x8a,0x68,0x69,0x8a,0x00,0x9f,0x83,0xbe,0x79,0x7d,0x01,0x9e,0xf2,0xb2,0x5d,0x56,0xe0,0xe6,0x49,0xe5,0xe1,0x76,0x57,0x7a,0x85,0xac,0x94,0x16,0xe3,0x68,0x05,0x14,0xb5,0x33,0x54 +.byte 0x64,0x5a,0xbe,0xa3,0x04,0x90,0x5c,0x1c,0xf8,0x97,0x16,0x36,0xce,0x76,0xe7,0xf0,0xaf,0x8a,0xea,0x65,0xa8,0x15,0x5b,0x1e,0x0a,0x91,0xad,0x62,0x62,0x67,0xb4,0xf0,0x94,0x1f,0x64,0x50,0xa8,0xc0,0x6b,0x38,0x80,0xd7,0x53,0xbb,0x70,0xbd,0x54,0x01,0xb0,0xa5,0xbc,0x00,0xe0,0xd6,0x23,0x37,0xe6,0x9f,0x0f,0x2f,0x96,0x21,0xc2,0x90 +.byte 0x55,0x26,0x55,0xa4,0xcd,0x3e,0x54,0x6b,0xa6,0xb0,0x2c,0xf2,0xd4,0xcc,0x6a,0x44,0xea,0x18,0x61,0xc5,0x1a,0x8e,0x60,0x64,0xf4,0x5f,0x21,0x36,0x01,0x5d,0x9f,0xc4,0x2c,0x67,0x1c,0x48,0x94,0x16,0xae,0xa8,0x13,0x5c,0xee,0x18,0x88,0x61,0xe4,0x54,0x6b,0xa2,0xe8,0x7f,0xf0,0x15,0xc3,0xce,0xbc,0x5b,0x91,0x25,0x7b,0x1d,0xd3,0x9f +.byte 0x13,0x1b,0x01,0x5d,0x43,0xe8,0xa1,0x77,0x5a,0x87,0x79,0x8b,0xd5,0x69,0xf7,0xdf,0x66,0xa2,0x84,0x0c,0x66,0xac,0x15,0x65,0xbf,0x74,0xc0,0xd2,0x78,0x6a,0x3a,0x9c,0x98,0x62,0x04,0x41,0x95,0xb2,0x23,0x59,0xc6,0xb0,0xc5,0x22,0xc0,0xfa,0xaa,0xc8,0x94,0x73,0x91,0x5b,0x64,0x1b,0x74,0xbe,0xcb,0xa1,0x81,0xb1,0xc1,0x26,0xa1,0x94 +.byte 0x55,0x04,0xb3,0x9c,0x80,0xb7,0x00,0x6f,0x36,0xc7,0x7f,0x6d,0x97,0xea,0xf3,0xf5,0x55,0xc5,0xfe,0x61,0xd9,0xb1,0x6d,0x8c,0xa1,0x02,0x08,0xb3,0x41,0xe6,0xe6,0x57,0xc6,0xff,0x6e,0x47,0xa4,0x22,0x2e,0x2d,0x21,0x53,0xbe,0xe3,0xbe,0x15,0xec,0x23,0x9d,0x87,0xe0,0x2e,0xcc,0x6c,0xd0,0xc7,0xb7,0x3d,0xa4,0x07,0x5f,0x69,0x4e,0x2b +.byte 0x07,0x69,0x4f,0xc5,0xa3,0x66,0x52,0x91,0x8f,0xa4,0x48,0xb9,0x40,0x76,0xd9,0xcb,0x6e,0x1a,0x35,0x9e,0x50,0x9f,0xd1,0x78,0xb2,0xb8,0x0d,0xa8,0xf8,0x6e,0x07,0xa5,0x3a,0xdf,0x3c,0x32,0xa6,0x10,0xbd,0x73,0x2f,0x07,0x45,0x66,0x0f,0x61,0xce,0xc2,0x08,0x19,0x98,0x33,0x4b,0x59,0x81,0xb5,0x78,0x4f,0x46,0x88,0xae,0x29,0xf8,0xf5 +.byte 0xc2,0x29,0x6f,0x8f,0xe5,0x8f,0xb0,0x53,0xc8,0x7a,0x48,0xda,0x6f,0x7e,0x8a,0x69,0x68,0xab,0xba,0xd9,0x20,0x0f,0x96,0x69,0x41,0xa6,0x92,0x94,0x8e,0x0f,0x86,0xdf,0x8d,0x70,0xaf,0xfe,0xf1,0x20,0x50,0x01,0xff,0xca,0x30,0x24,0x67,0x4a,0x04,0xa2,0xde,0x06,0xdc,0x26,0x1e,0x17,0xbc,0x52,0x9a,0x62,0x72,0xc1,0xd8,0xd7,0xe0,0xed +.byte 0xcf,0x4b,0x13,0x80,0x9a,0xbf,0x72,0x4f,0xf4,0x24,0x26,0xcd,0xe0,0x21,0x99,0x7b,0x5c,0x4f,0xbf,0x5c,0x41,0x08,0x8b,0x17,0x69,0x62,0x60,0x2c,0x74,0xb0,0x2d,0x22,0x7e,0x25,0x95,0x6a,0x84,0x0f,0x45,0x8f,0x9a,0x92,0xa1,0xcd,0xa5,0x50,0xf0,0x52,0x7f,0x60,0xd8,0x91,0xe1,0x17,0xe1,0x66,0x8f,0xd3,0x1f,0x41,0x7f,0x6f,0xf1,0x72 +.byte 0xa3,0xb6,0x12,0x62,0x46,0x16,0xea,0x26,0x9e,0xda,0x61,0x13,0x0b,0x17,0xf7,0xe1,0xec,0xc0,0x38,0xfe,0x40,0x31,0x6b,0x38,0x2a,0x4b,0xa5,0x8e,0xfb,0x99,0x60,0xd6,0x4a,0xbd,0xfb,0x75,0x2b,0x41,0xd4,0x33,0x5d,0x35,0xfe,0x2d,0xfc,0x1a,0xac,0x02,0xb3,0xf0,0xa2,0x6d,0xfa,0x8b,0x12,0x99,0xdd,0x54,0xf2,0x1c,0x35,0xd3,0x60,0x5a +.byte 0xdb,0x65,0xa7,0x58,0x1b,0x82,0xb4,0xf6,0x49,0x77,0xf2,0xea,0xa3,0xa9,0x57,0x94,0xb7,0x6e,0x19,0xda,0x7e,0xa5,0x70,0xb8,0xff,0x39,0x81,0x7d,0xfa,0xea,0xd6,0xc6,0x12,0x84,0x0a,0x8a,0x16,0xde,0x99,0xa6,0xe7,0xe0,0x77,0x76,0xb8,0xa3,0x6f,0xfb,0xb4,0x8f,0xc3,0xbd,0x90,0xd8,0x2a,0x04,0xed,0x42,0x91,0x9b,0x84,0x40,0x2d,0x01 +.byte 0x94,0xdb,0xbb,0x58,0x25,0xed,0xa3,0xdd,0xaa,0x0c,0xce,0x25,0x12,0xcd,0x11,0xbf,0xd0,0x57,0xe9,0x51,0x74,0xa7,0x45,0x6c,0x58,0xe7,0x4d,0x43,0xc6,0xd0,0x09,0x93,0x2d,0xe0,0xe3,0xae,0x7b,0x8f,0x53,0xa0,0x80,0xa1,0xef,0xcb,0xf5,0xfe,0x38,0x4d,0x31,0xa2,0x5c,0xd3,0x4a,0x66,0x1a,0x5c,0x07,0xbe,0x25,0xba,0x30,0xb6,0x00,0x27 +.byte 0x52,0xb9,0x1f,0xa3,0xed,0xd7,0x31,0x33,0x4a,0xf6,0x3f,0xed,0x75,0xe7,0xa4,0xf4,0xdf,0x97,0xc1,0x78,0x90,0x9b,0x4b,0xbd,0x06,0xc6,0x72,0x5c,0xdf,0x57,0x60,0xbe,0xbc,0x88,0x02,0xb6,0x5a,0x65,0xea,0x3a,0x3a,0x74,0x03,0xc8,0x66,0xef,0xf0,0x63,0xc7,0x9d,0x58,0x8e,0xa1,0xb2,0x25,0x4f,0xc4,0x14,0x5f,0x80,0x78,0x08,0x06,0x21 +.byte 0x50,0x34,0x01,0x2b,0x15,0xf4,0x7d,0x1f,0x1f,0x32,0x36,0x0a,0x52,0x1f,0x50,0xa2,0x50,0xbc,0x9a,0xdf,0x4e,0x84,0x49,0x2d,0x08,0xaa,0x46,0xc0,0x0e,0xcf,0x27,0x17,0x91,0x78,0x8c,0xb9,0x72,0xc5,0x8e,0x25,0x85,0x11,0xff,0x2f,0x4a,0x71,0x7c,0x14,0xfe,0x86,0xfe,0xb4,0x3a,0xd0,0x67,0xfd,0xaa,0x9b,0xee,0x89,0x66,0x03,0x59,0x4e +.byte 0x1c,0x96,0xaf,0x2b,0x8d,0x4d,0x6f,0xf6,0x72,0xc6,0x13,0xc7,0x14,0xce,0x19,0x0c,0x0b,0xa3,0x01,0x12,0x7c,0x8e,0x10,0xb8,0x63,0x41,0x57,0xb9,0xfe,0x6e,0x3e,0xda,0x20,0xfb,0x92,0x08,0x7d,0x66,0x31,0x9d,0x4f,0xdb,0x14,0xf4,0xb6,0xb8,0xea,0xee,0x54,0x0f,0xaf,0xc1,0x99,0xf0,0x8f,0x55,0x44,0x20,0x44,0xd0,0xa6,0x98,0xa3,0xa8 +.byte 0x8b,0x8e,0x26,0x03,0xec,0x2d,0x50,0x4f,0xb0,0x8d,0xd0,0xf2,0x96,0xcc,0x18,0xa9,0xb1,0x0f,0x79,0xe3,0x9f,0x08,0xb3,0x53,0x0b,0x9c,0x9f,0x22,0xdb,0x45,0x57,0xd6,0xaa,0x3b,0x6a,0xcb,0xdc,0xc9,0xda,0x57,0x75,0x65,0x0a,0xc1,0x17,0xb3,0x97,0xa9,0x07,0x40,0x20,0xfb,0x72,0x2d,0xc6,0x37,0x1e,0x44,0xb7,0x7e,0x0b,0x38,0xcc,0xfc +.byte 0xa0,0xed,0x48,0xa9,0x9b,0x87,0xbc,0x71,0x0f,0x8b,0xda,0x4f,0x09,0x27,0x1e,0x3d,0x9c,0x03,0x62,0x81,0xa8,0x7c,0x7b,0x8a,0x14,0xa7,0x22,0x69,0xa8,0xba,0x0e,0xcc,0x1f,0x2b,0xb3,0x0f,0x7d,0xce,0x3f,0xec,0xb5,0x9d,0xe0,0x3a,0x67,0x56,0x08,0x5d,0x03,0x8b,0x71,0x01,0x44,0x11,0x1b,0x7b,0xcf,0xcc,0x2e,0xfc,0xa5,0x52,0x9b,0xeb +.byte 0x1e,0x8a,0xa1,0x86,0x64,0xcf,0x32,0x03,0x6b,0x3e,0x29,0xe7,0x9a,0x16,0x7e,0xe2,0x21,0x2f,0x5f,0xe2,0x86,0x7f,0xf8,0x22,0x36,0x10,0x99,0xc8,0x27,0x43,0xa1,0xb9,0xf4,0xb4,0xb8,0xe1,0xa3,0x1d,0x80,0x9c,0x81,0x92,0xef,0x1f,0x28,0x54,0x51,0xf3,0x62,0x9c,0x7a,0x24,0xd4,0x5a,0xdc,0x38,0x4f,0xa5,0x57,0xdd,0x4d,0xa1,0x52,0xf3 +.byte 0xd3,0x9d,0xa1,0x93,0x5e,0xbe,0x9b,0xd1,0x2a,0x52,0xf1,0xbb,0xa5,0x3f,0x3a,0x94,0x7c,0x7d,0x41,0x61,0x36,0x14,0x25,0x5f,0xab,0xef,0x32,0xf3,0x0f,0x6c,0xc5,0xf5,0x5f,0xe5,0x88,0x51,0x17,0x60,0x8b,0xd5,0xa6,0xea,0x8b,0x21,0xec,0x1a,0xa7,0x69,0xa0,0x59,0xf9,0xeb,0x51,0x94,0x70,0x2b,0x96,0x2e,0x71,0xa9,0x8c,0x12,0x15,0xce +.byte 0x7d,0x59,0x6b,0xf2,0xca,0x2c,0xbd,0x85,0xfb,0x23,0xab,0xcb,0x89,0x89,0xda,0x28,0x49,0x7e,0xfc,0x90,0x2a,0x9a,0x3d,0x6d,0x24,0x57,0xba,0xd9,0x30,0xe0,0x10,0x04,0xb1,0x7f,0x8a,0xcf,0xc8,0x27,0x63,0xd6,0xbd,0xea,0xef,0x90,0x6f,0xc2,0xfc,0x78,0xfd,0xc4,0x5b,0x45,0x0c,0x41,0x8a,0x53,0x5b,0xbc,0x62,0x32,0x86,0x7f,0x19,0xb7 +.byte 0x8b,0x03,0x50,0xed,0xca,0x8e,0x8b,0xa0,0xe3,0xc2,0x0e,0x81,0xe5,0x8a,0xe8,0xf1,0x6a,0x0b,0x1a,0xa7,0xb6,0xed,0x74,0x23,0x34,0xad,0x5b,0xd8,0xf7,0x17,0x8d,0xa5,0x05,0xf3,0x00,0x4a,0xad,0x7e,0x91,0xc9,0x6b,0x13,0xff,0x76,0x78,0xf0,0xd1,0xf4,0x99,0x43,0x73,0xd9,0xba,0x59,0xbe,0xb5,0xa3,0xbd,0x5e,0xc5,0xd3,0x88,0x06,0x9c +.byte 0x86,0x32,0xb4,0xd5,0x30,0x77,0x78,0x8e,0xd5,0x6a,0x1d,0xeb,0xfd,0x6b,0xe6,0xf8,0x4b,0xe8,0xf3,0xba,0xbb,0x86,0x8e,0xe6,0x63,0x83,0x92,0x23,0x05,0x58,0x2e,0x61,0xdd,0x38,0xad,0x8d,0x19,0x7d,0xfa,0x7c,0x3e,0xc8,0x9f,0xae,0xea,0x6d,0x12,0xf0,0xa4,0x08,0xed,0x12,0x0c,0x97,0x87,0x58,0xd8,0xbc,0x3f,0xde,0x7c,0xee,0x0c,0xc0 +.byte 0xa2,0x2e,0xf0,0x25,0x6d,0xf3,0x30,0x23,0xa7,0xc2,0xc8,0x09,0x67,0x01,0xe1,0x25,0x26,0x46,0x38,0xf5,0x5e,0x55,0x8b,0xd6,0x43,0x6a,0xb8,0xe4,0xdf,0x0f,0x5d,0x6c,0xc3,0xb2,0x56,0x38,0xda,0xbc,0xbf,0x5e,0x85,0x8c,0xd5,0x2a,0x6a,0xe2,0xff,0x4f,0x36,0xf7,0x52,0x2c,0xe2,0xae,0x65,0x65,0xd1,0xfc,0xd3,0xc6,0xf7,0x26,0xa6,0xd0 +.byte 0x0b,0xc8,0xf0,0x68,0x5d,0x07,0x89,0x06,0xb3,0xfb,0x39,0x1d,0xd8,0xd8,0xd7,0x53,0xd0,0xc9,0x76,0x56,0xc0,0xd3,0xf5,0x66,0x80,0x5b,0xff,0x4a,0xdf,0xae,0x52,0x86,0x54,0x24,0x53,0xcf,0xcf,0xd2,0x89,0xde,0x71,0x62,0x9c,0x31,0xa5,0x3d,0x62,0x07,0xa1,0x33,0x49,0xbb,0x06,0x88,0xd8,0xa1,0xdd,0x0e,0x47,0x8d,0x72,0x00,0x2d,0x51 +.byte 0xa3,0x35,0x6e,0xb6,0x1f,0xbf,0xe5,0x42,0x68,0x6f,0x62,0xfa,0xf3,0x12,0xa9,0x1a,0xbd,0xe8,0xa4,0xf1,0x6d,0x07,0xe7,0x70,0x87,0x44,0xb7,0x3d,0xea,0xdc,0x3a,0x24,0xbd,0xa0,0x9b,0xb8,0xc5,0xa8,0xd9,0x06,0xde,0x02,0x68,0x7e,0xd5,0x2d,0x3b,0x5f,0x12,0x31,0x72,0x35,0x77,0xf6,0x10,0x6e,0x81,0x7d,0x3c,0xac,0x95,0x5b,0xbe,0x90 +.byte 0x74,0xf3,0x3e,0x9b,0x07,0x54,0x97,0xe3,0x1d,0xcf,0xe2,0xc5,0x80,0x6b,0x5f,0x0b,0x96,0x00,0x0f,0x0e,0x53,0x36,0x76,0x6e,0x99,0x0c,0x32,0xa2,0xc9,0xaa,0xa0,0xa1,0xb7,0xee,0x9d,0xd6,0x46,0xe7,0x2d,0x10,0x7a,0xf2,0x22,0x50,0x52,0xbf,0xec,0xcc,0xbc,0x0d,0x81,0x55,0x2d,0xac,0x2e,0xf7,0x99,0xbe,0x68,0x09,0xb0,0x11,0xc3,0xc8 +.byte 0xca,0x63,0xa7,0xc2,0x0f,0x37,0x2a,0x9e,0x85,0x79,0x6b,0x44,0xc1,0x4f,0xb9,0xd6,0x6c,0x56,0x0e,0x59,0x33,0xc3,0x00,0x53,0xe2,0xf4,0x30,0x90,0x4e,0x4b,0x09,0x4d,0x6f,0x9a,0x9e,0xb9,0x8d,0x0b,0xa1,0x80,0xfd,0xfb,0xde,0x74,0x49,0x53,0x04,0x3a,0x35,0xcb,0x45,0xe2,0x67,0x2c,0x4d,0x6e,0x39,0x7b,0xbd,0x68,0xaa,0x93,0x1e,0xee +.byte 0x1e,0x35,0xae,0x1e,0xf2,0xe7,0xb1,0x80,0x92,0x45,0x27,0x85,0xd0,0xc7,0x26,0x17,0x54,0x30,0xba,0x0c,0x8e,0x48,0xf3,0x08,0x51,0xa6,0x41,0x70,0xba,0x5b,0x90,0x69,0x7c,0x64,0x1d,0x61,0xb5,0x23,0x4a,0xef,0x97,0xe4,0x9a,0xd0,0xff,0x47,0x7a,0x93,0x1a,0x28,0xb3,0x8a,0x32,0x29,0xf8,0xe9,0x08,0xc3,0xf3,0x24,0xd7,0x2e,0x18,0x6d +.byte 0x99,0x40,0x77,0x43,0x9f,0x98,0xe4,0xe5,0x3a,0x34,0x9d,0x46,0x52,0x9f,0x84,0x79,0x8c,0x70,0xbc,0x88,0x30,0xaf,0x87,0x69,0x57,0x6e,0xde,0x2e,0xfe,0x0f,0x3b,0x8d,0xc8,0x95,0xcf,0x69,0x78,0xff,0xa1,0xb1,0x81,0x49,0x1e,0x45,0xc0,0x83,0x1b,0xa3,0x5a,0xee,0x3e,0x9a,0x15,0x7c,0xf0,0xa2,0xfd,0x04,0x22,0x55,0x2d,0x74,0x61,0x29 +.byte 0x0e,0x4f,0x31,0xdb,0x35,0x99,0x37,0xb7,0x7d,0x11,0xde,0x87,0x4f,0x84,0xeb,0x6c,0x14,0xcc,0xbb,0x71,0x47,0xab,0x5b,0x61,0x51,0xeb,0xa1,0xc1,0x5f,0xe4,0x5c,0x3c,0xab,0x04,0xf1,0x60,0x50,0xe1,0xd0,0x58,0xdf,0x42,0xed,0x73,0x5f,0x31,0xdf,0x8d,0xb8,0xb8,0xdc,0x4e,0x2f,0xe3,0x7f,0x89,0x9e,0x62,0xc9,0xef,0xfd,0x60,0xae,0x58 +.byte 0xa9,0xa5,0x8b,0xa8,0x3b,0xd8,0x5f,0xd4,0x09,0xff,0x61,0x8c,0x25,0xde,0x84,0x7f,0x35,0xc9,0x5c,0x2b,0xe8,0x46,0xe4,0x1c,0xbd,0x77,0x51,0x31,0x55,0x3d,0xb4,0x35,0xf3,0xdc,0xa5,0x55,0xd3,0xe3,0x24,0xf9,0x41,0xe2,0xf0,0xbd,0xf5,0xff,0x81,0x87,0x64,0xc9,0xe7,0x69,0x29,0x86,0xaf,0x98,0x33,0x33,0x62,0x9c,0x7b,0x16,0xbb,0xfe +.byte 0x0b,0xa7,0x92,0xa5,0x7b,0x81,0xbc,0x50,0x88,0xf6,0xe7,0xfc,0x73,0xd6,0x37,0x43,0x09,0xa5,0xc6,0xd6,0x4d,0x28,0xb5,0xaa,0x53,0x52,0x8c,0x2c,0x06,0x64,0x6c,0x21,0x6b,0xe7,0x67,0x4a,0xa5,0xcc,0xa1,0x32,0xf0,0xd9,0x78,0xb9,0xc3,0xdb,0x41,0xee,0x10,0x11,0x81,0x04,0x03,0x73,0x48,0xc6,0x3e,0x60,0x6d,0x82,0xef,0xe2,0xa8,0xe8 +.byte 0xd7,0xda,0xd9,0xb5,0x34,0x42,0xc8,0x1c,0xa7,0xa4,0x8e,0x88,0x2e,0xbc,0x96,0x0a,0xfc,0x40,0x36,0x80,0xdf,0x60,0xe9,0x03,0x02,0x0c,0x51,0xf7,0x7d,0x01,0xd2,0x21,0x38,0x44,0x4b,0x34,0x80,0xbf,0x5e,0xc1,0x86,0xf2,0x35,0xeb,0xa8,0x21,0x15,0x74,0x7c,0x99,0x55,0x64,0xf4,0x48,0xd6,0xd1,0x47,0x1f,0x4d,0xbf,0x0c,0x20,0x5d,0x86 +.byte 0xb9,0xab,0x4e,0xc8,0x86,0x08,0x71,0x1d,0x13,0xf6,0xd3,0x17,0xac,0x61,0x10,0x5d,0x2a,0xb4,0x48,0xa1,0xb9,0x79,0x5a,0x09,0x3a,0x65,0x4c,0xbd,0x97,0xbe,0x48,0xc6,0x66,0xd8,0xce,0x0c,0x19,0xb5,0x44,0x02,0xfa,0xb7,0xa8,0x3f,0x9b,0x86,0xec,0xd1,0xef,0x1d,0x7d,0xb3,0x82,0x5c,0x92,0x48,0x02,0x2c,0x56,0x0f,0xff,0xf7,0x19,0x74 +.byte 0xc2,0x38,0x24,0x8d,0xb2,0x87,0xb6,0xeb,0x49,0x50,0x6a,0x33,0x74,0x4e,0x2a,0xcb,0xf4,0x13,0x2c,0xfa,0x3b,0x0e,0x3d,0x98,0x3e,0x33,0xd9,0x55,0xfa,0xb9,0x74,0xb8,0x6f,0xc1,0xd8,0xfd,0x8f,0xff,0xb9,0x1a,0x17,0xf8,0xb6,0x21,0xc4,0x9d,0x47,0x5e,0x84,0xf6,0xe5,0xbf,0x93,0x98,0xac,0x8f,0x68,0x85,0xf8,0xe8,0x79,0x7f,0x6f,0x0d +.byte 0x62,0x2c,0xaa,0x1e,0xe4,0xab,0x73,0xf8,0x6f,0x02,0xda,0x6b,0x3c,0x14,0x2e,0xc9,0xdb,0xb0,0x4e,0x39,0xb5,0xcf,0x05,0xae,0x9c,0x63,0x2f,0x6a,0x25,0x61,0x9d,0x40,0xeb,0x7e,0xd8,0x97,0x97,0x33,0x67,0x5c,0x78,0x84,0x68,0xc2,0x7a,0x26,0x58,0xe3,0x6c,0x0a,0x2e,0x6a,0x82,0xd6,0x43,0xed,0x79,0xa5,0x8d,0x4e,0x7c,0xf7,0x80,0x01 +.byte 0xe7,0x02,0x5e,0x3a,0xf7,0x8a,0x4a,0x85,0xe9,0x98,0x1e,0x69,0x33,0xf3,0x54,0x96,0x79,0xc8,0x03,0x0a,0x9f,0x0c,0x5d,0x66,0x44,0x88,0x3c,0xd7,0x9e,0xd1,0xde,0x01,0xfd,0x5e,0xa5,0x6a,0x82,0x00,0x36,0xe6,0x12,0xe3,0x62,0x46,0x45,0x69,0xfb,0x4f,0x44,0x8e,0xe5,0x8d,0x21,0x57,0x6a,0x61,0x8e,0x56,0xcb,0x5b,0x2c,0x5f,0x65,0x41 +.byte 0x2c,0xad,0xf2,0x98,0x34,0xbb,0x06,0x0d,0x8a,0x3c,0x34,0x0d,0xa3,0xe2,0x6e,0x86,0xfa,0xa9,0xfb,0x6f,0xbb,0x32,0xd6,0x0d,0x76,0x6b,0x77,0xf3,0x83,0x41,0xc0,0x80,0x63,0x55,0x47,0xb8,0x13,0x6b,0x99,0x96,0x08,0x9b,0xc0,0x82,0xae,0x49,0x4a,0x51,0x63,0x74,0xf2,0xec,0xfa,0x0d,0xbc,0x3a,0xde,0xf5,0x4b,0x4f,0x08,0x41,0x23,0x88 +.byte 0x14,0x88,0x6a,0x3a,0xf0,0x5f,0x0c,0x45,0x7f,0x65,0x7a,0x67,0xd8,0x17,0xed,0x04,0x47,0x60,0x0e,0x74,0x8f,0xfd,0x48,0xda,0xcd,0xe9,0xfe,0xf5,0x6f,0x43,0xcd,0xa5,0x05,0xa2,0x2e,0x78,0x5b,0xff,0xb8,0x6f,0x2e,0xfd,0x3e,0x4b,0xef,0xcf,0xe0,0x06,0x57,0x28,0xf4,0x2e,0x3b,0xb5,0x9e,0x3c,0xbd,0x63,0xa6,0x78,0x8e,0xd5,0xb8,0x81 +.byte 0x4e,0xf0,0xbf,0x14,0x65,0xc8,0x00,0x9f,0x0e,0x25,0x6a,0x7a,0x63,0x58,0xe4,0xe7,0xa9,0x82,0x16,0xc9,0x86,0x20,0x94,0x71,0x5b,0x9f,0x9b,0xc3,0xc5,0x32,0xb0,0x6c,0x2b,0x8c,0x54,0x67,0x36,0x94,0xb1,0x47,0x33,0xfd,0x9f,0x7c,0x7f,0x7e,0x08,0x51,0x1f,0x7e,0xbf,0x09,0x57,0xf3,0xaa,0x77,0x94,0xf3,0x20,0x1b,0x95,0xf6,0x04,0xb2 +.byte 0x09,0x9d,0xe2,0xbb,0x4d,0xfe,0x6b,0x99,0x06,0x58,0x40,0x84,0x90,0xfa,0x0e,0x9b,0x58,0x6d,0x02,0xbe,0x53,0x73,0xd1,0xc9,0xc7,0x31,0x2a,0x4a,0x12,0x2c,0xb6,0x1c,0xfb,0x49,0xc6,0x1a,0x93,0x33,0x1f,0x29,0x8b,0x94,0xe9,0x20,0xa7,0xe6,0x20,0xe6,0xbf,0xcd,0x5c,0xb6,0x52,0x42,0xf0,0x9c,0x6c,0x21,0x61,0x10,0xe7,0x0e,0x9f,0x33 +.byte 0x5f,0xc8,0xd0,0x20,0xe0,0x3e,0xc5,0x7a,0x10,0xf1,0xe5,0x19,0x52,0xcd,0xe1,0xa8,0x62,0x43,0x20,0x79,0xc3,0xac,0x93,0x27,0x02,0x8e,0x21,0x06,0xb9,0x66,0xd9,0xc8,0x40,0xe0,0xd1,0xf0,0x64,0x81,0xa6,0xc4,0x87,0x85,0x2b,0x92,0x1c,0xd6,0x48,0x85,0xb1,0xbe,0x78,0xf3,0x89,0xa2,0xf0,0xe5,0x39,0xac,0xbf,0x59,0x5d,0xf8,0x4f,0x74 +.byte 0x44,0x85,0x98,0x03,0x81,0x4b,0x7e,0x6f,0x5c,0xa1,0x11,0xd2,0xfd,0x30,0x7f,0xcd,0xd0,0xe2,0xcc,0xd4,0x80,0x16,0x46,0xa6,0x64,0x8b,0x9e,0xfc,0x2a,0x1a,0x65,0x5c,0x90,0x82,0xf9,0x23,0x48,0x11,0xf6,0xf2,0x50,0x3f,0xed,0x44,0xf2,0x9a,0x5a,0xca,0x1c,0x9a,0xd2,0x71,0x1b,0xd6,0x4c,0x51,0xf6,0x89,0x6f,0x65,0xe4,0x97,0x41,0x47 +.byte 0x1b,0x86,0xbd,0x83,0xa0,0xfe,0xac,0x16,0xe8,0xab,0x28,0x96,0x2f,0xa2,0x12,0x5f,0x7c,0xb3,0x18,0x2b,0x05,0x51,0x49,0xba,0xb4,0x1f,0x1e,0xe6,0x8a,0x82,0xca,0x33,0x7d,0xe6,0x8c,0x95,0xba,0x08,0x60,0x47,0x6d,0x79,0xac,0x0f,0xba,0x46,0xff,0xed,0xe0,0x34,0x03,0xfe,0xa7,0x85,0xe5,0x61,0xe3,0xe4,0x6c,0x5c,0x1b,0x9d,0x8a,0x54 +.byte 0x17,0xaf,0x08,0x4c,0x44,0x7f,0xb7,0xb0,0x6a,0x3a,0xff,0xb7,0xf6,0x10,0xc4,0x8f,0x31,0xd6,0x1a,0x25,0x27,0x35,0xca,0x87,0xa9,0x61,0x0b,0x35,0x96,0x89,0x0f,0x1a,0xbd,0x1e,0xf6,0xee,0xaa,0x95,0x16,0xe4,0x38,0x7b,0xb2,0xbe,0xea,0xc9,0x5a,0xcd,0x3b,0xb8,0x9e,0xd7,0x20,0xcd,0x3f,0x90,0xaa,0x8b,0x2a,0x42,0xed,0xab,0xc1,0x53 +.byte 0x83,0xc7,0xb8,0x3f,0xa1,0xb9,0xf4,0xf4,0xb0,0xe0,0x1f,0xb0,0xeb,0xa9,0x81,0x9f,0x31,0x67,0x1e,0x6c,0x96,0x9f,0x09,0xea,0x04,0xfe,0x37,0x22,0x87,0x60,0xb9,0x91,0x8f,0xa9,0x11,0xa3,0x68,0x5e,0x29,0x21,0x41,0xa3,0x02,0x08,0x82,0xd0,0x2b,0x66,0x6d,0x3c,0x46,0xc7,0x23,0x09,0x86,0x7f,0x53,0x11,0x3e,0x83,0x52,0x0a,0x4a,0xe4 +.byte 0x93,0xc6,0xc1,0x96,0x17,0x94,0x51,0x17,0x69,0xea,0x72,0xb8,0x85,0xde,0x7e,0x13,0x4a,0x08,0x26,0xae,0x31,0x19,0x0f,0x6f,0x48,0xa1,0xf2,0x57,0xa2,0x01,0x8e,0x84,0xee,0x63,0x23,0xc0,0x97,0x84,0xa2,0xf5,0x3f,0xeb,0x30,0x9e,0xdd,0xd2,0x43,0x24,0xa2,0x57,0xb7,0x57,0x86,0x26,0xa3,0xe6,0x6e,0xf2,0xcd,0xfb,0x7b,0x34,0x74,0x53 +.byte 0x07,0x95,0x51,0xb7,0xfd,0xf3,0xd1,0x83,0xbd,0x25,0xd6,0x2c,0x69,0x73,0x02,0x8e,0x76,0x19,0xea,0xb0,0x83,0x60,0x8c,0x53,0x9d,0x77,0x86,0x1e,0x65,0xc7,0x57,0x31,0x29,0xd9,0xa9,0x3a,0xb2,0x0d,0xd8,0xf4,0xf9,0x48,0x49,0xfb,0x3c,0x40,0x3d,0x1b,0xc4,0x8b,0x94,0x0e,0x50,0x7f,0xd5,0x39,0x5e,0x57,0x86,0xd1,0xba,0x0c,0x38,0x10 +.byte 0x01,0x5f,0x44,0xf3,0xe5,0xb0,0xf8,0xae,0x17,0xdf,0xd2,0xb3,0x10,0xc5,0x3b,0xfd,0xd9,0x68,0x90,0x9c,0x6c,0x26,0xdf,0x12,0x50,0xfa,0xbf,0x8b,0xce,0x68,0x80,0x8c,0x04,0x60,0xbf,0x34,0x81,0xbd,0x29,0xa3,0xa2,0xe4,0xe0,0x2d,0x25,0xb2,0xff,0x9f,0xd1,0x20,0x07,0xd5,0x8c,0x19,0xfa,0x3f,0x47,0xec,0xc1,0x8d,0xc9,0x36,0xf8,0x51 +.byte 0x4c,0xaa,0x40,0xe3,0x6a,0x21,0xd5,0xe6,0xa6,0xcf,0x8c,0xd9,0x10,0x47,0x66,0xfd,0x32,0x48,0x36,0x8f,0x14,0xed,0x09,0x80,0x50,0x27,0xaa,0xd5,0x1f,0x69,0xb8,0xe4,0x96,0x27,0x56,0x78,0xd6,0xd5,0x2d,0xf0,0x4f,0x14,0x30,0x17,0x9e,0x5b,0x69,0x8c,0x7c,0x1c,0x97,0x38,0x65,0x77,0x75,0x49,0xac,0x4b,0x06,0xda,0x74,0x11,0x86,0xbc +.byte 0xad,0x01,0xf2,0x03,0x29,0x5d,0xa7,0x74,0xd3,0x44,0xae,0x1d,0xbf,0xf9,0xc5,0x5b,0x83,0x8c,0xd6,0x84,0x8a,0x8e,0xe9,0xa6,0x08,0xf4,0x88,0x13,0xcb,0x16,0x45,0x13,0x9c,0xc7,0x75,0xa9,0xa7,0x55,0x04,0x91,0xd6,0xe9,0xd4,0xe5,0x65,0xa0,0x3a,0x53,0xa0,0xfc,0x62,0xce,0x91,0x01,0xb4,0x06,0x8b,0x10,0x79,0x6f,0x2c,0xd6,0x0a,0xa2 +.byte 0x31,0x8f,0x75,0x32,0x0e,0xfa,0x0d,0xec,0xfd,0x71,0x7f,0x74,0x97,0x30,0xe9,0xee,0x9f,0x04,0x21,0xb5,0xc9,0xd1,0x52,0x2a,0x0f,0x18,0xbe,0x3e,0xbb,0x98,0xaf,0x59,0x9b,0x85,0x79,0x5e,0x52,0x93,0x1c,0x42,0x67,0x67,0x6b,0xd5,0x41,0xaf,0xba,0x09,0x3a,0xb4,0x0e,0x97,0x22,0xe6,0xbb,0xe1,0x27,0xa1,0xf9,0xf0,0xcd,0xa2,0x3d,0xdb +.byte 0x81,0x2f,0x65,0x90,0xb7,0xe5,0xe5,0xce,0x1d,0x3b,0xfe,0x34,0x57,0xcd,0x3a,0xbd,0x19,0x59,0x23,0x12,0xf1,0xb6,0xf2,0xf7,0xc1,0xf5,0x1d,0x0b,0x46,0x8f,0x16,0x6a,0x81,0xfe,0xc1,0x97,0x8d,0x69,0x55,0x60,0xdd,0xf0,0x61,0xe9,0x22,0x30,0x72,0x1a,0x24,0x30,0xd7,0xbc,0x1c,0xfa,0x02,0x55,0xfc,0xb9,0x4b,0x0a,0xe4,0x90,0x90,0x3a +.byte 0xe3,0xce,0xd4,0xa0,0x7d,0x21,0x5a,0xf7,0x79,0x6e,0x03,0x4f,0x4e,0x93,0xad,0xc4,0x8e,0x9d,0x9f,0x8a,0x39,0x59,0x20,0xc1,0x5d,0x6a,0x4d,0x8f,0x69,0x78,0xea,0xba,0xde,0xc0,0x87,0xb2,0xf2,0x20,0xd6,0x7a,0x9c,0xf9,0x09,0x03,0x2a,0x4d,0xb9,0x10,0xfc,0xe5,0x05,0x90,0xed,0x45,0x4f,0x5f,0x7c,0x5d,0xfa,0xe6,0x0d,0x07,0xae,0xcc +.byte 0x21,0xc8,0x1c,0x7a,0xfb,0x1d,0xb9,0xe3,0x69,0xa1,0xb7,0x5f,0xb5,0x6a,0xb9,0x58,0x9d,0xcd,0x99,0xf8,0x38,0xbb,0xa0,0xfe,0xf8,0x41,0x51,0x72,0xce,0x76,0x89,0x59,0xa2,0xab,0xef,0xea,0xab,0x79,0xbc,0xda,0x73,0xdb,0x18,0xda,0x60,0x1b,0xc4,0xb7,0x4f,0xb3,0x86,0x21,0x2a,0xc3,0xec,0x7f,0x0e,0x89,0x16,0x0e,0xd2,0xbd,0xea,0x0e +.byte 0xcf,0xc1,0x4b,0x2c,0x97,0x69,0xce,0xd3,0x94,0xad,0x81,0xe9,0x70,0xf4,0xf8,0xe5,0x77,0xe6,0x92,0xe0,0x23,0x38,0xd3,0xc1,0xdd,0x2e,0x58,0x77,0xc5,0xc3,0x29,0x34,0x66,0x48,0xf9,0x75,0x3c,0x8a,0x6a,0xb8,0xbf,0xf8,0xba,0xf0,0xb9,0xa1,0x81,0x0b,0xa1,0xaa,0x17,0x34,0x1a,0xbb,0xa3,0xa2,0xba,0x21,0x45,0xc0,0x1d,0x57,0x11,0x4d +.byte 0x9b,0xd4,0x64,0x84,0xd7,0x0b,0xd6,0xfb,0x72,0x2c,0xdb,0xc3,0xe6,0x24,0xa9,0xf3,0x30,0x9f,0x21,0x05,0x1e,0xcc,0x48,0x58,0xed,0xfd,0xb2,0x34,0xe3,0xf7,0x7e,0x56,0xee,0xdf,0xa4,0xbb,0xb1,0xcc,0x7f,0x81,0x40,0xe9,0xdf,0x3f,0x82,0xc4,0x0d,0x14,0x9b,0x3b,0x80,0x15,0x24,0x6e,0xa4,0xce,0xfa,0x28,0xa7,0x7f,0x89,0xfb,0xc6,0x83 +.byte 0xe8,0x2a,0x70,0xfb,0x9c,0x75,0xb8,0xfd,0xec,0xbc,0xbb,0xf5,0xef,0x0a,0xa5,0x77,0x0b,0x38,0xa0,0x63,0xa5,0x71,0x12,0xc9,0xaa,0xc3,0xf9,0x72,0x30,0x45,0x4e,0x19,0x44,0x2d,0x09,0xf4,0xf1,0xa8,0xe8,0xde,0x58,0x87,0x70,0xa8,0x91,0x86,0xef,0x5d,0x02,0x90,0x55,0x63,0x99,0xde,0xd7,0xb7,0x5f,0x07,0x01,0xdf,0xb1,0xe5,0x55,0xf5 +.byte 0x87,0x69,0xd2,0x7a,0x71,0xbc,0x0e,0x4b,0x8b,0x98,0xf7,0xf6,0x0a,0x01,0xbb,0x9f,0x1b,0x15,0xb6,0x76,0xe0,0xc0,0x4b,0x5d,0x08,0xba,0xba,0x73,0x3f,0x36,0x5a,0x29,0xd7,0x7c,0xc2,0x87,0x03,0x75,0xff,0x26,0x21,0xae,0xbe,0x66,0x70,0xa2,0x99,0x11,0x35,0x49,0x78,0x7b,0x3a,0xfe,0x94,0xf7,0x37,0xe0,0x69,0x56,0x39,0xf7,0x3f,0x71 +.byte 0x39,0x74,0x75,0x32,0x1f,0xfb,0x3a,0x87,0x07,0xab,0xf1,0xed,0xe3,0xe2,0xbf,0x3f,0xb1,0x73,0x11,0xc9,0x34,0x4b,0xb1,0x1e,0x62,0x4e,0xc1,0x8a,0xae,0xcc,0xc7,0xb3,0xa7,0x70,0x01,0x73,0xad,0xb3,0xc3,0x59,0x70,0x14,0x31,0x94,0x9f,0x6b,0x18,0x11,0x50,0x52,0xc9,0xf0,0xf8,0x12,0x9d,0x7c,0x90,0x64,0x9d,0xd9,0x41,0xa6,0x45,0xe3 +.byte 0xc9,0x25,0x73,0xe7,0x48,0x9d,0xdc,0xe0,0x2c,0x71,0xd3,0x68,0xc5,0xab,0xac,0xe3,0x16,0x95,0xe3,0xa5,0xae,0x2f,0x57,0x60,0x4b,0x11,0x90,0xaa,0xe7,0x48,0xca,0xc7,0xde,0x2e,0x56,0x10,0x8e,0xc3,0x0a,0x7d,0x66,0xf1,0xc3,0xf7,0x2d,0xdd,0xfa,0x5e,0xb2,0xcb,0x99,0x4d,0xaa,0x4e,0x91,0xc1,0x94,0x60,0x27,0x33,0x82,0xa6,0x2a,0xba +.byte 0x05,0x32,0x33,0x0a,0x30,0x47,0xb0,0xac,0x68,0x7d,0xef,0x25,0x09,0xcf,0x51,0xf4,0x06,0x28,0x14,0xb2,0xb4,0x1f,0xaf,0x37,0xdc,0x70,0x88,0x4d,0xb9,0xfc,0x2d,0x61,0x25,0x13,0x1f,0x32,0x48,0x6d,0xeb,0x46,0x05,0x66,0x44,0xa1,0xec,0xce,0xe9,0x51,0xa9,0xba,0xf8,0xde,0x95,0x1b,0x20,0xe1,0x21,0x75,0x4b,0x25,0x7f,0x3c,0x16,0xf7 +.byte 0xe2,0xbe,0xeb,0xca,0x2b,0x77,0x92,0x16,0x32,0xe2,0x74,0x21,0x52,0x3f,0x08,0xba,0x41,0xb0,0xd3,0xd2,0xf7,0xf3,0x29,0xb6,0x10,0xfa,0xa5,0x29,0x35,0x29,0x21,0x0d,0xec,0xba,0x5a,0xf3,0x63,0x0f,0x9d,0xbc,0x42,0x02,0x46,0xe9,0x07,0x4a,0x9a,0xe8,0xd3,0x78,0x92,0xa2,0xe5,0x03,0xec,0xd4,0xe2,0xc8,0x8f,0x92,0x4a,0xae,0xbc,0xd7 +.byte 0xdf,0x4b,0x07,0x22,0x47,0xbd,0xb4,0xb5,0xa0,0x7e,0xfb,0x21,0x40,0x62,0xb1,0x6c,0x07,0x00,0x64,0xf6,0xb2,0x75,0x5c,0x29,0x84,0xff,0x38,0x0c,0xc8,0x08,0x38,0x92,0xf9,0xad,0xd7,0xcc,0xc3,0x1c,0x03,0x80,0x49,0x39,0x1c,0xdb,0xae,0x60,0x87,0x8a,0x5c,0xe9,0x17,0xbd,0x2b,0x0f,0xa5,0xa1,0xf9,0x0d,0x4b,0x8c,0x4d,0x39,0xda,0x15 +.byte 0x8c,0xc4,0x69,0xaf,0x2b,0xb0,0xa1,0xfd,0xd9,0x65,0x3c,0x87,0x4b,0xf2,0x5a,0xd7,0xd8,0xb9,0xef,0x78,0x67,0x30,0x4c,0x6c,0x92,0xc5,0x1e,0x15,0xf8,0xd9,0x74,0x1b,0x54,0x0c,0x10,0x1b,0xb5,0x11,0x13,0xd6,0xb4,0xc0,0x53,0x03,0x2c,0x4b,0xee,0xac,0xf9,0x87,0x17,0x51,0x35,0xb8,0x1a,0xdc,0x16,0x61,0x5b,0xe9,0x5a,0x43,0x94,0x42 +.byte 0x8f,0x68,0xbd,0xb6,0x52,0x00,0x63,0xa3,0x52,0x6e,0x5d,0x8e,0xe9,0x4f,0xf5,0x69,0xd8,0x4f,0xf5,0x5c,0x89,0x7e,0x1c,0xb9,0xdc,0x7b,0x92,0x8a,0x2b,0xfc,0xb8,0xad,0xbb,0xff,0x61,0x2e,0xc0,0xdc,0xfb,0x2f,0x78,0x2a,0x50,0x32,0x9b,0x4c,0xfd,0x9e,0xab,0x80,0x5c,0x7d,0xc8,0x6b,0xb3,0x2d,0x0a,0xfe,0x43,0xa2,0x10,0x10,0x79,0xbc +.byte 0x8c,0xa0,0x86,0x09,0x8c,0x8b,0x28,0xf3,0x8a,0xc9,0xeb,0xcb,0xb5,0x0e,0x56,0x19,0xae,0xe0,0xa1,0x22,0x72,0xc5,0xad,0x01,0x12,0x69,0xb6,0x52,0xb8,0xdd,0x36,0x25,0x21,0xae,0x73,0x06,0xc1,0xe0,0x23,0x20,0xe1,0x8e,0xe4,0x99,0xcd,0x86,0xca,0xf5,0x93,0x0e,0x6b,0xb8,0xba,0x18,0x4a,0x36,0xed,0xd0,0x37,0xc8,0xc7,0x8a,0xb2,0x63 +.byte 0x2e,0xa4,0x22,0x76,0x6f,0xf7,0xdd,0x81,0xd6,0x6f,0xcd,0xb9,0x65,0xf0,0x95,0x77,0xae,0xca,0x54,0x62,0xce,0x5d,0x47,0x9e,0x10,0x89,0xb9,0xfa,0x72,0x0a,0xef,0x24,0x17,0x45,0xb0,0xb0,0xc7,0x51,0x85,0xa1,0xb1,0x6a,0xd2,0xea,0x48,0xe2,0x6a,0x03,0x2a,0xdf,0xa8,0x0e,0x62,0xa2,0x1e,0xe2,0xa7,0x20,0x57,0xbd,0x73,0xeb,0xef,0x86 +.byte 0xc9,0xd4,0xfa,0x96,0xfe,0xfa,0xb3,0xc6,0xbf,0x7a,0x16,0xa2,0x43,0x73,0x56,0x71,0x78,0x32,0x3b,0xc1,0xd8,0x26,0xbf,0xde,0x39,0x5d,0xbd,0x3b,0xff,0xd7,0x4f,0xa0,0x67,0xa6,0x09,0x9a,0x81,0xfd,0xec,0x34,0x73,0xcd,0x90,0x15,0x8b,0x3e,0x2d,0x6f,0x7d,0xcc,0xf5,0x20,0x15,0x07,0xa8,0x2f,0xa5,0x5b,0x2b,0x4f,0xb8,0x2f,0x14,0x6c +.byte 0x52,0x78,0xbd,0x92,0x98,0xda,0x69,0x19,0x58,0x4c,0x76,0xe4,0x20,0xb2,0x48,0xa4,0x9f,0x2f,0x4c,0x9b,0x45,0x7f,0x7d,0x1c,0x46,0xe9,0x1e,0x43,0x26,0x49,0x39,0xb6,0x42,0x3a,0x4c,0x59,0x95,0x6b,0x28,0xd5,0xbe,0xa7,0x2e,0xd0,0x0c,0x00,0xa0,0x67,0x06,0x4e,0xee,0xae,0x7f,0xc2,0xb5,0x12,0x46,0x3f,0xb4,0x35,0x16,0x2a,0xda,0xbf +.byte 0x41,0x34,0xbe,0x30,0x2a,0x0f,0x7b,0x60,0xa6,0x8b,0xcd,0xae,0x7a,0x8c,0xd6,0x97,0xab,0x06,0x1e,0x14,0x87,0x45,0xa3,0x3c,0x9c,0xc4,0xa0,0x1d,0xee,0xf0,0xca,0xb8,0xa6,0x8d,0x37,0x92,0xad,0xbc,0xe6,0x1f,0x65,0x75,0xd3,0xbc,0x72,0x66,0xe2,0xff,0xbc,0x19,0x93,0xae,0xee,0xd0,0x63,0x6d,0x97,0x6f,0x57,0xf3,0x77,0xcd,0xe3,0x57 +.byte 0x3f,0x00,0xc8,0xe1,0x63,0x83,0x15,0x84,0xc6,0x08,0xdb,0x03,0xc9,0x27,0x47,0x4c,0x17,0x12,0x40,0x6e,0xac,0x74,0x6f,0x3c,0x22,0x57,0x36,0x29,0xbb,0x6a,0xc7,0x5a,0xfe,0x60,0x1c,0x0f,0x32,0x95,0x1b,0xf2,0x3c,0xed,0x04,0x87,0x4c,0x48,0xc7,0x63,0x79,0x24,0xb3,0x12,0xbf,0x55,0x3b,0x32,0xbf,0x52,0x4e,0x1e,0xc1,0x1f,0xf2,0xfd +.byte 0xe6,0xb8,0x56,0x38,0x0e,0xd2,0x75,0x3d,0x41,0x99,0x0c,0x7a,0x12,0x3f,0xa7,0x3a,0x79,0xa0,0xd7,0x6f,0x47,0x97,0x7e,0x9e,0xf6,0xfe,0x29,0xc0,0x16,0x34,0x38,0x80,0x2f,0xde,0x65,0x79,0xc9,0xfd,0xa0,0x84,0xc3,0x39,0xbc,0x0b,0xbe,0x18,0xba,0x0d,0xe3,0x35,0x11,0xba,0x9f,0xde,0x5d,0x0c,0xae,0x8e,0x0c,0x0f,0x66,0x9c,0xe6,0xfc +.byte 0x3d,0xdb,0x46,0xf1,0x84,0x57,0x62,0xb0,0x00,0xd4,0x8c,0xaa,0x93,0xeb,0xf7,0xa7,0x8e,0x82,0xba,0x89,0x67,0xbb,0x38,0xb0,0xb6,0x13,0x0c,0x96,0x22,0x9c,0x6a,0x86,0xea,0x83,0xad,0x5f,0x7b,0x3a,0x28,0xd8,0x53,0x90,0x2d,0xab,0xc9,0xbe,0x99,0xfb,0x68,0x42,0x27,0xf6,0xe3,0x5a,0xaf,0xf3,0xd6,0xee,0xb6,0xa2,0xe0,0x32,0x3c,0x1d +.byte 0xd4,0x3c,0x2b,0x58,0xc2,0x4f,0x3d,0x20,0x39,0xdb,0x80,0x89,0x20,0x20,0x7b,0xe6,0x1d,0xd0,0xa2,0x1a,0xd4,0x88,0xc9,0xe0,0xb9,0xf6,0xb2,0xa1,0xcd,0xf2,0x67,0x60,0x44,0xd8,0xce,0x6a,0xe2,0x52,0xc3,0xf3,0x61,0xa3,0x14,0x58,0xd6,0xe5,0x43,0x4a,0x8d,0xcc,0x4f,0xf8,0x17,0xdd,0xd2,0x5d,0xd5,0x5a,0x86,0x8e,0xc4,0x74,0xdc,0x1b +.byte 0xad,0xca,0x63,0x75,0xf0,0x43,0x41,0x16,0x02,0x49,0x6a,0x3a,0xe3,0xb9,0xa9,0xdc,0xfb,0x99,0xbc,0x60,0x0d,0xdb,0xa0,0xcf,0x27,0xaa,0xd5,0xc5,0x42,0x0b,0x02,0x00,0x43,0xaf,0xb5,0x4f,0xe1,0x88,0xa1,0x9d,0xca,0xfb,0x9f,0x1f,0x08,0x9c,0x66,0x23,0xca,0x4b,0x88,0xb4,0x40,0xdc,0xd3,0xd3,0x1a,0x64,0xe3,0x9b,0x43,0xea,0x20,0x90 +.byte 0x30,0x2e,0xc4,0x75,0xc5,0x52,0xc5,0x7c,0x0e,0x35,0x56,0xf5,0x1f,0x50,0x2b,0xf6,0x28,0x93,0x6f,0xde,0x10,0xc6,0x49,0x2b,0x77,0xb1,0x6d,0xce,0xfd,0x37,0xd4,0x8d,0x11,0xed,0x88,0x1e,0xca,0x68,0x0c,0x4e,0x38,0x7f,0x0f,0xab,0x6f,0x8d,0x1c,0x7d,0xd4,0x7d,0xd8,0xa9,0x5c,0x24,0x5a,0x7d,0xf4,0x5b,0xb6,0xb7,0x28,0xc7,0x93,0xd6 +.byte 0xa9,0xe5,0xac,0x62,0x16,0x9c,0x4e,0x5c,0x24,0xa0,0x2a,0x76,0xce,0x7d,0x5c,0x4b,0xbe,0xbc,0x83,0x5c,0x9a,0xc8,0x06,0x7b,0x1e,0xac,0x98,0x67,0x17,0x32,0x94,0xda,0xd1,0x8b,0x58,0xad,0x8e,0x26,0x03,0x81,0x7c,0x48,0xd1,0x83,0x03,0xba,0x6c,0x51,0xe9,0x25,0x82,0xd2,0xb9,0x7f,0xd8,0x33,0x3f,0x77,0x29,0x45,0x41,0xa9,0x17,0x3d +.byte 0x62,0xc6,0xd2,0xfb,0xd1,0x24,0xc7,0xee,0x10,0xc0,0x64,0xc3,0x46,0xc6,0x2b,0xe8,0x9c,0xc8,0x99,0x23,0x77,0xa9,0xb5,0x12,0xc4,0x53,0xde,0xbc,0x20,0xb2,0xc4,0x12,0xdb,0xc2,0x0b,0x63,0x70,0x6a,0x41,0x31,0x65,0x48,0xa0,0xfc,0xbc,0xd6,0x3f,0x55,0x18,0x17,0x65,0x35,0x58,0xe3,0x33,0xac,0xaf,0xca,0xb2,0x51,0xc1,0xcc,0x60,0x38 +.byte 0x94,0x8f,0x13,0xb8,0xcc,0x8c,0xc4,0x12,0xea,0xd5,0x39,0xd3,0x46,0x55,0x17,0x27,0x7a,0x07,0x01,0x02,0x74,0xa6,0xe7,0xc8,0xa7,0xd0,0x76,0xc8,0x5e,0x57,0x50,0xc5,0x19,0xf1,0x95,0xa3,0x52,0x10,0xa3,0x1e,0xcd,0xb1,0x05,0x64,0xe5,0x69,0xd9,0x5e,0xfc,0x71,0xef,0xe1,0xf6,0xb3,0xa7,0xf7,0xf9,0x71,0xfd,0xbb,0x5b,0x2b,0x7a,0xd2 +.byte 0x72,0x7c,0xc7,0x73,0x89,0xf7,0xe2,0x0b,0xcd,0x05,0x4f,0x0c,0x10,0xed,0xcc,0xda,0xb6,0x81,0x19,0xe6,0x2b,0x06,0x66,0xef,0xc5,0xfd,0xd5,0xc6,0x66,0x20,0x86,0x2a,0x4f,0x05,0x49,0xf1,0x54,0x4a,0x6e,0x1d,0xcd,0xad,0x18,0xeb,0x6c,0x58,0xd6,0x75,0x3e,0x62,0x48,0xab,0xea,0x1f,0x7f,0x05,0x45,0x6e,0x75,0x2a,0x5e,0x97,0x5b,0xde +.byte 0x5a,0x99,0x42,0xc1,0x62,0xab,0xc7,0x01,0x4d,0xac,0xd6,0xdc,0xc9,0x71,0x24,0xd1,0x33,0xe2,0x4b,0x1f,0x09,0x04,0x1f,0x0d,0x42,0x45,0xcf,0x7c,0xa0,0xee,0x48,0xfd,0x8b,0x1f,0xaa,0x50,0x48,0x6d,0x8e,0x34,0x76,0x09,0x23,0x8a,0x40,0x0d,0x5d,0xc1,0x2a,0xba,0x5f,0x9c,0x86,0xfb,0x37,0xdf,0x24,0xff,0x27,0x88,0xbf,0xf6,0xa4,0xc3 +.byte 0xf0,0xd3,0x02,0xa8,0x7c,0x6d,0xc4,0xc5,0x14,0xc3,0x64,0x28,0xa8,0x05,0x33,0xc2,0xda,0x12,0xfc,0xbe,0x0d,0x8e,0xf4,0xf5,0x48,0x5a,0x8e,0x8a,0xd2,0x50,0x7c,0xc0,0xbc,0xde,0xdb,0x9a,0xf6,0xa0,0x92,0x8d,0x19,0xbc,0x5a,0xdc,0xbf,0xfb,0x13,0x8f,0x41,0x09,0xba,0xd9,0x0b,0x91,0x7a,0xdb,0x92,0x10,0xac,0xf2,0xb5,0x76,0xb5,0x7d +.byte 0x80,0x04,0xd6,0xec,0x98,0x09,0x5f,0x63,0x0d,0x58,0x00,0x8a,0x07,0x76,0xfa,0xe6,0x6e,0xdf,0xbf,0x73,0xe5,0xc9,0xe5,0x12,0x44,0x58,0xf9,0x2e,0xb1,0xe6,0x2c,0xf5,0x0d,0x94,0xa9,0x51,0x0d,0x01,0x03,0xab,0x79,0xf9,0xee,0x7e,0x10,0x4b,0xcb,0x20,0xbb,0x01,0x19,0xd6,0x12,0xd1,0xac,0x96,0xe9,0x0e,0xde,0xbf,0x7e,0x80,0xf6,0x58 +.byte 0xc9,0xec,0xaf,0xf7,0x2d,0x98,0xbc,0x2b,0xb1,0xf1,0x34,0x94,0x39,0x8e,0xbc,0x13,0x13,0x41,0x8f,0xf3,0x4e,0x4e,0x6b,0x2a,0xaa,0xea,0x70,0x5c,0xf8,0x42,0xf7,0xbc,0xfd,0xbd,0x6f,0x62,0x1b,0xcb,0xb9,0x39,0xdc,0x6a,0x47,0x81,0xaf,0xff,0x5b,0x7e,0x80,0xb9,0xbf,0xfa,0x15,0x7e,0xd1,0xc3,0xb2,0x80,0x99,0xbd,0xb9,0x30,0x8d,0xb5 +.byte 0x43,0x6b,0x7a,0x31,0xaf,0x45,0xf7,0xdd,0x21,0x8f,0x54,0xb1,0xf6,0x2d,0x7d,0x96,0x63,0x4a,0x93,0x98,0x37,0x7f,0x48,0x02,0x4b,0x0f,0x71,0xe4,0x70,0xce,0x66,0x6a,0x36,0xde,0x58,0x84,0x69,0xd6,0xbd,0x1a,0x9a,0x8b,0xc5,0xda,0x97,0xc5,0xe1,0x4e,0xec,0x9b,0x7a,0x65,0xe0,0xa5,0xdd,0x39,0x3c,0x9f,0xfd,0x45,0x17,0x4c,0x2f,0xb4 +.byte 0xb1,0xb1,0x42,0xe8,0x88,0x75,0x9f,0xb4,0xc1,0xdf,0x44,0xf9,0x4f,0x9a,0xf7,0x3d,0x35,0xc5,0x32,0xbe,0x43,0xd0,0x0d,0x71,0x4e,0x21,0xbf,0x31,0x99,0x73,0x5a,0x84,0x45,0x2e,0x00,0x8b,0x42,0x2b,0x14,0x86,0x51,0xcb,0xa0,0x98,0xa9,0x68,0x8d,0xdb,0x58,0x3d,0x73,0x9d,0xf9,0x2d,0x86,0x76,0x62,0xcb,0x93,0x29,0x48,0x92,0x38,0xfb +.byte 0xeb,0x1d,0xda,0xc3,0x10,0x1f,0x32,0x68,0xee,0xcb,0xb7,0x8a,0xcb,0xcb,0xe0,0x37,0x31,0xe8,0xad,0x7b,0x4a,0x29,0x2c,0x10,0x9e,0xdf,0x86,0xeb,0x13,0x0c,0xab,0xa4,0x30,0x36,0xf0,0xe0,0xac,0x14,0x41,0xa4,0xf4,0xf8,0x44,0x95,0xe8,0x8f,0x28,0xc2,0x35,0x0a,0x44,0x61,0xc7,0x60,0xc5,0x3b,0xc4,0x1d,0x67,0xfd,0xac,0x0b,0x2e,0x49 +.byte 0x62,0xea,0x17,0x3c,0xf5,0x4b,0xbe,0xba,0xba,0x42,0x02,0x0d,0x13,0xf1,0x15,0xff,0x2e,0x47,0x46,0xd1,0x27,0x64,0xb7,0x35,0x28,0x31,0xb5,0xde,0x1e,0xf9,0x26,0x6c,0x04,0x3c,0x0e,0x06,0x9d,0x4d,0xc7,0x1c,0x97,0x67,0x2c,0x6d,0x36,0x0d,0x4c,0x61,0x08,0xe9,0xbd,0x04,0x1d,0x8d,0xfb,0x0c,0x03,0x3d,0xb4,0x40,0xd5,0x1b,0x69,0x3b +.byte 0x68,0xcf,0x46,0x27,0xcf,0xb3,0xda,0x1e,0xdc,0x85,0x6f,0x4f,0x6b,0x09,0x9d,0xe9,0x6c,0x73,0x40,0x27,0xc9,0x8b,0x12,0x97,0xea,0x34,0xd7,0x51,0x32,0x90,0x4e,0xd7,0x91,0x41,0x3a,0xee,0xbc,0x97,0xb0,0x4a,0x39,0xdb,0xe3,0xe5,0x12,0x73,0xbf,0x5d,0x68,0xe0,0xc6,0x7c,0x6f,0x0d,0x14,0x1c,0xaa,0xde,0x29,0xb7,0xc7,0xa5,0x90,0x62 +.byte 0xe9,0xc5,0x75,0x16,0xe6,0xc0,0x9d,0xc5,0xb8,0xd6,0xfa,0xb0,0x72,0xb7,0x27,0xa6,0xa8,0x3f,0xbf,0x18,0x8b,0xaa,0x94,0xb3,0x47,0x50,0x2f,0x1c,0x49,0xab,0x46,0x38,0x7f,0x3e,0xf3,0xf1,0xb8,0xb3,0x44,0xaa,0x1f,0x76,0xb4,0x67,0xff,0xcf,0x7c,0x4b,0xa9,0xe1,0x62,0x93,0x4d,0x3e,0x96,0xdb,0x56,0xf6,0x26,0x5d,0x95,0x4c,0xfa,0x5f +.byte 0x06,0x2b,0x5c,0x33,0x2d,0xf8,0xfa,0x68,0x8a,0xed,0x28,0x2a,0x6e,0x95,0x86,0x59,0x71,0xef,0x86,0x47,0x60,0xec,0x35,0x79,0xa9,0x98,0x2d,0x6e,0x20,0x26,0x3a,0x21,0xec,0x59,0x15,0x65,0xcd,0xb9,0x91,0x19,0x6e,0x74,0x89,0x3b,0x10,0x00,0xab,0x8a,0x45,0x23,0x20,0x94,0x03,0x02,0x77,0xb7,0xcf,0x9c,0x71,0x18,0x0c,0x5b,0x40,0x62 +.byte 0x3b,0x8f,0xc9,0xf6,0x4c,0x8f,0x60,0x66,0x05,0x87,0x05,0x90,0xd4,0x08,0x76,0xd7,0xa3,0xb6,0x37,0xa8,0x83,0x05,0xb2,0x48,0xe9,0x24,0xc4,0xfb,0x79,0xa1,0xce,0xac,0x29,0x13,0x4e,0x72,0xdf,0xad,0x9e,0x5b,0xcd,0x9c,0x39,0x1d,0x3e,0x57,0x9d,0xf2,0x96,0x13,0xa4,0x79,0x4c,0x76,0x40,0x03,0xb3,0x18,0xcf,0xd7,0x45,0x2a,0x2d,0x07 +.byte 0xe5,0x2e,0xb7,0x74,0xda,0x94,0xea,0x32,0x74,0xb0,0xca,0xf4,0xd1,0x09,0x97,0x3c,0x69,0x17,0xf6,0x5b,0x13,0x7b,0xb8,0xb1,0xd9,0x0e,0x12,0x44,0x29,0xea,0x26,0xd8,0xaa,0x9d,0x26,0x87,0x0c,0x89,0x4e,0xec,0x29,0x48,0x43,0x66,0x21,0x0b,0xab,0xce,0x40,0x57,0x4c,0xa7,0xdd,0x56,0xde,0xac,0x5c,0x62,0xea,0xc4,0x54,0x4a,0xe0,0x8d +.byte 0x54,0xc8,0x65,0x44,0xcc,0x6f,0x2a,0xcd,0x0e,0xb3,0xad,0xa3,0x30,0xd1,0xb7,0x19,0x70,0x51,0xd3,0x9a,0xcf,0xe5,0x42,0x6c,0xa1,0xc1,0x0f,0xe2,0xda,0x86,0xb4,0x51,0x50,0x62,0xdc,0x51,0x3f,0xd2,0xff,0xde,0x7f,0x38,0x5a,0xff,0x2d,0x21,0x1d,0x59,0xb9,0xdd,0xde,0x83,0x13,0xb0,0x25,0xf5,0xbb,0x11,0x47,0x4a,0xaf,0x81,0x15,0xa0 +.byte 0x39,0x5b,0x30,0x17,0x2b,0xbf,0x5a,0x03,0x60,0xb6,0xbb,0x86,0x9f,0x50,0x45,0x15,0x0b,0xba,0x42,0xf4,0x3d,0x05,0x62,0xcd,0x9b,0x8c,0xcf,0x93,0x5c,0x33,0x6c,0xea,0x4b,0xd0,0x1d,0x91,0x3e,0xbf,0xa4,0x9d,0x7c,0x2c,0x87,0x9c,0x42,0x9f,0x03,0x98,0x03,0x1b,0x98,0x66,0x4f,0x8f,0x29,0x12,0xc5,0xb5,0xec,0x81,0xf8,0xb2,0x5e,0x44 +.byte 0x4f,0xb0,0x31,0xe4,0x2a,0x73,0x83,0xac,0x5a,0x3f,0xfa,0xcf,0x8b,0x7c,0xa3,0xf1,0x01,0x14,0xa1,0xca,0x60,0x8d,0x6a,0x6c,0x04,0x31,0xcc,0xba,0x12,0xe0,0x4e,0xaf,0x01,0x8d,0xf5,0x60,0x23,0x79,0x8a,0x80,0xcc,0x32,0x31,0x69,0x83,0xb6,0x83,0xaa,0xd9,0x3b,0x86,0x4a,0xd8,0x10,0x28,0x09,0x82,0x36,0xee,0x6a,0xc0,0x80,0x3f,0xfd +.byte 0xb1,0xd2,0xde,0x34,0xf9,0x4c,0x87,0x5b,0xdd,0xd0,0xb6,0x2d,0x99,0x69,0xd3,0x2c,0xb7,0x0b,0xfc,0x16,0x88,0x7b,0x80,0x21,0xbc,0x30,0x7b,0x56,0xe5,0x7b,0x41,0x43,0x4d,0xaf,0x40,0x5e,0x74,0x14,0x17,0x66,0x32,0xd6,0x81,0x53,0x94,0x35,0xf0,0x0f,0x4f,0x99,0x54,0x9a,0x38,0xc0,0x2a,0xa9,0xd3,0x53,0xdd,0x9a,0xc5,0x29,0x18,0x62 +.byte 0xf6,0x93,0xa3,0x02,0xf0,0x13,0xcb,0xcb,0xcc,0x64,0x0b,0x00,0xf4,0x43,0x03,0x26,0xe6,0x2f,0x39,0xa1,0x83,0xea,0x94,0x2f,0xde,0x61,0xbd,0xe1,0xbe,0x08,0xf8,0xd4,0x01,0x6e,0x61,0x98,0x01,0x39,0x4b,0x93,0x39,0x38,0x34,0x58,0x24,0xc1,0xf5,0x03,0x05,0x15,0x9c,0xf0,0x30,0x20,0x24,0xd4,0x7e,0x73,0xb2,0x60,0x06,0x3b,0xd3,0xb7 +.byte 0x2c,0x47,0x17,0xc4,0x79,0x4e,0x45,0x0b,0x89,0xf0,0xfc,0x42,0xa0,0x0d,0x80,0xd2,0x44,0x36,0x70,0xaa,0x9e,0x72,0x85,0xa8,0xc8,0x1d,0x35,0x28,0xc3,0x5a,0x72,0x4c,0x06,0x6d,0xf4,0xae,0x54,0x86,0x9a,0x32,0x3c,0xa5,0x06,0x63,0xc1,0x37,0xbb,0xaf,0xa6,0xae,0xce,0x94,0xea,0x9c,0x4a,0x9e,0x56,0xb1,0xc3,0x84,0x84,0xef,0x3d,0xe9 +.byte 0x24,0xf4,0xbf,0xc3,0xf6,0x45,0x74,0x4e,0xbb,0x86,0xd3,0x7f,0xab,0x19,0xe3,0x63,0x67,0x81,0xb6,0x18,0xc8,0x78,0x8e,0xf8,0x83,0x5f,0xfb,0x2e,0x49,0x97,0x2b,0x34,0xbb,0x76,0x2e,0x93,0xec,0xe9,0x7f,0x4d,0x7e,0x52,0x0c,0x92,0xbc,0x6d,0x3a,0x34,0x9b,0x5e,0x61,0x6f,0xea,0x45,0xe7,0x5c,0x34,0x6b,0xcb,0xc0,0x31,0x61,0x64,0x9d +.byte 0xad,0x7f,0x98,0xca,0xfe,0x3d,0xad,0xf7,0x21,0xf6,0x4c,0x2a,0x21,0x07,0x80,0x25,0xa2,0xea,0x26,0x85,0xc3,0xb1,0x74,0x04,0x7f,0xd1,0x1c,0x1b,0xa5,0x7e,0x96,0x45,0xfe,0x6f,0xa6,0x34,0xdf,0x94,0x1f,0x7e,0xfb,0xcf,0xfd,0x29,0xeb,0x3a,0xb0,0xfc,0xb6,0xd5,0x80,0x8b,0x37,0x71,0xfb,0x70,0x19,0x30,0xc4,0x6f,0xa0,0x5b,0xae,0x5b +.byte 0x75,0x51,0x98,0x89,0x9e,0xf0,0xf5,0x79,0xaf,0x1c,0x07,0xb6,0x5e,0xcf,0x34,0x70,0x0f,0x0b,0xbc,0x0a,0xa6,0x40,0xc7,0xf8,0xe4,0xef,0xe6,0xb7,0x94,0x6e,0x98,0x75,0x22,0x73,0x5c,0xca,0xcc,0xfb,0x09,0x2f,0x9c,0xfe,0x49,0x0f,0xd3,0x65,0xfe,0xd4,0xf0,0x9b,0xeb,0x8c,0xd7,0x8c,0xff,0x4b,0x18,0x3e,0xf3,0x9d,0x3f,0xf5,0x83,0xd6 +.byte 0x1d,0x3d,0x23,0x79,0x0f,0xae,0x17,0x62,0x33,0x07,0xc3,0xac,0x98,0x07,0x72,0x9b,0xd9,0x26,0x5c,0x1a,0x9d,0xf1,0x35,0x92,0xf9,0x38,0x17,0xf8,0xee,0x26,0xf9,0x64,0xfc,0x5e,0x8b,0x80,0xce,0xdb,0x64,0xf7,0xde,0x20,0x19,0x5c,0x26,0xf6,0x23,0xd6,0x99,0x8e,0x75,0x77,0x3d,0x17,0x0f,0xea,0x31,0x5a,0x65,0x32,0x1b,0x78,0x78,0xe4 +.byte 0xfe,0x76,0xf8,0xa7,0x81,0x34,0xf1,0x2a,0x13,0x22,0xe4,0x8a,0xe1,0x42,0x5a,0x3f,0x44,0x22,0xeb,0x7e,0xcd,0x20,0xcd,0xf7,0x44,0x1a,0x87,0xb9,0x7a,0x0e,0xf8,0xcb,0xb5,0x0a,0x1f,0x6a,0xe6,0x0b,0x70,0x59,0x38,0xa3,0x6b,0x64,0x7b,0x61,0xfe,0xbd,0xa4,0xb7,0x89,0x7a,0x28,0x70,0xfe,0x9d,0x64,0x2c,0xe9,0xc4,0xc9,0x2f,0xc8,0x3e +.byte 0xfa,0x70,0xce,0x21,0x9b,0xa8,0x10,0x6a,0x16,0xdd,0x28,0xce,0x4e,0xd4,0x6c,0x8c,0x47,0x83,0x13,0x8b,0xec,0x1c,0x76,0xdc,0x4d,0x81,0x25,0x08,0xd8,0xf9,0xde,0x66,0x1d,0xe2,0xf3,0xe7,0xdc,0x3e,0x3c,0x6b,0x98,0x25,0x55,0x88,0xe8,0xda,0x7f,0x16,0xe5,0x7d,0xad,0x8a,0x36,0x00,0xf0,0x68,0xc5,0xe4,0xfc,0xe9,0xe3,0x54,0xeb,0x4c +.byte 0xd1,0xff,0x07,0x1a,0x5c,0x5e,0xd4,0xb1,0xff,0x7d,0xfc,0x5b,0x34,0x42,0x95,0x89,0x01,0x24,0x8e,0x30,0xec,0xfe,0x67,0xf8,0xe2,0xaa,0xd5,0x6a,0x9f,0xe3,0xc3,0xa5,0x53,0x7f,0xd3,0xf4,0x98,0xa5,0x47,0x11,0xad,0xac,0xea,0xba,0x20,0x34,0x03,0x65,0x8c,0xec,0xb6,0xa3,0x2b,0xf6,0x93,0xe1,0xc8,0xad,0x34,0x30,0x8f,0x0e,0x3b,0xf6 +.byte 0x63,0xc6,0x58,0xc3,0xe8,0xa3,0x85,0xf8,0x24,0x8e,0x21,0xb9,0x36,0x7c,0xe0,0x11,0x64,0x31,0x6a,0x6a,0xa2,0xad,0xd3,0x94,0xbb,0x13,0x5b,0xb4,0xe9,0xee,0x09,0xdc,0xfe,0xb2,0xad,0xa8,0x43,0x02,0xba,0x85,0x1f,0x56,0xcb,0xb5,0x95,0x32,0xcc,0x7e,0xe0,0x00,0xde,0xfa,0x3f,0x91,0x71,0xde,0x21,0x19,0xff,0xc9,0x97,0x43,0x95,0xd8 +.byte 0x0d,0xc2,0x8a,0xde,0xcc,0x34,0x48,0xf4,0x35,0x41,0xb8,0x56,0x52,0xce,0x06,0xb3,0xcf,0xd4,0xae,0x7a,0xcb,0xe9,0xed,0x37,0xd6,0x76,0xa0,0x77,0x04,0xfb,0xb7,0x41,0x25,0x38,0xe1,0xd1,0xb5,0xde,0x21,0xe0,0x64,0xd8,0x83,0x13,0x7b,0x4b,0xb8,0xc9,0x12,0x02,0x51,0x56,0x52,0xe9,0x1c,0x49,0x48,0x83,0xd0,0x99,0x73,0x60,0x4a,0x4c +.byte 0x7d,0x8d,0x43,0xf9,0x06,0xa4,0xbb,0x0e,0xb6,0xdd,0x5f,0xc7,0x5e,0x35,0xcb,0xa0,0xc1,0x66,0x4a,0xe3,0x4a,0xa9,0xec,0xa4,0x5a,0xd7,0xd6,0xea,0xa5,0x20,0xa6,0xc3,0x1b,0xc0,0xa8,0xd1,0xf1,0x08,0x05,0xab,0x40,0x14,0x35,0xf2,0xdd,0x0f,0xc5,0xda,0xb3,0xa6,0xb1,0x07,0x36,0x17,0x5d,0xe9,0x96,0x23,0x96,0x46,0xd4,0xa7,0x71,0x64 +.byte 0x13,0x72,0x4e,0x83,0xe0,0x65,0x40,0x41,0xaf,0xb6,0x5b,0x00,0xa2,0xab,0x09,0x7f,0xa5,0xd5,0xc2,0xd9,0xc0,0x68,0x2a,0x44,0xdc,0x43,0x37,0x81,0xb8,0x88,0x4c,0x85,0x1b,0xb1,0x83,0xb2,0x56,0xa3,0x91,0x0f,0xa6,0x70,0x3f,0xbd,0xe9,0xda,0x40,0x9b,0xf5,0x9e,0x53,0xed,0x5f,0x84,0x70,0xd2,0x4c,0x1c,0xb6,0x87,0xd6,0xbb,0x3b,0xec +.byte 0xe5,0x35,0x1b,0x2c,0x9b,0xf1,0xe5,0xf8,0x0e,0x07,0x98,0xcc,0x58,0x38,0x57,0x74,0xdb,0x0e,0x08,0xd9,0x56,0xe8,0x08,0x63,0x3d,0x94,0x4a,0xdc,0x59,0xfc,0x3d,0xc1,0xa4,0x36,0xc3,0xe8,0xbe,0x4b,0xd7,0x47,0x69,0x33,0xb8,0x72,0x30,0x59,0x28,0x4e,0xf1,0xc1,0x25,0xa3,0xa4,0xe3,0x12,0xcf,0x31,0xf6,0xf8,0xae,0x31,0x06,0x76,0x92 +.byte 0x64,0x87,0x8e,0xb0,0x9f,0x1d,0xf4,0x56,0x73,0xc5,0x5d,0xbb,0x80,0x0d,0x19,0x3f,0x56,0x8c,0xe4,0xd6,0x8a,0x9a,0x62,0x26,0x4e,0x8a,0x21,0x7d,0x72,0x34,0x87,0xb6,0x7e,0x49,0xdc,0xfd,0x27,0x95,0xba,0x25,0xdd,0xf4,0x58,0x2b,0x11,0x3f,0xd1,0xd7,0x13,0x1d,0xb0,0xec,0xe2,0x55,0x5e,0x72,0xea,0x36,0xc9,0xd8,0x61,0xc0,0xee,0xc4 +.byte 0x9f,0x35,0x7e,0x73,0xd3,0xf6,0xd7,0x6a,0xce,0xd6,0xd2,0x80,0xe6,0x10,0x4b,0x65,0x18,0x6f,0xab,0xd3,0x41,0xbb,0x39,0x36,0x95,0x84,0x3c,0x99,0x9a,0xfd,0xf0,0xa3,0x46,0xdf,0x48,0x7c,0xd5,0x57,0x9d,0x10,0x59,0xca,0x70,0xc4,0xb5,0xbe,0x47,0x9e,0xca,0x2b,0x49,0x54,0xbb,0x34,0x8e,0x39,0xf4,0xf8,0x8c,0xa5,0xa1,0xab,0xf6,0x51 +.byte 0xd8,0x22,0x9a,0xd5,0xc2,0x12,0xf8,0x26,0xc6,0x19,0x2a,0xa6,0x6e,0xab,0xd3,0xac,0xd1,0x21,0x97,0x67,0x3e,0x39,0x90,0x5c,0x37,0x65,0x7b,0x06,0x54,0x1a,0xb8,0x2a,0x56,0x02,0xa3,0x92,0xee,0xf3,0x38,0x53,0x25,0x4d,0x5d,0x0a,0x37,0x9e,0xbb,0xf4,0xb2,0x13,0x77,0xbb,0x93,0xa9,0x85,0xf2,0x15,0xfd,0x71,0x17,0x00,0x89,0xe7,0x7b +.byte 0xa9,0xdc,0x10,0xd9,0xc7,0x44,0xa5,0x7b,0x3f,0x2f,0x1e,0x6d,0xa7,0xfe,0x0c,0x0e,0x83,0x3e,0x38,0x27,0xa7,0x4e,0x85,0x3c,0x84,0xfe,0x95,0x48,0x85,0x09,0x75,0x62,0x1d,0xa4,0x64,0x54,0xed,0x89,0xd5,0x28,0x62,0x52,0x18,0xef,0xf0,0x57,0x05,0x30,0xf0,0xce,0x87,0x05,0x0d,0x81,0xe8,0x2a,0x3c,0x8c,0x22,0xe1,0x4b,0x32,0x42,0x9d +.byte 0x02,0xc5,0xe4,0x6a,0xa4,0x4d,0x9b,0xc4,0x82,0x47,0xdc,0x61,0xbd,0x82,0x01,0xcd,0x5e,0x64,0x9f,0x4c,0xe3,0x31,0xe9,0x48,0x53,0x85,0x07,0xc7,0x47,0x49,0x35,0xd8,0x6a,0xab,0x4f,0x73,0x3f,0xd3,0xde,0x87,0x29,0xac,0xbc,0x35,0x0a,0xb4,0x74,0xc2,0xa7,0x0b,0xb1,0x93,0x92,0x29,0x3b,0x3e,0xa8,0xde,0x12,0x49,0x75,0xda,0x16,0x27 +.byte 0x52,0x2f,0x93,0x23,0xd6,0xf7,0x10,0xfe,0x1e,0x93,0x97,0x06,0x9d,0xef,0x4f,0xe4,0x3d,0x5d,0xde,0x30,0x70,0x3d,0x78,0x3a,0x30,0x00,0x9b,0x77,0x12,0x90,0x62,0xda,0x32,0x9b,0x6a,0x47,0xd7,0x0f,0xee,0x75,0x18,0xdd,0x4d,0x8a,0xe2,0x35,0x5b,0x60,0xb8,0xf9,0xa4,0x6c,0x93,0x3e,0x47,0x23,0xed,0x7a,0xe2,0x58,0x42,0xd6,0x3f,0x90 +.byte 0xc0,0x12,0x38,0x8b,0x70,0xe0,0xf8,0x1a,0xb5,0x8d,0xe1,0x39,0xdf,0x93,0x25,0x72,0x2e,0xa9,0x3f,0x58,0x12,0x40,0xc4,0x92,0x46,0x08,0xf0,0x64,0xdd,0x34,0x42,0xfe,0x74,0x35,0x0c,0xda,0xef,0x06,0x0b,0x33,0x59,0xd9,0xee,0x4c,0xf9,0x02,0x3a,0x93,0x40,0xa3,0x99,0x0e,0x64,0x11,0x2f,0x52,0x9d,0x28,0x4d,0xe8,0x45,0xd0,0x22,0xd7 +.byte 0x8f,0xd6,0x28,0x8c,0x0e,0x18,0x87,0x24,0xf9,0x88,0xd2,0xc0,0xe8,0xd4,0x9d,0xa2,0x5a,0x79,0x83,0x37,0x18,0x84,0x12,0xca,0xc7,0x10,0xd5,0x5a,0xa8,0xe5,0xa8,0xe7,0x79,0xb6,0x2c,0xb3,0x90,0x6c,0xc5,0xa4,0x99,0x1b,0x85,0x29,0x78,0x0b,0x09,0x77,0x05,0xf4,0x23,0x79,0x5c,0x91,0xf3,0xe0,0xe4,0x6f,0x82,0x33,0x4e,0xa2,0x2e,0xa2 +.byte 0x65,0x79,0xad,0x98,0x36,0x34,0x72,0x97,0xd7,0x39,0x89,0x5e,0x82,0x9f,0x4c,0xe2,0xea,0x51,0x85,0x62,0x0c,0x39,0xf6,0xdc,0xc6,0x80,0x48,0xcf,0x98,0x93,0x64,0x7d,0xf9,0x63,0xf4,0xf5,0x18,0x2a,0xb6,0x04,0xb7,0x44,0xc4,0x60,0xc0,0xcf,0x3d,0x88,0xa8,0xb6,0x81,0xa3,0x99,0x2a,0xf0,0x1a,0x8d,0x76,0x20,0x1d,0xcc,0x10,0x50,0x58 +.byte 0x09,0xf9,0xda,0x65,0x60,0xc3,0xb1,0xc1,0xc0,0x4d,0x62,0x52,0x22,0x45,0x32,0xbc,0x11,0x93,0x15,0xb6,0x25,0x8f,0x65,0xa0,0x4c,0x88,0xc9,0x83,0xe1,0x5c,0xbb,0xfb,0x1a,0xab,0xdb,0x35,0x40,0x66,0xc0,0x2f,0xdc,0xf5,0x92,0x08,0x4c,0xc7,0xb8,0x49,0x05,0xe0,0xe1,0x61,0x2b,0xde,0xc7,0x6a,0x04,0x05,0x4d,0x9f,0xe9,0x59,0x22,0x56 +.byte 0x63,0x77,0x9d,0xe3,0x1e,0x36,0xdf,0x87,0x4a,0xeb,0xba,0x42,0x3d,0x1b,0xa5,0xd0,0xc5,0x44,0x07,0xbe,0x37,0x37,0x70,0x10,0x2d,0x02,0x9b,0xf6,0x52,0xf3,0x54,0x6d,0x50,0xdb,0xdb,0x57,0x01,0x0b,0x9b,0xd5,0x99,0x99,0x69,0x9b,0x10,0x76,0x48,0xea,0x28,0x27,0x06,0x30,0x63,0x3b,0xdf,0x06,0x30,0x37,0x28,0x75,0xcf,0x9c,0xe7,0x52 +.byte 0x43,0xe2,0xd5,0x7b,0xfa,0x88,0x98,0x9c,0x3e,0x27,0x30,0x21,0xcc,0x11,0x71,0x14,0x24,0x04,0x1a,0x8c,0xe9,0xfe,0x2f,0x9d,0xec,0xb1,0x10,0x33,0x05,0x31,0x01,0x1b,0xde,0x6b,0x30,0x20,0x6d,0xf4,0x7c,0xbf,0x41,0x04,0x5f,0xb9,0x9c,0x24,0x63,0x74,0x98,0x3e,0x60,0xc7,0xf1,0xb1,0xc6,0x94,0xf3,0x6f,0x95,0x24,0xdf,0x97,0xd5,0xc7 +.byte 0x50,0x19,0xaf,0xa5,0xae,0x51,0xde,0x6d,0x44,0x0c,0x90,0x72,0x11,0x82,0x04,0xf9,0xda,0x17,0xd8,0xf3,0x03,0xf2,0x03,0x3f,0x65,0x7f,0xd7,0x66,0x84,0x9a,0x02,0x90,0x2b,0x65,0x00,0xd9,0x9c,0xfb,0xaa,0xe2,0xde,0x5f,0x1e,0x19,0x1e,0x6d,0x20,0x1e,0x01,0xf1,0xca,0x7b,0x90,0x06,0x96,0x1d,0x7a,0x34,0x0c,0x66,0x57,0xd7,0x61,0x1f +.byte 0x74,0x03,0xcb,0xae,0xea,0xaf,0x65,0x8e,0x32,0xbe,0xb8,0xe6,0xd8,0x6d,0xf7,0x51,0x6d,0xec,0x7e,0xc6,0x9d,0x20,0x01,0xbf,0xd7,0xbc,0xcb,0x34,0x7c,0xe5,0x1f,0x92,0x72,0x2f,0x6f,0xa3,0x1f,0xe8,0x4d,0x7e,0xa5,0x85,0x3b,0xed,0xc7,0x25,0x53,0xe3,0x77,0x90,0x1f,0xda,0xb7,0x48,0x7d,0xbe,0x20,0x48,0x9f,0xb4,0x05,0x5d,0x41,0xc5 +.byte 0x48,0xd0,0xc9,0x83,0xbe,0xf8,0xd8,0x6b,0x0d,0x26,0x66,0x2e,0xef,0x6b,0x13,0x58,0x6b,0x5f,0x0e,0x8b,0x4e,0x57,0xb2,0x6b,0x3d,0x4d,0xcd,0xcb,0x9a,0x9b,0xda,0x4d,0x7f,0xea,0x17,0x06,0x7f,0xcd,0xaf,0x18,0xda,0x3d,0xf0,0x30,0x2e,0xbb,0xc2,0x1d,0xcf,0xde,0xf7,0xee,0xda,0xd6,0x3d,0x75,0xcf,0x19,0xcf,0xfc,0xdf,0x7a,0xb6,0x1f +.byte 0x89,0xf5,0x0c,0xe9,0xd5,0xf1,0xd0,0x40,0xbd,0xae,0xb5,0x16,0xf6,0x05,0x1e,0xba,0xcd,0x18,0x80,0x4a,0xb3,0x87,0x93,0x6b,0x19,0xfc,0x47,0xa8,0x45,0x4b,0x75,0xe8,0x06,0xc0,0xbd,0x86,0xf7,0xcf,0x2c,0x39,0xc6,0x0b,0x3f,0x32,0xcd,0x1c,0x02,0xec,0x4b,0xd5,0x90,0x84,0xaf,0xc9,0x5c,0x9e,0x64,0x82,0x13,0x81,0x05,0x03,0xe4,0xed +.byte 0x48,0x23,0xc3,0x53,0x2c,0x5a,0x22,0x0a,0x27,0x7e,0x55,0x79,0xdc,0x46,0xf5,0x4b,0x04,0xcc,0x43,0x87,0x6c,0xb5,0xa4,0x2d,0x78,0x70,0x02,0x43,0x0e,0x76,0x62,0x99,0x86,0x40,0x2a,0xe4,0x62,0xe6,0xee,0x4e,0x03,0x64,0x83,0x9c,0x38,0x6d,0x62,0xa6,0x85,0xb8,0xce,0xd7,0xf8,0xcb,0x78,0x00,0x7a,0x48,0x72,0x75,0x4e,0x9c,0x6f,0x0c +.byte 0x61,0xc7,0x93,0x4e,0x6d,0x65,0xa3,0x1b,0x17,0x84,0xc6,0xd2,0x29,0xc3,0x4d,0xe3,0x14,0x21,0x5f,0x9e,0xa9,0x28,0x11,0xf3,0xb2,0xe8,0xe7,0x60,0x9e,0x24,0xab,0x88,0x9c,0x9c,0x5e,0x17,0xe4,0xe1,0xa7,0x74,0xb4,0x82,0xd5,0xaa,0x92,0x08,0xa7,0xa2,0x04,0x6f,0x77,0x14,0x54,0x44,0x5d,0x13,0x10,0xa2,0x40,0x1d,0xf0,0x44,0x16,0x17 +.byte 0xda,0x8c,0x80,0x83,0x2b,0x19,0xb8,0xab,0xf2,0xb8,0xb1,0x92,0xb5,0xc5,0x05,0x3e,0xd2,0x1a,0xfc,0xfd,0x21,0xa6,0xb2,0xbd,0x89,0xee,0x9c,0x3c,0x90,0xd9,0xf1,0xd2,0xe8,0xc3,0x21,0xb9,0x0e,0x0c,0x98,0xbc,0x5e,0xa1,0x0d,0x89,0xfe,0x0f,0x3c,0x45,0xea,0xe1,0x6e,0x06,0x59,0xff,0x79,0xf4,0x7e,0xf4,0x82,0xc0,0x6b,0xd9,0x53,0x30 +.byte 0x98,0xed,0x8d,0x6f,0x3d,0x0e,0xfb,0x42,0x66,0xab,0x41,0xa8,0x4a,0xef,0x73,0xa4,0x54,0x99,0x4f,0xb6,0x65,0x44,0xf9,0xd9,0x3c,0x6b,0x59,0x36,0xb0,0xe3,0x7c,0x4a,0x85,0x80,0x6c,0x77,0x6f,0x34,0x4e,0x9e,0x54,0xfd,0x0c,0x25,0x72,0xc3,0x5a,0xb6,0x3b,0xad,0x2b,0xd5,0x29,0x55,0x31,0xab,0x62,0xe4,0x15,0xed,0xef,0x16,0xef,0x43 +.byte 0xd5,0xdd,0x3d,0x64,0x8c,0x13,0xbc,0xcd,0x4d,0xfb,0x4f,0x86,0x3b,0x73,0x1e,0xc4,0xe8,0x54,0xb4,0xcc,0x49,0xba,0x4f,0x81,0xcd,0xe8,0x30,0x92,0x4b,0x57,0xd1,0x7c,0x0c,0x65,0x7d,0xe1,0x59,0xc6,0x8c,0x7d,0xad,0xd5,0xcf,0x6c,0xc4,0x9d,0xc5,0x3f,0x23,0x1f,0xb0,0x6d,0x1c,0x07,0xbf,0x38,0xc9,0x16,0xdc,0x5b,0x51,0xa1,0xdb,0x8f +.byte 0xf8,0x25,0xc6,0x4d,0xc0,0x4d,0xa1,0x02,0xd9,0xd3,0xb5,0x63,0xda,0xe1,0x91,0x60,0x71,0x39,0x46,0x1a,0x13,0xe0,0xf2,0xca,0xcc,0xd3,0xbb,0x6b,0xd0,0x64,0xaa,0x0e,0xc0,0x89,0xa3,0xc6,0x14,0x56,0xe4,0x44,0x97,0xa9,0xcc,0x17,0x68,0xe6,0xfc,0xe5,0xfd,0xf0,0xa6,0x69,0xcd,0xac,0x20,0xc7,0xeb,0x53,0x1b,0x4f,0xdd,0xd3,0xb0,0xed +.byte 0x30,0x4e,0x36,0x73,0x63,0xef,0x51,0x3e,0x9a,0x3e,0x41,0x2b,0x9c,0xda,0x67,0x96,0x46,0x33,0xe3,0x3f,0x87,0x01,0xd8,0xc5,0x26,0x80,0xe4,0x7e,0xf4,0x78,0x8c,0x2b,0x81,0x2a,0x01,0x7c,0xe3,0xfc,0x8d,0x6b,0xdc,0x84,0xb9,0xff,0x43,0x37,0x57,0xce,0x3f,0x5e,0x63,0xd3,0xbe,0xb6,0x4a,0x31,0xbf,0xb8,0x74,0x64,0x9c,0xf3,0xc5,0x8a +.byte 0xae,0xe8,0x5f,0x68,0xcf,0xce,0xff,0x3f,0xc5,0xb5,0xfd,0x13,0x08,0x11,0x9d,0x1a,0x0f,0x06,0x08,0x4d,0x7c,0xf9,0xd4,0x20,0xdf,0x82,0xf9,0x86,0xfc,0xf3,0x67,0xa0,0x14,0x99,0xe5,0x47,0xf0,0x02,0x7b,0x16,0xca,0xcf,0xb9,0x0f,0x68,0x08,0x5d,0x1d,0x65,0xee,0x23,0x56,0xeb,0x11,0x5b,0xca,0xf1,0xa7,0xad,0x50,0xb2,0xd1,0x37,0x65 +.byte 0xe9,0x7e,0xf6,0xe9,0x64,0x42,0x49,0x80,0x40,0x17,0xe3,0x43,0x00,0xda,0xe1,0x7a,0x1c,0xb3,0xde,0xd9,0xf7,0x33,0xeb,0xb3,0xb8,0xf5,0x40,0x1b,0xcd,0x71,0x97,0x30,0xf9,0x9c,0x4d,0xac,0x7e,0x8e,0xd9,0x36,0x92,0x39,0xb5,0x56,0x0f,0x4f,0xbf,0x58,0xb8,0xba,0xc3,0xbd,0x79,0xb0,0xd7,0x6c,0x45,0x49,0xe2,0xde,0x94,0x04,0x9d,0x3e +.byte 0x91,0x0a,0xb2,0x9b,0x90,0x57,0x2e,0x69,0xa4,0x4f,0x61,0xbf,0xdb,0xfb,0xe3,0xe9,0x81,0x26,0xe0,0x48,0x90,0x8c,0x32,0x95,0x8d,0x38,0xec,0x8e,0xa7,0x5e,0xc3,0x36,0xc6,0xd1,0xbc,0x9a,0xb3,0xba,0xdb,0x2c,0xe4,0xa0,0x50,0x74,0xef,0x98,0x48,0x14,0xc9,0x38,0x4d,0xa9,0x48,0x13,0xd4,0x08,0x60,0xfd,0xcf,0x5e,0xf2,0xcd,0xc7,0xeb +.byte 0xaf,0x88,0x32,0x30,0x6f,0x19,0x01,0xec,0x87,0xae,0x6d,0x63,0xa3,0xa7,0x7b,0xcd,0x53,0xa7,0xf2,0xf2,0x9f,0x43,0xcb,0x0a,0x3f,0x8c,0xd2,0x55,0x8d,0xa7,0x95,0xcf,0x5b,0xae,0x64,0x23,0xda,0xb4,0xbd,0x32,0x34,0x95,0x8a,0x03,0xe7,0x6e,0xef,0x3f,0xb4,0xcf,0xc6,0x8a,0x2f,0xc6,0x59,0x99,0xdf,0xad,0x3c,0x15,0xed,0x83,0x0b,0x59 +.byte 0x8b,0xcd,0x0d,0xa6,0xcf,0x3a,0xc3,0xdb,0xc3,0x01,0xa9,0x32,0x38,0x45,0x5c,0xc8,0x56,0x81,0xef,0x21,0x7f,0x52,0xc4,0xb5,0x48,0x97,0x6a,0x60,0x75,0x3a,0x1a,0xd3,0xb0,0x60,0x9a,0x83,0x61,0xad,0x3b,0x4b,0x65,0xaa,0x9e,0x77,0x47,0x6f,0x3b,0x48,0xb0,0xc6,0x36,0x9a,0x59,0x5e,0x26,0xc4,0xb9,0xed,0x04,0xf3,0xc7,0x09,0x33,0xda +.byte 0x81,0x63,0xa6,0x5d,0xe1,0x54,0x6b,0x04,0x17,0x2b,0xb9,0x2f,0xbd,0x55,0xdb,0xa1,0x69,0x00,0xcd,0xba,0xfa,0x36,0xaa,0x47,0x5a,0x7c,0xf4,0x1f,0x53,0x94,0x95,0x2f,0xf8,0x2a,0x4b,0xa8,0xcc,0x73,0xab,0xfd,0x25,0xb2,0x4e,0xd6,0x62,0x90,0x8c,0x8f,0x02,0xe4,0xdc,0x22,0x79,0x04,0x34,0x9b,0x54,0x5c,0x54,0xca,0x9b,0x8a,0xf8,0x05 +.byte 0xd1,0xb0,0x9e,0x8f,0xa3,0x0b,0x53,0xa8,0x6f,0x1b,0x2e,0xf2,0x71,0x78,0x28,0xce,0xa9,0xdb,0x4c,0x5b,0x83,0xfe,0xaa,0xff,0x99,0x2f,0x03,0x14,0xb2,0xe0,0x5f,0xaa,0x65,0x15,0x1f,0xd2,0x31,0x95,0x70,0x3c,0x8b,0x55,0x8e,0x87,0xed,0xbb,0x0c,0x91,0x87,0xaa,0xbe,0x49,0xdb,0x18,0x7b,0x1d,0x26,0xa7,0xdf,0x00,0xff,0x73,0x70,0x2e +.byte 0x10,0xaf,0x46,0xea,0x7f,0xca,0xfa,0x09,0x13,0x02,0xac,0x3f,0xa0,0x02,0xa6,0x67,0xb7,0xec,0x18,0x73,0x91,0x25,0xa0,0x28,0xe3,0xd8,0xfa,0x11,0x6d,0x34,0x79,0x1d,0xe4,0x8f,0x7c,0x73,0x66,0x77,0x3e,0x43,0x23,0xb0,0xee,0x84,0xb5,0x75,0xc9,0x23,0x87,0x6a,0x4f,0x59,0x3d,0xb5,0xf1,0xd6,0x06,0xf8,0xa6,0x5d,0x0c,0x24,0xed,0x94 +.byte 0xd7,0xa8,0x31,0x37,0x10,0x60,0xb6,0x03,0x33,0x27,0x38,0xdd,0xd3,0x74,0x02,0xa3,0xa6,0x01,0x94,0xa9,0x56,0x11,0x23,0x0e,0xdb,0xfd,0x25,0x92,0xa8,0xfb,0x79,0xc8,0x8e,0x0e,0x10,0x1f,0xca,0x95,0xf6,0xad,0x28,0xe7,0xaa,0x2b,0xf1,0x40,0xf6,0xef,0x7b,0x40,0x28,0x57,0xbb,0x4c,0xac,0x0b,0x8b,0xb3,0xe3,0xec,0x53,0xf2,0x15,0x61 +.byte 0x2e,0x91,0xdf,0x91,0xfb,0x55,0xb6,0x7f,0x6c,0xfc,0xb7,0x4b,0x91,0xdc,0xf7,0xe5,0x91,0xd8,0x70,0x92,0x94,0xea,0x3f,0x62,0x98,0x14,0xc3,0x43,0x34,0x02,0x87,0xc7,0xca,0x60,0x4a,0xfb,0x50,0xe4,0xa9,0x92,0x10,0x04,0x7c,0x55,0xd3,0x9a,0x89,0xba,0x8e,0x6f,0x02,0xd6,0xc7,0x6f,0x91,0xb5,0x87,0xb9,0x0e,0xbe,0xe4,0x9f,0x01,0x0b +.byte 0x20,0x60,0xc8,0x16,0xe6,0x23,0x1d,0x5f,0x4d,0x82,0xf4,0x42,0x25,0xe6,0x05,0xe3,0x5b,0xbb,0xd1,0xb0,0xad,0x0b,0x05,0x71,0x3a,0x7b,0xee,0x0e,0xe1,0xe4,0x08,0x9f,0xda,0xdf,0x59,0x57,0x4f,0x05,0x5a,0x51,0x9a,0x60,0xfd,0x85,0x21,0xd1,0x0a,0x3b,0x0a,0x15,0x61,0x28,0x98,0x0a,0x8f,0x1e,0x33,0x15,0xb3,0x5f,0xf3,0xbb,0x89,0x22 +.byte 0x0c,0xaf,0x91,0xce,0x44,0xb1,0x54,0xd0,0x80,0x86,0x43,0xa1,0xb9,0x07,0xde,0xab,0x1f,0x9b,0xae,0xef,0x07,0xf2,0x40,0x33,0x31,0x4d,0xf9,0x45,0x97,0xf6,0xcc,0xe5,0x3c,0x49,0xcd,0x83,0x6e,0x38,0x81,0xab,0x40,0x18,0xda,0xf6,0xfe,0xe7,0x96,0xd1,0x17,0x98,0xae,0xec,0xe9,0x93,0x37,0xbc,0x0b,0xa8,0x12,0xe7,0x65,0xca,0x27,0x37 +.byte 0x6a,0x74,0x81,0xf1,0xe0,0x6c,0x0d,0xba,0x86,0x48,0x94,0xd0,0x72,0xd5,0x4d,0x71,0xcf,0xa8,0x5e,0xd1,0x97,0xd1,0xed,0xf0,0xd3,0xe4,0xe3,0x41,0xc9,0x8f,0xfc,0x89,0xe8,0xbf,0x96,0x8b,0x86,0xb0,0x97,0x79,0x95,0xdf,0x69,0x56,0x6d,0x61,0x0a,0x37,0xcb,0x36,0xe1,0x95,0x88,0xf5,0xf0,0xe2,0x5c,0xb2,0x44,0x73,0xda,0x83,0xa7,0xdc +.byte 0x8b,0x35,0x3e,0xc1,0xd5,0x88,0x17,0x3b,0xeb,0xcf,0x36,0x9c,0xef,0x40,0xb2,0x72,0xde,0x4f,0x16,0x6c,0x8c,0x9d,0x15,0xce,0x7d,0x0d,0xc3,0x2f,0xea,0xab,0x50,0xdf,0x02,0xe0,0x24,0xcc,0xf4,0xa7,0x25,0xba,0x85,0x0d,0x62,0x9a,0x39,0xc7,0x5a,0xd1,0x9a,0xd1,0xa7,0x45,0x5f,0xc2,0x44,0xf5,0xa9,0x8d,0xd8,0xbc,0xd3,0xc8,0x75,0x0d +.byte 0x06,0xc6,0x4b,0x24,0xc6,0xe5,0x72,0xf7,0xd5,0x87,0xca,0x3c,0xc0,0x1c,0x18,0xa9,0x40,0xc6,0x7b,0xe5,0x4c,0xe6,0xb7,0x01,0x57,0xc1,0xcf,0x63,0x83,0x58,0x63,0x47,0xcf,0xa4,0xd3,0xf6,0x1d,0x2c,0xbf,0x17,0xe6,0x0a,0x7b,0x2d,0xa9,0x34,0x23,0xfc,0x1f,0x06,0x31,0x47,0x7b,0x31,0x34,0x8c,0x3c,0x15,0x9b,0xac,0xfd,0x38,0xe6,0xa3 +.byte 0x9e,0xa7,0xdf,0xa6,0x37,0x61,0xfd,0x85,0xb8,0x2e,0x67,0x73,0x7f,0x60,0x12,0x8b,0x62,0xb0,0x38,0xd0,0xaa,0xc4,0xad,0x3b,0xa9,0x04,0x66,0xdd,0xbb,0x9c,0xb1,0x95,0xe1,0x9c,0x0a,0x72,0x80,0x12,0xaa,0xa8,0x0c,0x3f,0x90,0x20,0x33,0xb4,0x76,0xdd,0x26,0xfe,0x1e,0x8f,0x6a,0x2d,0xea,0x4a,0xdc,0x28,0x47,0x66,0x36,0x5b,0x50,0x60 +.byte 0x7e,0x3e,0x93,0xf3,0xe9,0x37,0x31,0x3b,0x43,0x46,0x85,0xb3,0xa9,0xb2,0x14,0x95,0x96,0x49,0xf9,0x2a,0xe7,0x9e,0x3a,0x3e,0xd8,0x12,0xf7,0xbc,0x43,0x8c,0x35,0x31,0x44,0x08,0x7f,0x25,0x39,0x86,0x98,0x6a,0xe8,0xe3,0x2e,0x73,0x2d,0x3b,0xac,0x2d,0x75,0x4c,0xc8,0xca,0x21,0x2d,0x96,0x9b,0x4f,0x56,0xff,0x2d,0xc2,0xe2,0x98,0x3d +.byte 0xe2,0x3f,0xee,0x10,0xb7,0xc3,0x3d,0xa8,0x50,0x88,0x7f,0xd5,0x4e,0xbd,0xc7,0x9d,0xdc,0x01,0x49,0x27,0xf2,0xae,0xea,0x93,0x72,0xdf,0x00,0xcd,0xe6,0xa1,0xdd,0xd1,0x18,0xeb,0xa7,0xe1,0x4a,0x7b,0x38,0x72,0x73,0x29,0x46,0xa3,0xb3,0x25,0x23,0x6d,0x26,0xab,0x86,0xdc,0x67,0x52,0xe5,0x4a,0x5e,0x8f,0x16,0x67,0x8a,0x28,0x13,0xba +.byte 0x44,0x42,0xb5,0x21,0x9f,0x30,0x66,0x7f,0xc9,0x87,0x40,0xcb,0x75,0x58,0x2e,0xcd,0x09,0xb9,0x8a,0x84,0xa3,0xbd,0x63,0x53,0x75,0x2f,0x77,0x8b,0x7e,0x19,0x31,0x33,0x3b,0x9a,0xfb,0x86,0x39,0xa6,0xd9,0xeb,0x9b,0x43,0xc6,0xd9,0xc2,0x10,0xab,0x42,0xe5,0xc6,0x4a,0xe6,0x3e,0xde,0x9d,0xac,0x8e,0x95,0xf0,0xdb,0x48,0x95,0xc2,0x87 +.byte 0x6b,0x7f,0xde,0x09,0xdb,0xed,0x49,0x19,0x73,0x2d,0xa4,0x5c,0xdf,0xfa,0x2e,0x15,0xd0,0xb6,0x46,0x32,0xc9,0x7f,0x7e,0x01,0xd3,0x25,0x45,0x0e,0x5b,0x0d,0xf0,0x67,0xe3,0xd9,0xdf,0x4f,0x3b,0x6f,0xb3,0x15,0xc5,0x6b,0x91,0x75,0xa2,0xaf,0x42,0x3a,0x14,0x50,0xd9,0x4f,0x19,0x65,0x12,0x83,0x5d,0x8f,0x8a,0x01,0x0b,0x89,0xcc,0x7f +.byte 0x1a,0xde,0x5b,0x44,0x34,0x98,0x0f,0x8e,0x5a,0x5e,0x03,0x41,0x3e,0x66,0x9b,0x16,0xf5,0x91,0x7c,0xb0,0xc1,0xbf,0xa2,0x10,0x0b,0x60,0x3a,0x63,0x0c,0xcf,0xd8,0x49,0xdb,0x42,0x88,0x1f,0x36,0x8e,0x15,0xdb,0x5d,0x3f,0xe7,0xf1,0x9a,0x73,0x2b,0x74,0x0c,0xd5,0x09,0xab,0x01,0x2e,0x52,0x6f,0x03,0xf6,0xc9,0x0b,0xeb,0xa5,0xce,0x2e +.byte 0x1c,0x02,0x35,0xca,0xce,0xfe,0x4b,0xad,0x67,0x21,0xf8,0x44,0xea,0x70,0xf2,0x3d,0xfc,0x43,0x77,0x05,0x26,0xbe,0xaf,0x99,0xab,0x41,0xd4,0xcc,0x53,0x33,0x33,0xcd,0xb4,0x2d,0x76,0xfb,0xae,0x0c,0xac,0xc1,0xd0,0x42,0xfb,0x45,0x4a,0x6e,0x55,0xd2,0x93,0xef,0xb9,0x06,0xbc,0x38,0xce,0x94,0xc2,0x01,0xdf,0x27,0xc8,0x47,0xff,0x74 +.byte 0xfb,0x84,0xc5,0xa2,0x78,0x1f,0x4f,0x73,0x12,0xec,0x2d,0x82,0x5b,0xeb,0x3c,0xb6,0x1c,0x5a,0x29,0x9c,0xba,0x9e,0xa4,0x85,0x94,0x84,0x68,0x01,0xd7,0xb1,0x27,0x84,0x4a,0x7d,0x62,0x9c,0x32,0x12,0x89,0xd8,0x66,0xb5,0xe9,0x07,0xf4,0x5f,0x6b,0x0e,0x90,0x87,0xe5,0xc1,0x8b,0xaf,0x8f,0xf7,0xca,0x54,0xe0,0xc6,0x5f,0xa5,0xec,0xd1 +.byte 0xdc,0xdc,0x17,0x9e,0xca,0x4b,0x72,0x72,0x03,0x96,0x62,0xaa,0xc1,0xfe,0x23,0x7e,0xd2,0x06,0x61,0xb6,0xc9,0x0d,0x7e,0xbf,0x72,0x1c,0x66,0x46,0x0b,0x31,0x96,0x81,0x11,0x3d,0xac,0x5e,0xd0,0x35,0xaf,0xac,0x4c,0x74,0xce,0xf9,0x9c,0x64,0x3d,0xe5,0x9d,0xfe,0xc7,0x05,0x09,0xe1,0x70,0xc5,0x37,0xd5,0x4e,0xd8,0x7d,0xdb,0xfa,0x1c +.byte 0x28,0xfc,0x10,0x2a,0xe8,0x62,0x18,0x09,0x97,0xe0,0x98,0x2e,0x9f,0x1d,0x18,0xff,0x22,0xe9,0x5d,0x37,0xd2,0x74,0xf1,0x81,0x08,0x8a,0x55,0xc0,0x40,0x0f,0x70,0xbe,0x82,0x23,0x78,0x35,0xc8,0xf8,0x59,0x6e,0x0d,0x2e,0xd5,0xe7,0xf5,0x2e,0xbd,0xcd,0x1a,0xcf,0x76,0x43,0x1f,0xca,0x15,0x6c,0x4a,0xb7,0xc7,0xb9,0xaf,0x68,0xd7,0x31 +.byte 0x1e,0x0c,0x9c,0x78,0x74,0x66,0x80,0xc6,0x74,0xbe,0x86,0x59,0x0c,0x12,0xdc,0xf3,0x1b,0xaf,0x63,0x74,0xce,0x1e,0xac,0xf0,0x65,0xa0,0xab,0x7f,0x96,0x08,0x32,0xb2,0xca,0x9c,0xfb,0x9d,0x66,0x63,0x76,0xf9,0x69,0x08,0x6e,0xd3,0x46,0xde,0xdf,0x54,0x06,0x0d,0x25,0x81,0xd9,0x5a,0x45,0xeb,0xe5,0xc0,0xf6,0x86,0x0f,0xe9,0x27,0x7c +.byte 0xdc,0x52,0x28,0xb5,0xd0,0x7d,0x07,0xc1,0xb6,0x9b,0xdc,0xea,0xd3,0x2a,0xba,0xb0,0xd5,0xa3,0xd8,0x25,0x07,0x9c,0x6c,0xd6,0x16,0xa5,0x93,0x43,0x52,0xa7,0x5c,0x2b,0xe2,0xfa,0x8e,0x6e,0xaa,0x04,0x84,0x63,0x80,0x0f,0x90,0x10,0x41,0x1c,0xf6,0x67,0xea,0x39,0xb0,0x16,0xfc,0x6f,0x85,0x28,0x8c,0x8e,0xfb,0x79,0x39,0xdf,0xf6,0x6e +.byte 0x57,0xa1,0xaa,0xf1,0x0b,0x99,0xde,0xad,0x69,0xe2,0xf4,0x74,0x8e,0x8c,0x2d,0x20,0xdb,0xf3,0x2d,0xc2,0x75,0xe7,0xd6,0xc8,0x9d,0x46,0x3b,0x8b,0x8b,0x18,0xd8,0x41,0xfd,0xc2,0x7d,0xec,0x66,0x78,0xe7,0xbe,0xee,0x2b,0x07,0xd8,0x7e,0x13,0x61,0x7e,0xab,0x7d,0x2b,0x3f,0x83,0x96,0xf5,0xab,0x0b,0x20,0xd2,0x5b,0xb0,0xeb,0xf7,0x1b +.byte 0xac,0x1a,0x16,0x46,0x21,0x90,0xdb,0x67,0x66,0x42,0xe2,0x54,0x34,0xae,0x34,0xae,0x21,0x33,0x8c,0x48,0x19,0xdb,0x1f,0xa8,0x25,0x76,0xe0,0x03,0x1c,0x35,0x8d,0xd3,0xab,0x6b,0x93,0xf3,0xad,0x7d,0x3c,0x76,0x1d,0xaa,0x43,0x80,0x0f,0x5f,0x20,0xd9,0xf0,0xff,0x8b,0xf4,0xdb,0xbc,0xf2,0xff,0xf2,0x8a,0xfc,0xf5,0x0e,0x4e,0xd9,0xb0 +.byte 0xd6,0xb3,0x86,0x5b,0x3e,0x10,0x87,0x50,0xf1,0xd2,0x8f,0x8d,0xa4,0x39,0x85,0xf5,0x90,0xd6,0x53,0x69,0x40,0x42,0xc1,0xc3,0x7c,0xc1,0x3e,0x97,0xb4,0x08,0x49,0x93,0x4e,0x4c,0x67,0xd9,0x2e,0x05,0x70,0x04,0x98,0x0a,0xed,0xd0,0xff,0x0c,0x13,0xe4,0xde,0x75,0x81,0x24,0xb1,0x27,0x79,0xeb,0x80,0x68,0x52,0x50,0x66,0x77,0x4f,0xf6 +.byte 0x64,0x2f,0x85,0x9e,0xc1,0xbf,0x9f,0x0e,0x31,0x9a,0x36,0x24,0xcd,0xa8,0xe8,0xce,0x41,0x86,0xd1,0x02,0x96,0xdc,0x1a,0xa0,0x48,0xca,0x61,0xd5,0x87,0xdb,0x0a,0xeb,0x69,0x95,0xca,0xf8,0xe5,0xa0,0x5b,0x91,0x8f,0xb9,0x59,0x5f,0x68,0x60,0x58,0xc5,0xe0,0xc7,0x02,0x68,0xa5,0x67,0x1e,0xfc,0xa9,0x27,0x9f,0x83,0x4c,0x05,0x60,0xee +.byte 0xcb,0x79,0x31,0x73,0x36,0xf4,0x39,0x44,0xdb,0xea,0x62,0x89,0x97,0x69,0xd1,0x0d,0xf6,0x27,0xcf,0x47,0xfe,0x3d,0x5c,0xe9,0x92,0x54,0x0a,0x66,0xaf,0x82,0xb1,0x49,0x87,0x3f,0xa2,0x95,0x91,0x0e,0x72,0x1e,0x7b,0xde,0x32,0x31,0x51,0x40,0x24,0x4f,0x30,0x59,0x7d,0x97,0x28,0x30,0x7e,0x93,0xcd,0x1e,0x16,0xef,0xe1,0xb5,0xa8,0xff +.byte 0x3a,0xd0,0x62,0x94,0x8b,0x72,0xe7,0x97,0x8f,0x2f,0x58,0x3e,0x62,0x43,0x6b,0x28,0x05,0xc9,0x0d,0xf0,0x09,0xbd,0x12,0x3b,0xd8,0x15,0xd3,0x7c,0x97,0x96,0x5a,0xf4,0x9f,0x8d,0x25,0xb7,0xc5,0x66,0xf7,0xf7,0x5f,0x7e,0xca,0x2f,0xcd,0x9a,0xf2,0xa3,0x9b,0x4f,0x6f,0xc3,0xd9,0x64,0x38,0xda,0x87,0x97,0x8a,0x49,0x2d,0x80,0x16,0x73 +.byte 0x88,0x62,0xd2,0xdf,0x4f,0xf7,0x79,0xc0,0x83,0xeb,0x2b,0x66,0x5a,0x21,0x3a,0xa2,0x2a,0xed,0x8c,0xe7,0x91,0x6d,0x56,0x18,0xfc,0x59,0x68,0xea,0x9f,0x5c,0x3c,0xd5,0x0f,0x64,0x70,0x89,0x22,0x83,0xed,0xfa,0xc9,0x21,0x68,0x3c,0x69,0xb8,0x3e,0x89,0xb5,0x9d,0x8b,0xc8,0xf7,0x57,0x17,0x27,0x90,0x12,0xa7,0xd2,0x4d,0x2c,0x30,0x64 +.byte 0x42,0xbe,0xa6,0x49,0x4e,0xa3,0x3b,0xdb,0xdb,0x64,0x0e,0x89,0x66,0x87,0x72,0x90,0x86,0x1d,0x0b,0x61,0x32,0x47,0x3d,0x55,0x81,0xb2,0x50,0x5a,0x76,0x6c,0xa3,0x46,0x12,0x1b,0xaf,0x6e,0xbf,0xfd,0x98,0x2f,0xb7,0xd2,0x31,0x92,0xb5,0x26,0x1a,0x3d,0xfa,0x5d,0xc0,0x24,0x44,0xd2,0x6b,0x1c,0x81,0xf5,0x5d,0x50,0xb0,0x33,0x18,0xe0 +.byte 0xc5,0xb3,0x6b,0xf4,0xfd,0xde,0xf7,0x2f,0x69,0x1d,0x5a,0xfe,0x03,0x6d,0xca,0xad,0x29,0xe0,0x6e,0x70,0xcd,0xe3,0x6d,0x38,0xef,0xf1,0x3a,0x76,0x2b,0x2c,0xb6,0xcd,0xff,0xeb,0xbc,0xe7,0xd9,0x40,0xbe,0x23,0x61,0x20,0xd5,0xb8,0x66,0x77,0x65,0xc9,0x33,0xf5,0x75,0x8e,0x15,0x98,0x3f,0xb1,0x4a,0xb8,0x1c,0x47,0x73,0x45,0x0f,0x73 +.byte 0x2a,0xa1,0xb7,0x73,0x76,0x94,0x16,0x45,0xcf,0xd6,0x8f,0xe3,0x62,0x8a,0x42,0xfd,0xe3,0x1e,0xe0,0x7d,0xb5,0x99,0xbd,0x1c,0xf2,0x60,0xb2,0x72,0xa8,0x4b,0x19,0xd6,0xd0,0xdb,0x0b,0x1f,0xc9,0x68,0xc0,0xf3,0x65,0x04,0x50,0x41,0xf0,0xb3,0x0e,0x0a,0x9d,0x7f,0x0b,0x1f,0xeb,0x5b,0x4c,0x58,0x6a,0xf2,0x02,0x95,0xd2,0xf3,0xac,0xe5 +.byte 0x69,0x81,0xb1,0x3f,0x08,0xfc,0xba,0xcb,0x36,0xcd,0x54,0x28,0xac,0x65,0xd8,0x81,0xab,0xc1,0x6a,0x51,0x97,0x21,0xe4,0xc6,0xaf,0xd8,0x76,0x76,0xa4,0xc4,0xd0,0x58,0x63,0xdf,0x32,0xf5,0x04,0xfb,0x11,0xeb,0x76,0x39,0xda,0x55,0xf4,0x7e,0x1c,0x7b,0x04,0x07,0x4d,0x5a,0xeb,0x74,0x0a,0x57,0xcf,0x10,0xf6,0x0e,0x73,0x02,0x25,0x67 +.byte 0x4f,0x8f,0x37,0x75,0x8f,0x44,0x2a,0x1a,0x6d,0x05,0xda,0xe0,0xa0,0xaa,0xd2,0x78,0xaa,0x7e,0x76,0x0a,0xde,0x2a,0x54,0xae,0x1e,0x39,0xcc,0x3c,0x1c,0xa6,0xd5,0x8a,0xca,0xb4,0xcc,0x76,0xb9,0x30,0xd2,0xe2,0x46,0x31,0xb6,0x51,0xcf,0xe2,0x24,0x77,0xc9,0x9b,0x57,0x3c,0xa3,0x84,0x60,0x59,0x28,0x5f,0x23,0x74,0x17,0x79,0x42,0xbe +.byte 0x60,0x3f,0x09,0x6a,0x43,0x8e,0x40,0x25,0x79,0xb5,0xbb,0xbb,0x72,0x50,0xad,0x4f,0xaa,0xa2,0xd4,0xb2,0xc6,0x7d,0x50,0x7b,0x98,0x59,0x22,0x06,0x7d,0x2c,0x35,0xdd,0x44,0x34,0x9c,0x28,0x98,0xf3,0xe5,0xd0,0x7e,0x09,0xbe,0xc4,0x00,0x72,0xd5,0xa6,0x3b,0x0e,0xb1,0x18,0x91,0x0a,0x4d,0x5d,0xe2,0x0a,0x98,0x79,0x30,0x9b,0xaa,0x38 +.byte 0x03,0x2b,0x6c,0xb2,0x8e,0x0a,0x1d,0x30,0x59,0x8a,0xe8,0x6c,0x6d,0xb5,0xd4,0x91,0xc5,0x28,0x1d,0x5e,0x49,0xe0,0xfc,0x26,0x7f,0x40,0xc0,0x6a,0x81,0x0d,0xb9,0xc6,0x05,0xc6,0x18,0x82,0x70,0xf6,0xea,0x0e,0xb4,0x85,0xba,0x5d,0xfa,0xfd,0xe3,0xd6,0x08,0x7c,0x3d,0x99,0x03,0xd4,0xdc,0x9b,0x50,0x12,0xc8,0xbd,0x8c,0x47,0x67,0x28 +.byte 0x83,0x97,0xca,0xef,0xc3,0x1c,0x2b,0x6e,0x3b,0xf7,0xca,0x7a,0x68,0x6e,0x39,0x25,0x58,0xf7,0xa4,0x11,0x9d,0x8d,0x49,0x29,0xd6,0x6e,0x0b,0x0a,0xcf,0xa7,0x04,0x14,0x6f,0xc4,0x4c,0x36,0x1a,0x16,0x3e,0x8f,0x99,0x69,0x94,0x1d,0xa8,0x66,0x93,0xeb,0x1d,0x82,0xfd,0x3f,0x84,0xb0,0x9d,0xa4,0xe1,0xb0,0xd4,0x9d,0xb2,0x60,0x20,0xfb +.byte 0xd3,0xa0,0xdc,0x79,0x83,0xb0,0xfc,0x50,0x18,0x57,0xe1,0xeb,0x44,0x25,0x05,0xab,0x27,0xfb,0x5f,0x83,0xcd,0x51,0xd0,0x3b,0x80,0x4a,0xce,0xbf,0xe9,0xfe,0x46,0xd2,0x5f,0xea,0x8c,0x89,0x48,0xc8,0x65,0xdd,0x2a,0xa4,0xda,0x54,0xc2,0x37,0x7e,0xd7,0xff,0x80,0x5b,0xf0,0xc3,0x40,0x44,0x40,0x72,0x63,0x23,0xc6,0x9a,0x48,0xf3,0x4b +.byte 0x91,0x64,0x26,0xfc,0xf3,0xa0,0xb9,0x06,0x0c,0x88,0xbb,0xc0,0x93,0x73,0x63,0xf6,0x9c,0x0d,0xe2,0xf6,0xee,0xe0,0x51,0xfd,0xae,0x4d,0x21,0xb9,0x6b,0x7d,0x1e,0x34,0xa0,0x4d,0xe4,0x25,0x30,0xe6,0x81,0x2e,0x32,0xef,0xb9,0x9e,0xaf,0xa0,0x22,0xe0,0x67,0xe6,0x07,0x55,0x3a,0xed,0xef,0x4f,0x87,0x2f,0x44,0xd2,0xef,0xc1,0xfb,0xc4 +.byte 0x7b,0x27,0x20,0x44,0xd2,0xd6,0xf9,0xf3,0x67,0xc1,0xbf,0xaa,0xd5,0x9c,0xd9,0x2c,0xd5,0xf1,0x42,0x2d,0xec,0x39,0xb5,0xc1,0x18,0xed,0x6c,0x47,0x80,0xf8,0x6f,0x66,0x10,0xee,0x1d,0xd6,0x79,0x01,0x4e,0x2a,0xd0,0x83,0xa7,0x9d,0x1d,0x81,0xce,0xf5,0x6f,0x26,0x86,0xd2,0xd7,0x56,0x15,0x65,0x48,0x4c,0xf1,0xf9,0x21,0x77,0xd1,0x84 +.byte 0x22,0xce,0x4d,0x8d,0x83,0xda,0x8c,0x50,0x56,0xc8,0x3b,0xc5,0xb6,0xcf,0x3e,0x0d,0x50,0xe5,0x9d,0x6c,0xb5,0x2a,0x5a,0x58,0x28,0xf5,0x0a,0x05,0xf3,0x0e,0x40,0x8e,0xb6,0xb4,0xdf,0x11,0x1b,0x34,0x81,0xc5,0x0e,0x09,0xa6,0xfc,0x46,0x14,0x02,0x78,0x94,0xbb,0x63,0x9d,0x3e,0x25,0x2c,0xc8,0x1b,0x5c,0xef,0x64,0x77,0x0c,0x04,0x40 +.byte 0xe1,0x45,0x85,0xf8,0x07,0xbf,0x14,0x65,0xe9,0xfc,0xba,0xe4,0x9c,0xa7,0x91,0x56,0x2a,0x3a,0x8e,0x33,0xae,0x56,0x04,0x9d,0x35,0xbc,0xad,0x64,0x0e,0x99,0x8e,0xb5,0x84,0x72,0xcf,0xcc,0x81,0x14,0x11,0x9e,0xe6,0xac,0x0d,0x41,0x43,0x4e,0x2a,0x0d,0xda,0x98,0x42,0xfa,0x8c,0x21,0x79,0x93,0xa3,0xdf,0x84,0x88,0x76,0x14,0x5b,0xb9 +.byte 0xff,0xe1,0xab,0x94,0xc3,0xcd,0x10,0x69,0xee,0x53,0xea,0xfe,0xfb,0xaa,0x43,0x8f,0xdd,0x55,0x88,0x34,0x5d,0x55,0x0f,0x42,0x4d,0x1d,0x93,0xce,0x96,0x67,0xf8,0x33,0xc7,0xca,0x34,0x11,0x28,0xb2,0xed,0x0f,0x00,0x40,0x84,0xee,0x51,0x26,0x6e,0x7b,0x2d,0x77,0xeb,0x18,0xb8,0x9a,0xad,0x28,0xb6,0x6c,0x5e,0xde,0x10,0x4c,0x29,0x1d +.byte 0x79,0x3c,0x2e,0x1c,0xf0,0xc8,0xb3,0xee,0x19,0x7a,0x10,0xe1,0xe3,0x05,0x1e,0x63,0xe9,0x00,0xd7,0xfe,0x83,0xe7,0x54,0xff,0x65,0x9a,0x27,0xa3,0x86,0x72,0x5c,0xb6,0xef,0xf5,0x84,0x68,0x1e,0xae,0xe6,0xf8,0x66,0x9c,0x1b,0x86,0xab,0xfa,0x1a,0xe3,0xb8,0x97,0x16,0xb1,0xb7,0x42,0xfa,0x85,0xa3,0x3a,0x0d,0x21,0xd2,0x35,0xb1,0x89 +.byte 0xf0,0x4f,0x1a,0x1d,0x45,0x34,0x2f,0x31,0x12,0x8c,0x19,0xe7,0x4b,0x14,0xa7,0xcf,0x0f,0xf9,0xcd,0x77,0x40,0xbe,0x09,0xeb,0xc3,0x3e,0x4a,0x37,0x55,0xab,0xbb,0x9c,0xe5,0x22,0x56,0x8a,0x66,0xfa,0xb1,0xff,0x73,0x29,0x52,0xb1,0x89,0xf7,0xab,0xa6,0x58,0x53,0x97,0xfd,0x44,0xda,0xbd,0x0b,0x1f,0xc8,0x88,0x01,0xcc,0x5e,0xf7,0x05 +.byte 0xbd,0xf7,0x0a,0x4d,0xcb,0xef,0xbf,0xd9,0x8e,0x15,0xc3,0x40,0xb9,0xc9,0x14,0xe5,0x05,0x3c,0x20,0x67,0xfe,0xdc,0xa6,0xb8,0x92,0xbd,0xf5,0x33,0xb5,0x77,0x11,0x28,0x47,0x21,0x28,0x18,0x61,0xf8,0x1c,0xdb,0x65,0xad,0x89,0x0d,0x98,0x79,0xca,0x2b,0xa3,0x4f,0x16,0xa6,0xb3,0xb9,0xcc,0x47,0x5b,0x13,0x96,0x2e,0x39,0x78,0x24,0xc5 +.byte 0xf9,0xf5,0xae,0xdc,0x34,0x3c,0xf7,0x48,0x0d,0x75,0xaf,0x51,0x75,0x48,0xbe,0x4d,0x73,0x89,0x5a,0xfc,0xd7,0x51,0xd3,0x93,0xa8,0xbc,0xc3,0xa6,0x6b,0x63,0xc1,0xc3,0x7b,0x48,0xf1,0x57,0xe4,0xb4,0xce,0x5f,0x18,0xae,0xdc,0x61,0x99,0xaa,0x7e,0x49,0xd6,0xb5,0x2c,0x62,0xb8,0x8c,0x4a,0x94,0xc1,0xc2,0x13,0x23,0xdc,0x7c,0x48,0xc2 +.byte 0xaa,0xc4,0xd9,0xc0,0x09,0x11,0x6e,0x35,0x07,0x14,0x77,0x7e,0xeb,0x87,0x00,0x05,0x30,0xec,0xb2,0xc6,0xde,0x6e,0x42,0x0b,0x2a,0xb6,0xca,0xb1,0xdc,0x69,0x57,0x1b,0xad,0x52,0xa8,0x22,0x1e,0xb5,0x2b,0xb5,0x8e,0x39,0x4b,0xbf,0x38,0xf4,0xb2,0xf5,0xa1,0x9c,0x7b,0x7f,0x6c,0x14,0x48,0x37,0xa9,0xf9,0xcd,0x85,0x50,0x53,0xb0,0xc1 +.byte 0x15,0x28,0x19,0x3b,0xb1,0x04,0x44,0x93,0x7a,0x16,0x76,0x69,0xa1,0x5c,0x67,0xcc,0x8d,0x02,0x56,0xcd,0xd9,0x91,0x49,0x8c,0x1b,0xc9,0x89,0x98,0x09,0x2e,0x5b,0xf8,0x7c,0xe6,0x0f,0x46,0xb0,0xcc,0xe5,0x75,0x63,0xaf,0x40,0xd5,0xa3,0x45,0x4a,0x76,0x67,0x1d,0x81,0xc2,0x25,0x85,0x7f,0x52,0xc5,0xf8,0x6d,0xd9,0xb6,0xa8,0xa4,0x96 +.byte 0x63,0xcc,0x15,0xc5,0xec,0x40,0x0e,0x08,0xf7,0x6f,0x85,0xa5,0xe7,0x2e,0xbe,0x3f,0xf4,0xc8,0x74,0xc7,0xed,0x86,0x85,0xc0,0x44,0x9e,0x80,0xc8,0x89,0xdc,0x16,0x47,0xb1,0x68,0x0e,0x65,0x66,0x0f,0xbc,0x33,0xb1,0x78,0x1e,0x5e,0xd7,0xde,0x97,0x96,0xb8,0x74,0x5c,0x90,0x7a,0xed,0x36,0xf4,0x10,0x91,0x5a,0x42,0x92,0x81,0x11,0x73 +.byte 0x3e,0xf1,0x5e,0xfb,0xc2,0x38,0xe6,0xe5,0x41,0xce,0x96,0xed,0x44,0x14,0x9c,0xc0,0x1f,0x83,0x5f,0xdd,0x50,0x87,0x90,0x86,0x50,0x61,0x87,0x99,0x7c,0x64,0x2d,0x50,0x17,0xa3,0xb0,0x7e,0x69,0xd3,0x86,0xb4,0x7c,0xe7,0x15,0x34,0x9e,0x3b,0x17,0xc0,0x2d,0x08,0x60,0x8b,0xae,0xec,0xa2,0xf6,0xf1,0xa4,0xbc,0x7b,0xc2,0x75,0x91,0x13 +.byte 0xf6,0xd0,0x71,0xf0,0x3c,0x9c,0x51,0xb3,0x33,0x53,0x57,0x47,0x8b,0x47,0xb0,0x0b,0x95,0x9a,0x39,0x70,0x63,0x91,0xcc,0xd8,0xd0,0x23,0x32,0xc0,0xb6,0x0f,0x91,0x30,0x29,0x45,0xf1,0xfc,0xa1,0x83,0x10,0x9a,0xa4,0x05,0x05,0x9f,0x33,0xbd,0xaf,0x16,0x3e,0x53,0x39,0xb1,0x4b,0x76,0x55,0x3e,0x6f,0x47,0x23,0x59,0x4c,0xbb,0x82,0x31 +.byte 0x19,0xe2,0xb1,0x49,0x20,0x91,0x2d,0xb0,0xfe,0xa6,0xae,0x7f,0x6e,0xd1,0x5b,0xb9,0x84,0x18,0x0f,0x68,0xc6,0x56,0x8a,0x22,0x81,0x3f,0x38,0x42,0x7a,0x31,0xa1,0xc1,0xf7,0x10,0x6a,0xc3,0xb1,0xaf,0x19,0xad,0x06,0x3a,0x53,0x9d,0x44,0x9f,0xe7,0x25,0xac,0x59,0x06,0xb9,0xd2,0xf6,0xce,0xb6,0x1e,0x4d,0x65,0x2e,0x05,0xb4,0x14,0x91 +.byte 0xfb,0x5b,0x26,0xd0,0xee,0xfa,0x45,0x5b,0x0c,0xd5,0x5c,0x1f,0x0c,0xe0,0xf6,0x50,0x78,0x77,0x7e,0x83,0x04,0xec,0x3b,0x53,0x28,0x97,0x56,0x61,0xeb,0xa0,0x78,0xe5,0xc0,0xb2,0x3c,0xcd,0x6f,0x4b,0xda,0x11,0x00,0x93,0x49,0x9f,0x03,0x22,0x39,0x3a,0xc8,0xef,0x01,0x91,0x12,0x36,0x15,0x0c,0x47,0xd5,0x8b,0x77,0x5e,0x5f,0x91,0x4b +.byte 0x44,0x98,0xa0,0xa0,0x46,0x0f,0x17,0xef,0xf9,0x52,0x0b,0x92,0xc1,0xe0,0xfc,0x63,0x9b,0x6d,0xe2,0xde,0x88,0x89,0x32,0x89,0x93,0x44,0x6d,0x69,0xe7,0x26,0xfd,0x77,0xc0,0x18,0x58,0xdb,0x74,0xec,0x04,0x0c,0x60,0x51,0x74,0xca,0x49,0x3e,0x4f,0x5f,0xaa,0x53,0xf2,0xc1,0xcb,0x89,0x1f,0x69,0xaa,0xbb,0x97,0x17,0x04,0x49,0x5e,0x44 +.byte 0xf3,0xf3,0xc4,0x98,0x9d,0x49,0x1e,0xb0,0x27,0x7d,0xff,0x54,0xa5,0xed,0xbe,0xb0,0x52,0xf6,0x00,0x87,0x67,0x2d,0x28,0xdb,0x09,0x4e,0xa2,0xee,0x4f,0x81,0xeb,0xa1,0xca,0x2b,0x07,0x2f,0x54,0x6d,0x5a,0x2e,0x13,0xa4,0xd0,0xac,0x21,0x7c,0x44,0xc0,0x98,0xac,0xe4,0x6e,0x94,0xd1,0x5b,0x5e,0xd6,0xf1,0x3c,0x45,0x88,0xe1,0xbd,0x58 +.byte 0xf1,0xc7,0xba,0x36,0x2c,0x15,0xb9,0xf4,0xa3,0xea,0x73,0xb4,0x91,0x53,0xd8,0x18,0x86,0x23,0x87,0x0b,0x7a,0x4a,0x2d,0x2d,0x3d,0x73,0xcb,0x05,0x11,0x4c,0x19,0x26,0xf2,0x05,0x89,0xc8,0x29,0x26,0xa7,0xe4,0xcb,0x43,0xd0,0xf6,0xbc,0x76,0xbd,0x9a,0x17,0x4a,0xf1,0x39,0xe3,0xde,0x05,0x10,0x8a,0xd3,0x11,0x53,0x61,0xef,0x33,0xd9 +.byte 0x65,0x0d,0x99,0x0b,0x39,0xa4,0x1b,0x4f,0x0b,0xa5,0xf1,0x37,0xa3,0x4f,0x54,0xa7,0x29,0xc1,0xae,0x88,0x5c,0x13,0x2f,0xb2,0xbf,0xcf,0x1b,0x0d,0xa0,0x68,0x21,0xe2,0x20,0x3f,0x02,0x9f,0x08,0x39,0xc6,0x20,0x2d,0x08,0x01,0x5d,0xf1,0x47,0xde,0x88,0xad,0x49,0x09,0xf7,0x1a,0x0c,0xa7,0x29,0x91,0xe5,0xfc,0xc5,0xde,0xd7,0x92,0x3f +.byte 0xe5,0x0c,0x91,0xea,0x24,0xfb,0x02,0x9a,0x13,0x3a,0x61,0x01,0x9d,0x7e,0x9d,0x11,0xf8,0xbd,0xe0,0x05,0xbb,0x13,0xf0,0x00,0x67,0x90,0x6f,0x80,0xe7,0x2e,0xfc,0xe0,0xea,0x8a,0x9d,0x2c,0x13,0x57,0x4c,0x78,0x1c,0x44,0xe2,0xa6,0x62,0x01,0x46,0xf8,0xbe,0xf4,0x51,0x32,0x15,0xd4,0x3c,0x7d,0x3b,0xcc,0xfd,0xc3,0x46,0x43,0xf1,0xfa +.byte 0x9e,0xee,0xad,0x47,0x8f,0x32,0x31,0x94,0x70,0x92,0xea,0x45,0xe3,0x63,0xd6,0x28,0x23,0xa5,0xdf,0x61,0xee,0x19,0x1a,0x5e,0xb0,0xe7,0x17,0xab,0xac,0xb4,0x03,0xed,0xf6,0x9e,0xba,0xdf,0x52,0x88,0xb7,0xca,0x7c,0x27,0xcd,0x7b,0xf8,0x1e,0x54,0x4b,0xe6,0xa3,0x91,0xf7,0xeb,0x22,0x65,0x95,0x13,0xe1,0xac,0xb6,0x22,0x80,0xe3,0xeb +.byte 0xf9,0xde,0xf1,0xb7,0x6a,0xfd,0xc7,0xb8,0x9b,0x9c,0x49,0x4f,0x84,0x7f,0x68,0x93,0x6c,0x3c,0xea,0xb1,0x8a,0xeb,0x23,0xca,0x2d,0x5e,0x29,0xb5,0x52,0x49,0x98,0x12,0x3f,0xed,0xf0,0xb7,0xbc,0x22,0x14,0x73,0x92,0x84,0x1b,0x3e,0x2f,0xed,0x24,0x1e,0x62,0xcc,0x09,0xe8,0x7c,0x5a,0x08,0xd4,0xc6,0xd9,0xd1,0x55,0x66,0x18,0x2c,0x6a +.byte 0x99,0xc3,0x0e,0x1e,0x7b,0xb7,0xd4,0xbd,0x0e,0x1f,0x22,0x85,0x09,0x2c,0xcf,0xff,0x79,0x9f,0x93,0xbe,0xec,0xed,0x63,0xb7,0x97,0xbb,0xeb,0xd6,0x70,0x76,0xa9,0x4f,0xb7,0x9a,0x60,0x5b,0x50,0xdf,0x85,0x46,0x69,0xa0,0x9a,0x86,0xe3,0xe2,0x13,0x2b,0x8c,0x0f,0x3b,0xab,0xa8,0xce,0xa3,0xb0,0x78,0x72,0x40,0xfb,0xd1,0x26,0x72,0xc1 +.byte 0x91,0x25,0x7b,0x29,0xde,0xcf,0x99,0xf3,0x8e,0x87,0x39,0x81,0x04,0xad,0x3b,0x11,0x6a,0xda,0x00,0xdd,0xe9,0x41,0xc1,0xd8,0xcc,0xf9,0x59,0xac,0x9b,0xb1,0x64,0x6f,0xb8,0xf4,0x9f,0x20,0xde,0x67,0x09,0x1b,0xdf,0x11,0xa5,0x94,0x56,0xab,0x76,0xba,0xc5,0xda,0x6c,0x86,0xe6,0xa4,0x73,0x59,0xa9,0xe3,0x68,0xb9,0xc0,0x50,0x1b,0x55 +.byte 0x21,0x9e,0xea,0x8d,0xcc,0x5d,0xee,0x88,0xe1,0x18,0x7c,0xcd,0x8f,0xff,0x18,0xbd,0x13,0xea,0x95,0xc4,0x8e,0xd3,0x92,0xfe,0x3d,0xda,0x6f,0xa5,0xbc,0xa0,0x77,0x5a,0x1d,0x61,0xff,0x7b,0x77,0xc4,0x06,0x25,0xc5,0xa7,0x76,0x36,0x55,0xe7,0xc0,0xf0,0x46,0x7e,0xca,0xe7,0xc1,0xe8,0x88,0x65,0xff,0xa7,0xb6,0x9c,0x83,0x1d,0x2e,0x6e +.byte 0xd6,0xd3,0x07,0x22,0x65,0x79,0x4f,0x3c,0x0a,0x5c,0x4f,0x95,0xb3,0x14,0x37,0x9b,0x0b,0x97,0x69,0xd9,0x5b,0x37,0x09,0xc3,0x70,0x5b,0x4f,0x11,0xcb,0xce,0xc0,0x06,0xf2,0xb9,0x32,0xdd,0x24,0x7b,0x8c,0xe6,0x0c,0x91,0x3b,0xa8,0xb0,0x82,0x56,0x4d,0xde,0xa0,0x5c,0x0b,0x5b,0x70,0x53,0x64,0x9d,0xab,0xbb,0x51,0x6b,0x8c,0x8f,0xe5 +.byte 0x1f,0xc0,0xb8,0xfe,0x1b,0xf6,0x24,0x26,0x62,0xcb,0x78,0x84,0x90,0x76,0x67,0x30,0x18,0x37,0xa9,0xca,0xb7,0x0d,0xac,0x17,0x86,0xb1,0x87,0x59,0x18,0xc3,0x9e,0x62,0x1b,0xb1,0x04,0x52,0xfc,0x7c,0x86,0xa0,0x37,0xb9,0x8b,0x7a,0x85,0x79,0x21,0xe0,0x0f,0x87,0x28,0x91,0xd0,0xe5,0x24,0x63,0x5c,0x7c,0xe8,0x47,0xfa,0x42,0x55,0xe9 +.byte 0x66,0xad,0xdf,0xc3,0x43,0x90,0x47,0x83,0x24,0x09,0x54,0x5f,0x14,0x27,0x53,0xb3,0x22,0x15,0x52,0x84,0x2f,0x61,0x8c,0x01,0x9e,0x34,0x61,0x3f,0x76,0x44,0x1c,0xca,0x79,0x2c,0x40,0x4e,0xa0,0x36,0x11,0xe0,0x23,0x0f,0xa7,0x78,0xf9,0xf9,0x2a,0x2c,0x98,0x5c,0xa9,0x2d,0x66,0xb9,0x87,0x43,0xd5,0xbc,0x64,0xe5,0x52,0x2f,0x1d,0xdc +.byte 0x1d,0xf4,0xb3,0x18,0x6b,0xd1,0x3b,0x8b,0xa3,0x47,0x65,0x62,0xcc,0xca,0x5f,0x00,0xbb,0x78,0x9d,0x35,0xd4,0x79,0x45,0x33,0xc7,0xa8,0x29,0x96,0x98,0xa4,0x23,0x2c,0x23,0x7f,0x5a,0x1d,0x09,0xb4,0xcf,0xac,0x54,0xcd,0x27,0xda,0x88,0x21,0xe2,0xb4,0x85,0xdc,0xc9,0x4a,0x6b,0xc4,0xfa,0x48,0xc5,0x91,0xc1,0x53,0x4b,0xa1,0x7a,0x9c +.byte 0x8a,0x7d,0x35,0x52,0xf1,0x58,0x9d,0x20,0x36,0xc2,0x78,0xdb,0x37,0xf8,0xa4,0x2f,0x50,0x98,0xb0,0x34,0x51,0x66,0x93,0xcf,0xe7,0xf0,0x06,0xf1,0xcd,0x0e,0x4f,0x33,0xcc,0x9b,0x73,0x3b,0xc9,0x51,0x63,0x6d,0x29,0x6b,0xf4,0x9d,0x2c,0x76,0x59,0xcd,0xfc,0x11,0x35,0x52,0xbd,0x3b,0x2e,0x7d,0x8a,0x0d,0xb0,0xbb,0x90,0x9b,0x9c,0xac +.byte 0x1c,0x80,0x89,0xd6,0x6f,0xaf,0xea,0x89,0x38,0x74,0xef,0x83,0x82,0x91,0xf7,0x74,0x96,0x30,0x40,0xe2,0x18,0x2b,0xb4,0xf6,0x15,0xf0,0x8e,0x63,0xe1,0x82,0x55,0x7b,0x65,0x70,0x33,0x14,0xef,0x7a,0x7c,0x2d,0xa9,0x17,0x1b,0x53,0x1e,0xf8,0x98,0x1b,0xbe,0xc8,0x00,0xf5,0xbf,0x79,0xe7,0x8e,0xf2,0xdb,0x59,0x0d,0x46,0xab,0x43,0xd0 +.byte 0xe4,0xa0,0xeb,0x29,0x6a,0x8b,0xc1,0x99,0xa6,0xcc,0x8e,0xe5,0xde,0x67,0xdf,0x49,0x09,0x62,0x8d,0x4b,0xa1,0x1c,0x3b,0x01,0xe2,0x95,0x65,0x10,0xa5,0x91,0xd0,0x48,0x35,0x96,0xcf,0xe4,0x51,0xd2,0x7f,0x93,0x49,0xab,0x1a,0xba,0x08,0x33,0x54,0x34,0xd7,0x00,0xc9,0xa0,0x07,0x03,0xc7,0x8a,0x65,0xa2,0x84,0x60,0xcd,0xaa,0xa2,0x46 +.byte 0x8c,0x67,0xd9,0xc1,0xe7,0x58,0xc5,0x1d,0xc0,0xb3,0xc6,0xb2,0x2a,0xfb,0x70,0x04,0xa2,0x25,0x7f,0x75,0x3c,0xd5,0x8e,0x9c,0x33,0xa2,0xdc,0x20,0x4c,0x26,0x5b,0xbe,0xd9,0x00,0x5d,0xa2,0xbd,0x42,0xbd,0x0d,0xd6,0x52,0x79,0xb5,0x67,0xf6,0x27,0x62,0xc8,0x64,0x05,0xc5,0x0f,0xae,0xe1,0x78,0x39,0xd1,0xb5,0x28,0xe9,0xd4,0x2a,0xaa +.byte 0xd4,0xc4,0x3e,0x43,0x27,0x83,0xfa,0xdb,0x46,0x73,0x20,0xcd,0x2c,0xba,0x33,0xb4,0x77,0x10,0x32,0x3d,0x8e,0x56,0x88,0x81,0xe1,0x4c,0x8b,0x46,0x60,0xcb,0xb7,0x67,0xd7,0x7b,0xc2,0x47,0x7d,0xd8,0x2d,0x4c,0x09,0x9f,0x07,0x8e,0x34,0x45,0xf4,0x50,0x69,0xfd,0x35,0x0a,0x09,0x9e,0xac,0x49,0x5f,0xdf,0x72,0x84,0x97,0x93,0x30,0x2c +.byte 0xc6,0x20,0x6f,0xb5,0x18,0x03,0xb6,0x30,0x23,0xc8,0xcd,0xa1,0x43,0xbd,0xbb,0x6f,0xde,0xb3,0xcb,0x1c,0xdd,0x41,0x71,0xfa,0x37,0xa7,0xa9,0x57,0x5a,0xf7,0xee,0xcd,0xb1,0xc1,0xb6,0x78,0x1c,0xe3,0xde,0x5c,0x02,0xc8,0xce,0xb7,0x8e,0x72,0xce,0xfd,0x79,0xcf,0x1a,0xef,0xcb,0x5b,0x5d,0x3c,0x1d,0xc8,0x1e,0x9f,0x67,0x26,0x86,0xd3 +.byte 0x3b,0x98,0x49,0x04,0xcd,0x1b,0x48,0x7c,0xa6,0xbe,0x37,0x0b,0x19,0xb1,0xb7,0x8a,0x74,0x0a,0xd9,0x4f,0x7b,0xbb,0x8e,0xc6,0x9b,0xdd,0xbc,0x61,0xfd,0xdd,0x86,0x7e,0x70,0x2e,0xe4,0x94,0xb4,0x62,0x47,0x6b,0x7c,0x92,0x41,0xda,0x05,0xdc,0xaf,0x5c,0x93,0xbc,0x7d,0xad,0xce,0x44,0x9e,0x27,0x1c,0x74,0x30,0x01,0xf2,0x8a,0x22,0xce +.byte 0x88,0x61,0xf5,0xb8,0xe2,0xf0,0xca,0x14,0x21,0x53,0xd3,0xbe,0x95,0x8f,0x52,0x10,0x21,0xc5,0x25,0x16,0xa1,0x4f,0xef,0x9a,0x6f,0xce,0xe9,0xee,0x06,0xa8,0x32,0xa4,0xac,0xee,0xd8,0x95,0x0b,0x65,0x10,0xbc,0xb3,0x15,0x48,0xf9,0x96,0xee,0xde,0x5d,0xf6,0x38,0x5f,0x32,0x70,0xd1,0x29,0xa8,0x1d,0xdc,0xf4,0x34,0x2d,0x0c,0x93,0x48 +.byte 0x8c,0x40,0xed,0x35,0x41,0xfe,0x4b,0xab,0x20,0x7d,0x95,0x74,0x02,0xe5,0x71,0x76,0x7e,0x59,0x35,0xb3,0xd7,0x43,0x1f,0xd4,0xe6,0x02,0x86,0xba,0x4f,0x53,0xd9,0xc3,0x7d,0x7f,0x3d,0xb6,0xd8,0x92,0x07,0x89,0x99,0x46,0xf8,0x09,0xcd,0x19,0x43,0x93,0xa7,0xc1,0xb2,0x5d,0xec,0xbf,0x09,0xf4,0xba,0xfc,0xf7,0xf1,0xa7,0x2e,0xfe,0x71 +.byte 0x04,0x58,0xab,0x16,0xd7,0xc0,0xf7,0x03,0xd4,0xc4,0xb9,0xe4,0xd8,0xfc,0x5b,0x66,0xa6,0xb3,0x6a,0x94,0x0e,0xba,0x8c,0x54,0x5c,0x8c,0x02,0x0a,0x33,0xcb,0xde,0x1c,0xad,0x6d,0xef,0x48,0x05,0xa6,0xca,0x9a,0x27,0xd6,0x1c,0xc3,0xea,0x3a,0x46,0x20,0xec,0x72,0xc4,0x94,0x89,0x7e,0xba,0xa9,0x2f,0xe5,0xec,0x1a,0xe4,0x50,0x54,0xeb +.byte 0xd9,0x5a,0x08,0xc5,0x84,0xc1,0x9a,0xdf,0xb0,0xd4,0x9a,0x6d,0xa2,0x93,0x52,0xd2,0x4d,0x69,0x88,0xc8,0x40,0x2d,0x26,0xbd,0x7a,0x37,0x04,0x21,0xe1,0x9d,0xc9,0xed,0xda,0x7a,0x4c,0x11,0x49,0x14,0x42,0xa1,0xdb,0x6e,0xed,0x1b,0x37,0xbf,0x09,0xac,0x35,0xda,0x80,0xf6,0x75,0xd4,0x32,0x54,0xb5,0x18,0xe8,0x79,0x25,0xc4,0x95,0xe8 +.byte 0x74,0xcf,0x6d,0xac,0x34,0x1f,0xea,0xd4,0x2e,0xd1,0x77,0x5e,0x90,0x8f,0x12,0x51,0xbb,0x3c,0xdf,0xe6,0xf4,0x49,0x8c,0x0f,0x9a,0x8e,0xe3,0x96,0xbd,0xba,0xe6,0x47,0x4b,0x50,0xc7,0xa9,0x29,0xea,0x09,0x5d,0xef,0x3c,0x91,0x48,0xc6,0x37,0xfd,0xac,0x7b,0xe5,0x04,0x25,0x93,0x0b,0xe3,0xce,0x32,0x46,0x38,0x81,0x97,0x57,0xbe,0x1f +.byte 0x3c,0x61,0x2d,0xd1,0x4e,0xca,0xbb,0x44,0xc6,0xfd,0xdf,0xdd,0x11,0xbf,0xbf,0xa8,0xc0,0x32,0x67,0xc1,0x2e,0xd7,0xbe,0x3c,0xe3,0xcb,0x57,0xa5,0x6d,0xbb,0x8e,0x0f,0x69,0x22,0x42,0xef,0x53,0x0f,0xce,0x09,0x6a,0xda,0xbf,0xd6,0xed,0x61,0x67,0x82,0x83,0x13,0x63,0x97,0x7d,0x1a,0xad,0x34,0x77,0x37,0xa6,0xe0,0x89,0xaa,0xd4,0xb6 +.byte 0x8f,0x93,0xff,0xb8,0x8f,0x63,0x14,0xfd,0x17,0xff,0xe5,0x7c,0x83,0x23,0xaa,0xe0,0xb9,0xd9,0x94,0x3a,0x1a,0xe7,0xa5,0xbd,0xa6,0x2b,0xd3,0x49,0xca,0xeb,0x7d,0x87,0x1d,0x54,0x16,0x93,0xec,0x14,0x8b,0x77,0x3c,0xb4,0xbe,0x33,0x76,0x5e,0xcb,0x33,0x27,0xd3,0x20,0xd6,0xed,0x0c,0x66,0xb8,0xe0,0x00,0xa6,0x76,0xcd,0x8b,0xb4,0xef +.byte 0x11,0xbc,0xe5,0x59,0xcf,0x1d,0xf5,0x15,0x58,0x4a,0xe1,0xfd,0x87,0x8c,0x7b,0xb9,0xa4,0x42,0x5a,0xed,0x51,0x7e,0x8d,0xa6,0x19,0xaa,0xc4,0xa6,0x14,0x74,0x45,0xb1,0xda,0x87,0x0f,0xd7,0xe7,0x66,0x3b,0xcd,0x04,0x02,0x14,0x20,0x41,0x15,0x4c,0x33,0x79,0x80,0x7d,0xd4,0x44,0x2c,0xab,0x6c,0xf4,0xa8,0xd4,0x31,0x43,0x7b,0xa7,0xc7 +.byte 0x65,0x0e,0x32,0xc8,0xc8,0x6d,0xf5,0x65,0x1b,0x26,0xf1,0xe4,0x68,0x15,0x88,0x1b,0x00,0x60,0x23,0x31,0xd7,0x4b,0x57,0xda,0xf1,0x19,0xa9,0xd9,0xaf,0xe6,0xa9,0x1e,0x2c,0x0d,0x23,0xe4,0x5b,0xcb,0x43,0x38,0xf0,0x93,0xd3,0xfb,0x6a,0x9b,0x83,0x30,0x55,0x96,0x9f,0x53,0x06,0x3f,0xaf,0x40,0x69,0xef,0x9a,0x47,0x6b,0xba,0x7c,0x10 +.byte 0x10,0x44,0x89,0xfa,0xb9,0x9e,0x70,0xed,0x25,0x59,0x68,0xae,0x9b,0x17,0xcf,0x80,0x6f,0x34,0xb8,0x07,0x40,0xe5,0x27,0x6d,0xcd,0x46,0x2c,0x36,0x90,0xf3,0x83,0x74,0x68,0x35,0xf2,0x05,0xa8,0xdf,0x4e,0x34,0xc5,0xb4,0xeb,0x5a,0x7d,0xe6,0x10,0x8a,0x23,0x54,0xeb,0x9b,0x27,0xf2,0x07,0xee,0xf9,0x05,0xc2,0x5a,0x88,0xbd,0x49,0x2e +.byte 0x1b,0x00,0x31,0x68,0x4a,0xc9,0x3a,0xc5,0x93,0x82,0xa8,0x39,0xba,0x55,0xcd,0xc1,0xda,0x49,0xc2,0x4c,0xf4,0x93,0x00,0xcf,0x61,0xa4,0xbb,0x8c,0x64,0x33,0x90,0x14,0x6d,0x1d,0xad,0x75,0x97,0xd9,0x1d,0xfb,0x27,0x67,0x43,0x04,0xdc,0x4e,0xdf,0x0e,0x0c,0x7e,0x1c,0x89,0xfe,0x31,0xb7,0x9b,0x07,0x5e,0x99,0x08,0x22,0xef,0x6e,0x4d +.byte 0x8b,0xd6,0x27,0xe6,0x24,0x1a,0x28,0xb0,0x22,0xa5,0x69,0x17,0x82,0x46,0xe3,0x90,0xe8,0x04,0xae,0x90,0x66,0x14,0xec,0xa2,0x1b,0x7e,0x09,0x13,0x32,0x9d,0xec,0x8b,0x51,0x5f,0xa8,0x96,0x8f,0x4c,0xc6,0xbd,0x5c,0x70,0x29,0x21,0xac,0xe9,0x6e,0xb0,0x0c,0x61,0x50,0xba,0xcc,0x55,0x71,0xda,0x2a,0x92,0x86,0x0c,0xff,0xaf,0x7a,0xcf +.byte 0xaf,0x2a,0xbd,0xd6,0x15,0xa4,0x4c,0x2e,0x76,0x0d,0xcf,0x10,0x11,0x4a,0xd1,0x89,0xdd,0x46,0x5f,0x6b,0x5a,0x02,0x05,0x49,0x6f,0x98,0x6a,0xa7,0x8a,0x66,0x87,0x59,0x23,0xb5,0x3f,0x2e,0x95,0x73,0xfe,0x48,0xe9,0x0d,0x17,0xa6,0xa5,0x4e,0x40,0x98,0x79,0x40,0x1a,0x10,0x1d,0x84,0xdd,0x6f,0x17,0xa7,0xb7,0xfb,0x49,0xbd,0x54,0x97 +.byte 0x0f,0x42,0x25,0x95,0x83,0xf0,0x97,0xe7,0x4c,0x24,0xb5,0xe8,0x23,0x0a,0xd6,0xbf,0xef,0x2c,0x03,0x4f,0x87,0x59,0xe8,0x80,0x87,0xcc,0x51,0x1b,0x94,0xd8,0x60,0xe7,0x10,0x4d,0x01,0xfd,0x83,0xf2,0xd8,0x8d,0x1b,0x33,0xbf,0xaf,0x36,0x41,0x47,0x51,0xe0,0x45,0x2a,0x05,0x5f,0xe1,0x92,0xf8,0xa5,0x15,0x46,0x35,0xd8,0x9b,0xe0,0xff +.byte 0xee,0xa6,0x4e,0x7d,0xfd,0x96,0xa5,0x75,0xdf,0x7e,0xb0,0x7d,0x14,0x73,0xdd,0xbe,0x17,0x6d,0xdd,0xec,0xac,0x9a,0x92,0x68,0xe3,0x44,0x16,0x63,0x22,0xa8,0x15,0x58,0x8c,0x11,0x23,0x46,0x18,0xae,0x47,0x39,0x87,0xc7,0x4c,0x30,0x09,0xce,0xe5,0xc4,0xd8,0x82,0xc6,0xc6,0x3d,0x31,0xf6,0x0f,0xb5,0x69,0x61,0x63,0x88,0xd6,0xb8,0xda +.byte 0x89,0x29,0x87,0x69,0x6e,0x3f,0x55,0x2f,0xbc,0x91,0x91,0x43,0x7d,0xb3,0x7b,0x99,0x5a,0x5a,0xb0,0x7d,0x90,0xa7,0xe7,0x30,0x0d,0x32,0xb2,0x43,0x43,0x78,0x59,0x6e,0xbb,0xd7,0x76,0xd4,0x5b,0x4d,0xc4,0xa9,0x99,0xdd,0xd3,0xce,0x3d,0x13,0x41,0x38,0x33,0xed,0xb8,0x76,0x1a,0xbb,0xfd,0x26,0xcd,0x69,0x89,0x22,0x16,0x9a,0x21,0x35 +.byte 0x38,0x77,0x14,0x10,0x42,0x17,0x1f,0xa1,0xbf,0x55,0xb4,0x51,0x62,0x15,0xac,0xd0,0xa2,0x71,0xe4,0x32,0x89,0x33,0x8b,0x74,0xc6,0x61,0x38,0xd0,0xfe,0x28,0x69,0xe6,0x88,0x1b,0x11,0x7e,0x46,0x39,0xba,0x24,0xdd,0x1f,0x61,0xf4,0x74,0xad,0x58,0x94,0xa9,0x3e,0xc7,0x2a,0x9e,0xc0,0xe1,0x1c,0xee,0x21,0xab,0x3e,0x65,0x0c,0xe8,0xd8 +.byte 0x71,0x52,0xf3,0x6c,0x64,0x53,0x75,0x17,0x87,0x55,0x14,0x42,0x25,0x7f,0xe7,0x0d,0x89,0x1b,0x77,0x26,0xc4,0xaa,0xcc,0x91,0x47,0xe5,0x54,0xae,0x1a,0x0d,0x04,0x99,0xeb,0x56,0xd8,0xb4,0x6d,0xeb,0xec,0x2f,0x6c,0xc5,0x8e,0x76,0xe1,0xa0,0xa7,0x42,0x06,0xc9,0xc3,0x03,0xee,0xa9,0x9b,0x1e,0xfc,0x11,0xf5,0x2f,0x2b,0x14,0xb8,0x9f +.byte 0x87,0x61,0x9b,0xc7,0x38,0x0e,0x58,0xf1,0xd4,0x36,0xca,0x82,0x85,0x9c,0xde,0xec,0xd3,0x1e,0x29,0x4e,0x70,0x9e,0x9a,0xe0,0x8b,0x6f,0xfe,0xd0,0xe9,0x95,0x51,0xcf,0x36,0x31,0x9c,0xff,0x63,0xc6,0x04,0x8e,0x61,0xc2,0xcb,0x3a,0xfa,0xd0,0xd7,0x29,0xbd,0xe7,0x8a,0x2b,0x8e,0xa0,0xac,0x58,0x93,0xb3,0x52,0xca,0x80,0x17,0xd2,0x2d +.byte 0x93,0x5f,0xe0,0x8a,0x47,0x3c,0x67,0x95,0x64,0x91,0xa4,0x76,0xa4,0x5f,0xfa,0x93,0x4d,0xc7,0x6e,0x5d,0x23,0x9f,0xe1,0x4a,0x16,0xff,0xa5,0xf0,0x94,0xa8,0x02,0xcc,0x9a,0x84,0xd5,0x9d,0xb6,0xe5,0x7c,0x76,0x3f,0xc9,0xfd,0xdc,0x8e,0x59,0x9a,0x22,0x18,0x3c,0xe6,0x90,0x85,0x10,0x73,0x2d,0x65,0xa7,0xa7,0xe1,0xeb,0xc5,0x05,0x24 +.byte 0x1e,0x0b,0x31,0x19,0xb5,0xb0,0x8d,0xc0,0xb5,0x04,0xfe,0x9d,0xfa,0xf7,0xcd,0x71,0x29,0x40,0x19,0x23,0xed,0x2c,0xdb,0x89,0x89,0x8d,0x69,0x22,0x4c,0x9c,0xa7,0xf7,0xb1,0x56,0x87,0xa3,0x44,0xa9,0xa3,0x16,0x28,0xce,0x94,0x40,0x6f,0x71,0x77,0x0e,0x6d,0xe9,0x78,0xa2,0x2a,0x17,0x45,0x03,0xeb,0x1e,0xf1,0xfa,0x56,0x3e,0xa7,0x6b +.byte 0x08,0x06,0x6a,0xcb,0x8f,0x5e,0x0f,0xd3,0x6e,0x4b,0x21,0x31,0x73,0x50,0x94,0x56,0xf9,0xb9,0xc7,0x38,0x69,0xe8,0x09,0x3f,0x03,0xb3,0xb5,0xe8,0x2a,0x5e,0xf6,0xad,0xae,0x6f,0xab,0x6a,0x49,0xdd,0x93,0x6d,0xfb,0x8b,0xde,0xea,0x8b,0xb0,0xa1,0x44,0xf0,0xb3,0xf6,0xaa,0xe3,0xc8,0x04,0x87,0x9f,0x8b,0xee,0xab,0x13,0x1d,0x2d,0xeb +.byte 0x09,0x62,0x21,0x49,0x5f,0xb6,0x95,0xab,0xc4,0xee,0x69,0xfb,0x31,0xff,0xbf,0x1a,0xa6,0x4c,0x67,0x66,0x84,0xe6,0x0c,0xb7,0xb2,0x3e,0x3f,0xa4,0xb3,0x52,0xde,0x15,0xc9,0xa7,0xa9,0xb5,0x0d,0xe5,0x0b,0x99,0xa6,0xb6,0x8f,0x69,0xc5,0x6d,0x6c,0xbb,0x83,0x89,0x4e,0xfc,0x49,0x79,0x4d,0x46,0x31,0xa0,0x09,0x5f,0x5d,0xd0,0x5b,0x80 +.byte 0xa1,0xf4,0x36,0x48,0x97,0x6a,0xfd,0x34,0xcb,0x20,0xa8,0x01,0x25,0x04,0xe7,0x13,0x12,0x87,0x66,0x27,0x96,0x36,0xba,0x92,0xbd,0xda,0x94,0x11,0xef,0x90,0xbd,0xbc,0x9e,0xf9,0x63,0xb3,0xa6,0xc1,0xbb,0x46,0xe8,0x86,0x3f,0x2d,0xf9,0x11,0x3a,0x23,0xa8,0x7a,0x33,0x41,0x3e,0x2e,0x5d,0xde,0xc0,0xd2,0x23,0xca,0x41,0xa0,0xb9,0x70 +.byte 0x6d,0x31,0xf3,0x89,0x87,0x9b,0x72,0xd9,0x15,0x4d,0x8b,0x51,0xdd,0x56,0xa1,0xb4,0x68,0x52,0x65,0x81,0x12,0x46,0xea,0x24,0xb4,0x34,0xcc,0xa0,0xdb,0x7d,0x96,0xd9,0x8e,0x64,0x61,0x10,0x7c,0x2a,0x00,0x4d,0x82,0x61,0x54,0xa4,0x70,0x3d,0x9c,0xa5,0x0b,0xd2,0x08,0x71,0xa8,0x94,0xb1,0xb4,0x30,0x61,0x59,0x9f,0x72,0x61,0x56,0x2d +.byte 0xa3,0xf4,0x9d,0x1c,0xfc,0x49,0x9d,0x39,0x27,0xcb,0x54,0xb2,0xce,0x3c,0xb6,0x76,0xe5,0x8e,0xa5,0xe7,0x08,0xd4,0xc7,0x2c,0xa6,0x28,0xc8,0x3e,0x22,0x14,0x06,0x75,0x68,0x0d,0x6b,0xb5,0xa3,0x68,0x14,0x17,0xfe,0xb8,0xcc,0x26,0x5b,0x9d,0x0b,0xcc,0x3e,0xd7,0x6c,0xe0,0xec,0x5e,0x1e,0x1e,0xb8,0x9a,0xbe,0x91,0xb5,0xa6,0xb5,0x83 +.byte 0x28,0xc2,0x35,0x65,0xd3,0xde,0xdd,0x71,0x29,0x13,0xc1,0xee,0x78,0x22,0x34,0x0b,0x77,0x3a,0x48,0x98,0x26,0x43,0xc2,0xce,0x03,0xe8,0x75,0xf8,0x8a,0xdf,0x6a,0xb0,0xb4,0x8c,0x11,0x8c,0xe5,0x95,0x96,0x17,0xfb,0x06,0x5e,0x8f,0x36,0x10,0xc5,0x04,0x43,0x1b,0xed,0xd3,0xad,0xd4,0xa4,0xe0,0x17,0x85,0xed,0x9b,0xd8,0xae,0x98,0x46 +.byte 0x58,0x57,0x0e,0x46,0xea,0x3f,0x07,0x6d,0x0e,0x46,0xda,0x2f,0x68,0x2b,0xd6,0xe7,0x0d,0x4b,0xbe,0x32,0xee,0x10,0x73,0x18,0x7d,0x6b,0x2d,0x04,0x27,0x72,0xb1,0xe1,0xbf,0x89,0xaa,0x4d,0x1a,0xfc,0xbd,0xf2,0xc3,0x9f,0xf0,0x01,0x85,0x62,0x09,0x4d,0x08,0x2c,0x57,0x9a,0x7b,0xad,0x0b,0x79,0xff,0x14,0xa1,0x45,0xde,0x21,0x8f,0xe2 +.byte 0x93,0xd0,0x35,0x26,0xc3,0xbc,0x8c,0xb7,0x57,0x6a,0xdf,0x98,0xa7,0x75,0xc6,0xf6,0x4b,0x5f,0x91,0x6e,0x71,0x3a,0x5c,0x5f,0x57,0x63,0x34,0x87,0xf8,0x20,0x6a,0xa1,0xbf,0xf8,0xca,0x8e,0xf9,0xa9,0x10,0x8b,0xab,0x0b,0xc2,0xcc,0x71,0x89,0x7c,0xef,0x70,0x3a,0xb0,0xf6,0x90,0xcc,0x6b,0x2c,0xcc,0x8b,0x2a,0x21,0x78,0x23,0xa0,0x71 +.byte 0x8c,0x7b,0xc1,0x0f,0x27,0x72,0x40,0xe4,0x9e,0x35,0xf3,0x0a,0xc0,0x7e,0x7f,0xe5,0x9b,0xdb,0x93,0x49,0x08,0xc3,0x6b,0xb7,0xea,0xea,0xd4,0x5a,0x96,0x97,0x3c,0xdf,0xc7,0x02,0x39,0x9f,0xa3,0xca,0xdd,0x62,0xf3,0x68,0xc7,0xae,0x37,0xc1,0x35,0x73,0xb2,0x5d,0x99,0xe4,0xae,0x27,0x55,0x5e,0x6a,0xae,0x6f,0x1a,0x95,0x51,0xb1,0x3b +.byte 0xd7,0xb4,0x4d,0x3d,0x88,0x54,0x01,0xbe,0x2c,0x12,0x17,0x29,0x4f,0xf3,0xed,0x5a,0x1f,0xa9,0xf0,0x67,0xbd,0x7c,0xad,0xe5,0x58,0x52,0xd4,0xd1,0xfe,0x1e,0x1b,0xd6,0xce,0x7c,0xc3,0xa2,0xa9,0x72,0x9b,0x6a,0xe5,0xf9,0x39,0x22,0xaa,0x7f,0x2e,0xa2,0x53,0x75,0xf0,0x99,0x2e,0x36,0x86,0x83,0x10,0x63,0xd7,0xac,0xa3,0x52,0xa6,0x23 +.byte 0x80,0x46,0xe4,0xa9,0x07,0x79,0xe1,0x61,0x75,0xbf,0x08,0x31,0x6c,0xdd,0xe1,0x30,0xd0,0x35,0xc2,0xbd,0x30,0xb8,0x85,0xf3,0xd2,0x2c,0x90,0x7a,0xf0,0xd3,0x80,0xe5,0xf1,0xc2,0x58,0x3d,0xf7,0x3c,0xbc,0xff,0x03,0x4d,0xf7,0xad,0x2f,0xa6,0xfe,0x73,0xde,0xa8,0x60,0xd7,0x89,0x4a,0xcf,0x3d,0xf3,0xab,0x62,0xfa,0x9d,0x46,0xad,0xd0 +.byte 0x97,0x6f,0x89,0x84,0x16,0x9b,0x84,0xb2,0x6c,0x63,0x6d,0x29,0xee,0x8e,0x97,0x3c,0x48,0x19,0x92,0x62,0xdc,0x1d,0x35,0x9d,0xec,0x01,0x00,0x64,0xbf,0x4d,0x8b,0xa3,0x13,0x48,0x9f,0xb4,0x01,0x0d,0xb1,0xc4,0xf2,0xf2,0x6a,0x84,0x1a,0x07,0x3c,0x46,0xa6,0xb5,0x41,0x9a,0x32,0x7e,0xc3,0x4f,0x87,0x95,0x71,0x7a,0xbf,0x74,0xf8,0x0b +.byte 0xfb,0xa5,0xde,0xa8,0x35,0xf1,0xcb,0x04,0x8d,0x8b,0xd3,0xb0,0xc8,0x1d,0x6c,0xaf,0xb4,0x21,0x79,0x1c,0x34,0x71,0x2f,0xf5,0xc4,0xbe,0xad,0xbc,0xaf,0x2f,0x54,0x81,0xd9,0xf8,0xff,0x59,0xf9,0x4e,0x62,0x9f,0x7d,0x7c,0xe9,0xdc,0x67,0xae,0xa3,0x32,0x4b,0xf7,0x4e,0x53,0x4c,0x55,0x7d,0xc5,0xdd,0xd4,0x5d,0x93,0xb8,0x98,0x3e,0xd3 +.byte 0x15,0x65,0x52,0x78,0x5a,0xd2,0x21,0x84,0x5d,0x28,0xaf,0x44,0x7d,0x18,0xf8,0xdd,0x5c,0xc3,0x6e,0xc8,0x05,0x05,0x30,0xd0,0x82,0xf8,0x00,0x0f,0x3d,0x5c,0x62,0x7e,0xa6,0xd5,0x7b,0x9f,0xb1,0x44,0xb7,0x0d,0x22,0x81,0xe1,0x4a,0x2b,0x79,0x7e,0x39,0x4d,0x8a,0x9a,0xfd,0x94,0x0c,0xf7,0x23,0x10,0x99,0xd2,0xd2,0x8b,0x98,0xe5,0x9d +.byte 0xb0,0xbf,0xcf,0x06,0x08,0x80,0x32,0x69,0xfd,0x81,0x5f,0xb3,0x66,0x11,0x63,0xeb,0x30,0x1d,0xcd,0x5b,0x5b,0xec,0x0c,0xca,0x30,0x37,0xa0,0x82,0x79,0x75,0x87,0xc1,0xfa,0x5b,0x38,0x4b,0xe3,0xea,0x46,0x49,0x36,0x92,0x92,0xf0,0xc9,0x15,0xa5,0xec,0x9e,0x21,0xb6,0x9f,0xb4,0x6d,0xf6,0xef,0x5c,0x2f,0x7d,0xa4,0xb3,0x25,0xfb,0x13 +.byte 0x40,0xe1,0xa0,0x20,0x4a,0x3a,0xe2,0x3e,0xf5,0xe0,0x68,0x61,0x11,0x9a,0xfb,0x1e,0xe8,0x1b,0xe0,0x17,0x9c,0x8a,0xe5,0x53,0x74,0xdd,0xec,0xc6,0x03,0xc6,0xd0,0x9b,0xc2,0x0b,0x77,0x4c,0x36,0x2b,0xac,0x4e,0x4d,0xd2,0x26,0x70,0x39,0x96,0xb4,0x11,0x1a,0x5b,0xcc,0x3f,0xb9,0xcf,0x0d,0x04,0x55,0x05,0x00,0x66,0x8f,0xa9,0xec,0x31 +.byte 0xe5,0x47,0x4c,0x9b,0xb7,0x6e,0xa5,0xe7,0x9e,0x70,0xf4,0x02,0x2a,0x3c,0xa2,0x03,0x04,0x30,0x9e,0x3f,0x7c,0xaa,0x0a,0x8f,0x55,0x61,0xca,0x50,0x35,0xe6,0xa4,0x24,0x61,0x26,0x31,0x9e,0x9e,0x77,0x0d,0x15,0x3a,0xc0,0x88,0x32,0xb5,0xbb,0x3d,0x3e,0x59,0x25,0x52,0x81,0x2e,0x4b,0xc6,0x5d,0x9f,0x87,0x0f,0x1f,0x5e,0xec,0xdd,0xbe +.byte 0x32,0x6c,0x71,0xef,0xd2,0x9c,0xfd,0x70,0xc8,0xf6,0x1f,0xb9,0xc9,0xdd,0x4d,0x39,0x61,0x92,0xbd,0x0c,0x48,0x63,0x4b,0xd2,0x2b,0x8c,0x4b,0x35,0xb1,0x8e,0x04,0x44,0x3c,0xe1,0xde,0xfd,0x6e,0xde,0xeb,0x94,0x51,0xea,0x36,0x7b,0xc6,0x87,0x15,0x34,0x68,0xa0,0xb8,0x94,0xb6,0x56,0x33,0xf4,0xab,0x84,0xed,0x1c,0x36,0x91,0xa7,0x1b +.byte 0x03,0xca,0x48,0x64,0x16,0x5b,0x4b,0x69,0x47,0xae,0xd7,0xc9,0xcf,0x74,0xd2,0xbd,0x60,0x04,0x7c,0x66,0xe9,0x12,0x92,0x40,0x78,0x23,0x0b,0x5b,0xa0,0xda,0xf7,0xe4,0x9a,0xad,0x9c,0x31,0xe7,0xaa,0xad,0x5a,0xc3,0x45,0x00,0x6c,0xd3,0x4d,0x93,0xdf,0xb6,0x68,0x11,0x3f,0x2a,0xbc,0x9a,0x8d,0xeb,0x0f,0xb5,0xa9,0x8e,0xa5,0x2c,0x99 +.byte 0x94,0x8d,0x21,0xa9,0x41,0x6b,0x11,0x2e,0x02,0x21,0xd8,0xc1,0xbc,0xf0,0x2a,0x87,0xae,0x35,0xa9,0x78,0x5c,0x43,0xb8,0xb7,0x63,0x2d,0x09,0x31,0xae,0x6f,0xfc,0x39,0x7b,0x18,0xc3,0xce,0xe3,0xfa,0x51,0x70,0xc7,0x6b,0x5e,0xc3,0xce,0xc8,0xa2,0x3a,0x66,0x9e,0xfe,0x45,0xb4,0xa2,0xaf,0x81,0x03,0x74,0xbf,0x0c,0x65,0x4c,0x30,0x27 +.byte 0xd5,0x34,0x29,0x2d,0x83,0xa8,0xb9,0x1d,0xf8,0x12,0x09,0x51,0xdd,0x0e,0x66,0x95,0xf3,0x94,0xaa,0x83,0x3a,0x6f,0x8a,0x7c,0x3a,0x29,0x82,0xbb,0x80,0xa1,0x37,0x8c,0x79,0xf4,0x4a,0xa8,0xe4,0x17,0x72,0x77,0xee,0xc4,0xaa,0x25,0xd3,0x8f,0x2e,0xaf,0xb9,0xb2,0x3c,0xa6,0xd5,0x72,0x97,0x07,0x23,0x38,0xae,0x9e,0x22,0x08,0x85,0x70 +.byte 0xfa,0xff,0x38,0xe6,0x96,0x9f,0x2c,0x11,0x14,0x16,0x9a,0xfa,0x5a,0x7b,0x05,0x31,0x3e,0x20,0xbf,0x4d,0x87,0xaa,0xba,0x94,0xcd,0xdb,0xeb,0xec,0x29,0x58,0x4e,0x43,0x12,0xe8,0xf9,0x01,0x50,0xc8,0x51,0x7a,0x61,0x12,0xe9,0xed,0xc2,0xd6,0x2e,0xd3,0xed,0x54,0x72,0xf7,0x1b,0x0c,0x8c,0xb4,0x65,0xea,0x22,0x31,0x22,0xeb,0xcd,0x53 +.byte 0x66,0xf1,0xa5,0x34,0xe9,0x81,0x74,0xcb,0xb5,0x6b,0x45,0x71,0x69,0x6d,0x84,0xe8,0xc6,0x86,0xc9,0xdd,0x0c,0xa4,0x30,0x12,0x08,0x42,0x10,0x6b,0xcd,0x65,0x6c,0xfd,0x9c,0xde,0x77,0x3c,0x32,0x09,0xef,0x99,0x27,0x0e,0x4a,0x72,0x03,0x8d,0xb5,0x68,0xa0,0x67,0xf7,0xc2,0xae,0xb8,0xce,0x41,0x70,0x4e,0xdd,0x13,0xcb,0x3f,0x05,0x4e +.byte 0xf4,0xbc,0x88,0x98,0x2f,0x42,0x4e,0x5f,0x3e,0xcb,0x2c,0xd3,0x2f,0xb8,0x92,0xbb,0xd8,0x95,0xc8,0xaf,0xa9,0x44,0x8b,0xf0,0x2f,0x81,0xd4,0xe7,0x06,0x19,0xf7,0xa7,0x0a,0x73,0x3e,0x30,0xd9,0x00,0xe4,0x2d,0x76,0xb1,0x0d,0xfa,0x12,0x1f,0xbe,0x59,0x4f,0xf7,0xc8,0x5b,0xab,0xd7,0x16,0x3d,0x7e,0x97,0x9e,0xec,0xf8,0xcb,0x31,0x2e +.byte 0xe0,0x41,0x0b,0x00,0xa6,0x6d,0xe9,0x5e,0xd5,0x4a,0xc5,0xbf,0x1c,0xcc,0xa5,0x71,0x94,0x29,0x3d,0x17,0x43,0x27,0x63,0xc4,0xc7,0x8f,0x1b,0xb7,0x5f,0xcf,0xdf,0x8e,0x6a,0x69,0x87,0xc1,0x29,0xab,0x7b,0x8d,0xdf,0x07,0x95,0x50,0xa3,0x1c,0x8e,0xdc,0x7f,0x8a,0x21,0x37,0x1e,0x26,0xa7,0x67,0x28,0xb2,0xc8,0x23,0x5a,0x1d,0x94,0x46 +.byte 0x1b,0x3e,0x72,0x87,0x73,0x08,0xe2,0x3b,0x46,0x51,0xbe,0x5b,0xa9,0x72,0xb9,0xf8,0x45,0x6d,0x0c,0x89,0x80,0x0d,0x7a,0xfb,0x4c,0x3f,0x7f,0x3d,0x29,0xff,0xef,0xb2,0xec,0x23,0xc2,0x26,0xcf,0x8c,0x2e,0x28,0xbf,0xc5,0x68,0x47,0xd9,0x49,0x95,0xf1,0x67,0x7e,0x3a,0x48,0xe2,0x43,0x5c,0xc8,0x95,0x5b,0xb2,0xf3,0x22,0xc9,0x73,0x91 +.byte 0xb5,0x78,0x96,0x1b,0x9a,0x75,0x5f,0xb2,0x6b,0x8c,0x66,0x8c,0x8e,0xc1,0xe1,0xde,0xd6,0x64,0x31,0xe1,0x7b,0x12,0xd2,0x85,0x8f,0x52,0x68,0xec,0x80,0x26,0x3d,0xcc,0x9b,0xe3,0x57,0xbe,0x19,0x42,0xb9,0xdd,0x7d,0x2b,0x5b,0x6d,0x1b,0x9e,0x96,0xd7,0x75,0x83,0x82,0x3c,0x3e,0x5f,0xf8,0xa9,0x36,0xbe,0x14,0xc7,0xce,0x9d,0x05,0x7e +.byte 0xd7,0x38,0x37,0x35,0xc9,0x37,0x8b,0x9f,0xc6,0x2d,0xff,0x00,0x41,0xff,0x1b,0x09,0xea,0xd2,0xb0,0x04,0x48,0xff,0xfc,0xb5,0x67,0x54,0x39,0x3d,0x23,0x68,0x0b,0x7d,0x97,0xf3,0x65,0x20,0xa2,0xf8,0x33,0x96,0xd1,0xf4,0xc7,0xba,0x6f,0x00,0x95,0x36,0xf6,0x33,0xd1,0x8d,0xde,0xee,0x1e,0xfa,0x60,0x8e,0x5e,0x4c,0x70,0xbb,0x53,0x79 +.byte 0xc9,0x9a,0xdf,0x3c,0x53,0xe4,0x35,0x87,0xc3,0xe6,0x8e,0x0e,0x1a,0xd0,0xf8,0x57,0x2b,0x33,0x51,0x4d,0x7d,0x43,0x17,0x3e,0x6f,0x0e,0xca,0x86,0xb2,0xc6,0x09,0xf3,0x2f,0xc1,0x5f,0x0e,0x9a,0x5e,0x7d,0x9d,0xf7,0xff,0x09,0x46,0xe5,0x30,0x91,0x61,0x93,0xb5,0x2f,0xc5,0x7f,0x09,0x0b,0x55,0x94,0x17,0x25,0x19,0x9b,0xa9,0x0e,0x68 +.byte 0x71,0x18,0x1b,0x4b,0x1b,0xa3,0x75,0x90,0x56,0x96,0x5e,0x33,0x71,0xf2,0x06,0x69,0x07,0x04,0xcb,0x8c,0x79,0x9b,0xa5,0x17,0xd8,0xd8,0x77,0xc7,0xca,0x95,0x58,0x12,0xec,0xdd,0x41,0xc9,0x12,0x16,0x9a,0xc4,0xf0,0x27,0x7a,0x8e,0xeb,0x19,0x79,0x27,0x7b,0x2e,0x55,0x96,0x57,0x19,0xbe,0x55,0x8c,0x7f,0x97,0x90,0x80,0x40,0x5d,0x5a +.byte 0xf6,0x07,0xd6,0xb4,0xc5,0xe8,0x0e,0x54,0xde,0x78,0x23,0xca,0x39,0x90,0x42,0xb6,0x8b,0x14,0x22,0x06,0x71,0x77,0xd5,0xf7,0x8d,0x05,0x9d,0xbf,0xfe,0x38,0x91,0xba,0x79,0x85,0x30,0x47,0x25,0xf0,0xa2,0x72,0x55,0x94,0x2a,0x8a,0xc8,0x28,0xc8,0xa9,0x23,0xab,0xf0,0x4e,0x49,0x2f,0x58,0x53,0x35,0xd1,0xb6,0x16,0x81,0xc2,0x25,0x18 +.byte 0xd9,0x71,0x91,0xc4,0x81,0x3e,0xf4,0xd7,0x87,0x9e,0x57,0x78,0xf7,0x7d,0x4b,0xb2,0xfd,0x91,0x9f,0xa8,0x0e,0x77,0xb3,0xc7,0xe5,0x6a,0x95,0x17,0xc3,0xf4,0xcb,0x7f,0x96,0xc1,0xa8,0xee,0x6a,0x0f,0x1f,0x5d,0x20,0x28,0x93,0xe5,0xf3,0x13,0x46,0x53,0x47,0x9f,0x98,0xc6,0xf5,0x29,0x69,0xb9,0x83,0x36,0x03,0xa1,0x9a,0xb4,0xa9,0x4e +.byte 0xd6,0xda,0x25,0xe2,0x5b,0xbb,0x95,0xdf,0x0f,0x37,0x0b,0x02,0x51,0x03,0xd1,0x0e,0x84,0xef,0xdd,0x85,0xdd,0xae,0x10,0x32,0x65,0x03,0x65,0xf0,0x8e,0x0c,0x69,0x90,0x35,0x26,0x36,0xe8,0x05,0x46,0xe6,0xce,0x52,0x4d,0xb5,0x93,0x9f,0xe3,0xe5,0xb0,0x43,0x57,0x32,0x5d,0xca,0xd4,0xc9,0x89,0x2e,0x5b,0x03,0x8a,0x82,0x78,0x21,0x6b +.byte 0x41,0xa9,0x0a,0x9f,0xe0,0x50,0xec,0x72,0x01,0x67,0xe7,0x1c,0x92,0xe3,0xe4,0x83,0x4d,0x4b,0xcf,0x01,0x37,0x2f,0x34,0x86,0xcf,0x36,0xf7,0x3a,0x57,0xa3,0x89,0x73,0x0f,0x9c,0x06,0x82,0x75,0x7a,0x4b,0xd8,0x44,0x40,0xf2,0xc5,0xc4,0x22,0xa6,0x99,0x1b,0x73,0x2f,0xad,0x09,0xe9,0x84,0x6f,0xc3,0xca,0x72,0x3a,0x8a,0x55,0x55,0x0a +.byte 0xcd,0x33,0x51,0xef,0x5b,0x36,0x77,0x6c,0xb4,0x4a,0xae,0xdd,0xbd,0xec,0x65,0x99,0x43,0xd6,0x8a,0x16,0xba,0x89,0x4d,0x0c,0x11,0xb4,0x0d,0x5d,0x3e,0x76,0xcb,0x48,0x9d,0x31,0x40,0x71,0xe2,0xe4,0xa9,0xd9,0x6e,0x3c,0x3d,0xd1,0x6e,0xaf,0xb9,0x28,0x71,0x5a,0x07,0x6f,0xab,0xdb,0xf8,0x4f,0x11,0xbc,0xe0,0x14,0x01,0x43,0x4d,0xe2 +.byte 0xad,0x5d,0x2a,0xb2,0x58,0x66,0x05,0x50,0x66,0xf6,0x2f,0x66,0x11,0xd1,0xd7,0x05,0x85,0xb0,0x7f,0xa8,0x89,0xbd,0x41,0xda,0x35,0x1e,0xbb,0xff,0x70,0x1a,0xe8,0x65,0x96,0xe9,0x50,0x18,0x7f,0x4c,0xb2,0xe2,0x95,0x26,0xf6,0x37,0x09,0x8c,0x8d,0x7b,0x02,0xb0,0x7f,0x32,0xb5,0x70,0x22,0xd6,0x83,0x0b,0x85,0x25,0x00,0xc5,0x55,0x3f +.byte 0xfa,0x7a,0xc9,0xaf,0x87,0xc1,0x1c,0x11,0x96,0x71,0x18,0xd8,0xdb,0xab,0x86,0x57,0x0a,0x16,0x23,0x32,0x40,0xd3,0xaf,0x17,0x55,0xe3,0xe7,0x01,0x65,0x1f,0x87,0xda,0xb5,0x46,0x67,0x18,0x34,0xcc,0x28,0x77,0xc3,0x12,0x62,0x6c,0x8b,0x8a,0x11,0x7a,0x5a,0xd1,0xdf,0xb3,0x13,0x6b,0x29,0xce,0xf8,0x03,0xba,0xad,0x7c,0x14,0x60,0x42 +.byte 0x17,0xf6,0x7b,0x0c,0xb7,0x5f,0xd6,0xc1,0xb5,0xa5,0x2b,0xb1,0x9f,0x6c,0x65,0x29,0xe5,0xf4,0x84,0x85,0x11,0x82,0xf1,0x4c,0xcd,0xff,0x99,0x29,0x53,0x7b,0x43,0x04,0x60,0xc4,0x6c,0x01,0x5c,0xcb,0x33,0x4f,0xdb,0xc4,0xad,0x8c,0xea,0xff,0xd6,0xcd,0x8e,0x85,0x6e,0x54,0xd5,0x18,0x63,0x84,0x78,0xea,0xff,0x08,0x95,0xdc,0x2a,0x07 +.byte 0xac,0xea,0x44,0x79,0x52,0x07,0xf3,0xf1,0x03,0x7f,0x71,0x53,0xd8,0x85,0xdb,0x70,0xde,0x5e,0xd5,0x9a,0x18,0x9f,0xcc,0x3f,0xc0,0xc0,0x49,0x82,0x70,0x09,0xce,0x29,0x04,0x0a,0x19,0x81,0xd9,0x81,0x22,0x71,0x48,0x8e,0x79,0x08,0x1c,0xb4,0xc8,0x7e,0x60,0x43,0x4a,0xe3,0xd5,0x6b,0x09,0x5c,0x01,0x6e,0x20,0x9e,0xd2,0xaf,0x80,0xb7 +.byte 0xa2,0x0a,0x5b,0x26,0x08,0x32,0x73,0xbc,0xc6,0xfd,0x06,0xaa,0x2e,0x55,0xa0,0x5b,0xa9,0x3c,0x85,0xb2,0x04,0xdc,0x9a,0x94,0x02,0x93,0x96,0x6b,0x3e,0xc3,0x5e,0x37,0x9b,0x6f,0xef,0xb9,0x65,0x52,0x42,0x1c,0xa7,0x84,0x09,0x0c,0x49,0x3a,0x95,0x06,0x94,0xd7,0xc7,0x40,0xf5,0xf1,0x69,0x41,0xfb,0xf8,0x57,0xb5,0x1e,0x0c,0xf3,0xd9 +.byte 0xb1,0x2e,0x58,0x33,0xbe,0xb1,0x3d,0x61,0xc6,0xca,0x01,0xe5,0xda,0x60,0x8f,0x87,0xf7,0x9a,0xb5,0x92,0xb4,0x8c,0x2a,0xaf,0xd4,0x1e,0x9c,0x97,0x39,0x83,0x99,0x4a,0x07,0x54,0x75,0x7d,0xde,0x72,0x06,0xc1,0x8f,0xb4,0xde,0x12,0x43,0xf2,0x62,0xae,0xe7,0xec,0xfe,0xb2,0xe5,0x63,0x35,0xb7,0xee,0xaa,0xf0,0x09,0xb8,0x61,0xf2,0x42 +.byte 0x28,0x87,0xd7,0x47,0xa8,0xfc,0x51,0x85,0x6f,0xa2,0xb1,0xa6,0x82,0xd6,0x0e,0x1b,0x3f,0xea,0xa1,0xe1,0x91,0xc9,0xd2,0x5b,0x3e,0xff,0x18,0x39,0x14,0xe0,0x44,0xda,0x3d,0xd8,0xca,0xdb,0xd9,0xbf,0x3f,0xa4,0xdb,0x99,0x2e,0x31,0x32,0x7c,0xf4,0x61,0x2f,0xa1,0xf9,0xa9,0xbe,0x26,0x94,0xea,0xb4,0xe3,0x25,0x8d,0x93,0x3b,0xa1,0x7e +.byte 0x1e,0x99,0x87,0x6c,0xaf,0x14,0x54,0xd0,0xc0,0x37,0x39,0x76,0x3c,0x07,0x2e,0xce,0x98,0x25,0x81,0xe4,0x01,0x0c,0x07,0x79,0x4e,0xcd,0x82,0x44,0x83,0x04,0x07,0xa6,0x52,0xb7,0x96,0x7c,0x43,0x12,0xe1,0xc5,0x12,0x18,0x25,0x47,0xe4,0x19,0x6d,0x26,0x1e,0x55,0x66,0xca,0x28,0x4c,0xfa,0xd2,0xd9,0xcc,0x7e,0xad,0x9f,0x2a,0x2f,0xc6 +.byte 0x6c,0x77,0xaa,0x0f,0x5b,0xeb,0x15,0x97,0x62,0x52,0x3c,0x6f,0x4b,0xf3,0xcc,0x80,0x7b,0x1f,0x1d,0x58,0xf8,0xfe,0xc1,0x8c,0x3b,0xe3,0xd7,0x05,0xc3,0xd6,0xa9,0xda,0xcf,0x85,0x1c,0x68,0xd6,0x6d,0x2b,0x06,0x30,0x5f,0x58,0x39,0xea,0xfa,0x99,0xaa,0x04,0x10,0x05,0xaf,0xb0,0xf7,0x32,0x60,0x8d,0xe4,0xd1,0x40,0x32,0xd6,0xa3,0xf2 +.byte 0xba,0x5a,0x79,0x58,0x92,0x75,0xf0,0x3a,0xce,0xb2,0xee,0x66,0x3e,0xe3,0xbe,0x4d,0x53,0x9d,0xbb,0xdb,0x45,0xf0,0x09,0xeb,0xd5,0x83,0x39,0x20,0x06,0xa9,0x44,0x35,0xeb,0x6d,0x9b,0xd9,0xa4,0xda,0x4b,0x9d,0xde,0x3d,0x26,0xa2,0x2d,0xcf,0x8e,0x3e,0xbc,0xb4,0x8c,0x3a,0xbf,0x56,0x7c,0x48,0x50,0xb5,0xc5,0xbe,0x84,0x5e,0x63,0x82 +.byte 0x5f,0x87,0x77,0x4a,0xa7,0xf6,0x66,0x07,0x42,0x6a,0xb0,0xcf,0x19,0xaf,0x6c,0x16,0x85,0x78,0x88,0x3b,0xa5,0xbc,0x42,0xd2,0x4c,0xdf,0x51,0x3b,0xc4,0x0e,0xf5,0xc5,0x70,0x57,0x40,0xf6,0xed,0xd2,0x37,0x3e,0x14,0x0c,0x31,0xda,0x94,0x87,0x6b,0xd9,0x8c,0x15,0x41,0xa9,0xc0,0x2a,0x61,0xd3,0x52,0xe0,0xb6,0x0a,0x83,0x6b,0x75,0x1b +.byte 0x1e,0xd1,0x7f,0x26,0x19,0x34,0x9b,0x70,0xc9,0xba,0xdc,0xa2,0x03,0x6d,0xc7,0xac,0xbd,0x2c,0x63,0x8a,0x7b,0xb1,0x62,0x51,0xc1,0x1d,0x54,0x0d,0x34,0x0e,0xfb,0xa6,0xb8,0x9d,0x79,0x4f,0xc3,0xaa,0x8d,0xa0,0xcc,0x80,0x96,0x86,0x37,0xd6,0x80,0x9c,0x3d,0x91,0xd0,0xe7,0xe2,0xb4,0x00,0xba,0x86,0xe9,0xeb,0x86,0xea,0x84,0x78,0x81 +.byte 0x20,0x29,0x28,0x02,0x4d,0xd8,0x1b,0x5e,0x4f,0x41,0xfc,0x13,0x3e,0x4c,0x7f,0x64,0x55,0x35,0x41,0x0d,0x74,0xc5,0x6a,0x7c,0x37,0x82,0x41,0xbd,0x67,0x39,0xd9,0x83,0xfa,0x7f,0x8c,0xe1,0x9f,0x23,0x0d,0xe4,0x1d,0x40,0xe6,0x6e,0x94,0x5d,0xec,0x77,0xf7,0x5e,0xb4,0xa1,0x03,0xfb,0xa0,0x0e,0xba,0xf8,0x28,0x50,0x3c,0x38,0x47,0xf7 +.byte 0xed,0x2d,0xe5,0x0b,0xa8,0x7a,0xbd,0xbf,0x7e,0x38,0xc0,0x60,0xe7,0x7e,0xb1,0x03,0xef,0x4a,0x8c,0xc7,0x98,0xf1,0x94,0xf6,0xa0,0x50,0xb2,0x0b,0x7c,0x66,0x0a,0x62,0x10,0x24,0xb0,0xa1,0x69,0x02,0x33,0x79,0xbf,0xd0,0xb5,0xcb,0x17,0x20,0x55,0x02,0x70,0x44,0x5b,0xac,0x20,0x35,0xea,0x05,0x2d,0x68,0x51,0xe7,0x5f,0x1b,0xcd,0x4c +.byte 0x33,0x4d,0x04,0x21,0xfd,0x06,0x67,0x82,0x60,0x98,0x1f,0x79,0xf4,0x28,0xe0,0xa8,0x18,0xeb,0xf5,0x86,0x58,0xe6,0x9f,0xb5,0x29,0x0f,0xe8,0x37,0xeb,0x09,0xf4,0xc6,0x08,0xf2,0xde,0x4d,0x96,0x48,0x62,0x36,0x63,0x10,0x3f,0x63,0xeb,0x44,0x84,0xc8,0xf5,0x74,0x19,0x03,0x50,0xf7,0x7c,0xd2,0x06,0x20,0x6e,0x9b,0xa2,0x37,0xb0,0x68 +.byte 0x78,0x31,0xb6,0x05,0xfa,0xc9,0xcd,0x1d,0x4c,0xbd,0x33,0xb7,0xf3,0x93,0x38,0x7d,0x5f,0x00,0x85,0x5b,0x10,0x7f,0xc4,0x3f,0x3e,0xfe,0x62,0xca,0x51,0x83,0x95,0xcf,0x00,0x65,0x83,0x0e,0xd3,0x78,0xd0,0x51,0xcb,0x70,0x34,0x42,0xc6,0x3a,0x04,0xb9,0x10,0x92,0xe0,0x09,0x06,0xb0,0x66,0x9b,0x37,0x02,0x8d,0x0d,0x3e,0x2f,0xc5,0x17 +.byte 0x6a,0x87,0x7d,0x48,0xa4,0xcc,0x55,0x20,0x7b,0x77,0x07,0xcf,0x44,0x2f,0x88,0x8a,0xcc,0xf2,0x5d,0xa6,0x3e,0x5f,0xda,0xe2,0xde,0xd2,0x7f,0x7f,0xb7,0x90,0x53,0x64,0x6b,0x79,0x42,0x52,0x69,0xc6,0xd6,0xaa,0x9f,0xf9,0x19,0xbe,0x65,0x10,0x99,0x49,0xaf,0x36,0x49,0x1b,0x8a,0x3d,0x7f,0xdb,0xa2,0x1a,0xb5,0xd6,0x34,0x51,0xc8,0xc8 +.byte 0x06,0xca,0xf6,0xb8,0x76,0xa8,0x9d,0x43,0xae,0xf0,0x51,0xe5,0x9a,0x42,0xa2,0x83,0xed,0x20,0x8d,0xe8,0x1c,0xca,0x15,0x4e,0x37,0x3f,0xd8,0x06,0xa0,0xe1,0xf8,0x05,0xfd,0x42,0xf3,0x7a,0x96,0x44,0x36,0x02,0xca,0x11,0x2a,0xc3,0x24,0x58,0xdd,0x85,0x55,0xb2,0xe5,0x1d,0x92,0xc2,0x2d,0x5f,0x7c,0xb5,0x02,0x37,0x7c,0x07,0x35,0x25 +.byte 0x2b,0x33,0x80,0xe2,0xd4,0xfd,0xc7,0xa7,0x19,0x7e,0xba,0x36,0xaf,0xa0,0x4e,0xab,0x8b,0x28,0x4f,0x3b,0x92,0x72,0x42,0x49,0xaa,0x3b,0x08,0x0f,0x1e,0xff,0x2d,0xbf,0x9c,0x48,0x16,0x72,0xbe,0x28,0x05,0x8b,0x3a,0x20,0x6b,0x38,0x43,0xa2,0x35,0xea,0xf7,0x4e,0x50,0xa0,0x43,0x40,0x5c,0xbf,0xe5,0x75,0x13,0x4c,0x36,0x61,0xa1,0x5d +.byte 0x46,0xd7,0x7a,0x94,0x06,0x2f,0x63,0x32,0x9c,0x6e,0x54,0x18,0x31,0x79,0xf2,0x83,0xcf,0xb4,0x47,0x40,0xe5,0x9a,0xd6,0x99,0x12,0xb3,0x61,0x3d,0x0f,0x5e,0xc8,0x95,0xa3,0x5f,0xc3,0xd5,0x6b,0x6e,0xa0,0xf2,0x2f,0xeb,0x66,0xd0,0x68,0x67,0x10,0x85,0x64,0x27,0xd8,0xb8,0x68,0x00,0x36,0xa5,0xab,0x3e,0xe1,0x43,0x65,0x81,0x2d,0xb9 +.byte 0x0f,0x87,0xfe,0xa1,0x52,0xe9,0x8d,0x82,0x3a,0xd1,0x10,0x52,0x34,0x48,0x7c,0x1c,0xc6,0xd0,0xfe,0xa0,0x1a,0x92,0x07,0x88,0x57,0x9e,0xd7,0x5e,0x9f,0xc8,0xb0,0x93,0x73,0x03,0x28,0x36,0x8c,0x25,0x8c,0x0f,0x4e,0x0f,0x5b,0x26,0x58,0xed,0x5c,0x33,0x75,0x20,0x08,0x11,0x47,0xe1,0x47,0x85,0x47,0xeb,0x54,0xbf,0x58,0xe3,0xd4,0x5b +.byte 0xf9,0xc6,0x5e,0x42,0x58,0xe6,0xaf,0x79,0x66,0x3c,0xa5,0xa3,0x30,0x33,0xe3,0xbe,0x21,0x4b,0x42,0x98,0x6e,0x44,0xd7,0x68,0xc0,0xff,0xbe,0x7f,0xc5,0xb3,0x4f,0x4a,0x93,0xb0,0x11,0x88,0xcf,0x36,0xb2,0x03,0xbe,0x30,0x52,0x71,0x20,0x0d,0x16,0xc5,0xbb,0xf5,0x92,0x12,0x67,0x6a,0x35,0x66,0x00,0x09,0xd7,0xc6,0x67,0xb0,0x6a,0x04 +.byte 0x19,0x3e,0xbf,0xe2,0x82,0x74,0x78,0x2f,0x77,0x44,0xdc,0xad,0x0f,0x66,0x2a,0x23,0x62,0x2c,0x5a,0x4e,0x3a,0x82,0x2a,0x75,0x16,0x0d,0x74,0x64,0x35,0x53,0xc5,0xf6,0xda,0x36,0x44,0xba,0xe2,0xfa,0x1e,0xc2,0xcf,0x29,0x01,0x36,0x66,0xc3,0xca,0x40,0xf7,0xc4,0xba,0x67,0xac,0xf6,0x17,0xcc,0xa3,0x96,0x2d,0x08,0x5f,0x0a,0xea,0x5e +.byte 0x97,0xdc,0xc8,0xf9,0x59,0x24,0x6e,0xc5,0x0b,0x02,0xb9,0x1a,0xde,0xac,0x60,0x1d,0xaf,0x9f,0x5a,0x6f,0xe1,0xa6,0xdf,0x75,0xc5,0x9b,0xb7,0xde,0xa4,0xf7,0xf6,0xa4,0xdc,0xb6,0x96,0x08,0xde,0x2a,0x0e,0xb3,0x9d,0xf5,0x75,0x7d,0x7e,0x96,0x91,0x79,0xd4,0xa7,0x30,0x97,0x3a,0xbd,0x7c,0xe0,0xc5,0x87,0x24,0xb0,0x65,0xb7,0x58,0x00 +.byte 0xd9,0x0e,0x97,0xa6,0xa4,0x6a,0xe8,0x0a,0xac,0xac,0x9f,0x3a,0xe3,0x2a,0x9a,0x43,0x41,0x92,0x6e,0x0e,0xc4,0x63,0xc3,0x18,0xb6,0xe1,0xef,0x3d,0xe8,0x0b,0xb0,0x9f,0x2e,0x19,0xa0,0x98,0x98,0x34,0xf8,0x86,0x6d,0xc5,0x8c,0x41,0x26,0xb7,0xf2,0x1d,0xd4,0x72,0x39,0xeb,0x79,0x06,0xaf,0x53,0xaa,0x34,0x80,0x53,0xf8,0x1b,0xf4,0x53 +.byte 0x19,0xfa,0x16,0x8b,0x39,0xea,0x63,0x7f,0x38,0xc4,0x66,0x1d,0xd1,0x90,0xe4,0x2f,0x20,0x43,0x0d,0x5f,0x98,0xcc,0xae,0xef,0x86,0xc8,0xe5,0xf6,0xd2,0xa5,0x49,0xd0,0x3f,0xb5,0x7e,0x42,0xb5,0x6e,0x5e,0x13,0xa5,0xb4,0x71,0x2c,0x5d,0x57,0x24,0x06,0xd2,0x29,0x7c,0x4c,0x90,0xb6,0xea,0xdb,0x62,0xa4,0x2c,0x6c,0x38,0x57,0x97,0xbd +.byte 0xfd,0x41,0x6e,0x26,0xc1,0xe1,0x6b,0xbb,0xf0,0xe7,0x71,0xf1,0xcf,0x6a,0x7f,0xfa,0xe7,0xfb,0x17,0xe7,0x81,0x19,0x9a,0xf2,0xf6,0x86,0x22,0x4f,0x62,0x59,0xd6,0xc2,0x33,0xbd,0x11,0xe7,0x07,0x3a,0xfe,0x74,0x0d,0xf8,0xd9,0xdb,0xbd,0x05,0xf4,0xf4,0xb1,0x41,0xc9,0xb3,0xf8,0x6a,0x7b,0x98,0x08,0x6c,0xce,0x4c,0x28,0xbf,0x8c,0x77 +.byte 0x68,0xdc,0xee,0xf7,0x11,0xde,0xfc,0x5a,0x58,0x4f,0xf4,0x74,0x9d,0x5b,0x78,0xc3,0x78,0xe5,0x5e,0x26,0x83,0x40,0x17,0x80,0x2a,0x02,0xa4,0xf1,0x0f,0xa0,0xc8,0x22,0xe6,0x09,0x3a,0x52,0x74,0xf0,0xb9,0xb9,0x60,0xaf,0x20,0xa6,0x7e,0x88,0xf4,0xc2,0x38,0xa2,0x21,0x73,0xa9,0x18,0x3f,0x7a,0x04,0x7b,0xc4,0xcd,0x68,0xd9,0x83,0xa4 +.byte 0x8e,0x54,0x0d,0xbc,0xee,0x8b,0x39,0x93,0x66,0xa2,0xd6,0x76,0x4a,0xb2,0x33,0x4f,0x61,0x53,0xde,0x3b,0xff,0x47,0xcb,0x87,0xd9,0x21,0xd0,0x82,0x64,0x54,0xdf,0xf2,0x67,0x62,0x40,0x33,0xc7,0x0d,0xea,0x98,0xaa,0x95,0xfb,0xa9,0x0e,0x90,0xa5,0xd9,0x54,0x81,0x86,0xad,0x9e,0xa4,0x4d,0x36,0xe1,0x77,0xf2,0xe3,0x0a,0x54,0x1a,0x57 +.byte 0x9d,0x62,0x5e,0x0e,0x00,0xc8,0xa6,0x1e,0xf3,0x43,0xe6,0x20,0x0d,0x6a,0x8e,0x90,0x1d,0x4d,0xac,0x2f,0x9f,0x1c,0xb7,0x30,0xec,0x5c,0x99,0x78,0x6f,0x3b,0xe7,0xe0,0x28,0xb9,0x97,0xc5,0x6a,0xf2,0x17,0xc2,0x11,0xac,0x1a,0xe2,0xca,0x57,0x49,0x64,0xc8,0xc7,0x66,0x43,0x8d,0xc8,0xa7,0x0e,0xfc,0xcf,0x05,0x2f,0xae,0x4b,0xfe,0xe4 +.byte 0xbe,0x9c,0xe7,0xe6,0xa8,0x36,0x49,0x0d,0x9c,0x60,0x39,0x0c,0xfd,0x41,0x5b,0xc7,0xa4,0xa5,0x30,0x89,0xe5,0x10,0xf6,0xea,0xf8,0x2c,0xf2,0x3e,0xb1,0x96,0x81,0xa7,0x32,0x8b,0x39,0x14,0x15,0x36,0xfc,0x55,0x3c,0x22,0xcf,0xa3,0x98,0x90,0x68,0x13,0xd8,0x3f,0xf2,0x53,0x19,0x3e,0x9a,0x0c,0x1f,0xc6,0x29,0x43,0x46,0x23,0x58,0xea +.byte 0x49,0x49,0x15,0x46,0x8e,0x63,0x30,0x1f,0x3e,0x2a,0xa0,0x18,0xfd,0x28,0xc5,0x32,0x77,0x75,0xac,0x6e,0x5d,0x39,0xa9,0x44,0xce,0xfe,0x39,0xa6,0xec,0xde,0x69,0xde,0xfa,0xc8,0x40,0x44,0x34,0x29,0x15,0x19,0xa7,0xbe,0xd6,0x5b,0xfd,0x1f,0x7b,0xb9,0x88,0xf1,0x14,0xcf,0x42,0xc5,0xa7,0xa7,0x0e,0x6b,0x6e,0x86,0xb2,0x7c,0x23,0x8e +.byte 0xf6,0xae,0xde,0x3c,0xd7,0x26,0x5e,0xde,0x31,0x94,0xc1,0x19,0x65,0x55,0x03,0x73,0xba,0xdc,0x69,0x95,0x9c,0x9d,0x8e,0x59,0xd8,0x51,0x61,0x9f,0x8f,0xf4,0x29,0x43,0x4b,0x6a,0x75,0xb3,0x4b,0x9d,0xcc,0x46,0xd2,0x6e,0x00,0x49,0x4f,0xf0,0xac,0x80,0x55,0xc0,0x0c,0xbf,0x18,0x52,0x75,0x76,0x3b,0xac,0x92,0x83,0x69,0x1b,0xb4,0x15 +.byte 0xe5,0x9e,0xde,0x10,0x30,0x30,0x0e,0x85,0xc7,0xf9,0xae,0xbc,0x9e,0xaf,0x4b,0xee,0x27,0x6b,0xa5,0x6d,0xe4,0x8e,0xed,0xdd,0x95,0xaa,0x85,0xe2,0xf5,0x38,0x15,0x50,0xd3,0xcd,0x2c,0x88,0x6c,0x2b,0x14,0x37,0x74,0x2d,0x6d,0x30,0xec,0x96,0x78,0xae,0x80,0xb3,0xd9,0x84,0xc1,0xd6,0x71,0x90,0xe4,0x8d,0x3a,0x7c,0x9c,0xc4,0xf5,0xa0 +.byte 0x20,0x7e,0xa2,0x0e,0x75,0x7c,0x25,0x7a,0x7e,0x2b,0x2e,0xdb,0x12,0x23,0x73,0x6a,0x8e,0xe3,0xd7,0x47,0x94,0xfb,0xcc,0xe4,0x5a,0x8c,0xfb,0xdc,0x46,0xb3,0x4a,0x42,0x15,0xe0,0xaf,0x6e,0x81,0x72,0x72,0x04,0x52,0x09,0xc5,0x8b,0x6e,0xdd,0x7d,0xff,0x27,0xa8,0xc1,0x94,0xb5,0x33,0x59,0xc2,0x7d,0x59,0x6c,0x3c,0xaa,0xd9,0xd8,0x05 +.byte 0x43,0x7e,0x8a,0x47,0xdd,0x76,0x36,0xe3,0x05,0x49,0xd1,0x8f,0xdf,0x45,0x46,0x63,0xff,0x17,0xb4,0x52,0xc8,0xee,0x4d,0xf5,0x74,0x65,0xc6,0xca,0x19,0xfd,0xb9,0x51,0xc8,0xc9,0x96,0xd4,0x06,0xd4,0x09,0x1e,0xab,0x6d,0x1b,0x26,0x61,0x80,0x5b,0xa8,0xcb,0x62,0x92,0x5a,0x1a,0x8e,0xa4,0xb7,0x25,0x19,0x96,0x63,0xd5,0xc3,0xc9,0xdc +.byte 0x04,0x83,0x62,0x31,0xe3,0x76,0x00,0x4d,0xf8,0xb3,0x98,0xae,0x4d,0x1a,0x38,0xe3,0xa1,0x27,0x52,0x87,0xbe,0x2c,0x93,0x45,0xd1,0xab,0x56,0xc6,0xf5,0xbc,0xb5,0xe6,0x9c,0xe1,0x1b,0x37,0x42,0x08,0xe7,0x71,0xb5,0xa4,0x67,0xf9,0x48,0xd4,0xc4,0x10,0x25,0x53,0x9c,0x03,0xfc,0x6d,0x5e,0x62,0x5e,0x6d,0x56,0xbc,0x78,0x11,0x0a,0x6d +.byte 0x1b,0x7a,0xdc,0x62,0xb5,0x58,0x86,0x15,0x71,0xff,0x11,0x33,0x94,0x2b,0xa6,0xc7,0x68,0xd5,0x68,0xda,0x5b,0xd5,0xb7,0x38,0x6c,0x1c,0xf4,0x07,0x39,0xef,0x1f,0x72,0x0a,0xb3,0x12,0x13,0x25,0x86,0xd3,0xf8,0x9f,0xb5,0x40,0x58,0xe7,0x5e,0x9f,0xa0,0xbc,0xd7,0xab,0x4f,0xf3,0x94,0xcf,0x0f,0x5a,0x4c,0x98,0xb4,0x70,0x35,0x62,0xee +.byte 0x33,0x24,0x72,0x31,0xd4,0x06,0xd9,0xb4,0x1c,0x1e,0x0f,0xa7,0x48,0xc7,0x75,0x45,0x40,0x02,0xd0,0x60,0x32,0x29,0x4d,0x61,0x7a,0xee,0x65,0x35,0x2b,0xe5,0x50,0xac,0x82,0xdb,0xf7,0x9c,0x8f,0x82,0xe4,0xf0,0xbd,0xdb,0x00,0x3d,0x3a,0x3d,0xa2,0xc3,0x2d,0x0e,0x51,0x20,0xdb,0xdb,0x8d,0x15,0x03,0xbd,0xcb,0xcb,0x24,0x81,0xc5,0xdb +.byte 0x05,0x39,0x48,0xb8,0x3c,0x93,0x35,0x10,0xef,0x19,0xba,0x09,0x9e,0xff,0xf9,0x3f,0x0c,0xdc,0x96,0x98,0x32,0x26,0x76,0xe7,0xfa,0xaa,0xdf,0xdc,0xb9,0x15,0x44,0x42,0x9a,0x8c,0x6c,0x88,0xea,0x43,0x63,0xb5,0x79,0xb6,0x50,0x30,0x78,0xea,0x70,0xba,0x33,0x36,0x8f,0x8c,0xe5,0x78,0xfd,0xbc,0xc0,0xbd,0xde,0x3a,0x3d,0xe6,0xe6,0x57 +.byte 0x0f,0x29,0xf2,0x82,0x05,0xf2,0x5c,0xfd,0x33,0xc1,0xb2,0x2e,0xc2,0xc0,0x42,0xa2,0xc8,0xa5,0xf9,0x70,0x05,0xff,0x7b,0x8d,0xb9,0x68,0xc3,0xf6,0x74,0x00,0xcd,0x9d,0x70,0xfa,0x62,0x34,0xe5,0x05,0xe8,0x5f,0x53,0x9b,0x69,0x01,0x86,0xb9,0x1d,0x68,0x80,0x89,0x51,0x52,0x0d,0xe8,0x28,0xa1,0xdd,0x62,0x2b,0xf3,0x53,0x74,0xaa,0x98 +.byte 0xdb,0x7e,0x74,0x44,0xeb,0x25,0xe7,0xde,0xc4,0x29,0x14,0x11,0x7b,0xc6,0xef,0x14,0xe4,0x04,0xd0,0xf4,0x11,0xca,0xdc,0xdc,0xe6,0x3f,0x9a,0xc9,0xe2,0x0e,0x67,0x30,0x78,0x65,0x94,0x5a,0xa1,0x24,0xd6,0x90,0x2f,0x1c,0x13,0x46,0xf5,0xb5,0xf9,0x74,0x56,0x3e,0xd5,0x1b,0x09,0xb3,0x04,0xbe,0x89,0x00,0xbd,0xe0,0xba,0x13,0x05,0xd1 +.byte 0x98,0xa7,0x93,0x09,0xc5,0x96,0x46,0xb5,0x5a,0x05,0xac,0x1e,0x66,0x03,0xf0,0xaa,0x3d,0xc2,0x54,0xa3,0xc4,0x2b,0x0d,0xa3,0xe4,0x92,0xd6,0xd0,0x44,0xa6,0x37,0x30,0xa5,0xac,0xc2,0xc8,0x58,0x2a,0x2c,0x18,0x68,0x8d,0x9b,0x4f,0x99,0xd0,0x55,0x41,0xf4,0x84,0x3c,0x69,0xda,0x3c,0x6d,0x43,0xb3,0x85,0x15,0x1f,0xdb,0x58,0x0b,0x71 +.byte 0x33,0x24,0xbb,0x21,0x43,0x19,0x16,0xeb,0x83,0xde,0xe5,0xb7,0x68,0x9e,0xb9,0xd9,0xf6,0x2e,0xae,0xdd,0x88,0x2c,0x18,0xd7,0xc3,0x72,0x8b,0xbe,0xaf,0x8d,0xfd,0xcd,0x2f,0x8e,0x3e,0x2b,0xa4,0x20,0x11,0x9d,0x00,0x4f,0xea,0xf0,0xaa,0x2d,0xf3,0x9d,0xfd,0x11,0x7b,0xac,0x2c,0x66,0x74,0x03,0xe5,0xcc,0x70,0x9f,0xfb,0xb7,0x5a,0x16 +.byte 0xc3,0x05,0x61,0x7c,0x8c,0x73,0xcc,0x9c,0x6a,0x2f,0xee,0xae,0x85,0xc9,0x51,0x91,0x13,0xa4,0x09,0x82,0x4d,0x62,0x09,0x24,0x25,0x35,0x1f,0x82,0x88,0xbb,0xdd,0x16,0x5e,0x8d,0x98,0x5f,0x07,0x49,0x32,0x96,0xb7,0xee,0x85,0xb0,0x7b,0xfd,0xf5,0x35,0x4b,0xa9,0xd4,0xee,0xf2,0x37,0xd1,0xfe,0x62,0xf5,0x52,0x13,0xb4,0xb2,0xce,0xc4 +.byte 0xe0,0x09,0x78,0x48,0xd5,0xc6,0x5d,0x36,0x1b,0x90,0x3a,0x6a,0x3c,0x21,0x50,0xf0,0x0a,0xe9,0x46,0x24,0x45,0xc1,0x5e,0x76,0xa3,0xf9,0x70,0xb8,0x62,0x4d,0x0e,0x92,0x87,0x4a,0x6a,0xf9,0x46,0x91,0x64,0xfe,0x7f,0x53,0x24,0x7e,0xc7,0x3e,0xb0,0x37,0x1a,0xc8,0xd6,0x33,0x0b,0x5f,0xa5,0x30,0x03,0x0e,0x85,0x3d,0x7b,0xc1,0xa1,0x18 +.byte 0xb3,0x8c,0xfe,0xca,0x3e,0x71,0xd8,0x92,0x46,0x49,0x60,0x54,0xd9,0x7b,0xf7,0xc3,0x99,0x2f,0xb5,0x79,0xcc,0x32,0x40,0x7d,0x3d,0x0b,0xc6,0x6f,0x04,0xd9,0xf1,0xdd,0x64,0xf5,0xc4,0x60,0x14,0x04,0x5c,0x3a,0xa4,0xda,0xdc,0xad,0x8f,0xc2,0x44,0x37,0x96,0x63,0x00,0xf7,0xb1,0xc0,0x7c,0x8c,0x12,0xb5,0x3a,0xec,0xc0,0x16,0xd8,0x24 +.byte 0xe9,0xc0,0xc4,0xfa,0xb1,0x85,0x5b,0xe3,0x62,0x24,0xa1,0x75,0x92,0x82,0x04,0x59,0x10,0x50,0x4b,0x51,0x51,0x3e,0x39,0xba,0x6d,0xa0,0x65,0x2d,0xfc,0x23,0x1c,0x9d,0x69,0x22,0xe7,0x15,0xfa,0xba,0x76,0xbf,0x53,0x62,0xb0,0x0d,0x0d,0x5d,0x55,0x00,0xbc,0x58,0x01,0xed,0x37,0x53,0xb9,0xa6,0x0d,0x71,0xab,0xec,0x42,0xbf,0x3b,0x52 +.byte 0xfd,0xae,0xe9,0x6d,0x65,0x07,0xf3,0xd9,0x32,0x66,0xc1,0x66,0x1a,0x18,0x73,0x86,0x01,0xaf,0x1d,0xd1,0xd0,0xcf,0xb1,0xea,0x54,0x23,0xdf,0xf2,0x4d,0x7d,0xc7,0xfe,0xfe,0x7d,0x1d,0x2c,0x1b,0xb6,0xa7,0x7a,0x9e,0x90,0x3a,0x3b,0xb0,0x6c,0xb0,0xd2,0xd1,0xd0,0x6a,0x94,0x4c,0x84,0x1c,0x45,0xae,0xda,0x16,0xa9,0x2e,0x63,0x19,0x26 +.byte 0xf6,0x74,0xd3,0x6f,0x9b,0x9c,0x0c,0xb8,0x85,0x9f,0xeb,0x99,0xbc,0xab,0xff,0xc3,0x75,0x86,0xe5,0x3a,0xa0,0xf9,0xfc,0x6b,0x3d,0x5a,0xad,0x46,0x7f,0x17,0x0e,0x94,0xb7,0xa4,0x43,0x61,0x54,0x76,0x29,0x78,0xe4,0x41,0x91,0xbe,0xa5,0x36,0x39,0xdf,0xdc,0xcc,0x8e,0x42,0x40,0x08,0x51,0x26,0xb0,0x53,0x5d,0xb4,0x7a,0x18,0x8e,0xb3 +.byte 0xae,0xf2,0xe0,0xef,0x63,0x51,0x3a,0xbe,0x4c,0x2d,0xce,0xc7,0xe2,0x1b,0xc2,0x40,0xf3,0x82,0x61,0xf0,0x1b,0x05,0xdd,0x1e,0xae,0xed,0x87,0x2c,0xe5,0xad,0xc7,0xec,0xb5,0x63,0xf7,0x3a,0xf9,0xb7,0xd8,0x4e,0xa7,0xef,0xac,0x6d,0x9c,0x27,0xd9,0xcc,0x66,0xf4,0x75,0x40,0x94,0x8b,0x78,0x4f,0x61,0x4f,0x31,0x49,0x5c,0x96,0x72,0x58 +.byte 0xcf,0x55,0xb2,0x66,0x16,0x29,0x27,0x24,0x39,0xc3,0x64,0xb1,0xdf,0x69,0x87,0x85,0x46,0xe3,0xd0,0x82,0x53,0x1a,0xc2,0xf1,0x3a,0xab,0xdf,0xe5,0x29,0x17,0xdd,0xfe,0xbf,0xf9,0x3d,0x7a,0xfb,0xe7,0x74,0x49,0xa9,0xef,0x61,0x93,0x4c,0xfa,0x30,0xea,0x65,0xa7,0x61,0x32,0x88,0x74,0x12,0xc1,0x91,0xf1,0xc2,0x1f,0x38,0x6a,0xfd,0x0d +.byte 0xc8,0x6f,0x87,0xe6,0x15,0x55,0x26,0x13,0x86,0x13,0xb9,0x01,0x98,0x34,0x1c,0x2d,0x1d,0x30,0xae,0x7d,0x8e,0x07,0x7d,0x4d,0xe9,0xfd,0x58,0x18,0xc3,0xa6,0x8e,0x87,0x98,0x33,0xcc,0x80,0xd7,0x70,0x07,0x6a,0x4a,0x97,0xef,0x56,0xf3,0x9d,0xf9,0xef,0x6f,0xa8,0x71,0x7f,0x61,0x07,0x1d,0x9d,0x51,0x06,0x86,0x4a,0x35,0x9e,0xab,0x2c +.byte 0x66,0x8d,0x61,0x62,0xbd,0xed,0x6c,0x76,0x7c,0x67,0xe0,0xe1,0x6e,0x90,0x74,0xb1,0xa6,0x26,0x0d,0x01,0x1f,0xe9,0xb4,0x30,0x9a,0x7e,0x37,0xd1,0xea,0x97,0x9a,0x0f,0x9e,0x8d,0x52,0xd4,0x96,0x36,0x5b,0x6f,0x40,0xbb,0x9e,0x44,0xb4,0x6e,0xee,0x15,0x70,0xef,0x66,0x81,0xf5,0xb4,0xe7,0x69,0xb0,0x40,0x44,0xdc,0x70,0x1e,0x4d,0x3c +.byte 0x9b,0x19,0x2a,0x97,0xbd,0xb2,0xd2,0x9b,0x98,0xac,0x36,0xf1,0x05,0x48,0xdc,0x5d,0x21,0xfb,0x17,0xe3,0x9c,0x3c,0xbf,0xfd,0x1d,0x39,0x1e,0x5b,0x2a,0xa2,0xb3,0x7d,0x4f,0xdf,0x3a,0x41,0x7a,0x31,0x01,0xc2,0xe5,0xd0,0x06,0x50,0x29,0x05,0xce,0xb8,0x28,0xb7,0xdd,0x83,0xc8,0xaa,0x39,0x78,0xc7,0x7d,0x9e,0xcd,0x9a,0x07,0x71,0x7e +.byte 0x20,0x92,0x82,0xce,0x49,0x90,0xce,0xef,0x53,0xa7,0x48,0x2a,0x69,0x86,0xa1,0x5e,0x35,0xe8,0x7d,0x10,0xb8,0x5e,0xa6,0x9a,0x69,0x6f,0x32,0x75,0xf3,0x4a,0xee,0x9c,0x06,0x5c,0xdd,0x84,0x7e,0x38,0x00,0x67,0x39,0x42,0xed,0x72,0xda,0xe3,0x6b,0x5a,0xf4,0xc9,0x80,0x3e,0x0e,0xda,0x39,0xfa,0x83,0x2c,0x60,0x69,0x87,0x85,0x05,0xfc +.byte 0xf4,0x2b,0xd4,0x0a,0xad,0x86,0xca,0xd5,0xf0,0x92,0x1f,0x43,0x3c,0x0e,0xac,0x99,0xf3,0x67,0xa3,0x41,0x6d,0xb9,0x29,0x70,0x57,0x62,0x9f,0x45,0x91,0x72,0xe5,0x53,0xcc,0x89,0x80,0x3f,0xbc,0x1c,0x66,0x21,0xdd,0x90,0x2b,0xa4,0xca,0x2f,0xf0,0x0f,0x9f,0xd0,0xe9,0x28,0xe2,0xd9,0x36,0xaf,0xf9,0x01,0x81,0xce,0xb4,0xe7,0x71,0xfd +.byte 0x92,0xf8,0x56,0x2e,0xc3,0xc8,0x8b,0x54,0xc8,0xc7,0x40,0x79,0x27,0x06,0x18,0x4a,0x7b,0x88,0x3f,0xd6,0x4f,0xd4,0x66,0x1e,0x1f,0x9a,0x14,0x1a,0x0a,0x98,0xc7,0xd6,0x25,0x83,0x37,0x8a,0x5d,0xb2,0x88,0x39,0x68,0x7b,0x1f,0x4e,0x0a,0xed,0x11,0x1a,0x77,0x9b,0xcb,0xb6,0x7d,0x5c,0x36,0xac,0x07,0x07,0x9f,0x05,0xcf,0x90,0x8f,0x3f +.byte 0x4b,0xc5,0xf9,0x42,0x90,0xb4,0x42,0x26,0xa1,0x2c,0x66,0xc6,0xb8,0x98,0x80,0x8a,0xbb,0x9b,0x41,0xe4,0x44,0x8c,0x5e,0x56,0x33,0xe3,0xba,0xcf,0x31,0x8e,0x28,0xd7,0xc5,0xd1,0x3b,0x68,0x47,0x10,0xae,0xda,0xc3,0xbd,0x20,0xe7,0xac,0xe2,0xe1,0xe0,0x7a,0x4b,0x83,0xb1,0xab,0x72,0xf4,0xc4,0xe7,0x0d,0x02,0xaf,0x5b,0x74,0xac,0xda +.byte 0x9d,0xce,0x26,0x1f,0x79,0x05,0x67,0x7e,0xc4,0x98,0x3f,0xde,0xa6,0xf3,0xfe,0x59,0x65,0x88,0xfb,0x14,0x3a,0x43,0x91,0x04,0x1a,0x78,0x7e,0x08,0xba,0x55,0x50,0xc7,0x65,0xd3,0x8e,0xda,0x0a,0xee,0x8e,0x11,0xa9,0xf6,0x9e,0xd3,0x23,0x97,0x05,0x0c,0x98,0x2a,0x36,0x25,0xec,0x5e,0x0b,0xf9,0x31,0x80,0x00,0x8a,0x70,0xf1,0xaa,0x7c +.byte 0x73,0x02,0x98,0x8d,0x42,0x27,0x53,0xf1,0x83,0x37,0xd0,0x2d,0xfa,0xc7,0x4b,0xa5,0xb3,0xc9,0xb8,0xd4,0x56,0x94,0x5a,0x17,0x2e,0x9d,0x1b,0x46,0xaa,0xb6,0xd9,0x2a,0x3a,0x6c,0xaf,0x24,0x59,0xfd,0x08,0xc5,0xca,0x0c,0x79,0x3f,0xe7,0x91,0x8d,0x9d,0x59,0x91,0xd8,0x5f,0xda,0x6d,0x35,0x7b,0x52,0x47,0x35,0xf9,0x81,0x86,0x2c,0xee +.byte 0x1a,0x14,0xc5,0x1f,0xb6,0x85,0xb5,0x74,0xe9,0xb7,0x4f,0xde,0xcd,0x93,0x2d,0xf3,0x10,0xbe,0x34,0xfa,0xca,0x15,0x9f,0x02,0x9d,0x19,0x72,0x7c,0xd6,0xfd,0x81,0x43,0x49,0xb5,0x2b,0x52,0x31,0xd6,0x2c,0x28,0x2e,0x83,0x6d,0xd3,0x0f,0x6e,0x03,0x65,0xf0,0x8a,0xdd,0x0a,0xec,0x58,0x10,0x45,0x5d,0xac,0xda,0xf5,0x32,0x5d,0x18,0x26 +.byte 0xcc,0x2e,0xcf,0xd3,0x41,0x2d,0x1d,0xba,0xdf,0xd8,0x96,0x8f,0x18,0x0f,0xa7,0xec,0x8e,0x6e,0x84,0x2c,0xd6,0x1f,0x4e,0x76,0xfe,0xf3,0x14,0x27,0x4b,0x5b,0x3d,0x7c,0x1c,0x59,0x46,0x97,0x1b,0x59,0x5a,0x2d,0x57,0x80,0x17,0x98,0x7d,0x92,0x5d,0x2f,0x98,0x53,0x10,0x59,0x8e,0x7f,0x55,0x64,0x15,0x62,0x2c,0x16,0x0b,0x8d,0x48,0x54 +.byte 0xaf,0x96,0x17,0xa9,0x8e,0x2c,0xcf,0x41,0x8c,0x8a,0x37,0x55,0xe4,0xf9,0x20,0x3b,0x21,0x5c,0x86,0x8d,0x3f,0xa6,0x5e,0x43,0xf3,0x3b,0xf7,0x7c,0x27,0x88,0x8e,0xa5,0x15,0xca,0x0e,0x9e,0x85,0x30,0x17,0x0d,0xcf,0xf0,0x82,0x87,0xd6,0xe8,0xd2,0xad,0xe9,0x4d,0x3f,0xc9,0x58,0x19,0xf9,0x99,0x4d,0xf9,0x6b,0x1b,0xd3,0xf9,0xdd,0x52 +.byte 0xd1,0x3c,0x64,0x46,0xfd,0x4f,0x2e,0x63,0x39,0xd8,0xe4,0xeb,0xfc,0x07,0xf1,0xa5,0xff,0x84,0xa8,0x92,0xfe,0xbc,0xc5,0x36,0x91,0x2b,0xec,0x2c,0xad,0xf0,0xac,0xc5,0xb0,0xad,0x8a,0x0d,0x6a,0xd9,0x29,0x7a,0xb0,0x87,0x0c,0xaf,0xda,0x75,0x84,0x25,0xbe,0xee,0x0d,0xfd,0x4c,0xf5,0x2d,0x46,0xe9,0x17,0xb9,0x9d,0x3d,0x4b,0x8f,0x3a +.byte 0xe9,0x49,0xb6,0x32,0x99,0x27,0xe2,0x4d,0xff,0x2f,0x2e,0xd5,0x69,0x52,0x56,0x20,0x0a,0xbf,0x62,0x14,0x34,0xfb,0xbf,0x95,0xe8,0xfe,0xb1,0x9f,0x43,0x30,0x02,0x03,0x9e,0xa8,0xe2,0x68,0x64,0xdd,0x37,0xfc,0xb9,0x0f,0x85,0x8c,0x36,0x45,0xdb,0x7c,0x8b,0x97,0x50,0xc3,0x75,0xa1,0xcf,0xf4,0xc2,0x46,0xd8,0xa1,0x8c,0xab,0x8d,0x3a +.byte 0xde,0xe7,0x9e,0xd2,0x1e,0x2d,0x8b,0xe4,0x31,0xe3,0x12,0x3f,0x9f,0x0b,0x2c,0x95,0x75,0x8d,0xf1,0x24,0xb9,0xdf,0x1e,0x64,0x35,0x45,0x2a,0xc2,0xf9,0x96,0x5d,0x10,0x64,0x32,0xae,0xe9,0xf8,0x71,0xd4,0x2d,0x6b,0xc6,0xde,0x08,0x1e,0x5d,0x51,0xf1,0xe7,0xfd,0x3c,0x22,0x43,0x59,0x82,0x83,0x13,0x75,0x36,0xef,0x81,0xe4,0xcf,0xa8 +.byte 0xb8,0x30,0x16,0x44,0xae,0x55,0x06,0xdd,0xb9,0x60,0x3f,0x75,0xc6,0xd1,0x73,0xa9,0xea,0xc9,0x64,0x2b,0x8a,0xde,0x44,0x4b,0x3d,0xc3,0x31,0x12,0x84,0x9a,0xe3,0xda,0x24,0x82,0x99,0x00,0x6d,0x8e,0xb8,0x26,0x82,0xa6,0xc2,0x37,0x6c,0x2a,0x1d,0xcf,0x6d,0x18,0xc7,0xee,0x27,0xca,0xe7,0xad,0x95,0xed,0x7d,0xe0,0xe0,0x6f,0x45,0xc3 +.byte 0x8a,0x2f,0x08,0x49,0x7e,0x09,0x9e,0xc1,0xb7,0x1e,0x8f,0x57,0x61,0xf8,0x3e,0xea,0xd7,0x47,0xfb,0xd0,0xda,0xaa,0x04,0xf9,0x06,0xbb,0xa3,0x80,0x68,0x89,0xb0,0x7f,0x18,0xf3,0xd2,0xeb,0xee,0x48,0x30,0x6a,0x24,0xc8,0x71,0x43,0xc3,0x50,0xcc,0x85,0x68,0xf5,0xca,0x44,0x34,0x43,0xaa,0x2e,0x4f,0x02,0x1b,0x23,0x4f,0xe9,0x07,0x02 +.byte 0xa2,0xfa,0x24,0x57,0x70,0x4e,0x1a,0x78,0x03,0xa2,0xdd,0x53,0x50,0x82,0x05,0xb1,0x0f,0xcb,0x9e,0x2e,0x58,0x04,0x62,0xc8,0xac,0x71,0x31,0x56,0x0f,0xc7,0x70,0x32,0x53,0xda,0x51,0xc3,0x15,0x78,0x82,0xb6,0xe8,0x6e,0x32,0xeb,0x39,0xab,0xba,0x67,0xcc,0xbc,0x99,0x58,0x88,0xc4,0x60,0x0d,0x0b,0xc1,0xfa,0x6f,0x40,0x85,0x04,0xdf +.byte 0x5f,0x17,0x69,0xf1,0xbd,0x44,0x97,0xc8,0x62,0x19,0x49,0x1f,0x23,0xcb,0x3d,0x17,0x04,0xf2,0xbd,0x58,0x15,0xa6,0x37,0x3a,0x3f,0x77,0x98,0x32,0x40,0x8a,0x72,0xf0,0x41,0x0b,0xad,0x88,0xba,0xd3,0xae,0xdc,0x3b,0x9a,0x37,0x89,0xa5,0x09,0xe5,0xbb,0xf2,0xf8,0x5d,0xa5,0xed,0xe8,0x39,0x7b,0xed,0x2b,0x90,0xd6,0x6c,0xd3,0xfa,0x69 +.byte 0xa7,0xca,0x09,0x83,0x15,0x8d,0xd8,0xe3,0x81,0x03,0x4e,0x2d,0xd8,0x96,0x3b,0x4b,0x18,0x91,0xac,0x5f,0x22,0xe6,0x9d,0x4b,0x09,0xaf,0xf0,0xdf,0x16,0xa2,0xf1,0x2c,0xd9,0x35,0x8a,0x6e,0x85,0x7a,0xbc,0xc7,0x10,0xd1,0x5f,0x8a,0x53,0x9c,0x8e,0xbc,0x8c,0x15,0xb3,0x8a,0xb0,0x0b,0x74,0x40,0x2a,0x5f,0x46,0x71,0x1c,0x0b,0xee,0x08 +.byte 0xae,0x17,0x26,0x1e,0xcf,0xbf,0x3d,0xa0,0x5e,0x3a,0xdb,0x39,0x6b,0x4a,0x82,0x53,0x02,0xf4,0xa2,0x15,0x5c,0xb6,0xdb,0x20,0x30,0xa2,0x7d,0xcb,0x9a,0xf7,0x88,0x69,0xb5,0xc8,0xe6,0xcd,0x9e,0xa4,0xaf,0x27,0x0e,0x61,0x41,0xcd,0x8e,0x71,0x83,0x11,0xce,0x5e,0x6c,0xaf,0xa4,0x50,0x81,0xb6,0xf2,0x36,0x05,0xbb,0x36,0x4e,0x4a,0x1b +.byte 0x09,0x9f,0xca,0x1b,0x12,0xb0,0x01,0xc0,0xbf,0x7e,0x3f,0x81,0x60,0x9f,0xfd,0x56,0x81,0x54,0x99,0x2b,0x7f,0x1e,0xb1,0xbf,0xd4,0xb7,0xe1,0x7c,0x71,0xf9,0x00,0x72,0x5f,0x10,0xab,0x60,0x03,0x9d,0x13,0xf1,0xba,0x48,0x93,0x1c,0x1d,0x11,0x04,0x40,0xf6,0xde,0x3b,0xef,0x6c,0x47,0xb3,0x0d,0xcf,0x53,0xbd,0x45,0x7e,0xd7,0x8c,0x34 +.byte 0xd0,0xcb,0x85,0x4b,0x1e,0xd1,0xc5,0xfd,0x5b,0x1a,0x18,0x8a,0x27,0xe3,0x16,0x3c,0x25,0x12,0xf2,0xf1,0xa1,0x40,0x53,0x68,0x27,0x2c,0x81,0x0e,0x20,0x12,0xe3,0xde,0xe2,0x9f,0x08,0x75,0xc0,0x25,0x79,0xf0,0xc4,0xaa,0x10,0xad,0x41,0x3f,0x0b,0xc7,0xb2,0xe0,0x50,0xde,0xec,0x24,0x09,0xeb,0xb5,0xd3,0xbc,0xd3,0xdf,0x44,0x6d,0xc8 +.byte 0xf1,0x79,0xf8,0x33,0xb7,0x75,0x09,0x18,0x04,0x59,0x0f,0x15,0x5e,0xf9,0xca,0xe0,0xa9,0x2a,0xe1,0x1b,0xf0,0x49,0x5f,0xca,0xa3,0x80,0xd5,0x9b,0x1e,0xc1,0x1f,0x98,0x18,0x0a,0x24,0xc3,0x3f,0xfb,0x43,0xfd,0xa3,0x01,0x59,0x50,0xea,0x21,0xe0,0x92,0xfd,0xe1,0xd5,0xe4,0x38,0x24,0x88,0xf3,0xb0,0xc9,0x79,0xfd,0x4e,0xd3,0x3e,0xbf +.byte 0xc6,0xb8,0x9e,0x7f,0xab,0x65,0x79,0xd9,0xb9,0x83,0x38,0xe1,0xf7,0xd0,0x37,0x04,0xb3,0x0c,0x48,0x82,0x74,0xe1,0x0c,0x80,0x13,0x59,0xc4,0x72,0xf9,0x2d,0x88,0x06,0x46,0x08,0x7a,0x6b,0xb4,0xfc,0x5f,0x63,0x31,0x2f,0x4f,0xfd,0x4b,0x1f,0x8e,0x21,0x3c,0x67,0x83,0xdd,0xa9,0x65,0x68,0xc6,0xd0,0xb8,0x1d,0xcd,0x60,0xc5,0xb9,0x3b +.byte 0xea,0xe9,0xc7,0xa5,0x1a,0x98,0x8a,0x87,0xb7,0x73,0x29,0x3a,0x6a,0x3a,0x75,0xbf,0xa4,0x79,0x64,0xcb,0x94,0x68,0x93,0x56,0x55,0x1e,0xd5,0x61,0xda,0x87,0xe1,0x28,0xf0,0xa5,0x64,0x9a,0xd7,0xa0,0x91,0xfd,0x46,0x20,0x6c,0x87,0x1f,0xe8,0x9e,0x7e,0x95,0xc4,0x60,0xdb,0xf4,0xe2,0x3e,0xb2,0x6a,0x4a,0xe7,0x46,0x3f,0xca,0xf3,0x72 +.byte 0xb5,0xe8,0x06,0x3a,0x1b,0xeb,0xcb,0x81,0x46,0x44,0xf6,0x97,0xa0,0x79,0xe4,0xa4,0x8a,0xba,0x5e,0x1b,0x6d,0xf4,0xcf,0x7c,0x12,0x7a,0xec,0xdd,0xf6,0xc8,0xab,0x5f,0x30,0xb3,0xf9,0x8e,0x31,0xfd,0x51,0x95,0x8b,0xa1,0xe9,0xe8,0x2d,0xec,0x86,0x12,0x4a,0xf8,0x8b,0xa5,0xdd,0xb2,0xe4,0xad,0xdd,0xcb,0xf5,0xcd,0x9c,0x9f,0x0a,0x42 +.byte 0x5f,0x83,0x9d,0xa6,0x4f,0xbe,0x11,0x75,0x3c,0xde,0x67,0x6b,0x95,0xcd,0xcf,0xdc,0xfd,0x1f,0x1a,0x14,0x01,0x27,0x68,0xaf,0x9b,0x82,0xd6,0xae,0x29,0x8a,0x1f,0xc8,0xf1,0x1f,0xb8,0xa9,0xa2,0x1d,0x81,0xbb,0x19,0xda,0x06,0xe3,0x34,0x7b,0xce,0x99,0x3c,0x5b,0x0c,0x9b,0x8b,0x35,0xc0,0x6c,0x88,0xef,0xeb,0x9f,0x64,0xe3,0xc3,0xbf +.byte 0x37,0xd7,0xf6,0xdf,0xad,0x28,0xf4,0xd7,0x19,0xb0,0xf2,0xa7,0xd4,0x71,0xbc,0xd3,0xa3,0x09,0x5c,0x1a,0x45,0x30,0x2d,0x53,0xa5,0x19,0x2f,0xb0,0x5d,0xae,0x04,0x28,0xe6,0x16,0x3e,0x75,0x9f,0xcc,0x76,0xc4,0xc2,0xa0,0xfb,0xff,0xdd,0x4c,0xa3,0x8b,0xad,0x05,0x73,0x26,0xf0,0xef,0x48,0xd5,0x25,0x22,0x90,0x78,0x21,0xfd,0xc6,0x23 +.byte 0x14,0xbc,0xed,0x13,0x29,0x76,0x17,0xa6,0x93,0x09,0x6e,0xa7,0x42,0xdd,0x11,0x9e,0x05,0xa3,0xb7,0x48,0x84,0x85,0xf8,0x4e,0xed,0x3d,0xdb,0xfc,0x68,0xd2,0xec,0xec,0x69,0x2b,0x60,0x38,0xd1,0x99,0x44,0xf9,0x60,0xd3,0x5a,0x9e,0xe4,0x26,0x9d,0x12,0xf8,0x6a,0x53,0xde,0x76,0x78,0xa7,0x68,0xb0,0xb4,0xdc,0x33,0x7b,0x8a,0x73,0xa0 +.byte 0xa5,0x5f,0x8f,0x81,0x0e,0x51,0x06,0x13,0x6b,0x56,0x16,0x91,0x1f,0xf5,0x6b,0x68,0xe6,0x8b,0x69,0xda,0x0a,0x9c,0xb1,0x74,0x8f,0x1c,0xb3,0xbf,0x52,0x59,0xaa,0xb1,0xb6,0x3a,0x81,0xc2,0x04,0x54,0x12,0x46,0xa2,0xd5,0x21,0xdf,0xe0,0x57,0x1f,0xe8,0x36,0x56,0x87,0xbf,0xcb,0x7d,0x06,0x6c,0xd5,0xc9,0x4e,0xca,0x47,0x47,0x11,0x91 +.byte 0x7a,0x14,0x13,0x5d,0x5d,0x46,0xd5,0x3a,0xe4,0xa4,0x4d,0x99,0x3a,0x54,0x99,0x62,0xb4,0x70,0xa0,0xf5,0x8a,0xda,0x05,0x75,0xf1,0xa5,0xa1,0x5d,0x9d,0xc4,0x7f,0x83,0x8a,0x5b,0x09,0x54,0x0e,0x69,0x28,0xef,0x66,0xfb,0xe4,0xc4,0xe4,0xc4,0xda,0xb0,0xda,0xe2,0x19,0x33,0x3c,0x76,0xa0,0x35,0xdc,0x31,0x4e,0x40,0xfe,0xb8,0x20,0x26 +.byte 0x8f,0x6f,0x7d,0x02,0x54,0x86,0x1d,0xca,0xa6,0x10,0xa6,0x89,0x87,0x3a,0x5a,0xd5,0x3d,0x0f,0xb5,0x81,0x7d,0xab,0xb6,0xc6,0x36,0x87,0xce,0xd7,0xe4,0xc3,0x9e,0xc2,0x9c,0xf6,0x75,0xd5,0x9a,0x69,0xd2,0x13,0x89,0x5a,0xe9,0x29,0xc9,0xf5,0x6e,0xcc,0x05,0x87,0x0a,0x61,0x49,0xd7,0xa5,0x76,0xd0,0xaf,0x96,0xe0,0x2f,0x91,0xf4,0x45 +.byte 0x70,0x5a,0xdc,0x9f,0x07,0x7f,0x86,0x02,0xa4,0x83,0x8d,0x4a,0x6d,0xfc,0x1b,0xd8,0x9b,0xc2,0x42,0x4f,0xcb,0xdf,0xcb,0xe0,0x55,0xb4,0x8f,0xf7,0x27,0x73,0xd9,0x7e,0xf8,0x3a,0x5c,0x4f,0x29,0x64,0xd8,0x39,0xfa,0xf2,0xc4,0x6b,0xeb,0x55,0xc3,0x13,0x22,0x15,0xdf,0xc5,0x91,0x6d,0xd7,0xf3,0x11,0x34,0x08,0xce,0xe5,0xbd,0x16,0x14 +.byte 0x60,0x14,0x8a,0xed,0x4d,0x38,0x98,0x15,0x5d,0xee,0x70,0xff,0x05,0xd2,0x74,0x3a,0x5f,0x78,0x1a,0x70,0x61,0x2a,0x42,0x4a,0xf3,0x15,0x6f,0x9e,0x33,0xca,0xb8,0x46,0x22,0x64,0xd6,0x24,0xe8,0x10,0x1a,0x89,0xab,0x74,0xdf,0x56,0x35,0x41,0x57,0xe1,0xd9,0x4b,0x67,0x60,0x89,0x6f,0xbf,0x73,0xac,0x6b,0xf9,0x78,0x3f,0xbc,0xf3,0x2a +.byte 0xb5,0x8c,0x1f,0xda,0xe7,0xe2,0xac,0x60,0xbf,0x41,0x96,0xbb,0xd5,0x35,0x9c,0x56,0xe7,0xfd,0x95,0xc7,0x4d,0x32,0xa1,0x07,0x34,0xbc,0x99,0xca,0xcc,0x42,0x71,0xfb,0xec,0x5c,0x1e,0xf9,0x8b,0xde,0x43,0x65,0x84,0x16,0x52,0x0a,0x5e,0x92,0x20,0xd8,0x26,0x4b,0x97,0x71,0xde,0xd2,0x1f,0x2e,0xd1,0xb2,0xb6,0x29,0x6a,0x6d,0x41,0x00 +.byte 0x20,0x3d,0x03,0xf8,0x43,0x7b,0x57,0x87,0x4e,0xf1,0x8e,0x6f,0xd3,0xf4,0x6c,0x6c,0x29,0xf6,0x99,0xe3,0xd3,0x1d,0xd3,0x26,0x21,0x3b,0x02,0xa2,0xc1,0x06,0xcf,0x31,0xec,0x7f,0xc6,0x80,0xbc,0xab,0x86,0x01,0xff,0x11,0x8a,0x24,0xfd,0x1b,0x41,0x49,0xd4,0xbe,0x15,0x34,0x82,0xc5,0x02,0x51,0x67,0x5c,0x41,0x8e,0xbf,0x94,0x12,0x15 +.byte 0x64,0xea,0x00,0x0c,0x51,0x40,0x57,0x66,0x1e,0x6d,0x3e,0x41,0x8e,0x84,0xdf,0x71,0xb8,0xd7,0xfa,0x12,0x17,0x22,0x17,0x05,0xdc,0x82,0xfd,0x7c,0x5e,0xfa,0x62,0x23,0xa8,0xbe,0x14,0xdc,0x84,0x42,0xf0,0x90,0xc5,0xb0,0x68,0xbe,0x64,0x74,0xc3,0xa5,0xd1,0x10,0xcf,0xe3,0xd1,0x09,0x98,0x3b,0xb9,0x19,0xf2,0x9b,0x5d,0x90,0x99,0x3d +.byte 0x30,0x67,0x55,0x34,0x50,0x78,0x3b,0xd2,0x70,0xb1,0xd2,0x91,0x4e,0xfa,0x98,0x7d,0x93,0xad,0x7f,0xb1,0x89,0xb0,0x61,0x4c,0x95,0x3f,0x51,0x95,0xd7,0xc6,0x87,0x7a,0xc5,0x53,0xb6,0x6d,0x61,0xec,0xbe,0x40,0x1f,0xa5,0x7f,0x73,0x4a,0x78,0xd2,0x58,0x1e,0x41,0x8e,0x9a,0x08,0x49,0xce,0x39,0x52,0xf9,0xd1,0xcd,0x41,0xb6,0x39,0x99 +.byte 0xfa,0xfb,0x1c,0x38,0xe1,0xe5,0xe1,0xd6,0x16,0x0f,0xc8,0x12,0x0b,0x88,0xdc,0x00,0xd4,0x7b,0x24,0x69,0x16,0x27,0x37,0xa3,0xd5,0x39,0x27,0x34,0xda,0x23,0x24,0x50,0x13,0xd8,0x02,0x48,0x14,0xd7,0xc9,0x28,0x1b,0xba,0x66,0xa8,0xc8,0x9a,0x7b,0xed,0x92,0x5b,0x78,0x46,0x79,0x5a,0xd1,0xf2,0x75,0xf0,0x98,0xd3,0x9f,0x4c,0x72,0x51 +.byte 0xed,0xe5,0xce,0x83,0xac,0xe1,0xc8,0x2b,0x7f,0x77,0x6a,0x70,0xdd,0x80,0x88,0x62,0x58,0x94,0x15,0x72,0x53,0x34,0x48,0x17,0xb2,0xe8,0x4a,0xab,0x2d,0x4e,0xef,0x93,0xb7,0xba,0xd1,0x1c,0x53,0x69,0xd5,0xac,0xa1,0x61,0x7c,0x44,0xec,0x81,0x72,0xcc,0xe8,0x6f,0x5d,0x67,0x1f,0x65,0x9a,0x34,0xf5,0x95,0x89,0x1c,0x2e,0x54,0x42,0xc0 +.byte 0x85,0x79,0xb0,0xfa,0x44,0x0d,0x28,0xc4,0x20,0x2f,0x2e,0x85,0x73,0xfb,0xf6,0x44,0x0e,0xbc,0xab,0x4f,0x42,0x5c,0xdb,0x1f,0x11,0x6f,0x9a,0x23,0x75,0x70,0x78,0x1a,0xd2,0xb8,0x83,0x72,0xf5,0xf6,0x40,0x48,0x3f,0xc8,0xd5,0xe3,0x2c,0x08,0x5c,0x0c,0x2a,0xb0,0x8e,0x69,0xe6,0xdf,0x4b,0x4a,0x95,0x9c,0x4c,0x5e,0x09,0x24,0xc3,0xd0 +.byte 0x4c,0x20,0x0c,0x9a,0xce,0x95,0x53,0x6a,0x7b,0x54,0x0a,0x7e,0x73,0xa7,0x95,0xe7,0x7c,0x67,0x9d,0x05,0xbc,0x26,0x3a,0xa1,0x43,0x99,0x7a,0xee,0x04,0xcf,0x94,0x02,0x36,0x26,0xb3,0x81,0x74,0x22,0xee,0x1e,0x9e,0xe2,0x82,0xd4,0xe0,0xca,0xf2,0xec,0xd2,0x9e,0xf8,0x3f,0x9f,0xc4,0x5b,0xe8,0xfc,0xbd,0x93,0xaa,0xc3,0x2f,0xce,0xf2 +.byte 0x32,0xa9,0x23,0xf3,0xe1,0x06,0xae,0x7d,0x87,0xe9,0xe7,0xe0,0xc1,0x7c,0x74,0x9c,0xdf,0x86,0x6d,0x5c,0x8a,0x51,0x45,0x9d,0x43,0x49,0x87,0x45,0x75,0xfb,0x40,0x55,0xab,0x9a,0x52,0xf1,0x32,0x5e,0xde,0x8b,0x52,0x50,0x9f,0xb8,0x7a,0xe5,0x1c,0x40,0x4f,0xc7,0xb1,0x29,0x90,0xcc,0x98,0x99,0xa0,0x4e,0x1c,0x43,0x6e,0x91,0x61,0x9c +.byte 0xf7,0xa7,0xf7,0x43,0x89,0x15,0x8c,0x56,0x22,0x9d,0x66,0xac,0x71,0x19,0xdc,0xb9,0xf8,0xd3,0xaf,0x2e,0xd7,0x7b,0xc3,0xe4,0x25,0x0d,0x2c,0xaf,0x15,0x8c,0xea,0x2b,0xdb,0x8c,0x71,0xff,0x55,0x29,0x11,0x35,0x11,0xef,0xb0,0x97,0xb2,0x95,0xab,0xeb,0x4a,0x40,0x1c,0x92,0xc4,0x13,0x36,0x74,0x53,0x78,0x51,0x6c,0xca,0x37,0xcb,0xda +.byte 0x5e,0x6b,0x8c,0x69,0xc5,0xd0,0xf9,0xdb,0xbe,0xd9,0x30,0x42,0x16,0xcf,0x40,0x63,0x87,0x10,0x28,0x7d,0xae,0xa9,0x8c,0x14,0x99,0xe1,0x4f,0x11,0x98,0x7e,0xe9,0x14,0x9c,0x2e,0xe2,0xed,0x20,0x15,0x7c,0xb5,0xf4,0xc9,0x16,0x30,0x8d,0x7c,0x61,0x45,0xf4,0x23,0xf5,0xdb,0x81,0x8f,0x6b,0x41,0xaf,0xa9,0xf8,0x51,0xbe,0xc4,0x5d,0x8c +.byte 0xda,0x5e,0x07,0x62,0x7c,0xc6,0xd1,0xae,0x91,0x5e,0x05,0xa8,0xc6,0xc5,0xfc,0xb7,0x12,0x2e,0x7f,0x85,0xef,0xbd,0x2b,0x56,0x57,0x32,0xad,0x3d,0x97,0x5b,0x26,0xcf,0xd3,0xe7,0x48,0x4e,0x9b,0x15,0x98,0x77,0xb4,0x3e,0xf1,0x3e,0x1c,0x21,0xb0,0x98,0xe2,0x69,0xee,0xd8,0x29,0x10,0x93,0xd5,0xc9,0x71,0x8f,0x28,0xbd,0xe3,0xd9,0x54 +.byte 0xf3,0x72,0xb6,0x85,0xe9,0x2b,0xdc,0x96,0x52,0x53,0x5c,0x61,0x54,0x96,0x4a,0xf5,0x3f,0xee,0x53,0xc3,0x63,0xc9,0x67,0x14,0xdf,0x3a,0xfe,0x46,0x8a,0xa6,0xec,0x06,0x0c,0xea,0xb8,0x82,0x49,0xb5,0xed,0x94,0xf2,0xac,0x76,0xd5,0x87,0x79,0x15,0x4f,0xa1,0x34,0x90,0x8e,0x7b,0x02,0xf7,0x02,0xb0,0x07,0xa5,0x7c,0x6b,0xc2,0x34,0x84 +.byte 0xd4,0xaa,0xbf,0x32,0x81,0xf7,0xed,0x1f,0x61,0xd7,0x6e,0x40,0xa0,0xdc,0x4c,0xb5,0xb7,0x36,0x3a,0x87,0x09,0x82,0xd5,0x5a,0xc8,0x1f,0xe6,0x77,0xa6,0xaa,0xcf,0x3c,0x7b,0x23,0x46,0x58,0x95,0x7f,0x84,0xba,0x4a,0x05,0x0b,0x36,0xdb,0x58,0xf9,0xa4,0x2b,0x24,0xd4,0x8a,0xbc,0xb2,0xb7,0x04,0xac,0x64,0x0e,0x88,0x25,0x9a,0x69,0xe7 +.byte 0x87,0x70,0x0b,0xa6,0x43,0xe9,0xb2,0xbb,0x4e,0x4c,0x10,0x19,0x44,0x4d,0x12,0x4c,0x58,0x2a,0x49,0xe2,0x01,0xd2,0x65,0x23,0xee,0xe9,0xca,0x0b,0xa1,0x28,0x02,0x8d,0xcf,0x37,0x06,0xbc,0x5d,0x35,0xba,0xec,0x97,0x95,0xcc,0xfe,0x7b,0xc9,0x1c,0x0d,0x89,0x4e,0xe1,0x8d,0x9b,0x5e,0x5b,0xb9,0x6c,0x24,0x73,0x9a,0x62,0xd7,0xc5,0xfa +.byte 0x54,0xeb,0x05,0x22,0xd9,0xe7,0xc4,0x68,0x88,0x20,0x43,0xd9,0x14,0x47,0xd7,0xa5,0xd0,0xce,0x10,0x77,0xe8,0x5c,0x85,0x39,0x99,0x3f,0x72,0x88,0x4f,0x22,0x15,0x87,0xa0,0xa3,0x47,0x10,0x81,0x64,0xff,0x94,0x77,0x5d,0xce,0x6d,0xd8,0x29,0xb1,0x9c,0x8e,0xce,0xa8,0x39,0x4f,0xfc,0x36,0x3c,0x50,0xb2,0xf1,0x08,0x66,0x1a,0xf0,0x22 +.byte 0x65,0x1f,0x4d,0x17,0xd3,0x63,0x10,0x64,0xd1,0xc6,0x5a,0x3e,0x82,0x72,0x0c,0x48,0x5e,0x07,0x9c,0x07,0xa0,0x40,0x60,0xab,0x74,0x9a,0x00,0xdf,0xd7,0x7d,0xd4,0x11,0x4e,0xce,0x5a,0xaf,0x12,0x4f,0xe7,0x12,0x36,0x1a,0x12,0x11,0x16,0xb7,0xad,0x4b,0x28,0x84,0x7b,0xd8,0x30,0x0d,0x85,0xb8,0x76,0xde,0xa3,0x78,0x8c,0xb7,0x7c,0xbc +.byte 0x97,0x33,0x53,0x95,0xf8,0x14,0x5f,0xf8,0x0d,0xc1,0x6b,0x79,0xa2,0x42,0x49,0xab,0xae,0x8e,0x78,0xf3,0x51,0x01,0xcc,0x20,0x36,0x80,0xbd,0x32,0x0b,0x1b,0xd2,0xcd,0x27,0x52,0x69,0x1b,0x4a,0x37,0xba,0x31,0xe4,0xc2,0x03,0x8d,0x00,0x48,0x4b,0xcd,0x39,0x2e,0xec,0x94,0x2e,0xe0,0x81,0xfd,0x94,0xd9,0x86,0x39,0x23,0x87,0x3c,0x2f +.byte 0x25,0xe1,0x5b,0x22,0xe0,0x2e,0x37,0x6d,0x9b,0x97,0x9c,0x94,0x37,0x01,0x26,0xb8,0xb1,0x73,0x7c,0xfc,0x0a,0x64,0xe7,0x54,0xf1,0x0f,0x71,0xa1,0xd6,0xc7,0xc8,0xb4,0x86,0x2d,0xfe,0x30,0x8b,0xca,0xb2,0x18,0x21,0xc0,0xc7,0x7d,0x60,0xcf,0x2e,0x25,0xb0,0xa4,0x1a,0x28,0x19,0xa9,0xa9,0x15,0x32,0x5e,0x21,0x89,0x3a,0x99,0x5f,0x50 +.byte 0x86,0x37,0x3b,0x10,0xb8,0xa5,0xad,0x8e,0xbf,0xfc,0x8c,0x85,0xf1,0x76,0x5c,0xe7,0x4d,0xac,0xe7,0x21,0xb3,0x45,0x87,0x3b,0x05,0xc8,0x41,0xf4,0x99,0x83,0x28,0x40,0x6b,0x30,0x37,0x31,0xd2,0xb3,0xdd,0x43,0x3b,0x3f,0xec,0x50,0x58,0x7d,0x20,0xc6,0xb2,0xa9,0x3c,0x22,0x38,0xea,0x16,0x32,0x01,0xc4,0xb0,0x9f,0x7d,0x12,0x91,0x82 +.byte 0x0c,0xd8,0x36,0xfc,0xa4,0xec,0x06,0xb2,0xc2,0xce,0x9b,0xa4,0x53,0x71,0x77,0xdd,0xc3,0xfc,0x34,0x6f,0xd9,0x5c,0xfc,0x36,0xdd,0x63,0x19,0x06,0xfb,0x3c,0xf3,0x3f,0x82,0x28,0x6d,0x00,0xf9,0xfd,0x8d,0x6b,0x79,0x06,0x8a,0xe7,0x6f,0xcc,0x39,0x12,0x80,0x71,0xcb,0x71,0xb3,0xb6,0xa4,0xa8,0xbe,0x61,0x9d,0x1f,0x48,0xa2,0x15,0xa1 +.byte 0xb5,0xf5,0x16,0x70,0xc5,0x39,0xce,0x43,0xa3,0x09,0xe5,0xf4,0x8b,0x77,0x18,0x5e,0xa0,0x77,0xa3,0xa4,0x17,0x2c,0x3e,0x50,0x73,0x2f,0xaa,0x5d,0x58,0x5e,0xdc,0xec,0xaf,0xca,0x6e,0x57,0x80,0xa3,0xd5,0x94,0x30,0x7c,0x11,0x75,0xc4,0xbb,0x9d,0x18,0xc1,0x5a,0x58,0xc7,0x04,0x56,0xb1,0x3a,0x21,0x55,0x02,0xea,0xad,0x58,0x19,0x72 +.byte 0xdc,0x7d,0x0e,0x41,0x62,0x1b,0x5c,0x48,0x97,0x3f,0xed,0xd7,0x4e,0x30,0x1f,0xf5,0xde,0xc5,0x23,0xf2,0xd7,0x22,0xde,0x2f,0x3e,0x80,0x06,0x81,0xf6,0x24,0xb7,0x91,0x09,0x56,0x91,0x00,0x1a,0xea,0xaa,0xa6,0xc2,0x8b,0xc9,0x78,0xd7,0xde,0xf6,0x87,0xb1,0x04,0xcc,0xbb,0xc1,0xc6,0x48,0x43,0xc8,0x03,0xb2,0xdd,0x70,0xc0,0xe3,0xf5 +.byte 0xc0,0xf5,0x13,0xd5,0x11,0x41,0x7f,0x1a,0xdc,0x48,0xf5,0xd6,0x1b,0x0a,0x84,0xd2,0x84,0xcd,0x10,0x4f,0x0a,0xd7,0xcb,0x41,0x61,0x1c,0xcc,0x5c,0xa9,0xbd,0x6e,0x6a,0xf3,0x81,0xd8,0xaa,0x3a,0xff,0x39,0x90,0x8e,0x33,0xe6,0x58,0x13,0x5f,0xec,0x58,0x74,0x35,0xe0,0x06,0x38,0x0f,0xd0,0xbf,0x8d,0xf7,0x26,0x99,0xea,0xdd,0xfb,0xdf +.byte 0x5b,0xcc,0xf1,0x3d,0x9b,0x84,0x8b,0x5b,0xe8,0xc4,0xc6,0x3e,0x0a,0x55,0xec,0x73,0xf7,0x70,0xb1,0xc8,0xfa,0xf8,0xd6,0x72,0x2c,0x6d,0x8d,0xc1,0xa3,0xb2,0x9a,0xe7,0x80,0x6d,0x09,0xa6,0x76,0x06,0x71,0xf9,0x95,0x9a,0xa9,0x2f,0x4b,0x7c,0xad,0x64,0x01,0x01,0x91,0xe4,0x87,0x1d,0xe1,0x46,0xf5,0x4a,0x96,0xc6,0x58,0xd9,0xe0,0xa9 +.byte 0x2f,0x80,0x1e,0xd6,0xe9,0xa6,0xeb,0xfe,0x5a,0xb6,0xd3,0xe8,0x76,0xd2,0x51,0xc6,0x68,0x34,0xc9,0xed,0x76,0x29,0x7e,0x63,0xb1,0x09,0xdf,0x23,0x47,0x41,0x2f,0x70,0x46,0x4d,0xbb,0x36,0xc8,0x84,0xe9,0x58,0x20,0x6b,0x04,0xb2,0xa4,0x1c,0x4d,0xe0,0xa5,0xa2,0x59,0xc9,0xed,0x63,0x25,0x5f,0x3f,0x24,0x18,0x59,0x29,0xe3,0x79,0xbd +.byte 0x35,0x50,0xee,0x81,0x59,0xff,0xd4,0x0e,0x62,0xd3,0x52,0x30,0x81,0xa2,0xe6,0x9e,0xc3,0xc9,0x7a,0x10,0x57,0x36,0x27,0xb7,0x3c,0x61,0x38,0x89,0x70,0xa0,0xc5,0xdf,0x78,0x05,0xa5,0x81,0xe2,0x8a,0x93,0xda,0x7c,0xaf,0xbf,0x6d,0x42,0x09,0x1b,0x43,0x9d,0xf9,0x26,0x87,0xc3,0x84,0x6c,0xb7,0x25,0x31,0x50,0x00,0xd8,0x13,0xc0,0xc0 +.byte 0x6c,0x21,0x82,0x6d,0xf9,0x2f,0xef,0x40,0xe8,0xf8,0xae,0x4d,0x9e,0x1d,0x4a,0xda,0xa0,0x0d,0x77,0x36,0x8b,0xed,0xaf,0x6e,0x2a,0x3d,0xa8,0x36,0xe4,0xff,0x37,0xc2,0xa3,0x11,0x5e,0x68,0x58,0xa8,0xa3,0x19,0xf3,0xc1,0x33,0xea,0x39,0x49,0xfe,0x51,0x87,0xb6,0x31,0x6a,0x61,0x47,0xe7,0xb1,0x46,0xde,0x5a,0xf7,0x93,0x06,0xa7,0x72 +.byte 0xa9,0x2e,0x9e,0x2e,0xc9,0x7f,0xe1,0xb2,0x86,0xb4,0xc9,0xff,0x3b,0xf7,0xaf,0xef,0x91,0x47,0xc2,0xfa,0x42,0x0a,0x4e,0xbb,0x10,0x0d,0xea,0xa4,0x11,0x54,0xa9,0x53,0xde,0xc4,0x01,0xde,0xc7,0x2d,0x1f,0x18,0x40,0x79,0xd1,0x44,0x7d,0x51,0x1d,0xf6,0xdc,0x6f,0xad,0xa2,0x5d,0xd9,0xbe,0x5d,0x11,0x57,0xb7,0x68,0x0d,0x96,0xad,0xb3 +.byte 0x32,0xf7,0x99,0xcc,0x0e,0x03,0xa2,0x79,0x9b,0x63,0xce,0xee,0xf9,0x0c,0xfd,0xfa,0x9a,0x82,0xc9,0x43,0xd3,0xd5,0x23,0xfa,0xac,0x75,0xbe,0x61,0x85,0x18,0xb6,0x75,0x72,0x8d,0x17,0xdd,0xde,0x3f,0x6d,0xb4,0xe8,0x47,0x09,0xe1,0xa7,0xe0,0x4c,0xce,0x93,0x7b,0xc3,0xa3,0x3f,0xc0,0x81,0x21,0x6f,0xe8,0xce,0x68,0x61,0xde,0x1a,0x58 +.byte 0x48,0x7f,0xb4,0xae,0xfd,0x7c,0x80,0x63,0x43,0x5a,0xfc,0xf9,0xf9,0x4d,0xb4,0x8c,0x85,0x27,0x12,0x4f,0x7d,0xe8,0x69,0xc3,0x7d,0x57,0x63,0x0d,0x5f,0xd2,0x85,0x4e,0x0c,0x9a,0x0d,0x1c,0x4d,0xdf,0x3f,0x9a,0x16,0x2f,0x34,0x43,0xc3,0xf0,0xf1,0x16,0x16,0xd2,0x9f,0x2e,0x78,0xd8,0x3c,0x63,0xa0,0x7e,0x02,0x8e,0x65,0xd2,0xb0,0x61 +.byte 0xb0,0x1d,0x7a,0x8f,0xf7,0x30,0x45,0x05,0xf7,0x15,0xc3,0x69,0x24,0x98,0xc3,0x74,0x20,0x16,0x09,0x57,0x39,0x16,0x68,0x23,0x33,0x62,0x4c,0xf5,0xd6,0x34,0xe3,0xad,0x7a,0x14,0x64,0x8c,0x2b,0x48,0x96,0xf9,0x85,0x39,0x19,0x73,0x27,0x04,0xa6,0x55,0x66,0x15,0x8c,0xf1,0x47,0xcd,0x53,0xaf,0x31,0x3a,0xd9,0xfa,0xf9,0xac,0xbd,0xb8 +.byte 0x27,0xe0,0xaa,0xa5,0x62,0x85,0x9f,0xbb,0x4e,0xaf,0xa5,0x72,0x42,0x98,0xa6,0x7f,0xa1,0xb6,0xac,0x17,0xc2,0x2c,0xf3,0xd6,0xc0,0x14,0x4b,0xb3,0x86,0x88,0x89,0x81,0x83,0x7d,0x9d,0xf7,0xe3,0xe4,0x27,0xba,0xa8,0x03,0xb4,0xe3,0x97,0x74,0x1c,0x0d,0xab,0xb4,0x6e,0xc6,0x9e,0x58,0xdd,0x15,0x95,0x2f,0xa6,0xd6,0xaa,0x5a,0x96,0x71 +.byte 0x69,0xca,0xe0,0x5f,0xd2,0x3c,0x66,0x1b,0x58,0x25,0xd6,0xec,0xc0,0x46,0x3e,0x56,0xd0,0xe1,0x36,0x44,0x56,0xc0,0xf2,0x15,0x48,0x9e,0x07,0xce,0x5d,0xb9,0xd4,0x4e,0xcc,0x31,0x26,0xaa,0xdb,0x6a,0x87,0x98,0x0e,0x37,0xfc,0xc5,0x91,0x28,0x1b,0xf8,0x70,0xbf,0x30,0x71,0xbe,0xa0,0x81,0x1e,0x30,0x33,0x37,0x37,0xc8,0x07,0x08,0x9b +.byte 0x8f,0xe4,0x27,0x9f,0x90,0x67,0xb4,0x96,0x08,0xd7,0x30,0x9e,0xa6,0x53,0x39,0xd1,0x9b,0xde,0x02,0x35,0xf3,0xb1,0x19,0x7b,0xd2,0x28,0x5a,0xc3,0x1f,0x69,0x0e,0x48,0xbf,0xa3,0xb4,0x55,0xd1,0x10,0x3d,0x30,0x71,0xc6,0x82,0x2d,0xb8,0x6f,0xe6,0x99,0x6b,0xef,0x9f,0x86,0xed,0x93,0x13,0xb6,0xb0,0x87,0x91,0x77,0x4a,0x00,0xe4,0x5f +.byte 0x4c,0x7d,0x41,0x3b,0xc9,0xda,0x99,0x6b,0xff,0xec,0xef,0x05,0x3c,0xc6,0x0d,0xec,0x68,0x12,0x44,0x31,0xac,0xc9,0x0b,0x9c,0xf5,0xea,0xed,0xda,0x88,0xec,0x6e,0x6e,0x73,0xda,0x85,0x52,0x69,0xa1,0x13,0x52,0xcf,0xc3,0x4d,0x95,0x88,0xec,0x1f,0x53,0x81,0x6f,0xac,0x53,0x60,0x48,0x20,0x9a,0x4d,0x88,0x2c,0x4b,0xb0,0x69,0x5f,0x07 +.byte 0xf9,0xa7,0x2c,0x9a,0x13,0x91,0x86,0xa2,0x98,0x20,0xa9,0x80,0x1e,0xaa,0x8e,0xbc,0x3c,0x3d,0x51,0x34,0x3d,0x5b,0x80,0xe4,0x39,0xfe,0xc8,0xb1,0x6d,0xfe,0x36,0x9d,0x9b,0xde,0x22,0x39,0x41,0xe9,0xff,0xda,0x67,0x67,0xd4,0xeb,0x60,0x44,0xd5,0xc1,0x74,0xcd,0xa0,0x98,0x06,0x34,0x76,0xf8,0xe5,0x0d,0xc8,0x52,0xca,0x83,0xd2,0xdd +.byte 0xf2,0x12,0x36,0x7d,0x3e,0x7f,0xbd,0xa6,0xd8,0x1e,0xc0,0x9d,0x67,0x2a,0x33,0x87,0x86,0x79,0x7a,0x70,0x3a,0x63,0x0b,0x74,0x77,0x89,0xce,0x8f,0x5a,0x3b,0xf3,0x2e,0x52,0x4d,0x1d,0xc6,0xc3,0xc8,0x69,0x98,0xdc,0x81,0x45,0x99,0xfd,0xcd,0x6b,0x6d,0x05,0x33,0x40,0xde,0xb3,0xbd,0x4a,0x27,0xc2,0x9e,0x8b,0xf1,0x4c,0xac,0x92,0x82 +.byte 0x55,0x04,0x79,0xe7,0x28,0x74,0x5b,0x70,0xdc,0xc0,0x4f,0x0c,0xcf,0x3a,0x7f,0x08,0xcc,0x2e,0x1d,0xfd,0x8d,0xd9,0x5c,0xe2,0xa7,0x98,0xc1,0xe8,0x4b,0x96,0xbe,0x27,0xd6,0xfd,0x0a,0x59,0x30,0x33,0x85,0x41,0xc5,0x63,0xab,0xe7,0xda,0x26,0xbd,0xce,0xe7,0x9d,0x50,0xd7,0x2d,0x67,0x7a,0xa1,0x05,0x2b,0x74,0x60,0x5e,0x6c,0x04,0x2b +.byte 0xba,0xe6,0x2d,0x25,0xc9,0x00,0xd0,0xf0,0xa5,0x4f,0x22,0x59,0x34,0xb8,0x43,0x6b,0xb7,0x67,0x25,0x99,0xff,0x75,0x17,0xb1,0x13,0x7e,0x34,0x1d,0x42,0xa3,0x6b,0xb5,0x9d,0xfe,0xa1,0x71,0x0d,0x90,0x81,0x58,0xfc,0xc7,0x85,0xe6,0xbd,0xc2,0xcc,0xc9,0xc9,0x23,0x6e,0xd6,0xbe,0x4a,0x61,0xd4,0xf5,0x9e,0x37,0x6a,0xb1,0x8b,0x91,0x59 +.byte 0xe1,0x3e,0xac,0x87,0x54,0xa6,0xf9,0xf5,0x90,0xd2,0x7c,0xba,0x4b,0x37,0x33,0x1b,0x88,0x5e,0xbd,0x78,0x3f,0xed,0x43,0x40,0x4f,0x16,0x59,0x29,0xbc,0x27,0x98,0x87,0xfe,0x62,0x56,0x93,0x21,0x0a,0xca,0xc1,0x21,0x99,0xb3,0x32,0xbb,0x5a,0x79,0x40,0xab,0xea,0x00,0xf8,0xe9,0x90,0x0d,0x59,0xbd,0x6e,0x7f,0x74,0x01,0x50,0x67,0x3a +.byte 0x8e,0x24,0x1d,0x6c,0xc8,0xd6,0x93,0xca,0x71,0x95,0xec,0xac,0x78,0xe9,0x1f,0x38,0x0d,0xa2,0xe5,0x32,0x90,0xa2,0xaf,0xef,0x15,0x06,0xd6,0x52,0xa4,0xd2,0x94,0x0f,0xbd,0x86,0x81,0x82,0x12,0x9b,0x3a,0xc4,0x0b,0xdf,0x8a,0x5f,0xc6,0x3b,0xb4,0x13,0x9b,0xeb,0xed,0x2d,0x06,0x46,0xa3,0xbe,0xbb,0xe1,0xe1,0x93,0xa1,0xab,0x46,0xf3 +.byte 0xd0,0xd9,0xce,0xb6,0xfb,0xd0,0xd5,0xb6,0xde,0x0c,0xed,0x90,0x18,0x6c,0x1e,0x46,0xb0,0x36,0xa7,0xf1,0x29,0xbe,0x9a,0xa0,0xcf,0xed,0xd6,0xaf,0xb8,0x89,0x9b,0x83,0xa8,0xa0,0x8d,0x26,0xaf,0x8f,0x48,0x66,0xfc,0x22,0x1a,0xc0,0xcf,0xf8,0x90,0x57,0x7e,0x25,0x5f,0xe4,0x0c,0x68,0xd2,0xaa,0x59,0x09,0x2f,0x6d,0x3f,0x80,0x8d,0xe0 +.byte 0xfa,0x25,0xb0,0xe0,0x85,0xe9,0x13,0x39,0x3d,0x1f,0xed,0xd1,0x94,0x9b,0xb5,0xc2,0x65,0xda,0xec,0x7a,0x1f,0x2f,0xe2,0x0a,0x42,0x09,0xbd,0x79,0x7d,0xcb,0xb8,0x4a,0x02,0x2b,0x72,0xaf,0x33,0x85,0x72,0x1b,0x18,0x0c,0xa3,0xec,0x39,0x0e,0x30,0x21,0x41,0xf8,0x2e,0xc7,0x8e,0x5c,0x4c,0xda,0x22,0x49,0x8c,0xa7,0xfb,0x89,0x76,0x2e +.byte 0x45,0x90,0x6c,0xeb,0x70,0x78,0x6d,0x6e,0xee,0x12,0x6c,0xb9,0xb9,0x8d,0xe7,0xf3,0x4d,0x86,0xc4,0x58,0x49,0x55,0xa6,0x86,0xaf,0x39,0x03,0x21,0xfa,0xa7,0xdd,0x51,0x80,0x79,0x6d,0x5b,0xa5,0x58,0x0f,0xfd,0x57,0xb3,0x83,0xe6,0x0d,0x25,0xec,0x55,0xdc,0x0a,0x6f,0xbc,0x7d,0xfd,0x94,0x16,0xdd,0x60,0x9f,0x2a,0x4b,0x6c,0x82,0x03 +.byte 0x4b,0x44,0xbb,0x84,0xdc,0xcb,0x97,0x8e,0x58,0xe7,0xc1,0x79,0xa9,0xf3,0x53,0x78,0x1f,0xf1,0x3e,0xdd,0x94,0x24,0x6d,0xb1,0xd2,0x99,0xbc,0xa1,0xbe,0x7d,0xdd,0xff,0xa8,0x5d,0xd2,0xc2,0xba,0xad,0x60,0x6b,0x40,0x5d,0x7b,0x99,0xd2,0xea,0x45,0x66,0x80,0x6c,0x47,0xf2,0xeb,0x94,0xb8,0xe8,0xe8,0xa0,0x46,0x05,0xe1,0x4f,0x40,0x23 +.byte 0x34,0xdf,0x91,0x63,0xae,0xc9,0xe7,0x32,0x20,0x9a,0x95,0x1e,0xcd,0x5a,0x60,0xe1,0x3d,0xe0,0xf1,0x16,0x3d,0x6e,0x8b,0x96,0x23,0xe0,0xaa,0x1d,0x1a,0xde,0xed,0xc6,0x63,0xb5,0x46,0x8b,0x78,0x71,0x9a,0x14,0x88,0x79,0x61,0x68,0x6b,0xcf,0x80,0xd8,0x9c,0xaa,0xfb,0xb1,0xc0,0xf3,0x39,0x07,0x26,0x56,0x80,0xba,0x9d,0xf5,0xe7,0x95 +.byte 0x99,0xac,0x90,0xea,0xe7,0xe1,0xc9,0x0d,0x40,0x94,0x83,0x58,0xd2,0xc3,0x2b,0xce,0x1e,0xae,0x2a,0xa6,0xfa,0xc7,0x89,0x44,0xcb,0xe2,0x9e,0x74,0x33,0xaa,0x70,0xe5,0x28,0x3a,0x51,0x74,0x53,0xe2,0xfb,0x7c,0x47,0x76,0x22,0xdf,0x46,0xa6,0x01,0x17,0xef,0x88,0x43,0x46,0x3f,0x1a,0x26,0x0c,0xad,0xf4,0x31,0x55,0xf2,0xe7,0xc9,0x35 +.byte 0x6f,0x7c,0x0c,0x5c,0xfd,0x43,0xa4,0x6c,0x6c,0x74,0xf0,0xa4,0xec,0x1d,0x83,0x97,0xc1,0x6c,0x9c,0xd7,0x97,0x90,0x7c,0x07,0x88,0xc0,0xb4,0x79,0x2c,0x7a,0x9c,0x93,0xa2,0x15,0x6c,0xd2,0xa9,0x45,0xa5,0xc1,0x16,0xfe,0x72,0xf4,0x01,0x32,0xe4,0x51,0xdd,0xdb,0x50,0xe3,0x61,0x4e,0x29,0x1e,0x27,0x10,0xe9,0x5e,0x30,0x2b,0x30,0x27 +.byte 0x99,0xff,0x92,0x23,0x04,0x8d,0x28,0x68,0x28,0xd3,0x0f,0xec,0xbb,0xf9,0xfb,0x44,0x1c,0xaa,0x8b,0x38,0x95,0x67,0x1e,0xf5,0x42,0xc9,0xec,0x05,0xeb,0x94,0xe5,0x1c,0x8a,0x2a,0xef,0x3b,0x74,0x46,0x89,0x4f,0xd5,0x6f,0xa0,0xe5,0x74,0xae,0x24,0x8d,0x81,0xae,0x9d,0x3c,0x3e,0x3d,0x41,0x54,0x8f,0xd9,0xc2,0x98,0xf4,0x84,0xeb,0x30 +.byte 0x6a,0x06,0x67,0x11,0x2d,0xb0,0x55,0x70,0x26,0xdf,0x19,0x5f,0x81,0xe9,0x39,0x69,0x3a,0xd6,0x09,0xa4,0x40,0x22,0x1f,0x5c,0xbf,0xd5,0xa6,0xea,0x69,0x99,0x0d,0xea,0x70,0xed,0xfe,0x3a,0xba,0x23,0x8b,0xab,0x08,0xfe,0xfb,0xe9,0x1a,0x88,0x80,0x13,0x45,0x9c,0xca,0x2e,0xda,0x4a,0xc8,0x5d,0x15,0x52,0x87,0x36,0x9b,0x87,0x8a,0x76 +.byte 0x5d,0x31,0x24,0x4a,0xcb,0xf5,0xd3,0xd3,0xc1,0xec,0xde,0x1e,0x48,0x99,0xd5,0xcb,0x93,0xf7,0xca,0x2d,0xa4,0x66,0x5e,0xa4,0xcf,0xc6,0x15,0x20,0x10,0xb1,0xe2,0x8e,0xb9,0x44,0xa7,0xc3,0x54,0x14,0x86,0x08,0xb7,0x89,0x52,0xd5,0x72,0xc5,0x62,0x4d,0x82,0x96,0x23,0xcf,0x6e,0x52,0x3a,0x92,0x53,0x48,0xa2,0xa5,0x9d,0xa4,0xcc,0x32 +.byte 0x45,0x5a,0xdf,0xe2,0xbe,0xce,0x28,0xc8,0xb1,0xb7,0x0f,0x6a,0x38,0x28,0x14,0x66,0x55,0x7a,0xab,0x35,0x56,0xd0,0xc7,0xe5,0xa1,0x8a,0x84,0xf7,0xc5,0xa9,0xdb,0x2a,0x45,0xe9,0x34,0x2d,0xf2,0xed,0x2b,0xa9,0x9e,0x49,0x1b,0x23,0x10,0xeb,0x0e,0x01,0x46,0x6f,0x7a,0x50,0x09,0x5f,0xc3,0xb6,0x1e,0x2f,0x1a,0x3e,0x89,0x32,0xaa,0x5a +.byte 0xaa,0xef,0x23,0x45,0xdc,0xb5,0x7e,0x5f,0x87,0x77,0xde,0x50,0xab,0xbf,0x9e,0x62,0xa8,0xe0,0xf0,0xc8,0x4a,0xf1,0x4e,0xaf,0xe4,0x50,0x8a,0xfe,0xc9,0x68,0xdd,0x19,0x1d,0xc6,0x54,0xe5,0x38,0x0a,0x6f,0x36,0xe4,0x85,0xe8,0xab,0xc4,0x06,0xef,0x07,0x29,0xce,0xea,0x9d,0x2e,0x22,0x97,0x18,0x7e,0x59,0x89,0x92,0x31,0xc5,0x87,0x50 +.byte 0xa8,0x23,0x22,0x58,0x47,0x27,0x1c,0x89,0x5f,0xec,0x94,0x1d,0xb2,0xc8,0x61,0x1e,0x0a,0x80,0xd3,0xe9,0xbf,0x65,0xb9,0x66,0x32,0x56,0xde,0xd2,0x13,0xee,0xea,0xc4,0xc9,0xbf,0x4c,0xb7,0xa4,0x1c,0xc0,0xbf,0xcf,0xa4,0x58,0x1f,0x98,0x1d,0x25,0x4e,0x51,0xd9,0xbe,0x89,0x32,0xdb,0x7a,0xa6,0x39,0xa9,0xbf,0xed,0x65,0x6b,0x92,0xc4 +.byte 0x8d,0xcd,0x63,0x18,0x65,0x44,0x95,0xcf,0x17,0x72,0x8f,0x27,0x79,0x83,0xda,0xe3,0xe7,0xd9,0xca,0x57,0xff,0xa3,0x15,0xbf,0xb6,0xd8,0xc2,0x8c,0xe8,0xdb,0x8c,0xdc,0x54,0x6a,0xc8,0x57,0x6e,0x24,0xc3,0x3c,0x1f,0x33,0xdd,0x68,0xbd,0x7a,0xa3,0xbc,0xa9,0x9a,0xe8,0xfc,0x97,0xa5,0xbe,0x59,0xfb,0x77,0xcd,0x22,0xc6,0x3d,0x95,0x21 +.byte 0xcb,0xf7,0x8d,0xc1,0x77,0xc6,0xe0,0x06,0xb2,0xdb,0xec,0x54,0x19,0xad,0x02,0x25,0xe0,0x0f,0xda,0x4c,0xa5,0xf2,0x47,0x3f,0xc9,0xa0,0x91,0x21,0x39,0xe9,0x74,0x2a,0x9a,0xc1,0x57,0x86,0x3c,0x32,0x27,0x4c,0xc2,0x2d,0x50,0xbd,0x7a,0x04,0x9c,0x45,0x0d,0x7e,0x06,0x1d,0x3e,0xc1,0x6f,0x06,0x7f,0xd4,0x71,0xd3,0x5c,0x66,0x74,0xa7 +.byte 0x33,0x75,0x64,0xa8,0x7d,0xc0,0x23,0xda,0xb0,0x6d,0x12,0xbe,0x83,0x98,0xe7,0x65,0x38,0x4d,0x39,0xc3,0xd7,0x33,0xfb,0x58,0x64,0xfc,0xde,0xd7,0xbf,0x9e,0xdb,0xcc,0x7a,0x35,0xac,0xdf,0x13,0x08,0xbc,0x0a,0x55,0x82,0x5f,0xc3,0x74,0xc5,0xb2,0xdb,0x89,0xdc,0x9c,0x60,0xfa,0x02,0x1c,0xba,0x5b,0x7e,0x0f,0xb1,0x0f,0xad,0x43,0xe1 +.byte 0xe1,0xbe,0x1e,0x06,0x05,0x0f,0x39,0x80,0x3d,0x7d,0xbe,0x8f,0x38,0x25,0x46,0x5e,0xea,0x47,0x36,0x65,0x4c,0x3c,0x6c,0xd6,0xaa,0x46,0xaa,0xb0,0x95,0x1d,0xff,0x67,0x6c,0x70,0x9d,0xec,0x3d,0x3d,0x4c,0x2f,0xd9,0x2b,0xb0,0xbd,0x8c,0x6a,0xca,0xac,0x0c,0x53,0xa1,0xda,0xd8,0xc1,0x3c,0xaa,0xcc,0x50,0x85,0x41,0xa1,0xa7,0xe9,0x7f +.byte 0xf7,0xa8,0x28,0xb1,0x5f,0xd6,0x77,0xc9,0xb5,0xae,0x33,0xa7,0x2d,0x16,0xe0,0x13,0xe8,0xd4,0xf9,0x4e,0x62,0x2e,0xc2,0x9a,0xf3,0x83,0xe0,0x45,0x43,0x68,0x40,0x5a,0x56,0xf3,0x31,0xc8,0x5b,0x46,0x0b,0x38,0x1f,0xa5,0xff,0xe6,0xa1,0x81,0xc0,0x91,0xe5,0x5a,0x63,0x8f,0x47,0x9a,0xe7,0x26,0x0d,0x78,0x8d,0x11,0x7d,0xc8,0xd4,0x9f +.byte 0xc1,0xf7,0x8f,0x93,0xfa,0x2f,0xb5,0xfd,0x6d,0xa4,0x34,0xcf,0x3c,0x6c,0xf6,0x64,0xae,0x5c,0x60,0xa2,0xb4,0xcc,0x18,0x3e,0x08,0x8e,0x36,0x88,0xab,0xc3,0xea,0x53,0x4f,0x1c,0x9e,0xe6,0xef,0x2d,0x9c,0x78,0x4a,0x3a,0x5a,0x60,0x8e,0xf7,0xeb,0x0b,0x36,0xb1,0xbb,0x59,0xe2,0x5e,0x64,0x60,0xe5,0xd6,0x3d,0x2a,0xe1,0x1b,0x03,0x40 +.byte 0x8d,0xde,0x2e,0xd0,0x76,0x0a,0x6b,0x63,0x2a,0x53,0x2d,0x39,0xe0,0x53,0xee,0x7d,0xc4,0x8a,0x39,0xc5,0xda,0xfc,0x31,0x7e,0xa2,0x1b,0x11,0x1d,0x8a,0x8e,0x66,0xf4,0x00,0x17,0xd3,0x78,0x1b,0x94,0xad,0xcf,0xdd,0x56,0xce,0xaf,0xf6,0x34,0xe4,0xb6,0x47,0xe0,0xda,0x1b,0x36,0x4f,0x86,0x26,0xc1,0x65,0xec,0x85,0x8c,0xa9,0xfe,0x96 +.byte 0x75,0x0d,0xe3,0xeb,0x9a,0xa6,0x3f,0xb3,0x10,0x03,0x85,0x24,0xf2,0xb5,0xcd,0x69,0x7d,0xba,0xa2,0x5c,0x8a,0x6d,0x45,0xf4,0xc8,0x4f,0x69,0x8e,0xd4,0x69,0x82,0x42,0xfd,0x00,0x59,0xfd,0x20,0x7a,0x63,0x58,0x56,0x30,0x21,0x73,0xbd,0xd4,0x49,0x84,0x3f,0x51,0x0e,0xfb,0xd3,0xfc,0x93,0x17,0x7f,0x23,0x75,0x25,0xea,0x78,0x79,0xf7 +.byte 0xec,0x22,0xef,0x86,0x91,0x0a,0x90,0x10,0x71,0x3b,0xb8,0x8e,0xb7,0xc9,0xd1,0x26,0x98,0x7d,0x1a,0xab,0x74,0x3e,0x5f,0x10,0xa8,0x47,0xdf,0xc9,0x0a,0x03,0xbb,0xe2,0xbb,0x34,0xbe,0x87,0x1a,0x3e,0x13,0x4b,0xd5,0xdd,0x53,0xb7,0x65,0xb4,0x16,0x38,0xd3,0xfd,0x01,0xde,0xe8,0xba,0x1d,0x33,0x5b,0x7b,0x9b,0x9f,0xfb,0xe7,0x8d,0x82 +.byte 0x21,0x78,0x9e,0xb2,0xf5,0x16,0x37,0x88,0x47,0x9d,0x1a,0x2c,0xfe,0x6a,0xac,0xde,0x3e,0xc4,0xa8,0xed,0x64,0x46,0xdd,0x05,0x07,0x60,0xef,0x99,0x96,0xf0,0x84,0x27,0x38,0x58,0xe5,0xc0,0x53,0x7d,0x07,0xe3,0xa5,0x31,0xb5,0x8a,0xe7,0x50,0x94,0xbb,0x29,0xf9,0x58,0x13,0x91,0x5b,0x54,0x77,0xf6,0x91,0xb8,0x75,0x05,0x3d,0x70,0x3e +.byte 0x07,0x95,0x7d,0x37,0xbd,0x1d,0x29,0x4d,0x33,0x07,0x13,0x2b,0x54,0x70,0x9c,0x31,0xf1,0xcd,0x2d,0x28,0x09,0x43,0x90,0x24,0x8c,0x82,0xb0,0x08,0x71,0x08,0x97,0x7e,0x1a,0xbc,0x82,0xd8,0x31,0x0a,0x13,0xe9,0x22,0xf0,0x8d,0x2b,0x91,0xe5,0x2e,0x34,0x56,0x97,0x86,0xc9,0xbd,0x45,0x1e,0x32,0x03,0xcb,0xa1,0x29,0x00,0x81,0xd4,0x6e +.byte 0x5d,0xbc,0x0f,0x01,0x8d,0x5c,0xb9,0x80,0xcc,0xfe,0x0d,0xa3,0xef,0x8e,0x85,0x59,0x37,0xf7,0x64,0xa7,0xe5,0x2a,0xd5,0x44,0xee,0x91,0xcf,0x6c,0xf5,0x0a,0x9b,0xc7,0xdf,0xb6,0x02,0x2d,0xa4,0xf1,0x22,0x2a,0x97,0xfe,0x1d,0xb7,0x4c,0xc7,0x4f,0x2f,0x0b,0x38,0xd2,0xbf,0xfe,0xe3,0x94,0x55,0xae,0x85,0x0c,0x34,0x59,0x67,0x23,0x7b +.byte 0x4a,0x87,0xd9,0xd2,0xca,0xd5,0x38,0xd2,0x9d,0x05,0x2e,0xd8,0xe3,0x26,0x51,0xa4,0x14,0x66,0xfb,0x38,0x40,0x18,0x3b,0xda,0x43,0x85,0xc9,0xf5,0xf4,0xe7,0x22,0x82,0x45,0xa1,0xdf,0x98,0xa0,0xab,0x5f,0x7a,0x50,0x84,0x75,0x7a,0x70,0xa6,0x3b,0x04,0x20,0xed,0xa8,0x68,0x6d,0x3f,0x43,0xf8,0xb8,0xac,0xc7,0x32,0xa0,0xff,0x47,0xd5 +.byte 0xb3,0x92,0x6a,0x15,0x5a,0xf1,0x7c,0x32,0x30,0xda,0x1e,0x5d,0xab,0xcc,0xd0,0x3a,0xdc,0xcf,0x70,0xd8,0x4d,0xa3,0x50,0xac,0x50,0x42,0x53,0xc6,0xe0,0x3a,0x26,0xdc,0x77,0x30,0x31,0x59,0xa1,0xfc,0x4d,0x48,0x00,0x0d,0xe0,0x66,0xb3,0x9b,0xd3,0x38,0x45,0xbb,0x0c,0x57,0xc5,0x78,0xee,0x8c,0x96,0xea,0xa2,0x16,0xa3,0x12,0xb1,0x06 +.byte 0xd0,0x2a,0x70,0xf7,0xce,0x42,0xae,0x17,0x64,0xbf,0x13,0xa0,0xe9,0x62,0x57,0x1d,0x55,0x78,0xfa,0x72,0x19,0x58,0x15,0xea,0xe5,0xdf,0x72,0x0e,0xc6,0xd3,0xb4,0x3d,0x60,0xee,0x32,0x2a,0xce,0xdc,0xad,0xd0,0x34,0xe6,0xb4,0xcf,0xce,0x5a,0x4a,0x9f,0xaf,0x01,0xb3,0x2a,0xed,0x46,0xa0,0xad,0xaa,0x62,0x8b,0xa4,0xf7,0x4b,0xce,0x32 +.byte 0x35,0x29,0x1e,0x7a,0xda,0x74,0xf8,0xe5,0xda,0x52,0x66,0xaf,0x3d,0x1a,0xff,0x42,0xc0,0xcc,0xb1,0x32,0x36,0x10,0x44,0x34,0x6a,0x16,0xc2,0x5b,0x9a,0x35,0x3f,0xd2,0x29,0xc5,0x76,0x3c,0x24,0xc7,0x2b,0x92,0xae,0xe0,0xe2,0x04,0x6c,0x3b,0x97,0xda,0xfd,0x49,0x43,0x6d,0x35,0xf5,0xc3,0xc1,0x93,0xf8,0x2f,0x25,0xef,0x3e,0xd8,0xf2 +.byte 0xc0,0xb3,0xb5,0x71,0x01,0xe0,0x07,0x11,0xd5,0xf1,0xd3,0x54,0x59,0x93,0x77,0x2e,0x77,0xdc,0x57,0xd7,0x9b,0x0a,0xe2,0xde,0x29,0x04,0x81,0xa1,0x81,0x6f,0x94,0x86,0x39,0xd7,0x29,0x69,0x3f,0xfa,0xe4,0x02,0x01,0x85,0x04,0x21,0xd3,0x17,0xf5,0x68,0x85,0x6e,0x74,0x15,0x56,0xe6,0x5e,0x12,0x1c,0x0d,0x2f,0x7a,0x8d,0xe1,0xc8,0x47 +.byte 0x7b,0xdc,0x35,0x64,0xf1,0x00,0xc0,0x7b,0xd8,0x2c,0x8c,0x60,0x10,0x53,0x11,0x2c,0x5c,0xa2,0xb6,0x05,0xa3,0xcd,0x14,0xb6,0xd0,0x36,0xe9,0x74,0x78,0xc3,0x84,0x6b,0x51,0xa9,0xf9,0xf1,0x05,0xe2,0xd4,0xa3,0x57,0xec,0xb1,0x5e,0xd5,0x75,0x64,0xe3,0xb0,0xf9,0x8f,0x88,0x60,0xdf,0x8e,0x75,0xf9,0x32,0xfc,0x58,0x5b,0x4b,0x17,0xdb +.byte 0x41,0x04,0x6f,0x17,0x7a,0xf8,0xd0,0x47,0x8e,0xeb,0xd1,0xf9,0xa6,0xa8,0x52,0x7e,0x07,0x6b,0x5b,0x4d,0xb9,0xda,0x91,0x40,0x51,0x25,0x67,0x4b,0xf1,0x95,0x12,0x07,0xa9,0xa5,0x33,0x96,0x92,0x5e,0xb4,0x0e,0xf0,0x85,0x2e,0x70,0xd8,0xaf,0xae,0x9a,0x3d,0x0c,0xb0,0xee,0xe1,0x80,0x5a,0xb9,0x17,0xe6,0x00,0xa8,0x82,0xd0,0x9b,0xf5 +.byte 0xe3,0xa0,0x12,0xc4,0x15,0xd6,0x5e,0x57,0x5c,0xd2,0xb9,0xa7,0x8e,0xfd,0x09,0xc3,0xd2,0x66,0xfd,0x86,0xb4,0xdc,0xa3,0xc2,0xfe,0x16,0x86,0xc4,0x98,0xa3,0x2e,0x4c,0xc9,0x2c,0xd6,0x87,0x83,0x1b,0x6f,0xe2,0x44,0xd6,0x72,0x94,0x1d,0xba,0xaf,0x34,0x1f,0xf2,0x40,0x40,0x33,0x24,0x63,0xc1,0x26,0xef,0xbc,0x0f,0x3b,0x3c,0x65,0x2b +.byte 0xa7,0xc7,0xdf,0x96,0x67,0xab,0x92,0x0e,0x04,0x8c,0x82,0x9e,0xbe,0x52,0x61,0x40,0xdf,0x77,0x00,0xc5,0x01,0x9a,0xe9,0xde,0xe1,0xe2,0x45,0xb8,0xed,0x94,0xd5,0xf0,0x28,0x29,0xef,0x0d,0x91,0x07,0x9b,0xfe,0x69,0x78,0x26,0xd7,0xf9,0x51,0xf1,0x9c,0xf2,0xbb,0x83,0x2d,0x79,0x1e,0xff,0x97,0x13,0xdc,0x28,0x93,0x26,0x7c,0x54,0x52 +.byte 0xc0,0x92,0xeb,0x4a,0xa2,0xe3,0x01,0xfc,0x07,0xb9,0x26,0x11,0x03,0xe0,0x19,0xa8,0x9c,0xff,0x3a,0x95,0x26,0x3a,0x17,0xf1,0x7d,0x6a,0x6a,0xb2,0xb5,0x5a,0x07,0x43,0x2b,0xb7,0xdd,0x19,0x14,0xe0,0x05,0x91,0xc5,0xee,0x49,0x35,0x7b,0x1a,0x2d,0x34,0xda,0xa2,0x45,0x7e,0x0d,0x64,0x98,0xb6,0x2e,0x47,0xaa,0x6c,0x73,0x66,0x55,0x01 +.byte 0x27,0xb0,0xa9,0x13,0xa6,0xe0,0x74,0x38,0xb3,0x97,0xfe,0xaf,0xdc,0xc0,0x6a,0x4f,0xd8,0xdb,0x07,0x62,0x61,0x05,0xbb,0xa0,0xa8,0xc5,0xb3,0x89,0x13,0xbb,0x09,0x01,0x6f,0x09,0xcb,0x47,0x62,0x46,0xf0,0x4b,0xf0,0xb7,0x7c,0x39,0x8d,0xe5,0x7b,0x64,0x49,0x32,0x93,0x1e,0x94,0x0a,0x98,0xe0,0xca,0xc6,0x67,0x5b,0xdf,0x88,0x0a,0x26 +.byte 0x83,0x77,0xc3,0xd0,0x11,0x66,0x3d,0x25,0x91,0x61,0x80,0xfc,0x9c,0x50,0xfb,0xe8,0x81,0x6f,0xd8,0xfa,0x77,0x78,0x4c,0x2b,0x44,0xd0,0x92,0x52,0xa4,0x50,0x50,0x7e,0xa2,0xb9,0xe7,0x79,0x33,0x95,0xfe,0x29,0x1c,0x1d,0x43,0x9d,0xa7,0x12,0xfe,0xa1,0x45,0xf4,0xd9,0x1c,0x7e,0x5a,0x67,0x99,0x7f,0x22,0x7c,0xa3,0xb1,0x2d,0xb7,0x1d +.byte 0x6b,0xf6,0xb4,0x94,0xf2,0xd1,0x5c,0x28,0x56,0xe9,0x4f,0x21,0x81,0x96,0x37,0x7c,0x25,0x74,0x0f,0xf9,0xc5,0xf5,0xc6,0xe8,0x8f,0xbb,0xfb,0xe4,0xaf,0x23,0xac,0x4c,0x20,0x35,0x7d,0xb4,0x4a,0xde,0x90,0xec,0x16,0x30,0x95,0x1b,0x79,0xf6,0x77,0xfe,0x80,0x10,0xba,0xd2,0x49,0xda,0xca,0x9e,0x6b,0x63,0x2f,0x24,0x38,0xf9,0xee,0x20 +.byte 0x38,0x5c,0xeb,0xf5,0xbc,0x07,0x7a,0xeb,0xde,0xc4,0x97,0xcf,0x48,0x9b,0x80,0x40,0xfa,0x81,0xf5,0x24,0xa7,0xf3,0xf7,0x16,0xe9,0xba,0xae,0x9f,0xde,0xa1,0x00,0x34,0x74,0x36,0x9f,0x47,0xce,0xcf,0x35,0xdb,0x30,0x7e,0x72,0x81,0xc5,0xe1,0x59,0x07,0x3e,0xc7,0x5b,0x7b,0xd3,0xc6,0xeb,0x4e,0x71,0x9c,0xeb,0x41,0x37,0xd9,0x9e,0x34 +.byte 0x0b,0xc1,0x9c,0xf7,0xfd,0x56,0xb0,0xd6,0xa6,0xe4,0x1d,0xdf,0x43,0xc6,0xf3,0x26,0x0f,0x01,0x07,0x29,0x57,0x9c,0x8f,0xe1,0x31,0xc9,0xa6,0x98,0x0f,0x0e,0x27,0xfd,0xa0,0x59,0xdf,0x92,0x7b,0x0a,0x4c,0x42,0x4b,0x03,0x98,0x2a,0xea,0xcb,0xd8,0x0f,0x6d,0x19,0x0b,0x22,0x69,0x8b,0xaa,0x3b,0xc8,0x41,0x66,0x81,0xc3,0xaa,0x64,0x6d +.byte 0x44,0xdd,0xb9,0xe2,0xc4,0x47,0x6d,0xdf,0x61,0xe0,0xf3,0x26,0x40,0x23,0x2f,0xf9,0x2a,0xb3,0xfa,0xe2,0xe8,0x36,0xc0,0xd9,0x89,0xb0,0x05,0x47,0x36,0x20,0x3b,0x03,0x0c,0xd1,0x46,0x9b,0xc9,0x65,0xfa,0x14,0xba,0x68,0x49,0xfc,0x2a,0xb9,0x04,0x47,0xbb,0x64,0xe1,0x7f,0x5a,0xd3,0x70,0x19,0x0f,0x14,0x09,0xc0,0xbe,0xc3,0x9b,0x2f +.byte 0xd1,0x05,0x90,0x56,0x09,0x47,0xb3,0xc5,0x08,0x6f,0x89,0x59,0x8c,0xf3,0xd4,0x1c,0xaf,0x68,0x00,0x32,0x58,0xe2,0x66,0x55,0xe2,0xc3,0x46,0x73,0xfd,0x4b,0x63,0xc5,0xdd,0x48,0xa8,0x14,0xe9,0x07,0x94,0x8f,0x51,0x6e,0x2d,0x7c,0x62,0x97,0x73,0xa5,0x42,0x7d,0xad,0x43,0xcb,0x65,0x56,0xf0,0x23,0x28,0x72,0xdb,0x1f,0xcf,0x34,0x9a +.byte 0x62,0x06,0x8d,0xc9,0x86,0x40,0x6d,0xee,0x58,0x72,0x02,0xbb,0xce,0x33,0x6a,0xe4,0xcb,0x46,0x25,0xda,0x2f,0x8d,0xc9,0x8e,0xfe,0xcf,0xbb,0xfc,0xb0,0xe8,0xec,0xf2,0xf9,0xff,0x5d,0x70,0x9e,0x2e,0x22,0x0e,0x9a,0x4d,0xb8,0x26,0x7a,0x48,0x3f,0xba,0x5c,0xcd,0x10,0xf4,0x6d,0x89,0x3d,0x5d,0x87,0xd4,0x69,0xb8,0x4a,0x20,0xc6,0xf8 +.byte 0x03,0x6c,0x60,0x1e,0x9c,0xc6,0xe3,0x39,0x9b,0xa1,0x16,0x64,0xed,0xc6,0xd7,0x54,0xfd,0x8d,0xa0,0x2f,0xcf,0xc6,0xde,0x43,0xe4,0xc5,0xb7,0xd6,0x00,0xaf,0x95,0x7a,0xc6,0xde,0x26,0x59,0x39,0xb0,0x12,0x6b,0xe1,0x3c,0xa9,0x09,0xb6,0x15,0xb0,0x62,0xad,0xa9,0x11,0x4f,0x86,0xde,0xc6,0xe8,0x32,0x46,0x78,0xeb,0x60,0x81,0x6b,0x8f +.byte 0xac,0x80,0xbf,0xa4,0xc4,0xb7,0x5f,0x3b,0x2f,0xf8,0xe4,0x05,0xcf,0xbf,0xa3,0x14,0x6f,0x16,0xbc,0x6c,0x4e,0x31,0xd7,0x79,0x09,0xcf,0x9c,0x58,0xa3,0x0b,0x1a,0x31,0x4b,0xda,0xcb,0x11,0x35,0xb1,0xf5,0xbb,0xfb,0x00,0x46,0x6d,0x70,0x5e,0x4a,0x85,0x19,0xdf,0xb5,0xd0,0x03,0x2e,0x5d,0x01,0x95,0x4e,0x5a,0x59,0x99,0x24,0xac,0x3f +.byte 0x2d,0x64,0xaf,0xef,0x40,0x16,0x2a,0xcc,0x6a,0x6c,0x0f,0xe3,0x45,0x15,0x74,0x3d,0xea,0xdb,0xa7,0x3f,0xd2,0x50,0x4d,0xc7,0xc6,0x19,0x36,0x84,0xf4,0xbd,0x09,0xff,0xe7,0xf3,0xc0,0xa5,0x34,0x49,0x8a,0xfe,0x83,0xcd,0xe4,0x80,0x7d,0xe3,0xff,0xc9,0x8a,0xb9,0xd6,0x34,0x01,0xd1,0x47,0x16,0x5e,0x7c,0x16,0xf5,0x7c,0xf8,0xb5,0x53 +.byte 0x26,0x84,0x89,0x73,0xf3,0x7f,0x9c,0xb0,0x2f,0x07,0x9e,0xf2,0x12,0xdf,0xba,0xc0,0x15,0xd0,0x3a,0x59,0x9d,0xde,0x67,0x5e,0x1c,0x2b,0x4b,0x84,0xb8,0x89,0xfb,0x62,0x90,0xe9,0x89,0xd9,0xdb,0xb7,0x21,0x4a,0x9f,0xbd,0xc0,0x02,0x01,0xda,0xb3,0x4c,0x9d,0xfb,0x46,0xa1,0xd0,0x3c,0xf5,0x27,0x6f,0x70,0xb5,0xa9,0x74,0xdc,0xa0,0x76 +.byte 0xb7,0x3a,0x53,0x18,0xdd,0x80,0x5e,0x43,0xb5,0x35,0xe4,0x0e,0x26,0x27,0x0a,0xab,0xe8,0x4d,0x2e,0x89,0x20,0xc3,0xff,0xe4,0x7f,0x03,0x2c,0x5f,0x25,0xc7,0x70,0x53,0x27,0x4c,0xc8,0xb9,0xb1,0x81,0x10,0x7a,0xa2,0x65,0xe4,0x0b,0x65,0x8e,0x3d,0x2f,0x96,0xa0,0xa5,0x7b,0x4f,0x09,0xe9,0x9d,0x10,0x06,0xf7,0x18,0xad,0x2d,0x7f,0xb8 +.byte 0x8f,0x08,0xa7,0x2c,0xda,0x82,0xbe,0x5c,0xd6,0x1d,0xb6,0xe2,0x9b,0xa2,0xfc,0x18,0x8c,0x8d,0xf7,0x81,0xf4,0xc6,0x1e,0xcb,0xe5,0x73,0xa6,0x74,0x06,0x20,0xf3,0xa9,0xcb,0x80,0x01,0x55,0x7e,0xc0,0x6a,0x1f,0x5a,0x5b,0xb1,0x56,0x5d,0xd8,0x2a,0xd5,0xf5,0x57,0xe8,0x48,0x6c,0xfb,0x9e,0x93,0xa7,0x0e,0x13,0x2b,0x68,0xc5,0x6b,0x17 +.byte 0x43,0xb0,0x58,0x04,0x65,0x3d,0x46,0x57,0xa7,0x3d,0x99,0xb8,0xa1,0x48,0x17,0x44,0x67,0x2a,0x0d,0x44,0x87,0x9f,0x63,0xd7,0x92,0x56,0x7b,0xab,0xd3,0x6a,0xbd,0x4f,0xc0,0xc3,0xd2,0xee,0xd1,0x3d,0xd1,0x18,0x2e,0x6a,0xf5,0x3b,0x67,0xa0,0x0a,0xf3,0x11,0x49,0xc5,0x4b,0xef,0xcf,0x00,0xfd,0x22,0x8f,0xa0,0x9c,0x99,0x32,0x2f,0x58 +.byte 0xf9,0x97,0x98,0x13,0x4a,0x88,0x50,0xcc,0x58,0x1e,0x27,0x02,0x34,0x7d,0xec,0xf6,0x88,0x3a,0x74,0xb5,0x34,0x6d,0x6f,0x52,0x2d,0x20,0x02,0x70,0x22,0x27,0xdf,0x7a,0xff,0x30,0x36,0x66,0x1a,0xa0,0x51,0xc3,0x75,0x9a,0x06,0xe5,0x3f,0x6c,0x74,0x0d,0x15,0xa2,0xb6,0xe5,0xcd,0x55,0x4d,0xea,0x65,0x8f,0xbb,0xb2,0xd4,0x95,0x73,0xa4 +.byte 0xcd,0xb9,0xc8,0x82,0x60,0x49,0xe9,0x36,0xc9,0xb1,0xe9,0xcb,0x52,0xae,0xa7,0x7a,0x64,0xab,0x75,0x84,0x03,0x4b,0x37,0xf7,0x07,0x75,0xf7,0x1c,0x32,0x19,0xb6,0x8b,0xca,0x7c,0x43,0x15,0xe8,0xec,0x57,0x89,0x1d,0xe2,0xa0,0x80,0xc5,0xb6,0x02,0x29,0xfd,0xda,0xe0,0x14,0x93,0xb4,0xb3,0x44,0x2e,0x17,0x2f,0xed,0x3b,0x38,0x6e,0x8f +.byte 0xe0,0x3d,0xc6,0x77,0xe9,0xa7,0x76,0xcb,0x98,0x2d,0x08,0x61,0xcf,0x1b,0x25,0x3f,0xfb,0x1d,0x99,0xb1,0x5a,0x3c,0x53,0x96,0x4e,0x09,0x11,0xf6,0x5b,0x09,0x31,0xe1,0xad,0xb0,0xaf,0x7b,0xec,0xf9,0xa8,0x68,0xb7,0x93,0x57,0xf7,0x17,0x77,0x87,0x2b,0xdb,0x00,0x28,0xc6,0x48,0xac,0xff,0xcd,0x26,0x4a,0x8a,0x76,0x9a,0x2a,0x1d,0x37 +.byte 0x4c,0x70,0x4f,0xf6,0x52,0xe3,0x7a,0x78,0x94,0x5b,0x0b,0x50,0xb4,0x48,0x03,0xcd,0x78,0xd0,0x5d,0x89,0x6d,0x76,0xaf,0x9d,0x67,0xc3,0x75,0x6f,0x6a,0x2d,0xe2,0xb7,0x58,0x51,0x10,0x0d,0xef,0xa0,0x1a,0x74,0x28,0x3a,0x97,0x19,0x4f,0x3c,0x8a,0x86,0x3d,0xe4,0x66,0x3d,0x57,0xb4,0x66,0xb3,0x0b,0x4f,0x57,0x57,0x34,0x2e,0xc7,0x0c +.byte 0x11,0xdf,0x3c,0xb4,0x9f,0xe1,0xd5,0x27,0x41,0x08,0xec,0xca,0x18,0x88,0x48,0x5e,0x88,0x55,0x89,0x71,0xe6,0xa5,0x90,0x7c,0x3b,0xe5,0xf3,0x2a,0xd7,0xf5,0x0b,0x3d,0xbb,0x47,0xad,0xd7,0x78,0x41,0xa8,0xef,0xd4,0x36,0x31,0xd1,0xe4,0x9c,0x87,0x9e,0xb1,0x11,0x0e,0xff,0x8f,0x4d,0x79,0x65,0xc4,0x83,0x75,0x33,0xc9,0x89,0xe2,0xc3 +.byte 0x41,0x68,0x11,0xe7,0xe4,0x58,0xb9,0xf1,0xee,0x06,0x48,0x4d,0xc3,0xc7,0x76,0x60,0x42,0x94,0x8f,0x0d,0xb9,0x53,0x46,0x78,0x06,0x97,0x94,0x36,0xf4,0x3e,0xf3,0xdd,0x5b,0x46,0xe1,0x9d,0x3f,0x9e,0x78,0x00,0x9e,0xe7,0xcb,0x9e,0xc8,0x30,0x87,0x4a,0x52,0x91,0xd5,0xe2,0xa3,0x65,0x98,0xb2,0xc9,0x6c,0xfb,0x4e,0x54,0x5a,0x9f,0x57 +.byte 0x2c,0x4a,0x76,0xe4,0x97,0x88,0xd5,0x6a,0x0e,0x6c,0x7c,0xef,0x78,0x2a,0x7c,0x26,0xa3,0x25,0xf6,0x33,0x82,0x46,0x6d,0x91,0x0d,0xe4,0x83,0xec,0xf1,0x24,0xf8,0x0a,0x34,0xec,0xfc,0x7e,0x47,0xda,0x9a,0x17,0x1b,0x33,0xd0,0xf1,0x70,0xe4,0x0b,0xc7,0x70,0x58,0x1d,0x76,0x20,0x89,0xce,0x4f,0xd1,0xcb,0x3b,0x26,0xd1,0x98,0xd9,0x51 +.byte 0xb1,0xd0,0xaa,0x4a,0xd5,0x10,0xf2,0xae,0xaa,0x14,0xa7,0x72,0x99,0x3d,0xc8,0xbf,0xfb,0xec,0x6a,0x14,0xdd,0x97,0x7b,0x2f,0x16,0x96,0x0f,0x41,0xb8,0x33,0x15,0x1b,0xa2,0x6a,0x7e,0x64,0x0d,0xab,0xe7,0x62,0xf5,0x6c,0x56,0x69,0x09,0x46,0x32,0x24,0x60,0x4e,0x21,0xc7,0x5b,0xee,0x0a,0xe2,0x94,0x7c,0x20,0xe2,0x06,0xa0,0xa2,0x36 +.byte 0xa0,0x7d,0xb5,0x37,0x2a,0xee,0x20,0x25,0x4c,0xba,0x9a,0x06,0x4c,0x07,0x9b,0xea,0x55,0xac,0x2a,0xf7,0xb9,0x5c,0x23,0xac,0x43,0xda,0x9d,0xad,0x76,0xe2,0x5f,0xe0,0x27,0xaf,0x0a,0x5e,0x3d,0x54,0x84,0xfc,0x19,0x75,0x8c,0x62,0x4d,0x37,0x17,0x1a,0x90,0x55,0xb8,0x7e,0xa1,0xad,0x31,0x1a,0xc0,0x91,0x96,0x51,0xa9,0x5f,0xbb,0xb9 +.byte 0x95,0xbf,0xe2,0xd5,0x7e,0x31,0xba,0xc4,0x1e,0x63,0x98,0xd3,0xe2,0x7d,0x87,0xa5,0x46,0xe3,0xae,0xe1,0xe8,0x4e,0x74,0x29,0x0e,0x4b,0x10,0xa8,0x7f,0x3a,0xe5,0x60,0x0f,0x49,0x6a,0xcd,0x3d,0x5a,0x8e,0xf1,0x48,0xd0,0x80,0x7b,0xa3,0x7f,0x06,0x47,0x2b,0x60,0xf2,0x17,0xc3,0xe1,0x26,0x1e,0xb7,0x0f,0x2b,0x7c,0xc7,0xb8,0x3a,0x4f +.byte 0xad,0x05,0x97,0x88,0x93,0x82,0x8e,0x06,0x77,0x44,0xd1,0x65,0xfd,0x18,0x48,0xd6,0x88,0xcd,0x5c,0xbd,0xe4,0xaa,0xea,0xf1,0xed,0x16,0x5f,0xb3,0x58,0xe2,0x69,0x82,0xbe,0x9e,0xfc,0xcb,0xf6,0x17,0xa9,0x70,0xeb,0x08,0xd7,0x06,0x86,0xf6,0x5a,0x43,0x68,0x7b,0xcf,0xa3,0xfa,0x26,0x5e,0xe5,0x42,0xd3,0x5a,0xc8,0x1c,0x3b,0x8d,0x2d +.byte 0xf1,0x45,0xb0,0x97,0x90,0x0b,0xe7,0x2d,0xab,0xd7,0xd8,0x8a,0x16,0xf9,0x5f,0xa6,0xcf,0xc5,0x60,0x2c,0x34,0x5a,0x2e,0x2b,0xb9,0xb4,0x9c,0xa7,0x09,0x77,0xd2,0x3f,0x8c,0xf3,0xf6,0xf7,0xe0,0x27,0x79,0xc3,0x4e,0x61,0x7d,0x09,0x50,0x05,0x01,0x35,0x1b,0x33,0x54,0x6f,0x90,0x9a,0x19,0xcd,0x86,0x45,0x23,0xcd,0x6f,0x1b,0x62,0xc5 +.byte 0xce,0x4e,0x8e,0xff,0xe7,0x12,0x32,0x85,0x9a,0xc4,0x11,0x83,0xcf,0x78,0xd7,0x41,0x99,0x64,0x20,0xa6,0x69,0xdd,0xe3,0x53,0x98,0x6b,0xc7,0x98,0x51,0xc5,0xf8,0x3e,0xa3,0x5f,0x0d,0x78,0x2f,0xa7,0x05,0xff,0xe5,0x3a,0x0f,0x7c,0x09,0x58,0x3f,0xaa,0x0d,0x9a,0x9d,0x8d,0xe7,0xbf,0x6b,0x7d,0xfe,0x3a,0x4f,0x5c,0x50,0xb2,0xe7,0xc5 +.byte 0xa5,0x13,0xde,0xc8,0xe8,0x59,0xac,0xb0,0xdd,0xc0,0x81,0xa7,0x0b,0x78,0x32,0x23,0x76,0x85,0x11,0xef,0xe3,0x88,0x6f,0x7f,0xa9,0x09,0x7b,0x0c,0x6f,0x34,0xb2,0x67,0x5e,0xd6,0x11,0xad,0xd7,0x3b,0xf2,0xbb,0x66,0x5b,0xde,0x22,0xfc,0x55,0x26,0xa1,0x89,0x80,0x2e,0xb8,0xf3,0x3c,0xf8,0x1e,0xba,0x99,0x1c,0x24,0x33,0xb4,0xe6,0x17 +.byte 0x2b,0x9c,0x80,0xe5,0x9b,0x58,0x54,0x70,0xcd,0x15,0x81,0xcd,0x51,0x48,0x75,0x24,0x27,0xf5,0x30,0x79,0xc1,0x16,0xff,0x89,0x70,0x12,0x74,0x07,0x9d,0x39,0xf2,0x9c,0xc6,0x89,0x8d,0x94,0x41,0x01,0x04,0xf5,0x16,0x99,0xf3,0xf0,0xd1,0xf5,0x6d,0xd3,0x11,0x19,0x29,0x36,0xfb,0x41,0xf9,0x32,0xb9,0x0f,0x13,0xaf,0xac,0xfb,0x30,0x75 +.byte 0x62,0x8c,0x04,0x5b,0xf1,0xce,0x52,0x9b,0xbe,0x8c,0xf9,0x86,0x5d,0x7d,0xc1,0x8e,0x41,0x76,0x42,0x63,0xd7,0x74,0x8e,0x2c,0x46,0xa1,0x0a,0x51,0xb5,0xec,0xe9,0x91,0x56,0xbc,0xdc,0x32,0xfc,0x10,0xb5,0xca,0x5b,0x4b,0x72,0x99,0x07,0xff,0x01,0x11,0x2c,0xa4,0x60,0xf5,0x6b,0xd4,0xa8,0x96,0x21,0xee,0xbe,0x14,0x8f,0x69,0x99,0xdc +.byte 0x43,0x7f,0x13,0x3d,0x17,0x1e,0xa3,0x1b,0x21,0x23,0x26,0x7e,0xff,0x80,0x6b,0x66,0x3e,0xb2,0x48,0x1a,0x77,0x3c,0x50,0xe2,0xca,0x4d,0xc6,0xdb,0xfd,0xd1,0x23,0xcc,0xcb,0x01,0x25,0xc0,0x62,0x8d,0xe5,0x9c,0xb7,0x13,0x97,0xf5,0x49,0x01,0x19,0x45,0x45,0x83,0x17,0xff,0x8e,0x94,0x8c,0xb0,0xc0,0xaf,0x46,0x62,0x0e,0x62,0xb7,0x8c +.byte 0xd5,0xcf,0xb9,0x82,0x6e,0x8a,0xb9,0x22,0xbc,0x30,0xf9,0x65,0xc2,0x7f,0xce,0x6b,0x4d,0xad,0x87,0xcb,0x23,0xab,0x57,0x36,0x6a,0xb7,0x8c,0x63,0x17,0x60,0x13,0xa1,0x1f,0x3d,0xa4,0xd4,0xab,0x5d,0x97,0xc7,0x18,0xaf,0xf8,0xae,0x13,0x64,0x2a,0x19,0x34,0xe2,0x28,0x28,0x4f,0x32,0x2a,0xd8,0x43,0x79,0xaf,0x1e,0x56,0xfc,0x97,0x51 +.byte 0x67,0x8c,0x63,0x80,0x32,0x63,0x71,0x5c,0x78,0x00,0xeb,0xfd,0xa2,0x96,0x58,0x21,0x36,0x13,0x02,0xe5,0xa4,0xb7,0xcd,0x5a,0x30,0xa0,0x5b,0x7b,0x23,0xa4,0xcc,0x54,0x64,0x6f,0x6d,0x9b,0xaf,0xea,0x49,0x69,0x9e,0x2f,0x51,0x5c,0xe7,0xa3,0xa3,0xb8,0xac,0xed,0x47,0x23,0x7a,0x37,0x38,0xe3,0x15,0x98,0x6f,0x50,0x6c,0x8d,0xa7,0xe6 +.byte 0xa8,0x39,0xcc,0x63,0x08,0xeb,0x8f,0x8c,0xfd,0x83,0xaa,0x34,0x75,0x19,0xc0,0xf4,0xd6,0x25,0x18,0x94,0x9d,0xa1,0x7e,0xc8,0x6b,0x19,0x76,0xc0,0x8d,0xaf,0x51,0xe5,0x7c,0x8a,0x98,0x17,0x80,0x90,0xc0,0xb6,0xed,0x5c,0x8f,0x33,0x56,0xba,0xce,0xbe,0x83,0x87,0x5d,0x51,0x2e,0x64,0x84,0xa6,0x9d,0x49,0x27,0x5b,0x92,0xe0,0xe7,0xac +.byte 0x37,0x3d,0x22,0x5e,0x25,0xe7,0xca,0x2f,0x5d,0x2f,0xa0,0xd5,0xcb,0xe9,0xac,0x84,0x5b,0x19,0x72,0x1c,0x2c,0x0a,0xd1,0xb7,0x73,0x24,0x8a,0x0f,0xe0,0x07,0xd8,0x49,0x4d,0x23,0x1b,0xac,0xb8,0xd1,0x42,0xd4,0xdf,0xf8,0x4d,0x85,0xa2,0x37,0x30,0x46,0x38,0x88,0x55,0x1d,0xea,0x37,0x54,0x8c,0x43,0xb0,0xed,0x01,0x53,0x75,0xe6,0xf7 +.byte 0x9b,0xe6,0x10,0x91,0x6e,0x80,0x11,0xf9,0x96,0x29,0x4f,0x08,0x77,0x2b,0x7e,0xdb,0x5b,0x14,0xbd,0x77,0x37,0xe8,0x36,0x07,0x4a,0xe4,0xd8,0xa2,0x4e,0x38,0xea,0xeb,0xc2,0xd6,0x43,0x59,0x20,0x0c,0x12,0x31,0x6c,0x27,0xc5,0x7b,0xfc,0xfc,0x54,0x94,0x1d,0x5f,0x82,0x73,0xd7,0x1f,0x43,0x3a,0x73,0xc4,0xf3,0xb3,0xbb,0x53,0xfe,0x22 +.byte 0xc0,0xa4,0x7e,0x2b,0x84,0x1b,0xef,0x6d,0x83,0x9d,0xb3,0x8b,0x2a,0x6c,0xea,0x1e,0xfa,0x77,0x01,0x35,0xd2,0x5b,0xc4,0xd3,0xe7,0x1e,0xca,0x73,0x8b,0xb9,0x1f,0xfb,0x67,0xf2,0xdd,0x03,0xe6,0xca,0xfe,0x3b,0x61,0xd7,0xb5,0x96,0xe0,0x85,0xc2,0x23,0xa7,0xea,0x38,0xbf,0x6e,0x29,0x9e,0x8e,0x18,0xd4,0xbf,0x16,0x73,0xf9,0x18,0xef +.byte 0xc9,0xaf,0x6c,0xe2,0xdc,0xa4,0x58,0x9c,0xf5,0x6d,0x4a,0xc8,0xb4,0x8f,0x16,0x02,0xb7,0x65,0xd3,0x32,0x3b,0x83,0xfe,0xf3,0xc7,0xba,0x68,0xf4,0x95,0xa4,0xf6,0x33,0x57,0x43,0xbe,0xae,0x83,0xa9,0xe4,0x0d,0x0b,0x23,0xaa,0xbc,0x15,0x53,0x18,0x4d,0xb4,0x35,0xe3,0x8e,0x86,0xfe,0xe4,0x98,0x5d,0x63,0x23,0xce,0x44,0xea,0x4d,0x64 +.byte 0x86,0xf8,0x06,0x8f,0xc0,0x73,0xa6,0x6d,0x04,0x53,0x47,0x95,0x0f,0x6d,0x6c,0x01,0x1c,0x3f,0x7b,0x83,0xe4,0xc2,0x40,0xb8,0x97,0x26,0x9e,0x35,0xb0,0x76,0xee,0xe4,0xc7,0xd8,0xaa,0x22,0x83,0x96,0xe1,0x34,0x7b,0x78,0x31,0xee,0xd3,0x9a,0x50,0xd4,0x05,0xfd,0xd6,0x15,0xca,0x83,0x2f,0x49,0xfd,0x00,0x23,0x82,0x39,0xac,0x46,0x7a +.byte 0xe4,0xb5,0xcc,0xee,0xbb,0xaa,0x98,0x82,0xb5,0x27,0x45,0xd5,0x96,0x6e,0x89,0x01,0x1e,0x30,0xe4,0x1c,0x3a,0x65,0xcc,0x9f,0xda,0x38,0xf0,0x4c,0x68,0xfa,0xe5,0xf2,0xe2,0xce,0x34,0xc2,0x15,0xfd,0x21,0xf6,0xe2,0x33,0xbd,0xef,0xfd,0x49,0x15,0xdc,0x38,0x3b,0x24,0xba,0x3a,0x80,0x35,0x60,0xbe,0x50,0x17,0x38,0x3e,0xe2,0x96,0x84 +.byte 0x01,0x41,0x6c,0xb2,0x0b,0xc6,0xff,0xce,0xb3,0x37,0xa2,0x46,0x27,0x33,0x8e,0x04,0x44,0x8a,0x7c,0x64,0x0e,0xbc,0xed,0x74,0x4f,0x40,0x58,0xf4,0x8c,0xf8,0xd9,0x92,0xa9,0x0b,0x18,0x7c,0x93,0x95,0xca,0xa7,0x3e,0x1d,0xad,0x68,0x80,0xd9,0xdb,0x81,0x78,0x50,0x37,0x49,0xbc,0x64,0xc2,0x52,0x5c,0x70,0x7e,0x0a,0x26,0x7e,0xc6,0xbf +.byte 0xd2,0x7f,0x05,0x55,0x7a,0x5a,0x3e,0x9e,0xe3,0x8b,0xf5,0x95,0x2b,0xd8,0xb4,0xb8,0xc6,0x5d,0x91,0xb8,0xc7,0x7c,0xe1,0x75,0xf2,0x43,0x6b,0x73,0xb7,0xb1,0x10,0xf2,0xa7,0x1e,0xab,0xaf,0xc9,0xc0,0x3b,0xab,0xbe,0xf7,0x4a,0x43,0x9c,0xca,0x3d,0x00,0x5b,0x02,0xf8,0xa2,0x4f,0x57,0x81,0xb0,0xde,0x1e,0xd1,0x60,0xbe,0x6c,0x0d,0xe6 +.byte 0xcd,0x51,0xb6,0xc7,0x00,0x52,0x37,0x4f,0xfc,0xee,0xe2,0x43,0x5c,0x61,0x76,0xed,0x80,0x72,0x38,0x26,0x94,0xfe,0x28,0x06,0xfb,0x62,0xa6,0x21,0x9b,0x53,0x60,0x1b,0xf0,0x56,0xae,0xba,0x6b,0x52,0x27,0x2a,0xd5,0xed,0x11,0x92,0xa2,0xe2,0xab,0xdd,0x05,0x38,0x38,0xae,0xeb,0x72,0xcb,0x6c,0xa5,0x2a,0x73,0xc5,0xfc,0xb0,0x36,0x83 +.byte 0xd6,0xe6,0xda,0x6b,0x38,0x72,0x5e,0x8d,0xaf,0x11,0x5f,0x5b,0x89,0x58,0x21,0x36,0xf6,0x7d,0x42,0x48,0xdc,0xce,0xaa,0x94,0xf0,0xc3,0xc5,0x2c,0x08,0x2a,0x36,0x35,0x25,0x95,0xc4,0x11,0x09,0xea,0x7a,0xbc,0x2e,0xc6,0x0a,0x5b,0x4f,0x86,0xeb,0xc2,0x38,0x71,0x48,0x8c,0x63,0x79,0x3b,0xe4,0xba,0x14,0x44,0x31,0x28,0x4f,0x9d,0xb4 +.byte 0x26,0xa6,0x3b,0xea,0x3f,0xcb,0x30,0x6c,0x02,0x13,0xdb,0x4c,0x9c,0x76,0xc8,0xd8,0x01,0x52,0x3d,0x2f,0x51,0x70,0x15,0x91,0xec,0x8f,0x80,0xed,0x88,0xb7,0xfa,0x91,0x2c,0x10,0xcd,0x3b,0x92,0x85,0xe7,0xe8,0x11,0xfa,0x50,0x15,0xe2,0xdf,0xf7,0xbe,0xa4,0x2d,0x13,0x75,0xa6,0x00,0x25,0x8d,0xe1,0xb6,0x9b,0xbb,0x64,0xfb,0x5c,0xde +.byte 0x97,0xcc,0x00,0x51,0xd6,0xac,0x67,0xc3,0x91,0x1e,0x56,0x36,0x2b,0x43,0xed,0x8c,0x67,0x7b,0xf6,0x54,0x6f,0x91,0x44,0x28,0x93,0x60,0xac,0xca,0xb9,0x91,0x7e,0xeb,0x49,0xd8,0xfc,0x12,0x6c,0x40,0x9d,0x0a,0x4d,0xb4,0xab,0xe6,0xad,0x5b,0x8e,0x2d,0x3e,0x53,0xa1,0x88,0xf7,0x41,0x71,0xa7,0xff,0x05,0x46,0x04,0x34,0x1f,0x12,0x89 +.byte 0x92,0xc1,0xf9,0x26,0x16,0x23,0xb6,0x59,0x82,0xdc,0xa7,0xb8,0xa4,0x8a,0x0f,0x1d,0x7d,0x8f,0x44,0xe8,0x4f,0x70,0xbb,0xdb,0x8d,0xe6,0x7e,0x9d,0xd9,0x44,0x10,0x41,0x6c,0x3f,0xb7,0xe8,0x6f,0x39,0x93,0xe1,0xde,0xb8,0x6c,0xba,0x99,0x95,0xb7,0xc8,0xb2,0x2a,0xcd,0x81,0x53,0xc3,0xb5,0x2a,0x8a,0xd6,0x62,0x1e,0x74,0x4d,0xde,0xfa +.byte 0xff,0x7b,0xed,0x11,0x1e,0x44,0x3e,0x93,0x1c,0xae,0x7c,0x5c,0xed,0x52,0x75,0x5e,0x0a,0xf3,0x95,0xce,0x47,0x86,0x1b,0x7f,0x17,0x09,0x12,0xcc,0x08,0xca,0x16,0x11,0xf1,0xa1,0x39,0x78,0x89,0x5c,0x11,0x25,0xc7,0x39,0x5f,0x97,0x74,0xbc,0xa9,0x2a,0x25,0x5d,0xdd,0x93,0x0d,0x8c,0x74,0x07,0x1e,0xd9,0x9f,0xc1,0x38,0x9c,0xbf,0xe0 +.byte 0x42,0xad,0xb2,0xe7,0xb1,0x84,0x82,0xb4,0x56,0xbe,0x3c,0x42,0xb0,0xce,0x2c,0x94,0xb7,0xe6,0x78,0xc8,0x04,0x06,0x58,0x15,0x3e,0xdc,0xf6,0x9a,0x58,0xc3,0xe3,0x85,0x16,0xc8,0x84,0xba,0x8f,0xbc,0x94,0xa7,0x44,0x04,0x29,0xc4,0xd8,0xec,0x63,0xc4,0x47,0x58,0x22,0x02,0x08,0x20,0x44,0x39,0x52,0xa5,0x33,0xfe,0x1c,0x30,0x27,0x92 +.byte 0xbf,0x42,0x44,0x4c,0x3f,0x3d,0x00,0x7b,0x21,0xef,0xbb,0x25,0x75,0x4c,0xb2,0xe7,0x66,0xc9,0xc1,0xfb,0x1e,0x13,0x04,0xd0,0xcb,0x69,0x51,0x9d,0x9a,0xb0,0xb0,0xec,0xb0,0x12,0x24,0x84,0x57,0x9f,0xef,0xb4,0x19,0x50,0xa6,0xf5,0x03,0xa3,0x93,0x0f,0x77,0xaf,0xe0,0x4c,0xa5,0xd3,0xb0,0xd8,0x5e,0xc3,0x78,0x94,0xd5,0x6e,0x48,0x58 +.byte 0x7a,0x93,0xb1,0x62,0x60,0xea,0xa1,0xba,0x7a,0x86,0x6e,0x87,0xe9,0x97,0xe0,0x7c,0x1e,0xb6,0x63,0x94,0x76,0x5f,0x9c,0x95,0x65,0x00,0xd4,0x14,0x0e,0x4c,0x87,0xe7,0xcd,0x9e,0xb1,0xe2,0x13,0x1b,0xb1,0x8a,0x83,0xaa,0xaa,0x34,0xcd,0xb2,0xf6,0x7f,0x12,0xb0,0x79,0xff,0x1e,0x04,0xc8,0x9a,0xfc,0x41,0x88,0xbb,0x28,0x42,0xeb,0x45 +.byte 0x47,0x8b,0xcb,0x57,0x03,0xcd,0xe5,0x9a,0x84,0xea,0x0a,0xb5,0x0c,0xb8,0x30,0x33,0xd6,0xde,0x66,0xa8,0x57,0xf9,0x76,0x4f,0x0f,0x8f,0x53,0x56,0x57,0x91,0xd4,0x55,0xf5,0x78,0xde,0xa6,0xa2,0x59,0xc8,0xb0,0xf2,0xb9,0xfa,0x6d,0x4a,0x70,0x86,0x3d,0x24,0x1b,0xc6,0xb8,0x06,0xf5,0xea,0x09,0x63,0x9b,0x1e,0x61,0x18,0x85,0xba,0x08 +.byte 0x20,0xaa,0x33,0x66,0xcf,0xa7,0xff,0xf5,0x30,0xfe,0xf8,0x39,0xd3,0x88,0x9a,0x5b,0x3f,0x55,0xa6,0x00,0x4c,0x57,0x0d,0xd1,0xa4,0x0c,0xe7,0x8a,0x95,0xd8,0x64,0xc7,0x93,0x51,0x84,0xa6,0x41,0x2c,0xfc,0xb0,0xfb,0x99,0x9a,0xcd,0x2c,0x62,0x3a,0xca,0x43,0x15,0xf2,0x5a,0x22,0x25,0xa4,0x91,0xa3,0x7c,0x42,0x69,0xc1,0x67,0xe3,0xf5 +.byte 0xd4,0x92,0x54,0xbd,0xb3,0x57,0xe5,0x19,0xca,0x1b,0x9c,0x19,0x79,0x9d,0xbf,0x89,0xfc,0xaa,0x72,0xcd,0xcb,0xc5,0xbc,0xdd,0x0c,0x7c,0x31,0x42,0xb0,0xc2,0x76,0xe5,0x8b,0x9b,0x7c,0x92,0x13,0x20,0x5c,0xdc,0x94,0xfc,0xa1,0x90,0x34,0x27,0x88,0x9f,0xe5,0x97,0x5f,0xc3,0xa3,0x83,0xca,0x8b,0xf8,0xac,0x36,0x33,0x47,0xc6,0x20,0x2f +.byte 0x04,0x2d,0x13,0xc1,0x3c,0x07,0x6e,0xf0,0xe2,0x3d,0x32,0x5c,0x50,0x41,0xf2,0x92,0x3f,0x25,0x2c,0x80,0x34,0xa5,0x90,0x2b,0x97,0x6e,0xd1,0xa2,0xa6,0xf4,0x4a,0xe0,0x20,0xd9,0xb9,0x2b,0x66,0xe5,0x06,0x73,0x97,0xfe,0x80,0x70,0x28,0xf9,0xb6,0xae,0x93,0x27,0x7a,0x65,0xff,0x23,0xc1,0x78,0x18,0x92,0xc9,0x0b,0x05,0x82,0x93,0xbc +.byte 0x73,0x3f,0x98,0xe9,0xa0,0x6d,0x20,0x8d,0x13,0xb1,0xf0,0x7e,0xe4,0x07,0x21,0x7d,0x6d,0xea,0x03,0x59,0xf8,0x29,0xc0,0xc8,0x7d,0xce,0xd1,0xf8,0x67,0x82,0x7f,0x84,0xe8,0x77,0xa9,0x9c,0xa2,0x34,0xdf,0xa9,0xac,0xec,0x6d,0x54,0xe5,0x0f,0xcb,0xdb,0x86,0xbc,0x01,0x44,0x91,0x3b,0xc8,0x85,0x4e,0x1d,0xe4,0x74,0x19,0xc6,0x39,0x2e +.byte 0xdf,0xf2,0x8f,0x3a,0x7f,0xe3,0x1e,0x55,0x45,0xcb,0x7e,0xde,0xcd,0xa6,0x1c,0xef,0x20,0xf7,0x07,0x31,0x94,0x9a,0x3d,0x04,0xd7,0x5e,0x65,0x20,0x6a,0x4d,0x31,0x1e,0x6f,0x89,0x40,0x45,0x1f,0x37,0xc1,0x7e,0x07,0xd5,0xa6,0x38,0x4a,0xf1,0x39,0xae,0x72,0x26,0x60,0xb0,0xb5,0xc7,0xd3,0x9a,0xaf,0x57,0x12,0xe9,0x34,0x28,0x8b,0xaf +.byte 0xd8,0x62,0x24,0x58,0xe2,0xcd,0xa2,0x9e,0x74,0x23,0x2d,0x52,0xc7,0x09,0xe5,0xb5,0xf5,0xc1,0xd3,0xa3,0x19,0xe5,0x1d,0x8d,0x0c,0xdf,0x13,0x8d,0xa4,0xa7,0xc1,0x41,0xea,0x9e,0x6d,0x61,0xd4,0xa4,0x74,0xe5,0xf8,0x5f,0x9e,0xfd,0x6d,0xf6,0x6e,0x87,0x0f,0xb5,0xa3,0x82,0xac,0x64,0xb4,0xda,0x07,0x49,0x51,0xc2,0xfd,0xcb,0x55,0xa3 +.byte 0x59,0x34,0xdf,0xa1,0xd6,0x90,0x62,0x43,0x1a,0xf9,0xae,0x85,0x5c,0x11,0x40,0xb2,0xbe,0xa5,0x03,0x04,0x4f,0xec,0x2c,0x58,0x2d,0xe9,0xda,0xcf,0xaa,0x2f,0xcf,0x60,0xc3,0x2c,0x6c,0x81,0x4d,0xf2,0x71,0x41,0xe4,0xae,0x4c,0xfa,0x8e,0x05,0x10,0xff,0x40,0xfa,0xea,0x96,0x78,0x6e,0xfc,0x35,0x35,0xec,0x84,0xf6,0x1d,0x24,0x60,0xcd +.byte 0x96,0x21,0x21,0xa7,0x32,0x90,0x3d,0x51,0x72,0x13,0xa4,0x9b,0x7e,0x94,0x3a,0x9d,0x97,0xf6,0x68,0xd8,0x08,0x42,0x54,0x7a,0xbb,0x9a,0x95,0x83,0xac,0xb8,0xb4,0x68,0xe3,0x31,0xdb,0xe2,0x32,0x8b,0x7d,0x57,0x62,0x1d,0x61,0x81,0xa1,0x36,0x7a,0x25,0x00,0x72,0x24,0x4c,0xa7,0x96,0x3b,0xa5,0x82,0xba,0x8e,0x89,0x1e,0x1b,0x8e,0xf4 +.byte 0xab,0x91,0x85,0x7a,0x32,0x4a,0x47,0x9f,0xce,0xd2,0x51,0x77,0xcd,0xc9,0x02,0x54,0xf2,0x7b,0xcb,0xb8,0x83,0xe0,0xe0,0x1b,0x4a,0xa2,0xe0,0xd9,0x15,0xb6,0x02,0x19,0x75,0xa6,0xba,0xa6,0x98,0xd9,0x61,0x74,0xc6,0x48,0xa5,0x59,0x3d,0xc8,0x47,0xc9,0xe8,0x6b,0xbb,0x6d,0xcf,0x0e,0x8d,0x6b,0x58,0x8b,0x7d,0x4e,0x0b,0x3d,0x67,0xc4 +.byte 0x8e,0x78,0x59,0x40,0x88,0x82,0x33,0x27,0x2c,0xfe,0x2a,0x6c,0xe4,0x80,0xee,0x5a,0xd4,0x5f,0xc8,0xf7,0x82,0x02,0x67,0xfd,0xcb,0x55,0x3e,0xd8,0x41,0xb3,0xce,0x93,0xfe,0xe7,0x56,0xf5,0x63,0xba,0xfa,0x2e,0x79,0xfc,0x11,0x5d,0xb0,0xc6,0x32,0x54,0xed,0x71,0x9b,0x15,0xce,0x62,0x09,0xd4,0x28,0x7f,0x7b,0xa1,0x50,0x5b,0x46,0x24 +.byte 0x0e,0x40,0xa2,0xe2,0x7d,0x93,0xa6,0x2b,0x0b,0x9b,0x40,0x25,0xc9,0xca,0x7a,0x01,0x8b,0x7d,0x68,0xeb,0xd7,0x84,0xc1,0x9d,0xf9,0xfb,0xd0,0x1a,0xec,0xef,0x6b,0x4c,0x78,0x31,0x62,0x8e,0x9d,0xdc,0x78,0x8f,0xcb,0xf8,0xf9,0x41,0xdc,0x9f,0x6d,0x0a,0x27,0x67,0xce,0xbd,0xeb,0x87,0xb3,0x26,0xf3,0x51,0xe1,0xd6,0xd1,0x57,0x46,0xfe +.byte 0x21,0xb9,0x88,0x7c,0xdd,0xa2,0x49,0x71,0x24,0xfb,0xc4,0xc0,0x6a,0x6b,0x05,0x7f,0x80,0xb0,0x09,0x3b,0x9e,0x6c,0x59,0x31,0x3e,0xac,0x7a,0x2e,0x5c,0x04,0x03,0xa3,0x6e,0xf5,0x66,0xee,0xc2,0x9b,0x65,0x88,0x06,0xbf,0xf5,0xe3,0x23,0x73,0x38,0x88,0x99,0xf1,0x64,0x68,0xdf,0x7d,0x04,0x06,0x72,0x92,0x0b,0x62,0x5d,0x12,0x1e,0x4e +.byte 0xff,0x60,0x35,0xe3,0x0f,0xd9,0x8c,0xac,0x38,0x5b,0x91,0xc1,0x51,0xbb,0xa5,0x19,0x7d,0xfb,0x79,0xfa,0x42,0x3b,0xaa,0xf8,0xd3,0x0f,0xc3,0xf2,0xb2,0x68,0x91,0xae,0x28,0x83,0x4f,0x75,0xbd,0x20,0x5f,0x20,0xba,0xc2,0x75,0x85,0x74,0x23,0xf3,0x36,0x33,0x99,0x9c,0x64,0x4c,0xd1,0x5d,0xbd,0x06,0x46,0xbd,0x49,0xf0,0x86,0xc0,0xcb +.byte 0x1b,0xbd,0xec,0x98,0x5b,0xb1,0x80,0xba,0x12,0x42,0x22,0x09,0x9a,0x62,0x3c,0xa8,0x33,0xbf,0xce,0x92,0xd4,0x07,0xef,0x34,0x33,0x8f,0x67,0x1d,0x25,0x60,0xeb,0xd3,0xe4,0x31,0x63,0xa8,0xab,0xe3,0xab,0x70,0x50,0xd8,0x44,0x9f,0x39,0x51,0xd2,0xb9,0x4b,0x16,0xe4,0xfa,0xc5,0x47,0xf3,0xae,0xb5,0xfe,0x7d,0x5d,0x43,0x28,0xa6,0x3d +.byte 0xcf,0x71,0x23,0x6d,0x8e,0xd7,0x74,0xa4,0x86,0x9f,0x92,0x86,0x3c,0x1e,0x51,0xd4,0xe0,0xe6,0xd5,0xc4,0x53,0x3c,0x96,0x55,0xb9,0xac,0x63,0x5b,0xee,0x5a,0x03,0x84,0xb9,0x43,0x2c,0x0f,0x6d,0xbb,0xb5,0xca,0xf0,0x4f,0x3e,0x8b,0x3b,0x14,0x01,0x0e,0x81,0x0d,0xe6,0x62,0xa9,0x34,0x4e,0x03,0xc9,0x85,0x9f,0xc8,0x4f,0x52,0x3f,0x84 +.byte 0x1b,0xab,0x7e,0xaf,0x93,0x22,0xe2,0x0d,0x41,0x79,0x50,0xb2,0x17,0xa7,0x9a,0x80,0xd5,0x65,0x40,0x3b,0x56,0x9b,0xc9,0x00,0xcf,0x03,0xf1,0xff,0xcd,0x72,0x27,0xdb,0x74,0x94,0x70,0x02,0xdc,0x3a,0xee,0x00,0xcc,0x08,0x0a,0xab,0x40,0x87,0x24,0xaf,0x7d,0x67,0x18,0xd0,0x7c,0xeb,0x91,0x1f,0x7e,0x9e,0x41,0x7b,0x39,0xf2,0xfe,0xaf +.byte 0xb7,0x6c,0x58,0xe0,0xdb,0xf7,0xf1,0x23,0x0b,0x98,0x08,0xfa,0xde,0xfa,0xf9,0x24,0x23,0xd1,0x7f,0x69,0xd3,0xb1,0x82,0x68,0x03,0x06,0x86,0x7a,0xf4,0x90,0x8d,0xa5,0xbd,0xbe,0x14,0x2f,0xa2,0x5e,0xaf,0x5c,0x1e,0x07,0x68,0x19,0x5a,0xd3,0x53,0x7d,0xe8,0x13,0x6b,0xe3,0x02,0x49,0x0d,0xd2,0x96,0x56,0xae,0x67,0x8a,0x27,0x61,0xa0 +.byte 0x60,0x20,0x2c,0xb4,0x5d,0xdf,0xc3,0x24,0x50,0xa9,0xbc,0x3d,0x5c,0xf3,0x2e,0xb6,0xba,0x71,0xf0,0x04,0x43,0x84,0x4d,0x80,0xe9,0xa5,0xdd,0xb3,0x1e,0x5e,0x56,0x32,0x1a,0xd4,0xe3,0x10,0x57,0x35,0xa8,0xf1,0xe5,0x96,0xc1,0x27,0xef,0xcc,0x21,0x71,0x10,0xd1,0x07,0x7e,0xb3,0xab,0x95,0x64,0x86,0xaf,0xc9,0x15,0xe6,0x98,0x5e,0xb1 +.byte 0xbd,0xde,0x99,0x38,0xfc,0x8d,0xb2,0x5a,0xa4,0x44,0x5b,0x74,0x31,0x31,0x07,0x93,0xf5,0x86,0x78,0xc5,0x82,0x26,0xfc,0x95,0x1f,0x33,0xd8,0xfe,0x70,0x42,0x2a,0xa7,0x3a,0xb1,0xb2,0x63,0xd6,0x5b,0x54,0x9c,0x54,0x45,0x4f,0x1b,0x4a,0xc2,0xb4,0x0e,0x99,0x48,0xde,0x8d,0xa6,0x5d,0xd3,0xdc,0x31,0xa4,0x2b,0x0d,0x44,0x6e,0x1a,0x10 +.byte 0x3f,0x6c,0xa0,0xab,0xcb,0xb4,0xf6,0x18,0xba,0x11,0xd4,0xd4,0x70,0xc4,0xab,0x04,0x4c,0xe7,0xe9,0x53,0xe5,0xd9,0xe7,0xeb,0x21,0xa2,0x2c,0xc4,0xc6,0xc3,0xe7,0x73,0xd9,0xd3,0x84,0xb0,0x12,0x94,0x3b,0xfd,0xd9,0x32,0xba,0xe3,0x37,0xc1,0xb9,0x4d,0xea,0x3e,0x3d,0x31,0x4e,0xa0,0xe7,0x73,0x9d,0x4e,0x26,0xd1,0xdf,0xe6,0x26,0xcd +.byte 0xd7,0x17,0xd7,0x28,0x2c,0x04,0xe9,0x55,0xd5,0x70,0xaf,0xab,0xc1,0x07,0xbc,0xc4,0xd2,0x89,0xdc,0x22,0x59,0x19,0x0e,0xd8,0x8b,0xdd,0x46,0x7f,0xe4,0xad,0xa5,0x70,0xd7,0x18,0x51,0x30,0xd7,0xbc,0x26,0x45,0xe7,0xea,0xce,0xc7,0xf2,0xca,0xb1,0x9c,0x57,0x1e,0x10,0x5f,0x44,0x8d,0x3d,0xe8,0x55,0xa1,0x22,0x68,0x97,0xe8,0x03,0x9c +.byte 0x8b,0x63,0x81,0xd9,0xcd,0x4c,0x6c,0xe3,0x68,0xc9,0x35,0xee,0x94,0x13,0x25,0x0b,0x12,0x61,0xbd,0xee,0x6f,0xc7,0xe8,0xb5,0x01,0x7a,0x9e,0xd0,0x5a,0x46,0xc6,0x19,0x1b,0xc2,0xf1,0x2d,0xaa,0x53,0x29,0xcf,0x23,0x1a,0x4d,0x94,0x0a,0x50,0x64,0xf5,0x3b,0x52,0x55,0xac,0xa5,0x21,0x15,0x47,0xd9,0x14,0x8c,0x7f,0x4d,0x79,0x6b,0xc1 +.byte 0x43,0x0a,0xf2,0x42,0xd2,0xb0,0x95,0x19,0x99,0xdd,0x1d,0x8e,0x84,0x8c,0x7e,0x59,0x69,0x93,0x86,0xae,0xf1,0x67,0x35,0x55,0x7c,0x5b,0x38,0x11,0x56,0xec,0x6c,0xbb,0xe8,0xc0,0x54,0xec,0x5f,0x65,0x13,0xe3,0x86,0xa0,0xb1,0xc1,0x5e,0x34,0x4f,0xdd,0x4d,0x00,0xc6,0x29,0x05,0x78,0x64,0x8c,0x19,0xb0,0xfc,0x8a,0xb2,0xc7,0x86,0x57 +.byte 0xa2,0xdd,0xed,0x43,0xc1,0x7f,0xab,0x89,0x19,0xe8,0xa6,0xf5,0x7a,0x15,0xfe,0xd5,0x4f,0x53,0xde,0x78,0x42,0x76,0xf7,0x8a,0x54,0xe8,0x37,0xfd,0xee,0x82,0x20,0xd5,0xe2,0x32,0xb9,0x32,0x67,0xc7,0xff,0xdc,0xf0,0x40,0x07,0x28,0x55,0x16,0x56,0x84,0xe9,0x17,0x25,0x17,0x8e,0x10,0xef,0x9f,0xed,0x33,0x83,0x6d,0x9e,0x87,0x82,0xb8 +.byte 0xa9,0x6b,0xcb,0xe5,0x04,0xfb,0x87,0x51,0x05,0x1a,0x64,0x64,0x51,0x34,0xa3,0x61,0x4a,0xe3,0xa6,0x35,0xa5,0xc9,0xe3,0xde,0xb0,0xcf,0x5f,0x68,0x49,0xbc,0x98,0xf9,0x0b,0x82,0xde,0xb1,0xf9,0x77,0x16,0x7c,0x1f,0x80,0x0c,0xfc,0xbb,0x6d,0x8e,0x92,0x93,0x00,0xc2,0xa5,0xbe,0xde,0x55,0x09,0x9d,0x83,0xa5,0x6c,0x0a,0xb5,0xc4,0x53 +.byte 0xde,0xbc,0x07,0xca,0x0f,0x43,0xea,0x50,0x25,0xee,0x51,0x3b,0xfb,0x7a,0xcf,0x31,0x8a,0x19,0x1c,0xa2,0x2d,0x72,0x79,0x81,0xc6,0xb8,0xe6,0xe1,0xd8,0x3e,0x0f,0xc0,0xae,0x73,0x40,0x30,0x15,0xaa,0xe3,0x72,0xc3,0x36,0xc1,0x42,0x11,0xc5,0x3f,0xf5,0x69,0x78,0xea,0x95,0x54,0x36,0xe8,0x7e,0x9c,0xad,0xbd,0xcd,0x19,0xfe,0x4a,0x04 +.byte 0xb4,0x54,0x14,0x98,0x58,0x6f,0x06,0x8f,0x8c,0x95,0xa8,0xc9,0xe8,0xc4,0x2b,0x03,0xaa,0x42,0x75,0x74,0xa2,0x63,0xdb,0xca,0xd1,0xf0,0x60,0xc3,0x63,0x84,0xfb,0xd7,0x5a,0x7b,0xca,0x45,0x8d,0x14,0xdc,0xf8,0x71,0x40,0x71,0xbb,0xa1,0x1a,0xd3,0x8c,0xfb,0xf6,0xf7,0xfc,0x82,0x72,0x50,0xc9,0xe3,0xc5,0xe2,0xb1,0x57,0xb1,0x24,0x3e +.byte 0x11,0x4d,0x96,0x1c,0x3a,0xe1,0xb6,0xb7,0x0e,0x55,0x35,0x6c,0xd8,0x2b,0xe3,0x78,0xcd,0xac,0x8f,0x24,0x70,0xc6,0x35,0x5b,0x6e,0x75,0x7a,0xf1,0x7d,0x87,0x53,0xcf,0x0a,0x24,0xb6,0x6a,0xfd,0xef,0x90,0x07,0xcf,0xde,0x30,0xbc,0x8c,0xec,0xda,0x6f,0x45,0xad,0x92,0xb6,0x8d,0x6b,0xb8,0x8e,0xdc,0xe5,0xbf,0x57,0x67,0x5e,0x2f,0x4d +.byte 0x5d,0xee,0x38,0x0a,0xaf,0xeb,0x62,0x84,0x2b,0x4c,0x30,0x7b,0x91,0x99,0x40,0x6f,0x09,0x2b,0x36,0xcd,0x04,0xeb,0x7c,0x8d,0xa5,0xbd,0xd6,0xb0,0xfc,0x27,0xcf,0x6b,0xdd,0xe1,0x94,0xbc,0x21,0xc6,0xc9,0x55,0x24,0xd4,0xa1,0x6f,0x1e,0xa2,0x81,0x31,0x22,0xb7,0x75,0x9e,0xa7,0x01,0x26,0x01,0x6c,0x12,0x91,0x02,0x87,0x40,0x5c,0x91 +.byte 0x1f,0x0c,0x55,0x07,0x12,0xa7,0x48,0xdd,0xed,0xb6,0xfe,0x38,0x05,0xbc,0xe1,0x2e,0x3b,0x89,0x4f,0x98,0x65,0x22,0x93,0xda,0x09,0x9f,0x04,0x90,0x66,0x81,0xd1,0x56,0x27,0x8b,0x26,0x99,0xbe,0x93,0x08,0xf1,0xfb,0x80,0x5b,0xaa,0xc4,0x96,0x88,0x93,0xb6,0x01,0xae,0xf6,0x69,0xaa,0x6f,0x4d,0xde,0x2f,0xc7,0x24,0xbf,0xe9,0xb8,0xeb +.byte 0xcd,0xb2,0x0a,0x50,0x5c,0xd2,0x0b,0xfc,0x57,0x3b,0x96,0xf8,0xd9,0xbe,0xd2,0xb5,0x16,0xac,0x7c,0xe4,0x2f,0x46,0x93,0x86,0x48,0x91,0xfa,0xae,0xca,0x05,0x9e,0xfe,0x6e,0xae,0xa5,0x58,0x94,0xc0,0x58,0x1e,0xc5,0x69,0x28,0xe0,0x99,0x12,0x83,0xcf,0x35,0xe4,0x72,0x7d,0x4e,0x8b,0x66,0x56,0xb3,0xa6,0x2a,0x72,0x06,0x03,0x45,0xd1 +.byte 0x95,0xc9,0x93,0xb7,0xf4,0x8a,0x83,0xce,0x17,0x8b,0xf0,0x8e,0x8f,0x4a,0x68,0x55,0xd8,0xfc,0x54,0x8d,0xb5,0x62,0x17,0xa8,0xe6,0x18,0x03,0x53,0x04,0xb8,0xbe,0xd2,0xd0,0x7a,0x84,0xe1,0x39,0x31,0xc5,0x74,0xf2,0x64,0x1c,0x3b,0xd5,0x52,0x9b,0x81,0x8a,0x8f,0x36,0xc8,0xab,0x3d,0xe1,0xa8,0x2a,0xf2,0x84,0x9a,0xca,0x0c,0xcf,0xc9 +.byte 0x45,0x54,0x06,0xe8,0xd2,0x62,0x61,0x4d,0xeb,0x0b,0x38,0x4e,0x43,0x59,0x85,0x3a,0xe4,0xa3,0x25,0x15,0xc2,0xb5,0x7b,0x5e,0x2f,0xe6,0xc1,0x5d,0x2a,0xb7,0x57,0xb8,0x7e,0x61,0x51,0xc3,0x81,0x53,0x45,0x8a,0x6e,0x4c,0x89,0x84,0x2a,0x6b,0xca,0x15,0xff,0x97,0xfc,0x1f,0x8a,0x44,0xbd,0xcd,0x5e,0x32,0x6b,0x5f,0x78,0x7b,0xdf,0xdd +.byte 0x9d,0x2f,0x21,0xf2,0x14,0x40,0x5f,0x5a,0xd5,0x21,0x27,0x3d,0x0b,0x9f,0x9f,0xb0,0x8e,0xab,0x9e,0x68,0x96,0x02,0xfd,0x4d,0xcc,0x03,0xf0,0x03,0xfb,0x4c,0xac,0xfa,0x00,0x3b,0xea,0x1a,0x53,0x80,0x77,0xec,0x53,0xc3,0x3c,0x6c,0xf8,0xa5,0x3e,0x52,0x34,0xd4,0xa1,0x52,0xb8,0xd6,0x19,0x8c,0xdf,0x85,0x27,0x61,0x22,0xe7,0x43,0xeb +.byte 0x85,0xc0,0xbe,0x58,0xe6,0x60,0x81,0x4c,0xc6,0xbb,0xc0,0xbf,0x63,0x39,0x9d,0xad,0x2e,0xa8,0x2a,0x83,0x3d,0xfa,0xdb,0x0b,0x98,0x16,0x78,0x18,0x43,0xc7,0x17,0x82,0xb8,0xec,0x32,0x45,0x75,0x0c,0xc1,0x4c,0x84,0xbf,0xce,0x83,0x3b,0xb4,0x91,0xf4,0x0d,0x5d,0x83,0xf6,0xd6,0x10,0xab,0xc6,0x26,0x9b,0x68,0x59,0xec,0x48,0x4b,0x1d +.byte 0x35,0x2a,0x5b,0x23,0x83,0x22,0x8e,0x7d,0xfa,0xce,0xde,0xb1,0xd9,0x78,0xf6,0x9e,0x08,0xba,0xfb,0xda,0xf2,0x04,0xc5,0x2a,0xac,0xbf,0xb4,0x04,0x05,0x1f,0x0b,0xeb,0xe8,0x2a,0x3c,0x3f,0x4f,0xb6,0xc8,0x6b,0x97,0x5a,0x9e,0xdb,0x4b,0x3c,0x93,0xc1,0x20,0x1c,0x62,0x91,0x74,0x76,0x49,0x92,0xc2,0xd8,0x0d,0xd8,0xfe,0xb5,0x68,0x77 +.byte 0x48,0x9f,0xbe,0xe0,0x78,0x20,0xe7,0xa4,0x3d,0x3e,0xa1,0x4c,0xc7,0xeb,0xd3,0x30,0xd3,0xf0,0x65,0xcf,0x18,0x3c,0xf8,0x25,0xc2,0x99,0xf4,0xec,0xef,0xdd,0xef,0xf3,0x6b,0x28,0x00,0xaa,0xfd,0x76,0xec,0x19,0x67,0xd6,0x79,0xa6,0x01,0x6e,0x20,0x3a,0x7f,0xd4,0xd0,0x05,0xb4,0xea,0xd4,0xde,0x11,0x06,0x44,0x4a,0x6f,0x15,0x2f,0x62 +.byte 0x9a,0xaa,0xeb,0xaf,0xb5,0xb5,0x46,0xb2,0x28,0x2e,0x74,0x26,0x06,0x91,0xeb,0x15,0xef,0xd4,0xfd,0xc7,0x1b,0x65,0x25,0x01,0x24,0xd2,0x44,0x05,0x18,0x1c,0x71,0x36,0x58,0xc4,0x37,0xfe,0x22,0x29,0xc0,0x2f,0xd2,0x4e,0xeb,0x43,0xb9,0xf9,0x4e,0x87,0xd7,0x92,0x77,0xa8,0x4f,0xa5,0x6e,0x5c,0x4d,0x3a,0xe9,0x16,0x62,0x30,0x51,0xbb +.byte 0x32,0xd8,0x0d,0x86,0x20,0xbf,0x68,0x0f,0x3e,0xef,0x8b,0x0d,0xc5,0xa6,0x94,0x81,0xe9,0x6f,0x85,0xf5,0x22,0x6e,0x9e,0x0a,0x56,0xa3,0x43,0x79,0x50,0xd9,0x45,0x5f,0x5a,0x3f,0x53,0x53,0xb7,0xfe,0xb6,0x1c,0x63,0xab,0x7c,0xed,0x2f,0xc4,0x2b,0xa8,0x53,0xfb,0xad,0x46,0xf0,0x63,0xca,0x7a,0x6e,0xce,0xf4,0xb9,0x34,0xd0,0x9a,0xc8 +.byte 0x0d,0xd2,0x32,0xce,0x26,0x3f,0xcd,0xd9,0xbc,0xa9,0x46,0x65,0x45,0xfe,0x45,0xeb,0x0d,0xab,0xe6,0x31,0xb6,0xb9,0x41,0x53,0x7d,0x55,0xc3,0xfb,0x10,0x46,0x37,0x77,0x1f,0x15,0xf0,0x5f,0xcb,0x8f,0xea,0xc5,0xc0,0xb8,0xc6,0xb1,0x3a,0x06,0x42,0xec,0x38,0xec,0x06,0xd1,0x37,0x3b,0xe1,0x8d,0xad,0xc2,0xce,0x96,0x0b,0xf0,0xab,0xde +.byte 0x9c,0x3c,0x09,0xef,0x59,0xcd,0x67,0xa7,0x6e,0x0e,0xc7,0xee,0x51,0x6d,0x90,0x40,0x0e,0xdf,0xb1,0x13,0xe3,0x0c,0xb6,0xe8,0xcb,0xf5,0x57,0x50,0xeb,0xdf,0x09,0x45,0x72,0x40,0xff,0xdc,0x5c,0x51,0x42,0x47,0xb2,0x9e,0xca,0xf3,0x1b,0x06,0xb1,0x3e,0x04,0x55,0x96,0x63,0x24,0x16,0xdb,0x3e,0xab,0x98,0x33,0x70,0x6f,0xfd,0x8f,0x7b +.byte 0x56,0xb0,0x7f,0x28,0x26,0xc4,0x2a,0x9e,0xf5,0xa7,0xba,0x61,0x75,0xa4,0xb1,0x25,0x60,0xe5,0x9c,0x7e,0xb4,0xaa,0x04,0xa1,0x33,0x5a,0x8d,0x88,0x1d,0xc4,0x38,0x58,0x28,0x23,0xc7,0xac,0x20,0xf8,0xaa,0x18,0xf8,0xc7,0x27,0x05,0x07,0xf7,0x12,0xfe,0xe1,0xa5,0x99,0xaa,0x55,0x79,0x72,0xc4,0x14,0x08,0x14,0x4a,0xfb,0xf7,0x66,0x81 +.byte 0x6e,0xed,0x81,0x12,0x5f,0xb6,0x08,0x00,0x37,0xf9,0xdc,0xdf,0x4d,0xcb,0xfa,0xc6,0xf3,0xc2,0x17,0x17,0x52,0x39,0x7b,0xa0,0x3e,0x25,0xc9,0x48,0xd8,0xa6,0x1b,0x8b,0xdb,0xf8,0x74,0xac,0x6b,0x16,0xec,0xa6,0x4a,0x1e,0x7e,0x5c,0x50,0xbf,0x81,0xef,0x3c,0x7d,0x9d,0x21,0x38,0xa9,0x26,0x3c,0x30,0x7a,0xfb,0xab,0xd8,0x6a,0x0a,0xaa +.byte 0xbb,0x6e,0x91,0x92,0x7c,0x04,0x02,0x0e,0xa2,0x71,0xc7,0xde,0x7d,0x42,0xaf,0xe5,0x92,0xc1,0xb9,0xd7,0x52,0xaa,0x32,0xea,0x39,0x84,0x17,0x40,0xb0,0x83,0x18,0xff,0x46,0xb8,0x59,0xd9,0xa3,0xce,0x82,0x7e,0x65,0x54,0xe0,0xa4,0x6d,0x8a,0xbc,0x6a,0x65,0xb2,0xd5,0x96,0x5b,0x1c,0x9a,0x32,0x72,0xf7,0x81,0x57,0xcd,0xb3,0x22,0xc5 +.byte 0x7d,0x20,0x24,0xea,0xbe,0x51,0x4c,0xb3,0x48,0x36,0x4f,0x73,0xf4,0x3f,0x07,0x92,0x01,0xe2,0x1e,0x78,0x3f,0x8e,0x1f,0x35,0x1a,0xf1,0xe1,0x14,0xd1,0xe7,0xd9,0xfd,0xd8,0xf7,0x20,0xc2,0xf3,0x7a,0x59,0xc9,0x1d,0x13,0x41,0x01,0xf6,0x77,0x69,0xfb,0x0f,0xc7,0xe4,0x58,0x04,0xce,0xe8,0x73,0x87,0x2f,0xef,0xe6,0x36,0x38,0xc7,0x91 +.byte 0x2d,0x17,0xb5,0x56,0x68,0xb1,0x9f,0xbf,0x2e,0x4b,0xe7,0x09,0x7b,0x35,0x33,0x5a,0x6c,0xc1,0x6f,0xb3,0xac,0x6c,0x1e,0xfe,0xc0,0xc9,0xd8,0x77,0xf5,0xcb,0x5e,0xcc,0xd1,0x2f,0xdd,0x23,0x8b,0x3b,0xb5,0x43,0x96,0x1f,0xa9,0xe4,0x84,0x41,0x92,0xe9,0x68,0x47,0x50,0xf7,0xd4,0x85,0x22,0xa1,0x43,0xaa,0xde,0xf7,0xea,0xe0,0x54,0xaa +.byte 0x0d,0xe6,0xa5,0xb8,0x7e,0xec,0x13,0x9a,0x1e,0x6c,0x10,0x9d,0xa8,0xfb,0x97,0xde,0x24,0xda,0x33,0xbb,0xab,0x17,0x7a,0xb4,0x72,0xaf,0xed,0xc9,0xa4,0x62,0x65,0x0c,0x99,0x3d,0x74,0x7f,0xff,0x59,0xa9,0x8e,0x37,0xb9,0x10,0x30,0x26,0x3f,0x2f,0xfc,0x1e,0xe2,0xc6,0xb8,0xff,0x41,0xb3,0x35,0x3f,0x41,0xf4,0x47,0xbc,0x76,0xc6,0x77 +.byte 0x0f,0xf8,0xff,0xb8,0xd2,0x34,0x40,0xac,0x43,0xcb,0xcf,0x1f,0x57,0xaa,0x1a,0xa7,0xe1,0x4a,0x69,0xd7,0x05,0xa7,0x9d,0xff,0x13,0x43,0x91,0xe3,0x09,0x1c,0xb2,0xb2,0x82,0x06,0xa3,0x3c,0x35,0x85,0x9e,0xd0,0xcf,0x1c,0xb9,0x13,0x09,0x7d,0x3d,0x17,0x0f,0xf8,0x2f,0x61,0x97,0x7e,0x02,0xe0,0x78,0x07,0x69,0x8c,0x91,0xbe,0x96,0x92 +.byte 0x4a,0x03,0xa7,0x31,0x5f,0x6c,0xfe,0x55,0xb2,0x17,0xe8,0x4c,0x64,0x48,0x18,0xde,0x4f,0x5a,0xce,0xd2,0xcb,0x83,0x4d,0x1b,0x2a,0x1f,0xce,0x85,0xf7,0xdc,0x74,0x8c,0x42,0xc6,0x5a,0x3a,0x51,0x22,0x79,0x70,0xa0,0xe0,0x29,0x2a,0x73,0xe4,0x53,0xb4,0x47,0x5f,0x54,0xa8,0x65,0xe4,0x89,0x78,0xf9,0xb9,0x5f,0x5f,0x9d,0xa8,0xf7,0x82 +.byte 0x4e,0x34,0x60,0xfc,0xe3,0x88,0x65,0x73,0x99,0x1f,0x53,0xed,0xe8,0xf0,0xf4,0x5a,0x0a,0x49,0x42,0x6e,0x02,0x3f,0xa8,0x63,0x21,0x02,0x2e,0x8f,0x33,0xba,0x0e,0x10,0xd3,0x4c,0x1a,0x8b,0xf5,0x84,0x8e,0x2b,0x37,0x12,0x23,0x77,0x02,0x45,0xc7,0xc3,0x79,0x06,0xc2,0x8c,0xaa,0x32,0x53,0x7c,0x19,0xa2,0x92,0x7e,0x47,0x40,0x8f,0xae +.byte 0x8a,0x64,0x51,0x67,0xe1,0xc1,0xc3,0xd2,0x14,0x1d,0x63,0x0c,0x80,0x04,0x30,0x3d,0xee,0x58,0x44,0xe4,0x14,0x63,0xfc,0x95,0x05,0x3e,0xc1,0x8d,0xd3,0xcb,0x5d,0xc1,0x8e,0xf9,0xd7,0xe5,0x9d,0x97,0xef,0x8a,0xaa,0x50,0x31,0xa3,0x01,0x3a,0xb2,0x8d,0x63,0xb6,0xe7,0x34,0xec,0xa1,0x7a,0xff,0x57,0x95,0xbb,0x1d,0xbe,0x0c,0xa5,0x91 +.byte 0x92,0x08,0x06,0x1c,0x67,0x03,0x2e,0xee,0xf6,0x6f,0xa0,0xb7,0x9a,0x7c,0xe3,0x6a,0x8e,0xd8,0x50,0xc1,0xd6,0xa1,0x8d,0xe9,0x66,0x9a,0x1f,0x62,0x15,0x04,0x93,0x74,0xe8,0x04,0x0d,0x27,0x55,0x2b,0x07,0xb1,0xbd,0x69,0xe4,0xc1,0x34,0x8e,0xe7,0xfb,0xa0,0x3f,0x40,0x31,0x47,0xba,0xcb,0x80,0x88,0xf7,0x4f,0x46,0x05,0x31,0xaf,0x23 +.byte 0xdf,0x93,0x09,0x0a,0x15,0xc9,0x95,0x74,0x52,0x72,0xf4,0xbf,0x0d,0x07,0xb6,0xcc,0x4b,0x40,0x12,0xf3,0x87,0xea,0x29,0xd8,0x29,0x31,0x23,0xac,0x29,0x1a,0x89,0x83,0x5b,0x33,0x4b,0x6b,0x69,0xbe,0xb6,0x15,0x7e,0xfd,0xf2,0x95,0xc4,0xbe,0xeb,0xee,0x59,0x01,0x2a,0xce,0xca,0x80,0xda,0xf8,0x1a,0x01,0x23,0xf7,0xa1,0x4f,0xf5,0x83 +.byte 0x5e,0x16,0xd9,0x12,0xa9,0x4e,0xcb,0x59,0x23,0x4f,0x40,0xd7,0xbf,0xaf,0x76,0xf0,0x50,0x31,0x27,0x3a,0x8b,0x1d,0x9b,0xb1,0x1c,0x41,0xb0,0xed,0xe6,0xf3,0xa8,0x5f,0x6b,0x58,0x54,0x92,0xaf,0xcc,0x44,0x5c,0xea,0xdb,0x09,0xc5,0x26,0x5e,0xbe,0x46,0xbd,0x72,0x49,0x5a,0x4e,0x65,0x7e,0x75,0xcf,0xfc,0xf6,0xd0,0x3c,0x4a,0x7e,0xd6 +.byte 0x8e,0x8e,0xb4,0x19,0x45,0x75,0xbf,0xc3,0x5e,0x46,0xff,0xc9,0x46,0x65,0x8d,0x31,0x01,0x5e,0x1c,0x13,0x93,0x56,0x6f,0x28,0xec,0xf3,0x77,0xfa,0x6e,0xb9,0x0e,0xb6,0x8e,0x0e,0x38,0xf8,0x28,0x64,0xa2,0xa1,0x42,0x9a,0xb4,0xf3,0x14,0x8d,0x17,0x80,0x05,0x82,0x7c,0xf1,0xea,0x8b,0x4b,0x62,0xa0,0xde,0xf6,0xd7,0x36,0xb0,0x70,0x8d +.byte 0x03,0xf6,0xc8,0x2a,0x9e,0xc0,0xbb,0x2f,0xcb,0xef,0x35,0xf7,0x16,0xcd,0xd6,0xd6,0x90,0xd7,0x5d,0x61,0x00,0x33,0x9f,0xd8,0xd1,0xda,0x17,0x67,0x90,0xd1,0xf8,0x59,0xcb,0xf1,0x76,0xc2,0xbe,0x1f,0x5d,0x0d,0xb2,0x02,0xbd,0x19,0x9f,0x5a,0xa0,0x91,0xac,0x51,0xb5,0xf5,0x0a,0x64,0x67,0xf2,0x49,0x30,0x6c,0x57,0x83,0xda,0x90,0xf1 +.byte 0xc6,0xc7,0xe6,0x05,0x13,0x30,0x52,0xfd,0x2a,0x47,0xea,0xae,0xd3,0xed,0xe4,0x64,0x1f,0x6c,0xb1,0xdf,0xca,0x20,0x97,0x2a,0xc8,0xdc,0x00,0x0e,0x5b,0x59,0xc8,0x16,0x95,0x68,0x9a,0x2e,0x44,0xab,0xf6,0x93,0x7c,0x8f,0x66,0x4f,0x07,0x42,0x3f,0xa5,0x81,0xe7,0xab,0x59,0xbb,0xae,0xb1,0x3e,0x9a,0x25,0xf1,0xde,0xac,0x4c,0x1d,0x7a +.byte 0x54,0xb9,0xa9,0x59,0xaf,0xb0,0xab,0xaf,0x6b,0x76,0x66,0x1e,0xbe,0x1a,0xc1,0x61,0x1b,0x81,0x6b,0xe8,0xe4,0x73,0x6a,0x87,0xe9,0x39,0xcb,0x2c,0xab,0x64,0x36,0x9a,0x11,0x46,0xec,0x9f,0x30,0xb6,0x2c,0x14,0xe0,0xec,0xbe,0x33,0xde,0x60,0xc6,0x00,0x29,0x3c,0x55,0xda,0xfc,0x64,0xff,0xaa,0xbf,0x99,0x58,0xe2,0xe3,0xec,0xde,0xca +.byte 0xd1,0x3d,0xd2,0xad,0xaa,0xca,0x36,0x8f,0x93,0xa2,0xdd,0xde,0xaa,0x49,0x7f,0xdd,0x39,0x91,0xa0,0x7b,0x33,0xdf,0x36,0xcd,0xc3,0x3a,0xbc,0x53,0xf0,0x07,0x99,0x78,0x4e,0x63,0x47,0x79,0xbf,0x21,0xfc,0x05,0x47,0x69,0xec,0xee,0xf4,0x21,0x97,0x94,0x0c,0x7a,0x9f,0xa6,0xeb,0x5b,0x23,0xed,0x9d,0xc1,0xe1,0x5e,0x10,0xca,0xe0,0x84 +.byte 0x5a,0xdd,0xf6,0xae,0xd8,0x23,0x98,0xea,0x6c,0x43,0x77,0x41,0xf3,0x84,0x5a,0xe8,0xda,0xb3,0x11,0x0e,0x19,0x33,0xe9,0xf9,0x7a,0x90,0x07,0x68,0xf1,0xe4,0x52,0x0c,0x03,0x67,0xb9,0x42,0x41,0x24,0xa3,0x61,0x67,0x75,0xc9,0xb5,0xdd,0x10,0xf1,0x20,0x93,0x54,0xdb,0x0d,0xc7,0x0d,0x25,0x3e,0xda,0xb3,0xe7,0xce,0x97,0x7e,0xdb,0x1a +.byte 0x8f,0x92,0xff,0xe3,0x44,0x2d,0x6b,0xdb,0xe0,0x69,0x8b,0x16,0xce,0xe8,0xc7,0x93,0xf1,0x19,0xb9,0xd3,0x41,0x45,0x8d,0x95,0xb3,0x03,0xb2,0x66,0x96,0x95,0x91,0x33,0x1c,0xee,0xde,0xd7,0x9d,0xab,0x32,0x2f,0xb8,0x3c,0x7a,0x44,0x8f,0xa6,0xca,0x02,0x03,0x2f,0xa8,0x44,0x85,0x0e,0xf5,0x27,0x90,0x84,0xd9,0x80,0x06,0xf4,0x4f,0xc7 +.byte 0x21,0xc5,0x92,0xa4,0x2d,0x08,0x42,0x4c,0xa7,0x84,0xfa,0x7e,0x2b,0x66,0xfb,0x7c,0x81,0xea,0x5c,0x7d,0xdd,0x86,0xf1,0xf5,0x04,0xef,0xf2,0x50,0x12,0x72,0x42,0x22,0x23,0x74,0x7f,0xe7,0xed,0xd9,0xce,0x78,0x10,0x83,0x37,0xd0,0x81,0x97,0x4a,0xac,0xc2,0xe5,0x13,0x91,0x83,0xe2,0x6e,0xff,0x5a,0x0b,0xc3,0x4d,0xc1,0x3e,0x97,0x16 +.byte 0x96,0x69,0x39,0x9e,0x1d,0x6b,0x16,0x82,0xa2,0x94,0x0d,0x50,0xdd,0xa3,0xda,0x9d,0xda,0x3f,0x46,0xce,0x6c,0xd0,0xdf,0x6e,0x1b,0x17,0x47,0x51,0x74,0x6f,0xe9,0xa4,0x6b,0xae,0xd2,0x6e,0x5b,0xc0,0x26,0xc6,0x0b,0x84,0xb1,0x39,0xcf,0x9e,0x7c,0x18,0x52,0xd7,0x8f,0x33,0xae,0x3d,0xaf,0x3d,0x1a,0xba,0x3f,0x09,0x76,0x22,0x1d,0xf3 +.byte 0x42,0x14,0x4f,0x06,0xc7,0x33,0xc1,0x2d,0x58,0x1b,0x4c,0xc0,0x3a,0x29,0xa6,0x5e,0x19,0x26,0xdf,0x36,0x18,0xa9,0xc5,0xe9,0xd3,0xb1,0xae,0x86,0xa8,0x7f,0xd9,0xb4,0x18,0xef,0x9c,0x46,0xb6,0xf2,0xb2,0xb6,0x6e,0xe2,0xf8,0x5f,0x27,0xea,0x76,0xd3,0x40,0x68,0x94,0x66,0x8a,0xf5,0x9f,0xee,0x0c,0xe5,0xae,0xb6,0xba,0x87,0x42,0x40 +.byte 0xc9,0x83,0xac,0xb4,0x2c,0xec,0x74,0xb7,0x55,0x17,0x0b,0x1e,0x45,0x1a,0x87,0x9d,0x52,0xce,0xb7,0x58,0x2f,0x45,0xc7,0x7d,0xf3,0xd3,0x11,0x2e,0xf4,0xd8,0xc0,0xb8,0xc3,0x31,0x45,0x68,0x40,0xe8,0x8a,0x33,0x20,0x9a,0x06,0xa8,0x18,0x53,0xb2,0x73,0xa1,0x57,0xac,0x8f,0x56,0xeb,0x8e,0xa4,0xfc,0xd6,0x76,0x7e,0x81,0x62,0x2c,0x17 +.byte 0x49,0xb4,0xcc,0x15,0x66,0xcb,0xa2,0x3c,0x29,0xf0,0x73,0x0e,0x9a,0x34,0x16,0x6d,0x43,0x62,0x20,0x89,0x14,0xae,0x8b,0x5d,0x61,0x54,0xa1,0x82,0x49,0x73,0xb9,0x2b,0x48,0xd4,0xe3,0x21,0x37,0x5e,0x4d,0xbf,0xd0,0x72,0xa4,0x23,0xdb,0x7c,0xd9,0x45,0x77,0x8a,0x24,0x23,0x56,0xcd,0x84,0x80,0x44,0x12,0xce,0x99,0x39,0xbd,0x77,0xff +.byte 0x8c,0x62,0x8d,0x56,0x77,0x24,0x40,0x11,0x22,0xab,0x28,0xd6,0x75,0x2b,0xbb,0xc1,0x51,0xd6,0x5e,0x61,0x1c,0xe9,0xac,0x36,0x99,0x52,0x44,0xa5,0x20,0xdb,0xe0,0x12,0x9a,0x45,0x8f,0x7f,0x47,0xf9,0xa3,0x91,0x18,0x2b,0x51,0x9a,0x9f,0x3f,0x7d,0x36,0xde,0x71,0xae,0xca,0x62,0x62,0x16,0xda,0x19,0x9c,0x84,0xce,0xde,0x93,0x22,0xde +.byte 0xaf,0xe7,0x91,0x09,0xe8,0xf0,0x0e,0x07,0x71,0xdf,0x48,0xcd,0x8a,0x77,0x19,0x3c,0xd6,0xef,0x8e,0xe0,0x49,0xdf,0xcb,0xd6,0x34,0x78,0x7f,0x42,0xc2,0x6e,0x7a,0x50,0x53,0xee,0xbf,0x73,0x4b,0xd4,0x4f,0x06,0x18,0x26,0x67,0x51,0x54,0xa3,0x40,0xe6,0xb3,0x61,0x4b,0xfd,0xee,0x62,0x00,0x44,0x6c,0x0d,0x8b,0x2f,0x4d,0x06,0x17,0x41 +.byte 0xee,0x8b,0xde,0x1f,0x80,0x36,0x58,0x3e,0x0a,0x53,0x0a,0x83,0xf9,0xba,0xbd,0x91,0x6a,0x20,0x32,0x42,0x6c,0x85,0xdc,0x84,0xfd,0xce,0x57,0xbe,0xf8,0xa5,0x2c,0x7e,0xf9,0x1b,0x07,0xf4,0x32,0x13,0x32,0x79,0xdc,0x91,0xfc,0xc0,0x18,0xe6,0x1e,0xb2,0x67,0x9d,0x08,0xd2,0x89,0xa2,0xb1,0xbf,0x37,0xe1,0x3f,0x9e,0xb5,0x17,0xf7,0x2f +.byte 0x9a,0x4f,0x3c,0xea,0x5d,0x48,0x56,0x48,0x35,0x17,0xe9,0x5a,0x99,0xa7,0x2e,0x25,0x4f,0x96,0xa6,0x3d,0x3c,0xf8,0xdc,0xe7,0xe5,0x98,0x46,0xf7,0x10,0x16,0x4f,0xb0,0x7b,0x48,0x06,0xbb,0x9a,0x5a,0xad,0x32,0x49,0x92,0x39,0xb2,0xfe,0x01,0x1a,0x5e,0xcc,0xf7,0x0d,0x65,0x1c,0xf5,0x3d,0xb3,0x40,0x28,0x06,0x6e,0xbb,0x74,0x2a,0x95 +.byte 0xe9,0x62,0x2a,0xe2,0x19,0x38,0xc6,0x0d,0x46,0x30,0x6d,0x90,0xa5,0x68,0x4d,0x89,0xf0,0xf4,0xaf,0x52,0x11,0x8a,0x47,0x65,0xc0,0x6d,0xee,0xde,0xbc,0xed,0xf2,0x94,0xf3,0xfb,0xfd,0x2f,0xea,0xd5,0x36,0x89,0x8a,0x22,0xb8,0x75,0x3c,0xda,0x8d,0x3f,0x71,0xe5,0x50,0xb8,0xef,0xfc,0xa1,0x34,0x4a,0xb0,0x56,0x64,0xaf,0x28,0x0c,0x7a +.byte 0x28,0x3e,0xc8,0x83,0xc2,0xbb,0x89,0xc4,0x29,0x7f,0xc9,0xe7,0x4e,0xcb,0xdc,0x8f,0xe8,0xa4,0xdc,0x0d,0xcc,0xa0,0x16,0xda,0xa9,0x34,0x61,0xec,0x64,0xa7,0xf4,0x47,0xe9,0xee,0xbf,0xc6,0x4b,0xc5,0x01,0x65,0xe4,0xe0,0x12,0xd6,0x27,0xda,0x30,0xb5,0x60,0x72,0xe1,0xee,0x38,0x23,0x6c,0x9d,0xbb,0x83,0x01,0x4b,0x26,0x9a,0x68,0xb3 +.byte 0x89,0xb3,0xe0,0x10,0x22,0x58,0xef,0x2d,0xd4,0x86,0xab,0xab,0xc4,0xd8,0x9c,0x56,0xe8,0x54,0x40,0x86,0x11,0xd2,0x6b,0xc0,0xaf,0xfc,0x4a,0xef,0x24,0x38,0x79,0x32,0x54,0x26,0x8b,0x7e,0x02,0xad,0x86,0x9d,0x40,0x65,0x28,0x28,0xa3,0xa6,0xe4,0x07,0x29,0x3a,0xbb,0x81,0xed,0x17,0x54,0x51,0x35,0xc6,0x88,0x9c,0x63,0x7e,0x73,0x02 +.byte 0x28,0x13,0x4b,0x33,0xc0,0x68,0xbc,0xae,0x8c,0x59,0xd4,0x84,0x1d,0x41,0x86,0x5a,0xf6,0x14,0x50,0x13,0x88,0xca,0xc8,0xb8,0xfc,0x61,0xeb,0xe6,0x69,0x70,0x4a,0xa5,0xa5,0x36,0x4b,0xac,0xca,0x00,0x28,0xae,0xb0,0x03,0xef,0xe3,0x92,0xad,0x97,0x32,0x05,0x8c,0x93,0x95,0x45,0xd5,0x75,0x66,0x11,0xd3,0x6f,0x7f,0x5f,0x35,0x44,0xb7 +.byte 0xd7,0x34,0xcf,0x8c,0x4a,0x61,0x68,0x63,0x3f,0x92,0x54,0x01,0x3c,0x25,0x2d,0x6f,0x4a,0x2d,0x55,0xff,0x3f,0x86,0x85,0x9f,0xc2,0xa1,0xde,0x6b,0xbf,0x7e,0xb4,0x7c,0xc1,0x80,0x73,0xf5,0x3b,0x85,0xae,0x36,0x1a,0xdf,0x00,0x52,0xb7,0x70,0xa9,0x42,0x79,0xd2,0x26,0xf8,0x3b,0xeb,0x9f,0x2e,0x15,0x33,0xc8,0x85,0x2d,0x63,0xb2,0x89 +.byte 0x24,0x8e,0xfd,0xe6,0xdf,0x01,0x80,0x8b,0x27,0xe3,0x7e,0x17,0xc2,0x4e,0x26,0xa2,0xe1,0x95,0x81,0x3a,0xdd,0x2a,0xf4,0x75,0x21,0x64,0x11,0x04,0x5e,0x00,0x39,0xf0,0x08,0x68,0x67,0x09,0xa8,0x9b,0xbe,0xb7,0x62,0x0e,0xa8,0x69,0xcd,0x4e,0xaf,0xc8,0x4f,0x92,0x3d,0x8e,0x35,0x60,0x70,0xb3,0xda,0x2f,0x38,0x80,0x6f,0x5e,0xcc,0x3b +.byte 0x6e,0x05,0x26,0x14,0x9d,0x36,0x72,0x7d,0x09,0xb8,0xb7,0xa1,0xf7,0x5f,0xb3,0xe1,0xd6,0xc5,0x54,0x4e,0x80,0x4d,0x06,0x8f,0x84,0xbb,0xb6,0x65,0x87,0x2c,0x19,0x4a,0x74,0x3c,0x34,0x62,0x32,0xad,0x4c,0x06,0xa3,0xbb,0xfb,0x4f,0x4f,0x9d,0x91,0x84,0x63,0x75,0x34,0xcc,0x6b,0x00,0xa1,0x5a,0x63,0x03,0x8d,0x1e,0xdb,0xa4,0x0c,0xe6 +.byte 0x3d,0xd1,0x94,0x77,0xd8,0x77,0x8c,0x39,0x48,0x78,0xb1,0xb5,0xa2,0x41,0xd0,0x6d,0x27,0x20,0x4a,0x41,0x88,0xa5,0x78,0x3f,0x51,0x72,0x8c,0x80,0xe7,0x37,0x81,0x8b,0x06,0x46,0x58,0xab,0x23,0x85,0x47,0x89,0x39,0xf9,0x14,0xfe,0xbf,0x07,0x7c,0x47,0x8e,0xcc,0xd7,0x08,0xfe,0x5d,0xee,0xf9,0x94,0xa2,0x83,0x81,0x8a,0xfd,0x0f,0x9a +.byte 0xa7,0xe4,0x59,0xad,0xe6,0x1f,0xed,0x5d,0xe4,0x20,0xd6,0x2f,0xa7,0xd3,0xcf,0x5b,0x18,0x6d,0x24,0x79,0x66,0xd9,0xaa,0x44,0xfa,0x8d,0x74,0x60,0xcc,0x7e,0xbf,0x4f,0x0e,0xe3,0x9c,0xa5,0xe4,0xff,0x14,0x05,0xff,0x24,0x62,0x94,0x00,0x7a,0x58,0xe5,0x0b,0x3b,0xe8,0xee,0xe1,0x4d,0x4e,0x34,0x26,0xba,0x70,0x10,0x5e,0x14,0x4f,0xa5 +.byte 0x7a,0x9e,0x7b,0x28,0x99,0xbe,0x94,0x4a,0xcb,0x8d,0x65,0x60,0xa0,0x6e,0xc7,0xbc,0x51,0xba,0xb5,0x07,0x97,0x25,0x42,0xb7,0x2c,0x0e,0x9b,0xfc,0xfb,0x35,0x6f,0x74,0x10,0xce,0x25,0xdb,0xa9,0x7c,0x11,0x61,0x43,0xf9,0x19,0xbf,0xe2,0x21,0xa3,0x57,0x3c,0x41,0x0a,0x15,0x4e,0x7f,0x6b,0x38,0xb6,0x73,0x41,0xa2,0x4e,0x8e,0xb9,0x44 +.byte 0xee,0x2a,0x2e,0x0a,0x9e,0x85,0xf1,0x6e,0x93,0x72,0x42,0x50,0x55,0xe1,0xc6,0x18,0x11,0x92,0xf7,0xbf,0x05,0xd8,0xb6,0xbc,0x2b,0xd5,0xe0,0xd3,0x9b,0x64,0xc4,0xdd,0xb0,0xb3,0x46,0xd8,0xfb,0x73,0xea,0xed,0x06,0x96,0x16,0x9e,0xf6,0xc6,0xe8,0xbe,0xae,0x00,0x2f,0x5a,0xf4,0x1f,0xb5,0x28,0x7c,0x75,0x76,0x68,0x74,0xa2,0x57,0x0e +.byte 0x6c,0xfa,0x2d,0xbe,0x34,0xf1,0xc9,0x2b,0x83,0x58,0xe7,0x2a,0x87,0xdb,0x47,0xae,0xc7,0xc2,0x78,0x50,0xed,0x20,0xdf,0x30,0x38,0xdd,0x84,0xa9,0x6b,0x00,0xb1,0x7b,0xbb,0x69,0xd3,0xbe,0xed,0x3d,0x99,0x6e,0x39,0x42,0x75,0x8a,0x6c,0x7c,0xa5,0xcf,0xc9,0xcf,0x11,0x14,0xb3,0xaf,0x72,0x00,0x3b,0x58,0xdd,0x2a,0xe1,0x44,0xa7,0x51 +.byte 0x15,0x05,0x1b,0x18,0x49,0x07,0x90,0x4c,0xbc,0x99,0x88,0x64,0xf6,0x14,0x0b,0x99,0xc0,0x84,0xc9,0x06,0x32,0xf0,0xec,0x19,0x8d,0x4a,0xb8,0xdb,0x32,0xb4,0x5e,0xc9,0x0c,0x24,0xf0,0xad,0xdc,0xf4,0x32,0x3b,0xf6,0x68,0x28,0x4a,0xa5,0x5b,0xb7,0xd5,0x00,0x35,0xf8,0x56,0x03,0xa3,0x86,0xa0,0x8a,0x1b,0x53,0xb5,0x58,0x73,0x8c,0xf9 +.byte 0x2b,0xd8,0xcb,0x88,0xe7,0x7e,0x79,0x68,0x13,0x5d,0x7d,0x23,0xc4,0xec,0x9c,0xf4,0x95,0x97,0xbf,0xb2,0xd9,0xdf,0x38,0xe8,0xa2,0x79,0xf7,0xe8,0x36,0x80,0x59,0x3f,0x58,0x2f,0xf7,0xf9,0x32,0x73,0xdd,0xd6,0x9e,0x20,0x1a,0x29,0xab,0xc1,0x77,0x14,0x71,0x3c,0xde,0x90,0xe9,0xea,0xdb,0x78,0x14,0xa3,0x89,0x43,0xf1,0x42,0x43,0x3f +.byte 0xe7,0x67,0x32,0x3d,0x65,0xdc,0xa4,0x79,0x8f,0x81,0xa5,0xb0,0x94,0x0f,0x96,0xf5,0x82,0xcc,0x47,0xc1,0x29,0x39,0x70,0x7a,0xf3,0x49,0xf5,0x09,0x43,0x50,0x56,0xd6,0xea,0xc4,0x35,0xa5,0xa2,0x8a,0xbe,0xc0,0xe3,0xfe,0x4c,0xa2,0x83,0x09,0xab,0x72,0x8a,0x96,0x7c,0x01,0x70,0xb2,0xd5,0x62,0xb7,0x67,0x59,0x36,0xcf,0x56,0x2d,0x14 +.byte 0xc2,0x69,0x49,0x52,0x4e,0x7c,0x45,0x4b,0xef,0xcd,0x79,0xcd,0xe6,0xa6,0xd0,0xbe,0x10,0x1e,0x18,0xca,0xe7,0x8d,0x65,0xb1,0x17,0xc7,0x2c,0xc8,0x2a,0x5b,0xe8,0x08,0x11,0x15,0xea,0xa9,0x43,0x7b,0x70,0x04,0x0c,0xc8,0xca,0x67,0x18,0x18,0x12,0x16,0xc2,0xd3,0xf2,0x0a,0xc7,0x01,0xa9,0x97,0x61,0xf6,0xa7,0x44,0x9a,0xb3,0x67,0xdc +.byte 0x07,0x63,0x02,0x02,0x2e,0x58,0x80,0xa9,0x95,0xa0,0x8e,0x86,0xb6,0xf6,0x14,0x13,0x0a,0xea,0xf1,0x6d,0xd9,0x98,0x37,0x12,0xdb,0x67,0x1b,0x13,0x8e,0xd1,0xfa,0x2f,0x98,0x53,0x3c,0xd7,0x56,0x55,0x42,0x2f,0x64,0x59,0xd5,0xb7,0x6e,0xa8,0x6c,0xc2,0x40,0x11,0xb5,0xa1,0xc0,0x5c,0x45,0x87,0x91,0xb1,0x1c,0x4e,0xa9,0xf6,0x72,0x57 +.byte 0x50,0x8e,0xc5,0xfc,0x64,0x59,0x52,0x82,0xb0,0x75,0xc3,0x98,0xff,0x32,0xce,0xa4,0x39,0xb8,0xa4,0x61,0xb4,0x53,0x3f,0xc7,0x80,0x35,0x48,0xaf,0xa8,0x67,0xfe,0xa1,0x1d,0x3c,0x95,0xb5,0x63,0x1c,0x3a,0x2c,0x68,0xfa,0x98,0x8b,0xa7,0x19,0x29,0x79,0xe4,0x9b,0xff,0x8f,0x15,0x9c,0x65,0x60,0xd2,0xa9,0x4f,0xd5,0xb2,0x57,0xff,0x32 +.byte 0x4c,0x96,0x82,0x6b,0x09,0x6c,0x74,0x55,0x00,0x5c,0x68,0x68,0xd5,0x9b,0xd4,0xdf,0x3d,0x2d,0xb9,0x0b,0xf5,0x2c,0x87,0x35,0x2a,0xc0,0xc0,0xc9,0xd7,0xa1,0x76,0x30,0x82,0x46,0xd8,0x24,0x6e,0x27,0x02,0x71,0x57,0x5c,0x43,0xf2,0x54,0xd6,0xea,0xd7,0x67,0x7d,0xac,0x76,0x91,0xf1,0x26,0x6e,0xaf,0x87,0x05,0x06,0x48,0x57,0xbd,0x67 +.byte 0x1d,0xd7,0x07,0xcd,0x41,0x02,0x49,0x6c,0x8c,0xe1,0xe3,0x00,0x78,0xbe,0x28,0x84,0x16,0x44,0xb1,0x0d,0x6d,0x40,0xfe,0xab,0x7e,0xf6,0x6b,0xff,0xfa,0xe1,0xc7,0x9d,0x56,0x62,0xf1,0x68,0xba,0x76,0x34,0x8f,0x54,0x20,0x49,0xf5,0xa2,0x54,0x52,0xca,0x42,0xed,0x4f,0x9b,0xdf,0xcf,0xfb,0xf6,0xee,0x12,0x29,0x43,0x8f,0xf9,0xfd,0xf4 +.byte 0x8a,0xbf,0xae,0x50,0xf2,0x8f,0x46,0xa2,0x97,0x3b,0x2d,0xfb,0x84,0x98,0x61,0xae,0xba,0x36,0x25,0x30,0x8b,0xdc,0xd3,0x08,0x8e,0x7e,0xfa,0x91,0xac,0x4b,0x29,0x6d,0x0c,0x81,0x0f,0xc7,0xc8,0xc4,0x5c,0x48,0x68,0xa7,0x83,0xf3,0x6a,0xc8,0x0d,0x3a,0x9b,0x46,0xb9,0xe1,0x31,0xac,0x3c,0x12,0xa2,0xae,0x74,0xb8,0x91,0xed,0x63,0xba +.byte 0x40,0xb8,0x57,0x58,0x1f,0x1d,0x1a,0x2d,0x98,0x60,0xe8,0xe1,0x84,0x16,0xe5,0xf0,0x1e,0x35,0x58,0x31,0xc3,0x0c,0x49,0x6e,0x13,0x2c,0xac,0x14,0xc2,0xde,0x5f,0x62,0xe5,0x37,0x5b,0x1d,0x71,0x8b,0xc3,0x3d,0xd8,0xaf,0x3d,0x0a,0xef,0x80,0x3c,0x9a,0x4b,0x0a,0x3f,0x0e,0x8f,0x90,0x8f,0x73,0x2e,0xff,0x8e,0x8e,0x87,0xf8,0x46,0x52 +.byte 0xed,0x7d,0x76,0xf3,0xff,0xaf,0x5e,0x62,0x87,0x16,0x9c,0xa6,0x12,0x39,0x13,0xc3,0x62,0x4b,0xd2,0x21,0xa2,0x43,0xfa,0x4c,0x5d,0x75,0x61,0x64,0x5b,0x23,0xcd,0x76,0x86,0x81,0xd6,0xa6,0x25,0xe1,0xc1,0xc6,0x04,0x5e,0x65,0xfe,0x89,0x0e,0x67,0x02,0xeb,0xb9,0x26,0x88,0x81,0x97,0x1e,0x62,0x4e,0xf4,0x4e,0x0d,0xef,0xac,0xcf,0xd7 +.byte 0xc5,0x9b,0x9d,0x3a,0xa2,0x71,0xd7,0xd4,0x72,0xa6,0x66,0x90,0xe2,0xf7,0xb7,0xec,0xe4,0xca,0x9f,0xd1,0xd8,0x5a,0x65,0xff,0x39,0x65,0x78,0x47,0x1c,0x64,0xab,0x1a,0x35,0x2e,0xe2,0xf7,0x67,0xa4,0x7f,0xd5,0xea,0x04,0xee,0x4d,0xf6,0x29,0xe4,0xcd,0x1b,0xcf,0x0a,0xef,0xa1,0x14,0x90,0x0e,0xed,0x1a,0x10,0x63,0xa0,0x56,0x11,0x05 +.byte 0x57,0x94,0x3a,0x11,0xff,0xe0,0xc7,0x33,0x19,0x67,0xd7,0xd0,0xcc,0x76,0x52,0x5d,0x9e,0x10,0xe7,0xd6,0xaa,0x13,0xe8,0x8d,0xa5,0x60,0x66,0x98,0x26,0x11,0x66,0x0f,0x2d,0x4d,0xec,0x28,0x93,0x17,0x3a,0x6f,0x99,0x70,0x00,0x2b,0x66,0xb3,0x49,0x69,0x3c,0x3b,0x03,0xb8,0xc0,0x9b,0x1c,0x96,0xd9,0xd1,0xe1,0x6d,0x8f,0x45,0xce,0x22 +.byte 0xcf,0x48,0x61,0x85,0x10,0x1b,0x3f,0x2b,0x74,0x48,0x61,0x68,0x63,0xe3,0xa3,0x83,0xe2,0xcc,0xa0,0x6d,0x82,0x8b,0xe5,0x42,0xab,0xa7,0x62,0x6c,0x05,0xb4,0x7b,0x65,0xf5,0xd8,0x0b,0x7d,0x61,0xd6,0x5c,0xf0,0xc0,0x03,0x0c,0x51,0xec,0x06,0xad,0x79,0x8c,0x62,0x0c,0xf5,0x8e,0xcb,0x97,0x62,0xf9,0x3e,0x39,0x8d,0x3c,0x2e,0xd1,0xc0 +.byte 0x5f,0x98,0xea,0xb5,0x26,0x19,0xf5,0x93,0xbb,0xf8,0xd4,0xd5,0x35,0xee,0x1f,0xf8,0x71,0x81,0x0e,0xe6,0xe9,0xf3,0x2c,0x80,0xa8,0x15,0x35,0x1e,0xda,0x07,0x41,0x39,0x8a,0x19,0x1f,0x70,0x99,0xbe,0x3d,0x5c,0x1f,0xf6,0x72,0x85,0x73,0xea,0xb5,0x61,0xbb,0x77,0xaa,0xef,0xc7,0x2c,0xed,0x1e,0xa6,0xfd,0xc9,0xde,0xa9,0x82,0xba,0x19 +.byte 0x04,0x17,0xf7,0xa1,0x59,0x5c,0x7d,0x8d,0xe7,0x1c,0x89,0x7f,0xe1,0x02,0xd3,0xb0,0x46,0x6c,0xcf,0xde,0xf0,0x0b,0x00,0x43,0x8d,0xd6,0xe6,0xf7,0xc8,0x83,0x20,0x77,0x8b,0x9f,0x14,0xea,0x2b,0xb2,0xd2,0x41,0xfd,0x96,0x7c,0x0d,0x05,0xb9,0x5a,0xa0,0x83,0x50,0xde,0x0e,0xc6,0xa6,0x29,0x55,0x12,0x8e,0x2f,0x0a,0x5c,0xcd,0xae,0x92 +.byte 0x76,0x84,0xc9,0x8a,0x81,0xe5,0x3e,0xf0,0xe6,0x5b,0xe4,0x21,0xfb,0x4c,0xb6,0x0a,0x7b,0x7f,0x7e,0xab,0xdc,0x15,0x44,0xf8,0xeb,0x23,0x21,0x31,0xef,0x98,0xec,0x84,0x69,0x34,0x29,0x99,0x03,0x8a,0x12,0x8e,0x28,0xdd,0x00,0x6a,0xa3,0xe7,0x08,0x17,0x35,0x2a,0x42,0x8a,0xcb,0x4a,0x7b,0x1c,0xd2,0x74,0x4f,0x6a,0x8c,0x85,0x1c,0xd6 +.byte 0x05,0x3a,0xfd,0xdf,0x1c,0xa5,0x59,0xbb,0xdb,0xe3,0xa7,0x59,0xb1,0x67,0x3d,0xa4,0x71,0x4d,0x6c,0x99,0xe0,0xa7,0x8c,0xfa,0x96,0x1f,0x8d,0x0c,0xa7,0xc8,0xce,0xa3,0xbf,0x4d,0xc7,0xa9,0xb7,0xfd,0x04,0x58,0xcd,0xd7,0x20,0xb1,0xb9,0xf5,0x06,0x70,0x1b,0xdd,0xf4,0x1c,0xdc,0x32,0xa0,0x90,0x0d,0xb2,0x91,0x14,0x05,0xa2,0xf7,0xb7 +.byte 0xb6,0xd2,0xf1,0x30,0x75,0xcc,0x78,0x0d,0x56,0x70,0x64,0x02,0xe7,0x83,0x97,0x65,0x63,0x4b,0x64,0xff,0x8b,0x62,0xc9,0xa4,0x6e,0x96,0xbf,0xd3,0xeb,0x74,0xc5,0x1f,0xdb,0x1c,0xf3,0xca,0x54,0x7d,0x8d,0xd9,0xec,0x18,0xd8,0x99,0xd1,0xa5,0x70,0x8a,0xc5,0xdc,0xa0,0xcb,0xb7,0x52,0xe3,0xe6,0x88,0x0c,0x5a,0x42,0xde,0xe6,0xd8,0xc4 +.byte 0x39,0xe5,0x6c,0x0b,0xd4,0xa5,0x9b,0x51,0xa2,0x3d,0xc5,0xc7,0x17,0x17,0xb8,0xd8,0x09,0xad,0xeb,0x67,0x47,0xe0,0x88,0xef,0x1d,0x22,0x18,0x25,0xdc,0x32,0xb2,0xf7,0x47,0xc5,0xb3,0x0b,0x57,0x01,0x67,0xac,0xc3,0x9e,0xb0,0xa8,0xd7,0xce,0xb2,0xcd,0xea,0x3b,0x61,0xbb,0x24,0xad,0x91,0x7b,0xa2,0x9a,0xb3,0x63,0x56,0xe2,0x9d,0x69 +.byte 0x9e,0xd7,0x5f,0x5f,0x47,0x9f,0xae,0xf6,0x09,0xb1,0x9e,0x22,0x35,0xaa,0x55,0x0b,0xfc,0x70,0x96,0xfd,0x53,0x8a,0x37,0xaf,0x2d,0xa2,0xc5,0x49,0x5b,0x1e,0x32,0x47,0x9d,0xc3,0xb4,0x46,0xf3,0x54,0xdb,0x3f,0xb9,0x69,0x9e,0x8b,0xad,0x11,0xb2,0x68,0xe8,0x27,0x0d,0xca,0x33,0x1c,0x86,0xb2,0x2c,0xaa,0xc2,0x15,0xf9,0x6e,0xed,0x30 +.byte 0x71,0x08,0xeb,0x93,0x1d,0x16,0xc5,0x34,0x73,0x65,0x7a,0x19,0x2b,0xa7,0x3d,0xe6,0x88,0xb5,0x0f,0xa0,0x92,0x91,0x22,0x9d,0x01,0xf3,0xf4,0x57,0x9f,0xd9,0x23,0x1b,0xbd,0xd7,0xd5,0x11,0xc9,0x24,0xf6,0x36,0x30,0x30,0x69,0x95,0x17,0x48,0xf9,0x76,0x71,0xef,0xef,0xc0,0x00,0x9c,0x7d,0x87,0xdc,0xdc,0x1a,0x32,0x82,0x7a,0x13,0xc2 +.byte 0x9f,0x53,0xc2,0x7d,0x4d,0xbf,0xbe,0xf5,0x9d,0xc8,0x81,0x5b,0x81,0xe9,0x38,0xb6,0xa5,0x40,0xa5,0xd4,0x6f,0x0c,0xea,0xf1,0x52,0x59,0x37,0x3b,0xc2,0xb2,0x5f,0x10,0xdf,0x22,0xf7,0x77,0xe8,0x66,0xb0,0x97,0x91,0x5f,0xc2,0x18,0x8d,0x17,0x40,0xd1,0x6d,0xde,0x6e,0xf0,0x6c,0x1f,0x4e,0x9b,0x15,0x83,0x9b,0x70,0x21,0x2b,0x98,0x46 +.byte 0xbf,0xa5,0x82,0xac,0x63,0xac,0xd7,0x52,0xec,0x2c,0xf2,0xe4,0xe0,0x2a,0xbf,0x7e,0xa2,0xd2,0x9d,0x0d,0xf2,0x9b,0x79,0x5f,0x22,0xb0,0x6d,0x22,0x2e,0xed,0xe2,0x4f,0x73,0xc5,0x89,0xcc,0x4a,0xaa,0x9a,0x7e,0xab,0x95,0x25,0xa7,0x9d,0xf4,0xc2,0xe8,0x42,0x6e,0xd3,0xf9,0x25,0x54,0xb9,0x1f,0xa9,0x16,0x9c,0x22,0x7a,0xf0,0xa6,0xac +.byte 0x8b,0x9d,0xe6,0xe3,0x93,0x4e,0x65,0x3a,0x39,0x3e,0xf5,0x41,0x38,0x02,0xb7,0x37,0xd4,0xdc,0xea,0xc5,0x53,0x0e,0x52,0x85,0x96,0xc0,0xa7,0x21,0xbf,0xe7,0xca,0x12,0x1c,0x59,0x33,0xe4,0xd5,0x70,0x6b,0x25,0x54,0x24,0x58,0x48,0x1b,0x65,0x6e,0x7e,0xe6,0x84,0x39,0x38,0xbc,0xdf,0x96,0xbc,0x39,0xdf,0x8f,0x36,0x9e,0x3a,0xda,0x02 +.byte 0x86,0xe2,0x9f,0xb7,0x3a,0xd0,0xdb,0xc2,0x5d,0xb0,0xde,0x31,0x73,0x43,0xe5,0x4b,0x6a,0xa1,0x6d,0xaa,0xca,0x34,0xfa,0xa9,0xaf,0xec,0x05,0x2a,0xdb,0x82,0xa1,0xdc,0xdc,0x3d,0xb5,0x92,0x42,0x28,0xdc,0x93,0xec,0xab,0x9b,0x75,0xae,0x7c,0xbf,0x9b,0x25,0x01,0xb1,0xc8,0x3b,0x47,0xb6,0xfd,0x11,0x6f,0x4b,0xaa,0x6f,0xdf,0x1f,0x15 +.byte 0xc2,0xf3,0x87,0x4a,0xaf,0xf7,0x41,0x64,0x5a,0x19,0xa0,0xc4,0x4f,0x58,0xe8,0x19,0xe0,0x84,0x44,0xc7,0x65,0x0c,0xf1,0xff,0xcb,0x73,0xb2,0xac,0x25,0x28,0xe1,0xd4,0x03,0x16,0x3c,0x1c,0x24,0x3a,0xfc,0x2b,0x7e,0xcb,0xa3,0xba,0xb7,0x78,0x87,0xbe,0x95,0x06,0x27,0xb8,0x16,0x72,0xe4,0x24,0xa6,0x5d,0xe7,0x5e,0x93,0xa9,0x96,0xfd +.byte 0x01,0x1d,0xb8,0x7c,0x85,0x3c,0xe3,0xc9,0x56,0x68,0xcd,0xd9,0x79,0x97,0x50,0x39,0xfe,0x96,0x93,0x50,0xae,0xde,0xcd,0x8d,0xa0,0x38,0x31,0xba,0xca,0x21,0xff,0x19,0xea,0x44,0x95,0x4d,0xba,0xae,0xe2,0x62,0xd2,0x82,0x60,0x0c,0xb9,0x10,0x40,0x9a,0xaf,0x9b,0x17,0xcd,0xf3,0x26,0xec,0x38,0x13,0x18,0xd3,0xf2,0xd2,0x11,0xa6,0xc3 +.byte 0x3c,0x3b,0xe8,0xa0,0x49,0xba,0x4e,0x07,0xec,0x44,0x75,0x1c,0xc9,0x2f,0x68,0x64,0x02,0x1d,0x14,0x35,0x80,0xd8,0xa8,0x53,0xde,0x44,0x65,0x72,0x37,0x28,0x61,0x5f,0xa1,0x58,0xea,0x17,0xb3,0x89,0x25,0xf7,0xcb,0x87,0xe6,0x43,0xc5,0xc3,0xf3,0xd1,0xf5,0x1f,0x18,0xe9,0xd1,0x05,0xd9,0x85,0x38,0xf0,0x5e,0x26,0x35,0xf2,0x72,0x92 +.byte 0x34,0x2f,0xea,0xdd,0x7b,0x64,0xac,0x1d,0x78,0x41,0x56,0x83,0x7d,0x83,0x83,0x59,0xbe,0x9f,0x81,0x90,0x00,0x1f,0x04,0xd8,0xd8,0x8e,0xd9,0xeb,0x12,0x16,0x96,0x81,0x61,0x96,0xe8,0x7b,0x36,0x7b,0x26,0x9b,0x43,0x1e,0x0e,0xc2,0x59,0xdf,0x8f,0xb4,0x91,0x74,0x2e,0x1e,0x6d,0x20,0x70,0xe7,0x3c,0x39,0xe3,0xa8,0x62,0x66,0x32,0x63 +.byte 0x7d,0x89,0xb6,0xad,0x69,0x38,0x2c,0x21,0xe5,0x02,0xcc,0x93,0x8a,0x65,0x71,0x65,0x02,0x5c,0xeb,0xc9,0x70,0xf3,0x81,0xce,0x65,0x37,0x22,0xb7,0x47,0x3c,0xd6,0x3d,0x29,0x65,0x29,0xba,0xf9,0xae,0xd9,0x1f,0xd7,0x38,0x88,0x95,0xa9,0x66,0xa8,0x77,0x75,0x4a,0xf9,0x2e,0xd9,0x63,0x75,0x80,0x90,0x82,0x39,0x8b,0x21,0x58,0xf4,0x2e +.byte 0x2d,0x1f,0x7f,0xcb,0x33,0xdb,0x9b,0x9b,0x31,0x21,0x4e,0x6e,0xdb,0x0f,0x1f,0x69,0x22,0x97,0x69,0xd7,0x7f,0x2e,0xd7,0xce,0x6c,0xe4,0xc0,0xe7,0x27,0x82,0xe6,0x8a,0xf8,0xae,0x46,0x2d,0x5a,0x45,0x82,0xce,0xb6,0x49,0x84,0x15,0x4a,0x54,0xa6,0x76,0xf3,0x29,0x28,0xc0,0x05,0x82,0xae,0x7d,0x85,0x41,0xb0,0x87,0x67,0x44,0x37,0x46 +.byte 0x3e,0x47,0xbc,0x00,0x7c,0x05,0xd3,0xdc,0x9a,0x31,0x49,0xf8,0x48,0x99,0x57,0x4a,0x2b,0xe7,0xcf,0xb2,0xa7,0xf0,0xcf,0xc7,0xf5,0xfd,0x73,0x59,0xf1,0xe4,0x86,0xb5,0x5d,0xce,0x6d,0xbf,0xc6,0xe5,0xa9,0xca,0x75,0xe9,0x69,0xe6,0x09,0xab,0x66,0x17,0x09,0xe9,0xbc,0x14,0xd8,0x6f,0xe9,0xc2,0x87,0x39,0x2f,0x87,0x1e,0xb8,0x16,0x08 +.byte 0x10,0xee,0x1c,0x2f,0x47,0x7d,0xa3,0x5b,0x1f,0x1f,0x5d,0x95,0xd0,0xa4,0xbb,0x08,0xc2,0x47,0xab,0x46,0x3c,0xbb,0xbe,0x3a,0x64,0x82,0x40,0x08,0x75,0x03,0x02,0x6e,0x6a,0xab,0x6b,0xd4,0x90,0xa7,0x28,0x7a,0xb4,0x8b,0x1f,0x6b,0xcc,0x16,0x30,0x16,0xf5,0xc6,0xd8,0x4a,0xed,0xc9,0xc7,0xac,0x0f,0x75,0x1b,0x13,0xe3,0x45,0x6d,0x22 +.byte 0x7e,0x3d,0x59,0x55,0x87,0x8d,0x04,0xee,0x85,0xac,0x98,0x0c,0x52,0x5b,0xe6,0x92,0x04,0x31,0xdf,0x7c,0x44,0x4d,0x06,0xbe,0xb2,0x5a,0x95,0xef,0x29,0x75,0x9b,0xb2,0xe7,0xb8,0x83,0x18,0x82,0x23,0x4e,0x66,0xe5,0xdd,0x47,0xa1,0x6b,0x33,0x4e,0x9c,0x13,0x0e,0x0a,0x8a,0x5c,0xba,0x7b,0x2f,0x6c,0x72,0x78,0x86,0xd2,0xf8,0xbd,0x1b +.byte 0x4b,0x9e,0xe0,0x99,0x46,0x7f,0x24,0x0f,0x1b,0xda,0x85,0x87,0xe9,0xda,0x96,0x25,0xc6,0x81,0x77,0x8b,0x56,0xae,0x7a,0x9c,0x47,0x34,0xe1,0xac,0xf2,0xba,0x52,0x95,0xf8,0x56,0x26,0x66,0xf0,0x53,0xcc,0xc4,0x6f,0x46,0x94,0x10,0x22,0x69,0xb1,0x93,0x7b,0x51,0xb7,0xb8,0xdd,0x42,0x67,0x51,0x6d,0x9c,0xb2,0xbd,0xdb,0xdd,0x19,0xa2 +.byte 0x25,0x13,0xfe,0x42,0xca,0x36,0xeb,0xce,0x15,0x41,0xe7,0x35,0xce,0xa8,0x45,0x56,0x58,0x9f,0x46,0xcf,0x11,0xe7,0xcc,0x40,0x54,0xe4,0x85,0x0d,0x73,0x36,0x7e,0xae,0x38,0x8c,0x56,0xab,0xf0,0x5f,0x5c,0xff,0x14,0x9b,0x46,0x1b,0x35,0xbd,0x03,0x0e,0x2f,0x9e,0xde,0xd8,0x82,0xfe,0xa0,0x09,0xb4,0xb4,0xbd,0x58,0xc0,0xe2,0x01,0xb1 +.byte 0xca,0x5c,0x3d,0xc3,0x18,0x5e,0xc1,0xee,0x61,0x60,0x00,0xca,0x1e,0xf3,0x71,0xd8,0x15,0x37,0xf0,0x2e,0x13,0xa0,0xf7,0xac,0x73,0x4b,0xfb,0x6a,0x27,0x6b,0xde,0x69,0x3d,0x19,0x36,0x4b,0x63,0x55,0xae,0xd1,0x2b,0x66,0x69,0x0d,0x64,0xa7,0x86,0xfd,0x3a,0xb8,0xe6,0x87,0xaa,0x32,0x5f,0xbc,0xa7,0x67,0xde,0x7a,0xe0,0xdd,0xff,0x57 +.byte 0x2c,0xc9,0x25,0x92,0x03,0x91,0xa8,0x0e,0x39,0xe4,0x9a,0xdf,0x21,0x29,0xc7,0xbc,0x93,0x01,0x2a,0x02,0xd8,0xaf,0xbc,0x20,0x57,0xc7,0x37,0x77,0xa7,0xad,0x5e,0x15,0x20,0xcf,0x4a,0x3c,0x22,0x1b,0x92,0xa9,0x05,0x91,0x70,0xb3,0x88,0x4e,0x97,0x58,0xf7,0x33,0x1a,0x05,0x33,0x57,0xdc,0xbb,0x2a,0xba,0xd0,0x22,0xac,0x40,0xbe,0x60 +.byte 0xa2,0x89,0xe6,0x6c,0xf3,0x5d,0xef,0x58,0xb4,0x7c,0x4a,0x28,0xb8,0x16,0xd2,0xe0,0x49,0xf5,0xe8,0xaf,0x84,0x39,0xae,0x1e,0xa2,0x34,0x67,0x42,0x26,0x31,0x93,0x87,0x7a,0xd5,0xde,0x79,0xdb,0x4c,0x7e,0xcf,0x1f,0xef,0x9a,0x4c,0xb9,0x70,0xe2,0x72,0x9b,0xcd,0x30,0xe5,0xf1,0x84,0x44,0x5a,0xff,0x36,0xa2,0x37,0xe7,0x49,0x78,0x63 +.byte 0xbe,0xe0,0x90,0xdf,0xef,0x9e,0xf3,0x55,0x9e,0x8a,0x51,0xe8,0xa3,0x32,0x2d,0xed,0xc8,0x99,0xf6,0x92,0xf9,0x62,0x74,0xa7,0x8d,0xcf,0xa5,0x09,0xb3,0x43,0xb9,0x18,0x70,0x59,0x4f,0xd2,0x7f,0x7e,0xce,0x1e,0x7d,0xe8,0xa9,0xb7,0x29,0x0f,0x86,0x8a,0xac,0x22,0x41,0x98,0xb2,0xc3,0x48,0x3b,0x60,0xcb,0x7b,0x1d,0xc3,0x5e,0x19,0x5b +.byte 0x31,0x57,0x12,0x09,0x41,0x54,0xf8,0x01,0x70,0x02,0x03,0x8a,0x6e,0x8e,0x5b,0x23,0xf3,0xd4,0x13,0xbf,0x51,0xba,0xf9,0x2d,0x6c,0xb9,0xb3,0x90,0xd0,0xa3,0x76,0xfb,0xef,0x85,0x17,0x8b,0x2c,0x05,0xa3,0x06,0x0a,0xaa,0xdd,0xbf,0xd4,0xcc,0xe4,0x96,0x19,0x7f,0x51,0xf6,0x7e,0xa1,0x2c,0x14,0x1c,0x21,0x99,0x28,0x3a,0x0e,0x36,0x1b +.byte 0xf1,0xd7,0x3e,0x29,0x94,0xa6,0x03,0xf7,0xe5,0x6f,0x1b,0x56,0xc8,0xfb,0x2d,0x4f,0x12,0x2b,0xc7,0x3a,0xec,0x5e,0xc8,0x88,0x1b,0xd8,0x65,0x21,0x04,0x0e,0xe2,0x95,0x6d,0x62,0xea,0xeb,0xee,0xbe,0x47,0x0a,0x90,0x26,0xe3,0x85,0xd7,0x1d,0xb5,0xd5,0x56,0x8b,0xc0,0x2f,0x7f,0x01,0xc8,0xac,0x90,0xc3,0x2d,0x10,0xf2,0x11,0x30,0x0c +.byte 0xa9,0x4d,0x13,0xde,0x65,0x6d,0x34,0x68,0x5d,0xad,0x3f,0x7a,0x56,0x3a,0x1f,0xb9,0xd6,0x7b,0x8f,0xe8,0x42,0x2a,0x16,0xb6,0x3f,0xf2,0x4f,0x14,0x8e,0x8e,0x29,0x88,0x68,0x1b,0x10,0x80,0x80,0x47,0x36,0xaa,0x82,0xf5,0xa8,0x97,0xc4,0xcb,0xc2,0xef,0xaa,0x9f,0xdc,0x96,0x4f,0x1f,0xaf,0x39,0x71,0x55,0x8f,0x3c,0xbf,0x26,0x91,0x46 +.byte 0x38,0x59,0xa7,0xd1,0xb5,0x87,0xd6,0x81,0x71,0x17,0x83,0x05,0x40,0x9c,0xf3,0x33,0x4b,0x09,0x06,0xb1,0x69,0xfb,0x43,0x1f,0xef,0x9a,0xfe,0xc3,0x4e,0x4e,0x25,0xe1,0x3a,0xfb,0xf9,0xc9,0x97,0xe2,0x1c,0xa1,0x9a,0x06,0x6e,0xbb,0x16,0x4a,0x9f,0xf4,0x87,0x31,0x38,0x78,0xae,0x77,0x4c,0x42,0x28,0xc4,0x63,0xc0,0x49,0x37,0x4f,0xf9 +.byte 0xeb,0x31,0x0d,0x3e,0x0c,0x8a,0xb7,0x17,0xa7,0x90,0x26,0xc2,0xea,0xa5,0x9d,0xe4,0x4d,0xc6,0x3a,0x33,0x2d,0x47,0x42,0x8c,0xeb,0x50,0xea,0xfe,0x74,0x43,0x06,0xcd,0xa5,0xb1,0x49,0xf0,0x98,0x91,0x25,0xf4,0x8d,0x06,0xd1,0xeb,0x56,0x2c,0xf9,0xc4,0x84,0x02,0x9e,0xf2,0x3a,0xfe,0xb4,0x39,0xce,0xee,0x85,0xb6,0x64,0x6c,0xbc,0x1f +.byte 0xe6,0x86,0x00,0xc3,0xa9,0xb4,0x53,0xdf,0x2d,0x7c,0xc6,0xde,0x2e,0x79,0x25,0x5c,0xbb,0xe5,0xbe,0x33,0xe9,0x58,0x49,0x35,0xbe,0xae,0xbc,0x06,0xdc,0x48,0x9d,0xc3,0x08,0x6f,0xe8,0xb8,0x48,0x67,0xea,0x1c,0x05,0xb4,0xf7,0xe3,0xcc,0xc1,0xb3,0xa8,0x61,0xcb,0xa8,0xf6,0x12,0x52,0x68,0x06,0x36,0x2b,0x15,0x43,0xc9,0x98,0xfe,0xe5 +.byte 0x43,0x11,0x0d,0xc3,0x37,0x38,0x7a,0xcb,0x98,0x14,0xc1,0xaf,0x29,0x36,0x35,0x63,0x74,0x98,0xcf,0x0f,0x44,0xe4,0x6e,0xf7,0x3f,0x6e,0x15,0xe8,0xe9,0x93,0x7b,0x96,0x1b,0x84,0xe7,0x8b,0x83,0x30,0xa1,0xdc,0xc3,0xb8,0x18,0x2f,0xc5,0x34,0xd1,0xa5,0xb9,0xee,0x4a,0x04,0xbf,0x26,0x63,0x29,0xba,0x90,0xb5,0x7c,0x83,0x2b,0x1f,0xe8 +.byte 0x5c,0x9f,0x23,0x40,0x7f,0x9c,0x2f,0x76,0x96,0xd6,0xd5,0x13,0xda,0x5c,0x81,0xa4,0x60,0x60,0xbd,0x5e,0xb3,0xd2,0x2c,0xaa,0x48,0x04,0x74,0x31,0x5d,0xbd,0x46,0xd8,0x8d,0x3f,0x62,0x2d,0x1e,0x17,0x97,0x08,0x71,0x06,0x1b,0x96,0x1b,0xd5,0x80,0xa6,0x41,0x06,0x10,0x6e,0x36,0xd4,0xfb,0x36,0x6d,0x96,0xb8,0x86,0x22,0x34,0xda,0x7e +.byte 0x6c,0x5f,0x3b,0x95,0x35,0x1b,0x42,0x3c,0xf2,0x9d,0xe3,0xe9,0x3f,0x44,0xd5,0x4c,0x60,0x55,0xae,0xbe,0x4f,0xf2,0xb3,0x84,0xa1,0x79,0xdf,0x86,0xf0,0x8f,0xad,0xa5,0xa3,0x4a,0xea,0x5d,0x68,0x34,0x17,0x4c,0xb7,0xd8,0x6f,0x67,0x22,0x85,0xe2,0x16,0xcf,0xba,0xee,0x92,0xeb,0x95,0x8e,0x67,0xb1,0xf0,0xbb,0xb0,0x34,0x2f,0x58,0x49 +.byte 0x56,0x3e,0x81,0x31,0xb6,0xc3,0x2c,0xee,0x2b,0x85,0x72,0xbc,0xe9,0x20,0xaa,0x4e,0x34,0xb9,0x8b,0x32,0x2f,0x9e,0xd7,0x98,0x63,0x9d,0xfd,0x3a,0xe9,0x30,0x49,0x23,0x4a,0xb4,0xcb,0xc5,0xe5,0x78,0xcd,0x22,0x90,0xce,0x9f,0x35,0x13,0xda,0x8f,0x14,0xdb,0x36,0x0f,0x66,0x87,0x62,0x50,0xde,0x52,0x15,0x10,0x67,0x8a,0x5c,0xdb,0x76 +.byte 0x51,0x7f,0x72,0x9b,0x8e,0x91,0x39,0xc8,0x3c,0x34,0x0f,0x3d,0x92,0x07,0xb8,0xef,0x2a,0x8b,0x59,0xbd,0x82,0xc1,0x5c,0x95,0x93,0x0d,0x3d,0x9b,0x51,0x53,0x38,0x6b,0xd0,0xe3,0x5b,0xbb,0xe5,0x6c,0xc0,0xb5,0x71,0xa8,0xd8,0x7d,0x5d,0xbd,0xfc,0x69,0xcf,0xcc,0xa1,0xcd,0x83,0x9d,0x8f,0x46,0x47,0xe7,0x36,0x19,0x9f,0x4d,0xda,0x9c +.byte 0xcb,0x2a,0x47,0x58,0x93,0xbb,0x64,0xa3,0x89,0x53,0xbf,0xc7,0xc2,0xe2,0x65,0x0f,0x4f,0x17,0xc6,0x4c,0x15,0xfe,0x4b,0x95,0xb2,0x79,0x4a,0xb8,0xf6,0xae,0xcc,0xba,0xc3,0x5d,0x18,0xb2,0x8e,0xd8,0x6b,0x43,0x1b,0x2f,0xe1,0x36,0xb2,0xa5,0x22,0xa0,0xc7,0xc0,0x26,0x8e,0x48,0x77,0x0c,0x14,0xdd,0xdc,0xde,0x71,0x98,0xce,0xdd,0x61 +.byte 0x85,0xd9,0x23,0x42,0x7f,0x85,0xc8,0x06,0x81,0x3e,0xa2,0x0f,0x1e,0x3e,0xcf,0x33,0xef,0x43,0x6a,0xc7,0xee,0x3f,0x91,0x68,0x32,0x89,0xd9,0xed,0xdf,0x45,0x33,0x10,0xbb,0xd5,0xef,0x1d,0x3c,0x1e,0x26,0x21,0x4d,0x1a,0x06,0x98,0x60,0x71,0x7f,0xce,0x45,0x4e,0xe3,0x3f,0xfa,0xff,0xcd,0xe2,0x92,0x82,0x2e,0x83,0x69,0x9c,0xc6,0x5c +.byte 0x6e,0xb6,0xec,0x28,0xdc,0x7b,0xdb,0xf3,0x02,0x3a,0xf7,0xad,0x9b,0x7a,0x73,0xb2,0x07,0x70,0x76,0x9d,0xa2,0x11,0xcf,0x89,0xea,0xaf,0x6a,0xd2,0x15,0xeb,0x5a,0x99,0x1a,0x17,0x1d,0xce,0xc0,0x7f,0x50,0x26,0x84,0x07,0xd7,0x7e,0x33,0x27,0x74,0x84,0x18,0x32,0x86,0x32,0x34,0x28,0xe8,0x45,0x21,0xb7,0x26,0x3b,0x11,0xbb,0x9a,0x8b +.byte 0x46,0x8e,0x27,0xf8,0x62,0xb5,0x98,0x6e,0x03,0xee,0x9e,0xcb,0xbc,0x74,0xbe,0x63,0x7a,0x86,0xe5,0x75,0xeb,0x7f,0x14,0xa6,0x96,0x76,0x5a,0x46,0xa9,0xda,0xf1,0x4e,0x0e,0x90,0x59,0x56,0x4a,0x48,0x2d,0x91,0xbe,0x78,0x5b,0xfb,0xf7,0xea,0xab,0x1c,0xc0,0x0c,0x5d,0xba,0xb4,0x7b,0xc7,0x21,0xb1,0xc9,0xa3,0x20,0xe6,0xae,0xee,0x0e +.byte 0xf0,0x3b,0x44,0xd6,0xaa,0x57,0x88,0x1f,0x76,0xc8,0x43,0x07,0x91,0x71,0xa5,0xcc,0x04,0x38,0x01,0x13,0xa6,0xea,0x18,0x48,0x8f,0x09,0x8d,0x37,0x8b,0x6f,0x35,0x36,0x51,0xc6,0x30,0xca,0x9e,0xe2,0xaf,0x0c,0x26,0x14,0xe3,0xbf,0xea,0x0e,0x14,0x88,0x97,0xcc,0xf6,0xc1,0x8f,0xad,0xef,0x2d,0xc1,0x0f,0xad,0x45,0x12,0x7a,0xe6,0x37 +.byte 0x97,0xcb,0x34,0x83,0xd8,0xef,0x34,0x2a,0xce,0xd0,0x21,0x8a,0x7d,0x87,0x7a,0x66,0xf7,0x1c,0xdf,0xa0,0x3f,0xa0,0xf6,0xb3,0x24,0xee,0x6e,0x21,0xe9,0xc3,0x73,0xe4,0xd9,0xc6,0xf6,0xf6,0xac,0x25,0xb7,0xb5,0x64,0x7f,0xcc,0x88,0x3e,0x98,0xe1,0xef,0xa9,0xd2,0x03,0x10,0x4b,0xa3,0xbc,0x3c,0x24,0xfc,0x41,0x36,0x30,0x2d,0xca,0x17 +.byte 0x35,0xd6,0x17,0xa2,0x2b,0x48,0xed,0xd3,0xd7,0x18,0x4f,0x45,0xe9,0x59,0x03,0x35,0xa0,0x80,0x75,0x17,0x48,0xd5,0xea,0x07,0x7a,0x6c,0x3f,0x7a,0x2c,0x02,0x0a,0x7f,0xb5,0x17,0xea,0xf4,0xf6,0xb5,0xf4,0x81,0xba,0x69,0x44,0x81,0x6b,0xff,0xb2,0x43,0xae,0x3d,0x37,0x81,0x91,0x3f,0x6a,0x70,0x35,0x2d,0x06,0x9d,0xa8,0xb5,0xb8,0xc7 +.byte 0x19,0x3a,0x5f,0x59,0x79,0x0b,0x62,0x23,0xa4,0x5b,0x46,0x7b,0x17,0x82,0x19,0x87,0xe8,0xdf,0x09,0xb7,0x50,0x7e,0x40,0xe3,0x71,0x2d,0x09,0xde,0x69,0x2e,0x6c,0x35,0x5c,0x44,0xae,0xb7,0x05,0xb8,0x7e,0xb4,0xe4,0x34,0x05,0x1f,0xd2,0x1f,0xe5,0x79,0x2a,0x15,0xf8,0x8f,0x02,0xc7,0xc8,0x1e,0xe6,0x12,0x83,0x08,0x9c,0x7a,0x2f,0xc6 +.byte 0xc9,0x15,0x0f,0x0f,0x0f,0xa9,0x53,0x16,0x19,0x5b,0x74,0x58,0x6c,0xac,0x21,0x72,0x7f,0xa1,0xae,0xbc,0x34,0x76,0xa6,0x9b,0xbe,0x0f,0x13,0x55,0x50,0x5a,0x8b,0x9e,0xb3,0xf3,0x9e,0x8b,0x61,0xbe,0xb4,0x09,0x71,0x61,0xf0,0xd6,0xaa,0x8c,0x0d,0x0c,0x66,0x31,0x88,0xe3,0x71,0x6a,0xb5,0xaa,0xc0,0x9b,0xce,0x0d,0x79,0x90,0xc1,0x0a +.byte 0xf9,0xfe,0x4d,0x49,0xd0,0x5a,0x63,0xf1,0xfc,0x47,0x71,0x9e,0xbb,0xd1,0x2c,0xef,0xfe,0x90,0x28,0x75,0x82,0xf6,0xa5,0x95,0xea,0x65,0xfa,0xe8,0x04,0xcd,0xb4,0xe1,0x0d,0xb2,0xac,0xd5,0x12,0xf5,0x17,0xbb,0x3b,0x2e,0x52,0x9e,0x7b,0xe7,0x8e,0x86,0x03,0xce,0x77,0x01,0xf0,0x4f,0xb5,0xf7,0xef,0x8b,0x37,0x5e,0x97,0x80,0xbb,0x2b +.byte 0xcf,0x9a,0x63,0x18,0xc5,0x0c,0xfb,0x3c,0x91,0x9c,0x37,0x90,0x76,0x71,0x62,0xbc,0x80,0x40,0x1a,0x74,0xb8,0x1b,0x61,0xb1,0x89,0x4d,0xf7,0x8d,0xd4,0x46,0xef,0x1f,0x3b,0xac,0xe8,0x41,0x62,0x8e,0xea,0x2b,0x56,0x22,0x25,0x37,0x70,0x53,0xcd,0x8f,0x57,0xfa,0xad,0x00,0xc5,0x0c,0x9e,0x57,0xde,0x50,0x07,0x8d,0x80,0xbf,0x22,0x5d +.byte 0x4a,0xbd,0x6a,0xcb,0xfc,0x6f,0xd1,0x56,0x8f,0xd5,0x34,0x8a,0xe6,0xe9,0xa0,0x00,0x06,0x12,0xd8,0xb1,0x49,0x0a,0xbb,0x87,0xe5,0xca,0x75,0x11,0x4c,0x85,0x60,0x77,0xc0,0x90,0x1c,0x14,0x38,0x38,0x3e,0x4f,0xff,0xbf,0xfc,0xa1,0xa1,0xe7,0xb0,0x5d,0xd8,0x1f,0x33,0x07,0x5f,0x04,0x4f,0xc7,0x93,0xc6,0xcc,0xe3,0x01,0xd0,0x43,0xe1 +.byte 0xd9,0x00,0xc5,0x9f,0x79,0xab,0xfc,0xe9,0x55,0x51,0x03,0x0c,0xe1,0x73,0xd6,0x09,0xe3,0xb9,0x76,0x72,0x77,0x4c,0x1b,0x7c,0x57,0x1e,0x7f,0x5f,0x02,0x83,0xa3,0xc6,0xde,0x23,0x85,0x76,0x1a,0xbf,0x48,0xc8,0x02,0xdb,0x31,0x30,0x95,0x85,0x68,0x8a,0xf6,0xe9,0x48,0x7f,0xc9,0x26,0xab,0x68,0x36,0x9f,0x1c,0xf0,0x90,0xbc,0x4a,0x68 +.byte 0x94,0xf8,0x7f,0xae,0xa9,0x3b,0x5b,0x63,0x9a,0xcd,0xe3,0xf0,0xac,0x9f,0x6f,0x78,0xa0,0x67,0x58,0xd8,0x2c,0x71,0x8a,0x14,0x31,0x07,0x95,0x0c,0x38,0xa4,0x53,0x33,0x60,0x23,0x21,0x87,0x6b,0x4f,0xf9,0xa8,0xb8,0xfc,0x8e,0xf1,0x3a,0x03,0x0b,0x03,0x02,0x33,0xbc,0x6a,0xb9,0x8e,0x41,0xc8,0x38,0xd8,0x83,0x30,0x6a,0x61,0x5c,0xcf +.byte 0x49,0xdd,0xd7,0xda,0x2c,0xaf,0xc4,0x68,0xad,0x07,0x9c,0xd4,0xaf,0x94,0x64,0xcf,0xe1,0x9b,0x37,0x50,0x65,0x03,0x20,0x3c,0x34,0x43,0xe9,0xb0,0x9b,0xba,0xb1,0x9a,0x3e,0x10,0x99,0x8f,0x93,0xb7,0x3d,0xac,0xbd,0xab,0xa8,0xfa,0x74,0x90,0xe1,0x38,0xe4,0xf3,0x47,0xfc,0xad,0x8b,0xb4,0x98,0xe4,0x65,0xe9,0xd9,0x8a,0x21,0x81,0x4f +.byte 0x0c,0xd7,0xb1,0x84,0xb9,0x69,0x68,0x64,0xa3,0x1f,0x25,0x84,0x5f,0xf7,0x3f,0xca,0x52,0xff,0xda,0xc9,0x3d,0x5e,0x8b,0x57,0xd3,0x9a,0x1d,0xb7,0xae,0x90,0xa4,0xc3,0x78,0x68,0xfd,0x80,0x3f,0xfd,0x5c,0x09,0x83,0x5d,0xc2,0x48,0xd8,0x84,0xeb,0x8a,0xfe,0xbe,0x30,0x12,0x79,0x54,0x5f,0x7f,0x6e,0x4b,0x8a,0x1e,0xcb,0xcd,0xed,0xb6 +.byte 0xe9,0x6d,0x8a,0x1f,0xdc,0xb1,0x46,0xab,0xdc,0x0d,0xbf,0xda,0xd9,0x39,0x3b,0xd2,0x81,0x00,0x83,0x77,0x32,0xf7,0xdf,0x0e,0x31,0x5d,0x1d,0x6c,0xa7,0x4e,0x54,0xa8,0xac,0x81,0x8c,0xb6,0xa5,0x89,0x02,0xd7,0x2e,0xfd,0x26,0xa3,0x9e,0xcf,0xdb,0x1f,0x5a,0xf3,0x54,0xac,0xe5,0xd0,0x1f,0x9b,0xa7,0xab,0x28,0xcc,0x66,0xd3,0xbc,0x4c +.byte 0x54,0x1a,0x54,0x73,0x78,0xde,0x08,0xd5,0xa5,0x08,0xdc,0x00,0x09,0xc5,0x37,0x61,0x1a,0x98,0x12,0x84,0x2d,0xff,0xc3,0x25,0x62,0x93,0x83,0x05,0x66,0x3d,0xfb,0x1d,0x54,0x08,0x8a,0x50,0x03,0xc4,0xc4,0x6e,0xfa,0x16,0x83,0xbb,0x27,0xf1,0xb7,0x31,0x92,0x64,0x76,0xbc,0xf0,0x44,0x62,0xe9,0x5e,0x15,0x94,0xdc,0xe9,0xf3,0xf8,0x20 +.byte 0x93,0x4d,0x11,0xa2,0xc8,0xde,0x83,0xe6,0x75,0x63,0xfe,0x13,0x75,0x0f,0x79,0xd1,0x3d,0x75,0xb7,0x43,0x62,0x57,0x8d,0x96,0x9c,0xa3,0xc4,0xb2,0x84,0x6a,0x14,0x6e,0x17,0x32,0x09,0x76,0x95,0xbb,0xd6,0xc1,0x2e,0xdc,0x8c,0x73,0xd7,0xad,0x5a,0x41,0x8b,0xb3,0x7e,0x8d,0x90,0xec,0xf5,0xa0,0x46,0x90,0x4c,0x52,0xec,0x97,0xc6,0x98 +.byte 0x7d,0x19,0x77,0xa0,0x99,0x85,0x11,0x26,0x77,0x26,0xf9,0xac,0xe3,0x81,0xcf,0x7d,0x22,0xc8,0x00,0x3d,0x5b,0xee,0xa5,0xf8,0x6d,0xfe,0x47,0xe4,0xef,0x60,0xcc,0xd0,0x33,0xf7,0x5b,0xed,0xbd,0x82,0xc9,0xa8,0x41,0xb8,0x47,0x34,0x9f,0x62,0xb2,0x67,0x62,0xb0,0x3a,0x27,0x95,0xe1,0x22,0x76,0x98,0x0f,0x35,0xaf,0xfc,0x4d,0xc7,0x92 +.byte 0x92,0x7e,0xaf,0x3b,0x3a,0x36,0x5e,0x5c,0xbf,0x43,0x02,0x66,0x5a,0x30,0x78,0x82,0x52,0x20,0x98,0xd6,0xa1,0xe9,0x9a,0x61,0x54,0x0b,0x74,0x85,0xb5,0x99,0x69,0x9f,0x9b,0x3b,0x2f,0x49,0xec,0xb3,0x18,0x0c,0x4a,0x53,0x20,0xd7,0x80,0x7b,0xd4,0x20,0x21,0x32,0x89,0x08,0x81,0x50,0x2b,0x16,0x8d,0xbb,0xe6,0xbb,0xc7,0x74,0x80,0x67 +.byte 0x47,0xf1,0x06,0x68,0x02,0x37,0x31,0x00,0x50,0x8b,0xe2,0x44,0x85,0x2e,0x39,0x54,0xda,0x26,0x7b,0xe1,0xb0,0x23,0xd7,0x0c,0x3c,0x3b,0x81,0x9b,0xa6,0xbe,0x24,0xfd,0x09,0x73,0xbe,0xc3,0x2f,0xa0,0x7b,0x85,0x5b,0x1b,0x55,0x4e,0x9e,0x38,0x80,0x61,0xd7,0xe8,0x9b,0xec,0x88,0x00,0x6a,0x64,0x1b,0xd5,0x65,0x20,0x2a,0x62,0x64,0xbc +.byte 0x21,0xca,0xce,0xc3,0xeb,0x2d,0x2b,0x5c,0x4d,0xb8,0x7c,0xb5,0xbe,0x98,0x0d,0x5b,0x88,0x23,0x60,0xff,0xbe,0x0a,0xb6,0xdd,0xdf,0x28,0xd5,0x2c,0xe5,0x9d,0xb5,0x29,0xea,0x6c,0x3a,0xf4,0x78,0x91,0xa3,0xb2,0xab,0x12,0xf9,0x90,0x96,0xc9,0xa4,0xfc,0x4d,0x28,0x2b,0x0c,0x28,0x8b,0xb7,0x8b,0x36,0xd6,0x80,0xbf,0x07,0x09,0xf9,0x62 +.byte 0x32,0xc0,0x50,0x60,0xd9,0x73,0xe3,0xbe,0xfa,0xa6,0x78,0x48,0x47,0xd7,0xb5,0x39,0xd8,0x04,0x6d,0x79,0x98,0x2e,0xd6,0x3a,0xe5,0xc9,0x01,0xd0,0x00,0x2e,0xd2,0x8b,0xd7,0x1f,0xf1,0xba,0xd4,0x0e,0x9f,0x9d,0xab,0xbf,0x2c,0xe1,0x75,0xf6,0x9c,0xc0,0xae,0x73,0x2b,0x58,0xcb,0x6d,0x46,0x6d,0x11,0xb7,0xce,0xc7,0xef,0x34,0x2c,0x11 +.byte 0x93,0x3c,0x17,0xd9,0x3e,0xad,0xc9,0x4c,0xb3,0xd0,0x0a,0xd0,0xfe,0xf3,0x9d,0xc5,0x43,0x03,0xa9,0x78,0x4a,0x42,0x7f,0xfb,0x75,0xd2,0x85,0xfb,0xe7,0xe6,0xa9,0x48,0x2f,0xa6,0xc3,0x16,0xe2,0x2a,0x9d,0x0d,0xcb,0x2e,0x8b,0x75,0xa8,0x14,0x3a,0x2e,0xb1,0xff,0x58,0x1d,0xa8,0xa6,0xc0,0xf6,0x17,0xda,0xc1,0xce,0xaf,0x08,0xa9,0xc2 +.byte 0xa3,0xc1,0xab,0xb6,0xe8,0x10,0x57,0x8a,0xce,0xc0,0x03,0x5c,0x53,0x5c,0x02,0x5d,0xcf,0x5c,0x65,0xc6,0x47,0x3c,0x62,0x0e,0xa3,0xfc,0xe2,0xae,0x10,0x55,0x4a,0xb4,0x27,0xe8,0x59,0x5e,0x45,0xa9,0xbb,0x21,0x10,0x91,0x46,0x1f,0x50,0x3b,0xc6,0x8c,0xa1,0x8a,0xee,0x5e,0x6e,0x32,0xe6,0x42,0x40,0x79,0x7f,0xbb,0xb3,0x5b,0x05,0xde +.byte 0xe0,0xf6,0x7f,0x3d,0x37,0xe6,0xc3,0x3b,0x40,0xc9,0xe0,0x42,0x36,0xd0,0x0e,0x13,0x32,0x3e,0x48,0xce,0xd8,0xa2,0xef,0xae,0x93,0x66,0x7d,0xde,0xb9,0xdd,0x60,0x15,0x53,0xf2,0xd9,0x90,0x3d,0x38,0x8c,0xa6,0x34,0x44,0xb5,0x6c,0x74,0x7d,0x9d,0xe7,0xd0,0xef,0x6c,0xd6,0xfe,0x9b,0x79,0x4e,0x79,0x5e,0x48,0xef,0x93,0xb2,0x81,0x0b +.byte 0x2b,0xee,0x83,0x69,0x3d,0x15,0x8c,0x27,0x69,0x6f,0xca,0xbf,0x75,0x29,0x37,0xc6,0xe6,0xca,0xb2,0x70,0xd0,0xaf,0xc8,0x5e,0x69,0xf1,0x6b,0x2d,0x0d,0xe7,0xe9,0xbf,0x07,0x52,0xe5,0xac,0x98,0xcf,0xcf,0xd6,0xdd,0x7c,0x2b,0xfc,0x8f,0xd2,0x5f,0x81,0x4b,0x1b,0x7b,0x2d,0x84,0xe2,0x69,0x96,0xcb,0xa2,0x59,0x10,0xba,0xda,0x51,0x11 +.byte 0xeb,0xc3,0x4f,0x10,0xbf,0x8e,0x5b,0xbb,0xa3,0x29,0xe9,0xd8,0x0e,0x71,0xa0,0x1b,0xff,0xee,0x36,0x8c,0x00,0x83,0x6b,0x32,0xfe,0x05,0xeb,0x89,0x8f,0xed,0x48,0x22,0xe1,0x76,0x0a,0xac,0xae,0x3c,0x24,0x54,0x84,0xc2,0x0f,0x79,0x33,0x2b,0x49,0x35,0x1c,0x84,0x5a,0xca,0x92,0x6c,0x1f,0x78,0x15,0x5a,0x36,0xad,0xd5,0x1d,0x9d,0x10 +.byte 0xc1,0x5f,0x7c,0x61,0x60,0xba,0x2e,0xe6,0x9b,0x34,0x02,0xe9,0x68,0x1c,0xfb,0xbf,0x02,0xdc,0x79,0x57,0x1c,0x0f,0xc8,0x8c,0x2a,0x66,0x2a,0x50,0xaa,0x81,0x4e,0x1f,0xa8,0x2d,0xe4,0x61,0xe8,0x43,0x84,0xcb,0xda,0x96,0xf9,0x4a,0xd0,0x8f,0xe1,0xd7,0xc4,0x05,0xf5,0x76,0xfa,0x47,0x7a,0x07,0x1a,0x77,0xbb,0x63,0xb3,0x3a,0x85,0x3b +.byte 0x0d,0x32,0x4f,0x14,0x15,0x02,0x5b,0x9c,0xbc,0xc2,0x12,0x90,0x0f,0x7b,0x94,0x27,0x5f,0x70,0x23,0xd8,0x5d,0x54,0xc4,0xca,0x6a,0x69,0x9e,0xd1,0xb3,0x2a,0x75,0x1a,0x07,0x9c,0x20,0xf6,0x76,0x22,0x4d,0x09,0x30,0x24,0x3f,0x3b,0xe5,0xcb,0x4b,0x5a,0x03,0x2d,0xe8,0xbe,0xed,0xf0,0xe3,0x91,0xf2,0x6c,0xb8,0x02,0x2d,0x6c,0x7a,0xa6 +.byte 0xc1,0x8e,0xa7,0xbb,0x73,0xdf,0x40,0xa5,0x60,0x91,0xbf,0xbe,0x28,0x0b,0x37,0x2e,0x5f,0x4b,0xcd,0x14,0x4d,0x2d,0xfc,0x5e,0x43,0xb5,0x78,0x8d,0xea,0xa0,0x86,0x54,0x4f,0xb6,0x25,0x40,0x39,0x3f,0x9c,0x7a,0x26,0x74,0x88,0x42,0x53,0xb0,0x3b,0x81,0x75,0x04,0x67,0x41,0x65,0x66,0x2c,0xdc,0xe9,0xf0,0xb3,0xab,0x2a,0xa5,0xf3,0xef +.byte 0xfa,0xc5,0x10,0x63,0xe2,0x70,0xb5,0x29,0x60,0x86,0x9e,0xb9,0x0b,0xe2,0xc4,0x05,0xa9,0x3c,0x1b,0x60,0x15,0x6b,0x2f,0x74,0x93,0x5e,0x70,0x9a,0x56,0x6a,0xc4,0x92,0x49,0xaa,0x95,0x51,0xc4,0xba,0xfd,0xf6,0x2d,0x36,0x3e,0x66,0xbd,0x74,0xbc,0x2e,0xb3,0xad,0xa1,0x41,0x50,0x33,0x79,0x84,0xac,0x21,0x7a,0xfc,0x3a,0x8e,0xdb,0xcc +.byte 0x27,0xf6,0x2c,0x5c,0x23,0x38,0x73,0xd5,0xaf,0xc9,0x2d,0x9c,0x18,0x58,0xdf,0x8f,0x89,0x9d,0xdd,0x00,0x3c,0x5f,0x23,0x00,0x6e,0x66,0x1d,0xf3,0x1c,0x40,0x9d,0x43,0xb0,0x74,0xf1,0x41,0xa5,0x77,0xcb,0x8d,0x5b,0x94,0x68,0x95,0xb6,0x0e,0xd4,0x4d,0x47,0x9b,0xd2,0xcd,0x9b,0x94,0xa4,0x28,0xf9,0xf0,0x3d,0xcf,0x89,0xb1,0xc3,0x73 +.byte 0x84,0x15,0xb6,0xc8,0x6b,0xf1,0xb1,0xdc,0x1b,0x1a,0x6f,0xb5,0x73,0x87,0x8b,0x63,0xbf,0x4b,0x25,0x9b,0xe4,0xdd,0x44,0xed,0xe7,0x0e,0x6f,0x03,0xae,0xa1,0x5e,0x1f,0x5f,0xa7,0xa4,0xed,0x69,0x7a,0x91,0x6d,0x55,0xac,0xce,0x18,0x32,0x17,0x78,0x49,0x9f,0x1e,0x9c,0xd2,0x7b,0x1f,0x74,0x60,0xa5,0x64,0xb1,0x99,0xe6,0xc5,0x0d,0x69 +.byte 0xfa,0xb2,0xd9,0x05,0x61,0x71,0xa4,0x6f,0xc2,0xb6,0x91,0x0e,0x6c,0xf2,0xa6,0x6c,0xea,0x8e,0x94,0x8b,0xac,0xa7,0xfe,0x70,0x8e,0x8d,0xc2,0x85,0xa6,0xa7,0x8e,0xe8,0xfa,0xbc,0xa1,0xaf,0x0e,0xa9,0x06,0xa4,0x9a,0xb0,0x23,0x93,0xbc,0x93,0x2d,0x97,0x42,0xe2,0x0d,0x3a,0x65,0xb4,0x60,0x5b,0xeb,0xa1,0x20,0x8a,0xdc,0x17,0x6b,0xc5 +.byte 0x19,0xc3,0x67,0xbf,0xae,0xf7,0xb9,0xb1,0x88,0x7f,0xe5,0x1b,0xc2,0x61,0x97,0xa0,0xd3,0x64,0x74,0x6b,0x7a,0x46,0x39,0x3f,0xc8,0xd3,0x53,0x79,0x74,0x4e,0x1e,0x63,0x91,0xc5,0x4a,0x70,0xb0,0x05,0x35,0x19,0xc2,0x26,0x54,0x44,0x3b,0xa9,0x12,0x40,0xd0,0x21,0x19,0xf3,0x8d,0xc7,0x2b,0x88,0x9a,0xec,0x41,0x8f,0x4f,0x23,0x19,0x1a +.byte 0xf3,0x1d,0x0a,0x88,0x0f,0xa7,0x02,0xd4,0x78,0x88,0xe6,0x43,0xb6,0x9e,0x07,0xdf,0x6a,0x1f,0x41,0xbb,0x3e,0xea,0x15,0xff,0x66,0x4c,0x7a,0x8b,0xee,0x27,0x47,0x81,0x81,0x95,0xa2,0x22,0xb4,0x9f,0x1c,0x09,0x1c,0xfc,0x0a,0xef,0x88,0x7f,0x59,0x60,0x91,0x6a,0xe4,0x92,0x8c,0x02,0x54,0xc9,0xee,0xc7,0x5e,0xd1,0xbf,0xc9,0x41,0xde +.byte 0x2f,0xa3,0x22,0x07,0x1d,0x8c,0xe1,0x04,0x59,0x94,0x75,0x3e,0xee,0x56,0x62,0x07,0x80,0x18,0x60,0x78,0x0e,0x55,0x06,0xec,0xe1,0xa5,0xf6,0x21,0x7e,0xf9,0x37,0xab,0x6a,0xed,0x07,0xcb,0xbf,0xa2,0xab,0x50,0xee,0x1f,0x2f,0x54,0x2b,0x82,0x93,0x59,0x03,0x35,0xd9,0xe8,0x2b,0xa6,0x03,0xc2,0xef,0x37,0x85,0xfc,0x89,0x06,0x30,0xe0 +.byte 0xc2,0x00,0xc4,0xaf,0x59,0xb6,0x31,0x52,0x37,0xa4,0x6c,0xdb,0x1b,0x20,0x87,0xf0,0xa4,0x15,0x4b,0xa8,0xd9,0x7e,0x1b,0x96,0x00,0x07,0xf4,0x86,0x07,0x14,0x55,0x70,0x37,0xe3,0xe3,0xf0,0xeb,0xd6,0xf1,0xe0,0xe9,0x6c,0xdf,0x3d,0xaf,0x86,0xb8,0x00,0x9b,0xdf,0xc6,0x5c,0xd2,0x53,0xcb,0xcf,0x63,0xcc,0x3e,0x6d,0x62,0xeb,0xe6,0x97 +.byte 0xd8,0x54,0xed,0x36,0xe4,0xed,0x69,0xaa,0x10,0x83,0xde,0x16,0xfd,0xcc,0xd6,0x24,0xb9,0x3c,0x4f,0x99,0x81,0xc2,0x23,0x16,0x91,0x5d,0x9f,0x46,0xa5,0xdd,0xb4,0x8a,0xe1,0x07,0x89,0x84,0x2e,0x62,0x48,0xf6,0x1a,0x17,0x7b,0xc8,0xf7,0xb4,0x3d,0x9e,0x82,0xe3,0xe3,0xcf,0x0b,0xd9,0x52,0x90,0x61,0xd8,0xdf,0x9e,0xc4,0xc7,0x7c,0xfa +.byte 0xcf,0x09,0xd2,0x94,0x86,0x37,0x94,0xaf,0x7e,0x0a,0x9d,0x16,0xee,0xad,0xfb,0xa2,0x9e,0x2d,0x2f,0xad,0xd5,0xc2,0xf9,0x91,0xf8,0x7e,0x2b,0xb8,0xb2,0x60,0x3c,0x0a,0x89,0x53,0x07,0x87,0x3b,0x83,0x70,0xee,0x71,0xa3,0x94,0x0b,0x77,0x50,0xeb,0xcc,0x23,0xf0,0xbe,0x95,0x51,0x54,0xd2,0xd6,0xd2,0x09,0xa5,0x19,0x3d,0x4e,0xec,0xe3 +.byte 0x88,0x71,0xa7,0xb1,0x10,0x03,0x7e,0xc4,0x92,0x2a,0xe7,0x99,0x75,0xff,0xae,0x10,0x3d,0xbb,0x33,0xc9,0x7f,0xc2,0xe6,0x3c,0xc4,0xe7,0xba,0x37,0xba,0x68,0x69,0x92,0x4a,0xfb,0x32,0x3b,0xb5,0xde,0xdb,0x91,0xd0,0x8e,0x77,0xf2,0x1e,0x2d,0x25,0xb4,0xa0,0x42,0xef,0x78,0x6c,0x75,0xcb,0xa0,0x73,0xdf,0xde,0xd8,0x26,0xfe,0xe3,0xf9 +.byte 0x74,0xe7,0xa0,0xd2,0xbd,0x6c,0x99,0x8d,0x07,0xf2,0xf8,0xff,0x36,0x2d,0x8e,0xda,0x5e,0x5c,0x47,0x06,0xf8,0x08,0x33,0x1d,0x93,0xcf,0xc3,0x1a,0x20,0x86,0xb6,0x8e,0x44,0x10,0xbc,0xba,0x89,0xfc,0xa3,0x57,0x92,0x2c,0x28,0xa1,0xd0,0xab,0xdc,0xba,0x0a,0x7e,0x9d,0xd2,0xfd,0x09,0xd3,0x87,0x6c,0x06,0x44,0x17,0x73,0xfe,0xc9,0x8b +.byte 0x52,0xd3,0x09,0x60,0x14,0x03,0xb1,0x79,0x4c,0x9c,0xc4,0xec,0x42,0x4c,0xd3,0x21,0xe5,0x34,0x21,0x38,0xdd,0x12,0x95,0xd4,0x20,0x50,0xef,0x5f,0x46,0x4f,0x37,0x65,0xd5,0xf1,0xb2,0x2c,0x6c,0x9a,0x06,0x28,0x77,0xbf,0xe3,0xec,0xec,0x2b,0xcb,0x2c,0x8b,0x62,0x2e,0x39,0xaa,0x28,0x0b,0x51,0x01,0xa5,0x02,0x06,0x66,0x4a,0x67,0x0c +.byte 0x96,0xa3,0x12,0x74,0x94,0x2c,0x0f,0x23,0xa3,0xea,0xda,0x1a,0x6d,0x54,0x30,0x33,0xc8,0x33,0x0a,0xfb,0x25,0x2a,0x8b,0x9a,0x87,0xd9,0x9d,0x37,0x4c,0x41,0x3b,0xe5,0x4a,0x81,0x92,0x40,0x38,0x18,0x82,0x13,0x54,0xde,0x56,0x11,0x63,0xf3,0x09,0x61,0x3b,0xdd,0x0c,0x71,0xe8,0x4f,0xc2,0x9a,0x77,0x2f,0xeb,0xf1,0x39,0x1c,0x10,0x0e +.byte 0x01,0xaf,0x92,0x34,0x9a,0xb6,0x7b,0x79,0x86,0x0c,0xf1,0x53,0xb6,0x59,0xbd,0x6d,0x79,0x6e,0x37,0x11,0x25,0x67,0x95,0x31,0x4f,0x43,0xdf,0xb7,0x4b,0x80,0x8d,0x07,0x3c,0x49,0x73,0x8a,0x72,0x61,0x02,0x0f,0x2f,0x13,0xed,0x91,0x10,0xf6,0x08,0xf3,0x50,0x4a,0xd4,0x36,0xcb,0x52,0xb3,0x3b,0xe6,0xef,0x85,0xe9,0xe0,0xad,0x0d,0x3d +.byte 0x84,0x07,0x70,0xdf,0x16,0x47,0xeb,0x26,0x19,0x27,0xaf,0x7a,0x9f,0x2f,0x2b,0x6d,0xbb,0x37,0x68,0x8e,0x19,0x46,0x5a,0x65,0x0d,0x0a,0x67,0xd8,0xe2,0xc2,0xcd,0x49,0xf6,0xc2,0x27,0xac,0x12,0xea,0x1f,0x81,0x60,0xac,0x8b,0x5d,0xcc,0x9a,0x5b,0xec,0xc3,0xcb,0x85,0x0d,0xef,0xa6,0xd5,0x33,0xb3,0x67,0x73,0x3f,0xc9,0x90,0x25,0x3e +.byte 0xe6,0x7c,0x41,0x59,0x83,0xf7,0x90,0x4a,0xbf,0x14,0x72,0x11,0xf2,0x3a,0x38,0x58,0x17,0xd8,0x3d,0x00,0xc6,0x42,0xf2,0xbc,0xfd,0x05,0x37,0x6d,0x11,0xb0,0xd7,0xb2,0xb7,0x73,0x69,0x80,0x47,0x30,0x64,0x13,0x8c,0x24,0xb2,0x42,0x12,0x8c,0xc0,0x8a,0x45,0x0b,0x71,0x23,0xeb,0xac,0x65,0xda,0x44,0x13,0x85,0x77,0xdf,0xb8,0x4b,0x69 +.byte 0xd4,0x8e,0x40,0x54,0x24,0xac,0xc8,0x62,0x36,0x51,0x20,0xaa,0xcd,0x5d,0xa5,0x73,0x2c,0x81,0x92,0x99,0x44,0x6b,0x04,0xac,0x8e,0xee,0x96,0x29,0xca,0xdc,0x2f,0xd1,0x13,0x5c,0x9e,0xc2,0x67,0x6a,0xaf,0xf6,0x3e,0xe2,0xa1,0x6d,0xda,0xbe,0x8a,0x55,0x50,0x27,0xee,0x6d,0xb8,0x35,0x5f,0xb4,0xa8,0x76,0xa1,0xe2,0x52,0x87,0xf6,0xfb +.byte 0xe2,0x16,0x1c,0x90,0x78,0xe4,0x17,0xb0,0xd9,0x56,0xf5,0xd3,0xa4,0xb0,0x3f,0xe9,0x01,0xf9,0xd0,0x67,0x2b,0xeb,0x1d,0x73,0x24,0x90,0x36,0x36,0x0d,0xcf,0xfb,0x3f,0xa1,0xa0,0x25,0x3b,0xf1,0x7f,0x9e,0x90,0xcf,0xb6,0xd0,0x83,0x90,0xcd,0x3f,0xff,0x5f,0xa3,0x33,0x95,0xd7,0xbe,0x78,0xfe,0xcc,0x9a,0xb9,0x64,0x88,0xb7,0xd9,0x5e +.byte 0x46,0x2d,0xf0,0xb1,0xa1,0x81,0x2b,0xab,0x80,0xf5,0x4d,0x3b,0xd8,0x53,0x64,0x8f,0xac,0x7a,0x03,0xb3,0x39,0x7a,0x85,0xef,0x61,0xb5,0x2c,0x8e,0xf4,0x27,0x07,0x9b,0x7b,0xc9,0x8b,0x1a,0xe4,0x4f,0xce,0x8b,0x35,0x32,0xac,0xcf,0x47,0xb8,0x2f,0x9e,0xe5,0x11,0x48,0xc1,0x07,0xea,0x0c,0xee,0x06,0xc6,0xa3,0x48,0xb6,0x1a,0xd8,0xb4 +.byte 0xa7,0xae,0x59,0x7d,0x9e,0x4e,0x66,0x7f,0xe9,0x02,0x40,0xdc,0x21,0x5e,0x74,0x2c,0x1d,0x29,0x22,0xca,0x97,0x4f,0xc8,0xc7,0xea,0x69,0x02,0x89,0xd1,0x43,0xff,0x83,0x89,0x58,0x66,0x92,0xbc,0x11,0xf6,0x02,0x8b,0xa8,0x34,0x8d,0xbe,0x3a,0x70,0xc3,0x10,0xe7,0xb5,0xc4,0xda,0xdb,0xc6,0x87,0xee,0xee,0xe0,0x48,0x62,0x80,0x8d,0xfc +.byte 0xaa,0xc7,0xce,0x1a,0xea,0xb9,0x1b,0x30,0x4a,0x48,0x9b,0xf4,0x58,0xff,0x5d,0x15,0xc8,0xf2,0x84,0x44,0xae,0x63,0xe8,0xb1,0xe0,0x2e,0x38,0x8e,0x47,0xf9,0x09,0xec,0xb9,0x94,0x18,0x37,0x68,0xef,0xbd,0xd5,0x67,0x72,0x01,0x9a,0x15,0xb9,0x7c,0x36,0xc0,0x22,0x80,0x12,0xb1,0x4e,0xab,0x3c,0xea,0x81,0xcf,0x70,0xf3,0xde,0x1f,0xd4 +.byte 0x67,0x94,0xfa,0xe1,0xf0,0xb6,0xd6,0x6b,0xc3,0xa2,0xbb,0x59,0x6b,0x9f,0x58,0x26,0x99,0x0c,0xdc,0xcd,0xb8,0xae,0x49,0xf0,0x8f,0xd3,0x0d,0xb7,0x4c,0x22,0xcf,0xb6,0x6c,0xa3,0x19,0x09,0x42,0x59,0x25,0xf8,0xdc,0xf3,0xc2,0x00,0xc3,0xc3,0xd3,0x9e,0x98,0xd3,0xa3,0xd0,0x96,0xfd,0x4f,0x15,0x57,0x5b,0xa7,0x08,0x3a,0x0e,0x3d,0xd2 +.byte 0x7d,0xa1,0xa0,0x94,0xc0,0x76,0x83,0xf6,0xc1,0xe8,0x7e,0xd3,0x97,0xc1,0xbf,0x38,0x74,0x9b,0xfb,0x35,0xeb,0xf7,0x34,0x20,0xea,0xda,0xd3,0xb1,0x2e,0x10,0x16,0x9c,0x09,0x1c,0x67,0x46,0xa2,0x05,0xf9,0x47,0xde,0x35,0x53,0x18,0x58,0xb0,0xbb,0x7a,0x88,0x58,0xc5,0x3e,0x98,0x29,0x43,0x98,0x07,0x76,0xa3,0xe1,0x95,0x92,0x21,0xe9 +.byte 0x06,0x17,0x15,0xe0,0x6b,0xd5,0x5a,0x6d,0x10,0xa6,0x08,0x92,0xa9,0xf5,0xcf,0x57,0x1a,0x28,0x5d,0x14,0x33,0x99,0xf9,0xa0,0xb3,0xeb,0xee,0xd4,0x6e,0x0b,0x5e,0xf7,0xe9,0xe3,0xc6,0x71,0x34,0x55,0xf3,0xde,0xd5,0xc2,0x52,0xc3,0x7b,0x06,0x87,0xef,0x26,0x81,0xc9,0xbd,0xaf,0x12,0x61,0x95,0x2b,0xa4,0x8e,0xe8,0x08,0x9a,0x13,0x48 +.byte 0x2e,0x84,0x98,0xf6,0x95,0x21,0x22,0xe5,0xcf,0x30,0x8d,0xaf,0x70,0x16,0x27,0x0c,0xcd,0x26,0x7f,0xe8,0xa0,0x35,0x0c,0x01,0x0e,0xdd,0x9d,0x2c,0x89,0x41,0x34,0xc4,0xa2,0xaa,0xf6,0x3f,0xca,0x3b,0x86,0xce,0xd7,0x4c,0xe3,0xb5,0x69,0xe9,0x41,0xbe,0x3c,0x9a,0x4c,0x1a,0xb3,0x88,0xea,0x78,0x12,0x4c,0x1b,0x79,0xc7,0xcd,0x32,0x72 +.byte 0xfa,0x3f,0x0b,0x73,0x1b,0xd9,0xec,0x85,0xd4,0x52,0x6c,0x91,0x2d,0xbe,0x76,0x8b,0xfd,0xb6,0x49,0xcf,0x67,0xd1,0x18,0x7b,0xae,0x86,0x47,0x47,0xfd,0xff,0x63,0xf2,0x88,0x1b,0x58,0xd5,0x30,0x69,0xf9,0x9a,0x03,0x52,0xae,0xe5,0xe2,0x55,0xbf,0x35,0x12,0xb0,0x84,0xa9,0xed,0xb6,0x8d,0x5f,0x6c,0xed,0x1a,0x00,0x7a,0xdc,0xf2,0x03 +.byte 0x9e,0xef,0x59,0x27,0x4c,0xf4,0x83,0xa2,0x36,0x3d,0x3d,0x8c,0x75,0x8c,0x37,0x68,0x93,0x0b,0x30,0x48,0xea,0x91,0x14,0x37,0x88,0x87,0x7f,0xe6,0xd8,0xbd,0x04,0x34,0x1e,0xe8,0x2a,0x41,0x48,0x5c,0x66,0xf9,0xc2,0xd1,0x56,0x25,0x29,0x45,0xfa,0x71,0xe1,0x59,0xa8,0x52,0x99,0x0b,0x92,0xe0,0x33,0x52,0x91,0xd6,0x5f,0x0a,0x70,0x83 +.byte 0x4f,0xa3,0x47,0x6e,0xfa,0x85,0x5e,0xb1,0x0a,0x1d,0xe7,0x35,0xc9,0x88,0x27,0xc9,0x8c,0x3e,0x7f,0x6d,0x34,0x1e,0x11,0x7b,0xcd,0xe7,0x09,0x82,0x3a,0xa1,0x46,0xc6,0x15,0xde,0x0b,0xde,0x35,0x71,0x92,0x5c,0x72,0x50,0x08,0x6b,0x62,0xa7,0xec,0xa2,0xca,0x53,0x6e,0x47,0x7d,0x50,0x32,0xa7,0x32,0x7b,0x49,0x0c,0x97,0xcc,0x98,0x8d +.byte 0xc3,0x29,0x72,0x1e,0x85,0x47,0x1b,0xa7,0x89,0x19,0x85,0xaa,0x3f,0x11,0x6a,0xea,0x61,0x84,0x07,0x9a,0xc8,0xb3,0x25,0xfe,0x72,0xca,0x83,0xa9,0xf0,0x9e,0x01,0xe4,0x9a,0xd6,0x1b,0x87,0xfc,0xd4,0x3a,0x04,0x34,0x8c,0x0b,0x46,0xbc,0xe9,0x3c,0x3f,0xd9,0x93,0xf1,0xca,0x41,0x0b,0xdb,0x28,0xe8,0x28,0x1b,0x84,0x36,0x16,0x84,0x22 +.byte 0x1e,0x1e,0x2b,0xb0,0xfb,0xa6,0xcc,0x95,0x31,0x46,0xd7,0xca,0xc2,0x8b,0xa3,0x3a,0xa5,0xb0,0xaf,0x52,0x66,0x53,0x39,0x5f,0x58,0xb5,0xdf,0x01,0x52,0x07,0xb4,0x82,0xdc,0xb7,0xf9,0x88,0xd8,0x77,0xf8,0x12,0x9d,0xe8,0x21,0xd7,0x0b,0x0f,0x57,0x90,0x40,0xb2,0x64,0x3f,0xce,0xa0,0xa3,0xfa,0x12,0x16,0xec,0x6d,0xcc,0xc7,0x2a,0x43 +.byte 0xc9,0xe7,0xb7,0x90,0x52,0x35,0x22,0x6d,0x46,0x99,0x1e,0x44,0x12,0xd6,0x0f,0xaf,0x5c,0x16,0xd3,0x7a,0xd6,0xb4,0xfe,0x20,0x26,0x11,0xe1,0xc6,0xa5,0x10,0xfd,0x9f,0x0c,0x47,0xae,0x32,0x08,0x15,0x8f,0xef,0xef,0x4c,0x83,0xbc,0xbf,0x6a,0xe5,0xf5,0x69,0x11,0x4d,0x7d,0x47,0x1f,0x10,0x58,0x61,0xb0,0x0d,0x98,0x67,0xc0,0x99,0x3a +.byte 0x2d,0x9a,0x5b,0xd5,0x37,0xe7,0xe5,0xd4,0x56,0x96,0x69,0xf8,0x53,0x7e,0x24,0x70,0x51,0x01,0x83,0x8d,0x49,0x01,0x32,0x7d,0x4f,0x41,0x92,0x54,0x9c,0x15,0xf1,0x3c,0x05,0x32,0x28,0x0d,0x0f,0x67,0xbe,0x65,0xfa,0x1b,0xa3,0xd0,0x28,0x18,0xb8,0x84,0xfe,0x6a,0x30,0xea,0xb9,0x00,0xb1,0x10,0x7c,0xa2,0x94,0x4f,0x86,0x18,0xdd,0xb4 +.byte 0x80,0x18,0x48,0x18,0xe1,0x56,0x70,0x7d,0x5c,0x3b,0xe5,0xd7,0x88,0x66,0x57,0xe3,0xe1,0x04,0x4c,0x68,0x5b,0x64,0x4d,0x0d,0x30,0x76,0x26,0xaa,0x84,0x0e,0xe0,0xed,0x53,0x62,0x20,0x33,0xaf,0x45,0x42,0x40,0x47,0x01,0x15,0xc9,0x0b,0x27,0x7c,0x68,0x4d,0x55,0xc4,0x6a,0x5f,0x96,0x9f,0x96,0x67,0xae,0x13,0x1c,0x84,0x52,0x33,0x41 +.byte 0x80,0xfc,0xae,0xb6,0xb1,0x8c,0xc3,0x19,0x80,0xa8,0x5f,0xe5,0x8c,0xd0,0xa8,0xb4,0x58,0xc9,0x48,0x29,0xab,0x11,0xd1,0x09,0xc6,0x20,0x98,0x4c,0xdb,0xa4,0x83,0x5c,0x26,0x51,0xce,0x80,0xe5,0xc4,0x9b,0xae,0xba,0x8e,0x99,0x4e,0xa4,0xff,0xdc,0x99,0x4c,0x02,0xa0,0x42,0x80,0xca,0xd7,0xea,0x6a,0x58,0x31,0xdb,0x16,0xd8,0x4d,0xab +.byte 0x03,0x2e,0x3a,0xdc,0xe9,0x07,0xfb,0xfb,0x5b,0x57,0x67,0x2a,0x7b,0xdc,0xc1,0x66,0xd1,0x31,0x3a,0x03,0x87,0xd8,0x66,0xda,0xa1,0x24,0x00,0x26,0xc0,0x26,0x78,0xf8,0x59,0x13,0x3f,0x34,0x08,0x35,0x45,0xbd,0x45,0x4f,0x89,0x65,0x97,0xdb,0xe6,0x1e,0x09,0x6e,0x23,0x2a,0xc4,0xf5,0x6a,0x74,0x28,0xb0,0xae,0x8c,0xfb,0x49,0x35,0x99 +.byte 0x06,0x30,0xc6,0xb2,0x8c,0xcd,0x8b,0x41,0xea,0xf2,0x04,0x18,0x29,0x25,0x1b,0x32,0x42,0x45,0xb5,0x92,0x42,0xb4,0x33,0xd2,0x90,0x31,0x08,0xcd,0x35,0x5d,0x50,0x64,0xa8,0x93,0xfd,0xa5,0xfd,0x32,0xbd,0xe8,0x13,0x1c,0x48,0x5c,0x14,0x70,0x03,0x92,0x0f,0x12,0x86,0xf6,0x6c,0xcd,0xc6,0xec,0xbf,0x8e,0x85,0x28,0x1d,0x1c,0x63,0x3f +.byte 0x81,0x93,0xd4,0x80,0x3c,0x29,0x0b,0x63,0xfe,0x87,0xa6,0x24,0xd6,0x3e,0x62,0xb6,0xd9,0xb0,0x58,0xf1,0x41,0x36,0xc7,0x47,0x8b,0xfd,0x4b,0x91,0x4e,0x5d,0x41,0x44,0xb0,0x65,0x3d,0x9e,0x3b,0x70,0x01,0xcc,0x7d,0x77,0xf0,0x23,0xd9,0xca,0x5f,0xda,0xa1,0x8c,0x71,0x11,0x91,0x7d,0x36,0xf5,0xc9,0xcd,0xf4,0x34,0x5f,0x69,0x57,0xd6 +.byte 0x33,0x4c,0xb2,0xe1,0x38,0x5f,0x86,0x3c,0x57,0x7b,0x2e,0x99,0x05,0x80,0x63,0xc4,0x77,0x69,0x06,0xc2,0x47,0x44,0xca,0x17,0x27,0x1d,0x55,0x34,0x02,0xd0,0x89,0x3a,0x3b,0x79,0xf0,0x86,0xd7,0x6b,0x01,0x9c,0xc7,0xa8,0xde,0xdb,0xdf,0x49,0xd1,0xb9,0x11,0xaf,0x7e,0x22,0x8b,0x5d,0xb5,0x0b,0xdc,0xd0,0x36,0xe6,0x9d,0x85,0x41,0x4a +.byte 0x35,0xf0,0xe1,0xcd,0xce,0x7b,0xd1,0xd6,0x00,0xdd,0xb6,0xe4,0x06,0x3e,0x66,0xe9,0x2b,0xa8,0x44,0x0d,0x18,0xd4,0xbc,0xfb,0x3c,0x58,0x6c,0x11,0xe9,0xdc,0x19,0x14,0x08,0x27,0x23,0x0c,0xd0,0xf9,0x97,0xaf,0x97,0x07,0x02,0x1a,0x5e,0xcd,0xae,0xd2,0x80,0x96,0x16,0x49,0xc3,0xfc,0xda,0x25,0x12,0x20,0xe1,0xc0,0x68,0x90,0x4b,0x30 +.byte 0x2d,0x06,0x53,0x2c,0x57,0x63,0x4a,0x7a,0xf6,0xc8,0x5a,0xb7,0x58,0x8c,0x13,0xfe,0x43,0xb3,0xf8,0x25,0x3e,0x7a,0x25,0x3e,0x1d,0x7f,0x8f,0x5e,0xdb,0xad,0x99,0x83,0xfc,0xd9,0x0a,0xdf,0xb5,0x19,0x1c,0x2c,0xf6,0xe8,0x06,0xbe,0xc0,0x9f,0x7e,0x0f,0x95,0xaa,0xac,0x09,0xdc,0x8c,0x37,0xcf,0x35,0x35,0x95,0x62,0xf1,0xff,0x96,0x1c +.byte 0x77,0xe9,0x53,0x7e,0x12,0x56,0x2d,0x4e,0x3e,0x1f,0xdb,0x1d,0x71,0x0e,0xdc,0xf7,0x65,0xb1,0x78,0x7f,0xe4,0xba,0xbf,0x7f,0x6c,0xcb,0x73,0xd3,0xe8,0xd9,0xce,0xfb,0xdb,0x48,0x87,0xe0,0x10,0x00,0x74,0xcb,0xdf,0x32,0xa8,0xdd,0x83,0x24,0x49,0xda,0x86,0x38,0x1c,0x2c,0x93,0x09,0x8a,0x26,0xbb,0x34,0x21,0x1d,0xac,0xb5,0x16,0xae +.byte 0xd8,0xcb,0x94,0x04,0xd6,0xbc,0xde,0x9c,0x70,0x28,0xa5,0x1a,0x15,0x5e,0x35,0xe4,0xe6,0x53,0xea,0x9c,0x3b,0x0c,0x36,0x3b,0x80,0x13,0x28,0x1d,0xc7,0x1a,0xa8,0x8e,0x9e,0x09,0xce,0x5d,0x50,0xd3,0xc7,0x6f,0x3a,0x75,0xa5,0x84,0x1c,0x08,0x66,0xe6,0x05,0xda,0x8b,0xf1,0x4b,0x5c,0xe2,0xc7,0x0f,0xa1,0xf1,0x47,0x02,0xf4,0xa7,0x24 +.byte 0xf3,0x0e,0x2c,0xa9,0xae,0x67,0xdf,0xce,0x30,0x88,0x4a,0x9a,0x39,0x4a,0x97,0x64,0xa8,0x30,0x53,0xf9,0x47,0x66,0x5c,0x19,0x1c,0xfb,0x2f,0x05,0x89,0x4f,0xfe,0x25,0xe7,0xed,0xed,0x17,0x5a,0x86,0xeb,0x25,0xee,0xe4,0x09,0x88,0x05,0x49,0x20,0x54,0x4b,0x7f,0x3e,0xb5,0x23,0x85,0xa9,0x66,0x61,0x73,0xe0,0x61,0x94,0xc6,0xe5,0x29 +.byte 0xb4,0xe1,0x6f,0xa4,0x4d,0x50,0x56,0x2e,0x30,0x75,0x51,0x5d,0xdd,0xa2,0x68,0x56,0x67,0xd8,0xec,0x2d,0x2a,0xfd,0x49,0xc5,0xbc,0xae,0x2f,0x6b,0xc7,0x8d,0x2e,0xca,0x91,0x35,0xe8,0xea,0x65,0xe9,0x9c,0x65,0xaf,0x8e,0xd5,0x16,0xdf,0xac,0x44,0x1e,0xb6,0x16,0xf0,0xb6,0x33,0x6a,0xe6,0x96,0x0f,0x85,0x2e,0xa1,0xaa,0x6a,0xe0,0x12 +.byte 0x0c,0xaa,0x7d,0xae,0xf7,0xe3,0xb2,0x4c,0x3c,0x10,0xc6,0x87,0x8e,0x87,0xfb,0xac,0xf7,0xd7,0x7a,0x2e,0x9a,0x7a,0xa7,0x4f,0xf0,0x75,0xce,0xbd,0xc3,0xe6,0x79,0x1d,0x56,0xab,0xff,0x56,0xfe,0x69,0xbd,0xcf,0x15,0x27,0x64,0x3c,0x83,0x1c,0x08,0xb0,0x91,0x60,0x67,0xe7,0x27,0x44,0x49,0x22,0x78,0xd5,0x1a,0xc8,0x3b,0x35,0x9b,0xa5 +.byte 0x53,0xce,0xde,0x04,0xd2,0x3e,0x67,0x48,0xaf,0x54,0xdf,0x9c,0xf7,0xb9,0xd4,0xe3,0xb6,0x85,0x02,0x68,0x21,0x10,0xdb,0xb5,0xca,0x11,0xa2,0x7c,0xcf,0x13,0x41,0x7a,0xfd,0xe9,0x0a,0x3c,0x53,0xd6,0x07,0xf2,0xdd,0xe2,0x7c,0x16,0xf0,0x44,0x3f,0x5d,0x34,0x09,0x7c,0x7b,0x21,0x8c,0x8e,0xdb,0x0d,0xc5,0x73,0xce,0x61,0xce,0x17,0x46 +.byte 0x6c,0x14,0x07,0xb5,0x70,0x80,0xf0,0x29,0x7c,0x13,0x41,0x2d,0x8e,0xdc,0x53,0xc2,0xbf,0xf0,0xc2,0xfb,0x59,0xa0,0x66,0x5f,0x25,0xda,0x17,0x5f,0xac,0xab,0x75,0x1b,0xc7,0x61,0x87,0x53,0x80,0x2e,0x11,0x4e,0x04,0x48,0xf9,0xee,0x54,0xe6,0x69,0x69,0x57,0xc2,0x46,0xd8,0xb3,0x2e,0x7b,0xc8,0xa5,0xd0,0xb2,0x5e,0xd4,0x6b,0x9b,0x1a +.byte 0xd6,0x79,0x9d,0x99,0xa6,0xbb,0x4d,0xca,0x74,0x2c,0x3d,0xd4,0x86,0xd0,0x64,0xd4,0x81,0x49,0x76,0x42,0xb8,0xf9,0x2c,0x52,0xe7,0x77,0x37,0x31,0xbb,0x2e,0x5b,0x38,0x81,0x01,0x2c,0x27,0x28,0xcb,0x0c,0xba,0xfa,0x8a,0x9a,0x45,0x51,0xa2,0xde,0xf2,0x7b,0xe6,0x65,0xec,0x5b,0x2d,0xe8,0x55,0x8e,0xb4,0x7f,0xf8,0x1a,0x66,0x3a,0x5f +.byte 0x06,0x10,0x15,0xb2,0x3d,0xb2,0x36,0x6e,0x9f,0x8e,0xe2,0x4c,0x78,0xe5,0x3a,0xac,0x21,0x16,0x20,0x30,0x0f,0x51,0x56,0xcb,0x53,0xca,0x70,0x3c,0xa2,0x3f,0x37,0x06,0x6c,0x70,0xec,0xf4,0x3d,0x7c,0x77,0xa0,0x61,0xc7,0x0e,0x26,0x9f,0x25,0xc0,0xf2,0x28,0xdb,0x57,0xbe,0xe6,0x4e,0x9c,0x4d,0x2e,0x48,0x50,0xc2,0xd4,0xfd,0x5e,0x52 +.byte 0x3f,0xd0,0x82,0xd1,0xd4,0x53,0xad,0x42,0x38,0xb1,0x02,0xd6,0xa0,0x34,0x7a,0xb4,0xb3,0xdd,0x91,0x12,0xf4,0x91,0xc9,0xa2,0x35,0x2d,0xdc,0x97,0xa1,0xdb,0x82,0xe7,0x92,0x99,0x66,0x13,0x99,0x20,0x95,0x1f,0x47,0x64,0x80,0x5e,0x5f,0x74,0x6b,0xa6,0xca,0x47,0x0b,0x24,0x72,0xa6,0x27,0xe7,0x56,0x61,0xa7,0x8e,0x62,0xa4,0xff,0x8e +.byte 0x29,0xf8,0x09,0xa4,0xbb,0x70,0x97,0x8a,0x39,0xe8,0x65,0xc8,0x52,0x23,0x9d,0xbf,0x10,0xe8,0x7d,0xbc,0x3c,0xc4,0x8b,0x1e,0x5c,0x75,0x94,0x24,0x62,0x3f,0x5b,0x2b,0x9a,0x08,0x00,0x78,0xfd,0x28,0x44,0x12,0x62,0x2a,0x6f,0x47,0x9d,0x57,0xb0,0x4e,0x3b,0xcd,0x01,0x7d,0x6e,0x62,0xe3,0x99,0x9c,0xae,0x6e,0xe2,0x70,0x7a,0x32,0xb4 +.byte 0xc1,0x19,0xb1,0x03,0x6b,0x92,0x89,0x4f,0x37,0xaf,0x36,0xee,0x5e,0x03,0x31,0x8c,0x41,0x27,0x17,0x21,0xdf,0xe4,0x34,0x97,0x8d,0xe7,0x41,0x47,0xf2,0x80,0x51,0x41,0x01,0xe4,0x0c,0x1a,0x09,0xfc,0x07,0xc3,0x94,0x07,0x6f,0xa7,0x6c,0xff,0x32,0x21,0xa5,0x01,0x8c,0xa2,0x88,0x3c,0xc8,0x57,0xe8,0x68,0x19,0x4a,0x46,0x7a,0x36,0xd2 +.byte 0x75,0x8e,0xc5,0xa4,0x84,0x91,0x13,0x7f,0xdd,0x2b,0x3c,0x2e,0xc4,0x92,0x29,0xb3,0x60,0x74,0xc8,0x81,0x58,0x0e,0xad,0x6a,0x9d,0xaa,0x81,0x49,0x26,0x0f,0xd4,0x2a,0x39,0xdd,0x4d,0x2b,0x13,0xdb,0x2e,0x72,0xe6,0x45,0x99,0xeb,0xe6,0xe5,0xd5,0x76,0xd4,0x19,0xd8,0xd7,0xa9,0x1f,0xce,0x7f,0xc4,0x1c,0x9e,0x6f,0x68,0x32,0xb1,0x26 +.byte 0xc4,0xb6,0x4e,0x9f,0xbf,0xdc,0xe0,0xde,0x54,0x9b,0xe0,0x04,0x03,0xae,0xc9,0xce,0x3a,0xcb,0x93,0xad,0xcc,0x1f,0x46,0xf6,0xbb,0xff,0x40,0x52,0x9c,0x64,0x97,0x5a,0x6f,0x8d,0x28,0x45,0x1c,0xf6,0x8b,0xcb,0xb9,0x38,0xb8,0x00,0xee,0xec,0xac,0x68,0x3f,0x50,0xcb,0x36,0x6e,0x97,0xfd,0xa5,0x1d,0x29,0x6e,0xfa,0x9f,0x4b,0x83,0xcd +.byte 0x0d,0x34,0xf3,0x1e,0x3f,0x0f,0x2e,0x89,0xeb,0xf7,0x8e,0x5f,0xe0,0x3b,0x39,0xd2,0xe8,0x87,0xe3,0xe7,0xe9,0xd0,0x1b,0x32,0x03,0x6b,0x3c,0x75,0x7d,0xe2,0x5c,0x3c,0x42,0xb4,0x46,0x69,0x0b,0xaf,0x0a,0x5d,0x1a,0x83,0x0b,0x0e,0x3c,0x5a,0x36,0xbd,0x5d,0xb6,0xad,0x4c,0xdd,0xf1,0x8d,0xbf,0x2b,0x70,0x8e,0xbc,0x92,0x95,0x1b,0x0f +.byte 0xed,0x3f,0xae,0x9e,0xa2,0x5a,0x50,0xe4,0xda,0xde,0x04,0x51,0x31,0xac,0xa4,0x0b,0x94,0xcc,0x14,0x87,0x59,0xa8,0x30,0x09,0xe6,0x46,0xb9,0x07,0x3e,0x1a,0xbf,0x5a,0x23,0x32,0xfb,0x60,0x63,0x24,0x25,0x12,0xf6,0x3e,0x2d,0xd0,0x8b,0x88,0x9b,0xe9,0x2d,0xab,0xf5,0xaf,0xba,0xbc,0xfe,0xab,0xb2,0x61,0x7a,0x7c,0xbb,0x28,0x6b,0x86 +.byte 0xe5,0xa2,0x9c,0x2c,0x5a,0x23,0x12,0x11,0xe5,0x72,0xe8,0x7b,0x6b,0x40,0xf1,0x91,0x37,0x3b,0x47,0x75,0x65,0xac,0x4d,0x22,0x59,0x75,0x13,0xb0,0x73,0xff,0x59,0xd1,0x1b,0xcc,0x05,0x1f,0xf2,0xc8,0x50,0x83,0xf1,0x28,0x38,0x0b,0xc3,0xa0,0x3b,0xe3,0x86,0xbb,0x9c,0x7e,0xc1,0xe9,0xcc,0xd9,0xb8,0x2b,0x05,0xf3,0x6f,0xc7,0x9d,0xaf +.byte 0x7b,0xb7,0x38,0x41,0xa3,0x50,0x8f,0x92,0xe0,0x63,0x35,0xb3,0x95,0x9f,0x80,0xf8,0x75,0xbb,0xf3,0x2b,0x0e,0xaf,0x32,0x6e,0xff,0xeb,0x79,0xca,0xbf,0x1c,0x4f,0x6c,0x9c,0x06,0xb2,0xeb,0x99,0x57,0x1f,0xf6,0x64,0x0b,0x81,0x57,0xba,0xf4,0x32,0x1e,0x77,0x37,0x55,0xb7,0xbc,0xba,0x70,0x0b,0x0d,0xdd,0x95,0x41,0xb5,0x17,0x5b,0x14 +.byte 0x10,0x9d,0x14,0x52,0x83,0x65,0x0a,0xf4,0x55,0xca,0xf8,0xbe,0xa6,0x3a,0xa0,0x6e,0xcc,0x83,0x84,0x65,0xb4,0x1c,0x7e,0x40,0xdd,0x32,0x36,0x5a,0x23,0x17,0x7d,0xb5,0xb9,0x38,0x48,0x5c,0x6f,0x23,0x54,0x0e,0x93,0x74,0x27,0x0f,0xfd,0x58,0xc1,0x97,0x26,0x78,0x9a,0xd3,0x85,0xc5,0xb2,0xb3,0x44,0xb7,0x36,0x85,0x69,0xde,0x3b,0xa1 +.byte 0x2b,0x11,0xef,0x75,0xfc,0xaa,0x92,0xf1,0xf1,0x72,0xa0,0x5f,0x33,0xf6,0x0b,0x72,0xdb,0xce,0x6c,0x2a,0x15,0x76,0x40,0xd4,0x85,0xff,0x96,0xe1,0x48,0xe1,0x27,0x8f,0x74,0xf3,0xfa,0xa1,0xb7,0x2a,0xb6,0x41,0x90,0x92,0x7e,0xfa,0xfc,0xad,0xa3,0x94,0x91,0x77,0xf1,0x8f,0xee,0xa2,0x64,0x47,0x01,0xb3,0x01,0x99,0x05,0xe7,0x31,0x4a +.byte 0xe8,0xd2,0x65,0x40,0x21,0xc4,0x83,0x8e,0xc9,0x89,0xda,0x16,0x7b,0xe0,0xcb,0xc0,0xc0,0x3d,0x37,0x18,0x66,0xe9,0x70,0x86,0x0b,0x6c,0xe8,0x65,0x44,0xce,0x3a,0xcd,0x84,0x1e,0xce,0x0e,0xe3,0xf9,0x77,0x12,0xfb,0xe6,0x92,0x8b,0x0d,0x7e,0x15,0x7a,0x34,0x94,0x2a,0xa7,0xc5,0x35,0xa4,0xfc,0xbe,0xa3,0x13,0x70,0xe4,0x6b,0x2f,0x71 +.byte 0x31,0xef,0xdb,0x79,0x44,0xf2,0x77,0xc7,0xc9,0x0d,0x1a,0x7b,0xff,0x34,0xf8,0xc9,0xe8,0xc9,0xc2,0xe0,0x0c,0x9e,0xd6,0xb4,0x7a,0xdb,0x1f,0x65,0xb8,0xd4,0x92,0xbf,0x7f,0x06,0x44,0xe3,0xb4,0xd8,0x14,0xe3,0x9b,0x49,0x81,0x12,0xec,0x7d,0x01,0xe2,0x50,0x2c,0x0e,0xfd,0x4b,0x84,0x3b,0x4d,0x89,0x1d,0x2e,0x4b,0xe9,0xda,0xa5,0x3f +.byte 0x19,0xc2,0x53,0x36,0x5d,0xd8,0xdc,0x6e,0xc3,0x48,0x8f,0x09,0xd5,0x95,0x4b,0x0c,0x7c,0x00,0x15,0x33,0x8e,0x1d,0x0c,0xdf,0x32,0x3b,0x93,0x1f,0xf5,0x49,0x4f,0xfd,0x8b,0x64,0xe7,0x96,0xaf,0x2f,0xc8,0xea,0xab,0x91,0x53,0x29,0xe3,0x31,0x0a,0x1c,0x6e,0xe0,0xbb,0x81,0x11,0x83,0xe0,0x07,0xfb,0x29,0x11,0x0f,0x0d,0x85,0xd4,0x61 +.byte 0x3c,0x75,0xbb,0x8a,0x23,0xb6,0xa0,0x7f,0xa4,0xbb,0x11,0xd4,0x75,0xde,0x27,0xe5,0xeb,0x11,0x5d,0x02,0xfe,0x5c,0x62,0x60,0x0f,0x6f,0x45,0x9b,0xfb,0xb7,0x32,0xa8,0x1c,0xd6,0xff,0x43,0x7b,0x53,0xee,0xa4,0x1f,0xf2,0xba,0xb6,0xb7,0xb7,0x39,0x18,0x85,0x79,0x77,0x27,0x30,0x26,0xe4,0xef,0xd1,0x39,0xc9,0xa2,0x0d,0x50,0xd7,0xef +.byte 0x9e,0xd8,0x8e,0xd2,0x74,0x1a,0x3f,0x99,0x24,0xf4,0x8b,0x4d,0x02,0x63,0x18,0x3a,0xaf,0x26,0xef,0xfc,0x1d,0xfe,0x46,0xc1,0x55,0xd7,0x92,0x65,0x2f,0xe7,0x4f,0x47,0xa8,0x2f,0x5d,0x47,0x67,0xeb,0x62,0x1d,0x69,0xa6,0x0e,0x51,0x1d,0x2c,0xed,0x6e,0x94,0xe9,0x48,0x4c,0x22,0xc2,0x93,0x79,0x6f,0x1b,0xc2,0x93,0x61,0x3d,0x8b,0xba +.byte 0xcb,0xe9,0x4a,0x88,0x5e,0x19,0x50,0x14,0xfe,0xda,0x3f,0x4d,0x47,0x54,0xfc,0x1c,0x09,0x77,0x37,0x30,0xfe,0x75,0x9f,0xdd,0xa4,0x74,0x04,0x04,0x88,0xe0,0xac,0x93,0x64,0x6f,0xbf,0x50,0xd8,0xf0,0xf7,0xa0,0xfa,0x98,0x49,0xfa,0xf7,0x6e,0xcf,0xa2,0xbf,0xb6,0x07,0x15,0x0e,0x4e,0x21,0x74,0x0a,0xa6,0xa3,0x67,0xce,0xf9,0x3b,0xd6 +.byte 0x4c,0xc8,0x43,0xe3,0x3b,0x3b,0x6a,0x86,0x62,0x3f,0x5a,0xf3,0x3f,0xf9,0xeb,0xbf,0xa3,0x2a,0x83,0x8a,0x70,0x8f,0x01,0x65,0x17,0x9a,0xa6,0x26,0x3b,0x09,0x06,0x22,0x19,0xed,0xd7,0x25,0x4b,0xd2,0x9a,0x30,0xfe,0x1c,0x82,0x68,0x16,0x04,0x0e,0x04,0x8f,0xc6,0x92,0xbe,0xe4,0x43,0x98,0x1d,0x3b,0x10,0x15,0x5b,0xef,0x4e,0x60,0x5e +.byte 0x6b,0xc9,0xde,0xb8,0x47,0x02,0x86,0x45,0x39,0x7a,0x1a,0xef,0x67,0x28,0xc5,0x40,0x73,0x2a,0xa7,0x12,0x9d,0x58,0x3a,0x34,0xc2,0xda,0x34,0xb0,0x48,0xd9,0x34,0xcd,0x18,0xe9,0x76,0x41,0x78,0x8f,0xe5,0xe8,0x3d,0xb2,0x01,0x3b,0x84,0xd1,0xca,0x5e,0x26,0x1d,0x8c,0xea,0xe1,0x46,0xa3,0xf9,0x11,0xac,0x0d,0x98,0x9f,0xd3,0x46,0x79 +.byte 0xff,0xad,0x99,0x32,0x63,0x96,0xbc,0x57,0x39,0x16,0xce,0x06,0x7e,0x63,0x78,0x7b,0x86,0x92,0x1a,0xe1,0x45,0xc0,0x73,0xe1,0xec,0xfc,0x88,0x8f,0xf8,0x36,0x0f,0x54,0x76,0x02,0x98,0x49,0x40,0xb9,0xef,0xd8,0x13,0x68,0xf5,0x1d,0x0a,0x98,0x65,0x21,0xc5,0x1a,0x22,0x4e,0x8e,0xad,0xa9,0x52,0x57,0xc4,0xc6,0xa8,0x48,0x01,0x7a,0x78 +.byte 0xc9,0xfc,0xdd,0xf3,0xc3,0x83,0xc0,0x06,0xb5,0x56,0x84,0xe2,0x0c,0x6b,0x80,0xd9,0x59,0xa1,0x3d,0xe3,0x56,0xf0,0xe3,0x3f,0x93,0x61,0xf7,0x8c,0x6b,0x40,0x65,0x6e,0x01,0xc2,0xa1,0xc1,0xb8,0x9b,0x15,0x6c,0xa1,0x18,0x4a,0x6c,0x8b,0x18,0x2d,0x8e,0x71,0x7a,0xa1,0x26,0xc1,0x4b,0xac,0x0c,0xca,0x08,0x33,0xef,0x35,0x33,0x63,0xeb +.byte 0x57,0x6e,0x7e,0x36,0xe0,0x31,0xad,0x10,0x76,0xb7,0x45,0xd9,0x3a,0x92,0x66,0x69,0x13,0x61,0x59,0x87,0xfd,0x6b,0xf1,0x46,0x0a,0x7a,0x3f,0x29,0x88,0x5b,0x7d,0xef,0x07,0x02,0xa8,0xa1,0xdc,0xd4,0x0e,0x77,0x8f,0x68,0x32,0xbd,0x8e,0xd6,0x0b,0xe4,0xd1,0x75,0xc1,0xb0,0x74,0x6c,0x0e,0xc3,0x46,0x79,0x36,0x3b,0x5f,0x0e,0xa0,0xad +.byte 0x28,0x8c,0xcb,0x01,0x8e,0x58,0x14,0x09,0xf1,0xd4,0x3b,0x2e,0xdc,0xbf,0x37,0x95,0x26,0xda,0xb6,0xcf,0xc8,0xa1,0xd4,0xec,0x72,0xf3,0x44,0xf5,0x4e,0x27,0x9b,0x2e,0x7c,0xfa,0x37,0x16,0x1d,0x7f,0x90,0x86,0xae,0x96,0x3b,0xe1,0xda,0xf7,0xc4,0x54,0x0b,0x51,0x7e,0x83,0xbe,0xed,0xd6,0x5f,0xd2,0x6d,0xbb,0xd3,0xc6,0x53,0x95,0x65 +.byte 0x3d,0x19,0xc2,0xc5,0xdf,0x47,0x00,0x2c,0x4b,0x2d,0xec,0x32,0xd5,0x28,0xb5,0x30,0xe0,0x79,0x15,0x2e,0xab,0x97,0xa8,0xcf,0xc5,0x40,0x98,0x30,0x22,0x9f,0xbc,0xdb,0x65,0x06,0xfc,0x58,0xe5,0x55,0x5b,0xe2,0xf8,0x6e,0xc6,0xfc,0xec,0x6c,0x14,0xd2,0xe3,0x9a,0x71,0x8a,0x61,0xea,0x39,0xc6,0x77,0x94,0xdf,0x7b,0x99,0x71,0xdd,0x18 +.byte 0xc6,0x03,0x2d,0x49,0xf6,0xc3,0xe8,0x2b,0x7e,0x3f,0x28,0xfc,0xc8,0xa1,0xb0,0x15,0x31,0x7e,0x83,0xb8,0x14,0x34,0x0e,0x7f,0xde,0x74,0x7b,0xbf,0xb7,0x8e,0xd9,0x31,0x90,0x16,0xb6,0x57,0x14,0x4a,0xc6,0x67,0x3d,0xb9,0x46,0x92,0xf2,0xf9,0x94,0x36,0x2b,0xd6,0x1f,0x84,0xa5,0x8c,0x0f,0xd9,0x8c,0x5f,0x97,0x7a,0x7b,0xff,0xc9,0xf5 +.byte 0x5e,0x13,0x5f,0x19,0x58,0xba,0xa6,0xe8,0x29,0xf4,0xb8,0x7e,0x98,0xb7,0xef,0x1b,0x00,0xe8,0x90,0x8f,0x86,0x4c,0xe0,0x51,0x13,0x8b,0xa1,0x37,0x40,0x38,0x51,0x2f,0x5a,0x9b,0x63,0x8f,0xce,0x9a,0x97,0x07,0x0d,0x8e,0xce,0xb1,0x66,0x89,0x78,0xca,0xa6,0x0c,0x20,0xc4,0xf1,0xe3,0xab,0xe2,0x1c,0x83,0x2b,0x46,0x97,0xe8,0x8f,0x94 +.byte 0xb4,0x71,0x40,0xde,0xa1,0x05,0x4b,0xed,0xbf,0x0c,0x46,0xe1,0x25,0xf1,0xd0,0x5a,0xdb,0x9c,0x2a,0x09,0x03,0x80,0x24,0xc1,0x22,0x02,0xa5,0xde,0xf6,0x4c,0xbc,0x93,0x37,0xa9,0x28,0xb3,0x92,0x19,0xa8,0x3f,0x71,0x90,0x62,0x78,0xaa,0x9a,0x0c,0xab,0x50,0xaf,0x89,0x2b,0xf1,0xf4,0x12,0xbd,0xc9,0xd5,0xee,0x64,0x8b,0x48,0x21,0xd6 +.byte 0xa1,0xa1,0xf2,0x68,0x4a,0xf8,0x06,0x3e,0x20,0x31,0x66,0xb7,0x2f,0x64,0x01,0x5a,0x46,0x14,0x85,0xfb,0xde,0x04,0xc3,0xe4,0xd6,0x25,0x14,0xa0,0xbe,0x4d,0x39,0xd8,0xe0,0x9b,0xb7,0x6b,0x00,0xe6,0x46,0xfb,0xcc,0xa8,0xad,0x67,0x12,0x2c,0x53,0x2c,0xb6,0x9f,0x6e,0xfe,0xbc,0xcc,0x2c,0xa8,0x09,0x17,0x00,0x8e,0xf1,0xf4,0x3e,0xa9 +.byte 0x92,0x4d,0x83,0xe6,0x3c,0xf0,0xd3,0x1c,0xaf,0x84,0x2c,0x59,0x7e,0xda,0x1e,0xfd,0x7d,0xf3,0xef,0x93,0x05,0x03,0xb0,0x76,0x69,0xb5,0x51,0xa8,0x65,0x8f,0x8a,0xf8,0x55,0x92,0x08,0xfe,0xbf,0xc1,0x95,0x98,0x58,0xb1,0xd3,0xb6,0x78,0x4f,0x2f,0x25,0xcb,0x9d,0x32,0x4f,0xa6,0xcc,0xf8,0x36,0xff,0x72,0xb3,0x93,0x3d,0xd8,0x0b,0xe6 +.byte 0xc6,0xf6,0xed,0xcc,0x2a,0xa5,0x44,0x6e,0xe2,0x2d,0x6e,0x02,0xb4,0x7c,0x24,0x7f,0x57,0x02,0x84,0x61,0x8e,0xbd,0x32,0x4e,0x41,0x92,0x01,0x1b,0x8b,0x1d,0xd1,0x1e,0x31,0xc1,0x4c,0x5b,0x0c,0xa7,0x48,0x52,0x67,0xc2,0xd9,0xdc,0x86,0x9d,0xbd,0x6c,0x19,0x95,0x00,0xf0,0xd4,0x47,0xaf,0xfe,0x5d,0xa5,0x81,0xbd,0x1b,0x42,0x62,0xce +.byte 0x18,0x1b,0xa3,0x6f,0xf5,0x0b,0xb7,0x6a,0x3d,0xe3,0xcc,0x41,0x27,0xcd,0x49,0x4b,0xe5,0x2b,0xc4,0x28,0xfa,0xbe,0xd5,0x7e,0xb7,0xac,0xab,0x64,0x3b,0xe3,0x87,0xb1,0x33,0x8b,0xa8,0xe5,0x75,0xce,0x61,0x57,0x89,0xad,0x5f,0x61,0xdd,0x7c,0x06,0x2a,0x3f,0x50,0xb8,0x7e,0xd2,0xfb,0x32,0x83,0x07,0xd4,0xc5,0x3f,0xad,0x64,0x59,0x1f +.byte 0x21,0x59,0x6f,0x1b,0xd7,0x40,0x89,0x28,0x18,0xac,0xca,0xee,0x92,0x1c,0x0d,0x88,0x98,0x7a,0x75,0x68,0xe0,0xe2,0x96,0xda,0x88,0xb3,0xc6,0x21,0x02,0x34,0xfa,0xae,0x0b,0x38,0xcf,0x1c,0x6c,0x7a,0xc9,0xd9,0x5f,0xf0,0x4c,0x73,0xfd,0xe6,0x14,0xf3,0x39,0xed,0xbc,0x28,0x2f,0xf8,0x79,0x02,0x39,0x05,0xf3,0x6a,0x88,0xd9,0x03,0xe2 +.byte 0xb9,0x65,0x81,0x3a,0x34,0x80,0x3f,0x17,0x37,0x1e,0xe8,0x7d,0x41,0x49,0xfb,0x70,0x5d,0x58,0x3a,0x71,0x7b,0x3e,0xd3,0x83,0x0b,0x1b,0x11,0xfc,0x53,0xce,0xc6,0xc4,0x39,0x55,0xbe,0xbe,0x32,0xa5,0x88,0xab,0xcd,0x38,0x78,0x3e,0x52,0xaf,0x64,0x42,0x10,0xc3,0x70,0x81,0x76,0xe9,0x7d,0x8e,0x46,0x41,0xca,0x2c,0x0c,0x4c,0x30,0xd3 +.byte 0xca,0x38,0xa3,0x97,0x2e,0x0f,0xa5,0x18,0x3b,0xaa,0x0f,0x00,0x75,0x35,0x9c,0xcd,0x28,0x83,0xd4,0xa7,0x7c,0xb9,0xcd,0xb5,0x55,0x29,0x4c,0x14,0xcd,0xfc,0x8f,0xaf,0x7d,0x69,0x4f,0xf7,0x0f,0xed,0x7c,0xa5,0x79,0x9d,0x36,0xbb,0x72,0xbc,0xf2,0x14,0xfd,0xf0,0x04,0x2a,0x89,0x1e,0xf7,0x80,0x4c,0x5e,0xb8,0xc1,0xdb,0xfa,0x3c,0x27 +.byte 0xbb,0x30,0x08,0x2b,0xd2,0xf8,0xdb,0xe0,0x8c,0x00,0xe4,0xca,0xa9,0xde,0xb0,0x14,0x5b,0xec,0x6b,0xe6,0x5c,0x90,0x17,0x02,0x59,0x5f,0x5f,0x51,0xf8,0x30,0x10,0x11,0xc4,0xdf,0x37,0x30,0x32,0xb1,0x4d,0x49,0xfe,0x82,0x87,0xd2,0x42,0xf5,0x38,0x76,0xf9,0xa5,0x28,0xfc,0x14,0xb2,0xe0,0x72,0x82,0xde,0xc8,0x47,0x9e,0x8f,0x8a,0xb5 +.byte 0x85,0x44,0x42,0x12,0xc6,0xc0,0xa5,0x60,0x5a,0x27,0xd0,0x36,0x14,0x7b,0x2a,0x83,0x98,0x92,0x08,0xe9,0x03,0xc9,0xc3,0xd3,0x36,0x97,0xba,0x5e,0xd5,0x51,0xcc,0x44,0xeb,0x81,0x76,0xae,0x28,0x94,0x0b,0xf6,0xc7,0xeb,0xae,0x61,0x6f,0x7b,0x34,0xb5,0x8c,0x5f,0x31,0xb6,0x23,0xe3,0xe7,0x4b,0x60,0xe6,0xba,0x8d,0x0e,0xd1,0xb2,0x37 +.byte 0x72,0x3d,0xc1,0x75,0x9b,0x5e,0xcb,0x0f,0xf9,0xe4,0xdb,0x82,0x4c,0xc4,0x37,0xef,0x9d,0xde,0x16,0x85,0xe9,0xc2,0x03,0xd8,0x5b,0xa1,0xff,0xfa,0xd4,0xd7,0x5c,0x34,0xb6,0x1e,0x25,0x96,0xf5,0x8b,0xc3,0xee,0x16,0x1f,0xf8,0x55,0x4e,0x1c,0x83,0x80,0x77,0x1d,0x4f,0xb6,0x95,0x1c,0x91,0x7d,0x50,0x25,0xf4,0x2a,0x5d,0x2e,0xc7,0x8a +.byte 0x14,0xf8,0xb9,0xbc,0xab,0x5b,0xcd,0x47,0xb5,0xaf,0x85,0xc0,0x34,0x27,0x7d,0x6a,0x8c,0x84,0x8a,0xae,0x68,0x60,0x0e,0xa1,0x45,0xf7,0x83,0x66,0x91,0x69,0x30,0xed,0x26,0x5e,0xf5,0x48,0x6b,0x20,0xb3,0x11,0x50,0xf7,0x70,0x9d,0x10,0x50,0x44,0x87,0xfe,0x96,0x5c,0xc6,0xa4,0xa4,0xed,0x5e,0x7f,0x3d,0x90,0x19,0xbe,0x31,0xa3,0xdd +.byte 0x44,0xbb,0x9b,0x51,0x5a,0x06,0x1d,0x2e,0xd7,0xef,0xd1,0x81,0xb6,0xec,0xc6,0x89,0xfb,0x13,0xc5,0x21,0xef,0x9a,0x1a,0x48,0xf2,0xf8,0xb3,0xa3,0xec,0x7f,0x85,0xc1,0xc6,0x8c,0x5f,0xa9,0x30,0x38,0x25,0x1e,0x8d,0xcf,0x18,0x24,0xef,0x5a,0x9a,0x14,0x31,0xc0,0x2c,0x88,0xa5,0x3f,0x50,0x8b,0xb1,0xda,0x5d,0x26,0xd9,0xd3,0x81,0xb1 +.byte 0xec,0xf0,0x42,0x88,0xd0,0x81,0x51,0xf9,0x1b,0xbc,0x43,0xa4,0x37,0xf1,0xd7,0x90,0x21,0x7e,0xa0,0x3e,0x63,0xfb,0x21,0xfa,0x12,0xfb,0xde,0xc7,0xbf,0xb3,0x58,0xe7,0x76,0x42,0x20,0x01,0x3d,0x66,0x80,0xf1,0xb8,0xaf,0xfa,0x7d,0x96,0x89,0x36,0x48,0x95,0xd9,0x6e,0x6d,0xe6,0x4f,0xff,0x2a,0x47,0x61,0xf2,0x04,0xb7,0x83,0x14,0xce +.byte 0x0a,0x3c,0x73,0x17,0x50,0x88,0x03,0x25,0x4a,0xe3,0x13,0x55,0x8b,0x7e,0x50,0x38,0xfc,0x14,0x0b,0x04,0x8e,0xa8,0x5b,0xd6,0x72,0x20,0x60,0xe9,0xaa,0x22,0x82,0x11,0xc6,0xc4,0xd7,0xb9,0xc8,0x0c,0x7e,0x05,0xfb,0x90,0xe4,0x9c,0x28,0x89,0x29,0x99,0x63,0x4d,0xec,0x7b,0x50,0xbd,0xd8,0xa3,0x5b,0x50,0x77,0x19,0x81,0x92,0xce,0x82 +.align 64 +.LRR: +.long 3,0,-1,-5,-2,-1,-3,4 +.LONE_mont: +.long 1,0,0,-1,-1,-1,-2,0 +.LONE: +.long 1,0,0,0,0,0,0,0 +.byte 69,67,80,95,78,73,83,90,50,53,54,32,102,111,114,32 +.byte 120,56,54,47,83,83,69,50,44,32,67,82,89,80,84,79 +.byte 71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111 +.byte 112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 +.globl ecp_nistz256_mul_by_2 +.type ecp_nistz256_mul_by_2,@function +.align 16 +ecp_nistz256_mul_by_2: +.L_ecp_nistz256_mul_by_2_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + movl 20(%esp),%edi + movl %esi,%ebp + call _ecp_nistz256_add + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_mul_by_2,.-.L_ecp_nistz256_mul_by_2_begin +.globl ecp_nistz256_mul_by_3 +.type ecp_nistz256_mul_by_3,@function +.align 16 +ecp_nistz256_mul_by_3: +.L_ecp_nistz256_mul_by_3_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + subl $32,%esp + movl %esp,%edi + movl %esi,%ebp + call _ecp_nistz256_add + leal (%edi),%esi + movl 56(%esp),%ebp + movl 52(%esp),%edi + call _ecp_nistz256_add + addl $32,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_mul_by_3,.-.L_ecp_nistz256_mul_by_3_begin +.globl ecp_nistz256_div_by_2 +.type ecp_nistz256_div_by_2,@function +.align 16 +ecp_nistz256_div_by_2: +.L_ecp_nistz256_div_by_2_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + movl 20(%esp),%edi + call _ecp_nistz256_div_by_2 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_div_by_2,.-.L_ecp_nistz256_div_by_2_begin +.type _ecp_nistz256_div_by_2,@function +.align 16 +_ecp_nistz256_div_by_2: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl (%esi),%ebp + xorl %edx,%edx + movl 4(%esi),%ebx + movl %ebp,%eax + andl $1,%ebp + movl 8(%esi),%ecx + subl %ebp,%edx + addl %edx,%eax + adcl %edx,%ebx + movl %eax,(%edi) + adcl %edx,%ecx + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl 12(%esi),%eax + movl 16(%esi),%ebx + adcl $0,%eax + movl 20(%esi),%ecx + adcl $0,%ebx + movl %eax,12(%edi) + adcl $0,%ecx + movl %ebx,16(%edi) + movl %ecx,20(%edi) + movl 24(%esi),%eax + movl 28(%esi),%ebx + adcl %ebp,%eax + adcl %edx,%ebx + movl %eax,24(%edi) + sbbl %esi,%esi + movl %ebx,28(%edi) + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + shrl $1,%eax + movl %ebx,%ebp + shll $31,%ebx + orl %ebx,%eax + shrl $1,%ebp + movl %ecx,%ebx + shll $31,%ecx + movl %eax,(%edi) + orl %ecx,%ebp + movl 16(%edi),%eax + shrl $1,%ebx + movl %edx,%ecx + shll $31,%edx + movl %ebp,4(%edi) + orl %edx,%ebx + movl 20(%edi),%ebp + shrl $1,%ecx + movl %eax,%edx + shll $31,%eax + movl %ebx,8(%edi) + orl %eax,%ecx + movl 24(%edi),%ebx + shrl $1,%edx + movl %ebp,%eax + shll $31,%ebp + movl %ecx,12(%edi) + orl %ebp,%edx + movl 28(%edi),%ecx + shrl $1,%eax + movl %ebx,%ebp + shll $31,%ebx + movl %edx,16(%edi) + orl %ebx,%eax + shrl $1,%ebp + movl %ecx,%ebx + shll $31,%ecx + movl %eax,20(%edi) + orl %ecx,%ebp + shrl $1,%ebx + shll $31,%esi + movl %ebp,24(%edi) + orl %esi,%ebx + movl %ebx,28(%edi) + ret +.size _ecp_nistz256_div_by_2,.-_ecp_nistz256_div_by_2 +.globl ecp_nistz256_add +.type ecp_nistz256_add,@function +.align 16 +ecp_nistz256_add: +.L_ecp_nistz256_add_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + movl 28(%esp),%ebp + movl 20(%esp),%edi + call _ecp_nistz256_add + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_add,.-.L_ecp_nistz256_add_begin +.type _ecp_nistz256_add,@function +.align 16 +_ecp_nistz256_add: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + addl (%ebp),%eax + movl 12(%esi),%edx + adcl 4(%ebp),%ebx + movl %eax,(%edi) + adcl 8(%ebp),%ecx + movl %ebx,4(%edi) + adcl 12(%ebp),%edx + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + adcl 16(%ebp),%eax + movl 28(%esi),%edx + adcl 20(%ebp),%ebx + movl %eax,16(%edi) + adcl 24(%ebp),%ecx + movl %ebx,20(%edi) + movl $0,%esi + adcl 28(%ebp),%edx + movl %ecx,24(%edi) + adcl $0,%esi + movl %edx,28(%edi) + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + subl $-1,%eax + movl 12(%edi),%edx + sbbl $-1,%ebx + movl 16(%edi),%eax + sbbl $-1,%ecx + movl 20(%edi),%ebx + sbbl $0,%edx + movl 24(%edi),%ecx + sbbl $0,%eax + movl 28(%edi),%edx + sbbl $0,%ebx + sbbl $1,%ecx + sbbl $-1,%edx + sbbl $0,%esi + notl %esi + movl (%edi),%eax + movl %esi,%ebp + movl 4(%edi),%ebx + shrl $31,%ebp + movl 8(%edi),%ecx + subl %esi,%eax + movl 12(%edi),%edx + sbbl %esi,%ebx + movl %eax,(%edi) + sbbl %esi,%ecx + movl %ebx,4(%edi) + sbbl $0,%edx + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 16(%edi),%eax + movl 20(%edi),%ebx + movl 24(%edi),%ecx + sbbl $0,%eax + movl 28(%edi),%edx + sbbl $0,%ebx + movl %eax,16(%edi) + sbbl %ebp,%ecx + movl %ebx,20(%edi) + sbbl %esi,%edx + movl %ecx,24(%edi) + movl %edx,28(%edi) + ret +.size _ecp_nistz256_add,.-_ecp_nistz256_add +.globl ecp_nistz256_sub +.type ecp_nistz256_sub,@function +.align 16 +ecp_nistz256_sub: +.L_ecp_nistz256_sub_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + movl 28(%esp),%ebp + movl 20(%esp),%edi + call _ecp_nistz256_sub + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_sub,.-.L_ecp_nistz256_sub_begin +.type _ecp_nistz256_sub,@function +.align 16 +_ecp_nistz256_sub: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + subl (%ebp),%eax + movl 12(%esi),%edx + sbbl 4(%ebp),%ebx + movl %eax,(%edi) + sbbl 8(%ebp),%ecx + movl %ebx,4(%edi) + sbbl 12(%ebp),%edx + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + sbbl 16(%ebp),%eax + movl 28(%esi),%edx + sbbl 20(%ebp),%ebx + sbbl 24(%ebp),%ecx + movl %eax,16(%edi) + sbbl 28(%ebp),%edx + movl %ebx,20(%edi) + sbbl %esi,%esi + movl %ecx,24(%edi) + movl %edx,28(%edi) + movl (%edi),%eax + movl %esi,%ebp + movl 4(%edi),%ebx + shrl $31,%ebp + movl 8(%edi),%ecx + addl %esi,%eax + movl 12(%edi),%edx + adcl %esi,%ebx + movl %eax,(%edi) + adcl %esi,%ecx + movl %ebx,4(%edi) + adcl $0,%edx + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 16(%edi),%eax + movl 20(%edi),%ebx + movl 24(%edi),%ecx + adcl $0,%eax + movl 28(%edi),%edx + adcl $0,%ebx + movl %eax,16(%edi) + adcl %ebp,%ecx + movl %ebx,20(%edi) + adcl %esi,%edx + movl %ecx,24(%edi) + movl %edx,28(%edi) + ret +.size _ecp_nistz256_sub,.-_ecp_nistz256_sub +.globl ecp_nistz256_neg +.type ecp_nistz256_neg,@function +.align 16 +ecp_nistz256_neg: +.L_ecp_nistz256_neg_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%ebp + movl 20(%esp),%edi + xorl %eax,%eax + subl $32,%esp + movl %eax,(%esp) + movl %esp,%esi + movl %eax,4(%esp) + movl %eax,8(%esp) + movl %eax,12(%esp) + movl %eax,16(%esp) + movl %eax,20(%esp) + movl %eax,24(%esp) + movl %eax,28(%esp) + call _ecp_nistz256_sub + addl $32,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_neg,.-.L_ecp_nistz256_neg_begin +.type _picup_eax,@function +.align 16 +_picup_eax: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl (%esp),%eax + ret +.size _picup_eax,.-_picup_eax +.globl ecp_nistz256_to_mont +.type ecp_nistz256_to_mont,@function +.align 16 +ecp_nistz256_to_mont: +.L_ecp_nistz256_to_mont_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + call _picup_eax +.L000pic: + leal .LRR-.L000pic(%eax),%ebp + leal OPENSSL_ia32cap_P-.L000pic(%eax),%eax + movl (%eax),%eax + movl 20(%esp),%edi + call _ecp_nistz256_mul_mont + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_to_mont,.-.L_ecp_nistz256_to_mont_begin +.globl ecp_nistz256_from_mont +.type ecp_nistz256_from_mont,@function +.align 16 +ecp_nistz256_from_mont: +.L_ecp_nistz256_from_mont_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + call _picup_eax +.L001pic: + leal .LONE-.L001pic(%eax),%ebp + leal OPENSSL_ia32cap_P-.L001pic(%eax),%eax + movl (%eax),%eax + movl 20(%esp),%edi + call _ecp_nistz256_mul_mont + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_from_mont,.-.L_ecp_nistz256_from_mont_begin +.globl ecp_nistz256_mul_mont +.type ecp_nistz256_mul_mont,@function +.align 16 +ecp_nistz256_mul_mont: +.L_ecp_nistz256_mul_mont_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + movl 28(%esp),%ebp + call _picup_eax +.L002pic: + leal OPENSSL_ia32cap_P-.L002pic(%eax),%eax + movl (%eax),%eax + movl 20(%esp),%edi + call _ecp_nistz256_mul_mont + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_mul_mont,.-.L_ecp_nistz256_mul_mont_begin +.globl ecp_nistz256_sqr_mont +.type ecp_nistz256_sqr_mont,@function +.align 16 +ecp_nistz256_sqr_mont: +.L_ecp_nistz256_sqr_mont_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + call _picup_eax +.L003pic: + leal OPENSSL_ia32cap_P-.L003pic(%eax),%eax + movl (%eax),%eax + movl 20(%esp),%edi + movl %esi,%ebp + call _ecp_nistz256_mul_mont + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_sqr_mont,.-.L_ecp_nistz256_sqr_mont_begin +.type _ecp_nistz256_mul_mont,@function +.align 16 +_ecp_nistz256_mul_mont: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + andl $83886080,%eax + cmpl $83886080,%eax + jne .L004mul_mont_ialu + movl %esp,%edx + subl $256,%esp + movd (%ebp),%xmm7 + leal 4(%ebp),%ebp + pcmpeqd %xmm6,%xmm6 + psrlq $48,%xmm6 + pshuflw $220,%xmm7,%xmm7 + andl $-64,%esp + pshufd $220,%xmm7,%xmm7 + leal 128(%esp),%ebx + movd (%esi),%xmm0 + pshufd $204,%xmm0,%xmm0 + movd 4(%esi),%xmm1 + movdqa %xmm0,(%ebx) + pmuludq %xmm7,%xmm0 + movd 8(%esi),%xmm2 + pshufd $204,%xmm1,%xmm1 + movdqa %xmm1,16(%ebx) + pmuludq %xmm7,%xmm1 + movq %xmm0,%xmm4 + pslldq $6,%xmm4 + paddq %xmm0,%xmm4 + movdqa %xmm4,%xmm5 + psrldq $10,%xmm4 + pand %xmm6,%xmm5 + movd 12(%esi),%xmm3 + pshufd $204,%xmm2,%xmm2 + movdqa %xmm2,32(%ebx) + pmuludq %xmm7,%xmm2 + paddq %xmm4,%xmm1 + movdqa %xmm1,(%esp) + movd 16(%esi),%xmm0 + pshufd $204,%xmm3,%xmm3 + movdqa %xmm3,48(%ebx) + pmuludq %xmm7,%xmm3 + movdqa %xmm2,16(%esp) + movd 20(%esi),%xmm1 + pshufd $204,%xmm0,%xmm0 + movdqa %xmm0,64(%ebx) + pmuludq %xmm7,%xmm0 + paddq %xmm5,%xmm3 + movdqa %xmm3,32(%esp) + movd 24(%esi),%xmm2 + pshufd $204,%xmm1,%xmm1 + movdqa %xmm1,80(%ebx) + pmuludq %xmm7,%xmm1 + movdqa %xmm0,48(%esp) + pshufd $177,%xmm5,%xmm4 + movd 28(%esi),%xmm3 + pshufd $204,%xmm2,%xmm2 + movdqa %xmm2,96(%ebx) + pmuludq %xmm7,%xmm2 + movdqa %xmm1,64(%esp) + psubq %xmm5,%xmm4 + movd (%ebp),%xmm0 + pshufd $204,%xmm3,%xmm3 + movdqa %xmm3,112(%ebx) + pmuludq %xmm7,%xmm3 + pshuflw $220,%xmm0,%xmm7 + movdqa (%ebx),%xmm0 + pshufd $220,%xmm7,%xmm7 + movl $6,%ecx + leal 4(%ebp),%ebp + jmp .L005madd_sse2 +.align 16 +.L005madd_sse2: + paddq %xmm5,%xmm2 + paddq %xmm4,%xmm3 + movdqa 16(%ebx),%xmm1 + pmuludq %xmm7,%xmm0 + movdqa %xmm2,80(%esp) + movdqa 32(%ebx),%xmm2 + pmuludq %xmm7,%xmm1 + movdqa %xmm3,96(%esp) + paddq (%esp),%xmm0 + movdqa 48(%ebx),%xmm3 + pmuludq %xmm7,%xmm2 + movq %xmm0,%xmm4 + pslldq $6,%xmm4 + paddq 16(%esp),%xmm1 + paddq %xmm0,%xmm4 + movdqa %xmm4,%xmm5 + psrldq $10,%xmm4 + movdqa 64(%ebx),%xmm0 + pmuludq %xmm7,%xmm3 + paddq %xmm4,%xmm1 + paddq 32(%esp),%xmm2 + movdqa %xmm1,(%esp) + movdqa 80(%ebx),%xmm1 + pmuludq %xmm7,%xmm0 + paddq 48(%esp),%xmm3 + movdqa %xmm2,16(%esp) + pand %xmm6,%xmm5 + movdqa 96(%ebx),%xmm2 + pmuludq %xmm7,%xmm1 + paddq %xmm5,%xmm3 + paddq 64(%esp),%xmm0 + movdqa %xmm3,32(%esp) + pshufd $177,%xmm5,%xmm4 + movdqa %xmm7,%xmm3 + pmuludq %xmm7,%xmm2 + movd (%ebp),%xmm7 + leal 4(%ebp),%ebp + paddq 80(%esp),%xmm1 + psubq %xmm5,%xmm4 + movdqa %xmm0,48(%esp) + pshuflw $220,%xmm7,%xmm7 + pmuludq 112(%ebx),%xmm3 + pshufd $220,%xmm7,%xmm7 + movdqa (%ebx),%xmm0 + movdqa %xmm1,64(%esp) + paddq 96(%esp),%xmm2 + decl %ecx + jnz .L005madd_sse2 + paddq %xmm5,%xmm2 + paddq %xmm4,%xmm3 + movdqa 16(%ebx),%xmm1 + pmuludq %xmm7,%xmm0 + movdqa %xmm2,80(%esp) + movdqa 32(%ebx),%xmm2 + pmuludq %xmm7,%xmm1 + movdqa %xmm3,96(%esp) + paddq (%esp),%xmm0 + movdqa 48(%ebx),%xmm3 + pmuludq %xmm7,%xmm2 + movq %xmm0,%xmm4 + pslldq $6,%xmm4 + paddq 16(%esp),%xmm1 + paddq %xmm0,%xmm4 + movdqa %xmm4,%xmm5 + psrldq $10,%xmm4 + movdqa 64(%ebx),%xmm0 + pmuludq %xmm7,%xmm3 + paddq %xmm4,%xmm1 + paddq 32(%esp),%xmm2 + movdqa %xmm1,(%esp) + movdqa 80(%ebx),%xmm1 + pmuludq %xmm7,%xmm0 + paddq 48(%esp),%xmm3 + movdqa %xmm2,16(%esp) + pand %xmm6,%xmm5 + movdqa 96(%ebx),%xmm2 + pmuludq %xmm7,%xmm1 + paddq %xmm5,%xmm3 + paddq 64(%esp),%xmm0 + movdqa %xmm3,32(%esp) + pshufd $177,%xmm5,%xmm4 + movdqa 112(%ebx),%xmm3 + pmuludq %xmm7,%xmm2 + paddq 80(%esp),%xmm1 + psubq %xmm5,%xmm4 + movdqa %xmm0,48(%esp) + pmuludq %xmm7,%xmm3 + pcmpeqd %xmm7,%xmm7 + movdqa (%esp),%xmm0 + pslldq $8,%xmm7 + movdqa %xmm1,64(%esp) + paddq 96(%esp),%xmm2 + paddq %xmm5,%xmm2 + paddq %xmm4,%xmm3 + movdqa %xmm2,80(%esp) + movdqa %xmm3,96(%esp) + movdqa 16(%esp),%xmm1 + movdqa 32(%esp),%xmm2 + movdqa 48(%esp),%xmm3 + movq %xmm0,%xmm4 + pand %xmm7,%xmm0 + xorl %ebp,%ebp + pslldq $6,%xmm4 + movq %xmm1,%xmm5 + paddq %xmm4,%xmm0 + pand %xmm7,%xmm1 + psrldq $6,%xmm0 + movd %xmm0,%eax + psrldq $4,%xmm0 + paddq %xmm0,%xmm5 + movdqa 64(%esp),%xmm0 + subl $-1,%eax + pslldq $6,%xmm5 + movq %xmm2,%xmm4 + paddq %xmm5,%xmm1 + pand %xmm7,%xmm2 + psrldq $6,%xmm1 + movl %eax,(%edi) + movd %xmm1,%eax + psrldq $4,%xmm1 + paddq %xmm1,%xmm4 + movdqa 80(%esp),%xmm1 + sbbl $-1,%eax + pslldq $6,%xmm4 + movq %xmm3,%xmm5 + paddq %xmm4,%xmm2 + pand %xmm7,%xmm3 + psrldq $6,%xmm2 + movl %eax,4(%edi) + movd %xmm2,%eax + psrldq $4,%xmm2 + paddq %xmm2,%xmm5 + movdqa 96(%esp),%xmm2 + sbbl $-1,%eax + pslldq $6,%xmm5 + movq %xmm0,%xmm4 + paddq %xmm5,%xmm3 + pand %xmm7,%xmm0 + psrldq $6,%xmm3 + movl %eax,8(%edi) + movd %xmm3,%eax + psrldq $4,%xmm3 + paddq %xmm3,%xmm4 + sbbl $0,%eax + pslldq $6,%xmm4 + movq %xmm1,%xmm5 + paddq %xmm4,%xmm0 + pand %xmm7,%xmm1 + psrldq $6,%xmm0 + movl %eax,12(%edi) + movd %xmm0,%eax + psrldq $4,%xmm0 + paddq %xmm0,%xmm5 + sbbl $0,%eax + pslldq $6,%xmm5 + movq %xmm2,%xmm4 + paddq %xmm5,%xmm1 + pand %xmm7,%xmm2 + psrldq $6,%xmm1 + movd %xmm1,%ebx + psrldq $4,%xmm1 + movl %edx,%esp + paddq %xmm1,%xmm4 + pslldq $6,%xmm4 + paddq %xmm4,%xmm2 + psrldq $6,%xmm2 + movd %xmm2,%ecx + psrldq $4,%xmm2 + sbbl $0,%ebx + movd %xmm2,%edx + pextrw $2,%xmm2,%esi + sbbl $1,%ecx + sbbl $-1,%edx + sbbl $0,%esi + subl %esi,%ebp + addl %esi,(%edi) + adcl %esi,4(%edi) + adcl %esi,8(%edi) + adcl $0,12(%edi) + adcl $0,%eax + adcl $0,%ebx + movl %eax,16(%edi) + adcl %ebp,%ecx + movl %ebx,20(%edi) + adcl %esi,%edx + movl %ecx,24(%edi) + movl %edx,28(%edi) + ret +.align 16 +.L004mul_mont_ialu: + subl $40,%esp + movl (%esi),%eax + movl (%ebp),%ebx + movl %edi,32(%esp) + mull %ebx + movl %eax,(%esp) + movl 4(%esi),%eax + movl %edx,%ecx + mull %ebx + addl %eax,%ecx + movl 8(%esi),%eax + adcl $0,%edx + movl %ecx,4(%esp) + movl %edx,%ecx + mull %ebx + addl %eax,%ecx + movl 12(%esi),%eax + adcl $0,%edx + movl %ecx,8(%esp) + movl %edx,%ecx + mull %ebx + addl %eax,%ecx + movl 16(%esi),%eax + adcl $0,%edx + movl %ecx,12(%esp) + movl %edx,%ecx + mull %ebx + addl %eax,%ecx + movl 20(%esi),%eax + adcl $0,%edx + movl %ecx,16(%esp) + movl %edx,%ecx + mull %ebx + addl %eax,%ecx + movl 24(%esi),%eax + adcl $0,%edx + movl %ecx,20(%esp) + movl %edx,%ecx + mull %ebx + addl %eax,%ecx + movl 28(%esi),%eax + adcl $0,%edx + movl %ecx,24(%esp) + movl %edx,%ecx + xorl %edi,%edi + mull %ebx + addl %eax,%ecx + movl (%esp),%eax + adcl $0,%edx + addl %eax,12(%esp) + adcl $0,16(%esp) + adcl $0,20(%esp) + adcl %eax,24(%esp) + adcl $0,%ecx + adcl %eax,%edx + adcl $0,%edi + movl 4(%ebp),%ebx + subl %eax,%ecx + movl (%esi),%eax + sbbl $0,%edx + movl %ecx,28(%esp) + sbbl $0,%edi + movl %edx,(%esp) + mull %ebx + addl 4(%esp),%eax + adcl $0,%edx + movl %eax,4(%esp) + movl 4(%esi),%eax + movl %edx,%ecx + mull %ebx + addl 8(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 8(%esi),%eax + movl %ecx,8(%esp) + movl %edx,%ecx + mull %ebx + addl 12(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 12(%esi),%eax + movl %ecx,12(%esp) + movl %edx,%ecx + mull %ebx + addl 16(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 16(%esi),%eax + movl %ecx,16(%esp) + movl %edx,%ecx + mull %ebx + addl 20(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 20(%esi),%eax + movl %ecx,20(%esp) + movl %edx,%ecx + mull %ebx + addl 24(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 24(%esi),%eax + movl %ecx,24(%esp) + movl %edx,%ecx + mull %ebx + addl 28(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 28(%esi),%eax + movl %ecx,28(%esp) + movl %edx,%ecx + mull %ebx + addl (%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + movl 4(%esp),%eax + adcl %edi,%edx + movl $0,%edi + adcl $0,%edi + addl %eax,16(%esp) + adcl $0,20(%esp) + adcl $0,24(%esp) + adcl %eax,28(%esp) + adcl $0,%ecx + adcl %eax,%edx + adcl $0,%edi + movl 8(%ebp),%ebx + subl %eax,%ecx + movl (%esi),%eax + sbbl $0,%edx + movl %ecx,(%esp) + sbbl $0,%edi + movl %edx,4(%esp) + mull %ebx + addl 8(%esp),%eax + adcl $0,%edx + movl %eax,8(%esp) + movl 4(%esi),%eax + movl %edx,%ecx + mull %ebx + addl 12(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 8(%esi),%eax + movl %ecx,12(%esp) + movl %edx,%ecx + mull %ebx + addl 16(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 12(%esi),%eax + movl %ecx,16(%esp) + movl %edx,%ecx + mull %ebx + addl 20(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 16(%esi),%eax + movl %ecx,20(%esp) + movl %edx,%ecx + mull %ebx + addl 24(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 20(%esi),%eax + movl %ecx,24(%esp) + movl %edx,%ecx + mull %ebx + addl 28(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 24(%esi),%eax + movl %ecx,28(%esp) + movl %edx,%ecx + mull %ebx + addl (%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 28(%esi),%eax + movl %ecx,(%esp) + movl %edx,%ecx + mull %ebx + addl 4(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + movl 8(%esp),%eax + adcl %edi,%edx + movl $0,%edi + adcl $0,%edi + addl %eax,20(%esp) + adcl $0,24(%esp) + adcl $0,28(%esp) + adcl %eax,(%esp) + adcl $0,%ecx + adcl %eax,%edx + adcl $0,%edi + movl 12(%ebp),%ebx + subl %eax,%ecx + movl (%esi),%eax + sbbl $0,%edx + movl %ecx,4(%esp) + sbbl $0,%edi + movl %edx,8(%esp) + mull %ebx + addl 12(%esp),%eax + adcl $0,%edx + movl %eax,12(%esp) + movl 4(%esi),%eax + movl %edx,%ecx + mull %ebx + addl 16(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 8(%esi),%eax + movl %ecx,16(%esp) + movl %edx,%ecx + mull %ebx + addl 20(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 12(%esi),%eax + movl %ecx,20(%esp) + movl %edx,%ecx + mull %ebx + addl 24(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 16(%esi),%eax + movl %ecx,24(%esp) + movl %edx,%ecx + mull %ebx + addl 28(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 20(%esi),%eax + movl %ecx,28(%esp) + movl %edx,%ecx + mull %ebx + addl (%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 24(%esi),%eax + movl %ecx,(%esp) + movl %edx,%ecx + mull %ebx + addl 4(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 28(%esi),%eax + movl %ecx,4(%esp) + movl %edx,%ecx + mull %ebx + addl 8(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + movl 12(%esp),%eax + adcl %edi,%edx + movl $0,%edi + adcl $0,%edi + addl %eax,24(%esp) + adcl $0,28(%esp) + adcl $0,(%esp) + adcl %eax,4(%esp) + adcl $0,%ecx + adcl %eax,%edx + adcl $0,%edi + movl 16(%ebp),%ebx + subl %eax,%ecx + movl (%esi),%eax + sbbl $0,%edx + movl %ecx,8(%esp) + sbbl $0,%edi + movl %edx,12(%esp) + mull %ebx + addl 16(%esp),%eax + adcl $0,%edx + movl %eax,16(%esp) + movl 4(%esi),%eax + movl %edx,%ecx + mull %ebx + addl 20(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 8(%esi),%eax + movl %ecx,20(%esp) + movl %edx,%ecx + mull %ebx + addl 24(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 12(%esi),%eax + movl %ecx,24(%esp) + movl %edx,%ecx + mull %ebx + addl 28(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 16(%esi),%eax + movl %ecx,28(%esp) + movl %edx,%ecx + mull %ebx + addl (%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 20(%esi),%eax + movl %ecx,(%esp) + movl %edx,%ecx + mull %ebx + addl 4(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 24(%esi),%eax + movl %ecx,4(%esp) + movl %edx,%ecx + mull %ebx + addl 8(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 28(%esi),%eax + movl %ecx,8(%esp) + movl %edx,%ecx + mull %ebx + addl 12(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + movl 16(%esp),%eax + adcl %edi,%edx + movl $0,%edi + adcl $0,%edi + addl %eax,28(%esp) + adcl $0,(%esp) + adcl $0,4(%esp) + adcl %eax,8(%esp) + adcl $0,%ecx + adcl %eax,%edx + adcl $0,%edi + movl 20(%ebp),%ebx + subl %eax,%ecx + movl (%esi),%eax + sbbl $0,%edx + movl %ecx,12(%esp) + sbbl $0,%edi + movl %edx,16(%esp) + mull %ebx + addl 20(%esp),%eax + adcl $0,%edx + movl %eax,20(%esp) + movl 4(%esi),%eax + movl %edx,%ecx + mull %ebx + addl 24(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 8(%esi),%eax + movl %ecx,24(%esp) + movl %edx,%ecx + mull %ebx + addl 28(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 12(%esi),%eax + movl %ecx,28(%esp) + movl %edx,%ecx + mull %ebx + addl (%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 16(%esi),%eax + movl %ecx,(%esp) + movl %edx,%ecx + mull %ebx + addl 4(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 20(%esi),%eax + movl %ecx,4(%esp) + movl %edx,%ecx + mull %ebx + addl 8(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 24(%esi),%eax + movl %ecx,8(%esp) + movl %edx,%ecx + mull %ebx + addl 12(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 28(%esi),%eax + movl %ecx,12(%esp) + movl %edx,%ecx + mull %ebx + addl 16(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + movl 20(%esp),%eax + adcl %edi,%edx + movl $0,%edi + adcl $0,%edi + addl %eax,(%esp) + adcl $0,4(%esp) + adcl $0,8(%esp) + adcl %eax,12(%esp) + adcl $0,%ecx + adcl %eax,%edx + adcl $0,%edi + movl 24(%ebp),%ebx + subl %eax,%ecx + movl (%esi),%eax + sbbl $0,%edx + movl %ecx,16(%esp) + sbbl $0,%edi + movl %edx,20(%esp) + mull %ebx + addl 24(%esp),%eax + adcl $0,%edx + movl %eax,24(%esp) + movl 4(%esi),%eax + movl %edx,%ecx + mull %ebx + addl 28(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 8(%esi),%eax + movl %ecx,28(%esp) + movl %edx,%ecx + mull %ebx + addl (%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 12(%esi),%eax + movl %ecx,(%esp) + movl %edx,%ecx + mull %ebx + addl 4(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 16(%esi),%eax + movl %ecx,4(%esp) + movl %edx,%ecx + mull %ebx + addl 8(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 20(%esi),%eax + movl %ecx,8(%esp) + movl %edx,%ecx + mull %ebx + addl 12(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 24(%esi),%eax + movl %ecx,12(%esp) + movl %edx,%ecx + mull %ebx + addl 16(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 28(%esi),%eax + movl %ecx,16(%esp) + movl %edx,%ecx + mull %ebx + addl 20(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + movl 24(%esp),%eax + adcl %edi,%edx + movl $0,%edi + adcl $0,%edi + addl %eax,4(%esp) + adcl $0,8(%esp) + adcl $0,12(%esp) + adcl %eax,16(%esp) + adcl $0,%ecx + adcl %eax,%edx + adcl $0,%edi + movl 28(%ebp),%ebx + subl %eax,%ecx + movl (%esi),%eax + sbbl $0,%edx + movl %ecx,20(%esp) + sbbl $0,%edi + movl %edx,24(%esp) + mull %ebx + addl 28(%esp),%eax + adcl $0,%edx + movl %eax,28(%esp) + movl 4(%esi),%eax + movl %edx,%ecx + mull %ebx + addl (%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 8(%esi),%eax + movl %ecx,(%esp) + movl %edx,%ecx + mull %ebx + addl 4(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 12(%esi),%eax + movl %ecx,4(%esp) + movl %edx,%ecx + mull %ebx + addl 8(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 16(%esi),%eax + movl %ecx,8(%esp) + movl %edx,%ecx + mull %ebx + addl 12(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 20(%esi),%eax + movl %ecx,12(%esp) + movl %edx,%ecx + mull %ebx + addl 16(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 24(%esi),%eax + movl %ecx,16(%esp) + movl %edx,%ecx + mull %ebx + addl 20(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + adcl $0,%edx + movl 28(%esi),%eax + movl %ecx,20(%esp) + movl %edx,%ecx + mull %ebx + addl 24(%esp),%ecx + adcl $0,%edx + addl %eax,%ecx + movl 28(%esp),%eax + adcl %edi,%edx + movl $0,%edi + adcl $0,%edi + movl 32(%esp),%ebp + xorl %esi,%esi + addl %eax,8(%esp) + adcl $0,12(%esp) + adcl $0,16(%esp) + adcl %eax,20(%esp) + adcl $0,%ecx + adcl %eax,%edx + adcl $0,%edi + movl 4(%esp),%ebx + subl %eax,%ecx + movl (%esp),%eax + sbbl $0,%edx + movl %ecx,24(%esp) + sbbl $0,%edi + movl %edx,28(%esp) + movl 8(%esp),%ecx + subl $-1,%eax + movl 12(%esp),%edx + sbbl $-1,%ebx + movl %eax,(%ebp) + sbbl $-1,%ecx + movl %ebx,4(%ebp) + sbbl $0,%edx + movl %ecx,8(%ebp) + movl %edx,12(%ebp) + movl 16(%esp),%eax + movl 20(%esp),%ebx + movl 24(%esp),%ecx + sbbl $0,%eax + movl 28(%esp),%edx + sbbl $0,%ebx + sbbl $1,%ecx + sbbl $-1,%edx + sbbl $0,%edi + subl %edi,%esi + addl %edi,(%ebp) + adcl %edi,4(%ebp) + adcl %edi,8(%ebp) + adcl $0,12(%ebp) + adcl $0,%eax + adcl $0,%ebx + movl %eax,16(%ebp) + adcl %esi,%ecx + movl %ebx,20(%ebp) + adcl %edi,%edx + movl %ecx,24(%ebp) + movl %ebp,%edi + movl %edx,28(%ebp) + addl $40,%esp + ret +.size _ecp_nistz256_mul_mont,.-_ecp_nistz256_mul_mont +.globl ecp_nistz256_scatter_w5 +.type ecp_nistz256_scatter_w5,@function +.align 16 +ecp_nistz256_scatter_w5: +.L_ecp_nistz256_scatter_w5_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%edi + movl 24(%esp),%esi + movl 28(%esp),%ebp + leal 124(%edi,%ebp,4),%edi + movl $6,%ebp +.L006scatter_w5_loop: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + leal 16(%esi),%esi + movl %eax,-128(%edi) + movl %ebx,-64(%edi) + movl %ecx,(%edi) + movl %edx,64(%edi) + leal 256(%edi),%edi + decl %ebp + jnz .L006scatter_w5_loop + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_scatter_w5,.-.L_ecp_nistz256_scatter_w5_begin +.globl ecp_nistz256_gather_w5 +.type ecp_nistz256_gather_w5,@function +.align 16 +ecp_nistz256_gather_w5: +.L_ecp_nistz256_gather_w5_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + movl 28(%esp),%ebp + leal (%esi,%ebp,4),%esi + negl %ebp + sarl $31,%ebp + movl 20(%esp),%edi + leal (%esi,%ebp,4),%esi + movl (%esi),%eax + movl 64(%esi),%ebx + movl 128(%esi),%ecx + movl 192(%esi),%edx + andl %ebp,%eax + andl %ebp,%ebx + andl %ebp,%ecx + andl %ebp,%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 256(%esi),%eax + movl 320(%esi),%ebx + movl 384(%esi),%ecx + movl 448(%esi),%edx + andl %ebp,%eax + andl %ebp,%ebx + andl %ebp,%ecx + andl %ebp,%edx + movl %eax,16(%edi) + movl %ebx,20(%edi) + movl %ecx,24(%edi) + movl %edx,28(%edi) + movl 512(%esi),%eax + movl 576(%esi),%ebx + movl 640(%esi),%ecx + movl 704(%esi),%edx + andl %ebp,%eax + andl %ebp,%ebx + andl %ebp,%ecx + andl %ebp,%edx + movl %eax,32(%edi) + movl %ebx,36(%edi) + movl %ecx,40(%edi) + movl %edx,44(%edi) + movl 768(%esi),%eax + movl 832(%esi),%ebx + movl 896(%esi),%ecx + movl 960(%esi),%edx + andl %ebp,%eax + andl %ebp,%ebx + andl %ebp,%ecx + andl %ebp,%edx + movl %eax,48(%edi) + movl %ebx,52(%edi) + movl %ecx,56(%edi) + movl %edx,60(%edi) + movl 1024(%esi),%eax + movl 1088(%esi),%ebx + movl 1152(%esi),%ecx + movl 1216(%esi),%edx + andl %ebp,%eax + andl %ebp,%ebx + andl %ebp,%ecx + andl %ebp,%edx + movl %eax,64(%edi) + movl %ebx,68(%edi) + movl %ecx,72(%edi) + movl %edx,76(%edi) + movl 1280(%esi),%eax + movl 1344(%esi),%ebx + movl 1408(%esi),%ecx + movl 1472(%esi),%edx + andl %ebp,%eax + andl %ebp,%ebx + andl %ebp,%ecx + andl %ebp,%edx + movl %eax,80(%edi) + movl %ebx,84(%edi) + movl %ecx,88(%edi) + movl %edx,92(%edi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_gather_w5,.-.L_ecp_nistz256_gather_w5_begin +.globl ecp_nistz256_scatter_w7 +.type ecp_nistz256_scatter_w7,@function +.align 16 +ecp_nistz256_scatter_w7: +.L_ecp_nistz256_scatter_w7_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%edi + movl 24(%esp),%esi + movl 28(%esp),%ebp + leal (%edi,%ebp,1),%edi + movl $16,%ebp +.L007scatter_w7_loop: + movl (%esi),%eax + leal 4(%esi),%esi + movb %al,(%edi) + movb %ah,64(%edi) + shrl $16,%eax + movb %al,128(%edi) + movb %ah,192(%edi) + leal 256(%edi),%edi + decl %ebp + jnz .L007scatter_w7_loop + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_scatter_w7,.-.L_ecp_nistz256_scatter_w7_begin +.globl ecp_nistz256_gather_w7 +.type ecp_nistz256_gather_w7,@function +.align 16 +ecp_nistz256_gather_w7: +.L_ecp_nistz256_gather_w7_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + movl 28(%esp),%ebp + addl %ebp,%esi + negl %ebp + sarl $31,%ebp + movl 20(%esp),%edi + leal (%esi,%ebp,1),%esi + movzbl (%esi),%eax + movzbl 64(%esi),%ebx + movzbl 128(%esi),%ecx + andl %ebp,%eax + movzbl 192(%esi),%edx + andl %ebp,%ebx + movb %al,(%edi) + andl %ebp,%ecx + movb %bl,1(%edi) + andl %ebp,%edx + movb %cl,2(%edi) + movb %dl,3(%edi) + movzbl 256(%esi),%eax + movzbl 320(%esi),%ebx + movzbl 384(%esi),%ecx + andl %ebp,%eax + movzbl 448(%esi),%edx + andl %ebp,%ebx + movb %al,4(%edi) + andl %ebp,%ecx + movb %bl,5(%edi) + andl %ebp,%edx + movb %cl,6(%edi) + movb %dl,7(%edi) + movzbl 512(%esi),%eax + movzbl 576(%esi),%ebx + movzbl 640(%esi),%ecx + andl %ebp,%eax + movzbl 704(%esi),%edx + andl %ebp,%ebx + movb %al,8(%edi) + andl %ebp,%ecx + movb %bl,9(%edi) + andl %ebp,%edx + movb %cl,10(%edi) + movb %dl,11(%edi) + movzbl 768(%esi),%eax + movzbl 832(%esi),%ebx + movzbl 896(%esi),%ecx + andl %ebp,%eax + movzbl 960(%esi),%edx + andl %ebp,%ebx + movb %al,12(%edi) + andl %ebp,%ecx + movb %bl,13(%edi) + andl %ebp,%edx + movb %cl,14(%edi) + movb %dl,15(%edi) + movzbl 1024(%esi),%eax + movzbl 1088(%esi),%ebx + movzbl 1152(%esi),%ecx + andl %ebp,%eax + movzbl 1216(%esi),%edx + andl %ebp,%ebx + movb %al,16(%edi) + andl %ebp,%ecx + movb %bl,17(%edi) + andl %ebp,%edx + movb %cl,18(%edi) + movb %dl,19(%edi) + movzbl 1280(%esi),%eax + movzbl 1344(%esi),%ebx + movzbl 1408(%esi),%ecx + andl %ebp,%eax + movzbl 1472(%esi),%edx + andl %ebp,%ebx + movb %al,20(%edi) + andl %ebp,%ecx + movb %bl,21(%edi) + andl %ebp,%edx + movb %cl,22(%edi) + movb %dl,23(%edi) + movzbl 1536(%esi),%eax + movzbl 1600(%esi),%ebx + movzbl 1664(%esi),%ecx + andl %ebp,%eax + movzbl 1728(%esi),%edx + andl %ebp,%ebx + movb %al,24(%edi) + andl %ebp,%ecx + movb %bl,25(%edi) + andl %ebp,%edx + movb %cl,26(%edi) + movb %dl,27(%edi) + movzbl 1792(%esi),%eax + movzbl 1856(%esi),%ebx + movzbl 1920(%esi),%ecx + andl %ebp,%eax + movzbl 1984(%esi),%edx + andl %ebp,%ebx + movb %al,28(%edi) + andl %ebp,%ecx + movb %bl,29(%edi) + andl %ebp,%edx + movb %cl,30(%edi) + movb %dl,31(%edi) + movzbl 2048(%esi),%eax + movzbl 2112(%esi),%ebx + movzbl 2176(%esi),%ecx + andl %ebp,%eax + movzbl 2240(%esi),%edx + andl %ebp,%ebx + movb %al,32(%edi) + andl %ebp,%ecx + movb %bl,33(%edi) + andl %ebp,%edx + movb %cl,34(%edi) + movb %dl,35(%edi) + movzbl 2304(%esi),%eax + movzbl 2368(%esi),%ebx + movzbl 2432(%esi),%ecx + andl %ebp,%eax + movzbl 2496(%esi),%edx + andl %ebp,%ebx + movb %al,36(%edi) + andl %ebp,%ecx + movb %bl,37(%edi) + andl %ebp,%edx + movb %cl,38(%edi) + movb %dl,39(%edi) + movzbl 2560(%esi),%eax + movzbl 2624(%esi),%ebx + movzbl 2688(%esi),%ecx + andl %ebp,%eax + movzbl 2752(%esi),%edx + andl %ebp,%ebx + movb %al,40(%edi) + andl %ebp,%ecx + movb %bl,41(%edi) + andl %ebp,%edx + movb %cl,42(%edi) + movb %dl,43(%edi) + movzbl 2816(%esi),%eax + movzbl 2880(%esi),%ebx + movzbl 2944(%esi),%ecx + andl %ebp,%eax + movzbl 3008(%esi),%edx + andl %ebp,%ebx + movb %al,44(%edi) + andl %ebp,%ecx + movb %bl,45(%edi) + andl %ebp,%edx + movb %cl,46(%edi) + movb %dl,47(%edi) + movzbl 3072(%esi),%eax + movzbl 3136(%esi),%ebx + movzbl 3200(%esi),%ecx + andl %ebp,%eax + movzbl 3264(%esi),%edx + andl %ebp,%ebx + movb %al,48(%edi) + andl %ebp,%ecx + movb %bl,49(%edi) + andl %ebp,%edx + movb %cl,50(%edi) + movb %dl,51(%edi) + movzbl 3328(%esi),%eax + movzbl 3392(%esi),%ebx + movzbl 3456(%esi),%ecx + andl %ebp,%eax + movzbl 3520(%esi),%edx + andl %ebp,%ebx + movb %al,52(%edi) + andl %ebp,%ecx + movb %bl,53(%edi) + andl %ebp,%edx + movb %cl,54(%edi) + movb %dl,55(%edi) + movzbl 3584(%esi),%eax + movzbl 3648(%esi),%ebx + movzbl 3712(%esi),%ecx + andl %ebp,%eax + movzbl 3776(%esi),%edx + andl %ebp,%ebx + movb %al,56(%edi) + andl %ebp,%ecx + movb %bl,57(%edi) + andl %ebp,%edx + movb %cl,58(%edi) + movb %dl,59(%edi) + movzbl 3840(%esi),%eax + movzbl 3904(%esi),%ebx + movzbl 3968(%esi),%ecx + andl %ebp,%eax + movzbl 4032(%esi),%edx + andl %ebp,%ebx + movb %al,60(%edi) + andl %ebp,%ecx + movb %bl,61(%edi) + andl %ebp,%edx + movb %cl,62(%edi) + movb %dl,63(%edi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_gather_w7,.-.L_ecp_nistz256_gather_w7_begin +.globl ecp_nistz256_point_double +.type ecp_nistz256_point_double,@function +.align 16 +ecp_nistz256_point_double: +.L_ecp_nistz256_point_double_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + subl $164,%esp + call _picup_eax +.L008pic: + leal OPENSSL_ia32cap_P-.L008pic(%eax),%edx + movl (%edx),%ebp +.Lpoint_double_shortcut: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,96(%esp) + movl %ebx,100(%esp) + movl %ecx,104(%esp) + movl %edx,108(%esp) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + movl %eax,112(%esp) + movl %ebx,116(%esp) + movl %ecx,120(%esp) + movl %edx,124(%esp) + movl %ebp,160(%esp) + leal 32(%esi),%ebp + leal 32(%esi),%esi + leal (%esp),%edi + call _ecp_nistz256_add + movl 160(%esp),%eax + movl $64,%esi + addl 188(%esp),%esi + leal 64(%esp),%edi + movl %esi,%ebp + call _ecp_nistz256_mul_mont + movl 160(%esp),%eax + leal (%esp),%esi + leal (%esp),%ebp + leal (%esp),%edi + call _ecp_nistz256_mul_mont + movl 160(%esp),%eax + movl 188(%esp),%ebp + leal 32(%ebp),%esi + leal 64(%ebp),%ebp + leal 128(%esp),%edi + call _ecp_nistz256_mul_mont + leal 96(%esp),%esi + leal 64(%esp),%ebp + leal 32(%esp),%edi + call _ecp_nistz256_add + movl $64,%edi + leal 128(%esp),%esi + leal 128(%esp),%ebp + addl 184(%esp),%edi + call _ecp_nistz256_add + leal 96(%esp),%esi + leal 64(%esp),%ebp + leal 64(%esp),%edi + call _ecp_nistz256_sub + movl 160(%esp),%eax + leal (%esp),%esi + leal (%esp),%ebp + leal 128(%esp),%edi + call _ecp_nistz256_mul_mont + movl 160(%esp),%eax + leal 32(%esp),%esi + leal 64(%esp),%ebp + leal 32(%esp),%edi + call _ecp_nistz256_mul_mont + movl $32,%edi + leal 128(%esp),%esi + addl 184(%esp),%edi + call _ecp_nistz256_div_by_2 + leal 32(%esp),%esi + leal 32(%esp),%ebp + leal 128(%esp),%edi + call _ecp_nistz256_add + movl 160(%esp),%eax + leal 96(%esp),%esi + leal (%esp),%ebp + leal (%esp),%edi + call _ecp_nistz256_mul_mont + leal 128(%esp),%esi + leal 32(%esp),%ebp + leal 32(%esp),%edi + call _ecp_nistz256_add + leal (%esp),%esi + leal (%esp),%ebp + leal 128(%esp),%edi + call _ecp_nistz256_add + movl 160(%esp),%eax + leal 32(%esp),%esi + leal 32(%esp),%ebp + movl 184(%esp),%edi + call _ecp_nistz256_mul_mont + movl %edi,%esi + leal 128(%esp),%ebp + call _ecp_nistz256_sub + leal (%esp),%esi + movl %edi,%ebp + leal (%esp),%edi + call _ecp_nistz256_sub + movl 160(%esp),%eax + movl %edi,%esi + leal 32(%esp),%ebp + call _ecp_nistz256_mul_mont + movl $32,%ebp + leal (%esp),%esi + addl 184(%esp),%ebp + movl %ebp,%edi + call _ecp_nistz256_sub + addl $164,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_point_double,.-.L_ecp_nistz256_point_double_begin +.globl ecp_nistz256_point_add +.type ecp_nistz256_point_add,@function +.align 16 +ecp_nistz256_point_add: +.L_ecp_nistz256_point_add_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 28(%esp),%esi + subl $596,%esp + call _picup_eax +.L009pic: + leal OPENSSL_ia32cap_P-.L009pic(%eax),%edx + movl (%edx),%ebp + leal 192(%esp),%edi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %ebp,588(%esp) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + movl %eax,16(%edi) + movl %ebx,20(%edi) + movl %ecx,24(%edi) + movl %edx,28(%edi) + movl 32(%esi),%eax + movl 36(%esi),%ebx + movl 40(%esi),%ecx + movl 44(%esi),%edx + movl %eax,32(%edi) + movl %ebx,36(%edi) + movl %ecx,40(%edi) + movl %edx,44(%edi) + movl 48(%esi),%eax + movl 52(%esi),%ebx + movl 56(%esi),%ecx + movl 60(%esi),%edx + movl %eax,48(%edi) + movl %ebx,52(%edi) + movl %ecx,56(%edi) + movl %edx,60(%edi) + movl 64(%esi),%eax + movl 68(%esi),%ebx + movl 72(%esi),%ecx + movl 76(%esi),%edx + movl %eax,64(%edi) + movl %eax,%ebp + movl %ebx,68(%edi) + orl %ebx,%ebp + movl %ecx,72(%edi) + orl %ecx,%ebp + movl %edx,76(%edi) + orl %edx,%ebp + movl 80(%esi),%eax + movl 84(%esi),%ebx + movl 88(%esi),%ecx + movl 92(%esi),%edx + movl %eax,80(%edi) + orl %eax,%ebp + movl %ebx,84(%edi) + orl %ebx,%ebp + movl %ecx,88(%edi) + orl %ecx,%ebp + movl %edx,92(%edi) + orl %edx,%ebp + xorl %eax,%eax + movl 620(%esp),%esi + subl %ebp,%eax + orl %eax,%ebp + sarl $31,%ebp + movl %ebp,580(%esp) + leal 96(%esp),%edi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + movl %eax,16(%edi) + movl %ebx,20(%edi) + movl %ecx,24(%edi) + movl %edx,28(%edi) + movl 32(%esi),%eax + movl 36(%esi),%ebx + movl 40(%esi),%ecx + movl 44(%esi),%edx + movl %eax,32(%edi) + movl %ebx,36(%edi) + movl %ecx,40(%edi) + movl %edx,44(%edi) + movl 48(%esi),%eax + movl 52(%esi),%ebx + movl 56(%esi),%ecx + movl 60(%esi),%edx + movl %eax,48(%edi) + movl %ebx,52(%edi) + movl %ecx,56(%edi) + movl %edx,60(%edi) + movl 64(%esi),%eax + movl 68(%esi),%ebx + movl 72(%esi),%ecx + movl 76(%esi),%edx + movl %eax,64(%edi) + movl %eax,%ebp + movl %ebx,68(%edi) + orl %ebx,%ebp + movl %ecx,72(%edi) + orl %ecx,%ebp + movl %edx,76(%edi) + orl %edx,%ebp + movl 80(%esi),%eax + movl 84(%esi),%ebx + movl 88(%esi),%ecx + movl 92(%esi),%edx + movl %eax,80(%edi) + orl %eax,%ebp + movl %ebx,84(%edi) + orl %ebx,%ebp + movl %ecx,88(%edi) + orl %ecx,%ebp + movl %edx,92(%edi) + orl %edx,%ebp + xorl %eax,%eax + subl %ebp,%eax + orl %eax,%ebp + sarl $31,%ebp + movl %ebp,576(%esp) + movl 588(%esp),%eax + leal 256(%esp),%esi + leal 256(%esp),%ebp + leal 384(%esp),%edi + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 160(%esp),%esi + leal 160(%esp),%ebp + leal 320(%esp),%edi + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 384(%esp),%esi + leal 256(%esp),%ebp + leal 512(%esp),%edi + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 320(%esp),%esi + leal 160(%esp),%ebp + leal 544(%esp),%edi + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 128(%esp),%esi + leal 512(%esp),%ebp + leal 512(%esp),%edi + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 224(%esp),%esi + leal 544(%esp),%ebp + leal 544(%esp),%edi + call _ecp_nistz256_mul_mont + leal 544(%esp),%esi + leal 512(%esp),%ebp + leal 352(%esp),%edi + call _ecp_nistz256_sub + orl %eax,%ebx + movl 588(%esp),%eax + orl %ecx,%ebx + orl %edx,%ebx + orl (%edi),%ebx + orl 4(%edi),%ebx + leal 96(%esp),%esi + orl 8(%edi),%ebx + leal 384(%esp),%ebp + orl 12(%edi),%ebx + leal 448(%esp),%edi + movl %ebx,584(%esp) + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 192(%esp),%esi + leal 320(%esp),%ebp + leal 480(%esp),%edi + call _ecp_nistz256_mul_mont + leal 480(%esp),%esi + leal 448(%esp),%ebp + leal 288(%esp),%edi + call _ecp_nistz256_sub + orl %ebx,%eax + orl %ecx,%eax + orl %edx,%eax + orl (%edi),%eax + orl 4(%edi),%eax + orl 8(%edi),%eax + orl 12(%edi),%eax + movl 576(%esp),%ebx + notl %ebx + orl %ebx,%eax + movl 580(%esp),%ebx + notl %ebx + orl %ebx,%eax + orl 584(%esp),%eax +.byte 62 + jnz .L010add_proceed +.align 16 +.L011add_double: + movl 620(%esp),%esi + movl 588(%esp),%ebp + addl $432,%esp + jmp .Lpoint_double_shortcut +.align 16 +.L010add_proceed: + movl 588(%esp),%eax + leal 352(%esp),%esi + leal 352(%esp),%ebp + leal 384(%esp),%edi + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 288(%esp),%esi + leal 160(%esp),%ebp + leal 64(%esp),%edi + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 288(%esp),%esi + leal 288(%esp),%ebp + leal 320(%esp),%edi + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 256(%esp),%esi + leal 64(%esp),%ebp + leal 64(%esp),%edi + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 320(%esp),%esi + leal 448(%esp),%ebp + leal 480(%esp),%edi + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 288(%esp),%esi + leal 320(%esp),%ebp + leal 416(%esp),%edi + call _ecp_nistz256_mul_mont + leal 480(%esp),%esi + leal 480(%esp),%ebp + leal 320(%esp),%edi + call _ecp_nistz256_add + leal 384(%esp),%esi + leal 320(%esp),%ebp + leal (%esp),%edi + call _ecp_nistz256_sub + leal (%esp),%esi + leal 416(%esp),%ebp + leal (%esp),%edi + call _ecp_nistz256_sub + leal 480(%esp),%esi + leal (%esp),%ebp + leal 32(%esp),%edi + call _ecp_nistz256_sub + movl 588(%esp),%eax + leal 416(%esp),%esi + leal 512(%esp),%ebp + leal 544(%esp),%edi + call _ecp_nistz256_mul_mont + movl 588(%esp),%eax + leal 352(%esp),%esi + leal 32(%esp),%ebp + leal 32(%esp),%edi + call _ecp_nistz256_mul_mont + leal 32(%esp),%esi + leal 544(%esp),%ebp + leal 32(%esp),%edi + call _ecp_nistz256_sub + movl 576(%esp),%ebp + movl 580(%esp),%esi + movl 616(%esp),%edi + movl %ebp,%edx + notl %ebp + andl %esi,%edx + andl %esi,%ebp + notl %esi + movl %edx,%eax + andl 64(%esp),%eax + movl %ebp,%ebx + andl 256(%esp),%ebx + movl %esi,%ecx + andl 160(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,64(%edi) + movl %edx,%eax + andl 68(%esp),%eax + movl %ebp,%ebx + andl 260(%esp),%ebx + movl %esi,%ecx + andl 164(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,68(%edi) + movl %edx,%eax + andl 72(%esp),%eax + movl %ebp,%ebx + andl 264(%esp),%ebx + movl %esi,%ecx + andl 168(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,72(%edi) + movl %edx,%eax + andl 76(%esp),%eax + movl %ebp,%ebx + andl 268(%esp),%ebx + movl %esi,%ecx + andl 172(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,76(%edi) + movl %edx,%eax + andl 80(%esp),%eax + movl %ebp,%ebx + andl 272(%esp),%ebx + movl %esi,%ecx + andl 176(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,80(%edi) + movl %edx,%eax + andl 84(%esp),%eax + movl %ebp,%ebx + andl 276(%esp),%ebx + movl %esi,%ecx + andl 180(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,84(%edi) + movl %edx,%eax + andl 88(%esp),%eax + movl %ebp,%ebx + andl 280(%esp),%ebx + movl %esi,%ecx + andl 184(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,88(%edi) + movl %edx,%eax + andl 92(%esp),%eax + movl %ebp,%ebx + andl 284(%esp),%ebx + movl %esi,%ecx + andl 188(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,92(%edi) + movl %edx,%eax + andl (%esp),%eax + movl %ebp,%ebx + andl 192(%esp),%ebx + movl %esi,%ecx + andl 96(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,(%edi) + movl %edx,%eax + andl 4(%esp),%eax + movl %ebp,%ebx + andl 196(%esp),%ebx + movl %esi,%ecx + andl 100(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,4(%edi) + movl %edx,%eax + andl 8(%esp),%eax + movl %ebp,%ebx + andl 200(%esp),%ebx + movl %esi,%ecx + andl 104(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,8(%edi) + movl %edx,%eax + andl 12(%esp),%eax + movl %ebp,%ebx + andl 204(%esp),%ebx + movl %esi,%ecx + andl 108(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,12(%edi) + movl %edx,%eax + andl 16(%esp),%eax + movl %ebp,%ebx + andl 208(%esp),%ebx + movl %esi,%ecx + andl 112(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,16(%edi) + movl %edx,%eax + andl 20(%esp),%eax + movl %ebp,%ebx + andl 212(%esp),%ebx + movl %esi,%ecx + andl 116(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,20(%edi) + movl %edx,%eax + andl 24(%esp),%eax + movl %ebp,%ebx + andl 216(%esp),%ebx + movl %esi,%ecx + andl 120(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,24(%edi) + movl %edx,%eax + andl 28(%esp),%eax + movl %ebp,%ebx + andl 220(%esp),%ebx + movl %esi,%ecx + andl 124(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,28(%edi) + movl %edx,%eax + andl 32(%esp),%eax + movl %ebp,%ebx + andl 224(%esp),%ebx + movl %esi,%ecx + andl 128(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,32(%edi) + movl %edx,%eax + andl 36(%esp),%eax + movl %ebp,%ebx + andl 228(%esp),%ebx + movl %esi,%ecx + andl 132(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,36(%edi) + movl %edx,%eax + andl 40(%esp),%eax + movl %ebp,%ebx + andl 232(%esp),%ebx + movl %esi,%ecx + andl 136(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,40(%edi) + movl %edx,%eax + andl 44(%esp),%eax + movl %ebp,%ebx + andl 236(%esp),%ebx + movl %esi,%ecx + andl 140(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,44(%edi) + movl %edx,%eax + andl 48(%esp),%eax + movl %ebp,%ebx + andl 240(%esp),%ebx + movl %esi,%ecx + andl 144(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,48(%edi) + movl %edx,%eax + andl 52(%esp),%eax + movl %ebp,%ebx + andl 244(%esp),%ebx + movl %esi,%ecx + andl 148(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,52(%edi) + movl %edx,%eax + andl 56(%esp),%eax + movl %ebp,%ebx + andl 248(%esp),%ebx + movl %esi,%ecx + andl 152(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,56(%edi) + movl %edx,%eax + andl 60(%esp),%eax + movl %ebp,%ebx + andl 252(%esp),%ebx + movl %esi,%ecx + andl 156(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,60(%edi) +.L012add_done: + addl $596,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_point_add,.-.L_ecp_nistz256_point_add_begin +.globl ecp_nistz256_point_add_affine +.type ecp_nistz256_point_add_affine,@function +.align 16 +ecp_nistz256_point_add_affine: +.L_ecp_nistz256_point_add_affine_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 24(%esp),%esi + subl $492,%esp + call _picup_eax +.L013pic: + leal OPENSSL_ia32cap_P-.L013pic(%eax),%edx + movl (%edx),%ebp + leal 96(%esp),%edi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %ebp,488(%esp) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + movl %eax,16(%edi) + movl %ebx,20(%edi) + movl %ecx,24(%edi) + movl %edx,28(%edi) + movl 32(%esi),%eax + movl 36(%esi),%ebx + movl 40(%esi),%ecx + movl 44(%esi),%edx + movl %eax,32(%edi) + movl %ebx,36(%edi) + movl %ecx,40(%edi) + movl %edx,44(%edi) + movl 48(%esi),%eax + movl 52(%esi),%ebx + movl 56(%esi),%ecx + movl 60(%esi),%edx + movl %eax,48(%edi) + movl %ebx,52(%edi) + movl %ecx,56(%edi) + movl %edx,60(%edi) + movl 64(%esi),%eax + movl 68(%esi),%ebx + movl 72(%esi),%ecx + movl 76(%esi),%edx + movl %eax,64(%edi) + movl %eax,%ebp + movl %ebx,68(%edi) + orl %ebx,%ebp + movl %ecx,72(%edi) + orl %ecx,%ebp + movl %edx,76(%edi) + orl %edx,%ebp + movl 80(%esi),%eax + movl 84(%esi),%ebx + movl 88(%esi),%ecx + movl 92(%esi),%edx + movl %eax,80(%edi) + orl %eax,%ebp + movl %ebx,84(%edi) + orl %ebx,%ebp + movl %ecx,88(%edi) + orl %ecx,%ebp + movl %edx,92(%edi) + orl %edx,%ebp + xorl %eax,%eax + movl 520(%esp),%esi + subl %ebp,%eax + orl %eax,%ebp + sarl $31,%ebp + movl %ebp,480(%esp) + leal 192(%esp),%edi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + movl %eax,(%edi) + movl %eax,%ebp + movl %ebx,4(%edi) + orl %ebx,%ebp + movl %ecx,8(%edi) + orl %ecx,%ebp + movl %edx,12(%edi) + orl %edx,%ebp + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + movl %eax,16(%edi) + orl %eax,%ebp + movl %ebx,20(%edi) + orl %ebx,%ebp + movl %ecx,24(%edi) + orl %ecx,%ebp + movl %edx,28(%edi) + orl %edx,%ebp + movl 32(%esi),%eax + movl 36(%esi),%ebx + movl 40(%esi),%ecx + movl 44(%esi),%edx + movl %eax,32(%edi) + orl %eax,%ebp + movl %ebx,36(%edi) + orl %ebx,%ebp + movl %ecx,40(%edi) + orl %ecx,%ebp + movl %edx,44(%edi) + orl %edx,%ebp + movl 48(%esi),%eax + movl 52(%esi),%ebx + movl 56(%esi),%ecx + movl 60(%esi),%edx + movl %eax,48(%edi) + orl %eax,%ebp + movl %ebx,52(%edi) + orl %ebx,%ebp + movl %ecx,56(%edi) + orl %ecx,%ebp + movl %edx,60(%edi) + orl %edx,%ebp + xorl %ebx,%ebx + movl 488(%esp),%eax + subl %ebp,%ebx + leal 160(%esp),%esi + orl %ebp,%ebx + leal 160(%esp),%ebp + sarl $31,%ebx + leal 288(%esp),%edi + movl %ebx,484(%esp) + call _ecp_nistz256_mul_mont + movl 488(%esp),%eax + leal 192(%esp),%esi + movl %edi,%ebp + leal 256(%esp),%edi + call _ecp_nistz256_mul_mont + movl 488(%esp),%eax + leal 160(%esp),%esi + leal 288(%esp),%ebp + leal 288(%esp),%edi + call _ecp_nistz256_mul_mont + leal 256(%esp),%esi + leal 96(%esp),%ebp + leal 320(%esp),%edi + call _ecp_nistz256_sub + movl 488(%esp),%eax + leal 224(%esp),%esi + leal 288(%esp),%ebp + leal 288(%esp),%edi + call _ecp_nistz256_mul_mont + movl 488(%esp),%eax + leal 160(%esp),%esi + leal 320(%esp),%ebp + leal 64(%esp),%edi + call _ecp_nistz256_mul_mont + leal 288(%esp),%esi + leal 128(%esp),%ebp + leal 352(%esp),%edi + call _ecp_nistz256_sub + movl 488(%esp),%eax + leal 320(%esp),%esi + leal 320(%esp),%ebp + leal 384(%esp),%edi + call _ecp_nistz256_mul_mont + movl 488(%esp),%eax + leal 352(%esp),%esi + leal 352(%esp),%ebp + leal 448(%esp),%edi + call _ecp_nistz256_mul_mont + movl 488(%esp),%eax + leal 96(%esp),%esi + leal 384(%esp),%ebp + leal 256(%esp),%edi + call _ecp_nistz256_mul_mont + movl 488(%esp),%eax + leal 320(%esp),%esi + leal 384(%esp),%ebp + leal 416(%esp),%edi + call _ecp_nistz256_mul_mont + leal 256(%esp),%esi + leal 256(%esp),%ebp + leal 384(%esp),%edi + call _ecp_nistz256_add + leal 448(%esp),%esi + leal 384(%esp),%ebp + leal (%esp),%edi + call _ecp_nistz256_sub + leal (%esp),%esi + leal 416(%esp),%ebp + leal (%esp),%edi + call _ecp_nistz256_sub + leal 256(%esp),%esi + leal (%esp),%ebp + leal 32(%esp),%edi + call _ecp_nistz256_sub + movl 488(%esp),%eax + leal 416(%esp),%esi + leal 128(%esp),%ebp + leal 288(%esp),%edi + call _ecp_nistz256_mul_mont + movl 488(%esp),%eax + leal 352(%esp),%esi + leal 32(%esp),%ebp + leal 32(%esp),%edi + call _ecp_nistz256_mul_mont + leal 32(%esp),%esi + leal 288(%esp),%ebp + leal 32(%esp),%edi + call _ecp_nistz256_sub + movl 480(%esp),%ebp + movl 484(%esp),%esi + movl 512(%esp),%edi + movl %ebp,%edx + notl %ebp + andl %esi,%edx + andl %esi,%ebp + notl %esi + movl %edx,%eax + andl 64(%esp),%eax + movl %ebp,%ebx + andl $1,%ebx + movl %esi,%ecx + andl 160(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,64(%edi) + movl %edx,%eax + andl 68(%esp),%eax + movl %esi,%ecx + andl 164(%esp),%ecx + orl %ecx,%eax + movl %eax,68(%edi) + movl %edx,%eax + andl 72(%esp),%eax + movl %esi,%ecx + andl 168(%esp),%ecx + orl %ecx,%eax + movl %eax,72(%edi) + movl %edx,%eax + andl 76(%esp),%eax + movl %esi,%ecx + andl 172(%esp),%ecx + orl %ebp,%eax + orl %ecx,%eax + movl %eax,76(%edi) + movl %edx,%eax + andl 80(%esp),%eax + movl %esi,%ecx + andl 176(%esp),%ecx + orl %ebp,%eax + orl %ecx,%eax + movl %eax,80(%edi) + movl %edx,%eax + andl 84(%esp),%eax + movl %esi,%ecx + andl 180(%esp),%ecx + orl %ebp,%eax + orl %ecx,%eax + movl %eax,84(%edi) + movl %edx,%eax + andl 88(%esp),%eax + movl %ebp,%ebx + andl $-2,%ebx + movl %esi,%ecx + andl 184(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,88(%edi) + movl %edx,%eax + andl 92(%esp),%eax + movl %esi,%ecx + andl 188(%esp),%ecx + orl %ecx,%eax + movl %eax,92(%edi) + movl %edx,%eax + andl (%esp),%eax + movl %ebp,%ebx + andl 192(%esp),%ebx + movl %esi,%ecx + andl 96(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,(%edi) + movl %edx,%eax + andl 4(%esp),%eax + movl %ebp,%ebx + andl 196(%esp),%ebx + movl %esi,%ecx + andl 100(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,4(%edi) + movl %edx,%eax + andl 8(%esp),%eax + movl %ebp,%ebx + andl 200(%esp),%ebx + movl %esi,%ecx + andl 104(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,8(%edi) + movl %edx,%eax + andl 12(%esp),%eax + movl %ebp,%ebx + andl 204(%esp),%ebx + movl %esi,%ecx + andl 108(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,12(%edi) + movl %edx,%eax + andl 16(%esp),%eax + movl %ebp,%ebx + andl 208(%esp),%ebx + movl %esi,%ecx + andl 112(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,16(%edi) + movl %edx,%eax + andl 20(%esp),%eax + movl %ebp,%ebx + andl 212(%esp),%ebx + movl %esi,%ecx + andl 116(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,20(%edi) + movl %edx,%eax + andl 24(%esp),%eax + movl %ebp,%ebx + andl 216(%esp),%ebx + movl %esi,%ecx + andl 120(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,24(%edi) + movl %edx,%eax + andl 28(%esp),%eax + movl %ebp,%ebx + andl 220(%esp),%ebx + movl %esi,%ecx + andl 124(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,28(%edi) + movl %edx,%eax + andl 32(%esp),%eax + movl %ebp,%ebx + andl 224(%esp),%ebx + movl %esi,%ecx + andl 128(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,32(%edi) + movl %edx,%eax + andl 36(%esp),%eax + movl %ebp,%ebx + andl 228(%esp),%ebx + movl %esi,%ecx + andl 132(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,36(%edi) + movl %edx,%eax + andl 40(%esp),%eax + movl %ebp,%ebx + andl 232(%esp),%ebx + movl %esi,%ecx + andl 136(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,40(%edi) + movl %edx,%eax + andl 44(%esp),%eax + movl %ebp,%ebx + andl 236(%esp),%ebx + movl %esi,%ecx + andl 140(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,44(%edi) + movl %edx,%eax + andl 48(%esp),%eax + movl %ebp,%ebx + andl 240(%esp),%ebx + movl %esi,%ecx + andl 144(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,48(%edi) + movl %edx,%eax + andl 52(%esp),%eax + movl %ebp,%ebx + andl 244(%esp),%ebx + movl %esi,%ecx + andl 148(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,52(%edi) + movl %edx,%eax + andl 56(%esp),%eax + movl %ebp,%ebx + andl 248(%esp),%ebx + movl %esi,%ecx + andl 152(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,56(%edi) + movl %edx,%eax + andl 60(%esp),%eax + movl %ebp,%ebx + andl 252(%esp),%ebx + movl %esi,%ecx + andl 156(%esp),%ecx + orl %ebx,%eax + orl %ecx,%eax + movl %eax,60(%edi) + addl $492,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size ecp_nistz256_point_add_affine,.-.L_ecp_nistz256_point_add_affine_begin +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/ec/ecp_nistz256-x86_64.S b/crypto/openssl/crypto/ec/ecp_nistz256-x86_64.S new file mode 100644 index 000000000000..284c11748946 --- /dev/null +++ b/crypto/openssl/crypto/ec/ecp_nistz256-x86_64.S @@ -0,0 +1,7364 @@ +.text +.globl ecp_nistz256_precomputed +.type ecp_nistz256_precomputed,@object +.align 4096 +ecp_nistz256_precomputed: +.long 0x18a9143c,0x79e730d4,0x5fedb601,0x75ba95fc,0x77622510,0x79fb732b,0xa53755c6,0x18905f76,0xce95560a,0xddf25357,0xba19e45c,0x8b4ab8e4,0xdd21f325,0xd2e88688,0x25885d85,0x8571ff18 +.long 0x10ddd64d,0x850046d4,0xa433827d,0xaa6ae3c1,0x8d1490d9,0x73220503,0x3dcf3a3b,0xf6bb32e4,0x61bee1a5,0x2f3648d3,0xeb236ff8,0x152cd7cb,0x92042dbe,0x19a8fb0e,0x0a5b8a3b,0x78c57751 +.long 0x4eebc127,0xffac3f90,0x087d81fb,0xb027f84a,0x87cbbc98,0x66ad77dd,0xb6ff747e,0x26936a3f,0xc983a7eb,0xb04c5c1f,0x0861fe1a,0x583e47ad,0x1a2ee98e,0x78820831,0xe587cc07,0xd5f06a29 +.long 0x46918dcc,0x74b0b50d,0xc623c173,0x4650a6ed,0xe8100af2,0x0cdaacac,0x41b0176b,0x577362f5,0xe4cbaba6,0x2d96f24c,0xfad6f447,0x17628471,0xe5ddd22e,0x6b6c36de,0x4c5ab863,0x84b14c39 +.long 0xc45c61f5,0xbe1b8aae,0x94b9537d,0x90ec649a,0xd076c20c,0x941cb5aa,0x890523c8,0xc9079605,0xe7ba4f10,0xeb309b4a,0xe5eb882b,0x73c568ef,0x7e7a1f68,0x3540a987,0x2dd1e916,0x73a076bb +.long 0x3e77664a,0x40394737,0x346cee3e,0x55ae744f,0x5b17a3ad,0xd50a961a,0x54213673,0x13074b59,0xd377e44b,0x93d36220,0xadff14b5,0x299c2b53,0xef639f11,0xf424d44c,0x4a07f75f,0xa4c9916d +.long 0xa0173b4f,0x0746354e,0xd23c00f7,0x2bd20213,0x0c23bb08,0xf43eaab5,0xc3123e03,0x13ba5119,0x3f5b9d4d,0x2847d030,0x5da67bdd,0x6742f2f2,0x77c94195,0xef933bdc,0x6e240867,0xeaedd915 +.long 0x9499a78f,0x27f14cd1,0x6f9b3455,0x462ab5c5,0xf02cfc6b,0x8f90f02a,0xb265230d,0xb763891e,0x532d4977,0xf59da3a9,0xcf9eba15,0x21e3327d,0xbe60bbf0,0x123c7b84,0x7706df76,0x56ec12f2 +.long 0x264e20e8,0x75c96e8f,0x59a7a841,0xabe6bfed,0x44c8eb00,0x2cc09c04,0xf0c4e16b,0xe05b3080,0xa45f3314,0x1eb7777a,0xce5d45e3,0x56af7bed,0x88b12f1a,0x2b6e019a,0xfd835f9b,0x086659cd +.long 0x9dc21ec8,0x2c18dbd1,0x0fcf8139,0x98f9868a,0x48250b49,0x737d2cd6,0x24b3428f,0xcc61c947,0x80dd9e76,0x0c2b4078,0x383fbe08,0xc43a8991,0x779be5d2,0x5f7d2d65,0xeb3b4ab5,0x78719a54 +.long 0x6245e404,0xea7d260a,0x6e7fdfe0,0x9de40795,0x8dac1ab5,0x1ff3a415,0x649c9073,0x3e7090f1,0x2b944e88,0x1a768561,0xe57f61c8,0x250f939e,0x1ead643d,0x0c0daa89,0xe125b88e,0x68930023 +.long 0xd2697768,0x04b71aa7,0xca345a33,0xabdedef5,0xee37385e,0x2409d29d,0xcb83e156,0x4ee1df77,0x1cbb5b43,0x0cac12d9,0xca895637,0x170ed2f6,0x8ade6d66,0x28228cfa,0x53238aca,0x7ff57c95 +.long 0x4b2ed709,0xccc42563,0x856fd30d,0x0e356769,0x559e9811,0xbcbcd43f,0x5395b759,0x738477ac,0xc00ee17f,0x35752b90,0x742ed2e3,0x68748390,0xbd1f5bc1,0x7cd06422,0xc9e7b797,0xfbc08769 +.long 0xb0cf664a,0xa242a35b,0x7f9707e3,0x126e48f7,0xc6832660,0x1717bf54,0xfd12c72e,0xfaae7332,0x995d586b,0x27b52db7,0x832237c2,0xbe29569e,0x2a65e7db,0xe8e4193e,0x2eaa1bbb,0x152706dc +.long 0xbc60055b,0x72bcd8b7,0x56e27e4b,0x03cc23ee,0xe4819370,0xee337424,0x0ad3da09,0xe2aa0e43,0x6383c45d,0x40b8524f,0x42a41b25,0xd7663554,0x778a4797,0x64efa6de,0x7079adf4,0x2042170a +.long 0x0bc6fb80,0x808b0b65,0x3ffe2e6b,0x5882e075,0x2c83f549,0xd5ef2f7c,0x9103b723,0x54d63c80,0x52a23f9b,0xf2f11bd6,0x4b0b6587,0x3670c319,0xb1580e9e,0x55c4623b,0x01efe220,0x64edf7b2 +.long 0xd53c5c9d,0x97091dcb,0xac0a177b,0xf17624b6,0x2cfe2dff,0xb0f13975,0x6c7a574e,0xc1a35c0a,0x93e79987,0x227d3146,0xe89cb80e,0x0575bf30,0x0d1883bb,0x2f4e247f,0x3274c3d0,0xebd51226 +.long 0x56ada97a,0x5f3e51c8,0x8f8b403e,0x4afc964d,0x412e2979,0xa6f247ab,0x6f80ebda,0x675abd1b,0x5e485a1d,0x66a2bd72,0x8f4f0b3c,0x4b2a5caf,0x1b847bba,0x2626927f,0x0502394d,0x6c6fc7d9 +.long 0xa5659ae8,0xfea912ba,0x25e1a16e,0x68363aba,0x752c41ac,0xb8842277,0x2897c3fc,0xfe545c28,0xdc4c696b,0x2d36e9e7,0xfba977c5,0x5806244a,0xe39508c1,0x85665e9b,0x6d12597b,0xf720ee25 +.long 0xd2337a31,0x8a979129,0x0f862bdc,0x5916868f,0x5dd283ba,0x048099d9,0xfe5bfb4e,0xe2d1eeb6,0x7884005d,0x82ef1c41,0xffffcbae,0xa2d4ec17,0x8aa95e66,0x9161c53f,0xc5fee0d0,0x5ee104e1 +.long 0xc135b208,0x562e4cec,0x4783f47d,0x74e1b265,0x5a3f3b30,0x6d2a506c,0xc16762fc,0xecead9f4,0xe286e5b9,0xf29dd4b2,0x83bb3c61,0x1b0fadc0,0x7fac29a4,0x7a75023e,0xc9477fa3,0xc086d5f1 +.long 0x2f6f3076,0x0fc61135,0xe3912a9a,0xc99ffa23,0xd2f8ba3d,0x6a0b0685,0xe93358a4,0xfdc777e8,0x35415f04,0x94a787bb,0x4d23fea4,0x640c2d6a,0x153a35b5,0x9de917da,0x5d5cd074,0x793e8d07 +.long 0x2de45068,0xf4f87653,0x9e2e1f6e,0x37c7a7e8,0xa3584069,0xd0825fa2,0x1727bf42,0xaf2cea7c,0x9e4785a9,0x0360a4fb,0x27299f4a,0xe5fda49c,0x71ac2f71,0x48068e13,0x9077666f,0x83d0687b +.long 0x15d02819,0x6d3883b2,0x40dd9a35,0x6d0d7550,0x1d2b469f,0x61d7cbf9,0x2efc3115,0xf97b232f,0xb24bcbc7,0xa551d750,0x88a1e356,0x11ea4949,0x93cb7501,0x7669f031,0xca737b8a,0x595dc55e +.long 0xd837879f,0xa4a319ac,0xed6b67b0,0x6fc1b49e,0x32f1f3af,0xe3959933,0x65432a2e,0x966742eb,0xb4966228,0x4b8dc9fe,0x43f43950,0x96cc6312,0xc9b731ee,0x12068859,0x56f79968,0x7b948dc3 +.long 0xed1f8008,0x61e4ad32,0xd8b17538,0xe6c9267a,0x857ff6fb,0x1ac7c5eb,0x55f2fb10,0x994baaa8,0x1d248018,0x84cf14e1,0x628ac508,0x5a39898b,0x5fa944f5,0x14fde97b,0xd12e5ac7,0xed178030 +.long 0x97e2feb4,0x042c2af4,0xaebf7313,0xd36a42d7,0x084ffdd7,0x49d2c9eb,0x2ef7c76a,0x9f8aa54b,0x09895e70,0x9200b7ba,0xddb7fb58,0x3bd0c66f,0x78eb4cbb,0x2d97d108,0xd84bde31,0x2d431068 +.long 0x172ccd1f,0x4b523eb7,0x30a6a892,0x7323cb28,0xcfe153eb,0x97082ec0,0xf2aadb97,0xe97f6b6a,0xd1a83da1,0x1d3d393e,0x804b2a68,0xa6a7f9c7,0x2d0cb71e,0x4a688b48,0x40585278,0xa9b4cc5f +.long 0xcb66e132,0x5e5db46a,0x0d925880,0xf1be963a,0x0317b9e2,0x944a7027,0x48603d48,0xe266f959,0x5c208899,0x98db6673,0xa2fb18a3,0x90472447,0x777c619f,0x8a966939,0x2a3be21b,0x3798142a +.long 0x3298b343,0xb4241cb1,0xb44f65a1,0xa3a14e49,0x3ac77acd,0xc5f4d6cd,0x52b6fc3c,0xd0288cb5,0x1c040abc,0xd5cc8c2f,0x06bf9b4a,0xb675511e,0x9b3aa441,0xd667da37,0x51601f72,0x460d45ce +.long 0x6755ff89,0xe2f73c69,0x473017e6,0xdd3cf7e7,0x3cf7600d,0x8ef5689d,0xb1fc87b4,0x948dc4f8,0x4ea53299,0xd9e9fe81,0x98eb6028,0x2d921ca2,0x0c9803fc,0xfaecedfd,0x4d7b4745,0xf38ae891 +.long 0xc5e3a3d8,0xd8c5fccf,0x4079dfbf,0xbefd904c,0xfead0197,0xbc6d6a58,0x695532a4,0x39227077,0xdbef42f5,0x09e23e6d,0x480a9908,0x7e449b64,0xad9a2e40,0x7b969c1a,0x9591c2a4,0x6231d792 +.long 0x0f664534,0x87151456,0x4b68f103,0x85ceae7c,0x65578ab9,0xac09c4ae,0xf044b10c,0x33ec6868,0x3a8ec1f1,0x6ac4832b,0x5847d5ef,0x5509d128,0x763f1574,0xf909604f,0xc32f63c4,0xb16c4303 +.long 0x7ca23cd3,0xb6ab2014,0xa391849d,0xcaa7a5c6,0x75678d94,0x5b0673a3,0xdd303e64,0xc982ddd4,0x5db6f971,0xfd7b000b,0x6f876f92,0xbba2cb1f,0x3c569426,0xc77332a3,0x570d74f8,0xa159100c +.long 0xdec67ef5,0xfd16847f,0x233e76b7,0x742ee464,0xefc2b4c8,0x0b8e4134,0x42a3e521,0xca640b86,0x8ceb6aa9,0x653a0190,0x547852d5,0x313c300c,0x6b237af7,0x24e4ab12,0x8bb47af8,0x2ba90162 +.long 0xa8219bb7,0x3d5e58d6,0x1b06c57f,0xc691d0bd,0xd257576e,0x0ae4cb10,0xd54a3dc3,0x3569656c,0x94cda03a,0xe5ebaebd,0x162bfe13,0x934e82d3,0xe251a0c6,0x450ac0ba,0xdd6da526,0x480b9e11 +.long 0x8cce08b5,0x00467bc5,0x7f178d55,0xb636458c,0xa677d806,0xc5748bae,0xdfa394eb,0x2763a387,0x7d3cebb6,0xa12b448a,0x6f20d850,0xe7adda3e,0x1558462c,0xf63ebce5,0x620088a8,0x58b36143 +.long 0x4d63c0ee,0x8a2cc3ca,0x0fe948ce,0x51233117,0x222ef33b,0x7463fd85,0x7c603d6c,0xadf0c7dc,0xfe7765e5,0x0ec32d3b,0xbf380409,0xccaab359,0x8e59319c,0xbdaa84d6,0x9c80c34d,0xd9a4c280 +.long 0xa059c142,0xa9d89488,0xff0b9346,0x6f5ae714,0x16fb3664,0x068f237d,0x363186ac,0x5853e4c4,0x63c52f98,0xe2d87d23,0x81828876,0x2ec4a766,0xe14e7b1c,0x47b864fa,0x69192408,0x0c0bc0e5 +.long 0xb82e9f3e,0xe4d7681d,0xdf25e13c,0x83200f0b,0x66f27280,0x8909984c,0x75f73227,0x462d7b00,0xf2651798,0xd90ba188,0x36ab1c34,0x74c6e18c,0x5ef54359,0xab256ea3,0xd1aa702f,0x03466612 +.long 0x2ed22e91,0x624d6049,0x6f072822,0x6fdfe0b5,0x39ce2271,0xeeca1115,0xdb01614f,0x98100a4f,0xa35c628f,0xb6b0daa2,0xc87e9a47,0xb6f94d2e,0x1d57d9ce,0xc6773259,0x03884a7b,0xf70bfeec +.long 0xed2bad01,0x5fb35ccf,0x1da6a5c7,0xa155cbe3,0x30a92f8f,0xc2e2594c,0x5bfafe43,0x649c89ce,0xe9ff257a,0xd158667d,0xf32c50ae,0x9b359611,0x906014cf,0x4b00b20b,0x89bc7d3d,0xf3a8cfe3 +.long 0x248a7d06,0x4ff23ffd,0x878873fa,0x80c5bfb4,0x05745981,0xb7d9ad90,0x3db01994,0x179c85db,0x61a6966c,0xba41b062,0xeadce5a8,0x4d82d052,0xa5e6a318,0x9e91cd3b,0x95b2dda0,0x47795f4f +.long 0xd55a897c,0xecfd7c1f,0xb29110fb,0x009194ab,0xe381d3b0,0x5f0e2046,0xa98dd291,0x5f3425f6,0x730d50da,0xbfa06687,0x4b083b7f,0x0423446c,0xd69d3417,0x397a247d,0x387ba42a,0xeb629f90 +.long 0xd5cd79bf,0x1ee426cc,0x946c6e18,0x0032940b,0x57477f58,0x1b1e8ae0,0x6d823278,0xe94f7d34,0x782ba21a,0xc747cb96,0xf72b33a5,0xc5254469,0xc7f80c81,0x772ef6de,0x2cd9e6b5,0xd73acbfe +.long 0x49ee90d9,0x4075b5b1,0xa06e9eba,0x785c339a,0xabf825e0,0xa1030d5b,0xa42931dc,0xcec684c3,0xc1586e63,0x42ab62c9,0x5ab43f2b,0x45431d66,0x55f7835d,0x57c8b2c0,0xc1b7f865,0x033da338 +.long 0xcaa76097,0x283c7513,0x36c83906,0x0a624fa9,0x715af2c7,0x6b20afec,0xeba78bfd,0x4b969974,0xd921d60e,0x220755cc,0x7baeca13,0x9b944e10,0x5ded93d4,0x04819d51,0x6dddfd27,0x9bbff86e +.long 0x77adc612,0x6b344130,0xbbd803a0,0xa7496529,0x6d8805bd,0x1a1baaa7,0x470343ad,0xc8403902,0x175adff1,0x39f59f66,0xb7d8c5b7,0x0b26d7fb,0x529d75e3,0xa875f5ce,0x41325cc2,0x85efc7e9 +.long 0x1ff6acd3,0x21950b42,0x53dc6909,0xffe70484,0x28766127,0xff4cd0b2,0x4fb7db2b,0xabdbe608,0x5e1109e8,0x837c9228,0xf4645b5a,0x26147d27,0xf7818ed8,0x4d78f592,0xf247fa36,0xd394077e +.long 0x488c171a,0x0fb9c2d0,0x13685278,0xa78bfbaa,0xd5b1fa6a,0xedfbe268,0x2b7eaba7,0x0dceb8db,0x9ae2b710,0xbf9e8089,0xa4449c96,0xefde7ae6,0xcc143a46,0x43b7716b,0xc3628c13,0xd7d34194 +.long 0x3b3f64c9,0x508cec1c,0x1e5edf3f,0xe20bc0ba,0x2f4318d4,0xda1deb85,0x5c3fa443,0xd20ebe0d,0x73241ea3,0x370b4ea7,0x5e1a5f65,0x61f1511c,0x82681c62,0x99a5e23d,0xa2f54c2d,0xd731e383 +.long 0x83445904,0x2692f36e,0xaf45f9c0,0x2e0ec469,0xc67528b7,0x905a3201,0xd0e5e542,0x88f77f34,0x5864687c,0xf67a8d29,0x22df3562,0x23b92eae,0x9bbec39e,0x5c27014b,0x9c0f0f8d,0x7ef2f226 +.long 0x546c4d8d,0x97359638,0x92f24679,0x5f9c3fc4,0xa8c8acd9,0x912e8bed,0x306634b0,0xec3a318d,0xc31cb264,0x80167f41,0x522113f2,0x3db82f6f,0xdcafe197,0xb155bcd2,0x43465283,0xfba1da59 +.long 0xb212cf53,0xa0425b8e,0xf8557c5f,0x4f2e512e,0x25c4d56c,0xc1286ff9,0xee26c851,0xbb8a0fea,0xe7d6107e,0xc28f70d2,0xe76265aa,0x7ee0c444,0x1d1936b1,0x3df277a4,0xea9595eb,0x1a556e3f +.long 0xe7305683,0x258bbbf9,0x07ef5be6,0x31eea5bf,0x46c814c1,0x0deb0e4a,0xa7b730dd,0x5cee8449,0xa0182bde,0xeab495c5,0x9e27a6b4,0xee759f87,0x80e518ca,0xc2cf6a68,0xf14cf3f4,0x25e8013f +.long 0x7e8d7a14,0x8fc44140,0x9556f36a,0xbb1ff3ca,0x14600044,0x6a844385,0x7451ae63,0xba3f0c4a,0x1f9af32a,0xdfcac25b,0xb1f2214b,0x01e0db86,0xa4b596ac,0x4e9a5bc2,0x026c2c08,0x83927681 +.long 0x7acaca28,0x3ec832e7,0xc7385b29,0x1bfeea57,0xfd1eaf38,0x068212e3,0x6acf8ccc,0xc1329830,0x2aac9e59,0xb909f2db,0xb661782a,0x5748060d,0xc79b7a01,0xc5ab2632,0x00017626,0xda44c6c6 +.long 0xa7ea82f0,0xf26c00e8,0xe4299aaf,0x99cac80d,0x7ed78be1,0xd66fe3b6,0x648d02cd,0x305f725f,0x623fb21b,0x33ed1bc4,0x7a6319ad,0xfa70533e,0xbe5ffb3e,0x17ab562d,0x56674741,0x06374994 +.long 0x5c46aa8e,0x69d44ed6,0xa8d063d1,0x2100d5d3,0xa2d17c36,0xcb9727ea,0x8add53b7,0x4c2bab1b,0x15426704,0xa084e90c,0xa837ebea,0x778afcd3,0x7ce477f8,0x6651f701,0x46fb7a8b,0xa0624998 +.long 0xed8a6e19,0xdc1e6828,0x4189d9c7,0x33fc2336,0x671c39bc,0x026f8fe2,0xbc6f9915,0xd40c4ccd,0xf80e75ca,0xafa135bb,0x22adff2c,0x12c651a0,0x4f51ad96,0xc40a04bd,0xbbe4e832,0x04820109 +.long 0x7f4c04cc,0x3667eb1a,0xa9404f84,0x59556621,0x7eceb50a,0x71cdf653,0x9b8335fa,0x994a44a6,0xdbeb9b69,0xd7faf819,0xeed4350d,0x473c5680,0xda44bba2,0xb6658466,0x872bdbf3,0x0d1bc780 +.long 0xa1962f91,0xe535f175,0xed58f5a7,0x6ed7e061,0x2089a233,0x177aa4c0,0xe539b413,0x0dbcb03a,0xbb32e38e,0xe3dc424e,0x6806701e,0x6472e5ef,0x814be9ee,0xdd47ff98,0x35ace009,0x6b60cfff +.long 0x9ff91fe5,0xb8d3d931,0xf0518eed,0x039c4800,0x9182cb26,0x95c37632,0x82fc568d,0x0763a434,0x383e76ba,0x707c04d5,0x824e8197,0xac98b930,0x91230de0,0x92bf7c8f,0x40959b70,0x90876a01 +.long 0x05968b80,0xdb6d96f3,0x089f73b9,0x380a0913,0xc2c61e01,0x7da70b83,0x569b38c7,0x95fb8394,0x80edfe2f,0x9a3c6512,0x8faeaf82,0x8f726bb9,0x78424bf8,0x8010a4a0,0x0e844970,0x29672044 +.long 0x7a2ad62a,0x63c5cb81,0xac62ff54,0x7ef2b6b9,0xb3ad9db5,0x3749bba4,0x46d5a617,0xad311f2c,0xc2ff3b6d,0xb77a8087,0x367834ff,0xb46feaf3,0x75d6b138,0xf8aa266d,0xec008188,0xfa38d320 +.long 0x696946fc,0x486d8ffa,0xb9cba56d,0x50fbc6d8,0x90f35a15,0x7e3d423e,0xc0dd962c,0x7c3da195,0x3cfd5d8b,0xe673fdb0,0x889dfca5,0x0704b7c2,0xf52305aa,0xf6ce581f,0x914d5e53,0x399d49eb +.long 0x6ec293cd,0x380a496d,0x8e7051f5,0x733dbda7,0xb849140a,0x037e388d,0x5946dbf6,0xee4b32b0,0xcae368d1,0xb1c4fda9,0xfdb0b2f3,0x5001a7b0,0x2e3ac46e,0x6df59374,0x39b3e656,0x4af675f2 +.long 0x39949296,0x44e38110,0x361db1b5,0x5b63827b,0x206eaff5,0x3e5323ed,0xc21f4290,0x942370d2,0xe0d985a1,0xf2caaf2e,0x7239846d,0x192cc64b,0xae6312f8,0x7c0b8f47,0x96620108,0x7dc61f91 +.long 0xc2da7de9,0xb830fb5b,0x0ff8d3be,0xd0e643df,0x188a9641,0x31ee77ba,0xbcf6d502,0x4e8aa3aa,0x9a49110f,0xf9fb6532,0x2dd6b220,0xd18317f6,0x52c3ea5a,0x7e3ced41,0x7d579c4a,0x0d296a14 +.long 0xed4c3717,0x35d6a53e,0x3d0ed2a3,0x9f8240cf,0xe5543aa5,0x8c0d4d05,0xdd33b4b4,0x45d5bbfb,0x137fd28e,0xfa04cc73,0xc73b3ffd,0x862ac6ef,0x31f51ef2,0x403ff9f5,0xbc73f5a2,0x34d5e0fc +.long 0x08913f4f,0xf2526820,0xeac93d95,0xea20ed61,0x6ca6b26c,0x51ed38b4,0xea4327b0,0x8662dcbc,0x725d2aaa,0x6daf295c,0x8e52dcda,0xbad2752f,0x0b17dacc,0x2210e721,0xd51e8232,0xa37f7912 +.long 0x44cc3add,0x4f7081e1,0x87be82cf,0xd5ffa1d6,0x0edd6472,0x89890b6c,0x3ed17863,0xada26e1a,0x63483caa,0x276f2715,0x2f6077fd,0xe6924cd9,0x0a466e3c,0x05a7fe98,0xb1902d1f,0xf1c794b0 +.long 0x82a8042c,0xe5213688,0xcd278298,0xd931cfaf,0xf597a740,0x069a0ae0,0xeb59107c,0x0adbb3f3,0x5eaa8eb8,0x983e951e,0x11b48e78,0xe663a8b5,0x8a03f2c5,0x1631cc0d,0x11e271e2,0x7577c11e +.long 0x08369a90,0x33b2385c,0x190eb4f8,0x2990c59b,0xc68eac80,0x819a6145,0x2ec4a014,0x7a786d62,0x20ac3a8d,0x33faadbe,0x5aba2d30,0x31a21781,0xdba4f565,0x209d2742,0x55aa0fbb,0xdb2ce9e3 +.long 0x168984df,0x8cef334b,0x33879638,0xe81dce17,0x263720f0,0xf6e6949c,0xf593cbec,0x5c56feaf,0xfde58c84,0x8bff5601,0x2eccb314,0x74e24117,0x4c9a8a78,0xbcf01b61,0x544c9868,0xa233e35e +.long 0x8bd7aff1,0xb3156bf3,0x1d81b146,0x1b5ee4cb,0xd628a915,0x7ba1ac41,0xfd89699e,0x8f3a8f9c,0xa0748be7,0x7329b9c9,0xa92e621f,0x1d391c95,0x4d10a837,0xe51e6b21,0x4947b435,0xd255f53a +.long 0xf1788ee3,0x07669e04,0xa86938a2,0xc14f27af,0xe93a01c0,0x8b47a334,0xd9366808,0xff627438,0xca2a5965,0x7a0985d8,0xd6e9b9b3,0x3d9a5542,0x4cf972e8,0xc23eb80b,0x4fdf72fd,0x5c1c33bb +.long 0x74a86108,0x0c4a58d4,0xee4c5d90,0xf8048a8f,0xe86d4c80,0xe3c7c924,0x056a1e60,0x28c889de,0xb214a040,0x57e2662e,0x37e10347,0xe8c48e98,0x80ac748a,0x87742862,0x186b06f2,0xf1c24022 +.long 0x5f74040a,0xac2dd4c3,0xfceac957,0x409aeb71,0x55c4ec23,0x4fbad782,0x8a7b76ec,0xb359ed61,0xed6f4a60,0x12744926,0x4b912de3,0xe21e8d7f,0xfc705a59,0xe2575a59,0xed2dbc0e,0x72f1d4de +.long 0xeb7926b8,0x3d2b24b9,0xcdbe5509,0xbff88cb3,0xe4dd640b,0xd0f399af,0x2f76ed45,0x3c5fe130,0x3764fb3d,0x6f3562f4,0x3151b62d,0x7b5af318,0xd79ce5f3,0xd5bd0bc7,0xec66890f,0xfdaf6b20 +.long 0x6063540c,0x735c67ec,0xe5f9cb8f,0x50b259c2,0x3f99c6ab,0xb8734f9a,0xa3a7bc85,0xf8cc13d5,0xc5217659,0x80c1b305,0x4ec12a54,0xfe5364d4,0x681345fe,0xbd87045e,0x582f897f,0x7f8efeb1 +.long 0xd5923359,0xe8cbf1e5,0x539b9fb0,0xdb0cea9d,0x49859b98,0x0c5b34cf,0xa4403cc6,0x5e583c56,0xd48185b7,0x11fc1a2d,0x6e521787,0xc93fbc7e,0x05105b8b,0x47e7a058,0xdb8260c8,0x7b4d4d58 +.long 0x46eb842a,0xe33930b0,0x7bdae56d,0x8e844a9a,0x13f7fdfc,0x34ef3a9e,0x636ca176,0xb3768f82,0x4e09e61c,0x2821f4e0,0xa0c7cddc,0x414dc3a1,0x54945fcd,0xd5379437,0xb3555ff1,0x151b6eef +.long 0x6339c083,0xb31bd613,0xdfb64701,0x39ff8155,0xe29604ab,0x7c3388d2,0xa6b10442,0x1e19084b,0xeccd47ef,0x17cf54c0,0x4a5dfb30,0x89693385,0x47daf9f6,0x69d023fb,0x7d91d959,0x9222840b +.long 0x803bac62,0x439108f5,0x379bd45f,0x0b7dd91d,0xca63c581,0xd651e827,0x509c104f,0x5c5d75f6,0x1f2dc308,0x7d5fc738,0xd98454be,0x20faa7bf,0xa517b031,0x95374bee,0x642692ac,0xf036b9b1 +.long 0x39842194,0xc5106109,0x49d05295,0xb7e2353e,0xefb42ee0,0xfc8c1d5c,0x08ce811c,0xe04884eb,0x7419f40e,0xf1f75d81,0xa995c241,0x5b0ac162,0xc4c55646,0x120921bb,0x8d33cf97,0x713520c2 +.long 0xe98c5100,0xb4a65a5c,0x2ddd0f5a,0x6cec871d,0x9ba2e78b,0x251f0b7f,0xce3a2a5f,0x224a8434,0x25f5c46f,0x26827f61,0x48545ec0,0x6a22bedc,0xb1bb5cdc,0x25ae5fa0,0xfcb9b98f,0xd693682f +.long 0x91e5d7d3,0x32027fe8,0x73a07678,0xf14b7d17,0xc0dfdd61,0xf88497b3,0x2a8c4f48,0xf7c2eec0,0x3756e621,0xaa5573f4,0x1825b948,0xc013a240,0x63878572,0x1c03b345,0x653a4184,0xa0472bea +.long 0x0ac69a80,0xf4222e27,0xf51e54f6,0x34096d25,0x8fffa591,0x00a648cb,0x69b6527f,0x4e87acdc,0xe285ccb4,0x0575e037,0x50ddcf52,0x188089e4,0x870ff719,0xaa96c9a8,0x1fc7e369,0x74a56cd8 +.long 0x1726931a,0x41d04ee2,0x3660ecfd,0x0bbbb2c8,0x24818e18,0xa6ef6de5,0xe7d57887,0xe421cc51,0xbea87be6,0xf127d208,0xb1cdd682,0x16a475d3,0x439b63f7,0x9db1b684,0xf0f113b6,0x5359b3db +.long 0x8bf06e31,0xdfccf1de,0xdd383901,0x1fdf8f44,0x5017e7d2,0x10775cad,0x58d11eef,0xdfc3a597,0xb1ecff10,0x6ec9c8a0,0x28400549,0xee6ed6cc,0x1b4f8d73,0xb5ad7bae,0xe00aaab9,0x61b4f11d +.long 0xd4eff2d7,0x7b32d69b,0x4288b60f,0x88ae6771,0x37a1e723,0x159461b4,0x570aae8c,0x1f3d4789,0x7f9871da,0x869118c0,0xf635e278,0x35fbda78,0xe1541dac,0x738f3641,0xc0dae45f,0x6794b13a +.long 0x09cc0917,0x065064ac,0xc68540fd,0x27c53729,0xef227671,0x0d2d4c8e,0xa1785a04,0xd23a9f80,0x52650359,0x98c59528,0x74a1acad,0xfa09ad01,0x0b55bf5c,0x082d5a29,0x419b8084,0xa40f1c67 +.long 0xdcc18770,0x3a5c752e,0x8825c3a5,0x4baf1f2f,0x21b153ed,0xebd63f74,0xb2f64723,0xa2383e47,0x2646d19a,0xe7bf620a,0x03c83ffd,0x56cb44ec,0x4f6be9f1,0xaf7267c9,0xc06bb5e9,0x8b2dfd7b +.long 0xa672c5c7,0xb87072f2,0x0d53c5e2,0xeacb11c8,0xff435932,0x22dac29d,0x4408693c,0x37bdb99d,0x2899c20f,0xf6e62fb6,0x447ece24,0x3535d512,0xff577ce3,0xfbdc6b88,0x190575f2,0x726693bd +.long 0xab4b35a2,0x6772b0e5,0xf5eeaacf,0x1d8b6001,0x795b9580,0x728f7ce4,0x41fb81da,0x4a20ed2a,0x4fec01e6,0x9f685cd4,0xa7ff50ad,0x3ed7ddcc,0x0c2d97fd,0x460fd264,0xeb82f4f9,0x3a241426 +.long 0x6a8ea820,0x17d1df2c,0xf22cc254,0xb2b50d3b,0xb7291426,0x03856cba,0x04f5ee39,0x87fd26ae,0x02bee4ba,0x9cb696cc,0x06820fd6,0x53121804,0x0212e985,0xa5dfc269,0x160f9a09,0x666f7ffa +.long 0xbccd9617,0xc503cd33,0xba7730a3,0x365dede4,0x5ddb0786,0x798c6355,0xfc9cd3bc,0xa6c3200e,0xe5e35efd,0x060ffb2c,0x5555a1c1,0x99a4e25b,0xf70b3751,0x11d95375,0x160e1bf6,0x0a57354a +.long 0xf8e4b065,0xecb3ae4b,0x2e53022b,0x07a834c4,0x8692ed96,0x1cd300b3,0x61ee14ec,0x16a6f792,0x6a8649ed,0x8f1063c6,0x869f3e14,0xfbcdfcfe,0x00a7b3ec,0x2cfb97c1,0x7130c2f1,0xcea49b3c +.long 0xe9d96488,0x462d044f,0x8182a0c1,0x4b53d52e,0x0391e9e9,0x84b6ddd3,0xb1741a09,0x80ab7b48,0x27d3317f,0xec0e15d4,0x1a64671e,0x8dfc1ddb,0xd49c5b92,0x93cc5d5f,0x3674a331,0xc995d53d +.long 0x090090ae,0x302e41ec,0xedb06830,0x2278a0cc,0xfbc99690,0x1d025932,0xb80d68da,0x0c32fbd2,0xf341a6c1,0xd79146da,0x1bef68a0,0xae0ba139,0x8d774b3a,0xc6b8a563,0x880ba4d7,0x1cf307bd +.long 0x19803511,0xc033bdc7,0x8888c3be,0xa9f97b3b,0x85c6d05e,0x3d68aebc,0x193919eb,0xc3b88a9d,0xc48b0ee3,0x2d300748,0x07a746c1,0x7506bc7c,0x6e6d57f3,0xfc48437c,0xcfeaa91a,0x5bd71587 +.long 0xc1bc5225,0xa4ed0408,0x2719226d,0xd0b946db,0x758d2d43,0x109ecd62,0x2751759b,0x75c8485a,0x9ce4177a,0xb0b75f49,0x79c10c3d,0x4fa61a1e,0xa167fcd7,0xc062d300,0x750f0fa8,0x4df3874c +.long 0x83dfedc9,0x29ae2cf9,0x8d87631a,0xf8437134,0x7429c8d2,0xaf571711,0x146d9272,0x18d15867,0x69769bb7,0x83053ecf,0xc479ab82,0xc55eb856,0x21b0f4b2,0x5ef7791c,0x3d491525,0xaa5956ba +.long 0x9fe20eba,0x407a96c2,0xe52a5ad3,0xf27168bb,0xbf1d9d89,0x43b60ab3,0x710e727a,0xe45c51ef,0x099b4221,0xdfca5276,0x2557a159,0x8dc6407c,0x91035895,0x0ead8335,0x9c55dc32,0x0a9db957 +.long 0xdf61bc76,0xe40736d3,0x3f778cdb,0x13a619c0,0xc56ea28f,0x6dd921a4,0x2fa647b4,0x76a52433,0xac5bdc5d,0x23591891,0xbac7dc01,0xff4a1a72,0x62df8453,0x9905e261,0xe63b265f,0x3ac045df +.long 0xad53dba7,0x8a3f341b,0x837b625a,0x8ec269cc,0x3ae31189,0xd71a2782,0x55e96120,0x8fb4f9a3,0xff9875cf,0x804af823,0x5d442a9b,0x23224f57,0xecc62679,0x1c4d3b9e,0xa0e7ddb1,0x91da22fb +.long 0x6c04a661,0xa370324d,0x5e376d17,0x9710d3b6,0x3044e357,0xed8c98f0,0x6422701c,0xc364ebbe,0x7733d61c,0x347f5d51,0xcea826c3,0xd55644b9,0x55a25548,0x80c6e0ad,0x844220a7,0x0aa7641d +.long 0x31810660,0x1438ec81,0xde4b4043,0x9dfa6507,0xcc3e0273,0x10b515d8,0x28d8cfb2,0x1b6066dd,0x9c9efebd,0xd3b04591,0xa21c1ff4,0x425d4bdf,0xd57607d3,0x5fe5af19,0x54481084,0xbbf773f7 +.long 0x94b03ed1,0x8435bd69,0x634cc546,0xd9ad1de3,0x00e420ca,0x2cf423fc,0xa03096dd,0xeed26d80,0xa4db09d2,0xd7f60be7,0x960622f7,0xf47f569d,0x7296c729,0xe5925fd7,0x26ca2715,0xeff2db26 +.long 0xb913e759,0xa6fcd014,0x8ff4de93,0x53da4786,0xc32068e1,0x14616d79,0xccdf352e,0xb187d664,0x1dc90b59,0xf7afb650,0x7daa1b26,0x8170e943,0x700c0a84,0xc8e3bdd8,0x6482bdfa,0x6e8d345f +.long 0xc5c5ea50,0x84cfbfa1,0x67960681,0xd3baf14c,0x0dd50942,0x26398403,0x4716a663,0xe4b7839c,0xe7de6dc0,0xd5f1f794,0x622aa7ce,0x5cd0f4d4,0x59acfeec,0x5295f3f1,0x953e0607,0x8d933552 +.long 0x776c5722,0xc7db8ec5,0x2b5f290c,0xdc467e62,0x4ff425a9,0xd4297e70,0x0cf7bb72,0x4be924c1,0xa1892131,0x0d5dc5ae,0xa705c992,0x8bf8a8e3,0x7a305ac5,0x73a0b064,0x9a8c77a8,0x00c9ca4e +.long 0x83774bdd,0x5dfee80f,0x85734485,0x63131602,0x914a69a9,0xa1b524ae,0xd4e300d7,0xebc2ffaf,0x7cfa46a5,0x52c93db7,0x21653b50,0x71e6161f,0xa4bc580a,0x3574fc57,0xe1bc1253,0xc09015dd +.long 0xd174d7aa,0x4b7b47b2,0xf3a15d04,0x4072d8e8,0xd6fa07ed,0xeeb7d47f,0xedbdafb1,0x6f2b9ff9,0x3760fe8a,0x18c51615,0xf06c6c13,0x7a96e6bf,0x0ea2d071,0x4d7a0410,0x0be2a5ce,0xa1914e9b +.long 0xd8a3c5cf,0x5726e357,0x2abb2b13,0x1197ecc3,0x31ae88dd,0x6c0d7f7f,0xfdbb3efe,0x15b20d1a,0x70584039,0xcd06aa26,0xa7dc9747,0x2277c969,0x7855d815,0xbca69587,0x5188b32a,0x899ea238 +.long 0x760c1c9d,0x37d9228b,0x9b5c18da,0xc7efbb11,0x19f6dbc5,0x7f0d1bc8,0x07e6905b,0x4875384b,0x3ba8cd86,0xc7c50baa,0xc2905de0,0xb0ce40fb,0x7a231952,0x70840673,0xcf43de26,0xa912a262 +.long 0xeb5b76c1,0x9c38ddcc,0x26fc0ab4,0x746f5285,0xd62c269f,0x52a63a50,0x99458621,0x60049c55,0x3c2f7c9e,0xe7f48f82,0x917d5cf3,0x6bd99043,0x8701f469,0xeb1317a8,0x9a449fe0,0xbd3fe2ed +.long 0x12ef3d36,0x421e79ca,0x3e7ea5de,0x9ee3c36c,0xcdff36f7,0xe48198b5,0xc6b82228,0xaff4f967,0xc47adb7e,0x15e19dd0,0x032e7dfa,0x45699b23,0x1fae026a,0x40680c8b,0x550dbf4d,0x5a347a48 +.long 0x3cef0d7d,0xe652533b,0x2bbb4381,0xd94f7b18,0x0e80f500,0x838752be,0x9e9c9bfb,0x8e6e2488,0x16caca6a,0xc9751697,0x38531ad9,0x866c49d8,0x7151ade1,0xc917e239,0x6037c407,0x2d016ec1 +.long 0x00eac3f9,0xa407ccc9,0xe2ed4748,0x835f6280,0x1cc98e0d,0xcc54c347,0xdcb572eb,0x0e969937,0x8f30c9cb,0x1b16c8e8,0x373c4661,0xa606ae75,0x35502cab,0x47aa689b,0x4d9bb64f,0xf89014ae +.long 0x31c71f7b,0x202f6a9c,0x296ffe5c,0x01f95aa3,0x53cec3a3,0x5fc06014,0x5f498a45,0xeb991237,0x5d91ba87,0xae9a935e,0x0b564a19,0xc6ac6281,0x3bd44e69,0x8a8fe81c,0x9dd11d45,0x7c8b467f +.long 0xea5b8e69,0xf772251f,0xc5b75fbc,0xaeecb3bd,0x887ff0e5,0x1aca3331,0x19f0a131,0xbe5d49ff,0xe5c8646f,0x582c13aa,0x20e19980,0xdbaa12e8,0xf7abbd94,0x8f40f31a,0x1dfc7663,0x1f13f5a8 +.long 0xaceb4fc0,0x5d81f1ee,0x5e6f0f42,0x36256002,0x751370c8,0x4b67d6d7,0x03e80589,0x2608b698,0x05268301,0xcfc0d2fc,0x40309212,0xa6943d39,0x1fd0e1c2,0x192a90c2,0x37f1dc76,0xb209f113 +.long 0x97bf1298,0xefcc5e06,0x219d639e,0xcbdb6730,0xb81e8c6f,0xd009c116,0x1a7ce2e5,0xa3ffdde3,0xa914d3ba,0xc53fbaaa,0x88df85ee,0x836d500f,0x66ee0751,0xd98dc71b,0x714516fd,0x5a3d7005 +.long 0x39eedbba,0x21d3634d,0x0455a46d,0x35cd2e68,0xf9d7eb0c,0xc8cafe65,0x00cefb3e,0xbda3ce9e,0x2c9cf7a4,0xddc17a60,0x7bcb8773,0x01572ee4,0x8c7548df,0xa92b2b01,0xa84600e3,0x732fd309 +.long 0x16543a40,0xe22109c7,0xfede3c6c,0x9acafd36,0x6824e614,0xfb206852,0xda25dca0,0x2a4544a9,0x91d60b06,0x25985262,0x28753545,0x281b7be9,0x90f13b27,0xec667b1a,0x940e2eb4,0x33a83aff +.long 0xd5d721d5,0x80009862,0x5bd3a182,0x0c3357a3,0x7aa2cda4,0x27f3a83b,0xf6f83085,0xb58ae74e,0x2e6dad6b,0x2a911a81,0xf43d6c5b,0xde286051,0xf996c4d8,0x4bdccc41,0x0ae1e24e,0xe7312ec0 +.long 0x6e6485b3,0xf8d112e7,0x771c52f8,0x4d3e24db,0x684a2f6d,0x48e3ee41,0x21d95551,0x7161957d,0xcdb12a6c,0x19631283,0x2e50e164,0xbf3fa882,0x3166cc73,0xf6254b63,0xaee8cc38,0x3aefa7ae +.long 0x3b36f9fd,0x79b0fe62,0xfde19fc0,0x26543b23,0x958482ef,0x136e64a0,0x9b095825,0x23f63771,0xb6a1142e,0x14cfd596,0x335aac0b,0x5ea6aac6,0xf3081dd5,0x86a0e8bd,0x003dc12a,0x5fb89d79 +.long 0xf72e34d4,0xf615c33a,0x110eec35,0x0bd9ea40,0xc1dea34e,0x1c12bc5b,0x49ae4699,0x686584c9,0x8c97b942,0x13ad95d3,0x4e5c7562,0x4609561a,0xf2737f89,0x9e94a4ae,0x371c78b6,0xf57594c6 +.long 0xe3779ee3,0x0f0165fc,0xbd495d9e,0xe00e7f9d,0x20284e7a,0x1fa4efa2,0x47ac6219,0x4564bade,0xc4708e8e,0x90e6312a,0xa71e9adf,0x4f5725fb,0x3d684b9f,0xe95f55ae,0x1e94b415,0x47f7ccb1 +.long 0x8d946581,0x7322851b,0xbdf4a012,0xf0d13133,0x6584dae0,0xa3510f69,0x3c9f6c6d,0x03a7c171,0xe475381a,0x5be97f38,0x85823334,0xca1ba422,0x0be17dda,0xf83cc5c7,0x0b918c0f,0x158b1494 +.long 0x522e6b69,0xda3a77e5,0xbbcd6c18,0x69c908c3,0xd924fd56,0x1f1b9e48,0xaa4bb3f7,0x37c64e36,0xee478d7d,0x5a4fdbdf,0x0193f7a0,0xba75c8bc,0x56cd16df,0x84bc1e84,0x46fad151,0x1fb08f08 +.long 0x842e9f30,0x8a7cabf9,0x5eab83af,0xa331d4bf,0x017f2a6a,0xd272cfba,0x83aba0e3,0x27560abc,0x0e3a6b75,0x94b83387,0x6b9f50f5,0x25c6aea2,0xb5fdf6d0,0x803d691d,0xe6333514,0x03b77509 +.long 0x61a341c1,0x36178903,0x0cfd6142,0x3604dc60,0x8533316c,0x022295eb,0x44af2922,0x3dbde4ac,0x1c7eef69,0x898afc5d,0xd14f4fa1,0x58896805,0x203c21ca,0x05002160,0x40ef730b,0x6f0d1f30 +.long 0x196224f8,0x8e8c44d4,0x374d079d,0x75a4ab95,0x7d48f123,0x79085ecc,0x1bf65ad8,0x56f04d31,0xbda602b2,0xe220bf1c,0xf9612c69,0x73ee1742,0x084fd06b,0x76008fc8,0xf11380d1,0x4000ef9f +.long 0x12cfe297,0x48201b4b,0x292f74e5,0x3eee129c,0xc9e874e8,0xe1fe114e,0x92c5fc41,0x899b055c,0x3a39c8cf,0x4e477a64,0x78963cc9,0x82f09efe,0xd333f863,0x6fd3fd8f,0xdc949c63,0x85132b2a +.long 0x516eb17b,0x7e06a3ab,0xd2c7372b,0x73bec06f,0xba896da6,0xe4f74f55,0x8e9eb40f,0xbb4afef8,0xe61d66b0,0x2d75bec8,0xef29300b,0x02bda4b4,0x026baa5a,0x8bbaa8de,0xa07f4440,0xff54befd +.long 0xbe7a2af3,0xbd9b8b1d,0x4fb74a72,0xec51caa9,0x63879697,0xb9937a4b,0xec2687d5,0x7c9a9d20,0x6ef5f014,0x1773e44f,0xe90c6900,0x8abcf412,0x8142161e,0x387bd022,0xfcb6ff2a,0x50393755 +.long 0xed6def63,0x9813fd56,0x7d53106c,0x53cf6482,0x431f7ac1,0x991a35bd,0x63e65faf,0xf1e274dd,0x44cc7880,0xf63ffa3c,0x7c256981,0x411a426b,0x93a420e0,0xb698b9fd,0xae53f8fe,0x89fdddc0 +.long 0x32398baa,0x766e0722,0x5cfca031,0x205fee42,0x7a029cf2,0xa49f5341,0x4023890d,0xa88c68b8,0x7337aaa8,0xbc275041,0x0eb384f4,0x9ed364ad,0x29aba92f,0xe0816f85,0x04e38a88,0x2e9e1941 +.long 0x3dafd2d5,0x57eef44a,0x97ed98d8,0x35d1fae5,0x2307f9b1,0x50628c09,0xd6cba5c6,0x09d84aae,0x88aaa691,0x67071bc7,0xafe6cb03,0x2dea57a9,0x3d78ac01,0xdfe11bb4,0x7fd7aa51,0x7286418c +.long 0x77f7195a,0xfabf7709,0xadeb838f,0x8ec86167,0xbb4f012d,0xea1285a8,0x9a3eab3f,0xd6883503,0x309004c2,0xee5d24f8,0x13ffe95e,0xa96e4b76,0xbd223ea4,0x0cdffe12,0xb6739a53,0x8f5c2ee5 +.long 0xdd968198,0x5cb4aaa5,0x72413a6c,0xfa131c52,0x9536d903,0x53d46a90,0x48606d8e,0xb270f0d3,0xa053a3bc,0x518c7564,0x1a86caef,0x088254b7,0x0ab5efd0,0xb3ba8cb4,0x4605945d,0x5c59900e +.long 0xa1887395,0xecace1dd,0x932a65de,0x40960f36,0x3aa95529,0x9611ff5c,0x7c1e5a36,0xc58215b0,0xf0e1a524,0xd48c9b58,0xf590dfb8,0xb406856b,0x9cd95662,0xc7605e04,0xa33ecf82,0x0dd036ee +.long 0xc33156b3,0xa50171ac,0x4a80172e,0xf09d24ea,0x76dc8eef,0x4e1f72c6,0x5e3d44ee,0xe60caadc,0x979b1d8f,0x006ef8a6,0x97788d26,0x60908a1c,0x266feec0,0x6e08f95b,0x22e8c94e,0x618427c2 +.long 0x59145a65,0x3d613339,0xfa406337,0xcd9bc368,0x2d8a52a0,0x82d11be3,0x97a1c590,0xf6877b27,0xf5cbdb25,0x837a819b,0xde090249,0x2a4fd1d8,0x74990e5f,0x622a7de7,0x7945511b,0x840fa5a0 +.long 0x6558842d,0x30b974be,0x17f3d0a6,0x70df8c64,0x7542e46d,0x7c803520,0xe4ecc823,0x7251fe7f,0x5e9aac9a,0xe59134cb,0xf0045d71,0x11bb0934,0xdbcb1d4e,0x53e5d9b5,0x92defc91,0x8d97a905 +.long 0x7946d3f9,0xfe289327,0x07472273,0xe132bd24,0x1eb6ae86,0xeeeb510c,0xf0595067,0x777708c5,0x1297029e,0x18e2c8cd,0xbbf9305e,0x2c61095c,0x6b85d6d9,0xe466c258,0xda1ea530,0x8ac06c36 +.long 0xa1304668,0xa365dc39,0x07f89606,0xe4a9c885,0xacc7228d,0x65a4898f,0x84ca8303,0x3e2347ff,0xea7d23a3,0xa5f6fb77,0x672a71cd,0x2fac257d,0x7e6a44d3,0x6908bef8,0x891d3d7a,0x8ff87566 +.long 0x6b0cf82e,0xe58e90b3,0x2615b5e7,0x6438d246,0x669c145a,0x07b1f8fc,0x36f1e1cb,0xb0d8b2da,0xd9184c4d,0x54d5dadb,0xf93d9976,0x3dbb18d5,0xd1147d47,0x0a3e0f56,0xa0a48609,0x2afa8c8d +.long 0xbc36742c,0x275353e8,0xeea0ed90,0x898f427e,0x3e477b00,0x26f4947e,0x308741e3,0x8ad8848a,0xd74a2a46,0x6c703c38,0x9ba17ba2,0x5e3e05a9,0x4ab9a9e4,0xc1fa6f66,0x3841d6ec,0x474a2d9a +.long 0x653ae326,0x871239ad,0xa74cbb43,0x14bcf72a,0x20d4c083,0x8737650e,0x110ed4af,0x3df86536,0xb53ca555,0xd2d86fe7,0xabd5d538,0x688cb00d,0x1ad38468,0xcf81bda3,0xf01167b6,0x7ccfe3cc +.long 0x6c4c1fe6,0xcf4f47e0,0x298bbb79,0x557e1f1a,0x30d45a14,0xf93b974f,0x0baf97c4,0x174a1d2d,0xc51fbf53,0x7a003b30,0xee68b225,0xd8940991,0x1c0f4173,0x5b0aa7b7,0xa20a7153,0x975797c9 +.long 0xe3533d77,0x26e08c07,0x2e341c99,0xd7222e6a,0x8d2dc4ed,0x9d60ec3d,0x7c476cf8,0xbdfe0d8f,0x1d056605,0x1fe59ab6,0x86a8551f,0xa9ea9df6,0x47fb8d8c,0x8489941e,0x4a7f1b10,0xfeb874eb +.long 0x7ee0d98f,0xfe5fea86,0xdbf61864,0x201ad34b,0x37c031d4,0x45d8fe47,0x795f0822,0xd5f49fae,0xc7f4a40c,0xdb0fb291,0x730ddd92,0x2e69d9c1,0x49d76987,0x754e1054,0x7662db87,0x8a24911d +.long 0x60a71676,0x61fc1810,0xf66a8ad1,0xe852d1a8,0x6417231e,0x172bbd65,0x3babb11f,0x0d6de7bd,0xc8e347f8,0x6fde6f88,0x9bd99cc3,0x1c587547,0x34076950,0x78e54ed0,0x796e83ba,0x97f0f334 +.long 0x4924867a,0xe4dbe1ce,0x60b84917,0xbd5f51b0,0x3cb09a79,0x37530040,0xff1743d8,0xdb3fe0f8,0x556fa9db,0xed7894d8,0x23412fbf,0xfa262169,0xba7b9291,0x563be0db,0x0c9fb234,0x6ca8b8c0 +.long 0xbd763802,0xed406aa9,0x65303da1,0xc21486a0,0xc7e62ec4,0x61ae291e,0xdf99333e,0x622a0492,0xbb7a8ee0,0x7fd80c9d,0x6c01aedb,0xdc2ed3bc,0x08be74ec,0x35c35a12,0x469f671f,0xd540cb1a +.long 0xcf84f6c7,0xd16ced4e,0x2d090f43,0x8561fb9c,0x6f239db4,0x7e693d79,0x77bd0d94,0xa736f928,0x2c1950ee,0x07b4d929,0x56dc11b3,0xda177543,0x7a6a878e,0xa5dfbbaa,0x4decb08a,0x1c70cb29 +.long 0x6f0f7c50,0xfba28c8b,0x854dcc6d,0xa8eba2b8,0x36b78642,0x5ff8e89a,0xf6873adf,0x070c1c8e,0x6484d2e4,0xbbd3c371,0x0d414129,0xfb78318f,0x6ad93b0b,0x2621a39c,0xa9e917f7,0x979d74c2 +.long 0x61fb0428,0xfc195647,0xbee624d4,0x4d78954a,0xb8ae86fd,0xb94896e0,0xc91c8b13,0x6667ac0c,0x43bcf832,0x9f180512,0xa0010137,0xfbadf8b7,0xb3ba8aa7,0xc69b4089,0xe687ce85,0xfac4bacd +.long 0x977eab40,0x9164088d,0x2760b390,0x51f4c5b6,0x340dd553,0xd238238f,0xdb1d31c9,0x358566c3,0x5068f5ff,0x3a5ad69e,0xdaff6b06,0xf31435fc,0xd6debff0,0xae549a5b,0x75e01331,0x59e5f0b7 +.long 0x98559acf,0x5d492fb8,0x4db79b50,0x96018c2e,0x609f66aa,0x55f4a48f,0x4900a14f,0x1943b3af,0x15a40d39,0xc22496df,0x4c20f7c5,0xb2a44684,0x3b98404c,0x76a35afa,0xff5d1b77,0xbec75725 +.long 0xbea06444,0xb67aa163,0xf724b6f2,0x27e95bb2,0xd238c8ab,0x3c20e3e9,0xddd6ae17,0x1213754e,0x716e0f74,0x8c431020,0xffc095c2,0x6679c82e,0xd0ac2932,0x2eb3adf4,0x01bb7a76,0x2cc970d3 +.long 0x740f0e66,0x70c71f2f,0x2b6b23cc,0x545c616b,0xb40a8bd7,0x4528cfcb,0x2ab27722,0xff839633,0x025ac99a,0x049127d9,0x2b63e33b,0xd314d4a0,0x28d84519,0xc8c310e7,0xb3bc84ba,0x0fcb8983 +.long 0x38634818,0x2cc52261,0xb44c2e0b,0x501814f4,0x54dfdba3,0xf7e181aa,0xe759718c,0xcfd58ff0,0xd3b507a8,0xf90cdb14,0xc50bdad8,0x57bd478e,0x50e5f9aa,0x29c197e2,0xe40bc855,0x4db6eef8 +.long 0xd1fc0654,0x2cc8f21a,0x81269d73,0xc71cc963,0x077f49f9,0xecfbb204,0xca56b793,0xdde92571,0xf97ad8f7,0x9abed6a3,0x924de3bd,0xe6c19d3f,0xa140a800,0x8dce92f4,0x1337af07,0x85f44d1e +.long 0x09d64c52,0x5953c08b,0xf5df9749,0xa1b5e49f,0x52735f7d,0x336a8fb8,0x9add676b,0xb332b6db,0xb4511aa4,0x558b88a0,0xdbd5cc55,0x09788752,0xd8cd52bd,0x16b43b9c,0xc2a2696b,0x7f0bc5a0 +.long 0xc11f61ef,0x146e12d4,0x3a83e79e,0x9ce10754,0x6cbfca15,0x08ec73d9,0x5b49653f,0x09ff29ad,0xe7da946e,0xe31b72bd,0xee80a4f2,0xebf9eb3b,0x17598ce4,0xd1aabd08,0x53f37e80,0x18b5fef4 +.long 0x5958cd79,0xd5d5cdd3,0x1d373114,0x3580a1b5,0xfa935726,0xa36e4c91,0xef20d760,0xa38c534d,0x2ff5845b,0x7088e40a,0xbd78177f,0xe5bb40bd,0x857f9920,0x4f06a7a8,0xe968f05d,0xe3cc3e50 +.long 0xe5682d26,0x1d68b7fe,0xaec7f87c,0x5206f76f,0x041951ab,0x41110530,0xd4b5a71a,0x58ec52c1,0x0f75cf9a,0xf3488f99,0xba82d0d5,0xf411951f,0x618895ab,0x27ee75be,0x6d8aab14,0xeae060d4 +.long 0x7fb54dc2,0x9ae1df73,0x25963649,0x1f3e391b,0xfe055081,0x242ec32a,0x8491c9bd,0x5bd450ef,0x981eb389,0x367efc67,0x3a0550d5,0xed7e1928,0xab3ce75c,0x362e776b,0x1f24c523,0xe890e308 +.long 0xfeccef76,0xb961b682,0x8bba6d92,0x8b8e11f5,0x2b2375c4,0x8f2ccc4c,0xe2f86cfa,0x0d7f7a52,0x9efe5633,0xfd94d30a,0x5451f934,0x2d8d246b,0x244e6a00,0x2234c6e3,0xddec8c50,0xde2b5b0d +.long 0xbf776f5b,0x2ce53c5a,0x60357b05,0x6f724071,0x71bf3f7a,0xb2593717,0x440c4a9f,0x87d2501c,0x87b05340,0x440552e1,0x21624c32,0xb7bf7cc8,0x22facddb,0x4155a6ce,0x889837ef,0x5a4228cb +.long 0xfd4fd671,0xef87d6d6,0xc2daa10e,0xa233687e,0x03c0eb96,0x75622244,0x8bf19be6,0x7632d184,0x40735ff4,0x05d0f8e9,0xc00931f1,0x3a3e6e13,0xdafe3f18,0x31ccde6a,0xcfe51207,0xf381366a +.long 0x60167d92,0x24c222a9,0x7529f18c,0x62f9d6f8,0x0353b114,0x412397c0,0xef808043,0x334d89dc,0x2a4383ce,0xd9ec63ba,0x5cf92ba0,0xcec8e937,0xc8be74c0,0xfb8b4288,0x105d4391,0x67d6912f +.long 0x1b913149,0x7b996c46,0x3a4e02da,0x36aae2ef,0x972de594,0xb68aa003,0x4ec6d545,0x284ec70d,0x61391d54,0xf3d2b2d0,0xfe114e92,0x69c5d5d6,0xb4482dff,0xbe0f00b5,0xf5bf33c5,0xe1596fa5 +.long 0x96a71cba,0x10595b56,0xfdcadeb7,0x944938b2,0xfccd8471,0xa282da4c,0x0d37bfe1,0x98ec05f3,0x0698304a,0xe171ce1b,0x21bdf79b,0x2d691444,0x1b21dec1,0xd0cd3b74,0x16a15f71,0x712ecd8b +.long 0x00fd56e1,0x8d4c00a7,0xf9527c18,0x02ec9692,0x4a3e42e1,0x21c44937,0x1392ae0a,0x9176fbab,0x44b7b618,0x8726f1ba,0xf1de491c,0xb4d7aae9,0x07b582c0,0xf91df7b9,0xef60aa3a,0x7e116c30 +.long 0x466265d7,0x99270f81,0x4df7adf0,0xb15b6fe2,0xf9738f7f,0xfe33b2d3,0xd6d70f95,0x48553ab9,0xc21e94db,0x2cc72ac8,0xbdc0bbee,0x795ac38d,0x2e40478f,0x0a1be449,0x052bde55,0x81bd3394 +.long 0x56b3c4f2,0x63c8dbe9,0x904177cc,0x017a99cf,0x4d010fc1,0x947bbddb,0xbb2c9b21,0xacf9b00b,0x47173611,0x2970bc8d,0xac7d756f,0x1a4cbe08,0x67d541a2,0x06d9f4aa,0x59c2cf44,0xa3e8b689 +.long 0x4d88f1dd,0xaad066da,0x7ad35dea,0xc604f165,0x4478ca67,0x7edc0720,0xba02ce06,0xa10dfae0,0xaf36f4e4,0xeceb1c76,0xaf3f8f48,0x994b2292,0x77c8a68c,0xbf9ed77b,0x51744c9d,0x74f544ea +.long 0x8113a757,0x82d05bb9,0x8a9885e4,0x4ef2d2b4,0x1aa7865f,0x1e332be5,0x290d1a52,0x22b76b18,0x44351683,0x308a2310,0xa3f22840,0x9d861896,0x841ed947,0x5959ddcd,0x154b73bf,0x0def0c94 +.long 0x4c7c15e0,0xf0105417,0x3a277c32,0x539bfb02,0xf9dccf5f,0xe699268e,0x0247a3bd,0x9f5796a5,0x4f157269,0x8b839de8,0x7a30196b,0xc825c1e5,0xdc8a5a91,0x6ef0aabc,0x498b7fe6,0xf4a8ce6c +.long 0x70cbac78,0x1cce35a7,0xf6b23958,0x83488e9b,0xd76cb011,0x0341a070,0xae1b2658,0xda6c9d06,0xdd648c52,0xb701fb30,0x52fb9fd1,0x994ca02c,0x6f563086,0x06933117,0x17856bab,0x3d2b8100 +.long 0x5963a46e,0xe89f48c8,0xa99e61c7,0x658ab875,0x4b8517b4,0x6e296f87,0xfc1bc656,0x36c4fcdc,0xa3906def,0xde5227a1,0x62418945,0x9fe95f57,0xfdd96cde,0x20c91e81,0xda4480de,0x5adbe47e +.long 0x396de2b6,0xa009370f,0xf0ecc7bd,0x98583d4b,0xe51d0672,0xf44f6b57,0x556b1984,0x03d6b078,0xb0b64912,0x27dbdd93,0x15687b09,0x9b3a3434,0x51ec20a9,0x0dba6461,0xff28187c,0xec93db7f +.long 0x66e48bdd,0x00ff8c24,0x11ccd78e,0x2514f2f9,0xe1250603,0xeba11f4f,0x243fa156,0x8a22cd41,0xb283e4c6,0xa4e58df4,0x8b39783f,0x78c29859,0xa5259809,0x5235aee2,0x0e0227dd,0xc16284b5 +.long 0x1338830d,0xa5f57916,0xd2123fca,0x6d4b8a6b,0xf9c546f8,0x236ea68a,0xfa608d36,0xc1d36873,0x8d436d13,0xcd76e495,0x8fb080af,0xd4d9c221,0xe8ad3fb5,0x665c1728,0xb3d572e0,0xcf1ebe4d +.long 0x584c5e20,0xa7a8746a,0xb9dc7035,0x267e4ea1,0xb9548c9b,0x593a15cf,0x4bd012f3,0x5e6e2135,0x8c8f936e,0xdf31cc6a,0xb5c241dc,0x8af84d04,0x345efb86,0x63990a6f,0xb9b962cb,0x6fef4e61 +.long 0x25722608,0xf6368f09,0x131cf5c6,0x131260db,0xfab4f7ac,0x40eb353b,0x37eee829,0x85c78880,0xc3bdf24e,0x4c1581ff,0xf5c3c5a8,0x5bff75cb,0xa14e6f40,0x35e8c83f,0x0295e0ca,0xb81d1c0f +.long 0xf43a730f,0xfcde7cc8,0x33ab590e,0xe89b6f3c,0xad03240b,0xc823f529,0x98bea5db,0x82b79afe,0x962fe5de,0x568f2856,0x60c591f3,0x0c590adb,0x4a28a858,0x1fc74a14,0xb3203f4c,0x3b662498 +.long 0x6c39765a,0x91e3cf0d,0xac3cca0b,0xa2db3acd,0xcb953b50,0x288f2f08,0xcf43cf1a,0x2414582c,0x60eee9a8,0x8dec8bbc,0x729aa042,0x54c79f02,0x6532f5d5,0xd81cd5ec,0xcf82e15f,0xa672303a +.long 0x719c0563,0x376aafa8,0xbc5fc79f,0xcd8ad2dc,0xcb750cd3,0x303fdb9f,0x4418b08e,0x14ff052f,0x3e2d6520,0xf75084cf,0x144ed509,0x7ebdf0f8,0xd3f25b98,0xf43bf0f2,0xa354d837,0x86ad71cf +.long 0x26f43572,0xb827fe92,0x5d824758,0xdfd3ab5b,0x539094c1,0x315dd23a,0x66623d68,0x85c0e37a,0x7be19ae0,0x575c7972,0xdf0d36b5,0x616a3396,0x26b1ff7e,0xa1ebb3c8,0x140ad453,0x635b9485 +.long 0xda430c0b,0x92bf3cda,0x3a96dac6,0x4702850e,0x15ac326a,0xc91cf0a5,0xab8c25e4,0x95de4f49,0xe265c17c,0xb01bad09,0x087b3881,0x24e45464,0xe1fac5ca,0xd43e583c,0x6ead97a6,0xe17cb318 +.long 0x74dcec46,0x6cc39243,0x54c2b73f,0x33cfc02d,0xf26cd99c,0x82917844,0xd1773f89,0x8819dd95,0x0871f427,0x09572aa6,0xf6f01c34,0x8e0cf365,0xbff1f5af,0x7fa52988,0xe75e8e50,0x4eb357ea +.long 0x868af75d,0xd9d0c8c4,0x45c8c7ea,0xd7325cff,0xcc81ecb0,0xab471996,0x611824ed,0xff5d55f3,0x1977a0ee,0xbe314541,0x722038c6,0x5085c4c5,0xf94bb495,0x2d5335bf,0xc8e2a082,0x894ad8a6 +.long 0xada35438,0x5c3e2341,0x049b8c4e,0xf4a9fc89,0x9f17cf34,0xbeeb355a,0x6c91fe10,0x3f311e0e,0x92ab9891,0xc2d20038,0x3e8ce9a9,0x257bdcc1,0x88c53bee,0x1b2d9789,0xcdba143a,0x927ce89a +.long 0x523db280,0xb0a32cca,0x50d43783,0x5c889f8a,0x4897d16f,0x503e04b3,0x08f5f2e8,0x8cdb6e78,0x179c8e74,0x6ab91cf0,0x48211d60,0xd8874e52,0xea851200,0xf948d4d5,0xe6f9840a,0x4076d41e +.long 0x47b517ea,0xc20e263c,0x30685e5e,0x79a448fd,0xf90631a0,0xe55f6f78,0xa79e6346,0x88a790b1,0x80969fe8,0x62160c7d,0x41491bb9,0x54f92fd4,0x5c957526,0xa6645c23,0xbea3ce7b,0xf44cc5ae +.long 0x8b1e68b7,0xf7628327,0x303f29d3,0xc731ad7a,0x57d03ecb,0xfe5a9ca9,0x41bc97a7,0x96c0d50c,0x9b4f7f24,0xc4669fe7,0x3d9967ef,0xfdd781d8,0x5d2c208d,0x7892c7c3,0xae545cb3,0x8bf64f7c +.long 0x467be912,0xc01f862c,0xc73d30cc,0xf4c85ee9,0x6ab83ec7,0x1fa6f4be,0x4e3e3cf9,0xa07a3c1c,0x0c00beb3,0x87f8ef45,0x000d4c3e,0x30e2c2b3,0xfe08bf5b,0x1aa00b94,0x9224ef52,0x32c133aa +.long 0x32e5685d,0x38df16bb,0x58e6f544,0x68a9e069,0xcdc5ebc6,0x495aaff7,0x378b135f,0xf894a645,0x09e27ecf,0xf316350a,0x58f7179d,0xeced201e,0xe97861ba,0x2eec273c,0xd693be2e,0x47ec2cae +.long 0xf68367ce,0xfa4c97c4,0xbe5a5755,0xe4f47d0b,0xb298a979,0x17de815d,0xc177dc7d,0xd7eca659,0x49ded0a3,0x20fdbb71,0xfb34d3c5,0x4cb2aad4,0x60858a33,0x2cf31d28,0xa24aa40f,0x3b6873ef +.long 0x2c11bb37,0x540234b2,0xed4c74a3,0x2d0366dd,0xeec5f25d,0xf9a968da,0x67b63142,0x36601068,0x68d7b6d4,0x07cd6d2c,0x0c842942,0xa8f74f09,0x7768b1ee,0xe2751404,0xfe62aee4,0x4b5f7e89 +.long 0x89070d26,0xc6a77177,0xdd1c8bc7,0xa1f28e4e,0x469e1f17,0xea5f4f06,0xfbdb78e0,0x78fc242a,0x8b0588f1,0xc9c7c592,0x1535921e,0xb6b7a0fd,0xbde5ae35,0xcc5bdb91,0x12ff1864,0xb42c485e +.long 0xdbab98aa,0xa1113e13,0xa17b1024,0xde9d469b,0xc0462d3a,0x23f48b37,0x7c5c078d,0x3752e537,0x15544eb9,0xe3a86add,0x80fba279,0xf013aea7,0xf22001b5,0x8b5bb76c,0xf02891ab,0xe617ba14 +.long 0x936219d3,0xd39182a6,0xae51cb19,0x5ce1f194,0xbf07a74c,0xc78f8598,0x22cbf1bc,0x6d7158f2,0xe300ce18,0x3b846b21,0x2d11275d,0x35fba630,0xa0239b9b,0x5fe25c36,0xdf05d940,0xd8beb35d +.long 0x1f7e320d,0x4db02bb0,0x6da320ea,0x0641c364,0x821389a3,0x6d95fa5d,0x8fcd8e3d,0x92699748,0xceb6c143,0x316fef17,0xd933762b,0x67fcb841,0x118b17f8,0xbb837e35,0x9fd24821,0x4b92552f +.long 0x46aca793,0xae6bc70e,0xe579311b,0x1cf0b0e4,0x5802f716,0x8dc631be,0xbddbee4d,0x099bdc6f,0x0caf8b05,0xcc352bb2,0x72d63df2,0xf74d505a,0x91c4f408,0xb9876d4b,0x9e229b2d,0x1ce18473 +.long 0x83abdb4a,0x49507597,0xdee84b18,0x850fbcb6,0x609e67dc,0x6325236e,0x9336c6d8,0x04d831d9,0xfa12d45d,0x8deaae3b,0x4746e246,0xe425f8ce,0x24f5f31e,0x8004c175,0xad62c3b7,0xaca16d8f +.long 0x9152f934,0x0dc15a6a,0xed0e12c1,0xf1235e5d,0xda477dac,0xc33c06ec,0xb2ea0006,0x76be8732,0x0c0cd313,0xcf3f7831,0xa614260d,0x3c524553,0xcab22d15,0x31a756f8,0x77827a20,0x03ee10d1 +.long 0x1994ef20,0xd1e059b2,0x638ae318,0x2a653b69,0x2f699010,0x70d5eb58,0x09f5f84a,0x279739f7,0x8b799336,0x5da4663c,0x203c37eb,0xfdfdf14d,0xa1dbfb2d,0x32d8a9dc,0x77d48f9b,0xab40cff0 +.long 0xd20b42d5,0xc018b383,0x9f78845f,0xf9a810ef,0xbdba9df0,0x40af3753,0x131dfdf9,0xb90bdcfc,0xf01ab782,0x18720591,0x6af12a88,0xc823f211,0x0dc14401,0xa51b80f3,0xfb2dfbe3,0xde248f77 +.long 0x0cafe751,0xef5a44e5,0xd4dcd221,0x73997c9c,0xde854024,0x32fd86d1,0xa09b84bb,0xd5b53adc,0xdcedd8d1,0x008d7a11,0x74b32c84,0x406bd1c8,0x05dde8b1,0x5d4472ff,0xfce2b32f,0x2e25f2cd +.long 0x29dfc254,0xbec0dd5e,0x2b98b267,0x4455fcf6,0xc72df2ad,0x0b4d43a5,0x48a75397,0xea70e6be,0x5820f3bf,0x2aad6169,0x9e37f68f,0xf410d2dd,0x7be5ac83,0x70fb7dba,0x36ec3eec,0x636bb645 +.long 0x9754e21c,0x27104ea3,0x8d63c373,0xbc87a3e6,0x4109db9a,0x483351d7,0x60134da7,0x0fa724e3,0xb0720b16,0x9ff44c29,0x06aceead,0x2dd0cf13,0xe26929a6,0x5942758c,0xb766a92b,0x96c5db92 +.long 0x5f18395e,0xcec7d4c0,0x1f80d032,0xd3f22744,0xcb86075b,0x7a68b37a,0xafef92db,0x074764dd,0x7bc7f389,0xded1e950,0xb9756460,0xc580c850,0x7da48157,0xaeeec2a4,0x82c587b3,0x3f0b4e7f +.long 0xa9f19c53,0x231c6de8,0x6974e34e,0x5717bd73,0xf1508fa9,0xd9e1d216,0xdadaa124,0x9f112361,0x823b7348,0x80145e31,0xac634069,0x4dd8f0d5,0x2297c258,0xe3d82fc7,0x9cee7431,0x276fcfee +.long 0x2bc0aea9,0x8eb61b5e,0xde329431,0x4f668fd5,0x38e4b87e,0x03a32ab1,0x73d0ef0b,0xe1374517,0x853ac983,0x1a46f7e6,0x68e78a57,0xc3bdf42e,0x2ea96dd1,0xacf20785,0xf1638460,0xa10649b9 +.long 0x879fbbed,0xf2369f0b,0xda9d1869,0x0ff0ae86,0x56766f45,0x5251d759,0x2be8d0fc,0x4984d8c0,0xd21008f0,0x7ecc95a6,0x3a1a1c49,0x29bd54a0,0xd26c50f3,0xab9828c5,0x51d0d251,0x32c0087c +.long 0x0c1cdb26,0x9bac3ce6,0x557ca205,0xcd94d947,0x9db1fdcd,0x1b1bd598,0xa3d8b149,0x0eda0108,0x56152fcc,0x95066610,0xe7192b33,0xc2f037e6,0xc92e05a4,0xdeffb41a,0xc2f6c62e,0x1105f6c2 +.long 0x8733913c,0x68e73500,0x3f3adc40,0xcce86163,0x38a278e9,0xf407a942,0x2ab21292,0xd13c1b9d,0x1c74cf5c,0x93ed7ec7,0xf1a4c1b4,0x8887dc48,0x4b3a11f1,0x3830ff30,0x58937cb6,0x358c5a3c +.long 0x89022829,0x027dc404,0x3b798f79,0x40e93977,0x38be6ead,0x90ad3337,0xf34c0a5d,0x9c23f6bc,0xfbffd8bb,0xd1711a35,0x1949d3dd,0x60fcfb49,0x7825d93a,0x09c8ef4b,0xa0a8c968,0x24233cff +.long 0xe6d982af,0x67ade46c,0xe7544d7c,0xebb6bf3e,0x3d8bd087,0xd6b9ba76,0x4dc61280,0x46fe382d,0xb5bdbd75,0xbd39a7e8,0xb8f228fe,0xab381331,0xce1c4300,0x0709a77c,0xf337ceac,0x6a247e56 +.long 0x636288be,0x8f34f21b,0xc8a7c305,0x9dfdca74,0xea919e04,0x6decfd1b,0x8e1991f8,0xcdf2688d,0xd0f8a67e,0xe607df44,0x0b58d010,0xd985df4b,0x0c24f8f4,0x57f834c5,0xa0bf01ae,0xe976ef56 +.long 0xa1c32373,0x536395ac,0x734c0a13,0x351027aa,0x5e6bd5bc,0xd2f1b5d6,0x223debed,0x2b539e24,0x0eaa1d71,0xd4994cec,0x661dcf65,0x2a83381d,0x7b54c740,0x5f1aed2f,0xd6dda5ee,0x0bea3fa5 +.long 0x36cc6134,0x9d4fb684,0xc0a443dd,0x8eb9bbf3,0x383b7d2a,0xfc500e2e,0x5b775257,0x7aad621c,0x0a8f7cc0,0x69284d74,0x07562d65,0xe820c2ce,0x499758ee,0xbf9531b9,0x6ee0cc2d,0x73e95ca5 +.long 0xfbaf50a5,0xf61790ab,0x684e0750,0xdf55e76b,0xf176b005,0xec516da7,0x7a2dddc7,0x575553bb,0x553afa73,0x37c87ca3,0x4d55c251,0x315f3ffc,0xaf3e5d35,0xe846442a,0x6495ff28,0x61b91149 +.long 0xfa326dc3,0x23cc95d3,0x18fc2cea,0x1df4da1f,0xd0a37d59,0x24bf9adc,0x320d6e1e,0xb6710053,0x618344d1,0x96f9667e,0xa06445af,0xcc7ce042,0xd68dbc3a,0xa02d8514,0x280b5a5b,0x4ea109e4 +.long 0xb40961bf,0x5741a7ac,0x6aa56bfa,0x4ada5937,0x02b765d1,0x7feb9145,0xe6ad1582,0x561e97be,0xda3982f5,0xbbc4a5b6,0xb546f468,0x0c2659ed,0x59612d20,0xb8e7e6aa,0xac19e8e0,0xd83dfe20 +.long 0xb835398c,0x8530c45f,0xb38a41c2,0x6106a8bf,0x35f5dcdb,0x21e8f9a6,0xcae498ed,0x39707137,0xd8249f00,0x70c23834,0xab2537a0,0x9f14b58f,0x5f61c0c2,0xd043c365,0x09a194a7,0xdc5926d6 +.long 0x8e77738a,0xddec0339,0xfba46426,0xd07a63ef,0xee7f6e86,0x2e58e79c,0xff32d241,0xe59b0459,0x20fa0338,0xc5ec84e5,0xeaff5ace,0x97939ac8,0xb4a38313,0x0310a4e3,0x8f9d9885,0x9115fba2 +.long 0x5fadf8c3,0x8dd710c2,0xce19c0e2,0x66be38a2,0x4cfe5022,0xd42a279c,0x0e24e1b8,0x597bb530,0xc153ca7f,0x3cde86b7,0x707d63bd,0xa8d30fb3,0xbd60d21e,0xac905f92,0x7b9a54ab,0x98e7ffb6 +.long 0xe9726a30,0xd7147df8,0xafce3533,0xb5e216ff,0x2ff1ec40,0xb550b799,0xa1e953fd,0x6b613b87,0x792d5610,0x87b88dba,0xa190fbe1,0x2ee1270a,0x2ef581da,0x02f4e2dc,0xeff82a95,0x016530e4 +.long 0x8fd6ee89,0xcbb93dfd,0x46848fff,0x16d3d986,0x1da47adf,0x600eff24,0x0ad47a71,0x1b9754a0,0x70c33b98,0x8f9266df,0xdf34186e,0xaadc87ae,0x4ad24132,0x0d2ce8e1,0x19946eba,0x8a47cbfc +.long 0x62b5f3af,0x47feeb66,0x0abb3734,0xcefab561,0x19f35cb1,0x449de60e,0x157f0eb9,0x39f8db14,0x3c61bfd6,0xffaecc5b,0x41216703,0xa5a4d41d,0x224e1cc2,0x7f8fabed,0x871ad953,0x0d5a8186 +.long 0xd22da9a9,0xf10774f7,0xcc8a9b0d,0x45b8a678,0xbdc32cff,0xd9c2e722,0x337202a5,0xbf71b5f5,0x69fc4db9,0x95c57f2f,0x765d01e1,0xb6dad34c,0xcb904635,0x7e0bd13f,0x763a588c,0x61751253 +.long 0x81af2c2d,0xd85c2997,0x81b9d7da,0xc0f7d9c4,0x08533e8d,0x838a34ae,0x311d8311,0x15c4cb08,0x8e121e14,0x97f83285,0x85000a5f,0xeea7dc1e,0x5d256274,0x0c6059b6,0xb95075c0,0xec9beace +.long 0x1df97828,0x173daad7,0xa8937877,0xbf851cb5,0x01646f3c,0xb083c594,0x50c6d352,0x3bad30cf,0x496bbcea,0xfeb2b202,0x18a1e8ba,0x3cf9fd4f,0x1c066029,0xd26de7ff,0x4e9ed4f8,0x39c81e9e +.long 0x7b390d35,0xd8be0cb9,0x964aab27,0x01df2bbd,0xc3ef64f8,0x3e8c1a65,0x716ed1dd,0x567291d1,0x5f5406d3,0x95499c6c,0x5ba8e23f,0x71fdda39,0xd5096ece,0xcfeb320e,0xca66dd16,0xbe7ba92b +.long 0xc6fb5a7d,0x4608d36b,0x6d2dd0e0,0xe3eea15a,0x8f97a36a,0x75b0a3eb,0x1c83de1e,0xf59814cc,0x1c33c23f,0x56c9c5b0,0x6faa4136,0xa96c1da4,0xde316551,0x46bf2074,0x1f756c8f,0x3b866e7b +.long 0x1495ed6b,0x727727d8,0xb682dce7,0xb2394243,0x758610f3,0x8ab8454e,0x857d72a4,0xc243ce84,0xdbbf370f,0x7b320d71,0x78e0f7ca,0xff9afa37,0xea7b523f,0x0119d1e0,0x058c7d42,0xb997f8cb +.long 0x37bbb184,0x285bcd2a,0xa45d1fa6,0x51dcec49,0xe29634cb,0x6ade3b64,0x26b86ef1,0x080c94a7,0x2283fbe3,0xba583db1,0x5a9315ed,0x902bddc8,0x86964bec,0x07c1ccb3,0xb6258301,0x78f4eacf +.long 0x56f90823,0x4bdf3a49,0x741d777b,0xba0f5080,0xf38bf760,0x091d71c3,0x9b625b02,0x9633d50f,0xb8c9de61,0x03ecb743,0x5de74720,0xb4751254,0x74ce1cb2,0x9f9defc9,0x00bd32ef,0x774a4f6a +.long 0x73848f22,0xaca385f7,0xf3f8558e,0x53dad716,0x93c471f9,0xab7b34b0,0x19644bc7,0xf530e069,0xdd59d31a,0x3d9fb1ff,0x08daa795,0x4382e0df,0xd5cc88d7,0x165c6f4b,0x4a18c900,0xeaa392d5 +.long 0x648024ee,0x94203c67,0x8c2fabcd,0x188763f2,0xbbaec835,0xa80f87ac,0xf29d8d54,0x632c96e0,0x4c00a95e,0x29b0a60e,0xe011e9fa,0x2ef17f40,0x15b77223,0xf6c0e1d1,0x14b04e32,0xaaec2c62 +.long 0x3d84e58c,0xd35688d8,0x958571db,0x2af5094c,0x760682a6,0x4fff7e19,0xe39a407c,0x4cb27077,0x4ff0e321,0x0f59c547,0x1b34c8ff,0x169f34a6,0x52bc1ba7,0x2bff1096,0x83583544,0xa25423b7 +.long 0x0ac8b782,0x5d55d5d5,0x2db3c892,0xff6622ec,0x6b8bb642,0x48fce741,0x69d7e3dc,0x31d6998c,0xcadcaed0,0xdbaf8004,0xd81d053c,0x801b0142,0x59630ec6,0x94b189fc,0xaf762c8e,0x120e9934 +.long 0xfdc6a404,0x53a29aa4,0xa1909948,0x19d8e01e,0xd7e89681,0x3cfcabf1,0x4e132d37,0x3321a50d,0xe9a86111,0xd0496863,0x06a3bc65,0x8c0cde61,0xfc9f8eef,0xaf866c49,0xff7f5141,0x2066350e +.long 0xe56ddfbd,0x4f8a4689,0xfe32983a,0xea1b0c07,0x873cb8cb,0x2b317462,0x2d93229f,0x658deddc,0x0f64ef58,0x65efaf4d,0x730cc7a8,0xfe43287d,0x3d047d70,0xaebc0c72,0xd92d26c9,0x92efa539 +.long 0x94b56526,0x06e78457,0x0961002d,0x415cb80f,0x76dcb10f,0x89e5c565,0xff9259fe,0x8bbb6982,0x9abc2668,0x4fe8795b,0x1e678fb1,0xb5d4f534,0x7b7da2b9,0x6601f3be,0xa13d6805,0x98da59e2 +.long 0x01799a52,0x190d8ea6,0xb86d2952,0xa20cec41,0x7fff2a7c,0x3062ffb2,0x79f19d37,0x741b32e5,0x4eb57d47,0xf80d8181,0x16aef06b,0x7a2d0ed4,0x1cecb588,0x09735fb0,0xc6061f5b,0x1641caaa +.long 0x20151427,0x7f99824f,0x92430206,0x206828b6,0xe1112357,0xaa9097d7,0x09e414ec,0xacf9a2f2,0x27915356,0xdbdac9da,0x001efee3,0x7e0734b7,0xd2b288e2,0x54fab5bb,0xf62dd09c,0x4c630fc4 +.long 0x1ac2703b,0x8537107a,0x6bc857b5,0xb49258d8,0xbcdaccd1,0x57df14de,0xc4ae8529,0x24ab68d7,0x734e59d0,0x7ed8b5d4,0xc495cc80,0x5f8740c8,0x291db9b3,0x84aedd5a,0x4fb995be,0x80b360f8 +.long 0x5fa067d1,0xae915f5d,0x9668960c,0x4134b57f,0xa48edaac,0xbd3656d6,0xfc1d7436,0xdac1e3e4,0xd81fbb26,0x674ff869,0xb26c33d4,0x449ed3ec,0xd94203e8,0x85138705,0xbeeb6f4a,0xccde538b +.long 0xa61a76fa,0x55d5c68d,0xca1554dc,0x598b441d,0x773b279c,0xd39923b9,0x36bf9efc,0x33331d3c,0x298de399,0x2d4c848e,0xa1a27f56,0xcfdb8e77,0x57b8ab70,0x94c855ea,0x6f7879ba,0xdcdb9dae +.long 0x019f2a59,0x7bdff8c2,0xcb4fbc74,0xb3ce5bb3,0x8a9173dd,0xea907f68,0x95a75439,0x6cd3d0d3,0xefed021c,0x92ecc4d6,0x6a77339a,0x09a9f9b0,0x7188c64a,0x87ca6b15,0x44899158,0x10c29968 +.long 0xed6e82ef,0x5859a229,0x65ebaf4e,0x16f338e3,0x5ead67ae,0x0cd31387,0x54ef0bb4,0x1c73d228,0x74a5c8c7,0x4cb55131,0x7f69ad6a,0x01cd2970,0xe966f87e,0xa04d00dd,0x0b7b0321,0xd96fe447 +.long 0x88fbd381,0x342ac06e,0x5c35a493,0x02cd4a84,0x54f1bbcd,0xe8fa89de,0x2575ed4c,0x341d6367,0xd238202b,0xebe357fb,0xa984ead9,0x600b4d1a,0x52436ea0,0xc35c9f44,0xa370751b,0x96fe0a39 +.long 0x7f636a38,0x4c4f0736,0x0e76d5cb,0x9f943fb7,0xa8b68b8b,0xb03510ba,0x9ed07a1f,0xc246780a,0x6d549fc2,0x3c051415,0x607781ca,0xc2953f31,0xd8d95413,0x955e2c69,0x7bd282e3,0xb300fadc +.long 0x87e9189f,0x81fe7b50,0xf42dda27,0xdb17375c,0xcf0a5904,0x22f7d896,0xebe348e6,0xa0e57c5a,0xf40e3c80,0xa61011d3,0x8db705c5,0xb1189321,0x50fedec3,0x4ed9309e,0x4d6d5c1d,0xdcf14a10 +.long 0x55691342,0x056c265b,0x91049dc7,0xe8e08504,0xc9bae20a,0x131329f5,0xd9dccdb4,0x96c8b3e8,0xfb4ee6b4,0x8c5ff838,0x41e8ccf0,0xfc5a9aeb,0xfae050c6,0x7417b764,0x00452080,0x0953c3d7 +.long 0x38dfe7e8,0x21372682,0x2bb79d4b,0xea417e15,0x76e7cf2d,0x59641f1c,0xea0bcfcc,0x271e3059,0x7253ecbd,0x624c7dfd,0x4fca6186,0x2f552e25,0x4d866e9c,0xcbf84ecd,0xf68d4610,0x73967709 +.long 0xc27901b4,0xa14b1163,0x899b8bf3,0xfd9236e0,0xcbc6da0a,0x42b091ec,0x5ad1d297,0xbb1dac6f,0xa91cf76e,0x80e61d53,0xd31f1ee7,0x4110a412,0x13efcf77,0x2d87c3ba,0xdf450d76,0x1f374bb4 +.long 0x0d188dab,0x5e78e2f2,0xf4b885ef,0xe3968ed0,0x7314570f,0x46c0568e,0x01170521,0x31616338,0x4f0c8afe,0x18e1e7e2,0xdeea78da,0x4caa75ff,0x7c5d8a51,0x82db67f2,0x6f505370,0x36a44d86 +.long 0x0333974f,0xd72c5bda,0x27a70146,0x5db516ae,0x210ef921,0x34705281,0x0c9c38e5,0xbff17a8f,0x12476da1,0x78f4814e,0x33c16980,0xc1e16613,0x424d4bca,0x9e5b386f,0xc85740de,0x4c274e87 +.long 0x6c2f5226,0xb6a9b88d,0x550d7ca8,0x14d1b944,0x1fc41709,0x580c85fc,0x54c6d519,0xc1da368b,0xd5113cf7,0x2b0785ce,0x5a34708f,0x0670f633,0x15cc3f88,0x46e23767,0x50c72c8f,0x1b480cfa +.long 0x4147519a,0x20288602,0x26b372f0,0xd0981eac,0xa785ebc8,0xa9d4a7ca,0xdbdf58e9,0xd953c50d,0xfd590f8f,0x9d6361cc,0x44e6c917,0x72e9626b,0x22eb64cf,0x7fd96110,0x9eb288f3,0x863ebb7e +.long 0x6aca8ee7,0x6e6ab761,0xd7b40358,0x97d10b39,0x1e5feb0d,0x1687d377,0x8265a27a,0xc83e50e4,0xc954b313,0x8f75a9fe,0x310d1f61,0xcc2e8f47,0x6557d0e0,0xf5ba81c5,0x3eaf6207,0x25f9680c +.long 0x4354080b,0xf95c6609,0x7bf2fe1c,0x5225bfa5,0x5c7d98fa,0xc5c004e2,0x019aaf60,0x3561bf1c,0xba151474,0x5e6f9f17,0xb04f6eca,0xdec2f934,0x269acb1e,0x64e368a1,0x0cdda493,0x1332d9e4 +.long 0xdf23de05,0x60d6cf69,0x009339a0,0x66d17da2,0x0a693923,0x9fcac985,0xed7c6a6d,0xbcf057fc,0xf0b5662c,0xc3c5c8c5,0xdcba4f24,0x25318dd8,0x082b69ff,0x60e8cb75,0x1e728c01,0x7c23b3ee +.long 0x097e4403,0x15e10a0a,0x19854665,0xcb3d0a86,0xd67d4826,0x88d8e211,0x0b9d2839,0xb39af66e,0xbd475ca8,0xa5f94588,0xc077b80b,0xe06b7966,0xda27c26c,0xfedb1485,0xfe0fd5e0,0xd290d33a +.long 0xf34fb0fa,0xa40bcc47,0x1fb1ab09,0xb4760cc8,0xa273bfe3,0x8fca0993,0xf70b213c,0x13e4fe07,0xfdb05163,0x3bcdb992,0x0c2b19b6,0x8c484b11,0xaaf2e3e2,0x1acb815f,0xb89ff1b4,0xc6905935 +.long 0x586e74e1,0xb2ad6f9d,0x67b80484,0x488883ad,0x369c3ddb,0x758aa2c7,0x9f9afd31,0x8ab74e69,0x5e21beb1,0x10fc2d28,0x318c42f9,0x3484518a,0x53cf40c3,0x377427dc,0x391bc1d9,0x9de0781a +.long 0x693807e1,0x8faee858,0x4e81ccc7,0xa3865327,0x6f835b84,0x02c30ff2,0x0d3d38d4,0xb604437b,0x5ca1823d,0xb3fc8a98,0x03be0324,0xb82f7ec9,0xcf684a33,0xee36d761,0x9f29bf7d,0x5a01df0e +.long 0x1306583d,0x686202f3,0x437c622e,0x05b10da0,0x076a7bc8,0xbf9aaa0f,0x8f8f4e43,0x25e94efb,0xfa3dc26d,0x8a35c9b7,0x96ff03c5,0xe0e5fb93,0xebc394ce,0xa77e3843,0x8361de60,0xcede6595 +.long 0xa1993545,0xd27c22f6,0x24d671ba,0xab01cc36,0xa169c28e,0x63fa2877,0x2eb08376,0x925ef904,0x53aa0b32,0x3b2fa3cf,0x71c49d7a,0xb27beb5b,0xd105e27f,0xb60e1834,0x4f68570d,0xd6089788 +.long 0xd6fbc2ac,0x23094ce0,0x815ff551,0x738037a1,0x6bef119c,0xda73b1bb,0xeef506ba,0xdcf6c430,0xe3ef104a,0x00e4fe7b,0x0a065628,0xebdd9a2c,0x8792043e,0x853a81c3,0xb3b59108,0x22ad6ece +.long 0x39cd297d,0x9fb813c0,0x05bda5d9,0x8ec7e16e,0x0d104b96,0x2834797c,0x7c511510,0xcc11a2e7,0x96ee6380,0x96ca5a53,0xcea38742,0x054c8655,0xd54dfa7d,0xb5946852,0x1f4ab207,0x97c422e7 +.long 0x0c22b540,0xbf907509,0xb7c267d4,0x2cde42aa,0x5ab0d693,0xba18f9ed,0x6e4660d9,0x3ba62aa6,0xab9ea96a,0xb24bf97b,0xe3b60e32,0x5d039642,0x7c4d9bd5,0x4e6a4506,0x7ed4a6a4,0x666c5b9e +.long 0x8edbd7cc,0xfa3fdcd9,0xc6ccd753,0x4660bb87,0x21e6b64f,0x9ae90820,0xb36bfb3f,0x8a56a713,0x5726d47f,0xabfce096,0x0b1a9a7f,0x9eed01b2,0x4eb74a37,0x30e9cad4,0x53e9666d,0x7b2524cc +.long 0x8f4b002f,0x6a29683b,0x41f4fc20,0xc2200d7a,0x3a338acc,0xcf3af47a,0xe7128975,0x6539a4fb,0xc33c7fcf,0xcec31c14,0xc7be322b,0x7eb6799b,0x6646f623,0x119ef4e9,0x54d7299b,0x7b7a26a5 +.long 0x403f46f2,0xcb37f08d,0x1a0ec0c7,0x94b8fc43,0xc332142f,0xbb8514e3,0xe80d2a7a,0xf3ed2c33,0xb639126c,0x8d2080af,0xe3553ade,0xf7b6be60,0x1c7e2b09,0x3950aa9f,0x6410f02b,0x847ff958 +.long 0x678a31b0,0x877b7cf5,0x3998b620,0xd50301ae,0xc00fb396,0x734257c5,0x04e672a6,0xf9fb18a0,0xe8758851,0xff8bd8eb,0x5d99ba44,0x1e64e4c6,0x7dfd93b7,0x4b8eaedf,0x04e76b8c,0xba2f2a98 +.long 0xe8053433,0x7d790cba,0x3d2c9585,0xc8e725a0,0xcdd8f5ed,0x58c5c476,0xefa9fe1d,0xd106b952,0x0eff13a9,0x3c5c775b,0xe057b930,0x242442ba,0xc9b70cbd,0xe9f458d4,0xa3cdb89a,0x69b71448 +.long 0x0e2ed742,0x41ee46f6,0x40067493,0x573f1045,0x9d54c304,0xb1e154ff,0x8d3a7502,0x2ad0436a,0x431a8121,0xee4aaa2d,0x886f11ed,0xcd38b3ab,0x034a0eb7,0x57d49ea6,0xf7e85e58,0xd2b773bd +.long 0x9b5c1f14,0x4a559ac4,0x3e54df2b,0xc444be1a,0xeda41891,0x13aad704,0x5eb5c788,0xcd927bec,0xe48c8a34,0xeb3c8516,0x4b546669,0x1b7ac812,0x594df8ec,0x1815f896,0x79227865,0x87c6a79c +.long 0x9b56ddbd,0xae02a2f0,0x8a2f1cf3,0x1339b5ac,0x839dff0d,0xf2b569c7,0xfee9a43d,0xb0b9e864,0x77bb064e,0x4ff8ca41,0xfd249f63,0x145a2812,0xf86f689a,0x3ab7beac,0x01d35f5e,0x9bafec27 +.long 0x4265aa91,0x28054c65,0x035efe42,0xa4b18304,0x9639dec7,0x6887b0e6,0x3d52aea5,0xf4b8f6ad,0x971a8a13,0xfb9293cc,0x4c934d07,0x3f159e5d,0x09acbc29,0x2c50e9b1,0x7154d129,0x08eb65e6 +.long 0x30b75c3e,0x4feff589,0x94491c93,0x0bb82fe2,0x89af62bb,0xd8ac377a,0x9685e49f,0xd7b51490,0x04497f19,0xabca9a7b,0x1a7ad13f,0x1b35ed0a,0x3ec86ed6,0x6b601e21,0xce0c76f1,0xda91fcb9 +.long 0xd7ab27e1,0x9e28507b,0x63945b7b,0x7c19a555,0xaafc9827,0x6b43f0a1,0x3aa55b91,0x443b4fbd,0x6962c88f,0x962b2e65,0xce0db0ca,0x139da8d4,0x1b8d6c4f,0xb93f05dd,0x180b9824,0x779cdff7 +.long 0xae57c7b7,0xbba23fdd,0x1b932522,0x345342f2,0x556d4aa3,0xfd9c80fe,0x6525bb61,0xa03907ba,0xff218933,0x38b010e1,0xaa52117b,0xc066b654,0x94f2e6ea,0x8e141920,0x0d32f2b2,0x66a27dca +.long 0x048b3717,0x69c7f993,0xb178ae1c,0xbf5a989a,0x564f1d6b,0x49fa9058,0xd31fde4e,0x27ec6e15,0x7276e7fc,0x4cce0373,0x89d6bf02,0x64086d79,0x4ccdd979,0x5a72f046,0x47775631,0x909c3566 +.long 0x75dd7125,0x1c07bc6b,0x87a0428d,0xb4c6bc97,0xfdeb6b9d,0x507ece52,0xb2c95432,0xfca56512,0xd0e8bd06,0x15d97181,0xc6bb46ea,0x384dd317,0x3952b624,0x5441ea20,0x4e7dc2fb,0xbcf70dee +.long 0x6628e8c3,0x372b016e,0xb60a7522,0x07a0d667,0x0a344ee2,0xcf05751b,0x118bdeec,0x0ec09a48,0xd83dce46,0x6e4b3d4e,0x99d2fc6e,0x43a6316d,0x56cf044c,0xa99d8989,0xae3e5fb7,0x7c7f4454 +.long 0xfbabbe92,0xb2e6b121,0xe1330076,0x281850fb,0x97890015,0x093581ec,0x75ff77f5,0x69b1dded,0xab105105,0x7cf0b18f,0xa89ccfef,0x953ced31,0xeb914009,0x3151f85f,0x88ed48ad,0x3c9f1b87 +.long 0x4a7eadcb,0xc9aba1a1,0x522e71cf,0x928e7501,0x3a2e4f83,0xeaede727,0x1ce3bbd3,0x467e10d1,0xb955dcf0,0xf3442ac3,0xd3d5e527,0xba96307d,0xfd77f474,0xf763a10e,0x6a6e1ff0,0x5d744bd0 +.long 0xa777899e,0xd287282a,0xd03f3cde,0xe20eda8f,0x50b07d31,0x6a7e75bb,0x6f379de4,0x0b7e2a94,0x19f593cf,0x31cb64ad,0x1e76ef1d,0x7b1a9e4f,0xb62d609c,0xe18c9c9d,0xe779a650,0x439bad6d +.long 0xe032f144,0x219d9066,0xe8b2ec6a,0x1db632b8,0xfda12f78,0xff0d0fd4,0x2a25d265,0x56fb4c2d,0x255a03f1,0x5f4e2ee1,0xe96af176,0x61cd6af2,0xd068bc97,0xe0317ba8,0x264b988e,0x927d6bab +.long 0xe90fb21e,0xa18f07e0,0xbba7fca1,0x00fd2b80,0x95cd67b5,0x20387f27,0xd39707f7,0x5b89a4e7,0x894407ce,0x8f83ad3f,0x6c226132,0xa0025b94,0xf906c13b,0xc79563c7,0x4e7bb025,0x5f548f31 +.long 0xeac6d113,0x2b4c6b8f,0x0e813c76,0xa67e3f9c,0x3fe1f4b9,0x3982717c,0x26d8050e,0x58865819,0xf7f06f20,0x99f3640c,0x2a66ebc2,0xdc610216,0x767a1e08,0x52f2c175,0x5999871b,0x05660e1a +.long 0x6d3c4693,0x6b0f1762,0x37ed7bea,0xf0e7d627,0xb75b226d,0xc51758c7,0x1f91613b,0x40a88628,0xbbb38ce0,0x889dbaa7,0xbddcad81,0xe0404b65,0x8bc9671f,0xfebccd3a,0xee1f5375,0xfbf9a357 +.long 0x28f33398,0x5dc169b0,0x72e90f65,0xb07ec11d,0xfaab1eb1,0xae7f3b4a,0x5f17538a,0xd970195e,0x0181e640,0x52b05cbe,0x2643313d,0xf5debd62,0x5df31f82,0x76148154,0x3a9e13c5,0x23e03b33 +.long 0x4fde0c1f,0xff758949,0xe5b6ec20,0xbf8a1abe,0x87e1db6c,0x702278fb,0x35ed658f,0xc447ad7a,0x03d0ccf2,0x48d4aa38,0x819a7c03,0x80acb338,0x6e17cecc,0x9bc7c89e,0x03be1d82,0x46736b8b +.long 0xc0432f96,0xd65d7b60,0xdeb5442f,0xddebe7a3,0x7dff69a2,0x79a25307,0x02cf3122,0x37a56d94,0xf2350d0a,0x8bab8aed,0x037b0d9a,0x13c3f276,0x44c65cae,0xc664957c,0xc2e71a88,0x88b44089 +.long 0x5cb02664,0xdb88e5a3,0x8686c72e,0x5d4c0bf1,0xa682d53e,0xea3d9b62,0x0b2ad431,0x9b605ef4,0xc69645d0,0x71bac202,0x6a1b66e7,0xa115f03a,0x158f4dc4,0xfe2c563a,0x4d12a78c,0xf715b3a0 +.long 0xd413213a,0x8f7f0a48,0xc04becdb,0x2035806d,0x5d8587f5,0xecd34a99,0x9f6d3a71,0x4d8c3079,0x8d95a8f6,0x1b2a2a67,0xf2110d0d,0xc58c9d7d,0xcf8fba3f,0xdeee81d5,0x0c7cdf68,0xa42be3c0 +.long 0xd43b5eaa,0x2126f742,0xdfa59b85,0x054a0766,0x126bfd45,0x9d0d5e36,0x384f8a8f,0xa1f8fbd7,0xd563fccc,0x317680f5,0xf280a928,0x48ca5055,0x27b578cf,0xe00b81b2,0x2994a514,0x10aad918 +.long 0xb7bdc953,0xd9e07b62,0x5bc086dd,0x9f0f6ff2,0x655eee77,0x09d1ccff,0x5bef7df1,0x45475f79,0x86f702cc,0x3faa28fa,0x0f021f07,0x92e60905,0x7f8fa8c6,0xe9e62968,0xf036ea2c,0xbd71419a +.long 0x6028da9a,0x171ee1cc,0xc251f573,0x5352fe1a,0x3fa997f4,0xf8ff236e,0xa5749d5f,0xd831b6c9,0xe350e2c2,0x7c872e1d,0x1e0ce403,0xc56240d9,0x6974f5cb,0xf9deb077,0x961c3728,0x7d50ba87 +.long 0x5a3a2518,0xd6f89426,0xc6303d43,0xcf817799,0x619e5696,0x510a0471,0x3a5e307b,0xab049ff6,0xfeb13ec7,0xe4cdf9b0,0x9d8ff90c,0xd5e97117,0x9afa96af,0xf6f64d06,0x9d2012a2,0x00d0bf5e +.long 0x358bcdc0,0xe63f301f,0x0a9d47f8,0x07689e99,0x4f43d43a,0x1f689e2f,0x90920904,0x4d542a16,0x9ca0a707,0xaea293d5,0x8ac68065,0xd061fe45,0x0090008c,0x1033bf1b,0xc08a6db6,0x29749558 +.long 0xc1d5d034,0x74b5fc59,0x67e215e0,0xf712e9f6,0x860200e6,0xfd520cbd,0x3ea22588,0x0229acb4,0xfff0c82e,0x9cd1e14c,0x59c69e73,0x87684b62,0x96ccb989,0xda85e61c,0xa3d06493,0x2d5dbb02 +.long 0xe86b173c,0xf22ad33a,0xa79ff0e3,0xe8e41ea5,0xdd0d0c10,0x01d2d725,0x032d28f9,0x31f39088,0x7829839e,0x7b3f71e1,0x4502ae58,0x0cf691b4,0xbefc6115,0xef658dbd,0xb3ab5314,0xa5cd6ee5 +.long 0x5f1d2347,0x206c8d7b,0x4cc2253a,0x794645ba,0x58389e08,0xd517d8ff,0x9f847288,0x4fa20dee,0xd797770a,0xeba072d8,0xbf429e26,0x7360c91d,0x80af8279,0x7200a3b3,0x82dadce3,0x6a1c9150 +.long 0xc35d8794,0x0ee6d3a7,0x0356bae5,0x042e6558,0x643322fd,0x9f59698d,0x50a61967,0x9379ae15,0xfcc9981e,0x64b9ae62,0x6d2934c6,0xaed3d631,0x5e4e65eb,0x2454b302,0xf9950428,0xab09f647 +.long 0x22248acc,0xb2083a12,0x3264e366,0x1f6ec0ef,0x5afdee28,0x5659b704,0xe6430bb5,0x7a823a40,0xe1900a79,0x24592a04,0xc9ee6576,0xcde09d4a,0x4b5ea54a,0x52b6463f,0xd3ca65a7,0x1efe9ed3 +.long 0x305406dd,0xe27a6dbe,0xdd5d1957,0x8eb7dc7f,0x387d4d8f,0xf54a6876,0xc7762de4,0x9c479409,0x99b30778,0xbe4d5b5d,0x6e793682,0x25380c56,0xdac740e3,0x602d37f3,0x1566e4ae,0x140deabe +.long 0xafd32acf,0x4481d067,0xe1f71ccf,0xd8f0fcca,0xb596f2da,0xd208dd0c,0x9aad93f9,0xd049d730,0x42ab580e,0xc79f263d,0x23f707b4,0x09411bb1,0x835e0eda,0x8cfde1ff,0x90f03402,0x72707490 +.long 0xc49a861e,0xeaee6126,0xe14f0d06,0x024f3b65,0xc69bfc17,0x51a3f1e8,0xa7686381,0xc3c3a8e9,0xb103d4c8,0x3400752c,0x9218b36b,0x02bc4613,0x7651504a,0xc67f75eb,0xd02aebfa,0xd6848b56 +.long 0xc30fa92b,0xbd9802e6,0x9a552784,0x5a70d96d,0x3f83169b,0x9085c4ea,0x06908228,0xfa9423bb,0xfe97a5b9,0x2ffebe12,0x71b99118,0x85da6049,0x63178846,0x9cbc2f7f,0x9153218e,0xfd96bc70 +.long 0x1782269b,0x958381db,0x2597e550,0xae34bf79,0x5f385153,0xbb5c6064,0xe3088048,0x6f0e96af,0x77884456,0xbf6a0215,0x69310ea7,0xb3b5688c,0x04fad2de,0x17c94295,0x17896d4d,0xe020f0e5 +.long 0x0976505f,0x730ba0ab,0x095e2ec5,0x567f6813,0x6331ab71,0x47062010,0x41d22b9f,0x72cfa977,0x8a2373da,0x33e55ead,0x7ba45a68,0xa8d0d5f4,0x03029d15,0xba1d8f9c,0xfc55b9f3,0x8f34f1cc +.long 0xbbe5a1a9,0xcca4428d,0x3126bd67,0x8187fd5f,0x48105826,0x0036973a,0xb8bd61a0,0xa39b6663,0x2d65a808,0x6d42deef,0x94636b19,0x4969044f,0xdd5d564c,0xf611ee47,0xd2873077,0x7b2f3a49 +.long 0x300eb294,0x94157d45,0x169c1494,0x2b2a656e,0xd3a47aa9,0xc000dd76,0xa6243ea4,0xa2864e4f,0xdb89842e,0x82716c47,0x61479fb7,0x12dfd7d7,0xe0b2f6dc,0x3b9a2c56,0xd7f85d67,0x46be862a +.long 0x0f82b214,0x03b0d8dd,0xf103cbc6,0x460c34f9,0x18d79e19,0xf32e5c03,0xa84117f8,0x8b8888ba,0xc0722677,0x8f3c37dc,0x1c1c0f27,0x10d21be9,0xe0f7a0c6,0xd47c8468,0xadecc0e0,0x9bf02213 +.long 0x42b48b99,0x0baa7d12,0x48424096,0x1bcb665d,0xebfb5cfb,0x8b847cd6,0x9ad4d10d,0x87c2ae56,0x0de36726,0xf1cbb122,0x3fdfbd21,0xe7043c68,0x4e79d460,0x4bd0826a,0x4bd1a2cb,0x11f5e598 +.long 0xb7fe7b6e,0x97554160,0x400a3fb2,0x7d16189a,0xe328ca1e,0xd73e9bea,0xe793d8cc,0x0dd04b97,0x506db8cc,0xa9c83c9b,0xcf38814c,0x5cd47aae,0xb64b45e6,0x26fc430d,0xd818ea84,0x079b5499 +.long 0xc1c24a3b,0xebb01102,0x1c161c1a,0xca24e568,0x36f00a4a,0x103eea69,0x76176c7b,0x9ad76ee8,0x538e0ff7,0x97451fc2,0x6604b3b0,0x94f89809,0x3249cfd7,0x6311436e,0x41224f69,0x27b4a7bd +.long 0xe0ac2941,0x03b5d21a,0xc2d31937,0x279b0254,0xcac992d0,0x3307c052,0xefa8b1f3,0x6aa7cb92,0x0d37c7a5,0x5a182580,0x342d5422,0x13380c37,0xd5d2ef92,0x92ac2d66,0x030c63c6,0x035a70c9 +.long 0x4ce4f152,0xc16025dd,0xf9df7c06,0x1f419a71,0x91e4bb14,0x6d5b2214,0x839fb4ce,0xfc43c6cc,0x925d6b2d,0x49f06591,0x62186598,0x4b37d9d3,0xd01b1629,0x8c54a971,0x51d50e05,0xe1a9c29f +.long 0x71ba1861,0x5109b785,0xd0c8f93d,0x48b22d5c,0x8633bb93,0xe8fa84a7,0x5aebbd08,0x53fba6ba,0xe5eea7d8,0x7ff27df3,0x68ca7158,0x521c8796,0xce6f1a05,0xb9d5133b,0xfd0ebee4,0x2d50cd53 +.long 0xc5a3ef16,0xc82115d6,0xba079221,0x993eff9d,0x4b5da81c,0xe4da2c5e,0x8033fd85,0x9a89dbdb,0x2b892891,0x60819ebf,0x5d14a4d5,0x53902b21,0xd7fda421,0x6ac35051,0x61c83284,0xcc6ab885 +.long 0xf74cff17,0x14eba133,0xecb813f2,0x240aaa03,0x6f665bee,0xcfbb6540,0xa425ad73,0x084b1fe4,0xd081f6a6,0x009d5d16,0xeef82c90,0x35304fe8,0xaa9eaa22,0xf20346d5,0xac1c91e3,0x0ada9f07 +.long 0x968a6144,0xa6e21678,0x07b31a1e,0x54c1f77c,0x5781fbe1,0xd6bb787e,0xe31f1c4a,0x61bd2ee0,0x781105fc,0xf25aa1e9,0x7b2f8e80,0x9cf2971f,0xcdff919b,0x26d15412,0x34bc896e,0x01db4ebe +.long 0xb40df1cf,0x7d9b3e23,0x94e971b4,0x59337373,0x669cf921,0xbf57bd14,0x0c1a1064,0x865daedf,0x83279125,0x3eb70bd3,0x34ecdaab,0xbc3d5b9f,0x5f755caf,0x91e3ed7e,0xd41e6f02,0x49699f54 +.long 0xd4a7a15b,0x185770e1,0xeaac87e7,0x08f3587a,0x473133ea,0x352018db,0x04fd30fc,0x674ce719,0x088b3e0e,0x7b8d9835,0x5d0d47a1,0x7a0356a9,0x6474a3c4,0x9d9e7659,0xff66966c,0x61ea48a7 +.long 0x0f3e4834,0x30417758,0x17a9afcb,0xfdbb21c2,0x2f9a67b3,0x756fa17f,0xa245c1a8,0x2a6b2421,0x4af02291,0x64be2794,0x2a5804fe,0xade465c6,0xa6f08fd7,0x8dffbd39,0xaa14403b,0xc4efa84c +.long 0x442b0f5c,0xa1b91b2a,0xcf997736,0xb748e317,0xcee90e16,0x8d1b62bf,0x0b2078c0,0x907ae271,0x0c9bcddd,0xdf31534b,0x39adce83,0x043fb054,0xd826846a,0x99031043,0xb144f393,0x61a9c0d6 +.long 0x47718427,0xdab48046,0x6e830f8b,0xdf17ff9b,0xe49a1347,0x408d7ee8,0x91c1d4ae,0x6ac71e23,0x1defd73c,0xc8cbb9fd,0xbbbbfec5,0x19840657,0x9e7ef8ea,0x39db1cb5,0x64105f30,0x78aa8296 +.long 0xa3738c29,0xa3d9b7f0,0xbc3250a3,0x0a2f235a,0x445e4caf,0x55e506f6,0x33475f7a,0x0974f73d,0x5ba2f5a8,0xd37dbba3,0x6af40066,0x542c6e63,0xc5d73e2c,0x26d99b53,0x6c3ca33e,0x06060d7d +.long 0x065fef4a,0xcdbef1c2,0xfd5b92e3,0x77e60f7d,0x26708350,0xd7c549f0,0x34f121bf,0x201b3ad0,0x0334fc14,0x5fcac2a1,0x344552f6,0x8a9a9e09,0x97653082,0x7dd8a1d3,0x79d4f289,0x5fc0738f +.long 0x17d2d8c3,0x787d244d,0x70830684,0xeffc6345,0xe4f73ae5,0x5ddb96dd,0x172549a5,0x8efb14b1,0x2245ae7a,0x6eb73eee,0xea11f13e,0xbca4061e,0x30b01f5d,0xb577421d,0x782e152c,0xaa688b24 +.long 0xbd3502ba,0x67608e71,0xb4de75a0,0x4ef41f24,0xfd6125e5,0xb08dde5e,0xa409543f,0xde484825,0x65cc2295,0x1f198d98,0x6e0edfa2,0x428a3771,0xadf35fc7,0x4f9697a2,0xf7cac3c7,0x01a43c79 +.long 0x0fd3659a,0xb05d7059,0xbb7f2d9a,0x8927f30c,0x8cf984d3,0x4023d1ac,0x02897a45,0x32125ed3,0x3d414205,0xfb572dad,0xe3fa82a9,0x73000ef2,0xf10a5581,0x4c0868e9,0x6b0b3ca5,0x5b61fc67 +.long 0x7cae440c,0xc1258d5b,0x402b7531,0x21c08b41,0xde932321,0xf61a8955,0x2d1408af,0x3568faf8,0x9ecf965b,0x71b15e99,0xe917276f,0xf14ed248,0x820cf9e2,0xc6f4caa1,0x18d83c7e,0x681b20b2 +.long 0xc6c01120,0x6cde738d,0xae70e0db,0x71db0813,0x74afe18c,0x95fc0644,0x129e2be7,0x34619053,0xdb2a3b15,0x80615cea,0xdb4c7073,0x0a49a19e,0x8fd2d367,0x0e1b84c8,0x033fb8aa,0xd74bf462 +.long 0x533ef217,0x889f6d65,0xc3ca2e87,0x7158c7e4,0xdc2b4167,0xfb670dfb,0x844c257f,0x75910a01,0xcf88577d,0xf336bf07,0xe45e2ace,0x22245250,0x7ca23d85,0x2ed92e8d,0x2b812f58,0x29f8be4c +.long 0x076fe12b,0xdd9ebaa7,0xae1537f9,0x3f2400cb,0x17bdfb46,0x1aa93528,0x67883b41,0xc0f98430,0x0170911d,0x5590ede1,0x34d4b17f,0x7562f5bb,0x1826b8d2,0xe1fa1df2,0x6bd80d59,0xb40b796a +.long 0x3467ba92,0xd65bf197,0xf70954b0,0x8c9b46db,0x0e78f15d,0x97c8a0f3,0x85a4c961,0xa8f3a69a,0x61e4ce9b,0x4242660f,0x6ea6790c,0xbf06aab3,0xec986416,0xc6706f8e,0x9a9fc225,0x9e56dec1 +.long 0x9a9898d9,0x527c46f4,0x5633cdef,0xd799e77b,0x7d9e4297,0x24eacc16,0x6b1cb734,0xabb61cea,0xf778443c,0xbee2e8a7,0x29de2fe6,0x3bb42bf1,0x3003bb6f,0xcbed86a1,0xd781cdf6,0xd3918e6c +.long 0x9a5103f1,0x4bee3271,0xf50eac06,0x5243efc6,0x6adcc119,0xb8e122cb,0xc0b80a08,0x1b7faa84,0x6dfcd08c,0x32c3d1bd,0x0be427de,0x129dec4e,0x1d263c83,0x98ab679c,0xcef64eff,0xafc83cb7 +.long 0x2fa6be76,0x85eb6088,0x1328cbfe,0x892585fb,0xcf618dda,0xc154d3ed,0x3abaf26e,0xc44f601b,0x2be1fdfd,0x7bf57d0b,0x21137fee,0xa833bd2d,0x2db591a8,0x9353af36,0x5562a056,0xc76f26dc +.long 0x3fdf5a51,0x1d87e47d,0x55c9cab0,0x7afb5f93,0x89e0586e,0x91bbf58f,0x0d843709,0x7c72c018,0x99b5c3dc,0xa9a5aafb,0x3844aeb0,0xa48a0f1d,0xb667e482,0x7178b7dd,0x6e23a59a,0x453985e9 +.long 0x01b25dd8,0x4a54c860,0xfb897c8a,0x0dd37f48,0x0ea90cd9,0x5f8aa610,0x16d5830d,0xc8892c68,0xef514ca5,0xeb4befc0,0xe72c9ee6,0x478eb679,0xdbc40d5f,0x9bca20da,0xdde4f64a,0xf015de21 +.long 0xeaf4b8a5,0xaa6a4de0,0x4bc60e32,0x68cfd9ca,0x7fd15e70,0x668a4b01,0xf27dc09d,0xd9f0694a,0xba708bcd,0xf6c3cad5,0x5bb95c2a,0x5cd2ba69,0x33c0a58f,0xaa28c1d3,0xabc77870,0x23e274e3 +.long 0xdfd20a4a,0x44c3692d,0x81a66653,0x091c5fd3,0x09a0757d,0x6c0bb691,0x667343ea,0x9072e8b9,0x80848bec,0x31d40eb0,0x79fd36cc,0x95bd480a,0x65ed43f5,0x01a77c61,0x2e0d40bf,0xafccd127 +.long 0x1cc1884b,0xeccfc82d,0x5d4753b4,0xc85ac201,0x658e099f,0xc7a6caac,0x04b27390,0xcf46369e,0x506467ea,0xe2e7d049,0x37cdeccc,0x481b63a2,0xed80143a,0x4029abd8,0xbcb00b88,0x28bfe3c7 +.long 0x0643d84a,0x3bec1009,0xabd11041,0x885f3668,0xf83a34d6,0xdb02432c,0x719ceebe,0x32f7b360,0xdad1fe7a,0xf06c7837,0x5441a0b0,0x60a157a9,0xe2d47550,0x704970e9,0x271b9020,0xcd2bd553 +.long 0x33e24a0b,0xff57f82f,0xf2565079,0x9cbee23f,0xeb5f5825,0x16353427,0xe948d662,0x276feec4,0xda10032b,0xd1b62bc6,0xf0e72a53,0x718351dd,0x2420e7ba,0x93452076,0x3a00118d,0x96368fff +.long 0x150a49e4,0x00ce2d26,0x3f04706b,0x0c28b636,0x58b196d0,0xbad65a46,0xec9f8b7c,0x6c8455fc,0x2d71867e,0xe90c895f,0xedf9f38c,0x5c0be31b,0xd8f6ec04,0x2a37a15e,0x8cd85251,0x239639e7 +.long 0x9c7c4c6b,0xd8975315,0xd7409af7,0x603aa3c0,0x007132fb,0xb8d53d0c,0xa6849238,0x68d12af7,0xbf5d9279,0xbe0607e7,0xaada74ce,0x9aa50055,0xba7e8ccb,0xe81079cb,0xa5f4ff5e,0x610c71d1 +.long 0x5aa07093,0x9e2ee1a7,0xa75da47c,0xca84004b,0x3de75401,0x074d3951,0xbb311592,0xf938f756,0x00a43421,0x96197618,0x07bc78c8,0x39a25362,0x0a171276,0x278f710a,0x8d1a8f08,0xb28446ea +.long 0xe3b6a661,0x184781bf,0xe6d279f7,0x7751cb1d,0xc59eb662,0xf8ff95d6,0x58d3dea7,0x186d90b7,0xdfb4f754,0x0e4bb6c1,0x2b2801dc,0x5c5cf56b,0x1f54564d,0xc561e452,0xf0dd7f13,0xb4fb8c60 +.long 0x33ff98c7,0xf8849630,0xcf17769c,0x9619fffa,0x1bfdd80a,0xf8090bf6,0x422cfe63,0x14d9a149,0x6f6df9ea,0xb354c360,0x218f17ea,0xdbcf770d,0x79eb3480,0x207db7c8,0x559b6a26,0x213dbda8 +.long 0x29fc81b3,0xac4c200b,0x171d87c1,0xebc3e09f,0x1481aa9e,0x91799530,0x92e114fa,0x051b92e1,0xecb5537f,0xdf8f92e9,0x290c7483,0x44b1b2cc,0x2adeb016,0xa711455a,0x81a10c2c,0x964b6856 +.long 0xcec03623,0x4f159d99,0xef3271ea,0x05532225,0xc5ee4849,0xb231bea3,0x7094f103,0x57a54f50,0x9598b352,0x3e2d421d,0x67412ab4,0xe865a49c,0x1cc3a912,0xd2998a25,0x0c74d65d,0x5d092808 +.long 0x4088567a,0x73f45908,0x1f214a61,0xeb6b280e,0xcaf0c13d,0x8c9adc34,0xf561fb80,0x39d12938,0xbc6edfb4,0xb2dc3a5e,0xfe4d210e,0x7485b1b1,0xe186ae72,0x062e0400,0x6eeb3b88,0x91e32d5c +.long 0x4be59224,0x6df574d7,0x716d55f3,0xebc88ccc,0xcad6ed33,0x26c2e6d0,0x0d3e8b10,0xc6e21e7d,0x5bcc36bb,0x2cc5840e,0x7da74f69,0x9292445e,0x4e5193a8,0x8be8d321,0x8df06413,0x3ec23629 +.long 0xb134defa,0xc7e9ae85,0x1bb2d475,0x6073b1d0,0x2863c00d,0xb9ad615e,0x525f4ac4,0x9e29493d,0x4e9acf4f,0xc32b1dea,0xa50db88d,0x3e1f01c8,0x04da916c,0xb05d70ea,0xd865803e,0x714b0d0a +.long 0x9920cb5e,0x4bd493fc,0x92c7a3ac,0x5b44b1f7,0xbcec9235,0xa2a77293,0xcd378553,0x5ee06e87,0xda621607,0xceff8173,0x99f5d290,0x2bb03e4c,0xa6f734ac,0x2945106a,0xd25c4732,0xb5056604 +.long 0xe079afee,0x5945920c,0x6789831f,0x686e17a0,0xb74a5ae5,0x5966bee8,0x1e258d46,0x38a673a2,0x83141c95,0xbd1cc1f2,0x0e96e486,0x3b2ecf4f,0x74e5fc78,0xcd3aa896,0x2482fa7a,0x415ec10c +.long 0x80503380,0x15234419,0xd314b392,0x513d917a,0x63caecae,0xb0b52f4e,0x2dc7780b,0x07bf22ad,0xe4306839,0xe761e8a1,0x5dd7feaa,0x1b3be962,0x74c778f1,0x4fe728de,0x5e0070f6,0xf1fa0bda +.long 0x6ec3f510,0x85205a31,0xd2980475,0x2c7e4a14,0x6f30ebfd,0xde3c19c0,0xd4b7e644,0xdb1c1f38,0x5dce364a,0xfe291a75,0x058f5be3,0xb7b22a3c,0x37fea38c,0x2cd2c302,0x2e17be17,0x2930967a +.long 0x0c061c65,0x87f009de,0xedc6ed44,0xcb014aac,0x3bafb1eb,0x49bd1cb4,0x282d3688,0x81bd8b5c,0xf01a17af,0x1cdab87e,0xe710063b,0x21f37ac4,0x42fc8193,0x5a6c5676,0x56a6015c,0xf4753e70 +.long 0xa15b0a44,0x020f795e,0x8958a958,0x8f37c8d7,0xa4b675b5,0x63b7e89b,0x0fc31aea,0xb4fb0c0c,0xa7ff1f2e,0xed95e639,0x619614fb,0x9880f5a3,0x947151ab,0xdeb6ff02,0xa868dcdb,0x5bc5118c +.long 0x4c20cea5,0xd8da2055,0x14c4d69a,0xcac2776e,0x622d599b,0xcccb22c1,0x68a9bb50,0xa4ddb653,0x1b4941b4,0x2c4ff151,0x6efba588,0xe1ff19b4,0xc48345e0,0x35034363,0x1e29dfc4,0x45542e3d +.long 0x349f7aed,0xf197cb91,0x8fca8420,0x3b2b5a00,0x23aaf6d8,0x7c175ee8,0x35af32b6,0x54dcf421,0x27d6561e,0x0ba14307,0xd175b1e2,0x879d5ee4,0x99807db5,0xc7c43673,0x9cd55bcd,0x77a54455 +.long 0x0105c072,0xe6c2ff13,0x8dda7da4,0x18f7a99f,0x0e2d35c1,0x4c301820,0xd9cc6c82,0x06a53ca0,0xf1aa1d9e,0xaa21cc1e,0x4a75b1e8,0x32414334,0x0ebe9fdc,0x2a6d1328,0x98a4755a,0x16bd173f +.long 0x2133ffd9,0xfbb9b245,0x830f1a20,0x39a8b2f1,0xd5a1f52a,0x484bc97d,0xa40eddf8,0xd6aebf56,0x76ccdac6,0x32257acb,0x1586ff27,0xaf4d36ec,0xf8de7dd1,0x8eaa8863,0x88647c16,0x0045d5cf +.long 0xc005979d,0xa6f3d574,0x6a40e350,0xc2072b42,0x8de2ecf9,0xfca5c156,0xa515344e,0xa8c8bf5b,0x114df14a,0x97aee555,0xfdc5ec6b,0xd4374a4d,0x2ca85418,0x754cc28f,0xd3c41f78,0x71cb9e27 +.long 0x03605c39,0x89105079,0xa142c96c,0xf0843d9e,0x16923684,0xf3744934,0xfa0a2893,0x732caa2f,0x61160170,0xb2e8c270,0x437fbaa3,0xc32788cc,0xa6eda3ac,0x39cd818e,0x9e2b2e07,0xe2e94239 +.long 0x0260e52a,0x6967d39b,0x90653325,0xd42585cc,0x21ca7954,0x0d9bd605,0x81ed57b3,0x4fa20877,0xe34a0bbe,0x60c1eff8,0x84f6ef64,0x56b0040c,0xb1af8483,0x28be2b24,0xf5531614,0xb2278163 +.long 0x5922ac1c,0x8df27545,0xa52b3f63,0xa7b3ef5c,0x71de57c4,0x8e77b214,0x834c008b,0x31682c10,0x4bd55d31,0xc76824f0,0x17b61c71,0xb6d1c086,0xc2a5089d,0x31db0903,0x184e5d3f,0x9c092172 +.long 0xc00cc638,0xdd7ced5b,0x61278fc2,0x1a2015eb,0x6a37f8d6,0x2e8e5288,0xe79933ad,0xc457786f,0x2c51211a,0xb3fe4cce,0x24c20498,0xad9b10b2,0xd28db5e5,0x90d87a4f,0x3aca2fc3,0x698cd105 +.long 0xe91b536d,0x4f112d07,0x9eba09d6,0xceb982f2,0x197c396f,0x3c157b2c,0x7b66eb24,0xe23c2d41,0x3f330d37,0x480c57d9,0x79108deb,0xb3a4c8a1,0xcb199ce5,0x702388de,0xb944a8d4,0x0b019211 +.long 0x840bb336,0x24f2a692,0xa669fa7b,0x7c353bdc,0xdec9c300,0xda20d6fc,0xa13a4f17,0x625fbe2f,0xdbc17328,0xa2b1b61a,0xa9515621,0x008965bf,0xc620ff46,0x49690939,0x8717e91c,0x182dd27d +.long 0xea6c3997,0x5ace5035,0xc2610bef,0x54259aaa,0x3c80dd39,0xef18bb3f,0x5fc3fa39,0x6910b95b,0x43e09aee,0xfce2f510,0xa7675665,0xced56c9f,0xd872db61,0x10e265ac,0xae9fce69,0x6982812e +.long 0xce800998,0x29be11c6,0xb90360d9,0x72bb1752,0x5a4ad590,0x2c193197,0x9fc1dbc0,0x2ba2f548,0xe490ebe0,0x7fe4eebb,0x7fae11c0,0x12a0a4cd,0xe903ba37,0x7197cf81,0xde1c6dd8,0xcf7d4aa8 +.long 0x3fd5684c,0x92af6bf4,0x80360aa1,0x2b26eecf,0x00546a82,0xbd960f30,0xf59ad8fe,0x407b3c43,0x249c82ba,0x86cae5fe,0x2463744c,0x9e0faec7,0x94916272,0x87f551e8,0x6ceb0615,0x033f9344 +.long 0x8be82e84,0x1e5eb0d1,0x7a582fef,0x89967f0e,0xa6e921fa,0xbcf687d5,0xd37a09ba,0xdfee4cf3,0xb493c465,0x94f06965,0x7635c030,0x638b9a1c,0x66f05e9f,0x76667864,0xc04da725,0xccaf6808 +.long 0x768fccfc,0xca2eb690,0xb835b362,0xf402d37d,0xe2fdfcce,0x0efac0d0,0xb638d990,0xefc9cdef,0xd1669a8b,0x2af12b72,0x5774ccbd,0x33c536bc,0xfb34870e,0x30b21909,0x7df25aca,0xc38fa2f7 +.long 0xbf81f3f5,0x74c5f02b,0xaf7e4581,0x0525a5ae,0x433c54ae,0x88d2aaba,0x806a56c5,0xed9775db,0xc0edb37d,0xd320738a,0x66cc1f51,0x25fdb6ee,0x10600d76,0xac661d17,0xbdd1ed76,0x931ec1f3 +.long 0x19ee43f1,0x65c11d62,0x60829d97,0x5cd57c3e,0x984be6e8,0xd26c91a3,0x8b0c53bd,0xf08d9309,0xc016e4ea,0x94bc9e5b,0x11d43d2b,0xd3916839,0x73701155,0x886c5ad7,0x20b00715,0xe0377626 +.long 0xaa80ba59,0x7f01c9ec,0x68538e51,0x3083411a,0xe88128af,0x970370f1,0x91dec14b,0x625cc3db,0x01ac3107,0xfef9666c,0xd5057ac3,0xb2a8d577,0x92be5df7,0xb0f26299,0x00353924,0xf579c8e5 +.long 0x1341ed7a,0xb8fa3d93,0xa7b59d49,0x4223272c,0x83b8c4a4,0x3dcb1947,0xed1302e4,0x4e413c01,0xe17e44ce,0x6d999127,0x33b3adfb,0xee86bf75,0x25aa96ca,0xf6902fe6,0xe5aae47d,0xb73540e4 +.long 0x1b4a158c,0x32801d7b,0x27e2a369,0xe571c99e,0x10d9f197,0x40cb76c0,0x3167c0ae,0xc308c289,0xeb7958f2,0xa6ef9dd3,0x300879b1,0xa7226dfc,0x7edf0636,0x6cd0b362,0x7bc37eed,0x4efbce6c +.long 0x8d699021,0x75f92a05,0x772566e3,0x586d4c79,0x761ad23a,0x378ca5f1,0x1465a8ac,0x650d86fc,0x842ba251,0x7a4ed457,0x42234933,0x6b65e3e6,0x31aad657,0xaf1543b7,0xcbfec369,0xa4cefe98 +.long 0x9f47befb,0xb587da90,0x41312d13,0x6562e9fb,0xeff1cefe,0xa691ea59,0x05fc4cf6,0xcc30477a,0x0b0ffd3d,0xa1632461,0x5b355956,0xa1f16f3b,0x4224ec24,0x5b148d53,0xf977012a,0xdc834e7b +.long 0xb2c69dbc,0x7bfc5e75,0x03c3da6c,0x3aa77a29,0xca910271,0xde0df03c,0x7806dc55,0xcbd5ca4a,0x6db476cb,0xe1ca5807,0x5f37a31e,0xfde15d62,0xf41af416,0xf49af520,0x7d342db5,0x96c5c5b1 +.long 0xeb4ceb9b,0x155c43b7,0x4e77371a,0x2e993010,0x675d43af,0x1d2987da,0x8599fd72,0xef2bc1c0,0x9342f6b2,0x96894b7b,0x7c8e71f0,0x201eadf2,0x4a1f3efc,0xf3479d9f,0x702a9704,0xe0f8a742 +.long 0xb3eba40c,0xeafd44b6,0xc1c1e0d0,0xf9739f29,0x619d505e,0x0091471a,0x9d7c263e,0xc15f9c96,0x83afbe33,0x5be47285,0x04f1e092,0xa3b6d6af,0x751a9d11,0xe76526b9,0x9a4ae4d2,0x2ec5b26d +.long 0x02f6fb8d,0xeb66f4d9,0x96912164,0x4063c561,0x80ef3000,0xeb7050c1,0xeaa5b3f0,0x288d1c33,0x07806fd8,0xe87c68d6,0x4bbbf50f,0xb2f7f9d5,0xac8d6627,0x25972f3a,0x10e8c13b,0xf8547774 +.long 0x872b4a60,0xcc50ef6c,0x4613521b,0xab2a34a4,0x983e15d1,0x39c5c190,0x59905512,0x61dde5df,0x9f2275f3,0xe417f621,0x451d894b,0x0750c8b6,0x78b0bdaa,0x75b04ab9,0x458589bd,0x3bfd9fd4 +.long 0xee9120b6,0xf1013e30,0x23a4743e,0x2b51af93,0x48d14d9e,0xea96ffae,0x698a1d32,0x71dc0dbe,0x0180cca4,0x914962d2,0xc3568963,0x1ae60677,0x437bc444,0x8cf227b1,0xc9962c7a,0xc650c83b +.long 0xfe7ccfc4,0x23c2c7dd,0x1b929d48,0xf925c89d,0x06783c33,0x4460f74b,0xa590475a,0xac2c8d49,0xb807bba0,0xfb40b407,0x69ff8f3a,0x9d1e362d,0xcbef64a4,0xa33e9681,0x332fb4b2,0x67ece5fa +.long 0x739f10e3,0x6900a99b,0xff525925,0xc3341ca9,0xa9e2d041,0xee18a626,0x29580ddd,0xa5a83685,0x9d7de3cd,0xf3470c81,0x2062cf9c,0xedf02586,0xc010edb0,0xf43522fa,0x13a4b1ae,0x30314135 +.long 0xdb22b94b,0xc792e02a,0xa1eaa45b,0x993d8ae9,0xcd1e1c63,0x8aad6cd3,0xc5ce688a,0x89529ca7,0xe572a253,0x2ccee3aa,0x02a21efb,0xe02b6438,0xc9430358,0xa7091b6e,0x9d7db504,0x06d1b1fa +.long 0xc4744733,0x58846d32,0x379f9e34,0x40517c71,0x130ef6ca,0x2f65655f,0xf1f3503f,0x526e4488,0x7ee4a976,0x8467bd17,0x921363d1,0x1d9dc913,0xb069e041,0xd8d24c33,0x2cdf7f51,0x5eb5da0a +.long 0x197b994f,0x1c0f3cb1,0x2843eae9,0x3c95a6c5,0xa6097ea5,0x7766ffc9,0xd723b867,0x7bea4093,0x4db378f9,0xb48e1f73,0xe37b77ac,0x70025b00,0xaf24ad46,0x943dc8e7,0x16d00a85,0xb98a15ac +.long 0x2743b004,0x3adc38ba,0x334415ee,0xb1c7f4f7,0x1e62d05a,0xea43df8f,0x9d76a3b6,0x32618905,0xa23a0f46,0x2fbd0bb5,0x6a01918c,0x5bc971db,0xb4743f94,0x7801d94a,0x676ae22b,0xb94df65e +.long 0xaf95894c,0xaafcbfab,0x276b2241,0x7b9bdc07,0x5bdda48b,0xeaf98362,0xa3fcb4df,0x5977faf2,0x052c4b5b,0xbed042ef,0x067591f0,0x9fe87f71,0x22f24ec7,0xc89c73ca,0xe64a9f1b,0x7d37fa9e +.long 0x15562627,0x2710841a,0xc243b034,0x2c01a613,0x2bc68609,0x1d135c56,0x8b03f1f6,0xc2ca1715,0x3eb81d82,0xc9966c2d,0x8f6df13e,0xc02abf4a,0x8f72b43b,0x77b34bd7,0x360c82b0,0xaff6218f +.long 0x8d55b9d2,0x0aa5726c,0x99e9bffb,0xdc0adbe9,0xefb9e72a,0x9097549c,0x9dfb3111,0x16755712,0xf26847f9,0xdd8bf984,0xdfb30cb7,0xbcb8e387,0x5171ef9c,0xc1fd32a7,0x389b363f,0x977f3fc7 +.long 0xf4babda0,0x116eaf2b,0xf7113c8e,0xfeab68bd,0xb7def526,0xd1e3f064,0xe0b3fa02,0x1ac30885,0x40142d9d,0x1c5a6e7b,0x30921c0b,0x839b5603,0x36a116a3,0x48f301fa,0xcfd9ee6d,0x380e1107 +.long 0x58854be1,0x7945ead8,0xcbd4d49d,0x4111c12e,0x3a29c2ef,0xece3b1ec,0x8d3616f5,0x6356d404,0x594d320e,0x9f0d6a8f,0xf651ccd2,0x0989316d,0x0f8fdde4,0x6c32117a,0xa26a9bbc,0x9abe5cc5 +.long 0x9723f671,0xcff560fb,0x7f3d593c,0x21b2a12d,0x24ba0696,0xe4cb18da,0xc3543384,0x186e2220,0x88312c29,0x722f64e0,0x17dc7752,0x94282a99,0x5a85ee89,0x62467bbf,0xf10076a0,0xf435c650 +.long 0x43b3a50b,0xc9ff1539,0x1a53efbc,0x7132130c,0xf7b0c5b7,0x31bfe063,0x4ea994cc,0xb0179a7d,0xc85f455b,0x12d064b3,0x8f6e0062,0x47259328,0xb875d6d9,0xf64e590b,0xad92bcc7,0x22dd6225 +.long 0xb9c3bd6d,0xb658038e,0xfbba27c8,0x00cdb0d6,0x1062c45d,0x0c681337,0x2d33407d,0xd8515b8c,0x8cbb5ecf,0xcb8f699e,0xc608d7d8,0x8c4347f8,0xbb3e00db,0x2c11850a,0xecb49d19,0x20a8dafd +.long 0x45ee2f40,0xbd781480,0x416b60cf,0x75e354af,0x8d49a8c4,0xde0b58a1,0xfa359536,0xe40e94e2,0x62accd76,0xbd4fa59f,0x8c762837,0x05cf466a,0x448c277b,0xb5abda99,0x48b13740,0x5a9e01bf +.long 0x326aad8d,0x9d457798,0xc396f7e7,0xbdef4954,0xc253e292,0x6fb274a2,0x1cfe53e7,0x2800bf0a,0x44438fd4,0x22426d31,0x5e259f9a,0xef233923,0x03f66264,0x4188503c,0x7f9fdfab,0x9e5e7f13 +.long 0x5fcc1aba,0x565eb76c,0x59b5bff8,0xea632548,0xaab6d3fa,0x5587c087,0x6ce39c1b,0x92b639ea,0x953b135c,0x0706e782,0x425268ef,0x7308912e,0x090e7469,0x599e92c7,0x9bc35e75,0x83b90f52 +.long 0x244975b3,0x4750b3d0,0x11965d72,0xf3a44358,0x9c8dc751,0x179c6774,0xd23d9ff0,0xff18cdfe,0x2028e247,0xc4013833,0xf3bfbc79,0x96e280e2,0xd0880a84,0xf60417bd,0x2a568151,0x263c9f3d +.long 0x2d2ce811,0x36be15b3,0xf8291d21,0x846dc0c2,0x789fcfdb,0x5cfa0ecb,0xd7535b9a,0x45a0beed,0x96d69af1,0xec8e9f07,0x599ab6dc,0x31a7c5b8,0xf9e2e09f,0xd36d45ef,0xdcee954b,0x3cf49ef1 +.long 0x086cff9b,0x6be34cf3,0x39a3360f,0x88dbd491,0x0dbfbd1d,0x1e96b8cc,0xcb7e2552,0xc1e5f7bf,0x28819d98,0x0547b214,0x7aea9dcb,0xc770dd9c,0x041d68c8,0xaef0d4c7,0x13cb9ba8,0xcc2b9818 +.long 0xfe86c607,0x7fc7bc76,0x502a9a95,0x6b7b9337,0xd14dab63,0x1948dc27,0xdae047be,0x249dd198,0xa981a202,0xe8356584,0x3a893387,0x3531dd18,0xc85c7209,0x1be11f90,0xe2a52b5a,0x93d2fe1e +.long 0xec6d6b97,0x8225bfe2,0xbd0aa5de,0x9cf6d6f4,0x54779f5f,0x911459cb,0x86aeb1f3,0x5649cddb,0x3f26ce5a,0x32133579,0x550f431e,0xc289a102,0x73b84c6f,0x559dcfda,0xee3ac4d7,0x84973819 +.long 0xf2606a82,0xb51e55e6,0x90f2fb57,0xe25f7061,0xb1a4e37c,0xacef6c2a,0x5dcf2706,0x864e359d,0x7ce57316,0x479e6b18,0x3a96b23d,0x2cab2500,0x8ef16df7,0xed489862,0xef3758b5,0x2056538c +.long 0xf15d3101,0xa7df865e,0x61b553d7,0x80c5533a,0x4ed14294,0x366e1997,0xb3c0bcd6,0x6620741f,0xedc45418,0x21d1d9c4,0xc1cc4a9d,0x005b859e,0xa1c462f0,0xdf01f630,0xf26820c7,0x15d06cf3 +.long 0x3484be47,0x9f7f24ee,0x4a0c902f,0x2ff33e96,0x5a0bc453,0x00bdf457,0x1aa238db,0x2378dfaf,0x856720f2,0x272420ec,0x96797291,0x2ad9d95b,0x768a1558,0xd1242cc6,0x5cc86aa8,0x2e287f8b +.long 0x990cecaa,0x796873d0,0x675d4080,0xade55f81,0x21f0cd84,0x2645eea3,0xb4e17d02,0x7a1efa0f,0x037cc061,0xf6858420,0xd5d43e12,0x682e05f0,0x27218710,0x59c36994,0x3f7cd2fc,0x85cbba4d +.long 0x7a3cd22a,0x726f9729,0x4a628397,0x9f8cd5dc,0xc23165ed,0x17b93ab9,0x122823d4,0xff5f5dbf,0x654a446d,0xc1e4e4b5,0x677257ba,0xd1a9496f,0xde766a56,0x6387ba94,0x521ec74a,0x23608bc8 +.long 0x6688c4d4,0x16a522d7,0x07373abd,0x9d6b4282,0xb42efaa3,0xa62f07ac,0xe3b90180,0xf73e00f7,0x49421c3e,0x36175fec,0x3dcf2678,0xc4e44f9b,0x7220f09f,0x76df436b,0x3aa8b6cf,0x172755fb +.long 0x446139cc,0xbab89d57,0x5fe0208f,0x0a0a6e02,0x11e5d399,0xcdbb63e2,0xa8977f0b,0x33ecaa12,0xf7c42664,0x59598b21,0xab65d08a,0xb3e91b32,0xf4502526,0x035822ee,0x720a82a9,0x1dcf0176 +.long 0x3d589e02,0x50f8598f,0xb1d63d2c,0xdf0478ff,0x1571cd07,0x8b8068bd,0xd79670cd,0x30c3aa4f,0x941ade7f,0x25e8fd4b,0x32790011,0x3d1debdc,0x3a3f9ff0,0x65b6dcbd,0x793de69c,0x282736a4 +.long 0xd41d3bd3,0xef69a0c3,0x07a26bde,0xb533b8c9,0xdb2edf9f,0xe2801d97,0xe1877af0,0xdc4a8269,0x3d590dbe,0x6c1c5851,0xee4e9357,0x84632f6b,0x79b33374,0xd36d36b7,0x9bbca2e6,0xb46833e3 +.long 0xf7fc0586,0x37893913,0x66bf4719,0x385315f7,0xb31855dc,0x72c56293,0x849061fe,0xd1416d4e,0x51047213,0xbeb3ab78,0xf040c996,0x447f6e61,0x638b1d0c,0xd06d310d,0xbad1522e,0xe28a413f +.long 0x82003f86,0x685a76cb,0x0bcdbca3,0x610d07f7,0x9ca4c455,0x6ff66021,0xcea10eec,0x7df39b87,0xe22db218,0xb9255f96,0x08a34c44,0x8cc6d9eb,0x859f9276,0xcd4ffb86,0x50d07335,0x8fa15eb2 +.long 0xcf2c24b5,0xdf553845,0x52f9c3ba,0x89f66a9f,0xe4a7ceb3,0x8f22b5b9,0x0e134686,0xaffef809,0x8eb8fac2,0x3e53e1c6,0x28aec98e,0x93c1e4eb,0x32a43bcb,0xb6b91ec5,0xb2d74a51,0x2dbfa947 +.long 0xca84bad7,0xe065d190,0xad58e65c,0xfb13919f,0xf1cb6e31,0x3c41718b,0x06d05c3f,0x688969f0,0x21264d45,0xd4f94ce7,0x7367532b,0xfdfb65e9,0x0945a39d,0x5b1be8b1,0x2b8baf3b,0x229f789c +.long 0x6f49f15d,0xd8f41f3e,0x907f0792,0x678ce828,0xfca6e867,0xc69ace82,0xd01dcc89,0x106451ae,0x19fc32d2,0x1bb4f7f0,0xb00c52d2,0x64633dfc,0xad9ea445,0x8f13549a,0xfb323705,0x99a3bf50 +.long 0x534d4dbc,0x0c9625a2,0xc2a2fea3,0x45b8f1d1,0xa530fc1a,0x76ec21a1,0x9e5bd734,0x4bac9c2a,0x7b4e3587,0x5996d76a,0x1182d9e3,0x0045cdee,0x1207f13d,0x1aee24b9,0x97345a41,0x66452e97 +.long 0x9f950cd0,0x16e5b054,0xd7fdd075,0x9cc72fb1,0x66249663,0x6edd61e7,0xf043cccb,0xde4caa4d,0x55c7ac17,0x11b1f57a,0x1a85e24d,0x779cbd44,0xe46081e7,0x78030f86,0x8e20f643,0xfd4a6032 +.long 0x0a750c0f,0xcc7a6488,0x4e548e83,0x39bacfe3,0x0c110f05,0x3d418c76,0xb1f11588,0x3e4daa4c,0x5ffc69ff,0x2733e7b5,0x92053127,0x46f147bc,0xd722df94,0x885b2434,0xe6fc6b7c,0x6a444f65 +.long 0xc3f16ea8,0x7a1a465a,0xb2f1d11c,0x115a461d,0x6c68a172,0x4767dd95,0xd13a4698,0x3392f2eb,0xe526cdc7,0xc7a99ccd,0x22292b81,0x8e537fdc,0xa6d39198,0x76d8cf69,0x2446852d,0xffc5ff43 +.long 0xa90567e6,0x97b14f7e,0xb6ae5cb7,0x513257b7,0x9f10903d,0x85454a3c,0x69bc3724,0xd8d2c9ad,0x6b29cb44,0x38da9324,0x77c8cbac,0xb540a21d,0x01918e42,0x9bbfe435,0x56c3614e,0xfffa707a +.long 0xd4e353b7,0x0ce4e3f1,0xef46b0a0,0x062d8a14,0x574b73fd,0x6408d5ab,0xd3273ffd,0xbc41d1c9,0x6be77800,0x3538e1e7,0xc5655031,0x71fe8b37,0x6b9b331a,0x1cd91621,0xbb388f73,0xad825d0b +.long 0x1cb76219,0x56c2e05b,0x71567e7e,0x0ec0bf91,0x61c4c910,0xe7076f86,0xbabc04d9,0xd67b085b,0x5e93a96a,0x9fb90459,0xfbdc249a,0x7526c1ea,0xecdd0bb7,0x0d44d367,0x9dc0d695,0x95399917 +.long 0x9e240d18,0x61360ee9,0xb4b94466,0x057cdcac,0x2fe5325c,0xe7667cd1,0x21974e3b,0x1fa297b5,0xdb083d76,0xfa4081e7,0xf206bd15,0x31993be6,0x14c19f8c,0x8949269b,0xa9d92357,0x21468d72 +.long 0xa4c506ec,0x2ccbc583,0xd1acfe97,0x957ed188,0x12f1aea2,0x8baed833,0x8325362d,0xef2a6cb4,0x8e195c43,0x130dde42,0x0e6050c6,0xc842025a,0x08686a5d,0x2da972a7,0xe508b4a8,0xb52999a1 +.long 0x10a5a8bd,0xd9f090b9,0x096864da,0xca91d249,0x3f67dbc1,0x8e6a93be,0xf5f4764c,0xacae6fba,0xd21411a0,0x1563c6e0,0xda0a4ad8,0x28fa787f,0x908c8030,0xd524491c,0x4c795f07,0x1257ba0e +.long 0xceca9754,0x83f49167,0x4b7939a0,0x426d2cf6,0x723fd0bf,0x2555e355,0xc4f144e2,0xa96e6d06,0x87880e61,0x4768a8dd,0xe508e4d5,0x15543815,0xb1b65e15,0x09d7e772,0xac302fa0,0x63439dd6 +.long 0xc14e35c2,0xb93f802f,0x4341333c,0x71735b7c,0x16d4f362,0x03a25104,0xbf433c8e,0x3f4d069b,0xf78f5a7c,0x0d83ae01,0x7c4eed07,0x50a8ffbe,0x76e10f83,0xc74f8906,0x9ddaf8e1,0x7d080966 +.long 0x698e04cc,0xb11df8e1,0x169005c8,0x877be203,0x4f3c6179,0x32749e8c,0x7853fc05,0x2dbc9d0a,0x9454d937,0x187d4f93,0xb4800e1b,0xe682ce9d,0x165e68e8,0xa9129ad8,0xbe7f785b,0x0fe29735 +.long 0x5b9e02b7,0x5303f40c,0x35ee04e8,0xa37c9692,0x34d6632b,0x5f46cc20,0x96ac545b,0x55ef72b2,0x7b91b062,0xabec5c1f,0xbb33e821,0x0a79e1c7,0x3a9f4117,0xbb04b428,0xfd2a475a,0x0de1f28f +.long 0x3a4434b4,0x31019ccf,0x1a7954dc,0xa3458111,0xe34972a7,0xa9dac80d,0x74f6b8dd,0xb043d054,0x11137b1a,0x021c319e,0xed5cc03f,0x00a754ce,0xcbea5ad4,0x0aa2c794,0x70c015b6,0x093e67f4 +.long 0xc97e3f6b,0x72cdfee9,0xb6da7461,0xc10bcab4,0xb59806b9,0x3b02d2fc,0xa1de6f47,0x85185e89,0x0eb6c4d4,0x39e6931f,0xd4fa5b04,0x4d4440bd,0x34be7eb8,0x5418786e,0x9d7259bc,0x6380e521 +.long 0xd598d710,0x20ac0351,0xcb3a4da4,0x272c4166,0xca71de1f,0xdb82fe1a,0xd8f54b0f,0x746e79f2,0x4b573e9b,0x6e7fc736,0xfd4b5040,0x75d03f46,0x0b98d87b,0x5c1cc36d,0x1f472da1,0x513ba3f1 +.long 0xabb177dd,0x79d0af26,0x7891d564,0xf82ab568,0x72232173,0x2b6768a9,0x8c1f6619,0xefbb3bb0,0xa6d18358,0xb29c11db,0xb0916d3a,0x519e2797,0x9188e290,0xd4dc18f0,0x98b0ca7f,0x648e86e3 +.long 0x983c38b5,0x859d3145,0x637abc8b,0xb14f176c,0xcaff7be6,0x2793fb9d,0x35a66a5a,0xebe5a55f,0x9f87dc59,0x7cec1dcd,0xfbdbf560,0x7c595cd3,0x26eb3257,0x5b543b22,0xc4c935fd,0x69080646 +.long 0x81e9ede3,0x7f2e4403,0xcaf6df0a,0x243c3894,0x1c073b11,0x7c605bb1,0xba6a4a62,0xcd06a541,0x49d4e2e5,0x29168949,0x4af66880,0x33649d07,0xe9a85035,0xbfc0c885,0xfc410f4b,0xb4e52113 +.long 0x78a6513b,0xdca3b706,0x9edb1943,0x92ea4a2a,0xdb6e2dd8,0x02642216,0x9fd57894,0x9b45d0b4,0xc69d11ae,0x114e70db,0x4c57595f,0x1477dd19,0xec77c272,0xbc2208b4,0xdb68f59c,0x95c5b4d7 +.long 0x42e532b7,0xb8c4fc63,0x9ae35290,0x386ba422,0xd201ecbc,0xfb5dda42,0xa0e38fd6,0x2353dc8b,0x68f7e978,0x9a0b85ea,0x2ad6d11f,0x96ec5682,0xe5f6886d,0x5e279d6c,0x3cb1914d,0xd3fe03cd +.long 0x7ea67c77,0xfe541fa4,0xe3ea810c,0x952bd2af,0x8d01d374,0x791fef56,0x0f11336e,0xa3a1c621,0xc7ec6d79,0x5ad0d5a9,0x3225c342,0xff7038af,0xbc69601b,0x003c6689,0x45e8747d,0x25059bc7 +.long 0xf2086fbf,0xfa4965b2,0x86916078,0xf6840ea6,0x70081d6c,0xd7ac7620,0xb5328645,0xe600da31,0x529b8a80,0x01916f63,0x2d7d6f3e,0xe80e4858,0xd664ca7c,0x29eb0fe8,0xe7b43b0c,0xf017637b +.long 0x76cb2566,0x9a75c806,0xb24892d9,0x8f76acb1,0x1f08fe45,0x7ae7b9cc,0x6a4907d8,0x19ef7329,0x5f228bf0,0x2db4ab71,0x817032d7,0xf3cdea39,0xdcabe3c0,0x0b1f482e,0xbb86325c,0x3baf76b4 +.long 0x10089465,0xd49065e0,0x8e77c596,0x3bab5d29,0x193dbd95,0x7636c3a6,0xb246e499,0xdef5d294,0x286b2475,0xb22c58b9,0xcd80862b,0xa0b93939,0xf0992388,0x3002c83a,0xeacbe14c,0x6de01f9b +.long 0xadd70482,0x6aac688e,0x7b4a4e8a,0x708de92a,0x758a6eef,0x75b6dd73,0x725b3c43,0xea4bf352,0x87912868,0x10041f2c,0xef09297a,0xb1b1be95,0xa9f3860a,0x19ae23c5,0x515dcf4b,0xc4f0f839 +.long 0x97f6306a,0x3c7ecca3,0x68a3a4b0,0x744c44ae,0xb3a1d8a2,0x69cd13a0,0x5256b578,0x7cad0a1e,0x33791d9e,0xea653fcd,0x74b2e05f,0x9cc2a05d,0xfd7affa2,0x73b391dc,0xb6b05442,0xddb7091e +.long 0x8538a5c6,0xc71e27bf,0x89abff17,0x195c63dd,0x1b71e3da,0xfd315285,0xfa680fa0,0x9cbdfda7,0x849d7eab,0x9db876ca,0x3c273271,0xebe2764b,0xf208dcea,0x663357e3,0x565b1b70,0x8c5bd833 +.long 0x9837fc0d,0xccc3b4f5,0xa79cf00f,0x9b641ba8,0xdfdf3990,0x7428243d,0x020786b1,0x83a594c4,0x526c4502,0xb712451a,0x6adb3f93,0x9d39438e,0xe9ff0ccd,0xfdb261e3,0xe07af4c3,0x80344e3c +.long 0x2fa4f126,0x75900d7c,0x5c99a232,0x08a3b865,0xdb25e0c3,0x2478b6bf,0x71db2edf,0x482cc2c2,0x5f321bb8,0x37df7e64,0x9a8005b4,0x8a93821b,0xcc8c1958,0x3fa2f10c,0x2c269d0a,0x0d332218 +.long 0xe246b0e6,0x20ab8119,0xd349fd17,0xb39781e4,0xb31aa100,0xd293231e,0xbb032168,0x4b779c97,0xc8470500,0x4b3f19e1,0x0c4c869d,0x45b7efe9,0xa1a6bbcc,0xdb84f38a,0xb2fddbc1,0x3b59cb15 +.long 0x3fd165e8,0xba5514df,0x061f8811,0x499fd6a9,0xbfef9f00,0x72cd1fe0,0x79ad7e8a,0x120a4bb9,0x5f4a5ac5,0xf2ffd095,0x95a7a2f0,0xcfd174f1,0x9d17baf1,0xd42301ba,0x77f22089,0xd2fa487a +.long 0xb1dc77e1,0x9cb09efe,0x21c99682,0xe9566939,0x6c6067bb,0x8c546901,0x61c24456,0xfd378574,0x81796b33,0x2b6a6cbe,0x58e87f8b,0x62d550f6,0x7f1b01b4,0x1b763e1c,0x1b1b5e12,0x4b93cfea +.long 0x1d531696,0xb9345238,0x88cdde69,0x57201c00,0x9a86afc7,0xdde92251,0xbd35cea8,0xe3043895,0x8555970d,0x7608c1e1,0x2535935e,0x8267dfa9,0x322ea38b,0xd4c60a57,0x804ef8b5,0xe0bf7977 +.long 0xc06fece4,0x1a0dab28,0x94e7b49d,0xd405991e,0x706dab28,0xc542b6d2,0xa91618fb,0xcb228da3,0x107d1cea,0x224e4164,0xd0f5d8f1,0xeb9fdab3,0x0d6e41cd,0xc02ba386,0x9b1f7146,0x676a72c5 +.long 0x4d6cb00b,0xffd6dd98,0xde2e8d7c,0xcef9c5ca,0x641c7936,0xa1bbf5d7,0xee8f772e,0x1b95b230,0xe8ac25b1,0xf765a92e,0x3a18b7c6,0xceb04cfc,0x0acc8966,0x27944cef,0x434c1004,0xcbb3c957 +.long 0xa43ff93c,0x9c9971a1,0xa1e358a9,0x5bc2db17,0xa8d9bc82,0x45b4862e,0x2201e052,0x70ebfbfb,0x92871591,0xafdf64c7,0xb42d0219,0xea5bcae6,0x2ad8f03c,0xde536c55,0xa76aa33c,0xcd6c3f4d +.long 0x0bca6de3,0xbeb5f623,0xb1e706fd,0xdd20dd99,0xac9059d4,0x90b3ff9d,0x7ccccc4e,0x2d7b2902,0xce98840f,0x8a090a59,0x8410680a,0xa5d947e0,0x923379a5,0x49ae346a,0xb28a3156,0x7dbc84f9 +.long 0x54a1aff2,0xfd40d916,0x3a78fb9b,0xabf318ba,0x3029f95e,0x50152ed8,0xc58ad7fa,0x9fc1dd77,0x13595c17,0x5fa57915,0x8f62b3a9,0xb9504668,0xff3055b0,0x907b5b24,0x9a84f125,0x2e995e35 +.long 0x7e9bbcfb,0x87dacf69,0xe86d96e3,0x95d0c1d6,0x2d95a75c,0x65726e3c,0xacd27f21,0x2c3c9001,0x6c973f57,0x1deab561,0xa5221643,0x108b7e2c,0xc4ef79d4,0x5fee9859,0x40d4b8c6,0xbd62b88a +.long 0x197c75d6,0xb4dd29c4,0xb7076feb,0x266a6df2,0x4bf2df11,0x9512d0ea,0x6b0cc9ec,0x1320c24f,0x01a59596,0x6bb1e0e1,0xeff9aaac,0x8317c5bb,0x385aa6c9,0x65bb405e,0x8f07988f,0x613439c1 +.long 0x16a66e91,0xd730049f,0xfa1b0e0d,0xe97f2820,0x304c28ea,0x4131e003,0x526bac62,0x820ab732,0x28714423,0xb2ac9ef9,0xadb10cb2,0x54ecfffa,0xf886a4cc,0x8781476e,0xdb2f8d49,0x4b2c87b5 +.long 0x0a44295d,0xe857cd20,0x58c6b044,0x707d7d21,0xf596757c,0xae8521f9,0x67b2b714,0x87448f03,0x5ebcd58d,0x13a9bc45,0x9122d3c1,0x79bcced9,0x9e076642,0x3c644247,0x2df4767d,0x0cf22778 +.long 0x71d444b6,0x5e61aee4,0xc5084a1d,0x211236bf,0x4fd3eaf6,0x7e15bc9a,0xab622bf5,0x68df2c34,0x59bf4f36,0x9e674f0f,0xd7f34d73,0xf883669b,0x31497b1d,0xc48ac1b8,0x5106703b,0x323b925d +.long 0x74082008,0x22156f42,0xc8482bcb,0xeffc521a,0x12173479,0x5c6831bf,0xc4739490,0xcaa2528f,0x8f1b3c4d,0x84d2102a,0x2d9bec0d,0xcf64dfc1,0x78a546ef,0x433febad,0x7b73cef1,0x1f621ec3 +.long 0x37338615,0x6aecd627,0x01d8edf6,0x162082ab,0x19e86b66,0x833a8119,0xd299b5db,0x6023a251,0xbbf04b89,0xf5bb0c3a,0xae749a44,0x6735eb69,0x4713de3b,0xd0e058c5,0x2c3d4ccd,0xfdf2593e +.long 0xfdd23667,0x1b8f414e,0xfa2015ee,0xdd52aaca,0xbd9625ff,0x3e31b517,0x8db5918c,0x5ec9322d,0xa96f5294,0xbc73ac85,0x61a0666a,0x82aa5bf3,0xbf08ac42,0x49755810,0x891cedfc,0xd21cdfd5 +.long 0x67f8be10,0x918cb57b,0x56ffa726,0x365d1a7c,0x6532de93,0x2435c504,0x2674cd02,0xc0fc5e10,0x9cbbb142,0x6e51fcf8,0xafc50692,0x1d436e5a,0x3fbcae22,0x766bffff,0xfd55d3b8,0x3148c2fd +.long 0x233222fa,0x52c7fdc9,0xe419fb6b,0x89ff1092,0x25254977,0x3cd6db99,0x1cf12ca7,0x2e85a161,0xdc810bc9,0xadd2547c,0x9d257c22,0xea3f458f,0x27d6b19b,0x642c1fbe,0x140481a6,0xed07e6b5 +.long 0x86d2e0f8,0x6ada1d42,0x0e8a9fd5,0xe5920122,0x708c1b49,0x02c936af,0x2b4bfaff,0x60f30fee,0x858e6a61,0x6637ad06,0x3fd374d0,0xce4c7767,0x7188defb,0x39d54b2d,0xf56a6b66,0xa8c9d250 +.long 0xb24fe1dc,0x58fc0f5e,0x6b73f24c,0x9eaf9dee,0x33650705,0xa90d588b,0xaf2ec729,0xde5b62c5,0xd3c2b36e,0x5c72cfae,0x034435da,0x868c19d5,0xe17ee145,0x88605f93,0x77a5d5b1,0xaa60c4ee +.long 0x3b60c472,0xbcf5bfd2,0xeb1d3049,0xaf4ef13c,0xe13895c9,0x373f44fc,0x0cbc9822,0xf29b382f,0x73efaef6,0x1bfcb853,0xa8c96f40,0xcf56ac9c,0x7a191e24,0xd7adf109,0xbf8a8dc2,0x98035f44 +.long 0x1e750c84,0xf40a71b9,0x5dc6c469,0xc57f7b0c,0x6fbc19c1,0x49a0e79c,0xa48ebdb8,0x6b0f5889,0xa07c4e9f,0x5d3fd084,0xab27de14,0xc3830111,0x33e08dcc,0x0e4929fe,0x40bb73a3,0xf4a5ad24 +.long 0x490f97ca,0xde86c2bf,0x67a1ce18,0x288f09c6,0x1844478d,0x364bb886,0xceedb040,0x7840fa42,0x5a631b37,0x1269fdd2,0xa47c8b7d,0x94761f1e,0x481c6266,0xfc0c2e17,0x3daa5fa7,0x85e16ea2 +.long 0x92491048,0xccd86033,0xf4d402d7,0x0c2f6963,0xdf6a865c,0x6336f7df,0xb5c02a87,0x0a2a463c,0xbf2f12ee,0xb0e29be7,0x66bad988,0xf0a22002,0x9123c1d7,0x27f87e03,0x328a8c98,0x21669c55 +.long 0x92f14529,0x186b9803,0x63954df3,0xd3d056cc,0x175a46f6,0x2f03fd58,0x11558558,0x63e34ebe,0x5b80cfa5,0xe13fedee,0xd401dbd1,0xe872a120,0xe8a9d667,0x52657616,0xe08d6693,0xbc8da4b6 +.long 0x1b703e75,0x370fb9bb,0xd4338363,0x6773b186,0xecef7bff,0x18dad378,0x995677da,0xaac787ed,0x0437164b,0x4801ea8b,0x73fe795e,0xf430ad20,0x8ee5eb73,0xb164154d,0x108f7c0e,0x0884ecd8 +.long 0x5f520698,0x0e6ec096,0x44f7b8d9,0x640631fe,0xa35a68b9,0x92fd34fc,0x4d40cf4e,0x9c5a4b66,0x80b6783d,0x949454bf,0x3a320a10,0x80e701fe,0x1a0a39b2,0x8d1a564a,0x320587db,0x1436d53d +.long 0x6556c362,0xf5096e6d,0xe2455d7e,0xbc23a3c0,0x807230f9,0x3a7aee54,0x22ae82fd,0x9ba1cfa6,0x99c5d706,0x833a057a,0x842315c9,0x8be85f4b,0x66a72f12,0xd083179a,0xcdcc73cd,0x2fc77d5d +.long 0x5616ee30,0x22b88a80,0xe7ab1083,0xfb09548f,0x511270cd,0x8ad6ab0d,0x6924d9ab,0x61f6c57a,0x90aecb08,0xa0f7bf72,0x0df784a4,0x849f87c9,0xcfaf1d03,0x27c79c15,0xc463face,0xbbf9f675 +.long 0x765ba543,0x91502c65,0x42ea60dd,0x18ce3cac,0x6e43ecb3,0xe5cee6ac,0x68f2aeeb,0x63e4e910,0xc85932ee,0x26234fa3,0x4c90c44d,0x96883e8b,0xa18a50f6,0x29b9e738,0x3f0420df,0xbfc62b2a +.long 0x6d3e1fa9,0xd22a7d90,0xfe05b8a3,0x17115618,0xbb2b9c01,0x2a0c9926,0xe07e76a2,0xc739fcc6,0x165e439a,0x540e9157,0x6a9063d8,0x06353a62,0x61e927a3,0x84d95594,0xe2e0be7f,0x013b9b26 +.long 0x973497f1,0x4feaec3b,0x093ebc2d,0x15c0f94e,0x33af0583,0x6af5f227,0xc61f3340,0x0c2af206,0x4457397c,0xd25dbdf1,0xcabcbae0,0x2e8ed017,0xc2815306,0xe3010938,0xe8c6cd68,0xbaa99337 +.long 0x3b0ec7de,0x08513182,0x58df05df,0x1e1b822b,0xa5c3b683,0x5c14842f,0x3eba34ce,0x98fe977e,0x0d5e8873,0xfd2316c2,0xbd0d427d,0xe48d839a,0x623fc961,0x495b2218,0xb46fba5e,0x24ee56e7 +.long 0x91e4de58,0x9184a55b,0xdfdea288,0xa7488ca5,0xa8dcc943,0xa723862e,0x849dc0fc,0x92d762b2,0x091ff4a9,0x3c444a12,0x0cada274,0x581113fa,0x30d8eae2,0xb9de0a45,0xdf6b41ea,0x5e0fcd85 +.long 0xc094dbb5,0x6233ea68,0xd968d410,0xb77d062e,0x58b3002d,0x3e719bbc,0x3dc49d58,0x68e7dd3d,0x013a5e58,0x8d825740,0x3c9e3c1b,0x21311747,0x7c99b6ab,0x0cb0a2a7,0xc2f888f2,0x5c48a3b3 +.long 0x991724f3,0xc7913e91,0x39cbd686,0x5eda799c,0x63d4fc1e,0xddb595c7,0xac4fed54,0x6b63b80b,0x7e5fb516,0x6ea0fc69,0xd0f1c964,0x737708ba,0x11a92ca5,0x9628745f,0x9a86967a,0x61f37958 +.long 0xaa665072,0x9af39b2c,0xefd324ef,0x78322fa4,0xc327bd31,0x3d153394,0x3129dab0,0x81d5f271,0xf48027f5,0xc72e0c42,0x8536e717,0xaa40cdbc,0x2d369d0f,0xf45a657a,0xea7f74e6,0xb03bbfc4 +.long 0x0d738ded,0x46a8c418,0xe0de5729,0x6f1a5bb0,0x8ba81675,0xf10230b9,0x112b33d4,0x32c6f30c,0xd8fffb62,0x7559129d,0xb459bf05,0x6a281b47,0xfa3b6776,0x77c1bd3a,0x7829973a,0x0709b380 +.long 0xa3326505,0x8c26b232,0xee1d41bf,0x38d69272,0xffe32afa,0x0459453e,0x7cb3ea87,0xce8143ad,0x7e6ab666,0x932ec1fa,0x22286264,0x6cd2d230,0x6736f8ed,0x459a46fe,0x9eca85bb,0x50bf0d00 +.long 0x877a21ec,0x0b825852,0x0f537a94,0x300414a7,0x21a9a6a2,0x3f1cba40,0x76943c00,0x50824eee,0xf83cba5d,0xa0dbfcec,0x93b4f3c0,0xf9538148,0x48f24dd7,0x61744162,0xe4fb09dd,0x5322d64d +.long 0x3d9325f3,0x57447384,0xf371cb84,0xa9bef2d0,0xa61e36c5,0x77d2188b,0xc602df72,0xbbd6a7d7,0x8f61bc0b,0xba3aa902,0x6ed0b6a1,0xf49085ed,0xae6e8298,0x8bc625d6,0xa2e9c01d,0x832b0b1d +.long 0xf1f0ced1,0xa337c447,0x9492dd2b,0x800cc793,0xbea08efa,0x4b93151d,0xde0a741e,0x820cf3f8,0x1c0f7d13,0xff1982dc,0x84dde6ca,0xef921960,0x45f96ee3,0x1ad7d972,0x29dea0c7,0x319c8dbe +.long 0x7b82b99b,0xd3ea3871,0x470eb624,0x75922d4d,0x3b95d466,0x8f66ec54,0xbee1e346,0x66e673cc,0xb5f2b89a,0x6afe67c4,0x290e5cd3,0x3de9c1e6,0x310a2ada,0x8c278bb6,0x0bdb323b,0x420fa384 +.long 0x0eb919b0,0x0ae1d63b,0xa74b9620,0xd74ee51d,0xa674290c,0x395458d0,0x4620a510,0x324c930f,0xfbac27d4,0x2d1f4d19,0x9bedeeac,0x4086e8ca,0x9b679ab8,0x0cdd211b,0x7090fec4,0x5970167d +.long 0xfaf1fc63,0x3420f2c9,0x328c8bb4,0x616d333a,0x57f1fe4a,0x7d65364c,0x55e5c73a,0x9343e877,0xe970e78c,0x5795176b,0x60533627,0xa36ccebf,0x09cdfc1b,0xfc7c7380,0xb3fec326,0xb39a2afe +.long 0x6224408a,0xb7ff1ba1,0x247cfc5e,0xcc856e92,0xc18bc493,0x01f102e7,0x2091c727,0x4613ab74,0xc420bf2b,0xaa25e89c,0x90337ec2,0x00a53176,0x7d025fc7,0xd2be9f43,0x6e6fe3dc,0x3316fb85 +.long 0x9ac50814,0x27520af5,0x9a8e4223,0xfdf95e78,0x56bec5a0,0xb7e7df2a,0xdf159e5d,0xf7022f7d,0xcac1fe8f,0x93eeeab1,0x37451168,0x8040188c,0xd967dce6,0x7ee8aa8a,0x3abc9299,0xfa0e79e7 +.long 0x2064cfd1,0x67332cfc,0xb0651934,0x339c31de,0x2a3bcbea,0x719b28d5,0x9d6ae5c6,0xee74c82b,0xbaf28ee6,0x0927d05e,0x9d719028,0x82cecf2c,0xddb30289,0x0b0d353e,0xfddb2e29,0xfe4bb977 +.long 0x640bfd9e,0xbb5bb990,0x82f62108,0xd226e277,0x02ffdd56,0x4bf00985,0x2ca1b1b5,0x7756758a,0x5285fe91,0xc32b62a3,0x8c9cd140,0xedbc546a,0xaf5cb008,0x1e47a013,0x073ce8f2,0xbca7e720 +.long 0x17a91cae,0xe10b2ab8,0x08e27f63,0xb89aab65,0xdba3ddf9,0x7b3074a7,0x330c2972,0x1c20ce09,0x5fcf7e33,0x6b9917b4,0x945ceb42,0xe6793743,0x5c633d19,0x18fc2215,0xc7485474,0xad1adb3c +.long 0x6424c49b,0x646f9679,0x67c241c9,0xf888dfe8,0x24f68b49,0xe12d4b93,0xa571df20,0x9a6b62d8,0x179483cb,0x81b4b26d,0x9511fae2,0x666f9632,0xd53aa51f,0xd281b3e4,0x7f3dbd16,0x7f96a765 +.long 0x074a30ce,0xa7f8b5bf,0x005a32e6,0xd7f52107,0x50237ed4,0x6f9e0907,0x8096fa2b,0x2f21da47,0xeec863a0,0xf3e19cb4,0x9527620a,0xd18f77fd,0x407c1cf8,0x9505c81c,0x1b6ec284,0x9998db4e +.long 0xc247d44d,0x7e3389e5,0x3f4f3d80,0x12507141,0x4a78a6c7,0xd4ba0110,0x767720be,0x312874a0,0x75944370,0xded059a6,0x3b2c0bdd,0xd6123d90,0x51c108e3,0xa56b717b,0x070623e9,0x9bb7940e +.long 0x84ac066c,0x794e2d59,0xe68c69a0,0xf5954a92,0x4fd99dcc,0x28c52458,0xb1012517,0x60e639fc,0x7de79248,0xc2e60125,0xf12fc6d7,0xe9ef6404,0x2a3b5d32,0x4c4f2808,0xc768eb8a,0x865ad32e +.long 0x13fb70b6,0xac02331b,0x95599b27,0x037b44c1,0x60bd082c,0x1a860fc4,0xc980cd01,0xa2e25745,0x1da0263e,0xee3387a8,0x2d10f3d6,0x931bfb95,0xa1f24a32,0x5b687270,0xca494b86,0xf140e65d +.long 0xb2f1ac7a,0x4f4ddf91,0x760fee27,0xf99eaabb,0x49c228e5,0x57f4008a,0x1cf713bb,0x090be440,0x5004f022,0xac91fbe4,0x569e1af6,0xd838c2c2,0x0f1daaa5,0xd6c7d20b,0x1bbb02c0,0xaa063ac1 +.long 0x59558a78,0x0938a422,0x8435da2f,0x5343c669,0x034410dc,0x96f67b18,0x84510804,0x7cc1e424,0x16dfbb7d,0x86a1543f,0x5b5bd592,0x921fa942,0xb33dd03c,0x9dcccb6e,0xb843f51e,0x8581ddd9 +.long 0x81d73c9e,0x54935fcb,0x0a5e97ab,0x6d07e979,0xcf3a6bab,0x4dc7b30a,0x170bee11,0x147ab1f3,0x9fafdee4,0x0aaf8e3d,0x538a8b95,0xfab3dbcb,0x6ef13871,0x405df4b3,0x088d5a49,0xf1f4e9cb +.long 0x66b33f1d,0x9bcd24d3,0x5ce445c0,0x3b97b820,0xba93ff61,0xe2926549,0x4dafe616,0xd9c341ce,0x16efb6f3,0xfb30a76e,0x605b953c,0xdf24b8ca,0xc2fffb9f,0x8bd52afe,0xe19d0b96,0xbbac5ff7 +.long 0x459afccd,0x43c01b87,0xb7432652,0x6bd45143,0x55b5d78e,0x84734530,0x1554ba7d,0x81088fdb,0x1e269375,0xada0a52c,0x2dc5ec10,0xf9f037c4,0x94bfbc11,0xc0660607,0xc9c40d2f,0xc0a630bb +.long 0xab64c31e,0x5efc797e,0x74507144,0xffdb1dab,0x1ca6790c,0xf6124287,0xe69bf1bf,0xe9609d81,0x00d24fc9,0xdb898595,0xe51fb417,0x9c750333,0xfef7bbde,0x51830a91,0x945f585c,0x0ce67dc8 +.long 0x4763eb50,0x9a730ed4,0xc1ab0d66,0x24a0e221,0x648748f3,0x643b6393,0x6d3c6291,0x1982daa1,0x8bbc5549,0x6f00a9f7,0x7f36384e,0x7a1783e1,0xde977f50,0xe8346323,0xb245502a,0x91ab688d +.long 0x6d0bdd66,0x331ab6b5,0x64b71229,0x0a6ef32e,0xfe7c352f,0x1028150e,0xce7b39d3,0x27e04350,0xc1070c82,0x2a3c8acd,0x80c9feef,0xfb2034d3,0x709f3729,0x2d729621,0x62cb4549,0x8df290bf +.long 0xfc2e4326,0x02f99f33,0x5eddf032,0x3b30076d,0x0c652fb5,0xbb21f8cf,0xed91cf7b,0x314fb49e,0x2f700750,0xa013eca5,0x712a4575,0x2b9e3c23,0xaf30fbb0,0xe5355557,0x7c77e771,0x1ada3516 +.long 0x7b135670,0x45f6ecb2,0x7cfc202e,0xe85d19df,0x58d1be9f,0x0f1b50c7,0xead2e344,0x5ebf2c0a,0xabc199c9,0x1531fe4e,0x56bab0ae,0xc7032592,0x6c1fec54,0x16ab2e48,0x04280188,0x0f87fda8 +.long 0x609e4a74,0xdc9f46fc,0xba667f91,0x2a44a143,0xb4d83436,0xbc3d8b95,0xc7bd2958,0xa01e4bd0,0x73483c90,0x7b182932,0xa7c7b598,0xa79c6aa1,0xeaaac07e,0xbf3983c6,0x96e0d4e6,0x8f18181e +.long 0x051af62b,0x8553d37c,0x0bf94496,0xe9a998eb,0xb0d59aa1,0xe0844f9f,0xe6afb813,0x983fd558,0x65d69804,0x9670c0ca,0x6ea5ff2d,0x732b22de,0x5fd8623b,0xd7640ba9,0xa6351782,0x9f619163 +.long 0xacee5043,0x0bfc27ee,0x2eb10f02,0xae419e73,0x8943fb05,0x19c028d1,0xff13aa2a,0x71f01cf7,0x8887a132,0x7790737e,0x66318410,0x67513309,0x7ddb795e,0x9819e8a3,0xdad100b2,0xfecb8ef5 +.long 0x3021926a,0x59f74a22,0x6f9b4c1c,0xb7c28a49,0x912ad0ab,0xed1a733f,0x01a5659c,0x42a910af,0x7bd68cab,0x3842c6e0,0x76d70ac8,0x2b57fa38,0x3c53aaeb,0x8a6707a8,0x65b4db18,0x62c1c510 +.long 0xb2d09dc7,0x8de2c1fb,0x266bd23b,0xc3dfed12,0xd5b27db6,0x927d039b,0x103243da,0x2fb2f0f1,0x80be7399,0xf855a07b,0x1f9f27a8,0xed9327ce,0x729bdef7,0xa0bd99c7,0x28250d88,0x2b67125e +.long 0x8670ced7,0x784b26e8,0xc31bd3b4,0xe3dfe41f,0xbcc85cbc,0x9e353a06,0x60178a9d,0x302e2909,0xa6eac16e,0x860abf11,0xaa2b3aac,0x76447000,0x850afdab,0x46ff9d19,0xfdb2d4c1,0x35bdd6a5 +.long 0x7e5c9ce9,0xe82594b0,0x20af346e,0x0f379e53,0xbc65ad4a,0x608b31e3,0x267c4826,0x710c6b12,0x71954cf1,0x51c966f9,0x0d0aa215,0xb1cec793,0x86bd23a8,0x1f155989,0xf9452e86,0xae2ff99c +.long 0x340ceaa2,0xd8dd953c,0x2e2e9333,0x26355275,0x8586f06d,0x15d4e5f9,0xf7cab546,0xd6bf94a8,0xb76a9af0,0x33c59a0a,0xba095af7,0x52740ab3,0x24389ca0,0xc444de8a,0x706da0cb,0xcc6f9863 +.long 0x6b2515cf,0xb5a741a7,0x9585c749,0x71c41601,0xe683de97,0x78350d4f,0x63d0b5f5,0x31d61524,0xfbce090b,0x7a0cc5e1,0xfbcb2a5b,0xaac927ed,0x20d84c35,0xe920de49,0x22b4de26,0x8c06a0b6 +.long 0xafe7ddf3,0xd34dd58b,0xc1e6e55b,0x55851fed,0x960696e7,0xd1395616,0x5f22705f,0x940304b2,0xb0a2a860,0x6f43f861,0x0e7cc981,0xcf121282,0x0ab64a96,0x12186212,0xb789383c,0x09215b9a +.long 0x37387c09,0x311eb305,0xf03ee760,0xc5832fce,0x32f7ea19,0x30358f58,0x91d53551,0xe01d3c34,0xda48ea80,0x1ca5ee41,0xcf4fa4c1,0x34e71e8e,0x7af1e1c7,0x312abd25,0x2153f4a5,0xe3afcdeb +.long 0x00235e9a,0x9d5c84d7,0x8c4c836f,0x0308d3f4,0x89332de5,0xc0a66b04,0x89e566ef,0x610dd399,0xd1ac1635,0xf8eea460,0x20a2c0df,0x84cbb3fb,0xe74a48c5,0x40afb488,0xd326b150,0x29738198 +.long 0xa6d74081,0x2a17747f,0x55a26214,0x60ea4c05,0x1f88c5fe,0x53514bb4,0x7e83426c,0xedd64567,0x96460b25,0xd5d6cbec,0x68dc115e,0xa12fd0ce,0x697840ea,0xc5bc3ed2,0xa6331e31,0x969876a8 +.long 0x472ff580,0x60c36217,0x4ad41393,0xf4229705,0xa03b8b92,0x4bd99ef0,0xc144f4f6,0x501c7317,0x18464945,0x159009b3,0x74c5c6be,0x6d5e594c,0x321a3660,0x2d587011,0x3898d022,0xd1e184b1 +.long 0x4c6a7e04,0x5ba04752,0x45550b65,0x47fa1e2b,0x48c0a9a5,0x9419daf0,0x7c243236,0x66362953,0x5cb12a88,0xcd0744b1,0x2b646188,0x561b6f9a,0x66c2c0c0,0x599415a5,0x0f83f09a,0xbe3f0859 +.long 0xb92041b8,0x9141c5be,0x26477d0d,0x01ae38c7,0xd12c7a94,0xca8b71f3,0x765c70db,0xfab5b31f,0x487443e9,0x76ae7492,0x990d1349,0x8595a310,0x7d460a37,0xf8dbeda8,0x1e45a38f,0x7f7ad082 +.long 0x1059705a,0xed1d4db6,0xe6b9c697,0xa3dd492a,0x6eb38bd5,0x4b92ee3a,0x67cc0bb7,0xbab2609d,0x6e70ee82,0x7fc4fe89,0x13e6b7e3,0xeff2c56e,0x34d26fca,0x9b18959e,0x889d6b45,0x2517ab66 +.long 0xbdefdd4f,0xf167b4e0,0xf366e401,0x69958465,0xa73bbec0,0x5aa368ab,0x7b240c21,0x12148709,0x18969006,0x378c3233,0xe1fe53d1,0xcb4d73ce,0x130c4361,0x5f50a80e,0x7ef5212b,0xd67f5951 +.long 0x9e70c72e,0xf145e21e,0x5566d2fb,0xb2e52e29,0x032397f5,0x44eaba4a,0x7e31a7de,0x5e56937b,0x456c61e1,0x68dcf517,0xa8b0a388,0xbc2e954a,0x60a8b755,0xe3552fa7,0x73ad0cde,0x03442dae +.long 0xceb26210,0x37ffe747,0x787baef9,0x983545e8,0x86a3de31,0x8b8c8535,0xfacd46db,0xc621dbcb,0x59266fbb,0x82e442e9,0x339d471c,0xa3514c37,0x62cdad96,0x3a11b771,0xecf9bdf0,0xf0cb3b3c +.long 0x478e2135,0x3fcbdbce,0xbda35342,0x7547b5cf,0x8a677af6,0xa97e81f1,0x28817987,0xc8c2bf83,0x45580985,0xdf07eaaf,0xc93b45cb,0xc68d1f05,0xc77b4cac,0x106aa2fe,0x04a7ae86,0x4c1d8afc +.long 0x9eb45ab2,0xdb41c3fd,0xd4b22e74,0x5b234b5b,0xf215958a,0xda253dec,0xa04edfa0,0x67e0606e,0xef751b11,0xabbbf070,0xf6f06dce,0xf352f175,0x6839f6b4,0xdfc4b6af,0x9959848e,0x53ddf9a8 +.long 0xc21520b0,0xda49c379,0xdbd5d1b6,0x90864ff0,0x5f49c7f7,0x2f055d23,0xa796b2d8,0xe51e4e6a,0x5c9dc340,0xc361a67f,0xbca7c620,0x5ad53c37,0x32c756d0,0xda1d6588,0x8bb67e13,0xad60d911 +.long 0x0eeec8c6,0xd6c47bdf,0x078a1821,0x4a27fec1,0xc3099524,0x081f7415,0x82cd8060,0x8effdf0b,0x65842df8,0xdb70ec1c,0xd319a901,0x8821b358,0xde42b529,0x72ee56ee,0x236e4286,0x5bb39592 +.long 0xfd6f7140,0xd1183316,0xbd8e81f7,0xf9fadb5b,0x5a02d962,0x701d5e0c,0x1b601324,0xfdee4dbf,0x35d7620e,0xbed17407,0xf48c0012,0x04e3c2c3,0x3455449a,0x9ee29da7,0x91a836c4,0x562cdef4 +.long 0x47701097,0x8f682a5f,0xff88d0c2,0x617125d8,0x57bb86dd,0x948fda24,0x289f7286,0x348abb8f,0x99d94bbd,0xeb10eab5,0x4684d160,0xd51ba28e,0x30c8f41a,0xabe0e51c,0x13254f4a,0x66588b45 +.long 0xfad097a5,0x147ebf01,0x610e815d,0x49883ea8,0x8a11de56,0xe44d60ba,0x827a7a6d,0xa970de6e,0x5e17fc19,0x2be41424,0x01214057,0xd833c657,0x363e723f,0x1375813b,0xe6a52e9b,0x6820bb88 +.long 0xd875d56a,0x7e7f6970,0x51fbf6bf,0xd6a0a9ac,0xa3083c12,0x54ba8790,0x6ae7eb64,0xebaeb23d,0xb99a907a,0xa8685c3a,0x026bf40b,0xf1e74550,0xc802cd9e,0x7b73a027,0x4fef4635,0x9a8a927c +.long 0x08191224,0xe1b6f60c,0xde4ec091,0xc4126ebb,0x4ae38d84,0xe1dff4dc,0x4f2ef985,0xde3f57db,0xd446a1dd,0x34964337,0x859e77f6,0x7bf217a0,0x8e1d13f5,0x8ff10527,0x74eeae27,0xa304ef03 +.long 0xd19dfa5a,0xfc6f5e47,0x7fad982b,0xdb007de3,0x613715f5,0x28205ad1,0x7889529e,0x251e6729,0x1ae98e78,0x72705184,0x271cac32,0xf818537d,0xb7f410f5,0xc8a15b7e,0x81f62393,0xc474356f +.long 0xc242316b,0x92dbdc5a,0xdbf4aff5,0xabe060ac,0x909a8ec6,0x6e8c38fe,0x6116cb94,0x43e514e5,0x07d784f9,0x2078fa38,0xf4b5b357,0x1161a880,0x13adea3d,0x5283ce79,0xcc6a910b,0x0756c3e6 +.long 0xaaa79697,0x60bcfe01,0x56391db1,0x04a73b29,0x189b45a0,0xdd8dad47,0x48d5b8d9,0xbfac0dd0,0x7d3d2ec2,0x34ab3af5,0x207bd3af,0x6fa2fc2d,0x66550ded,0x9ff40092,0x1fd5b913,0x719b3e87 +.long 0x6d17fbc7,0xa573a496,0x73d2b24e,0x0cd1a70a,0xb2676937,0x34e2c5ca,0xbf669f21,0xe7050b06,0x1ede9046,0xfbe948b6,0x97662659,0xa0530051,0xf10124c5,0x58cbd4ed,0xdd6c06c8,0xde2646e4 +.long 0x8cad38c0,0x332f8108,0x6bd68ae2,0x471b7e90,0x0d8e27a3,0x56ac3fb2,0x136b4b0d,0xb54660db,0xa6fd8de4,0x123a1e11,0xa37799ef,0x44dbffea,0xce6ac17c,0x4540b977,0xaf60acef,0x495173a8 +.long 0x391c2a82,0x9ebb284d,0x158308e8,0xbcdd4863,0x83f1edca,0x006f16ec,0x695dc6c8,0xa13e2c37,0x4a057a87,0x2ab756f0,0xa6b48f98,0xa8765500,0x68651c44,0x4252face,0xe1765e02,0xa52b540b +.long 0x16a0d2bb,0x4f922fc5,0x1a623499,0x0d5cc16c,0x57c62c8b,0x9241cf3a,0xfd1b667f,0x2f5e6961,0xf5a01797,0x5c15c70b,0x60956192,0x3d20b44d,0x071fdb52,0x04911b37,0x8d6f0f7b,0xf648f916 +.long 0xe60b7cf7,0x6dc1acaf,0x84a9d869,0x25860a50,0xe7ba8ac4,0x56fc6f09,0x6148d29e,0x828c5bd0,0xdc55ae5f,0xac6b435e,0xc0117411,0xa527f56c,0xfd24342c,0x94d5045e,0x70b67c0d,0x2c4c0a35 +.long 0xfac61d9a,0x027cc8b8,0xe3c6fe8a,0x7d25e062,0xe5bff503,0xe08805bf,0x6ff632f7,0x13271e6c,0x232f76a5,0x55dca6c0,0x701ef426,0x8957c32d,0xa10a5178,0xee728bcb,0xb62c5173,0x5ea60411 +.long 0xd0b8892b,0xfc4e964e,0x9301bb74,0x9ea17683,0xfcc48626,0x6265c5ae,0xbb3e9102,0xe60cf82e,0xd4df5531,0x57adf797,0x8deeefe2,0x235b59a1,0x3f306eb1,0x60adcf58,0x3d09492d,0x105c2753 +.long 0xb5def996,0x4090914b,0x233dd1e7,0x1cb69c83,0x9b3d5e76,0xc1e9c1d3,0xfccf6012,0x1f3338ed,0x2f5378a8,0xb1e95d0d,0x2f00cd21,0xacf4c2c7,0xeb5fe290,0x6e984240,0x248088ae,0xd66c038d +.long 0xf94d70cf,0x804d264a,0x7314bf7e,0xbdb802ef,0x4333ed02,0x8fb54de2,0x285635d9,0x740461e0,0x365e9383,0x4113b2c8,0x3fdef652,0xea762c83,0x47b956c1,0x4eec6e2e,0x65620fa4,0xa3d814be +.long 0xb4d8bc50,0x9ad5462b,0xa9195770,0x181c0b16,0x78412a68,0xebd4fe1c,0xc0dff48c,0xae0341bc,0x7003e866,0xb6bc45cf,0x8a24a41b,0xf11a6dea,0xd04c24c2,0x5407151a,0xda5b7b68,0x62c9d27d +.long 0x88cceff6,0x2e964235,0x8b07ed69,0x8594c54f,0xc84d0d0d,0x1578e73c,0xff532868,0x7b4e1055,0xb5ec995a,0xa348c0d5,0x14289a54,0xbf4b9d55,0x58fbd777,0x9ba155a6,0x1a84491d,0x186ed7a8 +.long 0x614c0900,0xd4992b30,0xbd00c24b,0xda98d121,0x7ec4bfa1,0x7f534dc8,0x37dc34bc,0x4a5ff674,0x1d7ea1d7,0x68c196b8,0x80a6d208,0x38cf2893,0xe3cbbd6e,0xfd56cd09,0x4205a5b6,0xec72e27e +.long 0xa44f77f7,0x15ea68f5,0xb43c52bc,0x7aa5f9fd,0x94f0e609,0x86ff676f,0x2e2d432b,0xa4cde963,0xeee470af,0x8cafa0c0,0x8a3f5ec8,0x84137d0e,0xfaa31231,0xebb40411,0x6f7f7ccf,0xa239c13f +.long 0xa8afd30b,0x32865719,0x8a826dce,0x86798328,0xc4a8fbe0,0xdf04e891,0xebf56ad3,0xbb6b6e1b,0x471f1ff0,0x0a695b11,0xbe15baf0,0xd76c3389,0xbe96c43e,0x018edb95,0x90794158,0xf2beaaf4 +.long 0xc3076a27,0x152db09e,0xe416545d,0x5e82908e,0x356d6f2e,0xa2c41272,0x31fd74e1,0xdc9c9642,0x519bf615,0x66ceb88d,0x05a2274e,0xe29ecd76,0xbf5e2fa0,0x3a0473c4,0x64284e67,0x6b6eb671 +.long 0xb88756dd,0xe8b97932,0xf17e3e61,0xed4e8652,0x3ee1c4a4,0xc2dd1499,0x597f8c0e,0xc0aaee17,0x6c168af3,0x15c4edb9,0xb39ae875,0x6563c7bf,0x20adb436,0xadfadb6f,0x9a042ac0,0xad55e8c9 +.long 0xb76da1f5,0x975a1ed8,0xa58acb94,0x10dfa466,0xac060282,0x8dd7f7e3,0x572a051e,0x6813e66a,0x350cb901,0xb4ccae1e,0x50cb7822,0xb653d656,0xdfab3b87,0x42484710,0x9b670fd0,0xcd7ee537 +.long 0x523b8bf6,0x0a50b12e,0x8f910c1b,0x8009eb5b,0x4a167588,0xf535af82,0xfb2a2abd,0x0f835f9c,0x2afceb62,0xf59b2931,0x169d383f,0xc797df2a,0x66ac02b0,0xeb3f5fb0,0xdaa2d0ca,0x029d4c6f +.long 0xafab4bc5,0xd4059bc1,0x56783247,0x833f5c6f,0x8d2d3605,0xb5346630,0xd34d8433,0x83387891,0xadd9419a,0xd973b30f,0xafe3fce8,0xbcca1099,0x0809aac6,0x08178315,0x540f0f11,0x01b7f21a +.long 0x909523c8,0x65c29219,0xa3a1c741,0xa62f648f,0x60c9e55a,0x88598d4f,0x0e4f347a,0xbce9141b,0x35f9b988,0x9af97d84,0x320475b6,0x0210da62,0x9191476c,0x3c076e22,0x44fc7834,0x7520dbd9 +.long 0xc1ab1bbd,0x6a6b2cfe,0xdc650938,0xef8a65be,0x805d7bc4,0x72855540,0xed11fdfd,0xda389396,0x74660876,0xa9d5bd36,0xb45dff35,0x11d67c54,0xa4f5da94,0x6af7d148,0xc0bbeb31,0xbb8d4c3f +.long 0xe0a1b12a,0x87a7ebd1,0x770ba95f,0x1e4ef88d,0xdc2ae9cb,0x8c33345c,0x01cc8403,0xcecf1276,0x1b39b80f,0x687c012e,0x35c33ba4,0xfd90d0ad,0x5c9661c2,0xa3ef5a67,0xe017429e,0x368fc88e +.long 0x196a2fa2,0xd30c6761,0xbd5b312e,0x931b9817,0x72f54a31,0xba01000c,0x66eaa541,0xa203d2c8,0x98939db3,0xf2abdee0,0x3e606c02,0xe37d6c2c,0x521ff643,0xf2921574,0xd7e2fca3,0x2781b3c4 +.long 0x7850ec06,0x664300b0,0x7d3a10cf,0xac5a38b9,0xe34ab39d,0x9233188d,0x5072cbb9,0xe77057e4,0xb59e78df,0xbcf0c042,0x1d97de52,0x4cfc91e8,0x3ee0ca4a,0x4661a26c,0xfb8507bc,0x5620a4c1 +.long 0x049f842c,0x4b44d4aa,0x1540e82b,0xceabc5d5,0x15c6f156,0x306710fd,0x63db1d72,0xbe5ae52b,0x334957f1,0x06f1e7e6,0x31144a70,0x57e388f0,0xdf96447b,0xfb69bb2f,0x73e38a12,0x0f78ebd3 +.long 0x2b7ce542,0xb8222605,0x7472bde1,0xe6d4ce99,0x09d2f4da,0x53e16ebe,0x53b92b2e,0x180ff42e,0x2c34a1c6,0xc59bcc02,0x422c46c2,0x3803d6f9,0x5c14a8a2,0x18aff74f,0x10a08b28,0x55aebf80 +.long 0x7135593f,0x66097d58,0x2be570cd,0x32e6eff7,0x2a8c860d,0x584e6a10,0xa2eb4163,0xcd185890,0x6d97e134,0x7ceae99d,0xdd8447ce,0xd42c6b70,0xb8c50273,0x59ddbb4a,0x3cf34e1e,0x03c612df +.long 0x04b6c5a0,0x84b9ca15,0x18f0e3a3,0x35216f39,0xbd986c00,0x3ec2d2bc,0xd19228fe,0x8bf546d9,0x4cd623c3,0xd1c655a4,0x502b8e5a,0x366ce718,0xeea0bfe7,0x2cfc84b4,0xcf443e8e,0xe01d5cee +.long 0x036520f8,0x8ec045d9,0x92d40e98,0xdfb3c3d1,0xcc559a04,0x0bac4cce,0x240ea6b1,0x35eccae5,0xf8a5a0ac,0x180b32db,0xeb699700,0x547972a5,0xca26bca0,0xa3765801,0xa647f25a,0x57e09d0e +.long 0x2fdd23cc,0xb956970e,0x5682e971,0xb80288bc,0x9ae86ebc,0xe6e6d91e,0x8c9f1939,0x0564c83f,0x39560368,0x551932a2,0x049c28e2,0xe893752b,0xa6a158c3,0x0b03cee5,0x04964263,0xe12d656b +.long 0x63e3bc1d,0x4b47554e,0x45044ff7,0xc719b6a2,0xe48daa07,0x4f24d30a,0xc8c1edc3,0xa3f37556,0x0700d360,0x9a47bf76,0x822ae4e2,0xbb1a1824,0x89f1fb4c,0x22e275a3,0x9968c5f5,0x72b1aa23 +.long 0xbe063f64,0xa75feaca,0xbce47a09,0x9b392f43,0x1ad07aca,0xd4241509,0x8d26cd0f,0x4b0c591b,0x92f1169a,0x2d42ddfd,0x4cbf2392,0x63aeb1ac,0x0691a2af,0x1de9e877,0xd98021da,0xebe79af7 +.long 0x40e50acf,0xcfdf2a4e,0xaf01d665,0xf0a98ad7,0x1831be1f,0xefb640bf,0x80e9ada0,0x6fe8bd2f,0x6cafbc91,0x94c103a1,0x8308e08c,0x170f8759,0x9780ff4f,0x5de2d2ab,0x45b201f2,0x666466bc +.long 0xf5b343bc,0x58af2010,0xf2f142fe,0x0f2e400a,0xa85f4bdf,0x3483bfde,0x03bfeaa9,0xf0b1d093,0xc7081603,0x2ea01b95,0x3dba1097,0xe943e4c9,0xb438f3a6,0x47be92ad,0xe5bf6636,0x00bb7742 +.long 0x824297b4,0x136b7083,0x5584455f,0x9d0e5580,0xf1c7d69e,0xab48cedc,0x2a256e76,0x53a9e481,0x65eb2413,0x0402b0e0,0x8fc407a7,0xdadbbb84,0x8d7f5492,0xa65cd5a4,0x74bae294,0x21d44293 +.long 0x3b5f1cc4,0x66917ce6,0xce872e62,0x37ae52ea,0x2905f244,0xbb087b72,0x1e6af74f,0x12077086,0x1058edea,0x4b644e49,0xb638ca1d,0x827510e3,0x6038591c,0x8cf2b704,0xfe635063,0xffc8b47a +.long 0x1b4d5e63,0x3ae220e6,0x9d961b4b,0xbd864742,0x9bd16bed,0x610c107e,0x1127147b,0x4270352a,0x64cfc50e,0x7d17ffe6,0x1e36cb42,0x50dee01a,0x35dc5f9a,0x068a7622,0xdf53f62c,0x9a08d536 +.long 0x6be5f7de,0x4ed71457,0xc2263c9e,0xd93006f8,0xcacacb36,0xe073694c,0x3ae118ab,0x2ff7a5b4,0xcd871236,0x3cce53f1,0xc2aa6d52,0xf156a39d,0xb198d76d,0x9cc5f271,0x81383d39,0xbc615b6f +.long 0xde3eee6b,0xa54538e8,0xab910d91,0x58c77538,0x58d278bd,0x31e5bdbc,0xb963acae,0x3cde4adf,0x5302169c,0xb1881fd2,0xa989ed8b,0x8ca60fa0,0xff96a0ee,0xa1999458,0xac6c283d,0xc1141f03 +.long 0x6dfafed3,0x7677408d,0x39661588,0x33a01653,0x0b726fa0,0x3c9c15ec,0x6c9b56da,0x090cfd93,0xa3c40af5,0xe34f4bae,0xd21129f1,0x3469eadb,0x1e207ce8,0xcc51674a,0xc83b1ef9,0x1e293b24 +.long 0x1e6c0bb4,0x17173d13,0x90776d35,0x19004695,0x6de6f922,0xe7980e34,0xf4dd9a22,0x873554cb,0xcbf18a51,0x0316c627,0x3032c081,0x4d93651b,0x3946834d,0x207f2771,0x30cdbf80,0x2c08d7b4 +.long 0x86df2a61,0x137a4fb4,0xecf7b4a2,0xa1ed9c07,0x7bd042ff,0xb2e460e2,0x5f62f5ec,0xb7f5e2fa,0xcc2423b7,0x7aa6ec6b,0xba63eea7,0x75ce0a7f,0xf250a6e1,0x67a45fb1,0xe53cdc9f,0x93bc919c +.long 0x871942df,0x9271f56f,0x7859ad66,0x2372ff6f,0x33cb1a78,0x5f4c2b96,0x5838aa83,0xe3e29101,0xe4e8110c,0xa7ed1611,0x330198ce,0x2a2d70d5,0x6720efe0,0xbdf132e8,0x66a471bf,0xe61a8962 +.long 0x825808bd,0x796d3a85,0x3fd6e902,0x51dc3cb7,0x916219d1,0x643c768a,0xa2ad7d32,0x36cd7685,0xb22922a4,0xe3db9d05,0xdba29660,0x6494c87e,0xbcd2ebc7,0xf0ac91df,0x45107f8d,0x4deb57a0 +.long 0xc3d12a73,0x42271f59,0xa5c2c51d,0x5f71687c,0x05797bcb,0xcb1f50c6,0xd6d34eb0,0x29ed0ed9,0x4683c2eb,0xe5fe5b47,0x97447c46,0x4956eeb5,0x71207167,0x5b163a43,0x0248c5ef,0x93fa2fed +.long 0x31f63950,0x67930af2,0x14caa2c9,0xa77797c1,0x27ac7e62,0x526e80ee,0x58b28aec,0xe1e6e626,0xb3c9fef0,0x636178b0,0x6d5f90be,0xaf7752e0,0xeece51cf,0x94ecaf18,0xca806e1f,0x2864d0ed +.long 0x97c69134,0x6de2e383,0xeb291293,0x5a42c316,0x6a60bae0,0xc7779219,0x6b7599d1,0xa24de346,0xb75d4941,0x49d374aa,0x2d501ff0,0x98900586,0xeb7974cf,0x9f16d40e,0xcdd8c115,0x1033860b +.long 0x2094cec3,0xb6c69ac8,0x403b770c,0x9976fb88,0x4859590d,0x1dea026c,0x8562d1fd,0xb6acbb46,0x44569d85,0x7cd6c461,0x97f0891d,0xc3190a36,0x48d5a17d,0xc6f53195,0xd749abc8,0x7d919966 +.long 0xdd1c8a20,0x65104837,0x2f683419,0x7e5410c8,0xbe94022e,0x958c3ca8,0x6145dac2,0x605c3197,0x01683d54,0x3fc07501,0x595b1234,0x1d7127c5,0x9481277f,0x10b8f87c,0xe65a1adb,0x677db2a8 +.long 0xddce3345,0xec2fccaa,0x012a4350,0x2a6811b7,0xac598bdc,0x96760ff1,0xd1bf4128,0x054d652a,0x92a21005,0x0a1151d4,0x33110fdf,0xad7f3971,0x1960100f,0x8c95928c,0x7bf03362,0x6c91c825 +.long 0xce309f06,0xc8c8b2a2,0xca27204b,0xfdb27b59,0x0848e32e,0xd223eaa5,0xe7bfaf1e,0xb93e4b2e,0x44aa3ded,0xc5308ae6,0xc015d573,0x317a666a,0x1a979707,0xc888ce23,0x0d5c4958,0xf141c1e6 +.long 0x61906373,0xb53b7de5,0xeb999595,0x858dbade,0xa59e5c36,0x8cbb47b2,0xdcf4e842,0x660318b3,0x12ba4b7a,0xbd161ccd,0xf8c8282a,0xf399daab,0xeeb2130d,0x1587633a,0xda38dd7d,0xa465311a +.long 0x64d3779b,0x5f75eec8,0xad64c171,0x3c5d0476,0x2a914428,0x87410371,0x90e2fc29,0x8096a891,0x23b3ebc2,0xd3d2ae9d,0xa580cfd6,0x90bdd6db,0xc5b01f6c,0x52dbb7f3,0xe102a2dc,0xe68eded4 +.long 0x99eb6df0,0x17785b77,0x7386b779,0x26c3cc51,0x6417a48e,0x345ed988,0x07d6ef31,0xe990b4e4,0x2586abba,0x0f456b7e,0x59c96e9a,0x239ca6a5,0xe2eb4206,0xe327459c,0xa002b90a,0x3a4c3313 +.long 0xf6a3f6fb,0x2a114806,0x85c251dd,0xad5cad2f,0xf5a784d3,0x92c1f613,0x349766d5,0xec7bfacf,0x3e23cb3b,0x04b3cd33,0xc5a64b2d,0x3979fe84,0x7e589106,0x192e2720,0xa15b527f,0xa60c43d1 +.long 0xbe7cf3a6,0x2dae9082,0xbc967274,0xcc86ba92,0xaea0a8a9,0xf28a2ce8,0x6ee988b3,0x404ca6d9,0x005921b8,0xfd7e9c5d,0x44e79bf9,0xf56297f1,0x0d75ddc2,0xa163b460,0xa1f2be87,0x30b23616 +.long 0xbfe50e2b,0x4b070d21,0xe1bfede1,0x7ef8cfd0,0x2aac4ae0,0xadba0011,0xb9ebd033,0x2a3e7d01,0xe38d9d1c,0x995277ec,0x9c5d2de3,0xb500249e,0xf13ca8c9,0x8912b820,0x877793af,0xc8798114 +.long 0xec3f1dec,0x19e6125d,0x911178da,0x07b1f040,0x904a6738,0xd93ededa,0x0bebedcd,0x55187a5a,0xeb329d41,0xf7d04722,0xf170b391,0xf449099e,0xca99f828,0xfd317a69,0x34a4976d,0x50c3db2b +.long 0x3757b392,0xe9ba7784,0xaa3ca05a,0x326caefd,0xf1e593d4,0x78e5293b,0x0d98fd13,0x7842a937,0x5f96b10d,0xe694bf96,0x06a8cd05,0x373a9df6,0xe8f0c7fc,0x997d1e51,0x63fd972e,0x1d019790 +.long 0x5499fb32,0x0064d858,0x77a8aeb7,0x7b67bad9,0x2d08eec5,0x1d3eb977,0xcbabae1d,0x5fc047a6,0xe54a64bb,0x0577d159,0xc43497e4,0x8862201b,0x2ce0608d,0xad6b4e28,0x0b167aac,0x8b687b7d +.long 0x8b2ecfa9,0x6ed4d367,0xa90c3c38,0x24dfe62d,0x3fe5c42b,0xa1862e10,0xd5732a9f,0x1ca73dca,0x76bb87ad,0x35f038b7,0xf242b81f,0x674976ab,0xb0fd90cd,0x4f2bde7e,0xa7fdf092,0x6efc172e +.long 0x92222f1f,0x3806b69b,0x6cf7ae70,0x5a2459ca,0xa85217ee,0x6789f69c,0xe3dc85ac,0x5f232b5e,0x48e9e516,0x660e3ec5,0x3197eb31,0x124b4e47,0xaafcca23,0x10a0cb13,0x8213224f,0x7bd63ba4 +.long 0x290a7f4f,0xaffad7cc,0x0286b461,0x6b409c9e,0xffa407af,0x58ab809f,0xc68ac073,0xc3122eed,0x4ef24d7e,0x17bf9e50,0x3e2a5811,0x5d929794,0x02902e01,0x519bc867,0x39c8a851,0x76bba5da +.long 0xda94951e,0xe9f9669c,0x66b8d418,0x4b6af58d,0x17d426a4,0xfa321074,0x9dde6027,0xc78e66a9,0x4a53b964,0x0516c083,0xff602330,0xfc659d38,0x58c5c897,0x0ab55e5c,0x838bc5df,0x985099b2 +.long 0xc52fc238,0x061d9efc,0x6ac1da3f,0x712b2728,0x9283fe08,0xfb658149,0xb8aaa2f7,0x4954ac94,0x7fb2e74f,0x85c0ada4,0xb89926b0,0xee8ba98e,0x23d1af5b,0xe4f9d37d,0xba9b015e,0x14ccdbf9 +.long 0x7bfe7178,0xb674481b,0x65405868,0x4e1debae,0xc48c867d,0x061b2821,0x513b30ea,0x69c15b35,0x36871088,0x3b4a1666,0x1220b1ff,0xe5e29f5d,0x233d9f4d,0x4b82bb35,0x18cdc675,0x4e076333 +.long 0xa3e6fced,0x0d53f5c7,0xf45fbdeb,0xe8cbbdd5,0x13339a70,0xf85c01df,0x142ceb81,0x0ff71880,0xbd70437a,0x4c4e8774,0xba0bda6a,0x5fb32891,0xf18bd26e,0x1cdbebd2,0x03a9d522,0x2f9526f1 +.long 0x92c4d684,0x40ce3051,0x7612efcd,0x8b04d725,0x6f9cae20,0xb9dcda36,0xf058856c,0x0edc4d24,0x85427900,0x64f2e6bf,0xdc09dfea,0x3de81295,0x379bf26c,0xd41b4487,0x6df135a9,0x50b62c6d +.long 0xc72dfe67,0xd4f8e3b4,0x90e19fdf,0xc416b0f6,0x4c13bd35,0x18b9098d,0x15b8cb9e,0xac11118a,0xf0062841,0xf598a318,0x89f356f4,0xbfe0602f,0x30177a0c,0x7ae3637e,0x61136537,0x34097747 +.long 0xd005832a,0x0db2fb5e,0x91042e4f,0x5f5efd3b,0xed70f8ca,0x8c4ffdc6,0xb52da9cc,0xe4645d0b,0xc9001d1f,0x9596f58b,0x4e117205,0x52c8f0bc,0xe398a084,0xfd4aa0d2,0x104f49de,0x815bfe3a +.long 0x23885e5f,0x97e5443f,0xe8433aab,0xf72f8f99,0xe4d4e604,0xbd00b154,0xe5e173ff,0xd0b35e6a,0x9164722d,0x57b2a048,0x88761ec8,0x3e3c665b,0x3da83832,0x6bdd1397,0x73dafe3b,0x3c8b1a1e +.long 0x54317cac,0x4497ace6,0x521771b3,0xbe600ab9,0xb0dfe8b8,0xb42e409e,0x3942310f,0x386a67d7,0x4431cc28,0x25548d8d,0x985dc524,0xa7cff142,0x93c4be32,0x4d60f5a1,0xd071c6e1,0x83ebd5c8 +.long 0xb1fd2b0b,0xba3a80a7,0x5bec33e8,0x9b3ad396,0x79743fb3,0xb3868d61,0xfdb462fa,0xcfd169fc,0x9ce0a6af,0xd3b499d7,0xe42d3ff8,0x55dc1cf1,0xc6c3e1b2,0x04fb9e6c,0x6f69a474,0x47e6961d +.long 0xe548b37b,0x54eb3acc,0x84d40549,0xb38e7542,0x7b341b4f,0x8c3daa51,0x690bf7fa,0x2f6928ec,0x86ce6c41,0x0496b323,0x10adadcd,0x01be1c55,0x4bb5faf9,0xc04e67e7,0xe15c9985,0x3cbaf678 +.long 0x50ca4247,0x8cd12145,0xe7dd30aa,0xba1aa47a,0xe58fee24,0x2f81ddf1,0xeec9b0e8,0x03452936,0x243aea96,0x8bdc3b81,0x15c3d0e5,0x9a2919af,0x10948361,0x9ea640ec,0x6e0bcccf,0x5ac86d5b +.long 0xc36cf440,0xf892d918,0xc939719c,0xaed3e837,0xc0218b64,0xb07b08d2,0xce9790dd,0x6f1bcbba,0x60919b8e,0x4a84d6ed,0x8ac1f9eb,0xd8900791,0x0dd5daef,0xf84941aa,0x67fd62c5,0xb22fe40a +.long 0x157f2db3,0x97e15ba2,0x8e28ca9c,0xbda2fc8f,0x37b9f454,0x5d050da4,0x2379d72e,0x3d57eb57,0xfb5ee997,0xe9b5eba2,0xe11538ca,0x01648ca2,0xf6327974,0x32bb76f6,0xff3f4bb7,0x338f14b8 +.long 0xd7ab9a2d,0x524d226a,0x7dfae958,0x9c00090d,0x8751d8c2,0x0ba5f539,0x3ab8262d,0x8afcbcdd,0xe99d043b,0x57392729,0xaebc943a,0xef51263b,0x20862935,0x9feace93,0xb06c817b,0x639efc03 +.long 0x66b4be7a,0x1fe054b3,0x84a37a1e,0x3f25a9de,0x78d75cd9,0xf39ef1ad,0x5062c1b5,0xd7b58f49,0xff563436,0x6f74f9a9,0xe8af51e7,0xf718ff29,0x15e97fec,0x5234d313,0x292f1c0a,0xb6a8e2b1 +.long 0x327720c1,0xa7f53aa8,0xba092cc8,0x956ca322,0x28746c4d,0x8f03d64a,0x66d0d392,0x51fe1782,0x3c832c80,0xd19b34db,0x6da2e3b4,0x60dccc5c,0x0a104ccc,0x245dd62e,0x620b21fd,0xa7ab1de1 +.long 0x3893d123,0xb293ae0b,0xb15ee71c,0xf7b75783,0x42a9468b,0x5aa3c614,0xdb15d744,0xd686123c,0xa7ab4116,0x8c616891,0xa4e6a459,0x6fcd72c8,0x77e5fad7,0xac219110,0x704fa46b,0xfb6a20e7 +.long 0x341d81dc,0xe839be7d,0x32148379,0xcddb6889,0xf7026ead,0xda6211a1,0xf4d1cc5e,0xf3b2575f,0xa7a73ae6,0x40cfc8f6,0x61d5b483,0x83879a5e,0x41a50ebc,0xc5acb1ed,0x3c07d8fa,0x59a60cc8 +.long 0xb1876262,0x1b73bdce,0x12af4ee9,0x2b0d79f0,0xd46e1d07,0x8bcf3b0b,0xe45d152f,0x17d6af9d,0x6d736451,0x73520461,0x56b0bf5a,0x43cbbd97,0xd5999b9d,0xb0833a5b,0xeb72e398,0x702614f0 +.long 0x59c3e9f8,0x0aadf01a,0xce6b3d16,0x40200e77,0xdeddafad,0xda22bdd3,0x310d72e1,0x76dedaf4,0x4bc2e88f,0x49ef807c,0x146dd5a5,0x6ba81291,0x7d8d59e9,0xa1a4077a,0x802db349,0x87b6a2e7 +.long 0x1b4e598e,0xd5679997,0x06fe4b1d,0xf499ef1f,0xfcb267c5,0x3978d3ae,0x235786d0,0xb582b557,0x1715cb07,0x32b3b2ca,0x8480241d,0x4c3de6a2,0xcb571ecd,0x63b5ffed,0xed2fe9a9,0xeaf53900 +.long 0xc3b81990,0xdec98d4a,0x9e0cc8fe,0x1cb83722,0xd2b427b9,0xfe0b0491,0xe983a66c,0x0f2386ac,0xb3291213,0x930c4d1e,0x59a62ae4,0xa2f82b2e,0xf93e89e3,0x77233853,0x11777c7f,0x7f8063ac +.long 0x59ad2877,0xff0eb567,0x9865c754,0x6f454642,0x236e9a84,0xe6fe701a,0x06e40fc3,0xc586ef16,0x24bafad9,0x3f62b6e0,0x64da906a,0xc8b42bd2,0xda3276a0,0xc98e1eb4,0x06cbf852,0x30d0e5fc +.long 0xe8b4dfd4,0x1b6b2ae1,0x8301cbac,0xd754d5c7,0x112a39ac,0x66097629,0x93ba4ab9,0xf86b5999,0x99f9d581,0x26c9dea7,0xc2fafeaa,0x0473b1a8,0x3b2505a5,0x1469af55,0xd6a43323,0x227d16d7 +.long 0xad3d97f9,0x3316f73c,0x1f137455,0x52bf3bb5,0x09954e7c,0x953eafeb,0xdd732411,0xa721dfed,0x141d4579,0xb4929821,0xaa3bd435,0x3411321c,0x17fa6015,0xafb355aa,0x18e42f0e,0xb4e7ef4a +.long 0x59371000,0x604ac97c,0x7f759c18,0xe1c48c70,0xa5db6b65,0x3f62ecc5,0x38a21495,0x0a78b173,0xbcc8ad94,0x6be1819d,0xd89c3400,0x70dc04f6,0xa6b4840a,0x462557b4,0x60bd21c0,0x544c6ade +.long 0x907a544b,0x6a00f24e,0x313da210,0xa7520dcb,0x11e4994b,0xfe939b75,0xbc275d70,0x918b6ba6,0x644be892,0xd3e5e0fc,0xfdaf6c42,0x707a9816,0xf15c13fe,0x60145567,0xe130a54a,0x4818ebaa +.long 0x58d2f767,0x28aad3ad,0xd7e7c773,0xdc5267fd,0xc3afcc98,0x4919cc88,0x2db8cd4b,0xaa2e6ab0,0xd0c63eaa,0xd46fec04,0x19ffa832,0xa1cb92c5,0xe43a631f,0x678dd178,0x3dc788b3,0xfb5ae1cd +.long 0x6e77de04,0x68b4fb90,0xf06dbb97,0x7992bcf0,0xc417c01d,0x896e6a13,0xb956be01,0x8d96332c,0x413aa2b9,0x902fc93a,0xfc98c8a5,0x99a4d915,0x565f1137,0x52c29407,0x21e4f281,0x4072690f +.long 0x02ff6072,0x36e607cf,0x8ad98cdc,0xa47d2ca9,0xf5f56609,0xbf471d1e,0xf264ada0,0xbcf86623,0xaa9e5cb6,0xb70c0687,0x17401c6c,0xc98124f2,0xd4a61435,0x8189635f,0xa9d98ea6,0xd28fb8af +.long 0x40c251f8,0xb9a67c2a,0xa2da44be,0x88cd5d87,0xe09b5423,0x437deb96,0x64287dc1,0x150467db,0xcdabb839,0xe161debb,0xf1839a3e,0xa79e9742,0x652d202b,0xbb8dd3c2,0xe9f97d96,0x7b3e67f7 +.long 0xb1cb6ac9,0x5aa5d78f,0xca1d0d45,0xffa13e8e,0x2ba5bf95,0x369295dd,0x39aff05e,0xd68bd1f8,0x26d783f2,0xaf0d86f9,0xfc3aafc1,0x543a59b3,0x7b7da97c,0x3fcf81d2,0xd25dee46,0xc990a056 +.long 0x519cce2c,0x3e6775b8,0xae13d863,0xfc9af71f,0x47c1605c,0x774a4a6f,0x2fd205e8,0x46ba4245,0xd3fd524d,0xa06feea4,0x6de1acc2,0x1e724641,0x334e2b42,0xf53816f1,0x922f0024,0x49e5918e +.long 0x65c7322d,0x439530b6,0xb3c1b3fb,0xcf12cc01,0x0172f685,0xc70b0186,0x1b58391d,0xb915ee22,0xa317db24,0x9afdf03b,0x17b8ffc4,0x87dec659,0xe4d3d050,0x7f46597b,0x006500e7,0x80a1c1ed +.long 0x78bf030e,0x84902a96,0x50560148,0xfb5e9c9a,0x63362426,0x6dae0a92,0xa9e30c40,0xdcaeecf4,0x518d0c6b,0xc0d887bb,0xcb985b9d,0x99181152,0xef7bc381,0xad186898,0x9ee46201,0x18168ffb +.long 0x2502753c,0x9a04cdaa,0x51407c41,0xbb279e26,0xf23564e5,0xeacb03aa,0x71e61016,0x18336582,0xeb809877,0x8684b8c4,0xea0e672e,0xb336e18d,0x34ee5867,0xefb601f0,0x1341cfd1,0x2733edbe +.long 0x26025c3c,0xb15e809a,0x9350df88,0xe6e981a6,0x8502fd8e,0x92376237,0x0c12be9b,0x4791f216,0x25f02425,0xb7256789,0x7a974443,0xec863194,0xfb41cc52,0x7c0ce882,0xf25c07f2,0xc266ff7e +.long 0x017025f3,0x3d4da8c3,0xfb9579b4,0xefcf628c,0x1f3716ec,0x5c4d0016,0x6801116e,0x9c27ebc4,0x1da1767e,0x5eba0ea1,0x47004c57,0xfe151452,0x8c2373b7,0x3ace6df6,0x5dbc37ac,0x75c3dffe +.long 0xddc925fc,0x3dc32a73,0x2f65ee0b,0xb679c841,0x451cbfeb,0x715a3295,0xf76e9a29,0xd9889768,0xb28ad247,0xec20ce7f,0x00894d79,0xe99146c4,0x9f5e3ea7,0x71457d7c,0x38030031,0x097b2662 +.long 0xcf9f82a8,0xdb7f6ae6,0x438f473a,0x319decb9,0x283856c3,0xa63ab386,0xb06a361b,0x13e3172f,0x7d5a006c,0x2959f8dc,0x75fba752,0x2dbc27c6,0x87c22c9e,0xc1227ab2,0x71a268b2,0x06f61f75 +.long 0x04779ce2,0x1b6bb971,0x0aadcb1d,0xaca83812,0xaeaab2d5,0x297ae0bc,0x5bfb9f13,0xa5c14ee7,0xf17a62c7,0xaa00c583,0x173759f6,0x39eb962c,0x86c9a88f,0x1eeba1d4,0xdf016c5e,0x0ab6c37a +.long 0xa28a0749,0xa2a147db,0xee519165,0x246c20d6,0xd3810715,0x5068d1b1,0x748160b9,0xb1e7018c,0xf380ff62,0x03f5b1fa,0xf3cb2c1e,0xef7fb1dd,0xfc91a7da,0xeab539a8,0xf3f9b561,0x83ddb707 +.long 0xfe7df7a4,0xc550e211,0x063f6f40,0xa7cd07f2,0x2976879c,0xb0de3635,0xe55741da,0xb5f83f85,0xf3d8ac3d,0x4ea9d25e,0x62819f02,0x6fe2066f,0xcef4a564,0x4ab2b9c2,0x5ffa2de3,0x1e155d96 +.long 0xc3a72d00,0x0eb0a19b,0x8513c31b,0x4037665b,0x04c64637,0x2fb2b6bf,0x08cdc639,0x45c34d6e,0xf01fd796,0x56f1e10f,0xfe3667b8,0x4dfb8101,0x9021d0c0,0xe0eda253,0x8a06c6ab,0x7a94e9ff +.long 0xbb9aa882,0x2d3bb0d9,0xec05fd10,0xea20e4e5,0x1a1ca64e,0xed7eeb5f,0xc6327cbd,0x2fa6b43c,0x3aa91121,0xb577e3cf,0x3a34079b,0x8c6bd5ea,0x60e02fc0,0xd7e5ba39,0x90141bf8,0xf16dd2c3 +.long 0x80101b98,0xb57276d9,0xb82f0f66,0x760883fd,0x4bc3eff3,0x89d7de75,0x5dc2ab40,0x03b60643,0xe05beeac,0xcd6e53df,0xbc3325cd,0xf2f1e862,0x774f03c3,0xdd0f7921,0x4552cc1b,0x97ca7221 +.long 0x1cd19f72,0x5a0d6afe,0xf183fbeb,0xa20915dc,0x832c403c,0x9fda4b40,0xbe425442,0x32738edd,0xb5eccf1a,0x469a1df6,0x28bbe1f0,0x4b5aff42,0x570dfc93,0x31359d7f,0xf0088628,0xa18be235 +.long 0xb00ed3a9,0xa5b30fba,0x73cdf8be,0x34c61374,0xabc56797,0x2c5c5f46,0xb82a8ae2,0x5cecf93d,0xa968fbf0,0x7d3dbe41,0x1a5c7f3d,0xd23d4583,0xc087a9c7,0xf28f69a0,0x474471ca,0xc2d75471 +.long 0x4eb732ec,0x36ec9f4a,0xb1ca6bed,0x6c943bbd,0xf2457892,0xd64535e1,0xf7e2ac06,0x8b84a8ea,0x2499dd5f,0xe0936cd3,0x0ed04e57,0x12053d7e,0xe4305d9d,0x4bdd0076,0x1f67f0a2,0x34a527b9 +.long 0x9cec46ea,0xe79a4af0,0x658b9bc7,0xb15347a1,0x35af2f75,0x6bd2796f,0x4051c435,0xac957990,0xc33a655d,0x2669dda3,0x88514aa3,0x5d503c2e,0x3753dd41,0xdfa11337,0x0b754f78,0x3f054673 +.long 0x496125bd,0xbf185677,0x3775006c,0xfb0023c8,0x3a037899,0xfa0f072f,0x0e4aea57,0x4222b6eb,0x7866d25a,0x3dde5e76,0x4837aa6f,0xb6eb04f8,0x2cf1cdb8,0x5315591a,0x2d4e683c,0x6dfb4f41 +.long 0x48ee1f3a,0x7e923ea4,0x05a2afd5,0x9604d9f7,0x40ea4948,0xbe1d4a33,0xb44cbd2f,0x5b45f1f4,0x4acc757e,0x5faf8376,0x63d68ff7,0xa7cf9ab8,0xdf0e404b,0x8ad62f69,0x12bdafdf,0xd65f33c2 +.long 0xa377b14e,0xc365de15,0x8e39f60c,0x6bf5463b,0x2ce68148,0x62030d2d,0xe6f843a8,0xd95867ef,0xef5ab017,0xd39a0244,0x4ab55d12,0x0bd2d8c1,0x41639169,0xc9503db3,0xf7660c8a,0x2d4e25b0 +.long 0xe224c5d7,0x760cb3b5,0x68616919,0xfa3baf8c,0x8d142552,0x9fbca113,0x7669ebf5,0x1ab18bf1,0x9bdf25dd,0x55e6f53e,0xcb6cd154,0x04cc0bf3,0x95e89080,0x595bef49,0x104a9ac1,0xfe9459a8 +.long 0xcce9bb32,0xad2d89ca,0xf7de8285,0xddea65e1,0xb351bd4b,0x62ed8c35,0x0c0e19a7,0x4150ff36,0x345f4e47,0x86e3c801,0x203a266c,0x3bf21f71,0x855b1f13,0x7ae110d4,0x07262517,0x5d6aaf6a +.long 0x813d28f1,0x1e0f12e1,0x7ad7a523,0x6000e11d,0xc744a17b,0xc7d8deef,0x14c05a00,0x1e990b48,0x93e976d5,0x68fddaee,0x46610d63,0x696241d1,0x893dda88,0xb204e7c3,0x6a3a6946,0x8bccfa65 +.long 0xc5cd1411,0xb59425b4,0xff3658b1,0x701b4042,0x4784cf93,0xe3e56bca,0x8fe68d60,0x27de5f15,0xf8d53f19,0x4ab9cfce,0xa40a730d,0xddb10311,0x4eee0a8a,0x6fa73cd1,0x5249719d,0xfd548748 +.long 0xa8123ef0,0x49d66316,0xe7f95438,0x73c32db4,0x0d9e7854,0x2e2ed209,0x9d9f0507,0xf98a9329,0x0c6aa20a,0xc5d33cf6,0x75279bb2,0x9a32ba14,0x774a7307,0x7e3202cb,0xe8c42dbd,0x64ed4bc4 +.long 0xd4caed0d,0xc20f1a06,0x171d22b3,0xb8021407,0xd13268d7,0xd426ca04,0x25f4d126,0x92377007,0x71f21a85,0x4204cbc3,0xf82369ba,0x18461b7a,0x3fc858f9,0xc0c07d31,0xe2bab569,0x5deb5a50 +.long 0xd5eea89e,0xd5959d46,0x08437f4b,0xfdff8424,0x3cfe254f,0xf21071e4,0x95468321,0x72417696,0x102cae3e,0x5d8288b9,0xf1965dff,0x2d143e3d,0xa078d847,0x00c9a376,0x26028731,0x6fc0da31 +.long 0xe45083a2,0xa2baeadf,0x5e5b4bcd,0x66bc7218,0xd04b8e7f,0x2c826442,0x6c4b586b,0xc19f5451,0x5b7eeed5,0x60182c49,0x7aa9dfa1,0xd9954ecd,0xc73884ad,0xa403a8ec,0x9bb39041,0x7fb17de2 +.long 0xabb020e8,0x694b64c5,0x19c4eec7,0x3d18c184,0x1c4793e5,0x9c4673ef,0x056092e6,0xc7b8aeb5,0xf0f8c16b,0x3aa1ca43,0xd679b2f6,0x224ed5ec,0x55a205c9,0x0d56eeaf,0x4b8e028b,0xbfe115ba +.long 0x3927f4fe,0x97e60849,0x759aa7c5,0xf91fbf94,0x6be90a51,0x985af769,0x78ccb823,0xc1277b78,0xe7a75952,0x395b656e,0x928da5f5,0x00df7de0,0x4ca4454f,0x09c23175,0x7aa2d3c1,0x4ec971f4 +.long 0xe75d9ccc,0x45c3c507,0x3dc90306,0x63b7be8a,0x5db44bdc,0x37e09c66,0x6841c6a2,0x50d60da1,0x08df1b12,0x6f9b65ee,0x7ff089df,0x38734879,0x3fe8013d,0x9c331a66,0x5f42fcc8,0x017f5de9 +.long 0xe8e57567,0x43077866,0xf9fcdb18,0xc9f781ce,0x9b12e174,0x38131dda,0x8a03752a,0x25d84aa3,0x4d0c0ce2,0x45e09e09,0x92bebba5,0x1564008b,0xa87284c7,0xf7e8ad31,0x97e7bbaa,0xb7c4b46c +.long 0x97acf4ec,0x3e22a7b3,0x5ea8b640,0x0426c400,0x4e969285,0x5e3295a6,0xa6a45670,0x22aabc59,0x5f5942bc,0xb929714c,0xfa3182ed,0x9a6168bd,0x104152ba,0x2216a665,0xb6926368,0x46908d03 +.long 0x5a1251fb,0xa9f5d874,0xc72725c7,0x967747a8,0x31ffe89e,0x195c33e5,0xe964935e,0x609d210f,0x2fe12227,0xcafd6ca8,0x0426469d,0xaf9b5b96,0x5693183c,0x2e9ee04c,0xc8146fef,0x1084a333 +.long 0xaed1d1f7,0x96649933,0x50563090,0x566eaff3,0xad2e39cf,0x345057f0,0x1f832124,0x148ff65b,0xcf94cf0d,0x042e89d4,0x520c58b3,0x319bec84,0x5361aa0d,0x2a267626,0x8fbc87ad,0xc86fa302 +.long 0x5c8b06d5,0xfc83d2ab,0xfe4eac46,0xb1a785a2,0x846f7779,0xb99315bc,0xef9ea505,0xcf31d816,0x15d7dc85,0x2391fe6a,0xb4016b33,0x2f132b04,0x181cb4c7,0x29547fe3,0x650155a1,0xdb66d8a6 +.long 0xadc1696f,0x6b66d7e1,0x0acd72d0,0x98ebe593,0xcc1b7435,0x65f24550,0xb4b9a5ec,0xce231393,0xdb067df9,0x234a22d4,0xcaff9b00,0x98dda095,0x6100c9c1,0x1bbc75a0,0x939cf695,0x1560a9c8 +.long 0x99e0925f,0xcf006d3e,0x6322375a,0x2dd74a96,0xb56af5ba,0xc58b446a,0xe0b9b4f1,0x50292683,0x1aeaffa3,0xe2c34cb4,0x9b9587c1,0x8b17203f,0xead1350c,0x6d559207,0xfb7f9604,0x2b66a215 +.long 0xfe51bf74,0x0850325e,0x5e460094,0x9c4f579e,0x76da2f25,0x5c87b92a,0x6febef33,0x889de4e0,0x646083ce,0x6900ec06,0xbfe12773,0xbe2a0335,0xc5344110,0xadd1da35,0xb802cd20,0x757568b7 +.long 0x00f7e6c8,0x75559779,0x0facd2f0,0x38e8b94f,0x03fde375,0xfea1f3af,0x75881dfc,0x5e11a1d8,0xc1e2f2ef,0xb3a6b02e,0xc605a6c5,0x193d2bbb,0x339a0b2d,0x325ffeee,0x9e0c8846,0x27b6a724 +.long 0xf1c367ca,0xe4050f1c,0xc90fbc7d,0x9bc85a9b,0xe1a11032,0xa373c4a2,0xad0393a9,0xb64232b7,0x167dad29,0xf5577eb0,0x94b78ab2,0x1604f301,0xe829348b,0x0baa94af,0x41654342,0x77fbd8dd +.long 0xb964e39a,0xdab50ea5,0xd0d3c76e,0xd4c29e3c,0x56d11964,0x80dae67c,0xe5ffcc2f,0x7307a8bf,0x91708c3b,0x65bbc1aa,0x28bf0eeb,0xa151e62c,0x6fa34db7,0x6cb53381,0xa29403a8,0x5139e05c +.long 0x94a7cd2e,0x6ff651b4,0x0699336c,0x5671ffd1,0x979a896a,0x6f5fd2cc,0xd8148cef,0x11e893a8,0x65cf7b10,0x988906a1,0xc50d8485,0x81b67178,0x8a35b3de,0x7c0deb35,0xc1d29799,0x423ac855 +.long 0xdac50b74,0xaf580d87,0x5869734c,0x28b2b89f,0x874e28fb,0x99a3b936,0x25f3f73a,0xbb2c9190,0x84a9d5b7,0x199f6918,0x7e770374,0x7ebe2325,0x0738efe2,0xf442e107,0xcf9082d2,0xcf9f3f56 +.long 0x09618708,0x719f69e1,0xc183f9b1,0xcc9e8364,0x366a21af,0xec203a95,0x068b141f,0x6aec5d6d,0x994f04e9,0xee2df78a,0x271245b0,0xb39ccae8,0x97e43f4f,0xb875a4a9,0xdb2cea98,0x507dfe11 +.long 0x489b03e9,0x4fbf81cb,0x6ec414fa,0xdb86ec5b,0xf51b3ae5,0xfad444f9,0x1914e3fe,0xca7d33d6,0x0ae6c4d0,0xa9c32f5c,0x73969568,0xa9ca1d1e,0x1aa7467e,0x98043c31,0xe21b5ac6,0xe832e75c +.long 0x5232123d,0x314b7aea,0x65ae86db,0x08307c8c,0xaa4668ed,0x06e7165c,0xb4d3ec39,0xb170458b,0xc19bb986,0x4d2e3ec6,0xae0304ed,0xc5f34846,0x6c9f9722,0x917695a0,0x4cab1c0a,0x6c7f7317 +.long 0x9d6d2e8b,0x6295940e,0x549f7c97,0xd318b8c1,0x97713885,0x22453204,0xa8a440fe,0x468d834b,0xbfba796e,0xd81fe5b2,0x6d71f116,0x152364db,0xb5b66e53,0xbb8c7c59,0x2641a192,0x0b12c61b +.long 0xfcf0a7fd,0x31f14802,0x5488b01e,0x42fd0789,0x9952b498,0x71d78d6d,0x07ac5201,0x8eb572d9,0x4d194a88,0xe0a2a44c,0xba017e66,0xd2b63fd9,0xf888aefc,0x78efc6c8,0x4a881a11,0xb76f6bda +.long 0xb46c2397,0x187f314b,0x5ded2819,0x004cf566,0x38764d34,0xa9ea5704,0x78084709,0xbba45217,0x1171121e,0x06474571,0xe7c9b671,0xad7b7eb1,0x730f7507,0xdacfbc40,0xc7ad7bd1,0x178cd8c6 +.long 0xb2a67238,0xbf0be101,0xaf9c14f2,0x3556d367,0xa5662075,0x104b7831,0x79d9e60a,0x58ca59bb,0xa569a73b,0x4bc45392,0x5698f6c9,0x517a52e8,0xaeadd755,0x85643da5,0x2a581b84,0x1aed0cd5 +.long 0x80af1372,0xb9b4ff84,0xf1ba5d1f,0x244c3113,0xf5f98d31,0x2a5dacbe,0x4375bc2a,0x2c3323e8,0x5594b1dd,0x17a3ab4a,0xceb4797e,0xa1928bfb,0xe4886a19,0xe83af245,0x72b5a74a,0x8979d546 +.long 0x19f9e967,0xa0f726bc,0xe8fbbf4e,0xd9d03152,0xb7707d40,0xcfd6f51d,0x63f6e6e0,0x633084d9,0x55667eaf,0xedcd9cdc,0x2e44d56f,0x73b7f92b,0x4e962b14,0xfb2e39b6,0xf671fcbf,0x7d408f6e +.long 0x164a89bb,0xcc634ddc,0x3ef3bd05,0x74a42bb2,0x428decbb,0x1280dbb2,0x402c8596,0x6103f6bb,0x355a5752,0xfa2bf581,0x00946674,0x562f96a8,0x6da0223b,0x4e4ca16d,0x28d3aa25,0xfe47819f +.long 0xf8dfcf8a,0x9eea3075,0x95669825,0xa284f0aa,0x867d3fd8,0xb3fca250,0x269d691e,0x20757b5f,0x93b8a5de,0xf2c24020,0xebc06da6,0xd3f93359,0xb2739c33,0x1178293e,0xbcd686e5,0xd2a3e770 +.long 0xcd941534,0xa76f49f4,0xe3c71c0e,0x0d37406b,0x3b97f7e3,0x172d9397,0xbd7fd0de,0xec17e239,0x6f496ba2,0xe3290551,0x36ad50e7,0x6a693172,0x83e7eff5,0xc4e539a2,0x18e1b4cf,0x752737e7 +.long 0x68af43ee,0xa2f7932c,0x703d00bd,0x5502468e,0x2fb061f5,0xe5dc978f,0x28c815ad,0xc9a1904a,0x470c56a4,0xd3af538d,0x193d8ced,0x159abc5f,0x20108ef3,0x2a37245f,0x223f7178,0xfa17081e +.long 0x10c8c0f5,0x27b0fb2b,0x40650547,0x2102c3ea,0x8ac3bfa7,0x594564df,0x509dad96,0x98102033,0xf1d18a13,0x6989643f,0xd7fc5af0,0x35eebd91,0xfaeaafd8,0x078d096a,0xdef3de98,0xb7a89341 +.long 0xecf2a73a,0x2a206e8d,0x8e551994,0x066a6397,0xb98d53a2,0x3a6a088a,0x2d1124aa,0x0ce7c67c,0x759a113c,0x48cec671,0x4f6f67fa,0xe3b373d3,0xfd36727b,0x5455d479,0xa13c0d81,0xe5a428ee +.long 0x1c86682b,0xb853dbc8,0xb8d02b2a,0xb78d2727,0x8ebc329a,0xaaf69bed,0x293b2148,0xdb6b40b3,0xb8c4961f,0xe42ea77d,0x20e5e0ab,0xb1a12f7c,0x79e8b05e,0xa0ec5274,0xfab60a80,0x68027391 +.long 0x16b1bd5e,0x6bfeea5f,0x4de30ad3,0xf957e420,0x6a353b9e,0xcbaf664e,0x26d14feb,0x5c873312,0xb65f57cb,0x4e87f98c,0x5e0cdd41,0xdb60a621,0xa6881440,0x67c16865,0x46ab52aa,0x1093ef1a +.long 0x3f4ece64,0xc095afb5,0x7604551a,0x6a6bb02e,0x0b26b8cd,0x55d44b4e,0xf971268a,0xe5f9a999,0x11a7de84,0xc08ec425,0xfda469dd,0x83568095,0x6c6c90a2,0x737bfba1,0xbe229831,0x1cb9c4a0 +.long 0xbb2eec64,0x93bccbba,0xda03adbe,0xa0c23b64,0xe0e86ac4,0x5f7aa00a,0xfc1401e6,0x470b941e,0x9df43574,0x5ad8d679,0x0f65d810,0x4ccfb8a9,0xaa7fbd81,0x1bce80e3,0x9508d20a,0x273291ad +.long 0x42a92806,0xf5c4b46b,0xa86ab44a,0x810684ec,0xca0bc9f8,0x4591640b,0x5c4b6054,0xb5efcdfc,0x6e9edd12,0x16fc8907,0xd4d792f9,0xe29d0b50,0x9b03116d,0xa45fd01c,0xc81765a4,0x85035235 +.long 0xb4b4b67c,0x1fe2a9b2,0xe8020604,0xc1d10df0,0xbc8058d8,0x9d64abfc,0x712a0fbb,0x8943b9b2,0x3b3def04,0x90eed914,0x4ce775ff,0x85ab3aa2,0x7bbc9040,0x605fd4ca,0xe2c75dfb,0x8b34a564 +.long 0x10358560,0x41ffc94a,0x9e5c28aa,0x2d8a5072,0x4cc7eb15,0xe915a0fc,0x8f6d0f5d,0xe9efab05,0xd19e9b91,0xdbab47a9,0x0276154c,0x8cfed745,0x2cfede0d,0x154357ae,0x19f5a4ef,0x520630df +.long 0xe382360f,0x25759f7c,0x88bf5857,0xb6db05c9,0x6c58d46c,0x2917d61d,0xfd20cb7a,0x14f8e491,0x11c20340,0xb68a727a,0xaf7ccbb6,0x0386f86f,0xfee09a20,0x5c8bc6cc,0xbb7eea35,0x7d76ff4a +.long 0xdb15be7a,0xa7bdebe7,0xd89f0302,0x67a08054,0xc1193364,0x56bf0ea9,0x62837ebe,0xc8244467,0x20d841b8,0x32bd8e8b,0xdbb8a54f,0x127a0548,0x63b20236,0x83dd4ca6,0x203491fa,0x87714718 +.long 0xaa8a5288,0x4dabcaaa,0xaf23a1c9,0x91cc0c8a,0x3f220e0c,0x34c72c6a,0x1232144a,0xbcc20bdf,0xa20ede1b,0x6e2f42da,0x74a00515,0xc441f00c,0x734b8c4b,0xbf46a5b6,0x7b56c9a4,0x57409503 +.long 0xe4585d45,0x9f735261,0x6734e642,0x9231faed,0xbe70ee6c,0x1158a176,0x7c3501bf,0x35f1068d,0xa2d26115,0x6beef900,0xef0afee3,0x649406f2,0xbc2420a1,0x3f43a60a,0xd5aee4ac,0x509002a7 +.long 0x3ff3571b,0xb46836a5,0x837927c1,0x24f98b78,0x4533c716,0x6254256a,0xd07ee196,0xf27abb0b,0x5c6d5bfd,0xd7cf64fc,0xf0cd7a77,0x6915c751,0x8798f534,0xd9f59012,0xf81d8b5f,0x772b0da8 +.long 0x2e03fa69,0x1244260c,0x3be1a374,0x36cf0e3a,0xef06b960,0x6e7c1633,0x671f90f6,0xa71a4c55,0x33c673db,0x7a941251,0x73e8c131,0xc0bea510,0xd4f6c734,0x61a8a699,0x341ed001,0x25e78c88 +.long 0x8e2f7d90,0x5c18acf8,0x77be32cd,0xfdbf33d7,0xd2eb5ee9,0x0a085cd7,0xb3201115,0x2d702cfb,0x85c88ce8,0xb6e0ebdb,0x1e01d617,0x23a3ce3c,0x567333ac,0x3041618e,0x157edb6b,0x9dd0fd8f +.long 0xb57872b8,0x27f74702,0x657d5fe1,0x2ef26b4f,0x57cf3d40,0x95426f0a,0x65a6067a,0x847e2ad1,0x09996a74,0xd474d9a0,0x2a26115c,0x16a56acd,0xd16f4d43,0x02a615c3,0xaadb85b7,0xcc3fc965 +.long 0xce07d1b0,0x386bda73,0x58ad4178,0xd82910c2,0xcd2617f4,0x124f82cf,0xef691770,0xcc2f5e8d,0xb8c30ccc,0x82702550,0x1a8e575a,0x7b856aea,0xb1ab9459,0xbb822fef,0xec24e38e,0x085928bc +.long 0xba8f4b4d,0x5d0402ec,0x00b4d58b,0xc07cd4ba,0x29227e7a,0x5d8dffd5,0x31bf386f,0x61d44d0c,0x135e6f4d,0xe486dc2b,0xe79410ef,0x680962eb,0xf10088b5,0xa61bd343,0xe2e28686,0x6aa76076 +.long 0x8fb98871,0x80463d11,0xbbc76aff,0xcb26f5c3,0xfbe03614,0xd4ab8edd,0xc0cf2dee,0xc8eb579b,0xc93bae41,0xcc004c15,0x3aeca3b2,0x46fbae5d,0x0f1e9ab1,0x671235cf,0x9ec285c1,0xadfba934 +.long 0xf216c980,0x88ded013,0xf79e0bc1,0xc8ac4fb8,0xfb97a237,0xa29b89c6,0x9922d8e7,0xb697b780,0xddb945b5,0x3142c639,0xe094c3a9,0x447b06c7,0x72266c90,0xcdcb3642,0xa9385046,0x633aad08 +.long 0xb57c6477,0xa36c936b,0xe94dbcc6,0x871f8b64,0xa591a67b,0x28d0fb62,0xc1d926f5,0x9d40e081,0xf2d84b5a,0x3111eaf6,0xa565b644,0x228993f9,0x2c83188b,0x0ccbf592,0x3df3e197,0xf87b30ab +.long 0x7642bca8,0xb8658b31,0x52800f17,0x1a032d7f,0x79bf9445,0x051dcae5,0x54a2e253,0xeba6b8ee,0xd4485692,0x5c8b9cad,0x8986e9be,0x84bda40e,0x2f0db448,0xd16d16a4,0xa14d4188,0x8ec80050 +.long 0x98fa7aaa,0xb2b26107,0xf073aa4e,0x41209ee4,0xf2d6b19b,0xf1570359,0xfc577caf,0xcbe6868c,0x32c04dd3,0x186c4bdc,0xcfeee397,0xa6c35fae,0xf086c0cf,0xb4a1b312,0xd9461fe2,0xe0a5ccc6 +.long 0x1536189f,0xc32278aa,0xba6df571,0x1126c55f,0xb194560e,0x0f71a602,0x324bd6e1,0x8b2d7405,0x3738be71,0x8481939e,0x1a4d97a9,0xb5090b1a,0xf05ba915,0x116c65a3,0xaae448aa,0x21863ad3 +.long 0xa7aae5d3,0xd24e2679,0x0de5c1c4,0x7076013d,0xbb05b629,0x2d50f8ba,0x6e66efbb,0x73c1abe2,0xf2488af7,0xefd4b422,0x663ba575,0xe4105d02,0x53a69457,0x7eb60a8b,0xc945973b,0x62210008 +.long 0x77a50ec6,0xfb255478,0x0a37a72c,0xbf0392f7,0x4be18e7a,0xa0a7a19c,0x25b1e0af,0x90d8ea16,0xef953f57,0x7582a293,0xbdc5465a,0x90a64d05,0xe2510717,0xca79c497,0x18cb641f,0x560dbb7c +.long 0x4b66abfb,0x1d8e3286,0x59030900,0xd26f52e5,0x5584941a,0x1ee3f643,0x569f5958,0x6d3b3730,0x4789dba5,0x9ff2a62f,0x72b5c9b7,0x91fcb815,0x6c8f9a0e,0xf446cb7d,0x39b7ecb5,0x48f625c1 +.long 0x1c6219b8,0xbabae801,0x28ac2f23,0xe7a562d9,0x26e20588,0xe1b48732,0x775af051,0x06ee1cad,0xfaff79f7,0xda29ae43,0x652ee9e0,0xc141a412,0x195f4bd0,0x1e127f6f,0x072f34f8,0x29c6ab4f +.long 0x30448112,0x7b7c1477,0xe4a38656,0x82b51af1,0x2f315010,0x2bf2028a,0x6ea88cd4,0xc9a4a01f,0x257e5818,0xf63e95d8,0xb4519b16,0xdd8efa10,0x0da910bf,0xed8973e0,0x5c0fe4a9,0xed49d077 +.long 0xb7caee1e,0xac3aac5e,0xa7f4da57,0x1033898d,0x5c6669b9,0x42145c0e,0xc1aa2aa0,0x42daa688,0x1a1d885a,0x629cc15c,0xf4b76817,0x25572ec0,0x9c8f8f28,0x8312e435,0x81965490,0x8107f8cd +.long 0x6fa6110c,0x516ff3a3,0xfb93561f,0x74fb1eb1,0x8457522b,0x6c0c9047,0x6bb8bdc6,0xcfd32104,0xcc80ad57,0x2d6884a2,0x86a9b637,0x7c27fc35,0xadf4e8cd,0x3461baed,0x617242f0,0x1d56251a +.long 0xc955bef4,0x0b80d209,0x06adb047,0xdf02cad2,0x5ec74fee,0xf0d7cb91,0x1111ba44,0xd2503375,0xdf53cb36,0x9671755e,0x3368551b,0x54dcb612,0xc8a025a4,0x66d69aac,0xe77ef445,0x6be946c6 +.long 0xa995e094,0x719946d1,0xe51e04d8,0x65e848f6,0x6a1e3113,0xe62f3300,0x501de503,0x1541c7c1,0xf4acfade,0x4daac9fa,0x44cd0b71,0x0e585897,0x0a51cd77,0x544fd869,0x0031016d,0x60fc20ed +.long 0xa4276867,0x58b404ec,0x34f34993,0x46f6c3cc,0xc636e5bd,0x477ca007,0x7c458b47,0x8018f5e5,0xe47b668f,0xa1202270,0xee14f203,0xcef48ccd,0x62ff9b4d,0x23f98bae,0xc589eddd,0x55acc035 +.long 0x64db4444,0x3fe712af,0xbecdd480,0x19e9d634,0xa930978a,0xe08bc047,0xa1280733,0x2dbf24ec,0x2cd706b2,0x3c0ae38c,0x359017b9,0x5b012a5b,0x72e0f5ae,0x3943c38c,0x57176fa3,0x786167ea +.long 0x594881dc,0xe5f9897d,0xcfb820c1,0x6b5efad8,0xd55018de,0xb2179093,0x0bac56ce,0x39ad7d32,0x2cfc0e81,0xb55122e0,0xf6d89daa,0x117c4661,0xcb64fa09,0x362d01e1,0x3e9c4ddd,0x6a309b4e +.long 0xabea49b1,0xfa979fb7,0x10e2c6c5,0xb4b1d27d,0x23afde7a,0xbd61c2c4,0x9786d358,0xeb6614f8,0x7f6f7459,0x4a5d816b,0x09360e7b,0xe431a44f,0xc309914c,0x8c27a032,0xcaede3d8,0xcea5d68a +.long 0x3a0a3f95,0x3668f665,0x7ceba27b,0x89369416,0xe4728fe9,0x89981fad,0x8a093562,0x7102c8a0,0x235d21c8,0xbb80310e,0xbefb7f7b,0x505e55d1,0x12958a67,0xa0a90811,0x4d851fef,0xd67e106a +.long 0x431dd80e,0xb84011a9,0x73306cd9,0xeb7c7cca,0xd1b3b730,0x20fadd29,0xfe37b3d3,0x83858b5b,0xb6251d5c,0xbf4cd193,0x1352d952,0x1cca1fd3,0x90fbc051,0xc66157a4,0x89b98636,0x7990a638 +.long 0x87dec0e1,0xe5aa692a,0xf7b39d00,0x010ded8d,0x54cfa0b5,0x7b1b80c8,0xa0f8ea28,0x66beb876,0x3476cd0e,0x50d7f531,0xb08d3949,0xa63d0e65,0x53479fc6,0x1a09eea9,0xf499e742,0x82ae9891 +.long 0x5ca7d866,0xab58b910,0x3adb3b34,0x582967e2,0xcceac0bc,0x89ae4447,0x7bf56af5,0x919c667c,0x60f5dcd7,0x9aec17b1,0xddcaadbc,0xec697b9f,0x463467f5,0x0b98f341,0xa967132f,0xb187f1f7 +.long 0x214aeb18,0x90fe7a1d,0x741432f7,0x1506af3c,0xe591a0c4,0xbb5565f9,0xb44f1bc3,0x10d41a77,0xa84bde96,0xa09d65e4,0xf20a6a1c,0x42f060d8,0xf27f9ce7,0x652a3bfd,0x3b3d739f,0xb6bdb65c +.long 0xec7fae9f,0xeb5ddcb6,0xefb66e5a,0x995f2714,0x69445d52,0xdee95d8e,0x09e27620,0x1b6c2d46,0x8129d716,0x32621c31,0x0958c1aa,0xb03909f1,0x1af4af63,0x8c468ef9,0xfba5cdf6,0x162c429f +.long 0x753b9371,0x2f682343,0x5f1f9cd7,0x29cab45a,0xb245db96,0x571623ab,0x3fd79999,0xc507db09,0xaf036c32,0x4e2ef652,0x05018e5c,0x86f0cc78,0xab8be350,0xc10a73d4,0x7e826327,0x6519b397 +.long 0x9c053df7,0xe8cb5eef,0xb300ea6f,0x8de25b37,0xc849cffb,0xdb03fa92,0xe84169bb,0x242e43a7,0xdd6f958e,0xe4fa51f4,0xf4445a8d,0x6925a77f,0xe90d8949,0xe6e72a50,0x2b1f6390,0xc66648e3 +.long 0x173e460c,0xb2ab1957,0x30704590,0x1bbbce75,0xdb1c7162,0xc0a90dbd,0x15cdd65d,0x505e399e,0x57797ab7,0x68434dcb,0x6a2ca8e8,0x60ad35ba,0xde3336c1,0x4bfdb1e0,0xd8b39015,0xbbef99eb +.long 0x1711ebec,0x6c3b96f3,0xce98fdc4,0x2da40f1f,0x57b4411f,0xb99774d3,0x15b65bb6,0x87c8bdf4,0xc2eef12d,0xda3a89e3,0x3c7471f3,0xde95bb9b,0xd812c594,0x600f225b,0x2b75a56b,0x54907c5d +.long 0x8db60e35,0xa93cc5f0,0xfa833319,0x743e3cd6,0xf81683c9,0x7dad5c41,0x9c34107e,0x70c1e7d9,0xa6be0907,0x0edc4a39,0x86d0b7d3,0x36d47035,0x272bfa60,0x8c76da03,0x0f08a414,0x0b4a07ea +.long 0x45c1dd53,0x699e4d29,0x231debb5,0xcadc5898,0xa77f00e0,0xdf49fcc7,0xa73e5a0e,0x93057bbf,0x027a4cd1,0x2f8b7ecd,0xc614011a,0x114734b3,0x67677c68,0xe7a01db7,0x7e273f4f,0x89d9be5e +.long 0x089808ef,0xd225cb2e,0xd59e4107,0xf1f7a27d,0x8211b9c9,0x53afc761,0xe6819159,0x0361bc67,0x7f071426,0x2a865d0b,0xe7072567,0x6a3c1810,0x0d6bcabd,0x3e3bca1e,0x408591bc,0xa1b02bc1 +.long 0x31fba239,0xe0deee59,0x98bd91d1,0xf47424d3,0x071a3c1d,0x0f8886f4,0xa819233b,0x3f7d41e8,0xcf6eb998,0x708623c2,0x609a287f,0x86bb49af,0x63c90762,0x942bb249,0x55a9654b,0x0ef6eea5 +.long 0x36f5defe,0x5f6d2d72,0x56f99176,0xfa9922dc,0xf78ce0c7,0x6c8c5ece,0xbe09b55e,0x7b44589d,0x9ea83770,0xe11b3bca,0x2ab71547,0xd7fa2c7f,0x2a1ddcc0,0x2a3dd6fa,0x5a7b7707,0x09acb430 +.long 0x649d4e57,0x4add4a2e,0x1917526e,0xcd53a2b0,0x20b44ac4,0xc5262330,0xbaa2c31d,0x4028746a,0x64291d4c,0x51318390,0xee5ad909,0xbf48f151,0x7b185681,0xcce57f59,0x4854d442,0x7c3ac1b0 +.long 0xc093c171,0x65587dc3,0x24f42b65,0xae7acb24,0x955996cb,0x5a338adb,0x6051f91b,0xc8e65675,0x28b8d0b1,0x66711fba,0xb6c10a90,0x15d74137,0x3a232a80,0x70cdd7eb,0x6191ed24,0xc9e2f07f +.long 0xf79588c0,0xa80d1db6,0xb55768cc,0xfa52fc69,0x7f54438a,0x0b4df1ae,0xf9b46a4f,0x0cadd1a7,0x1803dd6f,0xb40ea6b3,0x55eaae35,0x488e4fa5,0x382e4e16,0x9f047d55,0x2f6e0c98,0xc9b5b7e0 +.long 0x95762649,0x6b1bd2d3,0xc7aea3f6,0xa9604ee7,0x6dc6f896,0x3646ff27,0x2860bad1,0x9bf0e7f5,0x7cb44b92,0x2d92c821,0xaea9c182,0xa2f5ce63,0x9154a5fd,0xd0a2afb1,0x95801da6,0x482e474c +.long 0xb611c24b,0xc19972d0,0x60a8f351,0x1d468e65,0x7bcf6421,0xeb758069,0x88fbc491,0xec9dd0ee,0x956c2e32,0x5b59d2bf,0xdcddf94e,0x73dc6864,0xbcee7665,0xfd5e2321,0x5e9a06c4,0xa7b4f8ef +.long 0x7280f855,0xfba918dd,0x8baec688,0xbbaac260,0x33400f42,0xa3b3f00f,0x66f2e6e4,0x3d2dba29,0x98509375,0xb6f71a94,0xcea423cc,0x8f33031f,0x4807e6fb,0x009b8dd0,0x5cdb954c,0x5163cfe5 +.long 0xcf41c6e8,0x03cc8f17,0x037b925c,0xf1f03c2a,0x66d2427c,0xc39c19cc,0x7b6c18e4,0x823d24ba,0x901f0b4f,0x32ef9013,0xf8941c2e,0x684360f1,0x2c28092e,0x0ebaff52,0x256c932f,0x7891e4e3 +.long 0xac445e3d,0x51264319,0x8ea74381,0x553432e7,0x67e9c50a,0xe6eeaa69,0x62e628c7,0x27ced284,0x7a4afa57,0x3f96d375,0xe484c150,0xde0a14c3,0x38bd9923,0x364a24eb,0xe5177422,0x1df18da0 +.long 0xd8d38a9b,0x174e8f82,0xe7de1391,0x2e97c600,0xa1c175dd,0xc5709850,0x32ae5035,0x969041a0,0x76a2086b,0xcbfd533b,0xd7c2e8fe,0xd6bba71b,0x099dfb67,0xb2d58ee6,0x064a85d9,0x3a8b342d +.long 0x522f9be3,0x3bc07649,0xdf1f49a8,0x690c075b,0x3854ec42,0x80e1aee8,0x17689dc7,0x2a7dbf44,0x3faf4078,0xc004fc0e,0xdf11862c,0xb2f02e9e,0xa0a1b7b3,0xf10a5e0f,0x8936ec80,0x30aca623 +.long 0x02f40d9a,0xf83cbf05,0x2c318a4d,0x4681c468,0x0e9c2674,0x98575618,0x1847092e,0xbe79d046,0x78bd01e0,0xaf1e480a,0x72a51db9,0x6dd359e4,0xe3afbab6,0x62ce3821,0x17733199,0xc5cee5b6 +.long 0x6ffd9fbb,0xe08b30d4,0x36c610b7,0x6e5bc699,0x9ce262cf,0xf343cff2,0x68b914c1,0xca2e4e35,0x16de36c5,0x011d64c0,0x42e2b829,0xe0b10fdd,0x6685aaf8,0x78942981,0x230ede97,0xe7511708 +.long 0x3b922bf8,0x671ed8fc,0x4c29b133,0xe4d8c0a0,0x3b6e99c4,0x87eb1239,0x8793beba,0xaff3974c,0x2c18df9b,0x03749405,0x91007139,0xc5c3a293,0xe37a0b95,0x6a77234f,0xb661c96b,0x02c29a21 +.long 0x141ecf61,0xc3aaf1d6,0x3bb22f53,0x9195509e,0x22d51357,0x29597404,0x537bed60,0x1b083822,0xe07289f0,0xcd7d6e35,0x6dd86eff,0x1f94c48c,0xeb0f9cfa,0xc8bb1f82,0x1b2eb97d,0x9ee0b7e6 +.long 0x34d74e31,0x5a52fe2e,0x3bf79ab6,0xa352c310,0xabfeeb8f,0x97ff6c5a,0xf5c97305,0xbfbe8fef,0xa7904608,0xd6081ce6,0xc4fca249,0x1f812f3a,0xb9e5e200,0x9b24bc9a,0x38012ee8,0x91022c67 +.long 0x30a713a1,0xe83d9c5d,0x84ef0f93,0x4876e3f0,0xc1fbf928,0xc9777029,0xbce7d2a4,0xef7a6bb3,0xdfa2a659,0xb8067228,0xd877a48f,0xd5cd3398,0x025d0f3f,0xbea4fd8f,0x2eae7c2b,0xd67d2e35 +.long 0xcc5f4394,0x184de7d7,0x4536e142,0xb5551b5c,0xd34aa60a,0x2e89b212,0xf50051d5,0x14a96fea,0x0d12bb0b,0x4e21ef74,0x60b9677e,0xc522f020,0x2df7731d,0x8b12e467,0x7b326d31,0x39f80382 +.long 0x39024a94,0xdfb8630c,0x97319452,0xaacb96a8,0xeda3867c,0xd68a3961,0x77c4ffca,0x0c58e2b0,0x4da919fa,0x3d545d63,0xf15e2289,0xef79b69a,0x808bab10,0x54bc3d3d,0x45f82c37,0xc8ab3007 +.long 0x7c4a658a,0xc12738b6,0x40e72182,0xb3c47639,0x8798e44f,0x3b77be46,0x17a7f85f,0xdc047df2,0x5e59d92d,0x2439d4c5,0xe8e64d8d,0xcedca475,0x87ca9b16,0xa724cd0d,0xa5540dfe,0x35e4fd59 +.long 0xe4bcf6b1,0xf8c1ff18,0x295018fa,0x856d6285,0x3263c949,0x433f665c,0xa1f21409,0xa6a76dd6,0xcc7b4f79,0x17d32334,0x06720e4a,0xa1d03122,0x81d9bed5,0xadb6661d,0x11db15d1,0xf0d6fb02 +.long 0x1fb747d2,0x7fd11ad5,0x3033762b,0xab50f959,0xfbefaf5a,0x2a7e711b,0x3fef2bbf,0xc7393278,0x0df6f9be,0xe29fa244,0x71efd215,0x9092757b,0x4f3d6fd9,0xee60e311,0x0acfb78b,0x338542d4 +.long 0x38961a0f,0x44a23f08,0x986987ca,0x1426eade,0x4a863cc6,0x36e6ee2e,0x628b8b79,0x48059420,0x7396e1de,0x30303ad8,0x38c5aad1,0x5c8bdc48,0x5c8f5066,0x3e40e11f,0x8d246bbd,0xabd6e768 +.long 0x23330a01,0x68aa40bb,0xc34eafa0,0xd23f5ee4,0x5de02c21,0x3bbee315,0xd1d8dd06,0x18dd4397,0x122d7b44,0x3ba1939a,0xa33870d6,0xe6d3b40a,0x1c4fe3f8,0x8e620f70,0xd3a50cbf,0xf6bba1a5 +.long 0xcfc0aee0,0x4a78bde5,0xc08c50bd,0x847edc46,0xad63c9b2,0xbaa2439c,0x10fc2acb,0xceb4a728,0x26da033d,0xa419e40e,0x03e02683,0x6cc3889d,0xfdccf725,0x1cd28559,0x8d13d208,0x0fd7e0f1 +.long 0x1f0df9d4,0x01b9733b,0xa2b5e4f3,0x8cc2c5f3,0x3a304fd4,0x43053bfa,0x0a9f1aa7,0x8e87665c,0xd73dc965,0x087f29ec,0x3e9023db,0x15ace455,0x2bce28b4,0x2370e309,0xb6b1e84a,0xf9723442 +.long 0xb72d9f26,0xbeee662e,0xf0e47109,0xb19396de,0xe13289d0,0x85b1fa73,0x54e58e32,0x436cf77e,0xe990ef77,0x0ec833b3,0x1b11fc25,0x7373e3ed,0x0fc332ce,0xbe0eda87,0x8d7ea856,0xced04970 +.long 0x7e977ca0,0xf85ff785,0xdfdd5d2b,0xb66ee8da,0x905af461,0xf5e37950,0x966d487c,0x587b9090,0x32ba0127,0x6a198a1b,0x141615ac,0xa7720e07,0x996ef2f2,0xa23f3499,0x470bcb3d,0xef5f64b4 +.long 0x92b8c559,0xa526a962,0x69740a0f,0x0c14aac0,0xa6bdc0a5,0x0d41a9e3,0x9c48aef4,0x97d52106,0x3e7c253b,0xcf16bd30,0x47fdedc1,0xcc834b1a,0x373aab2e,0x7362c6e5,0xc5f590ff,0x264ed85e +.long 0x66d41870,0x7a46d9c0,0x4787ba09,0xa50c20b1,0xe3d44635,0x185e7e51,0x31e2d8dc,0xb3b3e080,0xa179e9d9,0xbed1e558,0x74a76781,0x2daa3f79,0x3a40864f,0x4372baf2,0x4fe75cb5,0x46900c54 +.long 0xf76765d0,0xb95f171e,0x95c87502,0x4ad726d2,0x4d7c99bd,0x2ec769da,0xc36cdfa8,0x5e2ddd19,0xa93e6dea,0xc22117fc,0x93771123,0xe8a2583b,0xfa08a3a2,0xbe2f6089,0x8f0e1112,0x4809d5ed +.long 0xda7a095e,0x3b414aa3,0x26f5aadd,0x9049acf1,0x6be8b84a,0x78d46a4d,0xb732b9b3,0xd66b1963,0xde6e9555,0x5c2ac2a0,0xb5bd8770,0xcf52d098,0x0fd28921,0x15a15fa6,0x8b27536d,0x56ccb81e +.long 0x9f4ccbb8,0x0f0d8ab8,0xdb221729,0xed5f44d2,0x00bed10c,0x43141988,0x1d735b8b,0xc94348a4,0x29ef8479,0x79f3e9c4,0x614c693f,0x4c13a4e3,0x8e143a14,0x32c9af56,0xe29ac5c4,0xbc517799 +.long 0x2774856f,0x05e17992,0x6c1bf55f,0x6e52fb05,0xe4f19e16,0xaeda4225,0xaf5ccb26,0x70f4728a,0xb2947f22,0x5d2118d1,0x281d6fb9,0xc827ea16,0x8cf0eabd,0x8412328d,0x03ef9dcf,0x45ee9fb2 +.long 0xbb937d63,0x8e700421,0xcc4b37a6,0xdf8ff2d5,0x5ced7b68,0xa4c0d5b2,0xc7308f59,0x6537c1ef,0x3b37f8e8,0x25ce6a26,0xdeebc6ce,0x170e9a9b,0x8728d72c,0xdd037952,0x850154bc,0x445b0e55 +.long 0x83a7337b,0x4b7d0e06,0xffecf249,0x1e3416d4,0x66a2b71f,0x24840eff,0xb37cc26d,0xd0d9a50a,0x6fe28ef7,0xe2198150,0x23324c7f,0x3cc5ef16,0x769b5263,0x220f3455,0xa10bf475,0xe2ade2f1 +.long 0x458d3671,0x28cd20fa,0x2dc4847b,0x1549722c,0x591941e3,0x6dd01e55,0x27128ccb,0x0e6fbcea,0x3bef0262,0xae1a1e6b,0x8f54e103,0xfa8c472c,0x72c052ec,0x7539c0a8,0x5a3490e9,0xd7b27369 +.long 0x71684349,0x143fe1f1,0x32e19b97,0x36b4722e,0x90980aff,0xdc059227,0x9e13d674,0x175c9c88,0x6e6bfdb1,0xa7de5b22,0xbedb4b46,0x5ea5b7b2,0xd34a6e44,0xd5570191,0xa24ff7e6,0xfcf60d2e +.long 0x677819e1,0x614a392d,0xaa5a29e8,0x7be74c7e,0x63c85f3f,0xab50fece,0x46cab337,0xaca2e2a9,0x122a6fe3,0x7f700388,0x882a04a8,0xdb69f703,0xcf7aed57,0x9a77935d,0x8d91c86f,0xdf16207c +.long 0x63ed9998,0x2fca49ab,0xa77ddf96,0xa3125c44,0x24344072,0x05dd8a86,0xfec3fb56,0xa023dda2,0x0c743032,0x421b41fc,0x5e438639,0x4f2120c1,0xc83c1b07,0xfb7cae51,0xcac2171a,0xb2370caa +.long 0x6cc820fb,0x2eb2d962,0xb85a44bf,0x59feee5c,0x5b6598f0,0x94620fca,0x7e314051,0x6b922cae,0x106bed4e,0xff8745ad,0xdfa1e9ab,0x546e71f5,0x1ec29487,0x935c1e48,0x4d936530,0x9509216c +.long 0x85c9a2db,0xc7ca3067,0x6be8606f,0xd6ae5152,0xe14c651d,0x09dbcae6,0x9bc32f96,0xc9536e23,0x34521b03,0xa90535a9,0x878756ff,0xf39c526c,0x8aedf03c,0x383172ec,0xefe0c034,0x20a8075e +.long 0x64026422,0xf22f9c62,0x24b9d076,0x8dd10780,0x3bef2950,0x944c742a,0x88a2b00b,0x55b9502e,0x86a09817,0xa59e14b4,0x47bb4071,0xa39dd3ac,0x3be0592f,0x55137f66,0xc9e63f5b,0x07fcafd4 +.long 0x346eb226,0x963652ee,0xec2facb7,0x7dfab085,0x691add26,0x273bf2b8,0xf2b46c44,0x30d74540,0xf2c2d065,0x05e8e73e,0xd42eeac9,0xff9b8a00,0x97209d22,0x2fcbd205,0xde14ea2c,0xeb740ffa +.long 0xa8aef518,0xc71ff913,0xfff4cfa2,0x7bfc74bb,0xb6b36048,0x1716680c,0x9ef79af1,0x121b2cce,0xa01eb3d3,0xbff3c836,0x5f79077b,0x50eb1c6a,0xa004bbcf,0xa48c32d6,0x7d64f61d,0x47a59316 +.long 0x93102016,0x6068147f,0x94d12576,0x12c5f654,0xc9bc6b91,0xefb071a7,0x6e23ea95,0x7c2da0c5,0xd4a1dd5d,0xf4fd45b6,0x9122b13c,0x3e7ad9b6,0xe6f57a48,0x342ca118,0x06f8288f,0x1c2e94a7 +.long 0x5a97d231,0x99e68f07,0x4d838758,0x7c80de97,0x05872727,0xbce0f5d0,0x19c4d016,0xbe5d95c2,0x9c2492ee,0x921d5cb1,0x404d6fb3,0x42192dc1,0x32f988d3,0x4c84dcd1,0xa17b8e85,0xde26d61f +.long 0x137c7408,0xc466dcb6,0x36a266da,0x9a38d7b6,0x83bebf1b,0x7ef5cb06,0x0fd014e3,0xe5cdcbbf,0xf65965a0,0x30aa376d,0xebb3e95e,0x60fe88c2,0x66ee6f20,0x33fd0b61,0x3f41f0a0,0x8827dcdb +.long 0x0c56c690,0xbf8a9d24,0xddb7641d,0x40265dad,0x3a6b662b,0x522b05bf,0xb1478c9b,0x466d1dfe,0x1484469b,0xaa616962,0x02df8f9f,0x0db60549,0x3cb8bf51,0xc37bca02,0x21371ce8,0x5effe346 +.long 0xff112c32,0xe8f65264,0x7b971fb2,0x8a9c736d,0x7b75080d,0xa4f19470,0x8839c59b,0xfc3f2c5a,0x5aeb49c2,0x1d6c777e,0xda1addfe,0xf3db034d,0x5535affc,0xd76fee5a,0xb92251fd,0x0853ac70 +.long 0x8b2a29d5,0x37e3d594,0x4de00ddb,0x28f1f457,0xf42c328b,0x8083c1b5,0xe493c73b,0xd8ef1d8f,0x41dc61bd,0x96fb6260,0x27ee2f8a,0xf74e8a9d,0x2c946a5d,0x7c605a80,0x3839ccfd,0xeed48d65 +.long 0x3a29467a,0x9894344f,0xc51eba6d,0xde81e949,0xa5e5c2f2,0xdaea066b,0x08c8c7b3,0x3fc8a614,0x06d0de9f,0x7adff88f,0x3b75ce0a,0xbbc11cf5,0xfbbc87d5,0x9fbb7acc,0x7badfde2,0xa1458e26 +.long 0xe039c256,0x1cb43668,0x7c17fd5d,0x5f26fb8b,0x79aa062b,0xeee426af,0xd78fbf04,0x072002d0,0xe84fb7e3,0x4c9ca237,0x0c82133d,0xb401d8a1,0x6d7e4181,0xaaa52592,0x73dbb152,0xe9430833 +.long 0xbe24319a,0xf92dda31,0xe095a8e7,0x03f7d28b,0x98782185,0xa52fe840,0x29c24dbc,0x276ddafe,0x1d7a64eb,0x80cd5496,0x7f1dbe42,0xe4360889,0x8438d2d5,0x2f81a877,0x85169036,0x7e4d52a8 +.long 0x1d59715d,0x19e3d5b1,0xd788983e,0xc7eaa762,0xabf1f248,0xe5a730b0,0xfae3fd83,0xfbab8084,0x53765b2f,0x65e50d21,0xfa127f3d,0xbdd4e083,0x397b1b10,0x9cf3c074,0xb1b59fd3,0x59f8090c +.long 0x615faa8f,0x7b15fd9d,0x968554ed,0x8fa1eb40,0x7aa44882,0x7bb4447e,0x029fff32,0x2bb2d0d1,0x6caa6d2f,0x075e2a64,0x22e7351b,0x8eb879de,0x9a506c62,0xbcd5624e,0xa87e24dc,0x218eaef0 +.long 0x44ddfa35,0x37e56847,0xdab3f747,0x9ccfc5c5,0x1ee96cf4,0x9ac1df3f,0x3b480b8f,0x0c0571a1,0x4b3a7b3c,0x2fbeb3d5,0x5dcdbb99,0x35c03669,0xb2415b3a,0x52a0f5dc,0x4413ed9a,0xd57759b4 +.long 0x3d30a2c5,0x1fe647d8,0xf78a81dc,0x0857f77e,0x131a4a9b,0x11d5a334,0x29d393f5,0xc0a94af9,0xdaa6ec1a,0xbc3a5c0b,0x88d2d7ed,0xba9fe493,0xbb614797,0xbb4335b4,0x72f83533,0x991c4d68 +.long 0xd2f01cb3,0x53258c28,0xd75db0b1,0x93d6eaa3,0xe87d0db4,0x419a2b0d,0xd8fe8493,0xa1e48f03,0xc508b23a,0xf747faf6,0x35d53549,0xf137571a,0xfcf9b838,0x9f5e58e2,0xa7fd3cf5,0xc7186cee +.long 0xe978a1d3,0x77b868ce,0x7ab92d04,0xe3a68b33,0x87a5b862,0x51029794,0x3a61d41d,0x5f0606c3,0x6f9326f1,0x2814be27,0xc6fe3c2e,0x2f521c14,0xacdf7351,0x17464d7d,0x777f7e44,0x10f5f9d3 +.long 0x269fb37d,0xce8e616b,0x7de62de5,0xaaf73804,0x4fdd4153,0xaba11175,0x3770b49b,0x515759ba,0xaa423a61,0x8b09ebf8,0xcd41fb92,0x592245a1,0x9b4c8936,0x1cba8ec1,0xaf36710e,0xa87e91e3 +.long 0x3d34a2e3,0x1fd84ce4,0xb43b5d61,0xee3759ce,0x619186c7,0x895bc78c,0xcbb9725a,0xf19c3809,0xde744b1f,0xc0be21aa,0x60f8056b,0xa7d222b0,0xb23efe11,0x74be6157,0x0cd68253,0x6fab2b4f +.long 0x4bf1d725,0xad33ea5f,0x4f6c950f,0x9c1d8ee2,0xa377af06,0x544ee78a,0x94a113e1,0x54f489bb,0x992fb7e8,0x8f11d634,0xa2a44347,0x0169a7aa,0x95020e00,0x1d49d4af,0xe08e120b,0x95945722 +.long 0xa4d32282,0xb6e33878,0x48020ae7,0xe36e029d,0x37a9b750,0xe05847fb,0xb29e3819,0xf876812c,0xd23a17f0,0x84ad138e,0xf0b3950e,0x6d7b4480,0x2fd67ae0,0xdfa8aef4,0x52333af6,0x8d3eea24 +.long 0xb15d5acc,0x0d052075,0xbd815bc4,0xc6d9c79f,0xdfa36cf2,0x8dcafd88,0x38aa9070,0x908ccbe2,0xba35afce,0x638722c4,0xfd6abf0b,0x5a3da8b0,0xc9c335c1,0x2dce252c,0x65aa799b,0x84e7f0de +.long 0xb99a72cb,0x2101a522,0x87618016,0x06de6e67,0xe6f3653e,0x5ff8c7cd,0xc7a6754a,0x0a821ab5,0x7cb0b5a2,0x7e3fa52b,0xc9048790,0xa7fb121c,0x06ce053a,0x1a725020,0x04e929b0,0xb490a31f +.long 0x62dd61ad,0xe17be47d,0x6be01371,0x781a961c,0xdae3cbba,0x1063bfd3,0x7f73c9ba,0x35647406,0x2736a129,0xf50e957b,0xed13f256,0xa6313702,0x3a19fcc5,0x9436ee65,0xe7a4c8b6,0xcf2bdb29 +.long 0xc5f95cd8,0xb06b1244,0xf4ab95f4,0xda8c8af0,0xb9e5836d,0x1bae59c2,0x3acffffc,0x07d51e7e,0xc2ccbcda,0x01e15e6a,0x8528c3e0,0x3bc1923f,0xa49fead4,0x43324577,0x2aa7a711,0x61a1b884 +.long 0x700230ef,0xf9a86e08,0xbd19adf8,0x0af585a1,0xf55ad8f2,0x7645f361,0x46c3614c,0x6e676223,0x4e774d3f,0x23cb257c,0xac102d1b,0x82a38513,0x7b126aa5,0x9bcddd88,0xeefd3ee4,0xe716998b +.long 0xfb167583,0x4239d571,0xd16c8f8a,0xdd011c78,0x69a27519,0x271c2895,0xd2d64b6a,0x9ce0a3b7,0xd5ec6738,0x8c977289,0x8840ef6b,0xa3b49f9a,0x9a453419,0x808c14c9,0x0cf0a2d5,0x5c00295b +.long 0x1d4bcc76,0x524414fb,0x459a88f1,0xb07691d2,0xf70d110f,0x77f43263,0xb7abf9f3,0x64ada5e0,0x5b544cf5,0xafd0f94e,0xfd2713fe,0xb4a13a15,0x250c74f4,0xb99b7d6e,0x20324e45,0x097f2f73 +.long 0xaffa8208,0x994b37d8,0xdc29aafc,0xc3c31b0b,0x7a3a607f,0x3da74651,0xfe6955d6,0xd8e1b8c1,0xc8418682,0x716e1815,0x7dc91d97,0x541d487f,0xc6996982,0x48a04669,0x83a6502e,0xf39cab15 +.long 0xe68db055,0x025801a0,0xba3338d5,0xf3569758,0xee2afa84,0xb0c8c0aa,0xfb6562d1,0x4f6985d3,0x132ed17a,0x351f1f15,0xc04365fe,0x510ed0b4,0xe5b1f066,0xa3f98138,0x32df03dc,0xbc9d95d6 +.long 0x19abd09e,0xa83ccf6e,0x4ff17edb,0x0b4097c1,0xd64a06ce,0x58a5c478,0x544a58fd,0x2ddcc3fd,0x9e8153b8,0xd449503d,0x7774179b,0x3324fd02,0xdbd9120c,0xaf5d47c8,0x34fa94db,0xeb860162 +.long 0x972f07f4,0x5817bdd1,0xd27bbceb,0xe5579e2e,0x5f11e5a6,0x86847a1f,0x7c3cf048,0xb39ed255,0xa2f62e55,0xe1076417,0x1bcf82a2,0x6b9ab38f,0x7aeb29f9,0x4bb7c319,0x17227a46,0xf6d17da3 +.long 0x0f968c00,0xab53ddbd,0x000c880b,0xa03da7ec,0x6a9ad24d,0x7b239624,0x01ec60d0,0x612c0401,0x109f5df1,0x70d10493,0x80af7550,0xfbda4030,0xc6b9a9b3,0x30b93f95,0x007d9418,0x0c74ec71 +.long 0x6edb951f,0x94175564,0x7f22c282,0x5f4a9d78,0xb38d1196,0xb7870895,0xa228ce7c,0xbc593df3,0x6af3641a,0xc78c5bd4,0x3d9b3dcc,0x7802200b,0x8be33304,0x0dc73f32,0x61ffb79a,0x847ed87d +.long 0x6d671192,0xf85c974e,0xde16f60f,0x1e14100a,0x95c38797,0x45cb0d5a,0x9b022da4,0x18923bba,0xbbe7e86e,0xef2be899,0x216067bf,0x4a1510ee,0x84d5ce3e,0xd98c8154,0xf92a2b90,0x1af777f0 +.long 0x4ef65724,0x9fbcb400,0x3c0ca6fe,0x3e04a4c9,0x55002994,0xfb3e2cb5,0x5363ecab,0x1f3a93c5,0x3923555b,0x1fe00efe,0x1e1751ea,0x744bedd9,0x6ab69357,0x3fb2db59,0xf5e6618b,0x8dbd7365 +.long 0xdf1ea40e,0x99d53099,0x57d61e64,0xb3f24a0b,0x596eb812,0xd088a198,0x5762940b,0x22c8361b,0xf9c0d95c,0x66f01f97,0x8e43cdae,0x88461172,0xb72b15c3,0x11599a7f,0x420d95cc,0x135a7536 +.long 0x5f7ae2f6,0x2dcdf0f7,0xd7fa6da2,0x15fc6e1d,0xd1d441b6,0x81ca829a,0x04a106b6,0x84c10cf8,0xa73fbbd0,0xa9b26c95,0x4d8f6ee8,0x7f24e0cb,0x1e25a043,0x48b45937,0x036f3dfe,0xf8a74fca +.long 0xc9f84296,0x1ed46585,0x3bc278b0,0x7fbaa8fb,0x6c4fcbd0,0xa8e96cd4,0x73b60a5f,0x940a1202,0x55a4aec8,0x34aae120,0xdbd742f0,0x550e9a74,0x228c68ab,0x794456d7,0xa4e25ec6,0x492f8868 +.long 0xb2d8f398,0x682915ad,0x5b84c953,0xf13b51cc,0x5bb917d6,0xcda90ab8,0x4ea3dee1,0x4b615560,0x0a52c1c8,0x578b4e85,0x20b75fc4,0xeab1a695,0xaa0bb3c6,0x60c14f3c,0xb8216094,0x220f448a +.long 0xb0e63d34,0x4fe7ee31,0xa9e54fab,0xf4600572,0xd5e7b5a4,0xc0493334,0x06d54831,0x8589fb92,0x6583553a,0xaa70f5cc,0xe25649e5,0x0879094a,0x10044652,0xcc904507,0x02541c4f,0xebb0696d +.long 0xb9718710,0x5a171fde,0xf374a9f5,0x38f1bed8,0xba39bdc1,0xc8c582e1,0x908cc0ce,0xfc457b0a,0x883841e2,0x9a187fd4,0x38725381,0x8ec25b39,0x96f84395,0x2553ed05,0x6f6c6897,0x095c7661 +.long 0x4bdc5610,0x917ac85c,0x179eb301,0xb2885fe4,0x8b78bdcc,0x5fc65547,0xe59e4699,0x4a9fc893,0x3ce299af,0xbb7ff0cd,0xadf38b20,0x195be9b3,0xd38ddb8f,0x6a929c87,0xb21a51b9,0x55fcc99c +.long 0x721a4593,0x2b695b4c,0x768eaac2,0xed1e9a15,0x7489f914,0xfb63d71c,0x78118910,0xf98ba31c,0x9b128eb4,0x80291373,0xd448af4a,0x7801214e,0x55418dd3,0xdbd2e22b,0xd3998242,0xeffb3c0d +.long 0xc7bf3827,0xdfa6077c,0x47f8238f,0xf2165bcb,0x8564d554,0xfe37cf68,0x0a81fb98,0xe5f825c4,0xffed4d6f,0x43cc4f67,0xb50a34b0,0xbc609578,0x5041faf1,0x8aa8fcf9,0x651773b6,0x5659f053 +.long 0x6044d63b,0xe87582c3,0x0cdb0ca0,0xa6089409,0xbfb2bcf6,0x8c993e0f,0x45985cfc,0xfc64a719,0x83dbedba,0x15c4da80,0x2be67df7,0x804ae112,0xa23defde,0xda4c9658,0x5156e0d3,0x12002ddd +.long 0x5dd21b96,0xe68eae89,0xcf44624d,0x8b99f28b,0x1ec8897a,0x0ae00808,0x6712f76e,0xdd0a9303,0x4e233de4,0x96237522,0x2b36a8a5,0x192445b1,0x023993d9,0xabf9ff74,0x2aad4a8f,0x21f37bf4 +.long 0xf8bd2bbd,0x340a4349,0x4868195d,0x1d902cd9,0xe5fdb6f1,0x3d27bbf1,0x124f9f1c,0x7a5ab088,0xf7a09e03,0xc466ab06,0x31f2c123,0x2f8a1977,0x041b6657,0xda355dc7,0x8ece2a7c,0xcb840d12 +.long 0x7db32675,0xb600ad9f,0x07a06f1b,0x78fea133,0xb31f6094,0x5d032269,0x83ec37aa,0x07753ef5,0x9c0bea78,0x03485aed,0xbc3f4524,0x41bb3989,0x697f726d,0x09403761,0xdf394820,0x6109beb3 +.long 0x3b6d1145,0x804111ea,0xa8582654,0xb6271ea9,0x24e66562,0x619615e6,0xd7b6ad9c,0xa2554945,0x99bfe35f,0xd9c4985e,0x7b51cdf6,0x9770ccc0,0x92881832,0x7c327013,0x286b26d1,0x8777d45f +.long 0xd847999d,0x9bbeda22,0xc3525d32,0x03aa33b6,0x28a959a1,0x4b7b96d4,0x31e5d234,0xbb3786e5,0x6961f247,0xaeb5d3ce,0x02f93d3f,0x20aa85af,0xd7a7ae4f,0x9cd1ad3d,0x781adaa8,0xbf6688f0 +.long 0x7469cead,0xb1b40e86,0x309fca48,0x1904c524,0x4b54bbc7,0x9b7312af,0x593affa2,0xbe24bf8f,0xbd98764b,0xbe5e0790,0xa26e299e,0xa0f45f17,0x6b8fe4c7,0x4af0d2c2,0x8ae8a3e6,0xef170db1 +.long 0x29e0ccc1,0x0e8d61a0,0x60ad36ca,0xcd53e87e,0xc8173822,0x328c6623,0xa496be55,0x7ee1767d,0x648945af,0x89f13259,0x25c8009c,0x9e45a5fd,0x1f61ab8c,0xaf2febd9,0x8a275385,0x43f6bc86 +.long 0xf2142e79,0x87792348,0xc6e6238a,0x17d89259,0x4a839d9b,0x7536d2f6,0x76a1fbdc,0x1f428fce,0x0db06dfe,0x1c109601,0x50a3a3cc,0xbfc16bc1,0x9b30f41b,0xf9cbd9ec,0x00138cce,0x5b5da0d6 +.long 0x56ef96a7,0xec1d0a48,0x982bf842,0xb47eb848,0xec3f700d,0x66deae32,0xaa1181e0,0x4e43c42c,0xd1a4aa2a,0xa1d72a31,0xc004f3ce,0x440d4668,0x45fe8a7a,0x0d6a2d3b,0xfb128365,0x820e52e2 +.long 0x25e51b09,0x29ac5fcf,0x2023d159,0x180cd2bf,0xa1ebf90e,0xa9892171,0x7c132181,0xf97c4c87,0xc03dbb7e,0x9f1dc724,0x018cbbe4,0xae043765,0x0767d153,0xfb0b2a36,0x249cbaeb,0xa8e2f4d6 +.long 0xd95ea168,0x172a5247,0x2970764a,0x1758fada,0x1d978169,0xac803a51,0xde77e01b,0x299cfe2e,0xb0a98927,0x652a1e17,0x20014495,0x2e26e1d1,0x7175b56a,0x7ae0af9f,0xd64b9f95,0xc2e22a80 +.long 0xd90a060a,0x4d0ff9fb,0xbaf38085,0x496a27db,0xda776bcf,0x32305401,0x725f209e,0xb8cdcef6,0x436a0bba,0x61ba0f37,0x76860049,0x263fa108,0xda3542cf,0x92beb98e,0xd5849538,0xa2d4d14a +.long 0x12e9a1bc,0x989b9d68,0x5f6e3268,0x61d9075c,0x99ace638,0x352c6aa9,0x920f43ff,0xde4e4a55,0xd673c017,0xe5e4144a,0x6f6e05ea,0x667417ae,0xdcd1bd56,0x613416ae,0x86693711,0x5eb36201 +.long 0x3a1aa914,0x2d7bc504,0x76dc5975,0x175a1299,0x3fc8125c,0xe900e0f2,0x11198875,0x569ef68c,0x63a113b4,0x9012db63,0x98835766,0xe3bd3f56,0x76412dea,0xa5c94a52,0xaa735e5c,0xad9e2a09 +.long 0x508b65e9,0x405a984c,0x6df1a0d1,0xbde4a1d1,0xdfba80da,0x1a9433a1,0x9440ad2e,0xe9192ff9,0x5099fe92,0x9f649696,0x0b27a54a,0x25ddb65c,0xc590da61,0x178279dd,0xfbde681a,0x5479a999 +.long 0x013fe162,0xd0e84e05,0x632d471b,0xbe11dc92,0xfc0e089f,0xdf0b0c45,0x4c144025,0x04fb15b0,0x13c99927,0xa61d5fc2,0x3de2eb35,0xa033e9e0,0xb8dacbb4,0xf8185d5c,0x8644549d,0x9a88e265 +.long 0x54671ff6,0xf717af62,0x5fa58603,0x4bd4241b,0xe67773c0,0x06fba40b,0x6a2847e9,0xc1d933d2,0x689e2c70,0xf4f5acf3,0x46bafd31,0x92aab0e7,0x3473f6e5,0x798d76aa,0x93141934,0xcc6641db +.long 0xd31e535e,0xcae27757,0x87c2ee11,0x04cc43b6,0x2e029ffa,0x8d1f9675,0xe4cc7a2c,0xc2150672,0x8d68b013,0x3b03c1e0,0xedf298f3,0xa9d6816f,0xa2804464,0x1bfbb529,0x5db22125,0x95a52fae +.long 0x0e1cb64e,0x55b32160,0x7e7fc9fe,0x004828f6,0x1bb0fb93,0x13394b82,0x35f1a920,0xb6293a2d,0xd145d2d9,0xde35ef21,0xbb8fa603,0xbe6225b3,0x32cf252d,0x00fc8f6b,0x117cf8c2,0xa28e52e6 +.long 0x4c371e6d,0x9d1dc89b,0x36ef0f28,0xcebe0675,0xa4292f81,0x5de05d09,0x353e3083,0xa8303593,0x7e37a9bb,0xa1715b0a,0x2b8faec3,0x8c56f61e,0x33c9b102,0x52507431,0xa44431f0,0x0130cefc +.long 0xbd865cfb,0x56039fa0,0xbc5f1dd7,0x4b03e578,0xbabe7224,0x40edf2e4,0x3a1988f6,0xc752496d,0x564beb6b,0xd1572d3b,0x39a1c608,0x0db1d110,0x16f60126,0x568d1934,0xf354af33,0x05ae9668 +.long 0xc92544f2,0x19de6d37,0xa35837d5,0xcc084353,0x1a514ece,0xcbb6869c,0x2e1d1066,0xb633e728,0x936c581c,0xf15dd69f,0x7439c4f9,0x96e7b8ce,0x2e448a5b,0x5e676f48,0xfd916bbb,0xb2ca7d5b +.long 0xf5024025,0xd55a2541,0xe4c2d937,0x47bc5769,0x0362189f,0x7d31b92a,0xef7816f9,0x83f3086e,0xb587579a,0xf9f46d94,0x30e76c5f,0xec2d22d8,0xb000ffcf,0x27d57461,0x364ffc2c,0xbb7e65f9 +.long 0x6652a220,0x7c7c9477,0xd696c981,0x61618f89,0x89effff3,0x5021701d,0x7c314163,0xf2c8ff8e,0x8efb4d3e,0x2da413ad,0xce176d95,0x937b5adf,0x2a67d51c,0x22867d34,0x18eb3ac9,0x262b9b10 +.long 0xc43ff28b,0x4e314fe4,0x6a664e7a,0x76476627,0xb7a565c2,0x3e90e40b,0xc1acf831,0x8588993a,0x8f938829,0xd7b501d6,0x3edd7d4c,0x996627ee,0x90cd34c7,0x37d44a62,0xf3833e8d,0xa8327499 +.long 0x4bf50353,0x2e18917d,0x556765fb,0x85dd726b,0x93d5ab66,0x54fe65d6,0x915c25fe,0x3ddbaced,0x12f22e85,0xa799d9a4,0x6d06f6bc,0xe2a24867,0x43ca1637,0xf4f1ee56,0x61ece30a,0xfda2828b +.long 0xa2dee7a6,0x758c1a3e,0x734b2284,0xdcde2f3c,0x4eaba6ad,0xaba445d2,0x76cee0a7,0x35aaf668,0xe5aa049a,0x7e0b04a9,0x91103e84,0xe74083ad,0x40afecc3,0xbeb183ce,0xea043f7a,0x6b89de9f +.long 0xfe67ba66,0x0e299d23,0x93cf2f34,0x91450760,0x97fcf913,0xf45b5ea9,0x8bd7ddda,0x5be00843,0xd53ff04d,0x358c3e05,0x5de91ef7,0xbf7ccdc3,0xb69ec1a0,0xad684dbf,0x801fd997,0x367e7cf2 +.long 0xb0dc8595,0x0ca1f3b7,0x9f1d9f2e,0x27de4608,0xbadd82a7,0x1af3bf39,0x65862448,0x79356a79,0xf5f9a052,0xc0602345,0x139a42f9,0x1a8b0f89,0x844d40fc,0xb53eee42,0x4e5b6368,0x93b0bfe5 +.long 0xc024789c,0x5434dd02,0x41b57bfc,0x90dca9ea,0x243398df,0x8aa898e2,0x894a94bb,0xf607c834,0xc2c99b76,0xbb07be97,0x18c29302,0x6576ba67,0xe703a88c,0x3d79efcc,0xb6a0d106,0xf259ced7 +.long 0xc8de610b,0x0f893a5d,0x67e223ce,0xe8c515fb,0x4ead6dc5,0x7774bfa6,0x925c728f,0x89d20f95,0x098583ce,0x7a1e0966,0x93f2a7d7,0xa2eedb94,0x4c304d4a,0x1b282097,0xc077282d,0x0842e3da +.long 0x3b9e2d7b,0xe4d972a3,0xc48218ff,0x7cc60b27,0x84149d91,0x8fc70838,0x2f461ecc,0x5c04346f,0x614650a9,0xebe9fdf2,0xc1f666ac,0x5e35b537,0x88babc83,0x645613d1,0xc5e1c93e,0x88cace3a +.long 0x3de92e23,0x209ca375,0x5fbbb6e3,0xccb03cc8,0xd7b1487e,0xccb90f03,0xc710941f,0xfa9c2a38,0x6724ceed,0x756c3823,0x192d0323,0x3a902258,0xea5e038e,0xb150e519,0xc7427591,0xdcba2865 +.long 0x78890732,0xe549237f,0x53fcb4d9,0xc443bef9,0xeb3480d6,0x9884d8a6,0x3048b186,0x8a35b6a1,0x65e9a90a,0xb4e44716,0x653006c0,0x45bf380d,0x4fe9ae3b,0x8f3f820d,0x979a3b71,0x244a35a0 +.long 0x74cd06ff,0xa1010e9d,0xaca3eeac,0x9c17c7df,0x8063aa2b,0x74c86cd3,0x734614ff,0x8595c4b3,0x990f62cc,0xa3de00ca,0xca0c3be5,0xd9bed213,0xdf8ce9f5,0x7886078a,0x5cd44444,0xddb27ce3 +.long 0x58926ddd,0xed374a66,0x908015b8,0x138b2d49,0xde1f7ab8,0x886c6579,0xc3020b7a,0x888b9aa0,0x3a96e355,0xd3ec034e,0xf30fbe9a,0xba65b0b8,0xff21367a,0x064c8e50,0x0b04b46e,0x1f508ea4 +.long 0x747c866c,0x98561a49,0x0518a062,0xbbb1e5fe,0xecdc3608,0x20ff4e8b,0x20184027,0x7f55cded,0xf38c85f0,0x8d73ec95,0x8bc3b8c3,0x5b589fdf,0x0f12b66f,0xbe95dd98,0x0e338e01,0xf5bd1a09 +.long 0x5e915918,0x65163ae5,0x86f8a46b,0x6158d6d9,0xeeebf99c,0x8466b538,0xbca477ef,0xca8761f6,0x9ebbc601,0xaf3449c2,0xe0c3ae2f,0xef3b0f41,0x5de63752,0xaa6c577d,0x64682a51,0xe9166601 +.long 0xfc15aa1e,0x5a3097be,0xb54b0745,0x40d12548,0x519a5f12,0x5bad4706,0xa439dee6,0xed03f717,0x4a02c499,0x0794bb6c,0xcffe71d2,0xf725083d,0x0f3adcaf,0x2cad7519,0x43729310,0x7f68ea1c +.long 0xb7ffd977,0xe747c8c7,0x80761a22,0xec104c35,0x5a3ffb83,0x8395ebaf,0xe4b63db7,0xfb3261f4,0xd883e544,0x53544960,0x8cc2eeb8,0x13520d70,0xd3d65f99,0x08f6337b,0x781cf95b,0x83997db2 +.long 0x0dbd2c01,0xce6ff106,0x1f9ce934,0x4f8eea6b,0x0e993921,0x546f7c4b,0x5e753fc7,0x6236a324,0xa16022e9,0x65a41f84,0x43d1dbb2,0x0c18d878,0x2d4cef9c,0x73c55640,0x70444c74,0xa0428108 +.long 0x9afdfb3c,0x68e4f15e,0x5bdfb6df,0x49a56143,0x5f823d97,0xa9bc1bd4,0xea111c2a,0xbceb5970,0xb269bbc4,0x366b455f,0xe9bc5d62,0x7cd85e1e,0x4f18b086,0xc743c41c,0x95294fb9,0xa4b40990 +.long 0x26ee8382,0x9c7c581d,0x359d638e,0xcf17dcc5,0xb728ae3d,0xee8273ab,0xf821f047,0x1d112926,0x50491a74,0x11498477,0xfde0dfb9,0x687fa761,0x7ea435ab,0x2c258022,0x91ce7e3f,0x6b8bdb94 +.long 0x3bf834aa,0x4c5b5dc9,0x4f6c7e4b,0x04371819,0x3736bcad,0xc284e00a,0x21ae8f8d,0x0d881118,0xf48c8e33,0xf9cf0f82,0xa1bf40db,0xa11fd075,0xdc2733e5,0xdceab0de,0x8e986bd7,0xc560a8b5 +.long 0x3929d097,0x48dd1fe2,0x92f188f1,0x3885b290,0xda6fcdac,0x0f2ae613,0xb662a46c,0x9054303e,0x0738042a,0xb6871e44,0xbdaf6449,0x98e6a977,0xd1c9df1b,0xd8bc0650,0x36e098f9,0xef3d6451 +.long 0xb6d72d28,0x03fbae82,0xf5d84080,0x77ca9db1,0xa58efc1c,0x8a112cff,0xc564cb4a,0x518d761c,0xf0d1b5ce,0x69b5740e,0xe9eb1785,0x717039cc,0x22f53382,0x3fe29f90,0x6bc7c95c,0x8e54ba56 +.long 0xf7f91d0f,0x9c806d8a,0xa82a5728,0x3b61b0f1,0x94d76754,0x4640032d,0x47d834c6,0x273eb5de,0x7b4e4d53,0x2988abf7,0xde401777,0xb7ce66bf,0x715071b3,0x9fba6b32,0xad3a1a98,0x82413c24 +.long 0xe0e8ad93,0x5b7fc8c4,0x5fab868d,0xb5679aee,0x2b3946f3,0xb1f9d2fa,0x5685b50a,0x458897dc,0x89d0caf3,0x1e98c930,0x78642e92,0x39564c5f,0x0dbdaf18,0x1b77729a,0x579e82e6,0xf9170722 +.long 0xe4515fa5,0x680c0317,0xfb0c790f,0xf85cff84,0x6d2e0765,0xc7a82aab,0x35c82b32,0x7446bca9,0x6d63184f,0x5de607aa,0x262803a6,0x7c1a46a8,0xaebe8035,0xd218313d,0xc73c51f8,0x92113ffd +.long 0x12e7e46c,0x4b38e083,0x56126bd5,0x69d0a37a,0x73c07e04,0xfb3f324b,0x8fda7267,0xa0c22f67,0x4d2c7d8f,0x8f2c0051,0xcbe2cae5,0xbc45ced3,0xa8f0f277,0xe1c6cf07,0x1eb99a98,0xbc392312 +.long 0x3cc8ac85,0x75537b7e,0xdd02753b,0x8d725f57,0xb737df2f,0xfd05ff64,0xf6d2531d,0x55fe8712,0x6ab6b01c,0x57ce04a9,0x7cd93724,0x69a02a89,0xcf86699b,0x4f82ac35,0x9cb4b232,0x8242d3ad +.long 0xd62105e5,0x713d0f65,0x2d29be61,0xbb222bfa,0x6cfbef09,0xf2f9a79e,0xd5d6782f,0xfc24d8d3,0xd4129967,0x5db77085,0xdc3c2a43,0xdb81c3cc,0x05d8d9a3,0x9d655fc0,0x54298026,0x3f5d057a +.long 0x88c54694,0x1157f56d,0x9b09573e,0xb26baba5,0x22adffd1,0x2cab03b0,0xdd69f383,0x60a412c8,0x54b25039,0xed76e98b,0x687e714d,0xd4ee67d3,0x7b00b594,0x87739648,0xc9ef709b,0xce419775 +.long 0x1c203a40,0x40f76f85,0xeafd8f91,0x30d352d6,0x95578dd2,0xaf196d3d,0x77cc3f3d,0xea4bb3d7,0xb98e782b,0x42a5bd03,0x0624920d,0xac958c40,0xfc56fcc8,0xb838134c,0x89572e5e,0x86ec4ccf +.long 0x9be47be0,0x69c43526,0xcb28fea1,0x323b7dd8,0x3a6c67e5,0xfa5538ba,0x1d378e46,0xef921d70,0x3c4b880e,0xf92961fc,0x98940a67,0x3f6f914e,0xfef0ff39,0xa990eb0a,0xf0eeff9c,0xa6c2920f +.long 0x51b8d9a3,0xca804166,0x0ffb0db1,0x42531bc9,0xaa82e7ce,0x72ce4718,0xdf574741,0x6e199913,0xd5d36946,0xd5f1b13d,0xf68f0194,0x8255dc65,0x8710d230,0xdc9df4cd,0x138c1988,0x3453c20f +.long 0x89a6ef01,0x9af98dc0,0x9857df85,0x4dbcc3f0,0x5c1ad924,0x34805601,0xd0493046,0x40448da5,0x4ee343e2,0xf629926d,0x90e8a301,0x6343f1bd,0x40815b3f,0xefc93491,0xde8f66fb,0xf882a423 +.long 0xe7db9f57,0x3a12d5f4,0x3c384c27,0x7dfba38a,0x6fc660b1,0x7a904bfd,0x2773b21c,0xeb6c5db3,0x1cdfe049,0xc350ee66,0x44540f29,0x9baac0ce,0xa5ec6aad,0xbc57b6ab,0x0a7c1baa,0x167ce8c3 +.long 0x53fb2b56,0xb23a03a5,0x4e057f78,0x6ce141e7,0x89e490d9,0x796525c3,0xa31a7e75,0x0bc95725,0x1220fd06,0x1ec56791,0x408b0bd6,0x716e3a3c,0xe8ebeba9,0x31cd6bf7,0xbee6b670,0xa7326ca6 +.long 0xcd090c43,0x3d9f851c,0xf12c3988,0x561e8f13,0x904b7be4,0x50490b6a,0x0410737b,0x61690ce1,0x0f009052,0x299e9a37,0xf026092e,0x258758f0,0xfdfcdc0f,0x9fa255f3,0xc0e1bcd2,0xdbc9fb1f +.long 0x24651840,0x35f9dd6e,0xa5c59abc,0xdca45a84,0xecca4938,0x103d396f,0xb97b3f29,0x4532da0a,0x1999a6bf,0xc4135ea5,0x5e6bf2ee,0x3aa9505a,0x3f5be093,0xf77cef06,0xa943152e,0x97d1a0f8 +.long 0x2e1c21dd,0x2cb0ebba,0x2c6797c4,0xf41b29fc,0xb300101f,0xc6e17321,0xd0d79a89,0x4422b0e9,0x92f1bfc4,0x49e4901c,0xe1e10ed9,0x06ab1f8f,0xdb2926b8,0x84d35577,0x356e8ec2,0xca349d39 +.long 0x343bf1a9,0x70b63d32,0x37d1a6b1,0x8fd3bd28,0x316865b4,0x0454879c,0xc458efa2,0xee959ff6,0x9706dc3f,0x0461dcf8,0x164e4b2e,0x737db0e2,0x2f8843c8,0x09262680,0x7745e6f6,0x54498bbc +.long 0xa29e24af,0x359473fa,0x70aa87a1,0xfcc3c454,0x00573ace,0xfd2c4bf5,0x28dd1965,0xb65b514e,0x2193e393,0xe46ae7cf,0xf5444d97,0x60e9a4e1,0x00ff38ed,0xe7594e96,0x0a0e0f02,0x43d84d2f +.long 0xee398a21,0x8b6db141,0xe3bcc5be,0xb88a56ae,0x373460ea,0x0a1aa52f,0x160bb19b,0x20da1a56,0x65bf0384,0xfb54999d,0x5d5a180e,0x71a14d24,0x21737b04,0xbc44db7b,0x01dd8e92,0xd84fcb18 +.long 0xfa44b479,0x80de937b,0x5c98fd4f,0x53505499,0x28f08727,0x1edb12ab,0xa5f3ef53,0x4c58b582,0x8327f246,0xbfb236d8,0x4d7df320,0xc3a3bfaa,0xb96024f2,0xecd96c59,0x7f4e0433,0xfc293a53 +.long 0x5acf6e10,0x5341352b,0xafe652c3,0xc50343fd,0x18577a7f,0x4af3792d,0xaf16823d,0xe1a4c617,0x33425d0a,0x9b26d0cd,0x9b7bc47f,0x306399ed,0x706bb20b,0x2a792f33,0x98111055,0x31219614 +.long 0x87f5d28b,0x864ec064,0x962277fd,0x11392d91,0xbb6aed5f,0xb5aa7942,0x47e799d9,0x080094dc,0x208ba19b,0x4afa588c,0x8512f284,0xd3e7570f,0x02f5799a,0xcbae64e6,0x514b9492,0xdeebe7ef +.long 0xe5c298ff,0x30300f98,0x3678361f,0x17f561be,0x98cb9a16,0xf52ff312,0x5562d490,0x6233c3bc,0x92e3a2cb,0x7bfa15a1,0xe6365119,0x961bcfd1,0x2c8c53b1,0x3bdd29bf,0x822844ba,0x739704df +.long 0x7e7b754b,0x7dacfb58,0xa806c9b9,0x23360791,0x23504452,0xe7eb88c9,0x852c1783,0x2983e996,0x958d881d,0xdd4ae529,0x262c7b3c,0x026bae03,0x960b52d1,0x3a6f9193,0x92696cfb,0xd0980f90 +.long 0xd5f30851,0x4c1f428c,0x2a4f6630,0x94dfed27,0xfc5d48a4,0x4df53772,0x933260ce,0xdd2d5a2f,0xd44cc7a5,0x574115bd,0xbd12533a,0x4ba6b20d,0x243057c9,0x30e93cb8,0x14de320e,0x794c486a +.long 0xf21496e4,0xe925d4ce,0xec696331,0xf951d198,0x3e8d812f,0x9810e2de,0x389294ab,0xd0a47259,0x0e3bab66,0x513ba2b5,0xabad306f,0x462caff5,0xaf04c49e,0xe2dc6d59,0xe0b84b0b,0x1aeb8750 +.long 0x2f7d0ca2,0xc034f12f,0xe06acf2f,0x6d2e8128,0x21facc2f,0x801f4f83,0xf40ef607,0xa1170c03,0x7805a99c,0xfe0a1d4f,0xcc26aba5,0xbde56a36,0x35531f40,0x5b1629d0,0x9afa6108,0xac212c2b +.long 0x15697be5,0x30a06bf3,0x2c63c7c1,0x6f0545dc,0x7ccdadaf,0x5d8cb842,0xac7015bb,0xd52e379b,0xf462c23e,0xc4f56147,0x46bc24b0,0xd44a4298,0xe2856d4f,0xbc73d23a,0x0832bcdf,0x61cedd8c +.long 0x99f241d7,0x60953556,0x001a349d,0xee4adbd7,0xaa89e491,0x0b35bf6a,0x136f7546,0x7f0076f4,0x9264da3d,0xd19a18ba,0x62a7a28b,0x6eb2d2cd,0x8761c971,0xcdba941f,0xa3be4a5d,0x1550518b +.long 0x57d0b70c,0xd0e8e2f0,0xcd133ba3,0xeea8612e,0x44416aec,0x814670f0,0x30775061,0x424db6c3,0x16213fd1,0xd96039d1,0x18a3478f,0xc61e7fa5,0xcb0c5021,0xa805bdcc,0x0cc616dd,0xbdd6f3a8 +.long 0x5d97f7e2,0x06009667,0xaf0bf4b6,0x31db0fc1,0x5491627a,0x23680ed4,0x7d741fb1,0xb99a3c66,0x36b1ff92,0xe9bb5f55,0x512b388d,0x29738577,0x50fcf263,0xdb8a2ce7,0x6c4f7b47,0x385346d4 +.long 0x31631f9e,0xbe86c5ef,0x03a57a29,0xbf91da21,0x7b23f821,0xc3b1f796,0x770db354,0x0f7d00d2,0xd8fe79da,0x8ffc6c3b,0xd525c996,0xcc5e8c40,0xcfff632a,0x4640991d,0x67112528,0x64d97e8c +.long 0x02f1cd1e,0xc232d973,0x1dd212a4,0xce87eacb,0xe69802f7,0x6e4c8c73,0x1fffddbd,0x12ef0290,0x1bcea6e2,0x941ec74e,0x3cb92cbb,0xd0b54024,0x7e8f9d05,0x809fb9d4,0xf2992aae,0x3bf16159 +.long 0xf8a7a838,0xad40f279,0x05615660,0x11aea631,0xa01f6fa1,0xbf52e6f1,0x3dc2aec9,0xef046995,0xd8080711,0x785dbec9,0x9fdedf76,0xe1aec60a,0xfa21c126,0xece797b5,0x05e52732,0xc66e898f +.long 0x08811fdb,0x39bb69c4,0x2fc7f082,0x8bfe1ef8,0x174f4138,0xc8e7a393,0xd58d1f98,0xfba8ad1d,0xbfd2fd5b,0xbc21d0ce,0x6ee60d61,0x0b839a82,0xafd22253,0xaacf7658,0xaae396b3,0xb526bed8 +.long 0x38564464,0xccc1bbc2,0x8c45bc73,0x9e3ff947,0x58188a78,0xcde9bca3,0xd73bf8f7,0x138b8ee0,0x4123c489,0x5c7e234c,0xfa643297,0x66e69368,0x39a15fa3,0x0629eeee,0xa9e2a927,0x95fab881 +.long 0xeafbb1e1,0xb2497007,0xe75b7a93,0xd75c9ce6,0xefb68d78,0x3558352d,0x223f6396,0xa2f26699,0xe469b17a,0xeb911ecf,0xe72d3ec2,0x62545779,0x82cb113f,0x8ea47de7,0x4e1fa98d,0xebe4b086 +.long 0x8cdfedb1,0xec2d5ed7,0xfe211a74,0xa535c077,0x11d244c5,0x9678109b,0xbe299a76,0xf17c8bfb,0xfb11fbc4,0xb651412e,0x94ab3f65,0xea0b5482,0x0cf78243,0xd8dffd95,0xce0361d4,0x2e719e57 +.long 0x304ddc5b,0x9007f085,0x4daba2ea,0x095e8c6d,0x3f9d28a9,0x5a33cdb4,0xe2283003,0x85b95cd8,0xb9744733,0xbcd6c819,0xfc7f5783,0x29c5f538,0xd59038e4,0x6c49b2fa,0x3bbe1018,0x68349cc1 +.long 0x21830ee5,0xcc490c1d,0xe9bfa297,0x36f9c4ee,0x48de1a94,0x58fd7294,0x4e8f2cdc,0xaadb13a8,0x81313dba,0x515eaaa0,0xc2152dd8,0xc76bb468,0xa653dbf8,0x357f8d75,0xb14ac143,0xe4d8c4d1 +.long 0xb055cb40,0xbdb8e675,0x977b5167,0x898f8e7b,0xb82fb863,0xecc65651,0x6d88f01f,0x56544814,0x263a75a9,0xb0928e95,0x1a22fcda,0xcfb6836f,0x3f3bd37c,0x651d14db,0xb6ad4664,0x1d3837fb +.long 0xff4f94ab,0x7c5fb538,0x6d7fb8f2,0x7243c712,0xa85c5287,0xef13d60c,0x4bb8dd1b,0x18cfb7c7,0x72908219,0x82f9bfe6,0x9d5144ab,0x35c4592b,0x9cf4b42f,0x52734f37,0x8c60ddc4,0x6bac55e7 +.long 0x94dea0f6,0xb5cd811e,0xe18cc1a3,0x259ecae4,0x15e660f8,0x6a0e836e,0x0e02bff2,0x6c639ea6,0x7e1026fd,0x8721b8cb,0x63261942,0x9e73b50b,0x77f01da3,0xb8c70974,0x8268f57f,0x1839e6a6 +.long 0x5150b805,0x571b9415,0xf92c7097,0x1892389e,0x4a084b95,0x8d69c18e,0xbe5b495c,0x7014c512,0x1b07523c,0x4780db36,0x2c1c64fa,0x2f6219ce,0x602c105a,0xc38b81b0,0x5dc8e360,0xab4f4f20 +.long 0xcf7d62d2,0x20d3c982,0x23ba8150,0x1f36e29d,0x92763f9e,0x48ae0bf0,0x1d3a7007,0x7a527e6b,0x581a85e3,0xb4a89097,0xdc158be5,0x1f1a520f,0x167d726e,0xf98db37d,0x1113e862,0x8802786e +.long 0x36f09ab0,0xefb2149e,0x4a10bb5b,0x03f163ca,0x06e20998,0xd0297045,0x1b5a3bab,0x56f0af00,0x70880e0d,0x7af4cfec,0xbe3d913f,0x7332a66f,0x7eceb4bd,0x32e6c84a,0x9c228f55,0xedc4a79a +.long 0xc55c4496,0xc37c7dd0,0x25bbabd2,0xa6a96357,0xadd7f363,0x5b7e63f2,0x2e73f1df,0x9dce3782,0xb2b91f71,0xe1e5a16a,0x5ba0163c,0xe4489823,0xf6e515ad,0xf2759c32,0x8615eecf,0xa5e2f1f8 +.long 0xabded551,0x74519be7,0xc8b74410,0x03d358b8,0x0e10d9a9,0x4d00b10b,0x28da52b7,0x6392b0b1,0x0b75c904,0x6744a298,0xa8f7f96c,0xc305b0ae,0x182cf932,0x042e421d,0x9e4636ca,0xf6fc5d50 +.long 0xd64cc78c,0x795847c9,0x9b6cb27b,0x6c50621b,0xdf8022ab,0x07099bf8,0xc04eda1d,0x48f862eb,0xe1603c16,0xd12732ed,0x5c9a9450,0x19a80e0f,0xb429b4fc,0xe2257f54,0x45460515,0x66d3b2c6 +.long 0x822e37be,0x6ca4f87e,0x253bda4e,0x73f237b4,0x41190aeb,0xf747f3a2,0x804cf284,0xf06fa36f,0xfc621c12,0x0a6bbb6e,0x40b80ec6,0x5d624b64,0x7ba556f3,0x4b072425,0x3e2d20a8,0x7fa0c354 +.long 0xe3229d41,0xe921fa31,0x94531bd4,0xa929c652,0xa6d38209,0x84156027,0x6bdb97bd,0xf3d69f73,0x16833631,0x8906d19a,0x03d51be3,0x68a34c2e,0x0e511cd8,0xcb59583b,0xfdc132a8,0x99ce6bfd +.long 0xffcdb463,0x3facdaaa,0x34a38b08,0x658bbc1a,0xf1a9078d,0x12a801f8,0x6ab855de,0x1567bcf9,0x3572359b,0xe08498e0,0x8659e68b,0xcf0353e5,0x7d23807c,0xbb86e9c8,0x2198e8a2,0xbc08728d +.long 0x453cadd6,0x8de2b7bc,0xbc0bc1f8,0x203900a7,0xa6abd3af,0xbcd86e47,0x8502effb,0x911cac12,0xec965469,0x2d550242,0x29e0017e,0x0e9f7692,0x65979885,0x633f078f,0x4cf751ef,0xfb87d449 +.long 0xfc25419a,0xe1790e4b,0x4bff3cfd,0x36467203,0x25b6e83f,0xc8db6386,0x6cad6fd2,0x6cc69f23,0x6bc68bb9,0x0219e45a,0x297f7334,0xe43d79b6,0x465dc97c,0x7d445368,0x2a0b949a,0x4b9eea32 +.long 0x6102d021,0x1b96c6ba,0x2f4461ea,0xeaafac78,0xc49f19a8,0xd4b85c41,0xcf538875,0x275c28e4,0xdd2e54e0,0x35451a9d,0x0605618b,0x6991adb5,0x7b36cd24,0x5b8b4bcd,0x56f37216,0x372a4f8c +.long 0xa6a5da60,0xc890bd73,0xdc4c9ff0,0x6f083da0,0xf0536e57,0xf4e14d94,0xaaec8243,0xf9ee1eda,0x8bdcf8e7,0x571241ec,0x0b041e26,0xa5db8271,0xe3fff040,0x9a0b9a99,0x7c271202,0xcaaf21dd +.long 0x4f0dd2e8,0xb4e2b2e1,0x0a377ac7,0xe77e7c4f,0x0d7a2198,0x69202c3f,0x28200eb8,0xf759b7ff,0xdcfe314e,0xc87526ed,0x53d5cf99,0xeb84c524,0x515138b6,0xb1b52ace,0x23fca3f4,0x5aa7ff8c +.long 0xb9791a26,0xff0b13c3,0xcdd58b16,0x960022da,0x57aad2de,0xdbd55c92,0xf30fe619,0x3baaaaa3,0x0d881efd,0x9a4b2346,0x46325e2a,0x506416c0,0x035c18d4,0x91381e76,0xf27817b0,0xb3bb68be +.long 0x5116f937,0x15bfb8bf,0xc1268943,0x7c64a586,0x8419a2c8,0x71e25cc3,0x8335f463,0x9fd6b0c4,0xe8ee0e0e,0x4bf0ba3c,0x298c21fa,0x6f6fba60,0xae66bee0,0x57d57b39,0x22672544,0x292d5130 +.long 0xbab093b3,0xf451105d,0x02839986,0x012f59b9,0x3474a89c,0x8a915802,0x2de03e97,0x048c919c,0x91071cd5,0xc476a2b5,0x034970a5,0x791ed89a,0xe1b7994b,0x89bd9042,0xa1057ffd,0x8eaf5179 +.long 0xd551ee10,0x6066e2a2,0x727e09a6,0x87a8f1d8,0x2c01148d,0x00d08bab,0x424f33fe,0x6da8e4f1,0xcf9a4e71,0x466d17f0,0x3bf5cb19,0xff502010,0xd062ecc0,0xdccf97d8,0x81d80ac4,0x80c0d9af +.long 0x033f2876,0xe87771d8,0x7d5cc3db,0xb0186ec6,0x3bc9bc1d,0x58e8bb80,0x6f6ef60e,0x4d1395cc,0x186244a0,0xa73c62d6,0x110a5b53,0x918e5f23,0x741b7eab,0xed4878ca,0xdbe03e51,0x3038d71a +.long 0xa93c3246,0x840204b7,0xa0b9b4cd,0x21ab6069,0xb1d64218,0xf5fa6e2b,0xf3d56191,0x1de6ad0e,0xff1929c7,0x570aaa88,0x640e87b5,0xc6df4c6b,0xc65f0ccc,0xde8a74f2,0xe6f6cc01,0x8b972fd5 +.long 0x0b846531,0x3fff36b6,0x10a5e475,0xba7e45e6,0x4145b6c5,0x84a1d10e,0x5e046d9d,0xf1f7f91a,0x44de90d7,0x0317a692,0xf199c15e,0x951a1d4a,0xc9d73deb,0x91f78046,0xfab8224f,0x74c82828 +.long 0xe7560b90,0xaa6778fc,0xa7e824ce,0xb4073e61,0xd642eba8,0xff0d693c,0x5dccef38,0x7ce2e57a,0x1df1ad46,0x89c2c789,0x098346fd,0x83a06922,0xda2fc177,0x2d715d72,0x85b6cf1d,0x7b6dd71d +.long 0x73fa9cb0,0xc60a6d0a,0x328bf5a9,0xedd3992e,0x832c8c82,0xc380ddd0,0xa2a0bf50,0xd182d410,0xd9a528db,0x7d9d7438,0xcaf53994,0xe8b1a0e9,0x0e19987c,0xddd6e5fe,0x190b059d,0xacb8df03 +.long 0x8300129f,0x53703a32,0x68c43bfd,0x1f637662,0x00e54051,0xbcbd1913,0x7bf5a8c5,0x812fcc62,0x29fb85da,0x3f969d5f,0x694759e8,0x72f4e00a,0x790726b7,0x426b6e52,0x3bdbb209,0x617bbc87 +.long 0x97aee317,0x511f8bb9,0xe81536a8,0x812a4096,0x3ac09b9b,0x137dfe59,0xba8c9a7a,0x0682238f,0xaeccb4bd,0x7072ead6,0x692ba633,0x6a34e9aa,0x6fff9d33,0xc82eaec2,0x1d4d2b62,0xfb753512 +.long 0x1d7aadab,0x1a0445ff,0xd5f6a67c,0x65d38260,0x91cfb26f,0x6e62fb08,0x5c7d91d6,0xef1e0fa5,0x33db72cd,0x47e7c7ba,0xfa7c74b2,0x017cbc09,0xf50a503c,0x3c931590,0x616baa42,0xcac54f60 +.long 0xb2369f0f,0x9b6cd380,0x23c76151,0x97d3a70d,0x9862a9c6,0x5f9dd6fc,0x12312f51,0x044c4ab2,0x834a2ddc,0x035ea0fd,0xcc7b826d,0x49e6b862,0x62fce490,0xb03d6883,0xb37e36e9,0x62f2497a +.long 0xc6458293,0x04b005b6,0xe8d10af7,0x36bb5276,0x8ee617b8,0xacf2dc13,0xb004b3d4,0x470d2d35,0xfeeb1b77,0x06790832,0x85657f9c,0x2bb75c39,0xc0f60004,0xd70bd4ed,0x219b018b,0xfe797ecc +.long 0x753aebcc,0x9b5bec2a,0xc939eca5,0xdaf9f3dc,0xd095ad09,0xd6bc6833,0xdaa4d2fc,0x98abdd51,0x8d168be5,0xd9840a31,0x2325a23c,0xcf7c10e0,0x7e6ecfaf,0xa5c02aa0,0xb5bfdf18,0x2462e7e6 +.long 0xa0cc3f12,0xab2d8a8b,0xbc672a29,0x68dd485d,0x596f2cd3,0x72039752,0xa0cf3d8d,0x5d3eea67,0xe6602671,0x810a1a81,0x14026c0c,0x8f144a40,0x76b50f85,0xbc753a6d,0x645cd4a4,0xc4dc21e8 +.long 0x521d0378,0xc5262dea,0x05011c6f,0x802b8e0e,0x0b4c19ea,0x1ba19cbb,0xebf0aaec,0x21db64b5,0x70342f9d,0x1f394ee9,0x1bc44a14,0x93a10aee,0x3efd0baa,0xa7eed31b,0x1d154e65,0x6e7c824e +.long 0x9966e7ee,0xee23fa81,0x05b7920d,0x64ec4aa8,0x2d90aad4,0x2d44462d,0xdf277ad5,0xf44dd195,0xbb46b6a1,0x8d6471f1,0xfd885090,0x1e65d313,0x13a977b4,0x33a800f5,0x0797e1ef,0xaca9d721 +.long 0xfcff6a17,0x9a5a85a0,0x1eca7cee,0x9970a3f3,0xc9504be3,0xbb9f0d6b,0xadd24ee2,0xe0c504be,0x77fcc2f4,0x7e09d956,0x65bb5fc4,0xef1a5227,0x8b9286aa,0x145d4fb1,0x6649028b,0x66fd0c5d +.long 0x1bf4581c,0x98857ceb,0xaca7b166,0xe635e186,0x659722ac,0x278ddd22,0x1db68007,0xa0903c4c,0x48f21402,0x366e4589,0xb96abda2,0x31b49c14,0xe0403190,0x329c4b09,0xd29f43fe,0x97197ca3 +.long 0x274983d8,0x8073dd1e,0x55717c8f,0xda1a3bde,0x0361f9d1,0xfd3d4da2,0x4c7de1ce,0x1332d081,0xaa6d0e10,0x9b7ef7a3,0xf54f1c4a,0x17db2e73,0x4cd35567,0xaf3dffae,0xe56f4e71,0xaaa2f406 +.long 0x7ace3fc7,0x8966759e,0x45a8d8c6,0x9594eacf,0x91834e0e,0x8de3bd8b,0x548c0421,0xafe4ca53,0xe6ee81c6,0xfdd7e856,0x6b891a3a,0x8f671beb,0xfae63829,0xf7a58f2b,0x9c11ac9f,0x9ab186fb +.long 0x10b5be76,0x8d6eb369,0xfb040bcd,0x046b7739,0xcb73de88,0xccb4529f,0xcf26be03,0x1df0fefc,0xbcfcd027,0xad7757a6,0xbb3165ca,0xa8786c75,0x7e99a4d9,0xe9db1e34,0xb06c504b,0x99ee86df +.long 0xc15c9f0a,0x5b7c2ddd,0x4295989e,0xdf87a734,0x03d08fda,0x59ece47c,0xad5fc702,0xb074d3dd,0x51a03776,0x20407903,0x2a608007,0x2bb1f77b,0xe1153185,0x25c58f4f,0x766e6447,0xe6df62f6 +.long 0xed51275a,0xefb3d1be,0x2f0f483f,0x5de47dc7,0x97c2bedf,0x7932d98e,0x0219f8a1,0xd5c11927,0xa73a294e,0x9d751200,0x9dc20172,0x5f88434a,0xa26f506a,0xd28d9fd3,0x9d1dcd48,0xa890cd31 +.long 0x70f4d3b4,0x0aebaec1,0x0ffc8d00,0xfd1a1369,0x57d57838,0xb9d9c240,0x68bac361,0x45929d26,0x25b15ca6,0x5a2cd060,0x6e474446,0x4b3c83e1,0xee1e5134,0x1aac7578,0xc91e2f41,0xa418f5d6 +.long 0x213ed68b,0x6936fc8a,0x510a5224,0x860ae7ed,0xdef09b53,0x63660335,0xcd79c98d,0x641b2897,0x01110f35,0x29bd38e1,0x648b1937,0x79c26f42,0x9d9164f4,0x64dae519,0x0265c273,0xd85a2310 +.long 0x4b07e2b1,0x7173dd5d,0x8d9ea221,0xd144c4cb,0x1105ab14,0xe8b04ea4,0xfe80d8f1,0x92dda542,0xcf03dce6,0xe9982fa8,0x1a22cffc,0x8b5ea965,0x3fad88c4,0xf7f4ea7f,0x6a5ba95c,0x62db773e +.long 0x93f24567,0xd20f02fb,0x315257ca,0xfd46c69a,0x8bcab987,0x0ac74cc7,0x5ceca2f5,0x46f31c01,0x888b219e,0x40aedb59,0xe1fccd02,0xe50ecc37,0x911f816c,0x1bcd9dad,0x8db9b00c,0x583cc1ec +.long 0xa483bf11,0xf3cd2e66,0xb1b2c169,0xfa08a6f5,0x4be9fa28,0xf375e245,0x5b6d011f,0x99a7ffec,0xc4ae62da,0x6a3ebddb,0x374aef5d,0x6cea00ae,0x9d4d05bc,0xab5fb98d,0xd560f252,0x7cba1423 +.long 0x208490de,0x49b2cc21,0xbcfb2879,0x1ca66ec3,0x1b6fb16f,0x7f1166b7,0x65fe5db3,0xfff63e08,0x8b2610be,0xb8345abe,0x39de3df4,0xb732ed80,0x211c32b4,0x0e24ed50,0x848ff27d,0xd10d8a69 +.long 0xed4de248,0xc1074398,0x10488927,0xd7cedace,0x85673e13,0xa4aa6bf8,0x6daf30af,0xb46bae91,0xfcef7ad8,0x07088472,0xd4b35e97,0x61151608,0xdde29986,0xbcfe8f26,0xd5a34c79,0xeb84c4c7 +.long 0x164e1214,0xc1eec55c,0xa147bb03,0x891be86d,0x0ba96835,0x9fab4d10,0xa5c1ae9f,0xbf01e9b8,0xb186ebc0,0x6b4de139,0x85b91bca,0xd5c74c26,0xc2d93854,0x5086a99c,0xa7a9dfbc,0xeed62a7b +.long 0x76b7618a,0x8778ed6f,0x03b66062,0xbff750a5,0xb65186db,0x4cb7be22,0xcc3a6d13,0x369dfbf0,0x7191a321,0xc7dab26c,0x40ed718e,0x9edac3f9,0xd0cfd183,0xbc142b36,0x7c991693,0xc8af82f6 +.long 0x97ce0b2a,0xb3d1e4d8,0xc3a55cdf,0xe6d7c87f,0x68b81afe,0x35846b95,0xd3c239d8,0x018d12af,0x01206e15,0x2b2c6208,0xa3b882c6,0xe0e42453,0xa50162d5,0x854470a3,0x7017a62a,0x08157478 +.long 0x820357c7,0x18bd3fb4,0x6f1458ad,0x992039ae,0x25b44aa1,0x9a1df3c5,0xed3d5281,0x2d780357,0xc77ad4d4,0x58cf7e4d,0xf9df4fc4,0xd49a7998,0x1d71205e,0x4465a8b5,0x649254aa,0xa0ee0ea6 +.long 0xab7bd771,0x4b5eeecf,0x35c262b9,0x6c873073,0x3c9d61e7,0xdc5bd648,0x321460d2,0x233d6d54,0xfc195bcc,0xd20c5626,0x04d78b63,0x25445958,0x17ec8ef3,0xe03fcb3d,0x46b8f781,0x54b690d1 +.long 0x21230646,0x82fa2c8a,0x084f418c,0xf51aabb9,0x1a30ba43,0xff4fbec1,0x743c9df7,0x6a5acf73,0xd635b4d5,0x1da2b357,0xecd5c1da,0xc3de68dd,0xd61af0dd,0xa689080b,0xd665bf99,0xdea5938a +.long 0xfe637294,0x0231d71a,0xa5a81cd8,0x01968aa6,0x048e63b5,0x11252d50,0x6ca007e9,0xc446bc52,0x96d6134b,0xef8c50a6,0x9e09a05c,0x9361fbf5,0xdca3291a,0xf17f85a6,0xff251a21,0xb178d548 +.long 0xa4df3915,0x87f6374b,0x2fd5d608,0x566ce1bf,0x7de35102,0x425cba4d,0x58c5d5e2,0x6b745f8f,0x63122edf,0x88402af6,0x3b989a89,0x3190f9ed,0xebba3156,0x4ad3d387,0xc7c469a5,0xef385ad9 +.long 0x3f642c29,0xb08281de,0x910ffb88,0x20be0888,0xd5292546,0xf353dd4a,0x8377a262,0x3f1627de,0xeefcd638,0xa5faa013,0x74cc77c3,0x8f3bf626,0xa348f55e,0x32618f65,0x9fefeb9e,0x5787c0dc +.long 0xd9a23e44,0xf1673aa2,0x4e10690d,0x88dfa993,0x2bf91108,0x1ced1b36,0x3af48649,0x9193ceca,0x2d738fc5,0xfb34327d,0x975fee6c,0x6697b037,0xc04079a5,0x2f485da0,0x2feaa1ac,0x2cdf5735 +.long 0xbd55659e,0x76944420,0x4376090c,0x7973e32b,0x163b591a,0x86bb4fe1,0xc196f0ca,0x10441aed,0x045ad915,0x3b431f4a,0xa4afacb1,0x6c11b437,0x71fdbbd8,0x30b0c7db,0xeda65acd,0xb642931f +.long 0x9c92b235,0x4baae6e8,0x6b3993a1,0xa73bbd0e,0x693dd031,0xd06d60ec,0x7156881c,0x03cab91b,0x1db3574b,0xd615862f,0x64bb061a,0x485b0185,0xa0181e06,0x27434988,0xc1c0c757,0x2cd61ad4 +.long 0x2ff9f403,0x3effed5a,0x62239029,0x8dc98d8b,0x1f17b70d,0x2206021e,0xbf510015,0xafbec0ca,0x80130dfa,0x9fed7164,0x8a02dcf5,0x306dc2b5,0xfeb10fc0,0x48f06620,0x5a57cf51,0x78d1e1d5 +.long 0x192ef710,0xadef8c5a,0x3b7431f9,0x88afbd4b,0x64250c9e,0x7e1f7407,0xb58bec07,0x6e31318d,0x24f89b4e,0xfd4fc4b8,0x48c36a2a,0x65a5dd88,0xf024baa7,0x4f1eccff,0xcba94650,0x22a21cf2 +.long 0x42a554f7,0x95d29dee,0x002ec4ba,0x828983a5,0x8badb73d,0x8112a1f7,0xa27c1839,0x79ea8897,0xd065fd83,0x8969a5a7,0xb262a0bc,0xf49af791,0xaf2b5127,0xfcdea8b6,0x564c2dbc,0x10e913e1 +.long 0xbc21ef51,0x51239d14,0x4ce57292,0xe51c3ceb,0x47bbcc3b,0x795ff068,0xbd7e11e6,0x86b46e1e,0x80041ef4,0x0ea6ba23,0x6262342e,0xd72fe505,0x31d294d4,0x8abc6dfd,0x1278c2c9,0xbbe017a2 +.long 0xb389328a,0xb1fcfa09,0xd01771b5,0x322fbc62,0x60b045bf,0x04c0d063,0x10e52d01,0xdb652edc,0x03ec6627,0x50ef932c,0xc1ee50e3,0xde1b3b2d,0xdc37a90d,0x5ab7bdc5,0x31e33a96,0xfea67213 +.long 0x4f2999aa,0x6482b5cb,0xb8cbf0dd,0x38476cc6,0x173405bb,0x93ebfacb,0xe52369ec,0x15cdafe7,0xd935b7db,0xd42d5ba4,0x1c99a4cd,0x648b6004,0xa3b5545b,0x785101bd,0x9dd67faf,0x4bf2c38a +.long 0x4442449c,0xb1aadc63,0x33ad4fb8,0xe0e9921a,0xaa686d82,0x5c552313,0x465d866c,0xdee635fa,0x18ee6e8a,0xbc3c224a,0xed42e02f,0xeed748a6,0xd474cd08,0xe70f930a,0xfff24adf,0x774ea6ec +.long 0xf3480d4a,0x03e2de1c,0xbc8acf1a,0xf0d8edc7,0x68295a9c,0xf23e3303,0xc546a97d,0xfadd5f68,0x96f8acb1,0x895597ad,0x671bdae2,0xbddd49d5,0x21dd43f4,0x16fcd528,0x6619141a,0xa5a45412 +.long 0xc360e25a,0x8ce9b6bf,0x075a1a78,0xe6425195,0x481732f4,0x9dc756a8,0x5432b57a,0x83c0440f,0xd720281f,0xc670b3f1,0xd135e051,0x2205910e,0xdb052be7,0xded14b0e,0xc568ea39,0x697b3d27 +.long 0xfb3ff9ed,0x2e599b9a,0x17f6515c,0x28c2e0ab,0x474da449,0x1cbee4fd,0x4f364452,0x071279a4,0x01fbe855,0x97abff66,0x5fda51c4,0x3ee394e8,0x67597c0b,0x190385f6,0xa27ee34b,0x6e9fccc6 +.long 0x14092ebb,0x0b89de93,0x428e240c,0xf17256bd,0x93d2f064,0xcf89a7f3,0xe1ed3b14,0x4f57841e,0xe708d855,0x4ee14405,0x03f1c3d0,0x856aae72,0xbdd7eed5,0xc8e5424f,0x73ab4270,0x3333e4ef +.long 0xdda492f8,0x3bc77ade,0x78297205,0xc11a3aea,0x34931b4c,0x5e89a3e7,0x9f5694bb,0x17512e2e,0x177bf8b6,0x5dc349f3,0x08c7ff3e,0x232ea4ba,0xf511145d,0x9c4f9d16,0x33b379c3,0xccf109a3 +.long 0xa1f25897,0xe75e7a88,0xa1b5d4d8,0x7ac6961f,0x08f3ed5c,0xe3e10773,0x0a892dfb,0x208a54ec,0x78660710,0xbe826e19,0x237df2c8,0x0cf70a97,0xed704da5,0x418a7340,0x08ca33fd,0xa3eeb9a9 +.long 0x169bca96,0x49d96233,0x2da6aafb,0x04d286d4,0xa0c2fa94,0xc09606ec,0x23ff0fb3,0x8869d0d5,0xd0150d65,0xa99937e5,0x240c14c9,0xa92e2503,0x108e2d49,0x656bf945,0xa2f59e2b,0x152a733a +.long 0x8434a920,0xb4323d58,0x622103c5,0xc0af8e93,0x938dbf9a,0x667518ef,0x83a9cdf2,0xa1843073,0x5447ab80,0x350a94aa,0xc75a3d61,0xe5e5a325,0x68411a9e,0x74ba507f,0x594f70c5,0x10581fc1 +.long 0x80eb24a9,0x60e28570,0x488e0cfd,0x7bedfb4d,0xc259cdb8,0x721ebbd7,0xbc6390a9,0x0b0da855,0xde314c70,0x2b4d04db,0x6c32e846,0xcdbf1fbc,0xb162fc9e,0x33833eab,0xb0dd3ab7,0x9939b48b +.long 0xcb0c9c8c,0x5aaa98a7,0x81c4375c,0x75105f30,0x5ef1c90f,0xceee5057,0xc23a17bf,0xb31e065f,0xd4b6d45a,0x5364d275,0x62ec8996,0xd363f3ad,0x4391c65b,0xb5d21239,0xebb41b47,0x84564765 +.long 0x37107c78,0x20d18ecc,0x570c2a66,0xacff3b6b,0x9bd0d845,0x22f975d9,0xba178fa0,0xef0a0c46,0x76b6028e,0x1a419651,0x248612d4,0xc49ec674,0x7338af55,0x5b6ac4f2,0x7bee5a36,0x06145e62 +.long 0xe75746b5,0x33e95d07,0xc40c78be,0x1c1e1f6d,0x222ff8e2,0x967833ef,0xb49180ad,0x4bedcf6a,0x3d7a4c8a,0x6b37e9c1,0x6ddfe760,0x2748887c,0xaa3a5bbc,0xf7055123,0x7bbb8e74,0x954ff225 +.long 0x97c3dfb9,0xc42b8ab1,0xcf168154,0x55a549b0,0xc1b50692,0xad6748e7,0x6fc5cbcb,0x2775780f,0xe1c9d7c8,0x4eab80b8,0x3fdbcd56,0x8c69dae1,0x9969eace,0x47e6b4fb,0xa705cb5a,0x002f1085 +.long 0x6d3fea55,0x4e23ca44,0xf4810568,0xb4ae9c86,0x2a62f27d,0x47bfb91b,0xd9bac28c,0x60deb4c9,0x7de6c34c,0xa892d894,0x4494587d,0x4ee68259,0x1a3f8a5b,0x914ee14e,0x28700385,0xbb113eaa +.long 0x2115b4c9,0x81ca03b9,0x8908cad1,0x7c163d38,0xaa18179a,0xc912a118,0x886e3081,0xe09ed750,0x26f516ca,0xa676e3fa,0x8e732f91,0x753cacf7,0x833da8b4,0x51592aea,0x4cbea8aa,0xc626f42f +.long 0xa7b56eaf,0xef9dc899,0x34ef7316,0x00c0e52c,0xfe818a86,0x5b1e4e24,0xc538be47,0x9d31e20d,0x3ed68974,0x22eb932d,0x7c4e87c4,0xe44bbc08,0x0dde9aef,0x4121086e,0x134f4345,0x8e6b9cff +.long 0x711b0eb9,0x96892c1f,0x780ab954,0xb905f2c8,0xa20792db,0xace26309,0x0684e126,0xec8ac9b3,0xb40a2447,0x486ad8b6,0x9fe3fb24,0x60121fc1,0x1a8e3b3f,0x5626fccf,0x6ad1f394,0x4e568622 +.long 0x196aa5a1,0xda7aae0d,0x1041b5fb,0xe0df8c77,0x26b318b7,0x451465d9,0x7ab136e9,0xc29b6e55,0x71148463,0x2c2ab48b,0x64454a76,0xb5738de3,0x5a03abe4,0x54ccf9a0,0x0427d58e,0x377c0296 +.long 0x2bb39c1f,0x73f5f0b9,0xe608d8c5,0x14373f2c,0x00fbb805,0xdcbfd314,0x83afdcfb,0xdf18fb20,0x42b3523f,0x81a57f42,0x87f650fb,0xe958532d,0x8b0a7d7c,0xaa8dc8b6,0x150166be,0x1b75dfb7 +.long 0x2d7d1413,0x90e4f7c9,0x9834f597,0x67e2d6b5,0xa808c3e8,0x4fd4f4f9,0xd5281ec1,0xaf8237e0,0x84687cee,0x25ab5fdc,0xa5b26c09,0xc5ded6b1,0xc8ea7650,0x8e4a5aec,0x14cc417f,0x23b73e5c +.long 0x3037bf52,0x2bfb4318,0x78c725d7,0xb61e6db5,0xbbb3e5d7,0x8efd4060,0xdbac488e,0x2e014701,0x360aa449,0xac75cf9a,0x79634d08,0xb70cfd05,0xfffb15ef,0xa591536d,0xd07c106c,0xb2c37582 +.long 0xf50225f9,0xb4293fdc,0xb0e12b03,0xc52e175c,0xd0a8bf64,0xf649c3ba,0xeb8ae3c6,0x745a8fef,0x58321bc3,0x30d7e5a3,0x0bc4df48,0xb1732be7,0xe9ea5058,0x1f217993,0x3e4fd745,0xf7a71cde +.long 0x894c5bbb,0x86cc533e,0x69d83082,0x6915c7d9,0x5815c244,0xa6aa2d05,0x49b22ce5,0xaeeee592,0x78135486,0x89e39d13,0x16b76f2f,0x3a275c1f,0xe036e8f5,0xdb6bcc1b,0x5e4709f5,0x4df69b21 +.long 0x2d0f39aa,0xa188b250,0x15a85947,0x622118bb,0xfde0f4fa,0x2ebf520f,0x4860e539,0xa40e9f29,0x22b57f0f,0x7b6a51eb,0x7e80644a,0x849a33b9,0x1cf095fe,0x50e5d16f,0xec55f002,0xd754b54e +.long 0x236f4a98,0x5cfbbb22,0x066800bb,0x0b0c59e9,0x5a9a7774,0x4ac69a8f,0xd6bec948,0x2b33f804,0x32e6c466,0xb3729295,0x4e599c73,0x68956d0f,0x155c31cc,0xa47a249f,0xe1ce284e,0x24d80f0d +.long 0x988baf01,0xcd821dfb,0xdbb16647,0xe6331a7d,0x094cb960,0x1eb8ad33,0xc91bbca5,0x593cca38,0x26567456,0x384aac8d,0xc04b6490,0x40fa0309,0xdab6c8f6,0x97834cd6,0x3f91e55f,0x68a7318d +.long 0xfc4d3157,0xa00fd04e,0x2bf3bdea,0xb56f8ab2,0x4fa57172,0x014f5648,0x450abdb3,0x948c5860,0x0ebd4f08,0x342b5df0,0x0e82938e,0x3e5168cd,0xb0df5dd0,0x7aedc1ce,0xe5732516,0x6bbbc6d9 +.long 0x605daaa6,0xc7bfd486,0xbb9a6c9e,0x46fd72b7,0xa124fb89,0xe4847fb1,0xa2d8ffbc,0x75959cbd,0xc8a588ee,0x42579f65,0xb80b499d,0x368c92e6,0x999a5df1,0xea4ef6cd,0x936fe604,0xaa73bb7f +.long 0x6457d188,0xf347a70d,0x8b7a388b,0x86eda86b,0x0ccd6013,0xb7cdff06,0xd0053fb2,0xbeb1b6c7,0x99240a9f,0x0b022387,0x776189b2,0x1bbb384f,0x9066193a,0x8695e71e,0x06ffac7e,0x2eb50097 +.long 0x4a7d2caa,0x0654a9c0,0xa5aaa290,0x6f3fb3d1,0xff476e8f,0x835db041,0xc42295e4,0x540b8b0b,0x05e214f5,0xa5c73ac9,0x56a0b638,0x9a74075a,0xce9e680b,0x2e4b1090,0x6b8d9afa,0x57a5b479 +.long 0x26bfe65c,0x0dca48e7,0x7290c307,0x097e391c,0x6669e72e,0x683c462e,0x062559ac,0xf505be1e,0xe3a3035a,0x5fbe3ea1,0x9cd50da8,0x6431ebf6,0x1f6407f2,0xfd169d5c,0x60fce6b8,0x8d838a95 +.long 0x650006f0,0x2a2bfa7f,0x50c0fbb2,0xdfd7dad3,0xccf9ad96,0x92452495,0xd95635f9,0x183bf494,0x4a7bd989,0x02d5df43,0xa5431095,0x505385cc,0xfd43f53e,0xdd98e67d,0x500c34a9,0xd61e1a6c +.long 0x4a8a3d62,0x5a4b46c6,0x247743d2,0x8469c4d0,0x88f7e433,0x2bb3a13d,0x01be5849,0x62b23a10,0xa63d1a4c,0xe83596b4,0x7d183f3e,0x454e7fea,0x17afb01c,0x643fce61,0x1c4c3638,0x4e65e5e6 +.long 0xef74c45b,0x41d85ea1,0xae328506,0x2cfbfa66,0x3ada7da9,0x98b078f5,0xec752fbb,0xd985fe37,0x5a0148b4,0xeece68fe,0x2d78136d,0x6f9a55c7,0xd2b729ce,0x232dccc4,0x90aafbc4,0xa27e0dfd +.long 0x12b4603e,0x96474452,0x6b706d14,0xa876c551,0x69a9d412,0xdf145fcf,0x2d479c34,0xe2ab75b7,0x1a23ff97,0x12df9a76,0x5d359d10,0xc6138992,0xfa835f22,0x6e51c7ae,0xc0fcc4d9,0x69a79cb1 +.long 0x594cc7e1,0xf57f350d,0x3350ab79,0x3079ca63,0x9aff594a,0x226fb614,0x6d59a62b,0x35afec02,0x06ed2c6e,0x9bee46f4,0x7d939a57,0x58da1735,0x8fd1797e,0x44c50402,0x5ccea6ca,0xd8853e7c +.long 0xa35fcd5f,0x4065508d,0x495ccaeb,0x8965df8c,0x12e1a962,0x0f2da850,0xc1cf1cc4,0xee471b94,0x0a08fb75,0xcef19bc8,0x81de3591,0x704958f5,0x3aef4f88,0x2867f8b2,0xea9f9a5f,0x8d749384 +.long 0x8c9049f4,0x1b385537,0x7b92d8b6,0x5be948f3,0xb6e2bd6b,0xd96f725d,0x958c454d,0x37a222bc,0x8809bf61,0xe7c61abb,0x1346f18d,0x46f07fbc,0xe87c0d1c,0xfb567a7a,0x7ef3d07a,0x84a461c8 +.long 0xd9278d98,0x0a5adce6,0x9dfc73e1,0x24d94813,0x054321c3,0x4f3528b6,0x692ea706,0x2e03fdde,0x47b533c0,0x10e60619,0x2ca3c055,0x1a8bc73f,0x1bb62b8f,0xae58d4b2,0x584a24e3,0xb2045a73 +.long 0xbd76e195,0x3ab3d5af,0x6938a810,0x478dd1ad,0x6ee3d5cb,0x6ffab393,0x22b361e4,0xdfb693db,0x51dbf1a7,0xf9694496,0x08a2e762,0xcab4b4ef,0xd39bba9a,0xe8c92f25,0xf1464d96,0x850e61bc +.long 0xdc09508b,0xb7e830e3,0x74317655,0xfaf6d2cf,0xdf690355,0x72606ceb,0xd0c3ded6,0x48bb92b3,0x5c7cf892,0x65b75484,0xd5d5f01f,0xf6cd7ac9,0x96401d69,0xc2c30a59,0xed921878,0x91268650 +.long 0xb78c558f,0x380bf913,0xc8afdaa9,0x43c0baeb,0x54f169d3,0x377f61d5,0xae5ff20b,0xf8da07e3,0xa8a90ea8,0xb676c49d,0x83a29b21,0x81c1ff2b,0x2ad8d276,0x383297ac,0xba89f982,0x3001122f +.long 0x6718e448,0xe1d794be,0x7c3e6e13,0x246c1482,0x5d26b5ef,0x56646ef8,0x88069cdd,0x80f5091e,0x724bdd38,0xc5992e2f,0x8471e8c7,0x02e915b4,0x0d0ff2a9,0x96ff320a,0x4384d1a0,0xbf886487 +.long 0xc93f72d6,0xbbe1e6a6,0xcad800ea,0xd5f75d12,0xe7acf117,0xfa40a09f,0x7581a355,0x32c8cdd5,0x7023c499,0x74221992,0x38ec3901,0xa8afe5d7,0xa90e83f0,0x5691afcb,0x0b8f8eac,0x41bcaa03 +.long 0x8d2668d5,0xe38b5ff9,0x7ad81965,0x0715281a,0x03c6ce11,0x1bc8fc7c,0x8b650436,0xcbbee6e2,0x0cdb9808,0x06b00fe8,0xfe3ed315,0x17d6e066,0x4d0b5018,0x2e9d38c6,0x844dcaef,0xab8bfd56 +.long 0x513aed8b,0x42894a59,0x314bd07a,0xf77f3b6d,0x8e42b582,0xbbdecb8f,0xd2390fe6,0xf10e2fa8,0x62a2f201,0xefb95022,0x50ee32b0,0x4d59ea50,0x6da789a8,0xd87f7728,0xf79492c4,0xcf98a2cf +.long 0x720943c2,0xf9577239,0x3990b9d0,0xba044cf5,0x95f2884a,0x5aa8e823,0x0278a0af,0x834de6ed,0x5f25bd12,0xc8e1ee9a,0x6f7ab271,0x9259ceaa,0x77d00b76,0x7e6d97a2,0xa437832a,0x5c0c6eea +.long 0x5606b81d,0x5232c20f,0x0d991ee5,0xabd7b375,0x8632d951,0x4d2bfe35,0x98ed9364,0x78f85146,0xf30c3282,0x951873f0,0xa789230b,0x0da8ac80,0x5398967f,0x3ac7789c,0xbdda0fb5,0xa69b8f7f +.long 0x6add8545,0xe5db7717,0x72c49b66,0x1b71cb66,0x68421d77,0xd8560739,0x83e3afea,0x03840fe8,0x1ec69977,0xb391dad5,0x307f6726,0xae243fb9,0xe8ca160c,0xc88ac87b,0x4ce355f4,0x5174cced +.long 0xe58ba37d,0x98a35966,0x7817335d,0xfdcc8da2,0x83fbc7bf,0x5b752830,0xd9c96984,0x68e419d4,0x02a40380,0x409a39f4,0x1fe977bc,0x88940faf,0x8f8edea6,0xc640a94b,0xed11547d,0x1e22cd17 +.long 0x59ffc3e2,0xe28568ce,0xc1dee4e7,0x60aa1b55,0x837cb363,0xc67497c8,0x105a2bf2,0x06fb438a,0x500d8e20,0x30357ec4,0x0670db10,0x1ad9095d,0xc73b7cfd,0x7f589a05,0x880d6d28,0xf544607d +.long 0xa20ef103,0x17ba93b1,0x6ba6577b,0xad859130,0x6fa214a0,0x65c91cf6,0x27990da5,0xd7d49c6c,0x20bb569d,0xecd9ec8d,0xeeffbc33,0xbd4b2502,0x6bed0467,0x2056ca5a,0x5b63728c,0x7916a1f7 +.long 0x53a4f566,0xd4f9497d,0x97b56810,0x89734664,0x0494a621,0xf8e1da74,0x8d011c68,0x82546a93,0xc61ac162,0x1f3acb19,0xabad0d3e,0x52f8fa9c,0xb4b7ea43,0x15356523,0xae608125,0x5a16ad61 +.long 0x4faed184,0xb0bcb87f,0x5029f45f,0x5f236b1d,0x0bc6b1fc,0xd42c7607,0x68aefce3,0xc644324e,0x5c5d8446,0x8e191d59,0x13ae1979,0xc0208077,0x3ba59cc7,0xadcaee55,0xa2cb81ba,0x20ed6d6b +.long 0xb6efcffc,0x0952ba19,0x97c0b87c,0x60f12d68,0x9caa30bc,0x4ee2c7c4,0x97fbff4e,0x767238b7,0x501b5d92,0xebc73921,0xc2a37737,0x3279e3df,0x6d197543,0x9fc12bc8,0x0a40db4e,0xfa94dc6f +.long 0x530ccbbd,0x7392b41a,0xea823525,0x87c82146,0x05d98d0c,0xa52f984c,0x5ef6974c,0x2ae57d73,0x3042a6dd,0x9377f7bf,0x19647a64,0xb1a007c0,0x0cca9767,0xfaa9079a,0xf68f72d5,0x3d81a25b +.long 0xff81578e,0x752067f8,0x9045447d,0x78622150,0x0505aa6f,0xc0c22fcf,0x6bed1c77,0x1030f0a6,0x1f0bd739,0x31f29f15,0xe6debe85,0x2d7989c7,0x8e677e98,0x5c070e72,0x06e81fd5,0x0a817bd3 +.long 0xb0f2ac95,0xc110d830,0xab20e64e,0x48d0995a,0x7729cd9a,0x0f3e00e1,0xdd556946,0x2a570c20,0x4e86214d,0x912dbcfd,0xcf615498,0x2d014ee2,0x3530d76e,0x55e2b1e6,0xfd0fd6d1,0xc5135ae4 +.long 0xd4f3049f,0x0066273a,0xe7087477,0xbb8e9893,0x14c6e5fd,0x2dba1ddb,0x51f57e6c,0xdba37886,0x5a72f2cf,0x5aaee0a6,0x7bea5642,0x1208bfbf,0x67872c37,0xf5c6aa3b,0x43f93224,0xd726e083 +.long 0x061f1658,0x1854daa5,0xdf0cd2b3,0xc0016df1,0x833d50de,0xc2a3f23e,0xbbbd3017,0x73b681d2,0x3ac343c0,0x2f046dc4,0x85716421,0x9c847e7d,0x0917eed4,0xe1e13c91,0x63a1b9c6,0x3fc9eebd +.long 0x7fe02299,0x0f816a72,0x294f3319,0x6335ccc2,0x4745c5be,0x3820179f,0x922f066e,0xe647b782,0x02cafb8a,0xc22e49de,0xfcc2eccc,0x299bc2ff,0x6e0e8282,0x9a8feea2,0xfe893205,0xa627278b +.long 0x7933e47b,0xa7e19733,0x2e766402,0xf4ff6b13,0x98440d9f,0xa4d8be0a,0x38938808,0x658f5c2f,0xc95b3b3e,0x90b75677,0x3137b6ff,0xfa044269,0x43c47c29,0x077b039b,0x8a6445b2,0xcca95dd3 +.long 0x2333fc4c,0x0b498ba4,0xf736a1b1,0x274f8e68,0x5f1d4b2e,0x6ca348fd,0xa8f10199,0x24d3be78,0xca14f530,0x8535f858,0x5b982e51,0xa6e7f163,0x36e1bf62,0x847c8512,0x03448418,0xf6a7c58e +.long 0xf9374ab6,0x583f3703,0x6e564145,0x864f9195,0x22526d50,0x33bc3f48,0x1262a496,0x9f323c80,0x3f046a9a,0xaa97a7ae,0xdf8a039a,0x70da183e,0x52aa0ba6,0x5b68f71c,0x21459c2d,0x9be0fe51 +.long 0xcbc613e5,0xc1e17eb6,0x497ea61c,0x33131d55,0xaf7eded5,0x2f69d39e,0xde6af11b,0x73c2f434,0xa4a375fa,0x4ca52493,0xb833c5c2,0x5f06787c,0x3e6e71cf,0x814e091f,0x8b746666,0x76451f57 +.long 0x694db7e0,0x80f9bdef,0xb9fcddc6,0xedca8787,0x03b8dce1,0x51981c34,0x70e10ba1,0x4274dcf1,0x6def6d1a,0xf72743b8,0xebdb1866,0xd25b1670,0x050c6f58,0xc4491e8c,0x87fbd7f5,0x2be2b2ab +.long 0xd111f8ec,0x3e0e5c9d,0xb7c4e760,0xbcc33f8d,0xbd392a51,0x702f9a91,0xc132e92d,0x7da4a795,0x0bb1151b,0x1a0b0ae3,0x02e32251,0x54febac8,0x694e9e78,0xea3a5082,0xe4fe40b8,0xe58ffec1 +.long 0xd1e0cf9e,0xf85592fc,0xc0e7b2e8,0xdea75f0d,0xc135584e,0xc04215cf,0x2f57092a,0x174fc727,0xeb930bea,0xe7277877,0x5eb02a5a,0x504caccb,0xf5241b9b,0xf9fe08f7,0x8d5ca954,0xe7fb62f4 +.long 0x29c4120b,0xfbb8349d,0xc0d0d915,0x9f94391f,0x5410ba51,0xc4074fa7,0x150a5911,0xa66adbf6,0x34bfca38,0xc164543c,0xb9e1ccfc,0xe0f27560,0xe820219c,0x99da0f53,0xc6b4997a,0xe8234498 +.long 0x9d4c5423,0xcfb88b76,0xb0521c49,0x9e56eb10,0xbe8700a1,0x418e0b5e,0xf93cb58a,0x00cbaad6,0xd92a5e67,0xe923fbde,0x1f347f11,0xca4979ac,0x6bc0585b,0x89162d85,0xac3c70e3,0xdd6254af +.long 0x516e19e4,0x7b23c513,0xc5c4d593,0x56e2e847,0x5ce71ef6,0x9f727d73,0xf79a44c5,0x5b6304a6,0x3ab7e433,0x6638a736,0xfe742f83,0x1adea470,0x5b7fc19f,0xe054b854,0xba1d0698,0xf935381a +.long 0x799e9a74,0x546eab2d,0xa949f729,0x96239e0e,0x7090055a,0xca274c6b,0x9020c9b0,0x835142c3,0xa2e8807f,0xa405667a,0x1aa3d39e,0x29f2c085,0x42fc72f5,0xcc555d64,0xfbeacb3c,0xe856e0e7 +.long 0x918e4936,0xb5504f9d,0xb2513982,0x65035ef6,0x6f4d9cb9,0x0553a0c2,0xbea85509,0x6cb10d56,0xa242da11,0x48d957b7,0x672b7268,0x16a4d3dd,0x8502a96b,0x3d7e637c,0x730d463b,0x27c7032b +.long 0xe4136a14,0xbdc02b18,0x678e32bf,0xbacf969d,0xdd9c3c03,0xc98d89a3,0x23becc4f,0x7b92420a,0xc64d565c,0xd4b41f78,0x10f28295,0x9f969d00,0xb13d051a,0xec7f7f76,0xa92da585,0x08945e1e +.long 0x5846426f,0x55366b7d,0x247d441d,0xe7d09e89,0x736fbf48,0x510b404d,0xe784bd7d,0x7fa003d0,0x17fd9596,0x25f7614f,0x35cb98db,0x49e0e0a1,0x2e83a76a,0x2c65957b,0xcddbe0f8,0x5d40da8d +.long 0x050bad24,0xf2b8c405,0xc2aa4823,0x8918426d,0xa38365a7,0x2aeab3dd,0x7c91b690,0x72031717,0x60a94120,0x8b00d699,0xe99eaeec,0x478a255d,0x6f60aafd,0xbf656a5f,0x5dee77b3,0xdfd7cb75 +.long 0xa595939d,0x37f68bb4,0x28740217,0x03556479,0x84ad7612,0x8e740e7c,0x9044695f,0xd89bc843,0x85a9184d,0xf7f3da5d,0x9fc0b074,0x562563bb,0xf88a888e,0x06d2e6aa,0x161fbe7c,0x612d8643 +.long 0xf64085e7,0x465edba7,0x29aa8511,0xb230f304,0xcda2d188,0x53388426,0x4b666649,0x90885735,0x652f54f6,0x6f02ff9a,0x5fae2bf0,0x65c82294,0x62f5eee3,0x7816ade0,0xfcc56d70,0xdcdbdf43 +.long 0x54530bb2,0x9fb3bba3,0xcb0869ea,0xbde3ef77,0x0b431163,0x89bc9046,0xe4819a35,0x4d03d7d2,0x43b6a782,0x33ae4f9e,0x9c88a686,0x216db307,0x00ffedd9,0x91dd88e0,0x12bd4840,0xb280da9f +.long 0x1635e741,0x32a7cb8a,0x78be02a7,0xfe14008a,0x1b7ae030,0x3fafb334,0x5add0ce9,0x7fd508e7,0xd607ad51,0x72c83219,0x8d40964a,0x0f229c0a,0x1c878da2,0x1be2c336,0xeab2ab86,0xe0c96742 +.long 0x3e538cd7,0x458f8691,0x8e08ad53,0xa7001f6c,0xbf5d15ff,0x52b8c6e6,0x011215dd,0x548234a4,0x3d5b4045,0xff5a9d2d,0x4a904190,0xb0ffeeb6,0x48607f8b,0x55a3aca4,0x30a0672a,0x8cbd665c +.long 0x42583068,0x87f834e0,0xf3f6e683,0x02da2aeb,0x05c12248,0x6b763e5d,0x65a8aefc,0x7230378f,0x71e8e5ca,0x93bd80b5,0xb3b62524,0x53ab041c,0x6c9c552e,0x1b860513,0xd5524e66,0xe84d402c +.long 0xf37f5937,0xa37f3573,0xd1e4fca5,0xeb0f6c7d,0xac8ab0fc,0x2965a554,0x274676ac,0x17fbf56c,0xacf7d720,0x2e2f6bd9,0x10224766,0x41fc8f88,0x85d53bef,0x517a14b3,0x7d76a7d1,0xdae327a5 +.long 0xc4818267,0x6ad0a065,0x37c1bbc1,0x33aa189b,0x27392a92,0x64970b52,0x2d1535ea,0x21699a1c,0xc2d7a7fd,0xcd20779c,0x99c83cf2,0xe3186059,0x72c0b8c7,0x9b69440b,0x7b9e0e4d,0xa81497d7 +.long 0x1f5f82dc,0x515d5c89,0x6361079e,0x9a7f67d7,0x11a35330,0xa8da81e3,0x4b18be1b,0xe44990c4,0xaf103e59,0xc7d5ed95,0x8dac9261,0xece8aba7,0x9394b8d3,0xbe82b099,0x16adfe83,0x6830f09a +.long 0x88172d01,0x250a29b4,0xcaff9e02,0x8b20bd65,0xe8a6329a,0xb8a7661e,0xd3fce920,0x4520304d,0x2b47f7ef,0xae45da1f,0x5bffc540,0xe07f5288,0x3464f874,0xf7997009,0xa6fa1f38,0x2244c2cd +.long 0x94d7d9b1,0x43c41ac1,0xc82e7f17,0x5bafdd82,0x5fda0fca,0xdf0614c1,0xa8ae37ad,0x74b043a7,0x9e71734c,0x3ba6afa1,0x9c450f2e,0x15d5437e,0x67e242b1,0x4a5883fe,0x2c1953c2,0x5143bdc2 +.long 0xfc5e8920,0x542b8b53,0x9a9cee08,0x363bf9a8,0xc3486e08,0x02375f10,0x8c5e70d2,0x2037543b,0x625640b4,0x7109bccc,0x8bc62c3b,0xcbc1051e,0x803f26ea,0xf8455fed,0xeb372424,0x6badceab +.long 0x6b53f5f9,0xa2a9ce7c,0x1b176d99,0x64246595,0xb95c081b,0xb1298d36,0x1d9a9ee6,0x53505bb8,0xf2ba70b0,0x3f6f9e61,0x8afad453,0xd07e16c9,0xe7eb4a6a,0x9f1694bb,0x3cb0bc8e,0xdfebced9 +.long 0x53868c8b,0x92d3dcdc,0x386107a6,0x174311a2,0x689b4e64,0x4109e07c,0x2df3dcb6,0x30e4587f,0x0811b3b2,0x841aea31,0x0cce43ea,0x6144d41d,0x2a9a7803,0x464c4581,0x3e158930,0xd03d371f +.long 0xb1f3390b,0xc676d7f2,0xa5b61272,0x9f7a1b8c,0xc2e127a9,0x4ebebfc9,0x5dd997bf,0x4602500c,0x4711230f,0x7f09771c,0x020f09c1,0x058eb37c,0xfee5e38b,0xab693d4b,0x4653cbc0,0x9289eb1f +.long 0xd51b9cf5,0xbecf46ab,0x9f0121af,0xd2aa9c02,0xe90dc274,0x36aaf7d2,0x48b95a3c,0x909e4ea0,0x6f32dbdb,0xe6b70496,0x8b030b3e,0x672188a0,0xcfb617e2,0xeeffe5b3,0x7c82709e,0x87e947de +.long 0x1770f5a7,0xa44d2b39,0x0e44eb82,0xe4d4d791,0x3f69712a,0x42e69d1e,0xac6a820e,0xbf11c4d6,0x42c4224c,0xb5e7f3e5,0x449d941c,0xd6b4e81c,0x5450e878,0x5d72bd16,0xee25ac54,0x6a61e28a +.long 0xe6f1cd95,0x33272094,0x0d18673f,0x7512f30d,0x5afc1464,0x32f7a4ca,0x6bbb977b,0x2f095656,0xa8226200,0x586f47ca,0x1ac07369,0x02c868ad,0xc613acbe,0x4ef2b845,0x0386054c,0x43d7563e +.long 0xab952578,0x54da9dc7,0x26e84d0b,0xb5423df2,0x9b872042,0xa8b64eeb,0x5990f6df,0xac205782,0x21f4c77a,0x4ff696eb,0xaab273af,0x1a79c3e4,0x9436b3f1,0x29bc922e,0xd6d9a27a,0xff807ef8 +.long 0x778f22a0,0x82acea3d,0x5b5e7469,0xfb10b2e8,0x2818ee7d,0xc0b16980,0xc91c1a2f,0x011afff4,0xad124418,0x95a6d126,0xe72e295f,0x31c081a5,0xf2f4db75,0x36bb283a,0x7acef462,0xd115540f +.long 0x33f6746c,0xc7f3a8f8,0xfea990ca,0x21e46f65,0xcaddb0a9,0x915fd5c5,0x78614555,0xbd41f016,0x426ffb58,0x346f4434,0x14dbc204,0x80559436,0x5a969b7f,0xf3dd20fe,0xe899a39a,0x9d59e956 +.long 0x8ad4cf4b,0xf1b0971c,0x2ffb8fb8,0x03448860,0x65340ba4,0xf071ac3c,0xb27fd758,0x408d0596,0x98c364b0,0xe7c78ea4,0x051e8ab5,0xa4aac4a5,0x485d9002,0xb9e1d560,0x88844455,0x9acd518a +.long 0xd06f56c0,0xe4ca688f,0xdf027972,0xa48af70d,0x5e9a609d,0x691f0f04,0xee61270e,0xa9dd82cd,0xa0ef18d3,0x8903ca63,0x3d6ca3bd,0x9fb7ee35,0xabf47d03,0xa7b4a09c,0x1c67de8e,0x4cdada01 +.long 0x9355a244,0x52003749,0x4f2151a9,0xe77fd2b6,0x66b4efcb,0x695d6cf6,0xda2cfe25,0xc5a0cacf,0xef811865,0x104efe5c,0x9ea5cc3d,0xf52813e8,0x40b58dbc,0x855683dc,0x175fcb11,0x0338ecde +.long 0x74921592,0xf9a05637,0xb9bb9d31,0xb4f1261d,0x4e9c5459,0x551429b7,0x6ea71f53,0xbe182e6f,0xdfc50573,0xd3a3b07c,0x62be8d44,0x9ba1afda,0x52ab65d3,0x9bcfd2cb,0xa9571802,0xdf11d547 +.long 0x02a2404a,0x099403ee,0x21088a71,0x497406f4,0x5004ae71,0x99479409,0xa812c362,0xbdb42078,0xd8828442,0x2b72a30f,0xfcb5ed1c,0x283add27,0x66a40015,0xf7c0e200,0x08b295ef,0x3e3be641 +.long 0xe038a675,0xac127dc1,0x8c5c6320,0x729deff3,0xa90d2c53,0xb7df8fd4,0x681e7cd3,0x9b74b0ec,0xdab407e5,0x5cb5a623,0x76b340c6,0xcdbd3615,0x7d28392c,0xa184415a,0xe96f7830,0xc184c1d8 +.long 0x81d3a80f,0xc3204f19,0xc8e02432,0xfde0c841,0x8149e0c1,0x78203b3e,0x08053a73,0x5904bdbb,0x101b6805,0x30fc1dd1,0x49aa6d49,0x43c223bc,0x7a174087,0x9ed67141,0xd5997008,0x311469a0 +.long 0x5e43fc61,0xb189b684,0xe0d3ab57,0xf3282375,0xb1181da8,0x4fa34b67,0x99ee52b8,0x621ed0b2,0xad990676,0x9b178de1,0x56d54065,0xd51de67b,0x7538c201,0x2a2c27c4,0x38a40f5c,0x33856ec8 +.long 0xbe6cdcde,0x2522fc15,0x9f0c6f89,0x1e603f33,0x103e30a6,0x7994edc3,0x220c853e,0x033a00db,0xf7bb7fd7,0xd3cfa409,0x462d18f6,0x70f8781e,0x687fe295,0xbbd82980,0x595669f3,0x6eef4c32 +.long 0x2f7e85c3,0x86a9303b,0x71988f9b,0x5fce4621,0xc138acb5,0x5b935bf6,0x25661212,0x30ea7d67,0xe51ab9a2,0xef1eb5f4,0xae067c78,0x0587c98a,0x77ca9ca6,0xb3ce1b3c,0x54b5f057,0x2a553d4d +.long 0x4da29ec2,0xc7898236,0xb9c57316,0xdbdd5d13,0x2cd80d47,0xc57d6e6b,0xfe9e7391,0x80b460cf,0xf963c31e,0x98648cab,0xcc4d32fd,0x67f9f633,0xfdf7c687,0x0af42a9d,0x0b015ea7,0x55f292a3 +.long 0xcd21ab3d,0x89e468b2,0xc393d392,0xe504f022,0xa5013af9,0xab21e1d4,0xc2c28acb,0xe3283f78,0x226bf99f,0xf38b35f6,0x0e291e69,0xe8354274,0xb20c162d,0x61673a15,0xb04fbdbe,0xc101dc75 +.long 0x255bd617,0x8323b4c2,0x6c2a9154,0x6c969693,0x62679387,0xc6e65860,0xb8c88e23,0x8e01db0c,0x893a5559,0x33c42873,0x47a3e149,0x7630f04b,0xddcf35f8,0xb5d80805,0x77dfe732,0x582ca080 +.long 0x0b1894a0,0x2c7156e1,0xd81c68c0,0x92034001,0xc8b115b5,0xed225d00,0x83b907f2,0x237f9c22,0x4470e2c0,0x0ea2f32f,0x58be4e95,0xb725f7c1,0xb1ae5463,0x0f1dcafa,0x1ba2fc04,0x59ed5187 +.long 0xd0115d4d,0xf6e0f316,0xd3691599,0x5180b12f,0x527f0a41,0x157e32c9,0xa8e0ecc0,0x7b0b081d,0xbf4f0dd0,0x6dbaaa8a,0x4d252696,0x99b289c7,0xdbf864fe,0x79b7755e,0x76cad3ab,0x6974e2b1 +.long 0x06ddd657,0x35dbbee2,0x2ff3a96d,0xe7cbdd11,0x076be758,0x88381968,0x08c91f5d,0x2d737e72,0x86ec3776,0x5f83ab62,0x945fa7a1,0x98aa649d,0x72ef0933,0xf477ec37,0x098c17b1,0x66f52b1e +.long 0xd803738b,0x9eec58fb,0xe4e86aa4,0x91aaade7,0xa5b51492,0x6b1ae617,0xbbc45974,0x63272121,0x862c5129,0x7e0e28f0,0x3321a4a0,0x0a8f79a9,0x5041c88f,0xe26d1664,0x53233e3a,0x0571b805 +.long 0xc9520711,0xd1b0ccde,0x3c8b84bf,0x55a9e4ed,0xa1fef314,0x9426bd39,0x6eb93f2b,0x4f5f638e,0x2bf9341b,0xba2a1ed3,0x4d42d5a9,0xd63c1321,0x316dc7c5,0xd2964a89,0xca511851,0xd1759606 +.long 0xf9e6ed35,0xd8a9201f,0x6736925a,0xb7b5ee45,0x99581af7,0x0a83fbbc,0x64eeb051,0x3076bc40,0x02dec312,0x5511c98c,0x238dcb78,0x270de898,0x539c08c9,0x2cf4cf9c,0x38d3b06e,0xa70cb65e +.long 0xcfe57bbd,0xb12ec10e,0x35a0c2b5,0x82c7b656,0x161c67bd,0xddc7d5cd,0xae3a32cc,0xe32e8985,0xd11a5529,0x7aba9444,0x2427fa1a,0xe964ed02,0x24a1770a,0x1528392d,0x12c72fcd,0xa152ce2c +.long 0x8ec07649,0x714553a4,0x459dd453,0x18b4c290,0x7b64b110,0xea32b714,0x2e6f07a2,0xb871bfa5,0x9e2e3c9b,0xb67112e5,0x44aa90f6,0xfbf250e5,0xbd539006,0xf77aedb8,0xd172a66f,0x3b0cdf9a +.long 0xf8c51187,0xedf69fea,0x741e4da7,0x05bb67ec,0x08114345,0x47df0f32,0xbb9792b1,0x56facb07,0x8f6229e4,0xf3e007e9,0x526fba0f,0x62d103f4,0xb0339d79,0x4f33bef7,0xb59bfec1,0x9841357b +.long 0xc34e6705,0xfa8dbb59,0x7fdaa84c,0xc3c7180b,0xa4108537,0xf95872fc,0x932a3e5a,0x8750cc3b,0xb7275d7d,0xb61cc69d,0x2e59b2e9,0xffa0168b,0x6ecbb493,0xca032abc,0x2c9082d8,0x1d86dbd3 +.long 0xe28ef5ba,0xae1e0b67,0xcb18e169,0x2c9a4699,0x1e6bbd20,0x0ecd0e33,0xaf5e81d2,0x571b360e,0x101c1d45,0xcd9fea58,0x18880452,0x6651788e,0x1f8dd446,0xa9972635,0xe37281d0,0x44bed022 +.long 0x33da525d,0x094b2b2d,0x13144fd8,0xf193678e,0xf4c1061d,0xb8ab5ba4,0xdccbe0f4,0x4343b5fa,0x63812713,0xa8702371,0xf7611d93,0x47bf6d2d,0xbd21e1d7,0x46729b8c,0xd629e77d,0x7484d4e0 +.long 0x60dbac1f,0x830e6eea,0xda06a2f7,0x23d8c484,0x50ca535b,0x896714b0,0xebd97a9b,0xdc8d3644,0xb12177b4,0x106ef9fa,0x534d5d9c,0xf79bf464,0xa6ab360b,0x2537a349,0xa00c744f,0xc7c54253 +.long 0xe5911a76,0xb3c7a047,0x647f1ee7,0x61ffa5c8,0x8f56ab42,0x15aed36f,0xa3ff9ac9,0x6a0d41b0,0xcc30d357,0x68f469f5,0x6b72be96,0xbe9adf81,0x903ad461,0x1cd926fe,0xcaca441b,0x7e89e38f +.long 0xfacf69d4,0xf0f82de5,0x4775344c,0x363b7e76,0xb2e36d04,0x6894f312,0x11d1c9a5,0x3c6cb4fe,0x4008e1f2,0x85d9c339,0x249f326c,0x5e9a85ea,0x678c5e06,0xdc35c60a,0x9f86fba9,0xc08b944f +.long 0x89f71f0f,0xde40c02c,0xff3da3c0,0xad8f3e31,0x42125ded,0x3ea5096b,0xa7379183,0x13879cbf,0x6b306a0b,0x6f4714a5,0x67646c5e,0x359c2ea6,0x07726368,0xfacf8943,0x65ff431e,0x07a58935 +.long 0x68754ab0,0x24d661d1,0x6f429a76,0x801fce1d,0xa58ce769,0xc068a85f,0x5d5eca2b,0xedc35c54,0xa3f660d1,0xea31276f,0xb8fc7167,0xa0184ebe,0x1d8db0ae,0x0f20f21a,0x56c35e12,0xd96d095f +.long 0xf8c2a25b,0xedf402b5,0x059204b6,0x1bb772b9,0x19b4e34c,0x50cbeae2,0x3fa0845a,0x93109d80,0x8ef59fb5,0x54f7ccf7,0x88070963,0x3b438fe2,0x31f3ba9b,0x9e28c659,0xead9da92,0x9cc31b46 +.long 0xb733aa5f,0x3c2f0ba9,0xf05af235,0xdece47cb,0xa2ac82a5,0xf8e3f715,0x2203f18a,0xc97ba641,0x09c11060,0xc3af5504,0x46af512d,0x56ea2c05,0xf3f28146,0xfac28daf,0x959ef494,0x87fab43a +.long 0xd4c5105f,0x09891641,0x6d7fbd65,0x1ae80f8e,0xbee6bdb0,0x9d67225f,0x7fc4d860,0x3b433b59,0x93e85638,0x44e66db6,0xe3e9862f,0xf7b59252,0x665c32ec,0xdb785157,0xae362f50,0x702fefd7 +.long 0x0fefb0c3,0x3754475d,0x46d7c35d,0xd48fb56b,0x363798a4,0xa070b633,0x8fdb98e6,0xae89f3d2,0x6363d14c,0x970b89c8,0x67abd27d,0x89817521,0x44d5a021,0x9bf7d474,0xcac72aee,0xb3083baf +.long 0xbe949a44,0x389741de,0x546a4fa5,0x638e9388,0xa0047bdc,0x3fe6419c,0xaaea57ca,0x7047f648,0x41fbab17,0x54e48a90,0x576bdba2,0xda8e0b28,0xc72afddc,0xe807eebc,0xf42577bf,0x07d3336d +.long 0xbfe20925,0x62a8c244,0x8fdce867,0x91c19ac3,0xdd387063,0x5a96a5d5,0x21d324f6,0x61d587d4,0xa37173ea,0xe87673a2,0x53778b65,0x23848008,0x05bab43e,0x10f8441e,0x4621efbe,0xfa11fe12 +.long 0x81685d7b,0x047b772e,0xbf34a976,0x23f27d81,0x915f48ef,0xc27608e2,0xa521d5c3,0x3b0b43fa,0x63ca7284,0x7613fb26,0x1d4db837,0x7f5729b4,0x583b526b,0x87b14898,0xbbadd3d1,0x00b732a6 +.long 0x2048e396,0x8e02f426,0x383d9de4,0x436b50b6,0x471e85ad,0xf78d3481,0xd005c8d6,0x8b01ea6a,0x97015c07,0xd3c7afee,0x4e3ba2ae,0x46cdf1a9,0x83d3a1d2,0x7a42e501,0xb541dff4,0xd54b5268 +.long 0x4e23e9bc,0x3f24cf30,0x126e3624,0x4387f816,0x3b0b6d61,0x26a46a03,0x8b2d777c,0xaf1bc845,0x527de79c,0x25c401ba,0x4261bbb6,0x0e1346d4,0x287b4bc7,0x4b96c44b,0x5254562f,0x658493c7 +.long 0xb8a24a20,0x23f949fe,0xf52ca53f,0x17ebfed1,0xbcfb4853,0x9b691bbe,0x6278a05d,0x5617ff6b,0xe3c99ebd,0x241b34c5,0x1784156a,0xfc64242e,0x695d67df,0x4206482f,0xee27c011,0xb967ce0e +.long 0x21c80b5d,0x65db3751,0xa31ecca0,0x2e7a563c,0x5238a07e,0xe56ffc4e,0x32ced854,0x3d6c2966,0xaf70b885,0xe99d7d1a,0x2d686459,0xafc3bad9,0x0cc8ba5b,0x9c78bf46,0x18955aa3,0x5a439519 +.long 0x5fe4e314,0xf8b517a8,0xfcb8906f,0xe60234d0,0xf2061b23,0xffe542ac,0x6b4cb59c,0x287e191f,0x09d877d8,0x21857ddc,0x14678941,0x1c23478c,0xb6e05ea4,0xbbf0c056,0xb01594fe,0x82da4b53 +.long 0xfadb8608,0xf7526791,0x7b74cdf6,0x049e832d,0xc2b90a34,0xa43581cc,0x9360b10c,0x73639eb8,0xe1e4a71b,0x4fba331f,0x8072f919,0x6ffd6b93,0x65679032,0x6e53271c,0xf14272ce,0x67206444 +.long 0xb2335834,0xc0f734a3,0x90ef6860,0x9526205a,0x04e2bb0d,0xcb8be717,0x02f383fa,0x2418871e,0x4082c157,0xd7177681,0x29c20073,0xcc914ad0,0xe587e728,0xf186c1eb,0x61bcd5fd,0x6fdb3c22 +.long 0xf2f9f8e9,0x30d014a6,0x4fec49d2,0x963ece23,0x9605a8d9,0x862025c5,0x19f8929a,0x39874445,0x12bf476a,0x01b6ff65,0x09cf7d91,0x598a64d8,0x93be56ca,0xd7ec7749,0xcbb33615,0x10899785 +.long 0x02eee3ad,0xb8a092fd,0x30145270,0xa86b3d35,0x8512b675,0x323d98c6,0x62ebb40f,0x4b8bc785,0x413f9cde,0x7d301f54,0x2bab5664,0xa5e4fb4f,0x1cbfec23,0x1d2b252d,0xe177120d,0xfcd576bb +.long 0x83731a34,0x04427d3e,0xed836e8e,0x2bb9028e,0xb612ca7c,0xb36acff8,0xd3d9c73a,0xb88fe5ef,0xedea4eb3,0xbe2a6bc6,0x488eec77,0x43b93133,0xb17106e1,0xf41ff566,0x654efa32,0x469e9172 +.long 0x41c23fa3,0xb4480f04,0xc1989a2e,0xb4712eb0,0x93a29ca7,0x3ccbba0f,0xd619428c,0x6e205c14,0xb3641686,0x90db7957,0x45ac8b4e,0x0432691d,0xf64e0350,0x07a759ac,0x9c972517,0x0514d89c +.long 0xa8e67fc3,0x1701147f,0xab2085be,0x9e2e0b8b,0xac284e57,0xd5651824,0x74893664,0x890d4325,0xc55e68a3,0x8a7c5e6e,0x4339c85a,0xbf12e90b,0xf922b655,0x31846b85,0x0bf4d700,0x9a54ce4d +.long 0xf1a14295,0xd7f4e83a,0xb285d4f9,0x916f955c,0x99ffdaba,0xe57bb0e0,0xeab0d152,0x28a43034,0xb8a9cef8,0x0a36ffa2,0xb9ec051a,0x5517407e,0xea68e672,0x9c796096,0xfb3c77fb,0x853db5fb +.long 0xe864a51a,0x21474ba9,0x6e8a1b8b,0x6c267699,0x94120a28,0x7c823626,0x8383a5db,0xe61e9a48,0x9f84216d,0x7dd75003,0xad43cd85,0xab020d07,0xda12c659,0x9437ae48,0xe65452ad,0x6449c2eb +.long 0x2cf9d7c1,0xcc7c4c1c,0xee95e5ab,0x1320886a,0xbeae170c,0xbb7b9056,0xdbc0d662,0xc8a5b250,0xc11d2303,0x4ed81432,0x1f03769f,0x7da66912,0x84539828,0x3ac7a5fd,0x3bccdd02,0x14dada94 +.long 0x7ef6b0d1,0x8b84c321,0x7c933f22,0x52a9477a,0xfd440b82,0x5ef6728a,0x6ce4bd5e,0x5c3bd859,0xf22c2d3e,0x918b80f5,0xb7bb6cc5,0x368d5040,0x2695a11c,0xb66142a1,0xeb19ea70,0x60ac583a +.long 0x0eab2437,0x317cbb98,0x5e2654c8,0x8cc08c55,0xe6d8307f,0xfe2d6520,0x57428993,0xe9f147f3,0xd2fd6cf1,0x5f9c7d14,0x2d4fcbb0,0xa3ecd064,0x8e7341f7,0xad83fef0,0x3a63115c,0x643f23a0 +.long 0xe65ab743,0xd38a78ab,0x35edc89c,0xbf7c75b1,0x530df568,0x3dd8752e,0xe308c682,0xf85c4a76,0xe68acf37,0x4c9955b2,0xab32af85,0xa544df3d,0xa25cf493,0x4b8ec3f5,0x1a622feb,0x4d8f2764 +.long 0xf0dcbc49,0x7bb4f7aa,0x70bbb45b,0x7de551f9,0x9f2ca2e5,0xcfd0f3e4,0x1f5c76ef,0xece58709,0x167d79ae,0x32920edd,0xfa7d7ec1,0x039df8a2,0xbb30af91,0xf46206c0,0x22676b59,0x1ff5e2f5 +.long 0x6ea51d66,0x11f4a039,0x807d7a26,0x506c1445,0x755a9b24,0x60da5705,0x1f1a319e,0x8fc8cc32,0x9433d67d,0x83642d4d,0x6a7dd296,0x7fa5cb8f,0x9b7bde07,0x576591db,0x419716fb,0x13173d25 +.long 0xd5b340ff,0xea30599d,0xb0fe76c5,0xfc6b5297,0xab8f5adc,0x1c6968c8,0x901c928d,0xf723c7f5,0x9773d402,0x4203c321,0x1b51dd47,0xdf7c6aa3,0x552be23c,0x3d49e37a,0x0b5a6e87,0x57febee8 +.long 0x7bd8e739,0xc5ecbee4,0xae63bf75,0x79d44994,0x38fb8923,0x168bd00f,0xd0533130,0x75d48ee4,0xdb5cdf33,0x554f77aa,0x3c696769,0x3396e896,0xd3fd674e,0x2fdddbf2,0x99d0e3e5,0xbbb8f6ee +.long 0xcbae2f70,0x51b90651,0x93aaa8eb,0xefc4bc05,0xdd1df499,0x8ecd8689,0x22f367a5,0x1aee99a8,0xae8274c5,0x95d485b9,0x7d30b39c,0x6c14d445,0xbcc1ef81,0xbafea90b,0xa459a2ed,0x7c5f317a +.long 0x4ef44227,0x01211075,0xdc20f496,0xa17bed6e,0x819853cd,0x0cdfe424,0xf71e2ce7,0x13793298,0xdbbe307b,0x3c1f3078,0x76ee9936,0x6dd1c20e,0x423caa20,0x23ee4b57,0x8efb840e,0x4ac3793b +.long 0xed1f8ca0,0x934438eb,0x4ebb25a2,0x3e546658,0xc069896f,0xc415af0e,0x9a5aa43d,0xc13eddb0,0xd49eb8f6,0x7a04204f,0xd74f1670,0xd0d5bdfc,0x56fc0558,0x3697e286,0x01cebade,0x10207371 +.long 0x0647a82b,0x5f87e690,0x8f40054f,0x908e0ed4,0x79853803,0xa9f633d4,0x4a28b252,0x8ed13c9a,0x1f460f64,0x3e2ef676,0x36d06336,0x53930b9b,0x8fc4979b,0x347073ac,0x5ecd5597,0x84380e0e +.long 0xc4fe3c39,0xe3b22c6b,0x6c7bebdf,0xba4a8153,0x25693459,0xf23ab6b7,0x14922b11,0x53bc3770,0x5afc60db,0x4645c8ab,0x20b9f2a3,0xaa022355,0xce0fc507,0x52a2954c,0x7ce1c2e7,0x8c2731bb +.long 0x18a0339d,0xf39608ab,0x3735436c,0xac7a658d,0xcd992b4f,0xb22c2b07,0xf40dcfd4,0x4e83daec,0x2f39ea3e,0x8a34c7be,0xb0a56d2e,0xef0c005f,0x6edd8038,0x62731f6a,0x4e3cb075,0x5721d740 +.long 0xfbeeee1b,0x1ea41511,0xef1d0c05,0xd1ef5e73,0x73c07d35,0x42feefd1,0x8a329493,0xe530a00a,0xf15ebfb0,0x5d55b7fe,0xd322491a,0x549de03c,0x745b3237,0xf7b5f602,0x1ab6e2b6,0x3632a3a2 +.long 0x0ef59f78,0x0d3bba89,0xc9e52b9a,0x0dfc6443,0x72631447,0x1dc79699,0xb3be20b1,0xef033917,0xb1383948,0x0c92735d,0xc0dd7d7d,0xc1fc29a2,0x403ed068,0x6485b697,0xaac93bdc,0x13bfaab3 +.long 0x0deeaf52,0x410dc6a9,0x4c641c15,0xb003fb02,0x5bc504c4,0x1384978c,0x864a6a77,0x37640487,0x222a77da,0x05991bc6,0x5e47eb11,0x62260a57,0xf21b432c,0xc7af6613,0xab4953e9,0x22f3acc9 +.long 0x8e41d155,0x52934922,0x3ac059ef,0x4d024568,0x4d884411,0xb0201755,0xa59a178f,0xce8055cf,0xf6204549,0xcd77d1af,0xc7066759,0xa0a00a3e,0x0272c229,0x471071ef,0xd3c4b6b0,0x009bcf6b +.long 0x22305177,0x2a2638a8,0x41645bbf,0xd51d59df,0xc0a7a3c0,0xa81142fd,0x4c7063ee,0xa17eca6d,0x60d9dcec,0x0bb887ed,0x20ad2455,0xd6d28e51,0xa67102ba,0xebed6308,0x8bffa408,0x042c3114 +.long 0x8aa68e30,0xfd099ac5,0x1483513e,0x7a6a3d7c,0xba2d8f0c,0xffcc6b75,0x1e78b954,0x54dacf96,0xa4a9af89,0xf645696f,0x06ac98ec,0x3a411940,0x22a67a20,0x41b8b3f6,0x99dec626,0x2d0b1e0f +.long 0x40be34e8,0x27c89192,0x91907f35,0xc7162b37,0xa956702b,0x90188ec1,0xdf93769c,0xca132f7d,0x0e2025b4,0x3ece44f9,0x0c62f14c,0x67aaec69,0x22e3cc11,0xad741418,0x7ff9a50e,0xcf9b75c3 +.long 0x4d348272,0x02fa2b16,0x9959d56d,0xbd99d61a,0x18762916,0xbc4f19db,0x49c1ac80,0xcc7cce50,0xd846bd83,0x4d59ebaa,0xa9202849,0x8775a9dc,0x6e1f4ca9,0x07ec4ae1,0xba893f11,0x27eb5875 +.long 0x662cc565,0x00284d51,0x0db4138d,0x82353a6b,0xaa32a594,0xd9c7aaaa,0xa5669c47,0xf5528b5e,0x2f23c5ff,0xf3220231,0x6affa3a1,0xe3e8147a,0x202ddda0,0xfb423d5c,0x6b871bd4,0x3d6414ac +.long 0xa51a168a,0x586f82e1,0x48ae5448,0xb712c671,0x76233eb8,0x9a2e4bd1,0x78811ca9,0x0188223a,0xf7c18de1,0x553c5e21,0xb27bb286,0x7682e451,0x0e51e929,0x3ed036b3,0xec9cb34f,0xf487211b +.long 0x0c24efc8,0x0d094277,0xbef737a4,0x0349fd04,0x514cdd28,0x6d1c9dd2,0x30da9521,0x29c135ff,0xf78b0b6f,0xea6e4508,0x678c143c,0x176f5dd2,0x4be21e65,0x08148418,0xe7df38c4,0x27f7525c +.long 0x748ab1a4,0x1fb70e09,0x5efe4433,0x9cba50a0,0x15f75af2,0x7846c7a6,0x5ee73ea8,0x2a7c2c57,0x3f0a449a,0x42e566a4,0xad90fc3d,0x45474c3b,0x8b61d057,0x7447be3d,0x3a4ec092,0x3e9d1cf1 +.long 0xf380a6e6,0x1603e453,0x9b1437c2,0x0b86e431,0xef29610a,0x7a4173f2,0xf03d57f7,0x8fa729a7,0x6c9c217e,0x3e186f6e,0x91919524,0xbe1d3079,0x153d4fb1,0x92a62a70,0xd68c2f71,0x32ed3e34 +.long 0x9eb1a8b7,0xd785027f,0xc5b22fe8,0xbc37eb77,0xb9d6a191,0x466b34f0,0x9a05f816,0x008a89af,0x7d42c10a,0x19b028fb,0x49b3f6b8,0x7fe8c92f,0xa5a0ade3,0x58907cc0,0x559d1a7c,0xb3154f51 +.long 0xd9790ed6,0x5066efb6,0xa6aa793b,0xa77a0cbc,0x223e042e,0x1a915f3c,0x69c5874b,0x1c5def04,0x73b6c1da,0x0e830078,0xfcd8557a,0x55cf85d2,0x0460f3b1,0x0f7c7c76,0x46e58063,0x87052acb +.long 0x907eae66,0x09212b80,0x4d721c89,0x3cb068e0,0xdd45ac1c,0xa87941ae,0x0daa0dbb,0xde8d5c0d,0xe3502e6e,0xda421fdc,0x4d89a084,0xc8944201,0xf0c24bfb,0x7307ba5e,0x20bde0ef,0xda212beb +.long 0xf82ce682,0xea2da24b,0x07f71fe4,0x058d3816,0x5ffad8de,0x35a02462,0xaadcefab,0xcd7b05dc,0x1d9f54ec,0xd442f8ed,0xb2d3b5ca,0x8be3d618,0xe06b2ce2,0xe2220ed0,0x1b0da4c0,0x82699a5f +.long 0x71c0c3a7,0x3ff106f5,0x0d34180c,0x8f580f5a,0x22d7d375,0x4ebb120e,0xe9513675,0x5e5782cc,0x99c82a70,0x2275580c,0x15ea8c4c,0xe8359fbf,0x7b415e70,0x53b48db8,0x100c6014,0xaacf2240 +.long 0xe4652f1d,0x9faaccf5,0xd56157b2,0xbd6fdd2a,0x6261ec50,0xa4f4fb1f,0x476bcd52,0x244e55ad,0x047d320b,0x881c9305,0x6181263f,0x1ca983d5,0x278fb8ee,0x354e9a44,0x396e4964,0xad2dbc0f +.long 0x9268b3de,0x723f3aa2,0xe6e0609a,0x0d1ca29a,0x6cf44252,0x794866aa,0x01af87ed,0x0b59f3e3,0x7f4a6c51,0xe234e5ff,0x61dc2f7e,0xa8768fd2,0x0a94d81f,0xdafc7332,0x06938ce1,0xd7f84282 +.long 0x0546063e,0xae0b3c0e,0x5d61abc6,0x7fbadcb2,0x369ac400,0xd5d7a2c9,0xae67d10c,0xa5978d09,0x4f85eaac,0x290f211e,0xfacac681,0xe61e2ad1,0x388384cd,0xae125225,0xccfde30f,0xa7fb68e9 +.long 0x3daed4c2,0x7a59b936,0x2606f789,0x80a9aa40,0xf6a6d90a,0xb40c1ea5,0x514d5885,0x948364d3,0x70985182,0x062ebc60,0x33310895,0xa6db5b0e,0xe329c2f5,0x64a12175,0x90ea237e,0xc5f25bd2 +.long 0x2d0a4c23,0x7915c524,0x6bb3cc52,0xeb5d26e4,0xc09e2c92,0x369a9116,0xcf182cf8,0x0c527f92,0x2aede0ac,0x9e591938,0x6cc34939,0xb2922208,0x99a34361,0x3c9d8962,0xc1905fe6,0x3c81836d +.long 0xa001ec5a,0x4bfeb57f,0xa0dc5dba,0xe993f5bb,0x724a1380,0x47884109,0x32fe9a04,0x8a0369ab,0x8c927db8,0xea068d60,0x94655741,0xbf5f37cf,0x04b6c7ea,0x47d402a2,0x6af259cb,0x4551c295 +.long 0xed77ee8b,0x698b71e7,0xf309d5c7,0xbddf7bd0,0x34e780ca,0x6201c22c,0x4c295ef4,0xab04f7d8,0x4313a8ce,0x1c947294,0x92ca4cfe,0xe532e4ac,0xd0a7a97a,0x89738f80,0xa580fd5b,0xec088c88 +.long 0x42ce9e51,0x612b1ecc,0xb25fdd2a,0x8f9840fd,0x01e7f839,0x3cda78c0,0xece05480,0x546b3d3a,0x80d30916,0x271719a9,0x584c20c4,0x45497107,0x5bc78608,0xaf8f9478,0x277e2a4c,0x28c7d484 +.long 0x88a2ffe4,0xfce01767,0x28e169a5,0xdc506a35,0x7af9c93a,0x0ea10861,0x03fa0e08,0x1ed24361,0xa3d694e7,0x96eaaa92,0xef50bc74,0xc0f43b4d,0x64114db4,0xce6aa58c,0x7c000fd4,0x8218e8ea +.long 0x185f8844,0xac815dfb,0x1557abfb,0xcd7e90cb,0xafbfecdf,0x23d16655,0x085cac4a,0x80f3271f,0xd0e62f47,0x7fc39aa7,0x460a48e5,0x88d519d1,0xd28f101e,0x59559ac4,0xca9ae816,0x7981d9e9 +.long 0x9ac38203,0x5c38652c,0x57657fe5,0x86eaf87f,0xe21f5416,0x568fc472,0xe7e597b5,0x2afff39c,0x256d4eab,0x3adbbb07,0x8285ab89,0x22598692,0x041caefe,0x35f8112a,0xa5064c8b,0x95df02e3 +.long 0xc7004bf3,0x4d63356e,0xdb83c7de,0x230a08f4,0x8709a7b7,0xca27b270,0xcb9abd2d,0x0d1c4cc4,0x7550fee8,0x8a0bc66e,0x9cf7247e,0x369cd4c7,0x92b5b7e7,0x75562e84,0x5802af7b,0x8fed0da0 +.long 0xe48fb889,0x6a7091c2,0x7b8a9d06,0x26882c13,0x1b82a0e2,0xa2498663,0x3518152d,0x844ed736,0xd86e27c7,0x282f476f,0x04afefdc,0xa04edaca,0x6119e34d,0x8b256ebc,0x0787d78b,0x56a413e9 +.long 0x5a74be50,0x82ee061d,0xdea16ff5,0xe41781c4,0x99bfc8a2,0xe0b0c81e,0x0b547e2d,0x624f4d69,0xbdcc9ae4,0x3a83545d,0x409b1e8e,0x2573dbb6,0xa6c93539,0x482960c4,0x5ae18798,0xf01059ad +.long 0x3112795f,0x715c9f97,0x984e6ee1,0xe8244437,0xecb66bcd,0x55cb4858,0xabaffbee,0x7c136735,0x5dbec38e,0x54661595,0x388ad153,0x51c0782c,0xc6e0952f,0x9ba4c53a,0x1b21dfa8,0x27e6782a +.long 0x4ed2dbc2,0x682f903d,0x7c3b2d83,0x0eba59c8,0x9c7e9335,0x8e9dc84d,0x0eb226d7,0x5f9b21b0,0xaf267bae,0xe33bd394,0xbe2e15ae,0xaa86cc25,0x6a8ec500,0x4f0bf67d,0xf9630658,0x5846aa44 +.long 0xe2c2bf15,0xfeb09740,0xa9e99704,0x627a2205,0xc2fbc565,0xec8d73d0,0xc20c8de8,0x223eed8f,0xa8363b49,0x1ee32583,0xc9c2b0a6,0x1a0b6cb9,0x90dbc85c,0x49f7c3d2,0x1ef4c1ac,0xa8dfbb97 +.long 0x65c7c2ab,0xafb34d4c,0xe2c5ea84,0x1d4610e7,0x973c4ab5,0x893f6d1b,0x945ba5c4,0xa3cdd7e9,0x064417ee,0x60514983,0xad6bdf2b,0x1459b23c,0x5cf726c3,0x23b2c341,0x32d6354a,0x3a829635 +.long 0xab192c18,0x294f901f,0x7030164f,0xec5fcbfe,0xe2246ba6,0xe2e2fcb7,0x221a1a0c,0x1e7c88b3,0xc92d88c5,0x72c7dd93,0x1106fb59,0x41c2148e,0xa0f60f14,0x547dd4f5,0x63960f31,0xed9b52b2 +.long 0xb0a5b358,0x6c8349eb,0x9e7e2ed6,0xb154c5c2,0xeda462db,0xcad5eccf,0x2de66b69,0xf2d6dbe4,0x8665e5b2,0x426aedf3,0x7b7f5723,0x488a8513,0x8bcbb386,0x15cc43b3,0xd791d879,0x27ad0af3 +.long 0x846e364f,0xc16c236e,0xdea50ca0,0x7f33527c,0x0926b86d,0xc4810775,0x0598e70c,0x6c2a3609,0xf024e924,0xa6755e52,0x9db4afca,0xe0fa07a4,0x66831790,0x15c3ce7d,0xa6cbb0d6,0x5b4ef350 +.long 0xb6205969,0x2c4aafc4,0xf6c7854f,0x42563f02,0x1d983b48,0x016aced5,0x99949755,0xfeb356d8,0xd1a39bd7,0x8c2a2c81,0xe6934ae9,0x8f44340f,0x447904da,0x148cf91c,0x0f51a926,0x7340185f +.long 0x7409ab46,0x2f8f00fb,0x80e289b2,0x057e78e6,0xa888e5d1,0x03e5022c,0x9dede4e2,0x3c87111a,0x7809460b,0x5b9b0e1c,0x71c9abc7,0xe751c852,0xc7cc1dc9,0x8b944e28,0x1d3cfa08,0x4f201ffa +.long 0x3e6721ce,0x02fc905c,0xd0b3674c,0xd52d70da,0x18810da4,0x5dc2e5ca,0x5c69dd99,0xa984b273,0x84de5ca4,0x63b92527,0xc852dec4,0x2f1c9872,0xc2e3de09,0x18b03593,0x9813dc2f,0x19d70b01 +.long 0xa6dc1d29,0x42806b2d,0xf871e144,0xd3030009,0xaaf49276,0xa1feb333,0xc70bc04b,0xb5583b9e,0x95695f20,0x1db0be78,0x89d012b5,0xfc841811,0x05f61643,0x6409f272,0xd5883128,0x40d34174 +.long 0x67419833,0xd79196f5,0x863b7b08,0x6059e252,0x1c56700c,0x84da1817,0xb28d3ec4,0x5758ee56,0x013b0ea6,0x7da2771d,0x54c5e9b9,0xfddf524b,0x24305d80,0x7df4faf8,0x3a97763f,0x58f5c1bf +.long 0x7c696042,0xa5af37f1,0x4a2538de,0xd4cba22c,0x9ea42600,0x211cb995,0x7b069889,0xcd105f41,0xddb81e74,0xb1e1cf19,0x5157b8ca,0x472f2d89,0xee9db885,0x086fb008,0x0f26d131,0x365cd570 +.long 0xa2be7053,0x284b02bb,0x7ab9a6d6,0xdcbbf7c6,0x20f7a530,0x4425559c,0x188767c8,0x961f2dfa,0x70dc80c4,0xe2fd9435,0xf0784120,0x104d6b63,0x53567122,0x7f592bc1,0xf688ad77,0xf6bc1246 +.long 0x0f15dde9,0x05214c05,0x0d5f2b82,0xa47a76a8,0x62e82b62,0xbb254d30,0x3ec955ee,0x11a05fe0,0x9d529b36,0x7eaff46e,0x8f9e3df6,0x55ab1301,0x99317698,0xc463e371,0xccda47ad,0xfd251438 +.long 0x23d695ea,0xca9c3547,0x16e589b5,0x48ce626e,0xb187d086,0x6b5b64c7,0xb2207948,0xd02e1794,0x7198111d,0x8b58e98f,0xdcf9c3cc,0x90ca6305,0xf34089b0,0x5691fe72,0xfc7c80ff,0x60941af1 +.long 0x22eb51e5,0xa09bc0a2,0xaa9cf09a,0xc0bb7244,0x80159f06,0x36a8077f,0xdddc560e,0x8b5c989e,0x512e1f43,0x19d2f316,0xad08ff62,0x02eac554,0x07d20b4e,0x012ab84c,0xd6d4e4e1,0x37d1e115 +.long 0xab7b19a8,0xb6443e1a,0xdef8cd45,0xf08d067e,0x685e03da,0x63adf3e9,0x4792b916,0xcf15a10e,0xb738a425,0xf44bcce5,0x9636b2fd,0xebe131d5,0x7850d605,0x94068841,0xb40d749d,0x09684eaa +.long 0x72ba075b,0x8c3c669c,0xba469015,0x89f78b55,0x3e9f8ba8,0x5706aade,0xb32d7ed7,0x6d8bd565,0x805f08d6,0x25f4e63b,0xc3bcc1b5,0x7f48200d,0xb025d847,0x4e801968,0x87cbe0a8,0x74afac04 +.long 0x7e63d690,0x43ed2c2b,0x0223cdb8,0xefb6bbf0,0x2884d3fe,0x4fec3cae,0xd75e25a4,0x065ecce6,0x69f79071,0x6c2294ce,0x044b8666,0x0d9a8e5f,0x17b69d8f,0x5009f238,0xc5dfdaf7,0x3c29f8fe +.long 0xebae68c4,0x9067528f,0x30c5ba21,0x5b385632,0x1fdd1aec,0x540df119,0xcfba4c78,0xcf37825b,0xbeb11454,0x77eff980,0x60c1b066,0x40a1a991,0xf889a1c7,0xe8018980,0x76c24be0,0xb9c52ae9 +.long 0x45650ef4,0x05fbbcce,0x8aa29ac7,0xae000f10,0x4f04c470,0x884b7172,0x19bb5c25,0x7cd4fde2,0xe8840869,0x6477b22a,0x5fbd0686,0xa8868859,0x1116dfba,0xf23cc02e,0xd87d7776,0x76cd563f +.long 0xa9d82abf,0xe2a37598,0xe6c170f5,0x5f188ccb,0x5066b087,0x81682200,0xc7155ada,0xda22c212,0xfbddb479,0x151e5d3a,0x6d715b99,0x4b606b84,0xf997cb2e,0x4a73b54b,0x3ecd8b66,0x9a1bfe43 +.long 0x2a67d48a,0x1c312809,0x031fa9e2,0xcd6a671e,0x0e43a34a,0xbec3312a,0x55ef47d3,0x1d935639,0x8fea73ea,0x5ea02489,0xa035afb2,0x8247b364,0x5265b54c,0xb58300a6,0x722c7148,0x3286662f +.long 0xb4ec4c20,0xb77fd76b,0x0f3fe3fd,0xf0a12fa7,0x41d8c7e8,0xf845bbf5,0x5ec10aa8,0xe4d969ca,0x43e232a3,0x4c0053b7,0x37f8a45a,0xdc7a3fac,0x20d81c8f,0x3c4261c5,0xb00eab00,0xfd4b3453 +.long 0xd36e3062,0x76d48f86,0xa143ff02,0x626c5277,0xaf76f42e,0x538174de,0x6407ceac,0x2267aa86,0x72e572d5,0xfad76351,0xba7330eb,0xab861af7,0x418d8657,0xa0a1c8c7,0x20289a52,0x988821cb +.long 0xcccc18ad,0x79732522,0xf1a6e027,0xaadf3f8d,0x17c2354d,0xf7382c93,0xd818b689,0x5ce1680c,0xd9ecbee9,0x359ebbfc,0x1cae62ac,0x4330689c,0xc51ac38a,0xb55ce5b4,0xfe238ee8,0x7921dfea +.long 0x271d1ca5,0x3972bef8,0xe8aabd18,0x3e423bc7,0x44a3e5e3,0x57b09f3f,0x7b444d66,0x5da886ae,0xa9964375,0x68206634,0x699cd0ff,0x356a2fa3,0xdba515e9,0xaf0faa24,0xb321d79a,0x536e1f5c +.long 0x5c04e4ea,0xd3b9913a,0xd6f11513,0xd549dcfe,0x79fd1d94,0xee227bf5,0xb43f2c67,0x9f35afee,0xf1314f53,0xd2638d24,0xcabcd822,0x62baf948,0x4ef48db0,0x5542de29,0xfc5f6bb2,0xb3eb6a04 +.long 0x1208e16a,0x23c110ae,0xf8363e24,0x1a4d15b5,0x164be00b,0x30716844,0xf6f4690d,0xa8e24824,0x90b170cf,0x548773a2,0x42f191f4,0xa1bef331,0x9247aa97,0x70f418d0,0x48be9147,0xea06028e +.long 0xdbfb894e,0xe13122f3,0xce274b18,0xbe9b79f6,0xca58aadf,0x85a49de5,0x11487351,0x24957758,0xbb939099,0x111def61,0x26d13694,0x1d6a974a,0xd3fc253b,0x4474b4ce,0x4c5db15e,0x3a1485e6 +.long 0x147c15b4,0xe79667b4,0x7bc61301,0xe34f553b,0x17094381,0x032b80f8,0x723eaa21,0x55d8bafd,0xf1c0e74e,0x5a987995,0xebba289c,0x5a9b292e,0xeb4c8251,0x413cd4b2,0xd162db0a,0x98b5d243 +.long 0x68342520,0xbb47bf66,0xbaa862d1,0x08d68949,0xe906abcd,0x11f349c7,0xed7bf00e,0x454ce985,0xb55b803b,0xacab5c9e,0x31e3c16d,0xb03468ea,0xd273bf12,0x5c24213d,0x71587887,0x211538eb +.long 0x731dea2d,0x198e4a2f,0x74ed7b2a,0xd5856cf2,0x13a664fe,0x86a632eb,0xbda41291,0x932cd909,0xc0c4ddc0,0x850e95d4,0x347fc2c9,0xc0f422f8,0x86076bcb,0xe68cbec4,0xcd6cd286,0xf9e7c0c0 +.long 0x0f5f27ca,0x65994ddb,0xa80d59ff,0xe85461fb,0x66601023,0xff05481a,0xfc9ebbfb,0xc665427a,0x7587fd52,0xb0571a69,0x8d49efce,0x935289f8,0xea420688,0x61becc60,0x13a786af,0xb22639d9 +.long 0x361ecf90,0x1a8e6220,0x25506463,0x001f23e0,0x0a5c2b79,0xe4ae9b5d,0xd8149db5,0xebc9cdad,0x934aa728,0xb33164a1,0xae9b60f3,0x750eb00e,0x9b9cfbfd,0x5a91615b,0xef45f7f6,0x97015cbf +.long 0xbf5151df,0xb462c4a5,0xb07118f2,0x21adcc41,0x043fa42c,0xd60c545b,0xe96be1ab,0xfc21aa54,0x4e51ea80,0xe84bc32f,0x259b5d8d,0x3dae45f0,0xc38f1b5e,0xbb73c7eb,0xe8ae617d,0xe405a74a +.long 0x9f1c56bd,0xbb1ae9c6,0x49f196a4,0x8c176b98,0x6875092b,0xc448f311,0x9f976033,0xb5afe3de,0x145813e5,0xa8dafd49,0xe2b34226,0x687fc4d9,0x4c7ff57f,0xf2dfc92d,0x401f1b46,0x004e3fc1 +.long 0x1430c9ab,0x5afddab6,0x2238e997,0x0bdd41d3,0x418042ae,0xf0947430,0xcdddc4cb,0x71f9adda,0xc52dd907,0x7090c016,0x29e2047f,0xd9bdf44d,0x1b1011a6,0xe6f1fe80,0xd9acdc78,0xb63accbc +.long 0x1272a95b,0xcfc7e235,0xa6276ac8,0x0c667717,0xe2d7eef7,0x3c0d3709,0x9a685b3e,0x5add2b06,0x14ea5d65,0x363ad32d,0x8d7dd506,0xf8e01f06,0x75b4aac6,0xc9ea2213,0x0d353466,0xed2a2bf9 +.long 0xe9d3a7c3,0x439d79b5,0x81b7f34b,0x8e0ee5a6,0x1dc4ba75,0xcf3dacf5,0xeb3310c7,0x1d3d1773,0x7747ae83,0xa8e67112,0x197d6b40,0x31f43160,0xcd961400,0x0521ccee,0xf6535768,0x67246f11 +.long 0xef0c3133,0x702fcc5a,0x7e16693b,0x247cc45d,0xc729b749,0xfd484e49,0xb218320f,0x522cef7d,0x59ab93b3,0xe56ef405,0x9f181071,0x225fba11,0x15330ed0,0x33bd6595,0x1ddb32f7,0xc4be69d5 +.long 0x0448087c,0x264c7668,0x71432dae,0xac30903f,0x00f9bf47,0x3851b266,0x6cdd6d03,0x400ed311,0xf8fd2424,0x045e79fe,0xfa6da98b,0xfdfd974a,0x0c1e673a,0x45c9f641,0x5b2c5168,0x76f2e733 +.long 0x2a601753,0x1adaebb5,0xc57c2d49,0xb286514c,0x1e0bfd24,0xd8769670,0x04478922,0x950c547e,0xe5d32bfe,0xd1d41969,0x750d6c3e,0x30bc1472,0xe0e27f3a,0x8f3679fe,0xa4a6ee0c,0x8f64a7dc +.long 0x633dfb1f,0x2fe59937,0x977f2547,0xea82c395,0x661ea646,0xcbdfdf1a,0xb9085451,0xc7ccc591,0x81761e13,0x82177962,0x9196885c,0xda57596f,0x28ffbd70,0xbc17e849,0x2671d36f,0x1e6e0a41 +.long 0x4152fcf5,0x61ae872c,0x9e77e754,0x441c87b0,0xa34dff09,0xd0799dd5,0x88a6b171,0x766b4e44,0x11f1c792,0xdc06a512,0x4be35c3e,0xea02ae93,0xe90c469e,0xe5ca4d6d,0x56e4ff5c,0x4df4368e +.long 0x4baef62e,0x7817acab,0xa85b91e8,0x9f5a2202,0x6ce57610,0x9666ebe6,0xf73bfe03,0x32ad31f3,0x25bcf4d6,0x628330a4,0x515056e6,0xea950593,0xe1332156,0x59811c89,0x8c11b2d7,0xc89cf1fe +.long 0x04e60cc0,0x75b63913,0x4625d375,0xce811e8d,0x2d26e562,0x030e43fc,0x608d36a0,0xfbb30b4b,0x48528118,0x634ff82c,0xcd285911,0x7c6fe085,0x99358f28,0x7f2830c0,0x665e6c09,0x2e60a95e +.long 0x9b785dbf,0x08407d3d,0xa759bce7,0x530889ab,0x52f61239,0xf228e0e6,0x6879be3c,0x2b6d1461,0x51a7bbf7,0xe6902c04,0x76f24a64,0x30ad99f0,0x98bc6da0,0x66d9317a,0xcb596ac0,0xf4f877f3 +.long 0x4c44f119,0xb05ff62d,0xe9b77416,0x4555f536,0x8caed63b,0xc7c0d059,0xc358b2a9,0x0cd2b7ce,0x46945fa3,0x3f33287b,0xd67c8791,0xf8785b20,0x9637bd08,0xc54a7a61,0x18be79d7,0x54d4598c +.long 0xc46d7ce1,0x889e5acb,0x8b085877,0x9a515bb7,0x0b7a5050,0xfac1a03d,0xf2926035,0x7d3e738a,0x2a6cb0eb,0x861cc2ce,0x8f7adc79,0x6f2e2955,0x33016376,0x61c4d451,0x5ad59090,0xd9fd2c80 +.long 0xb2b836a1,0xe5a83738,0x7c0d6622,0x855b41a0,0x7cc19af1,0x186fe317,0xfdd99acb,0x6465c1ff,0x6974b99e,0x46e5c23f,0xa2717cbe,0x75a7cf8b,0x062be658,0x4d2ebc3f,0x5f209c98,0x094b4447 +.long 0xb940cb5a,0x4af285ed,0x7cc82f10,0x6706d792,0x030526fa,0xc8c8776c,0xa0da9140,0xfa8e6f76,0x591ee4f0,0x77ea9d34,0x40274166,0x5f46e337,0xea671457,0x1bdf98bb,0x862a1fe2,0xd7c08b46 +.long 0x1c08ad63,0x46cc303c,0x4c845e7b,0x99543440,0x48f36bf7,0x1b8fbdb5,0x8c8273a7,0x5b82c392,0x928435d5,0x08f712c4,0x79330380,0x071cf0f1,0xa8da054a,0xc74c2d24,0x43c46b5c,0xcb0e7201 +.long 0xc0b7eff3,0x0ad7337a,0xc5e48b3c,0x8552225e,0x73f13a5f,0xe6f78b0c,0x82349cbe,0x5e70062e,0xe7073969,0x6b8d5048,0xc33cb3d2,0x392d2a29,0x4ecaa20f,0xee4f727c,0x2ccde707,0xa068c99e +.long 0xb87a2913,0xfcd5651f,0x3cc252f0,0xea3e3c15,0x3b6cd3e4,0x777d92df,0xc5a732e7,0x7a414143,0xa71ff493,0xa895951a,0xbbd37cf6,0xfe980c92,0xdecfeeff,0x45bd5e64,0xa44c43e9,0x910dc2a9 +.long 0xcca9f54d,0xcb403f26,0x9303f6db,0x928bbdfb,0xa9eee67c,0x3c37951e,0xf79961c3,0x3bd61a52,0x395c9a79,0x09a238e6,0x61eb352d,0x6940ca2d,0xc1875631,0x7d1e5c5e,0x1e1b20d1,0x1e19742c +.long 0x23fc2e6e,0x4633d908,0x08959149,0xa76e29a9,0x84ed7da5,0x61069d9c,0x5dbcad51,0x0baa11cf,0x961849da,0xd01eec64,0xaf3d8c28,0x93b75f1f,0x1ca2ee44,0x57bc4f9f,0x00e00558,0x5a26322d +.long 0x61a023ef,0x1888d658,0xb9e5246e,0x1d72aab4,0xe5563ec0,0xa9a26348,0xc3439a43,0xa0971963,0xadb9b5b7,0x567dd54b,0xc45a524b,0x73fac1a1,0xfe38e608,0x8fe97ef7,0x3f384f48,0x608748d2 +.long 0xc486094f,0xb0571794,0x8bf3a8d6,0x869254a3,0x310b0e25,0x148a8dd1,0x9aa3f7d8,0x99ab9f3f,0x6706c02e,0x0927c68a,0x69790e6c,0x22b5e76c,0x6c71376c,0x6c325260,0x09ef6657,0x53a57690 +.long 0xedffcf3a,0x8d63f852,0x3c0a6f55,0xb4d2ed04,0x12519b9e,0xdb3aa8de,0x1e0a569a,0x5d38e9c4,0x303747e2,0x871528bf,0xf5b5c18d,0xa208e77c,0xca6bf923,0x9d129c88,0xbf02839f,0xbcbf197f +.long 0x27323194,0x9b9bf030,0x339ca59d,0x3b055a8b,0x0f669520,0xb46b2312,0x497e5f24,0x19789f1f,0xaaf01801,0x9c499468,0x8b69d59c,0x72ee1190,0xacf4c079,0x8bd39595,0x8e0cd048,0x3ee11ece +.long 0x1ed66f18,0xebde86ec,0xd61fce43,0x225d906b,0xe8bed74d,0x5cab07d6,0x27855ab7,0x16e4617f,0xb2fbc3dd,0x6568aadd,0x8aeddf5b,0xedb5484f,0x6dcf2fad,0x878f20e8,0x615f5699,0x3516497c +.long 0xfa181e69,0xef0a3fec,0x30d69a98,0x9ea02f81,0x66eab95d,0xb2e9cf8e,0x24720021,0x520f2beb,0x1df84361,0x621c540a,0x71fa6d5d,0x12037721,0x0ff5f6ff,0x6e3c7b51,0xabb2bef3,0x817a069b +.long 0xb294cda6,0x83572fb6,0xb9039f34,0x6ce9bf75,0x095cbb21,0x20e012f0,0xd063f0da,0xa0aecc1b,0xf02909e5,0x57c21c3a,0x48ce9cdc,0xc7d59ecf,0x8ae336f8,0x2732b844,0x3f4f85f4,0x056e3723 +.long 0x89e800ca,0x8a10b531,0x145208fd,0x50fe0c17,0xb714ba37,0x9e43c0d3,0x34189acc,0x427d200e,0xe616e2c0,0x05dee24f,0xee1854c1,0x9c25f4c8,0x8f342a73,0x4d3222a5,0xa027c952,0x0807804f +.long 0x4f0d56f3,0xc222653a,0xca28b805,0x961e4047,0x4a73434b,0x2c03f8b0,0xab712a19,0x4c966787,0x864fee42,0xcc196c42,0x5b0ece5c,0xc1be93da,0xc131c159,0xa87d9f22,0xdce45655,0x2bb6d593 +.long 0xb809b7ce,0x22c49ec9,0xe2c72c2c,0x8a41486b,0xfea0bf36,0x813b9420,0xa66dac69,0xb3d36ee9,0x328cc987,0x6fddc08a,0x3a326461,0x0a3bcd2c,0xd810dbba,0x7103c49d,0x4b78a4c4,0xf9d81a28 +.long 0xe4d55941,0x3de865ad,0x30384087,0xdedafa5e,0x4ef18b9b,0x6f414abb,0xfaee5268,0x9ee9ea42,0x37a55a4a,0x260faa16,0x015f93b9,0xeb19a514,0x9e9c3598,0x51d7ebd2,0x1932178e,0x523fc56d +.long 0xb98fe684,0x501d070c,0x124a1458,0xd60fbe9a,0x92bc6b3f,0xa45761c8,0xfe6f27cb,0xf5384858,0xb59e763b,0x4b0271f7,0x5b5a8e5e,0x3d4606a9,0x05a48292,0x1eda5d9b,0xe6fec446,0xda7731d0 +.long 0x90d45871,0xa3e33693,0x06166d8d,0xe9764040,0x89a90403,0xb5c33682,0x72f1d637,0x4bd17983,0xd5d2c53a,0xa616679e,0xfdcf3b87,0x5ec4bcd8,0xb66a694e,0xae6d7613,0xe3fc27e5,0x7460fc76 +.long 0x95caabee,0x70469b82,0x889501e3,0xde024ca5,0x076ed265,0x6bdadc06,0x5a0ef8b2,0x0cb1236b,0x0972ebf9,0x4065ddbf,0x22aca432,0xf1dd3875,0x744aff76,0xa88b97cf,0xfe8e3d24,0xd1359afd +.long 0x91502cf3,0x52a3ba2b,0x084db75d,0x2c3832a8,0xde30b1c9,0x04a12ddd,0xe31fd60c,0x7802eabc,0xa37fddab,0x33707327,0xfaafa973,0x65d6f2ab,0x11e6f91a,0x3525c5b8,0x5f46530b,0x76aeb0c9 +.long 0x2f93a675,0xe8815ff6,0x05f48679,0xa6ec9684,0x358ae884,0x6dcbb556,0xe19e3873,0x0af61472,0xa5f696be,0x72334372,0x6f22fb70,0xc65e57ea,0x946cea90,0x268da30c,0x65681b2a,0x136a8a87 +.long 0x0f9f44d4,0xad5e81dc,0x2c46585a,0xf09a6960,0xc447d1b1,0xd1649164,0x879dc8b1,0x3b4b36c8,0x3b6b234c,0x20d4177b,0x1730d9d0,0x096a2505,0xef80531d,0x0611b9b8,0x64bb495d,0xba904b3b +.long 0x93a3147a,0x1192d9d4,0x9a565545,0x9f30a5dc,0x6ef07212,0x90b1f9cb,0x0d87fc13,0x29958546,0xc17db9ba,0xd3323eff,0xcb1644a8,0xcb18548c,0x4f49ffbc,0x18a306d4,0x4c2e8684,0x28d658f1 +.long 0xa99f8c71,0x44ba60cd,0x4bf742ff,0x67b7abdb,0x914b3f99,0x66310f9c,0xf412c161,0xae430a32,0x88ace52f,0x1e6776d3,0x52d7067d,0x4bc0fa24,0x8f07cd1b,0x03c286aa,0xa985b2c1,0x4cb8f38c +.long 0x8c3bff36,0x83ccbe80,0x5263e575,0x005a0bd2,0x259bdcd1,0x460d7dda,0xfa5cab6b,0x4a1c5642,0x9fe4fc88,0x2b7bdbb9,0xcc97bbb5,0x09418e28,0xa12321ae,0xd8274fb4,0x5c87b64e,0xb137007d +.long 0xc63c4962,0x80531fe1,0x981fdb25,0x50541e89,0xfd4c2b6b,0xdc1291a1,0xa6df4fca,0xc0693a17,0x0117f203,0xb2c4604e,0x0a99b8d0,0x245f1963,0xc6212c44,0xaedc20aa,0x520f52a8,0xb1ed4e56 +.long 0xf8547be3,0xfe48f575,0xa9e45f98,0x0a7033cd,0x18c50100,0x4b45d3a9,0xa61d41da,0xb2a6cd6a,0x57933c6b,0x60bbb4f5,0x2b0d7ffc,0xa7538ebd,0x8cd626b6,0x9ea3ab8d,0x3601625a,0x8273a484 +.long 0x0168e508,0x88859845,0x99a94abd,0x8cbc9bb2,0xfab0a671,0x713ac792,0x6c9ebffc,0xa3995b19,0x1239e152,0xe711668e,0xbbb8dff4,0x56892558,0xdbf17963,0x8bfc7dab,0xb3de1253,0x5b59fe5a +.long 0x34a9f7ae,0x7e3320eb,0xd751efe4,0xe5e8cf72,0xd9be2f37,0x7ea003bc,0xb6c08ef7,0xc0f551a0,0x038f6725,0x56606268,0x6d92d3b6,0x1dd38e35,0xc3cbd686,0x07dfce7c,0x651c5da8,0x4e549e04 +.long 0x08b19340,0x4058f93b,0xcac6d89d,0xc2fae6f4,0x8f159cc7,0x4bad8a8c,0xcb0b601c,0x0ddba4b3,0x1dd95f8c,0xda4fc7b5,0xcea5c255,0x1d163cd7,0x274a8c4c,0x30707d06,0x2802e9ce,0x79d9e008 +.long 0xe6ddd505,0x02a29ebf,0xb50bed1a,0x37064e74,0xa7327d57,0x3f6bae65,0xf83920bc,0x3846f5f1,0x60df1b9b,0x87c37491,0x2d1da29f,0x4cfb2895,0x4ed1743c,0x10a478ca,0x3edd47c6,0x390c6030 +.long 0x8c0a78de,0x8f3e5312,0x1e85df70,0xccd02bda,0xa61b6582,0xd6c75c03,0xfc0eebd1,0x0762921c,0xd85010c0,0xd34d0823,0x0044cf1f,0xd73aaacb,0xa3b5e78a,0xfb4159bb,0xe5826f3f,0x2287c7f7 +.long 0x580b1a01,0x4aeaf742,0x60423b79,0xf080415d,0xa7dea144,0xe12622cd,0x59d62472,0x49ea4996,0x571f3913,0xb42991ef,0xf5b25a8a,0x0610f214,0x30b79e8f,0x47adc585,0x07a065a2,0xf90e3df6 +.long 0x43e2e034,0x5d0a5deb,0x444024aa,0x53fb5a34,0x6b0c9f7f,0xa8628c68,0xac563656,0x9c69c29c,0xbace47b6,0x5a231feb,0x9ea5a2ec,0xbdce0289,0x9463853e,0x05da1fac,0x509e78aa,0x96812c52 +.long 0x57151692,0xd3fb5771,0xd98e1c44,0xeb2721f8,0x32399be1,0xc0506087,0xd979d8b8,0xda5a5511,0xc6f56780,0x737ed55d,0x0dc7a7f4,0xe20d3004,0xf5941a03,0x02ce7301,0xed30f83a,0x91ef5215 +.long 0x4092d85f,0x28727fc1,0x5c49e41a,0x72d223c6,0xba6a4d81,0xa7cf30a2,0xb030d87d,0x7c086209,0xfc588b09,0x04844c7d,0x5874bbb0,0x728cd499,0xe84c0495,0xcc1281ee,0xec31958f,0x0769b5ba +.long 0xf99c2471,0x665c228b,0x191eb110,0xf2d8a11b,0xd36d7024,0x4594f494,0xcdcb25a1,0x482ded8b,0xdadd4885,0xc958a9d8,0xf1d2b547,0x7004477e,0x2a0af550,0x0a45f6ef,0x2f8d6351,0x4fc739d6 +.long 0x786f08a9,0x75cdaf27,0x42c2737f,0x8700bb26,0x1c4e2670,0x855a7141,0x15076fef,0x810188c1,0xabcd3297,0xc251d0c9,0xf48108eb,0xae4c8967,0x18ceed30,0xbd146de7,0xc986bced,0xf9d4f07a +.long 0x83fa1e08,0x5ad98ed5,0xbeabd1fb,0x7780d33e,0x903b1196,0xe330513c,0xa47bc8c4,0xba11de9e,0x02c2d064,0x684334da,0xa48de23b,0x7ecf360d,0x0a9089d8,0x57a1b474,0xff36734c,0xf28fa439 +.long 0xea4570b3,0xf2a482cb,0xa5ebcee9,0xee65d68b,0xb9694cd5,0x988d0036,0x37885d32,0x53edd0e9,0xbeb9bc6d,0xe37e3307,0x9f5c6768,0xe9abb907,0x51f2160f,0x4396ccd5,0x47336da6,0x2500888c +.long 0x926fce43,0x383f9ed9,0x04da2930,0x809dd1c7,0x8a4cb227,0x30f6f596,0x73a56b38,0x0d700c7f,0xab64a065,0x1825ea33,0x1338df80,0xaab9b735,0x9b63f57f,0x1516100d,0x27a6a634,0x2574395a +.long 0x700a1acd,0xb5560fb6,0xfd999681,0xe823fd73,0x6cb4e1ba,0xda915d1f,0x6ebe00a3,0x0d030118,0x89fca8cd,0x744fb0c9,0xf9da0e0b,0x970d01db,0x7931d76f,0x0ad8c564,0xf659b96a,0xb15737bf +.long 0xa8b484e7,0xdc9933e8,0x7a26dec7,0xb2fdbdf9,0x9f1f0136,0x2349e9a4,0x70fddddb,0x7860368e,0xf9ad3e18,0xd93d2c1c,0x689f4e79,0x6d6c5f17,0xb24ff1b6,0x7a544d91,0xfe16cd8c,0x3e12a5eb +.long 0xa56b872f,0x543574e9,0xfcf68ea2,0xa1ad550c,0x3f560ef7,0x689e37d2,0xc9d47a8b,0x8c54b9ca,0x088ac342,0x46d40a4a,0x1576c6d0,0xec450c7c,0x1f9689e9,0xb589e31c,0xb8781718,0xdacf2602 +.long 0xc8cb6b42,0xa89237c6,0xb96ef381,0x1326fc93,0xb5f07825,0x55d56c6d,0x7449e22d,0xacba2eea,0x633c3000,0x74e0887a,0xd7cbcf71,0xcb6cd172,0xc36cf1be,0x309e81de,0x60ae399b,0x07a18a6d +.long 0x9edce57e,0xb36c2679,0xdf001d41,0x52b892f4,0x16a1f2c6,0xd884ae5d,0xefcc370a,0x9b329424,0xbd2e21df,0x3120daf2,0x02470a99,0x55298d2d,0xa05db32e,0x0b78af6c,0x601f5636,0x5c76a331 +.long 0xf8a4f29c,0xaae861ff,0xd68f8d49,0x70dc9240,0x81b1321c,0x960e649f,0x8792e4ce,0x3d2c801b,0x42521876,0xf479f772,0x416c79b1,0x0bed93bc,0x263e5bc9,0xa67fbc05,0x521db049,0x01e8e630 +.long 0xc6f3431e,0x76f26738,0xe3267541,0xe609cb02,0x818c877c,0xb10cff2d,0x786a13cb,0x1f0e75ce,0x1158544d,0xf4fdca64,0x6cb71ed0,0x5d777e89,0xa9aa4755,0x3c233737,0xe527ab40,0x7b453192 +.long 0x39f05ffe,0xdb59f688,0x6d82574e,0x8f4f4be0,0xee292d1b,0xcce3450c,0x61ccd086,0xaa448a12,0xf7914967,0xabce91b3,0x1908a5ed,0x4537f09b,0xf51042e7,0xa812421e,0xec0b3a34,0xfaf5cebc +.long 0x4ca6b39a,0x730ffd87,0x02efd342,0x70fb72ed,0xd75c8edb,0xeb4735f9,0xc278aa51,0xc11f2157,0xbf3bfebf,0xc459f635,0x6bd9601f,0x3a1ff0b4,0xc420cb73,0xc9d12823,0x3c2915a3,0x3e9af3e2 +.long 0xb41c3440,0xe0c82c72,0xe3039a5f,0x175239e5,0x558795a3,0xe1084b8a,0xd01e5c60,0x328d0a1d,0xd3788a04,0x0a495f2e,0x66c11a9f,0x25d8ff16,0x9ed692d6,0xf5155f05,0x4f425fe4,0x954fa107 +.long 0xe98aaa99,0xd16aabf2,0x96b0f88a,0x90cd8ba0,0xc154026a,0x957f4782,0x52af56d2,0x54ee0734,0x45b4147a,0xbcf89e54,0x9a52816c,0x3d102f21,0x39b62e77,0x6808517e,0x69169ad8,0x92e25421 +.long 0xbb608558,0xd721d871,0xf6d4ff9b,0x60e4ebae,0x41f2763e,0x0ba10819,0x51ee3247,0xca2e45be,0x2bfd7a5f,0x66d172ec,0x74d0b12d,0x528a8f2f,0xdabe70dc,0xe17f1e38,0x9f93983c,0x1d5d7316 +.long 0xdf423e31,0x51b2184a,0xaedb1a10,0xcb417291,0x625bcab9,0x2054ca93,0xa98998f0,0x54396860,0xa54ae57e,0x4e53f6c4,0xee648e9d,0x0ffeb590,0x6afaf6bc,0xfbbdaadc,0xaa3bfb8a,0xf88ae796 +.long 0xd2359ed9,0x209f1d44,0xf3544ce2,0xac68dd03,0xfd51e569,0xf378da47,0x2cc80097,0xe1abd860,0x343b6e3a,0x23ca18d9,0xb40a1bae,0x480797e8,0x533f3e67,0xd1f0c717,0x06e6cdfc,0x44896970 +.long 0x52a82e8d,0x8ca21055,0x78460cdc,0xb2caf785,0xe9037178,0x4c1b7b62,0xdb514b58,0xefc09d2c,0x9113be5c,0x5f2df9ee,0xb3f9271c,0x2fbda78f,0x8f83fc54,0xe09a81af,0x8afb5141,0x06b13866 +.long 0x43e3865d,0x38f6480f,0x1ddf47d9,0x72dd77a8,0x4c205ff7,0xf2a8e971,0x9d088ad8,0x46d449d8,0x185d706f,0x926619ea,0xc7dd7f62,0xe47e02eb,0x8cbc2031,0xe7f120a7,0x998d4ac9,0xc18bef00 +.long 0x6bdf22da,0x18f37a9c,0x90dc82df,0xefbc432f,0x5d703651,0xc52cef8e,0xd99881a5,0x82887ba0,0xb920ec1d,0x7cec9dda,0xec3e8d3b,0xd0d7e8c3,0x4ca88747,0x445bc395,0x9fd53535,0xedeaa2e0 +.long 0x6cc87475,0x461b1d93,0x6d2383bd,0xd92a52e2,0xd7903546,0xfabccb59,0x3d14b112,0x6111a761,0xb3d5f612,0x0ae584fe,0x60e828ec,0x5ea69b8d,0x54087030,0x6c078985,0xac4821fe,0x649cab04 +.long 0x8bdce214,0x25ecedcf,0x86af7361,0xb5622f72,0x7038b9e2,0x0e1227aa,0xac20fa77,0xd0efb273,0x79df975b,0x817ff88b,0x1999503e,0x856bf286,0x5038ec46,0xb4d5351f,0xfc42af6e,0x740a52c5 +.long 0x2cbb1a3f,0x2e38bb15,0x17a83429,0xc3eb99fe,0xdd66bb74,0xca4fcbf1,0xcde5e8fc,0x880784d6,0xb4e7a0be,0xddc84c1c,0xbd15a72f,0x8780510d,0x81ec30e1,0x44bcf1af,0x0a61073e,0x141e50a8 +.long 0x47be87ae,0x0d955718,0xf76a4372,0x68a61417,0xc607c3d3,0xf57e7e87,0x5252f332,0x043afaf8,0x1552a4d2,0xcc14e121,0xbb4d4ab4,0xb6dee692,0xa03816a4,0xb6ab74c8,0x6f394a29,0x84001ae4 +.long 0xd795fb45,0x5bed8344,0xb79f55a5,0x57326e7d,0x4accdffc,0xc9533ce0,0x3993fa04,0x53473caf,0xa13df4c8,0x7906eb93,0x97cbe46f,0xa73e51f6,0x0ae4ccf8,0xd1ab3ae1,0x8a5b3dbc,0x25614508 +.long 0x11a71b27,0x61eff962,0x6bb7fa39,0xdf71412b,0x2bd7f3ef,0xb31ba6b8,0x69180d29,0xb0b9c415,0x014cdde5,0xeec14552,0x227b4bbb,0x702c624b,0xd3e988f3,0x2b15e8c2,0xa4f7fd04,0xee3bcc6d +.long 0x42ac6c85,0x9d00822a,0x1df9f2b7,0x2db0cea6,0x42de1e58,0xd7cad2ab,0x2d6fbb61,0x346ed526,0x1a2faf09,0xb3962995,0x7c25612e,0x2fa8a580,0x7cf56490,0x30ae04da,0x0eea3961,0x75662908 +.long 0x3d080847,0x3609f5c5,0x5241d4f6,0xcb081d39,0x77961a63,0xb4fb3810,0x2abb66fc,0xc20c5984,0xf902f245,0x3d40aa7c,0x4e536b1e,0x9cb12736,0x99b3134f,0x5eda24da,0x5cd011af,0xafbd9c69 +.long 0xc7088c7d,0x9a16e30a,0x3207389f,0x5ab65710,0xe7407a53,0x1b09547f,0x4fdc6eab,0x2322f9d7,0x7430de4d,0xc0f2f22d,0xe68ca9a9,0x19382696,0x918e5868,0x17f1eff1,0x586f4204,0xe3b5b635 +.long 0x3fbc4341,0x146ef980,0x5b5eed4e,0x359f2c80,0x7482e41d,0x9f35744e,0xf3b224c2,0x9a9ac3ec,0x91fc50ae,0x9161a6fe,0xc613fa7c,0x89ccc66b,0xc732f15a,0x89268b14,0xb467ed03,0x7cd6f4e2 +.long 0xce56b40e,0xfbf79869,0xc02dde98,0xf93e094c,0xedee2cd7,0xefe0c3a8,0xb268fd42,0x90f3ffc0,0x08241aed,0x81a7fd56,0x00b1afe8,0x95ab7ad8,0x3e310d52,0x40127056,0x09d9fc43,0xd3ffdeb1 +.long 0xd11a8594,0xc8f85c91,0x31cf6db8,0x2e74d258,0x02b5dfd0,0x829c7ca3,0x69143c86,0xe389cfbe,0x941768d8,0xd01b6405,0x03bf825d,0x45103995,0x56cd17e2,0xcc4ee166,0xba037e79,0xbea3c283 +.long 0xd9a47520,0x4e1ac06e,0xaf852404,0xfbfe18aa,0x8087648a,0x5615f8e2,0xb9d150d9,0x7301e47e,0xb299b977,0x79f9f9dd,0xa5b78314,0x76697a7b,0x7d7c90e7,0x10d67468,0x937210b5,0x7afffe03 +.long 0x28c22cee,0x5aef3e4b,0x09fd55ae,0xefb0ecd8,0x0d2a5d6a,0x4cea7132,0x01db6357,0x9cfb5fa1,0xf36e1ac5,0x395e0b57,0x36cafb7d,0x008fa9ad,0x5308c4db,0x8f6cdf70,0x95ed2477,0x51527a37 +.long 0x5bd21311,0xba0dee30,0x909c90d7,0x6ed41b22,0x7c8696d3,0xc5f6b758,0x3ce83a80,0x0db8eaa8,0xb24b4b6f,0xd297fe37,0x522d1f0d,0xfe58afe8,0x8c98dbd9,0x97358736,0x9454a527,0x6bc226ca +.long 0xce53c2d0,0xa12b384e,0x5e4606da,0x779d897d,0x73ec12b0,0xa53e47b0,0x5756f1ad,0x462dbbba,0xcafe37b6,0x69fe09f2,0xecce2e17,0x273d1ebf,0x3cf607fd,0x8ac1d538,0x12e10c25,0x8035f7ff +.long 0x7e6c5520,0x854d34c7,0xdcb9ea58,0xc27df9ef,0xd686666d,0x405f2369,0x0417aa85,0x29d1febf,0x93470afe,0x9846819e,0xe2a27f9e,0x3e6a9669,0xe31e6504,0x24d008a2,0x9cb7680a,0xdba7cecf +.long 0x338d6e43,0xecaff541,0x4541d5cc,0x56f7dd73,0x96bc88ca,0xb5d426de,0x9ed3a2c3,0x48d94f6b,0x2ef8279c,0x6354a3bb,0x0b1867f2,0xd575465b,0x95225151,0xef99b0ff,0xf94500d8,0xf3e19d88 +.long 0xe32dd620,0x92a83268,0x627849a2,0x913ec99f,0x2c378882,0xedd8fdfa,0xee6f8cfe,0xaf96f33e,0xdc3fa8a5,0xc06737e5,0xb0b03a1d,0x236bb531,0x89f037b0,0x33e59f29,0xd9a12a53,0x13f9b5a7 +.long 0x51efb310,0x0d0df6ce,0x958df5be,0xcb5b2eb4,0x36158e59,0xd6459e29,0x1466e336,0x82aae2b9,0x411aa636,0xfb658a39,0xd4c0a933,0x7152ecc5,0x49f026b7,0xf10c758a,0xcb09311f,0xf4837f97 +.long 0xc753c45f,0xddfb02c4,0xf9c840fe,0x18ca81b6,0xb0f8a3e6,0x846fd09a,0xe7733dbc,0xb1162add,0x236e3ab6,0x7070ad20,0xb2a56326,0xf88cdaf5,0x997cbc7a,0x05fc8719,0x4b665272,0x442cd452 +.long 0xb71698f5,0x7807f364,0x9f7b605e,0x6ba418d2,0xa03b2cbb,0xfd20b00f,0xda54386f,0x883eca37,0xf3437f24,0xff0be43f,0xa48bb33c,0xe910b432,0x329df765,0x4963a128,0xbe2fe6f7,0xac1dd556 +.long 0x24a0a3fc,0x557610f9,0xe881c3f9,0x38e17bf4,0xed0dac99,0x6ba84faf,0x59eeb918,0xd4a222c3,0x13f542b6,0xc79c1dbe,0xe425d457,0x1fc65e0d,0x1debb779,0xeffb754f,0x9e08af60,0x638d8fd0 +.long 0x626332d5,0x994f523a,0x5561bb44,0x7bc38833,0x3d845ea2,0x005ed4b0,0xc2a1f08a,0xd39d3ee1,0xe7676b0d,0x6561fdd3,0xfb706017,0x620e35ff,0xf264f9a8,0x36ce424f,0xda2681f7,0xc4c3419f +.long 0x69beb6e8,0xfb6afd2f,0x6d700d03,0x3a50b993,0x0c83a14f,0xc840b2ad,0x54085bef,0x573207be,0x09fe7e5b,0x5af882e3,0x3b40a7e1,0x957678a4,0x543056e2,0x172d4bdd,0x0df13c0a,0x9c1b26b4 +.long 0xf405ff06,0x1c30861c,0x486e828b,0xebac86bd,0x636933fc,0xe791a971,0x7aeee947,0x50e7c2be,0xfa90d767,0xc3d4a095,0xe670ab7b,0xae60eb7b,0x397b056d,0x17633a64,0x105012aa,0x93a21f33 +.long 0xabb88643,0x663c370b,0x22e21599,0x91df36d7,0x8b761671,0x183ba835,0x728f3bf1,0x381eea1d,0x39966e6c,0xb9b2f1ba,0xe7295492,0x7c464a28,0x09b26b7f,0x0fd5f70a,0xfbe009df,0xa9aba1f9 +.long 0x369b87ad,0x857c1f22,0x32fca556,0x3c00e5d9,0x90b06466,0x1ad74cab,0x550faaf2,0xa7112386,0x6d9bd5f5,0x7435e198,0x59c3463f,0x2dcc7e38,0xca7bd4b2,0xdc7df748,0x9dec2f31,0x13cd4c08 +.long 0xe3237710,0x0d3b5df8,0xcbd2f7b0,0x0dadb26e,0xe4aa082b,0x9f5966ab,0x350e966e,0x666ec8de,0xee524216,0x1bfd1ed5,0x41dab0b6,0xcd93c59b,0xd186d6ba,0x658a8435,0x159d1195,0x1b7d34d2 +.long 0x22caf46b,0x5936e460,0x9a96fe4f,0x6a45dd8f,0xb98f474e,0xf7925434,0x0053ef15,0x41410412,0x41de97bf,0x71cf8d12,0xbd80bef4,0xb8547b61,0xc4db0037,0xb47d3970,0xfef20dff,0xf1bcd328 +.long 0x10caad67,0x31a92e09,0x5531a1e1,0x1f591960,0x5f4fc840,0x3bb852e0,0x93a72c6c,0x63e297ca,0x49abad67,0x3c2b0b2e,0xed3db0d9,0x6ec405fc,0x7fef1d40,0xdc14a530,0x280896fc,0xccd19846 +.long 0x9bb81648,0x00f83176,0x653120d0,0xd69eb485,0x4ccabc62,0xd17d75f4,0xb749fcb1,0x34a07f82,0xbbfb5554,0x2c3af787,0x62e283f8,0xb06ed4d0,0xa19213a0,0x5722889f,0xdcf3c7b4,0x162b085e +.long 0xe0dd3eca,0xbcaecb31,0xe52f13a5,0xc6237fbc,0x27bac297,0xcc2b6b03,0xb917f54a,0x2ae1cac5,0x7845ae4f,0x474807d4,0xce5972e0,0xfec7dd92,0x1d7915bb,0xc3bd2541,0xd94907ca,0x66f85dc4 +.long 0xbdbcf0ca,0xd981b888,0xdf279e9f,0xd75f5da6,0x7054e934,0x128bbf24,0x81db134b,0x3c6ff6e5,0x047d26e4,0x795b7cf4,0x5049ec37,0xf370f7b8,0xced945af,0xc6712d4d,0x095642bc,0xdf30b5ec +.long 0x4896246e,0x9b034c62,0xee90bbd1,0x5652c016,0x87fedb73,0xeb38636f,0x0135a613,0x5e32f847,0xcf933c83,0x0703b312,0x1a7f47e6,0xd05bb76e,0x949c2415,0x825e4f0c,0x7250d6f8,0x569e5622 +.long 0x6568013e,0xbbe9eb3a,0x22f243fc,0x8dbd203f,0xb342734a,0x9dbd7694,0x46afa984,0x8f6d12f8,0xc9eade29,0xb98610a2,0x47dd0f18,0xbab4f323,0x671c0d46,0x5779737b,0xd3e0a42a,0x10b6a7c6 +.long 0x3035b41c,0xfb19ddf3,0x99c45895,0xd336343f,0x54c857e5,0x61fe4938,0xae4e57d5,0xc4d506be,0xbbc33f75,0x3cd8c8cb,0x9262c77d,0x7281f08a,0xf11a2823,0x083f4ea6,0x9fba2e33,0x8895041e +.long 0x9c438edf,0xfcdfea49,0x91edba44,0x7678dcc3,0xe2ba50f0,0xf07b3b87,0x43948c1b,0xc13888ef,0x1140af42,0xc2135ad4,0x926ed1a7,0x8e5104f3,0x88f6695f,0xf24430cb,0x6d73c120,0x0ce0637b +.long 0xfe631e8f,0xb2db01e6,0xd7bdd24b,0x1c5563d7,0x369ad44f,0x8daea3ba,0x8187a9f9,0x000c81b6,0xaae1fd9a,0x5f48a951,0x8d5aed8a,0xe35626c7,0x0498c622,0x20952763,0x773aa504,0x76d17634 +.long 0xeb300f7a,0x36d90dda,0xedb5e801,0x9dcf7dfc,0x74d5244c,0x645cb268,0x348e3aa2,0xa127ee79,0x575f1dbb,0x488acc53,0x80e6161e,0x95037e85,0x292650d0,0x57e59283,0x14938216,0xabe67d99 +.long 0x3f8e1065,0x3c7f944b,0x330e8924,0xed908cb6,0x6f530136,0x08ee8fd5,0xd7ffc169,0x2227b7d5,0xb5cd6dd5,0x4f55c893,0xa62796e8,0x82225e11,0xcb18e12c,0x5c6cead1,0x84f5a51a,0x4381ae0c +.long 0x7fafa4c8,0x345913d3,0x0491aac0,0x3d918082,0x3e69264c,0x9347871f,0xb4f4f0cd,0xbea9dd3c,0x3eadd3e7,0xbda5d067,0x0573bcd8,0x0033c1b8,0x5da2486c,0x25589379,0x86abbee7,0xcb89ee5b +.long 0x22532e5d,0x8fe0a8f3,0x727dfc4c,0xb6410ff0,0x226726db,0x619b9d58,0x7a2b2dc7,0x5ec25669,0x4c3beb01,0xaf4d2e06,0x7acea556,0x852123d0,0xf783487a,0x0e9470fa,0x5664b3eb,0x75a7ea04 +.long 0x6798e4ba,0x4ad78f35,0xc7d0e091,0x9214e6e5,0xb1290403,0xc420b488,0xfc295749,0x64049e0a,0x3ae9841f,0x03ef5af1,0xb0b662a6,0xdbe4ca19,0xfa453458,0x46845c5f,0x10b66722,0xf8dabf19 +.long 0xcce2793b,0xb650f0aa,0xc5ec47c1,0x71db851e,0x3b234fa9,0x3eb78f3e,0xfc0106ce,0xb0c60f35,0x774eadbd,0x05427121,0xce323863,0x25367faf,0xcd086976,0x7541b5c9,0xdc507ad1,0x4ff069e2 +.long 0x8776e667,0x74145256,0xb23c6bb5,0x6e76142c,0x1b3a8a87,0xdbf30712,0x98450836,0x60e7363e,0xb7366d80,0x5741450e,0x4837dbdf,0xe4ee14ca,0x69d4316f,0xa765eb9b,0x8ef43825,0x04548dca +.long 0x5ae888eb,0x9c9f4e4c,0x56e9ac99,0x733abb51,0xba6ac029,0xdaad3c20,0x2ba3e38e,0x9b8dd3d3,0x0bc5d11a,0xa9bb4c92,0x9c5f88a3,0xf20127a7,0x161d3cb8,0x4f52b06e,0x6afaf0a6,0x26c1ff09 +.long 0x7189e71f,0x32670d2f,0x5ecf91e7,0xc6438748,0xdb757a21,0x15758e57,0x290a9ce5,0x427d09f8,0x38384a7a,0x846a308f,0xb0732b99,0xaac3acb4,0x17845819,0x9e941009,0xa7ce5e03,0x95cba111 +.long 0xb00009c4,0x6f3d4f7f,0x8ff28b5f,0xb8396c27,0x1c97975d,0xb1a9ae43,0xe5d9fed5,0x9d7ba8af,0x34f485b6,0x338cf09f,0x64122516,0xbc0ddacc,0x05d471fe,0xa450da12,0x628dd8c9,0x4c3a6250 +.long 0xd1295837,0x69c7d103,0x3807eb2f,0xa2893e50,0xbdb41491,0xd6e1e1de,0x5e138235,0xc630745b,0x48661ae1,0xc892109e,0xea2b2674,0x8d17e7eb,0xc328d6b5,0x00ec0f87,0xf079ff9e,0x6d858645 +.long 0x19115ead,0x6cdf243e,0x4bac4fcf,0x1ce1393e,0x9c29f25b,0x2c960ed0,0x9d388a05,0x59be4d8e,0xd0def72b,0x0d46e06c,0xe0342748,0xb923db5d,0x936d4a3d,0xf7d3aacd,0x0b0b099e,0x558519cc +.long 0x827097ef,0x3ea8ebf8,0xd054f55d,0x259353db,0x6d2ed089,0x84c89abc,0x8e096a7c,0x5c548b69,0x994b995d,0xd587f616,0xa5845601,0x4d1531f6,0x451fd9f0,0x792ab31e,0x65adf6ca,0xc8b57bb2 +.long 0x1cd5ad73,0x68440fcb,0x6144da4f,0xb9c860e6,0x8462beb8,0x2ab286aa,0xef46797f,0xcc6b8fff,0x20c8a471,0xac820da4,0x77ff7faf,0x69ae05a1,0xbfb5da77,0xb9163f39,0x2c73ab7a,0xbd03e590 +.long 0xb2940d9e,0x7e862b5e,0x4b9af564,0x3c663d86,0xbde3033d,0xd8309031,0xd42c5bc6,0x298231b2,0x552ad093,0x42090d2c,0xff854695,0xa4799d1c,0xd31f0d00,0x0a88b5d6,0xa2f26b46,0xf8b40825 +.long 0xf1bd7218,0xec29b1ed,0x4b24c86e,0xd491c53b,0x3395ea65,0xd2fe588f,0x4456ef15,0x6f3764f7,0xcdc34800,0xdb43116d,0xc1e33955,0xcdbcd456,0x74ab286b,0xefdb5540,0xd18c5d7c,0x948c7a51 +.long 0x7378058e,0xeb81aa37,0x04411154,0x41c746a1,0xfb828ac7,0xa10c73bc,0x9d972b29,0x6439be91,0x43a2fbad,0x4bf3b4b0,0x82b5e840,0x39e6dadf,0x6397bd4c,0x4f716408,0x7f1eeccb,0x0f7de568 +.long 0xd2ffbfc1,0x5865c5a1,0x4ccb6451,0xf74211fa,0xc0b32558,0x66368a88,0x9ad7812e,0x5b539dc2,0x2f3af6f6,0x579483d0,0x99934ece,0x52132078,0xdcc9e983,0x50b9650f,0xaee42b8a,0xca989ec9 +.long 0xd6f62f99,0x6a44c829,0x4c2a7c0c,0x8f06a309,0x98a0cb0a,0x4ea2b3a0,0xbeee8364,0x5c547b70,0x682afe11,0x461d40e1,0x7b41c0a8,0x9e0fc77a,0xe20d5d36,0x79e4aefd,0x32dd9f63,0x2916e520 +.long 0x3f883faf,0xf59e52e8,0x2b868d35,0x396f9639,0x4ca19881,0xc902a9df,0xdb2401a6,0x0fc96822,0x66f1c68d,0x41237587,0xfb476c0d,0x10fc6de3,0x841f5d90,0xf8b6b579,0xfa24f44a,0x2ba8446c +.long 0xef4a9975,0xa237b920,0x2330435f,0x60bb6004,0xcfb7e7b5,0xd6f4ab5a,0x83435391,0xb2ac5097,0xb0d1ea67,0xf036ee2f,0x74c56230,0xae779a6a,0xab838ae6,0x59bff8c8,0x9b38e6f0,0xcd83ca99 +.long 0xe33deed3,0xbb27bef5,0x001892a8,0xe6356f6f,0x7adfbd3e,0xbf3be6cc,0x33d1ac9d,0xaecbc81c,0xe6e861dc,0xe4feb909,0x53f5f801,0x90a247a4,0x27346e57,0x01c50acb,0x461acc1b,0xce29242e +.long 0x2f998a91,0x04dd214a,0xd4baf27b,0x271ee9b1,0xe8c26722,0x7e3027d1,0x1820dce5,0x21d1645c,0x7501779c,0x086f242c,0xfa0e8009,0xf0061407,0x60187129,0xf23ce477,0x0fde9bd0,0x05bbdedb +.long 0x25d98473,0x682f4832,0x5c658427,0xf207fe85,0x4166ffa1,0xb6fdd7ba,0x9eed799d,0x0c314056,0x4107e28f,0x0db8048f,0x41216840,0x74ed3871,0x56a3c06e,0x74489f8f,0x12777134,0x1e1c005b +.long 0xf37ec3c3,0xdb332a73,0xdd59eba0,0xc65259bd,0xdb4d3257,0x2291709c,0xbd389390,0x9a793b25,0xe43756f0,0xf39fe34b,0x9afb56c9,0x2f76bdce,0x61208b27,0x9f37867a,0x089972c3,0xea1d4307 +.long 0x8bdf623a,0x8c595330,0x8441fb7d,0x5f5accda,0x32ddfd95,0xfafa9418,0x0fde9be7,0x6ad40c5a,0xaeca8709,0x43faba89,0x2c248a9d,0xc64a7cf1,0x72637a76,0x16620252,0x22b8d1bb,0xaee1c791 +.long 0x21a843b2,0xf0f798fd,0x8d005cb1,0x56e4ed4d,0x1f0d8abe,0x355f7780,0x34522326,0x197b04cf,0xfd42c13f,0x41f9b31f,0xb40f933d,0x5ef7feb2,0x5d60bad4,0x27326f42,0x8c92cf89,0x027ecdb2 +.long 0x4e3352fe,0x04aae4d1,0x73591b90,0x08414d2f,0xb7da7d60,0x5ed6124e,0x4d13d4ec,0xb985b931,0x96bf36f9,0xa592d3ab,0xbbdf51df,0x012dbed5,0xdf6c177d,0xa57963c0,0x87ca29cf,0x010ec869 +.long 0xbf926dff,0xba1700f6,0xf4bf6bc2,0x7c9fdbd1,0x64da11f5,0xdc18dc8f,0xd938ae75,0xa6074b7a,0xe84f44a4,0x14270066,0xd27b954e,0x99998d38,0xb4f38e9a,0xc1be8ab2,0x15c01016,0x8bb55bbf +.long 0x0ea2ab30,0xf73472b4,0xf73d68dd,0xd365a340,0x19c2e1eb,0xc01a7168,0x34061719,0x32f49e37,0x01d8b4d6,0xb73c57f1,0x26b47700,0x03c8423c,0xa4d8826a,0x321d0bc8,0x4bc0e638,0x6004213c +.long 0xc1c06681,0xf78c64a1,0xef018e50,0x16e0a16f,0xdb42b2b3,0x31cbdf91,0xe0d36f58,0xf8f4ffce,0x4cc5e3e0,0xcdcc71cd,0xa129e3e0,0xd55c7cfa,0x0fb2cbf1,0xccdb6ba0,0xc4bce3cb,0x6aba0005 +.long 0xd232cfc4,0x501cdb30,0xd58a3cef,0x9ddcf12e,0x87e09149,0x02d2cf9c,0x2c976257,0xdc5d7ec7,0x0b50d7dd,0x6447986e,0x807f112a,0x88fdbaf7,0xb00ae9f6,0x58c9822a,0x6d3d27e0,0x6abfb950 +.long 0x8a429f4f,0xd0a74487,0xdb516609,0x0649712b,0xe769b5df,0xb826ba57,0x1fc7aaf2,0x82335df2,0x5c93d995,0x2389f067,0x68677be6,0x59ac367a,0x21d9951b,0xa77985ff,0x85011cce,0x038956fb +.long 0xbb734e37,0x608e48cb,0x2be5b26f,0xc08c0bf2,0xf9b1a0d9,0x17bbdd3b,0x10483319,0xeac7d898,0xbc1a6dea,0xc95c4baf,0x172aafdb,0xfdd0e2bf,0x8235c41a,0x40373cbc,0xfb6f41d5,0x14303f21 +.long 0x0408f237,0xba063621,0xecd2d1ed,0xcad3b09a,0x52abb6a2,0x4667855a,0xaa8b417b,0xba9157dc,0x4f013efb,0xfe7f3507,0xaa38c4a2,0x1b112c4b,0x9ba64345,0xa1406a60,0x6993c80b,0xe53cba33 +.long 0xded40d23,0x45466063,0x54908e25,0x3d5f1f4d,0x403c3c31,0x9ebefe62,0x0672a624,0x274ea0b5,0x451d1b71,0xff818d99,0x8f79cf79,0x80e82643,0x73ce37f5,0xa165df13,0xfe3a21fd,0xa744ef4f +.long 0xcf551396,0x73f1e7f5,0x868c676b,0xc616898e,0x8c442c36,0x671c28c7,0x5e0a317d,0xcfe5e558,0x7051f476,0x1242d818,0x14f03442,0x56fad2a6,0x0a44d0f6,0x262068bc,0xce6edf4e,0xdfa2cd6e +.long 0xd15d1517,0x0f43813a,0x377d44f5,0x61214cb2,0xc639b35f,0xd399aa29,0x54c51c19,0x42136d71,0x08417221,0x9774711b,0x52545a57,0x0a5546b3,0x1150582d,0x80624c41,0xfbc555bc,0x9ec5c418 +.long 0x771849f1,0x2c87dcad,0x01d7bf6f,0xb0c932c5,0x89116eb2,0x6aa5cd3e,0x51ca7bd3,0xd378c25a,0x9e6e3e31,0xc612a0da,0xb68ad5d0,0x0417a54d,0x22c6edb8,0x00451e4a,0xb42827ce,0x9fbfe019 +.long 0xba9384a2,0x2fa92505,0x64ad69c1,0x21b8596e,0x983b35a6,0x8f4fcc49,0x72754672,0xde093760,0xf7bffe6d,0x2f14ccc8,0x5d94263d,0x27566bff,0x2df3ec30,0xb5b4e9c6,0x3e6ea6ba,0x94f1d7d5 +.long 0xaaca5e9b,0x97b7851a,0x56713b97,0x518aa521,0x150a61f6,0x3357e8c7,0xec2c2b69,0x7842e7e2,0x6868a548,0x8dffaf65,0xe068fc81,0xd963bd82,0x65917733,0x64da5c8b,0x7b247328,0x927090ff +.long 0xd298c241,0x214bc9a7,0x56807cfd,0xe3b697ba,0x4564eadb,0xef1c7802,0xb48149c5,0xdde8cdcf,0x5a4d2604,0x946bf0a7,0x6c1538af,0x27154d7f,0xde5b1fcc,0x95cc9230,0x66864f82,0xd88519e9 +.long 0x7cb1282c,0xb828dd1a,0xbe46973a,0xa08d7626,0xe708d6b2,0x6baf8d40,0x4daeb3f3,0x72571fa1,0xf22dfd98,0x85b1732f,0x0087108d,0x87ab01a7,0x5988207a,0xaaaafea8,0x69f00755,0xccc832f8 +.long 0x36ff3bf0,0x964d950e,0xf0b34638,0x8ad20f6f,0xb5d7585f,0x4d9177b3,0xef3f019f,0xcf839760,0x8288c545,0x582fc5b3,0x13116bd1,0x2f8e4e9b,0x332120ef,0xf91e1b2f,0x2a17dd23,0xcf568724 +.long 0xca8d9d1a,0x488f1185,0xd987ded2,0xadf2c77d,0x60c46124,0x5f3039f0,0x71e095f4,0xe5d70b75,0x6260e70f,0x82d58650,0xf750d105,0x39d75ea7,0x75bac364,0x8cf3d0b1,0x21d01329,0xf3a7564d +.long 0x2f52d2a7,0x182f04cd,0xe2df565a,0x4fde149a,0xa79fb2f7,0xb80c5eec,0x22ddc897,0xab491d7b,0xc6312c7f,0x99d76c18,0x6aa41a57,0xca0d5f3d,0xd15363a0,0x71207325,0xbeb252c2,0xe82aa265 +.long 0xec3128c2,0x94ab4700,0x8e383f49,0x6c76d862,0xc03024eb,0xdc36b150,0x53daac69,0xfb439477,0x8dc79623,0xfc68764a,0xb440fbb2,0x5b86995d,0xccc5ee0d,0xd66879bf,0x95aa8bd3,0x05228942 +.long 0x1e6a75c1,0xb51a40a5,0x0ea7d817,0x24327c76,0x07774597,0x06630182,0x97fa7164,0xd6fdbec3,0x13c90f48,0x20c99dfb,0x686ef263,0xd6ac5273,0xfef64eeb,0xc6a50bdc,0x86fdfc32,0xcd87b281 +.long 0x3fcd3efc,0xb24aa43e,0xb8088e9a,0xdd26c034,0xbd3d46ea,0xa5ef4dc9,0x8a4c6a6f,0xa2f99d58,0x2f1da46c,0xddabd355,0x1afacdd1,0x72c3f8ce,0x92d40578,0xd90c4eee,0xca623b94,0xd28bb41f +.long 0x745edc11,0x50fc0711,0x3dc87558,0x9dd9ad7d,0xb49d1e64,0xce6931fb,0xc98bd0f9,0x6c77a0a2,0x6baf7cb1,0x62b9a629,0xccf72d22,0xcf065f91,0x79639071,0x7203cce9,0xf9cb732f,0x09ae4885 +.long 0xee8314f3,0x5e7c3bec,0xdbea298f,0x1c068aed,0x7c80acec,0x08d381f1,0xe330495b,0x03b56be8,0x9222882d,0xaeffb8f2,0xc4af8bf7,0x95ff38f6,0x1fc57d8c,0x50e32d35,0x17b444f0,0x6635be52 +.long 0xa5177900,0x04d15276,0xf6858752,0x4e1dbb47,0xc615796c,0x5b475622,0x691867bf,0xa6fa0387,0x2844c6d0,0xed7f5d56,0x03a2477d,0xc633cf9b,0x2d3721d6,0xf6be5c40,0xe9fd68e6,0xaf312eb7 +.long 0xe7417ce1,0x242792d2,0x970ee7f5,0xff42bc71,0x5c67a41e,0x1ff4dc6d,0x20882a58,0x77709b7b,0xbe217f2c,0x3554731d,0x5bb72177,0x2af2a8cd,0x591dd059,0x58eee769,0x4bba6477,0xbb2930c9 +.long 0x7d930cfc,0x863ee047,0x396fd1f4,0x4c262ad1,0x039af7e1,0xf4765bc8,0x5ba104f6,0x2519834b,0xd105f961,0x7cd61b4c,0xd63bca54,0xa5415da5,0x88a1f17c,0x778280a0,0x2329512c,0xc4968949 +.long 0xcecdaa7a,0x174a9126,0x0b13247b,0xfc8c7e0e,0x3484c1c4,0x29c110d2,0x831dfc3b,0xf8eb8757,0xc0067452,0x022f0212,0x7b9b926c,0x3f6f69ee,0xef42daf4,0x09032da0,0x83f80de4,0x79f00ade +.long 0x81236c97,0x6210db71,0x3ee0781f,0x74f7685b,0xa3e41372,0x4df7da7b,0xb1a1553e,0x2aae38b1,0xf6dd9d1b,0x1688e222,0x5b8b6487,0x57695448,0x4b2edeaa,0x478d2127,0x1e85956a,0xb2818fa5 +.long 0xf176f2c0,0x1e6addda,0xe2572658,0x01ca4604,0x85342ffb,0x0a404ded,0x441838d6,0x8cf60f96,0xc9071c4a,0x9bbc691c,0x34442803,0xfd588744,0x809c0d81,0x97101c85,0x8c456f7f,0xa7fb754c +.long 0xd51805e1,0xc95f3c5c,0xb299dca8,0xab4ccd39,0x47eaf500,0x3e03d20b,0xd7b80893,0xfa3165c1,0xe160e552,0x005e8b54,0x9019d11f,0xdc4972ba,0x0c9a4a7a,0x21a6972e,0x37840fd7,0xa52c258f +.long 0xc1e99d81,0xf8559ff4,0xa3c617c0,0x08e1a7d6,0x248c6ba7,0xb398fd43,0xd1283794,0x6ffedd91,0xd629d208,0x8a6a59d2,0x3490530e,0xa9d141d5,0x38505989,0x42f6fc18,0x479d94ee,0x09bf250d +.long 0xb3822790,0x223ad3b1,0x93b8971c,0x6c5926c0,0x75f7fa62,0x609efc7e,0x1ec2d989,0x45d66a6d,0x987d2792,0x4422d663,0x3eb31d2b,0x4a73caad,0xa32cb9e6,0xf06c2ac1,0x91aeba84,0xd9445c5f +.long 0xaf71013f,0x6af7a1d5,0x0bedc946,0xe68216e5,0xd27370a0,0xf4cba30b,0x870421cc,0x7981afbf,0x9449f0e1,0x02496a67,0x0a47edae,0x86cfc4be,0xb1feca22,0x3073c936,0x03f8f8fb,0xf5694612 +.long 0x901515ea,0xd063b723,0x749cf038,0x4c6c77a5,0xab9e5059,0x6361e360,0xa76a37c0,0x596cf171,0x6530ae7a,0x800f53fa,0x0792a7a6,0x0f5e631e,0xefdb81c9,0x5cc29c24,0x3f9c40ba,0xa269e868 +.long 0x2cb7191e,0xec14f9e1,0xe5b08ea6,0x78ea1bd8,0x46332bb9,0x3c65aa9b,0xbf80ce25,0x84cc22b3,0xd49d5bf1,0x0098e9e9,0x19087da4,0xcd4ec1c6,0xaef6e357,0x3c9d07c5,0x9f8f64b8,0x839a0268 +.long 0xc6d8607f,0xc5e9eb62,0x6aa995e4,0x759689f5,0xbbb48317,0x70464669,0xe402417d,0x921474bf,0x2a354c8c,0xcabe135b,0x812fa4b5,0xd51e52d2,0x53311fe8,0xec741096,0xb864514b,0x4f774535 +.long 0x5bde48f8,0xbcadd671,0x2189bc7d,0xc9703873,0xc709ee8a,0x5d45299e,0x845aaff8,0xd1287ee2,0xdb1dbf1f,0x7d1f8874,0x990c88d6,0xea46588b,0x84368313,0x60ba649a,0x60d543ae,0xd5fdcbce +.long 0x810d5ab0,0x90b46d43,0x04d7e5cc,0x6739d8f9,0x0d337c33,0x021c1a58,0x68e67c40,0x00a61162,0x379f0a1f,0x95ef413b,0xe9e2ab95,0xfe126605,0x2f5f199c,0x67578b85,0x2cb84913,0xf5c00329 +.long 0x37577dd8,0xf7956430,0x29c5fe88,0x83b82af4,0xcdbdc132,0x9c1bea26,0x9c04339e,0x589fa086,0xb13799df,0x033e9538,0xd295d034,0x85fa8b21,0xbd9ddcca,0xdf17f73f,0xddb66334,0xf32bd122 +.long 0x858b044c,0x55ef88a7,0x5aa9e397,0x1f0d69c2,0x40d85559,0x55fd9cc3,0x7785ddb2,0xc774df72,0xd3bd2e1c,0x5dcce9f6,0xa85dfed0,0xeb30da20,0xd3ed09c4,0x5ed7f5bb,0x82a9c1bd,0x7d42a35c +.long 0x9890272d,0xcf3de995,0x3e713a10,0x75f3432a,0xe28227b8,0x5e13479f,0xfefacdc8,0xb8561ea9,0x8332aafd,0xa6a297a0,0x73809b62,0x9b0d8bb5,0x0c63036f,0xd2fa1cfd,0xbd64bda8,0x7a16eb55 +.long 0x78e62ddc,0x3f5cf5f6,0x07fd752b,0x2267c454,0x5e437bbe,0x5e361b6b,0x8354e075,0x95c59501,0xf2b254d9,0xec725f85,0x2cb52b4e,0x844b617d,0xcf425fb5,0xed8554f5,0x2af9f312,0xab67703e +.long 0x3cf48283,0x4cc34ec1,0x9c8a705e,0xb09daa25,0x5b7d4f84,0xd1e9d0d0,0xdb38929d,0x4df6ef64,0xaa21ba46,0xe16b0763,0xa293f8fb,0xc6b1d178,0xd520aabf,0x0ff5b602,0xc339397a,0x94d671bd +.long 0x4f5792fa,0x7c7d98cf,0x11215261,0x7c5e0d67,0xa7c5a6d4,0x9b19a631,0x7a45274d,0xc8511a62,0xa5a60d99,0x0c16621c,0xcf5e48cb,0xf7fbab88,0xf7ddee08,0xab1e6ca2,0xe7867f3c,0x83bd08ce +.long 0x2ac13e27,0xf7e48e8a,0x4eb1a9f5,0x4494f6df,0x981f0a62,0xedbf84eb,0x536438f0,0x49badc32,0x004f7571,0x50bea541,0xdf1c94ee,0xbac67d10,0xb727bc31,0x253d73a1,0x30686e28,0xb3d01cf2 +.long 0x55fd0b8b,0x51b77b1b,0xfeec3173,0xa099d183,0x670e72b7,0x202b1fb7,0xa8e1635f,0xadc88b33,0xf989d905,0x34e8216a,0x29b58d01,0xc2e68d20,0x6fe55a93,0x11f81c92,0x8f296f40,0x15f1462a +.long 0xea3d62f2,0x1915d375,0x01c8977d,0xa17765a3,0xe47b26f6,0x7559710a,0x535077a5,0xe0bd29c8,0x08d84858,0x615f976d,0x69ced5c1,0x370dfe85,0xa734fa56,0xbbc7503c,0x91ac4574,0xfbb9f1ec +.long 0x060dd7ef,0x95d7ec53,0x6e657979,0xeef2dacd,0xe2a08235,0x54511af3,0x1f4aea3d,0x1e324aa4,0xe6e67671,0x550e7e71,0xbf52faf7,0xbccd5190,0x223cc62a,0xf880d316,0x2b32eb5d,0x0d402c7e +.long 0x306a5a3b,0xa40bc039,0x96783a1b,0x4e0a41fd,0x0253cdd4,0xa1e8d39a,0xc7388638,0x6480be26,0x2285f382,0xee365e1d,0xec0b5c36,0x188d8d8f,0x1f0f4d82,0x34ef1a48,0xa487d29a,0x1a8f43e1 +.long 0x77aefb3a,0x8168226d,0x1e72c253,0xf69a751e,0xe9594df1,0x8e04359a,0xd14c0467,0x475ffd7d,0x3844e95c,0xb5a2c2b1,0xdd12ef94,0x85caf647,0xf1063d00,0x1ecd2a9f,0x23843311,0x1dd2e229 +.long 0x73d17244,0x38f0e09d,0x8fc653f1,0x3ede7746,0xdc20e21c,0xae4459f5,0x6a8599ea,0x00db2ffa,0x30cfd905,0x11682c39,0xa5c112a6,0x4934d074,0x568bfe95,0xbdf063c5,0x016c441a,0x779a440a +.long 0x97d6fbdc,0x0c23f218,0xe0776aac,0xd3a5cd87,0xd712e8db,0xcee37f72,0x26f74e8d,0xfb28c70d,0xb61301a0,0xffe0c728,0xd3724354,0xa6282168,0x768ffedc,0x7ff4cb00,0x03b02de9,0xc51b3088 +.long 0x3902dda5,0xa5a8147c,0xfe6973b4,0x35d2f706,0xc257457e,0x5ac2efcf,0x8700611b,0x933f48d4,0x4912beb2,0xc365af88,0x162edf94,0x7f5a4de6,0x0c32f34b,0xc646ba7c,0xb2091074,0x632c6af3 +.long 0x753e43a9,0x58d4f2e3,0x24d4e23f,0x70e1d217,0xafede6a6,0xb24bf729,0x710c8b60,0x7f4a94d8,0x8d4faa6a,0xaad90a96,0xb066b690,0xd9ed0b32,0x78b6dbfd,0x52fcd37b,0x8bd2b431,0x0b64615e +.long 0xcfb9fad5,0x228e2048,0x240b76bd,0xbeaa386d,0x90dad7bc,0x2d6681c8,0x06d38f5e,0x3e553fc3,0x9d5f9750,0xf27cdb9b,0xd28c5b0e,0x3e85c52a,0x5247c39b,0x190795af,0xbddd6828,0x547831eb +.long 0x4a82f424,0xf327a227,0x7e47f89d,0x36919c78,0x43c7392c,0xe4783919,0x2316fefe,0xf101b9aa,0x1c5009d2,0xbcdc9e9c,0x9cd18345,0xfb55ea13,0xa3ce77c7,0xf5b5e231,0xd2f2cb3d,0xde6b4527 +.long 0x9bb26f5f,0x10f6a333,0x044d85b6,0x1e85db8e,0x94197e54,0xc3697a08,0xa7cb4ea8,0x65e18cc0,0xa471fe6e,0xa38c4f50,0x2f13439c,0xf031747a,0xc007318b,0x53c4a6ba,0x1deccb3d,0xa8da3ee5 +.long 0x558216b1,0x0555b31c,0x2f79e6c2,0x90c7810c,0xfe8eed3c,0x9b669f4d,0xe0fac126,0x70398ec8,0xf701b235,0xa96a449e,0xeb94f395,0x0ceecdb3,0xd0cb7431,0x285fc368,0x16a18c64,0x0d37bb52 +.long 0xb880d2dd,0x05110d38,0x65930d57,0xa60f177b,0xf36235f5,0x7da34a67,0x183816b9,0x47f5e17c,0xdb394af4,0xc7664b57,0x7036f789,0x39ba215d,0x2f27b472,0x46d2ca0e,0xf73a84b7,0xc42647ee +.long 0x64488f1d,0x44bc7545,0xf4cf85d5,0xaa922708,0x53e4df63,0x721a01d5,0x5db46ced,0x649c0c51,0x3cffcb6c,0x6bf0d64e,0x50f71d96,0xe3bf93fe,0xbcc194a0,0x75044558,0x6afdc554,0x16ae3372 +.long 0x5ca48f3f,0xbfc01adf,0xe22a9b84,0x64352f06,0xc1099e4a,0xcee54da1,0xfa1b89c0,0xbbda54e8,0x6f6e55fb,0x166a3df5,0x20176f88,0x1ca44a24,0xdfb7b5ff,0x936afd88,0x8611d4a0,0xe34c2437 +.long 0x86142103,0x7effbb75,0x1f34fc4d,0x6704ba1b,0x10c1b122,0x7c2a468f,0x8c6aace9,0x36b3a610,0x75a0d050,0xabfcc0a7,0x3ce33e32,0x066f9197,0x29fe09be,0xce905ef4,0xa8376351,0x89ee25ba +.long 0xfd29dc76,0x2a3ede22,0x36f17260,0x7fd32ed9,0x284b4126,0x0cadcf68,0xa7951fc8,0x63422f08,0x0807e199,0x562b24f4,0x22ad4490,0xfe9ce5d1,0x0db2b1b4,0xc2f51b10,0xe4541d0d,0xeb3613ff +.long 0x2680813b,0xbd2c4a05,0x561b08d6,0x527aa55d,0xa7205558,0xa9f8a40e,0x243d0bec,0xe3eea56f,0xa0ff58b3,0x7b853817,0x1a69e627,0xb67d3f65,0xa869b5d6,0x0b76bbb9,0x546723ed,0xa3afeb82 +.long 0x3e554892,0x5f24416d,0x430e2a45,0x8413b53d,0x9032a2a0,0x99c56aee,0xeec367b1,0x09432bf6,0xdaf0ecc1,0x552850c6,0x5bc92048,0x49ebce55,0x54811307,0xdfb66ba6,0x6f298597,0x1b84f797 +.long 0x8d1d7a0d,0x79590481,0x3a6fa556,0xd9fabe03,0xba9e5d35,0xa40f9c59,0xf6247577,0xcb1771c1,0xe9a6312b,0x542a47ca,0x552dd8c5,0xa34b3560,0x0d794716,0xfdf94de0,0x9c623094,0xd46124a9 +.long 0x68afe8b4,0x56b7435d,0x6c0d8ea1,0x27f20540,0x73186898,0x12b77e14,0x7479490f,0xdbc3dd46,0xc03b0c05,0x951a9842,0x7921bc96,0x8b1b3bb3,0x2b202e0a,0xa573b346,0x47254d56,0x77e4665d +.long 0xd23e3984,0x08b70dfc,0xebd14236,0xab86e8bc,0x57114ba7,0xaa3e07f8,0xab0ef4f2,0x5ac71689,0x0139d9af,0x88fca384,0x76644af0,0x72733f88,0x65d74f4a,0xf122f72a,0xa5626c7a,0x13931577 +.long 0x70f8d5a4,0xd5b5d9eb,0xd7bbb228,0x375adde7,0x0c1c0b32,0x31e88b86,0x173edbaa,0xd1f568c4,0x5459df02,0x1592fc83,0x0fcd9a7e,0x2beac0fb,0x1b473b0a,0xb0a6fdb8,0x0fe8fc48,0xe3224c6f +.long 0xe87edf5b,0x680bd00e,0x20e77cf5,0x30385f02,0x4d42d1b2,0xe9ab98c0,0xd3816d77,0x72d191d2,0x0917d9e5,0x1564daca,0x1f8fed7f,0x394eab59,0x7fbb3896,0xa209aa8d,0xbe6ac98e,0x5564f3b9 +.long 0xd73654ef,0xead21d05,0x13d78d74,0x68d1a9c4,0x6d4973a0,0x61e01708,0x46e6d32a,0x83da3500,0x68ae0118,0x6a3dfca4,0xd02da069,0xa1b9a4c9,0xebab8302,0x0b2ff9c7,0x944ba436,0x98af07c3 +.long 0x995f0f9f,0x85997326,0x71b58bc6,0x467fade0,0xbd625a2b,0x47e4495a,0x33c3b8cd,0xfdd2d01d,0xc693f9fa,0x2c38ae28,0x348f7999,0x48622329,0x2161f583,0x97bf738e,0x565e8cc9,0x15ee2fa7 +.long 0x5777e189,0xa1a5c845,0x456f2829,0xcc10bee0,0xda762bd5,0x8ad95c56,0xe9d91da8,0x152e2214,0x7cb23c74,0x975b0e72,0xa90c66df,0xfd5d7670,0x225ffc53,0xb5b5b8ad,0xfaded2ae,0xab6dff73 +.long 0x6f4cbe9d,0xebd56781,0x6a574bd7,0x0ed8b249,0x81a881fa,0x41c246fe,0xc3db9c70,0x91564805,0x5b862809,0xd7c12b08,0x55858d7b,0x1facd1f1,0xaf09e92a,0x7693747c,0x189a425f,0x3b69dcba +.long 0x967365ef,0x0be28e9f,0xe801f5c9,0x57300eb2,0xd583352f,0x93b8ac6a,0xcd05b2b7,0xa2cf1f89,0x4dcc40cc,0x7c0c9b74,0xada523fb,0xfee38c45,0x1099cc4d,0xb49a4dec,0x69f069c6,0x325c377f +.long 0x476cc9ff,0xe12458ce,0xc6d4cb63,0x580e0b6c,0x9072289b,0xd561c8b7,0xa619e6da,0x0377f264,0x88e591a5,0x26685362,0x7523ca2b,0xa453a7bd,0xc1df4533,0x8a9536d2,0xbe972f79,0xc8e50f2f +.long 0x6d3549cf,0xd433e50f,0xfacd665e,0x6f33696f,0xce11fcb4,0x695bfdac,0xaf7c9860,0x810ee252,0x7159bb2c,0x65450fe1,0x758b357b,0xf7dfbebe,0xd69fea72,0x2b057e74,0x92731745,0xd485717a +.long 0xee36860c,0x896c42e8,0x4113c22d,0xdaf04dfd,0x44104213,0x1adbb7b7,0x1fd394ea,0xe5fd5fa1,0x1a4e0551,0x68235d94,0x18d10151,0x6772cfbe,0x09984523,0x276071e3,0x5a56ba98,0xe4e879de +.long 0x285b9491,0xaaafafb0,0x1e4c705e,0x01a0be88,0x2ad9caab,0xff1d4f5d,0xc37a233f,0x6e349a4a,0x4a1c6a16,0xcf1c1246,0x29383260,0xd99e6b66,0x5f6d5471,0xea3d4366,0xff8cc89b,0x36974d04 +.long 0xcfe89d80,0xc26c49a1,0xda9c8371,0xb42c026d,0xdad066d2,0xca6c013a,0x56a4f3ee,0xfb8f7228,0xd850935b,0x08b579ec,0xd631e1b3,0x34c1a74c,0xac198534,0xcb5fe596,0xe1f24f25,0x39ff21f6 +.long 0x8f929057,0x27f29e14,0xc0c853df,0x7a64ae06,0x58e9c5ce,0x256cd183,0xded092a5,0x9d9cce82,0x6e93b7c7,0xcc6e5979,0x31bb9e27,0xe1e47092,0xaa9e29a0,0xb70b3083,0x3785e644,0xbf181a75 +.long 0x8ead09f7,0xf53f2c65,0x9780d14d,0x1335e1d5,0xcd1b66bc,0x69cc20e0,0xbbe0bfc8,0x9b670a37,0x28efbeed,0xce53dc81,0x8326a6e5,0x0c74e77c,0xb88e9a63,0x3604e0d2,0x13dc2248,0xbab38fca +.long 0x5c0a3f1e,0x8ed6e8c8,0x7c87c37f,0xbcad2492,0x9ee3b78d,0xfdfb62bb,0xcbceba46,0xeba8e477,0xeeaede4b,0x37d38cb0,0x7976deb6,0x0bc498e8,0x6b6147fb,0xb2944c04,0xf71f9609,0x8b123f35 +.long 0xde79dc24,0xa155dcc7,0x558f69cd,0xf1168a32,0x0d1850df,0xbac21595,0xb204c848,0x15c8295b,0x7d8184ff,0xf661aa36,0x30447bdb,0xc396228e,0xbde4a59e,0x11cd5143,0x6beab5e6,0xe3a26e3b +.long 0x1402b9d0,0xd3b3a13f,0x2c7bc863,0x573441c3,0x578c3e6e,0x4b301ec4,0x0adaf57e,0xc26fc9c4,0x7493cea3,0x96e71bfd,0x1af81456,0xd05d4b3f,0x6a8c608f,0xdaca2a8a,0x0725b276,0x53ef07f6 +.long 0x7824fc56,0x07a5fbd2,0x13289077,0x34675218,0xe0c48349,0x5bf69fd5,0xb6aa7875,0xa613ddd3,0x5450d866,0x7f78c19c,0x8f84a481,0x46f4409c,0x90fce239,0x9f1d1928,0xb2ce44b9,0x016c4168 +.long 0xc7435978,0xbae023f0,0x20e30e19,0xb152c888,0xe3fa6faf,0x9c241645,0x84823e60,0x735d95c1,0x03955317,0x03197573,0xf03b4995,0x0b4b02a9,0x70274600,0x076bf559,0xaaf57508,0x32c5cc53 +.long 0x60624129,0xe8af6d1f,0x9a5e2b5e,0xb7bc5d64,0x5f082d72,0x3814b048,0xce19677a,0x76f267f2,0xb36eed93,0x626c630f,0x3bf56803,0x55230cd7,0xce2736a0,0x78837949,0xaa6c55f1,0x0d792d60 +.long 0xd5c7c5d2,0x0318dbfd,0x072b342d,0xb38f8da7,0x7b8de38a,0x3569bddc,0xa1c94842,0xf25b5887,0x2946ad60,0xb2d5b284,0xe9d1707e,0x854f29ad,0x2c6a4509,0xaa5159dc,0x57189837,0x899f94c0 +.long 0xf4a55b03,0xcf6adc51,0x35e3b2d5,0x261762de,0x04827b51,0x4cc43012,0xc6021442,0xcd22a113,0x247c9569,0xce2fd61a,0xd152beca,0x59a50973,0x63a716d4,0x6c835a11,0x187dedcf,0xc26455ed +.long 0x49ce89e7,0x27f536e0,0xcc890cb5,0x18908539,0xd83c2aa1,0x308909ab,0x1ab73bd3,0xecd3142b,0xb3f5ab84,0x6a85bf59,0xf2bea4c6,0x3c320a68,0x6da4541f,0xad8dc538,0xb7c41186,0xeaf34eb0 +.long 0x977c97c4,0x1c780129,0xc57eb9fa,0x5ff9beeb,0xc822c478,0xa24d0524,0x461cd415,0xfd8eec2a,0xf027458c,0xfbde194e,0x1d1be115,0xb4ff5319,0x4866d6f4,0x63f874d9,0xb21ad0c9,0x35c75015 +.long 0x46ac49d2,0xa6b5c9d6,0x83137aa9,0x42c77c0b,0x68225a38,0x24d000fc,0x2fe1e907,0x0f63cfc8,0xc6441f95,0x22d1b01b,0xec8e448f,0x7d38f719,0x787fb1ba,0x9b33fa5f,0x190158df,0x94dcfda1 +.long 0x5f6d4a09,0xc47cb339,0xee52b826,0x6b4f355c,0xf51b930a,0x3d100f5d,0x9f668f69,0xf4512fac,0x206c4c74,0x546781d5,0xcb4d2e48,0xd021d4d4,0xca085c2d,0x494a54c2,0x520850a8,0xf1dbaca4 +.long 0x490a1aca,0x63c79326,0x41526b02,0xcb64dd9c,0xa2979258,0xbb772591,0x48d97846,0x3f582970,0x7c213ba7,0xd66b70d1,0xe8a0ced4,0xc28febb5,0xc10338c1,0x6b911831,0xbf0126f3,0x0d54e389 +.long 0x4af206ee,0x7048d460,0x77e97cb9,0x786c88f6,0xac64802e,0xd4375ae1,0xd53ec11c,0x469bcfe1,0x47062230,0xfc9b340d,0xc5b4a3ac,0xe743bb57,0x59ef45ac,0xfe00b4aa,0x59edf188,0x29a4ef23 +.long 0xb483689b,0x40242efe,0x513ac262,0x2575d3f6,0x0ca6db72,0xf30037c8,0x98864be2,0xc9fcce82,0x0149362d,0x84a112ff,0x1c4ae971,0x95e57582,0x945cf86c,0x1fa4b1a8,0x0b024a2f,0x4525a734 +.long 0x8f338360,0xe76c8b62,0x28edf32b,0x483ff593,0x298b1aec,0x67e8e90a,0x736d9a21,0x9caab338,0x66892709,0x5c09d2fd,0xb55a1d41,0x2496b4dc,0xe24a4394,0x93f5fb1a,0x6fa8f6c1,0x08c75049 +.long 0xc905d85f,0xcaead1c2,0x0733ae57,0xe9d7f790,0xf07cdd94,0x24c9a65c,0xa4b55931,0x7389359c,0x367e45f7,0xf58709b7,0xcb7e7adc,0x1f203067,0xc7b72818,0x82444bff,0xbaac8033,0x07303b35 +.long 0xd13b7ea1,0x1e1ee4e4,0xe0e74180,0xe6489b24,0x7e70ef70,0xa5f2c610,0xbdd10894,0xa1655412,0x7af4194e,0x555ebefb,0x8e89bd9c,0x533c1c3c,0x89895856,0x735b9b57,0x567f5c15,0x15fb3cd2 +.long 0x526f09fd,0x057fed45,0x8128240a,0xe8a4f10c,0xff2bfd8d,0x9332efc4,0xbd35aa31,0x214e77a0,0x14faa40e,0x32896d73,0x01e5f186,0x767867ec,0x17a1813e,0xc9adf8f1,0x54741795,0xcb6cda78 +.long 0x349d51aa,0xb7521b6d,0xe3c7b8e9,0xf56b5a9e,0x32a096df,0xc6f1e5c9,0xa3635024,0x083667c4,0x18087f2f,0x365ea135,0xd136e45d,0xf1b8eaac,0x73aec989,0xc8a0e484,0x142c9259,0xd75a324b +.long 0x01dae185,0xb7b4d001,0x9b7a94bc,0x45434e0b,0xfbd8cb0b,0xf54339af,0xe98ef49e,0xdcc4569e,0x09a51299,0x7789318a,0xb2b025d8,0x81b4d206,0xfae85792,0xf64aa418,0xacd7baf7,0x3e50258f +.long 0x2996864b,0xdce84cdb,0x1f485fa4,0xa2e67089,0x534c6a5a,0xb28b2bb6,0xc94b9d39,0x31a7ec6b,0xd6bc20da,0x1d217766,0x86761190,0x4acdb5ec,0x73701063,0x68726328,0x2128c29b,0x4d24ee7c +.long 0xa19fd868,0xc072ebd3,0xdb8ddd3b,0x612e481c,0x1a64d852,0xb4e1d754,0xc4c6c4ab,0x00ef95ac,0xaa0a6c46,0x1536d2ed,0x43774790,0x61294086,0x343fda10,0x54af25e8,0xfd25d6f2,0x9ff9d98d +.long 0x468b8835,0x0746af7c,0x730ecea7,0x977a31cb,0xc2cf4a81,0xa5096b80,0x6458c37a,0xaa986833,0xa6bd9d34,0x6af29bf3,0x33c5d854,0x6a62fe9b,0xb7133b5e,0x50e6c304,0x7d6e6848,0x04b60159 +.long 0x5579bea4,0x4cd296df,0x5ceedaf1,0x10e35ac8,0xe3bcc5b1,0x04c4c5fd,0x89412cf9,0x95f9ee8a,0x82b6eb0f,0x2c9459ee,0x95c2aadd,0x2e845765,0xd327fcfe,0x774a84ae,0x0368d476,0xd8c93722 +.long 0xf83e8a3b,0x0dbd5748,0x8d2495f3,0xa579aa96,0xae496e9b,0x535996a0,0xb7f9bcc2,0x07afbfe9,0x5b7bd293,0x3ac1dc6d,0x7022323d,0x3b592cff,0x9c0a3e76,0xba0deb98,0x4b197acb,0x18e78e9f +.long 0x296c36ef,0x211cde10,0x82c4da77,0x7ee89672,0xa57836da,0xb617d270,0x9cb7560b,0xf0cd9c31,0xe455fe90,0x01fdcbf7,0x7e7334f3,0x3fb53cbb,0x4e7de4ec,0x781e2ea4,0x0b384fd0,0x8adab3ad +.long 0x53d64829,0x129eee2f,0xa261492b,0x7a471e17,0xe4cb4a2c,0xe4f9adb9,0x97ba2c2d,0x3d359f6f,0x0aacd697,0x346c6786,0x75c2f8a8,0x92b444c3,0xd85df44e,0xc79fa117,0x398ddf31,0x56782372 +.long 0xbbbab3b8,0x60e690f2,0x8b04816b,0x4851f8ae,0x9c92e4d2,0xc72046ab,0x7cf3136b,0x518c74a1,0xf9877d4c,0xff4eb50a,0xa919cabb,0x14578d90,0xac5eb2b6,0x8218f8c4,0x542016e4,0xa3ccc547 +.long 0x327f8349,0x025bf48e,0xf43cb641,0xf3e97346,0x500f1085,0xdc2bafdf,0x2f063055,0x57167876,0x411925a6,0x5bd914b9,0xa1123de5,0x7c078d48,0x182b165d,0xee6bf835,0xba519727,0xb11b5e5b +.long 0x1eea7b85,0xe33ea76c,0x92d4f85e,0x2352b461,0xafe115bb,0xf101d334,0x889175a3,0xfabc1294,0x5233f925,0x7f6bcdc0,0xe77fec55,0xe0a802db,0x8069b659,0xbdb47b75,0xf98fbd74,0x1c5e12de +.long 0x4b8457ee,0x869c58c6,0x4f7ea9f7,0xa5360f69,0xf460b38f,0xe576c09f,0x22b7fb36,0x6b70d548,0x3bfae315,0x3fd237f1,0xcbdff369,0x33797852,0x25b516f9,0x97df25f5,0xba38ad2d,0x46f388f2 +.long 0x89d8ddbb,0x656c4658,0x70f38ee8,0x8830b26e,0xde1212b0,0x4320fd5c,0xe4a2edb2,0xc34f30cf,0x56ab64b8,0xabb131a3,0xd99c5d26,0x7f77f0cc,0xbf981d94,0x66856a37,0x738bd76e,0x19e76d09 +.long 0x96238f39,0xe76c8ac3,0xa830b366,0xc0a482be,0x0b4eb499,0xb7b8eaff,0x4bfb4865,0x8ecd83bc,0xa2f3776f,0x971b2cb7,0xf4b88adf,0xb42176a4,0xbe1fa446,0xb9617df5,0xcd031bd2,0x8b32d508 +.long 0x53b618c0,0x1c6bd47d,0x6a227923,0xc424f46c,0xdd92d964,0x7303ffde,0x71b5abf2,0xe9712878,0xf815561d,0x8f48a632,0xd3c055d1,0x85f48ff5,0x7525684f,0x222a1427,0x67360cc3,0xd0d841a0 +.long 0x0b9267c6,0x4245a926,0xcf07f863,0xc78913f1,0x4d0d9e24,0xaa844c8e,0x3d5f9017,0xa42ad522,0xa2c989d5,0xbd371749,0xe1f5e78e,0x928292df,0x0a1ea6da,0x493b383e,0x13aee529,0x5136fd8d +.long 0xf2c34a99,0x860c44b1,0xbf5855ac,0x3b00aca4,0xfaaf37be,0xabf6aaa0,0x2a53ec08,0x65f43682,0xa11b12e1,0x1d9a5801,0xe20ed475,0x78a7ab2c,0x9a41e0d5,0x0de1067e,0x305023ea,0x30473f5f +.long 0x169c7d97,0xdd3ae09d,0xcfaef9cd,0x5cd5baa4,0x65a44803,0x5cd7440b,0x47f364de,0xdc13966a,0x2b8357c1,0x077b2be8,0xe9d57c2a,0x0cb1b4c5,0x05ff363e,0x7a4ceb32,0xca35a9ef,0xf310fa4d +.long 0xf97f68c6,0xdbb7b352,0x0b02cf58,0x0c773b50,0x3c1f96d9,0xea2e4821,0xeee01815,0xffb357b0,0xe0f28039,0xb9c924cd,0x46a3fbe4,0x0b36c95a,0x5e46db6c,0x1faaaea4,0x1928aaff,0xcae575c3 +.long 0xa70dab86,0x7f671302,0x71c58cfc,0xfcbd12a9,0xbee0cb92,0xcbef9acf,0xf8c1b583,0x573da0b9,0x0d41d550,0x4752fcfe,0x2155cffe,0xe7eec0e3,0x545ae248,0x0fc39fcb,0x8065f44e,0x522cb8d1 +.long 0x70cbb96c,0x263c962a,0xbcd124a9,0xe034362a,0x3c2ae58d,0xf120db28,0xfef6d507,0xb9a38d49,0x1ff140fd,0xb1fd2a82,0x20aee7e0,0xbd162f30,0xcb251949,0x4e17a5d4,0x4f7e1c3d,0x2aebcb83 +.long 0x937b0527,0x608eb25f,0xeb7d9997,0xf42e1e47,0xb8a53a29,0xeba699c4,0xe091b536,0x1f921c71,0x5b26bbd5,0xcce29e7b,0x3b61a680,0x7a8ef5ed,0xba1f1c7e,0xe5ef8043,0x18158dda,0x16ea8217 +.long 0x599ff0f9,0x01778a2b,0x8104fc6b,0x68a923d7,0xda694ff3,0x5bfa44df,0xf7667f12,0x4f7199db,0xe46f2a79,0xc06d8ff6,0xe9f8131d,0x08b5dead,0xabb4ce7c,0x02519a59,0xb42aec3e,0xc4f710bc +.long 0x78bde41a,0x3d77b057,0xb4186b5a,0x6474bf80,0x88c65741,0x048b3f67,0x03c7c154,0xc64519de,0x0edfcc4f,0xdf073846,0x48f1aa6b,0x319aa737,0xca909f77,0x8b9f8a02,0x7580bfef,0x90258139 +.long 0xc0c22719,0xd8bfd3ca,0xc9ca151e,0xc60209e4,0xd9a1a69c,0x7a744ab5,0x14937f8f,0x6de5048b,0xe115ac04,0x171938d8,0x1c6b16d2,0x7df70940,0x7f8e94e7,0xa6aeb663,0x2a2cf094,0xc130388e +.long 0x77f54e6e,0x1850be84,0x65d60fe5,0x9f258a72,0x6c9146d6,0xff7ff0c0,0xe63a830b,0x039aaf90,0x9460342f,0x38f27a73,0x3f795f8a,0x4703148c,0x9681a97e,0x1bb5467b,0xecaeb594,0x00931ba5 +.long 0x786f337c,0xcdb6719d,0xe704397d,0xd9c01cd2,0x555c2fef,0x0f4a3f20,0x7c0af223,0x00452509,0x84db8e76,0x54a58047,0x93c8aa06,0x3bacf1aa,0xf7919422,0x11ca957c,0x78cdaa40,0x50641053 +.long 0x9f7144ae,0x7a303874,0x43d4acfd,0x170c963f,0x58ddd3ef,0x5e148149,0x9e72dba8,0xa7bde582,0x6fa68750,0x0769da8b,0x572e0249,0xfa64e532,0x2619ad31,0xfcaadf9d,0xa7b349cd,0x87882daa +.long 0x6c67a775,0x9f6eb731,0xefc5d0b1,0xcb10471a,0xe1b806b2,0xb433750c,0x57b1ae7e,0x19c5714d,0xed03fd3f,0xc0dc8b7b,0x31bc194e,0xdd03344f,0x8c6320b5,0xa66c52a7,0xd0b6fd93,0x8bc82ce3 +.long 0xb35f1341,0xf8e13501,0x25a43e42,0xe53156dd,0x4daeb85c,0xd3adf27e,0xbbeddeb5,0xb81d8379,0x2e435867,0x1b0b546e,0xeba5dd60,0x9020eb94,0x8210cb9d,0x37d91161,0x5c91f1cf,0x4c596b31 +.long 0x0e0b040d,0xb228a90f,0x45ff897f,0xbaf02d82,0x00fa6122,0x2aac79e6,0x8e36f557,0x24828817,0x113ec356,0xb9521d31,0x15eff1f8,0x9e48861e,0xe0d41715,0x2aa1d412,0x53f131b8,0x71f86203 +.long 0x3fd19408,0xf60da8da,0x278d9d99,0x4aa716dc,0xa8c51c90,0x394531f7,0xf59db51c,0xb560b0e8,0xfa34bdad,0xa28fc992,0x9cd4f8bd,0xf024fa14,0x23a9d0d3,0x5cf530f7,0xe28c9b56,0x615ca193 +.long 0x6f73c51e,0x6d2a483d,0xea0dc2dd,0xa4cb2412,0x1eb917ff,0x50663c41,0xeade299e,0x3d3a74cf,0x4a7a9202,0x29b3990f,0xa7b15c3d,0xa9bccf59,0xa5df9208,0x66a3ccdc,0x43f2f929,0x48027c14 +.long 0x40b557f0,0xd385377c,0xcd684660,0xe001c366,0xe2183a27,0x1b18ed6b,0x63210329,0x879738d8,0xbda94882,0xa687c74b,0xa684b299,0xd1bbcc48,0x863b3724,0xaf6f1112,0x2c8ce9f8,0x6943d1b4 +.long 0x098cafb4,0xe044a3bb,0x60d48caf,0x27ed2310,0x3a31b84d,0x542b5675,0xfcddbed7,0xcbf3dd50,0x41b1d830,0x25031f16,0xcb0c1e27,0xa7ec851d,0xb5ae75db,0xac1c8fe0,0x08c52120,0xb24c7557 +.long 0x1d4636c3,0x57f811dc,0x681a9939,0xf8436526,0x9c81adb3,0x1f6bc6d9,0x5b7d80d4,0x840f8ac3,0xf4387f1a,0x731a9811,0xb5156880,0x7c501cd3,0xdfe68867,0xa5ca4a07,0x5fcea120,0xf123d8f0 +.long 0xd607039e,0x1fbb0e71,0xcd3a4546,0x2b70e215,0x53324091,0x32d2f01d,0x180ab19b,0xb796ff08,0x3c57c4aa,0x32d87a86,0xb7c49a27,0x2aed9caf,0x31630d98,0x9fb35eac,0x5c3e20a3,0x338e8cdf +.long 0x66cde8db,0x80f16182,0x2d72fd36,0x4e159980,0x9b6e5072,0xd7b8f13b,0x3b7b5dc1,0xf5213907,0x8ce4396e,0x4d431f1d,0xa7ed2142,0x37a1a680,0xd01aaf6b,0xbf375696,0xe63aab66,0xaa1c0c54 +.long 0x4ed80940,0x3014368b,0x7a6fcedd,0x67e6d056,0xca97579f,0x7c208c49,0xa23597f6,0xfe3d7a81,0x7e096ae2,0x5e203202,0x24b39366,0xb1f3e1e7,0x2fdcdffc,0x26da26f3,0x6097be83,0x79422f1d +.long 0x9db3b381,0x263a2cfb,0xd4df0a4b,0x9c3a2dee,0x7d04e61f,0x728d06e9,0x42449325,0x8b1adfbc,0x7e053a1b,0x6ec1d939,0x66daf707,0xee2be5c7,0x810ac7ab,0x80ba1e14,0xf530f174,0xdd2ae778 +.long 0x205b9d8b,0x0435d97a,0x056756d4,0x6eb8f064,0xb6f8210e,0xd5e88a8b,0xec9fd9ea,0x070ef12d,0x3bcc876a,0x4d849505,0xa7404ce3,0x12a75338,0xb8a1db5e,0xd22b49e1,0x14bfa5ad,0xec1f2051 +.long 0xb6828f36,0xadbaeb79,0x01bd5b9e,0x9d7a0258,0x1e844b0c,0xeda01e0d,0x887edfc9,0x4b625175,0x9669b621,0x14109fdd,0xf6f87b98,0x88a2ca56,0x170df6bc,0xfe2eb788,0xffa473f9,0x0cea06f4 +.long 0xc4e83d33,0x43ed81b5,0x5efd488b,0xd9f35879,0x9deb4d0f,0x164a620f,0xac6a7394,0xc6927bdb,0x9f9e0f03,0x45c28df7,0xfcd7e1a9,0x2868661e,0xffa348f1,0x7cf4e8d0,0x398538e0,0x6bd4c284 +.long 0x289a8619,0x2618a091,0x6671b173,0xef796e60,0x9090c632,0x664e46e5,0x1e66f8fb,0xa38062d4,0x0573274e,0x6c744a20,0xa9271394,0xd07b67e4,0x6bdc0e20,0x391223b2,0xeb0a05a7,0xbe2d93f1 +.long 0x3f36d141,0xf23e2e53,0x4dfca442,0xe84bb3d4,0x6b7c023a,0xb804a48d,0x76431c3b,0x1e16a8fa,0xddd472e0,0x1b5452ad,0x0d1ee127,0x7d405ee7,0xffa27599,0x50fc6f1d,0xbf391b35,0x351ac53c +.long 0x4444896b,0x7efa14b8,0xf94027fb,0x64974d2f,0xde84487d,0xefdcd0e8,0x2b48989b,0x8c45b260,0xd8463487,0xa8fcbbc2,0x3fbc476c,0xd1b2b3f7,0xc8f443c0,0x21d005b7,0x40c0139c,0x518f2e67 +.long 0x06d75fc1,0x56036e8c,0x3249a89f,0x2dcf7bb7,0xe245e7dd,0x81dd1d3d,0xebd6e2a7,0xf578dc4b,0xdf2ce7a0,0x4c028903,0x9c39afac,0xaee36288,0x146404ab,0xdc847c31,0xa4e97818,0x6304c0d8 +.long 0xa91f6791,0xae51dca2,0x9baa9efc,0x2abe4190,0x559c7ac1,0xd9d2e2f4,0xfc9f773a,0xe82f4b51,0x4073e81c,0xa7713027,0xfbb596fc,0xc0276fac,0xa684f70c,0x1d819fc9,0xc9f7b1e0,0x29b47fdd +.long 0x459b1940,0x358de103,0x5b013e93,0xec881c59,0x49532ad3,0x51574c93,0xb37b46de,0x2db1d445,0xdf239fd8,0xc6445b87,0x151d24ee,0xc718af75,0xf43c6259,0xaea1c4a4,0x70be02f7,0x40c0e5d7 +.long 0x721b33f2,0x6a4590f4,0xfedf04ea,0x2124f1fb,0x9745efe7,0xf8e53cde,0x65f046d9,0xe7e10432,0xe4d0c7e6,0xc3fca28e,0x87253b1b,0x847e339a,0x3743e643,0x9b595348,0x4fd12fc5,0xcb6a0a0b +.long 0x27d02dcc,0xfb6836c3,0x7a68bcc2,0x5ad00982,0x005e912d,0x1b24b44c,0x811fdcfe,0xcc83d20f,0x666fba0c,0x36527ec1,0x14754635,0x69948197,0x556da9c2,0xfcdcb1a8,0x81a732b2,0xa5934267 +.long 0xa714181d,0xec1214ed,0x6067b341,0x609ac13b,0xa545df1f,0xff4b4c97,0x34d2076b,0xa1240501,0x1409ca97,0x6efa0c23,0x20638c43,0x254cc1a8,0xdcfb46cd,0xd4e363af,0x03942a27,0x62c2adc3 +.long 0x56e46483,0xc67b9df0,0x63736356,0xa55abb20,0xc551bc52,0xab93c098,0xb15fe64b,0x382b49f9,0x4dff8d47,0x9ec221ad,0x437df4d6,0x79caf615,0xbb456509,0x5f13dc64,0x191f0714,0xe4c589d9 +.long 0x3fd40e09,0x27b6a8ab,0x77313ea9,0xe455842e,0x1f55988b,0x8b51d1e2,0x062bbbfc,0x5716dd73,0x4e8bf3de,0x633c11e5,0x1b85be3b,0x9a0e77b6,0x0911cca6,0x56510729,0xefa6590f,0x27e76495 +.long 0x070d3aab,0xe4ac8b33,0x9a2cd5e5,0x2643672b,0x1cfc9173,0x52eff79b,0x90a7c13f,0x665ca49b,0xb3efb998,0x5a8dda59,0x052f1341,0x8a5b922d,0x3cf9a530,0xae9ebbab,0xf56da4d7,0x35986e7b +.long 0xff3513cc,0x3a636b5c,0x3198f7dd,0xbb0cf8ba,0x41f16f86,0xb8d40522,0xde13a7bf,0x760575d8,0x9f7aa181,0x36f74e16,0xf509ed1c,0x163a3ecf,0x3c40a491,0x6aead61f,0xdfe8fcaa,0x158c95fc +.long 0x13cda46f,0xa3991b6e,0x342faed0,0x79482415,0x666b5970,0xf3ba5bde,0xb26ab6dd,0x1d52e6bc,0x8608dd3d,0x768ba1e7,0xea076586,0x4930db2a,0xe7dc1afa,0xd9575714,0xf7c58817,0x1fc7bf7d +.long 0xd9eee96c,0x6b47accd,0xe58cec37,0x0ca277fb,0xe702c42a,0x113fe413,0xc47cbe51,0xdd1764ee,0x7b3ed739,0x041e7cde,0x5ce9e1c0,0x50cb7459,0x2925b212,0x35568513,0x001b081c,0x7cff95c4 +.long 0x8088b454,0x63ee4cbd,0x9a9e0c8a,0xdb7f32f7,0x6b2447cb,0xb377d418,0xd370219b,0xe3e982aa,0xc2a2a593,0x06ccc1e4,0x0773f24f,0x72c36865,0x95859423,0xa13b4da7,0x75040c8f,0x8bbf1d33 +.long 0xda50c991,0x726f0973,0x822d6ee2,0x48afcd5b,0x20fd7771,0xe5fc718b,0xfd0807a1,0xb9e8e77d,0x99a7703d,0x7f5e0f44,0x618e36f3,0x6972930e,0x23807bbe,0x2b7c77b8,0xcb27ff50,0xe5b82405 +.long 0xbd379062,0xba8b8be3,0x2dce4a92,0xd64b7a1d,0xb2952e37,0x040a73c5,0xd438aeca,0x0a9e252e,0xc39d3bcb,0xdd43956b,0xb32b2d63,0x1a31ca00,0x5c417a18,0xd67133b8,0x2ef442c8,0xd08e4790 +.long 0x255c0980,0x98cb1ae9,0x2b4a739f,0x4bd86381,0x1e4a45a1,0x5a5c31e1,0x9cb0db2f,0x1e5d55fe,0x8ff5cc29,0x74661b06,0x0eb8a4f4,0x026b389f,0x58848c24,0x536b21a4,0x81dc72b0,0x2e5bf8ec +.long 0xad886aac,0x03c187d0,0xb771b645,0x5c16878a,0xc74045ab,0xb07dfc6f,0x7800caed,0x2c6360bf,0xb9c972a3,0x24295bb5,0x7c9a6dba,0xc9e6f88e,0x92a79aa6,0x90ffbf24,0x41c26ac2,0xde29d50a +.long 0xd309cbe6,0x9f0af483,0xe0bced4f,0x5b020d8a,0xb38023e3,0x606e986d,0x1abc6933,0xad8f2c9d,0xe7400e93,0x19292e1d,0x52be5e4d,0xfe3e18a9,0x2e0680bf,0xe8e9771d,0xc54db063,0x8c5bec98 +.long 0x74a55d1f,0x2af9662a,0x046f66d8,0xe3fbf28f,0xd4dc4794,0xa3a72ab4,0x5c7c2dd8,0x09779f45,0xc3d19d8d,0xd893bdaf,0x57d6a6df,0xd5a75094,0x952e6255,0x8cf8fef9,0xda9a8aff,0x3da67cfb +.long 0x2c160dcd,0x4c23f62a,0x8f90eaef,0x34e6c5e3,0xa9a65d5a,0x35865519,0x8fd38a3d,0x07c48aae,0x50068527,0xb7e7aeda,0x1c90936a,0x2c09ef23,0xe879324c,0x31ecfeb6,0xfb0ec938,0xa0871f6b +.long 0xd84d835d,0xb1f0fb68,0x861dc1e6,0xc90caf39,0x7594f8d7,0x12e5b046,0x65012b92,0x26897ae2,0xa4d6755d,0xbcf68a08,0x0991fbda,0x403ee41c,0x3bbf17e8,0x733e343e,0x679b3d65,0xd2c7980d +.long 0xd2e11305,0x33056232,0xf3c07a6f,0x966be492,0xbb15509d,0x6a8878ff,0x0a9b59a4,0xff221101,0xabe30129,0x6c9f564a,0x336e64cf,0xc6f2c940,0x8b0c8022,0x0fe75262,0x6ae8db87,0xbe0267e9 +.long 0x93bc042b,0x22e192f1,0xb237c458,0xf085b534,0x832c4168,0xa0d192bd,0xbdf6271d,0x7a76e9e3,0xb88911b5,0x52a882fa,0xb4db0eb5,0xc85345e4,0x81a7c3ff,0xa3be02a6,0xf0ec0469,0x51889c8c +.long 0xa5e829e5,0x9d031369,0x1607aa41,0xcbb4c6fc,0x241d84c1,0x75ac59a6,0x8829e0ee,0xc043f2bf,0x8ea5e185,0x82a38f75,0xd87cbd9f,0x8bda40b9,0x2d8fc601,0x9e65e75e,0xa35690b3,0x3d515f74 +.long 0xda79e5ac,0x534acf4f,0x8630215f,0x68b83b3a,0xd085756e,0x5c748b2e,0xe5d37cb2,0xb0317258,0xc5ccc2c4,0x6735841a,0x3d9d5069,0x7d7dc96b,0xfd1754bd,0xa147e410,0xd399ddd5,0x65296e94 +.long 0xbc8fa5bc,0xf6b5b2d0,0x500c277b,0x8a5ead67,0xdfa08a5d,0x214625e6,0x959cf047,0x51fdfedc,0x289fca32,0x6bc9430b,0x9d9bdc3f,0xe36ff0cf,0x58ea0ede,0x2fe187cb,0x5a900b3f,0xed66af20 +.long 0x5fa9f4d6,0x00e0968b,0x37a362e7,0x2d4066ce,0xbd07e772,0xa99a9748,0x06a4f1d0,0x710989c0,0xce40cbd8,0xd5dedf35,0x1743293d,0xab55c5f0,0x8aa24e2c,0x766f1144,0x605fbcb4,0x94d874f8 +.long 0xa518001b,0xa365f0e8,0x9d04ef0f,0xee605eb6,0xba8d4d25,0x5a3915cd,0xb5113472,0x44c0e1b8,0x8b6740dc,0xcbb024e8,0xee1d4f0c,0x89087a53,0x1fc4e372,0xa88fa05c,0xaf8b3af2,0x8bf395cb +.long 0xdeb8568b,0x1e71c9a1,0x80fb3d32,0xa35daea0,0x2cf8fb81,0xe8b6f266,0x9490696a,0x6d51afe8,0x51803a19,0x81beac6e,0x86219080,0xe3d24b7f,0xdf6f463c,0x727cfd9d,0x72284ee8,0x8c6865ca +.long 0xb743f4ef,0x32c88b7d,0xe7d11dce,0x3793909b,0x2ff2ebe8,0xd398f922,0xe5e49796,0x2c70ca44,0xcb1131b1,0xdf4d9929,0x25888e79,0x7826f298,0xf1d8740a,0x4d3a112c,0x270afa8b,0x00384cb6 +.long 0x3ab48095,0xcb64125b,0x62d05106,0x3451c256,0xa4955845,0xd73d577d,0xbf9f4433,0x39570c16,0xadecf263,0xd7dfaad3,0xdc76e102,0xf1c3d8d1,0x54c6a836,0x5e774a58,0x3e92d47b,0xdad4b672 +.long 0xf0d796a0,0xbe7e990f,0xdf0e8b02,0x5fc62478,0x030c00ad,0x8aae8bf4,0x9004ba0f,0x3d2db93b,0xd85d5ddc,0xe48c8a79,0x6bb07f34,0xe907caa7,0xa39eaed5,0x58db343a,0xadaf5724,0x0ea6e007 +.long 0xd23233f3,0xe00df169,0x77cb637f,0x3e322796,0x1da0cf6c,0x1f897c0e,0x31d6bbdd,0xa651f5d8,0x1a230c76,0xdd61af19,0xcdaa5e4a,0xbd527272,0xd0abcd7e,0xca753636,0x370bd8dc,0x78bdd37c +.long 0x17cd93fe,0xc23916c2,0xdadce6e2,0x65b97a4d,0x174e42f8,0xe04ed4eb,0xbb21480a,0x1491ccaa,0x23196332,0x145a8280,0x587b479a,0x3c3862d7,0x01dcd0ed,0x9f4a88a3,0x3ea12f1f,0x4da2b7ef +.long 0xb126e48e,0xf8e7ae33,0xf494e237,0x404a0b32,0xc55acadb,0x9beac474,0xcbec9fd9,0x4ee5cf3b,0x7df3c8c3,0x336b33b9,0xb76808fd,0xbd905fe3,0xaa45c16a,0x8f436981,0x3dd27b62,0x255c5bfa +.long 0xc3dd9b4d,0x71965cbf,0xfc068a87,0xce23edbf,0x745b029b,0xb78d4725,0xcefdd9bd,0x74610713,0x1266bf52,0x7116f75f,0x18e49bb6,0x02046722,0x3d6f19e3,0xdf43df9f,0xe685cb2f,0xef1bc7d0 +.long 0x7078c432,0xcddb27c1,0xb77fedb7,0xe1961b9c,0xc2290570,0x1edc2f5c,0x19cbd886,0x2c3fefca,0xc2af389a,0xcf880a36,0xbda71cea,0x96c610fd,0x32aa8463,0xf03977a9,0x8586d90a,0x8eb7763f +.long 0x2a296e77,0x3f342454,0x42837a35,0xc8718683,0x6a09c731,0x7dc71090,0x51b816db,0x54778ffb,0xaf06defd,0x6b33bfec,0x8592b70b,0xfe3c105f,0x61da6114,0xf937fda4,0x4c266ad7,0x3c13e651 +.long 0x855938e8,0xe363a829,0x9de54b72,0x2eeb5d9e,0x20ccfab9,0xbeb93b0e,0x25e61a25,0x3dffbb5f,0x1acc093d,0x7f655e43,0x3964ce61,0x0cb6cc3d,0xe5e9b460,0x6ab283a1,0xa1c7e72d,0x55d787c5 +.long 0xdeadbf02,0x4d2efd47,0xac459068,0x11e80219,0x71f311f0,0x810c7626,0x4ab6ef53,0xfa17ef8d,0x93e43bff,0xaf47fd25,0x0be40632,0x5cb5ff3f,0x8ee61da3,0x54687106,0xb08afd0f,0x7764196e +.long 0xf0290a8f,0x831ab3ed,0xcb47c387,0xcae81966,0x184efb4f,0xaad7dece,0x4749110e,0xdcfc53b3,0x4cb632f9,0x6698f23c,0xb91f8067,0xc42a1ad6,0x6284180a,0xb116a81d,0xe901326f,0xebedf5f8 +.long 0x97e3e044,0xf2274c9f,0x11d09fc9,0x42018520,0xd18e6e23,0x56a65f17,0x352b683c,0x2ea61e2a,0x575eaa94,0x27d291bc,0xb8ff522d,0x9e7bc721,0xa7f04d6f,0x5f7268bf,0xaba41748,0x5868c73f +.long 0x7be0eead,0x9f85c2db,0xff719135,0x511e7842,0xc5ea90d7,0x5a06b1e9,0x26fab631,0x0c19e283,0xe9206c55,0x8af8f0cf,0x3553c06a,0x89389cb4,0xf65f8004,0x39dbed97,0xc508991d,0x0621b037 +.long 0x96e78cc4,0x1c52e635,0x0c06b4a8,0x5385c8b2,0xb0e87d03,0xd84ddfdb,0x934bafad,0xc49dfb66,0x59f70772,0x7071e170,0x3a1db56b,0x3a073a84,0x3b8af190,0x03494903,0xd32920f0,0x7d882de3 +.long 0xb2cf8940,0x91633f0a,0x6f948f51,0x72b0b178,0x782653c8,0x2d28dc30,0xdb903a05,0x88829849,0x6a19d2bb,0xb8095d0c,0x86f782cb,0x4b9e7f0c,0x2d907064,0x7af73988,0x8b32643c,0xd12be0fe +.long 0x0e165dc3,0x358ed23d,0x4e2378ce,0x3d47ce62,0xfeb8a087,0x7e2bb0b9,0xe29e10b9,0x3246e8ae,0x03ce2b4d,0x459f4ec7,0xbbc077cf,0xe9b4ca1b,0x0e9940c1,0x2613b4f2,0x047d1eb1,0xfc598bb9 +.long 0x45036099,0x9744c62b,0x167c65d8,0xa9dee742,0xdabe1943,0x0c511525,0x93c6c624,0xda110554,0x651a3be2,0xae00a52c,0x884449a6,0xcda5111d,0xff33bed1,0x063c06f4,0x0d3d76b4,0x73baaf9a +.long 0x7fc63668,0x52fb0c9d,0x0c039cde,0x6886c9dd,0x55b22351,0x602bd599,0x360c7c13,0xb00cab02,0x81b69442,0x8cb616bc,0xb55c3cee,0x41486700,0xf49ba278,0x71093281,0x64a50710,0xad956d9c +.long 0x638a7e81,0x9561f28b,0x5980ddc3,0x54155cdf,0xd26f247a,0xb2db4a96,0x4787d100,0x9d774e4e,0x078637d2,0x1a9e6e2e,0x5e0ae06a,0x1c363e2d,0xe9cfa354,0x7493483e,0x7f74b98d,0x76843cb3 +.long 0xd4b66947,0xbaca6591,0x04460a8c,0xb452ce98,0x43768f55,0x6830d246,0x7dff12df,0xf4197ed8,0x400dd0f7,0x6521b472,0x4b1e7093,0x59f5ca8f,0x080338ae,0x6feff11b,0xa29ca3c6,0x0ada31f6 +.long 0x94a2c215,0x24794eb6,0x05a57ab4,0xd83a43ab,0x2a6f89fe,0x264a543a,0xdd5ec7c2,0x2c2a3868,0x8439d9b2,0xd3373940,0x0acd1f11,0x715ea672,0xe7e6cc19,0x42c1d235,0xb990585c,0x81ce6e96 +.long 0xd809c7bd,0x04e5dfe0,0x8f1050ab,0xd7b2580c,0xd8a4176f,0x6d91ad78,0x4e2e897c,0x0af556ee,0x921de0ac,0x162a8b73,0x7ea78400,0x52ac9c22,0xefce2174,0xee2a4eea,0x6d637f79,0xbe61844e +.long 0x789a283b,0x0491f1bc,0x880836f4,0x72d3ac3d,0x88e5402d,0xaa1c5ea3,0xd5cc473d,0x1b192421,0x9dc84cac,0x5c0b9998,0x9c6e75b8,0xb0a8482d,0x3a191ce2,0x639961d0,0x6d837930,0xda3bc865 +.long 0x056e6f8f,0xca990653,0x64d133a7,0x84861c41,0x746abe40,0x8b403276,0xebf8e303,0xb7b4d51a,0x220a255d,0x05b43211,0x02419e6e,0xc997152c,0x630c2fea,0x76ff47b6,0x281fdade,0x50518677 +.long 0xcf902b0b,0x3283b8ba,0x37db303b,0x8d4b4eb5,0x755011bc,0xcc89f42d,0xdd09d19b,0xb43d74bb,0x8adba350,0x65746bc9,0xb51c1927,0x364eaf8c,0x10ad72ec,0x13c76596,0xf8d40c20,0x30045121 +.long 0xea7b979b,0x6d2d99b7,0xe6fb3bcd,0xcd78cd74,0x86cffbfe,0x11e45a9e,0x637024f6,0x78a61cf4,0x3d502295,0xd06bc872,0x458cb288,0xf1376854,0x342f8586,0xb9db26a1,0x4beee09e,0xf33effcf +.long 0xb30cfb3a,0xd7e0c4cd,0x6c9db4c8,0x6d09b8c1,0x07c8d9df,0x40ba1a42,0x1c52c66d,0x6fd495f7,0x275264da,0xfb0e169f,0xe57d8362,0x80c2b746,0x49ad7222,0xedd987f7,0x4398ec7b,0xfdc229af +.long 0x52666a58,0xb0d1ed84,0xe6a9c3c2,0x4bcb6e00,0x26906408,0x3c57411c,0x13556400,0xcfc20755,0x5294dba3,0xa08b1c50,0x8b7dd31e,0xa30ba286,0x991eca74,0xd70ba90e,0xe762c2b9,0x094e142c +.long 0x979f3925,0xb81d783e,0xaf4c89a7,0x1efd130a,0xfd1bf7fa,0x525c2144,0x1b265a9e,0x4b296904,0xb9db65b6,0xed8e9634,0x03599d8a,0x35c82e32,0x403563f3,0xdaa7a54f,0x022c38ab,0x9df088ad +.long 0xbb3fd30a,0xe5cfb066,0xeff0354e,0x429169da,0x3524e36c,0x809cf852,0x0155be1d,0x136f4fb3,0x1fbba712,0x4826af01,0x506ba1a1,0x6ef0f0b4,0x77aea73e,0xd9928b31,0x5eaa244e,0xe2bf6af2 +.long 0x4237b64b,0x8d084f12,0xe3ecfd07,0x688ebe99,0xf6845dd8,0x57b8a70c,0x5da4a325,0x808fc59c,0xa3585862,0xa9032b2b,0xedf29386,0xb66825d5,0x431ec29b,0xb5a5a8db,0x3a1e8dc8,0xbb143a98 +.long 0x12ae381b,0x35ee94ce,0x86ccda90,0x3a7f176c,0x4606eaca,0xc63a657e,0x43cd04df,0x9ae5a380,0xed251b46,0x9bec8d15,0xcaca5e64,0x1f5d6d30,0x9ff20f07,0x347b3b35,0xf7e4b286,0x4d65f034 +.long 0xf111661e,0x9e93ba24,0xb105eb04,0xedced484,0xf424b578,0x96dc9ba1,0xe83e9069,0xbf8f66b7,0xd7ed8216,0x872d4df4,0x8e2cbecf,0xbf07f377,0x98e73754,0x4281d899,0x8aab8708,0xfec85fbb +.long 0xa5ba5b0b,0x9a3c0dee,0x42d05299,0xe6a116ce,0xe9b02d42,0xae9775fe,0xa1545cb6,0x72b05200,0x31a3b4ea,0xbc506f7d,0x8bbd9b32,0xe5893078,0xe4b12a97,0xc8bc5f37,0x4a73b671,0x6b000c06 +.long 0x765fa7d0,0x13b5bf22,0x1d6a5370,0x59805bf0,0x4280db98,0x67a5e29d,0x776b1ce3,0x4f53916f,0x33ddf626,0x714ff61f,0xa085d103,0x4206238e,0xe5809ee3,0x1c50d4b7,0x85f8eb1d,0x999f450d +.long 0xe4c79e9b,0x658a6051,0xc66a9fea,0x1394cb73,0xc6be7b23,0x27f31ed5,0x5aa6f8fe,0xf4c88f36,0x4aaa499e,0x0fb0721f,0xe3fb2a6b,0x68b3a7d5,0x3a92851d,0xa788097d,0xe96f4913,0x060e7f8a +.long 0x1a3a93bc,0x82eebe73,0xa21adc1a,0x42bbf465,0xef030efd,0xc10b6fa4,0x87b097bb,0x247aa4c7,0xf60c77da,0x8b8dc632,0xc223523e,0x6ffbc26a,0x344579cf,0xa4f6ff11,0x980250f6,0x5825653c +.long 0xbc1aa2b9,0xb2dd097e,0x37a0333a,0x07889393,0x37a0db38,0x1cf55e71,0x792c1613,0x2648487f,0x3fcef261,0xdad01336,0x0eabf129,0x6239c81d,0x9d276be2,0x8ee761de,0x1eda6ad3,0x406a7a34 +.long 0x4a493b31,0x4bf367ba,0x9bf7f026,0x54f20a52,0x9795914b,0xb696e062,0x8bf236ac,0xcddab96d,0xed25ea13,0x4ff2c70a,0x81cbbbe7,0xfa1d09eb,0x468544c5,0x88fc8c87,0x696b3317,0x847a670d +.long 0x64bcb626,0xf133421e,0x26dee0b5,0xaea638c8,0xb310346c,0xd6e7680b,0xd5d4ced3,0xe06f4097,0x7512a30b,0x09961452,0xe589a59a,0xf3d867fd,0x52d0c180,0x2e73254f,0x333c74ac,0x9063d8a3 +.long 0xd314e7bc,0xeda6c595,0x467899ed,0x2ee7464b,0x0a1ed5d3,0x1cef423c,0x69cc7613,0x217e76ea,0xe7cda917,0x27ccce1f,0x8a893f16,0x12d8016b,0x9fc74f6b,0xbcd6de84,0xf3144e61,0xfa5817e2 +.long 0x0821ee4c,0x1f354164,0x0bc61992,0x1583eab4,0x1d72879f,0x7490caf6,0xf76ae7b2,0x998ad9f3,0xa41157f7,0x1e181950,0xe8da3a7e,0xa9d7e1e6,0x8426b95f,0x963784eb,0x542e2a10,0x0ee4ed6e +.long 0xac751e7b,0xb79d4cc5,0xfd4211bd,0x93f96472,0xc8de4fc6,0x8c72d3d2,0xdf44f064,0x7b69cbf5,0xf4bf94e1,0x3da90ca2,0xf12894e2,0x1a5325f8,0x7917d60b,0x0a437f6c,0x96c9cb5d,0x9be70486 +.long 0xe1dc5c05,0xb4d880bf,0xeebeeb57,0xd738adda,0xdf0fe6a3,0x6f0119d3,0x66eaaf5a,0x5c686e55,0xdfd0b7ec,0x9cb10b50,0x6a497c21,0xbdd0264b,0x8c546c96,0xfc093514,0x79dbf42a,0x58a947fa +.long 0x49ccd6d7,0xc0b48d4e,0x88bd5580,0xff8fb02c,0x07d473b2,0xc75235e9,0xa2188af3,0x4fab1ac5,0x97576ec0,0x030fa3bc,0x0b7e7d2f,0xe8c946e8,0x70305600,0x40a5c9cc,0xc8b013b4,0x6d8260a9 +.long 0x70bba85c,0x0368304f,0xa4a0d311,0xad090da1,0x2415eec1,0x7170e870,0x8461ea47,0xbfba35fe,0xc1e91938,0x6279019a,0x1afc415f,0xa47638f3,0xbcba0e0f,0x36c65cbb,0x034e2c48,0x02160efb +.long 0x615cd9e4,0xe6c51073,0xf1243c06,0x498ec047,0xb17b3d8c,0x3e5a8809,0x0cc565f1,0x5cd99e61,0x7851dafe,0x81e312df,0xa79061e2,0xf156f5ba,0x880c590e,0x80d62b71,0x0a39faa1,0xbec9746f +.long 0xc8ed1f7a,0x1d98a9c1,0xa81d5ff2,0x09e43bb5,0x0da0794a,0xd5f00f68,0x661aa836,0x412050d9,0x90747e40,0xa89f7c4e,0xb62a3686,0x6dc05ebb,0x308e3353,0xdf4de847,0x9fb53bb9,0x53868fbb +.long 0xcfdcf7dd,0x2b09d2c3,0x723fcab4,0x41a9fce3,0x07f57ca3,0x73d905f7,0xac8e1555,0x080f9fb1,0x9ba7a531,0x7c088e84,0xed9a147f,0x07d35586,0xaf48c336,0x602846ab,0x0ccf0e79,0x7320fd32 +.long 0xb18bd1ff,0xaa780798,0xafdd2905,0x52c2e300,0x434267cd,0xf27ea3d6,0x15605b5f,0x8b96d16d,0x4b45706b,0x7bb31049,0x743d25f8,0xe7f58b8e,0x87f30076,0xe9b5e45b,0x5d053d5a,0xd19448d6 +.long 0xd3210a04,0x1ecc8cb9,0xdafb5269,0x6bc7d463,0x67c3489f,0x3e59b10a,0x65641e1b,0x1769788c,0xbd6cb838,0x8a53b82d,0x236d5f22,0x7066d6e6,0x6908536e,0x03aa1c61,0x66ae9809,0xc971da0d +.long 0xc49a2fac,0x01b3a86b,0x3092e77a,0x3b8420c0,0x7d6fb556,0x02057300,0xbff40a87,0x6941b2a1,0x0658ff2a,0x140b6308,0x3424ab36,0x87804363,0x5751e299,0x0253bd51,0x449c3e3a,0xc75bcd76 +.long 0x7f8f875d,0x92eb4090,0x56c26bbf,0x9c9d754e,0x8110bbe7,0x158cea61,0x745f91ea,0x62a6b802,0xc6e7394b,0xa79c41aa,0xad57ef10,0x445b6a83,0x6ea6f40c,0x0c5277eb,0x88633365,0x319fe96b +.long 0x385f63cb,0x0b0fc61f,0x22bdd127,0x41250c84,0x09e942c2,0x67d153f1,0xc021ad5d,0x60920d08,0x724d81a5,0x229f5746,0x5bba3299,0xb7ffb892,0xde413032,0x518c51a1,0x3c2fd94c,0x2a9bfe77 +.long 0x3191f4fd,0xcbcde239,0xd3d6ada1,0x43093e16,0x58769606,0x184579f3,0xd236625c,0x2c94a8b3,0x5c437d8e,0x6922b9c0,0xd8d9f3c8,0x3d4ae423,0x2e7090a2,0xf72c31c1,0xd76a55bd,0x4ac3f5f3 +.long 0x6b6af991,0x342508fc,0x1b5cebbd,0x0d527100,0xdd440dd7,0xb84740d0,0x780162fd,0x748ef841,0xdfc6fafb,0xa8dbfe0e,0xf7300f27,0xeadfdf05,0xfeba4ec9,0x7d06555f,0x9e25fa97,0x12c56f83 +.long 0xd39b8c34,0x77f84203,0x3125eddb,0xed8b1be6,0xf6e39dc5,0x5bbf2441,0x6a5d678a,0xb00f6ee6,0x57d0ea99,0xba456ecf,0x17e06c43,0xdcae0f58,0x0f5b4baa,0x01643de4,0xd161b9be,0x2c324341 +.long 0xe126d468,0x80177f55,0x76748e09,0xed325f1f,0xcfa9bdc2,0x6116004a,0x3a9fb468,0x2d8607e6,0x6009d660,0x0e573e27,0x8d10c5a1,0x3a525d2e,0x3b9009a0,0xd26cb45c,0xde9d7448,0xb6b0cdc0 +.long 0xe1337c26,0x949c9976,0xd73d68e5,0x6faadebd,0xf1b768d9,0x9e158614,0x9cc4f069,0x22dfa557,0xbe93c6d6,0xccd6da17,0xa504f5b9,0x24866c61,0x8d694da1,0x2121353c,0x0140b8c6,0x1c6ca580 +.long 0xe964021e,0xc245ad8c,0x032b82b3,0xb83bffba,0x47ef9898,0xfaa220c6,0x982c948a,0x7e8d3ac6,0xbc2d124a,0x1faa2091,0x05b15ff4,0xbd54c3dd,0xc87c6fb7,0x386bf3ab,0xfdeb6f66,0xfb2b0563 +.long 0x5b45afb4,0x4e77c557,0xefb8912d,0xe9ded649,0x42f6e557,0x7ec9bbf5,0x62671f00,0x2570dfff,0x88e084bd,0x2b3bfb78,0xf37fe5b4,0xa024b238,0x95649aee,0x44e7dc04,0x5e7ec1d8,0x498ca255 +.long 0xaaa07e86,0x3bc766ea,0xf3608586,0x0db6facb,0xbdc259c8,0xbadd2549,0x041c649f,0x95af3c6e,0x02e30afb,0xb36a928c,0x008a88b8,0x9b5356ad,0xcf1d9e9d,0x4b67a5f1,0xa5d8d8ce,0xc6542e47 +.long 0x7adfb6cc,0x73061fe8,0x98678141,0xcc826fd3,0x3c80515a,0x00e758b1,0x41485083,0x6afe3247,0xb6ae8a75,0x0fcb08b9,0x4acf51e1,0xb8cf388d,0x6961b9d6,0x344a5560,0x6a97fd0c,0x1a6778b8 +.long 0xecc4c7e3,0xd840fdc1,0x16db68cc,0xde9fe47d,0xa3e216aa,0xe95f89de,0x9594a8be,0x84f1a6a4,0x5a7b162b,0x7ddc7d72,0xadc817a3,0xc5cfda19,0x78b58d46,0x80a5d350,0x82978f19,0x93365b13 +.long 0x26a1fc90,0x2e44d225,0x4d70705d,0x0d6d10d2,0xd70c45f4,0xd94b6b10,0xb216c079,0x0f201022,0x658fde41,0xcec966c5,0x7e27601d,0xa8d2bc7d,0xff230be7,0xbfcce3e1,0x0033ffb5,0x3394ff6b +.long 0x8132c9af,0xd890c509,0x361e7868,0xaac4b0eb,0xe82d15aa,0x5194ded3,0x23ae6b7d,0x4550bd2e,0xea5399d4,0x3fda318e,0x91638b80,0xd989bffa,0xa14aa12d,0x5ea124d0,0x3667b944,0x1fb1b899 +.long 0x44c44d6a,0x95ec7969,0x57e86137,0x91df144a,0x73adac44,0x915fd620,0x59a83801,0x8f01732d,0x3aa0a633,0xec579d25,0xc9d6d59c,0x06de5e7c,0xb1ef8010,0xc132f958,0xe65c1a02,0x29476f96 +.long 0xd34c3565,0x336a77c0,0x1b9f1e9e,0xef1105b2,0xf9e08002,0x63e6d08b,0xc613809e,0x9aff2f21,0x3a80e75d,0xb5754f85,0x6bbda681,0xde71853e,0x8197fd7a,0x86f041df,0x127817fa,0x8b332e08 +.long 0xb9c20cda,0x05d99be8,0xd5cd0c98,0x89f7aad5,0x5bb94183,0x7ef936fe,0xb05cd7f2,0x92ca0753,0x74a1e035,0x9d65db11,0x13eaea92,0x02628cc8,0x49e4fbf2,0xf2d9e242,0xe384f8b7,0x94fdfd9b +.long 0x63428c6b,0x65f56054,0x90b409a5,0x2f7205b2,0xff45ae11,0xf778bb78,0xc5ee53b2,0xa13045be,0x03ef77fe,0xe00a14ff,0xffef8bef,0x689cd59f,0x1e9ade22,0x3578f0ed,0x6268b6a8,0xe99f3ec0 +.long 0xea1b3c3e,0xa2057d91,0xb8823a4a,0x2d1a7053,0x2cca451e,0xabbb336a,0x2218bb5d,0xcd2466e3,0xc8cb762d,0x3ac1f42f,0x7690211f,0x7e312aae,0x45d07450,0xebb9bd73,0x46c2213f,0x207c4b82 +.long 0x375913ec,0x99d425c1,0x67908220,0x94e45e96,0xcd67dbf6,0xc08f3087,0xc0887056,0xa5670fbe,0x66f5b8fc,0x6717b64a,0x786fec28,0xd5a56aea,0xc0ff4952,0xa8c3f55f,0x457ac49b,0xa77fefae +.long 0x98379d44,0x29882d7c,0x509edc8a,0xd000bdfb,0xe66fe464,0xc6f95979,0xfa61bde0,0x504a6115,0xeffea31a,0x56b3b871,0xf0c21a54,0x2d3de26d,0x834753bf,0x21dbff31,0x69269d86,0xe67ecf49 +.long 0x151fe690,0x7a176952,0x7f2adb5f,0x03515804,0xd1b62a8d,0xee794b15,0xaae454e6,0xf004ceec,0xf0386fac,0x0897ea7c,0xd1fca751,0x3b62ff12,0x1b7a04ec,0x154181df,0xfb5847ec,0x2008e04a +.long 0x41dbd772,0xd147148e,0x22942654,0x2b419f73,0xe9c544f7,0x669f30d3,0xc8540149,0x52a2c223,0x634dfb02,0x5da9ee14,0xf47869f3,0x5f074ff0,0xa3933acc,0x74ee878d,0x4fe35ed1,0xe6510651 +.long 0xf1012e7a,0xb3eb9482,0xa8a566ae,0x51013cc0,0x47c00d3b,0xdd5e9243,0x946bb0e5,0x7fde089d,0xc731b4b3,0x030754fe,0x99fda062,0x12a136a4,0x5a1a35bc,0x7c1064b8,0x446c84ef,0xbf1f5763 +.long 0xa16d4b34,0xed29a56d,0xdca21c4f,0x7fba9d09,0x6d8de486,0x66d7ac00,0x73a2a5e1,0x60061987,0x9da28ff0,0x8b400f86,0x43c4599c,0x3133f708,0xee28cb0d,0x9911c9b8,0x8e0af61d,0xcd7e2874 +.long 0x72ed91fc,0x5a85f0f2,0x9cd4a373,0x85214f31,0x1925253c,0x881fe5be,0x91e8bc76,0xd8dc98e0,0x585cc3a2,0x7120affe,0x735bf97a,0x724952ed,0x3eb34581,0x5581e7dc,0xe52ee57d,0x5cbff4f2 +.long 0x87d8cc7b,0x8d320a0e,0xf1d280d0,0x9beaa7f3,0x9beec704,0x7a0b9571,0x5b7f0057,0x9126332e,0x8ed3bd6d,0x01fbc1b4,0xd945eb24,0x35bb2c12,0x9a8ae255,0x6404694e,0x8d6abfb3,0xb6092eec +.long 0xcc058865,0x4d76143f,0x6e249922,0x7b0a5af2,0x6a50d353,0x8aef9440,0x64f0e07a,0xe11e4bcc,0xa14a90fa,0x4472993a,0xba0c51d4,0x7706e20c,0x1532672d,0xf403292f,0x21829382,0x52573bfa +.long 0x3b5bdb83,0x6a7bb6a9,0xa4a72318,0x08da65c0,0x63eb065f,0xc58d22aa,0x1b15d685,0x1717596c,0xb266d88b,0x112df0d0,0x5941945a,0xf688ae97,0x7c292cac,0x487386e3,0x57d6985c,0x42f3b50d +.long 0x6a90fc34,0x6da4f998,0x65ca8a8d,0xc8f257d3,0x6951f762,0xc2feabca,0x74c323ac,0xe1bc81d0,0x251a2a12,0x1bc68f67,0xbe8a70dc,0x10d86587,0xf0f84d2e,0xd648af7f,0x6a43ac92,0xf0aa9ebc +.long 0x27596893,0x69e3be04,0x45bf452b,0xb6bb02a6,0xf4c698c8,0x0875c11a,0xbece3794,0x6652b5c7,0x4f5c0499,0x7b3755fd,0xb5532b38,0x6ea16558,0xa2e96ef7,0xd1c69889,0x61ed8f48,0x9c773c3a +.long 0x9b323abc,0x2b653a40,0xf0e1d791,0xe26605e1,0x4a87157a,0x45d41064,0xcbbce616,0x8f9a78b7,0xc407eddd,0xcf1e44aa,0xa35b964f,0x81ddd1d8,0xfd083999,0x473e339e,0x8e796802,0x6c94bdde +.long 0x8545d185,0x5a304ada,0x738bb8cb,0x82ae44ea,0xdf87e10e,0x628a35e3,0xa15b9fe3,0xd3624f3d,0x14be4254,0xcc44209b,0xbdbc2ea5,0x7d0efcbc,0x04c37bbe,0x1f603362,0x56a5852c,0x21f363f5 +.long 0xa8501550,0xa1503d1c,0xd8ab10bb,0x2251e0e1,0x6961c51c,0xde129c96,0x81910f68,0x1f7246a4,0x5f2591f2,0x2eb744ee,0x5e627157,0x3c47d33f,0x22f3bd68,0x4d6d62c9,0xcb8df856,0x6120a64b +.long 0x7b5d07df,0x3a9ac6c0,0x7ef39783,0xa92b9558,0xab3a9b4f,0xe128a134,0xb1252f05,0x41c18807,0x80ba9b1c,0xfc7ed089,0xc532a9dd,0xac8dc6de,0x55246809,0xbf829cef,0x5b4ee80f,0x101b784f +.long 0xb6f11603,0xc09945bb,0x41d2801e,0x57b09dbe,0xa97534a8,0xfba5202f,0xc17b9614,0x7fd8ae5f,0x78308435,0xa50ba666,0xd3868c4d,0x9572f77c,0x2dd7aab0,0x0cef7bfd,0x2c7c79ff,0xe7958e08 +.long 0x25346689,0x81262e42,0xb07c7004,0x716da290,0xb7950ee3,0x35f911ea,0x261d21b5,0x6fd72969,0x08b640d3,0x52389803,0x887f12a1,0x5b0026ee,0x742e9311,0x20e21660,0x5ff77ff7,0x0ef6d541 +.long 0xf9c41135,0x969127f0,0x68a64993,0xf21d60c9,0xe541875c,0x656e5d0c,0xa1d3c233,0xf1e0f84e,0x06002d60,0x9bcca359,0x06191552,0xbe2da60c,0x61181ec3,0x5da8bbae,0x65806f19,0x9f04b823 +.long 0xd4b79bb8,0xf1604a7d,0x52c878c8,0xaee806fb,0x8d47b8e8,0x34144f11,0x949f9054,0x72edf52b,0x2127015a,0xebfca84e,0x9cb7cef3,0x9051d0c0,0x296deec8,0x86e8fe58,0x41010d74,0x33b28188 +.long 0x171b445f,0x01079383,0x8131ad4c,0x9bcf21e3,0xc93987e8,0x8cdfe205,0xc92e8c8f,0xe63f4152,0x30add43d,0x729462a9,0xc980f05a,0x62ebb143,0x3b06e968,0x4f3954e5,0x242cf6b1,0xfe1d75ad +.long 0xaf8685c8,0x5f95c6c7,0x2f8f01aa,0xd4c1c8ce,0x2574692a,0xc44bbe32,0xd4a4a068,0xb8003478,0x2eca3cdb,0x7c8fc6e5,0xec04d399,0xea1db16b,0x8f2bc5cf,0xb05bc82e,0xf44793d2,0x763d517f +.long 0x08bd98d0,0x4451c1b8,0x6575f240,0x644b1cd4,0x7375d270,0x6907eb33,0xfa2286bd,0x56c8bebd,0xc4632b46,0xc713d2ac,0xafd60242,0x17da427a,0xc95c7546,0x313065b7,0xbf17a3de,0xf8239898 +.long 0x4c830320,0xf3b7963f,0x903203e3,0x842c7aa0,0xe7327afb,0xaf22ca0a,0x967609b6,0x38e13092,0x757558f1,0x73b8fb62,0xf7eca8c1,0x3cc3e831,0xf6331627,0xe4174474,0xc3c40234,0xa77989ca +.long 0x44a081e0,0xe5fd17a1,0xb70e296a,0xd797fb7d,0x481f719c,0x2b472b30,0xfe6f8c52,0x0e632a98,0xc5f0c284,0x89ccd116,0x2d987c62,0xf51088af,0x4c2de6cf,0x2a2bccda,0xf679f0f9,0x810f9efe +.long 0x7ffe4b3e,0xb0f394b9,0xe5fa5d21,0x0b691d21,0x9dfbbc75,0xb0bd7747,0xfaf78b00,0xd2830fda,0x52434f57,0xf78c249c,0x98096dab,0x4b1f7545,0x8ff8c0b3,0x73bf6f94,0x454e134c,0x34aef03d +.long 0xb7ac7ec5,0xf8d151f4,0xe50da7d5,0xd6ceb95a,0xdc3a0eb8,0xa1b492b0,0xb3dd2863,0x75157b69,0xc5413d62,0xe2c4c74e,0xbc5fc4c7,0xbe329ff7,0x60fa9dda,0x835a2aea,0x7445cb87,0xf117f5ad +.long 0xb0166f7a,0xae8317f4,0xceec74e6,0xfbd3e3f7,0xe0874bfd,0xfdb516ac,0xc681f3a3,0x3d846019,0x7c1620b0,0x0b12ee5c,0x2b63c501,0xba68b4dd,0x6668c51e,0xac03cd32,0x4e0bcb5b,0x2a6279f7 +.long 0x6ae85c10,0x17bd69b0,0x1dfdd3a6,0x72946979,0x2c078bec,0xd9a03268,0xbfd68a52,0x41c6a658,0x0e023900,0xcdea1024,0xb10d144d,0xbaeec121,0x058ab8dc,0x5a600e74,0xbb89ccdd,0x1333af21 +.long 0x3aaba1f1,0xdf25eae0,0x3b7144cf,0x2cada16e,0x71ab98bc,0x657ee27d,0x7a6fc96e,0x99088b4c,0x3549dbd4,0x05d5c0a0,0xf158c3ac,0x42cbdf8f,0x87edd685,0x3fb6b3b0,0x86f064d0,0x22071cf6 +.long 0xff2811e5,0xd2d6721f,0xfe7fae8c,0xdb81b703,0xd3f1f7bb,0x3cfb74ef,0x16cdeb5d,0x0cdbcd76,0x566a808c,0x4f39642a,0x340064d6,0x02b74454,0x0528fa6f,0xfabbadca,0xd3fc0bb6,0xe4c3074c +.long 0xb796d219,0xb32cb8b0,0x34741dd9,0xc3e95f4f,0x68edf6f5,0x87212125,0xa2b9cb8e,0x7a03aee4,0xf53a89aa,0x0cd3c376,0x948a28dc,0x0d8af9b1,0x902ab04f,0xcf86a3f4,0x7f42002d,0x8aacb62a +.long 0xf62ffd52,0x106985eb,0x5797bf10,0xe670b54e,0xc5e30aef,0x4b405209,0x4365b5e9,0x12c97a20,0x1fe32093,0x104646ce,0x3907a8c9,0x13cb4ff6,0xd46e726b,0x8b9f30d1,0xaba0f499,0xe1985e21 +.long 0x10a230cd,0xc573dea9,0xcd30f947,0x24f46a93,0xabe2010a,0xf2623fcf,0x73f00e4f,0x3f278cb2,0x50b920eb,0xed55c67d,0x8e760571,0xf1cb9a2d,0x0895b709,0x7c50d109,0x190d4369,0x4207cf07 +.long 0xc4127fe1,0x3b027e81,0x3ae9c566,0xa9f8b9ad,0xacbfbba5,0x5ab10851,0x569556f5,0xa747d648,0x2ba97bf7,0xcc172b5c,0xbcfa3324,0x15e0f77d,0x7686279d,0xa345b797,0xe38003d3,0x5a723480 +.long 0x8f5fcda8,0xfd8e139f,0xbdee5bfd,0xf3e558c4,0xe33f9f77,0xd76cbaf4,0x71771969,0x3a4c97a4,0xf6dce6a7,0xda27e84b,0x13e6c2d1,0xff373d96,0xd759a6e9,0xf115193c,0x63d2262c,0x3f9b7025 +.long 0x317cd062,0xd9764a31,0x199f8332,0x30779d8e,0x16b11b0b,0xd8074106,0x78aeaed8,0x7917ab9f,0x28fb1d8e,0xb67a9cbe,0x136eda33,0x2e313563,0xa371a86c,0x010b7069,0x6744e6b7,0x44d90fa2 +.long 0xd6b3e243,0x68190867,0x59048c48,0x9fe6cd9d,0x95731538,0xb900b028,0x32cae04f,0xa012062f,0x9399d082,0x8107c8bc,0x41df12e2,0x47e8c54a,0xb6ef3f73,0x14ba5117,0x81362f0b,0x22260bea +.long 0x1a18cc20,0x90ea261e,0x2321d636,0x2192999f,0xe311b6a0,0xef64d314,0x3b54a1f5,0xd7401e4c,0x6fbca2ba,0x19019983,0x8fbffc4b,0x46ad3293,0x3786bf40,0xa142d3f6,0xb67039fc,0xeb5cbc26 +.long 0x252bd479,0x9cb0ae6c,0x12b5848f,0x05e0f88a,0xa5c97663,0x78f6d2b2,0xc162225c,0x6f6e149b,0xde601a89,0xe602235c,0xf373be1f,0xd17bbe98,0xa8471827,0xcaf49a5b,0x18aaa116,0x7e1a0a85 +.long 0x270580c3,0x6c833196,0xf1c98a14,0x1e233839,0xae34e0a5,0x67b2f7b4,0xd8ce7289,0x47ac8745,0x100dd467,0x2b74779a,0x4ee50d09,0x274a4337,0x83608bc9,0x603dcf13,0xc89e8388,0xcd9da6c3 +.long 0x355116ac,0x2660199f,0xb6d18eed,0xcc38bb59,0x2f4bc071,0x3075f31f,0x265dc57e,0x9774457f,0xc6db88bb,0x06a6a9c8,0x4ec98e04,0x6429d07f,0x05ecaa8b,0x8d05e57b,0x7872ea7b,0x20f140b1 +.long 0xca494693,0xdf8c0f09,0xf252e909,0x48d3a020,0x57b14b12,0x4c5c29af,0xbf47ad1c,0x7e6fa37d,0x49a0c938,0x66e7b506,0x6be5f41f,0xb72c0d48,0xb2359412,0x6a6242b8,0x8e859480,0xcd35c774 +.long 0x87baa627,0x12536fea,0xf72aa680,0x58c1fec1,0x601e5dc9,0x6c29b637,0xde9e01b9,0x9e3c3c1c,0x2bcfe0b0,0xefc8127b,0x2a12f50d,0x35107102,0x4879b397,0x6ccd6cb1,0xf8a82f21,0xf792f804 +.long 0xa9b46402,0x509d4804,0xc10f0850,0xedddf85d,0x4b6208aa,0x928410dc,0x391012dc,0xf6229c46,0x7727b9b6,0xc5a7c41e,0xaa444842,0x289e4e4b,0xe9a947ea,0x049ba1d9,0x83c8debc,0x44f9e47f +.long 0x611f8b8e,0xfa77a1fe,0xf518f427,0xfd2e416a,0x114ebac3,0xc5fffa70,0x5d89697b,0xfe57c4e9,0xb1aaf613,0xfdd053ac,0xea585a45,0x31df210f,0x24985034,0x318cc10e,0x5f1d6130,0x1a38efd1 +.long 0x0b1e9e21,0xbf86f237,0x1dbe88aa,0xb258514d,0x90c1baf9,0x1e38a588,0xbdb9b692,0x2936a01e,0x6dd5b20c,0xd576de98,0x70f98ecf,0xb586bf71,0xc42d2fd7,0xcccf0f12,0xfb35bd7b,0x8717e61c +.long 0x35e6fc06,0x8b1e5722,0x0b3e13d5,0x3477728f,0xaa8a7372,0x150c294d,0x3bfa528a,0xc0291d43,0xcec5a196,0xc6c8bc67,0x5c2e8a7c,0xdeeb31e4,0xfb6e1c51,0xba93e244,0x2e28e156,0xb9f8b71b +.long 0x968a2ab9,0xce65a287,0x46bbcb1f,0xe3c5ce69,0xe7ae3f30,0xf8c835b9,0xff72b82b,0x16bbee26,0xfd42cd22,0x665e2017,0xf8b1d2a0,0x1e139970,0x79204932,0x125cda29,0x49c3bee5,0x7aee94a5 +.long 0x89821a66,0x68c70160,0x8f981669,0xf7c37678,0x48cc3645,0xd90829fc,0xd70addfc,0x346af049,0x370bf29c,0x2057b232,0x42e650ee,0xf90c73ce,0xa126ab90,0xe03386ea,0x975a087b,0x0e266e7e +.long 0x0fca65d9,0x80578eb9,0x16af45b8,0x7e2989ea,0xcac75a4e,0x7438212d,0x4fef36b8,0x38c7ca39,0xd402676a,0x8650c494,0xf72c7c48,0x26ab5a66,0xce3a464e,0x4e6cb426,0x2b72f841,0xf8f99896 +.long 0x1a335cc8,0x8c318491,0x6a5913e4,0x563459ba,0xc7b32919,0x1b920d61,0xa02425ad,0x805ab8b6,0x8d006086,0x2ac512da,0xbcf5c0fd,0x6ca4846a,0xac2138d7,0xafea51d8,0x344cd443,0xcb647545 +.long 0xbd7d9040,0x0429ee8f,0x819b9c96,0xee66a2de,0xdea7d744,0x54f9ec25,0x671721bb,0x2ffea642,0x114344ea,0x4f19dbd1,0xfd0dbc8b,0x04304536,0x29ec7f91,0x014b50aa,0xbb06014d,0xb5fc22fe +.long 0x1ee682e0,0x60d963a9,0xfe85c727,0xdf48abc0,0x2e707c2d,0x0cadba13,0xa645aeff,0xde608d3a,0xedafd883,0x05f1c28b,0xbd94de1f,0x3c362ede,0x13593e41,0x8dd0629d,0x766d6eaf,0x0a5e736f +.long 0xf68cf9d1,0xbfa92311,0xc1797556,0xa4f9ef87,0x5601c209,0x10d75a1f,0x09b07361,0x651c374c,0x88b5cead,0x49950b58,0x6fa9dbaa,0x0ef00058,0x4e15f33a,0xf51ddc26,0x2ef46140,0x1f8b5ca6 +.long 0xee9523f0,0x343ac0a3,0x975ea978,0xbb75eab2,0x107387f4,0x1bccf332,0x9ab0062e,0x790f9259,0x1e4f6a5f,0xf1a363ad,0x62519a50,0x06e08b84,0x7265f1ee,0x60915187,0x93ae985e,0x6a80ca34 +.long 0xaaba4864,0x81b29768,0x8d52a7d6,0xb13cabf2,0x8ead03f1,0xb5c36348,0x81c7c1c0,0xc932ad95,0xcae1e27b,0x5452708e,0x1b0df648,0x9dac4269,0xdfcdb8bc,0x233e3f0c,0xec540174,0xe6ceccdf +.long 0x95081181,0xbd0d845e,0x699355d5,0xcc8a7920,0xc3b375a8,0x111c0f6d,0xfd51e0dc,0xfd95bc6b,0x6888523a,0x4a106a26,0xcb01a06d,0x4d142bd6,0xadb9b397,0x79bfd289,0xe9863914,0x0bdbfb94 +.long 0x1660f6a6,0x29d8a229,0x551c042d,0x7f6abcd6,0x0ac3ffe8,0x13039deb,0xec8523fb,0xa01be628,0x0ca1c328,0x6ea34103,0xb903928e,0xc74114bd,0x9e9144b0,0x8aa4ff4e,0x7f9a4b17,0x7064091f +.long 0xe447f2c4,0xa3f4f521,0x604291f0,0x81b8da7a,0x7d5926de,0xd680bc46,0x34a1202f,0x84f21fd5,0x4e9df3d8,0x1d1e3181,0x39ab8d34,0x1ca4861a,0x5b19aa4a,0x809ddeec,0x4d329366,0x59f72f7e +.long 0x386d5087,0xa2f93f41,0xdd67d64f,0x40bf739c,0x66702158,0xb4494205,0x73b1e178,0xc33c65be,0x38ca6153,0xcdcd657c,0xdc791976,0x97f4519a,0xcd6e1f39,0xcc7c7f29,0x7e3c3932,0x38de9cfb +.long 0x7b793f85,0xe448eba3,0xf067e914,0xe9f8dbf9,0xf114ae87,0xc0390266,0xcd6a8e2a,0x39ed75a7,0x7ffba390,0xadb14848,0x6af9bc09,0x67f8cb8b,0x9c7476db,0x322c3848,0x52a538d6,0xa320fecf +.long 0xb2aced2b,0xe0493002,0x616bd430,0xdfba1809,0xc331be70,0x531c4644,0x90d2e450,0xbc04d32e,0x0f9f142d,0x1805a0d1,0x47ee5a23,0x2c44a0c5,0x3989b4e3,0x31875a43,0x0c063481,0x6b1949fd +.long 0xbe0f4492,0x2dfb9e08,0xe9d5e517,0x3ff0da03,0xf79466a8,0x03dbe9a1,0x15ea9932,0x0b87bcd0,0xab1f58ab,0xeb64fc83,0x817edc8a,0x6d9598da,0x1d3b67e5,0x699cff66,0x92635853,0x645c0f29 +.long 0xeabaf21c,0x253cdd82,0x2241659e,0x82b9602a,0x2d9f7091,0x2cae07ec,0x8b48cd9b,0xbe4c720c,0x6f08d6c9,0x6ce5bc03,0xaf10bf40,0x36e8a997,0x3e10ff12,0x83422d21,0xbcc12494,0x7b26d3eb +.long 0xc9469ad6,0xb240d2d0,0x30afa05b,0xc4a11b4d,0xdd6ba286,0x4b604ace,0x3ee2864c,0x18486600,0x8d9ce5be,0x5869d6ba,0xff4bfb0d,0x0d8f68c5,0x5700cf73,0xb69f210b,0x6d37c135,0x61f6653a +.long 0x5aff5a48,0xff3d432b,0x72ba3a69,0x0d81c4b9,0xfa1899ef,0xee879ae9,0x2d6acafd,0xbac7e2a0,0x1c664399,0xd6d93f6c,0x5bcb135d,0x4c288de1,0x9dab7cbf,0x83031dab,0x3abbf5f0,0xfe23feb0 +.long 0xcdedca85,0x9f1b2466,0x1a09538c,0x140bb710,0x5e11115d,0xac8ae851,0x6f03f59e,0x0d63ff67,0x7d234afb,0x755e5551,0x7e208fc1,0x61c2db4e,0xf28a4b5d,0xaa9859ce,0x34af030f,0xbdd6d4fc +.long 0x3be01cb1,0xd1c4a26d,0x243aa07c,0x9ba14ffc,0xb2503502,0xf95cd3a9,0x7d2a93ab,0xe379bc06,0xd4ca8d68,0x3efc18e9,0x80bb412a,0x083558ec,0x9645a968,0xd903b940,0x9ba6054f,0xa499f0b6 +.long 0xb8349abe,0x208b573c,0x30b4fc1c,0x3baab3e5,0xcb524990,0x87e978ba,0xccdf0e80,0x3524194e,0x7d4bcc42,0x62711725,0xb90109ba,0xe90a3d9b,0x1323e1e0,0x3b1bdd57,0x5eae1599,0xb78e9bd5 +.long 0x9e03d278,0x0794b746,0xd70e6297,0x80178605,0x99c97855,0x171792f8,0xf5a86b5c,0x11b393ee,0xd8884f27,0x48ef6582,0xbf19ba5f,0xbd44737a,0xa42062c6,0x8698de4c,0x61ce9c54,0x8975eb80 +.long 0xd7fe71f3,0xd50e57c7,0xbc97ce38,0x15342190,0x4df07b63,0x51bda2de,0x200eb87d,0xba12aeae,0xa9b4f8f6,0xabe135d2,0xfad6d99c,0x04619d65,0x7994937c,0x4a6683a7,0x6f94f09a,0x7a778c8b +.long 0x20a71b89,0x8c508623,0x1c229165,0x241a2aed,0xaaf83a99,0x352be595,0x1562bac8,0x9fbfee7f,0x5c4017e3,0xeaf658b9,0x15120b86,0x1dc7f9e0,0x4c034d6f,0xd84f13dd,0xeaea3038,0x283dd737 +.long 0xcd85d6a2,0x197f2609,0xfae60177,0x6ebbc345,0x4e12fede,0xb80f031b,0x07a2186b,0xde55d0c2,0x24dcdd5a,0x1fb3e37f,0x7ed191fb,0x8d602da5,0x76023e0d,0x108fb056,0x459c20c0,0x70178c71 +.long 0x3fe54cf0,0xfad5a386,0x02bbb475,0xa4a3ec4f,0x919d94d7,0x1aa5ec20,0xa81e4ab3,0x5d3b63b5,0x5ad3d2af,0x7fa733d8,0xd1ac7a37,0xfbc586dd,0x40779614,0x282925de,0xe74a242a,0xfe0ffffb +.long 0x906151e5,0x3f39e67f,0x55e10649,0xcea27f5f,0xc17cf7b7,0xdca1d4e1,0x2fe2362d,0x0c326d12,0x7dd35df3,0x05f7ac33,0xc396dbdf,0x0c3b7639,0x03b7db1c,0x0912f5ac,0x5c9ed4a9,0x9dea4b70 +.long 0xaae3f639,0x475e6e53,0xfc278bac,0xfaba0e7c,0x9490375f,0x16f9e221,0xa5a7ed0a,0xaebf9746,0xf41ad5d6,0x45f9af3f,0xb2e99224,0x03c4623c,0xb3cf56aa,0x82c5bb5c,0x34567ed3,0x64311819 +.long 0x8be489ac,0xec57f211,0xb9a1104b,0x2821895d,0x6064e007,0x610dc875,0x5b20d0fe,0x8e526f3f,0x5b645aee,0x6e71ca77,0x800e10ff,0x3d1dcb9f,0x189cf6de,0x36b51162,0x6bb17353,0x2c5a3e30 +.long 0x2a6c6fbf,0xc186cd3e,0x4bf97906,0xa74516fa,0x279d6901,0x5b4b8f4b,0x2b573743,0x0c4e57b4,0xb6e386b6,0x75fdb229,0x99deac27,0xb46793fd,0xcf712629,0xeeec47ea,0xcbc3b2dd,0xe965f3c4 +.long 0x425c6559,0x8dd1fb83,0x0af06fda,0x7fc00ee6,0x33d956df,0xe98c9225,0x4fbdc8a2,0x0f1ef335,0xb79b8ea2,0x2abb5145,0xbdbff288,0x40fd2945,0xd7185db7,0x6a814ac4,0xc084609a,0xc4329d6f +.long 0xed1be45d,0xc9ba7b52,0xe4cd2c74,0x891dd20d,0x824139b1,0x5a4d4a7f,0xb873c710,0x66c17716,0x2843c4e0,0x5e5bc141,0xb97eb5bf,0xd5ac4817,0x450c95c7,0xc0f8af54,0x318406c5,0xc91b3fa0 +.long 0xab9d97f8,0x360c340a,0x90a2d611,0xfb57bd07,0xa6a6f7e5,0x4339ae3c,0x2feb8a10,0x9c1fcd2a,0xc7ea7432,0x972bcca9,0x308076f6,0x1b0b924c,0x2a5b4ca5,0x80b2814a,0x61ef3b29,0x2f78f55b +.long 0xc18a414f,0xf838744a,0x903d0a86,0xc611eaae,0x2a453f55,0x94dabc16,0x14efb279,0xe6f2e3da,0x9320dc3c,0x5b7a6017,0x8df6b5a4,0x692e382f,0x2d40fa90,0x3f5e15e0,0x643dd318,0xc87883ae +.long 0x53544774,0x511053e4,0x3adba2bc,0x834d0ecc,0xbae371f5,0x4215d7f7,0x6c8663bc,0xfcfd57bf,0xd6901b1d,0xded2383d,0xb5587dc3,0x3b49fbb4,0x07625f62,0xfd44a08d,0x9de9b762,0x3ee4d65b +.long 0x0d63d1fa,0x64e5137d,0x02a9d89f,0x658fc052,0x50436309,0x48894874,0xd598da61,0xe9ae30f8,0x818baf91,0x2ed710d1,0x8b6a0c20,0xe27e9e06,0x1c1a6b44,0x1e28dcfb,0xd6ac57dc,0x883acb64 +.long 0xc2c6ff70,0x8735728d,0xc5dc2235,0x79d6122f,0x19e277f9,0x23f5d003,0xdded8cc7,0x7ee84e25,0x63cd880a,0x91a8afb0,0x3574af60,0x3f3ea7c6,0x02de7f42,0x0cfcdc84,0xb31aa152,0x62d0792f +.long 0x8a5807ce,0x8e1b4e43,0xe4109a7e,0xad283893,0xafd59dda,0xc30cc9cb,0x3d8d8093,0xf65f36c6,0xa60d32b2,0xdf31469e,0x3e8191c8,0xee93df4b,0x355bdeb5,0x9c1017c5,0x8616aa28,0xd2623185 +.long 0xdec31a21,0xb02c83f9,0x6ad9d573,0x988c8b23,0xa57be365,0x53e983ae,0x646f834e,0xe968734d,0x5da6309b,0x9137ea8f,0xc1f1ce16,0x10f3a624,0xca440921,0x782a9ea2,0x5b46f1b5,0xdf94739e +.long 0xcce85c9b,0x9f9be006,0xa4c7c2d3,0x360e70d6,0xaefa1e60,0x2cd5beea,0x8c3d2b6d,0x64cf63c0,0xe1cf6f90,0xfb107fa3,0xd5e044e6,0xb7e937c6,0xce34db9f,0x74e8ca78,0x3e210bd0,0x4f8b36c1 +.long 0x34a35ea8,0x1df165a4,0x4d4412f6,0x3418e0f7,0x518836c3,0x5af1f8af,0x130e1965,0x42ceef4d,0x543a1957,0x5560ca0b,0x886cb123,0xc33761e5,0xfe98ed30,0x66624b1f,0x1090997d,0xf772f4bf +.long 0x4885d410,0xf4e540bb,0x9ba5f8d7,0x7287f810,0xde98dfb1,0x22d0d865,0xbcfbb8a3,0x49ff51a1,0x6bc3012e,0xb6b6fa53,0x170d541d,0x3d31fd72,0x4b0f4966,0x8018724f,0x87dbde07,0x79e7399f +.long 0xf4f8b16a,0x56f8410e,0xc47b266a,0x97241afe,0x6d9c87c1,0x0a406b8e,0xcd42ab1b,0x803f3e02,0x04dbec69,0x7f0309a8,0x3bbad05f,0xa83b85f7,0xad8e197f,0xc6097273,0x5067adc1,0xc097440e +.long 0x3524ff16,0x730eafb6,0x823fc6ce,0xd7f9b51e,0x443e4ac0,0x27bd0d32,0x4d66f217,0x40c59ad9,0x17c387a4,0x6c33136f,0xeb86804d,0x5043b8d5,0x675a73c9,0x74970312,0xf16669b6,0x838fdb31 +.long 0x418e7ddd,0xc507b6dd,0x472f19d6,0x39888d93,0x0c27eb4d,0x7eae26be,0xfbabb884,0x17b53ed3,0x2b01ae4f,0xfc27021b,0xcf488682,0x88462e87,0x215e2d87,0xbee096ec,0xd242e29b,0xeb2fea9a +.long 0xb821fc28,0x5d985b5f,0xdc1e2ad2,0x89d2e197,0x9030ba62,0x55b566b8,0x4f41b1c6,0xe3fd41b5,0xb9a96d61,0xb738ac2e,0x369443f4,0x7f8567ca,0xf803a440,0x8698622d,0x8fe2f4dc,0x2b586236 +.long 0x56b95bce,0xbbcc00c7,0x616da680,0x5ec03906,0x72214252,0x79162ee6,0x86a892d2,0x43132b63,0x2f3263bf,0x4bdd3ff2,0x9cd0a142,0xd5b3733c,0x44415ccb,0x592eaa82,0x8d5474ea,0x663e8924 +.long 0x5236344e,0x8058a25e,0xbda76ee6,0x82e8df9d,0x11cc3d22,0xdcf6efd8,0x3b4ab529,0x00089cda,0xbd38a3db,0x91d3a071,0xef72b925,0x4ea97fc0,0xea3edf75,0x0c9fc15b,0xa4348ed3,0x5a6297cd +.long 0xce7c42d4,0x0d38ab35,0x82feab10,0x9fd493ef,0x82111b45,0x46056b6d,0x73efc5c3,0xda11dae1,0x5545a7fb,0xdc740278,0x40d507e6,0xbdb2601c,0x7066fa58,0x121dfeeb,0x39ae8c2a,0x214369a8 +.long 0x06e0956c,0x195709cb,0x010cd34b,0x4c9d254f,0x0471a532,0xf51e13f7,0x1e73054d,0xe19d6791,0xdb5c7be3,0xf702a628,0xb24dde05,0xc7141218,0xf29b2e2e,0xdc18233c,0x85342dba,0x3a6bd1e8 +.long 0xb311898c,0x3f747fa0,0xcd0eac65,0xe2a272e4,0xf914d0bc,0x4bba5851,0xc4a43ee3,0x7a1a9660,0xa1c8cde9,0xe5a367ce,0x7271abe3,0x9d958ba9,0x3d1615cd,0xf3ff7eb6,0xf5ae20b0,0xa2280dce +.long 0xcf640147,0x56dba5c1,0x5e83d118,0xea5a2e3d,0xda24c511,0x04cd6b6d,0xe854d214,0x1c0f4671,0x69565381,0x91a6b7a9,0xdecf1f5b,0xdc966240,0xfcf5d009,0x1b22d21c,0x9021dbd5,0x2a05f641 +.long 0xd4312483,0x8c0ed566,0x643e216f,0x5179a95d,0x17044493,0xcc185fec,0x54991a21,0xb3063339,0x0081a726,0xd801ecdb,0x4fa89bbb,0x0149b0c6,0x4391b6b9,0xafe9065a,0xd633f3a3,0xedc92786 +.long 0xae6a8e13,0xe408c24a,0x9f3897ab,0x85833fde,0xd81a0715,0x43800e7e,0xb44ffc5f,0xde08e346,0xcdeff2e0,0x7094184c,0x165eaed1,0x49f9387b,0x777c468a,0x635d6129,0x538c2dd8,0x8c0dcfd1 +.long 0x7a6a308b,0xd6d9d9e3,0x4c2767d3,0x62375830,0xf38cbeb6,0x874a8bc6,0xccb6fd9e,0xd94d3f1a,0xba21f248,0x92a9735b,0x6cd1efb0,0x272ad0e5,0x05b03284,0x7437b69c,0x6948c225,0xe7f04702 +.long 0xcba2ecec,0x8a56c04a,0xe3a73e41,0x0c181270,0x03e93725,0x6cb34e9d,0x496521a9,0xf77c8713,0xfa7f9f90,0x94569183,0x8c9707ad,0xf2e7aa4c,0x26c1c9a3,0xced2c9ba,0x40197507,0x9109fe96 +.long 0xe9adfe1c,0x9ae868a9,0x314e39bb,0x3984403d,0xf2fe378f,0xb5875720,0xba44a628,0x33f901e0,0x3652438c,0xea1125fe,0x9dd1f20b,0xae9ec4e6,0xbebf7fbd,0x1e740d9e,0x42dbe79c,0x6dbd3ddc +.long 0xedd36776,0x62082aec,0xe9859039,0xf612c478,0x032f7065,0xa493b201,0x4ff9b211,0xebd4d8f2,0xaac4cb32,0x3f23a0aa,0x15ed4005,0xea3aadb7,0xafa27e63,0xacf17ea4,0xc11fd66c,0x56125c1a +.long 0x3794f8dc,0x266344a4,0x483c5c36,0xdcca923a,0x3f9d10a0,0x2d6b6bbf,0x81d9bdf3,0xb320c5ca,0x47b50a95,0x620e28ff,0xcef03371,0x933e3b01,0x99100153,0xf081bf85,0xc3a8c8d6,0x183be9a0 +.long 0xd6bbe24d,0x4e3ddc5a,0x53843795,0xc6c74630,0x65ec2d4c,0x78193dd7,0xcd3c89b2,0xb8df26cc,0x5a483f8d,0x98dbe399,0x7dd3313a,0x72d8a957,0xab0bd375,0x65087294,0x7c259d16,0xfcd89248 +.long 0x7613aa81,0x8a9443d7,0x85fe6584,0x80100800,0x7fb10288,0x70fc4dbc,0xe86beee8,0xf58280d3,0x7c978c38,0x14fdd82f,0x0de44d7b,0xdf1204c1,0x4160252f,0xa08a1c84,0xc17646a5,0x591554ca +.long 0xa05bd525,0x214a37d6,0x07957b3c,0x48d5f09b,0xd7109bc9,0x0247cdcb,0x30599ce7,0x40f9e4bb,0xf46ad2ec,0xc325fa03,0xc3e3f9ee,0x00f766cf,0xd43a4577,0xab556668,0x3ee03b93,0x68d30a61 +.long 0x77b46a08,0x7ddc81ea,0xc7480699,0xcf5a6477,0x6633f683,0x43a8cb34,0x92363c60,0x1b867e6b,0x1f60558e,0x43921114,0x2f41450e,0xcdbcdd63,0xcc630e8b,0x7fc04601,0x97038b43,0xea7c66d5 +.long 0x04e99fd8,0x7259b8a5,0x4785549a,0x98a8dd12,0x840552e1,0x0e459a7c,0x4bb0909e,0xcdfcf4d0,0x53758da7,0x34a86db2,0xeac997e1,0xe643bb83,0x530c5b7e,0x96400bd7,0xb41c8b52,0x9f97af87 +.long 0xfbeee3f9,0x34fc8820,0x49091afd,0x93e53490,0x9a31f35c,0x764b9be5,0x57e3d924,0x71f37864,0x943aa75e,0x02fb34e0,0xab8ff6e4,0xa18c9c58,0x33cf0d19,0x080f31b1,0x083518a7,0x5c9682db +.long 0xb709c3de,0x873d4ca6,0x3575b8f0,0x64a84262,0x020154bb,0x6275da1f,0xd17cf1ab,0x97678caa,0x951a95c3,0x8779795f,0x50fccc08,0xdd35b163,0x33d8f031,0x32709627,0x498dd85c,0x3c5ab10a +.long 0x41dca566,0xb6c185c3,0xd8622aa3,0x7de7feda,0x901b6dfb,0x99e84d92,0x7c4ad288,0x30a02b0e,0x2fd3cf36,0xc7c81daa,0xdf89e59f,0xd1319547,0xcd496733,0xb2be8184,0x93d3412b,0xd5f449eb +.long 0x25fe531d,0x7ea41b1b,0x6a1d5646,0xf9797432,0x2bde501a,0x86067f72,0x0c85e89c,0xf91481c0,0xf8b05bc6,0xca8ee465,0x02e83cda,0x1844e1cf,0xb4dbe33b,0xca82114a,0x4eabfde2,0x0f9f8769 +.long 0x38b27fe2,0x4936b1c0,0xaba402df,0x63b6359b,0x656bdbab,0x40c0ea2f,0x6580c39c,0x9c992a89,0x2a60aed1,0x600e8f15,0xe0bf49df,0xeb089ca4,0x2d42d99a,0x9c233d7d,0x4c6bc2fa,0x648d3f95 +.long 0xe1add3f3,0xdcc383a8,0x4f64a348,0xf42c0c6a,0x0030dbdb,0x2abd176f,0x7d6c215e,0x4de501a3,0x4b9a64bc,0x4a107c1f,0x2496cd59,0xa77f0ad3,0x7688dffb,0xfb78ac62,0x67937d8e,0x7025a2ca +.long 0xd1a8f4e7,0xfde8b2d1,0x7354927c,0xf5b3da47,0xd9205735,0xe48606a3,0xe177b917,0xac477cc6,0xa883239a,0xfb1f73d2,0xcc8b8357,0xe12572f6,0xfb1f4f86,0x9d355e9c,0xd9f3ec6e,0x89b795f8 +.long 0xb54398dc,0x27be56f1,0x3fedeed5,0x1890efd7,0x9c6d0140,0x62f77f1f,0x596f0ee4,0x7ef0e314,0xcc61dab3,0x50ca6631,0xf4866e4f,0x4a39801d,0xae363b39,0x66c8d032,0x2ead66aa,0x22c591e5 +.long 0xde02a53e,0x954ba308,0xd389f357,0x2a6c060f,0xfbf40b66,0xe6cfcde8,0xc6340ce1,0x8e02fc56,0x73adb4ba,0xe4957795,0xa7b03805,0x7b86122c,0x0c8e6fa6,0x63f83512,0x057d7804,0x83660ea0 +.long 0x21ba473c,0xbad79105,0xded5389d,0xb6c50bee,0xaa7c9bc0,0xee2caf4d,0x8c4e98a7,0xd97b8de4,0xab3bbddb,0xa9f63e70,0x2597815a,0x3898aabf,0xac15b3d9,0x7659af89,0x703ce784,0xedf7725b +.long 0xe085116b,0x25470fab,0x87285310,0x04a43375,0xe2bfd52f,0x4e39187e,0x7d9ebc74,0x36166b44,0xfd4b322c,0x92ad433c,0xba79ab51,0x726aa817,0xc1db15eb,0xf96eacd8,0x0476be63,0xfaf71e91 +.long 0x641fad98,0xdd69a640,0x29622559,0xb7995918,0xde4199dc,0x03c6daa5,0xad545eb4,0x92cadc97,0x256534e4,0x1028238b,0x8595409a,0x73e80ce6,0xd05dc59b,0x690d4c66,0x981dee80,0xc95f7b8f +.long 0xd856ac25,0xf4337014,0xac524dca,0x441bd9dd,0x5f0499f5,0x640b3d85,0xd5fda182,0x39cf84a9,0xb2aa95a0,0x04e7b055,0x0ddf1860,0x29e33f0a,0x423f6b43,0x082e74b5,0x0aaa2b0f,0x217edeb9 +.long 0x83cbea55,0x58b83f35,0xbc185d70,0xc485ee4d,0x1e5f6992,0x833ff03b,0xcf0c0dd5,0xb5b9b9cc,0x4e9e8a50,0x7caaee8e,0x6269dafd,0x462e907b,0xfbe791c6,0x6ed5cee9,0xed430790,0x68ca3259 +.long 0x13b5ba88,0x2b72bdf2,0x35ef0ac4,0x60294c8a,0x19b99b08,0x9c3230ed,0x6c2589aa,0x560fff17,0xd6770374,0x552b8487,0x9a56f685,0xa373202d,0x45f175d9,0xd3e7f907,0xd080d810,0x3c2f315f +.long 0x7b9520e8,0x1130e9dd,0x0af037b5,0xc078f9e2,0x1e9c104c,0x38cd2ec7,0xc472fe92,0x0f684368,0x6247e7ef,0xd3f1b5ed,0x396dfe21,0xb32d33a9,0x4a9aa2c2,0x46f59cf4,0xff0f7e41,0x69cd5168 +.long 0x4b3234da,0x3f59da0f,0xb4579ebe,0xcf0b0235,0x6d2476c7,0x6d1cbb25,0x9dc30f08,0x4f0837e6,0x906f6e98,0x9a4075bb,0xc761e7d1,0x253bb434,0x6e73af10,0xde2e645f,0x0c5f131c,0xb89a4060 +.long 0xb8cc037f,0xd12840c5,0x7405bb47,0x3d093a5b,0x206348b8,0x6202c253,0xc55a3ca7,0xbf5d57fc,0x8c3bef48,0x89f6c90c,0x5a0a960a,0x23ac7623,0x552b42ab,0xdfbd3d6b,0x132061f6,0x3ef22458 +.long 0xc97e6516,0xd74e9bda,0xc230f49e,0x88779360,0x1e74ea49,0xa6ec1de3,0x3fb645a2,0x581dcee5,0x8f483f14,0xbaef2391,0xd137d13b,0x6d2dddfc,0xd2743a42,0x54cde50e,0xe4d97e67,0x89a34fc5 +.long 0x12e08ce5,0x13f1f5b3,0xa7f0b2ca,0xa80540b8,0x01982805,0x854bcf77,0x233bea04,0xb8653ffd,0x02b0b4c9,0x8e7b8787,0x9acb170a,0x2675261f,0x930c14e5,0x061a9d90,0xdef0abea,0xb59b30e0 +.long 0x0200ec7d,0x1dc19ea6,0x0bce132b,0xb6f4a3f9,0xf13e27e0,0xb8d5de90,0x1fade16f,0xbaee5ef0,0xe4c6cf38,0x6f406aaa,0xd1369815,0xab4cfe06,0xefd550c6,0x0dcffe87,0x75ff7d39,0x9d4f59c7 +.long 0x51deb6ad,0xb02553b1,0xb1877749,0x812399a4,0xca6006e1,0xce90f71f,0xb02b6e77,0xc32363a6,0xdc36c64d,0x02284fbe,0xa7e1ae61,0x86c81e31,0xb909d94a,0x2576c7e5,0x818b2bb0,0x8b6f7d02 +.long 0x56faa38a,0xeca3ed07,0x9305bb54,0xa3790e6c,0x7bc73061,0xd784eeda,0x6dd50614,0xbd56d369,0x229a8aa9,0xd6575949,0x4595ec28,0xdcca8f47,0x06ab4fe6,0x814305c1,0x24f43f16,0xc8c39768 +.long 0x523f2b36,0xe2a45f36,0x920d93bb,0x995c6493,0x90f1632b,0xf8afdab7,0x1c295954,0x79ebbecd,0x79592f48,0xc7bb3ddb,0x5f88e998,0x67216a7b,0xbc01193e,0xd91f098b,0xb1db83fc,0xf7d928a5 +.long 0xe991f600,0x55e38417,0x2981a934,0x2a91113e,0x06b13bde,0xcbc9d648,0x0755ff44,0xb011b6ac,0x045ec613,0x6f4cb518,0xc2f5930a,0x522d2d31,0x382e65de,0x5acae1af,0x27bc966f,0x57643067 +.long 0x1c7193f0,0x5e12705d,0x3be8858e,0xf0f32f47,0x96c6dfc7,0x785c3d7d,0xbf31795d,0xd75b4a20,0x342659d4,0x91acf17b,0x44f0378f,0xe596ea34,0xce52129d,0x4515708f,0x79f2f585,0x17387e1e +.long 0x49dee168,0x72cfd2e9,0x3e2af239,0x1ae05223,0x1d94066a,0x009e75be,0x38abf413,0x6cca31c7,0x9bc49908,0xb50bd61d,0xf5e2bc1e,0x4a9b4a8c,0x946f83ac,0xeb6cc5f7,0xebffab28,0x27da93fc +.long 0x4821c8c5,0xea314c96,0xa83c15f4,0x8de49ded,0x7af33004,0x7a64cf20,0xc9627e10,0x45f1bfeb,0x54b9df60,0x878b0626,0xa95c0b33,0x5e4fdc3c,0xc2035d8e,0xe54a37ca,0x80f20b8c,0x9087cda9 +.long 0x8319ade4,0x36f61c23,0xde8cfdf8,0x766f287a,0x346f3705,0x48821948,0x16e4f4a2,0x49a7b853,0x5cedadfd,0xb9b3f8a7,0x8db2a815,0x8f562815,0x01f68f95,0xc0b7d554,0x688a208e,0x12971e27 +.long 0xd0ff34fc,0xc9f8b696,0x1222718c,0x20824de2,0x0c95284d,0x7213cf9f,0xdc158240,0xe2ad741b,0x54043ccf,0x0ee3a6df,0xd84412b3,0x16ff479b,0xdfc98af0,0xf6c74ee0,0x52fcd2fb,0xa78a169f +.long 0x99c930e9,0xd8ae8746,0x49e117a5,0x1d33e858,0x6624759f,0x7581fcb4,0x5bedc01d,0xde50644f,0xcaf3155e,0xbeec5d00,0xbc73e75f,0x672d66ac,0x270b01db,0x86b9d8c6,0x50f55b79,0xd249ef83 +.long 0x73978fe3,0x6131d6d4,0x754b00a1,0xcc4e4542,0x57dfcfe9,0x4e05df05,0x51ef6bf0,0x94b29cdd,0x9bc7edf2,0xe4530cff,0xd3da65f3,0x8ac236fd,0xc8eb0b48,0x0faf7d5f,0x660eb039,0x4d2de14c +.long 0x60430e54,0xc006bba7,0xda3289ab,0x10a2d0d6,0xd7979c59,0x9c037a5d,0xa116d944,0x04d1f3d3,0x8a0983cd,0x9ff22473,0xc883cabb,0x28e25b38,0x47a58995,0xe968dba5,0x774eebdf,0x2c80b505 +.long 0x4a953beb,0xee763b71,0x1642e7f6,0x502e223f,0x61d5e722,0x6fe4b641,0xdbef5316,0x9d37c5b0,0xf8330bc7,0x0115ed70,0x75a72789,0x139850e6,0xffceccc2,0x27d7faec,0x4fd9f7f6,0x3016a860 +.long 0x4cd8f64c,0xc492ec64,0x279d7b51,0x58a2d790,0x1fc75256,0x0ced1fc5,0x8f433017,0x3e658aed,0x05da59eb,0x0b61942e,0x0ddc3722,0xba3d60a3,0x742e7f87,0x7c311cd1,0xf6b01b6e,0x6473ffee +.long 0x692ac542,0x8303604f,0x227b91d3,0xf079ffe1,0x15aaf9bd,0x19f63e63,0xf1f344fb,0xf99ee565,0xd6219199,0x8a1d661f,0xd48ce41c,0x8c883bc6,0x3c74d904,0x1065118f,0x0faf8b1b,0x713889ee +.long 0x81a1b3be,0x972b3f8f,0xce2764a0,0x4f3ce145,0x28c4f5f7,0xe2d0f1cc,0xc7f3985b,0xdeee0c0d,0xd39e25c3,0x7df4adc0,0xc467a080,0x40619820,0x61cf5a58,0x440ebc93,0x422ad600,0x527729a6 +.long 0xb1b76ba6,0xca6c0937,0x4d2026dc,0x1a2eab85,0x19d9ae0a,0xb1715e15,0xbac4a026,0xf1ad9199,0x07ea7b0e,0x35b3dfb8,0x3ed9eb89,0xedf5496f,0x2d6d08ab,0x8932e5ff,0x25bd2731,0xf314874e +.long 0x3f73f449,0xefb26a75,0x8d44fc79,0x1d1c94f8,0x3bc0dc4d,0x49f0fbc5,0x3698a0d0,0xb747ea0b,0x228d291e,0x5218c3fe,0x43c129d6,0x35b804b5,0xd1acc516,0xfac859b8,0x95d6e668,0x6c10697d +.long 0x0876fd4e,0xc38e438f,0x83d2f383,0x45f0c307,0xb10934cb,0x203cc2ec,0x2c9d46ee,0x6a8f2439,0x65ccde7b,0xf16b431b,0x27e76a6f,0x41e2cd18,0x4e3484d7,0xb9c8cf8f,0x8315244a,0x64426efd +.long 0xfc94dea3,0x1c0a8e44,0xdad6a0b0,0x34c8cdbf,0x04113cef,0x919c3840,0x15490ffa,0xfd32fba4,0x795dcfb7,0x58d190f6,0x83588baf,0xfef01b03,0xca1fc1c0,0x9e6d1d63,0xf0a41ac9,0x53173f96 +.long 0xba16f73b,0x2b1d402a,0x8cf9b9fc,0x2fb31014,0x446ef7bf,0x2d51e60e,0xb91e1745,0xc731021b,0x4fee99d4,0x9d3b4724,0xfac5c1ea,0x4bca48b6,0xbbea9af7,0x70f5f514,0x974c283a,0x751f55a5 +.long 0xcb452fdb,0x6e30251a,0x50f30650,0x31ee6965,0x933548d9,0xb0b3e508,0xf4b0ef5b,0xb8949a4f,0x3c88f3bd,0x208b8326,0xdb1d9989,0xab147c30,0x44d4df03,0xed6515fd,0xe72eb0c5,0x17a12f75 +.long 0x36cf69db,0x3b59796d,0x56670c18,0x1219eee9,0x7a070d8e,0xfe3341f7,0xa327f90c,0x9b70130b,0x0ae18e0e,0x36a32462,0x46c0a638,0x2021a623,0xc62eb0d4,0x251b5817,0x4c762293,0x87bfbcdf +.long 0xcdd61d64,0xf78ab505,0xc8c18857,0x8c7a53fc,0x16147515,0xa653ce6f,0xea7d52d5,0x9c923aa5,0x5c18871f,0xc24709cb,0x73b3cc74,0x7d53bec8,0xfdd1d4c4,0x59264aff,0x240da582,0x5555917e +.long 0x548f5a0e,0xcae8bbda,0x3bbfbbe1,0x1910eaba,0x7677afc3,0xae579685,0x73ff0b5c,0x49ea61f1,0x4f7c3922,0x78655478,0x20c68eef,0x95d337cd,0xdf779ab9,0x68f1e1e5,0xb5cf69a8,0x14b491b0 +.long 0x28e3fe89,0x7a6cbbe0,0xc5aac0eb,0xe7e1fee4,0x697e5140,0x7f47eda5,0xb454921f,0x4f450137,0x95cd8185,0xdb625f84,0xcdb2e583,0x74be0ba1,0xdd5e6de4,0xaee4fd7c,0xe8101739,0x4251437d +.long 0xac620366,0x686d72a0,0xb6d59344,0x4be3fb9c,0xa1eb75b9,0x6e8b44e7,0x91a5c10c,0x84e39da3,0xb38f0409,0x37cc1490,0x2c2ade82,0x02951943,0x1190a2d8,0x9b688783,0x231182ba,0x25627d14 +.long 0x658a6d87,0x6eb550aa,0xcf9c7325,0x1405aaa7,0x5c8748c9,0xd147142e,0x53ede0e0,0x7f637e4f,0x14ffad2c,0xf8ca2776,0xbafb6791,0xe58fb1bd,0xbf8f93fc,0x17158c23,0x0a4a4655,0x7f15b373 +.long 0xd842ca72,0x39d4add2,0x3ed96305,0xa71e4391,0x6700be14,0x5bb09cbe,0xd8befcf6,0x68d69d54,0x37183bcf,0xa45f5367,0x3370dff7,0x7152b7bb,0xbf12525b,0xcf887baa,0xd6d1e3cd,0xe7ac7bdd +.long 0x81fdad90,0x25914f78,0x0d2cf6ab,0xcf638f56,0xcc054de5,0xb90bc03f,0x18b06350,0x932811a7,0x9bbd11ff,0x2f00b330,0xb4044974,0x76108a6f,0xa851d266,0x801bb9e0,0xbf8990c1,0x0dd099be +.long 0xabe32986,0x58c5aaaa,0x50d59c27,0x0fe9dd2a,0x8d307305,0x84951ff4,0x86529b78,0x6c23f829,0x0b136a79,0x50bb2218,0x77a20996,0x7e2174de,0xc0bb4da6,0x6f00a4b9,0xefdde8da,0x89a25a17 +.long 0xc11ee01d,0xf728a27e,0xe5f10dfb,0xf900553a,0x02ec893c,0x189a83c8,0x23f66d77,0x3ca5bdc1,0x97eada9f,0x98781537,0x10256230,0x59c50ab3,0x323c69b3,0x346042d9,0x2c460449,0x1b715a6d +.long 0x6ae06e0b,0xa41dd476,0x9d42e25f,0xcdd7888e,0x56b25a20,0x0f395f74,0x8700e27e,0xeadfe0ae,0x69950093,0xb09d52a9,0x327f8d40,0x3525d9cb,0x67df886a,0xb8235a94,0x035faec2,0x77e4b0dd +.long 0x517d7061,0x115eb20a,0x6c2df683,0x77fe3433,0xcdc6fc67,0x6870ddc7,0x0b87de83,0xb1610588,0xd9c4ddbe,0x343584ca,0x3d754be2,0xb3164f1c,0xc1e6c894,0x0731ed3a,0x4f6b904c,0x26327dec +.long 0x97b5cd32,0x9d49c6de,0xb5eceecd,0x40835dae,0xd9ded7fe,0xc66350ed,0x7a678804,0x8aeebb5c,0x5b8ee9ec,0x51d42fb7,0x8e3ca118,0xd7a17bdd,0x2ef4400e,0x40d7511a,0x875a66f4,0xc48990ac +.long 0x2199e347,0x8de07d2a,0x2a39e051,0xbee75556,0x916e51dc,0x56918786,0x4a2d89ec,0xeb191313,0x37d341ed,0x6679610d,0x56d51c2b,0x434fbb41,0xd7492dba,0xe54b7ee7,0x59021493,0xaa33a79a +.long 0xe4bd6d3d,0x49fc5054,0x5ab551d0,0x09540f04,0x4942d3a6,0x8acc9085,0x2d28323b,0x231af02f,0x0992c163,0x93458cac,0x888e3bb4,0x1fef8e71,0xbe8c268c,0x27578da5,0xe805ec00,0xcc8be792 +.long 0xc61c3855,0x29267bae,0x58c1fd3b,0xebff429d,0x8c0b93b8,0x22d886c0,0x2ddb8953,0xca5e00b2,0xc3fed8b7,0xcf330117,0x819c01f6,0xd49ac6fa,0x3c0fbd54,0x6ddaa6bd,0x8049a2cf,0x91743068 +.long 0xaff2ef81,0xd67f981e,0x2818ae80,0xc3654d35,0x1b2aa892,0x81d05044,0x3d099328,0x2db067bf,0x703dcc97,0xe7c79e86,0xe133e215,0xe66f9b37,0xe39a7a5c,0xcdf119a6,0x876f1b61,0x47c60de3 +.long 0xd860f1b2,0x6e405939,0xf5ed4d4a,0x3e9a1dbc,0xc9b6bcbd,0x3f23619e,0x734e4497,0x5ee790cf,0x5bdaf9bb,0xf0a834b1,0x4ca295f0,0x02cedda7,0xcb8e378c,0x4619aa2b,0xcc987ea4,0xe5613244 +.long 0x76b23a50,0x0bc022cc,0x0a6c21ce,0x4a2793ad,0x89cac3f5,0x38328780,0xcba26d56,0x29176f1b,0x4f6f59eb,0x06296187,0x8bdc658e,0x86e9bca9,0x57e30402,0x2ca9c4d3,0x516a09bb,0x5438b216 +.long 0x7672765a,0x0a6a063c,0x0547b9bf,0x37a3ce64,0x98b1a633,0x42c099c8,0x05ee6961,0xb5ab800d,0x11a5acd6,0xf1963f59,0x46201063,0xbaee6157,0xa596210a,0x36d9a649,0x1ba7138c,0xaed04363 +.long 0xa4a82b76,0xcf817d1c,0xf3806be9,0x5586960e,0x09dc6bb5,0x7ab67c89,0x114fe7eb,0x52ace7a0,0xcbbc9b70,0xcd987618,0x604ca5e1,0x4f06fd5a,0x6dbde133,0x90af14ca,0x948a3264,0x1afe4322 +.long 0xc44b2c6c,0xa70d2ca6,0x0ef87dfe,0xab726799,0x2e696377,0x310f64dc,0x4c8126a0,0x49b42e68,0xcea0b176,0x0ea444c3,0xcb269182,0x53a8ddf7,0xbbba9dcb,0xf3e674eb,0xd8669d33,0x0d2878a8 +.long 0xd019b6a3,0x04b935d5,0x406f1e46,0xbb5cf88e,0x5b57c111,0xa1912d16,0x19ebfd78,0x9803fc21,0xc07764a9,0x4f231c9e,0xb75bd055,0xd93286ee,0x8ee6c9de,0x83a9457d,0x6087ec90,0x04695915 +.long 0x58d6cd46,0x14c6dd8a,0x8e6634d2,0x9cb633b5,0xf81bc328,0xc1305047,0x26a177e5,0x12ede0e2,0x065a6f4f,0x332cca62,0x67be487b,0xc3a47ecd,0x0f47ed1c,0x741eb187,0xe7598b14,0x99e66e58 +.long 0x63d0ff12,0x6f0544ca,0xb610a05f,0xe5efc784,0x7cad7b47,0xf72917b1,0xf2cac0c0,0x3ff6ea20,0xf21db8b7,0xcc23791b,0xd7d93565,0x7dac70b1,0x694bdaad,0x682cda1d,0x1023516d,0xeb88bb8c +.long 0xdfdbeb1b,0xc4c634b4,0xb4ee4dea,0x22f5ca72,0xe6524821,0x1045a368,0x052b18b2,0xed9e8a3f,0xb961f49a,0x9b7f2cb1,0x7b009670,0x7fee2ec1,0x22507a6d,0x350d8754,0x4db55f1d,0x561bd711 +.long 0x320bbcaf,0x4c189ccc,0xdf1de48c,0x568434cf,0x0fa8f128,0x6af1b00e,0x8907583c,0xf0ba9d02,0x32ff9f60,0x735a4004,0xc25dcf33,0x3dd8e4b6,0x42c74cef,0xf2230f16,0x013fa8ad,0xd8117623 +.long 0xf51fe76e,0x36822876,0x11d62589,0x8a6811cc,0x46225718,0xc3fc7e65,0xc82fdbcd,0xb7df2c9f,0xdd7b205b,0x3b1d4e52,0x47a2e414,0xb6959478,0xefa91148,0x05e4d793,0xfd2e9675,0xb47ed446 +.long 0x04c9d9bf,0x1a7098b9,0x1b793048,0x661e2881,0xb01ee461,0xb1a16966,0x2954746f,0xbc521308,0x2477de50,0xc909a0fc,0x7dbd51ef,0xd80bb41c,0x53294905,0xa85be7ec,0x83958f97,0x6d465b18 +.long 0xfb6840fd,0x16f6f330,0x3401e6c8,0xfaaeb214,0xccb5b4f8,0xaf83d30f,0x266dec4b,0x22885739,0x7bc467df,0x51b4367c,0xd842d27a,0x926562e3,0x0fea14a6,0xdfcb6614,0xf2734cd9,0xeb394dae +.long 0x11c0be98,0x3eeae5d2,0x814e8165,0xb1e6ed11,0xe52bce1c,0x191086bc,0xa75a04da,0x14b74cc6,0x8c060985,0x63cf1186,0x2dbd7f7c,0x071047de,0xce0942ca,0x4e433b8b,0xd8fec61d,0xecbac447 +.long 0xebf3232f,0x8f0ed0e2,0xc52a2edd,0xfff80f9e,0x75b55fdb,0xad9ab433,0xe42e0c11,0x73ca7820,0xe6251b46,0x6dace0a0,0x4c0d932d,0x89bc6b5c,0x095da19a,0x3438cd77,0x8d48bdfb,0x2f24a939 +.long 0x766561b7,0x99b47e46,0x0ed0322a,0x736600e6,0x638e1865,0x06a47cb1,0xcb136000,0x927c1c2d,0x0cc5df69,0x29542337,0x09d649a9,0x99b37c02,0x6aefdb27,0xc5f0043c,0x1be95c27,0x6cdd9987 +.long 0x390420d2,0x69850931,0x0983efa4,0x299c40ac,0xaf39aead,0x3a05e778,0x43a45193,0x84274408,0x91a711a0,0x6bcd0fb9,0x9f52ab17,0x461592c8,0xda3c6ed6,0xb49302b4,0x330d7067,0xc51fddc7 +.long 0xda50d531,0x94babeb6,0xa6a7b9da,0x521b840d,0x404bdc89,0x5305151e,0xd0d07449,0x1bcde201,0x3b76a59a,0xf427a78b,0x07791a1b,0xf84841ce,0xbf91ed1c,0xebd314be,0xbf172943,0x8e61d34c +.long 0x5541b892,0x1d5dc451,0xfc9d9e54,0xb186ee41,0xd5bf610d,0x9d9f345e,0xf6acca9f,0x3e7ba65d,0xa8369486,0x9dda787a,0x8eb5ba53,0x09f9dab7,0xd6481bc3,0x5afb2033,0xafa62104,0x76f4ce30 +.long 0xf4f066b5,0xa8fa00cf,0x461dafc2,0x89ab5143,0xa3389998,0x44339ed7,0xbc214903,0x2ff862f1,0xb05556e3,0x2c88f985,0x3467081e,0xcd96058e,0xedc637ea,0x7d6a4176,0x36a5acdc,0xe1743d09 +.long 0x7eb37726,0x66fd72e2,0x1481a037,0xf7fa264e,0x45f4aa79,0x9fbd3bde,0x767c3e22,0xed1e0147,0x82e7abe2,0x7621f979,0x45f633f8,0x19eedc72,0x6137bf3a,0xe69b155e,0x414ee94e,0xa0ad13ce +.long 0x1c0e651a,0x93e3d524,0x02ce227e,0xab1a6e2a,0x4ab27eca,0xe7af1797,0xbd444f39,0x245446de,0x56c07613,0x59e22a21,0xf4275498,0x43deafce,0x67fd0946,0x10834ccb,0x47406edf,0xa75841e5 +.long 0x7b0ac93d,0xebd6a677,0x78f5e0d7,0xa6e37b0d,0x76f5492b,0x2516c096,0x9ac05f3a,0x1e4bf888,0x4df0ba2b,0xcdb42ce0,0x5062341b,0x935d5cfd,0x82acac20,0x8a303333,0x5198b00e,0x429438c4 +.long 0x049d33fa,0x1d083bc9,0x946f67ff,0x58b82dda,0x67a1d6a3,0xac3e2db8,0x1798aac8,0x62e6bead,0xde46c58c,0xfc85980f,0x69c8d7be,0xa7f69379,0x837b35ec,0x23557927,0xe0790c0c,0x06a933d8 +.long 0x077ff55d,0x827c0e9b,0xbb26e680,0x53977798,0x1d9cb54f,0x59530874,0x4aac53ef,0xcca3f449,0xa07eda0f,0x11dc5c87,0xfd6400c8,0xc138bccf,0x13e5da72,0x549680d3,0x4540617e,0xc93eed82 +.long 0x4d0b75c0,0xfd3db157,0x6386075b,0x9716eb42,0x817b2c16,0x0639605c,0xf1e4f201,0x09915109,0x5cca6c3b,0x35c9a928,0x3505c900,0xb25f7d1a,0x630480c4,0xeb9f7d20,0x2a1a501c,0xc3c7b8c6 +.long 0x5a1f8e24,0x3f99183c,0x9dd255f0,0xfdb118fa,0xc27f62a6,0xb9b18b90,0x396ec191,0xe8f732f7,0x0be786ab,0x524a2d91,0x0ac5a0f5,0x5d32adef,0x9725f694,0x9b53d4d6,0x0510ba89,0x032a76c6 +.long 0xebeb1544,0x840391a3,0x3ed73ac3,0x44b7b88c,0x256cb8b3,0xd24bae7a,0xe394cb12,0x7ceb151a,0x5bc1e6a8,0xbd6b66d0,0x090f07bf,0xec70cecb,0x7d937589,0x270644ed,0x5f1dccfe,0xee9e1a3d +.long 0x745b98d2,0xb0d40a84,0x2556ed40,0xda429a21,0x85148cb9,0xf676eced,0xded18936,0x5a22d40c,0x70e8a4ce,0x3bc4b9e5,0x9eae0379,0xbfd1445b,0x1a0bd47e,0xf23f2c0c,0xe1845531,0xa9c0bb31 +.long 0x0a4c3f6b,0x9ddc4d60,0x2c15ef44,0xbdfaad79,0x7f484acc,0xce55a236,0x055b1f15,0x08653ca7,0x538873a3,0x2efa8724,0xace1c7e7,0x09299e5d,0xade332ba,0x07afab66,0x92dd71b7,0x9be1fdf6 +.long 0x5758b11c,0xa49b5d59,0xc8654f40,0x0b852893,0x52379447,0xb63ef6f4,0x105e690c,0xd4957d29,0x646559b0,0x7d484363,0x49788a8e,0xf4a8273c,0x34ce54a9,0xee406cb8,0xf86fda9b,0x1e1c260f +.long 0xcf6a4a81,0xe150e228,0x1b488772,0x1fa3b6a3,0xc5a9c15b,0x1e6ff110,0x8ad6aa47,0xc6133b91,0x9dffa978,0x8ac5d55c,0x5f3965f2,0xba1d1c1d,0x7732b52f,0xf969f4e0,0xa5172a07,0xfceecdb5 +.long 0x10f2b8f5,0xb0120a5f,0x5c4c2f63,0xc83a6cdf,0xf8f9c213,0x4d47a491,0xd3f1bbd5,0xd9e1cce5,0xaba7e372,0x0d91bc7c,0xdfd1a2db,0xfcdc74c8,0x374618e5,0x05efa800,0x15a7925e,0x11216969 +.long 0xf6021c5d,0xd4c89823,0xeff14423,0x880d5e84,0x6dcd1396,0x6523bc5a,0x113c978b,0xd1acfdfc,0xbbb66840,0xb0c164e8,0x72b58459,0xf7f4301e,0xa638e8ec,0xc29ad4a6,0x46b78699,0xf5ab8961 +.long 0x0e954750,0x9dbd7974,0x64f9d2c6,0x0121de88,0xd985232e,0x2e597b42,0x53451777,0x55b6c3c5,0x519cb9fb,0xbb53e547,0x8428600d,0xf134019f,0xe081791a,0x5a473176,0x35fb0c08,0x2f3e2263 +.long 0x73d273b0,0xb28c3017,0x7721ef9a,0xccd21076,0xb650dc39,0x054cc292,0x6188045e,0x662246de,0x6b83c0d1,0x904b52fa,0x97e9cd46,0xa72df267,0x899725e4,0x886b43cd,0xd849ff22,0x2b651688 +.long 0x02f34533,0x60479b79,0x0c77c148,0x5e354c14,0xa8537c78,0xb4bb7581,0xefe1495f,0x188043d7,0x8c1d5026,0x9ba12f42,0x93d4aaab,0x2e0c8a26,0xaa57c450,0xbdba7b8b,0x9bbdafef,0x140c9ad6 +.long 0x25ac0f18,0x2067aa42,0x04d1fbf3,0xf7b1295b,0xa4b04824,0x14829111,0x33bd5e91,0x2ce3f192,0x8f2e1b72,0x9c7a1d55,0x302aa243,0xfe932286,0xd4be9554,0x497ca7b4,0xe0547a6e,0xb8e821b8 +.long 0x67e573e0,0xfb2838be,0x4084c44b,0x05891db9,0x96c1c2c5,0x91311373,0xd958444b,0x6aebfa3f,0xe56e55c1,0xac9cdce9,0x2caa46d0,0x7148ced3,0xb61fe8eb,0x2e10c7ef,0xff97cf4d,0x9fd835da +.long 0x081e9387,0xa36da109,0x8c935828,0xfb9780d7,0xe540b015,0xd5940332,0xe0f466fa,0xc9d7b51b,0xd6d9f671,0xfaadcd41,0xb1a2ac17,0xba6c1e28,0xed201e5f,0x066a7833,0xf90f462b,0x19d99719 +.long 0x060b5f61,0xf431f462,0x7bd057c2,0xa56f46b4,0x47e1bf65,0x348dca6c,0x41bcf1ff,0x9a38783e,0xda710718,0x7a5d33a9,0x2e0aeaf6,0x5a779987,0x2d29d187,0xca87314d,0xc687d733,0xfa0edc3e +.long 0x6a31e09b,0x9df33621,0xc1350e35,0xde89e44d,0x4ca0cf52,0x29214871,0x0b88a538,0xdf379672,0x2591d61b,0xc92a510a,0x585b447b,0x79aa87d7,0xe5287f77,0xf67db604,0x5efe7a80,0x1697c8bf +.long 0xcb198ac7,0x1c894849,0x0f264665,0xa884a93d,0x9b200678,0x2da964ef,0x009834e6,0x3c351b87,0xe2c4b44b,0xafb2ef9f,0x3326790c,0x580f6c47,0x0b02264a,0xb8480521,0x42a194e2,0x8ba6f9e2 +.long 0x8fb54738,0xfc87975f,0x27c3ead3,0x35160788,0xb74a085a,0x834116d2,0xa62fe996,0x53c99a73,0x5b81c51b,0x87585be0,0xbe0852b7,0x925bafa8,0xa84d19a7,0x76a4fafd,0x585206d4,0x39a45982 +.long 0x5eb03c0e,0x499b6ab6,0x72bc3fde,0xf19b7954,0x6e3a80d2,0xa86b5b9c,0x6d42819f,0xe4377508,0xbb3ee8a3,0xc1663650,0xb132075f,0x75eb14fc,0x7ad834f6,0xa8ccc906,0xe6e92ffd,0xea6a2474 +.long 0x0f8d6758,0x9d72fd95,0x408c07dd,0xcb84e101,0xa5e23221,0xb9114bfd,0xe94e742c,0x358b5fe2,0x95f40e75,0x1c0577ec,0x3d73f3d6,0xf0155451,0xbd1b9b66,0x9d55cd67,0xaf8d63c7,0x63e86e78 +.long 0xd3c095f1,0x39d934ab,0xe4b76d71,0x04b261be,0xe73e6984,0x1d2e6970,0x5e5fcb11,0x879fb23b,0xdfd75490,0x11506c72,0x61bcf1c1,0x3a97d085,0xbf5e7007,0x43201d82,0x798232a7,0x7f0ac52f +.long 0x6eb564d4,0x2715cbc4,0x9e570e29,0x8d6c752c,0x9ef5fd5d,0xf80247c8,0xd53eb514,0xc3c66b46,0x0f87de56,0x9666b401,0xc6c603b5,0xce62c06f,0x7e4fc942,0xae7b4c60,0x663a9c19,0x38ac0b77 +.long 0x4b049136,0xcb4d20ee,0x356a4613,0x8b63bf12,0x70e08128,0x1221aef6,0x4acb6b16,0xe62d8c51,0x379e7896,0x71f64a67,0xcafd7fa5,0xb25237a2,0x3841ba6a,0xf077bd98,0x3cd16e7e,0xc4ac0244 +.long 0x21fea4ca,0x548ba869,0xf3dfdac1,0xd36d0817,0xf4685faf,0x09d8d71f,0xc52c459a,0x8eff66be,0x0b57235e,0x182faee7,0x0106712b,0xee3c39b1,0xc0fcdcb0,0x5107331f,0xa51054ba,0x669fb9dc +.long 0x319d7682,0xb25101fb,0x0a982fee,0xb0293129,0x0261b344,0x51c1c9b9,0xbfd371fa,0x0e008c5b,0x0278ca33,0xd866dd1c,0xe5aa53b1,0x666f76a6,0x6013a2cf,0xe5cfb779,0xa3521836,0x1d3a1aad +.long 0x73faa485,0xcedd2531,0xc0a76878,0xc8ee6c4f,0x2a11667d,0xddbccfc9,0x1c2f695a,0x1a418ea9,0x51f73971,0xdb11bd92,0xda2ed89f,0x3e4b3c82,0xe73e0319,0x9a44f3f4,0x303431af,0xd1e3de0f +.long 0x50f75f9c,0x3c5604ff,0x7e752b22,0x1d8eddf3,0x3c9a1118,0x0ef074dd,0xccb86d7b,0xd0ffc172,0x037d90f2,0xabd1ece3,0x6055856c,0xe3f307d6,0x7e4c6daf,0x422f9328,0x334879a0,0x902aac66 +.long 0x94cdfade,0xb6a1e7bf,0x7fc6d634,0x6c97e1ed,0xa2fb63f8,0x662ad24d,0xa5928405,0xf81be1b9,0xd14b4206,0x86d765e4,0x8fa0db65,0xbecc2e0e,0xb17fc76c,0xa28838e0,0xe37cf24e,0xe49a602a +.long 0x567193ec,0x76b4131a,0xe5f6e70b,0xaf3c305a,0x031eebdd,0x9587bd39,0x71bbe831,0x5709def8,0x0eb2b669,0x57059983,0x875b7029,0x4d80ce1b,0x0364ac16,0x838a7da8,0xbe1c83ab,0x2f431d23 +.long 0xf9294dd3,0xe56812a6,0x9b4b0d77,0xb448d01f,0x04e8305c,0xf3ae6061,0x94d8c63e,0x2bead645,0x84fd8b07,0x0a85434d,0xf7a9dee5,0x537b983f,0xef55bd85,0xedcc5f18,0x21c6cf8b,0x2041af62 +.long 0xb940c71e,0x8e52874c,0xdb5f4b3a,0x211935a9,0x301b1dc3,0x94350492,0x29958620,0x33d2646d,0xef911404,0x16b0d64b,0x9a3c5ef4,0x9d1f25ea,0x4a352c78,0x20f200eb,0x4bd0b428,0x43929f2c +.long 0xc7196e29,0xa5656667,0x9391be48,0x7992c2f0,0x9ee0cd6e,0xaaa97cbd,0x3dc8c9bf,0x51b0310c,0xdd9f22cb,0x237f8acf,0xb585d584,0xbb1d81a1,0x8c416388,0x8d5d85f5,0x42fe474f,0x0d6e5a5a +.long 0x38235d4e,0xe7812766,0x496e3298,0x1c62bd67,0x3f175bc8,0x8378660c,0x17afdd4d,0x4d04e189,0x85a8068c,0x32a81601,0x92b29a85,0xdb58e4e1,0xc70d8a3b,0xe8a65b86,0x98a0403b,0x5f0e6f4e +.long 0x69ed2370,0x08129684,0x0871ee26,0x34dc30bd,0x7c9c5b05,0x3a5ce948,0x43a90c87,0x7d487b80,0xdd0e7179,0x4089ba37,0xb4041811,0x45f80191,0x98747ba5,0x1c3e1058,0x6e1ae592,0x98c4e13a +.long 0xe82c9f9e,0xd44636e6,0xc33a1043,0x711db87c,0xaa8aec05,0x6f431263,0x2744a4aa,0x43ff120d,0xae77779b,0xd3bd892f,0x8cdc9f82,0xf0fe0cc9,0xf1c5b1bc,0xca5f7fe6,0x44929a72,0xcc63a682 +.long 0x09dbe19a,0xc7eaba0c,0x6b5c73c2,0x2f3585ad,0x0ae50c30,0x8ab8924b,0x638b30ba,0x17fcd27a,0x10b3d5a5,0xaf414d34,0x2a9accf1,0x09c107d2,0x946a6242,0x15dac49f,0xd707d642,0xaec3df2a +.long 0x3f894ae0,0x2c2492b7,0xb75f18ce,0xf59df3e5,0x8f53cad0,0x7cb740d2,0xc4f01294,0x3eb585fb,0x32c7f717,0x17da0c86,0xaf943f4c,0xeb8c795b,0xf67c51d2,0x4ee23fb5,0x68889949,0xef187575 +.long 0x0389168b,0xa6b4bdb2,0xea577d03,0xc4ecd258,0x55743082,0x3a63782b,0xc72f08cd,0x6f678f4c,0x65e58dd8,0x553511cf,0xd402c0cd,0xd53b4e3e,0xa037c14c,0x37de3e29,0xc05712aa,0x86b6c516 +.long 0xb38dff6f,0x2834da3e,0xea636be8,0xbe012c52,0x61dd37f8,0x292d238c,0x8f8142db,0x0e54523f,0x036a05d8,0xe31eb436,0x1e93c0ff,0x83e3cdff,0x50821ddf,0x3fd2fe0f,0xff9eb33b,0xc8e19b0d +.long 0xb569a5fe,0xc8cc943f,0xd4342d75,0xad0090d4,0xcaeca000,0x82090b4b,0x1bd410eb,0xca39687f,0x65959d77,0xe7bb0df7,0x9c964999,0x39d78218,0xb2415451,0xd87f62e8,0xbed76108,0xe5efb774 +.long 0xe822f0d0,0x3ea011a4,0x5a8704f8,0xbc647ad1,0x50c6820f,0xbb315b35,0xb7e76bec,0x863dec3d,0xf017bfc7,0x01ff5d3a,0x976b8229,0x20054439,0x0bbd0d3b,0x067fca37,0x7f5e3d0f,0xf63dde64 +.long 0x2a4c94e9,0x22dbefb3,0x96f8278a,0xafbff0fe,0x3503793d,0x80aea0b1,0x5f06cd29,0xb2238029,0x8ec3feca,0x65703e57,0x393e7053,0x06c38314,0x7c6734c4,0xa0b751eb,0xc59f0f1e,0xd2e8a435 +.long 0x5e9ca895,0x147d9052,0x972072df,0x2f4dd31e,0xe6c6755c,0xa16fda8e,0xcf196558,0xc66826ff,0x0cf43895,0x1f1a76a3,0x83c3097b,0xa9d604e0,0x66390e0e,0xe1908309,0xb3c85eff,0xa50bf753 +.long 0xf6a70251,0x0696bdde,0x3c6ab16a,0x548b801b,0xa4d08762,0x37fcf704,0xdff76c4e,0x090b3def,0x69cb9158,0x87e8cb89,0x995ece43,0x44a90744,0x0ad9fbf5,0xf85395f4,0x4fb0c82d,0x49b0f6c5 +.long 0xadf7cccf,0x75d9bc15,0xdfa1e1b0,0x81a3e5d6,0x249bc17e,0x8c39e444,0x8ea7fd43,0xf37dccb2,0x907fba12,0xda654873,0x4a372904,0x35daa6da,0x6283a6c5,0x0564cfc6,0x4a9395bf,0xd09fa4f6 +.long 0xaeb19a36,0x688e9ec9,0xc7bfbfb4,0xd913f1ce,0x61c2faa6,0x797b9a3c,0x6a0a9c12,0x2f979bec,0x359679ec,0xb5969d0f,0x079b0460,0xebcf523d,0x10fab870,0xfd6b0008,0x9373a39c,0x3f2edcda +.long 0x6f568431,0x0d64f9a7,0x02f8898c,0xf848c27c,0x260b5bd5,0xf418ade1,0x6973dee8,0xc1f3e323,0x26c185dd,0x46e9319c,0x546f0ac4,0x6d85b7d8,0x247f9d57,0x427965f2,0xb0035f48,0xb519b636 +.long 0xab87d59c,0x6b6163a9,0x39caaa11,0xff9f58c3,0x3177387b,0x4ac39cde,0x873e77f9,0x5f6557c2,0x36a83041,0x67504006,0x75ef196c,0x9b1c96ca,0xb08c7940,0xf34283de,0x1128c316,0x7ea09644 +.long 0x6aa39dff,0xb510b3b5,0x9f8e4d8c,0x59b43da2,0x9e4c4b9f,0xa8ce31fd,0xc1303c01,0x0e20be26,0xe8ee47c9,0x18187182,0x7db98101,0xd9687cdb,0xa1e14ff6,0x7a520e4d,0x8836d572,0x429808ba +.long 0x4944b663,0xa37ca60d,0xa3f91ae5,0xf901f7a9,0x9e36e3b1,0xe4e3e76e,0x29d93250,0x9aa219cf,0x056a2512,0x347fe275,0xde65d95c,0xa4d643d9,0x699fc3ed,0x9669d396,0xcf8c6bbe,0xb598dee2 +.long 0xdda9e5c6,0x682ac1e5,0xcaa9fc95,0x4e0d3c72,0x772bea44,0x17faaade,0xab0009c8,0x5ef8428c,0x460ff016,0xcc4ce47a,0x725281cb,0xda6d12bf,0x0223aad2,0x44c67848,0x36256e28,0x6e342afa +.long 0x93a37c04,0x1400bb0b,0xdd10bd96,0x62b1bc9b,0x0dac46b7,0x7251adeb,0x7be4ef51,0x7d33b92e,0xe61fa29a,0x28b2a94b,0x06422233,0x4b2be13f,0x330d8d37,0x36d6d062,0xb28ca005,0x5ef80e1e +.long 0x6d16768e,0x174d4699,0x628bf217,0x9fc4ff6a,0x154e490d,0x77705a94,0x8d2d997a,0x9d96dd28,0xce5d72c4,0x77e2d9d8,0xc11c714f,0x9d06c5a4,0x79e4a03e,0x02aa5136,0x030ff28b,0x1386b3c2 +.long 0xfb283f61,0xfe82e8a6,0xf3abc3fb,0x7df203e5,0x3a4d3622,0xeec7c351,0xdf762761,0xf7d17dbf,0x522055f0,0xc3956e44,0x8fa748db,0xde3012db,0xbf1dcc14,0xca9fcb63,0xbe4e2f3a,0xa56d9dcf +.long 0x8bcec9c2,0xb86186b6,0x680b9f06,0x7cf24df9,0xc0d29281,0xc46b45ea,0x07b10e12,0xfff42bc5,0x4d289427,0x12263c40,0xb4848ec4,0x3d5f1899,0xd040800c,0x11f97010,0x300feb20,0xb4c5f529 +.long 0xde94fdcb,0xcc543f8f,0xc7c2f05e,0xe96af739,0x882692e1,0xaa5e0036,0x950d4ae9,0x09c75b68,0xb5932a7a,0x62f63df2,0xde0979ad,0x2658252e,0xb5e69631,0x2a19343f,0x525b666b,0x718c7501 +.long 0xea40dc3a,0x26a42d69,0xaecc018f,0xdc84ad22,0x3270f04a,0x25c36c7b,0x50fa72ed,0x46ba6d47,0x93e58a8e,0x6c37d1c5,0x120c088c,0xa2394731,0xcb6e86da,0xc3be4263,0x7126d038,0x2c417d36 +.long 0x8b6f8efa,0x5b70f9c5,0x37718536,0x671a2faa,0xb539c92b,0xd3ced3c6,0xa31203c2,0xe56f1bd9,0x9ff3c8eb,0x8b096ec4,0x43491cea,0x2deae432,0x17943794,0x2465c6eb,0x20586843,0x5d267e66 +.long 0xb07159d0,0x9d3d116d,0xc1896210,0xae07a67f,0xbb961579,0x8fc84d87,0x1c1f8dd6,0x30009e49,0xe3132819,0x8a8caf22,0xf23ab4ff,0xcffa197c,0x205dd687,0x58103a44,0x0ded67a2,0x57b796c3 +.long 0xa1779ad7,0x0b9c3a6c,0x357c09c5,0xa33cfe2e,0x3db4a57e,0x2ea29315,0x8ebeb52e,0x91959695,0xe546c879,0x118db9a6,0x6295c8d6,0x8e996df4,0x55ec806b,0xdd990484,0x165c1035,0x24f291ca +.long 0x440e2229,0xcca523bb,0x73ef4d04,0x324673a2,0x3e11ec39,0xaf3adf34,0xdc5968d3,0x6136d7f1,0xb053a927,0x7a7b2899,0xae067ecd,0x3eaa2661,0x02779cd9,0x8549b9c8,0xc53385ea,0x061d7940 +.long 0xf06d18bd,0x3e0ba883,0xb2700843,0x4ba6de53,0x591a9e4d,0xb966b668,0x7f4fa0ed,0x93f67567,0x4347237b,0x5a02711b,0xe794608e,0xbc041e2f,0x70f73d8c,0x55af10f5,0xbb7564f7,0xd2d4d4f7 +.long 0xb3e93ce7,0xd7d27a89,0x5d3a2c1b,0xf7b5a875,0x255b218a,0xb29e68a0,0x8af76754,0xb533837e,0x579fab2e,0xd1b05a73,0xecd74385,0xb41055a1,0x445e9115,0xb2369274,0xf520274e,0x2972a7c4 +.long 0xf678e68a,0x6c08334e,0x99b057ed,0x4e4160f0,0x52ccb69a,0x3cfe11b8,0x21c8f772,0x2fd1823a,0x3298f055,0xdf7f072f,0xfec74a6e,0x8c0566f9,0x5bb4d041,0xe549e019,0x9208d850,0x7c3930ba +.long 0xaaa2902b,0xe07141fc,0xe4f69ad3,0x539ad799,0x813f9ffd,0xa6453f94,0x375bc2f7,0xc58d3c48,0x5dc64e96,0xb3326fad,0xb240e354,0x3aafcaa9,0xaca1e7a9,0x1d1b0903,0x1211b8a0,0x4ceb9767 +.long 0xe32a858e,0xeca83e49,0xae907bad,0x4c32892e,0x2eb9b494,0xd5b42ab6,0x1eabae1b,0x7fde3ee2,0xcaf54957,0x13b5ab09,0xe5f5d5d5,0xbfb028be,0x2003e2c0,0x928a0650,0x67476843,0x90793aac +.long 0xc81710a0,0x5e942e79,0x27ccadd4,0x557e4a36,0x4bcf6d0c,0x72a2bc56,0x26d7b80c,0x09ee5f43,0xd4292f19,0x6b70dbe9,0x63f16b18,0x56f74c26,0x35fbb42a,0xc23db0f7,0x6ae10040,0xb606bdf6 +.long 0x044573ac,0x1eb15d4d,0x556b0ba4,0x7dc3cf86,0xc60df6f7,0x97af9a33,0xa716ce8c,0x0b1ef85c,0xc96958be,0x2922f884,0x35690963,0x7c32fa94,0xeaa00061,0x2d7f667c,0x3547365c,0xeaaf7c17 +.long 0x87032d58,0x1eb4de46,0x5e2c79e0,0xc54f3d83,0x5d04ef23,0x07818df4,0x673d41b4,0x55faa9c8,0x89b95355,0xced64f6f,0xb7415c84,0x4860d2ea,0x050ebad3,0x5fdb9bd2,0x6685a5bf,0xdb53e0cc +.long 0x9feb6593,0xb830c031,0x6accff17,0xdd87f310,0x9f555c10,0x2303ebab,0x287e7065,0x94603695,0x2e83358c,0xf88311c3,0xeefb0178,0x508dd9b4,0x2dba8652,0x7ca23706,0x0047abe5,0x62aac5a3 +.long 0x8b1ea7b3,0x9a61d2a0,0xae8b1485,0xd495ab63,0x87052f99,0x38740f84,0xb2974eea,0x178ebe5b,0x5b36d17f,0x030bbcca,0xaaf86eea,0xb5e4cce3,0x68f8e9e0,0xb51a0220,0x09eb3e75,0xa4348796 +.long 0xeef1a752,0xbe592309,0x6f2aa1ed,0x5d7162d7,0x0f007dd2,0xaebfb5ed,0xc89edd22,0x255e14b2,0x0303b697,0xba85e072,0xf05720ff,0xc5d17e25,0x5128ebb6,0x02b58d6e,0xd754e113,0x2c80242d +.long 0xabfae1ca,0x919fca5f,0x1a21459b,0x937afaac,0x1f66a4d2,0x9e0ca91c,0x23ec1331,0x194cc7f3,0x8aa11690,0xad25143a,0x09b59e08,0xbe40ad8d,0xe750860a,0x37d60d9b,0xc6bf434c,0x6c53b008 +.long 0x1356eb80,0xb572415d,0x9578ded8,0xb8bf9da3,0x5e8fb38b,0x22658e36,0x5af8cb22,0x9b70ce22,0x829a8180,0x7c00018a,0xb81ed295,0x84329f93,0x5f3cea83,0x7c343ea2,0x67586536,0x38f8655f +.long 0x1d3ec517,0xa661a0d0,0x512321ae,0x98744652,0xeca92598,0x084ca591,0x1dcb3feb,0xa9bb9dc9,0x78b4c240,0x14c54355,0x610cafdc,0x5ed62a3b,0x1b38846b,0x07512f37,0xb0e38161,0x571bb70a +.long 0x2da705d2,0xb556b95b,0xb1a08f98,0x3ef8ada6,0xddecfbe5,0x85302ca7,0x943105cd,0x0e530573,0x21a9255d,0x60554d55,0xf2f3802a,0x63a32fa1,0xcd477875,0x35c8c5b0,0x6ad42da1,0x97f458ea +.long 0xeb6b242d,0x832d7080,0x3b71e246,0xd30bd023,0xbe31139d,0x7027991b,0x462e4e53,0x68797e91,0x6b4e185a,0x423fe20a,0x42d9b707,0x82f2c67e,0x4cf7811b,0x25c81768,0x045bb95d,0xbd53005e +.long 0x9d8e68fd,0xe5f649be,0x1b044320,0xdb0f0533,0xe0c33398,0xf6fde9b3,0x66c8cfae,0x92f4209b,0x1a739d4b,0xe9d1afcc,0xa28ab8de,0x09aea75f,0xeac6f1d0,0x14375fb5,0x708f7aa5,0x6420b560 +.long 0x6254dc41,0x9eae499c,0x7a837e7e,0x7e293924,0x090524a7,0x74aec08c,0x8d6f55f2,0xf82b9219,0x1402cec5,0x493c962e,0xfa2f30e7,0x9f17ca17,0xe9b879cb,0xbcd783e8,0x5a6f145f,0xea3d8c14 +.long 0x5e0dee6e,0xdede15e7,0xdc628aa2,0x74f24872,0x7861bb93,0xd3e9c4fe,0x6187b2e0,0x56d4822a,0xc59826f9,0xb66417cf,0x2408169e,0xca260969,0xc79ef885,0xedf69d06,0xdc7d138f,0x00031f8a +.long 0x0ebcf726,0x103c46e6,0x6231470e,0x4482b831,0x487c2109,0x6f6dfaca,0x62e666ef,0x2e0ace97,0x1f8d1f42,0x3246a9d3,0x574944d2,0x1b1e83f1,0xa57f334b,0x13dfa63a,0x9f025d81,0x0cf8daed +.long 0x00ee11c1,0x30d78ea8,0xb5e3dd75,0xeb053cd4,0xd58c43c5,0x9b65b13e,0xbd151663,0xc3ad49bd,0xb6427990,0x99fd8e41,0x707eae1e,0x12cf15bd,0x1aabb71e,0x29ad4f1b,0x07545d0e,0x5143e74d +.long 0xc88bdee1,0x30266336,0x5876767c,0x25f29306,0xc6731996,0x9c078571,0xed552951,0xc88690b2,0x852705b4,0x274f2c2d,0x4e09552d,0xb0bf8d44,0x986575d1,0x7628beeb,0x7f864651,0x407be238 +.long 0xa639fc6b,0x0e5e3049,0x86003625,0xe75c35d9,0x5dcc1646,0x0cf35bd8,0x6c26273a,0x8bcaced2,0xb5536742,0xe22ecf1d,0x1a9e068b,0x013dd897,0x8a7909c5,0x17f411cb,0x861dd506,0x5757ac98 +.long 0x1e935abb,0x85de1f0d,0x154de37a,0xdefd10b4,0x369cebb5,0xb8d9e392,0x761324be,0x54d5ef9b,0x74f17e26,0x4d6341ba,0x78c1dde4,0xc0a0e3c8,0x87d918fd,0xa6d77581,0x02ca3a13,0x66876015 +.long 0xf36658f0,0xc7313e9c,0x71f8057e,0xc433ef1c,0x1b6a835a,0x85326246,0x7c86394c,0xc8f05398,0xe983c4a1,0xff398cdf,0x03b7b931,0xbf5e8162,0xb7b9045b,0x93193c46,0xa4a6e46b,0x1e4ebf5d +.long 0x43a24fe7,0xf9942a60,0xffb3492b,0x29c1191e,0x902fde05,0x9f662449,0x6713c32d,0xc792a7ac,0xb737982c,0x2fd88ad8,0xa21e60e3,0x7e3a0319,0x7383591a,0x09b0de44,0x8310a456,0x6df141ee +.long 0xe6d6f471,0xaec1a039,0x1198d12e,0x14b2ba0f,0x3aeee5ac,0xebc1a160,0xe0b964ce,0x401f4836,0x4fd03f66,0x2ee43796,0xdd8f3f12,0x3fdb4e49,0x29380f18,0x6ef267f6,0x8da64d16,0x3e8e9670 +.long 0x207674f1,0xbc19180c,0x33ae8fdb,0x112e09a7,0x6aaeb71e,0x99667554,0xe101b1c7,0x79432af1,0xde2ddec6,0xd5eb558f,0x5357753f,0x81392d1f,0x3ae1158a,0xa7a76b97,0x4a899991,0x416fbbff +.long 0x0d4a9dcf,0x9e65fdfd,0x944ddf12,0x7bc29e48,0x3c856866,0xbc1a92d9,0x6e98dfe2,0x273c6905,0xcdfaa6b8,0x69fce418,0x5061c69f,0x606bd823,0x6af75e27,0x42d495a0,0x6d873a1f,0x8ed3d505 +.long 0x6ab25b6a,0xaf552841,0x2b1a4523,0xc6c0ffc7,0x21c99e03,0xab18827b,0x9034691b,0x060e8648,0x93c7f398,0x5207f90f,0x82f8d10b,0x9f4a96cb,0x3ad0f9e3,0xdd71cd79,0xfc3a54f5,0x84f435d2 +.long 0x8e33787f,0x4b03c55b,0xa6384673,0xef42f975,0x5051b9f0,0xff7304f7,0x741c87c2,0x18aca1dc,0x2d4bfe80,0x56f120a7,0x053e732c,0xfd823b3d,0x7537ca16,0x11bccfe4,0x1b5a996b,0xdf6c9c74 +.long 0x904fc3fa,0xee7332c7,0xc7e3636a,0x14a23f45,0xf091d9aa,0xc38659c3,0xb12d8540,0x4a995e5d,0xf3a5598a,0x20a53bec,0xb1eaa995,0x56534b17,0xbf04e03c,0x9ed3dca4,0xd8d56268,0x716c563a +.long 0x1d6178e7,0x27ba77a4,0x68a1ff8e,0xe4c80c40,0x0a13f63d,0x75011099,0xa61d46f3,0x7bf33521,0x10b365bb,0x0aff218e,0x0fd7ea75,0x81021804,0xa4b3a925,0x05a3fd8a,0x9b3db4e6,0xb829e75f +.long 0x4d53e5fb,0x6bdc75a5,0xd52717e3,0x04a5dc02,0xe9a42ec2,0x86af502f,0x2630e382,0x8867e8fb,0xbec9889b,0xbf845c6e,0xcb47c98d,0x54f491f2,0x790c2a12,0xa3091fba,0xc20f708b,0xd7f6fd78 +.long 0xacde5e17,0xa569ac30,0x6852b4d7,0xd0f996d0,0x4609ae54,0xe51d4bb5,0x0daed061,0x3fa37d17,0x34b8fb41,0x62a88684,0x9efb64f1,0x99a2acbd,0x6448e1f2,0xb75c1a5e,0x42b5a069,0xfa99951a +.long 0x2f3b26e7,0x6d956e89,0xda875247,0xf4709860,0x2482dda3,0x3ad15179,0x017d82f0,0xd64110e3,0xfad414e4,0x14928d2c,0x2ed02b24,0x2b155f58,0xcb821bf1,0x481a141b,0x4f81f5da,0x12e3c770 +.long 0x9fff8381,0xe49c5de5,0x5bbec894,0x11053232,0x454d88c4,0xa0d051cc,0x1f8e531b,0x4f6db89c,0xca563a44,0x34fe3fd6,0x58da8ab9,0x7f5c2215,0x9474f0a1,0x8445016d,0xcb7d8a0a,0x17d34d61 +.long 0x1c474019,0x8e9d3910,0xd52ceefb,0xcaff2629,0xc1622c2b,0xf9cf3e32,0xe9071a05,0xd4b95e3c,0x1594438c,0xfbbca61f,0x04aadedf,0x1eb6e6a6,0x68e14940,0x853027f4,0xdfabda9c,0x221d322a +.long 0xb7cb179a,0xed8ea9f6,0xb7934dcc,0xdc7b764d,0x5e09180d,0xfcb13940,0xb47dc2dd,0x6629a6bf,0x9f5a915e,0xbfc55e4e,0x6204441e,0xb1db9d37,0x930c5f53,0xf82d68cf,0xcbb605b1,0x17d3a142 +.long 0x308780f2,0xdd5944ea,0x3845f5e4,0xdc8de761,0x7624d7a3,0x6beaba7d,0x304df11e,0x1e709afd,0x02170456,0x95364376,0xc8f94b64,0xbf204b3a,0x5680ca68,0x4e53af7c,0xe0c67574,0x0526074a +.long 0xecd92af6,0x95d8cef8,0x6cd1745a,0xe6b9fa7a,0xa325c3e4,0x3d546d3d,0x9ae93aae,0x1f57691d,0x9d2e1a33,0xe891f3fe,0xac063d35,0xd430093f,0x5513a327,0xeda59b12,0x5536f18f,0xdc2134f3 +.long 0x5c210286,0xaa51fe2c,0x1cab658c,0x3f68aaee,0xf9357292,0x5a23a00b,0x7efdabed,0x9a626f39,0x199d78e3,0xfe2b3bf3,0x71bbc345,0xb7a2af77,0x1e59802c,0x3d19827a,0xb487a51c,0x823bbc15 +.long 0x99d0a422,0x856139f2,0xf456c6fb,0x9ac3df65,0x701f8bd6,0xaddf65c6,0x3758df87,0x149f321e,0x721b7eba,0xb1ecf714,0x31a3312a,0xe17df098,0xd5c4d581,0xdb2fd6ec,0x8fcea1b3,0xfd02996f +.long 0x7882f14f,0xe29fa63e,0x07c6cadc,0xc9f6dc35,0xb882bed0,0x46f22d6f,0xd118e52c,0x1a45755b,0x7c4608cf,0x9f2c7c27,0x568012c2,0x7ccbdf32,0x61729b0e,0xfcb0aedd,0xf7d75dbf,0x7ca2ca9e +.long 0x6f640f62,0xf58fecb1,0x39f51946,0xe274b92b,0x6288af44,0x7f4dfc04,0xeac329e5,0x0a91f32a,0xd6aaba31,0x43ad274b,0x0f6884f9,0x719a1640,0xdaf91e20,0x685d29f6,0x27e49d52,0x5ec1cc33 +.long 0x3b54a059,0x38f4de96,0xefbcfdb3,0x0e0015e5,0x4dbb8da6,0x177d23d9,0x97a617ad,0x98724aa2,0xfdb6558e,0x30f0885b,0xc7899a96,0xf9f7a28a,0x872dc112,0xd2ae8ac8,0x73c3c459,0xfa0642ca +.long 0xe7dfc8d6,0x15296981,0x1fb5b94a,0x67cd4450,0x0eddfd37,0x0ec71cf1,0x9a8eddc7,0xc7e5eeb3,0x81d95028,0x02ac8e3d,0x70b0e35d,0x0088f172,0xe1881fe3,0xec041fab,0xd99e7faa,0x62cf71b8 +.long 0xe0f222c2,0x5043dea7,0x72e65142,0x309d42ac,0x9216cd30,0x94fe9ddd,0x0f87feec,0xd6539c7d,0x432ac7d7,0x03c5a57c,0x327fda10,0x72692cf0,0x280698de,0xec28c85f,0x7ec283b1,0x2331fb46 +.long 0x2867e633,0xd34bfa32,0x0a9cc815,0x78709a82,0x875e2fa5,0xb7fe6964,0x9e98bfb5,0x25cc064f,0x493a65c5,0x9eb0151c,0x53182464,0x5fb5d941,0xf04618e2,0x69e6f130,0xf89c8ab6,0xa8ecec22 +.long 0xb96209bd,0xcd6ac88b,0xb3e1c9e0,0x65fa8cdb,0x4a8d8eac,0xa47d22f5,0x8d33f963,0x83895cdf,0xb56cd3d1,0xa8adca59,0xdaf38232,0x10c8350b,0xa5080a9f,0x2b161fb3,0x3af65b3a,0xbe7f5c64 +.long 0x97403a11,0x2c754039,0x121b96af,0x94626cf7,0x6a983ec2,0x431de7c4,0x52cc3df7,0x3780dd3a,0x2baf8e3b,0xe28a0e46,0x51d299ae,0xabe68aad,0x647a2408,0x603eb8f9,0x5c750981,0x14c61ed6 +.long 0xc53352e7,0x88b34414,0x1337d46e,0x5a34889c,0xf95f2bc8,0x612c1560,0xd4807a3a,0x8a3f8441,0x5224da68,0x680d9e97,0xc3eb00e9,0x60cd6e88,0x9a6bc375,0x3875a98e,0x4fd554c2,0xdc80f924 +.long 0x6ac77407,0x6c4b3415,0x25420681,0xa1e5ea8f,0x4607a458,0x541bfa14,0x96d7fbf9,0x5dbc7e7a,0x31590a47,0x646a851b,0x15ee6df8,0x039e85ba,0xd7b43fc0,0xd19fa231,0x299a0e04,0x84bc8be8 +.long 0xf20df03a,0x2b9d2936,0x8608d472,0x24054382,0x9149202a,0x76b6ba04,0x3670e7b7,0xb21c3831,0xd6fdee10,0xddd93059,0x78488e71,0x9da47ad3,0xa0fcfb25,0x99cc1dfd,0x64696954,0x42abde10 +.long 0x17eab9fe,0x14cc15fc,0xd3e70972,0xd6e863e4,0x6432112c,0x29a7765c,0x5b0774d8,0x88660001,0x2c088eae,0x3729175a,0x8230b8d4,0x13afbcae,0x915f4379,0x44768151,0xd8d22812,0xf086431a +.long 0xc298b974,0x37461955,0xf8711e04,0x905fb5f0,0xfe969d18,0x787abf3a,0x6f6a494e,0x392167c2,0x28c511da,0xfc7a0d2d,0xb66a262d,0xf127c7dc,0xfd63fdf0,0xf9c4bb95,0x3913ef46,0x90016589 +.long 0x11aa600d,0x74d2a73c,0x9fb5ab52,0x2f5379bd,0x7fb70068,0xe49e53a4,0x404aa9a7,0x68dd39e5,0x2ecaa9c3,0xb9b0cf57,0xe824826b,0xba0e103b,0x4631a3c4,0x60c2198b,0xfa8966a2,0xc5ff84ab +.long 0xac95aff8,0x2d6ebe22,0xb5a46d09,0x1c9bb6db,0x53ee4f8d,0x419062da,0xbb97efef,0x7b9042d0,0x830cf6bd,0x0f87f080,0x6ec8a6c6,0x4861d19a,0x202f01aa,0xd3a0daa1,0xf25afbd5,0xb0111674 +.long 0x1afb20d9,0x6d00d6cf,0x40671bc5,0x13695000,0x2485ea9b,0x913ab0dc,0x9eef61ac,0x1f2bed06,0x6d799e20,0x850c8217,0x3271c2de,0x93415f37,0x6c4f5910,0x5afb06e9,0xc4e9e421,0x688a52df +.long 0xe2a9a6db,0x30495ba3,0x58f9268b,0x4601303d,0x7eb0f04f,0xbe3b0dad,0x4456936d,0x4ea47250,0xd33fd3e7,0x8caf8798,0xeb433708,0x1ccd8a89,0x87fd50ad,0x9effe3e8,0x6b29c4df,0xbe240a56 +.long 0xca0e7ebd,0xec4ffd98,0xe748616e,0xf586783a,0xc77baa99,0xa5b00d8f,0xb4f34c9c,0x0acada29,0x0fe723ac,0x36dad67d,0x39c36c1e,0x1d8e53a5,0x1f4bea41,0xe4dd342d,0xebc9e4e0,0x64fd5e35 +.long 0x57908805,0x96f01f90,0x5ed480dd,0xb5b9ea3d,0x3efd2dd0,0x366c5dc2,0x6e9dfa27,0xed2fe305,0x6e9197e2,0x4575e892,0xab502a5d,0x11719c09,0xe81f213f,0x264c7bec,0x55f5c457,0x741b9241 +.long 0x49a5f4f4,0x78ac7b68,0x9fc45b7d,0xf91d70a2,0xb0f5f355,0x39b05544,0xeef930d9,0x11f06bce,0x038d05e1,0xdb84d25d,0xbacc1d51,0x04838ee5,0x9e8ee00b,0x9da3ce86,0xc36eda1f,0xc3412057 +.long 0x64d9c2f4,0xae80b913,0xa010a8ff,0x7468bac3,0x37359d41,0xdfd20037,0x15efeacc,0x1a0f5ab8,0x659d0ce0,0x7c25ad2f,0x6785cff1,0x4011bcbb,0x7e2192c7,0x128b9912,0x13ccb0e8,0xa549d8e1 +.long 0xc85438b1,0x805588d8,0xbc25cb27,0x5680332d,0x1a4bfdf4,0xdcd1bc96,0x706f6566,0x779ff428,0xf059987a,0x8bbee998,0xcc686de7,0xf6ce8cf2,0x953cfdb2,0xf8ad3c4a,0x2205da36,0xd1d426d9 +.long 0xc781a241,0xb3c0f13f,0xd75362a8,0x3e89360e,0xc8a91184,0xccd05863,0xefa8a7f4,0x9bd0c9b7,0x8a912a4b,0x97ee4d53,0xbcf518fd,0xde5e15f8,0xc467e1e0,0x6a055bf8,0x1587e256,0x10be4b4b +.long 0x668621c9,0xd90c14f2,0xab9c92c1,0xd5518f51,0xd6d47b3c,0x8e6a0100,0x66716175,0xcbe980dd,0xddd83683,0x500d3f10,0x99cac73c,0x3b6cb35d,0x6083d550,0x53730c8b,0xdf0a1987,0xcf159767 +.long 0x43ad73b3,0x84bfcf53,0x4f035a94,0x1b528c20,0x33eeac69,0x4294edf7,0x817f3240,0xb6283e83,0x0a5f25b1,0xc3fdc959,0x5844ee22,0xefaf8aa5,0xdbdde4de,0xde269ba5,0xc56133bf,0xe3347160 +.long 0x8d9ea9f8,0xc1184219,0xf3fc1ab5,0x090de5db,0x0bf22cda,0x404c37b1,0xf5618894,0x7de20ec8,0xecdaecab,0x754c588e,0x88342743,0x6ca4b0ed,0xf4a938ec,0x76f08bdd,0x91493ccb,0xd182de89 +.long 0xc8a4186a,0xd652c53e,0x946d8e33,0xb3e878db,0x5f37663c,0x088453c0,0xb407748b,0x5cd9daaa,0x586d5e72,0xa1f5197f,0xc443ca59,0x47500be8,0xe2652424,0x78ef35b2,0x6dd7767d,0x09c5d26f +.long 0xa74d3f7b,0x7175a79a,0xcf5ea459,0x0428fd8d,0xa5d1746d,0x511cb97c,0xe71d1278,0x36363939,0x10350bf4,0xcf2df955,0x60aae782,0xb3817439,0x3e688809,0xa748c0e4,0xd7a5a006,0x98021fbf +.long 0x0e367a98,0x9076a70c,0x0f62b7c2,0xbea1bc15,0x30fe0343,0x2645a68c,0x699dc14f,0xacaffa78,0x457bf9c4,0xf4469964,0x0d2ead83,0x0db6407b,0xb2c6f3eb,0x68d56cad,0xf376356c,0x3b512e73 +.long 0xfce10408,0xe43b0e1f,0x5a5e257d,0x89ddc003,0x0362e5b3,0xb0ae0d12,0xb0519161,0x07f983c7,0x5d5231e7,0xc2e94d15,0x0b4f9513,0xcff22aed,0x6ad0b0b5,0xb02588dd,0x11d0dcd5,0xb967d1ac +.long 0xcf777b6c,0x8dac6bc6,0x4c6d1959,0x0062bdbd,0x0ef5cc85,0x53da71b5,0x4006f14f,0x07012c7d,0xac47800d,0x4617f962,0xc102ed75,0x53365f2b,0x4ab8c9d3,0xb422efcb,0x34af31c9,0x195cb26b +.long 0x05f2c4ce,0x3a926e29,0x9856966c,0xbd2bdecb,0x85527015,0x5d16ab3a,0x4486c231,0x9f81609e,0xda350002,0xd8b96b2c,0xfa1b7d36,0xbd054690,0xe71d79bc,0xdc90ebf5,0x08964e4e,0xf241b6f9 +.long 0x2fe3cd4c,0x7c838643,0xb4bc633c,0xe0f33acb,0x3d139f1f,0xb4a9ecec,0xdc4a1f49,0x05ce69cd,0xf5f98aaf,0xa19d1b16,0x6f23e0ef,0x45bb71d6,0x46cdfdd3,0x33789fcd,0xcee040ca,0x9b8e2978 +.long 0xae0a6828,0x9c69b246,0x7078d5aa,0xba533d24,0x7bb4fbdb,0x7a2e42c0,0x7035385c,0xcfb4879a,0x3281705b,0x8c3dd30b,0x404fe081,0x7e361c6c,0x3f604edf,0x7b21649c,0xe52ffe47,0x5dbf6a3f +.long 0x4b54d9bf,0xc41b7c23,0x3511c3d9,0x1374e681,0xc1b2b758,0x1863bf16,0x1e9e6a96,0x90e78507,0x5d86f174,0xab4bf98d,0x85e96fe4,0xd74e0bd3,0xcac5d344,0x8afde39f,0xbd91b847,0x90946dbc +.long 0xfe1a838c,0xf5b42358,0x620ac9d8,0x05aae6c5,0xa1ce5a0b,0x8e193bd8,0x4dabfd72,0x8f710571,0x182caaac,0x8d8fdd48,0x040745cf,0x8c4aeefa,0xf3b93e6d,0x73c6c30a,0x16f42011,0x991241f3 +.long 0xe457a477,0xa0158eea,0xee6ddc05,0xd19857db,0x18c41671,0xb3265224,0x3c2c0d58,0x3ffdfc7e,0x26ee7cda,0x3a3a5254,0xdf02c3a8,0x341b0869,0x723bbfc8,0xa023bf42,0x14452691,0x3d15002a +.long 0x85edfa30,0x5ef7324c,0x87d4f3da,0x25976554,0xdcb50c86,0x352f5bc0,0x4832a96c,0x8f6927b0,0x55f2f94c,0xd08ee1ba,0x344b45fa,0x6a996f99,0xa8aa455d,0xe133cb8d,0x758dc1f7,0x5d0721ec +.long 0x79e5fb67,0x6ba7a920,0x70aa725e,0xe1331feb,0x7df5d837,0x5080ccf5,0x7ff72e21,0xe4cae01d,0x0412a77d,0xd9243ee6,0xdf449025,0x06ff7cac,0x23ef5a31,0xbe75f7cd,0x0ddef7a8,0xbc957822 +.long 0xb0ce1c55,0x8cf7230c,0x0bbfb607,0x5b534d05,0x0e16363b,0xee1ef113,0xb4999e82,0x27e0aa7a,0x79362c41,0xce1dac2d,0x91bb6cb0,0x67920c90,0x2223df24,0x1e648d63,0xe32e8f28,0x0f7d9eef +.long 0xfa833834,0x6943f39a,0xa6328562,0x22951722,0x4170fc10,0x81d63dd5,0xaecc2e6d,0x9f5fa58f,0xe77d9a3b,0xb66c8725,0x6384ebe0,0x11235cea,0x5845e24a,0x06a8c118,0xebd093b1,0x0137b286 +.long 0x44ace150,0xc589e1ce,0x4381e97c,0xe0f8d3d9,0x62c5a4b8,0x59e99b11,0xfd0ec9f9,0x90d262f7,0x283e13c9,0xfbc854c9,0xaedc7085,0x2d04fde7,0x47dcbecb,0x057d7765,0x9a76fa5f,0x8dbdf591 +.long 0x0de1e578,0xd0150695,0xe9f72bc6,0x2e1463e7,0x1b39eca5,0xffa68441,0x7c037f2f,0x673c8530,0x747f91da,0xd0d6a600,0xc9cb78e9,0xb08d43e1,0x27b5cef5,0x0fc0c644,0xa60a2fd6,0x5c1d160a +.long 0x28c8e13b,0xf98cae53,0xb2eddcd1,0x375f10c4,0x5cce06ad,0xd4eb8b7f,0x80a2e1ef,0xb4669f45,0x5bbd8699,0xd593f9d0,0xe7976d13,0x5528a4c9,0x1c7e28d3,0x3923e095,0x3f6bb577,0xb9293790 +.long 0xc42bd6d2,0xdb567d6a,0xbb1f96ae,0x6df86468,0x4843b28e,0x0efe5b1a,0x6379b240,0x961bbb05,0x70a6a26b,0xb6caf5f0,0x328e6e39,0x70686c0d,0x895fc8d3,0x80da06cf,0xb363fdc9,0x804d8810 +.long 0x207f1670,0xbe22877b,0x4e615291,0x9b0dd188,0x97a3c2bf,0x625ae8dc,0x439b86e8,0x08584ef7,0xdcd898ff,0xde7190a5,0x2058ee3d,0x26286c40,0x5f87b1c1,0x3db0b217,0x102a6db5,0xcc334771 +.long 0x2f770fb1,0xd99de954,0x4cd7535e,0x97c1c620,0x3f09cefc,0xd3b6c448,0x5a63b4f8,0xd725af15,0xc01e20ec,0x0c95d24f,0x9ae7121f,0xdfd37494,0xec77b7ec,0x7d6ddb72,0x0353a4ae,0xfe079d3b +.long 0x2e6ac8d2,0x3066e70a,0x106e5c05,0x9c6b5a43,0xede59b8c,0x52d3c6f5,0xfccec9ae,0x30d6a5c3,0x4fc0a9ef,0xedec7c22,0x95c16ced,0x190ff083,0x94de0fde,0xbe12ec8f,0x852d3433,0x0d131ab8 +.long 0x85701291,0x42ace07e,0x194061a8,0x94793ed9,0xd7f4a485,0x30e83ed6,0xf9eeff4d,0x9eec7269,0x0c9d8005,0x90acba59,0x1e79b9d1,0x5feca458,0x1d506a1e,0x8fbe5427,0x2439cfa7,0xa32b2c8e +.long 0x73dd0b4e,0x1671c173,0x44a054c6,0x37a28214,0x4e8b53f1,0x81760a1b,0xf9f93b9e,0xa6c04224,0xcf671e3c,0x18784b34,0xcda9b994,0x81bbecd2,0xb2ab3848,0x38831979,0xf2e03c2d,0xef54feb7 +.long 0xfb8088fa,0xcf197ca7,0x4ddc96c5,0x01427247,0x30777176,0xa2d2550a,0x4d0cf71d,0x53469898,0x3a2aaac6,0x6ce937b8,0x5af38d9b,0xe9f91dc3,0xc8bf2899,0x2598ad83,0xb5536c16,0x8e706ac9 +.long 0xf688dc98,0x40dc7495,0x124c4afc,0x26490cd7,0x1f18775c,0xe651ec84,0xb4fdaf4a,0x393ea6c3,0x7f338e0d,0x1e1f3343,0x6053e7b5,0x39fb832b,0x619e14d5,0x46e702da,0xcdeef6e0,0x859cacd1 +.long 0x4462007d,0x63b99ce7,0x4cb5f5b7,0xb8ab48a5,0xf55edde7,0x9ec673d2,0x8cfaefda,0xd1567f74,0x0887bcec,0x46381b6b,0xe178f3c2,0x694497ce,0x1e6266cb,0x5e6525e3,0x697d6413,0x5931de26 +.long 0x0e58d493,0x87f8df7c,0x58b73f12,0xb1ae5ed0,0xdea0c34d,0xc368f784,0x859a91a0,0x9bd0a120,0xcc863c68,0xb00d88b7,0x3d1f4d65,0x3a1cc11e,0x0aa85593,0xea38e0e7,0x7dc4aee8,0x37f13e98 +.long 0xbc947bad,0x10d38667,0x2a36ee2e,0x738e07ce,0xc577fcac,0xc93470cd,0x2782470d,0xdee1b616,0x2e793d12,0x36a25e67,0xe0f186da,0xd6aa6cae,0x80e07af7,0x474d0fd9,0xba8a5cd4,0xf7cdc47d +.long 0xab15247f,0x28af6d9d,0x493a537f,0x7c789c10,0x23a334e7,0x7ac9b110,0x12c9c277,0x0236ac09,0x1d7a5144,0xa7e5bd25,0xf13ec4ec,0x098b9c2a,0xd3f0abca,0x3639daca,0xa23960f9,0x642da81a +.long 0x4f7269b1,0x7d2e5c05,0xe287c385,0xfcf30777,0xf2a46f21,0x10edc84f,0x4f43fa36,0x35441757,0xfd703431,0xf1327899,0x16dd587a,0xa438d7a6,0xe9c8352d,0x65c34c57,0x5cc5a24e,0xa728edab +.long 0x42531689,0xaed78abc,0x010963ef,0x0a51a0e8,0xd717d9b3,0x5776fa0a,0x7dd3428b,0xf356c239,0x8d3a3dac,0x29903fff,0x3d94491f,0x409597fa,0xbf4a56a4,0x4cd7a5ff,0x8adab462,0xe5096474 +.long 0x5c3427b0,0xa97b5126,0xd282c9bd,0x6401405c,0x222c5c45,0x3629f8d7,0xe8d50aed,0xb1c02c16,0xd9635bc9,0xbea2ed75,0x6e24552f,0x226790c7,0x65f1d066,0x3c33f2a3,0x6dfccc2e,0x2a43463e +.long 0xdb483761,0x8cc3453a,0x65d5672b,0xe7cc6085,0xde3efc87,0x277ed6cb,0x69234eaf,0x19f2f368,0x5c0b800b,0x9aaf4317,0x8b6da6e2,0x1f1e7c89,0xb94ec75e,0x6cfb4715,0x453118c2,0xd590dd5f +.long 0x1f17a34c,0x14e49da1,0x235a1456,0x5420ab39,0x2f50363b,0xb7637241,0xc3fabb6e,0x7b15d623,0xe274e49c,0xa0ef40b1,0x96b1860a,0x5cf50744,0x66afe5a4,0xd6583fbf,0xf47e3e9a,0x44240510 +.long 0x11b2d595,0x99254343,0xeec8df57,0xf1367499,0x3e73dd05,0x3cb12c61,0x7dac102a,0xd248c033,0xa77739f5,0xcf154f13,0x23d2af42,0xbf4288cb,0x32e4a1cf,0xaa64c9b6,0xc8a208f3,0xee8c07a8 +.long 0x6fe8393f,0xe10d4999,0xe91f3a32,0x0f809a3f,0x802f63c8,0x61096d1c,0x57750d3d,0x289e1462,0x9889feea,0xed06167e,0xe0993909,0xd5c9c0e2,0x56508ac6,0x46fca0d8,0x4f1b8e83,0x91826047 +.long 0x9a4a2751,0x4f2c877a,0xcae6fead,0x71bd0072,0x06aa1941,0x38df8dcc,0x63beeaa8,0x5a074b4c,0xc1cec8ed,0xd6d65934,0xaabc03bd,0xa6ecb49e,0xde8a8415,0xaade91c2,0x691136e0,0xcfb0efdf +.long 0x23ab3495,0x11af45ee,0x0b77463d,0xa132df88,0x815d06f4,0x8923c15c,0x0d61a436,0xc3ceb3f5,0xe88fb1da,0xaf52291d,0x1da12179,0xea057974,0xd2fef720,0xb0d7218c,0x8e1d8845,0x6c0899c9 +.long 0x752ddad7,0x98157504,0xa1a68a97,0xd60bd74f,0xf658fb99,0x7047a3a9,0x5f8511e4,0x1f5d86d6,0x4b5a6d88,0xb8a4bc42,0x1abefa7d,0x69eb2c33,0x13c9c510,0x95bf39e8,0xd48aab43,0xf571960a +.long 0x704e23c6,0x7e8cfbcf,0x28aaa65b,0xc71b7d22,0x245e3c83,0xa041b2bd,0xd21854ff,0x69b98834,0x963bfeec,0x89d227a3,0xde7da7cb,0x99947aaa,0xee68a9b1,0x1d9ee9db,0x698ec368,0x0a08f003 +.long 0x78ef2487,0xe9ea4094,0x02cfec26,0xc8d2d415,0xb7dcf328,0xc52f9a6e,0x85b6a937,0x0ed489e3,0xbef3366e,0x9b94986b,0xedddddb8,0x0de59c70,0xeadddbe2,0xffdb748c,0x8266ea40,0x9b9784bb +.long 0x1a93507a,0x142b5502,0x8d3c06cf,0xb4cd1187,0x91ec3f40,0xdf70e76a,0x4e7553c2,0x484e81ad,0x272e9d6e,0x830f87b5,0xc6ff514a,0xea1c93e5,0xc4192a8e,0x67cc2adc,0x42f4535a,0xc77e27e2 +.long 0xd2b713c5,0x9cdbab36,0xcf7b0cd3,0x86274ea0,0x09af826b,0x784680f3,0x0c72dea3,0xbfcc837a,0xd6529b73,0xa8bdfe9d,0x63a88002,0x708aa228,0xc91d45b9,0x6c7a9a54,0xfd004f56,0xdf1a38bb +.long 0xb8bad853,0x2e8c9a26,0x3723eae7,0x2d52cea3,0x56ca2830,0x054d6d81,0x9a8dc411,0xa3317d14,0xfd4ddeda,0xa08662fe,0xb55d792b,0xed2a153a,0xbfc6e944,0x7035c16a,0x00171cf3,0xb6bc5834 +.long 0x83d102b6,0xe27152b3,0x0646b848,0xfe695a47,0x916e6d37,0xa5bb09d8,0x0d17015e,0xb4269d64,0x0a1d2285,0x8d8156a1,0x46d26d72,0xfeef6c51,0x4c5434a7,0x9dac57c8,0x59d39e31,0x0282e5be +.long 0x721c486d,0xedfff181,0xbc58824e,0x301baf10,0x00570031,0x8136a6aa,0x1cddde68,0x55aaf78c,0x59c63952,0x26829371,0x8bc25baf,0x3a3bd274,0xb7e52dc3,0xecdf8657,0xfd78e6c8,0x2dd8c087 +.long 0xf5531461,0x20553274,0x5d95499b,0x8b4a1281,0x1a80f9d2,0xe2c8763a,0x4ddec758,0xd1dbe32b,0x30c34169,0xaf12210d,0x78baa533,0xba74a953,0xa438f254,0x3d133c6e,0x201bef5b,0xa431531a +.long 0xf669d7ec,0x15295e22,0x357fb515,0xca374f64,0xeaa3fdb3,0x8a8406ff,0xdf3f2da8,0x106ae448,0x33c8e9a1,0x8f9b0a90,0x71ad5885,0x234645e2,0x1c0aed14,0x3d083224,0x7a942d46,0xf10a7d3e +.long 0x40d5c9be,0x7c11deee,0xba84ed98,0xb2bae7ff,0xaad58ddd,0x93e97139,0x3f6d1fa3,0x3d872796,0x8569ff13,0x483aca81,0x9a600f72,0x8b89a5fb,0xc06f2b86,0x4cbc27c3,0x63ad9c0b,0x22130713 +.long 0x48ac2840,0xb5358b1e,0xecba9477,0x18311294,0xa6946b43,0xda58f990,0x9ab41819,0x3098baf9,0x4198da52,0x66c4c158,0x146bfd1b,0xab4fc17c,0xbf36a908,0x2f0a4c3c,0x58cf7838,0x2ae9e34b +.long 0x3fa11b1f,0xf411529e,0x974af2b4,0x21e43677,0xc230793b,0x7c20958e,0x16e840f3,0x710ea885,0xc5dc67cf,0xfc0b21fc,0x88405718,0x08d51647,0xcfe49eb7,0xd955c21f,0x56dd4a1f,0x9722a5d5 +.long 0xc861baa5,0xc9ef50e2,0x9505ac3e,0xc0c21a5d,0x8b7c063f,0xaf6b9a33,0x2f4779c1,0xc6370339,0x638167c3,0x22df99c7,0x795db30c,0xfe6ffe76,0xa4854989,0x2b822d33,0x30563aa5,0xfef031dd +.long 0xd57c667f,0x16b09f82,0xcc0b76f1,0xc70312ce,0xc9118aec,0xbf04a9e6,0x3409d133,0x82fcb419,0xab45d44d,0x1a8ab385,0x617b83a3,0xfba07222,0x58e81b52,0xb05f50dd,0x21ce5aff,0x1d8db553 +.long 0xe344a873,0x3097b8d4,0xfe36d53e,0x7d8d116d,0x7875e750,0x6db22f58,0x43e144ea,0x2dc5e373,0xe799eb95,0xc05f32e6,0x6899e6ec,0xe9e5f4df,0x1fab23d5,0xbdc3bd68,0x73af60e6,0xb72b8ab7 +.long 0x2cecc84a,0x8db27ae0,0x7bdb871c,0x600016d8,0xd7c46f58,0x42a44b13,0xc3a77d39,0xb8919727,0xdafd6088,0xcfc6bbbd,0x6bd20d39,0x1a740146,0x98c41072,0x8c747abd,0xbdf68ea1,0x4c91e765 +.long 0x08819a78,0x7c95e5ca,0xc9587921,0xcf48b729,0xdebbcc7d,0x091c7c5f,0xf0e05149,0x6f287404,0x26cd44ec,0xf83b5ac2,0xcfea250e,0x88ae32a6,0x1d06ebc5,0x6ac5047a,0xd434f781,0xc7e550b4 +.long 0x5c727bd2,0x61ab1cf2,0x1cf915b0,0x2e4badb1,0xf69d3920,0x1b4dadec,0xf14c1dfe,0xe61b1ca6,0xbd6bd51f,0x90b479cc,0x8045ec30,0x8024e401,0x25ef0e62,0xcab29ca3,0x49e4ebc0,0x4f2e9416 +.long 0x0ccced58,0x45eb40ec,0x0da44f98,0x25cd4b9c,0x871812c6,0x43e06458,0x16cef651,0x99f80d55,0xce6dc153,0x571340c9,0xd8665521,0x138d5117,0x4e07014d,0xacdb45bc,0x84b60b91,0x2f34bb38 +.long 0x2ae8921e,0xf44a4fd2,0x892ba1e2,0xb039288e,0xb1c180b2,0x9da50174,0x1693dc87,0x6b70ab66,0xe7057481,0x7e9babc9,0x9c80dc41,0x4581ddef,0x51294682,0x0c890da9,0x3f4736e5,0x0b5629d3 +.long 0xb06f5b41,0x2340c79e,0x4e243469,0xa42e84ce,0x045a71a9,0xf9a20135,0xd27b6fb6,0xefbfb415,0x9d33cd6f,0x25ebea23,0xaa6c0af8,0x9caedb88,0xd9ce6f96,0x53dc7e9a,0x51e0b15a,0x3897f9fd +.long 0x8e5d788e,0xf51cb1f8,0xe1d490ee,0x1aec7ba8,0xcc58cb3c,0x265991e0,0x9fc3ad31,0x9f306e8c,0x5040a0ac,0x5fed006e,0xfb476f2e,0xca9d5043,0xbeea7a23,0xa19c06e8,0x0edabb63,0xd2865801 +.long 0x6967469a,0xdb92293f,0x8d8a8ed8,0x2894d839,0xbbc77122,0x87c9e406,0x2ea3a26a,0x8671c6f1,0xd7de9853,0xe42df8d6,0xb1f2bcc7,0x2e3ce346,0x899d50cf,0xda601dfc,0xfb1b598f,0xbfc913de +.long 0xe61f7908,0x81c4909f,0x9bbc7b29,0x192e304f,0xc104b338,0xc3ed8738,0x783f5d61,0xedbe9e47,0x2db30660,0x0c06e9be,0xc0eb7d8e,0xda3e613f,0x322e096e,0xd8fa3e97,0xd336e247,0xfebd91e8 +.long 0xdf655a49,0x8f13ccc4,0x5eb20210,0xa9e00dfc,0xc656b6ea,0x84631d0f,0xd8c0d947,0x93a058cd,0x67bd3448,0x6846904a,0xf394fd5c,0x4a3d4e1a,0xdb225f52,0xc102c1a5,0xfc4f5e9a,0xe3455bba +.long 0x4b9ad1ce,0x6b36985b,0x5bb7f793,0xa9818536,0x48b1a416,0x6c25e1d0,0x3c81bee7,0x1381dd53,0x7a4a7620,0xd2a30d61,0x39b8944c,0xc8412926,0x7a97c33a,0x3c1c6fbe,0x938664e7,0x941e541d +.long 0x4a34f239,0x417499e8,0xb90402d5,0x15fdb83c,0x433aa832,0xb75f46bf,0x63215db1,0xb61e15af,0xa127f89a,0xaabe59d4,0x07e816da,0x5d541e0c,0xa618b692,0xaaba0659,0x17266026,0x55327733 +.long 0x95f57552,0xaf53a0fc,0x6cacb0c9,0x32947650,0xc821be01,0x253ff58d,0xa06f1146,0xb0309531,0x05c2e54d,0x59bbbdf5,0x26e8dd22,0x158f27ad,0x397e1e53,0xcc5b7ffb,0x7fc1e50d,0xae03f65b +.long 0x9c95f0f9,0xa9784ebd,0x24640771,0x5ed9deb2,0x035561c4,0x31244af7,0x7ee857de,0x87332f3a,0x2b9e0d88,0x09e16e9e,0x56a06049,0x52d910f4,0xa9592f48,0x507ed477,0x2365d678,0x85cb917b +.long 0x4c8998d1,0xf8511c93,0x730ea58f,0x2186a3f1,0xb2029db0,0x50189626,0x02ceb75a,0x9137a6d9,0x748bc82c,0x2fe17f37,0x80469f8c,0x87c2e931,0xbf891aa2,0x850f71cd,0x75ec3d8d,0x0ca1b89b +.long 0x5e1cd3cd,0x516c43aa,0x9a887c28,0x89397808,0xddea1f9f,0x0059c699,0x8e6868f7,0x7737d6fa,0x60f1524b,0x6d93746a,0xba052aa7,0x36985e55,0xed923ea5,0x41b1d322,0x25852a11,0x3429759f +.long 0x092e9f41,0xbeca6ec3,0x62256bbd,0x3a238c66,0x70ad487d,0xd82958ea,0x65610d93,0x4ac8aaf9,0x5e4ccab0,0x3fa101b1,0x9de14bfb,0x9bf430f2,0x6531899d,0xa10f5cc6,0xea8ce17d,0x590005fb +.long 0x24544cb6,0xc437912f,0xd79ac2e3,0x9987b71a,0xc058a212,0x13e3d9dd,0xd2de9606,0x00075aac,0x6cac8369,0x80ab508b,0xf54f6c89,0x87842be7,0x6bc532a4,0xa7ad663d,0x78a91bc8,0x67813de7 +.long 0xc3427239,0x5dcb61ce,0xc56934d9,0x5f3c7cf0,0xe3191591,0xc079e0fb,0xb01aada7,0xe40896bd,0x0492d25f,0x8d466791,0xe7408276,0x8aeb30c9,0x9287aacc,0xe9437495,0x79fe03d4,0x23d4708d +.long 0xd0c05199,0x8cda9cf2,0xfae78454,0x502fbc22,0xf572a182,0xc0bda9df,0x6158b372,0x5f9b71b8,0x2b82dd07,0xe0f33a59,0x9523032e,0x76302735,0xc4505a32,0x7fe1a721,0xf796409f,0x7b6e3e82 +.long 0x35d0b34a,0xe3417bc0,0x8327c0a7,0x440b386b,0xac0362d1,0x8fb7262d,0xe0cdf943,0x2c41114c,0xad95a0b1,0x2ba5cef1,0x67d54362,0xc09b37a8,0x01e486c9,0x26d6cdd2,0x42ff9297,0x20477abf +.long 0x292a9287,0xa004dcb3,0x77b092c7,0xddc15cf6,0x806c0605,0x083a8464,0x3db997b0,0x4a68df70,0x05bf7dd0,0x9c134e45,0x8ccf7f8c,0xa4e63d39,0x41b5f8af,0xa6e6517f,0xad7bc1cc,0xaa8b9342 +.long 0x1e706ad9,0x126f35b5,0xc3a9ebdf,0xb99cebb4,0xbf608d90,0xa75389af,0xc6c89858,0x76113c4f,0x97e2b5aa,0x80de8eb0,0x63b91304,0x7e1022cc,0x6ccc066c,0x3bdab605,0xb2edf900,0x33cbb144 +.long 0x7af715d2,0xc4176471,0xd0134a96,0xe2f7f594,0xa41ec956,0x2c1873ef,0x77821304,0xe4e7b4f6,0x88d5374a,0xe5c8ff97,0x80823d5b,0x2b915e63,0xb2ee8fe2,0xea6bc755,0xe7112651,0x6657624c +.long 0xdace5aca,0x157af101,0x11a6a267,0xc4fdbcf2,0xc49c8609,0xdaddf340,0xe9604a65,0x97e49f52,0x937e2ad5,0x9be8e790,0x326e17f1,0x846e2508,0x0bbbc0dc,0x3f38007a,0xb11e16d6,0xcf03603f +.long 0x7442f1d5,0xd6f800e0,0x66e0e3ab,0x475607d1,0xb7c64047,0x82807f16,0xa749883d,0x8858e1e3,0x8231ee10,0x5859120b,0x638a1ece,0x1b80e7eb,0xc6aa73a4,0xcb72525a,0x844423ac,0xa7cdea3d +.long 0xf8ae7c38,0x5ed0c007,0x3d740192,0x6db07a5c,0x5fe36db3,0xbe5e9c2a,0x76e95046,0xd5b9d57a,0x8eba20f2,0x54ac32e7,0x71b9a352,0xef11ca8f,0xff98a658,0x305e373e,0x823eb667,0xffe5a100 +.long 0xe51732d2,0x57477b11,0x2538fc0e,0xdfd6eb28,0x3b39eec5,0x5c43b0cc,0xcb36cc57,0x6af12778,0x06c425ae,0x70b0852d,0x5c221b9b,0x6df92f8c,0xce826d9c,0x6c8d4f9e,0xb49359c3,0xf59aba7b +.long 0xda64309d,0x5c8ed8d5,0x91b30704,0x61a6de56,0x2f9b5808,0xd6b52f6a,0x98c958a7,0x0eee4194,0x771e4caa,0xcddd9aab,0x78bc21be,0x83965dfd,0xb3b504f5,0x02affce3,0x561c8291,0x30847a21 +.long 0x52bfda05,0xd2eb2cf1,0x6197b98c,0xe0e4c4e9,0xf8a1726f,0x1d35076c,0x2db11e3d,0x6c06085b,0x4463ba14,0x15c0c4d7,0x0030238c,0x9d292f83,0x3727536d,0x1311ee8b,0xbeaedc1e,0xfeea86ef +.long 0x66131e2e,0xb9d18cd3,0x80fe2682,0xf31d974f,0xe4160289,0xb6e49e0f,0x08e92799,0x7c48ec0b,0xd1989aa7,0x818111d8,0xebf926f9,0xb34fa0aa,0xa245474a,0xdb5fe2f5,0x3c7ca756,0xf80a6ebb +.long 0xafa05dd8,0xa7f96054,0xfcaf119e,0x26dfcf21,0x0564bb59,0xe20ef2e3,0x61cb02b8,0xef4dca50,0x65d30672,0xcda7838a,0xfd657e86,0x8b08d534,0x46d595c8,0x4c5b4395,0x425cb836,0x39b58725 +.long 0x3de9abe3,0x8ea61059,0x9cdc03be,0x40434881,0xcfedce8c,0x9b261245,0xcf5234a1,0x78c318b4,0xfde24c99,0x510bcf16,0xa2c2ff5d,0x2a77cb75,0x27960fb4,0x9c895c2b,0xb0eda42b,0xd30ce975 +.long 0x1a62cc26,0xfda85393,0x50c0e052,0x23c69b96,0xbfc633f3,0xa227df15,0x1bae7d48,0x2ac78848,0x187d073d,0x487878f9,0x967f807d,0x6c2be919,0x336e6d8f,0x765861d8,0xce528a43,0x88b8974c +.long 0xff57d051,0x09521177,0xfb6a1961,0x2ff38037,0xa3d76ad4,0xfc0aba74,0x25a7ec17,0x7c764803,0x48879bc8,0x7532d75f,0x58ce6bc1,0xea7eacc0,0x8e896c16,0xc82176b4,0x2c750fed,0x9a30e0b2 +.long 0x421d3aa4,0xc37e2c2e,0xe84fa840,0xf926407c,0x1454e41c,0x18abc03d,0x3f7af644,0x26605ecd,0xd6a5eabf,0x242341a6,0x216b668e,0x1edb84f4,0x04010102,0xd836edb8,0x945e1d8c,0x5b337ce7 +.long 0xc055dc14,0xd2075c77,0x81d89cdf,0x2a0ffa25,0x6ffdcbaf,0x8ce815ea,0xfb648867,0xa3428878,0x884655fb,0x277699cf,0x364d3e41,0xfa5b5bd6,0x441e1cb7,0x01f680c6,0xb70a7d67,0x3fd61e66 +.long 0xcc78cf66,0x666ba2dc,0x6fdbff77,0xb3018174,0x168d4668,0x8d4dd0db,0x1dab3a2a,0x259455d0,0xcde3acec,0xf58564c5,0x13adb276,0x77141925,0x8a303f65,0x527d725d,0xe6f38f7b,0x55deb6c9 +.long 0xb1fa70fb,0xfd5bb657,0xd8073a00,0xfa07f50f,0xbca02500,0xf72e3aa7,0x9975740d,0xf68f895d,0x5cae2a6a,0x30112060,0x02874842,0x01bd7218,0x7ce47bd3,0x3d423891,0x789544f6,0xa66663c1 +.long 0x3272d838,0x864d05d7,0xfa6295c5,0xe22924f9,0x6c2fda32,0x8189593f,0xb184b544,0x330d7189,0xbde1f714,0x79efa62c,0xe5cb1a63,0x35771c94,0x641c8332,0x2f4826b8,0xc8cee854,0x00a894fb +.long 0x36194d40,0xb4b9a39b,0x77612601,0xe857a7c5,0x4ecf2f58,0xf4209dd2,0x5a033487,0x82b9e66d,0xe4e8b9dd,0xc1e36934,0xa42377d7,0xd2372c9d,0x0e3ae43b,0x51dc94c7,0x04474f6f,0x4c57761e +.long 0x1058a318,0xdcdacd0a,0x78053a9a,0x369cf3f5,0x31c68de2,0xc6c3de50,0x3c4b6d9f,0x4653a576,0xaa4e5c97,0x1688dd5a,0xb7ab3c74,0x5be80aa1,0xbc65c283,0x70cefe7c,0x06867091,0x57f95f13 +.long 0x4415503b,0xa39114e2,0x4cbb17e9,0xc08ff7c6,0xd7dec966,0x1eff674d,0x53376f63,0x6d4690af,0xea74237b,0xff6fe32e,0xcd57508e,0xc436d17e,0xedcc40fe,0x15aa28e1,0x581bbb44,0x0d769c04 +.long 0x34eaacda,0xc240b6de,0x2ba0f1de,0xd9e116e8,0x79438e55,0xcbe45ec7,0x96f752d7,0x91787c9d,0xf129ac2f,0x897f532b,0x5a36e22c,0xd307b7c8,0x749fb8f3,0x91940675,0x157fdb28,0xd14f95d0 +.long 0x6ae55043,0xfe51d029,0x44a87de1,0x8931e98f,0x09e4fee2,0xe57f1cc6,0x4e072d92,0x0d063b67,0xed0e4316,0x70a998b9,0x306aca46,0xe74a736b,0x4fda97c7,0xecf0fbf2,0x3e178d93,0xa40f65cb +.long 0x16df4285,0x16253604,0xd0c56ae2,0xb0c9babb,0xcfc5cfc3,0x73032b19,0x09752056,0xe497e5c3,0x164bda96,0x12096bb4,0xa0b74da1,0x1ee42419,0x403826ba,0x8fc36243,0xdc09e660,0x0c8f0069 +.long 0xc27253c9,0x8667e981,0x92b36a45,0x05a6aefb,0x9cb7bb46,0xa62c4b36,0x11f7027b,0x8394f375,0x5f109d0f,0x747bc79c,0x5b8cc60a,0xcad88a76,0x58f09e68,0x80c5a66b,0xf6127eac,0xe753d451 +.long 0x5b0ec6f5,0xc44b74a1,0x5289b2b8,0x47989fe4,0x58d6fc73,0x745f8484,0xf61c70ab,0xec362a6f,0xb3a8ad41,0x070c98a7,0x7b63db51,0x73a20fc0,0xf44c35f4,0xed2c2173,0x9acc9dca,0x8a56149d +.long 0x9ac6e0f4,0x98f17881,0xa413b5ed,0x360fdeaf,0xa300b0fd,0x0625b8f4,0x5b3222d3,0xf1f4d76a,0x587f76b8,0x9d6f5109,0x2317fdb5,0x8b4ee08d,0x8c68b095,0x88089bb7,0x5808d9b9,0x95570e9a +.long 0x35d33ae7,0xa395c36f,0x50bb5a94,0x200ea123,0x0bafe84b,0x20c789bd,0x0919276a,0x243ef52d,0xe23ae233,0x3934c577,0xa460d1ec,0xb93807af,0xf8fa76a4,0xb72a53b1,0xc3ca4491,0xd8914cb0 +.long 0x3fb42622,0x2e128494,0x500907d5,0x3b2700ac,0x1a95ec63,0xf370fb09,0x31b6dfbd,0xf8f30be2,0x69e55f15,0xf2b2f8d2,0xcc1323e9,0x1fead851,0xd9e5eef6,0xfa366010,0xe316107e,0x64d487b0 +.long 0xd23ddc82,0x4c076b86,0x7e0143f0,0x03fd344c,0x317af2c5,0xa95362ff,0xe18b7a4f,0x0add3db7,0x8260e01b,0x9c673e3f,0x54a1cc91,0xfbeb49e5,0x92f2e433,0x91351bf2,0x851141eb,0xc755e7ec +.long 0x29607745,0xc9a95139,0xa26f2b28,0x0ca07420,0x4bc6f9dd,0xcb2790e7,0xadcaffc0,0x345bbb58,0xbe0f27a2,0xc65ea38c,0x641fcb56,0x67c24d7c,0xa9e2c757,0x2c25f0a7,0x16f16c49,0x93f5cdb0 +.long 0xc5ee30a1,0x2ca5a9d7,0xb909b729,0xd1593635,0xdadeff48,0x804ce9f3,0xb07c30c3,0xec464751,0x9e49af6a,0x89d65ff3,0x6f3d01bc,0xf2d6238a,0x0bced843,0x1095561e,0xc8a13fd8,0x51789e12 +.long 0x763231df,0xd633f929,0xe7cbddef,0x46df9f7d,0xcb265da8,0x01c889c0,0xaf4336d2,0xfce1ad10,0xfc6a0a7e,0x8d110df6,0x6da425dc,0xdd431b98,0x1834aabe,0xcdc4aeab,0x8439b7fc,0x84deb124 +.long 0x3c2a5998,0x8796f169,0x7947190d,0x9b9247b4,0x11597014,0x55b9d9a5,0x7b1566ee,0x7e9dd70d,0xcbcd5e64,0x94ad78f7,0x9bd4c032,0x0359ac17,0x7cc222ae,0x3b11baaf,0xba78e812,0xa6a6e284 +.long 0x24cea1a0,0x8392053f,0x33621491,0xc97bce4a,0x35399ee9,0x7eb1db34,0xece81ad1,0x473f78ef,0xf63d3d0d,0x41d72fe0,0xafab62fc,0xe620b880,0x93158383,0x92096bc9,0x8f896f6c,0x41a21357 +.long 0xc7dcfcab,0x1b5ee2fa,0x9546e007,0x650acfde,0xb1b02e07,0xc081b749,0xf9eca03d,0xda9e41a0,0x175a54ab,0x013ba727,0xea5d8d10,0xca0cd190,0x95fd96a9,0x85ea52c0,0xbc5c3940,0x2c591b9f +.long 0x2bad4d5f,0x6fb4d4e4,0xfef0059b,0xfa4c3590,0xf5122294,0x6a10218a,0xa85751d1,0x9a78a81a,0xa98e84e7,0x04f20579,0x4997e5b5,0xfe1242c0,0xca21e1e4,0xe77a273b,0x9411939d,0xfcc8b1ef +.long 0x92d0487a,0xe20ea302,0x294b91fe,0x1442dbec,0xbb6b0e8f,0x1f7a4afe,0x6889c318,0x1700ef74,0x70f1fc62,0xf5bbffc3,0x69c79cca,0x3b31d4b6,0xa7f6340d,0xe8bc2aab,0xa725e10a,0xb0b08ab4 +.long 0xae340050,0x44f05701,0x1cf0c569,0xba4b3016,0xfbe19a51,0x5aa29f83,0xb71d752e,0x1b9ed428,0xeb4819f5,0x1666e54e,0x9e18b75b,0x616cdfed,0x3ee27b0b,0x112ed5be,0x44c7de4d,0xfbf28319 +.long 0xe0e60d84,0xd685ec85,0x1db7ee78,0x68037e30,0x003c4d6e,0x5b65bdcd,0x93e29a6a,0x33e7363a,0x08d0756c,0x995b3a61,0x2faf134b,0xd727f85c,0x1d337823,0xfac6edf7,0x0439b8b4,0x99b9aa50 +.long 0xe2b4e075,0x722eb104,0x437c4926,0x49987295,0x46a9b82d,0xb1e4c0e4,0x57a006f5,0xd0cb3197,0xd7808c56,0xf3de0f7d,0x51f89772,0xb5c54d8f,0xadbd31aa,0x500a114a,0x295f6cab,0x9afaaaa6 +.long 0x04cf667a,0x94705e21,0x9d3935d7,0xfc2a811b,0x6d09267c,0x560b0280,0xf780e53b,0xf19ed119,0x067b6269,0xf0227c09,0x5caef599,0x967b8533,0x68efeebc,0x155b9243,0xc497bae6,0xcd6d34f5 +.long 0x6cceb370,0x1dd8d5d3,0xa78d7bf9,0x2aeac579,0x70b67a62,0x5d65017d,0x17c53f67,0x70c8e44f,0x86a34d09,0xd1fc0950,0xe7134907,0xe0fca256,0x80fdd315,0xe24fa29c,0xd87499ad,0x2c4acd03 +.long 0x3b5a9ba6,0xbaaf7517,0x12e51a51,0xb9cbe1f6,0x5e154897,0xd88edae3,0x77b66ca0,0xe4309c3c,0xf67f3746,0xf5555805,0xa36401ff,0x85fc37ba,0xd9499a53,0xdf86e2ca,0xecbc955b,0x6270b2a3 +.long 0x974ad33b,0xafae64f5,0xfe7b2df1,0x04d85977,0x4ab03f73,0x2a3db3ff,0x8702740a,0x0b87878a,0x5a061732,0x6d263f01,0xa32a1901,0xc25430ce,0xdb155018,0xf7ebab3d,0x63a9b78e,0x3a86f693 +.long 0xda9f3804,0x349ae368,0xa164349c,0x470f07fe,0x8562baa5,0xd52f4cc9,0x2b290df3,0xc74a9e86,0x43471a24,0xd3a1aa35,0xb8194511,0x239446be,0x81dcd44d,0xbec2dd00,0xc42ac82d,0xca3d7f0f +.long 0xfdaf4520,0x1f3db085,0x4549daf2,0xbb6d3e80,0x19ad5c42,0xf5969d8a,0xdbfd1511,0x7052b13d,0x682b9060,0x11890d1b,0xac34452c,0xa71d3883,0x783805b4,0xa438055b,0x4725b23e,0x43241277 +.long 0x4901bbed,0xf20cf96e,0xf432a2bb,0x6419c710,0xdfa9cd7d,0x57a0fbb9,0x00daa249,0x589111e4,0x7b60554e,0x19809a33,0xede283a4,0xea5f8887,0x503bfd35,0x2d713802,0x585d2a53,0x151bb0af +.long 0x43b30ca8,0x40b08f74,0xd9934583,0xe10b5bba,0xb51110ad,0xe8a546d6,0x28e0b6c5,0x1dd50e66,0xcff2b821,0x292e9d54,0x47281760,0x3882555d,0x3724d6e3,0x134838f8,0x22ddcda1,0xf2c679e0 +.long 0x6d2a5768,0x40ee8815,0x1c1e7e2d,0x7f227bd2,0xd04ff443,0x487ba134,0xc614e54b,0x76e2ff3d,0xa3177ec7,0x36b88d6f,0x2328fff5,0xbf731d51,0x49ba158e,0x758caea2,0x02938188,0x5ab8ff4c +.long 0x35edc56d,0x33e16056,0x7e940d79,0x5a69d349,0x03866dcb,0x6c4fd001,0x4893cdef,0x20a38f57,0xfac3a15b,0xfbf3e790,0x7a4f8e6b,0x6ed7ea2e,0xbc3aca86,0xa663eb4f,0x080d53f7,0x22061ea5 +.long 0xf546783f,0x2480dfe6,0x5a0a641e,0xd38bc6da,0x2ede8965,0xfb093cd1,0xacb455cf,0x89654db4,0x26e1adee,0x413cbf9a,0x373294d4,0x291f3764,0x648083fe,0x00797257,0x208cc341,0x25f504d3 +.long 0xc3a0ee43,0x635a8e5e,0x679898ff,0x70aaebca,0x5dc63d56,0x9ee9f547,0xffb34d00,0xce987966,0x5e26310a,0xf9f86b19,0x382a8ca8,0x9e435484,0xc2352fe4,0x253bcb81,0x4474b571,0xa4eac8b0 +.long 0xc1ad8cf8,0xc1b97512,0x99e0b697,0x193b4e9e,0x01e85df0,0x939d2716,0xcd44eafd,0x4fb265b3,0xe51e1ae2,0x321e7dcd,0xe3d8b096,0x8e3a8ca6,0x52604998,0x8de46cb0,0x39072aa7,0x91099ad8 +.long 0x93aa96b8,0x2617f91c,0x7fca2e13,0x0fc8716b,0x95328723,0xa7106f5e,0x262e6522,0xd1c9c40b,0x42b7c094,0xb9bafe86,0x1543c021,0x1873439d,0x5cbefd5d,0xe1baa5de,0x521e8aff,0xa363fc5e +.long 0xf862eaac,0xefe6320d,0x22c647dc,0x14419c63,0x4e46d428,0x0e06707c,0x4a178f8f,0xcb6c834f,0xd30f917c,0x0f993a45,0x9879afee,0xd4c4b049,0x70500063,0xb6142a1e,0xa5d9d605,0x7c9b41c3 +.long 0x2f8ba2c7,0xbc00fc2f,0x7c67aa28,0x0966eb2f,0x5a786972,0x13f7b516,0x8a2fbba0,0x3bfb7557,0x5a2b9620,0x131c4f23,0x6faf46be,0xbff3ed27,0x7e172323,0x9b4473d1,0x339f6246,0x421e8878 +.long 0x25a41632,0x0fa8587a,0xa35b6c93,0xc0814124,0x59ebb8db,0x2b18a9f5,0x76edb29c,0x264e3357,0xc87c51e2,0xaf245ccd,0x501e6214,0x16b3015b,0x0a3882ce,0xbb31c560,0xfec11e04,0x6961bb94 +.long 0xeff7a3a0,0x3b825b8d,0xb1df7326,0xbec33738,0x99604a1f,0x68ad747c,0x9a3bd499,0xd154c934,0x1cc7a906,0xac33506f,0x6c560e8f,0x73bb5392,0x263e3944,0x6428fcbe,0x1c387434,0xc11828d5 +.long 0x3e4b12ff,0x3cd04be1,0x2d88667c,0xc3aad9f9,0x248120cf,0xc52ddcf8,0x2a389532,0x985a892e,0x3bb85fa0,0xfbb4b21b,0x8dfc6269,0xf95375e0,0x7ee2acea,0xfb4fb06c,0x309c4d1f,0x6785426e +.long 0xd8ceb147,0x659b17c8,0xb70a5554,0x9b649eee,0xac6bc634,0x6b7fa0b5,0x1d6e732f,0xd99fe2c7,0x8d3abba2,0x30e6e762,0xa797b799,0x18fee6e7,0xc696464d,0x5c9d360d,0x27bfde12,0xe3baeb48 +.long 0xf23206d5,0x2bf5db47,0x1d260152,0x2f6d3420,0x3f8ff89a,0x17b87653,0x378fa458,0x5157c30c,0x2d4fb936,0x7517c5c5,0xe6518cdc,0xef22f7ac,0xbf847a64,0xdeb483e6,0x92e0fa89,0xf5084558 +.long 0xdf7304d4,0xab9659d8,0xff210e8e,0xb71bcf1b,0xd73fbd60,0xa9a2438b,0x5d11b4de,0x4595cd1f,0x4835859d,0x9c0d329a,0x7dbb6e56,0x4a0f0d2d,0xdf928a4e,0xc6038e5e,0x8f5ad154,0xc9429621 +.long 0xf23f2d92,0x91213462,0x60b94078,0x6cab71bd,0x176cde20,0x6bdd0a63,0xee4d54bc,0x54c9b20c,0x9f2ac02f,0x3cd2d8aa,0x206eedb0,0x03f8e617,0x93086434,0xc7f68e16,0x92dd3db9,0x831469c5 +.long 0x8f981354,0x8521df24,0x3588a259,0x587e23ec,0xd7a0992c,0xcbedf281,0x38961407,0x06930a55,0xbe5bbe21,0x09320deb,0x2491817f,0xa7ffa5b5,0x09065160,0xe6c8b4d9,0xfff6d2a9,0xac4f3992 +.long 0x3ae9c1bd,0x7aa7a158,0xe37ce240,0xe0af6d98,0x28ab38b4,0xe54342d9,0x0a1c98ca,0xe8b75007,0xe02358f2,0xefce86af,0xea921228,0x31b8b856,0x0a1c67fc,0x052a1912,0xe3aead59,0xb4069ea4 +.long 0x7fa03cb3,0x3232d6e2,0x0fdd7d88,0xdb938e5b,0x2ccbfc5d,0x04c1d2cd,0xaf3a580f,0xd2f45c12,0x7883e614,0x592620b5,0xbe7c5f26,0x5fd27e68,0x1567e1e3,0x139e45a9,0x44d8aaaf,0x2cc71d2d +.long 0xe36d0757,0x4a9090cd,0xd9a29382,0xf722d7b1,0x04b48ddf,0xfb7fb04c,0xebe16f43,0x628ad2a7,0x20226040,0xcd3fbfb5,0x5104b6c4,0x6c34ecb1,0xc903c188,0x30c0754e,0x2d23cab0,0xec336b08 +.long 0x1e206ee5,0x473d62a2,0x8c49a633,0xf1e27480,0xe9f6b2c3,0x87ab956c,0x62b606ea,0x61830b48,0xe78e815f,0x67cd6846,0x4c02082a,0xfe40139f,0x952ec365,0x52bbbfcb,0x6b9836ab,0x74c11642 +.long 0x558df019,0x9f51439e,0xac712b27,0x230da4ba,0x55185a24,0x518919e3,0x84b78f50,0x4dcefcdd,0xa47d4c5a,0xa7d90fb2,0xb30e009e,0x55ac9abf,0x74eed273,0xfd2fc359,0xdbea8faf,0xb72d824c +.long 0x4513e2ca,0xce721a74,0x38240b2c,0x0b418612,0xd5baa450,0x05199968,0x2b0e8c25,0xeb1757ed,0x3dfac6d5,0x6ebc3e28,0x48a237f5,0xb2431e2e,0x52f61499,0x2acb5e23,0xe06c936b,0x5558a2a7 +.long 0xcbb13d1b,0xd213f923,0x5bfb9bfe,0x98799f42,0x701144a9,0x1ae8ddc9,0x4c5595ee,0x0b8b3bb6,0x3ecebb21,0x0ea9ef2e,0x3671f9a7,0x17cb6c4b,0x726f1d1f,0x47ef464f,0x6943a276,0x171b9484 +.long 0x7ef0329c,0x51a4ae2d,0x91c4402a,0x08509222,0xafd45bbc,0x64a61d35,0x3035a851,0x38f096fe,0xa1dec027,0xc7468b74,0x4fc7dcba,0xe8cf10e7,0xf4a06353,0xea35ff40,0x8b77dd66,0x0b4c0dfa +.long 0xde7e5c19,0x779b8552,0xc1c0256c,0xfab28609,0xabd4743d,0x64f58eee,0x7b6cc93b,0x4e8ef838,0x4cb1bf3d,0xee650d26,0x73dedf61,0x4c1f9d09,0xbfb70ced,0xaef7c9d7,0x1641de1e,0x1ec0507e +.long 0xcde45079,0xcd7e5cc7,0x516ac9e4,0xde173c9a,0xc170315c,0x517a8494,0x91d8e8fb,0x438fd905,0xc7d9630b,0x5145c506,0xf47d4d75,0x6457a87b,0x0d9a80e8,0xd31646bf,0xcef3aabe,0x453add2b +.long 0xa607419d,0xc9941109,0xbb6bca80,0xfaa71e62,0x07c431f3,0x34158c13,0x992bc47a,0x594abebc,0xeb78399f,0x6dfea691,0x3f42cba4,0x48aafb35,0x077c04f0,0xedcd65af,0xe884491a,0x1a29a366 +.long 0x1c21f2bf,0x023a40e5,0xa5057aee,0xf99a513c,0xbcab072e,0xa3fe7e25,0x40e32bcf,0x8568d2e1,0xd3f69d9f,0x904594eb,0x07affab1,0x181a9733,0xb6e330f4,0xe4d68d76,0xc75a7fc1,0x87a6dafb +.long 0xef7d9289,0x549db2b5,0x197f015a,0x2480d4a8,0xc40493b6,0x61d5590b,0x6f780331,0x3a55b52e,0x309eadb0,0x40eb8115,0x92e5c625,0xdea7de5a,0xcc6a3d5a,0x64d631f0,0x93e8dd61,0x9d5e9d7c +.long 0x206d3ffc,0xf297bef5,0x7d808bd4,0x23d5e033,0xd24cf5ba,0x4a4f6912,0x09cdaa8a,0xe4d8163b,0xd3082e8e,0x0e0de9ef,0x0192f360,0x4fe1246c,0x4b8eee0a,0x1f900150,0xf1da391b,0x5219da81 +.long 0xf7ea25aa,0x7bf6a5c1,0xfbb07d5f,0xd165e6bf,0x89e78671,0xe3539361,0x2bac4219,0xa3fcac89,0xf0baa8ab,0xdfab6fd4,0xe2c1c2e5,0x5a4adac1,0x40d85849,0x6cd75e31,0x19b39181,0xce263fea +.long 0x07032c72,0xcb6803d3,0x790968c8,0x7f40d5ce,0xdce978f0,0xa6de86bd,0x368f751c,0x25547c4f,0x65fb2a9e,0xb1e685fd,0x1eb9179c,0xce69336f,0x12504442,0xb15d1c27,0xb911a06b,0xb7df465c +.long 0x315980cd,0xb8d804a3,0xfa3bebf7,0x693bc492,0x2253c504,0x3578aeee,0xcd2474a2,0x158de498,0xcfda8368,0x1331f5c7,0x78d7177e,0xd2d7bbb3,0xf3c1e46e,0xdf61133a,0xd30e7be8,0x5836ce7d +.long 0x94f834cb,0x83084f19,0x429ed782,0xd35653d4,0x59e58243,0xa542f16f,0x0470a22d,0xc2b52f65,0x18f23d96,0xe3b6221b,0x3f5252b4,0xcb05abac,0x87d61402,0xca00938b,0x411933e4,0x2f186cdd +.long 0x9a29a5c5,0xe042ece5,0x3b6c8402,0xb19b3c07,0x19d92684,0xc97667c7,0xebc66372,0xb5624622,0x3c04fa02,0x0cb96e65,0x8eaa39aa,0x83a7176c,0xeaa1633f,0x2033561d,0x4533df73,0x45a9d086 +.long 0x3dc090bc,0xe0542c1d,0xaa59c167,0x82c996ef,0x0ee7fc4d,0xe3f735e8,0x7c35db79,0x7b179393,0xf8c5dbfd,0xb6419e25,0x1f327b04,0x4d9d7a1e,0x298dfca8,0x979f6f9b,0x8de9366a,0xc7c5dff1 +.long 0x04c82bdd,0x1b7a588d,0xf8319dfd,0x68005534,0xd8eb9580,0xde8a55b5,0x8d5bca81,0x5ea886da,0x252a0b4d,0xe8530a01,0x35eaa0a1,0x1bffb4fe,0xd8e99563,0x2ad828b1,0x95f9cd87,0x7de96ef5 +.long 0xd77d970c,0x4abb2d0c,0xd33ef9cb,0x03cfb933,0x8b211fe9,0xb0547c01,0xa56ed1c6,0x2fe64809,0xc2ac98cc,0xcb7d5624,0x1a393e33,0x2a1372c0,0x29660521,0xc8d1ec1c,0xb37ac3e9,0xf3d31b04 +.long 0x5ece6e7c,0xa29ae9df,0x0facfb55,0x0603ac8f,0xdda233a5,0xcfe85b7a,0xbd75f0b8,0xe618919f,0x99bf1603,0xf555a3d2,0xf184255a,0x1f43afc9,0x319a3e02,0xdcdaf341,0x03903a39,0xd3b117ef +.long 0x65d1d131,0xe095da13,0xc37ad03e,0x86f16367,0x462cd8dd,0x5f37389e,0xd67a60e6,0xc103fa04,0xf4b478f0,0x57c34344,0xe117c98d,0xce91edd8,0x231fc12e,0x001777b0,0xb207bccb,0x11ae47f2 +.long 0x20f8a242,0xd983cf8d,0xf22e1ad8,0x7aff5b1d,0x7fc4feb3,0x68fd11d0,0xb0f1c3e1,0x5d53ae90,0xec041803,0x50fb7905,0x14404888,0x85e3c977,0xac628d8f,0x0e67faed,0x6668532c,0x2e865150 +.long 0x6a67a6b0,0x15acaaa4,0xb25cec41,0xf4cdee25,0xe4c6701e,0x49ee565a,0xfc7d63d8,0x2a04ca66,0xef0543fb,0xeb105018,0xd1b0d81d,0xf709a4f5,0x2915d333,0x5b906ee6,0x96f1f0ab,0xf4a87412 +.long 0x4d82f4c2,0xb6b82fa7,0x6804efb3,0x90725a60,0xadc3425e,0xbc82ec46,0x2787843e,0xb7b80581,0xdd1fc74c,0xdf46d91c,0xe783a6c4,0xdc1c62cb,0x1a04cbba,0x59d1b9f3,0x95e40764,0xd87f6f72 +.long 0x317f4a76,0x02b4cfc1,0x91036bce,0x8d2703eb,0xa5e72a56,0x98206cc6,0xcf53fb0f,0x57be9ed1,0xef0b17ac,0x09374571,0xd9181b38,0x74b2655e,0x89935d0e,0xc8f80ea8,0x91529936,0xc0d9e942 +.long 0x1e84e0e5,0x19686041,0xaea34c93,0xa5db84d3,0x7073a732,0xf9d5bb19,0x6bcfd7c0,0xb8d2fe56,0xf3eb82fa,0x45775f36,0xfdff8b58,0x8cb20ccc,0x8374c110,0x1659b65f,0x330c789a,0xb8b4a422 +.long 0x6fe8208b,0x75e3c3ea,0x286e78fe,0xbd74b9e4,0xd7d93a1a,0x0be2e81b,0xdd0a5aae,0x7ed06e27,0x6be8b800,0x721f5a58,0xd846db28,0x428299d1,0x5be88ed3,0x95cb8e6b,0x1c034e11,0xc3186b23 +.long 0x8977d99b,0xa6312c9e,0x83f531e7,0xbe944331,0x18d3b1d4,0x8232c0c2,0xe1247b73,0x617aae8b,0x282aec3b,0x40153fc4,0xf7b8f823,0xc6063d2f,0x3304f94c,0x68f10e58,0xee676346,0x31efae74 +.long 0x40a9b97c,0xbadb6c6d,0x4f666256,0x14702c63,0x5184b2e3,0xdeb954f1,0x94b6ca40,0x5184a526,0x003c32ea,0xfff05337,0x205974c7,0x5aa374dd,0x4b0dd71a,0x9a763854,0xdeb947ec,0x459cd27f +.long 0x459c2b92,0xa6e28161,0x75ee8ef5,0x2f020fa8,0x30b06310,0xb132ec2d,0xbc6a4530,0xc3e15899,0xaa3f451a,0xdc5f53fe,0xc2d9acac,0x3a3c7f23,0x6b27e58b,0x2ec2f892,0xd742799f,0x68466ee7 +.long 0x1fa26613,0x98324dd4,0xbdc29d63,0xa2dc6dab,0xd712d657,0xf9675faa,0x21fd8d15,0x813994be,0xfd4f7553,0x5ccbb722,0xf3a36b20,0x5135ff8b,0x69559df5,0x44be28af,0x9d41bf30,0x40b65bed +.long 0x3734e520,0xd98bf2a4,0x209bdcba,0x5e3abbe3,0xbc945b35,0x77c76553,0xc6ef14aa,0x5331c093,0x76b60c80,0x518ffe29,0x7ace16f8,0x2285593b,0xbe2b9784,0xab1f64cc,0xab2421b6,0xe8f2c0d9 +.long 0xc1df065c,0x617d7174,0x5f6578fa,0xafeeb5ab,0x263b54a8,0x16ff1329,0xc990dce3,0x45c55808,0xecc8c177,0x42eab6c0,0x5982ecaa,0x799ea9b5,0xb607ef8e,0xf65da244,0x32a3fc2c,0x8ab226ce +.long 0x7ea973dc,0x745741e5,0x20888f2e,0x5c00ca70,0x45fd9cf1,0x7cdce3cf,0x5507f872,0x8a741ef1,0x196b4cec,0x47c51c2f,0xc97ea618,0x70d08e43,0x15b18a2b,0x930da15c,0x2f610514,0x33b6c678 +.long 0x07ac9794,0xc662e4f8,0xba06cb79,0x1eccf050,0xe7d954e5,0x1ff08623,0x24cf71c3,0x6ef2c5fb,0x67978453,0xb2c063d2,0x1d654af8,0xa0cf3796,0x7ebdaa37,0x7cb242ea,0xb86747e0,0x206e0b10 +.long 0xd5ecfefc,0x481dae5f,0xc2bff8fc,0x07084fd8,0xea324596,0x8040a01a,0xd4de4036,0x4c646980,0xd65abfc3,0x9eb8ab4e,0x13541ec7,0xe01cb91f,0xfd695012,0x8f029adb,0x3c7569ec,0x9ae28483 +.long 0xa66d80a1,0xa5614c9e,0x75f5f911,0x680a3e44,0xceba4fc1,0x0c07b14d,0xa13071c1,0x891c285b,0x799ece3c,0xcac67ceb,0x41e07e27,0x29b910a9,0xf2e43123,0x66bdb409,0x7ac9ecbe,0x06f8b137 +.long 0x38547090,0x5981fafd,0x85e3415d,0x19ab8b9f,0xc7e31b27,0xfc28c194,0x6fbcbb42,0x843be0aa,0xa6db836c,0xf3b1ed43,0x01a45c05,0x2a1330e4,0x95c1a377,0x4f19f3c5,0x44b5ee33,0xa85f39d0 +.long 0x4ae52834,0x3da18e6d,0x7423dcb0,0x5a403b39,0xf2374aef,0xbb555e0a,0x1e8ca111,0x2ad599c4,0x014b3bf8,0x1b3a2fb9,0xf66d5007,0x73092684,0xc4340102,0x079f1426,0x8fddf4de,0x1827cf81 +.long 0xf10ff927,0xc83605f6,0x23739fc6,0xd3871451,0xcac1c2cc,0x6d163450,0xa2ec1ac5,0x6b521296,0x6e3cb4a5,0x0606c4f9,0x778abff7,0xe47d3f41,0xbe8e3a45,0x425a8d5e,0xa6102160,0x53ea9e97 +.long 0x39cbb688,0x477a106e,0xf3386d32,0x532401d2,0xb1b9b421,0x8e564f64,0x81dad33f,0xca9b8388,0x2093913e,0xb1422b4e,0x69bc8112,0x533d2f92,0xebe7b2c7,0x3fa017be,0xcaf197c6,0xb2767c4a +.long 0xaedbae9f,0xc925ff87,0x36880a54,0x7daf0eb9,0x9c4d0e71,0x9284ddf5,0x316f8cf5,0x1581cf93,0x3ac1f452,0x3eeca887,0xfb6aeffe,0xb417fce9,0xeefb8dc3,0xa5918046,0x02209400,0x73d318ac +.long 0x728693e5,0xe800400f,0x339927ed,0xe87d814b,0x57ea9910,0x93e94d3b,0x2245fb69,0xff8a35b6,0x7f200d34,0x043853d7,0x0f653ce1,0x470f1e68,0x59a06379,0x81ac05bd,0x03930c29,0xa14052c2 +.long 0x26bc2797,0x6b72fab5,0x99f16771,0x13670d16,0x1e3e48d1,0x00170052,0xb7adf678,0x978fe401,0xd41c5dd4,0x55ecfb92,0xc7b27da5,0x5ff8e247,0x013fb606,0xe7518272,0x2f547a3c,0x5768d7e5 +.long 0x60017a5f,0xbb24eaa3,0x9c64ce9b,0x6b18e6e4,0x103dde07,0xc225c655,0x7592f7ea,0xfc3672ae,0xd06283a1,0x9606ad77,0xe4d59d99,0x542fc650,0x2a40e7c2,0xabb57c49,0xa8db9f55,0xac948f13 +.long 0xb04465c3,0x6d4c9682,0x6468bd15,0xe3d062fa,0x5f318d7e,0xa51729ac,0x9eb6fc95,0x1fc87df6,0x0591f652,0x63d146a8,0x589621aa,0xa861b8f7,0xce31348c,0x59f5f15a,0x440da6da,0x8f663391 +.long 0xb591ffa3,0xcfa778ac,0x4cdfebce,0x027ca9c5,0x444ea6b3,0xbe8e05a5,0xa78d8254,0x8aab4e69,0xb474d6b8,0x2437f04f,0x045b3855,0x6597ffd4,0xca47ecaa,0xbb0aea4e,0x85c7ebfc,0x568aae83 +.long 0xc73b2383,0x0e966e64,0xd17d8762,0x49eb3447,0x8da05dab,0xde107821,0x016b7236,0x443d8baa,0xea7610d6,0x163b63a5,0xce1ca979,0xe47e4185,0x80baa132,0xae648b65,0x0e0d5b64,0xebf53de2 +.long 0xd3c8c1ca,0x8d3bfcb4,0x5d04b309,0x0d914ef3,0x3de7d395,0x55ef6415,0x26b850e8,0xbde1666f,0xd449ab19,0xdbe1ca6e,0xe89a2672,0x8902b322,0xdacb7a53,0xb1674b7e,0xf52523ff,0x8e9faf6e +.long 0x9a85788b,0x6ba535da,0xbd0626d4,0xd21f03ae,0xe873dc64,0x099f8c47,0x018ec97e,0xcda8564d,0xde92c68c,0x3e8d7a5c,0x73323cc4,0x78e035a1,0xf880ff7c,0x3ef26275,0x273eedaa,0xa4ee3dff +.long 0xaf4e18f8,0x58823507,0x0672f328,0x967ec9b5,0x559d3186,0x9ded19d9,0x6cdce39c,0x5e2ab3de,0x11c226df,0xabad6e4d,0x87723014,0xf9783f43,0x1a885719,0x9a49a0cf,0x90da9dbf,0xfc0c1a5a +.long 0x571d92ac,0x8bbaec49,0x4692517f,0x569e85fe,0xa14ea4af,0x8333b014,0x12e5c5ad,0x32f2a62f,0x06d89b85,0x98c2ce3a,0x2ff77a08,0xb90741aa,0x01f795a2,0x2530defc,0x84b3c199,0xd6e5ba0b +.long 0x12e4c936,0x7d8e8451,0xbd0be17b,0xae419f7d,0x22262bc9,0xa583fc8c,0x91bfe2bd,0x6b842ac7,0x440d6827,0x33cef4e9,0xef81fb14,0x5f69f4de,0x234fbb92,0xf16cf6f6,0xd9e7e158,0x76ae3fc3 +.long 0xe9740b33,0x4e89f6c2,0x4962d6a1,0x677bc85d,0x68d10d15,0x6c6d8a7f,0x0257b1cd,0x5f9a7224,0x4ad85961,0x7096b916,0xe657ab4a,0x5f8c47f7,0xf7461d7e,0xde57d7d0,0x80ce5ee2,0x7eb6094d +.long 0x34190547,0x0b1e1dfd,0xf05dd150,0x8a394f43,0x97df44e6,0x0a9eb24d,0x87675719,0x78ca06bf,0x6ffeec22,0x6f0b3462,0x36cdd8fb,0x9d91bcea,0xa105be47,0xac83363c,0x069710e3,0x81ba76c1 +.long 0x28c682c6,0x3d1b24cb,0x8612575b,0x27f25228,0xe8e66e98,0xb587c779,0x405eb1fe,0x7b0c03e9,0x15b548e7,0xfdf0d030,0x38b36af7,0xa8be76e0,0x4f310c40,0x4cdab04a,0xf47ecaec,0x6287223e +.long 0x8b399320,0x678e6055,0xc01e4646,0x61fe3fa6,0x03261a5e,0xc482866b,0x5c2f244a,0xdfcf45b8,0x2f684b43,0x8fab9a51,0xc7220a66,0xf796c654,0xf5afa58f,0x1d90707e,0x4fdbe0de,0x2c421d97 +.long 0xaf2ebc2f,0xc4f4cda3,0xcb4efe24,0xa0af843d,0x9ccd10b1,0x53b857c1,0x914d3e04,0xddc9d1eb,0x62771deb,0x7bdec8bb,0x91c5aa81,0x829277aa,0x832391ae,0x7af18dd6,0xc71a84ca,0x1740f316 +.long 0xeeaf8c49,0x8928e99a,0x6e24d728,0xee7aa73d,0xe72b156c,0x4c5007c2,0xed408a1d,0x5fcf57c5,0xb6057604,0x9f719e39,0xc2868bbf,0x7d343c01,0x7e103e2d,0x2cca254b,0xf131bea2,0xe6eb38a9 +.long 0x8be762b4,0xb33e624f,0x058e3413,0x2a9ee4d1,0x67d805fa,0x968e6369,0x7db8bfd7,0x9848949b,0xd23a8417,0x5308d7e5,0xf3e29da5,0x892f3b1d,0x3dee471f,0xc95c139e,0xd757e089,0x8631594d +.long 0xde918dcc,0xe0c82a3c,0x26fdcf4b,0x2e7b5994,0x32cb1b2d,0x82c50249,0x7657ae07,0xea613a9d,0xf1fdc9f7,0xc2eb5f6c,0x879fe682,0xb6eae8b8,0x591cbc7f,0x253dfee0,0x3e1290e6,0x000da713 +.long 0x1f095615,0x1083e2ea,0x14e68c33,0x0a28ad77,0x3d8818be,0x6bfc0252,0xf35850cd,0xb585113a,0x30df8aa1,0x7d935f0b,0x4ab7e3ac,0xaddda07c,0x552f00cb,0x92c34299,0x2909df6c,0xc33ed1de +.long 0x80e87766,0x22c2195d,0x9ddf4ac0,0x9e99e6d8,0x65e74934,0x09642e4e,0xff1ff241,0x2610ffa2,0x751c8159,0x4d1d47d4,0xaf3a9363,0x697b4985,0x87477c33,0x0318ca46,0x9441eff3,0xa90cb565 +.long 0x36f024cb,0x58bb3848,0x36016168,0x85be1f77,0xdc7e07f1,0x6c59587c,0xaf1d8f02,0x191be071,0xcca5e55c,0xbf169fa5,0xf7d04eac,0x3864ba3c,0x8d7d05db,0x915e367f,0xa6549e5d,0xb48a876d +.long 0x580e40a2,0xef89c656,0x728068bc,0xf194ed8c,0xa47990c9,0x74528045,0x5e1a4649,0xf53fc7d7,0x78593e7d,0xbec5ae9b,0x41db65d7,0x2cac4ee3,0x04a3d39b,0xa8c1eb24,0x03f8f3ef,0x53b7d634 +.long 0x3e07113c,0x2dc40d48,0x7d8b63ae,0x6e4a5d39,0x79684c2b,0x5582a94b,0x622da26c,0x932b33d4,0x0dbbf08d,0xf534f651,0x64c23a52,0x211d07c9,0xee5bdc9b,0x0eeece0f,0xf7015558,0xdf178168 +.long 0x0a712229,0xd4294635,0x09273f8c,0x93cbe448,0x8f13bc83,0x00b095ef,0x8798978c,0xbb741972,0x56dbe6e7,0x9d7309a2,0x5a5d39ec,0xe578ec56,0x851f9a31,0x3961151b,0xe5709eb4,0x2da7715d +.long 0x53dfabf0,0x867f3017,0xb8e39259,0x728d2078,0x815d9958,0x5c75a0cd,0x16603be1,0xf84867a6,0x70e35b1c,0xc865b13d,0x19b03e2c,0x02414468,0xac1f3121,0xe46041da,0x6f028a7c,0x7c9017ad +.long 0x0a482873,0xabc96de9,0xb77e54d4,0x4265d6b1,0xa57d88e7,0x68c38e79,0x9ce82de3,0xd461d766,0x64a7e489,0x817a9ec5,0xa0def5f2,0xcc5675cd,0x985d494e,0x9a00e785,0x1b03514a,0xc626833f +.long 0x83cdd60e,0xabe7905a,0xa1170184,0x50602fb5,0xb023642a,0x689886cd,0xa6e1fb00,0xd568d090,0x0259217f,0x5b1922c7,0xc43141e4,0x93831cd9,0x0c95f86e,0xdfca3587,0x568ae828,0xdec2057a +.long 0xf98a759a,0xc44ea599,0xf7c23c1d,0x55a0a7a2,0x94c4f687,0xd5ffb6e6,0x12848478,0x3563cce2,0xe7b1fbe1,0x812b3517,0x4f7338e0,0x8a7dc979,0x52d048db,0x211ecee9,0xc86ea3b8,0x2eea4056 +.long 0xba772b34,0xd8cb68a7,0x5f4e2541,0xe16ed341,0x0fec14db,0x9b32f6a6,0x391698be,0xeee376f7,0x83674c02,0xe9a7aa17,0x5843022a,0x65832f97,0x5ba4990f,0x29f3a8da,0xfb8e3216,0x79a59c3a +.long 0xbd19bb16,0x9cdc4d2e,0xb3262d86,0xc6c7cfd0,0x969c0b47,0xd4ce14d0,0x13e56128,0x1fa352b7,0x973db6d3,0x383d55b8,0xe8e5b7bf,0x71836850,0xe6bb571f,0xc7714596,0x2d5b2dd2,0x259df31f +.long 0x913cc16d,0x568f8925,0xe1a26f5a,0x18bc5b6d,0xf5f499ae,0xdfa413be,0xc3f0ae84,0xf8835dec,0x65a40ab0,0xb6e60bd8,0x194b377e,0x65596439,0x92084a69,0xbcd85625,0x4f23ede0,0x5ce433b9 +.long 0x6ad65143,0xe8e8f04f,0xd6e14af6,0x11511827,0x8295c0c7,0x3d390a10,0x621eba16,0x71e29ee4,0x63717b46,0xa588fc09,0xe06ad4a2,0x02be02fe,0x04c22b22,0x931558c6,0x12f3c849,0xbb4d4bd6 +.long 0x20efd662,0x54a4f496,0xc5952d14,0x92ba6d20,0xcc9784c2,0x2db8ea1e,0x4b353644,0x81cc10ca,0x4b4d7f6c,0x40b570ad,0x84a1dcd2,0x5c9f1d96,0x3147e797,0x01379f81,0x2bd499f5,0xe5c6097b +.long 0x328e5e20,0x40dcafa6,0x54815550,0xf7b5244a,0x47bfc978,0xb9a4f118,0xd25825b1,0x0ea0e79f,0x646c7ecf,0xa50f96eb,0x446dea9d,0xeb811493,0xdfabcf69,0x2af04677,0xc713f6e8,0xbe3a068f +.long 0x42e06189,0x860d523d,0x4e3aff13,0xbf077941,0xc1b20650,0x0b616dca,0x2131300d,0xe66dd6d1,0xff99abde,0xd4a0fd67,0xc7aac50d,0xc9903550,0x7c46b2d7,0x022ecf8b,0x3abf92af,0x3333b1e8 +.long 0x6c491c14,0x11cc113c,0x80dd3f88,0x05976688,0x29d932ed,0xf5b4d9e7,0xa2c38b6d,0xe982aad8,0x8be0dcf0,0x6f925347,0x65ca53f2,0x700080ae,0x443ca77f,0xd8131156,0xec51f984,0xe92d6942 +.long 0x85dfe9ae,0xd2a08af8,0x4d2a86ca,0xd825d9a5,0x39dff020,0x2c53988d,0x430cdc40,0xf38b135a,0x62a7150b,0x0c918ae0,0x0c340e9b,0xf31fd8de,0x4dbbf02e,0xafa0e7ae,0x5eba6239,0x5847fb2a +.long 0xdccbac8b,0x6b1647dc,0x06f485c8,0xb642aa78,0x7038ecdf,0x873f3765,0xfa49d3fe,0x2ce5e865,0xc98c4400,0xea223788,0xf1fa5279,0x8104a8cd,0x06becfd7,0xbcf7cc7a,0xc8f974ae,0x49424316 +.long 0x84d6365d,0xc0da65e7,0x8f759fb8,0xbcb7443f,0x7ae81930,0x35c712b1,0x4c6e08ab,0x80428dff,0xa4faf843,0xf19dafef,0xffa9855f,0xced8538d,0xbe3ac7ce,0x20ac409c,0x882da71e,0x358c1fb6 +.long 0xfd349961,0xafa9c0e5,0x8421c2fc,0x2b2cfa51,0xf3a28d38,0x2a80db17,0x5d138e7e,0xa8aba539,0x6e96eb8d,0x52012d1d,0xcbaf9622,0x65d8dea0,0xb264f56c,0x57735447,0x1b6c8da2,0xbeebef3f +.long 0xce785254,0xfc346d98,0xbb64a161,0xd50e8d72,0x49794add,0xc03567c7,0x752c7ef6,0x15a76065,0x961f23d6,0x59f3a222,0x73ecc0b0,0x378e4438,0x5a82fde4,0xc74be434,0xd8b9cf34,0xae509af2 +.long 0x577f44a1,0x4a61ee46,0xb611deeb,0xe09b748c,0xf5f7b884,0xc0481b2c,0x61acfa6b,0x35626678,0xbf8d21e6,0x37f4c518,0xb205a76d,0x22d96531,0x954073c0,0x37fb85e1,0x65b3a567,0xbceafe4f +.long 0xbe42a582,0xefecdef7,0x65046be6,0xd3fc6080,0x09e8dba9,0xc9af13c8,0x641491ff,0x1e6c9847,0xd30c31f7,0x3b574925,0xac2a2122,0xb7eb72ba,0xef0859e7,0x776a0dac,0x21900942,0x06fec314 +.long 0xf8c22049,0x2464bc10,0x875ebf69,0x9bfbcce7,0x4336326b,0xd7a88e2a,0x5bc2acfa,0xda05261c,0xeba7efc8,0xc29f5bdc,0x25dbbf2e,0x471237ca,0x2975f127,0xa72773f2,0x04d0b326,0xdc744e8e +.long 0xa56edb73,0x38a7ed16,0x2c007e70,0x64357e37,0x5080b400,0xa167d15b,0x23de4be1,0x07b41164,0x74c89883,0xb2d91e32,0x2882e7ed,0x3c162821,0x7503e482,0xad6b36ba,0x0ea34331,0x48434e8e +.long 0x2c7ae0b9,0x79f4f24f,0x1939b44a,0xc46fbf81,0x56595eb1,0x76fefae8,0xcd5f29c7,0x417b66ab,0xc5ceec20,0x5f2332b2,0xe1a1cae2,0xd69661ff,0x9b0286e6,0x5ede7e52,0xe276b993,0x9d062529 +.long 0x7e50122b,0x324794b0,0x4af07ca5,0xdd744f8b,0xd63fc97b,0x30a12f08,0x76626d9d,0x39650f1a,0x1fa38477,0x101b47f7,0xd4dc124f,0x3d815f19,0xb26eb58a,0x1569ae95,0x95fb1887,0xc3cde188 +.long 0xf9539a48,0x54e9f37b,0x7408c1a5,0xb0100e06,0xea580cbb,0x821d9811,0x86e50c56,0x8af52d35,0xdbbf698b,0xdfbd9d47,0x03dc1c73,0x2961a1ea,0xe76a5df8,0x203d38f8,0x6def707a,0x08a53a68 +.long 0x1bee45d4,0x26eefb48,0x3c688036,0xb3cee346,0xc42f2469,0x463c5315,0x81378162,0x19d84d2e,0x1c4d349f,0x22d7c3c5,0x163d59c5,0x65965844,0xb8abceae,0xcf198c56,0x628559d5,0x6fb1fb1b +.long 0x07bf8fe3,0x8bbffd06,0x3467734b,0x46259c58,0x35f7f0d3,0xd8953cea,0xd65b0ff1,0x1f0bece2,0xf3c72914,0xf7d5b4b3,0x3cb53389,0x29e8ea95,0x836b6d46,0x4a365626,0xea174fde,0xe849f910 +.long 0xf4737f21,0x7ec62fbb,0x6209f5ac,0xd8dba5ab,0xa5f9adbe,0x24b5d7a9,0xa61dc768,0x707d28f7,0xcaa999ea,0x7711460b,0x1c92e4cc,0xba7b174d,0x18d4bf2d,0x3c4bab66,0xeb8bd279,0xb8f0c980 +.long 0x324b4737,0x024bea9a,0x32a83bca,0xfba9e423,0xa232dced,0x6e635643,0x2571c8ba,0x99619367,0x54b7032b,0xe8c9f357,0x2442d54a,0xf936b3ba,0x8290c65a,0x2263f0f0,0xee2c7fdb,0x48989780 +.long 0x13d4f95e,0xadc5d55a,0xad9b8500,0x737cff85,0x8a73f43d,0x271c557b,0xe18bc476,0xbed617a4,0x7dfd8ab2,0x66245401,0x3a2870aa,0xae7b89ae,0x23a7e545,0x1b555f53,0xbe057e4c,0x6791e247 +.long 0x324fa34d,0x860136ad,0x4cbeae28,0xea111447,0xbedd3299,0x023a4270,0xc1c35c34,0x3d5c3a7f,0x8d0412d2,0xb0f6db67,0xfcdc6b9a,0xd92625e2,0x4e28a982,0x92ae5ccc,0x47a3ce7e,0xea251c36 +.long 0x790691bf,0x9d658932,0x06b736ae,0xed610589,0xc0d63b6e,0x712c2f04,0xc63d488f,0x5cf06fd5,0xd9588e41,0x97363fac,0x2b93257e,0x1f9bf762,0x667acace,0xa9d1ffc4,0x0a061ecf,0x1cf4a1aa +.long 0xdc1818d0,0x40e48a49,0xa3621ab0,0x0643ff39,0xe39ef639,0x5768640c,0x04d86854,0x1fc099ea,0xeccd28fd,0x9130b9c3,0x7eec54ab,0xd743cbd2,0xe5b475b6,0x052b146f,0x900a7d1f,0x058d9a82 +.long 0x91262b72,0x65e02292,0xbb0edf03,0x96f924f9,0xfe206842,0x5cfa59c8,0x5eafa720,0xf6037004,0x18d7dd96,0x5f30699e,0xcbab2495,0x381e8782,0xdd8be949,0x91669b46,0x26aae8ef,0xb40606f5 +.long 0xfc6751a4,0x2812b839,0xfba800ef,0x16196214,0x4c1a2875,0x4398d5ca,0x653d8349,0x720c00ee,0xd820007c,0xc2699eb0,0xa39b5825,0x880ee660,0x471f6984,0x70694694,0xe3dda99a,0xf7d16ea8 +.long 0xc0519a23,0x28d675b2,0x4f6952e3,0x9ebf94fe,0xa2294a8a,0xf28bb767,0xfe0af3f5,0x85512b4d,0x99b16a0d,0x18958ba8,0xba7548a7,0x95c2430c,0xa16be615,0xb30d1b10,0x85bfb74c,0xe3ebbb97 +.long 0x18549fdb,0xa3273cfe,0x4fcdb792,0xf6e200bf,0x83aba56c,0x54a76e18,0x89ef6aa2,0x73ec66f6,0xd1b9a305,0x8d17add7,0xb7ae1b9d,0xa959c5b9,0x6bcc094a,0x88643522,0xd7d429b9,0xcc5616c4 +.long 0xe6a33f7c,0xa6dada01,0x9d4e70ad,0xc6217a07,0x09c15b7c,0xd619a818,0x0e80c854,0xea06b329,0xa5f5e7b9,0x174811ce,0x787c65f4,0x66dfc310,0x3316ab54,0x4ea7bd69,0x1dcc0f70,0xc12c4acb +.long 0x1e407dd9,0xe4308d1a,0x91afa997,0xe8a3587c,0xab77b7a5,0xea296c12,0x673c0d52,0xb5ad49e4,0x7006085a,0x40f9b2b2,0x87bf6ec2,0xa88ff340,0x4e3066a6,0x978603b1,0xb5e486e2,0xb3f99fc2 +.long 0xb2e63645,0x07b53f5e,0x84c84232,0xbe57e547,0x7214d5cf,0xd779c216,0x029a3aca,0x617969cd,0x8a7017a0,0xd17668cd,0xbe9b7ee8,0x77b4d19a,0x9c161776,0x58fd0e93,0xd5968a72,0xa8c4f4ef +.long 0x67b3de77,0x296071cc,0x634f7905,0xae3c0b8e,0x8a7100c9,0x67e440c2,0xeb4b9b42,0xbb8c3c1b,0xc51b3583,0x6d71e8ea,0x9525e642,0x7591f5af,0x13f509f3,0xf73a2f7b,0x5619ac9b,0x618487aa +.long 0x9d61718a,0x3a72e5f7,0x7592d28c,0x00413bcc,0x963c35cf,0x7d9b11d3,0xb90a46ed,0x77623bcf,0xdcdd2a50,0xdeef273b,0x0601846e,0x4a741f9b,0x0ec6e929,0x33b89e51,0x8b7f22cd,0xcb02319f +.long 0x084bae24,0xbbe1500d,0x343d2693,0x2f0ae8d7,0x7cdef811,0xacffb5f2,0x263fb94f,0xaa0c030a,0xa0f442de,0x6eef0d61,0x27b139d3,0xf92e1817,0x0ad8bc28,0x1ae6deb7,0xc0514130,0xa89e38dc +.long 0xd2fdca23,0x81eeb865,0xcc8ef895,0x5a15ee08,0x01905614,0x768fa10a,0x880ee19b,0xeff5b8ef,0xcb1c8a0e,0xf0c0cabb,0xb8c838f9,0x2e1ee9cd,0x8a4a14c0,0x0587d8b8,0x2ff698e5,0xf6f27896 +.long 0x89ee6256,0xed38ef1c,0x6b353b45,0xf44ee1fe,0x70e903b3,0x9115c0c7,0x818f31df,0xc78ec0a1,0xb7dccbc6,0x6c003324,0x163bbc25,0xd96dd1f3,0x5cedd805,0x33aa82dd,0x7f7eb2f1,0x123aae4f +.long 0xa26262cd,0x1723fcf5,0x0060ebd5,0x1f7f4d5d,0xb2eaa3af,0xf19c5c01,0x9790accf,0x2ccb9b14,0x52324aa6,0x1f9c1cad,0x7247df54,0x63200526,0xbac96f82,0x5732fe42,0x01a1c384,0x52fe771f +.long 0xb1001684,0x546ca13d,0xa1709f75,0xb56b4eee,0xd5db8672,0x266545a9,0x1e8f3cfb,0xed971c90,0xe3a07b29,0x4e7d8691,0xe4b696b9,0x7570d9ec,0x7bc7e9ae,0xdc5fa067,0xc82c4844,0x68b44caf +.long 0xbf44da80,0x519d34b3,0x5ab32e66,0x283834f9,0x6278a000,0x6e608797,0x627312f6,0x1e62960e,0xe6901c55,0x9b87b27b,0x24fdbc1f,0x80e78538,0x2facc27d,0xbbbc0951,0xac143b5a,0x06394239 +.long 0x376c1944,0x35bb4a40,0x63da1511,0x7cb62694,0xb7148a3b,0xafd29161,0x4e2ea2ee,0xa6f9d9ed,0x880dd212,0x15dc2ca2,0xa61139a9,0x903c3813,0x6c0f8785,0x2aa7b46d,0x901c60ff,0x36ce2871 +.long 0xe10d9c12,0xc683b028,0x032f33d3,0x7573baa2,0x67a31b58,0x87a9b1f6,0xf4ffae12,0xfd3ed11a,0x0cb2748e,0x83dcaa9a,0x5d6fdf16,0x8239f018,0x72753941,0xba67b49c,0xc321cb36,0x2beec455 +.long 0x3f8b84ce,0x88015606,0x8d38c86f,0x76417083,0x598953dd,0x054f1ca7,0x4e8e7429,0xc939e110,0x5a914f2f,0x9b1ac2b3,0xe74b8f9c,0x39e35ed3,0x781b2fb0,0xd0debdb2,0x2d997ba2,0x1585638f +.long 0x9e2fce99,0x9c4b646e,0x1e80857f,0x68a21081,0x3643b52a,0x06d54e44,0x0d8eb843,0xde8d6d63,0x42146a0a,0x70321563,0x5eaa3622,0x8ba826f2,0x86138787,0x227a58bd,0x10281d37,0x43b6c03c +.long 0xb54dde39,0x6326afbb,0xdb6f2d5f,0x744e5e8a,0xcff158e1,0x48b2a99a,0xef87918f,0xa93c8fa0,0xde058c5c,0x2182f956,0x936f9e7a,0x216235d2,0xd2e31e67,0xace0c0db,0xf23ac3e7,0xc96449bf +.long 0x170693bd,0x7e9a2874,0xa45e6335,0xa28e14fd,0x56427344,0x5757f6b3,0xacf8edf9,0x822e4556,0xe6a285cd,0x2b7a6ee2,0xa9df3af0,0x5866f211,0xf845b844,0x40dde2dd,0x110e5e49,0x986c3726 +.long 0xf7172277,0x73680c2a,0x0cccb244,0x57b94f0f,0x2d438ca7,0xbdff7267,0xcf4663fd,0xbad1ce11,0xd8f71cae,0x9813ed9d,0x961fdaa6,0xf43272a6,0xbd6d1637,0xbeff0119,0x30361978,0xfebc4f91 +.long 0x2f41deff,0x02b37a95,0xe63b89b7,0x0e44a59a,0x143ff951,0x673257dc,0xd752baf4,0x19c02205,0xc4b7d692,0x46c23069,0xfd1502ac,0x2e6392c3,0x1b220846,0x6057b1a2,0x0c1b5b63,0xe51ff946 +.long 0x566c5c43,0x6e85cb51,0x3597f046,0xcff9c919,0x4994d94a,0x9354e90c,0x2147927d,0xe0a39332,0x0dc1eb2b,0x8427fac1,0x2ff319fa,0x88cfd8c2,0x01965274,0xe2d4e684,0x67aaa746,0xfa2e067d +.long 0x3e5f9f11,0xb6d92a7f,0xd6cb3b8e,0x9afe153a,0xddf800bd,0x4d1a6dd7,0xcaf17e19,0xf6c13cc0,0x325fc3ee,0x15f6c58e,0xa31dc3b2,0x71095400,0xafa3d3e7,0x168e7c07,0x94c7ae2d,0x3f8417a1 +.long 0x813b230d,0xec234772,0x17344427,0x634d0f5f,0xd77fc56a,0x11548ab1,0xce06af77,0x7fab1750,0x4f7c4f83,0xb62c10a7,0x220a67d9,0xa7d2edc4,0x921209a0,0x1c404170,0xface59f0,0x0b9815a0 +.long 0x319540c3,0x2842589b,0xa283d6f8,0x18490f59,0xdaae9fcb,0xa2731f84,0xc3683ba0,0x3db6d960,0x14611069,0xc85c63bb,0x0788bf05,0xb19436af,0x347460d2,0x905459df,0xe11a7db1,0x73f6e094 +.long 0xb6357f37,0xdc7f938e,0x2bd8aa62,0xc5d00f79,0x2ca979fc,0xc878dcb9,0xeb023a99,0x37e83ed9,0x1560bf3d,0x6b23e273,0x1d0fae61,0x1086e459,0x9a9414bd,0x78248316,0xf0ea9ea1,0x1b956bc0 +.long 0xc31b9c38,0x7b85bb91,0x48ef57b5,0x0c5aa90b,0xaf3bab6f,0xdedeb169,0x2d373685,0xe610ad73,0x02ba8e15,0xf13870df,0x8ca7f771,0x0337edb6,0xb62c036c,0xe4acf747,0xb6b94e81,0xd921d576 +.long 0x2c422f7a,0xdbc86439,0xed348898,0xfb635362,0xc45bfcd1,0x83084668,0x2b315e11,0xc357c9e3,0x5b2e5b8c,0xb173b540,0xe102b9a4,0x7e946931,0x7b0fb199,0x17c890eb,0xd61b662b,0xec225a83 +.long 0xee3c76cb,0xf306a3c8,0xd32a1f6e,0x3cf11623,0x6863e956,0xe6d5ab64,0x5c005c26,0x3b8a4cbe,0x9ce6bb27,0xdcd529a5,0x04d4b16f,0xc4afaa52,0x7923798d,0xb0624a26,0x6b307fab,0x85e56df6 +.long 0x2bf29698,0x0281893c,0xd7ce7603,0x91fc19a4,0xad9a558f,0x75a5dca3,0x4d50bf77,0x40ceb3fa,0xbc9ba369,0x1baf6060,0x597888c2,0x927e1037,0x86a34c07,0xd936bf19,0xc34ae980,0xd4cf10c1 +.long 0x859dd614,0x3a3e5334,0x18d0c8ee,0x9c475b5b,0x07cd51d5,0x63080d1f,0xb88b4326,0xc9c0d0a6,0xc234296f,0x1ac98691,0x94887fb6,0x2a0a83a4,0x0cea9cf2,0x56511427,0xa24802f5,0x5230a6e8 +.long 0x72e3d5c1,0xf7a2bf0f,0x4f21439e,0x37717446,0x9ce30334,0xfedcbf25,0x7ce202f9,0xe0030a78,0x1202e9ca,0x6f2d9ebf,0x75e6e591,0xe79dde6c,0xf1dac4f8,0xf52072af,0xbb9b404d,0x6c8d087e +.long 0xbce913af,0xad0fc73d,0x458a07cb,0x909e587b,0xd4f00c8a,0x1300da84,0xb54466ac,0x425cd048,0x90e9d8bf,0xb59cb9be,0x3e431b0e,0x991616db,0x531aecff,0xd3aa117a,0x59f4dc3b,0x91af92d3 +.long 0xe93fda29,0x9b1ec292,0xe97d91bc,0x76bb6c17,0xaface1e6,0x7509d95f,0xbe855ae3,0x3653fe47,0x0f680e75,0x73180b28,0xeeb6c26c,0x75eefd1b,0xb66d4236,0xa4cdf29f,0x6b5821d8,0x2d70a997 +.long 0x20445c36,0x7a3ee207,0x59877174,0x71d1ac82,0x949f73e9,0x0fc539f7,0x982e3081,0xd05cf3d7,0x7b1c7129,0x8758e20b,0x569e61f2,0xffadcc20,0x59544c2d,0xb05d3a2f,0x9fff5e53,0xbe16f5c1 +.long 0xaad58135,0x73cf65b8,0x037aa5be,0x622c2119,0x646fd6a0,0x79373b3f,0x0d3978cf,0x0e029db5,0x94fba037,0x8bdfc437,0x620797a6,0xaefbd687,0xbd30d38e,0x3fa5382b,0x585d7464,0x7627cfbf +.long 0x4e4ca463,0xb2330fef,0x3566cc63,0xbcef7287,0xcf780900,0xd161d2ca,0x5b54827d,0x135dc539,0x27bf1bc6,0x638f052e,0x07dfa06c,0x10a224f0,0x6d3321da,0xe973586d,0x26152c8f,0x8b0c5738 +.long 0x34606074,0x07ef4f2a,0xa0f7047a,0x80fe7fe8,0xe1a0e306,0x3d1a8152,0x88da5222,0x32cf43d8,0x5f02ffe6,0xbf89a95f,0x806ad3ea,0x3d9eb9a4,0x79c8e55e,0x012c17bb,0x99c81dac,0xfdcd1a74 +.long 0xb9556098,0x7043178b,0x801c3886,0x4090a1df,0x9b67b912,0x759800ff,0x232620c8,0x3e5c0304,0x70dceeca,0x4b9d3c4b,0x181f648e,0xbb2d3c15,0x6e33345c,0xf981d837,0x0cf2297a,0xb626289b +.long 0x8baebdcf,0x766ac659,0x75df01e5,0x1a28ae09,0x375876d8,0xb71283da,0x607b9800,0x4865a96d,0x237936b2,0x25dd1bcd,0x60417494,0x332f4f4b,0x370a2147,0xd0923d68,0xdc842203,0x497f5dfb +.long 0x32be5e0f,0x9dc74cbd,0x17a01375,0x7475bcb7,0x50d872b1,0x438477c9,0xffe1d63d,0xcec67879,0xd8578c70,0x9b006014,0x78bb6b8b,0xc9ad99a8,0x11fb3806,0x6799008e,0xcd44cab3,0xcfe81435 +.long 0x2f4fb344,0xa2ee1582,0x483fa6eb,0xb8823450,0x652c7749,0x622d323d,0xbeb0a15b,0xd8474a98,0x5d1c00d0,0xe43c154d,0x0e3e7aac,0x7fd581d9,0x2525ddf8,0x2b44c619,0xb8ae9739,0x67a033eb +.long 0x9ef2d2e4,0x113ffec1,0xd5a0ea7f,0x1bf6767e,0x03714c0a,0x57fff75e,0x0a23e9ee,0xa23c422e,0x540f83af,0xdd5f6b2d,0x55ea46a7,0xc2c2c27e,0x672a1208,0xeb6b4246,0xae634f7a,0xd13599f7 +.long 0xd7b32c6e,0xcf914b5c,0xeaf61814,0x61a5a640,0x208a1bbb,0x8dc3df8b,0xb6d79aa5,0xef627fd6,0xc4c86bc8,0x44232ffc,0x061539fe,0xe6f9231b,0x958b9533,0x1d04f25a,0x49e8c885,0x180cf934 +.long 0x9884aaf7,0x89689595,0x07b348a6,0xb1959be3,0x3c147c87,0x96250e57,0xdd0c61f8,0xae0efb3a,0xca8c325e,0xed00745e,0xecff3f70,0x3c911696,0x319ad41d,0x73acbc65,0xf0b1c7ef,0x7b01a020 +.long 0x63a1483f,0xea32b293,0x7a248f96,0x89eabe71,0x343157e5,0x9c6231d3,0xdf3c546d,0x93a375e5,0x6a2afe69,0xe76e9343,0xe166c88e,0xc4f89100,0x4f872093,0x248efd0d,0x8fe0ea61,0xae0eb3ea +.long 0x9d79046e,0xaf89790d,0x6cee0976,0x4d650f2d,0x43071eca,0xa3935d9a,0x283b0bfe,0x66fcd2c9,0x696605f1,0x0e665eb5,0xa54cd38d,0xe77e5d07,0x43d950cf,0x90ee050a,0xd32e69b5,0x86ddebda +.long 0xfddf7415,0x6ad94a3d,0x3f6e8d5a,0xf7fa1309,0xe9957f75,0xc4831d1d,0xd5817447,0x7de28501,0x9e2aeb6b,0x6f1d7078,0xf67a53c2,0xba2b9ff4,0xdf9defc3,0x36963767,0x0d38022c,0x479deed3 +.long 0x3a8631e8,0xd2edb89b,0x7a213746,0x8de855de,0xb00c5f11,0xb2056cb7,0x2c9b85e4,0xdeaefbd0,0xd150892d,0x03f39a8d,0x218b7985,0x37b84686,0xb7375f1a,0x36296dd8,0xb78e898e,0x472cd4b1 +.long 0xe9f05de9,0x15dff651,0x2ce98ba9,0xd4045069,0x9b38024c,0x8466a7ae,0xe5a6b5ef,0xb910e700,0xb3aa8f0d,0xae1c56ea,0x7eee74a6,0xbab2a507,0x4b4c4620,0x0dca11e2,0x4c47d1f4,0xfd896e2e +.long 0x308fbd93,0xeb45ae53,0x02c36fda,0x46cd5a2e,0xbaa48385,0x6a3d4e90,0x9dbe9960,0xdd55e62e,0x2a81ede7,0xa1406aa0,0xf9274ea7,0x6860dd14,0x80414f86,0xcfdcb0c2,0x22f94327,0xff410b10 +.long 0x49ad467b,0x5a33cc38,0x0a7335f1,0xefb48b6c,0xb153a360,0x14fb54a4,0xb52469cc,0x604aa9d2,0x754e48e9,0x5e9dc486,0x37471e8e,0x693cb455,0x8d3b37b6,0xfb2fd7cd,0xcf09ff07,0x63345e16 +.long 0x23a5d896,0x9910ba6b,0x7fe4364e,0x1fe19e35,0x9a33c677,0x6e1da8c3,0x29fd9fd0,0x15b4488b,0x1a1f22bf,0x1f439254,0xab8163e8,0x920a8a70,0x07e5658e,0x3fd1b249,0xb6ec839b,0xf2c4f79c +.long 0x4aa38d1b,0x1abbc3d0,0xb5d9510e,0x3b0db35c,0x3e60dec0,0x1754ac78,0xea099b33,0x53272fd7,0x07a8e107,0x5fb0494f,0x6a8191fa,0x4a89e137,0x3c4ad544,0xa113b7f6,0x6cb9897b,0x88a2e909 +.long 0xb44a3f84,0x17d55de3,0x17c6c690,0xacb2f344,0x10232390,0x32088168,0x6c733bf7,0xf2e8a61f,0x9c2d7652,0xa774aab6,0xed95c5bc,0xfb5307e3,0x4981f110,0xa05c73c2,0xa39458c9,0x1baae31c +.long 0xcbea62e7,0x1def185b,0xeaf63059,0xe8ac9eae,0x9921851c,0x098a8cfd,0x3abe2f5b,0xd959c3f1,0x20e40ae5,0xa4f19525,0x07a24aa1,0x320789e3,0x7392b2bc,0x259e6927,0x1918668b,0x58f6c667 +.long 0xc55d2d8b,0xce1db2bb,0xf4f6ca56,0x41d58bb7,0x8f877614,0x7650b680,0xf4c349ed,0x905e16ba,0xf661acac,0xed415140,0xcb2270af,0x3b8784f0,0x8a402cba,0x3bc280ac,0x0937921a,0xd53f7146 +.long 0xe5681e83,0xc03c8ee5,0xf6ac9e4a,0x62126105,0x936b1a38,0x9503a53f,0x782fecbd,0x3d45e2d4,0x76e8ae98,0x69a5c439,0xbfb4b00e,0xb53b2eeb,0x72386c89,0xf1674712,0x4268bce4,0x30ca34a2 +.long 0x78341730,0x7f1ed86c,0xb525e248,0x8ef5beb8,0xb74fbf38,0xbbc489fd,0x91a0b382,0x38a92a0e,0x22433ccf,0x7a77ba3f,0xa29f05a9,0xde8362d6,0x61189afc,0x7f6a30ea,0x59ef114f,0x693b5505 +.long 0xcd1797a1,0x50266bc0,0xf4b7af2d,0xea17b47e,0x3df9483e,0xd6c4025c,0xa37b18c9,0x8cbb9d9f,0x4d8424cf,0x91cbfd9c,0xab1c3506,0xdb7048f1,0x028206a3,0x9eaf641f,0x25bdf6ce,0xf986f3f9 +.long 0x224c08dc,0x262143b5,0x81b50c91,0x2bbb09b4,0xaca8c84f,0xc16ed709,0xb2850ca8,0xa6210d9d,0x09cb54d6,0x6d8df67a,0x500919a4,0x91eef6e0,0x0f132857,0x90f61381,0xf8d5028b,0x9acede47 +.long 0x90b771c3,0x844d1b71,0xba6426be,0x563b71e4,0xbdb802ff,0x2efa2e83,0xab5b4a41,0x3410cbab,0x30da84dd,0x555b2d26,0xee1cc29a,0xd0711ae9,0x2f547792,0xcf3e8c60,0xdc678b35,0x03d7d5de +.long 0xced806b8,0x071a2fa8,0x697f1478,0x222e6134,0xabfcdbbf,0xdc16fd5d,0x121b53b8,0x44912ebf,0x2496c27c,0xac943674,0x1ffc26b0,0x8ea3176c,0x13debf2c,0xb6e224ac,0xf372a832,0x524cc235 +.long 0x9f6f1b18,0xd706e1d8,0x44cce35b,0x2552f005,0xa88e31fc,0x8c8326c2,0xf9552047,0xb5468b2c,0x3ff90f2b,0xce683e88,0x2f0a5423,0x77947bdf,0xed56e328,0xd0a1b28b,0xc20134ac,0xaee35253 +.long 0x3567962f,0x7e98367d,0x8188bffb,0x379ed61f,0xfaf130a1,0x73bba348,0x904ed734,0x6c1f75e1,0x3b4a79fc,0x18956642,0x54ef4493,0xf20bc83d,0x9111eca1,0x836d425d,0x009a8dcf,0xe5b5c318 +.long 0x13221bc5,0x3360b25d,0x6b3eeaf7,0x707baad2,0x743a95a1,0xd7279ed8,0x969e809f,0x7450a875,0xe5d0338f,0x32b6bd53,0x2b883bbc,0x1e77f7af,0x1063ecd0,0x90da12cc,0xc315be47,0xe2697b58 +.long 0xda85d534,0x2771a5bd,0xff980eea,0x53e78c1f,0x900385e7,0xadf1cf84,0xc9387b62,0x7d3b14f6,0xcb8f2bd2,0x170e74b0,0x827fa993,0x2d50b486,0xf6f32bab,0xcdbe8c9a,0xc3b93ab8,0x55e906b0 +.long 0x8fe280d1,0x747f22fc,0xb2e114ab,0xcd8e0de5,0xe10b68b0,0x5ab7dbeb,0xa480d4b2,0x9dc63a9c,0x4be1495f,0x78d4bc3b,0x9359122d,0x25eb3db8,0x0809cbdc,0x3f8ac05b,0xd37c702f,0xbf4187bb +.long 0x1416a6a5,0x84cea069,0x43ef881c,0x8f860c79,0x38038a5d,0x41311f8a,0xfc612067,0xe78c2ec0,0x5ad73581,0x494d2e81,0x59604097,0xb4cc9e00,0xf3612cba,0xff558aec,0x9e36c39e,0x35beef7a +.long 0xdbcf41b9,0x1845c7cf,0xaea997c0,0x5703662a,0xe402f6d8,0x8b925afe,0x4dd72162,0xd0a1b1ae,0x03c41c4b,0x9f47b375,0x0391d042,0xa023829b,0x503b8b0a,0x5f5045c3,0x98c010e5,0x123c2688 +.long 0x36ba06ee,0x324ec0cc,0x3dd2cc0c,0xface3115,0xf333e91f,0xb364f3be,0x28e832b0,0xef8aff73,0x2d05841b,0x1e9bad04,0x356a21e2,0x42f0e3df,0x4add627e,0xa3270bcb,0xd322e711,0xb09a8158 +.long 0x0fee104a,0x86e326a1,0x3703f65d,0xad7788f8,0x47bc4833,0x7e765430,0x2b9b893a,0x6cee582b,0xe8f55a7b,0x9cd2a167,0xd9e4190d,0xefbee3c6,0xd40c2e9d,0x33ee7185,0xa380b548,0x844cc9c5 +.long 0x66926e04,0x323f8ecd,0x8110c1ba,0x0001e38f,0xfc6a7f07,0x8dbcac12,0x0cec0827,0xd65e1d58,0xbe76ca2d,0xd2cd4141,0xe892f33a,0x7895cf5c,0x367139d2,0x956d230d,0xd012c4c1,0xa91abd3e +.long 0x87eb36bf,0x34fa4883,0x914b8fb4,0xc5f07102,0xadb9c95f,0x90f0e579,0x28888195,0xfe6ea8cb,0xedfa9284,0x7b9b5065,0x2b8c8d65,0x6c510bd2,0xcbe8aafd,0xd7b8ebef,0x96b1da07,0xedb3af98 +.long 0x6295d426,0x28ff779d,0x3fa3ad7b,0x0c4f6ac7,0x8b8e2604,0xec44d054,0x8b0050e1,0x9b32a66d,0xf0476ce2,0x1f943366,0xa602c7b4,0x7554d953,0x524f2809,0xbe35aca6,0xfd4edbea,0xb6881229 +.long 0x508efb63,0xe8cd0c8f,0x6abcefc7,0x9eb5b5c8,0xb441ab4f,0xf5621f5f,0xb76a2b22,0x79e6c046,0xe37a1f69,0x74a4792c,0x03542b60,0xcbd252cb,0xb3c20bd3,0x785f65d5,0x4fabc60c,0x8dea6143 +.long 0xde673629,0x45e21446,0x703c2d21,0x57f7aa1e,0x98c868c7,0xa0e99b7f,0x8b641676,0x4e42f66d,0x91077896,0x602884dc,0xc2c9885b,0xa0d690cf,0x3b9a5187,0xfeb4da33,0x153c87ee,0x5f789598 +.long 0x52b16dba,0x2192dd47,0x3524c1b1,0xdeefc0e6,0xe4383693,0x465ea76e,0x361b8d98,0x79401711,0xf21a15cb,0xa5f9ace9,0xefee9aeb,0x73d26163,0xe677016c,0xcca844b3,0x57eaee06,0x6c122b07 +.long 0x15f09690,0xb782dce7,0x2dfc0fc9,0x508b9b12,0x65d89fc6,0x9015ab4b,0xd6d5bb0f,0x5e79dab7,0x6c775aa2,0x64f021f0,0x37c7eca1,0xdf09d8cc,0xef2fa506,0x9a761367,0x5b81eec6,0xed4ca476 +.long 0x10bbb8b5,0x262ede36,0x0641ada3,0x0737ce83,0xe9831ccc,0x4c94288a,0x8065e635,0x487fc1ce,0xb8bb3659,0xb13d7ab3,0x855e4120,0xdea5df3e,0x85eb0244,0xb9a18573,0xa7cfe0a3,0x1a1b8ea3 +.long 0x67b0867c,0x3b837119,0x9d364520,0x8d5e0d08,0xd930f0e3,0x52dccc1e,0xbf20bbaf,0xefbbcec7,0x0263ad10,0x99cffcab,0xfcd18f8a,0xd8199e6d,0xe9f10617,0x64e2773f,0x08704848,0x0079e8e1 +.long 0x8a342283,0x1169989f,0xa83012e6,0x8097799c,0x8a6a9001,0xece966cb,0x072ac7fc,0x93b3afef,0x2db3d5ba,0xe6893a2a,0x89bf4fdc,0x263dc462,0xe0396673,0x8852dfc9,0x3af362b6,0x7ac70895 +.long 0x5c2f342b,0xbb9cce4d,0xb52d7aae,0xbf80907a,0x2161bcd0,0x97f3d3cd,0x0962744d,0xb25b0834,0x6c3a1dda,0xc5b18ea5,0x06c92317,0xfe4ec7eb,0xad1c4afe,0xb787b890,0x0ede801a,0xdccd9a92 +.long 0xdb58da1f,0x9ac6ddda,0xb8cae6ee,0x22bbc12f,0x815c4a43,0xc6f8bced,0xf96480c7,0x8105a92c,0x7a859d51,0x0dc3dbf3,0x3041196b,0xe3ec7ce6,0x0d1067c9,0xd9f64b25,0x3d1f8dd8,0xf2321321 +.long 0x76497ee8,0x8b5c619c,0xc717370e,0x5d2b0ac6,0x4fcf68e1,0x98204cb6,0x62bc6792,0x0bdec211,0xa63b1011,0x6973ccef,0xe0de1ac5,0xf9e3fa97,0x3d0e0c8b,0x5efb693e,0xd2d4fcb4,0x037248e9 +.long 0x1ec34f9e,0x80802dc9,0x33810603,0xd8772d35,0x530cb4f3,0x3f06d66c,0xc475c129,0x7be5ed0d,0x31e82b10,0xcb9e3c19,0xc9ff6b4c,0xc63d2857,0x92a1b45e,0xb92118c6,0x7285bbca,0x0aec4414 +.long 0x1e29a3ef,0xfc189ae7,0x4c93302e,0xcbe906f0,0xceaae10e,0xd0107914,0xb68e19f8,0xb7a23f34,0xefd2119d,0xe9d875c2,0xfcadc9c8,0x03198c6e,0x4da17113,0x65591bf6,0x3d443038,0x3cf0bbf8 +.long 0x2b724759,0xae485bb7,0xb2d4c63a,0x945353e1,0xde7d6f2c,0x82159d07,0x4ec5b109,0x389caef3,0xdb65ef14,0x4a8ebb53,0xdd99de43,0x2dc2cb7e,0x83f2405f,0x816fa3ed,0xc14208a3,0x73429bb9 +.long 0xb01e6e27,0xb618d590,0xe180b2dc,0x047e2ccd,0x04aea4a9,0xd1b299b5,0x9fa403a4,0x412c9e1e,0x79407552,0x88d28a36,0xf332b8e3,0x49c50136,0xe668de19,0x3a1b6fcc,0x75122b97,0x178851bc +.long 0xfb85fa4c,0xb1e13752,0x383c8ce9,0xd61257ce,0xd2f74dae,0xd43da670,0xbf846bbb,0xa35aa23f,0x4421fc83,0x5e74235d,0xc363473b,0xf6df8ee0,0x3c4aa158,0x34d7f52a,0x9bc6d22e,0x50d05aab +.long 0xa64785f4,0x8c56e735,0x5f29cd07,0xbc56637b,0x3ee35067,0x53b2bb80,0xdc919270,0x50235a0f,0xf2c4aa65,0x191ab6d8,0x8396023b,0xc3475831,0xf0f805ba,0x80400ba5,0x5ec0f80f,0x8881065b +.long 0xcc1b5e83,0xc370e522,0x860b8bfb,0xde2d4ad1,0x67b256df,0xad364df0,0xe0138997,0x8f12502e,0x7783920a,0x503fa0dc,0xc0bc866a,0xe80014ad,0xd3064ba6,0x3f89b744,0xcba5dba5,0x03511dcd +.long 0x95a7b1a2,0x197dd46d,0x3c6341fb,0x9c4e7ad6,0x484c2ece,0x426eca29,0xde7f4f8a,0x9211e489,0xc78ef1f4,0x14997f6e,0x06574586,0x2b2c0910,0x1c3eede8,0x17286a6e,0x0f60e018,0x25f92e47 +.long 0x31890a36,0x805c5646,0x57feea5b,0x703ef600,0xaf3c3030,0x389f747c,0x54dd3739,0xe0e5daeb,0xc9c9f155,0xfe24a4c3,0xb5393962,0x7e4bf176,0xaf20bf29,0x37183de2,0xf95a8c3b,0x4a1bd7b5 +.long 0x46191d3d,0xa83b9699,0x7b87f257,0x281fc8dd,0x54107588,0xb18e2c13,0x9b2bafe8,0x6372def7,0x0d8972ca,0xdaf4bb48,0x56167a3f,0x3f2dd4b7,0x84310cf4,0x1eace32d,0xe42700aa,0xe3bcefaf +.long 0xd785e73d,0x5fe5691e,0x2ea60467,0xa5db5ab6,0xdfc6514a,0x02e23d41,0xe03c3665,0x35e8048e,0x1adaa0f8,0x3f8b118f,0x84ce1a5a,0x28ec3b45,0x2c6646b8,0xe8cacc6e,0xdbd0e40f,0x1343d185 +.long 0xcaaa358c,0xe5d7f844,0x9924182a,0x1a1db7e4,0x9c875d9a,0xd64cd42d,0x042eeec8,0xb37b515f,0x7b165fbe,0x4d4dd409,0xe206eff3,0xfc322ed9,0x59b7e17e,0x7dee4102,0x8236ca00,0x55a481c0 +.long 0xc23fc975,0x8c885312,0x05d6297b,0x15715806,0xf78edd39,0xa078868e,0x03c45e52,0x956b31e0,0xff7b33a6,0x470275d5,0x0c7e673f,0xc8d5dc3a,0x7e2f2598,0x419227b4,0x4c14a975,0x8b37b634 +.long 0x8b11888c,0xd0667ed6,0x803e25dc,0x5e0e8c3e,0xb987a24a,0x34e5d0dc,0xae920323,0x9f40ac3b,0x34e0f63a,0x5463de95,0x6b6328f9,0xa128bf92,0xda64f1b7,0x491ccd7c,0xc47bde35,0x7ef1ec27 +.long 0xa36a2737,0xa857240f,0x63621bc1,0x35dc1366,0xd4fb6897,0x7a3a6453,0xc929319d,0x80f1a439,0xf8cb0ba0,0xfc18274b,0x8078c5eb,0xb0b53766,0x1e01d0ef,0xfb0d4924,0x372ab09c,0x50d7c67d +.long 0x3aeac968,0xb4e370af,0xc4b63266,0xe4f7fee9,0xe3ac5664,0xb4acd4c2,0xceb38cbf,0xf8910bd2,0xc9c0726e,0x1c3ae50c,0xd97b40bf,0x15309569,0xfd5a5a1b,0x70884b7f,0xef8314cd,0x3890896a +.long 0xa5618c93,0x58e1515c,0x77d942d1,0xe665432b,0xb6f767a8,0xb32181bf,0x3a604110,0x753794e8,0xe8c0dbcc,0x09afeb7c,0x598673a3,0x31e02613,0x7d46db00,0x5d98e557,0x9d985b28,0xfc21fb8c +.long 0xb0843e0b,0xc9040116,0x69b04531,0x53b1b3a8,0x85d7d830,0xdd1649f0,0xcb7427e8,0xbb3bcc87,0xc93dce83,0x77261100,0xa1922a2a,0x7e79da61,0xf3149ce8,0x587a2b02,0xde92ec83,0x147e1384 +.long 0xaf077f30,0x484c83d3,0x0658b53a,0xea78f844,0x027aec53,0x912076c2,0x93c8177d,0xf34714e3,0xc2376c84,0x37ef5d15,0x3d1aa783,0x8315b659,0xef852a90,0x3a75c484,0x16086bd4,0x0ba0c58a +.long 0x529a6d48,0x29688d7a,0xc2f19203,0x9c7f250d,0x682e2df9,0x123042fb,0xad8121bc,0x2b7587e7,0xe0182a65,0x30fc0233,0xe3e1128a,0xb82ecf87,0x93fb098f,0x71682861,0x85e9e6a7,0x043e21ae +.long 0x66c834ea,0xab5b49d6,0x47414287,0x3be43e18,0x219a2a47,0xf40fb859,0xcc58df3c,0x0e6559e9,0x0c6615b4,0xfe1dfe8e,0x56459d70,0x14abc8fd,0x05de0386,0x7be0fa8e,0xe9035c7c,0x8e63ef68 +.long 0x53b31e91,0x116401b4,0x4436b4d8,0x0cba7ad4,0x107afd66,0x9151f9a0,0x1f0ee4c4,0xafaca8d0,0x9ee9761c,0x75fe5c1d,0xf0c0588f,0x3497a16b,0x0304804c,0x3ee2bebd,0xc2c990b9,0xa8fb9a60 +.long 0x39251114,0xd14d32fe,0xcac73366,0x36bf25bc,0xdba7495c,0xc9562c66,0x46ad348b,0x324d301b,0xd670407e,0x9f46620c,0xe3733a01,0x0ea8d4f1,0xb0c324e0,0xd396d532,0x03c317cd,0x5b211a0e +.long 0x5ffe7b37,0x090d7d20,0x1747d2da,0x3b7f3efb,0xb54fc519,0xa2cb525f,0xf66a971e,0x6e220932,0xb486d440,0xddc160df,0x3fe13465,0x7fcfec46,0x76e4c151,0x83da7e4e,0xd8d302b5,0xd6fa48a1 +.long 0x5872cd88,0xc6304f26,0x278b90a1,0x806c1d3c,0xcaf0bc1c,0x3553e725,0xbb9d8d5c,0xff59e603,0x7a0b85dd,0xa4550f32,0x93ecc217,0xdec5720a,0x69d62213,0x0b88b741,0x5b365955,0x7212f245 +.long 0xb5cae787,0x20764111,0x1dfd3124,0x13cb7f58,0x1175aefb,0x2dca77da,0xffaae775,0xeb75466b,0xdb6cff32,0x74d76f3b,0x61fcda9a,0x7440f37a,0xb525028b,0x1bb3ac92,0xa1975f29,0x20fbf8f7 +.long 0xdf83097f,0x982692e1,0x554b0800,0x28738f6c,0xa2ce2f2f,0xdc703717,0x40814194,0x7913b93c,0x1fe89636,0x04924593,0xf78834a6,0x7b98443f,0x5114a5a1,0x11c6ab01,0xffba5f4c,0x60deb383 +.long 0x01a982e6,0x4caa54c6,0x3491cd26,0x1dd35e11,0x7cbd6b05,0x973c315f,0x52494724,0xcab00775,0x6565e15a,0x04659b1f,0x8c8fb026,0xbf30f529,0xa8a0de37,0xfc21641b,0xfa5e5114,0xe9c7a366 +.long 0x52f03ad8,0xdb849ca5,0x024e35c0,0xc7e8dbe9,0xcfc3c789,0xa1a2bbac,0x9c26f262,0xbf733e7d,0xb8444823,0x882ffbf5,0x6bf8483b,0xb7224e88,0x65bef640,0x53023b8b,0xd4d5f8cd,0xaabfec91 +.long 0x079ea1bd,0xa40e1510,0xd05d5d26,0x1ad9addc,0x13e68d4f,0xdb3f2eab,0x640f803f,0x1cff1ae2,0xd4cee117,0xe0e7b749,0x4036d909,0x8e9f275b,0x8f4d4c38,0xce34e31d,0xd75130fc,0x22b37f69 +.long 0xb4014604,0x83e0f1fd,0x89415078,0xa8ce9919,0x41792efe,0x82375b75,0x97d4515b,0x4f59bf5c,0x923a277d,0xac4f324f,0x650f3406,0xd9bc9b7d,0x8a39bc51,0xc6fa87d1,0x5ccc108f,0x82588530 +.long 0x82e4c634,0x5ced3c9f,0x3a4464f8,0x8efb8314,0x7a1dca25,0xe706381b,0x5a2a412b,0x6cd15a3c,0xbfcd8fb5,0x9347a8fd,0x6e54cd22,0x31db2eef,0xf8d8932f,0xc4aeb11e,0x344411af,0x11e7c1ed +.long 0xdc9a151e,0x2653050c,0x3bb0a859,0x9edbfc08,0xfd5691e7,0x926c81c7,0x6f39019a,0x9c1b2342,0x7f8474b9,0x64a81c8b,0x01761819,0x90657c07,0x55e0375a,0x390b3331,0xb6ebc47d,0xc676c626 +.long 0xb7d6dee8,0x51623247,0x79659313,0x0948d927,0xe9ab35ed,0x99700161,0x8ddde408,0x06cc32b4,0x061ef338,0x6f2fd664,0xc202e9ed,0x1606fa02,0x929ba99b,0x55388bc1,0x1e81df69,0xc4428c5e +.long 0xf91b0b2a,0xce2028ae,0xf03dfd3f,0xce870a23,0x0affe8ed,0x66ec2c87,0x284d0c00,0xb205fb46,0x44cefa48,0xbf5dffe7,0xa19876d7,0xb6fc37a8,0x08b72863,0xbecfa84c,0x2576374f,0xd7205ff5 +.long 0x8887de41,0x80330d32,0x869ea534,0x5de0df0c,0x3c56ea17,0x13f42753,0x452b1a78,0xeb1f6069,0xe30ea15c,0x50474396,0xc1494125,0x575816a1,0xfe6bb38f,0xbe1ce55b,0x96ae30f7,0xb901a948 +.long 0xd8fc3548,0xe5af0f08,0xd73bfd08,0x5010b5d0,0x53fe655a,0x993d2880,0x1c1309fd,0x99f2630b,0xb4e3b76f,0xd8677baf,0xb840784b,0x14e51ddc,0xbf0092ce,0x326c750c,0xf528320f,0xc83d306b +.long 0x77d4715c,0xc4456715,0x6b703235,0xd30019f9,0xd669e986,0x207ccb2e,0xf6dbfc28,0x57c824af,0xd8f92a23,0xf0eb532f,0x9bb98fd2,0x4a557fd4,0xc1e6199a,0xa57acea7,0x8b94b1ed,0x0c663820 +.long 0xf83a9266,0x9b42be8f,0x0101bd45,0xc7741c97,0x07bd9ceb,0x95770c11,0x8b2e0744,0x1f50250a,0x1477b654,0xf762eec8,0x15efe59a,0xc65b900e,0x9546a897,0x88c96148,0xc30b4d7c,0x7e8025b3 +.long 0x12045cf9,0xae4065ef,0x9ccce8bd,0x6fcb2caf,0xf2cf6525,0x1fa0ba4e,0xcb72c312,0xf683125d,0xe312410e,0xa01da4ea,0x6cd8e830,0x67e28677,0x98fb3f07,0xabd95752,0xeef649a5,0x05f11e11 +.long 0x9d3472c2,0xba47faef,0xc77d1345,0x3adff697,0xdd15afee,0x4761fa04,0xb9e69462,0x64f1f61a,0x9bfb9093,0xfa691fab,0xa1133dfe,0x3df8ae8f,0x58cc710d,0xcd5f8967,0x16c7fe79,0xfbb88d50 +.long 0xe88c50d1,0x8e011b4c,0xa8771c4f,0x7532e807,0xe2278ee4,0x64c78a48,0x3845072a,0x0b283e83,0x49e69274,0x98a6f291,0x1868b21c,0xb96e9668,0xb1a8908e,0x38f0adc2,0x1feb829d,0x90afcff7 +.long 0x210b0856,0x9915a383,0xdef04889,0xa5a80602,0x7c64d509,0x800e9af9,0xb8996f6f,0x81382d0b,0x81927e27,0x490eba53,0x4af50182,0x46c63b32,0xd3ad62ce,0x784c5fd9,0xf8ae8736,0xe4fa1870 +.long 0xd7466b25,0x4ec9d0bc,0xdb235c65,0x84ddbe1a,0x163c1688,0x5e2645ee,0x00eba747,0x570bd00e,0x128bfa0f,0xfa51b629,0x6c1d3b68,0x92fce1bd,0xb66778b1,0x3e7361dc,0x5561d2bb,0x9c7d249d +.long 0x0bbc6229,0xa40b28bf,0xdfd91497,0x1c83c05e,0xf083df05,0x5f9f5154,0xeee66c9d,0xbac38b3c,0xec0dfcfd,0xf71db7e3,0x8b0a8416,0xf2ecda8e,0x7812aa66,0x52fddd86,0x4e6f4272,0x2896ef10 +.long 0x0fe9a745,0xff27186a,0x49ca70db,0x08249fcd,0x441cac49,0x7425a2e6,0xece5ff57,0xf4a0885a,0x7d7ead58,0x6e2cb731,0x1898d104,0xf96cf7d6,0x4f2c9a89,0xafe67c9d,0x1c7bf5bc,0x89895a50 +.long 0x573cecfa,0xdc7cb8e5,0xd15f03e6,0x66497eae,0x3f084420,0x6bc0de69,0xacd532b0,0x323b9b36,0x0115a3c1,0xcfed390a,0x2d65ca0e,0x9414c40b,0x2f530c78,0x641406bd,0x833438f2,0x29369a44 +.long 0x903fa271,0x996884f5,0xb9da921e,0xe6da0fd2,0x5db01e54,0xa6f2f269,0x6876214e,0x1ee3e9bd,0xe27a9497,0xa26e181c,0x8e215e04,0x36d254e4,0x252cabca,0x42f32a6c,0x80b57614,0x99481487 +.long 0x40d9cae1,0x4c4dfe69,0x11a10f09,0x05869580,0x3491b64b,0xca287b57,0x3fd4a53b,0x77862d5d,0x50349126,0xbf94856e,0x71c5268f,0x2be30bd1,0xcbb650a6,0x10393f19,0x778cf9fd,0x639531fe +.long 0xb2935359,0x02556a11,0xaf8c126e,0xda38aa96,0x0960167f,0x47dbe6c2,0x501901cd,0x37bbabb6,0x2c947778,0xb6e979e0,0x7a1a1dc6,0xd69a5175,0x9d9faf0c,0xc3ed5095,0x1d5fa5f0,0x4dd9c096 +.long 0x64f16ea8,0xa0c4304d,0x7e718623,0x8b1cac16,0x7c67f03e,0x0b576546,0xcbd88c01,0x559cf5ad,0x0e2af19a,0x074877bb,0xa1228c92,0x1f717ec1,0x326e8920,0x70bcb800,0x4f312804,0xec6e2c5c +.long 0x3fca4752,0x426aea7d,0x2211f62a,0xf12c0949,0x7be7b6b5,0x24beecd8,0x36d7a27d,0xb77eaf4c,0xfda78fd3,0x154c2781,0x264eeabe,0x848a83b0,0x4ffe2bc4,0x81287ef0,0xb6b6fc2a,0x7b6d88c6 +.long 0xce417d99,0x805fb947,0x8b916cc4,0x4b93dcc3,0x21273323,0x72e65bb3,0x6ea9886e,0xbcc1badd,0x4bc5ee85,0x0e223011,0xc18ee1e4,0xa561be74,0xa6bcf1f1,0x762fd2d4,0x95231489,0x50e6a5a4 +.long 0xa00b500b,0xca96001f,0x5d7dcdf5,0x5c098cfc,0x8c446a85,0xa64e2d2e,0x971f3c62,0xbae9bcf1,0x8435a2c5,0x4ec22683,0x4bad4643,0x8ceaed6c,0xccccf4e3,0xe9f8fb47,0x1ce3b21e,0xbd4f3fa4 +.long 0xa3db3292,0xd79fb110,0xb536c66a,0xe28a37da,0x8e49e6a9,0x279ce87b,0xfdcec8e3,0x70ccfe8d,0x3ba464b2,0x2193e4e0,0xaca9a398,0x0f39d60e,0xf82c12ab,0x7d7932af,0x91e7e0f7,0xd8ff50ed +.long 0xfa28a7e0,0xea961058,0x0bf5ec74,0xc726cf25,0xdb229666,0xe74d55c8,0xa57f5799,0x0bd9abbf,0x4dfc47b3,0x7479ef07,0x0c52f91d,0xd9c65fc3,0x36a8bde2,0x8e0283fe,0x7d4b7280,0xa32a8b5e +.long 0x12e83233,0x6a677c61,0xdcc9bf28,0x0fbb3512,0x0d780f61,0x562e8ea5,0x1dc4e89c,0x0db8b22b,0x89be0144,0x0a6fd1fb,0xca57113b,0x8c77d246,0xff09c91c,0x4639075d,0x5060824c,0x5b47b17f +.long 0x16287b52,0x58aea2b0,0xd0cd8eb0,0xa1343520,0xc5d58573,0x6148b4d0,0x291c68ae,0xdd2b6170,0x1da3b3b7,0xa61b3929,0x08c4ac10,0x5f946d79,0x7217d583,0x4105d4a5,0x25e6de5e,0x5061da3d +.long 0xec1b4991,0x3113940d,0x36f485ae,0xf12195e1,0x731a2ee0,0xa7507fb2,0x6e9e196e,0x95057a8e,0x2e130136,0xa3c2c911,0x33c60d15,0x97dfbb36,0xb300ee2b,0xcaf3c581,0xf4bac8b8,0x77f25d90 +.long 0x6d840cd6,0xdb1c4f98,0xe634288c,0x471d62c0,0xcec8a161,0x8ec2f85e,0xfa6f4ae2,0x41f37cbc,0x4b709985,0x6793a20f,0xefa8985b,0x7a7bd33b,0x938e6446,0x2c6a3fbd,0x2a8d47c1,0x19042619 +.long 0xcc36975f,0x16848667,0x9d5f1dfb,0x02acf168,0x613baa94,0x62d41ad4,0x9f684670,0xb56fbb92,0xe9e40569,0xce610d0d,0x35489fef,0x7b99c65f,0x3df18b97,0x0c88ad1b,0x5d0e9edb,0x81b7d9be +.long 0xc716cc0a,0xd85218c0,0x85691c49,0xf4b5ff90,0xce356ac6,0xa4fd666b,0x4b327a7a,0x17c72895,0xda6be7de,0xf93d5085,0x3301d34e,0xff71530e,0xd8f448e8,0x4cd96442,0x2ed18ffa,0x9283d331 +.long 0x2a849870,0x4d33dd99,0x41576335,0xa716964b,0x179be0e5,0xff5e3a9b,0x83b13632,0x5b9d6b1b,0xa52f313b,0x3b8bd7d4,0x637a4660,0xc9dd95a0,0x0b3e218f,0x30035962,0xc7b28a3c,0xce1481a3 +.long 0x43228d83,0xab41b43a,0x4ad63f99,0x24ae1c30,0x46a51229,0x8e525f1a,0xcd26d2b4,0x14af860f,0x3f714aa1,0xd6baef61,0xeb78795e,0xf51865ad,0xe6a9d694,0xd3e21fce,0x8a37b527,0x82ceb1dd +.size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed +.text + + + +.align 64 +.Lpoly: +.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 + + +.LRR: +.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd + +.LOne: +.long 1,1,1,1,1,1,1,1 +.LTwo: +.long 2,2,2,2,2,2,2,2 +.LThree: +.long 3,3,3,3,3,3,3,3 +.LONE_mont: +.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe + + +.Lord: +.quad 0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000 +.LordK: +.quad 0xccd1c8aaee00bc4f + +.globl ecp_nistz256_mul_by_2 +.type ecp_nistz256_mul_by_2,@function +.align 64 +ecp_nistz256_mul_by_2: +.cfi_startproc + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-16 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-24 +.Lmul_by_2_body: + + movq 0(%rsi),%r8 + xorq %r13,%r13 + movq 8(%rsi),%r9 + addq %r8,%r8 + movq 16(%rsi),%r10 + adcq %r9,%r9 + movq 24(%rsi),%r11 + leaq .Lpoly(%rip),%rsi + movq %r8,%rax + adcq %r10,%r10 + adcq %r11,%r11 + movq %r9,%rdx + adcq $0,%r13 + + subq 0(%rsi),%r8 + movq %r10,%rcx + sbbq 8(%rsi),%r9 + sbbq 16(%rsi),%r10 + movq %r11,%r12 + sbbq 24(%rsi),%r11 + sbbq $0,%r13 + + cmovcq %rax,%r8 + cmovcq %rdx,%r9 + movq %r8,0(%rdi) + cmovcq %rcx,%r10 + movq %r9,8(%rdi) + cmovcq %r12,%r11 + movq %r10,16(%rdi) + movq %r11,24(%rdi) + + movq 0(%rsp),%r13 +.cfi_restore %r13 + movq 8(%rsp),%r12 +.cfi_restore %r12 + leaq 16(%rsp),%rsp +.cfi_adjust_cfa_offset -16 +.Lmul_by_2_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2 + + + +.globl ecp_nistz256_div_by_2 +.type ecp_nistz256_div_by_2,@function +.align 32 +ecp_nistz256_div_by_2: +.cfi_startproc + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-16 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-24 +.Ldiv_by_2_body: + + movq 0(%rsi),%r8 + movq 8(%rsi),%r9 + movq 16(%rsi),%r10 + movq %r8,%rax + movq 24(%rsi),%r11 + leaq .Lpoly(%rip),%rsi + + movq %r9,%rdx + xorq %r13,%r13 + addq 0(%rsi),%r8 + movq %r10,%rcx + adcq 8(%rsi),%r9 + adcq 16(%rsi),%r10 + movq %r11,%r12 + adcq 24(%rsi),%r11 + adcq $0,%r13 + xorq %rsi,%rsi + testq $1,%rax + + cmovzq %rax,%r8 + cmovzq %rdx,%r9 + cmovzq %rcx,%r10 + cmovzq %r12,%r11 + cmovzq %rsi,%r13 + + movq %r9,%rax + shrq $1,%r8 + shlq $63,%rax + movq %r10,%rdx + shrq $1,%r9 + orq %rax,%r8 + shlq $63,%rdx + movq %r11,%rcx + shrq $1,%r10 + orq %rdx,%r9 + shlq $63,%rcx + shrq $1,%r11 + shlq $63,%r13 + orq %rcx,%r10 + orq %r13,%r11 + + movq %r8,0(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + + movq 0(%rsp),%r13 +.cfi_restore %r13 + movq 8(%rsp),%r12 +.cfi_restore %r12 + leaq 16(%rsp),%rsp +.cfi_adjust_cfa_offset -16 +.Ldiv_by_2_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 + + + +.globl ecp_nistz256_mul_by_3 +.type ecp_nistz256_mul_by_3,@function +.align 32 +ecp_nistz256_mul_by_3: +.cfi_startproc + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-16 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-24 +.Lmul_by_3_body: + + movq 0(%rsi),%r8 + xorq %r13,%r13 + movq 8(%rsi),%r9 + addq %r8,%r8 + movq 16(%rsi),%r10 + adcq %r9,%r9 + movq 24(%rsi),%r11 + movq %r8,%rax + adcq %r10,%r10 + adcq %r11,%r11 + movq %r9,%rdx + adcq $0,%r13 + + subq $-1,%r8 + movq %r10,%rcx + sbbq .Lpoly+8(%rip),%r9 + sbbq $0,%r10 + movq %r11,%r12 + sbbq .Lpoly+24(%rip),%r11 + sbbq $0,%r13 + + cmovcq %rax,%r8 + cmovcq %rdx,%r9 + cmovcq %rcx,%r10 + cmovcq %r12,%r11 + + xorq %r13,%r13 + addq 0(%rsi),%r8 + adcq 8(%rsi),%r9 + movq %r8,%rax + adcq 16(%rsi),%r10 + adcq 24(%rsi),%r11 + movq %r9,%rdx + adcq $0,%r13 + + subq $-1,%r8 + movq %r10,%rcx + sbbq .Lpoly+8(%rip),%r9 + sbbq $0,%r10 + movq %r11,%r12 + sbbq .Lpoly+24(%rip),%r11 + sbbq $0,%r13 + + cmovcq %rax,%r8 + cmovcq %rdx,%r9 + movq %r8,0(%rdi) + cmovcq %rcx,%r10 + movq %r9,8(%rdi) + cmovcq %r12,%r11 + movq %r10,16(%rdi) + movq %r11,24(%rdi) + + movq 0(%rsp),%r13 +.cfi_restore %r13 + movq 8(%rsp),%r12 +.cfi_restore %r12 + leaq 16(%rsp),%rsp +.cfi_adjust_cfa_offset -16 +.Lmul_by_3_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 + + + +.globl ecp_nistz256_add +.type ecp_nistz256_add,@function +.align 32 +ecp_nistz256_add: +.cfi_startproc + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-16 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-24 +.Ladd_body: + + movq 0(%rsi),%r8 + xorq %r13,%r13 + movq 8(%rsi),%r9 + movq 16(%rsi),%r10 + movq 24(%rsi),%r11 + leaq .Lpoly(%rip),%rsi + + addq 0(%rdx),%r8 + adcq 8(%rdx),%r9 + movq %r8,%rax + adcq 16(%rdx),%r10 + adcq 24(%rdx),%r11 + movq %r9,%rdx + adcq $0,%r13 + + subq 0(%rsi),%r8 + movq %r10,%rcx + sbbq 8(%rsi),%r9 + sbbq 16(%rsi),%r10 + movq %r11,%r12 + sbbq 24(%rsi),%r11 + sbbq $0,%r13 + + cmovcq %rax,%r8 + cmovcq %rdx,%r9 + movq %r8,0(%rdi) + cmovcq %rcx,%r10 + movq %r9,8(%rdi) + cmovcq %r12,%r11 + movq %r10,16(%rdi) + movq %r11,24(%rdi) + + movq 0(%rsp),%r13 +.cfi_restore %r13 + movq 8(%rsp),%r12 +.cfi_restore %r12 + leaq 16(%rsp),%rsp +.cfi_adjust_cfa_offset -16 +.Ladd_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_add,.-ecp_nistz256_add + + + +.globl ecp_nistz256_sub +.type ecp_nistz256_sub,@function +.align 32 +ecp_nistz256_sub: +.cfi_startproc + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-16 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-24 +.Lsub_body: + + movq 0(%rsi),%r8 + xorq %r13,%r13 + movq 8(%rsi),%r9 + movq 16(%rsi),%r10 + movq 24(%rsi),%r11 + leaq .Lpoly(%rip),%rsi + + subq 0(%rdx),%r8 + sbbq 8(%rdx),%r9 + movq %r8,%rax + sbbq 16(%rdx),%r10 + sbbq 24(%rdx),%r11 + movq %r9,%rdx + sbbq $0,%r13 + + addq 0(%rsi),%r8 + movq %r10,%rcx + adcq 8(%rsi),%r9 + adcq 16(%rsi),%r10 + movq %r11,%r12 + adcq 24(%rsi),%r11 + testq %r13,%r13 + + cmovzq %rax,%r8 + cmovzq %rdx,%r9 + movq %r8,0(%rdi) + cmovzq %rcx,%r10 + movq %r9,8(%rdi) + cmovzq %r12,%r11 + movq %r10,16(%rdi) + movq %r11,24(%rdi) + + movq 0(%rsp),%r13 +.cfi_restore %r13 + movq 8(%rsp),%r12 +.cfi_restore %r12 + leaq 16(%rsp),%rsp +.cfi_adjust_cfa_offset -16 +.Lsub_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_sub,.-ecp_nistz256_sub + + + +.globl ecp_nistz256_neg +.type ecp_nistz256_neg,@function +.align 32 +ecp_nistz256_neg: +.cfi_startproc + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-16 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-24 +.Lneg_body: + + xorq %r8,%r8 + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + xorq %r13,%r13 + + subq 0(%rsi),%r8 + sbbq 8(%rsi),%r9 + sbbq 16(%rsi),%r10 + movq %r8,%rax + sbbq 24(%rsi),%r11 + leaq .Lpoly(%rip),%rsi + movq %r9,%rdx + sbbq $0,%r13 + + addq 0(%rsi),%r8 + movq %r10,%rcx + adcq 8(%rsi),%r9 + adcq 16(%rsi),%r10 + movq %r11,%r12 + adcq 24(%rsi),%r11 + testq %r13,%r13 + + cmovzq %rax,%r8 + cmovzq %rdx,%r9 + movq %r8,0(%rdi) + cmovzq %rcx,%r10 + movq %r9,8(%rdi) + cmovzq %r12,%r11 + movq %r10,16(%rdi) + movq %r11,24(%rdi) + + movq 0(%rsp),%r13 +.cfi_restore %r13 + movq 8(%rsp),%r12 +.cfi_restore %r12 + leaq 16(%rsp),%rsp +.cfi_adjust_cfa_offset -16 +.Lneg_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_neg,.-ecp_nistz256_neg + + + + + + +.globl ecp_nistz256_ord_mul_mont +.type ecp_nistz256_ord_mul_mont,@function +.align 32 +ecp_nistz256_ord_mul_mont: +.cfi_startproc + movl $0x80100,%ecx + andl OPENSSL_ia32cap_P+8(%rip),%ecx + cmpl $0x80100,%ecx + je .Lecp_nistz256_ord_mul_montx + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lord_mul_body: + + movq 0(%rdx),%rax + movq %rdx,%rbx + leaq .Lord(%rip),%r14 + movq .LordK(%rip),%r15 + + + movq %rax,%rcx + mulq 0(%rsi) + movq %rax,%r8 + movq %rcx,%rax + movq %rdx,%r9 + + mulq 8(%rsi) + addq %rax,%r9 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq 16(%rsi) + addq %rax,%r10 + movq %rcx,%rax + adcq $0,%rdx + + movq %r8,%r13 + imulq %r15,%r8 + + movq %rdx,%r11 + mulq 24(%rsi) + addq %rax,%r11 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%r12 + + + mulq 0(%r14) + movq %r8,%rbp + addq %rax,%r13 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%rcx + + subq %r8,%r10 + sbbq $0,%r8 + + mulq 8(%r14) + addq %rcx,%r9 + adcq $0,%rdx + addq %rax,%r9 + movq %rbp,%rax + adcq %rdx,%r10 + movq %rbp,%rdx + adcq $0,%r8 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r11 + movq 8(%rbx),%rax + sbbq %rdx,%rbp + + addq %r8,%r11 + adcq %rbp,%r12 + adcq $0,%r13 + + + movq %rax,%rcx + mulq 0(%rsi) + addq %rax,%r9 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 8(%rsi) + addq %rbp,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 16(%rsi) + addq %rbp,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rcx,%rax + adcq $0,%rdx + + movq %r9,%rcx + imulq %r15,%r9 + + movq %rdx,%rbp + mulq 24(%rsi) + addq %rbp,%r12 + adcq $0,%rdx + xorq %r8,%r8 + addq %rax,%r12 + movq %r9,%rax + adcq %rdx,%r13 + adcq $0,%r8 + + + mulq 0(%r14) + movq %r9,%rbp + addq %rax,%rcx + movq %r9,%rax + adcq %rdx,%rcx + + subq %r9,%r11 + sbbq $0,%r9 + + mulq 8(%r14) + addq %rcx,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %rbp,%rax + adcq %rdx,%r11 + movq %rbp,%rdx + adcq $0,%r9 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r12 + movq 16(%rbx),%rax + sbbq %rdx,%rbp + + addq %r9,%r12 + adcq %rbp,%r13 + adcq $0,%r8 + + + movq %rax,%rcx + mulq 0(%rsi) + addq %rax,%r10 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 8(%rsi) + addq %rbp,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 16(%rsi) + addq %rbp,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rcx,%rax + adcq $0,%rdx + + movq %r10,%rcx + imulq %r15,%r10 + + movq %rdx,%rbp + mulq 24(%rsi) + addq %rbp,%r13 + adcq $0,%rdx + xorq %r9,%r9 + addq %rax,%r13 + movq %r10,%rax + adcq %rdx,%r8 + adcq $0,%r9 + + + mulq 0(%r14) + movq %r10,%rbp + addq %rax,%rcx + movq %r10,%rax + adcq %rdx,%rcx + + subq %r10,%r12 + sbbq $0,%r10 + + mulq 8(%r14) + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rbp,%rax + adcq %rdx,%r12 + movq %rbp,%rdx + adcq $0,%r10 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r13 + movq 24(%rbx),%rax + sbbq %rdx,%rbp + + addq %r10,%r13 + adcq %rbp,%r8 + adcq $0,%r9 + + + movq %rax,%rcx + mulq 0(%rsi) + addq %rax,%r11 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 8(%rsi) + addq %rbp,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rcx,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq 16(%rsi) + addq %rbp,%r13 + adcq $0,%rdx + addq %rax,%r13 + movq %rcx,%rax + adcq $0,%rdx + + movq %r11,%rcx + imulq %r15,%r11 + + movq %rdx,%rbp + mulq 24(%rsi) + addq %rbp,%r8 + adcq $0,%rdx + xorq %r10,%r10 + addq %rax,%r8 + movq %r11,%rax + adcq %rdx,%r9 + adcq $0,%r10 + + + mulq 0(%r14) + movq %r11,%rbp + addq %rax,%rcx + movq %r11,%rax + adcq %rdx,%rcx + + subq %r11,%r13 + sbbq $0,%r11 + + mulq 8(%r14) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rbp,%rax + adcq %rdx,%r13 + movq %rbp,%rdx + adcq $0,%r11 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r8 + sbbq %rdx,%rbp + + addq %r11,%r8 + adcq %rbp,%r9 + adcq $0,%r10 + + + movq %r12,%rsi + subq 0(%r14),%r12 + movq %r13,%r11 + sbbq 8(%r14),%r13 + movq %r8,%rcx + sbbq 16(%r14),%r8 + movq %r9,%rbp + sbbq 24(%r14),%r9 + sbbq $0,%r10 + + cmovcq %rsi,%r12 + cmovcq %r11,%r13 + cmovcq %rcx,%r8 + cmovcq %rbp,%r9 + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lord_mul_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont + + + + + + + +.globl ecp_nistz256_ord_sqr_mont +.type ecp_nistz256_ord_sqr_mont,@function +.align 32 +ecp_nistz256_ord_sqr_mont: +.cfi_startproc + movl $0x80100,%ecx + andl OPENSSL_ia32cap_P+8(%rip),%ecx + cmpl $0x80100,%ecx + je .Lecp_nistz256_ord_sqr_montx + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lord_sqr_body: + + movq 0(%rsi),%r8 + movq 8(%rsi),%rax + movq 16(%rsi),%r14 + movq 24(%rsi),%r15 + leaq .Lord(%rip),%rsi + movq %rdx,%rbx + jmp .Loop_ord_sqr + +.align 32 +.Loop_ord_sqr: + + movq %rax,%rbp + mulq %r8 + movq %rax,%r9 +.byte 102,72,15,110,205 + movq %r14,%rax + movq %rdx,%r10 + + mulq %r8 + addq %rax,%r10 + movq %r15,%rax +.byte 102,73,15,110,214 + adcq $0,%rdx + movq %rdx,%r11 + + mulq %r8 + addq %rax,%r11 + movq %r15,%rax +.byte 102,73,15,110,223 + adcq $0,%rdx + movq %rdx,%r12 + + + mulq %r14 + movq %rax,%r13 + movq %r14,%rax + movq %rdx,%r14 + + + mulq %rbp + addq %rax,%r11 + movq %r15,%rax + adcq $0,%rdx + movq %rdx,%r15 + + mulq %rbp + addq %rax,%r12 + adcq $0,%rdx + + addq %r15,%r12 + adcq %rdx,%r13 + adcq $0,%r14 + + + xorq %r15,%r15 + movq %r8,%rax + addq %r9,%r9 + adcq %r10,%r10 + adcq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + adcq %r14,%r14 + adcq $0,%r15 + + + mulq %rax + movq %rax,%r8 +.byte 102,72,15,126,200 + movq %rdx,%rbp + + mulq %rax + addq %rbp,%r9 + adcq %rax,%r10 +.byte 102,72,15,126,208 + adcq $0,%rdx + movq %rdx,%rbp + + mulq %rax + addq %rbp,%r11 + adcq %rax,%r12 +.byte 102,72,15,126,216 + adcq $0,%rdx + movq %rdx,%rbp + + movq %r8,%rcx + imulq 32(%rsi),%r8 + + mulq %rax + addq %rbp,%r13 + adcq %rax,%r14 + movq 0(%rsi),%rax + adcq %rdx,%r15 + + + mulq %r8 + movq %r8,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r8,%r10 + sbbq $0,%rbp + + mulq %r8 + addq %rcx,%r9 + adcq $0,%rdx + addq %rax,%r9 + movq %r8,%rax + adcq %rdx,%r10 + movq %r8,%rdx + adcq $0,%rbp + + movq %r9,%rcx + imulq 32(%rsi),%r9 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r11 + movq 0(%rsi),%rax + sbbq %rdx,%r8 + + addq %rbp,%r11 + adcq $0,%r8 + + + mulq %r9 + movq %r9,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r9,%r11 + sbbq $0,%rbp + + mulq %r9 + addq %rcx,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %r9,%rax + adcq %rdx,%r11 + movq %r9,%rdx + adcq $0,%rbp + + movq %r10,%rcx + imulq 32(%rsi),%r10 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r8 + movq 0(%rsi),%rax + sbbq %rdx,%r9 + + addq %rbp,%r8 + adcq $0,%r9 + + + mulq %r10 + movq %r10,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r10,%r8 + sbbq $0,%rbp + + mulq %r10 + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %r10,%rax + adcq %rdx,%r8 + movq %r10,%rdx + adcq $0,%rbp + + movq %r11,%rcx + imulq 32(%rsi),%r11 + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r9 + movq 0(%rsi),%rax + sbbq %rdx,%r10 + + addq %rbp,%r9 + adcq $0,%r10 + + + mulq %r11 + movq %r11,%rbp + addq %rax,%rcx + movq 8(%rsi),%rax + adcq %rdx,%rcx + + subq %r11,%r9 + sbbq $0,%rbp + + mulq %r11 + addq %rcx,%r8 + adcq $0,%rdx + addq %rax,%r8 + movq %r11,%rax + adcq %rdx,%r9 + movq %r11,%rdx + adcq $0,%rbp + + shlq $32,%rax + shrq $32,%rdx + subq %rax,%r10 + sbbq %rdx,%r11 + + addq %rbp,%r10 + adcq $0,%r11 + + + xorq %rdx,%rdx + addq %r12,%r8 + adcq %r13,%r9 + movq %r8,%r12 + adcq %r14,%r10 + adcq %r15,%r11 + movq %r9,%rax + adcq $0,%rdx + + + subq 0(%rsi),%r8 + movq %r10,%r14 + sbbq 8(%rsi),%r9 + sbbq 16(%rsi),%r10 + movq %r11,%r15 + sbbq 24(%rsi),%r11 + sbbq $0,%rdx + + cmovcq %r12,%r8 + cmovncq %r9,%rax + cmovncq %r10,%r14 + cmovncq %r11,%r15 + + decq %rbx + jnz .Loop_ord_sqr + + movq %r8,0(%rdi) + movq %rax,8(%rdi) + pxor %xmm1,%xmm1 + movq %r14,16(%rdi) + pxor %xmm2,%xmm2 + movq %r15,24(%rdi) + pxor %xmm3,%xmm3 + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lord_sqr_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont + +.type ecp_nistz256_ord_mul_montx,@function +.align 32 +ecp_nistz256_ord_mul_montx: +.cfi_startproc +.Lecp_nistz256_ord_mul_montx: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lord_mulx_body: + + movq %rdx,%rbx + movq 0(%rdx),%rdx + movq 0(%rsi),%r9 + movq 8(%rsi),%r10 + movq 16(%rsi),%r11 + movq 24(%rsi),%r12 + leaq -128(%rsi),%rsi + leaq .Lord-128(%rip),%r14 + movq .LordK(%rip),%r15 + + + mulxq %r9,%r8,%r9 + mulxq %r10,%rcx,%r10 + mulxq %r11,%rbp,%r11 + addq %rcx,%r9 + mulxq %r12,%rcx,%r12 + movq %r8,%rdx + mulxq %r15,%rdx,%rax + adcq %rbp,%r10 + adcq %rcx,%r11 + adcq $0,%r12 + + + xorq %r13,%r13 + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r8 + adoxq %rbp,%r9 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 24+128(%r14),%rcx,%rbp + movq 8(%rbx),%rdx + adcxq %rcx,%r11 + adoxq %rbp,%r12 + adcxq %r8,%r12 + adoxq %r8,%r13 + adcq $0,%r13 + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r9,%rdx + mulxq %r15,%rdx,%rax + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + adcxq %r8,%r13 + adoxq %r8,%r8 + adcq $0,%r8 + + + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 24+128(%r14),%rcx,%rbp + movq 16(%rbx),%rdx + adcxq %rcx,%r12 + adoxq %rbp,%r13 + adcxq %r9,%r13 + adoxq %r9,%r8 + adcq $0,%r8 + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r10,%rdx + mulxq %r15,%rdx,%rax + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + adcxq %r9,%r8 + adoxq %r9,%r9 + adcq $0,%r9 + + + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 24+128(%r14),%rcx,%rbp + movq 24(%rbx),%rdx + adcxq %rcx,%r13 + adoxq %rbp,%r8 + adcxq %r10,%r8 + adoxq %r10,%r9 + adcq $0,%r9 + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r11,%rdx + mulxq %r15,%rdx,%rax + adcxq %rcx,%r8 + adoxq %rbp,%r9 + + adcxq %r10,%r9 + adoxq %r10,%r10 + adcq $0,%r10 + + + mulxq 0+128(%r14),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 8+128(%r14),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 16+128(%r14),%rcx,%rbp + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + mulxq 24+128(%r14),%rcx,%rbp + leaq 128(%r14),%r14 + movq %r12,%rbx + adcxq %rcx,%r8 + adoxq %rbp,%r9 + movq %r13,%rdx + adcxq %r11,%r9 + adoxq %r11,%r10 + adcq $0,%r10 + + + + movq %r8,%rcx + subq 0(%r14),%r12 + sbbq 8(%r14),%r13 + sbbq 16(%r14),%r8 + movq %r9,%rbp + sbbq 24(%r14),%r9 + sbbq $0,%r10 + + cmovcq %rbx,%r12 + cmovcq %rdx,%r13 + cmovcq %rcx,%r8 + cmovcq %rbp,%r9 + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lord_mulx_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_ord_mul_montx,.-ecp_nistz256_ord_mul_montx + +.type ecp_nistz256_ord_sqr_montx,@function +.align 32 +ecp_nistz256_ord_sqr_montx: +.cfi_startproc +.Lecp_nistz256_ord_sqr_montx: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lord_sqrx_body: + + movq %rdx,%rbx + movq 0(%rsi),%rdx + movq 8(%rsi),%r14 + movq 16(%rsi),%r15 + movq 24(%rsi),%r8 + leaq .Lord(%rip),%rsi + jmp .Loop_ord_sqrx + +.align 32 +.Loop_ord_sqrx: + mulxq %r14,%r9,%r10 + mulxq %r15,%rcx,%r11 + movq %rdx,%rax +.byte 102,73,15,110,206 + mulxq %r8,%rbp,%r12 + movq %r14,%rdx + addq %rcx,%r10 +.byte 102,73,15,110,215 + adcq %rbp,%r11 + adcq $0,%r12 + xorq %r13,%r13 + + mulxq %r15,%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq %r8,%rcx,%rbp + movq %r15,%rdx + adcxq %rcx,%r12 + adoxq %rbp,%r13 + adcq $0,%r13 + + mulxq %r8,%rcx,%r14 + movq %rax,%rdx +.byte 102,73,15,110,216 + xorq %r15,%r15 + adcxq %r9,%r9 + adoxq %rcx,%r13 + adcxq %r10,%r10 + adoxq %r15,%r14 + + + mulxq %rdx,%r8,%rbp +.byte 102,72,15,126,202 + adcxq %r11,%r11 + adoxq %rbp,%r9 + adcxq %r12,%r12 + mulxq %rdx,%rcx,%rax +.byte 102,72,15,126,210 + adcxq %r13,%r13 + adoxq %rcx,%r10 + adcxq %r14,%r14 + mulxq %rdx,%rcx,%rbp +.byte 0x67 +.byte 102,72,15,126,218 + adoxq %rax,%r11 + adcxq %r15,%r15 + adoxq %rcx,%r12 + adoxq %rbp,%r13 + mulxq %rdx,%rcx,%rax + adoxq %rcx,%r14 + adoxq %rax,%r15 + + + movq %r8,%rdx + mulxq 32(%rsi),%rdx,%rcx + + xorq %rax,%rax + mulxq 0(%rsi),%rcx,%rbp + adcxq %rcx,%r8 + adoxq %rbp,%r9 + mulxq 8(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + mulxq 16(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + mulxq 24(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r8 + adcxq %rax,%r8 + + + movq %r9,%rdx + mulxq 32(%rsi),%rdx,%rcx + + mulxq 0(%rsi),%rcx,%rbp + adoxq %rcx,%r9 + adcxq %rbp,%r10 + mulxq 8(%rsi),%rcx,%rbp + adoxq %rcx,%r10 + adcxq %rbp,%r11 + mulxq 16(%rsi),%rcx,%rbp + adoxq %rcx,%r11 + adcxq %rbp,%r8 + mulxq 24(%rsi),%rcx,%rbp + adoxq %rcx,%r8 + adcxq %rbp,%r9 + adoxq %rax,%r9 + + + movq %r10,%rdx + mulxq 32(%rsi),%rdx,%rcx + + mulxq 0(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + mulxq 8(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r8 + mulxq 16(%rsi),%rcx,%rbp + adcxq %rcx,%r8 + adoxq %rbp,%r9 + mulxq 24(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + adcxq %rax,%r10 + + + movq %r11,%rdx + mulxq 32(%rsi),%rdx,%rcx + + mulxq 0(%rsi),%rcx,%rbp + adoxq %rcx,%r11 + adcxq %rbp,%r8 + mulxq 8(%rsi),%rcx,%rbp + adoxq %rcx,%r8 + adcxq %rbp,%r9 + mulxq 16(%rsi),%rcx,%rbp + adoxq %rcx,%r9 + adcxq %rbp,%r10 + mulxq 24(%rsi),%rcx,%rbp + adoxq %rcx,%r10 + adcxq %rbp,%r11 + adoxq %rax,%r11 + + + addq %r8,%r12 + adcq %r13,%r9 + movq %r12,%rdx + adcq %r14,%r10 + adcq %r15,%r11 + movq %r9,%r14 + adcq $0,%rax + + + subq 0(%rsi),%r12 + movq %r10,%r15 + sbbq 8(%rsi),%r9 + sbbq 16(%rsi),%r10 + movq %r11,%r8 + sbbq 24(%rsi),%r11 + sbbq $0,%rax + + cmovncq %r12,%rdx + cmovncq %r9,%r14 + cmovncq %r10,%r15 + cmovncq %r11,%r8 + + decq %rbx + jnz .Loop_ord_sqrx + + movq %rdx,0(%rdi) + movq %r14,8(%rdi) + pxor %xmm1,%xmm1 + movq %r15,16(%rdi) + pxor %xmm2,%xmm2 + movq %r8,24(%rdi) + pxor %xmm3,%xmm3 + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lord_sqrx_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_ord_sqr_montx,.-ecp_nistz256_ord_sqr_montx + + + + +.globl ecp_nistz256_to_mont +.type ecp_nistz256_to_mont,@function +.align 32 +ecp_nistz256_to_mont: +.cfi_startproc + movl $0x80100,%ecx + andl OPENSSL_ia32cap_P+8(%rip),%ecx + leaq .LRR(%rip),%rdx + jmp .Lmul_mont +.cfi_endproc +.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont + + + + + + + +.globl ecp_nistz256_mul_mont +.type ecp_nistz256_mul_mont,@function +.align 32 +ecp_nistz256_mul_mont: +.cfi_startproc + movl $0x80100,%ecx + andl OPENSSL_ia32cap_P+8(%rip),%ecx +.Lmul_mont: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lmul_body: + cmpl $0x80100,%ecx + je .Lmul_montx + movq %rdx,%rbx + movq 0(%rdx),%rax + movq 0(%rsi),%r9 + movq 8(%rsi),%r10 + movq 16(%rsi),%r11 + movq 24(%rsi),%r12 + + call __ecp_nistz256_mul_montq + jmp .Lmul_mont_done + +.align 32 +.Lmul_montx: + movq %rdx,%rbx + movq 0(%rdx),%rdx + movq 0(%rsi),%r9 + movq 8(%rsi),%r10 + movq 16(%rsi),%r11 + movq 24(%rsi),%r12 + leaq -128(%rsi),%rsi + + call __ecp_nistz256_mul_montx +.Lmul_mont_done: + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lmul_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont + +.type __ecp_nistz256_mul_montq,@function +.align 32 +__ecp_nistz256_mul_montq: +.cfi_startproc + + + movq %rax,%rbp + mulq %r9 + movq .Lpoly+8(%rip),%r14 + movq %rax,%r8 + movq %rbp,%rax + movq %rdx,%r9 + + mulq %r10 + movq .Lpoly+24(%rip),%r15 + addq %rax,%r9 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%r10 + + mulq %r11 + addq %rax,%r10 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %r12 + addq %rax,%r11 + movq %r8,%rax + adcq $0,%rdx + xorq %r13,%r13 + movq %rdx,%r12 + + + + + + + + + + + movq %r8,%rbp + shlq $32,%r8 + mulq %r15 + shrq $32,%rbp + addq %r8,%r9 + adcq %rbp,%r10 + adcq %rax,%r11 + movq 8(%rbx),%rax + adcq %rdx,%r12 + adcq $0,%r13 + xorq %r8,%r8 + + + + movq %rax,%rbp + mulq 0(%rsi) + addq %rax,%r9 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 8(%rsi) + addq %rcx,%r10 + adcq $0,%rdx + addq %rax,%r10 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 16(%rsi) + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 24(%rsi) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %r9,%rax + adcq %rdx,%r13 + adcq $0,%r8 + + + + movq %r9,%rbp + shlq $32,%r9 + mulq %r15 + shrq $32,%rbp + addq %r9,%r10 + adcq %rbp,%r11 + adcq %rax,%r12 + movq 16(%rbx),%rax + adcq %rdx,%r13 + adcq $0,%r8 + xorq %r9,%r9 + + + + movq %rax,%rbp + mulq 0(%rsi) + addq %rax,%r10 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 8(%rsi) + addq %rcx,%r11 + adcq $0,%rdx + addq %rax,%r11 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 16(%rsi) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 24(%rsi) + addq %rcx,%r13 + adcq $0,%rdx + addq %rax,%r13 + movq %r10,%rax + adcq %rdx,%r8 + adcq $0,%r9 + + + + movq %r10,%rbp + shlq $32,%r10 + mulq %r15 + shrq $32,%rbp + addq %r10,%r11 + adcq %rbp,%r12 + adcq %rax,%r13 + movq 24(%rbx),%rax + adcq %rdx,%r8 + adcq $0,%r9 + xorq %r10,%r10 + + + + movq %rax,%rbp + mulq 0(%rsi) + addq %rax,%r11 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 8(%rsi) + addq %rcx,%r12 + adcq $0,%rdx + addq %rax,%r12 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 16(%rsi) + addq %rcx,%r13 + adcq $0,%rdx + addq %rax,%r13 + movq %rbp,%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq 24(%rsi) + addq %rcx,%r8 + adcq $0,%rdx + addq %rax,%r8 + movq %r11,%rax + adcq %rdx,%r9 + adcq $0,%r10 + + + + movq %r11,%rbp + shlq $32,%r11 + mulq %r15 + shrq $32,%rbp + addq %r11,%r12 + adcq %rbp,%r13 + movq %r12,%rcx + adcq %rax,%r8 + adcq %rdx,%r9 + movq %r13,%rbp + adcq $0,%r10 + + + + subq $-1,%r12 + movq %r8,%rbx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%rdx + sbbq %r15,%r9 + sbbq $0,%r10 + + cmovcq %rcx,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rbx,%r8 + movq %r13,8(%rdi) + cmovcq %rdx,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq + + + + + + + + +.globl ecp_nistz256_sqr_mont +.type ecp_nistz256_sqr_mont,@function +.align 32 +ecp_nistz256_sqr_mont: +.cfi_startproc + movl $0x80100,%ecx + andl OPENSSL_ia32cap_P+8(%rip),%ecx + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lsqr_body: + cmpl $0x80100,%ecx + je .Lsqr_montx + movq 0(%rsi),%rax + movq 8(%rsi),%r14 + movq 16(%rsi),%r15 + movq 24(%rsi),%r8 + + call __ecp_nistz256_sqr_montq + jmp .Lsqr_mont_done + +.align 32 +.Lsqr_montx: + movq 0(%rsi),%rdx + movq 8(%rsi),%r14 + movq 16(%rsi),%r15 + movq 24(%rsi),%r8 + leaq -128(%rsi),%rsi + + call __ecp_nistz256_sqr_montx +.Lsqr_mont_done: + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbx +.cfi_restore %rbx + movq 40(%rsp),%rbp +.cfi_restore %rbp + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lsqr_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont + +.type __ecp_nistz256_sqr_montq,@function +.align 32 +__ecp_nistz256_sqr_montq: +.cfi_startproc + movq %rax,%r13 + mulq %r14 + movq %rax,%r9 + movq %r15,%rax + movq %rdx,%r10 + + mulq %r13 + addq %rax,%r10 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%r11 + + mulq %r13 + addq %rax,%r11 + movq %r15,%rax + adcq $0,%rdx + movq %rdx,%r12 + + + mulq %r14 + addq %rax,%r11 + movq %r8,%rax + adcq $0,%rdx + movq %rdx,%rbp + + mulq %r14 + addq %rax,%r12 + movq %r8,%rax + adcq $0,%rdx + addq %rbp,%r12 + movq %rdx,%r13 + adcq $0,%r13 + + + mulq %r15 + xorq %r15,%r15 + addq %rax,%r13 + movq 0(%rsi),%rax + movq %rdx,%r14 + adcq $0,%r14 + + addq %r9,%r9 + adcq %r10,%r10 + adcq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + adcq %r14,%r14 + adcq $0,%r15 + + mulq %rax + movq %rax,%r8 + movq 8(%rsi),%rax + movq %rdx,%rcx + + mulq %rax + addq %rcx,%r9 + adcq %rax,%r10 + movq 16(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq %rax + addq %rcx,%r11 + adcq %rax,%r12 + movq 24(%rsi),%rax + adcq $0,%rdx + movq %rdx,%rcx + + mulq %rax + addq %rcx,%r13 + adcq %rax,%r14 + movq %r8,%rax + adcq %rdx,%r15 + + movq .Lpoly+8(%rip),%rsi + movq .Lpoly+24(%rip),%rbp + + + + + movq %r8,%rcx + shlq $32,%r8 + mulq %rbp + shrq $32,%rcx + addq %r8,%r9 + adcq %rcx,%r10 + adcq %rax,%r11 + movq %r9,%rax + adcq $0,%rdx + + + + movq %r9,%rcx + shlq $32,%r9 + movq %rdx,%r8 + mulq %rbp + shrq $32,%rcx + addq %r9,%r10 + adcq %rcx,%r11 + adcq %rax,%r8 + movq %r10,%rax + adcq $0,%rdx + + + + movq %r10,%rcx + shlq $32,%r10 + movq %rdx,%r9 + mulq %rbp + shrq $32,%rcx + addq %r10,%r11 + adcq %rcx,%r8 + adcq %rax,%r9 + movq %r11,%rax + adcq $0,%rdx + + + + movq %r11,%rcx + shlq $32,%r11 + movq %rdx,%r10 + mulq %rbp + shrq $32,%rcx + addq %r11,%r8 + adcq %rcx,%r9 + adcq %rax,%r10 + adcq $0,%rdx + xorq %r11,%r11 + + + + addq %r8,%r12 + adcq %r9,%r13 + movq %r12,%r8 + adcq %r10,%r14 + adcq %rdx,%r15 + movq %r13,%r9 + adcq $0,%r11 + + subq $-1,%r12 + movq %r14,%r10 + sbbq %rsi,%r13 + sbbq $0,%r14 + movq %r15,%rcx + sbbq %rbp,%r15 + sbbq $0,%r11 + + cmovcq %r8,%r12 + cmovcq %r9,%r13 + movq %r12,0(%rdi) + cmovcq %r10,%r14 + movq %r13,8(%rdi) + cmovcq %rcx,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq +.type __ecp_nistz256_mul_montx,@function +.align 32 +__ecp_nistz256_mul_montx: +.cfi_startproc + + + mulxq %r9,%r8,%r9 + mulxq %r10,%rcx,%r10 + movq $32,%r14 + xorq %r13,%r13 + mulxq %r11,%rbp,%r11 + movq .Lpoly+24(%rip),%r15 + adcq %rcx,%r9 + mulxq %r12,%rcx,%r12 + movq %r8,%rdx + adcq %rbp,%r10 + shlxq %r14,%r8,%rbp + adcq %rcx,%r11 + shrxq %r14,%r8,%rcx + adcq $0,%r12 + + + + addq %rbp,%r9 + adcq %rcx,%r10 + + mulxq %r15,%rcx,%rbp + movq 8(%rbx),%rdx + adcq %rcx,%r11 + adcq %rbp,%r12 + adcq $0,%r13 + xorq %r8,%r8 + + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r9 + adoxq %rbp,%r10 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r9,%rdx + adcxq %rcx,%r12 + shlxq %r14,%r9,%rcx + adoxq %rbp,%r13 + shrxq %r14,%r9,%rbp + + adcxq %r8,%r13 + adoxq %r8,%r8 + adcq $0,%r8 + + + + addq %rcx,%r10 + adcq %rbp,%r11 + + mulxq %r15,%rcx,%rbp + movq 16(%rbx),%rdx + adcq %rcx,%r12 + adcq %rbp,%r13 + adcq $0,%r8 + xorq %r9,%r9 + + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r10 + adoxq %rbp,%r11 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r10,%rdx + adcxq %rcx,%r13 + shlxq %r14,%r10,%rcx + adoxq %rbp,%r8 + shrxq %r14,%r10,%rbp + + adcxq %r9,%r8 + adoxq %r9,%r9 + adcq $0,%r9 + + + + addq %rcx,%r11 + adcq %rbp,%r12 + + mulxq %r15,%rcx,%rbp + movq 24(%rbx),%rdx + adcq %rcx,%r13 + adcq %rbp,%r8 + adcq $0,%r9 + xorq %r10,%r10 + + + + mulxq 0+128(%rsi),%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq 8+128(%rsi),%rcx,%rbp + adcxq %rcx,%r12 + adoxq %rbp,%r13 + + mulxq 16+128(%rsi),%rcx,%rbp + adcxq %rcx,%r13 + adoxq %rbp,%r8 + + mulxq 24+128(%rsi),%rcx,%rbp + movq %r11,%rdx + adcxq %rcx,%r8 + shlxq %r14,%r11,%rcx + adoxq %rbp,%r9 + shrxq %r14,%r11,%rbp + + adcxq %r10,%r9 + adoxq %r10,%r10 + adcq $0,%r10 + + + + addq %rcx,%r12 + adcq %rbp,%r13 + + mulxq %r15,%rcx,%rbp + movq %r12,%rbx + movq .Lpoly+8(%rip),%r14 + adcq %rcx,%r8 + movq %r13,%rdx + adcq %rbp,%r9 + adcq $0,%r10 + + + + xorl %eax,%eax + movq %r8,%rcx + sbbq $-1,%r12 + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%rbp + sbbq %r15,%r9 + sbbq $0,%r10 + + cmovcq %rbx,%r12 + cmovcq %rdx,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %rbp,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_mul_montx,.-__ecp_nistz256_mul_montx + +.type __ecp_nistz256_sqr_montx,@function +.align 32 +__ecp_nistz256_sqr_montx: +.cfi_startproc + mulxq %r14,%r9,%r10 + mulxq %r15,%rcx,%r11 + xorl %eax,%eax + adcq %rcx,%r10 + mulxq %r8,%rbp,%r12 + movq %r14,%rdx + adcq %rbp,%r11 + adcq $0,%r12 + xorq %r13,%r13 + + + mulxq %r15,%rcx,%rbp + adcxq %rcx,%r11 + adoxq %rbp,%r12 + + mulxq %r8,%rcx,%rbp + movq %r15,%rdx + adcxq %rcx,%r12 + adoxq %rbp,%r13 + adcq $0,%r13 + + + mulxq %r8,%rcx,%r14 + movq 0+128(%rsi),%rdx + xorq %r15,%r15 + adcxq %r9,%r9 + adoxq %rcx,%r13 + adcxq %r10,%r10 + adoxq %r15,%r14 + + mulxq %rdx,%r8,%rbp + movq 8+128(%rsi),%rdx + adcxq %r11,%r11 + adoxq %rbp,%r9 + adcxq %r12,%r12 + mulxq %rdx,%rcx,%rax + movq 16+128(%rsi),%rdx + adcxq %r13,%r13 + adoxq %rcx,%r10 + adcxq %r14,%r14 +.byte 0x67 + mulxq %rdx,%rcx,%rbp + movq 24+128(%rsi),%rdx + adoxq %rax,%r11 + adcxq %r15,%r15 + adoxq %rcx,%r12 + movq $32,%rsi + adoxq %rbp,%r13 +.byte 0x67,0x67 + mulxq %rdx,%rcx,%rax + movq .Lpoly+24(%rip),%rdx + adoxq %rcx,%r14 + shlxq %rsi,%r8,%rcx + adoxq %rax,%r15 + shrxq %rsi,%r8,%rax + movq %rdx,%rbp + + + addq %rcx,%r9 + adcq %rax,%r10 + + mulxq %r8,%rcx,%r8 + adcq %rcx,%r11 + shlxq %rsi,%r9,%rcx + adcq $0,%r8 + shrxq %rsi,%r9,%rax + + + addq %rcx,%r10 + adcq %rax,%r11 + + mulxq %r9,%rcx,%r9 + adcq %rcx,%r8 + shlxq %rsi,%r10,%rcx + adcq $0,%r9 + shrxq %rsi,%r10,%rax + + + addq %rcx,%r11 + adcq %rax,%r8 + + mulxq %r10,%rcx,%r10 + adcq %rcx,%r9 + shlxq %rsi,%r11,%rcx + adcq $0,%r10 + shrxq %rsi,%r11,%rax + + + addq %rcx,%r8 + adcq %rax,%r9 + + mulxq %r11,%rcx,%r11 + adcq %rcx,%r10 + adcq $0,%r11 + + xorq %rdx,%rdx + addq %r8,%r12 + movq .Lpoly+8(%rip),%rsi + adcq %r9,%r13 + movq %r12,%r8 + adcq %r10,%r14 + adcq %r11,%r15 + movq %r13,%r9 + adcq $0,%rdx + + subq $-1,%r12 + movq %r14,%r10 + sbbq %rsi,%r13 + sbbq $0,%r14 + movq %r15,%r11 + sbbq %rbp,%r15 + sbbq $0,%rdx + + cmovcq %r8,%r12 + cmovcq %r9,%r13 + movq %r12,0(%rdi) + cmovcq %r10,%r14 + movq %r13,8(%rdi) + cmovcq %r11,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_sqr_montx,.-__ecp_nistz256_sqr_montx + + + + + + +.globl ecp_nistz256_from_mont +.type ecp_nistz256_from_mont,@function +.align 32 +ecp_nistz256_from_mont: +.cfi_startproc + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-16 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-24 +.Lfrom_body: + + movq 0(%rsi),%rax + movq .Lpoly+24(%rip),%r13 + movq 8(%rsi),%r9 + movq 16(%rsi),%r10 + movq 24(%rsi),%r11 + movq %rax,%r8 + movq .Lpoly+8(%rip),%r12 + + + + movq %rax,%rcx + shlq $32,%r8 + mulq %r13 + shrq $32,%rcx + addq %r8,%r9 + adcq %rcx,%r10 + adcq %rax,%r11 + movq %r9,%rax + adcq $0,%rdx + + + + movq %r9,%rcx + shlq $32,%r9 + movq %rdx,%r8 + mulq %r13 + shrq $32,%rcx + addq %r9,%r10 + adcq %rcx,%r11 + adcq %rax,%r8 + movq %r10,%rax + adcq $0,%rdx + + + + movq %r10,%rcx + shlq $32,%r10 + movq %rdx,%r9 + mulq %r13 + shrq $32,%rcx + addq %r10,%r11 + adcq %rcx,%r8 + adcq %rax,%r9 + movq %r11,%rax + adcq $0,%rdx + + + + movq %r11,%rcx + shlq $32,%r11 + movq %rdx,%r10 + mulq %r13 + shrq $32,%rcx + addq %r11,%r8 + adcq %rcx,%r9 + movq %r8,%rcx + adcq %rax,%r10 + movq %r9,%rsi + adcq $0,%rdx + + + + subq $-1,%r8 + movq %r10,%rax + sbbq %r12,%r9 + sbbq $0,%r10 + movq %rdx,%r11 + sbbq %r13,%rdx + sbbq %r13,%r13 + + cmovnzq %rcx,%r8 + cmovnzq %rsi,%r9 + movq %r8,0(%rdi) + cmovnzq %rax,%r10 + movq %r9,8(%rdi) + cmovzq %rdx,%r11 + movq %r10,16(%rdi) + movq %r11,24(%rdi) + + movq 0(%rsp),%r13 +.cfi_restore %r13 + movq 8(%rsp),%r12 +.cfi_restore %r12 + leaq 16(%rsp),%rsp +.cfi_adjust_cfa_offset -16 +.Lfrom_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_from_mont,.-ecp_nistz256_from_mont + + +.globl ecp_nistz256_scatter_w5 +.type ecp_nistz256_scatter_w5,@function +.align 32 +ecp_nistz256_scatter_w5: +.cfi_startproc + leal -3(%rdx,%rdx,2),%edx + movdqa 0(%rsi),%xmm0 + shll $5,%edx + movdqa 16(%rsi),%xmm1 + movdqa 32(%rsi),%xmm2 + movdqa 48(%rsi),%xmm3 + movdqa 64(%rsi),%xmm4 + movdqa 80(%rsi),%xmm5 + movdqa %xmm0,0(%rdi,%rdx,1) + movdqa %xmm1,16(%rdi,%rdx,1) + movdqa %xmm2,32(%rdi,%rdx,1) + movdqa %xmm3,48(%rdi,%rdx,1) + movdqa %xmm4,64(%rdi,%rdx,1) + movdqa %xmm5,80(%rdi,%rdx,1) + + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5 + + + +.globl ecp_nistz256_gather_w5 +.type ecp_nistz256_gather_w5,@function +.align 32 +ecp_nistz256_gather_w5: +.cfi_startproc + movl OPENSSL_ia32cap_P+8(%rip),%eax + testl $32,%eax + jnz .Lavx2_gather_w5 + movdqa .LOne(%rip),%xmm0 + movd %edx,%xmm1 + + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + + movdqa %xmm0,%xmm8 + pshufd $0,%xmm1,%xmm1 + + movq $16,%rax +.Lselect_loop_sse_w5: + + movdqa %xmm8,%xmm15 + paddd %xmm0,%xmm8 + pcmpeqd %xmm1,%xmm15 + + movdqa 0(%rsi),%xmm9 + movdqa 16(%rsi),%xmm10 + movdqa 32(%rsi),%xmm11 + movdqa 48(%rsi),%xmm12 + movdqa 64(%rsi),%xmm13 + movdqa 80(%rsi),%xmm14 + leaq 96(%rsi),%rsi + + pand %xmm15,%xmm9 + pand %xmm15,%xmm10 + por %xmm9,%xmm2 + pand %xmm15,%xmm11 + por %xmm10,%xmm3 + pand %xmm15,%xmm12 + por %xmm11,%xmm4 + pand %xmm15,%xmm13 + por %xmm12,%xmm5 + pand %xmm15,%xmm14 + por %xmm13,%xmm6 + por %xmm14,%xmm7 + + decq %rax + jnz .Lselect_loop_sse_w5 + + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + movdqu %xmm4,32(%rdi) + movdqu %xmm5,48(%rdi) + movdqu %xmm6,64(%rdi) + movdqu %xmm7,80(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_ecp_nistz256_gather_w5: +.size ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5 + + + +.globl ecp_nistz256_scatter_w7 +.type ecp_nistz256_scatter_w7,@function +.align 32 +ecp_nistz256_scatter_w7: +.cfi_startproc + movdqu 0(%rsi),%xmm0 + shll $6,%edx + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqa %xmm0,0(%rdi,%rdx,1) + movdqa %xmm1,16(%rdi,%rdx,1) + movdqa %xmm2,32(%rdi,%rdx,1) + movdqa %xmm3,48(%rdi,%rdx,1) + + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7 + + + +.globl ecp_nistz256_gather_w7 +.type ecp_nistz256_gather_w7,@function +.align 32 +ecp_nistz256_gather_w7: +.cfi_startproc + movl OPENSSL_ia32cap_P+8(%rip),%eax + testl $32,%eax + jnz .Lavx2_gather_w7 + movdqa .LOne(%rip),%xmm8 + movd %edx,%xmm1 + + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + + movdqa %xmm8,%xmm0 + pshufd $0,%xmm1,%xmm1 + movq $64,%rax + +.Lselect_loop_sse_w7: + movdqa %xmm8,%xmm15 + paddd %xmm0,%xmm8 + movdqa 0(%rsi),%xmm9 + movdqa 16(%rsi),%xmm10 + pcmpeqd %xmm1,%xmm15 + movdqa 32(%rsi),%xmm11 + movdqa 48(%rsi),%xmm12 + leaq 64(%rsi),%rsi + + pand %xmm15,%xmm9 + pand %xmm15,%xmm10 + por %xmm9,%xmm2 + pand %xmm15,%xmm11 + por %xmm10,%xmm3 + pand %xmm15,%xmm12 + por %xmm11,%xmm4 + prefetcht0 255(%rsi) + por %xmm12,%xmm5 + + decq %rax + jnz .Lselect_loop_sse_w7 + + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + movdqu %xmm4,32(%rdi) + movdqu %xmm5,48(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_ecp_nistz256_gather_w7: +.size ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7 + + +.type ecp_nistz256_avx2_gather_w5,@function +.align 32 +ecp_nistz256_avx2_gather_w5: +.cfi_startproc +.Lavx2_gather_w5: + vzeroupper + vmovdqa .LTwo(%rip),%ymm0 + + vpxor %ymm2,%ymm2,%ymm2 + vpxor %ymm3,%ymm3,%ymm3 + vpxor %ymm4,%ymm4,%ymm4 + + vmovdqa .LOne(%rip),%ymm5 + vmovdqa .LTwo(%rip),%ymm10 + + vmovd %edx,%xmm1 + vpermd %ymm1,%ymm2,%ymm1 + + movq $8,%rax +.Lselect_loop_avx2_w5: + + vmovdqa 0(%rsi),%ymm6 + vmovdqa 32(%rsi),%ymm7 + vmovdqa 64(%rsi),%ymm8 + + vmovdqa 96(%rsi),%ymm11 + vmovdqa 128(%rsi),%ymm12 + vmovdqa 160(%rsi),%ymm13 + + vpcmpeqd %ymm1,%ymm5,%ymm9 + vpcmpeqd %ymm1,%ymm10,%ymm14 + + vpaddd %ymm0,%ymm5,%ymm5 + vpaddd %ymm0,%ymm10,%ymm10 + leaq 192(%rsi),%rsi + + vpand %ymm9,%ymm6,%ymm6 + vpand %ymm9,%ymm7,%ymm7 + vpand %ymm9,%ymm8,%ymm8 + vpand %ymm14,%ymm11,%ymm11 + vpand %ymm14,%ymm12,%ymm12 + vpand %ymm14,%ymm13,%ymm13 + + vpxor %ymm6,%ymm2,%ymm2 + vpxor %ymm7,%ymm3,%ymm3 + vpxor %ymm8,%ymm4,%ymm4 + vpxor %ymm11,%ymm2,%ymm2 + vpxor %ymm12,%ymm3,%ymm3 + vpxor %ymm13,%ymm4,%ymm4 + + decq %rax + jnz .Lselect_loop_avx2_w5 + + vmovdqu %ymm2,0(%rdi) + vmovdqu %ymm3,32(%rdi) + vmovdqu %ymm4,64(%rdi) + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_ecp_nistz256_avx2_gather_w5: +.size ecp_nistz256_avx2_gather_w5,.-ecp_nistz256_avx2_gather_w5 + + + +.globl ecp_nistz256_avx2_gather_w7 +.type ecp_nistz256_avx2_gather_w7,@function +.align 32 +ecp_nistz256_avx2_gather_w7: +.cfi_startproc +.Lavx2_gather_w7: + vzeroupper + vmovdqa .LThree(%rip),%ymm0 + + vpxor %ymm2,%ymm2,%ymm2 + vpxor %ymm3,%ymm3,%ymm3 + + vmovdqa .LOne(%rip),%ymm4 + vmovdqa .LTwo(%rip),%ymm8 + vmovdqa .LThree(%rip),%ymm12 + + vmovd %edx,%xmm1 + vpermd %ymm1,%ymm2,%ymm1 + + + movq $21,%rax +.Lselect_loop_avx2_w7: + + vmovdqa 0(%rsi),%ymm5 + vmovdqa 32(%rsi),%ymm6 + + vmovdqa 64(%rsi),%ymm9 + vmovdqa 96(%rsi),%ymm10 + + vmovdqa 128(%rsi),%ymm13 + vmovdqa 160(%rsi),%ymm14 + + vpcmpeqd %ymm1,%ymm4,%ymm7 + vpcmpeqd %ymm1,%ymm8,%ymm11 + vpcmpeqd %ymm1,%ymm12,%ymm15 + + vpaddd %ymm0,%ymm4,%ymm4 + vpaddd %ymm0,%ymm8,%ymm8 + vpaddd %ymm0,%ymm12,%ymm12 + leaq 192(%rsi),%rsi + + vpand %ymm7,%ymm5,%ymm5 + vpand %ymm7,%ymm6,%ymm6 + vpand %ymm11,%ymm9,%ymm9 + vpand %ymm11,%ymm10,%ymm10 + vpand %ymm15,%ymm13,%ymm13 + vpand %ymm15,%ymm14,%ymm14 + + vpxor %ymm5,%ymm2,%ymm2 + vpxor %ymm6,%ymm3,%ymm3 + vpxor %ymm9,%ymm2,%ymm2 + vpxor %ymm10,%ymm3,%ymm3 + vpxor %ymm13,%ymm2,%ymm2 + vpxor %ymm14,%ymm3,%ymm3 + + decq %rax + jnz .Lselect_loop_avx2_w7 + + + vmovdqa 0(%rsi),%ymm5 + vmovdqa 32(%rsi),%ymm6 + + vpcmpeqd %ymm1,%ymm4,%ymm7 + + vpand %ymm7,%ymm5,%ymm5 + vpand %ymm7,%ymm6,%ymm6 + + vpxor %ymm5,%ymm2,%ymm2 + vpxor %ymm6,%ymm3,%ymm3 + + vmovdqu %ymm2,0(%rdi) + vmovdqu %ymm3,32(%rdi) + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.LSEH_end_ecp_nistz256_avx2_gather_w7: +.size ecp_nistz256_avx2_gather_w7,.-ecp_nistz256_avx2_gather_w7 +.type __ecp_nistz256_add_toq,@function +.align 32 +__ecp_nistz256_add_toq: +.cfi_startproc + xorq %r11,%r11 + addq 0(%rbx),%r12 + adcq 8(%rbx),%r13 + movq %r12,%rax + adcq 16(%rbx),%r8 + adcq 24(%rbx),%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_add_toq,.-__ecp_nistz256_add_toq + +.type __ecp_nistz256_sub_fromq,@function +.align 32 +__ecp_nistz256_sub_fromq: +.cfi_startproc + subq 0(%rbx),%r12 + sbbq 8(%rbx),%r13 + movq %r12,%rax + sbbq 16(%rbx),%r8 + sbbq 24(%rbx),%r9 + movq %r13,%rbp + sbbq %r11,%r11 + + addq $-1,%r12 + movq %r8,%rcx + adcq %r14,%r13 + adcq $0,%r8 + movq %r9,%r10 + adcq %r15,%r9 + testq %r11,%r11 + + cmovzq %rax,%r12 + cmovzq %rbp,%r13 + movq %r12,0(%rdi) + cmovzq %rcx,%r8 + movq %r13,8(%rdi) + cmovzq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_sub_fromq,.-__ecp_nistz256_sub_fromq + +.type __ecp_nistz256_subq,@function +.align 32 +__ecp_nistz256_subq: +.cfi_startproc + subq %r12,%rax + sbbq %r13,%rbp + movq %rax,%r12 + sbbq %r8,%rcx + sbbq %r9,%r10 + movq %rbp,%r13 + sbbq %r11,%r11 + + addq $-1,%rax + movq %rcx,%r8 + adcq %r14,%rbp + adcq $0,%rcx + movq %r10,%r9 + adcq %r15,%r10 + testq %r11,%r11 + + cmovnzq %rax,%r12 + cmovnzq %rbp,%r13 + cmovnzq %rcx,%r8 + cmovnzq %r10,%r9 + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_subq,.-__ecp_nistz256_subq + +.type __ecp_nistz256_mul_by_2q,@function +.align 32 +__ecp_nistz256_mul_by_2q: +.cfi_startproc + xorq %r11,%r11 + addq %r12,%r12 + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_mul_by_2q,.-__ecp_nistz256_mul_by_2q +.globl ecp_nistz256_point_double +.type ecp_nistz256_point_double,@function +.align 32 +ecp_nistz256_point_double: +.cfi_startproc + movl $0x80100,%ecx + andl OPENSSL_ia32cap_P+8(%rip),%ecx + cmpl $0x80100,%ecx + je .Lpoint_doublex + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $160+8,%rsp +.cfi_adjust_cfa_offset 32*5+8 +.Lpoint_doubleq_body: + +.Lpoint_double_shortcutq: + movdqu 0(%rsi),%xmm0 + movq %rsi,%rbx + movdqu 16(%rsi),%xmm1 + movq 32+0(%rsi),%r12 + movq 32+8(%rsi),%r13 + movq 32+16(%rsi),%r8 + movq 32+24(%rsi),%r9 + movq .Lpoly+8(%rip),%r14 + movq .Lpoly+24(%rip),%r15 + movdqa %xmm0,96(%rsp) + movdqa %xmm1,96+16(%rsp) + leaq 32(%rdi),%r10 + leaq 64(%rdi),%r11 +.byte 102,72,15,110,199 +.byte 102,73,15,110,202 +.byte 102,73,15,110,211 + + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_by_2q + + movq 64+0(%rsi),%rax + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + leaq 64-0(%rsi),%rsi + leaq 64(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 0+0(%rsp),%rax + movq 8+0(%rsp),%r14 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 0(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 32(%rbx),%rax + movq 64+0(%rbx),%r9 + movq 64+8(%rbx),%r10 + movq 64+16(%rbx),%r11 + movq 64+24(%rbx),%r12 + leaq 64-0(%rbx),%rsi + leaq 32(%rbx),%rbx +.byte 102,72,15,126,215 + call __ecp_nistz256_mul_montq + call __ecp_nistz256_mul_by_2q + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_toq + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 0+0(%rsp),%rax + movq 8+0(%rsp),%r14 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 +.byte 102,72,15,126,207 + call __ecp_nistz256_sqr_montq + xorq %r9,%r9 + movq %r12,%rax + addq $-1,%r12 + movq %r13,%r10 + adcq %rsi,%r13 + movq %r14,%rcx + adcq $0,%r14 + movq %r15,%r8 + adcq %rbp,%r15 + adcq $0,%r9 + xorq %rsi,%rsi + testq $1,%rax + + cmovzq %rax,%r12 + cmovzq %r10,%r13 + cmovzq %rcx,%r14 + cmovzq %r8,%r15 + cmovzq %rsi,%r9 + + movq %r13,%rax + shrq $1,%r12 + shlq $63,%rax + movq %r14,%r10 + shrq $1,%r13 + orq %rax,%r12 + shlq $63,%r10 + movq %r15,%rcx + shrq $1,%r14 + orq %r10,%r13 + shlq $63,%rcx + movq %r12,0(%rdi) + shrq $1,%r15 + movq %r13,8(%rdi) + shlq $63,%r9 + orq %rcx,%r14 + orq %r9,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + movq 64(%rsp),%rax + leaq 64(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2q + + leaq 32(%rsp),%rbx + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_toq + + movq 96(%rsp),%rax + leaq 96(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2q + + movq 0+32(%rsp),%rax + movq 8+32(%rsp),%r14 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r15 + movq 24+32(%rsp),%r8 +.byte 102,72,15,126,199 + call __ecp_nistz256_sqr_montq + + leaq 128(%rsp),%rbx + movq %r14,%r8 + movq %r15,%r9 + movq %rsi,%r14 + movq %rbp,%r15 + call __ecp_nistz256_sub_fromq + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 0(%rsp),%rdi + call __ecp_nistz256_subq + + movq 32(%rsp),%rax + leaq 32(%rsp),%rbx + movq %r12,%r14 + xorl %ecx,%ecx + movq %r12,0+0(%rsp) + movq %r13,%r10 + movq %r13,0+8(%rsp) + cmovzq %r8,%r11 + movq %r8,0+16(%rsp) + leaq 0-0(%rsp),%rsi + cmovzq %r9,%r12 + movq %r9,0+24(%rsp) + movq %r14,%r9 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + +.byte 102,72,15,126,203 +.byte 102,72,15,126,207 + call __ecp_nistz256_sub_fromq + + leaq 160+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpoint_doubleq_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_double,.-ecp_nistz256_point_double +.globl ecp_nistz256_point_add +.type ecp_nistz256_point_add,@function +.align 32 +ecp_nistz256_point_add: +.cfi_startproc + movl $0x80100,%ecx + andl OPENSSL_ia32cap_P+8(%rip),%ecx + cmpl $0x80100,%ecx + je .Lpoint_addx + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $576+8,%rsp +.cfi_adjust_cfa_offset 32*18+8 +.Lpoint_addq_body: + + movdqu 0(%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq %rsi,%rbx + movq %rdx,%rsi + movdqa %xmm0,384(%rsp) + movdqa %xmm1,384+16(%rsp) + movdqa %xmm2,416(%rsp) + movdqa %xmm3,416+16(%rsp) + movdqa %xmm4,448(%rsp) + movdqa %xmm5,448+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rsi),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rsi),%xmm3 + movq 64+0(%rsi),%rax + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,480(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,480+16(%rsp) + movdqu 64(%rsi),%xmm0 + movdqu 80(%rsi),%xmm1 + movdqa %xmm2,512(%rsp) + movdqa %xmm3,512+16(%rsp) + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + + leaq 64-0(%rsi),%rsi + movq %rax,544+0(%rsp) + movq %r14,544+8(%rsp) + movq %r15,544+16(%rsp) + movq %r8,544+24(%rsp) + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm1,%xmm4 + por %xmm1,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + movq 64+0(%rbx),%rax + movq 64+8(%rbx),%r14 + movq 64+16(%rbx),%r15 + movq 64+24(%rbx),%r8 +.byte 102,72,15,110,203 + + leaq 64-0(%rbx),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 544(%rsp),%rax + leaq 544(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq 0+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 448(%rsp),%rax + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 416(%rsp),%rax + leaq 416(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq 0+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 512(%rsp),%rax + leaq 512(%rsp),%rbx + movq 0+256(%rsp),%r9 + movq 8+256(%rsp),%r10 + leaq 0+256(%rsp),%rsi + movq 16+256(%rsp),%r11 + movq 24+256(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 224(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + orq %r13,%r12 + movdqa %xmm4,%xmm2 + orq %r8,%r12 + orq %r9,%r12 + por %xmm5,%xmm2 +.byte 102,73,15,110,220 + + movq 384(%rsp),%rax + leaq 384(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq 0+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 480(%rsp),%rax + leaq 480(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 160(%rsp),%rbx + leaq 0(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + orq %r13,%r12 + orq %r8,%r12 + orq %r9,%r12 + +.byte 102,73,15,126,208 +.byte 102,73,15,126,217 + + orq %r8,%r12 + orq %r9,%r12 + + +.byte 0x3e + jnz .Ladd_proceedq + +.Ladd_doubleq: +.byte 102,72,15,126,206 +.byte 102,72,15,126,199 + addq $416,%rsp +.cfi_adjust_cfa_offset -416 + jmp .Lpoint_double_shortcutq +.cfi_adjust_cfa_offset 416 + +.align 32 +.Ladd_proceedq: + movq 0+64(%rsp),%rax + movq 8+64(%rsp),%r14 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 448(%rsp),%rax + leaq 448(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 0+0(%rsp),%rax + movq 8+0(%rsp),%r14 + leaq 0+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 544(%rsp),%rax + leaq 544(%rsp),%rbx + movq 0+352(%rsp),%r9 + movq 8+352(%rsp),%r10 + leaq 0+352(%rsp),%rsi + movq 16+352(%rsp),%r11 + movq 24+352(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 0(%rsp),%rax + leaq 0(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 160(%rsp),%rax + leaq 160(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montq + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 96(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subq + + leaq 128(%rsp),%rbx + leaq 288(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 192+0(%rsp),%rax + movq 192+8(%rsp),%rbp + movq 192+16(%rsp),%rcx + movq 192+24(%rsp),%r10 + leaq 320(%rsp),%rdi + + call __ecp_nistz256_subq + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 128(%rsp),%rax + leaq 128(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq 0+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 320(%rsp),%rax + leaq 320(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 320(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 256(%rsp),%rbx + leaq 320(%rsp),%rdi + call __ecp_nistz256_sub_fromq + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 352(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 352+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 544(%rsp),%xmm2 + pand 544+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 480(%rsp),%xmm2 + pand 480+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 320(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 320+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 512(%rsp),%xmm2 + pand 512+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + +.Ladd_doneq: + leaq 576+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpoint_addq_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_add,.-ecp_nistz256_point_add +.globl ecp_nistz256_point_add_affine +.type ecp_nistz256_point_add_affine,@function +.align 32 +ecp_nistz256_point_add_affine: +.cfi_startproc + movl $0x80100,%ecx + andl OPENSSL_ia32cap_P+8(%rip),%ecx + cmpl $0x80100,%ecx + je .Lpoint_add_affinex + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $480+8,%rsp +.cfi_adjust_cfa_offset 32*15+8 +.Ladd_affineq_body: + + movdqu 0(%rsi),%xmm0 + movq %rdx,%rbx + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq 64+0(%rsi),%rax + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,320(%rsp) + movdqa %xmm1,320+16(%rsp) + movdqa %xmm2,352(%rsp) + movdqa %xmm3,352+16(%rsp) + movdqa %xmm4,384(%rsp) + movdqa %xmm5,384+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rbx),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rbx),%xmm1 + movdqu 32(%rbx),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rbx),%xmm3 + movdqa %xmm0,416(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,416+16(%rsp) + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + movdqa %xmm2,448(%rsp) + movdqa %xmm3,448+16(%rsp) + por %xmm2,%xmm3 + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm1,%xmm3 + + leaq 64-0(%rsi),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm3,%xmm4 + movq 0(%rbx),%rax + + movq %r12,%r9 + por %xmm3,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + movq %r13,%r10 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + movq %r14,%r11 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + + leaq 32-0(%rsp),%rsi + movq %r15,%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 320(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 384(%rsp),%rax + leaq 384(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 384(%rsp),%rax + leaq 384(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 288(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 448(%rsp),%rax + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq 0+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 352(%rsp),%rbx + leaq 96(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 0+64(%rsp),%rax + movq 8+64(%rsp),%r14 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 128(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 0+96(%rsp),%rax + movq 8+96(%rsp),%r14 + leaq 0+96(%rsp),%rsi + movq 16+96(%rsp),%r15 + movq 24+96(%rsp),%r8 + leaq 192(%rsp),%rdi + call __ecp_nistz256_sqr_montq + + movq 128(%rsp),%rax + leaq 128(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 320(%rsp),%rax + leaq 320(%rsp),%rbx + movq 0+128(%rsp),%r9 + movq 8+128(%rsp),%r10 + leaq 0+128(%rsp),%rsi + movq 16+128(%rsp),%r11 + movq 24+128(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montq + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 192(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subq + + leaq 160(%rsp),%rbx + leaq 224(%rsp),%rdi + call __ecp_nistz256_sub_fromq + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 64(%rsp),%rdi + + call __ecp_nistz256_subq + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 352(%rsp),%rax + leaq 352(%rsp),%rbx + movq 0+160(%rsp),%r9 + movq 8+160(%rsp),%r10 + leaq 0+160(%rsp),%rsi + movq 16+160(%rsp),%r11 + movq 24+160(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montq + + movq 96(%rsp),%rax + leaq 96(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq 0+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 64(%rsp),%rdi + call __ecp_nistz256_mul_montq + + leaq 32(%rsp),%rbx + leaq 256(%rsp),%rdi + call __ecp_nistz256_sub_fromq + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand .LONE_mont(%rip),%xmm2 + pand .LONE_mont+16(%rip),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 224(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 224+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 320(%rsp),%xmm2 + pand 320+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 256(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 256+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 352(%rsp),%xmm2 + pand 352+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + + leaq 480+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Ladd_affineq_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine +.type __ecp_nistz256_add_tox,@function +.align 32 +__ecp_nistz256_add_tox: +.cfi_startproc + xorq %r11,%r11 + adcq 0(%rbx),%r12 + adcq 8(%rbx),%r13 + movq %r12,%rax + adcq 16(%rbx),%r8 + adcq 24(%rbx),%r9 + movq %r13,%rbp + adcq $0,%r11 + + xorq %r10,%r10 + sbbq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_add_tox,.-__ecp_nistz256_add_tox + +.type __ecp_nistz256_sub_fromx,@function +.align 32 +__ecp_nistz256_sub_fromx: +.cfi_startproc + xorq %r11,%r11 + sbbq 0(%rbx),%r12 + sbbq 8(%rbx),%r13 + movq %r12,%rax + sbbq 16(%rbx),%r8 + sbbq 24(%rbx),%r9 + movq %r13,%rbp + sbbq $0,%r11 + + xorq %r10,%r10 + adcq $-1,%r12 + movq %r8,%rcx + adcq %r14,%r13 + adcq $0,%r8 + movq %r9,%r10 + adcq %r15,%r9 + + btq $0,%r11 + cmovncq %rax,%r12 + cmovncq %rbp,%r13 + movq %r12,0(%rdi) + cmovncq %rcx,%r8 + movq %r13,8(%rdi) + cmovncq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_sub_fromx,.-__ecp_nistz256_sub_fromx + +.type __ecp_nistz256_subx,@function +.align 32 +__ecp_nistz256_subx: +.cfi_startproc + xorq %r11,%r11 + sbbq %r12,%rax + sbbq %r13,%rbp + movq %rax,%r12 + sbbq %r8,%rcx + sbbq %r9,%r10 + movq %rbp,%r13 + sbbq $0,%r11 + + xorq %r9,%r9 + adcq $-1,%rax + movq %rcx,%r8 + adcq %r14,%rbp + adcq $0,%rcx + movq %r10,%r9 + adcq %r15,%r10 + + btq $0,%r11 + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + cmovcq %rcx,%r8 + cmovcq %r10,%r9 + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_subx,.-__ecp_nistz256_subx + +.type __ecp_nistz256_mul_by_2x,@function +.align 32 +__ecp_nistz256_mul_by_2x: +.cfi_startproc + xorq %r11,%r11 + adcq %r12,%r12 + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + xorq %r10,%r10 + sbbq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + cmovcq %rbp,%r13 + movq %r12,0(%rdi) + cmovcq %rcx,%r8 + movq %r13,8(%rdi) + cmovcq %r10,%r9 + movq %r8,16(%rdi) + movq %r9,24(%rdi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size __ecp_nistz256_mul_by_2x,.-__ecp_nistz256_mul_by_2x +.type ecp_nistz256_point_doublex,@function +.align 32 +ecp_nistz256_point_doublex: +.cfi_startproc +.Lpoint_doublex: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $160+8,%rsp +.cfi_adjust_cfa_offset 32*5+8 +.Lpoint_doublex_body: + +.Lpoint_double_shortcutx: + movdqu 0(%rsi),%xmm0 + movq %rsi,%rbx + movdqu 16(%rsi),%xmm1 + movq 32+0(%rsi),%r12 + movq 32+8(%rsi),%r13 + movq 32+16(%rsi),%r8 + movq 32+24(%rsi),%r9 + movq .Lpoly+8(%rip),%r14 + movq .Lpoly+24(%rip),%r15 + movdqa %xmm0,96(%rsp) + movdqa %xmm1,96+16(%rsp) + leaq 32(%rdi),%r10 + leaq 64(%rdi),%r11 +.byte 102,72,15,110,199 +.byte 102,73,15,110,202 +.byte 102,73,15,110,211 + + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_by_2x + + movq 64+0(%rsi),%rdx + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + leaq 64-128(%rsi),%rsi + leaq 64(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 0+0(%rsp),%rdx + movq 8+0(%rsp),%r14 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 0(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 32(%rbx),%rdx + movq 64+0(%rbx),%r9 + movq 64+8(%rbx),%r10 + movq 64+16(%rbx),%r11 + movq 64+24(%rbx),%r12 + leaq 64-128(%rbx),%rsi + leaq 32(%rbx),%rbx +.byte 102,72,15,126,215 + call __ecp_nistz256_mul_montx + call __ecp_nistz256_mul_by_2x + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_tox + + movq 96+0(%rsp),%r12 + movq 96+8(%rsp),%r13 + leaq 64(%rsp),%rbx + movq 96+16(%rsp),%r8 + movq 96+24(%rsp),%r9 + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 0+0(%rsp),%rdx + movq 8+0(%rsp),%r14 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 +.byte 102,72,15,126,207 + call __ecp_nistz256_sqr_montx + xorq %r9,%r9 + movq %r12,%rax + addq $-1,%r12 + movq %r13,%r10 + adcq %rsi,%r13 + movq %r14,%rcx + adcq $0,%r14 + movq %r15,%r8 + adcq %rbp,%r15 + adcq $0,%r9 + xorq %rsi,%rsi + testq $1,%rax + + cmovzq %rax,%r12 + cmovzq %r10,%r13 + cmovzq %rcx,%r14 + cmovzq %r8,%r15 + cmovzq %rsi,%r9 + + movq %r13,%rax + shrq $1,%r12 + shlq $63,%rax + movq %r14,%r10 + shrq $1,%r13 + orq %rax,%r12 + shlq $63,%r10 + movq %r15,%rcx + shrq $1,%r14 + orq %r10,%r13 + shlq $63,%rcx + movq %r12,0(%rdi) + shrq $1,%r15 + movq %r13,8(%rdi) + shlq $63,%r9 + orq %rcx,%r14 + orq %r9,%r15 + movq %r14,16(%rdi) + movq %r15,24(%rdi) + movq 64(%rsp),%rdx + leaq 64(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2x + + leaq 32(%rsp),%rbx + leaq 32(%rsp),%rdi + call __ecp_nistz256_add_tox + + movq 96(%rsp),%rdx + leaq 96(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_by_2x + + movq 0+32(%rsp),%rdx + movq 8+32(%rsp),%r14 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r15 + movq 24+32(%rsp),%r8 +.byte 102,72,15,126,199 + call __ecp_nistz256_sqr_montx + + leaq 128(%rsp),%rbx + movq %r14,%r8 + movq %r15,%r9 + movq %rsi,%r14 + movq %rbp,%r15 + call __ecp_nistz256_sub_fromx + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 0(%rsp),%rdi + call __ecp_nistz256_subx + + movq 32(%rsp),%rdx + leaq 32(%rsp),%rbx + movq %r12,%r14 + xorl %ecx,%ecx + movq %r12,0+0(%rsp) + movq %r13,%r10 + movq %r13,0+8(%rsp) + cmovzq %r8,%r11 + movq %r8,0+16(%rsp) + leaq 0-128(%rsp),%rsi + cmovzq %r9,%r12 + movq %r9,0+24(%rsp) + movq %r14,%r9 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + +.byte 102,72,15,126,203 +.byte 102,72,15,126,207 + call __ecp_nistz256_sub_fromx + + leaq 160+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpoint_doublex_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_doublex,.-ecp_nistz256_point_doublex +.type ecp_nistz256_point_addx,@function +.align 32 +ecp_nistz256_point_addx: +.cfi_startproc +.Lpoint_addx: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $576+8,%rsp +.cfi_adjust_cfa_offset 32*18+8 +.Lpoint_addx_body: + + movdqu 0(%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq %rsi,%rbx + movq %rdx,%rsi + movdqa %xmm0,384(%rsp) + movdqa %xmm1,384+16(%rsp) + movdqa %xmm2,416(%rsp) + movdqa %xmm3,416+16(%rsp) + movdqa %xmm4,448(%rsp) + movdqa %xmm5,448+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rsi),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rsi),%xmm3 + movq 64+0(%rsi),%rdx + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,480(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,480+16(%rsp) + movdqu 64(%rsi),%xmm0 + movdqu 80(%rsi),%xmm1 + movdqa %xmm2,512(%rsp) + movdqa %xmm3,512+16(%rsp) + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + + leaq 64-128(%rsi),%rsi + movq %rdx,544+0(%rsp) + movq %r14,544+8(%rsp) + movq %r15,544+16(%rsp) + movq %r8,544+24(%rsp) + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm1,%xmm4 + por %xmm1,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + movq 64+0(%rbx),%rdx + movq 64+8(%rbx),%r14 + movq 64+16(%rbx),%r15 + movq 64+24(%rbx),%r8 +.byte 102,72,15,110,203 + + leaq 64-128(%rbx),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 544(%rsp),%rdx + leaq 544(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq -128+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 448(%rsp),%rdx + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 416(%rsp),%rdx + leaq 416(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq -128+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 224(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 512(%rsp),%rdx + leaq 512(%rsp),%rbx + movq 0+256(%rsp),%r9 + movq 8+256(%rsp),%r10 + leaq -128+256(%rsp),%rsi + movq 16+256(%rsp),%r11 + movq 24+256(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 224(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + orq %r13,%r12 + movdqa %xmm4,%xmm2 + orq %r8,%r12 + orq %r9,%r12 + por %xmm5,%xmm2 +.byte 102,73,15,110,220 + + movq 384(%rsp),%rdx + leaq 384(%rsp),%rbx + movq 0+96(%rsp),%r9 + movq 8+96(%rsp),%r10 + leaq -128+96(%rsp),%rsi + movq 16+96(%rsp),%r11 + movq 24+96(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 480(%rsp),%rdx + leaq 480(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 160(%rsp),%rbx + leaq 0(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + orq %r13,%r12 + orq %r8,%r12 + orq %r9,%r12 + +.byte 102,73,15,126,208 +.byte 102,73,15,126,217 + + orq %r8,%r12 + orq %r9,%r12 + + +.byte 0x3e + jnz .Ladd_proceedx + +.Ladd_doublex: +.byte 102,72,15,126,206 +.byte 102,72,15,126,199 + addq $416,%rsp +.cfi_adjust_cfa_offset -416 + jmp .Lpoint_double_shortcutx +.cfi_adjust_cfa_offset 416 + +.align 32 +.Ladd_proceedx: + movq 0+64(%rsp),%rdx + movq 8+64(%rsp),%r14 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 96(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 448(%rsp),%rdx + leaq 448(%rsp),%rbx + movq 0+0(%rsp),%r9 + movq 8+0(%rsp),%r10 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r11 + movq 24+0(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 0+0(%rsp),%rdx + movq 8+0(%rsp),%r14 + leaq -128+0(%rsp),%rsi + movq 16+0(%rsp),%r15 + movq 24+0(%rsp),%r8 + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 544(%rsp),%rdx + leaq 544(%rsp),%rbx + movq 0+352(%rsp),%r9 + movq 8+352(%rsp),%r10 + leaq -128+352(%rsp),%rsi + movq 16+352(%rsp),%r11 + movq 24+352(%rsp),%r12 + leaq 352(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 0(%rsp),%rdx + leaq 0(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 128(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 160(%rsp),%rdx + leaq 160(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 192(%rsp),%rdi + call __ecp_nistz256_mul_montx + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 96(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subx + + leaq 128(%rsp),%rbx + leaq 288(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 192+0(%rsp),%rax + movq 192+8(%rsp),%rbp + movq 192+16(%rsp),%rcx + movq 192+24(%rsp),%r10 + leaq 320(%rsp),%rdi + + call __ecp_nistz256_subx + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 128(%rsp),%rdx + leaq 128(%rsp),%rbx + movq 0+224(%rsp),%r9 + movq 8+224(%rsp),%r10 + leaq -128+224(%rsp),%rsi + movq 16+224(%rsp),%r11 + movq 24+224(%rsp),%r12 + leaq 256(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 320(%rsp),%rdx + leaq 320(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 320(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 256(%rsp),%rbx + leaq 320(%rsp),%rdi + call __ecp_nistz256_sub_fromx + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 352(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 352+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 544(%rsp),%xmm2 + pand 544+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 480(%rsp),%xmm2 + pand 480+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 320(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 320+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 512(%rsp),%xmm2 + pand 512+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + +.Ladd_donex: + leaq 576+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lpoint_addx_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_addx,.-ecp_nistz256_point_addx +.type ecp_nistz256_point_add_affinex,@function +.align 32 +ecp_nistz256_point_add_affinex: +.cfi_startproc +.Lpoint_add_affinex: + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $480+8,%rsp +.cfi_adjust_cfa_offset 32*15+8 +.Ladd_affinex_body: + + movdqu 0(%rsi),%xmm0 + movq %rdx,%rbx + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 + movdqu 48(%rsi),%xmm3 + movdqu 64(%rsi),%xmm4 + movdqu 80(%rsi),%xmm5 + movq 64+0(%rsi),%rdx + movq 64+8(%rsi),%r14 + movq 64+16(%rsi),%r15 + movq 64+24(%rsi),%r8 + movdqa %xmm0,320(%rsp) + movdqa %xmm1,320+16(%rsp) + movdqa %xmm2,352(%rsp) + movdqa %xmm3,352+16(%rsp) + movdqa %xmm4,384(%rsp) + movdqa %xmm5,384+16(%rsp) + por %xmm4,%xmm5 + + movdqu 0(%rbx),%xmm0 + pshufd $0xb1,%xmm5,%xmm3 + movdqu 16(%rbx),%xmm1 + movdqu 32(%rbx),%xmm2 + por %xmm3,%xmm5 + movdqu 48(%rbx),%xmm3 + movdqa %xmm0,416(%rsp) + pshufd $0x1e,%xmm5,%xmm4 + movdqa %xmm1,416+16(%rsp) + por %xmm0,%xmm1 +.byte 102,72,15,110,199 + movdqa %xmm2,448(%rsp) + movdqa %xmm3,448+16(%rsp) + por %xmm2,%xmm3 + por %xmm4,%xmm5 + pxor %xmm4,%xmm4 + por %xmm1,%xmm3 + + leaq 64-128(%rsi),%rsi + leaq 32(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + pcmpeqd %xmm4,%xmm5 + pshufd $0xb1,%xmm3,%xmm4 + movq 0(%rbx),%rdx + + movq %r12,%r9 + por %xmm3,%xmm4 + pshufd $0,%xmm5,%xmm5 + pshufd $0x1e,%xmm4,%xmm3 + movq %r13,%r10 + por %xmm3,%xmm4 + pxor %xmm3,%xmm3 + movq %r14,%r11 + pcmpeqd %xmm3,%xmm4 + pshufd $0,%xmm4,%xmm4 + + leaq 32-128(%rsp),%rsi + movq %r15,%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 320(%rsp),%rbx + leaq 64(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 384(%rsp),%rdx + leaq 384(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 384(%rsp),%rdx + leaq 384(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 288(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 448(%rsp),%rdx + leaq 448(%rsp),%rbx + movq 0+32(%rsp),%r9 + movq 8+32(%rsp),%r10 + leaq -128+32(%rsp),%rsi + movq 16+32(%rsp),%r11 + movq 24+32(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 352(%rsp),%rbx + leaq 96(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 0+64(%rsp),%rdx + movq 8+64(%rsp),%r14 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r15 + movq 24+64(%rsp),%r8 + leaq 128(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 0+96(%rsp),%rdx + movq 8+96(%rsp),%r14 + leaq -128+96(%rsp),%rsi + movq 16+96(%rsp),%r15 + movq 24+96(%rsp),%r8 + leaq 192(%rsp),%rdi + call __ecp_nistz256_sqr_montx + + movq 128(%rsp),%rdx + leaq 128(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 160(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 320(%rsp),%rdx + leaq 320(%rsp),%rbx + movq 0+128(%rsp),%r9 + movq 8+128(%rsp),%r10 + leaq -128+128(%rsp),%rsi + movq 16+128(%rsp),%r11 + movq 24+128(%rsp),%r12 + leaq 0(%rsp),%rdi + call __ecp_nistz256_mul_montx + + + + + xorq %r11,%r11 + addq %r12,%r12 + leaq 192(%rsp),%rsi + adcq %r13,%r13 + movq %r12,%rax + adcq %r8,%r8 + adcq %r9,%r9 + movq %r13,%rbp + adcq $0,%r11 + + subq $-1,%r12 + movq %r8,%rcx + sbbq %r14,%r13 + sbbq $0,%r8 + movq %r9,%r10 + sbbq %r15,%r9 + sbbq $0,%r11 + + cmovcq %rax,%r12 + movq 0(%rsi),%rax + cmovcq %rbp,%r13 + movq 8(%rsi),%rbp + cmovcq %rcx,%r8 + movq 16(%rsi),%rcx + cmovcq %r10,%r9 + movq 24(%rsi),%r10 + + call __ecp_nistz256_subx + + leaq 160(%rsp),%rbx + leaq 224(%rsp),%rdi + call __ecp_nistz256_sub_fromx + + movq 0+0(%rsp),%rax + movq 0+8(%rsp),%rbp + movq 0+16(%rsp),%rcx + movq 0+24(%rsp),%r10 + leaq 64(%rsp),%rdi + + call __ecp_nistz256_subx + + movq %r12,0(%rdi) + movq %r13,8(%rdi) + movq %r8,16(%rdi) + movq %r9,24(%rdi) + movq 352(%rsp),%rdx + leaq 352(%rsp),%rbx + movq 0+160(%rsp),%r9 + movq 8+160(%rsp),%r10 + leaq -128+160(%rsp),%rsi + movq 16+160(%rsp),%r11 + movq 24+160(%rsp),%r12 + leaq 32(%rsp),%rdi + call __ecp_nistz256_mul_montx + + movq 96(%rsp),%rdx + leaq 96(%rsp),%rbx + movq 0+64(%rsp),%r9 + movq 8+64(%rsp),%r10 + leaq -128+64(%rsp),%rsi + movq 16+64(%rsp),%r11 + movq 24+64(%rsp),%r12 + leaq 64(%rsp),%rdi + call __ecp_nistz256_mul_montx + + leaq 32(%rsp),%rbx + leaq 256(%rsp),%rdi + call __ecp_nistz256_sub_fromx + +.byte 102,72,15,126,199 + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 288(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 288+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand .LONE_mont(%rip),%xmm2 + pand .LONE_mont+16(%rip),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 384(%rsp),%xmm2 + pand 384+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,64(%rdi) + movdqu %xmm3,80(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 224(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 224+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 416(%rsp),%xmm2 + pand 416+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 320(%rsp),%xmm2 + pand 320+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,0(%rdi) + movdqu %xmm3,16(%rdi) + + movdqa %xmm5,%xmm0 + movdqa %xmm5,%xmm1 + pandn 256(%rsp),%xmm0 + movdqa %xmm5,%xmm2 + pandn 256+16(%rsp),%xmm1 + movdqa %xmm5,%xmm3 + pand 448(%rsp),%xmm2 + pand 448+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + pandn %xmm2,%xmm0 + movdqa %xmm4,%xmm2 + pandn %xmm3,%xmm1 + movdqa %xmm4,%xmm3 + pand 352(%rsp),%xmm2 + pand 352+16(%rsp),%xmm3 + por %xmm0,%xmm2 + por %xmm1,%xmm3 + movdqu %xmm2,32(%rdi) + movdqu %xmm3,48(%rdi) + + leaq 480+56(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbx +.cfi_restore %rbx + movq -8(%rsi),%rbp +.cfi_restore %rbp + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Ladd_affinex_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size ecp_nistz256_point_add_affinex,.-ecp_nistz256_point_add_affinex + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/ec/ecp_nistz256.c b/crypto/openssl/crypto/ec/ecp_nistz256.c index cfad3e15b0bf..d65f6984ded3 100644 --- a/crypto/openssl/crypto/ec/ecp_nistz256.c +++ b/crypto/openssl/crypto/ec/ecp_nistz256.c @@ -3,7 +3,7 @@ * Copyright (c) 2014, Intel Corporation. All Rights Reserved. * Copyright (c) 2015, CloudFlare, Inc. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -18,6 +18,12 @@ * 256 Bit Primes" */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" @@ -631,7 +637,7 @@ __owur static int ecp_nistz256_windowed_mul(const EC_GROUP *group, || (p_str = OPENSSL_malloc(num * 33 * sizeof(unsigned char))) == NULL || (scalars = OPENSSL_malloc(num * sizeof(BIGNUM *))) == NULL) { - ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -648,7 +654,7 @@ __owur static int ecp_nistz256_windowed_mul(const EC_GROUP *group, if ((mod = BN_CTX_get(ctx)) == NULL) goto err; if (!BN_nnmod(mod, scalar[i], group->order, ctx)) { - ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } scalars[i] = mod; @@ -676,8 +682,7 @@ __owur static int ecp_nistz256_windowed_mul(const EC_GROUP *group, if (!ecp_nistz256_bignum_to_field_elem(temp[0].X, point[i]->X) || !ecp_nistz256_bignum_to_field_elem(temp[0].Y, point[i]->Y) || !ecp_nistz256_bignum_to_field_elem(temp[0].Z, point[i]->Z)) { - ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL, - EC_R_COORDINATES_OUT_OF_RANGE); + ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); goto err; } @@ -828,7 +833,7 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) EC_pre_comp_free(group); generator = EC_GROUP_get0_generator(group); if (generator == NULL) { - ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, EC_R_UNDEFINED_GENERATOR); + ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR); return 0; } @@ -844,7 +849,7 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) return 0; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) goto err; } @@ -856,7 +861,7 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) goto err; if (BN_is_zero(order)) { - ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, EC_R_UNKNOWN_ORDER); + ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_ORDER); goto err; } @@ -864,7 +869,7 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) if ((precomp_storage = OPENSSL_malloc(37 * 64 * sizeof(P256_POINT_AFFINE) + 64)) == NULL) { - ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -891,12 +896,12 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) * It would be faster to use EC_POINTs_make_affine and * make multiple points affine at the same time. */ - if (!EC_POINT_make_affine(group, P, ctx)) + if (group->meth->make_affine == NULL + || !group->meth->make_affine(group, P, ctx)) goto err; if (!ecp_nistz256_bignum_to_field_elem(temp.X, P->X) || !ecp_nistz256_bignum_to_field_elem(temp.Y, P->Y)) { - ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, - EC_R_COORDINATES_OUT_OF_RANGE); + ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); goto err; } ecp_nistz256_scatter_w7(preComputedTable[j], &temp, k); @@ -969,7 +974,7 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group, BIGNUM *tmp_scalar; if ((num + 1) == 0 || (num + 1) > OPENSSL_MALLOC_MAX_NELEMS(void *)) { - ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } @@ -979,7 +984,7 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group, if (scalar) { generator = EC_GROUP_get0_generator(group); if (generator == NULL) { - ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_UNDEFINED_GENERATOR); + ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR); goto err; } @@ -1027,7 +1032,7 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group, goto err; if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) { - ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } scalar = tmp_scalar; @@ -1119,13 +1124,13 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group, */ new_scalars = OPENSSL_malloc((num + 1) * sizeof(BIGNUM *)); if (new_scalars == NULL) { - ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } new_points = OPENSSL_malloc((num + 1) * sizeof(EC_POINT *)); if (new_points == NULL) { - ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -1180,14 +1185,14 @@ __owur static int ecp_nistz256_get_affine(const EC_GROUP *group, BN_ULONG x_ret[P256_LIMBS], y_ret[P256_LIMBS]; if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_ECP_NISTZ256_GET_AFFINE, EC_R_POINT_AT_INFINITY); + ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); return 0; } if (!ecp_nistz256_bignum_to_field_elem(point_x, point->X) || !ecp_nistz256_bignum_to_field_elem(point_y, point->Y) || !ecp_nistz256_bignum_to_field_elem(point_z, point->Z)) { - ECerr(EC_F_ECP_NISTZ256_GET_AFFINE, EC_R_COORDINATES_OUT_OF_RANGE); + ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); return 0; } @@ -1222,7 +1227,7 @@ static NISTZ256_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group) ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - ECerr(EC_F_ECP_NISTZ256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return ret; } @@ -1232,7 +1237,7 @@ static NISTZ256_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group) ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ECerr(EC_F_ECP_NISTZ256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } @@ -1255,7 +1260,7 @@ void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *pre) return; CRYPTO_DOWN_REF(&pre->references, &i, pre->lock); - REF_PRINT_COUNT("EC_nistz256", x); + REF_PRINT_COUNT("EC_nistz256", pre); if (i > 0) return; REF_ASSERT_ISNT(i < 0); @@ -1291,7 +1296,7 @@ void ecp_nistz256_ord_mul_mont(BN_ULONG res[P256_LIMBS], const BN_ULONG b[P256_LIMBS]); void ecp_nistz256_ord_sqr_mont(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS], - int rep); + BN_ULONG rep); static int ecp_nistz256_inv_mod_ord(const EC_GROUP *group, BIGNUM *r, const BIGNUM *x, BN_CTX *ctx) @@ -1321,7 +1326,7 @@ static int ecp_nistz256_inv_mod_ord(const EC_GROUP *group, BIGNUM *r, * Catch allocation failure early. */ if (bn_wexpand(r, P256_LIMBS) == NULL) { - ECerr(EC_F_ECP_NISTZ256_INV_MOD_ORD, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -1330,14 +1335,14 @@ static int ecp_nistz256_inv_mod_ord(const EC_GROUP *group, BIGNUM *r, if ((tmp = BN_CTX_get(ctx)) == NULL || !BN_nnmod(tmp, x, group->order, ctx)) { - ECerr(EC_F_ECP_NISTZ256_INV_MOD_ORD, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } x = tmp; } if (!ecp_nistz256_bignum_to_field_elem(t, x)) { - ECerr(EC_F_ECP_NISTZ256_INV_MOD_ORD, EC_R_COORDINATES_OUT_OF_RANGE); + ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); goto err; } @@ -1467,52 +1472,53 @@ const EC_METHOD *EC_GFp_nistz256_method(void) static const EC_METHOD ret = { EC_FLAGS_DEFAULT_OCT, NID_X9_62_prime_field, - ec_GFp_mont_group_init, - ec_GFp_mont_group_finish, - ec_GFp_mont_group_clear_finish, - ec_GFp_mont_group_copy, - ec_GFp_mont_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_group_simple_order_bits, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, + ossl_ec_GFp_mont_group_init, + ossl_ec_GFp_mont_group_finish, + ossl_ec_GFp_mont_group_clear_finish, + ossl_ec_GFp_mont_group_copy, + ossl_ec_GFp_mont_group_set_curve, + ossl_ec_GFp_simple_group_get_curve, + ossl_ec_GFp_simple_group_get_degree, + ossl_ec_group_simple_order_bits, + ossl_ec_GFp_simple_group_check_discriminant, + ossl_ec_GFp_simple_point_init, + ossl_ec_GFp_simple_point_finish, + ossl_ec_GFp_simple_point_clear_finish, + ossl_ec_GFp_simple_point_copy, + ossl_ec_GFp_simple_point_set_to_infinity, + ossl_ec_GFp_simple_point_set_affine_coordinates, ecp_nistz256_get_affine, 0, 0, 0, - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, + ossl_ec_GFp_simple_add, + ossl_ec_GFp_simple_dbl, + ossl_ec_GFp_simple_invert, + ossl_ec_GFp_simple_is_at_infinity, + ossl_ec_GFp_simple_is_on_curve, + ossl_ec_GFp_simple_cmp, + ossl_ec_GFp_simple_make_affine, + ossl_ec_GFp_simple_points_make_affine, ecp_nistz256_points_mul, /* mul */ ecp_nistz256_mult_precompute, /* precompute_mult */ ecp_nistz256_window_have_precompute_mult, /* have_precompute_mult */ - ec_GFp_mont_field_mul, - ec_GFp_mont_field_sqr, + ossl_ec_GFp_mont_field_mul, + ossl_ec_GFp_mont_field_sqr, 0, /* field_div */ - ec_GFp_mont_field_inv, - ec_GFp_mont_field_encode, - ec_GFp_mont_field_decode, - ec_GFp_mont_field_set_to_one, - ec_key_simple_priv2oct, - ec_key_simple_oct2priv, + ossl_ec_GFp_mont_field_inv, + ossl_ec_GFp_mont_field_encode, + ossl_ec_GFp_mont_field_decode, + ossl_ec_GFp_mont_field_set_to_one, + ossl_ec_key_simple_priv2oct, + ossl_ec_key_simple_oct2priv, 0, /* set private */ - ec_key_simple_generate_key, - ec_key_simple_check_key, - ec_key_simple_generate_public_key, + ossl_ec_key_simple_generate_key, + ossl_ec_key_simple_check_key, + ossl_ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key, + ossl_ecdh_simple_compute_key, + ossl_ecdsa_simple_sign_setup, + ossl_ecdsa_simple_sign_sig, + ossl_ecdsa_simple_verify_sig, ecp_nistz256_inv_mod_ord, /* can be #define-d NULL */ 0, /* blind_coordinates */ 0, /* ladder_pre */ diff --git a/crypto/openssl/crypto/ec/ecp_nistz256_table.c b/crypto/openssl/crypto/ec/ecp_nistz256_table.c index 3f5625c6c5eb..71430d4b8142 100644 --- a/crypto/openssl/crypto/ec/ecp_nistz256_table.c +++ b/crypto/openssl/crypto/ec/ecp_nistz256_table.c @@ -1,7 +1,7 @@ /* * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ec/ecp_oct.c b/crypto/openssl/crypto/ec/ecp_oct.c index 9460763256fd..68943e521e8a 100644 --- a/crypto/openssl/crypto/ec/ecp_oct.c +++ b/crypto/openssl/crypto/ec/ecp_oct.c @@ -1,32 +1,35 @@ /* - * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2021 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 + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include "ec_local.h" -int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, - EC_POINT *point, - const BIGNUM *x_, int y_bit, - BN_CTX *ctx) +int ossl_ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x_, int y_bit, + BN_CTX *ctx) { BN_CTX *new_ctx = NULL; BIGNUM *tmp1, *tmp2, *x, *y; int ret = 0; - /* clear error queue */ - ERR_clear_error(); - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -98,19 +101,24 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, goto err; } + ERR_set_mark(); if (!BN_mod_sqrt(y, tmp1, group->field, ctx)) { +#ifndef FIPS_MODULE unsigned long err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { - ERR_clear_error(); - ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, - EC_R_INVALID_COMPRESSED_POINT); + ERR_pop_to_mark(); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT); } else - ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, - ERR_R_BN_LIB); +#endif + { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + } goto err; } + ERR_clear_last_mark(); if (y_bit != BN_is_odd(y)) { if (BN_is_zero(y)) { @@ -121,22 +129,19 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, goto err; if (kron == 1) - ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, - EC_R_INVALID_COMPRESSION_BIT); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_COMPRESSION_BIT); else /* * BN_mod_sqrt() should have caught this error (not a square) */ - ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, - EC_R_INVALID_COMPRESSED_POINT); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT); goto err; } if (!BN_usub(y, group->field, y)) goto err; } if (y_bit != BN_is_odd(y)) { - ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, - ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } @@ -151,9 +156,9 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, return ret; } -size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, - point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *ctx) +size_t ossl_ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx) { size_t ret; BN_CTX *new_ctx = NULL; @@ -164,7 +169,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, if ((form != POINT_CONVERSION_COMPRESSED) && (form != POINT_CONVERSION_UNCOMPRESSED) && (form != POINT_CONVERSION_HYBRID)) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM); goto err; } @@ -172,7 +177,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, /* encodes to a single 0 octet */ if (buf != NULL) { if (len < 1) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); return 0; } buf[0] = 0; @@ -189,12 +194,12 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, /* if 'buf' is NULL, just return required length */ if (buf != NULL) { if (len < ret) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); goto err; } if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -219,7 +224,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, skip = field_len - BN_num_bytes(x); if (skip > field_len) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } while (skip > 0) { @@ -229,7 +234,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, skip = BN_bn2bin(x, buf + i); i += skip; if (i != 1 + field_len) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } @@ -237,7 +242,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, || form == POINT_CONVERSION_HYBRID) { skip = field_len - BN_num_bytes(y); if (skip > field_len) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } while (skip > 0) { @@ -249,7 +254,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, } if (i != ret) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } } @@ -266,8 +271,9 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, return 0; } -int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, - const unsigned char *buf, size_t len, BN_CTX *ctx) +int ossl_ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, + const unsigned char *buf, size_t len, + BN_CTX *ctx) { point_conversion_form_t form; int y_bit; @@ -277,7 +283,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, int ret = 0; if (len == 0) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); return 0; } form = buf[0]; @@ -286,17 +292,17 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) && (form != POINT_CONVERSION_UNCOMPRESSED) && (form != POINT_CONVERSION_HYBRID)) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); return 0; } if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); return 0; } if (form == 0) { if (len != 1) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); return 0; } @@ -309,12 +315,12 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; if (len != enc_len) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); return 0; } if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -328,7 +334,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, if (!BN_bin2bn(buf + 1, field_len, x)) goto err; if (BN_ucmp(x, group->field) >= 0) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); goto err; } @@ -339,12 +345,12 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err; if (BN_ucmp(y, group->field) >= 0) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); goto err; } if (form == POINT_CONVERSION_HYBRID) { if (y_bit != BN_is_odd(y)) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); goto err; } } diff --git a/crypto/openssl/crypto/ec/ecp_ppc.c b/crypto/openssl/crypto/ec/ecp_ppc.c new file mode 100644 index 000000000000..b2b9f772b87b --- /dev/null +++ b/crypto/openssl/crypto/ec/ecp_ppc.c @@ -0,0 +1,34 @@ +/* + * Copyright 2009-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/cryptlib.h" +#include "crypto/ppc_arch.h" +#include "ec_local.h" + +void ecp_nistz256_mul_mont(unsigned long res[4], const unsigned long a[4], + const unsigned long b[4]); + +void ecp_nistz256_to_mont(unsigned long res[4], const unsigned long in[4]); +void ecp_nistz256_to_mont(unsigned long res[4], const unsigned long in[4]) +{ + static const unsigned long RR[] = { 0x0000000000000003U, + 0xfffffffbffffffffU, + 0xfffffffffffffffeU, + 0x00000004fffffffdU }; + + ecp_nistz256_mul_mont(res, in, RR); +} + +void ecp_nistz256_from_mont(unsigned long res[4], const unsigned long in[4]); +void ecp_nistz256_from_mont(unsigned long res[4], const unsigned long in[4]) +{ + static const unsigned long one[] = { 1, 0, 0, 0 }; + + ecp_nistz256_mul_mont(res, in, one); +} diff --git a/crypto/openssl/crypto/ec/ecp_s390x_nistp.c b/crypto/openssl/crypto/ec/ecp_s390x_nistp.c new file mode 100644 index 000000000000..0c10196ea34e --- /dev/null +++ b/crypto/openssl/crypto/ec/ecp_s390x_nistp.c @@ -0,0 +1,400 @@ +/* + * Copyright 2019-2022 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 + */ + +/* + * EC_METHOD low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include "ec_local.h" +#include "s390x_arch.h" + +/* Size of parameter blocks */ +#define S390X_SIZE_PARAM 4096 + +/* Size of fields in parameter blocks */ +#define S390X_SIZE_P256 32 +#define S390X_SIZE_P384 48 +#define S390X_SIZE_P521 80 + +/* Offsets of fields in PCC parameter blocks */ +#define S390X_OFF_RES_X(n) (0 * n) +#define S390X_OFF_RES_Y(n) (1 * n) +#define S390X_OFF_SRC_X(n) (2 * n) +#define S390X_OFF_SRC_Y(n) (3 * n) +#define S390X_OFF_SCALAR(n) (4 * n) + +/* Offsets of fields in KDSA parameter blocks */ +#define S390X_OFF_R(n) (0 * n) +#define S390X_OFF_S(n) (1 * n) +#define S390X_OFF_H(n) (2 * n) +#define S390X_OFF_K(n) (3 * n) +#define S390X_OFF_X(n) (3 * n) +#define S390X_OFF_RN(n) (4 * n) +#define S390X_OFF_Y(n) (4 * n) + +static int ec_GFp_s390x_nistp_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, + size_t num, const EC_POINT *points[], + const BIGNUM *scalars[], + BN_CTX *ctx, unsigned int fc, int len) +{ + unsigned char param[S390X_SIZE_PARAM]; + BIGNUM *x, *y; + const EC_POINT *point_ptr = NULL; + const BIGNUM *scalar_ptr = NULL; + BN_CTX *new_ctx = NULL; + int rc = -1; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new_ex(group->libctx); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (x == NULL || y == NULL) { + rc = 0; + goto ret; + } + + /* + * Use PCC for EC keygen and ECDH key derivation: + * scalar * generator and scalar * peer public key, + * scalar in [0,order). + */ + if ((scalar != NULL && num == 0 && BN_is_negative(scalar) == 0) + || (scalar == NULL && num == 1 && BN_is_negative(scalars[0]) == 0)) { + + if (num == 0) { + point_ptr = EC_GROUP_get0_generator(group); + scalar_ptr = scalar; + } else { + point_ptr = points[0]; + scalar_ptr = scalars[0]; + } + + if (EC_POINT_is_at_infinity(group, point_ptr) == 1 + || BN_is_zero(scalar_ptr)) { + rc = EC_POINT_set_to_infinity(group, r); + goto ret; + } + + memset(¶m, 0, sizeof(param)); + + if (group->meth->point_get_affine_coordinates(group, point_ptr, + x, y, ctx) != 1 + || BN_bn2binpad(x, param + S390X_OFF_SRC_X(len), len) == -1 + || BN_bn2binpad(y, param + S390X_OFF_SRC_Y(len), len) == -1 + || BN_bn2binpad(scalar_ptr, + param + S390X_OFF_SCALAR(len), len) == -1 + || s390x_pcc(fc, param) != 0 + || BN_bin2bn(param + S390X_OFF_RES_X(len), len, x) == NULL + || BN_bin2bn(param + S390X_OFF_RES_Y(len), len, y) == NULL + || group->meth->point_set_affine_coordinates(group, r, + x, y, ctx) != 1) + goto ret; + + rc = 1; + } + +ret: + /* Otherwise use default. */ + if (rc == -1) + rc = ossl_ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); + OPENSSL_cleanse(param, sizeof(param)); + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + return rc; +} + +static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst, + int dgstlen, + const BIGNUM *kinv, + const BIGNUM *r, + EC_KEY *eckey, + unsigned int fc, int len) +{ + unsigned char param[S390X_SIZE_PARAM]; + int ok = 0; + BIGNUM *k; + ECDSA_SIG *sig; + const EC_GROUP *group; + const BIGNUM *privkey; + int off; + + group = EC_KEY_get0_group(eckey); + privkey = EC_KEY_get0_private_key(eckey); + if (group == NULL || privkey == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS); + return NULL; + } + + if (!EC_KEY_can_sign(eckey)) { + ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); + return NULL; + } + + k = BN_secure_new(); + sig = ECDSA_SIG_new(); + if (k == NULL || sig == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto ret; + } + + sig->r = BN_new(); + sig->s = BN_new(); + if (sig->r == NULL || sig->s == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto ret; + } + + memset(param, 0, sizeof(param)); + off = len - (dgstlen > len ? len : dgstlen); + memcpy(param + S390X_OFF_H(len) + off, dgst, len - off); + + if (BN_bn2binpad(privkey, param + S390X_OFF_K(len), len) == -1) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + goto ret; + } + + if (r == NULL || kinv == NULL) { + if (len < 0) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_LENGTH); + goto ret; + } + /* + * Generate random k and copy to param param block. RAND_priv_bytes_ex + * is used instead of BN_priv_rand_range or BN_generate_dsa_nonce + * because kdsa instruction constructs an in-range, invertible nonce + * internally implementing counter-measures for RNG weakness. + */ + if (RAND_priv_bytes_ex(eckey->libctx, param + S390X_OFF_RN(len), + (size_t)len, 0) != 1) { + ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED); + goto ret; + } + } else { + /* Reconstruct k = (k^-1)^-1. */ + if (ossl_ec_group_do_inverse_ord(group, k, kinv, NULL) == 0 + || BN_bn2binpad(k, param + S390X_OFF_RN(len), len) == -1) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + goto ret; + } + /* Turns KDSA internal nonce-generation off. */ + fc |= S390X_KDSA_D; + } + + if (s390x_kdsa(fc, param, NULL, 0) != 0) { + ERR_raise(ERR_LIB_EC, ERR_R_ECDSA_LIB); + goto ret; + } + + if (BN_bin2bn(param + S390X_OFF_R(len), len, sig->r) == NULL + || BN_bin2bn(param + S390X_OFF_S(len), len, sig->s) == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + goto ret; + } + + ok = 1; +ret: + OPENSSL_cleanse(param, sizeof(param)); + if (ok != 1) { + ECDSA_SIG_free(sig); + sig = NULL; + } + BN_clear_free(k); + return sig; +} + +static int ecdsa_s390x_nistp_verify_sig(const unsigned char *dgst, int dgstlen, + const ECDSA_SIG *sig, EC_KEY *eckey, + unsigned int fc, int len) +{ + unsigned char param[S390X_SIZE_PARAM]; + int rc = -1; + BN_CTX *ctx; + BIGNUM *x, *y; + const EC_GROUP *group; + const EC_POINT *pubkey; + int off; + + group = EC_KEY_get0_group(eckey); + pubkey = EC_KEY_get0_public_key(eckey); + if (eckey == NULL || group == NULL || pubkey == NULL || sig == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS); + return -1; + } + + if (!EC_KEY_can_sign(eckey)) { + ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); + return -1; + } + + ctx = BN_CTX_new_ex(group->libctx); + if (ctx == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + return -1; + } + + BN_CTX_start(ctx); + + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (x == NULL || y == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto ret; + } + + memset(param, 0, sizeof(param)); + off = len - (dgstlen > len ? len : dgstlen); + memcpy(param + S390X_OFF_H(len) + off, dgst, len - off); + + if (group->meth->point_get_affine_coordinates(group, pubkey, + x, y, ctx) != 1 + || BN_bn2binpad(sig->r, param + S390X_OFF_R(len), len) == -1 + || BN_bn2binpad(sig->s, param + S390X_OFF_S(len), len) == -1 + || BN_bn2binpad(x, param + S390X_OFF_X(len), len) == -1 + || BN_bn2binpad(y, param + S390X_OFF_Y(len), len) == -1) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + goto ret; + } + + rc = s390x_kdsa(fc, param, NULL, 0) == 0 ? 1 : 0; +ret: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return rc; +} + +#define EC_GFP_S390X_NISTP_METHOD(bits) \ + \ +static int ec_GFp_s390x_nistp##bits##_mul(const EC_GROUP *group, \ + EC_POINT *r, \ + const BIGNUM *scalar, \ + size_t num, \ + const EC_POINT *points[], \ + const BIGNUM *scalars[], \ + BN_CTX *ctx) \ +{ \ + return ec_GFp_s390x_nistp_mul(group, r, scalar, num, points, \ + scalars, ctx, \ + S390X_SCALAR_MULTIPLY_P##bits, \ + S390X_SIZE_P##bits); \ +} \ + \ +static ECDSA_SIG *ecdsa_s390x_nistp##bits##_sign_sig(const unsigned \ + char *dgst, \ + int dgstlen, \ + const BIGNUM *kinv,\ + const BIGNUM *r, \ + EC_KEY *eckey) \ +{ \ + return ecdsa_s390x_nistp_sign_sig(dgst, dgstlen, kinv, r, eckey, \ + S390X_ECDSA_SIGN_P##bits, \ + S390X_SIZE_P##bits); \ +} \ + \ +static int ecdsa_s390x_nistp##bits##_verify_sig(const \ + unsigned char *dgst, \ + int dgstlen, \ + const ECDSA_SIG *sig, \ + EC_KEY *eckey) \ +{ \ + return ecdsa_s390x_nistp_verify_sig(dgst, dgstlen, sig, eckey, \ + S390X_ECDSA_VERIFY_P##bits, \ + S390X_SIZE_P##bits); \ +} \ + \ +const EC_METHOD *EC_GFp_s390x_nistp##bits##_method(void) \ +{ \ + static const EC_METHOD EC_GFp_s390x_nistp##bits##_meth = { \ + EC_FLAGS_DEFAULT_OCT, \ + NID_X9_62_prime_field, \ + ossl_ec_GFp_simple_group_init, \ + ossl_ec_GFp_simple_group_finish, \ + ossl_ec_GFp_simple_group_clear_finish, \ + ossl_ec_GFp_simple_group_copy, \ + ossl_ec_GFp_simple_group_set_curve, \ + ossl_ec_GFp_simple_group_get_curve, \ + ossl_ec_GFp_simple_group_get_degree, \ + ossl_ec_group_simple_order_bits, \ + ossl_ec_GFp_simple_group_check_discriminant, \ + ossl_ec_GFp_simple_point_init, \ + ossl_ec_GFp_simple_point_finish, \ + ossl_ec_GFp_simple_point_clear_finish, \ + ossl_ec_GFp_simple_point_copy, \ + ossl_ec_GFp_simple_point_set_to_infinity, \ + ossl_ec_GFp_simple_point_set_affine_coordinates, \ + ossl_ec_GFp_simple_point_get_affine_coordinates, \ + NULL, /* point_set_compressed_coordinates */ \ + NULL, /* point2oct */ \ + NULL, /* oct2point */ \ + ossl_ec_GFp_simple_add, \ + ossl_ec_GFp_simple_dbl, \ + ossl_ec_GFp_simple_invert, \ + ossl_ec_GFp_simple_is_at_infinity, \ + ossl_ec_GFp_simple_is_on_curve, \ + ossl_ec_GFp_simple_cmp, \ + ossl_ec_GFp_simple_make_affine, \ + ossl_ec_GFp_simple_points_make_affine, \ + ec_GFp_s390x_nistp##bits##_mul, \ + NULL, /* precompute_mult */ \ + NULL, /* have_precompute_mult */ \ + ossl_ec_GFp_simple_field_mul, \ + ossl_ec_GFp_simple_field_sqr, \ + NULL, /* field_div */ \ + ossl_ec_GFp_simple_field_inv, \ + NULL, /* field_encode */ \ + NULL, /* field_decode */ \ + NULL, /* field_set_to_one */ \ + ossl_ec_key_simple_priv2oct, \ + ossl_ec_key_simple_oct2priv, \ + NULL, /* set_private */ \ + ossl_ec_key_simple_generate_key, \ + ossl_ec_key_simple_check_key, \ + ossl_ec_key_simple_generate_public_key, \ + NULL, /* keycopy */ \ + NULL, /* keyfinish */ \ + ossl_ecdh_simple_compute_key, \ + ossl_ecdsa_simple_sign_setup, \ + ecdsa_s390x_nistp##bits##_sign_sig, \ + ecdsa_s390x_nistp##bits##_verify_sig, \ + NULL, /* field_inverse_mod_ord */ \ + ossl_ec_GFp_simple_blind_coordinates, \ + ossl_ec_GFp_simple_ladder_pre, \ + ossl_ec_GFp_simple_ladder_step, \ + ossl_ec_GFp_simple_ladder_post \ + }; \ + static const EC_METHOD *ret; \ + \ + if ((OPENSSL_s390xcap_P.pcc[1] \ + & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P##bits)) \ + && (OPENSSL_s390xcap_P.kdsa[0] \ + & S390X_CAPBIT(S390X_ECDSA_VERIFY_P##bits)) \ + && (OPENSSL_s390xcap_P.kdsa[0] \ + & S390X_CAPBIT(S390X_ECDSA_SIGN_P##bits))) \ + ret = &EC_GFp_s390x_nistp##bits##_meth; \ + else \ + ret = EC_GFp_mont_method(); \ + \ + return ret; \ +} + +EC_GFP_S390X_NISTP_METHOD(256) +EC_GFP_S390X_NISTP_METHOD(384) +EC_GFP_S390X_NISTP_METHOD(521) diff --git a/crypto/openssl/crypto/ec/ecp_smpl.c b/crypto/openssl/crypto/ec/ecp_smpl.c index b3110ec89dbe..bde8cad34641 100644 --- a/crypto/openssl/crypto/ec/ecp_smpl.c +++ b/crypto/openssl/crypto/ec/ecp_smpl.c @@ -1,13 +1,19 @@ /* - * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 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 + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include @@ -18,57 +24,58 @@ const EC_METHOD *EC_GFp_simple_method(void) static const EC_METHOD ret = { EC_FLAGS_DEFAULT_OCT, NID_X9_62_prime_field, - ec_GFp_simple_group_init, - ec_GFp_simple_group_finish, - ec_GFp_simple_group_clear_finish, - ec_GFp_simple_group_copy, - ec_GFp_simple_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_group_simple_order_bits, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_simple_point_get_affine_coordinates, + ossl_ec_GFp_simple_group_init, + ossl_ec_GFp_simple_group_finish, + ossl_ec_GFp_simple_group_clear_finish, + ossl_ec_GFp_simple_group_copy, + ossl_ec_GFp_simple_group_set_curve, + ossl_ec_GFp_simple_group_get_curve, + ossl_ec_GFp_simple_group_get_degree, + ossl_ec_group_simple_order_bits, + ossl_ec_GFp_simple_group_check_discriminant, + ossl_ec_GFp_simple_point_init, + ossl_ec_GFp_simple_point_finish, + ossl_ec_GFp_simple_point_clear_finish, + ossl_ec_GFp_simple_point_copy, + ossl_ec_GFp_simple_point_set_to_infinity, + ossl_ec_GFp_simple_point_set_affine_coordinates, + ossl_ec_GFp_simple_point_get_affine_coordinates, 0, 0, 0, - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, + ossl_ec_GFp_simple_add, + ossl_ec_GFp_simple_dbl, + ossl_ec_GFp_simple_invert, + ossl_ec_GFp_simple_is_at_infinity, + ossl_ec_GFp_simple_is_on_curve, + ossl_ec_GFp_simple_cmp, + ossl_ec_GFp_simple_make_affine, + ossl_ec_GFp_simple_points_make_affine, 0 /* mul */ , 0 /* precompute_mult */ , 0 /* have_precompute_mult */ , - ec_GFp_simple_field_mul, - ec_GFp_simple_field_sqr, + ossl_ec_GFp_simple_field_mul, + ossl_ec_GFp_simple_field_sqr, 0 /* field_div */ , - ec_GFp_simple_field_inv, + ossl_ec_GFp_simple_field_inv, 0 /* field_encode */ , 0 /* field_decode */ , 0, /* field_set_to_one */ - ec_key_simple_priv2oct, - ec_key_simple_oct2priv, + ossl_ec_key_simple_priv2oct, + ossl_ec_key_simple_oct2priv, 0, /* set private */ - ec_key_simple_generate_key, - ec_key_simple_check_key, - ec_key_simple_generate_public_key, + ossl_ec_key_simple_generate_key, + ossl_ec_key_simple_check_key, + ossl_ec_key_simple_generate_public_key, 0, /* keycopy */ 0, /* keyfinish */ - ecdh_simple_compute_key, + ossl_ecdh_simple_compute_key, + ossl_ecdsa_simple_sign_setup, + ossl_ecdsa_simple_sign_sig, + ossl_ecdsa_simple_verify_sig, 0, /* field_inverse_mod_ord */ - ec_GFp_simple_blind_coordinates, - ec_GFp_simple_ladder_pre, - ec_GFp_simple_ladder_step, - ec_GFp_simple_ladder_post + ossl_ec_GFp_simple_blind_coordinates, + ossl_ec_GFp_simple_ladder_pre, + ossl_ec_GFp_simple_ladder_step, + ossl_ec_GFp_simple_ladder_post }; return &ret; @@ -88,7 +95,7 @@ const EC_METHOD *EC_GFp_simple_method(void) * representation (i.e. 'encoding' means multiplying by some factor R). */ -int ec_GFp_simple_group_init(EC_GROUP *group) +int ossl_ec_GFp_simple_group_init(EC_GROUP *group) { group->field = BN_new(); group->a = BN_new(); @@ -103,21 +110,21 @@ int ec_GFp_simple_group_init(EC_GROUP *group) return 1; } -void ec_GFp_simple_group_finish(EC_GROUP *group) +void ossl_ec_GFp_simple_group_finish(EC_GROUP *group) { BN_free(group->field); BN_free(group->a); BN_free(group->b); } -void ec_GFp_simple_group_clear_finish(EC_GROUP *group) +void ossl_ec_GFp_simple_group_clear_finish(EC_GROUP *group) { BN_clear_free(group->field); BN_clear_free(group->a); BN_clear_free(group->b); } -int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) +int ossl_ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) { if (!BN_copy(dest->field, src->field)) return 0; @@ -131,9 +138,9 @@ int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) return 1; } -int ec_GFp_simple_group_set_curve(EC_GROUP *group, - const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) +int ossl_ec_GFp_simple_group_set_curve(EC_GROUP *group, + const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) { int ret = 0; BN_CTX *new_ctx = NULL; @@ -141,12 +148,12 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, /* p must be a prime > 3 */ if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { - ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); return 0; } if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -190,8 +197,8 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, return ret; } -int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, - BIGNUM *b, BN_CTX *ctx) +int ossl_ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, + BIGNUM *a, BIGNUM *b, BN_CTX *ctx) { int ret = 0; BN_CTX *new_ctx = NULL; @@ -204,7 +211,7 @@ int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, if (a != NULL || b != NULL) { if (group->meth->field_decode) { if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -235,12 +242,13 @@ int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, return ret; } -int ec_GFp_simple_group_get_degree(const EC_GROUP *group) +int ossl_ec_GFp_simple_group_get_degree(const EC_GROUP *group) { return BN_num_bits(group->field); } -int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) +int ossl_ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, + BN_CTX *ctx) { int ret = 0; BIGNUM *a, *b, *order, *tmp_1, *tmp_2; @@ -248,10 +256,9 @@ int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) BN_CTX *new_ctx = NULL; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) { - ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } } @@ -312,7 +319,7 @@ int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) return ret; } -int ec_GFp_simple_point_init(EC_POINT *point) +int ossl_ec_GFp_simple_point_init(EC_POINT *point) { point->X = BN_new(); point->Y = BN_new(); @@ -328,14 +335,14 @@ int ec_GFp_simple_point_init(EC_POINT *point) return 1; } -void ec_GFp_simple_point_finish(EC_POINT *point) +void ossl_ec_GFp_simple_point_finish(EC_POINT *point) { BN_free(point->X); BN_free(point->Y); BN_free(point->Z); } -void ec_GFp_simple_point_clear_finish(EC_POINT *point) +void ossl_ec_GFp_simple_point_clear_finish(EC_POINT *point) { BN_clear_free(point->X); BN_clear_free(point->Y); @@ -343,7 +350,7 @@ void ec_GFp_simple_point_clear_finish(EC_POINT *point) point->Z_is_one = 0; } -int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) +int ossl_ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) { if (!BN_copy(dest->X, src->X)) return 0; @@ -357,26 +364,26 @@ int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) return 1; } -int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, - EC_POINT *point) +int ossl_ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, + EC_POINT *point) { point->Z_is_one = 0; BN_zero(point->Z); return 1; } -int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, - EC_POINT *point, - const BIGNUM *x, - const BIGNUM *y, - const BIGNUM *z, - BN_CTX *ctx) +int ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, + const BIGNUM *z, + BN_CTX *ctx) { BN_CTX *new_ctx = NULL; int ret = 0; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -425,17 +432,17 @@ int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, return ret; } -int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BIGNUM *z, BN_CTX *ctx) +int ossl_ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BIGNUM *z, BN_CTX *ctx) { BN_CTX *new_ctx = NULL; int ret = 0; if (group->meth->field_decode != 0) { if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -474,17 +481,16 @@ int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, return ret; } -int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, - EC_POINT *point, - const BIGNUM *x, - const BIGNUM *y, BN_CTX *ctx) +int ossl_ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) { if (x == NULL || y == NULL) { /* * unlike for projective coordinates, we do not tolerate this */ - ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, - ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } @@ -492,10 +498,10 @@ int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, BN_value_one(), ctx); } -int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx) +int ossl_ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) { BN_CTX *new_ctx = NULL; BIGNUM *Z, *Z_1, *Z_2, *Z_3; @@ -503,13 +509,12 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, int ret = 0; if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, - EC_R_POINT_AT_INFINITY); + ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); return 0; } if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -554,8 +559,7 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, } } else { if (!group->meth->field_inv(group, Z_1, Z_, ctx)) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -606,8 +610,8 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, return ret; } -int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *ctx) +int ossl_ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) { int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); @@ -629,7 +633,7 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, p = group->field; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -791,8 +795,8 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, return ret; } -int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - BN_CTX *ctx) +int ossl_ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx) { int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); @@ -813,7 +817,7 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, p = group->field; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -933,7 +937,8 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, return ret; } -int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) +int ossl_ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, + BN_CTX *ctx) { if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y)) /* point is its own inverse */ @@ -942,13 +947,14 @@ int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) return BN_usub(point->Y, group->field, point->Y); } -int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) +int ossl_ec_GFp_simple_is_at_infinity(const EC_GROUP *group, + const EC_POINT *point) { return BN_is_zero(point->Z); } -int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, - BN_CTX *ctx) +int ossl_ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) { int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); @@ -966,7 +972,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, p = group->field; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return -1; } @@ -1050,8 +1056,8 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, return ret; } -int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, - const EC_POINT *b, BN_CTX *ctx) +int ossl_ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) { /*- * return values: @@ -1083,7 +1089,7 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, field_sqr = group->meth->field_sqr; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return -1; } @@ -1158,8 +1164,8 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, return ret; } -int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, - BN_CTX *ctx) +int ossl_ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, + BN_CTX *ctx) { BN_CTX *new_ctx = NULL; BIGNUM *x, *y; @@ -1169,7 +1175,7 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, return 1; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -1185,7 +1191,7 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx)) goto err; if (!point->Z_is_one) { - ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } @@ -1197,8 +1203,8 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, return ret; } -int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, - EC_POINT *points[], BN_CTX *ctx) +int ossl_ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx) { BN_CTX *new_ctx = NULL; BIGNUM *tmp, *tmp_Z; @@ -1210,7 +1216,7 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, return 1; if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); + ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) return 0; } @@ -1266,7 +1272,7 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, */ if (!group->meth->field_inv(group, tmp, prod_Z[num - 1], ctx)) { - ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } if (group->meth->field_encode != 0) { @@ -1356,14 +1362,14 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, return ret; } -int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) +int ossl_ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) { return BN_mod_mul(r, a, b, group->field, ctx); } -int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - BN_CTX *ctx) +int ossl_ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) { return BN_mod_sqr(r, a, group->field, ctx); } @@ -1374,14 +1380,15 @@ int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, * Since we don't have a Mont structure here, SCA hardening is with blinding. * NB: "a" must be in _decoded_ form. (i.e. field_decode must precede.) */ -int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - BN_CTX *ctx) +int ossl_ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) { BIGNUM *e = NULL; BN_CTX *new_ctx = NULL; int ret = 0; - if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) + if (ctx == NULL + && (ctx = new_ctx = BN_CTX_secure_new_ex(group->libctx)) == NULL) return 0; BN_CTX_start(ctx); @@ -1389,7 +1396,7 @@ int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, goto err; do { - if (!BN_priv_rand_range(e, group->field)) + if (!BN_priv_rand_range_ex(e, group->field, 0, ctx)) goto err; } while (BN_is_zero(e)); @@ -1398,7 +1405,7 @@ int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, goto err; /* r := 1/(a * e) */ if (!BN_mod_inverse(r, r, group->field, ctx)) { - ECerr(EC_F_EC_GFP_SIMPLE_FIELD_INV, EC_R_CANNOT_INVERT); + ERR_raise(ERR_LIB_EC, EC_R_CANNOT_INVERT); goto err; } /* r := e/(a * e) = 1/a */ @@ -1420,8 +1427,8 @@ int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, * lambda = [1,group->field) * */ -int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, - BN_CTX *ctx) +int ossl_ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, + BN_CTX *ctx) { int ret = 0; BIGNUM *lambda = NULL; @@ -1431,7 +1438,7 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, lambda = BN_CTX_get(ctx); temp = BN_CTX_get(ctx); if (temp == NULL) { - ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto end; } @@ -1442,7 +1449,7 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, */ do { ERR_set_mark(); - ret = BN_priv_rand_range(lambda, group->field); + ret = BN_priv_rand_range_ex(lambda, group->field, 0, ctx); ERR_pop_to_mark(); if (ret == 0) { ret = 1; @@ -1483,9 +1490,9 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, * Blinding uses the equivalence relation (\lambda X, \lambda Y, \lambda Z) * for any non-zero \lambda that holds for projective (homogeneous) coords. */ -int ec_GFp_simple_ladder_pre(const EC_GROUP *group, - EC_POINT *r, EC_POINT *s, - EC_POINT *p, BN_CTX *ctx) +int ossl_ec_GFp_simple_ladder_pre(const EC_GROUP *group, + EC_POINT *r, EC_POINT *s, + EC_POINT *p, BN_CTX *ctx) { BIGNUM *t1, *t2, *t3, *t4, *t5 = NULL; @@ -1512,13 +1519,13 @@ int ec_GFp_simple_ladder_pre(const EC_GROUP *group, /* make sure lambda (r->Y here for storage) is not zero */ do { - if (!BN_priv_rand_range(r->Y, group->field)) + if (!BN_priv_rand_range_ex(r->Y, group->field, 0, ctx)) return 0; } while (BN_is_zero(r->Y)); /* make sure lambda (s->Z here for storage) is not zero */ do { - if (!BN_priv_rand_range(s->Z, group->field)) + if (!BN_priv_rand_range_ex(s->Z, group->field, 0, ctx)) return 0; } while (BN_is_zero(s->Z)); @@ -1553,9 +1560,9 @@ int ec_GFp_simple_ladder_pre(const EC_GROUP *group, * attacks", as described at * https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-mladd-2002-it-4 */ -int ec_GFp_simple_ladder_step(const EC_GROUP *group, - EC_POINT *r, EC_POINT *s, - EC_POINT *p, BN_CTX *ctx) +int ossl_ec_GFp_simple_ladder_step(const EC_GROUP *group, + EC_POINT *r, EC_POINT *s, + EC_POINT *p, BN_CTX *ctx) { int ret = 0; BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL; @@ -1641,9 +1648,9 @@ int ec_GFp_simple_ladder_step(const EC_GROUP *group, * - Y1==0 implies p has order 2, so either r or s are infinity and handled by * one of the BN_is_zero(...) branches. */ -int ec_GFp_simple_ladder_post(const EC_GROUP *group, - EC_POINT *r, EC_POINT *s, - EC_POINT *p, BN_CTX *ctx) +int ossl_ec_GFp_simple_ladder_post(const EC_GROUP *group, + EC_POINT *r, EC_POINT *s, + EC_POINT *p, BN_CTX *ctx) { int ret = 0; BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL; diff --git a/crypto/openssl/crypto/ec/ecx_backend.c b/crypto/openssl/crypto/ec/ecx_backend.c new file mode 100644 index 000000000000..2ab7611be9af --- /dev/null +++ b/crypto/openssl/crypto/ec/ecx_backend.c @@ -0,0 +1,260 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#ifndef FIPS_MODULE +# include +#endif +#include "crypto/ecx.h" +#include "ecx_backend.h" + +/* + * The intention with the "backend" source file is to offer backend support + * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider + * implementations alike. + */ + +int ossl_ecx_public_from_private(ECX_KEY *key) +{ + switch (key->type) { + case ECX_KEY_TYPE_X25519: + ossl_x25519_public_from_private(key->pubkey, key->privkey); + break; + case ECX_KEY_TYPE_ED25519: + if (!ossl_ed25519_public_from_private(key->libctx, key->pubkey, + key->privkey, key->propq)) { + ERR_raise(ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY); + return 0; + } + break; + case ECX_KEY_TYPE_X448: + ossl_x448_public_from_private(key->pubkey, key->privkey); + break; + case ECX_KEY_TYPE_ED448: + if (!ossl_ed448_public_from_private(key->libctx, key->pubkey, + key->privkey, key->propq)) { + ERR_raise(ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY); + return 0; + } + break; + } + return 1; +} + +int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], + int include_private) +{ + size_t privkeylen = 0, pubkeylen = 0; + const OSSL_PARAM *param_priv_key = NULL, *param_pub_key; + unsigned char *pubkey; + + if (ecx == NULL) + return 0; + + param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); + if (include_private) + param_priv_key = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); + + if (param_pub_key == NULL && param_priv_key == NULL) + return 0; + + if (param_priv_key != NULL) { + if (!OSSL_PARAM_get_octet_string(param_priv_key, + (void **)&ecx->privkey, ecx->keylen, + &privkeylen)) + return 0; + if (privkeylen != ecx->keylen) { + /* + * Invalid key length. We will clear what we've received now. We + * can't leave it to ossl_ecx_key_free() because that will call + * OPENSSL_secure_clear_free() and assume the correct key length + */ + OPENSSL_secure_clear_free(ecx->privkey, privkeylen); + ecx->privkey = NULL; + return 0; + } + } + + + pubkey = ecx->pubkey; + if (param_pub_key != NULL + && !OSSL_PARAM_get_octet_string(param_pub_key, + (void **)&pubkey, + sizeof(ecx->pubkey), &pubkeylen)) + return 0; + + if ((param_pub_key != NULL && pubkeylen != ecx->keylen)) + return 0; + + if (param_pub_key == NULL && !ossl_ecx_public_from_private(ecx)) + return 0; + + ecx->haspubkey = 1; + + return 1; +} + +ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key, int selection) +{ + ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); + + if (ret == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) { + OPENSSL_free(ret); + return NULL; + } + + ret->libctx = key->libctx; + ret->haspubkey = key->haspubkey; + ret->keylen = key->keylen; + ret->type = key->type; + ret->references = 1; + + if (key->propq != NULL) { + ret->propq = OPENSSL_strdup(key->propq); + if (ret->propq == NULL) + goto err; + } + + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) + memcpy(ret->pubkey, key->pubkey, sizeof(ret->pubkey)); + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 + && key->privkey != NULL) { + if (ossl_ecx_key_allocate_privkey(ret) == NULL) + goto err; + memcpy(ret->privkey, key->privkey, ret->keylen); + } + + return ret; + +err: + ossl_ecx_key_free(ret); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + return NULL; +} + +#ifndef FIPS_MODULE +ECX_KEY *ossl_ecx_key_op(const X509_ALGOR *palg, + const unsigned char *p, int plen, + int id, ecx_key_op_t op, + OSSL_LIB_CTX *libctx, const char *propq) +{ + ECX_KEY *key = NULL; + unsigned char *privkey, *pubkey; + + if (op != KEY_OP_KEYGEN) { + if (palg != NULL) { + int ptype; + + /* Algorithm parameters must be absent */ + X509_ALGOR_get0(NULL, &ptype, NULL, palg); + if (ptype != V_ASN1_UNDEF) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); + return 0; + } + if (id == EVP_PKEY_NONE) + id = OBJ_obj2nid(palg->algorithm); + else if (id != OBJ_obj2nid(palg->algorithm)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); + return 0; + } + } + + if (p == NULL || id == EVP_PKEY_NONE || plen != KEYLENID(id)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); + return 0; + } + } + + key = ossl_ecx_key_new(libctx, KEYNID2TYPE(id), 1, propq); + if (key == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + return 0; + } + pubkey = key->pubkey; + + if (op == KEY_OP_PUBLIC) { + memcpy(pubkey, p, plen); + } else { + privkey = ossl_ecx_key_allocate_privkey(key); + if (privkey == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + if (op == KEY_OP_KEYGEN) { + if (id != EVP_PKEY_NONE) { + if (RAND_priv_bytes_ex(libctx, privkey, KEYLENID(id), 0) <= 0) + goto err; + if (id == EVP_PKEY_X25519) { + privkey[0] &= 248; + privkey[X25519_KEYLEN - 1] &= 127; + privkey[X25519_KEYLEN - 1] |= 64; + } else if (id == EVP_PKEY_X448) { + privkey[0] &= 252; + privkey[X448_KEYLEN - 1] |= 128; + } + } + } else { + memcpy(privkey, p, KEYLENID(id)); + } + if (!ossl_ecx_public_from_private(key)) { + ERR_raise(ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY); + goto err; + } + } + + return key; + err: + ossl_ecx_key_free(key); + return NULL; +} + +ECX_KEY *ossl_ecx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq) +{ + ECX_KEY *ecx = NULL; + const unsigned char *p; + int plen; + ASN1_OCTET_STRING *oct = NULL; + const X509_ALGOR *palg; + + if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8inf)) + return 0; + + oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen); + if (oct == NULL) { + p = NULL; + plen = 0; + } else { + p = ASN1_STRING_get0_data(oct); + plen = ASN1_STRING_length(oct); + } + + /* + * EVP_PKEY_NONE means that ecx_key_op() has to figure out the key type + * on its own. + */ + ecx = ossl_ecx_key_op(palg, p, plen, EVP_PKEY_NONE, KEY_OP_PRIVATE, + libctx, propq); + ASN1_OCTET_STRING_free(oct); + return ecx; +} +#endif diff --git a/crypto/openssl/crypto/ec/ecx_backend.h b/crypto/openssl/crypto/ec/ecx_backend.h new file mode 100644 index 000000000000..2c01294789b3 --- /dev/null +++ b/crypto/openssl/crypto/ec/ecx_backend.h @@ -0,0 +1,20 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#define ISX448(id) ((id) == EVP_PKEY_X448) +#define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519) +#define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \ + : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \ + : ED448_KEYLEN)) +#define KEYNID2TYPE(id) \ + (IS25519(id) ? ((id) == EVP_PKEY_X25519 ? ECX_KEY_TYPE_X25519 \ + : ECX_KEY_TYPE_ED25519) \ + : ((id) == EVP_PKEY_X448 ? ECX_KEY_TYPE_X448 \ + : ECX_KEY_TYPE_ED448)) +#define KEYLEN(p) KEYLENID((p)->ameth->pkey_id) diff --git a/crypto/openssl/crypto/ec/ecx_key.c b/crypto/openssl/crypto/ec/ecx_key.c new file mode 100644 index 000000000000..dcec26c2e9b3 --- /dev/null +++ b/crypto/openssl/crypto/ec/ecx_key.c @@ -0,0 +1,98 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/ecx.h" + +ECX_KEY *ossl_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, + const char *propq) +{ + ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); + + if (ret == NULL) + return NULL; + + ret->libctx = libctx; + ret->haspubkey = haspubkey; + switch (type) { + case ECX_KEY_TYPE_X25519: + ret->keylen = X25519_KEYLEN; + break; + case ECX_KEY_TYPE_X448: + ret->keylen = X448_KEYLEN; + break; + case ECX_KEY_TYPE_ED25519: + ret->keylen = ED25519_KEYLEN; + break; + case ECX_KEY_TYPE_ED448: + ret->keylen = ED448_KEYLEN; + break; + } + ret->type = type; + ret->references = 1; + + if (propq != NULL) { + ret->propq = OPENSSL_strdup(propq); + if (ret->propq == NULL) + goto err; + } + + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) + goto err; + return ret; +err: + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return NULL; +} + +void ossl_ecx_key_free(ECX_KEY *key) +{ + int i; + + if (key == NULL) + return; + + CRYPTO_DOWN_REF(&key->references, &i, key->lock); + REF_PRINT_COUNT("ECX_KEY", key); + if (i > 0) + return; + REF_ASSERT_ISNT(i < 0); + + OPENSSL_free(key->propq); + OPENSSL_secure_clear_free(key->privkey, key->keylen); + CRYPTO_THREAD_lock_free(key->lock); + OPENSSL_free(key); +} + +void ossl_ecx_key_set0_libctx(ECX_KEY *key, OSSL_LIB_CTX *libctx) +{ + key->libctx = libctx; +} + +int ossl_ecx_key_up_ref(ECX_KEY *key) +{ + int i; + + if (CRYPTO_UP_REF(&key->references, &i, key->lock) <= 0) + return 0; + + REF_PRINT_COUNT("ECX_KEY", key); + REF_ASSERT_ISNT(i < 2); + return ((i > 1) ? 1 : 0); +} + +unsigned char *ossl_ecx_key_allocate_privkey(ECX_KEY *key) +{ + key->privkey = OPENSSL_secure_zalloc(key->keylen); + + return key->privkey; +} diff --git a/crypto/openssl/crypto/ec/ecx_meth.c b/crypto/openssl/crypto/ec/ecx_meth.c index 9dc5259e4afc..4e32210bf436 100644 --- a/crypto/openssl/crypto/ec/ecx_meth.c +++ b/crypto/openssl/crypto/ec/ecx_meth.c @@ -1,126 +1,32 @@ /* - * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include -#include "internal/cryptlib.h" #include #include +#include +#include #include +#include "internal/cryptlib.h" +#include "internal/provider.h" #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/ecx.h" #include "ec_local.h" #include "curve448/curve448_local.h" - -#define X25519_BITS 253 -#define X25519_SECURITY_BITS 128 - -#define ED25519_SIGSIZE 64 - -#define X448_BITS 448 -#define ED448_BITS 456 -#define X448_SECURITY_BITS 224 - -#define ED448_SIGSIZE 114 - -#define ISX448(id) ((id) == EVP_PKEY_X448) -#define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519) -#define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \ - : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \ - : ED448_KEYLEN)) -#define KEYLEN(p) KEYLENID((p)->ameth->pkey_id) - - -typedef enum { - KEY_OP_PUBLIC, - KEY_OP_PRIVATE, - KEY_OP_KEYGEN -} ecx_key_op_t; - -/* Setup EVP_PKEY using public, private or generation */ -static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg, - const unsigned char *p, int plen, ecx_key_op_t op) -{ - ECX_KEY *key = NULL; - unsigned char *privkey, *pubkey; - - if (op != KEY_OP_KEYGEN) { - if (palg != NULL) { - int ptype; - - /* Algorithm parameters must be absent */ - X509_ALGOR_get0(NULL, &ptype, NULL, palg); - if (ptype != V_ASN1_UNDEF) { - ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING); - return 0; - } - } - - if (p == NULL || plen != KEYLENID(id)) { - ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING); - return 0; - } - } - - key = OPENSSL_zalloc(sizeof(*key)); - if (key == NULL) { - ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE); - return 0; - } - pubkey = key->pubkey; - - if (op == KEY_OP_PUBLIC) { - memcpy(pubkey, p, plen); - } else { - privkey = key->privkey = OPENSSL_secure_malloc(KEYLENID(id)); - if (privkey == NULL) { - ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE); - goto err; - } - if (op == KEY_OP_KEYGEN) { - if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0) { - OPENSSL_secure_free(privkey); - key->privkey = NULL; - goto err; - } - if (id == EVP_PKEY_X25519) { - privkey[0] &= 248; - privkey[X25519_KEYLEN - 1] &= 127; - privkey[X25519_KEYLEN - 1] |= 64; - } else if (id == EVP_PKEY_X448) { - privkey[0] &= 252; - privkey[X448_KEYLEN - 1] |= 128; - } - } else { - memcpy(privkey, p, KEYLENID(id)); - } - switch (id) { - case EVP_PKEY_X25519: - X25519_public_from_private(pubkey, privkey); - break; - case EVP_PKEY_ED25519: - ED25519_public_from_private(pubkey, privkey); - break; - case EVP_PKEY_X448: - X448_public_from_private(pubkey, privkey); - break; - case EVP_PKEY_ED448: - ED448_public_from_private(pubkey, privkey); - break; - } - } - - EVP_PKEY_assign(pkey, id, key); - return 1; - err: - OPENSSL_free(key); - return 0; -} +#include "ecx_backend.h" static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { @@ -128,35 +34,42 @@ static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) unsigned char *penc; if (ecxkey == NULL) { - ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); return 0; } penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey)); if (penc == NULL) { - ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) { OPENSSL_free(penc); - ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } return 1; } -static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +static int ecx_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) { const unsigned char *p; int pklen; X509_ALGOR *palg; + ECX_KEY *ecx; + int ret = 0; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) return 0; - return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen, - KEY_OP_PUBLIC); + ecx = ossl_ecx_key_op(palg, p, pklen, pkey->ameth->pkey_id, + KEY_OP_PUBLIC, NULL, NULL); + if (ecx != NULL) { + ret = 1; + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); + } + return ret; } static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) @@ -170,29 +83,18 @@ static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0; } -static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) +static int ecx_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8, + OSSL_LIB_CTX *libctx, const char *propq) { - const unsigned char *p; - int plen; - ASN1_OCTET_STRING *oct = NULL; - const X509_ALGOR *palg; - int rv; + int ret = 0; + ECX_KEY *ecx = ossl_ecx_key_from_pkcs8(p8, libctx, propq); - if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8)) - return 0; - - oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen); - if (oct == NULL) { - p = NULL; - plen = 0; - } else { - p = ASN1_STRING_get0_data(oct); - plen = ASN1_STRING_length(oct); + if (ecx != NULL) { + ret = 1; + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); } - rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE); - ASN1_STRING_clear_free(oct); - return rv; + return ret; } static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) @@ -203,7 +105,7 @@ static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) int penclen; if (ecxkey == NULL || ecxkey->privkey == NULL) { - ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY); return 0; } @@ -213,14 +115,14 @@ static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) penclen = i2d_ASN1_OCTET_STRING(&oct, &penc); if (penclen < 0) { - ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, V_ASN1_UNDEF, NULL, penc, penclen)) { OPENSSL_clear_free(penc, penclen); - ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } @@ -254,9 +156,7 @@ static int ecx_security_bits(const EVP_PKEY *pkey) static void ecx_free(EVP_PKEY *pkey) { - if (pkey->pkey.ecx != NULL) - OPENSSL_secure_clear_free(pkey->pkey.ecx->privkey, KEYLEN(pkey)); - OPENSSL_free(pkey->pkey.ecx); + ossl_ecx_key_free(pkey->pkey.ecx); } /* "parameters" are always equal */ @@ -318,10 +218,16 @@ static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { - case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: - return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1, - KEY_OP_PUBLIC); + case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: { + ECX_KEY *ecx = ossl_ecx_key_op(NULL, arg2, arg1, pkey->ameth->pkey_id, + KEY_OP_PUBLIC, NULL, NULL); + if (ecx != NULL) { + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); + return 1; + } + return 0; + } case ASN1_PKEY_CTRL_GET1_TLS_ENCPT: if (pkey->pkey.ecx != NULL) { unsigned char **ppt = arg2; @@ -355,14 +261,38 @@ static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, size_t len) { - return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len, - KEY_OP_PRIVATE); + OSSL_LIB_CTX *libctx = NULL; + ECX_KEY *ecx = NULL; + + if (pkey->keymgmt != NULL) + libctx = ossl_provider_libctx(EVP_KEYMGMT_get0_provider(pkey->keymgmt)); + + ecx = ossl_ecx_key_op(NULL, priv, len, pkey->ameth->pkey_id, + KEY_OP_PRIVATE, libctx, NULL); + + if (ecx != NULL) { + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); + return 1; + } + return 0; } static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len) { - return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len, - KEY_OP_PUBLIC); + OSSL_LIB_CTX *libctx = NULL; + ECX_KEY *ecx = NULL; + + if (pkey->keymgmt != NULL) + libctx = ossl_provider_libctx(EVP_KEYMGMT_get0_provider(pkey->keymgmt)); + + ecx = ossl_ecx_key_op(NULL, pub, len, pkey->ameth->pkey_id, + KEY_OP_PUBLIC, libctx, NULL); + + if (ecx != NULL) { + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); + return 1; + } + return 0; } static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, @@ -406,7 +336,97 @@ static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub, return 1; } -const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = { +static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey) +{ + /* + * We provide no mechanism to "update" an ECX key once it has been set, + * therefore we do not have to maintain a dirty count. + */ + return 1; +} + +static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata, + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const ECX_KEY *key = from->pkey.ecx; + OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new(); + OSSL_PARAM *params = NULL; + int selection = 0; + int rv = 0; + + if (tmpl == NULL) + return 0; + + /* A key must at least have a public part */ + if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY, + key->pubkey, key->keylen)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + + if (key->privkey != NULL) { + if (!OSSL_PARAM_BLD_push_octet_string(tmpl, + OSSL_PKEY_PARAM_PRIV_KEY, + key->privkey, key->keylen)) + goto err; + selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY; + } + + params = OSSL_PARAM_BLD_to_param(tmpl); + + /* We export, the provider imports */ + rv = importer(to_keydata, selection, params); + + err: + OSSL_PARAM_BLD_free(tmpl); + OSSL_PARAM_free(params); + return rv; +} + +static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx, + int keytype) +{ + EVP_PKEY_CTX *pctx = vpctx; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); + ECX_KEY *ecx = ossl_ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0, + pctx->propquery); + + if (ecx == NULL) { + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!ossl_ecx_key_fromdata(ecx, params, 1) + || !EVP_PKEY_assign(pkey, keytype, ecx)) { + ossl_ecx_key_free(ecx); + return 0; + } + return 1; +} + +static int ecx_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) +{ + ECX_KEY *ecx = from->pkey.ecx, *dupkey = NULL; + int ret; + + if (ecx != NULL) { + dupkey = ossl_ecx_key_dup(ecx, OSSL_KEYMGMT_SELECT_ALL); + if (dupkey == NULL) + return 0; + } + + ret = EVP_PKEY_assign(to, from->type, dupkey); + if (!ret) + ossl_ecx_key_free(dupkey); + return ret; +} + +static int x25519_import_from(const OSSL_PARAM params[], void *vpctx) +{ + return ecx_generic_import_from(params, vpctx, EVP_PKEY_X25519); +} + +const EVP_PKEY_ASN1_METHOD ossl_ecx25519_asn1_meth = { EVP_PKEY_X25519, EVP_PKEY_X25519, 0, @@ -418,7 +438,7 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = { ecx_pub_cmp, ecx_pub_print, - ecx_priv_decode, + NULL, ecx_priv_encode, ecx_priv_print, @@ -447,9 +467,20 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = { ecx_set_pub_key, ecx_get_priv_key, ecx_get_pub_key, + ecx_pkey_dirty_cnt, + ecx_pkey_export_to, + x25519_import_from, + ecx_pkey_copy, + + ecx_priv_decode_ex }; -const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = { +static int x448_import_from(const OSSL_PARAM params[], void *vpctx) +{ + return ecx_generic_import_from(params, vpctx, EVP_PKEY_X448); +} + +const EVP_PKEY_ASN1_METHOD ossl_ecx448_asn1_meth = { EVP_PKEY_X448, EVP_PKEY_X448, 0, @@ -461,7 +492,7 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = { ecx_pub_cmp, ecx_pub_print, - ecx_priv_decode, + NULL, ecx_priv_encode, ecx_priv_print, @@ -490,6 +521,12 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = { ecx_set_pub_key, ecx_get_priv_key, ecx_get_pub_key, + ecx_pkey_dirty_cnt, + ecx_pkey_export_to, + x448_import_from, + ecx_pkey_copy, + + ecx_priv_decode_ex }; static int ecd_size25519(const EVP_PKEY *pkey) @@ -502,9 +539,9 @@ static int ecd_size448(const EVP_PKEY *pkey) return ED448_SIGSIZE; } -static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *sigalg, ASN1_BIT_STRING *str, - EVP_PKEY *pkey) +static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, + const void *asn, const X509_ALGOR *sigalg, + const ASN1_BIT_STRING *str, EVP_PKEY *pkey) { const ASN1_OBJECT *obj; int ptype; @@ -514,7 +551,7 @@ static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR_get0(&obj, &ptype, NULL, sigalg); nid = OBJ_obj2nid(obj); if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) { - ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); return 0; } @@ -524,7 +561,8 @@ static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, return 2; } -static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, +static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, + const void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *str) { @@ -544,7 +582,8 @@ static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg, return 1; } -static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, +static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, + const void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *str) { @@ -564,8 +603,12 @@ static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg, return 1; } +static int ed25519_import_from(const OSSL_PARAM params[], void *vpctx) +{ + return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED25519); +} -const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { +const EVP_PKEY_ASN1_METHOD ossl_ed25519_asn1_meth = { EVP_PKEY_ED25519, EVP_PKEY_ED25519, 0, @@ -577,7 +620,7 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { ecx_pub_cmp, ecx_pub_print, - ecx_priv_decode, + NULL, ecx_priv_encode, ecx_priv_print, @@ -605,9 +648,20 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { ecx_set_pub_key, ecx_get_priv_key, ecx_get_pub_key, + ecx_pkey_dirty_cnt, + ecx_pkey_export_to, + ed25519_import_from, + ecx_pkey_copy, + + ecx_priv_decode_ex }; -const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = { +static int ed448_import_from(const OSSL_PARAM params[], void *vpctx) +{ + return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED448); +} + +const EVP_PKEY_ASN1_METHOD ossl_ed448_asn1_meth = { EVP_PKEY_ED448, EVP_PKEY_ED448, 0, @@ -619,7 +673,7 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = { ecx_pub_cmp, ecx_pub_print, - ecx_priv_decode, + NULL, ecx_priv_encode, ecx_priv_print, @@ -647,11 +701,24 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = { ecx_set_pub_key, ecx_get_priv_key, ecx_get_pub_key, + ecx_pkey_dirty_cnt, + ecx_pkey_export_to, + ed448_import_from, + ecx_pkey_copy, + + ecx_priv_decode_ex }; static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { - return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN); + ECX_KEY *ecx = ossl_ecx_key_op(NULL, NULL, 0, ctx->pmeth->pkey_id, + KEY_OP_PUBLIC, NULL, NULL); + + if (ecx != NULL) { + EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, ecx); + return 1; + } + return 0; } static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key, @@ -662,17 +729,17 @@ static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key, const ECX_KEY *ecxkey, *peerkey; if (ctx->pkey == NULL || ctx->peerkey == NULL) { - ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET); + ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET); return 0; } - ecxkey = ctx->pkey->pkey.ecx; - peerkey = ctx->peerkey->pkey.ecx; + ecxkey = evp_pkey_get_legacy(ctx->pkey); + peerkey = evp_pkey_get_legacy(ctx->peerkey); if (ecxkey == NULL || ecxkey->privkey == NULL) { - ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY); return 0; } if (peerkey == NULL) { - ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_PEER_KEY); return 0; } *privkey = ecxkey->privkey; @@ -688,7 +755,7 @@ static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key, if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey) || (key != NULL - && X25519(key, privkey, pubkey) == 0)) + && ossl_x25519(key, privkey, pubkey) == 0)) return 0; *keylen = X25519_KEYLEN; return 1; @@ -701,7 +768,7 @@ static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key, if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey) || (key != NULL - && X448(key, privkey, pubkey) == 0)) + && ossl_x448(key, privkey, pubkey) == 0)) return 0; *keylen = X448_KEYLEN; return 1; @@ -715,7 +782,7 @@ static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return -2; } -const EVP_PKEY_METHOD ecx25519_pkey_meth = { +static const EVP_PKEY_METHOD ecx25519_pkey_meth = { EVP_PKEY_X25519, 0, 0, 0, 0, 0, 0, 0, pkey_ecx_keygen, @@ -725,7 +792,7 @@ const EVP_PKEY_METHOD ecx25519_pkey_meth = { 0 }; -const EVP_PKEY_METHOD ecx448_pkey_meth = { +static const EVP_PKEY_METHOD ecx448_pkey_meth = { EVP_PKEY_X448, 0, 0, 0, 0, 0, 0, 0, pkey_ecx_keygen, @@ -739,18 +806,24 @@ static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) { - const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx; + const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); + + if (edkey == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); + return 0; + } if (sig == NULL) { *siglen = ED25519_SIGSIZE; return 1; } if (*siglen < ED25519_SIGSIZE) { - ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); return 0; } - if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0) + if (ossl_ed25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL, + NULL) == 0) return 0; *siglen = ED25519_SIGSIZE; return 1; @@ -760,19 +833,24 @@ static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) { - const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx; + const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); + + if (edkey == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); + return 0; + } if (sig == NULL) { *siglen = ED448_SIGSIZE; return 1; } if (*siglen < ED448_SIGSIZE) { - ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); return 0; } - if (ED448_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL, - 0) == 0) + if (ossl_ed448_sign(edkey->libctx, sig, tbs, tbslen, edkey->pubkey, + edkey->privkey, NULL, 0, edkey->propq) == 0) return 0; *siglen = ED448_SIGSIZE; return 1; @@ -782,24 +860,36 @@ static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) { - const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx; + const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); + + if (edkey == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); + return 0; + } if (siglen != ED25519_SIGSIZE) return 0; - return ED25519_verify(tbs, tbslen, sig, edkey->pubkey); + return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey, + edkey->libctx, edkey->propq); } static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) { - const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx; + const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); + + if (edkey == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); + return 0; + } if (siglen != ED448_SIGSIZE) return 0; - return ED448_verify(tbs, tbslen, sig, edkey->pubkey, NULL, 0); + return ossl_ed448_verify(edkey->libctx, tbs, tbslen, sig, edkey->pubkey, + NULL, 0, edkey->propq); } static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) @@ -809,7 +899,7 @@ static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) /* Only NULL allowed as digest */ if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null()) return 1; - ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE); return 0; case EVP_PKEY_CTRL_DIGESTINIT: @@ -818,7 +908,7 @@ static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return -2; } -const EVP_PKEY_METHOD ed25519_pkey_meth = { +static const EVP_PKEY_METHOD ed25519_pkey_meth = { EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM, 0, 0, 0, 0, 0, 0, pkey_ecx_keygen, @@ -829,7 +919,7 @@ const EVP_PKEY_METHOD ed25519_pkey_meth = { pkey_ecd_digestverify25519 }; -const EVP_PKEY_METHOD ed448_pkey_meth = { +static const EVP_PKEY_METHOD ed448_pkey_meth = { EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM, 0, 0, 0, 0, 0, 0, pkey_ecx_keygen, @@ -839,3 +929,496 @@ const EVP_PKEY_METHOD ed448_pkey_meth = { pkey_ecd_digestsign448, pkey_ecd_digestverify448 }; + +#ifdef S390X_EC_ASM +# include "s390x_arch.h" + +static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + static const unsigned char generator[] = { + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1, + ctx->propquery); + unsigned char *privkey = NULL, *pubkey; + + if (key == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + pubkey = key->pubkey; + + privkey = ossl_ecx_key_allocate_privkey(key); + if (privkey == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (RAND_priv_bytes_ex(ctx->libctx, privkey, X25519_KEYLEN, 0) <= 0) + goto err; + + privkey[0] &= 248; + privkey[31] &= 127; + privkey[31] |= 64; + + if (s390x_x25519_mul(pubkey, generator, privkey) != 1) + goto err; + + EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key); + return 1; + err: + ossl_ecx_key_free(key); + return 0; +} + +static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + static const unsigned char generator[] = { + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1, + ctx->propquery); + unsigned char *privkey = NULL, *pubkey; + + if (key == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + pubkey = key->pubkey; + + privkey = ossl_ecx_key_allocate_privkey(key); + if (privkey == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (RAND_priv_bytes_ex(ctx->libctx, privkey, X448_KEYLEN, 0) <= 0) + goto err; + + privkey[0] &= 252; + privkey[55] |= 128; + + if (s390x_x448_mul(pubkey, generator, privkey) != 1) + goto err; + + EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key); + return 1; + err: + ossl_ecx_key_free(key); + return 0; +} + +static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + static const unsigned char generator_x[] = { + 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, + 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, + 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21 + }; + static const unsigned char generator_y[] = { + 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + }; + unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH]; + ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED25519, 1, + ctx->propquery); + unsigned char *privkey = NULL, *pubkey; + unsigned int sz; + EVP_MD *md = NULL; + int rv; + + if (key == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + pubkey = key->pubkey; + + privkey = ossl_ecx_key_allocate_privkey(key); + if (privkey == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0) + goto err; + + md = EVP_MD_fetch(ctx->libctx, "SHA512", ctx->propquery); + if (md == NULL) + goto err; + + rv = EVP_Digest(privkey, 32, buff, &sz, md, NULL); + EVP_MD_free(md); + if (!rv) + goto err; + + buff[0] &= 248; + buff[31] &= 63; + buff[31] |= 64; + + if (s390x_ed25519_mul(x_dst, pubkey, + generator_x, generator_y, buff) != 1) + goto err; + + pubkey[31] |= ((x_dst[0] & 0x01) << 7); + + EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key); + return 1; + err: + ossl_ecx_key_free(key); + return 0; +} + +static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + static const unsigned char generator_x[] = { + 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b, + 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12, + 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47, + 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22, + 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00 + }; + static const unsigned char generator_y[] = { + 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e, + 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a, + 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c, + 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88, + 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00 + }; + unsigned char x_dst[57], buff[114]; + ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED448, 1, + ctx->propquery); + unsigned char *privkey = NULL, *pubkey; + EVP_MD_CTX *hashctx = NULL; + EVP_MD *md = NULL; + int rv; + + if (key == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + pubkey = key->pubkey; + + privkey = ossl_ecx_key_allocate_privkey(key); + if (privkey == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED448_KEYLEN, 0) <= 0) + goto err; + + hashctx = EVP_MD_CTX_new(); + if (hashctx == NULL) + goto err; + + md = EVP_MD_fetch(ctx->libctx, "SHAKE256", ctx->propquery); + if (md == NULL) + goto err; + + rv = EVP_DigestInit_ex(hashctx, md, NULL); + EVP_MD_free(md); + if (rv != 1) + goto err; + + if (EVP_DigestUpdate(hashctx, privkey, 57) != 1) + goto err; + if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1) + goto err; + + buff[0] &= -4; + buff[55] |= 0x80; + buff[56] = 0; + + if (s390x_ed448_mul(x_dst, pubkey, + generator_x, generator_y, buff) != 1) + goto err; + + pubkey[56] |= ((x_dst[0] & 0x01) << 7); + + EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key); + EVP_MD_CTX_free(hashctx); + return 1; + err: + ossl_ecx_key_free(key); + EVP_MD_CTX_free(hashctx); + return 0; +} + +static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen) +{ + const unsigned char *privkey, *pubkey; + + if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey) + || (key != NULL + && s390x_x25519_mul(key, privkey, pubkey) == 0)) + return 0; + *keylen = X25519_KEYLEN; + return 1; +} + +static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen) +{ + const unsigned char *privkey, *pubkey; + + if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey) + || (key != NULL + && s390x_x448_mul(key, pubkey, privkey) == 0)) + return 0; + *keylen = X448_KEYLEN; + return 1; +} + +static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen) +{ + union { + struct { + unsigned char sig[64]; + unsigned char priv[32]; + } ed25519; + unsigned long long buff[512]; + } param; + const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); + int rc; + + if (edkey == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); + return 0; + } + + if (sig == NULL) { + *siglen = ED25519_SIGSIZE; + return 1; + } + + if (*siglen < ED25519_SIGSIZE) { + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + memset(¶m, 0, sizeof(param)); + memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv)); + + rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen); + OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv)); + if (rc != 0) + return 0; + + s390x_flip_endian32(sig, param.ed25519.sig); + s390x_flip_endian32(sig + 32, param.ed25519.sig + 32); + + *siglen = ED25519_SIGSIZE; + return 1; +} + +static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen) +{ + union { + struct { + unsigned char sig[128]; + unsigned char priv[64]; + } ed448; + unsigned long long buff[512]; + } param; + const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); + int rc; + + if (edkey == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); + return 0; + } + + if (sig == NULL) { + *siglen = ED448_SIGSIZE; + return 1; + } + + if (*siglen < ED448_SIGSIZE) { + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + memset(¶m, 0, sizeof(param)); + memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57); + + rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen); + OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv)); + if (rc != 0) + return 0; + + s390x_flip_endian64(param.ed448.sig, param.ed448.sig); + s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64); + memcpy(sig, param.ed448.sig, 57); + memcpy(sig + 57, param.ed448.sig + 64, 57); + + *siglen = ED448_SIGSIZE; + return 1; +} + +static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen) +{ + union { + struct { + unsigned char sig[64]; + unsigned char pub[32]; + } ed25519; + unsigned long long buff[512]; + } param; + const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); + + if (edkey == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); + return 0; + } + + if (siglen != ED25519_SIGSIZE) + return 0; + + memset(¶m, 0, sizeof(param)); + s390x_flip_endian32(param.ed25519.sig, sig); + s390x_flip_endian32(param.ed25519.sig + 32, sig + 32); + s390x_flip_endian32(param.ed25519.pub, edkey->pubkey); + + return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519, + ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0; +} + +static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen) +{ + union { + struct { + unsigned char sig[128]; + unsigned char pub[64]; + } ed448; + unsigned long long buff[512]; + } param; + const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); + + if (edkey == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); + return 0; + } + + if (siglen != ED448_SIGSIZE) + return 0; + + memset(¶m, 0, sizeof(param)); + memcpy(param.ed448.sig, sig, 57); + s390x_flip_endian64(param.ed448.sig, param.ed448.sig); + memcpy(param.ed448.sig + 64, sig + 57, 57); + s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64); + memcpy(param.ed448.pub, edkey->pubkey, 57); + s390x_flip_endian64(param.ed448.pub, param.ed448.pub); + + return s390x_kdsa(S390X_EDDSA_VERIFY_ED448, + ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0; +} + +static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = { + EVP_PKEY_X25519, + 0, 0, 0, 0, 0, 0, 0, + s390x_pkey_ecx_keygen25519, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + s390x_pkey_ecx_derive25519, + pkey_ecx_ctrl, + 0 +}; + +static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = { + EVP_PKEY_X448, + 0, 0, 0, 0, 0, 0, 0, + s390x_pkey_ecx_keygen448, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + s390x_pkey_ecx_derive448, + pkey_ecx_ctrl, + 0 +}; +static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = { + EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM, + 0, 0, 0, 0, 0, 0, + s390x_pkey_ecd_keygen25519, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + pkey_ecd_ctrl, + 0, + s390x_pkey_ecd_digestsign25519, + s390x_pkey_ecd_digestverify25519 +}; + +static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = { + EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM, + 0, 0, 0, 0, 0, 0, + s390x_pkey_ecd_keygen448, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + pkey_ecd_ctrl, + 0, + s390x_pkey_ecd_digestsign448, + s390x_pkey_ecd_digestverify448 +}; +#endif + +const EVP_PKEY_METHOD *ossl_ecx25519_pkey_method(void) +{ +#ifdef S390X_EC_ASM + if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519)) + return &ecx25519_s390x_pkey_meth; +#endif + return &ecx25519_pkey_meth; +} + +const EVP_PKEY_METHOD *ossl_ecx448_pkey_method(void) +{ +#ifdef S390X_EC_ASM + if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)) + return &ecx448_s390x_pkey_meth; +#endif + return &ecx448_pkey_meth; +} + +const EVP_PKEY_METHOD *ossl_ed25519_pkey_method(void) +{ +#ifdef S390X_EC_ASM + if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519) + && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519) + && OPENSSL_s390xcap_P.kdsa[0] + & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519)) + return &ed25519_s390x_pkey_meth; +#endif + return &ed25519_pkey_meth; +} + +const EVP_PKEY_METHOD *ossl_ed448_pkey_method(void) +{ +#ifdef S390X_EC_ASM + if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448) + && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448) + && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448)) + return &ed448_s390x_pkey_meth; +#endif + return &ed448_pkey_meth; +} diff --git a/crypto/openssl/crypto/ec/ecx_s390x.c b/crypto/openssl/crypto/ec/ecx_s390x.c new file mode 100644 index 000000000000..d424d6252dcf --- /dev/null +++ b/crypto/openssl/crypto/ec/ecx_s390x.c @@ -0,0 +1,217 @@ +/* + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include "crypto/ecx.h" +#include "ec_local.h" +#include "curve448/curve448_local.h" +#include "ecx_backend.h" +#include "s390x_arch.h" +#include "internal/constant_time.h" + +static void s390x_x25519_mod_p(unsigned char u[32]) +{ + unsigned char u_red[32]; + unsigned int c = 0; + int i; + + memcpy(u_red, u, sizeof(u_red)); + + c += (unsigned int)u_red[31] + 19; + u_red[31] = (unsigned char)c; + c >>= 8; + + for (i = 30; i >= 0; i--) { + c += (unsigned int)u_red[i]; + u_red[i] = (unsigned char)c; + c >>= 8; + } + + c = (u_red[0] & 0x80) >> 7; + u_red[0] &= 0x7f; + constant_time_cond_swap_buff(0 - (unsigned char)c, + u, u_red, sizeof(u_red)); +} + +static void s390x_x448_mod_p(unsigned char u[56]) +{ + unsigned char u_red[56]; + unsigned int c = 0; + int i; + + memcpy(u_red, u, sizeof(u_red)); + + c += (unsigned int)u_red[55] + 1; + u_red[55] = (unsigned char)c; + c >>= 8; + + for (i = 54; i >= 28; i--) { + c += (unsigned int)u_red[i]; + u_red[i] = (unsigned char)c; + c >>= 8; + } + + c += (unsigned int)u_red[27] + 1; + u_red[27] = (unsigned char)c; + c >>= 8; + + for (i = 26; i >= 0; i--) { + c += (unsigned int)u_red[i]; + u_red[i] = (unsigned char)c; + c >>= 8; + } + + constant_time_cond_swap_buff(0 - (unsigned char)c, + u, u_red, sizeof(u_red)); +} + +int s390x_x25519_mul(unsigned char u_dst[32], + const unsigned char u_src[32], + const unsigned char d_src[32]) +{ + union { + struct { + unsigned char u_dst[32]; + unsigned char u_src[32]; + unsigned char d_src[32]; + } x25519; + unsigned long long buff[512]; + } param; + int rc; + + memset(¶m, 0, sizeof(param)); + + s390x_flip_endian32(param.x25519.u_src, u_src); + param.x25519.u_src[0] &= 0x7f; + s390x_x25519_mod_p(param.x25519.u_src); + + s390x_flip_endian32(param.x25519.d_src, d_src); + param.x25519.d_src[31] &= 248; + param.x25519.d_src[0] &= 127; + param.x25519.d_src[0] |= 64; + + rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1; + if (rc == 1) + s390x_flip_endian32(u_dst, param.x25519.u_dst); + + OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src)); + return rc; +} + +int s390x_x448_mul(unsigned char u_dst[56], + const unsigned char u_src[56], + const unsigned char d_src[56]) +{ + union { + struct { + unsigned char u_dst[64]; + unsigned char u_src[64]; + unsigned char d_src[64]; + } x448; + unsigned long long buff[512]; + } param; + int rc; + + memset(¶m, 0, sizeof(param)); + + memcpy(param.x448.u_src, u_src, 56); + memcpy(param.x448.d_src, d_src, 56); + + s390x_flip_endian64(param.x448.u_src, param.x448.u_src); + s390x_x448_mod_p(param.x448.u_src + 8); + + s390x_flip_endian64(param.x448.d_src, param.x448.d_src); + param.x448.d_src[63] &= 252; + param.x448.d_src[8] |= 128; + + rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1; + if (rc == 1) { + s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst); + memcpy(u_dst, param.x448.u_dst, 56); + } + + OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src)); + return rc; +} + +int s390x_ed25519_mul(unsigned char x_dst[32], + unsigned char y_dst[32], + const unsigned char x_src[32], + const unsigned char y_src[32], + const unsigned char d_src[32]) +{ + union { + struct { + unsigned char x_dst[32]; + unsigned char y_dst[32]; + unsigned char x_src[32]; + unsigned char y_src[32]; + unsigned char d_src[32]; + } ed25519; + unsigned long long buff[512]; + } param; + int rc; + + memset(¶m, 0, sizeof(param)); + + s390x_flip_endian32(param.ed25519.x_src, x_src); + s390x_flip_endian32(param.ed25519.y_src, y_src); + s390x_flip_endian32(param.ed25519.d_src, d_src); + + rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1; + if (rc == 1) { + s390x_flip_endian32(x_dst, param.ed25519.x_dst); + s390x_flip_endian32(y_dst, param.ed25519.y_dst); + } + + OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src)); + return rc; +} + +int s390x_ed448_mul(unsigned char x_dst[57], + unsigned char y_dst[57], + const unsigned char x_src[57], + const unsigned char y_src[57], + const unsigned char d_src[57]) +{ + union { + struct { + unsigned char x_dst[64]; + unsigned char y_dst[64]; + unsigned char x_src[64]; + unsigned char y_src[64]; + unsigned char d_src[64]; + } ed448; + unsigned long long buff[512]; + } param; + int rc; + + memset(¶m, 0, sizeof(param)); + + memcpy(param.ed448.x_src, x_src, 57); + memcpy(param.ed448.y_src, y_src, 57); + memcpy(param.ed448.d_src, d_src, 57); + s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src); + s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src); + s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src); + + rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1; + if (rc == 1) { + s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst); + s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst); + memcpy(x_dst, param.ed448.x_dst, 57); + memcpy(y_dst, param.ed448.y_dst, 57); + } + + OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src)); + return rc; +} diff --git a/crypto/openssl/crypto/ec/x25519-x86_64.S b/crypto/openssl/crypto/ec/x25519-x86_64.S new file mode 100644 index 000000000000..4dc99724c3a1 --- /dev/null +++ b/crypto/openssl/crypto/ec/x25519-x86_64.S @@ -0,0 +1,823 @@ +.text + +.globl x25519_fe51_mul +.type x25519_fe51_mul,@function +.align 32 +x25519_fe51_mul: +.cfi_startproc + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + leaq -40(%rsp),%rsp +.cfi_adjust_cfa_offset 40 +.Lfe51_mul_body: + + movq 0(%rsi),%rax + movq 0(%rdx),%r11 + movq 8(%rdx),%r12 + movq 16(%rdx),%r13 + movq 24(%rdx),%rbp + movq 32(%rdx),%r14 + + movq %rdi,32(%rsp) + movq %rax,%rdi + mulq %r11 + movq %r11,0(%rsp) + movq %rax,%rbx + movq %rdi,%rax + movq %rdx,%rcx + mulq %r12 + movq %r12,8(%rsp) + movq %rax,%r8 + movq %rdi,%rax + leaq (%r14,%r14,8),%r15 + movq %rdx,%r9 + mulq %r13 + movq %r13,16(%rsp) + movq %rax,%r10 + movq %rdi,%rax + leaq (%r14,%r15,2),%rdi + movq %rdx,%r11 + mulq %rbp + movq %rax,%r12 + movq 0(%rsi),%rax + movq %rdx,%r13 + mulq %r14 + movq %rax,%r14 + movq 8(%rsi),%rax + movq %rdx,%r15 + + mulq %rdi + addq %rax,%rbx + movq 16(%rsi),%rax + adcq %rdx,%rcx + mulq %rdi + addq %rax,%r8 + movq 24(%rsi),%rax + adcq %rdx,%r9 + mulq %rdi + addq %rax,%r10 + movq 32(%rsi),%rax + adcq %rdx,%r11 + mulq %rdi + imulq $19,%rbp,%rdi + addq %rax,%r12 + movq 8(%rsi),%rax + adcq %rdx,%r13 + mulq %rbp + movq 16(%rsp),%rbp + addq %rax,%r14 + movq 16(%rsi),%rax + adcq %rdx,%r15 + + mulq %rdi + addq %rax,%rbx + movq 24(%rsi),%rax + adcq %rdx,%rcx + mulq %rdi + addq %rax,%r8 + movq 32(%rsi),%rax + adcq %rdx,%r9 + mulq %rdi + imulq $19,%rbp,%rdi + addq %rax,%r10 + movq 8(%rsi),%rax + adcq %rdx,%r11 + mulq %rbp + addq %rax,%r12 + movq 16(%rsi),%rax + adcq %rdx,%r13 + mulq %rbp + movq 8(%rsp),%rbp + addq %rax,%r14 + movq 24(%rsi),%rax + adcq %rdx,%r15 + + mulq %rdi + addq %rax,%rbx + movq 32(%rsi),%rax + adcq %rdx,%rcx + mulq %rdi + addq %rax,%r8 + movq 8(%rsi),%rax + adcq %rdx,%r9 + mulq %rbp + imulq $19,%rbp,%rdi + addq %rax,%r10 + movq 16(%rsi),%rax + adcq %rdx,%r11 + mulq %rbp + addq %rax,%r12 + movq 24(%rsi),%rax + adcq %rdx,%r13 + mulq %rbp + movq 0(%rsp),%rbp + addq %rax,%r14 + movq 32(%rsi),%rax + adcq %rdx,%r15 + + mulq %rdi + addq %rax,%rbx + movq 8(%rsi),%rax + adcq %rdx,%rcx + mulq %rbp + addq %rax,%r8 + movq 16(%rsi),%rax + adcq %rdx,%r9 + mulq %rbp + addq %rax,%r10 + movq 24(%rsi),%rax + adcq %rdx,%r11 + mulq %rbp + addq %rax,%r12 + movq 32(%rsi),%rax + adcq %rdx,%r13 + mulq %rbp + addq %rax,%r14 + adcq %rdx,%r15 + + movq 32(%rsp),%rdi + jmp .Lreduce51 +.Lfe51_mul_epilogue: +.cfi_endproc +.size x25519_fe51_mul,.-x25519_fe51_mul + +.globl x25519_fe51_sqr +.type x25519_fe51_sqr,@function +.align 32 +x25519_fe51_sqr: +.cfi_startproc + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + leaq -40(%rsp),%rsp +.cfi_adjust_cfa_offset 40 +.Lfe51_sqr_body: + + movq 0(%rsi),%rax + movq 16(%rsi),%r15 + movq 32(%rsi),%rbp + + movq %rdi,32(%rsp) + leaq (%rax,%rax,1),%r14 + mulq %rax + movq %rax,%rbx + movq 8(%rsi),%rax + movq %rdx,%rcx + mulq %r14 + movq %rax,%r8 + movq %r15,%rax + movq %r15,0(%rsp) + movq %rdx,%r9 + mulq %r14 + movq %rax,%r10 + movq 24(%rsi),%rax + movq %rdx,%r11 + imulq $19,%rbp,%rdi + mulq %r14 + movq %rax,%r12 + movq %rbp,%rax + movq %rdx,%r13 + mulq %r14 + movq %rax,%r14 + movq %rbp,%rax + movq %rdx,%r15 + + mulq %rdi + addq %rax,%r12 + movq 8(%rsi),%rax + adcq %rdx,%r13 + + movq 24(%rsi),%rsi + leaq (%rax,%rax,1),%rbp + mulq %rax + addq %rax,%r10 + movq 0(%rsp),%rax + adcq %rdx,%r11 + mulq %rbp + addq %rax,%r12 + movq %rbp,%rax + adcq %rdx,%r13 + mulq %rsi + addq %rax,%r14 + movq %rbp,%rax + adcq %rdx,%r15 + imulq $19,%rsi,%rbp + mulq %rdi + addq %rax,%rbx + leaq (%rsi,%rsi,1),%rax + adcq %rdx,%rcx + + mulq %rdi + addq %rax,%r10 + movq %rsi,%rax + adcq %rdx,%r11 + mulq %rbp + addq %rax,%r8 + movq 0(%rsp),%rax + adcq %rdx,%r9 + + leaq (%rax,%rax,1),%rsi + mulq %rax + addq %rax,%r14 + movq %rbp,%rax + adcq %rdx,%r15 + mulq %rsi + addq %rax,%rbx + movq %rsi,%rax + adcq %rdx,%rcx + mulq %rdi + addq %rax,%r8 + adcq %rdx,%r9 + + movq 32(%rsp),%rdi + jmp .Lreduce51 + +.align 32 +.Lreduce51: + movq $0x7ffffffffffff,%rbp + + movq %r10,%rdx + shrq $51,%r10 + shlq $13,%r11 + andq %rbp,%rdx + orq %r10,%r11 + addq %r11,%r12 + adcq $0,%r13 + + movq %rbx,%rax + shrq $51,%rbx + shlq $13,%rcx + andq %rbp,%rax + orq %rbx,%rcx + addq %rcx,%r8 + adcq $0,%r9 + + movq %r12,%rbx + shrq $51,%r12 + shlq $13,%r13 + andq %rbp,%rbx + orq %r12,%r13 + addq %r13,%r14 + adcq $0,%r15 + + movq %r8,%rcx + shrq $51,%r8 + shlq $13,%r9 + andq %rbp,%rcx + orq %r8,%r9 + addq %r9,%rdx + + movq %r14,%r10 + shrq $51,%r14 + shlq $13,%r15 + andq %rbp,%r10 + orq %r14,%r15 + + leaq (%r15,%r15,8),%r14 + leaq (%r15,%r14,2),%r15 + addq %r15,%rax + + movq %rdx,%r8 + andq %rbp,%rdx + shrq $51,%r8 + addq %r8,%rbx + + movq %rax,%r9 + andq %rbp,%rax + shrq $51,%r9 + addq %r9,%rcx + + movq %rax,0(%rdi) + movq %rcx,8(%rdi) + movq %rdx,16(%rdi) + movq %rbx,24(%rdi) + movq %r10,32(%rdi) + + movq 40(%rsp),%r15 +.cfi_restore %r15 + movq 48(%rsp),%r14 +.cfi_restore %r14 + movq 56(%rsp),%r13 +.cfi_restore %r13 + movq 64(%rsp),%r12 +.cfi_restore %r12 + movq 72(%rsp),%rbx +.cfi_restore %rbx + movq 80(%rsp),%rbp +.cfi_restore %rbp + leaq 88(%rsp),%rsp +.cfi_adjust_cfa_offset 88 +.Lfe51_sqr_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size x25519_fe51_sqr,.-x25519_fe51_sqr + +.globl x25519_fe51_mul121666 +.type x25519_fe51_mul121666,@function +.align 32 +x25519_fe51_mul121666: +.cfi_startproc + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + leaq -40(%rsp),%rsp +.cfi_adjust_cfa_offset 40 +.Lfe51_mul121666_body: + movl $121666,%eax + + mulq 0(%rsi) + movq %rax,%rbx + movl $121666,%eax + movq %rdx,%rcx + mulq 8(%rsi) + movq %rax,%r8 + movl $121666,%eax + movq %rdx,%r9 + mulq 16(%rsi) + movq %rax,%r10 + movl $121666,%eax + movq %rdx,%r11 + mulq 24(%rsi) + movq %rax,%r12 + movl $121666,%eax + movq %rdx,%r13 + mulq 32(%rsi) + movq %rax,%r14 + movq %rdx,%r15 + + jmp .Lreduce51 +.Lfe51_mul121666_epilogue: +.cfi_endproc +.size x25519_fe51_mul121666,.-x25519_fe51_mul121666 + +.globl x25519_fe64_eligible +.type x25519_fe64_eligible,@function +.align 32 +x25519_fe64_eligible: +.cfi_startproc + movl OPENSSL_ia32cap_P+8(%rip),%ecx + xorl %eax,%eax + andl $0x80100,%ecx + cmpl $0x80100,%ecx + cmovel %ecx,%eax + .byte 0xf3,0xc3 +.cfi_endproc +.size x25519_fe64_eligible,.-x25519_fe64_eligible + +.globl x25519_fe64_mul +.type x25519_fe64_mul,@function +.align 32 +x25519_fe64_mul: +.cfi_startproc + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + pushq %rdi +.cfi_adjust_cfa_offset 8 +.cfi_offset %rdi,-64 + leaq -16(%rsp),%rsp +.cfi_adjust_cfa_offset 16 +.Lfe64_mul_body: + + movq %rdx,%rax + movq 0(%rdx),%rbp + movq 0(%rsi),%rdx + movq 8(%rax),%rcx + movq 16(%rax),%r14 + movq 24(%rax),%r15 + + mulxq %rbp,%r8,%rax + xorl %edi,%edi + mulxq %rcx,%r9,%rbx + adcxq %rax,%r9 + mulxq %r14,%r10,%rax + adcxq %rbx,%r10 + mulxq %r15,%r11,%r12 + movq 8(%rsi),%rdx + adcxq %rax,%r11 + movq %r14,(%rsp) + adcxq %rdi,%r12 + + mulxq %rbp,%rax,%rbx + adoxq %rax,%r9 + adcxq %rbx,%r10 + mulxq %rcx,%rax,%rbx + adoxq %rax,%r10 + adcxq %rbx,%r11 + mulxq %r14,%rax,%rbx + adoxq %rax,%r11 + adcxq %rbx,%r12 + mulxq %r15,%rax,%r13 + movq 16(%rsi),%rdx + adoxq %rax,%r12 + adcxq %rdi,%r13 + adoxq %rdi,%r13 + + mulxq %rbp,%rax,%rbx + adcxq %rax,%r10 + adoxq %rbx,%r11 + mulxq %rcx,%rax,%rbx + adcxq %rax,%r11 + adoxq %rbx,%r12 + mulxq %r14,%rax,%rbx + adcxq %rax,%r12 + adoxq %rbx,%r13 + mulxq %r15,%rax,%r14 + movq 24(%rsi),%rdx + adcxq %rax,%r13 + adoxq %rdi,%r14 + adcxq %rdi,%r14 + + mulxq %rbp,%rax,%rbx + adoxq %rax,%r11 + adcxq %rbx,%r12 + mulxq %rcx,%rax,%rbx + adoxq %rax,%r12 + adcxq %rbx,%r13 + mulxq (%rsp),%rax,%rbx + adoxq %rax,%r13 + adcxq %rbx,%r14 + mulxq %r15,%rax,%r15 + movl $38,%edx + adoxq %rax,%r14 + adcxq %rdi,%r15 + adoxq %rdi,%r15 + + jmp .Lreduce64 +.Lfe64_mul_epilogue: +.cfi_endproc +.size x25519_fe64_mul,.-x25519_fe64_mul + +.globl x25519_fe64_sqr +.type x25519_fe64_sqr,@function +.align 32 +x25519_fe64_sqr: +.cfi_startproc + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + pushq %rdi +.cfi_adjust_cfa_offset 8 +.cfi_offset %rdi,-64 + leaq -16(%rsp),%rsp +.cfi_adjust_cfa_offset 16 +.Lfe64_sqr_body: + + movq 0(%rsi),%rdx + movq 8(%rsi),%rcx + movq 16(%rsi),%rbp + movq 24(%rsi),%rsi + + + mulxq %rdx,%r8,%r15 + mulxq %rcx,%r9,%rax + xorl %edi,%edi + mulxq %rbp,%r10,%rbx + adcxq %rax,%r10 + mulxq %rsi,%r11,%r12 + movq %rcx,%rdx + adcxq %rbx,%r11 + adcxq %rdi,%r12 + + + mulxq %rbp,%rax,%rbx + adoxq %rax,%r11 + adcxq %rbx,%r12 + mulxq %rsi,%rax,%r13 + movq %rbp,%rdx + adoxq %rax,%r12 + adcxq %rdi,%r13 + + + mulxq %rsi,%rax,%r14 + movq %rcx,%rdx + adoxq %rax,%r13 + adcxq %rdi,%r14 + adoxq %rdi,%r14 + + adcxq %r9,%r9 + adoxq %r15,%r9 + adcxq %r10,%r10 + mulxq %rdx,%rax,%rbx + movq %rbp,%rdx + adcxq %r11,%r11 + adoxq %rax,%r10 + adcxq %r12,%r12 + adoxq %rbx,%r11 + mulxq %rdx,%rax,%rbx + movq %rsi,%rdx + adcxq %r13,%r13 + adoxq %rax,%r12 + adcxq %r14,%r14 + adoxq %rbx,%r13 + mulxq %rdx,%rax,%r15 + movl $38,%edx + adoxq %rax,%r14 + adcxq %rdi,%r15 + adoxq %rdi,%r15 + jmp .Lreduce64 + +.align 32 +.Lreduce64: + mulxq %r12,%rax,%rbx + adcxq %rax,%r8 + adoxq %rbx,%r9 + mulxq %r13,%rax,%rbx + adcxq %rax,%r9 + adoxq %rbx,%r10 + mulxq %r14,%rax,%rbx + adcxq %rax,%r10 + adoxq %rbx,%r11 + mulxq %r15,%rax,%r12 + adcxq %rax,%r11 + adoxq %rdi,%r12 + adcxq %rdi,%r12 + + movq 16(%rsp),%rdi + imulq %rdx,%r12 + + addq %r12,%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + + sbbq %rax,%rax + andq $38,%rax + + addq %rax,%r8 + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r8,0(%rdi) + + movq 24(%rsp),%r15 +.cfi_restore %r15 + movq 32(%rsp),%r14 +.cfi_restore %r14 + movq 40(%rsp),%r13 +.cfi_restore %r13 + movq 48(%rsp),%r12 +.cfi_restore %r12 + movq 56(%rsp),%rbx +.cfi_restore %rbx + movq 64(%rsp),%rbp +.cfi_restore %rbp + leaq 72(%rsp),%rsp +.cfi_adjust_cfa_offset 88 +.Lfe64_sqr_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size x25519_fe64_sqr,.-x25519_fe64_sqr + +.globl x25519_fe64_mul121666 +.type x25519_fe64_mul121666,@function +.align 32 +x25519_fe64_mul121666: +.Lfe64_mul121666_body: +.cfi_startproc + movl $121666,%edx + mulxq 0(%rsi),%r8,%rcx + mulxq 8(%rsi),%r9,%rax + addq %rcx,%r9 + mulxq 16(%rsi),%r10,%rcx + adcq %rax,%r10 + mulxq 24(%rsi),%r11,%rax + adcq %rcx,%r11 + adcq $0,%rax + + imulq $38,%rax,%rax + + addq %rax,%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%r11 + + sbbq %rax,%rax + andq $38,%rax + + addq %rax,%r8 + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r8,0(%rdi) + +.Lfe64_mul121666_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size x25519_fe64_mul121666,.-x25519_fe64_mul121666 + +.globl x25519_fe64_add +.type x25519_fe64_add,@function +.align 32 +x25519_fe64_add: +.Lfe64_add_body: +.cfi_startproc + movq 0(%rsi),%r8 + movq 8(%rsi),%r9 + movq 16(%rsi),%r10 + movq 24(%rsi),%r11 + + addq 0(%rdx),%r8 + adcq 8(%rdx),%r9 + adcq 16(%rdx),%r10 + adcq 24(%rdx),%r11 + + sbbq %rax,%rax + andq $38,%rax + + addq %rax,%r8 + adcq $0,%r9 + adcq $0,%r10 + movq %r9,8(%rdi) + adcq $0,%r11 + movq %r10,16(%rdi) + sbbq %rax,%rax + movq %r11,24(%rdi) + andq $38,%rax + + addq %rax,%r8 + movq %r8,0(%rdi) + +.Lfe64_add_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size x25519_fe64_add,.-x25519_fe64_add + +.globl x25519_fe64_sub +.type x25519_fe64_sub,@function +.align 32 +x25519_fe64_sub: +.Lfe64_sub_body: +.cfi_startproc + movq 0(%rsi),%r8 + movq 8(%rsi),%r9 + movq 16(%rsi),%r10 + movq 24(%rsi),%r11 + + subq 0(%rdx),%r8 + sbbq 8(%rdx),%r9 + sbbq 16(%rdx),%r10 + sbbq 24(%rdx),%r11 + + sbbq %rax,%rax + andq $38,%rax + + subq %rax,%r8 + sbbq $0,%r9 + sbbq $0,%r10 + movq %r9,8(%rdi) + sbbq $0,%r11 + movq %r10,16(%rdi) + sbbq %rax,%rax + movq %r11,24(%rdi) + andq $38,%rax + + subq %rax,%r8 + movq %r8,0(%rdi) + +.Lfe64_sub_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size x25519_fe64_sub,.-x25519_fe64_sub + +.globl x25519_fe64_tobytes +.type x25519_fe64_tobytes,@function +.align 32 +x25519_fe64_tobytes: +.Lfe64_to_body: +.cfi_startproc + movq 0(%rsi),%r8 + movq 8(%rsi),%r9 + movq 16(%rsi),%r10 + movq 24(%rsi),%r11 + + + leaq (%r11,%r11,1),%rax + sarq $63,%r11 + shrq $1,%rax + andq $19,%r11 + addq $19,%r11 + + addq %r11,%r8 + adcq $0,%r9 + adcq $0,%r10 + adcq $0,%rax + + leaq (%rax,%rax,1),%r11 + sarq $63,%rax + shrq $1,%r11 + notq %rax + andq $19,%rax + + subq %rax,%r8 + sbbq $0,%r9 + sbbq $0,%r10 + sbbq $0,%r11 + + movq %r8,0(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + +.Lfe64_to_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size x25519_fe64_tobytes,.-x25519_fe64_tobytes +.byte 88,50,53,53,49,57,32,112,114,105,109,105,116,105,118,101,115,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/encode_decode/build.info b/crypto/openssl/crypto/encode_decode/build.info new file mode 100644 index 000000000000..e2cd84667338 --- /dev/null +++ b/crypto/openssl/crypto/encode_decode/build.info @@ -0,0 +1,5 @@ +SOURCE[../../libcrypto]=encoder_meth.c encoder_lib.c encoder_pkey.c +SOURCE[../../libcrypto]=decoder_meth.c decoder_lib.c decoder_pkey.c + +SOURCE[../../libcrypto]=encoder_err.c +SOURCE[../../libcrypto]=decoder_err.c diff --git a/crypto/openssl/crypto/encode_decode/decoder_err.c b/crypto/openssl/crypto/encode_decode/decoder_err.c new file mode 100644 index 000000000000..88324a1d5078 --- /dev/null +++ b/crypto/openssl/crypto/encode_decode/decoder_err.c @@ -0,0 +1,36 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/decodererr.h" + +#ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA OSSL_DECODER_str_reasons[] = { + {ERR_PACK(ERR_LIB_OSSL_DECODER, 0, OSSL_DECODER_R_COULD_NOT_DECODE_OBJECT), + "could not decode object"}, + {ERR_PACK(ERR_LIB_OSSL_DECODER, 0, OSSL_DECODER_R_DECODER_NOT_FOUND), + "decoder not found"}, + {ERR_PACK(ERR_LIB_OSSL_DECODER, 0, OSSL_DECODER_R_MISSING_GET_PARAMS), + "missing get params"}, + {0, NULL} +}; + +#endif + +int ossl_err_load_OSSL_DECODER_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(OSSL_DECODER_str_reasons[0].error) == NULL) + ERR_load_strings_const(OSSL_DECODER_str_reasons); +#endif + return 1; +} diff --git a/crypto/openssl/crypto/encode_decode/decoder_lib.c b/crypto/openssl/crypto/encode_decode/decoder_lib.c new file mode 100644 index 000000000000..e24d2c6cd588 --- /dev/null +++ b/crypto/openssl/crypto/encode_decode/decoder_lib.c @@ -0,0 +1,999 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/bio.h" +#include "internal/provider.h" +#include "crypto/decoder.h" +#include "encoder_local.h" +#include "e_os.h" + +struct decoder_process_data_st { + OSSL_DECODER_CTX *ctx; + + /* Current BIO */ + BIO *bio; + + /* Index of the current decoder instance to be processed */ + size_t current_decoder_inst_index; + /* For tracing, count recursion level */ + size_t recursion; + + /*- + * Flags + */ + unsigned int flag_next_level_called : 1; + unsigned int flag_construct_called : 1; + unsigned int flag_input_structure_checked : 1; +}; + +static int decoder_process(const OSSL_PARAM params[], void *arg); + +int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in) +{ + struct decoder_process_data_st data; + int ok = 0; + BIO *new_bio = NULL; + unsigned long lasterr; + + if (in == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (OSSL_DECODER_CTX_get_num_decoders(ctx) == 0) { + ERR_raise_data(ERR_LIB_OSSL_DECODER, OSSL_DECODER_R_DECODER_NOT_FOUND, + "No decoders were found. For standard decoders you need " + "at least one of the default or base providers " + "available. Did you forget to load them?"); + return 0; + } + + lasterr = ERR_peek_last_error(); + + if (BIO_tell(in) < 0) { + new_bio = BIO_new(BIO_f_readbuffer()); + if (new_bio == NULL) + return 0; + in = BIO_push(new_bio, in); + } + memset(&data, 0, sizeof(data)); + data.ctx = ctx; + data.bio = in; + + /* Enable passphrase caching */ + (void)ossl_pw_enable_passphrase_caching(&ctx->pwdata); + + ok = decoder_process(NULL, &data); + + if (!data.flag_construct_called) { + const char *spaces + = ctx->start_input_type != NULL && ctx->input_structure != NULL + ? " " : ""; + const char *input_type_label + = ctx->start_input_type != NULL ? "Input type: " : ""; + const char *input_structure_label + = ctx->input_structure != NULL ? "Input structure: " : ""; + const char *comma + = ctx->start_input_type != NULL && ctx->input_structure != NULL + ? ", " : ""; + const char *input_type + = ctx->start_input_type != NULL ? ctx->start_input_type : ""; + const char *input_structure + = ctx->input_structure != NULL ? ctx->input_structure : ""; + + if (ERR_peek_last_error() == lasterr || ERR_peek_error() == 0) + /* Prevent spurious decoding error but add at least something */ + ERR_raise_data(ERR_LIB_OSSL_DECODER, ERR_R_UNSUPPORTED, + "No supported data to decode. %s%s%s%s%s%s", + spaces, input_type_label, input_type, comma, + input_structure_label, input_structure); + ok = 0; + } + + /* Clear any internally cached passphrase */ + (void)ossl_pw_clear_passphrase_cache(&ctx->pwdata); + + if (new_bio != NULL) { + BIO_pop(new_bio); + BIO_free(new_bio); + } + return ok; +} + +#ifndef OPENSSL_NO_STDIO +static BIO *bio_from_file(FILE *fp) +{ + BIO *b; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_BIO_LIB); + return NULL; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + return b; +} + +int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *fp) +{ + BIO *b = bio_from_file(fp); + int ret = 0; + + if (b != NULL) + ret = OSSL_DECODER_from_bio(ctx, b); + + BIO_free(b); + return ret; +} +#endif + +int OSSL_DECODER_from_data(OSSL_DECODER_CTX *ctx, const unsigned char **pdata, + size_t *pdata_len) +{ + BIO *membio; + int ret = 0; + + if (pdata == NULL || *pdata == NULL || pdata_len == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + membio = BIO_new_mem_buf(*pdata, (int)*pdata_len); + if (OSSL_DECODER_from_bio(ctx, membio)) { + *pdata_len = (size_t)BIO_get_mem_data(membio, pdata); + ret = 1; + } + BIO_free(membio); + + return ret; +} + +int OSSL_DECODER_CTX_set_selection(OSSL_DECODER_CTX *ctx, int selection) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* + * 0 is a valid selection, and means that the caller leaves + * it to code to discover what the selection is. + */ + ctx->selection = selection; + return 1; +} + +int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx, + const char *input_type) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* + * NULL is a valid starting input type, and means that the caller leaves + * it to code to discover what the starting input type is. + */ + ctx->start_input_type = input_type; + return 1; +} + +int OSSL_DECODER_CTX_set_input_structure(OSSL_DECODER_CTX *ctx, + const char *input_structure) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* + * NULL is a valid starting input structure, and means that the caller + * leaves it to code to discover what the starting input structure is. + */ + ctx->input_structure = input_structure; + return 1; +} + +OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder, + void *decoderctx) +{ + OSSL_DECODER_INSTANCE *decoder_inst = NULL; + const OSSL_PROVIDER *prov; + OSSL_LIB_CTX *libctx; + const OSSL_PROPERTY_LIST *props; + const OSSL_PROPERTY_DEFINITION *prop; + + if (!ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((decoder_inst = OPENSSL_zalloc(sizeof(*decoder_inst))) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return 0; + } + + prov = OSSL_DECODER_get0_provider(decoder); + libctx = ossl_provider_libctx(prov); + props = ossl_decoder_parsed_properties(decoder); + if (props == NULL) { + ERR_raise_data(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROPERTY_DEFINITION, + "there are no property definitions with decoder %s", + OSSL_DECODER_get0_name(decoder)); + goto err; + } + + /* The "input" property is mandatory */ + prop = ossl_property_find_property(props, libctx, "input"); + decoder_inst->input_type = ossl_property_get_string_value(libctx, prop); + if (decoder_inst->input_type == NULL) { + ERR_raise_data(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROPERTY_DEFINITION, + "the mandatory 'input' property is missing " + "for decoder %s (properties: %s)", + OSSL_DECODER_get0_name(decoder), + OSSL_DECODER_get0_properties(decoder)); + goto err; + } + + /* The "structure" property is optional */ + prop = ossl_property_find_property(props, libctx, "structure"); + if (prop != NULL) { + decoder_inst->input_structure + = ossl_property_get_string_value(libctx, prop); + } + + if (!OSSL_DECODER_up_ref(decoder)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR); + goto err; + } + decoder_inst->decoder = decoder; + decoder_inst->decoderctx = decoderctx; + return decoder_inst; + err: + ossl_decoder_instance_free(decoder_inst); + return NULL; +} + +void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst) +{ + if (decoder_inst != NULL) { + if (decoder_inst->decoder != NULL) + decoder_inst->decoder->freectx(decoder_inst->decoderctx); + decoder_inst->decoderctx = NULL; + OSSL_DECODER_free(decoder_inst->decoder); + decoder_inst->decoder = NULL; + OPENSSL_free(decoder_inst); + } +} + +int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_INSTANCE *di) +{ + int ok; + + if (ctx->decoder_insts == NULL + && (ctx->decoder_insts = + sk_OSSL_DECODER_INSTANCE_new_null()) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return 0; + } + + ok = (sk_OSSL_DECODER_INSTANCE_push(ctx->decoder_insts, di) > 0); + if (ok) { + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) Added decoder instance %p for decoder %p\n" + " %s with %s\n", + (void *)ctx, (void *)di, (void *)di->decoder, + OSSL_DECODER_get0_name(di->decoder), + OSSL_DECODER_get0_properties(di->decoder)); + } OSSL_TRACE_END(DECODER); + } + return ok; +} + +int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder) +{ + OSSL_DECODER_INSTANCE *decoder_inst = NULL; + const OSSL_PROVIDER *prov = NULL; + void *decoderctx = NULL; + void *provctx = NULL; + + if (!ossl_assert(ctx != NULL) || !ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + prov = OSSL_DECODER_get0_provider(decoder); + provctx = OSSL_PROVIDER_get0_provider_ctx(prov); + + if ((decoderctx = decoder->newctx(provctx)) == NULL + || (decoder_inst = + ossl_decoder_instance_new(decoder, decoderctx)) == NULL) + goto err; + /* Avoid double free of decoderctx on further errors */ + decoderctx = NULL; + + if (!ossl_decoder_ctx_add_decoder_inst(ctx, decoder_inst)) + goto err; + + return 1; + err: + ossl_decoder_instance_free(decoder_inst); + if (decoderctx != NULL) + decoder->freectx(decoderctx); + return 0; +} + +struct collect_extra_decoder_data_st { + OSSL_DECODER_CTX *ctx; + const char *output_type; + /* + * 0 to check that the decoder's input type is the same as the decoder name + * 1 to check that the decoder's input type differs from the decoder name + */ + enum { IS_SAME = 0, IS_DIFFERENT = 1 } type_check; + size_t w_prev_start, w_prev_end; /* "previous" decoders */ + size_t w_new_start, w_new_end; /* "new" decoders */ +}; + +DEFINE_STACK_OF(OSSL_DECODER) + +static void collect_all_decoders(OSSL_DECODER *decoder, void *arg) +{ + STACK_OF(OSSL_DECODER) *skdecoders = arg; + + if (OSSL_DECODER_up_ref(decoder) + && !sk_OSSL_DECODER_push(skdecoders, decoder)) + OSSL_DECODER_free(decoder); +} + +static void collect_extra_decoder(OSSL_DECODER *decoder, void *arg) +{ + struct collect_extra_decoder_data_st *data = arg; + size_t j; + const OSSL_PROVIDER *prov = OSSL_DECODER_get0_provider(decoder); + void *provctx = OSSL_PROVIDER_get0_provider_ctx(prov); + + if (OSSL_DECODER_is_a(decoder, data->output_type)) { + void *decoderctx = NULL; + OSSL_DECODER_INSTANCE *di = NULL; + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) [%d] Checking out decoder %p:\n" + " %s with %s\n", + (void *)data->ctx, data->type_check, (void *)decoder, + OSSL_DECODER_get0_name(decoder), + OSSL_DECODER_get0_properties(decoder)); + } OSSL_TRACE_END(DECODER); + + /* + * Check that we don't already have this decoder in our stack, + * starting with the previous windows but also looking at what + * we have added in the current window. + */ + for (j = data->w_prev_start; j < data->w_new_end; j++) { + OSSL_DECODER_INSTANCE *check_inst = + sk_OSSL_DECODER_INSTANCE_value(data->ctx->decoder_insts, j); + + if (decoder->base.algodef == check_inst->decoder->base.algodef) { + /* We found it, so don't do anything more */ + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + " REJECTED: already exists in the chain\n"); + } OSSL_TRACE_END(DECODER); + return; + } + } + + if ((decoderctx = decoder->newctx(provctx)) == NULL) + return; + + if ((di = ossl_decoder_instance_new(decoder, decoderctx)) == NULL) { + decoder->freectx(decoderctx); + return; + } + + switch (data->type_check) { + case IS_SAME: + /* If it differs, this is not a decoder to add for now. */ + if (!OSSL_DECODER_is_a(decoder, + OSSL_DECODER_INSTANCE_get_input_type(di))) { + ossl_decoder_instance_free(di); + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + " REJECTED: input type doesn't match output type\n"); + } OSSL_TRACE_END(DECODER); + return; + } + break; + case IS_DIFFERENT: + /* If it's the same, this is not a decoder to add for now. */ + if (OSSL_DECODER_is_a(decoder, + OSSL_DECODER_INSTANCE_get_input_type(di))) { + ossl_decoder_instance_free(di); + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + " REJECTED: input type matches output type\n"); + } OSSL_TRACE_END(DECODER); + return; + } + break; + } + + /* + * Apart from keeping w_new_end up to date, We don't care about + * errors here. If it doesn't collect, then it doesn't... + */ + if (!ossl_decoder_ctx_add_decoder_inst(data->ctx, di)) { + ossl_decoder_instance_free(di); + return; + } + + data->w_new_end++; + } +} + +int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq) +{ + /* + * This function goes through existing decoder methods in + * |ctx->decoder_insts|, and tries to fetch new decoders that produce + * what the existing ones want as input, and push those newly fetched + * decoders on top of the same stack. + * Then it does the same again, but looping over the newly fetched + * decoders, until there are no more decoders to be fetched, or + * when we have done this 10 times. + * + * we do this with sliding windows on the stack by keeping track of indexes + * and of the end. + * + * +----------------+ + * | DER to RSA | <--- w_prev_start + * +----------------+ + * | DER to DSA | + * +----------------+ + * | DER to DH | + * +----------------+ + * | PEM to DER | <--- w_prev_end, w_new_start + * +----------------+ + * <--- w_new_end + */ + struct collect_extra_decoder_data_st data; + size_t depth = 0; /* Counts the number of iterations */ + size_t count; /* Calculates how many were added in each iteration */ + size_t numdecoders; + STACK_OF(OSSL_DECODER) *skdecoders; + + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* + * If there is no stack of OSSL_DECODER_INSTANCE, we have nothing + * more to add. That's fine. + */ + if (ctx->decoder_insts == NULL) + return 1; + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, "(ctx %p) Looking for extra decoders\n", + (void *)ctx); + } OSSL_TRACE_END(DECODER); + + + skdecoders = sk_OSSL_DECODER_new_null(); + if (skdecoders == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return 0; + } + OSSL_DECODER_do_all_provided(libctx, collect_all_decoders, skdecoders); + numdecoders = sk_OSSL_DECODER_num(skdecoders); + + memset(&data, 0, sizeof(data)); + data.ctx = ctx; + data.w_prev_start = 0; + data.w_prev_end = sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts); + do { + size_t i, j; + + data.w_new_start = data.w_new_end = data.w_prev_end; + + /* + * Two iterations: + * 0. All decoders that have the same name as their input type. + * This allows for decoders that unwrap some data in a specific + * encoding, and pass the result on with the same encoding. + * 1. All decoders that a different name than their input type. + */ + for (data.type_check = IS_SAME; + data.type_check <= IS_DIFFERENT; + data.type_check++) { + for (i = data.w_prev_start; i < data.w_prev_end; i++) { + OSSL_DECODER_INSTANCE *decoder_inst = + sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i); + + data.output_type + = OSSL_DECODER_INSTANCE_get_input_type(decoder_inst); + + + for (j = 0; j < numdecoders; j++) + collect_extra_decoder(sk_OSSL_DECODER_value(skdecoders, j), + &data); + } + } + /* How many were added in this iteration */ + count = data.w_new_end - data.w_new_start; + + /* Slide the "previous decoder" windows */ + data.w_prev_start = data.w_new_start; + data.w_prev_end = data.w_new_end; + + depth++; + } while (count != 0 && depth <= 10); + + sk_OSSL_DECODER_pop_free(skdecoders, OSSL_DECODER_free); + return 1; +} + +int OSSL_DECODER_CTX_get_num_decoders(OSSL_DECODER_CTX *ctx) +{ + if (ctx == NULL || ctx->decoder_insts == NULL) + return 0; + return sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts); +} + +int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_CONSTRUCT *construct) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->construct = construct; + return 1; +} + +int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx, + void *construct_data) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->construct_data = construct_data; + return 1; +} + +int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_CLEANUP *cleanup) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->cleanup = cleanup; + return 1; +} + +OSSL_DECODER_CONSTRUCT * +OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + return ctx->construct; +} + +void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + return ctx->construct_data; +} + +OSSL_DECODER_CLEANUP * +OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + return ctx->cleanup; +} + +int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst, + void *reference, size_t reference_sz, + OSSL_CALLBACK *export_cb, void *export_cbarg) +{ + OSSL_DECODER *decoder = NULL; + void *decoderctx = NULL; + + if (!(ossl_assert(decoder_inst != NULL) + && ossl_assert(reference != NULL) + && ossl_assert(export_cb != NULL) + && ossl_assert(export_cbarg != NULL))) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); + decoderctx = OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst); + return decoder->export_object(decoderctx, reference, reference_sz, + export_cb, export_cbarg); +} + +OSSL_DECODER * +OSSL_DECODER_INSTANCE_get_decoder(OSSL_DECODER_INSTANCE *decoder_inst) +{ + if (decoder_inst == NULL) + return NULL; + return decoder_inst->decoder; +} + +void * +OSSL_DECODER_INSTANCE_get_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst) +{ + if (decoder_inst == NULL) + return NULL; + return decoder_inst->decoderctx; +} + +const char * +OSSL_DECODER_INSTANCE_get_input_type(OSSL_DECODER_INSTANCE *decoder_inst) +{ + if (decoder_inst == NULL) + return NULL; + return decoder_inst->input_type; +} + +const char * +OSSL_DECODER_INSTANCE_get_input_structure(OSSL_DECODER_INSTANCE *decoder_inst, + int *was_set) +{ + if (decoder_inst == NULL) + return NULL; + *was_set = decoder_inst->flag_input_structure_was_set; + return decoder_inst->input_structure; +} + +static int decoder_process(const OSSL_PARAM params[], void *arg) +{ + struct decoder_process_data_st *data = arg; + OSSL_DECODER_CTX *ctx = data->ctx; + OSSL_DECODER_INSTANCE *decoder_inst = NULL; + OSSL_DECODER *decoder = NULL; + OSSL_CORE_BIO *cbio = NULL; + BIO *bio = data->bio; + long loc; + size_t i; + int ok = 0; + /* For recursions */ + struct decoder_process_data_st new_data; + const char *data_type = NULL; + const char *data_structure = NULL; + + /* + * This is an indicator up the call stack that something was indeed + * decoded, leading to a recursive call of this function. + */ + data->flag_next_level_called = 1; + + memset(&new_data, 0, sizeof(new_data)); + new_data.ctx = data->ctx; + new_data.recursion = data->recursion + 1; + +#define LEVEL_STR ">>>>>>>>>>>>>>>>" +#define LEVEL (new_data.recursion < sizeof(LEVEL_STR) \ + ? &LEVEL_STR[sizeof(LEVEL_STR) - new_data.recursion - 1] \ + : LEVEL_STR "...") + + if (params == NULL) { + /* First iteration, where we prepare for what is to come */ + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) starting to walk the decoder chain\n", + (void *)new_data.ctx); + } OSSL_TRACE_END(DECODER); + + data->current_decoder_inst_index = + OSSL_DECODER_CTX_get_num_decoders(ctx); + + bio = data->bio; + } else { + const OSSL_PARAM *p; + const char *trace_data_structure; + + decoder_inst = + sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, + data->current_decoder_inst_index); + decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); + + data->flag_construct_called = 0; + if (ctx->construct != NULL) { + int rv; + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) %s Running constructor\n", + (void *)new_data.ctx, LEVEL); + } OSSL_TRACE_END(DECODER); + + rv = ctx->construct(decoder_inst, params, ctx->construct_data); + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) %s Running constructor => %d\n", + (void *)new_data.ctx, LEVEL, rv); + } OSSL_TRACE_END(DECODER); + + data->flag_construct_called = 1; + ok = (rv > 0); + if (ok) + goto end; + } + + /* The constructor didn't return success */ + + /* + * so we try to use the object we got and feed it to any next + * decoder that will take it. Object references are not + * allowed for this. + * If this data isn't present, decoding has failed. + */ + + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA); + if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING) + goto end; + new_data.bio = BIO_new_mem_buf(p->data, (int)p->data_size); + if (new_data.bio == NULL) + goto end; + bio = new_data.bio; + + /* Get the data type if there is one */ + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_TYPE); + if (p != NULL && !OSSL_PARAM_get_utf8_string_ptr(p, &data_type)) + goto end; + + /* Get the data structure if there is one */ + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_STRUCTURE); + if (p != NULL && !OSSL_PARAM_get_utf8_string_ptr(p, &data_structure)) + goto end; + + /* + * If the data structure is "type-specific" and the data type is + * given, we drop the data structure. The reasoning is that the + * data type is already enough to find the applicable next decoder, + * so an additional "type-specific" data structure is extraneous. + * + * Furthermore, if the OSSL_DECODER caller asked for a type specific + * structure under another name, such as "DH", we get a mismatch + * if the data structure we just received is "type-specific". + * There's only so much you can do without infusing this code with + * too special knowledge. + */ + trace_data_structure = data_structure; + if (data_type != NULL && data_structure != NULL + && OPENSSL_strcasecmp(data_structure, "type-specific") == 0) + data_structure = NULL; + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) %s incoming from previous decoder (%p):\n" + " data type: %s, data structure: %s%s\n", + (void *)new_data.ctx, LEVEL, (void *)decoder, + data_type, trace_data_structure, + (trace_data_structure == data_structure + ? "" : " (dropped)")); + } OSSL_TRACE_END(DECODER); + } + + /* + * If we have no more decoders to look through at this point, + * we failed + */ + if (data->current_decoder_inst_index == 0) + goto end; + + if ((loc = BIO_tell(bio)) < 0) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_BIO_LIB); + goto end; + } + + if ((cbio = ossl_core_bio_new_from_bio(bio)) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + goto end; + } + + for (i = data->current_decoder_inst_index; i-- > 0;) { + OSSL_DECODER_INSTANCE *new_decoder_inst = + sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i); + OSSL_DECODER *new_decoder = + OSSL_DECODER_INSTANCE_get_decoder(new_decoder_inst); + void *new_decoderctx = + OSSL_DECODER_INSTANCE_get_decoder_ctx(new_decoder_inst); + const char *new_input_type = + OSSL_DECODER_INSTANCE_get_input_type(new_decoder_inst); + int n_i_s_was_set = 0; /* We don't care here */ + const char *new_input_structure = + OSSL_DECODER_INSTANCE_get_input_structure(new_decoder_inst, + &n_i_s_was_set); + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) %s [%u] Considering decoder instance %p (decoder %p):\n" + " %s with %s\n", + (void *)new_data.ctx, LEVEL, (unsigned int)i, + (void *)new_decoder_inst, (void *)new_decoder, + OSSL_DECODER_get0_name(new_decoder), + OSSL_DECODER_get0_properties(new_decoder)); + } OSSL_TRACE_END(DECODER); + + /* + * If |decoder| is NULL, it means we've just started, and the caller + * may have specified what it expects the initial input to be. If + * that's the case, we do this extra check. + */ + if (decoder == NULL && ctx->start_input_type != NULL + && OPENSSL_strcasecmp(ctx->start_input_type, new_input_type) != 0) { + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) %s [%u] the start input type '%s' doesn't match the input type of the considered decoder, skipping...\n", + (void *)new_data.ctx, LEVEL, (unsigned int)i, + ctx->start_input_type); + } OSSL_TRACE_END(DECODER); + continue; + } + + /* + * If we have a previous decoder, we check that the input type + * of the next to be used matches the type of this previous one. + * |new_input_type| holds the value of the "input-type" parameter + * for the decoder we're currently considering. + */ + if (decoder != NULL && !OSSL_DECODER_is_a(decoder, new_input_type)) { + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) %s [%u] the input type doesn't match the name of the previous decoder (%p), skipping...\n", + (void *)new_data.ctx, LEVEL, (unsigned int)i, + (void *)decoder); + } OSSL_TRACE_END(DECODER); + continue; + } + + /* + * If the previous decoder gave us a data type, we check to see + * if that matches the decoder we're currently considering. + */ + if (data_type != NULL && !OSSL_DECODER_is_a(new_decoder, data_type)) { + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) %s [%u] the previous decoder's data type doesn't match the name of the considered decoder, skipping...\n", + (void *)new_data.ctx, LEVEL, (unsigned int)i); + } OSSL_TRACE_END(DECODER); + continue; + } + + /* + * If the previous decoder gave us a data structure name, we check + * to see that it matches the input data structure of the decoder + * we're currently considering. + */ + if (data_structure != NULL + && (new_input_structure == NULL + || OPENSSL_strcasecmp(data_structure, + new_input_structure) != 0)) { + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) %s [%u] the previous decoder's data structure doesn't match the input structure of the considered decoder, skipping...\n", + (void *)new_data.ctx, LEVEL, (unsigned int)i); + } OSSL_TRACE_END(DECODER); + continue; + } + + /* + * If the decoder we're currently considering specifies a structure, + * and this check hasn't already been done earlier in this chain of + * decoder_process() calls, check that it matches the user provided + * input structure, if one is given. + */ + if (!data->flag_input_structure_checked + && ctx->input_structure != NULL + && new_input_structure != NULL) { + data->flag_input_structure_checked = 1; + if (OPENSSL_strcasecmp(new_input_structure, + ctx->input_structure) != 0) { + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) %s [%u] the previous decoder's data structure doesn't match the input structure given by the user, skipping...\n", + (void *)new_data.ctx, LEVEL, (unsigned int)i); + } OSSL_TRACE_END(DECODER); + continue; + } + } + + /* + * Checking the return value of BIO_reset() or BIO_seek() is unsafe. + * Furthermore, BIO_reset() is unsafe to use if the source BIO happens + * to be a BIO_s_mem(), because the earlier BIO_tell() gives us zero + * no matter where we are in the underlying buffer we're reading from. + * + * So, we simply do a BIO_seek(), and use BIO_tell() that we're back + * at the same position. This is a best effort attempt, but BIO_seek() + * and BIO_tell() should come as a pair... + */ + (void)BIO_seek(bio, loc); + if (BIO_tell(bio) != loc) + goto end; + + /* Recurse */ + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) %s [%u] Running decoder instance %p\n", + (void *)new_data.ctx, LEVEL, (unsigned int)i, + (void *)new_decoder_inst); + } OSSL_TRACE_END(DECODER); + + /* + * We only care about errors reported from decoder implementations + * if it returns false (i.e. there was a fatal error). + */ + ERR_set_mark(); + + new_data.current_decoder_inst_index = i; + new_data.flag_input_structure_checked + = data->flag_input_structure_checked; + ok = new_decoder->decode(new_decoderctx, cbio, + new_data.ctx->selection, + decoder_process, &new_data, + ossl_pw_passphrase_callback_dec, + &new_data.ctx->pwdata); + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) %s [%u] Running decoder instance %p => %d" + " (recursed further: %s, construct called: %s)\n", + (void *)new_data.ctx, LEVEL, (unsigned int)i, + (void *)new_decoder_inst, ok, + new_data.flag_next_level_called ? "yes" : "no", + new_data.flag_construct_called ? "yes" : "no"); + } OSSL_TRACE_END(DECODER); + + data->flag_construct_called = new_data.flag_construct_called; + + /* Break on error or if we tried to construct an object already */ + if (!ok || data->flag_construct_called) { + ERR_clear_last_mark(); + break; + } + ERR_pop_to_mark(); + + /* + * Break if the decoder implementation that we called recursed, since + * that indicates that it successfully decoded something. + */ + if (new_data.flag_next_level_called) + break; + } + + end: + ossl_core_bio_free(cbio); + BIO_free(new_data.bio); + return ok; +} diff --git a/crypto/openssl/crypto/encode_decode/decoder_meth.c b/crypto/openssl/crypto/encode_decode/decoder_meth.c new file mode 100644 index 000000000000..56899a926981 --- /dev/null +++ b/crypto/openssl/crypto/encode_decode/decoder_meth.c @@ -0,0 +1,701 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/core.h" +#include "internal/namemap.h" +#include "internal/property.h" +#include "internal/provider.h" +#include "crypto/decoder.h" +#include "encoder_local.h" + +/* + * Decoder can have multiple names, separated with colons in a name string + */ +#define NAME_SEPARATOR ':' + +/* Simple method structure constructor and destructor */ +static OSSL_DECODER *ossl_decoder_new(void) +{ + OSSL_DECODER *decoder = NULL; + + if ((decoder = OPENSSL_zalloc(sizeof(*decoder))) == NULL + || (decoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) { + OSSL_DECODER_free(decoder); + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return NULL; + } + + decoder->base.refcnt = 1; + + return decoder; +} + +int OSSL_DECODER_up_ref(OSSL_DECODER *decoder) +{ + int ref = 0; + + CRYPTO_UP_REF(&decoder->base.refcnt, &ref, decoder->base.lock); + return 1; +} + +void OSSL_DECODER_free(OSSL_DECODER *decoder) +{ + int ref = 0; + + if (decoder == NULL) + return; + + CRYPTO_DOWN_REF(&decoder->base.refcnt, &ref, decoder->base.lock); + if (ref > 0) + return; + OPENSSL_free(decoder->base.name); + ossl_property_free(decoder->base.parsed_propdef); + ossl_provider_free(decoder->base.prov); + CRYPTO_THREAD_lock_free(decoder->base.lock); + OPENSSL_free(decoder); +} + +/* Permanent decoder method store, constructor and destructor */ +static void decoder_store_free(void *vstore) +{ + ossl_method_store_free(vstore); +} + +static void *decoder_store_new(OSSL_LIB_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + +static const OSSL_LIB_CTX_METHOD decoder_store_method = { + /* We want decoder_store to be cleaned up before the provider store */ + OSSL_LIB_CTX_METHOD_PRIORITY_2, + decoder_store_new, + decoder_store_free, +}; + +/* Data to be passed through ossl_method_construct() */ +struct decoder_data_st { + OSSL_LIB_CTX *libctx; + int id; /* For get_decoder_from_store() */ + const char *names; /* For get_decoder_from_store() */ + const char *propquery; /* For get_decoder_from_store() */ + + OSSL_METHOD_STORE *tmp_store; /* For get_tmp_decoder_store() */ + + unsigned int flag_construct_error_occurred : 1; +}; + +/* + * Generic routines to fetch / create DECODER methods with + * ossl_method_construct() + */ + +/* Temporary decoder method store, constructor and destructor */ +static void *get_tmp_decoder_store(void *data) +{ + struct decoder_data_st *methdata = data; + + if (methdata->tmp_store == NULL) + methdata->tmp_store = ossl_method_store_new(methdata->libctx); + return methdata->tmp_store; +} + +static void dealloc_tmp_decoder_store(void *store) +{ + if (store != NULL) + ossl_method_store_free(store); +} + +/* Get the permanent decoder store */ +static OSSL_METHOD_STORE *get_decoder_store(OSSL_LIB_CTX *libctx) +{ + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_STORE_INDEX, + &decoder_store_method); +} + +static int reserve_decoder_store(void *store, void *data) +{ + struct decoder_data_st *methdata = data; + + if (store == NULL + && (store = get_decoder_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_lock_store(store); +} + +static int unreserve_decoder_store(void *store, void *data) +{ + struct decoder_data_st *methdata = data; + + if (store == NULL + && (store = get_decoder_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_unlock_store(store); +} + +/* Get decoder methods from a store, or put one in */ +static void *get_decoder_from_store(void *store, const OSSL_PROVIDER **prov, + void *data) +{ + struct decoder_data_st *methdata = data; + void *method = NULL; + int id; + + /* + * get_decoder_from_store() is only called to try and get the method + * that OSSL_DECODER_fetch() is asking for, and the name or name id are + * passed via methdata. + */ + if ((id = methdata->id) == 0 && methdata->names != NULL) { + OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx); + const char *names = methdata->names; + const char *q = strchr(names, NAME_SEPARATOR); + size_t l = (q == NULL ? strlen(names) : (size_t)(q - names)); + + if (namemap == 0) + return NULL; + id = ossl_namemap_name2num_n(namemap, names, l); + } + + if (id == 0) + return NULL; + + if (store == NULL + && (store = get_decoder_store(methdata->libctx)) == NULL) + return NULL; + + if (!ossl_method_store_fetch(store, id, methdata->propquery, prov, &method)) + return NULL; + return method; +} + +static int put_decoder_in_store(void *store, void *method, + const OSSL_PROVIDER *prov, + const char *names, const char *propdef, + void *data) +{ + struct decoder_data_st *methdata = data; + OSSL_NAMEMAP *namemap; + int id; + size_t l = 0; + + /* + * put_decoder_in_store() is only called with an OSSL_DECODER method that + * was successfully created by construct_decoder() below, which means that + * all the names should already be stored in the namemap with the same + * numeric identity, so just use the first to get that identity. + */ + if (names != NULL) { + const char *q = strchr(names, NAME_SEPARATOR); + + l = (q == NULL ? strlen(names) : (size_t)(q - names)); + } + + if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL + || (id = ossl_namemap_name2num_n(namemap, names, l)) == 0) + return 0; + + if (store == NULL && (store = get_decoder_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_store_add(store, prov, id, propdef, method, + (int (*)(void *))OSSL_DECODER_up_ref, + (void (*)(void *))OSSL_DECODER_free); +} + +/* Create and populate a decoder method */ +void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + OSSL_DECODER *decoder = NULL; + const OSSL_DISPATCH *fns = algodef->implementation; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + + if ((decoder = ossl_decoder_new()) == NULL) + return NULL; + decoder->base.id = id; + if ((decoder->base.name = ossl_algorithm_get1_first_name(algodef)) == NULL) { + OSSL_DECODER_free(decoder); + return NULL; + } + decoder->base.algodef = algodef; + if ((decoder->base.parsed_propdef + = ossl_parse_property(libctx, algodef->property_definition)) == NULL) { + OSSL_DECODER_free(decoder); + return NULL; + } + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_DECODER_NEWCTX: + if (decoder->newctx == NULL) + decoder->newctx = OSSL_FUNC_decoder_newctx(fns); + break; + case OSSL_FUNC_DECODER_FREECTX: + if (decoder->freectx == NULL) + decoder->freectx = OSSL_FUNC_decoder_freectx(fns); + break; + case OSSL_FUNC_DECODER_GET_PARAMS: + if (decoder->get_params == NULL) + decoder->get_params = + OSSL_FUNC_decoder_get_params(fns); + break; + case OSSL_FUNC_DECODER_GETTABLE_PARAMS: + if (decoder->gettable_params == NULL) + decoder->gettable_params = + OSSL_FUNC_decoder_gettable_params(fns); + break; + case OSSL_FUNC_DECODER_SET_CTX_PARAMS: + if (decoder->set_ctx_params == NULL) + decoder->set_ctx_params = + OSSL_FUNC_decoder_set_ctx_params(fns); + break; + case OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS: + if (decoder->settable_ctx_params == NULL) + decoder->settable_ctx_params = + OSSL_FUNC_decoder_settable_ctx_params(fns); + break; + case OSSL_FUNC_DECODER_DOES_SELECTION: + if (decoder->does_selection == NULL) + decoder->does_selection = + OSSL_FUNC_decoder_does_selection(fns); + break; + case OSSL_FUNC_DECODER_DECODE: + if (decoder->decode == NULL) + decoder->decode = OSSL_FUNC_decoder_decode(fns); + break; + case OSSL_FUNC_DECODER_EXPORT_OBJECT: + if (decoder->export_object == NULL) + decoder->export_object = OSSL_FUNC_decoder_export_object(fns); + break; + } + } + /* + * Try to check that the method is sensible. + * If you have a constructor, you must have a destructor and vice versa. + * You must have at least one of the encoding driver functions. + */ + if (!((decoder->newctx == NULL && decoder->freectx == NULL) + || (decoder->newctx != NULL && decoder->freectx != NULL)) + || decoder->decode == NULL) { + OSSL_DECODER_free(decoder); + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + + if (prov != NULL && !ossl_provider_up_ref(prov)) { + OSSL_DECODER_free(decoder); + return NULL; + } + + decoder->base.prov = prov; + return decoder; +} + + +/* + * The core fetching functionality passes the names of the implementation. + * This function is responsible to getting an identity number for them, + * then call ossl_decoder_from_algorithm() with that identity number. + */ +static void *construct_decoder(const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov, void *data) +{ + /* + * This function is only called if get_decoder_from_store() returned + * NULL, so it's safe to say that of all the spots to create a new + * namemap entry, this is it. Should the name already exist there, we + * know that ossl_namemap_add() will return its corresponding number. + */ + struct decoder_data_st *methdata = data; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *names = algodef->algorithm_names; + int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); + void *method = NULL; + + if (id != 0) + method = ossl_decoder_from_algorithm(id, algodef, prov); + + /* + * Flag to indicate that there was actual construction errors. This + * helps inner_evp_generic_fetch() determine what error it should + * record on inaccessible algorithms. + */ + if (method == NULL) + methdata->flag_construct_error_occurred = 1; + + return method; +} + +/* Intermediary function to avoid ugly casts, used below */ +static void destruct_decoder(void *method, void *data) +{ + OSSL_DECODER_free(method); +} + +static int up_ref_decoder(void *method) +{ + return OSSL_DECODER_up_ref(method); +} + +static void free_decoder(void *method) +{ + OSSL_DECODER_free(method); +} + +/* Fetching support. Can fetch by numeric identity or by name */ +static OSSL_DECODER * +inner_ossl_decoder_fetch(struct decoder_data_st *methdata, int id, + const char *name, const char *properties) +{ + OSSL_METHOD_STORE *store = get_decoder_store(methdata->libctx); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx); + const char *const propq = properties != NULL ? properties : ""; + void *method = NULL; + int unsupported = 0; + + if (store == NULL || namemap == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + + /* + * If we have been passed both an id and a name, we have an + * internal programming error. + */ + if (!ossl_assert(id == 0 || name == NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR); + return NULL; + } + + if (id == 0 && name != NULL) + id = ossl_namemap_name2num(namemap, name); + + /* + * If we haven't found the name yet, chances are that the algorithm to + * be fetched is unsupported. + */ + if (id == 0) + unsupported = 1; + + if (id == 0 + || !ossl_method_store_cache_get(store, NULL, id, propq, &method)) { + OSSL_METHOD_CONSTRUCT_METHOD mcm = { + get_tmp_decoder_store, + reserve_decoder_store, + unreserve_decoder_store, + get_decoder_from_store, + put_decoder_in_store, + construct_decoder, + destruct_decoder + }; + OSSL_PROVIDER *prov = NULL; + + methdata->id = id; + methdata->names = name; + methdata->propquery = propq; + methdata->flag_construct_error_occurred = 0; + if ((method = ossl_method_construct(methdata->libctx, OSSL_OP_DECODER, + &prov, 0 /* !force_cache */, + &mcm, methdata)) != NULL) { + /* + * If construction did create a method for us, we know that + * there is a correct name_id and meth_id, since those have + * already been calculated in get_decoder_from_store() and + * put_decoder_in_store() above. + */ + if (id == 0 && name != NULL) + id = ossl_namemap_name2num(namemap, name); + if (id != 0) + ossl_method_store_cache_set(store, prov, id, propq, method, + up_ref_decoder, free_decoder); + } + + /* + * If we never were in the constructor, the algorithm to be fetched + * is unsupported. + */ + unsupported = !methdata->flag_construct_error_occurred; + } + + if ((id != 0 || name != NULL) && method == NULL) { + int code = unsupported ? ERR_R_UNSUPPORTED : ERR_R_FETCH_FAILED; + + if (name == NULL) + name = ossl_namemap_num2name(namemap, id, 0); + ERR_raise_data(ERR_LIB_OSSL_DECODER, code, + "%s, Name (%s : %d), Properties (%s)", + ossl_lib_ctx_get_descriptor(methdata->libctx), + name == NULL ? "" : name, id, + properties == NULL ? "" : properties); + } + + return method; +} + +OSSL_DECODER *OSSL_DECODER_fetch(OSSL_LIB_CTX *libctx, const char *name, + const char *properties) +{ + struct decoder_data_st methdata; + void *method; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + method = inner_ossl_decoder_fetch(&methdata, 0, name, properties); + dealloc_tmp_decoder_store(methdata.tmp_store); + return method; +} + +OSSL_DECODER *ossl_decoder_fetch_by_number(OSSL_LIB_CTX *libctx, int id, + const char *properties) +{ + struct decoder_data_st methdata; + void *method; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + method = inner_ossl_decoder_fetch(&methdata, id, NULL, properties); + dealloc_tmp_decoder_store(methdata.tmp_store); + return method; +} + +int ossl_decoder_store_cache_flush(OSSL_LIB_CTX *libctx) +{ + OSSL_METHOD_STORE *store = get_decoder_store(libctx); + + if (store != NULL) + return ossl_method_store_cache_flush_all(store); + return 1; +} + +int ossl_decoder_store_remove_all_provided(const OSSL_PROVIDER *prov) +{ + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_METHOD_STORE *store = get_decoder_store(libctx); + + if (store != NULL) + return ossl_method_store_remove_all_provided(store, prov); + return 1; +} + +/* + * Library of basic method functions + */ + +const OSSL_PROVIDER *OSSL_DECODER_get0_provider(const OSSL_DECODER *decoder) +{ + if (!ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return decoder->base.prov; +} + +const char *OSSL_DECODER_get0_properties(const OSSL_DECODER *decoder) +{ + if (!ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return decoder->base.algodef->property_definition; +} + +const OSSL_PROPERTY_LIST * +ossl_decoder_parsed_properties(const OSSL_DECODER *decoder) +{ + if (!ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return decoder->base.parsed_propdef; +} + +int ossl_decoder_get_number(const OSSL_DECODER *decoder) +{ + if (!ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return decoder->base.id; +} + +const char *OSSL_DECODER_get0_name(const OSSL_DECODER *decoder) +{ + return decoder->base.name; +} + +const char *OSSL_DECODER_get0_description(const OSSL_DECODER *decoder) +{ + return decoder->base.algodef->algorithm_description; +} + +int OSSL_DECODER_is_a(const OSSL_DECODER *decoder, const char *name) +{ + if (decoder->base.prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(decoder->base.prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_name2num(namemap, name) == decoder->base.id; + } + return 0; +} + +struct do_one_data_st { + void (*user_fn)(OSSL_DECODER *decoder, void *arg); + void *user_arg; +}; + +static void do_one(ossl_unused int id, void *method, void *arg) +{ + struct do_one_data_st *data = arg; + + data->user_fn(method, data->user_arg); +} + +void OSSL_DECODER_do_all_provided(OSSL_LIB_CTX *libctx, + void (*user_fn)(OSSL_DECODER *decoder, + void *arg), + void *user_arg) +{ + struct decoder_data_st methdata; + struct do_one_data_st data; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + (void)inner_ossl_decoder_fetch(&methdata, 0, NULL, NULL /* properties */); + + data.user_fn = user_fn; + data.user_arg = user_arg; + if (methdata.tmp_store != NULL) + ossl_method_store_do_all(methdata.tmp_store, &do_one, &data); + ossl_method_store_do_all(get_decoder_store(libctx), &do_one, &data); + dealloc_tmp_decoder_store(methdata.tmp_store); +} + +int OSSL_DECODER_names_do_all(const OSSL_DECODER *decoder, + void (*fn)(const char *name, void *data), + void *data) +{ + if (decoder == NULL) + return 0; + + if (decoder->base.prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(decoder->base.prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_doall_names(namemap, decoder->base.id, fn, data); + } + + return 1; +} + +const OSSL_PARAM * +OSSL_DECODER_gettable_params(OSSL_DECODER *decoder) +{ + if (decoder != NULL && decoder->gettable_params != NULL) { + void *provctx = ossl_provider_ctx(OSSL_DECODER_get0_provider(decoder)); + + return decoder->gettable_params(provctx); + } + return NULL; +} + +int OSSL_DECODER_get_params(OSSL_DECODER *decoder, OSSL_PARAM params[]) +{ + if (decoder != NULL && decoder->get_params != NULL) + return decoder->get_params(params); + return 0; +} + +const OSSL_PARAM * +OSSL_DECODER_settable_ctx_params(OSSL_DECODER *decoder) +{ + if (decoder != NULL && decoder->settable_ctx_params != NULL) { + void *provctx = ossl_provider_ctx(OSSL_DECODER_get0_provider(decoder)); + + return decoder->settable_ctx_params(provctx); + } + return NULL; +} + +/* + * Decoder context support + */ + +/* + * |encoder| value NULL is valid, and signifies that there is no decoder. + * This is useful to provide fallback mechanisms. + * Functions that want to verify if there is a decoder can do so with + * OSSL_DECODER_CTX_get_decoder() + */ +OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(void) +{ + OSSL_DECODER_CTX *ctx; + + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + + return ctx; +} + +int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx, + const OSSL_PARAM params[]) +{ + int ok = 1; + size_t i; + size_t l; + + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (ctx->decoder_insts == NULL) + return 1; + + l = OSSL_DECODER_CTX_get_num_decoders(ctx); + for (i = 0; i < l; i++) { + OSSL_DECODER_INSTANCE *decoder_inst = + sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i); + OSSL_DECODER *decoder = + OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); + OSSL_DECODER *decoderctx = + OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst); + + if (decoderctx == NULL || decoder->set_ctx_params == NULL) + continue; + if (!decoder->set_ctx_params(decoderctx, params)) + ok = 0; + } + return ok; +} + +void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx) +{ + if (ctx != NULL) { + if (ctx->cleanup != NULL) + ctx->cleanup(ctx->construct_data); + sk_OSSL_DECODER_INSTANCE_pop_free(ctx->decoder_insts, + ossl_decoder_instance_free); + ossl_pw_clear_passphrase_data(&ctx->pwdata); + OPENSSL_free(ctx); + } +} diff --git a/crypto/openssl/crypto/encode_decode/decoder_pkey.c b/crypto/openssl/crypto/encode_decode/decoder_pkey.c new file mode 100644 index 000000000000..ed10bb1cee03 --- /dev/null +++ b/crypto/openssl/crypto/encode_decode/decoder_pkey.c @@ -0,0 +1,462 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "crypto/evp.h" +#include "crypto/decoder.h" +#include "encoder_local.h" + +int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx, + const unsigned char *kstr, + size_t klen) +{ + return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen); +} + +int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx, + const UI_METHOD *ui_method, + void *ui_data) +{ + return ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data); +} + +int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx, + pem_password_cb *cb, void *cbarg) +{ + return ossl_pw_set_pem_password_cb(&ctx->pwdata, cb, cbarg); +} + +int OSSL_DECODER_CTX_set_passphrase_cb(OSSL_DECODER_CTX *ctx, + OSSL_PASSPHRASE_CALLBACK *cb, + void *cbarg) +{ + return ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg); +} + +/* + * Support for OSSL_DECODER_CTX_new_for_pkey: + * The construct data, and collecting keymgmt information for it + */ + +DEFINE_STACK_OF(EVP_KEYMGMT) + +struct decoder_pkey_data_st { + OSSL_LIB_CTX *libctx; + char *propq; + int selection; + + STACK_OF(EVP_KEYMGMT) *keymgmts; + char *object_type; /* recorded object data type, may be NULL */ + void **object; /* Where the result should end up */ +}; + +static int decoder_construct_pkey(OSSL_DECODER_INSTANCE *decoder_inst, + const OSSL_PARAM *params, + void *construct_data) +{ + struct decoder_pkey_data_st *data = construct_data; + OSSL_DECODER *decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); + void *decoderctx = OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst); + const OSSL_PROVIDER *decoder_prov = OSSL_DECODER_get0_provider(decoder); + EVP_KEYMGMT *keymgmt = NULL; + const OSSL_PROVIDER *keymgmt_prov = NULL; + int i, end; + /* + * |object_ref| points to a provider reference to an object, its exact + * contents entirely opaque to us, but may be passed to any provider + * function that expects this (such as OSSL_FUNC_keymgmt_load(). + * + * This pointer is considered volatile, i.e. whatever it points at + * is assumed to be freed as soon as this function returns. + */ + void *object_ref = NULL; + size_t object_ref_sz = 0; + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_TYPE); + if (p != NULL) { + char *object_type = NULL; + + if (!OSSL_PARAM_get_utf8_string(p, &object_type, 0)) + return 0; + OPENSSL_free(data->object_type); + data->object_type = object_type; + } + + /* + * For stuff that should end up in an EVP_PKEY, we only accept an object + * reference for the moment. This enforces that the key data itself + * remains with the provider. + */ + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_REFERENCE); + if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING) + return 0; + object_ref = p->data; + object_ref_sz = p->data_size; + + /* + * First, we try to find a keymgmt that comes from the same provider as + * the decoder that passed the params. + */ + end = sk_EVP_KEYMGMT_num(data->keymgmts); + for (i = 0; i < end; i++) { + keymgmt = sk_EVP_KEYMGMT_value(data->keymgmts, i); + keymgmt_prov = EVP_KEYMGMT_get0_provider(keymgmt); + + if (keymgmt_prov == decoder_prov + && evp_keymgmt_has_load(keymgmt) + && EVP_KEYMGMT_is_a(keymgmt, data->object_type)) + break; + } + if (i < end) { + /* To allow it to be freed further down */ + if (!EVP_KEYMGMT_up_ref(keymgmt)) + return 0; + } else if ((keymgmt = EVP_KEYMGMT_fetch(data->libctx, + data->object_type, + data->propq)) != NULL) { + keymgmt_prov = EVP_KEYMGMT_get0_provider(keymgmt); + } + + if (keymgmt != NULL) { + EVP_PKEY *pkey = NULL; + void *keydata = NULL; + + /* + * If the EVP_KEYMGMT and the OSSL_DECODER are from the + * same provider, we assume that the KEYMGMT has a key loading + * function that can handle the provider reference we hold. + * + * Otherwise, we export from the decoder and import the + * result in the keymgmt. + */ + if (keymgmt_prov == decoder_prov) { + keydata = evp_keymgmt_load(keymgmt, object_ref, object_ref_sz); + } else { + struct evp_keymgmt_util_try_import_data_st import_data; + + import_data.keymgmt = keymgmt; + import_data.keydata = NULL; + import_data.selection = data->selection; + + /* + * No need to check for errors here, the value of + * |import_data.keydata| is as much an indicator. + */ + (void)decoder->export_object(decoderctx, + object_ref, object_ref_sz, + &evp_keymgmt_util_try_import, + &import_data); + keydata = import_data.keydata; + import_data.keydata = NULL; + } + + if (keydata != NULL + && (pkey = evp_keymgmt_util_make_pkey(keymgmt, keydata)) == NULL) + evp_keymgmt_freedata(keymgmt, keydata); + + *data->object = pkey; + + /* + * evp_keymgmt_util_make_pkey() increments the reference count when + * assigning the EVP_PKEY, so we can free the keymgmt here. + */ + EVP_KEYMGMT_free(keymgmt); + } + /* + * We successfully looked through, |*ctx->object| determines if we + * actually found something. + */ + return (*data->object != NULL); +} + +static void decoder_clean_pkey_construct_arg(void *construct_data) +{ + struct decoder_pkey_data_st *data = construct_data; + + if (data != NULL) { + sk_EVP_KEYMGMT_pop_free(data->keymgmts, EVP_KEYMGMT_free); + OPENSSL_free(data->propq); + OPENSSL_free(data->object_type); + OPENSSL_free(data); + } +} + +static void collect_name(const char *name, void *arg) +{ + STACK_OF(OPENSSL_CSTRING) *names = arg; + + sk_OPENSSL_CSTRING_push(names, name); +} + +static void collect_keymgmt(EVP_KEYMGMT *keymgmt, void *arg) +{ + STACK_OF(EVP_KEYMGMT) *keymgmts = arg; + + if (!EVP_KEYMGMT_up_ref(keymgmt) /* ref++ */) + return; + if (sk_EVP_KEYMGMT_push(keymgmts, keymgmt) <= 0) { + EVP_KEYMGMT_free(keymgmt); /* ref-- */ + return; + } +} + +struct collect_decoder_data_st { + STACK_OF(OPENSSL_CSTRING) *names; + OSSL_DECODER_CTX *ctx; + + int total; + unsigned int error_occurred:1; +}; + +static void collect_decoder(OSSL_DECODER *decoder, void *arg) +{ + struct collect_decoder_data_st *data = arg; + size_t i, end_i; + const OSSL_PROVIDER *prov = OSSL_DECODER_get0_provider(decoder); + void *provctx = OSSL_PROVIDER_get0_provider_ctx(prov); + + if (data->error_occurred) + return; + + if (data->names == NULL) { + data->error_occurred = 1; + return; + } + + /* + * Either the caller didn't give a selection, or if they did, + * the decoder must tell us if it supports that selection to + * be accepted. If the decoder doesn't have |does_selection|, + * it's seen as taking anything. + */ + if (decoder->does_selection != NULL + && !decoder->does_selection(provctx, data->ctx->selection)) + return; + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) Checking out decoder %p:\n" + " %s with %s\n", + (void *)data->ctx, (void *)decoder, + OSSL_DECODER_get0_name(decoder), + OSSL_DECODER_get0_properties(decoder)); + } OSSL_TRACE_END(DECODER); + + end_i = sk_OPENSSL_CSTRING_num(data->names); + for (i = 0; i < end_i; i++) { + const char *name = sk_OPENSSL_CSTRING_value(data->names, i); + + if (OSSL_DECODER_is_a(decoder, name)) { + void *decoderctx = NULL; + OSSL_DECODER_INSTANCE *di = NULL; + + if ((decoderctx = decoder->newctx(provctx)) == NULL) { + data->error_occurred = 1; + return; + } + if ((di = ossl_decoder_instance_new(decoder, decoderctx)) == NULL) { + decoder->freectx(decoderctx); + data->error_occurred = 1; + return; + } + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) Checking out decoder %p:\n" + " %s with %s\n", + (void *)data->ctx, (void *)decoder, + OSSL_DECODER_get0_name(decoder), + OSSL_DECODER_get0_properties(decoder)); + } OSSL_TRACE_END(DECODER); + + if (!ossl_decoder_ctx_add_decoder_inst(data->ctx, di)) { + ossl_decoder_instance_free(di); + data->error_occurred = 1; + return; + } + data->total++; + + /* Success */ + return; + } + } + + /* Decoder not suitable - but not a fatal error */ + data->error_occurred = 0; +} + +int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx, + EVP_PKEY **pkey, const char *keytype, + OSSL_LIB_CTX *libctx, + const char *propquery) +{ + struct decoder_pkey_data_st *process_data = NULL; + STACK_OF(OPENSSL_CSTRING) *names = NULL; + const char *input_type = ctx->start_input_type; + const char *input_structure = ctx->input_structure; + int ok = 0; + int isecoid = 0; + int i, end; + + if (keytype != NULL + && (strcmp(keytype, "id-ecPublicKey") == 0 + || strcmp(keytype, "1.2.840.10045.2.1") == 0)) + isecoid = 1; + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) Looking for decoders producing %s%s%s%s%s%s\n", + (void *)ctx, + keytype != NULL ? keytype : "", + keytype != NULL ? " keys" : "keys of any type", + input_type != NULL ? " from " : "", + input_type != NULL ? input_type : "", + input_structure != NULL ? " with " : "", + input_structure != NULL ? input_structure : ""); + } OSSL_TRACE_END(DECODER); + + if ((process_data = OPENSSL_zalloc(sizeof(*process_data))) == NULL + || (propquery != NULL + && (process_data->propq = OPENSSL_strdup(propquery)) == NULL) + || (process_data->keymgmts = sk_EVP_KEYMGMT_new_null()) == NULL + || (names = sk_OPENSSL_CSTRING_new_null()) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + goto err; + } + + process_data->object = (void **)pkey; + process_data->libctx = libctx; + process_data->selection = ctx->selection; + + /* First, find all keymgmts to form goals */ + EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, + process_data->keymgmts); + + /* Then, we collect all the keymgmt names */ + end = sk_EVP_KEYMGMT_num(process_data->keymgmts); + for (i = 0; i < end; i++) { + EVP_KEYMGMT *keymgmt = sk_EVP_KEYMGMT_value(process_data->keymgmts, i); + + /* + * If the key type is given by the caller, we only use the matching + * KEYMGMTs, otherwise we use them all. + * We have to special case SM2 here because of its abuse of the EC OID. + * The EC OID can be used to identify an EC key or an SM2 key - so if + * we have seen that OID we try both key types + */ + if (keytype == NULL + || EVP_KEYMGMT_is_a(keymgmt, keytype) + || (isecoid && EVP_KEYMGMT_is_a(keymgmt, "SM2"))) { + if (!EVP_KEYMGMT_names_do_all(keymgmt, collect_name, names)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR); + goto err; + } + } + } + + OSSL_TRACE_BEGIN(DECODER) { + end = sk_OPENSSL_CSTRING_num(names); + BIO_printf(trc_out, + " Found %d keytypes (possibly with duplicates)", + end); + for (i = 0; i < end; i++) + BIO_printf(trc_out, "%s%s", + i == 0 ? ": " : ", ", + sk_OPENSSL_CSTRING_value(names, i)); + BIO_printf(trc_out, "\n"); + } OSSL_TRACE_END(DECODER); + + /* + * Finally, find all decoders that have any keymgmt of the collected + * keymgmt names + */ + { + struct collect_decoder_data_st collect_decoder_data = { NULL, }; + + collect_decoder_data.names = names; + collect_decoder_data.ctx = ctx; + OSSL_DECODER_do_all_provided(libctx, + collect_decoder, &collect_decoder_data); + sk_OPENSSL_CSTRING_free(names); + names = NULL; + + if (collect_decoder_data.error_occurred) + goto err; + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) Got %d decoders producing keys\n", + (void *)ctx, collect_decoder_data.total); + } OSSL_TRACE_END(DECODER); + } + + if (OSSL_DECODER_CTX_get_num_decoders(ctx) != 0) { + if (!OSSL_DECODER_CTX_set_construct(ctx, decoder_construct_pkey) + || !OSSL_DECODER_CTX_set_construct_data(ctx, process_data) + || !OSSL_DECODER_CTX_set_cleanup(ctx, + decoder_clean_pkey_construct_arg)) + goto err; + + process_data = NULL; /* Avoid it being freed */ + } + + ok = 1; + err: + decoder_clean_pkey_construct_arg(process_data); + sk_OPENSSL_CSTRING_free(names); + + return ok; +} + +OSSL_DECODER_CTX * +OSSL_DECODER_CTX_new_for_pkey(EVP_PKEY **pkey, + const char *input_type, + const char *input_structure, + const char *keytype, int selection, + OSSL_LIB_CTX *libctx, const char *propquery) +{ + OSSL_DECODER_CTX *ctx = NULL; + + if ((ctx = OSSL_DECODER_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, + "(ctx %p) Looking for %s decoders with selection %d\n", + (void *)ctx, keytype, selection); + BIO_printf(trc_out, " input type: %s, input structure: %s\n", + input_type, input_structure); + } OSSL_TRACE_END(DECODER); + + if (OSSL_DECODER_CTX_set_input_type(ctx, input_type) + && OSSL_DECODER_CTX_set_input_structure(ctx, input_structure) + && OSSL_DECODER_CTX_set_selection(ctx, selection) + && ossl_decoder_ctx_setup_for_pkey(ctx, pkey, keytype, + libctx, propquery) + && OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery)) { + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, "(ctx %p) Got %d decoders\n", + (void *)ctx, OSSL_DECODER_CTX_get_num_decoders(ctx)); + } OSSL_TRACE_END(DECODER); + return ctx; + } + + OSSL_DECODER_CTX_free(ctx); + return NULL; +} diff --git a/crypto/openssl/crypto/encode_decode/encoder_err.c b/crypto/openssl/crypto/encode_decode/encoder_err.c new file mode 100644 index 000000000000..a904e87ef2e7 --- /dev/null +++ b/crypto/openssl/crypto/encode_decode/encoder_err.c @@ -0,0 +1,36 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/encodererr.h" + +#ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA OSSL_ENCODER_str_reasons[] = { + {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_ENCODER_NOT_FOUND), + "encoder not found"}, + {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY), + "incorrect property query"}, + {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_MISSING_GET_PARAMS), + "missing get params"}, + {0, NULL} +}; + +#endif + +int ossl_err_load_OSSL_ENCODER_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(OSSL_ENCODER_str_reasons[0].error) == NULL) + ERR_load_strings_const(OSSL_ENCODER_str_reasons); +#endif + return 1; +} diff --git a/crypto/openssl/crypto/encode_decode/encoder_lib.c b/crypto/openssl/crypto/encode_decode/encoder_lib.c new file mode 100644 index 000000000000..7a55c7ab9a27 --- /dev/null +++ b/crypto/openssl/crypto/encode_decode/encoder_lib.c @@ -0,0 +1,674 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include "internal/bio.h" +#include "internal/provider.h" +#include "encoder_local.h" + +struct encoder_process_data_st { + OSSL_ENCODER_CTX *ctx; + + /* Current BIO */ + BIO *bio; + + /* Index of the current encoder instance to be processed */ + int current_encoder_inst_index; + + /* Processing data passed down through recursion */ + int level; /* Recursion level */ + OSSL_ENCODER_INSTANCE *next_encoder_inst; + int count_output_structure; + + /* Processing data passed up through recursion */ + OSSL_ENCODER_INSTANCE *prev_encoder_inst; + unsigned char *running_output; + size_t running_output_length; + /* Data type = the name of the first succeeding encoder implementation */ + const char *data_type; +}; + +static int encoder_process(struct encoder_process_data_st *data); + +int OSSL_ENCODER_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out) +{ + struct encoder_process_data_st data; + + memset(&data, 0, sizeof(data)); + data.ctx = ctx; + data.bio = out; + data.current_encoder_inst_index = OSSL_ENCODER_CTX_get_num_encoders(ctx); + + if (data.current_encoder_inst_index == 0) { + ERR_raise_data(ERR_LIB_OSSL_ENCODER, OSSL_ENCODER_R_ENCODER_NOT_FOUND, + "No encoders were found. For standard encoders you need " + "at least one of the default or base providers " + "available. Did you forget to load them?"); + return 0; + } + + return encoder_process(&data) > 0; +} + +#ifndef OPENSSL_NO_STDIO +static BIO *bio_from_file(FILE *fp) +{ + BIO *b; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_BUF_LIB); + return NULL; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + return b; +} + +int OSSL_ENCODER_to_fp(OSSL_ENCODER_CTX *ctx, FILE *fp) +{ + BIO *b = bio_from_file(fp); + int ret = 0; + + if (b != NULL) + ret = OSSL_ENCODER_to_bio(ctx, b); + + BIO_free(b); + return ret; +} +#endif + +int OSSL_ENCODER_to_data(OSSL_ENCODER_CTX *ctx, unsigned char **pdata, + size_t *pdata_len) +{ + BIO *out; + BUF_MEM *buf = NULL; + int ret = 0; + + if (pdata_len == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + out = BIO_new(BIO_s_mem()); + + if (out != NULL + && OSSL_ENCODER_to_bio(ctx, out) + && BIO_get_mem_ptr(out, &buf) > 0) { + ret = 1; /* Hope for the best. A too small buffer will clear this */ + + if (pdata != NULL && *pdata != NULL) { + if (*pdata_len < buf->length) + /* + * It's tempting to do |*pdata_len = (size_t)buf->length| + * However, it's believed to be confusing more than helpful, + * so we don't. + */ + ret = 0; + else + *pdata_len -= buf->length; + } else { + /* The buffer with the right size is already allocated for us */ + *pdata_len = (size_t)buf->length; + } + + if (ret) { + if (pdata != NULL) { + if (*pdata != NULL) { + memcpy(*pdata, buf->data, buf->length); + *pdata += buf->length; + } else { + /* In this case, we steal the data from BIO_s_mem() */ + *pdata = (unsigned char *)buf->data; + buf->data = NULL; + } + } + } + } + BIO_free(out); + return ret; +} + +int OSSL_ENCODER_CTX_set_selection(OSSL_ENCODER_CTX *ctx, int selection) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!ossl_assert(selection != 0)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + ctx->selection = selection; + return 1; +} + +int OSSL_ENCODER_CTX_set_output_type(OSSL_ENCODER_CTX *ctx, + const char *output_type) +{ + if (!ossl_assert(ctx != NULL) || !ossl_assert(output_type != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + ctx->output_type = output_type; + return 1; +} + +int OSSL_ENCODER_CTX_set_output_structure(OSSL_ENCODER_CTX *ctx, + const char *output_structure) +{ + if (!ossl_assert(ctx != NULL) || !ossl_assert(output_structure != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + ctx->output_structure = output_structure; + return 1; +} + +static OSSL_ENCODER_INSTANCE *ossl_encoder_instance_new(OSSL_ENCODER *encoder, + void *encoderctx) +{ + OSSL_ENCODER_INSTANCE *encoder_inst = NULL; + const OSSL_PROVIDER *prov; + OSSL_LIB_CTX *libctx; + const OSSL_PROPERTY_LIST *props; + const OSSL_PROPERTY_DEFINITION *prop; + + if (!ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((encoder_inst = OPENSSL_zalloc(sizeof(*encoder_inst))) == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!OSSL_ENCODER_up_ref(encoder)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR); + goto err; + } + + prov = OSSL_ENCODER_get0_provider(encoder); + libctx = ossl_provider_libctx(prov); + props = ossl_encoder_parsed_properties(encoder); + if (props == NULL) { + ERR_raise_data(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROPERTY_DEFINITION, + "there are no property definitions with encoder %s", + OSSL_ENCODER_get0_name(encoder)); + goto err; + } + + /* The "output" property is mandatory */ + prop = ossl_property_find_property(props, libctx, "output"); + encoder_inst->output_type = ossl_property_get_string_value(libctx, prop); + if (encoder_inst->output_type == NULL) { + ERR_raise_data(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROPERTY_DEFINITION, + "the mandatory 'output' property is missing " + "for encoder %s (properties: %s)", + OSSL_ENCODER_get0_name(encoder), + OSSL_ENCODER_get0_properties(encoder)); + goto err; + } + + /* The "structure" property is optional */ + prop = ossl_property_find_property(props, libctx, "structure"); + if (prop != NULL) + encoder_inst->output_structure + = ossl_property_get_string_value(libctx, prop); + + encoder_inst->encoder = encoder; + encoder_inst->encoderctx = encoderctx; + return encoder_inst; + err: + ossl_encoder_instance_free(encoder_inst); + return NULL; +} + +void ossl_encoder_instance_free(OSSL_ENCODER_INSTANCE *encoder_inst) +{ + if (encoder_inst != NULL) { + if (encoder_inst->encoder != NULL) + encoder_inst->encoder->freectx(encoder_inst->encoderctx); + encoder_inst->encoderctx = NULL; + OSSL_ENCODER_free(encoder_inst->encoder); + encoder_inst->encoder = NULL; + OPENSSL_free(encoder_inst); + } +} + +static int ossl_encoder_ctx_add_encoder_inst(OSSL_ENCODER_CTX *ctx, + OSSL_ENCODER_INSTANCE *ei) +{ + int ok; + + if (ctx->encoder_insts == NULL + && (ctx->encoder_insts = + sk_OSSL_ENCODER_INSTANCE_new_null()) == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + return 0; + } + + ok = (sk_OSSL_ENCODER_INSTANCE_push(ctx->encoder_insts, ei) > 0); + if (ok) { + OSSL_TRACE_BEGIN(ENCODER) { + BIO_printf(trc_out, + "(ctx %p) Added encoder instance %p (encoder %p):\n" + " %s with %s\n", + (void *)ctx, (void *)ei, (void *)ei->encoder, + OSSL_ENCODER_get0_name(ei->encoder), + OSSL_ENCODER_get0_properties(ei->encoder)); + } OSSL_TRACE_END(ENCODER); + } + return ok; +} + +int OSSL_ENCODER_CTX_add_encoder(OSSL_ENCODER_CTX *ctx, OSSL_ENCODER *encoder) +{ + OSSL_ENCODER_INSTANCE *encoder_inst = NULL; + const OSSL_PROVIDER *prov = NULL; + void *encoderctx = NULL; + void *provctx = NULL; + + if (!ossl_assert(ctx != NULL) || !ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + prov = OSSL_ENCODER_get0_provider(encoder); + provctx = OSSL_PROVIDER_get0_provider_ctx(prov); + + if ((encoderctx = encoder->newctx(provctx)) == NULL + || (encoder_inst = + ossl_encoder_instance_new(encoder, encoderctx)) == NULL) + goto err; + /* Avoid double free of encoderctx on further errors */ + encoderctx = NULL; + + if (!ossl_encoder_ctx_add_encoder_inst(ctx, encoder_inst)) + goto err; + + return 1; + err: + ossl_encoder_instance_free(encoder_inst); + if (encoderctx != NULL) + encoder->freectx(encoderctx); + return 0; +} + +int OSSL_ENCODER_CTX_add_extra(OSSL_ENCODER_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return 1; +} + +int OSSL_ENCODER_CTX_get_num_encoders(OSSL_ENCODER_CTX *ctx) +{ + if (ctx == NULL || ctx->encoder_insts == NULL) + return 0; + return sk_OSSL_ENCODER_INSTANCE_num(ctx->encoder_insts); +} + +int OSSL_ENCODER_CTX_set_construct(OSSL_ENCODER_CTX *ctx, + OSSL_ENCODER_CONSTRUCT *construct) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->construct = construct; + return 1; +} + +int OSSL_ENCODER_CTX_set_construct_data(OSSL_ENCODER_CTX *ctx, + void *construct_data) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->construct_data = construct_data; + return 1; +} + +int OSSL_ENCODER_CTX_set_cleanup(OSSL_ENCODER_CTX *ctx, + OSSL_ENCODER_CLEANUP *cleanup) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->cleanup = cleanup; + return 1; +} + +OSSL_ENCODER * +OSSL_ENCODER_INSTANCE_get_encoder(OSSL_ENCODER_INSTANCE *encoder_inst) +{ + if (encoder_inst == NULL) + return NULL; + return encoder_inst->encoder; +} + +void * +OSSL_ENCODER_INSTANCE_get_encoder_ctx(OSSL_ENCODER_INSTANCE *encoder_inst) +{ + if (encoder_inst == NULL) + return NULL; + return encoder_inst->encoderctx; +} + +const char * +OSSL_ENCODER_INSTANCE_get_output_type(OSSL_ENCODER_INSTANCE *encoder_inst) +{ + if (encoder_inst == NULL) + return NULL; + return encoder_inst->output_type; +} + +const char * +OSSL_ENCODER_INSTANCE_get_output_structure(OSSL_ENCODER_INSTANCE *encoder_inst) +{ + if (encoder_inst == NULL) + return NULL; + return encoder_inst->output_structure; +} + +static int encoder_process(struct encoder_process_data_st *data) +{ + OSSL_ENCODER_INSTANCE *current_encoder_inst = NULL; + OSSL_ENCODER *current_encoder = NULL; + OSSL_ENCODER_CTX *current_encoder_ctx = NULL; + BIO *allocated_out = NULL; + const void *original_data = NULL; + OSSL_PARAM abstract[10]; + const OSSL_PARAM *current_abstract = NULL; + int i; + int ok = -1; /* -1 signifies that the lookup loop gave nothing */ + int top = 0; + + if (data->next_encoder_inst == NULL) { + /* First iteration, where we prepare for what is to come */ + + data->count_output_structure = + data->ctx->output_structure == NULL ? -1 : 0; + top = 1; + } + + for (i = data->current_encoder_inst_index; i-- > 0;) { + OSSL_ENCODER *next_encoder = NULL; + const char *current_output_type; + const char *current_output_structure; + struct encoder_process_data_st new_data; + + if (!top) + next_encoder = + OSSL_ENCODER_INSTANCE_get_encoder(data->next_encoder_inst); + + current_encoder_inst = + sk_OSSL_ENCODER_INSTANCE_value(data->ctx->encoder_insts, i); + current_encoder = + OSSL_ENCODER_INSTANCE_get_encoder(current_encoder_inst); + current_encoder_ctx = + OSSL_ENCODER_INSTANCE_get_encoder_ctx(current_encoder_inst); + current_output_type = + OSSL_ENCODER_INSTANCE_get_output_type(current_encoder_inst); + current_output_structure = + OSSL_ENCODER_INSTANCE_get_output_structure(current_encoder_inst); + memset(&new_data, 0, sizeof(new_data)); + new_data.ctx = data->ctx; + new_data.current_encoder_inst_index = i; + new_data.next_encoder_inst = current_encoder_inst; + new_data.count_output_structure = data->count_output_structure; + new_data.level = data->level + 1; + + OSSL_TRACE_BEGIN(ENCODER) { + BIO_printf(trc_out, + "[%d] (ctx %p) Considering encoder instance %p (encoder %p)\n", + data->level, (void *)data->ctx, + (void *)current_encoder_inst, (void *)current_encoder); + } OSSL_TRACE_END(ENCODER); + + /* + * If this is the top call, we check if the output type of the current + * encoder matches the desired output type. + * If this isn't the top call, i.e. this is deeper in the recursion, + * we instead check if the output type of the current encoder matches + * the name of the next encoder (the one found by the parent call). + */ + if (top) { + if (data->ctx->output_type != NULL + && OPENSSL_strcasecmp(current_output_type, + data->ctx->output_type) != 0) { + OSSL_TRACE_BEGIN(ENCODER) { + BIO_printf(trc_out, + "[%d] Skipping because current encoder output type (%s) != desired output type (%s)\n", + data->level, + current_output_type, data->ctx->output_type); + } OSSL_TRACE_END(ENCODER); + continue; + } + } else { + if (!OSSL_ENCODER_is_a(next_encoder, current_output_type)) { + OSSL_TRACE_BEGIN(ENCODER) { + BIO_printf(trc_out, + "[%d] Skipping because current encoder output type (%s) != name of encoder %p\n", + data->level, + current_output_type, (void *)next_encoder); + } OSSL_TRACE_END(ENCODER); + continue; + } + } + + /* + * If the caller and the current encoder specify an output structure, + * Check if they match. If they do, count the match, otherwise skip + * the current encoder. + */ + if (data->ctx->output_structure != NULL + && current_output_structure != NULL) { + if (OPENSSL_strcasecmp(data->ctx->output_structure, + current_output_structure) != 0) { + OSSL_TRACE_BEGIN(ENCODER) { + BIO_printf(trc_out, + "[%d] Skipping because current encoder output structure (%s) != ctx output structure (%s)\n", + data->level, + current_output_structure, + data->ctx->output_structure); + } OSSL_TRACE_END(ENCODER); + continue; + } + + data->count_output_structure++; + } + + /* + * Recurse to process the encoder implementations before the current + * one. + */ + ok = encoder_process(&new_data); + + data->prev_encoder_inst = new_data.prev_encoder_inst; + data->running_output = new_data.running_output; + data->running_output_length = new_data.running_output_length; + + /* + * ok == -1 means that the recursion call above gave no further + * encoders, and that the one we're currently at should + * be tried. + * ok == 0 means that something failed in the recursion call + * above, making the result unsuitable for a chain. + * In this case, we simply continue to try finding a + * suitable encoder at this recursion level. + * ok == 1 means that the recursion call was successful, and we + * try to use the result at this recursion level. + */ + if (ok != 0) + break; + + OSSL_TRACE_BEGIN(ENCODER) { + BIO_printf(trc_out, + "[%d] Skipping because recusion level %d failed\n", + data->level, new_data.level); + } OSSL_TRACE_END(ENCODER); + } + + /* + * If |i < 0|, we didn't find any useful encoder in this recursion, so + * we do the rest of the process only if |i >= 0|. + */ + if (i < 0) { + ok = -1; + + OSSL_TRACE_BEGIN(ENCODER) { + BIO_printf(trc_out, + "[%d] (ctx %p) No suitable encoder found\n", + data->level, (void *)data->ctx); + } OSSL_TRACE_END(ENCODER); + } else { + /* Preparations */ + + switch (ok) { + case 0: + break; + case -1: + /* + * We have reached the beginning of the encoder instance sequence, + * so we prepare the object to be encoded. + */ + + /* + * |data->count_output_structure| is one of these values: + * + * -1 There is no desired output structure + * 0 There is a desired output structure, and it wasn't + * matched by any of the encoder instances that were + * considered + * >0 There is a desired output structure, and at least one + * of the encoder instances matched it + */ + if (data->count_output_structure == 0) + return 0; + + original_data = + data->ctx->construct(current_encoder_inst, + data->ctx->construct_data); + + /* Also set the data type, using the encoder implementation name */ + data->data_type = OSSL_ENCODER_get0_name(current_encoder); + + /* Assume that the constructor recorded an error */ + if (original_data != NULL) + ok = 1; + else + ok = 0; + break; + case 1: + if (!ossl_assert(data->running_output != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR); + ok = 0; + break; + } + + { + /* + * Create an object abstraction from the latest output, which + * was stolen from the previous round. + */ + + OSSL_PARAM *abstract_p = abstract; + const char *prev_output_structure = + OSSL_ENCODER_INSTANCE_get_output_structure(data->prev_encoder_inst); + + *abstract_p++ = + OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, + (char *)data->data_type, 0); + if (prev_output_structure != NULL) + *abstract_p++ = + OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE, + (char *)prev_output_structure, + 0); + *abstract_p++ = + OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, + data->running_output, + data->running_output_length); + *abstract_p = OSSL_PARAM_construct_end(); + current_abstract = abstract; + } + break; + } + + /* Calling the encoder implementation */ + + if (ok) { + OSSL_CORE_BIO *cbio = NULL; + BIO *current_out = NULL; + + /* + * If we're at the last encoder instance to use, we're setting up + * final output. Otherwise, set up an intermediary memory output. + */ + if (top) + current_out = data->bio; + else if ((current_out = allocated_out = BIO_new(BIO_s_mem())) + == NULL) + ok = 0; /* Assume BIO_new() recorded an error */ + + if (ok) + ok = (cbio = ossl_core_bio_new_from_bio(current_out)) != NULL; + if (ok) { + ok = current_encoder->encode(current_encoder_ctx, cbio, + original_data, current_abstract, + data->ctx->selection, + ossl_pw_passphrase_callback_enc, + &data->ctx->pwdata); + OSSL_TRACE_BEGIN(ENCODER) { + BIO_printf(trc_out, + "[%d] (ctx %p) Running encoder instance %p => %d\n", + data->level, (void *)data->ctx, + (void *)current_encoder_inst, ok); + } OSSL_TRACE_END(ENCODER); + } + + ossl_core_bio_free(cbio); + data->prev_encoder_inst = current_encoder_inst; + } + } + + /* Cleanup and collecting the result */ + + OPENSSL_free(data->running_output); + data->running_output = NULL; + + /* + * Steal the output from the BIO_s_mem, if we did allocate one. + * That'll be the data for an object abstraction in the next round. + */ + if (allocated_out != NULL) { + BUF_MEM *buf; + + BIO_get_mem_ptr(allocated_out, &buf); + data->running_output = (unsigned char *)buf->data; + data->running_output_length = buf->length; + memset(buf, 0, sizeof(*buf)); + } + + BIO_free(allocated_out); + if (original_data != NULL) + data->ctx->cleanup(data->ctx->construct_data); + return ok; +} diff --git a/crypto/openssl/crypto/encode_decode/encoder_local.h b/crypto/openssl/crypto/encode_decode/encoder_local.h new file mode 100644 index 000000000000..c1885ffc771f --- /dev/null +++ b/crypto/openssl/crypto/encode_decode/encoder_local.h @@ -0,0 +1,164 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/passphrase.h" +#include "internal/property.h" +#include "internal/refcount.h" + +struct ossl_endecode_base_st { + OSSL_PROVIDER *prov; + int id; + char *name; + const OSSL_ALGORITHM *algodef; + OSSL_PROPERTY_LIST *parsed_propdef; + + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; +}; + +struct ossl_encoder_st { + struct ossl_endecode_base_st base; + OSSL_FUNC_encoder_newctx_fn *newctx; + OSSL_FUNC_encoder_freectx_fn *freectx; + OSSL_FUNC_encoder_get_params_fn *get_params; + OSSL_FUNC_encoder_gettable_params_fn *gettable_params; + OSSL_FUNC_encoder_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_encoder_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_encoder_does_selection_fn *does_selection; + OSSL_FUNC_encoder_encode_fn *encode; + OSSL_FUNC_encoder_import_object_fn *import_object; + OSSL_FUNC_encoder_free_object_fn *free_object; +}; + +struct ossl_decoder_st { + struct ossl_endecode_base_st base; + OSSL_FUNC_decoder_newctx_fn *newctx; + OSSL_FUNC_decoder_freectx_fn *freectx; + OSSL_FUNC_decoder_get_params_fn *get_params; + OSSL_FUNC_decoder_gettable_params_fn *gettable_params; + OSSL_FUNC_decoder_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_decoder_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_decoder_does_selection_fn *does_selection; + OSSL_FUNC_decoder_decode_fn *decode; + OSSL_FUNC_decoder_export_object_fn *export_object; +}; + +struct ossl_encoder_instance_st { + OSSL_ENCODER *encoder; /* Never NULL */ + void *encoderctx; /* Never NULL */ + const char *output_type; /* Never NULL */ + const char *output_structure; /* May be NULL */ +}; + +DEFINE_STACK_OF(OSSL_ENCODER_INSTANCE) + +void ossl_encoder_instance_free(OSSL_ENCODER_INSTANCE *encoder_inst); + +struct ossl_encoder_ctx_st { + /* + * Select what parts of an object will be encoded. This selection is + * bit encoded, and the bits correspond to selection bits available with + * the provider side operation. For example, when encoding an EVP_PKEY, + * the OSSL_KEYMGMT_SELECT_ macros are used for this. + */ + int selection; + /* + * The desired output type. The encoder implementation must have a + * gettable "output-type" parameter that this will match against. + */ + const char *output_type; + /* + * The desired output structure, if that's relevant for the type of + * object being encoded. It may be used for selection of the starting + * encoder implementations in a chain. + */ + const char *output_structure; + + /* + * Decoders that are components of any current decoding path. + */ + STACK_OF(OSSL_ENCODER_INSTANCE) *encoder_insts; + + /* + * The constructor and destructor of an object to pass to the first + * encoder in a chain. + */ + OSSL_ENCODER_CONSTRUCT *construct; + OSSL_ENCODER_CLEANUP *cleanup; + void *construct_data; + + /* For any function that needs a passphrase reader */ + struct ossl_passphrase_data_st pwdata; +}; + +struct ossl_decoder_instance_st { + OSSL_DECODER *decoder; /* Never NULL */ + void *decoderctx; /* Never NULL */ + const char *input_type; /* Never NULL */ + const char *input_structure; /* May be NULL */ + + unsigned int flag_input_structure_was_set : 1; +}; + +DEFINE_STACK_OF(OSSL_DECODER_INSTANCE) + +struct ossl_decoder_ctx_st { + /* + * The caller may know the input type of the data they pass. If not, + * this will remain NULL and the decoding functionality will start + * with trying to decode with any desencoder in |decoder_insts|, + * regardless of their respective input type. + */ + const char *start_input_type; + /* + * The desired input structure, if that's relevant for the type of + * object being encoded. It may be used for selection of the ending + * decoder implementations in a chain, i.e. those chosen using the + * expected output data type. + */ + const char *input_structure; + /* + * Select what parts of an object are expected. This may affect what + * decoder implementations are selected, because there are structures + * that look different depending on this selection; for example, EVP_PKEY + * objects often have different encoding structures for private keys, + * public keys and key parameters. + * This selection is bit encoded, and the bits correspond to selection + * bits available with the provider side operation. For example, when + * encoding an EVP_PKEY, the OSSL_KEYMGMT_SELECT_ macros are used for + * this. + */ + int selection; + + /* + * Decoders that are components of any current decoding path. + */ + STACK_OF(OSSL_DECODER_INSTANCE) *decoder_insts; + + /* + * The constructors of a decoding, and its caller argument. + */ + OSSL_DECODER_CONSTRUCT *construct; + OSSL_DECODER_CLEANUP *cleanup; + void *construct_data; + + /* For any function that needs a passphrase reader */ + struct ossl_passphrase_data_st pwdata; +}; + +const OSSL_PROPERTY_LIST * +ossl_decoder_parsed_properties(const OSSL_DECODER *decoder); +const OSSL_PROPERTY_LIST * +ossl_encoder_parsed_properties(const OSSL_ENCODER *encoder); diff --git a/crypto/openssl/crypto/encode_decode/encoder_meth.c b/crypto/openssl/crypto/encode_decode/encoder_meth.c new file mode 100644 index 000000000000..89e7b6abf855 --- /dev/null +++ b/crypto/openssl/crypto/encode_decode/encoder_meth.c @@ -0,0 +1,700 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/core.h" +#include "internal/namemap.h" +#include "internal/property.h" +#include "internal/provider.h" +#include "crypto/encoder.h" +#include "encoder_local.h" + +/* + * Encoder can have multiple names, separated with colons in a name string + */ +#define NAME_SEPARATOR ':' + +/* Simple method structure constructor and destructor */ +static OSSL_ENCODER *ossl_encoder_new(void) +{ + OSSL_ENCODER *encoder = NULL; + + if ((encoder = OPENSSL_zalloc(sizeof(*encoder))) == NULL + || (encoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) { + OSSL_ENCODER_free(encoder); + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + return NULL; + } + + encoder->base.refcnt = 1; + + return encoder; +} + +int OSSL_ENCODER_up_ref(OSSL_ENCODER *encoder) +{ + int ref = 0; + + CRYPTO_UP_REF(&encoder->base.refcnt, &ref, encoder->base.lock); + return 1; +} + +void OSSL_ENCODER_free(OSSL_ENCODER *encoder) +{ + int ref = 0; + + if (encoder == NULL) + return; + + CRYPTO_DOWN_REF(&encoder->base.refcnt, &ref, encoder->base.lock); + if (ref > 0) + return; + OPENSSL_free(encoder->base.name); + ossl_property_free(encoder->base.parsed_propdef); + ossl_provider_free(encoder->base.prov); + CRYPTO_THREAD_lock_free(encoder->base.lock); + OPENSSL_free(encoder); +} + +/* Permanent encoder method store, constructor and destructor */ +static void encoder_store_free(void *vstore) +{ + ossl_method_store_free(vstore); +} + +static void *encoder_store_new(OSSL_LIB_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + +static const OSSL_LIB_CTX_METHOD encoder_store_method = { + /* We want encoder_store to be cleaned up before the provider store */ + OSSL_LIB_CTX_METHOD_PRIORITY_2, + encoder_store_new, + encoder_store_free, +}; + +/* Data to be passed through ossl_method_construct() */ +struct encoder_data_st { + OSSL_LIB_CTX *libctx; + int id; /* For get_encoder_from_store() */ + const char *names; /* For get_encoder_from_store() */ + const char *propquery; /* For get_encoder_from_store() */ + + OSSL_METHOD_STORE *tmp_store; /* For get_tmp_encoder_store() */ + + unsigned int flag_construct_error_occurred : 1; +}; + +/* + * Generic routines to fetch / create ENCODER methods with + * ossl_method_construct() + */ + +/* Temporary encoder method store, constructor and destructor */ +static void *get_tmp_encoder_store(void *data) +{ + struct encoder_data_st *methdata = data; + + if (methdata->tmp_store == NULL) + methdata->tmp_store = ossl_method_store_new(methdata->libctx); + return methdata->tmp_store; +} + +static void dealloc_tmp_encoder_store(void *store) +{ + if (store != NULL) + ossl_method_store_free(store); +} + +/* Get the permanent encoder store */ +static OSSL_METHOD_STORE *get_encoder_store(OSSL_LIB_CTX *libctx) +{ + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_ENCODER_STORE_INDEX, + &encoder_store_method); +} + +static int reserve_encoder_store(void *store, void *data) +{ + struct encoder_data_st *methdata = data; + + if (store == NULL + && (store = get_encoder_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_lock_store(store); +} + +static int unreserve_encoder_store(void *store, void *data) +{ + struct encoder_data_st *methdata = data; + + if (store == NULL + && (store = get_encoder_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_unlock_store(store); +} + +/* Get encoder methods from a store, or put one in */ +static void *get_encoder_from_store(void *store, const OSSL_PROVIDER **prov, + void *data) +{ + struct encoder_data_st *methdata = data; + void *method = NULL; + int id; + + /* + * get_encoder_from_store() is only called to try and get the method + * that OSSL_ENCODER_fetch() is asking for, and the name or name id are + * passed via methdata. + */ + if ((id = methdata->id) == 0 && methdata->names != NULL) { + OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx); + const char *names = methdata->names; + const char *q = strchr(names, NAME_SEPARATOR); + size_t l = (q == NULL ? strlen(names) : (size_t)(q - names)); + + if (namemap == 0) + return NULL; + id = ossl_namemap_name2num_n(namemap, methdata->names, l); + } + + if (id == 0) + return NULL; + + if (store == NULL + && (store = get_encoder_store(methdata->libctx)) == NULL) + return NULL; + + if (!ossl_method_store_fetch(store, id, methdata->propquery, prov, &method)) + return NULL; + return method; +} + +static int put_encoder_in_store(void *store, void *method, + const OSSL_PROVIDER *prov, + const char *names, const char *propdef, + void *data) +{ + struct encoder_data_st *methdata = data; + OSSL_NAMEMAP *namemap; + int id; + size_t l = 0; + + /* + * put_encoder_in_store() is only called with an OSSL_ENCODER method that + * was successfully created by construct_encoder() below, which means that + * all the names should already be stored in the namemap with the same + * numeric identity, so just use the first to get that identity. + */ + if (names != NULL) { + const char *q = strchr(names, NAME_SEPARATOR); + + l = (q == NULL ? strlen(names) : (size_t)(q - names)); + } + + if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL + || (id = ossl_namemap_name2num_n(namemap, names, l)) == 0) + return 0; + + if (store == NULL && (store = get_encoder_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_store_add(store, prov, id, propdef, method, + (int (*)(void *))OSSL_ENCODER_up_ref, + (void (*)(void *))OSSL_ENCODER_free); +} + +/* Create and populate a encoder method */ +static void *encoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + OSSL_ENCODER *encoder = NULL; + const OSSL_DISPATCH *fns = algodef->implementation; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + + if ((encoder = ossl_encoder_new()) == NULL) + return NULL; + encoder->base.id = id; + if ((encoder->base.name = ossl_algorithm_get1_first_name(algodef)) == NULL) { + OSSL_ENCODER_free(encoder); + return NULL; + } + encoder->base.algodef = algodef; + if ((encoder->base.parsed_propdef + = ossl_parse_property(libctx, algodef->property_definition)) == NULL) { + OSSL_ENCODER_free(encoder); + return NULL; + } + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_ENCODER_NEWCTX: + if (encoder->newctx == NULL) + encoder->newctx = + OSSL_FUNC_encoder_newctx(fns); + break; + case OSSL_FUNC_ENCODER_FREECTX: + if (encoder->freectx == NULL) + encoder->freectx = + OSSL_FUNC_encoder_freectx(fns); + break; + case OSSL_FUNC_ENCODER_GET_PARAMS: + if (encoder->get_params == NULL) + encoder->get_params = + OSSL_FUNC_encoder_get_params(fns); + break; + case OSSL_FUNC_ENCODER_GETTABLE_PARAMS: + if (encoder->gettable_params == NULL) + encoder->gettable_params = + OSSL_FUNC_encoder_gettable_params(fns); + break; + case OSSL_FUNC_ENCODER_SET_CTX_PARAMS: + if (encoder->set_ctx_params == NULL) + encoder->set_ctx_params = + OSSL_FUNC_encoder_set_ctx_params(fns); + break; + case OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS: + if (encoder->settable_ctx_params == NULL) + encoder->settable_ctx_params = + OSSL_FUNC_encoder_settable_ctx_params(fns); + break; + case OSSL_FUNC_ENCODER_DOES_SELECTION: + if (encoder->does_selection == NULL) + encoder->does_selection = + OSSL_FUNC_encoder_does_selection(fns); + break; + case OSSL_FUNC_ENCODER_ENCODE: + if (encoder->encode == NULL) + encoder->encode = OSSL_FUNC_encoder_encode(fns); + break; + case OSSL_FUNC_ENCODER_IMPORT_OBJECT: + if (encoder->import_object == NULL) + encoder->import_object = + OSSL_FUNC_encoder_import_object(fns); + break; + case OSSL_FUNC_ENCODER_FREE_OBJECT: + if (encoder->free_object == NULL) + encoder->free_object = + OSSL_FUNC_encoder_free_object(fns); + break; + } + } + /* + * Try to check that the method is sensible. + * If you have a constructor, you must have a destructor and vice versa. + * You must have the encoding driver functions. + */ + if (!((encoder->newctx == NULL && encoder->freectx == NULL) + || (encoder->newctx != NULL && encoder->freectx != NULL) + || (encoder->import_object != NULL && encoder->free_object != NULL) + || (encoder->import_object == NULL && encoder->free_object == NULL)) + || encoder->encode == NULL) { + OSSL_ENCODER_free(encoder); + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + + if (prov != NULL && !ossl_provider_up_ref(prov)) { + OSSL_ENCODER_free(encoder); + return NULL; + } + + encoder->base.prov = prov; + return encoder; +} + + +/* + * The core fetching functionality passes the names of the implementation. + * This function is responsible to getting an identity number for them, + * then call encoder_from_algorithm() with that identity number. + */ +static void *construct_encoder(const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov, void *data) +{ + /* + * This function is only called if get_encoder_from_store() returned + * NULL, so it's safe to say that of all the spots to create a new + * namemap entry, this is it. Should the name already exist there, we + * know that ossl_namemap_add() will return its corresponding number. + */ + struct encoder_data_st *methdata = data; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *names = algodef->algorithm_names; + int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); + void *method = NULL; + + if (id != 0) + method = encoder_from_algorithm(id, algodef, prov); + + /* + * Flag to indicate that there was actual construction errors. This + * helps inner_evp_generic_fetch() determine what error it should + * record on inaccessible algorithms. + */ + if (method == NULL) + methdata->flag_construct_error_occurred = 1; + + return method; +} + +/* Intermediary function to avoid ugly casts, used below */ +static void destruct_encoder(void *method, void *data) +{ + OSSL_ENCODER_free(method); +} + +static int up_ref_encoder(void *method) +{ + return OSSL_ENCODER_up_ref(method); +} + +static void free_encoder(void *method) +{ + OSSL_ENCODER_free(method); +} + +/* Fetching support. Can fetch by numeric identity or by name */ +static OSSL_ENCODER * +inner_ossl_encoder_fetch(struct encoder_data_st *methdata, int id, + const char *name, const char *properties) +{ + OSSL_METHOD_STORE *store = get_encoder_store(methdata->libctx); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx); + const char *const propq = properties != NULL ? properties : ""; + void *method = NULL; + int unsupported = 0; + + if (store == NULL || namemap == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + + /* + * If we have been passed both an id and a name, we have an + * internal programming error. + */ + if (!ossl_assert(id == 0 || name == NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR); + return NULL; + } + + if (id == 0) + id = ossl_namemap_name2num(namemap, name); + + /* + * If we haven't found the name yet, chances are that the algorithm to + * be fetched is unsupported. + */ + if (id == 0) + unsupported = 1; + + if (id == 0 + || !ossl_method_store_cache_get(store, NULL, id, propq, &method)) { + OSSL_METHOD_CONSTRUCT_METHOD mcm = { + get_tmp_encoder_store, + reserve_encoder_store, + unreserve_encoder_store, + get_encoder_from_store, + put_encoder_in_store, + construct_encoder, + destruct_encoder + }; + OSSL_PROVIDER *prov = NULL; + + methdata->id = id; + methdata->names = name; + methdata->propquery = propq; + methdata->flag_construct_error_occurred = 0; + if ((method = ossl_method_construct(methdata->libctx, OSSL_OP_ENCODER, + &prov, 0 /* !force_cache */, + &mcm, methdata)) != NULL) { + /* + * If construction did create a method for us, we know that + * there is a correct name_id and meth_id, since those have + * already been calculated in get_encoder_from_store() and + * put_encoder_in_store() above. + */ + if (id == 0) + id = ossl_namemap_name2num(namemap, name); + ossl_method_store_cache_set(store, prov, id, propq, method, + up_ref_encoder, free_encoder); + } + + /* + * If we never were in the constructor, the algorithm to be fetched + * is unsupported. + */ + unsupported = !methdata->flag_construct_error_occurred; + } + + if ((id != 0 || name != NULL) && method == NULL) { + int code = unsupported ? ERR_R_UNSUPPORTED : ERR_R_FETCH_FAILED; + + if (name == NULL) + name = ossl_namemap_num2name(namemap, id, 0); + ERR_raise_data(ERR_LIB_OSSL_ENCODER, code, + "%s, Name (%s : %d), Properties (%s)", + ossl_lib_ctx_get_descriptor(methdata->libctx), + name == NULL ? "" : name, id, + properties == NULL ? "" : properties); + } + + return method; +} + +OSSL_ENCODER *OSSL_ENCODER_fetch(OSSL_LIB_CTX *libctx, const char *name, + const char *properties) +{ + struct encoder_data_st methdata; + void *method; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + method = inner_ossl_encoder_fetch(&methdata, 0, name, properties); + dealloc_tmp_encoder_store(methdata.tmp_store); + return method; +} + +OSSL_ENCODER *ossl_encoder_fetch_by_number(OSSL_LIB_CTX *libctx, int id, + const char *properties) +{ + struct encoder_data_st methdata; + void *method; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + method = inner_ossl_encoder_fetch(&methdata, id, NULL, properties); + dealloc_tmp_encoder_store(methdata.tmp_store); + return method; +} + +int ossl_encoder_store_cache_flush(OSSL_LIB_CTX *libctx) +{ + OSSL_METHOD_STORE *store = get_encoder_store(libctx); + + if (store != NULL) + return ossl_method_store_cache_flush_all(store); + return 1; +} + +int ossl_encoder_store_remove_all_provided(const OSSL_PROVIDER *prov) +{ + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_METHOD_STORE *store = get_encoder_store(libctx); + + if (store != NULL) + return ossl_method_store_remove_all_provided(store, prov); + return 1; +} + +/* + * Library of basic method functions + */ + +const OSSL_PROVIDER *OSSL_ENCODER_get0_provider(const OSSL_ENCODER *encoder) +{ + if (!ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return encoder->base.prov; +} + +const char *OSSL_ENCODER_get0_properties(const OSSL_ENCODER *encoder) +{ + if (!ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return encoder->base.algodef->property_definition; +} + +const OSSL_PROPERTY_LIST * +ossl_encoder_parsed_properties(const OSSL_ENCODER *encoder) +{ + if (!ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return encoder->base.parsed_propdef; +} + +int ossl_encoder_get_number(const OSSL_ENCODER *encoder) +{ + if (!ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return encoder->base.id; +} + +const char *OSSL_ENCODER_get0_name(const OSSL_ENCODER *encoder) +{ + return encoder->base.name; +} + +const char *OSSL_ENCODER_get0_description(const OSSL_ENCODER *encoder) +{ + return encoder->base.algodef->algorithm_description; +} + +int OSSL_ENCODER_is_a(const OSSL_ENCODER *encoder, const char *name) +{ + if (encoder->base.prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(encoder->base.prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_name2num(namemap, name) == encoder->base.id; + } + return 0; +} + +struct do_one_data_st { + void (*user_fn)(OSSL_ENCODER *encoder, void *arg); + void *user_arg; +}; + +static void do_one(ossl_unused int id, void *method, void *arg) +{ + struct do_one_data_st *data = arg; + + data->user_fn(method, data->user_arg); +} + +void OSSL_ENCODER_do_all_provided(OSSL_LIB_CTX *libctx, + void (*user_fn)(OSSL_ENCODER *encoder, + void *arg), + void *user_arg) +{ + struct encoder_data_st methdata; + struct do_one_data_st data; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + (void)inner_ossl_encoder_fetch(&methdata, 0, NULL, NULL /* properties */); + + data.user_fn = user_fn; + data.user_arg = user_arg; + if (methdata.tmp_store != NULL) + ossl_method_store_do_all(methdata.tmp_store, &do_one, &data); + ossl_method_store_do_all(get_encoder_store(libctx), &do_one, &data); + dealloc_tmp_encoder_store(methdata.tmp_store); +} + +int OSSL_ENCODER_names_do_all(const OSSL_ENCODER *encoder, + void (*fn)(const char *name, void *data), + void *data) +{ + if (encoder == NULL) + return 0; + + if (encoder->base.prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(encoder->base.prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_doall_names(namemap, encoder->base.id, fn, data); + } + + return 1; +} + +const OSSL_PARAM * +OSSL_ENCODER_gettable_params(OSSL_ENCODER *encoder) +{ + if (encoder != NULL && encoder->gettable_params != NULL) { + void *provctx = ossl_provider_ctx(OSSL_ENCODER_get0_provider(encoder)); + + return encoder->gettable_params(provctx); + } + return NULL; +} + +int OSSL_ENCODER_get_params(OSSL_ENCODER *encoder, OSSL_PARAM params[]) +{ + if (encoder != NULL && encoder->get_params != NULL) + return encoder->get_params(params); + return 0; +} + +const OSSL_PARAM *OSSL_ENCODER_settable_ctx_params(OSSL_ENCODER *encoder) +{ + if (encoder != NULL && encoder->settable_ctx_params != NULL) { + void *provctx = ossl_provider_ctx(OSSL_ENCODER_get0_provider(encoder)); + + return encoder->settable_ctx_params(provctx); + } + return NULL; +} + +/* + * Encoder context support + */ + +OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new(void) +{ + OSSL_ENCODER_CTX *ctx; + + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + + return ctx; +} + +int OSSL_ENCODER_CTX_set_params(OSSL_ENCODER_CTX *ctx, + const OSSL_PARAM params[]) +{ + int ok = 1; + size_t i; + size_t l; + + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (ctx->encoder_insts == NULL) + return 1; + + l = OSSL_ENCODER_CTX_get_num_encoders(ctx); + for (i = 0; i < l; i++) { + OSSL_ENCODER_INSTANCE *encoder_inst = + sk_OSSL_ENCODER_INSTANCE_value(ctx->encoder_insts, i); + OSSL_ENCODER *encoder = OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst); + void *encoderctx = OSSL_ENCODER_INSTANCE_get_encoder_ctx(encoder_inst); + + if (encoderctx == NULL || encoder->set_ctx_params == NULL) + continue; + if (!encoder->set_ctx_params(encoderctx, params)) + ok = 0; + } + return ok; +} + +void OSSL_ENCODER_CTX_free(OSSL_ENCODER_CTX *ctx) +{ + if (ctx != NULL) { + sk_OSSL_ENCODER_INSTANCE_pop_free(ctx->encoder_insts, + ossl_encoder_instance_free); + OPENSSL_free(ctx->construct_data); + ossl_pw_clear_passphrase_data(&ctx->pwdata); + OPENSSL_free(ctx); + } +} diff --git a/crypto/openssl/crypto/encode_decode/encoder_pkey.c b/crypto/openssl/crypto/encode_decode/encoder_pkey.c new file mode 100644 index 000000000000..3a24317cf4d6 --- /dev/null +++ b/crypto/openssl/crypto/encode_decode/encoder_pkey.c @@ -0,0 +1,379 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/provider.h" +#include "internal/property.h" +#include "crypto/evp.h" +#include "encoder_local.h" + +DEFINE_STACK_OF(OSSL_ENCODER) + +int OSSL_ENCODER_CTX_set_cipher(OSSL_ENCODER_CTX *ctx, + const char *cipher_name, + const char *propquery) +{ + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_CIPHER, + (void *)cipher_name, 0); + params[1] = + OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES, + (void *)propquery, 0); + + return OSSL_ENCODER_CTX_set_params(ctx, params); +} + +int OSSL_ENCODER_CTX_set_passphrase(OSSL_ENCODER_CTX *ctx, + const unsigned char *kstr, + size_t klen) +{ + return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen); +} + +int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx, + const UI_METHOD *ui_method, + void *ui_data) +{ + return ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data); +} + +int OSSL_ENCODER_CTX_set_pem_password_cb(OSSL_ENCODER_CTX *ctx, + pem_password_cb *cb, void *cbarg) +{ + return ossl_pw_set_pem_password_cb(&ctx->pwdata, cb, cbarg); +} + +int OSSL_ENCODER_CTX_set_passphrase_cb(OSSL_ENCODER_CTX *ctx, + OSSL_PASSPHRASE_CALLBACK *cb, + void *cbarg) +{ + return ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg); +} + +/* + * Support for OSSL_ENCODER_CTX_new_for_type: + * finding a suitable encoder + */ + +struct collected_encoder_st { + STACK_OF(OPENSSL_CSTRING) *names; + const char *output_structure; + const char *output_type; + + const OSSL_PROVIDER *keymgmt_prov; + OSSL_ENCODER_CTX *ctx; + unsigned int flag_find_same_provider:1; + + int error_occurred; +}; + +static void collect_encoder(OSSL_ENCODER *encoder, void *arg) +{ + struct collected_encoder_st *data = arg; + size_t i, end_i; + + if (data->error_occurred) + return; + + data->error_occurred = 1; /* Assume the worst */ + + if (data->names == NULL) + return; + + end_i = sk_OPENSSL_CSTRING_num(data->names); + for (i = 0; i < end_i; i++) { + const char *name = sk_OPENSSL_CSTRING_value(data->names, i); + const OSSL_PROVIDER *prov = OSSL_ENCODER_get0_provider(encoder); + void *provctx = OSSL_PROVIDER_get0_provider_ctx(prov); + + /* + * collect_encoder() is called in two passes, one where the encoders + * from the same provider as the keymgmt are looked up, and one where + * the other encoders are looked up. |data->flag_find_same_provider| + * tells us which pass we're in. + */ + if ((data->keymgmt_prov == prov) != data->flag_find_same_provider) + continue; + + if (!OSSL_ENCODER_is_a(encoder, name) + || (encoder->does_selection != NULL + && !encoder->does_selection(provctx, data->ctx->selection)) + || (data->keymgmt_prov != prov + && encoder->import_object == NULL)) + continue; + + /* Only add each encoder implementation once */ + if (OSSL_ENCODER_CTX_add_encoder(data->ctx, encoder)) + break; + } + + data->error_occurred = 0; /* All is good now */ +} + +struct collected_names_st { + STACK_OF(OPENSSL_CSTRING) *names; + unsigned int error_occurred:1; +}; + +static void collect_name(const char *name, void *arg) +{ + struct collected_names_st *data = arg; + + if (data->error_occurred) + return; + + data->error_occurred = 1; /* Assume the worst */ + + if (sk_OPENSSL_CSTRING_push(data->names, name) <= 0) + return; + + data->error_occurred = 0; /* All is good now */ +} + +/* + * Support for OSSL_ENCODER_to_bio: + * writing callback for the OSSL_PARAM (the implementation doesn't have + * intimate knowledge of the provider side object) + */ + +struct construct_data_st { + const EVP_PKEY *pk; + int selection; + + OSSL_ENCODER_INSTANCE *encoder_inst; + const void *obj; + void *constructed_obj; +}; + +static int encoder_import_cb(const OSSL_PARAM params[], void *arg) +{ + struct construct_data_st *construct_data = arg; + OSSL_ENCODER_INSTANCE *encoder_inst = construct_data->encoder_inst; + OSSL_ENCODER *encoder = OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst); + void *encoderctx = OSSL_ENCODER_INSTANCE_get_encoder_ctx(encoder_inst); + + construct_data->constructed_obj = + encoder->import_object(encoderctx, construct_data->selection, params); + + return (construct_data->constructed_obj != NULL); +} + +static const void * +encoder_construct_pkey(OSSL_ENCODER_INSTANCE *encoder_inst, void *arg) +{ + struct construct_data_st *data = arg; + + if (data->obj == NULL) { + OSSL_ENCODER *encoder = + OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst); + const EVP_PKEY *pk = data->pk; + const OSSL_PROVIDER *k_prov = EVP_KEYMGMT_get0_provider(pk->keymgmt); + const OSSL_PROVIDER *e_prov = OSSL_ENCODER_get0_provider(encoder); + + if (k_prov != e_prov) { + data->encoder_inst = encoder_inst; + + if (!evp_keymgmt_export(pk->keymgmt, pk->keydata, data->selection, + &encoder_import_cb, data)) + return NULL; + data->obj = data->constructed_obj; + } else { + data->obj = pk->keydata; + } + } + + return data->obj; +} + +static void encoder_destruct_pkey(void *arg) +{ + struct construct_data_st *data = arg; + + if (data->encoder_inst != NULL) { + OSSL_ENCODER *encoder = + OSSL_ENCODER_INSTANCE_get_encoder(data->encoder_inst); + + encoder->free_object(data->constructed_obj); + } + data->constructed_obj = NULL; +} + +/* + * OSSL_ENCODER_CTX_new_for_pkey() returns a ctx with no encoder if + * it couldn't find a suitable encoder. This allows a caller to detect if + * a suitable encoder was found, with OSSL_ENCODER_CTX_get_num_encoder(), + * and to use fallback methods if the result is NULL. + */ +static int ossl_encoder_ctx_setup_for_pkey(OSSL_ENCODER_CTX *ctx, + const EVP_PKEY *pkey, + int selection, + const char *propquery) +{ + struct construct_data_st *data = NULL; + const OSSL_PROVIDER *prov = NULL; + OSSL_LIB_CTX *libctx = NULL; + int ok = 0; + + if (!ossl_assert(ctx != NULL) || !ossl_assert(pkey != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (evp_pkey_is_provided(pkey)) { + prov = EVP_KEYMGMT_get0_provider(pkey->keymgmt); + libctx = ossl_provider_libctx(prov); + } + + if (pkey->keymgmt != NULL) { + struct collected_encoder_st encoder_data; + struct collected_names_st keymgmt_data; + + if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * Select the first encoder implementations in two steps. + * First, collect the keymgmt names, then the encoders that match. + */ + keymgmt_data.names = sk_OPENSSL_CSTRING_new_null(); + if (keymgmt_data.names == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + goto err; + } + + keymgmt_data.error_occurred = 0; + EVP_KEYMGMT_names_do_all(pkey->keymgmt, collect_name, &keymgmt_data); + if (keymgmt_data.error_occurred) { + sk_OPENSSL_CSTRING_free(keymgmt_data.names); + goto err; + } + + encoder_data.names = keymgmt_data.names; + encoder_data.output_type = ctx->output_type; + encoder_data.output_structure = ctx->output_structure; + encoder_data.error_occurred = 0; + encoder_data.keymgmt_prov = prov; + encoder_data.ctx = ctx; + + /* + * Place the encoders with the a different provider as the keymgmt + * last (the chain is processed in reverse order) + */ + encoder_data.flag_find_same_provider = 0; + OSSL_ENCODER_do_all_provided(libctx, collect_encoder, &encoder_data); + + /* + * Place the encoders with the same provider as the keymgmt first + * (the chain is processed in reverse order) + */ + encoder_data.flag_find_same_provider = 1; + OSSL_ENCODER_do_all_provided(libctx, collect_encoder, &encoder_data); + + sk_OPENSSL_CSTRING_free(keymgmt_data.names); + if (encoder_data.error_occurred) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (data != NULL && OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0) { + if (!OSSL_ENCODER_CTX_set_construct(ctx, encoder_construct_pkey) + || !OSSL_ENCODER_CTX_set_construct_data(ctx, data) + || !OSSL_ENCODER_CTX_set_cleanup(ctx, encoder_destruct_pkey)) + goto err; + + data->pk = pkey; + data->selection = selection; + + data = NULL; /* Avoid it being freed */ + } + + ok = 1; + err: + if (data != NULL) { + OSSL_ENCODER_CTX_set_construct_data(ctx, NULL); + OPENSSL_free(data); + } + return ok; +} + +OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_for_pkey(const EVP_PKEY *pkey, + int selection, + const char *output_type, + const char *output_struct, + const char *propquery) +{ + OSSL_ENCODER_CTX *ctx = NULL; + OSSL_LIB_CTX *libctx = NULL; + + if (pkey == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if (!evp_pkey_is_assigned(pkey)) { + ERR_raise_data(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT, + "The passed EVP_PKEY must be assigned a key"); + return NULL; + } + + if ((ctx = OSSL_ENCODER_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (evp_pkey_is_provided(pkey)) { + const OSSL_PROVIDER *prov = EVP_KEYMGMT_get0_provider(pkey->keymgmt); + + libctx = ossl_provider_libctx(prov); + } + + OSSL_TRACE_BEGIN(ENCODER) { + BIO_printf(trc_out, + "(ctx %p) Looking for %s encoders with selection %d\n", + (void *)ctx, EVP_PKEY_get0_type_name(pkey), selection); + BIO_printf(trc_out, " output type: %s, output structure: %s\n", + output_type, output_struct); + } OSSL_TRACE_END(ENCODER); + + if (OSSL_ENCODER_CTX_set_output_type(ctx, output_type) + && (output_struct == NULL + || OSSL_ENCODER_CTX_set_output_structure(ctx, output_struct)) + && OSSL_ENCODER_CTX_set_selection(ctx, selection) + && ossl_encoder_ctx_setup_for_pkey(ctx, pkey, selection, propquery) + && OSSL_ENCODER_CTX_add_extra(ctx, libctx, propquery)) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + int save_parameters = pkey->save_parameters; + + params[0] = OSSL_PARAM_construct_int(OSSL_ENCODER_PARAM_SAVE_PARAMETERS, + &save_parameters); + /* ignoring error as this is only auxiliary parameter */ + (void)OSSL_ENCODER_CTX_set_params(ctx, params); + + OSSL_TRACE_BEGIN(ENCODER) { + BIO_printf(trc_out, "(ctx %p) Got %d encoders\n", + (void *)ctx, OSSL_ENCODER_CTX_get_num_encoders(ctx)); + } OSSL_TRACE_END(ENCODER); + return ctx; + } + + OSSL_ENCODER_CTX_free(ctx); + return NULL; +} diff --git a/crypto/openssl/crypto/engine/README b/crypto/openssl/crypto/engine/README.md similarity index 95% rename from crypto/openssl/crypto/engine/README rename to crypto/openssl/crypto/engine/README.md index 0f8a8fbde410..b45115ca2481 100644 --- a/crypto/openssl/crypto/engine/README +++ b/crypto/openssl/crypto/engine/README.md @@ -1,12 +1,12 @@ -Notes: 2001-09-24 ------------------ +Notes on engines of 2001-09-24 +============================== This "description" (if one chooses to call it that) needed some major updating so here goes. This update addresses a change being made at the same time to OpenSSL, and it pretty much completely restructures the underlying mechanics of the "ENGINE" code. So it serves a double purpose of being a "ENGINE internals for masochists" document *and* a rather extensive commit log message. (I'd get -lynched for sticking all this in CHANGES or the commit mails :-). +lynched for sticking all this in CHANGES.md or the commit mails :-). ENGINE_TABLE underlies this restructuring, as described in the internal header "eng_local.h", implemented in eng_table.c, and used in each of the "class" files; @@ -21,16 +21,16 @@ or can be loaded "en masse" into EVP storage so that they can be catalogued and searched in various ways, ie. two ways of encrypting with the "des_cbc" algorithm/mode pair are; -(i) directly; - const EVP_CIPHER *cipher = EVP_des_cbc(); - EVP_EncryptInit(&ctx, cipher, key, iv); - [ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...] + (i) directly; + const EVP_CIPHER *cipher = EVP_des_cbc(); + EVP_EncryptInit(&ctx, cipher, key, iv); + [ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...] -(ii) indirectly; - OpenSSL_add_all_ciphers(); - cipher = EVP_get_cipherbyname("des_cbc"); - EVP_EncryptInit(&ctx, cipher, key, iv); - [ ... etc ... ] + (ii) indirectly; + OpenSSL_add_all_ciphers(); + cipher = EVP_get_cipherbyname("des_cbc"); + EVP_EncryptInit(&ctx, cipher, key, iv); + [ ... etc ... ] The latter is more generally used because it also allows ciphers/digests to be looked up based on other identifiers which can be useful for automatic cipher @@ -177,7 +177,7 @@ is deliberately a distinct step. Moreover, registration and unregistration has nothing to do with whether an ENGINE is *functional* or not (ie. you can even register an ENGINE and its implementations without it being operational, you may not even have the drivers to make it operate). What actually happens with -respect to cleanup is managed inside eng_lib.c with the "engine_cleanup_***" +respect to cleanup is managed inside eng_lib.c with the `engine_cleanup_***` functions. These functions are internal-only and each part of ENGINE code that could require cleanup will, upon performing its first allocation, register a callback with the "engine_cleanup" code. The other part of this that makes it @@ -208,4 +208,3 @@ hooking of ENGINE is now automatic (and passive, it can internally use a NULL ENGINE pointer to simply ignore ENGINE from then on). Hell, that should be enough for now ... comments welcome. - diff --git a/crypto/openssl/crypto/engine/build.info b/crypto/openssl/crypto/engine/build.info index e00802a3fd55..47fe948966ea 100644 --- a/crypto/openssl/crypto/engine/build.info +++ b/crypto/openssl/crypto/engine/build.info @@ -6,6 +6,3 @@ SOURCE[../../libcrypto]=\ tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c tb_eckey.c \ eng_openssl.c eng_cnf.c eng_dyn.c \ eng_rdrand.c -IF[{- !$disabled{devcryptoeng} -}] - SOURCE[../../libcrypto]=eng_devcrypto.c -ENDIF diff --git a/crypto/openssl/crypto/engine/eng_all.c b/crypto/openssl/crypto/engine/eng_all.c index 474a60c9bf13..2f83b2ec182f 100644 --- a/crypto/openssl/crypto/engine/eng_all.c +++ b/crypto/openssl/crypto/engine/eng_all.c @@ -1,7 +1,7 @@ /* - * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,8 +15,10 @@ void ENGINE_load_builtin_engines(void) OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL); } -#if (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)) && OPENSSL_API_COMPAT < 0x10100000L +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# if (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)) void ENGINE_setup_bsd_cryptodev(void) { } +# endif #endif diff --git a/crypto/openssl/crypto/engine/eng_cnf.c b/crypto/openssl/crypto/engine/eng_cnf.c index df00df6acd61..14744bb7f55b 100644 --- a/crypto/openssl/crypto/engine/eng_cnf.c +++ b/crypto/openssl/crypto/engine/eng_cnf.c @@ -1,16 +1,18 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" #include - -/* #define ENGINE_CONF_DEBUG */ +#include /* ENGINE config module */ @@ -50,15 +52,12 @@ static int int_engine_configure(const char *name, const char *value, const CONF int soft = 0; name = skip_dot(name); -#ifdef ENGINE_CONF_DEBUG - fprintf(stderr, "Configuring engine %s\n", name); -#endif + OSSL_TRACE1(CONF, "Configuring engine %s\n", name); /* Value is a section containing ENGINE commands */ ecmds = NCONF_get_section(cnf, value); if (!ecmds) { - ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, - ENGINE_R_ENGINE_SECTION_ERROR); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ENGINE_SECTION_ERROR); return 0; } @@ -66,10 +65,8 @@ static int int_engine_configure(const char *name, const char *value, const CONF ecmd = sk_CONF_VALUE_value(ecmds, i); ctrlname = skip_dot(ecmd->name); ctrlvalue = ecmd->value; -#ifdef ENGINE_CONF_DEBUG - fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, - ctrlvalue); -#endif + OSSL_TRACE2(CONF, "ENGINE: doing ctrl(%s,%s)\n", + ctrlname, ctrlvalue); /* First handle some special pseudo ctrls */ @@ -118,8 +115,7 @@ static int int_engine_configure(const char *name, const char *value, const CONF if (!int_engine_init(e)) goto err; } else if (do_init != 0) { - ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, - ENGINE_R_INVALID_INIT_VALUE); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INVALID_INIT_VALUE); goto err; } } else if (strcmp(ctrlname, "default_algorithms") == 0) { @@ -137,12 +133,12 @@ static int int_engine_configure(const char *name, const char *value, const CONF ret = 1; err: if (ret != 1) { - ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, - ENGINE_R_ENGINE_CONFIGURATION_ERROR); - if (ecmd) - ERR_add_error_data(6, "section=", ecmd->section, - ", name=", ecmd->name, - ", value=", ecmd->value); + if (ecmd == NULL) + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ENGINE_CONFIGURATION_ERROR); + else + ERR_raise_data(ERR_LIB_ENGINE, ENGINE_R_ENGINE_CONFIGURATION_ERROR, + "section=%s, name=%s, value=%s", + ecmd->section, ecmd->name, ecmd->value); } ENGINE_free(e); return ret; @@ -153,16 +149,13 @@ static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf) STACK_OF(CONF_VALUE) *elist; CONF_VALUE *cval; int i; -#ifdef ENGINE_CONF_DEBUG - fprintf(stderr, "Called engine module: name %s, value %s\n", - CONF_imodule_get_name(md), CONF_imodule_get_value(md)); -#endif + OSSL_TRACE2(CONF, "Called engine module: name %s, value %s\n", + CONF_imodule_get_name(md), CONF_imodule_get_value(md)); /* Value is a section containing ENGINEs to configure */ elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); if (!elist) { - ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, - ENGINE_R_ENGINES_SECTION_ERROR); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ENGINES_SECTION_ERROR); return 0; } diff --git a/crypto/openssl/crypto/engine/eng_ctrl.c b/crypto/openssl/crypto/engine/eng_ctrl.c index e65e78447b43..5d7e15634e6e 100644 --- a/crypto/openssl/crypto/engine/eng_ctrl.c +++ b/crypto/openssl/crypto/engine/eng_ctrl.c @@ -1,12 +1,15 @@ /* - * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" /* @@ -76,7 +79,7 @@ static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) || (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD)) { if (s == NULL) { - ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return -1; } } @@ -84,7 +87,7 @@ static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, if (cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) { if ((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(e->cmd_defns, s)) < 0)) { - ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NAME); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NAME); return -1; } return e->cmd_defns[idx].cmd_num; @@ -95,7 +98,7 @@ static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, */ if ((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns, (unsigned int)i)) < 0)) { - ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NUMBER); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NUMBER); return -1; } /* Now the logic splits depending on command type */ @@ -118,7 +121,7 @@ static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, return cdp->cmd_flags; } /* Shouldn't really be here ... */ - ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INTERNAL_LIST_ERROR); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); return -1; } @@ -126,15 +129,16 @@ int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) { int ctrl_exists, ref_exists; if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_CTRL, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return 0; ref_exists = ((e->struct_ref > 0) ? 1 : 0); CRYPTO_THREAD_unlock(global_engine_lock); ctrl_exists = ((e->ctrl == NULL) ? 0 : 1); if (!ref_exists) { - ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_REFERENCE); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_REFERENCE); return 0; } /* @@ -155,7 +159,7 @@ int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) if (ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL)) return int_ctrl_helper(e, cmd, i, p, f); if (!ctrl_exists) { - ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_CONTROL_FUNCTION); /* * For these cmd-related functions, failure is indicated by a -1 * return value (because 0 is used as a valid return in some @@ -168,7 +172,7 @@ int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) } /* Anything else requires a ctrl() handler to exist. */ if (!ctrl_exists) { - ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_CONTROL_FUNCTION); return 0; } return e->ctrl(e, cmd, i, p, f); @@ -179,8 +183,7 @@ int ENGINE_cmd_is_executable(ENGINE *e, int cmd) int flags; if ((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0) { - ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE, - ENGINE_R_INVALID_CMD_NUMBER); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NUMBER); return 0; } if (!(flags & ENGINE_CMD_FLAG_NO_INPUT) && @@ -196,7 +199,7 @@ int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, int num; if (e == NULL || cmd_name == NULL) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (e->ctrl == NULL @@ -214,7 +217,7 @@ int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, ERR_clear_error(); return 1; } - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ENGINE_R_INVALID_CMD_NAME); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NAME); return 0; } /* @@ -234,7 +237,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, char *ptr; if (e == NULL || cmd_name == NULL) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (e->ctrl == NULL @@ -252,12 +255,11 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, ERR_clear_error(); return 1; } - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, ENGINE_R_INVALID_CMD_NAME); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NAME); return 0; } if (!ENGINE_cmd_is_executable(e, num)) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_CMD_NOT_EXECUTABLE); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_CMD_NOT_EXECUTABLE); return 0; } @@ -267,8 +269,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, * Shouldn't happen, given that ENGINE_cmd_is_executable() returned * success. */ - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_INTERNAL_LIST_ERROR); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); return 0; } /* @@ -276,8 +277,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, */ if (flags & ENGINE_CMD_FLAG_NO_INPUT) { if (arg != NULL) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_COMMAND_TAKES_NO_INPUT); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_COMMAND_TAKES_NO_INPUT); return 0; } /* @@ -292,8 +292,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, } /* So, we require input */ if (arg == NULL) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_COMMAND_TAKES_INPUT); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_COMMAND_TAKES_INPUT); return 0; } /* If it takes string input, that's easy */ @@ -310,14 +309,12 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, * used. */ if (!(flags & ENGINE_CMD_FLAG_NUMERIC)) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_INTERNAL_LIST_ERROR); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); return 0; } l = strtol(arg, &ptr, 10); if ((arg == ptr) || (*ptr != '\0')) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER); return 0; } /* diff --git a/crypto/openssl/crypto/engine/eng_dyn.c b/crypto/openssl/crypto/engine/eng_dyn.c index 27d7b893cdad..6d402927c546 100644 --- a/crypto/openssl/crypto/engine/eng_dyn.c +++ b/crypto/openssl/crypto/engine/eng_dyn.c @@ -1,12 +1,15 @@ /* * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" #include "internal/dso.h" #include @@ -154,22 +157,22 @@ static void dynamic_data_ctx_free_func(void *parent, void *ptr, static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) { dynamic_data_ctx *c = OPENSSL_zalloc(sizeof(*c)); - int ret = 1; + int ret = 0; if (c == NULL) { - ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); return 0; } c->dirs = sk_OPENSSL_STRING_new_null(); if (c->dirs == NULL) { - ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); - OPENSSL_free(c); - return 0; + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + goto end; } c->DYNAMIC_F1 = "v_check"; c->DYNAMIC_F2 = "bind_engine"; c->dir_load = 1; - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + goto end; if ((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx)) == NULL) { @@ -181,11 +184,13 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) } } CRYPTO_THREAD_unlock(global_engine_lock); + ret = 1; /* * If we lost the race to set the context, c is non-NULL and *ctx is the * context of the thread that won. */ - if (c) +end: + if (c != NULL) sk_OPENSSL_STRING_free(c->dirs); OPENSSL_free(c); return ret; @@ -207,10 +212,11 @@ static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e) int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, dynamic_data_ctx_free_func); if (new_idx == -1) { - ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX, ENGINE_R_NO_INDEX); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_INDEX); return NULL; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return NULL; /* Avoid a race by checking again inside this lock */ if (dynamic_ex_data_idx < 0) { /* Good, someone didn't beat us to it */ @@ -254,6 +260,8 @@ void engine_load_dynamic_int(void) ENGINE *toadd = engine_dynamic(); if (!toadd) return; + + ERR_set_mark(); ENGINE_add(toadd); /* * If the "add" worked, it gets a structural reference. So either way, we @@ -265,7 +273,7 @@ void engine_load_dynamic_int(void) * already added (eg. someone calling ENGINE_load_blah then calling * ENGINE_load_builtin_engines() perhaps). */ - ERR_clear_error(); + ERR_pop_to_mark(); } static int dynamic_init(ENGINE *e) @@ -292,13 +300,13 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) int initialised; if (!ctx) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_NOT_LOADED); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NOT_LOADED); return 0; } initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1); /* All our control commands require the ENGINE to be uninitialised */ if (initialised) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_ALREADY_LOADED); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ALREADY_LOADED); return 0; } switch (cmd) { @@ -327,7 +335,7 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) return (ctx->engine_id ? 1 : 0); case DYNAMIC_CMD_LIST_ADD: if ((i < 0) || (i > 2)) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INVALID_ARGUMENT); return 0; } ctx->list_add_value = (int)i; @@ -336,26 +344,26 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) return dynamic_load(e, ctx); case DYNAMIC_CMD_DIR_LOAD: if ((i < 0) || (i > 2)) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INVALID_ARGUMENT); return 0; } ctx->dir_load = (int)i; return 1; case DYNAMIC_CMD_DIR_ADD: /* a NULL 'p' or a string of zero-length is the same thing */ - if (!p || (strlen((const char *)p) < 1)) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); + if (p == NULL || (strlen((const char *)p) < 1)) { + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INVALID_ARGUMENT); return 0; } { char *tmp_str = OPENSSL_strdup(p); if (tmp_str == NULL) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); return 0; } if (!sk_OPENSSL_STRING_push(ctx->dirs, tmp_str)) { OPENSSL_free(tmp_str); - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); return 0; } } @@ -363,7 +371,7 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) default: break; } - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); return 0; } @@ -396,18 +404,18 @@ static int int_load(dynamic_data_ctx *ctx) /* * Unfortunately the version checker does not distinguish between * engines built for openssl 1.1.x and openssl 3.x, but loading - * an engine that is built for openssl 3.x will cause a fatal - * error. Detect such engines, since EVP_PKEY_get_base_id is exported - * as a function in openssl 3.x, while it is named EVP_PKEY_base_id - * in openssl 1.1.x. Therefore we take the presence of that symbol + * an engine that is built for openssl 1.1.x will cause a fatal + * error. Detect such engines, since EVP_PKEY_base_id is exported + * as a function in openssl 1.1.x, while it is named EVP_PKEY_get_base_id + * in openssl 3.x. Therefore we take the presence of that symbol * as an indication that the engine will be incompatible. */ -static int using_libcrypto_3(dynamic_data_ctx *ctx) +static int using_libcrypto_11(dynamic_data_ctx *ctx) { int ret; ERR_set_mark(); - ret = DSO_bind_func(ctx->dynamic_dso, "EVP_PKEY_get_base_id") != NULL; + ret = DSO_bind_func(ctx->dynamic_dso, "EVP_PKEY_base_id") != NULL; ERR_pop_to_mark(); return ret; @@ -431,7 +439,7 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id); } if (!int_load(ctx)) { - ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_NOT_FOUND); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_DSO_NOT_FOUND); DSO_free(ctx->dynamic_dso); ctx->dynamic_dso = NULL; return 0; @@ -444,7 +452,7 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) ctx->bind_engine = NULL; DSO_free(ctx->dynamic_dso); ctx->dynamic_dso = NULL; - ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_DSO_FAILURE); return 0; } /* Do we perform version checking? */ @@ -462,16 +470,15 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) /* * We fail if the version checker veto'd the load *or* if it is * deferring to us (by returning its version) and we think it is too - * old. Also fail if this is engine for openssl 3.x. + * old. Also fail if this is engine for openssl 1.1.x. */ - if (vcheck_res < OSSL_DYNAMIC_OLDEST || using_libcrypto_3(ctx)) { + if (vcheck_res < OSSL_DYNAMIC_OLDEST || using_libcrypto_11(ctx)) { /* Fail */ ctx->bind_engine = NULL; ctx->v_check = NULL; DSO_free(ctx->dynamic_dso); ctx->dynamic_dso = NULL; - ENGINEerr(ENGINE_F_DYNAMIC_LOAD, - ENGINE_R_VERSION_INCOMPATIBILITY); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_VERSION_INCOMPATIBILITY); return 0; } } @@ -504,7 +511,7 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) ctx->v_check = NULL; DSO_free(ctx->dynamic_dso); ctx->dynamic_dso = NULL; - ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_INIT_FAILED); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INIT_FAILED); /* Copy the original ENGINE structure back */ memcpy(e, &cpy, sizeof(ENGINE)); return 0; @@ -520,8 +527,7 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) * created leaks. We just have to fail where we are, after * the ENGINE has changed. */ - ENGINEerr(ENGINE_F_DYNAMIC_LOAD, - ENGINE_R_CONFLICTING_ENGINE_ID); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_CONFLICTING_ENGINE_ID); return 0; } /* Tolerate */ diff --git a/crypto/openssl/crypto/engine/eng_err.c b/crypto/openssl/crypto/engine/eng_err.c index bd1aefa185ec..17c1b7d008ee 100644 --- a/crypto/openssl/crypto/engine/eng_err.c +++ b/crypto/openssl/crypto/engine/eng_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,72 +10,11 @@ #include #include +#include "crypto/engineerr.h" -#ifndef OPENSSL_NO_ERR +#ifndef OPENSSL_NO_ENGINE -static const ERR_STRING_DATA ENGINE_str_functs[] = { - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DIGEST_UPDATE, 0), "digest_update"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_CTRL, 0), "dynamic_ctrl"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_GET_DATA_CTX, 0), - "dynamic_get_data_ctx"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_LOAD, 0), "dynamic_load"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_SET_DATA_CTX, 0), - "dynamic_set_data_ctx"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_ADD, 0), "ENGINE_add"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_BY_ID, 0), "ENGINE_by_id"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CMD_IS_EXECUTABLE, 0), - "ENGINE_cmd_is_executable"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CTRL, 0), "ENGINE_ctrl"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CTRL_CMD, 0), "ENGINE_ctrl_cmd"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CTRL_CMD_STRING, 0), - "ENGINE_ctrl_cmd_string"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_FINISH, 0), "ENGINE_finish"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_CIPHER, 0), - "ENGINE_get_cipher"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_DIGEST, 0), - "ENGINE_get_digest"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_FIRST, 0), - "ENGINE_get_first"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_LAST, 0), "ENGINE_get_last"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_NEXT, 0), "ENGINE_get_next"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_PKEY_ASN1_METH, 0), - "ENGINE_get_pkey_asn1_meth"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_PKEY_METH, 0), - "ENGINE_get_pkey_meth"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_PREV, 0), "ENGINE_get_prev"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_INIT, 0), "ENGINE_init"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LIST_ADD, 0), "engine_list_add"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LIST_REMOVE, 0), - "engine_list_remove"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, 0), - "ENGINE_load_private_key"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, 0), - "ENGINE_load_public_key"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, 0), - "ENGINE_load_ssl_client_cert"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_NEW, 0), "ENGINE_new"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR, 0), - "ENGINE_pkey_asn1_find_str"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_REMOVE, 0), "ENGINE_remove"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_SET_DEFAULT_STRING, 0), - "ENGINE_set_default_string"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_SET_ID, 0), "ENGINE_set_id"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_SET_NAME, 0), "ENGINE_set_name"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_TABLE_REGISTER, 0), - "engine_table_register"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_UNLOCKED_FINISH, 0), - "engine_unlocked_finish"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_UP_REF, 0), "ENGINE_up_ref"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_INT_CLEANUP_ITEM, 0), - "int_cleanup_item"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_INT_CTRL_HELPER, 0), "int_ctrl_helper"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_INT_ENGINE_CONFIGURE, 0), - "int_engine_configure"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_INT_ENGINE_MODULE_INIT, 0), - "int_engine_module_init"}, - {ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_OSSL_HMAC_INIT, 0), "ossl_hmac_init"}, - {0, NULL} -}; +# ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA ENGINE_str_reasons[] = { {ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_ALREADY_LOADED), "already loaded"}, @@ -140,15 +79,16 @@ static const ERR_STRING_DATA ENGINE_str_reasons[] = { {0, NULL} }; -#endif +# endif -int ERR_load_ENGINE_strings(void) +int ossl_err_load_ENGINE_strings(void) { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL) { - ERR_load_strings_const(ENGINE_str_functs); +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(ENGINE_str_reasons[0].error) == NULL) ERR_load_strings_const(ENGINE_str_reasons); - } -#endif +# endif return 1; } +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/engine/eng_fat.c b/crypto/openssl/crypto/engine/eng_fat.c index fe231a65f658..0cf27715c5cc 100644 --- a/crypto/openssl/crypto/engine/eng_fat.c +++ b/crypto/openssl/crypto/engine/eng_fat.c @@ -1,13 +1,16 @@ /* - * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 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 + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" #include @@ -17,10 +20,8 @@ int ENGINE_set_default(ENGINE *e, unsigned int flags) return 0; if ((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e)) return 0; -#ifndef OPENSSL_NO_RSA if ((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e)) return 0; -#endif #ifndef OPENSSL_NO_DSA if ((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e)) return 0; @@ -82,9 +83,8 @@ int ENGINE_set_default_string(ENGINE *e, const char *def_list) { unsigned int flags = 0; if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags)) { - ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING, - ENGINE_R_INVALID_STRING); - ERR_add_error_data(2, "str=", def_list); + ERR_raise_data(ERR_LIB_ENGINE, ENGINE_R_INVALID_STRING, + "str=%s", def_list); return 0; } return ENGINE_set_default(e, flags); @@ -94,9 +94,7 @@ int ENGINE_register_complete(ENGINE *e) { ENGINE_register_ciphers(e); ENGINE_register_digests(e); -#ifndef OPENSSL_NO_RSA ENGINE_register_RSA(e); -#endif #ifndef OPENSSL_NO_DSA ENGINE_register_DSA(e); #endif diff --git a/crypto/openssl/crypto/engine/eng_init.c b/crypto/openssl/crypto/engine/eng_init.c index 6c9063f8f681..c204eb189986 100644 --- a/crypto/openssl/crypto/engine/eng_init.c +++ b/crypto/openssl/crypto/engine/eng_init.c @@ -1,12 +1,15 @@ /* - * Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "e_os.h" #include "eng_local.h" @@ -31,8 +34,8 @@ int engine_unlocked_init(ENGINE *e) */ e->struct_ref++; e->funct_ref++; - engine_ref_debug(e, 0, 1); - engine_ref_debug(e, 1, 1); + ENGINE_REF_PRINT(e, 0, 1); + ENGINE_REF_PRINT(e, 1, 1); } return to_return; } @@ -54,20 +57,21 @@ int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers) * to 0 without either calling finish(). */ e->funct_ref--; - engine_ref_debug(e, 1, -1); + ENGINE_REF_PRINT(e, 1, -1); if ((e->funct_ref == 0) && e->finish) { if (unlock_for_handlers) CRYPTO_THREAD_unlock(global_engine_lock); to_return = e->finish(e); if (unlock_for_handlers) - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return 0; if (!to_return) return 0; } REF_ASSERT_ISNT(e->funct_ref < 0); /* Release the structural reference too */ if (!engine_free_util(e, 0)) { - ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH, ENGINE_R_FINISH_FAILED); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_FINISH_FAILED); return 0; } return to_return; @@ -78,14 +82,15 @@ int ENGINE_init(ENGINE *e) { int ret; if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_INIT, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { - ENGINEerr(ENGINE_F_ENGINE_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); return 0; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return 0; ret = engine_unlocked_init(e); CRYPTO_THREAD_unlock(global_engine_lock); return ret; @@ -98,11 +103,12 @@ int ENGINE_finish(ENGINE *e) if (e == NULL) return 1; - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return 0; to_return = engine_unlocked_finish(e, 1); CRYPTO_THREAD_unlock(global_engine_lock); if (!to_return) { - ENGINEerr(ENGINE_F_ENGINE_FINISH, ENGINE_R_FINISH_FAILED); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_FINISH_FAILED); return 0; } return to_return; diff --git a/crypto/openssl/crypto/engine/eng_lib.c b/crypto/openssl/crypto/engine/eng_lib.c index fb727b787747..05c6a67c1e1b 100644 --- a/crypto/openssl/crypto/engine/eng_lib.c +++ b/crypto/openssl/crypto/engine/eng_lib.c @@ -1,7 +1,7 @@ /* * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,8 +20,6 @@ CRYPTO_ONCE engine_lock_init = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE(do_engine_lock_init) { - if (!OPENSSL_init_crypto(0, NULL)) - return 0; global_engine_lock = CRYPTO_THREAD_lock_new(); return global_engine_lock != NULL; } @@ -32,11 +30,11 @@ ENGINE *ENGINE_new(void) if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init) || (ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); return NULL; } ret->struct_ref = 1; - engine_ref_debug(ret, 0, 1); + ENGINE_REF_PRINT(ret, 0, 1); if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data)) { OPENSSL_free(ret); return NULL; @@ -80,7 +78,7 @@ int engine_free_util(ENGINE *e, int not_locked) CRYPTO_DOWN_REF(&e->struct_ref, &i, global_engine_lock); else i = --e->struct_ref; - engine_ref_debug(e, 0, -1); + ENGINE_REF_PRINT(e, 0, -1); if (i > 0) return 1; REF_ASSERT_ISNT(i < 0); @@ -128,7 +126,7 @@ static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb) ENGINE_CLEANUP_ITEM *item; if ((item = OPENSSL_malloc(sizeof(*item))) == NULL) { - ENGINEerr(ENGINE_F_INT_CLEANUP_ITEM, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); return NULL; } item->cb = cb; @@ -196,7 +194,7 @@ void *ENGINE_get_ex_data(const ENGINE *e, int idx) int ENGINE_set_id(ENGINE *e, const char *id) { if (id == NULL) { - ENGINEerr(ENGINE_F_ENGINE_SET_ID, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } e->id = id; @@ -206,7 +204,7 @@ int ENGINE_set_id(ENGINE *e, const char *id) int ENGINE_set_name(ENGINE *e, const char *name) { if (name == NULL) { - ENGINEerr(ENGINE_F_ENGINE_SET_NAME, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } e->name = name; diff --git a/crypto/openssl/crypto/engine/eng_list.c b/crypto/openssl/crypto/engine/eng_list.c index e2e91d297bd6..04c73c762864 100644 --- a/crypto/openssl/crypto/engine/eng_list.c +++ b/crypto/openssl/crypto/engine/eng_list.c @@ -2,12 +2,15 @@ * Copyright 2001-2021 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 + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" /* @@ -57,7 +60,7 @@ static int engine_list_add(ENGINE *e) ENGINE *iterator = NULL; if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } iterator = engine_list_head; @@ -66,13 +69,13 @@ static int engine_list_add(ENGINE *e) iterator = iterator->next; } if (conflict) { - ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_CONFLICTING_ENGINE_ID); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_CONFLICTING_ENGINE_ID); return 0; } if (engine_list_head == NULL) { /* We are adding to an empty list. */ if (engine_list_tail) { - ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); return 0; } engine_list_head = e; @@ -84,7 +87,7 @@ static int engine_list_add(ENGINE *e) } else { /* We are adding to the tail of an existing list. */ if ((engine_list_tail == NULL) || (engine_list_tail->next != NULL)) { - ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); return 0; } engine_list_tail->next = e; @@ -94,7 +97,7 @@ static int engine_list_add(ENGINE *e) * Having the engine in the list assumes a structural reference. */ e->struct_ref++; - engine_ref_debug(e, 0, 1); + ENGINE_REF_PRINT(e, 0, 1); /* However it came to be, e is the last item in the list. */ engine_list_tail = e; e->next = NULL; @@ -106,7 +109,7 @@ static int engine_list_remove(ENGINE *e) ENGINE *iterator; if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } /* We need to check that e is in our linked list! */ @@ -114,8 +117,7 @@ static int engine_list_remove(ENGINE *e) while (iterator && (iterator != e)) iterator = iterator->next; if (iterator == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, - ENGINE_R_ENGINE_IS_NOT_IN_LIST); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ENGINE_IS_NOT_IN_LIST); return 0; } /* un-link e from the chain. */ @@ -217,15 +219,16 @@ ENGINE *ENGINE_get_first(void) ENGINE *ret; if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { - ENGINEerr(ENGINE_F_ENGINE_GET_FIRST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); return NULL; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return NULL; ret = engine_list_head; if (ret) { ret->struct_ref++; - engine_ref_debug(ret, 0, 1); + ENGINE_REF_PRINT(ret, 0, 1); } CRYPTO_THREAD_unlock(global_engine_lock); return ret; @@ -236,15 +239,16 @@ ENGINE *ENGINE_get_last(void) ENGINE *ret; if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { - ENGINEerr(ENGINE_F_ENGINE_GET_LAST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); return NULL; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return NULL; ret = engine_list_tail; if (ret) { ret->struct_ref++; - engine_ref_debug(ret, 0, 1); + ENGINE_REF_PRINT(ret, 0, 1); } CRYPTO_THREAD_unlock(global_engine_lock); return ret; @@ -255,15 +259,16 @@ ENGINE *ENGINE_get_next(ENGINE *e) { ENGINE *ret = NULL; if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_GET_NEXT, ERR_R_PASSED_NULL_PARAMETER); - return 0; + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); + return NULL; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return NULL; ret = e->next; if (ret) { /* Return a valid structural reference to the next ENGINE */ ret->struct_ref++; - engine_ref_debug(ret, 0, 1); + ENGINE_REF_PRINT(ret, 0, 1); } CRYPTO_THREAD_unlock(global_engine_lock); /* Release the structural reference to the previous ENGINE */ @@ -275,15 +280,16 @@ ENGINE *ENGINE_get_prev(ENGINE *e) { ENGINE *ret = NULL; if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_GET_PREV, ERR_R_PASSED_NULL_PARAMETER); - return 0; + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); + return NULL; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return NULL; ret = e->prev; if (ret) { /* Return a valid structural reference to the next ENGINE */ ret->struct_ref++; - engine_ref_debug(ret, 0, 1); + ENGINE_REF_PRINT(ret, 0, 1); } CRYPTO_THREAD_unlock(global_engine_lock); /* Release the structural reference to the previous ENGINE */ @@ -296,16 +302,17 @@ int ENGINE_add(ENGINE *e) { int to_return = 1; if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_ADD, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } if ((e->id == NULL) || (e->name == NULL)) { - ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_ID_OR_NAME_MISSING); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ID_OR_NAME_MISSING); return 0; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return 0; if (!engine_list_add(e)) { - ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_INTERNAL_LIST_ERROR); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); to_return = 0; } CRYPTO_THREAD_unlock(global_engine_lock); @@ -317,12 +324,13 @@ int ENGINE_remove(ENGINE *e) { int to_return = 1; if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_REMOVE, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return 0; if (!engine_list_remove(e)) { - ENGINEerr(ENGINE_F_ENGINE_REMOVE, ENGINE_R_INTERNAL_LIST_ERROR); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); to_return = 0; } CRYPTO_THREAD_unlock(global_engine_lock); @@ -333,9 +341,7 @@ static void engine_cpy(ENGINE *dest, const ENGINE *src) { dest->id = src->id; dest->name = src->name; -#ifndef OPENSSL_NO_RSA dest->rsa_meth = src->rsa_meth; -#endif #ifndef OPENSSL_NO_DSA dest->dsa_meth = src->dsa_meth; #endif @@ -366,15 +372,18 @@ ENGINE *ENGINE_by_id(const char *id) ENGINE *iterator; char *load_dir = NULL; if (id == NULL) { - ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return NULL; } + ENGINE_load_builtin_engines(); + if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { - ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); return NULL; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return NULL; iterator = engine_list_head; while (iterator && (strcmp(id, iterator->id) != 0)) iterator = iterator->next; @@ -394,7 +403,7 @@ ENGINE *ENGINE_by_id(const char *id) } } else { iterator->struct_ref++; - engine_ref_debug(iterator, 0, 1); + ENGINE_REF_PRINT(iterator, 0, 1); } } CRYPTO_THREAD_unlock(global_engine_lock); @@ -418,8 +427,7 @@ ENGINE *ENGINE_by_id(const char *id) } notfound: ENGINE_free(iterator); - ENGINEerr(ENGINE_F_ENGINE_BY_ID, ENGINE_R_NO_SUCH_ENGINE); - ERR_add_error_data(2, "id=", id); + ERR_raise_data(ERR_LIB_ENGINE, ENGINE_R_NO_SUCH_ENGINE, "id=%s", id); return NULL; /* EEK! Experimental code ends */ } @@ -428,7 +436,7 @@ int ENGINE_up_ref(ENGINE *e) { int i; if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_UP_REF, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } CRYPTO_UP_REF(&e->struct_ref, &i, global_engine_lock); diff --git a/crypto/openssl/crypto/engine/eng_local.h b/crypto/openssl/crypto/engine/eng_local.h index e271222d76a8..03a86299cf88 100644 --- a/crypto/openssl/crypto/engine/eng_local.h +++ b/crypto/openssl/crypto/engine/eng_local.h @@ -2,7 +2,7 @@ * Copyright 2001-2021 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 + * 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 @@ -11,6 +11,7 @@ #ifndef OSSL_CRYPTO_ENGINE_ENG_LOCAL_H # define OSSL_CRYPTO_ENGINE_ENG_LOCAL_H +# include # include "internal/cryptlib.h" # include "crypto/engine.h" # include "internal/thread_once.h" @@ -19,27 +20,20 @@ extern CRYPTO_RWLOCK *global_engine_lock; /* - * If we compile with this symbol defined, then both reference counts in the - * ENGINE structure will be monitored with a line of output on stderr for - * each change. This prints the engine's pointer address (truncated to - * unsigned int), "struct" or "funct" to indicate the reference type, the - * before and after reference count, and the file:line-number pair. The - * "engine_ref_debug" statements must come *after* the change. + * This prints the engine's pointer address, "struct" or "funct" to + * indicate the reference type, the before and after reference count, and + * the file:line-number pair. The "ENGINE_REF_PRINT" statements must come + * *after* the change. */ -# ifdef ENGINE_REF_COUNT_DEBUG - -# define engine_ref_debug(e, isfunct, diff) \ - fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \ - (unsigned int)(e), (isfunct ? "funct" : "struct"), \ - ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \ - ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \ - (OPENSSL_FILE), (OPENSSL_LINE)) - -# else - -# define engine_ref_debug(e, isfunct, diff) - -# endif +# define ENGINE_REF_PRINT(e, isfunct, diff) \ + OSSL_TRACE6(ENGINE_REF_COUNT, \ + "engine: %p %s from %d to %d (%s:%d)\n", \ + (void *)(e), (isfunct ? "funct" : "struct"), \ + ((isfunct) \ + ? ((e)->funct_ref - (diff)) \ + : ((e)->struct_ref - (diff))), \ + ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \ + (OPENSSL_FILE), (OPENSSL_LINE)) /* * Any code that will need cleanup operations should use these functions to @@ -58,14 +52,6 @@ void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb); /* We need stacks of ENGINEs for use in eng_table.c */ DEFINE_STACK_OF(ENGINE) -/* - * If this symbol is defined then engine_table_select(), the function that is - * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults - * and functional references (etc), will display debugging summaries to - * stderr. - */ -/* #define ENGINE_TABLE_DEBUG */ - /* * This represents an implementation table. Dependent code should instantiate * it as a (ENGINE_TABLE *) pointer value set initially to NULL. @@ -76,13 +62,8 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, int setdefault); void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e); void engine_table_cleanup(ENGINE_TABLE **table); -# ifndef ENGINE_TABLE_DEBUG -ENGINE *engine_table_select(ENGINE_TABLE **table, int nid); -# else -ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, - int l); -# define engine_table_select(t,n) engine_table_select_tmp(t,n,OPENSSL_FILE,OPENSSL_LINE) -# endif +ENGINE *ossl_engine_table_select(ENGINE_TABLE **table, int nid, + const char *f, int l); typedef void (engine_table_doall_cb) (int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg); void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, diff --git a/crypto/openssl/crypto/engine/eng_openssl.c b/crypto/openssl/crypto/engine/eng_openssl.c index 25631fb879ee..91656e6b8084 100644 --- a/crypto/openssl/crypto/engine/eng_openssl.c +++ b/crypto/openssl/crypto/engine/eng_openssl.c @@ -1,13 +1,22 @@ /* - * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 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 + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + +/* + * RC4 and SHA-1 low level APIs and EVP _meth_ APISs are deprecated for public + * use, but still ok for internal use. + */ +#include "internal/deprecated.h" + #include #include #include "internal/cryptlib.h" @@ -89,9 +98,7 @@ static int bind_helper(ENGINE *e) || !ENGINE_set_name(e, engine_openssl_name) || !ENGINE_set_destroy_function(e, openssl_destroy) #ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS -# ifndef OPENSSL_NO_RSA || !ENGINE_set_RSA(e, RSA_get_default_method()) -# endif # ifndef OPENSSL_NO_DSA || !ENGINE_set_DSA(e, DSA_get_default_method()) # endif @@ -143,13 +150,20 @@ void engine_load_openssl_int(void) ENGINE *toadd = engine_openssl(); if (!toadd) return; + + ERR_set_mark(); ENGINE_add(toadd); /* * If the "add" worked, it gets a structural reference. So either way, we * release our just-created reference. */ ENGINE_free(toadd); - ERR_clear_error(); + /* + * If the "add" didn't work, it was probably a conflict because it was + * already added (eg. someone calling ENGINE_load_blah then calling + * ENGINE_load_builtin_engines() perhaps). + */ + ERR_pop_to_mark(); } /* @@ -167,7 +181,7 @@ static int bind_fn(ENGINE *e, const char *id) } IMPLEMENT_DYNAMIC_CHECK_FN() -IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) + IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) #endif /* ENGINE_DYNAMIC_SUPPORT */ #ifdef TEST_ENG_OPENSSL_RC4 /*- @@ -191,12 +205,15 @@ typedef struct { static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { + const int n = EVP_CIPHER_CTX_get_key_length(ctx); + # ifdef TEST_ENG_OPENSSL_RC4_P_INIT fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n"); # endif - memcpy(&test(ctx)->key[0], key, EVP_CIPHER_CTX_key_length(ctx)); - RC4_set_key(&test(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), - test(ctx)->key); + if (n <= 0) + return n; + memcpy(&test(ctx)->key[0], key, n); + RC4_set_key(&test(ctx)->ks, n, test(ctx)->key); return 1; } @@ -268,9 +285,9 @@ static int test_cipher_nids(const int **nids) if (!init) { const EVP_CIPHER *cipher; if ((cipher = test_r4_cipher()) != NULL) - cipher_nids[pos++] = EVP_CIPHER_nid(cipher); + cipher_nids[pos++] = EVP_CIPHER_get_nid(cipher); if ((cipher = test_r4_40_cipher()) != NULL) - cipher_nids[pos++] = EVP_CIPHER_nid(cipher); + cipher_nids[pos++] = EVP_CIPHER_get_nid(cipher); cipher_nids[pos] = 0; init = 1; } @@ -311,7 +328,7 @@ static int test_sha1_init(EVP_MD_CTX *ctx) # ifdef TEST_ENG_OPENSSL_SHA_P_INIT fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n"); # endif - return SHA1_Init(EVP_MD_CTX_md_data(ctx)); + return SHA1_Init(EVP_MD_CTX_get0_md_data(ctx)); } static int test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) @@ -319,7 +336,7 @@ static int test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) # ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n"); # endif - return SHA1_Update(EVP_MD_CTX_md_data(ctx), data, count); + return SHA1_Update(EVP_MD_CTX_get0_md_data(ctx), data, count); } static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) @@ -327,7 +344,7 @@ static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) # ifdef TEST_ENG_OPENSSL_SHA_P_FINAL fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n"); # endif - return SHA1_Final(md, EVP_MD_CTX_md_data(ctx)); + return SHA1_Final(md, EVP_MD_CTX_get0_md_data(ctx)); } static EVP_MD *sha1_md = NULL; @@ -366,7 +383,7 @@ static int test_digest_nids(const int **nids) if (!init) { const EVP_MD *md; if ((md = test_sha_md()) != NULL) - digest_nids[pos++] = EVP_MD_type(md); + digest_nids[pos++] = EVP_MD_get_type(md); digest_nids[pos] = 0; init = 1; } @@ -434,7 +451,7 @@ static int ossl_hmac_init(EVP_PKEY_CTX *ctx) OSSL_HMAC_PKEY_CTX *hctx; if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) { - ENGINEerr(ENGINE_F_OSSL_HMAC_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); return 0; } hctx->ktmp.type = V_ASN1_OCTET_STRING; @@ -505,7 +522,7 @@ static int ossl_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) static int ossl_int_update(EVP_MD_CTX *ctx, const void *data, size_t count) { - OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx)); + OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_get_pkey_ctx(ctx)); if (!HMAC_Update(hctx->ctx, data, count)) return 0; return 1; @@ -523,7 +540,7 @@ static int ossl_hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, { unsigned int hlen; OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); - int l = EVP_MD_CTX_size(mctx); + int l = EVP_MD_CTX_get_size(mctx); if (l < 0) return 0; @@ -622,7 +639,8 @@ static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth, EVP_PKEY_HMAC, 0 }; - if (!pmeth) { + + if (pmeth == NULL) { *nids = ossl_pkey_nids; return 1; } diff --git a/crypto/openssl/crypto/engine/eng_pkey.c b/crypto/openssl/crypto/engine/eng_pkey.c index e813bc6db0e6..6e6d6df35b2b 100644 --- a/crypto/openssl/crypto/engine/eng_pkey.c +++ b/crypto/openssl/crypto/engine/eng_pkey.c @@ -1,12 +1,15 @@ /* - * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" /* Basic get/set stuff */ @@ -56,27 +59,25 @@ EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, EVP_PKEY *pkey; if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, - ERR_R_PASSED_NULL_PARAMETER); - return 0; + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); + return NULL; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return NULL; if (e->funct_ref == 0) { CRYPTO_THREAD_unlock(global_engine_lock); - ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, ENGINE_R_NOT_INITIALISED); - return 0; + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NOT_INITIALISED); + return NULL; } CRYPTO_THREAD_unlock(global_engine_lock); if (!e->load_privkey) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, - ENGINE_R_NO_LOAD_FUNCTION); - return 0; + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_LOAD_FUNCTION); + return NULL; } pkey = e->load_privkey(e, key_id, ui_method, callback_data); - if (!pkey) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, - ENGINE_R_FAILED_LOADING_PRIVATE_KEY); - return 0; + if (pkey == NULL) { + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PRIVATE_KEY); + return NULL; } return pkey; } @@ -87,26 +88,25 @@ EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, EVP_PKEY *pkey; if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, - ERR_R_PASSED_NULL_PARAMETER); - return 0; + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); + return NULL; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return NULL; if (e->funct_ref == 0) { CRYPTO_THREAD_unlock(global_engine_lock); - ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NOT_INITIALISED); - return 0; + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NOT_INITIALISED); + return NULL; } CRYPTO_THREAD_unlock(global_engine_lock); if (!e->load_pubkey) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NO_LOAD_FUNCTION); - return 0; + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_LOAD_FUNCTION); + return NULL; } pkey = e->load_pubkey(e, key_id, ui_method, callback_data); - if (!pkey) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, - ENGINE_R_FAILED_LOADING_PUBLIC_KEY); - return 0; + if (pkey == NULL) { + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PUBLIC_KEY); + return NULL; } return pkey; } @@ -118,21 +118,19 @@ int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, { if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, - ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return 0; if (e->funct_ref == 0) { CRYPTO_THREAD_unlock(global_engine_lock); - ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, - ENGINE_R_NOT_INITIALISED); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NOT_INITIALISED); return 0; } CRYPTO_THREAD_unlock(global_engine_lock); if (!e->load_ssl_client_cert) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, - ENGINE_R_NO_LOAD_FUNCTION); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_LOAD_FUNCTION); return 0; } return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother, diff --git a/crypto/openssl/crypto/engine/eng_rdrand.c b/crypto/openssl/crypto/engine/eng_rdrand.c index 9dceb1671099..f46a5145974e 100644 --- a/crypto/openssl/crypto/engine/eng_rdrand.c +++ b/crypto/openssl/crypto/engine/eng_rdrand.c @@ -1,17 +1,21 @@ /* - * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include #include "crypto/engine.h" +#include "internal/cryptlib.h" #include #include #include @@ -79,15 +83,23 @@ static ENGINE *ENGINE_rdrand(void) void engine_load_rdrand_int(void) { - extern unsigned int OPENSSL_ia32cap_P[]; - if (OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) { ENGINE *toadd = ENGINE_rdrand(); if (!toadd) return; + ERR_set_mark(); ENGINE_add(toadd); + /* + * If the "add" worked, it gets a structural reference. So either way, we + * release our just-created reference. + */ ENGINE_free(toadd); - ERR_clear_error(); + /* + * If the "add" didn't work, it was probably a conflict because it was + * already added (eg. someone calling ENGINE_load_blah then calling + * ENGINE_load_builtin_engines() perhaps). + */ + ERR_pop_to_mark(); } } #else diff --git a/crypto/openssl/crypto/engine/eng_table.c b/crypto/openssl/crypto/engine/eng_table.c index 72f393dbe143..a8209d9e7176 100644 --- a/crypto/openssl/crypto/engine/eng_table.c +++ b/crypto/openssl/crypto/engine/eng_table.c @@ -1,7 +1,7 @@ /* - * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,6 +10,7 @@ #include "internal/cryptlib.h" #include #include +#include #include "eng_local.h" /* The type of the items in the table */ @@ -85,7 +86,9 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, { int ret = 0, added = 0; ENGINE_PILE tmplate, *fnd; - CRYPTO_THREAD_write_lock(global_engine_lock); + + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return 0; if (!(*table)) added = 1; if (!int_table_check(table, 1)) @@ -126,8 +129,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, fnd->uptodate = 0; if (setdefault) { if (!engine_unlocked_init(e)) { - ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, - ENGINE_R_INIT_FAILED); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INIT_FAILED); goto end; } if (fnd->funct) @@ -161,7 +163,9 @@ IMPLEMENT_LHASH_DOALL_ARG(ENGINE_PILE, ENGINE); void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) { - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + /* Can't return a value. :( */ + return; if (int_table_check(table, 0)) lh_ENGINE_PILE_doall_ENGINE(&(*table)->piles, int_unregister_cb, e); CRYPTO_THREAD_unlock(global_engine_lock); @@ -169,7 +173,7 @@ void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) static void int_cleanup_cb_doall(ENGINE_PILE *p) { - if (!p) + if (p == NULL) return; sk_ENGINE_free(p->sk); if (p->funct) @@ -179,7 +183,8 @@ static void int_cleanup_cb_doall(ENGINE_PILE *p) void engine_table_cleanup(ENGINE_TABLE **table) { - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return; if (*table) { lh_ENGINE_PILE_doall(&(*table)->piles, int_cleanup_cb_doall); lh_ENGINE_PILE_free(&(*table)->piles); @@ -189,29 +194,28 @@ void engine_table_cleanup(ENGINE_TABLE **table) } /* return a functional reference for a given 'nid' */ -#ifndef ENGINE_TABLE_DEBUG -ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) -#else -ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, - int l) -#endif +ENGINE *ossl_engine_table_select(ENGINE_TABLE **table, int nid, + const char *f, int l) { ENGINE *ret = NULL; ENGINE_PILE tmplate, *fnd = NULL; int initres, loop = 0; + /* Load the config before trying to check if engines are available */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + if (!(*table)) { -#ifdef ENGINE_TABLE_DEBUG - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing " - "registered!\n", f, l, nid); -#endif + OSSL_TRACE3(ENGINE_TABLE, + "%s:%d, nid=%d, nothing registered!\n", + f, l, nid); return NULL; } ERR_set_mark(); - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + goto end; /* * Check again inside the lock otherwise we could race against cleanup - * operations. But don't worry about a fprintf(stderr). + * operations. But don't worry about a debug printout */ if (!int_table_check(table, 0)) goto end; @@ -220,10 +224,9 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, if (!fnd) goto end; if (fnd->funct && engine_unlocked_init(fnd->funct)) { -#ifdef ENGINE_TABLE_DEBUG - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " - "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); -#endif + OSSL_TRACE4(ENGINE_TABLE, + "%s:%d, nid=%d, using ENGINE '%s' cached\n", + f, l, nid, fnd->funct->id); ret = fnd->funct; goto end; } @@ -234,10 +237,10 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, trynext: ret = sk_ENGINE_value(fnd->sk, loop++); if (!ret) { -#ifdef ENGINE_TABLE_DEBUG - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " - "registered implementations would initialise\n", f, l, nid); -#endif + OSSL_TRACE3(ENGINE_TABLE, + "%s:%d, nid=%d, " + "no registered implementations would initialise\n", + f, l, nid); goto end; } /* Try to initialise the ENGINE? */ @@ -252,15 +255,13 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, if (fnd->funct) engine_unlocked_finish(fnd->funct, 0); fnd->funct = ret; -#ifdef ENGINE_TABLE_DEBUG - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " - "setting default to '%s'\n", f, l, nid, ret->id); -#endif + OSSL_TRACE4(ENGINE_TABLE, + "%s:%d, nid=%d, setting default to '%s'\n", + f, l, nid, ret->id); } -#ifdef ENGINE_TABLE_DEBUG - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " - "newly initialised '%s'\n", f, l, nid, ret->id); -#endif + OSSL_TRACE4(ENGINE_TABLE, + "%s:%d, nid=%d, using newly initialised '%s'\n", + f, l, nid, ret->id); goto end; } goto trynext; @@ -271,14 +272,14 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, */ if (fnd) fnd->uptodate = 1; -#ifdef ENGINE_TABLE_DEBUG if (ret) - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " - "ENGINE '%s'\n", f, l, nid, ret->id); + OSSL_TRACE4(ENGINE_TABLE, + "%s:%d, nid=%d, caching ENGINE '%s'\n", + f, l, nid, ret->id); else - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " - "'no matching ENGINE'\n", f, l, nid); -#endif + OSSL_TRACE3(ENGINE_TABLE, + "%s:%d, nid=%d, caching 'no matching ENGINE'\n", + f, l, nid); CRYPTO_THREAD_unlock(global_engine_lock); /* * Whatever happened, any failed init()s are not failures in this diff --git a/crypto/openssl/crypto/engine/tb_asnmth.c b/crypto/openssl/crypto/engine/tb_asnmth.c index 72850b9398e3..81f8e7add0e7 100644 --- a/crypto/openssl/crypto/engine/tb_asnmth.c +++ b/crypto/openssl/crypto/engine/tb_asnmth.c @@ -1,12 +1,15 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "e_os.h" #include "eng_local.h" #include @@ -73,7 +76,8 @@ int ENGINE_set_default_pkey_asn1_meths(ENGINE *e) */ ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid) { - return engine_table_select(&pkey_asn1_meth_table, nid); + return ossl_engine_table_select(&pkey_asn1_meth_table, nid, + OPENSSL_FILE, OPENSSL_LINE); } /* @@ -85,8 +89,7 @@ const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid) EVP_PKEY_ASN1_METHOD *ret; ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e); if (!fn || !fn(e, &ret, NULL, nid)) { - ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH, - ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); return NULL; } return ret; @@ -149,7 +152,7 @@ const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, e->pkey_asn1_meths(e, &ameth, NULL, nids[i]); if (ameth != NULL && ((int)strlen(ameth->pem_str) == len) - && strncasecmp(ameth->pem_str, str, len) == 0) + && OPENSSL_strncasecmp(ameth->pem_str, str, len) == 0) return ameth; } return NULL; @@ -174,7 +177,7 @@ static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg) e->pkey_asn1_meths(e, &ameth, NULL, nid); if (ameth != NULL && ((int)strlen(ameth->pem_str) == lk->len) - && strncasecmp(ameth->pem_str, lk->str, lk->len) == 0) { + && OPENSSL_strncasecmp(ameth->pem_str, lk->str, lk->len) == 0) { lk->e = e; lk->ameth = ameth; return; @@ -193,16 +196,17 @@ const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, fstr.len = len; if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { - ENGINEerr(ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); return NULL; } - CRYPTO_THREAD_write_lock(global_engine_lock); + if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + return NULL; engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr); /* If found obtain a structural reference to engine */ if (fstr.e) { fstr.e->struct_ref++; - engine_ref_debug(fstr.e, 0, 1); + ENGINE_REF_PRINT(fstr.e, 0, 1); } *pe = fstr.e; CRYPTO_THREAD_unlock(global_engine_lock); diff --git a/crypto/openssl/crypto/engine/tb_cipher.c b/crypto/openssl/crypto/engine/tb_cipher.c index 236da346cd4c..037f5687524f 100644 --- a/crypto/openssl/crypto/engine/tb_cipher.c +++ b/crypto/openssl/crypto/engine/tb_cipher.c @@ -1,12 +1,15 @@ /* - * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" static ENGINE_TABLE *cipher_table = NULL; @@ -62,7 +65,8 @@ int ENGINE_set_default_ciphers(ENGINE *e) */ ENGINE *ENGINE_get_cipher_engine(int nid) { - return engine_table_select(&cipher_table, nid); + return ossl_engine_table_select(&cipher_table, nid, + OPENSSL_FILE, OPENSSL_LINE); } /* Obtains a cipher implementation from an ENGINE functional reference */ @@ -71,7 +75,7 @@ const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid) const EVP_CIPHER *ret; ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e); if (!fn || !fn(e, &ret, NULL, nid)) { - ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER, ENGINE_R_UNIMPLEMENTED_CIPHER); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_CIPHER); return NULL; } return ret; diff --git a/crypto/openssl/crypto/engine/tb_dh.c b/crypto/openssl/crypto/engine/tb_dh.c index a13a13950083..e1fa45685b11 100644 --- a/crypto/openssl/crypto/engine/tb_dh.c +++ b/crypto/openssl/crypto/engine/tb_dh.c @@ -1,12 +1,15 @@ /* - * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" static ENGINE_TABLE *dh_table = NULL; @@ -55,7 +58,8 @@ int ENGINE_set_default_DH(ENGINE *e) */ ENGINE *ENGINE_get_default_DH(void) { - return engine_table_select(&dh_table, dummy_nid); + return ossl_engine_table_select(&dh_table, dummy_nid, + OPENSSL_FILE, OPENSSL_LINE); } /* Obtains an DH implementation from an ENGINE functional reference */ diff --git a/crypto/openssl/crypto/engine/tb_digest.c b/crypto/openssl/crypto/engine/tb_digest.c index a6e6337a01d9..dcc70eca4587 100644 --- a/crypto/openssl/crypto/engine/tb_digest.c +++ b/crypto/openssl/crypto/engine/tb_digest.c @@ -1,12 +1,15 @@ /* - * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" static ENGINE_TABLE *digest_table = NULL; @@ -62,7 +65,8 @@ int ENGINE_set_default_digests(ENGINE *e) */ ENGINE *ENGINE_get_digest_engine(int nid) { - return engine_table_select(&digest_table, nid); + return ossl_engine_table_select(&digest_table, nid, + OPENSSL_FILE, OPENSSL_LINE); } /* Obtains a digest implementation from an ENGINE functional reference */ @@ -71,7 +75,7 @@ const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid) const EVP_MD *ret; ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e); if (!fn || !fn(e, &ret, NULL, nid)) { - ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST, ENGINE_R_UNIMPLEMENTED_DIGEST); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_DIGEST); return NULL; } return ret; diff --git a/crypto/openssl/crypto/engine/tb_dsa.c b/crypto/openssl/crypto/engine/tb_dsa.c index 2c77f0f3e151..6de314b7fcbe 100644 --- a/crypto/openssl/crypto/engine/tb_dsa.c +++ b/crypto/openssl/crypto/engine/tb_dsa.c @@ -1,12 +1,15 @@ /* - * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" static ENGINE_TABLE *dsa_table = NULL; @@ -55,7 +58,8 @@ int ENGINE_set_default_DSA(ENGINE *e) */ ENGINE *ENGINE_get_default_DSA(void) { - return engine_table_select(&dsa_table, dummy_nid); + return ossl_engine_table_select(&dsa_table, dummy_nid, + OPENSSL_FILE, OPENSSL_LINE); } /* Obtains an DSA implementation from an ENGINE functional reference */ diff --git a/crypto/openssl/crypto/engine/tb_eckey.c b/crypto/openssl/crypto/engine/tb_eckey.c index 907d55ae8c44..0394a5bc220a 100644 --- a/crypto/openssl/crypto/engine/tb_eckey.c +++ b/crypto/openssl/crypto/engine/tb_eckey.c @@ -1,12 +1,15 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" static ENGINE_TABLE *dh_table = NULL; @@ -55,7 +58,8 @@ int ENGINE_set_default_EC(ENGINE *e) */ ENGINE *ENGINE_get_default_EC(void) { - return engine_table_select(&dh_table, dummy_nid); + return ossl_engine_table_select(&dh_table, dummy_nid, + OPENSSL_FILE, OPENSSL_LINE); } /* Obtains an EC_KEY implementation from an ENGINE functional reference */ diff --git a/crypto/openssl/crypto/engine/tb_pkmeth.c b/crypto/openssl/crypto/engine/tb_pkmeth.c index c5c001c5cbec..5c3da1136d2b 100644 --- a/crypto/openssl/crypto/engine/tb_pkmeth.c +++ b/crypto/openssl/crypto/engine/tb_pkmeth.c @@ -1,12 +1,15 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some deprecated APIs */ +#include "internal/deprecated.h" + #include "eng_local.h" #include @@ -63,7 +66,8 @@ int ENGINE_set_default_pkey_meths(ENGINE *e) */ ENGINE *ENGINE_get_pkey_meth_engine(int nid) { - return engine_table_select(&pkey_meth_table, nid); + return ossl_engine_table_select(&pkey_meth_table, nid, + OPENSSL_FILE, OPENSSL_LINE); } /* Obtains a pkey_meth implementation from an ENGINE functional reference */ @@ -72,8 +76,7 @@ const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid) EVP_PKEY_METHOD *ret; ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e); if (!fn || !fn(e, &ret, NULL, nid)) { - ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH, - ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); return NULL; } return ret; diff --git a/crypto/openssl/crypto/engine/tb_rand.c b/crypto/openssl/crypto/engine/tb_rand.c index 92f61c5a8840..991a4914eafe 100644 --- a/crypto/openssl/crypto/engine/tb_rand.c +++ b/crypto/openssl/crypto/engine/tb_rand.c @@ -1,12 +1,15 @@ /* - * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" static ENGINE_TABLE *rand_table = NULL; @@ -55,7 +58,8 @@ int ENGINE_set_default_RAND(ENGINE *e) */ ENGINE *ENGINE_get_default_RAND(void) { - return engine_table_select(&rand_table, dummy_nid); + return ossl_engine_table_select(&rand_table, dummy_nid, + OPENSSL_FILE, OPENSSL_LINE); } /* Obtains an RAND implementation from an ENGINE functional reference */ diff --git a/crypto/openssl/crypto/engine/tb_rsa.c b/crypto/openssl/crypto/engine/tb_rsa.c index 43e865e6d6d1..b68b8f0ca74e 100644 --- a/crypto/openssl/crypto/engine/tb_rsa.c +++ b/crypto/openssl/crypto/engine/tb_rsa.c @@ -1,12 +1,15 @@ /* - * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "eng_local.h" static ENGINE_TABLE *rsa_table = NULL; @@ -55,7 +58,8 @@ int ENGINE_set_default_RSA(ENGINE *e) */ ENGINE *ENGINE_get_default_RSA(void) { - return engine_table_select(&rsa_table, dummy_nid); + return ossl_engine_table_select(&rsa_table, dummy_nid, + OPENSSL_FILE, OPENSSL_LINE); } /* Obtains an RSA implementation from an ENGINE functional reference */ diff --git a/crypto/openssl/crypto/err/README b/crypto/openssl/crypto/err/README deleted file mode 100644 index 6d2ce0cd0ee8..000000000000 --- a/crypto/openssl/crypto/err/README +++ /dev/null @@ -1,44 +0,0 @@ -Adding new libraries --------------------- - -When adding a new sub-library to OpenSSL, assign it a library number -ERR_LIB_XXX, define a macro XXXerr() (both in err.h), add its -name to ERR_str_libraries[] (in crypto/err/err.c), and add -ERR_load_XXX_strings() to the ERR_load_crypto_strings() function -(in crypto/err/err_all.c). Finally, add an entry: - - L XXX xxx.h xxx_err.c - -to crypto/err/openssl.ec, and add xxx_err.c to the Makefile. -Running make errors will then generate a file xxx_err.c, and -add all error codes used in the library to xxx.h. - -Additionally the library include file must have a certain form. -Typically it will initially look like this: - - #ifndef HEADER_XXX_H - #define HEADER_XXX_H - - #ifdef __cplusplus - extern "C" { - #endif - - /* Include files */ - - #include - #include - - /* Macros, structures and function prototypes */ - - - /* BEGIN ERROR CODES */ - -The BEGIN ERROR CODES sequence is used by the error code -generation script as the point to place new error codes, any text -after this point will be overwritten when make errors is run. -The closing #endif etc will be automatically added by the script. - -The generated C error code file xxx_err.c will load the header -files stdio.h, openssl/err.h and openssl/xxx.h so the -header file must load any additional header files containing any -definitions it uses. diff --git a/crypto/openssl/crypto/err/README.md b/crypto/openssl/crypto/err/README.md new file mode 100644 index 000000000000..477dffa2ad32 --- /dev/null +++ b/crypto/openssl/crypto/err/README.md @@ -0,0 +1,55 @@ +Adding new libraries +==================== + +When adding a new sub-library to OpenSSL, assign it a library number +`ERR_LIB_XXX`, define a macro `XXXerr()` (both in `err.h`), add its +name to `ERR_str_libraries[]` (in `crypto/err/err.c`), and add +`ERR_load_XXX_strings()` to the `ERR_load_crypto_strings()` function +(in `crypto/err/err_all.c`). Finally, add an entry: + + L XXX xxx.h xxx_err.c + +to `crypto/err/openssl.ec`, and add `xxx_err.c` to the `Makefile`. +Running make errors will then generate a file `xxx_err.c`, and +add all error codes used in the library to `xxx.h`. + +Additionally the library include file must have a certain form. +Typically it will initially look like this: + + #ifndef HEADER_XXX_H + #define HEADER_XXX_H + + #ifdef __cplusplus + extern "C" { + #endif + + /* Include files */ + + #include + #include + + /* Macros, structures and function prototypes */ + + + /* BEGIN ERROR CODES */ + +The `BEGIN ERROR CODES` sequence is used by the error code +generation script as the point to place new error codes, any text +after this point will be overwritten when make errors is run. +The closing `#endif` etc will be automatically added by the script. + +The generated C error code file `xxx_err.c` will load the header +files `stdio.h`, `openssl/err.h` and `openssl/xxx.h` so the +header file must load any additional header files containing any +definitions it uses. + +Adding new error codes +====================== + +Instead of manually adding error codes into `crypto/err/openssl.txt`, +it is recommended to leverage `make update` for error code generation. +The target will process relevant sources and generate error codes for +any *used* error codes. + +If an error code is added manually into `crypto/err/openssl.txt`, +subsequent `make update` has no effect. diff --git a/crypto/openssl/crypto/err/build.info b/crypto/openssl/crypto/err/build.info index 6163d95b74f3..98f8801e34a6 100644 --- a/crypto/openssl/crypto/err/build.info +++ b/crypto/openssl/crypto/err/build.info @@ -1,3 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - err.c err_all.c err_prn.c + err_blocks.c err.c err_all.c err_all_legacy.c err_prn.c diff --git a/crypto/openssl/crypto/err/err.c b/crypto/openssl/crypto/err/err.c index 239a3cea9cc2..ec55642308c4 100644 --- a/crypto/openssl/crypto/err/err.c +++ b/crypto/openssl/crypto/err/err.c @@ -1,12 +1,14 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +#define OSSL_FORCE_ERR_STATE + #include #include #include @@ -22,6 +24,10 @@ #include "crypto/ctype.h" #include "internal/constant_time.h" #include "e_os.h" +#include "err_local.h" + +/* Forward declaration in case it's not published because of configuration */ +ERR_STATE *ERR_get_state(void); #ifndef OPENSSL_NO_ERR static int err_load_strings(const ERR_STRING_DATA *str); @@ -60,45 +66,26 @@ static ERR_STRING_DATA ERR_str_libraries[] = { {ERR_PACK(ERR_LIB_UI, 0, 0), "UI routines"}, {ERR_PACK(ERR_LIB_FIPS, 0, 0), "FIPS routines"}, {ERR_PACK(ERR_LIB_CMS, 0, 0), "CMS routines"}, + {ERR_PACK(ERR_LIB_CRMF, 0, 0), "CRMF routines"}, + {ERR_PACK(ERR_LIB_CMP, 0, 0), "CMP routines"}, {ERR_PACK(ERR_LIB_HMAC, 0, 0), "HMAC routines"}, {ERR_PACK(ERR_LIB_CT, 0, 0), "CT routines"}, {ERR_PACK(ERR_LIB_ASYNC, 0, 0), "ASYNC routines"}, {ERR_PACK(ERR_LIB_KDF, 0, 0), "KDF routines"}, {ERR_PACK(ERR_LIB_OSSL_STORE, 0, 0), "STORE routines"}, {ERR_PACK(ERR_LIB_SM2, 0, 0), "SM2 routines"}, + {ERR_PACK(ERR_LIB_ESS, 0, 0), "ESS routines"}, + {ERR_PACK(ERR_LIB_PROV, 0, 0), "Provider routines"}, + {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, 0), "ENCODER routines"}, + {ERR_PACK(ERR_LIB_OSSL_DECODER, 0, 0), "DECODER routines"}, + {ERR_PACK(ERR_LIB_HTTP, 0, 0), "HTTP routines"}, {0, NULL}, }; -static ERR_STRING_DATA ERR_str_functs[] = { - {ERR_PACK(0, SYS_F_FOPEN, 0), "fopen"}, - {ERR_PACK(0, SYS_F_CONNECT, 0), "connect"}, - {ERR_PACK(0, SYS_F_GETSERVBYNAME, 0), "getservbyname"}, - {ERR_PACK(0, SYS_F_SOCKET, 0), "socket"}, - {ERR_PACK(0, SYS_F_IOCTLSOCKET, 0), "ioctlsocket"}, - {ERR_PACK(0, SYS_F_BIND, 0), "bind"}, - {ERR_PACK(0, SYS_F_LISTEN, 0), "listen"}, - {ERR_PACK(0, SYS_F_ACCEPT, 0), "accept"}, -#ifdef OPENSSL_SYS_WINDOWS - {ERR_PACK(0, SYS_F_WSASTARTUP, 0), "WSAstartup"}, -#endif - {ERR_PACK(0, SYS_F_OPENDIR, 0), "opendir"}, - {ERR_PACK(0, SYS_F_FREAD, 0), "fread"}, - {ERR_PACK(0, SYS_F_GETADDRINFO, 0), "getaddrinfo"}, - {ERR_PACK(0, SYS_F_GETNAMEINFO, 0), "getnameinfo"}, - {ERR_PACK(0, SYS_F_SETSOCKOPT, 0), "setsockopt"}, - {ERR_PACK(0, SYS_F_GETSOCKOPT, 0), "getsockopt"}, - {ERR_PACK(0, SYS_F_GETSOCKNAME, 0), "getsockname"}, - {ERR_PACK(0, SYS_F_GETHOSTBYNAME, 0), "gethostbyname"}, - {ERR_PACK(0, SYS_F_FFLUSH, 0), "fflush"}, - {ERR_PACK(0, SYS_F_OPEN, 0), "open"}, - {ERR_PACK(0, SYS_F_CLOSE, 0), "close"}, - {ERR_PACK(0, SYS_F_IOCTL, 0), "ioctl"}, - {ERR_PACK(0, SYS_F_STAT, 0), "stat"}, - {ERR_PACK(0, SYS_F_FCNTL, 0), "fcntl"}, - {ERR_PACK(0, SYS_F_FSTAT, 0), "fstat"}, - {0, NULL}, -}; - +/* + * Should make sure that all ERR_R_ reasons defined in include/openssl/err.h.in + * are listed. For maintainability, please keep all reasons in the same order. + */ static ERR_STRING_DATA ERR_str_reasons[] = { {ERR_R_SYS_LIB, "system lib"}, {ERR_R_BN_LIB, "BN lib"}, @@ -111,17 +98,16 @@ static ERR_STRING_DATA ERR_str_reasons[] = { {ERR_R_DSA_LIB, "DSA lib"}, {ERR_R_X509_LIB, "X509 lib"}, {ERR_R_ASN1_LIB, "ASN1 lib"}, + {ERR_R_CRYPTO_LIB, "CRYPTO lib"}, {ERR_R_EC_LIB, "EC lib"}, {ERR_R_BIO_LIB, "BIO lib"}, {ERR_R_PKCS7_LIB, "PKCS7 lib"}, {ERR_R_X509V3_LIB, "X509V3 lib"}, {ERR_R_ENGINE_LIB, "ENGINE lib"}, {ERR_R_UI_LIB, "UI lib"}, - {ERR_R_OSSL_STORE_LIB, "STORE lib"}, {ERR_R_ECDSA_LIB, "ECDSA lib"}, - - {ERR_R_NESTED_ASN1_ERROR, "nested asn1 error"}, - {ERR_R_MISSING_ASN1_EOS, "missing asn1 eos"}, + {ERR_R_OSSL_STORE_LIB, "OSSL_STORE lib"}, + {ERR_R_OSSL_DECODER_LIB, "OSSL_DECODER lib"}, {ERR_R_FATAL, "fatal"}, {ERR_R_MALLOC_FAILURE, "malloc failure"}, @@ -133,7 +119,22 @@ static ERR_STRING_DATA ERR_str_reasons[] = { {ERR_R_INIT_FAIL, "init fail"}, {ERR_R_PASSED_INVALID_ARGUMENT, "passed invalid argument"}, {ERR_R_OPERATION_FAIL, "operation fail"}, - + {ERR_R_INVALID_PROVIDER_FUNCTIONS, "invalid provider functions"}, + {ERR_R_INTERRUPTED_OR_CANCELLED, "interrupted or cancelled"}, + {ERR_R_NESTED_ASN1_ERROR, "nested asn1 error"}, + {ERR_R_MISSING_ASN1_EOS, "missing asn1 eos"}, + /* + * Something is unsupported, exactly what is expressed with additional data + */ + {ERR_R_UNSUPPORTED, "unsupported"}, + /* + * A fetch failed for other reasons than the name to be fetched being + * unsupported. + */ + {ERR_R_FETCH_FAILED, "fetch failed"}, + {ERR_R_INVALID_PROPERTY_DEFINITION, "invalid property definition"}, + {ERR_R_UNABLE_TO_GET_READ_LOCK, "unable to get read lock"}, + {ERR_R_UNABLE_TO_GET_WRITE_LOCK, "unable to get write lock"}, {0, NULL}, }; #endif @@ -158,8 +159,13 @@ static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL; #endif static int int_err_library_number = ERR_LIB_USER; -static unsigned long get_error_values(int inc, int top, const char **file, - int *line, const char **data, +typedef enum ERR_GET_ACTION_e { + EV_POP, EV_PEEK, EV_PEEK_LAST +} ERR_GET_ACTION; + +static unsigned long get_error_values(ERR_GET_ACTION g, + const char **file, int *line, + const char **func, const char **data, int *flags); #ifndef OPENSSL_NO_ERR @@ -168,7 +174,7 @@ static unsigned long err_string_data_hash(const ERR_STRING_DATA *a) unsigned long ret, l; l = a->error; - ret = l ^ ERR_GET_LIB(l) ^ ERR_GET_FUNC(l); + ret = l ^ ERR_GET_LIB(l); return (ret ^ ret % 19 * 13); } @@ -184,108 +190,15 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) { ERR_STRING_DATA *p = NULL; - CRYPTO_THREAD_read_lock(err_string_lock); + if (!CRYPTO_THREAD_read_lock(err_string_lock)) + return NULL; p = lh_ERR_STRING_DATA_retrieve(int_error_hash, d); CRYPTO_THREAD_unlock(err_string_lock); return p; } - -/* 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]; -/* - * SYS_str_reasons is filled with copies of strerror() results at - * initialization. 'errno' values up to 127 should cover all usual errors, - * others will be displayed numerically by ERR_error_string. It is crucial - * that we have something for each reason code that occurs in - * ERR_str_reasons, or bogus reason strings will be returned for SYSerr(), - * which always gets an errno value and never one of those 'standard' reason - * codes. - */ - -static void build_SYS_str_reasons(void) -{ - /* OPENSSL_malloc cannot be used here, use static storage instead */ - static char strerror_pool[SPACE_SYS_STR_REASONS]; - char *cur = strerror_pool; - size_t cnt = 0; - static int init = 1; - int i; - int saveerrno = get_last_sys_error(); - - CRYPTO_THREAD_write_lock(err_string_lock); - if (!init) { - CRYPTO_THREAD_unlock(err_string_lock); - return; - } - - for (i = 1; i <= NUM_SYS_STR_REASONS; i++) { - ERR_STRING_DATA *str = &SYS_str_reasons[i - 1]; - - str->error = ERR_PACK(ERR_LIB_SYS, 0, i); - /* - * 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; - cur += l; - - /* - * VMS has an unusual quirk of adding spaces at the end of - * some (most? all?) messages. Lets trim them off. - */ - while (cur > strerror_pool && ossl_isspace(cur[-1])) { - cur--; - cnt--; - } - *cur++ = '\0'; - cnt++; - } - } - if (str->string == NULL) - str->string = "unknown"; - } - - /* - * Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, as - * required by ERR_load_strings. - */ - - init = 0; - - CRYPTO_THREAD_unlock(err_string_lock); - /* openssl_strerror_r could change errno, but we want to preserve it */ - set_sys_error(saveerrno); - err_load_strings(SYS_str_reasons); -} #endif -#define err_clear_data(p, i) \ - do { \ - if ((p)->err_data_flags[i] & ERR_TXT_MALLOCED) {\ - OPENSSL_free((p)->err_data[i]); \ - (p)->err_data[i] = NULL; \ - } \ - (p)->err_data_flags[i] = 0; \ - } while (0) - -#define err_clear(p, i) \ - do { \ - err_clear_data(p, i); \ - (p)->err_flags[i] = 0; \ - (p)->err_buffer[i] = 0; \ - (p)->err_file[i] = NULL; \ - (p)->err_line[i] = -1; \ - } while (0) - static void ERR_STATE_free(ERR_STATE *s) { int i; @@ -293,14 +206,14 @@ static void ERR_STATE_free(ERR_STATE *s) if (s == NULL) return; for (i = 0; i < ERR_NUM_ERRORS; i++) { - err_clear_data(s, i); + err_clear(s, i, 1); } OPENSSL_free(s); } DEFINE_RUN_ONCE_STATIC(do_err_strings_init) { - if (!OPENSSL_init_crypto(0, NULL)) + if (!OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL)) return 0; err_string_lock = CRYPTO_THREAD_lock_new(); if (err_string_lock == NULL) @@ -342,11 +255,12 @@ static void err_patch(int lib, ERR_STRING_DATA *str) } /* - * Hash in |str| error strings. Assumes the URN_ONCE was done. + * Hash in |str| error strings. Assumes the RUN_ONCE was done. */ static int err_load_strings(const ERR_STRING_DATA *str) { - CRYPTO_THREAD_write_lock(err_string_lock); + if (!CRYPTO_THREAD_write_lock(err_string_lock)) + return 0; for (; str->error; str++) (void)lh_ERR_STRING_DATA_insert(int_error_hash, (ERR_STRING_DATA *)str); @@ -355,7 +269,7 @@ static int err_load_strings(const ERR_STRING_DATA *str) } #endif -int ERR_load_ERR_strings(void) +int ossl_err_load_ERR_strings(void) { #ifndef OPENSSL_NO_ERR if (!RUN_ONCE(&err_string_init, do_err_strings_init)) @@ -363,9 +277,6 @@ int ERR_load_ERR_strings(void) err_load_strings(ERR_str_libraries); err_load_strings(ERR_str_reasons); - err_patch(ERR_LIB_SYS, ERR_str_functs); - err_load_strings(ERR_str_functs); - build_SYS_str_reasons(); #endif return 1; } @@ -373,7 +284,7 @@ int ERR_load_ERR_strings(void) int ERR_load_strings(int lib, ERR_STRING_DATA *str) { #ifndef OPENSSL_NO_ERR - if (ERR_load_ERR_strings() == 0) + if (ossl_err_load_ERR_strings() == 0) return 0; err_patch(lib, str); @@ -386,7 +297,7 @@ int ERR_load_strings(int lib, ERR_STRING_DATA *str) int ERR_load_strings_const(const ERR_STRING_DATA *str) { #ifndef OPENSSL_NO_ERR - if (ERR_load_ERR_strings() == 0) + if (ossl_err_load_ERR_strings() == 0) return 0; err_load_strings(str); #endif @@ -400,7 +311,8 @@ int ERR_unload_strings(int lib, ERR_STRING_DATA *str) if (!RUN_ONCE(&err_string_init, do_err_strings_init)) return 0; - CRYPTO_THREAD_write_lock(err_string_lock); + if (!CRYPTO_THREAD_write_lock(err_string_lock)) + return 0; /* * We don't need to ERR_PACK the lib, since that was done (to * the table) when it was loaded. @@ -420,193 +332,199 @@ void err_free_strings_int(void) /********************************************************/ -void ERR_put_error(int lib, int func, int reason, const char *file, int line) -{ - ERR_STATE *es; - -#ifdef _OSD_POSIX - /* - * In the BS2000-OSD POSIX subsystem, the compiler generates path names - * in the form "*POSIX(/etc/passwd)". This dirty hack strips them to - * something sensible. @@@ We shouldn't modify a const string, though. - */ - if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) { - char *end; - - /* Skip the "*POSIX(" prefix */ - file += sizeof("*POSIX(") - 1; - end = &file[strlen(file) - 1]; - if (*end == ')') - *end = '\0'; - /* Optional: use the basename of the path only. */ - if ((end = strrchr(file, '/')) != NULL) - file = &end[1]; - } -#endif - es = ERR_get_state(); - if (es == NULL) - return; - - es->top = (es->top + 1) % ERR_NUM_ERRORS; - if (es->top == es->bottom) - es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS; - es->err_flags[es->top] = 0; - es->err_buffer[es->top] = ERR_PACK(lib, func, reason); - es->err_file[es->top] = file; - es->err_line[es->top] = line; - err_clear_data(es, es->top); -} - void ERR_clear_error(void) { int i; ERR_STATE *es; - es = ERR_get_state(); + es = ossl_err_get_state_int(); if (es == NULL) return; for (i = 0; i < ERR_NUM_ERRORS; i++) { - err_clear(es, i); + err_clear(es, i, 0); } es->top = es->bottom = 0; } unsigned long ERR_get_error(void) { - return get_error_values(1, 0, NULL, NULL, NULL, NULL); + return get_error_values(EV_POP, NULL, NULL, NULL, NULL, NULL); +} + +unsigned long ERR_get_error_all(const char **file, int *line, + const char **func, + const char **data, int *flags) +{ + return get_error_values(EV_POP, file, line, func, data, flags); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 unsigned long ERR_get_error_line(const char **file, int *line) { - return get_error_values(1, 0, file, line, NULL, NULL); + return get_error_values(EV_POP, file, line, NULL, NULL, NULL); } unsigned long ERR_get_error_line_data(const char **file, int *line, const char **data, int *flags) { - return get_error_values(1, 0, file, line, data, flags); + return get_error_values(EV_POP, file, line, NULL, data, flags); } +#endif unsigned long ERR_peek_error(void) { - return get_error_values(0, 0, NULL, NULL, NULL, NULL); + return get_error_values(EV_PEEK, NULL, NULL, NULL, NULL, NULL); } unsigned long ERR_peek_error_line(const char **file, int *line) { - return get_error_values(0, 0, file, line, NULL, NULL); + return get_error_values(EV_PEEK, file, line, NULL, NULL, NULL); } +unsigned long ERR_peek_error_func(const char **func) +{ + return get_error_values(EV_PEEK, NULL, NULL, func, NULL, NULL); +} + +unsigned long ERR_peek_error_data(const char **data, int *flags) +{ + return get_error_values(EV_PEEK, NULL, NULL, NULL, data, flags); +} + +unsigned long ERR_peek_error_all(const char **file, int *line, + const char **func, + const char **data, int *flags) +{ + return get_error_values(EV_PEEK, file, line, func, data, flags); +} + +#ifndef OPENSSL_NO_DEPRECATED_3_0 unsigned long ERR_peek_error_line_data(const char **file, int *line, const char **data, int *flags) { - return get_error_values(0, 0, file, line, data, flags); + return get_error_values(EV_PEEK, file, line, NULL, data, flags); } +#endif unsigned long ERR_peek_last_error(void) { - return get_error_values(0, 1, NULL, NULL, NULL, NULL); + return get_error_values(EV_PEEK_LAST, NULL, NULL, NULL, NULL, NULL); } unsigned long ERR_peek_last_error_line(const char **file, int *line) { - return get_error_values(0, 1, file, line, NULL, NULL); + return get_error_values(EV_PEEK_LAST, file, line, NULL, NULL, NULL); +} + +unsigned long ERR_peek_last_error_func(const char **func) +{ + return get_error_values(EV_PEEK_LAST, NULL, NULL, func, NULL, NULL); } +unsigned long ERR_peek_last_error_data(const char **data, int *flags) +{ + return get_error_values(EV_PEEK_LAST, NULL, NULL, NULL, data, flags); +} + +unsigned long ERR_peek_last_error_all(const char **file, int *line, + const char **func, + const char **data, int *flags) +{ + return get_error_values(EV_PEEK_LAST, file, line, func, data, flags); +} + +#ifndef OPENSSL_NO_DEPRECATED_3_0 unsigned long ERR_peek_last_error_line_data(const char **file, int *line, const char **data, int *flags) { - return get_error_values(0, 1, file, line, data, flags); + return get_error_values(EV_PEEK_LAST, file, line, NULL, data, flags); } +#endif -static unsigned long get_error_values(int inc, int top, const char **file, - int *line, const char **data, - int *flags) +static unsigned long get_error_values(ERR_GET_ACTION g, + const char **file, int *line, + const char **func, + const char **data, int *flags) { int i = 0; ERR_STATE *es; unsigned long ret; - es = ERR_get_state(); + es = ossl_err_get_state_int(); if (es == NULL) return 0; - if (inc && top) { - if (file) - *file = ""; - if (line) - *line = 0; - if (data) - *data = ""; - if (flags) - *flags = 0; - - return ERR_R_INTERNAL_ERROR; - } - + /* + * Clear anything that should have been cleared earlier. We do this + * here because this doesn't have constant-time issues. + */ while (es->bottom != es->top) { if (es->err_flags[es->top] & ERR_FLAG_CLEAR) { - err_clear(es, es->top); + err_clear(es, es->top, 0); es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1; continue; } i = (es->bottom + 1) % ERR_NUM_ERRORS; if (es->err_flags[i] & ERR_FLAG_CLEAR) { es->bottom = i; - err_clear(es, es->bottom); + err_clear(es, es->bottom, 0); continue; } break; } + /* If everything has been cleared, the stack is empty. */ if (es->bottom == es->top) return 0; - if (top) - i = es->top; /* last error */ + /* Which error, the top of stack (latest one) or the first one? */ + if (g == EV_PEEK_LAST) + i = es->top; else - i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */ + i = (es->bottom + 1) % ERR_NUM_ERRORS; ret = es->err_buffer[i]; - if (inc) { + if (g == EV_POP) { es->bottom = i; es->err_buffer[i] = 0; } - if (file != NULL && line != NULL) { - if (es->err_file[i] == NULL) { - *file = "NA"; - *line = 0; - } else { - *file = es->err_file[i]; - *line = es->err_line[i]; - } + if (file != NULL) { + *file = es->err_file[i]; + if (*file == NULL) + *file = ""; } - + if (line != NULL) + *line = es->err_line[i]; + if (func != NULL) { + *func = es->err_func[i]; + if (*func == NULL) + *func = ""; + } + if (flags != NULL) + *flags = es->err_data_flags[i]; if (data == NULL) { - if (inc) { - err_clear_data(es, i); + if (g == EV_POP) { + err_clear_data(es, i, 0); } } else { - if (es->err_data[i] == NULL) { + *data = es->err_data[i]; + if (*data == NULL) { *data = ""; if (flags != NULL) *flags = 0; - } else { - *data = es->err_data[i]; - if (flags != NULL) - *flags = es->err_data_flags[i]; } } return ret; } -void ERR_error_string_n(unsigned long e, char *buf, size_t len) +void ossl_err_string_int(unsigned long e, const char *func, + char *buf, size_t len) { - char lsbuf[64], fsbuf[64], rsbuf[64]; - const char *ls, *fs, *rs; - unsigned long l, f, r; + char lsbuf[64], rsbuf[256]; + const char *ls, *rs = NULL; + unsigned long l, r; if (len == 0) return; @@ -618,27 +536,39 @@ void ERR_error_string_n(unsigned long e, char *buf, size_t len) ls = lsbuf; } - fs = ERR_func_error_string(e); - f = ERR_GET_FUNC(e); - if (fs == NULL) { - BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f); - fs = fsbuf; - } - - rs = ERR_reason_error_string(e); + /* + * ERR_reason_error_string() can't safely return system error strings, + * since it would call openssl_strerror_r(), which needs a buffer for + * thread safety. So for system errors, we call openssl_strerror_r() + * directly instead. + */ r = ERR_GET_REASON(e); +#ifndef OPENSSL_NO_ERR + if (ERR_SYSTEM_ERROR(e)) { + if (openssl_strerror_r(r, rsbuf, sizeof(rsbuf))) + rs = rsbuf; + } else { + rs = ERR_reason_error_string(e); + } +#endif if (rs == NULL) { BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r); rs = rsbuf; } - BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, fs, rs); + BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, func, rs); if (strlen(buf) == len - 1) { /* Didn't fit; use a minimal format. */ - BIO_snprintf(buf, len, "err:%lx:%lx:%lx:%lx", e, l, f, r); + BIO_snprintf(buf, len, "err:%lx:%lx:%lx:%lx", e, l, 0L, r); } } + +void ERR_error_string_n(unsigned long e, char *buf, size_t len) +{ + ossl_err_string_int(e, "", buf, len); +} + /* * ERR_error_string_n should be used instead for ret != NULL as * ERR_error_string cannot know how large the buffer is @@ -672,25 +602,12 @@ const char *ERR_lib_error_string(unsigned long e) #endif } +#ifndef OPENSSL_NO_DEPRECATED_3_0 const char *ERR_func_error_string(unsigned long e) { -#ifndef OPENSSL_NO_ERR - ERR_STRING_DATA d, *p; - unsigned long l, f; - - if (!RUN_ONCE(&err_string_init, do_err_strings_init)) { - return NULL; - } - - l = ERR_GET_LIB(e); - f = ERR_GET_FUNC(e); - d.error = ERR_PACK(l, f, 0); - p = int_err_get_item(&d); - return ((p == NULL) ? NULL : p->string); -#else return NULL; -#endif } +#endif const char *ERR_reason_error_string(unsigned long e) { @@ -702,11 +619,19 @@ const char *ERR_reason_error_string(unsigned long e) return NULL; } + /* + * ERR_reason_error_string() can't safely return system error strings, + * since openssl_strerror_r() needs a buffer for thread safety, and we + * haven't got one that would serve any sensible purpose. + */ + if (ERR_SYSTEM_ERROR(e)) + return NULL; + l = ERR_GET_LIB(e); r = ERR_GET_REASON(e); d.error = ERR_PACK(l, 0, r); p = int_err_get_item(&d); - if (!p) { + if (p == NULL) { d.error = ERR_PACK(0, 0, r); p = int_err_get_item(&d); } @@ -716,7 +641,7 @@ const char *ERR_reason_error_string(unsigned long e) #endif } -void err_delete_thread_state(void) +static void err_delete_thread_state(void *unused) { ERR_STATE *state = CRYPTO_THREAD_get_local(&err_thread_local); if (state == NULL) @@ -726,13 +651,13 @@ void err_delete_thread_state(void) ERR_STATE_free(state); } -#if OPENSSL_API_COMPAT < 0x10100000L +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 void ERR_remove_thread_state(void *dummy) { } #endif -#if OPENSSL_API_COMPAT < 0x10000000L +#ifndef OPENSSL_NO_DEPRECATED_1_0_0 void ERR_remove_state(unsigned long pid) { } @@ -744,7 +669,7 @@ DEFINE_RUN_ONCE_STATIC(err_do_init) return CRYPTO_THREAD_init_local(&err_thread_local, NULL); } -ERR_STATE *ERR_get_state(void) +ERR_STATE *ossl_err_get_state_int(void) { ERR_STATE *state; int saveerrno = get_last_sys_error(); @@ -768,7 +693,7 @@ ERR_STATE *ERR_get_state(void) return NULL; } - if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE) + if (!ossl_init_thread_start(NULL, NULL, err_delete_thread_state) || !CRYPTO_THREAD_set_local(&err_thread_local, state)) { ERR_STATE_free(state); CRYPTO_THREAD_set_local(&err_thread_local, NULL); @@ -783,6 +708,14 @@ ERR_STATE *ERR_get_state(void) return state; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 +ERR_STATE *ERR_get_state(void) +{ + return ossl_err_get_state_int(); +} +#endif + + /* * err_shelve_state returns the current thread local error state * and freezes the error module until err_unshelve_state is called. @@ -834,26 +767,24 @@ int ERR_get_next_error_library(void) if (!RUN_ONCE(&err_string_init, do_err_strings_init)) return 0; - CRYPTO_THREAD_write_lock(err_string_lock); + if (!CRYPTO_THREAD_write_lock(err_string_lock)) + return 0; ret = int_err_library_number++; CRYPTO_THREAD_unlock(err_string_lock); return ret; } -static int err_set_error_data_int(char *data, int flags) +static int err_set_error_data_int(char *data, size_t size, int flags, + int deallocate) { ERR_STATE *es; - int i; - es = ERR_get_state(); + es = ossl_err_get_state_int(); if (es == NULL) return 0; - i = es->top; - - err_clear_data(es, i); - es->err_data[i] = data; - es->err_data_flags[i] = flags; + err_clear_data(es, es->top, deallocate); + err_set_data(es, es->top, data, size, flags); return 1; } @@ -863,8 +794,18 @@ void ERR_set_error_data(char *data, int flags) /* * This function is void so we cannot propagate the error return. Since it * is also in the public API we can't change the return type. + * + * We estimate the size of the data. If it's not flagged as allocated, + * then this is safe, and if it is flagged as allocated, then our size + * may be smaller than the actual allocation, but that doesn't matter + * too much, the buffer will remain untouched or will eventually be + * reallocated to a new size. + * + * callers should be advised that this function takes over ownership of + * the allocated memory, i.e. they can't count on the pointer to remain + * valid. */ - err_set_error_data_int(data, flags); + err_set_error_data_int(data, strlen(data) + 1, flags, 1); } void ERR_add_error_data(int num, ...) @@ -877,34 +818,60 @@ void ERR_add_error_data(int num, ...) void ERR_add_error_vdata(int num, va_list args) { - int i, n, s; - char *str, *p, *a; + int i, len, size; + int flags = ERR_TXT_MALLOCED | ERR_TXT_STRING; + char *str, *arg; + ERR_STATE *es; - s = 80; - if ((str = OPENSSL_malloc(s + 1)) == NULL) { - /* ERRerr(ERR_F_ERR_ADD_ERROR_VDATA, ERR_R_MALLOC_FAILURE); */ + /* Get the current error data; if an allocated string get it. */ + es = ossl_err_get_state_int(); + if (es == NULL) return; + i = es->top; + + /* + * If err_data is allocated already, re-use the space. + * Otherwise, allocate a small new buffer. + */ + if ((es->err_data_flags[i] & flags) == flags) { + str = es->err_data[i]; + size = es->err_data_size[i]; + + /* + * To protect the string we just grabbed from tampering by other + * functions we may call, or to protect them from freeing a pointer + * that may no longer be valid at that point, we clear away the + * data pointer and the flags. We will set them again at the end + * of this function. + */ + es->err_data[i] = NULL; + es->err_data_flags[i] = 0; + } else if ((str = OPENSSL_malloc(size = 81)) == NULL) { + return; + } else { + str[0] = '\0'; } - str[0] = '\0'; - - n = 0; - for (i = 0; i < num; i++) { - a = va_arg(args, char *); - if (a == NULL) - a = ""; - n += strlen(a); - if (n > s) { - s = n + 20; - p = OPENSSL_realloc(str, s + 1); + len = strlen(str); + + while (--num >= 0) { + arg = va_arg(args, char *); + if (arg == NULL) + arg = ""; + len += strlen(arg); + if (len >= size) { + char *p; + + size = len + 20; + p = OPENSSL_realloc(str, size); if (p == NULL) { OPENSSL_free(str); return; } str = p; } - OPENSSL_strlcat(str, a, (size_t)s + 1); + OPENSSL_strlcat(str, arg, (size_t)size); } - if (!err_set_error_data_int(str, ERR_TXT_MALLOCED | ERR_TXT_STRING)) + if (!err_set_error_data_int(str, size, flags, 0)) OPENSSL_free(str); } @@ -912,13 +879,13 @@ int ERR_set_mark(void) { ERR_STATE *es; - es = ERR_get_state(); + es = ossl_err_get_state_int(); if (es == NULL) return 0; if (es->bottom == es->top) return 0; - es->err_flags[es->top] |= ERR_FLAG_MARK; + es->err_marks[es->top]++; return 1; } @@ -926,19 +893,19 @@ int ERR_pop_to_mark(void) { ERR_STATE *es; - es = ERR_get_state(); + es = ossl_err_get_state_int(); if (es == NULL) return 0; while (es->bottom != es->top - && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { - err_clear(es, es->top); + && es->err_marks[es->top] == 0) { + err_clear(es, es->top, 0); es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1; } if (es->bottom == es->top) return 0; - es->err_flags[es->top] &= ~ERR_FLAG_MARK; + es->err_marks[es->top]--; return 1; } @@ -947,19 +914,19 @@ int ERR_clear_last_mark(void) ERR_STATE *es; int top; - es = ERR_get_state(); + es = ossl_err_get_state_int(); if (es == NULL) return 0; top = es->top; while (es->bottom != top - && (es->err_flags[top] & ERR_FLAG_MARK) == 0) { + && es->err_marks[top] == 0) { top = top > 0 ? top - 1 : ERR_NUM_ERRORS - 1; } if (es->bottom == top) return 0; - es->err_flags[top] &= ~ERR_FLAG_MARK; + es->err_marks[top]--; return 1; } @@ -968,7 +935,7 @@ void err_clear_last_constant_time(int clear) ERR_STATE *es; int top; - es = ERR_get_state(); + es = ossl_err_get_state_int(); if (es == NULL) return; diff --git a/crypto/openssl/crypto/err/err_all.c b/crypto/openssl/crypto/err/err_all.c index 7c0a5f0b9c5f..55aa2b8dbd56 100644 --- a/crypto/openssl/crypto/err/err_all.c +++ b/crypto/openssl/crypto/err/err_all.c @@ -1,100 +1,112 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include -#include "crypto/err.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "internal/dso.h" -#include -#include -#include #include -#include -#include -#include -#include -#include -#include +#include "crypto/err.h" +#include "crypto/cryptoerr.h" +#include "crypto/asn1err.h" +#include "crypto/bnerr.h" +#include "crypto/ecerr.h" +#include "crypto/buffererr.h" +#include "crypto/bioerr.h" +#include "crypto/comperr.h" +#include "crypto/rsaerr.h" +#include "crypto/dherr.h" +#include "crypto/dsaerr.h" +#include "crypto/evperr.h" +#include "crypto/objectserr.h" +#include "crypto/pemerr.h" +#include "crypto/pkcs7err.h" +#include "crypto/x509err.h" +#include "crypto/x509v3err.h" +#include "crypto/conferr.h" +#include "crypto/pkcs12err.h" +#include "crypto/randerr.h" +#include "internal/dsoerr.h" +#include "crypto/engineerr.h" +#include "crypto/uierr.h" +#include "crypto/httperr.h" +#include "crypto/ocsperr.h" +#include "crypto/tserr.h" +#include "crypto/cmserr.h" +#include "crypto/crmferr.h" +#include "crypto/cmperr.h" +#include "crypto/cterr.h" +#include "crypto/asyncerr.h" +#include "crypto/storeerr.h" +#include "crypto/esserr.h" +#include "internal/propertyerr.h" +#include "prov/proverr.h" -int err_load_crypto_strings_int(void) +int ossl_err_load_crypto_strings(void) { - if ( + if (0 #ifndef OPENSSL_NO_ERR - ERR_load_ERR_strings() == 0 || /* include error strings for SYSerr */ - ERR_load_BN_strings() == 0 || -# ifndef OPENSSL_NO_RSA - ERR_load_RSA_strings() == 0 || -# endif + || ossl_err_load_ERR_strings() == 0 /* include error strings for SYSerr */ + || ossl_err_load_BN_strings() == 0 + || ossl_err_load_RSA_strings() == 0 # ifndef OPENSSL_NO_DH - ERR_load_DH_strings() == 0 || + || ossl_err_load_DH_strings() == 0 # endif - ERR_load_EVP_strings() == 0 || - ERR_load_BUF_strings() == 0 || - ERR_load_OBJ_strings() == 0 || - ERR_load_PEM_strings() == 0 || + || ossl_err_load_EVP_strings() == 0 + || ossl_err_load_BUF_strings() == 0 + || ossl_err_load_OBJ_strings() == 0 + || ossl_err_load_PEM_strings() == 0 # ifndef OPENSSL_NO_DSA - ERR_load_DSA_strings() == 0 || + || ossl_err_load_DSA_strings() == 0 # endif - ERR_load_X509_strings() == 0 || - ERR_load_ASN1_strings() == 0 || - ERR_load_CONF_strings() == 0 || - ERR_load_CRYPTO_strings() == 0 || + || ossl_err_load_X509_strings() == 0 + || ossl_err_load_ASN1_strings() == 0 + || ossl_err_load_CONF_strings() == 0 + || ossl_err_load_CRYPTO_strings() == 0 # ifndef OPENSSL_NO_COMP - ERR_load_COMP_strings() == 0 || + || ossl_err_load_COMP_strings() == 0 # endif # ifndef OPENSSL_NO_EC - ERR_load_EC_strings() == 0 || + || ossl_err_load_EC_strings() == 0 # endif - /* skip ERR_load_SSL_strings() because it is not in this library */ - ERR_load_BIO_strings() == 0 || - ERR_load_PKCS7_strings() == 0 || - ERR_load_X509V3_strings() == 0 || - ERR_load_PKCS12_strings() == 0 || - ERR_load_RAND_strings() == 0 || - ERR_load_DSO_strings() == 0 || + /* skip ossl_err_load_SSL_strings() because it is not in this library */ + || ossl_err_load_BIO_strings() == 0 + || ossl_err_load_PKCS7_strings() == 0 + || ossl_err_load_X509V3_strings() == 0 + || ossl_err_load_PKCS12_strings() == 0 + || ossl_err_load_RAND_strings() == 0 + || ossl_err_load_DSO_strings() == 0 # ifndef OPENSSL_NO_TS - ERR_load_TS_strings() == 0 || + || ossl_err_load_TS_strings() == 0 # endif # ifndef OPENSSL_NO_ENGINE - ERR_load_ENGINE_strings() == 0 || + || ossl_err_load_ENGINE_strings() == 0 # endif + || ossl_err_load_HTTP_strings() == 0 # ifndef OPENSSL_NO_OCSP - ERR_load_OCSP_strings() == 0 || + || ossl_err_load_OCSP_strings() == 0 # endif - ERR_load_UI_strings() == 0 || + || ossl_err_load_UI_strings() == 0 # ifndef OPENSSL_NO_CMS - ERR_load_CMS_strings() == 0 || + || ossl_err_load_CMS_strings() == 0 +# endif +# ifndef OPENSSL_NO_CRMF + || ossl_err_load_CRMF_strings() == 0 + || ossl_err_load_CMP_strings() == 0 # endif # ifndef OPENSSL_NO_CT - ERR_load_CT_strings() == 0 || + || ossl_err_load_CT_strings() == 0 # endif - ERR_load_ASYNC_strings() == 0 || + || ossl_err_load_ESS_strings() == 0 + || ossl_err_load_ASYNC_strings() == 0 + || ossl_err_load_OSSL_STORE_strings() == 0 + || ossl_err_load_PROP_strings() == 0 + || ossl_err_load_PROV_strings() == 0 #endif - ERR_load_KDF_strings() == 0 || - ERR_load_OSSL_STORE_strings() == 0) + ) return 0; return 1; diff --git a/crypto/openssl/crypto/err/err_all_legacy.c b/crypto/openssl/crypto/err/err_all_legacy.c new file mode 100644 index 000000000000..64dd61867d6d --- /dev/null +++ b/crypto/openssl/crypto/err/err_all_legacy.c @@ -0,0 +1,106 @@ +/* + * Copyright 2020-2021 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 + */ + +/* This is the C source file where we include this header directly */ +#include + +#ifndef OPENSSL_NO_DEPRECATED_3_0 + +# include "crypto/err.h" +# include "crypto/asn1err.h" +# include "crypto/asyncerr.h" +# include "crypto/bnerr.h" +# include "crypto/buffererr.h" +# include "crypto/bioerr.h" +# include "crypto/cmserr.h" +# include "crypto/comperr.h" +# include "crypto/conferr.h" +# include "crypto/cryptoerr.h" +# include "crypto/cterr.h" +# include "crypto/dherr.h" +# include "crypto/dsaerr.h" +# include "internal/dsoerr.h" +# include "crypto/ecerr.h" +# include "crypto/engineerr.h" +# include "crypto/evperr.h" +# include "crypto/httperr.h" +# include "crypto/objectserr.h" +# include "crypto/ocsperr.h" +# include "crypto/pemerr.h" +# include "crypto/pkcs12err.h" +# include "crypto/pkcs7err.h" +# include "crypto/randerr.h" +# include "crypto/rsaerr.h" +# include "crypto/storeerr.h" +# include "crypto/tserr.h" +# include "crypto/uierr.h" +# include "crypto/x509err.h" +# include "crypto/x509v3err.h" + +# ifdef OPENSSL_NO_ERR +# define IMPLEMENT_LEGACY_ERR_LOAD(lib) \ + int ERR_load_##lib##_strings(void) \ + { \ + return 1; \ + } +# else +# define IMPLEMENT_LEGACY_ERR_LOAD(lib) \ + int ERR_load_##lib##_strings(void) \ + { \ + return ossl_err_load_##lib##_strings(); \ + } +# endif + +IMPLEMENT_LEGACY_ERR_LOAD(ASN1) +IMPLEMENT_LEGACY_ERR_LOAD(ASYNC) +IMPLEMENT_LEGACY_ERR_LOAD(BIO) +IMPLEMENT_LEGACY_ERR_LOAD(BN) +IMPLEMENT_LEGACY_ERR_LOAD(BUF) +# ifndef OPENSSL_NO_CMS +IMPLEMENT_LEGACY_ERR_LOAD(CMS) +# endif +# ifndef OPENSSL_NO_COMP +IMPLEMENT_LEGACY_ERR_LOAD(COMP) +# endif +IMPLEMENT_LEGACY_ERR_LOAD(CONF) +IMPLEMENT_LEGACY_ERR_LOAD(CRYPTO) +# ifndef OPENSSL_NO_CT +IMPLEMENT_LEGACY_ERR_LOAD(CT) +# endif +# ifndef OPENSSL_NO_DH +IMPLEMENT_LEGACY_ERR_LOAD(DH) +# endif +# ifndef OPENSSL_NO_DSA +IMPLEMENT_LEGACY_ERR_LOAD(DSA) +# endif +# ifndef OPENSSL_NO_EC +IMPLEMENT_LEGACY_ERR_LOAD(EC) +# endif +# ifndef OPENSSL_NO_ENGINE +IMPLEMENT_LEGACY_ERR_LOAD(ENGINE) +# endif +IMPLEMENT_LEGACY_ERR_LOAD(ERR) +IMPLEMENT_LEGACY_ERR_LOAD(EVP) +IMPLEMENT_LEGACY_ERR_LOAD(OBJ) +# ifndef OPENSSL_NO_OCSP +IMPLEMENT_LEGACY_ERR_LOAD(OCSP) +# endif +IMPLEMENT_LEGACY_ERR_LOAD(PEM) +IMPLEMENT_LEGACY_ERR_LOAD(PKCS12) +IMPLEMENT_LEGACY_ERR_LOAD(PKCS7) +IMPLEMENT_LEGACY_ERR_LOAD(RAND) +IMPLEMENT_LEGACY_ERR_LOAD(RSA) +IMPLEMENT_LEGACY_ERR_LOAD(OSSL_STORE) +# ifndef OPENSSL_NO_TS +IMPLEMENT_LEGACY_ERR_LOAD(TS) +# endif +IMPLEMENT_LEGACY_ERR_LOAD(UI) +IMPLEMENT_LEGACY_ERR_LOAD(X509) +IMPLEMENT_LEGACY_ERR_LOAD(X509V3) +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ diff --git a/crypto/openssl/crypto/err/err_blocks.c b/crypto/openssl/crypto/err/err_blocks.c new file mode 100644 index 000000000000..a658df05766d --- /dev/null +++ b/crypto/openssl/crypto/err/err_blocks.c @@ -0,0 +1,117 @@ +/* + * Copyright 2019-2021 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 + */ + +#define OSSL_FORCE_ERR_STATE + +#include +#include +#include "err_local.h" + +void ERR_new(void) +{ + ERR_STATE *es; + + es = ossl_err_get_state_int(); + if (es == NULL) + return; + + /* Allocate a slot */ + err_get_slot(es); + err_clear(es, es->top, 0); +} + +void ERR_set_debug(const char *file, int line, const char *func) +{ + ERR_STATE *es; + + es = ossl_err_get_state_int(); + if (es == NULL) + return; + + err_set_debug(es, es->top, file, line, func); +} + +void ERR_set_error(int lib, int reason, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + ERR_vset_error(lib, reason, fmt, args); + va_end(args); +} + +void ERR_vset_error(int lib, int reason, const char *fmt, va_list args) +{ + ERR_STATE *es; + char *buf = NULL; + size_t buf_size = 0; + unsigned long flags = 0; + size_t i; + + es = ossl_err_get_state_int(); + if (es == NULL) + return; + i = es->top; + + if (fmt != NULL) { + int printed_len = 0; + char *rbuf = NULL; + + buf = es->err_data[i]; + buf_size = es->err_data_size[i]; + + /* + * To protect the string we just grabbed from tampering by other + * functions we may call, or to protect them from freeing a pointer + * that may no longer be valid at that point, we clear away the + * data pointer and the flags. We will set them again at the end + * of this function. + */ + es->err_data[i] = NULL; + es->err_data_flags[i] = 0; + + /* + * Try to maximize the space available. If that fails, we use what + * we have. + */ + if (buf_size < ERR_MAX_DATA_SIZE + && (rbuf = OPENSSL_realloc(buf, ERR_MAX_DATA_SIZE)) != NULL) { + buf = rbuf; + buf_size = ERR_MAX_DATA_SIZE; + } + + if (buf != NULL) { + printed_len = BIO_vsnprintf(buf, buf_size, fmt, args); + } + if (printed_len < 0) + printed_len = 0; + if (buf != NULL) + buf[printed_len] = '\0'; + + /* + * Try to reduce the size, but only if we maximized above. If that + * fails, we keep what we have. + * (According to documentation, realloc leaves the old buffer untouched + * if it fails) + */ + if ((rbuf = OPENSSL_realloc(buf, printed_len + 1)) != NULL) { + buf = rbuf; + buf_size = printed_len + 1; + buf[printed_len] = '\0'; + } + + if (buf != NULL) + flags = ERR_TXT_MALLOCED | ERR_TXT_STRING; + } + + err_clear_data(es, es->top, 0); + err_set_error(es, es->top, lib, reason); + if (fmt != NULL) + err_set_data(es, es->top, buf, buf_size, flags); +} diff --git a/crypto/openssl/crypto/err/err_local.h b/crypto/openssl/crypto/err/err_local.h new file mode 100644 index 000000000000..d4e19dff241b --- /dev/null +++ b/crypto/openssl/crypto/err/err_local.h @@ -0,0 +1,94 @@ +/* + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +static ossl_inline void err_get_slot(ERR_STATE *es) +{ + es->top = (es->top + 1) % ERR_NUM_ERRORS; + if (es->top == es->bottom) + es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS; +} + +static ossl_inline void err_clear_data(ERR_STATE *es, size_t i, int deall) +{ + if (es->err_data_flags[i] & ERR_TXT_MALLOCED) { + if (deall) { + OPENSSL_free(es->err_data[i]); + es->err_data[i] = NULL; + es->err_data_size[i] = 0; + es->err_data_flags[i] = 0; + } else if (es->err_data[i] != NULL) { + es->err_data[i][0] = '\0'; + es->err_data_flags[i] = ERR_TXT_MALLOCED; + } + } else { + es->err_data[i] = NULL; + es->err_data_size[i] = 0; + es->err_data_flags[i] = 0; + } +} + +static ossl_inline void err_set_error(ERR_STATE *es, size_t i, + int lib, int reason) +{ + es->err_buffer[i] = + lib == ERR_LIB_SYS + ? (unsigned int)(ERR_SYSTEM_FLAG | reason) + : ERR_PACK(lib, 0, reason); +} + +static ossl_inline void err_set_debug(ERR_STATE *es, size_t i, + const char *file, int line, + const char *fn) +{ + /* + * We dup the file and fn strings because they may be provider owned. If the + * provider gets unloaded, they may not be valid anymore. + */ + OPENSSL_free(es->err_file[i]); + if (file == NULL || file[0] == '\0') + es->err_file[i] = NULL; + else + es->err_file[i] = OPENSSL_strdup(file); + es->err_line[i] = line; + OPENSSL_free(es->err_func[i]); + if (fn == NULL || fn[0] == '\0') + es->err_func[i] = NULL; + else + es->err_func[i] = OPENSSL_strdup(fn); +} + +static ossl_inline void err_set_data(ERR_STATE *es, size_t i, + void *data, size_t datasz, int flags) +{ + if ((es->err_data_flags[i] & ERR_TXT_MALLOCED) != 0) + OPENSSL_free(es->err_data[i]); + es->err_data[i] = data; + es->err_data_size[i] = datasz; + es->err_data_flags[i] = flags; +} + +static ossl_inline void err_clear(ERR_STATE *es, size_t i, int deall) +{ + err_clear_data(es, i, (deall)); + es->err_marks[i] = 0; + es->err_flags[i] = 0; + es->err_buffer[i] = 0; + es->err_line[i] = -1; + OPENSSL_free(es->err_file[i]); + es->err_file[i] = NULL; + OPENSSL_free(es->err_func[i]); + es->err_func[i] = NULL; +} + +ERR_STATE *ossl_err_get_state_int(void); +void ossl_err_string_int(unsigned long e, const char *func, + char *buf, size_t len); diff --git a/crypto/openssl/crypto/err/err_prn.c b/crypto/openssl/crypto/err/err_prn.c index c82e62947ed3..028811eedeee 100644 --- a/crypto/openssl/crypto/err/err_prn.c +++ b/crypto/openssl/crypto/err/err_prn.c @@ -1,47 +1,168 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +#define OSSL_FORCE_ERR_STATE + #include #include "internal/cryptlib.h" #include #include #include +#include "err_local.h" +#define ERR_PRINT_BUF_SIZE 4096 void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), void *u) { + CRYPTO_THREAD_ID tid = CRYPTO_THREAD_get_current_id(); unsigned long l; - char buf[256]; - char buf2[4096]; - const char *file, *data; + const char *file, *data, *func; int line, flags; - /* - * We don't know what kind of thing CRYPTO_THREAD_ID is. Here is our best - * attempt to convert it into something we can print. - */ - union { - CRYPTO_THREAD_ID tid; - unsigned long ltid; - } tid; - - tid.ltid = 0; - tid.tid = CRYPTO_THREAD_get_current_id(); - - while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) { - ERR_error_string_n(l, buf, sizeof(buf)); - BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", tid.ltid, buf, - file, line, (flags & ERR_TXT_STRING) ? data : ""); - if (cb(buf2, strlen(buf2), u) <= 0) + + while ((l = ERR_get_error_all(&file, &line, &func, &data, &flags)) != 0) { + char buf[ERR_PRINT_BUF_SIZE] = ""; + char *hex = NULL; + int offset; + + if ((flags & ERR_TXT_STRING) == 0) + data = ""; + + hex = ossl_buf2hexstr_sep((const unsigned char *)&tid, sizeof(tid), '\0'); + BIO_snprintf(buf, sizeof(buf), "%s:", hex == NULL ? "" : hex); + offset = strlen(buf); + ossl_err_string_int(l, func, buf + offset, sizeof(buf) - offset); + offset += strlen(buf + offset); + BIO_snprintf(buf + offset, sizeof(buf) - offset, ":%s:%d:%s\n", + file, line, data); + OPENSSL_free(hex); + if (cb(buf, strlen(buf), u) <= 0) break; /* abort outputting the error report */ } } +/* auxiliary function for incrementally reporting texts via the error queue */ +static void put_error(int lib, const char *func, int reason, + const char *file, int line) +{ + ERR_new(); + ERR_set_debug(file, line, func); + ERR_set_error(lib, reason, NULL /* no data here, so fmt is NULL */); +} + +#define TYPICAL_MAX_OUTPUT_BEFORE_DATA 100 +#define MAX_DATA_LEN (ERR_PRINT_BUF_SIZE - TYPICAL_MAX_OUTPUT_BEFORE_DATA) +void ERR_add_error_txt(const char *separator, const char *txt) +{ + const char *file = NULL; + int line; + const char *func = NULL; + const char *data = NULL; + int flags; + unsigned long err = ERR_peek_last_error(); + + if (separator == NULL) + separator = ""; + if (err == 0) + put_error(ERR_LIB_NONE, NULL, 0, "", 0); + + do { + size_t available_len, data_len; + const char *curr = txt, *next = txt; + const char *leading_separator = separator; + int trailing_separator = 0; + char *tmp; + + ERR_peek_last_error_all(&file, &line, &func, &data, &flags); + if ((flags & ERR_TXT_STRING) == 0) { + data = ""; + leading_separator = ""; + } + data_len = strlen(data); + + /* workaround for limit of ERR_print_errors_cb() */ + if (data_len >= MAX_DATA_LEN + || strlen(separator) >= (size_t)(MAX_DATA_LEN - data_len)) + available_len = 0; + else + available_len = MAX_DATA_LEN - data_len - strlen(separator) - 1; + /* MAX_DATA_LEN > available_len >= 0 */ + + if (*separator == '\0') { + const size_t len_next = strlen(next); + + if (len_next <= available_len) { + next += len_next; + curr = NULL; /* no need to split */ + } else { + next += available_len; + curr = next; /* will split at this point */ + } + } else { + while (*next != '\0' && (size_t)(next - txt) <= available_len) { + curr = next; + next = strstr(curr, separator); + if (next != NULL) { + next += strlen(separator); + trailing_separator = *next == '\0'; + } else { + next = curr + strlen(curr); + } + } + if ((size_t)(next - txt) <= available_len) + curr = NULL; /* the above loop implies *next == '\0' */ + } + if (curr != NULL) { + /* split error msg at curr since error data would get too long */ + if (curr != txt) { + tmp = OPENSSL_strndup(txt, curr - txt); + if (tmp == NULL) + return; + ERR_add_error_data(2, separator, tmp); + OPENSSL_free(tmp); + } + put_error(ERR_GET_LIB(err), func, err, file, line); + txt = curr; + } else { + if (trailing_separator) { + tmp = OPENSSL_strndup(txt, next - strlen(separator) - txt); + if (tmp == NULL) + return; + /* output txt without the trailing separator */ + ERR_add_error_data(2, leading_separator, tmp); + OPENSSL_free(tmp); + } else { + ERR_add_error_data(2, leading_separator, txt); + } + txt = next; /* finished */ + } + } while (*txt != '\0'); +} + +void ERR_add_error_mem_bio(const char *separator, BIO *bio) +{ + if (bio != NULL) { + char *str; + long len = BIO_get_mem_data(bio, &str); + + if (len > 0) { + if (str[len - 1] != '\0') { + if (BIO_write(bio, "", 1) <= 0) + return; + + len = BIO_get_mem_data(bio, &str); + } + if (len > 1) + ERR_add_error_txt(separator, str); + } + } +} + static int print_bio(const char *str, size_t len, void *bp) { return BIO_write((BIO *)bp, str, len); diff --git a/crypto/openssl/crypto/err/openssl.txt b/crypto/openssl/crypto/err/openssl.txt index 775a72006c26..49e42550db1a 100644 --- a/crypto/openssl/crypto/err/openssl.txt +++ b/crypto/openssl/crypto/err/openssl.txt @@ -1,1776 +1,10 @@ -# Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 -# Function codes -ASN1_F_A2D_ASN1_OBJECT:100:a2d_ASN1_OBJECT -ASN1_F_A2I_ASN1_INTEGER:102:a2i_ASN1_INTEGER -ASN1_F_A2I_ASN1_STRING:103:a2i_ASN1_STRING -ASN1_F_APPEND_EXP:176:append_exp -ASN1_F_ASN1_BIO_INIT:113:asn1_bio_init -ASN1_F_ASN1_BIT_STRING_SET_BIT:183:ASN1_BIT_STRING_set_bit -ASN1_F_ASN1_CB:177:asn1_cb -ASN1_F_ASN1_CHECK_TLEN:104:asn1_check_tlen -ASN1_F_ASN1_COLLECT:106:asn1_collect -ASN1_F_ASN1_D2I_EX_PRIMITIVE:108:asn1_d2i_ex_primitive -ASN1_F_ASN1_D2I_FP:109:ASN1_d2i_fp -ASN1_F_ASN1_D2I_READ_BIO:107:asn1_d2i_read_bio -ASN1_F_ASN1_DIGEST:184:ASN1_digest -ASN1_F_ASN1_DO_ADB:110:asn1_do_adb -ASN1_F_ASN1_DO_LOCK:233:asn1_do_lock -ASN1_F_ASN1_DUP:111:ASN1_dup -ASN1_F_ASN1_ENC_SAVE:115:asn1_enc_save -ASN1_F_ASN1_EX_C2I:204:asn1_ex_c2i -ASN1_F_ASN1_FIND_END:190:asn1_find_end -ASN1_F_ASN1_GENERALIZEDTIME_ADJ:216:ASN1_GENERALIZEDTIME_adj -ASN1_F_ASN1_GENERATE_V3:178:ASN1_generate_v3 -ASN1_F_ASN1_GET_INT64:224:asn1_get_int64 -ASN1_F_ASN1_GET_OBJECT:114:ASN1_get_object -ASN1_F_ASN1_GET_UINT64:225:asn1_get_uint64 -ASN1_F_ASN1_I2D_BIO:116:ASN1_i2d_bio -ASN1_F_ASN1_I2D_FP:117:ASN1_i2d_fp -ASN1_F_ASN1_ITEM_D2I_FP:206:ASN1_item_d2i_fp -ASN1_F_ASN1_ITEM_DUP:191:ASN1_item_dup -ASN1_F_ASN1_ITEM_EMBED_D2I:120:asn1_item_embed_d2i -ASN1_F_ASN1_ITEM_EMBED_NEW:121:asn1_item_embed_new -ASN1_F_ASN1_ITEM_EX_I2D:144:ASN1_item_ex_i2d -ASN1_F_ASN1_ITEM_FLAGS_I2D:118:asn1_item_flags_i2d -ASN1_F_ASN1_ITEM_I2D_BIO:192:ASN1_item_i2d_bio -ASN1_F_ASN1_ITEM_I2D_FP:193:ASN1_item_i2d_fp -ASN1_F_ASN1_ITEM_PACK:198:ASN1_item_pack -ASN1_F_ASN1_ITEM_SIGN:195:ASN1_item_sign -ASN1_F_ASN1_ITEM_SIGN_CTX:220:ASN1_item_sign_ctx -ASN1_F_ASN1_ITEM_UNPACK:199:ASN1_item_unpack -ASN1_F_ASN1_ITEM_VERIFY:197:ASN1_item_verify -ASN1_F_ASN1_MBSTRING_NCOPY:122:ASN1_mbstring_ncopy -ASN1_F_ASN1_OBJECT_NEW:123:ASN1_OBJECT_new -ASN1_F_ASN1_OUTPUT_DATA:214:asn1_output_data -ASN1_F_ASN1_PCTX_NEW:205:ASN1_PCTX_new -ASN1_F_ASN1_PRIMITIVE_NEW:119:asn1_primitive_new -ASN1_F_ASN1_SCTX_NEW:221:ASN1_SCTX_new -ASN1_F_ASN1_SIGN:128:ASN1_sign -ASN1_F_ASN1_STR2TYPE:179:asn1_str2type -ASN1_F_ASN1_STRING_GET_INT64:227:asn1_string_get_int64 -ASN1_F_ASN1_STRING_GET_UINT64:230:asn1_string_get_uint64 -ASN1_F_ASN1_STRING_SET:186:ASN1_STRING_set -ASN1_F_ASN1_STRING_TABLE_ADD:129:ASN1_STRING_TABLE_add -ASN1_F_ASN1_STRING_TO_BN:228:asn1_string_to_bn -ASN1_F_ASN1_STRING_TYPE_NEW:130:ASN1_STRING_type_new -ASN1_F_ASN1_TEMPLATE_EX_D2I:132:asn1_template_ex_d2i -ASN1_F_ASN1_TEMPLATE_NEW:133:asn1_template_new -ASN1_F_ASN1_TEMPLATE_NOEXP_D2I:131:asn1_template_noexp_d2i -ASN1_F_ASN1_TIME_ADJ:217:ASN1_TIME_adj -ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING:134:ASN1_TYPE_get_int_octetstring -ASN1_F_ASN1_TYPE_GET_OCTETSTRING:135:ASN1_TYPE_get_octetstring -ASN1_F_ASN1_UTCTIME_ADJ:218:ASN1_UTCTIME_adj -ASN1_F_ASN1_VERIFY:137:ASN1_verify -ASN1_F_B64_READ_ASN1:209:b64_read_asn1 -ASN1_F_B64_WRITE_ASN1:210:B64_write_ASN1 -ASN1_F_BIO_NEW_NDEF:208:BIO_new_NDEF -ASN1_F_BITSTR_CB:180:bitstr_cb -ASN1_F_BN_TO_ASN1_STRING:229:bn_to_asn1_string -ASN1_F_C2I_ASN1_BIT_STRING:189:c2i_ASN1_BIT_STRING -ASN1_F_C2I_ASN1_INTEGER:194:c2i_ASN1_INTEGER -ASN1_F_C2I_ASN1_OBJECT:196:c2i_ASN1_OBJECT -ASN1_F_C2I_IBUF:226:c2i_ibuf -ASN1_F_C2I_UINT64_INT:101:c2i_uint64_int -ASN1_F_COLLECT_DATA:140:collect_data -ASN1_F_D2I_ASN1_OBJECT:147:d2i_ASN1_OBJECT -ASN1_F_D2I_ASN1_UINTEGER:150:d2i_ASN1_UINTEGER -ASN1_F_D2I_AUTOPRIVATEKEY:207:d2i_AutoPrivateKey -ASN1_F_D2I_PRIVATEKEY:154:d2i_PrivateKey -ASN1_F_D2I_PUBLICKEY:155:d2i_PublicKey -ASN1_F_DO_BUF:142:do_buf -ASN1_F_DO_CREATE:124:do_create -ASN1_F_DO_DUMP:125:do_dump -ASN1_F_DO_TCREATE:222:do_tcreate -ASN1_F_I2A_ASN1_OBJECT:126:i2a_ASN1_OBJECT -ASN1_F_I2D_ASN1_BIO_STREAM:211:i2d_ASN1_bio_stream -ASN1_F_I2D_ASN1_OBJECT:143:i2d_ASN1_OBJECT -ASN1_F_I2D_DSA_PUBKEY:161:i2d_DSA_PUBKEY -ASN1_F_I2D_EC_PUBKEY:181:i2d_EC_PUBKEY -ASN1_F_I2D_PRIVATEKEY:163:i2d_PrivateKey -ASN1_F_I2D_PUBLICKEY:164:i2d_PublicKey -ASN1_F_I2D_RSA_PUBKEY:165:i2d_RSA_PUBKEY -ASN1_F_LONG_C2I:166:long_c2i -ASN1_F_NDEF_PREFIX:127:ndef_prefix -ASN1_F_NDEF_SUFFIX:136:ndef_suffix -ASN1_F_OID_MODULE_INIT:174:oid_module_init -ASN1_F_PARSE_TAGGING:182:parse_tagging -ASN1_F_PKCS5_PBE2_SET_IV:167:PKCS5_pbe2_set_iv -ASN1_F_PKCS5_PBE2_SET_SCRYPT:231:PKCS5_pbe2_set_scrypt -ASN1_F_PKCS5_PBE_SET:202:PKCS5_pbe_set -ASN1_F_PKCS5_PBE_SET0_ALGOR:215:PKCS5_pbe_set0_algor -ASN1_F_PKCS5_PBKDF2_SET:219:PKCS5_pbkdf2_set -ASN1_F_PKCS5_SCRYPT_SET:232:pkcs5_scrypt_set -ASN1_F_SMIME_READ_ASN1:212:SMIME_read_ASN1 -ASN1_F_SMIME_TEXT:213:SMIME_text -ASN1_F_STABLE_GET:138:stable_get -ASN1_F_STBL_MODULE_INIT:223:stbl_module_init -ASN1_F_UINT32_C2I:105:uint32_c2i -ASN1_F_UINT32_NEW:139:uint32_new -ASN1_F_UINT64_C2I:112:uint64_c2i -ASN1_F_UINT64_NEW:141:uint64_new -ASN1_F_X509_CRL_ADD0_REVOKED:169:X509_CRL_add0_revoked -ASN1_F_X509_INFO_NEW:170:X509_INFO_new -ASN1_F_X509_NAME_ENCODE:203:x509_name_encode -ASN1_F_X509_NAME_EX_D2I:158:x509_name_ex_d2i -ASN1_F_X509_NAME_EX_NEW:171:x509_name_ex_new -ASN1_F_X509_PKEY_NEW:173:X509_PKEY_new -ASYNC_F_ASYNC_CTX_NEW:100:async_ctx_new -ASYNC_F_ASYNC_INIT_THREAD:101:ASYNC_init_thread -ASYNC_F_ASYNC_JOB_NEW:102:async_job_new -ASYNC_F_ASYNC_PAUSE_JOB:103:ASYNC_pause_job -ASYNC_F_ASYNC_START_FUNC:104:async_start_func -ASYNC_F_ASYNC_START_JOB:105:ASYNC_start_job -ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD:106:ASYNC_WAIT_CTX_set_wait_fd -BIO_F_ACPT_STATE:100:acpt_state -BIO_F_ADDRINFO_WRAP:148:addrinfo_wrap -BIO_F_ADDR_STRINGS:134:addr_strings -BIO_F_BIO_ACCEPT:101:BIO_accept -BIO_F_BIO_ACCEPT_EX:137:BIO_accept_ex -BIO_F_BIO_ACCEPT_NEW:152:BIO_ACCEPT_new -BIO_F_BIO_ADDR_NEW:144:BIO_ADDR_new -BIO_F_BIO_BIND:147:BIO_bind -BIO_F_BIO_CALLBACK_CTRL:131:BIO_callback_ctrl -BIO_F_BIO_CONNECT:138:BIO_connect -BIO_F_BIO_CONNECT_NEW:153:BIO_CONNECT_new -BIO_F_BIO_CTRL:103:BIO_ctrl -BIO_F_BIO_GETS:104:BIO_gets -BIO_F_BIO_GET_HOST_IP:106:BIO_get_host_ip -BIO_F_BIO_GET_NEW_INDEX:102:BIO_get_new_index -BIO_F_BIO_GET_PORT:107:BIO_get_port -BIO_F_BIO_LISTEN:139:BIO_listen -BIO_F_BIO_LOOKUP:135:BIO_lookup -BIO_F_BIO_LOOKUP_EX:143:BIO_lookup_ex -BIO_F_BIO_MAKE_PAIR:121:bio_make_pair -BIO_F_BIO_METH_NEW:146:BIO_meth_new -BIO_F_BIO_NEW:108:BIO_new -BIO_F_BIO_NEW_DGRAM_SCTP:145:BIO_new_dgram_sctp -BIO_F_BIO_NEW_FILE:109:BIO_new_file -BIO_F_BIO_NEW_MEM_BUF:126:BIO_new_mem_buf -BIO_F_BIO_NREAD:123:BIO_nread -BIO_F_BIO_NREAD0:124:BIO_nread0 -BIO_F_BIO_NWRITE:125:BIO_nwrite -BIO_F_BIO_NWRITE0:122:BIO_nwrite0 -BIO_F_BIO_PARSE_HOSTSERV:136:BIO_parse_hostserv -BIO_F_BIO_PUTS:110:BIO_puts -BIO_F_BIO_READ:111:BIO_read -BIO_F_BIO_READ_EX:105:BIO_read_ex -BIO_F_BIO_READ_INTERN:120:bio_read_intern -BIO_F_BIO_SOCKET:140:BIO_socket -BIO_F_BIO_SOCKET_NBIO:142:BIO_socket_nbio -BIO_F_BIO_SOCK_INFO:141:BIO_sock_info -BIO_F_BIO_SOCK_INIT:112:BIO_sock_init -BIO_F_BIO_WRITE:113:BIO_write -BIO_F_BIO_WRITE_EX:119:BIO_write_ex -BIO_F_BIO_WRITE_INTERN:128:bio_write_intern -BIO_F_BUFFER_CTRL:114:buffer_ctrl -BIO_F_CONN_CTRL:127:conn_ctrl -BIO_F_CONN_STATE:115:conn_state -BIO_F_DGRAM_SCTP_NEW:149:dgram_sctp_new -BIO_F_DGRAM_SCTP_READ:132:dgram_sctp_read -BIO_F_DGRAM_SCTP_WRITE:133:dgram_sctp_write -BIO_F_DOAPR_OUTCH:150:doapr_outch -BIO_F_FILE_CTRL:116:file_ctrl -BIO_F_FILE_READ:130:file_read -BIO_F_LINEBUFFER_CTRL:129:linebuffer_ctrl -BIO_F_LINEBUFFER_NEW:151:linebuffer_new -BIO_F_MEM_WRITE:117:mem_write -BIO_F_NBIOF_NEW:154:nbiof_new -BIO_F_SLG_WRITE:155:slg_write -BIO_F_SSL_NEW:118:SSL_new -BN_F_BNRAND:127:bnrand -BN_F_BNRAND_RANGE:138:bnrand_range -BN_F_BN_BLINDING_CONVERT_EX:100:BN_BLINDING_convert_ex -BN_F_BN_BLINDING_CREATE_PARAM:128:BN_BLINDING_create_param -BN_F_BN_BLINDING_INVERT_EX:101:BN_BLINDING_invert_ex -BN_F_BN_BLINDING_NEW:102:BN_BLINDING_new -BN_F_BN_BLINDING_UPDATE:103:BN_BLINDING_update -BN_F_BN_BN2DEC:104:BN_bn2dec -BN_F_BN_BN2HEX:105:BN_bn2hex -BN_F_BN_COMPUTE_WNAF:142:bn_compute_wNAF -BN_F_BN_CTX_GET:116:BN_CTX_get -BN_F_BN_CTX_NEW:106:BN_CTX_new -BN_F_BN_CTX_START:129:BN_CTX_start -BN_F_BN_DIV:107:BN_div -BN_F_BN_DIV_RECP:130:BN_div_recp -BN_F_BN_EXP:123:BN_exp -BN_F_BN_EXPAND_INTERNAL:120:bn_expand_internal -BN_F_BN_GENCB_NEW:143:BN_GENCB_new -BN_F_BN_GENERATE_DSA_NONCE:140:BN_generate_dsa_nonce -BN_F_BN_GENERATE_PRIME_EX:141:BN_generate_prime_ex -BN_F_BN_GF2M_MOD:131:BN_GF2m_mod -BN_F_BN_GF2M_MOD_EXP:132:BN_GF2m_mod_exp -BN_F_BN_GF2M_MOD_MUL:133:BN_GF2m_mod_mul -BN_F_BN_GF2M_MOD_SOLVE_QUAD:134:BN_GF2m_mod_solve_quad -BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR:135:BN_GF2m_mod_solve_quad_arr -BN_F_BN_GF2M_MOD_SQR:136:BN_GF2m_mod_sqr -BN_F_BN_GF2M_MOD_SQRT:137:BN_GF2m_mod_sqrt -BN_F_BN_LSHIFT:145:BN_lshift -BN_F_BN_MOD_EXP2_MONT:118:BN_mod_exp2_mont -BN_F_BN_MOD_EXP_MONT:109:BN_mod_exp_mont -BN_F_BN_MOD_EXP_MONT_CONSTTIME:124:BN_mod_exp_mont_consttime -BN_F_BN_MOD_EXP_MONT_WORD:117:BN_mod_exp_mont_word -BN_F_BN_MOD_EXP_RECP:125:BN_mod_exp_recp -BN_F_BN_MOD_EXP_SIMPLE:126:BN_mod_exp_simple -BN_F_BN_MOD_INVERSE:110:BN_mod_inverse -BN_F_BN_MOD_INVERSE_NO_BRANCH:139:BN_mod_inverse_no_branch -BN_F_BN_MOD_LSHIFT_QUICK:119:BN_mod_lshift_quick -BN_F_BN_MOD_SQRT:121:BN_mod_sqrt -BN_F_BN_MONT_CTX_NEW:149:BN_MONT_CTX_new -BN_F_BN_MPI2BN:112:BN_mpi2bn -BN_F_BN_NEW:113:BN_new -BN_F_BN_POOL_GET:147:BN_POOL_get -BN_F_BN_RAND:114:BN_rand -BN_F_BN_RAND_RANGE:122:BN_rand_range -BN_F_BN_RECP_CTX_NEW:150:BN_RECP_CTX_new -BN_F_BN_RSHIFT:146:BN_rshift -BN_F_BN_SET_WORDS:144:bn_set_words -BN_F_BN_STACK_PUSH:148:BN_STACK_push -BN_F_BN_USUB:115:BN_usub -BN_F_OSSL_BN_RSA_DO_UNBLIND:151:ossl_bn_rsa_do_unblind -BUF_F_BUF_MEM_GROW:100:BUF_MEM_grow -BUF_F_BUF_MEM_GROW_CLEAN:105:BUF_MEM_grow_clean -BUF_F_BUF_MEM_NEW:101:BUF_MEM_new -CMS_F_CHECK_CONTENT:99:check_content -CMS_F_CMS_ADD0_CERT:164:CMS_add0_cert -CMS_F_CMS_ADD0_RECIPIENT_KEY:100:CMS_add0_recipient_key -CMS_F_CMS_ADD0_RECIPIENT_PASSWORD:165:CMS_add0_recipient_password -CMS_F_CMS_ADD1_RECEIPTREQUEST:158:CMS_add1_ReceiptRequest -CMS_F_CMS_ADD1_RECIPIENT_CERT:101:CMS_add1_recipient_cert -CMS_F_CMS_ADD1_SIGNER:102:CMS_add1_signer -CMS_F_CMS_ADD1_SIGNINGTIME:103:cms_add1_signingTime -CMS_F_CMS_COMPRESS:104:CMS_compress -CMS_F_CMS_COMPRESSEDDATA_CREATE:105:cms_CompressedData_create -CMS_F_CMS_COMPRESSEDDATA_INIT_BIO:106:cms_CompressedData_init_bio -CMS_F_CMS_COPY_CONTENT:107:cms_copy_content -CMS_F_CMS_COPY_MESSAGEDIGEST:108:cms_copy_messageDigest -CMS_F_CMS_DATA:109:CMS_data -CMS_F_CMS_DATAFINAL:110:CMS_dataFinal -CMS_F_CMS_DATAINIT:111:CMS_dataInit -CMS_F_CMS_DECRYPT:112:CMS_decrypt -CMS_F_CMS_DECRYPT_SET1_KEY:113:CMS_decrypt_set1_key -CMS_F_CMS_DECRYPT_SET1_PASSWORD:166:CMS_decrypt_set1_password -CMS_F_CMS_DECRYPT_SET1_PKEY:114:CMS_decrypt_set1_pkey -CMS_F_CMS_DIGESTALGORITHM_FIND_CTX:115:cms_DigestAlgorithm_find_ctx -CMS_F_CMS_DIGESTALGORITHM_INIT_BIO:116:cms_DigestAlgorithm_init_bio -CMS_F_CMS_DIGESTEDDATA_DO_FINAL:117:cms_DigestedData_do_final -CMS_F_CMS_DIGEST_VERIFY:118:CMS_digest_verify -CMS_F_CMS_ENCODE_RECEIPT:161:cms_encode_Receipt -CMS_F_CMS_ENCRYPT:119:CMS_encrypt -CMS_F_CMS_ENCRYPTEDCONTENT_INIT:179:cms_EncryptedContent_init -CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO:120:cms_EncryptedContent_init_bio -CMS_F_CMS_ENCRYPTEDDATA_DECRYPT:121:CMS_EncryptedData_decrypt -CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT:122:CMS_EncryptedData_encrypt -CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY:123:CMS_EncryptedData_set1_key -CMS_F_CMS_ENVELOPEDDATA_CREATE:124:CMS_EnvelopedData_create -CMS_F_CMS_ENVELOPEDDATA_INIT_BIO:125:cms_EnvelopedData_init_bio -CMS_F_CMS_ENVELOPED_DATA_INIT:126:cms_enveloped_data_init -CMS_F_CMS_ENV_ASN1_CTRL:171:cms_env_asn1_ctrl -CMS_F_CMS_FINAL:127:CMS_final -CMS_F_CMS_GET0_CERTIFICATE_CHOICES:128:cms_get0_certificate_choices -CMS_F_CMS_GET0_CONTENT:129:CMS_get0_content -CMS_F_CMS_GET0_ECONTENT_TYPE:130:cms_get0_econtent_type -CMS_F_CMS_GET0_ENVELOPED:131:cms_get0_enveloped -CMS_F_CMS_GET0_REVOCATION_CHOICES:132:cms_get0_revocation_choices -CMS_F_CMS_GET0_SIGNED:133:cms_get0_signed -CMS_F_CMS_MSGSIGDIGEST_ADD1:162:cms_msgSigDigest_add1 -CMS_F_CMS_RECEIPTREQUEST_CREATE0:159:CMS_ReceiptRequest_create0 -CMS_F_CMS_RECEIPT_VERIFY:160:cms_Receipt_verify -CMS_F_CMS_RECIPIENTINFO_DECRYPT:134:CMS_RecipientInfo_decrypt -CMS_F_CMS_RECIPIENTINFO_ENCRYPT:169:CMS_RecipientInfo_encrypt -CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT:178:cms_RecipientInfo_kari_encrypt -CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG:175:CMS_RecipientInfo_kari_get0_alg -CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID:173:\ - CMS_RecipientInfo_kari_get0_orig_id -CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS:172:CMS_RecipientInfo_kari_get0_reks -CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP:174:CMS_RecipientInfo_kari_orig_id_cmp -CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT:135:cms_RecipientInfo_kekri_decrypt -CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT:136:cms_RecipientInfo_kekri_encrypt -CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID:137:CMS_RecipientInfo_kekri_get0_id -CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP:138:CMS_RecipientInfo_kekri_id_cmp -CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP:139:CMS_RecipientInfo_ktri_cert_cmp -CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT:140:cms_RecipientInfo_ktri_decrypt -CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT:141:cms_RecipientInfo_ktri_encrypt -CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS:142:CMS_RecipientInfo_ktri_get0_algs -CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID:143:\ - CMS_RecipientInfo_ktri_get0_signer_id -CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT:167:cms_RecipientInfo_pwri_crypt -CMS_F_CMS_RECIPIENTINFO_SET0_KEY:144:CMS_RecipientInfo_set0_key -CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD:168:CMS_RecipientInfo_set0_password -CMS_F_CMS_RECIPIENTINFO_SET0_PKEY:145:CMS_RecipientInfo_set0_pkey -CMS_F_CMS_SD_ASN1_CTRL:170:cms_sd_asn1_ctrl -CMS_F_CMS_SET1_IAS:176:cms_set1_ias -CMS_F_CMS_SET1_KEYID:177:cms_set1_keyid -CMS_F_CMS_SET1_SIGNERIDENTIFIER:146:cms_set1_SignerIdentifier -CMS_F_CMS_SET_DETACHED:147:CMS_set_detached -CMS_F_CMS_SIGN:148:CMS_sign -CMS_F_CMS_SIGNED_DATA_INIT:149:cms_signed_data_init -CMS_F_CMS_SIGNERINFO_CONTENT_SIGN:150:cms_SignerInfo_content_sign -CMS_F_CMS_SIGNERINFO_SIGN:151:CMS_SignerInfo_sign -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 -CMS_F_KEK_UNWRAP_KEY:180:kek_unwrap_key -COMP_F_BIO_ZLIB_FLUSH:99:bio_zlib_flush -COMP_F_BIO_ZLIB_NEW:100:bio_zlib_new -COMP_F_BIO_ZLIB_READ:101:bio_zlib_read -COMP_F_BIO_ZLIB_WRITE:102:bio_zlib_write -COMP_F_COMP_CTX_NEW:103:COMP_CTX_new -CONF_F_CONF_DUMP_FP:104:CONF_dump_fp -CONF_F_CONF_LOAD:100:CONF_load -CONF_F_CONF_LOAD_FP:103:CONF_load_fp -CONF_F_CONF_PARSE_LIST:119:CONF_parse_list -CONF_F_DEF_LOAD:120:def_load -CONF_F_DEF_LOAD_BIO:121:def_load_bio -CONF_F_GET_NEXT_FILE:107:get_next_file -CONF_F_MODULE_ADD:122:module_add -CONF_F_MODULE_INIT:115:module_init -CONF_F_MODULE_LOAD_DSO:117:module_load_dso -CONF_F_MODULE_RUN:118:module_run -CONF_F_NCONF_DUMP_BIO:105:NCONF_dump_bio -CONF_F_NCONF_DUMP_FP:106:NCONF_dump_fp -CONF_F_NCONF_GET_NUMBER_E:112:NCONF_get_number_e -CONF_F_NCONF_GET_SECTION:108:NCONF_get_section -CONF_F_NCONF_GET_STRING:109:NCONF_get_string -CONF_F_NCONF_LOAD:113:NCONF_load -CONF_F_NCONF_LOAD_BIO:110:NCONF_load_bio -CONF_F_NCONF_LOAD_FP:114:NCONF_load_fp -CONF_F_NCONF_NEW:111:NCONF_new -CONF_F_PROCESS_INCLUDE:116:process_include -CONF_F_SSL_MODULE_INIT:123:ssl_module_init -CONF_F_STR_COPY:101:str_copy -CRYPTO_F_CMAC_CTX_NEW:120:CMAC_CTX_new -CRYPTO_F_CRYPTO_DUP_EX_DATA:110:CRYPTO_dup_ex_data -CRYPTO_F_CRYPTO_FREE_EX_DATA:111:CRYPTO_free_ex_data -CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX:100:CRYPTO_get_ex_new_index -CRYPTO_F_CRYPTO_MEMDUP:115:CRYPTO_memdup -CRYPTO_F_CRYPTO_NEW_EX_DATA:112:CRYPTO_new_ex_data -CRYPTO_F_CRYPTO_OCB128_COPY_CTX:121:CRYPTO_ocb128_copy_ctx -CRYPTO_F_CRYPTO_OCB128_INIT:122:CRYPTO_ocb128_init -CRYPTO_F_CRYPTO_SET_EX_DATA:102:CRYPTO_set_ex_data -CRYPTO_F_FIPS_MODE_SET:109:FIPS_mode_set -CRYPTO_F_GET_AND_LOCK:113:get_and_lock -CRYPTO_F_OPENSSL_ATEXIT:114:OPENSSL_atexit -CRYPTO_F_OPENSSL_BUF2HEXSTR:117:OPENSSL_buf2hexstr -CRYPTO_F_OPENSSL_FOPEN:119:openssl_fopen -CRYPTO_F_OPENSSL_HEXSTR2BUF:118:OPENSSL_hexstr2buf -CRYPTO_F_OPENSSL_INIT_CRYPTO:116:OPENSSL_init_crypto -CRYPTO_F_OPENSSL_LH_NEW:126:OPENSSL_LH_new -CRYPTO_F_OPENSSL_SK_DEEP_COPY:127:OPENSSL_sk_deep_copy -CRYPTO_F_OPENSSL_SK_DUP:128:OPENSSL_sk_dup -CRYPTO_F_PKEY_HMAC_INIT:123:pkey_hmac_init -CRYPTO_F_PKEY_POLY1305_INIT:124:pkey_poly1305_init -CRYPTO_F_PKEY_SIPHASH_INIT:125:pkey_siphash_init -CRYPTO_F_SK_RESERVE:129:sk_reserve -CT_F_CTLOG_NEW:117:CTLOG_new -CT_F_CTLOG_NEW_FROM_BASE64:118:CTLOG_new_from_base64 -CT_F_CTLOG_NEW_FROM_CONF:119:ctlog_new_from_conf -CT_F_CTLOG_STORE_LOAD_CTX_NEW:122:ctlog_store_load_ctx_new -CT_F_CTLOG_STORE_LOAD_FILE:123:CTLOG_STORE_load_file -CT_F_CTLOG_STORE_LOAD_LOG:130:ctlog_store_load_log -CT_F_CTLOG_STORE_NEW:131:CTLOG_STORE_new -CT_F_CT_BASE64_DECODE:124:ct_base64_decode -CT_F_CT_POLICY_EVAL_CTX_NEW:133:CT_POLICY_EVAL_CTX_new -CT_F_CT_V1_LOG_ID_FROM_PKEY:125:ct_v1_log_id_from_pkey -CT_F_I2O_SCT:107:i2o_SCT -CT_F_I2O_SCT_LIST:108:i2o_SCT_LIST -CT_F_I2O_SCT_SIGNATURE:109:i2o_SCT_signature -CT_F_O2I_SCT:110:o2i_SCT -CT_F_O2I_SCT_LIST:111:o2i_SCT_LIST -CT_F_O2I_SCT_SIGNATURE:112:o2i_SCT_signature -CT_F_SCT_CTX_NEW:126:SCT_CTX_new -CT_F_SCT_CTX_VERIFY:128:SCT_CTX_verify -CT_F_SCT_NEW:100:SCT_new -CT_F_SCT_NEW_FROM_BASE64:127:SCT_new_from_base64 -CT_F_SCT_SET0_LOG_ID:101:SCT_set0_log_id -CT_F_SCT_SET1_EXTENSIONS:114:SCT_set1_extensions -CT_F_SCT_SET1_LOG_ID:115:SCT_set1_log_id -CT_F_SCT_SET1_SIGNATURE:116:SCT_set1_signature -CT_F_SCT_SET_LOG_ENTRY_TYPE:102:SCT_set_log_entry_type -CT_F_SCT_SET_SIGNATURE_NID:103:SCT_set_signature_nid -CT_F_SCT_SET_VERSION:104:SCT_set_version -DH_F_COMPUTE_KEY:102:compute_key -DH_F_DHPARAMS_PRINT_FP:101:DHparams_print_fp -DH_F_DH_BUILTIN_GENPARAMS:106:dh_builtin_genparams -DH_F_DH_CHECK_EX:121:DH_check_ex -DH_F_DH_CHECK_PARAMS_EX:122:DH_check_params_ex -DH_F_DH_CHECK_PUB_KEY_EX:123:DH_check_pub_key_ex -DH_F_DH_CMS_DECRYPT:114:dh_cms_decrypt -DH_F_DH_CMS_SET_PEERKEY:115:dh_cms_set_peerkey -DH_F_DH_CMS_SET_SHARED_INFO:116:dh_cms_set_shared_info -DH_F_DH_METH_DUP:117:DH_meth_dup -DH_F_DH_METH_NEW:118:DH_meth_new -DH_F_DH_METH_SET1_NAME:119:DH_meth_set1_name -DH_F_DH_NEW_BY_NID:104:DH_new_by_nid -DH_F_DH_NEW_METHOD:105:DH_new_method -DH_F_DH_PARAM_DECODE:107:dh_param_decode -DH_F_DH_PKEY_PUBLIC_CHECK:124:dh_pkey_public_check -DH_F_DH_PRIV_DECODE:110:dh_priv_decode -DH_F_DH_PRIV_ENCODE:111:dh_priv_encode -DH_F_DH_PUB_DECODE:108:dh_pub_decode -DH_F_DH_PUB_ENCODE:109:dh_pub_encode -DH_F_DO_DH_PRINT:100:do_dh_print -DH_F_GENERATE_KEY:103:generate_key -DH_F_PKEY_DH_CTRL_STR:120:pkey_dh_ctrl_str -DH_F_PKEY_DH_DERIVE:112:pkey_dh_derive -DH_F_PKEY_DH_INIT:125:pkey_dh_init -DH_F_PKEY_DH_KEYGEN:113:pkey_dh_keygen -DSA_F_DSAPARAMS_PRINT:100:DSAparams_print -DSA_F_DSAPARAMS_PRINT_FP:101:DSAparams_print_fp -DSA_F_DSA_BUILTIN_PARAMGEN:125:dsa_builtin_paramgen -DSA_F_DSA_BUILTIN_PARAMGEN2:126:dsa_builtin_paramgen2 -DSA_F_DSA_DO_SIGN:112:DSA_do_sign -DSA_F_DSA_DO_VERIFY:113:DSA_do_verify -DSA_F_DSA_METH_DUP:127:DSA_meth_dup -DSA_F_DSA_METH_NEW:128:DSA_meth_new -DSA_F_DSA_METH_SET1_NAME:129:DSA_meth_set1_name -DSA_F_DSA_NEW_METHOD:103:DSA_new_method -DSA_F_DSA_PARAM_DECODE:119:dsa_param_decode -DSA_F_DSA_PRINT_FP:105:DSA_print_fp -DSA_F_DSA_PRIV_DECODE:115:dsa_priv_decode -DSA_F_DSA_PRIV_ENCODE:116:dsa_priv_encode -DSA_F_DSA_PUB_DECODE:117:dsa_pub_decode -DSA_F_DSA_PUB_ENCODE:118:dsa_pub_encode -DSA_F_DSA_SIGN:106:DSA_sign -DSA_F_DSA_SIGN_SETUP:107:DSA_sign_setup -DSA_F_DSA_SIG_NEW:102:DSA_SIG_new -DSA_F_OLD_DSA_PRIV_DECODE:122:old_dsa_priv_decode -DSA_F_PKEY_DSA_CTRL:120:pkey_dsa_ctrl -DSA_F_PKEY_DSA_CTRL_STR:104:pkey_dsa_ctrl_str -DSA_F_PKEY_DSA_KEYGEN:121:pkey_dsa_keygen -DSO_F_DLFCN_BIND_FUNC:100:dlfcn_bind_func -DSO_F_DLFCN_LOAD:102:dlfcn_load -DSO_F_DLFCN_MERGER:130:dlfcn_merger -DSO_F_DLFCN_NAME_CONVERTER:123:dlfcn_name_converter -DSO_F_DLFCN_UNLOAD:103:dlfcn_unload -DSO_F_DL_BIND_FUNC:104:dl_bind_func -DSO_F_DL_LOAD:106:dl_load -DSO_F_DL_MERGER:131:dl_merger -DSO_F_DL_NAME_CONVERTER:124:dl_name_converter -DSO_F_DL_UNLOAD:107:dl_unload -DSO_F_DSO_BIND_FUNC:108:DSO_bind_func -DSO_F_DSO_CONVERT_FILENAME:126:DSO_convert_filename -DSO_F_DSO_CTRL:110:DSO_ctrl -DSO_F_DSO_FREE:111:DSO_free -DSO_F_DSO_GET_FILENAME:127:DSO_get_filename -DSO_F_DSO_GLOBAL_LOOKUP:139:DSO_global_lookup -DSO_F_DSO_LOAD:112:DSO_load -DSO_F_DSO_MERGE:132:DSO_merge -DSO_F_DSO_NEW_METHOD:113:DSO_new_method -DSO_F_DSO_PATHBYADDR:105:DSO_pathbyaddr -DSO_F_DSO_SET_FILENAME:129:DSO_set_filename -DSO_F_DSO_UP_REF:114:DSO_up_ref -DSO_F_VMS_BIND_SYM:115:vms_bind_sym -DSO_F_VMS_LOAD:116:vms_load -DSO_F_VMS_MERGER:133:vms_merger -DSO_F_VMS_UNLOAD:117:vms_unload -DSO_F_WIN32_BIND_FUNC:101:win32_bind_func -DSO_F_WIN32_GLOBALLOOKUP:142:win32_globallookup -DSO_F_WIN32_JOINER:135:win32_joiner -DSO_F_WIN32_LOAD:120:win32_load -DSO_F_WIN32_MERGER:134:win32_merger -DSO_F_WIN32_NAME_CONVERTER:125:win32_name_converter -DSO_F_WIN32_PATHBYADDR:109:* -DSO_F_WIN32_SPLITTER:136:win32_splitter -DSO_F_WIN32_UNLOAD:121:win32_unload -EC_F_BN_TO_FELEM:224:BN_to_felem -EC_F_D2I_ECPARAMETERS:144:d2i_ECParameters -EC_F_D2I_ECPKPARAMETERS:145:d2i_ECPKParameters -EC_F_D2I_ECPRIVATEKEY:146:d2i_ECPrivateKey -EC_F_DO_EC_KEY_PRINT:221:do_EC_KEY_print -EC_F_ECDH_CMS_DECRYPT:238:ecdh_cms_decrypt -EC_F_ECDH_CMS_SET_SHARED_INFO:239:ecdh_cms_set_shared_info -EC_F_ECDH_COMPUTE_KEY:246:ECDH_compute_key -EC_F_ECDH_SIMPLE_COMPUTE_KEY:257:ecdh_simple_compute_key -EC_F_ECDSA_DO_SIGN_EX:251:ECDSA_do_sign_ex -EC_F_ECDSA_DO_VERIFY:252:ECDSA_do_verify -EC_F_ECDSA_SIGN_EX:254:ECDSA_sign_ex -EC_F_ECDSA_SIGN_SETUP:248:ECDSA_sign_setup -EC_F_ECDSA_SIG_NEW:265:ECDSA_SIG_new -EC_F_ECDSA_VERIFY:253:ECDSA_verify -EC_F_ECD_ITEM_VERIFY:270:ecd_item_verify -EC_F_ECKEY_PARAM2TYPE:223:eckey_param2type -EC_F_ECKEY_PARAM_DECODE:212:eckey_param_decode -EC_F_ECKEY_PRIV_DECODE:213:eckey_priv_decode -EC_F_ECKEY_PRIV_ENCODE:214:eckey_priv_encode -EC_F_ECKEY_PUB_DECODE:215:eckey_pub_decode -EC_F_ECKEY_PUB_ENCODE:216:eckey_pub_encode -EC_F_ECKEY_TYPE2PARAM:220:eckey_type2param -EC_F_ECPARAMETERS_PRINT:147:ECParameters_print -EC_F_ECPARAMETERS_PRINT_FP:148:ECParameters_print_fp -EC_F_ECPKPARAMETERS_PRINT:149:ECPKParameters_print -EC_F_ECPKPARAMETERS_PRINT_FP:150:ECPKParameters_print_fp -EC_F_ECP_NISTZ256_GET_AFFINE:240:ecp_nistz256_get_affine -EC_F_ECP_NISTZ256_INV_MOD_ORD:275:ecp_nistz256_inv_mod_ord -EC_F_ECP_NISTZ256_MULT_PRECOMPUTE:243:ecp_nistz256_mult_precompute -EC_F_ECP_NISTZ256_POINTS_MUL:241:ecp_nistz256_points_mul -EC_F_ECP_NISTZ256_PRE_COMP_NEW:244:ecp_nistz256_pre_comp_new -EC_F_ECP_NISTZ256_WINDOWED_MUL:242:ecp_nistz256_windowed_mul -EC_F_ECX_KEY_OP:266:ecx_key_op -EC_F_ECX_PRIV_ENCODE:267:ecx_priv_encode -EC_F_ECX_PUB_ENCODE:268:ecx_pub_encode -EC_F_EC_ASN1_GROUP2CURVE:153:ec_asn1_group2curve -EC_F_EC_ASN1_GROUP2FIELDID:154:ec_asn1_group2fieldid -EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY:208:ec_GF2m_montgomery_point_multiply -EC_F_EC_GF2M_SIMPLE_FIELD_INV:296:ec_GF2m_simple_field_inv -EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT:159:\ - ec_GF2m_simple_group_check_discriminant -EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE:195:ec_GF2m_simple_group_set_curve -EC_F_EC_GF2M_SIMPLE_LADDER_POST:285:ec_GF2m_simple_ladder_post -EC_F_EC_GF2M_SIMPLE_LADDER_PRE:288:ec_GF2m_simple_ladder_pre -EC_F_EC_GF2M_SIMPLE_OCT2POINT:160:ec_GF2m_simple_oct2point -EC_F_EC_GF2M_SIMPLE_POINT2OCT:161:ec_GF2m_simple_point2oct -EC_F_EC_GF2M_SIMPLE_POINTS_MUL:289:ec_GF2m_simple_points_mul -EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES:162:\ - ec_GF2m_simple_point_get_affine_coordinates -EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES:163:\ - ec_GF2m_simple_point_set_affine_coordinates -EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES:164:\ - ec_GF2m_simple_set_compressed_coordinates -EC_F_EC_GFP_MONT_FIELD_DECODE:133:ec_GFp_mont_field_decode -EC_F_EC_GFP_MONT_FIELD_ENCODE:134:ec_GFp_mont_field_encode -EC_F_EC_GFP_MONT_FIELD_INV:297:ec_GFp_mont_field_inv -EC_F_EC_GFP_MONT_FIELD_MUL:131:ec_GFp_mont_field_mul -EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE:209:ec_GFp_mont_field_set_to_one -EC_F_EC_GFP_MONT_FIELD_SQR:132:ec_GFp_mont_field_sqr -EC_F_EC_GFP_MONT_GROUP_SET_CURVE:189:ec_GFp_mont_group_set_curve -EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE:225:ec_GFp_nistp224_group_set_curve -EC_F_EC_GFP_NISTP224_POINTS_MUL:228:ec_GFp_nistp224_points_mul -EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES:226:\ - ec_GFp_nistp224_point_get_affine_coordinates -EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE:230:ec_GFp_nistp256_group_set_curve -EC_F_EC_GFP_NISTP256_POINTS_MUL:231:ec_GFp_nistp256_points_mul -EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES:232:\ - ec_GFp_nistp256_point_get_affine_coordinates -EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE:233:ec_GFp_nistp521_group_set_curve -EC_F_EC_GFP_NISTP521_POINTS_MUL:234:ec_GFp_nistp521_points_mul -EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES:235:\ - ec_GFp_nistp521_point_get_affine_coordinates -EC_F_EC_GFP_NIST_FIELD_MUL:200:ec_GFp_nist_field_mul -EC_F_EC_GFP_NIST_FIELD_SQR:201:ec_GFp_nist_field_sqr -EC_F_EC_GFP_NIST_GROUP_SET_CURVE:202:ec_GFp_nist_group_set_curve -EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES:287:ec_GFp_simple_blind_coordinates -EC_F_EC_GFP_SIMPLE_FIELD_INV:298:ec_GFp_simple_field_inv -EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT:165:\ - ec_GFp_simple_group_check_discriminant -EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE:166:ec_GFp_simple_group_set_curve -EC_F_EC_GFP_SIMPLE_MAKE_AFFINE:102:ec_GFp_simple_make_affine -EC_F_EC_GFP_SIMPLE_OCT2POINT:103:ec_GFp_simple_oct2point -EC_F_EC_GFP_SIMPLE_POINT2OCT:104:ec_GFp_simple_point2oct -EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE:137:ec_GFp_simple_points_make_affine -EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES:167:\ - ec_GFp_simple_point_get_affine_coordinates -EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES:168:\ - ec_GFp_simple_point_set_affine_coordinates -EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES:169:\ - ec_GFp_simple_set_compressed_coordinates -EC_F_EC_GROUP_CHECK:170:EC_GROUP_check -EC_F_EC_GROUP_CHECK_DISCRIMINANT:171:EC_GROUP_check_discriminant -EC_F_EC_GROUP_COPY:106:EC_GROUP_copy -EC_F_EC_GROUP_GET_CURVE:291:EC_GROUP_get_curve -EC_F_EC_GROUP_GET_CURVE_GF2M:172:EC_GROUP_get_curve_GF2m -EC_F_EC_GROUP_GET_CURVE_GFP:130:EC_GROUP_get_curve_GFp -EC_F_EC_GROUP_GET_DEGREE:173:EC_GROUP_get_degree -EC_F_EC_GROUP_GET_ECPARAMETERS:261:EC_GROUP_get_ecparameters -EC_F_EC_GROUP_GET_ECPKPARAMETERS:262:EC_GROUP_get_ecpkparameters -EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS:193:EC_GROUP_get_pentanomial_basis -EC_F_EC_GROUP_GET_TRINOMIAL_BASIS:194:EC_GROUP_get_trinomial_basis -EC_F_EC_GROUP_NEW:108:EC_GROUP_new -EC_F_EC_GROUP_NEW_BY_CURVE_NAME:174:EC_GROUP_new_by_curve_name -EC_F_EC_GROUP_NEW_FROM_DATA:175:ec_group_new_from_data -EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS:263:EC_GROUP_new_from_ecparameters -EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS:264:EC_GROUP_new_from_ecpkparameters -EC_F_EC_GROUP_SET_CURVE:292:EC_GROUP_set_curve -EC_F_EC_GROUP_SET_CURVE_GF2M:176:EC_GROUP_set_curve_GF2m -EC_F_EC_GROUP_SET_CURVE_GFP:109:EC_GROUP_set_curve_GFp -EC_F_EC_GROUP_SET_GENERATOR:111:EC_GROUP_set_generator -EC_F_EC_GROUP_SET_SEED:286:EC_GROUP_set_seed -EC_F_EC_KEY_CHECK_KEY:177:EC_KEY_check_key -EC_F_EC_KEY_COPY:178:EC_KEY_copy -EC_F_EC_KEY_GENERATE_KEY:179:EC_KEY_generate_key -EC_F_EC_KEY_NEW:182:EC_KEY_new -EC_F_EC_KEY_NEW_METHOD:245:EC_KEY_new_method -EC_F_EC_KEY_OCT2PRIV:255:EC_KEY_oct2priv -EC_F_EC_KEY_PRINT:180:EC_KEY_print -EC_F_EC_KEY_PRINT_FP:181:EC_KEY_print_fp -EC_F_EC_KEY_PRIV2BUF:279:EC_KEY_priv2buf -EC_F_EC_KEY_PRIV2OCT:256:EC_KEY_priv2oct -EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES:229:\ - EC_KEY_set_public_key_affine_coordinates -EC_F_EC_KEY_SIMPLE_CHECK_KEY:258:ec_key_simple_check_key -EC_F_EC_KEY_SIMPLE_OCT2PRIV:259:ec_key_simple_oct2priv -EC_F_EC_KEY_SIMPLE_PRIV2OCT:260:ec_key_simple_priv2oct -EC_F_EC_PKEY_CHECK:273:ec_pkey_check -EC_F_EC_PKEY_PARAM_CHECK:274:ec_pkey_param_check -EC_F_EC_POINTS_MAKE_AFFINE:136:EC_POINTs_make_affine -EC_F_EC_POINTS_MUL:290:EC_POINTs_mul -EC_F_EC_POINT_ADD:112:EC_POINT_add -EC_F_EC_POINT_BN2POINT:280:EC_POINT_bn2point -EC_F_EC_POINT_CMP:113:EC_POINT_cmp -EC_F_EC_POINT_COPY:114:EC_POINT_copy -EC_F_EC_POINT_DBL:115:EC_POINT_dbl -EC_F_EC_POINT_GET_AFFINE_COORDINATES:293:EC_POINT_get_affine_coordinates -EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M:183:\ - EC_POINT_get_affine_coordinates_GF2m -EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP:116:EC_POINT_get_affine_coordinates_GFp -EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP:117:\ - EC_POINT_get_Jprojective_coordinates_GFp -EC_F_EC_POINT_INVERT:210:EC_POINT_invert -EC_F_EC_POINT_IS_AT_INFINITY:118:EC_POINT_is_at_infinity -EC_F_EC_POINT_IS_ON_CURVE:119:EC_POINT_is_on_curve -EC_F_EC_POINT_MAKE_AFFINE:120:EC_POINT_make_affine -EC_F_EC_POINT_NEW:121:EC_POINT_new -EC_F_EC_POINT_OCT2POINT:122:EC_POINT_oct2point -EC_F_EC_POINT_POINT2BUF:281:EC_POINT_point2buf -EC_F_EC_POINT_POINT2OCT:123:EC_POINT_point2oct -EC_F_EC_POINT_SET_AFFINE_COORDINATES:294:EC_POINT_set_affine_coordinates -EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M:185:\ - EC_POINT_set_affine_coordinates_GF2m -EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP:124:EC_POINT_set_affine_coordinates_GFp -EC_F_EC_POINT_SET_COMPRESSED_COORDINATES:295:EC_POINT_set_compressed_coordinates -EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M:186:\ - EC_POINT_set_compressed_coordinates_GF2m -EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP:125:\ - EC_POINT_set_compressed_coordinates_GFp -EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP:126:\ - EC_POINT_set_Jprojective_coordinates_GFp -EC_F_EC_POINT_SET_TO_INFINITY:127:EC_POINT_set_to_infinity -EC_F_EC_PRE_COMP_NEW:196:ec_pre_comp_new -EC_F_EC_SCALAR_MUL_LADDER:284:ec_scalar_mul_ladder -EC_F_EC_WNAF_MUL:187:ec_wNAF_mul -EC_F_EC_WNAF_PRECOMPUTE_MULT:188:ec_wNAF_precompute_mult -EC_F_I2D_ECPARAMETERS:190:i2d_ECParameters -EC_F_I2D_ECPKPARAMETERS:191:i2d_ECPKParameters -EC_F_I2D_ECPRIVATEKEY:192:i2d_ECPrivateKey -EC_F_I2O_ECPUBLICKEY:151:i2o_ECPublicKey -EC_F_NISTP224_PRE_COMP_NEW:227:nistp224_pre_comp_new -EC_F_NISTP256_PRE_COMP_NEW:236:nistp256_pre_comp_new -EC_F_NISTP521_PRE_COMP_NEW:237:nistp521_pre_comp_new -EC_F_O2I_ECPUBLICKEY:152:o2i_ECPublicKey -EC_F_OLD_EC_PRIV_DECODE:222:old_ec_priv_decode -EC_F_OSSL_ECDH_COMPUTE_KEY:247:ossl_ecdh_compute_key -EC_F_OSSL_ECDSA_SIGN_SIG:249:ossl_ecdsa_sign_sig -EC_F_OSSL_ECDSA_VERIFY_SIG:250:ossl_ecdsa_verify_sig -EC_F_PKEY_ECD_CTRL:271:pkey_ecd_ctrl -EC_F_PKEY_ECD_DIGESTSIGN:272:pkey_ecd_digestsign -EC_F_PKEY_ECD_DIGESTSIGN25519:276:pkey_ecd_digestsign25519 -EC_F_PKEY_ECD_DIGESTSIGN448:277:pkey_ecd_digestsign448 -EC_F_PKEY_ECX_DERIVE:269:pkey_ecx_derive -EC_F_PKEY_EC_CTRL:197:pkey_ec_ctrl -EC_F_PKEY_EC_CTRL_STR:198:pkey_ec_ctrl_str -EC_F_PKEY_EC_DERIVE:217:pkey_ec_derive -EC_F_PKEY_EC_INIT:282:pkey_ec_init -EC_F_PKEY_EC_KDF_DERIVE:283:pkey_ec_kdf_derive -EC_F_PKEY_EC_KEYGEN:199:pkey_ec_keygen -EC_F_PKEY_EC_PARAMGEN:219:pkey_ec_paramgen -EC_F_PKEY_EC_SIGN:218:pkey_ec_sign -EC_F_VALIDATE_ECX_DERIVE:278:validate_ecx_derive -ENGINE_F_DIGEST_UPDATE:198:digest_update -ENGINE_F_DYNAMIC_CTRL:180:dynamic_ctrl -ENGINE_F_DYNAMIC_GET_DATA_CTX:181:dynamic_get_data_ctx -ENGINE_F_DYNAMIC_LOAD:182:dynamic_load -ENGINE_F_DYNAMIC_SET_DATA_CTX:183:dynamic_set_data_ctx -ENGINE_F_ENGINE_ADD:105:ENGINE_add -ENGINE_F_ENGINE_BY_ID:106:ENGINE_by_id -ENGINE_F_ENGINE_CMD_IS_EXECUTABLE:170:ENGINE_cmd_is_executable -ENGINE_F_ENGINE_CTRL:142:ENGINE_ctrl -ENGINE_F_ENGINE_CTRL_CMD:178:ENGINE_ctrl_cmd -ENGINE_F_ENGINE_CTRL_CMD_STRING:171:ENGINE_ctrl_cmd_string -ENGINE_F_ENGINE_FINISH:107:ENGINE_finish -ENGINE_F_ENGINE_GET_CIPHER:185:ENGINE_get_cipher -ENGINE_F_ENGINE_GET_DIGEST:186:ENGINE_get_digest -ENGINE_F_ENGINE_GET_FIRST:195:ENGINE_get_first -ENGINE_F_ENGINE_GET_LAST:196:ENGINE_get_last -ENGINE_F_ENGINE_GET_NEXT:115:ENGINE_get_next -ENGINE_F_ENGINE_GET_PKEY_ASN1_METH:193:ENGINE_get_pkey_asn1_meth -ENGINE_F_ENGINE_GET_PKEY_METH:192:ENGINE_get_pkey_meth -ENGINE_F_ENGINE_GET_PREV:116:ENGINE_get_prev -ENGINE_F_ENGINE_INIT:119:ENGINE_init -ENGINE_F_ENGINE_LIST_ADD:120:engine_list_add -ENGINE_F_ENGINE_LIST_REMOVE:121:engine_list_remove -ENGINE_F_ENGINE_LOAD_PRIVATE_KEY:150:ENGINE_load_private_key -ENGINE_F_ENGINE_LOAD_PUBLIC_KEY:151:ENGINE_load_public_key -ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT:194:ENGINE_load_ssl_client_cert -ENGINE_F_ENGINE_NEW:122:ENGINE_new -ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR:197:ENGINE_pkey_asn1_find_str -ENGINE_F_ENGINE_REMOVE:123:ENGINE_remove -ENGINE_F_ENGINE_SET_DEFAULT_STRING:189:ENGINE_set_default_string -ENGINE_F_ENGINE_SET_ID:129:ENGINE_set_id -ENGINE_F_ENGINE_SET_NAME:130:ENGINE_set_name -ENGINE_F_ENGINE_TABLE_REGISTER:184:engine_table_register -ENGINE_F_ENGINE_UNLOCKED_FINISH:191:engine_unlocked_finish -ENGINE_F_ENGINE_UP_REF:190:ENGINE_up_ref -ENGINE_F_INT_CLEANUP_ITEM:199:int_cleanup_item -ENGINE_F_INT_CTRL_HELPER:172:int_ctrl_helper -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 -EVP_F_ARIA_GCM_INIT_KEY:176:aria_gcm_init_key -EVP_F_ARIA_INIT_KEY:185:aria_init_key -EVP_F_B64_NEW:198:b64_new -EVP_F_CAMELLIA_INIT_KEY:159:camellia_init_key -EVP_F_CHACHA20_POLY1305_CTRL:182:chacha20_poly1305_ctrl -EVP_F_CMLL_T4_INIT_KEY:179:cmll_t4_init_key -EVP_F_DES_EDE3_WRAP_CIPHER:171:des_ede3_wrap_cipher -EVP_F_DO_SIGVER_INIT:161:do_sigver_init -EVP_F_ENC_NEW:199:enc_new -EVP_F_EVP_CIPHERINIT_EX:123:EVP_CipherInit_ex -EVP_F_EVP_CIPHER_ASN1_TO_PARAM:204:EVP_CIPHER_asn1_to_param -EVP_F_EVP_CIPHER_CTX_COPY:163:EVP_CIPHER_CTX_copy -EVP_F_EVP_CIPHER_CTX_CTRL:124:EVP_CIPHER_CTX_ctrl -EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH:122:EVP_CIPHER_CTX_set_key_length -EVP_F_EVP_CIPHER_PARAM_TO_ASN1:205:EVP_CIPHER_param_to_asn1 -EVP_F_EVP_DECRYPTFINAL_EX:101:EVP_DecryptFinal_ex -EVP_F_EVP_DECRYPTUPDATE:166:EVP_DecryptUpdate -EVP_F_EVP_DIGESTFINALXOF:174:EVP_DigestFinalXOF -EVP_F_EVP_DIGESTINIT_EX:128:EVP_DigestInit_ex -EVP_F_EVP_ENCRYPTDECRYPTUPDATE:219:evp_EncryptDecryptUpdate -EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex -EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate -EVP_F_EVP_MD_CTX_COPY_EX:110:EVP_MD_CTX_copy_ex -EVP_F_EVP_MD_SIZE:162:EVP_MD_size -EVP_F_EVP_OPENINIT:102:EVP_OpenInit -EVP_F_EVP_PBE_ALG_ADD:115:EVP_PBE_alg_add -EVP_F_EVP_PBE_ALG_ADD_TYPE:160:EVP_PBE_alg_add_type -EVP_F_EVP_PBE_CIPHERINIT:116:EVP_PBE_CipherInit -EVP_F_EVP_PBE_SCRYPT:181:EVP_PBE_scrypt -EVP_F_EVP_PKCS82PKEY:111:EVP_PKCS82PKEY -EVP_F_EVP_PKEY2PKCS8:113:EVP_PKEY2PKCS8 -EVP_F_EVP_PKEY_ASN1_ADD0:188:EVP_PKEY_asn1_add0 -EVP_F_EVP_PKEY_CHECK:186:EVP_PKEY_check -EVP_F_EVP_PKEY_COPY_PARAMETERS:103:EVP_PKEY_copy_parameters -EVP_F_EVP_PKEY_CTX_CTRL:137:EVP_PKEY_CTX_ctrl -EVP_F_EVP_PKEY_CTX_CTRL_STR:150:EVP_PKEY_CTX_ctrl_str -EVP_F_EVP_PKEY_CTX_DUP:156:EVP_PKEY_CTX_dup -EVP_F_EVP_PKEY_CTX_MD:168:EVP_PKEY_CTX_md -EVP_F_EVP_PKEY_DECRYPT:104:EVP_PKEY_decrypt -EVP_F_EVP_PKEY_DECRYPT_INIT:138:EVP_PKEY_decrypt_init -EVP_F_EVP_PKEY_DECRYPT_OLD:151:EVP_PKEY_decrypt_old -EVP_F_EVP_PKEY_DERIVE:153:EVP_PKEY_derive -EVP_F_EVP_PKEY_DERIVE_INIT:154:EVP_PKEY_derive_init -EVP_F_EVP_PKEY_DERIVE_SET_PEER:155:EVP_PKEY_derive_set_peer -EVP_F_EVP_PKEY_ENCRYPT:105:EVP_PKEY_encrypt -EVP_F_EVP_PKEY_ENCRYPT_INIT:139:EVP_PKEY_encrypt_init -EVP_F_EVP_PKEY_ENCRYPT_OLD:152:EVP_PKEY_encrypt_old -EVP_F_EVP_PKEY_GET0_DH:119:EVP_PKEY_get0_DH -EVP_F_EVP_PKEY_GET0_DSA:120:EVP_PKEY_get0_DSA -EVP_F_EVP_PKEY_GET0_EC_KEY:131:EVP_PKEY_get0_EC_KEY -EVP_F_EVP_PKEY_GET0_HMAC:183:EVP_PKEY_get0_hmac -EVP_F_EVP_PKEY_GET0_POLY1305:184:EVP_PKEY_get0_poly1305 -EVP_F_EVP_PKEY_GET0_RSA:121:EVP_PKEY_get0_RSA -EVP_F_EVP_PKEY_GET0_SIPHASH:172:EVP_PKEY_get0_siphash -EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY:202:EVP_PKEY_get_raw_private_key -EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY:203:EVP_PKEY_get_raw_public_key -EVP_F_EVP_PKEY_KEYGEN:146:EVP_PKEY_keygen -EVP_F_EVP_PKEY_KEYGEN_INIT:147:EVP_PKEY_keygen_init -EVP_F_EVP_PKEY_METH_ADD0:194:EVP_PKEY_meth_add0 -EVP_F_EVP_PKEY_METH_NEW:195:EVP_PKEY_meth_new -EVP_F_EVP_PKEY_NEW:106:EVP_PKEY_new -EVP_F_EVP_PKEY_NEW_CMAC_KEY:193:EVP_PKEY_new_CMAC_key -EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY:191:EVP_PKEY_new_raw_private_key -EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY:192:EVP_PKEY_new_raw_public_key -EVP_F_EVP_PKEY_PARAMGEN:148:EVP_PKEY_paramgen -EVP_F_EVP_PKEY_PARAMGEN_INIT:149:EVP_PKEY_paramgen_init -EVP_F_EVP_PKEY_PARAM_CHECK:189:EVP_PKEY_param_check -EVP_F_EVP_PKEY_PUBLIC_CHECK:190:EVP_PKEY_public_check -EVP_F_EVP_PKEY_SET1_ENGINE:187:EVP_PKEY_set1_engine -EVP_F_EVP_PKEY_SET_ALIAS_TYPE:206:EVP_PKEY_set_alias_type -EVP_F_EVP_PKEY_SIGN:140:EVP_PKEY_sign -EVP_F_EVP_PKEY_SIGN_INIT:141:EVP_PKEY_sign_init -EVP_F_EVP_PKEY_VERIFY:142:EVP_PKEY_verify -EVP_F_EVP_PKEY_VERIFY_INIT:143:EVP_PKEY_verify_init -EVP_F_EVP_PKEY_VERIFY_RECOVER:144:EVP_PKEY_verify_recover -EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT:145:EVP_PKEY_verify_recover_init -EVP_F_EVP_SIGNFINAL:107:EVP_SignFinal -EVP_F_EVP_VERIFYFINAL:108:EVP_VerifyFinal -EVP_F_INT_CTX_NEW:157:int_ctx_new -EVP_F_OK_NEW:200:ok_new -EVP_F_PKCS5_PBE_KEYIVGEN:117:PKCS5_PBE_keyivgen -EVP_F_PKCS5_V2_PBE_KEYIVGEN:118:PKCS5_v2_PBE_keyivgen -EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN:164:PKCS5_v2_PBKDF2_keyivgen -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 -KDF_F_PKEY_HKDF_DERIVE:102:pkey_hkdf_derive -KDF_F_PKEY_HKDF_INIT:108:pkey_hkdf_init -KDF_F_PKEY_SCRYPT_CTRL_STR:104:pkey_scrypt_ctrl_str -KDF_F_PKEY_SCRYPT_CTRL_UINT64:105:pkey_scrypt_ctrl_uint64 -KDF_F_PKEY_SCRYPT_DERIVE:109:pkey_scrypt_derive -KDF_F_PKEY_SCRYPT_INIT:106:pkey_scrypt_init -KDF_F_PKEY_SCRYPT_SET_MEMBUF:107:pkey_scrypt_set_membuf -KDF_F_PKEY_TLS1_PRF_CTRL_STR:100:pkey_tls1_prf_ctrl_str -KDF_F_PKEY_TLS1_PRF_DERIVE:101:pkey_tls1_prf_derive -KDF_F_PKEY_TLS1_PRF_INIT:110:pkey_tls1_prf_init -KDF_F_TLS1_PRF_ALG:111:tls1_prf_alg -OBJ_F_OBJ_ADD_OBJECT:105:OBJ_add_object -OBJ_F_OBJ_ADD_SIGID:107:OBJ_add_sigid -OBJ_F_OBJ_CREATE:100:OBJ_create -OBJ_F_OBJ_DUP:101:OBJ_dup -OBJ_F_OBJ_NAME_NEW_INDEX:106:OBJ_NAME_new_index -OBJ_F_OBJ_NID2LN:102:OBJ_nid2ln -OBJ_F_OBJ_NID2OBJ:103:OBJ_nid2obj -OBJ_F_OBJ_NID2SN:104:OBJ_nid2sn -OBJ_F_OBJ_TXT2OBJ:108:OBJ_txt2obj -OCSP_F_D2I_OCSP_NONCE:102:d2i_ocsp_nonce -OCSP_F_OCSP_BASIC_ADD1_STATUS:103:OCSP_basic_add1_status -OCSP_F_OCSP_BASIC_SIGN:104:OCSP_basic_sign -OCSP_F_OCSP_BASIC_SIGN_CTX:119:OCSP_basic_sign_ctx -OCSP_F_OCSP_BASIC_VERIFY:105:OCSP_basic_verify -OCSP_F_OCSP_CERT_ID_NEW:101:OCSP_cert_id_new -OCSP_F_OCSP_CHECK_DELEGATED:106:ocsp_check_delegated -OCSP_F_OCSP_CHECK_IDS:107:ocsp_check_ids -OCSP_F_OCSP_CHECK_ISSUER:108:ocsp_check_issuer -OCSP_F_OCSP_CHECK_VALIDITY:115:OCSP_check_validity -OCSP_F_OCSP_MATCH_ISSUERID:109:ocsp_match_issuerid -OCSP_F_OCSP_PARSE_URL:114:OCSP_parse_url -OCSP_F_OCSP_REQUEST_SIGN:110:OCSP_request_sign -OCSP_F_OCSP_REQUEST_VERIFY:116:OCSP_request_verify -OCSP_F_OCSP_RESPONSE_GET1_BASIC:111:OCSP_response_get1_basic -OCSP_F_PARSE_HTTP_LINE1:118:parse_http_line1 -OSSL_STORE_F_FILE_CTRL:129:file_ctrl -OSSL_STORE_F_FILE_FIND:138:file_find -OSSL_STORE_F_FILE_GET_PASS:118:file_get_pass -OSSL_STORE_F_FILE_LOAD:119:file_load -OSSL_STORE_F_FILE_LOAD_TRY_DECODE:124:file_load_try_decode -OSSL_STORE_F_FILE_NAME_TO_URI:126:file_name_to_uri -OSSL_STORE_F_FILE_OPEN:120:file_open -OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO:127:ossl_store_attach_pem_bio -OSSL_STORE_F_OSSL_STORE_EXPECT:130:OSSL_STORE_expect -OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT:128:\ - ossl_store_file_attach_pem_bio_int -OSSL_STORE_F_OSSL_STORE_FIND:131:OSSL_STORE_find -OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT:100:ossl_store_get0_loader_int -OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT:101:OSSL_STORE_INFO_get1_CERT -OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL:102:OSSL_STORE_INFO_get1_CRL -OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME:103:OSSL_STORE_INFO_get1_NAME -OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION:135:\ - OSSL_STORE_INFO_get1_NAME_description -OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS:104:OSSL_STORE_INFO_get1_PARAMS -OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY:105:OSSL_STORE_INFO_get1_PKEY -OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT:106:OSSL_STORE_INFO_new_CERT -OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL:107:OSSL_STORE_INFO_new_CRL -OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED:123:ossl_store_info_new_EMBEDDED -OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME:109:OSSL_STORE_INFO_new_NAME -OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS:110:OSSL_STORE_INFO_new_PARAMS -OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY:111:OSSL_STORE_INFO_new_PKEY -OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION:134:\ - OSSL_STORE_INFO_set0_NAME_description -OSSL_STORE_F_OSSL_STORE_INIT_ONCE:112:ossl_store_init_once -OSSL_STORE_F_OSSL_STORE_LOADER_NEW:113:OSSL_STORE_LOADER_new -OSSL_STORE_F_OSSL_STORE_OPEN:114:OSSL_STORE_open -OSSL_STORE_F_OSSL_STORE_OPEN_INT:115:* -OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT:117:ossl_store_register_loader_int -OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS:132:OSSL_STORE_SEARCH_by_alias -OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL:133:\ - OSSL_STORE_SEARCH_by_issuer_serial -OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT:136:\ - OSSL_STORE_SEARCH_by_key_fingerprint -OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME:137:OSSL_STORE_SEARCH_by_name -OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT:116:\ - ossl_store_unregister_loader_int -OSSL_STORE_F_TRY_DECODE_PARAMS:121:try_decode_params -OSSL_STORE_F_TRY_DECODE_PKCS12:122:try_decode_PKCS12 -OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED:125:try_decode_PKCS8Encrypted -PEM_F_B2I_DSS:127:b2i_dss -PEM_F_B2I_PVK_BIO:128:b2i_PVK_bio -PEM_F_B2I_RSA:129:b2i_rsa -PEM_F_CHECK_BITLEN_DSA:130:check_bitlen_dsa -PEM_F_CHECK_BITLEN_RSA:131:check_bitlen_rsa -PEM_F_D2I_PKCS8PRIVATEKEY_BIO:120:d2i_PKCS8PrivateKey_bio -PEM_F_D2I_PKCS8PRIVATEKEY_FP:121:d2i_PKCS8PrivateKey_fp -PEM_F_DO_B2I:132:do_b2i -PEM_F_DO_B2I_BIO:133:do_b2i_bio -PEM_F_DO_BLOB_HEADER:134:do_blob_header -PEM_F_DO_I2B:146:do_i2b -PEM_F_DO_PK8PKEY:126:do_pk8pkey -PEM_F_DO_PK8PKEY_FP:125:do_pk8pkey_fp -PEM_F_DO_PVK_BODY:135:do_PVK_body -PEM_F_DO_PVK_HEADER:136:do_PVK_header -PEM_F_GET_HEADER_AND_DATA:143:get_header_and_data -PEM_F_GET_NAME:144:get_name -PEM_F_I2B_PVK:137:i2b_PVK -PEM_F_I2B_PVK_BIO:138:i2b_PVK_bio -PEM_F_LOAD_IV:101:load_iv -PEM_F_PEM_ASN1_READ:102:PEM_ASN1_read -PEM_F_PEM_ASN1_READ_BIO:103:PEM_ASN1_read_bio -PEM_F_PEM_ASN1_WRITE:104:PEM_ASN1_write -PEM_F_PEM_ASN1_WRITE_BIO:105:PEM_ASN1_write_bio -PEM_F_PEM_DEF_CALLBACK:100:PEM_def_callback -PEM_F_PEM_DO_HEADER:106:PEM_do_header -PEM_F_PEM_GET_EVP_CIPHER_INFO:107:PEM_get_EVP_CIPHER_INFO -PEM_F_PEM_READ:108:PEM_read -PEM_F_PEM_READ_BIO:109:PEM_read_bio -PEM_F_PEM_READ_BIO_DHPARAMS:141:PEM_read_bio_DHparams -PEM_F_PEM_READ_BIO_EX:145:PEM_read_bio_ex -PEM_F_PEM_READ_BIO_PARAMETERS:140:PEM_read_bio_Parameters -PEM_F_PEM_READ_BIO_PRIVATEKEY:123:PEM_read_bio_PrivateKey -PEM_F_PEM_READ_DHPARAMS:142:PEM_read_DHparams -PEM_F_PEM_READ_PRIVATEKEY:124:PEM_read_PrivateKey -PEM_F_PEM_SIGNFINAL:112:PEM_SignFinal -PEM_F_PEM_WRITE:113:PEM_write -PEM_F_PEM_WRITE_BIO:114:PEM_write_bio -PEM_F_PEM_WRITE_BIO_PRIVATEKEY_TRADITIONAL:147:\ - PEM_write_bio_PrivateKey_traditional -PEM_F_PEM_WRITE_PRIVATEKEY:139:PEM_write_PrivateKey -PEM_F_PEM_X509_INFO_READ:115:PEM_X509_INFO_read -PEM_F_PEM_X509_INFO_READ_BIO:116:PEM_X509_INFO_read_bio -PEM_F_PEM_X509_INFO_WRITE_BIO:117:PEM_X509_INFO_write_bio -PKCS12_F_OPENSSL_ASC2UNI:121:OPENSSL_asc2uni -PKCS12_F_OPENSSL_UNI2ASC:124:OPENSSL_uni2asc -PKCS12_F_OPENSSL_UNI2UTF8:127:OPENSSL_uni2utf8 -PKCS12_F_OPENSSL_UTF82UNI:129:OPENSSL_utf82uni -PKCS12_F_PKCS12_CREATE:105:PKCS12_create -PKCS12_F_PKCS12_GEN_MAC:107:PKCS12_gen_mac -PKCS12_F_PKCS12_INIT:109:PKCS12_init -PKCS12_F_PKCS12_ITEM_DECRYPT_D2I:106:PKCS12_item_decrypt_d2i -PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT:108:PKCS12_item_i2d_encrypt -PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG:117:PKCS12_item_pack_safebag -PKCS12_F_PKCS12_KEY_GEN_ASC:110:PKCS12_key_gen_asc -PKCS12_F_PKCS12_KEY_GEN_UNI:111:PKCS12_key_gen_uni -PKCS12_F_PKCS12_KEY_GEN_UTF8:116:PKCS12_key_gen_utf8 -PKCS12_F_PKCS12_NEWPASS:128:PKCS12_newpass -PKCS12_F_PKCS12_PACK_P7DATA:114:PKCS12_pack_p7data -PKCS12_F_PKCS12_PACK_P7ENCDATA:115:PKCS12_pack_p7encdata -PKCS12_F_PKCS12_PARSE:118:PKCS12_parse -PKCS12_F_PKCS12_PBE_CRYPT:119:PKCS12_pbe_crypt -PKCS12_F_PKCS12_PBE_KEYIVGEN:120:PKCS12_PBE_keyivgen -PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF:112:PKCS12_SAFEBAG_create0_p8inf -PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8:113:PKCS12_SAFEBAG_create0_pkcs8 -PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT:133:\ - PKCS12_SAFEBAG_create_pkcs8_encrypt -PKCS12_F_PKCS12_SETUP_MAC:122:PKCS12_setup_mac -PKCS12_F_PKCS12_SET_MAC:123:PKCS12_set_mac -PKCS12_F_PKCS12_UNPACK_AUTHSAFES:130:PKCS12_unpack_authsafes -PKCS12_F_PKCS12_UNPACK_P7DATA:131:PKCS12_unpack_p7data -PKCS12_F_PKCS12_VERIFY_MAC:126:PKCS12_verify_mac -PKCS12_F_PKCS8_ENCRYPT:125:PKCS8_encrypt -PKCS12_F_PKCS8_SET0_PBE:132:PKCS8_set0_pbe -PKCS7_F_DO_PKCS7_SIGNED_ATTRIB:136:do_pkcs7_signed_attrib -PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME:135:PKCS7_add0_attrib_signing_time -PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP:118:PKCS7_add_attrib_smimecap -PKCS7_F_PKCS7_ADD_CERTIFICATE:100:PKCS7_add_certificate -PKCS7_F_PKCS7_ADD_CRL:101:PKCS7_add_crl -PKCS7_F_PKCS7_ADD_RECIPIENT_INFO:102:PKCS7_add_recipient_info -PKCS7_F_PKCS7_ADD_SIGNATURE:131:PKCS7_add_signature -PKCS7_F_PKCS7_ADD_SIGNER:103:PKCS7_add_signer -PKCS7_F_PKCS7_BIO_ADD_DIGEST:125:PKCS7_bio_add_digest -PKCS7_F_PKCS7_COPY_EXISTING_DIGEST:138:pkcs7_copy_existing_digest -PKCS7_F_PKCS7_CTRL:104:PKCS7_ctrl -PKCS7_F_PKCS7_DATADECODE:112:PKCS7_dataDecode -PKCS7_F_PKCS7_DATAFINAL:128:PKCS7_dataFinal -PKCS7_F_PKCS7_DATAINIT:105:PKCS7_dataInit -PKCS7_F_PKCS7_DATAVERIFY:107:PKCS7_dataVerify -PKCS7_F_PKCS7_DECRYPT:114:PKCS7_decrypt -PKCS7_F_PKCS7_DECRYPT_RINFO:133:pkcs7_decrypt_rinfo -PKCS7_F_PKCS7_ENCODE_RINFO:132:pkcs7_encode_rinfo -PKCS7_F_PKCS7_ENCRYPT:115:PKCS7_encrypt -PKCS7_F_PKCS7_FINAL:134:PKCS7_final -PKCS7_F_PKCS7_FIND_DIGEST:127:PKCS7_find_digest -PKCS7_F_PKCS7_GET0_SIGNERS:124:PKCS7_get0_signers -PKCS7_F_PKCS7_RECIP_INFO_SET:130:PKCS7_RECIP_INFO_set -PKCS7_F_PKCS7_SET_CIPHER:108:PKCS7_set_cipher -PKCS7_F_PKCS7_SET_CONTENT:109:PKCS7_set_content -PKCS7_F_PKCS7_SET_DIGEST:126:PKCS7_set_digest -PKCS7_F_PKCS7_SET_TYPE:110:PKCS7_set_type -PKCS7_F_PKCS7_SIGN:116:PKCS7_sign -PKCS7_F_PKCS7_SIGNATUREVERIFY:113:PKCS7_signatureVerify -PKCS7_F_PKCS7_SIGNER_INFO_SET:129:PKCS7_SIGNER_INFO_set -PKCS7_F_PKCS7_SIGNER_INFO_SIGN:139:PKCS7_SIGNER_INFO_sign -PKCS7_F_PKCS7_SIGN_ADD_SIGNER:137:PKCS7_sign_add_signer -PKCS7_F_PKCS7_SIMPLE_SMIMECAP:119:PKCS7_simple_smimecap -PKCS7_F_PKCS7_VERIFY:117:PKCS7_verify -RAND_F_DATA_COLLECT_METHOD:127:data_collect_method -RAND_F_DRBG_BYTES:101:drbg_bytes -RAND_F_DRBG_GET_ENTROPY:105:drbg_get_entropy -RAND_F_DRBG_SETUP:117:drbg_setup -RAND_F_GET_ENTROPY:106:get_entropy -RAND_F_RAND_BYTES:100:RAND_bytes -RAND_F_RAND_DRBG_ENABLE_LOCKING:119:rand_drbg_enable_locking -RAND_F_RAND_DRBG_GENERATE:107:RAND_DRBG_generate -RAND_F_RAND_DRBG_GET_ENTROPY:120:rand_drbg_get_entropy -RAND_F_RAND_DRBG_GET_NONCE:123:rand_drbg_get_nonce -RAND_F_RAND_DRBG_INSTANTIATE:108:RAND_DRBG_instantiate -RAND_F_RAND_DRBG_NEW:109:RAND_DRBG_new -RAND_F_RAND_DRBG_RESEED:110:RAND_DRBG_reseed -RAND_F_RAND_DRBG_RESTART:102:rand_drbg_restart -RAND_F_RAND_DRBG_SET:104:RAND_DRBG_set -RAND_F_RAND_DRBG_SET_DEFAULTS:121:RAND_DRBG_set_defaults -RAND_F_RAND_DRBG_UNINSTANTIATE:118:RAND_DRBG_uninstantiate -RAND_F_RAND_LOAD_FILE:111:RAND_load_file -RAND_F_RAND_POOL_ACQUIRE_ENTROPY:122:rand_pool_acquire_entropy -RAND_F_RAND_POOL_ADD:103:rand_pool_add -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_PSEUDO_BYTES:126:RAND_pseudo_bytes -RAND_F_RAND_WRITE_FILE:112:RAND_write_file -RSA_F_CHECK_PADDING_MD:140:check_padding_md -RSA_F_ENCODE_PKCS1:146:encode_pkcs1 -RSA_F_INT_RSA_VERIFY:145:int_rsa_verify -RSA_F_OLD_RSA_PRIV_DECODE:147:old_rsa_priv_decode -RSA_F_PKEY_PSS_INIT:165:pkey_pss_init -RSA_F_PKEY_RSA_CTRL:143:pkey_rsa_ctrl -RSA_F_PKEY_RSA_CTRL_STR:144:pkey_rsa_ctrl_str -RSA_F_PKEY_RSA_SIGN:142:pkey_rsa_sign -RSA_F_PKEY_RSA_VERIFY:149:pkey_rsa_verify -RSA_F_PKEY_RSA_VERIFYRECOVER:141:pkey_rsa_verifyrecover -RSA_F_RSA_ALGOR_TO_MD:156:rsa_algor_to_md -RSA_F_RSA_BUILTIN_KEYGEN:129:rsa_builtin_keygen -RSA_F_RSA_CHECK_KEY:123:RSA_check_key -RSA_F_RSA_CHECK_KEY_EX:160:RSA_check_key_ex -RSA_F_RSA_CMS_DECRYPT:159:rsa_cms_decrypt -RSA_F_RSA_CMS_VERIFY:158:rsa_cms_verify -RSA_F_RSA_ITEM_VERIFY:148:rsa_item_verify -RSA_F_RSA_METH_DUP:161:RSA_meth_dup -RSA_F_RSA_METH_NEW:162:RSA_meth_new -RSA_F_RSA_METH_SET1_NAME:163:RSA_meth_set1_name -RSA_F_RSA_MGF1_TO_MD:157:* -RSA_F_RSA_MULTIP_INFO_NEW:166:rsa_multip_info_new -RSA_F_RSA_NEW_METHOD:106:RSA_new_method -RSA_F_RSA_NULL:124:* -RSA_F_RSA_NULL_PRIVATE_DECRYPT:132:* -RSA_F_RSA_NULL_PRIVATE_ENCRYPT:133:* -RSA_F_RSA_NULL_PUBLIC_DECRYPT:134:* -RSA_F_RSA_NULL_PUBLIC_ENCRYPT:135:* -RSA_F_RSA_OSSL_PRIVATE_DECRYPT:101:rsa_ossl_private_decrypt -RSA_F_RSA_OSSL_PRIVATE_ENCRYPT:102:rsa_ossl_private_encrypt -RSA_F_RSA_OSSL_PUBLIC_DECRYPT:103:rsa_ossl_public_decrypt -RSA_F_RSA_OSSL_PUBLIC_ENCRYPT:104:rsa_ossl_public_encrypt -RSA_F_RSA_PADDING_ADD_NONE:107:RSA_padding_add_none -RSA_F_RSA_PADDING_ADD_PKCS1_OAEP:121:RSA_padding_add_PKCS1_OAEP -RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1:154:RSA_padding_add_PKCS1_OAEP_mgf1 -RSA_F_RSA_PADDING_ADD_PKCS1_PSS:125:RSA_padding_add_PKCS1_PSS -RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1:152:RSA_padding_add_PKCS1_PSS_mgf1 -RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1:108:RSA_padding_add_PKCS1_type_1 -RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2:109:RSA_padding_add_PKCS1_type_2 -RSA_F_RSA_PADDING_ADD_SSLV23:110:RSA_padding_add_SSLv23 -RSA_F_RSA_PADDING_ADD_X931:127:RSA_padding_add_X931 -RSA_F_RSA_PADDING_CHECK_NONE:111:RSA_padding_check_none -RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP:122:RSA_padding_check_PKCS1_OAEP -RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1:153:RSA_padding_check_PKCS1_OAEP_mgf1 -RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1:112:RSA_padding_check_PKCS1_type_1 -RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2:113:RSA_padding_check_PKCS1_type_2 -RSA_F_RSA_PADDING_CHECK_SSLV23:114:RSA_padding_check_SSLv23 -RSA_F_RSA_PADDING_CHECK_X931:128:RSA_padding_check_X931 -RSA_F_RSA_PARAM_DECODE:164:rsa_param_decode -RSA_F_RSA_PRINT:115:RSA_print -RSA_F_RSA_PRINT_FP:116:RSA_print_fp -RSA_F_RSA_PRIV_DECODE:150:rsa_priv_decode -RSA_F_RSA_PRIV_ENCODE:138:rsa_priv_encode -RSA_F_RSA_PSS_GET_PARAM:151:rsa_pss_get_param -RSA_F_RSA_PSS_TO_CTX:155:rsa_pss_to_ctx -RSA_F_RSA_PUB_DECODE:139:rsa_pub_decode -RSA_F_RSA_SETUP_BLINDING:136:RSA_setup_blinding -RSA_F_RSA_SIGN:117:RSA_sign -RSA_F_RSA_SIGN_ASN1_OCTET_STRING:118:RSA_sign_ASN1_OCTET_STRING -RSA_F_RSA_VERIFY:119:RSA_verify -RSA_F_RSA_VERIFY_ASN1_OCTET_STRING:120:RSA_verify_ASN1_OCTET_STRING -RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1:126:RSA_verify_PKCS1_PSS_mgf1 -RSA_F_SETUP_TBUF:167:setup_tbuf -SM2_F_PKEY_SM2_COPY:115:pkey_sm2_copy -SM2_F_PKEY_SM2_CTRL:109:pkey_sm2_ctrl -SM2_F_PKEY_SM2_CTRL_STR:110:pkey_sm2_ctrl_str -SM2_F_PKEY_SM2_DIGEST_CUSTOM:114:pkey_sm2_digest_custom -SM2_F_PKEY_SM2_INIT:111:pkey_sm2_init -SM2_F_PKEY_SM2_SIGN:112:pkey_sm2_sign -SM2_F_SM2_COMPUTE_MSG_HASH:100:sm2_compute_msg_hash -SM2_F_SM2_COMPUTE_USERID_DIGEST:101:sm2_compute_userid_digest -SM2_F_SM2_COMPUTE_Z_DIGEST:113:sm2_compute_z_digest -SM2_F_SM2_DECRYPT:102:sm2_decrypt -SM2_F_SM2_ENCRYPT:103:sm2_encrypt -SM2_F_SM2_PLAINTEXT_SIZE:104:sm2_plaintext_size -SM2_F_SM2_SIGN:105:sm2_sign -SM2_F_SM2_SIG_GEN:106:sm2_sig_gen -SM2_F_SM2_SIG_VERIFY:107:sm2_sig_verify -SM2_F_SM2_VERIFY:108:sm2_verify -SSL_F_ADD_CLIENT_KEY_SHARE_EXT:438:* -SSL_F_ADD_KEY_SHARE:512:add_key_share -SSL_F_BYTES_TO_CIPHER_LIST:519:bytes_to_cipher_list -SSL_F_CHECK_SUITEB_CIPHER_LIST:331:check_suiteb_cipher_list -SSL_F_CIPHERSUITE_CB:622:ciphersuite_cb -SSL_F_CONSTRUCT_CA_NAMES:552:construct_ca_names -SSL_F_CONSTRUCT_KEY_EXCHANGE_TBS:553:construct_key_exchange_tbs -SSL_F_CONSTRUCT_STATEFUL_TICKET:636:construct_stateful_ticket -SSL_F_CONSTRUCT_STATELESS_TICKET:637:construct_stateless_ticket -SSL_F_CREATE_SYNTHETIC_MESSAGE_HASH:539:create_synthetic_message_hash -SSL_F_CREATE_TICKET_PREQUEL:638:create_ticket_prequel -SSL_F_CT_MOVE_SCTS:345:ct_move_scts -SSL_F_CT_STRICT:349:ct_strict -SSL_F_CUSTOM_EXT_ADD:554:custom_ext_add -SSL_F_CUSTOM_EXT_PARSE:555:custom_ext_parse -SSL_F_D2I_SSL_SESSION:103:d2i_SSL_SESSION -SSL_F_DANE_CTX_ENABLE:347:dane_ctx_enable -SSL_F_DANE_MTYPE_SET:393:dane_mtype_set -SSL_F_DANE_TLSA_ADD:394:dane_tlsa_add -SSL_F_DERIVE_SECRET_KEY_AND_IV:514:derive_secret_key_and_iv -SSL_F_DO_DTLS1_WRITE:245:do_dtls1_write -SSL_F_DO_SSL3_WRITE:104:do_ssl3_write -SSL_F_DTLS1_BUFFER_RECORD:247:dtls1_buffer_record -SSL_F_DTLS1_CHECK_TIMEOUT_NUM:318:dtls1_check_timeout_num -SSL_F_DTLS1_HEARTBEAT:305:* -SSL_F_DTLS1_HM_FRAGMENT_NEW:623:dtls1_hm_fragment_new -SSL_F_DTLS1_PREPROCESS_FRAGMENT:288:dtls1_preprocess_fragment -SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS:424:dtls1_process_buffered_records -SSL_F_DTLS1_PROCESS_RECORD:257:dtls1_process_record -SSL_F_DTLS1_READ_BYTES:258:dtls1_read_bytes -SSL_F_DTLS1_READ_FAILED:339:dtls1_read_failed -SSL_F_DTLS1_RETRANSMIT_MESSAGE:390:dtls1_retransmit_message -SSL_F_DTLS1_WRITE_APP_DATA_BYTES:268:dtls1_write_app_data_bytes -SSL_F_DTLS1_WRITE_BYTES:545:dtls1_write_bytes -SSL_F_DTLSV1_LISTEN:350:DTLSv1_listen -SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC:371:dtls_construct_change_cipher_spec -SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST:385:\ - dtls_construct_hello_verify_request -SSL_F_DTLS_GET_REASSEMBLED_MESSAGE:370:dtls_get_reassembled_message -SSL_F_DTLS_PROCESS_HELLO_VERIFY:386:dtls_process_hello_verify -SSL_F_DTLS_RECORD_LAYER_NEW:635:DTLS_RECORD_LAYER_new -SSL_F_DTLS_WAIT_FOR_DRY:592:dtls_wait_for_dry -SSL_F_EARLY_DATA_COUNT_OK:532:early_data_count_ok -SSL_F_FINAL_EARLY_DATA:556:final_early_data -SSL_F_FINAL_EC_PT_FORMATS:485:final_ec_pt_formats -SSL_F_FINAL_EMS:486:final_ems -SSL_F_FINAL_KEY_SHARE:503:final_key_share -SSL_F_FINAL_MAXFRAGMENTLEN:557:final_maxfragmentlen -SSL_F_FINAL_PSK:639:final_psk -SSL_F_FINAL_RENEGOTIATE:483:final_renegotiate -SSL_F_FINAL_SERVER_NAME:558:final_server_name -SSL_F_FINAL_SIG_ALGS:497:final_sig_algs -SSL_F_GET_CERT_VERIFY_TBS_DATA:588:get_cert_verify_tbs_data -SSL_F_NSS_KEYLOG_INT:500:nss_keylog_int -SSL_F_OPENSSL_INIT_SSL:342:OPENSSL_init_ssl -SSL_F_OSSL_STATEM_CLIENT13_READ_TRANSITION:436:* -SSL_F_OSSL_STATEM_CLIENT13_WRITE_TRANSITION:598:\ - ossl_statem_client13_write_transition -SSL_F_OSSL_STATEM_CLIENT_CONSTRUCT_MESSAGE:430:* -SSL_F_OSSL_STATEM_CLIENT_POST_PROCESS_MESSAGE:593:\ - ossl_statem_client_post_process_message -SSL_F_OSSL_STATEM_CLIENT_PROCESS_MESSAGE:594:ossl_statem_client_process_message -SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION:417:ossl_statem_client_read_transition -SSL_F_OSSL_STATEM_CLIENT_WRITE_TRANSITION:599:\ - ossl_statem_client_write_transition -SSL_F_OSSL_STATEM_SERVER13_READ_TRANSITION:437:* -SSL_F_OSSL_STATEM_SERVER13_WRITE_TRANSITION:600:\ - ossl_statem_server13_write_transition -SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE:431:* -SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE:601:\ - ossl_statem_server_post_process_message -SSL_F_OSSL_STATEM_SERVER_POST_WORK:602:ossl_statem_server_post_work -SSL_F_OSSL_STATEM_SERVER_PRE_WORK:640: -SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE:603:ossl_statem_server_process_message -SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION:418:ossl_statem_server_read_transition -SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION:604:\ - ossl_statem_server_write_transition -SSL_F_PARSE_CA_NAMES:541:parse_ca_names -SSL_F_PITEM_NEW:624:pitem_new -SSL_F_PQUEUE_NEW:625:pqueue_new -SSL_F_PROCESS_KEY_SHARE_EXT:439:* -SSL_F_READ_STATE_MACHINE:352:read_state_machine -SSL_F_SET_CLIENT_CIPHERSUITE:540:set_client_ciphersuite -SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET:595:srp_generate_client_master_secret -SSL_F_SRP_GENERATE_SERVER_MASTER_SECRET:589:srp_generate_server_master_secret -SSL_F_SRP_VERIFY_SERVER_PARAM:596:srp_verify_server_param -SSL_F_SSL3_CHANGE_CIPHER_STATE:129:ssl3_change_cipher_state -SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM:130:ssl3_check_cert_and_algorithm -SSL_F_SSL3_CTRL:213:ssl3_ctrl -SSL_F_SSL3_CTX_CTRL:133:ssl3_ctx_ctrl -SSL_F_SSL3_DIGEST_CACHED_RECORDS:293:ssl3_digest_cached_records -SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC:292:ssl3_do_change_cipher_spec -SSL_F_SSL3_ENC:608:ssl3_enc -SSL_F_SSL3_FINAL_FINISH_MAC:285:ssl3_final_finish_mac -SSL_F_SSL3_FINISH_MAC:587:ssl3_finish_mac -SSL_F_SSL3_GENERATE_KEY_BLOCK:238:ssl3_generate_key_block -SSL_F_SSL3_GENERATE_MASTER_SECRET:388:ssl3_generate_master_secret -SSL_F_SSL3_GET_RECORD:143:ssl3_get_record -SSL_F_SSL3_INIT_FINISHED_MAC:397:ssl3_init_finished_mac -SSL_F_SSL3_OUTPUT_CERT_CHAIN:147:ssl3_output_cert_chain -SSL_F_SSL3_READ_BYTES:148:ssl3_read_bytes -SSL_F_SSL3_READ_N:149:ssl3_read_n -SSL_F_SSL3_SETUP_KEY_BLOCK:157:ssl3_setup_key_block -SSL_F_SSL3_SETUP_READ_BUFFER:156:ssl3_setup_read_buffer -SSL_F_SSL3_SETUP_WRITE_BUFFER:291:ssl3_setup_write_buffer -SSL_F_SSL3_WRITE_BYTES:158:ssl3_write_bytes -SSL_F_SSL3_WRITE_PENDING:159:ssl3_write_pending -SSL_F_SSL_ADD_CERT_CHAIN:316:ssl_add_cert_chain -SSL_F_SSL_ADD_CERT_TO_BUF:319:* -SSL_F_SSL_ADD_CERT_TO_WPACKET:493:ssl_add_cert_to_wpacket -SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT:298:* -SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT:277:* -SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT:307:* -SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK:215:SSL_add_dir_cert_subjects_to_stack -SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK:216:\ - SSL_add_file_cert_subjects_to_stack -SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT:299:* -SSL_F_SSL_ADD_SERVERHELLO_TLSEXT:278:* -SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT:308:* -SSL_F_SSL_BAD_METHOD:160:ssl_bad_method -SSL_F_SSL_BUILD_CERT_CHAIN:332:ssl_build_cert_chain -SSL_F_SSL_BYTES_TO_CIPHER_LIST:161:SSL_bytes_to_cipher_list -SSL_F_SSL_CACHE_CIPHERLIST:520:ssl_cache_cipherlist -SSL_F_SSL_CERT_ADD0_CHAIN_CERT:346:ssl_cert_add0_chain_cert -SSL_F_SSL_CERT_DUP:221:ssl_cert_dup -SSL_F_SSL_CERT_NEW:162:ssl_cert_new -SSL_F_SSL_CERT_SET0_CHAIN:340:ssl_cert_set0_chain -SSL_F_SSL_CHECK_PRIVATE_KEY:163:SSL_check_private_key -SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT:280:* -SSL_F_SSL_CHECK_SRP_EXT_CLIENTHELLO:606:ssl_check_srp_ext_ClientHello -SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG:279:ssl_check_srvr_ecc_cert_and_alg -SSL_F_SSL_CHOOSE_CLIENT_VERSION:607:ssl_choose_client_version -SSL_F_SSL_CIPHER_DESCRIPTION:626:SSL_CIPHER_description -SSL_F_SSL_CIPHER_LIST_TO_BYTES:425:ssl_cipher_list_to_bytes -SSL_F_SSL_CIPHER_PROCESS_RULESTR:230:ssl_cipher_process_rulestr -SSL_F_SSL_CIPHER_STRENGTH_SORT:231:ssl_cipher_strength_sort -SSL_F_SSL_CLEAR:164:SSL_clear -SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT:627:\ - SSL_client_hello_get1_extensions_present -SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD:165:SSL_COMP_add_compression_method -SSL_F_SSL_CONF_CMD:334:SSL_CONF_cmd -SSL_F_SSL_CREATE_CIPHER_LIST:166:ssl_create_cipher_list -SSL_F_SSL_CTRL:232:SSL_ctrl -SSL_F_SSL_CTX_CHECK_PRIVATE_KEY:168:SSL_CTX_check_private_key -SSL_F_SSL_CTX_ENABLE_CT:398:SSL_CTX_enable_ct -SSL_F_SSL_CTX_MAKE_PROFILES:309:ssl_ctx_make_profiles -SSL_F_SSL_CTX_NEW:169:SSL_CTX_new -SSL_F_SSL_CTX_SET_ALPN_PROTOS:343:SSL_CTX_set_alpn_protos -SSL_F_SSL_CTX_SET_CIPHER_LIST:269:SSL_CTX_set_cipher_list -SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE:290:SSL_CTX_set_client_cert_engine -SSL_F_SSL_CTX_SET_CT_VALIDATION_CALLBACK:396:SSL_CTX_set_ct_validation_callback -SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT:219:SSL_CTX_set_session_id_context -SSL_F_SSL_CTX_SET_SSL_VERSION:170:SSL_CTX_set_ssl_version -SSL_F_SSL_CTX_SET_TLSEXT_MAX_FRAGMENT_LENGTH:551:\ - SSL_CTX_set_tlsext_max_fragment_length -SSL_F_SSL_CTX_USE_CERTIFICATE:171:SSL_CTX_use_certificate -SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1:172:SSL_CTX_use_certificate_ASN1 -SSL_F_SSL_CTX_USE_CERTIFICATE_FILE:173:SSL_CTX_use_certificate_file -SSL_F_SSL_CTX_USE_PRIVATEKEY:174:SSL_CTX_use_PrivateKey -SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1:175:SSL_CTX_use_PrivateKey_ASN1 -SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE:176:SSL_CTX_use_PrivateKey_file -SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT:272:SSL_CTX_use_psk_identity_hint -SSL_F_SSL_CTX_USE_RSAPRIVATEKEY:177:SSL_CTX_use_RSAPrivateKey -SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1:178:SSL_CTX_use_RSAPrivateKey_ASN1 -SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE:179:SSL_CTX_use_RSAPrivateKey_file -SSL_F_SSL_CTX_USE_SERVERINFO:336:SSL_CTX_use_serverinfo -SSL_F_SSL_CTX_USE_SERVERINFO_EX:543:SSL_CTX_use_serverinfo_ex -SSL_F_SSL_CTX_USE_SERVERINFO_FILE:337:SSL_CTX_use_serverinfo_file -SSL_F_SSL_DANE_DUP:403:ssl_dane_dup -SSL_F_SSL_DANE_ENABLE:395:SSL_dane_enable -SSL_F_SSL_DERIVE:590:ssl_derive -SSL_F_SSL_DO_CONFIG:391:ssl_do_config -SSL_F_SSL_DO_HANDSHAKE:180:SSL_do_handshake -SSL_F_SSL_DUP_CA_LIST:408:SSL_dup_CA_list -SSL_F_SSL_ENABLE_CT:402:SSL_enable_ct -SSL_F_SSL_GENERATE_PKEY_GROUP:559:ssl_generate_pkey_group -SSL_F_SSL_GENERATE_SESSION_ID:547:ssl_generate_session_id -SSL_F_SSL_GET_NEW_SESSION:181:ssl_get_new_session -SSL_F_SSL_GET_PREV_SESSION:217:ssl_get_prev_session -SSL_F_SSL_GET_SERVER_CERT_INDEX:322:* -SSL_F_SSL_GET_SIGN_PKEY:183:* -SSL_F_SSL_HANDSHAKE_HASH:560:ssl_handshake_hash -SSL_F_SSL_INIT_WBIO_BUFFER:184:ssl_init_wbio_buffer -SSL_F_SSL_KEY_UPDATE:515:SSL_key_update -SSL_F_SSL_LOAD_CLIENT_CA_FILE:185:SSL_load_client_CA_file -SSL_F_SSL_LOG_MASTER_SECRET:498:* -SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE:499:ssl_log_rsa_client_key_exchange -SSL_F_SSL_MODULE_INIT:392:ssl_module_init -SSL_F_SSL_NEW:186:SSL_new -SSL_F_SSL_NEXT_PROTO_VALIDATE:565:ssl_next_proto_validate -SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT:300:* -SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT:302:* -SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT:310:* -SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT:301:* -SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT:303:* -SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT:311:* -SSL_F_SSL_PEEK:270:SSL_peek -SSL_F_SSL_PEEK_EX:432:SSL_peek_ex -SSL_F_SSL_PEEK_INTERNAL:522:ssl_peek_internal -SSL_F_SSL_READ:223:SSL_read -SSL_F_SSL_READ_EARLY_DATA:529:SSL_read_early_data -SSL_F_SSL_READ_EX:434:SSL_read_ex -SSL_F_SSL_READ_INTERNAL:523:ssl_read_internal -SSL_F_SSL_RENEGOTIATE:516:SSL_renegotiate -SSL_F_SSL_RENEGOTIATE_ABBREVIATED:546:SSL_renegotiate_abbreviated -SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT:320:* -SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT:321:* -SSL_F_SSL_SENDFILE:639:SSL_sendfile -SSL_F_SSL_SESSION_DUP:348:ssl_session_dup -SSL_F_SSL_SESSION_NEW:189:SSL_SESSION_new -SSL_F_SSL_SESSION_PRINT_FP:190:SSL_SESSION_print_fp -SSL_F_SSL_SESSION_SET1_ID:423:SSL_SESSION_set1_id -SSL_F_SSL_SESSION_SET1_ID_CONTEXT:312:SSL_SESSION_set1_id_context -SSL_F_SSL_SET_ALPN_PROTOS:344:SSL_set_alpn_protos -SSL_F_SSL_SET_CERT:191:ssl_set_cert -SSL_F_SSL_SET_CERT_AND_KEY:621:ssl_set_cert_and_key -SSL_F_SSL_SET_CIPHER_LIST:271:SSL_set_cipher_list -SSL_F_SSL_SET_CT_VALIDATION_CALLBACK:399:SSL_set_ct_validation_callback -SSL_F_SSL_SET_FD:192:SSL_set_fd -SSL_F_SSL_SET_PKEY:193:ssl_set_pkey -SSL_F_SSL_SET_RFD:194:SSL_set_rfd -SSL_F_SSL_SET_SESSION:195:SSL_set_session -SSL_F_SSL_SET_SESSION_ID_CONTEXT:218:SSL_set_session_id_context -SSL_F_SSL_SET_SESSION_TICKET_EXT:294:SSL_set_session_ticket_ext -SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH:550:SSL_set_tlsext_max_fragment_length -SSL_F_SSL_SET_WFD:196:SSL_set_wfd -SSL_F_SSL_SHUTDOWN:224:SSL_shutdown -SSL_F_SSL_SRP_CTX_INIT:313:SSL_SRP_CTX_init -SSL_F_SSL_START_ASYNC_JOB:389:ssl_start_async_job -SSL_F_SSL_UNDEFINED_FUNCTION:197:ssl_undefined_function -SSL_F_SSL_UNDEFINED_VOID_FUNCTION:244:ssl_undefined_void_function -SSL_F_SSL_USE_CERTIFICATE:198:SSL_use_certificate -SSL_F_SSL_USE_CERTIFICATE_ASN1:199:SSL_use_certificate_ASN1 -SSL_F_SSL_USE_CERTIFICATE_FILE:200:SSL_use_certificate_file -SSL_F_SSL_USE_PRIVATEKEY:201:SSL_use_PrivateKey -SSL_F_SSL_USE_PRIVATEKEY_ASN1:202:SSL_use_PrivateKey_ASN1 -SSL_F_SSL_USE_PRIVATEKEY_FILE:203:SSL_use_PrivateKey_file -SSL_F_SSL_USE_PSK_IDENTITY_HINT:273:SSL_use_psk_identity_hint -SSL_F_SSL_USE_RSAPRIVATEKEY:204:SSL_use_RSAPrivateKey -SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1:205:SSL_use_RSAPrivateKey_ASN1 -SSL_F_SSL_USE_RSAPRIVATEKEY_FILE:206:SSL_use_RSAPrivateKey_file -SSL_F_SSL_VALIDATE_CT:400:ssl_validate_ct -SSL_F_SSL_VERIFY_CERT_CHAIN:207:ssl_verify_cert_chain -SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE:616:SSL_verify_client_post_handshake -SSL_F_SSL_WRITE:208:SSL_write -SSL_F_SSL_WRITE_EARLY_DATA:526:SSL_write_early_data -SSL_F_SSL_WRITE_EARLY_FINISH:527:* -SSL_F_SSL_WRITE_EX:433:SSL_write_ex -SSL_F_SSL_WRITE_INTERNAL:524:ssl_write_internal -SSL_F_STATE_MACHINE:353:state_machine -SSL_F_TLS12_CHECK_PEER_SIGALG:333:tls12_check_peer_sigalg -SSL_F_TLS12_COPY_SIGALGS:533:tls12_copy_sigalgs -SSL_F_TLS13_CHANGE_CIPHER_STATE:440:tls13_change_cipher_state -SSL_F_TLS13_ENC:609:tls13_enc -SSL_F_TLS13_FINAL_FINISH_MAC:605:tls13_final_finish_mac -SSL_F_TLS13_GENERATE_SECRET:591:tls13_generate_secret -SSL_F_TLS13_HKDF_EXPAND:561:tls13_hkdf_expand -SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA:617:\ - tls13_restore_handshake_digest_for_pha -SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA:618:\ - tls13_save_handshake_digest_for_pha -SSL_F_TLS13_SETUP_KEY_BLOCK:441:tls13_setup_key_block -SSL_F_TLS1_CHANGE_CIPHER_STATE:209:tls1_change_cipher_state -SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS:341:* -SSL_F_TLS1_ENC:401:tls1_enc -SSL_F_TLS1_EXPORT_KEYING_MATERIAL:314:tls1_export_keying_material -SSL_F_TLS1_GET_CURVELIST:338:tls1_get_curvelist -SSL_F_TLS1_PRF:284:tls1_PRF -SSL_F_TLS1_SAVE_U16:628:tls1_save_u16 -SSL_F_TLS1_SETUP_KEY_BLOCK:211:tls1_setup_key_block -SSL_F_TLS1_SET_GROUPS:629:tls1_set_groups -SSL_F_TLS1_SET_RAW_SIGALGS:630:tls1_set_raw_sigalgs -SSL_F_TLS1_SET_SERVER_SIGALGS:335:tls1_set_server_sigalgs -SSL_F_TLS1_SET_SHARED_SIGALGS:631:tls1_set_shared_sigalgs -SSL_F_TLS1_SET_SIGALGS:632:tls1_set_sigalgs -SSL_F_TLS_CHOOSE_SIGALG:513:tls_choose_sigalg -SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK:354:tls_client_key_exchange_post_work -SSL_F_TLS_COLLECT_EXTENSIONS:435:tls_collect_extensions -SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES:542:\ - tls_construct_certificate_authorities -SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST:372:tls_construct_certificate_request -SSL_F_TLS_CONSTRUCT_CERT_STATUS:429:* -SSL_F_TLS_CONSTRUCT_CERT_STATUS_BODY:494:tls_construct_cert_status_body -SSL_F_TLS_CONSTRUCT_CERT_VERIFY:496:tls_construct_cert_verify -SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC:427:tls_construct_change_cipher_spec -SSL_F_TLS_CONSTRUCT_CKE_DHE:404:tls_construct_cke_dhe -SSL_F_TLS_CONSTRUCT_CKE_ECDHE:405:tls_construct_cke_ecdhe -SSL_F_TLS_CONSTRUCT_CKE_GOST:406:tls_construct_cke_gost -SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE:407:tls_construct_cke_psk_preamble -SSL_F_TLS_CONSTRUCT_CKE_RSA:409:tls_construct_cke_rsa -SSL_F_TLS_CONSTRUCT_CKE_SRP:410:tls_construct_cke_srp -SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE:484:tls_construct_client_certificate -SSL_F_TLS_CONSTRUCT_CLIENT_HELLO:487:tls_construct_client_hello -SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE:488:tls_construct_client_key_exchange -SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY:489:* -SSL_F_TLS_CONSTRUCT_CTOS_ALPN:466:tls_construct_ctos_alpn -SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE:355:* -SSL_F_TLS_CONSTRUCT_CTOS_COOKIE:535:tls_construct_ctos_cookie -SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA:530:tls_construct_ctos_early_data -SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS:467:tls_construct_ctos_ec_pt_formats -SSL_F_TLS_CONSTRUCT_CTOS_EMS:468:tls_construct_ctos_ems -SSL_F_TLS_CONSTRUCT_CTOS_ETM:469:tls_construct_ctos_etm -SSL_F_TLS_CONSTRUCT_CTOS_HELLO:356:* -SSL_F_TLS_CONSTRUCT_CTOS_KEY_EXCHANGE:357:* -SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE:470:tls_construct_ctos_key_share -SSL_F_TLS_CONSTRUCT_CTOS_MAXFRAGMENTLEN:549:tls_construct_ctos_maxfragmentlen -SSL_F_TLS_CONSTRUCT_CTOS_NPN:471:tls_construct_ctos_npn -SSL_F_TLS_CONSTRUCT_CTOS_PADDING:472:tls_construct_ctos_padding -SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH:619:\ - tls_construct_ctos_post_handshake_auth -SSL_F_TLS_CONSTRUCT_CTOS_PSK:501:tls_construct_ctos_psk -SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES:509:tls_construct_ctos_psk_kex_modes -SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE:473:tls_construct_ctos_renegotiate -SSL_F_TLS_CONSTRUCT_CTOS_SCT:474:tls_construct_ctos_sct -SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME:475:tls_construct_ctos_server_name -SSL_F_TLS_CONSTRUCT_CTOS_SESSION_TICKET:476:tls_construct_ctos_session_ticket -SSL_F_TLS_CONSTRUCT_CTOS_SIG_ALGS:477:tls_construct_ctos_sig_algs -SSL_F_TLS_CONSTRUCT_CTOS_SRP:478:tls_construct_ctos_srp -SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST:479:tls_construct_ctos_status_request -SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS:480:\ - tls_construct_ctos_supported_groups -SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS:481:\ - tls_construct_ctos_supported_versions -SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP:482:tls_construct_ctos_use_srtp -SSL_F_TLS_CONSTRUCT_CTOS_VERIFY:358:* -SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS:443:tls_construct_encrypted_extensions -SSL_F_TLS_CONSTRUCT_END_OF_EARLY_DATA:536:tls_construct_end_of_early_data -SSL_F_TLS_CONSTRUCT_EXTENSIONS:447:tls_construct_extensions -SSL_F_TLS_CONSTRUCT_FINISHED:359:tls_construct_finished -SSL_F_TLS_CONSTRUCT_HELLO_REQUEST:373:* -SSL_F_TLS_CONSTRUCT_HELLO_RETRY_REQUEST:510:tls_construct_hello_retry_request -SSL_F_TLS_CONSTRUCT_KEY_UPDATE:517:tls_construct_key_update -SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET:428:tls_construct_new_session_ticket -SSL_F_TLS_CONSTRUCT_NEXT_PROTO:426:tls_construct_next_proto -SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE:490:tls_construct_server_certificate -SSL_F_TLS_CONSTRUCT_SERVER_HELLO:491:tls_construct_server_hello -SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE:492:tls_construct_server_key_exchange -SSL_F_TLS_CONSTRUCT_STOC_ALPN:451:tls_construct_stoc_alpn -SSL_F_TLS_CONSTRUCT_STOC_CERTIFICATE:374:* -SSL_F_TLS_CONSTRUCT_STOC_COOKIE:613:tls_construct_stoc_cookie -SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG:452:tls_construct_stoc_cryptopro_bug -SSL_F_TLS_CONSTRUCT_STOC_DONE:375:* -SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA:531:tls_construct_stoc_early_data -SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA_INFO:525:* -SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS:453:tls_construct_stoc_ec_pt_formats -SSL_F_TLS_CONSTRUCT_STOC_EMS:454:tls_construct_stoc_ems -SSL_F_TLS_CONSTRUCT_STOC_ETM:455:tls_construct_stoc_etm -SSL_F_TLS_CONSTRUCT_STOC_HELLO:376:* -SSL_F_TLS_CONSTRUCT_STOC_KEY_EXCHANGE:377:* -SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE:456:tls_construct_stoc_key_share -SSL_F_TLS_CONSTRUCT_STOC_MAXFRAGMENTLEN:548:tls_construct_stoc_maxfragmentlen -SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG:457:tls_construct_stoc_next_proto_neg -SSL_F_TLS_CONSTRUCT_STOC_PSK:504:tls_construct_stoc_psk -SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE:458:tls_construct_stoc_renegotiate -SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME:459:tls_construct_stoc_server_name -SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET:460:tls_construct_stoc_session_ticket -SSL_F_TLS_CONSTRUCT_STOC_STATUS_REQUEST:461:tls_construct_stoc_status_request -SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS:544:\ - tls_construct_stoc_supported_groups -SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_VERSIONS:611:\ - tls_construct_stoc_supported_versions -SSL_F_TLS_CONSTRUCT_STOC_USE_SRTP:462:tls_construct_stoc_use_srtp -SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO:521:\ - tls_early_post_process_client_hello -SSL_F_TLS_FINISH_HANDSHAKE:597:tls_finish_handshake -SSL_F_TLS_GET_MESSAGE_BODY:351:tls_get_message_body -SSL_F_TLS_GET_MESSAGE_HEADER:387:tls_get_message_header -SSL_F_TLS_HANDLE_ALPN:562:tls_handle_alpn -SSL_F_TLS_HANDLE_STATUS_REQUEST:563:tls_handle_status_request -SSL_F_TLS_PARSE_CERTIFICATE_AUTHORITIES:566:tls_parse_certificate_authorities -SSL_F_TLS_PARSE_CLIENTHELLO_TLSEXT:449:* -SSL_F_TLS_PARSE_CTOS_ALPN:567:tls_parse_ctos_alpn -SSL_F_TLS_PARSE_CTOS_COOKIE:614:tls_parse_ctos_cookie -SSL_F_TLS_PARSE_CTOS_EARLY_DATA:568:tls_parse_ctos_early_data -SSL_F_TLS_PARSE_CTOS_EC_PT_FORMATS:569:tls_parse_ctos_ec_pt_formats -SSL_F_TLS_PARSE_CTOS_EMS:570:tls_parse_ctos_ems -SSL_F_TLS_PARSE_CTOS_KEY_SHARE:463:tls_parse_ctos_key_share -SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN:571:tls_parse_ctos_maxfragmentlen -SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH:620:tls_parse_ctos_post_handshake_auth -SSL_F_TLS_PARSE_CTOS_PSK:505:tls_parse_ctos_psk -SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES:572:tls_parse_ctos_psk_kex_modes -SSL_F_TLS_PARSE_CTOS_RENEGOTIATE:464:tls_parse_ctos_renegotiate -SSL_F_TLS_PARSE_CTOS_SERVER_NAME:573:tls_parse_ctos_server_name -SSL_F_TLS_PARSE_CTOS_SESSION_TICKET:574:tls_parse_ctos_session_ticket -SSL_F_TLS_PARSE_CTOS_SIG_ALGS:575:tls_parse_ctos_sig_algs -SSL_F_TLS_PARSE_CTOS_SIG_ALGS_CERT:615:tls_parse_ctos_sig_algs_cert -SSL_F_TLS_PARSE_CTOS_SRP:576:tls_parse_ctos_srp -SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST:577:tls_parse_ctos_status_request -SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS:578:tls_parse_ctos_supported_groups -SSL_F_TLS_PARSE_CTOS_USE_SRTP:465:tls_parse_ctos_use_srtp -SSL_F_TLS_PARSE_STOC_ALPN:579:tls_parse_stoc_alpn -SSL_F_TLS_PARSE_STOC_COOKIE:534:tls_parse_stoc_cookie -SSL_F_TLS_PARSE_STOC_EARLY_DATA:538:tls_parse_stoc_early_data -SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO:528:* -SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS:580:tls_parse_stoc_ec_pt_formats -SSL_F_TLS_PARSE_STOC_KEY_SHARE:445:tls_parse_stoc_key_share -SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN:581:tls_parse_stoc_maxfragmentlen -SSL_F_TLS_PARSE_STOC_NPN:582:tls_parse_stoc_npn -SSL_F_TLS_PARSE_STOC_PSK:502:tls_parse_stoc_psk -SSL_F_TLS_PARSE_STOC_RENEGOTIATE:448:tls_parse_stoc_renegotiate -SSL_F_TLS_PARSE_STOC_SCT:564:tls_parse_stoc_sct -SSL_F_TLS_PARSE_STOC_SERVER_NAME:583:tls_parse_stoc_server_name -SSL_F_TLS_PARSE_STOC_SESSION_TICKET:584:tls_parse_stoc_session_ticket -SSL_F_TLS_PARSE_STOC_STATUS_REQUEST:585:tls_parse_stoc_status_request -SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS:612:tls_parse_stoc_supported_versions -SSL_F_TLS_PARSE_STOC_USE_SRTP:446:tls_parse_stoc_use_srtp -SSL_F_TLS_POST_PROCESS_CLIENT_HELLO:378:tls_post_process_client_hello -SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE:384:\ - tls_post_process_client_key_exchange -SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE:360:tls_prepare_client_certificate -SSL_F_TLS_PROCESS_AS_HELLO_RETRY_REQUEST:610:tls_process_as_hello_retry_request -SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST:361:tls_process_certificate_request -SSL_F_TLS_PROCESS_CERT_STATUS:362:* -SSL_F_TLS_PROCESS_CERT_STATUS_BODY:495:tls_process_cert_status_body -SSL_F_TLS_PROCESS_CERT_VERIFY:379:tls_process_cert_verify -SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC:363:tls_process_change_cipher_spec -SSL_F_TLS_PROCESS_CKE_DHE:411:tls_process_cke_dhe -SSL_F_TLS_PROCESS_CKE_ECDHE:412:tls_process_cke_ecdhe -SSL_F_TLS_PROCESS_CKE_GOST:413:tls_process_cke_gost -SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE:414:tls_process_cke_psk_preamble -SSL_F_TLS_PROCESS_CKE_RSA:415:tls_process_cke_rsa -SSL_F_TLS_PROCESS_CKE_SRP:416:tls_process_cke_srp -SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE:380:tls_process_client_certificate -SSL_F_TLS_PROCESS_CLIENT_HELLO:381:tls_process_client_hello -SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE:382:tls_process_client_key_exchange -SSL_F_TLS_PROCESS_ENCRYPTED_EXTENSIONS:444:tls_process_encrypted_extensions -SSL_F_TLS_PROCESS_END_OF_EARLY_DATA:537:tls_process_end_of_early_data -SSL_F_TLS_PROCESS_FINISHED:364:tls_process_finished -SSL_F_TLS_PROCESS_HELLO_REQ:507:tls_process_hello_req -SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST:511:tls_process_hello_retry_request -SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT:442:tls_process_initial_server_flight -SSL_F_TLS_PROCESS_KEY_EXCHANGE:365:tls_process_key_exchange -SSL_F_TLS_PROCESS_KEY_UPDATE:518:tls_process_key_update -SSL_F_TLS_PROCESS_NEW_SESSION_TICKET:366:tls_process_new_session_ticket -SSL_F_TLS_PROCESS_NEXT_PROTO:383:tls_process_next_proto -SSL_F_TLS_PROCESS_SERVER_CERTIFICATE:367:tls_process_server_certificate -SSL_F_TLS_PROCESS_SERVER_DONE:368:tls_process_server_done -SSL_F_TLS_PROCESS_SERVER_HELLO:369:tls_process_server_hello -SSL_F_TLS_PROCESS_SKE_DHE:419:tls_process_ske_dhe -SSL_F_TLS_PROCESS_SKE_ECDHE:420:tls_process_ske_ecdhe -SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE:421:tls_process_ske_psk_preamble -SSL_F_TLS_PROCESS_SKE_SRP:422:tls_process_ske_srp -SSL_F_TLS_PSK_DO_BINDER:506:tls_psk_do_binder -SSL_F_TLS_SCAN_CLIENTHELLO_TLSEXT:450:* -SSL_F_TLS_SETUP_HANDSHAKE:508:tls_setup_handshake -SSL_F_USE_CERTIFICATE_CHAIN_FILE:220:use_certificate_chain_file -SSL_F_WPACKET_INTERN_INIT_LEN:633:wpacket_intern_init_len -SSL_F_WPACKET_START_SUB_PACKET_LEN__:634:WPACKET_start_sub_packet_len__ -SSL_F_WRITE_STATE_MACHINE:586:write_state_machine -TS_F_DEF_SERIAL_CB:110:def_serial_cb -TS_F_DEF_TIME_CB:111:def_time_cb -TS_F_ESS_ADD_SIGNING_CERT:112:ess_add_signing_cert -TS_F_ESS_ADD_SIGNING_CERT_V2:147:ess_add_signing_cert_v2 -TS_F_ESS_CERT_ID_NEW_INIT:113:ess_CERT_ID_new_init -TS_F_ESS_CERT_ID_V2_NEW_INIT:156:ess_cert_id_v2_new_init -TS_F_ESS_SIGNING_CERT_NEW_INIT:114:ess_SIGNING_CERT_new_init -TS_F_ESS_SIGNING_CERT_V2_NEW_INIT:157:ess_signing_cert_v2_new_init -TS_F_INT_TS_RESP_VERIFY_TOKEN:149:int_ts_RESP_verify_token -TS_F_PKCS7_TO_TS_TST_INFO:148:PKCS7_to_TS_TST_INFO -TS_F_TS_ACCURACY_SET_MICROS:115:TS_ACCURACY_set_micros -TS_F_TS_ACCURACY_SET_MILLIS:116:TS_ACCURACY_set_millis -TS_F_TS_ACCURACY_SET_SECONDS:117:TS_ACCURACY_set_seconds -TS_F_TS_CHECK_IMPRINTS:100:ts_check_imprints -TS_F_TS_CHECK_NONCES:101:ts_check_nonces -TS_F_TS_CHECK_POLICY:102:ts_check_policy -TS_F_TS_CHECK_SIGNING_CERTS:103:ts_check_signing_certs -TS_F_TS_CHECK_STATUS_INFO:104:ts_check_status_info -TS_F_TS_COMPUTE_IMPRINT:145:ts_compute_imprint -TS_F_TS_CONF_INVALID:151:ts_CONF_invalid -TS_F_TS_CONF_LOAD_CERT:153:TS_CONF_load_cert -TS_F_TS_CONF_LOAD_CERTS:154:TS_CONF_load_certs -TS_F_TS_CONF_LOAD_KEY:155:TS_CONF_load_key -TS_F_TS_CONF_LOOKUP_FAIL:152:ts_CONF_lookup_fail -TS_F_TS_CONF_SET_DEFAULT_ENGINE:146:TS_CONF_set_default_engine -TS_F_TS_GET_STATUS_TEXT:105:ts_get_status_text -TS_F_TS_MSG_IMPRINT_SET_ALGO:118:TS_MSG_IMPRINT_set_algo -TS_F_TS_REQ_SET_MSG_IMPRINT:119:TS_REQ_set_msg_imprint -TS_F_TS_REQ_SET_NONCE:120:TS_REQ_set_nonce -TS_F_TS_REQ_SET_POLICY_ID:121:TS_REQ_set_policy_id -TS_F_TS_RESP_CREATE_RESPONSE:122:TS_RESP_create_response -TS_F_TS_RESP_CREATE_TST_INFO:123:ts_RESP_create_tst_info -TS_F_TS_RESP_CTX_ADD_FAILURE_INFO:124:TS_RESP_CTX_add_failure_info -TS_F_TS_RESP_CTX_ADD_MD:125:TS_RESP_CTX_add_md -TS_F_TS_RESP_CTX_ADD_POLICY:126:TS_RESP_CTX_add_policy -TS_F_TS_RESP_CTX_NEW:127:TS_RESP_CTX_new -TS_F_TS_RESP_CTX_SET_ACCURACY:128:TS_RESP_CTX_set_accuracy -TS_F_TS_RESP_CTX_SET_CERTS:129:TS_RESP_CTX_set_certs -TS_F_TS_RESP_CTX_SET_DEF_POLICY:130:TS_RESP_CTX_set_def_policy -TS_F_TS_RESP_CTX_SET_SIGNER_CERT:131:TS_RESP_CTX_set_signer_cert -TS_F_TS_RESP_CTX_SET_STATUS_INFO:132:TS_RESP_CTX_set_status_info -TS_F_TS_RESP_GET_POLICY:133:ts_RESP_get_policy -TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION:134:TS_RESP_set_genTime_with_precision -TS_F_TS_RESP_SET_STATUS_INFO:135:TS_RESP_set_status_info -TS_F_TS_RESP_SET_TST_INFO:150:TS_RESP_set_tst_info -TS_F_TS_RESP_SIGN:136:ts_RESP_sign -TS_F_TS_RESP_VERIFY_SIGNATURE:106:TS_RESP_verify_signature -TS_F_TS_TST_INFO_SET_ACCURACY:137:TS_TST_INFO_set_accuracy -TS_F_TS_TST_INFO_SET_MSG_IMPRINT:138:TS_TST_INFO_set_msg_imprint -TS_F_TS_TST_INFO_SET_NONCE:139:TS_TST_INFO_set_nonce -TS_F_TS_TST_INFO_SET_POLICY_ID:140:TS_TST_INFO_set_policy_id -TS_F_TS_TST_INFO_SET_SERIAL:141:TS_TST_INFO_set_serial -TS_F_TS_TST_INFO_SET_TIME:142:TS_TST_INFO_set_time -TS_F_TS_TST_INFO_SET_TSA:143:TS_TST_INFO_set_tsa -TS_F_TS_VERIFY:108:* -TS_F_TS_VERIFY_CERT:109:ts_verify_cert -TS_F_TS_VERIFY_CTX_NEW:144:TS_VERIFY_CTX_new -UI_F_CLOSE_CONSOLE:115:close_console -UI_F_ECHO_CONSOLE:116:echo_console -UI_F_GENERAL_ALLOCATE_BOOLEAN:108:general_allocate_boolean -UI_F_GENERAL_ALLOCATE_PROMPT:109:general_allocate_prompt -UI_F_NOECHO_CONSOLE:117:noecho_console -UI_F_OPEN_CONSOLE:114:open_console -UI_F_UI_CONSTRUCT_PROMPT:121:UI_construct_prompt -UI_F_UI_CREATE_METHOD:112:UI_create_method -UI_F_UI_CTRL:111:UI_ctrl -UI_F_UI_DUP_ERROR_STRING:101:UI_dup_error_string -UI_F_UI_DUP_INFO_STRING:102:UI_dup_info_string -UI_F_UI_DUP_INPUT_BOOLEAN:110:UI_dup_input_boolean -UI_F_UI_DUP_INPUT_STRING:103:UI_dup_input_string -UI_F_UI_DUP_USER_DATA:118:UI_dup_user_data -UI_F_UI_DUP_VERIFY_STRING:106:UI_dup_verify_string -UI_F_UI_GET0_RESULT:107:UI_get0_result -UI_F_UI_GET_RESULT_LENGTH:119:UI_get_result_length -UI_F_UI_NEW_METHOD:104:UI_new_method -UI_F_UI_PROCESS:113:UI_process -UI_F_UI_SET_RESULT:105:UI_set_result -UI_F_UI_SET_RESULT_EX:120:UI_set_result_ex -X509V3_F_A2I_GENERAL_NAME:164:a2i_GENERAL_NAME -X509V3_F_ADDR_VALIDATE_PATH_INTERNAL:166:addr_validate_path_internal -X509V3_F_ASIDENTIFIERCHOICE_CANONIZE:161:ASIdentifierChoice_canonize -X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL:162:ASIdentifierChoice_is_canonical -X509V3_F_BIGNUM_TO_STRING:167:bignum_to_string -X509V3_F_COPY_EMAIL:122:copy_email -X509V3_F_COPY_ISSUER:123:copy_issuer -X509V3_F_DO_DIRNAME:144:do_dirname -X509V3_F_DO_EXT_I2D:135:do_ext_i2d -X509V3_F_DO_EXT_NCONF:151:do_ext_nconf -X509V3_F_GNAMES_FROM_SECTNAME:156:gnames_from_sectname -X509V3_F_I2S_ASN1_ENUMERATED:121:i2s_ASN1_ENUMERATED -X509V3_F_I2S_ASN1_IA5STRING:149:i2s_ASN1_IA5STRING -X509V3_F_I2S_ASN1_INTEGER:120:i2s_ASN1_INTEGER -X509V3_F_I2V_AUTHORITY_INFO_ACCESS:138:i2v_AUTHORITY_INFO_ACCESS -X509V3_F_I2V_AUTHORITY_KEYID:173:i2v_AUTHORITY_KEYID -X509V3_F_LEVEL_ADD_NODE:168:level_add_node -X509V3_F_NOTICE_SECTION:132:notice_section -X509V3_F_NREF_NOS:133:nref_nos -X509V3_F_POLICY_CACHE_CREATE:169:policy_cache_create -X509V3_F_POLICY_CACHE_NEW:170:policy_cache_new -X509V3_F_POLICY_DATA_NEW:171:policy_data_new -X509V3_F_POLICY_SECTION:131:policy_section -X509V3_F_PROCESS_PCI_VALUE:150:process_pci_value -X509V3_F_R2I_CERTPOL:130:r2i_certpol -X509V3_F_R2I_PCI:155:r2i_pci -X509V3_F_S2I_ASN1_IA5STRING:100:s2i_ASN1_IA5STRING -X509V3_F_S2I_ASN1_INTEGER:108:s2i_ASN1_INTEGER -X509V3_F_S2I_ASN1_OCTET_STRING:112:s2i_ASN1_OCTET_STRING -X509V3_F_S2I_SKEY_ID:115:s2i_skey_id -X509V3_F_SET_DIST_POINT_NAME:158:set_dist_point_name -X509V3_F_SXNET_ADD_ID_ASC:125:SXNET_add_id_asc -X509V3_F_SXNET_ADD_ID_INTEGER:126:SXNET_add_id_INTEGER -X509V3_F_SXNET_ADD_ID_ULONG:127:SXNET_add_id_ulong -X509V3_F_SXNET_GET_ID_ASC:128:SXNET_get_id_asc -X509V3_F_SXNET_GET_ID_ULONG:129:SXNET_get_id_ulong -X509V3_F_TREE_INIT:172:tree_init -X509V3_F_V2I_ASIDENTIFIERS:163:v2i_ASIdentifiers -X509V3_F_V2I_ASN1_BIT_STRING:101:v2i_ASN1_BIT_STRING -X509V3_F_V2I_AUTHORITY_INFO_ACCESS:139:v2i_AUTHORITY_INFO_ACCESS -X509V3_F_V2I_AUTHORITY_KEYID:119:v2i_AUTHORITY_KEYID -X509V3_F_V2I_BASIC_CONSTRAINTS:102:v2i_BASIC_CONSTRAINTS -X509V3_F_V2I_CRLD:134:v2i_crld -X509V3_F_V2I_EXTENDED_KEY_USAGE:103:v2i_EXTENDED_KEY_USAGE -X509V3_F_V2I_GENERAL_NAMES:118:v2i_GENERAL_NAMES -X509V3_F_V2I_GENERAL_NAME_EX:117:v2i_GENERAL_NAME_ex -X509V3_F_V2I_IDP:157:v2i_idp -X509V3_F_V2I_IPADDRBLOCKS:159:v2i_IPAddrBlocks -X509V3_F_V2I_ISSUER_ALT:153:v2i_issuer_alt -X509V3_F_V2I_NAME_CONSTRAINTS:147:v2i_NAME_CONSTRAINTS -X509V3_F_V2I_POLICY_CONSTRAINTS:146:v2i_POLICY_CONSTRAINTS -X509V3_F_V2I_POLICY_MAPPINGS:145:v2i_POLICY_MAPPINGS -X509V3_F_V2I_SUBJECT_ALT:154:v2i_subject_alt -X509V3_F_V2I_TLS_FEATURE:165:v2i_TLS_FEATURE -X509V3_F_V3_GENERIC_EXTENSION:116:v3_generic_extension -X509V3_F_X509V3_ADD1_I2D:140:X509V3_add1_i2d -X509V3_F_X509V3_ADD_LEN_VALUE:174:x509v3_add_len_value -X509V3_F_X509V3_ADD_VALUE:105:X509V3_add_value -X509V3_F_X509V3_EXT_ADD:104:X509V3_EXT_add -X509V3_F_X509V3_EXT_ADD_ALIAS:106:X509V3_EXT_add_alias -X509V3_F_X509V3_EXT_I2D:136:X509V3_EXT_i2d -X509V3_F_X509V3_EXT_NCONF:152:X509V3_EXT_nconf -X509V3_F_X509V3_GET_SECTION:142:X509V3_get_section -X509V3_F_X509V3_GET_STRING:143:X509V3_get_string -X509V3_F_X509V3_GET_VALUE_BOOL:110:X509V3_get_value_bool -X509V3_F_X509V3_PARSE_LIST:109:X509V3_parse_list -X509V3_F_X509_PURPOSE_ADD:137:X509_PURPOSE_add -X509V3_F_X509_PURPOSE_SET:141:X509_PURPOSE_set -X509_F_ADD_CERT_DIR:100:add_cert_dir -X509_F_BUILD_CHAIN:106:build_chain -X509_F_BY_FILE_CTRL:101:by_file_ctrl -X509_F_CHECK_NAME_CONSTRAINTS:149:check_name_constraints -X509_F_CHECK_POLICY:145:check_policy -X509_F_DANE_I2D:107:dane_i2d -X509_F_DIR_CTRL:102:dir_ctrl -X509_F_GET_CERT_BY_SUBJECT:103:get_cert_by_subject -X509_F_I2D_X509_AUX:151:i2d_X509_AUX -X509_F_LOOKUP_CERTS_SK:152:lookup_certs_sk -X509_F_NETSCAPE_SPKI_B64_DECODE:129:NETSCAPE_SPKI_b64_decode -X509_F_NETSCAPE_SPKI_B64_ENCODE:130:NETSCAPE_SPKI_b64_encode -X509_F_NEW_DIR:153:new_dir -X509_F_X509AT_ADD1_ATTR:135:X509at_add1_attr -X509_F_X509V3_ADD_EXT:104:X509v3_add_ext -X509_F_X509_ATTRIBUTE_CREATE_BY_NID:136:X509_ATTRIBUTE_create_by_NID -X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ:137:X509_ATTRIBUTE_create_by_OBJ -X509_F_X509_ATTRIBUTE_CREATE_BY_TXT:140:X509_ATTRIBUTE_create_by_txt -X509_F_X509_ATTRIBUTE_GET0_DATA:139:X509_ATTRIBUTE_get0_data -X509_F_X509_ATTRIBUTE_SET1_DATA:138:X509_ATTRIBUTE_set1_data -X509_F_X509_CHECK_PRIVATE_KEY:128:X509_check_private_key -X509_F_X509_CRL_DIFF:105:X509_CRL_diff -X509_F_X509_CRL_METHOD_NEW:154:X509_CRL_METHOD_new -X509_F_X509_CRL_PRINT_FP:147:X509_CRL_print_fp -X509_F_X509_EXTENSION_CREATE_BY_NID:108:X509_EXTENSION_create_by_NID -X509_F_X509_EXTENSION_CREATE_BY_OBJ:109:X509_EXTENSION_create_by_OBJ -X509_F_X509_GET_PUBKEY_PARAMETERS:110:X509_get_pubkey_parameters -X509_F_X509_LOAD_CERT_CRL_FILE:132:X509_load_cert_crl_file -X509_F_X509_LOAD_CERT_FILE:111:X509_load_cert_file -X509_F_X509_LOAD_CRL_FILE:112:X509_load_crl_file -X509_F_X509_LOOKUP_METH_NEW:160:X509_LOOKUP_meth_new -X509_F_X509_LOOKUP_NEW:155:X509_LOOKUP_new -X509_F_X509_NAME_ADD_ENTRY:113:X509_NAME_add_entry -X509_F_X509_NAME_CANON:156:x509_name_canon -X509_F_X509_NAME_ENTRY_CREATE_BY_NID:114:X509_NAME_ENTRY_create_by_NID -X509_F_X509_NAME_ENTRY_CREATE_BY_TXT:131:X509_NAME_ENTRY_create_by_txt -X509_F_X509_NAME_ENTRY_SET_OBJECT:115:X509_NAME_ENTRY_set_object -X509_F_X509_NAME_ONELINE:116:X509_NAME_oneline -X509_F_X509_NAME_PRINT:117:X509_NAME_print -X509_F_X509_OBJECT_NEW:150:X509_OBJECT_new -X509_F_X509_PRINT_EX_FP:118:X509_print_ex_fp -X509_F_X509_PUBKEY_DECODE:148:x509_pubkey_decode -X509_F_X509_PUBKEY_GET:161:X509_PUBKEY_get -X509_F_X509_PUBKEY_GET0:119:X509_PUBKEY_get0 -X509_F_X509_PUBKEY_SET:120:X509_PUBKEY_set -X509_F_X509_REQ_CHECK_PRIVATE_KEY:144:X509_REQ_check_private_key -X509_F_X509_REQ_PRINT_EX:121:X509_REQ_print_ex -X509_F_X509_REQ_PRINT_FP:122:X509_REQ_print_fp -X509_F_X509_REQ_TO_X509:123:X509_REQ_to_X509 -X509_F_X509_STORE_ADD_CERT:124:X509_STORE_add_cert -X509_F_X509_STORE_ADD_CRL:125:X509_STORE_add_crl -X509_F_X509_STORE_ADD_LOOKUP:157:X509_STORE_add_lookup -X509_F_X509_STORE_CTX_GET1_ISSUER:146:X509_STORE_CTX_get1_issuer -X509_F_X509_STORE_CTX_INIT:143:X509_STORE_CTX_init -X509_F_X509_STORE_CTX_NEW:142:X509_STORE_CTX_new -X509_F_X509_STORE_CTX_PURPOSE_INHERIT:134:X509_STORE_CTX_purpose_inherit -X509_F_X509_STORE_NEW:158:X509_STORE_new -X509_F_X509_TO_X509_REQ:126:X509_to_X509_REQ -X509_F_X509_TRUST_ADD:133:X509_TRUST_add -X509_F_X509_TRUST_SET:141:X509_TRUST_set -X509_F_X509_VERIFY_CERT:127:X509_verify_cert -X509_F_X509_VERIFY_PARAM_NEW:159:X509_VERIFY_PARAM_new - #Reason codes ASN1_R_ADDING_OBJECT:171:adding object ASN1_R_ASN1_PARSE_ERROR:203:asn1 parse error @@ -1832,6 +66,7 @@ ASN1_R_INVALID_STRING_TABLE_VALUE:218:invalid string table value ASN1_R_INVALID_UNIVERSALSTRING_LENGTH:133:invalid universalstring length ASN1_R_INVALID_UTF8STRING:134:invalid utf8string ASN1_R_INVALID_VALUE:219:invalid value +ASN1_R_LENGTH_TOO_LONG:231:length too long ASN1_R_LIST_ERROR:188:list error ASN1_R_MIME_NO_CONTENT_TYPE:206:mime no content type ASN1_R_MIME_PARSE_ERROR:207:mime parse error @@ -1873,6 +108,7 @@ ASN1_R_TYPE_NOT_CONSTRUCTED:156:type not constructed ASN1_R_TYPE_NOT_PRIMITIVE:195:type not primitive ASN1_R_UNEXPECTED_EOC:159:unexpected eoc ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH:215:universalstring is wrong length +ASN1_R_UNKNOWN_DIGEST:229:unknown digest ASN1_R_UNKNOWN_FORMAT:160:unknown format ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM:161:unknown message digest algorithm ASN1_R_UNKNOWN_OBJECT_TYPE:162:unknown object type @@ -1896,6 +132,7 @@ BIO_R_AMBIGUOUS_HOST_OR_SERVICE:129:ambiguous host or service BIO_R_BAD_FOPEN_MODE:101:bad fopen mode BIO_R_BROKEN_PIPE:124:broken pipe BIO_R_CONNECT_ERROR:103:connect error +BIO_R_CONNECT_TIMEOUT:147:connect timeout BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET:107:gethostbyname addr is not af inet BIO_R_GETSOCKNAME_ERROR:132:getsockname error BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS:133:getsockname truncated address @@ -1913,7 +150,8 @@ BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED:143:\ BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED:144:no hostname or service specified BIO_R_NO_PORT_DEFINED:113:no port defined BIO_R_NO_SUCH_FILE:128:no such file -BIO_R_NULL_PARAMETER:115:null parameter +BIO_R_TRANSFER_ERROR:104:transfer error +BIO_R_TRANSFER_TIMEOUT:105:transfer timeout BIO_R_UNABLE_TO_BIND_SOCKET:117:unable to bind socket BIO_R_UNABLE_TO_CREATE_SOCKET:118:unable to create socket BIO_R_UNABLE_TO_KEEPALIVE:137:unable to keepalive @@ -1943,16 +181,109 @@ BN_R_INVALID_SHIFT:119:invalid shift BN_R_NOT_A_SQUARE:111:not a square BN_R_NOT_INITIALIZED:107:not initialized BN_R_NO_INVERSE:108:no inverse +BN_R_NO_PRIME_CANDIDATE:121:no prime candidate BN_R_NO_SOLUTION:116:no solution +BN_R_NO_SUITABLE_DIGEST:120:no suitable digest BN_R_PRIVATE_KEY_TOO_LARGE:117:private key too large 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 +CMP_R_ALGORITHM_NOT_SUPPORTED:139:algorithm not supported +CMP_R_BAD_CHECKAFTER_IN_POLLREP:167:bad checkafter in pollrep +CMP_R_BAD_REQUEST_ID:108:bad request id +CMP_R_CERTHASH_UNMATCHED:156:certhash unmatched +CMP_R_CERTID_NOT_FOUND:109:certid not found +CMP_R_CERTIFICATE_NOT_ACCEPTED:169:certificate not accepted +CMP_R_CERTIFICATE_NOT_FOUND:112:certificate not found +CMP_R_CERTREQMSG_NOT_FOUND:157:certreqmsg not found +CMP_R_CERTRESPONSE_NOT_FOUND:113:certresponse not found +CMP_R_CERT_AND_KEY_DO_NOT_MATCH:114:cert and key do not match +CMP_R_CHECKAFTER_OUT_OF_RANGE:181:checkafter out of range +CMP_R_ENCOUNTERED_KEYUPDATEWARNING:176:encountered keyupdatewarning +CMP_R_ENCOUNTERED_WAITING:162:encountered waiting +CMP_R_ERROR_CALCULATING_PROTECTION:115:error calculating protection +CMP_R_ERROR_CREATING_CERTCONF:116:error creating certconf +CMP_R_ERROR_CREATING_CERTREP:117:error creating certrep +CMP_R_ERROR_CREATING_CERTREQ:163:error creating certreq +CMP_R_ERROR_CREATING_ERROR:118:error creating error +CMP_R_ERROR_CREATING_GENM:119:error creating genm +CMP_R_ERROR_CREATING_GENP:120:error creating genp +CMP_R_ERROR_CREATING_PKICONF:122:error creating pkiconf +CMP_R_ERROR_CREATING_POLLREP:123:error creating pollrep +CMP_R_ERROR_CREATING_POLLREQ:124:error creating pollreq +CMP_R_ERROR_CREATING_RP:125:error creating rp +CMP_R_ERROR_CREATING_RR:126:error creating rr +CMP_R_ERROR_PARSING_PKISTATUS:107:error parsing pkistatus +CMP_R_ERROR_PROCESSING_MESSAGE:158:error processing message +CMP_R_ERROR_PROTECTING_MESSAGE:127:error protecting message +CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash +CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf +CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection +CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature +CMP_R_FAILED_BUILDING_OWN_CHAIN:164:failed building own chain +CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey +CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random +CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range +CMP_R_INVALID_ARGS:100:invalid args +CMP_R_INVALID_OPTION:174:invalid option +CMP_R_MISSING_CERTID:165:missing certid +CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION:130:\ + missing key input for creating protection +CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE:142:missing key usage digitalsignature +CMP_R_MISSING_P10CSR:121:missing p10csr +CMP_R_MISSING_PBM_SECRET:166:missing pbm secret +CMP_R_MISSING_PRIVATE_KEY:131:missing private key +CMP_R_MISSING_PROTECTION:143:missing protection +CMP_R_MISSING_REFERENCE_CERT:168:missing reference cert +CMP_R_MISSING_SECRET:178:missing secret +CMP_R_MISSING_SENDER_IDENTIFICATION:111:missing sender identification +CMP_R_MISSING_TRUST_ANCHOR:179:missing trust anchor +CMP_R_MISSING_TRUST_STORE:144:missing trust store +CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED:161:multiple requests not supported +CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED:170:multiple responses not supported +CMP_R_MULTIPLE_SAN_SOURCES:102:multiple san sources +CMP_R_NO_STDIO:194:no stdio +CMP_R_NO_SUITABLE_SENDER_CERT:145:no suitable sender cert +CMP_R_NULL_ARGUMENT:103:null argument +CMP_R_PKIBODY_ERROR:146:pkibody error +CMP_R_PKISTATUSINFO_NOT_FOUND:132:pkistatusinfo not found +CMP_R_POLLING_FAILED:172:polling failed +CMP_R_POTENTIALLY_INVALID_CERTIFICATE:147:potentially invalid certificate +CMP_R_RECEIVED_ERROR:180:received error +CMP_R_RECIPNONCE_UNMATCHED:148:recipnonce unmatched +CMP_R_REQUEST_NOT_ACCEPTED:149:request not accepted +CMP_R_REQUEST_REJECTED_BY_SERVER:182:request rejected by server +CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED:150:\ + sender generalname type not supported +CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG:151:srvcert does not validate msg +CMP_R_TOTAL_TIMEOUT:184:total timeout +CMP_R_TRANSACTIONID_UNMATCHED:152:transactionid unmatched +CMP_R_TRANSFER_ERROR:159:transfer error +CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody +CMP_R_UNEXPECTED_PKISTATUS:185:unexpected pkistatus +CMP_R_UNEXPECTED_PVNO:153:unexpected pvno +CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id +CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type +CMP_R_UNKNOWN_PKISTATUS:186:unknown pkistatus +CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm +CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type +CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC:154:\ + unsupported protection alg dhbasedmac +CMP_R_VALUE_TOO_LARGE:175:value too large +CMP_R_VALUE_TOO_SMALL:177:value too small +CMP_R_WRONG_ALGORITHM_OID:138:wrong algorithm oid +CMP_R_WRONG_CERTID:189:wrong certid +CMP_R_WRONG_CERTID_IN_RP:187:wrong certid in rp +CMP_R_WRONG_PBM_VALUE:155:wrong pbm value +CMP_R_WRONG_RP_COMPONENT_COUNT:188:wrong rp component count +CMP_R_WRONG_SERIAL_IN_RP:173:wrong serial in rp 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 +CMS_R_CIPHER_AEAD_SET_TAG_ERROR:184:cipher aead set tag error +CMS_R_CIPHER_GET_TAG:185:cipher get tag CMS_R_CIPHER_INITIALISATION_ERROR:101:cipher initialisation error CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR:102:\ cipher parameter initialisation error @@ -1967,15 +298,20 @@ CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA:108:content type not signed data CMS_R_CONTENT_VERIFY_ERROR:109:content verify error CMS_R_CTRL_ERROR:110:ctrl error CMS_R_CTRL_FAILURE:111:ctrl failure +CMS_R_DECODE_ERROR:187:decode error CMS_R_DECRYPT_ERROR:112:decrypt error CMS_R_ERROR_GETTING_PUBLIC_KEY:113:error getting public key CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE:114:\ error reading messagedigest attribute CMS_R_ERROR_SETTING_KEY:115:error setting key CMS_R_ERROR_SETTING_RECIPIENTINFO:116:error setting recipientinfo +CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR:183:ess signing certid mismatch error CMS_R_INVALID_ENCRYPTED_KEY_LENGTH:117:invalid encrypted key length CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER:176:invalid key encryption parameter CMS_R_INVALID_KEY_LENGTH:118:invalid key length +CMS_R_INVALID_LABEL:190:invalid label +CMS_R_INVALID_OAEP_PARAMETERS:191:invalid oaep parameters +CMS_R_KDF_PARAMETER_ERROR:186:kdf parameter error CMS_R_MD_BIO_INIT_ERROR:119:md bio init error CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH:120:\ messagedigest attribute wrong length @@ -2007,10 +343,12 @@ CMS_R_NO_PRIVATE_KEY:133:no private key CMS_R_NO_PUBLIC_KEY:134:no public key CMS_R_NO_RECEIPT_REQUEST:168:no receipt request CMS_R_NO_SIGNERS:135:no signers +CMS_R_PEER_KEY_ERROR:188:peer key error CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE:136:\ private key does not match certificate CMS_R_RECEIPT_DECODE_ERROR:169:receipt decode error CMS_R_RECIPIENT_ERROR:137:recipient error +CMS_R_SHARED_INFO_ERROR:189:shared info error CMS_R_SIGNER_CERTIFICATE_NOT_FOUND:138:signer certificate not found CMS_R_SIGNFINAL_ERROR:139:signfinal error CMS_R_SMIME_TEXT_ERROR:140:smime text error @@ -2028,9 +366,11 @@ CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM:151:unsupported compression algorithm CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM:194:\ unsupported content encryption algorithm CMS_R_UNSUPPORTED_CONTENT_TYPE:152:unsupported content type +CMS_R_UNSUPPORTED_ENCRYPTION_TYPE:192:unsupported encryption type CMS_R_UNSUPPORTED_KEK_ALGORITHM:153:unsupported kek algorithm CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM:179:\ unsupported key encryption algorithm +CMS_R_UNSUPPORTED_LABEL_SOURCE:193:unsupported label source CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE:155:unsupported recipientinfo type CMS_R_UNSUPPORTED_RECIPIENT_TYPE:154:unsupported recipient type CMS_R_UNSUPPORTED_TYPE:156:unsupported type @@ -2042,7 +382,10 @@ COMP_R_ZLIB_DEFLATE_ERROR:99:zlib deflate error COMP_R_ZLIB_INFLATE_ERROR:100:zlib inflate error COMP_R_ZLIB_NOT_SUPPORTED:101:zlib not supported CONF_R_ERROR_LOADING_DSO:110:error loading dso +CONF_R_INVALID_PRAGMA:122:invalid pragma CONF_R_LIST_CANNOT_BE_NULL:115:list cannot be null +CONF_R_MANDATORY_BRACES_IN_VARIABLE_EXPANSION:123:\ + mandatory braces in variable expansion CONF_R_MISSING_CLOSE_SQUARE_BRACKET:100:missing close square bracket CONF_R_MISSING_EQUAL_SIGN:101:missing equal sign CONF_R_MISSING_INIT_FUNCTION:112:missing init function @@ -2054,7 +397,10 @@ CONF_R_NO_SECTION:107:no section CONF_R_NO_SUCH_FILE:114:no such file CONF_R_NO_VALUE:108:no value CONF_R_NUMBER_TOO_LARGE:121:number too large +CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION:124:\ + openssl conf references missing section CONF_R_RECURSIVE_DIRECTORY_INCLUDE:111:recursive directory include +CONF_R_RELATIVE_PATH:125:relative path CONF_R_SSL_COMMAND_SECTION_EMPTY:117:ssl command section empty CONF_R_SSL_COMMAND_SECTION_NOT_FOUND:118:ssl command section not found CONF_R_SSL_SECTION_EMPTY:119:ssl section empty @@ -2063,9 +409,50 @@ CONF_R_UNABLE_TO_CREATE_NEW_SECTION:103:unable to create new section CONF_R_UNKNOWN_MODULE_NAME:113:unknown module name CONF_R_VARIABLE_EXPANSION_TOO_LONG:116:variable expansion too long CONF_R_VARIABLE_HAS_NO_VALUE:104:variable has no value -CRYPTO_R_FIPS_MODE_NOT_SUPPORTED:101:fips mode not supported +CRMF_R_BAD_PBM_ITERATIONCOUNT:100:bad pbm iterationcount +CRMF_R_CRMFERROR:102:crmferror +CRMF_R_ERROR:103:error +CRMF_R_ERROR_DECODING_CERTIFICATE:104:error decoding certificate +CRMF_R_ERROR_DECRYPTING_CERTIFICATE:105:error decrypting certificate +CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY:106:error decrypting symmetric key +CRMF_R_FAILURE_OBTAINING_RANDOM:107:failure obtaining random +CRMF_R_ITERATIONCOUNT_BELOW_100:108:iterationcount below 100 +CRMF_R_MALFORMED_IV:101:malformed iv +CRMF_R_NULL_ARGUMENT:109:null argument +CRMF_R_POPOSKINPUT_NOT_SUPPORTED:113:poposkinput not supported +CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY:117:popo inconsistent public key +CRMF_R_POPO_MISSING:121:popo missing +CRMF_R_POPO_MISSING_PUBLIC_KEY:118:popo missing public key +CRMF_R_POPO_MISSING_SUBJECT:119:popo missing subject +CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED:120:popo raverified not accepted +CRMF_R_SETTING_MAC_ALGOR_FAILURE:110:setting mac algor failure +CRMF_R_SETTING_OWF_ALGOR_FAILURE:111:setting owf algor failure +CRMF_R_UNSUPPORTED_ALGORITHM:112:unsupported algorithm +CRMF_R_UNSUPPORTED_CIPHER:114:unsupported cipher +CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO:115:\ + unsupported method for creating popo +CRMF_R_UNSUPPORTED_POPO_METHOD:116:unsupported popo method +CRYPTO_R_BAD_ALGORITHM_NAME:117:bad algorithm name +CRYPTO_R_CONFLICTING_NAMES:118:conflicting names +CRYPTO_R_HEX_STRING_TOO_SHORT:121:hex string too short CRYPTO_R_ILLEGAL_HEX_DIGIT:102:illegal hex digit +CRYPTO_R_INSUFFICIENT_DATA_SPACE:106:insufficient data space +CRYPTO_R_INSUFFICIENT_PARAM_SIZE:107:insufficient param size +CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE:108:insufficient secure data space +CRYPTO_R_INVALID_NEGATIVE_VALUE:122:invalid negative value +CRYPTO_R_INVALID_NULL_ARGUMENT:109:invalid null argument +CRYPTO_R_INVALID_OSSL_PARAM_TYPE:110:invalid ossl param type CRYPTO_R_ODD_NUMBER_OF_DIGITS:103:odd number of digits +CRYPTO_R_PROVIDER_ALREADY_EXISTS:104:provider already exists +CRYPTO_R_PROVIDER_SECTION_ERROR:105:provider section error +CRYPTO_R_RANDOM_SECTION_ERROR:119:random section error +CRYPTO_R_SECURE_MALLOC_FAILURE:111:secure malloc failure +CRYPTO_R_STRING_TOO_LONG:112:string too long +CRYPTO_R_TOO_MANY_BYTES:113:too many bytes +CRYPTO_R_TOO_MANY_RECORDS:114:too many records +CRYPTO_R_TOO_SMALL_BUFFER:116:too small buffer +CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION:120:unknown name in random section +CRYPTO_R_ZERO_LENGTH_NUMBER:115:zero length number CT_R_BASE64_DECODE_ERROR:108:base64 decode error CT_R_INVALID_LOG_ID_LENGTH:100:invalid log id length CT_R_LOG_CONF_INVALID:109:log conf invalid @@ -2083,6 +470,7 @@ CT_R_SCT_UNSUPPORTED_VERSION:115:sct unsupported version CT_R_UNRECOGNIZED_SIGNATURE_NID:101:unrecognized signature nid CT_R_UNSUPPORTED_ENTRY_TYPE:102:unsupported entry type CT_R_UNSUPPORTED_VERSION:103:unsupported version +DH_R_BAD_FFC_PARAMETERS:127:bad ffc parameters DH_R_BAD_GENERATOR:101:bad generator DH_R_BN_DECODE_ERROR:109:bn decode error DH_R_BN_ERROR:106:bn error @@ -2098,10 +486,12 @@ DH_R_DECODE_ERROR:104:decode error DH_R_INVALID_PARAMETER_NAME:110:invalid parameter name DH_R_INVALID_PARAMETER_NID:114:invalid parameter nid DH_R_INVALID_PUBKEY:102:invalid public key +DH_R_INVALID_SECRET:128:invalid secret DH_R_KDF_PARAMETER_ERROR:112:kdf parameter error DH_R_KEYS_NOT_SET:108:keys not set DH_R_MISSING_PUBKEY:125:missing pubkey DH_R_MODULUS_TOO_LARGE:103:modulus too large +DH_R_MODULUS_TOO_SMALL:126:modulus too small DH_R_NOT_SUITABLE_GENERATOR:120:not suitable generator DH_R_NO_PARAMETERS_SET:107:no parameters set DH_R_NO_PRIVATE_VALUE:100:no private value @@ -2109,6 +499,7 @@ DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error DH_R_PEER_KEY_ERROR:111:peer key error DH_R_SHARED_INFO_ERROR:113:shared info error DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator +DSA_R_BAD_FFC_PARAMETERS:114:bad ffc parameters DSA_R_BAD_Q_VALUE:102:bad q value DSA_R_BN_DECODE_ERROR:108:bn decode error DSA_R_BN_ERROR:109:bn error @@ -2120,6 +511,7 @@ 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 +DSA_R_P_NOT_PRIME:115:p not prime DSA_R_Q_NOT_PRIME:113:q not prime DSA_R_SEED_LEN_SMALL:110:seed_len is less than the length of q DSO_R_CTRL_FAILED:100:control command failed @@ -2145,17 +537,22 @@ EC_R_BUFFER_TOO_SMALL:100:buffer too small EC_R_CANNOT_INVERT:165:cannot invert EC_R_COORDINATES_OUT_OF_RANGE:146:coordinates out of range EC_R_CURVE_DOES_NOT_SUPPORT_ECDH:160:curve does not support ecdh +EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA:170:curve does not support ecdsa EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING:159:curve does not support signing -EC_R_D2I_ECPKPARAMETERS_FAILURE:117:d2i ecpkparameters failure EC_R_DECODE_ERROR:142:decode error EC_R_DISCRIMINANT_IS_ZERO:118:discriminant is zero EC_R_EC_GROUP_NEW_BY_NAME_FAILURE:119:ec group new by name failure +EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED:127:explicit params not supported +EC_R_FAILED_MAKING_PUBLIC_KEY:166:failed making public key EC_R_FIELD_TOO_LARGE:143:field too large EC_R_GF2M_NOT_SUPPORTED:147:gf2m not supported EC_R_GROUP2PKPARAMETERS_FAILURE:120:group2pkparameters failure EC_R_I2D_ECPKPARAMETERS_FAILURE:121:i2d ecpkparameters failure EC_R_INCOMPATIBLE_OBJECTS:101:incompatible objects +EC_R_INVALID_A:168:invalid a EC_R_INVALID_ARGUMENT:112:invalid argument +EC_R_INVALID_B:169:invalid b +EC_R_INVALID_COFACTOR:171:invalid cofactor EC_R_INVALID_COMPRESSED_POINT:110:invalid compressed point EC_R_INVALID_COMPRESSION_BIT:109:invalid compression bit EC_R_INVALID_CURVE:141:invalid curve @@ -2164,12 +561,17 @@ EC_R_INVALID_DIGEST_TYPE:138:invalid digest type EC_R_INVALID_ENCODING:102:invalid encoding EC_R_INVALID_FIELD:103:invalid field EC_R_INVALID_FORM:104:invalid form +EC_R_INVALID_GENERATOR:173:invalid generator EC_R_INVALID_GROUP_ORDER:122:invalid group order EC_R_INVALID_KEY:116:invalid key +EC_R_INVALID_LENGTH:117:invalid length +EC_R_INVALID_NAMED_GROUP_CONVERSION:174:invalid named group conversion EC_R_INVALID_OUTPUT_LENGTH:161:invalid output length +EC_R_INVALID_P:172:invalid p EC_R_INVALID_PEER_KEY:133:invalid peer key EC_R_INVALID_PENTANOMIAL_BASIS:132:invalid pentanomial basis EC_R_INVALID_PRIVATE_KEY:123:invalid private key +EC_R_INVALID_SEED:175:invalid seed EC_R_INVALID_TRINOMIAL_BASIS:137:invalid trinomial basis EC_R_KDF_PARAMETER_ERROR:148:kdf parameter error EC_R_KEYS_NOT_SET:140:keys not set @@ -2188,7 +590,6 @@ EC_R_NO_PRIVATE_VALUE:154:no private value EC_R_OPERATION_NOT_SUPPORTED:152:operation not supported EC_R_PASSED_NULL_PARAMETER:134:passed null parameter EC_R_PEER_KEY_ERROR:149:peer key error -EC_R_PKPARAMETERS2GROUP_FAILURE:127:pkparameters2group failure EC_R_POINT_ARITHMETIC_FAILURE:155:point arithmetic failure EC_R_POINT_AT_INFINITY:106:point at infinity EC_R_POINT_COORDINATES_BLIND_FAILURE:163:point coordinates blind failure @@ -2239,58 +640,92 @@ ENGINE_R_UNIMPLEMENTED_CIPHER:146:unimplemented cipher ENGINE_R_UNIMPLEMENTED_DIGEST:147:unimplemented digest ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD:101:unimplemented public key method ENGINE_R_VERSION_INCOMPATIBILITY:145:version incompatibility +ESS_R_EMPTY_ESS_CERT_ID_LIST:107:empty ess cert id list +ESS_R_ESS_CERT_DIGEST_ERROR:103:ess cert digest error +ESS_R_ESS_CERT_ID_NOT_FOUND:104:ess cert id not found +ESS_R_ESS_CERT_ID_WRONG_ORDER:105:ess cert id wrong order +ESS_R_ESS_DIGEST_ALG_UNKNOWN:106:ess digest alg unknown +ESS_R_ESS_SIGNING_CERTIFICATE_ERROR:102:ess signing certificate error +ESS_R_ESS_SIGNING_CERT_ADD_ERROR:100:ess signing cert add error +ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR:101:ess signing cert v2 add error +ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE:108:\ + missing signing certificate attribute 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_ALGORITHM_NAME:200:bad algorithm name 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_CACHE_CONSTANTS_FAILED:225:cache constants failed EVP_R_CAMELLIA_KEY_SETUP_FAILED:157:camellia key setup failed +EVP_R_CANNOT_GET_PARAMETERS:197:cannot get parameters +EVP_R_CANNOT_SET_PARAMETERS:198:cannot set parameters +EVP_R_CIPHER_NOT_GCM_MODE:184:cipher not gcm mode EVP_R_CIPHER_PARAMETER_ERROR:122:cipher parameter error EVP_R_COMMAND_NOT_SUPPORTED:147:command not supported +EVP_R_CONFLICTING_ALGORITHM_NAME:201:conflicting algorithm name EVP_R_COPY_ERROR:173:copy error EVP_R_CTRL_NOT_IMPLEMENTED:132:ctrl not implemented EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED:133:ctrl operation not implemented EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:138:data not multiple of block length EVP_R_DECODE_ERROR:114:decode error +EVP_R_DEFAULT_QUERY_PARSE_ERROR:210:default query parse error EVP_R_DIFFERENT_KEY_TYPES:101:different key types EVP_R_DIFFERENT_PARAMETERS:153:different parameters EVP_R_ERROR_LOADING_SECTION:165:error loading section -EVP_R_ERROR_SETTING_FIPS_MODE:166:error setting fips mode EVP_R_EXPECTING_AN_HMAC_KEY:174:expecting an hmac key EVP_R_EXPECTING_AN_RSA_KEY:127:expecting an rsa key EVP_R_EXPECTING_A_DH_KEY:128:expecting a dh key EVP_R_EXPECTING_A_DSA_KEY:129:expecting a dsa key -EVP_R_EXPECTING_A_EC_KEY:142:expecting a ec key +EVP_R_EXPECTING_A_ECX_KEY:219:expecting an ecx key +EVP_R_EXPECTING_A_EC_KEY:142:expecting an ec key EVP_R_EXPECTING_A_POLY1305_KEY:164:expecting a poly1305 key EVP_R_EXPECTING_A_SIPHASH_KEY:175:expecting a siphash key -EVP_R_FIPS_MODE_NOT_SUPPORTED:167:fips mode not supported +EVP_R_FINAL_ERROR:188:final error +EVP_R_GENERATE_ERROR:214:generate error EVP_R_GET_RAW_KEY_FAILED:182:get raw key failed EVP_R_ILLEGAL_SCRYPT_PARAMETERS:171:illegal scrypt parameters +EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS:204:inaccessible domain parameters +EVP_R_INACCESSIBLE_KEY:203:inaccessible key EVP_R_INITIALIZATION_ERROR:134:initialization error EVP_R_INPUT_NOT_INITIALIZED:111:input not initialized +EVP_R_INVALID_CUSTOM_LENGTH:185:invalid custom length EVP_R_INVALID_DIGEST:152:invalid digest -EVP_R_INVALID_FIPS_MODE:168:invalid fips mode EVP_R_INVALID_IV_LENGTH:194:invalid iv length EVP_R_INVALID_KEY:163:invalid key EVP_R_INVALID_KEY_LENGTH:130:invalid key length +EVP_R_INVALID_LENGTH:221:invalid length +EVP_R_INVALID_NULL_ALGORITHM:218:invalid null algorithm EVP_R_INVALID_OPERATION:148:invalid operation -EVP_R_KEYGEN_FAILURE:120:keygen failure +EVP_R_INVALID_PROVIDER_FUNCTIONS:193:invalid provider functions +EVP_R_INVALID_SALT_LENGTH:186:invalid salt length +EVP_R_INVALID_SECRET_LENGTH:223:invalid secret length +EVP_R_INVALID_SEED_LENGTH:220:invalid seed length +EVP_R_INVALID_VALUE:222:invalid value +EVP_R_KEYMGMT_EXPORT_FAILURE:205:keymgmt export failure EVP_R_KEY_SETUP_FAILED:180:key setup failed +EVP_R_LOCKING_NOT_SUPPORTED:213:locking not supported EVP_R_MEMORY_LIMIT_EXCEEDED:172:memory limit exceeded EVP_R_MESSAGE_DIGEST_IS_NULL:159:message digest is null EVP_R_METHOD_NOT_SUPPORTED:144:method not supported EVP_R_MISSING_PARAMETERS:103:missing parameters +EVP_R_NOT_ABLE_TO_COPY_CTX:190:not able to copy ctx EVP_R_NOT_XOF_OR_INVALID_LENGTH:178:not XOF or invalid length EVP_R_NO_CIPHER_SET:131:no cipher set EVP_R_NO_DEFAULT_DIGEST:158:no default digest EVP_R_NO_DIGEST_SET:139:no digest set +EVP_R_NO_IMPORT_FUNCTION:206:no import function +EVP_R_NO_KEYMGMT_AVAILABLE:199:no keymgmt available +EVP_R_NO_KEYMGMT_PRESENT:196:no keymgmt present EVP_R_NO_KEY_SET:154:no key set EVP_R_NO_OPERATION_SET:149:no operation set +EVP_R_NULL_MAC_PKEY_CTX:208:null mac pkey ctx EVP_R_ONLY_ONESHOT_SUPPORTED:177:only oneshot supported +EVP_R_OPERATION_NOT_INITIALIZED:151:operation not initialized EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:150:\ operation not supported for this keytype -EVP_R_OPERATON_NOT_INITIALIZED:151:operaton not initialized -EVP_R_OUTPUT_WOULD_OVERFLOW:184:output would overflow +EVP_R_OUTPUT_WOULD_OVERFLOW:202:output would overflow +EVP_R_PARAMETER_TOO_LARGE:187:parameter too large EVP_R_PARTIALLY_OVERLAPPING:162:partially overlapping buffers EVP_R_PBKDF2_ERROR:181:pbkdf2 error EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED:179:\ @@ -2298,8 +733,17 @@ EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED:179:\ EVP_R_PRIVATE_KEY_DECODE_ERROR:145:private key decode error EVP_R_PRIVATE_KEY_ENCODE_ERROR:146:private key encode error EVP_R_PUBLIC_KEY_NOT_RSA:106:public key not rsa +EVP_R_SETTING_XOF_FAILED:227:setting xof failed +EVP_R_SET_DEFAULT_PROPERTY_FAILURE:209:set default property failure +EVP_R_TOO_MANY_RECORDS:183:too many records +EVP_R_UNABLE_TO_ENABLE_LOCKING:212:unable to enable locking +EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE:215:unable to get maximum request size +EVP_R_UNABLE_TO_GET_RANDOM_STRENGTH:216:unable to get random strength +EVP_R_UNABLE_TO_LOCK_CONTEXT:211:unable to lock context +EVP_R_UNABLE_TO_SET_CALLBACKS:217:unable to set callbacks EVP_R_UNKNOWN_CIPHER:160:unknown cipher EVP_R_UNKNOWN_DIGEST:161:unknown digest +EVP_R_UNKNOWN_KEY_TYPE:207:unknown key type EVP_R_UNKNOWN_OPTION:169:unknown option EVP_R_UNKNOWN_PBE_ALGORITHM:121:unknown pbe algorithm EVP_R_UNSUPPORTED_ALGORITHM:156:unsupported algorithm @@ -2308,32 +752,55 @@ EVP_R_UNSUPPORTED_KEYLENGTH:123:unsupported keylength EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION:124:\ unsupported key derivation function EVP_R_UNSUPPORTED_KEY_SIZE:108:unsupported key size +EVP_R_UNSUPPORTED_KEY_TYPE:224:unsupported key type EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS:135:unsupported number of rounds EVP_R_UNSUPPORTED_PRF:125:unsupported prf EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM:118:unsupported private key algorithm EVP_R_UNSUPPORTED_SALT_TYPE:126:unsupported salt type +EVP_R_UPDATE_ERROR:189:update error 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 -KDF_R_MISSING_MESSAGE_DIGEST:105:missing message digest -KDF_R_MISSING_PARAMETER:101:missing parameter -KDF_R_MISSING_PASS:110:missing pass -KDF_R_MISSING_SALT:111:missing salt -KDF_R_MISSING_SECRET:107:missing secret -KDF_R_MISSING_SEED:106:missing seed -KDF_R_UNKNOWN_PARAMETER_TYPE:103:unknown parameter type -KDF_R_VALUE_ERROR:108:value error -KDF_R_VALUE_MISSING:102:value missing +EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE:191:xts data unit is too large +EVP_R_XTS_DUPLICATED_KEYS:192:xts duplicated keys +HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN:108:asn1 len exceeds max resp len +HTTP_R_CONNECT_FAILURE:100:connect failure +HTTP_R_ERROR_PARSING_ASN1_LENGTH:109:error parsing asn1 length +HTTP_R_ERROR_PARSING_CONTENT_LENGTH:119:error parsing content length +HTTP_R_ERROR_PARSING_URL:101:error parsing url +HTTP_R_ERROR_RECEIVING:103:error receiving +HTTP_R_ERROR_SENDING:102:error sending +HTTP_R_FAILED_READING_DATA:128:failed reading data +HTTP_R_HEADER_PARSE_ERROR:126:header parse error +HTTP_R_INCONSISTENT_CONTENT_LENGTH:120:inconsistent content length +HTTP_R_INVALID_PORT_NUMBER:123:invalid port number +HTTP_R_INVALID_URL_PATH:125:invalid url path +HTTP_R_INVALID_URL_SCHEME:124:invalid url scheme +HTTP_R_MAX_RESP_LEN_EXCEEDED:117:max resp len exceeded +HTTP_R_MISSING_ASN1_ENCODING:110:missing asn1 encoding +HTTP_R_MISSING_CONTENT_TYPE:121:missing content type +HTTP_R_MISSING_REDIRECT_LOCATION:111:missing redirect location +HTTP_R_RECEIVED_ERROR:105:received error +HTTP_R_RECEIVED_WRONG_HTTP_VERSION:106:received wrong http version +HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP:112:redirection from https to http +HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled +HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long +HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error +HTTP_R_RETRY_TIMEOUT:129:retry timeout +HTTP_R_SERVER_CANCELED_CONNECTION:127:server canceled connection +HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported +HTTP_R_STATUS_CODE_UNSUPPORTED:114:status code unsupported +HTTP_R_TLS_NOT_ENABLED:107:tls not enabled +HTTP_R_TOO_MANY_REDIRECTIONS:115:too many redirections +HTTP_R_UNEXPECTED_CONTENT_TYPE:118:unexpected content type OBJ_R_OID_EXISTS:102:oid exists OBJ_R_UNKNOWN_NID:101:unknown nid +OBJ_R_UNKNOWN_OBJECT_NAME:103:unknown object name OCSP_R_CERTIFICATE_VERIFY_ERROR:101:certificate verify error OCSP_R_DIGEST_ERR:102:digest err +OCSP_R_DIGEST_NAME_ERR:106:digest name err +OCSP_R_DIGEST_SIZE_ERR:107:digest size err OCSP_R_ERROR_IN_NEXTUPDATE_FIELD:122:error in nextupdate field OCSP_R_ERROR_IN_THISUPDATE_FIELD:123:error in thisupdate field -OCSP_R_ERROR_PARSING_URL:121:error parsing url OCSP_R_MISSING_OCSPSIGNING_USAGE:103:missing ocspsigning usage OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE:124:nextupdate before thisupdate OCSP_R_NOT_BASIC_RESPONSE:104:not basic response @@ -2347,8 +814,6 @@ OCSP_R_REQUEST_NOT_SIGNED:128:request not signed OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA:111:\ response contains no revocation data OCSP_R_ROOT_CA_NOT_TRUSTED:112:root ca not trusted -OCSP_R_SERVER_RESPONSE_ERROR:114:server response error -OCSP_R_SERVER_RESPONSE_PARSE_ERROR:115:server response parse error OCSP_R_SIGNATURE_FAILURE:117:signature failure OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND:118:signer certificate not found OCSP_R_STATUS_EXPIRED:125:status expired @@ -2357,6 +822,12 @@ OCSP_R_STATUS_TOO_OLD:127:status too old OCSP_R_UNKNOWN_MESSAGE_DIGEST:119:unknown message digest OCSP_R_UNKNOWN_NID:120:unknown nid OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE:129:unsupported requestorname type +OSSL_DECODER_R_COULD_NOT_DECODE_OBJECT:101:could not decode object +OSSL_DECODER_R_DECODER_NOT_FOUND:102:decoder not found +OSSL_DECODER_R_MISSING_GET_PARAMS:100:missing get params +OSSL_ENCODER_R_ENCODER_NOT_FOUND:101:encoder not found +OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY:100:incorrect property query +OSSL_ENCODER_R_MISSING_GET_PARAMS:102:missing get params OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE:107:ambiguous content type OSSL_STORE_R_BAD_PASSWORD_READ:115:bad password read OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC:113:error verifying pkcs12 mac @@ -2368,9 +839,11 @@ OSSL_STORE_R_LOADER_INCOMPLETE:116:loader incomplete OSSL_STORE_R_LOADING_STARTED:117:loading started OSSL_STORE_R_NOT_A_CERTIFICATE:100:not a certificate OSSL_STORE_R_NOT_A_CRL:101:not a crl -OSSL_STORE_R_NOT_A_KEY:102:not a key OSSL_STORE_R_NOT_A_NAME:103:not a name +OSSL_STORE_R_NOT_A_PRIVATE_KEY:102:not a private key +OSSL_STORE_R_NOT_A_PUBLIC_KEY:122:not a public key OSSL_STORE_R_NOT_PARAMETERS:104:not parameters +OSSL_STORE_R_NO_LOADERS_FOUND:123:no loaders found OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR:114:passphrase callback error OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE:108:path must be absolute OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES:119:\ @@ -2392,8 +865,10 @@ PEM_R_BAD_VERSION_NUMBER:117:bad version number PEM_R_BIO_WRITE_FAILURE:118:bio write failure PEM_R_CIPHER_IS_NULL:127:cipher is null PEM_R_ERROR_CONVERTING_PRIVATE_KEY:115:error converting private key +PEM_R_EXPECTING_DSS_KEY_BLOB:131:expecting dss key blob PEM_R_EXPECTING_PRIVATE_KEY_BLOB:119:expecting private key blob PEM_R_EXPECTING_PUBLIC_KEY_BLOB:120:expecting public key blob +PEM_R_EXPECTING_RSA_KEY_BLOB:132:expecting rsa key blob PEM_R_HEADER_TOO_LONG:128:header too long PEM_R_INCONSISTENT_HEADER:121:inconsistent header PEM_R_KEYBLOB_HEADER_PARSE_ERROR:122:keyblob header parse error @@ -2421,6 +896,7 @@ PKCS12_R_ENCRYPT_ERROR:103:encrypt error PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE:120:error setting encrypted data type PKCS12_R_INVALID_NULL_ARGUMENT:104:invalid null argument PKCS12_R_INVALID_NULL_PKCS12_POINTER:105:invalid null pkcs12 pointer +PKCS12_R_INVALID_TYPE:112:invalid type PKCS12_R_IV_GEN_ERROR:106:iv gen error PKCS12_R_KEY_GEN_ERROR:107:key gen error PKCS12_R_MAC_ABSENT:108:mac absent @@ -2429,9 +905,7 @@ PKCS12_R_MAC_SETUP_ERROR:110:mac setup error PKCS12_R_MAC_STRING_SET_ERROR:111:mac string set error PKCS12_R_MAC_VERIFY_FAILURE:113:mac verify failure PKCS12_R_PARSE_ERROR:114:parse error -PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR:115:pkcs12 algor cipherinit error PKCS12_R_PKCS12_CIPHERFINAL_ERROR:116:pkcs12 cipherfinal error -PKCS12_R_PKCS12_PBE_CRYPT_ERROR:117:pkcs12 pbe crypt error PKCS12_R_UNKNOWN_DIGEST_ALGORITHM:118:unknown digest algorithm PKCS12_R_UNSUPPORTED_PKCS12_MODE:119:unsupported pkcs12 mode PKCS7_R_CERTIFICATE_VERIFY_ERROR:117:certificate verify error @@ -2476,6 +950,145 @@ PKCS7_R_UNSUPPORTED_CIPHER_TYPE:111:unsupported cipher type PKCS7_R_UNSUPPORTED_CONTENT_TYPE:112:unsupported content type PKCS7_R_WRONG_CONTENT_TYPE:113:wrong content type PKCS7_R_WRONG_PKCS7_TYPE:114:wrong pkcs7 type +PROP_R_NAME_TOO_LONG:100:name too long +PROP_R_NOT_AN_ASCII_CHARACTER:101:not an ascii character +PROP_R_NOT_AN_HEXADECIMAL_DIGIT:102:not an hexadecimal digit +PROP_R_NOT_AN_IDENTIFIER:103:not an identifier +PROP_R_NOT_AN_OCTAL_DIGIT:104:not an octal digit +PROP_R_NOT_A_DECIMAL_DIGIT:105:not a decimal digit +PROP_R_NO_MATCHING_STRING_DELIMITER:106:no matching string delimiter +PROP_R_NO_VALUE:107:no value +PROP_R_PARSE_FAILED:108:parse failed +PROP_R_STRING_TOO_LONG:109:string too long +PROP_R_TRAILING_CHARACTERS:110:trailing characters +PROV_R_ADDITIONAL_INPUT_TOO_LONG:184:additional input too long +PROV_R_ALGORITHM_MISMATCH:173:algorithm mismatch +PROV_R_ALREADY_INSTANTIATED:185:already instantiated +PROV_R_BAD_DECRYPT:100:bad decrypt +PROV_R_BAD_ENCODING:141:bad encoding +PROV_R_BAD_LENGTH:142:bad length +PROV_R_BAD_TLS_CLIENT_VERSION:161:bad tls client version +PROV_R_BN_ERROR:160:bn error +PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed +PROV_R_DERIVATION_FUNCTION_INIT_FAILED:205:derivation function init failed +PROV_R_DIGEST_NOT_ALLOWED:174:digest not allowed +PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK:186:entropy source strength too weak +PROV_R_ERROR_INSTANTIATING_DRBG:188:error instantiating drbg +PROV_R_ERROR_RETRIEVING_ENTROPY:189:error retrieving entropy +PROV_R_ERROR_RETRIEVING_NONCE:190:error retrieving nonce +PROV_R_FAILED_DURING_DERIVATION:164:failed during derivation +PROV_R_FAILED_TO_CREATE_LOCK:180:failed to create lock +PROV_R_FAILED_TO_DECRYPT:162:failed to decrypt +PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key +PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter +PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter +PROV_R_FAILED_TO_SIGN:175:failed to sign +PROV_R_FIPS_MODULE_CONDITIONAL_ERROR:227:fips module conditional error +PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE:224:fips module entering error state +PROV_R_FIPS_MODULE_IN_ERROR_STATE:225:fips module in error state +PROV_R_GENERATE_ERROR:191:generate error +PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\ + illegal or unsupported padding mode +PROV_R_INDICATOR_INTEGRITY_FAILURE:210:indicator integrity failure +PROV_R_INSUFFICIENT_DRBG_STRENGTH:181:insufficient drbg strength +PROV_R_INVALID_AAD:108:invalid aad +PROV_R_INVALID_CONFIG_DATA:211:invalid config data +PROV_R_INVALID_CONSTANT_LENGTH:157:invalid constant length +PROV_R_INVALID_CURVE:176:invalid curve +PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length +PROV_R_INVALID_DATA:115:invalid data +PROV_R_INVALID_DIGEST:122:invalid digest +PROV_R_INVALID_DIGEST_LENGTH:166:invalid digest length +PROV_R_INVALID_DIGEST_SIZE:218:invalid digest size +PROV_R_INVALID_INPUT_LENGTH:230:invalid input length +PROV_R_INVALID_ITERATION_COUNT:123:invalid iteration count +PROV_R_INVALID_IV_LENGTH:109:invalid iv length +PROV_R_INVALID_KEY:158:invalid key +PROV_R_INVALID_KEY_LENGTH:105:invalid key length +PROV_R_INVALID_MAC:151:invalid mac +PROV_R_INVALID_MGF1_MD:167:invalid mgf1 md +PROV_R_INVALID_MODE:125:invalid mode +PROV_R_INVALID_OUTPUT_LENGTH:217:invalid output length +PROV_R_INVALID_PADDING_MODE:168:invalid padding mode +PROV_R_INVALID_PUBINFO:198:invalid pubinfo +PROV_R_INVALID_SALT_LENGTH:112:invalid salt length +PROV_R_INVALID_SEED_LENGTH:154:invalid seed length +PROV_R_INVALID_SIGNATURE_SIZE:179:invalid signature size +PROV_R_INVALID_STATE:212:invalid state +PROV_R_INVALID_TAG:110:invalid tag +PROV_R_INVALID_TAG_LENGTH:118:invalid tag length +PROV_R_INVALID_UKM_LENGTH:200:invalid ukm length +PROV_R_INVALID_X931_DIGEST:170:invalid x931 digest +PROV_R_IN_ERROR_STATE:192:in error state +PROV_R_KEY_SETUP_FAILED:101:key setup failed +PROV_R_KEY_SIZE_TOO_SMALL:171:key size too small +PROV_R_LENGTH_TOO_LARGE:202:length too large +PROV_R_MISMATCHING_DOMAIN_PARAMETERS:203:mismatching domain parameters +PROV_R_MISSING_CEK_ALG:144:missing cek alg +PROV_R_MISSING_CIPHER:155:missing cipher +PROV_R_MISSING_CONFIG_DATA:213:missing config data +PROV_R_MISSING_CONSTANT:156:missing constant +PROV_R_MISSING_KEY:128:missing key +PROV_R_MISSING_MAC:150:missing mac +PROV_R_MISSING_MESSAGE_DIGEST:129:missing message digest +PROV_R_MISSING_OID:209:missing OID +PROV_R_MISSING_PASS:130:missing pass +PROV_R_MISSING_SALT:131:missing salt +PROV_R_MISSING_SECRET:132:missing secret +PROV_R_MISSING_SEED:140:missing seed +PROV_R_MISSING_SESSION_ID:133:missing session id +PROV_R_MISSING_TYPE:134:missing type +PROV_R_MISSING_XCGHASH:135:missing xcghash +PROV_R_MODULE_INTEGRITY_FAILURE:214:module integrity failure +PROV_R_NOT_A_PRIVATE_KEY:221:not a private key +PROV_R_NOT_A_PUBLIC_KEY:220:not a public key +PROV_R_NOT_INSTANTIATED:193:not instantiated +PROV_R_NOT_PARAMETERS:226:not parameters +PROV_R_NOT_SUPPORTED:136:not supported +PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length +PROV_R_NO_KEY_SET:114:no key set +PROV_R_NO_PARAMETERS_SET:177:no parameters set +PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:178:\ + operation not supported for this keytype +PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small +PROV_R_PARENT_CANNOT_GENERATE_RANDOM_NUMBERS:228:\ + parent cannot generate random numbers +PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED:187:parent cannot supply entropy seed +PROV_R_PARENT_LOCKING_NOT_ENABLED:182:parent locking not enabled +PROV_R_PARENT_STRENGTH_TOO_WEAK:194:parent strength too weak +PROV_R_PATH_MUST_BE_ABSOLUTE:219:path must be absolute +PROV_R_PERSONALISATION_STRING_TOO_LONG:195:personalisation string too long +PROV_R_PSS_SALTLEN_TOO_SMALL:172:pss saltlen too small +PROV_R_REQUEST_TOO_LARGE_FOR_DRBG:196:request too large for drbg +PROV_R_REQUIRE_CTR_MODE_CIPHER:206:require ctr mode cipher +PROV_R_RESEED_ERROR:197:reseed error +PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES:222:\ + search only supported for directories +PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT:229:\ + seed sources must not have a parent +PROV_R_SELF_TEST_KAT_FAILURE:215:self test kat failure +PROV_R_SELF_TEST_POST_FAILURE:216:self test post failure +PROV_R_TAG_NOT_NEEDED:120:tag not needed +PROV_R_TAG_NOT_SET:119:tag not set +PROV_R_TOO_MANY_RECORDS:126:too many records +PROV_R_UNABLE_TO_FIND_CIPHERS:207:unable to find ciphers +PROV_R_UNABLE_TO_GET_PARENT_STRENGTH:199:unable to get parent strength +PROV_R_UNABLE_TO_GET_PASSPHRASE:159:unable to get passphrase +PROV_R_UNABLE_TO_INITIALISE_CIPHERS:208:unable to initialise ciphers +PROV_R_UNABLE_TO_LOAD_SHA256:147:unable to load sha256 +PROV_R_UNABLE_TO_LOCK_PARENT:201:unable to lock parent +PROV_R_UNABLE_TO_RESEED:204:unable to reseed +PROV_R_UNSUPPORTED_CEK_ALG:145:unsupported cek alg +PROV_R_UNSUPPORTED_KEY_SIZE:153:unsupported key size +PROV_R_UNSUPPORTED_MAC_TYPE:137:unsupported mac type +PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS:152:unsupported number of rounds +PROV_R_URI_AUTHORITY_UNSUPPORTED:223:uri authority unsupported +PROV_R_VALUE_ERROR:138:value error +PROV_R_WRONG_FINAL_BLOCK_LENGTH:107:wrong final block length +PROV_R_WRONG_OUTPUT_BUFFER_SIZE:139:wrong output buffer size +PROV_R_XOF_DIGESTS_NOT_ALLOWED:183:xof digests not allowed +PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE:148:xts data unit is too large +PROV_R_XTS_DUPLICATED_KEYS:149:xts duplicated keys RAND_R_ADDITIONAL_INPUT_TOO_LONG:102:additional input too long RAND_R_ALREADY_INSTANTIATED:103:already instantiated RAND_R_ARGUMENT_OUT_OF_RANGE:105:argument out of range @@ -2494,6 +1107,7 @@ RAND_R_FAILED_TO_CREATE_LOCK:126:failed to create lock RAND_R_FUNC_NOT_IMPLEMENTED:101:Function not implemented RAND_R_FWRITE_ERROR:123:Error writing file RAND_R_GENERATE_ERROR:112:generate error +RAND_R_INSUFFICIENT_DRBG_STRENGTH:139:insufficient drbg strength RAND_R_INTERNAL_ERROR:113:internal error RAND_R_IN_ERROR_STATE:114:in error state RAND_R_NOT_A_REGULAR_FILE:122:Not a regular file @@ -2512,6 +1126,12 @@ RAND_R_RESEED_ERROR:118:reseed error RAND_R_SELFTEST_FAILURE:119:selftest failure RAND_R_TOO_LITTLE_NONCE_REQUESTED:135:too little nonce requested RAND_R_TOO_MUCH_NONCE_REQUESTED:136:too much nonce requested +RAND_R_UNABLE_TO_CREATE_DRBG:143:unable to create drbg +RAND_R_UNABLE_TO_FETCH_DRBG:144:unable to fetch drbg +RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER:141:\ + unable to get parent reseed prop counter +RAND_R_UNABLE_TO_GET_PARENT_STRENGTH:138:unable to get parent strength +RAND_R_UNABLE_TO_LOCK_PARENT:140:unable to lock parent RAND_R_UNSUPPORTED_DRBG_FLAGS:132:unsupported drbg flags RAND_R_UNSUPPORTED_DRBG_TYPE:120:unsupported drbg type RSA_R_ALGORITHM_MISMATCH:100:algorithm mismatch @@ -2539,16 +1159,22 @@ RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:144:\ RSA_R_INVALID_DIGEST:157:invalid digest RSA_R_INVALID_DIGEST_LENGTH:143:invalid digest length RSA_R_INVALID_HEADER:137:invalid header +RSA_R_INVALID_KEYPAIR:171:invalid keypair +RSA_R_INVALID_KEY_LENGTH:173:invalid key length RSA_R_INVALID_LABEL:160:invalid label +RSA_R_INVALID_LENGTH:181:invalid length RSA_R_INVALID_MESSAGE_LENGTH:131:invalid message length RSA_R_INVALID_MGF1_MD:156:invalid mgf1 md +RSA_R_INVALID_MODULUS:174:invalid modulus RSA_R_INVALID_MULTI_PRIME_KEY:167:invalid multi prime key RSA_R_INVALID_OAEP_PARAMETERS:161:invalid oaep parameters RSA_R_INVALID_PADDING:138:invalid padding RSA_R_INVALID_PADDING_MODE:141:invalid padding mode RSA_R_INVALID_PSS_PARAMETERS:149:invalid pss parameters RSA_R_INVALID_PSS_SALTLEN:146:invalid pss saltlen +RSA_R_INVALID_REQUEST:175:invalid request RSA_R_INVALID_SALT_LENGTH:150:invalid salt length +RSA_R_INVALID_STRENGTH:176:invalid strength RSA_R_INVALID_TRAILER:139:invalid trailer RSA_R_INVALID_X931_DIGEST:142:invalid x931 digest RSA_R_IQMP_NOT_INVERSE_OF_Q:126:iqmp not inverse of q @@ -2569,10 +1195,14 @@ RSA_R_OAEP_DECODING_ERROR:121:oaep decoding error RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:148:\ operation not supported for this keytype RSA_R_PADDING_CHECK_FAILED:114:padding check failed +RSA_R_PAIRWISE_TEST_FAILURE:177:pairwise test failure RSA_R_PKCS_DECODING_ERROR:159:pkcs decoding error RSA_R_PSS_SALTLEN_TOO_SMALL:164:pss saltlen too small +RSA_R_PUB_EXPONENT_OUT_OF_RANGE:178:pub exponent out of range RSA_R_P_NOT_PRIME:128:p not prime RSA_R_Q_NOT_PRIME:129:q not prime +RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT:180:\ + randomness source strength insufficient RSA_R_RSA_OPERATIONS_NOT_SUPPORTED:130:rsa operations not supported RSA_R_SLEN_CHECK_FAILED:136:salt length check failed RSA_R_SLEN_RECOVERY_FAILED:135:salt length recovery failed @@ -2601,6 +1231,7 @@ SM2_R_INVALID_DIGEST:102:invalid digest SM2_R_INVALID_DIGEST_TYPE:103:invalid digest type SM2_R_INVALID_ENCODING:104:invalid encoding SM2_R_INVALID_FIELD:105:invalid field +SM2_R_INVALID_PRIVATE_KEY:113:invalid private key SM2_R_NO_PARAMETERS_SET:109:no parameters set SM2_R_USER_ID_TOO_LARGE:106:user id too large SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY:291:\ @@ -2608,8 +1239,6 @@ SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY:291:\ SSL_R_APP_DATA_IN_HANDSHAKE:100:app data in handshake SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT:272:\ attempt to reuse session in different context -SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE:143:\ - at least TLS 1.0 needed in FIPS mode SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE:158:\ at least (D)TLS 1.2 needed in Suite B mode SSL_R_BAD_CHANGE_CIPHER_SPEC:103:bad change cipher spec @@ -2652,6 +1281,7 @@ SSL_R_BLOCK_CIPHER_PAD_IS_WRONG:129:block cipher pad is wrong SSL_R_BN_LIB:130:bn lib SSL_R_CALLBACK_FAILED:234:callback failed SSL_R_CANNOT_CHANGE_CIPHER:109:cannot change cipher +SSL_R_CANNOT_GET_GROUP_NAME:299:cannot get group name SSL_R_CA_DN_LENGTH_MISMATCH:131:ca dn length mismatch SSL_R_CA_KEY_TOO_SMALL:397:ca key too small SSL_R_CA_MD_TOO_WEAK:398:ca md too weak @@ -2661,7 +1291,6 @@ SSL_R_CERT_CB_ERROR:377:cert cb error SSL_R_CERT_LENGTH_MISMATCH:135:cert length mismatch SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED:218:ciphersuite digest has changed SSL_R_CIPHER_CODE_WRONG_LENGTH:137:cipher code wrong length -SSL_R_CIPHER_OR_HASH_UNAVAILABLE:138:cipher or hash unavailable SSL_R_CLIENTHELLO_TLSEXT:226:clienthello tlsext SSL_R_COMPRESSED_LENGTH_TOO_LONG:140:compressed length too long SSL_R_COMPRESSION_DISABLED:343:compression disabled @@ -2673,6 +1302,7 @@ SSL_R_CONNECTION_TYPE_NOT_SET:144:connection type not set SSL_R_CONTEXT_NOT_DANE_ENABLED:167:context not dane enabled SSL_R_COOKIE_GEN_CALLBACK_FAILURE:400:cookie gen callback failure SSL_R_COOKIE_MISMATCH:308:cookie mismatch +SSL_R_COPY_PARAMETERS_FAILED:296:copy parameters failed SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED:206:\ custom ext handler already installed SSL_R_DANE_ALREADY_ENABLED:172:dane already enabled @@ -2739,6 +1369,8 @@ SSL_R_INVALID_SESSION_ID:999:invalid session id SSL_R_INVALID_SRP_USERNAME:357:invalid srp username SSL_R_INVALID_STATUS_RESPONSE:328:invalid status response SSL_R_INVALID_TICKET_KEYS_LENGTH:325:invalid ticket keys length +SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED:333:\ + legacy sigalg disallowed or unsupported SSL_R_LENGTH_MISMATCH:159:length mismatch SSL_R_LENGTH_TOO_LONG:404:length too long SSL_R_LENGTH_TOO_SHORT:160:length too short @@ -2786,13 +1418,15 @@ SSL_R_NO_SHARED_CIPHER:193:no shared cipher SSL_R_NO_SHARED_GROUPS:410:no shared groups SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS:376:no shared signature algorithms SSL_R_NO_SRTP_PROFILES:359:no srtp profiles +SSL_R_NO_SUITABLE_DIGEST_ALGORITHM:297:no suitable digest algorithm +SSL_R_NO_SUITABLE_GROUPS:295:no suitable groups SSL_R_NO_SUITABLE_KEY_SHARE:101:no suitable key share SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM:118:no suitable signature algorithm SSL_R_NO_VALID_SCTS:216:no valid scts SSL_R_NO_VERIFY_COOKIE_CALLBACK:403:no verify cookie callback SSL_R_NULL_SSL_CTX:195:null ssl ctx SSL_R_NULL_SSL_METHOD_PASSED:196:null ssl method passed -SSL_R_OCSP_CALLBACK_FAILURE:294:ocsp callback failure +SSL_R_OCSP_CALLBACK_FAILURE:305:ocsp callback failure SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED:197:old session cipher not returned SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED:344:\ old session compression algorithm not returned @@ -2855,8 +1489,6 @@ SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH:303:ssl session id has bad length SSL_R_SSL_SESSION_ID_TOO_LONG:408:ssl session id too long SSL_R_SSL_SESSION_VERSION_MISMATCH:210:ssl session version mismatch SSL_R_STILL_IN_INIT:121:still in init -SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT:365:peer does not accept heartbeats -SSL_R_TLS_HEARTBEAT_PENDING:366:heartbeat request already pending SSL_R_TLS_ILLEGAL_EXPORTER_LABEL:367:tls illegal exporter label SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST:157:tls invalid ecpointformat list SSL_R_TOO_MANY_KEY_UPDATES:132:too many key updates @@ -2869,6 +1501,7 @@ SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES:242:unable to load ssl3 md5 routines SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data +SSL_R_UNEXPECTED_EOF_WHILE_READING:294:unexpected eof while reading SSL_R_UNEXPECTED_MESSAGE:244:unexpected message SSL_R_UNEXPECTED_RECORD:245:unexpected record SSL_R_UNINITIALIZED:276:uninitialized @@ -2965,6 +1598,7 @@ X509V3_R_BN_TO_ASN1_INTEGER_ERROR:101:bn to asn1 integer error X509V3_R_DIRNAME_ERROR:149:dirname error X509V3_R_DISTPOINT_ALREADY_SET:160:distpoint already set X509V3_R_DUPLICATE_ZONE_ID:133:duplicate zone id +X509V3_R_EMPTY_KEY_USAGE:169:empty key usage X509V3_R_ERROR_CONVERTING_ZONE:131:error converting zone X509V3_R_ERROR_CREATING_EXTENSION:144:error creating extension X509V3_R_ERROR_IN_EXTENSION:128:error in extension @@ -2979,13 +1613,14 @@ X509V3_R_INCORRECT_POLICY_SYNTAX_TAG:152:incorrect policy syntax tag X509V3_R_INVALID_ASNUMBER:162:invalid asnumber X509V3_R_INVALID_ASRANGE:163:invalid asrange X509V3_R_INVALID_BOOLEAN_STRING:104:invalid boolean string +X509V3_R_INVALID_CERTIFICATE:158:invalid certificate +X509V3_R_INVALID_EMPTY_NAME:108:invalid empty name X509V3_R_INVALID_EXTENSION_STRING:105:invalid extension string X509V3_R_INVALID_INHERITANCE:165:invalid inheritance X509V3_R_INVALID_IPADDRESS:166:invalid ipaddress X509V3_R_INVALID_MULTIPLE_RDNS:161:invalid multiple rdns X509V3_R_INVALID_NAME:106:invalid name X509V3_R_INVALID_NULL_ARGUMENT:107:invalid null argument -X509V3_R_INVALID_NULL_NAME:108:invalid null name X509V3_R_INVALID_NULL_VALUE:109:invalid null value X509V3_R_INVALID_NUMBER:140:invalid number X509V3_R_INVALID_NUMBERS:141:invalid numbers @@ -3000,6 +1635,7 @@ X509V3_R_INVALID_SYNTAX:143:invalid syntax X509V3_R_ISSUER_DECODE_ERROR:126:issuer decode error X509V3_R_MISSING_VALUE:124:missing value X509V3_R_NEED_ORGANIZATION_AND_NUMBERS:142:need organization and numbers +X509V3_R_NEGATIVE_PATHLEN:168:negative pathlen X509V3_R_NO_CONFIG_DATABASE:136:no config database X509V3_R_NO_ISSUER_CERTIFICATE:121:no issuer certificate X509V3_R_NO_ISSUER_DETAILS:127:no issuer details @@ -3031,12 +1667,16 @@ X509_R_BAD_SELECTOR:133:bad selector X509_R_BAD_X509_FILETYPE:100:bad x509 filetype X509_R_BASE64_DECODE_ERROR:118:base64 decode error X509_R_CANT_CHECK_DH_KEY:114:cant check dh key +X509_R_CERTIFICATE_VERIFICATION_FAILED:139:certificate verification failed 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_ERROR_GETTING_MD_BY_NID:141:error getting md by nid +X509_R_ERROR_USING_SIGINF_SET:142:error using siginf set X509_R_IDP_MISMATCH:128:idp mismatch X509_R_INVALID_ATTRIBUTES:138:invalid attributes X509_R_INVALID_DIRECTORY:113:invalid directory +X509_R_INVALID_DISTPOINT:143:invalid distpoint X509_R_INVALID_FIELD_NAME:119:invalid field name X509_R_INVALID_TRUST:123:invalid trust X509_R_ISSUER_MISMATCH:129:issuer mismatch @@ -3060,6 +1700,7 @@ X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY:108:unable to get certs public key X509_R_UNKNOWN_KEY_TYPE:117:unknown key type X509_R_UNKNOWN_NID:109:unknown nid X509_R_UNKNOWN_PURPOSE_ID:121:unknown purpose id +X509_R_UNKNOWN_SIGID_ALGS:144:unknown sigid algs X509_R_UNKNOWN_TRUST_ID:120:unknown trust id X509_R_UNSUPPORTED_ALGORITHM:111:unsupported algorithm X509_R_WRONG_LOOKUP_TYPE:112:wrong lookup type diff --git a/crypto/openssl/crypto/ess/build.info b/crypto/openssl/crypto/ess/build.info new file mode 100644 index 000000000000..f25c1271fb2f --- /dev/null +++ b/crypto/openssl/crypto/ess/build.info @@ -0,0 +1,3 @@ +LIBS=../../libcrypto + +SOURCE[../../libcrypto]= ess_asn1.c ess_err.c ess_lib.c diff --git a/crypto/openssl/crypto/ess/ess_asn1.c b/crypto/openssl/crypto/ess/ess_asn1.c new file mode 100644 index 000000000000..68bc854c99bb --- /dev/null +++ b/crypto/openssl/crypto/ess/ess_asn1.c @@ -0,0 +1,58 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include "crypto/ess.h" + +/* ASN1 stuff for ESS Structure */ + +ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = { + ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME), + ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER) +} static_ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL) + +IMPLEMENT_ASN1_FUNCTIONS(ESS_ISSUER_SERIAL) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL) + +ASN1_SEQUENCE(ESS_CERT_ID) = { + ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING), + ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL) +} static_ASN1_SEQUENCE_END(ESS_CERT_ID) + +IMPLEMENT_ASN1_FUNCTIONS(ESS_CERT_ID) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID) + +ASN1_SEQUENCE(ESS_SIGNING_CERT) = { + ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID), + ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO) +} ASN1_SEQUENCE_END(ESS_SIGNING_CERT) + +IMPLEMENT_ASN1_FUNCTIONS(ESS_SIGNING_CERT) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT) + +ASN1_SEQUENCE(ESS_CERT_ID_V2) = { + ASN1_OPT(ESS_CERT_ID_V2, hash_alg, X509_ALGOR), + ASN1_SIMPLE(ESS_CERT_ID_V2, hash, ASN1_OCTET_STRING), + ASN1_OPT(ESS_CERT_ID_V2, issuer_serial, ESS_ISSUER_SERIAL) +} static_ASN1_SEQUENCE_END(ESS_CERT_ID_V2) + +IMPLEMENT_ASN1_FUNCTIONS(ESS_CERT_ID_V2) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID_V2) + +ASN1_SEQUENCE(ESS_SIGNING_CERT_V2) = { + ASN1_SEQUENCE_OF(ESS_SIGNING_CERT_V2, cert_ids, ESS_CERT_ID_V2), + ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT_V2, policy_info, POLICYINFO) +} ASN1_SEQUENCE_END(ESS_SIGNING_CERT_V2) + +IMPLEMENT_ASN1_FUNCTIONS(ESS_SIGNING_CERT_V2) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT_V2) diff --git a/crypto/openssl/crypto/ess/ess_err.c b/crypto/openssl/crypto/ess/ess_err.c new file mode 100644 index 000000000000..eb76dfe7cc8f --- /dev/null +++ b/crypto/openssl/crypto/ess/ess_err.c @@ -0,0 +1,48 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/esserr.h" + +#ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA ESS_str_reasons[] = { + {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_EMPTY_ESS_CERT_ID_LIST), + "empty ess cert id list"}, + {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_CERT_DIGEST_ERROR), + "ess cert digest error"}, + {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_CERT_ID_NOT_FOUND), + "ess cert id not found"}, + {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_CERT_ID_WRONG_ORDER), + "ess cert id wrong order"}, + {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_DIGEST_ALG_UNKNOWN), + "ess digest alg unknown"}, + {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_SIGNING_CERTIFICATE_ERROR), + "ess signing certificate error"}, + {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_SIGNING_CERT_ADD_ERROR), + "ess signing cert add error"}, + {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR), + "ess signing cert v2 add error"}, + {ERR_PACK(ERR_LIB_ESS, 0, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE), + "missing signing certificate attribute"}, + {0, NULL} +}; + +#endif + +int ossl_err_load_ESS_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(ESS_str_reasons[0].error) == NULL) + ERR_load_strings_const(ESS_str_reasons); +#endif + return 1; +} diff --git a/crypto/openssl/crypto/ess/ess_lib.c b/crypto/openssl/crypto/ess/ess_lib.c new file mode 100644 index 000000000000..65444d383ff4 --- /dev/null +++ b/crypto/openssl/crypto/ess/ess_lib.c @@ -0,0 +1,315 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/sizes.h" +#include "crypto/ess.h" +#include "crypto/x509.h" + +static ESS_CERT_ID *ESS_CERT_ID_new_init(const X509 *cert, + int set_issuer_serial); +static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg, + const X509 *cert, + int set_issuer_serial); + +ESS_SIGNING_CERT *OSSL_ESS_signing_cert_new_init(const X509 *signcert, + const STACK_OF(X509) *certs, + int set_issuer_serial) +{ + ESS_CERT_ID *cid = NULL; + ESS_SIGNING_CERT *sc; + int i; + + if ((sc = ESS_SIGNING_CERT_new()) == NULL) + goto err; + if (sc->cert_ids == NULL + && (sc->cert_ids = sk_ESS_CERT_ID_new_null()) == NULL) + goto err; + + if ((cid = ESS_CERT_ID_new_init(signcert, set_issuer_serial)) == NULL + || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + goto err; + for (i = 0; i < sk_X509_num(certs); ++i) { + X509 *cert = sk_X509_value(certs, i); + + if ((cid = ESS_CERT_ID_new_init(cert, 1)) == NULL + || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + goto err; + } + + return sc; + err: + ESS_SIGNING_CERT_free(sc); + ESS_CERT_ID_free(cid); + ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); + return NULL; +} + +static ESS_CERT_ID *ESS_CERT_ID_new_init(const X509 *cert, + int set_issuer_serial) +{ + ESS_CERT_ID *cid = NULL; + GENERAL_NAME *name = NULL; + unsigned char cert_sha1[SHA_DIGEST_LENGTH]; + + if ((cid = ESS_CERT_ID_new()) == NULL) + goto err; + if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL)) + goto err; + if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH)) + goto err; + + /* Setting the issuer/serial if requested. */ + if (!set_issuer_serial) + return cid; + + if (cid->issuer_serial == NULL + && (cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL) + goto err; + if ((name = GENERAL_NAME_new()) == NULL) + goto err; + name->type = GEN_DIRNAME; + if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL) + goto err; + if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) + goto err; + name = NULL; /* Ownership is lost. */ + ASN1_INTEGER_free(cid->issuer_serial->serial); + if ((cid->issuer_serial->serial = + ASN1_INTEGER_dup(X509_get0_serialNumber(cert))) == NULL) + goto err; + + return cid; + err: + GENERAL_NAME_free(name); + ESS_CERT_ID_free(cid); + ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); + return NULL; +} + +ESS_SIGNING_CERT_V2 *OSSL_ESS_signing_cert_v2_new_init(const EVP_MD *hash_alg, + const X509 *signcert, + const + STACK_OF(X509) *certs, + int set_issuer_serial) +{ + ESS_CERT_ID_V2 *cid = NULL; + ESS_SIGNING_CERT_V2 *sc; + int i; + + if ((sc = ESS_SIGNING_CERT_V2_new()) == NULL) + goto err; + cid = ESS_CERT_ID_V2_new_init(hash_alg, signcert, set_issuer_serial); + if (cid == NULL) + goto err; + if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid)) + goto err; + cid = NULL; + + for (i = 0; i < sk_X509_num(certs); ++i) { + X509 *cert = sk_X509_value(certs, i); + + if ((cid = ESS_CERT_ID_V2_new_init(hash_alg, cert, 1)) == NULL) + goto err; + if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid)) + goto err; + cid = NULL; + } + + return sc; + err: + ESS_SIGNING_CERT_V2_free(sc); + ESS_CERT_ID_V2_free(cid); + ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); + return NULL; +} + +static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg, + const X509 *cert, + int set_issuer_serial) +{ + ESS_CERT_ID_V2 *cid; + GENERAL_NAME *name = NULL; + unsigned char hash[EVP_MAX_MD_SIZE]; + unsigned int hash_len = sizeof(hash); + X509_ALGOR *alg = NULL; + + memset(hash, 0, sizeof(hash)); + + if ((cid = ESS_CERT_ID_V2_new()) == NULL) + goto err; + + if (!EVP_MD_is_a(hash_alg, SN_sha256)) { + alg = X509_ALGOR_new(); + if (alg == NULL) + goto err; + X509_ALGOR_set_md(alg, hash_alg); + if (alg->algorithm == NULL) + goto err; + cid->hash_alg = alg; + alg = NULL; + } else { + cid->hash_alg = NULL; + } + + if (!X509_digest(cert, hash_alg, hash, &hash_len)) + goto err; + + if (!ASN1_OCTET_STRING_set(cid->hash, hash, hash_len)) + goto err; + + if (!set_issuer_serial) + return cid; + + if ((cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL) + goto err; + if ((name = GENERAL_NAME_new()) == NULL) + goto err; + name->type = GEN_DIRNAME; + if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL) + goto err; + if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) + goto err; + name = NULL; /* Ownership is lost. */ + ASN1_INTEGER_free(cid->issuer_serial->serial); + cid->issuer_serial->serial = ASN1_INTEGER_dup(X509_get0_serialNumber(cert)); + if (cid->issuer_serial->serial == NULL) + goto err; + + return cid; + err: + X509_ALGOR_free(alg); + GENERAL_NAME_free(name); + ESS_CERT_ID_V2_free(cid); + ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); + return NULL; +} + +static int ess_issuer_serial_cmp(const ESS_ISSUER_SERIAL *is, const X509 *cert) +{ + GENERAL_NAME *issuer; + + if (is == NULL || cert == NULL || sk_GENERAL_NAME_num(is->issuer) != 1) + return -1; + + issuer = sk_GENERAL_NAME_value(is->issuer, 0); + if (issuer->type != GEN_DIRNAME + || X509_NAME_cmp(issuer->d.dirn, X509_get_issuer_name(cert)) != 0) + return -1; + + return ASN1_INTEGER_cmp(is->serial, X509_get0_serialNumber(cert)); +} + +/* + * Find the cert in |certs| referenced by |cid| if not NULL, else by |cid_v2|. + * The cert must be the first one in |certs| if and only if |index| is 0. + * Return 0 on not found, -1 on error, else 1 + the position in |certs|. + */ +static int find(const ESS_CERT_ID *cid, const ESS_CERT_ID_V2 *cid_v2, + int index, const STACK_OF(X509) *certs) +{ + const X509 *cert; + EVP_MD *md = NULL; + char name[OSSL_MAX_NAME_SIZE]; + unsigned char cert_digest[EVP_MAX_MD_SIZE]; + unsigned int len, cid_hash_len; + const ESS_ISSUER_SERIAL *is; + int i; + int ret = -1; + + if (cid == NULL && cid_v2 == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_PASSED_INVALID_ARGUMENT); + return -1; + } + + if (cid != NULL) + strcpy(name, "SHA1"); + else if (cid_v2->hash_alg == NULL) + strcpy(name, "SHA256"); + else + OBJ_obj2txt(name, sizeof(name), cid_v2->hash_alg->algorithm, 0); + + (void)ERR_set_mark(); + md = EVP_MD_fetch(NULL, name, NULL); + + if (md == NULL) + md = (EVP_MD *)EVP_get_digestbyname(name); + + if (md == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_ESS, ESS_R_ESS_DIGEST_ALG_UNKNOWN); + goto end; + } + (void)ERR_pop_to_mark(); + + for (i = 0; i < sk_X509_num(certs); ++i) { + cert = sk_X509_value(certs, i); + + cid_hash_len = cid != NULL ? cid->hash->length : cid_v2->hash->length; + if (!X509_digest(cert, md, cert_digest, &len) + || cid_hash_len != len) { + ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_DIGEST_ERROR); + goto end; + } + + if (memcmp(cid != NULL ? cid->hash->data : cid_v2->hash->data, + cert_digest, len) == 0) { + is = cid != NULL ? cid->issuer_serial : cid_v2->issuer_serial; + /* Well, it's not really required to match the serial numbers. */ + if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0) { + if ((i == 0) == (index == 0)) { + ret = i + 1; + goto end; + } + ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_ID_WRONG_ORDER); + goto end; + } + } + } + + ret = 0; + ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_ID_NOT_FOUND); +end: + EVP_MD_free(md); + return ret; +} + +int OSSL_ESS_check_signing_certs(const ESS_SIGNING_CERT *ss, + const ESS_SIGNING_CERT_V2 *ssv2, + const STACK_OF(X509) *chain, + int require_signing_cert) +{ + int n_v1 = ss == NULL ? -1 : sk_ESS_CERT_ID_num(ss->cert_ids); + int n_v2 = ssv2 == NULL ? -1 : sk_ESS_CERT_ID_V2_num(ssv2->cert_ids); + int i, ret; + + if (require_signing_cert && ss == NULL && ssv2 == NULL) { + ERR_raise(ERR_LIB_CMS, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE); + return -1; + } + if (n_v1 == 0 || n_v2 == 0) { + ERR_raise(ERR_LIB_ESS, ESS_R_EMPTY_ESS_CERT_ID_LIST); + return -1; + } + /* If both ss and ssv2 exist, as required evaluate them independently. */ + for (i = 0; i < n_v1; i++) { + ret = find(sk_ESS_CERT_ID_value(ss->cert_ids, i), NULL, i, chain); + if (ret <= 0) + return ret; + } + for (i = 0; i < n_v2; i++) { + ret = find(NULL, sk_ESS_CERT_ID_V2_value(ssv2->cert_ids, i), i, chain); + if (ret <= 0) + return ret; + } + return 1; +} diff --git a/crypto/openssl/crypto/evp/asymcipher.c b/crypto/openssl/crypto/evp/asymcipher.c new file mode 100644 index 000000000000..b7784c899457 --- /dev/null +++ b/crypto/openssl/crypto/evp/asymcipher.c @@ -0,0 +1,552 @@ +/* + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/provider.h" +#include "internal/core.h" +#include "crypto/evp.h" +#include "evp_local.h" + +static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation, + const OSSL_PARAM params[]) +{ + int ret = 0; + void *provkey = NULL; + EVP_ASYM_CIPHER *cipher = NULL; + EVP_KEYMGMT *tmp_keymgmt = NULL; + const OSSL_PROVIDER *tmp_prov = NULL; + const char *supported_ciph = NULL; + int iter; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = operation; + + ERR_set_mark(); + + if (evp_pkey_ctx_is_legacy(ctx)) + goto legacy; + + if (ctx->pkey == NULL) { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); + goto err; + } + + /* + * Try to derive the supported asym cipher from |ctx->keymgmt|. + */ + if (!ossl_assert(ctx->pkey->keymgmt == NULL + || ctx->pkey->keymgmt == ctx->keymgmt)) { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + goto err; + } + supported_ciph + = evp_keymgmt_util_query_operation_name(ctx->keymgmt, + OSSL_OP_ASYM_CIPHER); + if (supported_ciph == NULL) { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + /* + * We perform two iterations: + * + * 1. Do the normal asym cipher fetch, using the fetching data given by + * the EVP_PKEY_CTX. + * 2. Do the provider specific asym cipher fetch, from the same provider + * as |ctx->keymgmt| + * + * We then try to fetch the keymgmt from the same provider as the + * asym cipher, and try to export |ctx->pkey| to that keymgmt (when + * this keymgmt happens to be the same as |ctx->keymgmt|, the export + * is a no-op, but we call it anyway to not complicate the code even + * more). + * If the export call succeeds (returns a non-NULL provider key pointer), + * we're done and can perform the operation itself. If not, we perform + * the second iteration, or jump to legacy. + */ + for (iter = 1, provkey = NULL; iter < 3 && provkey == NULL; iter++) { + EVP_KEYMGMT *tmp_keymgmt_tofree; + + /* + * If we're on the second iteration, free the results from the first. + * They are NULL on the first iteration, so no need to check what + * iteration we're on. + */ + EVP_ASYM_CIPHER_free(cipher); + EVP_KEYMGMT_free(tmp_keymgmt); + + switch (iter) { + case 1: + cipher = EVP_ASYM_CIPHER_fetch(ctx->libctx, supported_ciph, + ctx->propquery); + if (cipher != NULL) + tmp_prov = EVP_ASYM_CIPHER_get0_provider(cipher); + break; + case 2: + tmp_prov = EVP_KEYMGMT_get0_provider(ctx->keymgmt); + cipher = + evp_asym_cipher_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, + supported_ciph, ctx->propquery); + if (cipher == NULL) + goto legacy; + break; + } + if (cipher == NULL) + continue; + + /* + * Ensure that the key is provided, either natively, or as a cached + * export. We start by fetching the keymgmt with the same name as + * |ctx->pkey|, but from the provider of the asym cipher method, using + * the same property query as when fetching the asym cipher method. + * With the keymgmt we found (if we did), we try to export |ctx->pkey| + * to it (evp_pkey_export_to_provider() is smart enough to only actually + * export it if |tmp_keymgmt| is different from |ctx->pkey|'s keymgmt) + */ + tmp_keymgmt_tofree = tmp_keymgmt + = evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, + EVP_KEYMGMT_get0_name(ctx->keymgmt), + ctx->propquery); + if (tmp_keymgmt != NULL) + provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, + &tmp_keymgmt, ctx->propquery); + if (tmp_keymgmt == NULL) + EVP_KEYMGMT_free(tmp_keymgmt_tofree); + } + + if (provkey == NULL) { + EVP_ASYM_CIPHER_free(cipher); + goto legacy; + } + + ERR_pop_to_mark(); + + /* No more legacy from here down to legacy: */ + + ctx->op.ciph.cipher = cipher; + ctx->op.ciph.algctx = cipher->newctx(ossl_provider_ctx(cipher->prov)); + if (ctx->op.ciph.algctx == NULL) { + /* The provider key can stay in the cache */ + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + switch (operation) { + case EVP_PKEY_OP_ENCRYPT: + if (cipher->encrypt_init == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = cipher->encrypt_init(ctx->op.ciph.algctx, provkey, params); + break; + case EVP_PKEY_OP_DECRYPT: + if (cipher->decrypt_init == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = cipher->decrypt_init(ctx->op.ciph.algctx, provkey, params); + break; + default: + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + if (ret <= 0) + goto err; + EVP_KEYMGMT_free(tmp_keymgmt); + return 1; + + legacy: + /* + * If we don't have the full support we need with provided methods, + * let's go see if legacy does. + */ + ERR_pop_to_mark(); + EVP_KEYMGMT_free(tmp_keymgmt); + tmp_keymgmt = NULL; + + if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + switch(ctx->operation) { + case EVP_PKEY_OP_ENCRYPT: + if (ctx->pmeth->encrypt_init == NULL) + return 1; + ret = ctx->pmeth->encrypt_init(ctx); + break; + case EVP_PKEY_OP_DECRYPT: + if (ctx->pmeth->decrypt_init == NULL) + return 1; + ret = ctx->pmeth->decrypt_init(ctx); + break; + default: + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + ret = -1; + } + + err: + if (ret <= 0) { + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = EVP_PKEY_OP_UNDEFINED; + } + EVP_KEYMGMT_free(tmp_keymgmt); + return ret; +} + +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_ENCRYPT, NULL); +} + +int EVP_PKEY_encrypt_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) +{ + return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_ENCRYPT, params); +} + +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + int ret; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.ciph.algctx == NULL) + goto legacy; + + ret = ctx->op.ciph.cipher->encrypt(ctx->op.ciph.algctx, out, outlen, + (out == NULL ? 0 : *outlen), in, inlen); + return ret; + + legacy: + if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) + return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); +} + +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT, NULL); +} + +int EVP_PKEY_decrypt_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) +{ + return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT, params); +} + +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + int ret; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_DECRYPT) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.ciph.algctx == NULL) + goto legacy; + + ret = ctx->op.ciph.cipher->decrypt(ctx->op.ciph.algctx, out, outlen, + (out == NULL ? 0 : *outlen), in, inlen); + return ret; + + legacy: + if (ctx->pmeth == NULL || ctx->pmeth->decrypt == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) + return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); +} + + +static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov) +{ + EVP_ASYM_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_ASYM_CIPHER)); + + if (cipher == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + cipher->lock = CRYPTO_THREAD_lock_new(); + if (cipher->lock == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(cipher); + return NULL; + } + cipher->prov = prov; + ossl_provider_up_ref(prov); + cipher->refcnt = 1; + + return cipher; +} + +static void *evp_asym_cipher_from_algorithm(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + const OSSL_DISPATCH *fns = algodef->implementation; + EVP_ASYM_CIPHER *cipher = NULL; + int ctxfncnt = 0, encfncnt = 0, decfncnt = 0; + int gparamfncnt = 0, sparamfncnt = 0; + + if ((cipher = evp_asym_cipher_new(prov)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + cipher->name_id = name_id; + if ((cipher->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) + goto err; + cipher->description = algodef->algorithm_description; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_ASYM_CIPHER_NEWCTX: + if (cipher->newctx != NULL) + break; + cipher->newctx = OSSL_FUNC_asym_cipher_newctx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT: + if (cipher->encrypt_init != NULL) + break; + cipher->encrypt_init = OSSL_FUNC_asym_cipher_encrypt_init(fns); + encfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_ENCRYPT: + if (cipher->encrypt != NULL) + break; + cipher->encrypt = OSSL_FUNC_asym_cipher_encrypt(fns); + encfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT: + if (cipher->decrypt_init != NULL) + break; + cipher->decrypt_init = OSSL_FUNC_asym_cipher_decrypt_init(fns); + decfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_DECRYPT: + if (cipher->decrypt != NULL) + break; + cipher->decrypt = OSSL_FUNC_asym_cipher_decrypt(fns); + decfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_FREECTX: + if (cipher->freectx != NULL) + break; + cipher->freectx = OSSL_FUNC_asym_cipher_freectx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_DUPCTX: + if (cipher->dupctx != NULL) + break; + cipher->dupctx = OSSL_FUNC_asym_cipher_dupctx(fns); + break; + case OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS: + if (cipher->get_ctx_params != NULL) + break; + cipher->get_ctx_params + = OSSL_FUNC_asym_cipher_get_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS: + if (cipher->gettable_ctx_params != NULL) + break; + cipher->gettable_ctx_params + = OSSL_FUNC_asym_cipher_gettable_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS: + if (cipher->set_ctx_params != NULL) + break; + cipher->set_ctx_params + = OSSL_FUNC_asym_cipher_set_ctx_params(fns); + sparamfncnt++; + break; + case OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS: + if (cipher->settable_ctx_params != NULL) + break; + cipher->settable_ctx_params + = OSSL_FUNC_asym_cipher_settable_ctx_params(fns); + sparamfncnt++; + break; + } + } + if (ctxfncnt != 2 + || (encfncnt != 0 && encfncnt != 2) + || (decfncnt != 0 && decfncnt != 2) + || (encfncnt != 2 && decfncnt != 2) + || (gparamfncnt != 0 && gparamfncnt != 2) + || (sparamfncnt != 0 && sparamfncnt != 2)) { + /* + * In order to be a consistent set of functions we must have at least + * a set of context functions (newctx and freectx) as well as a pair of + * "cipher" functions: (encrypt_init, encrypt) or + * (decrypt_init decrypt). set_ctx_params and settable_ctx_params are + * optional, but if one of them is present then the other one must also + * be present. The same applies to get_ctx_params and + * gettable_ctx_params. The dupctx function is optional. + */ + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + goto err; + } + + return cipher; + err: + EVP_ASYM_CIPHER_free(cipher); + return NULL; +} + +void EVP_ASYM_CIPHER_free(EVP_ASYM_CIPHER *cipher) +{ + int i; + + if (cipher == NULL) + return; + CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock); + if (i > 0) + return; + OPENSSL_free(cipher->type_name); + ossl_provider_free(cipher->prov); + CRYPTO_THREAD_lock_free(cipher->lock); + OPENSSL_free(cipher); +} + +int EVP_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher) +{ + int ref = 0; + + CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock); + return 1; +} + +OSSL_PROVIDER *EVP_ASYM_CIPHER_get0_provider(const EVP_ASYM_CIPHER *cipher) +{ + return cipher->prov; +} + +EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(ctx, OSSL_OP_ASYM_CIPHER, algorithm, properties, + evp_asym_cipher_from_algorithm, + (int (*)(void *))EVP_ASYM_CIPHER_up_ref, + (void (*)(void *))EVP_ASYM_CIPHER_free); +} + +EVP_ASYM_CIPHER *evp_asym_cipher_fetch_from_prov(OSSL_PROVIDER *prov, + const char *algorithm, + const char *properties) +{ + return evp_generic_fetch_from_prov(prov, OSSL_OP_ASYM_CIPHER, + algorithm, properties, + evp_asym_cipher_from_algorithm, + (int (*)(void *))EVP_ASYM_CIPHER_up_ref, + (void (*)(void *))EVP_ASYM_CIPHER_free); +} + +int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name) +{ + return evp_is_a(cipher->prov, cipher->name_id, NULL, name); +} + +int evp_asym_cipher_get_number(const EVP_ASYM_CIPHER *cipher) +{ + return cipher->name_id; +} + +const char *EVP_ASYM_CIPHER_get0_name(const EVP_ASYM_CIPHER *cipher) +{ + return cipher->type_name; +} + +const char *EVP_ASYM_CIPHER_get0_description(const EVP_ASYM_CIPHER *cipher) +{ + return cipher->description; +} + +void EVP_ASYM_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_ASYM_CIPHER *cipher, + void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_ASYM_CIPHER, + (void (*)(void *, void *))fn, arg, + evp_asym_cipher_from_algorithm, + (int (*)(void *))EVP_ASYM_CIPHER_up_ref, + (void (*)(void *))EVP_ASYM_CIPHER_free); +} + + +int EVP_ASYM_CIPHER_names_do_all(const EVP_ASYM_CIPHER *cipher, + void (*fn)(const char *name, void *data), + void *data) +{ + if (cipher->prov != NULL) + return evp_names_do_all(cipher->prov, cipher->name_id, fn, data); + + return 1; +} + +const OSSL_PARAM *EVP_ASYM_CIPHER_gettable_ctx_params(const EVP_ASYM_CIPHER *cip) +{ + void *provctx; + + if (cip == NULL || cip->gettable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_get0_provider(cip)); + return cip->gettable_ctx_params(NULL, provctx); +} + +const OSSL_PARAM *EVP_ASYM_CIPHER_settable_ctx_params(const EVP_ASYM_CIPHER *cip) +{ + void *provctx; + + if (cip == NULL || cip->settable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_get0_provider(cip)); + return cip->settable_ctx_params(NULL, provctx); +} diff --git a/crypto/openssl/crypto/evp/bio_b64.c b/crypto/openssl/crypto/evp/bio_b64.c index 9f891f7626a6..81d2609c302b 100644 --- a/crypto/openssl/crypto/evp/bio_b64.c +++ b/crypto/openssl/crypto/evp/bio_b64.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -46,10 +46,8 @@ typedef struct b64_struct { static const BIO_METHOD methods_b64 = { BIO_TYPE_BASE64, "base64 encoding", - /* TODO: Convert to new style write function */ bwrite_conv, b64_write, - /* TODO: Convert to new style read function */ bread_conv, b64_read, b64_puts, @@ -71,7 +69,7 @@ static int b64_new(BIO *bi) BIO_B64_CTX *ctx; if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - EVPerr(EVP_F_B64_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -534,17 +532,12 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) static long b64_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) { - long ret = 1; BIO *next = BIO_next(b); if (next == NULL) return 0; - switch (cmd) { - default: - ret = BIO_callback_ctrl(next, cmd, fp); - break; - } - return ret; + + return BIO_callback_ctrl(next, cmd, fp); } static int b64_puts(BIO *b, const char *str) diff --git a/crypto/openssl/crypto/evp/bio_enc.c b/crypto/openssl/crypto/evp/bio_enc.c index 9afce7c08409..304030bcb3b5 100644 --- a/crypto/openssl/crypto/evp/bio_enc.c +++ b/crypto/openssl/crypto/evp/bio_enc.c @@ -1,12 +1,14 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +#define OPENSSL_SUPPRESS_DEPRECATED /* for BIO_get_callback */ + #include #include #include "internal/cryptlib.h" @@ -42,10 +44,8 @@ typedef struct enc_struct { static const BIO_METHOD methods_enc = { BIO_TYPE_CIPHER, "cipher", - /* TODO: Convert to new style write function */ bwrite_conv, enc_write, - /* TODO: Convert to new style read function */ bread_conv, enc_read, NULL, /* enc_puts, */ @@ -66,7 +66,7 @@ static int enc_new(BIO *bi) BIO_ENC_CTX *ctx; if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - EVPerr(EVP_F_ENC_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -133,7 +133,7 @@ static int enc_read(BIO *b, char *out, int outl) } } - blocksize = EVP_CIPHER_CTX_block_size(ctx->cipher); + blocksize = EVP_CIPHER_CTX_get_block_size(ctx->cipher); if (blocksize == 1) blocksize = 0; @@ -311,7 +311,7 @@ static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) ctx->ok = 1; ctx->finished = 0; if (!EVP_CipherInit_ex(ctx->cipher, NULL, NULL, NULL, NULL, - EVP_CIPHER_CTX_encrypting(ctx->cipher))) + EVP_CIPHER_CTX_is_encrypting(ctx->cipher))) return 0; ret = BIO_ctrl(next, cmd, num, ptr); break; @@ -395,42 +395,54 @@ static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) static long enc_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) { - long ret = 1; BIO *next = BIO_next(b); if (next == NULL) return 0; - switch (cmd) { - default: - ret = BIO_callback_ctrl(next, cmd, fp); - break; - } - return ret; + + return BIO_callback_ctrl(next, cmd, fp); } int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, const unsigned char *i, int e) { BIO_ENC_CTX *ctx; - long (*callback) (struct bio_st *, int, const char *, int, long, long); + BIO_callback_fn_ex callback_ex; +#ifndef OPENSSL_NO_DEPRECATED_3_0 + long (*callback) (struct bio_st *, int, const char *, int, long, long) = NULL; +#endif ctx = BIO_get_data(b); if (ctx == NULL) return 0; - callback = BIO_get_callback(b); + if ((callback_ex = BIO_get_callback_ex(b)) != NULL) { + if (callback_ex(b, BIO_CB_CTRL, (const char *)c, 0, BIO_CTRL_SET, + e, 1, NULL) <= 0) + return 0; + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + else { + callback = BIO_get_callback(b); - if ((callback != NULL) && + if ((callback != NULL) && (callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 0L) <= 0)) - return 0; + return 0; + } +#endif BIO_set_init(b, 1); if (!EVP_CipherInit_ex(ctx->cipher, c, NULL, k, i, e)) return 0; - if (callback != NULL) + if (callback_ex != NULL) + return callback_ex(b, BIO_CB_CTRL | BIO_CB_RETURN, (const char *)c, 0, + BIO_CTRL_SET, e, 1, NULL); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + else if (callback != NULL) return callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L); +#endif return 1; } diff --git a/crypto/openssl/crypto/evp/bio_md.c b/crypto/openssl/crypto/evp/bio_md.c index fed4cf1eb1ff..1a85be18118b 100644 --- a/crypto/openssl/crypto/evp/bio_md.c +++ b/crypto/openssl/crypto/evp/bio_md.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,11 +9,8 @@ #include #include -#include "internal/cryptlib.h" #include #include -#include "crypto/evp.h" -#include "evp_local.h" #include "internal/bio.h" /* @@ -31,10 +28,8 @@ static long md_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); static const BIO_METHOD methods_md = { BIO_TYPE_MD, "message digest", - /* TODO: Convert to new style write function */ bwrite_conv, md_write, - /* TODO: Convert to new style read function */ bread_conv, md_read, NULL, /* md_puts, */ @@ -148,7 +143,7 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr) switch (cmd) { case BIO_CTRL_RESET: if (BIO_get_init(b)) - ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL); + ret = EVP_DigestInit_ex(ctx, EVP_MD_CTX_get0_md(ctx), NULL); else ret = 0; if (ret > 0) @@ -157,7 +152,7 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_C_GET_MD: if (BIO_get_init(b)) { ppmd = ptr; - *ppmd = ctx->digest; + *ppmd = EVP_MD_CTX_get0_md(ctx); } else ret = 0; break; @@ -200,7 +195,6 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr) static long md_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) { - long ret = 1; BIO *next; next = BIO_next(b); @@ -208,12 +202,7 @@ static long md_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) if (next == NULL) return 0; - switch (cmd) { - default: - ret = BIO_callback_ctrl(next, cmd, fp); - break; - } - return ret; + return BIO_callback_ctrl(next, cmd, fp); } static int md_gets(BIO *bp, char *buf, int size) @@ -223,7 +212,7 @@ static int md_gets(BIO *bp, char *buf, int size) ctx = BIO_get_data(bp); - if (size < ctx->digest->md_size) + if (size < EVP_MD_CTX_get_size(ctx)) return 0; if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0) diff --git a/crypto/openssl/crypto/evp/bio_ok.c b/crypto/openssl/crypto/evp/bio_ok.c index 9610f3c1efeb..97e67fcb6814 100644 --- a/crypto/openssl/crypto/evp/bio_ok.c +++ b/crypto/openssl/crypto/evp/bio_ok.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -76,6 +76,7 @@ #include "internal/bio.h" #include #include +#include "internal/endian.h" #include "crypto/evp.h" static int ok_write(BIO *h, const char *buf, int num); @@ -110,10 +111,8 @@ typedef struct ok_struct { static const BIO_METHOD methods_ok = { BIO_TYPE_CIPHER, "reliable", - /* TODO: Convert to new style write function */ bwrite_conv, ok_write, - /* TODO: Convert to new style read function */ bread_conv, ok_read, NULL, /* ok_puts, */ @@ -134,7 +133,7 @@ static int ok_new(BIO *bi) BIO_OK_CTX *ctx; if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - EVPerr(EVP_F_OK_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -393,7 +392,7 @@ static long ok_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_C_GET_MD: if (BIO_get_init(b)) { ppmd = ptr; - *ppmd = EVP_MD_CTX_md(ctx->md); + *ppmd = EVP_MD_CTX_get0_md(ctx->md); } else ret = 0; break; @@ -406,7 +405,6 @@ static long ok_ctrl(BIO *b, int cmd, long num, void *ptr) static long ok_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) { - long ret = 1; BIO *next; next = BIO_next(b); @@ -414,25 +412,14 @@ static long ok_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) if (next == NULL) return 0; - switch (cmd) { - default: - ret = BIO_callback_ctrl(next, cmd, fp); - break; - } - - return ret; + return BIO_callback_ctrl(next, cmd, fp); } static void longswap(void *_ptr, size_t len) { - const union { - long one; - char little; - } is_endian = { - 1 - }; - - if (is_endian.little) { + DECLARE_IS_ENDIAN; + + if (IS_LITTLE_ENDIAN) { size_t i; unsigned char *p = _ptr, c; @@ -453,9 +440,9 @@ static int sig_out(BIO *b) ctx = BIO_get_data(b); md = ctx->md; - digest = EVP_MD_CTX_md(md); - md_size = EVP_MD_size(digest); - md_data = EVP_MD_CTX_md_data(md); + digest = EVP_MD_CTX_get0_md(md); + md_size = EVP_MD_get_size(digest); + md_data = EVP_MD_CTX_get0_md_data(md); if (ctx->buf_len + 2 * md_size > OK_BLOCK_SIZE) return 1; @@ -496,10 +483,12 @@ static int sig_in(BIO *b) void *md_data; ctx = BIO_get_data(b); - md = ctx->md; - digest = EVP_MD_CTX_md(md); - md_size = EVP_MD_size(digest); - md_data = EVP_MD_CTX_md_data(md); + if ((md = ctx->md) == NULL) + goto berr; + digest = EVP_MD_CTX_get0_md(md); + if ((md_size = EVP_MD_get_size(digest)) < 0) + goto berr; + md_data = EVP_MD_CTX_get0_md_data(md); if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md_size) return 1; @@ -543,8 +532,8 @@ static int block_out(BIO *b) ctx = BIO_get_data(b); md = ctx->md; - digest = EVP_MD_CTX_md(md); - md_size = EVP_MD_size(digest); + digest = EVP_MD_CTX_get0_md(md); + md_size = EVP_MD_get_size(digest); tl = ctx->buf_len - OK_BLOCK_BLOCK; ctx->buf[0] = (unsigned char)(tl >> 24); @@ -574,7 +563,9 @@ static int block_in(BIO *b) ctx = BIO_get_data(b); md = ctx->md; - md_size = EVP_MD_size(EVP_MD_CTX_md(md)); + md_size = EVP_MD_get_size(EVP_MD_CTX_get0_md(md)); + if (md_size < 0) + goto berr; assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */ tl = ctx->buf[0]; diff --git a/crypto/openssl/crypto/evp/build.info b/crypto/openssl/crypto/evp/build.info index cc33ac3c4942..95fea31226b0 100644 --- a/crypto/openssl/crypto/evp/build.info +++ b/crypto/openssl/crypto/evp/build.info @@ -1,25 +1,71 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - encode.c digest.c evp_enc.c evp_key.c evp_cnf.c \ - e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\ - e_rc4.c e_aes.c names.c e_seed.c e_aria.c e_sm4.c \ - e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \ - m_null.c m_md2.c m_md4.c m_md5.c m_sha1.c m_wp.c \ - m_md5_sha1.c m_mdc2.c m_ripemd.c m_sha3.c \ - p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \ +$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c evp_utils.c \ + mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c \ + m_sigver.c pmeth_lib.c signature.c p_lib.c pmeth_gn.c exchange.c \ + evp_rand.c asymcipher.c kem.c dh_support.c ec_support.c pmeth_check.c + +SOURCE[../../libcrypto]=$COMMON\ + encode.c evp_key.c evp_cnf.c \ + e_des.c e_bf.c e_idea.c e_des3.c \ + e_rc4.c e_aes.c names.c e_aria.c e_sm4.c \ + e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c m_null.c \ + p_seal.c p_sign.c p_verify.c p_legacy.c \ bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \ - c_allc.c c_alld.c evp_lib.c bio_ok.c \ + c_allc.c c_alld.c bio_ok.c \ evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \ - e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \ e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \ - e_chacha20_poly1305.c cmeth_lib.c + e_chacha20_poly1305.c \ + legacy_sha.c ctrl_params_translate.c \ + cmeth_lib.c + +# Diverse type specific ctrl functions. They are kinda sorta legacy, kinda +# sorta not. +SOURCE[../../libcrypto]=dh_ctrl.c dsa_ctrl.c ec_ctrl.c + +IF[{- !$disabled{'deprecated-3.0'} -}] + SOURCE[../../libcrypto]=p_enc.c p_dec.c +ENDIF +IF[{- !$disabled{'deprecated-0.9.8'} -}] + SOURCE[../../libcrypto]=e_old.c +ENDIF +IF[{- !$disabled{'rsa'} -}] + SOURCE[../../libcrypto]=p_open.c +ENDIF +IF[{- !$disabled{md2} -}] + SOURCE[../../libcrypto]=legacy_md2.c +ENDIF +IF[{- !$disabled{md4} -}] + SOURCE[../../libcrypto]=legacy_md4.c +ENDIF +IF[{- !$disabled{md5} -}] + SOURCE[../../libcrypto]=legacy_md5.c legacy_md5_sha1.c +ENDIF +IF[{- !$disabled{mdc2} -}] + SOURCE[../../libcrypto]=legacy_mdc2.c +ENDIF +IF[{- !$disabled{blake2} -}] + SOURCE[../../libcrypto]=legacy_blake2.c +ENDIF +IF[{- !$disabled{whirlpool} -}] + SOURCE[../../libcrypto]=legacy_wp.c +ENDIF +IF[{- !$disabled{rmd160} -}] + SOURCE[../../libcrypto]=legacy_ripemd.c +ENDIF +IF[{- !$disabled{seed} -}] + SOURCE[../../libcrypto]=e_seed.c +ENDIF +IF[{- !$disabled{camellia} -}] + SOURCE[../../libcrypto]=e_camellia.c + INCLUDE[e_camellia.o]=.. ../modes +ENDIF + +SOURCE[../../providers/libfips.a]=$COMMON INCLUDE[e_aes.o]=.. ../modes INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes INCLUDE[e_aes_cbc_hmac_sha256.o]=../modes INCLUDE[e_aria.o]=.. ../modes -INCLUDE[e_camellia.o]=.. ../modes INCLUDE[e_sm4.o]=.. ../modes INCLUDE[e_des.o]=.. INCLUDE[e_des3.o]=.. -INCLUDE[m_sha3.o]=.. diff --git a/crypto/openssl/crypto/evp/c_allc.c b/crypto/openssl/crypto/evp/c_allc.c index 22fdcc409c16..d556b5ab280a 100644 --- a/crypto/openssl/crypto/evp/c_allc.c +++ b/crypto/openssl/crypto/evp/c_allc.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -190,7 +190,6 @@ void openssl_add_all_ciphers_int(void) EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256()); - #ifndef OPENSSL_NO_ARIA EVP_add_cipher(EVP_aria_128_ecb()); EVP_add_cipher(EVP_aria_128_cbc()); diff --git a/crypto/openssl/crypto/evp/c_alld.c b/crypto/openssl/crypto/evp/c_alld.c index 16ac1b67f465..f7d62bd2ecff 100644 --- a/crypto/openssl/crypto/evp/c_alld.c +++ b/crypto/openssl/crypto/evp/c_alld.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/evp/cmeth_lib.c b/crypto/openssl/crypto/evp/cmeth_lib.c index 272e48249e42..a806ec5f9e22 100644 --- a/crypto/openssl/crypto/evp/cmeth_lib.c +++ b/crypto/openssl/crypto/evp/cmeth_lib.c @@ -1,59 +1,91 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * EVP _meth_ APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include "crypto/evp.h" +#include "internal/provider.h" #include "evp_local.h" EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len) { - EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER)); + EVP_CIPHER *cipher = evp_cipher_new(); if (cipher != NULL) { cipher->nid = cipher_type; cipher->block_size = block_size; cipher->key_len = key_len; + cipher->origin = EVP_ORIG_METH; } return cipher; } EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher) { - EVP_CIPHER *to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size, - cipher->key_len); + EVP_CIPHER *to = NULL; + + /* + * Non-legacy EVP_CIPHERs can't be duplicated like this. + * Use EVP_CIPHER_up_ref() instead. + */ + if (cipher->prov != NULL) + return NULL; + + if ((to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size, + cipher->key_len)) != NULL) { + CRYPTO_RWLOCK *lock = to->lock; - if (to != NULL) memcpy(to, cipher, sizeof(*to)); + to->lock = lock; + to->origin = EVP_ORIG_METH; + } return to; } void EVP_CIPHER_meth_free(EVP_CIPHER *cipher) { - OPENSSL_free(cipher); + if (cipher == NULL || cipher->origin != EVP_ORIG_METH) + return; + + evp_cipher_free_int(cipher); } int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len) { + if (cipher->iv_len != 0) + return 0; + cipher->iv_len = iv_len; return 1; } int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags) { + if (cipher->flags != 0) + return 0; + cipher->flags = flags; return 1; } int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size) { + if (cipher->ctx_size != 0) + return 0; + cipher->ctx_size = ctx_size; return 1; } @@ -64,6 +96,9 @@ int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, const unsigned char *iv, int enc)) { + if (cipher->init != NULL) + return 0; + cipher->init = init; return 1; } @@ -74,6 +109,9 @@ int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, const unsigned char *in, size_t inl)) { + if (cipher->do_cipher != NULL) + return 0; + cipher->do_cipher = do_cipher; return 1; } @@ -81,6 +119,9 @@ int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, int (*cleanup) (EVP_CIPHER_CTX *)) { + if (cipher->cleanup != NULL) + return 0; + cipher->cleanup = cleanup; return 1; } @@ -89,6 +130,9 @@ int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher, int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *)) { + if (cipher->set_asn1_parameters != NULL) + return 0; + cipher->set_asn1_parameters = set_asn1_parameters; return 1; } @@ -97,6 +141,9 @@ int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher, int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *)) { + if (cipher->get_asn1_parameters != NULL) + return 0; + cipher->get_asn1_parameters = get_asn1_parameters; return 1; } @@ -105,6 +152,9 @@ int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr)) { + if (cipher->ctrl != NULL) + return 0; + cipher->ctrl = ctrl; return 1; } diff --git a/crypto/openssl/crypto/evp/ctrl_params_translate.c b/crypto/openssl/crypto/evp/ctrl_params_translate.c new file mode 100644 index 000000000000..c767c316439d --- /dev/null +++ b/crypto/openssl/crypto/evp/ctrl_params_translate.c @@ -0,0 +1,2808 @@ +/* + * Copyright 2021-2022 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 + */ + +/* + * Some ctrls depend on deprecated functionality. We trust that this is + * functionality that remains internally even when 'no-deprecated' is + * configured. When we drop #legacy EVP_PKEYs, this source should be + * possible to drop as well. + */ +#include "internal/deprecated.h" + +#include + +/* The following includes get us all the EVP_PKEY_CTRL macros */ +#include +#include +#include +#include +#include + +/* This include gets us all the OSSL_PARAM key string macros */ +#include + +#include +#include +#include +#include "internal/nelem.h" +#include "internal/cryptlib.h" +#include "internal/ffc.h" +#include "crypto/evp.h" +#include "crypto/dh.h" +#include "crypto/ec.h" + +struct translation_ctx_st; /* Forwarding */ +struct translation_st; /* Forwarding */ + +/* + * The fixup_args functions are called with the following parameters: + * + * |state| The state we're called in, explained further at the + * end of this comment. + * |translation| The translation item, to be pilfered for data as + * necessary. + * |ctx| The translation context, which contains copies of + * the following arguments, applicable according to + * the caller. All of the attributes in this context + * may be freely modified by the fixup_args function. + * For cleanup, call cleanup_translation_ctx(). + * + * The |state| tells the fixup_args function something about the caller and + * what they may expect: + * + * PKEY The fixup_args function has been called + * from an EVP_PKEY payload getter / setter, + * and is fully responsible for getting or + * setting the requested data. With this + * state, the fixup_args function is expected + * to use or modify |*params|, depending on + * |action_type|. + * + * PRE_CTRL_TO_PARAMS The fixup_args function has been called + * POST_CTRL_TO_PARAMS from EVP_PKEY_CTX_ctrl(), to help with + * translating the ctrl data to an OSSL_PARAM + * element or back. The calling sequence is + * as follows: + * + * 1. fixup_args(PRE_CTRL_TO_PARAMS, ...) + * 2. EVP_PKEY_CTX_set_params() or + * EVP_PKEY_CTX_get_params() + * 3. fixup_args(POST_CTRL_TO_PARAMS, ...) + * + * With the PRE_CTRL_TO_PARAMS state, the + * fixup_args function is expected to modify + * the passed |*params| in whatever way + * necessary, when |action_type == SET|. + * With the POST_CTRL_TO_PARAMS state, the + * fixup_args function is expected to modify + * the passed |p2| in whatever way necessary, + * when |action_type == GET|. + * + * The return value from the fixup_args call + * with the POST_CTRL_TO_PARAMS state becomes + * the return value back to EVP_PKEY_CTX_ctrl(). + * + * CLEANUP_CTRL_TO_PARAMS The cleanup_args functions has been called + * from EVP_PKEY_CTX_ctrl(), to clean up what + * the fixup_args function has done, if needed. + * + * + * PRE_CTRL_STR_TO_PARAMS The fixup_args function has been called + * POST_CTRL_STR_TO_PARAMS from EVP_PKEY_CTX_ctrl_str(), to help with + * translating the ctrl_str data to an + * OSSL_PARAM element or back. The calling + * sequence is as follows: + * + * 1. fixup_args(PRE_CTRL_STR_TO_PARAMS, ...) + * 2. EVP_PKEY_CTX_set_params() or + * EVP_PKEY_CTX_get_params() + * 3. fixup_args(POST_CTRL_STR_TO_PARAMS, ...) + * + * With the PRE_CTRL_STR_TO_PARAMS state, + * the fixup_args function is expected to + * modify the passed |*params| in whatever + * way necessary, when |action_type == SET|. + * With the POST_CTRL_STR_TO_PARAMS state, + * the fixup_args function is only expected + * to return a value. + * + * CLEANUP_CTRL_STR_TO_PARAMS The cleanup_args functions has been called + * from EVP_PKEY_CTX_ctrl_str(), to clean up + * what the fixup_args function has done, if + * needed. + * + * PRE_PARAMS_TO_CTRL The fixup_args function has been called + * POST_PARAMS_TO_CTRL from EVP_PKEY_CTX_get_params() or + * EVP_PKEY_CTX_set_params(), to help with + * translating the OSSL_PARAM data to the + * corresponding EVP_PKEY_CTX_ctrl() arguments + * or the other way around. The calling + * sequence is as follows: + * + * 1. fixup_args(PRE_PARAMS_TO_CTRL, ...) + * 2. EVP_PKEY_CTX_ctrl() + * 3. fixup_args(POST_PARAMS_TO_CTRL, ...) + * + * With the PRE_PARAMS_TO_CTRL state, the + * fixup_args function is expected to modify + * the passed |p1| and |p2| in whatever way + * necessary, when |action_type == SET|. + * With the POST_PARAMS_TO_CTRL state, the + * fixup_args function is expected to + * modify the passed |*params| in whatever + * way necessary, when |action_type == GET|. + * + * CLEANUP_PARAMS_TO_CTRL The cleanup_args functions has been called + * from EVP_PKEY_CTX_get_params() or + * EVP_PKEY_CTX_set_params(), to clean up what + * the fixup_args function has done, if needed. + */ +enum state { + PKEY, + PRE_CTRL_TO_PARAMS, POST_CTRL_TO_PARAMS, CLEANUP_CTRL_TO_PARAMS, + PRE_CTRL_STR_TO_PARAMS, POST_CTRL_STR_TO_PARAMS, CLEANUP_CTRL_STR_TO_PARAMS, + PRE_PARAMS_TO_CTRL, POST_PARAMS_TO_CTRL, CLEANUP_PARAMS_TO_CTRL +}; +enum action { + NONE = 0, GET = 1, SET = 2 +}; +typedef int fixup_args_fn(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx); +typedef int cleanup_args_fn(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx); + +struct translation_ctx_st { + /* + * The EVP_PKEY_CTX, for calls on that structure, to be pilfered for data + * as necessary. + */ + EVP_PKEY_CTX *pctx; + /* + * The action type (GET or SET). This may be 0 in some cases, and should + * be modified by the fixup_args function in the PRE states. It should + * otherwise remain untouched once set. + */ + enum action action_type; + /* + * For ctrl to params translation, the actual ctrl command number used. + * For params to ctrl translation, 0. + */ + int ctrl_cmd; + /* + * For ctrl_str to params translation, the actual ctrl command string + * used. In this case, the (string) value is always passed as |p2|. + * For params to ctrl translation, this is NULL. Along with it is also + * and indicator whether it matched |ctrl_str| or |ctrl_hexstr| in the + * translation item. + */ + const char *ctrl_str; + int ishex; + /* the ctrl-style int argument. */ + int p1; + /* the ctrl-style void* argument. */ + void *p2; + /* a size, for passing back the |p2| size where applicable */ + size_t sz; + /* pointer to the OSSL_PARAM-style params array. */ + OSSL_PARAM *params; + + /*- + * The following are used entirely internally by the fixup_args functions + * and should not be touched by the callers, at all. + */ + + /* + * Copy of the ctrl-style void* argument, if the fixup_args function + * needs to manipulate |p2| but wants to remember original. + */ + void *orig_p2; + /* Diverse types of storage for the needy. */ + char name_buf[OSSL_MAX_NAME_SIZE]; + void *allocated_buf; + void *bufp; + size_t buflen; +}; + +struct translation_st { + /*- + * What this table item does. + * + * If the item has this set to 0, it means that both GET and SET are + * supported, and |fixup_args| will determine which it is. This is to + * support translations of ctrls where the action type depends on the + * value of |p1| or |p2| (ctrls are really bi-directional, but are + * seldom used that way). + * + * This can be also used in the lookup template when it looks up by + * OSSL_PARAM key, to indicate if a setter or a getter called. + */ + enum action action_type; + + /*- + * Conditions, for params->ctrl translations. + * + * In table item, |keytype1| and |keytype2| can be set to -1 to indicate + * that this item supports all key types (or rather, that |fixup_args| + * will check and return an error if it's not supported). + * Any of these may be set to 0 to indicate that they are unset. + */ + int keytype1; /* The EVP_PKEY_XXX type, i.e. NIDs. #legacy */ + int keytype2; /* Another EVP_PKEY_XXX type, used for aliases */ + int optype; /* The operation type */ + + /* + * Lookup and translation attributes + * + * |ctrl_num|, |ctrl_str|, |ctrl_hexstr| and |param_key| are lookup + * attributes. + * + * |ctrl_num| may be 0 or that |param_key| may be NULL in the table item, + * but not at the same time. If they are, they are simply not used for + * lookup. + * When |ctrl_num| == 0, no ctrl will be called. Likewise, when + * |param_key| == NULL, no OSSL_PARAM setter/getter will be called. + * In that case the treatment of the translation item relies entirely on + * |fixup_args|, which is then assumed to have side effects. + * + * As a special case, it's possible to set |ctrl_hexstr| and assign NULL + * to |ctrl_str|. That will signal to default_fixup_args() that the + * value must always be interpreted as hex. + */ + int ctrl_num; /* EVP_PKEY_CTRL_xxx */ + const char *ctrl_str; /* The corresponding ctrl string */ + const char *ctrl_hexstr; /* The alternative "hex{str}" ctrl string */ + const char *param_key; /* The corresponding OSSL_PARAM key */ + /* + * The appropriate OSSL_PARAM data type. This may be 0 to indicate that + * this OSSL_PARAM may have more than one data type, depending on input + * material. In this case, |fixup_args| is expected to check and handle + * it. + */ + unsigned int param_data_type; + + /* + * Fixer functions + * + * |fixup_args| is always called before (for SET) or after (for GET) + * the actual ctrl / OSSL_PARAM function. + */ + fixup_args_fn *fixup_args; +}; + +/*- + * Fixer function implementations + * ============================== + */ + +/* + * default_check isn't a fixer per se, but rather a helper function to + * perform certain standard checks. + */ +static int default_check(enum state state, + const struct translation_st *translation, + const struct translation_ctx_st *ctx) +{ + switch (state) { + default: + break; + case PRE_CTRL_TO_PARAMS: + if (!ossl_assert(translation != NULL)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (!ossl_assert(translation->param_key != 0) + || !ossl_assert(translation->param_data_type != 0)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return -1; + } + break; + case PRE_CTRL_STR_TO_PARAMS: + /* + * For ctrl_str to params translation, we allow direct use of + * OSSL_PARAM keys as ctrl_str keys. Therefore, it's possible that + * we end up with |translation == NULL|, which is fine. The fixup + * function will have to deal with it carefully. + */ + if (translation != NULL) { + if (!ossl_assert(translation->action_type != GET)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (!ossl_assert(translation->param_key != NULL) + || !ossl_assert(translation->param_data_type != 0)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + } + break; + case PRE_PARAMS_TO_CTRL: + case POST_PARAMS_TO_CTRL: + if (!ossl_assert(translation != NULL)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (!ossl_assert(translation->ctrl_num != 0) + || !ossl_assert(translation->param_data_type != 0)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return -1; + } + } + + /* Nothing else to check */ + return 1; +} + +/*- + * default_fixup_args fixes up all sorts of arguments, governed by the + * diverse attributes in the translation item. It covers all "standard" + * base ctrl functionality, meaning it can handle basic conversion of + * data between p1+p2 (SET) or return value+p2 (GET) as long as the values + * don't have extra semantics (such as NIDs, OIDs, that sort of stuff). + * Extra semantics must be handled via specific fixup_args functions. + * + * The following states and action type combinations have standard handling + * done in this function: + * + * PRE_CTRL_TO_PARAMS, 0 - ERROR. action type must be + * determined by a fixup function. + * PRE_CTRL_TO_PARAMS, SET | GET - |p1| and |p2| are converted to an + * OSSL_PARAM according to the data + * type given in |translattion|. + * For OSSL_PARAM_UNSIGNED_INTEGER, + * a BIGNUM passed as |p2| is accepted. + * POST_CTRL_TO_PARAMS, GET - If the OSSL_PARAM data type is a + * STRING or PTR type, |p1| is set + * to the OSSL_PARAM return size, and + * |p2| is set to the string. + * PRE_CTRL_STR_TO_PARAMS, !SET - ERROR. That combination is not + * supported. + * PRE_CTRL_STR_TO_PARAMS, SET - |p2| is taken as a string, and is + * converted to an OSSL_PARAM in a + * standard manner, guided by the + * param key and data type from + * |translation|. + * PRE_PARAMS_TO_CTRL, SET - the OSSL_PARAM is converted to + * |p1| and |p2| according to the + * data type given in |translation| + * For OSSL_PARAM_UNSIGNED_INTEGER, + * if |p2| is non-NULL, then |*p2| + * is assigned a BIGNUM, otherwise + * |p1| is assigned an unsigned int. + * POST_PARAMS_TO_CTRL, GET - |p1| and |p2| are converted to + * an OSSL_PARAM, in the same manner + * as for the combination of + * PRE_CTRL_TO_PARAMS, SET. + */ +static int default_fixup_args(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + int ret; + + if ((ret = default_check(state, translation, ctx)) < 0) + return ret; + + switch (state) { + default: + /* For states this function should never have been called with */ + ERR_raise_data(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, + "[action:%d, state:%d]", ctx->action_type, state); + return 0; + + /* + * PRE_CTRL_TO_PARAMS and POST_CTRL_TO_PARAMS handle ctrl to params + * translations. PRE_CTRL_TO_PARAMS is responsible for preparing + * |*params|, and POST_CTRL_TO_PARAMS is responsible for bringing the + * result back to |*p2| and the return value. + */ + case PRE_CTRL_TO_PARAMS: + /* This is ctrl to params translation, so we need an OSSL_PARAM key */ + if (ctx->action_type == NONE) { + /* + * No action type is an error here. That's a case for a + * special fixup function. + */ + ERR_raise_data(ERR_LIB_EVP, ERR_R_UNSUPPORTED, + "[action:%d, state:%d]", ctx->action_type, state); + return 0; + } + + if (translation->optype != 0) { + if ((EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx) + && ctx->pctx->op.sig.algctx == NULL) + || (EVP_PKEY_CTX_IS_DERIVE_OP(ctx->pctx) + && ctx->pctx->op.kex.algctx == NULL) + || (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx->pctx) + && ctx->pctx->op.ciph.algctx == NULL) + || (EVP_PKEY_CTX_IS_KEM_OP(ctx->pctx) + && ctx->pctx->op.encap.algctx == NULL) + /* + * The following may be unnecessary, but we have them + * for good measure... + */ + || (EVP_PKEY_CTX_IS_GEN_OP(ctx->pctx) + && ctx->pctx->op.keymgmt.genctx == NULL) + || (EVP_PKEY_CTX_IS_FROMDATA_OP(ctx->pctx) + && ctx->pctx->op.keymgmt.genctx == NULL)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + } + + /* + * OSSL_PARAM_construct_TYPE() works equally well for both SET and GET. + */ + switch (translation->param_data_type) { + case OSSL_PARAM_INTEGER: + *ctx->params = OSSL_PARAM_construct_int(translation->param_key, + &ctx->p1); + break; + case OSSL_PARAM_UNSIGNED_INTEGER: + /* + * BIGNUMs are passed via |p2|. For all ctrl's that just want + * to pass a simple integer via |p1|, |p2| is expected to be + * NULL. + * + * Note that this allocates a buffer, which the cleanup function + * must deallocate. + */ + if (ctx->p2 != NULL) { + if (ctx->action_type == SET) { + ctx->buflen = BN_num_bytes(ctx->p2); + if ((ctx->allocated_buf = + OPENSSL_malloc(ctx->buflen)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + if (BN_bn2nativepad(ctx->p2, + ctx->allocated_buf, ctx->buflen) < 0) { + OPENSSL_free(ctx->allocated_buf); + ctx->allocated_buf = NULL; + return 0; + } + *ctx->params = + OSSL_PARAM_construct_BN(translation->param_key, + ctx->allocated_buf, + ctx->buflen); + } else { + /* + * No support for getting a BIGNUM by ctrl, this needs + * fixup_args function support. + */ + ERR_raise_data(ERR_LIB_EVP, ERR_R_UNSUPPORTED, + "[action:%d, state:%d] trying to get a " + "BIGNUM via ctrl call", + ctx->action_type, state); + return 0; + } + } else { + *ctx->params = + OSSL_PARAM_construct_uint(translation->param_key, + (unsigned int *)&ctx->p1); + } + break; + case OSSL_PARAM_UTF8_STRING: + *ctx->params = + OSSL_PARAM_construct_utf8_string(translation->param_key, + ctx->p2, (size_t)ctx->p1); + break; + case OSSL_PARAM_UTF8_PTR: + *ctx->params = + OSSL_PARAM_construct_utf8_ptr(translation->param_key, + ctx->p2, (size_t)ctx->p1); + break; + case OSSL_PARAM_OCTET_STRING: + *ctx->params = + OSSL_PARAM_construct_octet_string(translation->param_key, + ctx->p2, (size_t)ctx->p1); + break; + case OSSL_PARAM_OCTET_PTR: + *ctx->params = + OSSL_PARAM_construct_octet_ptr(translation->param_key, + ctx->p2, (size_t)ctx->p1); + break; + } + break; + case POST_CTRL_TO_PARAMS: + /* + * Because EVP_PKEY_CTX_ctrl() returns the length of certain objects + * as its return value, we need to ensure that we do it here as well, + * for the OSSL_PARAM data types where this makes sense. + */ + if (ctx->action_type == GET) { + switch (translation->param_data_type) { + case OSSL_PARAM_UTF8_STRING: + case OSSL_PARAM_UTF8_PTR: + case OSSL_PARAM_OCTET_STRING: + case OSSL_PARAM_OCTET_PTR: + ctx->p1 = (int)ctx->params[0].return_size; + break; + } + } + break; + + /* + * PRE_CTRL_STR_TO_PARAMS and POST_CTRL_STR_TO_PARAMS handle ctrl_str to + * params translations. PRE_CTRL_TO_PARAMS is responsible for preparing + * |*params|, and POST_CTRL_TO_PARAMS currently has nothing to do, since + * there's no support for getting data via ctrl_str calls. + */ + case PRE_CTRL_STR_TO_PARAMS: + { + /* This is ctrl_str to params translation */ + const char *tmp_ctrl_str = ctx->ctrl_str; + const char *orig_ctrl_str = ctx->ctrl_str; + const char *orig_value = ctx->p2; + const OSSL_PARAM *settable = NULL; + int exists = 0; + + /* Only setting is supported here */ + if (ctx->action_type != SET) { + ERR_raise_data(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED, + "[action:%d, state:%d] only setting allowed", + ctx->action_type, state); + return 0; + } + + /* + * If no translation exists, we simply pass the control string + * unmodified. + */ + if (translation != NULL) { + tmp_ctrl_str = ctx->ctrl_str = translation->param_key; + + if (ctx->ishex) { + strcpy(ctx->name_buf, "hex"); + if (OPENSSL_strlcat(ctx->name_buf, tmp_ctrl_str, + sizeof(ctx->name_buf)) <= 3) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return -1; + } + tmp_ctrl_str = ctx->name_buf; + } + } + + settable = EVP_PKEY_CTX_settable_params(ctx->pctx); + if (!OSSL_PARAM_allocate_from_text(ctx->params, settable, + tmp_ctrl_str, + ctx->p2, strlen(ctx->p2), + &exists)) { + if (!exists) { + ERR_raise_data(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED, + "[action:%d, state:%d] name=%s, value=%s", + ctx->action_type, state, + orig_ctrl_str, orig_value); + return -2; + } + return 0; + } + ctx->allocated_buf = ctx->params->data; + ctx->buflen = ctx->params->data_size; + } + break; + case POST_CTRL_STR_TO_PARAMS: + /* Nothing to be done */ + break; + + /* + * PRE_PARAMS_TO_CTRL and POST_PARAMS_TO_CTRL handle params to ctrl + * translations. PRE_PARAMS_TO_CTRL is responsible for preparing + * |p1| and |p2|, and POST_PARAMS_TO_CTRL is responsible for bringing + * the EVP_PKEY_CTX_ctrl() return value (passed as |p1|) and |p2| back + * to |*params|. + * + * PKEY is treated just like POST_PARAMS_TO_CTRL, making it easy + * for the related fixup_args functions to just set |p1| and |p2| + * appropriately and leave it to this section of code to fix up + * |ctx->params| accordingly. + */ + case PKEY: + case POST_PARAMS_TO_CTRL: + ret = ctx->p1; + /* FALLTHRU */ + case PRE_PARAMS_TO_CTRL: + { + /* This is params to ctrl translation */ + if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == SET) { + /* For the PRE state, only setting needs some work to be done */ + + /* When setting, we populate |p1| and |p2| from |*params| */ + switch (translation->param_data_type) { + case OSSL_PARAM_INTEGER: + return OSSL_PARAM_get_int(ctx->params, &ctx->p1); + case OSSL_PARAM_UNSIGNED_INTEGER: + if (ctx->p2 != NULL) { + /* BIGNUM passed down with p2 */ + if (!OSSL_PARAM_get_BN(ctx->params, ctx->p2)) + return 0; + } else { + /* Normal C unsigned int passed down */ + if (!OSSL_PARAM_get_uint(ctx->params, + (unsigned int *)&ctx->p1)) + return 0; + } + return 1; + case OSSL_PARAM_UTF8_STRING: + return OSSL_PARAM_get_utf8_string(ctx->params, + ctx->p2, ctx->sz); + case OSSL_PARAM_OCTET_STRING: + return OSSL_PARAM_get_octet_string(ctx->params, + ctx->p2, ctx->sz, + &ctx->sz); + case OSSL_PARAM_OCTET_PTR: + return OSSL_PARAM_get_octet_ptr(ctx->params, + ctx->p2, &ctx->sz); + default: + ERR_raise_data(ERR_LIB_EVP, ERR_R_UNSUPPORTED, + "[action:%d, state:%d] " + "unknown OSSL_PARAM data type %d", + ctx->action_type, state, + translation->param_data_type); + return 0; + } + } else if ((state == POST_PARAMS_TO_CTRL || state == PKEY) + && ctx->action_type == GET) { + /* For the POST state, only getting needs some work to be done */ + unsigned int param_data_type = translation->param_data_type; + size_t size = (size_t)ctx->p1; + + if (state == PKEY) + size = ctx->sz; + if (param_data_type == 0) { + /* we must have a fixup_args function to work */ + if (!ossl_assert(translation->fixup_args != NULL)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + param_data_type = ctx->params->data_type; + } + /* When getting, we populate |*params| from |p1| and |p2| */ + switch (param_data_type) { + case OSSL_PARAM_INTEGER: + return OSSL_PARAM_set_int(ctx->params, ctx->p1); + case OSSL_PARAM_UNSIGNED_INTEGER: + if (ctx->p2 != NULL) { + /* BIGNUM passed back */ + return OSSL_PARAM_set_BN(ctx->params, ctx->p2); + } else { + /* Normal C unsigned int passed back */ + return OSSL_PARAM_set_uint(ctx->params, + (unsigned int)ctx->p1); + } + return 0; + case OSSL_PARAM_UTF8_STRING: + return OSSL_PARAM_set_utf8_string(ctx->params, ctx->p2); + case OSSL_PARAM_OCTET_STRING: + return OSSL_PARAM_set_octet_string(ctx->params, ctx->p2, + size); + case OSSL_PARAM_OCTET_PTR: + return OSSL_PARAM_set_octet_ptr(ctx->params, ctx->p2, + size); + default: + ERR_raise_data(ERR_LIB_EVP, ERR_R_UNSUPPORTED, + "[action:%d, state:%d] " + "unsupported OSSL_PARAM data type %d", + ctx->action_type, state, + translation->param_data_type); + return 0; + } + } + } + /* Any other combination is simply pass-through */ + break; + } + return ret; +} + +static int +cleanup_translation_ctx(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + if (ctx->allocated_buf != NULL) + OPENSSL_free(ctx->allocated_buf); + ctx->allocated_buf = NULL; + return 1; +} + +/* + * fix_cipher_md fixes up an EVP_CIPHER / EVP_MD to its name on SET, + * and cipher / md name to EVP_MD on GET. + */ +static const char *get_cipher_name(void *cipher) +{ + return EVP_CIPHER_get0_name(cipher); +} + +static const char *get_md_name(void *md) +{ + return EVP_MD_get0_name(md); +} + +static const void *get_cipher_by_name(OSSL_LIB_CTX *libctx, const char *name) +{ + return evp_get_cipherbyname_ex(libctx, name); +} + +static const void *get_md_by_name(OSSL_LIB_CTX *libctx, const char *name) +{ + return evp_get_digestbyname_ex(libctx, name); +} + +static int fix_cipher_md(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx, + const char *(*get_name)(void *algo), + const void *(*get_algo_by_name)(OSSL_LIB_CTX *libctx, + const char *name)) +{ + int ret = 1; + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == GET) { + /* + * |ctx->p2| contains the address to an EVP_CIPHER or EVP_MD pointer + * to be filled in. We need to remember it, then make |ctx->p2| + * point at a buffer to be filled in with the name, and |ctx->p1| + * with its size. default_fixup_args() will take care of the rest + * for us. + */ + ctx->orig_p2 = ctx->p2; + ctx->p2 = ctx->name_buf; + ctx->p1 = sizeof(ctx->name_buf); + } else if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == SET) { + /* + * In different parts of OpenSSL, this ctrl command is used + * differently. Some calls pass a NID as p1, others pass an + * EVP_CIPHER pointer as p2... + */ + ctx->p2 = (char *)(ctx->p2 == NULL + ? OBJ_nid2sn(ctx->p1) + : get_name(ctx->p2)); + ctx->p1 = strlen(ctx->p2); + } else if (state == POST_PARAMS_TO_CTRL && ctx->action_type == GET) { + ctx->p2 = (ctx->p2 == NULL ? "" : (char *)get_name(ctx->p2)); + ctx->p1 = strlen(ctx->p2); + } + + if ((ret = default_fixup_args(state, translation, ctx)) <= 0) + return ret; + + if (state == POST_CTRL_TO_PARAMS && ctx->action_type == GET) { + /* + * Here's how we re-use |ctx->orig_p2| that was set in the + * PRE_CTRL_TO_PARAMS state above. + */ + *(void **)ctx->orig_p2 = + (void *)get_algo_by_name(ctx->pctx->libctx, ctx->p2); + ctx->p1 = 1; + } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == SET) { + ctx->p2 = (void *)get_algo_by_name(ctx->pctx->libctx, ctx->p2); + ctx->p1 = 0; + } + + return ret; +} + +static int fix_cipher(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + return fix_cipher_md(state, translation, ctx, + get_cipher_name, get_cipher_by_name); +} + +static int fix_md(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + return fix_cipher_md(state, translation, ctx, + get_md_name, get_md_by_name); +} + +static int fix_distid_len(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + int ret = default_fixup_args(state, translation, ctx); + + if (ret > 0) { + ret = 0; + if ((state == POST_CTRL_TO_PARAMS + || state == POST_CTRL_STR_TO_PARAMS) && ctx->action_type == GET) { + *(size_t *)ctx->p2 = ctx->sz; + ret = 1; + } + } + return ret; +} + +struct kdf_type_map_st { + int kdf_type_num; + const char *kdf_type_str; +}; + +static int fix_kdf_type(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx, + const struct kdf_type_map_st *kdf_type_map) +{ + /* + * The EVP_PKEY_CTRL_DH_KDF_TYPE ctrl command is a bit special, in + * that it's used both for setting a value, and for getting it, all + * depending on the value if |p1|; if |p1| is -2, the backend is + * supposed to place the current kdf type in |p2|, and if not, |p1| + * is interpreted as the new kdf type. + */ + int ret = 0; + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + if (state == PRE_CTRL_TO_PARAMS) { + /* + * In |translations|, the initial value for |ctx->action_type| must + * be NONE. + */ + if (!ossl_assert(ctx->action_type == NONE)) + return 0; + + /* The action type depends on the value of *p1 */ + if (ctx->p1 == -2) { + /* + * The OSSL_PARAMS getter needs space to store a copy of the kdf + * type string. We use |ctx->name_buf|, which has enough space + * allocated. + * + * (this wouldn't be needed if the OSSL_xxx_PARAM_KDF_TYPE + * had the data type OSSL_PARAM_UTF8_PTR) + */ + ctx->p2 = ctx->name_buf; + ctx->p1 = sizeof(ctx->name_buf); + ctx->action_type = GET; + } else { + ctx->action_type = SET; + } + } + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + if ((state == PRE_CTRL_TO_PARAMS && ctx->action_type == SET) + || (state == POST_PARAMS_TO_CTRL && ctx->action_type == GET)) { + ret = -2; + /* Convert KDF type numbers to strings */ + for (; kdf_type_map->kdf_type_str != NULL; kdf_type_map++) + if (ctx->p1 == kdf_type_map->kdf_type_num) { + ctx->p2 = (char *)kdf_type_map->kdf_type_str; + ret = 1; + break; + } + if (ret <= 0) + goto end; + ctx->p1 = strlen(ctx->p2); + } + + if ((ret = default_fixup_args(state, translation, ctx)) <= 0) + return ret; + + if ((state == POST_CTRL_TO_PARAMS && ctx->action_type == GET) + || (state == PRE_PARAMS_TO_CTRL && ctx->action_type == SET)) { + ctx->p1 = ret = -1; + + /* Convert KDF type strings to numbers */ + for (; kdf_type_map->kdf_type_str != NULL; kdf_type_map++) + if (OPENSSL_strcasecmp(ctx->p2, kdf_type_map->kdf_type_str) == 0) { + ctx->p1 = kdf_type_map->kdf_type_num; + ret = 1; + break; + } + ctx->p2 = NULL; + } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == GET) { + ctx->p1 = -2; + } + end: + return ret; +} + +/* EVP_PKEY_CTRL_DH_KDF_TYPE */ +static int fix_dh_kdf_type(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + static const struct kdf_type_map_st kdf_type_map[] = { + { EVP_PKEY_DH_KDF_NONE, "" }, + { EVP_PKEY_DH_KDF_X9_42, OSSL_KDF_NAME_X942KDF_ASN1 }, + { 0, NULL } + }; + + return fix_kdf_type(state, translation, ctx, kdf_type_map); +} + +/* EVP_PKEY_CTRL_EC_KDF_TYPE */ +static int fix_ec_kdf_type(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + static const struct kdf_type_map_st kdf_type_map[] = { + { EVP_PKEY_ECDH_KDF_NONE, "" }, + { EVP_PKEY_ECDH_KDF_X9_63, OSSL_KDF_NAME_X963KDF }, + { 0, NULL } + }; + + return fix_kdf_type(state, translation, ctx, kdf_type_map); +} + +/* EVP_PKEY_CTRL_DH_KDF_OID, EVP_PKEY_CTRL_GET_DH_KDF_OID, ...??? */ +static int fix_oid(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + int ret; + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + if ((state == PRE_CTRL_TO_PARAMS && ctx->action_type == SET) + || (state == POST_PARAMS_TO_CTRL && ctx->action_type == GET)) { + /* + * We're translating from ctrl to params and setting the OID, or + * we're translating from params to ctrl and getting the OID. + * Either way, |ctx->p2| points at an ASN1_OBJECT, and needs to have + * that replaced with the corresponding name. + * default_fixup_args() will then be able to convert that to the + * corresponding OSSL_PARAM. + */ + OBJ_obj2txt(ctx->name_buf, sizeof(ctx->name_buf), ctx->p2, 0); + ctx->p2 = (char *)ctx->name_buf; + ctx->p1 = 0; /* let default_fixup_args() figure out the length */ + } + + if ((ret = default_fixup_args(state, translation, ctx)) <= 0) + return ret; + + if ((state == PRE_PARAMS_TO_CTRL && ctx->action_type == SET) + || (state == POST_CTRL_TO_PARAMS && ctx->action_type == GET)) { + /* + * We're translating from ctrl to params and setting the OID name, + * or we're translating from params to ctrl and getting the OID + * name. Either way, default_fixup_args() has placed the OID name + * in |ctx->p2|, all we need to do now is to replace that with the + * corresponding ASN1_OBJECT. + */ + ctx->p2 = (ASN1_OBJECT *)OBJ_txt2obj(ctx->p2, 0); + } + + return ret; +} + +/* EVP_PKEY_CTRL_DH_NID */ +static int fix_dh_nid(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + int ret; + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + /* This is only settable */ + if (ctx->action_type != SET) + return 0; + + if (state == PRE_CTRL_TO_PARAMS) { + if ((ctx->p2 = (char *)ossl_ffc_named_group_get_name + (ossl_ffc_uid_to_dh_named_group(ctx->p1))) == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } + ctx->p1 = 0; + } + + return default_fixup_args(state, translation, ctx); +} + +/* EVP_PKEY_CTRL_DH_RFC5114 */ +static int fix_dh_nid5114(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + int ret; + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + /* This is only settable */ + if (ctx->action_type != SET) + return 0; + + switch (state) { + case PRE_CTRL_TO_PARAMS: + if ((ctx->p2 = (char *)ossl_ffc_named_group_get_name + (ossl_ffc_uid_to_dh_named_group(ctx->p1))) == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } + + ctx->p1 = 0; + break; + + case PRE_CTRL_STR_TO_PARAMS: + if (ctx->p2 == NULL) + return 0; + if ((ctx->p2 = (char *)ossl_ffc_named_group_get_name + (ossl_ffc_uid_to_dh_named_group(atoi(ctx->p2)))) == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } + + ctx->p1 = 0; + break; + + default: + break; + } + + return default_fixup_args(state, translation, ctx); +} + +/* EVP_PKEY_CTRL_DH_PARAMGEN_TYPE */ +static int fix_dh_paramgen_type(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + int ret; + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + /* This is only settable */ + if (ctx->action_type != SET) + return 0; + + if (state == PRE_CTRL_STR_TO_PARAMS) { + if ((ctx->p2 = (char *)ossl_dh_gen_type_id2name(atoi(ctx->p2))) + == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } + ctx->p1 = strlen(ctx->p2); + } + + return default_fixup_args(state, translation, ctx); +} + +/* EVP_PKEY_CTRL_EC_PARAM_ENC */ +static int fix_ec_param_enc(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + int ret; + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + /* This is currently only settable */ + if (ctx->action_type != SET) + return 0; + + if (state == PRE_CTRL_TO_PARAMS) { + switch (ctx->p1) { + case OPENSSL_EC_EXPLICIT_CURVE: + ctx->p2 = OSSL_PKEY_EC_ENCODING_EXPLICIT; + break; + case OPENSSL_EC_NAMED_CURVE: + ctx->p2 = OSSL_PKEY_EC_ENCODING_GROUP; + break; + default: + ret = -2; + goto end; + } + ctx->p1 = 0; + } + + if ((ret = default_fixup_args(state, translation, ctx)) <= 0) + return ret; + + if (state == PRE_PARAMS_TO_CTRL) { + if (strcmp(ctx->p2, OSSL_PKEY_EC_ENCODING_EXPLICIT) == 0) + ctx->p1 = OPENSSL_EC_EXPLICIT_CURVE; + else if (strcmp(ctx->p2, OSSL_PKEY_EC_ENCODING_GROUP) == 0) + ctx->p1 = OPENSSL_EC_NAMED_CURVE; + else + ctx->p1 = ret = -2; + ctx->p2 = NULL; + } + + end: + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return ret; +} + +/* EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID */ +static int fix_ec_paramgen_curve_nid(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + int ret; + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + /* This is currently only settable */ + if (ctx->action_type != SET) + return 0; + + if (state == PRE_CTRL_TO_PARAMS) { + ctx->p2 = (char *)OBJ_nid2sn(ctx->p1); + ctx->p1 = 0; + } + + if ((ret = default_fixup_args(state, translation, ctx)) <= 0) + return ret; + + if (state == PRE_PARAMS_TO_CTRL) { + ctx->p1 = OBJ_sn2nid(ctx->p2); + ctx->p2 = NULL; + } + + return ret; +} + +/* EVP_PKEY_CTRL_EC_ECDH_COFACTOR */ +static int fix_ecdh_cofactor(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + /* + * The EVP_PKEY_CTRL_EC_ECDH_COFACTOR ctrl command is a bit special, in + * that it's used both for setting a value, and for getting it, all + * depending on the value if |ctx->p1|; if |ctx->p1| is -2, the backend is + * supposed to place the current cofactor mode in |ctx->p2|, and if not, + * |ctx->p1| is interpreted as the new cofactor mode. + */ + int ret = 0; + + if (state == PRE_CTRL_TO_PARAMS) { + /* + * The initial value for |ctx->action_type| must be zero. + * evp_pkey_ctrl_to_params() takes it from the translation item. + */ + if (!ossl_assert(ctx->action_type == NONE)) + return 0; + + /* The action type depends on the value of ctx->p1 */ + if (ctx->p1 == -2) + ctx->action_type = GET; + else + ctx->action_type = SET; + } else if (state == PRE_CTRL_STR_TO_PARAMS) { + ctx->action_type = SET; + } else if (state == PRE_PARAMS_TO_CTRL) { + /* The initial value for |ctx->action_type| must not be zero. */ + if (!ossl_assert(ctx->action_type != NONE)) + return 0; + } + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == SET) { + if (ctx->p1 < -1 || ctx->p1 > 1) { + /* Uses the same return value of pkey_ec_ctrl() */ + return -2; + } + } + + if ((ret = default_fixup_args(state, translation, ctx)) <= 0) + return ret; + + if (state == POST_CTRL_TO_PARAMS && ctx->action_type == GET) { + if (ctx->p1 < 0 || ctx->p1 > 1) { + /* + * The provider should return either 0 or 1, any other value is a + * provider error. + */ + ctx->p1 = ret = -1; + } + } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == GET) { + ctx->p1 = -2; + } + + return ret; +} + +/* EVP_PKEY_CTRL_RSA_PADDING, EVP_PKEY_CTRL_GET_RSA_PADDING */ +static int fix_rsa_padding_mode(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + static const OSSL_ITEM str_value_map[] = { + { RSA_PKCS1_PADDING, "pkcs1" }, + { RSA_NO_PADDING, "none" }, + { RSA_PKCS1_OAEP_PADDING, "oaep" }, + { RSA_PKCS1_OAEP_PADDING, "oeap" }, + { RSA_X931_PADDING, "x931" }, + { RSA_PKCS1_PSS_PADDING, "pss" }, + /* Special case, will pass directly as an integer */ + { RSA_PKCS1_WITH_TLS_PADDING, NULL } + }; + int ret; + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == GET) { + /* + * EVP_PKEY_CTRL_GET_RSA_PADDING returns the padding mode in the + * weirdest way for a ctrl. Instead of doing like all other ctrls + * that return a simple, i.e. just have that as a return value, + * this particular ctrl treats p2 as the address for the int to be + * returned. We must therefore remember |ctx->p2|, then make + * |ctx->p2| point at a buffer to be filled in with the name, and + * |ctx->p1| with its size. default_fixup_args() will take care + * of the rest for us, along with the POST_CTRL_TO_PARAMS && GET + * code section further down. + */ + ctx->orig_p2 = ctx->p2; + ctx->p2 = ctx->name_buf; + ctx->p1 = sizeof(ctx->name_buf); + } else if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == SET) { + /* + * Ideally, we should use utf8 strings for the diverse padding modes. + * We only came here because someone called EVP_PKEY_CTX_ctrl(), + * though, and since that can reasonably be seen as legacy code + * that uses the diverse RSA macros for the padding mode, and we + * know that at least our providers can handle the numeric modes, + * we take the cheap route for now. + * + * The other solution would be to match |ctx->p1| against entries + * in str_value_map and pass the corresponding string. However, + * since we don't have a string for RSA_PKCS1_WITH_TLS_PADDING, + * we have to do this same hack at least for that one. + * + * Since the "official" data type for the RSA padding mode is utf8 + * string, we cannot count on default_fixup_args(). Instead, we + * build the OSSL_PARAM item ourselves and return immediately. + */ + ctx->params[0] = OSSL_PARAM_construct_int(translation->param_key, + &ctx->p1); + return 1; + } else if (state == POST_PARAMS_TO_CTRL && ctx->action_type == GET) { + size_t i; + + /* + * The EVP_PKEY_CTX_get_params() caller may have asked for a utf8 + * string, or may have asked for an integer of some sort. If they + * ask for an integer, we respond directly. If not, we translate + * the response from the ctrl function into a string. + */ + switch (ctx->params->data_type) { + case OSSL_PARAM_INTEGER: + return OSSL_PARAM_get_int(ctx->params, &ctx->p1); + case OSSL_PARAM_UNSIGNED_INTEGER: + return OSSL_PARAM_get_uint(ctx->params, (unsigned int *)&ctx->p1); + default: + break; + } + + for (i = 0; i < OSSL_NELEM(str_value_map); i++) { + if (ctx->p1 == (int)str_value_map[i].id) + break; + } + if (i == OSSL_NELEM(str_value_map)) { + ERR_raise_data(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE, + "[action:%d, state:%d] padding number %d", + ctx->action_type, state, ctx->p1); + return -2; + } + /* + * If we don't have a string, we can't do anything. The caller + * should have asked for a number... + */ + if (str_value_map[i].ptr == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + ctx->p2 = str_value_map[i].ptr; + ctx->p1 = strlen(ctx->p2); + } + + if ((ret = default_fixup_args(state, translation, ctx)) <= 0) + return ret; + + if ((ctx->action_type == SET && state == PRE_PARAMS_TO_CTRL) + || (ctx->action_type == GET && state == POST_CTRL_TO_PARAMS)) { + size_t i; + + for (i = 0; i < OSSL_NELEM(str_value_map); i++) { + if (strcmp(ctx->p2, str_value_map[i].ptr) == 0) + break; + } + + if (i == OSSL_NELEM(str_value_map)) { + ERR_raise_data(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE, + "[action:%d, state:%d] padding name %s", + ctx->action_type, state, ctx->p1); + ctx->p1 = ret = -2; + } else if (state == POST_CTRL_TO_PARAMS) { + /* EVP_PKEY_CTRL_GET_RSA_PADDING weirdness explained further up */ + *(int *)ctx->orig_p2 = str_value_map[i].id; + } else { + ctx->p1 = str_value_map[i].id; + } + ctx->p2 = NULL; + } + + return ret; +} + +/* EVP_PKEY_CTRL_RSA_PSS_SALTLEN, EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN */ +static int fix_rsa_pss_saltlen(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + static const OSSL_ITEM str_value_map[] = { + { (unsigned int)RSA_PSS_SALTLEN_DIGEST, "digest" }, + { (unsigned int)RSA_PSS_SALTLEN_MAX, "max" }, + { (unsigned int)RSA_PSS_SALTLEN_AUTO, "auto" } + }; + int ret; + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == GET) { + /* + * EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN returns the saltlen by filling + * in the int pointed at by p2. This is potentially as weird as + * the way EVP_PKEY_CTRL_GET_RSA_PADDING works, except that saltlen + * might be a negative value, so it wouldn't work as a legitimate + * return value. + * In any case, we must therefore remember |ctx->p2|, then make + * |ctx->p2| point at a buffer to be filled in with the name, and + * |ctx->p1| with its size. default_fixup_args() will take care + * of the rest for us, along with the POST_CTRL_TO_PARAMS && GET + * code section further down. + */ + ctx->orig_p2 = ctx->p2; + ctx->p2 = ctx->name_buf; + ctx->p1 = sizeof(ctx->name_buf); + } else if ((ctx->action_type == SET && state == PRE_CTRL_TO_PARAMS) + || (ctx->action_type == GET && state == POST_PARAMS_TO_CTRL)) { + size_t i; + + for (i = 0; i < OSSL_NELEM(str_value_map); i++) { + if (ctx->p1 == (int)str_value_map[i].id) + break; + } + if (i == OSSL_NELEM(str_value_map)) { + BIO_snprintf(ctx->name_buf, sizeof(ctx->name_buf), "%d", ctx->p1); + } else { + /* This won't truncate but it will quiet static analysers */ + strncpy(ctx->name_buf, str_value_map[i].ptr, sizeof(ctx->name_buf) - 1); + ctx->name_buf[sizeof(ctx->name_buf) - 1] = '\0'; + } + ctx->p2 = ctx->name_buf; + ctx->p1 = strlen(ctx->p2); + } + + if ((ret = default_fixup_args(state, translation, ctx)) <= 0) + return ret; + + if ((ctx->action_type == SET && state == PRE_PARAMS_TO_CTRL) + || (ctx->action_type == GET && state == POST_CTRL_TO_PARAMS)) { + size_t i; + int val; + + for (i = 0; i < OSSL_NELEM(str_value_map); i++) { + if (strcmp(ctx->p2, str_value_map[i].ptr) == 0) + break; + } + + val = i == OSSL_NELEM(str_value_map) ? atoi(ctx->p2) + : (int)str_value_map[i].id; + if (state == POST_CTRL_TO_PARAMS) { + /* + * EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN weirdness explained further + * up + */ + *(int *)ctx->orig_p2 = val; + } else { + ctx->p1 = val; + } + ctx->p2 = NULL; + } + + return ret; +} + +/* EVP_PKEY_CTRL_HKDF_MODE */ +static int fix_hkdf_mode(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + static const OSSL_ITEM str_value_map[] = { + { EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND, "EXTRACT_AND_EXPAND" }, + { EVP_KDF_HKDF_MODE_EXTRACT_ONLY, "EXTRACT_ONLY" }, + { EVP_KDF_HKDF_MODE_EXPAND_ONLY, "EXPAND_ONLY" } + }; + int ret; + + if ((ret = default_check(state, translation, ctx)) <= 0) + return ret; + + if ((ctx->action_type == SET && state == PRE_CTRL_TO_PARAMS) + || (ctx->action_type == GET && state == POST_PARAMS_TO_CTRL)) { + size_t i; + + for (i = 0; i < OSSL_NELEM(str_value_map); i++) { + if (ctx->p1 == (int)str_value_map[i].id) + break; + } + if (i == OSSL_NELEM(str_value_map)) + return 0; + ctx->p2 = str_value_map[i].ptr; + ctx->p1 = strlen(ctx->p2); + } + + if ((ret = default_fixup_args(state, translation, ctx)) <= 0) + return ret; + + if ((ctx->action_type == SET && state == PRE_PARAMS_TO_CTRL) + || (ctx->action_type == GET && state == POST_CTRL_TO_PARAMS)) { + size_t i; + + for (i = 0; i < OSSL_NELEM(str_value_map); i++) { + if (strcmp(ctx->p2, str_value_map[i].ptr) == 0) + break; + } + if (i == OSSL_NELEM(str_value_map)) + return 0; + if (state == POST_CTRL_TO_PARAMS) + ret = str_value_map[i].id; + else + ctx->p1 = str_value_map[i].id; + ctx->p2 = NULL; + } + + return 1; +} + +/*- + * Payload getters + * =============== + * + * These all get the data they want, then call default_fixup_args() as + * a post-ctrl GET fixup. They all get NULL ctx, ctrl_cmd, ctrl_str, + * p1, sz + */ + +/* Pilfering DH, DSA and EC_KEY */ +static int get_payload_group_name(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + EVP_PKEY *pkey = ctx->p2; + + ctx->p2 = NULL; + switch (EVP_PKEY_get_base_id(pkey)) { +#ifndef OPENSSL_NO_DH + case EVP_PKEY_DH: + { + const DH *dh = EVP_PKEY_get0_DH(pkey); + int uid = DH_get_nid(dh); + + if (uid != NID_undef) { + const DH_NAMED_GROUP *dh_group = + ossl_ffc_uid_to_dh_named_group(uid); + + ctx->p2 = (char *)ossl_ffc_named_group_get_name(dh_group); + } + } + break; +#endif +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + { + const EC_GROUP *grp = + EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey)); + int nid = NID_undef; + + if (grp != NULL) + nid = EC_GROUP_get_curve_name(grp); + if (nid != NID_undef) + ctx->p2 = (char *)OSSL_EC_curve_nid2name(nid); + } + break; +#endif + default: + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE); + return 0; + } + + /* + * Quietly ignoring unknown groups matches the behaviour on the provider + * side. + */ + if (ctx->p2 == NULL) + return 1; + + ctx->p1 = strlen(ctx->p2); + return default_fixup_args(state, translation, ctx); +} + +static int get_payload_private_key(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + EVP_PKEY *pkey = ctx->p2; + + ctx->p2 = NULL; + if (ctx->params->data_type != OSSL_PARAM_UNSIGNED_INTEGER) + return 0; + + switch (EVP_PKEY_get_base_id(pkey)) { +#ifndef OPENSSL_NO_DH + case EVP_PKEY_DH: + { + const DH *dh = EVP_PKEY_get0_DH(pkey); + + ctx->p2 = (BIGNUM *)DH_get0_priv_key(dh); + } + break; +#endif +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + { + const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); + + ctx->p2 = (BIGNUM *)EC_KEY_get0_private_key(ec); + } + break; +#endif + default: + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE); + return 0; + } + + return default_fixup_args(state, translation, ctx); +} + +static int get_payload_public_key(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + EVP_PKEY *pkey = ctx->p2; + unsigned char *buf = NULL; + int ret; + + ctx->p2 = NULL; + switch (EVP_PKEY_get_base_id(pkey)) { +#ifndef OPENSSL_NO_DH + case EVP_PKEY_DHX: + case EVP_PKEY_DH: + switch (ctx->params->data_type) { + case OSSL_PARAM_OCTET_STRING: + ctx->sz = ossl_dh_key2buf(EVP_PKEY_get0_DH(pkey), &buf, 0, 1); + ctx->p2 = buf; + break; + case OSSL_PARAM_UNSIGNED_INTEGER: + ctx->p2 = (void *)DH_get0_pub_key(EVP_PKEY_get0_DH(pkey)); + break; + default: + return 0; + } + break; +#endif +#ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + if (ctx->params->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { + ctx->p2 = (void *)DSA_get0_pub_key(EVP_PKEY_get0_DSA(pkey)); + break; + } + return 0; +#endif +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + if (ctx->params->data_type == OSSL_PARAM_OCTET_STRING) { + const EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey); + BN_CTX *bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eckey)); + const EC_GROUP *ecg = EC_KEY_get0_group(eckey); + const EC_POINT *point = EC_KEY_get0_public_key(eckey); + + if (bnctx == NULL) + return 0; + ctx->sz = EC_POINT_point2buf(ecg, point, + POINT_CONVERSION_COMPRESSED, + &buf, bnctx); + ctx->p2 = buf; + BN_CTX_free(bnctx); + break; + } + return 0; +#endif + default: + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE); + return 0; + } + + ret = default_fixup_args(state, translation, ctx); + OPENSSL_free(buf); + return ret; +} + +static int get_payload_bn(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx, const BIGNUM *bn) +{ + if (bn == NULL) + return 0; + if (ctx->params->data_type != OSSL_PARAM_UNSIGNED_INTEGER) + return 0; + ctx->p2 = (BIGNUM *)bn; + + return default_fixup_args(state, translation, ctx); +} + +static int get_dh_dsa_payload_p(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + const BIGNUM *bn = NULL; + EVP_PKEY *pkey = ctx->p2; + + switch (EVP_PKEY_get_base_id(pkey)) { +#ifndef OPENSSL_NO_DH + case EVP_PKEY_DH: + bn = DH_get0_p(EVP_PKEY_get0_DH(pkey)); + break; +#endif +#ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + bn = DSA_get0_p(EVP_PKEY_get0_DSA(pkey)); + break; +#endif + default: + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE); + } + + return get_payload_bn(state, translation, ctx, bn); +} + +static int get_dh_dsa_payload_q(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + const BIGNUM *bn = NULL; + + switch (EVP_PKEY_get_base_id(ctx->p2)) { +#ifndef OPENSSL_NO_DH + case EVP_PKEY_DH: + bn = DH_get0_q(EVP_PKEY_get0_DH(ctx->p2)); + break; +#endif +#ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + bn = DSA_get0_q(EVP_PKEY_get0_DSA(ctx->p2)); + break; +#endif + } + + return get_payload_bn(state, translation, ctx, bn); +} + +static int get_dh_dsa_payload_g(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + const BIGNUM *bn = NULL; + + switch (EVP_PKEY_get_base_id(ctx->p2)) { +#ifndef OPENSSL_NO_DH + case EVP_PKEY_DH: + bn = DH_get0_g(EVP_PKEY_get0_DH(ctx->p2)); + break; +#endif +#ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + bn = DSA_get0_g(EVP_PKEY_get0_DSA(ctx->p2)); + break; +#endif + } + + return get_payload_bn(state, translation, ctx, bn); +} + +static int get_payload_int(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx, + const int val) +{ + if (ctx->params->data_type != OSSL_PARAM_INTEGER) + return 0; + ctx->p1 = val; + ctx->p2 = NULL; + + return default_fixup_args(state, translation, ctx); +} + +static int get_ec_decoded_from_explicit_params(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + int val = 0; + EVP_PKEY *pkey = ctx->p2; + + switch (EVP_PKEY_base_id(pkey)) { +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + val = EC_KEY_decoded_from_explicit_params(EVP_PKEY_get0_EC_KEY(pkey)); + if (val < 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY); + return 0; + } + break; +#endif + default: + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE); + return 0; + } + + return get_payload_int(state, translation, ctx, val); +} + +static int get_rsa_payload_n(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + const BIGNUM *bn = NULL; + + if (EVP_PKEY_get_base_id(ctx->p2) != EVP_PKEY_RSA) + return 0; + bn = RSA_get0_n(EVP_PKEY_get0_RSA(ctx->p2)); + + return get_payload_bn(state, translation, ctx, bn); +} + +static int get_rsa_payload_e(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + const BIGNUM *bn = NULL; + + if (EVP_PKEY_get_base_id(ctx->p2) != EVP_PKEY_RSA) + return 0; + bn = RSA_get0_e(EVP_PKEY_get0_RSA(ctx->p2)); + + return get_payload_bn(state, translation, ctx, bn); +} + +static int get_rsa_payload_d(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + const BIGNUM *bn = NULL; + + if (EVP_PKEY_get_base_id(ctx->p2) != EVP_PKEY_RSA) + return 0; + bn = RSA_get0_d(EVP_PKEY_get0_RSA(ctx->p2)); + + return get_payload_bn(state, translation, ctx, bn); +} + +static int get_rsa_payload_factor(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx, + size_t factornum) +{ + const RSA *r = EVP_PKEY_get0_RSA(ctx->p2); + const BIGNUM *bn = NULL; + + switch (factornum) { + case 0: + bn = RSA_get0_p(r); + break; + case 1: + bn = RSA_get0_q(r); + break; + default: + { + size_t pnum = RSA_get_multi_prime_extra_count(r); + const BIGNUM *factors[10]; + + if (factornum - 2 < pnum + && RSA_get0_multi_prime_factors(r, factors)) + bn = factors[factornum - 2]; + } + break; + } + + return get_payload_bn(state, translation, ctx, bn); +} + +static int get_rsa_payload_exponent(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx, + size_t exponentnum) +{ + const RSA *r = EVP_PKEY_get0_RSA(ctx->p2); + const BIGNUM *bn = NULL; + + switch (exponentnum) { + case 0: + bn = RSA_get0_dmp1(r); + break; + case 1: + bn = RSA_get0_dmq1(r); + break; + default: + { + size_t pnum = RSA_get_multi_prime_extra_count(r); + const BIGNUM *exps[10], *coeffs[10]; + + if (exponentnum - 2 < pnum + && RSA_get0_multi_prime_crt_params(r, exps, coeffs)) + bn = exps[exponentnum - 2]; + } + break; + } + + return get_payload_bn(state, translation, ctx, bn); +} + +static int get_rsa_payload_coefficient(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx, + size_t coefficientnum) +{ + const RSA *r = EVP_PKEY_get0_RSA(ctx->p2); + const BIGNUM *bn = NULL; + + switch (coefficientnum) { + case 0: + bn = RSA_get0_iqmp(r); + break; + default: + { + size_t pnum = RSA_get_multi_prime_extra_count(r); + const BIGNUM *exps[10], *coeffs[10]; + + if (coefficientnum - 1 < pnum + && RSA_get0_multi_prime_crt_params(r, exps, coeffs)) + bn = coeffs[coefficientnum - 1]; + } + break; + } + + return get_payload_bn(state, translation, ctx, bn); +} + +#define IMPL_GET_RSA_PAYLOAD_FACTOR(n) \ + static int \ + get_rsa_payload_f##n(enum state state, \ + const struct translation_st *translation, \ + struct translation_ctx_st *ctx) \ + { \ + if (EVP_PKEY_get_base_id(ctx->p2) != EVP_PKEY_RSA) \ + return 0; \ + return get_rsa_payload_factor(state, translation, ctx, n - 1); \ + } + +#define IMPL_GET_RSA_PAYLOAD_EXPONENT(n) \ + static int \ + get_rsa_payload_e##n(enum state state, \ + const struct translation_st *translation, \ + struct translation_ctx_st *ctx) \ + { \ + if (EVP_PKEY_get_base_id(ctx->p2) != EVP_PKEY_RSA) \ + return 0; \ + return get_rsa_payload_exponent(state, translation, ctx, \ + n - 1); \ + } + +#define IMPL_GET_RSA_PAYLOAD_COEFFICIENT(n) \ + static int \ + get_rsa_payload_c##n(enum state state, \ + const struct translation_st *translation, \ + struct translation_ctx_st *ctx) \ + { \ + if (EVP_PKEY_get_base_id(ctx->p2) != EVP_PKEY_RSA) \ + return 0; \ + return get_rsa_payload_coefficient(state, translation, ctx, \ + n - 1); \ + } + +IMPL_GET_RSA_PAYLOAD_FACTOR(1) +IMPL_GET_RSA_PAYLOAD_FACTOR(2) +IMPL_GET_RSA_PAYLOAD_FACTOR(3) +IMPL_GET_RSA_PAYLOAD_FACTOR(4) +IMPL_GET_RSA_PAYLOAD_FACTOR(5) +IMPL_GET_RSA_PAYLOAD_FACTOR(6) +IMPL_GET_RSA_PAYLOAD_FACTOR(7) +IMPL_GET_RSA_PAYLOAD_FACTOR(8) +IMPL_GET_RSA_PAYLOAD_FACTOR(9) +IMPL_GET_RSA_PAYLOAD_FACTOR(10) +IMPL_GET_RSA_PAYLOAD_EXPONENT(1) +IMPL_GET_RSA_PAYLOAD_EXPONENT(2) +IMPL_GET_RSA_PAYLOAD_EXPONENT(3) +IMPL_GET_RSA_PAYLOAD_EXPONENT(4) +IMPL_GET_RSA_PAYLOAD_EXPONENT(5) +IMPL_GET_RSA_PAYLOAD_EXPONENT(6) +IMPL_GET_RSA_PAYLOAD_EXPONENT(7) +IMPL_GET_RSA_PAYLOAD_EXPONENT(8) +IMPL_GET_RSA_PAYLOAD_EXPONENT(9) +IMPL_GET_RSA_PAYLOAD_EXPONENT(10) +IMPL_GET_RSA_PAYLOAD_COEFFICIENT(1) +IMPL_GET_RSA_PAYLOAD_COEFFICIENT(2) +IMPL_GET_RSA_PAYLOAD_COEFFICIENT(3) +IMPL_GET_RSA_PAYLOAD_COEFFICIENT(4) +IMPL_GET_RSA_PAYLOAD_COEFFICIENT(5) +IMPL_GET_RSA_PAYLOAD_COEFFICIENT(6) +IMPL_GET_RSA_PAYLOAD_COEFFICIENT(7) +IMPL_GET_RSA_PAYLOAD_COEFFICIENT(8) +IMPL_GET_RSA_PAYLOAD_COEFFICIENT(9) + +static int fix_group_ecx(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ + const char *value = NULL; + + switch (state) { + case PRE_PARAMS_TO_CTRL: + if (!EVP_PKEY_CTX_IS_GEN_OP(ctx->pctx)) + return 0; + ctx->action_type = NONE; + return 1; + case POST_PARAMS_TO_CTRL: + if (OSSL_PARAM_get_utf8_string_ptr(ctx->params, &value) == 0 || + OPENSSL_strcasecmp(ctx->pctx->keytype, value) != 0) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT); + ctx->p1 = 0; + return 0; + } + ctx->p1 = 1; + return 1; + default: + return 0; + } +} + +/*- + * The translation table itself + * ============================ + */ + +static const struct translation_st evp_pkey_ctx_translations[] = { + /* + * DistID: we pass it to the backend as an octet string, + * but get it back as a pointer to an octet string. + * + * Note that the EVP_PKEY_CTRL_GET1_ID_LEN is purely for legacy purposes + * that has no separate counterpart in OSSL_PARAM terms, since we get + * the length of the DistID automatically when getting the DistID itself. + */ + { SET, -1, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_SET1_ID, "distid", "hexdistid", + OSSL_PKEY_PARAM_DIST_ID, OSSL_PARAM_OCTET_STRING, NULL }, + { GET, -1, -1, -1, + EVP_PKEY_CTRL_GET1_ID, "distid", "hexdistid", + OSSL_PKEY_PARAM_DIST_ID, OSSL_PARAM_OCTET_PTR, NULL }, + { GET, -1, -1, -1, + EVP_PKEY_CTRL_GET1_ID_LEN, NULL, NULL, + OSSL_PKEY_PARAM_DIST_ID, OSSL_PARAM_OCTET_PTR, fix_distid_len }, + + /*- + * DH & DHX + * ======== + */ + + /* + * EVP_PKEY_CTRL_DH_KDF_TYPE is used both for setting and getting. The + * fixup function has to handle this... + */ + { NONE, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_TYPE, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_TYPE, OSSL_PARAM_UTF8_STRING, + fix_dh_kdf_type }, + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_MD, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + { GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_DH_KDF_MD, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_OUTLEN, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_OUTLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_OUTLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_UKM, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_STRING, NULL }, + { GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_DH_KDF_UKM, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, NULL }, + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_OID, NULL, NULL, + OSSL_KDF_PARAM_CEK_ALG, OSSL_PARAM_UTF8_STRING, fix_oid }, + { GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_DH_KDF_OID, NULL, NULL, + OSSL_KDF_PARAM_CEK_ALG, OSSL_PARAM_UTF8_STRING, fix_oid }, + + /* DHX Keygen Parameters that are shared with DH */ + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, "dh_paramgen_type", NULL, + OSSL_PKEY_PARAM_FFC_TYPE, OSSL_PARAM_UTF8_STRING, fix_dh_paramgen_type }, + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, "dh_paramgen_prime_len", NULL, + OSSL_PKEY_PARAM_FFC_PBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_DH_NID, "dh_param", NULL, + OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, NULL }, + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_DH_RFC5114, "dh_rfc5114", NULL, + OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_dh_nid5114 }, + + /* DH Keygen Parameters that are shared with DHX */ + { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, "dh_paramgen_type", NULL, + OSSL_PKEY_PARAM_FFC_TYPE, OSSL_PARAM_UTF8_STRING, fix_dh_paramgen_type }, + { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, "dh_paramgen_prime_len", NULL, + OSSL_PKEY_PARAM_FFC_PBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_DH_NID, "dh_param", NULL, + OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_dh_nid }, + { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_DH_RFC5114, "dh_rfc5114", NULL, + OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_dh_nid5114 }, + + /* DH specific Keygen Parameters */ + { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, "dh_paramgen_generator", NULL, + OSSL_PKEY_PARAM_DH_GENERATOR, OSSL_PARAM_INTEGER, NULL }, + + /* DHX specific Keygen Parameters */ + { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, "dh_paramgen_subprime_len", NULL, + OSSL_PKEY_PARAM_FFC_QBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + + { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_PAD, "dh_pad", NULL, + OSSL_EXCHANGE_PARAM_PAD, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + + /*- + * DSA + * === + */ + { SET, EVP_PKEY_DSA, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, "dsa_paramgen_bits", NULL, + OSSL_PKEY_PARAM_FFC_PBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, EVP_PKEY_DSA, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, "dsa_paramgen_q_bits", NULL, + OSSL_PKEY_PARAM_FFC_QBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, EVP_PKEY_DSA, 0, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DSA_PARAMGEN_MD, "dsa_paramgen_md", NULL, + OSSL_PKEY_PARAM_FFC_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + + /*- + * EC + * == + */ + { SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_EC_PARAM_ENC, "ec_param_enc", NULL, + OSSL_PKEY_PARAM_EC_ENCODING, OSSL_PARAM_UTF8_STRING, fix_ec_param_enc }, + { SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, "ec_paramgen_curve", NULL, + OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, + fix_ec_paramgen_curve_nid }, + /* + * EVP_PKEY_CTRL_EC_ECDH_COFACTOR and EVP_PKEY_CTRL_EC_KDF_TYPE are used + * both for setting and getting. The fixup function has to handle this... + */ + { NONE, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, "ecdh_cofactor_mode", NULL, + OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE, OSSL_PARAM_INTEGER, + fix_ecdh_cofactor }, + { NONE, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_EC_KDF_TYPE, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_TYPE, OSSL_PARAM_UTF8_STRING, fix_ec_kdf_type }, + { SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_EC_KDF_MD, "ecdh_kdf_md", NULL, + OSSL_EXCHANGE_PARAM_KDF_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + { GET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_EC_KDF_MD, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + { SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_EC_KDF_OUTLEN, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_OUTLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { GET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_OUTLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_EC_KDF_UKM, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_STRING, NULL }, + { GET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_EC_KDF_UKM, NULL, NULL, + OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, NULL }, + + /*- + * RSA + * === + */ + + /* + * RSA padding modes are numeric with ctrls, strings with ctrl_strs, + * and can be both with OSSL_PARAM. We standardise on strings here, + * fix_rsa_padding_mode() does the work when the caller has a different + * idea. + */ + { SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, + EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_RSA_PADDING, "rsa_padding_mode", NULL, + OSSL_PKEY_PARAM_PAD_MODE, OSSL_PARAM_UTF8_STRING, fix_rsa_padding_mode }, + { GET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, + EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_GET_RSA_PADDING, NULL, NULL, + OSSL_PKEY_PARAM_PAD_MODE, OSSL_PARAM_UTF8_STRING, fix_rsa_padding_mode }, + + { SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, + EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_RSA_MGF1_MD, "rsa_mgf1_md", NULL, + OSSL_PKEY_PARAM_MGF1_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + { GET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, + EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, NULL, NULL, + OSSL_PKEY_PARAM_MGF1_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + + /* + * RSA-PSS saltlen is essentially numeric, but certain values can be + * expressed as keywords (strings) with ctrl_str. The corresponding + * OSSL_PARAM allows both forms. + * fix_rsa_pss_saltlen() takes care of the distinction. + */ + { SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, "rsa_pss_saltlen", NULL, + OSSL_PKEY_PARAM_RSA_PSS_SALTLEN, OSSL_PARAM_UTF8_STRING, + fix_rsa_pss_saltlen }, + { GET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, NULL, NULL, + OSSL_PKEY_PARAM_RSA_PSS_SALTLEN, OSSL_PARAM_UTF8_STRING, + fix_rsa_pss_saltlen }, + + { SET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_MD, "rsa_oaep_md", NULL, + OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + { GET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, NULL, NULL, + OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + /* + * The "rsa_oaep_label" ctrl_str expects the value to always be hex. + * This is accomodated by default_fixup_args() above, which mimics that + * expectation for any translation item where |ctrl_str| is NULL and + * |ctrl_hexstr| is non-NULL. + */ + { SET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_LABEL, NULL, "rsa_oaep_label", + OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_STRING, NULL }, + { GET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, NULL, NULL, + OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_STRING, NULL }, + + { SET, EVP_PKEY_RSA_PSS, 0, EVP_PKEY_OP_TYPE_GEN, + EVP_PKEY_CTRL_MD, "rsa_pss_keygen_md", NULL, + OSSL_ALG_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + { SET, EVP_PKEY_RSA_PSS, 0, EVP_PKEY_OP_TYPE_GEN, + EVP_PKEY_CTRL_RSA_MGF1_MD, "rsa_pss_keygen_mgf1_md", NULL, + OSSL_PKEY_PARAM_MGF1_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + { SET, EVP_PKEY_RSA_PSS, 0, EVP_PKEY_OP_TYPE_GEN, + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, "rsa_pss_keygen_saltlen", NULL, + OSSL_SIGNATURE_PARAM_PSS_SALTLEN, OSSL_PARAM_INTEGER, NULL }, + { SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, "rsa_keygen_bits", NULL, + OSSL_PKEY_PARAM_RSA_BITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, "rsa_keygen_pubexp", NULL, + OSSL_PKEY_PARAM_RSA_E, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES, "rsa_keygen_primes", NULL, + OSSL_PKEY_PARAM_RSA_PRIMES, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + + /*- + * SipHash + * ====== + */ + { SET, -1, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_SET_DIGEST_SIZE, "digestsize", NULL, + OSSL_MAC_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + + /*- + * TLS1-PRF + * ======== + */ + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_TLS_MD, "md", NULL, + OSSL_KDF_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_TLS_SECRET, "secret", "hexsecret", + OSSL_KDF_PARAM_SECRET, OSSL_PARAM_OCTET_STRING, NULL }, + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_TLS_SEED, "seed", "hexseed", + OSSL_KDF_PARAM_SEED, OSSL_PARAM_OCTET_STRING, NULL }, + + /*- + * HKDF + * ==== + */ + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_MD, "md", NULL, + OSSL_KDF_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_SALT, "salt", "hexsalt", + OSSL_KDF_PARAM_SALT, OSSL_PARAM_OCTET_STRING, NULL }, + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_KEY, "key", "hexkey", + OSSL_KDF_PARAM_KEY, OSSL_PARAM_OCTET_STRING, NULL }, + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_INFO, "info", "hexinfo", + OSSL_KDF_PARAM_INFO, OSSL_PARAM_OCTET_STRING, NULL }, + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_MODE, "mode", NULL, + OSSL_KDF_PARAM_MODE, OSSL_PARAM_INTEGER, fix_hkdf_mode }, + + /*- + * Scrypt + * ====== + */ + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_PASS, "pass", "hexpass", + OSSL_KDF_PARAM_PASSWORD, OSSL_PARAM_OCTET_STRING, NULL }, + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_SCRYPT_SALT, "salt", "hexsalt", + OSSL_KDF_PARAM_SALT, OSSL_PARAM_OCTET_STRING, NULL }, + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_SCRYPT_N, "N", NULL, + OSSL_KDF_PARAM_SCRYPT_N, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_SCRYPT_R, "r", NULL, + OSSL_KDF_PARAM_SCRYPT_R, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_SCRYPT_P, "p", NULL, + OSSL_KDF_PARAM_SCRYPT_P, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + { SET, -1, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, "maxmem_bytes", NULL, + OSSL_KDF_PARAM_SCRYPT_MAXMEM, OSSL_PARAM_UNSIGNED_INTEGER, NULL }, + + { SET, -1, -1, EVP_PKEY_OP_KEYGEN | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_CIPHER, NULL, NULL, + OSSL_PKEY_PARAM_CIPHER, OSSL_PARAM_UTF8_STRING, fix_cipher }, + { SET, -1, -1, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_SET_MAC_KEY, "key", "hexkey", + OSSL_PKEY_PARAM_PRIV_KEY, OSSL_PARAM_OCTET_STRING, NULL }, + + { SET, -1, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_MD, NULL, NULL, + OSSL_SIGNATURE_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + { GET, -1, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_GET_MD, NULL, NULL, + OSSL_SIGNATURE_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, + + /*- + * ECX + * === + */ + { SET, EVP_PKEY_X25519, EVP_PKEY_X25519, EVP_PKEY_OP_KEYGEN, -1, NULL, NULL, + OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_group_ecx }, + { SET, EVP_PKEY_X448, EVP_PKEY_X448, EVP_PKEY_OP_KEYGEN, -1, NULL, NULL, + OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_group_ecx }, +}; + +static const struct translation_st evp_pkey_translations[] = { + /* + * The following contain no ctrls, they are exclusively here to extract + * key payloads from legacy keys, using OSSL_PARAMs, and rely entirely + * on |fixup_args| to pass the actual data. The |fixup_args| should + * expect to get the EVP_PKEY pointer through |ctx->p2|. + */ + + /* DH, DSA & EC */ + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, + get_payload_group_name }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_PRIV_KEY, OSSL_PARAM_UNSIGNED_INTEGER, + get_payload_private_key }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_PUB_KEY, + 0 /* no data type, let get_payload_public_key() handle that */, + get_payload_public_key }, + + /* DH and DSA */ + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_FFC_P, OSSL_PARAM_UNSIGNED_INTEGER, + get_dh_dsa_payload_p }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_FFC_G, OSSL_PARAM_UNSIGNED_INTEGER, + get_dh_dsa_payload_g }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_FFC_Q, OSSL_PARAM_UNSIGNED_INTEGER, + get_dh_dsa_payload_q }, + + /* RSA */ + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_N, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_n }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_E, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_e }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_D, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_d }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_FACTOR1, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_f1 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_FACTOR2, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_f2 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_FACTOR3, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_f3 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_FACTOR4, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_f4 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_FACTOR5, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_f5 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_FACTOR6, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_f6 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_FACTOR7, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_f7 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_FACTOR8, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_f8 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_FACTOR9, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_f9 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_FACTOR10, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_f10 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_EXPONENT1, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_e1 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_EXPONENT2, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_e2 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_EXPONENT3, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_e3 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_EXPONENT4, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_e4 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_EXPONENT5, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_e5 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_EXPONENT6, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_e6 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_EXPONENT7, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_e7 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_EXPONENT8, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_e8 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_EXPONENT9, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_e9 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_EXPONENT10, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_e10 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_COEFFICIENT1, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_c1 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_COEFFICIENT2, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_c2 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_COEFFICIENT3, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_c3 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_COEFFICIENT4, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_c4 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_COEFFICIENT5, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_c5 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_COEFFICIENT6, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_c6 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_COEFFICIENT7, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_c7 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_COEFFICIENT8, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_c8 }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_RSA_COEFFICIENT9, OSSL_PARAM_UNSIGNED_INTEGER, + get_rsa_payload_c9 }, + + /* EC */ + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, OSSL_PARAM_INTEGER, + get_ec_decoded_from_explicit_params }, +}; + +static const struct translation_st * +lookup_translation(struct translation_st *tmpl, + const struct translation_st *translations, + size_t translations_num) +{ + size_t i; + + for (i = 0; i < translations_num; i++) { + const struct translation_st *item = &translations[i]; + + /* + * Sanity check the translation table item. + * + * 1. Either both keytypes are -1, or neither of them are. + * 2. TBA... + */ + if (!ossl_assert((item->keytype1 == -1) == (item->keytype2 == -1))) + continue; + + + /* + * Base search criteria: check that the optype and keytypes match, + * if relevant. All callers must synthesise these bits somehow. + */ + if (item->optype != -1 && (tmpl->optype & item->optype) == 0) + continue; + /* + * This expression is stunningly simple thanks to the sanity check + * above. + */ + if (item->keytype1 != -1 + && tmpl->keytype1 != item->keytype1 + && tmpl->keytype2 != item->keytype2) + continue; + + /* + * Done with the base search criteria, now we check the criteria for + * the individual types of translations: + * ctrl->params, ctrl_str->params, and params->ctrl + */ + if (tmpl->ctrl_num != 0) { + if (tmpl->ctrl_num != item->ctrl_num) + continue; + } else if (tmpl->ctrl_str != NULL) { + const char *ctrl_str = NULL; + const char *ctrl_hexstr = NULL; + + /* + * Search criteria that originates from a ctrl_str is only used + * for setting, never for getting. Therefore, we only look at + * the setter items. + */ + if (item->action_type != NONE + && item->action_type != SET) + continue; + /* + * At least one of the ctrl cmd names must be match the ctrl + * cmd name in the template. + */ + if (item->ctrl_str != NULL + && OPENSSL_strcasecmp(tmpl->ctrl_str, item->ctrl_str) == 0) + ctrl_str = tmpl->ctrl_str; + else if (item->ctrl_hexstr != NULL + && OPENSSL_strcasecmp(tmpl->ctrl_hexstr, + item->ctrl_hexstr) == 0) + ctrl_hexstr = tmpl->ctrl_hexstr; + else + continue; + + /* Modify the template to signal which string matched */ + tmpl->ctrl_str = ctrl_str; + tmpl->ctrl_hexstr = ctrl_hexstr; + } else if (tmpl->param_key != NULL) { + /* + * Search criteria that originates from a OSSL_PARAM setter or + * getter. + * + * Ctrls were fundamentally bidirectional, with only the ctrl + * command macro name implying direction (if you're lucky). + * A few ctrl commands were even taking advantage of the + * bidirectional nature, making the direction depend in the + * value of the numeric argument. + * + * OSSL_PARAM functions are fundamentally different, in that + * setters and getters are separated, so the data direction is + * implied by the function that's used. The same OSSL_PARAM + * key name can therefore be used in both directions. We must + * therefore take the action type into account in this case. + */ + if ((item->action_type != NONE + && tmpl->action_type != item->action_type) + || (item->param_key != NULL + && OPENSSL_strcasecmp(tmpl->param_key, + item->param_key) != 0)) + continue; + } else { + return NULL; + } + + return item; + } + + return NULL; +} + +static const struct translation_st * +lookup_evp_pkey_ctx_translation(struct translation_st *tmpl) +{ + return lookup_translation(tmpl, evp_pkey_ctx_translations, + OSSL_NELEM(evp_pkey_ctx_translations)); +} + +static const struct translation_st * +lookup_evp_pkey_translation(struct translation_st *tmpl) +{ + return lookup_translation(tmpl, evp_pkey_translations, + OSSL_NELEM(evp_pkey_translations)); +} + +/* This must ONLY be called for provider side operations */ +int evp_pkey_ctx_ctrl_to_param(EVP_PKEY_CTX *pctx, + int keytype, int optype, + int cmd, int p1, void *p2) +{ + struct translation_ctx_st ctx = { 0, }; + struct translation_st tmpl = { 0, }; + const struct translation_st *translation = NULL; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + int ret; + fixup_args_fn *fixup = default_fixup_args; + + if (keytype == -1) + keytype = pctx->legacy_keytype; + tmpl.ctrl_num = cmd; + tmpl.keytype1 = tmpl.keytype2 = keytype; + tmpl.optype = optype; + translation = lookup_evp_pkey_ctx_translation(&tmpl); + + if (translation == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + + if (pctx->pmeth != NULL + && pctx->pmeth->pkey_id != translation->keytype1 + && pctx->pmeth->pkey_id != translation->keytype2) + return -1; + + if (translation->fixup_args != NULL) + fixup = translation->fixup_args; + ctx.action_type = translation->action_type; + ctx.ctrl_cmd = cmd; + ctx.p1 = p1; + ctx.p2 = p2; + ctx.pctx = pctx; + ctx.params = params; + + ret = fixup(PRE_CTRL_TO_PARAMS, translation, &ctx); + + if (ret > 0) { + switch (ctx.action_type) { + default: + /* fixup_args is expected to make sure this is dead code */ + break; + case GET: + ret = evp_pkey_ctx_get_params_strict(pctx, ctx.params); + break; + case SET: + ret = evp_pkey_ctx_set_params_strict(pctx, ctx.params); + break; + } + } + + /* + * In POST, we pass the return value as p1, allowing the fixup_args + * function to affect it by changing its value. + */ + if (ret > 0) { + ctx.p1 = ret; + fixup(POST_CTRL_TO_PARAMS, translation, &ctx); + ret = ctx.p1; + } + + cleanup_translation_ctx(POST_CTRL_TO_PARAMS, translation, &ctx); + + return ret; +} + +/* This must ONLY be called for provider side operations */ +int evp_pkey_ctx_ctrl_str_to_param(EVP_PKEY_CTX *pctx, + const char *name, const char *value) +{ + struct translation_ctx_st ctx = { 0, }; + struct translation_st tmpl = { 0, }; + const struct translation_st *translation = NULL; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + int keytype = pctx->legacy_keytype; + int optype = pctx->operation == 0 ? -1 : pctx->operation; + int ret; + fixup_args_fn *fixup = default_fixup_args; + + tmpl.action_type = SET; + tmpl.keytype1 = tmpl.keytype2 = keytype; + tmpl.optype = optype; + tmpl.ctrl_str = name; + tmpl.ctrl_hexstr = name; + translation = lookup_evp_pkey_ctx_translation(&tmpl); + + if (translation != NULL) { + if (translation->fixup_args != NULL) + fixup = translation->fixup_args; + ctx.action_type = translation->action_type; + ctx.ishex = (tmpl.ctrl_hexstr != NULL); + } else { + /* String controls really only support setting */ + ctx.action_type = SET; + } + ctx.ctrl_str = name; + ctx.p1 = (int)strlen(value); + ctx.p2 = (char *)value; + ctx.pctx = pctx; + ctx.params = params; + + ret = fixup(PRE_CTRL_STR_TO_PARAMS, translation, &ctx); + + if (ret > 0) { + switch (ctx.action_type) { + default: + /* fixup_args is expected to make sure this is dead code */ + break; + case GET: + /* + * this is dead code, but must be present, or some compilers + * will complain + */ + break; + case SET: + ret = evp_pkey_ctx_set_params_strict(pctx, ctx.params); + break; + } + } + + if (ret > 0) + ret = fixup(POST_CTRL_STR_TO_PARAMS, translation, &ctx); + + cleanup_translation_ctx(CLEANUP_CTRL_STR_TO_PARAMS, translation, &ctx); + + return ret; +} + +/* This must ONLY be called for legacy operations */ +static int evp_pkey_ctx_setget_params_to_ctrl(EVP_PKEY_CTX *pctx, + enum action action_type, + OSSL_PARAM *params) +{ + int keytype = pctx->legacy_keytype; + int optype = pctx->operation == 0 ? -1 : pctx->operation; + + for (; params != NULL && params->key != NULL; params++) { + struct translation_ctx_st ctx = { 0, }; + struct translation_st tmpl = { 0, }; + const struct translation_st *translation = NULL; + fixup_args_fn *fixup = default_fixup_args; + int ret; + + tmpl.action_type = action_type; + tmpl.keytype1 = tmpl.keytype2 = keytype; + tmpl.optype = optype; + tmpl.param_key = params->key; + translation = lookup_evp_pkey_ctx_translation(&tmpl); + + if (translation != NULL) { + if (translation->fixup_args != NULL) + fixup = translation->fixup_args; + ctx.action_type = translation->action_type; + } + ctx.pctx = pctx; + ctx.params = params; + + ret = fixup(PRE_PARAMS_TO_CTRL, translation, &ctx); + + if (ret > 0 && ctx.action_type != NONE) + ret = EVP_PKEY_CTX_ctrl(pctx, keytype, optype, + ctx.ctrl_cmd, ctx.p1, ctx.p2); + + /* + * In POST, we pass the return value as p1, allowing the fixup_args + * function to put it to good use, or maybe affect it. + */ + if (ret > 0) { + ctx.p1 = ret; + fixup(POST_PARAMS_TO_CTRL, translation, &ctx); + ret = ctx.p1; + } + + cleanup_translation_ctx(CLEANUP_PARAMS_TO_CTRL, translation, &ctx); + + if (ret <= 0) + return 0; + } + return 1; +} + +int evp_pkey_ctx_set_params_to_ctrl(EVP_PKEY_CTX *ctx, const OSSL_PARAM *params) +{ + return evp_pkey_ctx_setget_params_to_ctrl(ctx, SET, (OSSL_PARAM *)params); +} + +int evp_pkey_ctx_get_params_to_ctrl(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) +{ + return evp_pkey_ctx_setget_params_to_ctrl(ctx, GET, params); +} + +/* This must ONLY be called for legacy EVP_PKEYs */ +static int evp_pkey_setget_params_to_ctrl(const EVP_PKEY *pkey, + enum action action_type, + OSSL_PARAM *params) +{ + int ret = 1; + + for (; params != NULL && params->key != NULL; params++) { + struct translation_ctx_st ctx = { 0, }; + struct translation_st tmpl = { 0, }; + const struct translation_st *translation = NULL; + fixup_args_fn *fixup = default_fixup_args; + + tmpl.action_type = action_type; + tmpl.param_key = params->key; + translation = lookup_evp_pkey_translation(&tmpl); + + if (translation != NULL) { + if (translation->fixup_args != NULL) + fixup = translation->fixup_args; + ctx.action_type = translation->action_type; + } + ctx.p2 = (void *)pkey; + ctx.params = params; + + /* + * EVP_PKEY doesn't have any ctrl function, so we rely completely + * on fixup_args to do the whole work. Also, we currently only + * support getting. + */ + if (!ossl_assert(translation != NULL) + || !ossl_assert(translation->action_type == GET) + || !ossl_assert(translation->fixup_args != NULL)) { + return -2; + } + + ret = fixup(PKEY, translation, &ctx); + + cleanup_translation_ctx(PKEY, translation, &ctx); + } + return ret; +} + +int evp_pkey_get_params_to_ctrl(const EVP_PKEY *pkey, OSSL_PARAM *params) +{ + return evp_pkey_setget_params_to_ctrl(pkey, GET, params); +} diff --git a/crypto/openssl/crypto/evp/dh_ctrl.c b/crypto/openssl/crypto/evp/dh_ctrl.c new file mode 100644 index 000000000000..fee7757d9aee --- /dev/null +++ b/crypto/openssl/crypto/evp/dh_ctrl.c @@ -0,0 +1,346 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include "crypto/dh.h" +#include "crypto/evp.h" + +static int dh_paramgen_check(EVP_PKEY_CTX *ctx) +{ + if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + /* If key type not DH return error */ + if (evp_pkey_ctx_is_legacy(ctx) + && ctx->pmeth->pkey_id != EVP_PKEY_DH + && ctx->pmeth->pkey_id != EVP_PKEY_DHX) + return -1; + return 1; +} + +static int dh_param_derive_check(EVP_PKEY_CTX *ctx) +{ + if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + /* If key type not DH return error */ + if (evp_pkey_ctx_is_legacy(ctx) + && ctx->pmeth->pkey_id != EVP_PKEY_DH + && ctx->pmeth->pkey_id != EVP_PKEY_DHX) + return -1; + return 1; +} + +int EVP_PKEY_CTX_set_dh_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GINDEX, &gindex); + *p = OSSL_PARAM_construct_end(); + + return evp_pkey_ctx_set_params_strict(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_seed(EVP_PKEY_CTX *ctx, + const unsigned char *seed, + size_t seedlen) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_FFC_SEED, + (void *)seed, seedlen); + *p = OSSL_PARAM_construct_end(); + + return evp_pkey_ctx_set_params_strict(ctx, params); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX *ctx, int typ) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL); +} + +int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits) +{ + int ret; + OSSL_PARAM params[2], *p = params; + size_t bits = pbits; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_PBITS, &bits); + *p = OSSL_PARAM_construct_end(); + return evp_pkey_ctx_set_params_strict(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX *ctx, int qbits) +{ + int ret; + OSSL_PARAM params[2], *p = params; + size_t bits2 = qbits; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_QBITS, &bits2); + *p = OSSL_PARAM_construct_end(); + + return evp_pkey_ctx_set_params_strict(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_DH_GENERATOR, &gen); + *p = OSSL_PARAM_construct_end(); + + return evp_pkey_ctx_set_params_strict(ctx, params); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL); +} + +int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int gen) +{ + return EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, + EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_DH_NID, nid, NULL); +} + +int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad) +{ + OSSL_PARAM dh_pad_params[2]; + unsigned int upad = pad; + + /* We use EVP_PKEY_CTX_ctrl return values */ + if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + + dh_pad_params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD, &upad); + dh_pad_params[1] = OSSL_PARAM_construct_end(); + + return evp_pkey_ctx_set_params_strict(ctx, dh_pad_params); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX *ctx, int kdf) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_get_dh_kdf_type(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT *oid) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)(oid)); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_get0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT **oid) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)(oid)); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)(md)); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_get_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)(pmd)); +} + +int EVP_PKEY_CTX_set_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int outlen) +{ + int ret; + size_t len = outlen; + OSSL_PARAM params[2], *p = params; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + if (outlen <= 0) { + /* + * This would ideally be -1 or 0, but we have to retain compatibility + * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if + * inlen <= 0 + */ + return -2; + } + + *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, + &len); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return ret; +} + +int EVP_PKEY_CTX_get_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen) +{ + int ret; + size_t len = UINT_MAX; + OSSL_PARAM params[2], *p = params; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, + &len); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_get_params_strict(ctx, params); + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + if (ret != 1 || len > INT_MAX) + return -1; + + *plen = (int)len; + + return 1; +} + +int EVP_PKEY_CTX_set0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if (len < 0) + return -1; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, + /* + * Cast away the const. This is read + * only so should be safe + */ + (void *)ukm, + (size_t)len); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + if (ret == 1) + OPENSSL_free(ukm); + return ret; +} + +#ifndef OPENSSL_NO_DEPRECATED_3_0 +int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm) +{ + int ret; + size_t ukmlen; + OSSL_PARAM params[2], *p = params; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM, + (void **)pukm, 0); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_get_params_strict(ctx, params); + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + if (ret != 1) + return -1; + + ukmlen = params[0].return_size; + if (ukmlen > INT_MAX) + return -1; + + return (int)ukmlen; +} +#endif diff --git a/crypto/openssl/crypto/evp/dh_support.c b/crypto/openssl/crypto/evp/dh_support.c new file mode 100644 index 000000000000..87296ffbee2b --- /dev/null +++ b/crypto/openssl/crypto/evp/dh_support.c @@ -0,0 +1,63 @@ +/* + * Copyright 2020-2021 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 /* strcmp */ +#include +#include "internal/nelem.h" +#include "crypto/dh.h" + +typedef struct dh_name2id_st{ + const char *name; + int id; + int type; +} DH_GENTYPE_NAME2ID; + +/* Indicates that the paramgen_type can be used for either DH or DHX */ +#define TYPE_ANY -1 +#ifndef OPENSSL_NO_DH +# define TYPE_DH DH_FLAG_TYPE_DH +# define TYPE_DHX DH_FLAG_TYPE_DHX +#else +# define TYPE_DH 0 +# define TYPE_DHX 0 +#endif + +static const DH_GENTYPE_NAME2ID dhtype2id[] = +{ + { "group", DH_PARAMGEN_TYPE_GROUP, TYPE_ANY }, + { "generator", DH_PARAMGEN_TYPE_GENERATOR, TYPE_DH }, + { "fips186_4", DH_PARAMGEN_TYPE_FIPS_186_4, TYPE_DHX }, + { "fips186_2", DH_PARAMGEN_TYPE_FIPS_186_2, TYPE_DHX }, +}; + +const char *ossl_dh_gen_type_id2name(int id) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(dhtype2id); ++i) { + if (dhtype2id[i].id == id) + return dhtype2id[i].name; + } + return NULL; +} + +#ifndef OPENSSL_NO_DH +int ossl_dh_gen_type_name2id(const char *name, int type) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(dhtype2id); ++i) { + if ((dhtype2id[i].type == TYPE_ANY + || type == dhtype2id[i].type) + && strcmp(dhtype2id[i].name, name) == 0) + return dhtype2id[i].id; + } + return -1; +} +#endif diff --git a/crypto/openssl/crypto/evp/digest.c b/crypto/openssl/crypto/evp/digest.c index 01a6f251f56e..e6e03eaf34a5 100644 --- a/crypto/openssl/crypto/evp/digest.c +++ b/crypto/openssl/crypto/evp/digest.c @@ -1,21 +1,30 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include -#include "internal/cryptlib.h" #include #include -#include +#include +#ifndef FIPS_MODULE +# include +#endif +#include +#include +#include "internal/cryptlib.h" +#include "internal/provider.h" +#include "internal/core.h" #include "crypto/evp.h" #include "evp_local.h" - static void cleanup_old_md_data(EVP_MD_CTX *ctx, int force) { if (ctx->digest != NULL) { @@ -31,32 +40,93 @@ static void cleanup_old_md_data(EVP_MD_CTX *ctx, int force) } } -/* This call frees resources associated with the context */ -int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) +void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force, int keep_fetched) { - if (ctx == NULL) - return 1; + if (ctx->algctx != NULL) { + if (ctx->digest != NULL && ctx->digest->freectx != NULL) + ctx->digest->freectx(ctx->algctx); + ctx->algctx = NULL; + EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); + } + + /* Code below to be removed when legacy support is dropped. */ /* * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because * sometimes only copies of the context are ever finalised. */ - cleanup_old_md_data(ctx, 0); + cleanup_old_md_data(ctx, force); + if (force) + ctx->digest = NULL; + +#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE) + ENGINE_finish(ctx->engine); + ctx->engine = NULL; +#endif + + /* Non legacy code, this has to be later than the ctx->digest cleaning */ + if (!keep_fetched) { + EVP_MD_free(ctx->fetched_digest); + ctx->fetched_digest = NULL; + ctx->reqdigest = NULL; + } +} + +static int evp_md_ctx_reset_ex(EVP_MD_CTX *ctx, int keep_fetched) +{ + if (ctx == NULL) + return 1; +#ifndef FIPS_MODULE /* * pctx should be freed by the user of EVP_MD_CTX * if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set */ - if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) + if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { EVP_PKEY_CTX_free(ctx->pctx); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(ctx->engine); + ctx->pctx = NULL; + } #endif - OPENSSL_cleanse(ctx, sizeof(*ctx)); + + evp_md_ctx_clear_digest(ctx, 0, keep_fetched); + if (!keep_fetched) + OPENSSL_cleanse(ctx, sizeof(*ctx)); return 1; } +/* This call frees resources associated with the context */ +int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) +{ + return evp_md_ctx_reset_ex(ctx, 0); +} + +#ifndef FIPS_MODULE +EVP_MD_CTX *evp_md_ctx_new_ex(EVP_PKEY *pkey, const ASN1_OCTET_STRING *id, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_MD_CTX *ctx; + EVP_PKEY_CTX *pctx = NULL; + + if ((ctx = EVP_MD_CTX_new()) == NULL + || (pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq)) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (id != NULL && EVP_PKEY_CTX_set1_id(pctx, id->data, id->length) <= 0) + goto err; + + EVP_MD_CTX_set_pkey_ctx(ctx, pctx); + return ctx; + + err: + EVP_PKEY_CTX_free(pctx); + EVP_MD_CTX_free(ctx); + return NULL; +} +#endif + EVP_MD_CTX *EVP_MD_CTX_new(void) { return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); @@ -64,20 +134,63 @@ EVP_MD_CTX *EVP_MD_CTX_new(void) void EVP_MD_CTX_free(EVP_MD_CTX *ctx) { + if (ctx == NULL) + return; + EVP_MD_CTX_reset(ctx); OPENSSL_free(ctx); } -int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) +static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type, + const OSSL_PARAM params[], ENGINE *impl) { - EVP_MD_CTX_reset(ctx); - return EVP_DigestInit_ex(ctx, type, NULL); -} +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + ENGINE *tmpimpl = NULL; +#endif + +#if !defined(FIPS_MODULE) + if (ctx->pctx != NULL + && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx) + && ctx->pctx->op.sig.algctx != NULL) { + /* + * Prior to OpenSSL 3.0 calling EVP_DigestInit_ex() on an mdctx + * previously initialised with EVP_DigestSignInit() would retain + * information about the key, and re-initialise for another sign + * operation. So in that case we redirect to EVP_DigestSignInit() + */ + if (ctx->pctx->operation == EVP_PKEY_OP_SIGNCTX) + return EVP_DigestSignInit(ctx, NULL, type, impl, NULL); + if (ctx->pctx->operation == EVP_PKEY_OP_VERIFYCTX) + return EVP_DigestVerifyInit(ctx, NULL, type, impl, NULL); + ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); + return 0; + } +#endif -int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) -{ EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); -#ifndef OPENSSL_NO_ENGINE + + if (ctx->algctx != NULL) { + if (!ossl_assert(ctx->digest != NULL)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + if (ctx->digest->freectx != NULL) + ctx->digest->freectx(ctx->algctx); + ctx->algctx = NULL; + } + + if (type != NULL) { + ctx->reqdigest = type; + } else { + if (ctx->digest == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_DIGEST_SET); + return 0; + } + type = ctx->digest; + } + + /* Code below to be removed when legacy support is dropped. */ +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) /* * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so * this context may already have an ENGINE! Try to avoid releasing the @@ -88,28 +201,114 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) (type == NULL || (type->type == ctx->digest->type))) goto skip_to_init; - if (type) { + if (type != NULL) { /* * Ensure an ENGINE left lying around from last time is cleared (the * previous check attempted to avoid this if the same ENGINE and * EVP_MD could be used). */ ENGINE_finish(ctx->engine); + ctx->engine = NULL; + } + + if (type != NULL && impl == NULL) + tmpimpl = ENGINE_get_digest_engine(type->type); +#endif + + /* + * If there are engines involved or EVP_MD_CTX_FLAG_NO_INIT is set then we + * should use legacy handling for now. + */ + if (ctx->engine != NULL + || impl != NULL +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + || tmpimpl != NULL +#endif + || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0 + || (type != NULL && type->origin == EVP_ORIG_METH) + || (type == NULL && ctx->digest != NULL + && ctx->digest->origin == EVP_ORIG_METH)) { + if (ctx->digest == ctx->fetched_digest) + ctx->digest = NULL; + EVP_MD_free(ctx->fetched_digest); + ctx->fetched_digest = NULL; + goto legacy; + } + + cleanup_old_md_data(ctx, 1); + + /* Start of non-legacy code below */ + + if (type->prov == NULL) { +#ifdef FIPS_MODULE + /* We only do explicit fetches inside the FIPS module */ + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; +#else + /* The NULL digest is a special case */ + EVP_MD *provmd = EVP_MD_fetch(NULL, + type->type != NID_undef ? OBJ_nid2sn(type->type) + : "NULL", ""); + + if (provmd == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + type = provmd; + EVP_MD_free(ctx->fetched_digest); + ctx->fetched_digest = provmd; +#endif + } + + if (ctx->algctx != NULL && ctx->digest != NULL && ctx->digest != type) { + if (ctx->digest->freectx != NULL) + ctx->digest->freectx(ctx->algctx); + ctx->algctx = NULL; + } + if (type->prov != NULL && ctx->fetched_digest != type) { + if (!EVP_MD_up_ref((EVP_MD *)type)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + EVP_MD_free(ctx->fetched_digest); + ctx->fetched_digest = (EVP_MD *)type; + } + ctx->digest = type; + if (ctx->algctx == NULL) { + ctx->algctx = ctx->digest->newctx(ossl_provider_ctx(type->prov)); + if (ctx->algctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + } + + if (ctx->digest->dinit == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + + return ctx->digest->dinit(ctx->algctx, params); + + /* Code below to be removed when legacy support is dropped. */ + legacy: + +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + if (type) { if (impl != NULL) { if (!ENGINE_init(impl)) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); return 0; } } else { /* Ask if an ENGINE is reserved for this job */ - impl = ENGINE_get_digest_engine(type->type); + impl = tmpimpl; } if (impl != NULL) { /* There's an ENGINE for this job ... (apparently) */ const EVP_MD *d = ENGINE_get_digest(impl, type->type); if (d == NULL) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); ENGINE_finish(impl); return 0; } @@ -122,12 +321,6 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) ctx->engine = impl; } else ctx->engine = NULL; - } else { - if (!ctx->digest) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET); - return 0; - } - type = ctx->digest; } #endif if (ctx->digest != type) { @@ -138,31 +331,84 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) ctx->update = type->update; ctx->md_data = OPENSSL_zalloc(type->ctx_size); if (ctx->md_data == NULL) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } } } -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) skip_to_init: #endif - if (ctx->pctx) { +#ifndef FIPS_MODULE + if (ctx->pctx != NULL + && (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx) + || ctx->pctx->op.sig.signature == NULL)) { int r; r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); if (r <= 0 && (r != -2)) return 0; } +#endif if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) return 1; return ctx->digest->init(ctx); } +int EVP_DigestInit_ex2(EVP_MD_CTX *ctx, const EVP_MD *type, + const OSSL_PARAM params[]) +{ + return evp_md_init_internal(ctx, type, params, NULL); +} + +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) +{ + EVP_MD_CTX_reset(ctx); + return evp_md_init_internal(ctx, type, NULL, NULL); +} + +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) +{ + return evp_md_init_internal(ctx, type, NULL, impl); +} + int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) { if (count == 0) return 1; + if (ctx->pctx != NULL + && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx) + && ctx->pctx->op.sig.algctx != NULL) { + /* + * Prior to OpenSSL 3.0 EVP_DigestSignUpdate() and + * EVP_DigestVerifyUpdate() were just macros for EVP_DigestUpdate(). + * Some code calls EVP_DigestUpdate() directly even when initialised + * with EVP_DigestSignInit_ex() or + * EVP_DigestVerifyInit_ex(), so we detect that and redirect to + * the correct EVP_Digest*Update() function + */ + if (ctx->pctx->operation == EVP_PKEY_OP_SIGNCTX) + return EVP_DigestSignUpdate(ctx, data, count); + if (ctx->pctx->operation == EVP_PKEY_OP_VERIFYCTX) + return EVP_DigestVerifyUpdate(ctx, data, count); + ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); + return 0; + } + + if (ctx->digest == NULL + || ctx->digest->prov == NULL + || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) + goto legacy; + + if (ctx->digest->dupdate == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); + return 0; + } + return ctx->digest->dupdate(ctx->algctx, data, count); + + /* Code below to be removed when legacy support is dropped. */ + legacy: return ctx->update(ctx, data, count); } @@ -176,14 +422,46 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) } /* The caller can assume that this removes any secret data from the context */ -int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize) { - int ret; + int ret, sz; + size_t size = 0; + size_t mdsize = 0; + + if (ctx->digest == NULL) + return 0; + + sz = EVP_MD_get_size(ctx->digest); + if (sz < 0) + return 0; + mdsize = sz; + if (ctx->digest->prov == NULL) + goto legacy; + + if (ctx->digest->dfinal == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + + ret = ctx->digest->dfinal(ctx->algctx, md, &size, mdsize); + + if (isize != NULL) { + if (size <= UINT_MAX) { + *isize = (int)size; + } else { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + ret = 0; + } + } - OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); + return ret; + + /* Code below to be removed when legacy support is dropped. */ + legacy: + OPENSSL_assert(mdsize <= EVP_MAX_MD_SIZE); ret = ctx->digest->final(ctx, md); - if (size != NULL) - *size = ctx->digest->md_size; + if (isize != NULL) + *isize = mdsize; if (ctx->digest->cleanup) { ctx->digest->cleanup(ctx); EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); @@ -195,19 +473,42 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size) { int ret = 0; + OSSL_PARAM params[2]; + size_t i = 0; + if (ctx->digest == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_NULL_ALGORITHM); + return 0; + } + + if (ctx->digest->prov == NULL) + goto legacy; + + if (ctx->digest->dfinal == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + + params[i++] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &size); + params[i++] = OSSL_PARAM_construct_end(); + + if (EVP_MD_CTX_set_params(ctx, params) > 0) + ret = ctx->digest->dfinal(ctx->algctx, md, &size, size); + + return ret; + +legacy: if (ctx->digest->flags & EVP_MD_FLAG_XOF && size <= INT_MAX && ctx->digest->md_ctrl(ctx, EVP_MD_CTRL_XOF_LEN, (int)size, NULL)) { ret = ctx->digest->final(ctx, md); - if (ctx->digest->cleanup != NULL) { ctx->digest->cleanup(ctx); EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); } OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); } else { - EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_NOT_XOF_OR_INVALID_LENGTH); + ERR_raise(ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH); } return ret; @@ -221,15 +522,74 @@ int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { + int digest_change = 0; unsigned char *tmp_buf; - if ((in == NULL) || (in->digest == NULL)) { - EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED); + + if (in == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); return 0; } -#ifndef OPENSSL_NO_ENGINE + + if (in->digest == NULL) { + /* copying uninitialized digest context */ + EVP_MD_CTX_reset(out); + if (out->fetched_digest != NULL) + EVP_MD_free(out->fetched_digest); + *out = *in; + goto clone_pkey; + } + + if (in->digest->prov == NULL + || (in->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) + goto legacy; + + if (in->digest->dupctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX); + return 0; + } + + evp_md_ctx_reset_ex(out, 1); + digest_change = (out->fetched_digest != in->fetched_digest); + if (digest_change && out->fetched_digest != NULL) + EVP_MD_free(out->fetched_digest); + *out = *in; + /* NULL out pointers in case of error */ + out->pctx = NULL; + out->algctx = NULL; + + if (digest_change && in->fetched_digest != NULL) + EVP_MD_up_ref(in->fetched_digest); + + if (in->algctx != NULL) { + out->algctx = in->digest->dupctx(in->algctx); + if (out->algctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX); + return 0; + } + } + + clone_pkey: + /* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */ + EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); +#ifndef FIPS_MODULE + if (in->pctx != NULL) { + out->pctx = EVP_PKEY_CTX_dup(in->pctx); + if (out->pctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX); + EVP_MD_CTX_reset(out); + return 0; + } + } +#endif + + return 1; + + /* Code below to be removed when legacy support is dropped. */ + legacy: +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) /* Make sure it's safe to copy a digest context using an ENGINE */ if (in->engine && !ENGINE_init(in->engine)) { - EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_EVP, ERR_R_ENGINE_LIB); return 0; } #endif @@ -258,7 +618,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) else { out->md_data = OPENSSL_malloc(out->digest->ctx_size); if (out->md_data == NULL) { - EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } } @@ -267,6 +627,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) out->update = in->update; +#ifndef FIPS_MODULE if (in->pctx) { out->pctx = EVP_PKEY_CTX_dup(in->pctx); if (!out->pctx) { @@ -274,6 +635,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) return 0; } } +#endif if (out->digest->copy) return out->digest->copy(out, in); @@ -299,13 +661,448 @@ int EVP_Digest(const void *data, size_t count, return ret; } -int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2) +int EVP_Q_digest(OSSL_LIB_CTX *libctx, const char *name, const char *propq, + const void *data, size_t datalen, + unsigned char *md, size_t *mdlen) { - if (ctx->digest && ctx->digest->md_ctrl) { - int ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2); - if (ret <= 0) - return 0; - return 1; + EVP_MD *digest = EVP_MD_fetch(libctx, name, propq); + unsigned int temp = 0; + int ret = 0; + + if (digest != NULL) { + ret = EVP_Digest(data, datalen, md, &temp, digest, NULL); + EVP_MD_free(digest); + } + if (mdlen != NULL) + *mdlen = temp; + return ret; +} + +int EVP_MD_get_params(const EVP_MD *digest, OSSL_PARAM params[]) +{ + if (digest != NULL && digest->get_params != NULL) + return digest->get_params(params); + return 0; +} + +const OSSL_PARAM *EVP_MD_gettable_params(const EVP_MD *digest) +{ + if (digest != NULL && digest->gettable_params != NULL) + return digest->gettable_params( + ossl_provider_ctx(EVP_MD_get0_provider(digest))); + return NULL; +} + +int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[]) +{ + EVP_PKEY_CTX *pctx = ctx->pctx; + + /* If we have a pctx then we should try that first */ + if (pctx != NULL + && (pctx->operation == EVP_PKEY_OP_VERIFYCTX + || pctx->operation == EVP_PKEY_OP_SIGNCTX) + && pctx->op.sig.algctx != NULL + && pctx->op.sig.signature->set_ctx_md_params != NULL) + return pctx->op.sig.signature->set_ctx_md_params(pctx->op.sig.algctx, + params); + + if (ctx->digest != NULL && ctx->digest->set_ctx_params != NULL) + return ctx->digest->set_ctx_params(ctx->algctx, params); + + return 0; +} + +const OSSL_PARAM *EVP_MD_settable_ctx_params(const EVP_MD *md) +{ + void *provctx; + + if (md != NULL && md->settable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_MD_get0_provider(md)); + return md->settable_ctx_params(NULL, provctx); + } + return NULL; +} + +const OSSL_PARAM *EVP_MD_CTX_settable_params(EVP_MD_CTX *ctx) +{ + EVP_PKEY_CTX *pctx; + void *alg; + + if (ctx == NULL) + return NULL; + + /* If we have a pctx then we should try that first */ + pctx = ctx->pctx; + if (pctx != NULL + && (pctx->operation == EVP_PKEY_OP_VERIFYCTX + || pctx->operation == EVP_PKEY_OP_SIGNCTX) + && pctx->op.sig.algctx != NULL + && pctx->op.sig.signature->settable_ctx_md_params != NULL) + return pctx->op.sig.signature->settable_ctx_md_params( + pctx->op.sig.algctx); + + if (ctx->digest != NULL && ctx->digest->settable_ctx_params != NULL) { + alg = ossl_provider_ctx(EVP_MD_get0_provider(ctx->digest)); + return ctx->digest->settable_ctx_params(ctx->algctx, alg); } + + return NULL; +} + +int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[]) +{ + EVP_PKEY_CTX *pctx = ctx->pctx; + + /* If we have a pctx then we should try that first */ + if (pctx != NULL + && (pctx->operation == EVP_PKEY_OP_VERIFYCTX + || pctx->operation == EVP_PKEY_OP_SIGNCTX) + && pctx->op.sig.algctx != NULL + && pctx->op.sig.signature->get_ctx_md_params != NULL) + return pctx->op.sig.signature->get_ctx_md_params(pctx->op.sig.algctx, + params); + + if (ctx->digest != NULL && ctx->digest->get_params != NULL) + return ctx->digest->get_ctx_params(ctx->algctx, params); + return 0; } + +const OSSL_PARAM *EVP_MD_gettable_ctx_params(const EVP_MD *md) +{ + void *provctx; + + if (md != NULL && md->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_MD_get0_provider(md)); + return md->gettable_ctx_params(NULL, provctx); + } + return NULL; +} + +const OSSL_PARAM *EVP_MD_CTX_gettable_params(EVP_MD_CTX *ctx) +{ + EVP_PKEY_CTX *pctx; + void *provctx; + + if (ctx == NULL) + return NULL; + + /* If we have a pctx then we should try that first */ + pctx = ctx->pctx; + if (pctx != NULL + && (pctx->operation == EVP_PKEY_OP_VERIFYCTX + || pctx->operation == EVP_PKEY_OP_SIGNCTX) + && pctx->op.sig.algctx != NULL + && pctx->op.sig.signature->gettable_ctx_md_params != NULL) + return pctx->op.sig.signature->gettable_ctx_md_params( + pctx->op.sig.algctx); + + if (ctx->digest != NULL && ctx->digest->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_MD_get0_provider(ctx->digest)); + return ctx->digest->gettable_ctx_params(ctx->algctx, provctx); + } + return NULL; +} + +int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2) +{ + int ret = EVP_CTRL_RET_UNSUPPORTED; + int set_params = 1; + size_t sz; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (ctx->digest != NULL && ctx->digest->prov == NULL) + goto legacy; + + switch (cmd) { + case EVP_MD_CTRL_XOF_LEN: + sz = (size_t)p1; + params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &sz); + break; + case EVP_MD_CTRL_MICALG: + set_params = 0; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_DIGEST_PARAM_MICALG, + p2, p1 ? p1 : 9999); + break; + case EVP_CTRL_SSL3_MASTER_SECRET: + params[0] = OSSL_PARAM_construct_octet_string(OSSL_DIGEST_PARAM_SSL3_MS, + p2, p1); + break; + default: + goto conclude; + } + + if (set_params) + ret = EVP_MD_CTX_set_params(ctx, params); + else + ret = EVP_MD_CTX_get_params(ctx, params); + goto conclude; + + + /* Code below to be removed when legacy support is dropped. */ + legacy: + if (ctx->digest->md_ctrl == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED); + return 0; + } + + ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2); + conclude: + if (ret <= 0) + return 0; + return ret; +} + +EVP_MD *evp_md_new(void) +{ + EVP_MD *md = OPENSSL_zalloc(sizeof(*md)); + + if (md != NULL) { + md->lock = CRYPTO_THREAD_lock_new(); + if (md->lock == NULL) { + OPENSSL_free(md); + return NULL; + } + md->refcnt = 1; + } + return md; +} + +/* + * FIPS module note: since internal fetches will be entirely + * provider based, we know that none of its code depends on legacy + * NIDs or any functionality that use them. + */ +#ifndef FIPS_MODULE +static void set_legacy_nid(const char *name, void *vlegacy_nid) +{ + int nid; + int *legacy_nid = vlegacy_nid; + /* + * We use lowest level function to get the associated method, because + * higher level functions such as EVP_get_digestbyname() have changed + * to look at providers too. + */ + const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); + + if (*legacy_nid == -1) /* We found a clash already */ + return; + + if (legacy_method == NULL) + return; + nid = EVP_MD_nid(legacy_method); + if (*legacy_nid != NID_undef && *legacy_nid != nid) { + *legacy_nid = -1; + return; + } + *legacy_nid = nid; +} +#endif + +static int evp_md_cache_constants(EVP_MD *md) +{ + int ok, xof = 0, algid_absent = 0; + size_t blksz = 0; + size_t mdsize = 0; + OSSL_PARAM params[5]; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, &blksz); + params[1] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &mdsize); + params[2] = OSSL_PARAM_construct_int(OSSL_DIGEST_PARAM_XOF, &xof); + params[3] = OSSL_PARAM_construct_int(OSSL_DIGEST_PARAM_ALGID_ABSENT, + &algid_absent); + params[4] = OSSL_PARAM_construct_end(); + ok = evp_do_md_getparams(md, params) > 0; + if (mdsize > INT_MAX || blksz > INT_MAX) + ok = 0; + if (ok) { + md->block_size = (int)blksz; + md->md_size = (int)mdsize; + if (xof) + md->flags |= EVP_MD_FLAG_XOF; + if (algid_absent) + md->flags |= EVP_MD_FLAG_DIGALGID_ABSENT; + } + return ok; +} + +static void *evp_md_from_algorithm(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + const OSSL_DISPATCH *fns = algodef->implementation; + EVP_MD *md = NULL; + int fncnt = 0; + + /* EVP_MD_fetch() will set the legacy NID if available */ + if ((md = evp_md_new()) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + +#ifndef FIPS_MODULE + md->type = NID_undef; + if (!evp_names_do_all(prov, name_id, set_legacy_nid, &md->type) + || md->type == -1) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + EVP_MD_free(md); + return NULL; + } +#endif + + md->name_id = name_id; + if ((md->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { + EVP_MD_free(md); + return NULL; + } + md->description = algodef->algorithm_description; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_DIGEST_NEWCTX: + if (md->newctx == NULL) { + md->newctx = OSSL_FUNC_digest_newctx(fns); + fncnt++; + } + break; + case OSSL_FUNC_DIGEST_INIT: + if (md->dinit == NULL) { + md->dinit = OSSL_FUNC_digest_init(fns); + fncnt++; + } + break; + case OSSL_FUNC_DIGEST_UPDATE: + if (md->dupdate == NULL) { + md->dupdate = OSSL_FUNC_digest_update(fns); + fncnt++; + } + break; + case OSSL_FUNC_DIGEST_FINAL: + if (md->dfinal == NULL) { + md->dfinal = OSSL_FUNC_digest_final(fns); + fncnt++; + } + break; + case OSSL_FUNC_DIGEST_DIGEST: + if (md->digest == NULL) + md->digest = OSSL_FUNC_digest_digest(fns); + /* We don't increment fnct for this as it is stand alone */ + break; + case OSSL_FUNC_DIGEST_FREECTX: + if (md->freectx == NULL) { + md->freectx = OSSL_FUNC_digest_freectx(fns); + fncnt++; + } + break; + case OSSL_FUNC_DIGEST_DUPCTX: + if (md->dupctx == NULL) + md->dupctx = OSSL_FUNC_digest_dupctx(fns); + break; + case OSSL_FUNC_DIGEST_GET_PARAMS: + if (md->get_params == NULL) + md->get_params = OSSL_FUNC_digest_get_params(fns); + break; + case OSSL_FUNC_DIGEST_SET_CTX_PARAMS: + if (md->set_ctx_params == NULL) + md->set_ctx_params = OSSL_FUNC_digest_set_ctx_params(fns); + break; + case OSSL_FUNC_DIGEST_GET_CTX_PARAMS: + if (md->get_ctx_params == NULL) + md->get_ctx_params = OSSL_FUNC_digest_get_ctx_params(fns); + break; + case OSSL_FUNC_DIGEST_GETTABLE_PARAMS: + if (md->gettable_params == NULL) + md->gettable_params = OSSL_FUNC_digest_gettable_params(fns); + break; + case OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS: + if (md->settable_ctx_params == NULL) + md->settable_ctx_params = + OSSL_FUNC_digest_settable_ctx_params(fns); + break; + case OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS: + if (md->gettable_ctx_params == NULL) + md->gettable_ctx_params = + OSSL_FUNC_digest_gettable_ctx_params(fns); + break; + } + } + if ((fncnt != 0 && fncnt != 5) + || (fncnt == 0 && md->digest == NULL)) { + /* + * In order to be a consistent set of functions we either need the + * whole set of init/update/final etc functions or none of them. + * The "digest" function can standalone. We at least need one way to + * generate digests. + */ + EVP_MD_free(md); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + md->prov = prov; + if (prov != NULL) + ossl_provider_up_ref(prov); + + if (!evp_md_cache_constants(md)) { + EVP_MD_free(md); + ERR_raise(ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED); + md = NULL; + } + + return md; +} + +static int evp_md_up_ref(void *md) +{ + return EVP_MD_up_ref(md); +} + +static void evp_md_free(void *md) +{ + EVP_MD_free(md); +} + +EVP_MD *EVP_MD_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties) +{ + EVP_MD *md = + evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties, + evp_md_from_algorithm, evp_md_up_ref, evp_md_free); + + return md; +} + +int EVP_MD_up_ref(EVP_MD *md) +{ + int ref = 0; + + if (md->origin == EVP_ORIG_DYNAMIC) + CRYPTO_UP_REF(&md->refcnt, &ref, md->lock); + return 1; +} + +void EVP_MD_free(EVP_MD *md) +{ + int i; + + if (md == NULL || md->origin != EVP_ORIG_DYNAMIC) + return; + + CRYPTO_DOWN_REF(&md->refcnt, &i, md->lock); + if (i > 0) + return; + evp_md_free_int(md); +} + +void EVP_MD_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_MD *mac, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_DIGEST, + (void (*)(void *, void *))fn, arg, + evp_md_from_algorithm, evp_md_up_ref, evp_md_free); +} diff --git a/crypto/openssl/crypto/evp/dsa_ctrl.c b/crypto/openssl/crypto/evp/dsa_ctrl.c new file mode 100644 index 000000000000..531a21fa8d4d --- /dev/null +++ b/crypto/openssl/crypto/evp/dsa_ctrl.c @@ -0,0 +1,132 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include "crypto/evp.h" + +static int dsa_paramgen_check(EVP_PKEY_CTX *ctx) +{ + if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + /* If key type not DSA return error */ + if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_DSA) + return -1; + return 1; +} + +int EVP_PKEY_CTX_set_dsa_paramgen_type(EVP_PKEY_CTX *ctx, const char *name) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dsa_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, + (char *)name, 0); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dsa_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dsa_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GINDEX, &gindex); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dsa_paramgen_seed(EVP_PKEY_CTX *ctx, + const unsigned char *seed, + size_t seedlen) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dsa_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_FFC_SEED, + (void *)seed, seedlen); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) +{ + int ret; + OSSL_PARAM params[2], *p = params; + size_t bits = nbits; + + if ((ret = dsa_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_PBITS, &bits); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, int qbits) +{ + int ret; + OSSL_PARAM params[2], *p = params; + size_t bits2 = qbits; + + if ((ret = dsa_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_QBITS, &bits2); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dsa_paramgen_md_props(EVP_PKEY_CTX *ctx, + const char *md_name, + const char *md_properties) +{ + int ret; + OSSL_PARAM params[3], *p = params; + + if ((ret = dsa_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST, + (char *)md_name, 0); + if (md_properties != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST_PROPS, + (char *)md_properties, 0); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +#if !defined(FIPS_MODULE) +int EVP_PKEY_CTX_set_dsa_paramgen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, (void *)(md)); +} +#endif diff --git a/crypto/openssl/crypto/evp/e_aes.c b/crypto/openssl/crypto/evp/e_aes.c index 715fac9f88df..52b9e87c1e2b 100644 --- a/crypto/openssl/crypto/evp/e_aes.c +++ b/crypto/openssl/crypto/evp/e_aes.c @@ -1,27 +1,37 @@ /* * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * This file uses the low level AES functions (which are deprecated for + * non-internal use) in order to implement the EVP AES ciphers. + */ +#include "internal/deprecated.h" + +#include +#include #include #include #include #include -#include -#include #include -#include "crypto/evp.h" -#include "modes_local.h" #include +#include +#include "crypto/evp.h" +#include "internal/cryptlib.h" +#include "crypto/modes.h" +#include "crypto/siv.h" +#include "crypto/aes_platform.h" #include "evp_local.h" typedef struct { union { - double align; + OSSL_UNION_ALIGN; AES_KEY ks; } ks; block128_f block; @@ -33,7 +43,7 @@ typedef struct { typedef struct { union { - double align; + OSSL_UNION_ALIGN; AES_KEY ks; } ks; /* AES key schedule to use */ int key_set; /* Set if key initialised */ @@ -43,13 +53,15 @@ typedef struct { int ivlen; /* IV length */ int taglen; int iv_gen; /* It is OK to generate IVs */ + int iv_gen_rand; /* No IV was specified, so generate a rand IV */ int tls_aad_len; /* TLS AAD length */ + uint64_t tls_enc_records; /* Number of TLS records encrypted */ ctr128_f ctr; } EVP_AES_GCM_CTX; typedef struct { union { - double align; + OSSL_UNION_ALIGN; AES_KEY ks; } ks1, ks2; /* AES key schedules to use */ XTS128_CONTEXT xts; @@ -59,9 +71,15 @@ typedef struct { const unsigned char iv[16]); } EVP_AES_XTS_CTX; +#ifdef FIPS_MODULE +static const int allow_insecure_decrypt = 0; +#else +static const int allow_insecure_decrypt = 1; +#endif + typedef struct { union { - double align; + OSSL_UNION_ALIGN; AES_KEY ks; } ks; /* AES key schedule to use */ int key_set; /* Set if key initialised */ @@ -77,11 +95,11 @@ typedef struct { #ifndef OPENSSL_NO_OCB typedef struct { union { - double align; + OSSL_UNION_ALIGN; AES_KEY ks; } ksenc; /* AES key schedule to use for encryption */ union { - double align; + OSSL_UNION_ALIGN; AES_KEY ks; } ksdec; /* AES key schedule to use for decryption */ int key_set; /* Set if key initialised */ @@ -100,50 +118,6 @@ typedef struct { #define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) -#ifdef VPAES_ASM -int vpaes_set_encrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); -int vpaes_set_decrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); - -void vpaes_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void vpaes_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); - -void vpaes_cbc_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key, unsigned char *ivec, int enc); -#endif -#ifdef BSAES_ASM -void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char ivec[16], int enc); -void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - const unsigned char ivec[16]); -void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out, - size_t len, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char iv[16]); -void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, - size_t len, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char iv[16]); -#endif -#ifdef AES_CTR_ASM -void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - const unsigned char ivec[AES_BLOCK_SIZE]); -#endif -#ifdef AES_XTS_ASM -void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); -void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); -#endif - /* increment counter (64-bit int) by 1 */ static void ctr64_inc(unsigned char *counter) { @@ -160,105 +134,8 @@ static void ctr64_inc(unsigned char *counter) } while (n); } -#if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC)) -# include "ppc_arch.h" -# ifdef VPAES_ASM -# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC) -# endif -# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207) -# define HWAES_set_encrypt_key aes_p8_set_encrypt_key -# define HWAES_set_decrypt_key aes_p8_set_decrypt_key -# define HWAES_encrypt aes_p8_encrypt -# define HWAES_decrypt aes_p8_decrypt -# define HWAES_cbc_encrypt aes_p8_cbc_encrypt -# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks -# define HWAES_xts_encrypt aes_p8_xts_encrypt -# define HWAES_xts_decrypt aes_p8_xts_decrypt -#endif - -#if defined(OPENSSL_CPUID_OBJ) && ( \ - ((defined(__i386) || defined(__i386__) || \ - defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64) ) - -extern unsigned int OPENSSL_ia32cap_P[]; - -# ifdef VPAES_ASM -# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) -# endif -# ifdef BSAES_ASM -# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) -# endif -/* - * AES-NI section - */ -# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32))) - -int aesni_set_encrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); -int aesni_set_decrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); - -void aesni_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void aesni_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); - -void aesni_ecb_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, const AES_KEY *key, int enc); -void aesni_cbc_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key, unsigned char *ivec, int enc); - -void aesni_ctr32_encrypt_blocks(const unsigned char *in, - unsigned char *out, - size_t blocks, - const void *key, const unsigned char *ivec); - -void aesni_xts_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); - -void aesni_xts_decrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); - -void aesni_ccm64_encrypt_blocks(const unsigned char *in, - unsigned char *out, - size_t blocks, - const void *key, - const unsigned char ivec[16], - unsigned char cmac[16]); - -void aesni_ccm64_decrypt_blocks(const unsigned char *in, - unsigned char *out, - size_t blocks, - const void *key, - const unsigned char ivec[16], - unsigned char cmac[16]); - +#if defined(AESNI_CAPABLE) # if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) -size_t aesni_gcm_encrypt(const unsigned char *in, - unsigned char *out, - size_t len, - const void *key, unsigned char ivec[16], u64 *Xi); -# define AES_gcm_encrypt aesni_gcm_encrypt -size_t aesni_gcm_decrypt(const unsigned char *in, - unsigned char *out, - size_t len, - const void *key, unsigned char ivec[16], u64 *Xi); -# define AES_gcm_decrypt aesni_gcm_decrypt -void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *in, - size_t len); -# define AES_GCM_ASM(gctx) (gctx->ctr==aesni_ctr32_encrypt_blocks && \ - gctx->gcm.ghash==gcm_ghash_avx) # define AES_GCM_ASM2(gctx) (gctx->gcm.block==(block128_f)aesni_encrypt && \ gctx->gcm.ghash==gcm_ghash_avx) # undef AES_GCM_ASM2 /* minor size optimization */ @@ -270,16 +147,18 @@ static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, int ret, mode; EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx); - mode = EVP_CIPHER_CTX_mode(ctx); + mode = EVP_CIPHER_CTX_get_mode(ctx); if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { - ret = aesni_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + ret = aesni_set_decrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &dat->ks.ks); dat->block = (block128_f) aesni_decrypt; dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? (cbc128_f) aesni_cbc_encrypt : NULL; } else { - ret = aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + ret = aesni_set_encrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &dat->ks.ks); dat->block = (block128_f) aesni_encrypt; if (mode == EVP_CIPH_CBC_MODE) @@ -291,7 +170,7 @@ static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } if (ret < 0) { - EVPerr(EVP_F_AESNI_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_EVP, EVP_R_AES_KEY_SETUP_FAILED); return 0; } @@ -302,8 +181,7 @@ static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { aesni_cbc_encrypt(in, out, len, &EVP_C_DATA(EVP_AES_KEY,ctx)->ks.ks, - EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + ctx->iv, EVP_CIPHER_CTX_is_encrypting(ctx)); return 1; } @@ -311,13 +189,13 @@ static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - size_t bl = EVP_CIPHER_CTX_block_size(ctx); + size_t bl = EVP_CIPHER_CTX_get_block_size(ctx); if (len < bl) return 1; aesni_ecb_encrypt(in, out, len, &EVP_C_DATA(EVP_AES_KEY,ctx)->ks.ks, - EVP_CIPHER_CTX_encrypting(ctx)); + EVP_CIPHER_CTX_is_encrypting(ctx)); return 1; } @@ -349,7 +227,7 @@ static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (!iv && !key) return 1; if (key) { - aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + aesni_set_encrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &gctx->ks.ks); CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) aesni_encrypt); gctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; @@ -389,35 +267,33 @@ static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (key) { /* The key is two half length keys in reality */ - const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2; + const int bytes = EVP_CIPHER_CTX_get_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_AESNI_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS); + if ((!allow_insecure_decrypt || enc) + && CRYPTO_memcmp(key, key + bytes, bytes) == 0) { + ERR_raise(ERR_LIB_EVP, 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, - &xctx->ks1.ks); + aesni_set_encrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) aesni_encrypt; xctx->stream = aesni_xts_encrypt; } else { - aesni_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + aesni_set_decrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) aesni_decrypt; xctx->stream = aesni_xts_decrypt; } - aesni_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks2.ks); + aesni_set_encrypt_key(key + bytes, bits, &xctx->ks2.ks); xctx->xts.block2 = (block128_f) aesni_encrypt; xctx->xts.key1 = &xctx->ks1; @@ -425,7 +301,7 @@ static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (iv) { xctx->xts.key2 = &xctx->ks2; - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16); + memcpy(ctx->iv, iv, 16); } return 1; @@ -442,7 +318,7 @@ static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (!iv && !key) return 1; if (key) { - aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + aesni_set_encrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &cctx->ks.ks); CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, &cctx->ks, (block128_f) aesni_encrypt); @@ -451,7 +327,7 @@ static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, cctx->key_set = 1; } if (iv) { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L); + memcpy(ctx->iv, iv, 15 - cctx->L); cctx->iv_set = 1; } return 1; @@ -462,19 +338,6 @@ static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); # ifndef OPENSSL_NO_OCB -void aesni_ocb_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const void *key, - size_t start_block_num, - unsigned char offset_i[16], - const unsigned char L_[][16], - unsigned char checksum[16]); -void aesni_ocb_decrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const void *key, - size_t start_block_num, - unsigned char offset_i[16], - const unsigned char L_[][16], - unsigned char checksum[16]); - static int aesni_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { @@ -488,9 +351,9 @@ static int aesni_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, * needs both. We could possibly optimise to remove setting the * decrypt for an encryption operation. */ - aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + aesni_set_encrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &octx->ksenc.ks); - aesni_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + aesni_set_decrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &octx->ksdec.ks); if (!CRYPTO_ocb128_init(&octx->ocb, &octx->ksenc.ks, &octx->ksdec.ks, @@ -534,6 +397,7 @@ static int aesni_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static const EVP_CIPHER aesni_##keylen##_##mode = { \ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aesni_init_key, \ aesni_##mode##_cipher, \ NULL, \ @@ -541,8 +405,9 @@ static const EVP_CIPHER aesni_##keylen##_##mode = { \ NULL,NULL,NULL,NULL }; \ static const EVP_CIPHER aes_##keylen##_##mode = { \ nid##_##keylen##_##nmode,blocksize, \ - keylen/8,ivlen, \ + keylen/8,ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aes_init_key, \ aes_##mode##_cipher, \ NULL, \ @@ -554,8 +419,10 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ # define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ static const EVP_CIPHER aesni_##keylen##_##mode = { \ nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \ + ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aesni_##mode##_init_key, \ aesni_##mode##_cipher, \ aes_##mode##_cleanup, \ @@ -563,8 +430,10 @@ static const EVP_CIPHER aesni_##keylen##_##mode = { \ NULL,NULL,aes_##mode##_ctrl,NULL }; \ static const EVP_CIPHER aes_##keylen##_##mode = { \ nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \ + ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aes_##mode##_init_key, \ aes_##mode##_cipher, \ aes_##mode##_cleanup, \ @@ -573,81 +442,7 @@ static const EVP_CIPHER aes_##keylen##_##mode = { \ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ { return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } -#elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) - -# include "sparc_arch.h" - -extern unsigned int OPENSSL_sparcv9cap_P[]; - -/* - * Initial Fujitsu SPARC64 X support - */ -# define HWAES_CAPABLE (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX) -# define HWAES_set_encrypt_key aes_fx_set_encrypt_key -# define HWAES_set_decrypt_key aes_fx_set_decrypt_key -# define HWAES_encrypt aes_fx_encrypt -# define HWAES_decrypt aes_fx_decrypt -# define HWAES_cbc_encrypt aes_fx_cbc_encrypt -# define HWAES_ctr32_encrypt_blocks aes_fx_ctr32_encrypt_blocks - -# define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES) - -void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks); -void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks); -void aes_t4_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void aes_t4_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -/* - * Key-length specific subroutines were chosen for following reason. - * Each SPARC T4 core can execute up to 8 threads which share core's - * resources. Loading as much key material to registers allows to - * minimize references to shared memory interface, as well as amount - * of instructions in inner loops [much needed on T4]. But then having - * non-key-length specific routines would require conditional branches - * either in inner loops or on subroutines' entries. Former is hardly - * acceptable, while latter means code size increase to size occupied - * by multiple key-length specific subroutines, so why fight? - */ -void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec, int /*unused*/); -void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec, int /*unused*/); -void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec, int /*unused*/); -void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec, int /*unused*/); -void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec, int /*unused*/); -void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec, int /*unused*/); -void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - unsigned char *ivec); -void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - unsigned char *ivec); -void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - unsigned char *ivec); -void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); -void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); -void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); -void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); +#elif defined(SPARC_AES_CAPABLE) static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) @@ -655,8 +450,8 @@ static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, int ret, mode, bits; EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx); - mode = EVP_CIPHER_CTX_mode(ctx); - bits = EVP_CIPHER_CTX_key_length(ctx) * 8; + mode = EVP_CIPHER_CTX_get_mode(ctx); + bits = EVP_CIPHER_CTX_get_key_length(ctx) * 8; if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { ret = 0; @@ -713,7 +508,7 @@ static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } if (ret < 0) { - EVPerr(EVP_F_AES_T4_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_EVP, EVP_R_AES_KEY_SETUP_FAILED); return 0; } @@ -755,7 +550,7 @@ static int aes_t4_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (!iv && !key) return 1; if (key) { - int bits = EVP_CIPHER_CTX_key_length(ctx) * 8; + int bits = EVP_CIPHER_CTX_get_key_length(ctx) * 8; aes_t4_set_encrypt_key(key, bits, &gctx->ks.ks); CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) aes_t4_encrypt); @@ -808,17 +603,18 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (key) { /* The key is two half length keys in reality */ - const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2; + const int bytes = EVP_CIPHER_CTX_get_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); + if ((!allow_insecure_decrypt || enc) + && CRYPTO_memcmp(key, key + bytes, bytes) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_XTS_DUPLICATED_KEYS); return 0; } @@ -838,8 +634,7 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, return 0; } } else { - aes_t4_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + aes_t4_set_decrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) aes_t4_decrypt; switch (bits) { case 128: @@ -853,9 +648,7 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } } - aes_t4_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks2.ks); + aes_t4_set_encrypt_key(key + bytes, bits, &xctx->ks2.ks); xctx->xts.block2 = (block128_f) aes_t4_encrypt; xctx->xts.key1 = &xctx->ks1; @@ -863,7 +656,7 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (iv) { xctx->xts.key2 = &xctx->ks2; - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16); + memcpy(ctx->iv, iv, 16); } return 1; @@ -880,7 +673,7 @@ static int aes_t4_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (!iv && !key) return 1; if (key) { - int bits = EVP_CIPHER_CTX_key_length(ctx) * 8; + int bits = EVP_CIPHER_CTX_get_key_length(ctx) * 8; aes_t4_set_encrypt_key(key, bits, &cctx->ks.ks); CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, &cctx->ks, (block128_f) aes_t4_encrypt); @@ -888,7 +681,7 @@ static int aes_t4_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, cctx->key_set = 1; } if (iv) { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L); + memcpy(ctx->iv, iv, 15 - cctx->L); cctx->iv_set = 1; } return 1; @@ -912,9 +705,9 @@ static int aes_t4_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, * needs both. We could possibly optimise to remove setting the * decrypt for an encryption operation. */ - aes_t4_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + aes_t4_set_encrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &octx->ksenc.ks); - aes_t4_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + aes_t4_set_decrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &octx->ksdec.ks); if (!CRYPTO_ocb128_init(&octx->ocb, &octx->ksenc.ks, &octx->ksdec.ks, @@ -953,10 +746,16 @@ static int aes_t4_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); # endif /* OPENSSL_NO_OCB */ +# ifndef OPENSSL_NO_SIV +# define aes_t4_siv_init_key aes_siv_init_key +# define aes_t4_siv_cipher aes_siv_cipher +# endif /* OPENSSL_NO_SIV */ + # define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ static const EVP_CIPHER aes_t4_##keylen##_##mode = { \ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aes_t4_init_key, \ aes_t4_##mode##_cipher, \ NULL, \ @@ -966,6 +765,7 @@ static const EVP_CIPHER aes_##keylen##_##mode = { \ nid##_##keylen##_##nmode,blocksize, \ keylen/8,ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aes_init_key, \ aes_##mode##_cipher, \ NULL, \ @@ -977,8 +777,10 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ # define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ static const EVP_CIPHER aes_t4_##keylen##_##mode = { \ nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \ + ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aes_t4_##mode##_init_key, \ aes_t4_##mode##_cipher, \ aes_##mode##_cleanup, \ @@ -986,8 +788,10 @@ static const EVP_CIPHER aes_t4_##keylen##_##mode = { \ NULL,NULL,aes_##mode##_ctrl,NULL }; \ static const EVP_CIPHER aes_##keylen##_##mode = { \ nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \ + ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aes_##mode##_init_key, \ aes_##mode##_cipher, \ aes_##mode##_cleanup, \ @@ -996,15 +800,11 @@ static const EVP_CIPHER aes_##keylen##_##mode = { \ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ { return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; } -#elif defined(OPENSSL_CPUID_OBJ) && defined(__s390__) -/* - * IBM S390X support - */ -# include "s390x_arch.h" - +#elif defined(S390X_aes_128_CAPABLE) +/* IBM S390X support */ typedef struct { union { - double align; + OSSL_UNION_ALIGN; /*- * KM-AES parameter block - begin * (see z/Architecture Principles of Operation >= SA22-7832-06) @@ -1019,7 +819,7 @@ typedef struct { typedef struct { union { - double align; + OSSL_UNION_ALIGN; /*- * KMO-AES parameter block - begin * (see z/Architecture Principles of Operation >= SA22-7832-08) @@ -1037,7 +837,7 @@ typedef struct { typedef struct { union { - double align; + OSSL_UNION_ALIGN; /*- * KMF-AES parameter block - begin * (see z/Architecture Principles of Operation >= SA22-7832-08) @@ -1055,7 +855,7 @@ typedef struct { typedef struct { union { - double align; + OSSL_UNION_ALIGN; /*- * KMA-GCM-AES parameter block - begin * (see z/Architecture Principles of Operation >= SA22-7832-11) @@ -1099,11 +899,12 @@ typedef struct { int kreslen; int tls_aad_len; + uint64_t tls_enc_records; /* Number of TLS records encrypted */ } S390X_AES_GCM_CTX; typedef struct { union { - double align; + OSSL_UNION_ALIGN; /*- * Padding is chosen so that ccm.kmac_param.k overlaps with key.k and * ccm.fc with key.k.rounds. Remember that on s390x, an AES_KEY's @@ -1153,25 +954,11 @@ typedef struct { } aes; } S390X_AES_CCM_CTX; -/* Convert key size to function code: [16,24,32] -> [18,19,20]. */ -# define S390X_AES_FC(keylen) (S390X_AES_128 + ((((keylen) << 3) - 128) >> 6)) - -/* Most modes of operation need km for partial block processing. */ -# define S390X_aes_128_CAPABLE (OPENSSL_s390xcap_P.km[0] & \ - S390X_CAPBIT(S390X_AES_128)) -# define S390X_aes_192_CAPABLE (OPENSSL_s390xcap_P.km[0] & \ - S390X_CAPBIT(S390X_AES_192)) -# define S390X_aes_256_CAPABLE (OPENSSL_s390xcap_P.km[0] & \ - S390X_CAPBIT(S390X_AES_256)) - # define s390x_aes_init_key aes_init_key static int s390x_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); -# define S390X_aes_128_cbc_CAPABLE 0 /* checked by callee */ -# define S390X_aes_192_cbc_CAPABLE 0 -# define S390X_aes_256_cbc_CAPABLE 0 -# define S390X_AES_CBC_CTX EVP_AES_KEY +# define S390X_AES_CBC_CTX EVP_AES_KEY # define s390x_aes_cbc_init_key aes_init_key @@ -1179,22 +966,18 @@ static int s390x_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int s390x_aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define S390X_aes_128_ecb_CAPABLE S390X_aes_128_CAPABLE -# define S390X_aes_192_ecb_CAPABLE S390X_aes_192_CAPABLE -# define S390X_aes_256_ecb_CAPABLE S390X_aes_256_CAPABLE - static int s390x_aes_ecb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { S390X_AES_ECB_CTX *cctx = EVP_C_DATA(S390X_AES_ECB_CTX, ctx); - const int keylen = EVP_CIPHER_CTX_key_length(ctx); - - cctx->fc = S390X_AES_FC(keylen) | (enc ? 0 : S390X_DECRYPT); + const int keylen = EVP_CIPHER_CTX_get_key_length(ctx); - if (key != NULL) - memcpy(cctx->km.param.k, key, keylen); + cctx->fc = S390X_AES_FC(keylen); + if (!enc) + cctx->fc |= S390X_DECRYPT; + memcpy(cctx->km.param.k, key, keylen); return 1; } @@ -1207,32 +990,19 @@ static int s390x_aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } -# define S390X_aes_128_ofb_CAPABLE (S390X_aes_128_CAPABLE && \ - (OPENSSL_s390xcap_P.kmo[0] & \ - S390X_CAPBIT(S390X_AES_128))) -# define S390X_aes_192_ofb_CAPABLE (S390X_aes_192_CAPABLE && \ - (OPENSSL_s390xcap_P.kmo[0] & \ - S390X_CAPBIT(S390X_AES_192))) -# define S390X_aes_256_ofb_CAPABLE (S390X_aes_256_CAPABLE && \ - (OPENSSL_s390xcap_P.kmo[0] & \ - S390X_CAPBIT(S390X_AES_256))) - static int s390x_aes_ofb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *ivec, int enc) { S390X_AES_OFB_CTX *cctx = EVP_C_DATA(S390X_AES_OFB_CTX, ctx); - const unsigned char *oiv = EVP_CIPHER_CTX_original_iv(ctx); - const int keylen = EVP_CIPHER_CTX_key_length(ctx); - const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); + const unsigned char *iv = ctx->oiv; + const int keylen = EVP_CIPHER_CTX_get_key_length(ctx); + const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); + memcpy(cctx->kmo.param.cv, iv, ivlen); + memcpy(cctx->kmo.param.k, key, keylen); cctx->fc = S390X_AES_FC(keylen); - - if (key != NULL) - memcpy(cctx->kmo.param.k, key, keylen); - cctx->res = 0; - memcpy(cctx->kmo.param.cv, oiv, ivlen); return 1; } @@ -1240,7 +1010,7 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { S390X_AES_OFB_CTX *cctx = EVP_C_DATA(S390X_AES_OFB_CTX, ctx); - const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); + const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); int n = cctx->res; int rem; @@ -1279,33 +1049,23 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } -# define S390X_aes_128_cfb_CAPABLE (S390X_aes_128_CAPABLE && \ - (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_128))) -# define S390X_aes_192_cfb_CAPABLE (S390X_aes_192_CAPABLE && \ - (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_192))) -# define S390X_aes_256_cfb_CAPABLE (S390X_aes_256_CAPABLE && \ - (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_256))) - static int s390x_aes_cfb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *ivec, int enc) { S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx); - const unsigned char *oiv = EVP_CIPHER_CTX_original_iv(ctx); - const int keylen = EVP_CIPHER_CTX_key_length(ctx); - const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); + const unsigned char *iv = ctx->oiv; + const int keylen = EVP_CIPHER_CTX_get_key_length(ctx); + const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); - cctx->fc = S390X_AES_FC(keylen) | (enc ? 0 : S390X_DECRYPT) - | (16 << 24); /* 16 bytes cipher feedback */ - - if (key != NULL) - memcpy(cctx->kmf.param.k, key, keylen); + cctx->fc = S390X_AES_FC(keylen); + cctx->fc |= 16 << 24; /* 16 bytes cipher feedback */ + if (!enc) + cctx->fc |= S390X_DECRYPT; cctx->res = 0; - memcpy(cctx->kmf.param.cv, oiv, ivlen); + memcpy(cctx->kmf.param.cv, iv, ivlen); + memcpy(cctx->kmf.param.k, key, keylen); return 1; } @@ -1313,9 +1073,9 @@ static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx); - const int keylen = EVP_CIPHER_CTX_key_length(ctx); - const int enc = EVP_CIPHER_CTX_encrypting(ctx); - const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); + const int keylen = EVP_CIPHER_CTX_get_key_length(ctx); + const int enc = EVP_CIPHER_CTX_is_encrypting(ctx); + const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); int n = cctx->res; int rem; @@ -1359,30 +1119,22 @@ static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } -# define S390X_aes_128_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_128)) -# define S390X_aes_192_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_192)) -# define S390X_aes_256_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \ - S390X_CAPBIT(S390X_AES_256)) - static int s390x_aes_cfb8_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *ivec, int enc) { S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx); - const unsigned char *oiv = EVP_CIPHER_CTX_original_iv(ctx); - const int keylen = EVP_CIPHER_CTX_key_length(ctx); - const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); - - cctx->fc = S390X_AES_FC(keylen) | (enc ? 0 : S390X_DECRYPT) - | (1 << 24); /* 1 byte cipher feedback flag */ + const unsigned char *iv = ctx->oiv; + const int keylen = EVP_CIPHER_CTX_get_key_length(ctx); + const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); - if (key != NULL) - memcpy(cctx->kmf.param.k, key, keylen); + cctx->fc = S390X_AES_FC(keylen); + cctx->fc |= 1 << 24; /* 1 byte cipher feedback */ + if (!enc) + cctx->fc |= S390X_DECRYPT; - cctx->res = 0; - memcpy(cctx->kmf.param.cv, oiv, ivlen); + memcpy(cctx->kmf.param.cv, iv, ivlen); + memcpy(cctx->kmf.param.k, key, keylen); return 1; } @@ -1390,7 +1142,7 @@ static int s390x_aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx); - const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); + const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); memcpy(cctx->kmf.param.cv, iv, ivlen); @@ -1399,20 +1151,13 @@ static int s390x_aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } -# define S390X_aes_128_cfb1_CAPABLE 0 -# define S390X_aes_192_cfb1_CAPABLE 0 -# define S390X_aes_256_cfb1_CAPABLE 0 - # define s390x_aes_cfb1_init_key aes_init_key # define s390x_aes_cfb1_cipher aes_cfb1_cipher static int s390x_aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define S390X_aes_128_ctr_CAPABLE 0 /* checked by callee */ -# define S390X_aes_192_ctr_CAPABLE 0 -# define S390X_aes_256_ctr_CAPABLE 0 -# define S390X_AES_CTR_CTX EVP_AES_KEY +# define S390X_AES_CTR_CTX EVP_AES_KEY # define s390x_aes_ctr_init_key aes_init_key @@ -1420,18 +1165,8 @@ static int s390x_aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int s390x_aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define S390X_aes_128_gcm_CAPABLE (S390X_aes_128_CAPABLE && \ - (OPENSSL_s390xcap_P.kma[0] & \ - S390X_CAPBIT(S390X_AES_128))) -# define S390X_aes_192_gcm_CAPABLE (S390X_aes_192_CAPABLE && \ - (OPENSSL_s390xcap_P.kma[0] & \ - S390X_CAPBIT(S390X_AES_192))) -# define S390X_aes_256_gcm_CAPABLE (S390X_aes_256_CAPABLE && \ - (OPENSSL_s390xcap_P.kma[0] & \ - S390X_CAPBIT(S390X_AES_256))) - /* iv + padding length for iv lengths != 12 */ -# define S390X_gcm_ivpadlen(i) ((((i) + 15) >> 4 << 4) + 16) +# define S390X_gcm_ivpadlen(i) ((((i) + 15) >> 4 << 4) + 16) /*- * Process additional authenticated data. Returns 0 on success. Code is @@ -1579,7 +1314,8 @@ static int s390x_aes_gcm(S390X_AES_GCM_CTX *ctx, const unsigned char *in, /*- * Initialize context structure. Code is big-endian. */ -static void s390x_aes_gcm_setiv(S390X_AES_GCM_CTX *ctx) +static void s390x_aes_gcm_setiv(S390X_AES_GCM_CTX *ctx, + const unsigned char *iv) { ctx->kma.param.t.g[0] = 0; ctx->kma.param.t.g[1] = 0; @@ -1590,11 +1326,12 @@ static void s390x_aes_gcm_setiv(S390X_AES_GCM_CTX *ctx) ctx->kreslen = 0; if (ctx->ivlen == 12) { - memcpy(&ctx->kma.param.j0, ctx->iv, ctx->ivlen); + memcpy(&ctx->kma.param.j0, iv, ctx->ivlen); ctx->kma.param.j0.w[3] = 1; ctx->kma.param.cv.w = 1; } else { /* ctx->iv has the right size and is already padded. */ + memcpy(ctx->iv, iv, ctx->ivlen); s390x_kma(ctx->iv, S390X_gcm_ivpadlen(ctx->ivlen), NULL, 0, NULL, ctx->fc, &ctx->kma.param); ctx->fc |= S390X_KMA_HS; @@ -1617,17 +1354,16 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, c); S390X_AES_GCM_CTX *gctx_out; EVP_CIPHER_CTX *out; - unsigned char *buf, *iv; + unsigned char *buf; int ivlen, enc, len; switch (type) { case EVP_CTRL_INIT: - ivlen = EVP_CIPHER_iv_length(c->cipher); - iv = EVP_CIPHER_CTX_iv_noconst(c); + ivlen = EVP_CIPHER_get_iv_length(c->cipher); gctx->key_set = 0; gctx->iv_set = 0; gctx->ivlen = ivlen; - gctx->iv = iv; + gctx->iv = c->iv; gctx->taglen = -1; gctx->iv_gen = 0; gctx->tls_aad_len = -1; @@ -1642,16 +1378,15 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; if (arg != 12) { - iv = EVP_CIPHER_CTX_iv_noconst(c); len = S390X_gcm_ivpadlen(arg); /* Allocate memory for iv if needed. */ if (gctx->ivlen == 12 || len > S390X_gcm_ivpadlen(gctx->ivlen)) { - if (gctx->iv != iv) + if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); if ((gctx->iv = OPENSSL_malloc(len)) == NULL) { - EVPerr(EVP_F_S390X_AES_GCM_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } } @@ -1664,7 +1399,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_AEAD_SET_TAG: buf = EVP_CIPHER_CTX_buf_noconst(c); - enc = EVP_CIPHER_CTX_encrypting(c); + enc = EVP_CIPHER_CTX_is_encrypting(c); if (arg <= 0 || arg > 16 || enc) return 0; @@ -1673,7 +1408,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 1; case EVP_CTRL_AEAD_GET_TAG: - enc = EVP_CIPHER_CTX_encrypting(c); + enc = EVP_CIPHER_CTX_is_encrypting(c); if (arg <= 0 || arg > 16 || !enc || gctx->taglen < 0) return 0; @@ -1697,7 +1432,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (arg) memcpy(gctx->iv, ptr, arg); - enc = EVP_CIPHER_CTX_encrypting(c); + enc = EVP_CIPHER_CTX_is_encrypting(c); if (enc && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) return 0; @@ -1708,7 +1443,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (gctx->iv_gen == 0 || gctx->key_set == 0) return 0; - s390x_aes_gcm_setiv(gctx); + s390x_aes_gcm_setiv(gctx, gctx->iv); if (arg <= 0 || arg > gctx->ivlen) arg = gctx->ivlen; @@ -1723,12 +1458,12 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 1; case EVP_CTRL_GCM_SET_IV_INV: - enc = EVP_CIPHER_CTX_encrypting(c); + enc = EVP_CIPHER_CTX_is_encrypting(c); if (gctx->iv_gen == 0 || gctx->key_set == 0 || enc) return 0; memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); - s390x_aes_gcm_setiv(gctx); + s390x_aes_gcm_setiv(gctx, gctx->iv); gctx->iv_set = 1; return 1; @@ -1740,6 +1475,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) buf = EVP_CIPHER_CTX_buf_noconst(c); memcpy(buf, ptr, arg); gctx->tls_aad_len = arg; + gctx->tls_enc_records = 0; len = buf[arg - 2] << 8 | buf[arg - 1]; /* Correct length for explicit iv. */ @@ -1748,7 +1484,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too. */ - enc = EVP_CIPHER_CTX_encrypting(c); + enc = EVP_CIPHER_CTX_is_encrypting(c); if (!enc) { if (len < EVP_GCM_TLS_TAG_LEN) return 0; @@ -1762,15 +1498,14 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_COPY: out = ptr; gctx_out = EVP_C_DATA(S390X_AES_GCM_CTX, out); - iv = EVP_CIPHER_CTX_iv_noconst(c); - if (gctx->iv == iv) { - gctx_out->iv = EVP_CIPHER_CTX_iv_noconst(out); + if (gctx->iv == c->iv) { + gctx_out->iv = out->iv; } else { len = S390X_gcm_ivpadlen(gctx->ivlen); if ((gctx_out->iv = OPENSSL_malloc(len)) == NULL) { - EVPerr(EVP_F_S390X_AES_GCM_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -1784,36 +1519,43 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) } /*- - * Set key or iv or enc/dec. Returns 1 on success. Otherwise 0 is returned. + * Set key and/or iv. Returns 1 on success. Otherwise 0 is returned. */ static int s390x_aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, ctx); - const int keylen = EVP_CIPHER_CTX_key_length(ctx); + int keylen; - gctx->fc = S390X_AES_FC(keylen) | (enc ? 0 : S390X_DECRYPT); + if (iv == NULL && key == NULL) + return 1; if (key != NULL) { - gctx->fc &= ~S390X_KMA_HS; + keylen = EVP_CIPHER_CTX_get_key_length(ctx); memcpy(&gctx->kma.param.k, key, keylen); + + gctx->fc = S390X_AES_FC(keylen); + if (!enc) + gctx->fc |= S390X_DECRYPT; + + if (iv == NULL && gctx->iv_set) + iv = gctx->iv; + + if (iv != NULL) { + s390x_aes_gcm_setiv(gctx, iv); + gctx->iv_set = 1; + } gctx->key_set = 1; - } + } else { + if (gctx->key_set) + s390x_aes_gcm_setiv(gctx, iv); + else + memcpy(gctx->iv, iv, gctx->ivlen); - if (iv != NULL) { - memcpy(gctx->iv, iv, gctx->ivlen); - gctx->iv_gen = 0; gctx->iv_set = 1; + gctx->iv_gen = 0; } - - if (gctx->key_set && gctx->iv_set) - s390x_aes_gcm_setiv(gctx); - - gctx->fc &= ~(S390X_KMA_LPC | S390X_KMA_LAAD); - gctx->areslen = 0; - gctx->mreslen = 0; - gctx->kreslen = 0; return 1; } @@ -1826,12 +1568,23 @@ static int s390x_aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, ctx); const unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx); - const int enc = EVP_CIPHER_CTX_encrypting(ctx); + const int enc = EVP_CIPHER_CTX_is_encrypting(ctx); int rv = -1; if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) return -1; + /* + * Check for too many keys as per FIPS 140-2 IG A.5 "Key/IV Pair Uniqueness + * Requirements from SP 800-38D". The requirements is for one party to the + * communication to fail after 2^64 - 1 keys. We do this on the encrypting + * side only. + */ + if (ctx->encrypt && ++gctx->tls_enc_records == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_TOO_MANY_RECORDS); + goto err; + } + if (EVP_CIPHER_CTX_ctrl(ctx, enc ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) @@ -1902,8 +1655,9 @@ static int s390x_aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, /* recall that we already did en-/decrypt gctx->mres * and returned it to caller... */ OPENSSL_cleanse(tmp, gctx->mreslen); + gctx->iv_set = 0; - enc = EVP_CIPHER_CTX_encrypting(ctx); + enc = EVP_CIPHER_CTX_is_encrypting(ctx); if (enc) { gctx->taglen = 16; } else { @@ -1921,22 +1675,18 @@ static int s390x_aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int s390x_aes_gcm_cleanup(EVP_CIPHER_CTX *c) { S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, c); - const unsigned char *iv; if (gctx == NULL) return 0; - iv = EVP_CIPHER_CTX_iv(c); - if (iv != gctx->iv) + if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); OPENSSL_cleanse(gctx, sizeof(*gctx)); return 1; } -# define S390X_AES_XTS_CTX EVP_AES_XTS_CTX -# define S390X_aes_128_xts_CAPABLE 0 /* checked by callee */ -# define S390X_aes_256_xts_CAPABLE 0 +# define S390X_AES_XTS_CTX EVP_AES_XTS_CTX # define s390x_aes_xts_init_key aes_xts_init_key static int s390x_aes_xts_init_key(EVP_CIPHER_CTX *ctx, @@ -1949,18 +1699,6 @@ static int s390x_aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int s390x_aes_xts_ctrl(EVP_CIPHER_CTX *, int type, int arg, void *ptr); # define s390x_aes_xts_cleanup aes_xts_cleanup -# define S390X_aes_128_ccm_CAPABLE (S390X_aes_128_CAPABLE && \ - (OPENSSL_s390xcap_P.kmac[0] & \ - S390X_CAPBIT(S390X_AES_128))) -# define S390X_aes_192_ccm_CAPABLE (S390X_aes_192_CAPABLE && \ - (OPENSSL_s390xcap_P.kmac[0] & \ - S390X_CAPBIT(S390X_AES_192))) -# define S390X_aes_256_ccm_CAPABLE (S390X_aes_256_CAPABLE && \ - (OPENSSL_s390xcap_P.kmac[0] & \ - S390X_CAPBIT(S390X_AES_256))) - -# define S390X_CCM_AAD_FLAG 0x40 - /*- * Set nonce and length fields. Code is big-endian. */ @@ -2073,13 +1811,13 @@ static int s390x_aes_ccm(S390X_AES_CCM_CTX *ctx, const unsigned char *in, ctx->aes.ccm.nonce.b[15] = 1; if (n != len) - return -1; /* length mismatch */ + return -1; /* length mismatch */ if (enc) { /* Two operations per block plus one for tag encryption */ ctx->aes.ccm.blocks += (((len + 15) >> 4) << 1) + 1; if (ctx->aes.ccm.blocks > (1ULL << 61)) - return -2; /* too much data */ + return -2; /* too much data */ } num = 0; @@ -2128,7 +1866,7 @@ static int s390x_aes_ccm(S390X_AES_CCM_CTX *ctx, const unsigned char *in, ctx->aes.ccm.kmac_param.icv.g[0] ^= ctx->aes.ccm.buf.g[0]; ctx->aes.ccm.kmac_param.icv.g[1] ^= ctx->aes.ccm.buf.g[1]; - ctx->aes.ccm.nonce.b[0] = flags; /* restore flags field */ + ctx->aes.ccm.nonce.b[0] = flags; /* restore flags field */ return 0; } @@ -2140,10 +1878,9 @@ static int s390x_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx); - const unsigned char *ivec = EVP_CIPHER_CTX_iv(ctx); + unsigned char *ivec = ctx->iv; unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx); - const int enc = EVP_CIPHER_CTX_encrypting(ctx); - unsigned char iv[EVP_MAX_IV_LENGTH]; + const int enc = EVP_CIPHER_CTX_is_encrypting(ctx); if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->aes.ccm.m)) @@ -2159,9 +1896,8 @@ static int s390x_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * Get explicit iv (sequence number). We already have fixed iv * (server/client_write_iv) here. */ - memcpy(iv, ivec, sizeof(iv)); - memcpy(iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); - s390x_aes_ccm_setiv(cctx, iv, len); + memcpy(ivec + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); + s390x_aes_ccm_setiv(cctx, ivec, len); /* Process aad (sequence number|type|version|length) */ s390x_aes_ccm_aad(cctx, buf, cctx->aes.ccm.tls_aad_len); @@ -2188,35 +1924,40 @@ static int s390x_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } /*- - * Set key or iv or enc/dec. Returns 1 if successful. - * Otherwise 0 is returned. + * Set key and flag field and/or iv. Returns 1 if successful. Otherwise 0 is + * returned. */ static int s390x_aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx); - const int keylen = EVP_CIPHER_CTX_key_length(ctx); - unsigned char *ivec = EVP_CIPHER_CTX_iv_noconst(ctx); + int keylen; - cctx->aes.ccm.fc = S390X_AES_FC(keylen); + if (iv == NULL && key == NULL) + return 1; if (key != NULL) { + keylen = EVP_CIPHER_CTX_get_key_length(ctx); + cctx->aes.ccm.fc = S390X_AES_FC(keylen); memcpy(cctx->aes.ccm.kmac_param.k, key, keylen); + + /* Store encoded m and l. */ + cctx->aes.ccm.nonce.b[0] = ((cctx->aes.ccm.l - 1) & 0x7) + | (((cctx->aes.ccm.m - 2) >> 1) & 0x7) << 3; + memset(cctx->aes.ccm.nonce.b + 1, 0, + sizeof(cctx->aes.ccm.nonce.b)); + cctx->aes.ccm.blocks = 0; + cctx->aes.ccm.key_set = 1; } + if (iv != NULL) { - memcpy(ivec, iv, 15 - cctx->aes.ccm.l); + memcpy(ctx->iv, iv, 15 - cctx->aes.ccm.l); + cctx->aes.ccm.iv_set = 1; } - /* Store encoded m and l. */ - cctx->aes.ccm.nonce.b[0] = ((cctx->aes.ccm.l - 1) & 0x7) - | (((cctx->aes.ccm.m - 2) >> 1) & 0x7) << 3; - memset(cctx->aes.ccm.nonce.b + 1, 0, sizeof(cctx->aes.ccm.nonce.b) - 1); - - cctx->aes.ccm.blocks = 0; - cctx->aes.ccm.len_set = 0; return 1; } @@ -2230,10 +1971,9 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx); - const int enc = EVP_CIPHER_CTX_encrypting(ctx); - const unsigned char *ivec = EVP_CIPHER_CTX_iv(ctx); - unsigned char *buf; + const int enc = EVP_CIPHER_CTX_is_encrypting(ctx); int rv; + unsigned char *buf; if (!cctx->aes.ccm.key_set) return -1; @@ -2255,7 +1995,7 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (out == NULL) { /* Update(): Pass message length. */ if (in == NULL) { - s390x_aes_ccm_setiv(cctx, ivec, len); + s390x_aes_ccm_setiv(cctx, ctx->iv, len); cctx->aes.ccm.len_set = 1; return len; @@ -2280,7 +2020,7 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * In case message length was not previously set explicitly via * Update(), set it now. */ - s390x_aes_ccm_setiv(cctx, ivec, len); + s390x_aes_ccm_setiv(cctx, ctx->iv, len); cctx->aes.ccm.len_set = 1; } @@ -2304,6 +2044,9 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (rv == -1) OPENSSL_cleanse(out, len); + cctx->aes.ccm.iv_set = 0; + cctx->aes.ccm.tag_set = 0; + cctx->aes.ccm.len_set = 0; return rv; } } @@ -2316,7 +2059,7 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, c); - unsigned char *buf, *iv; + unsigned char *buf; int enc, len; switch (type) { @@ -2350,7 +2093,7 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) /* Correct length for explicit iv. */ len -= EVP_CCM_TLS_EXPLICIT_IV_LEN; - enc = EVP_CIPHER_CTX_encrypting(c); + enc = EVP_CIPHER_CTX_is_encrypting(c); if (!enc) { if (len < cctx->aes.ccm.m) return 0; @@ -2370,8 +2113,7 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; /* Copy to first part of the iv. */ - iv = EVP_CIPHER_CTX_iv_noconst(c); - memcpy(iv, ptr, arg); + memcpy(c->iv, ptr, arg); return 1; case EVP_CTRL_AEAD_SET_IVLEN: @@ -2389,7 +2131,7 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if ((arg & 1) || arg < 4 || arg > 16) return 0; - enc = EVP_CIPHER_CTX_encrypting(c); + enc = EVP_CIPHER_CTX_is_encrypting(c); if (enc && ptr) return 0; @@ -2403,7 +2145,7 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 1; case EVP_CTRL_AEAD_GET_TAG: - enc = EVP_CIPHER_CTX_encrypting(c); + enc = EVP_CIPHER_CTX_is_encrypting(c); if (!enc || !cctx->aes.ccm.tag_set) return 0; @@ -2411,6 +2153,9 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; memcpy(ptr, cctx->aes.ccm.kmac_param.icv.b, cctx->aes.ccm.m); + cctx->aes.ccm.tag_set = 0; + cctx->aes.ccm.iv_set = 0; + cctx->aes.ccm.len_set = 0; return 1; case EVP_CTRL_COPY: @@ -2424,10 +2169,7 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) # define s390x_aes_ccm_cleanup aes_ccm_cleanup # ifndef OPENSSL_NO_OCB -# define S390X_AES_OCB_CTX EVP_AES_OCB_CTX -# define S390X_aes_128_ocb_CAPABLE 0 -# define S390X_aes_192_ocb_CAPABLE 0 -# define S390X_aes_256_ocb_CAPABLE 0 +# define S390X_AES_OCB_CTX EVP_AES_OCB_CTX # define s390x_aes_ocb_init_key aes_ocb_init_key static int s390x_aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, @@ -2441,77 +2183,90 @@ static int s390x_aes_ocb_cleanup(EVP_CIPHER_CTX *); static int s390x_aes_ocb_ctrl(EVP_CIPHER_CTX *, int type, int arg, void *ptr); # endif -# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode, \ - MODE,flags) \ -static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \ - nid##_##keylen##_##nmode,blocksize, \ - keylen / 8, \ - ivlen, \ - flags | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_##MODE##_MODE, \ - s390x_aes_##mode##_init_key, \ - s390x_aes_##mode##_cipher, \ - NULL, \ - sizeof(S390X_AES_##MODE##_CTX), \ - NULL, \ - NULL, \ - NULL, \ - NULL \ -}; \ -static const EVP_CIPHER aes_##keylen##_##mode = { \ - nid##_##keylen##_##nmode, \ - blocksize, \ - keylen / 8, \ - ivlen, \ - flags | EVP_CIPH_##MODE##_MODE, \ - aes_init_key, \ - aes_##mode##_cipher, \ - NULL, \ - sizeof(EVP_AES_KEY), \ - NULL, \ - NULL, \ - NULL, \ - NULL \ -}; \ -const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ -{ \ - return S390X_aes_##keylen##_##mode##_CAPABLE ? \ - &s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \ +# ifndef OPENSSL_NO_SIV +# define S390X_AES_SIV_CTX EVP_AES_SIV_CTX + +# define s390x_aes_siv_init_key aes_siv_init_key +# define s390x_aes_siv_cipher aes_siv_cipher +# define s390x_aes_siv_cleanup aes_siv_cleanup +# define s390x_aes_siv_ctrl aes_siv_ctrl +# endif + +# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode, \ + MODE,flags) \ +static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize, \ + keylen / 8, \ + ivlen, \ + flags | EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ + s390x_aes_##mode##_init_key, \ + s390x_aes_##mode##_cipher, \ + NULL, \ + sizeof(S390X_AES_##MODE##_CTX), \ + NULL, \ + NULL, \ + NULL, \ + NULL \ +}; \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##nmode, \ + blocksize, \ + keylen / 8, \ + ivlen, \ + flags | EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ + aes_init_key, \ + aes_##mode##_cipher, \ + NULL, \ + sizeof(EVP_AES_KEY), \ + NULL, \ + NULL, \ + NULL, \ + NULL \ +}; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ \ + return S390X_aes_##keylen##_##mode##_CAPABLE ? \ + &s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \ } # define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags)\ -static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \ - nid##_##keylen##_##mode, \ - blocksize, \ - (EVP_CIPH_##MODE##_MODE == EVP_CIPH_XTS_MODE ? 2 : 1) * keylen / 8, \ - ivlen, \ - flags | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_##MODE##_MODE, \ - s390x_aes_##mode##_init_key, \ - s390x_aes_##mode##_cipher, \ - s390x_aes_##mode##_cleanup, \ - sizeof(S390X_AES_##MODE##_CTX), \ - NULL, \ - NULL, \ - s390x_aes_##mode##_ctrl, \ - NULL \ -}; \ -static const EVP_CIPHER aes_##keylen##_##mode = { \ - nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE == EVP_CIPH_XTS_MODE ? 2 : 1) * keylen / 8, \ - ivlen, \ - flags | EVP_CIPH_##MODE##_MODE, \ - aes_##mode##_init_key, \ - aes_##mode##_cipher, \ - aes_##mode##_cleanup, \ - sizeof(EVP_AES_##MODE##_CTX), \ - NULL, \ - NULL, \ - aes_##mode##_ctrl, \ - NULL \ -}; \ -const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ -{ \ - return S390X_aes_##keylen##_##mode##_CAPABLE ? \ - &s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \ +static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \ + nid##_##keylen##_##mode, \ + blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE ? 2 : 1) * keylen / 8, \ + ivlen, \ + flags | EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ + s390x_aes_##mode##_init_key, \ + s390x_aes_##mode##_cipher, \ + s390x_aes_##mode##_cleanup, \ + sizeof(S390X_AES_##MODE##_CTX), \ + NULL, \ + NULL, \ + s390x_aes_##mode##_ctrl, \ + NULL \ +}; \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##mode,blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE ? 2 : 1) * keylen / 8, \ + ivlen, \ + flags | EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ + aes_##mode##_init_key, \ + aes_##mode##_cipher, \ + aes_##mode##_cleanup, \ + sizeof(EVP_AES_##MODE##_CTX), \ + NULL, \ + NULL, \ + aes_##mode##_ctrl, \ + NULL \ +}; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ \ + return S390X_aes_##keylen##_##mode##_CAPABLE ? \ + &s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \ } #else @@ -2520,6 +2275,7 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ static const EVP_CIPHER aes_##keylen##_##mode = { \ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aes_init_key, \ aes_##mode##_cipher, \ NULL, \ @@ -2531,8 +2287,10 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ # define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ static const EVP_CIPHER aes_##keylen##_##mode = { \ nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \ + ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aes_##mode##_init_key, \ aes_##mode##_cipher, \ aes_##mode##_cleanup, \ @@ -2543,48 +2301,6 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ #endif -#if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__)) -# include "arm_arch.h" -# if __ARM_MAX_ARCH__>=7 -# if defined(BSAES_ASM) -# define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON) -# endif -# if defined(VPAES_ASM) -# define VPAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON) -# endif -# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES) -# define HWAES_set_encrypt_key aes_v8_set_encrypt_key -# define HWAES_set_decrypt_key aes_v8_set_decrypt_key -# define HWAES_encrypt aes_v8_encrypt -# define HWAES_decrypt aes_v8_decrypt -# define HWAES_cbc_encrypt aes_v8_cbc_encrypt -# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks -# endif -#endif - -#if defined(HWAES_CAPABLE) -int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key); -int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key); -void HWAES_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void HWAES_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, const int enc); -void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - const unsigned char ivec[16]); -void HWAES_xts_encrypt(const unsigned char *inp, unsigned char *out, - size_t len, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char iv[16]); -void HWAES_xts_decrypt(const unsigned char *inp, unsigned char *out, - size_t len, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char iv[16]); -#endif - #define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ @@ -2600,13 +2316,13 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, int ret, mode; EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx); - mode = EVP_CIPHER_CTX_mode(ctx); + mode = EVP_CIPHER_CTX_get_mode(ctx); if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { #ifdef HWAES_CAPABLE if (HWAES_CAPABLE) { ret = HWAES_set_decrypt_key(key, - EVP_CIPHER_CTX_key_length(ctx) * 8, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &dat->ks.ks); dat->block = (block128_f) HWAES_decrypt; dat->stream.cbc = NULL; @@ -2618,16 +2334,17 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, #endif #ifdef BSAES_CAPABLE if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) { - ret = AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + ret = AES_set_decrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &dat->ks.ks); dat->block = (block128_f) AES_decrypt; - dat->stream.cbc = (cbc128_f) bsaes_cbc_encrypt; + dat->stream.cbc = (cbc128_f) ossl_bsaes_cbc_encrypt; } else #endif #ifdef VPAES_CAPABLE if (VPAES_CAPABLE) { ret = vpaes_set_decrypt_key(key, - EVP_CIPHER_CTX_key_length(ctx) * 8, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &dat->ks.ks); dat->block = (block128_f) vpaes_decrypt; dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? @@ -2636,7 +2353,7 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, #endif { ret = AES_set_decrypt_key(key, - EVP_CIPHER_CTX_key_length(ctx) * 8, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &dat->ks.ks); dat->block = (block128_f) AES_decrypt; dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? @@ -2645,7 +2362,8 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } else #ifdef HWAES_CAPABLE if (HWAES_CAPABLE) { - ret = HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + ret = HWAES_set_encrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &dat->ks.ks); dat->block = (block128_f) HWAES_encrypt; dat->stream.cbc = NULL; @@ -2664,15 +2382,16 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, #endif #ifdef BSAES_CAPABLE if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) { - ret = AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + ret = AES_set_encrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &dat->ks.ks); dat->block = (block128_f) AES_encrypt; - dat->stream.ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks; + dat->stream.ctr = (ctr128_f) ossl_bsaes_ctr32_encrypt_blocks; } else #endif #ifdef VPAES_CAPABLE if (VPAES_CAPABLE) { - ret = vpaes_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + ret = vpaes_set_encrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &dat->ks.ks); dat->block = (block128_f) vpaes_encrypt; dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? @@ -2680,7 +2399,7 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } else #endif { - ret = AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + ret = AES_set_encrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &dat->ks.ks); dat->block = (block128_f) AES_encrypt; dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? @@ -2692,7 +2411,7 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } if (ret < 0) { - EVPerr(EVP_F_AES_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_EVP, EVP_R_AES_KEY_SETUP_FAILED); return 0; } @@ -2705,15 +2424,14 @@ static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx); if (dat->stream.cbc) - (*dat->stream.cbc) (in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); - else if (EVP_CIPHER_CTX_encrypting(ctx)) - CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), dat->block); + (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); + else if (EVP_CIPHER_CTX_is_encrypting(ctx)) + CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, + dat->block); else CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), dat->block); + ctx->iv, dat->block); return 1; } @@ -2721,7 +2439,7 @@ static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - size_t bl = EVP_CIPHER_CTX_block_size(ctx); + size_t bl = EVP_CIPHER_CTX_get_block_size(ctx); size_t i; EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx); @@ -2739,9 +2457,9 @@ static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx); - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, dat->block); + ctx->iv, &num, dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -2751,10 +2469,10 @@ static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx); - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, - EVP_CIPHER_CTX_encrypting(ctx), dat->block); + ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -2764,10 +2482,10 @@ static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx); - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, - EVP_CIPHER_CTX_encrypting(ctx), dat->block); + ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -2778,29 +2496,29 @@ static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx); if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, - EVP_CIPHER_CTX_encrypting(ctx), dat->block); + ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } while (len >= MAXBITCHUNK) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, - EVP_CIPHER_CTX_encrypting(ctx), dat->block); + ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); len -= MAXBITCHUNK; out += MAXBITCHUNK; in += MAXBITCHUNK; } if (len) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, - EVP_CIPHER_CTX_encrypting(ctx), dat->block); + ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); } @@ -2810,17 +2528,22 @@ static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - unsigned int num = EVP_CIPHER_CTX_num(ctx); + int n = EVP_CIPHER_CTX_get_num(ctx); + unsigned int num; EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx); + if (n < 0) + return 0; + num = (unsigned int)n; + if (dat->stream.ctr) CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + ctx->iv, EVP_CIPHER_CTX_buf_noconst(ctx), &num, dat->stream.ctr); else CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + ctx->iv, EVP_CIPHER_CTX_buf_noconst(ctx), &num, dat->block); EVP_CIPHER_CTX_set_num(ctx, num); @@ -2837,7 +2560,7 @@ static int aes_gcm_cleanup(EVP_CIPHER_CTX *c) if (gctx == NULL) return 0; OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); - if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c)) + if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); return 1; } @@ -2849,7 +2572,7 @@ 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 = EVP_CIPHER_iv_length(c->cipher); + gctx->ivlen = EVP_CIPHER_get_iv_length(c->cipher); gctx->iv = c->iv; gctx->taglen = -1; gctx->iv_gen = 0; @@ -2868,7 +2591,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); if ((gctx->iv = OPENSSL_malloc(arg)) == NULL) { - EVPerr(EVP_F_AES_GCM_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } } @@ -2889,14 +2612,6 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) memcpy(ptr, c->buf, arg); return 1; - case EVP_CTRL_GET_IV: - if (gctx->iv_gen != 1) - return 0; - if (gctx->ivlen != arg) - return 0; - memcpy(ptr, gctx->iv, arg); - return 1; - case EVP_CTRL_GCM_SET_IV_FIXED: /* Special case: -1 length restores whole IV */ if (arg == -1) { @@ -2946,6 +2661,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; memcpy(c->buf, ptr, arg); gctx->tls_aad_len = arg; + gctx->tls_enc_records = 0; { unsigned int len = c->buf[arg - 2] << 8 | c->buf[arg - 1]; /* Correct length for explicit IV */ @@ -2977,7 +2693,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) gctx_out->iv = out->iv; else { if ((gctx_out->iv = OPENSSL_malloc(gctx->ivlen)) == NULL) { - EVPerr(EVP_F_AES_GCM_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); @@ -3017,7 +2733,7 @@ static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks); CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) AES_encrypt); - gctx->ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks; + gctx->ctr = (ctr128_f) ossl_bsaes_ctr32_encrypt_blocks; break; } else #endif @@ -3080,6 +2796,18 @@ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) return -1; + + /* + * Check for too many keys as per FIPS 140-2 IG A.5 "Key/IV Pair Uniqueness + * Requirements from SP 800-38D". The requirements is for one party to the + * communication to fail after 2^64 - 1 keys. We do this on the encrypting + * side only. + */ + if (ctx->encrypt && ++gctx->tls_enc_records == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_TOO_MANY_RECORDS); + goto err; + } + /* * Set IV from start of buffer or generate IV and write to start of * buffer. @@ -3189,10 +2917,35 @@ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return rv; } +#ifdef FIPS_MODULE +/* + * See SP800-38D (GCM) Section 8 "Uniqueness requirement on IVS and keys" + * + * See also 8.2.2 RBG-based construction. + * Random construction consists of a free field (which can be NULL) and a + * random field which will use a DRBG that can return at least 96 bits of + * entropy strength. (The DRBG must be seeded by the FIPS module). + */ +static int aes_gcm_iv_generate(EVP_AES_GCM_CTX *gctx, int offset) +{ + int sz = gctx->ivlen - offset; + + /* Must be at least 96 bits */ + if (sz <= 0 || gctx->ivlen < 12) + return 0; + + /* Use DRBG to generate random iv */ + if (RAND_bytes(gctx->iv + offset, sz) <= 0) + return 0; + return 1; +} +#endif /* FIPS_MODULE */ + static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,ctx); + /* If not set up, return error */ if (!gctx->key_set) return -1; @@ -3200,8 +2953,25 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (gctx->tls_aad_len >= 0) return aes_gcm_tls_cipher(ctx, out, in, len); +#ifdef FIPS_MODULE + /* + * FIPS requires generation of AES-GCM IV's inside the FIPS module. + * The IV can still be set externally (the security policy will state that + * this is not FIPS compliant). There are some applications + * where setting the IV externally is the only option available. + */ + if (!gctx->iv_set) { + if (!ctx->encrypt || !aes_gcm_iv_generate(gctx, 0)) + return -1; + CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); + gctx->iv_set = 1; + gctx->iv_gen_rand = 1; + } +#else if (!gctx->iv_set) return -1; +#endif /* FIPS_MODULE */ + if (in) { if (out == NULL) { if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) @@ -3361,10 +3131,11 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (!iv && !key) return 1; - if (key) + if (key) { do { /* The key is two half length keys in reality */ - const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2; + const int bytes = EVP_CIPHER_CTX_get_key_length(ctx) / 2; + const int bits = bytes * 8; /* * Verify that the two keys are different. @@ -3382,8 +3153,9 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, * 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); + if ((!allow_insecure_decrypt || enc) + && CRYPTO_memcmp(key, key + bytes, bytes) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_XTS_DUPLICATED_KEYS); return 0; } @@ -3396,26 +3168,20 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, #ifdef HWAES_CAPABLE if (HWAES_CAPABLE) { if (enc) { - HWAES_set_encrypt_key(key, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + HWAES_set_encrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) HWAES_encrypt; # ifdef HWAES_xts_encrypt xctx->stream = HWAES_xts_encrypt; # endif } else { - HWAES_set_decrypt_key(key, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + HWAES_set_decrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) HWAES_decrypt; # ifdef HWAES_xts_decrypt xctx->stream = HWAES_xts_decrypt; #endif } - HWAES_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks2.ks); + HWAES_set_encrypt_key(key + bytes, bits, &xctx->ks2.ks); xctx->xts.block2 = (block128_f) HWAES_encrypt; xctx->xts.key1 = &xctx->ks1; @@ -3424,26 +3190,20 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, #endif #ifdef BSAES_CAPABLE if (BSAES_CAPABLE) - xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt; + xctx->stream = enc ? ossl_bsaes_xts_encrypt : ossl_bsaes_xts_decrypt; else #endif #ifdef VPAES_CAPABLE if (VPAES_CAPABLE) { if (enc) { - vpaes_set_encrypt_key(key, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + vpaes_set_encrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) vpaes_encrypt; } else { - vpaes_set_decrypt_key(key, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + vpaes_set_decrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) vpaes_decrypt; } - vpaes_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks2.ks); + vpaes_set_encrypt_key(key + bytes, bits, &xctx->ks2.ks); xctx->xts.block2 = (block128_f) vpaes_encrypt; xctx->xts.key1 = &xctx->ks1; @@ -3453,26 +3213,23 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, (void)0; /* terminate potentially open 'else' */ if (enc) { - AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + AES_set_encrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) AES_encrypt; } else { - AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + AES_set_decrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) AES_decrypt; } - AES_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks2.ks); + AES_set_encrypt_key(key + bytes, bits, &xctx->ks2.ks); xctx->xts.block2 = (block128_f) AES_encrypt; xctx->xts.key1 = &xctx->ks1; } while (0); + } if (iv) { xctx->xts.key2 = &xctx->ks2; - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16); + memcpy(ctx->iv, iv, 16); } return 1; @@ -3482,17 +3239,31 @@ static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx); - if (!xctx->xts.key1 || !xctx->xts.key2) + + if (xctx->xts.key1 == NULL + || xctx->xts.key2 == NULL + || out == NULL + || in == NULL + || len < AES_BLOCK_SIZE) return 0; - if (!out || !in || len < AES_BLOCK_SIZE) + + /* + * Impose a limit of 2^20 blocks per data unit as specified by + * IEEE Std 1619-2018. The earlier and obsolete IEEE Std 1619-2007 + * indicated that this was a SHOULD NOT rather than a MUST NOT. + * NIST SP 800-38E mandates the same limit. + */ + if (len > XTS_MAX_BLOCKS_PER_DATA_UNIT * AES_BLOCK_SIZE) { + ERR_raise(ERR_LIB_EVP, EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE); return 0; + } + if (xctx->stream) (*xctx->stream) (in, out, len, xctx->xts.key1, xctx->xts.key2, - EVP_CIPHER_CTX_iv_noconst(ctx)); - else if (CRYPTO_xts128_encrypt(&xctx->xts, EVP_CIPHER_CTX_iv_noconst(ctx), - in, out, len, - EVP_CIPHER_CTX_encrypting(ctx))) + ctx->iv); + else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, + EVP_CIPHER_CTX_is_encrypting(ctx))) return 0; return 1; } @@ -3519,9 +3290,11 @@ 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) @@ -3537,7 +3310,7 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; len -= EVP_CCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ - if (!EVP_CIPHER_CTX_encrypting(c)) { + if (!EVP_CIPHER_CTX_is_encrypting(c)) { if (len < cctx->M) return 0; len -= cctx->M; @@ -3553,7 +3326,7 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (arg != EVP_CCM_TLS_FIXED_IV_LEN) return 0; /* Just copy to first part of IV */ - memcpy(EVP_CIPHER_CTX_iv_noconst(c), ptr, arg); + memcpy(c->iv, ptr, arg); return 1; case EVP_CTRL_AEAD_SET_IVLEN: @@ -3568,7 +3341,7 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_AEAD_SET_TAG: if ((arg & 1) || arg < 4 || arg > 16) return 0; - if (EVP_CIPHER_CTX_encrypting(c) && ptr) + if (EVP_CIPHER_CTX_is_encrypting(c) && ptr) return 0; if (ptr) { cctx->tag_set = 1; @@ -3578,7 +3351,7 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 1; case EVP_CTRL_AEAD_GET_TAG: - if (!EVP_CIPHER_CTX_encrypting(c) || !cctx->tag_set) + if (!EVP_CIPHER_CTX_is_encrypting(c) || !cctx->tag_set) return 0; if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg)) return 0; @@ -3615,7 +3388,8 @@ static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, do { #ifdef HWAES_CAPABLE if (HWAES_CAPABLE) { - HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + HWAES_set_encrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &cctx->ks.ks); CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, @@ -3627,7 +3401,8 @@ static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, #endif #ifdef VPAES_CAPABLE if (VPAES_CAPABLE) { - vpaes_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + vpaes_set_encrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &cctx->ks.ks); CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, &cctx->ks, (block128_f) vpaes_encrypt); @@ -3636,7 +3411,7 @@ static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, break; } #endif - AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + AES_set_encrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &cctx->ks.ks); CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, &cctx->ks, (block128_f) AES_encrypt); @@ -3644,7 +3419,7 @@ static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, cctx->key_set = 1; } while (0); if (iv) { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L); + memcpy(ctx->iv, iv, 15 - cctx->L); cctx->iv_set = 1; } return 1; @@ -3659,23 +3434,24 @@ static int aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M)) return -1; /* If encrypting set explicit IV from sequence number (start of AAD) */ - if (EVP_CIPHER_CTX_encrypting(ctx)) + if (EVP_CIPHER_CTX_is_encrypting(ctx)) memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx), EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Get rest of IV from explicit IV */ - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx) + EVP_CCM_TLS_FIXED_IV_LEN, in, + memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Correct length value */ len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), 15 - cctx->L, + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; /* Use saved AAD */ - CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx), cctx->tls_aad_len); + CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx), + cctx->tls_aad_len); /* Fix buffer to point to payload */ in += EVP_CCM_TLS_EXPLICIT_IV_LEN; out += EVP_CCM_TLS_EXPLICIT_IV_LEN; - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str) : CRYPTO_ccm128_encrypt(ccm, in, out, len)) @@ -3719,7 +3495,7 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (!out) { if (!in) { - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; cctx->len_set = 1; @@ -3733,17 +3509,16 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } /* The tag must be set before actually decrypting data */ - if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set) + if (!EVP_CIPHER_CTX_is_encrypting(ctx) && !cctx->tag_set) return -1; /* If not set length yet do it */ if (!cctx->len_set) { - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), - 15 - cctx->L, len)) + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; cctx->len_set = 1; } - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str) : CRYPTO_ccm128_encrypt(ccm, in, out, len)) @@ -3775,14 +3550,14 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM, EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) - BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM, - EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) - BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM, - EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) +BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM, + EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) +BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM, + EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) typedef struct { union { - double align; + OSSL_UNION_ALIGN; AES_KEY ks; } ks; /* Indicates if IV has been set */ @@ -3792,22 +3567,26 @@ typedef struct { static int aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { + int len; EVP_AES_WRAP_CTX *wctx = EVP_C_DATA(EVP_AES_WRAP_CTX,ctx); - if (!iv && !key) + + if (iv == NULL && key == NULL) return 1; - if (key) { - if (EVP_CIPHER_CTX_encrypting(ctx)) - AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + if (key != NULL) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) + AES_set_encrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &wctx->ks.ks); else - AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + AES_set_decrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &wctx->ks.ks); - if (!iv) + if (iv == NULL) wctx->iv = NULL; } - if (iv) { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, EVP_CIPHER_CTX_iv_length(ctx)); - wctx->iv = EVP_CIPHER_CTX_iv_noconst(ctx); + if (iv != NULL) { + if ((len = EVP_CIPHER_CTX_get_iv_length(ctx)) < 0) + return 0; + memcpy(ctx->iv, iv, len); + wctx->iv = ctx->iv; } return 1; } @@ -3818,7 +3597,7 @@ static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_AES_WRAP_CTX *wctx = EVP_C_DATA(EVP_AES_WRAP_CTX,ctx); size_t rv; /* AES wrap with padding has IV length of 4, without padding 8 */ - int pad = EVP_CIPHER_CTX_iv_length(ctx) == 4; + int pad = EVP_CIPHER_CTX_get_iv_length(ctx) == 4; /* No final operation so always return zero length */ if (!in) return 0; @@ -3826,17 +3605,17 @@ static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (!inlen) return -1; /* If decrypting need at least 16 bytes and multiple of 8 */ - if (!EVP_CIPHER_CTX_encrypting(ctx) && (inlen < 16 || inlen & 0x7)) + if (!EVP_CIPHER_CTX_is_encrypting(ctx) && (inlen < 16 || inlen & 0x7)) return -1; /* If not padding input must be multiple of 8 */ if (!pad && inlen & 0x7) return -1; - if (is_partially_overlapping(out, in, inlen)) { - EVPerr(EVP_F_AES_WRAP_CIPHER, EVP_R_PARTIALLY_OVERLAPPING); + if (ossl_is_partially_overlapping(out, in, inlen)) { + ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING); return 0; } if (!out) { - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { /* If padding round up to multiple of 8 */ if (pad) inlen = (inlen + 7) / 8 * 8; @@ -3852,7 +3631,7 @@ static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } } if (pad) { - if (EVP_CIPHER_CTX_encrypting(ctx)) + if (EVP_CIPHER_CTX_is_encrypting(ctx)) rv = CRYPTO_128_wrap_pad(&wctx->ks.ks, wctx->iv, out, in, inlen, (block128_f) AES_encrypt); @@ -3861,7 +3640,7 @@ static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, out, in, inlen, (block128_f) AES_decrypt); } else { - if (EVP_CIPHER_CTX_encrypting(ctx)) + if (EVP_CIPHER_CTX_is_encrypting(ctx)) rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv, out, in, inlen, (block128_f) AES_encrypt); else @@ -3877,7 +3656,7 @@ static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static const EVP_CIPHER aes_128_wrap = { NID_id_aes128_wrap, - 8, 16, 8, WRAP_FLAGS, + 8, 16, 8, WRAP_FLAGS, EVP_ORIG_GLOBAL, aes_wrap_init_key, aes_wrap_cipher, NULL, sizeof(EVP_AES_WRAP_CTX), @@ -3891,7 +3670,7 @@ const EVP_CIPHER *EVP_aes_128_wrap(void) static const EVP_CIPHER aes_192_wrap = { NID_id_aes192_wrap, - 8, 24, 8, WRAP_FLAGS, + 8, 24, 8, WRAP_FLAGS, EVP_ORIG_GLOBAL, aes_wrap_init_key, aes_wrap_cipher, NULL, sizeof(EVP_AES_WRAP_CTX), @@ -3905,7 +3684,7 @@ const EVP_CIPHER *EVP_aes_192_wrap(void) static const EVP_CIPHER aes_256_wrap = { NID_id_aes256_wrap, - 8, 32, 8, WRAP_FLAGS, + 8, 32, 8, WRAP_FLAGS, EVP_ORIG_GLOBAL, aes_wrap_init_key, aes_wrap_cipher, NULL, sizeof(EVP_AES_WRAP_CTX), @@ -3919,7 +3698,7 @@ const EVP_CIPHER *EVP_aes_256_wrap(void) static const EVP_CIPHER aes_128_wrap_pad = { NID_id_aes128_wrap_pad, - 8, 16, 4, WRAP_FLAGS, + 8, 16, 4, WRAP_FLAGS, EVP_ORIG_GLOBAL, aes_wrap_init_key, aes_wrap_cipher, NULL, sizeof(EVP_AES_WRAP_CTX), @@ -3933,7 +3712,7 @@ const EVP_CIPHER *EVP_aes_128_wrap_pad(void) static const EVP_CIPHER aes_192_wrap_pad = { NID_id_aes192_wrap_pad, - 8, 24, 4, WRAP_FLAGS, + 8, 24, 4, WRAP_FLAGS, EVP_ORIG_GLOBAL, aes_wrap_init_key, aes_wrap_cipher, NULL, sizeof(EVP_AES_WRAP_CTX), @@ -3947,7 +3726,7 @@ const EVP_CIPHER *EVP_aes_192_wrap_pad(void) static const EVP_CIPHER aes_256_wrap_pad = { NID_id_aes256_wrap_pad, - 8, 32, 4, WRAP_FLAGS, + 8, 32, 4, WRAP_FLAGS, EVP_ORIG_GLOBAL, aes_wrap_init_key, aes_wrap_cipher, NULL, sizeof(EVP_AES_WRAP_CTX), @@ -3970,8 +3749,8 @@ 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_iv_length(c->cipher); - octx->iv = EVP_CIPHER_CTX_iv_noconst(c); + octx->ivlen = EVP_CIPHER_get_iv_length(c->cipher); + octx->iv = c->iv; octx->taglen = 16; octx->data_buf_len = 0; octx->aad_buf_len = 0; @@ -3990,7 +3769,7 @@ static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 1; case EVP_CTRL_AEAD_SET_TAG: - if (!ptr) { + if (ptr == NULL) { /* Tag len must be 0 to 16 */ if (arg < 0 || arg > 16) return 0; @@ -3998,13 +3777,13 @@ static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) octx->taglen = arg; return 1; } - if (arg != octx->taglen || EVP_CIPHER_CTX_encrypting(c)) + if (arg != octx->taglen || EVP_CIPHER_CTX_is_encrypting(c)) return 0; memcpy(octx->tag, ptr, arg); return 1; case EVP_CTRL_AEAD_GET_TAG: - if (arg != octx->taglen || !EVP_CIPHER_CTX_encrypting(c)) + if (arg != octx->taglen || !EVP_CIPHER_CTX_is_encrypting(c)) return 0; memcpy(ptr, octx->tag, arg); @@ -4023,29 +3802,6 @@ static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) } } -# ifdef HWAES_CAPABLE -# ifdef HWAES_ocb_encrypt -void HWAES_ocb_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const void *key, - size_t start_block_num, - unsigned char offset_i[16], - const unsigned char L_[][16], - unsigned char checksum[16]); -# else -# define HWAES_ocb_encrypt ((ocb128_f)NULL) -# endif -# ifdef HWAES_ocb_decrypt -void HWAES_ocb_decrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const void *key, - size_t start_block_num, - unsigned char offset_i[16], - const unsigned char L_[][16], - unsigned char checksum[16]); -# else -# define HWAES_ocb_decrypt ((ocb128_f)NULL) -# endif -# endif - static int aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { @@ -4061,9 +3817,9 @@ static int aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, */ # ifdef HWAES_CAPABLE if (HWAES_CAPABLE) { - HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &octx->ksenc.ks); - HWAES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + HWAES_set_decrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &octx->ksdec.ks); if (!CRYPTO_ocb128_init(&octx->ocb, &octx->ksenc.ks, &octx->ksdec.ks, @@ -4077,9 +3833,11 @@ static int aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, # endif # ifdef VPAES_CAPABLE if (VPAES_CAPABLE) { - vpaes_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + vpaes_set_encrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &octx->ksenc.ks); - vpaes_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + vpaes_set_decrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &octx->ksdec.ks); if (!CRYPTO_ocb128_init(&octx->ocb, &octx->ksenc.ks, &octx->ksdec.ks, @@ -4090,9 +3848,9 @@ static int aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, break; } # endif - AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + AES_set_encrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &octx->ksenc.ks); - AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + AES_set_decrypt_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &octx->ksdec.ks); if (!CRYPTO_ocb128_init(&octx->ocb, &octx->ksenc.ks, &octx->ksdec.ks, @@ -4158,8 +3916,8 @@ static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, buf = octx->data_buf; buf_len = &(octx->data_buf_len); - if (is_partially_overlapping(out + *buf_len, in, len)) { - EVPerr(EVP_F_AES_OCB_CIPHER, EVP_R_PARTIALLY_OVERLAPPING); + if (ossl_is_partially_overlapping(out + *buf_len, in, len)) { + ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING); return 0; } } @@ -4187,7 +3945,7 @@ static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (out == NULL) { if (!CRYPTO_ocb128_aad(&octx->ocb, buf, AES_BLOCK_SIZE)) return -1; - } else if (EVP_CIPHER_CTX_encrypting(ctx)) { + } else if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (!CRYPTO_ocb128_encrypt(&octx->ocb, buf, out, AES_BLOCK_SIZE)) return -1; @@ -4212,7 +3970,7 @@ static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (out == NULL) { if (!CRYPTO_ocb128_aad(&octx->ocb, in, len - trailing_len)) return -1; - } else if (EVP_CIPHER_CTX_encrypting(ctx)) { + } else if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (!CRYPTO_ocb128_encrypt (&octx->ocb, in, out, len - trailing_len)) return -1; @@ -4238,7 +3996,7 @@ static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * have been provided - both for data and AAD */ if (octx->data_buf_len > 0) { - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (!CRYPTO_ocb128_encrypt(&octx->ocb, octx->data_buf, out, octx->data_buf_len)) return -1; @@ -4257,7 +4015,7 @@ static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, octx->aad_buf_len = 0; } /* If decrypting then verify */ - if (!EVP_CIPHER_CTX_encrypting(ctx)) { + if (!EVP_CIPHER_CTX_is_encrypting(ctx)) { if (octx->taglen < 0) return -1; if (CRYPTO_ocb128_finish(&octx->ocb, diff --git a/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c b/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c index 27c36b46e7a4..4941f98e6483 100644 --- a/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c +++ b/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c @@ -1,25 +1,32 @@ /* - * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 +/* + * AES low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" #include #include - +#include #include #include #include #include #include -#include "modes_local.h" +#include "internal/cryptlib.h" +#include "crypto/modes.h" #include "crypto/evp.h" #include "internal/constant_time.h" +#include "evp_local.h" typedef struct { AES_KEY ks; @@ -33,11 +40,10 @@ typedef struct { #define NO_PAYLOAD_LENGTH ((size_t)-1) -#if defined(AESNI_ASM) && ( \ +#if defined(AES_ASM) && ( \ defined(__x86_64) || defined(__x86_64__) || \ defined(_M_AMD64) || defined(_M_X64) ) -extern unsigned int OPENSSL_ia32cap_P[]; # define AESNI_CAPABLE (1<<(57-32)) int aesni_set_encrypt_key(const unsigned char *userKey, int bits, @@ -69,11 +75,11 @@ static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, if (enc) ret = aesni_set_encrypt_key(inkey, - EVP_CIPHER_CTX_key_length(ctx) * 8, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &key->ks); else ret = aesni_set_decrypt_key(inkey, - EVP_CIPHER_CTX_key_length(ctx) * 8, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &key->ks); SHA1_Init(&key->head); /* handy when benchmarking */ @@ -418,7 +424,7 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (len % AES_BLOCK_SIZE) return 0; - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (plen == NO_PAYLOAD_LENGTH) plen = len; else if (len != @@ -433,8 +439,7 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, && (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) { SHA1_Update(&key->md, in + iv, sha_off); - aesni_cbc_sha1_enc(in, out, blocks, &key->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + aesni_cbc_sha1_enc(in, out, blocks, &key->ks, ctx->iv, &key->md, in + iv + sha_off); blocks *= SHA_CBLOCK; aes_off += blocks; @@ -466,10 +471,10 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, out[plen] = l; /* encrypt HMAC|padding at once */ aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off, - &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1); + &key->ks, ctx->iv, 1); } else { aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off, - &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1); + &key->ks, ctx->iv, 1); } } else { union { @@ -499,7 +504,7 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 0; /* omit explicit iv */ - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), in, AES_BLOCK_SIZE); + memcpy(ctx->iv, in, AES_BLOCK_SIZE); in += AES_BLOCK_SIZE; out += AES_BLOCK_SIZE; @@ -520,7 +525,7 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, # endif /* decrypt HMAC|padding at once */ aesni_cbc_encrypt(in, out, len, &key->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), 0); + ctx->iv, 0); /* figure out payload length */ pad = out[len - 1]; @@ -697,8 +702,7 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, size_t off = out - p; unsigned int c, cmask; - maxpad += SHA_DIGEST_LENGTH; - for (res = 0, i = 0, j = 0; j < maxpad; j++) { + for (res = 0, i = 0, j = 0; j < maxpad + SHA_DIGEST_LENGTH; j++) { c = p[j]; cmask = ((int)(j - off - SHA_DIGEST_LENGTH)) >> (sizeof(int) * @@ -708,7 +712,6 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, res |= (c ^ pmac->c[i]) & cmask; i += 1 & cmask; } - maxpad -= SHA_DIGEST_LENGTH; res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); ret &= (int)~res; @@ -756,7 +759,7 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, # endif /* decrypt HMAC|padding at once */ aesni_cbc_encrypt(in, out, len, &key->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), 0); + ctx->iv, 0); SHA1_Update(&key->md, out, len); } @@ -810,7 +813,7 @@ static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, len = p[arg - 2] << 8 | p[arg - 1]; - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { key->payload_length = len; if ((key->aux.tls_ver = p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { @@ -848,7 +851,7 @@ static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, inp_len = param->inp[11] << 8 | param->inp[12]; - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION) return -1; @@ -911,6 +914,7 @@ static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = { AES_BLOCK_SIZE, 16, AES_BLOCK_SIZE, EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, + EVP_ORIG_GLOBAL, aesni_cbc_hmac_sha1_init_key, aesni_cbc_hmac_sha1_cipher, NULL, @@ -930,6 +934,7 @@ static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = { AES_BLOCK_SIZE, 32, AES_BLOCK_SIZE, EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, + EVP_ORIG_GLOBAL, aesni_cbc_hmac_sha1_init_key, aesni_cbc_hmac_sha1_cipher, NULL, diff --git a/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c b/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c index cc622b6faa8c..3a5f757dbff3 100644 --- a/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c +++ b/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c @@ -1,26 +1,32 @@ /* - * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2013-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 +/* + * AES low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" #include #include - - +#include #include #include #include #include #include -#include "modes_local.h" +#include "internal/cryptlib.h" +#include "crypto/modes.h" #include "internal/constant_time.h" #include "crypto/evp.h" +#include "evp_local.h" typedef struct { AES_KEY ks; @@ -34,11 +40,10 @@ typedef struct { # define NO_PAYLOAD_LENGTH ((size_t)-1) -#if defined(AESNI_ASM) && ( \ +#if defined(AES_ASM) && ( \ defined(__x86_64) || defined(__x86_64__) || \ defined(_M_AMD64) || defined(_M_X64) ) -extern unsigned int OPENSSL_ia32cap_P[]; # define AESNI_CAPABLE (1<<(57-32)) int aesni_set_encrypt_key(const unsigned char *userKey, int bits, @@ -66,11 +71,11 @@ static int aesni_cbc_hmac_sha256_init_key(EVP_CIPHER_CTX *ctx, if (enc) ret = aesni_set_encrypt_key(inkey, - EVP_CIPHER_CTX_key_length(ctx) * 8, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &key->ks); else ret = aesni_set_decrypt_key(inkey, - EVP_CIPHER_CTX_key_length(ctx) * 8, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, &key->ks); SHA256_Init(&key->head); /* handy when benchmarking */ @@ -434,7 +439,7 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, if (len % AES_BLOCK_SIZE) return 0; - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (plen == NO_PAYLOAD_LENGTH) plen = len; else if (len != @@ -464,8 +469,7 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, SHA256_Update(&key->md, in + iv, sha_off); (void)aesni_cbc_sha256_enc(in, out, blocks, &key->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), - &key->md, in + iv + sha_off); + ctx->iv, &key->md, in + iv + sha_off); blocks *= SHA256_CBLOCK; aes_off += blocks; sha_off += blocks; @@ -496,10 +500,10 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, out[plen] = l; /* encrypt HMAC|padding at once */ aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off, - &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1); + &key->ks, ctx->iv, 1); } else { aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off, - &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1); + &key->ks, ctx->iv, 1); } } else { union { @@ -512,7 +516,7 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, /* decrypt HMAC|padding at once */ aesni_cbc_encrypt(in, out, len, &key->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), 0); + ctx->iv, 0); if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ size_t inp_len, mask, j, i; @@ -702,8 +706,8 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, size_t off = out - p; unsigned int c, cmask; - maxpad += SHA256_DIGEST_LENGTH; - for (res = 0, i = 0, j = 0; j < maxpad; j++) { + for (res = 0, i = 0, j = 0; j < maxpad + SHA256_DIGEST_LENGTH; + j++) { c = p[j]; cmask = ((int)(j - off - SHA256_DIGEST_LENGTH)) >> @@ -713,7 +717,6 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, res |= (c ^ pmac->c[i]) & cmask; i += 1 & cmask; } - maxpad -= SHA256_DIGEST_LENGTH; res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); ret &= (int)~res; @@ -791,7 +794,7 @@ static int aesni_cbc_hmac_sha256_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, len = p[arg - 2] << 8 | p[arg - 1]; - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { key->payload_length = len; if ((key->aux.tls_ver = p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { @@ -832,7 +835,7 @@ static int aesni_cbc_hmac_sha256_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, inp_len = param->inp[11] << 8 | param->inp[12]; - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION) return -1; @@ -895,6 +898,7 @@ static EVP_CIPHER aesni_128_cbc_hmac_sha256_cipher = { AES_BLOCK_SIZE, 16, AES_BLOCK_SIZE, EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, + EVP_ORIG_GLOBAL, aesni_cbc_hmac_sha256_init_key, aesni_cbc_hmac_sha256_cipher, NULL, @@ -914,6 +918,7 @@ static EVP_CIPHER aesni_256_cbc_hmac_sha256_cipher = { AES_BLOCK_SIZE, 32, AES_BLOCK_SIZE, EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, + EVP_ORIG_GLOBAL, aesni_cbc_hmac_sha256_init_key, aesni_cbc_hmac_sha256_cipher, NULL, @@ -947,4 +952,4 @@ const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void) { return NULL; } -#endif /* AESNI_ASM */ +#endif diff --git a/crypto/openssl/crypto/evp/e_aria.c b/crypto/openssl/crypto/evp/e_aria.c index 1cc6dd91a95a..7e1fda33e121 100644 --- a/crypto/openssl/crypto/evp/e_aria.c +++ b/crypto/openssl/crypto/evp/e_aria.c @@ -1,22 +1,23 @@ /* - * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" #ifndef OPENSSL_NO_ARIA # include # include # include -# include # include "crypto/aria.h" # include "crypto/evp.h" -# include "modes_local.h" +# include "crypto/modes.h" # include "evp_local.h" /* ARIA subkey Structure */ @@ -27,7 +28,7 @@ typedef struct { /* ARIA GCM context */ typedef struct { union { - double align; + OSSL_UNION_ALIGN; ARIA_KEY ks; } ks; /* ARIA subkey to use */ int key_set; /* Set if key initialised */ @@ -43,7 +44,7 @@ typedef struct { /* ARIA CCM context */ typedef struct { union { - double align; + OSSL_UNION_ALIGN; ARIA_KEY ks; } ks; /* ARIA key schedule to use */ int key_set; /* Set if key initialised */ @@ -61,16 +62,18 @@ static int aria_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { int ret; - int mode = EVP_CIPHER_CTX_mode(ctx); + int mode = EVP_CIPHER_CTX_get_mode(ctx); if (enc || (mode != EVP_CIPH_ECB_MODE && mode != EVP_CIPH_CBC_MODE)) - ret = aria_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + ret = ossl_aria_set_encrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, EVP_CIPHER_CTX_get_cipher_data(ctx)); else - ret = aria_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + ret = ossl_aria_set_decrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, EVP_CIPHER_CTX_get_cipher_data(ctx)); if (ret < 0) { - EVPerr(EVP_F_ARIA_INIT_KEY,EVP_R_ARIA_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_EVP,EVP_R_ARIA_KEY_SETUP_FAILED); return 0; } return 1; @@ -83,10 +86,10 @@ static void aria_cbc_encrypt(const unsigned char *in, unsigned char *out, if (enc) CRYPTO_cbc128_encrypt(in, out, len, key, ivec, - (block128_f) aria_encrypt); + (block128_f) ossl_aria_encrypt); else CRYPTO_cbc128_decrypt(in, out, len, key, ivec, - (block128_f) aria_encrypt); + (block128_f) ossl_aria_encrypt); } static void aria_cfb128_encrypt(const unsigned char *in, unsigned char *out, @@ -95,7 +98,7 @@ static void aria_cfb128_encrypt(const unsigned char *in, unsigned char *out, { CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, - (block128_f) aria_encrypt); + (block128_f) ossl_aria_encrypt); } static void aria_cfb1_encrypt(const unsigned char *in, unsigned char *out, @@ -103,7 +106,7 @@ static void aria_cfb1_encrypt(const unsigned char *in, unsigned char *out, unsigned char *ivec, int *num, const int enc) { CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc, - (block128_f) aria_encrypt); + (block128_f) ossl_aria_encrypt); } static void aria_cfb8_encrypt(const unsigned char *in, unsigned char *out, @@ -111,13 +114,13 @@ static void aria_cfb8_encrypt(const unsigned char *in, unsigned char *out, unsigned char *ivec, int *num, const int enc) { CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc, - (block128_f) aria_encrypt); + (block128_f) ossl_aria_encrypt); } static void aria_ecb_encrypt(const unsigned char *in, unsigned char *out, const ARIA_KEY *key, const int enc) { - aria_encrypt(in, out, key); + ossl_aria_encrypt(in, out, key); } static void aria_ofb128_encrypt(const unsigned char *in, unsigned char *out, @@ -125,7 +128,7 @@ static void aria_ofb128_encrypt(const unsigned char *in, unsigned char *out, unsigned char *ivec, int *num) { CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, - (block128_f) aria_encrypt); + (block128_f) ossl_aria_encrypt); } IMPLEMENT_BLOCK_CIPHER(aria_128, ks, aria, EVP_ARIA_KEY, @@ -160,6 +163,7 @@ IMPLEMENT_ARIA_CFBR(256,8) static const EVP_CIPHER aria_##keylen##_##mode = { \ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aria_init_key, \ aria_##mode##_cipher, \ NULL, \ @@ -171,13 +175,17 @@ const EVP_CIPHER *EVP_aria_##keylen##_##mode(void) \ static int aria_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - unsigned int num = EVP_CIPHER_CTX_num(ctx); - EVP_ARIA_KEY *dat = EVP_C_DATA(EVP_ARIA_KEY,ctx); + int n = EVP_CIPHER_CTX_get_num(ctx); + unsigned int num; + EVP_ARIA_KEY *dat = EVP_C_DATA(EVP_ARIA_KEY, ctx); + + if (n < 0) + return 0; + num = (unsigned int)n; - CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, EVP_CIPHER_CTX_buf_noconst(ctx), &num, - (block128_f) aria_encrypt); + (block128_f) ossl_aria_encrypt); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -213,12 +221,13 @@ static int aria_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (!iv && !key) return 1; if (key) { - ret = aria_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, - &gctx->ks.ks); + ret = ossl_aria_set_encrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, + &gctx->ks.ks); CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, - (block128_f) aria_encrypt); + (block128_f) ossl_aria_encrypt); if (ret < 0) { - EVPerr(EVP_F_ARIA_GCM_INIT_KEY,EVP_R_ARIA_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_EVP,EVP_R_ARIA_KEY_SETUP_FAILED); return 0; } @@ -252,41 +261,41 @@ 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_iv_length(c->cipher); - gctx->iv = EVP_CIPHER_CTX_iv_noconst(c); + gctx->ivlen = EVP_CIPHER_get_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; /* Allocate memory for IV if needed */ if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { - if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c)) + if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); if ((gctx->iv = OPENSSL_malloc(arg)) == NULL) { - EVPerr(EVP_F_ARIA_GCM_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } } 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)) + if (arg <= 0 || arg > 16 || EVP_CIPHER_CTX_is_encrypting(c)) return 0; memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg); gctx->taglen = arg; return 1; case EVP_CTRL_AEAD_GET_TAG: - if (arg <= 0 || arg > 16 || !EVP_CIPHER_CTX_encrypting(c) + if (arg <= 0 || arg > 16 || !EVP_CIPHER_CTX_is_encrypting(c) || gctx->taglen < 0) return 0; memcpy(ptr, EVP_CIPHER_CTX_buf_noconst(c), arg); @@ -307,7 +316,7 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; if (arg) memcpy(gctx->iv, ptr, arg); - if (EVP_CIPHER_CTX_encrypting(c) + if (EVP_CIPHER_CTX_is_encrypting(c) && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) return 0; gctx->iv_gen = 1; @@ -330,7 +339,7 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_GCM_SET_IV_INV: if (gctx->iv_gen == 0 || gctx->key_set == 0 - || EVP_CIPHER_CTX_encrypting(c)) + || EVP_CIPHER_CTX_is_encrypting(c)) return 0; memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); @@ -352,7 +361,7 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ - if (!EVP_CIPHER_CTX_encrypting(c)) { + if (!EVP_CIPHER_CTX_is_encrypting(c)) { if (len < EVP_GCM_TLS_TAG_LEN) return 0; len -= EVP_GCM_TLS_TAG_LEN; @@ -372,11 +381,11 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; gctx_out->gcm.key = &gctx_out->ks; } - if (gctx->iv == EVP_CIPHER_CTX_iv_noconst(c)) - gctx_out->iv = EVP_CIPHER_CTX_iv_noconst(out); + if (gctx->iv == c->iv) + gctx_out->iv = out->iv; else { if ((gctx_out->iv = OPENSSL_malloc(gctx->ivlen)) == NULL) { - EVPerr(EVP_F_ARIA_GCM_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); @@ -404,7 +413,7 @@ static int aria_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * Set IV from start of buffer or generate IV and write to start of * buffer. */ - if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CIPHER_CTX_encrypting(ctx) ? + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CIPHER_CTX_is_encrypting(ctx) ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) goto err; @@ -416,7 +425,7 @@ static int aria_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, in += EVP_GCM_TLS_EXPLICIT_IV_LEN; out += EVP_GCM_TLS_EXPLICIT_IV_LEN; len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { /* Encrypt payload */ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) goto err; @@ -464,7 +473,7 @@ static int aria_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (out == NULL) { if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) return -1; - } else if (EVP_CIPHER_CTX_encrypting(ctx)) { + } else if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) return -1; } else { @@ -473,7 +482,7 @@ static int aria_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } return len; } - if (!EVP_CIPHER_CTX_encrypting(ctx)) { + if (!EVP_CIPHER_CTX_is_encrypting(ctx)) { if (gctx->taglen < 0) return -1; if (CRYPTO_gcm128_finish(&gctx->gcm, @@ -494,7 +503,7 @@ static int aria_gcm_cleanup(EVP_CIPHER_CTX *ctx) { EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx); - if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(ctx)) + if (gctx->iv != ctx->iv) OPENSSL_free(gctx->iv); return 1; @@ -510,19 +519,20 @@ static int aria_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, return 1; if (key) { - ret = aria_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, - &cctx->ks.ks); + ret = ossl_aria_set_encrypt_key(key, + EVP_CIPHER_CTX_get_key_length(ctx) * 8, + &cctx->ks.ks); CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, - &cctx->ks, (block128_f) aria_encrypt); + &cctx->ks, (block128_f) ossl_aria_encrypt); if (ret < 0) { - EVPerr(EVP_F_ARIA_CCM_INIT_KEY,EVP_R_ARIA_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_EVP,EVP_R_ARIA_KEY_SETUP_FAILED); return 0; } cctx->str = NULL; cctx->key_set = 1; } if (iv) { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L); + memcpy(ctx->iv, iv, 15 - cctx->L); cctx->iv_set = 1; } return 1; @@ -543,6 +553,10 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) cctx->tls_aad_len = -1; return 1; + case EVP_CTRL_GET_IVLEN: + *(int *)ptr = 15 - cctx->L; + return 1; + case EVP_CTRL_AEAD_TLS1_AAD: /* Save the AAD for later use */ if (arg != EVP_AEAD_TLS1_AAD_LEN) @@ -558,7 +572,7 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; len -= EVP_CCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ - if (!EVP_CIPHER_CTX_encrypting(c)) { + if (!EVP_CIPHER_CTX_is_encrypting(c)) { if (len < cctx->M) return 0; len -= cctx->M; @@ -574,11 +588,7 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (arg != EVP_CCM_TLS_FIXED_IV_LEN) return 0; /* Just copy to first part of IV */ - memcpy(EVP_CIPHER_CTX_iv_noconst(c), ptr, arg); - return 1; - - case EVP_CTRL_GET_IVLEN: - *(int *)ptr = 15 - cctx->L; + memcpy(c->iv, ptr, arg); return 1; case EVP_CTRL_AEAD_SET_IVLEN: @@ -592,7 +602,7 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_AEAD_SET_TAG: if ((arg & 1) || arg < 4 || arg > 16) return 0; - if (EVP_CIPHER_CTX_encrypting(c) && ptr) + if (EVP_CIPHER_CTX_is_encrypting(c) && ptr) return 0; if (ptr) { cctx->tag_set = 1; @@ -602,7 +612,7 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 1; case EVP_CTRL_AEAD_GET_TAG: - if (!EVP_CIPHER_CTX_encrypting(c) || !cctx->tag_set) + if (!EVP_CIPHER_CTX_is_encrypting(c) || !cctx->tag_set) return 0; if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg)) return 0; @@ -638,23 +648,24 @@ static int aria_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M)) return -1; /* If encrypting set explicit IV from sequence number (start of AAD) */ - if (EVP_CIPHER_CTX_encrypting(ctx)) + if (EVP_CIPHER_CTX_is_encrypting(ctx)) memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx), EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Get rest of IV from explicit IV */ - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx) + EVP_CCM_TLS_FIXED_IV_LEN, in, + memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Correct length value */ len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), 15 - cctx->L, + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; /* Use saved AAD */ - CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx), cctx->tls_aad_len); + CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx), + cctx->tls_aad_len); /* Fix buffer to point to payload */ in += EVP_CCM_TLS_EXPLICIT_IV_LEN; out += EVP_CCM_TLS_EXPLICIT_IV_LEN; - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str) : CRYPTO_ccm128_encrypt(ccm, in, out, len)) return -1; @@ -697,8 +708,7 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (!out) { if (!in) { - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), - 15 - cctx->L, len)) + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; cctx->len_set = 1; return len; @@ -711,17 +721,16 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } /* The tag must be set before actually decrypting data */ - if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set) + if (!EVP_CIPHER_CTX_is_encrypting(ctx) && !cctx->tag_set) return -1; /* If not set length yet do it */ if (!cctx->len_set) { - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), - 15 - cctx->L, len)) + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; cctx->len_set = 1; } - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str) : CRYPTO_ccm128_encrypt(ccm, in, out, len)) return -1; @@ -761,6 +770,7 @@ static const EVP_CIPHER aria_##keylen##_##mode = { \ nid##_##keylen##_##nmode, \ blocksize, keylen/8, ivlen, \ ARIA_AUTH_FLAGS|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ aria_##mode##_init_key, \ aria_##mode##_cipher, \ aria_##mode##_cleanup, \ diff --git a/crypto/openssl/crypto/evp/e_bf.c b/crypto/openssl/crypto/evp/e_bf.c index 9a065582c6c8..2aeda2ecf07a 100644 --- a/crypto/openssl/crypto/evp/e_bf.c +++ b/crypto/openssl/crypto/evp/e_bf.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * BF low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #ifndef OPENSSL_NO_BF @@ -14,6 +20,7 @@ # include "crypto/evp.h" # include # include +# include "evp_local.h" static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); @@ -31,7 +38,11 @@ IMPLEMENT_BLOCK_CIPHER(bf, ks, BF, EVP_BF_KEY, NID_bf, 8, 16, 8, 64, static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - BF_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + int len = EVP_CIPHER_CTX_get_key_length(ctx); + + if (len < 0) + return 0; + BF_set_key(&data(ctx)->ks, len, key); return 1; } diff --git a/crypto/openssl/crypto/evp/e_camellia.c b/crypto/openssl/crypto/evp/e_camellia.c index f8c019801267..4f1f4822dc92 100644 --- a/crypto/openssl/crypto/evp/e_camellia.c +++ b/crypto/openssl/crypto/evp/e_camellia.c @@ -1,24 +1,29 @@ /* * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * Camellia low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include -#ifdef OPENSSL_NO_CAMELLIA -NON_EMPTY_TRANSLATION_UNIT -#else -# include -# include -# include -# include -# include -# include "crypto/evp.h" -# include "modes_local.h" +#include +#include +#include +#include +#include +#include "crypto/evp.h" +#include "crypto/modes.h" +#include "crypto/cmll_platform.h" +#include "evp_local.h" static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); @@ -33,44 +38,15 @@ typedef struct { } stream; } EVP_CAMELLIA_KEY; -# define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) +#define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) /* Attribute operation for Camellia */ -# define data(ctx) EVP_C_DATA(EVP_CAMELLIA_KEY,ctx) +#define data(ctx) EVP_C_DATA(EVP_CAMELLIA_KEY,ctx) -# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) +#if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) /* ---------^^^ this is not a typo, just a way to detect that * assembler support was in general requested... */ -# include "sparc_arch.h" - -extern unsigned int OPENSSL_sparcv9cap_P[]; - -# define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA) - -void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks); -void cmll_t4_encrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key); -void cmll_t4_decrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key); - -void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec, int /*unused*/); -void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec, int /*unused*/); -void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec, int /*unused*/); -void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec, int /*unused*/); -void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const CAMELLIA_KEY *key, - unsigned char *ivec); -void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const CAMELLIA_KEY *key, - unsigned char *ivec); +# include "crypto/sparc_arch.h" static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) @@ -79,8 +55,8 @@ static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx); - mode = EVP_CIPHER_CTX_mode(ctx); - bits = EVP_CIPHER_CTX_key_length(ctx) * 8; + mode = EVP_CIPHER_CTX_get_mode(ctx); + bits = EVP_CIPHER_CTX_get_key_length(ctx) * 8; cmll_t4_set_key(key, bits, &dat->ks); @@ -128,45 +104,46 @@ static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } if (ret < 0) { - EVPerr(EVP_F_CMLL_T4_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_EVP, EVP_R_CAMELLIA_KEY_SETUP_FAILED); return 0; } return 1; } -# define cmll_t4_cbc_cipher camellia_cbc_cipher +# define cmll_t4_cbc_cipher camellia_cbc_cipher static int cmll_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define cmll_t4_ecb_cipher camellia_ecb_cipher +# define cmll_t4_ecb_cipher camellia_ecb_cipher static int cmll_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define cmll_t4_ofb_cipher camellia_ofb_cipher +# define cmll_t4_ofb_cipher camellia_ofb_cipher static int cmll_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define cmll_t4_cfb_cipher camellia_cfb_cipher +# define cmll_t4_cfb_cipher camellia_cfb_cipher static int cmll_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define cmll_t4_cfb8_cipher camellia_cfb8_cipher +# define cmll_t4_cfb8_cipher camellia_cfb8_cipher static int cmll_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define cmll_t4_cfb1_cipher camellia_cfb1_cipher +# define cmll_t4_cfb1_cipher camellia_cfb1_cipher static int cmll_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define cmll_t4_ctr_cipher camellia_ctr_cipher +# define cmll_t4_ctr_cipher camellia_ctr_cipher static int cmll_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); -# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ static const EVP_CIPHER cmll_t4_##keylen##_##mode = { \ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ cmll_t4_init_key, \ cmll_t4_##mode##_cipher, \ NULL, \ @@ -176,6 +153,7 @@ static const EVP_CIPHER camellia_##keylen##_##mode = { \ nid##_##keylen##_##nmode,blocksize, \ keylen/8,ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ camellia_init_key, \ camellia_##mode##_cipher, \ NULL, \ @@ -184,12 +162,13 @@ static const EVP_CIPHER camellia_##keylen##_##mode = { \ const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \ { return SPARC_CMLL_CAPABLE?&cmll_t4_##keylen##_##mode:&camellia_##keylen##_##mode; } -# else +#else -# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ static const EVP_CIPHER camellia_##keylen##_##mode = { \ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ flags|EVP_CIPH_##MODE##_MODE, \ + EVP_ORIG_GLOBAL, \ camellia_init_key, \ camellia_##mode##_cipher, \ NULL, \ @@ -198,9 +177,9 @@ static const EVP_CIPHER camellia_##keylen##_##mode = { \ const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \ { return &camellia_##keylen##_##mode; } -# endif +#endif -# define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ +#define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ @@ -216,13 +195,14 @@ static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, int ret, mode; EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); - ret = Camellia_set_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, &dat->ks); + ret = Camellia_set_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, + &dat->ks); if (ret < 0) { - EVPerr(EVP_F_CAMELLIA_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_EVP, EVP_R_CAMELLIA_KEY_SETUP_FAILED); return 0; } - mode = EVP_CIPHER_CTX_mode(ctx); + mode = EVP_CIPHER_CTX_get_mode(ctx); if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { dat->block = (block128_f) Camellia_decrypt; @@ -243,15 +223,12 @@ static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); if (dat->stream.cbc) - (*dat->stream.cbc) (in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); - else if (EVP_CIPHER_CTX_encrypting(ctx)) - CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), dat->block); + (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); + else if (EVP_CIPHER_CTX_is_encrypting(ctx)) + CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block); else - CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), dat->block); + CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block); return 1; } @@ -259,7 +236,7 @@ static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - size_t bl = EVP_CIPHER_CTX_block_size(ctx); + size_t bl = EVP_CIPHER_CTX_get_block_size(ctx); size_t i; EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); @@ -277,9 +254,8 @@ static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); - int num = EVP_CIPHER_CTX_num(ctx); - CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, dat->block); + int num = EVP_CIPHER_CTX_get_num(ctx); + CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, ctx->iv, &num, dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -289,9 +265,9 @@ static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); - int num = EVP_CIPHER_CTX_num(ctx); - CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); + int num = EVP_CIPHER_CTX_get_num(ctx); + CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -301,9 +277,9 @@ static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); - int num = EVP_CIPHER_CTX_num(ctx); - CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); + int num = EVP_CIPHER_CTX_get_num(ctx); + CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -314,26 +290,31 @@ static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) { - int num = EVP_CIPHER_CTX_num(ctx); - CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); + int num = EVP_CIPHER_CTX_get_num(ctx); + CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx), + dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } while (len >= MAXBITCHUNK) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); + ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx), + dat->block); EVP_CIPHER_CTX_set_num(ctx, num); len -= MAXBITCHUNK; out += MAXBITCHUNK; in += MAXBITCHUNK; } if (len) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); + ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx), + dat->block); EVP_CIPHER_CTX_set_num(ctx, num); } @@ -343,17 +324,20 @@ static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - unsigned int num = EVP_CIPHER_CTX_num(ctx); + int snum = EVP_CIPHER_CTX_get_num(ctx); + unsigned int num; EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); + if (snum < 0) + return 0; + num = snum; if (dat->stream.ctr) - CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_buf_noconst(ctx), &num, + CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ctx->iv, + EVP_CIPHER_CTX_buf_noconst(ctx), + &num, dat->stream.ctr); else - CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, EVP_CIPHER_CTX_buf_noconst(ctx), &num, dat->block); EVP_CIPHER_CTX_set_num(ctx, num); @@ -363,4 +347,3 @@ static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, BLOCK_CIPHER_generic_pack(NID_camellia, 128, 0) BLOCK_CIPHER_generic_pack(NID_camellia, 192, 0) BLOCK_CIPHER_generic_pack(NID_camellia, 256, 0) -#endif diff --git a/crypto/openssl/crypto/evp/e_cast.c b/crypto/openssl/crypto/evp/e_cast.c index df9f445bd0a2..5e9be2dc7dd5 100644 --- a/crypto/openssl/crypto/evp/e_cast.c +++ b/crypto/openssl/crypto/evp/e_cast.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * CAST low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" @@ -15,6 +21,7 @@ # include # include "crypto/evp.h" # include +# include "evp_local.h" static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); @@ -33,7 +40,11 @@ IMPLEMENT_BLOCK_CIPHER(cast5, ks, CAST, EVP_CAST_KEY, static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + int keylen = EVP_CIPHER_CTX_get_key_length(ctx); + + if (keylen <= 0) + return 0; + CAST_set_key(&data(ctx)->ks, keylen, key); return 1; } diff --git a/crypto/openssl/crypto/evp/e_chacha20_poly1305.c b/crypto/openssl/crypto/evp/e_chacha20_poly1305.c index bdc406bb69dc..18e1c0b5ac06 100644 --- a/crypto/openssl/crypto/evp/e_chacha20_poly1305.c +++ b/crypto/openssl/crypto/evp/e_chacha20_poly1305.c @@ -1,7 +1,7 @@ /* - * Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,18 +9,19 @@ #include #include "internal/cryptlib.h" +#include "internal/endian.h" #ifndef OPENSSL_NO_CHACHA # include # include -# include "evp_local.h" # include "crypto/evp.h" +# include "evp_local.h" # include "crypto/chacha.h" typedef struct { union { - double align; /* this ensures even sizeof(EVP_CHACHA_KEY)%8==0 */ + OSSL_UNION_ALIGN; /* this ensures even sizeof(EVP_CHACHA_KEY)%8==0 */ unsigned int d[CHACHA_KEY_SIZE / 4]; } key; unsigned int counter[CHACHA_CTR_SIZE / 4]; @@ -130,6 +131,7 @@ static const EVP_CIPHER chacha20 = { CHACHA_KEY_SIZE, /* key_len */ CHACHA_CTR_SIZE, /* iv_len, 128-bit counter in the context */ EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT, + EVP_ORIG_GLOBAL, chacha_init_key, chacha_cipher, NULL, @@ -310,12 +312,9 @@ static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } { - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { memcpy(ctr, (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE); } else { ctr[0] = (unsigned char)(actx->len.aad); @@ -426,10 +425,7 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } if (in == NULL /* explicit final */ || plen != len) { /* or tls mode */ - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; unsigned char temp[POLY1305_BLOCK_SIZE]; if (actx->aad) { /* wrap up aad */ @@ -443,7 +439,7 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, Poly1305_Update(POLY1305_ctx(actx), zero, POLY1305_BLOCK_SIZE - rem); - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { Poly1305_Update(POLY1305_ctx(actx), (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE); } else { @@ -508,7 +504,7 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, actx = ctx->cipher_data = OPENSSL_zalloc(sizeof(*actx) + Poly1305_ctx_size()); if (actx == NULL) { - EVPerr(EVP_F_CHACHA20_POLY1305_CTRL, EVP_R_INITIALIZATION_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); return 0; } actx->len.aad = 0; @@ -528,7 +524,7 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, dst->cipher_data = OPENSSL_memdup(actx, sizeof(*actx) + Poly1305_ctx_size()); if (dst->cipher_data == NULL) { - EVPerr(EVP_F_CHACHA20_POLY1305_CTRL, EVP_R_COPY_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_COPY_ERROR); return 0; } } @@ -619,6 +615,7 @@ static EVP_CIPHER chacha20_poly1305 = { EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_CUSTOM_IV_LENGTH, + EVP_ORIG_GLOBAL, chacha20_poly1305_init_key, chacha20_poly1305_cipher, chacha20_poly1305_cleanup, diff --git a/crypto/openssl/crypto/evp/e_des.c b/crypto/openssl/crypto/evp/e_des.c index 6d6e919af696..cd6e5af8d0e4 100644 --- a/crypto/openssl/crypto/evp/e_des.c +++ b/crypto/openssl/crypto/evp/e_des.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #ifndef OPENSSL_NO_DES @@ -15,10 +21,11 @@ # include "crypto/evp.h" # include # include +# include "evp_local.h" typedef struct { union { - double align; + OSSL_UNION_ALIGN; DES_key_schedule ks; } ks; union { @@ -30,9 +37,7 @@ typedef struct { # if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) /* ----------^^^ this is not a typo, just a way to detect that * assembler support was in general requested... */ -# include "sparc_arch.h" - -extern unsigned int OPENSSL_sparcv9cap_P[]; +# include "crypto/sparc_arch.h" # define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) @@ -58,7 +63,7 @@ static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, BLOCK_CIPHER_ecb_loop() DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), EVP_CIPHER_CTX_get_cipher_data(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + EVP_CIPHER_CTX_is_encrypting(ctx)); return 1; } @@ -66,20 +71,20 @@ static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { while (inl >= EVP_MAXCHUNK) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num); + (DES_cblock *)ctx->iv, &num); EVP_CIPHER_CTX_set_num(ctx, num); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; out += EVP_MAXCHUNK; } if (inl) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); DES_ofb64_encrypt(in, out, (long)inl, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num); + (DES_cblock *)ctx->iv, &num); EVP_CIPHER_CTX_set_num(ctx, num); } return 1; @@ -91,15 +96,14 @@ static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_DES_KEY *dat = (EVP_DES_KEY *) EVP_CIPHER_CTX_get_cipher_data(ctx); if (dat->stream.cbc != NULL) { - (*dat->stream.cbc) (in, out, inl, &dat->ks.ks, - EVP_CIPHER_CTX_iv_noconst(ctx)); + (*dat->stream.cbc) (in, out, inl, &dat->ks.ks, ctx->iv); return 1; } while (inl >= EVP_MAXCHUNK) { DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + (DES_cblock *)ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; out += EVP_MAXCHUNK; @@ -107,8 +111,8 @@ static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (inl) DES_ncbc_encrypt(in, out, (long)inl, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + (DES_cblock *)ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); return 1; } @@ -116,22 +120,22 @@ static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { while (inl >= EVP_MAXCHUNK) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num, - EVP_CIPHER_CTX_encrypting(ctx)); + (DES_cblock *)ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx)); EVP_CIPHER_CTX_set_num(ctx, num); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; out += EVP_MAXCHUNK; } if (inl) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); DES_cfb64_encrypt(in, out, (long)inl, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num, - EVP_CIPHER_CTX_encrypting(ctx)); + (DES_cblock *)ctx->iv, &num, + EVP_CIPHER_CTX_is_encrypting(ctx)); EVP_CIPHER_CTX_set_num(ctx, num); } return 1; @@ -154,8 +158,8 @@ static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, for (n = 0; n < chunk * 8; ++n) { c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; DES_cfb_encrypt(c, d, 1, 1, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + (DES_cblock *)ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | ((d[0] & 0x80) >> (unsigned int)(n % 8)); @@ -176,8 +180,8 @@ static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, while (inl >= EVP_MAXCHUNK) { DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + (DES_cblock *)ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; out += EVP_MAXCHUNK; @@ -185,8 +189,8 @@ static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (inl) DES_cfb_encrypt(in, out, 8, (long)inl, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + (DES_cblock *)ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); return 1; } @@ -211,7 +215,7 @@ static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, dat->stream.cbc = NULL; # if defined(SPARC_DES_CAPABLE) if (SPARC_DES_CAPABLE) { - int mode = EVP_CIPHER_CTX_mode(ctx); + int mode = EVP_CIPHER_CTX_get_mode(ctx); if (mode == EVP_CIPH_CBC_MODE) { des_t4_key_expand(key, &dat->ks.ks); diff --git a/crypto/openssl/crypto/evp/e_des3.c b/crypto/openssl/crypto/evp/e_des3.c index 2a5597fee527..1e1591834402 100644 --- a/crypto/openssl/crypto/evp/e_des3.c +++ b/crypto/openssl/crypto/evp/e_des3.c @@ -1,25 +1,31 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #ifndef OPENSSL_NO_DES -# include # include # include "crypto/evp.h" +# include "crypto/sha.h" # include # include # include "evp_local.h" typedef struct { union { - double align; + OSSL_UNION_ALIGN; DES_key_schedule ks[3]; } ks; union { @@ -34,9 +40,7 @@ typedef struct { # if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) /* ---------^^^ this is not a typo, just a way to detect that * assembler support was in general requested... */ -# include "sparc_arch.h" - -extern unsigned int OPENSSL_sparcv9cap_P[]; +# include "crypto/sparc_arch.h" # define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) @@ -69,7 +73,7 @@ static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, DES_ecb3_encrypt((const_DES_cblock *)(in + i), (DES_cblock *)(out + i), &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, EVP_CIPHER_CTX_encrypting(ctx)); + &data(ctx)->ks3, EVP_CIPHER_CTX_is_encrypting(ctx)); return 1; } @@ -77,11 +81,11 @@ static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { while (inl >= EVP_MAXCHUNK) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, &num); EVP_CIPHER_CTX_set_num(ctx, num); inl -= EVP_MAXCHUNK; @@ -89,11 +93,11 @@ static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, out += EVP_MAXCHUNK; } if (inl) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); DES_ede3_ofb64_encrypt(in, out, (long)inl, &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, &num); EVP_CIPHER_CTX_set_num(ctx, num); } @@ -107,15 +111,15 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (dat->stream.cbc != NULL) { (*dat->stream.cbc) (in, out, inl, dat->ks.ks, - EVP_CIPHER_CTX_iv_noconst(ctx)); + ctx->iv); return 1; } while (inl >= EVP_MAXCHUNK) { DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &dat->ks1, &dat->ks2, &dat->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + (DES_cblock *)ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; out += EVP_MAXCHUNK; @@ -123,8 +127,8 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (inl) DES_ede3_cbc_encrypt(in, out, (long)inl, &dat->ks1, &dat->ks2, &dat->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + (DES_cblock *)ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); return 1; } @@ -132,24 +136,22 @@ static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { while (inl >= EVP_MAXCHUNK) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - &num, EVP_CIPHER_CTX_encrypting(ctx)); + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + &num, EVP_CIPHER_CTX_is_encrypting(ctx)); EVP_CIPHER_CTX_set_num(ctx, num); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; out += EVP_MAXCHUNK; } if (inl) { - int num = EVP_CIPHER_CTX_num(ctx); + int num = EVP_CIPHER_CTX_get_num(ctx); DES_ede3_cfb64_encrypt(in, out, (long)inl, &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - &num, EVP_CIPHER_CTX_encrypting(ctx)); + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + &num, EVP_CIPHER_CTX_is_encrypting(ctx)); EVP_CIPHER_CTX_set_num(ctx, num); } return 1; @@ -171,9 +173,8 @@ static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; DES_ede3_cfb_encrypt(c, d, 1, 1, &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | ((d[0] & 0x80) >> (unsigned int)(n % 8)); } @@ -187,9 +188,8 @@ static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, while (inl >= EVP_MAXCHUNK) { DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; out += EVP_MAXCHUNK; @@ -197,9 +197,8 @@ static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (inl) DES_ede3_cfb_encrypt(in, out, 8, (long)inl, &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + EVP_CIPHER_CTX_is_encrypting(ctx)); return 1; } @@ -231,7 +230,7 @@ static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, dat->stream.cbc = NULL; # if defined(SPARC_DES_CAPABLE) if (SPARC_DES_CAPABLE) { - int mode = EVP_CIPHER_CTX_mode(ctx); + int mode = EVP_CIPHER_CTX_get_mode(ctx); if (mode == EVP_CIPH_CBC_MODE) { des_t4_key_expand(&deskey[0], &dat->ks1); @@ -258,7 +257,7 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, dat->stream.cbc = NULL; # if defined(SPARC_DES_CAPABLE) if (SPARC_DES_CAPABLE) { - int mode = EVP_CIPHER_CTX_mode(ctx); + int mode = EVP_CIPHER_CTX_get_mode(ctx); if (mode == EVP_CIPH_CBC_MODE) { des_t4_key_expand(&deskey[0], &dat->ks1); @@ -280,15 +279,17 @@ static int des3_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) { DES_cblock *deskey = ptr; + int kl; switch (type) { case EVP_CTRL_RAND_KEY: - if (RAND_priv_bytes(ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0) + kl = EVP_CIPHER_CTX_get_key_length(ctx); + if (kl < 0 || RAND_priv_bytes(ptr, kl) <= 0) return 0; DES_set_odd_parity(deskey); - if (EVP_CIPHER_CTX_key_length(ctx) >= 16) + if (kl >= 16) DES_set_odd_parity(deskey + 1); - if (EVP_CIPHER_CTX_key_length(ctx) >= 24) + if (kl >= 24) DES_set_odd_parity(deskey + 2); return 1; @@ -322,7 +323,7 @@ static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out, return -1; if (out == NULL) return inl - 16; - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), wrap_iv, 8); + memcpy(ctx->iv, wrap_iv, 8); /* Decrypt first block which will end up as icv */ des_ede_cbc_cipher(ctx, icv, in, 8); /* Decrypt central blocks */ @@ -340,19 +341,17 @@ static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out, /* Reverse order of everything */ BUF_reverse(icv, NULL, 8); BUF_reverse(out, NULL, inl - 16); - BUF_reverse(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 8); + BUF_reverse(ctx->iv, iv, 8); /* Decrypt again using new IV */ des_ede_cbc_cipher(ctx, out, out, inl - 16); des_ede_cbc_cipher(ctx, icv, icv, 8); - /* Work out SHA1 hash of first portion */ - SHA1(out, inl - 16, sha1tmp); - - if (!CRYPTO_memcmp(sha1tmp, icv, 8)) + if (ossl_sha1(out, inl - 16, sha1tmp) /* Work out hash of first portion */ + && CRYPTO_memcmp(sha1tmp, icv, 8) == 0) rv = inl - 16; OPENSSL_cleanse(icv, 8); OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); OPENSSL_cleanse(iv, 8); - OPENSSL_cleanse(EVP_CIPHER_CTX_iv_noconst(ctx), 8); + OPENSSL_cleanse(ctx->iv, 8); if (rv == -1) OPENSSL_cleanse(out, inl - 16); @@ -368,17 +367,18 @@ static int des_ede3_wrap(EVP_CIPHER_CTX *ctx, unsigned char *out, /* Copy input to output buffer + 8 so we have space for IV */ memmove(out + 8, in, inl); /* Work out ICV */ - SHA1(in, inl, sha1tmp); + if (!ossl_sha1(in, inl, sha1tmp)) + return -1; memcpy(out + inl + 8, sha1tmp, 8); OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); /* Generate random IV */ - if (RAND_bytes(EVP_CIPHER_CTX_iv_noconst(ctx), 8) <= 0) + if (RAND_bytes(ctx->iv, 8) <= 0) return -1; - memcpy(out, EVP_CIPHER_CTX_iv_noconst(ctx), 8); + memcpy(out, ctx->iv, 8); /* Encrypt everything after IV in place */ des_ede_cbc_cipher(ctx, out + 8, out + 8, inl + 8); BUF_reverse(out, NULL, inl + 16); - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), wrap_iv, 8); + memcpy(ctx->iv, wrap_iv, 8); des_ede_cbc_cipher(ctx, out, out, inl + 16); return inl + 16; } @@ -394,12 +394,12 @@ static int des_ede3_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (inl >= EVP_MAXCHUNK || inl % 8) return -1; - if (is_partially_overlapping(out, in, inl)) { - EVPerr(EVP_F_DES_EDE3_WRAP_CIPHER, EVP_R_PARTIALLY_OVERLAPPING); + if (ossl_is_partially_overlapping(out, in, inl)) { + ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING); return 0; } - if (EVP_CIPHER_CTX_encrypting(ctx)) + if (EVP_CIPHER_CTX_is_encrypting(ctx)) return des_ede3_wrap(ctx, out, in, inl); else return des_ede3_unwrap(ctx, out, in, inl); @@ -410,6 +410,7 @@ static const EVP_CIPHER des3_wrap = { 8, 24, 0, EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_FLAG_DEFAULT_ASN1, + EVP_ORIG_GLOBAL, des_ede3_init_key, des_ede3_wrap_cipher, NULL, sizeof(DES_EDE_KEY), diff --git a/crypto/openssl/crypto/evp/e_idea.c b/crypto/openssl/crypto/evp/e_idea.c index 1068378ddc75..4a4df4b92510 100644 --- a/crypto/openssl/crypto/evp/e_idea.c +++ b/crypto/openssl/crypto/evp/e_idea.c @@ -1,12 +1,19 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * IDEA low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" @@ -15,6 +22,7 @@ # include # include "crypto/evp.h" # include +# include "evp_local.h" /* Can't use IMPLEMENT_BLOCK_CIPHER because IDEA_ecb_encrypt is different */ @@ -50,9 +58,9 @@ static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { if (!enc) { - if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) + if (EVP_CIPHER_CTX_get_mode(ctx) == EVP_CIPH_OFB_MODE) enc = 1; - else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE) + else if (EVP_CIPHER_CTX_get_mode(ctx) == EVP_CIPH_CFB_MODE) enc = 1; } if (enc) diff --git a/crypto/openssl/crypto/evp/e_null.c b/crypto/openssl/crypto/evp/e_null.c index 0725454a3a4a..af900c52989f 100644 --- a/crypto/openssl/crypto/evp/e_null.c +++ b/crypto/openssl/crypto/evp/e_null.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,6 +20,7 @@ static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static const EVP_CIPHER n_cipher = { NID_undef, 1, 0, 0, 0, + EVP_ORIG_GLOBAL, null_init_key, null_cipher, NULL, diff --git a/crypto/openssl/crypto/evp/e_old.c b/crypto/openssl/crypto/evp/e_old.c index 927908f87176..e9c9f22119bf 100644 --- a/crypto/openssl/crypto/evp/e_old.c +++ b/crypto/openssl/crypto/evp/e_old.c @@ -1,18 +1,15 @@ /* - * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include -#if OPENSSL_API_COMPAT >= 0x00908000L -NON_EMPTY_TRANSLATION_UNIT -#else -# include +#include /* * Define some deprecated functions, so older programs don't crash and burn @@ -21,93 +18,91 @@ NON_EMPTY_TRANSLATION_UNIT * location, not by name. */ -# ifndef OPENSSL_NO_BF -# undef EVP_bf_cfb +#ifndef OPENSSL_NO_BF +# undef EVP_bf_cfb const EVP_CIPHER *EVP_bf_cfb(void); const EVP_CIPHER *EVP_bf_cfb(void) { return EVP_bf_cfb64(); } -# endif +#endif -# ifndef OPENSSL_NO_DES -# undef EVP_des_cfb +#ifndef OPENSSL_NO_DES +# undef EVP_des_cfb const EVP_CIPHER *EVP_des_cfb(void); const EVP_CIPHER *EVP_des_cfb(void) { return EVP_des_cfb64(); } -# undef EVP_des_ede3_cfb +# undef EVP_des_ede3_cfb const EVP_CIPHER *EVP_des_ede3_cfb(void); const EVP_CIPHER *EVP_des_ede3_cfb(void) { return EVP_des_ede3_cfb64(); } -# undef EVP_des_ede_cfb +# undef EVP_des_ede_cfb const EVP_CIPHER *EVP_des_ede_cfb(void); const EVP_CIPHER *EVP_des_ede_cfb(void) { return EVP_des_ede_cfb64(); } -# endif +#endif -# ifndef OPENSSL_NO_IDEA -# undef EVP_idea_cfb +#ifndef OPENSSL_NO_IDEA +# undef EVP_idea_cfb const EVP_CIPHER *EVP_idea_cfb(void); const EVP_CIPHER *EVP_idea_cfb(void) { return EVP_idea_cfb64(); } -# endif +#endif -# ifndef OPENSSL_NO_RC2 -# undef EVP_rc2_cfb +#ifndef OPENSSL_NO_RC2 +# undef EVP_rc2_cfb const EVP_CIPHER *EVP_rc2_cfb(void); const EVP_CIPHER *EVP_rc2_cfb(void) { return EVP_rc2_cfb64(); } -# endif +#endif -# ifndef OPENSSL_NO_CAST -# undef EVP_cast5_cfb +#ifndef OPENSSL_NO_CAST +# undef EVP_cast5_cfb const EVP_CIPHER *EVP_cast5_cfb(void); const EVP_CIPHER *EVP_cast5_cfb(void) { return EVP_cast5_cfb64(); } -# endif +#endif -# ifndef OPENSSL_NO_RC5 -# undef EVP_rc5_32_12_16_cfb +#ifndef OPENSSL_NO_RC5 +# undef EVP_rc5_32_12_16_cfb const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void); const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) { return EVP_rc5_32_12_16_cfb64(); } -# endif +#endif -# undef EVP_aes_128_cfb +#undef EVP_aes_128_cfb const EVP_CIPHER *EVP_aes_128_cfb(void); const EVP_CIPHER *EVP_aes_128_cfb(void) { return EVP_aes_128_cfb128(); } -# undef EVP_aes_192_cfb +#undef EVP_aes_192_cfb const EVP_CIPHER *EVP_aes_192_cfb(void); const EVP_CIPHER *EVP_aes_192_cfb(void) { return EVP_aes_192_cfb128(); } -# undef EVP_aes_256_cfb +#undef EVP_aes_256_cfb const EVP_CIPHER *EVP_aes_256_cfb(void); const EVP_CIPHER *EVP_aes_256_cfb(void) { return EVP_aes_256_cfb128(); } - -#endif diff --git a/crypto/openssl/crypto/evp/e_rc2.c b/crypto/openssl/crypto/evp/e_rc2.c index 4d8a0ee4b015..ffeb17fb1e5a 100644 --- a/crypto/openssl/crypto/evp/e_rc2.c +++ b/crypto/openssl/crypto/evp/e_rc2.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" @@ -16,6 +22,7 @@ # include # include "crypto/evp.h" # include +# include "evp_local.h" static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); @@ -46,6 +53,7 @@ static const EVP_CIPHER r2_64_cbc_cipher = { NID_rc2_64_cbc, 8, 8 /* 64 bit */ , 8, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + EVP_ORIG_GLOBAL, rc2_init_key, rc2_cbc_cipher, NULL, @@ -60,6 +68,7 @@ static const EVP_CIPHER r2_40_cbc_cipher = { NID_rc2_40_cbc, 8, 5 /* 40 bit */ , 8, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + EVP_ORIG_GLOBAL, rc2_init_key, rc2_cbc_cipher, NULL, @@ -83,7 +92,7 @@ const EVP_CIPHER *EVP_rc2_40_cbc(void) static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), + RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_get_key_length(ctx), key, data(ctx)->key_bits); return 1; } @@ -113,7 +122,7 @@ static int rc2_magic_to_meth(int i) else if (i == RC2_40_MAGIC) return 40; else { - EVPerr(EVP_F_RC2_MAGIC_TO_METH, EVP_R_UNSUPPORTED_KEY_SIZE); + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_SIZE); return 0; } } @@ -127,7 +136,7 @@ static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) unsigned char iv[EVP_MAX_IV_LENGTH]; if (type != NULL) { - l = EVP_CIPHER_CTX_iv_length(c); + l = EVP_CIPHER_CTX_get_iv_length(c); OPENSSL_assert(l <= sizeof(iv)); i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l); if (i != (int)l) @@ -152,10 +161,8 @@ static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) if (type != NULL) { num = rc2_meth_to_magic(c); - j = EVP_CIPHER_CTX_iv_length(c); - i = ASN1_TYPE_set_int_octetstring(type, num, - (unsigned char *)EVP_CIPHER_CTX_original_iv(c), - j); + j = EVP_CIPHER_CTX_get_iv_length(c); + i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j); } return i; } @@ -164,7 +171,7 @@ static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { switch (type) { case EVP_CTRL_INIT: - data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8; + data(c)->key_bits = EVP_CIPHER_CTX_get_key_length(c) * 8; return 1; case EVP_CTRL_GET_RC2_KEY_BITS: diff --git a/crypto/openssl/crypto/evp/e_rc4.c b/crypto/openssl/crypto/evp/e_rc4.c index c24bc8fe5982..e22e81d46752 100644 --- a/crypto/openssl/crypto/evp/e_rc4.c +++ b/crypto/openssl/crypto/evp/e_rc4.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC4 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" @@ -32,6 +38,7 @@ static const EVP_CIPHER r4_cipher = { NID_rc4, 1, EVP_RC4_KEY_SIZE, 0, EVP_CIPH_VARIABLE_LENGTH, + EVP_ORIG_GLOBAL, rc4_init_key, rc4_cipher, NULL, @@ -46,6 +53,7 @@ static const EVP_CIPHER r4_40_cipher = { NID_rc4_40, 1, 5 /* 40 bit */ , 0, EVP_CIPH_VARIABLE_LENGTH, + EVP_ORIG_GLOBAL, rc4_init_key, rc4_cipher, NULL, @@ -69,7 +77,11 @@ const EVP_CIPHER *EVP_rc4_40(void) static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - RC4_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + int keylen; + + if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) <= 0) + return 0; + RC4_set_key(&data(ctx)->ks, keylen, key); return 1; } diff --git a/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c b/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c index 201ce443435c..183ecefcec65 100644 --- a/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c +++ b/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c @@ -1,12 +1,19 @@ /* - * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * MD5 and RC4 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include "internal/cryptlib.h" #include #include @@ -39,8 +46,12 @@ static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *iv, int enc) { EVP_RC4_HMAC_MD5 *key = data(ctx); + const int keylen = EVP_CIPHER_CTX_get_key_length(ctx); + + if (keylen <= 0) + return 0; - RC4_set_key(&key->ks, EVP_CIPHER_CTX_key_length(ctx), inkey); + RC4_set_key(&key->ks, keylen, inkey); MD5_Init(&key->head); /* handy when benchmarking */ key->tail = key->head; @@ -51,7 +62,7 @@ static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx, return 1; } -# if defined(RC4_ASM) && defined(MD5_ASM) && ( \ +# if defined(RC4_ASM) && defined(MD5_ASM) && ( \ defined(__x86_64) || defined(__x86_64__) || \ defined(_M_AMD64) || defined(_M_X64) ) # define STITCHED_CALL @@ -71,14 +82,13 @@ static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * rc4_md5-x86_64.pl */ md5_off = MD5_CBLOCK - key->md.num, blocks; unsigned int l; - extern unsigned int OPENSSL_ia32cap_P[]; # endif size_t plen = key->payload_length; if (plen != NO_PAYLOAD_LENGTH && len != (plen + MD5_DIGEST_LENGTH)) return 0; - if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (plen == NO_PAYLOAD_LENGTH) plen = len; # if defined(STITCHED_CALL) @@ -218,7 +228,7 @@ static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, len = p[arg - 2] << 8 | p[arg - 1]; - if (!EVP_CIPHER_CTX_encrypting(ctx)) { + if (!EVP_CIPHER_CTX_is_encrypting(ctx)) { if (len < MD5_DIGEST_LENGTH) return -1; len -= MD5_DIGEST_LENGTH; @@ -245,6 +255,7 @@ static EVP_CIPHER r4_hmac_md5_cipher = { 1, EVP_RC4_KEY_SIZE, 0, EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_FLAG_AEAD_CIPHER, + EVP_ORIG_GLOBAL, rc4_hmac_md5_init_key, rc4_hmac_md5_cipher, NULL, diff --git a/crypto/openssl/crypto/evp/e_rc5.c b/crypto/openssl/crypto/evp/e_rc5.c index c86e87b65ab4..3496a701931c 100644 --- a/crypto/openssl/crypto/evp/e_rc5.c +++ b/crypto/openssl/crypto/evp/e_rc5.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" @@ -54,7 +60,7 @@ static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 1; default: - EVPerr(EVP_F_RC5_CTRL, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS); + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS); return 0; } @@ -66,13 +72,13 @@ 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); + const int key_len = EVP_CIPHER_CTX_get_key_length(ctx); + + if (key_len > 255 || key_len < 0) { + ERR_raise(ERR_LIB_EVP, 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; + return RC5_32_set_key(&data(ctx)->ks, key_len, key, data(ctx)->rounds); } #endif diff --git a/crypto/openssl/crypto/evp/e_seed.c b/crypto/openssl/crypto/evp/e_seed.c index aeb2363beade..98c7385f61da 100644 --- a/crypto/openssl/crypto/evp/e_seed.c +++ b/crypto/openssl/crypto/evp/e_seed.c @@ -1,22 +1,26 @@ /* - * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include -#ifdef OPENSSL_NO_SEED -NON_EMPTY_TRANSLATION_UNIT -#else -# include -# include -# include -# include -# include -# include "crypto/evp.h" +#include +#include +#include +#include +#include +#include "crypto/evp.h" +#include "evp_local.h" static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); @@ -35,5 +39,3 @@ static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, SEED_set_key(key, &EVP_C_DATA(EVP_SEED_KEY,ctx)->ks); return 1; } - -#endif diff --git a/crypto/openssl/crypto/evp/e_sm4.c b/crypto/openssl/crypto/evp/e_sm4.c index fce32794fc51..abd603015c71 100644 --- a/crypto/openssl/crypto/evp/e_sm4.c +++ b/crypto/openssl/crypto/evp/e_sm4.c @@ -1,20 +1,23 @@ /* - * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 Ribose Inc. All Rights Reserved. * Ported from Ribose contributions from Botan. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" #ifndef OPENSSL_NO_SM4 # include # include # include "crypto/sm4.h" # include "crypto/evp.h" +# include "evp_local.h" typedef struct { SM4_KEY ks; @@ -23,7 +26,7 @@ typedef struct { static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - SM4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx)); + ossl_sm4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx)); return 1; } @@ -33,10 +36,10 @@ static void sm4_cbc_encrypt(const unsigned char *in, unsigned char *out, { if (enc) CRYPTO_cbc128_encrypt(in, out, len, key, ivec, - (block128_f)SM4_encrypt); + (block128_f)ossl_sm4_encrypt); else CRYPTO_cbc128_decrypt(in, out, len, key, ivec, - (block128_f)SM4_decrypt); + (block128_f)ossl_sm4_decrypt); } static void sm4_cfb128_encrypt(const unsigned char *in, unsigned char *out, @@ -44,16 +47,16 @@ static void sm4_cfb128_encrypt(const unsigned char *in, unsigned char *out, unsigned char *ivec, int *num, const int enc) { CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, - (block128_f)SM4_encrypt); + (block128_f)ossl_sm4_encrypt); } static void sm4_ecb_encrypt(const unsigned char *in, unsigned char *out, const SM4_KEY *key, const int enc) { if (enc) - SM4_encrypt(in, out, key); + ossl_sm4_encrypt(in, out, key); else - SM4_decrypt(in, out, key); + ossl_sm4_decrypt(in, out, key); } static void sm4_ofb128_encrypt(const unsigned char *in, unsigned char *out, @@ -61,7 +64,7 @@ static void sm4_ofb128_encrypt(const unsigned char *in, unsigned char *out, unsigned char *ivec, int *num) { CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, - (block128_f)SM4_encrypt); + (block128_f)ossl_sm4_encrypt); } IMPLEMENT_BLOCK_CIPHER(sm4, ks, sm4, EVP_SM4_KEY, NID_sm4, @@ -71,13 +74,17 @@ IMPLEMENT_BLOCK_CIPHER(sm4, ks, sm4, EVP_SM4_KEY, NID_sm4, static int sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - unsigned int num = EVP_CIPHER_CTX_num(ctx); + int n = EVP_CIPHER_CTX_get_num(ctx); + unsigned int num; EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx); - CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + if (n < 0) + return 0; + num = (unsigned int)n; + + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, EVP_CIPHER_CTX_buf_noconst(ctx), &num, - (block128_f)SM4_encrypt); + (block128_f)ossl_sm4_encrypt); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -85,6 +92,7 @@ static int sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static const EVP_CIPHER sm4_ctr_mode = { NID_sm4_ctr, 1, 16, 16, EVP_CIPH_CTR_MODE, + EVP_ORIG_GLOBAL, sm4_init_key, sm4_ctr_cipher, NULL, diff --git a/crypto/openssl/crypto/evp/e_xcbc_d.c b/crypto/openssl/crypto/evp/e_xcbc_d.c index b73077542264..f930941887a3 100644 --- a/crypto/openssl/crypto/evp/e_xcbc_d.c +++ b/crypto/openssl/crypto/evp/e_xcbc_d.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DES low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" @@ -16,6 +22,7 @@ # include # include "crypto/evp.h" # include +# include "evp_local.h" static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); @@ -34,6 +41,7 @@ static const EVP_CIPHER d_xcbc_cipher = { NID_desx_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, + EVP_ORIG_GLOBAL, desx_cbc_init_key, desx_cbc_cipher, NULL, @@ -66,18 +74,18 @@ static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { while (inl >= EVP_MAXCHUNK) { DES_xcbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, &data(ctx)->inw, &data(ctx)->outw, - EVP_CIPHER_CTX_encrypting(ctx)); + EVP_CIPHER_CTX_is_encrypting(ctx)); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; out += EVP_MAXCHUNK; } if (inl) DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, &data(ctx)->inw, &data(ctx)->outw, - EVP_CIPHER_CTX_encrypting(ctx)); + EVP_CIPHER_CTX_is_encrypting(ctx)); return 1; } #endif diff --git a/crypto/openssl/crypto/evp/ec_ctrl.c b/crypto/openssl/crypto/evp/ec_ctrl.c new file mode 100644 index 000000000000..404358ab97f1 --- /dev/null +++ b/crypto/openssl/crypto/evp/ec_ctrl.c @@ -0,0 +1,300 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/deprecated.h" + +#include +#include +#include +#include "crypto/evp.h" +#include "crypto/ec.h" + +/* + * This file is meant to contain functions to provide EVP_PKEY support for EC + * keys. + */ + +static ossl_inline +int evp_pkey_ctx_getset_ecdh_param_checks(const EVP_PKEY_CTX *ctx) +{ + if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not EC return error */ + if (evp_pkey_ctx_is_legacy(ctx) + && ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_EC) + return -1; + + return 1; +} + +int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx, int cofactor_mode) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx); + if (ret != 1) + return ret; + + /* + * Valid input values are: + * * 0 for disable + * * 1 for enable + * * -1 for reset to default for associated priv key + */ + if (cofactor_mode < -1 || cofactor_mode > 1) { + /* Uses the same return value of pkey_ec_ctrl() */ + return -2; + } + + *p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE, + &cofactor_mode); + *p++ = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return ret; +} + +int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx) +{ + int ret, mode; + OSSL_PARAM params[2], *p = params; + + ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx); + if (ret != 1) + return ret; + + *p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE, + &mode); + *p++ = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_get_params_strict(ctx, params); + + switch (ret) { + case -2: + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + break; + case 1: + ret = mode; + if (mode < 0 || mode > 1) { + /* + * The provider should return either 0 or 1, any other value is a + * provider error. + */ + ret = -1; + } + break; + default: + ret = -1; + break; + } + + return ret; +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_ecdh_kdf_type(EVP_PKEY_CTX *ctx, int kdf) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_get_ecdh_kdf_type(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md)); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_get_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd)); +} + +int EVP_PKEY_CTX_set_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int outlen) +{ + int ret; + size_t len = outlen; + OSSL_PARAM params[2], *p = params; + + ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx); + if (ret != 1) + return ret; + + if (outlen <= 0) { + /* + * This would ideally be -1 or 0, but we have to retain compatibility + * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if + * in <= 0 + */ + return -2; + } + + *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, + &len); + *p++ = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return ret; +} + +int EVP_PKEY_CTX_get_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen) +{ + size_t len = UINT_MAX; + int ret; + OSSL_PARAM params[2], *p = params; + + ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx); + if (ret != 1) + return ret; + + *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, + &len); + *p++ = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_get_params_strict(ctx, params); + + switch (ret) { + case -2: + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + break; + case 1: + if (len <= INT_MAX) + *plen = (int)len; + else + ret = -1; + break; + default: + ret = -1; + break; + } + + return ret; +} + +int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx); + if (ret != 1) + return ret; + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, + /* + * Cast away the const. This is read + * only so should be safe + */ + (void *)ukm, + (size_t)len); + *p++ = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); + + switch (ret) { + case -2: + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + break; + case 1: + OPENSSL_free(ukm); + break; + } + + return ret; +} + +#ifndef OPENSSL_NO_DEPRECATED_3_0 +int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm) +{ + size_t ukmlen; + int ret; + OSSL_PARAM params[2], *p = params; + + ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx); + if (ret != 1) + return ret; + + *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM, + (void **)pukm, 0); + *p++ = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_get_params_strict(ctx, params); + + switch (ret) { + case -2: + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + break; + case 1: + ret = -1; + ukmlen = params[0].return_size; + if (ukmlen <= INT_MAX) + ret = (int)ukmlen; + break; + default: + ret = -1; + break; + } + + return ret; +} +#endif + +#ifndef FIPS_MODULE +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + * ASN1_OBJECT (which would be converted to text internally)? + */ +int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_TYPE_GEN, + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, + nid, NULL); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_TYPE_GEN, + EVP_PKEY_CTRL_EC_PARAM_ENC, param_enc, NULL); +} +#endif diff --git a/crypto/openssl/crypto/evp/ec_support.c b/crypto/openssl/crypto/evp/ec_support.c new file mode 100644 index 000000000000..1ec10143d2de --- /dev/null +++ b/crypto/openssl/crypto/evp/ec_support.c @@ -0,0 +1,188 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/ec.h" +#include "internal/nelem.h" + +typedef struct ec_name2nid_st { + const char *name; + int nid; +} EC_NAME2NID; + +static const EC_NAME2NID curve_list[] = { + /* prime field curves */ + /* secg curves */ + {"secp112r1", NID_secp112r1 }, + {"secp112r2", NID_secp112r2 }, + {"secp128r1", NID_secp128r1 }, + {"secp128r2", NID_secp128r2 }, + {"secp160k1", NID_secp160k1 }, + {"secp160r1", NID_secp160r1 }, + {"secp160r2", NID_secp160r2 }, + {"secp192k1", NID_secp192k1 }, + {"secp224k1", NID_secp224k1 }, + {"secp224r1", NID_secp224r1 }, + {"secp256k1", NID_secp256k1 }, + {"secp384r1", NID_secp384r1 }, + {"secp521r1", NID_secp521r1 }, + /* X9.62 curves */ + {"prime192v1", NID_X9_62_prime192v1 }, + {"prime192v2", NID_X9_62_prime192v2 }, + {"prime192v3", NID_X9_62_prime192v3 }, + {"prime239v1", NID_X9_62_prime239v1 }, + {"prime239v2", NID_X9_62_prime239v2 }, + {"prime239v3", NID_X9_62_prime239v3 }, + {"prime256v1", NID_X9_62_prime256v1 }, + /* characteristic two field curves */ + /* NIST/SECG curves */ + {"sect113r1", NID_sect113r1 }, + {"sect113r2", NID_sect113r2 }, + {"sect131r1", NID_sect131r1 }, + {"sect131r2", NID_sect131r2 }, + {"sect163k1", NID_sect163k1 }, + {"sect163r1", NID_sect163r1 }, + {"sect163r2", NID_sect163r2 }, + {"sect193r1", NID_sect193r1 }, + {"sect193r2", NID_sect193r2 }, + {"sect233k1", NID_sect233k1 }, + {"sect233r1", NID_sect233r1 }, + {"sect239k1", NID_sect239k1 }, + {"sect283k1", NID_sect283k1 }, + {"sect283r1", NID_sect283r1 }, + {"sect409k1", NID_sect409k1 }, + {"sect409r1", NID_sect409r1 }, + {"sect571k1", NID_sect571k1 }, + {"sect571r1", NID_sect571r1 }, + /* X9.62 curves */ + {"c2pnb163v1", NID_X9_62_c2pnb163v1 }, + {"c2pnb163v2", NID_X9_62_c2pnb163v2 }, + {"c2pnb163v3", NID_X9_62_c2pnb163v3 }, + {"c2pnb176v1", NID_X9_62_c2pnb176v1 }, + {"c2tnb191v1", NID_X9_62_c2tnb191v1 }, + {"c2tnb191v2", NID_X9_62_c2tnb191v2 }, + {"c2tnb191v3", NID_X9_62_c2tnb191v3 }, + {"c2pnb208w1", NID_X9_62_c2pnb208w1 }, + {"c2tnb239v1", NID_X9_62_c2tnb239v1 }, + {"c2tnb239v2", NID_X9_62_c2tnb239v2 }, + {"c2tnb239v3", NID_X9_62_c2tnb239v3 }, + {"c2pnb272w1", NID_X9_62_c2pnb272w1 }, + {"c2pnb304w1", NID_X9_62_c2pnb304w1 }, + {"c2tnb359v1", NID_X9_62_c2tnb359v1 }, + {"c2pnb368w1", NID_X9_62_c2pnb368w1 }, + {"c2tnb431r1", NID_X9_62_c2tnb431r1 }, + /* + * the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves + * from X9.62] + */ + {"wap-wsg-idm-ecid-wtls1", NID_wap_wsg_idm_ecid_wtls1 }, + {"wap-wsg-idm-ecid-wtls3", NID_wap_wsg_idm_ecid_wtls3 }, + {"wap-wsg-idm-ecid-wtls4", NID_wap_wsg_idm_ecid_wtls4 }, + {"wap-wsg-idm-ecid-wtls5", NID_wap_wsg_idm_ecid_wtls5 }, + {"wap-wsg-idm-ecid-wtls6", NID_wap_wsg_idm_ecid_wtls6 }, + {"wap-wsg-idm-ecid-wtls7", NID_wap_wsg_idm_ecid_wtls7 }, + {"wap-wsg-idm-ecid-wtls8", NID_wap_wsg_idm_ecid_wtls8 }, + {"wap-wsg-idm-ecid-wtls9", NID_wap_wsg_idm_ecid_wtls9 }, + {"wap-wsg-idm-ecid-wtls10", NID_wap_wsg_idm_ecid_wtls10 }, + {"wap-wsg-idm-ecid-wtls11", NID_wap_wsg_idm_ecid_wtls11 }, + {"wap-wsg-idm-ecid-wtls12", NID_wap_wsg_idm_ecid_wtls12 }, + /* IPSec curves */ + {"Oakley-EC2N-3", NID_ipsec3 }, + {"Oakley-EC2N-4", NID_ipsec4 }, + /* brainpool curves */ + {"brainpoolP160r1", NID_brainpoolP160r1 }, + {"brainpoolP160t1", NID_brainpoolP160t1 }, + {"brainpoolP192r1", NID_brainpoolP192r1 }, + {"brainpoolP192t1", NID_brainpoolP192t1 }, + {"brainpoolP224r1", NID_brainpoolP224r1 }, + {"brainpoolP224t1", NID_brainpoolP224t1 }, + {"brainpoolP256r1", NID_brainpoolP256r1 }, + {"brainpoolP256t1", NID_brainpoolP256t1 }, + {"brainpoolP320r1", NID_brainpoolP320r1 }, + {"brainpoolP320t1", NID_brainpoolP320t1 }, + {"brainpoolP384r1", NID_brainpoolP384r1 }, + {"brainpoolP384t1", NID_brainpoolP384t1 }, + {"brainpoolP512r1", NID_brainpoolP512r1 }, + {"brainpoolP512t1", NID_brainpoolP512t1 }, + /* SM2 curve */ + {"SM2", NID_sm2 }, +}; + +const char *OSSL_EC_curve_nid2name(int nid) +{ + size_t i; + + if (nid <= 0) + return NULL; + + for (i = 0; i < OSSL_NELEM(curve_list); i++) { + if (curve_list[i].nid == nid) + return curve_list[i].name; + } + return NULL; +} + +int ossl_ec_curve_name2nid(const char *name) +{ + size_t i; + int nid; + + if (name != NULL) { + if ((nid = ossl_ec_curve_nist2nid_int(name)) != NID_undef) + return nid; + + for (i = 0; i < OSSL_NELEM(curve_list); i++) { + if (OPENSSL_strcasecmp(curve_list[i].name, name) == 0) + return curve_list[i].nid; + } + } + + return NID_undef; +} + +/* Functions to translate between common NIST curve names and NIDs */ + +static const EC_NAME2NID nist_curves[] = { + {"B-163", NID_sect163r2}, + {"B-233", NID_sect233r1}, + {"B-283", NID_sect283r1}, + {"B-409", NID_sect409r1}, + {"B-571", NID_sect571r1}, + {"K-163", NID_sect163k1}, + {"K-233", NID_sect233k1}, + {"K-283", NID_sect283k1}, + {"K-409", NID_sect409k1}, + {"K-571", NID_sect571k1}, + {"P-192", NID_X9_62_prime192v1}, + {"P-224", NID_secp224r1}, + {"P-256", NID_X9_62_prime256v1}, + {"P-384", NID_secp384r1}, + {"P-521", NID_secp521r1} +}; + +const char *ossl_ec_curve_nid2nist_int(int nid) +{ + size_t i; + for (i = 0; i < OSSL_NELEM(nist_curves); i++) { + if (nist_curves[i].nid == nid) + return nist_curves[i].name; + } + return NULL; +} + +int ossl_ec_curve_nist2nid_int(const char *name) +{ + size_t i; + for (i = 0; i < OSSL_NELEM(nist_curves); i++) { + if (strcmp(nist_curves[i].name, name) == 0) + return nist_curves[i].nid; + } + return NID_undef; +} diff --git a/crypto/openssl/crypto/evp/encode.c b/crypto/openssl/crypto/evp/encode.c index 85926434c300..2c047fa039ae 100644 --- a/crypto/openssl/crypto/evp/encode.c +++ b/crypto/openssl/crypto/evp/encode.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,8 +11,8 @@ #include #include "internal/cryptlib.h" #include -#include "evp_local.h" #include "crypto/evp.h" +#include "evp_local.h" static unsigned char conv_ascii2bin(unsigned char a, const unsigned char *table); @@ -134,7 +134,7 @@ void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) OPENSSL_free(ctx); } -int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx) +int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, const EVP_ENCODE_CTX *sctx) { memcpy(dctx, sctx, sizeof(EVP_ENCODE_CTX)); @@ -422,7 +422,7 @@ static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t, else table = data_ascii2bin; - /* trim white space from the start of the line. */ + /* trim whitespace from the start of the line. */ while ((n > 0) && (conv_ascii2bin(*f, table) == B64_WS)) { f++; n--; diff --git a/crypto/openssl/crypto/evp/evp_cnf.c b/crypto/openssl/crypto/evp/evp_cnf.c index 8df2c06e1f52..0e7fe64cf92e 100644 --- a/crypto/openssl/crypto/evp/evp_cnf.c +++ b/crypto/openssl/crypto/evp/evp_cnf.c @@ -1,7 +1,7 @@ /* - * Copyright 2012-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,6 +13,8 @@ #include #include #include +#include +#include "crypto/evp.h" /* Algorithm configuration module. */ @@ -23,27 +25,42 @@ static int alg_module_init(CONF_IMODULE *md, const CONF *cnf) STACK_OF(CONF_VALUE) *sktmp; CONF_VALUE *oval; + OSSL_TRACE2(CONF, "Loading EVP module: name %s, value %s\n", + CONF_imodule_get_name(md), CONF_imodule_get_value(md)); + oid_section = CONF_imodule_get_value(md); if ((sktmp = NCONF_get_section(cnf, oid_section)) == NULL) { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION); + ERR_raise(ERR_LIB_EVP, EVP_R_ERROR_LOADING_SECTION); return 0; } for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { oval = sk_CONF_VALUE_value(sktmp, i); if (strcmp(oval->name, "fips_mode") == 0) { int m; - if (!X509V3_get_value_bool(oval, &m)) { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE); + + /* Detailed error already reported. */ + if (!X509V3_get_value_bool(oval, &m)) + return 0; + + /* + * fips_mode is deprecated and should not be used in new + * configurations. + */ + if (!evp_default_properties_enable_fips_int( + NCONF_get0_libctx((CONF *)cnf), m > 0, 0)) { + ERR_raise(ERR_LIB_EVP, EVP_R_SET_DEFAULT_PROPERTY_FAILURE); return 0; } - if (m > 0) { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED); + } else if (strcmp(oval->name, "default_properties") == 0) { + if (!evp_set_default_properties_int(NCONF_get0_libctx((CONF *)cnf), + oval->value, 0, 0)) { + ERR_raise(ERR_LIB_EVP, EVP_R_SET_DEFAULT_PROPERTY_FAILURE); return 0; } } else { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION); - ERR_add_error_data(4, "name=", oval->name, - ", value=", oval->value); + ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_OPTION, + "name=%s, value=%s", oval->name, oval->value); + return 0; } } @@ -52,5 +69,6 @@ static int alg_module_init(CONF_IMODULE *md, const CONF *cnf) void EVP_add_alg_module(void) { + OSSL_TRACE(CONF, "Adding config module 'alg_section'\n"); CONF_module_add("alg_section", alg_module_init, 0); } diff --git a/crypto/openssl/crypto/evp/evp_enc.c b/crypto/openssl/crypto/evp/evp_enc.c index e756624b2cdf..b178d1086473 100644 --- a/crypto/openssl/crypto/evp/evp_enc.c +++ b/crypto/openssl/crypto/evp/evp_enc.c @@ -1,40 +1,68 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include -#include "internal/cryptlib.h" #include #include #include -#include -#include +#ifndef FIPS_MODULE +# include +#endif +#include +#include +#include "internal/cryptlib.h" +#include "internal/provider.h" +#include "internal/core.h" #include "crypto/evp.h" #include "evp_local.h" -int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c) +int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx) { - if (c == NULL) + if (ctx == NULL) return 1; - if (c->cipher != NULL) { - if (c->cipher->cleanup && !c->cipher->cleanup(c)) + + if (ctx->cipher == NULL || ctx->cipher->prov == NULL) + goto legacy; + + if (ctx->algctx != NULL) { + if (ctx->cipher->freectx != NULL) + ctx->cipher->freectx(ctx->algctx); + ctx->algctx = NULL; + } + if (ctx->fetched_cipher != NULL) + EVP_CIPHER_free(ctx->fetched_cipher); + memset(ctx, 0, sizeof(*ctx)); + ctx->iv_len = -1; + + return 1; + + /* Remove legacy code below when legacy support is removed. */ + legacy: + + if (ctx->cipher != NULL) { + if (ctx->cipher->cleanup && !ctx->cipher->cleanup(ctx)) return 0; /* Cleanse cipher context data */ - if (c->cipher_data && c->cipher->ctx_size) - OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size); + if (ctx->cipher_data && ctx->cipher->ctx_size) + OPENSSL_cleanse(ctx->cipher_data, ctx->cipher->ctx_size); } - OPENSSL_free(c->cipher_data); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(c->engine); + OPENSSL_free(ctx->cipher_data); +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + ENGINE_finish(ctx->engine); #endif - memset(c, 0, sizeof(*c)); + memset(ctx, 0, sizeof(*ctx)); + ctx->iv_len = -1; return 1; } @@ -45,30 +73,46 @@ EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) { + if (ctx == NULL) + return; EVP_CIPHER_CTX_reset(ctx); OPENSSL_free(ctx); } -int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - const unsigned char *key, const unsigned char *iv, int enc) +static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv, int enc, + const OSSL_PARAM params[]) { - if (cipher != NULL) - EVP_CIPHER_CTX_reset(ctx); - return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); -} + int n; +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + ENGINE *tmpimpl = NULL; +#endif -int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - ENGINE *impl, const unsigned char *key, - const unsigned char *iv, int enc) -{ - if (enc == -1) + ctx->iv_len = -1; + + /* + * enc == 1 means we are encrypting. + * enc == 0 means we are decrypting. + * enc == -1 means, use the previously initialised value for encrypt/decrypt + */ + if (enc == -1) { enc = ctx->encrypt; - else { + } else { if (enc) enc = 1; ctx->encrypt = enc; } -#ifndef OPENSSL_NO_ENGINE + + if (cipher == NULL && ctx->cipher == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); + return 0; + } + + /* Code below to be removed when legacy support is dropped. */ + +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) /* * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so * this context may already have an ENGINE! Try to avoid releasing the @@ -78,39 +122,168 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, if (ctx->engine && ctx->cipher && (cipher == NULL || cipher->nid == ctx->cipher->nid)) goto skip_to_init; + + if (cipher != NULL && impl == NULL) { + /* Ask if an ENGINE is reserved for this job */ + tmpimpl = ENGINE_get_cipher_engine(cipher->nid); + } #endif - if (cipher) { + + /* + * If there are engines involved then we should use legacy handling for now. + */ + if (ctx->engine != NULL +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + || tmpimpl != NULL +#endif + || impl != NULL + || (cipher != NULL && cipher->origin == EVP_ORIG_METH) + || (cipher == NULL && ctx->cipher != NULL + && ctx->cipher->origin == EVP_ORIG_METH)) { + if (ctx->cipher == ctx->fetched_cipher) + ctx->cipher = NULL; + EVP_CIPHER_free(ctx->fetched_cipher); + ctx->fetched_cipher = NULL; + goto legacy; + } + /* + * Ensure a context left lying around from last time is cleared + * (legacy code) + */ + if (cipher != NULL && ctx->cipher != NULL) { + if (ctx->cipher->cleanup != NULL && !ctx->cipher->cleanup(ctx)) + return 0; + OPENSSL_clear_free(ctx->cipher_data, ctx->cipher->ctx_size); + ctx->cipher_data = NULL; + } + + /* Start of non-legacy code below */ + + /* Ensure a context left lying around from last time is cleared */ + if (cipher != NULL && ctx->cipher != NULL) { + unsigned long flags = ctx->flags; + + EVP_CIPHER_CTX_reset(ctx); + /* Restore encrypt and flags */ + ctx->encrypt = enc; + ctx->flags = flags; + } + + if (cipher == NULL) + cipher = ctx->cipher; + + if (cipher->prov == NULL) { +#ifdef FIPS_MODULE + /* We only do explicit fetches inside the FIPS module */ + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; +#else + EVP_CIPHER *provciph = + EVP_CIPHER_fetch(NULL, + cipher->nid == NID_undef ? "NULL" + : OBJ_nid2sn(cipher->nid), + ""); + + if (provciph == NULL) + return 0; + cipher = provciph; + EVP_CIPHER_free(ctx->fetched_cipher); + ctx->fetched_cipher = provciph; +#endif + } + + if (cipher->prov != NULL) { + if (!EVP_CIPHER_up_ref((EVP_CIPHER *)cipher)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + EVP_CIPHER_free(ctx->fetched_cipher); + ctx->fetched_cipher = (EVP_CIPHER *)cipher; + } + ctx->cipher = cipher; + if (ctx->algctx == NULL) { + ctx->algctx = ctx->cipher->newctx(ossl_provider_ctx(cipher->prov)); + if (ctx->algctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + } + + if ((ctx->flags & EVP_CIPH_NO_PADDING) != 0) { /* - * Ensure a context left lying around from last time is cleared (the - * previous check attempted to avoid this if the same ENGINE and + * If this ctx was already set up for no padding then we need to tell + * the new cipher about it. + */ + if (!EVP_CIPHER_CTX_set_padding(ctx, 0)) + return 0; + } + + if (enc) { + if (ctx->cipher->einit == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + + return ctx->cipher->einit(ctx->algctx, + key, + key == NULL ? 0 + : EVP_CIPHER_CTX_get_key_length(ctx), + iv, + iv == NULL ? 0 + : EVP_CIPHER_CTX_get_iv_length(ctx), + params); + } + + if (ctx->cipher->dinit == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + + return ctx->cipher->dinit(ctx->algctx, + key, + key == NULL ? 0 + : EVP_CIPHER_CTX_get_key_length(ctx), + iv, + iv == NULL ? 0 + : EVP_CIPHER_CTX_get_iv_length(ctx), + params); + + /* Code below to be removed when legacy support is dropped. */ + legacy: + + if (cipher != NULL) { + /* + * Ensure a context left lying around from last time is cleared (we + * previously attempted to avoid this if the same ENGINE and * EVP_CIPHER could be used). */ - if (ctx->cipher -#ifndef OPENSSL_NO_ENGINE - || ctx->engine -#endif - || ctx->cipher_data) { + if (ctx->cipher) { unsigned long flags = ctx->flags; EVP_CIPHER_CTX_reset(ctx); /* Restore encrypt and flags */ ctx->encrypt = enc; ctx->flags = flags; } -#ifndef OPENSSL_NO_ENGINE - if (impl) { +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + if (impl != NULL) { if (!ENGINE_init(impl)) { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); return 0; } - } else - /* Ask if an ENGINE is reserved for this job */ - impl = ENGINE_get_cipher_engine(cipher->nid); - if (impl) { + } else { + impl = tmpimpl; + } + if (impl != NULL) { /* There's an ENGINE for this job ... (apparently) */ const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid); - if (!c) { - ENGINE_finish(impl); - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + + if (c == NULL) { + /* + * One positive side-effect of US's export control history, + * is that we should at least be able to avoid using US + * misspellings of "initialisation"? + */ + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); return 0; } /* We'll use the ENGINE's private cipher definition */ @@ -120,8 +293,9 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, * from an ENGINE and we need to release it when done. */ ctx->engine = impl; - } else + } else { ctx->engine = NULL; + } #endif ctx->cipher = cipher; @@ -129,7 +303,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ctx->cipher_data = OPENSSL_zalloc(ctx->cipher->ctx_size); if (ctx->cipher_data == NULL) { ctx->cipher = NULL; - EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } } else { @@ -139,32 +313,33 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, /* Preserve wrap enable flag, zero everything else */ ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW; if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL) <= 0) { ctx->cipher = NULL; - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); return 0; } } - } else if (!ctx->cipher) { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET); - return 0; } -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) skip_to_init: #endif + if (ctx->cipher == NULL) + return 0; + /* we assume block size is a power of 2 in *cryptUpdate */ OPENSSL_assert(ctx->cipher->block_size == 1 || ctx->cipher->block_size == 8 || ctx->cipher->block_size == 16); if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW) - && EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_WRAP_MODE) { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_WRAP_MODE_NOT_ALLOWED); + && EVP_CIPHER_CTX_get_mode(ctx) == EVP_CIPH_WRAP_MODE) { + ERR_raise(ERR_LIB_EVP, EVP_R_WRAP_MODE_NOT_ALLOWED); return 0; } - if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_CUSTOM_IV)) { - switch (EVP_CIPHER_CTX_mode(ctx)) { + if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) + & EVP_CIPH_CUSTOM_IV) == 0) { + switch (EVP_CIPHER_CTX_get_mode(ctx)) { case EVP_CIPH_STREAM_CIPHER: case EVP_CIPH_ECB_MODE: @@ -177,19 +352,27 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, /* fall-through */ case EVP_CIPH_CBC_MODE: - - OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= - (int)sizeof(ctx->iv)); - if (iv) - memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); - memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + n = EVP_CIPHER_CTX_get_iv_length(ctx); + if (n < 0 || n > (int)sizeof(ctx->iv)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH); + return 0; + } + if (iv != NULL) + memcpy(ctx->oiv, iv, n); + memcpy(ctx->iv, ctx->oiv, n); break; case EVP_CIPH_CTR_MODE: ctx->num = 0; /* Don't reuse IV for CTR mode */ - if (iv) - memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + if (iv != NULL) { + n = EVP_CIPHER_CTX_get_iv_length(ctx); + if (n <= 0 || n > (int)sizeof(ctx->iv)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH); + return 0; + } + memcpy(ctx->iv, iv, n); + } break; default: @@ -197,7 +380,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, } } - if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { + if (key != NULL || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { if (!ctx->cipher->init(ctx, key, iv, enc)) return 0; } @@ -207,6 +390,28 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, return 1; } +int EVP_CipherInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, + int enc, const OSSL_PARAM params[]) +{ + return evp_cipher_init_internal(ctx, cipher, NULL, key, iv, enc, params); +} + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc) +{ + if (cipher != NULL) + EVP_CIPHER_CTX_reset(ctx); + return evp_cipher_init_internal(ctx, cipher, NULL, key, iv, enc, NULL); +} + +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv, int enc) +{ + return evp_cipher_init_internal(ctx, cipher, impl, key, iv, enc, NULL); +} + int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { @@ -245,6 +450,13 @@ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); } +int EVP_EncryptInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, + const OSSL_PARAM params[]) +{ + return EVP_CipherInit_ex2(ctx, cipher, key, iv, 1, params); +} + int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv) { @@ -258,6 +470,13 @@ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); } +int EVP_DecryptInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, + const OSSL_PARAM params[]) +{ + return EVP_CipherInit_ex2(ctx, cipher, key, iv, 0, params); +} + /* * According to the letter of standard difference between pointers * is specified to be valid only within same object. This makes @@ -281,7 +500,7 @@ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, # define PTRDIFF_T size_t #endif -int is_partially_overlapping(const void *ptr1, const void *ptr2, size_t len) +int ossl_is_partially_overlapping(const void *ptr1, const void *ptr2, int len) { PTRDIFF_T diff = (PTRDIFF_T)ptr1-(PTRDIFF_T)ptr2; /* @@ -299,29 +518,17 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { - int i, j, bl; - size_t cmpl = (size_t)inl; + int i, j, bl, cmpl = inl; if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) cmpl = (cmpl + 7) / 8; bl = ctx->cipher->block_size; - /* - * CCM mode needs to know about the case where inl == 0 && in == NULL - it - * means the plaintext/ciphertext length is 0 - */ - if (inl < 0 - || (inl == 0 - && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE)) { - *outl = 0; - return inl == 0; - } - if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { /* If block size > 1 then the cipher will have to do this check */ - if (bl == 1 && is_partially_overlapping(out, in, cmpl)) { - EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); + if (bl == 1 && ossl_is_partially_overlapping(out, in, cmpl)) { + ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING); return 0; } @@ -333,8 +540,12 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx, return 1; } - if (is_partially_overlapping(out + ctx->buf_len, in, cmpl)) { - EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); + if (inl <= 0) { + *outl = 0; + return inl == 0; + } + if (ossl_is_partially_overlapping(out + ctx->buf_len, in, cmpl)) { + ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING); return 0; } @@ -366,8 +577,7 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx, * we process from ctx->buf does not exceed INT_MAX */ if (((inl - j) & ~(bl - 1)) > INT_MAX - bl) { - EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, - EVP_R_OUTPUT_WOULD_OVERFLOW); + ERR_raise(ERR_LIB_EVP, EVP_R_OUTPUT_WOULD_OVERFLOW); return 0; } memcpy(&(ctx->buf[i]), in, j); @@ -398,12 +608,55 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx, int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { + int ret; + size_t soutl, inl_ = (size_t)inl; + int blocksize; + + if (outl != NULL) { + *outl = 0; + } else { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + /* Prevent accidental use of decryption context when encrypting */ if (!ctx->encrypt) { - EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_INVALID_OPERATION); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); + return 0; + } + + if (ctx->cipher == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); + return 0; + } + + if (ctx->cipher->prov == NULL) + goto legacy; + + blocksize = ctx->cipher->block_size; + + if (ctx->cipher->cupdate == NULL || blocksize < 1) { + ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); return 0; } + ret = ctx->cipher->cupdate(ctx->algctx, out, &soutl, + inl_ + (size_t)(blocksize == 1 ? 0 : blocksize), + in, inl_); + + if (ret) { + if (soutl > INT_MAX) { + ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); + return 0; + } + *outl = soutl; + } + + return ret; + + /* Code below to be removed when legacy support is dropped. */ + legacy: + return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl); } @@ -418,13 +671,52 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { int n, ret; unsigned int i, b, bl; + size_t soutl; + int blocksize; + + if (outl != NULL) { + *outl = 0; + } else { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } /* Prevent accidental use of decryption context when encrypting */ if (!ctx->encrypt) { - EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_INVALID_OPERATION); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); return 0; } + if (ctx->cipher == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); + return 0; + } + if (ctx->cipher->prov == NULL) + goto legacy; + + blocksize = EVP_CIPHER_CTX_get_block_size(ctx); + + if (blocksize < 1 || ctx->cipher->cfinal == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + + ret = ctx->cipher->cfinal(ctx->algctx, out, &soutl, + blocksize == 1 ? 0 : blocksize); + + if (ret) { + if (soutl > INT_MAX) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + *outl = soutl; + } + + return ret; + + /* Code below to be removed when legacy support is dropped. */ + legacy: + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { ret = ctx->cipher->do_cipher(ctx, out, NULL, 0); if (ret < 0) @@ -443,8 +735,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) bl = ctx->buf_len; if (ctx->flags & EVP_CIPH_NO_PADDING) { if (bl) { - EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, - EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + ERR_raise(ERR_LIB_EVP, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); return 0; } *outl = 0; @@ -465,35 +756,62 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { - int fix_len; + int fix_len, cmpl = inl, ret; unsigned int b; - size_t cmpl = (size_t)inl; + size_t soutl, inl_ = (size_t)inl; + int blocksize; + + if (outl != NULL) { + *outl = 0; + } else { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } /* Prevent accidental use of encryption context when decrypting */ if (ctx->encrypt) { - EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_INVALID_OPERATION); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); return 0; } + if (ctx->cipher == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); + return 0; + } + if (ctx->cipher->prov == NULL) + goto legacy; + + blocksize = EVP_CIPHER_CTX_get_block_size(ctx); + + if (ctx->cipher->cupdate == NULL || blocksize < 1) { + ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); + return 0; + } + ret = ctx->cipher->cupdate(ctx->algctx, out, &soutl, + inl_ + (size_t)(blocksize == 1 ? 0 : blocksize), + in, inl_); + + if (ret) { + if (soutl > INT_MAX) { + ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); + return 0; + } + *outl = soutl; + } + + return ret; + + /* Code below to be removed when legacy support is dropped. */ + legacy: + b = ctx->cipher->block_size; if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) cmpl = (cmpl + 7) / 8; - /* - * CCM mode needs to know about the case where inl == 0 - it means the - * plaintext/ciphertext length is 0 - */ - if (inl < 0 - || (inl == 0 - && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE)) { - *outl = 0; - return inl == 0; - } - if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { - if (b == 1 && is_partially_overlapping(out, in, cmpl)) { - EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); + if (b == 1 && ossl_is_partially_overlapping(out, in, cmpl)) { + ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING); return 0; } @@ -506,6 +824,11 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, return 1; } + if (inl <= 0) { + *outl = 0; + return inl == 0; + } + if (ctx->flags & EVP_CIPH_NO_PADDING) return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl); @@ -514,8 +837,8 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, if (ctx->final_used) { /* see comment about PTRDIFF_T comparison above */ if (((PTRDIFF_T)out == (PTRDIFF_T)in) - || is_partially_overlapping(out, in, b)) { - EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); + || ossl_is_partially_overlapping(out, in, b)) { + ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING); return 0; } /* @@ -528,7 +851,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, * This must never exceed INT_MAX */ if ((inl & ~(b - 1)) > INT_MAX - b) { - EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_OUTPUT_WOULD_OVERFLOW); + ERR_raise(ERR_LIB_EVP, EVP_R_OUTPUT_WOULD_OVERFLOW); return 0; } memcpy(out, ctx->final, b); @@ -568,15 +891,55 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { int i, n; unsigned int b; + size_t soutl; + int ret; + int blocksize; + + if (outl != NULL) { + *outl = 0; + } else { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } /* Prevent accidental use of encryption context when decrypting */ if (ctx->encrypt) { - EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_INVALID_OPERATION); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); return 0; } - *outl = 0; + if (ctx->cipher == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); + return 0; + } + + if (ctx->cipher->prov == NULL) + goto legacy; + + blocksize = EVP_CIPHER_CTX_get_block_size(ctx); + + if (blocksize < 1 || ctx->cipher->cfinal == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + ret = ctx->cipher->cfinal(ctx->algctx, out, &soutl, + blocksize == 1 ? 0 : blocksize); + + if (ret) { + if (soutl > INT_MAX) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + *outl = soutl; + } + + return ret; + + /* Code below to be removed when legacy support is dropped. */ + legacy: + + *outl = 0; if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { i = ctx->cipher->do_cipher(ctx, out, NULL, 0); if (i < 0) @@ -589,8 +952,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) b = ctx->cipher->block_size; if (ctx->flags & EVP_CIPH_NO_PADDING) { if (ctx->buf_len) { - EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, - EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + ERR_raise(ERR_LIB_EVP, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); return 0; } *outl = 0; @@ -598,7 +960,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) } if (b > 1) { if (ctx->buf_len || !ctx->final_used) { - EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH); + ERR_raise(ERR_LIB_EVP, EVP_R_WRONG_FINAL_BLOCK_LENGTH); return 0; } OPENSSL_assert(b <= sizeof(ctx->final)); @@ -609,12 +971,12 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) */ n = ctx->final[b - 1]; if (n == 0 || n > (int)b) { - EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); + ERR_raise(ERR_LIB_EVP, EVP_R_BAD_DECRYPT); return 0; } for (i = 0; i < n; i++) { if (ctx->final[--b] != n) { - EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); + ERR_raise(ERR_LIB_EVP, EVP_R_BAD_DECRYPT); return 0; } } @@ -629,69 +991,420 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) { + if (c->cipher->prov != NULL) { + int ok; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t len = keylen; + + if (EVP_CIPHER_CTX_get_key_length(c) == keylen) + return 1; + + /* Check the cipher actually understands this parameter */ + if (OSSL_PARAM_locate_const(EVP_CIPHER_settable_ctx_params(c->cipher), + OSSL_CIPHER_PARAM_KEYLEN) == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH); + return 0; + } + + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len); + ok = evp_do_ciph_ctx_setparams(c->cipher, c->algctx, params); + + return ok > 0 ? 1 : 0; + } + + /* Code below to be removed when legacy support is dropped. */ + + /* + * Note there have never been any built-in ciphers that define this flag + * since it was first introduced. + */ if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL); - if (c->key_len == keylen) + if (EVP_CIPHER_CTX_get_key_length(c) == keylen) return 1; if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { c->key_len = keylen; return 1; } - EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, EVP_R_INVALID_KEY_LENGTH); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH); return 0; } int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) { + int ok; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + unsigned int pd = pad; + if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING; else ctx->flags |= EVP_CIPH_NO_PADDING; - return 1; + + if (ctx->cipher != NULL && ctx->cipher->prov == NULL) + return 1; + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pd); + ok = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); + + return ok != 0; } int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) { - int ret; - - if (!ctx->cipher) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET); + int ret = EVP_CTRL_RET_UNSUPPORTED; + int set_params = 1; + size_t sz = arg; + unsigned int i; + OSSL_PARAM params[4] = { + OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END + }; + + if (ctx == NULL || ctx->cipher == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); return 0; } - if (!ctx->cipher->ctrl) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED); + if (ctx->cipher->prov == NULL) + goto legacy; + + switch (type) { + case EVP_CTRL_SET_KEY_LENGTH: + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &sz); + break; + case EVP_CTRL_RAND_KEY: /* Used by DES */ + set_params = 0; + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, + ptr, sz); + break; + + case EVP_CTRL_INIT: + /* + * EVP_CTRL_INIT is purely legacy, no provider counterpart. + * As a matter of fact, this should be dead code, but some caller + * might still do a direct control call with this command, so... + * Legacy methods return 1 except for exceptional circumstances, so + * we do the same here to not be disruptive. + */ + return 1; + case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: /* Used by DASYNC */ + default: + goto end; + case EVP_CTRL_AEAD_SET_IVLEN: + if (arg < 0) + return 0; + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &sz); + ctx->iv_len = -1; + break; + case EVP_CTRL_CCM_SET_L: + if (arg < 2 || arg > 8) + return 0; + sz = 15 - arg; + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &sz); + ctx->iv_len = -1; + break; + case EVP_CTRL_AEAD_SET_IV_FIXED: + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, ptr, sz); + break; + case EVP_CTRL_GCM_IV_GEN: + set_params = 0; + if (arg < 0) + sz = 0; /* special case that uses the iv length */ + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, ptr, sz); + break; + case EVP_CTRL_GCM_SET_IV_INV: + if (arg < 0) + return 0; + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, ptr, sz); + break; + case EVP_CTRL_GET_RC5_ROUNDS: + set_params = 0; /* Fall thru */ + case EVP_CTRL_SET_RC5_ROUNDS: + if (arg < 0) + return 0; + i = (unsigned int)arg; + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_ROUNDS, &i); + break; + case EVP_CTRL_SET_SPEED: + if (arg < 0) + return 0; + i = (unsigned int)arg; + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_SPEED, &i); + break; + case EVP_CTRL_AEAD_GET_TAG: + set_params = 0; /* Fall thru */ + case EVP_CTRL_AEAD_SET_TAG: + params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, + ptr, sz); + break; + case EVP_CTRL_AEAD_TLS1_AAD: + /* This one does a set and a get - since it returns a size */ + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, + ptr, sz); + ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); + if (ret <= 0) + goto end; + params[0] = + OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, &sz); + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + if (ret <= 0) + goto end; + return sz; +#ifndef OPENSSL_NO_RC2 + case EVP_CTRL_GET_RC2_KEY_BITS: + set_params = 0; /* Fall thru */ + case EVP_CTRL_SET_RC2_KEY_BITS: + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, &sz); + break; +#endif /* OPENSSL_NO_RC2 */ +#if !defined(OPENSSL_NO_MULTIBLOCK) + case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE: + params[0] = OSSL_PARAM_construct_size_t( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT, &sz); + ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); + if (ret <= 0) + return 0; + + params[0] = OSSL_PARAM_construct_size_t( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE, &sz); + params[1] = OSSL_PARAM_construct_end(); + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + if (ret <= 0) + return 0; + return sz; + case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD: { + EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *p = + (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *)ptr; + + if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM)) + return 0; + + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD, (void*)p->inp, p->len); + params[1] = OSSL_PARAM_construct_uint( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave); + ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); + if (ret <= 0) + return ret; + /* Retrieve the return values changed by the set */ + params[0] = OSSL_PARAM_construct_size_t( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN, &sz); + params[1] = OSSL_PARAM_construct_uint( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave); + params[2] = OSSL_PARAM_construct_end(); + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + if (ret <= 0) + return 0; + return sz; + } + case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT: { + EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *p = + (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *)ptr; + + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC, p->out, p->len); + + params[1] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN, (void*)p->inp, + p->len); + params[2] = OSSL_PARAM_construct_uint( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave); + ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); + if (ret <= 0) + return ret; + params[0] = OSSL_PARAM_construct_size_t( + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN, &sz); + params[1] = OSSL_PARAM_construct_end(); + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + if (ret <= 0) + return 0; + return sz; + } +#endif /* OPENSSL_NO_MULTIBLOCK */ + case EVP_CTRL_AEAD_SET_MAC_KEY: + if (arg < 0) + return -1; + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_AEAD_MAC_KEY, ptr, sz); + break; + } + + if (set_params) + ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); + else + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + goto end; + + /* Code below to be removed when legacy support is dropped. */ +legacy: + if (ctx->cipher->ctrl == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED); return 0; } ret = ctx->cipher->ctrl(ctx, type, arg, ptr); - if (ret == -1) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, - EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); + + end: + if (ret == EVP_CTRL_RET_UNSUPPORTED) { + ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); return 0; } return ret; } +int EVP_CIPHER_get_params(EVP_CIPHER *cipher, OSSL_PARAM params[]) +{ + if (cipher != NULL && cipher->get_params != NULL) + return cipher->get_params(params); + return 0; +} + +int EVP_CIPHER_CTX_set_params(EVP_CIPHER_CTX *ctx, const OSSL_PARAM params[]) +{ + if (ctx->cipher != NULL && ctx->cipher->set_ctx_params != NULL) { + ctx->iv_len = -1; + return ctx->cipher->set_ctx_params(ctx->algctx, params); + } + return 0; +} + +int EVP_CIPHER_CTX_get_params(EVP_CIPHER_CTX *ctx, OSSL_PARAM params[]) +{ + if (ctx->cipher != NULL && ctx->cipher->get_ctx_params != NULL) + return ctx->cipher->get_ctx_params(ctx->algctx, params); + return 0; +} + +const OSSL_PARAM *EVP_CIPHER_gettable_params(const EVP_CIPHER *cipher) +{ + if (cipher != NULL && cipher->gettable_params != NULL) + return cipher->gettable_params( + ossl_provider_ctx(EVP_CIPHER_get0_provider(cipher))); + return NULL; +} + +const OSSL_PARAM *EVP_CIPHER_settable_ctx_params(const EVP_CIPHER *cipher) +{ + void *provctx; + + if (cipher != NULL && cipher->settable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_CIPHER_get0_provider(cipher)); + return cipher->settable_ctx_params(NULL, provctx); + } + return NULL; +} + +const OSSL_PARAM *EVP_CIPHER_gettable_ctx_params(const EVP_CIPHER *cipher) +{ + void *provctx; + + if (cipher != NULL && cipher->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_CIPHER_get0_provider(cipher)); + return cipher->gettable_ctx_params(NULL, provctx); + } + return NULL; +} + +const OSSL_PARAM *EVP_CIPHER_CTX_settable_params(EVP_CIPHER_CTX *cctx) +{ + void *alg; + + if (cctx != NULL && cctx->cipher->settable_ctx_params != NULL) { + alg = ossl_provider_ctx(EVP_CIPHER_get0_provider(cctx->cipher)); + return cctx->cipher->settable_ctx_params(cctx->algctx, alg); + } + return NULL; +} + +const OSSL_PARAM *EVP_CIPHER_CTX_gettable_params(EVP_CIPHER_CTX *cctx) +{ + void *provctx; + + if (cctx != NULL && cctx->cipher->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_CIPHER_get0_provider(cctx->cipher)); + return cctx->cipher->gettable_ctx_params(cctx->algctx, provctx); + } + return NULL; +} + +#ifndef FIPS_MODULE +static OSSL_LIB_CTX *EVP_CIPHER_CTX_get_libctx(EVP_CIPHER_CTX *ctx) +{ + const EVP_CIPHER *cipher = ctx->cipher; + const OSSL_PROVIDER *prov; + + if (cipher == NULL) + return NULL; + + prov = EVP_CIPHER_get0_provider(cipher); + return ossl_provider_libctx(prov); +} +#endif + int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) { if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); - if (RAND_priv_bytes(key, ctx->key_len) <= 0) - return 0; - return 1; + +#ifdef FIPS_MODULE + return 0; +#else + { + int kl; + OSSL_LIB_CTX *libctx = EVP_CIPHER_CTX_get_libctx(ctx); + + kl = EVP_CIPHER_CTX_get_key_length(ctx); + if (kl <= 0 || RAND_priv_bytes_ex(libctx, key, kl, 0) <= 0) + return 0; + return 1; + } +#endif /* FIPS_MODULE */ } int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { if ((in == NULL) || (in->cipher == NULL)) { - EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INPUT_NOT_INITIALIZED); + ERR_raise(ERR_LIB_EVP, EVP_R_INPUT_NOT_INITIALIZED); return 0; } -#ifndef OPENSSL_NO_ENGINE + + if (in->cipher->prov == NULL) + goto legacy; + + if (in->cipher->dupctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX); + return 0; + } + + EVP_CIPHER_CTX_reset(out); + + *out = *in; + out->algctx = NULL; + + if (in->fetched_cipher != NULL && !EVP_CIPHER_up_ref(in->fetched_cipher)) { + out->fetched_cipher = NULL; + return 0; + } + + out->algctx = in->cipher->dupctx(in->algctx); + if (out->algctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX); + return 0; + } + + return 1; + + /* Code below to be removed when legacy support is dropped. */ + legacy: + +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) /* Make sure it's safe to copy a cipher context using an ENGINE */ if (in->engine && !ENGINE_init(in->engine)) { - EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_EVP, ERR_R_ENGINE_LIB); return 0; } #endif @@ -703,7 +1416,7 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); if (out->cipher_data == NULL) { out->cipher = NULL; - EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); @@ -712,8 +1425,253 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) { out->cipher = NULL; - EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INITIALIZATION_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); return 0; } return 1; } + +EVP_CIPHER *evp_cipher_new(void) +{ + EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER)); + + if (cipher != NULL) { + cipher->lock = CRYPTO_THREAD_lock_new(); + if (cipher->lock == NULL) { + OPENSSL_free(cipher); + return NULL; + } + cipher->refcnt = 1; + } + return cipher; +} + +/* + * FIPS module note: since internal fetches will be entirely + * provider based, we know that none of its code depends on legacy + * NIDs or any functionality that use them. + */ +#ifndef FIPS_MODULE +/* After removal of legacy support get rid of the need for legacy NIDs */ +static void set_legacy_nid(const char *name, void *vlegacy_nid) +{ + int nid; + int *legacy_nid = vlegacy_nid; + /* + * We use lowest level function to get the associated method, because + * higher level functions such as EVP_get_cipherbyname() have changed + * to look at providers too. + */ + const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); + + if (*legacy_nid == -1) /* We found a clash already */ + return; + if (legacy_method == NULL) + return; + nid = EVP_CIPHER_get_nid(legacy_method); + if (*legacy_nid != NID_undef && *legacy_nid != nid) { + *legacy_nid = -1; + return; + } + *legacy_nid = nid; +} +#endif + +static void *evp_cipher_from_algorithm(const int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + const OSSL_DISPATCH *fns = algodef->implementation; + EVP_CIPHER *cipher = NULL; + int fnciphcnt = 0, fnctxcnt = 0; + + if ((cipher = evp_cipher_new()) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + +#ifndef FIPS_MODULE + cipher->nid = NID_undef; + if (!evp_names_do_all(prov, name_id, set_legacy_nid, &cipher->nid) + || cipher->nid == -1) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + EVP_CIPHER_free(cipher); + return NULL; + } +#endif + + cipher->name_id = name_id; + if ((cipher->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { + EVP_CIPHER_free(cipher); + return NULL; + } + cipher->description = algodef->algorithm_description; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_CIPHER_NEWCTX: + if (cipher->newctx != NULL) + break; + cipher->newctx = OSSL_FUNC_cipher_newctx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_CIPHER_ENCRYPT_INIT: + if (cipher->einit != NULL) + break; + cipher->einit = OSSL_FUNC_cipher_encrypt_init(fns); + fnciphcnt++; + break; + case OSSL_FUNC_CIPHER_DECRYPT_INIT: + if (cipher->dinit != NULL) + break; + cipher->dinit = OSSL_FUNC_cipher_decrypt_init(fns); + fnciphcnt++; + break; + case OSSL_FUNC_CIPHER_UPDATE: + if (cipher->cupdate != NULL) + break; + cipher->cupdate = OSSL_FUNC_cipher_update(fns); + fnciphcnt++; + break; + case OSSL_FUNC_CIPHER_FINAL: + if (cipher->cfinal != NULL) + break; + cipher->cfinal = OSSL_FUNC_cipher_final(fns); + fnciphcnt++; + break; + case OSSL_FUNC_CIPHER_CIPHER: + if (cipher->ccipher != NULL) + break; + cipher->ccipher = OSSL_FUNC_cipher_cipher(fns); + break; + case OSSL_FUNC_CIPHER_FREECTX: + if (cipher->freectx != NULL) + break; + cipher->freectx = OSSL_FUNC_cipher_freectx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_CIPHER_DUPCTX: + if (cipher->dupctx != NULL) + break; + cipher->dupctx = OSSL_FUNC_cipher_dupctx(fns); + break; + case OSSL_FUNC_CIPHER_GET_PARAMS: + if (cipher->get_params != NULL) + break; + cipher->get_params = OSSL_FUNC_cipher_get_params(fns); + break; + case OSSL_FUNC_CIPHER_GET_CTX_PARAMS: + if (cipher->get_ctx_params != NULL) + break; + cipher->get_ctx_params = OSSL_FUNC_cipher_get_ctx_params(fns); + break; + case OSSL_FUNC_CIPHER_SET_CTX_PARAMS: + if (cipher->set_ctx_params != NULL) + break; + cipher->set_ctx_params = OSSL_FUNC_cipher_set_ctx_params(fns); + break; + case OSSL_FUNC_CIPHER_GETTABLE_PARAMS: + if (cipher->gettable_params != NULL) + break; + cipher->gettable_params = OSSL_FUNC_cipher_gettable_params(fns); + break; + case OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS: + if (cipher->gettable_ctx_params != NULL) + break; + cipher->gettable_ctx_params = + OSSL_FUNC_cipher_gettable_ctx_params(fns); + break; + case OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS: + if (cipher->settable_ctx_params != NULL) + break; + cipher->settable_ctx_params = + OSSL_FUNC_cipher_settable_ctx_params(fns); + break; + } + } + if ((fnciphcnt != 0 && fnciphcnt != 3 && fnciphcnt != 4) + || (fnciphcnt == 0 && cipher->ccipher == NULL) + || fnctxcnt != 2) { + /* + * In order to be a consistent set of functions we must have at least + * a complete set of "encrypt" functions, or a complete set of "decrypt" + * functions, or a single "cipher" function. In all cases we need both + * the "newctx" and "freectx" functions. + */ + EVP_CIPHER_free(cipher); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + cipher->prov = prov; + if (prov != NULL) + ossl_provider_up_ref(prov); + + if (!evp_cipher_cache_constants(cipher)) { + EVP_CIPHER_free(cipher); + ERR_raise(ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED); + cipher = NULL; + } + + return cipher; +} + +static int evp_cipher_up_ref(void *cipher) +{ + return EVP_CIPHER_up_ref(cipher); +} + +static void evp_cipher_free(void *cipher) +{ + EVP_CIPHER_free(cipher); +} + +EVP_CIPHER *EVP_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties) +{ + EVP_CIPHER *cipher = + evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties, + evp_cipher_from_algorithm, evp_cipher_up_ref, + evp_cipher_free); + + return cipher; +} + +int EVP_CIPHER_up_ref(EVP_CIPHER *cipher) +{ + int ref = 0; + + if (cipher->origin == EVP_ORIG_DYNAMIC) + CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock); + return 1; +} + +void evp_cipher_free_int(EVP_CIPHER *cipher) +{ + OPENSSL_free(cipher->type_name); + ossl_provider_free(cipher->prov); + CRYPTO_THREAD_lock_free(cipher->lock); + OPENSSL_free(cipher); +} + +void EVP_CIPHER_free(EVP_CIPHER *cipher) +{ + int i; + + if (cipher == NULL || cipher->origin != EVP_ORIG_DYNAMIC) + return; + + CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock); + if (i > 0) + return; + evp_cipher_free_int(cipher); +} + +void EVP_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_CIPHER *mac, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_CIPHER, + (void (*)(void *, void *))fn, arg, + evp_cipher_from_algorithm, evp_cipher_up_ref, + evp_cipher_free); +} diff --git a/crypto/openssl/crypto/evp/evp_err.c b/crypto/openssl/crypto/evp/evp_err.c index 32ac0125de24..c0d92321032f 100644 --- a/crypto/openssl/crypto/evp/evp_err.c +++ b/crypto/openssl/crypto/evp/evp_err.c @@ -2,7 +2,7 @@ * Generated by util/mkerr.pl DO NOT EDIT * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,170 +10,35 @@ #include #include +#include "crypto/evperr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA EVP_str_functs[] = { - {ERR_PACK(ERR_LIB_EVP, EVP_F_AESNI_INIT_KEY, 0), "aesni_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AESNI_XTS_INIT_KEY, 0), "aesni_xts_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_GCM_CTRL, 0), "aes_gcm_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_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"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_GCM_INIT_KEY, 0), "aria_gcm_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_INIT_KEY, 0), "aria_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_B64_NEW, 0), "b64_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_CAMELLIA_INIT_KEY, 0), "camellia_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_CHACHA20_POLY1305_CTRL, 0), - "chacha20_poly1305_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_CMLL_T4_INIT_KEY, 0), "cmll_t4_init_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_DES_EDE3_WRAP_CIPHER, 0), - "des_ede3_wrap_cipher"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_DO_SIGVER_INIT, 0), "do_sigver_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_ENC_NEW, 0), "enc_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHERINIT_EX, 0), "EVP_CipherInit_ex"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_ASN1_TO_PARAM, 0), - "EVP_CIPHER_asn1_to_param"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_COPY, 0), - "EVP_CIPHER_CTX_copy"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_CTRL, 0), - "EVP_CIPHER_CTX_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, 0), - "EVP_CIPHER_CTX_set_key_length"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_PARAM_TO_ASN1, 0), - "EVP_CIPHER_param_to_asn1"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, 0), - "EVP_DecryptFinal_ex"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTUPDATE, 0), "EVP_DecryptUpdate"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTFINALXOF, 0), "EVP_DigestFinalXOF"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTINIT_EX, 0), "EVP_DigestInit_ex"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTDECRYPTUPDATE, 0), - "evp_EncryptDecryptUpdate"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0), - "EVP_EncryptFinal_ex"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_CTX_COPY_EX, 0), "EVP_MD_CTX_copy_ex"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_SIZE, 0), "EVP_MD_size"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_OPENINIT, 0), "EVP_OpenInit"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_ALG_ADD, 0), "EVP_PBE_alg_add"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_ALG_ADD_TYPE, 0), - "EVP_PBE_alg_add_type"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_CIPHERINIT, 0), "EVP_PBE_CipherInit"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_SCRYPT, 0), "EVP_PBE_scrypt"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKCS82PKEY, 0), "EVP_PKCS82PKEY"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY2PKCS8, 0), "EVP_PKEY2PKCS8"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ASN1_ADD0, 0), "EVP_PKEY_asn1_add0"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CHECK, 0), "EVP_PKEY_check"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_COPY_PARAMETERS, 0), - "EVP_PKEY_copy_parameters"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, 0), "EVP_PKEY_CTX_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL_STR, 0), - "EVP_PKEY_CTX_ctrl_str"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_DUP, 0), "EVP_PKEY_CTX_dup"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_MD, 0), "EVP_PKEY_CTX_md"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT, 0), "EVP_PKEY_decrypt"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT_INIT, 0), - "EVP_PKEY_decrypt_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT_OLD, 0), - "EVP_PKEY_decrypt_old"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE, 0), "EVP_PKEY_derive"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_INIT, 0), - "EVP_PKEY_derive_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_SET_PEER, 0), - "EVP_PKEY_derive_set_peer"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT, 0), "EVP_PKEY_encrypt"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT_INIT, 0), - "EVP_PKEY_encrypt_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT_OLD, 0), - "EVP_PKEY_encrypt_old"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_DH, 0), "EVP_PKEY_get0_DH"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_DSA, 0), "EVP_PKEY_get0_DSA"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_EC_KEY, 0), - "EVP_PKEY_get0_EC_KEY"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_HMAC, 0), "EVP_PKEY_get0_hmac"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_POLY1305, 0), - "EVP_PKEY_get0_poly1305"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_RSA, 0), "EVP_PKEY_get0_RSA"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_SIPHASH, 0), - "EVP_PKEY_get0_siphash"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, 0), - "EVP_PKEY_get_raw_private_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, 0), - "EVP_PKEY_get_raw_public_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN, 0), "EVP_PKEY_keygen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN_INIT, 0), - "EVP_PKEY_keygen_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_METH_ADD0, 0), "EVP_PKEY_meth_add0"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_METH_NEW, 0), "EVP_PKEY_meth_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW, 0), "EVP_PKEY_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_CMAC_KEY, 0), - "EVP_PKEY_new_CMAC_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, 0), - "EVP_PKEY_new_raw_private_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, 0), - "EVP_PKEY_new_raw_public_key"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN, 0), "EVP_PKEY_paramgen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN_INIT, 0), - "EVP_PKEY_paramgen_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAM_CHECK, 0), - "EVP_PKEY_param_check"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PUBLIC_CHECK, 0), - "EVP_PKEY_public_check"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET1_ENGINE, 0), - "EVP_PKEY_set1_engine"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET_ALIAS_TYPE, 0), - "EVP_PKEY_set_alias_type"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN, 0), "EVP_PKEY_sign"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN_INIT, 0), "EVP_PKEY_sign_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, 0), "EVP_PKEY_verify"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_INIT, 0), - "EVP_PKEY_verify_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_RECOVER, 0), - "EVP_PKEY_verify_recover"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, 0), - "EVP_PKEY_verify_recover_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_SIGNFINAL, 0), "EVP_SignFinal"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, 0), "EVP_VerifyFinal"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_INT_CTX_NEW, 0), "int_ctx_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_OK_NEW, 0), "ok_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_PBE_KEYIVGEN, 0), "PKCS5_PBE_keyivgen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_PBE_KEYIVGEN, 0), - "PKCS5_v2_PBE_keyivgen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, 0), - "PKCS5_v2_PBKDF2_keyivgen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0), - "PKCS5_v2_scrypt_keyivgen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_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} -}; - static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_AES_KEY_SETUP_FAILED), "aes key setup failed"}, {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_ALGORITHM_NAME), "bad algorithm name"}, {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_CACHE_CONSTANTS_FAILED), + "cache constants failed"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CAMELLIA_KEY_SETUP_FAILED), "camellia key setup failed"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CANNOT_GET_PARAMETERS), + "cannot get parameters"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CANNOT_SET_PARAMETERS), + "cannot set parameters"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_NOT_GCM_MODE), + "cipher not gcm mode"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_PARAMETER_ERROR), "cipher parameter error"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COMMAND_NOT_SUPPORTED), "command not supported"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CONFLICTING_ALGORITHM_NAME), + "conflicting algorithm name"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COPY_ERROR), "copy error"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CTRL_NOT_IMPLEMENTED), "ctrl not implemented"}, @@ -182,14 +47,14 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH), "data not multiple of block length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DECODE_ERROR), "decode error"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DEFAULT_QUERY_PARSE_ERROR), + "default query parse error"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_KEY_TYPES), "different key types"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_PARAMETERS), "different parameters"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_LOADING_SECTION), "error loading section"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_SETTING_FIPS_MODE), - "error setting fips mode"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_HMAC_KEY), "expecting an hmac key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_RSA_KEY), @@ -197,28 +62,49 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DSA_KEY), "expecting a dsa key"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_EC_KEY), "expecting a ec key"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_ECX_KEY), + "expecting an ecx key"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_EC_KEY), "expecting an ec key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_POLY1305_KEY), "expecting a poly1305 key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_SIPHASH_KEY), "expecting a siphash key"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FIPS_MODE_NOT_SUPPORTED), - "fips mode not supported"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FINAL_ERROR), "final error"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GENERATE_ERROR), "generate error"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GET_RAW_KEY_FAILED), "get raw key failed"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ILLEGAL_SCRYPT_PARAMETERS), "illegal scrypt parameters"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS), + "inaccessible domain parameters"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INACCESSIBLE_KEY), "inaccessible key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INITIALIZATION_ERROR), "initialization error"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INPUT_NOT_INITIALIZED), "input not initialized"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_CUSTOM_LENGTH), + "invalid custom length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_DIGEST), "invalid digest"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_FIPS_MODE), "invalid fips mode"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_IV_LENGTH), "invalid iv length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_LENGTH), "invalid length"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_NULL_ALGORITHM), + "invalid null algorithm"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYGEN_FAILURE), "keygen failure"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_PROVIDER_FUNCTIONS), + "invalid provider functions"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH), + "invalid salt length"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SECRET_LENGTH), + "invalid secret length"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SEED_LENGTH), + "invalid seed length"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_VALUE), "invalid value"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYMGMT_EXPORT_FAILURE), + "keymgmt export failure"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEY_SETUP_FAILED), "key setup failed"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_LOCKING_NOT_SUPPORTED), + "locking not supported"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MEMORY_LIMIT_EXCEEDED), "memory limit exceeded"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MESSAGE_DIGEST_IS_NULL), @@ -226,21 +112,30 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_METHOD_NOT_SUPPORTED), "method not supported"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NOT_ABLE_TO_COPY_CTX), + "not able to copy ctx"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NOT_XOF_OR_INVALID_LENGTH), "not XOF or invalid length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_CIPHER_SET), "no cipher set"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DEFAULT_DIGEST), "no default digest"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DIGEST_SET), "no digest set"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_IMPORT_FUNCTION), "no import function"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_AVAILABLE), + "no keymgmt available"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_PRESENT), "no keymgmt present"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEY_SET), "no key set"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_OPERATION_SET), "no operation set"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NULL_MAC_PKEY_CTX), "null mac pkey ctx"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ONLY_ONESHOT_SUPPORTED), "only oneshot supported"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_INITIALIZED), + "operation not initialized"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "operation not supported for this keytype"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED), - "operaton not initialized"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OUTPUT_WOULD_OVERFLOW), "output would overflow"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARAMETER_TOO_LARGE), + "parameter too large"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARTIALLY_OVERLAPPING), "partially overlapping buffers"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PBKDF2_ERROR), "pbkdf2 error"}, @@ -251,8 +146,23 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SETTING_XOF_FAILED), "setting xof failed"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SET_DEFAULT_PROPERTY_FAILURE), + "set default property failure"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_TOO_MANY_RECORDS), "too many records"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_ENABLE_LOCKING), + "unable to enable locking"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE), + "unable to get maximum request size"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_GET_RANDOM_STRENGTH), + "unable to get random strength"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_LOCK_CONTEXT), + "unable to lock context"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_SET_CALLBACKS), + "unable to set callbacks"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_CIPHER), "unknown cipher"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_DIGEST), "unknown digest"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_KEY_TYPE), "unknown key type"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_OPTION), "unknown option"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_PBE_ALGORITHM), "unknown pbe algorithm"}, @@ -265,6 +175,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { "unsupported key derivation function"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_SIZE), "unsupported key size"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_TYPE), + "unsupported key type"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS), "unsupported number of rounds"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_PRF), "unsupported prf"}, @@ -272,10 +184,13 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { "unsupported private key algorithm"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_SALT_TYPE), "unsupported salt type"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UPDATE_ERROR), "update error"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRAP_MODE_NOT_ALLOWED), "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_DATA_UNIT_IS_TOO_LARGE), + "xts data unit is too large"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DUPLICATED_KEYS), "xts duplicated keys"}, {0, NULL} @@ -283,13 +198,11 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { #endif -int ERR_load_EVP_strings(void) +int ossl_err_load_EVP_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) { - ERR_load_strings_const(EVP_str_functs); + if (ERR_reason_error_string(EVP_str_reasons[0].error) == NULL) ERR_load_strings_const(EVP_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/evp/evp_fetch.c b/crypto/openssl/crypto/evp/evp_fetch.c new file mode 100644 index 000000000000..aafd927e63f9 --- /dev/null +++ b/crypto/openssl/crypto/evp/evp_fetch.c @@ -0,0 +1,690 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/thread_once.h" +#include "internal/property.h" +#include "internal/core.h" +#include "internal/provider.h" +#include "internal/namemap.h" +#include "internal/property.h" +#include "crypto/evp.h" /* evp_local.h needs it */ +#include "evp_local.h" + +#define NAME_SEPARATOR ':' + +static void evp_method_store_free(void *vstore) +{ + ossl_method_store_free(vstore); +} + +static void *evp_method_store_new(OSSL_LIB_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + +static const OSSL_LIB_CTX_METHOD evp_method_store_method = { + /* We want evp_method_store to be cleaned up before the provider store */ + OSSL_LIB_CTX_METHOD_PRIORITY_2, + evp_method_store_new, + evp_method_store_free, +}; + +/* Data to be passed through ossl_method_construct() */ +struct evp_method_data_st { + OSSL_LIB_CTX *libctx; + int operation_id; /* For get_evp_method_from_store() */ + int name_id; /* For get_evp_method_from_store() */ + const char *names; /* For get_evp_method_from_store() */ + const char *propquery; /* For get_evp_method_from_store() */ + + OSSL_METHOD_STORE *tmp_store; /* For get_tmp_evp_method_store() */ + + unsigned int flag_construct_error_occurred : 1; + + void *(*method_from_algorithm)(int name_id, const OSSL_ALGORITHM *, + OSSL_PROVIDER *); + int (*refcnt_up_method)(void *method); + void (*destruct_method)(void *method); +}; + +/* + * Generic routines to fetch / create EVP methods with ossl_method_construct() + */ +static void *get_tmp_evp_method_store(void *data) +{ + struct evp_method_data_st *methdata = data; + + if (methdata->tmp_store == NULL) + methdata->tmp_store = ossl_method_store_new(methdata->libctx); + return methdata->tmp_store; +} + + static void dealloc_tmp_evp_method_store(void *store) +{ + if (store != NULL) + ossl_method_store_free(store); +} + +static OSSL_METHOD_STORE *get_evp_method_store(OSSL_LIB_CTX *libctx) +{ + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_EVP_METHOD_STORE_INDEX, + &evp_method_store_method); +} + +static int reserve_evp_method_store(void *store, void *data) +{ + struct evp_method_data_st *methdata = data; + + if (store == NULL + && (store = get_evp_method_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_lock_store(store); +} + +static int unreserve_evp_method_store(void *store, void *data) +{ + struct evp_method_data_st *methdata = data; + + if (store == NULL + && (store = get_evp_method_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_unlock_store(store); +} + +/* + * To identify the method in the EVP method store, we mix the name identity + * with the operation identity, under the assumption that we don't have more + * than 2^23 names or more than 2^8 operation types. + * + * The resulting identity is a 31-bit integer, composed like this: + * + * +---------23 bits--------+-8 bits-+ + * | name identity | op id | + * +------------------------+--------+ + * + * We limit this composite number to 31 bits, thus leaving the top uint32_t + * bit always zero, to avoid negative sign extension when downshifting after + * this number happens to be passed to an int (which happens as soon as it's + * passed to ossl_method_store_cache_set(), and it's in that form that it + * gets passed along to filter_on_operation_id(), defined further down. + */ +#define METHOD_ID_OPERATION_MASK 0x000000FF +#define METHOD_ID_OPERATION_MAX ((1 << 8) - 1) +#define METHOD_ID_NAME_MASK 0x7FFFFF00 +#define METHOD_ID_NAME_OFFSET 8 +#define METHOD_ID_NAME_MAX ((1 << 23) - 1) +static uint32_t evp_method_id(int name_id, unsigned int operation_id) +{ + if (!ossl_assert(name_id > 0 && name_id <= METHOD_ID_NAME_MAX) + || !ossl_assert(operation_id > 0 + && operation_id <= METHOD_ID_OPERATION_MAX)) + return 0; + return (((name_id << METHOD_ID_NAME_OFFSET) & METHOD_ID_NAME_MASK) + | (operation_id & METHOD_ID_OPERATION_MASK)); +} + +static void *get_evp_method_from_store(void *store, const OSSL_PROVIDER **prov, + void *data) +{ + struct evp_method_data_st *methdata = data; + void *method = NULL; + int name_id = 0; + uint32_t meth_id; + + /* + * get_evp_method_from_store() is only called to try and get the method + * that evp_generic_fetch() is asking for, and the operation id as well + * as the name or name id are passed via methdata. + */ + if ((name_id = methdata->name_id) == 0 && methdata->names != NULL) { + OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx); + const char *names = methdata->names; + const char *q = strchr(names, NAME_SEPARATOR); + size_t l = (q == NULL ? strlen(names) : (size_t)(q - names)); + + if (namemap == 0) + return NULL; + name_id = ossl_namemap_name2num_n(namemap, names, l); + } + + if (name_id == 0 + || (meth_id = evp_method_id(name_id, methdata->operation_id)) == 0) + return NULL; + + if (store == NULL + && (store = get_evp_method_store(methdata->libctx)) == NULL) + return NULL; + + if (!ossl_method_store_fetch(store, meth_id, methdata->propquery, prov, + &method)) + return NULL; + return method; +} + +static int put_evp_method_in_store(void *store, void *method, + const OSSL_PROVIDER *prov, + const char *names, const char *propdef, + void *data) +{ + struct evp_method_data_st *methdata = data; + OSSL_NAMEMAP *namemap; + int name_id; + uint32_t meth_id; + size_t l = 0; + + /* + * put_evp_method_in_store() is only called with an EVP method that was + * successfully created by construct_method() below, which means that + * all the names should already be stored in the namemap with the same + * numeric identity, so just use the first to get that identity. + */ + if (names != NULL) { + const char *q = strchr(names, NAME_SEPARATOR); + + l = (q == NULL ? strlen(names) : (size_t)(q - names)); + } + + if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL + || (name_id = ossl_namemap_name2num_n(namemap, names, l)) == 0 + || (meth_id = evp_method_id(name_id, methdata->operation_id)) == 0) + return 0; + + if (store == NULL + && (store = get_evp_method_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_store_add(store, prov, meth_id, propdef, method, + methdata->refcnt_up_method, + methdata->destruct_method); +} + +/* + * The core fetching functionality passes the name of the implementation. + * This function is responsible to getting an identity number for it. + */ +static void *construct_evp_method(const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov, void *data) +{ + /* + * This function is only called if get_evp_method_from_store() returned + * NULL, so it's safe to say that of all the spots to create a new + * namemap entry, this is it. Should the name already exist there, we + * know that ossl_namemap_add_name() will return its corresponding + * number. + */ + struct evp_method_data_st *methdata = data; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *names = algodef->algorithm_names; + int name_id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); + void *method; + + if (name_id == 0) + return NULL; + + method = methdata->method_from_algorithm(name_id, algodef, prov); + + /* + * Flag to indicate that there was actual construction errors. This + * helps inner_evp_generic_fetch() determine what error it should + * record on inaccessible algorithms. + */ + if (method == NULL) + methdata->flag_construct_error_occurred = 1; + + return method; +} + +static void destruct_evp_method(void *method, void *data) +{ + struct evp_method_data_st *methdata = data; + + methdata->destruct_method(method); +} + +static void * +inner_evp_generic_fetch(struct evp_method_data_st *methdata, + OSSL_PROVIDER *prov, int operation_id, + int name_id, const char *name, + const char *properties, + void *(*new_method)(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov), + int (*up_ref_method)(void *), + void (*free_method)(void *)) +{ + OSSL_METHOD_STORE *store = get_evp_method_store(methdata->libctx); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx); + const char *const propq = properties != NULL ? properties : ""; + uint32_t meth_id = 0; + void *method = NULL; + int unsupported = 0; + + if (store == NULL || namemap == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + + /* + * If there's ever an operation_id == 0 passed, we have an internal + * programming error. + */ + if (!ossl_assert(operation_id > 0)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return NULL; + } + + /* + * If we have been passed both a name_id and a name, we have an + * internal programming error. + */ + if (!ossl_assert(name_id == 0 || name == NULL)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return NULL; + } + + /* If we haven't received a name id yet, try to get one for the name */ + if (name_id == 0 && name != NULL) + name_id = ossl_namemap_name2num(namemap, name); + + /* + * If we have a name id, calculate a method id with evp_method_id(). + * + * evp_method_id returns 0 if we have too many operations (more than + * about 2^8) or too many names (more than about 2^24). In that case, + * we can't create any new method. + * For all intents and purposes, this is an internal error. + */ + if (name_id != 0 && (meth_id = evp_method_id(name_id, operation_id)) == 0) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return NULL; + } + + /* + * If we haven't found the name yet, chances are that the algorithm to + * be fetched is unsupported. + */ + if (name_id == 0) + unsupported = 1; + + if (meth_id == 0 + || !ossl_method_store_cache_get(store, prov, meth_id, propq, &method)) { + OSSL_METHOD_CONSTRUCT_METHOD mcm = { + get_tmp_evp_method_store, + reserve_evp_method_store, + unreserve_evp_method_store, + get_evp_method_from_store, + put_evp_method_in_store, + construct_evp_method, + destruct_evp_method + }; + + methdata->operation_id = operation_id; + methdata->name_id = name_id; + methdata->names = name; + methdata->propquery = propq; + methdata->method_from_algorithm = new_method; + methdata->refcnt_up_method = up_ref_method; + methdata->destruct_method = free_method; + methdata->flag_construct_error_occurred = 0; + if ((method = ossl_method_construct(methdata->libctx, operation_id, + &prov, 0 /* !force_cache */, + &mcm, methdata)) != NULL) { + /* + * If construction did create a method for us, we know that + * there is a correct name_id and meth_id, since those have + * already been calculated in get_evp_method_from_store() and + * put_evp_method_in_store() above. + */ + if (name_id == 0) + name_id = ossl_namemap_name2num(namemap, name); + meth_id = evp_method_id(name_id, operation_id); + if (name_id != 0) + ossl_method_store_cache_set(store, prov, meth_id, propq, + method, up_ref_method, free_method); + } + + /* + * If we never were in the constructor, the algorithm to be fetched + * is unsupported. + */ + unsupported = !methdata->flag_construct_error_occurred; + } + + if ((name_id != 0 || name != NULL) && method == NULL) { + int code = unsupported ? ERR_R_UNSUPPORTED : ERR_R_FETCH_FAILED; + + if (name == NULL) + name = ossl_namemap_num2name(namemap, name_id, 0); + ERR_raise_data(ERR_LIB_EVP, code, + "%s, Algorithm (%s : %d), Properties (%s)", + ossl_lib_ctx_get_descriptor(methdata->libctx), + name == NULL ? "" : name, name_id, + properties == NULL ? "" : properties); + } + + return method; +} + +void *evp_generic_fetch(OSSL_LIB_CTX *libctx, int operation_id, + const char *name, const char *properties, + void *(*new_method)(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov), + int (*up_ref_method)(void *), + void (*free_method)(void *)) +{ + struct evp_method_data_st methdata; + void *method; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + method = inner_evp_generic_fetch(&methdata, NULL, operation_id, + 0, name, properties, + new_method, up_ref_method, free_method); + dealloc_tmp_evp_method_store(methdata.tmp_store); + return method; +} + +/* + * evp_generic_fetch_by_number() is special, and only returns methods for + * already known names, i.e. it refuses to work if no name_id can be found + * (it's considered an internal programming error). + * This is meant to be used when one method needs to fetch an associated + * method. + */ +void *evp_generic_fetch_by_number(OSSL_LIB_CTX *libctx, int operation_id, + int name_id, const char *properties, + void *(*new_method)(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov), + int (*up_ref_method)(void *), + void (*free_method)(void *)) +{ + struct evp_method_data_st methdata; + void *method; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + method = inner_evp_generic_fetch(&methdata, NULL, operation_id, + name_id, NULL, properties, + new_method, up_ref_method, free_method); + dealloc_tmp_evp_method_store(methdata.tmp_store); + return method; +} + +/* + * evp_generic_fetch_from_prov() is special, and only returns methods from + * the given provider. + * This is meant to be used when one method needs to fetch an associated + * method. + */ +void *evp_generic_fetch_from_prov(OSSL_PROVIDER *prov, int operation_id, + const char *name, const char *properties, + void *(*new_method)(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov), + int (*up_ref_method)(void *), + void (*free_method)(void *)) +{ + struct evp_method_data_st methdata; + void *method; + + methdata.libctx = ossl_provider_libctx(prov); + methdata.tmp_store = NULL; + method = inner_evp_generic_fetch(&methdata, prov, operation_id, + 0, name, properties, + new_method, up_ref_method, free_method); + dealloc_tmp_evp_method_store(methdata.tmp_store); + return method; +} + +int evp_method_store_cache_flush(OSSL_LIB_CTX *libctx) +{ + OSSL_METHOD_STORE *store = get_evp_method_store(libctx); + + if (store != NULL) + return ossl_method_store_cache_flush_all(store); + return 1; +} + +int evp_method_store_remove_all_provided(const OSSL_PROVIDER *prov) +{ + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_METHOD_STORE *store = get_evp_method_store(libctx); + + if (store != NULL) + return ossl_method_store_remove_all_provided(store, prov); + return 1; +} + +static int evp_set_parsed_default_properties(OSSL_LIB_CTX *libctx, + OSSL_PROPERTY_LIST *def_prop, + int loadconfig, + int mirrored) +{ + OSSL_METHOD_STORE *store = get_evp_method_store(libctx); + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, loadconfig); + + if (plp != NULL && store != NULL) { +#ifndef FIPS_MODULE + char *propstr = NULL; + size_t strsz; + + if (mirrored) { + if (ossl_global_properties_no_mirrored(libctx)) + return 0; + } else { + /* + * These properties have been explicitly set on this libctx, so + * don't allow any mirroring from a parent libctx. + */ + ossl_global_properties_stop_mirroring(libctx); + } + + strsz = ossl_property_list_to_string(libctx, def_prop, NULL, 0); + if (strsz > 0) + propstr = OPENSSL_malloc(strsz); + if (propstr == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + if (ossl_property_list_to_string(libctx, def_prop, propstr, + strsz) == 0) { + OPENSSL_free(propstr); + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + ossl_provider_default_props_update(libctx, propstr); + OPENSSL_free(propstr); +#endif + ossl_property_free(*plp); + *plp = def_prop; + if (store != NULL) + return ossl_method_store_cache_flush_all(store); + } + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; +} + +int evp_set_default_properties_int(OSSL_LIB_CTX *libctx, const char *propq, + int loadconfig, int mirrored) +{ + OSSL_PROPERTY_LIST *pl = NULL; + + if (propq != NULL && (pl = ossl_parse_query(libctx, propq, 1)) == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_DEFAULT_QUERY_PARSE_ERROR); + return 0; + } + if (!evp_set_parsed_default_properties(libctx, pl, loadconfig, mirrored)) { + ossl_property_free(pl); + return 0; + } + return 1; +} + +int EVP_set_default_properties(OSSL_LIB_CTX *libctx, const char *propq) +{ + return evp_set_default_properties_int(libctx, propq, 1, 0); +} + +static int evp_default_properties_merge(OSSL_LIB_CTX *libctx, const char *propq, + int loadconfig) +{ + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, loadconfig); + OSSL_PROPERTY_LIST *pl1, *pl2; + + if (propq == NULL) + return 1; + if (plp == NULL || *plp == NULL) + return evp_set_default_properties_int(libctx, propq, 0, 0); + if ((pl1 = ossl_parse_query(libctx, propq, 1)) == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_DEFAULT_QUERY_PARSE_ERROR); + return 0; + } + pl2 = ossl_property_merge(pl1, *plp); + ossl_property_free(pl1); + if (pl2 == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!evp_set_parsed_default_properties(libctx, pl2, 0, 0)) { + ossl_property_free(pl2); + return 0; + } + return 1; +} + +static int evp_default_property_is_enabled(OSSL_LIB_CTX *libctx, + const char *prop_name) +{ + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, 1); + + return plp != NULL && ossl_property_is_enabled(libctx, prop_name, *plp); +} + +int EVP_default_properties_is_fips_enabled(OSSL_LIB_CTX *libctx) +{ + return evp_default_property_is_enabled(libctx, "fips"); +} + +int evp_default_properties_enable_fips_int(OSSL_LIB_CTX *libctx, int enable, + int loadconfig) +{ + const char *query = (enable != 0) ? "fips=yes" : "-fips"; + + return evp_default_properties_merge(libctx, query, loadconfig); +} + +int EVP_default_properties_enable_fips(OSSL_LIB_CTX *libctx, int enable) +{ + return evp_default_properties_enable_fips_int(libctx, enable, 1); +} + +char *evp_get_global_properties_str(OSSL_LIB_CTX *libctx, int loadconfig) +{ + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, loadconfig); + char *propstr = NULL; + size_t sz; + + if (plp == NULL) + return OPENSSL_strdup(""); + + sz = ossl_property_list_to_string(libctx, *plp, NULL, 0); + if (sz == 0) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return NULL; + } + + propstr = OPENSSL_malloc(sz); + if (propstr == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (ossl_property_list_to_string(libctx, *plp, propstr, sz) == 0) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + OPENSSL_free(propstr); + return NULL; + } + return propstr; +} + +struct filter_data_st { + int operation_id; + void (*user_fn)(void *method, void *arg); + void *user_arg; +}; + +static void filter_on_operation_id(int id, void *method, void *arg) +{ + struct filter_data_st *data = arg; + + if ((id & METHOD_ID_OPERATION_MASK) == data->operation_id) + data->user_fn(method, data->user_arg); +} + +void evp_generic_do_all(OSSL_LIB_CTX *libctx, int operation_id, + void (*user_fn)(void *method, void *arg), + void *user_arg, + void *(*new_method)(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov), + int (*up_ref_method)(void *), + void (*free_method)(void *)) +{ + struct evp_method_data_st methdata; + struct filter_data_st data; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + (void)inner_evp_generic_fetch(&methdata, NULL, operation_id, 0, NULL, NULL, + new_method, up_ref_method, free_method); + + data.operation_id = operation_id; + data.user_fn = user_fn; + data.user_arg = user_arg; + if (methdata.tmp_store != NULL) + ossl_method_store_do_all(methdata.tmp_store, &filter_on_operation_id, + &data); + ossl_method_store_do_all(get_evp_method_store(libctx), + &filter_on_operation_id, &data); + dealloc_tmp_evp_method_store(methdata.tmp_store); +} + +int evp_is_a(OSSL_PROVIDER *prov, int number, + const char *legacy_name, const char *name) +{ + /* + * For a |prov| that is NULL, the library context will be NULL + */ + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + if (prov == NULL) + number = ossl_namemap_name2num(namemap, legacy_name); + return ossl_namemap_name2num(namemap, name) == number; +} + +int evp_names_do_all(OSSL_PROVIDER *prov, int number, + void (*fn)(const char *name, void *data), + void *data) +{ + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_doall_names(namemap, number, fn, data); +} diff --git a/crypto/openssl/crypto/evp/evp_key.c b/crypto/openssl/crypto/evp/evp_key.c index e5ac107c385c..607d45ee2340 100644 --- a/crypto/openssl/crypto/evp/evp_key.c +++ b/crypto/openssl/crypto/evp/evp_key.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,6 +14,10 @@ #include #include +#ifndef BUFSIZ +# define BUFSIZ 256 +#endif + /* should be init to zeros. */ static char prompt_string[80]; @@ -81,8 +85,8 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, int niv, nkey, addmd = 0; unsigned int mds = 0, i; int rv = 0; - nkey = EVP_CIPHER_key_length(type); - niv = EVP_CIPHER_iv_length(type); + nkey = EVP_CIPHER_get_key_length(type); + niv = EVP_CIPHER_get_iv_length(type); OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH); OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH); @@ -142,7 +146,7 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, if ((nkey == 0) && (niv == 0)) break; } - rv = EVP_CIPHER_key_length(type); + rv = EVP_CIPHER_get_key_length(type); err: EVP_MD_CTX_free(c); OPENSSL_cleanse(md_buf, sizeof(md_buf)); diff --git a/crypto/openssl/crypto/evp/evp_lib.c b/crypto/openssl/crypto/evp/evp_lib.c index 45cde0da8bfc..4f3d901eba5d 100644 --- a/crypto/openssl/crypto/evp/evp_lib.c +++ b/crypto/openssl/crypto/evp/evp_lib.c @@ -1,34 +1,118 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * EVP _meth_ APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include +#include #include "internal/cryptlib.h" #include #include +#include +#include +#include +#include +#include #include "crypto/evp.h" +#include "crypto/cryptlib.h" +#include "internal/provider.h" #include "evp_local.h" +#if !defined(FIPS_MODULE) +# include "crypto/asn1.h" + int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) { - int ret; + return evp_cipher_param_to_asn1_ex(c, type, NULL); +} + +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + return evp_cipher_asn1_to_param_ex(c, type, NULL); +} + +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *ctx, ASN1_TYPE *type) +{ + int i = 0; + unsigned int l; + + if (type != NULL) { + unsigned char iv[EVP_MAX_IV_LENGTH]; + + l = EVP_CIPHER_CTX_get_iv_length(ctx); + if (!ossl_assert(l <= sizeof(iv))) + return -1; + i = ASN1_TYPE_get_octetstring(type, iv, l); + if (i != (int)l) + return -1; + + if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1)) + return -1; + } + return i; +} + +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int i = 0; + unsigned int j; + unsigned char *oiv = NULL; - if (c->cipher->set_asn1_parameters != NULL) - ret = c->cipher->set_asn1_parameters(c, type); - else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) { - switch (EVP_CIPHER_CTX_mode(c)) { + if (type != NULL) { + oiv = (unsigned char *)EVP_CIPHER_CTX_original_iv(c); + j = EVP_CIPHER_CTX_get_iv_length(c); + OPENSSL_assert(j <= sizeof(c->iv)); + i = ASN1_TYPE_set_octetstring(type, oiv, j); + } + return i; +} + +int evp_cipher_param_to_asn1_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) +{ + int ret = -1; /* Assume the worst */ + const EVP_CIPHER *cipher = c->cipher; + + /* + * For legacy implementations, we detect custom AlgorithmIdentifier + * parameter handling by checking if the function pointer + * cipher->set_asn1_parameters is set. We know that this pointer + * is NULL for provided implementations. + * + * Otherwise, for any implementation, we check the flag + * EVP_CIPH_FLAG_CUSTOM_ASN1. If it isn't set, we apply + * default AI parameter extraction. + * + * Otherwise, for provided implementations, we convert |type| to + * a DER encoded blob and pass to the implementation in OSSL_PARAM + * form. + * + * If none of the above applies, this operation is unsupported. + */ + if (cipher->set_asn1_parameters != NULL) { + ret = cipher->set_asn1_parameters(c, type); + } else if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_CUSTOM_ASN1) == 0) { + switch (EVP_CIPHER_get_mode(cipher)) { case EVP_CIPH_WRAP_MODE: - if (EVP_CIPHER_CTX_nid(c) == NID_id_smime_alg_CMS3DESwrap) + if (EVP_CIPHER_is_a(cipher, SN_id_smime_alg_CMS3DESwrap)) ASN1_TYPE_set(type, V_ASN1_NULL, NULL); ret = 1; break; case EVP_CIPH_GCM_MODE: + ret = evp_cipher_set_asn1_aead_params(c, type, asn1_params); + break; + case EVP_CIPH_CCM_MODE: case EVP_CIPH_XTS_MODE: case EVP_CIPH_OCB_MODE: @@ -38,31 +122,86 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) default: ret = EVP_CIPHER_set_asn1_iv(c, type); } - } else - ret = -1; - if (ret <= 0) - EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, ret == -2 ? - ASN1_R_UNSUPPORTED_CIPHER : - EVP_R_CIPHER_PARAMETER_ERROR); + } else if (cipher->prov != NULL) { + OSSL_PARAM params[3], *p = params; + unsigned char *der = NULL, *derp; + + /* + * We make two passes, the first to get the appropriate buffer size, + * and the second to get the actual value. + */ + *p++ = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS, + NULL, 0); + *p = OSSL_PARAM_construct_end(); + + if (!EVP_CIPHER_CTX_get_params(c, params)) + goto err; + + /* ... but, we should get a return size too! */ + if (OSSL_PARAM_modified(params) + && params[0].return_size != 0 + && (der = OPENSSL_malloc(params[0].return_size)) != NULL) { + params[0].data = der; + params[0].data_size = params[0].return_size; + OSSL_PARAM_set_all_unmodified(params); + derp = der; + if (EVP_CIPHER_CTX_get_params(c, params) + && OSSL_PARAM_modified(params) + && d2i_ASN1_TYPE(&type, (const unsigned char **)&derp, + params[0].return_size) != NULL) { + ret = 1; + } + OPENSSL_free(der); + } + } else { + ret = -2; + } + + err: + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER); + else if (ret <= 0) + ERR_raise(ERR_LIB_EVP, EVP_R_CIPHER_PARAMETER_ERROR); if (ret < -1) ret = -1; return ret; } -int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) { - int ret; - - if (c->cipher->get_asn1_parameters != NULL) - ret = c->cipher->get_asn1_parameters(c, type); - else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) { - switch (EVP_CIPHER_CTX_mode(c)) { + int ret = -1; /* Assume the worst */ + const EVP_CIPHER *cipher = c->cipher; + /* + * For legacy implementations, we detect custom AlgorithmIdentifier + * parameter handling by checking if there the function pointer + * cipher->get_asn1_parameters is set. We know that this pointer + * is NULL for provided implementations. + * + * Otherwise, for any implementation, we check the flag + * EVP_CIPH_FLAG_CUSTOM_ASN1. If it isn't set, we apply + * default AI parameter creation. + * + * Otherwise, for provided implementations, we get the AI parameter + * in DER encoded form from the implementation by requesting the + * appropriate OSSL_PARAM and converting the result to a ASN1_TYPE. + * + * If none of the above applies, this operation is unsupported. + */ + if (cipher->get_asn1_parameters != NULL) { + ret = cipher->get_asn1_parameters(c, type); + } else if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_CUSTOM_ASN1) == 0) { + switch (EVP_CIPHER_get_mode(cipher)) { case EVP_CIPH_WRAP_MODE: ret = 1; break; case EVP_CIPH_GCM_MODE: + ret = evp_cipher_get_asn1_aead_params(c, type, asn1_params); + break; + case EVP_CIPH_CCM_MODE: case EVP_CIPH_XTS_MODE: case EVP_CIPH_OCB_MODE: @@ -70,56 +209,74 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) break; default: - ret = EVP_CIPHER_get_asn1_iv(c, type); - break; + ret = EVP_CIPHER_get_asn1_iv(c, type) >= 0 ? 1 : -1; } - } else - ret = -1; - if (ret <= 0) - EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, ret == -2 ? - EVP_R_UNSUPPORTED_CIPHER : - EVP_R_CIPHER_PARAMETER_ERROR); + } else if (cipher->prov != NULL) { + OSSL_PARAM params[3], *p = params; + unsigned char *der = NULL; + int derl = -1; + + if ((derl = i2d_ASN1_TYPE(type, &der)) >= 0) { + *p++ = + OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS, + der, (size_t)derl); + *p = OSSL_PARAM_construct_end(); + if (EVP_CIPHER_CTX_set_params(c, params)) + ret = 1; + OPENSSL_free(der); + } + } else { + ret = -2; + } + + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER); + else if (ret <= 0) + ERR_raise(ERR_LIB_EVP, EVP_R_CIPHER_PARAMETER_ERROR); if (ret < -1) ret = -1; return ret; } -int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +int evp_cipher_get_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) { int i = 0; - unsigned int l; + long tl; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (type == NULL || asn1_params == NULL) + return 0; + + i = ossl_asn1_type_get_octetstring_int(type, &tl, NULL, EVP_MAX_IV_LENGTH); + if (i <= 0) + return -1; + ossl_asn1_type_get_octetstring_int(type, &tl, iv, i); + + memcpy(asn1_params->iv, iv, i); + asn1_params->iv_len = i; - if (type != NULL) { - l = EVP_CIPHER_CTX_iv_length(c); - OPENSSL_assert(l <= sizeof(c->iv)); - i = ASN1_TYPE_get_octetstring(type, c->oiv, l); - if (i != (int)l) - return -1; - else if (i > 0) - memcpy(c->iv, c->oiv, l); - } return i; } -int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +int evp_cipher_set_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) { - int i = 0; - unsigned int j; + if (type == NULL || asn1_params == NULL) + return 0; - if (type != NULL) { - j = EVP_CIPHER_CTX_iv_length(c); - OPENSSL_assert(j <= sizeof(c->iv)); - i = ASN1_TYPE_set_octetstring(type, c->oiv, j); - } - return i; + return ossl_asn1_type_set_octetstring_int(type, asn1_params->tag_len, + asn1_params->iv, + asn1_params->iv_len); } +#endif /* !defined(FIPS_MODULE) */ /* Convert the various cipher NIDs and dummies to a proper OID NID */ -int EVP_CIPHER_type(const EVP_CIPHER *ctx) +int EVP_CIPHER_get_type(const EVP_CIPHER *cipher) { int nid; - ASN1_OBJECT *otmp; - nid = EVP_CIPHER_nid(ctx); + nid = EVP_CIPHER_get_nid(cipher); switch (nid) { @@ -165,23 +322,77 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx) return NID_des_cfb64; default: - /* Check it has an OID and it is valid */ - otmp = OBJ_nid2obj(nid); - if (OBJ_get0_data(otmp) == NULL) - nid = NID_undef; - ASN1_OBJECT_free(otmp); - return nid; +#ifdef FIPS_MODULE + return NID_undef; +#else + { + /* Check it has an OID and it is valid */ + ASN1_OBJECT *otmp = OBJ_nid2obj(nid); + + if (OBJ_get0_data(otmp) == NULL) + nid = NID_undef; + ASN1_OBJECT_free(otmp); + return nid; + } +#endif + } +} + +int evp_cipher_cache_constants(EVP_CIPHER *cipher) +{ + int ok, aead = 0, custom_iv = 0, cts = 0, multiblock = 0, randkey = 0; + size_t ivlen = 0; + size_t blksz = 0; + size_t keylen = 0; + unsigned int mode = 0; + OSSL_PARAM params[10]; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, &blksz); + params[1] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &ivlen); + params[2] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &keylen); + params[3] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_MODE, &mode); + params[4] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_AEAD, &aead); + params[5] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_CUSTOM_IV, + &custom_iv); + params[6] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_CTS, &cts); + params[7] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, + &multiblock); + params[8] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, + &randkey); + params[9] = OSSL_PARAM_construct_end(); + ok = evp_do_ciph_getparams(cipher, params) > 0; + if (ok) { + cipher->block_size = blksz; + cipher->iv_len = ivlen; + cipher->key_len = keylen; + cipher->flags = mode; + if (aead) + cipher->flags |= EVP_CIPH_FLAG_AEAD_CIPHER; + if (custom_iv) + cipher->flags |= EVP_CIPH_CUSTOM_IV; + if (cts) + cipher->flags |= EVP_CIPH_FLAG_CTS; + if (multiblock) + cipher->flags |= EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK; + if (cipher->ccipher != NULL) + cipher->flags |= EVP_CIPH_FLAG_CUSTOM_CIPHER; + if (randkey) + cipher->flags |= EVP_CIPH_RAND_KEY; + if (OSSL_PARAM_locate_const(EVP_CIPHER_gettable_ctx_params(cipher), + OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS)) + cipher->flags |= EVP_CIPH_FLAG_CUSTOM_ASN1; } + return ok; } -int EVP_CIPHER_block_size(const EVP_CIPHER *e) +int EVP_CIPHER_get_block_size(const EVP_CIPHER *cipher) { - return e->block_size; + return cipher->block_size; } -int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) +int EVP_CIPHER_CTX_get_block_size(const EVP_CIPHER_CTX *ctx) { - return ctx->cipher->block_size; + return EVP_CIPHER_get_block_size(ctx->cipher); } int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e) @@ -192,20 +403,71 @@ int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e) int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) { + if (ctx->cipher->prov != NULL) { + /* + * If the provided implementation has a ccipher function, we use it, + * and translate its return value like this: 0 => -1, 1 => outlen + * + * Otherwise, we call the cupdate function if in != NULL, or cfinal + * if in == NULL. Regardless of which, we return what we got. + */ + int ret = -1; + size_t outl = 0; + size_t blocksize = EVP_CIPHER_CTX_get_block_size(ctx); + + if (ctx->cipher->ccipher != NULL) + ret = ctx->cipher->ccipher(ctx->algctx, out, &outl, + inl + (blocksize == 1 ? 0 : blocksize), + in, (size_t)inl) + ? (int)outl : -1; + else if (in != NULL) + ret = ctx->cipher->cupdate(ctx->algctx, out, &outl, + inl + (blocksize == 1 ? 0 : blocksize), + in, (size_t)inl); + else + ret = ctx->cipher->cfinal(ctx->algctx, out, &outl, + blocksize == 1 ? 0 : blocksize); + + return ret; + } + return ctx->cipher->do_cipher(ctx, out, in, inl); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) { + if (ctx == NULL) + return NULL; return ctx->cipher; } +#endif + +const EVP_CIPHER *EVP_CIPHER_CTX_get0_cipher(const EVP_CIPHER_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + return ctx->cipher; +} + +EVP_CIPHER *EVP_CIPHER_CTX_get1_cipher(EVP_CIPHER_CTX *ctx) +{ + EVP_CIPHER *cipher; + + if (ctx == NULL) + return NULL; + cipher = (EVP_CIPHER *)ctx->cipher; + if (!EVP_CIPHER_up_ref(cipher)) + return NULL; + return cipher; +} -int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) +int EVP_CIPHER_CTX_is_encrypting(const EVP_CIPHER_CTX *ctx) { return ctx->encrypt; } -unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher) +unsigned long EVP_CIPHER_get_flags(const EVP_CIPHER *cipher) { return cipher->flags; } @@ -235,36 +497,121 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data) return old_cipher_data; } -int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) +int EVP_CIPHER_get_iv_length(const EVP_CIPHER *cipher) { return cipher->iv_len; } -int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) +int EVP_CIPHER_CTX_get_iv_length(const EVP_CIPHER_CTX *ctx) +{ + if (ctx->iv_len < 0) { + int rv, len = EVP_CIPHER_get_iv_length(ctx->cipher); + size_t v = len; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + if (ctx->cipher->get_ctx_params != NULL) { + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, + &v); + rv = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + if (rv > 0) { + if (OSSL_PARAM_modified(params) + && !OSSL_PARAM_get_int(params, &len)) + return -1; + } else if (rv != EVP_CTRL_RET_UNSUPPORTED) { + return -1; + } + } + /* Code below to be removed when legacy support is dropped. */ + else if ((EVP_CIPHER_get_flags(ctx->cipher) + & EVP_CIPH_CUSTOM_IV_LENGTH) != 0) { + rv = EVP_CIPHER_CTX_ctrl((EVP_CIPHER_CTX *)ctx, EVP_CTRL_GET_IVLEN, + 0, &len); + if (rv <= 0) + return -1; + } + /*- + * Casting away the const is annoying but required here. We need to + * cache the result for performance reasons. + */ + ((EVP_CIPHER_CTX *)ctx)->iv_len = len; + } + return ctx->iv_len; +} + +int EVP_CIPHER_CTX_get_tag_length(const EVP_CIPHER_CTX *ctx) { - int i, rv; + int ret; + size_t v = 0; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - 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; + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, &v); + ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + return ret == 1 ? (int)v : 0; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx) { - return ctx->oiv; + int ok; + const unsigned char *v = ctx->oiv; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_IV, + (void **)&v, sizeof(ctx->oiv)); + ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + + return ok != 0 ? v : NULL; } +/* + * OSSL_PARAM_OCTET_PTR gets us the pointer to the running IV in the provider + */ const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx) { - return ctx->iv; + int ok; + const unsigned char *v = ctx->iv; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_UPDATED_IV, + (void **)&v, sizeof(ctx->iv)); + ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + + return ok != 0 ? v : NULL; } unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx) { - return ctx->iv; + int ok; + unsigned char *v = ctx->iv; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_UPDATED_IV, + (void **)&v, sizeof(ctx->iv)); + ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + + return ok != 0 ? v : NULL; +} +#endif /* OPENSSL_NO_DEPRECATED_3_0_0 */ + +int EVP_CIPHER_CTX_get_updated_iv(EVP_CIPHER_CTX *ctx, void *buf, size_t len) +{ + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, buf, len); + return evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params) > 0; +} + +int EVP_CIPHER_CTX_get_original_iv(EVP_CIPHER_CTX *ctx, void *buf, size_t len) +{ + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_IV, buf, len); + return evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params) > 0; } unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx) @@ -272,109 +619,287 @@ unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx) return ctx->buf; } -int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx) +int EVP_CIPHER_CTX_get_num(const EVP_CIPHER_CTX *ctx) { - return ctx->num; + int ok; + unsigned int v = (unsigned int)ctx->num; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_NUM, &v); + ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + + return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED; } -void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num) +int EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num) { - ctx->num = num; + int ok; + unsigned int n = (unsigned int)num; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_NUM, &n); + ok = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params); + + if (ok != 0) + ctx->num = (int)n; + return ok != 0; } -int EVP_CIPHER_key_length(const EVP_CIPHER *cipher) +int EVP_CIPHER_get_key_length(const EVP_CIPHER *cipher) { return cipher->key_len; } -int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) +int EVP_CIPHER_CTX_get_key_length(const EVP_CIPHER_CTX *ctx) { - return ctx->key_len; + int ok; + size_t v = ctx->key_len; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &v); + ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params); + + return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED; } -int EVP_CIPHER_nid(const EVP_CIPHER *cipher) +int EVP_CIPHER_get_nid(const EVP_CIPHER *cipher) { return cipher->nid; } -int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) +int EVP_CIPHER_CTX_get_nid(const EVP_CIPHER_CTX *ctx) { return ctx->cipher->nid; } -int EVP_MD_block_size(const EVP_MD *md) +int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name) { - return md->block_size; + if (cipher == NULL) + return 0; + if (cipher->prov != NULL) + return evp_is_a(cipher->prov, cipher->name_id, NULL, name); + return evp_is_a(NULL, 0, EVP_CIPHER_get0_name(cipher), name); +} + +int evp_cipher_get_number(const EVP_CIPHER *cipher) +{ + return cipher->name_id; +} + +const char *EVP_CIPHER_get0_name(const EVP_CIPHER *cipher) +{ + if (cipher->type_name != NULL) + return cipher->type_name; +#ifndef FIPS_MODULE + return OBJ_nid2sn(EVP_CIPHER_get_nid(cipher)); +#else + return NULL; +#endif +} + +const char *EVP_CIPHER_get0_description(const EVP_CIPHER *cipher) +{ + if (cipher->description != NULL) + return cipher->description; +#ifndef FIPS_MODULE + return OBJ_nid2ln(EVP_CIPHER_get_nid(cipher)); +#else + return NULL; +#endif +} + +int EVP_CIPHER_names_do_all(const EVP_CIPHER *cipher, + void (*fn)(const char *name, void *data), + void *data) +{ + if (cipher->prov != NULL) + return evp_names_do_all(cipher->prov, cipher->name_id, fn, data); + + return 1; +} + +const OSSL_PROVIDER *EVP_CIPHER_get0_provider(const EVP_CIPHER *cipher) +{ + return cipher->prov; +} + +int EVP_CIPHER_get_mode(const EVP_CIPHER *cipher) +{ + return EVP_CIPHER_get_flags(cipher) & EVP_CIPH_MODE; +} + +int EVP_MD_is_a(const EVP_MD *md, const char *name) +{ + if (md == NULL) + return 0; + if (md->prov != NULL) + return evp_is_a(md->prov, md->name_id, NULL, name); + return evp_is_a(NULL, 0, EVP_MD_get0_name(md), name); +} + +int evp_md_get_number(const EVP_MD *md) +{ + return md->name_id; } -int EVP_MD_type(const EVP_MD *md) +const char *EVP_MD_get0_description(const EVP_MD *md) +{ + if (md->description != NULL) + return md->description; +#ifndef FIPS_MODULE + return OBJ_nid2ln(EVP_MD_nid(md)); +#else + return NULL; +#endif +} + +const char *EVP_MD_get0_name(const EVP_MD *md) +{ + if (md == NULL) + return NULL; + if (md->type_name != NULL) + return md->type_name; +#ifndef FIPS_MODULE + return OBJ_nid2sn(EVP_MD_nid(md)); +#else + return NULL; +#endif +} + +int EVP_MD_names_do_all(const EVP_MD *md, + void (*fn)(const char *name, void *data), + void *data) +{ + if (md->prov != NULL) + return evp_names_do_all(md->prov, md->name_id, fn, data); + + return 1; +} + +const OSSL_PROVIDER *EVP_MD_get0_provider(const EVP_MD *md) +{ + return md->prov; +} + +int EVP_MD_get_type(const EVP_MD *md) { return md->type; } -int EVP_MD_pkey_type(const EVP_MD *md) +int EVP_MD_get_pkey_type(const EVP_MD *md) { return md->pkey_type; } -int EVP_MD_size(const EVP_MD *md) +int EVP_MD_get_block_size(const EVP_MD *md) { - if (!md) { - EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL); + if (md == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL); + return -1; + } + return md->block_size; +} + +int EVP_MD_get_size(const EVP_MD *md) +{ + if (md == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL); return -1; } return md->md_size; } -unsigned long EVP_MD_flags(const EVP_MD *md) +unsigned long EVP_MD_get_flags(const EVP_MD *md) { return md->flags; } EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type) { - EVP_MD *md = OPENSSL_zalloc(sizeof(*md)); + EVP_MD *md = evp_md_new(); if (md != NULL) { md->type = md_type; md->pkey_type = pkey_type; + md->origin = EVP_ORIG_METH; } return md; } + EVP_MD *EVP_MD_meth_dup(const EVP_MD *md) { - EVP_MD *to = EVP_MD_meth_new(md->type, md->pkey_type); + EVP_MD *to = NULL; + + /* + * Non-legacy EVP_MDs can't be duplicated like this. + * Use EVP_MD_up_ref() instead. + */ + if (md->prov != NULL) + return NULL; + + if ((to = EVP_MD_meth_new(md->type, md->pkey_type)) != NULL) { + CRYPTO_RWLOCK *lock = to->lock; - if (to != NULL) memcpy(to, md, sizeof(*to)); + to->lock = lock; + to->origin = EVP_ORIG_METH; + } return to; } -void EVP_MD_meth_free(EVP_MD *md) + +void evp_md_free_int(EVP_MD *md) { + OPENSSL_free(md->type_name); + ossl_provider_free(md->prov); + CRYPTO_THREAD_lock_free(md->lock); OPENSSL_free(md); } + +void EVP_MD_meth_free(EVP_MD *md) +{ + if (md == NULL || md->origin != EVP_ORIG_METH) + return; + + evp_md_free_int(md); +} + int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize) { + if (md->block_size != 0) + return 0; + md->block_size = blocksize; return 1; } int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize) { + if (md->md_size != 0) + return 0; + md->md_size = resultsize; return 1; } int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize) { + if (md->ctx_size != 0) + return 0; + md->ctx_size = datasize; return 1; } int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags) { + if (md->flags != 0) + return 0; + md->flags = flags; return 1; } int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx)) { + if (md->init != NULL) + return 0; + md->init = init; return 1; } @@ -382,29 +907,44 @@ int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count)) { + if (md->update != NULL) + return 0; + md->update = update; return 1; } int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx, unsigned char *md)) { + if (md->final != NULL) + return 0; + md->final = final; return 1; } int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from)) { + if (md->copy != NULL) + return 0; + md->copy = copy; return 1; } int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx)) { + if (md->cleanup != NULL) + return 0; + md->cleanup = cleanup; return 1; } int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)) { + if (md->md_ctrl != NULL) + return 0; + md->md_ctrl = ctrl; return 1; } @@ -455,18 +995,40 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd, return md->md_ctrl; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) { - if (!ctx) + if (ctx == NULL) + return NULL; + return ctx->reqdigest; +} +#endif + +const EVP_MD *EVP_MD_CTX_get0_md(const EVP_MD_CTX *ctx) +{ + if (ctx == NULL) return NULL; - return ctx->digest; + return ctx->reqdigest; } -EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) +EVP_MD *EVP_MD_CTX_get1_md(EVP_MD_CTX *ctx) +{ + EVP_MD *md; + + if (ctx == NULL) + return NULL; + md = (EVP_MD *)ctx->reqdigest; + if (md == NULL || !EVP_MD_up_ref(md)) + return NULL; + return md; +} + +EVP_PKEY_CTX *EVP_MD_CTX_get_pkey_ctx(const EVP_MD_CTX *ctx) { return ctx->pctx; } +#if !defined(FIPS_MODULE) void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) { /* @@ -485,8 +1047,9 @@ void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); } } +#endif /* !defined(FIPS_MODULE) */ -void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx) +void *EVP_MD_CTX_get0_md_data(const EVP_MD_CTX *ctx) { return ctx->md_data; } @@ -519,17 +1082,135 @@ int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) return (ctx->flags & flags); } +static int evp_cipher_ctx_enable_use_bits(EVP_CIPHER_CTX *ctx, + unsigned int enable) +{ + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_USE_BITS, &enable); + return EVP_CIPHER_CTX_set_params(ctx, params); +} + void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags) { + int oldflags = ctx->flags; + ctx->flags |= flags; + if (((oldflags ^ ctx->flags) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) + evp_cipher_ctx_enable_use_bits(ctx, 1); } void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags) { + int oldflags = ctx->flags; + ctx->flags &= ~flags; + if (((oldflags ^ ctx->flags) & EVP_CIPH_FLAG_LENGTH_BITS) != 0) + evp_cipher_ctx_enable_use_bits(ctx, 0); } int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags) { return (ctx->flags & flags); } + +#if !defined(FIPS_MODULE) + +int EVP_PKEY_CTX_set_group_name(EVP_PKEY_CTX *ctx, const char *name) +{ + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + if (name == NULL) + return -1; + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + (char *)name, 0); + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_get_group_name(EVP_PKEY_CTX *ctx, char *name, size_t namelen) +{ + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + OSSL_PARAM *p = params; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { + /* There is no legacy support for this */ + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + if (name == NULL) + return -1; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + name, namelen); + if (!EVP_PKEY_CTX_get_params(ctx, params)) + return -1; + return 1; +} + +/* + * evp_pkey_keygen() abstracts from the explicit use of B + * while providing a generic way of generating a new asymmetric key pair + * of algorithm type I (e.g., C or C). + * The library context I and property query I + * are used when fetching algorithms from providers. + * The I specify algorithm-specific parameters + * such as the RSA modulus size or the name of an EC curve. + */ +static EVP_PKEY *evp_pkey_keygen(OSSL_LIB_CTX *libctx, const char *name, + const char *propq, const OSSL_PARAM *params) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(libctx, name, propq); + + if (ctx != NULL + && EVP_PKEY_keygen_init(ctx) > 0 + && EVP_PKEY_CTX_set_params(ctx, params)) + (void)EVP_PKEY_generate(ctx, &pkey); + + EVP_PKEY_CTX_free(ctx); + return pkey; +} + +EVP_PKEY *EVP_PKEY_Q_keygen(OSSL_LIB_CTX *libctx, const char *propq, + const char *type, ...) +{ + va_list args; + size_t bits; + char *name; + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + EVP_PKEY *ret = NULL; + + va_start(args, type); + + if (OPENSSL_strcasecmp(type, "RSA") == 0) { + bits = va_arg(args, size_t); + params[0] = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits); + } else if (OPENSSL_strcasecmp(type, "EC") == 0) { + name = va_arg(args, char *); + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + name, 0); + } else if (OPENSSL_strcasecmp(type, "ED25519") != 0 + && OPENSSL_strcasecmp(type, "X25519") != 0 + && OPENSSL_strcasecmp(type, "ED448") != 0 + && OPENSSL_strcasecmp(type, "X448") != 0 + && OPENSSL_strcasecmp(type, "SM2") != 0) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT); + goto end; + } + ret = evp_pkey_keygen(libctx, type, propq, params); + + end: + va_end(args); + return ret; +} + +#endif /* !defined(FIPS_MODULE) */ diff --git a/crypto/openssl/crypto/evp/evp_local.h b/crypto/openssl/crypto/evp/evp_local.h index b59beee49fa8..3ccfaeb37cd9 100644 --- a/crypto/openssl/crypto/evp/evp_local.h +++ b/crypto/openssl/crypto/evp/evp_local.h @@ -1,15 +1,20 @@ /* * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ -/* EVP_MD_CTX related stuff */ +#include +#include "internal/refcount.h" + +#define EVP_CTRL_RET_UNSUPPORTED -1 + struct evp_md_ctx_st { + const EVP_MD *reqdigest; /* The original requested digest */ const EVP_MD *digest; ENGINE *engine; /* functional reference if 'digest' is * ENGINE-provided */ @@ -19,6 +24,13 @@ struct evp_md_ctx_st { EVP_PKEY_CTX *pctx; /* Update function: usually copied from EVP_MD */ int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); + + /* + * Opaque ctx returned from a providers digest algorithm implementation + * OSSL_FUNC_digest_newctx() + */ + void *algctx; + EVP_MD *fetched_digest; } /* EVP_MD_CTX */ ; struct evp_cipher_ctx_st { @@ -34,17 +46,198 @@ struct evp_cipher_ctx_st { /* FIXME: Should this even exist? It appears unused */ void *app_data; /* application stuff */ int key_len; /* May change for variable length cipher */ + int iv_len; /* IV length */ unsigned long flags; /* Various flags */ void *cipher_data; /* per EVP data */ int final_used; int block_mask; unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */ + + /* + * Opaque ctx returned from a providers cipher algorithm implementation + * OSSL_FUNC_cipher_newctx() + */ + void *algctx; + EVP_CIPHER *fetched_cipher; } /* EVP_CIPHER_CTX */ ; +struct evp_mac_ctx_st { + EVP_MAC *meth; /* Method structure */ + /* + * Opaque ctx returned from a providers MAC algorithm implementation + * OSSL_FUNC_mac_newctx() + */ + void *algctx; +} /* EVP_MAC_CTX */; + +struct evp_kdf_ctx_st { + EVP_KDF *meth; /* Method structure */ + /* + * Opaque ctx returned from a providers KDF algorithm implementation + * OSSL_FUNC_kdf_newctx() + */ + void *algctx; +} /* EVP_KDF_CTX */ ; + +struct evp_rand_ctx_st { + EVP_RAND *meth; /* Method structure */ + /* + * Opaque ctx returned from a providers rand algorithm implementation + * OSSL_FUNC_rand_newctx() + */ + void *algctx; + EVP_RAND_CTX *parent; /* Parent EVP_RAND or NULL if none */ + CRYPTO_REF_COUNT refcnt; /* Context reference count */ + CRYPTO_RWLOCK *refcnt_lock; +} /* EVP_RAND_CTX */ ; + +struct evp_keymgmt_st { + int id; /* libcrypto internal */ + + int name_id; + char *type_name; + const char *description; + OSSL_PROVIDER *prov; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + /* Constructor(s), destructor, information */ + OSSL_FUNC_keymgmt_new_fn *new; + OSSL_FUNC_keymgmt_free_fn *free; + OSSL_FUNC_keymgmt_get_params_fn *get_params; + OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; + OSSL_FUNC_keymgmt_set_params_fn *set_params; + OSSL_FUNC_keymgmt_settable_params_fn *settable_params; + + /* Generation, a complex constructor */ + OSSL_FUNC_keymgmt_gen_init_fn *gen_init; + OSSL_FUNC_keymgmt_gen_set_template_fn *gen_set_template; + OSSL_FUNC_keymgmt_gen_set_params_fn *gen_set_params; + OSSL_FUNC_keymgmt_gen_settable_params_fn *gen_settable_params; + OSSL_FUNC_keymgmt_gen_fn *gen; + OSSL_FUNC_keymgmt_gen_cleanup_fn *gen_cleanup; + + OSSL_FUNC_keymgmt_load_fn *load; + + /* Key object checking */ + OSSL_FUNC_keymgmt_query_operation_name_fn *query_operation_name; + OSSL_FUNC_keymgmt_has_fn *has; + OSSL_FUNC_keymgmt_validate_fn *validate; + OSSL_FUNC_keymgmt_match_fn *match; + + /* Import and export routines */ + OSSL_FUNC_keymgmt_import_fn *import; + OSSL_FUNC_keymgmt_import_types_fn *import_types; + OSSL_FUNC_keymgmt_export_fn *export; + OSSL_FUNC_keymgmt_export_types_fn *export_types; + OSSL_FUNC_keymgmt_dup_fn *dup; +} /* EVP_KEYMGMT */ ; + +struct evp_keyexch_st { + int name_id; + char *type_name; + const char *description; + OSSL_PROVIDER *prov; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_FUNC_keyexch_newctx_fn *newctx; + OSSL_FUNC_keyexch_init_fn *init; + OSSL_FUNC_keyexch_set_peer_fn *set_peer; + OSSL_FUNC_keyexch_derive_fn *derive; + OSSL_FUNC_keyexch_freectx_fn *freectx; + OSSL_FUNC_keyexch_dupctx_fn *dupctx; + OSSL_FUNC_keyexch_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_keyexch_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_keyexch_get_ctx_params_fn *get_ctx_params; + OSSL_FUNC_keyexch_gettable_ctx_params_fn *gettable_ctx_params; +} /* EVP_KEYEXCH */; + +struct evp_signature_st { + int name_id; + char *type_name; + const char *description; + OSSL_PROVIDER *prov; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_FUNC_signature_newctx_fn *newctx; + OSSL_FUNC_signature_sign_init_fn *sign_init; + OSSL_FUNC_signature_sign_fn *sign; + OSSL_FUNC_signature_verify_init_fn *verify_init; + OSSL_FUNC_signature_verify_fn *verify; + OSSL_FUNC_signature_verify_recover_init_fn *verify_recover_init; + OSSL_FUNC_signature_verify_recover_fn *verify_recover; + OSSL_FUNC_signature_digest_sign_init_fn *digest_sign_init; + OSSL_FUNC_signature_digest_sign_update_fn *digest_sign_update; + OSSL_FUNC_signature_digest_sign_final_fn *digest_sign_final; + OSSL_FUNC_signature_digest_sign_fn *digest_sign; + OSSL_FUNC_signature_digest_verify_init_fn *digest_verify_init; + OSSL_FUNC_signature_digest_verify_update_fn *digest_verify_update; + OSSL_FUNC_signature_digest_verify_final_fn *digest_verify_final; + OSSL_FUNC_signature_digest_verify_fn *digest_verify; + OSSL_FUNC_signature_freectx_fn *freectx; + OSSL_FUNC_signature_dupctx_fn *dupctx; + OSSL_FUNC_signature_get_ctx_params_fn *get_ctx_params; + OSSL_FUNC_signature_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_signature_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_signature_get_ctx_md_params_fn *get_ctx_md_params; + OSSL_FUNC_signature_gettable_ctx_md_params_fn *gettable_ctx_md_params; + OSSL_FUNC_signature_set_ctx_md_params_fn *set_ctx_md_params; + OSSL_FUNC_signature_settable_ctx_md_params_fn *settable_ctx_md_params; +} /* EVP_SIGNATURE */; + +struct evp_asym_cipher_st { + int name_id; + char *type_name; + const char *description; + OSSL_PROVIDER *prov; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_FUNC_asym_cipher_newctx_fn *newctx; + OSSL_FUNC_asym_cipher_encrypt_init_fn *encrypt_init; + OSSL_FUNC_asym_cipher_encrypt_fn *encrypt; + OSSL_FUNC_asym_cipher_decrypt_init_fn *decrypt_init; + OSSL_FUNC_asym_cipher_decrypt_fn *decrypt; + OSSL_FUNC_asym_cipher_freectx_fn *freectx; + OSSL_FUNC_asym_cipher_dupctx_fn *dupctx; + OSSL_FUNC_asym_cipher_get_ctx_params_fn *get_ctx_params; + OSSL_FUNC_asym_cipher_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_FUNC_asym_cipher_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_asym_cipher_settable_ctx_params_fn *settable_ctx_params; +} /* EVP_ASYM_CIPHER */; + +struct evp_kem_st { + int name_id; + char *type_name; + const char *description; + OSSL_PROVIDER *prov; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_FUNC_kem_newctx_fn *newctx; + OSSL_FUNC_kem_encapsulate_init_fn *encapsulate_init; + OSSL_FUNC_kem_encapsulate_fn *encapsulate; + OSSL_FUNC_kem_decapsulate_init_fn *decapsulate_init; + OSSL_FUNC_kem_decapsulate_fn *decapsulate; + OSSL_FUNC_kem_freectx_fn *freectx; + OSSL_FUNC_kem_dupctx_fn *dupctx; + OSSL_FUNC_kem_get_ctx_params_fn *get_ctx_params; + OSSL_FUNC_kem_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_FUNC_kem_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_kem_settable_ctx_params_fn *settable_ctx_params; +} /* EVP_KEM */; + int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, int en_de); +int PKCS5_v2_PBKDF2_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, + int en_de, OSSL_LIB_CTX *libctx, const char *propq); struct evp_Encode_Ctx_st { /* number saved in a partial encode/decode */ @@ -65,4 +258,121 @@ struct evp_Encode_Ctx_st { typedef struct evp_pbe_st EVP_PBE_CTL; DEFINE_STACK_OF(EVP_PBE_CTL) -int is_partially_overlapping(const void *ptr1, const void *ptr2, size_t len); +int ossl_is_partially_overlapping(const void *ptr1, const void *ptr2, int len); + +#include +#include + +void *evp_generic_fetch(OSSL_LIB_CTX *ctx, int operation_id, + const char *name, const char *properties, + void *(*new_method)(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov), + int (*up_ref_method)(void *), + void (*free_method)(void *)); +void *evp_generic_fetch_by_number(OSSL_LIB_CTX *ctx, int operation_id, + int name_id, const char *properties, + void *(*new_method)(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov), + int (*up_ref_method)(void *), + void (*free_method)(void *)); +void *evp_generic_fetch_from_prov(OSSL_PROVIDER *prov, int operation_id, + const char *name, const char *properties, + void *(*new_method)(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov), + int (*up_ref_method)(void *), + void (*free_method)(void *)); +void evp_generic_do_all_prefetched(OSSL_LIB_CTX *libctx, int operation_id, + void (*user_fn)(void *method, void *arg), + void *user_arg); +void evp_generic_do_all(OSSL_LIB_CTX *libctx, int operation_id, + void (*user_fn)(void *method, void *arg), + void *user_arg, + void *(*new_method)(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov), + int (*up_ref_method)(void *), + void (*free_method)(void *)); + +/* Internal fetchers for method types that are to be combined with others */ +EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OSSL_LIB_CTX *ctx, int name_id, + const char *properties); +EVP_SIGNATURE *evp_signature_fetch_from_prov(OSSL_PROVIDER *prov, + const char *name, + const char *properties); +EVP_ASYM_CIPHER *evp_asym_cipher_fetch_from_prov(OSSL_PROVIDER *prov, + const char *name, + const char *properties); +EVP_KEYEXCH *evp_keyexch_fetch_from_prov(OSSL_PROVIDER *prov, + const char *name, + const char *properties); +EVP_KEM *evp_kem_fetch_from_prov(OSSL_PROVIDER *prov, + const char *name, + const char *properties); + +/* Internal structure constructors for fetched methods */ +EVP_MD *evp_md_new(void); +EVP_CIPHER *evp_cipher_new(void); + +int evp_cipher_get_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params); +int evp_cipher_set_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params); + +/* Helper functions to avoid duplicating code */ + +/* + * These methods implement different ways to pass a params array to the + * provider. They will return one of these values: + * + * -2 if the method doesn't come from a provider + * (evp_do_param will return this to the called) + * -1 if the provider doesn't offer the desired function + * (evp_do_param will raise an error and return 0) + * or the return value from the desired function + * (evp_do_param will return it to the caller) + */ +int evp_do_ciph_getparams(const EVP_CIPHER *ciph, OSSL_PARAM params[]); +int evp_do_ciph_ctx_getparams(const EVP_CIPHER *ciph, void *provctx, + OSSL_PARAM params[]); +int evp_do_ciph_ctx_setparams(const EVP_CIPHER *ciph, void *provctx, + OSSL_PARAM params[]); +int evp_do_md_getparams(const EVP_MD *md, OSSL_PARAM params[]); +int evp_do_md_ctx_getparams(const EVP_MD *md, void *provctx, + OSSL_PARAM params[]); +int evp_do_md_ctx_setparams(const EVP_MD *md, void *provctx, + OSSL_PARAM params[]); + +OSSL_PARAM *evp_pkey_to_param(EVP_PKEY *pkey, size_t *sz); + +#define M_check_autoarg(ctx, arg, arglen, err) \ + if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) { \ + size_t pksize = (size_t)EVP_PKEY_get_size(ctx->pkey); \ + \ + if (pksize == 0) { \ + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \ + return 0; \ + } \ + if (arg == NULL) { \ + *arglen = pksize; \ + return 1; \ + } \ + if (*arglen < pksize) { \ + ERR_raise(ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \ + return 0; \ + } \ + } + +void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx); +void evp_cipher_free_int(EVP_CIPHER *md); +void evp_md_free_int(EVP_MD *md); + +/* OSSL_PROVIDER * is only used to get the library context */ +int evp_is_a(OSSL_PROVIDER *prov, int number, + const char *legacy_name, const char *name); +int evp_names_do_all(OSSL_PROVIDER *prov, int number, + void (*fn)(const char *name, void *data), + void *data); +int evp_cipher_cache_constants(EVP_CIPHER *cipher); diff --git a/crypto/openssl/crypto/evp/evp_pbe.c b/crypto/openssl/crypto/evp/evp_pbe.c index 967203f373c9..5f6720d2c3f3 100644 --- a/crypto/openssl/crypto/evp/evp_pbe.c +++ b/crypto/openssl/crypto/evp/evp_pbe.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,8 +10,11 @@ #include #include "internal/cryptlib.h" #include +#include +#include #include #include +#include "crypto/evp.h" #include "evp_local.h" /* Password based encryption (PBE) functions */ @@ -24,41 +27,42 @@ struct evp_pbe_st { int cipher_nid; int md_nid; EVP_PBE_KEYGEN *keygen; + EVP_PBE_KEYGEN_EX *keygen_ex; }; static STACK_OF(EVP_PBE_CTL) *pbe_algs; static const EVP_PBE_CTL builtin_pbe[] = { {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC, - NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen}, + NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC, - NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen}, + NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC, - NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen}, + NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen}, {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4, - NID_rc4, NID_sha1, PKCS12_PBE_keyivgen}, + NID_rc4, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4, - NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen}, + NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, - NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, - NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC, - NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC, - NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, - {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen, &PKCS5_v2_PBE_keyivgen_ex}, {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC, - NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen}, + NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC, - NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen}, + NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC, - NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen}, + NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0}, {EVP_PBE_TYPE_PRF, NID_hmac_md5, -1, NID_md5, 0}, @@ -75,62 +79,90 @@ static const EVP_PBE_CTL builtin_pbe[] = { NID_id_GostR3411_2012_512, 0}, {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512_224, -1, NID_sha512_224, 0}, {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512_256, -1, NID_sha512_256, 0}, - {EVP_PBE_TYPE_KDF, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen}, + {EVP_PBE_TYPE_KDF, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen, &PKCS5_v2_PBKDF2_keyivgen_ex}, #ifndef OPENSSL_NO_SCRYPT - {EVP_PBE_TYPE_KDF, NID_id_scrypt, -1, -1, PKCS5_v2_scrypt_keyivgen} + {EVP_PBE_TYPE_KDF, NID_id_scrypt, -1, -1, PKCS5_v2_scrypt_keyivgen, &PKCS5_v2_scrypt_keyivgen_ex} #endif }; -int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, - ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) + +int EVP_PBE_CipherInit_ex(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de, + OSSL_LIB_CTX *libctx, const char *propq) { - const EVP_CIPHER *cipher; - const EVP_MD *md; - int cipher_nid, md_nid; + const EVP_CIPHER *cipher = NULL; + EVP_CIPHER *cipher_fetch = NULL; + const EVP_MD *md = NULL; + EVP_MD *md_fetch = NULL; + int ret = 0, cipher_nid, md_nid; + EVP_PBE_KEYGEN_EX *keygen_ex; EVP_PBE_KEYGEN *keygen; - if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj), - &cipher_nid, &md_nid, &keygen)) { + if (!EVP_PBE_find_ex(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj), + &cipher_nid, &md_nid, &keygen, &keygen_ex)) { char obj_tmp[80]; - EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_PBE_ALGORITHM); - if (!pbe_obj) + + if (pbe_obj == NULL) OPENSSL_strlcpy(obj_tmp, "NULL", sizeof(obj_tmp)); else i2t_ASN1_OBJECT(obj_tmp, sizeof(obj_tmp), pbe_obj); - ERR_add_error_data(2, "TYPE=", obj_tmp); - return 0; + ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_PBE_ALGORITHM, + "TYPE=%s", obj_tmp); + goto err; } - if (!pass) + if (pass == NULL) passlen = 0; else if (passlen == -1) passlen = strlen(pass); - if (cipher_nid == -1) - cipher = NULL; - else { - cipher = EVP_get_cipherbynid(cipher_nid); - if (!cipher) { - EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_CIPHER); - return 0; + if (cipher_nid != -1) { + (void)ERR_set_mark(); + cipher = cipher_fetch = EVP_CIPHER_fetch(libctx, OBJ_nid2sn(cipher_nid), propq); + /* Fallback to legacy method */ + if (cipher == NULL) + cipher = EVP_get_cipherbynid(cipher_nid); + if (cipher == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_CIPHER, + OBJ_nid2sn(cipher_nid)); + goto err; } + (void)ERR_pop_to_mark(); } - if (md_nid == -1) - md = NULL; - else { - md = EVP_get_digestbynid(md_nid); - if (!md) { - EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_DIGEST); - return 0; + if (md_nid != -1) { + (void)ERR_set_mark(); + md = md_fetch = EVP_MD_fetch(libctx, OBJ_nid2sn(md_nid), propq); + /* Fallback to legacy method */ + if (md == NULL) + EVP_get_digestbynid(md_nid); + + if (md == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_DIGEST); + goto err; } + (void)ERR_pop_to_mark(); } - if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) { - EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_KEYGEN_FAILURE); - return 0; - } - return 1; + /* Try extended keygen with libctx/propq first, fall back to legacy keygen */ + if (keygen_ex != NULL) + ret = keygen_ex(ctx, pass, passlen, param, cipher, md, en_de, libctx, propq); + else + ret = keygen(ctx, pass, passlen, param, cipher, md, en_de); + +err: + EVP_CIPHER_free(cipher_fetch); + EVP_MD_free(md_fetch); + + return ret; +} + +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) +{ + return EVP_PBE_CipherInit_ex(pbe_obj, pass, passlen, param, ctx, en_de, NULL, NULL); } DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); @@ -168,7 +200,7 @@ int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, goto err; } - if ((pbe_tmp = OPENSSL_malloc(sizeof(*pbe_tmp))) == NULL) + if ((pbe_tmp = OPENSSL_zalloc(sizeof(*pbe_tmp))) == NULL) goto err; pbe_tmp->pbe_type = pbe_type; @@ -184,7 +216,7 @@ int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, return 1; err: - EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -194,11 +226,11 @@ int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, int cipher_nid, md_nid; if (cipher) - cipher_nid = EVP_CIPHER_nid(cipher); + cipher_nid = EVP_CIPHER_get_nid(cipher); else cipher_nid = -1; if (md) - md_nid = EVP_MD_type(md); + md_nid = EVP_MD_get_type(md); else md_nid = -1; @@ -206,8 +238,8 @@ int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, cipher_nid, md_nid, keygen); } -int EVP_PBE_find(int type, int pbe_nid, - int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen) +int EVP_PBE_find_ex(int type, int pbe_nid, int *pcnid, int *pmnid, + EVP_PBE_KEYGEN **pkeygen, EVP_PBE_KEYGEN_EX **pkeygen_ex) { EVP_PBE_CTL *pbetmp = NULL, pbelu; int i; @@ -226,15 +258,23 @@ int EVP_PBE_find(int type, int pbe_nid, } if (pbetmp == NULL) return 0; - if (pcnid) + if (pcnid != NULL) *pcnid = pbetmp->cipher_nid; - if (pmnid) + if (pmnid != NULL) *pmnid = pbetmp->md_nid; - if (pkeygen) + if (pkeygen != NULL) *pkeygen = pbetmp->keygen; + if (pkeygen_ex != NULL) + *pkeygen_ex = pbetmp->keygen_ex; return 1; } +int EVP_PBE_find(int type, int pbe_nid, + int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen) +{ + return EVP_PBE_find_ex(type, pbe_nid, pcnid, pmnid, pkeygen, NULL); +} + static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe) { OPENSSL_free(pbe); diff --git a/crypto/openssl/crypto/evp/evp_pkey.c b/crypto/openssl/crypto/evp/evp_pkey.c index 586b74605cbd..8f3f1503756c 100644 --- a/crypto/openssl/crypto/evp/evp_pkey.c +++ b/crypto/openssl/crypto/evp/evp_pkey.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,13 +12,17 @@ #include "internal/cryptlib.h" #include #include +#include +#include +#include "internal/provider.h" #include "crypto/asn1.h" #include "crypto/evp.h" #include "crypto/x509.h" /* Extract a private key from a PKCS8 structure */ -EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8) +EVP_PKEY *evp_pkcs82pkey_legacy(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx, + const char *propq) { EVP_PKEY *pkey = NULL; const ASN1_OBJECT *algoid; @@ -28,24 +32,27 @@ EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8) return NULL; if ((pkey = EVP_PKEY_new()) == NULL) { - EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return NULL; } if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); i2t_ASN1_OBJECT(obj_tmp, 80, algoid); - ERR_add_error_data(2, "TYPE=", obj_tmp); + ERR_raise_data(ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM, + "TYPE=%s", obj_tmp); goto error; } - if (pkey->ameth->priv_decode) { + if (pkey->ameth->priv_decode_ex != NULL) { + if (!pkey->ameth->priv_decode_ex(pkey, p8, libctx, propq)) + goto error; + } else if (pkey->ameth->priv_decode != NULL) { if (!pkey->ameth->priv_decode(pkey, p8)) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_PRIVATE_KEY_DECODE_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_PRIVATE_KEY_DECODE_ERROR); goto error; } } else { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EVP, EVP_R_METHOD_NOT_SUPPORTED); goto error; } @@ -56,34 +63,100 @@ EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8) return NULL; } +EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx, + const char *propq) +{ + EVP_PKEY *pkey = NULL; + const unsigned char *p8_data = NULL; + unsigned char *encoded_data = NULL; + int encoded_len; + int selection; + size_t len; + OSSL_DECODER_CTX *dctx = NULL; + + if ((encoded_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &encoded_data)) <= 0 + || encoded_data == NULL) + return NULL; + + p8_data = encoded_data; + len = encoded_len; + selection = EVP_PKEY_KEYPAIR | EVP_PKEY_KEY_PARAMETERS; + dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", "PrivateKeyInfo", + NULL, selection, libctx, propq); + if (dctx == NULL + || !OSSL_DECODER_from_data(dctx, &p8_data, &len)) + /* try legacy */ + pkey = evp_pkcs82pkey_legacy(p8, libctx, propq); + + OPENSSL_clear_free(encoded_data, encoded_len); + OSSL_DECODER_CTX_free(dctx); + return pkey; +} + +EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8) +{ + return EVP_PKCS82PKEY_ex(p8, NULL, NULL); +} + /* Turn a private key into a PKCS8 structure */ -PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey) { - PKCS8_PRIV_KEY_INFO *p8 = PKCS8_PRIV_KEY_INFO_new(); - if (p8 == NULL) { - EVPerr(EVP_F_EVP_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); - return NULL; - } + PKCS8_PRIV_KEY_INFO *p8 = NULL; + OSSL_ENCODER_CTX *ctx = NULL; + + /* + * The implementation for provider-native keys is to encode the + * key to a DER encoded PKCS#8 structure, then convert it to a + * PKCS8_PRIV_KEY_INFO with good old d2i functions. + */ + if (evp_pkey_is_provided(pkey)) { + int selection = OSSL_KEYMGMT_SELECT_ALL; + unsigned char *der = NULL; + size_t derlen = 0; + const unsigned char *pp; + + if ((ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, + "DER", "PrivateKeyInfo", + NULL)) == NULL + || !OSSL_ENCODER_to_data(ctx, &der, &derlen)) + goto error; + + pp = der; + p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &pp, (long)derlen); + OPENSSL_free(der); + if (p8 == NULL) + goto error; + } else { + p8 = PKCS8_PRIV_KEY_INFO_new(); + if (p8 == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } - if (pkey->ameth) { - if (pkey->ameth->priv_encode) { - if (!pkey->ameth->priv_encode(p8, pkey)) { - EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_PRIVATE_KEY_ENCODE_ERROR); + if (pkey->ameth != NULL) { + if (pkey->ameth->priv_encode != NULL) { + if (!pkey->ameth->priv_encode(p8, pkey)) { + ERR_raise(ERR_LIB_EVP, EVP_R_PRIVATE_KEY_ENCODE_ERROR); + goto error; + } + } else { + ERR_raise(ERR_LIB_EVP, EVP_R_METHOD_NOT_SUPPORTED); goto error; } } else { - EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_METHOD_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); goto error; } - } else { - EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); - goto error; } - return p8; + goto end; error: PKCS8_PRIV_KEY_INFO_free(p8); - return NULL; + p8 = NULL; + end: + OSSL_ENCODER_CTX_free(ctx); + return p8; + } /* EVP_PKEY attribute functions */ @@ -147,3 +220,27 @@ int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, return 1; return 0; } + +const char *EVP_PKEY_get0_type_name(const EVP_PKEY *key) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + const char *name = NULL; + + if (key->keymgmt != NULL) + return EVP_KEYMGMT_get0_name(key->keymgmt); + + /* Otherwise fallback to legacy */ + ameth = EVP_PKEY_get0_asn1(key); + if (ameth != NULL) + EVP_PKEY_asn1_get0_info(NULL, NULL, + NULL, NULL, &name, ameth); + + return name; +} + +const OSSL_PROVIDER *EVP_PKEY_get0_provider(const EVP_PKEY *key) +{ + if (evp_pkey_is_provided(key)) + return EVP_KEYMGMT_get0_provider(key->keymgmt); + return NULL; +} diff --git a/crypto/openssl/crypto/evp/evp_rand.c b/crypto/openssl/crypto/evp/evp_rand.c new file mode 100644 index 000000000000..c36dbdc56c77 --- /dev/null +++ b/crypto/openssl/crypto/evp/evp_rand.c @@ -0,0 +1,682 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/numbers.h" +#include "internal/provider.h" +#include "internal/core.h" +#include "crypto/evp.h" +#include "evp_local.h" + +struct evp_rand_st { + OSSL_PROVIDER *prov; + int name_id; + char *type_name; + const char *description; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *refcnt_lock; + + const OSSL_DISPATCH *dispatch; + OSSL_FUNC_rand_newctx_fn *newctx; + OSSL_FUNC_rand_freectx_fn *freectx; + OSSL_FUNC_rand_instantiate_fn *instantiate; + OSSL_FUNC_rand_uninstantiate_fn *uninstantiate; + OSSL_FUNC_rand_generate_fn *generate; + OSSL_FUNC_rand_reseed_fn *reseed; + OSSL_FUNC_rand_nonce_fn *nonce; + OSSL_FUNC_rand_enable_locking_fn *enable_locking; + OSSL_FUNC_rand_lock_fn *lock; + OSSL_FUNC_rand_unlock_fn *unlock; + OSSL_FUNC_rand_gettable_params_fn *gettable_params; + OSSL_FUNC_rand_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_FUNC_rand_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_rand_get_params_fn *get_params; + OSSL_FUNC_rand_get_ctx_params_fn *get_ctx_params; + OSSL_FUNC_rand_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_rand_verify_zeroization_fn *verify_zeroization; +} /* EVP_RAND */ ; + +static int evp_rand_up_ref(void *vrand) +{ + EVP_RAND *rand = (EVP_RAND *)vrand; + int ref = 0; + + if (rand != NULL) + return CRYPTO_UP_REF(&rand->refcnt, &ref, rand->refcnt_lock); + return 1; +} + +static void evp_rand_free(void *vrand) +{ + EVP_RAND *rand = (EVP_RAND *)vrand; + int ref = 0; + + if (rand == NULL) + return; + CRYPTO_DOWN_REF(&rand->refcnt, &ref, rand->refcnt_lock); + if (ref > 0) + return; + OPENSSL_free(rand->type_name); + ossl_provider_free(rand->prov); + CRYPTO_THREAD_lock_free(rand->refcnt_lock); + OPENSSL_free(rand); +} + +static void *evp_rand_new(void) +{ + EVP_RAND *rand = OPENSSL_zalloc(sizeof(*rand)); + + if (rand == NULL + || (rand->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { + OPENSSL_free(rand); + return NULL; + } + rand->refcnt = 1; + return rand; +} + +/* Enable locking of the underlying DRBG/RAND if available */ +int EVP_RAND_enable_locking(EVP_RAND_CTX *rand) +{ + if (rand->meth->enable_locking != NULL) + return rand->meth->enable_locking(rand->algctx); + ERR_raise(ERR_LIB_EVP, EVP_R_LOCKING_NOT_SUPPORTED); + return 0; +} + +/* Lock the underlying DRBG/RAND if available */ +static int evp_rand_lock(EVP_RAND_CTX *rand) +{ + if (rand->meth->lock != NULL) + return rand->meth->lock(rand->algctx); + return 1; +} + +/* Unlock the underlying DRBG/RAND if available */ +static void evp_rand_unlock(EVP_RAND_CTX *rand) +{ + if (rand->meth->unlock != NULL) + rand->meth->unlock(rand->algctx); +} + +static void *evp_rand_from_algorithm(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + const OSSL_DISPATCH *fns = algodef->implementation; + EVP_RAND *rand = NULL; + int fnrandcnt = 0, fnctxcnt = 0, fnlockcnt = 0, fnenablelockcnt = 0; +#ifdef FIPS_MODULE + int fnzeroizecnt = 0; +#endif + + if ((rand = evp_rand_new()) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + rand->name_id = name_id; + if ((rand->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { + evp_rand_free(rand); + return NULL; + } + rand->description = algodef->algorithm_description; + rand->dispatch = fns; + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_RAND_NEWCTX: + if (rand->newctx != NULL) + break; + rand->newctx = OSSL_FUNC_rand_newctx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_RAND_FREECTX: + if (rand->freectx != NULL) + break; + rand->freectx = OSSL_FUNC_rand_freectx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_RAND_INSTANTIATE: + if (rand->instantiate != NULL) + break; + rand->instantiate = OSSL_FUNC_rand_instantiate(fns); + fnrandcnt++; + break; + case OSSL_FUNC_RAND_UNINSTANTIATE: + if (rand->uninstantiate != NULL) + break; + rand->uninstantiate = OSSL_FUNC_rand_uninstantiate(fns); + fnrandcnt++; + break; + case OSSL_FUNC_RAND_GENERATE: + if (rand->generate != NULL) + break; + rand->generate = OSSL_FUNC_rand_generate(fns); + fnrandcnt++; + break; + case OSSL_FUNC_RAND_RESEED: + if (rand->reseed != NULL) + break; + rand->reseed = OSSL_FUNC_rand_reseed(fns); + break; + case OSSL_FUNC_RAND_NONCE: + if (rand->nonce != NULL) + break; + rand->nonce = OSSL_FUNC_rand_nonce(fns); + break; + case OSSL_FUNC_RAND_ENABLE_LOCKING: + if (rand->enable_locking != NULL) + break; + rand->enable_locking = OSSL_FUNC_rand_enable_locking(fns); + fnenablelockcnt++; + break; + case OSSL_FUNC_RAND_LOCK: + if (rand->lock != NULL) + break; + rand->lock = OSSL_FUNC_rand_lock(fns); + fnlockcnt++; + break; + case OSSL_FUNC_RAND_UNLOCK: + if (rand->unlock != NULL) + break; + rand->unlock = OSSL_FUNC_rand_unlock(fns); + fnlockcnt++; + break; + case OSSL_FUNC_RAND_GETTABLE_PARAMS: + if (rand->gettable_params != NULL) + break; + rand->gettable_params = + OSSL_FUNC_rand_gettable_params(fns); + break; + case OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS: + if (rand->gettable_ctx_params != NULL) + break; + rand->gettable_ctx_params = + OSSL_FUNC_rand_gettable_ctx_params(fns); + break; + case OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS: + if (rand->settable_ctx_params != NULL) + break; + rand->settable_ctx_params = + OSSL_FUNC_rand_settable_ctx_params(fns); + break; + case OSSL_FUNC_RAND_GET_PARAMS: + if (rand->get_params != NULL) + break; + rand->get_params = OSSL_FUNC_rand_get_params(fns); + break; + case OSSL_FUNC_RAND_GET_CTX_PARAMS: + if (rand->get_ctx_params != NULL) + break; + rand->get_ctx_params = OSSL_FUNC_rand_get_ctx_params(fns); + fnctxcnt++; + break; + case OSSL_FUNC_RAND_SET_CTX_PARAMS: + if (rand->set_ctx_params != NULL) + break; + rand->set_ctx_params = OSSL_FUNC_rand_set_ctx_params(fns); + break; + case OSSL_FUNC_RAND_VERIFY_ZEROIZATION: + if (rand->verify_zeroization != NULL) + break; + rand->verify_zeroization = OSSL_FUNC_rand_verify_zeroization(fns); +#ifdef FIPS_MODULE + fnzeroizecnt++; +#endif + break; + } + } + /* + * In order to be a consistent set of functions we must have at least + * a complete set of "rand" functions and a complete set of context + * management functions. In FIPS mode, we also require the zeroization + * verification function. + * + * In addition, if locking can be enabled, we need a complete set of + * locking functions. + */ + if (fnrandcnt != 3 + || fnctxcnt != 3 + || (fnenablelockcnt != 0 && fnenablelockcnt != 1) + || (fnlockcnt != 0 && fnlockcnt != 2) +#ifdef FIPS_MODULE + || fnzeroizecnt != 1 +#endif + ) { + evp_rand_free(rand); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + + if (prov != NULL && !ossl_provider_up_ref(prov)) { + evp_rand_free(rand); + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return NULL; + } + rand->prov = prov; + + return rand; +} + +EVP_RAND *EVP_RAND_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties, + evp_rand_from_algorithm, evp_rand_up_ref, + evp_rand_free); +} + +int EVP_RAND_up_ref(EVP_RAND *rand) +{ + return evp_rand_up_ref(rand); +} + +void EVP_RAND_free(EVP_RAND *rand) +{ + evp_rand_free(rand); +} + +int evp_rand_get_number(const EVP_RAND *rand) +{ + return rand->name_id; +} + +const char *EVP_RAND_get0_name(const EVP_RAND *rand) +{ + return rand->type_name; +} + +const char *EVP_RAND_get0_description(const EVP_RAND *rand) +{ + return rand->description; +} + +int EVP_RAND_is_a(const EVP_RAND *rand, const char *name) +{ + return rand != NULL && evp_is_a(rand->prov, rand->name_id, NULL, name); +} + +const OSSL_PROVIDER *EVP_RAND_get0_provider(const EVP_RAND *rand) +{ + return rand->prov; +} + +int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[]) +{ + if (rand->get_params != NULL) + return rand->get_params(params); + return 1; +} + +static int evp_rand_ctx_up_ref(EVP_RAND_CTX *ctx) +{ + int ref = 0; + + return CRYPTO_UP_REF(&ctx->refcnt, &ref, ctx->refcnt_lock); +} + +EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) +{ + EVP_RAND_CTX *ctx; + void *parent_ctx = NULL; + const OSSL_DISPATCH *parent_dispatch = NULL; + + if (rand == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_NULL_ALGORITHM); + return NULL; + } + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL || (ctx->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { + OPENSSL_free(ctx); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (parent != NULL) { + if (!evp_rand_ctx_up_ref(parent)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + CRYPTO_THREAD_lock_free(ctx->refcnt_lock); + OPENSSL_free(ctx); + return NULL; + } + parent_ctx = parent->algctx; + parent_dispatch = parent->meth->dispatch; + } + if ((ctx->algctx = rand->newctx(ossl_provider_ctx(rand->prov), parent_ctx, + parent_dispatch)) == NULL + || !EVP_RAND_up_ref(rand)) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + rand->freectx(ctx->algctx); + CRYPTO_THREAD_lock_free(ctx->refcnt_lock); + OPENSSL_free(ctx); + EVP_RAND_CTX_free(parent); + return NULL; + } + ctx->meth = rand; + ctx->parent = parent; + ctx->refcnt = 1; + return ctx; +} + +void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx) +{ + int ref = 0; + EVP_RAND_CTX *parent; + + if (ctx == NULL) + return; + + CRYPTO_DOWN_REF(&ctx->refcnt, &ref, ctx->refcnt_lock); + if (ref > 0) + return; + parent = ctx->parent; + ctx->meth->freectx(ctx->algctx); + ctx->algctx = NULL; + EVP_RAND_free(ctx->meth); + CRYPTO_THREAD_lock_free(ctx->refcnt_lock); + OPENSSL_free(ctx); + EVP_RAND_CTX_free(parent); +} + +EVP_RAND *EVP_RAND_CTX_get0_rand(EVP_RAND_CTX *ctx) +{ + return ctx->meth; +} + +static int evp_rand_get_ctx_params_locked(EVP_RAND_CTX *ctx, + OSSL_PARAM params[]) +{ + return ctx->meth->get_ctx_params(ctx->algctx, params); +} + +int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[]) +{ + int res; + + if (!evp_rand_lock(ctx)) + return 0; + res = evp_rand_get_ctx_params_locked(ctx, params); + evp_rand_unlock(ctx); + return res; +} + +static int evp_rand_set_ctx_params_locked(EVP_RAND_CTX *ctx, + const OSSL_PARAM params[]) +{ + if (ctx->meth->set_ctx_params != NULL) + return ctx->meth->set_ctx_params(ctx->algctx, params); + return 1; +} + +int EVP_RAND_CTX_set_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[]) +{ + int res; + + if (!evp_rand_lock(ctx)) + return 0; + res = evp_rand_set_ctx_params_locked(ctx, params); + evp_rand_unlock(ctx); + return res; +} + +const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand) +{ + if (rand->gettable_params == NULL) + return NULL; + return rand->gettable_params(ossl_provider_ctx(EVP_RAND_get0_provider(rand))); +} + +const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand) +{ + void *provctx; + + if (rand->gettable_ctx_params == NULL) + return NULL; + provctx = ossl_provider_ctx(EVP_RAND_get0_provider(rand)); + return rand->gettable_ctx_params(NULL, provctx); +} + +const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand) +{ + void *provctx; + + if (rand->settable_ctx_params == NULL) + return NULL; + provctx = ossl_provider_ctx(EVP_RAND_get0_provider(rand)); + return rand->settable_ctx_params(NULL, provctx); +} + +const OSSL_PARAM *EVP_RAND_CTX_gettable_params(EVP_RAND_CTX *ctx) +{ + void *provctx; + + if (ctx->meth->gettable_ctx_params == NULL) + return NULL; + provctx = ossl_provider_ctx(EVP_RAND_get0_provider(ctx->meth)); + return ctx->meth->gettable_ctx_params(ctx->algctx, provctx); +} + +const OSSL_PARAM *EVP_RAND_CTX_settable_params(EVP_RAND_CTX *ctx) +{ + void *provctx; + + if (ctx->meth->settable_ctx_params == NULL) + return NULL; + provctx = ossl_provider_ctx(EVP_RAND_get0_provider(ctx->meth)); + return ctx->meth->settable_ctx_params(ctx->algctx, provctx); +} + +void EVP_RAND_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_RAND *rand, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_RAND, + (void (*)(void *, void *))fn, arg, + evp_rand_from_algorithm, evp_rand_up_ref, + evp_rand_free); +} + +int EVP_RAND_names_do_all(const EVP_RAND *rand, + void (*fn)(const char *name, void *data), + void *data) +{ + if (rand->prov != NULL) + return evp_names_do_all(rand->prov, rand->name_id, fn, data); + + return 1; +} + +static int evp_rand_instantiate_locked + (EVP_RAND_CTX *ctx, unsigned int strength, int prediction_resistance, + const unsigned char *pstr, size_t pstr_len, const OSSL_PARAM params[]) +{ + return ctx->meth->instantiate(ctx->algctx, strength, prediction_resistance, + pstr, pstr_len, params); +} + +int EVP_RAND_instantiate(EVP_RAND_CTX *ctx, unsigned int strength, + int prediction_resistance, + const unsigned char *pstr, size_t pstr_len, + const OSSL_PARAM params[]) +{ + int res; + + if (!evp_rand_lock(ctx)) + return 0; + res = evp_rand_instantiate_locked(ctx, strength, prediction_resistance, + pstr, pstr_len, params); + evp_rand_unlock(ctx); + return res; +} + +static int evp_rand_uninstantiate_locked(EVP_RAND_CTX *ctx) +{ + return ctx->meth->uninstantiate(ctx->algctx); +} + +int EVP_RAND_uninstantiate(EVP_RAND_CTX *ctx) +{ + int res; + + if (!evp_rand_lock(ctx)) + return 0; + res = evp_rand_uninstantiate_locked(ctx); + evp_rand_unlock(ctx); + return res; +} + +static int evp_rand_generate_locked(EVP_RAND_CTX *ctx, unsigned char *out, + size_t outlen, unsigned int strength, + int prediction_resistance, + const unsigned char *addin, + size_t addin_len) +{ + size_t chunk, max_request = 0; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_RAND_PARAM_MAX_REQUEST, + &max_request); + if (!evp_rand_get_ctx_params_locked(ctx, params) + || max_request == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE); + return 0; + } + for (; outlen > 0; outlen -= chunk, out += chunk) { + chunk = outlen > max_request ? max_request : outlen; + if (!ctx->meth->generate(ctx->algctx, out, chunk, strength, + prediction_resistance, addin, addin_len)) { + ERR_raise(ERR_LIB_EVP, EVP_R_GENERATE_ERROR); + return 0; + } + /* + * Prediction resistance is only relevant the first time around, + * subsequently, the DRBG has already been properly reseeded. + */ + prediction_resistance = 0; + } + return 1; +} + +int EVP_RAND_generate(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen, + unsigned int strength, int prediction_resistance, + const unsigned char *addin, size_t addin_len) +{ + int res; + + if (!evp_rand_lock(ctx)) + return 0; + res = evp_rand_generate_locked(ctx, out, outlen, strength, + prediction_resistance, addin, addin_len); + evp_rand_unlock(ctx); + return res; +} + +static int evp_rand_reseed_locked(EVP_RAND_CTX *ctx, int prediction_resistance, + const unsigned char *ent, size_t ent_len, + const unsigned char *addin, size_t addin_len) +{ + if (ctx->meth->reseed != NULL) + return ctx->meth->reseed(ctx->algctx, prediction_resistance, + ent, ent_len, addin, addin_len); + return 1; +} + +int EVP_RAND_reseed(EVP_RAND_CTX *ctx, int prediction_resistance, + const unsigned char *ent, size_t ent_len, + const unsigned char *addin, size_t addin_len) +{ + int res; + + if (!evp_rand_lock(ctx)) + return 0; + res = evp_rand_reseed_locked(ctx, prediction_resistance, + ent, ent_len, addin, addin_len); + evp_rand_unlock(ctx); + return res; +} + +static unsigned int evp_rand_strength_locked(EVP_RAND_CTX *ctx) +{ + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + unsigned int strength = 0; + + params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, &strength); + if (!evp_rand_get_ctx_params_locked(ctx, params)) + return 0; + return strength; +} + +unsigned int EVP_RAND_get_strength(EVP_RAND_CTX *ctx) +{ + unsigned int res; + + if (!evp_rand_lock(ctx)) + return 0; + res = evp_rand_strength_locked(ctx); + evp_rand_unlock(ctx); + return res; +} + +static int evp_rand_nonce_locked(EVP_RAND_CTX *ctx, unsigned char *out, + size_t outlen) +{ + unsigned int str = evp_rand_strength_locked(ctx); + + if (ctx->meth->nonce == NULL) + return 0; + if (ctx->meth->nonce(ctx->algctx, out, str, outlen, outlen)) + return 1; + return evp_rand_generate_locked(ctx, out, outlen, str, 0, NULL, 0); +} + +int EVP_RAND_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen) +{ + int res; + + if (!evp_rand_lock(ctx)) + return 0; + res = evp_rand_nonce_locked(ctx, out, outlen); + evp_rand_unlock(ctx); + return res; +} + +int EVP_RAND_get_state(EVP_RAND_CTX *ctx) +{ + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + int state; + + params[0] = OSSL_PARAM_construct_int(OSSL_RAND_PARAM_STATE, &state); + if (!EVP_RAND_CTX_get_params(ctx, params)) + state = EVP_RAND_STATE_ERROR; + return state; +} + +static int evp_rand_verify_zeroization_locked(EVP_RAND_CTX *ctx) +{ + if (ctx->meth->verify_zeroization != NULL) + return ctx->meth->verify_zeroization(ctx->algctx); + return 0; +} + +int EVP_RAND_verify_zeroization(EVP_RAND_CTX *ctx) +{ + int res; + + if (!evp_rand_lock(ctx)) + return 0; + res = evp_rand_verify_zeroization_locked(ctx); + evp_rand_unlock(ctx); + return res; +} diff --git a/crypto/openssl/crypto/evp/evp_utils.c b/crypto/openssl/crypto/evp/evp_utils.c new file mode 100644 index 000000000000..3cc17921f8f4 --- /dev/null +++ b/crypto/openssl/crypto/evp/evp_utils.c @@ -0,0 +1,81 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* Internal EVP utility functions */ + +#include +#include +#include +#include /* evp_local.h needs it */ +#include /* evp_local.h needs it */ +#include "crypto/evp.h" /* evp_local.h needs it */ +#include "evp_local.h" + +/* + * EVP_CTRL_RET_UNSUPPORTED = -1 is the returned value from any ctrl function + * where the control command isn't supported, and an alternative code path + * may be chosen. + * Since these functions are used to implement ctrl functionality, we + * use the same value, and other callers will have to compensate. + */ +#define PARAM_CHECK(obj, func, errfunc) \ + if (obj == NULL) \ + return 0; \ + if (obj->prov == NULL) \ + return EVP_CTRL_RET_UNSUPPORTED; \ + if (obj->func == NULL) { \ + errfunc(); \ + return 0; \ + } + +#define PARAM_FUNC(name, func, type, err) \ +int name (const type *obj, OSSL_PARAM params[]) \ +{ \ + PARAM_CHECK(obj, func, err) \ + return obj->func(params); \ +} + +#define PARAM_CTX_FUNC(name, func, type, err) \ +int name (const type *obj, void *algctx, OSSL_PARAM params[]) \ +{ \ + PARAM_CHECK(obj, func, err) \ + return obj->func(algctx, params); \ +} + +#define PARAM_FUNCTIONS(type, \ + getname, getfunc, \ + getctxname, getctxfunc, \ + setctxname, setctxfunc) \ + PARAM_FUNC(getname, getfunc, type, geterr) \ + PARAM_CTX_FUNC(getctxname, getctxfunc, type, geterr) \ + PARAM_CTX_FUNC(setctxname, setctxfunc, type, seterr) + +/* + * These error functions are a workaround for the error scripts, which + * currently require that XXXerr method appears inside a function (not a macro). + */ +static void geterr(void) +{ + ERR_raise(ERR_LIB_EVP, EVP_R_CANNOT_GET_PARAMETERS); +} + +static void seterr(void) +{ + ERR_raise(ERR_LIB_EVP, EVP_R_CANNOT_SET_PARAMETERS); +} + +PARAM_FUNCTIONS(EVP_CIPHER, + evp_do_ciph_getparams, get_params, + evp_do_ciph_ctx_getparams, get_ctx_params, + evp_do_ciph_ctx_setparams, set_ctx_params) + +PARAM_FUNCTIONS(EVP_MD, + evp_do_md_getparams, get_params, + evp_do_md_ctx_getparams, get_ctx_params, + evp_do_md_ctx_setparams, set_ctx_params) diff --git a/crypto/openssl/crypto/evp/exchange.c b/crypto/openssl/crypto/evp/exchange.c new file mode 100644 index 000000000000..d7a4ad142aa7 --- /dev/null +++ b/crypto/openssl/crypto/evp/exchange.c @@ -0,0 +1,597 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/refcount.h" +#include "internal/provider.h" +#include "internal/core.h" +#include "internal/numbers.h" /* includes SIZE_MAX */ +#include "crypto/evp.h" +#include "evp_local.h" + +static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov) +{ + EVP_KEYEXCH *exchange = OPENSSL_zalloc(sizeof(EVP_KEYEXCH)); + + if (exchange == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + exchange->lock = CRYPTO_THREAD_lock_new(); + if (exchange->lock == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(exchange); + return NULL; + } + exchange->prov = prov; + ossl_provider_up_ref(prov); + exchange->refcnt = 1; + + return exchange; +} + +static void *evp_keyexch_from_algorithm(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + const OSSL_DISPATCH *fns = algodef->implementation; + EVP_KEYEXCH *exchange = NULL; + int fncnt = 0, sparamfncnt = 0, gparamfncnt = 0; + + if ((exchange = evp_keyexch_new(prov)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + exchange->name_id = name_id; + if ((exchange->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) + goto err; + exchange->description = algodef->algorithm_description; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_KEYEXCH_NEWCTX: + if (exchange->newctx != NULL) + break; + exchange->newctx = OSSL_FUNC_keyexch_newctx(fns); + fncnt++; + break; + case OSSL_FUNC_KEYEXCH_INIT: + if (exchange->init != NULL) + break; + exchange->init = OSSL_FUNC_keyexch_init(fns); + fncnt++; + break; + case OSSL_FUNC_KEYEXCH_SET_PEER: + if (exchange->set_peer != NULL) + break; + exchange->set_peer = OSSL_FUNC_keyexch_set_peer(fns); + break; + case OSSL_FUNC_KEYEXCH_DERIVE: + if (exchange->derive != NULL) + break; + exchange->derive = OSSL_FUNC_keyexch_derive(fns); + fncnt++; + break; + case OSSL_FUNC_KEYEXCH_FREECTX: + if (exchange->freectx != NULL) + break; + exchange->freectx = OSSL_FUNC_keyexch_freectx(fns); + fncnt++; + break; + case OSSL_FUNC_KEYEXCH_DUPCTX: + if (exchange->dupctx != NULL) + break; + exchange->dupctx = OSSL_FUNC_keyexch_dupctx(fns); + break; + case OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS: + if (exchange->get_ctx_params != NULL) + break; + exchange->get_ctx_params = OSSL_FUNC_keyexch_get_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS: + if (exchange->gettable_ctx_params != NULL) + break; + exchange->gettable_ctx_params + = OSSL_FUNC_keyexch_gettable_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS: + if (exchange->set_ctx_params != NULL) + break; + exchange->set_ctx_params = OSSL_FUNC_keyexch_set_ctx_params(fns); + sparamfncnt++; + break; + case OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS: + if (exchange->settable_ctx_params != NULL) + break; + exchange->settable_ctx_params + = OSSL_FUNC_keyexch_settable_ctx_params(fns); + sparamfncnt++; + break; + } + } + if (fncnt != 4 + || (gparamfncnt != 0 && gparamfncnt != 2) + || (sparamfncnt != 0 && sparamfncnt != 2)) { + /* + * In order to be a consistent set of functions we must have at least + * a complete set of "exchange" functions: init, derive, newctx, + * and freectx. The set_ctx_params and settable_ctx_params functions are + * optional, but if one of them is present then the other one must also + * be present. Same goes for get_ctx_params and gettable_ctx_params. + * The dupctx and set_peer functions are optional. + */ + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + goto err; + } + + return exchange; + + err: + EVP_KEYEXCH_free(exchange); + return NULL; +} + +void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange) +{ + int i; + + if (exchange == NULL) + return; + CRYPTO_DOWN_REF(&exchange->refcnt, &i, exchange->lock); + if (i > 0) + return; + OPENSSL_free(exchange->type_name); + ossl_provider_free(exchange->prov); + CRYPTO_THREAD_lock_free(exchange->lock); + OPENSSL_free(exchange); +} + +int EVP_KEYEXCH_up_ref(EVP_KEYEXCH *exchange) +{ + int ref = 0; + + CRYPTO_UP_REF(&exchange->refcnt, &ref, exchange->lock); + return 1; +} + +OSSL_PROVIDER *EVP_KEYEXCH_get0_provider(const EVP_KEYEXCH *exchange) +{ + return exchange->prov; +} + +EVP_KEYEXCH *EVP_KEYEXCH_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties, + evp_keyexch_from_algorithm, + (int (*)(void *))EVP_KEYEXCH_up_ref, + (void (*)(void *))EVP_KEYEXCH_free); +} + +EVP_KEYEXCH *evp_keyexch_fetch_from_prov(OSSL_PROVIDER *prov, + const char *algorithm, + const char *properties) +{ + return evp_generic_fetch_from_prov(prov, OSSL_OP_KEYEXCH, + algorithm, properties, + evp_keyexch_from_algorithm, + (int (*)(void *))EVP_KEYEXCH_up_ref, + (void (*)(void *))EVP_KEYEXCH_free); +} + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_derive_init_ex(ctx, NULL); +} + +int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) +{ + int ret; + void *provkey = NULL; + EVP_KEYEXCH *exchange = NULL; + EVP_KEYMGMT *tmp_keymgmt = NULL; + const OSSL_PROVIDER *tmp_prov = NULL; + const char *supported_exch = NULL; + int iter; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return -2; + } + + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = EVP_PKEY_OP_DERIVE; + + ERR_set_mark(); + + if (evp_pkey_ctx_is_legacy(ctx)) + goto legacy; + + /* + * Some algorithms (e.g. legacy KDFs) don't have a pkey - so we create + * a blank one. + */ + if (ctx->pkey == NULL) { + EVP_PKEY *pkey = EVP_PKEY_new(); + + if (pkey == NULL + || !EVP_PKEY_set_type_by_keymgmt(pkey, ctx->keymgmt) + || (pkey->keydata = evp_keymgmt_newdata(ctx->keymgmt)) == NULL) { + ERR_clear_last_mark(); + EVP_PKEY_free(pkey); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + ctx->pkey = pkey; + } + + /* + * Try to derive the supported exch from |ctx->keymgmt|. + */ + if (!ossl_assert(ctx->pkey->keymgmt == NULL + || ctx->pkey->keymgmt == ctx->keymgmt)) { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + goto err; + } + supported_exch = evp_keymgmt_util_query_operation_name(ctx->keymgmt, + OSSL_OP_KEYEXCH); + if (supported_exch == NULL) { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + + /* + * We perform two iterations: + * + * 1. Do the normal exchange fetch, using the fetching data given by + * the EVP_PKEY_CTX. + * 2. Do the provider specific exchange fetch, from the same provider + * as |ctx->keymgmt| + * + * We then try to fetch the keymgmt from the same provider as the + * exchange, and try to export |ctx->pkey| to that keymgmt (when + * this keymgmt happens to be the same as |ctx->keymgmt|, the export + * is a no-op, but we call it anyway to not complicate the code even + * more). + * If the export call succeeds (returns a non-NULL provider key pointer), + * we're done and can perform the operation itself. If not, we perform + * the second iteration, or jump to legacy. + */ + for (iter = 1, provkey = NULL; iter < 3 && provkey == NULL; iter++) { + EVP_KEYMGMT *tmp_keymgmt_tofree = NULL; + + /* + * If we're on the second iteration, free the results from the first. + * They are NULL on the first iteration, so no need to check what + * iteration we're on. + */ + EVP_KEYEXCH_free(exchange); + EVP_KEYMGMT_free(tmp_keymgmt); + + switch (iter) { + case 1: + exchange = + EVP_KEYEXCH_fetch(ctx->libctx, supported_exch, ctx->propquery); + if (exchange != NULL) + tmp_prov = EVP_KEYEXCH_get0_provider(exchange); + break; + case 2: + tmp_prov = EVP_KEYMGMT_get0_provider(ctx->keymgmt); + exchange = + evp_keyexch_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, + supported_exch, ctx->propquery); + if (exchange == NULL) + goto legacy; + break; + } + if (exchange == NULL) + continue; + + /* + * Ensure that the key is provided, either natively, or as a cached + * export. We start by fetching the keymgmt with the same name as + * |ctx->keymgmt|, but from the provider of the exchange method, using + * the same property query as when fetching the exchange method. + * With the keymgmt we found (if we did), we try to export |ctx->pkey| + * to it (evp_pkey_export_to_provider() is smart enough to only actually + * export it if |tmp_keymgmt| is different from |ctx->pkey|'s keymgmt) + */ + tmp_keymgmt_tofree = tmp_keymgmt = + evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, + EVP_KEYMGMT_get0_name(ctx->keymgmt), + ctx->propquery); + if (tmp_keymgmt != NULL) + provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, + &tmp_keymgmt, ctx->propquery); + if (tmp_keymgmt == NULL) + EVP_KEYMGMT_free(tmp_keymgmt_tofree); + } + + if (provkey == NULL) { + EVP_KEYEXCH_free(exchange); + goto legacy; + } + + ERR_pop_to_mark(); + + /* No more legacy from here down to legacy: */ + + ctx->op.kex.exchange = exchange; + ctx->op.kex.algctx = exchange->newctx(ossl_provider_ctx(exchange->prov)); + if (ctx->op.kex.algctx == NULL) { + /* The provider key can stay in the cache */ + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + ret = exchange->init(ctx->op.kex.algctx, provkey, params); + + EVP_KEYMGMT_free(tmp_keymgmt); + return ret ? 1 : 0; + err: + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = EVP_PKEY_OP_UNDEFINED; + EVP_KEYMGMT_free(tmp_keymgmt); + return 0; + + legacy: + /* + * If we don't have the full support we need with provided methods, + * let's go see if legacy does. + */ + ERR_pop_to_mark(); + +#ifdef FIPS_MODULE + return 0; +#else + if (ctx->pmeth == NULL || ctx->pmeth->derive == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->pmeth->derive_init == NULL) + return 1; + ret = ctx->pmeth->derive_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + EVP_KEYMGMT_free(tmp_keymgmt); + return ret; +#endif +} + +int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer, + int validate_peer) +{ + int ret = 0, check; + void *provkey = NULL; + EVP_PKEY_CTX *check_ctx = NULL; + EVP_KEYMGMT *tmp_keymgmt = NULL, *tmp_keymgmt_tofree = NULL; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx) || ctx->op.kex.algctx == NULL) + goto legacy; + + if (ctx->op.kex.exchange->set_peer == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (validate_peer) { + check_ctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, peer, ctx->propquery); + if (check_ctx == NULL) + return -1; + check = EVP_PKEY_public_check(check_ctx); + EVP_PKEY_CTX_free(check_ctx); + if (check <= 0) + return -1; + } + + /* + * Ensure that the |peer| is provided, either natively, or as a cached + * export. We start by fetching the keymgmt with the same name as + * |ctx->keymgmt|, but from the provider of the exchange method, using + * the same property query as when fetching the exchange method. + * With the keymgmt we found (if we did), we try to export |peer| + * to it (evp_pkey_export_to_provider() is smart enough to only actually + * export it if |tmp_keymgmt| is different from |peer|'s keymgmt) + */ + tmp_keymgmt_tofree = tmp_keymgmt = + evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *) + EVP_KEYEXCH_get0_provider(ctx->op.kex.exchange), + EVP_KEYMGMT_get0_name(ctx->keymgmt), + ctx->propquery); + if (tmp_keymgmt != NULL) + provkey = evp_pkey_export_to_provider(peer, ctx->libctx, + &tmp_keymgmt, ctx->propquery); + EVP_KEYMGMT_free(tmp_keymgmt_tofree); + + /* + * If making the key provided wasn't possible, legacy may be able to pick + * it up + */ + if (provkey == NULL) + goto legacy; + return ctx->op.kex.exchange->set_peer(ctx->op.kex.algctx, provkey); + + legacy: +#ifdef FIPS_MODULE + return ret; +#else + if (ctx->pmeth == NULL + || !(ctx->pmeth->derive != NULL + || ctx->pmeth->encrypt != NULL + || ctx->pmeth->decrypt != NULL) + || ctx->pmeth->ctrl == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE + && ctx->operation != EVP_PKEY_OP_ENCRYPT + && ctx->operation != EVP_PKEY_OP_DECRYPT) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); + return -1; + } + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); + + if (ret <= 0) + return ret; + + if (ret == 2) + return 1; + + if (ctx->pkey == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); + return -1; + } + + if (ctx->pkey->type != peer->type) { + ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); + return -1; + } + + /* + * For clarity. The error is if parameters in peer are + * present (!missing) but don't match. EVP_PKEY_parameters_eq may return + * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 + * (different key types) is impossible here because it is checked earlier. + * -2 is OK for us here, as well as 1, so we can check for 0 only. + */ + if (!EVP_PKEY_missing_parameters(peer) && + !EVP_PKEY_parameters_eq(ctx->pkey, peer)) { + ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_PARAMETERS); + return -1; + } + + EVP_PKEY_free(ctx->peerkey); + ctx->peerkey = peer; + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); + + if (ret <= 0) { + ctx->peerkey = NULL; + return ret; + } + + EVP_PKEY_up_ref(peer); + return 1; +#endif +} + +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) +{ + return EVP_PKEY_derive_set_peer_ex(ctx, peer, 1); +} + +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) +{ + int ret; + + if (ctx == NULL || pkeylen == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.kex.algctx == NULL) + goto legacy; + + ret = ctx->op.kex.exchange->derive(ctx->op.kex.algctx, key, pkeylen, + key != NULL ? *pkeylen : 0); + + return ret; + legacy: + if (ctx->pmeth == NULL || ctx->pmeth->derive == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) + return ctx->pmeth->derive(ctx, key, pkeylen); +} + +int evp_keyexch_get_number(const EVP_KEYEXCH *keyexch) +{ + return keyexch->name_id; +} + +const char *EVP_KEYEXCH_get0_name(const EVP_KEYEXCH *keyexch) +{ + return keyexch->type_name; +} + +const char *EVP_KEYEXCH_get0_description(const EVP_KEYEXCH *keyexch) +{ + return keyexch->description; +} + +int EVP_KEYEXCH_is_a(const EVP_KEYEXCH *keyexch, const char *name) +{ + return keyexch != NULL + && evp_is_a(keyexch->prov, keyexch->name_id, NULL, name); +} + +void EVP_KEYEXCH_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_KEYEXCH *keyexch, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_KEYEXCH, + (void (*)(void *, void *))fn, arg, + evp_keyexch_from_algorithm, + (int (*)(void *))EVP_KEYEXCH_up_ref, + (void (*)(void *))EVP_KEYEXCH_free); +} + +int EVP_KEYEXCH_names_do_all(const EVP_KEYEXCH *keyexch, + void (*fn)(const char *name, void *data), + void *data) +{ + if (keyexch->prov != NULL) + return evp_names_do_all(keyexch->prov, keyexch->name_id, fn, data); + + return 1; +} + +const OSSL_PARAM *EVP_KEYEXCH_gettable_ctx_params(const EVP_KEYEXCH *keyexch) +{ + void *provctx; + + if (keyexch == NULL || keyexch->gettable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_KEYEXCH_get0_provider(keyexch)); + return keyexch->gettable_ctx_params(NULL, provctx); +} + +const OSSL_PARAM *EVP_KEYEXCH_settable_ctx_params(const EVP_KEYEXCH *keyexch) +{ + void *provctx; + + if (keyexch == NULL || keyexch->settable_ctx_params == NULL) + return NULL; + provctx = ossl_provider_ctx(EVP_KEYEXCH_get0_provider(keyexch)); + return keyexch->settable_ctx_params(NULL, provctx); +} diff --git a/crypto/openssl/crypto/evp/kdf_lib.c b/crypto/openssl/crypto/evp/kdf_lib.c new file mode 100644 index 000000000000..6a6bb31e6372 --- /dev/null +++ b/crypto/openssl/crypto/evp/kdf_lib.c @@ -0,0 +1,184 @@ +/* + * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include +#include "crypto/evp.h" +#include "internal/numbers.h" +#include "internal/provider.h" +#include "evp_local.h" + +EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf) +{ + EVP_KDF_CTX *ctx = NULL; + + if (kdf == NULL) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(EVP_KDF_CTX)); + if (ctx == NULL + || (ctx->algctx = kdf->newctx(ossl_provider_ctx(kdf->prov))) == NULL + || !EVP_KDF_up_ref(kdf)) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (ctx != NULL) + kdf->freectx(ctx->algctx); + OPENSSL_free(ctx); + ctx = NULL; + } else { + ctx->meth = kdf; + } + return ctx; +} + +void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx) +{ + if (ctx == NULL) + return; + ctx->meth->freectx(ctx->algctx); + ctx->algctx = NULL; + EVP_KDF_free(ctx->meth); + OPENSSL_free(ctx); +} + +EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src) +{ + EVP_KDF_CTX *dst; + + if (src == NULL || src->algctx == NULL || src->meth->dupctx == NULL) + return NULL; + + dst = OPENSSL_malloc(sizeof(*dst)); + if (dst == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + memcpy(dst, src, sizeof(*dst)); + if (!EVP_KDF_up_ref(dst->meth)) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(dst); + return NULL; + } + + dst->algctx = src->meth->dupctx(src->algctx); + if (dst->algctx == NULL) { + EVP_KDF_CTX_free(dst); + return NULL; + } + return dst; +} + +int evp_kdf_get_number(const EVP_KDF *kdf) +{ + return kdf->name_id; +} + +const char *EVP_KDF_get0_name(const EVP_KDF *kdf) +{ + return kdf->type_name; +} + +const char *EVP_KDF_get0_description(const EVP_KDF *kdf) +{ + return kdf->description; +} + +int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name) +{ + return kdf != NULL && evp_is_a(kdf->prov, kdf->name_id, NULL, name); +} + +const OSSL_PROVIDER *EVP_KDF_get0_provider(const EVP_KDF *kdf) +{ + return kdf->prov; +} + +const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx) +{ + return ctx->meth; +} + +void EVP_KDF_CTX_reset(EVP_KDF_CTX *ctx) +{ + if (ctx == NULL) + return; + + if (ctx->meth->reset != NULL) + ctx->meth->reset(ctx->algctx); +} + +size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX *ctx) +{ + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t s = 0; + + if (ctx == NULL) + return 0; + + *params = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_SIZE, &s); + if (ctx->meth->get_ctx_params != NULL + && ctx->meth->get_ctx_params(ctx->algctx, params)) + return s; + if (ctx->meth->get_params != NULL + && ctx->meth->get_params(params)) + return s; + return 0; +} + +int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen, + const OSSL_PARAM params[]) +{ + if (ctx == NULL) + return 0; + + return ctx->meth->derive(ctx->algctx, key, keylen, params); +} + +/* + * The {get,set}_params functions return 1 if there is no corresponding + * function in the implementation. This is the same as if there was one, + * but it didn't recognise any of the given params, i.e. nothing in the + * bag of parameters was useful. + */ +int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[]) +{ + if (kdf->get_params != NULL) + return kdf->get_params(params); + return 1; +} + +int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]) +{ + if (ctx->meth->get_ctx_params != NULL) + return ctx->meth->get_ctx_params(ctx->algctx, params); + return 1; +} + +int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]) +{ + if (ctx->meth->set_ctx_params != NULL) + return ctx->meth->set_ctx_params(ctx->algctx, params); + return 1; +} + +int EVP_KDF_names_do_all(const EVP_KDF *kdf, + void (*fn)(const char *name, void *data), + void *data) +{ + if (kdf->prov != NULL) + return evp_names_do_all(kdf->prov, kdf->name_id, fn, data); + + return 1; +} diff --git a/crypto/openssl/crypto/evp/kdf_meth.c b/crypto/openssl/crypto/evp/kdf_meth.c new file mode 100644 index 000000000000..94af5d40a091 --- /dev/null +++ b/crypto/openssl/crypto/evp/kdf_meth.c @@ -0,0 +1,232 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include "internal/provider.h" +#include "internal/core.h" +#include "crypto/evp.h" +#include "evp_local.h" + +static int evp_kdf_up_ref(void *vkdf) +{ + EVP_KDF *kdf = (EVP_KDF *)vkdf; + int ref = 0; + + CRYPTO_UP_REF(&kdf->refcnt, &ref, kdf->lock); + return 1; +} + +static void evp_kdf_free(void *vkdf) +{ + EVP_KDF *kdf = (EVP_KDF *)vkdf; + int ref = 0; + + if (kdf == NULL) + return; + + CRYPTO_DOWN_REF(&kdf->refcnt, &ref, kdf->lock); + if (ref > 0) + return; + OPENSSL_free(kdf->type_name); + ossl_provider_free(kdf->prov); + CRYPTO_THREAD_lock_free(kdf->lock); + OPENSSL_free(kdf); +} + +static void *evp_kdf_new(void) +{ + EVP_KDF *kdf = NULL; + + if ((kdf = OPENSSL_zalloc(sizeof(*kdf))) == NULL + || (kdf->lock = CRYPTO_THREAD_lock_new()) == NULL) { + OPENSSL_free(kdf); + return NULL; + } + kdf->refcnt = 1; + return kdf; +} + +static void *evp_kdf_from_algorithm(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + const OSSL_DISPATCH *fns = algodef->implementation; + EVP_KDF *kdf = NULL; + int fnkdfcnt = 0, fnctxcnt = 0; + + if ((kdf = evp_kdf_new()) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + kdf->name_id = name_id; + if ((kdf->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { + evp_kdf_free(kdf); + return NULL; + } + kdf->description = algodef->algorithm_description; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_KDF_NEWCTX: + if (kdf->newctx != NULL) + break; + kdf->newctx = OSSL_FUNC_kdf_newctx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_KDF_DUPCTX: + if (kdf->dupctx != NULL) + break; + kdf->dupctx = OSSL_FUNC_kdf_dupctx(fns); + break; + case OSSL_FUNC_KDF_FREECTX: + if (kdf->freectx != NULL) + break; + kdf->freectx = OSSL_FUNC_kdf_freectx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_KDF_RESET: + if (kdf->reset != NULL) + break; + kdf->reset = OSSL_FUNC_kdf_reset(fns); + break; + case OSSL_FUNC_KDF_DERIVE: + if (kdf->derive != NULL) + break; + kdf->derive = OSSL_FUNC_kdf_derive(fns); + fnkdfcnt++; + break; + case OSSL_FUNC_KDF_GETTABLE_PARAMS: + if (kdf->gettable_params != NULL) + break; + kdf->gettable_params = + OSSL_FUNC_kdf_gettable_params(fns); + break; + case OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS: + if (kdf->gettable_ctx_params != NULL) + break; + kdf->gettable_ctx_params = + OSSL_FUNC_kdf_gettable_ctx_params(fns); + break; + case OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS: + if (kdf->settable_ctx_params != NULL) + break; + kdf->settable_ctx_params = + OSSL_FUNC_kdf_settable_ctx_params(fns); + break; + case OSSL_FUNC_KDF_GET_PARAMS: + if (kdf->get_params != NULL) + break; + kdf->get_params = OSSL_FUNC_kdf_get_params(fns); + break; + case OSSL_FUNC_KDF_GET_CTX_PARAMS: + if (kdf->get_ctx_params != NULL) + break; + kdf->get_ctx_params = OSSL_FUNC_kdf_get_ctx_params(fns); + break; + case OSSL_FUNC_KDF_SET_CTX_PARAMS: + if (kdf->set_ctx_params != NULL) + break; + kdf->set_ctx_params = OSSL_FUNC_kdf_set_ctx_params(fns); + break; + } + } + if (fnkdfcnt != 1 || fnctxcnt != 2) { + /* + * In order to be a consistent set of functions we must have at least + * a derive function, and a complete set of context management + * functions. + */ + evp_kdf_free(kdf); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + kdf->prov = prov; + if (prov != NULL) + ossl_provider_up_ref(prov); + + return kdf; +} + +EVP_KDF *EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(libctx, OSSL_OP_KDF, algorithm, properties, + evp_kdf_from_algorithm, evp_kdf_up_ref, + evp_kdf_free); +} + +int EVP_KDF_up_ref(EVP_KDF *kdf) +{ + return evp_kdf_up_ref(kdf); +} + +void EVP_KDF_free(EVP_KDF *kdf) +{ + evp_kdf_free(kdf); +} + +const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf) +{ + if (kdf->gettable_params == NULL) + return NULL; + return kdf->gettable_params(ossl_provider_ctx(EVP_KDF_get0_provider(kdf))); +} + +const OSSL_PARAM *EVP_KDF_gettable_ctx_params(const EVP_KDF *kdf) +{ + void *alg; + + if (kdf->gettable_ctx_params == NULL) + return NULL; + alg = ossl_provider_ctx(EVP_KDF_get0_provider(kdf)); + return kdf->gettable_ctx_params(NULL, alg); +} + +const OSSL_PARAM *EVP_KDF_settable_ctx_params(const EVP_KDF *kdf) +{ + void *alg; + + if (kdf->settable_ctx_params == NULL) + return NULL; + alg = ossl_provider_ctx(EVP_KDF_get0_provider(kdf)); + return kdf->settable_ctx_params(NULL, alg); +} + +const OSSL_PARAM *EVP_KDF_CTX_gettable_params(EVP_KDF_CTX *ctx) +{ + void *alg; + + if (ctx->meth->gettable_ctx_params == NULL) + return NULL; + alg = ossl_provider_ctx(EVP_KDF_get0_provider(ctx->meth)); + return ctx->meth->gettable_ctx_params(ctx->algctx, alg); +} + +const OSSL_PARAM *EVP_KDF_CTX_settable_params(EVP_KDF_CTX *ctx) +{ + void *alg; + + if (ctx->meth->settable_ctx_params == NULL) + return NULL; + alg = ossl_provider_ctx(EVP_KDF_get0_provider(ctx->meth)); + return ctx->meth->settable_ctx_params(ctx->algctx, alg); +} + +void EVP_KDF_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_KDF *kdf, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_KDF, + (void (*)(void *, void *))fn, arg, + evp_kdf_from_algorithm, evp_kdf_up_ref, evp_kdf_free); +} diff --git a/crypto/openssl/crypto/evp/kem.c b/crypto/openssl/crypto/evp/kem.c new file mode 100644 index 000000000000..1786ae6553bf --- /dev/null +++ b/crypto/openssl/crypto/evp/kem.c @@ -0,0 +1,482 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/provider.h" +#include "internal/core.h" +#include "crypto/evp.h" +#include "evp_local.h" + +static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, + const OSSL_PARAM params[]) +{ + int ret = 0; + EVP_KEM *kem = NULL; + EVP_KEYMGMT *tmp_keymgmt = NULL; + const OSSL_PROVIDER *tmp_prov = NULL; + void *provkey = NULL; + const char *supported_kem = NULL; + int iter; + + if (ctx == NULL || ctx->keytype == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = operation; + + if (ctx->pkey == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); + goto err; + } + + /* + * Try to derive the supported kem from |ctx->keymgmt|. + */ + if (!ossl_assert(ctx->pkey->keymgmt == NULL + || ctx->pkey->keymgmt == ctx->keymgmt)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + goto err; + } + supported_kem = evp_keymgmt_util_query_operation_name(ctx->keymgmt, + OSSL_OP_KEM); + if (supported_kem == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + /* + * Because we cleared out old ops, we shouldn't need to worry about + * checking if kem is already there. + * We perform two iterations: + * + * 1. Do the normal kem fetch, using the fetching data given by + * the EVP_PKEY_CTX. + * 2. Do the provider specific kem fetch, from the same provider + * as |ctx->keymgmt| + * + * We then try to fetch the keymgmt from the same provider as the + * kem, and try to export |ctx->pkey| to that keymgmt (when this + * keymgmt happens to be the same as |ctx->keymgmt|, the export is + * a no-op, but we call it anyway to not complicate the code even + * more). + * If the export call succeeds (returns a non-NULL provider key pointer), + * we're done and can perform the operation itself. If not, we perform + * the second iteration, or jump to legacy. + */ + for (iter = 1, provkey = NULL; iter < 3 && provkey == NULL; iter++) { + EVP_KEYMGMT *tmp_keymgmt_tofree = NULL; + + /* + * If we're on the second iteration, free the results from the first. + * They are NULL on the first iteration, so no need to check what + * iteration we're on. + */ + EVP_KEM_free(kem); + EVP_KEYMGMT_free(tmp_keymgmt); + + switch (iter) { + case 1: + kem = EVP_KEM_fetch(ctx->libctx, supported_kem, ctx->propquery); + if (kem != NULL) + tmp_prov = EVP_KEM_get0_provider(kem); + break; + case 2: + tmp_prov = EVP_KEYMGMT_get0_provider(ctx->keymgmt); + kem = evp_kem_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, + supported_kem, ctx->propquery); + + if (kem == NULL) { + ERR_raise(ERR_LIB_EVP, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + } + if (kem == NULL) + continue; + + /* + * Ensure that the key is provided, either natively, or as a cached + * export. We start by fetching the keymgmt with the same name as + * |ctx->pkey|, but from the provider of the kem method, using the + * same property query as when fetching the kem method. + * With the keymgmt we found (if we did), we try to export |ctx->pkey| + * to it (evp_pkey_export_to_provider() is smart enough to only actually + + * export it if |tmp_keymgmt| is different from |ctx->pkey|'s keymgmt) + */ + tmp_keymgmt_tofree = tmp_keymgmt = + evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, + EVP_KEYMGMT_get0_name(ctx->keymgmt), + ctx->propquery); + if (tmp_keymgmt != NULL) + provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, + &tmp_keymgmt, ctx->propquery); + if (tmp_keymgmt == NULL) + EVP_KEYMGMT_free(tmp_keymgmt_tofree); + } + + if (provkey == NULL) { + EVP_KEM_free(kem); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + ctx->op.encap.kem = kem; + ctx->op.encap.algctx = kem->newctx(ossl_provider_ctx(kem->prov)); + if (ctx->op.encap.algctx == NULL) { + /* The provider key can stay in the cache */ + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + switch (operation) { + case EVP_PKEY_OP_ENCAPSULATE: + if (kem->encapsulate_init == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = kem->encapsulate_init(ctx->op.encap.algctx, provkey, params); + break; + case EVP_PKEY_OP_DECAPSULATE: + if (kem->decapsulate_init == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = kem->decapsulate_init(ctx->op.encap.algctx, provkey, params); + break; + default: + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + EVP_KEYMGMT_free(tmp_keymgmt); + tmp_keymgmt = NULL; + + if (ret > 0) + return 1; + err: + if (ret <= 0) { + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = EVP_PKEY_OP_UNDEFINED; + } + EVP_KEYMGMT_free(tmp_keymgmt); + return ret; +} + +int EVP_PKEY_encapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) +{ + return evp_kem_init(ctx, EVP_PKEY_OP_ENCAPSULATE, params); +} + +int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + unsigned char *secret, size_t *secretlen) +{ + if (ctx == NULL) + return 0; + + if (ctx->operation != EVP_PKEY_OP_ENCAPSULATE) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.encap.algctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (out != NULL && secret == NULL) + return 0; + + return ctx->op.encap.kem->encapsulate(ctx->op.encap.algctx, + out, outlen, secret, secretlen); +} + +int EVP_PKEY_decapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) +{ + return evp_kem_init(ctx, EVP_PKEY_OP_DECAPSULATE, params); +} + +int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx, + unsigned char *secret, size_t *secretlen, + const unsigned char *in, size_t inlen) +{ + if (ctx == NULL + || (in == NULL || inlen == 0) + || (secret == NULL && secretlen == NULL)) + return 0; + + if (ctx->operation != EVP_PKEY_OP_DECAPSULATE) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.encap.algctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + return ctx->op.encap.kem->decapsulate(ctx->op.encap.algctx, + secret, secretlen, in, inlen); +} + +static EVP_KEM *evp_kem_new(OSSL_PROVIDER *prov) +{ + EVP_KEM *kem = OPENSSL_zalloc(sizeof(EVP_KEM)); + + if (kem == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + kem->lock = CRYPTO_THREAD_lock_new(); + if (kem->lock == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(kem); + return NULL; + } + kem->prov = prov; + ossl_provider_up_ref(prov); + kem->refcnt = 1; + + return kem; +} + +static void *evp_kem_from_algorithm(int name_id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + const OSSL_DISPATCH *fns = algodef->implementation; + EVP_KEM *kem = NULL; + int ctxfncnt = 0, encfncnt = 0, decfncnt = 0; + int gparamfncnt = 0, sparamfncnt = 0; + + if ((kem = evp_kem_new(prov)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + kem->name_id = name_id; + if ((kem->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) + goto err; + kem->description = algodef->algorithm_description; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_KEM_NEWCTX: + if (kem->newctx != NULL) + break; + kem->newctx = OSSL_FUNC_kem_newctx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_KEM_ENCAPSULATE_INIT: + if (kem->encapsulate_init != NULL) + break; + kem->encapsulate_init = OSSL_FUNC_kem_encapsulate_init(fns); + encfncnt++; + break; + case OSSL_FUNC_KEM_ENCAPSULATE: + if (kem->encapsulate != NULL) + break; + kem->encapsulate = OSSL_FUNC_kem_encapsulate(fns); + encfncnt++; + break; + case OSSL_FUNC_KEM_DECAPSULATE_INIT: + if (kem->decapsulate_init != NULL) + break; + kem->decapsulate_init = OSSL_FUNC_kem_decapsulate_init(fns); + decfncnt++; + break; + case OSSL_FUNC_KEM_DECAPSULATE: + if (kem->decapsulate != NULL) + break; + kem->decapsulate = OSSL_FUNC_kem_decapsulate(fns); + decfncnt++; + break; + case OSSL_FUNC_KEM_FREECTX: + if (kem->freectx != NULL) + break; + kem->freectx = OSSL_FUNC_kem_freectx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_KEM_DUPCTX: + if (kem->dupctx != NULL) + break; + kem->dupctx = OSSL_FUNC_kem_dupctx(fns); + break; + case OSSL_FUNC_KEM_GET_CTX_PARAMS: + if (kem->get_ctx_params != NULL) + break; + kem->get_ctx_params + = OSSL_FUNC_kem_get_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_KEM_GETTABLE_CTX_PARAMS: + if (kem->gettable_ctx_params != NULL) + break; + kem->gettable_ctx_params + = OSSL_FUNC_kem_gettable_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_KEM_SET_CTX_PARAMS: + if (kem->set_ctx_params != NULL) + break; + kem->set_ctx_params + = OSSL_FUNC_kem_set_ctx_params(fns); + sparamfncnt++; + break; + case OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS: + if (kem->settable_ctx_params != NULL) + break; + kem->settable_ctx_params + = OSSL_FUNC_kem_settable_ctx_params(fns); + sparamfncnt++; + break; + } + } + if (ctxfncnt != 2 + || (encfncnt != 0 && encfncnt != 2) + || (decfncnt != 0 && decfncnt != 2) + || (encfncnt != 2 && decfncnt != 2) + || (gparamfncnt != 0 && gparamfncnt != 2) + || (sparamfncnt != 0 && sparamfncnt != 2)) { + /* + * In order to be a consistent set of functions we must have at least + * a set of context functions (newctx and freectx) as well as a pair of + * "kem" functions: (encapsulate_init, encapsulate) or + * (decapsulate_init, decapsulate). set_ctx_params and settable_ctx_params are + * optional, but if one of them is present then the other one must also + * be present. The same applies to get_ctx_params and + * gettable_ctx_params. The dupctx function is optional. + */ + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + goto err; + } + + return kem; + err: + EVP_KEM_free(kem); + return NULL; +} + +void EVP_KEM_free(EVP_KEM *kem) +{ + int i; + + if (kem == NULL) + return; + + CRYPTO_DOWN_REF(&kem->refcnt, &i, kem->lock); + if (i > 0) + return; + OPENSSL_free(kem->type_name); + ossl_provider_free(kem->prov); + CRYPTO_THREAD_lock_free(kem->lock); + OPENSSL_free(kem); +} + +int EVP_KEM_up_ref(EVP_KEM *kem) +{ + int ref = 0; + + CRYPTO_UP_REF(&kem->refcnt, &ref, kem->lock); + return 1; +} + +OSSL_PROVIDER *EVP_KEM_get0_provider(const EVP_KEM *kem) +{ + return kem->prov; +} + +EVP_KEM *EVP_KEM_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(ctx, OSSL_OP_KEM, algorithm, properties, + evp_kem_from_algorithm, + (int (*)(void *))EVP_KEM_up_ref, + (void (*)(void *))EVP_KEM_free); +} + +EVP_KEM *evp_kem_fetch_from_prov(OSSL_PROVIDER *prov, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch_from_prov(prov, OSSL_OP_KEM, algorithm, properties, + evp_kem_from_algorithm, + (int (*)(void *))EVP_KEM_up_ref, + (void (*)(void *))EVP_KEM_free); +} + +int EVP_KEM_is_a(const EVP_KEM *kem, const char *name) +{ + return kem != NULL && evp_is_a(kem->prov, kem->name_id, NULL, name); +} + +int evp_kem_get_number(const EVP_KEM *kem) +{ + return kem->name_id; +} + +const char *EVP_KEM_get0_name(const EVP_KEM *kem) +{ + return kem->type_name; +} + +const char *EVP_KEM_get0_description(const EVP_KEM *kem) +{ + return kem->description; +} + +void EVP_KEM_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_KEM *kem, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_KEM, (void (*)(void *, void *))fn, arg, + evp_kem_from_algorithm, + (int (*)(void *))EVP_KEM_up_ref, + (void (*)(void *))EVP_KEM_free); +} + +int EVP_KEM_names_do_all(const EVP_KEM *kem, + void (*fn)(const char *name, void *data), + void *data) +{ + if (kem->prov != NULL) + return evp_names_do_all(kem->prov, kem->name_id, fn, data); + + return 1; +} + +const OSSL_PARAM *EVP_KEM_gettable_ctx_params(const EVP_KEM *kem) +{ + void *provctx; + + if (kem == NULL || kem->gettable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_KEM_get0_provider(kem)); + return kem->gettable_ctx_params(NULL, provctx); +} + +const OSSL_PARAM *EVP_KEM_settable_ctx_params(const EVP_KEM *kem) +{ + void *provctx; + + if (kem == NULL || kem->settable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_KEM_get0_provider(kem)); + return kem->settable_ctx_params(NULL, provctx); +} diff --git a/crypto/openssl/crypto/evp/keymgmt_lib.c b/crypto/openssl/crypto/evp/keymgmt_lib.c new file mode 100644 index 000000000000..8369d9578cbd --- /dev/null +++ b/crypto/openssl/crypto/evp/keymgmt_lib.c @@ -0,0 +1,589 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include "internal/nelem.h" +#include "crypto/evp.h" +#include "internal/core.h" +#include "internal/provider.h" +#include "evp_local.h" + +/* + * match_type() checks if two EVP_KEYMGMT are matching key types. This + * function assumes that the caller has made all the necessary NULL checks. + */ +static int match_type(const EVP_KEYMGMT *keymgmt1, const EVP_KEYMGMT *keymgmt2) +{ + const char *name2 = EVP_KEYMGMT_get0_name(keymgmt2); + + return EVP_KEYMGMT_is_a(keymgmt1, name2); +} + +int evp_keymgmt_util_try_import(const OSSL_PARAM params[], void *arg) +{ + struct evp_keymgmt_util_try_import_data_st *data = arg; + int delete_on_error = 0; + + /* Just in time creation of keydata */ + if (data->keydata == NULL) { + if ((data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + delete_on_error = 1; + } + + /* + * It's fine if there was no data to transfer, we just end up with an + * empty destination key. + */ + if (params[0].key == NULL) + return 1; + + if (evp_keymgmt_import(data->keymgmt, data->keydata, data->selection, + params)) + return 1; + if (delete_on_error) { + evp_keymgmt_freedata(data->keymgmt, data->keydata); + data->keydata = NULL; + } + return 0; +} + +int evp_keymgmt_util_assign_pkey(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt, + void *keydata) +{ + if (pkey == NULL || keymgmt == NULL || keydata == NULL + || !EVP_PKEY_set_type_by_keymgmt(pkey, keymgmt)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + pkey->keydata = keydata; + evp_keymgmt_util_cache_keyinfo(pkey); + return 1; +} + +EVP_PKEY *evp_keymgmt_util_make_pkey(EVP_KEYMGMT *keymgmt, void *keydata) +{ + EVP_PKEY *pkey = NULL; + + if (keymgmt == NULL + || keydata == NULL + || (pkey = EVP_PKEY_new()) == NULL + || !evp_keymgmt_util_assign_pkey(pkey, keymgmt, keydata)) { + EVP_PKEY_free(pkey); + return NULL; + } + return pkey; +} + +int evp_keymgmt_util_export(const EVP_PKEY *pk, int selection, + OSSL_CALLBACK *export_cb, void *export_cbarg) +{ + if (pk == NULL || export_cb == NULL) + return 0; + return evp_keymgmt_export(pk->keymgmt, pk->keydata, selection, + export_cb, export_cbarg); +} + +void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, + int selection) +{ + struct evp_keymgmt_util_try_import_data_st import_data; + OP_CACHE_ELEM *op; + + /* Export to where? */ + if (keymgmt == NULL) + return NULL; + + /* If we have an unassigned key, give up */ + if (pk->keydata == NULL) + return NULL; + + /* + * If |keymgmt| matches the "origin" |keymgmt|, there is no more to do. + * The "origin" is determined by the |keymgmt| pointers being identical + * or when the provider and the name ID match. The latter case handles the + * situation where the fetch cache is flushed and a "new" key manager is + * created. + */ + if (pk->keymgmt == keymgmt + || (pk->keymgmt->name_id == keymgmt->name_id + && pk->keymgmt->prov == keymgmt->prov)) + return pk->keydata; + + if (!CRYPTO_THREAD_read_lock(pk->lock)) + return NULL; + /* + * If the provider native "origin" hasn't changed since last time, we + * try to find our keymgmt in the operation cache. If it has changed + * and our keymgmt isn't found, we will clear the cache further down. + */ + if (pk->dirty_cnt == pk->dirty_cnt_copy) { + /* If this key is already exported to |keymgmt|, no more to do */ + op = evp_keymgmt_util_find_operation_cache(pk, keymgmt, selection); + if (op != NULL && op->keymgmt != NULL) { + void *ret = op->keydata; + + CRYPTO_THREAD_unlock(pk->lock); + return ret; + } + } + CRYPTO_THREAD_unlock(pk->lock); + + /* If the "origin" |keymgmt| doesn't support exporting, give up */ + if (pk->keymgmt->export == NULL) + return NULL; + + /* + * Make sure that the type of the keymgmt to export to matches the type + * of the "origin" + */ + if (!ossl_assert(match_type(pk->keymgmt, keymgmt))) + return NULL; + + /* + * We look at the already cached provider keys, and import from the + * first that supports it (i.e. use its export function), and export + * the imported data to the new provider. + */ + + /* Setup for the export callback */ + import_data.keydata = NULL; /* evp_keymgmt_util_try_import will create it */ + import_data.keymgmt = keymgmt; + import_data.selection = selection; + + /* + * The export function calls the callback (evp_keymgmt_util_try_import), + * which does the import for us. If successful, we're done. + */ + if (!evp_keymgmt_util_export(pk, selection, + &evp_keymgmt_util_try_import, &import_data)) + /* If there was an error, bail out */ + return NULL; + + if (!CRYPTO_THREAD_write_lock(pk->lock)) { + evp_keymgmt_freedata(keymgmt, import_data.keydata); + return NULL; + } + /* Check to make sure some other thread didn't get there first */ + op = evp_keymgmt_util_find_operation_cache(pk, keymgmt, selection); + if (op != NULL && op->keydata != NULL) { + void *ret = op->keydata; + + CRYPTO_THREAD_unlock(pk->lock); + + /* + * Another thread seemms to have already exported this so we abandon + * all the work we just did. + */ + evp_keymgmt_freedata(keymgmt, import_data.keydata); + + return ret; + } + + /* + * If the dirty counter changed since last time, then clear the + * operation cache. In that case, we know that |i| is zero. + */ + if (pk->dirty_cnt != pk->dirty_cnt_copy) + evp_keymgmt_util_clear_operation_cache(pk, 0); + + /* Add the new export to the operation cache */ + if (!evp_keymgmt_util_cache_keydata(pk, keymgmt, import_data.keydata, + selection)) { + CRYPTO_THREAD_unlock(pk->lock); + evp_keymgmt_freedata(keymgmt, import_data.keydata); + return NULL; + } + + /* Synchronize the dirty count */ + pk->dirty_cnt_copy = pk->dirty_cnt; + + CRYPTO_THREAD_unlock(pk->lock); + + return import_data.keydata; +} + +static void op_cache_free(OP_CACHE_ELEM *e) +{ + evp_keymgmt_freedata(e->keymgmt, e->keydata); + EVP_KEYMGMT_free(e->keymgmt); + OPENSSL_free(e); +} + +int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk, int locking) +{ + if (pk != NULL) { + if (locking && pk->lock != NULL && !CRYPTO_THREAD_write_lock(pk->lock)) + return 0; + sk_OP_CACHE_ELEM_pop_free(pk->operation_cache, op_cache_free); + pk->operation_cache = NULL; + if (locking && pk->lock != NULL) + CRYPTO_THREAD_unlock(pk->lock); + } + + return 1; +} + +OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk, + EVP_KEYMGMT *keymgmt, + int selection) +{ + int i, end = sk_OP_CACHE_ELEM_num(pk->operation_cache); + OP_CACHE_ELEM *p; + + /* + * A comparison and sk_P_CACHE_ELEM_find() are avoided to not cause + * problems when we've only a read lock. + */ + for (i = 0; i < end; i++) { + p = sk_OP_CACHE_ELEM_value(pk->operation_cache, i); + if (keymgmt == p->keymgmt && (p->selection & selection) == selection) + return p; + } + return NULL; +} + +int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, + void *keydata, int selection) +{ + OP_CACHE_ELEM *p = NULL; + + if (keydata != NULL) { + if (pk->operation_cache == NULL) { + pk->operation_cache = sk_OP_CACHE_ELEM_new_null(); + if (pk->operation_cache == NULL) + return 0; + } + + p = OPENSSL_malloc(sizeof(*p)); + if (p == NULL) + return 0; + p->keydata = keydata; + p->keymgmt = keymgmt; + p->selection = selection; + + if (!EVP_KEYMGMT_up_ref(keymgmt)) { + OPENSSL_free(p); + return 0; + } + + if (!sk_OP_CACHE_ELEM_push(pk->operation_cache, p)) { + EVP_KEYMGMT_free(keymgmt); + OPENSSL_free(p); + return 0; + } + } + return 1; +} + +void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk) +{ + /* + * Cache information about the provider "origin" key. + * + * This services functions like EVP_PKEY_get_size, EVP_PKEY_get_bits, etc + */ + if (pk->keydata != NULL) { + int bits = 0; + int security_bits = 0; + int size = 0; + OSSL_PARAM params[4]; + + params[0] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_BITS, &bits); + params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_SECURITY_BITS, + &security_bits); + params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE, &size); + params[3] = OSSL_PARAM_construct_end(); + if (evp_keymgmt_get_params(pk->keymgmt, pk->keydata, params)) { + pk->cache.size = size; + pk->cache.bits = bits; + pk->cache.security_bits = security_bits; + } + } +} + +void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, + int selection, const OSSL_PARAM params[]) +{ + void *keydata = NULL; + + if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL + || !evp_keymgmt_import(keymgmt, keydata, selection, params) + || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) { + evp_keymgmt_freedata(keymgmt, keydata); + keydata = NULL; + } + return keydata; +} + +int evp_keymgmt_util_has(EVP_PKEY *pk, int selection) +{ + /* Check if key is even assigned */ + if (pk->keymgmt == NULL) + return 0; + + return evp_keymgmt_has(pk->keymgmt, pk->keydata, selection); +} + +/* + * evp_keymgmt_util_match() doesn't just look at the provider side "origin", + * but also in the operation cache to see if there's any common keymgmt that + * supplies OP_keymgmt_match. + * + * evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_eq() + * and EVP_PKEY_parameters_eq() return, i.e.: + * + * 1 same key + * 0 not same key + * -1 not same key type + * -2 unsupported operation + */ +int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection) +{ + EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL; + void *keydata1 = NULL, *keydata2 = NULL; + + if (pk1 == NULL || pk2 == NULL) { + if (pk1 == NULL && pk2 == NULL) + return 1; + return 0; + } + + keymgmt1 = pk1->keymgmt; + keydata1 = pk1->keydata; + keymgmt2 = pk2->keymgmt; + keydata2 = pk2->keydata; + + if (keymgmt1 != keymgmt2) { + /* + * The condition for a successful cross export is that the + * keydata to be exported is NULL (typed, but otherwise empty + * EVP_PKEY), or that it was possible to export it with + * evp_keymgmt_util_export_to_provider(). + * + * We use |ok| to determine if it's ok to cross export one way, + * but also to determine if we should attempt a cross export + * the other way. There's no point doing it both ways. + */ + int ok = 0; + + /* Complex case, where the keymgmt differ */ + if (keymgmt1 != NULL + && keymgmt2 != NULL + && !match_type(keymgmt1, keymgmt2)) { + ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); + return -1; /* Not the same type */ + } + + /* + * The key types are determined to match, so we try cross export, + * but only to keymgmt's that supply a matching function. + */ + if (keymgmt2 != NULL + && keymgmt2->match != NULL) { + void *tmp_keydata = NULL; + + ok = 1; + if (keydata1 != NULL) { + tmp_keydata = + evp_keymgmt_util_export_to_provider(pk1, keymgmt2, + selection); + ok = (tmp_keydata != NULL); + } + if (ok) { + keymgmt1 = keymgmt2; + keydata1 = tmp_keydata; + } + } + /* + * If we've successfully cross exported one way, there's no point + * doing it the other way, hence the |!ok| check. + */ + if (!ok + && keymgmt1 != NULL + && keymgmt1->match != NULL) { + void *tmp_keydata = NULL; + + ok = 1; + if (keydata2 != NULL) { + tmp_keydata = + evp_keymgmt_util_export_to_provider(pk2, keymgmt1, + selection); + ok = (tmp_keydata != NULL); + } + if (ok) { + keymgmt2 = keymgmt1; + keydata2 = tmp_keydata; + } + } + } + + /* If we still don't have matching keymgmt implementations, we give up */ + if (keymgmt1 != keymgmt2) + return -2; + + /* If both keydata are NULL, then they're the same key */ + if (keydata1 == NULL && keydata2 == NULL) + return 1; + /* If only one of the keydata is NULL, then they're different keys */ + if (keydata1 == NULL || keydata2 == NULL) + return 0; + /* If both keydata are non-NULL, we let the backend decide */ + return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection); +} + +int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection) +{ + /* Save copies of pointers we want to play with without affecting |to| */ + EVP_KEYMGMT *to_keymgmt = to->keymgmt; + void *to_keydata = to->keydata, *alloc_keydata = NULL; + + /* An unassigned key can't be copied */ + if (from == NULL || from->keydata == NULL) + return 0; + + /* + * If |to| is unassigned, ensure it gets the same KEYMGMT as |from|, + * Note that the final setting of KEYMGMT is done further down, with + * EVP_PKEY_set_type_by_keymgmt(); we don't want to do that prematurely. + */ + if (to_keymgmt == NULL) + to_keymgmt = from->keymgmt; + + if (to_keymgmt == from->keymgmt && to_keymgmt->dup != NULL + && to_keydata == NULL) { + to_keydata = alloc_keydata = evp_keymgmt_dup(to_keymgmt, + from->keydata, + selection); + if (to_keydata == NULL) + return 0; + } else if (match_type(to_keymgmt, from->keymgmt)) { + struct evp_keymgmt_util_try_import_data_st import_data; + + import_data.keymgmt = to_keymgmt; + import_data.keydata = to_keydata; + import_data.selection = selection; + + if (!evp_keymgmt_util_export(from, selection, + &evp_keymgmt_util_try_import, + &import_data)) + return 0; + + /* + * In case to_keydata was previously unallocated, + * evp_keymgmt_util_try_import() may have created it for us. + */ + if (to_keydata == NULL) + to_keydata = alloc_keydata = import_data.keydata; + } else { + ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); + return 0; + } + + /* + * We only need to set the |to| type when its |keymgmt| isn't set. + * We can then just set its |keydata| to what we have, which might + * be exactly what it had when entering this function. + * This is a bit different from using evp_keymgmt_util_assign_pkey(), + * which isn't as careful with |to|'s original |keymgmt|, since it's + * meant to forcibly reassign an EVP_PKEY no matter what, which is + * why we don't use that one here. + */ + if (to->keymgmt == NULL + && !EVP_PKEY_set_type_by_keymgmt(to, to_keymgmt)) { + evp_keymgmt_freedata(to_keymgmt, alloc_keydata); + return 0; + } + to->keydata = to_keydata; + evp_keymgmt_util_cache_keyinfo(to); + + return 1; +} + +void *evp_keymgmt_util_gen(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, + void *genctx, OSSL_CALLBACK *cb, void *cbarg) +{ + void *keydata = NULL; + + if ((keydata = evp_keymgmt_gen(keymgmt, genctx, cb, cbarg)) == NULL + || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) { + evp_keymgmt_freedata(keymgmt, keydata); + keydata = NULL; + } + + return keydata; +} + +/* + * Returns the same numbers as EVP_PKEY_get_default_digest_name() + * When the string from the EVP_KEYMGMT implementation is "", we use + * SN_undef, since that corresponds to what EVP_PKEY_get_default_nid() + * returns for no digest. + */ +int evp_keymgmt_util_get_deflt_digest_name(EVP_KEYMGMT *keymgmt, + void *keydata, + char *mdname, size_t mdname_sz) +{ + OSSL_PARAM params[3]; + char mddefault[100] = ""; + char mdmandatory[100] = ""; + char *result = NULL; + int rv = -2; + + params[0] = + OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, + mddefault, sizeof(mddefault)); + params[1] = + OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, + mdmandatory, + sizeof(mdmandatory)); + params[2] = OSSL_PARAM_construct_end(); + + if (!evp_keymgmt_get_params(keymgmt, keydata, params)) + return 0; + + if (OSSL_PARAM_modified(params + 1)) { + if (params[1].return_size <= 1) /* Only a NUL byte */ + result = SN_undef; + else + result = mdmandatory; + rv = 2; + } else if (OSSL_PARAM_modified(params)) { + if (params[0].return_size <= 1) /* Only a NUL byte */ + result = SN_undef; + else + result = mddefault; + rv = 1; + } + if (rv > 0) + OPENSSL_strlcpy(mdname, result, mdname_sz); + return rv; +} + +/* + * If |keymgmt| has the method function |query_operation_name|, use it to get + * the name of a supported operation identity. Otherwise, return the keytype, + * assuming that it works as a default operation name. + */ +const char *evp_keymgmt_util_query_operation_name(EVP_KEYMGMT *keymgmt, + int op_id) +{ + const char *name = NULL; + + if (keymgmt != NULL) { + if (keymgmt->query_operation_name != NULL) + name = keymgmt->query_operation_name(op_id); + if (name == NULL) + name = EVP_KEYMGMT_get0_name(keymgmt); + } + return name; +} diff --git a/crypto/openssl/crypto/evp/keymgmt_meth.c b/crypto/openssl/crypto/evp/keymgmt_meth.c new file mode 100644 index 000000000000..90fd8068dc42 --- /dev/null +++ b/crypto/openssl/crypto/evp/keymgmt_meth.c @@ -0,0 +1,496 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/provider.h" +#include "internal/refcount.h" +#include "internal/core.h" +#include "crypto/evp.h" +#include "evp_local.h" + +static void *keymgmt_new(void) +{ + EVP_KEYMGMT *keymgmt = NULL; + + if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL + || (keymgmt->lock = CRYPTO_THREAD_lock_new()) == NULL) { + EVP_KEYMGMT_free(keymgmt); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + keymgmt->refcnt = 1; + + return keymgmt; +} + +static void *keymgmt_from_algorithm(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + const OSSL_DISPATCH *fns = algodef->implementation; + EVP_KEYMGMT *keymgmt = NULL; + int setparamfncnt = 0, getparamfncnt = 0; + int setgenparamfncnt = 0; + int importfncnt = 0, exportfncnt = 0; + + if ((keymgmt = keymgmt_new()) == NULL) + return NULL; + + keymgmt->name_id = name_id; + if ((keymgmt->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { + EVP_KEYMGMT_free(keymgmt); + return NULL; + } + keymgmt->description = algodef->algorithm_description; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_KEYMGMT_NEW: + if (keymgmt->new == NULL) + keymgmt->new = OSSL_FUNC_keymgmt_new(fns); + break; + case OSSL_FUNC_KEYMGMT_GEN_INIT: + if (keymgmt->gen_init == NULL) + keymgmt->gen_init = OSSL_FUNC_keymgmt_gen_init(fns); + break; + case OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE: + if (keymgmt->gen_set_template == NULL) + keymgmt->gen_set_template = + OSSL_FUNC_keymgmt_gen_set_template(fns); + break; + case OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS: + if (keymgmt->gen_set_params == NULL) { + setgenparamfncnt++; + keymgmt->gen_set_params = + OSSL_FUNC_keymgmt_gen_set_params(fns); + } + break; + case OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS: + if (keymgmt->gen_settable_params == NULL) { + setgenparamfncnt++; + keymgmt->gen_settable_params = + OSSL_FUNC_keymgmt_gen_settable_params(fns); + } + break; + case OSSL_FUNC_KEYMGMT_GEN: + if (keymgmt->gen == NULL) + keymgmt->gen = OSSL_FUNC_keymgmt_gen(fns); + break; + case OSSL_FUNC_KEYMGMT_GEN_CLEANUP: + if (keymgmt->gen_cleanup == NULL) + keymgmt->gen_cleanup = OSSL_FUNC_keymgmt_gen_cleanup(fns); + break; + case OSSL_FUNC_KEYMGMT_FREE: + if (keymgmt->free == NULL) + keymgmt->free = OSSL_FUNC_keymgmt_free(fns); + break; + case OSSL_FUNC_KEYMGMT_LOAD: + if (keymgmt->load == NULL) + keymgmt->load = OSSL_FUNC_keymgmt_load(fns); + break; + case OSSL_FUNC_KEYMGMT_GET_PARAMS: + if (keymgmt->get_params == NULL) { + getparamfncnt++; + keymgmt->get_params = OSSL_FUNC_keymgmt_get_params(fns); + } + break; + case OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS: + if (keymgmt->gettable_params == NULL) { + getparamfncnt++; + keymgmt->gettable_params = + OSSL_FUNC_keymgmt_gettable_params(fns); + } + break; + case OSSL_FUNC_KEYMGMT_SET_PARAMS: + if (keymgmt->set_params == NULL) { + setparamfncnt++; + keymgmt->set_params = OSSL_FUNC_keymgmt_set_params(fns); + } + break; + case OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS: + if (keymgmt->settable_params == NULL) { + setparamfncnt++; + keymgmt->settable_params = + OSSL_FUNC_keymgmt_settable_params(fns); + } + break; + case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME: + if (keymgmt->query_operation_name == NULL) + keymgmt->query_operation_name = + OSSL_FUNC_keymgmt_query_operation_name(fns); + break; + case OSSL_FUNC_KEYMGMT_HAS: + if (keymgmt->has == NULL) + keymgmt->has = OSSL_FUNC_keymgmt_has(fns); + break; + case OSSL_FUNC_KEYMGMT_DUP: + if (keymgmt->dup == NULL) + keymgmt->dup = OSSL_FUNC_keymgmt_dup(fns); + break; + case OSSL_FUNC_KEYMGMT_VALIDATE: + if (keymgmt->validate == NULL) + keymgmt->validate = OSSL_FUNC_keymgmt_validate(fns); + break; + case OSSL_FUNC_KEYMGMT_MATCH: + if (keymgmt->match == NULL) + keymgmt->match = OSSL_FUNC_keymgmt_match(fns); + break; + case OSSL_FUNC_KEYMGMT_IMPORT: + if (keymgmt->import == NULL) { + importfncnt++; + keymgmt->import = OSSL_FUNC_keymgmt_import(fns); + } + break; + case OSSL_FUNC_KEYMGMT_IMPORT_TYPES: + if (keymgmt->import_types == NULL) { + importfncnt++; + keymgmt->import_types = OSSL_FUNC_keymgmt_import_types(fns); + } + break; + case OSSL_FUNC_KEYMGMT_EXPORT: + if (keymgmt->export == NULL) { + exportfncnt++; + keymgmt->export = OSSL_FUNC_keymgmt_export(fns); + } + break; + case OSSL_FUNC_KEYMGMT_EXPORT_TYPES: + if (keymgmt->export_types == NULL) { + exportfncnt++; + keymgmt->export_types = OSSL_FUNC_keymgmt_export_types(fns); + } + break; + } + } + /* + * Try to check that the method is sensible. + * At least one constructor and the destructor are MANDATORY + * The functions 'has' is MANDATORY + * It makes no sense being able to free stuff if you can't create it. + * It makes no sense providing OSSL_PARAM descriptors for import and + * export if you can't import or export. + */ + if (keymgmt->free == NULL + || (keymgmt->new == NULL + && keymgmt->gen == NULL + && keymgmt->load == NULL) + || keymgmt->has == NULL + || (getparamfncnt != 0 && getparamfncnt != 2) + || (setparamfncnt != 0 && setparamfncnt != 2) + || (setgenparamfncnt != 0 && setgenparamfncnt != 2) + || (importfncnt != 0 && importfncnt != 2) + || (exportfncnt != 0 && exportfncnt != 2) + || (keymgmt->gen != NULL + && (keymgmt->gen_init == NULL + || keymgmt->gen_cleanup == NULL))) { + EVP_KEYMGMT_free(keymgmt); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + keymgmt->prov = prov; + if (prov != NULL) + ossl_provider_up_ref(prov); + + return keymgmt; +} + +EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OSSL_LIB_CTX *ctx, int name_id, + const char *properties) +{ + return evp_generic_fetch_by_number(ctx, + OSSL_OP_KEYMGMT, name_id, properties, + keymgmt_from_algorithm, + (int (*)(void *))EVP_KEYMGMT_up_ref, + (void (*)(void *))EVP_KEYMGMT_free); +} + +EVP_KEYMGMT *evp_keymgmt_fetch_from_prov(OSSL_PROVIDER *prov, + const char *name, + const char *properties) +{ + return evp_generic_fetch_from_prov(prov, OSSL_OP_KEYMGMT, + name, properties, + keymgmt_from_algorithm, + (int (*)(void *))EVP_KEYMGMT_up_ref, + (void (*)(void *))EVP_KEYMGMT_free); +} + +EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties, + keymgmt_from_algorithm, + (int (*)(void *))EVP_KEYMGMT_up_ref, + (void (*)(void *))EVP_KEYMGMT_free); +} + +int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt) +{ + int ref = 0; + + CRYPTO_UP_REF(&keymgmt->refcnt, &ref, keymgmt->lock); + return 1; +} + +void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt) +{ + int ref = 0; + + if (keymgmt == NULL) + return; + + CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref, keymgmt->lock); + if (ref > 0) + return; + OPENSSL_free(keymgmt->type_name); + ossl_provider_free(keymgmt->prov); + CRYPTO_THREAD_lock_free(keymgmt->lock); + OPENSSL_free(keymgmt); +} + +const OSSL_PROVIDER *EVP_KEYMGMT_get0_provider(const EVP_KEYMGMT *keymgmt) +{ + return keymgmt->prov; +} + +int evp_keymgmt_get_number(const EVP_KEYMGMT *keymgmt) +{ + return keymgmt->name_id; +} + +const char *EVP_KEYMGMT_get0_description(const EVP_KEYMGMT *keymgmt) +{ + return keymgmt->description; +} + +const char *EVP_KEYMGMT_get0_name(const EVP_KEYMGMT *keymgmt) +{ + return keymgmt->type_name; +} + +int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name) +{ + return keymgmt != NULL + && evp_is_a(keymgmt->prov, keymgmt->name_id, NULL, name); +} + +void EVP_KEYMGMT_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_KEYMGMT *keymgmt, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_KEYMGMT, + (void (*)(void *, void *))fn, arg, + keymgmt_from_algorithm, + (int (*)(void *))EVP_KEYMGMT_up_ref, + (void (*)(void *))EVP_KEYMGMT_free); +} + +int EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt, + void (*fn)(const char *name, void *data), + void *data) +{ + if (keymgmt->prov != NULL) + return evp_names_do_all(keymgmt->prov, keymgmt->name_id, fn, data); + + return 1; +} + +/* + * Internal API that interfaces with the method function pointers + */ +void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt) +{ + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); + + /* + * 'new' is currently mandatory on its own, but when new + * constructors appear, it won't be quite as mandatory, + * so we have a check for future cases. + */ + if (keymgmt->new == NULL) + return NULL; + return keymgmt->new(provctx); +} + +void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keydata) +{ + /* This is mandatory, no need to check for its presence */ + keymgmt->free(keydata); +} + +void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection, + const OSSL_PARAM params[]) +{ + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); + + if (keymgmt->gen_init == NULL) + return NULL; + return keymgmt->gen_init(provctx, selection, params); +} + +int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx, + void *template) +{ + /* + * It's arguable if we actually should return success in this case, as + * it allows the caller to set a template key, which is then ignored. + * However, this is how the legacy methods (EVP_PKEY_METHOD) operate, + * so we do this in the interest of backward compatibility. + */ + if (keymgmt->gen_set_template == NULL) + return 1; + return keymgmt->gen_set_template(genctx, template); +} + +int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx, + const OSSL_PARAM params[]) +{ + if (keymgmt->gen_set_params == NULL) + return 0; + return keymgmt->gen_set_params(genctx, params); +} + +const OSSL_PARAM *EVP_KEYMGMT_gen_settable_params(const EVP_KEYMGMT *keymgmt) +{ + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); + + if (keymgmt->gen_settable_params == NULL) + return NULL; + return keymgmt->gen_settable_params(NULL, provctx); +} + +void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx, + OSSL_CALLBACK *cb, void *cbarg) +{ + if (keymgmt->gen == NULL) + return NULL; + return keymgmt->gen(genctx, cb, cbarg); +} + +void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx) +{ + if (keymgmt->gen != NULL) + keymgmt->gen_cleanup(genctx); +} + +int evp_keymgmt_has_load(const EVP_KEYMGMT *keymgmt) +{ + return keymgmt != NULL && keymgmt->load != NULL; +} + +void *evp_keymgmt_load(const EVP_KEYMGMT *keymgmt, + const void *objref, size_t objref_sz) +{ + if (evp_keymgmt_has_load(keymgmt)) + return keymgmt->load(objref, objref_sz); + return NULL; +} + +int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata, + OSSL_PARAM params[]) +{ + if (keymgmt->get_params == NULL) + return 1; + return keymgmt->get_params(keydata, params); +} + +const OSSL_PARAM *EVP_KEYMGMT_gettable_params(const EVP_KEYMGMT *keymgmt) +{ + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); + + if (keymgmt->gettable_params == NULL) + return NULL; + return keymgmt->gettable_params(provctx); +} + +int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt, void *keydata, + const OSSL_PARAM params[]) +{ + if (keymgmt->set_params == NULL) + return 1; + return keymgmt->set_params(keydata, params); +} + +const OSSL_PARAM *EVP_KEYMGMT_settable_params(const EVP_KEYMGMT *keymgmt) +{ + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); + + if (keymgmt->settable_params == NULL) + return NULL; + return keymgmt->settable_params(provctx); +} + +int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keydata, int selection) +{ + /* This is mandatory, no need to check for its presence */ + return keymgmt->has(keydata, selection); +} + +int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata, + int selection, int checktype) +{ + /* We assume valid if the implementation doesn't have a function */ + if (keymgmt->validate == NULL) + return 1; + return keymgmt->validate(keydata, selection, checktype); +} + +int evp_keymgmt_match(const EVP_KEYMGMT *keymgmt, + const void *keydata1, const void *keydata2, + int selection) +{ + /* We assume no match if the implementation doesn't have a function */ + if (keymgmt->match == NULL) + return 0; + return keymgmt->match(keydata1, keydata2, selection); +} + +int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata, + int selection, const OSSL_PARAM params[]) +{ + if (keymgmt->import == NULL) + return 0; + return keymgmt->import(keydata, selection, params); +} + +const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt, + int selection) +{ + if (keymgmt->import_types == NULL) + return NULL; + return keymgmt->import_types(selection); +} + +int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata, + int selection, OSSL_CALLBACK *param_cb, void *cbarg) +{ + if (keymgmt->export == NULL) + return 0; + return keymgmt->export(keydata, selection, param_cb, cbarg); +} + +const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt, + int selection) +{ + if (keymgmt->export_types == NULL) + return NULL; + return keymgmt->export_types(selection); +} + +void *evp_keymgmt_dup(const EVP_KEYMGMT *keymgmt, const void *keydata_from, + int selection) +{ + /* We assume no dup if the implementation doesn't have a function */ + if (keymgmt->dup == NULL) + return NULL; + return keymgmt->dup(keydata_from, selection); +} diff --git a/crypto/openssl/crypto/evp/legacy_blake2.c b/crypto/openssl/crypto/evp/legacy_blake2.c new file mode 100644 index 000000000000..6a18e5fe01b6 --- /dev/null +++ b/crypto/openssl/crypto/evp/legacy_blake2.c @@ -0,0 +1,48 @@ +/* + * Copyright 2019-2021 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 "crypto/evp.h" +#include "prov/blake2.h" /* diverse BLAKE2 macros */ +#include "legacy_meth.h" + +#define ossl_blake2b_init ossl_blake2b512_init +#define ossl_blake2s_init ossl_blake2s256_init + +IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2s_int, ossl_blake2s) +IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2b_int, ossl_blake2b) + +static const EVP_MD blake2b_md = { + NID_blake2b512, + 0, + BLAKE2B_DIGEST_LENGTH, + 0, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(blake2b_int_init, blake2b_int_update, + blake2b_int_final, NULL, BLAKE2B_BLOCKBYTES), +}; + +const EVP_MD *EVP_blake2b512(void) +{ + return &blake2b_md; +} + +static const EVP_MD blake2s_md = { + NID_blake2s256, + 0, + BLAKE2S_DIGEST_LENGTH, + 0, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(blake2s_int_init, blake2s_int_update, + blake2s_int_final, NULL, BLAKE2S_BLOCKBYTES), +}; + +const EVP_MD *EVP_blake2s256(void) +{ + return &blake2s_md; +} diff --git a/crypto/openssl/crypto/evp/legacy_md2.c b/crypto/openssl/crypto/evp/legacy_md2.c new file mode 100644 index 000000000000..72cc99ad7044 --- /dev/null +++ b/crypto/openssl/crypto/evp/legacy_md2.c @@ -0,0 +1,34 @@ +/* + * Copyright 2015-2021 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 + */ + +/* + * MD2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "crypto/evp.h" +#include "legacy_meth.h" + +IMPLEMENT_LEGACY_EVP_MD_METH(md2, MD2) + +static const EVP_MD md2_md = { + NID_md2, + NID_md2WithRSAEncryption, + MD2_DIGEST_LENGTH, + 0, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(md2_init, md2_update, md2_final, NULL, MD2_BLOCK) +}; + +const EVP_MD *EVP_md2(void) +{ + return &md2_md; +} diff --git a/crypto/openssl/crypto/evp/legacy_md4.c b/crypto/openssl/crypto/evp/legacy_md4.c new file mode 100644 index 000000000000..4bc852b5209a --- /dev/null +++ b/crypto/openssl/crypto/evp/legacy_md4.c @@ -0,0 +1,34 @@ +/* + * Copyright 2015-2021 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 + */ + +/* + * MD4 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "crypto/evp.h" +#include "legacy_meth.h" + +IMPLEMENT_LEGACY_EVP_MD_METH(md4, MD4) + +static const EVP_MD md4_md = { + NID_md4, + NID_md4WithRSAEncryption, + MD4_DIGEST_LENGTH, + 0, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(md4_init, md4_update, md4_final, NULL, MD4_CBLOCK), +}; + +const EVP_MD *EVP_md4(void) +{ + return &md4_md; +} diff --git a/crypto/openssl/crypto/evp/legacy_md5.c b/crypto/openssl/crypto/evp/legacy_md5.c new file mode 100644 index 000000000000..a67be9fef74b --- /dev/null +++ b/crypto/openssl/crypto/evp/legacy_md5.c @@ -0,0 +1,34 @@ +/* + * Copyright 2015-2021 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 + */ + +/* + * MD5 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "crypto/evp.h" +#include "legacy_meth.h" + +IMPLEMENT_LEGACY_EVP_MD_METH(md5, MD5) + +static const EVP_MD md5_md = { + NID_md5, + NID_md5WithRSAEncryption, + MD5_DIGEST_LENGTH, + 0, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(md5_init, md5_update, md5_final, NULL, MD5_CBLOCK) +}; + +const EVP_MD *EVP_md5(void) +{ + return &md5_md; +} diff --git a/crypto/openssl/crypto/evp/legacy_md5_sha1.c b/crypto/openssl/crypto/evp/legacy_md5_sha1.c new file mode 100644 index 000000000000..b84bf3deaaf4 --- /dev/null +++ b/crypto/openssl/crypto/evp/legacy_md5_sha1.c @@ -0,0 +1,41 @@ +/* + * Copyright 2015-2021 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 + */ + +/* + * MD5 and SHA-1 low level APIs are deprecated for public use, but still ok for + * internal use. The prov/md5_sha1.h include requires this, but this must + * be the first include loaded. + */ +#include "internal/deprecated.h" + +#include "crypto/evp.h" +#include "prov/md5_sha1.h" /* diverse MD5_SHA1 macros */ +#include "legacy_meth.h" + +IMPLEMENT_LEGACY_EVP_MD_METH_LC(md5_sha1_int, ossl_md5_sha1) +static int md5_sha1_int_ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) +{ + return ossl_md5_sha1_ctrl(EVP_MD_CTX_get0_md_data(ctx), cmd, mslen, ms); +} + +static const EVP_MD md5_sha1_md = { + NID_md5_sha1, + NID_md5_sha1, + MD5_SHA1_DIGEST_LENGTH, + 0, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(md5_sha1_int_init, md5_sha1_int_update, + md5_sha1_int_final, md5_sha1_int_ctrl, + MD5_SHA1_CBLOCK), +}; + +const EVP_MD *EVP_md5_sha1(void) +{ + return &md5_sha1_md; +} diff --git a/crypto/openssl/crypto/evp/legacy_mdc2.c b/crypto/openssl/crypto/evp/legacy_mdc2.c new file mode 100644 index 000000000000..317d87c61b14 --- /dev/null +++ b/crypto/openssl/crypto/evp/legacy_mdc2.c @@ -0,0 +1,35 @@ +/* + * Copyright 2015-2021 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 + */ + +/* + * MDC2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "crypto/evp.h" +#include "legacy_meth.h" + +IMPLEMENT_LEGACY_EVP_MD_METH(mdc2, MDC2) + +static const EVP_MD mdc2_md = { + NID_mdc2, + NID_mdc2WithRSA, + MDC2_DIGEST_LENGTH, + 0, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(mdc2_init, mdc2_update, mdc2_final, NULL, + MDC2_BLOCK), +}; + +const EVP_MD *EVP_mdc2(void) +{ + return &mdc2_md; +} diff --git a/crypto/openssl/crypto/evp/legacy_meth.h b/crypto/openssl/crypto/evp/legacy_meth.h new file mode 100644 index 000000000000..a6e58bc824e2 --- /dev/null +++ b/crypto/openssl/crypto/evp/legacy_meth.h @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2021 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 + */ + +#define IMPLEMENT_LEGACY_EVP_MD_METH(nm, fn) \ +static int nm##_init(EVP_MD_CTX *ctx) \ +{ \ + return fn##_Init(EVP_MD_CTX_get0_md_data(ctx)); \ +} \ +static int nm##_update(EVP_MD_CTX *ctx, const void *data, size_t count) \ +{ \ + return fn##_Update(EVP_MD_CTX_get0_md_data(ctx), data, count); \ +} \ +static int nm##_final(EVP_MD_CTX *ctx, unsigned char *md) \ +{ \ + return fn##_Final(md, EVP_MD_CTX_get0_md_data(ctx)); \ +} + +#define IMPLEMENT_LEGACY_EVP_MD_METH_LC(nm, fn) \ +static int nm##_init(EVP_MD_CTX *ctx) \ +{ \ + return fn##_init(EVP_MD_CTX_get0_md_data(ctx)); \ +} \ +static int nm##_update(EVP_MD_CTX *ctx, const void *data, size_t count) \ +{ \ + return fn##_update(EVP_MD_CTX_get0_md_data(ctx), data, count); \ +} \ +static int nm##_final(EVP_MD_CTX *ctx, unsigned char *md) \ +{ \ + return fn##_final(md, EVP_MD_CTX_get0_md_data(ctx)); \ +} + + +#define LEGACY_EVP_MD_METH_TABLE(init, update, final, ctrl, blksz) \ + init, update, final, NULL, NULL, blksz, 0, ctrl diff --git a/crypto/openssl/crypto/evp/legacy_ripemd.c b/crypto/openssl/crypto/evp/legacy_ripemd.c new file mode 100644 index 000000000000..1fa1ebc04998 --- /dev/null +++ b/crypto/openssl/crypto/evp/legacy_ripemd.c @@ -0,0 +1,35 @@ +/* + * Copyright 1995-2021 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 + */ + +/* + * RIPEMD160 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "crypto/evp.h" +#include "legacy_meth.h" + +IMPLEMENT_LEGACY_EVP_MD_METH(ripe, RIPEMD160) + +static const EVP_MD ripemd160_md = { + NID_ripemd160, + NID_ripemd160WithRSA, + RIPEMD160_DIGEST_LENGTH, + 0, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(ripe_init, ripe_update, ripe_final, NULL, + RIPEMD160_CBLOCK), +}; + +const EVP_MD *EVP_ripemd160(void) +{ + return &ripemd160_md; +} diff --git a/crypto/openssl/crypto/evp/legacy_sha.c b/crypto/openssl/crypto/evp/legacy_sha.c new file mode 100644 index 000000000000..3859286eeb20 --- /dev/null +++ b/crypto/openssl/crypto/evp/legacy_sha.c @@ -0,0 +1,228 @@ +/* + * Copyright 2019-2021 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 + */ + +/* + * All SHA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include /* diverse SHA macros */ +#include "internal/sha3.h" /* KECCAK1600_WIDTH */ +#include "crypto/evp.h" +/* Used by legacy methods */ +#include "crypto/sha.h" +#include "legacy_meth.h" +#include "evp_local.h" + +/*- + * LEGACY methods for SHA. + * These only remain to support engines that can get these methods. + * Hardware support for SHA3 has been removed from these legacy cases. + */ +#define IMPLEMENT_LEGACY_EVP_MD_METH_SHA3(nm, fn, tag) \ +static int nm##_init(EVP_MD_CTX *ctx) \ +{ \ + return fn##_init(EVP_MD_CTX_get0_md_data(ctx), tag, ctx->digest->md_size * 8); \ +} \ +static int nm##_update(EVP_MD_CTX *ctx, const void *data, size_t count) \ +{ \ + return fn##_update(EVP_MD_CTX_get0_md_data(ctx), data, count); \ +} \ +static int nm##_final(EVP_MD_CTX *ctx, unsigned char *md) \ +{ \ + return fn##_final(md, EVP_MD_CTX_get0_md_data(ctx)); \ +} +#define IMPLEMENT_LEGACY_EVP_MD_METH_SHAKE(nm, fn, tag) \ +static int nm##_init(EVP_MD_CTX *ctx) \ +{ \ + return fn##_init(EVP_MD_CTX_get0_md_data(ctx), tag, ctx->digest->md_size * 8); \ +} \ + +#define sha512_224_Init sha512_224_init +#define sha512_256_Init sha512_256_init + +#define sha512_224_Update SHA512_Update +#define sha512_224_Final SHA512_Final +#define sha512_256_Update SHA512_Update +#define sha512_256_Final SHA512_Final + +IMPLEMENT_LEGACY_EVP_MD_METH(sha1, SHA1) +IMPLEMENT_LEGACY_EVP_MD_METH(sha224, SHA224) +IMPLEMENT_LEGACY_EVP_MD_METH(sha256, SHA256) +IMPLEMENT_LEGACY_EVP_MD_METH(sha384, SHA384) +IMPLEMENT_LEGACY_EVP_MD_METH(sha512, SHA512) +IMPLEMENT_LEGACY_EVP_MD_METH(sha512_224_int, sha512_224) +IMPLEMENT_LEGACY_EVP_MD_METH(sha512_256_int, sha512_256) +IMPLEMENT_LEGACY_EVP_MD_METH_SHA3(sha3_int, ossl_sha3, '\x06') +IMPLEMENT_LEGACY_EVP_MD_METH_SHAKE(shake, ossl_sha3, '\x1f') + +static int sha1_int_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2) +{ + return ossl_sha1_ctrl(ctx != NULL ? EVP_MD_CTX_get0_md_data(ctx) : NULL, + cmd, p1, p2); +} + +static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2) +{ + KECCAK1600_CTX *ctx = evp_ctx->md_data; + + switch (cmd) { + case EVP_MD_CTRL_XOF_LEN: + ctx->md_size = p1; + return 1; + default: + return 0; + } +} + + + +static const EVP_MD sha1_md = { + NID_sha1, + NID_sha1WithRSAEncryption, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(sha1_init, sha1_update, sha1_final, sha1_int_ctrl, + SHA_CBLOCK), +}; + +const EVP_MD *EVP_sha1(void) +{ + return &sha1_md; +} + +static const EVP_MD sha224_md = { + NID_sha224, + NID_sha224WithRSAEncryption, + SHA224_DIGEST_LENGTH, + EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(sha224_init, sha224_update, sha224_final, NULL, + SHA256_CBLOCK), +}; + +const EVP_MD *EVP_sha224(void) +{ + return &sha224_md; +} + +static const EVP_MD sha256_md = { + NID_sha256, + NID_sha256WithRSAEncryption, + SHA256_DIGEST_LENGTH, + EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(sha256_init, sha256_update, sha256_final, NULL, + SHA256_CBLOCK), +}; + +const EVP_MD *EVP_sha256(void) +{ + return &sha256_md; +} + +static const EVP_MD sha512_224_md = { + NID_sha512_224, + NID_sha512_224WithRSAEncryption, + SHA224_DIGEST_LENGTH, + EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(sha512_224_int_init, sha512_224_int_update, + sha512_224_int_final, NULL, SHA512_CBLOCK), +}; + +const EVP_MD *EVP_sha512_224(void) +{ + return &sha512_224_md; +} + +static const EVP_MD sha512_256_md = { + NID_sha512_256, + NID_sha512_256WithRSAEncryption, + SHA256_DIGEST_LENGTH, + EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(sha512_256_int_init, sha512_256_int_update, + sha512_256_int_final, NULL, SHA512_CBLOCK), +}; + +const EVP_MD *EVP_sha512_256(void) +{ + return &sha512_256_md; +} + +static const EVP_MD sha384_md = { + NID_sha384, + NID_sha384WithRSAEncryption, + SHA384_DIGEST_LENGTH, + EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(sha384_init, sha384_update, sha384_final, NULL, + SHA512_CBLOCK), +}; + +const EVP_MD *EVP_sha384(void) +{ + return &sha384_md; +} + +static const EVP_MD sha512_md = { + NID_sha512, + NID_sha512WithRSAEncryption, + SHA512_DIGEST_LENGTH, + EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(sha512_init, sha512_update, sha512_final, NULL, + SHA512_CBLOCK), +}; + +const EVP_MD *EVP_sha512(void) +{ + return &sha512_md; +} + +#define EVP_MD_SHA3(bitlen) \ +const EVP_MD *EVP_sha3_##bitlen(void) \ +{ \ + static const EVP_MD sha3_##bitlen##_md = { \ + NID_sha3_##bitlen, \ + NID_RSA_SHA3_##bitlen, \ + bitlen / 8, \ + EVP_MD_FLAG_DIGALGID_ABSENT, \ + EVP_ORIG_GLOBAL, \ + LEGACY_EVP_MD_METH_TABLE(sha3_int_init, sha3_int_update, \ + sha3_int_final, NULL, \ + (KECCAK1600_WIDTH - bitlen * 2) / 8), \ + }; \ + return &sha3_##bitlen##_md; \ +} +#define EVP_MD_SHAKE(bitlen) \ +const EVP_MD *EVP_shake##bitlen(void) \ +{ \ + static const EVP_MD shake##bitlen##_md = { \ + NID_shake##bitlen, \ + 0, \ + bitlen / 8, \ + EVP_MD_FLAG_XOF, \ + EVP_ORIG_GLOBAL, \ + LEGACY_EVP_MD_METH_TABLE(shake_init, sha3_int_update, sha3_int_final, \ + shake_ctrl, (KECCAK1600_WIDTH - bitlen * 2) / 8), \ + }; \ + return &shake##bitlen##_md; \ +} + +EVP_MD_SHA3(224) +EVP_MD_SHA3(256) +EVP_MD_SHA3(384) +EVP_MD_SHA3(512) + +EVP_MD_SHAKE(128) +EVP_MD_SHAKE(256) diff --git a/crypto/openssl/crypto/evp/legacy_wp.c b/crypto/openssl/crypto/evp/legacy_wp.c new file mode 100644 index 000000000000..3976ff73fb2d --- /dev/null +++ b/crypto/openssl/crypto/evp/legacy_wp.c @@ -0,0 +1,35 @@ +/* + * Copyright 2005-2021 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 + */ + +/* + * Whirlpool low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "crypto/evp.h" +#include "legacy_meth.h" + +IMPLEMENT_LEGACY_EVP_MD_METH(wp, WHIRLPOOL) + +static const EVP_MD whirlpool_md = { + NID_whirlpool, + 0, + WHIRLPOOL_DIGEST_LENGTH, + 0, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(wp_init, wp_update, wp_final, NULL, + WHIRLPOOL_BBLOCK / 8), +}; + +const EVP_MD *EVP_whirlpool(void) +{ + return &whirlpool_md; +} diff --git a/crypto/openssl/crypto/evp/m_md2.c b/crypto/openssl/crypto/evp/m_md2.c deleted file mode 100644 index 1aec5185239d..000000000000 --- a/crypto/openssl/crypto/evp/m_md2.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 1995-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 - */ - -#include -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_MD2 - -# include -# include -# include -# include -# include - -#include "crypto/evp.h" - -static int init(EVP_MD_CTX *ctx) -{ - return MD2_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return MD2_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return MD2_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD md2_md = { - NID_md2, - NID_md2WithRSAEncryption, - MD2_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - MD2_BLOCK, - sizeof(EVP_MD *) + sizeof(MD2_CTX), -}; - -const EVP_MD *EVP_md2(void) -{ - return &md2_md; -} -#endif diff --git a/crypto/openssl/crypto/evp/m_md4.c b/crypto/openssl/crypto/evp/m_md4.c deleted file mode 100644 index 45d2cafee101..000000000000 --- a/crypto/openssl/crypto/evp/m_md4.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 1995-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 - */ - -#include -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_MD4 - -# include -# include -# include -# include -# include -# include "crypto/evp.h" - -static int init(EVP_MD_CTX *ctx) -{ - return MD4_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return MD4_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return MD4_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD md4_md = { - NID_md4, - NID_md4WithRSAEncryption, - MD4_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - MD4_CBLOCK, - sizeof(EVP_MD *) + sizeof(MD4_CTX), -}; - -const EVP_MD *EVP_md4(void) -{ - return &md4_md; -} -#endif diff --git a/crypto/openssl/crypto/evp/m_md5.c b/crypto/openssl/crypto/evp/m_md5.c deleted file mode 100644 index d26b5a4d31dc..000000000000 --- a/crypto/openssl/crypto/evp/m_md5.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 1995-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 - */ - -#include -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_MD5 - -# include -# include -# include -# include -# include -# include "crypto/evp.h" - -static int init(EVP_MD_CTX *ctx) -{ - return MD5_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return MD5_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return MD5_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD md5_md = { - NID_md5, - NID_md5WithRSAEncryption, - MD5_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - MD5_CBLOCK, - sizeof(EVP_MD *) + sizeof(MD5_CTX), -}; - -const EVP_MD *EVP_md5(void) -{ - return &md5_md; -} -#endif diff --git a/crypto/openssl/crypto/evp/m_mdc2.c b/crypto/openssl/crypto/evp/m_mdc2.c deleted file mode 100644 index fffa751efd18..000000000000 --- a/crypto/openssl/crypto/evp/m_mdc2.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 1995-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 - */ - -#include -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_MDC2 - -# include -# include -# include -# include -# include -# include "crypto/evp.h" - -static int init(EVP_MD_CTX *ctx) -{ - return MDC2_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return MDC2_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return MDC2_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD mdc2_md = { - NID_mdc2, - NID_mdc2WithRSA, - MDC2_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - MDC2_BLOCK, - sizeof(EVP_MD *) + sizeof(MDC2_CTX), -}; - -const EVP_MD *EVP_mdc2(void) -{ - return &mdc2_md; -} -#endif diff --git a/crypto/openssl/crypto/evp/m_null.c b/crypto/openssl/crypto/evp/m_null.c index 0847139df17b..7b310d70477e 100644 --- a/crypto/openssl/crypto/evp/m_null.c +++ b/crypto/openssl/crypto/evp/m_null.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -34,6 +34,7 @@ static const EVP_MD null_md = { NID_undef, 0, 0, + EVP_ORIG_GLOBAL, init, update, final, diff --git a/crypto/openssl/crypto/evp/m_ripemd.c b/crypto/openssl/crypto/evp/m_ripemd.c deleted file mode 100644 index d93ad24fe58a..000000000000 --- a/crypto/openssl/crypto/evp/m_ripemd.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 1995-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 - */ - -#include -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_RMD160 - -# include -# include -# include -# include -# include -# include "crypto/evp.h" - -static int init(EVP_MD_CTX *ctx) -{ - return RIPEMD160_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return RIPEMD160_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return RIPEMD160_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD ripemd160_md = { - NID_ripemd160, - NID_ripemd160WithRSA, - RIPEMD160_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - RIPEMD160_CBLOCK, - sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX), -}; - -const EVP_MD *EVP_ripemd160(void) -{ - return &ripemd160_md; -} -#endif diff --git a/crypto/openssl/crypto/evp/m_sha1.c b/crypto/openssl/crypto/evp/m_sha1.c deleted file mode 100644 index 22b9bbc7d861..000000000000 --- a/crypto/openssl/crypto/evp/m_sha1.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" - -#include -#include -#include -#include -#include "crypto/evp.h" -#include "crypto/sha.h" - -static int init(EVP_MD_CTX *ctx) -{ - return SHA1_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA1_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA1_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) -{ - unsigned char padtmp[40]; - unsigned char sha1tmp[SHA_DIGEST_LENGTH]; - - SHA_CTX *sha1; - - if (cmd != EVP_CTRL_SSL3_MASTER_SECRET) - return -2; - - if (ctx == NULL) - return 0; - - sha1 = EVP_MD_CTX_md_data(ctx); - - /* SSLv3 client auth handling: see RFC-6101 5.6.8 */ - if (mslen != 48) - return 0; - - /* At this point hash contains all handshake messages, update - * with master secret and pad_1. - */ - - if (SHA1_Update(sha1, ms, mslen) <= 0) - return 0; - - /* Set padtmp to pad_1 value */ - memset(padtmp, 0x36, sizeof(padtmp)); - - if (!SHA1_Update(sha1, padtmp, sizeof(padtmp))) - return 0; - - if (!SHA1_Final(sha1tmp, sha1)) - return 0; - - /* Reinitialise context */ - - if (!SHA1_Init(sha1)) - return 0; - - if (SHA1_Update(sha1, ms, mslen) <= 0) - return 0; - - /* Set padtmp to pad_2 value */ - memset(padtmp, 0x5c, sizeof(padtmp)); - - if (!SHA1_Update(sha1, padtmp, sizeof(padtmp))) - return 0; - - if (!SHA1_Update(sha1, sha1tmp, sizeof(sha1tmp))) - return 0; - - /* Now when ctx is finalised it will return the SSL v3 hash value */ - OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp)); - - return 1; - -} - -static const EVP_MD sha1_md = { - NID_sha1, - NID_sha1WithRSAEncryption, - SHA_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - init, - update, - final, - NULL, - NULL, - SHA_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA_CTX), - ctrl -}; - -const EVP_MD *EVP_sha1(void) -{ - return &sha1_md; -} - -static int init224(EVP_MD_CTX *ctx) -{ - return SHA224_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update224(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA224_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final224(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA224_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static int init256(EVP_MD_CTX *ctx) -{ - return SHA256_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update256(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA256_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final256(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA256_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD sha224_md = { - NID_sha224, - NID_sha224WithRSAEncryption, - SHA224_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - init224, - update224, - final224, - NULL, - NULL, - SHA256_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA256_CTX), -}; - -const EVP_MD *EVP_sha224(void) -{ - return &sha224_md; -} - -static const EVP_MD sha256_md = { - NID_sha256, - NID_sha256WithRSAEncryption, - SHA256_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - init256, - update256, - final256, - NULL, - NULL, - SHA256_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA256_CTX), -}; - -const EVP_MD *EVP_sha256(void) -{ - return &sha256_md; -} - -static int init512_224(EVP_MD_CTX *ctx) -{ - return sha512_224_init(EVP_MD_CTX_md_data(ctx)); -} - -static int init512_256(EVP_MD_CTX *ctx) -{ - return sha512_256_init(EVP_MD_CTX_md_data(ctx)); -} - -static int init384(EVP_MD_CTX *ctx) -{ - return SHA384_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update384(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA384_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final384(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA384_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static int init512(EVP_MD_CTX *ctx) -{ - return SHA512_Init(EVP_MD_CTX_md_data(ctx)); -} - -/* See comment in SHA224/256 section */ -static int update512(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA512_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final512(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA512_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD sha512_224_md = { - NID_sha512_224, - NID_sha512_224WithRSAEncryption, - SHA224_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - init512_224, - update512, - final512, - NULL, - NULL, - SHA512_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA512_CTX), -}; - -const EVP_MD *EVP_sha512_224(void) -{ - return &sha512_224_md; -} - -static const EVP_MD sha512_256_md = { - NID_sha512_256, - NID_sha512_256WithRSAEncryption, - SHA256_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - init512_256, - update512, - final512, - NULL, - NULL, - SHA512_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA512_CTX), -}; - -const EVP_MD *EVP_sha512_256(void) -{ - return &sha512_256_md; -} - -static const EVP_MD sha384_md = { - NID_sha384, - NID_sha384WithRSAEncryption, - SHA384_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - init384, - update384, - final384, - NULL, - NULL, - SHA512_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA512_CTX), -}; - -const EVP_MD *EVP_sha384(void) -{ - return &sha384_md; -} - -static const EVP_MD sha512_md = { - NID_sha512, - NID_sha512WithRSAEncryption, - SHA512_DIGEST_LENGTH, - EVP_MD_FLAG_DIGALGID_ABSENT, - init512, - update512, - final512, - NULL, - NULL, - SHA512_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA512_CTX), -}; - -const EVP_MD *EVP_sha512(void) -{ - return &sha512_md; -} diff --git a/crypto/openssl/crypto/evp/m_sha3.c b/crypto/openssl/crypto/evp/m_sha3.c deleted file mode 100644 index 54c592a3cce2..000000000000 --- a/crypto/openssl/crypto/evp/m_sha3.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * 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 - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include - -#include -#include -#include "crypto/evp.h" -#include "evp_local.h" - -size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len, - size_t r); -void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r); - -#define KECCAK1600_WIDTH 1600 - -typedef struct { - uint64_t A[5][5]; - size_t block_size; /* cached ctx->digest->block_size */ - size_t md_size; /* output length, variable in XOF */ - size_t num; /* used bytes in below buffer */ - unsigned char buf[KECCAK1600_WIDTH / 8 - 32]; - unsigned char pad; -} KECCAK1600_CTX; - -static int init(EVP_MD_CTX *evp_ctx, unsigned char pad) -{ - KECCAK1600_CTX *ctx = evp_ctx->md_data; - size_t bsz = evp_ctx->digest->block_size; - - if (bsz <= sizeof(ctx->buf)) { - memset(ctx->A, 0, sizeof(ctx->A)); - - ctx->num = 0; - ctx->block_size = bsz; - ctx->md_size = evp_ctx->digest->md_size; - ctx->pad = pad; - - return 1; - } - - return 0; -} - -static int sha3_init(EVP_MD_CTX *evp_ctx) -{ - return init(evp_ctx, '\x06'); -} - -static int shake_init(EVP_MD_CTX *evp_ctx) -{ - return init(evp_ctx, '\x1f'); -} - -static int sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len) -{ - KECCAK1600_CTX *ctx = evp_ctx->md_data; - const unsigned char *inp = _inp; - size_t bsz = ctx->block_size; - size_t num, rem; - - if (len == 0) - return 1; - - if ((num = ctx->num) != 0) { /* process intermediate buffer? */ - rem = bsz - num; - - if (len < rem) { - memcpy(ctx->buf + num, inp, len); - ctx->num += len; - return 1; - } - /* - * We have enough data to fill or overflow the intermediate - * buffer. So we append |rem| bytes and process the block, - * leaving the rest for later processing... - */ - memcpy(ctx->buf + num, inp, rem); - inp += rem, len -= rem; - (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz); - ctx->num = 0; - /* ctx->buf is processed, ctx->num is guaranteed to be zero */ - } - - if (len >= bsz) - rem = SHA3_absorb(ctx->A, inp, len, bsz); - else - rem = len; - - if (rem) { - memcpy(ctx->buf, inp + len - rem, rem); - ctx->num = rem; - } - - return 1; -} - -static int sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md) -{ - KECCAK1600_CTX *ctx = evp_ctx->md_data; - 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 - * same byte... - */ - memset(ctx->buf + num, 0, bsz - num); - ctx->buf[num] = ctx->pad; - ctx->buf[bsz - 1] |= 0x80; - - (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz); - - SHA3_squeeze(ctx->A, md, ctx->md_size, bsz); - - return 1; -} - -static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2) -{ - KECCAK1600_CTX *ctx = evp_ctx->md_data; - - switch (cmd) { - case EVP_MD_CTRL_XOF_LEN: - ctx->md_size = p1; - return 1; - default: - return 0; - } -} - -#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM) -/* - * IBM S390X support - */ -# include "s390x_arch.h" - -# define S390X_SHA3_FC(ctx) ((ctx)->pad) - -# define S390X_sha3_224_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ - S390X_CAPBIT(S390X_SHA3_224)) && \ - (OPENSSL_s390xcap_P.klmd[0] & \ - S390X_CAPBIT(S390X_SHA3_224))) -# define S390X_sha3_256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ - S390X_CAPBIT(S390X_SHA3_256)) && \ - (OPENSSL_s390xcap_P.klmd[0] & \ - S390X_CAPBIT(S390X_SHA3_256))) -# define S390X_sha3_384_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ - S390X_CAPBIT(S390X_SHA3_384)) && \ - (OPENSSL_s390xcap_P.klmd[0] & \ - S390X_CAPBIT(S390X_SHA3_384))) -# define S390X_sha3_512_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ - S390X_CAPBIT(S390X_SHA3_512)) && \ - (OPENSSL_s390xcap_P.klmd[0] & \ - S390X_CAPBIT(S390X_SHA3_512))) -# define S390X_shake128_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ - S390X_CAPBIT(S390X_SHAKE_128)) && \ - (OPENSSL_s390xcap_P.klmd[0] & \ - S390X_CAPBIT(S390X_SHAKE_128))) -# define S390X_shake256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \ - S390X_CAPBIT(S390X_SHAKE_256)) && \ - (OPENSSL_s390xcap_P.klmd[0] & \ - S390X_CAPBIT(S390X_SHAKE_256))) - -/* Convert md-size to block-size. */ -# define S390X_KECCAK1600_BSZ(n) ((KECCAK1600_WIDTH - ((n) << 1)) >> 3) - -static int s390x_sha3_init(EVP_MD_CTX *evp_ctx) -{ - KECCAK1600_CTX *ctx = evp_ctx->md_data; - const size_t bsz = evp_ctx->digest->block_size; - - /*- - * KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD - * function code. - */ - switch (bsz) { - case S390X_KECCAK1600_BSZ(224): - ctx->pad = S390X_SHA3_224; - break; - case S390X_KECCAK1600_BSZ(256): - ctx->pad = S390X_SHA3_256; - break; - case S390X_KECCAK1600_BSZ(384): - ctx->pad = S390X_SHA3_384; - break; - case S390X_KECCAK1600_BSZ(512): - ctx->pad = S390X_SHA3_512; - break; - default: - return 0; - } - - memset(ctx->A, 0, sizeof(ctx->A)); - ctx->num = 0; - ctx->block_size = bsz; - ctx->md_size = evp_ctx->digest->md_size; - return 1; -} - -static int s390x_shake_init(EVP_MD_CTX *evp_ctx) -{ - KECCAK1600_CTX *ctx = evp_ctx->md_data; - const size_t bsz = evp_ctx->digest->block_size; - - /*- - * KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD - * function code. - */ - switch (bsz) { - case S390X_KECCAK1600_BSZ(128): - ctx->pad = S390X_SHAKE_128; - break; - case S390X_KECCAK1600_BSZ(256): - ctx->pad = S390X_SHAKE_256; - break; - default: - return 0; - } - - memset(ctx->A, 0, sizeof(ctx->A)); - ctx->num = 0; - ctx->block_size = bsz; - ctx->md_size = evp_ctx->digest->md_size; - return 1; -} - -static int s390x_sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len) -{ - KECCAK1600_CTX *ctx = evp_ctx->md_data; - const unsigned char *inp = _inp; - const size_t bsz = ctx->block_size; - size_t num, rem; - - if (len == 0) - return 1; - - if ((num = ctx->num) != 0) { - rem = bsz - num; - - if (len < rem) { - memcpy(ctx->buf + num, inp, len); - ctx->num += len; - return 1; - } - memcpy(ctx->buf + num, inp, rem); - inp += rem; - len -= rem; - s390x_kimd(ctx->buf, bsz, ctx->pad, ctx->A); - ctx->num = 0; - } - rem = len % bsz; - - s390x_kimd(inp, len - rem, ctx->pad, ctx->A); - - if (rem) { - memcpy(ctx->buf, inp + len - rem, rem); - ctx->num = rem; - } - return 1; -} - -static int s390x_sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md) -{ - KECCAK1600_CTX *ctx = evp_ctx->md_data; - - s390x_klmd(ctx->buf, ctx->num, NULL, 0, ctx->pad, ctx->A); - memcpy(md, ctx->A, ctx->md_size); - return 1; -} - -static int s390x_shake_final(EVP_MD_CTX *evp_ctx, unsigned char *md) -{ - KECCAK1600_CTX *ctx = evp_ctx->md_data; - - s390x_klmd(ctx->buf, ctx->num, md, ctx->md_size, ctx->pad, ctx->A); - return 1; -} - -# define EVP_MD_SHA3(bitlen) \ -const EVP_MD *EVP_sha3_##bitlen(void) \ -{ \ - static const EVP_MD s390x_sha3_##bitlen##_md = { \ - NID_sha3_##bitlen, \ - NID_RSA_SHA3_##bitlen, \ - bitlen / 8, \ - EVP_MD_FLAG_DIGALGID_ABSENT, \ - s390x_sha3_init, \ - s390x_sha3_update, \ - s390x_sha3_final, \ - NULL, \ - NULL, \ - (KECCAK1600_WIDTH - bitlen * 2) / 8, \ - sizeof(KECCAK1600_CTX), \ - }; \ - static const EVP_MD sha3_##bitlen##_md = { \ - NID_sha3_##bitlen, \ - NID_RSA_SHA3_##bitlen, \ - bitlen / 8, \ - EVP_MD_FLAG_DIGALGID_ABSENT, \ - sha3_init, \ - sha3_update, \ - sha3_final, \ - NULL, \ - NULL, \ - (KECCAK1600_WIDTH - bitlen * 2) / 8, \ - sizeof(KECCAK1600_CTX), \ - }; \ - return S390X_sha3_##bitlen##_CAPABLE ? \ - &s390x_sha3_##bitlen##_md : \ - &sha3_##bitlen##_md; \ -} - -# define EVP_MD_SHAKE(bitlen) \ -const EVP_MD *EVP_shake##bitlen(void) \ -{ \ - static const EVP_MD s390x_shake##bitlen##_md = { \ - NID_shake##bitlen, \ - 0, \ - bitlen / 8, \ - EVP_MD_FLAG_XOF, \ - s390x_shake_init, \ - s390x_sha3_update, \ - s390x_shake_final, \ - NULL, \ - NULL, \ - (KECCAK1600_WIDTH - bitlen * 2) / 8, \ - sizeof(KECCAK1600_CTX), \ - shake_ctrl \ - }; \ - static const EVP_MD shake##bitlen##_md = { \ - NID_shake##bitlen, \ - 0, \ - bitlen / 8, \ - EVP_MD_FLAG_XOF, \ - shake_init, \ - sha3_update, \ - sha3_final, \ - NULL, \ - NULL, \ - (KECCAK1600_WIDTH - bitlen * 2) / 8, \ - sizeof(KECCAK1600_CTX), \ - shake_ctrl \ - }; \ - return S390X_shake##bitlen##_CAPABLE ? \ - &s390x_shake##bitlen##_md : \ - &shake##bitlen##_md; \ -} - -#else - -# define EVP_MD_SHA3(bitlen) \ -const EVP_MD *EVP_sha3_##bitlen(void) \ -{ \ - static const EVP_MD sha3_##bitlen##_md = { \ - NID_sha3_##bitlen, \ - NID_RSA_SHA3_##bitlen, \ - bitlen / 8, \ - EVP_MD_FLAG_DIGALGID_ABSENT, \ - sha3_init, \ - sha3_update, \ - sha3_final, \ - NULL, \ - NULL, \ - (KECCAK1600_WIDTH - bitlen * 2) / 8, \ - sizeof(KECCAK1600_CTX), \ - }; \ - return &sha3_##bitlen##_md; \ -} - -# define EVP_MD_SHAKE(bitlen) \ -const EVP_MD *EVP_shake##bitlen(void) \ -{ \ - static const EVP_MD shake##bitlen##_md = { \ - NID_shake##bitlen, \ - 0, \ - bitlen / 8, \ - EVP_MD_FLAG_XOF, \ - shake_init, \ - sha3_update, \ - sha3_final, \ - NULL, \ - NULL, \ - (KECCAK1600_WIDTH - bitlen * 2) / 8, \ - sizeof(KECCAK1600_CTX), \ - shake_ctrl \ - }; \ - return &shake##bitlen##_md; \ -} -#endif - -EVP_MD_SHA3(224) -EVP_MD_SHA3(256) -EVP_MD_SHA3(384) -EVP_MD_SHA3(512) - -EVP_MD_SHAKE(128) -EVP_MD_SHAKE(256) diff --git a/crypto/openssl/crypto/evp/m_sigver.c b/crypto/openssl/crypto/evp/m_sigver.c index 04643acc8837..76a6814b424b 100644 --- a/crypto/openssl/crypto/evp/m_sigver.c +++ b/crypto/openssl/crypto/evp/m_sigver.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,25 +11,301 @@ #include "internal/cryptlib.h" #include #include -#include #include "crypto/evp.h" +#include "internal/provider.h" +#include "internal/numbers.h" /* includes SIZE_MAX */ #include "evp_local.h" +#ifndef FIPS_MODULE + static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen) { - EVPerr(EVP_F_UPDATE, EVP_R_ONLY_ONESHOT_SUPPORTED); + ERR_raise(ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED); return 0; } +/* + * If we get the "NULL" md then the name comes back as "UNDEF". We want to use + * NULL for this. + */ +static const char *canon_mdname(const char *mdname) +{ + if (mdname != NULL && strcmp(mdname, "UNDEF") == 0) + return NULL; + + return mdname; +} + static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey, - int ver) + const EVP_MD *type, const char *mdname, + OSSL_LIB_CTX *libctx, const char *props, + ENGINE *e, EVP_PKEY *pkey, int ver, + const OSSL_PARAM params[]) { + EVP_PKEY_CTX *locpctx = NULL; + EVP_SIGNATURE *signature = NULL; + EVP_KEYMGMT *tmp_keymgmt = NULL; + const OSSL_PROVIDER *tmp_prov = NULL; + const char *supported_sig = NULL; + char locmdname[80] = ""; /* 80 chars should be enough */ + void *provkey = NULL; + int ret, iter, reinit = 1; + + if (ctx->algctx != NULL) { + if (!ossl_assert(ctx->digest != NULL)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + if (ctx->digest->freectx != NULL) + ctx->digest->freectx(ctx->algctx); + ctx->algctx = NULL; + } + + if (ctx->pctx == NULL) { + reinit = 0; + if (e == NULL) + ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props); + else + ctx->pctx = EVP_PKEY_CTX_new(pkey, e); + } if (ctx->pctx == NULL) - ctx->pctx = EVP_PKEY_CTX_new(pkey, e); - if (ctx->pctx == NULL) return 0; + locpctx = ctx->pctx; + ERR_set_mark(); + + if (evp_pkey_ctx_is_legacy(locpctx)) + goto legacy; + + /* do not reinitialize if pkey is set or operation is different */ + if (reinit + && (pkey != NULL + || locpctx->operation != (ver ? EVP_PKEY_OP_VERIFYCTX + : EVP_PKEY_OP_SIGNCTX) + || (signature = locpctx->op.sig.signature) == NULL + || locpctx->op.sig.algctx == NULL)) + reinit = 0; + + if (props == NULL) + props = locpctx->propquery; + + if (locpctx->pkey == NULL) { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); + goto err; + } + + if (!reinit) { + evp_pkey_ctx_free_old_ops(locpctx); + } else { + if (mdname == NULL && type == NULL) + mdname = canon_mdname(EVP_MD_get0_name(ctx->reqdigest)); + goto reinitialize; + } + + /* + * Try to derive the supported signature from |locpctx->keymgmt|. + */ + if (!ossl_assert(locpctx->pkey->keymgmt == NULL + || locpctx->pkey->keymgmt == locpctx->keymgmt)) { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + goto err; + } + supported_sig = evp_keymgmt_util_query_operation_name(locpctx->keymgmt, + OSSL_OP_SIGNATURE); + if (supported_sig == NULL) { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + /* + * We perform two iterations: + * + * 1. Do the normal signature fetch, using the fetching data given by + * the EVP_PKEY_CTX. + * 2. Do the provider specific signature fetch, from the same provider + * as |ctx->keymgmt| + * + * We then try to fetch the keymgmt from the same provider as the + * signature, and try to export |ctx->pkey| to that keymgmt (when + * this keymgmt happens to be the same as |ctx->keymgmt|, the export + * is a no-op, but we call it anyway to not complicate the code even + * more). + * If the export call succeeds (returns a non-NULL provider key pointer), + * we're done and can perform the operation itself. If not, we perform + * the second iteration, or jump to legacy. + */ + for (iter = 1, provkey = NULL; iter < 3 && provkey == NULL; iter++) { + EVP_KEYMGMT *tmp_keymgmt_tofree = NULL; + + /* + * If we're on the second iteration, free the results from the first. + * They are NULL on the first iteration, so no need to check what + * iteration we're on. + */ + EVP_SIGNATURE_free(signature); + EVP_KEYMGMT_free(tmp_keymgmt); + + switch (iter) { + case 1: + signature = EVP_SIGNATURE_fetch(locpctx->libctx, supported_sig, + locpctx->propquery); + if (signature != NULL) + tmp_prov = EVP_SIGNATURE_get0_provider(signature); + break; + case 2: + tmp_prov = EVP_KEYMGMT_get0_provider(locpctx->keymgmt); + signature = + evp_signature_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, + supported_sig, locpctx->propquery); + if (signature == NULL) + goto legacy; + break; + } + if (signature == NULL) + continue; + + /* + * Ensure that the key is provided, either natively, or as a cached + * export. We start by fetching the keymgmt with the same name as + * |locpctx->pkey|, but from the provider of the signature method, using + * the same property query as when fetching the signature method. + * With the keymgmt we found (if we did), we try to export |locpctx->pkey| + * to it (evp_pkey_export_to_provider() is smart enough to only actually + + * export it if |tmp_keymgmt| is different from |locpctx->pkey|'s keymgmt) + */ + tmp_keymgmt_tofree = tmp_keymgmt = + evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, + EVP_KEYMGMT_get0_name(locpctx->keymgmt), + locpctx->propquery); + if (tmp_keymgmt != NULL) + provkey = evp_pkey_export_to_provider(locpctx->pkey, locpctx->libctx, + &tmp_keymgmt, locpctx->propquery); + if (tmp_keymgmt == NULL) + EVP_KEYMGMT_free(tmp_keymgmt_tofree); + } + + if (provkey == NULL) { + EVP_SIGNATURE_free(signature); + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + ERR_pop_to_mark(); + + /* No more legacy from here down to legacy: */ + + locpctx->op.sig.signature = signature; + locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX + : EVP_PKEY_OP_SIGNCTX; + locpctx->op.sig.algctx + = signature->newctx(ossl_provider_ctx(signature->prov), props); + if (locpctx->op.sig.algctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + reinitialize: + if (pctx != NULL) + *pctx = locpctx; + + if (type != NULL) { + ctx->reqdigest = type; + if (mdname == NULL) + mdname = canon_mdname(EVP_MD_get0_name(type)); + } else { + if (mdname == NULL && !reinit) { + if (evp_keymgmt_util_get_deflt_digest_name(tmp_keymgmt, provkey, + locmdname, + sizeof(locmdname)) > 0) { + mdname = canon_mdname(locmdname); + } + } + + if (mdname != NULL) { + /* + * We're about to get a new digest so clear anything associated with + * an old digest. + */ + evp_md_ctx_clear_digest(ctx, 1, 0); + + /* legacy code support for engines */ + ERR_set_mark(); + /* + * This might be requested by a later call to EVP_MD_CTX_get0_md(). + * In that case the "explicit fetch" rules apply for that + * function (as per man pages), i.e. the ref count is not updated + * so the EVP_MD should not be used beyound the lifetime of the + * EVP_MD_CTX. + */ + ctx->fetched_digest = EVP_MD_fetch(locpctx->libctx, mdname, props); + if (ctx->fetched_digest != NULL) { + ctx->digest = ctx->reqdigest = ctx->fetched_digest; + } else { + /* legacy engine support : remove the mark when this is deleted */ + ctx->reqdigest = ctx->digest = EVP_get_digestbyname(mdname); + if (ctx->digest == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + } + (void)ERR_pop_to_mark(); + } + } + + if (ver) { + if (signature->digest_verify_init == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + ret = signature->digest_verify_init(locpctx->op.sig.algctx, + mdname, provkey, params); + } else { + if (signature->digest_sign_init == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + ret = signature->digest_sign_init(locpctx->op.sig.algctx, + mdname, provkey, params); + } + + /* + * If the operation was not a success and no digest was found, an error + * needs to be raised. + */ + if (ret > 0 || mdname != NULL) + goto end; + if (type == NULL) /* This check is redundant but clarifies matters */ + ERR_raise(ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST); + + err: + evp_pkey_ctx_free_old_ops(locpctx); + locpctx->operation = EVP_PKEY_OP_UNDEFINED; + EVP_KEYMGMT_free(tmp_keymgmt); + return 0; + + legacy: + /* + * If we don't have the full support we need with provided methods, + * let's go see if legacy does. + */ + ERR_pop_to_mark(); + EVP_KEYMGMT_free(tmp_keymgmt); + tmp_keymgmt = NULL; + + if (type == NULL && mdname != NULL) + type = evp_get_digestbyname_ex(locpctx->libctx, mdname); + + if (ctx->pctx->pmeth == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) { if (type == NULL) { @@ -39,7 +315,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, } if (type == NULL) { - EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST); + ERR_raise(ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST); return 0; } } @@ -79,57 +355,184 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, * This indicates the current algorithm requires * special treatment before hashing the tbs-message. */ + ctx->pctx->flag_call_digest_custom = 0; if (ctx->pctx->pmeth->digest_custom != NULL) - return ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx); + ctx->pctx->flag_call_digest_custom = 1; - return 1; + ret = 1; + + end: +#ifndef FIPS_MODULE + if (ret > 0) + ret = evp_pkey_ctx_use_cached_data(locpctx); +#endif + + EVP_KEYMGMT_free(tmp_keymgmt); + return ret > 0 ? 1 : 0; +} + +int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const char *mdname, OSSL_LIB_CTX *libctx, + const char *props, EVP_PKEY *pkey, + const OSSL_PARAM params[]) +{ + return do_sigver_init(ctx, pctx, NULL, mdname, libctx, props, NULL, pkey, 0, + params); } int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, type, e, pkey, 0); + return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 0, + NULL); +} + +int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const char *mdname, OSSL_LIB_CTX *libctx, + const char *props, EVP_PKEY *pkey, + const OSSL_PARAM params[]) +{ + return do_sigver_init(ctx, pctx, NULL, mdname, libctx, props, NULL, pkey, 1, + params); } int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, type, e, pkey, 1); + return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 1, + NULL); +} +#endif /* FIPS_MDOE */ + +int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) +{ + EVP_PKEY_CTX *pctx = ctx->pctx; + + if (pctx == NULL + || pctx->operation != EVP_PKEY_OP_SIGNCTX + || pctx->op.sig.algctx == NULL + || pctx->op.sig.signature == NULL) + goto legacy; + + if (pctx->op.sig.signature->digest_sign_update == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + return pctx->op.sig.signature->digest_sign_update(pctx->op.sig.algctx, + data, dsize); + + legacy: + if (pctx != NULL) { + /* do_sigver_init() checked that |digest_custom| is non-NULL */ + if (pctx->flag_call_digest_custom + && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) + return 0; + pctx->flag_call_digest_custom = 0; + } + + return EVP_DigestUpdate(ctx, data, dsize); +} + +int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) +{ + EVP_PKEY_CTX *pctx = ctx->pctx; + + if (pctx == NULL + || pctx->operation != EVP_PKEY_OP_VERIFYCTX + || pctx->op.sig.algctx == NULL + || pctx->op.sig.signature == NULL) + goto legacy; + + if (pctx->op.sig.signature->digest_verify_update == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + return pctx->op.sig.signature->digest_verify_update(pctx->op.sig.algctx, + data, dsize); + + legacy: + if (pctx != NULL) { + /* do_sigver_init() checked that |digest_custom| is non-NULL */ + if (pctx->flag_call_digest_custom + && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) + return 0; + pctx->flag_call_digest_custom = 0; + } + + return EVP_DigestUpdate(ctx, data, dsize); } +#ifndef FIPS_MODULE int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) { int sctx = 0, r = 0; - EVP_PKEY_CTX *pctx = ctx->pctx; + EVP_PKEY_CTX *dctx, *pctx = ctx->pctx; + + if (pctx == NULL + || pctx->operation != EVP_PKEY_OP_SIGNCTX + || pctx->op.sig.algctx == NULL + || pctx->op.sig.signature == NULL) + goto legacy; + + if (sigret == NULL || (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0) + return pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx, + sigret, siglen, + sigret == NULL ? 0 : *siglen); + dctx = EVP_PKEY_CTX_dup(pctx); + if (dctx == NULL) + return 0; + + r = dctx->op.sig.signature->digest_sign_final(dctx->op.sig.algctx, + sigret, siglen, + *siglen); + EVP_PKEY_CTX_free(dctx); + return r; + + legacy: + if (pctx == NULL || pctx->pmeth == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + + /* do_sigver_init() checked that |digest_custom| is non-NULL */ + if (pctx->flag_call_digest_custom + && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) + return 0; + pctx->flag_call_digest_custom = 0; + if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) { - if (!sigret) + if (sigret == NULL) return pctx->pmeth->signctx(pctx, sigret, siglen, ctx); if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx); else { - EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(ctx->pctx); - if (!dctx) + dctx = EVP_PKEY_CTX_dup(pctx); + if (dctx == NULL) return 0; r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx); EVP_PKEY_CTX_free(dctx); } return r; } - if (pctx->pmeth->signctx) + if (pctx->pmeth->signctx != NULL) sctx = 1; else sctx = 0; - if (sigret) { + if (sigret != NULL) { unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen = 0; + if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) { if (sctx) - r = ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx); + r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx); else r = EVP_DigestFinal_ex(ctx, md, &mdlen); } else { EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); + if (tmp_ctx == NULL) return 0; if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) { @@ -145,14 +548,15 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, } if (sctx || !r) return r; - if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0) + if (EVP_PKEY_sign(pctx, sigret, siglen, md, mdlen) <= 0) return 0; } else { if (sctx) { if (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0) return 0; } else { - int s = EVP_MD_size(ctx->digest); + int s = EVP_MD_get_size(ctx->digest); + if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0) return 0; } @@ -163,8 +567,23 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, const unsigned char *tbs, size_t tbslen) { - if (ctx->pctx->pmeth->digestsign != NULL) - return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen); + EVP_PKEY_CTX *pctx = ctx->pctx; + + if (pctx != NULL + && pctx->operation == EVP_PKEY_OP_SIGNCTX + && pctx->op.sig.algctx != NULL + && pctx->op.sig.signature != NULL) { + if (pctx->op.sig.signature->digest_sign != NULL) + return pctx->op.sig.signature->digest_sign(pctx->op.sig.algctx, + sigret, siglen, + sigret == NULL ? 0 : *siglen, + tbs, tbslen); + } else { + /* legacy */ + if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL) + return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen); + } + if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0) return 0; return EVP_DigestSignFinal(ctx, sigret, siglen); @@ -177,14 +596,45 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, int r = 0; unsigned int mdlen = 0; int vctx = 0; + EVP_PKEY_CTX *dctx, *pctx = ctx->pctx; - if (ctx->pctx->pmeth->verifyctx) + if (pctx == NULL + || pctx->operation != EVP_PKEY_OP_VERIFYCTX + || pctx->op.sig.algctx == NULL + || pctx->op.sig.signature == NULL) + goto legacy; + + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0) + return pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx, + sig, siglen); + dctx = EVP_PKEY_CTX_dup(pctx); + if (dctx == NULL) + return 0; + + r = dctx->op.sig.signature->digest_verify_final(dctx->op.sig.algctx, + sig, siglen); + EVP_PKEY_CTX_free(dctx); + return r; + + legacy: + if (pctx == NULL || pctx->pmeth == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + + /* do_sigver_init() checked that |digest_custom| is non-NULL */ + if (pctx->flag_call_digest_custom + && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) + return 0; + pctx->flag_call_digest_custom = 0; + + if (pctx->pmeth->verifyctx != NULL) vctx = 1; else vctx = 0; if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) { if (vctx) - r = ctx->pctx->pmeth->verifyctx(ctx->pctx, sig, siglen, ctx); + r = pctx->pmeth->verifyctx(pctx, sig, siglen, ctx); else r = EVP_DigestFinal_ex(ctx, md, &mdlen); } else { @@ -204,15 +654,30 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, } if (vctx || !r) return r; - return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen); + return EVP_PKEY_verify(pctx, sig, siglen, md, mdlen); } int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen) { - if (ctx->pctx->pmeth->digestverify != NULL) - return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen); + EVP_PKEY_CTX *pctx = ctx->pctx; + + if (pctx != NULL + && pctx->operation == EVP_PKEY_OP_VERIFYCTX + && pctx->op.sig.algctx != NULL + && pctx->op.sig.signature != NULL) { + if (pctx->op.sig.signature->digest_verify != NULL) + return pctx->op.sig.signature->digest_verify(pctx->op.sig.algctx, + sigret, siglen, + tbs, tbslen); + } else { + /* legacy */ + if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL) + return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen); + } + if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0) return -1; return EVP_DigestVerifyFinal(ctx, sigret, siglen); } +#endif /* FIPS_MODULE */ diff --git a/crypto/openssl/crypto/evp/m_wp.c b/crypto/openssl/crypto/evp/m_wp.c deleted file mode 100644 index 5ce15d2d5e57..000000000000 --- a/crypto/openssl/crypto/evp/m_wp.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2005-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 - */ - -#include -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_WHIRLPOOL - -# include -# include -# include -# include -# include "crypto/evp.h" - -static int init(EVP_MD_CTX *ctx) -{ - return WHIRLPOOL_Init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return WHIRLPOOL_Update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return WHIRLPOOL_Final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD whirlpool_md = { - NID_whirlpool, - 0, - WHIRLPOOL_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - WHIRLPOOL_BBLOCK / 8, - sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX), -}; - -const EVP_MD *EVP_whirlpool(void) -{ - return &whirlpool_md; -} -#endif diff --git a/crypto/openssl/crypto/evp/mac_lib.c b/crypto/openssl/crypto/evp/mac_lib.c new file mode 100644 index 000000000000..90c79715d757 --- /dev/null +++ b/crypto/openssl/crypto/evp/mac_lib.c @@ -0,0 +1,303 @@ +/* + * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include "internal/nelem.h" +#include "crypto/evp.h" +#include "internal/provider.h" +#include "evp_local.h" + +EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac) +{ + EVP_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_MAC_CTX)); + + if (ctx == NULL + || (ctx->algctx = mac->newctx(ossl_provider_ctx(mac->prov))) == NULL + || !EVP_MAC_up_ref(mac)) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (ctx != NULL) + mac->freectx(ctx->algctx); + OPENSSL_free(ctx); + ctx = NULL; + } else { + ctx->meth = mac; + } + return ctx; +} + +void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx) +{ + if (ctx == NULL) + return; + ctx->meth->freectx(ctx->algctx); + ctx->algctx = NULL; + /* refcnt-- */ + EVP_MAC_free(ctx->meth); + OPENSSL_free(ctx); +} + +EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src) +{ + EVP_MAC_CTX *dst; + + if (src->algctx == NULL) + return NULL; + + dst = OPENSSL_malloc(sizeof(*dst)); + if (dst == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + *dst = *src; + if (!EVP_MAC_up_ref(dst->meth)) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(dst); + return NULL; + } + + dst->algctx = src->meth->dupctx(src->algctx); + if (dst->algctx == NULL) { + EVP_MAC_CTX_free(dst); + return NULL; + } + + return dst; +} + +EVP_MAC *EVP_MAC_CTX_get0_mac(EVP_MAC_CTX *ctx) +{ + return ctx->meth; +} + +static size_t get_size_t_ctx_param(EVP_MAC_CTX *ctx, const char *name) +{ + size_t sz = 0; + + if (ctx->algctx != NULL) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_size_t(name, &sz); + if (ctx->meth->get_ctx_params != NULL) { + if (ctx->meth->get_ctx_params(ctx->algctx, params)) + return sz; + } else if (ctx->meth->get_params != NULL) { + if (ctx->meth->get_params(params)) + return sz; + } + } + /* + * If the MAC hasn't been initialized yet, or there is no size to get, + * we return zero + */ + return 0; +} + +size_t EVP_MAC_CTX_get_mac_size(EVP_MAC_CTX *ctx) +{ + return get_size_t_ctx_param(ctx, OSSL_MAC_PARAM_SIZE); +} + +size_t EVP_MAC_CTX_get_block_size(EVP_MAC_CTX *ctx) +{ + return get_size_t_ctx_param(ctx, OSSL_MAC_PARAM_BLOCK_SIZE); +} + +int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen, + const OSSL_PARAM params[]) +{ + return ctx->meth->init(ctx->algctx, key, keylen, params); +} + +int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen) +{ + return ctx->meth->update(ctx->algctx, data, datalen); +} + +static int evp_mac_final(EVP_MAC_CTX *ctx, int xof, + unsigned char *out, size_t *outl, size_t outsize) +{ + size_t l; + int res; + OSSL_PARAM params[2]; + size_t macsize; + + if (ctx == NULL || ctx->meth == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_NULL_ALGORITHM); + return 0; + } + if (ctx->meth->final == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + + macsize = EVP_MAC_CTX_get_mac_size(ctx); + if (out == NULL) { + if (outl == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + *outl = macsize; + return 1; + } + if (outsize < macsize) { + ERR_raise(ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + if (xof) { + params[0] = OSSL_PARAM_construct_int(OSSL_MAC_PARAM_XOF, &xof); + params[1] = OSSL_PARAM_construct_end(); + + if (EVP_MAC_CTX_set_params(ctx, params) <= 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_SETTING_XOF_FAILED); + return 0; + } + } + res = ctx->meth->final(ctx->algctx, out, &l, outsize); + if (outl != NULL) + *outl = l; + return res; +} + +int EVP_MAC_final(EVP_MAC_CTX *ctx, + unsigned char *out, size_t *outl, size_t outsize) +{ + return evp_mac_final(ctx, 0, out, outl, outsize); +} + +int EVP_MAC_finalXOF(EVP_MAC_CTX *ctx, unsigned char *out, size_t outsize) +{ + return evp_mac_final(ctx, 1, out, NULL, outsize); +} + +/* + * The {get,set}_params functions return 1 if there is no corresponding + * function in the implementation. This is the same as if there was one, + * but it didn't recognise any of the given params, i.e. nothing in the + * bag of parameters was useful. + */ +int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]) +{ + if (mac->get_params != NULL) + return mac->get_params(params); + return 1; +} + +int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]) +{ + if (ctx->meth->get_ctx_params != NULL) + return ctx->meth->get_ctx_params(ctx->algctx, params); + return 1; +} + +int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]) +{ + if (ctx->meth->set_ctx_params != NULL) + return ctx->meth->set_ctx_params(ctx->algctx, params); + return 1; +} + +int evp_mac_get_number(const EVP_MAC *mac) +{ + return mac->name_id; +} + +const char *EVP_MAC_get0_name(const EVP_MAC *mac) +{ + return mac->type_name; +} + +const char *EVP_MAC_get0_description(const EVP_MAC *mac) +{ + return mac->description; +} + +int EVP_MAC_is_a(const EVP_MAC *mac, const char *name) +{ + return mac != NULL && evp_is_a(mac->prov, mac->name_id, NULL, name); +} + +int EVP_MAC_names_do_all(const EVP_MAC *mac, + void (*fn)(const char *name, void *data), + void *data) +{ + if (mac->prov != NULL) + return evp_names_do_all(mac->prov, mac->name_id, fn, data); + + return 1; +} + +unsigned char *EVP_Q_mac(OSSL_LIB_CTX *libctx, + const char *name, const char *propq, + const char *subalg, const OSSL_PARAM *params, + const void *key, size_t keylen, + const unsigned char *data, size_t datalen, + unsigned char *out, size_t outsize, size_t *outlen) +{ + EVP_MAC *mac = EVP_MAC_fetch(libctx, name, propq); + OSSL_PARAM subalg_param[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + EVP_MAC_CTX *ctx = NULL; + size_t len = 0; + unsigned char *res = NULL; + + if (outlen != NULL) + *outlen = 0; + if (mac == NULL) + return NULL; + if (subalg != NULL) { + const OSSL_PARAM *defined_params = EVP_MAC_settable_ctx_params(mac); + const char *param_name = OSSL_MAC_PARAM_DIGEST; + + /* + * The underlying algorithm may be a cipher or a digest. + * We don't know which it is, but we can ask the MAC what it + * should be and bet on that. + */ + if (OSSL_PARAM_locate_const(defined_params, param_name) == NULL) { + param_name = OSSL_MAC_PARAM_CIPHER; + if (OSSL_PARAM_locate_const(defined_params, param_name) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + } + subalg_param[0] = + OSSL_PARAM_construct_utf8_string(param_name, (char *)subalg, 0); + } + /* Single-shot - on NULL key input, set dummy key value for EVP_MAC_Init. */ + if (key == NULL && keylen == 0) + key = data; + if ((ctx = EVP_MAC_CTX_new(mac)) != NULL + && EVP_MAC_CTX_set_params(ctx, subalg_param) + && EVP_MAC_CTX_set_params(ctx, params) + && EVP_MAC_init(ctx, key, keylen, params) + && EVP_MAC_update(ctx, data, datalen) + && EVP_MAC_final(ctx, out, &len, outsize)) { + if (out == NULL) { + out = OPENSSL_malloc(len); + if (out != NULL && !EVP_MAC_final(ctx, out, NULL, len)) { + OPENSSL_free(out); + out = NULL; + } + } + res = out; + if (res != NULL && outlen != NULL) + *outlen = len; + } + + err: + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + return res; +} diff --git a/crypto/openssl/crypto/evp/mac_meth.c b/crypto/openssl/crypto/evp/mac_meth.c new file mode 100644 index 000000000000..85fe7704fde2 --- /dev/null +++ b/crypto/openssl/crypto/evp/mac_meth.c @@ -0,0 +1,246 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/provider.h" +#include "internal/core.h" +#include "crypto/evp.h" +#include "evp_local.h" + +static int evp_mac_up_ref(void *vmac) +{ + EVP_MAC *mac = vmac; + int ref = 0; + + CRYPTO_UP_REF(&mac->refcnt, &ref, mac->lock); + return 1; +} + +static void evp_mac_free(void *vmac) +{ + EVP_MAC *mac = vmac; + int ref = 0; + + if (mac == NULL) + return; + + CRYPTO_DOWN_REF(&mac->refcnt, &ref, mac->lock); + if (ref > 0) + return; + OPENSSL_free(mac->type_name); + ossl_provider_free(mac->prov); + CRYPTO_THREAD_lock_free(mac->lock); + OPENSSL_free(mac); +} + +static void *evp_mac_new(void) +{ + EVP_MAC *mac = NULL; + + if ((mac = OPENSSL_zalloc(sizeof(*mac))) == NULL + || (mac->lock = CRYPTO_THREAD_lock_new()) == NULL) { + evp_mac_free(mac); + return NULL; + } + + mac->refcnt = 1; + + return mac; +} + +static void *evp_mac_from_algorithm(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + const OSSL_DISPATCH *fns = algodef->implementation; + EVP_MAC *mac = NULL; + int fnmaccnt = 0, fnctxcnt = 0; + + if ((mac = evp_mac_new()) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + mac->name_id = name_id; + if ((mac->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { + evp_mac_free(mac); + return NULL; + } + mac->description = algodef->algorithm_description; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_MAC_NEWCTX: + if (mac->newctx != NULL) + break; + mac->newctx = OSSL_FUNC_mac_newctx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_MAC_DUPCTX: + if (mac->dupctx != NULL) + break; + mac->dupctx = OSSL_FUNC_mac_dupctx(fns); + break; + case OSSL_FUNC_MAC_FREECTX: + if (mac->freectx != NULL) + break; + mac->freectx = OSSL_FUNC_mac_freectx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_MAC_INIT: + if (mac->init != NULL) + break; + mac->init = OSSL_FUNC_mac_init(fns); + fnmaccnt++; + break; + case OSSL_FUNC_MAC_UPDATE: + if (mac->update != NULL) + break; + mac->update = OSSL_FUNC_mac_update(fns); + fnmaccnt++; + break; + case OSSL_FUNC_MAC_FINAL: + if (mac->final != NULL) + break; + mac->final = OSSL_FUNC_mac_final(fns); + fnmaccnt++; + break; + case OSSL_FUNC_MAC_GETTABLE_PARAMS: + if (mac->gettable_params != NULL) + break; + mac->gettable_params = + OSSL_FUNC_mac_gettable_params(fns); + break; + case OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS: + if (mac->gettable_ctx_params != NULL) + break; + mac->gettable_ctx_params = + OSSL_FUNC_mac_gettable_ctx_params(fns); + break; + case OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS: + if (mac->settable_ctx_params != NULL) + break; + mac->settable_ctx_params = + OSSL_FUNC_mac_settable_ctx_params(fns); + break; + case OSSL_FUNC_MAC_GET_PARAMS: + if (mac->get_params != NULL) + break; + mac->get_params = OSSL_FUNC_mac_get_params(fns); + break; + case OSSL_FUNC_MAC_GET_CTX_PARAMS: + if (mac->get_ctx_params != NULL) + break; + mac->get_ctx_params = OSSL_FUNC_mac_get_ctx_params(fns); + break; + case OSSL_FUNC_MAC_SET_CTX_PARAMS: + if (mac->set_ctx_params != NULL) + break; + mac->set_ctx_params = OSSL_FUNC_mac_set_ctx_params(fns); + break; + } + } + if (fnmaccnt != 3 + || fnctxcnt != 2) { + /* + * In order to be a consistent set of functions we must have at least + * a complete set of "mac" functions, and a complete set of context + * management functions, as well as the size function. + */ + evp_mac_free(mac); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + mac->prov = prov; + if (prov != NULL) + ossl_provider_up_ref(prov); + + return mac; +} + +EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties, + evp_mac_from_algorithm, evp_mac_up_ref, + evp_mac_free); +} + +int EVP_MAC_up_ref(EVP_MAC *mac) +{ + return evp_mac_up_ref(mac); +} + +void EVP_MAC_free(EVP_MAC *mac) +{ + evp_mac_free(mac); +} + +const OSSL_PROVIDER *EVP_MAC_get0_provider(const EVP_MAC *mac) +{ + return mac->prov; +} + +const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac) +{ + if (mac->gettable_params == NULL) + return NULL; + return mac->gettable_params(ossl_provider_ctx(EVP_MAC_get0_provider(mac))); +} + +const OSSL_PARAM *EVP_MAC_gettable_ctx_params(const EVP_MAC *mac) +{ + void *alg; + + if (mac->gettable_ctx_params == NULL) + return NULL; + alg = ossl_provider_ctx(EVP_MAC_get0_provider(mac)); + return mac->gettable_ctx_params(NULL, alg); +} + +const OSSL_PARAM *EVP_MAC_settable_ctx_params(const EVP_MAC *mac) +{ + void *alg; + + if (mac->settable_ctx_params == NULL) + return NULL; + alg = ossl_provider_ctx(EVP_MAC_get0_provider(mac)); + return mac->settable_ctx_params(NULL, alg); +} + +const OSSL_PARAM *EVP_MAC_CTX_gettable_params(EVP_MAC_CTX *ctx) +{ + void *alg; + + if (ctx->meth->gettable_ctx_params == NULL) + return NULL; + alg = ossl_provider_ctx(EVP_MAC_get0_provider(ctx->meth)); + return ctx->meth->gettable_ctx_params(ctx->algctx, alg); +} + +const OSSL_PARAM *EVP_MAC_CTX_settable_params(EVP_MAC_CTX *ctx) +{ + void *alg; + + if (ctx->meth->settable_ctx_params == NULL) + return NULL; + alg = ossl_provider_ctx(EVP_MAC_get0_provider(ctx->meth)); + return ctx->meth->settable_ctx_params(ctx->algctx, alg); +} + +void EVP_MAC_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_MAC *mac, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_MAC, + (void (*)(void *, void *))fn, arg, + evp_mac_from_algorithm, evp_mac_up_ref, evp_mac_free); +} diff --git a/crypto/openssl/crypto/evp/names.c b/crypto/openssl/crypto/evp/names.c index 90c7b73b7a49..19c03a3085e8 100644 --- a/crypto/openssl/crypto/evp/names.c +++ b/crypto/openssl/crypto/evp/names.c @@ -1,17 +1,19 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include -#include "internal/cryptlib.h" #include -#include "crypto/objects.h" +#include #include +#include "internal/cryptlib.h" +#include "internal/namemap.h" +#include "crypto/objects.h" #include "crypto/evp.h" int EVP_add_cipher(const EVP_CIPHER *c) @@ -55,30 +57,102 @@ int EVP_add_digest(const EVP_MD *md) return r; } +static void cipher_from_name(const char *name, void *data) +{ + const EVP_CIPHER **cipher = data; + + if (*cipher != NULL) + return; + + *cipher = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); +} + const EVP_CIPHER *EVP_get_cipherbyname(const char *name) +{ + return evp_get_cipherbyname_ex(NULL, name); +} + +const EVP_CIPHER *evp_get_cipherbyname_ex(OSSL_LIB_CTX *libctx, + const char *name) { const EVP_CIPHER *cp; + OSSL_NAMEMAP *namemap; + int id; if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL)) return NULL; cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); + + if (cp != NULL) + return cp; + + /* + * It's not in the method database, but it might be there under a different + * name. So we check for aliases in the EVP namemap and try all of those + * in turn. + */ + + namemap = ossl_namemap_stored(libctx); + id = ossl_namemap_name2num(namemap, name); + if (id == 0) + return NULL; + + if (!ossl_namemap_doall_names(namemap, id, cipher_from_name, &cp)) + return NULL; + return cp; } +static void digest_from_name(const char *name, void *data) +{ + const EVP_MD **md = data; + + if (*md != NULL) + return; + + *md = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); +} + const EVP_MD *EVP_get_digestbyname(const char *name) { - const EVP_MD *cp; + return evp_get_digestbyname_ex(NULL, name); +} + +const EVP_MD *evp_get_digestbyname_ex(OSSL_LIB_CTX *libctx, const char *name) +{ + const EVP_MD *dp; + OSSL_NAMEMAP *namemap; + int id; if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)) return NULL; - cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); - return cp; + dp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); + + if (dp != NULL) + return dp; + + /* + * It's not in the method database, but it might be there under a different + * name. So we check for aliases in the EVP namemap and try all of those + * in turn. + */ + + namemap = ossl_namemap_stored(libctx); + id = ossl_namemap_name2num(namemap, name); + if (id == 0) + return NULL; + + if (!ossl_namemap_doall_names(namemap, id, digest_from_name, &dp)) + return NULL; + + return dp; } void evp_cleanup_int(void) { + OBJ_NAME_cleanup(OBJ_NAME_TYPE_KDF_METH); OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH); OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH); /* diff --git a/crypto/openssl/crypto/evp/p5_crpt.c b/crypto/openssl/crypto/evp/p5_crpt.c index 6c5f45f73368..f3ac675ff2e3 100644 --- a/crypto/openssl/crypto/evp/p5_crpt.c +++ b/crypto/openssl/crypto/evp/p5_crpt.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,6 +12,8 @@ #include "internal/cryptlib.h" #include #include +#include +#include /* * Doesn't do anything now: Builtin PBE algorithms in static table. @@ -21,85 +23,79 @@ void PKCS5_PBE_add(void) { } -int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, - ASN1_TYPE *param, const EVP_CIPHER *cipher, - const EVP_MD *md, int en_de) +int PKCS5_PBE_keyivgen_ex(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de, OSSL_LIB_CTX *libctx, + const char *propq) { - EVP_MD_CTX *ctx; unsigned char md_tmp[EVP_MAX_MD_SIZE]; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; - int i, ivl, kl; - PBEPARAM *pbe; + int ivl, kl; + PBEPARAM *pbe = NULL; int saltlen, iter; unsigned char *salt; int mdsize; int rv = 0; + EVP_KDF *kdf; + EVP_KDF_CTX *kctx = NULL; + OSSL_PARAM params[5], *p = params; + const char *mdname = EVP_MD_name(md); /* Extract useful info from parameter */ if (param == NULL || param->type != V_ASN1_SEQUENCE || param->value.sequence == NULL) { - EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); return 0; } pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param); if (pbe == NULL) { - EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); return 0; } - ivl = EVP_CIPHER_iv_length(cipher); + ivl = EVP_CIPHER_get_iv_length(cipher); if (ivl < 0 || ivl > 16) { - EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_INVALID_IV_LENGTH); - PBEPARAM_free(pbe); - return 0; + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH); + goto err; } - kl = EVP_CIPHER_key_length(cipher); + kl = EVP_CIPHER_get_key_length(cipher); if (kl < 0 || kl > (int)sizeof(md_tmp)) { - EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_INVALID_KEY_LENGTH); - PBEPARAM_free(pbe); - return 0; + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH); + goto err; } - if (!pbe->iter) + if (pbe->iter == NULL) iter = 1; else iter = ASN1_INTEGER_get(pbe->iter); salt = pbe->salt->data; saltlen = pbe->salt->length; - if (!pass) + if (pass == NULL) passlen = 0; else if (passlen == -1) passlen = strlen(pass); - ctx = EVP_MD_CTX_new(); - if (ctx == NULL) { - EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, ERR_R_MALLOC_FAILURE); + mdsize = EVP_MD_get_size(md); + if (mdsize < 0) goto err; - } - if (!EVP_DigestInit_ex(ctx, md, NULL)) - goto err; - if (!EVP_DigestUpdate(ctx, pass, passlen)) - goto err; - if (!EVP_DigestUpdate(ctx, salt, saltlen)) + kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_PBKDF1, propq); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (kctx == NULL) goto err; - PBEPARAM_free(pbe); - pbe = NULL; - if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL)) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, + (char *)pass, (size_t)passlen); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + salt, saltlen); + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, 0); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_derive(kctx, md_tmp, mdsize, params) != 1) goto err; - mdsize = EVP_MD_size(md); - if (mdsize < 0) - return 0; - for (i = 1; i < iter; i++) { - if (!EVP_DigestInit_ex(ctx, md, NULL)) - goto err; - if (!EVP_DigestUpdate(ctx, md_tmp, mdsize)) - goto err; - if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL)) - goto err; - } memcpy(key, md_tmp, kl); memcpy(iv, md_tmp + (16 - ivl), ivl); if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de)) @@ -109,7 +105,16 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); rv = 1; err: + EVP_KDF_CTX_free(kctx); PBEPARAM_free(pbe); - EVP_MD_CTX_free(ctx); return rv; } + +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de) +{ + return PKCS5_PBE_keyivgen_ex(cctx, pass, passlen, param, cipher, md, en_de, + NULL, NULL); +} + diff --git a/crypto/openssl/crypto/evp/p5_crpt2.c b/crypto/openssl/crypto/evp/p5_crpt2.c index 7f625b3d57f3..b7455be1cf0a 100644 --- a/crypto/openssl/crypto/evp/p5_crpt2.c +++ b/crypto/openssl/crypto/evp/p5_crpt2.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,123 +10,97 @@ #include #include #include "internal/cryptlib.h" -# include -# include -# include -# include "evp_local.h" +#include +#include +#include +#include +#include +#include +#include "crypto/evp.h" +#include "evp_local.h" -/* set this to print out info about the keygen algorithm */ -/* #define OPENSSL_DEBUG_PKCS5V2 */ - -# ifdef OPENSSL_DEBUG_PKCS5V2 -static void h__dump(const unsigned char *p, int len); -# endif - -/* - * This is an implementation of PKCS#5 v2.0 password based encryption key - * derivation function PBKDF2. SHA1 version verified against test vectors - * posted by Peter Gutmann to the PKCS-TNG mailing list. - */ - -int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, - const unsigned char *salt, int saltlen, int iter, - const EVP_MD *digest, int keylen, unsigned char *out) +int ossl_pkcs5_pbkdf2_hmac_ex(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out, + OSSL_LIB_CTX *libctx, const char *propq) { const char *empty = ""; - unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; - int cplen, j, k, tkeylen, mdlen; - unsigned long i = 1; - HMAC_CTX *hctx_tpl = NULL, *hctx = NULL; + int rv = 1, mode = 1; + EVP_KDF *kdf; + EVP_KDF_CTX *kctx; + const char *mdname = EVP_MD_get0_name(digest); + OSSL_PARAM params[6], *p = params; - mdlen = EVP_MD_size(digest); - if (mdlen < 0) - return 0; - - hctx_tpl = HMAC_CTX_new(); - if (hctx_tpl == NULL) - return 0; - p = out; - tkeylen = keylen; + /* Keep documented behaviour. */ if (pass == NULL) { pass = empty; passlen = 0; } else if (passlen == -1) { passlen = strlen(pass); } - if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) { - HMAC_CTX_free(hctx_tpl); - return 0; - } - hctx = HMAC_CTX_new(); - if (hctx == NULL) { - HMAC_CTX_free(hctx_tpl); + if (salt == NULL && saltlen == 0) + salt = (unsigned char *)empty; + + kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_PBKDF2, propq); + if (kdf == NULL) + return 0; + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (kctx == NULL) return 0; - } - while (tkeylen) { - if (tkeylen > mdlen) - cplen = mdlen; - else - cplen = tkeylen; - /* - * We are unlikely to ever use more than 256 blocks (5120 bits!) but - * just in case... - */ - itmp[0] = (unsigned char)((i >> 24) & 0xff); - itmp[1] = (unsigned char)((i >> 16) & 0xff); - itmp[2] = (unsigned char)((i >> 8) & 0xff); - itmp[3] = (unsigned char)(i & 0xff); - if (!HMAC_CTX_copy(hctx, hctx_tpl)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - if (!HMAC_Update(hctx, salt, saltlen) - || !HMAC_Update(hctx, itmp, 4) - || !HMAC_Final(hctx, digtmp, NULL)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - memcpy(p, digtmp, cplen); - for (j = 1; j < iter; j++) { - if (!HMAC_CTX_copy(hctx, hctx_tpl)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - if (!HMAC_Update(hctx, digtmp, mdlen) - || !HMAC_Final(hctx, digtmp, NULL)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - for (k = 0; k < cplen; k++) - p[k] ^= digtmp[k]; - } - tkeylen -= cplen; - i++; - p += cplen; - } - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); -# ifdef OPENSSL_DEBUG_PKCS5V2 - fprintf(stderr, "Password:\n"); - h__dump(pass, passlen); - fprintf(stderr, "Salt:\n"); - h__dump(salt, saltlen); - fprintf(stderr, "Iteration count %d\n", iter); - fprintf(stderr, "Key:\n"); - h__dump(out, keylen); -# endif - return 1; + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, + (char *)pass, (size_t)passlen); + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS5, &mode); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + (unsigned char *)salt, saltlen); + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, 0); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_derive(kctx, out, keylen, params) != 1) + rv = 0; + + EVP_KDF_CTX_free(kctx); + + OSSL_TRACE_BEGIN(PKCS5V2) { + BIO_printf(trc_out, "Password:\n"); + BIO_hex_string(trc_out, + 0, passlen, pass, passlen); + BIO_printf(trc_out, "\n"); + BIO_printf(trc_out, "Salt:\n"); + BIO_hex_string(trc_out, + 0, saltlen, salt, saltlen); + BIO_printf(trc_out, "\n"); + BIO_printf(trc_out, "Iteration count %d\n", iter); + BIO_printf(trc_out, "Key:\n"); + BIO_hex_string(trc_out, + 0, keylen, out, keylen); + BIO_printf(trc_out, "\n"); + } OSSL_TRACE_END(PKCS5V2); + return rv; } +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, + int saltlen, int iter, const EVP_MD *digest, int keylen, + unsigned char *out) +{ + return ossl_pkcs5_pbkdf2_hmac_ex(pass, passlen, salt, saltlen, iter, digest, + keylen, out, NULL, NULL); +} + + int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, int keylen, unsigned char *out) { - return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(), - keylen, out); + EVP_MD *digest; + int r = 0; + + if ((digest = EVP_MD_fetch(NULL, SN_sha1, NULL)) != NULL) + r = ossl_pkcs5_pbkdf2_hmac_ex(pass, passlen, salt, saltlen, iter, + digest, keylen, out, NULL, NULL); + EVP_MD_free(digest); + return r; } /* @@ -135,71 +109,93 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, * them... */ -int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, - ASN1_TYPE *param, const EVP_CIPHER *c, - const EVP_MD *md, int en_de) +int PKCS5_v2_PBE_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *c, + const EVP_MD *md, int en_de, + OSSL_LIB_CTX *libctx, const char *propq) { PBE2PARAM *pbe2 = NULL; - const EVP_CIPHER *cipher; - EVP_PBE_KEYGEN *kdf; + char ciph_name[80]; + const EVP_CIPHER *cipher = NULL; + EVP_CIPHER *cipher_fetch = NULL; + EVP_PBE_KEYGEN_EX *kdf; int rv = 0; pbe2 = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBE2PARAM), param); if (pbe2 == NULL) { - EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); goto err; } /* See if we recognise the key derivation function */ - if (!EVP_PBE_find(EVP_PBE_TYPE_KDF, OBJ_obj2nid(pbe2->keyfunc->algorithm), - NULL, NULL, &kdf)) { - EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, - EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); + if (!EVP_PBE_find_ex(EVP_PBE_TYPE_KDF, OBJ_obj2nid(pbe2->keyfunc->algorithm), + NULL, NULL, NULL, &kdf)) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); goto err; } /* * lets see if we recognise the encryption algorithm. */ + if (OBJ_obj2txt(ciph_name, sizeof(ciph_name), pbe2->encryption->algorithm, 0) <= 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER); + goto err; + } - cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm); + (void)ERR_set_mark(); + cipher = cipher_fetch = EVP_CIPHER_fetch(libctx, ciph_name, propq); + /* Fallback to legacy method */ + if (cipher == NULL) + cipher = EVP_get_cipherbyname(ciph_name); - if (!cipher) { - EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_CIPHER); + if (cipher == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER); goto err; } + (void)ERR_pop_to_mark(); /* Fixup cipher based on AlgorithmIdentifier */ if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de)) goto err; - if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) { - EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR); + if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) <= 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_CIPHER_PARAMETER_ERROR); goto err; } - rv = kdf(ctx, pass, passlen, pbe2->keyfunc->parameter, NULL, NULL, en_de); + rv = kdf(ctx, pass, passlen, pbe2->keyfunc->parameter, NULL, NULL, en_de, libctx, propq); err: + EVP_CIPHER_free(cipher_fetch); PBE2PARAM_free(pbe2); return rv; } -int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, - int passlen, ASN1_TYPE *param, - const EVP_CIPHER *c, const EVP_MD *md, int en_de) +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *c, + const EVP_MD *md, int en_de) +{ + return PKCS5_v2_PBE_keyivgen_ex(ctx, pass, passlen, param, c, md, en_de, NULL, NULL); +} + +int PKCS5_v2_PBKDF2_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, int en_de, + OSSL_LIB_CTX *libctx, const char *propq) { unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; - int saltlen, iter; + int saltlen, iter, t; int rv = 0; unsigned int keylen = 0; int prf_nid, hmac_md_nid; PBKDF2PARAM *kdf = NULL; - const EVP_MD *prfmd; + const EVP_MD *prfmd = NULL; + EVP_MD *prfmd_fetch = NULL; - if (EVP_CIPHER_CTX_cipher(ctx) == NULL) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET); + if (EVP_CIPHER_CTX_get0_cipher(ctx) == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); goto err; } - keylen = EVP_CIPHER_CTX_key_length(ctx); + keylen = EVP_CIPHER_CTX_get_key_length(ctx); OPENSSL_assert(keylen <= sizeof(key)); /* Decode parameter */ @@ -207,16 +203,21 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, kdf = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), param); if (kdf == NULL) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); goto err; } - keylen = EVP_CIPHER_CTX_key_length(ctx); + t = EVP_CIPHER_CTX_get_key_length(ctx); + if (t < 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH); + goto err; + } + keylen = t; /* Now check the parameters of the kdf */ if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_KEYLENGTH); + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEYLENGTH); goto err; } @@ -226,18 +227,20 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, prf_nid = NID_hmacWithSHA1; if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRF); goto err; } - prfmd = EVP_get_digestbynid(hmac_md_nid); + prfmd = prfmd_fetch = EVP_MD_fetch(libctx, OBJ_nid2sn(hmac_md_nid), propq); + if (prfmd == NULL) + prfmd = EVP_get_digestbynid(hmac_md_nid); if (prfmd == NULL) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRF); goto err; } if (kdf->salt->type != V_ASN1_OCTET_STRING) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_SALT_TYPE); + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_SALT_TYPE); goto err; } @@ -245,21 +248,21 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, salt = kdf->salt->value.octet_string->data; saltlen = kdf->salt->value.octet_string->length; iter = ASN1_INTEGER_get(kdf->iter); - if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd, - keylen, key)) + if (!ossl_pkcs5_pbkdf2_hmac_ex(pass, passlen, salt, saltlen, iter, prfmd, + keylen, key, libctx, propq)) goto err; rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); err: OPENSSL_cleanse(key, keylen); PBKDF2PARAM_free(kdf); + EVP_MD_free(prfmd_fetch); return rv; } -# ifdef OPENSSL_DEBUG_PKCS5V2 -static void h__dump(const unsigned char *p, int len) +int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, int en_de) { - for (; len--; p++) - fprintf(stderr, "%02X ", *p); - fprintf(stderr, "\n"); + return PKCS5_v2_PBKDF2_keyivgen_ex(ctx, pass, passlen, param, c, md, en_de, + NULL, NULL); } -# endif diff --git a/crypto/openssl/crypto/evp/p_dec.c b/crypto/openssl/crypto/evp/p_dec.c index a150a26e092c..d77eed14284f 100644 --- a/crypto/openssl/crypto/evp/p_dec.c +++ b/crypto/openssl/crypto/evp/p_dec.c @@ -1,36 +1,40 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use the deprecated RSA low level calls */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include "internal/cryptlib.h" #include #include #include #include +#include "crypto/evp.h" int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl, EVP_PKEY *priv) { int ret = -1; + RSA *rsa = NULL; -#ifndef OPENSSL_NO_RSA - if (EVP_PKEY_id(priv) != EVP_PKEY_RSA) { -#endif - EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA); -#ifndef OPENSSL_NO_RSA + if (EVP_PKEY_get_id(priv) != EVP_PKEY_RSA) { + ERR_raise(ERR_LIB_EVP, EVP_R_PUBLIC_KEY_NOT_RSA); goto err; } + rsa = evp_pkey_get0_RSA_int(priv); + if (rsa == NULL) + goto err; + ret = - RSA_private_decrypt(ekl, ek, key, EVP_PKEY_get0_RSA(priv), - RSA_PKCS1_PADDING); + RSA_private_decrypt(ekl, ek, key, rsa, RSA_PKCS1_PADDING); err: -#endif return ret; } diff --git a/crypto/openssl/crypto/evp/p_enc.c b/crypto/openssl/crypto/evp/p_enc.c index 04d67cb50f24..433c1a9e1710 100644 --- a/crypto/openssl/crypto/evp/p_enc.c +++ b/crypto/openssl/crypto/evp/p_enc.c @@ -1,35 +1,40 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use the deprecated RSA low level calls */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include "internal/cryptlib.h" #include #include #include #include +#include "crypto/evp.h" int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, int key_len, EVP_PKEY *pubk) { int ret = 0; + RSA *rsa = NULL; -#ifndef OPENSSL_NO_RSA - if (EVP_PKEY_id(pubk) != EVP_PKEY_RSA) { -#endif - EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA); -#ifndef OPENSSL_NO_RSA + if (EVP_PKEY_get_id(pubk) != EVP_PKEY_RSA) { + ERR_raise(ERR_LIB_EVP, EVP_R_PUBLIC_KEY_NOT_RSA); goto err; } + + rsa = evp_pkey_get0_RSA_int(pubk); + if (rsa == NULL) + goto err; + ret = - RSA_public_encrypt(key_len, key, ek, EVP_PKEY_get0_RSA(pubk), - RSA_PKCS1_PADDING); + RSA_public_encrypt(key_len, key, ek, rsa, RSA_PKCS1_PADDING); err: -#endif return ret; } diff --git a/crypto/openssl/crypto/evp/p_legacy.c b/crypto/openssl/crypto/evp/p_legacy.c new file mode 100644 index 000000000000..6c65e7e1947a --- /dev/null +++ b/crypto/openssl/crypto/evp/p_legacy.c @@ -0,0 +1,91 @@ +/* + * Copyright 1995-2021 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 + */ + +/* + * Legacy EVP_PKEY assign/set/get APIs are deprecated for public use, but + * still ok for internal use, particularly in providers. + */ +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include +#include "crypto/types.h" +#include "crypto/evp.h" +#include "evp_local.h" + +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) +{ + int ret = EVP_PKEY_assign_RSA(pkey, key); + + if (ret) + RSA_up_ref(key); + return ret; +} + +RSA *evp_pkey_get0_RSA_int(const EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA_PSS) { + ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_AN_RSA_KEY); + return NULL; + } + return evp_pkey_get_legacy((EVP_PKEY *)pkey); +} + +const RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) +{ + return evp_pkey_get0_RSA_int(pkey); +} + +RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) +{ + RSA *ret = evp_pkey_get0_RSA_int(pkey); + + if (ret != NULL) + RSA_up_ref(ret); + return ret; +} + +#ifndef OPENSSL_NO_EC +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) +{ + if (!EC_KEY_up_ref(key)) + return 0; + if (!EVP_PKEY_assign_EC_KEY(pkey, key)) { + EC_KEY_free(key); + return 0; + } + return 1; +} + +EC_KEY *evp_pkey_get0_EC_KEY_int(const EVP_PKEY *pkey) +{ + if (EVP_PKEY_get_base_id(pkey) != EVP_PKEY_EC) { + ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_EC_KEY); + return NULL; + } + return evp_pkey_get_legacy((EVP_PKEY *)pkey); +} + +const EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey) +{ + return evp_pkey_get0_EC_KEY_int(pkey); +} + +EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) +{ + EC_KEY *ret = evp_pkey_get0_EC_KEY_int(pkey); + + if (ret != NULL && !EC_KEY_up_ref(ret)) + ret = NULL; + return ret; +} +#endif /* OPENSSL_NO_EC */ diff --git a/crypto/openssl/crypto/evp/p_lib.c b/crypto/openssl/crypto/evp/p_lib.c index 1f36cb2164fc..5803974c3221 100644 --- a/crypto/openssl/crypto/evp/p_lib.c +++ b/crypto/openssl/crypto/evp/p_lib.c @@ -1,57 +1,91 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include #include #include "internal/cryptlib.h" #include "internal/refcount.h" +#include "internal/namemap.h" #include #include #include #include -#include #include #include #include +#include #include -#include +#ifndef FIPS_MODULE +# include +#endif +#include +#include +#include +#include -#include "crypto/asn1.h" +#include "internal/numbers.h" /* includes SIZE_MAX */ +#include "internal/ffc.h" #include "crypto/evp.h" +#include "crypto/dh.h" +#include "crypto/dsa.h" +#include "crypto/ec.h" +#include "crypto/ecx.h" +#include "crypto/rsa.h" +#ifndef FIPS_MODULE +# include "crypto/asn1.h" +# include "crypto/x509.h" +#endif +#include "internal/provider.h" +#include "evp_local.h" -static void EVP_PKEY_free_it(EVP_PKEY *x); +static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, + int len, EVP_KEYMGMT *keymgmt); +static void evp_pkey_free_it(EVP_PKEY *key); -int EVP_PKEY_bits(const EVP_PKEY *pkey) -{ - if (pkey && pkey->ameth && pkey->ameth->pkey_bits) - return pkey->ameth->pkey_bits(pkey); - return 0; -} +#ifndef FIPS_MODULE + +/* The type of parameters selected in key parameter functions */ +# define SELECT_PARAMETERS OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS -int EVP_PKEY_security_bits(const EVP_PKEY *pkey) +int EVP_PKEY_get_bits(const EVP_PKEY *pkey) { - if (pkey == NULL) - return 0; - if (!pkey->ameth || !pkey->ameth->pkey_security_bits) - return -2; - return pkey->ameth->pkey_security_bits(pkey); + int size = 0; + + if (pkey != NULL) { + size = pkey->cache.bits; + if (pkey->ameth != NULL && pkey->ameth->pkey_bits != NULL) + size = pkey->ameth->pkey_bits(pkey); + } + return size < 0 ? 0 : size; } -int EVP_PKEY_size(const EVP_PKEY *pkey) +int EVP_PKEY_get_security_bits(const EVP_PKEY *pkey) { - if (pkey && pkey->ameth && pkey->ameth->pkey_size) - return pkey->ameth->pkey_size(pkey); - return 0; + int size = 0; + + if (pkey != NULL) { + size = pkey->cache.security_bits; + if (pkey->ameth != NULL && pkey->ameth->pkey_security_bits != NULL) + size = pkey->ameth->pkey_security_bits(pkey); + } + return size < 0 ? 0 : size; } int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) { -#ifndef OPENSSL_NO_DSA +# ifndef OPENSSL_NO_DSA if (pkey->type == EVP_PKEY_DSA) { int ret = pkey->save_parameters; @@ -59,8 +93,8 @@ int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) pkey->save_parameters = mode; return ret; } -#endif -#ifndef OPENSSL_NO_EC +# endif +# ifndef OPENSSL_NO_EC if (pkey->type == EVP_PKEY_EC) { int ret = pkey->save_parameters; @@ -68,234 +102,477 @@ int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) pkey->save_parameters = mode; return ret; } -#endif +# endif return 0; } +int EVP_PKEY_set_ex_data(EVP_PKEY *key, int idx, void *arg) +{ + return CRYPTO_set_ex_data(&key->ex_data, idx, arg); +} + +void *EVP_PKEY_get_ex_data(const EVP_PKEY *key, int idx) +{ + return CRYPTO_get_ex_data(&key->ex_data, idx); +} + int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { - if (to->type == EVP_PKEY_NONE) { - if (EVP_PKEY_set_type(to, from->type) == 0) - return 0; - } else if (to->type != from->type) { - EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES); - goto err; + /* + * Clean up legacy stuff from this function when legacy support is gone. + */ + + EVP_PKEY *downgraded_from = NULL; + int ok = 0; + + /* + * If |to| is a legacy key and |from| isn't, we must make a downgraded + * copy of |from|. If that fails, this function fails. + */ + if (evp_pkey_is_legacy(to) && evp_pkey_is_provided(from)) { + if (!evp_pkey_copy_downgraded(&downgraded_from, from)) + goto end; + from = downgraded_from; + } + + /* + * Make sure |to| is typed. Content is less important at this early + * stage. + * + * 1. If |to| is untyped, assign |from|'s key type to it. + * 2. If |to| contains a legacy key, compare its |type| to |from|'s. + * (|from| was already downgraded above) + * + * If |to| is a provided key, there's nothing more to do here, functions + * like evp_keymgmt_util_copy() and evp_pkey_export_to_provider() called + * further down help us find out if they are the same or not. + */ + if (evp_pkey_is_blank(to)) { + if (evp_pkey_is_legacy(from)) { + if (EVP_PKEY_set_type(to, from->type) == 0) + goto end; + } else { + if (EVP_PKEY_set_type_by_keymgmt(to, from->keymgmt) == 0) + goto end; + } + } else if (evp_pkey_is_legacy(to)) { + if (to->type != from->type) { + ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); + goto end; + } } if (EVP_PKEY_missing_parameters(from)) { - EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS); - goto err; + ERR_raise(ERR_LIB_EVP, EVP_R_MISSING_PARAMETERS); + goto end; } if (!EVP_PKEY_missing_parameters(to)) { - if (EVP_PKEY_cmp_parameters(to, from) == 1) - return 1; - EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS); - return 0; + if (EVP_PKEY_parameters_eq(to, from) == 1) + ok = 1; + else + ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_PARAMETERS); + goto end; } - if (from->ameth && from->ameth->param_copy) - return from->ameth->param_copy(to, from); - err: - return 0; + /* For purely provided keys, we just call the keymgmt utility */ + if (to->keymgmt != NULL && from->keymgmt != NULL) { + ok = evp_keymgmt_util_copy(to, (EVP_PKEY *)from, SELECT_PARAMETERS); + goto end; + } + + /* + * If |to| is provided, we know that |from| is legacy at this point. + * Try exporting |from| to |to|'s keymgmt, then use evp_keymgmt_dup() + * to copy the appropriate data to |to|'s keydata. + * We cannot override existing data so do it only if there is no keydata + * in |to| yet. + */ + if (to->keymgmt != NULL && to->keydata == NULL) { + EVP_KEYMGMT *to_keymgmt = to->keymgmt; + void *from_keydata = + evp_pkey_export_to_provider((EVP_PKEY *)from, NULL, &to_keymgmt, + NULL); + + /* + * If we get a NULL, it could be an internal error, or it could be + * that there's a key mismatch. We're pretending the latter... + */ + if (from_keydata == NULL) + ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); + else + ok = (to->keydata = evp_keymgmt_dup(to->keymgmt, + from_keydata, + SELECT_PARAMETERS)) != NULL; + goto end; + } + + /* Both keys are legacy */ + if (from->ameth != NULL && from->ameth->param_copy != NULL) + ok = from->ameth->param_copy(to, from); + end: + EVP_PKEY_free(downgraded_from); + return ok; } int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) { - if (pkey != NULL && pkey->ameth && pkey->ameth->param_missing) - return pkey->ameth->param_missing(pkey); + if (pkey != NULL) { + if (pkey->keymgmt != NULL) + return !evp_keymgmt_util_has((EVP_PKEY *)pkey, SELECT_PARAMETERS); + else if (pkey->ameth != NULL && pkey->ameth->param_missing != NULL) + return pkey->ameth->param_missing(pkey); + } return 0; } +/* + * This function is called for any mixture of keys except pure legacy pair. + * When legacy keys are gone, we replace a call to this functions with + * a call to evp_keymgmt_util_match(). + */ +static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b, + int selection) +{ + EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL; + void *keydata1 = NULL, *keydata2 = NULL, *tmp_keydata = NULL; + + /* If none of them are provided, this function shouldn't have been called */ + if (!ossl_assert(evp_pkey_is_provided(a) || evp_pkey_is_provided(b))) + return -2; + + /* For purely provided keys, we just call the keymgmt utility */ + if (evp_pkey_is_provided(a) && evp_pkey_is_provided(b)) + return evp_keymgmt_util_match((EVP_PKEY *)a, (EVP_PKEY *)b, selection); + + /* + * At this point, one of them is provided, the other not. This allows + * us to compare types using legacy NIDs. + */ + if (evp_pkey_is_legacy(a) + && !EVP_KEYMGMT_is_a(b->keymgmt, OBJ_nid2sn(a->type))) + return -1; /* not the same key type */ + if (evp_pkey_is_legacy(b) + && !EVP_KEYMGMT_is_a(a->keymgmt, OBJ_nid2sn(b->type))) + return -1; /* not the same key type */ + + /* + * We've determined that they both are the same keytype, so the next + * step is to do a bit of cross export to ensure we have keydata for + * both keys in the same keymgmt. + */ + keymgmt1 = a->keymgmt; + keydata1 = a->keydata; + keymgmt2 = b->keymgmt; + keydata2 = b->keydata; + + if (keymgmt2 != NULL && keymgmt2->match != NULL) { + tmp_keydata = + evp_pkey_export_to_provider((EVP_PKEY *)a, NULL, &keymgmt2, NULL); + if (tmp_keydata != NULL) { + keymgmt1 = keymgmt2; + keydata1 = tmp_keydata; + } + } + if (tmp_keydata == NULL && keymgmt1 != NULL && keymgmt1->match != NULL) { + tmp_keydata = + evp_pkey_export_to_provider((EVP_PKEY *)b, NULL, &keymgmt1, NULL); + if (tmp_keydata != NULL) { + keymgmt2 = keymgmt1; + keydata2 = tmp_keydata; + } + } + + /* If we still don't have matching keymgmt implementations, we give up */ + if (keymgmt1 != keymgmt2) + return -2; + + /* If the keymgmt implementations are NULL, the export failed */ + if (keymgmt1 == NULL) + return -2; + + return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection); +} + +# ifndef OPENSSL_NO_DEPRECATED_3_0 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { + return EVP_PKEY_parameters_eq(a, b); +} +#endif + +int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b) +{ + /* + * This will just call evp_keymgmt_util_match when legacy support + * is gone. + */ + + if (a->keymgmt != NULL || b->keymgmt != NULL) + return evp_pkey_cmp_any(a, b, SELECT_PARAMETERS); + + /* All legacy keys */ if (a->type != b->type) return -1; - if (a->ameth && a->ameth->param_cmp) + if (a->ameth != NULL && a->ameth->param_cmp != NULL) return a->ameth->param_cmp(a, b); return -2; } +# ifndef OPENSSL_NO_DEPRECATED_3_0 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + return EVP_PKEY_eq(a, b); +} +#endif + +int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b) +{ + /* + * This will just call evp_keymgmt_util_match when legacy support + * is gone. + */ + + /* Trivial shortcuts */ + if (a == b) + return 1; + if (a == NULL || b == NULL) + return 0; + + if (a->keymgmt != NULL || b->keymgmt != NULL) { + int selection = SELECT_PARAMETERS; + + if (evp_keymgmt_util_has((EVP_PKEY *)a, OSSL_KEYMGMT_SELECT_PUBLIC_KEY) + && evp_keymgmt_util_has((EVP_PKEY *)b, OSSL_KEYMGMT_SELECT_PUBLIC_KEY)) + selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + else + selection |= OSSL_KEYMGMT_SELECT_KEYPAIR; + return evp_pkey_cmp_any(a, b, selection); + } + + /* All legacy keys */ if (a->type != b->type) return -1; - if (a->ameth) { + if (a->ameth != NULL) { int ret; /* Compare parameters if the algorithm has them */ - if (a->ameth->param_cmp) { + if (a->ameth->param_cmp != NULL) { ret = a->ameth->param_cmp(a, b); if (ret <= 0) return ret; } - if (a->ameth->pub_cmp) + if (a->ameth->pub_cmp != NULL) return a->ameth->pub_cmp(a, b); } return -2; } -EVP_PKEY *EVP_PKEY_new(void) -{ - EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret)); - - if (ret == NULL) { - EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - ret->type = EVP_PKEY_NONE; - ret->save_type = EVP_PKEY_NONE; - ret->references = 1; - ret->save_parameters = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return NULL; - } - return ret; -} -int EVP_PKEY_up_ref(EVP_PKEY *pkey) +static EVP_PKEY *new_raw_key_int(OSSL_LIB_CTX *libctx, + const char *strtype, + const char *propq, + int nidtype, + ENGINE *e, + const unsigned char *key, + size_t len, + int key_is_priv) { - int i; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + const EVP_PKEY_ASN1_METHOD *ameth = NULL; + int result = 0; - if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0) - return 0; +# ifndef OPENSSL_NO_ENGINE + /* Check if there is an Engine for this type */ + if (e == NULL) { + ENGINE *tmpe = NULL; - REF_PRINT_COUNT("EVP_PKEY", pkey); - REF_ASSERT_ISNT(i < 2); - return ((i > 1) ? 1 : 0); -} + if (strtype != NULL) + ameth = EVP_PKEY_asn1_find_str(&tmpe, strtype, -1); + else if (nidtype != EVP_PKEY_NONE) + ameth = EVP_PKEY_asn1_find(&tmpe, nidtype); -/* - * Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey - * is NULL just return 1 or 0 if the algorithm exists. - */ + /* If tmpe is NULL then no engine is claiming to support this type */ + if (tmpe == NULL) + ameth = NULL; -static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, - int len) -{ - const EVP_PKEY_ASN1_METHOD *ameth; - ENGINE **eptr = (e == NULL) ? &e : NULL; + ENGINE_finish(tmpe); + } +# endif - if (pkey) { - if (pkey->pkey.ptr) - EVP_PKEY_free_it(pkey); + if (e == NULL && ameth == NULL) { /* - * If key type matches and a method exists then this lookup has - * succeeded once so just indicate success. + * No engine is claiming to support this type, so lets see if we have + * a provider. */ - if ((type == pkey->save_type) && pkey->ameth) - return 1; -#ifndef OPENSSL_NO_ENGINE - /* If we have ENGINEs release them */ - ENGINE_finish(pkey->engine); - pkey->engine = NULL; - ENGINE_finish(pkey->pmeth_engine); - pkey->pmeth_engine = NULL; -#endif - } - if (str) - ameth = EVP_PKEY_asn1_find_str(eptr, str, len); - else - ameth = EVP_PKEY_asn1_find(eptr, type); -#ifndef OPENSSL_NO_ENGINE - if (pkey == NULL && eptr != NULL) - ENGINE_finish(e); -#endif - if (ameth == NULL) { - EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM); - return 0; - } - if (pkey) { - pkey->ameth = ameth; - pkey->type = pkey->ameth->pkey_id; - pkey->save_type = type; -# ifndef OPENSSL_NO_ENGINE - if (eptr == NULL && e != NULL && !ENGINE_init(e)) { - EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_INITIALIZATION_ERROR); - return 0; + ctx = EVP_PKEY_CTX_new_from_name(libctx, + strtype != NULL ? strtype + : OBJ_nid2sn(nidtype), + propq); + if (ctx == NULL) + goto err; + /* May fail if no provider available */ + ERR_set_mark(); + if (EVP_PKEY_fromdata_init(ctx) == 1) { + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + ERR_clear_last_mark(); + params[0] = OSSL_PARAM_construct_octet_string( + key_is_priv ? OSSL_PKEY_PARAM_PRIV_KEY + : OSSL_PKEY_PARAM_PUB_KEY, + (void *)key, len); + + if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) != 1) { + ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED); + goto err; + } + + EVP_PKEY_CTX_free(ctx); + + return pkey; } -# endif - pkey->engine = e; + ERR_pop_to_mark(); + /* else not supported so fallback to legacy */ } - return 1; -} -EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e, - const unsigned char *priv, - size_t len) -{ - EVP_PKEY *ret = EVP_PKEY_new(); + /* Legacy code path */ - if (ret == NULL - || !pkey_set_type(ret, e, type, NULL, -1)) { - /* EVPerr already called */ + pkey = EVP_PKEY_new(); + if (pkey == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); goto err; } - if (ret->ameth->set_priv_key == NULL) { - EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + if (!pkey_set_type(pkey, e, nidtype, strtype, -1, NULL)) { + /* EVPerr already called */ goto err; } - if (!ret->ameth->set_priv_key(ret, priv, len)) { - EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, EVP_R_KEY_SETUP_FAILED); + if (!ossl_assert(pkey->ameth != NULL)) goto err; - } - return ret; + if (key_is_priv) { + if (pkey->ameth->set_priv_key == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + goto err; + } + + if (!pkey->ameth->set_priv_key(pkey, key, len)) { + ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED); + goto err; + } + } else { + if (pkey->ameth->set_pub_key == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + goto err; + } + if (!pkey->ameth->set_pub_key(pkey, key, len)) { + ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED); + goto err; + } + } + + result = 1; err: - EVP_PKEY_free(ret); - return NULL; + if (!result) { + EVP_PKEY_free(pkey); + pkey = NULL; + } + EVP_PKEY_CTX_free(ctx); + return pkey; +} + +EVP_PKEY *EVP_PKEY_new_raw_private_key_ex(OSSL_LIB_CTX *libctx, + const char *keytype, + const char *propq, + const unsigned char *priv, size_t len) +{ + return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, priv, + len, 1); +} + +EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e, + const unsigned char *priv, + size_t len) +{ + return new_raw_key_int(NULL, NULL, NULL, type, e, priv, len, 1); +} + +EVP_PKEY *EVP_PKEY_new_raw_public_key_ex(OSSL_LIB_CTX *libctx, + const char *keytype, const char *propq, + const unsigned char *pub, size_t len) +{ + return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, pub, + len, 0); } EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e, const unsigned char *pub, size_t len) { - EVP_PKEY *ret = EVP_PKEY_new(); - - if (ret == NULL - || !pkey_set_type(ret, e, type, NULL, -1)) { - /* EVPerr already called */ - goto err; - } + return new_raw_key_int(NULL, NULL, NULL, type, e, pub, len, 0); +} - if (ret->ameth->set_pub_key == NULL) { - EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - goto err; - } +struct raw_key_details_st +{ + unsigned char **key; + size_t *len; + int selection; +}; - if (!ret->ameth->set_pub_key(ret, pub, len)) { - EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, EVP_R_KEY_SETUP_FAILED); - goto err; +static OSSL_CALLBACK get_raw_key_details; +static int get_raw_key_details(const OSSL_PARAM params[], void *arg) +{ + const OSSL_PARAM *p = NULL; + struct raw_key_details_st *raw_key = arg; + + if (raw_key->selection == OSSL_KEYMGMT_SELECT_PRIVATE_KEY) { + if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY)) + != NULL) + return OSSL_PARAM_get_octet_string(p, (void **)raw_key->key, + raw_key->key == NULL ? 0 : *raw_key->len, + raw_key->len); + } else if (raw_key->selection == OSSL_KEYMGMT_SELECT_PUBLIC_KEY) { + if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY)) + != NULL) + return OSSL_PARAM_get_octet_string(p, (void **)raw_key->key, + raw_key->key == NULL ? 0 : *raw_key->len, + raw_key->len); } - return ret; - - err: - EVP_PKEY_free(ret); - return NULL; + return 0; } int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, size_t *len) { - if (pkey->ameth->get_priv_key == NULL) { - EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + if (pkey->keymgmt != NULL) { + struct raw_key_details_st raw_key; + + raw_key.key = priv == NULL ? NULL : &priv; + raw_key.len = len; + raw_key.selection = OSSL_KEYMGMT_SELECT_PRIVATE_KEY; + + return evp_keymgmt_util_export(pkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY, + get_raw_key_details, &raw_key); + } + + if (pkey->ameth == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + if (pkey->ameth->get_priv_key == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } if (!pkey->ameth->get_priv_key(pkey, priv, len)) { - EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, EVP_R_GET_RAW_KEY_FAILED); + ERR_raise(ERR_LIB_EVP, EVP_R_GET_RAW_KEY_FAILED); return 0; } @@ -305,93 +582,122 @@ int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, size_t *len) { + if (pkey->keymgmt != NULL) { + struct raw_key_details_st raw_key; + + raw_key.key = pub == NULL ? NULL : &pub; + raw_key.len = len; + raw_key.selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + + return evp_keymgmt_util_export(pkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, + get_raw_key_details, &raw_key); + } + + if (pkey->ameth == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (pkey->ameth->get_pub_key == NULL) { - EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } if (!pkey->ameth->get_pub_key(pkey, pub, len)) { - EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, EVP_R_GET_RAW_KEY_FAILED); + ERR_raise(ERR_LIB_EVP, EVP_R_GET_RAW_KEY_FAILED); return 0; } return 1; } -EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, - size_t len, const EVP_CIPHER *cipher) +static EVP_PKEY *new_cmac_key_int(const unsigned char *priv, size_t len, + const char *cipher_name, + const EVP_CIPHER *cipher, + OSSL_LIB_CTX *libctx, + const char *propq, ENGINE *e) { -#ifndef OPENSSL_NO_CMAC - EVP_PKEY *ret = EVP_PKEY_new(); - CMAC_CTX *cmctx = CMAC_CTX_new(); +# ifndef OPENSSL_NO_CMAC +# ifndef OPENSSL_NO_ENGINE + const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL; +# endif + OSSL_PARAM params[5], *p = params; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx; + + if (cipher != NULL) + cipher_name = EVP_CIPHER_get0_name(cipher); + + if (cipher_name == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED); + return NULL; + } - if (ret == NULL - || cmctx == NULL - || !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1)) { - /* EVPerr already called */ + ctx = EVP_PKEY_CTX_new_from_name(libctx, "CMAC", propq); + if (ctx == NULL) goto err; - } - if (!CMAC_Init(cmctx, priv, len, cipher, e)) { - EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED); + if (EVP_PKEY_fromdata_init(ctx) <= 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED); goto err; } - ret->pkey.ptr = cmctx; - return ret; + *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, + (void *)priv, len); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_CIPHER, + (char *)cipher_name, 0); + if (propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, + (char *)propq, 0); +# ifndef OPENSSL_NO_ENGINE + if (engine_id != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_ENGINE, + (char *)engine_id, 0); +# endif + *p = OSSL_PARAM_construct_end(); + + if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED); + goto err; + } err: - EVP_PKEY_free(ret); - CMAC_CTX_free(cmctx); - return NULL; -#else - EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + EVP_PKEY_CTX_free(ctx); + + return pkey; +# else + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return NULL; -#endif +# endif } -int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) +EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, + size_t len, const EVP_CIPHER *cipher) { - return pkey_set_type(pkey, NULL, type, NULL, -1); + return new_cmac_key_int(priv, len, NULL, cipher, NULL, NULL, e); } -int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { - return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len); + return pkey_set_type(pkey, NULL, type, NULL, -1, NULL); } -int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type) +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) { - if (pkey->type == type) { - return 1; /* it already is that type */ - } - - /* - * The application is requesting to alias this to a different pkey type, - * but not one that resolves to the base type. - */ - if (EVP_PKEY_type(type) != EVP_PKEY_base_id(pkey)) { - EVPerr(EVP_F_EVP_PKEY_SET_ALIAS_TYPE, EVP_R_UNSUPPORTED_ALGORITHM); - return 0; - } - - pkey->type = type; - return 1; + return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len, NULL); } -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e) { if (e != NULL) { if (!ENGINE_init(e)) { - EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_EVP, ERR_R_ENGINE_LIB); return 0; } if (ENGINE_get_pkey_meth(e, pkey->type) == NULL) { ENGINE_finish(e); - EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, EVP_R_UNSUPPORTED_ALGORITHM); + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM); return 0; } } @@ -404,89 +710,151 @@ ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey) { return pkey->engine; } +# endif + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +static void detect_foreign_key(EVP_PKEY *pkey) +{ + switch (pkey->type) { + case EVP_PKEY_RSA: + pkey->foreign = pkey->pkey.rsa != NULL + && ossl_rsa_is_foreign(pkey->pkey.rsa); + break; +# ifndef OPENSSL_NO_EC + case EVP_PKEY_SM2: + case EVP_PKEY_EC: + pkey->foreign = pkey->pkey.ec != NULL + && ossl_ec_key_is_foreign(pkey->pkey.ec); + break; +# endif +# ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + pkey->foreign = pkey->pkey.dsa != NULL + && ossl_dsa_is_foreign(pkey->pkey.dsa); + break; #endif +# ifndef OPENSSL_NO_DH + case EVP_PKEY_DH: + pkey->foreign = pkey->pkey.dh != NULL + && ossl_dh_is_foreign(pkey->pkey.dh); + break; +#endif + default: + pkey->foreign = 0; + break; + } +} + int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { - if (pkey == NULL || !EVP_PKEY_set_type(pkey, type)) - return 0; +# ifndef OPENSSL_NO_EC + int pktype; + + pktype = EVP_PKEY_type(type); + if ((key != NULL) && (pktype == EVP_PKEY_EC || pktype == EVP_PKEY_SM2)) { + const EC_GROUP *group = EC_KEY_get0_group(key); + + if (group != NULL) { + int curve = EC_GROUP_get_curve_name(group); + + /* + * Regardless of what is requested the SM2 curve must be SM2 type, + * and non SM2 curves are EC type. + */ + if (curve == NID_sm2 && pktype == EVP_PKEY_EC) + type = EVP_PKEY_SM2; + else if(curve != NID_sm2 && pktype == EVP_PKEY_SM2) + type = EVP_PKEY_EC; + } + } +# endif + + if (pkey == NULL || !EVP_PKEY_set_type(pkey, type)) + return 0; + pkey->pkey.ptr = key; + detect_foreign_key(pkey); + return (key != NULL); } +# endif void *EVP_PKEY_get0(const EVP_PKEY *pkey) { - return pkey->pkey.ptr; + if (pkey == NULL) + return NULL; + + if (!evp_pkey_is_provided(pkey)) + return pkey->pkey.ptr; + + return NULL; } const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len) { - ASN1_OCTET_STRING *os = NULL; + const ASN1_OCTET_STRING *os = NULL; if (pkey->type != EVP_PKEY_HMAC) { - EVPerr(EVP_F_EVP_PKEY_GET0_HMAC, EVP_R_EXPECTING_AN_HMAC_KEY); + ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_AN_HMAC_KEY); return NULL; } - os = EVP_PKEY_get0(pkey); - *len = os->length; - return os->data; + os = evp_pkey_get_legacy((EVP_PKEY *)pkey); + if (os != NULL) { + *len = os->length; + return os->data; + } + return NULL; } -#ifndef OPENSSL_NO_POLY1305 +# ifndef OPENSSL_NO_POLY1305 const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len) { - ASN1_OCTET_STRING *os = NULL; + const ASN1_OCTET_STRING *os = NULL; if (pkey->type != EVP_PKEY_POLY1305) { - EVPerr(EVP_F_EVP_PKEY_GET0_POLY1305, EVP_R_EXPECTING_A_POLY1305_KEY); + ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_POLY1305_KEY); return NULL; } - os = EVP_PKEY_get0(pkey); - *len = os->length; - return os->data; + os = evp_pkey_get_legacy((EVP_PKEY *)pkey); + if (os != NULL) { + *len = os->length; + return os->data; + } + return NULL; } -#endif +# endif -#ifndef OPENSSL_NO_SIPHASH +# ifndef OPENSSL_NO_SIPHASH const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len) { - ASN1_OCTET_STRING *os = NULL; + const ASN1_OCTET_STRING *os = NULL; if (pkey->type != EVP_PKEY_SIPHASH) { - EVPerr(EVP_F_EVP_PKEY_GET0_SIPHASH, EVP_R_EXPECTING_A_SIPHASH_KEY); + ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_SIPHASH_KEY); return NULL; } - os = EVP_PKEY_get0(pkey); - *len = os->length; - return os->data; -} -#endif - -#ifndef OPENSSL_NO_RSA -int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) -{ - int ret = EVP_PKEY_assign_RSA(pkey, key); - if (ret) - RSA_up_ref(key); - return ret; + os = evp_pkey_get_legacy((EVP_PKEY *)pkey); + if (os != NULL) { + *len = os->length; + return os->data; + } + return NULL; } +# endif -RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) +# ifndef OPENSSL_NO_DSA +static DSA *evp_pkey_get0_DSA_int(const EVP_PKEY *pkey) { - if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA_PSS) { - EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY); + if (pkey->type != EVP_PKEY_DSA) { + ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_DSA_KEY); return NULL; } - return pkey->pkey.rsa; + return evp_pkey_get_legacy((EVP_PKEY *)pkey); } -RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) +const DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) { - RSA *ret = EVP_PKEY_get0_RSA(pkey); - if (ret != NULL) - RSA_up_ref(ret); - return ret; + return evp_pkey_get0_DSA_int(pkey); } -#endif -#ifndef OPENSSL_NO_DSA int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { int ret = EVP_PKEY_assign_DSA(pkey, key); @@ -494,82 +862,107 @@ int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) DSA_up_ref(key); return ret; } - -DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) -{ - if (pkey->type != EVP_PKEY_DSA) { - EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY); - return NULL; - } - return pkey->pkey.dsa; -} - DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) { - DSA *ret = EVP_PKEY_get0_DSA(pkey); + DSA *ret = evp_pkey_get0_DSA_int(pkey); + if (ret != NULL) DSA_up_ref(ret); return ret; } -#endif - -#ifndef OPENSSL_NO_EC - -int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) -{ - int ret = EVP_PKEY_assign_EC_KEY(pkey, key); - if (ret) - EC_KEY_up_ref(key); - return ret; -} +# endif /* OPENSSL_NO_DSA */ -EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) +# ifndef OPENSSL_NO_EC +static const ECX_KEY *evp_pkey_get0_ECX_KEY(const EVP_PKEY *pkey, int type) { - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { - EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY); + if (EVP_PKEY_get_base_id(pkey) != type) { + ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_ECX_KEY); return NULL; } - return pkey->pkey.ec; + return evp_pkey_get_legacy((EVP_PKEY *)pkey); } -EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) +static ECX_KEY *evp_pkey_get1_ECX_KEY(EVP_PKEY *pkey, int type) { - EC_KEY *ret = EVP_PKEY_get0_EC_KEY(pkey); - if (ret != NULL) - EC_KEY_up_ref(ret); + ECX_KEY *ret = (ECX_KEY *)evp_pkey_get0_ECX_KEY(pkey, type); + + if (ret != NULL && !ossl_ecx_key_up_ref(ret)) + ret = NULL; return ret; } -#endif -#ifndef OPENSSL_NO_DH +# define IMPLEMENT_ECX_VARIANT(NAME) \ + ECX_KEY *ossl_evp_pkey_get1_##NAME(EVP_PKEY *pkey) \ + { \ + return evp_pkey_get1_ECX_KEY(pkey, EVP_PKEY_##NAME); \ + } +IMPLEMENT_ECX_VARIANT(X25519) +IMPLEMENT_ECX_VARIANT(X448) +IMPLEMENT_ECX_VARIANT(ED25519) +IMPLEMENT_ECX_VARIANT(ED448) + +# endif + +# if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0) -int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *dhkey) { - int type = DH_get0_q(key) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX; - int ret = EVP_PKEY_assign(pkey, type, key); + int ret, type; + + /* + * ossl_dh_is_named_safe_prime_group() returns 1 for named safe prime groups + * related to ffdhe and modp (which cache q = (p - 1) / 2), + * and returns 0 for all other dh parameter generation types including + * RFC5114 named groups. + * + * The EVP_PKEY_DH type is used for dh parameter generation types: + * - named safe prime groups related to ffdhe and modp + * - safe prime generator + * + * The type EVP_PKEY_DHX is used for dh parameter generation types + * - fips186-4 and fips186-2 + * - rfc5114 named groups. + * + * The EVP_PKEY_DH type is used to save PKCS#3 data than can be stored + * without a q value. + * The EVP_PKEY_DHX type is used to save X9.42 data that requires the + * q value to be stored. + */ + if (ossl_dh_is_named_safe_prime_group(dhkey)) + type = EVP_PKEY_DH; + else + type = DH_get0_q(dhkey) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX; + + ret = EVP_PKEY_assign(pkey, type, dhkey); if (ret) - DH_up_ref(key); + DH_up_ref(dhkey); return ret; } -DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey) +DH *evp_pkey_get0_DH_int(const EVP_PKEY *pkey) { if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) { - EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY); + ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_DH_KEY); return NULL; } - return pkey->pkey.dh; + return evp_pkey_get_legacy((EVP_PKEY *)pkey); +} + +const DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey) +{ + return evp_pkey_get0_DH_int(pkey); } DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) { - DH *ret = EVP_PKEY_get0_DH(pkey); + DH *ret = evp_pkey_get0_DH_int(pkey); + if (ret != NULL) DH_up_ref(ret); return ret; } -#endif +# endif int EVP_PKEY_type(int type) { @@ -581,93 +974,350 @@ int EVP_PKEY_type(int type) ret = ameth->pkey_id; else ret = NID_undef; -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE ENGINE_finish(e); -#endif +# endif return ret; } -int EVP_PKEY_id(const EVP_PKEY *pkey) +int EVP_PKEY_get_id(const EVP_PKEY *pkey) { return pkey->type; } -int EVP_PKEY_base_id(const EVP_PKEY *pkey) +int EVP_PKEY_get_base_id(const EVP_PKEY *pkey) { return EVP_PKEY_type(pkey->type); } -void EVP_PKEY_free(EVP_PKEY *x) +/* + * These hard coded cases are pure hackery to get around the fact + * that names in crypto/objects/objects.txt are a mess. There is + * no "EC", and "RSA" leads to the NID for 2.5.8.1.1, an OID that's + * fallen out in favor of { pkcs-1 1 }, i.e. 1.2.840.113549.1.1.1, + * the NID of which is used for EVP_PKEY_RSA. Strangely enough, + * "DSA" is accurate... but still, better be safe and hard-code + * names that we know. + * On a similar topic, EVP_PKEY_type(EVP_PKEY_SM2) will result in + * EVP_PKEY_EC, because of aliasing. + * This should be cleaned away along with all other #legacy support. + */ +static const OSSL_ITEM standard_name2type[] = { + { EVP_PKEY_RSA, "RSA" }, + { EVP_PKEY_RSA_PSS, "RSA-PSS" }, + { EVP_PKEY_EC, "EC" }, + { EVP_PKEY_ED25519, "ED25519" }, + { EVP_PKEY_ED448, "ED448" }, + { EVP_PKEY_X25519, "X25519" }, + { EVP_PKEY_X448, "X448" }, + { EVP_PKEY_SM2, "SM2" }, + { EVP_PKEY_DH, "DH" }, + { EVP_PKEY_DHX, "X9.42 DH" }, + { EVP_PKEY_DHX, "DHX" }, + { EVP_PKEY_DSA, "DSA" }, +}; + +int evp_pkey_name2type(const char *name) { - int i; + int type; + size_t i; - if (x == NULL) - return; + for (i = 0; i < OSSL_NELEM(standard_name2type); i++) { + if (OPENSSL_strcasecmp(name, standard_name2type[i].ptr) == 0) + return (int)standard_name2type[i].id; + } - CRYPTO_DOWN_REF(&x->references, &i, x->lock); - REF_PRINT_COUNT("EVP_PKEY", x); - if (i > 0) - return; - REF_ASSERT_ISNT(i < 0); - EVP_PKEY_free_it(x); - CRYPTO_THREAD_lock_free(x->lock); - sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free); - OPENSSL_free(x); + if ((type = EVP_PKEY_type(OBJ_sn2nid(name))) != NID_undef) + return type; + return EVP_PKEY_type(OBJ_ln2nid(name)); } -static void EVP_PKEY_free_it(EVP_PKEY *x) +const char *evp_pkey_type2name(int type) { - /* internal function; x is never NULL */ - if (x->ameth && x->ameth->pkey_free) { - x->ameth->pkey_free(x); - x->pkey.ptr = NULL; + size_t i; + + for (i = 0; i < OSSL_NELEM(standard_name2type); i++) { + if (type == (int)standard_name2type[i].id) + return standard_name2type[i].ptr; } -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(x->engine); - x->engine = NULL; - ENGINE_finish(x->pmeth_engine); - x->pmeth_engine = NULL; -#endif + + return OBJ_nid2sn(type); +} + +int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name) +{ + if (pkey == NULL) + return 0; + if (pkey->keymgmt == NULL) + return pkey->type == evp_pkey_name2type(name); + return EVP_KEYMGMT_is_a(pkey->keymgmt, name); +} + +int EVP_PKEY_type_names_do_all(const EVP_PKEY *pkey, + void (*fn)(const char *name, void *data), + void *data) +{ + if (!evp_pkey_is_typed(pkey)) + return 0; + + if (!evp_pkey_is_provided(pkey)) { + const char *name = OBJ_nid2sn(EVP_PKEY_get_id(pkey)); + + fn(name, data); + return 1; + } + return EVP_KEYMGMT_names_do_all(pkey->keymgmt, fn, data); +} + +int EVP_PKEY_can_sign(const EVP_PKEY *pkey) +{ + if (pkey->keymgmt == NULL) { + switch (EVP_PKEY_get_base_id(pkey)) { + case EVP_PKEY_RSA: + return 1; +# ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + return 1; +# endif +# ifndef OPENSSL_NO_EC + case EVP_PKEY_ED25519: + case EVP_PKEY_ED448: + return 1; + case EVP_PKEY_EC: /* Including SM2 */ + return EC_KEY_can_sign(pkey->pkey.ec); +# endif + default: + break; + } + } else { + const OSSL_PROVIDER *prov = EVP_KEYMGMT_get0_provider(pkey->keymgmt); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + const char *supported_sig = + pkey->keymgmt->query_operation_name != NULL + ? pkey->keymgmt->query_operation_name(OSSL_OP_SIGNATURE) + : EVP_KEYMGMT_get0_name(pkey->keymgmt); + EVP_SIGNATURE *signature = NULL; + + signature = EVP_SIGNATURE_fetch(libctx, supported_sig, NULL); + if (signature != NULL) { + EVP_SIGNATURE_free(signature); + return 1; + } + } + return 0; +} + +static int print_reset_indent(BIO **out, int pop_f_prefix, long saved_indent) +{ + BIO_set_indent(*out, saved_indent); + if (pop_f_prefix) { + BIO *next = BIO_pop(*out); + + BIO_free(*out); + *out = next; + } + return 1; +} + +static int print_set_indent(BIO **out, int *pop_f_prefix, long *saved_indent, + long indent) +{ + *pop_f_prefix = 0; + *saved_indent = 0; + if (indent > 0) { + long i = BIO_get_indent(*out); + + *saved_indent = (i < 0 ? 0 : i); + if (BIO_set_indent(*out, indent) <= 0) { + BIO *prefbio = BIO_new(BIO_f_prefix()); + + if (prefbio == NULL) + return 0; + *out = BIO_push(prefbio, *out); + *pop_f_prefix = 1; + } + if (BIO_set_indent(*out, indent) <= 0) { + print_reset_indent(out, *pop_f_prefix, *saved_indent); + return 0; + } + } + return 1; } static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr) { - BIO_indent(out, indent, 128); - BIO_printf(out, "%s algorithm \"%s\" unsupported\n", - kstr, OBJ_nid2ln(pkey->type)); - return 1; + return BIO_indent(out, indent, 128) + && BIO_printf(out, "%s algorithm \"%s\" unsupported\n", + kstr, OBJ_nid2ln(pkey->type)) > 0; +} + +static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent, + int selection /* For provided encoding */, + const char *propquery /* For provided encoding */, + int (*legacy_print)(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx), + ASN1_PCTX *legacy_pctx /* For legacy print */) +{ + int pop_f_prefix; + long saved_indent; + OSSL_ENCODER_CTX *ctx = NULL; + int ret = -2; /* default to unsupported */ + + if (!print_set_indent(&out, &pop_f_prefix, &saved_indent, indent)) + return 0; + + ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, "TEXT", NULL, + propquery); + if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0) + ret = OSSL_ENCODER_to_bio(ctx, out); + OSSL_ENCODER_CTX_free(ctx); + + if (ret != -2) + goto end; + + /* legacy fallback */ + if (legacy_print != NULL) + ret = legacy_print(out, pkey, 0, legacy_pctx); + else + ret = unsup_alg(out, pkey, 0, "Public Key"); + + end: + print_reset_indent(&out, pop_f_prefix, saved_indent); + return ret; } int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - if (pkey->ameth && pkey->ameth->pub_print) - return pkey->ameth->pub_print(out, pkey, indent, pctx); - - return unsup_alg(out, pkey, indent, "Public Key"); + return print_pkey(pkey, out, indent, EVP_PKEY_PUBLIC_KEY, NULL, + (pkey->ameth != NULL ? pkey->ameth->pub_print : NULL), + pctx); } int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - if (pkey->ameth && pkey->ameth->priv_print) - return pkey->ameth->priv_print(out, pkey, indent, pctx); - - return unsup_alg(out, pkey, indent, "Private Key"); + return print_pkey(pkey, out, indent, EVP_PKEY_KEYPAIR, NULL, + (pkey->ameth != NULL ? pkey->ameth->priv_print : NULL), + pctx); } int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - if (pkey->ameth && pkey->ameth->param_print) - return pkey->ameth->param_print(out, pkey, indent, pctx); - return unsup_alg(out, pkey, indent, "Parameters"); + return print_pkey(pkey, out, indent, EVP_PKEY_KEY_PARAMETERS, NULL, + (pkey->ameth != NULL ? pkey->ameth->param_print : NULL), + pctx); +} + +# ifndef OPENSSL_NO_STDIO +int EVP_PKEY_print_public_fp(FILE *fp, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) +{ + int ret; + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + + if (b == NULL) + return 0; + ret = EVP_PKEY_print_public(b, pkey, indent, pctx); + BIO_free(b); + return ret; +} + +int EVP_PKEY_print_private_fp(FILE *fp, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) +{ + int ret; + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + + if (b == NULL) + return 0; + ret = EVP_PKEY_print_private(b, pkey, indent, pctx); + BIO_free(b); + return ret; +} + +int EVP_PKEY_print_params_fp(FILE *fp, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) +{ + int ret; + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + + if (b == NULL) + return 0; + ret = EVP_PKEY_print_params(b, pkey, indent, pctx); + BIO_free(b); + return ret; +} +# endif + +static void mdname2nid(const char *mdname, void *data) +{ + int *nid = (int *)data; + + if (*nid != NID_undef) + return; + + *nid = OBJ_sn2nid(mdname); + if (*nid == NID_undef) + *nid = OBJ_ln2nid(mdname); +} + +static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op, + int arg1, void *arg2) +{ + if (pkey->keymgmt == NULL) + return 0; + switch (op) { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + { + char mdname[80] = ""; + int rv = EVP_PKEY_get_default_digest_name(pkey, mdname, + sizeof(mdname)); + + if (rv > 0) { + int mdnum; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(pkey->keymgmt->prov); + /* Make sure the MD is in the namemap if available */ + EVP_MD *md; + OSSL_NAMEMAP *namemap; + int nid = NID_undef; + + (void)ERR_set_mark(); + md = EVP_MD_fetch(libctx, mdname, NULL); + (void)ERR_pop_to_mark(); + namemap = ossl_namemap_stored(libctx); + + /* + * The only reason to fetch the MD was to make sure it is in the + * namemap. We can immediately free it. + */ + EVP_MD_free(md); + mdnum = ossl_namemap_name2num(namemap, mdname); + if (mdnum == 0) + return 0; + + /* + * We have the namemap number - now we need to find the + * associated nid + */ + if (!ossl_namemap_doall_names(namemap, mdnum, mdname2nid, &nid)) + return 0; + *(int *)arg2 = nid; + } + return rv; + } + default: + return -2; + } } static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2) { - if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) + if (pkey->ameth == NULL) + return legacy_asn1_ctrl_to_param(pkey, op, arg1, arg2); + if (pkey->ameth->pkey_ctrl == NULL) return -2; return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2); } @@ -677,22 +1327,1134 @@ int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid); } -int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, - const unsigned char *pt, size_t ptlen) +int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey, + char *mdname, size_t mdname_sz) +{ + if (pkey->ameth == NULL) + return evp_keymgmt_util_get_deflt_digest_name(pkey->keymgmt, + pkey->keydata, + mdname, mdname_sz); + + { + int nid = NID_undef; + int rv = EVP_PKEY_get_default_digest_nid(pkey, &nid); + const char *name = rv > 0 ? OBJ_nid2sn(nid) : NULL; + + if (rv > 0) + OPENSSL_strlcpy(mdname, name, mdname_sz); + return rv; + } +} + +int EVP_PKEY_get_group_name(const EVP_PKEY *pkey, char *gname, size_t gname_sz, + size_t *gname_len) +{ + return EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, + gname, gname_sz, gname_len); +} + +int EVP_PKEY_digestsign_supports_digest(EVP_PKEY *pkey, OSSL_LIB_CTX *libctx, + const char *name, const char *propq) +{ + int rv; + EVP_MD_CTX *ctx = NULL; + + if ((ctx = EVP_MD_CTX_new()) == NULL) + return -1; + + ERR_set_mark(); + rv = EVP_DigestSignInit_ex(ctx, NULL, name, libctx, + propq, pkey, NULL); + ERR_pop_to_mark(); + + EVP_MD_CTX_free(ctx); + return rv; +} + +int EVP_PKEY_set1_encoded_public_key(EVP_PKEY *pkey, const unsigned char *pub, + size_t publen) { - if (ptlen > INT_MAX) + if (pkey != NULL && evp_pkey_is_provided(pkey)) + return + EVP_PKEY_set_octet_string_param(pkey, + OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, + (unsigned char *)pub, publen); + + if (publen > INT_MAX) return 0; - if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen, - (void *)pt) <= 0) + /* Historically this function was EVP_PKEY_set1_tls_encodedpoint */ + if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, publen, + (void *)pub) <= 0) return 0; return 1; } -size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt) +size_t EVP_PKEY_get1_encoded_public_key(EVP_PKEY *pkey, unsigned char **ppub) { int rv; - rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt); + + if (pkey != NULL && evp_pkey_is_provided(pkey)) { + size_t return_size = OSSL_PARAM_UNMODIFIED; + unsigned char *buf; + + /* + * We know that this is going to fail, but it will give us a size + * to allocate. + */ + EVP_PKEY_get_octet_string_param(pkey, + OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, + NULL, 0, &return_size); + if (return_size == OSSL_PARAM_UNMODIFIED) + return 0; + + *ppub = NULL; + buf = OPENSSL_malloc(return_size); + if (buf == NULL) + return 0; + + if (!EVP_PKEY_get_octet_string_param(pkey, + OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, + buf, return_size, NULL)) { + OPENSSL_free(buf); + return 0; + } + *ppub = buf; + return return_size; + } + + + rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppub); if (rv <= 0) return 0; return rv; } + +#endif /* FIPS_MODULE */ + +/*- All methods below can also be used in FIPS_MODULE */ + +EVP_PKEY *EVP_PKEY_new(void) +{ + EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret)); + + if (ret == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->type = EVP_PKEY_NONE; + ret->save_type = EVP_PKEY_NONE; + ret->references = 1; + + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) { + EVPerr(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + +#ifndef FIPS_MODULE + ret->save_parameters = 1; + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, ret, &ret->ex_data)) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + goto err; + } +#endif + return ret; + + err: + CRYPTO_THREAD_lock_free(ret->lock); + OPENSSL_free(ret); + return NULL; +} + +/* + * Setup a public key management method. + * + * For legacy keys, either |type| or |str| is expected to have the type + * information. In this case, the setup consists of finding an ASN1 method + * and potentially an ENGINE, and setting those fields in |pkey|. + * + * For provider side keys, |keymgmt| is expected to be non-NULL. In this + * case, the setup consists of setting the |keymgmt| field in |pkey|. + * + * If pkey is NULL just return 1 or 0 if the key management method exists. + */ + +static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, + int len, EVP_KEYMGMT *keymgmt) +{ +#ifndef FIPS_MODULE + const EVP_PKEY_ASN1_METHOD *ameth = NULL; + ENGINE **eptr = (e == NULL) ? &e : NULL; +#endif + + /* + * The setups can't set both legacy and provider side methods. + * It is forbidden + */ + if (!ossl_assert(type == EVP_PKEY_NONE || keymgmt == NULL) + || !ossl_assert(e == NULL || keymgmt == NULL)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (pkey != NULL) { + int free_it = 0; + +#ifndef FIPS_MODULE + free_it = free_it || pkey->pkey.ptr != NULL; +#endif + free_it = free_it || pkey->keydata != NULL; + if (free_it) + evp_pkey_free_it(pkey); +#ifndef FIPS_MODULE + /* + * If key type matches and a method exists then this lookup has + * succeeded once so just indicate success. + */ + if (pkey->type != EVP_PKEY_NONE + && type == pkey->save_type + && pkey->ameth != NULL) + return 1; +# ifndef OPENSSL_NO_ENGINE + /* If we have ENGINEs release them */ + ENGINE_finish(pkey->engine); + pkey->engine = NULL; + ENGINE_finish(pkey->pmeth_engine); + pkey->pmeth_engine = NULL; +# endif +#endif + } +#ifndef FIPS_MODULE + if (str != NULL) + ameth = EVP_PKEY_asn1_find_str(eptr, str, len); + else if (type != EVP_PKEY_NONE) + ameth = EVP_PKEY_asn1_find(eptr, type); +# ifndef OPENSSL_NO_ENGINE + if (pkey == NULL && eptr != NULL) + ENGINE_finish(e); +# endif +#endif + + + { + int check = 1; + +#ifndef FIPS_MODULE + check = check && ameth == NULL; +#endif + check = check && keymgmt == NULL; + if (check) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + } + if (pkey != NULL) { + if (keymgmt != NULL && !EVP_KEYMGMT_up_ref(keymgmt)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + + pkey->keymgmt = keymgmt; + + pkey->save_type = type; + pkey->type = type; + +#ifndef FIPS_MODULE + /* + * If the internal "origin" key is provider side, don't save |ameth|. + * The main reason is that |ameth| is one factor to detect that the + * internal "origin" key is a legacy one. + */ + if (keymgmt == NULL) + pkey->ameth = ameth; + + /* + * The EVP_PKEY_ASN1_METHOD |pkey_id| retains its legacy key purpose + * for any key type that has a legacy implementation, regardless of + * if the internal key is a legacy or a provider side one. When + * there is no legacy implementation for the key, the type becomes + * EVP_PKEY_KEYMGMT, which indicates that one should be cautious + * with functions that expect legacy internal keys. + */ + if (ameth != NULL) { + if (type == EVP_PKEY_NONE) + pkey->type = ameth->pkey_id; + } else { + pkey->type = EVP_PKEY_KEYMGMT; + } +# ifndef OPENSSL_NO_ENGINE + if (eptr == NULL && e != NULL && !ENGINE_init(e)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } +# endif + pkey->engine = e; +#endif + } + return 1; +} + +#ifndef FIPS_MODULE +static void find_ameth(const char *name, void *data) +{ + const char **str = data; + + /* + * The error messages from pkey_set_type() are uninteresting here, + * and misleading. + */ + ERR_set_mark(); + + if (pkey_set_type(NULL, NULL, EVP_PKEY_NONE, name, strlen(name), + NULL)) { + if (str[0] == NULL) + str[0] = name; + else if (str[1] == NULL) + str[1] = name; + } + + ERR_pop_to_mark(); +} +#endif + +int EVP_PKEY_set_type_by_keymgmt(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt) +{ +#ifndef FIPS_MODULE +# define EVP_PKEY_TYPE_STR str[0] +# define EVP_PKEY_TYPE_STRLEN (str[0] == NULL ? -1 : (int)strlen(str[0])) + /* + * Find at most two strings that have an associated EVP_PKEY_ASN1_METHOD + * Ideally, only one should be found. If two (or more) are found, the + * match is ambiguous. This should never happen, but... + */ + const char *str[2] = { NULL, NULL }; + + if (!EVP_KEYMGMT_names_do_all(keymgmt, find_ameth, &str) + || str[1] != NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; + } +#else +# define EVP_PKEY_TYPE_STR NULL +# define EVP_PKEY_TYPE_STRLEN -1 +#endif + return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, + EVP_PKEY_TYPE_STR, EVP_PKEY_TYPE_STRLEN, + keymgmt); + +#undef EVP_PKEY_TYPE_STR +#undef EVP_PKEY_TYPE_STRLEN +} + +int EVP_PKEY_up_ref(EVP_PKEY *pkey) +{ + int i; + + if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0) + return 0; + + REF_PRINT_COUNT("EVP_PKEY", pkey); + REF_ASSERT_ISNT(i < 2); + return ((i > 1) ? 1 : 0); +} + +#ifndef FIPS_MODULE +EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey) +{ + EVP_PKEY *dup_pk; + + if (pkey == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if ((dup_pk = EVP_PKEY_new()) == NULL) + return NULL; + + if (evp_pkey_is_blank(pkey)) + goto done; + + if (evp_pkey_is_provided(pkey)) { + if (!evp_keymgmt_util_copy(dup_pk, pkey, + OSSL_KEYMGMT_SELECT_ALL)) + goto err; + goto done; + } + + if (evp_pkey_is_legacy(pkey)) { + const EVP_PKEY_ASN1_METHOD *ameth = pkey->ameth; + + if (ameth == NULL || ameth->copy == NULL) { + if (pkey->pkey.ptr == NULL /* empty key, just set type */ + && EVP_PKEY_set_type(dup_pk, pkey->type) != 0) + goto done; + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE); + goto err; + } + if (!ameth->copy(dup_pk, pkey)) + goto err; + goto done; + } + + goto err; +done: + /* copy auxiliary data */ + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, + &dup_pk->ex_data, &pkey->ex_data)) + goto err; + + if (pkey->attributes != NULL) { + if ((dup_pk->attributes = ossl_x509at_dup(pkey->attributes)) == NULL) + goto err; + } + return dup_pk; +err: + EVP_PKEY_free(dup_pk); + return NULL; +} + +void evp_pkey_free_legacy(EVP_PKEY *x) +{ + const EVP_PKEY_ASN1_METHOD *ameth = x->ameth; + ENGINE *tmpe = NULL; + + if (ameth == NULL && x->legacy_cache_pkey.ptr != NULL) + ameth = EVP_PKEY_asn1_find(&tmpe, x->type); + + if (ameth != NULL) { + if (x->legacy_cache_pkey.ptr != NULL) { + /* + * We should never have both a legacy origin key, and a key in the + * legacy cache. + */ + assert(x->pkey.ptr == NULL); + /* + * For the purposes of freeing we make the legacy cache look like + * a legacy origin key. + */ + x->pkey = x->legacy_cache_pkey; + x->legacy_cache_pkey.ptr = NULL; + } + if (ameth->pkey_free != NULL) + ameth->pkey_free(x); + x->pkey.ptr = NULL; + } +# ifndef OPENSSL_NO_ENGINE + ENGINE_finish(tmpe); + ENGINE_finish(x->engine); + x->engine = NULL; + ENGINE_finish(x->pmeth_engine); + x->pmeth_engine = NULL; +# endif +} +#endif /* FIPS_MODULE */ + +static void evp_pkey_free_it(EVP_PKEY *x) +{ + /* internal function; x is never NULL */ + evp_keymgmt_util_clear_operation_cache(x, 1); +#ifndef FIPS_MODULE + evp_pkey_free_legacy(x); +#endif + + if (x->keymgmt != NULL) { + evp_keymgmt_freedata(x->keymgmt, x->keydata); + EVP_KEYMGMT_free(x->keymgmt); + x->keymgmt = NULL; + x->keydata = NULL; + } + x->type = EVP_PKEY_NONE; +} + +void EVP_PKEY_free(EVP_PKEY *x) +{ + int i; + + if (x == NULL) + return; + + CRYPTO_DOWN_REF(&x->references, &i, x->lock); + REF_PRINT_COUNT("EVP_PKEY", x); + if (i > 0) + return; + REF_ASSERT_ISNT(i < 0); + evp_pkey_free_it(x); +#ifndef FIPS_MODULE + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, x, &x->ex_data); +#endif + CRYPTO_THREAD_lock_free(x->lock); +#ifndef FIPS_MODULE + sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free); +#endif + OPENSSL_free(x); +} + +int EVP_PKEY_get_size(const EVP_PKEY *pkey) +{ + int size = 0; + + if (pkey != NULL) { + size = pkey->cache.size; +#ifndef FIPS_MODULE + if (pkey->ameth != NULL && pkey->ameth->pkey_size != NULL) + size = pkey->ameth->pkey_size(pkey); +#endif + } + return size < 0 ? 0 : size; +} + +const char *EVP_PKEY_get0_description(const EVP_PKEY *pkey) +{ + if (!evp_pkey_is_assigned(pkey)) + return NULL; + + if (evp_pkey_is_provided(pkey) && pkey->keymgmt->description != NULL) + return pkey->keymgmt->description; +#ifndef FIPS_MODULE + if (pkey->ameth != NULL) + return pkey->ameth->info; +#endif + return NULL; +} + +void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx, + EVP_KEYMGMT **keymgmt, + const char *propquery) +{ + EVP_KEYMGMT *allocated_keymgmt = NULL; + EVP_KEYMGMT *tmp_keymgmt = NULL; + int selection = OSSL_KEYMGMT_SELECT_ALL; + void *keydata = NULL; + int check; + + if (pk == NULL) + return NULL; + + /* No key data => nothing to export */ + check = 1; +#ifndef FIPS_MODULE + check = check && pk->pkey.ptr == NULL; +#endif + check = check && pk->keydata == NULL; + if (check) + return NULL; + +#ifndef FIPS_MODULE + if (pk->pkey.ptr != NULL) { + /* + * If the legacy key doesn't have an dirty counter or export function, + * give up + */ + if (pk->ameth->dirty_cnt == NULL || pk->ameth->export_to == NULL) + return NULL; + } +#endif + + if (keymgmt != NULL) { + tmp_keymgmt = *keymgmt; + *keymgmt = NULL; + } + + /* + * If no keymgmt was given or found, get a default keymgmt. We do so by + * letting EVP_PKEY_CTX_new_from_pkey() do it for us, then we steal it. + */ + if (tmp_keymgmt == NULL) { + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propquery); + + if (ctx == NULL) + goto end; + allocated_keymgmt = tmp_keymgmt = ctx->keymgmt; + ctx->keymgmt = NULL; + EVP_PKEY_CTX_free(ctx); + } + + /* If there's still no keymgmt to be had, give up */ + if (tmp_keymgmt == NULL) + goto end; + +#ifndef FIPS_MODULE + if (pk->pkey.ptr != NULL) { + OP_CACHE_ELEM *op; + + /* + * If the legacy "origin" hasn't changed since last time, we try + * to find our keymgmt in the operation cache. If it has changed, + * |i| remains zero, and we will clear the cache further down. + */ + if (pk->ameth->dirty_cnt(pk) == pk->dirty_cnt_copy) { + if (!CRYPTO_THREAD_read_lock(pk->lock)) + goto end; + op = evp_keymgmt_util_find_operation_cache(pk, tmp_keymgmt, + selection); + + /* + * If |tmp_keymgmt| is present in the operation cache, it means + * that export doesn't need to be redone. In that case, we take + * token copies of the cached pointers, to have token success + * values to return. + */ + if (op != NULL && op->keymgmt != NULL) { + keydata = op->keydata; + CRYPTO_THREAD_unlock(pk->lock); + goto end; + } + CRYPTO_THREAD_unlock(pk->lock); + } + + /* Make sure that the keymgmt key type matches the legacy NID */ + if (!EVP_KEYMGMT_is_a(tmp_keymgmt, OBJ_nid2sn(pk->type))) + goto end; + + if ((keydata = evp_keymgmt_newdata(tmp_keymgmt)) == NULL) + goto end; + + if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt->import, + libctx, propquery)) { + evp_keymgmt_freedata(tmp_keymgmt, keydata); + keydata = NULL; + goto end; + } + + /* + * If the dirty counter changed since last time, then clear the + * operation cache. In that case, we know that |i| is zero. Just + * in case this is a re-export, we increment then decrement the + * keymgmt reference counter. + */ + if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { /* refcnt++ */ + evp_keymgmt_freedata(tmp_keymgmt, keydata); + keydata = NULL; + goto end; + } + + if (!CRYPTO_THREAD_write_lock(pk->lock)) + goto end; + if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy + && !evp_keymgmt_util_clear_operation_cache(pk, 0)) { + CRYPTO_THREAD_unlock(pk->lock); + evp_keymgmt_freedata(tmp_keymgmt, keydata); + keydata = NULL; + EVP_KEYMGMT_free(tmp_keymgmt); + goto end; + } + EVP_KEYMGMT_free(tmp_keymgmt); /* refcnt-- */ + + /* Check to make sure some other thread didn't get there first */ + op = evp_keymgmt_util_find_operation_cache(pk, tmp_keymgmt, selection); + if (op != NULL && op->keymgmt != NULL) { + void *tmp_keydata = op->keydata; + + CRYPTO_THREAD_unlock(pk->lock); + evp_keymgmt_freedata(tmp_keymgmt, keydata); + keydata = tmp_keydata; + goto end; + } + + /* Add the new export to the operation cache */ + if (!evp_keymgmt_util_cache_keydata(pk, tmp_keymgmt, keydata, + selection)) { + CRYPTO_THREAD_unlock(pk->lock); + evp_keymgmt_freedata(tmp_keymgmt, keydata); + keydata = NULL; + goto end; + } + + /* Synchronize the dirty count */ + pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk); + + CRYPTO_THREAD_unlock(pk->lock); + goto end; + } +#endif /* FIPS_MODULE */ + + keydata = evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt, selection); + + end: + /* + * If nothing was exported, |tmp_keymgmt| might point at a freed + * EVP_KEYMGMT, so we clear it to be safe. It shouldn't be useful for + * the caller either way in that case. + */ + if (keydata == NULL) + tmp_keymgmt = NULL; + + if (keymgmt != NULL && tmp_keymgmt != NULL) { + *keymgmt = tmp_keymgmt; + allocated_keymgmt = NULL; + } + + EVP_KEYMGMT_free(allocated_keymgmt); + return keydata; +} + +#ifndef FIPS_MODULE +int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src) +{ + EVP_PKEY *allocpkey = NULL; + + if (!ossl_assert(dest != NULL)) + return 0; + + if (evp_pkey_is_assigned(src) && evp_pkey_is_provided(src)) { + EVP_KEYMGMT *keymgmt = src->keymgmt; + void *keydata = src->keydata; + int type = src->type; + const char *keytype = NULL; + + keytype = EVP_KEYMGMT_get0_name(keymgmt); + + /* + * If the type is EVP_PKEY_NONE, then we have a problem somewhere + * else in our code. If it's not one of the well known EVP_PKEY_xxx + * values, it should at least be EVP_PKEY_KEYMGMT at this point. + * The check is kept as a safety measure. + */ + if (!ossl_assert(type != EVP_PKEY_NONE)) { + ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR, + "keymgmt key type = %s but legacy type = EVP_PKEY_NONE", + keytype); + return 0; + } + + /* Prefer the legacy key type name for error reporting */ + if (type != EVP_PKEY_KEYMGMT) + keytype = OBJ_nid2sn(type); + + /* Make sure we have a clean slate to copy into */ + if (*dest == NULL) { + allocpkey = *dest = EVP_PKEY_new(); + if (*dest == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + evp_pkey_free_it(*dest); + } + + if (EVP_PKEY_set_type(*dest, type)) { + /* If the key is typed but empty, we're done */ + if (keydata == NULL) + return 1; + + if ((*dest)->ameth->import_from == NULL) { + ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION, + "key type = %s", keytype); + } else { + /* + * We perform the export in the same libctx as the keymgmt + * that we are using. + */ + OSSL_LIB_CTX *libctx = + ossl_provider_libctx(keymgmt->prov); + EVP_PKEY_CTX *pctx = + EVP_PKEY_CTX_new_from_pkey(libctx, *dest, NULL); + + if (pctx == NULL) + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + + if (pctx != NULL + && evp_keymgmt_export(keymgmt, keydata, + OSSL_KEYMGMT_SELECT_ALL, + (*dest)->ameth->import_from, + pctx)) { + /* Synchronize the dirty count */ + (*dest)->dirty_cnt_copy = (*dest)->ameth->dirty_cnt(*dest); + + EVP_PKEY_CTX_free(pctx); + return 1; + } + EVP_PKEY_CTX_free(pctx); + } + + ERR_raise_data(ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE, + "key type = %s", keytype); + } + } + + if (allocpkey != NULL) { + EVP_PKEY_free(allocpkey); + *dest = NULL; + } + return 0; +} + +void *evp_pkey_get_legacy(EVP_PKEY *pk) +{ + EVP_PKEY *tmp_copy = NULL; + void *ret = NULL; + + if (!ossl_assert(pk != NULL)) + return NULL; + + /* + * If this isn't an assigned provider side key, we just use any existing + * origin legacy key. + */ + if (!evp_pkey_is_assigned(pk)) + return NULL; + if (!evp_pkey_is_provided(pk)) + return pk->pkey.ptr; + + if (!CRYPTO_THREAD_read_lock(pk->lock)) + return NULL; + + ret = pk->legacy_cache_pkey.ptr; + + if (!CRYPTO_THREAD_unlock(pk->lock)) + return NULL; + + if (ret != NULL) + return ret; + + if (!evp_pkey_copy_downgraded(&tmp_copy, pk)) + goto err; + + if (!CRYPTO_THREAD_write_lock(pk->lock)) + goto err; + + /* Check again in case some other thread has updated it in the meantime */ + ret = pk->legacy_cache_pkey.ptr; + if (ret == NULL) { + /* Steal the legacy key reference from the temporary copy */ + ret = pk->legacy_cache_pkey.ptr = tmp_copy->pkey.ptr; + tmp_copy->pkey.ptr = NULL; + } + + if (!CRYPTO_THREAD_unlock(pk->lock)) { + ret = NULL; + goto err; + } + + err: + EVP_PKEY_free(tmp_copy); + + return ret; +} +#endif /* FIPS_MODULE */ + +int EVP_PKEY_get_bn_param(const EVP_PKEY *pkey, const char *key_name, + BIGNUM **bn) +{ + int ret = 0; + OSSL_PARAM params[2]; + unsigned char buffer[2048]; + unsigned char *buf = NULL; + size_t buf_sz = 0; + + if (key_name == NULL + || bn == NULL) + return 0; + + memset(buffer, 0, sizeof(buffer)); + params[0] = OSSL_PARAM_construct_BN(key_name, buffer, sizeof(buffer)); + params[1] = OSSL_PARAM_construct_end(); + if (!EVP_PKEY_get_params(pkey, params)) { + if (!OSSL_PARAM_modified(params) || params[0].return_size == 0) + return 0; + buf_sz = params[0].return_size; + /* + * If it failed because the buffer was too small then allocate the + * required buffer size and retry. + */ + buf = OPENSSL_zalloc(buf_sz); + if (buf == NULL) + return 0; + params[0].data = buf; + params[0].data_size = buf_sz; + + if (!EVP_PKEY_get_params(pkey, params)) + goto err; + } + /* Fail if the param was not found */ + if (!OSSL_PARAM_modified(params)) + goto err; + ret = OSSL_PARAM_get_BN(params, bn); +err: + OPENSSL_free(buf); + return ret; +} + +int EVP_PKEY_get_octet_string_param(const EVP_PKEY *pkey, const char *key_name, + unsigned char *buf, size_t max_buf_sz, + size_t *out_len) +{ + OSSL_PARAM params[2]; + int ret1 = 0, ret2 = 0; + + if (key_name == NULL) + return 0; + + params[0] = OSSL_PARAM_construct_octet_string(key_name, buf, max_buf_sz); + params[1] = OSSL_PARAM_construct_end(); + if ((ret1 = EVP_PKEY_get_params(pkey, params))) + ret2 = OSSL_PARAM_modified(params); + if (ret2 && out_len != NULL) + *out_len = params[0].return_size; + return ret1 && ret2; +} + +int EVP_PKEY_get_utf8_string_param(const EVP_PKEY *pkey, const char *key_name, + char *str, size_t max_buf_sz, + size_t *out_len) +{ + OSSL_PARAM params[2]; + int ret1 = 0, ret2 = 0; + + if (key_name == NULL) + return 0; + + params[0] = OSSL_PARAM_construct_utf8_string(key_name, str, max_buf_sz); + params[1] = OSSL_PARAM_construct_end(); + if ((ret1 = EVP_PKEY_get_params(pkey, params))) + ret2 = OSSL_PARAM_modified(params); + if (ret2 && out_len != NULL) + *out_len = params[0].return_size; + + if (ret2 && params[0].return_size == max_buf_sz) + /* There was no space for a NUL byte */ + return 0; + /* Add a terminating NUL byte for good measure */ + if (ret2 && str != NULL) + str[params[0].return_size] = '\0'; + + return ret1 && ret2; +} + +int EVP_PKEY_get_int_param(const EVP_PKEY *pkey, const char *key_name, + int *out) +{ + OSSL_PARAM params[2]; + + if (key_name == NULL) + return 0; + + params[0] = OSSL_PARAM_construct_int(key_name, out); + params[1] = OSSL_PARAM_construct_end(); + return EVP_PKEY_get_params(pkey, params) + && OSSL_PARAM_modified(params); +} + +int EVP_PKEY_get_size_t_param(const EVP_PKEY *pkey, const char *key_name, + size_t *out) +{ + OSSL_PARAM params[2]; + + if (key_name == NULL) + return 0; + + params[0] = OSSL_PARAM_construct_size_t(key_name, out); + params[1] = OSSL_PARAM_construct_end(); + return EVP_PKEY_get_params(pkey, params) + && OSSL_PARAM_modified(params); +} + +int EVP_PKEY_set_int_param(EVP_PKEY *pkey, const char *key_name, int in) +{ + OSSL_PARAM params[2]; + + if (key_name == NULL) + return 0; + + params[0] = OSSL_PARAM_construct_int(key_name, &in); + params[1] = OSSL_PARAM_construct_end(); + return EVP_PKEY_set_params(pkey, params); +} + +int EVP_PKEY_set_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t in) +{ + OSSL_PARAM params[2]; + + if (key_name == NULL) + return 0; + + params[0] = OSSL_PARAM_construct_size_t(key_name, &in); + params[1] = OSSL_PARAM_construct_end(); + return EVP_PKEY_set_params(pkey, params); +} + +int EVP_PKEY_set_bn_param(EVP_PKEY *pkey, const char *key_name, + const BIGNUM *bn) +{ + OSSL_PARAM params[2]; + unsigned char buffer[2048]; + int bsize = 0; + + if (key_name == NULL + || bn == NULL + || pkey == NULL + || !evp_pkey_is_assigned(pkey)) + return 0; + + bsize = BN_num_bytes(bn); + if (!ossl_assert(bsize <= (int)sizeof(buffer))) + return 0; + + if (BN_bn2nativepad(bn, buffer, bsize) < 0) + return 0; + params[0] = OSSL_PARAM_construct_BN(key_name, buffer, bsize); + params[1] = OSSL_PARAM_construct_end(); + return EVP_PKEY_set_params(pkey, params); +} + +int EVP_PKEY_set_utf8_string_param(EVP_PKEY *pkey, const char *key_name, + const char *str) +{ + OSSL_PARAM params[2]; + + if (key_name == NULL) + return 0; + + params[0] = OSSL_PARAM_construct_utf8_string(key_name, (char *)str, 0); + params[1] = OSSL_PARAM_construct_end(); + return EVP_PKEY_set_params(pkey, params); +} + +int EVP_PKEY_set_octet_string_param(EVP_PKEY *pkey, const char *key_name, + const unsigned char *buf, size_t bsize) +{ + OSSL_PARAM params[2]; + + if (key_name == NULL) + return 0; + + params[0] = OSSL_PARAM_construct_octet_string(key_name, + (unsigned char *)buf, bsize); + params[1] = OSSL_PARAM_construct_end(); + return EVP_PKEY_set_params(pkey, params); +} + +const OSSL_PARAM *EVP_PKEY_settable_params(const EVP_PKEY *pkey) +{ + return (pkey != NULL && evp_pkey_is_provided(pkey)) + ? EVP_KEYMGMT_settable_params(pkey->keymgmt) + : NULL; +} + +int EVP_PKEY_set_params(EVP_PKEY *pkey, OSSL_PARAM params[]) +{ + if (pkey != NULL) { + if (evp_pkey_is_provided(pkey)) { + pkey->dirty_cnt++; + return evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params); + } +#ifndef FIPS_MODULE + /* + * We will hopefully never find the need to set individual data in + * EVP_PKEYs with a legacy internal key, but we can't be entirely + * sure. This bit of code can be enabled if we find the need. If + * not, it can safely be removed when #legacy support is removed. + */ +# if 0 + else if (evp_pkey_is_legacy(pkey)) { + return evp_pkey_set_params_to_ctrl(pkey, params); + } +# endif +#endif + } + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY); + return 0; +} + +const OSSL_PARAM *EVP_PKEY_gettable_params(const EVP_PKEY *pkey) +{ + return (pkey != NULL && evp_pkey_is_provided(pkey)) + ? EVP_KEYMGMT_gettable_params(pkey->keymgmt) + : NULL; +} + +int EVP_PKEY_get_params(const EVP_PKEY *pkey, OSSL_PARAM params[]) +{ + if (pkey != NULL) { + if (evp_pkey_is_provided(pkey)) + return evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params) > 0; +#ifndef FIPS_MODULE + else if (evp_pkey_is_legacy(pkey)) + return evp_pkey_get_params_to_ctrl(pkey, params) > 0; +#endif + } + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY); + return 0; +} + +#ifndef FIPS_MODULE +int EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY *pkey) +{ + char name[80]; + size_t name_len; + + if (pkey == NULL) + return 0; + + if (pkey->keymgmt == NULL + || pkey->keydata == NULL) { +# ifndef OPENSSL_NO_EC + /* Might work through the legacy route */ + const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); + + if (ec == NULL) + return 0; + + return EC_KEY_get_conv_form(ec); +# else + return 0; +# endif + } + + if (!EVP_PKEY_get_utf8_string_param(pkey, + OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, + name, sizeof(name), &name_len)) + return 0; + + if (strcmp(name, "uncompressed") == 0) + return POINT_CONVERSION_UNCOMPRESSED; + + if (strcmp(name, "compressed") == 0) + return POINT_CONVERSION_COMPRESSED; + + if (strcmp(name, "hybrid") == 0) + return POINT_CONVERSION_HYBRID; + + return 0; +} + +int EVP_PKEY_get_field_type(const EVP_PKEY *pkey) +{ + char fstr[80]; + size_t fstrlen; + + if (pkey == NULL) + return 0; + + if (pkey->keymgmt == NULL + || pkey->keydata == NULL) { +# ifndef OPENSSL_NO_EC + /* Might work through the legacy route */ + const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); + const EC_GROUP *grp; + + if (ec == NULL) + return 0; + grp = EC_KEY_get0_group(ec); + if (grp == NULL) + return 0; + + return EC_GROUP_get_field_type(grp); +# else + return 0; +# endif + } + + if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_EC_FIELD_TYPE, + fstr, sizeof(fstr), &fstrlen)) + return 0; + + if (strcmp(fstr, SN_X9_62_prime_field) == 0) + return NID_X9_62_prime_field; + else if (strcmp(fstr, SN_X9_62_characteristic_two_field)) + return NID_X9_62_characteristic_two_field; + + return 0; +} +#endif diff --git a/crypto/openssl/crypto/evp/p_open.c b/crypto/openssl/crypto/evp/p_open.c index 1ce87454bdec..8ee8b7a0276b 100644 --- a/crypto/openssl/crypto/evp/p_open.c +++ b/crypto/openssl/crypto/evp/p_open.c @@ -1,63 +1,63 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include "internal/cryptlib.h" -#ifdef OPENSSL_NO_RSA -NON_EMPTY_TRANSLATION_UNIT -#else -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, const unsigned char *ek, int ekl, const unsigned char *iv, EVP_PKEY *priv) { unsigned char *key = NULL; - int i, size = 0, ret = 0; + size_t keylen = 0; + int ret = 0; + EVP_PKEY_CTX *pctx = NULL; if (type) { EVP_CIPHER_CTX_reset(ctx); if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL)) - return 0; + goto err; } - if (!priv) + if (priv == NULL) return 1; - if (EVP_PKEY_id(priv) != EVP_PKEY_RSA) { - EVPerr(EVP_F_EVP_OPENINIT, EVP_R_PUBLIC_KEY_NOT_RSA); + if ((pctx = EVP_PKEY_CTX_new(priv, NULL)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); goto err; } - size = EVP_PKEY_size(priv); - key = OPENSSL_malloc(size); - if (key == NULL) { - /* ERROR */ - EVPerr(EVP_F_EVP_OPENINIT, ERR_R_MALLOC_FAILURE); + if (EVP_PKEY_decrypt_init(pctx) <= 0 + || EVP_PKEY_decrypt(pctx, NULL, &keylen, ek, ekl) <= 0) goto err; - } - i = EVP_PKEY_decrypt_old(key, ek, ekl, priv); - if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) { - /* ERROR */ + if ((key = OPENSSL_malloc(keylen)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); goto err; } - if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) + + if (EVP_PKEY_decrypt(pctx, key, &keylen, ek, ekl) <= 0) + goto err; + + if (EVP_CIPHER_CTX_set_key_length(ctx, keylen) <= 0 + || !EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) goto err; ret = 1; err: - OPENSSL_clear_free(key, size); + EVP_PKEY_CTX_free(pctx); + OPENSSL_clear_free(key, keylen); return ret; } @@ -70,4 +70,3 @@ int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) i = EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL); return i; } -#endif diff --git a/crypto/openssl/crypto/evp/p_seal.c b/crypto/openssl/crypto/evp/p_seal.c index e851d7ab8b56..475082d43116 100644 --- a/crypto/openssl/crypto/evp/p_seal.c +++ b/crypto/openssl/crypto/evp/p_seal.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,48 +9,70 @@ #include #include "internal/cryptlib.h" +#include "internal/provider.h" #include #include #include #include #include +#include int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk) { unsigned char key[EVP_MAX_KEY_LENGTH]; - int i; + const OSSL_PROVIDER *prov; + OSSL_LIB_CTX *libctx = NULL; + EVP_PKEY_CTX *pctx = NULL; + const EVP_CIPHER *cipher; + int i, len; int rv = 0; - if (type) { + if (type != NULL) { EVP_CIPHER_CTX_reset(ctx); if (!EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL)) return 0; } + if ((cipher = EVP_CIPHER_CTX_get0_cipher(ctx)) != NULL + && (prov = EVP_CIPHER_get0_provider(cipher)) != NULL) + libctx = ossl_provider_libctx(prov); if ((npubk <= 0) || !pubk) return 1; + if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) return 0; - if (EVP_CIPHER_CTX_iv_length(ctx) - && RAND_bytes(iv, EVP_CIPHER_CTX_iv_length(ctx)) <= 0) + len = EVP_CIPHER_CTX_get_iv_length(ctx); + if (len < 0 || RAND_priv_bytes_ex(libctx, iv, len, 0) <= 0) + goto err; + + len = EVP_CIPHER_CTX_get_key_length(ctx); + if (len < 0) goto err; if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) goto err; for (i = 0; i < npubk; i++) { - ekl[i] = - EVP_PKEY_encrypt_old(ek[i], key, EVP_CIPHER_CTX_key_length(ctx), - pubk[i]); - if (ekl[i] <= 0) { - rv = -1; + size_t keylen = len; + + pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pubk[i], NULL); + if (pctx == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); goto err; } + + if (EVP_PKEY_encrypt_init(pctx) <= 0 + || EVP_PKEY_encrypt(pctx, ek[i], &keylen, key, keylen) <= 0) + goto err; + ekl[i] = (int)keylen; + EVP_PKEY_CTX_free(pctx); } + pctx = NULL; rv = npubk; err: + EVP_PKEY_CTX_free(pctx); OPENSSL_cleanse(key, sizeof(key)); return rv; } diff --git a/crypto/openssl/crypto/evp/p_sign.c b/crypto/openssl/crypto/evp/p_sign.c index 0383294a87c8..8e430f4704b2 100644 --- a/crypto/openssl/crypto/evp/p_sign.c +++ b/crypto/openssl/crypto/evp/p_sign.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,8 +14,9 @@ #include #include "crypto/evp.h" -int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, - unsigned int *siglen, EVP_PKEY *pkey) +int EVP_SignFinal_ex(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey, OSSL_LIB_CTX *libctx, + const char *propq) { unsigned char m[EVP_MAX_MD_SIZE]; unsigned int m_len = 0; @@ -30,8 +31,9 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, } else { int rv = 0; EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); + if (tmp_ctx == NULL) { - EVPerr(EVP_F_EVP_SIGNFINAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx); @@ -42,14 +44,14 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, return 0; } - sltmp = (size_t)EVP_PKEY_size(pkey); + sltmp = (size_t)EVP_PKEY_get_size(pkey); i = 0; - pkctx = EVP_PKEY_CTX_new(pkey, NULL); + pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); if (pkctx == NULL) goto err; if (EVP_PKEY_sign_init(pkctx) <= 0) goto err; - if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 0) + if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_get0_md(ctx)) <= 0) goto err; if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0) goto err; @@ -59,3 +61,9 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, EVP_PKEY_CTX_free(pkctx); return i; } + +int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey) +{ + return EVP_SignFinal_ex(ctx, sigret, siglen, pkey, NULL, NULL); +} diff --git a/crypto/openssl/crypto/evp/p_verify.c b/crypto/openssl/crypto/evp/p_verify.c index e27196f7c2e6..e5667afb7cca 100644 --- a/crypto/openssl/crypto/evp/p_verify.c +++ b/crypto/openssl/crypto/evp/p_verify.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,8 +14,9 @@ #include #include "crypto/evp.h" -int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, - unsigned int siglen, EVP_PKEY *pkey) +int EVP_VerifyFinal_ex(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey, OSSL_LIB_CTX *libctx, + const char *propq) { unsigned char m[EVP_MAX_MD_SIZE]; unsigned int m_len = 0; @@ -28,8 +29,9 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, } else { int rv = 0; EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); + if (tmp_ctx == NULL) { - EVPerr(EVP_F_EVP_VERIFYFINAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx); @@ -41,15 +43,21 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, } i = -1; - pkctx = EVP_PKEY_CTX_new(pkey, NULL); + pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); if (pkctx == NULL) goto err; if (EVP_PKEY_verify_init(pkctx) <= 0) goto err; - if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 0) + if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_get0_md(ctx)) <= 0) goto err; i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len); err: EVP_PKEY_CTX_free(pkctx); return i; } + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey) +{ + return EVP_VerifyFinal_ex(ctx, sigbuf, siglen, pkey, NULL, NULL); +} diff --git a/crypto/openssl/crypto/evp/pbe_scrypt.c b/crypto/openssl/crypto/evp/pbe_scrypt.c index 57da82f3fe4c..78b2d13ec9e1 100644 --- a/crypto/openssl/crypto/evp/pbe_scrypt.c +++ b/crypto/openssl/crypto/evp/pbe_scrypt.c @@ -1,141 +1,20 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include -#include #include #include +#include +#include #include "internal/numbers.h" #ifndef OPENSSL_NO_SCRYPT -#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) -static void salsa208_word_specification(uint32_t inout[16]) -{ - int i; - uint32_t x[16]; - memcpy(x, inout, sizeof(x)); - for (i = 8; i > 0; i -= 2) { - x[4] ^= R(x[0] + x[12], 7); - x[8] ^= R(x[4] + x[0], 9); - x[12] ^= R(x[8] + x[4], 13); - x[0] ^= R(x[12] + x[8], 18); - x[9] ^= R(x[5] + x[1], 7); - x[13] ^= R(x[9] + x[5], 9); - x[1] ^= R(x[13] + x[9], 13); - x[5] ^= R(x[1] + x[13], 18); - x[14] ^= R(x[10] + x[6], 7); - x[2] ^= R(x[14] + x[10], 9); - x[6] ^= R(x[2] + x[14], 13); - x[10] ^= R(x[6] + x[2], 18); - x[3] ^= R(x[15] + x[11], 7); - x[7] ^= R(x[3] + x[15], 9); - x[11] ^= R(x[7] + x[3], 13); - x[15] ^= R(x[11] + x[7], 18); - x[1] ^= R(x[0] + x[3], 7); - x[2] ^= R(x[1] + x[0], 9); - x[3] ^= R(x[2] + x[1], 13); - x[0] ^= R(x[3] + x[2], 18); - x[6] ^= R(x[5] + x[4], 7); - x[7] ^= R(x[6] + x[5], 9); - x[4] ^= R(x[7] + x[6], 13); - x[5] ^= R(x[4] + x[7], 18); - x[11] ^= R(x[10] + x[9], 7); - x[8] ^= R(x[11] + x[10], 9); - x[9] ^= R(x[8] + x[11], 13); - x[10] ^= R(x[9] + x[8], 18); - x[12] ^= R(x[15] + x[14], 7); - x[13] ^= R(x[12] + x[15], 9); - x[14] ^= R(x[13] + x[12], 13); - x[15] ^= R(x[14] + x[13], 18); - } - for (i = 0; i < 16; ++i) - inout[i] += x[i]; - OPENSSL_cleanse(x, sizeof(x)); -} - -static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r) -{ - uint64_t i, j; - uint32_t X[16], *pB; - - memcpy(X, B + (r * 2 - 1) * 16, sizeof(X)); - pB = B; - for (i = 0; i < r * 2; i++) { - for (j = 0; j < 16; j++) - X[j] ^= *pB++; - salsa208_word_specification(X); - memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X)); - } - OPENSSL_cleanse(X, sizeof(X)); -} - -static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N, - uint32_t *X, uint32_t *T, uint32_t *V) -{ - unsigned char *pB; - uint32_t *pV; - uint64_t i, k; - - /* Convert from little endian input */ - for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) { - *pV = *pB++; - *pV |= *pB++ << 8; - *pV |= *pB++ << 16; - *pV |= (uint32_t)*pB++ << 24; - } - - for (i = 1; i < N; i++, pV += 32 * r) - scryptBlockMix(pV, pV - 32 * r, r); - - scryptBlockMix(X, V + (N - 1) * 32 * r, r); - - for (i = 0; i < N; i++) { - uint32_t j; - j = X[16 * (2 * r - 1)] % N; - pV = V + 32 * r * j; - for (k = 0; k < 32 * r; k++) - T[k] = X[k] ^ *pV++; - scryptBlockMix(X, T, r); - } - /* Convert output to little endian */ - for (i = 0, pB = B; i < 32 * r; i++) { - uint32_t xtmp = X[i]; - *pB++ = xtmp & 0xff; - *pB++ = (xtmp >> 8) & 0xff; - *pB++ = (xtmp >> 16) & 0xff; - *pB++ = (xtmp >> 24) & 0xff; - } -} - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t)-1) -#endif - -/* - * Maximum power of two that will fit in uint64_t: this should work on - * most (all?) platforms. - */ - -#define LOG2_UINT64_MAX (sizeof(uint64_t) * 8 - 1) - -/* - * Maximum value of p * r: - * p <= ((2^32-1) * hLen) / MFLen => - * p <= ((2^32-1) * 32) / (128 * r) => - * p * r <= (2^30-1) - * - */ - -#define SCRYPT_PR_MAX ((1 << 30) - 1) - /* * Maximum permitted memory allow this to be overridden with Configuration * option: e.g. -DSCRYPT_MAX_MEM=0 for maximum possible. @@ -155,112 +34,66 @@ static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N, # define SCRYPT_MAX_MEM (1024 * 1024 * 32) #endif -int EVP_PBE_scrypt(const char *pass, size_t passlen, - const unsigned char *salt, size_t saltlen, - uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, - unsigned char *key, size_t keylen) +int EVP_PBE_scrypt_ex(const char *pass, size_t passlen, + const unsigned char *salt, size_t saltlen, + uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, + unsigned char *key, size_t keylen, + OSSL_LIB_CTX *ctx, const char *propq) { - int rv = 0; - unsigned char *B; - uint32_t *X, *V, *T; - uint64_t i, Blen, Vlen; - - /* Sanity check parameters */ - /* initial check, r,p must be non zero, N >= 2 and a power of 2 */ - if (r == 0 || p == 0 || N < 2 || (N & (N - 1))) - return 0; - /* Check p * r < SCRYPT_PR_MAX avoiding overflow */ - if (p > SCRYPT_PR_MAX / r) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; - } - - /* - * Need to check N: if 2^(128 * r / 8) overflows limit this is - * automatically satisfied since N <= UINT64_MAX. - */ - - if (16 * r <= LOG2_UINT64_MAX) { - if (N >= (((uint64_t)1) << (16 * r))) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; - } - } - - /* Memory checks: check total allocated buffer size fits in uint64_t */ - - /* - * B size in section 5 step 1.S - * Note: we know p * 128 * r < UINT64_MAX because we already checked - * p * r < SCRYPT_PR_MAX - */ - Blen = p * 128 * r; - /* - * Yet we pass it as integer to PKCS5_PBKDF2_HMAC... [This would - * have to be revised when/if PKCS5_PBKDF2_HMAC accepts size_t.] - */ - if (Blen > INT_MAX) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); + const char *empty = ""; + int rv = 1; + EVP_KDF *kdf; + EVP_KDF_CTX *kctx; + OSSL_PARAM params[7], *z = params; + + if (r > UINT32_MAX || p > UINT32_MAX) { + ERR_raise(ERR_LIB_EVP, EVP_R_PARAMETER_TOO_LARGE); return 0; } - /* - * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t - * This is combined size V, X and T (section 4) - */ - i = UINT64_MAX / (32 * sizeof(uint32_t)); - if (N + 2 > i / r) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; + /* Maintain existing behaviour. */ + if (pass == NULL) { + pass = empty; + passlen = 0; } - Vlen = 32 * r * (N + 2) * sizeof(uint32_t); - - /* check total allocated size fits in uint64_t */ - if (Blen > UINT64_MAX - Vlen) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; + if (salt == NULL) { + salt = (const unsigned char *)empty; + saltlen = 0; } - if (maxmem == 0) maxmem = SCRYPT_MAX_MEM; - /* Check that the maximum memory doesn't exceed a size_t limits */ - if (maxmem > SIZE_MAX) - maxmem = SIZE_MAX; - - if (Blen + Vlen > maxmem) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); + /* Use OSSL_LIB_CTX_set0_default() if you need a library context */ + kdf = EVP_KDF_fetch(ctx, OSSL_KDF_NAME_SCRYPT, propq); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (kctx == NULL) return 0; - } - - /* If no key return to indicate parameters are OK */ - if (key == NULL) - return 1; - - B = OPENSSL_malloc((size_t)(Blen + Vlen)); - if (B == NULL) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, ERR_R_MALLOC_FAILURE); - return 0; - } - X = (uint32_t *)(B + Blen); - T = X + 32 * r; - V = T + 32 * r; - if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(), - (int)Blen, B) == 0) - goto err; - - for (i = 0; i < p; i++) - scryptROMix(B + 128 * r * i, r, N, X, T, V); - if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, EVP_sha256(), - keylen, key) == 0) - goto err; - rv = 1; - err: - if (rv == 0) - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PBKDF2_ERROR); - - OPENSSL_clear_free(B, (size_t)(Blen + Vlen)); + *z++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, + (unsigned char *)pass, + passlen); + *z++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + (unsigned char *)salt, saltlen); + *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_N, &N); + *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_R, &r); + *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_P, &p); + *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, &maxmem); + *z = OSSL_PARAM_construct_end(); + if (EVP_KDF_derive(kctx, key, keylen, params) != 1) + rv = 0; + + EVP_KDF_CTX_free(kctx); return rv; } + +int EVP_PBE_scrypt(const char *pass, size_t passlen, + const unsigned char *salt, size_t saltlen, + uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, + unsigned char *key, size_t keylen) +{ + return EVP_PBE_scrypt_ex(pass, passlen, salt, saltlen, N, r, p, maxmem, + key, keylen, NULL, NULL); +} + #endif diff --git a/crypto/openssl/crypto/evp/pmeth_check.c b/crypto/openssl/crypto/evp/pmeth_check.c new file mode 100644 index 000000000000..7f3a2e3a1c80 --- /dev/null +++ b/crypto/openssl/crypto/evp/pmeth_check.c @@ -0,0 +1,193 @@ +/* + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/cryptlib.h" +#include +#include +#include "crypto/bn.h" +#ifndef FIPS_MODULE +# include "crypto/asn1.h" +#endif +#include "crypto/evp.h" +#include "evp_local.h" + +/* + * Returns: + * 1 True + * 0 False + * -1 Unsupported (use legacy path) + */ +static int try_provided_check(EVP_PKEY_CTX *ctx, int selection, int checktype) +{ + EVP_KEYMGMT *keymgmt; + void *keydata; + + if (evp_pkey_ctx_is_legacy(ctx)) + return -1; + + keymgmt = ctx->keymgmt; + keydata = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, + &keymgmt, ctx->propquery); + if (keydata == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + + return evp_keymgmt_validate(keymgmt, keydata, selection, checktype); +} + +static int evp_pkey_public_check_combined(EVP_PKEY_CTX *ctx, int checktype) +{ + EVP_PKEY *pkey = ctx->pkey; + int ok; + + if (pkey == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); + return 0; + } + + if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, + checktype)) != -1) + return ok; + + if (pkey->type == EVP_PKEY_NONE) + goto not_supported; + +#ifndef FIPS_MODULE + /* legacy */ + /* call customized public key check function first */ + if (ctx->pmeth->public_check != NULL) + return ctx->pmeth->public_check(pkey); + + /* use default public key check function in ameth */ + if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL) + goto not_supported; + + return pkey->ameth->pkey_public_check(pkey); +#endif + not_supported: + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; +} + +int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_public_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_FULL_CHECK); +} + +int EVP_PKEY_public_check_quick(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_public_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_QUICK_CHECK); +} + +static int evp_pkey_param_check_combined(EVP_PKEY_CTX *ctx, int checktype) +{ + EVP_PKEY *pkey = ctx->pkey; + int ok; + + if (pkey == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); + return 0; + } + + if ((ok = try_provided_check(ctx, + OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, + checktype)) != -1) + return ok; + + if (pkey->type == EVP_PKEY_NONE) + goto not_supported; + +#ifndef FIPS_MODULE + /* legacy */ + /* call customized param check function first */ + if (ctx->pmeth->param_check != NULL) + return ctx->pmeth->param_check(pkey); + + /* use default param check function in ameth */ + if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL) + goto not_supported; + + return pkey->ameth->pkey_param_check(pkey); +#endif + not_supported: + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; +} + +int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_param_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_FULL_CHECK); +} + +int EVP_PKEY_param_check_quick(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_param_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_QUICK_CHECK); +} + +int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx) +{ + EVP_PKEY *pkey = ctx->pkey; + int ok; + + if (pkey == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); + return 0; + } + + if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_PRIVATE_KEY, + OSSL_KEYMGMT_VALIDATE_FULL_CHECK)) != -1) + return ok; + + /* not supported for legacy keys */ + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; +} + +int EVP_PKEY_check(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_pairwise_check(ctx); +} + +int EVP_PKEY_pairwise_check(EVP_PKEY_CTX *ctx) +{ + EVP_PKEY *pkey = ctx->pkey; + int ok; + + if (pkey == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); + return 0; + } + + if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_KEYPAIR, + OSSL_KEYMGMT_VALIDATE_FULL_CHECK)) != -1) + return ok; + + if (pkey->type == EVP_PKEY_NONE) + goto not_supported; + +#ifndef FIPS_MODULE + /* legacy */ + /* call customized check function first */ + if (ctx->pmeth->check != NULL) + return ctx->pmeth->check(pkey); + + /* use default check function in ameth */ + if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL) + goto not_supported; + + return pkey->ameth->pkey_check(pkey); +#endif + not_supported: + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; +} + diff --git a/crypto/openssl/crypto/evp/pmeth_fn.c b/crypto/openssl/crypto/evp/pmeth_fn.c deleted file mode 100644 index 02f4093461d8..000000000000 --- a/crypto/openssl/crypto/evp/pmeth_fn.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2006-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 - */ - -#include -#include -#include "internal/cryptlib.h" -#include -#include -#include "crypto/evp.h" - -#define M_check_autoarg(ctx, arg, arglen, err) \ - if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) { \ - size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \ - \ - if (pksize == 0) { \ - EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \ - return 0; \ - } \ - if (!arg) { \ - *arglen = pksize; \ - return 1; \ - } \ - if (*arglen < pksize) { \ - EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \ - return 0; \ - } \ - } - -int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { - EVPerr(EVP_F_EVP_PKEY_SIGN_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_SIGN; - if (!ctx->pmeth->sign_init) - return 1; - ret = ctx->pmeth->sign_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, - unsigned char *sig, size_t *siglen, - const unsigned char *tbs, size_t tbslen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { - EVPerr(EVP_F_EVP_PKEY_SIGN, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_SIGN) { - EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) - return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); -} - -int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { - EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_VERIFY; - if (!ctx->pmeth->verify_init) - return 1; - ret = ctx->pmeth->verify_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, - const unsigned char *sig, size_t siglen, - const unsigned char *tbs, size_t tbslen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { - EVPerr(EVP_F_EVP_PKEY_VERIFY, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_VERIFY) { - EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); -} - -int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { - EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; - if (!ctx->pmeth->verify_recover_init) - return 1; - ret = ctx->pmeth->verify_recover_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, - unsigned char *rout, size_t *routlen, - const unsigned char *sig, size_t siglen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { - EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { - EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) - return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); -} - -int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { - EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_ENCRYPT; - if (!ctx->pmeth->encrypt_init) - return 1; - ret = ctx->pmeth->encrypt_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { - EVPerr(EVP_F_EVP_PKEY_ENCRYPT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { - EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) - return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); -} - -int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { - EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_DECRYPT; - if (!ctx->pmeth->decrypt_init) - return 1; - ret = ctx->pmeth->decrypt_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { - EVPerr(EVP_F_EVP_PKEY_DECRYPT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_DECRYPT) { - EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) - return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); -} - -int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_DERIVE; - if (!ctx->pmeth->derive_init) - return 1; - ret = ctx->pmeth->derive_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) -{ - int ret; - if (!ctx || !ctx->pmeth - || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) - || !ctx->pmeth->ctrl) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_DERIVE - && ctx->operation != EVP_PKEY_OP_ENCRYPT - && ctx->operation != EVP_PKEY_OP_DECRYPT) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, - EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - - ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); - - if (ret <= 0) - return ret; - - if (ret == 2) - return 1; - - if (!ctx->pkey) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET); - return -1; - } - - if (ctx->pkey->type != peer->type) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES); - return -1; - } - - /* - * For clarity. The error is if parameters in peer are - * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return - * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 - * (different key types) is impossible here because it is checked earlier. - * -2 is OK for us here, as well as 1, so we can check for 0 only. - */ - if (!EVP_PKEY_missing_parameters(peer) && - !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS); - return -1; - } - - EVP_PKEY_free(ctx->peerkey); - ctx->peerkey = peer; - - ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); - - if (ret <= 0) { - ctx->peerkey = NULL; - return ret; - } - - EVP_PKEY_up_ref(peer); - return 1; -} - -int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { - EVPerr(EVP_F_EVP_PKEY_DERIVE, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_DERIVE) { - EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) - return ctx->pmeth->derive(ctx, key, pkeylen); -} diff --git a/crypto/openssl/crypto/evp/pmeth_gn.c b/crypto/openssl/crypto/evp/pmeth_gn.c index 3ad6d5c7c7a0..8e4940ed5956 100644 --- a/crypto/openssl/crypto/evp/pmeth_gn.c +++ b/crypto/openssl/crypto/evp/pmeth_gn.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,108 +9,269 @@ #include #include +#include +#include #include "internal/cryptlib.h" +#include "internal/core.h" #include #include #include "crypto/bn.h" -#include "crypto/asn1.h" +#ifndef FIPS_MODULE +# include "crypto/asn1.h" +#endif #include "crypto/evp.h" +#include "evp_local.h" -int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) +static int gen_init(EVP_PKEY_CTX *ctx, int operation) { - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { - EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; + int ret = 0; + + if (ctx == NULL) + goto not_supported; + + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = operation; + + if (ctx->keymgmt == NULL || ctx->keymgmt->gen_init == NULL) + goto legacy; + + switch (operation) { + case EVP_PKEY_OP_PARAMGEN: + ctx->op.keymgmt.genctx = + evp_keymgmt_gen_init(ctx->keymgmt, + OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, NULL); + break; + case EVP_PKEY_OP_KEYGEN: + ctx->op.keymgmt.genctx = + evp_keymgmt_gen_init(ctx->keymgmt, OSSL_KEYMGMT_SELECT_KEYPAIR, + NULL); + break; + } + + if (ctx->op.keymgmt.genctx == NULL) + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + else + ret = 1; + goto end; + + legacy: +#ifdef FIPS_MODULE + goto not_supported; +#else + if (ctx->pmeth == NULL + || (operation == EVP_PKEY_OP_PARAMGEN + && ctx->pmeth->paramgen == NULL) + || (operation == EVP_PKEY_OP_KEYGEN + && ctx->pmeth->keygen == NULL)) + goto not_supported; + + ret = 1; + switch (operation) { + case EVP_PKEY_OP_PARAMGEN: + if (ctx->pmeth->paramgen_init != NULL) + ret = ctx->pmeth->paramgen_init(ctx); + break; + case EVP_PKEY_OP_KEYGEN: + if (ctx->pmeth->keygen_init != NULL) + ret = ctx->pmeth->keygen_init(ctx); + break; } - ctx->operation = EVP_PKEY_OP_PARAMGEN; - if (!ctx->pmeth->paramgen_init) - return 1; - ret = ctx->pmeth->paramgen_init(ctx); - if (ret <= 0) +#endif + + end: + if (ret <= 0 && ctx != NULL) { + evp_pkey_ctx_free_old_ops(ctx); ctx->operation = EVP_PKEY_OP_UNDEFINED; + } return ret; + + not_supported: + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto end; } -int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) { - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { - EVPerr(EVP_F_EVP_PKEY_PARAMGEN, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } + return gen_init(ctx, EVP_PKEY_OP_PARAMGEN); +} - if (ctx->operation != EVP_PKEY_OP_PARAMGEN) { - EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) +{ + return gen_init(ctx, EVP_PKEY_OP_KEYGEN); +} + +static int ossl_callback_to_pkey_gencb(const OSSL_PARAM params[], void *arg) +{ + EVP_PKEY_CTX *ctx = arg; + const OSSL_PARAM *param = NULL; + int p = -1, n = -1; + + if (ctx->pkey_gencb == NULL) + return 1; /* No callback? That's fine */ + + if ((param = OSSL_PARAM_locate_const(params, OSSL_GEN_PARAM_POTENTIAL)) + == NULL + || !OSSL_PARAM_get_int(param, &p)) + return 0; + if ((param = OSSL_PARAM_locate_const(params, OSSL_GEN_PARAM_ITERATION)) + == NULL + || !OSSL_PARAM_get_int(param, &n)) + return 0; + + ctx->keygen_info[0] = p; + ctx->keygen_info[1] = n; + + return ctx->pkey_gencb(ctx); +} + +int EVP_PKEY_generate(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +{ + int ret = 0; + EVP_PKEY *allocated_pkey = NULL; + /* Legacy compatible keygen callback info, only used with provider impls */ + int gentmp[2]; if (ppkey == NULL) return -1; + if (ctx == NULL) + goto not_supported; + + if ((ctx->operation & EVP_PKEY_OP_TYPE_GEN) == 0) + goto not_initialized; + if (*ppkey == NULL) - *ppkey = EVP_PKEY_new(); + *ppkey = allocated_pkey = EVP_PKEY_new(); if (*ppkey == NULL) { - EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return -1; } - ret = ctx->pmeth->paramgen(ctx, *ppkey); + if (ctx->op.keymgmt.genctx == NULL) + goto legacy; + + /* + * Asssigning gentmp to ctx->keygen_info is something our legacy + * implementations do. Because the provider implementations aren't + * allowed to reach into our EVP_PKEY_CTX, we need to provide similar + * space for backward compatibility. It's ok that we attach a local + * variable, as it should only be useful in the calls down from here. + * This is cleared as soon as it isn't useful any more, i.e. directly + * after the evp_keymgmt_util_gen() call. + */ + ctx->keygen_info = gentmp; + ctx->keygen_info_count = 2; + + ret = 1; + if (ctx->pkey != NULL) { + EVP_KEYMGMT *tmp_keymgmt = ctx->keymgmt; + void *keydata = + evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, + &tmp_keymgmt, ctx->propquery); + + if (tmp_keymgmt == NULL) + goto not_supported; + /* + * It's ok if keydata is NULL here. The backend is expected to deal + * with that as it sees fit. + */ + ret = evp_keymgmt_gen_set_template(ctx->keymgmt, + ctx->op.keymgmt.genctx, keydata); + } + + /* + * the returned value from evp_keymgmt_util_gen() is cached in *ppkey, + * so we do not need to save it, just check it. + */ + ret = ret + && (evp_keymgmt_util_gen(*ppkey, ctx->keymgmt, ctx->op.keymgmt.genctx, + ossl_callback_to_pkey_gencb, ctx) + != NULL); + + ctx->keygen_info = NULL; + +#ifndef FIPS_MODULE + /* In case |*ppkey| was originally a legacy key */ + if (ret) + evp_pkey_free_legacy(*ppkey); +#endif + + /* + * Because we still have legacy keys + */ + (*ppkey)->type = ctx->legacy_keytype; + + goto end; + + legacy: +#ifdef FIPS_MODULE + goto not_supported; +#else + /* + * If we get here then we're using legacy paramgen/keygen. In that case + * the pkey in ctx (if there is one) had better not be provided (because the + * legacy methods may not know how to handle it). However we can only get + * here if ctx->op.keymgmt.genctx == NULL, but that should never be the case + * if ctx->pkey is provided because we don't allow this when we initialise + * the ctx. + */ + if (ctx->pkey != NULL && !ossl_assert(!evp_pkey_is_provided(ctx->pkey))) + goto not_accessible; + + switch (ctx->operation) { + case EVP_PKEY_OP_PARAMGEN: + ret = ctx->pmeth->paramgen(ctx, *ppkey); + break; + case EVP_PKEY_OP_KEYGEN: + ret = ctx->pmeth->keygen(ctx, *ppkey); + break; + default: + goto not_supported; + } +#endif + + end: if (ret <= 0) { - EVP_PKEY_free(*ppkey); - *ppkey = NULL; + if (allocated_pkey != NULL) + *ppkey = NULL; + EVP_PKEY_free(allocated_pkey); } return ret; + + not_supported: + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto end; + not_initialized: + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); + ret = -1; + goto end; +#ifndef FIPS_MODULE + not_accessible: + ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS); + ret = -1; + goto end; +#endif } -int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) { - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { - EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; + if (ctx->operation != EVP_PKEY_OP_PARAMGEN) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); + return -1; } - ctx->operation = EVP_PKEY_OP_KEYGEN; - if (!ctx->pmeth->keygen_init) - return 1; - ret = ctx->pmeth->keygen_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; + return EVP_PKEY_generate(ctx, ppkey); } int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) { - int ret; - - if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { - EVPerr(EVP_F_EVP_PKEY_KEYGEN, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } if (ctx->operation != EVP_PKEY_OP_KEYGEN) { - EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED); + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); return -1; } - - if (ppkey == NULL) - return -1; - - if (*ppkey == NULL) - *ppkey = EVP_PKEY_new(); - if (*ppkey == NULL) - return -1; - - ret = ctx->pmeth->keygen(ctx, *ppkey); - if (ret <= 0) { - EVP_PKEY_free(*ppkey); - *ppkey = NULL; - } - return ret; + return EVP_PKEY_generate(ctx, ppkey); } void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb) @@ -150,6 +311,8 @@ int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx) return ctx->keygen_info[idx]; } +#ifndef FIPS_MODULE + EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen) { @@ -169,71 +332,130 @@ EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, return mac_key; } -int EVP_PKEY_check(EVP_PKEY_CTX *ctx) +#endif /* FIPS_MODULE */ + +/*- All methods below can also be used in FIPS_MODULE */ + +static int fromdata_init(EVP_PKEY_CTX *ctx, int operation) { - EVP_PKEY *pkey = ctx->pkey; + if (ctx == NULL || ctx->keytype == NULL) + goto not_supported; - if (pkey == NULL) { - EVPerr(EVP_F_EVP_PKEY_CHECK, EVP_R_NO_KEY_SET); - return 0; - } + evp_pkey_ctx_free_old_ops(ctx); + if (ctx->keymgmt == NULL) + goto not_supported; - /* call customized check function first */ - if (ctx->pmeth->check != NULL) - return ctx->pmeth->check(pkey); + ctx->operation = operation; + return 1; - /* use default check function in ameth */ - if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL) { - EVPerr(EVP_F_EVP_PKEY_CHECK, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } + not_supported: + if (ctx != NULL) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; +} - return pkey->ameth->pkey_check(pkey); +int EVP_PKEY_fromdata_init(EVP_PKEY_CTX *ctx) +{ + return fromdata_init(ctx, EVP_PKEY_OP_FROMDATA); } -int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx) +int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, int selection, + OSSL_PARAM params[]) { - EVP_PKEY *pkey = ctx->pkey; + void *keydata = NULL; + EVP_PKEY *allocated_pkey = NULL; - if (pkey == NULL) { - EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK, EVP_R_NO_KEY_SET); - return 0; + if (ctx == NULL || (ctx->operation & EVP_PKEY_OP_FROMDATA) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; } - /* call customized public key check function first */ - if (ctx->pmeth->public_check != NULL) - return ctx->pmeth->public_check(pkey); + if (ppkey == NULL) + return -1; - /* use default public key check function in ameth */ - if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL) { - EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; + if (*ppkey == NULL) + allocated_pkey = *ppkey = EVP_PKEY_new(); + + if (*ppkey == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return -1; } - return pkey->ameth->pkey_public_check(pkey); + keydata = evp_keymgmt_util_fromdata(*ppkey, ctx->keymgmt, selection, params); + if (keydata == NULL) { + if (allocated_pkey != NULL) { + *ppkey = NULL; + EVP_PKEY_free(allocated_pkey); + } + return 0; + } + /* keydata is cached in *ppkey, so we need not bother with it further */ + return 1; } -int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx) +const OSSL_PARAM *EVP_PKEY_fromdata_settable(EVP_PKEY_CTX *ctx, int selection) { - EVP_PKEY *pkey = ctx->pkey; + /* We call fromdata_init to get ctx->keymgmt populated */ + if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED) == 1) + return evp_keymgmt_import_types(ctx->keymgmt, selection); + return NULL; +} - if (pkey == NULL) { - EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK, EVP_R_NO_KEY_SET); +static OSSL_CALLBACK ossl_pkey_todata_cb; + +static int ossl_pkey_todata_cb(const OSSL_PARAM params[], void *arg) +{ + OSSL_PARAM **ret = arg; + + *ret = OSSL_PARAM_dup(params); + return 1; +} + +int EVP_PKEY_todata(const EVP_PKEY *pkey, int selection, OSSL_PARAM **params) +{ + if (params == NULL) return 0; - } + return EVP_PKEY_export(pkey, selection, ossl_pkey_todata_cb, params); +} - /* call customized param check function first */ - if (ctx->pmeth->param_check != NULL) - return ctx->pmeth->param_check(pkey); +#ifndef FIPS_MODULE +struct fake_import_data_st { + OSSL_CALLBACK *export_cb; + void *export_cbarg; +}; - /* use default param check function in ameth */ - if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL) { - EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } +static OSSL_FUNC_keymgmt_import_fn pkey_fake_import; +static int pkey_fake_import(void *fake_keydata, int ignored_selection, + const OSSL_PARAM params[]) +{ + struct fake_import_data_st *data = fake_keydata; + + return data->export_cb(params, data->export_cbarg); +} +#endif - return pkey->ameth->pkey_param_check(pkey); +int EVP_PKEY_export(const EVP_PKEY *pkey, int selection, + OSSL_CALLBACK *export_cb, void *export_cbarg) +{ + if (pkey == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } +#ifndef FIPS_MODULE + if (evp_pkey_is_legacy(pkey)) { + struct fake_import_data_st data; + + data.export_cb = export_cb; + data.export_cbarg = export_cbarg; + + /* + * We don't need to care about libctx or propq here, as we're only + * interested in the resulting OSSL_PARAM array. + */ + return pkey->ameth->export_to(pkey, &data, pkey_fake_import, + NULL, NULL); + } +#endif + return evp_keymgmt_util_export(pkey, selection, export_cb, export_cbarg); } diff --git a/crypto/openssl/crypto/evp/pmeth_lib.c b/crypto/openssl/crypto/evp/pmeth_lib.c index 603ccd835219..da367ed05fbe 100644 --- a/crypto/openssl/crypto/evp/pmeth_lib.c +++ b/crypto/openssl/crypto/evp/pmeth_lib.c @@ -1,76 +1,89 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * Low level key APIs (DH etc) are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include -#include "internal/cryptlib.h" -#include +#ifndef FIPS_MODULE +# include +#endif #include -#include -#include "crypto/asn1.h" +#include +#include +#include +#include +#include "internal/cryptlib.h" +#ifndef FIPS_MODULE +# include "crypto/asn1.h" +#endif #include "crypto/evp.h" +#include "crypto/dh.h" +#include "crypto/ec.h" +#include "internal/ffc.h" #include "internal/numbers.h" +#include "internal/provider.h" +#include "evp_local.h" + +#ifndef FIPS_MODULE +static int evp_pkey_ctx_store_cached_data(EVP_PKEY_CTX *ctx, + int keytype, int optype, + int cmd, const char *name, + const void *data, size_t data_len); +static void evp_pkey_ctx_free_cached_data(EVP_PKEY_CTX *ctx, + int cmd, const char *name); +static void evp_pkey_ctx_free_all_cached_data(EVP_PKEY_CTX *ctx); + +typedef const EVP_PKEY_METHOD *(*pmeth_fn)(void); typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); static STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL; /* This array needs to be in order of NIDs */ -static const EVP_PKEY_METHOD *standard_methods[] = { -#ifndef OPENSSL_NO_RSA - &rsa_pkey_meth, -#endif -#ifndef OPENSSL_NO_DH - &dh_pkey_meth, -#endif -#ifndef OPENSSL_NO_DSA - &dsa_pkey_meth, -#endif -#ifndef OPENSSL_NO_EC - &ec_pkey_meth, -#endif - &hmac_pkey_meth, -#ifndef OPENSSL_NO_CMAC - &cmac_pkey_meth, -#endif -#ifndef OPENSSL_NO_RSA - &rsa_pss_pkey_meth, -#endif -#ifndef OPENSSL_NO_DH - &dhx_pkey_meth, -#endif -#ifndef OPENSSL_NO_SCRYPT - &scrypt_pkey_meth, -#endif - &tls1_prf_pkey_meth, -#ifndef OPENSSL_NO_EC - &ecx25519_pkey_meth, - &ecx448_pkey_meth, -#endif - &hkdf_pkey_meth, -#ifndef OPENSSL_NO_POLY1305 - &poly1305_pkey_meth, -#endif -#ifndef OPENSSL_NO_SIPHASH - &siphash_pkey_meth, -#endif -#ifndef OPENSSL_NO_EC - &ed25519_pkey_meth, - &ed448_pkey_meth, -#endif -#ifndef OPENSSL_NO_SM2 - &sm2_pkey_meth, -#endif +static pmeth_fn standard_methods[] = { + ossl_rsa_pkey_method, +# ifndef OPENSSL_NO_DH + ossl_dh_pkey_method, +# endif +# ifndef OPENSSL_NO_DSA + ossl_dsa_pkey_method, +# endif +# ifndef OPENSSL_NO_EC + ossl_ec_pkey_method, +# endif + ossl_rsa_pss_pkey_method, +# ifndef OPENSSL_NO_DH + ossl_dhx_pkey_method, +# endif +# ifndef OPENSSL_NO_EC + ossl_ecx25519_pkey_method, + ossl_ecx448_pkey_method, +# endif +# ifndef OPENSSL_NO_EC + ossl_ed25519_pkey_method, + ossl_ed448_pkey_method, +# endif }; -DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, - pmeth); +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, pmeth_fn, pmeth_func); + +static int pmeth_func_cmp(const EVP_PKEY_METHOD *const *a, pmeth_fn const *b) +{ + return ((*a)->pkey_id - ((**b)())->pkey_id); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, pmeth_fn, pmeth_func); static int pmeth_cmp(const EVP_PKEY_METHOD *const *a, const EVP_PKEY_METHOD *const *b) @@ -78,45 +91,154 @@ static int pmeth_cmp(const EVP_PKEY_METHOD *const *a, return ((*a)->pkey_id - (*b)->pkey_id); } -IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, - pmeth); - -const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type) +static const EVP_PKEY_METHOD *evp_pkey_meth_find_added_by_application(int type) { - EVP_PKEY_METHOD tmp; - const EVP_PKEY_METHOD *t = &tmp, **ret; - tmp.pkey_id = type; - if (app_pkey_methods) { + if (app_pkey_methods != NULL) { int idx; + EVP_PKEY_METHOD tmp; + + tmp.pkey_id = type; idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp); if (idx >= 0) return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx); } - ret = OBJ_bsearch_pmeth(&t, standard_methods, - sizeof(standard_methods) / - sizeof(EVP_PKEY_METHOD *)); - if (!ret || !*ret) + return NULL; +} + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type) +{ + pmeth_fn *ret; + EVP_PKEY_METHOD tmp; + const EVP_PKEY_METHOD *t; + + if ((t = evp_pkey_meth_find_added_by_application(type)) != NULL) + return t; + + tmp.pkey_id = type; + t = &tmp; + ret = OBJ_bsearch_pmeth_func(&t, standard_methods, + OSSL_NELEM(standard_methods)); + if (ret == NULL || *ret == NULL) return NULL; - return *ret; + return (**ret)(); +} + +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) +{ + EVP_PKEY_METHOD *pmeth; + + pmeth = OPENSSL_zalloc(sizeof(*pmeth)); + if (pmeth == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + pmeth->pkey_id = id; + pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; + return pmeth; +} + +static void help_get_legacy_alg_type_from_keymgmt(const char *keytype, + void *arg) +{ + int *type = arg; + + if (*type == NID_undef) + *type = evp_pkey_name2type(keytype); } -static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) +static int get_legacy_alg_type_from_keymgmt(const EVP_KEYMGMT *keymgmt) { - EVP_PKEY_CTX *ret; - const EVP_PKEY_METHOD *pmeth; + int type = NID_undef; + EVP_KEYMGMT_names_do_all(keymgmt, help_get_legacy_alg_type_from_keymgmt, + &type); + return type; +} +#endif /* FIPS_MODULE */ + +int evp_pkey_ctx_state(const EVP_PKEY_CTX *ctx) +{ + if (ctx->operation == EVP_PKEY_OP_UNDEFINED) + return EVP_PKEY_STATE_UNKNOWN; + + if ((EVP_PKEY_CTX_IS_DERIVE_OP(ctx) + && ctx->op.kex.algctx != NULL) + || (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.algctx != NULL) + || (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.algctx != NULL) + || (EVP_PKEY_CTX_IS_GEN_OP(ctx) + && ctx->op.keymgmt.genctx != NULL) + || (EVP_PKEY_CTX_IS_KEM_OP(ctx) + && ctx->op.encap.algctx != NULL)) + return EVP_PKEY_STATE_PROVIDER; + + return EVP_PKEY_STATE_LEGACY; +} + +static EVP_PKEY_CTX *int_ctx_new(OSSL_LIB_CTX *libctx, + EVP_PKEY *pkey, ENGINE *e, + const char *keytype, const char *propquery, + int id) + +{ + EVP_PKEY_CTX *ret = NULL; + const EVP_PKEY_METHOD *pmeth = NULL, *app_pmeth = NULL; + EVP_KEYMGMT *keymgmt = NULL; + + /* Code below to be removed when legacy support is dropped. */ + /* BEGIN legacy */ if (id == -1) { - if (pkey == NULL) - return 0; - id = pkey->type; + if (pkey != NULL && !evp_pkey_is_provided(pkey)) { + id = pkey->type; + } else { + if (pkey != NULL) { + /* Must be provided if we get here */ + keytype = EVP_KEYMGMT_get0_name(pkey->keymgmt); + } +#ifndef FIPS_MODULE + if (keytype != NULL) { + id = evp_pkey_name2type(keytype); + if (id == NID_undef) + id = -1; + } +#endif + } } -#ifndef OPENSSL_NO_ENGINE + /* If no ID was found here, we can only resort to find a keymgmt */ + if (id == -1) { +#ifndef FIPS_MODULE + /* Using engine with a key without id will not work */ + if (e != NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return NULL; + } +#endif + goto common; + } + +#ifndef FIPS_MODULE + /* + * Here, we extract what information we can for the purpose of + * supporting usage with implementations from providers, to make + * for a smooth transition from legacy stuff to provider based stuff. + * + * If an engine is given, this is entirely legacy, and we should not + * pretend anything else, so we clear the name. + */ + if (e != NULL) + keytype = NULL; + if (e == NULL && (pkey == NULL || pkey->foreign == 0)) + keytype = OBJ_nid2sn(id); + +# ifndef OPENSSL_NO_ENGINE if (e == NULL && pkey != NULL) e = pkey->pmeth_engine != NULL ? pkey->pmeth_engine : pkey->engine; /* Try to find an ENGINE which implements this method */ - if (e) { + if (e != NULL) { if (!ENGINE_init(e)) { - EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_EVP, ERR_R_ENGINE_LIB); return NULL; } } else { @@ -127,28 +249,98 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) * If an ENGINE handled this method look it up. Otherwise use internal * tables. */ - if (e) + if (e != NULL) pmeth = ENGINE_get_pkey_meth(e, id); - else -#endif + else if (pkey != NULL && pkey->foreign) pmeth = EVP_PKEY_meth_find(id); + else +# endif + app_pmeth = pmeth = evp_pkey_meth_find_added_by_application(id); - if (pmeth == NULL) { -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(e); + /* END legacy */ +#endif /* FIPS_MODULE */ + common: + /* + * If there's no engine and no app supplied pmeth and there's a name, we try + * fetching a provider implementation. + */ + if (e == NULL && app_pmeth == NULL && keytype != NULL) { + /* + * If |pkey| is given and is provided, we take a reference to its + * keymgmt. Otherwise, we fetch one for the keytype we got. This + * is to ensure that operation init functions can access what they + * need through this single pointer. + */ + if (pkey != NULL && pkey->keymgmt != NULL) { + if (!EVP_KEYMGMT_up_ref(pkey->keymgmt)) + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + else + keymgmt = pkey->keymgmt; + } else { + keymgmt = EVP_KEYMGMT_fetch(libctx, keytype, propquery); + } + if (keymgmt == NULL) + return NULL; /* EVP_KEYMGMT_fetch() recorded an error */ + +#ifndef FIPS_MODULE + /* + * Chase down the legacy NID, as that might be needed for diverse + * purposes, such as ensure that EVP_PKEY_type() can return sensible + * values. We go through all keymgmt names, because the keytype + * that's passed to this function doesn't necessarily translate + * directly. + */ + if (keymgmt != NULL) { + int tmp_id = get_legacy_alg_type_from_keymgmt(keymgmt); + + if (tmp_id != NID_undef) { + if (id == -1) { + id = tmp_id; + } else { + /* + * It really really shouldn't differ. If it still does, + * something is very wrong. + */ + if (!ossl_assert(id == tmp_id)) { + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + EVP_KEYMGMT_free(keymgmt); + return NULL; + } + } + } + } #endif - EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM); - return NULL; } - ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { -#ifndef OPENSSL_NO_ENGINE + if (pmeth == NULL && keymgmt == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM); + } else { + ret = OPENSSL_zalloc(sizeof(*ret)); + if (ret == NULL) + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + } + +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + if ((ret == NULL || pmeth == NULL) && e != NULL) ENGINE_finish(e); #endif - EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE); + + if (ret == NULL) { + EVP_KEYMGMT_free(keymgmt); return NULL; } + if (propquery != NULL) { + ret->propquery = OPENSSL_strdup(propquery); + if (ret->propquery == NULL) { + OPENSSL_free(ret); + EVP_KEYMGMT_free(keymgmt); + return NULL; + } + } + ret->libctx = libctx; + ret->keytype = keytype; + ret->keymgmt = keymgmt; + ret->legacy_keytype = id; ret->engine = e; ret->pmeth = pmeth; ret->operation = EVP_PKEY_OP_UNDEFINED; @@ -156,7 +348,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) if (pkey != NULL) EVP_PKEY_up_ref(pkey); - if (pmeth->init) { + if (pmeth != NULL && pmeth->init != NULL) { if (pmeth->init(ret) <= 0) { ret->pmeth = NULL; EVP_PKEY_CTX_free(ret); @@ -167,21 +359,79 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) return ret; } -EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) +/*- All methods below can also be used in FIPS_MODULE */ + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OSSL_LIB_CTX *libctx, + const char *name, + const char *propquery) { - EVP_PKEY_METHOD *pmeth; + return int_ctx_new(libctx, NULL, NULL, name, propquery, -1); +} - pmeth = OPENSSL_zalloc(sizeof(*pmeth)); - if (pmeth == NULL) { - EVPerr(EVP_F_EVP_PKEY_METH_NEW, ERR_R_MALLOC_FAILURE); - return NULL; +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX *libctx, EVP_PKEY *pkey, + const char *propquery) +{ + return int_ctx_new(libctx, pkey, NULL, NULL, propquery, -1); +} + +void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx) +{ + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { + if (ctx->op.sig.algctx != NULL && ctx->op.sig.signature != NULL) + ctx->op.sig.signature->freectx(ctx->op.sig.algctx); + EVP_SIGNATURE_free(ctx->op.sig.signature); + ctx->op.sig.algctx = NULL; + ctx->op.sig.signature = NULL; + } else if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + if (ctx->op.kex.algctx != NULL && ctx->op.kex.exchange != NULL) + ctx->op.kex.exchange->freectx(ctx->op.kex.algctx); + EVP_KEYEXCH_free(ctx->op.kex.exchange); + ctx->op.kex.algctx = NULL; + ctx->op.kex.exchange = NULL; + } else if (EVP_PKEY_CTX_IS_KEM_OP(ctx)) { + if (ctx->op.encap.algctx != NULL && ctx->op.encap.kem != NULL) + ctx->op.encap.kem->freectx(ctx->op.encap.algctx); + EVP_KEM_free(ctx->op.encap.kem); + ctx->op.encap.algctx = NULL; + ctx->op.encap.kem = NULL; + } + else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + if (ctx->op.ciph.algctx != NULL && ctx->op.ciph.cipher != NULL) + ctx->op.ciph.cipher->freectx(ctx->op.ciph.algctx); + EVP_ASYM_CIPHER_free(ctx->op.ciph.cipher); + ctx->op.ciph.algctx = NULL; + ctx->op.ciph.cipher = NULL; + } else if (EVP_PKEY_CTX_IS_GEN_OP(ctx)) { + if (ctx->op.keymgmt.genctx != NULL && ctx->keymgmt != NULL) + evp_keymgmt_gen_cleanup(ctx->keymgmt, ctx->op.keymgmt.genctx); } +} - pmeth->pkey_id = id; - pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; - return pmeth; +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) +{ + if (ctx == NULL) + return; + if (ctx->pmeth && ctx->pmeth->cleanup) + ctx->pmeth->cleanup(ctx); + + evp_pkey_ctx_free_old_ops(ctx); +#ifndef FIPS_MODULE + evp_pkey_ctx_free_all_cached_data(ctx); +#endif + EVP_KEYMGMT_free(ctx->keymgmt); + + OPENSSL_free(ctx->propquery); + EVP_PKEY_free(ctx->pkey); + EVP_PKEY_free(ctx->peerkey); +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + ENGINE_finish(ctx->engine); +#endif + BN_free(ctx->rsa_pubexp); + OPENSSL_free(ctx); } +#ifndef FIPS_MODULE + void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, const EVP_PKEY_METHOD *meth) { @@ -193,45 +443,14 @@ void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src) { + int pkey_id = dst->pkey_id; + int flags = dst->flags; - dst->init = src->init; - dst->copy = src->copy; - dst->cleanup = src->cleanup; - - dst->paramgen_init = src->paramgen_init; - dst->paramgen = src->paramgen; + *dst = *src; - dst->keygen_init = src->keygen_init; - dst->keygen = src->keygen; - - dst->sign_init = src->sign_init; - dst->sign = src->sign; - - dst->verify_init = src->verify_init; - dst->verify = src->verify; - - dst->verify_recover_init = src->verify_recover_init; - dst->verify_recover = src->verify_recover; - - dst->signctx_init = src->signctx_init; - dst->signctx = src->signctx; - - dst->verifyctx_init = src->verifyctx_init; - dst->verifyctx = src->verifyctx; - - dst->encrypt_init = src->encrypt_init; - dst->encrypt = src->encrypt; - - dst->decrypt_init = src->decrypt_init; - dst->decrypt = src->decrypt; - - dst->derive_init = src->derive_init; - dst->derive = src->derive; - - dst->ctrl = src->ctrl; - dst->ctrl_str = src->ctrl_str; - - dst->check = src->check; + /* We only copy the function pointers so restore the other values */ + dst->pkey_id = pkey_id; + dst->flags = flags; } void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) @@ -242,58 +461,153 @@ void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { - return int_ctx_new(pkey, e, -1); + return int_ctx_new(NULL, pkey, e, NULL, NULL, -1); } EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { - return int_ctx_new(NULL, e, id); + return int_ctx_new(NULL, NULL, e, NULL, NULL, id); } -EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) { EVP_PKEY_CTX *rctx; - if (!pctx->pmeth || !pctx->pmeth->copy) - return NULL; -#ifndef OPENSSL_NO_ENGINE + +# ifndef OPENSSL_NO_ENGINE /* Make sure it's safe to copy a pkey context using an ENGINE */ if (pctx->engine && !ENGINE_init(pctx->engine)) { - EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_EVP, ERR_R_ENGINE_LIB); return 0; } -#endif - rctx = OPENSSL_malloc(sizeof(*rctx)); +# endif + rctx = OPENSSL_zalloc(sizeof(*rctx)); if (rctx == NULL) { - EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return NULL; } - rctx->pmeth = pctx->pmeth; -#ifndef OPENSSL_NO_ENGINE - rctx->engine = pctx->engine; -#endif - - if (pctx->pkey) + if (pctx->pkey != NULL) EVP_PKEY_up_ref(pctx->pkey); - rctx->pkey = pctx->pkey; + rctx->operation = pctx->operation; + rctx->libctx = pctx->libctx; + rctx->keytype = pctx->keytype; + rctx->propquery = NULL; + if (pctx->propquery != NULL) { + rctx->propquery = OPENSSL_strdup(pctx->propquery); + if (rctx->propquery == NULL) + goto err; + } + rctx->legacy_keytype = pctx->legacy_keytype; - if (pctx->peerkey) - EVP_PKEY_up_ref(pctx->peerkey); + if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) { + if (pctx->op.kex.exchange != NULL) { + rctx->op.kex.exchange = pctx->op.kex.exchange; + if (!EVP_KEYEXCH_up_ref(rctx->op.kex.exchange)) + goto err; + } + if (pctx->op.kex.algctx != NULL) { + if (!ossl_assert(pctx->op.kex.exchange != NULL)) + goto err; + rctx->op.kex.algctx + = pctx->op.kex.exchange->dupctx(pctx->op.kex.algctx); + if (rctx->op.kex.algctx == NULL) { + EVP_KEYEXCH_free(rctx->op.kex.exchange); + rctx->op.kex.exchange = NULL; + goto err; + } + return rctx; + } + } else if (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)) { + if (pctx->op.sig.signature != NULL) { + rctx->op.sig.signature = pctx->op.sig.signature; + if (!EVP_SIGNATURE_up_ref(rctx->op.sig.signature)) + goto err; + } + if (pctx->op.sig.algctx != NULL) { + if (!ossl_assert(pctx->op.sig.signature != NULL)) + goto err; + rctx->op.sig.algctx + = pctx->op.sig.signature->dupctx(pctx->op.sig.algctx); + if (rctx->op.sig.algctx == NULL) { + EVP_SIGNATURE_free(rctx->op.sig.signature); + rctx->op.sig.signature = NULL; + goto err; + } + return rctx; + } + } else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(pctx)) { + if (pctx->op.ciph.cipher != NULL) { + rctx->op.ciph.cipher = pctx->op.ciph.cipher; + if (!EVP_ASYM_CIPHER_up_ref(rctx->op.ciph.cipher)) + goto err; + } + if (pctx->op.ciph.algctx != NULL) { + if (!ossl_assert(pctx->op.ciph.cipher != NULL)) + goto err; + rctx->op.ciph.algctx + = pctx->op.ciph.cipher->dupctx(pctx->op.ciph.algctx); + if (rctx->op.ciph.algctx == NULL) { + EVP_ASYM_CIPHER_free(rctx->op.ciph.cipher); + rctx->op.ciph.cipher = NULL; + goto err; + } + return rctx; + } + } else if (EVP_PKEY_CTX_IS_KEM_OP(pctx)) { + if (pctx->op.encap.kem != NULL) { + rctx->op.encap.kem = pctx->op.encap.kem; + if (!EVP_KEM_up_ref(rctx->op.encap.kem)) + goto err; + } + if (pctx->op.encap.algctx != NULL) { + if (!ossl_assert(pctx->op.encap.kem != NULL)) + goto err; + rctx->op.encap.algctx + = pctx->op.encap.kem->dupctx(pctx->op.encap.algctx); + if (rctx->op.encap.algctx == NULL) { + EVP_KEM_free(rctx->op.encap.kem); + rctx->op.encap.kem = NULL; + goto err; + } + return rctx; + } + } else if (EVP_PKEY_CTX_IS_GEN_OP(pctx)) { + /* Not supported - This would need a gen_dupctx() to work */ + goto err; + } - rctx->peerkey = pctx->peerkey; + rctx->pmeth = pctx->pmeth; +# ifndef OPENSSL_NO_ENGINE + rctx->engine = pctx->engine; +# endif - rctx->data = NULL; - rctx->app_data = NULL; - rctx->operation = pctx->operation; + if (pctx->peerkey != NULL) + EVP_PKEY_up_ref(pctx->peerkey); + rctx->peerkey = pctx->peerkey; - if (pctx->pmeth->copy(rctx, pctx) > 0) + if (pctx->pmeth == NULL) { + if (rctx->operation == EVP_PKEY_OP_UNDEFINED) { + EVP_KEYMGMT *tmp_keymgmt = pctx->keymgmt; + void *provkey; + + provkey = evp_pkey_export_to_provider(pctx->pkey, pctx->libctx, + &tmp_keymgmt, pctx->propquery); + if (provkey == NULL) + goto err; + if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) + goto err; + EVP_KEYMGMT_free(rctx->keymgmt); + rctx->keymgmt = tmp_keymgmt; + return rctx; + } + } else if (pctx->pmeth->copy(rctx, pctx) > 0) { return rctx; - + } +err: rctx->pmeth = NULL; EVP_PKEY_CTX_free(rctx); return NULL; - } int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) @@ -301,12 +615,12 @@ int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) if (app_pkey_methods == NULL) { app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp); if (app_pkey_methods == NULL){ - EVPerr(EVP_F_EVP_PKEY_METH_ADD0, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } } if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth)) { - EVPerr(EVP_F_EVP_PKEY_METH_ADD0, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } sk_EVP_PKEY_METHOD_sort(app_pkey_methods); @@ -340,7 +654,7 @@ size_t EVP_PKEY_meth_get_count(void) const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx) { if (idx < OSSL_NELEM(standard_methods)) - return standard_methods[idx]; + return (standard_methods[idx])(); if (app_pkey_methods == NULL) return NULL; idx -= OSSL_NELEM(standard_methods); @@ -348,73 +662,917 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx) return NULL; return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx); } +#endif -void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) +int EVP_PKEY_CTX_is_a(EVP_PKEY_CTX *ctx, const char *keytype) { - if (ctx == NULL) - return; - if (ctx->pmeth && ctx->pmeth->cleanup) - ctx->pmeth->cleanup(ctx); - EVP_PKEY_free(ctx->pkey); - EVP_PKEY_free(ctx->peerkey); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(ctx->engine); +#ifndef FIPS_MODULE + if (evp_pkey_ctx_is_legacy(ctx)) + return (ctx->pmeth->pkey_id == evp_pkey_name2type(keytype)); #endif - OPENSSL_free(ctx); + return EVP_KEYMGMT_is_a(ctx->keymgmt, keytype); +} + +int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, const OSSL_PARAM *params) +{ + switch (evp_pkey_ctx_state(ctx)) { + case EVP_PKEY_STATE_PROVIDER: + if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) + && ctx->op.kex.exchange != NULL + && ctx->op.kex.exchange->set_ctx_params != NULL) + return + ctx->op.kex.exchange->set_ctx_params(ctx->op.kex.algctx, + params); + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.signature != NULL + && ctx->op.sig.signature->set_ctx_params != NULL) + return + ctx->op.sig.signature->set_ctx_params(ctx->op.sig.algctx, + params); + if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.cipher != NULL + && ctx->op.ciph.cipher->set_ctx_params != NULL) + return + ctx->op.ciph.cipher->set_ctx_params(ctx->op.ciph.algctx, + params); + if (EVP_PKEY_CTX_IS_GEN_OP(ctx) + && ctx->keymgmt != NULL + && ctx->keymgmt->gen_set_params != NULL) + return + evp_keymgmt_gen_set_params(ctx->keymgmt, ctx->op.keymgmt.genctx, + params); + if (EVP_PKEY_CTX_IS_KEM_OP(ctx) + && ctx->op.encap.kem != NULL + && ctx->op.encap.kem->set_ctx_params != NULL) + return + ctx->op.encap.kem->set_ctx_params(ctx->op.encap.algctx, + params); + break; +#ifndef FIPS_MODULE + case EVP_PKEY_STATE_UNKNOWN: + case EVP_PKEY_STATE_LEGACY: + return evp_pkey_ctx_set_params_to_ctrl(ctx, params); +#endif + } + return 0; +} + +int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) +{ + switch (evp_pkey_ctx_state(ctx)) { + case EVP_PKEY_STATE_PROVIDER: + if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) + && ctx->op.kex.exchange != NULL + && ctx->op.kex.exchange->get_ctx_params != NULL) + return + ctx->op.kex.exchange->get_ctx_params(ctx->op.kex.algctx, + params); + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.signature != NULL + && ctx->op.sig.signature->get_ctx_params != NULL) + return + ctx->op.sig.signature->get_ctx_params(ctx->op.sig.algctx, + params); + if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.cipher != NULL + && ctx->op.ciph.cipher->get_ctx_params != NULL) + return + ctx->op.ciph.cipher->get_ctx_params(ctx->op.ciph.algctx, + params); + if (EVP_PKEY_CTX_IS_KEM_OP(ctx) + && ctx->op.encap.kem != NULL + && ctx->op.encap.kem->get_ctx_params != NULL) + return + ctx->op.encap.kem->get_ctx_params(ctx->op.encap.algctx, + params); + break; +#ifndef FIPS_MODULE + case EVP_PKEY_STATE_UNKNOWN: + case EVP_PKEY_STATE_LEGACY: + return evp_pkey_ctx_get_params_to_ctrl(ctx, params); +#endif + } + return 0; } -int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, - int cmd, int p1, void *p2) +#ifndef FIPS_MODULE +const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(const EVP_PKEY_CTX *ctx) { - int ret; + void *provctx; + + if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) + && ctx->op.kex.exchange != NULL + && ctx->op.kex.exchange->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_KEYEXCH_get0_provider(ctx->op.kex.exchange)); + return ctx->op.kex.exchange->gettable_ctx_params(ctx->op.kex.algctx, + provctx); + } + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.signature != NULL + && ctx->op.sig.signature->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx( + EVP_SIGNATURE_get0_provider(ctx->op.sig.signature)); + return ctx->op.sig.signature->gettable_ctx_params(ctx->op.sig.algctx, + provctx); + } + if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.cipher != NULL + && ctx->op.ciph.cipher->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx( + EVP_ASYM_CIPHER_get0_provider(ctx->op.ciph.cipher)); + return ctx->op.ciph.cipher->gettable_ctx_params(ctx->op.ciph.algctx, + provctx); + } + if (EVP_PKEY_CTX_IS_KEM_OP(ctx) + && ctx->op.encap.kem != NULL + && ctx->op.encap.kem->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_KEM_get0_provider(ctx->op.encap.kem)); + return ctx->op.encap.kem->gettable_ctx_params(ctx->op.encap.algctx, + provctx); + } + return NULL; +} + +const OSSL_PARAM *EVP_PKEY_CTX_settable_params(const EVP_PKEY_CTX *ctx) +{ + void *provctx; + + if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) + && ctx->op.kex.exchange != NULL + && ctx->op.kex.exchange->settable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_KEYEXCH_get0_provider(ctx->op.kex.exchange)); + return ctx->op.kex.exchange->settable_ctx_params(ctx->op.kex.algctx, + provctx); + } + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.signature != NULL + && ctx->op.sig.signature->settable_ctx_params != NULL) { + provctx = ossl_provider_ctx( + EVP_SIGNATURE_get0_provider(ctx->op.sig.signature)); + return ctx->op.sig.signature->settable_ctx_params(ctx->op.sig.algctx, + provctx); + } + if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.cipher != NULL + && ctx->op.ciph.cipher->settable_ctx_params != NULL) { + provctx = ossl_provider_ctx( + EVP_ASYM_CIPHER_get0_provider(ctx->op.ciph.cipher)); + return ctx->op.ciph.cipher->settable_ctx_params(ctx->op.ciph.algctx, + provctx); + } + if (EVP_PKEY_CTX_IS_GEN_OP(ctx) + && ctx->keymgmt != NULL + && ctx->keymgmt->gen_settable_params != NULL) { + provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(ctx->keymgmt)); + return ctx->keymgmt->gen_settable_params(ctx->op.keymgmt.genctx, + provctx); + } + if (EVP_PKEY_CTX_IS_KEM_OP(ctx) + && ctx->op.encap.kem != NULL + && ctx->op.encap.kem->settable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_KEM_get0_provider(ctx->op.encap.kem)); + return ctx->op.encap.kem->settable_ctx_params(ctx->op.encap.algctx, + provctx); + } + return NULL; +} + +/* + * Internal helpers for stricter EVP_PKEY_CTX_{set,get}_params(). + * + * Return 1 on success, 0 or negative for errors. + * + * In particular they return -2 if any of the params is not supported. + * + * They are not available in FIPS_MODULE as they depend on + * - EVP_PKEY_CTX_{get,set}_params() + * - EVP_PKEY_CTX_{gettable,settable}_params() + * + */ +int evp_pkey_ctx_set_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) +{ + if (ctx == NULL || params == NULL) + return 0; + + /* + * We only check for provider side EVP_PKEY_CTX. For #legacy, we + * depend on the translation that happens in EVP_PKEY_CTX_set_params() + * call, and that the resulting ctrl call will return -2 if it doesn't + * known the ctrl command number. + */ + if (evp_pkey_ctx_is_provided(ctx)) { + const OSSL_PARAM *settable = EVP_PKEY_CTX_settable_params(ctx); + const OSSL_PARAM *p; + + for (p = params; p->key != NULL; p++) { + /* Check the ctx actually understands this parameter */ + if (OSSL_PARAM_locate_const(settable, p->key) == NULL ) + return -2; + } + } + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int evp_pkey_ctx_get_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) +{ + if (ctx == NULL || params == NULL) + return 0; + + /* + * We only check for provider side EVP_PKEY_CTX. For #legacy, we + * depend on the translation that happens in EVP_PKEY_CTX_get_params() + * call, and that the resulting ctrl call will return -2 if it doesn't + * known the ctrl command number. + */ + if (evp_pkey_ctx_is_provided(ctx)) { + const OSSL_PARAM *gettable = EVP_PKEY_CTX_gettable_params(ctx); + const OSSL_PARAM *p; + + for (p = params; p->key != NULL; p++ ) { + /* Check the ctx actually understands this parameter */ + if (OSSL_PARAM_locate_const(gettable, p->key) == NULL ) + return -2; + } + } + + return EVP_PKEY_CTX_get_params(ctx, params); +} - if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); +int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) +{ + OSSL_PARAM sig_md_params[2], *p = sig_md_params; + /* 80 should be big enough */ + char name[80] = ""; + const EVP_MD *tmp; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ return -2; } - if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) - return -1; - /* Skip the operation checks since this is called in a very early stage */ - if (ctx->pmeth->digest_custom != NULL) - goto doit; + if (ctx->op.sig.algctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_GET_MD, 0, (void *)(md)); - if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET); - return -1; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, + name, + sizeof(name)); + *p = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_get_params(ctx, sig_md_params)) + return 0; + + tmp = evp_get_digestbyname_ex(ctx->libctx, name); + if (tmp == NULL) + return 0; + + *md = tmp; + + return 1; +} + +static int evp_pkey_ctx_set_md(EVP_PKEY_CTX *ctx, const EVP_MD *md, + int fallback, const char *param, int op, + int ctrl) +{ + OSSL_PARAM md_params[2], *p = md_params; + const char *name; + + if (ctx == NULL || (ctx->operation & op) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; } - if ((optype != -1) && !(ctx->operation & optype)) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION); - return -1; + if (fallback) + return EVP_PKEY_CTX_ctrl(ctx, -1, op, ctrl, 0, (void *)(md)); + + if (md == NULL) { + name = ""; + } else { + name = EVP_MD_get0_name(md); + } + + *p++ = OSSL_PARAM_construct_utf8_string(param, + /* + * Cast away the const. This is read + * only so should be safe + */ + (char *)name, 0); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, md_params); +} + +int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return evp_pkey_ctx_set_md(ctx, md, ctx->op.sig.algctx == NULL, + OSSL_SIGNATURE_PARAM_DIGEST, + EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD); +} + +int EVP_PKEY_CTX_set_tls1_prf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return evp_pkey_ctx_set_md(ctx, md, ctx->op.kex.algctx == NULL, + OSSL_KDF_PARAM_DIGEST, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_TLS_MD); +} + +static int evp_pkey_ctx_set1_octet_string(EVP_PKEY_CTX *ctx, int fallback, + const char *param, int op, int ctrl, + const unsigned char *data, + int datalen) +{ + OSSL_PARAM octet_string_params[2], *p = octet_string_params; + + if (ctx == NULL || (ctx->operation & op) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* Code below to be removed when legacy support is dropped. */ + if (fallback) + return EVP_PKEY_CTX_ctrl(ctx, -1, op, ctrl, datalen, (void *)(data)); + /* end of legacy support */ + + if (datalen < 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH); + return 0; } - doit: - ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); + *p++ = OSSL_PARAM_construct_octet_string(param, + /* + * Cast away the const. This is read + * only so should be safe + */ + (unsigned char *)data, + (size_t)datalen); + *p = OSSL_PARAM_construct_end(); + return EVP_PKEY_CTX_set_params(ctx, octet_string_params); +} + +int EVP_PKEY_CTX_set1_tls1_prf_secret(EVP_PKEY_CTX *ctx, + const unsigned char *sec, int seclen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.algctx == NULL, + OSSL_KDF_PARAM_SECRET, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_TLS_SECRET, + sec, seclen); +} + +int EVP_PKEY_CTX_add1_tls1_prf_seed(EVP_PKEY_CTX *ctx, + const unsigned char *seed, int seedlen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.algctx == NULL, + OSSL_KDF_PARAM_SEED, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_TLS_SEED, + seed, seedlen); +} + +int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return evp_pkey_ctx_set_md(ctx, md, ctx->op.kex.algctx == NULL, + OSSL_KDF_PARAM_DIGEST, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_HKDF_MD); +} + +int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, + const unsigned char *salt, int saltlen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.algctx == NULL, + OSSL_KDF_PARAM_SALT, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_SALT, + salt, saltlen); +} + +int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, + const unsigned char *key, int keylen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.algctx == NULL, + OSSL_KDF_PARAM_KEY, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_KEY, + key, keylen); +} + +int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, + const unsigned char *info, int infolen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.algctx == NULL, + OSSL_KDF_PARAM_INFO, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_INFO, + info, infolen); +} + +int EVP_PKEY_CTX_set_hkdf_mode(EVP_PKEY_CTX *ctx, int mode) +{ + OSSL_PARAM int_params[2], *p = int_params; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* Code below to be removed when legacy support is dropped. */ + if (ctx->op.kex.algctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_MODE, mode, NULL); + /* end of legacy support */ + + if (mode < 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } + + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, int_params); +} + +int EVP_PKEY_CTX_set1_pbe_pass(EVP_PKEY_CTX *ctx, const char *pass, + int passlen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.algctx == NULL, + OSSL_KDF_PARAM_PASSWORD, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_PASS, + (const unsigned char *)pass, passlen); +} + +int EVP_PKEY_CTX_set1_scrypt_salt(EVP_PKEY_CTX *ctx, + const unsigned char *salt, int saltlen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.algctx == NULL, + OSSL_KDF_PARAM_SALT, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_SCRYPT_SALT, + salt, saltlen); +} + +static int evp_pkey_ctx_set_uint64(EVP_PKEY_CTX *ctx, const char *param, + int op, int ctrl, uint64_t val) +{ + OSSL_PARAM uint64_params[2], *p = uint64_params; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* Code below to be removed when legacy support is dropped. */ + if (ctx->op.kex.algctx == NULL) + return EVP_PKEY_CTX_ctrl_uint64(ctx, -1, op, ctrl, val); + /* end of legacy support */ + + *p++ = OSSL_PARAM_construct_uint64(param, &val); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, uint64_params); +} + +int EVP_PKEY_CTX_set_scrypt_N(EVP_PKEY_CTX *ctx, uint64_t n) +{ + return evp_pkey_ctx_set_uint64(ctx, OSSL_KDF_PARAM_SCRYPT_N, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_SCRYPT_N, + n); +} + +int EVP_PKEY_CTX_set_scrypt_r(EVP_PKEY_CTX *ctx, uint64_t r) +{ + return evp_pkey_ctx_set_uint64(ctx, OSSL_KDF_PARAM_SCRYPT_R, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_SCRYPT_R, + r); +} + +int EVP_PKEY_CTX_set_scrypt_p(EVP_PKEY_CTX *ctx, uint64_t p) +{ + return evp_pkey_ctx_set_uint64(ctx, OSSL_KDF_PARAM_SCRYPT_P, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_SCRYPT_P, + p); +} + +int EVP_PKEY_CTX_set_scrypt_maxmem_bytes(EVP_PKEY_CTX *ctx, + uint64_t maxmem_bytes) +{ + return evp_pkey_ctx_set_uint64(ctx, OSSL_KDF_PARAM_SCRYPT_MAXMEM, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, + maxmem_bytes); +} + +int EVP_PKEY_CTX_set_mac_key(EVP_PKEY_CTX *ctx, const unsigned char *key, + int keylen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.keymgmt.genctx == NULL, + OSSL_PKEY_PARAM_PRIV_KEY, + EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_SET_MAC_KEY, + key, keylen); +} + +int EVP_PKEY_CTX_set_kem_op(EVP_PKEY_CTX *ctx, const char *op) +{ + OSSL_PARAM params[2], *p = params; + + if (ctx == NULL || op == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } + if (!EVP_PKEY_CTX_IS_KEM_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION, + (char *)op, 0); + *p = OSSL_PARAM_construct_end(); + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int evp_pkey_ctx_set1_id_prov(EVP_PKEY_CTX *ctx, const void *id, int len) +{ + OSSL_PARAM params[2], *p = params; + int ret; + + if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DIST_ID, + /* + * Cast away the const. This is + * read only so should be safe + */ + (void *)id, (size_t)len); + *p++ = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); if (ret == -2) - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return ret; +} + +int EVP_PKEY_CTX_set1_id(EVP_PKEY_CTX *ctx, const void *id, int len) +{ + return EVP_PKEY_CTX_ctrl(ctx, -1, -1, + EVP_PKEY_CTRL_SET1_ID, (int)len, (void*)(id)); +} + +static int get1_id_data(EVP_PKEY_CTX *ctx, void *id, size_t *id_len) +{ + int ret; + void *tmp_id = NULL; + OSSL_PARAM params[2], *p = params; + + if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_PKEY_PARAM_DIST_ID, + &tmp_id, 0); + *p++ = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_get_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + } else if (ret > 0) { + size_t tmp_id_len = params[0].return_size; + + if (id != NULL) + memcpy(id, tmp_id, tmp_id_len); + if (id_len != NULL) + *id_len = tmp_id_len; + } + return ret; +} + +int evp_pkey_ctx_get1_id_prov(EVP_PKEY_CTX *ctx, void *id) +{ + return get1_id_data(ctx, id, NULL); +} + +int evp_pkey_ctx_get1_id_len_prov(EVP_PKEY_CTX *ctx, size_t *id_len) +{ + return get1_id_data(ctx, NULL, id_len); +} + +int EVP_PKEY_CTX_get1_id(EVP_PKEY_CTX *ctx, void *id) +{ + return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_GET1_ID, 0, (void*)id); +} + +int EVP_PKEY_CTX_get1_id_len(EVP_PKEY_CTX *ctx, size_t *id_len) +{ + return EVP_PKEY_CTX_ctrl(ctx, -1, -1, + EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)id_len); +} + +static int evp_pkey_ctx_ctrl_int(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2) +{ + int ret = 0; + + /* + * If the method has a |digest_custom| function, we can relax the + * operation type check, since this can be called before the operation + * is initialized. + */ + if (ctx->pmeth == NULL || ctx->pmeth->digest_custom == NULL) { + if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { + ERR_raise(ERR_LIB_EVP, EVP_R_NO_OPERATION_SET); + return -1; + } + + if ((optype != -1) && !(ctx->operation & optype)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); + return -1; + } + } + switch (evp_pkey_ctx_state(ctx)) { + case EVP_PKEY_STATE_PROVIDER: + return evp_pkey_ctx_ctrl_to_param(ctx, keytype, optype, cmd, p1, p2); + case EVP_PKEY_STATE_UNKNOWN: + case EVP_PKEY_STATE_LEGACY: + if (ctx->pmeth == NULL || ctx->pmeth->ctrl == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) + return -1; + + ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); + + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + break; + } return ret; } +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2) +{ + int ret = 0; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + /* If unsupported, we don't want that reported here */ + ERR_set_mark(); + ret = evp_pkey_ctx_store_cached_data(ctx, keytype, optype, + cmd, NULL, p2, p1); + if (ret == -2) { + ERR_pop_to_mark(); + } else { + ERR_clear_last_mark(); + /* + * If there was an error, there was an error. + * If the operation isn't initialized yet, we also return, as + * the saved values will be used then anyway. + */ + if (ret < 1 || ctx->operation == EVP_PKEY_OP_UNDEFINED) + return ret; + } + return evp_pkey_ctx_ctrl_int(ctx, keytype, optype, cmd, p1, p2); +} + int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, uint64_t value) { return EVP_PKEY_CTX_ctrl(ctx, keytype, optype, cmd, 0, &value); } + +static int evp_pkey_ctx_ctrl_str_int(EVP_PKEY_CTX *ctx, + const char *name, const char *value) +{ + int ret = 0; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + + switch (evp_pkey_ctx_state(ctx)) { + case EVP_PKEY_STATE_PROVIDER: + return evp_pkey_ctx_ctrl_str_to_param(ctx, name, value); + case EVP_PKEY_STATE_UNKNOWN: + case EVP_PKEY_STATE_LEGACY: + if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->ctrl_str == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (strcmp(name, "digest") == 0) + ret = EVP_PKEY_CTX_md(ctx, + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_MD, value); + else + ret = ctx->pmeth->ctrl_str(ctx, name, value); + break; + } + + return ret; +} + int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *name, const char *value) { - if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); + int ret = 0; + + /* If unsupported, we don't want that reported here */ + ERR_set_mark(); + ret = evp_pkey_ctx_store_cached_data(ctx, -1, -1, -1, + name, value, strlen(value) + 1); + if (ret == -2) { + ERR_pop_to_mark(); + } else { + ERR_clear_last_mark(); + /* + * If there was an error, there was an error. + * If the operation isn't initialized yet, we also return, as + * the saved values will be used then anyway. + */ + if (ret < 1 || ctx->operation == EVP_PKEY_OP_UNDEFINED) + return ret; + } + + return evp_pkey_ctx_ctrl_str_int(ctx, name, value); +} + +static int decode_cmd(int cmd, const char *name) +{ + if (cmd == -1) { + /* + * The consequence of the assertion not being true is that this + * function will return -1, which will cause the calling functions + * to signal that the command is unsupported... in non-debug mode. + */ + if (ossl_assert(name != NULL)) + if (strcmp(name, "distid") == 0 || strcmp(name, "hexdistid") == 0) + cmd = EVP_PKEY_CTRL_SET1_ID; + } + + return cmd; +} + +static int evp_pkey_ctx_store_cached_data(EVP_PKEY_CTX *ctx, + int keytype, int optype, + int cmd, const char *name, + const void *data, size_t data_len) +{ + /* + * Check that it's one of the supported commands. The ctrl commands + * number cases here must correspond to the cases in the bottom switch + * in this function. + */ + switch (cmd = decode_cmd(cmd, name)) { + case EVP_PKEY_CTRL_SET1_ID: + break; + default: + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); return -2; } - if (strcmp(name, "digest") == 0) - return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, - value); - return ctx->pmeth->ctrl_str(ctx, name, value); + + if (keytype != -1) { + switch (evp_pkey_ctx_state(ctx)) { + case EVP_PKEY_STATE_PROVIDER: + if (ctx->keymgmt == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (!EVP_KEYMGMT_is_a(ctx->keymgmt, + evp_pkey_type2name(keytype))) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); + return -1; + } + break; + case EVP_PKEY_STATE_UNKNOWN: + case EVP_PKEY_STATE_LEGACY: + if (ctx->pmeth == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (EVP_PKEY_type(ctx->pmeth->pkey_id) != EVP_PKEY_type(keytype)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); + return -1; + } + break; + } + } + if (optype != -1 && (ctx->operation & optype) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); + return -1; + } + + switch (cmd) { + case EVP_PKEY_CTRL_SET1_ID: + evp_pkey_ctx_free_cached_data(ctx, cmd, name); + if (name != NULL) { + ctx->cached_parameters.dist_id_name = OPENSSL_strdup(name); + if (ctx->cached_parameters.dist_id_name == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + } + if (data_len > 0) { + ctx->cached_parameters.dist_id = OPENSSL_memdup(data, data_len); + if (ctx->cached_parameters.dist_id == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + } + ctx->cached_parameters.dist_id_set = 1; + ctx->cached_parameters.dist_id_len = data_len; + break; + } + return 1; +} + +static void evp_pkey_ctx_free_cached_data(EVP_PKEY_CTX *ctx, + int cmd, const char *name) +{ + cmd = decode_cmd(cmd, name); + switch (cmd) { + case EVP_PKEY_CTRL_SET1_ID: + OPENSSL_free(ctx->cached_parameters.dist_id); + OPENSSL_free(ctx->cached_parameters.dist_id_name); + ctx->cached_parameters.dist_id = NULL; + ctx->cached_parameters.dist_id_name = NULL; + break; + } +} + +static void evp_pkey_ctx_free_all_cached_data(EVP_PKEY_CTX *ctx) +{ + evp_pkey_ctx_free_cached_data(ctx, EVP_PKEY_CTRL_SET1_ID, NULL); +} + +int evp_pkey_ctx_use_cached_data(EVP_PKEY_CTX *ctx) +{ + int ret = 1; + + if (ret && ctx->cached_parameters.dist_id_set) { + const char *name = ctx->cached_parameters.dist_id_name; + const void *val = ctx->cached_parameters.dist_id; + size_t len = ctx->cached_parameters.dist_id_len; + + if (name != NULL) + ret = evp_pkey_ctx_ctrl_str_int(ctx, name, val); + else + ret = evp_pkey_ctx_ctrl_int(ctx, -1, ctx->operation, + EVP_PKEY_CTRL_SET1_ID, + (int)len, (void *)val); + } + + return ret; +} + +OSSL_LIB_CTX *EVP_PKEY_CTX_get0_libctx(EVP_PKEY_CTX *ctx) +{ + return ctx->libctx; +} + +const char *EVP_PKEY_CTX_get0_propq(const EVP_PKEY_CTX *ctx) +{ + return ctx->propquery; +} + +const OSSL_PROVIDER *EVP_PKEY_CTX_get0_provider(const EVP_PKEY_CTX *ctx) +{ + if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { + if (ctx->op.sig.signature != NULL) + return EVP_SIGNATURE_get0_provider(ctx->op.sig.signature); + } else if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + if (ctx->op.kex.exchange != NULL) + return EVP_KEYEXCH_get0_provider(ctx->op.kex.exchange); + } else if (EVP_PKEY_CTX_IS_KEM_OP(ctx)) { + if (ctx->op.encap.kem != NULL) + return EVP_KEM_get0_provider(ctx->op.encap.kem); + } else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + if (ctx->op.ciph.cipher != NULL) + return EVP_ASYM_CIPHER_get0_provider(ctx->op.ciph.cipher); + } else if (EVP_PKEY_CTX_IS_GEN_OP(ctx)) { + if (ctx->keymgmt != NULL) + return EVP_KEYMGMT_get0_provider(ctx->keymgmt); + } + + return NULL; } /* Utility functions to send a string of hex string to a ctrl */ @@ -450,7 +1608,7 @@ int EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md) const EVP_MD *m; if (md == NULL || (m = EVP_get_digestbyname(md)) == NULL) { - EVPerr(EVP_F_EVP_PKEY_CTX_MD, EVP_R_INVALID_DIGEST); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_DIGEST); return 0; } return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, 0, (void *)m); @@ -472,7 +1630,7 @@ void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data) ctx->data = data; } -void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx) +void *EVP_PKEY_CTX_get_data(const EVP_PKEY_CTX *ctx) { return ctx->data; } @@ -505,7 +1663,7 @@ void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, int (*copy) (EVP_PKEY_CTX *dst, - EVP_PKEY_CTX *src)) + const EVP_PKEY_CTX *src)) { pmeth->copy = copy; } @@ -690,7 +1848,7 @@ void EVP_PKEY_meth_get_init(const EVP_PKEY_METHOD *pmeth, void EVP_PKEY_meth_get_copy(const EVP_PKEY_METHOD *pmeth, int (**pcopy) (EVP_PKEY_CTX *dst, - EVP_PKEY_CTX *src)) + const EVP_PKEY_CTX *src)) { *pcopy = pmeth->copy; } @@ -849,7 +2007,7 @@ void EVP_PKEY_meth_get_ctrl(const EVP_PKEY_METHOD *pmeth, *pctrl_str = pmeth->ctrl_str; } -void EVP_PKEY_meth_get_digestsign(EVP_PKEY_METHOD *pmeth, +void EVP_PKEY_meth_get_digestsign(const EVP_PKEY_METHOD *pmeth, int (**digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen)) { @@ -857,7 +2015,7 @@ void EVP_PKEY_meth_get_digestsign(EVP_PKEY_METHOD *pmeth, *digestsign = pmeth->digestsign; } -void EVP_PKEY_meth_get_digestverify(EVP_PKEY_METHOD *pmeth, +void EVP_PKEY_meth_get_digestverify(const EVP_PKEY_METHOD *pmeth, int (**digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen)) @@ -887,10 +2045,12 @@ void EVP_PKEY_meth_get_param_check(const EVP_PKEY_METHOD *pmeth, *pcheck = pmeth->param_check; } -void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth, +void EVP_PKEY_meth_get_digest_custom(const EVP_PKEY_METHOD *pmeth, int (**pdigest_custom) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)) { if (pdigest_custom != NULL) *pdigest_custom = pmeth->digest_custom; } + +#endif /* FIPS_MODULE */ diff --git a/crypto/openssl/crypto/evp/signature.c b/crypto/openssl/crypto/evp/signature.c new file mode 100644 index 000000000000..fb269b3bfd07 --- /dev/null +++ b/crypto/openssl/crypto/evp/signature.c @@ -0,0 +1,748 @@ +/* + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/numbers.h" /* includes SIZE_MAX */ +#include "internal/cryptlib.h" +#include "internal/provider.h" +#include "internal/core.h" +#include "crypto/evp.h" +#include "evp_local.h" + +static EVP_SIGNATURE *evp_signature_new(OSSL_PROVIDER *prov) +{ + EVP_SIGNATURE *signature = OPENSSL_zalloc(sizeof(EVP_SIGNATURE)); + + if (signature == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + signature->lock = CRYPTO_THREAD_lock_new(); + if (signature->lock == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(signature); + return NULL; + } + signature->prov = prov; + ossl_provider_up_ref(prov); + signature->refcnt = 1; + + return signature; +} + +static void *evp_signature_from_algorithm(int name_id, + const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + const OSSL_DISPATCH *fns = algodef->implementation; + EVP_SIGNATURE *signature = NULL; + int ctxfncnt = 0, signfncnt = 0, verifyfncnt = 0, verifyrecfncnt = 0; + int digsignfncnt = 0, digverifyfncnt = 0; + int gparamfncnt = 0, sparamfncnt = 0, gmdparamfncnt = 0, smdparamfncnt = 0; + + if ((signature = evp_signature_new(prov)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + signature->name_id = name_id; + if ((signature->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) + goto err; + signature->description = algodef->algorithm_description; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_SIGNATURE_NEWCTX: + if (signature->newctx != NULL) + break; + signature->newctx = OSSL_FUNC_signature_newctx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SIGN_INIT: + if (signature->sign_init != NULL) + break; + signature->sign_init = OSSL_FUNC_signature_sign_init(fns); + signfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SIGN: + if (signature->sign != NULL) + break; + signature->sign = OSSL_FUNC_signature_sign(fns); + signfncnt++; + break; + case OSSL_FUNC_SIGNATURE_VERIFY_INIT: + if (signature->verify_init != NULL) + break; + signature->verify_init = OSSL_FUNC_signature_verify_init(fns); + verifyfncnt++; + break; + case OSSL_FUNC_SIGNATURE_VERIFY: + if (signature->verify != NULL) + break; + signature->verify = OSSL_FUNC_signature_verify(fns); + verifyfncnt++; + break; + case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT: + if (signature->verify_recover_init != NULL) + break; + signature->verify_recover_init + = OSSL_FUNC_signature_verify_recover_init(fns); + verifyrecfncnt++; + break; + case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER: + if (signature->verify_recover != NULL) + break; + signature->verify_recover + = OSSL_FUNC_signature_verify_recover(fns); + verifyrecfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT: + if (signature->digest_sign_init != NULL) + break; + signature->digest_sign_init + = OSSL_FUNC_signature_digest_sign_init(fns); + break; + case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE: + if (signature->digest_sign_update != NULL) + break; + signature->digest_sign_update + = OSSL_FUNC_signature_digest_sign_update(fns); + digsignfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL: + if (signature->digest_sign_final != NULL) + break; + signature->digest_sign_final + = OSSL_FUNC_signature_digest_sign_final(fns); + digsignfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DIGEST_SIGN: + if (signature->digest_sign != NULL) + break; + signature->digest_sign + = OSSL_FUNC_signature_digest_sign(fns); + break; + case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT: + if (signature->digest_verify_init != NULL) + break; + signature->digest_verify_init + = OSSL_FUNC_signature_digest_verify_init(fns); + break; + case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE: + if (signature->digest_verify_update != NULL) + break; + signature->digest_verify_update + = OSSL_FUNC_signature_digest_verify_update(fns); + digverifyfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL: + if (signature->digest_verify_final != NULL) + break; + signature->digest_verify_final + = OSSL_FUNC_signature_digest_verify_final(fns); + digverifyfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY: + if (signature->digest_verify != NULL) + break; + signature->digest_verify + = OSSL_FUNC_signature_digest_verify(fns); + break; + case OSSL_FUNC_SIGNATURE_FREECTX: + if (signature->freectx != NULL) + break; + signature->freectx = OSSL_FUNC_signature_freectx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_SIGNATURE_DUPCTX: + if (signature->dupctx != NULL) + break; + signature->dupctx = OSSL_FUNC_signature_dupctx(fns); + break; + case OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS: + if (signature->get_ctx_params != NULL) + break; + signature->get_ctx_params + = OSSL_FUNC_signature_get_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS: + if (signature->gettable_ctx_params != NULL) + break; + signature->gettable_ctx_params + = OSSL_FUNC_signature_gettable_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS: + if (signature->set_ctx_params != NULL) + break; + signature->set_ctx_params + = OSSL_FUNC_signature_set_ctx_params(fns); + sparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS: + if (signature->settable_ctx_params != NULL) + break; + signature->settable_ctx_params + = OSSL_FUNC_signature_settable_ctx_params(fns); + sparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS: + if (signature->get_ctx_md_params != NULL) + break; + signature->get_ctx_md_params + = OSSL_FUNC_signature_get_ctx_md_params(fns); + gmdparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS: + if (signature->gettable_ctx_md_params != NULL) + break; + signature->gettable_ctx_md_params + = OSSL_FUNC_signature_gettable_ctx_md_params(fns); + gmdparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS: + if (signature->set_ctx_md_params != NULL) + break; + signature->set_ctx_md_params + = OSSL_FUNC_signature_set_ctx_md_params(fns); + smdparamfncnt++; + break; + case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS: + if (signature->settable_ctx_md_params != NULL) + break; + signature->settable_ctx_md_params + = OSSL_FUNC_signature_settable_ctx_md_params(fns); + smdparamfncnt++; + break; + } + } + if (ctxfncnt != 2 + || (signfncnt == 0 + && verifyfncnt == 0 + && verifyrecfncnt == 0 + && digsignfncnt == 0 + && digverifyfncnt == 0 + && signature->digest_sign == NULL + && signature->digest_verify == NULL) + || (signfncnt != 0 && signfncnt != 2) + || (verifyfncnt != 0 && verifyfncnt != 2) + || (verifyrecfncnt != 0 && verifyrecfncnt != 2) + || (digsignfncnt != 0 && digsignfncnt != 2) + || (digsignfncnt == 2 && signature->digest_sign_init == NULL) + || (digverifyfncnt != 0 && digverifyfncnt != 2) + || (digverifyfncnt == 2 && signature->digest_verify_init == NULL) + || (signature->digest_sign != NULL + && signature->digest_sign_init == NULL) + || (signature->digest_verify != NULL + && signature->digest_verify_init == NULL) + || (gparamfncnt != 0 && gparamfncnt != 2) + || (sparamfncnt != 0 && sparamfncnt != 2) + || (gmdparamfncnt != 0 && gmdparamfncnt != 2) + || (smdparamfncnt != 0 && smdparamfncnt != 2)) { + /* + * In order to be a consistent set of functions we must have at least + * a set of context functions (newctx and freectx) as well as a set of + * "signature" functions: + * (sign_init, sign) or + * (verify_init verify) or + * (verify_recover_init, verify_recover) or + * (digest_sign_init, digest_sign_update, digest_sign_final) or + * (digest_verify_init, digest_verify_update, digest_verify_final) or + * (digest_sign_init, digest_sign) or + * (digest_verify_init, digest_verify). + * + * set_ctx_params and settable_ctx_params are optional, but if one of + * them is present then the other one must also be present. The same + * applies to get_ctx_params and gettable_ctx_params. The same rules + * apply to the "md_params" functions. The dupctx function is optional. + */ + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + goto err; + } + + return signature; + err: + EVP_SIGNATURE_free(signature); + return NULL; +} + +void EVP_SIGNATURE_free(EVP_SIGNATURE *signature) +{ + int i; + + if (signature == NULL) + return; + CRYPTO_DOWN_REF(&signature->refcnt, &i, signature->lock); + if (i > 0) + return; + OPENSSL_free(signature->type_name); + ossl_provider_free(signature->prov); + CRYPTO_THREAD_lock_free(signature->lock); + OPENSSL_free(signature); +} + +int EVP_SIGNATURE_up_ref(EVP_SIGNATURE *signature) +{ + int ref = 0; + + CRYPTO_UP_REF(&signature->refcnt, &ref, signature->lock); + return 1; +} + +OSSL_PROVIDER *EVP_SIGNATURE_get0_provider(const EVP_SIGNATURE *signature) +{ + return signature->prov; +} + +EVP_SIGNATURE *EVP_SIGNATURE_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(ctx, OSSL_OP_SIGNATURE, algorithm, properties, + evp_signature_from_algorithm, + (int (*)(void *))EVP_SIGNATURE_up_ref, + (void (*)(void *))EVP_SIGNATURE_free); +} + +EVP_SIGNATURE *evp_signature_fetch_from_prov(OSSL_PROVIDER *prov, + const char *algorithm, + const char *properties) +{ + return evp_generic_fetch_from_prov(prov, OSSL_OP_SIGNATURE, + algorithm, properties, + evp_signature_from_algorithm, + (int (*)(void *))EVP_SIGNATURE_up_ref, + (void (*)(void *))EVP_SIGNATURE_free); +} + +int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name) +{ + return signature != NULL + && evp_is_a(signature->prov, signature->name_id, NULL, name); +} + +int evp_signature_get_number(const EVP_SIGNATURE *signature) +{ + return signature->name_id; +} + +const char *EVP_SIGNATURE_get0_name(const EVP_SIGNATURE *signature) +{ + return signature->type_name; +} + +const char *EVP_SIGNATURE_get0_description(const EVP_SIGNATURE *signature) +{ + return signature->description; +} + +void EVP_SIGNATURE_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_SIGNATURE *signature, + void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_SIGNATURE, + (void (*)(void *, void *))fn, arg, + evp_signature_from_algorithm, + (int (*)(void *))EVP_SIGNATURE_up_ref, + (void (*)(void *))EVP_SIGNATURE_free); +} + + +int EVP_SIGNATURE_names_do_all(const EVP_SIGNATURE *signature, + void (*fn)(const char *name, void *data), + void *data) +{ + if (signature->prov != NULL) + return evp_names_do_all(signature->prov, signature->name_id, fn, data); + + return 1; +} + +const OSSL_PARAM *EVP_SIGNATURE_gettable_ctx_params(const EVP_SIGNATURE *sig) +{ + void *provctx; + + if (sig == NULL || sig->gettable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_SIGNATURE_get0_provider(sig)); + return sig->gettable_ctx_params(NULL, provctx); +} + +const OSSL_PARAM *EVP_SIGNATURE_settable_ctx_params(const EVP_SIGNATURE *sig) +{ + void *provctx; + + if (sig == NULL || sig->settable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_SIGNATURE_get0_provider(sig)); + return sig->settable_ctx_params(NULL, provctx); +} + +static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation, + const OSSL_PARAM params[]) +{ + int ret = 0; + void *provkey = NULL; + EVP_SIGNATURE *signature = NULL; + EVP_KEYMGMT *tmp_keymgmt = NULL; + const OSSL_PROVIDER *tmp_prov = NULL; + const char *supported_sig = NULL; + int iter; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = operation; + + ERR_set_mark(); + + if (evp_pkey_ctx_is_legacy(ctx)) + goto legacy; + + if (ctx->pkey == NULL) { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); + goto err; + } + + /* + * Try to derive the supported signature from |ctx->keymgmt|. + */ + if (!ossl_assert(ctx->pkey->keymgmt == NULL + || ctx->pkey->keymgmt == ctx->keymgmt)) { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + goto err; + } + supported_sig = evp_keymgmt_util_query_operation_name(ctx->keymgmt, + OSSL_OP_SIGNATURE); + if (supported_sig == NULL) { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + /* + * We perform two iterations: + * + * 1. Do the normal signature fetch, using the fetching data given by + * the EVP_PKEY_CTX. + * 2. Do the provider specific signature fetch, from the same provider + * as |ctx->keymgmt| + * + * We then try to fetch the keymgmt from the same provider as the + * signature, and try to export |ctx->pkey| to that keymgmt (when + * this keymgmt happens to be the same as |ctx->keymgmt|, the export + * is a no-op, but we call it anyway to not complicate the code even + * more). + * If the export call succeeds (returns a non-NULL provider key pointer), + * we're done and can perform the operation itself. If not, we perform + * the second iteration, or jump to legacy. + */ + for (iter = 1; iter < 3 && provkey == NULL; iter++) { + EVP_KEYMGMT *tmp_keymgmt_tofree = NULL; + + /* + * If we're on the second iteration, free the results from the first. + * They are NULL on the first iteration, so no need to check what + * iteration we're on. + */ + EVP_SIGNATURE_free(signature); + EVP_KEYMGMT_free(tmp_keymgmt); + + switch (iter) { + case 1: + signature = + EVP_SIGNATURE_fetch(ctx->libctx, supported_sig, ctx->propquery); + if (signature != NULL) + tmp_prov = EVP_SIGNATURE_get0_provider(signature); + break; + case 2: + tmp_prov = EVP_KEYMGMT_get0_provider(ctx->keymgmt); + signature = + evp_signature_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, + supported_sig, ctx->propquery); + if (signature == NULL) + goto legacy; + break; + } + if (signature == NULL) + continue; + + /* + * Ensure that the key is provided, either natively, or as a cached + * export. We start by fetching the keymgmt with the same name as + * |ctx->pkey|, but from the provider of the signature method, using + * the same property query as when fetching the signature method. + * With the keymgmt we found (if we did), we try to export |ctx->pkey| + * to it (evp_pkey_export_to_provider() is smart enough to only actually + + * export it if |tmp_keymgmt| is different from |ctx->pkey|'s keymgmt) + */ + tmp_keymgmt_tofree = tmp_keymgmt = + evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, + EVP_KEYMGMT_get0_name(ctx->keymgmt), + ctx->propquery); + if (tmp_keymgmt != NULL) + provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, + &tmp_keymgmt, ctx->propquery); + if (tmp_keymgmt == NULL) + EVP_KEYMGMT_free(tmp_keymgmt_tofree); + } + + if (provkey == NULL) { + EVP_SIGNATURE_free(signature); + goto legacy; + } + + ERR_pop_to_mark(); + + /* No more legacy from here down to legacy: */ + + ctx->op.sig.signature = signature; + ctx->op.sig.algctx = + signature->newctx(ossl_provider_ctx(signature->prov), ctx->propquery); + if (ctx->op.sig.algctx == NULL) { + /* The provider key can stay in the cache */ + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + switch (operation) { + case EVP_PKEY_OP_SIGN: + if (signature->sign_init == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = signature->sign_init(ctx->op.sig.algctx, provkey, params); + break; + case EVP_PKEY_OP_VERIFY: + if (signature->verify_init == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = signature->verify_init(ctx->op.sig.algctx, provkey, params); + break; + case EVP_PKEY_OP_VERIFYRECOVER: + if (signature->verify_recover_init == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = signature->verify_recover_init(ctx->op.sig.algctx, provkey, + params); + break; + default: + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + if (ret <= 0) { + signature->freectx(ctx->op.sig.algctx); + ctx->op.sig.algctx = NULL; + goto err; + } + goto end; + + legacy: + /* + * If we don't have the full support we need with provided methods, + * let's go see if legacy does. + */ + ERR_pop_to_mark(); + EVP_KEYMGMT_free(tmp_keymgmt); + tmp_keymgmt = NULL; + + if (ctx->pmeth == NULL + || (operation == EVP_PKEY_OP_SIGN && ctx->pmeth->sign == NULL) + || (operation == EVP_PKEY_OP_VERIFY && ctx->pmeth->verify == NULL) + || (operation == EVP_PKEY_OP_VERIFYRECOVER + && ctx->pmeth->verify_recover == NULL)) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + switch (operation) { + case EVP_PKEY_OP_SIGN: + if (ctx->pmeth->sign_init == NULL) + return 1; + ret = ctx->pmeth->sign_init(ctx); + break; + case EVP_PKEY_OP_VERIFY: + if (ctx->pmeth->verify_init == NULL) + return 1; + ret = ctx->pmeth->verify_init(ctx); + break; + case EVP_PKEY_OP_VERIFYRECOVER: + if (ctx->pmeth->verify_recover_init == NULL) + return 1; + ret = ctx->pmeth->verify_recover_init(ctx); + break; + default: + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + if (ret <= 0) + goto err; + end: +#ifndef FIPS_MODULE + if (ret > 0) + ret = evp_pkey_ctx_use_cached_data(ctx); +#endif + + EVP_KEYMGMT_free(tmp_keymgmt); + return ret; + err: + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = EVP_PKEY_OP_UNDEFINED; + EVP_KEYMGMT_free(tmp_keymgmt); + return ret; +} + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_signature_init(ctx, EVP_PKEY_OP_SIGN, NULL); +} + +int EVP_PKEY_sign_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) +{ + return evp_pkey_signature_init(ctx, EVP_PKEY_OP_SIGN, params); +} + +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_SIGN) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.sig.algctx == NULL) + goto legacy; + + ret = ctx->op.sig.signature->sign(ctx->op.sig.algctx, sig, siglen, + (sig == NULL) ? 0 : *siglen, tbs, tbslen); + + return ret; + legacy: + + if (ctx->pmeth == NULL || ctx->pmeth->sign == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) + return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); +} + +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_signature_init(ctx, EVP_PKEY_OP_VERIFY, NULL); +} + +int EVP_PKEY_verify_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) +{ + return evp_pkey_signature_init(ctx, EVP_PKEY_OP_VERIFY, params); +} + +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_VERIFY) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.sig.algctx == NULL) + goto legacy; + + ret = ctx->op.sig.signature->verify(ctx->op.sig.algctx, sig, siglen, + tbs, tbslen); + + return ret; + legacy: + if (ctx->pmeth == NULL || ctx->pmeth->verify == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); +} + +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) +{ + return evp_pkey_signature_init(ctx, EVP_PKEY_OP_VERIFYRECOVER, NULL); +} + +int EVP_PKEY_verify_recover_init_ex(EVP_PKEY_CTX *ctx, + const OSSL_PARAM params[]) +{ + return evp_pkey_signature_init(ctx, EVP_PKEY_OP_VERIFYRECOVER, params); +} + +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen) +{ + int ret; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.sig.algctx == NULL) + goto legacy; + + ret = ctx->op.sig.signature->verify_recover(ctx->op.sig.algctx, rout, + routlen, + (rout == NULL ? 0 : *routlen), + sig, siglen); + return ret; + legacy: + if (ctx->pmeth == NULL || ctx->pmeth->verify_recover == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) + return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); +} diff --git a/crypto/openssl/crypto/ex_data.c b/crypto/openssl/crypto/ex_data.c index 0f5a9295056a..40223f06e4ec 100644 --- a/crypto/openssl/crypto/ex_data.c +++ b/crypto/openssl/crypto/ex_data.c @@ -1,81 +1,52 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#include #include "crypto/cryptlib.h" #include "internal/thread_once.h" -/* - * Each structure type (sometimes called a class), that supports - * exdata has a stack of callbacks for each instance. - */ -struct ex_callback_st { - long argl; /* Arbitrary long */ - void *argp; /* Arbitrary void * */ - CRYPTO_EX_new *new_func; - CRYPTO_EX_free *free_func; - CRYPTO_EX_dup *dup_func; -}; - -/* - * The state for each class. This could just be a typedef, but - * a structure allows future changes. - */ -typedef struct ex_callbacks_st { - STACK_OF(EX_CALLBACK) *meth; -} EX_CALLBACKS; - -static EX_CALLBACKS ex_data[CRYPTO_EX_INDEX__COUNT]; - -static CRYPTO_RWLOCK *ex_data_lock = NULL; -static CRYPTO_ONCE ex_data_init = CRYPTO_ONCE_STATIC_INIT; - -DEFINE_RUN_ONCE_STATIC(do_ex_data_init) +int ossl_do_ex_data_init(OSSL_LIB_CTX *ctx) { - if (!OPENSSL_init_crypto(0, NULL)) + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx); + + if (global == NULL) return 0; - ex_data_lock = CRYPTO_THREAD_lock_new(); - return ex_data_lock != NULL; + + global->ex_data_lock = CRYPTO_THREAD_lock_new(); + return global->ex_data_lock != NULL; } /* * Return the EX_CALLBACKS from the |ex_data| array that corresponds to * a given class. On success, *holds the lock.* + * The |global| parameter is assumed to be non null (checked by the caller). */ -static EX_CALLBACKS *get_and_lock(int class_index) +static EX_CALLBACKS *get_and_lock(OSSL_EX_DATA_GLOBAL *global, int class_index) { EX_CALLBACKS *ip; if (class_index < 0 || class_index >= CRYPTO_EX_INDEX__COUNT) { - CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_PASSED_INVALID_ARGUMENT); - return NULL; - } - - if (!RUN_ONCE(&ex_data_init, do_ex_data_init)) { - CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); return NULL; } - if (ex_data_lock == NULL) { + if (global->ex_data_lock == NULL) { /* - * This can happen in normal operation when using CRYPTO_mem_leaks(). - * The CRYPTO_mem_leaks() function calls OPENSSL_cleanup() which cleans - * up the locks. Subsequently the BIO that CRYPTO_mem_leaks() uses gets - * freed, which also attempts to free the ex_data. However - * CRYPTO_mem_leaks() ensures that the ex_data is freed early (i.e. - * before OPENSSL_cleanup() is called), so if we get here we can safely - * ignore this operation. We just treat it as an error. + * If we get here, someone (who?) cleaned up the lock, so just + * treat it as an error. */ return NULL; } - ip = &ex_data[class_index]; - CRYPTO_THREAD_write_lock(ex_data_lock); + if (!CRYPTO_THREAD_write_lock(global->ex_data_lock)) + return NULL; + ip = &global->ex_data[class_index]; return ip; } @@ -90,19 +61,23 @@ static void cleanup_cb(EX_CALLBACK *funcs) * called under potential race-conditions anyway (it's for program shutdown * after all). */ -void crypto_cleanup_all_ex_data_int(void) +void ossl_crypto_cleanup_all_ex_data_int(OSSL_LIB_CTX *ctx) { int i; + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx); + + if (global == NULL) + return; for (i = 0; i < CRYPTO_EX_INDEX__COUNT; ++i) { - EX_CALLBACKS *ip = &ex_data[i]; + EX_CALLBACKS *ip = &global->ex_data[i]; sk_EX_CALLBACK_pop_free(ip->meth, cleanup_cb); ip->meth = NULL; } - CRYPTO_THREAD_lock_free(ex_data_lock); - ex_data_lock = NULL; + CRYPTO_THREAD_lock_free(global->ex_data_lock); + global->ex_data_lock = NULL; } @@ -121,20 +96,26 @@ static void dummy_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, } static int dummy_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, - void *from_d, int idx, + void **from_d, int idx, long argl, void *argp) { return 1; } -int CRYPTO_free_ex_index(int class_index, int idx) +int ossl_crypto_free_ex_index_ex(OSSL_LIB_CTX *ctx, int class_index, int idx) { - EX_CALLBACKS *ip = get_and_lock(class_index); + EX_CALLBACKS *ip; EX_CALLBACK *a; int toret = 0; + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx); + + if (global == NULL) + return 0; + ip = get_and_lock(global, class_index); if (ip == NULL) return 0; + if (idx < 0 || idx >= sk_EX_CALLBACK_num(ip->meth)) goto err; a = sk_EX_CALLBACK_value(ip->meth, idx); @@ -145,21 +126,34 @@ int CRYPTO_free_ex_index(int class_index, int idx) a->free_func = dummy_free; toret = 1; err: - CRYPTO_THREAD_unlock(ex_data_lock); + CRYPTO_THREAD_unlock(global->ex_data_lock); return toret; } +int CRYPTO_free_ex_index(int class_index, int idx) +{ + return ossl_crypto_free_ex_index_ex(NULL, class_index, idx); +} + /* * Register a new index. */ -int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, - CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func) +int ossl_crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index, + long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func, + int priority) { int toret = -1; EX_CALLBACK *a; - EX_CALLBACKS *ip = get_and_lock(class_index); + EX_CALLBACKS *ip; + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx); + if (global == NULL) + return -1; + + ip = get_and_lock(global, class_index); if (ip == NULL) return -1; @@ -169,14 +163,14 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, * "app_data" routines use ex_data index zero. See RT 3710. */ if (ip->meth == NULL || !sk_EX_CALLBACK_push(ip->meth, NULL)) { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); goto err; } } a = (EX_CALLBACK *)OPENSSL_malloc(sizeof(*a)); if (a == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); goto err; } a->argl = argl; @@ -184,9 +178,10 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, a->new_func = new_func; a->dup_func = dup_func; a->free_func = free_func; + a->priority = priority; if (!sk_EX_CALLBACK_push(ip->meth, NULL)) { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); OPENSSL_free(a); goto err; } @@ -194,10 +189,18 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, (void)sk_EX_CALLBACK_set(ip->meth, toret, a); err: - CRYPTO_THREAD_unlock(ex_data_lock); + CRYPTO_THREAD_unlock(global->ex_data_lock); return toret; } +int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + return ossl_crypto_get_ex_new_index_ex(NULL, class_index, argl, argp, + new_func, dup_func, free_func, 0); +} + /* * Initialise a new CRYPTO_EX_DATA for use in a particular class - including * calling new() callbacks for each index in the class used by this variable @@ -205,19 +208,25 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, * in the lock, then using them outside the lock. Note this only applies * to the global "ex_data" state (ie. class definitions), not 'ad' itself. */ -int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +int ossl_crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj, + CRYPTO_EX_DATA *ad) { int mx, i; void *ptr; EX_CALLBACK **storage = NULL; EX_CALLBACK *stack[10]; - EX_CALLBACKS *ip = get_and_lock(class_index); + EX_CALLBACKS *ip; + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx); + if (global == NULL) + return 0; + + ip = get_and_lock(global, class_index); if (ip == NULL) return 0; + ad->ctx = ctx; ad->sk = NULL; - mx = sk_EX_CALLBACK_num(ip->meth); if (mx > 0) { if (mx < (int)OSSL_NELEM(stack)) @@ -228,10 +237,10 @@ int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) for (i = 0; i < mx; i++) storage[i] = sk_EX_CALLBACK_value(ip->meth, i); } - CRYPTO_THREAD_unlock(ex_data_lock); + CRYPTO_THREAD_unlock(global->ex_data_lock); if (mx > 0 && storage == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_NEW_EX_DATA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } for (i = 0; i < mx; i++) { @@ -246,6 +255,11 @@ int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) return 1; } +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + return ossl_crypto_new_ex_data_ex(NULL, class_index, obj, ad); +} + /* * Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks * for each index in the class used by this variable @@ -259,11 +273,19 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, EX_CALLBACK **storage = NULL; EX_CALLBACKS *ip; int toret = 0; + OSSL_EX_DATA_GLOBAL *global; + to->ctx = from->ctx; if (from->sk == NULL) /* Nothing to copy over */ return 1; - if ((ip = get_and_lock(class_index)) == NULL) + + global = ossl_lib_ctx_get_ex_data_global(from->ctx); + if (global == NULL) + return 0; + + ip = get_and_lock(global, class_index); + if (ip == NULL) return 0; mx = sk_EX_CALLBACK_num(ip->meth); @@ -279,12 +301,12 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, for (i = 0; i < mx; i++) storage[i] = sk_EX_CALLBACK_value(ip->meth, i); } - CRYPTO_THREAD_unlock(ex_data_lock); + CRYPTO_THREAD_unlock(global->ex_data_lock); if (mx == 0) return 1; if (storage == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_DUP_EX_DATA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } /* @@ -312,6 +334,27 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, return toret; } +struct ex_callback_entry { + const EX_CALLBACK *excb; + int index; +}; + +static int ex_callback_compare(const void *a, const void *b) +{ + const struct ex_callback_entry *ap = (const struct ex_callback_entry *)a; + const struct ex_callback_entry *bp = (const struct ex_callback_entry *)b; + + if (ap->excb == bp->excb) + return 0; + + if (ap->excb == NULL) + return 1; + if (bp->excb == NULL) + return -1; + if (ap->excb->priority == bp->excb->priority) + return 0; + return ap->excb->priority > bp->excb->priority ? -1 : 1; +} /* * Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for @@ -322,11 +365,16 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) int mx, i; EX_CALLBACKS *ip; void *ptr; - EX_CALLBACK *f; - EX_CALLBACK *stack[10]; - EX_CALLBACK **storage = NULL; + const EX_CALLBACK *f; + struct ex_callback_entry stack[10]; + struct ex_callback_entry *storage = NULL; + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ad->ctx); + + if (global == NULL) + goto err; - if ((ip = get_and_lock(class_index)) == NULL) + ip = get_and_lock(global, class_index); + if (ip == NULL) goto err; mx = sk_EX_CALLBACK_num(ip->meth); @@ -336,22 +384,23 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) else storage = OPENSSL_malloc(sizeof(*storage) * mx); if (storage != NULL) - for (i = 0; i < mx; i++) - storage[i] = sk_EX_CALLBACK_value(ip->meth, i); + for (i = 0; i < mx; i++) { + storage[i].excb = sk_EX_CALLBACK_value(ip->meth, i); + storage[i].index = i; + } } - CRYPTO_THREAD_unlock(ex_data_lock); - - for (i = 0; i < mx; i++) { - if (storage != NULL) - f = storage[i]; - else { - CRYPTO_THREAD_write_lock(ex_data_lock); - f = sk_EX_CALLBACK_value(ip->meth, i); - CRYPTO_THREAD_unlock(ex_data_lock); - } - if (f != NULL && f->free_func != NULL) { - ptr = CRYPTO_get_ex_data(ad, i); - f->free_func(obj, ptr, ad, i, f->argl, f->argp); + CRYPTO_THREAD_unlock(global->ex_data_lock); + + if (storage != NULL) { + /* Sort according to priority. High priority first */ + qsort(storage, mx, sizeof(*storage), ex_callback_compare); + for (i = 0; i < mx; i++) { + f = storage[i].excb; + + if (f != NULL && f->free_func != NULL) { + ptr = CRYPTO_get_ex_data(ad, storage[i].index); + f->free_func(obj, ptr, ad, storage[i].index, f->argl, f->argp); + } } } @@ -360,6 +409,53 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) err: sk_void_free(ad->sk); ad->sk = NULL; + ad->ctx = NULL; +} + +/* + * Allocate a given CRYPTO_EX_DATA item using the class specific allocation + * function + */ +int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad, + int idx) +{ + void *curval; + + curval = CRYPTO_get_ex_data(ad, idx); + /* Already there, no need to allocate */ + if (curval != NULL) + return 1; + + return ossl_crypto_alloc_ex_data_intern(class_index, obj, ad, idx); +} + +int ossl_crypto_alloc_ex_data_intern(int class_index, void *obj, + CRYPTO_EX_DATA *ad, int idx) +{ + EX_CALLBACK *f; + EX_CALLBACKS *ip; + OSSL_EX_DATA_GLOBAL *global; + + global = ossl_lib_ctx_get_ex_data_global(ad->ctx); + if (global == NULL) + return 0; + + ip = get_and_lock(global, class_index); + if (ip == NULL) + return 0; + f = sk_EX_CALLBACK_value(ip->meth, idx); + CRYPTO_THREAD_unlock(global->ex_data_lock); + + /* + * This should end up calling CRYPTO_set_ex_data(), which allocates + * everything necessary to support placing the new data in the right spot. + */ + if (f->new_func == NULL) + return 0; + + f->new_func(obj, NULL, ad, idx, f->argl, f->argp); + + return 1; } /* @@ -372,18 +468,22 @@ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) if (ad->sk == NULL) { if ((ad->sk = sk_void_new_null()) == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } } for (i = sk_void_num(ad->sk); i <= idx; ++i) { if (!sk_void_push(ad->sk, NULL)) { - CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } } - sk_void_set(ad->sk, idx, val); + if (sk_void_set(ad->sk, idx, val) != val) { + /* Probably the index is out of bounds */ + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } return 1; } @@ -397,3 +497,8 @@ void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) return NULL; return sk_void_value(ad->sk, idx); } + +OSSL_LIB_CTX *ossl_crypto_ex_data_get_ossl_lib_ctx(const CRYPTO_EX_DATA *ad) +{ + return ad->ctx; +} diff --git a/crypto/openssl/crypto/ffc/build.info b/crypto/openssl/crypto/ffc/build.info new file mode 100644 index 000000000000..61cca17c5fe8 --- /dev/null +++ b/crypto/openssl/crypto/ffc/build.info @@ -0,0 +1,8 @@ +LIBS=../../libcrypto + +$COMMON=ffc_params.c ffc_params_generate.c ffc_key_generate.c \ + ffc_params_validate.c ffc_key_validate.c ffc_backend.c \ + ffc_dh.c + +SOURCE[../../libcrypto]=$COMMON +SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/openssl/crypto/ffc/ffc_backend.c b/crypto/openssl/crypto/ffc/ffc_backend.c new file mode 100644 index 000000000000..dbd28b0e66bd --- /dev/null +++ b/crypto/openssl/crypto/ffc/ffc_backend.c @@ -0,0 +1,129 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/ffc.h" +#include "internal/sizes.h" + +/* + * The intention with the "backend" source file is to offer backend support + * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider + * implementations alike. + */ + +int ossl_ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *prm; + const OSSL_PARAM *param_p, *param_q, *param_g; + BIGNUM *p = NULL, *q = NULL, *g = NULL, *j = NULL; + int i; + + if (ffc == NULL) + return 0; + + prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); + if (prm != NULL) { + /* + * In a no-dh build we just go straight to err because we have no + * support for this. + */ +#ifndef OPENSSL_NO_DH + const DH_NAMED_GROUP *group = NULL; + + if (prm->data_type != OSSL_PARAM_UTF8_STRING + || prm->data == NULL + || (group = ossl_ffc_name_to_dh_named_group(prm->data)) == NULL + || !ossl_ffc_named_group_set(ffc, group)) +#endif + goto err; + } + + param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P); + param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G); + param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q); + + if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p)) + || (param_q != NULL && !OSSL_PARAM_get_BN(param_q, &q)) + || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g))) + goto err; + + prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GINDEX); + if (prm != NULL) { + if (!OSSL_PARAM_get_int(prm, &i)) + goto err; + ffc->gindex = i; + } + prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PCOUNTER); + if (prm != NULL) { + if (!OSSL_PARAM_get_int(prm, &i)) + goto err; + ffc->pcounter = i; + } + prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_COFACTOR); + if (prm != NULL && !OSSL_PARAM_get_BN(prm, &j)) + goto err; + prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_H); + if (prm != NULL) { + if (!OSSL_PARAM_get_int(prm, &i)) + goto err; + ffc->h = i; + } + prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_SEED); + if (prm != NULL) { + if (prm->data_type != OSSL_PARAM_OCTET_STRING) + goto err; + if (!ossl_ffc_params_set_seed(ffc, prm->data, prm->data_size)) + goto err; + } + prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_VALIDATE_PQ); + if (prm != NULL) { + if (!OSSL_PARAM_get_int(prm, &i)) + goto err; + ossl_ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_PQ, i); + } + prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_VALIDATE_G); + if (prm != NULL) { + if (!OSSL_PARAM_get_int(prm, &i)) + goto err; + ossl_ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_G, i); + } + prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_VALIDATE_LEGACY); + if (prm != NULL) { + if (!OSSL_PARAM_get_int(prm, &i)) + goto err; + ossl_ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_LEGACY, i); + } + + prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST); + if (prm != NULL) { + const OSSL_PARAM *p1; + const char *props = NULL; + + if (prm->data_type != OSSL_PARAM_UTF8_STRING) + goto err; + p1 = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS); + if (p1 != NULL) { + if (p1->data_type != OSSL_PARAM_UTF8_STRING) + goto err; + } + if (!ossl_ffc_set_digest(ffc, prm->data, props)) + goto err; + } + + ossl_ffc_params_set0_pqg(ffc, p, q, g); + ossl_ffc_params_set0_j(ffc, j); + return 1; + + err: + BN_free(j); + BN_free(p); + BN_free(q); + BN_free(g); + return 0; +} diff --git a/crypto/openssl/crypto/ffc/ffc_dh.c b/crypto/openssl/crypto/ffc/ffc_dh.c new file mode 100644 index 000000000000..df07e173bcb8 --- /dev/null +++ b/crypto/openssl/crypto/ffc/ffc_dh.c @@ -0,0 +1,173 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/ffc.h" +#include "internal/nelem.h" +#include "crypto/bn_dh.h" + +#ifndef OPENSSL_NO_DH + +# define FFDHE(sz, keylength) { \ + SN_ffdhe##sz, NID_ffdhe##sz, \ + sz, \ + keylength, \ + &ossl_bignum_ffdhe##sz##_p, &ossl_bignum_ffdhe##sz##_q, \ + &ossl_bignum_const_2, \ + } + +# define MODP(sz, keylength) { \ + SN_modp_##sz, NID_modp_##sz, \ + sz, \ + keylength, \ + &ossl_bignum_modp_##sz##_p, &ossl_bignum_modp_##sz##_q, \ + &ossl_bignum_const_2 \ + } + +# define RFC5114(name, uid, sz, tag) { \ + name, uid, \ + sz, \ + 0, \ + &ossl_bignum_dh##tag##_p, &ossl_bignum_dh##tag##_q, \ + &ossl_bignum_dh##tag##_g \ + } + +#else + +# define FFDHE(sz, keylength) { SN_ffdhe##sz, NID_ffdhe##sz } +# define MODP(sz, keylength) { SN_modp_##sz, NID_modp_##sz } +# define RFC5114(name, uid, sz, tag) { name, uid } + +#endif + +struct dh_named_group_st { + const char *name; + int uid; +#ifndef OPENSSL_NO_DH + int32_t nbits; + int keylength; + const BIGNUM *p; + const BIGNUM *q; + const BIGNUM *g; +#endif +}; + +/* + * The private key length values are taken from RFC7919 with the values for + * MODP primes given the same lengths as the equivalent FFDHE. + * The MODP 1536 value is approximated. + */ +static const DH_NAMED_GROUP dh_named_groups[] = { + FFDHE(2048, 225), + FFDHE(3072, 275), + FFDHE(4096, 325), + FFDHE(6144, 375), + FFDHE(8192, 400), +#ifndef FIPS_MODULE + MODP(1536, 200), +#endif + MODP(2048, 225), + MODP(3072, 275), + MODP(4096, 325), + MODP(6144, 375), + MODP(8192, 400), + /* + * Additional dh named groups from RFC 5114 that have a different g. + * The uid can be any unique identifier. + */ +#ifndef FIPS_MODULE + RFC5114("dh_1024_160", 1, 1024, 1024_160), + RFC5114("dh_2048_224", 2, 2048, 2048_224), + RFC5114("dh_2048_256", 3, 2048, 2048_256), +#endif +}; + +const DH_NAMED_GROUP *ossl_ffc_name_to_dh_named_group(const char *name) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { + if (OPENSSL_strcasecmp(dh_named_groups[i].name, name) == 0) + return &dh_named_groups[i]; + } + return NULL; +} + +const DH_NAMED_GROUP *ossl_ffc_uid_to_dh_named_group(int uid) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { + if (dh_named_groups[i].uid == uid) + return &dh_named_groups[i]; + } + return NULL; +} + +#ifndef OPENSSL_NO_DH +const DH_NAMED_GROUP *ossl_ffc_numbers_to_dh_named_group(const BIGNUM *p, + const BIGNUM *q, + const BIGNUM *g) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { + /* Keep searching until a matching p and g is found */ + if (BN_cmp(p, dh_named_groups[i].p) == 0 + && BN_cmp(g, dh_named_groups[i].g) == 0 + /* Verify q is correct if it exists */ + && (q == NULL || BN_cmp(q, dh_named_groups[i].q) == 0)) + return &dh_named_groups[i]; + } + return NULL; +} +#endif + +int ossl_ffc_named_group_get_uid(const DH_NAMED_GROUP *group) +{ + if (group == NULL) + return NID_undef; + return group->uid; +} + +const char *ossl_ffc_named_group_get_name(const DH_NAMED_GROUP *group) +{ + if (group == NULL) + return NULL; + return group->name; +} + +#ifndef OPENSSL_NO_DH +int ossl_ffc_named_group_get_keylength(const DH_NAMED_GROUP *group) +{ + if (group == NULL) + return 0; + return group->keylength; +} + +const BIGNUM *ossl_ffc_named_group_get_q(const DH_NAMED_GROUP *group) +{ + if (group == NULL) + return NULL; + return group->q; +} + +int ossl_ffc_named_group_set(FFC_PARAMS *ffc, const DH_NAMED_GROUP *group) +{ + if (ffc == NULL || group == NULL) + return 0; + + ossl_ffc_params_set0_pqg(ffc, (BIGNUM *)group->p, (BIGNUM *)group->q, + (BIGNUM *)group->g); + ffc->keylength = group->keylength; + + /* flush the cached nid, The DH layer is responsible for caching */ + ffc->nid = NID_undef; + return 1; +} +#endif diff --git a/crypto/openssl/crypto/ffc/ffc_key_generate.c b/crypto/openssl/crypto/ffc/ffc_key_generate.c new file mode 100644 index 000000000000..d02c6575274d --- /dev/null +++ b/crypto/openssl/crypto/ffc/ffc_key_generate.c @@ -0,0 +1,60 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/ffc.h" + +/* + * SP800-56Ar3 5.6.1.1.4 Key pair generation by testing candidates. + * Generates a private key in the interval [1, min(2 ^ N - 1, q - 1)]. + * + * ctx must be set up with a libctx (for fips mode). + * params contains the FFC domain parameters p, q and g (for DH or DSA). + * N is the maximum bit length of the generated private key, + * s is the security strength. + * priv_key is the returned private key, + */ +int ossl_ffc_generate_private_key(BN_CTX *ctx, const FFC_PARAMS *params, + int N, int s, BIGNUM *priv) +{ + int ret = 0, qbits = BN_num_bits(params->q); + BIGNUM *m, *two_powN = NULL; + + /* Deal with the edge cases where the value of N and/or s is not set */ + if (s == 0) + goto err; + if (N == 0) + N = params->keylength ? params->keylength : 2 * s; + + /* Step (2) : check range of N */ + if (N < 2 * s || N > qbits) + return 0; + + two_powN = BN_new(); + /* 2^N */ + if (two_powN == NULL || !BN_lshift(two_powN, BN_value_one(), N)) + goto err; + + /* Step (5) : M = min(2 ^ N, q) */ + m = (BN_cmp(two_powN, params->q) > 0) ? params->q : two_powN; + + do { + /* Steps (3, 4 & 7) : c + 1 = 1 + random[0..2^N - 1] */ + if (!BN_priv_rand_range_ex(priv, two_powN, 0, ctx) + || !BN_add_word(priv, 1)) + goto err; + /* Step (6) : loop if c > M - 2 (i.e. c + 1 >= M) */ + if (BN_cmp(priv, m) < 0) + break; + } while (1); + + ret = 1; +err: + BN_free(two_powN); + return ret; +} diff --git a/crypto/openssl/crypto/ffc/ffc_key_validate.c b/crypto/openssl/crypto/ffc/ffc_key_validate.c new file mode 100644 index 000000000000..342789621d6d --- /dev/null +++ b/crypto/openssl/crypto/ffc/ffc_key_validate.c @@ -0,0 +1,130 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/ffc.h" + +/* + * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Partial public key validation. + * To only be used with ephemeral FFC public keys generated using the approved + * safe-prime groups. (Checks that the public key is in the range [2, p - 1] + * + * ret contains 0 on success, or error flags (see FFC_ERROR_PUBKEY_TOO_SMALL) + */ +int ossl_ffc_validate_public_key_partial(const FFC_PARAMS *params, + const BIGNUM *pub_key, int *ret) +{ + int ok = 0; + BIGNUM *tmp = NULL; + BN_CTX *ctx = NULL; + + *ret = 0; + if (params == NULL || pub_key == NULL || params->p == NULL) { + *ret = FFC_ERROR_PASSED_NULL_PARAM; + return 0; + } + + ctx = BN_CTX_new_ex(NULL); + if (ctx == NULL) + goto err; + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + /* Step(1): Verify pub_key >= 2 */ + if (tmp == NULL + || !BN_set_word(tmp, 1)) + goto err; + if (BN_cmp(pub_key, tmp) <= 0) { + *ret |= FFC_ERROR_PUBKEY_TOO_SMALL; + goto err; + } + /* Step(1): Verify pub_key <= p-2 */ + if (BN_copy(tmp, params->p) == NULL + || !BN_sub_word(tmp, 1)) + goto err; + if (BN_cmp(pub_key, tmp) >= 0) { + *ret |= FFC_ERROR_PUBKEY_TOO_LARGE; + goto err; + } + ok = 1; + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +/* + * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Full public key validation. + */ +int ossl_ffc_validate_public_key(const FFC_PARAMS *params, + const BIGNUM *pub_key, int *ret) +{ + int ok = 0; + BIGNUM *tmp = NULL; + BN_CTX *ctx = NULL; + + if (!ossl_ffc_validate_public_key_partial(params, pub_key, ret)) + return 0; + + if (params->q != NULL) { + ctx = BN_CTX_new_ex(NULL); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + + /* Check pub_key^q == 1 mod p */ + if (tmp == NULL + || !BN_mod_exp(tmp, pub_key, params->q, params->p, ctx)) + goto err; + if (!BN_is_one(tmp)) { + *ret |= FFC_ERROR_PUBKEY_INVALID; + goto err; + } + } + + ok = 1; + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +/* + * See SP800-56Ar3 Section 5.6.2.1.2: Owner assurance of Private key validity. + * Verifies priv_key is in the range [1..upper-1]. The passed in value of upper + * is normally params->q but can be 2^N for approved safe prime groups. + * Note: This assumes that the domain parameters are valid. + */ +int ossl_ffc_validate_private_key(const BIGNUM *upper, const BIGNUM *priv, + int *ret) +{ + int ok = 0; + + *ret = 0; + + if (priv == NULL || upper == NULL) { + *ret = FFC_ERROR_PASSED_NULL_PARAM; + goto err; + } + if (BN_cmp(priv, BN_value_one()) < 0) { + *ret |= FFC_ERROR_PRIVKEY_TOO_SMALL; + goto err; + } + if (BN_cmp(priv, upper) >= 0) { + *ret |= FFC_ERROR_PRIVKEY_TOO_LARGE; + goto err; + } + ok = 1; +err: + return ok; +} diff --git a/crypto/openssl/crypto/ffc/ffc_params.c b/crypto/openssl/crypto/ffc/ffc_params.c new file mode 100644 index 000000000000..fb558f8221f6 --- /dev/null +++ b/crypto/openssl/crypto/ffc/ffc_params.c @@ -0,0 +1,322 @@ +/* + * Copyright 2019-2022 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 /* memset */ +#include +#include "internal/ffc.h" +#include "internal/param_build_set.h" +#include "internal/nelem.h" + +#ifndef FIPS_MODULE +# include /* ossl_ffc_params_print */ +#endif + +void ossl_ffc_params_init(FFC_PARAMS *params) +{ + memset(params, 0, sizeof(*params)); + params->pcounter = -1; + params->gindex = FFC_UNVERIFIABLE_GINDEX; + params->flags = FFC_PARAM_FLAG_VALIDATE_PQG; +} + +void ossl_ffc_params_cleanup(FFC_PARAMS *params) +{ + BN_free(params->p); + BN_free(params->q); + BN_free(params->g); + BN_free(params->j); + OPENSSL_free(params->seed); + ossl_ffc_params_init(params); +} + +void ossl_ffc_params_set0_pqg(FFC_PARAMS *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + if (p != NULL && p != d->p) { + BN_free(d->p); + d->p = p; + } + if (q != NULL && q != d->q) { + BN_free(d->q); + d->q = q; + } + if (g != NULL && g != d->g) { + BN_free(d->g); + d->g = g; + } +} + +void ossl_ffc_params_get0_pqg(const FFC_PARAMS *d, const BIGNUM **p, + const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = d->p; + if (q != NULL) + *q = d->q; + if (g != NULL) + *g = d->g; +} + + +/* j is the 'cofactor' that is optionally output for ASN1. */ +void ossl_ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j) +{ + BN_free(d->j); + d->j = NULL; + if (j != NULL) + d->j = j; +} + +int ossl_ffc_params_set_seed(FFC_PARAMS *params, + const unsigned char *seed, size_t seedlen) +{ + if (params == NULL) + return 0; + + if (params->seed != NULL) { + if (params->seed == seed) + return 1; + OPENSSL_free(params->seed); + } + + if (seed != NULL && seedlen > 0) { + params->seed = OPENSSL_memdup(seed, seedlen); + if (params->seed == NULL) + return 0; + params->seedlen = seedlen; + } else { + params->seed = NULL; + params->seedlen = 0; + } + return 1; +} + +void ossl_ffc_params_set_gindex(FFC_PARAMS *params, int index) +{ + params->gindex = index; +} + +void ossl_ffc_params_set_pcounter(FFC_PARAMS *params, int index) +{ + params->pcounter = index; +} + +void ossl_ffc_params_set_h(FFC_PARAMS *params, int index) +{ + params->h = index; +} + +void ossl_ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags) +{ + params->flags = flags; +} + +void ossl_ffc_params_enable_flags(FFC_PARAMS *params, unsigned int flags, + int enable) +{ + if (enable) + params->flags |= flags; + else + params->flags &= ~flags; +} + +int ossl_ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props) +{ + params->mdname = alg; + params->mdprops = props; + return 1; +} + +int ossl_ffc_params_set_validate_params(FFC_PARAMS *params, + const unsigned char *seed, + size_t seedlen, int counter) +{ + if (!ossl_ffc_params_set_seed(params, seed, seedlen)) + return 0; + params->pcounter = counter; + return 1; +} + +void ossl_ffc_params_get_validate_params(const FFC_PARAMS *params, + unsigned char **seed, size_t *seedlen, + int *pcounter) +{ + if (seed != NULL) + *seed = params->seed; + if (seedlen != NULL) + *seedlen = params->seedlen; + if (pcounter != NULL) + *pcounter = params->pcounter; +} + +static int ffc_bn_cpy(BIGNUM **dst, const BIGNUM *src) +{ + BIGNUM *a; + + /* + * If source is read only just copy the pointer, so + * we don't have to reallocate it. + */ + if (src == NULL) + a = NULL; + else if (BN_get_flags(src, BN_FLG_STATIC_DATA) + && !BN_get_flags(src, BN_FLG_MALLOCED)) + a = (BIGNUM *)src; + else if ((a = BN_dup(src)) == NULL) + return 0; + BN_clear_free(*dst); + *dst = a; + return 1; +} + +int ossl_ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src) +{ + if (!ffc_bn_cpy(&dst->p, src->p) + || !ffc_bn_cpy(&dst->g, src->g) + || !ffc_bn_cpy(&dst->q, src->q) + || !ffc_bn_cpy(&dst->j, src->j)) + return 0; + + OPENSSL_free(dst->seed); + dst->seedlen = src->seedlen; + if (src->seed != NULL) { + dst->seed = OPENSSL_memdup(src->seed, src->seedlen); + if (dst->seed == NULL) + return 0; + } else { + dst->seed = NULL; + } + dst->nid = src->nid; + dst->pcounter = src->pcounter; + dst->h = src->h; + dst->gindex = src->gindex; + dst->flags = src->flags; + dst->keylength = src->keylength; + return 1; +} + +int ossl_ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q) +{ + return BN_cmp(a->p, b->p) == 0 + && BN_cmp(a->g, b->g) == 0 + && (ignore_q || BN_cmp(a->q, b->q) == 0); /* Note: q may be NULL */ +} + +int ossl_ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, + OSSL_PARAM params[]) +{ + int test_flags; + + if (ffc == NULL) + return 0; + + if (ffc->p != NULL + && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_P, ffc->p)) + return 0; + if (ffc->q != NULL + && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_Q, ffc->q)) + return 0; + if (ffc->g != NULL + && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_G, ffc->g)) + return 0; + if (ffc->j != NULL + && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_COFACTOR, + ffc->j)) + return 0; + if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_GINDEX, + ffc->gindex)) + return 0; + if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_PCOUNTER, + ffc->pcounter)) + return 0; + if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_H, ffc->h)) + return 0; + if (ffc->seed != NULL + && !ossl_param_build_set_octet_string(bld, params, + OSSL_PKEY_PARAM_FFC_SEED, + ffc->seed, ffc->seedlen)) + return 0; + if (ffc->nid != NID_undef) { + const DH_NAMED_GROUP *group = ossl_ffc_uid_to_dh_named_group(ffc->nid); + const char *name = ossl_ffc_named_group_get_name(group); + + if (name == NULL + || !ossl_param_build_set_utf8_string(bld, params, + OSSL_PKEY_PARAM_GROUP_NAME, + name)) + return 0; + } + test_flags = ((ffc->flags & FFC_PARAM_FLAG_VALIDATE_PQ) != 0); + if (!ossl_param_build_set_int(bld, params, + OSSL_PKEY_PARAM_FFC_VALIDATE_PQ, test_flags)) + return 0; + test_flags = ((ffc->flags & FFC_PARAM_FLAG_VALIDATE_G) != 0); + if (!ossl_param_build_set_int(bld, params, + OSSL_PKEY_PARAM_FFC_VALIDATE_G, test_flags)) + return 0; + test_flags = ((ffc->flags & FFC_PARAM_FLAG_VALIDATE_LEGACY) != 0); + if (!ossl_param_build_set_int(bld, params, + OSSL_PKEY_PARAM_FFC_VALIDATE_LEGACY, + test_flags)) + return 0; + + if (ffc->mdname != NULL + && !ossl_param_build_set_utf8_string(bld, params, + OSSL_PKEY_PARAM_FFC_DIGEST, + ffc->mdname)) + return 0; + if (ffc->mdprops != NULL + && !ossl_param_build_set_utf8_string(bld, params, + OSSL_PKEY_PARAM_FFC_DIGEST_PROPS, + ffc->mdprops)) + return 0; + return 1; +} + +#ifndef FIPS_MODULE +int ossl_ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent) +{ + if (!ASN1_bn_print(bp, "prime P:", ffc->p, NULL, indent)) + goto err; + if (!ASN1_bn_print(bp, "generator G:", ffc->g, NULL, indent)) + goto err; + if (ffc->q != NULL + && !ASN1_bn_print(bp, "subgroup order Q:", ffc->q, NULL, indent)) + goto err; + if (ffc->j != NULL + && !ASN1_bn_print(bp, "subgroup factor:", ffc->j, NULL, indent)) + goto err; + if (ffc->seed != NULL) { + size_t i; + + if (!BIO_indent(bp, indent, 128) + || BIO_puts(bp, "seed:") <= 0) + goto err; + for (i = 0; i < ffc->seedlen; i++) { + if ((i % 15) == 0) { + if (BIO_puts(bp, "\n") <= 0 + || !BIO_indent(bp, indent + 4, 128)) + goto err; + } + if (BIO_printf(bp, "%02x%s", ffc->seed[i], + ((i + 1) == ffc->seedlen) ? "" : ":") <= 0) + goto err; + } + if (BIO_write(bp, "\n", 1) <= 0) + return 0; + } + if (ffc->pcounter != -1) { + if (!BIO_indent(bp, indent, 128) + || BIO_printf(bp, "counter: %d\n", ffc->pcounter) <= 0) + goto err; + } + return 1; +err: + return 0; +} +#endif /* FIPS_MODULE */ diff --git a/crypto/openssl/crypto/ffc/ffc_params_generate.c b/crypto/openssl/crypto/ffc/ffc_params_generate.c new file mode 100644 index 000000000000..6b018edfffce --- /dev/null +++ b/crypto/openssl/crypto/ffc/ffc_params_generate.c @@ -0,0 +1,1057 @@ +/* + * Copyright 2019-2023 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 + */ + +/* + * For the prime check.. + * FIPS 186-4 Section C.3 Table C.1 + * Returns the minimum number of Miller Rabin iterations for a L,N pair + * (where L = len(p), N = len(q)) + * L N Min + * 1024 160 40 + * 2048 224 56 + * 2048 256 56 + * 3072 256 64 + * + * BN_check_prime() uses: + * 64 iterations for L <= 2048 OR + * 128 iterations for L > 2048 + * So this satisfies the requirement. + */ + +#include /* memset */ +#include /* SHA_DIGEST_LENGTH */ +#include +#include +#include +#include +#include "crypto/bn.h" +#include "internal/ffc.h" + +/* + * Verify that the passed in L, N pair for DH or DSA is valid. + * Returns 0 if invalid, otherwise it returns the security strength. + */ + +#ifdef FIPS_MODULE +static int ffc_validate_LN(size_t L, size_t N, int type, int verify) +{ + if (type == FFC_PARAM_TYPE_DH) { + /* Valid DH L,N parameters from SP800-56Ar3 5.5.1 Table 1 */ + if (L == 2048 && (N == 224 || N == 256)) + return 112; +# ifndef OPENSSL_NO_DH + ERR_raise(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS); +# endif + } else if (type == FFC_PARAM_TYPE_DSA) { + /* Valid DSA L,N parameters from FIPS 186-4 Section 4.2 */ + /* In fips mode 1024/160 can only be used for verification */ + if (verify && L == 1024 && N == 160) + return 80; + if (L == 2048 && (N == 224 || N == 256)) + return 112; + if (L == 3072 && N == 256) + return 128; +# ifndef OPENSSL_NO_DSA + ERR_raise(ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS); +# endif + } + return 0; +} +#else +static int ffc_validate_LN(size_t L, size_t N, int type, int verify) +{ + if (type == FFC_PARAM_TYPE_DH) { + /* Allow legacy 1024/160 in non fips mode */ + if (L == 1024 && N == 160) + return 80; + /* Valid DH L,N parameters from SP800-56Ar3 5.5.1 Table 1 */ + if (L == 2048 && (N == 224 || N == 256)) + return 112; +# ifndef OPENSSL_NO_DH + ERR_raise(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS); +# endif + } else if (type == FFC_PARAM_TYPE_DSA) { + if (L >= 3072 && N >= 256) + return 128; + if (L >= 2048 && N >= 224) + return 112; + if (L >= 1024 && N >= 160) + return 80; +# ifndef OPENSSL_NO_DSA + ERR_raise(ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS); +# endif + } + return 0; +} +#endif /* FIPS_MODULE */ + +/* FIPS186-4 A.2.1 Unverifiable Generation of Generator g */ +static int generate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, BIGNUM *g, + BIGNUM *hbn, const BIGNUM *p, + const BIGNUM *e,const BIGNUM *pm1, + int *hret) +{ + int h = 2; + + /* Step (2): choose h (where 1 < h)*/ + if (!BN_set_word(hbn, h)) + return 0; + + for (;;) { + /* Step (3): g = h^e % p */ + if (!BN_mod_exp_mont(g, hbn, e, p, ctx, mont)) + return 0; + /* Step (4): Finish if g > 1 */ + if (BN_cmp(g, BN_value_one()) > 0) + break; + + /* Step (2) Choose any h in the range 1 < h < (p-1) */ + if (!BN_add_word(hbn, 1) || BN_cmp(hbn, pm1) >= 0) + return 0; + ++h; + } + *hret = h; + return 1; +} + +/* + * FIPS186-4 A.2 Generation of canonical generator g. + * + * It requires the following values as input: + * 'evpmd' digest, 'p' prime, 'e' cofactor, gindex and seed. + * tmp is a passed in temporary BIGNUM. + * mont is used in a BN_mod_exp_mont() with a modulus of p. + * Returns a value in g. + */ +static int generate_canonical_g(BN_CTX *ctx, BN_MONT_CTX *mont, + const EVP_MD *evpmd, BIGNUM *g, BIGNUM *tmp, + const BIGNUM *p, const BIGNUM *e, + int gindex, unsigned char *seed, size_t seedlen) +{ + int ret = 0; + int counter = 1; + unsigned char md[EVP_MAX_MD_SIZE]; + EVP_MD_CTX *mctx = NULL; + int mdsize; + + mdsize = EVP_MD_get_size(evpmd); + if (mdsize <= 0) + return 0; + + mctx = EVP_MD_CTX_new(); + if (mctx == NULL) + return 0; + + /* + * A.2.3 Step (4) & (5) + * A.2.4 Step (6) & (7) + * counter = 0; counter += 1 + */ + for (counter = 1; counter <= 0xFFFF; ++counter) { + /* + * A.2.3 Step (7) & (8) & (9) + * A.2.4 Step (9) & (10) & (11) + * W = Hash(seed || "ggen" || index || counter) + * g = W^e % p + */ + static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e }; + + md[0] = (unsigned char)(gindex & 0xff); + md[1] = (unsigned char)((counter >> 8) & 0xff); + md[2] = (unsigned char)(counter & 0xff); + if (!EVP_DigestInit_ex(mctx, evpmd, NULL) + || !EVP_DigestUpdate(mctx, seed, seedlen) + || !EVP_DigestUpdate(mctx, ggen, sizeof(ggen)) + || !EVP_DigestUpdate(mctx, md, 3) + || !EVP_DigestFinal_ex(mctx, md, NULL) + || (BN_bin2bn(md, mdsize, tmp) == NULL) + || !BN_mod_exp_mont(g, tmp, e, p, ctx, mont)) + break; /* exit on failure */ + /* + * A.2.3 Step (10) + * A.2.4 Step (12) + * Found a value for g if (g >= 2) + */ + if (BN_cmp(g, BN_value_one()) > 0) { + ret = 1; + break; /* found g */ + } + } + EVP_MD_CTX_free(mctx); + return ret; +} + +/* Generation of p is the same for FIPS 186-4 & FIPS 186-2 */ +static int generate_p(BN_CTX *ctx, const EVP_MD *evpmd, int max_counter, int n, + unsigned char *buf, size_t buf_len, const BIGNUM *q, + BIGNUM *p, int L, BN_GENCB *cb, int *counter, + int *res) +{ + int ret = -1; + int i, j, k, r; + unsigned char md[EVP_MAX_MD_SIZE]; + int mdsize; + BIGNUM *W, *X, *tmp, *c, *test; + + BN_CTX_start(ctx); + W = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + c = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + + if (!BN_lshift(test, BN_value_one(), L - 1)) + goto err; + + mdsize = EVP_MD_get_size(evpmd); + if (mdsize <= 0) + goto err; + + /* A.1.1.2 Step (10) AND + * A.1.1.2 Step (12) + * offset = 1 (this is handled below) + */ + /* + * A.1.1.2 Step (11) AND + * A.1.1.3 Step (13) + */ + for (i = 0; i <= max_counter; i++) { + if ((i != 0) && !BN_GENCB_call(cb, 0, i)) + goto err; + + BN_zero(W); + /* seed_tmp buffer contains "seed + offset - 1" */ + for (j = 0; j <= n; j++) { + /* obtain "seed + offset + j" by incrementing by 1: */ + for (k = (int)buf_len - 1; k >= 0; k--) { + buf[k]++; + if (buf[k] != 0) + break; + } + /* + * A.1.1.2 Step (11.1) AND + * A.1.1.3 Step (13.1) + * tmp = V(j) = Hash((seed + offset + j) % 2^seedlen) + */ + if (!EVP_Digest(buf, buf_len, md, NULL, evpmd, NULL) + || (BN_bin2bn(md, mdsize, tmp) == NULL) + /* + * A.1.1.2 Step (11.2) + * A.1.1.3 Step (13.2) + * W += V(j) * 2^(outlen * j) + */ + || !BN_lshift(tmp, tmp, (mdsize << 3) * j) + || !BN_add(W, W, tmp)) + goto err; + } + + /* + * A.1.1.2 Step (11.3) AND + * A.1.1.3 Step (13.3) + * X = W + 2^(L-1) where W < 2^(L-1) + */ + if (!BN_mask_bits(W, L - 1) + || !BN_copy(X, W) + || !BN_add(X, X, test) + /* + * A.1.1.2 Step (11.4) AND + * A.1.1.3 Step (13.4) + * c = X mod 2q + */ + || !BN_lshift1(tmp, q) + || !BN_mod(c, X, tmp, ctx) + /* + * A.1.1.2 Step (11.5) AND + * A.1.1.3 Step (13.5) + * p = X - (c - 1) + */ + || !BN_sub(tmp, c, BN_value_one()) + || !BN_sub(p, X, tmp)) + goto err; + + /* + * A.1.1.2 Step (11.6) AND + * A.1.1.3 Step (13.6) + * if (p < 2 ^ (L-1)) continue + * This makes sure the top bit is set. + */ + if (BN_cmp(p, test) >= 0) { + /* + * A.1.1.2 Step (11.7) AND + * A.1.1.3 Step (13.7) + * Test if p is prime + * (This also makes sure the bottom bit is set) + */ + r = BN_check_prime(p, ctx, cb); + /* A.1.1.2 Step (11.8) : Return if p is prime */ + if (r > 0) { + *counter = i; + ret = 1; /* return success */ + goto err; + } + if (r != 0) + goto err; + } + /* Step (11.9) : offset = offset + n + 1 is done auto-magically */ + } + /* No prime P found */ + ret = 0; + *res |= FFC_CHECK_P_NOT_PRIME; +err: + BN_CTX_end(ctx); + return ret; +} + +static int generate_q_fips186_4(BN_CTX *ctx, BIGNUM *q, const EVP_MD *evpmd, + int qsize, unsigned char *seed, size_t seedlen, + int generate_seed, int *retm, int *res, + BN_GENCB *cb) +{ + int ret = 0, r; + int m = *retm; + unsigned char md[EVP_MAX_MD_SIZE]; + int mdsize = EVP_MD_get_size(evpmd); + unsigned char *pmd; + OSSL_LIB_CTX *libctx = ossl_bn_get_libctx(ctx); + + /* find q */ + for (;;) { + if(!BN_GENCB_call(cb, 0, m++)) + goto err; + + /* A.1.1.2 Step (5) : generate seed with size seed_len */ + if (generate_seed + && RAND_bytes_ex(libctx, seed, seedlen, 0) <= 0) + goto err; + /* + * A.1.1.2 Step (6) AND + * A.1.1.3 Step (7) + * U = Hash(seed) % (2^(N-1)) + */ + if (!EVP_Digest(seed, seedlen, md, NULL, evpmd, NULL)) + goto err; + /* Take least significant bits of md */ + if (mdsize > qsize) + pmd = md + mdsize - qsize; + else + pmd = md; + if (mdsize < qsize) + memset(md + mdsize, 0, qsize - mdsize); + + /* + * A.1.1.2 Step (7) AND + * A.1.1.3 Step (8) + * q = U + 2^(N-1) + (1 - U %2) (This sets top and bottom bits) + */ + pmd[0] |= 0x80; + pmd[qsize-1] |= 0x01; + if (!BN_bin2bn(pmd, qsize, q)) + goto err; + + /* + * A.1.1.2 Step (8) AND + * A.1.1.3 Step (9) + * Test if q is prime + */ + r = BN_check_prime(q, ctx, cb); + if (r > 0) { + ret = 1; + goto err; + } + /* + * A.1.1.3 Step (9) : If the provided seed didn't produce a prime q + * return an error. + */ + if (!generate_seed) { + *res |= FFC_CHECK_Q_NOT_PRIME; + goto err; + } + if (r != 0) + goto err; + /* A.1.1.2 Step (9) : if q is not prime, try another q */ + } +err: + *retm = m; + return ret; +} + +static int generate_q_fips186_2(BN_CTX *ctx, BIGNUM *q, const EVP_MD *evpmd, + unsigned char *buf, unsigned char *seed, + size_t qsize, int generate_seed, int *retm, + int *res, BN_GENCB *cb) +{ + unsigned char buf2[EVP_MAX_MD_SIZE]; + unsigned char md[EVP_MAX_MD_SIZE]; + int i, r, ret = 0, m = *retm; + OSSL_LIB_CTX *libctx = ossl_bn_get_libctx(ctx); + + /* find q */ + for (;;) { + /* step 1 */ + if (!BN_GENCB_call(cb, 0, m++)) + goto err; + + if (generate_seed && RAND_bytes_ex(libctx, seed, qsize, 0) <= 0) + goto err; + + memcpy(buf, seed, qsize); + memcpy(buf2, seed, qsize); + + /* precompute "SEED + 1" for step 7: */ + for (i = (int)qsize - 1; i >= 0; i--) { + buf[i]++; + if (buf[i] != 0) + break; + } + + /* step 2 */ + if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) + goto err; + if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) + goto err; + for (i = 0; i < (int)qsize; i++) + md[i] ^= buf2[i]; + + /* step 3 */ + md[0] |= 0x80; + md[qsize - 1] |= 0x01; + if (!BN_bin2bn(md, (int)qsize, q)) + goto err; + + /* step 4 */ + r = BN_check_prime(q, ctx, cb); + if (r > 0) { + /* Found a prime */ + ret = 1; + goto err; + } + if (r != 0) + goto err; /* Exit if error */ + /* Try another iteration if it wasnt prime - was in old code.. */ + generate_seed = 1; + } +err: + *retm = m; + return ret; +} + +static const char *default_mdname(size_t N) +{ + if (N == 160) + return "SHA1"; + else if (N == 224) + return "SHA-224"; + else if (N == 256) + return "SHA-256"; + return NULL; +} + +/* + * FIPS 186-4 FFC parameter generation (as defined in Appendix A). + * The same code is used for validation (when validate_flags != 0) + * + * The primes p & q are generated/validated using: + * A.1.1.2 Generation of probable primes p & q using approved hash. + * A.1.1.3 Validation of generated probable primes + * + * Generator 'g' has 2 types in FIPS 186-4: + * (1) A.2.1 unverifiable generation of generator g. + * A.2.2 Assurance of the validity of unverifiable generator g. + * (2) A.2.3 Verifiable Canonical Generation of the generator g. + * A.2.4 Validation for Canonical Generation of the generator g. + * + * Notes: + * (1) is only a partial validation of g, The validation of (2) requires + * the seed and index used during generation as input. + * + * params: used to pass in values for generation and validation. + * params->md: is the digest to use, If this value is NULL, then the digest is + * chosen using the value of N. + * params->flags: + * For validation one of: + * -FFC_PARAM_FLAG_VALIDATE_PQ + * -FFC_PARAM_FLAG_VALIDATE_G + * -FFC_PARAM_FLAG_VALIDATE_PQG + * For generation of p & q: + * - This is skipped if p & q are passed in. + * - If the seed is passed in then generation of p & q uses this seed (and if + * this fails an error will occur). + * - Otherwise the seed is generated, and values of p & q are generated and + * the value of seed and counter are optionally returned. + * For the generation of g (after the generation of p, q): + * - If the seed has been generated or passed in and a valid gindex is passed + * in then canonical generation of g is used otherwise unverifiable + * generation of g is chosen. + * For validation of p & q: + * - p, q, and the seed and counter used for generation must be passed in. + * For validation of g: + * - For a partial validation : p, q and g are required. + * - For a canonical validation : the gindex and seed used for generation are + * also required. + * mode: The mode - either FFC_PARAM_MODE_GENERATE or FFC_PARAM_MODE_VERIFY. + * type: The key type - FFC_PARAM_TYPE_DSA or FFC_PARAM_TYPE_DH. + * L: is the size of the prime p in bits (e.g 2048) + * N: is the size of the prime q in bits (e.g 256) + * res: A returned failure reason (One of FFC_CHECK_XXXX), + * or 0 for general failures. + * cb: A callback (can be NULL) that is called during different phases + * + * Returns: + * - FFC_PARAM_RET_STATUS_FAILED: if there was an error, or validation failed. + * - FFC_PARAM_RET_STATUS_SUCCESS if the generation or validation succeeded. + * - FFC_PARAM_RET_STATUS_UNVERIFIABLE_G if the validation of G succeeded, + * but G is unverifiable. + */ +int ossl_ffc_params_FIPS186_4_gen_verify(OSSL_LIB_CTX *libctx, + FFC_PARAMS *params, int mode, int type, + size_t L, size_t N, int *res, + BN_GENCB *cb) +{ + int ok = FFC_PARAM_RET_STATUS_FAILED; + unsigned char *seed = NULL, *seed_tmp = NULL; + int mdsize, counter = 0, pcounter = 0, r = 0; + size_t seedlen = 0; + BIGNUM *tmp, *pm1, *e, *test; + BIGNUM *g = NULL, *q = NULL, *p = NULL; + BN_MONT_CTX *mont = NULL; + int n = 0, m = 0, qsize; + int canonical_g = 0, hret = 0; + BN_CTX *ctx = NULL; + EVP_MD_CTX *mctx = NULL; + EVP_MD *md = NULL; + int verify = (mode == FFC_PARAM_MODE_VERIFY); + unsigned int flags = verify ? params->flags : 0; + const char *def_name; + + *res = 0; + + if (params->mdname != NULL) { + md = EVP_MD_fetch(libctx, params->mdname, params->mdprops); + } else { + if (N == 0) + N = (L >= 2048 ? SHA256_DIGEST_LENGTH : SHA_DIGEST_LENGTH) * 8; + def_name = default_mdname(N); + if (def_name == NULL) { + *res = FFC_CHECK_INVALID_Q_VALUE; + goto err; + } + md = EVP_MD_fetch(libctx, def_name, params->mdprops); + } + if (md == NULL) + goto err; + mdsize = EVP_MD_get_size(md); + if (mdsize <= 0) + goto err; + + if (N == 0) + N = mdsize * 8; + qsize = N >> 3; + + /* + * A.1.1.2 Step (1) AND + * A.1.1.3 Step (3) + * Check that the L,N pair is an acceptable pair. + */ + if (L <= N || !ffc_validate_LN(L, N, type, verify)) { + *res = FFC_CHECK_BAD_LN_PAIR; + goto err; + } + + mctx = EVP_MD_CTX_new(); + if (mctx == NULL) + goto err; + + if ((ctx = BN_CTX_new_ex(libctx)) == NULL) + goto err; + + BN_CTX_start(ctx); + g = BN_CTX_get(ctx); + pm1 = BN_CTX_get(ctx); + e = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + + seedlen = params->seedlen; + if (seedlen == 0) + seedlen = (size_t)mdsize; + /* If the seed was passed in - use this value as the seed */ + if (params->seed != NULL) + seed = params->seed; + + if (!verify) { + /* For generation: p & q must both be NULL or NON-NULL */ + if ((params->p == NULL) != (params->q == NULL)) { + *res = FFC_CHECK_INVALID_PQ; + goto err; + } + } else { + /* Validation of p,q requires seed and counter to be valid */ + if ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) != 0) { + if (seed == NULL || params->pcounter < 0) { + *res = FFC_CHECK_MISSING_SEED_OR_COUNTER; + goto err; + } + } + if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) { + /* validation of g also requires g to be set */ + if (params->g == NULL) { + *res = FFC_CHECK_INVALID_G; + goto err; + } + } + } + + /* + * If p & q are passed in and + * validate_flags = 0 then skip the generation of PQ. + * validate_flags = VALIDATE_G then also skip the validation of PQ. + */ + if (params->p != NULL && ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) == 0)) { + /* p and q already exists so only generate g */ + p = params->p; + q = params->q; + goto g_only; + /* otherwise fall thru to validate p & q */ + } + + /* p & q will be used for generation and validation */ + p = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + if (q == NULL) + goto err; + + /* + * A.1.1.2 Step (2) AND + * A.1.1.3 Step (6) + * Return invalid if seedlen < N + */ + if ((seedlen * 8) < N) { + *res = FFC_CHECK_INVALID_SEED_SIZE; + goto err; + } + + seed_tmp = OPENSSL_malloc(seedlen); + if (seed_tmp == NULL) + goto err; + + if (seed == NULL) { + /* Validation requires the seed to be supplied */ + if (verify) { + *res = FFC_CHECK_MISSING_SEED_OR_COUNTER; + goto err; + } + /* if the seed is not supplied then alloc a seed buffer */ + seed = OPENSSL_malloc(seedlen); + if (seed == NULL) + goto err; + } + + /* A.1.1.2 Step (11): max loop count = 4L - 1 */ + counter = 4 * L - 1; + /* Validation requires the counter to be supplied */ + if (verify) { + /* A.1.1.3 Step (4) : if (counter > (4L -1)) return INVALID */ + if (params->pcounter > counter) { + *res = FFC_CHECK_INVALID_COUNTER; + goto err; + } + counter = params->pcounter; + } + + /* + * A.1.1.2 Step (3) AND + * A.1.1.3 Step (10) + * n = floor(L / hash_outlen) - 1 + */ + n = (L - 1 ) / (mdsize << 3); + + /* Calculate 2^(L-1): Used in step A.1.1.2 Step (11.3) */ + if (!BN_lshift(test, BN_value_one(), L - 1)) + goto err; + + for (;;) { + if (!generate_q_fips186_4(ctx, q, md, qsize, seed, seedlen, + seed != params->seed, &m, res, cb)) + goto err; + /* A.1.1.3 Step (9): Verify that q matches the expected value */ + if (verify && (BN_cmp(q, params->q) != 0)) { + *res = FFC_CHECK_Q_MISMATCH; + goto err; + } + if(!BN_GENCB_call(cb, 2, 0)) + goto err; + if(!BN_GENCB_call(cb, 3, 0)) + goto err; + + memcpy(seed_tmp, seed, seedlen); + r = generate_p(ctx, md, counter, n, seed_tmp, seedlen, q, p, L, + cb, &pcounter, res); + if (r > 0) + break; /* found p */ + if (r < 0) + goto err; + /* + * A.1.1.3 Step (14): + * If we get here we failed to get a p for the given seed. If the + * seed is not random then it needs to fail (as it will always fail). + */ + if (seed == params->seed) { + *res = FFC_CHECK_P_NOT_PRIME; + goto err; + } + } + if(!BN_GENCB_call(cb, 2, 1)) + goto err; + /* + * Gets here if we found p. + * A.1.1.3 Step (14): return error if i != counter OR computed_p != known_p. + */ + if (verify && (pcounter != counter || (BN_cmp(p, params->p) != 0))) + goto err; + + /* If validating p & q only then skip the g validation test */ + if ((flags & FFC_PARAM_FLAG_VALIDATE_PQG) == FFC_PARAM_FLAG_VALIDATE_PQ) + goto pass; +g_only: + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, p, ctx)) + goto err; + + if (((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) + && !ossl_ffc_params_validate_unverifiable_g(ctx, mont, p, q, params->g, + tmp, res)) + goto err; + + /* + * A.2.1 Step (1) AND + * A.2.3 Step (3) AND + * A.2.4 Step (5) + * e = (p - 1) / q (i.e- Cofactor 'e' is given by p = q * e + 1) + */ + if (!(BN_sub(pm1, p, BN_value_one()) && BN_div(e, NULL, pm1, q, ctx))) + goto err; + + /* Canonical g requires a seed and index to be set */ + if ((seed != NULL) && (params->gindex != FFC_UNVERIFIABLE_GINDEX)) { + canonical_g = 1; + if (!generate_canonical_g(ctx, mont, md, g, tmp, p, e, + params->gindex, seed, seedlen)) { + *res = FFC_CHECK_INVALID_G; + goto err; + } + /* A.2.4 Step (13): Return valid if computed_g == g */ + if (verify && BN_cmp(g, params->g) != 0) { + *res = FFC_CHECK_G_MISMATCH; + goto err; + } + } else if (!verify) { + if (!generate_unverifiable_g(ctx, mont, g, tmp, p, e, pm1, &hret)) + goto err; + } + + if (!BN_GENCB_call(cb, 3, 1)) + goto err; + + if (!verify) { + if (p != params->p) { + BN_free(params->p); + params->p = BN_dup(p); + } + if (q != params->q) { + BN_free(params->q); + params->q = BN_dup(q); + } + if (g != params->g) { + BN_free(params->g); + params->g = BN_dup(g); + } + if (params->p == NULL || params->q == NULL || params->g == NULL) + goto err; + if (!ossl_ffc_params_set_validate_params(params, seed, seedlen, + pcounter)) + goto err; + params->h = hret; + } +pass: + if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0 && (canonical_g == 0)) + /* Return for the case where g is partially valid */ + ok = FFC_PARAM_RET_STATUS_UNVERIFIABLE_G; + else + ok = FFC_PARAM_RET_STATUS_SUCCESS; +err: + if (seed != params->seed) + OPENSSL_free(seed); + OPENSSL_free(seed_tmp); + if (ctx != NULL) + BN_CTX_end(ctx); + BN_CTX_free(ctx); + BN_MONT_CTX_free(mont); + EVP_MD_CTX_free(mctx); + EVP_MD_free(md); + return ok; +} + +/* Note this function is only used for verification in fips mode */ +int ossl_ffc_params_FIPS186_2_gen_verify(OSSL_LIB_CTX *libctx, + FFC_PARAMS *params, int mode, int type, + size_t L, size_t N, int *res, + BN_GENCB *cb) +{ + int ok = FFC_PARAM_RET_STATUS_FAILED; + unsigned char seed[SHA256_DIGEST_LENGTH]; + unsigned char buf[SHA256_DIGEST_LENGTH]; + BIGNUM *r0, *test, *tmp, *g = NULL, *q = NULL, *p = NULL; + BN_MONT_CTX *mont = NULL; + EVP_MD *md = NULL; + size_t qsize; + int n = 0, m = 0; + int counter = 0, pcounter = 0, use_random_seed; + int rv; + BN_CTX *ctx = NULL; + int hret = -1; + unsigned char *seed_in = params->seed; + size_t seed_len = params->seedlen; + int verify = (mode == FFC_PARAM_MODE_VERIFY); + unsigned int flags = verify ? params->flags : 0; + const char *def_name; + + *res = 0; + + if (params->mdname != NULL) { + md = EVP_MD_fetch(libctx, params->mdname, params->mdprops); + } else { + if (N == 0) + N = (L >= 2048 ? SHA256_DIGEST_LENGTH : SHA_DIGEST_LENGTH) * 8; + def_name = default_mdname(N); + if (def_name == NULL) { + *res = FFC_CHECK_INVALID_Q_VALUE; + goto err; + } + md = EVP_MD_fetch(libctx, def_name, params->mdprops); + } + if (md == NULL) + goto err; + if (N == 0) + N = EVP_MD_get_size(md) * 8; + qsize = N >> 3; + + /* + * The original spec allowed L = 512 + 64*j (j = 0.. 8) + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf + * says that 512 can be used for legacy verification. + */ + if (L < 512) { + *res = FFC_CHECK_BAD_LN_PAIR; + goto err; + } + if (qsize != SHA_DIGEST_LENGTH + && qsize != SHA224_DIGEST_LENGTH + && qsize != SHA256_DIGEST_LENGTH) { + /* invalid q size */ + *res = FFC_CHECK_INVALID_Q_VALUE; + goto err; + } + + L = (L + 63) / 64 * 64; + + if (seed_in != NULL) { + if (seed_len < qsize) { + *res = FFC_CHECK_INVALID_SEED_SIZE; + goto err; + } + /* Only consume as much seed as is expected. */ + if (seed_len > qsize) + seed_len = qsize; + memcpy(seed, seed_in, seed_len); + } + + ctx = BN_CTX_new_ex(libctx); + if (ctx == NULL) + goto err; + + BN_CTX_start(ctx); + + r0 = BN_CTX_get(ctx); + g = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + p = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + if (test == NULL) + goto err; + + if (!BN_lshift(test, BN_value_one(), L - 1)) + goto err; + + if (!verify) { + /* For generation: p & q must both be NULL or NON-NULL */ + if ((params->p != NULL) != (params->q != NULL)) { + *res = FFC_CHECK_INVALID_PQ; + goto err; + } + } else { + if ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) != 0) { + /* Validation of p,q requires seed and counter to be valid */ + if (seed_in == NULL || params->pcounter < 0) { + *res = FFC_CHECK_MISSING_SEED_OR_COUNTER; + goto err; + } + } + if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) { + /* validation of g also requires g to be set */ + if (params->g == NULL) { + *res = FFC_CHECK_INVALID_G; + goto err; + } + } + } + + if (params->p != NULL && ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) == 0)) { + /* p and q already exists so only generate g */ + p = params->p; + q = params->q; + goto g_only; + /* otherwise fall thru to validate p and q */ + } + + use_random_seed = (seed_in == NULL); + for (;;) { + if (!generate_q_fips186_2(ctx, q, md, buf, seed, qsize, + use_random_seed, &m, res, cb)) + goto err; + + if (!BN_GENCB_call(cb, 2, 0)) + goto err; + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + + /* step 6 */ + n = (L - 1) / 160; + counter = 4 * L - 1; /* Was 4096 */ + /* Validation requires the counter to be supplied */ + if (verify) { + if (params->pcounter > counter) { + *res = FFC_CHECK_INVALID_COUNTER; + goto err; + } + counter = params->pcounter; + } + + rv = generate_p(ctx, md, counter, n, buf, qsize, q, p, L, cb, + &pcounter, res); + if (rv > 0) + break; /* found it */ + if (rv == -1) + goto err; + /* This is what the old code did - probably not a good idea! */ + use_random_seed = 1; + } + + if (!BN_GENCB_call(cb, 2, 1)) + goto err; + + if (verify) { + if (pcounter != counter) { + *res = FFC_CHECK_COUNTER_MISMATCH; + goto err; + } + if (BN_cmp(p, params->p) != 0) { + *res = FFC_CHECK_P_MISMATCH; + goto err; + } + } + /* If validating p & q only then skip the g validation test */ + if ((flags & FFC_PARAM_FLAG_VALIDATE_PQG) == FFC_PARAM_FLAG_VALIDATE_PQ) + goto pass; +g_only: + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, p, ctx)) + goto err; + + if (!verify) { + /* We now need to generate g */ + /* set test = p - 1 */ + if (!BN_sub(test, p, BN_value_one())) + goto err; + /* Set r0 = (p - 1) / q */ + if (!BN_div(r0, NULL, test, q, ctx)) + goto err; + if (!generate_unverifiable_g(ctx, mont, g, tmp, p, r0, test, &hret)) + goto err; + } else if (((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) + && !ossl_ffc_params_validate_unverifiable_g(ctx, mont, p, q, + params->g, tmp, + res)) { + goto err; + } + + if (!BN_GENCB_call(cb, 3, 1)) + goto err; + + if (!verify) { + if (p != params->p) { + BN_free(params->p); + params->p = BN_dup(p); + } + if (q != params->q) { + BN_free(params->q); + params->q = BN_dup(q); + } + if (g != params->g) { + BN_free(params->g); + params->g = BN_dup(g); + } + if (params->p == NULL || params->q == NULL || params->g == NULL) + goto err; + if (!ossl_ffc_params_set_validate_params(params, seed, qsize, pcounter)) + goto err; + params->h = hret; + } +pass: + if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) + ok = FFC_PARAM_RET_STATUS_UNVERIFIABLE_G; + else + ok = FFC_PARAM_RET_STATUS_SUCCESS; +err: + if (ctx != NULL) + BN_CTX_end(ctx); + BN_CTX_free(ctx); + BN_MONT_CTX_free(mont); + EVP_MD_free(md); + return ok; +} + +int ossl_ffc_params_FIPS186_4_generate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type, size_t L, size_t N, + int *res, BN_GENCB *cb) +{ + return ossl_ffc_params_FIPS186_4_gen_verify(libctx, params, + FFC_PARAM_MODE_GENERATE, + type, L, N, res, cb); +} + +/* This should no longer be used in FIPS mode */ +int ossl_ffc_params_FIPS186_2_generate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type, size_t L, size_t N, + int *res, BN_GENCB *cb) +{ + if (!ossl_ffc_params_FIPS186_2_gen_verify(libctx, params, + FFC_PARAM_MODE_GENERATE, + type, L, N, res, cb)) + return 0; + + ossl_ffc_params_enable_flags(params, FFC_PARAM_FLAG_VALIDATE_LEGACY, 1); + return 1; +} diff --git a/crypto/openssl/crypto/ffc/ffc_params_validate.c b/crypto/openssl/crypto/ffc/ffc_params_validate.c new file mode 100644 index 000000000000..c1b4cf05d200 --- /dev/null +++ b/crypto/openssl/crypto/ffc/ffc_params_validate.c @@ -0,0 +1,187 @@ +/* + * Copyright 2019-2021 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 + */ + +/* + * Finite Field cryptography (FFC) is used for DSA and DH. + * This file contains methods for validation of FFC parameters. + * It calls the same functions as the generation as the code is very similar. + */ + +#include +#include +#include +#include +#include "internal/ffc.h" + +/* FIPS186-4 A.2.2 Unverifiable partial validation of Generator g */ +int ossl_ffc_params_validate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, + const BIGNUM *p, const BIGNUM *q, + const BIGNUM *g, BIGNUM *tmp, + int *ret) +{ + /* + * A.2.2 Step (1) AND + * A.2.4 Step (2) + * Verify that 2 <= g <= (p - 1) + */ + if (BN_cmp(g, BN_value_one()) <= 0 || BN_cmp(g, p) >= 0) { + *ret |= FFC_ERROR_NOT_SUITABLE_GENERATOR; + return 0; + } + + /* + * A.2.2 Step (2) AND + * A.2.4 Step (3) + * Check g^q mod p = 1 + */ + if (!BN_mod_exp_mont(tmp, g, q, p, ctx, mont)) + return 0; + if (BN_cmp(tmp, BN_value_one()) != 0) { + *ret |= FFC_ERROR_NOT_SUITABLE_GENERATOR; + return 0; + } + return 1; +} + +int ossl_ffc_params_FIPS186_4_validate(OSSL_LIB_CTX *libctx, + const FFC_PARAMS *params, int type, + int *res, BN_GENCB *cb) +{ + size_t L, N; + + if (params == NULL || params->p == NULL || params->q == NULL) + return FFC_PARAM_RET_STATUS_FAILED; + + /* A.1.1.3 Step (1..2) : L = len(p), N = len(q) */ + L = BN_num_bits(params->p); + N = BN_num_bits(params->q); + return ossl_ffc_params_FIPS186_4_gen_verify(libctx, (FFC_PARAMS *)params, + FFC_PARAM_MODE_VERIFY, type, + L, N, res, cb); +} + +/* This may be used in FIPS mode to validate deprecated FIPS-186-2 Params */ +int ossl_ffc_params_FIPS186_2_validate(OSSL_LIB_CTX *libctx, + const FFC_PARAMS *params, int type, + int *res, BN_GENCB *cb) +{ + size_t L, N; + + if (params == NULL || params->p == NULL || params->q == NULL) { + *res = FFC_CHECK_INVALID_PQ; + return FFC_PARAM_RET_STATUS_FAILED; + } + + /* A.1.1.3 Step (1..2) : L = len(p), N = len(q) */ + L = BN_num_bits(params->p); + N = BN_num_bits(params->q); + return ossl_ffc_params_FIPS186_2_gen_verify(libctx, (FFC_PARAMS *)params, + FFC_PARAM_MODE_VERIFY, type, + L, N, res, cb); +} + +/* + * This does a simple check of L and N and partial g. + * It makes no attempt to do a full validation of p, q or g since these require + * extra parameters such as the digest and seed, which may not be available for + * this test. + */ +int ossl_ffc_params_simple_validate(OSSL_LIB_CTX *libctx, const FFC_PARAMS *params, + int paramstype, int *res) +{ + int ret; + int tmpres = 0; + FFC_PARAMS tmpparams = {0}; + + if (params == NULL) + return 0; + + if (res == NULL) + res = &tmpres; + + if (!ossl_ffc_params_copy(&tmpparams, params)) + return 0; + + tmpparams.flags = FFC_PARAM_FLAG_VALIDATE_G; + tmpparams.gindex = FFC_UNVERIFIABLE_GINDEX; + +#ifndef FIPS_MODULE + if (params->flags & FFC_PARAM_FLAG_VALIDATE_LEGACY) + ret = ossl_ffc_params_FIPS186_2_validate(libctx, &tmpparams, paramstype, + res, NULL); + else +#endif + ret = ossl_ffc_params_FIPS186_4_validate(libctx, &tmpparams, paramstype, + res, NULL); +#ifndef OPENSSL_NO_DH + if (ret == FFC_PARAM_RET_STATUS_FAILED + && (*res & FFC_ERROR_NOT_SUITABLE_GENERATOR) != 0) { + ERR_raise(ERR_LIB_DH, DH_R_NOT_SUITABLE_GENERATOR); + } +#endif + + ossl_ffc_params_cleanup(&tmpparams); + + return ret != FFC_PARAM_RET_STATUS_FAILED; +} + +/* + * If possible (or always in FIPS_MODULE) do full FIPS 186-4 validation. + * Otherwise do simple check but in addition also check the primality of the + * p and q. + */ +int ossl_ffc_params_full_validate(OSSL_LIB_CTX *libctx, const FFC_PARAMS *params, + int paramstype, int *res) +{ + int tmpres = 0; + + if (params == NULL) + return 0; + + if (res == NULL) + res = &tmpres; + +#ifdef FIPS_MODULE + return ossl_ffc_params_FIPS186_4_validate(libctx, params, paramstype, + res, NULL); +#else + if (params->seed != NULL) { + if (params->flags & FFC_PARAM_FLAG_VALIDATE_LEGACY) + return ossl_ffc_params_FIPS186_2_validate(libctx, params, paramstype, + res, NULL); + else + return ossl_ffc_params_FIPS186_4_validate(libctx, params, paramstype, + res, NULL); + } else { + int ret = 0; + + ret = ossl_ffc_params_simple_validate(libctx, params, paramstype, res); + if (ret) { + BN_CTX *ctx; + + if ((ctx = BN_CTX_new_ex(libctx)) == NULL) + return 0; + if (BN_check_prime(params->q, ctx, NULL) != 1) { +# ifndef OPENSSL_NO_DSA + ERR_raise(ERR_LIB_DSA, DSA_R_Q_NOT_PRIME); +# endif + ret = 0; + } + if (ret && BN_check_prime(params->p, ctx, NULL) != 1) { +# ifndef OPENSSL_NO_DSA + ERR_raise(ERR_LIB_DSA, DSA_R_P_NOT_PRIME); +# endif + ret = 0; + } + BN_CTX_free(ctx); + } + return ret; + } +#endif +} diff --git a/crypto/openssl/crypto/getenv.c b/crypto/openssl/crypto/getenv.c index 7e98b645b0d1..e79b6cc1618f 100644 --- a/crypto/openssl/crypto/getenv.c +++ b/crypto/openssl/crypto/getenv.c @@ -1,7 +1,7 @@ /* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,9 +13,81 @@ #include #include "internal/cryptlib.h" +#include "e_os.h" char *ossl_safe_getenv(const char *name) { +#if defined(_WIN32) && defined(CP_UTF8) && !defined(_WIN32_WCE) + if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) != 0) { + char *val = NULL; + int vallen = 0; + WCHAR *namew = NULL; + WCHAR *valw = NULL; + DWORD envlen = 0; + DWORD dwFlags = MB_ERR_INVALID_CHARS; + int rsize, fsize; + UINT curacp; + + curacp = GetACP(); + + /* + * For the code pages listed below, dwFlags must be set to 0. + * Otherwise, the function fails with ERROR_INVALID_FLAGS. + */ + if (curacp == 50220 || curacp == 50221 || curacp == 50222 || + curacp == 50225 || curacp == 50227 || curacp == 50229 || + (57002 <= curacp && curacp <=57011) || curacp == 65000 || + curacp == 42) + dwFlags = 0; + + /* query for buffer len */ + rsize = MultiByteToWideChar(curacp, dwFlags, name, -1, NULL, 0); + /* if name is valid string and can be converted to wide string */ + if (rsize > 0) + namew = _malloca(rsize * sizeof(WCHAR)); + + if (NULL != namew) { + /* convert name to wide string */ + fsize = MultiByteToWideChar(curacp, dwFlags, name, -1, namew, rsize); + /* if conversion is ok, then determine value string size in wchars */ + if (fsize > 0) + envlen = GetEnvironmentVariableW(namew, NULL, 0); + } + + if (envlen > 0) + valw = _malloca(envlen * sizeof(WCHAR)); + + if (NULL != valw) { + /* if can get env value as wide string */ + if (GetEnvironmentVariableW(namew, valw, envlen) < envlen) { + /* determine value string size in utf-8 */ + vallen = WideCharToMultiByte(CP_UTF8, 0, valw, -1, NULL, 0, + NULL, NULL); + } + } + + if (vallen > 0) + val = OPENSSL_malloc(vallen); + + if (NULL != val) { + /* convert value string from wide to utf-8 */ + if (WideCharToMultiByte(CP_UTF8, 0, valw, -1, val, vallen, + NULL, NULL) == 0) { + OPENSSL_free(val); + val = NULL; + } + } + + if (NULL != namew) + _freea(namew); + + if (NULL != valw) + _freea(valw); + + return val; + } +#endif + #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) # if __GLIBC_PREREQ(2, 17) # define SECURE_GETENV diff --git a/crypto/openssl/crypto/hmac/build.info b/crypto/openssl/crypto/hmac/build.info index 09f67c2a028e..b828ab122e49 100644 --- a/crypto/openssl/crypto/hmac/build.info +++ b/crypto/openssl/crypto/hmac/build.info @@ -1,3 +1,6 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - hmac.c hm_ameth.c hm_pmeth.c + +$COMMON=hmac.c + +SOURCE[../../libcrypto]=$COMMON +SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/openssl/crypto/hmac/hm_ameth.c b/crypto/openssl/crypto/hmac/hm_ameth.c deleted file mode 100644 index f871e4fe71e5..000000000000 --- a/crypto/openssl/crypto/hmac/hm_ameth.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" -#include -#include "crypto/asn1.h" -#include "crypto/evp.h" - -/* - * HMAC "ASN1" method. This is just here to indicate the maximum HMAC output - * length and to free up an HMAC key. - */ - -static int hmac_size(const EVP_PKEY *pkey) -{ - return EVP_MAX_MD_SIZE; -} - -static void hmac_key_free(EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey); - if (os) { - if (os->data) - OPENSSL_cleanse(os->data, os->length); - ASN1_OCTET_STRING_free(os); - } -} - -static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - switch (op) { - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - *(int *)arg2 = NID_sha256; - return 1; - - default: - return -2; - } -} - -static int hmac_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ - /* the ameth pub_cmp must return 1 on match, 0 on mismatch */ - return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b)) == 0; -} - -static int hmac_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, - size_t len) -{ - ASN1_OCTET_STRING *os; - - if (pkey->pkey.ptr != NULL) - return 0; - - os = ASN1_OCTET_STRING_new(); - if (os == NULL) - return 0; - - - if (!ASN1_OCTET_STRING_set(os, priv, len)) { - ASN1_OCTET_STRING_free(os); - return 0; - } - - pkey->pkey.ptr = os; - return 1; -} - -static int hmac_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, - size_t *len) -{ - ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; - - if (priv == NULL) { - *len = ASN1_STRING_length(os); - return 1; - } - - if (os == NULL || *len < (size_t)ASN1_STRING_length(os)) - return 0; - - *len = ASN1_STRING_length(os); - memcpy(priv, ASN1_STRING_get0_data(os), *len); - - return 1; -} - -const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = { - EVP_PKEY_HMAC, - EVP_PKEY_HMAC, - 0, - - "HMAC", - "OpenSSL HMAC method", - - 0, 0, hmac_pkey_public_cmp, 0, - - 0, 0, 0, - - hmac_size, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, - - hmac_key_free, - hmac_pkey_ctrl, - NULL, - NULL, - - NULL, - NULL, - NULL, - - NULL, - NULL, - NULL, - - hmac_set_priv_key, - NULL, - hmac_get_priv_key, - NULL, -}; diff --git a/crypto/openssl/crypto/hmac/hm_pmeth.c b/crypto/openssl/crypto/hmac/hm_pmeth.c deleted file mode 100644 index 56f98707f539..000000000000 --- a/crypto/openssl/crypto/hmac/hm_pmeth.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" -#include -#include -#include -#include -#include -#include "crypto/evp.h" - -/* HMAC pkey context structure */ - -typedef struct { - const EVP_MD *md; /* MD for HMAC use */ - ASN1_OCTET_STRING ktmp; /* Temp storage for key */ - HMAC_CTX *ctx; -} HMAC_PKEY_CTX; - -static int pkey_hmac_init(EVP_PKEY_CTX *ctx) -{ - HMAC_PKEY_CTX *hctx; - - if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) { - CRYPTOerr(CRYPTO_F_PKEY_HMAC_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - hctx->ktmp.type = V_ASN1_OCTET_STRING; - hctx->ctx = HMAC_CTX_new(); - if (hctx->ctx == NULL) { - OPENSSL_free(hctx); - return 0; - } - - ctx->data = hctx; - ctx->keygen_info_count = 0; - - return 1; -} - -static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx); - -static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - HMAC_PKEY_CTX *sctx, *dctx; - - /* allocate memory for dst->data and a new HMAC_CTX in dst->data->ctx */ - if (!pkey_hmac_init(dst)) - return 0; - sctx = EVP_PKEY_CTX_get_data(src); - dctx = EVP_PKEY_CTX_get_data(dst); - dctx->md = sctx->md; - if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx)) - goto err; - if (sctx->ktmp.data) { - if (!ASN1_OCTET_STRING_set(&dctx->ktmp, - sctx->ktmp.data, sctx->ktmp.length)) - goto err; - } - return 1; -err: - /* release HMAC_CTX in dst->data->ctx and memory allocated for dst->data */ - pkey_hmac_cleanup (dst); - return 0; -} - -static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) -{ - HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); - - if (hctx != NULL) { - HMAC_CTX_free(hctx->ctx); - OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length); - OPENSSL_free(hctx); - EVP_PKEY_CTX_set_data(ctx, NULL); - } -} - -static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *hkey = NULL; - HMAC_PKEY_CTX *hctx = ctx->data; - if (!hctx->ktmp.data) - return 0; - hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp); - if (!hkey) - return 0; - EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey); - - return 1; -} - -static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - HMAC_PKEY_CTX *hctx = EVP_MD_CTX_pkey_ctx(ctx)->data; - if (!HMAC_Update(hctx->ctx, data, count)) - return 0; - return 1; -} - -static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -{ - HMAC_PKEY_CTX *hctx = ctx->data; - HMAC_CTX_set_flags(hctx->ctx, - EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT)); - EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); - EVP_MD_CTX_set_update_fn(mctx, int_update); - return 1; -} - -static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - EVP_MD_CTX *mctx) -{ - unsigned int hlen; - HMAC_PKEY_CTX *hctx = ctx->data; - int l = EVP_MD_CTX_size(mctx); - - if (l < 0) - return 0; - *siglen = l; - if (!sig) - return 1; - - if (!HMAC_Final(hctx->ctx, sig, &hlen)) - return 0; - *siglen = (size_t)hlen; - return 1; -} - -static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - HMAC_PKEY_CTX *hctx = ctx->data; - ASN1_OCTET_STRING *key; - switch (type) { - - case EVP_PKEY_CTRL_SET_MAC_KEY: - if ((!p2 && p1 > 0) || (p1 < -1)) - return 0; - if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1)) - return 0; - break; - - case EVP_PKEY_CTRL_MD: - hctx->md = p2; - break; - - case EVP_PKEY_CTRL_DIGESTINIT: - key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; - if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md, - ctx->engine)) - return 0; - break; - - default: - return -2; - - } - return 1; -} - -static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (!value) { - return 0; - } - if (strcmp(type, "key") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); - if (strcmp(type, "hexkey") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); - return -2; -} - -const EVP_PKEY_METHOD hmac_pkey_meth = { - EVP_PKEY_HMAC, - 0, - pkey_hmac_init, - pkey_hmac_copy, - pkey_hmac_cleanup, - - 0, 0, - - 0, - pkey_hmac_keygen, - - 0, 0, - - 0, 0, - - 0, 0, - - hmac_signctx_init, - hmac_signctx, - - 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_hmac_ctrl, - pkey_hmac_ctrl_str -}; diff --git a/crypto/openssl/crypto/hmac/hmac.c b/crypto/openssl/crypto/hmac/hmac.c index 5e087bf92ff2..940d867ca652 100644 --- a/crypto/openssl/crypto/hmac/hmac.c +++ b/crypto/openssl/crypto/hmac/hmac.c @@ -1,18 +1,25 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * HMAC low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include #include #include "internal/cryptlib.h" -#include #include +#include +#include #include "hmac_local.h" int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, @@ -28,27 +35,28 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, if (md != NULL && md != ctx->md && (key == NULL || len < 0)) return 0; - if (md != NULL) { + if (md != NULL) ctx->md = md; - } else if (ctx->md) { + else if (ctx->md != NULL) md = ctx->md; - } else { + else return 0; - } /* - * The HMAC construction is not allowed to be used with the + * The HMAC construction is not allowed to be used with the * extendable-output functions (XOF) shake128 and shake256. */ - if ((EVP_MD_meth_get_flags(md) & EVP_MD_FLAG_XOF) != 0) + if ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0) return 0; if (key != NULL) { reset = 1; - j = EVP_MD_block_size(md); + j = EVP_MD_get_block_size(md); if (!ossl_assert(j <= (int)sizeof(keytmp))) return 0; + if (j < 0) + return 0; if (j < len) { if (!EVP_DigestInit_ex(ctx->md_ctx, md, impl) || !EVP_DigestUpdate(ctx->md_ctx, key, len) @@ -68,13 +76,15 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++) pad[i] = 0x36 ^ keytmp[i]; if (!EVP_DigestInit_ex(ctx->i_ctx, md, impl) - || !EVP_DigestUpdate(ctx->i_ctx, pad, EVP_MD_block_size(md))) + || !EVP_DigestUpdate(ctx->i_ctx, pad, + EVP_MD_get_block_size(md))) goto err; for (i = 0; i < HMAC_MAX_MD_CBLOCK_SIZE; i++) pad[i] = 0x5c ^ keytmp[i]; if (!EVP_DigestInit_ex(ctx->o_ctx, md, impl) - || !EVP_DigestUpdate(ctx->o_ctx, pad, EVP_MD_block_size(md))) + || !EVP_DigestUpdate(ctx->o_ctx, pad, + EVP_MD_get_block_size(md))) goto err; } if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->i_ctx)) @@ -88,7 +98,7 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, return rv; } -#if OPENSSL_API_COMPAT < 0x10100000L +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md) { if (key && md) @@ -127,7 +137,7 @@ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) size_t HMAC_size(const HMAC_CTX *ctx) { - int size = EVP_MD_size((ctx)->md); + int size = EVP_MD_get_size((ctx)->md); return (size < 0) ? 0 : size; } @@ -209,34 +219,22 @@ int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx) } unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, - const unsigned char *d, size_t n, unsigned char *md, - unsigned int *md_len) + const unsigned char *data, size_t data_len, + unsigned char *md, unsigned int *md_len) { - HMAC_CTX *c = NULL; - static unsigned char m[EVP_MAX_MD_SIZE]; - static const unsigned char dummy_key[1] = {'\0'}; - - if (md == NULL) - md = m; - if ((c = HMAC_CTX_new()) == NULL) - goto err; - - /* For HMAC_Init_ex, NULL key signals reuse. */ - if (key == NULL && key_len == 0) { - key = dummy_key; + static unsigned char static_md[EVP_MAX_MD_SIZE]; + int size = EVP_MD_get_size(evp_md); + size_t temp_md_len = 0; + unsigned char *ret = NULL; + + if (size >= 0) { + ret = EVP_Q_mac(NULL, "HMAC", NULL, EVP_MD_get0_name(evp_md), NULL, + key, key_len, data, data_len, + md == NULL ? static_md : md, size, &temp_md_len); + if (md_len != NULL) + *md_len = (unsigned int)temp_md_len; } - - if (!HMAC_Init_ex(c, key, key_len, evp_md, NULL)) - goto err; - if (!HMAC_Update(c, d, n)) - goto err; - if (!HMAC_Final(c, md, md_len)) - goto err; - HMAC_CTX_free(c); - return md; - err: - HMAC_CTX_free(c); - return NULL; + return ret; } void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) diff --git a/crypto/openssl/crypto/hmac/hmac_local.h b/crypto/openssl/crypto/hmac/hmac_local.h index 8bcc55817ae5..495b8593ffc6 100644 --- a/crypto/openssl/crypto/hmac/hmac_local.h +++ b/crypto/openssl/crypto/hmac/hmac_local.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/http/build.info b/crypto/openssl/crypto/http/build.info new file mode 100644 index 000000000000..b4626b13de7f --- /dev/null +++ b/crypto/openssl/crypto/http/build.info @@ -0,0 +1,2 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=http_client.c http_err.c http_lib.c diff --git a/crypto/openssl/crypto/http/http_client.c b/crypto/openssl/crypto/http/http_client.c new file mode 100644 index 000000000000..0d62f1c7bf16 --- /dev/null +++ b/crypto/openssl/crypto/http/http_client.c @@ -0,0 +1,1422 @@ +/* + * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Siemens AG 2018-2020 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "e_os.h" +#include +#include +#include "crypto/ctype.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/sockets.h" +#include "internal/cryptlib.h" /* for ossl_assert() */ + +#define HAS_PREFIX(str, prefix) (strncmp(str, prefix, sizeof(prefix) - 1) == 0) +#define HTTP_PREFIX "HTTP/" +#define HTTP_VERSION_PATT "1." /* allow 1.x */ +#define HTTP_VERSION_STR_LEN sizeof(HTTP_VERSION_PATT) /* == strlen("1.0") */ +#define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT +#define HTTP_1_0 HTTP_PREFIX_VERSION"0" /* "HTTP/1.0" */ +#define HTTP_LINE1_MINLEN (sizeof(HTTP_PREFIX_VERSION "x 200\n") - 1) +#define HTTP_VERSION_MAX_REDIRECTIONS 50 + +#define HTTP_STATUS_CODE_OK 200 +#define HTTP_STATUS_CODE_MOVED_PERMANENTLY 301 +#define HTTP_STATUS_CODE_FOUND 302 + +/* Stateful HTTP request code, supporting blocking and non-blocking I/O */ + +/* Opaque HTTP request status structure */ + +struct ossl_http_req_ctx_st { + int state; /* Current I/O state */ + unsigned char *buf; /* Buffer to write request or read response */ + int buf_size; /* Buffer size */ + int free_wbio; /* wbio allocated internally, free with ctx */ + BIO *wbio; /* BIO to write/send request to */ + BIO *rbio; /* BIO to read/receive response from */ + OSSL_HTTP_bio_cb_t upd_fn; /* Optional BIO update callback used for TLS */ + void *upd_arg; /* Optional arg for update callback function */ + int use_ssl; /* Use HTTPS */ + char *proxy; /* Optional proxy name or URI */ + char *server; /* Optional server host name */ + char *port; /* Optional server port */ + BIO *mem; /* Mem BIO holding request header or response */ + BIO *req; /* BIO holding the request provided by caller */ + int method_POST; /* HTTP method is POST (else GET) */ + char *expected_ct; /* Optional expected Content-Type */ + int expect_asn1; /* Response must be ASN.1-encoded */ + unsigned char *pos; /* Current position sending data */ + long len_to_send; /* Number of bytes still to send */ + size_t resp_len; /* Length of response */ + size_t max_resp_len; /* Maximum length of response, or 0 */ + int keep_alive; /* Persistent conn. 0=no, 1=prefer, 2=require */ + time_t max_time; /* Maximum end time of current transfer, or 0 */ + time_t max_total_time; /* Maximum end time of total transfer, or 0 */ + char *redirection_url; /* Location obtained from HTTP status 301/302 */ +}; + +/* HTTP states */ + +#define OHS_NOREAD 0x1000 /* If set no reading should be performed */ +#define OHS_ERROR (0 | OHS_NOREAD) /* Error condition */ +#define OHS_ADD_HEADERS (1 | OHS_NOREAD) /* Adding header lines to request */ +#define OHS_WRITE_INIT (2 | OHS_NOREAD) /* 1st call: ready to start send */ +#define OHS_WRITE_HDR (3 | OHS_NOREAD) /* Request header being sent */ +#define OHS_WRITE_REQ (4 | OHS_NOREAD) /* Request contents being sent */ +#define OHS_FLUSH (5 | OHS_NOREAD) /* Request being flushed */ +#define OHS_FIRSTLINE 1 /* First line of response being read */ +#define OHS_HEADERS 2 /* MIME headers of response being read */ +#define OHS_REDIRECT 3 /* MIME headers being read, expecting Location */ +#define OHS_ASN1_HEADER 4 /* ASN1 sequence header (tag+length) being read */ +#define OHS_ASN1_CONTENT 5 /* ASN1 content octets being read */ +#define OHS_ASN1_DONE (6 | OHS_NOREAD) /* ASN1 content read completed */ +#define OHS_STREAM (7 | OHS_NOREAD) /* HTTP content stream to be read */ + +/* Low-level HTTP API implementation */ + +OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int buf_size) +{ + OSSL_HTTP_REQ_CTX *rctx; + + if (wbio == NULL || rbio == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if ((rctx = OPENSSL_zalloc(sizeof(*rctx))) == NULL) + return NULL; + rctx->state = OHS_ERROR; + rctx->buf_size = buf_size > 0 ? buf_size : OSSL_HTTP_DEFAULT_MAX_LINE_LEN; + rctx->buf = OPENSSL_malloc(rctx->buf_size); + rctx->wbio = wbio; + rctx->rbio = rbio; + if (rctx->buf == NULL) { + OPENSSL_free(rctx); + return NULL; + } + rctx->max_resp_len = OSSL_HTTP_DEFAULT_MAX_RESP_LEN; + /* everything else is 0, e.g. rctx->len_to_send, or NULL, e.g. rctx->mem */ + return rctx; +} + +void OSSL_HTTP_REQ_CTX_free(OSSL_HTTP_REQ_CTX *rctx) +{ + if (rctx == NULL) + return; + /* + * Use BIO_free_all() because bio_update_fn may prepend or append to cbio. + * This also frees any (e.g., SSL/TLS) BIOs linked with bio and, + * like BIO_reset(bio), calls SSL_shutdown() to notify/alert the peer. + */ + if (rctx->free_wbio) + BIO_free_all(rctx->wbio); + /* do not free rctx->rbio */ + BIO_free(rctx->mem); + BIO_free(rctx->req); + OPENSSL_free(rctx->buf); + OPENSSL_free(rctx->proxy); + OPENSSL_free(rctx->server); + OPENSSL_free(rctx->port); + OPENSSL_free(rctx->expected_ct); + OPENSSL_free(rctx); +} + +BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(const OSSL_HTTP_REQ_CTX *rctx) +{ + if (rctx == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + return rctx->mem; +} + +size_t OSSL_HTTP_REQ_CTX_get_resp_len(const OSSL_HTTP_REQ_CTX *rctx) +{ + if (rctx == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return rctx->resp_len; +} + +void OSSL_HTTP_REQ_CTX_set_max_response_length(OSSL_HTTP_REQ_CTX *rctx, + unsigned long len) +{ + if (rctx == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return; + } + rctx->max_resp_len = len != 0 ? (size_t)len : OSSL_HTTP_DEFAULT_MAX_RESP_LEN; +} + +/* + * Create request line using |rctx| and |path| (or "/" in case |path| is NULL). + * Server name (and port) must be given if and only if plain HTTP proxy is used. + */ +int OSSL_HTTP_REQ_CTX_set_request_line(OSSL_HTTP_REQ_CTX *rctx, int method_POST, + const char *server, const char *port, + const char *path) +{ + if (rctx == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + BIO_free(rctx->mem); + if ((rctx->mem = BIO_new(BIO_s_mem())) == NULL) + return 0; + + rctx->method_POST = method_POST != 0; + if (BIO_printf(rctx->mem, "%s ", rctx->method_POST ? "POST" : "GET") <= 0) + return 0; + + if (server != NULL) { /* HTTP (but not HTTPS) proxy is used */ + /* + * Section 5.1.2 of RFC 1945 states that the absoluteURI form is only + * allowed when using a proxy + */ + if (BIO_printf(rctx->mem, OSSL_HTTP_PREFIX"%s", server) <= 0) + return 0; + if (port != NULL && BIO_printf(rctx->mem, ":%s", port) <= 0) + return 0; + } + + /* Make sure path includes a forward slash */ + if (path == NULL) + path = "/"; + if (path[0] != '/' && BIO_printf(rctx->mem, "/") <= 0) + return 0; + /* + * Add (the rest of) the path and the HTTP version, + * which is fixed to 1.0 for straightforward implementation of keep-alive + */ + if (BIO_printf(rctx->mem, "%s "HTTP_1_0"\r\n", path) <= 0) + return 0; + + rctx->resp_len = 0; + rctx->state = OHS_ADD_HEADERS; + return 1; +} + +int OSSL_HTTP_REQ_CTX_add1_header(OSSL_HTTP_REQ_CTX *rctx, + const char *name, const char *value) +{ + if (rctx == NULL || name == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (rctx->mem == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (BIO_puts(rctx->mem, name) <= 0) + return 0; + if (value != NULL) { + if (BIO_write(rctx->mem, ": ", 2) != 2) + return 0; + if (BIO_puts(rctx->mem, value) <= 0) + return 0; + } + return BIO_write(rctx->mem, "\r\n", 2) == 2; +} + +int OSSL_HTTP_REQ_CTX_set_expected(OSSL_HTTP_REQ_CTX *rctx, + const char *content_type, int asn1, + int timeout, int keep_alive) +{ + if (rctx == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (keep_alive != 0 + && rctx->state != OHS_ERROR && rctx->state != OHS_ADD_HEADERS) { + /* Cannot anymore set keep-alive in request header */ + ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + OPENSSL_free(rctx->expected_ct); + rctx->expected_ct = NULL; + if (content_type != NULL + && (rctx->expected_ct = OPENSSL_strdup(content_type)) == NULL) + return 0; + + rctx->expect_asn1 = asn1; + if (timeout >= 0) + rctx->max_time = timeout > 0 ? time(NULL) + timeout : 0; + else /* take over any |overall_timeout| arg of OSSL_HTTP_open(), else 0 */ + rctx->max_time = rctx->max_total_time; + rctx->keep_alive = keep_alive; + return 1; +} + +static int set1_content(OSSL_HTTP_REQ_CTX *rctx, + const char *content_type, BIO *req) +{ + long req_len = 0; +#ifndef OPENSSL_NO_STDIO + FILE *fp = NULL; +#endif + + if (rctx == NULL || (req == NULL && content_type != NULL)) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (rctx->keep_alive != 0 + && !OSSL_HTTP_REQ_CTX_add1_header(rctx, "Connection", "keep-alive")) + return 0; + + BIO_free(rctx->req); + rctx->req = NULL; + if (req == NULL) + return 1; + if (!rctx->method_POST) { + ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (content_type != NULL + && BIO_printf(rctx->mem, "Content-Type: %s\r\n", content_type) <= 0) + return 0; + + /* + * BIO_CTRL_INFO yields the data length at least for memory BIOs, but for + * file-based BIOs it gives the current position, which is not what we need. + */ + if (BIO_method_type(req) == BIO_TYPE_FILE) { +#ifndef OPENSSL_NO_STDIO + if (BIO_get_fp(req, &fp) == 1 && fseek(fp, 0, SEEK_END) == 0) { + req_len = ftell(fp); + (void)fseek(fp, 0, SEEK_SET); + } else { + fp = NULL; + } +#endif + } else { + req_len = BIO_ctrl(req, BIO_CTRL_INFO, 0, NULL); + /* + * Streaming BIOs likely will not support querying the size at all, + * and we assume we got a correct value if req_len > 0. + */ + } + if (( +#ifndef OPENSSL_NO_STDIO + fp != NULL /* definitely correct req_len */ || +#endif + req_len > 0) + && BIO_printf(rctx->mem, "Content-Length: %ld\r\n", req_len) < 0) + return 0; + + if (!BIO_up_ref(req)) + return 0; + rctx->req = req; + return 1; +} + +int OSSL_HTTP_REQ_CTX_set1_req(OSSL_HTTP_REQ_CTX *rctx, const char *content_type, + const ASN1_ITEM *it, const ASN1_VALUE *req) +{ + BIO *mem = NULL; + int res = 1; + + if (req != NULL) + res = (mem = ASN1_item_i2d_mem_bio(it, req)) != NULL; + res = res && set1_content(rctx, content_type, mem); + BIO_free(mem); + return res; +} + +static int add1_headers(OSSL_HTTP_REQ_CTX *rctx, + const STACK_OF(CONF_VALUE) *headers, const char *host) +{ + int i; + int add_host = host != NULL && *host != '\0'; + CONF_VALUE *hdr; + + for (i = 0; i < sk_CONF_VALUE_num(headers); i++) { + hdr = sk_CONF_VALUE_value(headers, i); + if (add_host && OPENSSL_strcasecmp("host", hdr->name) == 0) + add_host = 0; + if (!OSSL_HTTP_REQ_CTX_add1_header(rctx, hdr->name, hdr->value)) + return 0; + } + + if (add_host && !OSSL_HTTP_REQ_CTX_add1_header(rctx, "Host", host)) + return 0; + return 1; +} + +/* Create OSSL_HTTP_REQ_CTX structure using the values provided. */ +static OSSL_HTTP_REQ_CTX *http_req_ctx_new(int free_wbio, BIO *wbio, BIO *rbio, + OSSL_HTTP_bio_cb_t bio_update_fn, + void *arg, int use_ssl, + const char *proxy, + const char *server, const char *port, + int buf_size, int overall_timeout) +{ + OSSL_HTTP_REQ_CTX *rctx = OSSL_HTTP_REQ_CTX_new(wbio, rbio, buf_size); + + if (rctx == NULL) + return NULL; + rctx->free_wbio = free_wbio; + rctx->upd_fn = bio_update_fn; + rctx->upd_arg = arg; + rctx->use_ssl = use_ssl; + if (proxy != NULL + && (rctx->proxy = OPENSSL_strdup(proxy)) == NULL) + goto err; + if (server != NULL + && (rctx->server = OPENSSL_strdup(server)) == NULL) + goto err; + if (port != NULL + && (rctx->port = OPENSSL_strdup(port)) == NULL) + goto err; + rctx->max_total_time = + overall_timeout > 0 ? time(NULL) + overall_timeout : 0; + return rctx; + + err: + OSSL_HTTP_REQ_CTX_free(rctx); + return NULL; +} + +/* + * Parse first HTTP response line. This should be like this: "HTTP/1.0 200 OK". + * We need to obtain the status code and (optional) informational message. + * Return any received HTTP response status code, or 0 on fatal error. + */ + +static int parse_http_line1(char *line, int *found_keep_alive) +{ + int i, retcode, err; + char *code, *reason, *end; + + if (!HAS_PREFIX(line, HTTP_PREFIX_VERSION)) + goto err; + /* above HTTP 1.0, connection persistence is the default */ + *found_keep_alive = line[strlen(HTTP_PREFIX_VERSION)] > '0'; + + /* Skip to first whitespace (past protocol info) */ + for (code = line; *code != '\0' && !ossl_isspace(*code); code++) + continue; + if (*code == '\0') + goto err; + + /* Skip past whitespace to start of response code */ + while (*code != '\0' && ossl_isspace(*code)) + code++; + if (*code == '\0') + goto err; + + /* Find end of response code: first whitespace after start of code */ + for (reason = code; *reason != '\0' && !ossl_isspace(*reason); reason++) + continue; + + if (*reason == '\0') + goto err; + + /* Set end of response code and start of message */ + *reason++ = '\0'; + + /* Attempt to parse numeric code */ + retcode = strtoul(code, &end, 10); + if (*end != '\0') + goto err; + + /* Skip over any leading whitespace in message */ + while (*reason != '\0' && ossl_isspace(*reason)) + reason++; + + if (*reason != '\0') { + /* + * Finally zap any trailing whitespace in message (include CRLF) + */ + + /* chop any trailing whitespace from reason */ + /* We know reason has a non-whitespace character so this is OK */ + for (end = reason + strlen(reason) - 1; ossl_isspace(*end); end--) + *end = '\0'; + } + + switch (retcode) { + case HTTP_STATUS_CODE_OK: + case HTTP_STATUS_CODE_MOVED_PERMANENTLY: + case HTTP_STATUS_CODE_FOUND: + return retcode; + default: + err = HTTP_R_RECEIVED_ERROR; + if (retcode < 400) + err = HTTP_R_STATUS_CODE_UNSUPPORTED; + if (*reason == '\0') + ERR_raise_data(ERR_LIB_HTTP, err, "code=%s", code); + else + ERR_raise_data(ERR_LIB_HTTP, err, "code=%s, reason=%s", code, + reason); + return retcode; + } + + err: + for (i = 0; i < 60 && line[i] != '\0'; i++) + if (!ossl_isprint(line[i])) + line[i] = ' '; + line[i] = '\0'; + ERR_raise_data(ERR_LIB_HTTP, HTTP_R_HEADER_PARSE_ERROR, "content=%s", line); + return 0; +} + +static int check_set_resp_len(OSSL_HTTP_REQ_CTX *rctx, size_t len) +{ + if (rctx->max_resp_len != 0 && len > rctx->max_resp_len) + ERR_raise_data(ERR_LIB_HTTP, HTTP_R_MAX_RESP_LEN_EXCEEDED, + "length=%zu, max=%zu", len, rctx->max_resp_len); + if (rctx->resp_len != 0 && rctx->resp_len != len) + ERR_raise_data(ERR_LIB_HTTP, HTTP_R_INCONSISTENT_CONTENT_LENGTH, + "ASN.1 length=%zu, Content-Length=%zu", + len, rctx->resp_len); + rctx->resp_len = len; + return 1; +} + +static int may_still_retry(time_t max_time, int *ptimeout) +{ + time_t time_diff, now = time(NULL); + + if (max_time != 0) { + if (max_time < now) { + ERR_raise(ERR_LIB_HTTP, HTTP_R_RETRY_TIMEOUT); + return 0; + } + time_diff = max_time - now; + *ptimeout = time_diff > INT_MAX ? INT_MAX : (int)time_diff; + } + return 1; +} + +/* + * Try exchanging request and response via HTTP on (non-)blocking BIO in rctx. + * Returns 1 on success, 0 on error or redirection, -1 on BIO_should_retry. + */ +int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) +{ + int i, found_expected_ct = 0, found_keep_alive = 0; + long n; + size_t resp_len; + const unsigned char *p; + char *buf, *key, *value, *line_end = NULL; + + if (rctx == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (rctx->mem == NULL || rctx->wbio == NULL || rctx->rbio == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + rctx->redirection_url = NULL; + next_io: + buf = (char *)rctx->buf; + if ((rctx->state & OHS_NOREAD) == 0) { + if (rctx->expect_asn1) { + n = BIO_read(rctx->rbio, rctx->buf, rctx->buf_size); + } else { + (void)ERR_set_mark(); + n = BIO_gets(rctx->rbio, buf, rctx->buf_size); + if (n == -2) { /* unsupported method */ + (void)ERR_pop_to_mark(); + n = BIO_get_line(rctx->rbio, buf, rctx->buf_size); + } else { + (void)ERR_clear_last_mark(); + } + } + if (n <= 0) { + if (BIO_should_retry(rctx->rbio)) + return -1; + ERR_raise(ERR_LIB_HTTP, HTTP_R_FAILED_READING_DATA); + return 0; + } + + /* Write data to memory BIO */ + if (BIO_write(rctx->mem, rctx->buf, n) != n) + return 0; + } + + switch (rctx->state) { + case OHS_ADD_HEADERS: + /* Last operation was adding headers: need a final \r\n */ + if (BIO_write(rctx->mem, "\r\n", 2) != 2) { + rctx->state = OHS_ERROR; + return 0; + } + rctx->state = OHS_WRITE_INIT; + + /* fall thru */ + case OHS_WRITE_INIT: + rctx->len_to_send = BIO_get_mem_data(rctx->mem, &rctx->pos); + rctx->state = OHS_WRITE_HDR; + + /* fall thru */ + case OHS_WRITE_HDR: + /* Copy some chunk of data from rctx->mem to rctx->wbio */ + case OHS_WRITE_REQ: + /* Copy some chunk of data from rctx->req to rctx->wbio */ + + if (rctx->len_to_send > 0) { + i = BIO_write(rctx->wbio, rctx->pos, rctx->len_to_send); + if (i <= 0) { + if (BIO_should_retry(rctx->wbio)) + return -1; + rctx->state = OHS_ERROR; + return 0; + } + rctx->pos += i; + rctx->len_to_send -= i; + goto next_io; + } + if (rctx->state == OHS_WRITE_HDR) { + (void)BIO_reset(rctx->mem); + rctx->state = OHS_WRITE_REQ; + } + if (rctx->req != NULL && !BIO_eof(rctx->req)) { + n = BIO_read(rctx->req, rctx->buf, rctx->buf_size); + if (n <= 0) { + if (BIO_should_retry(rctx->req)) + return -1; + ERR_raise(ERR_LIB_HTTP, HTTP_R_FAILED_READING_DATA); + return 0; + } + rctx->pos = rctx->buf; + rctx->len_to_send = n; + goto next_io; + } + rctx->state = OHS_FLUSH; + + /* fall thru */ + case OHS_FLUSH: + + i = BIO_flush(rctx->wbio); + + if (i > 0) { + rctx->state = OHS_FIRSTLINE; + goto next_io; + } + + if (BIO_should_retry(rctx->wbio)) + return -1; + + rctx->state = OHS_ERROR; + return 0; + + case OHS_ERROR: + return 0; + + case OHS_FIRSTLINE: + case OHS_HEADERS: + case OHS_REDIRECT: + + /* Attempt to read a line in */ + next_line: + /* + * Due to strange memory BIO behavior with BIO_gets we have to check + * there's a complete line in there before calling BIO_gets or we'll + * just get a partial read. + */ + n = BIO_get_mem_data(rctx->mem, &p); + if (n <= 0 || memchr(p, '\n', n) == 0) { + if (n >= rctx->buf_size) { + rctx->state = OHS_ERROR; + return 0; + } + goto next_io; + } + n = BIO_gets(rctx->mem, buf, rctx->buf_size); + + if (n <= 0) { + if (BIO_should_retry(rctx->mem)) + goto next_io; + rctx->state = OHS_ERROR; + return 0; + } + + /* Don't allow excessive lines */ + if (n == rctx->buf_size) { + ERR_raise(ERR_LIB_HTTP, HTTP_R_RESPONSE_LINE_TOO_LONG); + rctx->state = OHS_ERROR; + return 0; + } + + /* First line */ + if (rctx->state == OHS_FIRSTLINE) { + switch (parse_http_line1(buf, &found_keep_alive)) { + case HTTP_STATUS_CODE_OK: + rctx->state = OHS_HEADERS; + goto next_line; + case HTTP_STATUS_CODE_MOVED_PERMANENTLY: + case HTTP_STATUS_CODE_FOUND: /* i.e., moved temporarily */ + if (!rctx->method_POST) { /* method is GET */ + rctx->state = OHS_REDIRECT; + goto next_line; + } + ERR_raise(ERR_LIB_HTTP, HTTP_R_REDIRECTION_NOT_ENABLED); + /* redirection is not supported/recommended for POST */ + /* fall through */ + default: + rctx->state = OHS_ERROR; + goto next_line; + } + } + key = buf; + value = strchr(key, ':'); + if (value != NULL) { + *(value++) = '\0'; + while (ossl_isspace(*value)) + value++; + line_end = strchr(value, '\r'); + if (line_end == NULL) + line_end = strchr(value, '\n'); + if (line_end != NULL) + *line_end = '\0'; + } + if (value != NULL && line_end != NULL) { + if (rctx->state == OHS_REDIRECT + && OPENSSL_strcasecmp(key, "Location") == 0) { + rctx->redirection_url = value; + return 0; + } + if (rctx->state == OHS_HEADERS && rctx->expected_ct != NULL + && OPENSSL_strcasecmp(key, "Content-Type") == 0) { + if (OPENSSL_strcasecmp(rctx->expected_ct, value) != 0) { + ERR_raise_data(ERR_LIB_HTTP, HTTP_R_UNEXPECTED_CONTENT_TYPE, + "expected=%s, actual=%s", + rctx->expected_ct, value); + return 0; + } + found_expected_ct = 1; + } + + /* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */ + if (OPENSSL_strcasecmp(key, "Connection") == 0) { + if (OPENSSL_strcasecmp(value, "keep-alive") == 0) + found_keep_alive = 1; + else if (OPENSSL_strcasecmp(value, "close") == 0) + found_keep_alive = 0; + } else if (OPENSSL_strcasecmp(key, "Content-Length") == 0) { + resp_len = (size_t)strtoul(value, &line_end, 10); + if (line_end == value || *line_end != '\0') { + ERR_raise_data(ERR_LIB_HTTP, + HTTP_R_ERROR_PARSING_CONTENT_LENGTH, + "input=%s", value); + return 0; + } + if (!check_set_resp_len(rctx, resp_len)) + return 0; + } + } + + /* Look for blank line indicating end of headers */ + for (p = rctx->buf; *p != '\0'; p++) { + if (*p != '\r' && *p != '\n') + break; + } + if (*p != '\0') /* not end of headers */ + goto next_line; + + if (rctx->keep_alive != 0 /* do not let server initiate keep_alive */ + && !found_keep_alive /* otherwise there is no change */) { + if (rctx->keep_alive == 2) { + rctx->keep_alive = 0; + ERR_raise(ERR_LIB_HTTP, HTTP_R_SERVER_CANCELED_CONNECTION); + return 0; + } + rctx->keep_alive = 0; + } + + if (rctx->state == OHS_ERROR) + return 0; + + if (rctx->expected_ct != NULL && !found_expected_ct) { + ERR_raise_data(ERR_LIB_HTTP, HTTP_R_MISSING_CONTENT_TYPE, + "expected=%s", rctx->expected_ct); + return 0; + } + if (rctx->state == OHS_REDIRECT) { + /* http status code indicated redirect but there was no Location */ + ERR_raise(ERR_LIB_HTTP, HTTP_R_MISSING_REDIRECT_LOCATION); + return 0; + } + + if (!rctx->expect_asn1) { + rctx->state = OHS_STREAM; + return 1; + } + + rctx->state = OHS_ASN1_HEADER; + + /* Fall thru */ + case OHS_ASN1_HEADER: + /* + * Now reading ASN1 header: can read at least 2 bytes which is enough + * for ASN1 SEQUENCE header and either length field or at least the + * length of the length field. + */ + n = BIO_get_mem_data(rctx->mem, &p); + if (n < 2) + goto next_io; + + /* Check it is an ASN1 SEQUENCE */ + if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { + ERR_raise(ERR_LIB_HTTP, HTTP_R_MISSING_ASN1_ENCODING); + return 0; + } + + /* Check out length field */ + if ((*p & 0x80) != 0) { + /* + * If MSB set on initial length octet we can now always read 6 + * octets: make sure we have them. + */ + if (n < 6) + goto next_io; + n = *p & 0x7F; + /* Not NDEF or excessive length */ + if (n == 0 || (n > 4)) { + ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_ASN1_LENGTH); + return 0; + } + p++; + resp_len = 0; + for (i = 0; i < n; i++) { + resp_len <<= 8; + resp_len |= *p++; + } + resp_len += n + 2; + } else { + resp_len = *p + 2; + } + if (!check_set_resp_len(rctx, resp_len)) + return 0; + + rctx->state = OHS_ASN1_CONTENT; + + /* Fall thru */ + case OHS_ASN1_CONTENT: + default: + n = BIO_get_mem_data(rctx->mem, NULL); + if (n < 0 || (size_t)n < rctx->resp_len) + goto next_io; + + rctx->state = OHS_ASN1_DONE; + return 1; + } +} + +int OSSL_HTTP_REQ_CTX_nbio_d2i(OSSL_HTTP_REQ_CTX *rctx, + ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + const unsigned char *p; + int rv; + + *pval = NULL; + if ((rv = OSSL_HTTP_REQ_CTX_nbio(rctx)) != 1) + return rv; + *pval = ASN1_item_d2i(NULL, &p, BIO_get_mem_data(rctx->mem, &p), it); + return *pval != NULL; + +} + +#ifndef OPENSSL_NO_SOCK + +/* set up a new connection BIO, to HTTP server or to HTTP(S) proxy if given */ +static BIO *http_new_bio(const char *server /* optionally includes ":port" */, + const char *server_port /* explicit server port */, + int use_ssl, + const char *proxy /* optionally includes ":port" */, + const char *proxy_port /* explicit proxy port */) +{ + const char *host = server; + const char *port = server_port; + BIO *cbio; + + if (!ossl_assert(server != NULL)) + return NULL; + + if (proxy != NULL) { + host = proxy; + port = proxy_port; + } + + if (port == NULL && strchr(host, ':') == NULL) + port = use_ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT; + + cbio = BIO_new_connect(host /* optionally includes ":port" */); + if (cbio == NULL) + goto end; + if (port != NULL) + (void)BIO_set_conn_port(cbio, port); + + end: + return cbio; +} +#endif /* OPENSSL_NO_SOCK */ + +/* Exchange request and response via HTTP on (non-)blocking BIO */ +BIO *OSSL_HTTP_REQ_CTX_exchange(OSSL_HTTP_REQ_CTX *rctx) +{ + int rv; + + if (rctx == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + for (;;) { + rv = OSSL_HTTP_REQ_CTX_nbio(rctx); + if (rv != -1) + break; + /* BIO_should_retry was true */ + /* will not actually wait if rctx->max_time == 0 */ + if (BIO_wait(rctx->rbio, rctx->max_time, 100 /* milliseconds */) <= 0) + return NULL; + } + + if (rv == 0) { + if (rctx->redirection_url == NULL) { /* an error occurred */ + if (rctx->len_to_send > 0) + ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_SENDING); + else + ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_RECEIVING); + } + return NULL; + } + return rctx->state == OHS_STREAM ? rctx->rbio : rctx->mem; +} + +int OSSL_HTTP_is_alive(const OSSL_HTTP_REQ_CTX *rctx) +{ + return rctx != NULL && rctx->keep_alive != 0; +} + +/* High-level HTTP API implementation */ + +/* Initiate an HTTP session using bio, else use given server, proxy, etc. */ +OSSL_HTTP_REQ_CTX *OSSL_HTTP_open(const char *server, const char *port, + const char *proxy, const char *no_proxy, + int use_ssl, BIO *bio, BIO *rbio, + OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, + int buf_size, int overall_timeout) +{ + BIO *cbio; /* == bio if supplied, used as connection BIO if rbio is NULL */ + OSSL_HTTP_REQ_CTX *rctx = NULL; + + if (use_ssl && bio_update_fn == NULL) { + ERR_raise(ERR_LIB_HTTP, HTTP_R_TLS_NOT_ENABLED); + return NULL; + } + if (rbio != NULL && (bio == NULL || bio_update_fn != NULL)) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + + if (bio != NULL) { + cbio = bio; + if (proxy != NULL || no_proxy != NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + } else { +#ifndef OPENSSL_NO_SOCK + char *proxy_host = NULL, *proxy_port = NULL; + + if (server == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (port != NULL && *port == '\0') + port = NULL; + if (port == NULL && strchr(server, ':') == NULL) + port = use_ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT; + proxy = OSSL_HTTP_adapt_proxy(proxy, no_proxy, server, use_ssl); + if (proxy != NULL + && !OSSL_HTTP_parse_url(proxy, NULL /* use_ssl */, NULL /* user */, + &proxy_host, &proxy_port, NULL /* num */, + NULL /* path */, NULL, NULL)) + return NULL; + cbio = http_new_bio(server, port, use_ssl, proxy_host, proxy_port); + OPENSSL_free(proxy_host); + OPENSSL_free(proxy_port); + if (cbio == NULL) + return NULL; +#else + ERR_raise(ERR_LIB_HTTP, HTTP_R_SOCK_NOT_SUPPORTED); + return NULL; +#endif + } + + (void)ERR_set_mark(); /* prepare removing any spurious libssl errors */ + if (rbio == NULL && BIO_do_connect_retry(cbio, overall_timeout, -1) <= 0) { + if (bio == NULL) /* cbio was not provided by caller */ + BIO_free_all(cbio); + goto end; + } + /* now overall_timeout is guaranteed to be >= 0 */ + + /* adapt in order to fix callback design flaw, see #17088 */ + /* callback can be used to wrap or prepend TLS session */ + if (bio_update_fn != NULL) { + BIO *orig_bio = cbio; + + cbio = (*bio_update_fn)(cbio, arg, 1 /* connect */, use_ssl != 0); + if (cbio == NULL) { + if (bio == NULL) /* cbio was not provided by caller */ + BIO_free_all(orig_bio); + goto end; + } + } + + rctx = http_req_ctx_new(bio == NULL, cbio, rbio != NULL ? rbio : cbio, + bio_update_fn, arg, use_ssl, proxy, server, port, + buf_size, overall_timeout); + + end: + if (rctx != NULL) + /* remove any spurious error queue entries by ssl_add_cert_chain() */ + (void)ERR_pop_to_mark(); + else + (void)ERR_clear_last_mark(); + + return rctx; +} + +int OSSL_HTTP_set1_request(OSSL_HTTP_REQ_CTX *rctx, const char *path, + const STACK_OF(CONF_VALUE) *headers, + const char *content_type, BIO *req, + const char *expected_content_type, int expect_asn1, + size_t max_resp_len, int timeout, int keep_alive) +{ + int use_http_proxy; + + if (rctx == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + use_http_proxy = rctx->proxy != NULL && !rctx->use_ssl; + if (use_http_proxy && rctx->server == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + rctx->max_resp_len = max_resp_len; /* allows for 0: indefinite */ + + return OSSL_HTTP_REQ_CTX_set_request_line(rctx, req != NULL, + use_http_proxy ? rctx->server + : NULL, rctx->port, path) + && add1_headers(rctx, headers, rctx->server) + && OSSL_HTTP_REQ_CTX_set_expected(rctx, expected_content_type, + expect_asn1, timeout, keep_alive) + && set1_content(rctx, content_type, req); +} + +/*- + * Exchange single HTTP request and response according to rctx. + * If rctx->method_POST then use POST, else use GET and ignore content_type. + * The redirection_url output (freed by caller) parameter is used only for GET. + */ +BIO *OSSL_HTTP_exchange(OSSL_HTTP_REQ_CTX *rctx, char **redirection_url) +{ + BIO *resp; + + if (rctx == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if (redirection_url != NULL) + *redirection_url = NULL; /* do this beforehand to prevent dbl free */ + + resp = OSSL_HTTP_REQ_CTX_exchange(rctx); + if (resp == NULL) { + if (rctx->redirection_url != NULL) { + if (redirection_url == NULL) + ERR_raise(ERR_LIB_HTTP, HTTP_R_REDIRECTION_NOT_ENABLED); + else + /* may be NULL if out of memory: */ + *redirection_url = OPENSSL_strdup(rctx->redirection_url); + } else { + char buf[200]; + unsigned long err = ERR_peek_error(); + int lib = ERR_GET_LIB(err); + int reason = ERR_GET_REASON(err); + + if (lib == ERR_LIB_SSL || lib == ERR_LIB_HTTP + || (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_TIMEOUT) + || (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_ERROR) +#ifndef OPENSSL_NO_CMP + || (lib == ERR_LIB_CMP + && reason == CMP_R_POTENTIALLY_INVALID_CERTIFICATE) +#endif + ) { + if (rctx->server != NULL) { + BIO_snprintf(buf, sizeof(buf), "server=http%s://%s%s%s", + rctx->use_ssl ? "s" : "", rctx->server, + rctx->port != NULL ? ":" : "", + rctx->port != NULL ? rctx->port : ""); + ERR_add_error_data(1, buf); + } + if (rctx->proxy != NULL) + ERR_add_error_data(2, " proxy=", rctx->proxy); + if (err == 0) { + BIO_snprintf(buf, sizeof(buf), " peer has disconnected%s", + rctx->use_ssl ? " violating the protocol" : + ", likely because it requires the use of TLS"); + ERR_add_error_data(1, buf); + } + } + } + } + + if (resp != NULL && !BIO_up_ref(resp)) + resp = NULL; + return resp; +} + +static int redirection_ok(int n_redir, const char *old_url, const char *new_url) +{ + if (n_redir >= HTTP_VERSION_MAX_REDIRECTIONS) { + ERR_raise(ERR_LIB_HTTP, HTTP_R_TOO_MANY_REDIRECTIONS); + return 0; + } + if (*new_url == '/') /* redirection to same server => same protocol */ + return 1; + if (HAS_PREFIX(old_url, OSSL_HTTPS_NAME":") && + !HAS_PREFIX(new_url, OSSL_HTTPS_NAME":")) { + ERR_raise(ERR_LIB_HTTP, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP); + return 0; + } + return 1; +} + +/* Get data via HTTP from server at given URL, potentially with redirection */ +BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, + BIO *bio, BIO *rbio, + OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, + int buf_size, const STACK_OF(CONF_VALUE) *headers, + const char *expected_ct, int expect_asn1, + size_t max_resp_len, int timeout) +{ + char *current_url, *redirection_url = NULL; + int n_redirs = 0; + char *host; + char *port; + char *path; + int use_ssl; + OSSL_HTTP_REQ_CTX *rctx; + BIO *resp = NULL; + time_t max_time = timeout > 0 ? time(NULL) + timeout : 0; + + if (url == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if ((current_url = OPENSSL_strdup(url)) == NULL) + return NULL; + + for (;;) { + if (!OSSL_HTTP_parse_url(current_url, &use_ssl, NULL /* user */, &host, + &port, NULL /* port_num */, &path, NULL, NULL)) + break; + + rctx = OSSL_HTTP_open(host, port, proxy, no_proxy, + use_ssl, bio, rbio, bio_update_fn, arg, + buf_size, timeout); + new_rpath: + if (rctx != NULL) { + if (!OSSL_HTTP_set1_request(rctx, path, headers, + NULL /* content_type */, + NULL /* req */, + expected_ct, expect_asn1, max_resp_len, + -1 /* use same max time (timeout) */, + 0 /* no keep_alive */)) + OSSL_HTTP_REQ_CTX_free(rctx); + else + resp = OSSL_HTTP_exchange(rctx, &redirection_url); + } + OPENSSL_free(path); + if (resp == NULL && redirection_url != NULL) { + if (redirection_ok(++n_redirs, current_url, redirection_url) + && may_still_retry(max_time, &timeout)) { + (void)BIO_reset(bio); + OPENSSL_free(current_url); + current_url = redirection_url; + if (*redirection_url == '/') { /* redirection to same server */ + path = OPENSSL_strdup(redirection_url); + if (path == NULL) { + OPENSSL_free(host); + OPENSSL_free(port); + (void)OSSL_HTTP_close(rctx, 1); + BIO_free(resp); + OPENSSL_free(current_url); + return NULL; + } + goto new_rpath; + } + OPENSSL_free(host); + OPENSSL_free(port); + (void)OSSL_HTTP_close(rctx, 1); + continue; + } + /* if redirection not allowed, ignore it */ + OPENSSL_free(redirection_url); + } + OPENSSL_free(host); + OPENSSL_free(port); + if (!OSSL_HTTP_close(rctx, resp != NULL)) { + BIO_free(resp); + resp = NULL; + } + break; + } + OPENSSL_free(current_url); + return resp; +} + +/* Exchange request and response over a connection managed via |prctx| */ +BIO *OSSL_HTTP_transfer(OSSL_HTTP_REQ_CTX **prctx, + const char *server, const char *port, + const char *path, int use_ssl, + const char *proxy, const char *no_proxy, + BIO *bio, BIO *rbio, + OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, + int buf_size, const STACK_OF(CONF_VALUE) *headers, + const char *content_type, BIO *req, + const char *expected_ct, int expect_asn1, + size_t max_resp_len, int timeout, int keep_alive) +{ + OSSL_HTTP_REQ_CTX *rctx = prctx == NULL ? NULL : *prctx; + BIO *resp = NULL; + + if (rctx == NULL) { + rctx = OSSL_HTTP_open(server, port, proxy, no_proxy, + use_ssl, bio, rbio, bio_update_fn, arg, + buf_size, timeout); + timeout = -1; /* Already set during opening the connection */ + } + if (rctx != NULL) { + if (OSSL_HTTP_set1_request(rctx, path, headers, content_type, req, + expected_ct, expect_asn1, + max_resp_len, timeout, keep_alive)) + resp = OSSL_HTTP_exchange(rctx, NULL); + if (resp == NULL || !OSSL_HTTP_is_alive(rctx)) { + if (!OSSL_HTTP_close(rctx, resp != NULL)) { + BIO_free(resp); + resp = NULL; + } + rctx = NULL; + } + } + if (prctx != NULL) + *prctx = rctx; + return resp; +} + +int OSSL_HTTP_close(OSSL_HTTP_REQ_CTX *rctx, int ok) +{ + BIO *wbio; + int ret = 1; + + /* callback can be used to finish TLS session and free its BIO */ + if (rctx != NULL && rctx->upd_fn != NULL) { + wbio = (*rctx->upd_fn)(rctx->wbio, rctx->upd_arg, + 0 /* disconnect */, ok); + ret = wbio != NULL; + if (ret) + rctx->wbio = wbio; + } + OSSL_HTTP_REQ_CTX_free(rctx); + return ret; +} + +/* BASE64 encoder used for encoding basic proxy authentication credentials */ +static char *base64encode(const void *buf, size_t len) +{ + int i; + size_t outl; + char *out; + + /* Calculate size of encoded data */ + outl = (len / 3); + if (len % 3 > 0) + outl++; + outl <<= 2; + out = OPENSSL_malloc(outl + 1); + if (out == NULL) + return 0; + + i = EVP_EncodeBlock((unsigned char *)out, buf, len); + if (!ossl_assert(0 <= i && (size_t)i <= outl)) { + OPENSSL_free(out); + return NULL; + } + return out; +} + +/* + * Promote the given connection BIO using the CONNECT method for a TLS proxy. + * This is typically called by an app, so bio_err and prog are used unless NULL + * to print additional diagnostic information in a user-oriented way. + */ +int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port, + const char *proxyuser, const char *proxypass, + int timeout, BIO *bio_err, const char *prog) +{ +#undef BUF_SIZE +#define BUF_SIZE (8 * 1024) + char *mbuf = OPENSSL_malloc(BUF_SIZE); + char *mbufp; + int read_len = 0; + int ret = 0; + BIO *fbio = BIO_new(BIO_f_buffer()); + int rv; + time_t max_time = timeout > 0 ? time(NULL) + timeout : 0; + + if (bio == NULL || server == NULL + || (bio_err != NULL && prog == NULL)) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + goto end; + } + if (port == NULL || *port == '\0') + port = OSSL_HTTPS_PORT; + + if (mbuf == NULL || fbio == NULL) { + BIO_printf(bio_err /* may be NULL */, "%s: out of memory", prog); + goto end; + } + BIO_push(fbio, bio); + + BIO_printf(fbio, "CONNECT %s:%s "HTTP_1_0"\r\n", server, port); + + /* + * Workaround for broken proxies which would otherwise close + * the connection when entering tunnel mode (e.g., Squid 2.6) + */ + BIO_printf(fbio, "Proxy-Connection: Keep-Alive\r\n"); + + /* Support for basic (base64) proxy authentication */ + if (proxyuser != NULL) { + size_t len = strlen(proxyuser) + 1; + char *proxyauth, *proxyauthenc = NULL; + + if (proxypass != NULL) + len += strlen(proxypass); + proxyauth = OPENSSL_malloc(len + 1); + if (proxyauth == NULL) + goto end; + if (BIO_snprintf(proxyauth, len + 1, "%s:%s", proxyuser, + proxypass != NULL ? proxypass : "") != (int)len) + goto proxy_end; + proxyauthenc = base64encode(proxyauth, len); + if (proxyauthenc != NULL) { + BIO_printf(fbio, "Proxy-Authorization: Basic %s\r\n", proxyauthenc); + OPENSSL_clear_free(proxyauthenc, strlen(proxyauthenc)); + } + proxy_end: + OPENSSL_clear_free(proxyauth, len); + if (proxyauthenc == NULL) + goto end; + } + + /* Terminate the HTTP CONNECT request */ + BIO_printf(fbio, "\r\n"); + + for (;;) { + if (BIO_flush(fbio) != 0) + break; + /* potentially needs to be retried if BIO is non-blocking */ + if (!BIO_should_retry(fbio)) + break; + } + + for (;;) { + /* will not actually wait if timeout == 0 */ + rv = BIO_wait(fbio, max_time, 100 /* milliseconds */); + if (rv <= 0) { + BIO_printf(bio_err, "%s: HTTP CONNECT %s\n", prog, + rv == 0 ? "timed out" : "failed waiting for data"); + goto end; + } + + /*- + * The first line is the HTTP response. + * According to RFC 7230, it is formatted exactly like this: + * HTTP/d.d ddd reason text\r\n + */ + read_len = BIO_gets(fbio, mbuf, BUF_SIZE); + /* the BIO may not block, so we must wait for the 1st line to come in */ + if (read_len < (int)HTTP_LINE1_MINLEN) + continue; + + /* Check for HTTP/1.x */ + if (!HAS_PREFIX(mbuf, HTTP_PREFIX) != 0) { + ERR_raise(ERR_LIB_HTTP, HTTP_R_HEADER_PARSE_ERROR); + BIO_printf(bio_err, "%s: HTTP CONNECT failed, non-HTTP response\n", + prog); + /* Wrong protocol, not even HTTP, so stop reading headers */ + goto end; + } + mbufp = mbuf + strlen(HTTP_PREFIX); + if (!HAS_PREFIX(mbufp, HTTP_VERSION_PATT) != 0) { + ERR_raise(ERR_LIB_HTTP, HTTP_R_RECEIVED_WRONG_HTTP_VERSION); + BIO_printf(bio_err, + "%s: HTTP CONNECT failed, bad HTTP version %.*s\n", + prog, (int)HTTP_VERSION_STR_LEN, mbufp); + goto end; + } + mbufp += HTTP_VERSION_STR_LEN; + + /* RFC 7231 4.3.6: any 2xx status code is valid */ + if (!HAS_PREFIX(mbufp, " 2")) { + /* chop any trailing whitespace */ + while (read_len > 0 && ossl_isspace(mbuf[read_len - 1])) + read_len--; + mbuf[read_len] = '\0'; + ERR_raise_data(ERR_LIB_HTTP, HTTP_R_CONNECT_FAILURE, + "reason=%s", mbufp); + BIO_printf(bio_err, "%s: HTTP CONNECT failed, reason=%s\n", + prog, mbufp); + goto end; + } + ret = 1; + break; + } + + /* Read past all following headers */ + do { + /* + * This does not necessarily catch the case when the full + * HTTP response came in in more than a single TCP message. + */ + read_len = BIO_gets(fbio, mbuf, BUF_SIZE); + } while (read_len > 2); + + end: + if (fbio != NULL) { + (void)BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + } + OPENSSL_free(mbuf); + return ret; +#undef BUF_SIZE +} diff --git a/crypto/openssl/crypto/http/http_err.c b/crypto/openssl/crypto/http/http_err.c new file mode 100644 index 000000000000..332ad926d367 --- /dev/null +++ b/crypto/openssl/crypto/http/http_err.c @@ -0,0 +1,82 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/httperr.h" + +#ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA HTTP_str_reasons[] = { + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN), + "asn1 len exceeds max resp len"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_CONNECT_FAILURE), "connect failure"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_ASN1_LENGTH), + "error parsing asn1 length"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_CONTENT_LENGTH), + "error parsing content length"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_URL), "error parsing url"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_RECEIVING), "error receiving"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_SENDING), "error sending"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_FAILED_READING_DATA), + "failed reading data"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_HEADER_PARSE_ERROR), + "header parse error"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INCONSISTENT_CONTENT_LENGTH), + "inconsistent content length"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_PORT_NUMBER), + "invalid port number"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_PATH), "invalid url path"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_SCHEME), + "invalid url scheme"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MAX_RESP_LEN_EXCEEDED), + "max resp len exceeded"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_ASN1_ENCODING), + "missing asn1 encoding"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_CONTENT_TYPE), + "missing content type"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_REDIRECT_LOCATION), + "missing redirect location"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RECEIVED_ERROR), "received error"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RECEIVED_WRONG_HTTP_VERSION), + "received wrong http version"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP), + "redirection from https to http"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_REDIRECTION_NOT_ENABLED), + "redirection not enabled"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_LINE_TOO_LONG), + "response line too long"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_PARSE_ERROR), + "response parse error"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RETRY_TIMEOUT), "retry timeout"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SERVER_CANCELED_CONNECTION), + "server canceled connection"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SOCK_NOT_SUPPORTED), + "sock not supported"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_STATUS_CODE_UNSUPPORTED), + "status code unsupported"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_TLS_NOT_ENABLED), "tls not enabled"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_TOO_MANY_REDIRECTIONS), + "too many redirections"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_UNEXPECTED_CONTENT_TYPE), + "unexpected content type"}, + {0, NULL} +}; + +#endif + +int ossl_err_load_HTTP_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(HTTP_str_reasons[0].error) == NULL) + ERR_load_strings_const(HTTP_str_reasons); +#endif + return 1; +} diff --git a/crypto/openssl/crypto/http/http_lib.c b/crypto/openssl/crypto/http/http_lib.c new file mode 100644 index 000000000000..bd9c096b989c --- /dev/null +++ b/crypto/openssl/crypto/http/http_lib.c @@ -0,0 +1,286 @@ +/* + * Copyright 2001-2021 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 /* for sscanf() */ +#include +#include +#include +#include /* for BIO_snprintf() */ +#include +#include "internal/cryptlib.h" /* for ossl_assert() */ + +static void init_pstring(char **pstr) +{ + if (pstr != NULL) { + *pstr = NULL; + } +} + +static int copy_substring(char **dest, const char *start, const char *end) +{ + return dest == NULL + || (*dest = OPENSSL_strndup(start, end - start)) != NULL; +} + +static void free_pstring(char **pstr) +{ + if (pstr != NULL) { + OPENSSL_free(*pstr); + *pstr = NULL; + } +} + +int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost, + char **pport, int *pport_num, + char **ppath, char **pquery, char **pfrag) +{ + const char *p, *tmp; + const char *scheme, *scheme_end; + const char *user, *user_end; + const char *host, *host_end; + const char *port, *port_end; + unsigned int portnum; + const char *path, *path_end; + const char *query, *query_end; + const char *frag, *frag_end; + + init_pstring(pscheme); + init_pstring(puser); + init_pstring(phost); + init_pstring(pport); + init_pstring(ppath); + init_pstring(pfrag); + init_pstring(pquery); + + if (url == NULL) { + ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* check for optional prefix "://" */ + scheme = scheme_end = url; + p = strstr(url, "://"); + if (p == NULL) { + p = url; + } else { + scheme_end = p; + if (scheme_end == scheme) + goto parse_err; + p += strlen("://"); + } + + /* parse optional "userinfo@" */ + user = user_end = host = p; + host = strchr(p, '@'); + if (host != NULL) + user_end = host++; + else + host = p; + + /* parse host name/address as far as needed here */ + if (host[0] == '[') { + /* ipv6 literal, which may include ':' */ + host_end = strchr(host + 1, ']'); + if (host_end == NULL) + goto parse_err; + p = ++host_end; + } else { + /* look for start of optional port, path, query, or fragment */ + host_end = strchr(host, ':'); + if (host_end == NULL) + host_end = strchr(host, '/'); + if (host_end == NULL) + host_end = strchr(host, '?'); + if (host_end == NULL) + host_end = strchr(host, '#'); + if (host_end == NULL) /* the remaining string is just the hostname */ + host_end = host + strlen(host); + p = host_end; + } + + /* parse optional port specification starting with ':' */ + port = "0"; /* default */ + if (*p == ':') + port = ++p; + /* remaining port spec handling is also done for the default values */ + /* make sure a decimal port number is given */ + if (!sscanf(port, "%u", &portnum) || portnum > 65535) { + ERR_raise_data(ERR_LIB_HTTP, HTTP_R_INVALID_PORT_NUMBER, "%s", port); + goto err; + } + for (port_end = port; '0' <= *port_end && *port_end <= '9'; port_end++) + ; + if (port == p) /* port was given explicitly */ + p += port_end - port; + + /* check for optional path starting with '/' or '?'. Else must start '#' */ + path = p; + if (*path != '\0' && *path != '/' && *path != '?' && *path != '#') { + ERR_raise(ERR_LIB_HTTP, HTTP_R_INVALID_URL_PATH); + goto parse_err; + } + path_end = query = query_end = frag = frag_end = path + strlen(path); + + /* parse optional "?query" */ + tmp = strchr(p, '?'); + if (tmp != NULL) { + p = tmp; + if (pquery != NULL) { + path_end = p; + query = p + 1; + } + } + + /* parse optional "#fragment" */ + tmp = strchr(p, '#'); + if (tmp != NULL) { + if (query == path_end) /* we did not record a query component */ + path_end = tmp; + query_end = tmp; + frag = tmp + 1; + } + + if (!copy_substring(pscheme, scheme, scheme_end) + || !copy_substring(phost, host, host_end) + || !copy_substring(pport, port, port_end) + || !copy_substring(puser, user, user_end) + || !copy_substring(pquery, query, query_end) + || !copy_substring(pfrag, frag, frag_end)) + goto err; + if (pport_num != NULL) + *pport_num = (int)portnum; + if (*path == '/') { + if (!copy_substring(ppath, path, path_end)) + goto err; + } else if (ppath != NULL) { /* must prepend '/' */ + size_t buflen = 1 + path_end - path + 1; + + if ((*ppath = OPENSSL_malloc(buflen)) == NULL) + goto err; + BIO_snprintf(*ppath, buflen, "/%s", path); + } + return 1; + + parse_err: + ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_URL); + + err: + free_pstring(pscheme); + free_pstring(puser); + free_pstring(phost); + free_pstring(pport); + free_pstring(ppath); + free_pstring(pquery); + free_pstring(pfrag); + return 0; +} + +int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost, + char **pport, int *pport_num, + char **ppath, char **pquery, char **pfrag) +{ + char *scheme, *port; + int ssl = 0, portnum; + + init_pstring(pport); + if (pssl != NULL) + *pssl = 0; + if (!OSSL_parse_url(url, &scheme, puser, phost, &port, pport_num, + ppath, pquery, pfrag)) + return 0; + + /* check for optional HTTP scheme "http[s]" */ + if (strcmp(scheme, OSSL_HTTPS_NAME) == 0) { + ssl = 1; + if (pssl != NULL) + *pssl = ssl; + } else if (*scheme != '\0' && strcmp(scheme, OSSL_HTTP_NAME) != 0) { + ERR_raise(ERR_LIB_HTTP, HTTP_R_INVALID_URL_SCHEME); + OPENSSL_free(scheme); + OPENSSL_free(port); + goto err; + } + OPENSSL_free(scheme); + + if (strcmp(port, "0") == 0) { + /* set default port */ + OPENSSL_free(port); + port = ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT; + if (!ossl_assert(sscanf(port, "%d", &portnum) == 1)) + goto err; + if (pport_num != NULL) + *pport_num = portnum; + if (pport != NULL) { + *pport = OPENSSL_strdup(port); + if (*pport == NULL) + goto err; + } + } else { + if (pport != NULL) + *pport = port; + else + OPENSSL_free(port); + } + return 1; + + err: + free_pstring(puser); + free_pstring(phost); + free_pstring(ppath); + free_pstring(pquery); + free_pstring(pfrag); + return 0; +} + +/* Respect no_proxy, taking default value from environment variable(s) */ +static int use_proxy(const char *no_proxy, const char *server) +{ + size_t sl; + const char *found = NULL; + + if (!ossl_assert(server != NULL)) + return 0; + sl = strlen(server); + + /* + * using environment variable names, both lowercase and uppercase variants, + * compatible with other HTTP client implementations like wget, curl and git + */ + if (no_proxy == NULL) + no_proxy = getenv("no_proxy"); + if (no_proxy == NULL) + no_proxy = getenv(OPENSSL_NO_PROXY); + + if (no_proxy != NULL) + found = strstr(no_proxy, server); + while (found != NULL + && ((found != no_proxy && found[-1] != ' ' && found[-1] != ',') + || (found[sl] != '\0' && found[sl] != ' ' && found[sl] != ','))) + found = strstr(found + 1, server); + return found == NULL; +} + +/* Take default value from environment variable(s), respect no_proxy */ +const char *OSSL_HTTP_adapt_proxy(const char *proxy, const char *no_proxy, + const char *server, int use_ssl) +{ + /* + * using environment variable names, both lowercase and uppercase variants, + * compatible with other HTTP client implementations like wget, curl and git + */ + if (proxy == NULL) + proxy = getenv(use_ssl ? "https_proxy" : "http_proxy"); + if (proxy == NULL) + proxy = getenv(use_ssl ? OPENSSL_HTTP_PROXY : + OPENSSL_HTTPS_PROXY); + + if (proxy == NULL || *proxy == '\0' || !use_proxy(no_proxy, server)) + return NULL; + return proxy; +} diff --git a/crypto/openssl/crypto/ia64cpuid.S b/crypto/openssl/crypto/ia64cpuid.S index 92c55124bd37..a09f8556372d 100644 --- a/crypto/openssl/crypto/ia64cpuid.S +++ b/crypto/openssl/crypto/ia64cpuid.S @@ -1,6 +1,6 @@ // Copyright 2004-2017 The OpenSSL Project Authors. All Rights Reserved. // -// Licensed under the OpenSSL license (the "License"). You may not use +// 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 diff --git a/crypto/openssl/crypto/idea/build.info b/crypto/openssl/crypto/idea/build.info index 232612379720..7ac120918b91 100644 --- a/crypto/openssl/crypto/idea/build.info +++ b/crypto/openssl/crypto/idea/build.info @@ -1,3 +1,10 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - i_cbc.c i_cfb64.c i_ofb64.c i_ecb.c i_skey.c +$ALL=i_cbc.c i_cfb64.c i_ofb64.c i_ecb.c i_skey.c + +SOURCE[../../libcrypto]=$ALL + +# When all deprecated symbols are removed, libcrypto doesn't export the +# idea functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=$ALL +ENDIF diff --git a/crypto/openssl/crypto/idea/i_cbc.c b/crypto/openssl/crypto/idea/i_cbc.c index 4eff467111be..e9608e82f561 100644 --- a/crypto/openssl/crypto/idea/i_cbc.c +++ b/crypto/openssl/crypto/idea/i_cbc.c @@ -1,12 +1,19 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * IDEA low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include "idea_local.h" diff --git a/crypto/openssl/crypto/idea/i_cfb64.c b/crypto/openssl/crypto/idea/i_cfb64.c index 61c723015b99..afea89edfa08 100644 --- a/crypto/openssl/crypto/idea/i_cfb64.c +++ b/crypto/openssl/crypto/idea/i_cfb64.c @@ -1,12 +1,19 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * IDEA low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include "idea_local.h" @@ -26,6 +33,11 @@ void IDEA_cfb64_encrypt(const unsigned char *in, unsigned char *out, unsigned long ti[2]; unsigned char *iv, c, cc; + if (n < 0) { + *num = -1; + return; + } + iv = (unsigned char *)ivec; if (encrypt) { while (l--) { diff --git a/crypto/openssl/crypto/idea/i_ecb.c b/crypto/openssl/crypto/idea/i_ecb.c index cb724e1a6c0b..6304e6cac802 100644 --- a/crypto/openssl/crypto/idea/i_ecb.c +++ b/crypto/openssl/crypto/idea/i_ecb.c @@ -1,12 +1,19 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * IDEA low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include "idea_local.h" #include diff --git a/crypto/openssl/crypto/idea/i_ofb64.c b/crypto/openssl/crypto/idea/i_ofb64.c index f000ced58620..a6a149764dbe 100644 --- a/crypto/openssl/crypto/idea/i_ofb64.c +++ b/crypto/openssl/crypto/idea/i_ofb64.c @@ -1,12 +1,19 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * IDEA low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include "idea_local.h" @@ -28,6 +35,11 @@ void IDEA_ofb64_encrypt(const unsigned char *in, unsigned char *out, unsigned char *iv; int save = 0; + if (n < 0) { + *num = -1; + return; + } + iv = (unsigned char *)ivec; n2l(iv, v0); n2l(iv, v1); diff --git a/crypto/openssl/crypto/idea/i_skey.c b/crypto/openssl/crypto/idea/i_skey.c index 230338d7e3ab..7564bce5b131 100644 --- a/crypto/openssl/crypto/idea/i_skey.c +++ b/crypto/openssl/crypto/idea/i_skey.c @@ -1,12 +1,19 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * IDEA low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + #include #include "idea_local.h" diff --git a/crypto/openssl/crypto/idea/idea_local.h b/crypto/openssl/crypto/idea/idea_local.h index 50f81dfd8dee..3c9ffa0827d0 100644 --- a/crypto/openssl/crypto/idea/idea_local.h +++ b/crypto/openssl/crypto/idea/idea_local.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/info.c b/crypto/openssl/crypto/info.c new file mode 100644 index 000000000000..a0dc2e80136f --- /dev/null +++ b/crypto/openssl/crypto/info.c @@ -0,0 +1,207 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "crypto/rand.h" +#include "crypto/dso_conf.h" +#include "internal/thread_once.h" +#include "internal/cryptlib.h" +#include "e_os.h" +#include "buildinf.h" + +#if defined(__arm__) || defined(__arm) || defined(__aarch64__) +# include "arm_arch.h" +# define CPU_INFO_STR_LEN 128 +#elif defined(__s390__) || defined(__s390x__) +# include "s390x_arch.h" +# define CPU_INFO_STR_LEN 2048 +#else +# define CPU_INFO_STR_LEN 128 +#endif + +/* extern declaration to avoid warning */ +extern char ossl_cpu_info_str[]; + +static char *seed_sources = NULL; + +char ossl_cpu_info_str[CPU_INFO_STR_LEN] = ""; +#define CPUINFO_PREFIX "CPUINFO: " + +static CRYPTO_ONCE init_info = CRYPTO_ONCE_STATIC_INIT; + +DEFINE_RUN_ONCE_STATIC(init_info_strings) +{ +#if defined(OPENSSL_CPUID_OBJ) +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) + const char *env; + + BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str), + CPUINFO_PREFIX "OPENSSL_ia32cap=0x%llx:0x%llx", + (unsigned long long)OPENSSL_ia32cap_P[0] | + (unsigned long long)OPENSSL_ia32cap_P[1] << 32, + (unsigned long long)OPENSSL_ia32cap_P[2] | + (unsigned long long)OPENSSL_ia32cap_P[3] << 32); + if ((env = getenv("OPENSSL_ia32cap")) != NULL) + BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str), + sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str), + " env:%s", env); +# elif defined(__arm__) || defined(__arm) || defined(__aarch64__) + const char *env; + + BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str), + CPUINFO_PREFIX "OPENSSL_armcap=0x%x", OPENSSL_armcap_P); + if ((env = getenv("OPENSSL_armcap")) != NULL) + BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str), + sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str), + " env:%s", env); +# elif defined(__s390__) || defined(__s390x__) + const char *env; + + BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str), + CPUINFO_PREFIX "OPENSSL_s390xcap=" + "stfle:0x%llx:0x%llx:0x%llx:0x%llx:" + "kimd:0x%llx:0x%llx:" + "klmd:0x%llx:0x%llx:" + "km:0x%llx:0x%llx:" + "kmc:0x%llx:0x%llx:" + "kmac:0x%llx:0x%llx:" + "kmctr:0x%llx:0x%llx:" + "kmo:0x%llx:0x%llx:" + "kmf:0x%llx:0x%llx:" + "prno:0x%llx:0x%llx:" + "kma:0x%llx:0x%llx:" + "pcc:0x%llx:0x%llx:" + "kdsa:0x%llx:0x%llx", + OPENSSL_s390xcap_P.stfle[0], OPENSSL_s390xcap_P.stfle[1], + OPENSSL_s390xcap_P.stfle[2], OPENSSL_s390xcap_P.stfle[3], + OPENSSL_s390xcap_P.kimd[0], OPENSSL_s390xcap_P.kimd[1], + OPENSSL_s390xcap_P.klmd[0], OPENSSL_s390xcap_P.klmd[1], + OPENSSL_s390xcap_P.km[0], OPENSSL_s390xcap_P.km[1], + OPENSSL_s390xcap_P.kmc[0], OPENSSL_s390xcap_P.kmc[1], + OPENSSL_s390xcap_P.kmac[0], OPENSSL_s390xcap_P.kmac[1], + OPENSSL_s390xcap_P.kmctr[0], OPENSSL_s390xcap_P.kmctr[1], + OPENSSL_s390xcap_P.kmo[0], OPENSSL_s390xcap_P.kmo[1], + OPENSSL_s390xcap_P.kmf[0], OPENSSL_s390xcap_P.kmf[1], + OPENSSL_s390xcap_P.prno[0], OPENSSL_s390xcap_P.prno[1], + OPENSSL_s390xcap_P.kma[0], OPENSSL_s390xcap_P.kma[1], + OPENSSL_s390xcap_P.pcc[0], OPENSSL_s390xcap_P.pcc[1], + OPENSSL_s390xcap_P.kdsa[0], OPENSSL_s390xcap_P.kdsa[1]); + if ((env = getenv("OPENSSL_s390xcap")) != NULL) + BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str), + sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str), + " env:%s", env); +# endif +#endif + + { + static char seeds[512] = ""; + +#define add_seeds_string(str) \ + do { \ + if (seeds[0] != '\0') \ + OPENSSL_strlcat(seeds, " ", sizeof(seeds)); \ + OPENSSL_strlcat(seeds, str, sizeof(seeds)); \ + } while (0) +#define add_seeds_stringlist(label, strlist) \ + do { \ + add_seeds_string(label "("); \ + { \ + const char *dev[] = { strlist, NULL }; \ + const char **p; \ + int first = 1; \ + \ + for (p = dev; *p != NULL; p++) { \ + if (!first) \ + OPENSSL_strlcat(seeds, " ", sizeof(seeds)); \ + first = 0; \ + OPENSSL_strlcat(seeds, *p, sizeof(seeds)); \ + } \ + } \ + OPENSSL_strlcat(seeds, ")", sizeof(seeds)); \ + } while (0) + +#ifdef OPENSSL_RAND_SEED_NONE + add_seeds_string("none"); +#endif +#ifdef OPENSSL_RAND_SEED_RDTSC + add_seeds_string("rdtsc"); +#endif +#ifdef OPENSSL_RAND_SEED_RDCPU + add_seeds_string("rdrand ( rdseed rdrand )"); +#endif +#ifdef OPENSSL_RAND_SEED_LIBRANDOM + add_seeds_string("C-library-random"); +#endif +#ifdef OPENSSL_RAND_SEED_GETRANDOM + add_seeds_string("getrandom-syscall"); +#endif +#ifdef OPENSSL_RAND_SEED_DEVRANDOM + add_seeds_stringlist("random-device", DEVRANDOM); +#endif +#ifdef OPENSSL_RAND_SEED_EGD + add_seeds_stringlist("EGD", DEVRANDOM_EGD); +#endif +#ifdef OPENSSL_RAND_SEED_OS + add_seeds_string("os-specific"); +#endif + seed_sources = seeds; + } + return 1; +} + +const char *OPENSSL_info(int t) +{ + /* + * We don't care about the result. Worst case scenario, the strings + * won't be initialised, i.e. remain NULL, which means that the info + * isn't available anyway... + */ + (void)RUN_ONCE(&init_info, init_info_strings); + + switch (t) { + case OPENSSL_INFO_CONFIG_DIR: + return OPENSSLDIR; + case OPENSSL_INFO_ENGINES_DIR: + return ENGINESDIR; + case OPENSSL_INFO_MODULES_DIR: + return MODULESDIR; + case OPENSSL_INFO_DSO_EXTENSION: + return DSO_EXTENSION; + case OPENSSL_INFO_DIR_FILENAME_SEPARATOR: +#if defined(_WIN32) + return "\\"; +#elif defined(__VMS) + return ""; +#else /* Assume POSIX */ + return "/"; +#endif + case OPENSSL_INFO_LIST_SEPARATOR: + { + static const char list_sep[] = { LIST_SEPARATOR_CHAR, '\0' }; + return list_sep; + } + case OPENSSL_INFO_SEED_SOURCE: + return seed_sources; + case OPENSSL_INFO_CPU_SETTINGS: + /* + * If successfully initialized, ossl_cpu_info_str will start + * with CPUINFO_PREFIX, if failed it will be an empty string. + * Strip away the CPUINFO_PREFIX which we don't need here. + */ + if (ossl_cpu_info_str[0] != '\0') + return ossl_cpu_info_str + strlen(CPUINFO_PREFIX); + break; + default: + break; + } + /* Not an error */ + return NULL; +} diff --git a/crypto/openssl/crypto/init.c b/crypto/openssl/crypto/init.c index b23af7977cd2..cacf637c89f8 100644 --- a/crypto/openssl/crypto/init.c +++ b/crypto/openssl/crypto/init.c @@ -1,12 +1,15 @@ /* * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "e_os.h" #include "crypto/cryptlib.h" #include @@ -27,53 +30,12 @@ #include "crypto/dso_conf.h" #include "internal/dso.h" #include "crypto/store.h" +#include /* for OSSL_CMP_log_close() */ +#include +#include "crypto/ctype.h" static int stopped = 0; - -/* - * Since per-thread-specific-data destructors are not universally - * available, i.e. not on Windows, only below CRYPTO_THREAD_LOCAL key - * is assumed to have destructor associated. And then an effort is made - * to call this single destructor on non-pthread platform[s]. - * - * Initial value is "impossible". It is used as guard value to shortcut - * 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 dereference real - * key value and pull NULL past initialization in the first thread that - * intends to use libcrypto. - */ -static union { - long sane; - CRYPTO_THREAD_LOCAL value; -} destructor_key = { -1 }; - -static void ossl_init_thread_stop(struct thread_local_inits_st *locals); - -static void ossl_init_thread_destructor(void *local) -{ - ossl_init_thread_stop((struct thread_local_inits_st *)local); -} - -static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc) -{ - struct thread_local_inits_st *local = - CRYPTO_THREAD_get_local(&destructor_key.value); - - if (alloc) { - if (local == NULL - && (local = OPENSSL_zalloc(sizeof(*local))) != NULL - && !CRYPTO_THREAD_set_local(&destructor_key.value, local)) { - OPENSSL_free(local); - return NULL; - } - } else { - CRYPTO_THREAD_set_local(&destructor_key.value, NULL); - } - - return local; -} +static uint64_t optsdone = 0; typedef struct ossl_init_stop_st OPENSSL_INIT_STOP; struct ossl_init_stop_st { @@ -82,38 +44,45 @@ struct ossl_init_stop_st { }; static OPENSSL_INIT_STOP *stop_handlers = NULL; +/* Guards access to the optsdone variable on platforms without atomics */ +static CRYPTO_RWLOCK *optsdone_lock = NULL; +/* Guards simultaneous INIT_LOAD_CONFIG calls with non-NULL settings */ static CRYPTO_RWLOCK *init_lock = NULL; +static CRYPTO_THREAD_LOCAL in_init_config_local; static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT; static int base_inited = 0; DEFINE_RUN_ONCE_STATIC(ossl_init_base) { - CRYPTO_THREAD_LOCAL key; + /* no need to init trace */ -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n"); -#endif + OSSL_TRACE(INIT, "ossl_init_base: setting up stop handlers\n"); #ifndef OPENSSL_NO_CRYPTO_MDEBUG ossl_malloc_setup_failures(); #endif - if (!CRYPTO_THREAD_init_local(&key, ossl_init_thread_destructor)) - return 0; - if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL) + + if ((optsdone_lock = CRYPTO_THREAD_lock_new()) == NULL + || (init_lock = CRYPTO_THREAD_lock_new()) == NULL) goto err; + OPENSSL_cpuid_setup(); - destructor_key.value = key; + if (!ossl_init_thread()) + goto err; + + if (!CRYPTO_THREAD_init_local(&in_init_config_local, NULL)) + goto err; + base_inited = 1; return 1; err: -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_base not ok!\n"); -#endif + OSSL_TRACE(INIT, "ossl_init_base failed!\n"); + CRYPTO_THREAD_lock_free(optsdone_lock); + optsdone_lock = NULL; CRYPTO_THREAD_lock_free(init_lock); init_lock = NULL; - CRYPTO_THREAD_cleanup_local(&key); return 0; } @@ -132,7 +101,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit) fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n"); #endif #ifndef OPENSSL_SYS_UEFI -# ifdef _WIN32 +# if defined(_WIN32) && !defined(__BORLANDC__) /* We use _onexit() in preference because it gets called on DLL unload */ if (_onexit(win32atexit) == NULL) return 0; @@ -158,9 +127,8 @@ DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_register_atexit, static CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_nodelete()\n"); -#endif + OSSL_TRACE(INIT, "ossl_init_load_crypto_nodelete()\n"); + #if !defined(OPENSSL_USE_NODELETE) \ && !defined(OPENSSL_NO_PINSHARED) # if defined(DSO_WIN32) && !defined(_WIN32_WCE) @@ -173,10 +141,10 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete) | GET_MODULE_HANDLE_EX_FLAG_PIN, (void *)&base_inited, &handle); -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: obtained DSO reference? %s\n", - (ret == TRUE ? "No!" : "Yes.")); -# endif + OSSL_TRACE1(INIT, + "ossl_init_load_crypto_nodelete: " + "obtained DSO reference? %s\n", + (ret == TRUE ? "No!" : "Yes.")); return (ret == TRUE) ? 1 : 0; } # elif !defined(DSO_NONE) @@ -192,15 +160,13 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete) return 0; dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE); -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: obtained DSO reference? %s\n", - (dso == NULL ? "No!" : "Yes.")); /* * In case of No!, it is uncertain our exit()-handlers can still be * called. After dlclose() the whole library might have been unloaded * already. */ -# endif + OSSL_TRACE1(INIT, "obtained DSO reference? %s\n", + (dso == NULL ? "No!" : "Yes.")); DSO_free(dso); err_unshelve_state(err); } @@ -220,11 +186,8 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings) * pulling in all the error strings during static linking */ #if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT) -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: " - "err_load_crypto_strings_int()\n"); -# endif - ret = err_load_crypto_strings_int(); + OSSL_TRACE(INIT, "ossl_err_load_crypto_strings()\n"); + ret = ossl_err_load_crypto_strings(); #endif return ret; } @@ -244,10 +207,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers) * pulling in all the ciphers during static linking */ #ifndef OPENSSL_NO_AUTOALGINIT -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: " - "openssl_add_all_ciphers_int()\n"); -# endif + OSSL_TRACE(INIT, "openssl_add_all_ciphers_int()\n"); openssl_add_all_ciphers_int(); #endif return 1; @@ -268,10 +228,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests) * pulling in all the ciphers during static linking */ #ifndef OPENSSL_NO_AUTOALGINIT -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: " - "openssl_add_all_digests()\n"); -# endif + OSSL_TRACE(INIT, "openssl_add_all_digests()\n"); openssl_add_all_digests_int(); #endif return 1; @@ -289,17 +246,22 @@ static int config_inited = 0; static const OPENSSL_INIT_SETTINGS *conf_settings = NULL; DEFINE_RUN_ONCE_STATIC(ossl_init_config) { - int ret = openssl_config_int(conf_settings); + int ret = ossl_config_int(NULL); + + config_inited = 1; + return ret; +} +DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_config_settings, ossl_init_config) +{ + int ret = ossl_config_int(conf_settings); + config_inited = 1; return ret; } DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config, ossl_init_config) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, - "OPENSSL_INIT: ossl_init_config: openssl_no_config_int()\n"); -#endif - openssl_no_config_int(); + OSSL_TRACE(INIT, "ossl_no_config_int()\n"); + ossl_no_config_int(); config_inited = 1; return 1; } @@ -308,9 +270,7 @@ static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT; static int async_inited = 0; DEFINE_RUN_ONCE_STATIC(ossl_init_async) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n"); -#endif + OSSL_TRACE(INIT, "async_init()\n"); if (!async_init()) return 0; async_inited = 1; @@ -321,34 +281,15 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_async) static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: " - "engine_load_openssl_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_openssl_int()\n"); engine_load_openssl_int(); return 1; } -# ifndef OPENSSL_NO_DEVCRYPTOENG -static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT; -DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto) -{ -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: " - "engine_load_devcrypto_int()\n"); -# endif - engine_load_devcrypto_int(); - return 1; -} -# endif - # ifndef OPENSSL_NO_RDRAND static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: " - "engine_load_rdrand_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_rdrand_int()\n"); engine_load_rdrand_int(); return 1; } @@ -356,22 +297,25 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand) static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: " - "engine_load_dynamic_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_dynamic_int()\n"); engine_load_dynamic_int(); return 1; } # ifndef OPENSSL_NO_STATIC_ENGINE -# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) +# ifndef OPENSSL_NO_DEVCRYPTOENG +static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto) +{ + OSSL_TRACE(INIT, "engine_load_devcrypto_int()\n"); + engine_load_devcrypto_int(); + return 1; +} +# endif +# if !defined(OPENSSL_NO_PADLOCKENG) static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: " - "engine_load_padlock_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_padlock_int()\n"); engine_load_padlock_int(); return 1; } @@ -380,10 +324,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock) static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: " - "engine_load_capi_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_capi_int()\n"); engine_load_capi_int(); return 1; } @@ -392,10 +333,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi) static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: " - "engine_load_afalg_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_afalg_int()\n"); engine_load_afalg_int(); return 1; } @@ -403,100 +341,14 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg) # endif #endif -#ifndef OPENSSL_NO_COMP -static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT; - -static int zlib_inited = 0; -DEFINE_RUN_ONCE_STATIC(ossl_init_zlib) -{ - /* Do nothing - we need to know about this for the later cleanup */ - zlib_inited = 1; - return 1; -} -#endif - -static void ossl_init_thread_stop(struct thread_local_inits_st *locals) -{ - /* Can't do much about this */ - if (locals == NULL) - return; - - if (locals->async) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " - "async_delete_thread_state()\n"); -#endif - async_delete_thread_state(); - } - - if (locals->err_state) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " - "err_delete_thread_state()\n"); -#endif - err_delete_thread_state(); - } - - if (locals->rand) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " - "drbg_delete_thread_state()\n"); -#endif - drbg_delete_thread_state(); - } - - OPENSSL_free(locals); -} - -void OPENSSL_thread_stop(void) -{ - if (destructor_key.sane != -1) - ossl_init_thread_stop(ossl_init_get_thread_local(0)); -} - -int ossl_init_thread_start(uint64_t opts) -{ - struct thread_local_inits_st *locals; - - if (!OPENSSL_init_crypto(0, NULL)) - return 0; - - locals = ossl_init_get_thread_local(1); - - if (locals == NULL) - return 0; - - if (opts & OPENSSL_INIT_THREAD_ASYNC) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: " - "marking thread for async\n"); -#endif - locals->async = 1; - } - - if (opts & OPENSSL_INIT_THREAD_ERR_STATE) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: " - "marking thread for err_state\n"); -#endif - locals->err_state = 1; - } - - if (opts & OPENSSL_INIT_THREAD_RAND) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: " - "marking thread for rand\n"); -#endif - locals->rand = 1; - } - - return 1; -} - void OPENSSL_cleanup(void) { OPENSSL_INIT_STOP *currhandler, *lasthandler; - CRYPTO_THREAD_LOCAL key; + + /* + * At some point we should consider looking at this function with a view to + * moving most/all of this into onfree handlers in OSSL_LIB_CTX. + */ /* If we've not been inited then no need to deinit */ if (!base_inited) @@ -511,7 +363,7 @@ void OPENSSL_cleanup(void) * Thread stop may not get automatically called by the thread library for * the very last thread in some situations, so call it directly. */ - ossl_init_thread_stop(ossl_init_get_thread_local(0)); + OPENSSL_thread_stop(); currhandler = stop_handlers; while (currhandler != NULL) { @@ -522,84 +374,83 @@ void OPENSSL_cleanup(void) } stop_handlers = NULL; + CRYPTO_THREAD_lock_free(optsdone_lock); + optsdone_lock = NULL; CRYPTO_THREAD_lock_free(init_lock); init_lock = NULL; + CRYPTO_THREAD_cleanup_local(&in_init_config_local); + /* * We assume we are single-threaded for this function, i.e. no race * conditions for the various "*_inited" vars below. */ #ifndef OPENSSL_NO_COMP - if (zlib_inited) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "comp_zlib_cleanup_int()\n"); -#endif - comp_zlib_cleanup_int(); - } + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zlib_cleanup()\n"); + ossl_comp_zlib_cleanup(); #endif if (async_inited) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "async_deinit()\n"); -# endif + OSSL_TRACE(INIT, "OPENSSL_cleanup: async_deinit()\n"); async_deinit(); } - key = destructor_key.value; - destructor_key.sane = -1; - CRYPTO_THREAD_cleanup_local(&key); - -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "rand_cleanup_int()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "conf_modules_free_int()\n"); -#ifndef OPENSSL_NO_ENGINE - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "engine_cleanup_int()\n"); -#endif - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "crypto_cleanup_all_ex_data_int()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "bio_sock_cleanup_int()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "bio_cleanup()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "evp_cleanup_int()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "obj_cleanup_int()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "err_cleanup()\n"); -#endif /* * Note that cleanup order is important: - * - rand_cleanup_int could call an ENGINE's RAND cleanup function so + * - ossl_rand_cleanup_int could call an ENGINE's RAND cleanup function so * must be called before engine_cleanup_int() * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up - * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data(). - * - conf_modules_free_int() can end up in ENGINE code so must be called + * before the ex data handlers are wiped during default ossl_lib_ctx deinit. + * - ossl_config_modules_free() can end up in ENGINE code so must be called * before engine_cleanup_int() * - ENGINEs and additional EVP algorithms might use added OIDs names so - * obj_cleanup_int() must be called last + * ossl_obj_cleanup_int() must be called last */ - rand_cleanup_int(); - rand_drbg_cleanup_int(); - conf_modules_free_int(); + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_rand_cleanup_int()\n"); + ossl_rand_cleanup_int(); + + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_config_modules_free()\n"); + ossl_config_modules_free(); + #ifndef OPENSSL_NO_ENGINE + OSSL_TRACE(INIT, "OPENSSL_cleanup: engine_cleanup_int()\n"); engine_cleanup_int(); #endif + +#ifndef OPENSSL_NO_DEPRECATED_3_0 + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_store_cleanup_int()\n"); ossl_store_cleanup_int(); - crypto_cleanup_all_ex_data_int(); +#endif + + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_lib_ctx_default_deinit()\n"); + ossl_lib_ctx_default_deinit(); + + ossl_cleanup_thread(); + + OSSL_TRACE(INIT, "OPENSSL_cleanup: bio_cleanup()\n"); bio_cleanup(); + + OSSL_TRACE(INIT, "OPENSSL_cleanup: evp_cleanup_int()\n"); evp_cleanup_int(); - obj_cleanup_int(); + + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_obj_cleanup_int()\n"); + ossl_obj_cleanup_int(); + + OSSL_TRACE(INIT, "OPENSSL_cleanup: err_int()\n"); err_cleanup(); + OSSL_TRACE(INIT, "OPENSSL_cleanup: CRYPTO_secure_malloc_done()\n"); CRYPTO_secure_malloc_done(); +#ifndef OPENSSL_NO_CMP + OSSL_TRACE(INIT, "OPENSSL_cleanup: OSSL_CMP_log_close()\n"); + OSSL_CMP_log_close(); +#endif + + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n"); + ossl_trace_cleanup(); + base_inited = 0; } @@ -610,13 +461,39 @@ void OPENSSL_cleanup(void) */ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { + uint64_t tmp; + int aloaddone = 0; + + /* Applications depend on 0 being returned when cleanup was already done */ if (stopped) { if (!(opts & OPENSSL_INIT_BASE_ONLY)) - CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL); return 0; } /* + * We ignore failures from this function. It is probably because we are + * on a platform that doesn't support lockless atomic loads (we may not + * have created optsdone_lock yet so we can't use it). This is just an + * optimisation to skip the full checks in this function if we don't need + * to, so we carry on regardless in the event of failure. + * + * There could be a race here with other threads, so that optsdone has not + * been updated yet, even though the options have in fact been initialised. + * This doesn't matter - it just means we will run the full function + * unnecessarily - but all the critical code is contained in RUN_ONCE + * functions anyway so we are safe. + */ + if (CRYPTO_atomic_load(&optsdone, &tmp, NULL)) { + if ((tmp & opts) == opts) + return 1; + aloaddone = 1; + } + + /* + * At some point we should look at this function with a view to moving + * most/all of this into OSSL_LIB_CTX. + * * When the caller specifies OPENSSL_INIT_BASE_ONLY, that should be the * *only* option specified. With that option we return immediately after * doing the requested limited initialization. Note that @@ -629,9 +506,22 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) */ if (!RUN_ONCE(&base, ossl_init_base)) return 0; + if (opts & OPENSSL_INIT_BASE_ONLY) return 1; + /* + * optsdone_lock should definitely be set up now, so we can now repeat the + * same check from above but be sure that it will work even on platforms + * without lockless CRYPTO_atomic_load + */ + if (!aloaddone) { + if (!CRYPTO_atomic_load(&optsdone, &tmp, optsdone_lock)) + return 0; + if ((tmp & opts) == opts) + return 1; + } + /* * Now we don't always set up exit handlers, the INIT_BASE_ONLY calls * should not have the side-effect of setting up exit handlers, and @@ -686,14 +576,29 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) return 0; if (opts & OPENSSL_INIT_LOAD_CONFIG) { - int ret; - CRYPTO_THREAD_write_lock(init_lock); - conf_settings = settings; - ret = RUN_ONCE(&config, ossl_init_config); - conf_settings = NULL; - CRYPTO_THREAD_unlock(init_lock); - if (ret <= 0) - return 0; + int loading = CRYPTO_THREAD_get_local(&in_init_config_local) != NULL; + + /* If called recursively from OBJ_ calls, just skip it. */ + if (!loading) { + int ret; + + if (!CRYPTO_THREAD_set_local(&in_init_config_local, (void *)-1)) + return 0; + if (settings == NULL) { + ret = RUN_ONCE(&config, ossl_init_config); + } else { + if (!CRYPTO_THREAD_write_lock(init_lock)) + return 0; + conf_settings = settings; + ret = RUN_ONCE_ALT(&config, ossl_init_config_settings, + ossl_init_config); + conf_settings = NULL; + CRYPTO_THREAD_unlock(init_lock); + } + + if (ret <= 0) + return 0; + } } if ((opts & OPENSSL_INIT_ASYNC) @@ -704,11 +609,6 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) if ((opts & OPENSSL_INIT_ENGINE_OPENSSL) && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl)) return 0; -# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG) - if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV) - && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto)) - return 0; -# endif # ifndef OPENSSL_NO_RDRAND if ((opts & OPENSSL_INIT_ENGINE_RDRAND) && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand)) @@ -718,7 +618,12 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic)) return 0; # ifndef OPENSSL_NO_STATIC_ENGINE -# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) +# ifndef OPENSSL_NO_DEVCRYPTOENG + if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV) + && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto)) + return 0; +# endif +# if !defined(OPENSSL_NO_PADLOCKENG) if ((opts & OPENSSL_INIT_ENGINE_PADLOCK) && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock)) return 0; @@ -741,11 +646,8 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) } #endif -#ifndef OPENSSL_NO_COMP - if ((opts & OPENSSL_INIT_ZLIB) - && !RUN_ONCE(&zlib, ossl_init_zlib)) + if (!CRYPTO_atomic_or(&optsdone, opts, &tmp, optsdone_lock)) return 0; -#endif return 1; } @@ -757,28 +659,26 @@ int OPENSSL_atexit(void (*handler)(void)) #if !defined(OPENSSL_USE_NODELETE)\ && !defined(OPENSSL_NO_PINSHARED) { +# if defined(DSO_WIN32) && !defined(_WIN32_WCE) + HMODULE handle = NULL; + BOOL ret; union { void *sym; void (*func)(void); } handlersym; handlersym.func = handler; -# if defined(DSO_WIN32) && !defined(_WIN32_WCE) - { - HMODULE handle = NULL; - BOOL ret; - - /* - * We don't use the DSO route for WIN32 because there is a better - * way - */ - ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS - | GET_MODULE_HANDLE_EX_FLAG_PIN, - handlersym.sym, &handle); - - if (!ret) - return 0; - } + + /* + * We don't use the DSO route for WIN32 because there is a better + * way + */ + ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS + | GET_MODULE_HANDLE_EX_FLAG_PIN, + handlersym.sym, &handle); + + if (!ret) + return 0; # elif !defined(DSO_NONE) /* * Deliberately leak a reference to the handler. This will force the @@ -786,26 +686,28 @@ int OPENSSL_atexit(void (*handler)(void)) * atexit handler. If -znodelete has been used then this is * unnecessary. */ - { - DSO *dso = NULL; - - ERR_set_mark(); - dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE); -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, - "OPENSSL_INIT: OPENSSL_atexit: obtained DSO reference? %s\n", - (dso == NULL ? "No!" : "Yes.")); - /* See same code above in ossl_init_base() for an explanation. */ -# endif - DSO_free(dso); - ERR_pop_to_mark(); - } + DSO *dso = NULL; + union { + void *sym; + void (*func)(void); + } handlersym; + + handlersym.func = handler; + + ERR_set_mark(); + dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE); + /* See same code above in ossl_init_base() for an explanation. */ + OSSL_TRACE1(INIT, + "atexit: obtained DSO reference? %s\n", + (dso == NULL ? "No!" : "Yes.")); + DSO_free(dso); + ERR_pop_to_mark(); # endif } #endif if ((newhand = OPENSSL_malloc(sizeof(*newhand))) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_ATEXIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } @@ -816,27 +718,3 @@ int OPENSSL_atexit(void (*handler)(void)) return 1; } -#ifdef OPENSSL_SYS_UNIX -/* - * The following three functions are for OpenSSL developers. This is - * where we set/reset state across fork (called via pthread_atfork when - * it exists, or manually by the application when it doesn't). - * - * WARNING! If you put code in either OPENSSL_fork_parent or - * OPENSSL_fork_child, you MUST MAKE SURE that they are async-signal- - * safe. See this link, for example: - * http://man7.org/linux/man-pages/man7/signal-safety.7.html - */ - -void OPENSSL_fork_prepare(void) -{ -} - -void OPENSSL_fork_parent(void) -{ -} - -void OPENSSL_fork_child(void) -{ -} -#endif diff --git a/crypto/openssl/crypto/initthread.c b/crypto/openssl/crypto/initthread.c new file mode 100644 index 000000000000..1bdaeda9fc8e --- /dev/null +++ b/crypto/openssl/crypto/initthread.c @@ -0,0 +1,467 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/cryptlib.h" +#include "prov/providercommon.h" +#include "internal/thread_once.h" + +#ifdef FIPS_MODULE +#include "prov/provider_ctx.h" + +/* + * Thread aware code may want to be told about thread stop events. We register + * to hear about those thread stop events when we see a new thread has started. + * We call the ossl_init_thread_start function to do that. In the FIPS provider + * we have our own copy of ossl_init_thread_start, which cascades notifications + * about threads stopping from libcrypto to all the code in the FIPS provider + * that needs to know about it. + * + * The FIPS provider tells libcrypto about which threads it is interested in + * by calling "c_thread_start" which is a function pointer created during + * provider initialisation (i.e. OSSL_init_provider). + */ +extern OSSL_FUNC_core_thread_start_fn *c_thread_start; +#endif + +typedef struct thread_event_handler_st THREAD_EVENT_HANDLER; +struct thread_event_handler_st { +#ifndef FIPS_MODULE + const void *index; +#endif + void *arg; + OSSL_thread_stop_handler_fn handfn; + THREAD_EVENT_HANDLER *next; +}; + +#ifndef FIPS_MODULE +DEFINE_SPECIAL_STACK_OF(THREAD_EVENT_HANDLER_PTR, THREAD_EVENT_HANDLER *) + +typedef struct global_tevent_register_st GLOBAL_TEVENT_REGISTER; +struct global_tevent_register_st { + STACK_OF(THREAD_EVENT_HANDLER_PTR) *skhands; + CRYPTO_RWLOCK *lock; +}; + +static GLOBAL_TEVENT_REGISTER *glob_tevent_reg = NULL; + +static CRYPTO_ONCE tevent_register_runonce = CRYPTO_ONCE_STATIC_INIT; + +DEFINE_RUN_ONCE_STATIC(create_global_tevent_register) +{ + glob_tevent_reg = OPENSSL_zalloc(sizeof(*glob_tevent_reg)); + if (glob_tevent_reg == NULL) + return 0; + + glob_tevent_reg->skhands = sk_THREAD_EVENT_HANDLER_PTR_new_null(); + glob_tevent_reg->lock = CRYPTO_THREAD_lock_new(); + if (glob_tevent_reg->skhands == NULL || glob_tevent_reg->lock == NULL) { + sk_THREAD_EVENT_HANDLER_PTR_free(glob_tevent_reg->skhands); + CRYPTO_THREAD_lock_free(glob_tevent_reg->lock); + OPENSSL_free(glob_tevent_reg); + glob_tevent_reg = NULL; + return 0; + } + + return 1; +} + +static GLOBAL_TEVENT_REGISTER *get_global_tevent_register(void) +{ + if (!RUN_ONCE(&tevent_register_runonce, create_global_tevent_register)) + return NULL; + return glob_tevent_reg; +} +#endif + +#ifndef FIPS_MODULE +static int init_thread_push_handlers(THREAD_EVENT_HANDLER **hands); +static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin); +static void init_thread_destructor(void *hands); +static int init_thread_deregister(void *arg, int all); +#endif +static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands); + +static THREAD_EVENT_HANDLER ** +init_get_thread_local(CRYPTO_THREAD_LOCAL *local, int alloc, int keep) +{ + THREAD_EVENT_HANDLER **hands = CRYPTO_THREAD_get_local(local); + + if (alloc) { + if (hands == NULL) { + + if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL) + return NULL; + + if (!CRYPTO_THREAD_set_local(local, hands)) { + OPENSSL_free(hands); + return NULL; + } + +#ifndef FIPS_MODULE + if (!init_thread_push_handlers(hands)) { + CRYPTO_THREAD_set_local(local, NULL); + OPENSSL_free(hands); + return NULL; + } +#endif + } + } else if (!keep) { + CRYPTO_THREAD_set_local(local, NULL); + } + + return hands; +} + +#ifndef FIPS_MODULE +/* + * Since per-thread-specific-data destructors are not universally + * available, i.e. not on Windows, only below CRYPTO_THREAD_LOCAL key + * is assumed to have destructor associated. And then an effort is made + * to call this single destructor on non-pthread platform[s]. + * + * Initial value is "impossible". It is used as guard value to shortcut + * 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 dereference real + * key value and pull NULL past initialization in the first thread that + * intends to use libcrypto. + */ +static union { + long sane; + CRYPTO_THREAD_LOCAL value; +} destructor_key = { -1 }; + +/* + * The thread event handler list is a thread specific linked list + * of callback functions which are invoked in list order by the + * current thread in case of certain events. (Currently, there is + * only one type of event, the 'thread stop' event.) + * + * We also keep a global reference to that linked list, so that we + * can deregister handlers if necessary before all the threads are + * stopped. + */ +static int init_thread_push_handlers(THREAD_EVENT_HANDLER **hands) +{ + int ret; + GLOBAL_TEVENT_REGISTER *gtr; + + gtr = get_global_tevent_register(); + if (gtr == NULL) + return 0; + + if (!CRYPTO_THREAD_write_lock(gtr->lock)) + return 0; + ret = (sk_THREAD_EVENT_HANDLER_PTR_push(gtr->skhands, hands) != 0); + CRYPTO_THREAD_unlock(gtr->lock); + + return ret; +} + +static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin) +{ + GLOBAL_TEVENT_REGISTER *gtr; + int i; + + gtr = get_global_tevent_register(); + if (gtr == NULL) + return; + if (!CRYPTO_THREAD_write_lock(gtr->lock)) + return; + for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) { + THREAD_EVENT_HANDLER **hands + = sk_THREAD_EVENT_HANDLER_PTR_value(gtr->skhands, i); + + if (hands == handsin) { + sk_THREAD_EVENT_HANDLER_PTR_delete(gtr->skhands, i); + CRYPTO_THREAD_unlock(gtr->lock); + return; + } + } + CRYPTO_THREAD_unlock(gtr->lock); + return; +} + +static void init_thread_destructor(void *hands) +{ + init_thread_stop(NULL, (THREAD_EVENT_HANDLER **)hands); + init_thread_remove_handlers(hands); + OPENSSL_free(hands); +} + +int ossl_init_thread(void) +{ + if (!CRYPTO_THREAD_init_local(&destructor_key.value, + init_thread_destructor)) + return 0; + + return 1; +} + +void ossl_cleanup_thread(void) +{ + init_thread_deregister(NULL, 1); + CRYPTO_THREAD_cleanup_local(&destructor_key.value); + destructor_key.sane = -1; +} + +void OPENSSL_thread_stop_ex(OSSL_LIB_CTX *ctx) +{ + ctx = ossl_lib_ctx_get_concrete(ctx); + /* + * It would be nice if we could figure out a way to do this on all threads + * that have used the OSSL_LIB_CTX when the context is freed. This is + * currently not possible due to the use of thread local variables. + */ + ossl_ctx_thread_stop(ctx); +} + +void OPENSSL_thread_stop(void) +{ + if (destructor_key.sane != -1) { + THREAD_EVENT_HANDLER **hands + = init_get_thread_local(&destructor_key.value, 0, 0); + init_thread_stop(NULL, hands); + + init_thread_remove_handlers(hands); + OPENSSL_free(hands); + } +} + +void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx) +{ + if (destructor_key.sane != -1) { + THREAD_EVENT_HANDLER **hands + = init_get_thread_local(&destructor_key.value, 0, 1); + init_thread_stop(ctx, hands); + } +} + +#else + +static void *thread_event_ossl_ctx_new(OSSL_LIB_CTX *libctx) +{ + THREAD_EVENT_HANDLER **hands = NULL; + CRYPTO_THREAD_LOCAL *tlocal = OPENSSL_zalloc(sizeof(*tlocal)); + + if (tlocal == NULL) + return NULL; + + if (!CRYPTO_THREAD_init_local(tlocal, NULL)) { + goto err; + } + + hands = OPENSSL_zalloc(sizeof(*hands)); + if (hands == NULL) + goto err; + + if (!CRYPTO_THREAD_set_local(tlocal, hands)) + goto err; + + return tlocal; + err: + OPENSSL_free(hands); + OPENSSL_free(tlocal); + return NULL; +} + +static void thread_event_ossl_ctx_free(void *tlocal) +{ + OPENSSL_free(tlocal); +} + +static const OSSL_LIB_CTX_METHOD thread_event_ossl_ctx_method = { + OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, + thread_event_ossl_ctx_new, + thread_event_ossl_ctx_free, +}; + +static void ossl_arg_thread_stop(void *arg) +{ + ossl_ctx_thread_stop((OSSL_LIB_CTX *)arg); +} + +void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx) +{ + THREAD_EVENT_HANDLER **hands; + CRYPTO_THREAD_LOCAL *local + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX, + &thread_event_ossl_ctx_method); + + if (local == NULL) + return; + hands = init_get_thread_local(local, 0, 0); + init_thread_stop(ctx, hands); + OPENSSL_free(hands); +} +#endif /* FIPS_MODULE */ + + +static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands) +{ + THREAD_EVENT_HANDLER *curr, *prev = NULL, *tmp; +#ifndef FIPS_MODULE + GLOBAL_TEVENT_REGISTER *gtr; +#endif + + /* Can't do much about this */ + if (hands == NULL) + return; + +#ifndef FIPS_MODULE + gtr = get_global_tevent_register(); + if (gtr == NULL) + return; + + if (!CRYPTO_THREAD_write_lock(gtr->lock)) + return; +#endif + + curr = *hands; + while (curr != NULL) { + if (arg != NULL && curr->arg != arg) { + prev = curr; + curr = curr->next; + continue; + } + curr->handfn(curr->arg); + if (prev == NULL) + *hands = curr->next; + else + prev->next = curr->next; + + tmp = curr; + curr = curr->next; + + OPENSSL_free(tmp); + } +#ifndef FIPS_MODULE + CRYPTO_THREAD_unlock(gtr->lock); +#endif +} + +int ossl_init_thread_start(const void *index, void *arg, + OSSL_thread_stop_handler_fn handfn) +{ + THREAD_EVENT_HANDLER **hands; + THREAD_EVENT_HANDLER *hand; +#ifdef FIPS_MODULE + OSSL_LIB_CTX *ctx = arg; + + /* + * In FIPS mode the list of THREAD_EVENT_HANDLERs is unique per combination + * of OSSL_LIB_CTX and thread. This is because in FIPS mode each + * OSSL_LIB_CTX gets informed about thread stop events individually. + */ + CRYPTO_THREAD_LOCAL *local + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX, + &thread_event_ossl_ctx_method); +#else + /* + * Outside of FIPS mode the list of THREAD_EVENT_HANDLERs is unique per + * thread, but may hold multiple OSSL_LIB_CTXs. We only get told about + * thread stop events globally, so we have to ensure all affected + * OSSL_LIB_CTXs are informed. + */ + CRYPTO_THREAD_LOCAL *local = &destructor_key.value; +#endif + + hands = init_get_thread_local(local, 1, 0); + if (hands == NULL) + return 0; + +#ifdef FIPS_MODULE + if (*hands == NULL) { + /* + * We've not yet registered any handlers for this thread. We need to get + * libcrypto to tell us about later thread stop events. c_thread_start + * is a callback to libcrypto defined in fipsprov.c + */ + if (!c_thread_start(FIPS_get_core_handle(ctx), ossl_arg_thread_stop, + ctx)) + return 0; + } +#endif + + hand = OPENSSL_malloc(sizeof(*hand)); + if (hand == NULL) + return 0; + + hand->handfn = handfn; + hand->arg = arg; +#ifndef FIPS_MODULE + hand->index = index; +#endif + hand->next = *hands; + *hands = hand; + + return 1; +} + +#ifndef FIPS_MODULE +static int init_thread_deregister(void *index, int all) +{ + GLOBAL_TEVENT_REGISTER *gtr; + int i; + + gtr = get_global_tevent_register(); + if (gtr == NULL) + return 0; + if (!all) { + if (!CRYPTO_THREAD_write_lock(gtr->lock)) + return 0; + } else { + glob_tevent_reg = NULL; + } + for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) { + THREAD_EVENT_HANDLER **hands + = sk_THREAD_EVENT_HANDLER_PTR_value(gtr->skhands, i); + THREAD_EVENT_HANDLER *curr = NULL, *prev = NULL, *tmp; + + if (hands == NULL) { + if (!all) + CRYPTO_THREAD_unlock(gtr->lock); + return 0; + } + curr = *hands; + while (curr != NULL) { + if (all || curr->index == index) { + if (prev != NULL) + prev->next = curr->next; + else + *hands = curr->next; + tmp = curr; + curr = curr->next; + OPENSSL_free(tmp); + continue; + } + prev = curr; + curr = curr->next; + } + if (all) + OPENSSL_free(hands); + } + if (all) { + CRYPTO_THREAD_lock_free(gtr->lock); + sk_THREAD_EVENT_HANDLER_PTR_free(gtr->skhands); + OPENSSL_free(gtr); + } else { + CRYPTO_THREAD_unlock(gtr->lock); + } + return 1; +} + +int ossl_init_thread_deregister(void *index) +{ + return init_thread_deregister(index, 0); +} +#endif diff --git a/crypto/openssl/crypto/kdf/build.info b/crypto/openssl/crypto/kdf/build.info index c166399d0ce7..7707c00988bb 100644 --- a/crypto/openssl/crypto/kdf/build.info +++ b/crypto/openssl/crypto/kdf/build.info @@ -1,3 +1,2 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - tls1_prf.c kdf_err.c hkdf.c scrypt.c +SOURCE[../../libcrypto]=kdf_err.c diff --git a/crypto/openssl/crypto/kdf/hkdf.c b/crypto/openssl/crypto/kdf/hkdf.c deleted file mode 100644 index 25bf4b729f64..000000000000 --- a/crypto/openssl/crypto/kdf/hkdf.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include "internal/cryptlib.h" -#include "crypto/evp.h" - -#define HKDF_MAXBUF 1024 - -static unsigned char *HKDF(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len); - -static unsigned char *HKDF_Extract(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - unsigned char *prk, size_t *prk_len); - -static unsigned char *HKDF_Expand(const EVP_MD *evp_md, - const unsigned char *prk, size_t prk_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len); - -typedef struct { - int mode; - const EVP_MD *md; - unsigned char *salt; - size_t salt_len; - unsigned char *key; - size_t key_len; - unsigned char info[HKDF_MAXBUF]; - size_t info_len; -} HKDF_PKEY_CTX; - -static int pkey_hkdf_init(EVP_PKEY_CTX *ctx) -{ - HKDF_PKEY_CTX *kctx; - - if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) { - KDFerr(KDF_F_PKEY_HKDF_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - - ctx->data = kctx; - - return 1; -} - -static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx) -{ - HKDF_PKEY_CTX *kctx = ctx->data; - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - OPENSSL_clear_free(kctx->key, kctx->key_len); - OPENSSL_cleanse(kctx->info, kctx->info_len); - OPENSSL_free(kctx); -} - -static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - HKDF_PKEY_CTX *kctx = ctx->data; - - switch (type) { - case EVP_PKEY_CTRL_HKDF_MD: - if (p2 == NULL) - return 0; - - kctx->md = p2; - return 1; - - case EVP_PKEY_CTRL_HKDF_MODE: - kctx->mode = p1; - return 1; - - case EVP_PKEY_CTRL_HKDF_SALT: - if (p1 == 0 || p2 == NULL) - return 1; - - if (p1 < 0) - return 0; - - if (kctx->salt != NULL) - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - - kctx->salt = OPENSSL_memdup(p2, p1); - if (kctx->salt == NULL) - return 0; - - kctx->salt_len = p1; - return 1; - - case EVP_PKEY_CTRL_HKDF_KEY: - if (p1 < 0) - return 0; - - if (kctx->key != NULL) - OPENSSL_clear_free(kctx->key, kctx->key_len); - - kctx->key = OPENSSL_memdup(p2, p1); - if (kctx->key == NULL) - return 0; - - kctx->key_len = p1; - return 1; - - case EVP_PKEY_CTRL_HKDF_INFO: - if (p1 == 0 || p2 == NULL) - return 1; - - if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len)) - return 0; - - memcpy(kctx->info + kctx->info_len, p2, p1); - kctx->info_len += p1; - return 1; - - default: - return -2; - - } -} - -static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, - const char *value) -{ - if (strcmp(type, "mode") == 0) { - int mode; - - if (strcmp(value, "EXTRACT_AND_EXPAND") == 0) - mode = EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND; - else if (strcmp(value, "EXTRACT_ONLY") == 0) - mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY; - else if (strcmp(value, "EXPAND_ONLY") == 0) - mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY; - else - return 0; - - return EVP_PKEY_CTX_hkdf_mode(ctx, mode); - } - - if (strcmp(type, "md") == 0) - return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_DERIVE, - EVP_PKEY_CTRL_HKDF_MD, value); - - if (strcmp(type, "salt") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value); - - if (strcmp(type, "hexsalt") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value); - - if (strcmp(type, "key") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value); - - if (strcmp(type, "hexkey") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value); - - if (strcmp(type, "info") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value); - - if (strcmp(type, "hexinfo") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value); - - KDFerr(KDF_F_PKEY_HKDF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); - return -2; -} - -static int pkey_hkdf_derive_init(EVP_PKEY_CTX *ctx) -{ - HKDF_PKEY_CTX *kctx = ctx->data; - - OPENSSL_clear_free(kctx->key, kctx->key_len); - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - OPENSSL_cleanse(kctx->info, kctx->info_len); - memset(kctx, 0, sizeof(*kctx)); - - return 1; -} - -static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) -{ - HKDF_PKEY_CTX *kctx = ctx->data; - - if (kctx->md == NULL) { - KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); - return 0; - } - if (kctx->key == NULL) { - KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_KEY); - return 0; - } - - switch (kctx->mode) { - case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: - return HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key, - kctx->key_len, kctx->info, kctx->info_len, key, - *keylen) != NULL; - - case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: - if (key == NULL) { - *keylen = EVP_MD_size(kctx->md); - return 1; - } - return HKDF_Extract(kctx->md, kctx->salt, kctx->salt_len, kctx->key, - kctx->key_len, key, keylen) != NULL; - - case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: - return HKDF_Expand(kctx->md, kctx->key, kctx->key_len, kctx->info, - kctx->info_len, key, *keylen) != NULL; - - default: - return 0; - } -} - -const EVP_PKEY_METHOD hkdf_pkey_meth = { - EVP_PKEY_HKDF, - 0, - pkey_hkdf_init, - 0, - pkey_hkdf_cleanup, - - 0, 0, - 0, 0, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - pkey_hkdf_derive_init, - pkey_hkdf_derive, - pkey_hkdf_ctrl, - pkey_hkdf_ctrl_str -}; - -static unsigned char *HKDF(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len) -{ - unsigned char prk[EVP_MAX_MD_SIZE]; - unsigned char *ret; - size_t prk_len; - - if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len)) - return NULL; - - ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len); - OPENSSL_cleanse(prk, sizeof(prk)); - - return ret; -} - -static unsigned char *HKDF_Extract(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - unsigned char *prk, size_t *prk_len) -{ - unsigned int tmp_len; - - if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len)) - return NULL; - - *prk_len = tmp_len; - return prk; -} - -static unsigned char *HKDF_Expand(const EVP_MD *evp_md, - const unsigned char *prk, size_t prk_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len) -{ - HMAC_CTX *hmac; - unsigned char *ret = NULL; - - unsigned int i; - - unsigned char prev[EVP_MAX_MD_SIZE]; - - size_t done_len = 0, dig_len = EVP_MD_size(evp_md); - - size_t n = okm_len / dig_len; - if (okm_len % dig_len) - n++; - - if (n > 255 || okm == NULL) - return NULL; - - if ((hmac = HMAC_CTX_new()) == NULL) - return NULL; - - if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL)) - goto err; - - for (i = 1; i <= n; i++) { - size_t copy_len; - const unsigned char ctr = i; - - if (i > 1) { - if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL)) - goto err; - - if (!HMAC_Update(hmac, prev, dig_len)) - goto err; - } - - if (!HMAC_Update(hmac, info, info_len)) - goto err; - - if (!HMAC_Update(hmac, &ctr, 1)) - goto err; - - if (!HMAC_Final(hmac, prev, NULL)) - goto err; - - copy_len = (done_len + dig_len > okm_len) ? - okm_len - done_len : - dig_len; - - memcpy(okm + done_len, prev, copy_len); - - done_len += copy_len; - } - ret = okm; - - err: - OPENSSL_cleanse(prev, sizeof(prev)); - HMAC_CTX_free(hmac); - return ret; -} diff --git a/crypto/openssl/crypto/kdf/kdf_err.c b/crypto/openssl/crypto/kdf/kdf_err.c index 1627c0a394b4..5b794285e47a 100644 --- a/crypto/openssl/crypto/kdf/kdf_err.c +++ b/crypto/openssl/crypto/kdf/kdf_err.c @@ -1,8 +1,8 @@ /* * 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 + * 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 @@ -11,57 +11,9 @@ #include #include -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA KDF_str_functs[] = { - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_CTRL_STR, 0), "pkey_hkdf_ctrl_str"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_DERIVE, 0), "pkey_hkdf_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_INIT, 0), "pkey_hkdf_init"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_SCRYPT_CTRL_STR, 0), - "pkey_scrypt_ctrl_str"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_SCRYPT_CTRL_UINT64, 0), - "pkey_scrypt_ctrl_uint64"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_SCRYPT_DERIVE, 0), "pkey_scrypt_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_SCRYPT_INIT, 0), "pkey_scrypt_init"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_SCRYPT_SET_MEMBUF, 0), - "pkey_scrypt_set_membuf"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_CTRL_STR, 0), - "pkey_tls1_prf_ctrl_str"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_DERIVE, 0), - "pkey_tls1_prf_derive"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_INIT, 0), "pkey_tls1_prf_init"}, - {ERR_PACK(ERR_LIB_KDF, KDF_F_TLS1_PRF_ALG, 0), "tls1_prf_alg"}, - {0, NULL} -}; - -static const ERR_STRING_DATA KDF_str_reasons[] = { - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_DIGEST), "invalid digest"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_ITERATION_COUNT), - "missing iteration count"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_KEY), "missing key"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_MESSAGE_DIGEST), - "missing message digest"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_PARAMETER), "missing parameter"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_PASS), "missing pass"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_SALT), "missing salt"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_SECRET), "missing secret"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_SEED), "missing seed"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNKNOWN_PARAMETER_TYPE), - "unknown parameter type"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_ERROR), "value error"}, - {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_MISSING), "value missing"}, - {0, NULL} -}; - -#endif - +#ifndef OPENSSL_NO_DEPRECATED_3_0 int ERR_load_KDF_strings(void) { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(KDF_str_functs[0].error) == NULL) { - ERR_load_strings_const(KDF_str_functs); - ERR_load_strings_const(KDF_str_reasons); - } -#endif return 1; } +#endif diff --git a/crypto/openssl/crypto/kdf/scrypt.c b/crypto/openssl/crypto/kdf/scrypt.c deleted file mode 100644 index 68606ac00aed..000000000000 --- a/crypto/openssl/crypto/kdf/scrypt.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include "internal/cryptlib.h" -#include "crypto/evp.h" - -#ifndef OPENSSL_NO_SCRYPT - -static int atou64(const char *nptr, uint64_t *result); - -typedef struct { - unsigned char *pass; - size_t pass_len; - unsigned char *salt; - size_t salt_len; - uint64_t N, r, p; - uint64_t maxmem_bytes; -} SCRYPT_PKEY_CTX; - -/* Custom uint64_t parser since we do not have strtoull */ -static int atou64(const char *nptr, uint64_t *result) -{ - uint64_t value = 0; - - while (*nptr) { - unsigned int digit; - uint64_t new_value; - - if ((*nptr < '0') || (*nptr > '9')) { - return 0; - } - digit = (unsigned int)(*nptr - '0'); - new_value = (value * 10) + digit; - if ((new_value < digit) || ((new_value - digit) / 10 != value)) { - /* Overflow */ - return 0; - } - value = new_value; - nptr++; - } - *result = value; - return 1; -} - -static int pkey_scrypt_init(EVP_PKEY_CTX *ctx) -{ - SCRYPT_PKEY_CTX *kctx; - - kctx = OPENSSL_zalloc(sizeof(*kctx)); - if (kctx == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - - /* Default values are the most conservative recommendation given in the - * original paper of C. Percival. Derivation uses roughly 1 GiB of memory - * for this parameter choice (approx. 128 * r * (N + p) bytes). - */ - kctx->N = 1 << 20; - kctx->r = 8; - kctx->p = 1; - kctx->maxmem_bytes = 1025 * 1024 * 1024; - - ctx->data = kctx; - - return 1; -} - -static void pkey_scrypt_cleanup(EVP_PKEY_CTX *ctx) -{ - SCRYPT_PKEY_CTX *kctx = ctx->data; - - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - OPENSSL_clear_free(kctx->pass, kctx->pass_len); - OPENSSL_free(kctx); -} - -static int pkey_scrypt_set_membuf(unsigned char **buffer, size_t *buflen, - const unsigned char *new_buffer, - const int new_buflen) -{ - if (new_buffer == NULL) - return 1; - - if (new_buflen < 0) - return 0; - - if (*buffer != NULL) - OPENSSL_clear_free(*buffer, *buflen); - - if (new_buflen > 0) { - *buffer = OPENSSL_memdup(new_buffer, new_buflen); - } else { - *buffer = OPENSSL_malloc(1); - } - if (*buffer == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_SET_MEMBUF, ERR_R_MALLOC_FAILURE); - return 0; - } - - *buflen = new_buflen; - return 1; -} - -static int is_power_of_two(uint64_t value) -{ - return (value != 0) && ((value & (value - 1)) == 0); -} - -static int pkey_scrypt_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - SCRYPT_PKEY_CTX *kctx = ctx->data; - uint64_t u64_value; - - switch (type) { - case EVP_PKEY_CTRL_PASS: - return pkey_scrypt_set_membuf(&kctx->pass, &kctx->pass_len, p2, p1); - - case EVP_PKEY_CTRL_SCRYPT_SALT: - return pkey_scrypt_set_membuf(&kctx->salt, &kctx->salt_len, p2, p1); - - case EVP_PKEY_CTRL_SCRYPT_N: - u64_value = *((uint64_t *)p2); - if ((u64_value <= 1) || !is_power_of_two(u64_value)) - return 0; - kctx->N = u64_value; - return 1; - - case EVP_PKEY_CTRL_SCRYPT_R: - u64_value = *((uint64_t *)p2); - if (u64_value < 1) - return 0; - kctx->r = u64_value; - return 1; - - case EVP_PKEY_CTRL_SCRYPT_P: - u64_value = *((uint64_t *)p2); - if (u64_value < 1) - return 0; - kctx->p = u64_value; - return 1; - - case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES: - u64_value = *((uint64_t *)p2); - if (u64_value < 1) - return 0; - kctx->maxmem_bytes = u64_value; - return 1; - - default: - return -2; - - } -} - -static int pkey_scrypt_ctrl_uint64(EVP_PKEY_CTX *ctx, int type, - const char *value) -{ - uint64_t int_value; - - if (!atou64(value, &int_value)) { - KDFerr(KDF_F_PKEY_SCRYPT_CTRL_UINT64, KDF_R_VALUE_ERROR); - return 0; - } - return pkey_scrypt_ctrl(ctx, type, 0, &int_value); -} - -static int pkey_scrypt_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, - const char *value) -{ - if (value == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_VALUE_MISSING); - return 0; - } - - if (strcmp(type, "pass") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_PASS, value); - - if (strcmp(type, "hexpass") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_PASS, value); - - if (strcmp(type, "salt") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value); - - if (strcmp(type, "hexsalt") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value); - - if (strcmp(type, "N") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_N, value); - - if (strcmp(type, "r") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_R, value); - - if (strcmp(type, "p") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_P, value); - - if (strcmp(type, "maxmem_bytes") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, - value); - - KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); - return -2; -} - -static int pkey_scrypt_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) -{ - SCRYPT_PKEY_CTX *kctx = ctx->data; - - if (kctx->pass == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_PASS); - return 0; - } - - if (kctx->salt == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_SALT); - return 0; - } - - return EVP_PBE_scrypt((char *)kctx->pass, kctx->pass_len, kctx->salt, - kctx->salt_len, kctx->N, kctx->r, kctx->p, - kctx->maxmem_bytes, key, *keylen); -} - -const EVP_PKEY_METHOD scrypt_pkey_meth = { - EVP_PKEY_SCRYPT, - 0, - pkey_scrypt_init, - 0, - pkey_scrypt_cleanup, - - 0, 0, - 0, 0, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - 0, - pkey_scrypt_derive, - pkey_scrypt_ctrl, - pkey_scrypt_ctrl_str -}; - -#endif diff --git a/crypto/openssl/crypto/kdf/tls1_prf.c b/crypto/openssl/crypto/kdf/tls1_prf.c deleted file mode 100644 index e9ca8e12780b..000000000000 --- a/crypto/openssl/crypto/kdf/tls1_prf.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" -#include -#include -#include "crypto/evp.h" - -static int tls1_prf_alg(const EVP_MD *md, - const unsigned char *sec, size_t slen, - const unsigned char *seed, size_t seed_len, - unsigned char *out, size_t olen); - -#define TLS1_PRF_MAXBUF 1024 - -/* TLS KDF pkey context structure */ - -typedef struct { - /* Digest to use for PRF */ - const EVP_MD *md; - /* Secret value to use for PRF */ - unsigned char *sec; - size_t seclen; - /* Buffer of concatenated seed data */ - unsigned char seed[TLS1_PRF_MAXBUF]; - size_t seedlen; -} TLS1_PRF_PKEY_CTX; - -static int pkey_tls1_prf_init(EVP_PKEY_CTX *ctx) -{ - TLS1_PRF_PKEY_CTX *kctx; - - if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - ctx->data = kctx; - - return 1; -} - -static void pkey_tls1_prf_cleanup(EVP_PKEY_CTX *ctx) -{ - TLS1_PRF_PKEY_CTX *kctx = ctx->data; - OPENSSL_clear_free(kctx->sec, kctx->seclen); - OPENSSL_cleanse(kctx->seed, kctx->seedlen); - OPENSSL_free(kctx); -} - -static int pkey_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - TLS1_PRF_PKEY_CTX *kctx = ctx->data; - switch (type) { - case EVP_PKEY_CTRL_TLS_MD: - kctx->md = p2; - return 1; - - case EVP_PKEY_CTRL_TLS_SECRET: - if (p1 < 0) - return 0; - if (kctx->sec != NULL) - OPENSSL_clear_free(kctx->sec, kctx->seclen); - OPENSSL_cleanse(kctx->seed, kctx->seedlen); - kctx->seedlen = 0; - kctx->sec = OPENSSL_memdup(p2, p1); - if (kctx->sec == NULL) - return 0; - kctx->seclen = p1; - return 1; - - case EVP_PKEY_CTRL_TLS_SEED: - if (p1 == 0 || p2 == NULL) - return 1; - if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - kctx->seedlen)) - return 0; - memcpy(kctx->seed + kctx->seedlen, p2, p1); - kctx->seedlen += p1; - return 1; - - default: - return -2; - - } -} - -static int pkey_tls1_prf_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (value == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING); - return 0; - } - if (strcmp(type, "md") == 0) { - TLS1_PRF_PKEY_CTX *kctx = ctx->data; - - const EVP_MD *md = EVP_get_digestbyname(value); - if (md == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_INVALID_DIGEST); - return 0; - } - kctx->md = md; - return 1; - } - if (strcmp(type, "secret") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value); - if (strcmp(type, "hexsecret") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value); - if (strcmp(type, "seed") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value); - if (strcmp(type, "hexseed") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value); - - KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); - return -2; -} - -static int pkey_tls1_prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) -{ - TLS1_PRF_PKEY_CTX *kctx = ctx->data; - if (kctx->md == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); - return 0; - } - if (kctx->sec == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SECRET); - return 0; - } - if (kctx->seedlen == 0) { - KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SEED); - return 0; - } - return tls1_prf_alg(kctx->md, kctx->sec, kctx->seclen, - kctx->seed, kctx->seedlen, - key, *keylen); -} - -const EVP_PKEY_METHOD tls1_prf_pkey_meth = { - EVP_PKEY_TLS1_PRF, - 0, - pkey_tls1_prf_init, - 0, - pkey_tls1_prf_cleanup, - - 0, 0, - 0, 0, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - 0, - pkey_tls1_prf_derive, - pkey_tls1_prf_ctrl, - pkey_tls1_prf_ctrl_str -}; - -static int tls1_prf_P_hash(const EVP_MD *md, - const unsigned char *sec, size_t sec_len, - const unsigned char *seed, size_t seed_len, - unsigned char *out, size_t olen) -{ - int chunk; - EVP_MD_CTX *ctx = NULL, *ctx_tmp = NULL, *ctx_init = NULL; - EVP_PKEY *mac_key = NULL; - unsigned char A1[EVP_MAX_MD_SIZE]; - size_t A1_len; - int ret = 0; - - chunk = EVP_MD_size(md); - if (!ossl_assert(chunk > 0)) - goto err; - - ctx = EVP_MD_CTX_new(); - ctx_tmp = EVP_MD_CTX_new(); - ctx_init = EVP_MD_CTX_new(); - if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL) - goto err; - EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - mac_key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, sec, sec_len); - if (mac_key == NULL) - goto err; - if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key)) - goto err; - if (!EVP_MD_CTX_copy_ex(ctx, ctx_init)) - goto err; - if (seed != NULL && !EVP_DigestSignUpdate(ctx, seed, seed_len)) - goto err; - if (!EVP_DigestSignFinal(ctx, A1, &A1_len)) - goto err; - - for (;;) { - /* Reinit mac contexts */ - if (!EVP_MD_CTX_copy_ex(ctx, ctx_init)) - goto err; - if (!EVP_DigestSignUpdate(ctx, A1, A1_len)) - goto err; - if (olen > (size_t)chunk && !EVP_MD_CTX_copy_ex(ctx_tmp, ctx)) - goto err; - if (seed && !EVP_DigestSignUpdate(ctx, seed, seed_len)) - goto err; - - if (olen > (size_t)chunk) { - size_t mac_len; - if (!EVP_DigestSignFinal(ctx, out, &mac_len)) - goto err; - out += mac_len; - olen -= mac_len; - /* calc the next A1 value */ - if (!EVP_DigestSignFinal(ctx_tmp, A1, &A1_len)) - goto err; - } else { /* last one */ - - if (!EVP_DigestSignFinal(ctx, A1, &A1_len)) - goto err; - memcpy(out, A1, olen); - break; - } - } - ret = 1; - err: - EVP_PKEY_free(mac_key); - EVP_MD_CTX_free(ctx); - EVP_MD_CTX_free(ctx_tmp); - EVP_MD_CTX_free(ctx_init); - OPENSSL_cleanse(A1, sizeof(A1)); - return ret; -} - -static int tls1_prf_alg(const EVP_MD *md, - const unsigned char *sec, size_t slen, - const unsigned char *seed, size_t seed_len, - unsigned char *out, size_t olen) -{ - - if (EVP_MD_type(md) == NID_md5_sha1) { - size_t i; - unsigned char *tmp; - if (!tls1_prf_P_hash(EVP_md5(), sec, slen/2 + (slen & 1), - seed, seed_len, out, olen)) - return 0; - - if ((tmp = OPENSSL_malloc(olen)) == NULL) { - KDFerr(KDF_F_TLS1_PRF_ALG, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!tls1_prf_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1), - seed, seed_len, tmp, olen)) { - OPENSSL_clear_free(tmp, olen); - return 0; - } - for (i = 0; i < olen; i++) - out[i] ^= tmp[i]; - OPENSSL_clear_free(tmp, olen); - return 1; - } - if (!tls1_prf_P_hash(md, sec, slen, seed, seed_len, out, olen)) - return 0; - - return 1; -} diff --git a/crypto/openssl/crypto/lhash/build.info b/crypto/openssl/crypto/lhash/build.info index 30797f2caf95..b3176b8358d4 100644 --- a/crypto/openssl/crypto/lhash/build.info +++ b/crypto/openssl/crypto/lhash/build.info @@ -1,3 +1,5 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ lhash.c lh_stats.c +SOURCE[../../providers/libfips.a]=\ + lhash.c diff --git a/crypto/openssl/crypto/lhash/lh_stats.c b/crypto/openssl/crypto/lhash/lh_stats.c index 45f1b105554f..ba4d4ea89708 100644 --- a/crypto/openssl/crypto/lhash/lh_stats.c +++ b/crypto/openssl/crypto/lhash/lh_stats.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -64,19 +64,19 @@ void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out) BIO_printf(out, "num_items = %lu\n", lh->num_items); BIO_printf(out, "num_nodes = %u\n", lh->num_nodes); BIO_printf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes); - BIO_printf(out, "num_expands = %lu\n", lh->num_expands); - BIO_printf(out, "num_expand_reallocs = %lu\n", lh->num_expand_reallocs); - BIO_printf(out, "num_contracts = %lu\n", lh->num_contracts); - BIO_printf(out, "num_contract_reallocs = %lu\n", lh->num_contract_reallocs); - BIO_printf(out, "num_hash_calls = %lu\n", lh->num_hash_calls); - BIO_printf(out, "num_comp_calls = %lu\n", lh->num_comp_calls); - BIO_printf(out, "num_insert = %lu\n", lh->num_insert); - BIO_printf(out, "num_replace = %lu\n", lh->num_replace); - BIO_printf(out, "num_delete = %lu\n", lh->num_delete); - BIO_printf(out, "num_no_delete = %lu\n", lh->num_no_delete); - BIO_printf(out, "num_retrieve = %lu\n", lh->num_retrieve); - BIO_printf(out, "num_retrieve_miss = %lu\n", lh->num_retrieve_miss); - BIO_printf(out, "num_hash_comps = %lu\n", lh->num_hash_comps); + BIO_printf(out, "num_expands = 0\n"); + BIO_printf(out, "num_expand_reallocs = 0\n"); + BIO_printf(out, "num_contracts = 0\n"); + BIO_printf(out, "num_contract_reallocs = 0\n"); + BIO_printf(out, "num_hash_calls = 0\n"); + BIO_printf(out, "num_comp_calls = 0\n"); + BIO_printf(out, "num_insert = 0\n"); + BIO_printf(out, "num_replace = 0\n"); + BIO_printf(out, "num_delete = 0\n"); + BIO_printf(out, "num_no_delete = 0\n"); + BIO_printf(out, "num_retrieve = 0\n"); + BIO_printf(out, "num_retrieve_miss = 0\n"); + BIO_printf(out, "num_hash_comps = 0\n"); } void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out) diff --git a/crypto/openssl/crypto/lhash/lhash.c b/crypto/openssl/crypto/lhash/lhash.c index 603224975ca1..1cd988f01fc7 100644 --- a/crypto/openssl/crypto/lhash/lhash.c +++ b/crypto/openssl/crypto/lhash/lhash.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -52,7 +52,7 @@ OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c) /* * Do not set the error code, because the ERR code uses LHASH * and we want to avoid possible endless error loop. - * CRYPTOerr(CRYPTO_F_OPENSSL_LH_NEW, ERR_R_MALLOC_FAILURE); + * ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); */ return NULL; } @@ -74,6 +74,16 @@ OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c) } void OPENSSL_LH_free(OPENSSL_LHASH *lh) +{ + if (lh == NULL) + return; + + OPENSSL_LH_flush(lh); + OPENSSL_free(lh->b); + OPENSSL_free(lh); +} + +void OPENSSL_LH_flush(OPENSSL_LHASH *lh) { unsigned int i; OPENSSL_LH_NODE *n, *nn; @@ -88,9 +98,10 @@ void OPENSSL_LH_free(OPENSSL_LHASH *lh) OPENSSL_free(n); n = nn; } + lh->b[i] = NULL; } - OPENSSL_free(lh->b); - OPENSSL_free(lh); + + lh->num_items = 0; } void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data) @@ -115,12 +126,10 @@ void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data) nn->hash = hash; *rn = nn; ret = NULL; - lh->num_insert++; lh->num_items++; } else { /* replace same key */ ret = (*rn)->data; (*rn)->data = data; - lh->num_replace++; } return ret; } @@ -135,14 +144,12 @@ void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data) rn = getrn(lh, data, &hash); if (*rn == NULL) { - lh->num_no_delete++; return NULL; } else { nn = *rn; *rn = nn->next; ret = nn->data; OPENSSL_free(nn); - lh->num_delete++; } lh->num_items--; @@ -157,21 +164,13 @@ void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data) { unsigned long hash; OPENSSL_LH_NODE **rn; - void *ret; - tsan_store((TSAN_QUALIFIER int *)&lh->error, 0); + if (lh->error != 0) + lh->error = 0; rn = getrn(lh, data, &hash); - if (*rn == NULL) { - tsan_counter(&lh->num_retrieve_miss); - return NULL; - } else { - ret = (*rn)->data; - tsan_counter(&lh->num_retrieve); - } - - return ret; + return *rn == NULL ? NULL : (*rn)->data; } static void doall_util_fn(OPENSSL_LHASH *lh, int use_arg, @@ -231,14 +230,12 @@ static int expand(OPENSSL_LHASH *lh) memset(n + nni, 0, sizeof(*n) * (j - nni)); lh->pmax = nni; lh->num_alloc_nodes = j; - lh->num_expand_reallocs++; lh->p = 0; } else { lh->p++; } lh->num_nodes++; - lh->num_expands++; n1 = &(lh->b[p]); n2 = &(lh->b[p + pmax]); *n2 = NULL; @@ -271,7 +268,6 @@ static void contract(OPENSSL_LHASH *lh) lh->error++; return; } - lh->num_contract_reallocs++; lh->num_alloc_nodes /= 2; lh->pmax /= 2; lh->p = lh->pmax - 1; @@ -280,7 +276,6 @@ static void contract(OPENSSL_LHASH *lh) lh->p--; lh->num_nodes--; - lh->num_contracts++; n1 = lh->b[(int)lh->p]; if (n1 == NULL) @@ -300,7 +295,6 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh, OPENSSL_LH_COMPFUNC cf; hash = (*(lh->hash)) (data); - tsan_counter(&lh->num_hash_calls); *rhash = hash; nn = hash % lh->pmax; @@ -310,12 +304,10 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh, cf = lh->comp; ret = &(lh->b[(int)nn]); for (n1 = *ret; n1 != NULL; n1 = n1->next) { - tsan_counter(&lh->num_hash_comps); if (n1->hash != hash) { ret = &(n1->next); continue; } - tsan_counter(&lh->num_comp_calls); if (cf(n1->data, data) == 0) break; ret = &(n1->next); @@ -352,7 +344,7 @@ unsigned long OPENSSL_LH_strhash(const char *c) return (ret >> 16) ^ ret; } -unsigned long openssl_lh_strcasehash(const char *c) +unsigned long ossl_lh_strcasehash(const char *c) { unsigned long ret = 0; long n; diff --git a/crypto/openssl/crypto/lhash/lhash_local.h b/crypto/openssl/crypto/lhash/lhash_local.h index 678224acd5d5..088ac94d2e63 100644 --- a/crypto/openssl/crypto/lhash/lhash_local.h +++ b/crypto/openssl/crypto/lhash/lhash_local.h @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -27,18 +27,5 @@ struct lhash_st { unsigned long up_load; /* load times 256 */ unsigned long down_load; /* load times 256 */ unsigned long num_items; - unsigned long num_expands; - unsigned long num_expand_reallocs; - unsigned long num_contracts; - unsigned long num_contract_reallocs; - TSAN_QUALIFIER unsigned long num_hash_calls; - TSAN_QUALIFIER unsigned long num_comp_calls; - unsigned long num_insert; - unsigned long num_replace; - unsigned long num_delete; - unsigned long num_no_delete; - TSAN_QUALIFIER unsigned long num_retrieve; - TSAN_QUALIFIER unsigned long num_retrieve_miss; - TSAN_QUALIFIER unsigned long num_hash_comps; int error; }; diff --git a/crypto/openssl/crypto/md2/build.info b/crypto/openssl/crypto/md2/build.info index e31948c23f5b..541245331f12 100644 --- a/crypto/openssl/crypto/md2/build.info +++ b/crypto/openssl/crypto/md2/build.info @@ -1,3 +1,9 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - md2_dgst.c md2_one.c + +SOURCE[../../libcrypto]=md2_dgst.c md2_one.c + +# When all deprecated symbols are removed, libcrypto doesn't export the +# MD2 functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=md2_dgst.c md2_one.c +ENDIF diff --git a/crypto/openssl/crypto/md2/md2_dgst.c b/crypto/openssl/crypto/md2/md2_dgst.c index faa9393f2e46..0b0033543881 100644 --- a/crypto/openssl/crypto/md2/md2_dgst.c +++ b/crypto/openssl/crypto/md2/md2_dgst.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * MD2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/openssl/crypto/md2/md2_one.c b/crypto/openssl/crypto/md2/md2_one.c index 5502b21696d4..f9be692732e0 100644 --- a/crypto/openssl/crypto/md2/md2_one.c +++ b/crypto/openssl/crypto/md2/md2_one.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * MD2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include diff --git a/crypto/openssl/crypto/md4/build.info b/crypto/openssl/crypto/md4/build.info index 20846e0dcee8..ccd93835f708 100644 --- a/crypto/openssl/crypto/md4/build.info +++ b/crypto/openssl/crypto/md4/build.info @@ -1,3 +1,9 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - md4_dgst.c md4_one.c + +SOURCE[../../libcrypto]=md4_dgst.c md4_one.c + +# When all deprecated symbols are removed, libcrypto doesn't export the +# MD4 functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=md4_dgst.c md4_one.c +ENDIF diff --git a/crypto/openssl/crypto/md4/md4_dgst.c b/crypto/openssl/crypto/md4/md4_dgst.c index 29b6b252bae3..aefe6a3a3770 100644 --- a/crypto/openssl/crypto/md4/md4_dgst.c +++ b/crypto/openssl/crypto/md4/md4_dgst.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * MD4 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include "md4_local.h" diff --git a/crypto/openssl/crypto/md4/md4_local.h b/crypto/openssl/crypto/md4/md4_local.h index 5f05720e9769..66aa5e403897 100644 --- a/crypto/openssl/crypto/md4/md4_local.h +++ b/crypto/openssl/crypto/md4/md4_local.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/md4/md4_one.c b/crypto/openssl/crypto/md4/md4_one.c index 9e52303c2fca..36fa88dd4166 100644 --- a/crypto/openssl/crypto/md4/md4_one.c +++ b/crypto/openssl/crypto/md4/md4_one.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * MD4 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/openssl/crypto/md5/asm/md5-586.pl b/crypto/openssl/crypto/md5/asm/md5-586.pl index 7986a2413da2..8dd8fa0cf765 100755 --- a/crypto/openssl/crypto/md5/asm/md5-586.pl +++ b/crypto/openssl/crypto/md5/asm/md5-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -18,8 +18,10 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; + +$output and open STDOUT,">$output"; &asm_init($ARGV[0]); @@ -40,7 +42,7 @@ $X="esi"; 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, # R3 ); -&md5_block("md5_block_asm_data_order"); +&md5_block("ossl_md5_block_asm_data_order"); &asm_finish(); close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/md5/asm/md5-sparcv9.pl b/crypto/openssl/crypto/md5/asm/md5-sparcv9.pl index 3595e3d32fc9..c41ccf6ba901 100755 --- a/crypto/openssl/crypto/md5/asm/md5-sparcv9.pl +++ b/crypto/openssl/crypto/md5/asm/md5-sparcv9.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -24,8 +24,10 @@ # single-process result on 8-core processor, or ~11GBps per 2.85GHz # socket. -$output=pop; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; + +$output and open STDOUT,">$output"; use integer; @@ -201,7 +203,10 @@ ___ } $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #ifdef __arch64__ .register %g2,#scratch @@ -214,9 +219,9 @@ $code.=<<___; SPARC_PIC_THUNK(%g1) #endif -.globl md5_block_asm_data_order +.globl ossl_md5_block_asm_data_order .align 32 -md5_block_asm_data_order: +ossl_md5_block_asm_data_order: SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5) ld [%g1+4],%g1 ! OPENSSL_sparcv9cap_P[1] @@ -369,8 +374,8 @@ $code.=<<___; wr %g0,$saved_asi,%asi ret restore -.type md5_block_asm_data_order,#function -.size md5_block_asm_data_order,(.-md5_block_asm_data_order) +.type ossl_md5_block_asm_data_order,#function +.size ossl_md5_block_asm_data_order,(.-ossl_md5_block_asm_data_order) .asciz "MD5 block transform for SPARCv9, CRYPTOGAMS by " .align 4 diff --git a/crypto/openssl/crypto/md5/asm/md5-x86_64.pl b/crypto/openssl/crypto/md5/asm/md5-x86_64.pl index c6a172d448c6..6625fb7d08aa 100755 --- a/crypto/openssl/crypto/md5/asm/md5-x86_64.pl +++ b/crypto/openssl/crypto/md5/asm/md5-x86_64.pl @@ -2,7 +2,7 @@ # Author: Marc Bevand # Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -119,9 +119,10 @@ EOF } no warnings qw(uninitialized); -my $flavour = shift; -my $output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -130,16 +131,17 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $code .= < #include "md5_local.h" #include diff --git a/crypto/openssl/crypto/md5/md5_local.h b/crypto/openssl/crypto/md5/md5_local.h index b0087bea81c4..22a0e0f62aed 100644 --- a/crypto/openssl/crypto/md5/md5_local.h +++ b/crypto/openssl/crypto/md5/md5_local.h @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,11 +15,11 @@ #ifdef MD5_ASM # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) -# define md5_block_data_order md5_block_asm_data_order +# define md5_block_data_order ossl_md5_block_asm_data_order # elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) -# define md5_block_data_order md5_block_asm_data_order +# define md5_block_data_order ossl_md5_block_asm_data_order # elif defined(__sparc) || defined(__sparc__) -# define md5_block_data_order md5_block_asm_data_order +# define md5_block_data_order ossl_md5_block_asm_data_order # endif #endif diff --git a/crypto/openssl/crypto/md5/md5_one.c b/crypto/openssl/crypto/md5/md5_one.c index c3bf2f88f0ba..fe9b3df29e83 100644 --- a/crypto/openssl/crypto/md5/md5_one.c +++ b/crypto/openssl/crypto/md5/md5_one.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * MD5 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/openssl/crypto/evp/m_md5_sha1.c b/crypto/openssl/crypto/md5/md5_sha1.c similarity index 59% rename from crypto/openssl/crypto/evp/m_md5_sha1.c rename to crypto/openssl/crypto/md5/md5_sha1.c index eeec2b13e9ed..56defab163fa 100644 --- a/crypto/openssl/crypto/evp/m_md5_sha1.c +++ b/crypto/openssl/crypto/md5/md5_sha1.c @@ -1,67 +1,55 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ -#if !defined(OPENSSL_NO_MD5) - -# include -# include -# include -# include -# include -# include "internal/cryptlib.h" -# include "crypto/evp.h" -# include +/* + * MD5 and SHA-1 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" -struct md5_sha1_ctx { - MD5_CTX md5; - SHA_CTX sha1; -}; +#include +#include "prov/md5_sha1.h" +#include -static int init(EVP_MD_CTX *ctx) +int ossl_md5_sha1_init(MD5_SHA1_CTX *mctx) { - struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx); if (!MD5_Init(&mctx->md5)) return 0; return SHA1_Init(&mctx->sha1); } -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +int ossl_md5_sha1_update(MD5_SHA1_CTX *mctx, const void *data, size_t count) { - struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx); if (!MD5_Update(&mctx->md5, data, count)) return 0; return SHA1_Update(&mctx->sha1, data, count); } -static int final(EVP_MD_CTX *ctx, unsigned char *md) +int ossl_md5_sha1_final(unsigned char *md, MD5_SHA1_CTX *mctx) { - struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx); if (!MD5_Final(md, &mctx->md5)) return 0; return SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1); } -static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) +int ossl_md5_sha1_ctrl(MD5_SHA1_CTX *mctx, int cmd, int mslen, void *ms) { unsigned char padtmp[48]; unsigned char md5tmp[MD5_DIGEST_LENGTH]; unsigned char sha1tmp[SHA_DIGEST_LENGTH]; - struct md5_sha1_ctx *mctx; if (cmd != EVP_CTRL_SSL3_MASTER_SECRET) return -2; - if (ctx == NULL) + if (mctx == NULL) return 0; - mctx = EVP_MD_CTX_md_data(ctx); - /* SSLv3 client auth handling: see RFC-6101 5.6.8 */ if (mslen != 48) return 0; @@ -70,7 +58,7 @@ static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) * with master secret and pad_1. */ - if (update(ctx, ms, mslen) <= 0) + if (ossl_md5_sha1_update(mctx, ms, mslen) <= 0) return 0; /* Set padtmp to pad_1 value */ @@ -90,10 +78,10 @@ static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) /* Reinitialise context */ - if (!init(ctx)) + if (!ossl_md5_sha1_init(mctx)) return 0; - if (update(ctx, ms, mslen) <= 0) + if (ossl_md5_sha1_update(mctx, ms, mslen) <= 0) return 0; /* Set padtmp to pad_2 value */ @@ -117,26 +105,4 @@ static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp)); return 1; - -} - -static const EVP_MD md5_sha1_md = { - NID_md5_sha1, - NID_md5_sha1, - MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - MD5_CBLOCK, - sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx), - ctrl -}; - -const EVP_MD *EVP_md5_sha1(void) -{ - return &md5_sha1_md; } -#endif diff --git a/crypto/openssl/crypto/mdc2/build.info b/crypto/openssl/crypto/mdc2/build.info index 8fe6878d600a..f748357b1a48 100644 --- a/crypto/openssl/crypto/mdc2/build.info +++ b/crypto/openssl/crypto/mdc2/build.info @@ -1,3 +1,9 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - mdc2dgst.c mdc2_one.c + +SOURCE[../../libcrypto]=mdc2dgst.c mdc2_one.c + +# When all deprecated symbols are removed, libcrypto doesn't export the +# MDC2 functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=mdc2dgst.c mdc2_one.c +ENDIF diff --git a/crypto/openssl/crypto/mdc2/mdc2_one.c b/crypto/openssl/crypto/mdc2/mdc2_one.c index 58e1e0fdf6c7..cb978263ed5d 100644 --- a/crypto/openssl/crypto/mdc2/mdc2_one.c +++ b/crypto/openssl/crypto/mdc2/mdc2_one.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * MD2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include diff --git a/crypto/openssl/crypto/mdc2/mdc2dgst.c b/crypto/openssl/crypto/mdc2/mdc2dgst.c index 14233b9aba08..607f9fc73a3e 100644 --- a/crypto/openssl/crypto/mdc2/mdc2dgst.c +++ b/crypto/openssl/crypto/mdc2/mdc2dgst.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * MD2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/openssl/crypto/mem.c b/crypto/openssl/crypto/mem.c index 2b39ca3a1049..f6cdcf5a423e 100644 --- a/crypto/openssl/crypto/mem.c +++ b/crypto/openssl/crypto/mem.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,36 +14,34 @@ #include #include #include -#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE -# include -#endif /* * the following pointers may be changed as long as 'allow_customize' is set */ static int allow_customize = 1; +static CRYPTO_malloc_fn malloc_impl = CRYPTO_malloc; +static CRYPTO_realloc_fn realloc_impl = CRYPTO_realloc; +static CRYPTO_free_fn free_impl = CRYPTO_free; -static void *(*malloc_impl)(size_t, const char *, int) - = CRYPTO_malloc; -static void *(*realloc_impl)(void *, size_t, const char *, int) - = CRYPTO_realloc; -static void (*free_impl)(void *, const char *, int) - = CRYPTO_free; - -#ifndef OPENSSL_NO_CRYPTO_MDEBUG +#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODULE) # include "internal/tsan_assist.h" +# ifdef TSAN_REQUIRES_LOCKING +# define INCREMENT(x) /* empty */ +# define LOAD(x) 0 +# else /* TSAN_REQUIRES_LOCKING */ static TSAN_QUALIFIER int malloc_count; static TSAN_QUALIFIER int realloc_count; static TSAN_QUALIFIER int free_count; -# define INCREMENT(x) tsan_counter(&(x)) +# define INCREMENT(x) tsan_counter(&(x)) +# define LOAD(x) tsan_load(&x) +# endif /* TSAN_REQUIRES_LOCKING */ static char *md_failstring; static long md_count; static int md_fail_percent = 0; static int md_tracefd = -1; -static int call_malloc_debug = 1; static void parseit(void); static int shouldfail(void); @@ -51,58 +49,47 @@ static int shouldfail(void); # define FAILTEST() if (shouldfail()) return NULL #else -static int call_malloc_debug = 0; # define INCREMENT(x) /* empty */ # define FAILTEST() /* empty */ #endif -int CRYPTO_set_mem_functions( - void *(*m)(size_t, const char *, int), - void *(*r)(void *, size_t, const char *, int), - void (*f)(void *, const char *, int)) -{ - if (!allow_customize) - return 0; - if (m) - malloc_impl = m; - if (r) - realloc_impl = r; - if (f) - free_impl = f; - return 1; -} - -int CRYPTO_set_mem_debug(int flag) +int CRYPTO_set_mem_functions(CRYPTO_malloc_fn malloc_fn, + CRYPTO_realloc_fn realloc_fn, + CRYPTO_free_fn free_fn) { if (!allow_customize) return 0; - call_malloc_debug = flag; + if (malloc_fn != NULL) + malloc_impl = malloc_fn; + if (realloc_fn != NULL) + realloc_impl = realloc_fn; + if (free_fn != NULL) + free_impl = free_fn; return 1; } -void CRYPTO_get_mem_functions( - void *(**m)(size_t, const char *, int), - void *(**r)(void *, size_t, const char *, int), - void (**f)(void *, const char *, int)) +void CRYPTO_get_mem_functions(CRYPTO_malloc_fn *malloc_fn, + CRYPTO_realloc_fn *realloc_fn, + CRYPTO_free_fn *free_fn) { - if (m != NULL) - *m = malloc_impl; - if (r != NULL) - *r = realloc_impl; - if (f != NULL) - *f = free_impl; + if (malloc_fn != NULL) + *malloc_fn = malloc_impl; + if (realloc_fn != NULL) + *realloc_fn = realloc_impl; + if (free_fn != NULL) + *free_fn = free_impl; } -#ifndef OPENSSL_NO_CRYPTO_MDEBUG +#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODULE) void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount) { if (mcount != NULL) - *mcount = tsan_load(&malloc_count); + *mcount = LOAD(malloc_count); if (rcount != NULL) - *rcount = tsan_load(&realloc_count); + *rcount = LOAD(realloc_count); if (fcount != NULL) - *fcount = tsan_load(&free_count); + *fcount = LOAD(free_count); } /* @@ -158,14 +145,6 @@ static int shouldfail(void) len = strlen(buff); if (write(md_tracefd, buff, len) != len) perror("shouldfail write failed"); -# ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE - if (shoulditfail) { - void *addrs[30]; - int num = backtrace(addrs, OSSL_NELEM(addrs)); - - backtrace_symbols_fd(addrs, num, md_tracefd); - } -# endif } # endif @@ -191,10 +170,8 @@ void ossl_malloc_setup_failures(void) void *CRYPTO_malloc(size_t num, const char *file, int line) { - void *ret = NULL; - INCREMENT(malloc_count); - if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc) + if (malloc_impl != CRYPTO_malloc) return malloc_impl(num, file, line); if (num == 0) @@ -209,36 +186,26 @@ void *CRYPTO_malloc(size_t num, const char *file, int line) */ allow_customize = 0; } -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - if (call_malloc_debug) { - CRYPTO_mem_debug_malloc(NULL, num, 0, file, line); - ret = malloc(num); - CRYPTO_mem_debug_malloc(ret, num, 1, file, line); - } else { - ret = malloc(num); - } -#else - (void)(file); (void)(line); - ret = malloc(num); -#endif - return ret; + return malloc(num); } void *CRYPTO_zalloc(size_t num, const char *file, int line) { - void *ret = CRYPTO_malloc(num, file, line); + void *ret; + ret = CRYPTO_malloc(num, file, line); FAILTEST(); if (ret != NULL) memset(ret, 0, num); + return ret; } void *CRYPTO_realloc(void *str, size_t num, const char *file, int line) { INCREMENT(realloc_count); - if (realloc_impl != NULL && realloc_impl != &CRYPTO_realloc) + if (realloc_impl != CRYPTO_realloc) return realloc_impl(str, num, file, line); FAILTEST(); @@ -250,19 +217,7 @@ void *CRYPTO_realloc(void *str, size_t num, const char *file, int line) return NULL; } -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - if (call_malloc_debug) { - void *ret; - CRYPTO_mem_debug_realloc(str, NULL, num, 0, file, line); - ret = realloc(str, num); - CRYPTO_mem_debug_realloc(str, ret, num, 1, file, line); - return ret; - } -#else - (void)(file); (void)(line); -#endif return realloc(str, num); - } void *CRYPTO_clear_realloc(void *str, size_t old_len, size_t num, @@ -295,22 +250,12 @@ void *CRYPTO_clear_realloc(void *str, size_t old_len, size_t num, void CRYPTO_free(void *str, const char *file, int line) { INCREMENT(free_count); - if (free_impl != NULL && free_impl != &CRYPTO_free) { + if (free_impl != CRYPTO_free) { free_impl(str, file, line); return; } -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - if (call_malloc_debug) { - CRYPTO_mem_debug_free(str, 0, file, line); - free(str); - CRYPTO_mem_debug_free(str, 1, file, line); - } else { - free(str); - } -#else free(str); -#endif } void CRYPTO_clear_free(void *str, size_t num, const char *file, int line) @@ -321,3 +266,72 @@ void CRYPTO_clear_free(void *str, size_t num, const char *file, int line) OPENSSL_cleanse(str, num); CRYPTO_free(str, file, line); } + +#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +int CRYPTO_mem_ctrl(int mode) +{ + (void)mode; + return -1; +} + +int CRYPTO_set_mem_debug(int flag) +{ + (void)flag; + return -1; +} + +int CRYPTO_mem_debug_push(const char *info, const char *file, int line) +{ + (void)info; (void)file; (void)line; + return 0; +} + +int CRYPTO_mem_debug_pop(void) +{ + return 0; +} + +void CRYPTO_mem_debug_malloc(void *addr, size_t num, int flag, + const char *file, int line) +{ + (void)addr; (void)num; (void)flag; (void)file; (void)line; +} + +void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num, int flag, + const char *file, int line) +{ + (void)addr1; (void)addr2; (void)num; (void)flag; (void)file; (void)line; +} + +void CRYPTO_mem_debug_free(void *addr, int flag, + const char *file, int line) +{ + (void)addr; (void)flag; (void)file; (void)line; +} + +int CRYPTO_mem_leaks(BIO *b) +{ + (void)b; + return -1; +} + +# ifndef OPENSSL_NO_STDIO +int CRYPTO_mem_leaks_fp(FILE *fp) +{ + (void)fp; + return -1; +} +# endif + +int CRYPTO_mem_leaks_cb(int (*cb)(const char *str, size_t len, void *u), + void *u) +{ + (void)cb; (void)u; + return -1; +} + +# endif + +#endif diff --git a/crypto/openssl/crypto/mem_clr.c b/crypto/openssl/crypto/mem_clr.c index 35bfb74eaebd..d76ef73179d0 100644 --- a/crypto/openssl/crypto/mem_clr.c +++ b/crypto/openssl/crypto/mem_clr.c @@ -1,7 +1,7 @@ /* * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/mem_dbg.c b/crypto/openssl/crypto/mem_dbg.c deleted file mode 100644 index 0489e97adbda..000000000000 --- a/crypto/openssl/crypto/mem_dbg.c +++ /dev/null @@ -1,670 +0,0 @@ -/* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include "internal/cryptlib.h" -#include "internal/thread_once.h" -#include -#include -#include "internal/bio.h" -#include - -#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE -# include -#endif - -/* - * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when - * the application asks for it (usually after library initialisation for - * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only - * temporarily when the library thinks that certain allocations should not be - * checked (e.g. the data structures used for memory checking). It is not - * suitable as an initial state: the library will unexpectedly enable memory - * checking when it executes one of those sections that want to disable - * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes - * no sense whatsoever. - */ -#ifndef OPENSSL_NO_CRYPTO_MDEBUG -static int mh_mode = CRYPTO_MEM_CHECK_OFF; -#endif - -#ifndef OPENSSL_NO_CRYPTO_MDEBUG -static unsigned long order = 0; /* number of memory requests */ - -/*- - * For application-defined information (static C-string `info') - * to be displayed in memory leak list. - * Each thread has its own stack. For applications, there is - * OPENSSL_mem_debug_push("...") to push an entry, - * OPENSSL_mem_debug_pop() to pop an entry, - */ -struct app_mem_info_st { - CRYPTO_THREAD_ID threadid; - const char *file; - int line; - const char *info; - struct app_mem_info_st *next; /* tail of thread's stack */ - int references; -}; - -static CRYPTO_ONCE memdbg_init = CRYPTO_ONCE_STATIC_INIT; -CRYPTO_RWLOCK *memdbg_lock; -static CRYPTO_RWLOCK *long_memdbg_lock; -static CRYPTO_THREAD_LOCAL appinfokey; - -/* memory-block description */ -struct mem_st { - void *addr; - int num; - const char *file; - int line; - CRYPTO_THREAD_ID threadid; - unsigned long order; - time_t time; - APP_INFO *app_info; -#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE - void *array[30]; - size_t array_siz; -#endif -}; - -/* - * hash-table of memory requests (address as * key); access requires - * long_memdbg_lock lock - */ -static LHASH_OF(MEM) *mh = NULL; - -/* num_disable > 0 iff mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */ -static unsigned int num_disable = 0; - -/* - * Valid iff num_disable > 0. long_memdbg_lock is locked exactly in this - * case (by the thread named in disabling_thread). - */ -static CRYPTO_THREAD_ID disabling_threadid; - -DEFINE_RUN_ONCE_STATIC(do_memdbg_init) -{ - memdbg_lock = CRYPTO_THREAD_lock_new(); - long_memdbg_lock = CRYPTO_THREAD_lock_new(); - if (memdbg_lock == NULL || long_memdbg_lock == NULL - || !CRYPTO_THREAD_init_local(&appinfokey, NULL)) { - CRYPTO_THREAD_lock_free(memdbg_lock); - memdbg_lock = NULL; - CRYPTO_THREAD_lock_free(long_memdbg_lock); - long_memdbg_lock = NULL; - return 0; - } - return 1; -} - -static void app_info_free(APP_INFO *inf) -{ - if (inf == NULL) - return; - if (--(inf->references) <= 0) { - app_info_free(inf->next); - OPENSSL_free(inf); - } -} -#endif - -int CRYPTO_mem_ctrl(int mode) -{ -#ifdef OPENSSL_NO_CRYPTO_MDEBUG - return mode - mode; -#else - int ret = mh_mode; - - if (!RUN_ONCE(&memdbg_init, do_memdbg_init)) - return -1; - - CRYPTO_THREAD_write_lock(memdbg_lock); - switch (mode) { - default: - break; - - case CRYPTO_MEM_CHECK_ON: - mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE; - num_disable = 0; - break; - - case CRYPTO_MEM_CHECK_OFF: - mh_mode = 0; - num_disable = 0; - break; - - /* switch off temporarily (for library-internal use): */ - case CRYPTO_MEM_CHECK_DISABLE: - if (mh_mode & CRYPTO_MEM_CHECK_ON) { - CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id(); - /* see if we don't have long_memdbg_lock already */ - if (!num_disable - || !CRYPTO_THREAD_compare_id(disabling_threadid, cur)) { - /* - * Long-time lock long_memdbg_lock must not be claimed - * while we're holding memdbg_lock, or we'll deadlock - * if somebody else holds long_memdbg_lock (and cannot - * release it because we block entry to this function). Give - * them a chance, first, and then claim the locks in - * appropriate order (long-time lock first). - */ - CRYPTO_THREAD_unlock(memdbg_lock); - /* - * Note that after we have waited for long_memdbg_lock and - * memdbg_lock, we'll still be in the right "case" and - * "if" branch because MemCheck_start and MemCheck_stop may - * never be used while there are multiple OpenSSL threads. - */ - CRYPTO_THREAD_write_lock(long_memdbg_lock); - CRYPTO_THREAD_write_lock(memdbg_lock); - mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE; - disabling_threadid = cur; - } - num_disable++; - } - break; - - case CRYPTO_MEM_CHECK_ENABLE: - if (mh_mode & CRYPTO_MEM_CHECK_ON) { - if (num_disable) { /* always true, or something is going wrong */ - num_disable--; - if (num_disable == 0) { - mh_mode |= CRYPTO_MEM_CHECK_ENABLE; - CRYPTO_THREAD_unlock(long_memdbg_lock); - } - } - } - break; - } - CRYPTO_THREAD_unlock(memdbg_lock); - return ret; -#endif -} - -#ifndef OPENSSL_NO_CRYPTO_MDEBUG - -static int mem_check_on(void) -{ - int ret = 0; - CRYPTO_THREAD_ID cur; - - if (mh_mode & CRYPTO_MEM_CHECK_ON) { - if (!RUN_ONCE(&memdbg_init, do_memdbg_init)) - return 0; - - cur = CRYPTO_THREAD_get_current_id(); - CRYPTO_THREAD_read_lock(memdbg_lock); - - ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) - || !CRYPTO_THREAD_compare_id(disabling_threadid, cur); - - CRYPTO_THREAD_unlock(memdbg_lock); - } - return ret; -} - -static int mem_cmp(const MEM *a, const MEM *b) -{ -#ifdef _WIN64 - const char *ap = (const char *)a->addr, *bp = (const char *)b->addr; - if (ap == bp) - return 0; - else if (ap > bp) - return 1; - else - return -1; -#else - return (const char *)a->addr - (const char *)b->addr; -#endif -} - -static unsigned long mem_hash(const MEM *a) -{ - size_t ret; - - ret = (size_t)a->addr; - - ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251; - return ret; -} - -/* returns 1 if there was an info to pop, 0 if the stack was empty. */ -static int pop_info(void) -{ - APP_INFO *current = NULL; - - if (!RUN_ONCE(&memdbg_init, do_memdbg_init)) - return 0; - - current = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey); - if (current != NULL) { - APP_INFO *next = current->next; - - if (next != NULL) { - next->references++; - CRYPTO_THREAD_set_local(&appinfokey, next); - } else { - CRYPTO_THREAD_set_local(&appinfokey, NULL); - } - if (--(current->references) <= 0) { - current->next = NULL; - if (next != NULL) - next->references--; - OPENSSL_free(current); - } - return 1; - } - return 0; -} - -int CRYPTO_mem_debug_push(const char *info, const char *file, int line) -{ - APP_INFO *ami, *amim; - int ret = 0; - - if (mem_check_on()) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - - if (!RUN_ONCE(&memdbg_init, do_memdbg_init) - || (ami = OPENSSL_malloc(sizeof(*ami))) == NULL) - goto err; - - ami->threadid = CRYPTO_THREAD_get_current_id(); - ami->file = file; - ami->line = line; - ami->info = info; - ami->references = 1; - ami->next = NULL; - - amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey); - CRYPTO_THREAD_set_local(&appinfokey, ami); - - if (amim != NULL) - ami->next = amim; - ret = 1; - err: - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } - - return ret; -} - -int CRYPTO_mem_debug_pop(void) -{ - int ret = 0; - - if (mem_check_on()) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - ret = pop_info(); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } - return ret; -} - -static unsigned long break_order_num = 0; - -void CRYPTO_mem_debug_malloc(void *addr, size_t num, int before_p, - const char *file, int line) -{ - MEM *m, *mm; - APP_INFO *amim; - - switch (before_p & 127) { - case 0: - break; - case 1: - if (addr == NULL) - break; - - if (mem_check_on()) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - - if (!RUN_ONCE(&memdbg_init, do_memdbg_init) - || (m = OPENSSL_malloc(sizeof(*m))) == NULL) { - OPENSSL_free(addr); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - return; - } - if (mh == NULL) { - if ((mh = lh_MEM_new(mem_hash, mem_cmp)) == NULL) { - OPENSSL_free(addr); - OPENSSL_free(m); - addr = NULL; - goto err; - } - } - - m->addr = addr; - m->file = file; - m->line = line; - m->num = num; - m->threadid = CRYPTO_THREAD_get_current_id(); - - if (order == break_order_num) { - /* BREAK HERE */ - m->order = order; - } - m->order = order++; -# ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE - m->array_siz = backtrace(m->array, OSSL_NELEM(m->array)); -# endif - m->time = time(NULL); - - amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey); - m->app_info = amim; - if (amim != NULL) - amim->references++; - - if ((mm = lh_MEM_insert(mh, m)) != NULL) { - /* Not good, but don't sweat it */ - if (mm->app_info != NULL) { - mm->app_info->references--; - } - OPENSSL_free(mm); - } - err: - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } - break; - } - return; -} - -void CRYPTO_mem_debug_free(void *addr, int before_p, - const char *file, int line) -{ - MEM m, *mp; - - switch (before_p) { - case 0: - if (addr == NULL) - break; - - if (mem_check_on() && (mh != NULL)) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - - m.addr = addr; - mp = lh_MEM_delete(mh, &m); - if (mp != NULL) { - app_info_free(mp->app_info); - OPENSSL_free(mp); - } - - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } - break; - case 1: - break; - } -} - -void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num, - int before_p, const char *file, int line) -{ - MEM m, *mp; - - switch (before_p) { - case 0: - break; - case 1: - if (addr2 == NULL) - break; - - if (addr1 == NULL) { - CRYPTO_mem_debug_malloc(addr2, num, 128 | before_p, file, line); - break; - } - - if (mem_check_on()) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - - m.addr = addr1; - mp = lh_MEM_delete(mh, &m); - if (mp != NULL) { - mp->addr = addr2; - mp->num = num; -#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE - mp->array_siz = backtrace(mp->array, OSSL_NELEM(mp->array)); -#endif - (void)lh_MEM_insert(mh, mp); - } - - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } - break; - } - return; -} - -typedef struct mem_leak_st { - int (*print_cb) (const char *str, size_t len, void *u); - void *print_cb_arg; - int chunks; - long bytes; -} MEM_LEAK; - -static void print_leak(const MEM *m, MEM_LEAK *l) -{ - char buf[1024]; - char *bufp = buf; - size_t len = sizeof(buf), ami_cnt; - APP_INFO *amip; - int n; - struct tm *lcl = NULL; - /* - * Convert between CRYPTO_THREAD_ID (which could be anything at all) and - * a long. This may not be meaningful depending on what CRYPTO_THREAD_ID is - * but hopefully should give something sensible on most platforms - */ - union { - CRYPTO_THREAD_ID tid; - unsigned long ltid; - } tid; - CRYPTO_THREAD_ID ti; - - lcl = localtime(&m->time); - n = BIO_snprintf(bufp, len, "[%02d:%02d:%02d] ", - lcl->tm_hour, lcl->tm_min, lcl->tm_sec); - if (n <= 0) { - bufp[0] = '\0'; - return; - } - bufp += n; - len -= n; - - n = BIO_snprintf(bufp, len, "%5lu file=%s, line=%d, ", - m->order, m->file, m->line); - if (n <= 0) - return; - bufp += n; - len -= n; - - tid.ltid = 0; - tid.tid = m->threadid; - n = BIO_snprintf(bufp, len, "thread=%lu, ", tid.ltid); - if (n <= 0) - return; - bufp += n; - len -= n; - - n = BIO_snprintf(bufp, len, "number=%d, address=%p\n", m->num, m->addr); - if (n <= 0) - return; - bufp += n; - len -= n; - - l->print_cb(buf, (size_t)(bufp - buf), l->print_cb_arg); - - l->chunks++; - l->bytes += m->num; - - amip = m->app_info; - ami_cnt = 0; - - if (amip) { - ti = amip->threadid; - - do { - int buf_len; - int info_len; - - ami_cnt++; - if (ami_cnt >= sizeof(buf) - 1) - break; - memset(buf, '>', ami_cnt); - buf[ami_cnt] = '\0'; - tid.ltid = 0; - tid.tid = amip->threadid; - n = BIO_snprintf(buf + ami_cnt, sizeof(buf) - ami_cnt, - " thread=%lu, file=%s, line=%d, info=\"", - tid.ltid, amip->file, amip->line); - if (n <= 0) - break; - buf_len = ami_cnt + n; - info_len = strlen(amip->info); - if (128 - buf_len - 3 < info_len) { - memcpy(buf + buf_len, amip->info, 128 - buf_len - 3); - buf_len = 128 - 3; - } else { - n = BIO_snprintf(buf + buf_len, sizeof(buf) - buf_len, "%s", - amip->info); - if (n < 0) - break; - buf_len += n; - } - n = BIO_snprintf(buf + buf_len, sizeof(buf) - buf_len, "\"\n"); - if (n <= 0) - break; - - l->print_cb(buf, buf_len + n, l->print_cb_arg); - - amip = amip->next; - } - while (amip && CRYPTO_THREAD_compare_id(amip->threadid, ti)); - } - -#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE - { - size_t i; - char **strings = backtrace_symbols(m->array, m->array_siz); - - for (i = 0; i < m->array_siz; i++) - fprintf(stderr, "##> %s\n", strings[i]); - free(strings); - } -#endif -} - -IMPLEMENT_LHASH_DOALL_ARG_CONST(MEM, MEM_LEAK); - -int CRYPTO_mem_leaks_cb(int (*cb) (const char *str, size_t len, void *u), - void *u) -{ - MEM_LEAK ml; - - /* Ensure all resources are released */ - OPENSSL_cleanup(); - - if (!RUN_ONCE(&memdbg_init, do_memdbg_init)) - return -1; - - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - - ml.print_cb = cb; - ml.print_cb_arg = u; - ml.bytes = 0; - ml.chunks = 0; - if (mh != NULL) - lh_MEM_doall_MEM_LEAK(mh, print_leak, &ml); - - if (ml.chunks != 0) { - char buf[256]; - - BIO_snprintf(buf, sizeof(buf), "%ld bytes leaked in %d chunks\n", - ml.bytes, ml.chunks); - cb(buf, strlen(buf), u); - } else { - /* - * Make sure that, if we found no leaks, memory-leak debugging itself - * does not introduce memory leaks (which might irritate external - * debugging tools). (When someone enables leak checking, but does not - * call this function, we declare it to be their fault.) - */ - int old_mh_mode; - - CRYPTO_THREAD_write_lock(memdbg_lock); - - /* - * avoid deadlock when lh_free() uses CRYPTO_mem_debug_free(), which uses - * mem_check_on - */ - old_mh_mode = mh_mode; - mh_mode = CRYPTO_MEM_CHECK_OFF; - - lh_MEM_free(mh); - mh = NULL; - - mh_mode = old_mh_mode; - CRYPTO_THREAD_unlock(memdbg_lock); - } - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF); - - /* Clean up locks etc */ - CRYPTO_THREAD_cleanup_local(&appinfokey); - CRYPTO_THREAD_lock_free(memdbg_lock); - CRYPTO_THREAD_lock_free(long_memdbg_lock); - memdbg_lock = NULL; - long_memdbg_lock = NULL; - - return ml.chunks == 0 ? 1 : 0; -} - -static int print_bio(const char *str, size_t len, void *b) -{ - return BIO_write((BIO *)b, str, len); -} - -int CRYPTO_mem_leaks(BIO *b) -{ - /* - * OPENSSL_cleanup() will free the ex_data locks so we can't have any - * ex_data hanging around - */ - bio_free_ex_data(b); - - return CRYPTO_mem_leaks_cb(print_bio, b); -} - -# ifndef OPENSSL_NO_STDIO -int CRYPTO_mem_leaks_fp(FILE *fp) -{ - BIO *b; - int ret; - - /* - * Need to turn off memory checking when allocated BIOs ... especially as - * we're creating them at a time when we're trying to check we've not - * left anything un-free()'d!! - */ - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - b = BIO_new(BIO_s_file()); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - if (b == NULL) - return -1; - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = CRYPTO_mem_leaks_cb(print_bio, b); - BIO_free(b); - return ret; -} -# endif - -#endif diff --git a/crypto/openssl/crypto/mem_sec.c b/crypto/openssl/crypto/mem_sec.c index 222c786cbaef..6ba75486a897 100644 --- a/crypto/openssl/crypto/mem_sec.c +++ b/crypto/openssl/crypto/mem_sec.c @@ -1,8 +1,8 @@ /* - * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2004-2014, Akamai Technologies. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,27 +20,48 @@ #include -/* e_os.h defines OPENSSL_SECURE_MEMORY if secure memory can be implemented */ -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY +# if defined(_WIN32) +# include +# if defined(WINAPI_FAMILY_PARTITION) +# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) +/* + * While VirtualLock is available under the app partition (e.g. UWP), + * the headers do not define the API. Define it ourselves instead. + */ +WINBASEAPI +BOOL +WINAPI +VirtualLock( + _In_ LPVOID lpAddress, + _In_ SIZE_T dwSize + ); +# endif +# endif +# endif # include # include -# include +# if defined(OPENSSL_SYS_UNIX) +# include +# endif # include -# include +# if defined(OPENSSL_SYS_UNIX) +# include +# if defined(__FreeBSD__) +# define MADV_DONTDUMP MADV_NOCORE +# endif +# if !defined(MAP_CONCEAL) +# define MAP_CONCEAL 0 +# endif +# endif # if defined(OPENSSL_SYS_LINUX) # include # if defined(SYS_mlock2) # include # include # endif +# include # endif -# if defined(__FreeBSD__) -# define MADV_DONTDUMP MADV_NOCORE -# endif -# if !defined(MAP_CONCEAL) -# define MAP_CONCEAL 0 -# endif -# include # include # include #endif @@ -53,7 +74,7 @@ # define MAP_ANON MAP_ANONYMOUS #endif -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY static size_t secure_mem_used; static int secure_mem_initialized; @@ -63,7 +84,7 @@ static CRYPTO_RWLOCK *sec_malloc_lock = NULL; /* * These are the functions that must be implemented by a secure heap (sh). */ -static int sh_init(size_t size, int minsize); +static int sh_init(size_t size, size_t minsize); static void *sh_malloc(size_t size); static void sh_free(void *ptr); static void sh_done(void); @@ -71,9 +92,9 @@ static size_t sh_actual_size(char *ptr); static int sh_allocated(const char *ptr); #endif -int CRYPTO_secure_malloc_init(size_t size, int minsize) +int CRYPTO_secure_malloc_init(size_t size, size_t minsize) { -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY int ret = 0; if (!secure_mem_initialized) { @@ -91,12 +112,12 @@ int CRYPTO_secure_malloc_init(size_t size, int minsize) return ret; #else return 0; -#endif /* OPENSSL_SECURE_MEMORY */ +#endif /* OPENSSL_NO_SECURE_MEMORY */ } int CRYPTO_secure_malloc_done(void) { -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY if (secure_mem_used == 0) { sh_done(); secure_mem_initialized = 0; @@ -104,29 +125,30 @@ int CRYPTO_secure_malloc_done(void) sec_malloc_lock = NULL; return 1; } -#endif /* OPENSSL_SECURE_MEMORY */ +#endif /* OPENSSL_NO_SECURE_MEMORY */ return 0; } int CRYPTO_secure_malloc_initialized(void) { -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY return secure_mem_initialized; #else return 0; -#endif /* OPENSSL_SECURE_MEMORY */ +#endif /* OPENSSL_NO_SECURE_MEMORY */ } void *CRYPTO_secure_malloc(size_t num, const char *file, int line) { -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY void *ret; size_t actual_size; if (!secure_mem_initialized) { return CRYPTO_malloc(num, file, line); } - CRYPTO_THREAD_write_lock(sec_malloc_lock); + if (!CRYPTO_THREAD_write_lock(sec_malloc_lock)) + return NULL; ret = sh_malloc(num); actual_size = ret ? sh_actual_size(ret) : 0; secure_mem_used += actual_size; @@ -134,12 +156,12 @@ void *CRYPTO_secure_malloc(size_t num, const char *file, int line) return ret; #else return CRYPTO_malloc(num, file, line); -#endif /* OPENSSL_SECURE_MEMORY */ +#endif /* OPENSSL_NO_SECURE_MEMORY */ } void *CRYPTO_secure_zalloc(size_t num, const char *file, int line) { -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY if (secure_mem_initialized) /* CRYPTO_secure_malloc() zeroes allocations when it is implemented */ return CRYPTO_secure_malloc(num, file, line); @@ -149,7 +171,7 @@ void *CRYPTO_secure_zalloc(size_t num, const char *file, int line) void CRYPTO_secure_free(void *ptr, const char *file, int line) { -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY size_t actual_size; if (ptr == NULL) @@ -158,7 +180,8 @@ void CRYPTO_secure_free(void *ptr, const char *file, int line) CRYPTO_free(ptr, file, line); return; } - CRYPTO_THREAD_write_lock(sec_malloc_lock); + if (!CRYPTO_THREAD_write_lock(sec_malloc_lock)) + return; actual_size = sh_actual_size(ptr); CLEAR(ptr, actual_size); secure_mem_used -= actual_size; @@ -166,13 +189,13 @@ void CRYPTO_secure_free(void *ptr, const char *file, int line) CRYPTO_THREAD_unlock(sec_malloc_lock); #else CRYPTO_free(ptr, file, line); -#endif /* OPENSSL_SECURE_MEMORY */ +#endif /* OPENSSL_NO_SECURE_MEMORY */ } void CRYPTO_secure_clear_free(void *ptr, size_t num, const char *file, int line) { -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY size_t actual_size; if (ptr == NULL) @@ -182,7 +205,8 @@ void CRYPTO_secure_clear_free(void *ptr, size_t num, CRYPTO_free(ptr, file, line); return; } - CRYPTO_THREAD_write_lock(sec_malloc_lock); + if (!CRYPTO_THREAD_write_lock(sec_malloc_lock)) + return; actual_size = sh_actual_size(ptr); CLEAR(ptr, actual_size); secure_mem_used -= actual_size; @@ -193,40 +217,41 @@ void CRYPTO_secure_clear_free(void *ptr, size_t num, return; OPENSSL_cleanse(ptr, num); CRYPTO_free(ptr, file, line); -#endif /* OPENSSL_SECURE_MEMORY */ +#endif /* OPENSSL_NO_SECURE_MEMORY */ } int CRYPTO_secure_allocated(const void *ptr) { -#ifdef OPENSSL_SECURE_MEMORY - int ret; - +#ifndef OPENSSL_NO_SECURE_MEMORY if (!secure_mem_initialized) return 0; - CRYPTO_THREAD_write_lock(sec_malloc_lock); - ret = sh_allocated(ptr); - CRYPTO_THREAD_unlock(sec_malloc_lock); - return ret; + /* + * Only read accesses to the arena take place in sh_allocated() and this + * is only changed by the sh_init() and sh_done() calls which are not + * locked. Hence, it is safe to make this check without a lock too. + */ + return sh_allocated(ptr); #else return 0; -#endif /* OPENSSL_SECURE_MEMORY */ +#endif /* OPENSSL_NO_SECURE_MEMORY */ } size_t CRYPTO_secure_used(void) { -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY return secure_mem_used; #else return 0; -#endif /* OPENSSL_SECURE_MEMORY */ +#endif /* OPENSSL_NO_SECURE_MEMORY */ } size_t CRYPTO_secure_actual_size(void *ptr) { -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY size_t actual_size; - CRYPTO_THREAD_write_lock(sec_malloc_lock); + if (!CRYPTO_THREAD_write_lock(sec_malloc_lock)) + return 0; actual_size = sh_actual_size(ptr); CRYPTO_THREAD_unlock(sec_malloc_lock); return actual_size; @@ -234,14 +259,11 @@ size_t CRYPTO_secure_actual_size(void *ptr) return 0; #endif } -/* END OF PAGE ... - - ... START OF PAGE */ /* * SECURE HEAP IMPLEMENTATION */ -#ifdef OPENSSL_SECURE_MEMORY +#ifndef OPENSSL_NO_SECURE_MEMORY /* @@ -379,27 +401,46 @@ static void sh_remove_from_list(char *ptr) } -static int sh_init(size_t size, int minsize) +static int sh_init(size_t size, size_t minsize) { int ret; size_t i; size_t pgsize; size_t aligned; +#if defined(_WIN32) + DWORD flOldProtect; + SYSTEM_INFO systemInfo; +#endif memset(&sh, 0, sizeof(sh)); - /* make sure size and minsize are powers of 2 */ + /* make sure size is a powers of 2 */ OPENSSL_assert(size > 0); OPENSSL_assert((size & (size - 1)) == 0); - OPENSSL_assert(minsize > 0); - OPENSSL_assert((minsize & (minsize - 1)) == 0); - if (size <= 0 || (size & (size - 1)) != 0) - goto err; - if (minsize <= 0 || (minsize & (minsize - 1)) != 0) + if (size == 0 || (size & (size - 1)) != 0) goto err; - while (minsize < (int)sizeof(SH_LIST)) - minsize *= 2; + if (minsize <= sizeof(SH_LIST)) { + OPENSSL_assert(sizeof(SH_LIST) <= 65536); + /* + * Compute the minimum possible allocation size. + * This must be a power of 2 and at least as large as the SH_LIST + * structure. + */ + minsize = sizeof(SH_LIST) - 1; + minsize |= minsize >> 1; + minsize |= minsize >> 2; + if (sizeof(SH_LIST) > 16) + minsize |= minsize >> 4; + if (sizeof(SH_LIST) > 256) + minsize |= minsize >> 8; + minsize++; + } else { + /* make sure minsize is a powers of 2 */ + OPENSSL_assert((minsize & (minsize - 1)) == 0); + if ((minsize & (minsize - 1)) != 0) + goto err; + } sh.arena_size = size; sh.minsize = minsize; @@ -441,16 +482,20 @@ static int sh_init(size_t size, int minsize) else pgsize = (size_t)tmppgsize; } +#elif defined(_WIN32) + GetSystemInfo(&systemInfo); + pgsize = (size_t)systemInfo.dwPageSize; #else pgsize = PAGE_SIZE; #endif sh.map_size = pgsize + sh.arena_size + pgsize; - if (1) { -#ifdef MAP_ANON - sh.map_result = mmap(NULL, sh.map_size, - PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_CONCEAL, -1, 0); - } else { -#endif + +#if !defined(_WIN32) +# ifdef MAP_ANON + sh.map_result = mmap(NULL, sh.map_size, + PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_CONCEAL, -1, 0); +# else + { int fd; sh.map_result = MAP_FAILED; @@ -460,8 +505,16 @@ static int sh_init(size_t size, int minsize) close(fd); } } +# endif if (sh.map_result == MAP_FAILED) goto err; +#else + sh.map_result = VirtualAlloc(NULL, sh.map_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + + if (sh.map_result == NULL) + goto err; +#endif + sh.arena = (char *)(sh.map_result + pgsize); sh_setbit(sh.arena, 0, sh.bittable); sh_add_to_list(&sh.freelist[0], sh.arena); @@ -469,14 +522,24 @@ static int sh_init(size_t size, int minsize) /* Now try to add guard pages and lock into memory. */ ret = 1; +#if !defined(_WIN32) /* Starting guard is already aligned from mmap. */ if (mprotect(sh.map_result, pgsize, PROT_NONE) < 0) ret = 2; +#else + if (VirtualProtect(sh.map_result, pgsize, PAGE_NOACCESS, &flOldProtect) == FALSE) + ret = 2; +#endif /* Ending guard page - need to round up to page boundary */ aligned = (pgsize + sh.arena_size + (pgsize - 1)) & ~(pgsize - 1); +#if !defined(_WIN32) if (mprotect(sh.map_result + aligned, pgsize, PROT_NONE) < 0) ret = 2; +#else + if (VirtualProtect(sh.map_result + aligned, pgsize, PAGE_NOACCESS, &flOldProtect) == FALSE) + ret = 2; +#endif #if defined(OPENSSL_SYS_LINUX) && defined(MLOCK_ONFAULT) && defined(SYS_mlock2) if (syscall(SYS_mlock2, sh.arena, sh.arena_size, MLOCK_ONFAULT) < 0) { @@ -487,6 +550,9 @@ static int sh_init(size_t size, int minsize) ret = 2; } } +#elif defined(_WIN32) + if (VirtualLock(sh.arena, sh.arena_size) == FALSE) + ret = 2; #else if (mlock(sh.arena, sh.arena_size) < 0) ret = 2; @@ -508,8 +574,13 @@ static void sh_done(void) OPENSSL_free(sh.freelist); OPENSSL_free(sh.bittable); OPENSSL_free(sh.bitmalloc); +#if !defined(_WIN32) if (sh.map_result != MAP_FAILED && sh.map_size) munmap(sh.map_result, sh.map_size); +#else + if (sh.map_result != NULL && sh.map_size) + VirtualFree(sh.map_result, 0, MEM_RELEASE); +#endif memset(&sh, 0, sizeof(sh)); } @@ -649,4 +720,4 @@ static size_t sh_actual_size(char *ptr) OPENSSL_assert(sh_testbit(ptr, list, sh.bittable)); return sh.arena_size / (ONE << list); } -#endif /* OPENSSL_SECURE_MEMORY */ +#endif /* OPENSSL_NO_SECURE_MEMORY */ diff --git a/crypto/openssl/crypto/mips_arch.h b/crypto/openssl/crypto/mips_arch.h index 4ae1a1a9339e..12a27615f14f 100644 --- a/crypto/openssl/crypto/mips_arch.h +++ b/crypto/openssl/crypto/mips_arch.h @@ -1,7 +1,7 @@ /* - * Copyright 2011-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/modes/aes-gcm-armv8_64.S b/crypto/openssl/crypto/modes/aes-gcm-armv8_64.S new file mode 100644 index 000000000000..3caabfa59358 --- /dev/null +++ b/crypto/openssl/crypto/modes/aes-gcm-armv8_64.S @@ -0,0 +1,6017 @@ +#include "arm_arch.h" + +#if __ARM_MAX_ARCH__>=8 +.arch armv8-a+crypto +.text +.globl aes_gcm_enc_128_kernel +.type aes_gcm_enc_128_kernel,%function +.align 4 +aes_gcm_enc_128_kernel: + cbz x1, .L128_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 + ldp x13, x14, [x8, #160] //load rk10 + + ld1 {v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + lsr x5, x1, #3 //byte_len + mov x15, x5 + + ldr q27, [x8, #144] //load rk9 + add x4, x0, x1, lsr #3 //end_input_ptr + sub x5, x5, #1 //byte_len - 1 + + lsr x12, x11, #32 + ldr q15, [x3, #112] //load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + + fmov d1, x10 //CTR block 1 + rev w12, w12 //rev_ctr32 + + add w12, w12, #1 //increment rev_ctr32 + orr w11, w11, w11 + ldr q18, [x8, #0] //load rk0 + + rev w9, w12 //CTR block 1 + add w12, w12, #1 //CTR block 1 + fmov d3, x10 //CTR block 3 + + orr x9, x11, x9, lsl #32 //CTR block 1 + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + + fmov d2, x10 //CTR block 2 + orr x9, x11, x9, lsl #32 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + orr x9, x11, x9, lsl #32 //CTR block 3 + ldr q19, [x8, #16] //load rk1 + + add w12, w12, #1 //CTR block 3 + fmov v3.d[1], x9 //CTR block 3 + + ldr q14, [x3, #80] //load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ldr q20, [x8, #32] //load rk2 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ldr q12, [x3, #32] //load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + ldr q26, [x8, #128] //load rk8 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + ldr q21, [x8, #48] //load rk3 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + ldr q24, [x8, #96] //load rk6 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + ldr q25, [x8, #112] //load rk7 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + ldr q23, [x8, #80] //load rk5 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + ldr q13, [x3, #64] //load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + eor v17.16b, v17.16b, v9.16b //h4k | h3k + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + ldr q22, [x8, #64] //load rk4 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + add x5, x5, x0 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + cmp x0, x5 //check if we have <= 4 blocks + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + + aese v2.16b, v27.16b //AES block 2 - round 9 + + aese v0.16b, v27.16b //AES block 0 - round 9 + + eor v16.16b, v16.16b, v8.16b //h2k | h1k + + aese v1.16b, v27.16b //AES block 1 - round 9 + + aese v3.16b, v27.16b //AES block 3 - round 9 + b.ge .L128_enc_tail //handle tail + + ldp x6, x7, [x0, #0] //AES block 0 - load plaintext + + ldp x21, x22, [x0, #32] //AES block 2 - load plaintext + + ldp x19, x20, [x0, #16] //AES block 1 - load plaintext + + ldp x23, x24, [x0, #48] //AES block 3 - load plaintext + + eor x6, x6, x13 //AES block 0 - round 10 low + eor x7, x7, x14 //AES block 0 - round 10 high + + eor x21, x21, x13 //AES block 2 - round 10 low + fmov d4, x6 //AES block 0 - mov low + + eor x19, x19, x13 //AES block 1 - round 10 low + eor x22, x22, x14 //AES block 2 - round 10 high + fmov v4.d[1], x7 //AES block 0 - mov high + + fmov d5, x19 //AES block 1 - mov low + eor x20, x20, x14 //AES block 1 - round 10 high + + eor x23, x23, x13 //AES block 3 - round 10 low + fmov v5.d[1], x20 //AES block 1 - mov high + + fmov d6, x21 //AES block 2 - mov low + eor x24, x24, x14 //AES block 3 - round 10 high + rev w9, w12 //CTR block 4 + + fmov v6.d[1], x22 //AES block 2 - mov high + orr x9, x11, x9, lsl #32 //CTR block 4 + + eor v4.16b, v4.16b, v0.16b //AES block 0 - result + fmov d0, x10 //CTR block 4 + add w12, w12, #1 //CTR block 4 + + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + + eor v5.16b, v5.16b, v1.16b //AES block 1 - result + fmov d1, x10 //CTR block 5 + orr x9, x11, x9, lsl #32 //CTR block 5 + + add w12, w12, #1 //CTR block 5 + add x0, x0, #64 //AES input_ptr update + fmov v1.d[1], x9 //CTR block 5 + + fmov d7, x23 //AES block 3 - mov low + rev w9, w12 //CTR block 6 + st1 { v4.16b}, [x2], #16 //AES block 0 - store result + + fmov v7.d[1], x24 //AES block 3 - mov high + orr x9, x11, x9, lsl #32 //CTR block 6 + + add w12, w12, #1 //CTR block 6 + eor v6.16b, v6.16b, v2.16b //AES block 2 - result + st1 { v5.16b}, [x2], #16 //AES block 1 - store result + + fmov d2, x10 //CTR block 6 + cmp x0, x5 //check if we have <= 8 blocks + + fmov v2.d[1], x9 //CTR block 6 + rev w9, w12 //CTR block 7 + st1 { v6.16b}, [x2], #16 //AES block 2 - store result + + orr x9, x11, x9, lsl #32 //CTR block 7 + + eor v7.16b, v7.16b, v3.16b //AES block 3 - result + st1 { v7.16b}, [x2], #16 //AES block 3 - store result + b.ge .L128_enc_prepretail //do prepretail + +.L128_enc_main_loop: //main loop start + ldp x23, x24, [x0, #48] //AES block 4k+3 - load plaintext + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + fmov d3, x10 //CTR block 4k+3 + + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + add w12, w12, #1 //CTR block 4k+3 + fmov v3.d[1], x9 //CTR block 4k+3 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + mov d30, v5.d[1] //GHASH block 4k+1 - mid + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + eor v4.16b, v4.16b, v11.16b //PRE 1 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor x24, x24, x14 //AES block 4k+3 - round 10 high + + pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + ldp x6, x7, [x0, #0] //AES block 4k+4 - load plaintext + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + rev w9, w12 //CTR block 4k+8 + + eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid + mov d8, v4.d[1] //GHASH block 4k - mid + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + add w12, w12, #1 //CTR block 4k+8 + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high + + pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid + + pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + eor x7, x7, x14 //AES block 4k+4 - round 10 high + + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + eor x6, x6, x13 //AES block 4k+4 - round 10 low + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + + pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + movi v8.8b, #0xc2 + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + shl d8, d8, #56 //mod_constant + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + ldp x19, x20, [x0, #16] //AES block 4k+5 - load plaintext + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + ldp x21, x22, [x0, #32] //AES block 4k+6 - load plaintext + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + eor x19, x19, x13 //AES block 4k+5 - round 10 low + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + eor x23, x23, x13 //AES block 4k+3 - round 10 low + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + fmov d4, x6 //AES block 4k+4 - mov low + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + fmov v4.d[1], x7 //AES block 4k+4 - mov high + + add x0, x0, #64 //AES input_ptr update + fmov d7, x23 //AES block 4k+3 - mov low + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + fmov d5, x19 //AES block 4k+5 - mov low + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + eor x20, x20, x14 //AES block 4k+5 - round 10 high + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + fmov v5.d[1], x20 //AES block 4k+5 - mov high + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + fmov v7.d[1], x24 //AES block 4k+3 - mov high + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + cmp x0, x5 //.LOOP CONTROL + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + aese v0.16b, v27.16b //AES block 4k+4 - round 9 + eor x21, x21, x13 //AES block 4k+6 - round 10 low + eor x22, x22, x14 //AES block 4k+6 - round 10 high + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + fmov d6, x21 //AES block 4k+6 - mov low + + aese v1.16b, v27.16b //AES block 4k+5 - round 9 + fmov v6.d[1], x22 //AES block 4k+6 - mov high + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + eor v4.16b, v4.16b, v0.16b //AES block 4k+4 - result + + fmov d0, x10 //CTR block 4k+8 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + fmov v0.d[1], x9 //CTR block 4k+8 + rev w9, w12 //CTR block 4k+9 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + eor v5.16b, v5.16b, v1.16b //AES block 4k+5 - result + + add w12, w12, #1 //CTR block 4k+9 + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + fmov d1, x10 //CTR block 4k+9 + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + fmov v1.d[1], x9 //CTR block 4k+9 + rev w9, w12 //CTR block 4k+10 + + aese v2.16b, v27.16b //AES block 4k+6 - round 9 + st1 { v4.16b}, [x2], #16 //AES block 4k+4 - store result + eor v6.16b, v6.16b, v2.16b //AES block 4k+6 - result + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + + aese v3.16b, v27.16b //AES block 4k+7 - round 9 + add w12, w12, #1 //CTR block 4k+10 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + fmov d2, x10 //CTR block 4k+10 + + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + st1 { v5.16b}, [x2], #16 //AES block 4k+5 - store result + + fmov v2.d[1], x9 //CTR block 4k+10 + st1 { v6.16b}, [x2], #16 //AES block 4k+6 - store result + rev w9, w12 //CTR block 4k+11 + + orr x9, x11, x9, lsl #32 //CTR block 4k+11 + eor v7.16b, v7.16b, v3.16b //AES block 4k+3 - result + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + st1 { v7.16b}, [x2], #16 //AES block 4k+3 - store result + b.lt .L128_enc_main_loop + +.L128_enc_prepretail: //PREPRETAIL + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + fmov d3, x10 //CTR block 4k+3 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + add w12, w12, #1 //CTR block 4k+3 + fmov v3.d[1], x9 //CTR block 4k+3 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + eor v4.16b, v4.16b, v11.16b //PRE 1 + + pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + mov d30, v5.d[1] //GHASH block 4k+1 - mid + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + + mov d31, v6.d[1] //GHASH block 4k+2 - mid + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid + + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + + pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + + pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + movi v8.8b, #0xc2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + shl d8, d8, #56 //mod_constant + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + pmull v28.1q, v9.1d, v8.1d + eor v10.16b, v10.16b, v9.16b //karatsuba tidy up + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + ext v9.16b, v9.16b, v9.16b, #8 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v11.16b + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + eor v10.16b, v10.16b, v28.16b + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v9.16b + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + + pmull v28.1q, v10.1d, v8.1d + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + ext v10.16b, v10.16b, v10.16b, #8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v28.16b + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + + aese v3.16b, v27.16b //AES block 4k+7 - round 9 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + + aese v0.16b, v27.16b //AES block 4k+4 - round 9 + + aese v1.16b, v27.16b //AES block 4k+5 - round 9 + eor v11.16b, v11.16b, v10.16b + + aese v2.16b, v27.16b //AES block 4k+6 - round 9 +.L128_enc_tail: //TAIL + + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ldp x6, x7, [x0], #16 //AES block 4k+4 - load plaintext + + cmp x5, #48 + + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + eor x6, x6, x13 //AES block 4k+4 - round 10 low + eor x7, x7, x14 //AES block 4k+4 - round 10 high + + fmov d4, x6 //AES block 4k+4 - mov low + + fmov v4.d[1], x7 //AES block 4k+4 - mov high + + eor v5.16b, v4.16b, v0.16b //AES block 4k+4 - result + + b.gt .L128_enc_blocks_more_than_3 + + sub w12, w12, #1 + movi v11.8b, #0 + mov v3.16b, v2.16b + + cmp x5, #32 + mov v2.16b, v1.16b + movi v9.8b, #0 + + movi v10.8b, #0 + b.gt .L128_enc_blocks_more_than_2 + + mov v3.16b, v1.16b + cmp x5, #16 + + sub w12, w12, #1 + b.gt .L128_enc_blocks_more_than_1 + + sub w12, w12, #1 + b .L128_enc_blocks_less_than_1 +.L128_enc_blocks_more_than_3: //blocks left > 3 + st1 { v5.16b}, [x2], #16 //AES final-3 block - store result + + ldp x6, x7, [x0], #16 //AES final-2 block - load input low & high + + rev64 v4.16b, v5.16b //GHASH final-3 block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + eor x7, x7, x14 //AES final-2 block - round 10 high + eor x6, x6, x13 //AES final-2 block - round 10 low + + fmov d5, x6 //AES final-2 block - mov low + + movi v8.8b, #0 //suppress further partial tag feed in + fmov v5.d[1], x7 //AES final-2 block - mov high + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + mov d22, v4.d[1] //GHASH final-3 block - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + mov d10, v17.d[1] //GHASH final-3 block - mid + + eor v5.16b, v5.16b, v1.16b //AES final-2 block - result + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid +.L128_enc_blocks_more_than_2: //blocks left > 2 + + st1 { v5.16b}, [x2], #16 //AES final-2 block - store result + + rev64 v4.16b, v5.16b //GHASH final-2 block + ldp x6, x7, [x0], #16 //AES final-1 block - load input low & high + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor x6, x6, x13 //AES final-1 block - round 10 low + + fmov d5, x6 //AES final-1 block - mov low + eor x7, x7, x14 //AES final-1 block - round 10 high + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + fmov v5.d[1], x7 //AES final-1 block - mov high + + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + + eor v5.16b, v5.16b, v2.16b //AES final-1 block - result + + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid +.L128_enc_blocks_more_than_1: //blocks left > 1 + + st1 { v5.16b}, [x2], #16 //AES final-1 block - store result + + rev64 v4.16b, v5.16b //GHASH final-1 block + ldp x6, x7, [x0], #16 //AES final block - load input low & high + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor x7, x7, x14 //AES final block - round 10 high + eor x6, x6, x13 //AES final block - round 10 low + + fmov d5, x6 //AES final block - mov low + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + fmov v5.d[1], x7 //AES final block - mov high + + mov d22, v4.d[1] //GHASH final-1 block - mid + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + + eor v5.16b, v5.16b, v3.16b //AES final block - result + + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid + movi v8.8b, #0 //suppress further partial tag feed in +.L128_enc_blocks_less_than_1: //blocks left <= 1 + + and x1, x1, #127 //bit_length %= 128 + mvn x13, xzr //rk10_l = 0xffffffffffffffff + + mvn x14, xzr //rk10_h = 0xffffffffffffffff + sub x1, x1, #128 //bit_length -= 128 + + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + + and x1, x1, #127 //bit_length %= 128 + + lsr x14, x14, x1 //rk10_h is mask for top 64b of last block + cmp x1, #64 + + csel x6, x13, x14, lt + csel x7, x14, xzr, lt + + fmov d0, x6 //ctr0b is mask for last block + + fmov v0.d[1], x7 + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + mov d8, v4.d[1] //GHASH final block - mid + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + ld1 { v18.16b}, [x2] //load existing bytes where the possibly partial last block is to be stored + + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid + + rev w9, w12 + + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + shl d8, d8, #56 //mod_constant + + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + bif v5.16b, v18.16b, v0.16b //insert existing bytes in top end of result before storing + + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + st1 { v5.16b}, [x2] //store all 16B + + str w9, [x16, #12] //store the updated counter + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L128_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_128_kernel,.-aes_gcm_enc_128_kernel +.globl aes_gcm_dec_128_kernel +.type aes_gcm_dec_128_kernel,%function +.align 4 +aes_gcm_dec_128_kernel: + cbz x1, .L128_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + lsr x5, x1, #3 //byte_len + mov x15, x5 + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 + + sub x5, x5, #1 //byte_len - 1 + ldr q18, [x8, #0] //load rk0 + + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + + ldr q13, [x3, #64] //load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + + lsr x12, x11, #32 + fmov d2, x10 //CTR block 2 + + ldr q19, [x8, #16] //load rk1 + orr w11, w11, w11 + rev w12, w12 //rev_ctr32 + + fmov d1, x10 //CTR block 1 + add w12, w12, #1 //increment rev_ctr32 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + rev w9, w12 //CTR block 1 + + orr x9, x11, x9, lsl #32 //CTR block 1 + ldr q20, [x8, #32] //load rk2 + add w12, w12, #1 //CTR block 1 + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + orr x9, x11, x9, lsl #32 //CTR block 2 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + fmov d3, x10 //CTR block 3 + orr x9, x11, x9, lsl #32 //CTR block 3 + add w12, w12, #1 //CTR block 3 + + fmov v3.d[1], x9 //CTR block 3 + add x4, x0, x1, lsr #3 //end_input_ptr + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ldr q21, [x8, #48] //load rk3 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + ldr q24, [x8, #96] //load rk6 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ldr q25, [x8, #112] //load rk7 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + ldr q22, [x8, #64] //load rk4 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + ldp x13, x14, [x8, #160] //load rk10 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + ldr q23, [x8, #80] //load rk5 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + ldr q27, [x8, #144] //load rk9 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + ldr q14, [x3, #80] //load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + ldr q26, [x8, #128] //load rk8 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + ldr q12, [x3, #32] //load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + + ldr q15, [x3, #112] //load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + add x5, x5, x0 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + eor v16.16b, v16.16b, v8.16b //h2k | h1k + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + aese v2.16b, v27.16b //AES block 2 - round 9 + + aese v3.16b, v27.16b //AES block 3 - round 9 + + aese v0.16b, v27.16b //AES block 0 - round 9 + cmp x0, x5 //check if we have <= 4 blocks + + aese v1.16b, v27.16b //AES block 1 - round 9 + eor v17.16b, v17.16b, v9.16b //h4k | h3k + b.ge .L128_dec_tail //handle tail + + ldr q5, [x0, #16] //AES block 1 - load ciphertext + + ldr q4, [x0, #0] //AES block 0 - load ciphertext + + eor v1.16b, v5.16b, v1.16b //AES block 1 - result + ldr q6, [x0, #32] //AES block 2 - load ciphertext + + eor v0.16b, v4.16b, v0.16b //AES block 0 - result + rev64 v4.16b, v4.16b //GHASH block 0 + rev w9, w12 //CTR block 4 + + orr x9, x11, x9, lsl #32 //CTR block 4 + add w12, w12, #1 //CTR block 4 + ldr q7, [x0, #48] //AES block 3 - load ciphertext + + rev64 v5.16b, v5.16b //GHASH block 1 + add x0, x0, #64 //AES input_ptr update + mov x19, v1.d[0] //AES block 1 - mov low + + mov x20, v1.d[1] //AES block 1 - mov high + + mov x6, v0.d[0] //AES block 0 - mov low + cmp x0, x5 //check if we have <= 8 blocks + + mov x7, v0.d[1] //AES block 0 - mov high + + fmov d0, x10 //CTR block 4 + + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + eor x19, x19, x13 //AES block 1 - round 10 low + + fmov d1, x10 //CTR block 5 + add w12, w12, #1 //CTR block 5 + orr x9, x11, x9, lsl #32 //CTR block 5 + + fmov v1.d[1], x9 //CTR block 5 + rev w9, w12 //CTR block 6 + add w12, w12, #1 //CTR block 6 + + orr x9, x11, x9, lsl #32 //CTR block 6 + + eor x20, x20, x14 //AES block 1 - round 10 high + eor x6, x6, x13 //AES block 0 - round 10 low + eor v2.16b, v6.16b, v2.16b //AES block 2 - result + + eor x7, x7, x14 //AES block 0 - round 10 high + stp x6, x7, [x2], #16 //AES block 0 - store result + + stp x19, x20, [x2], #16 //AES block 1 - store result + b.ge .L128_dec_prepretail //do prepretail + +.L128_dec_main_loop: //main loop start + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + mov x21, v2.d[0] //AES block 4k+2 - mov low + + pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + mov x22, v2.d[1] //AES block 4k+2 - mov high + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + fmov d2, x10 //CTR block 4k+6 + + rev64 v6.16b, v6.16b //GHASH block 4k+2 + fmov v2.d[1], x9 //CTR block 4k+6 + rev w9, w12 //CTR block 4k+7 + + mov x23, v3.d[0] //AES block 4k+3 - mov low + eor v4.16b, v4.16b, v11.16b //PRE 1 + mov d30, v5.d[1] //GHASH block 4k+1 - mid + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + rev64 v7.16b, v7.16b //GHASH block 4k+3 + + pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + mov x24, v3.d[1] //AES block 4k+3 - mov high + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + fmov d3, x10 //CTR block 4k+7 + eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + fmov v3.d[1], x9 //CTR block 4k+7 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + mov d10, v17.d[1] //GHASH block 4k - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low + + pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + mov d8, v4.d[1] //GHASH block 4k - mid + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + + pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + eor x23, x23, x13 //AES block 4k+3 - round 10 low + + pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid + eor x22, x22, x14 //AES block 4k+2 - round 10 high + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid + + pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + eor x24, x24, x14 //AES block 4k+3 - round 10 high + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + eor x21, x21, x13 //AES block 4k+2 - round 10 low + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + movi v8.8b, #0xc2 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high + ldr q4, [x0, #0] //AES block 4k+4 - load ciphertext + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + add w12, w12, #1 //CTR block 4k+7 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + shl d8, d8, #56 //mod_constant + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + rev w9, w12 //CTR block 4k+8 + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + ldr q5, [x0, #16] //AES block 4k+5 - load ciphertext + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v0.16b, v27.16b //AES block 4k+4 - round 9 + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + aese v1.16b, v27.16b //AES block 4k+5 - round 9 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + eor v0.16b, v4.16b, v0.16b //AES block 4k+4 - result + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + ldr q6, [x0, #32] //AES block 4k+6 - load ciphertext + + add w12, w12, #1 //CTR block 4k+8 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + eor v1.16b, v5.16b, v1.16b //AES block 4k+5 - result + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + ldr q7, [x0, #48] //AES block 4k+3 - load ciphertext + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + add x0, x0, #64 //AES input_ptr update + + rev64 v5.16b, v5.16b //GHASH block 4k+5 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + mov x7, v0.d[1] //AES block 4k+4 - mov high + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + mov x6, v0.d[0] //AES block 4k+4 - mov low + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + fmov d0, x10 //CTR block 4k+8 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + fmov v0.d[1], x9 //CTR block 4k+8 + rev w9, w12 //CTR block 4k+9 + + aese v2.16b, v27.16b //AES block 4k+6 - round 9 + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + eor x7, x7, x14 //AES block 4k+4 - round 10 high + + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + mov x20, v1.d[1] //AES block 4k+5 - mov high + eor x6, x6, x13 //AES block 4k+4 - round 10 low + + eor v2.16b, v6.16b, v2.16b //AES block 4k+6 - result + mov x19, v1.d[0] //AES block 4k+5 - mov low + add w12, w12, #1 //CTR block 4k+9 + + aese v3.16b, v27.16b //AES block 4k+7 - round 9 + fmov d1, x10 //CTR block 4k+9 + cmp x0, x5 //.LOOP CONTROL + + rev64 v4.16b, v4.16b //GHASH block 4k+4 + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + fmov v1.d[1], x9 //CTR block 4k+9 + + rev w9, w12 //CTR block 4k+10 + add w12, w12, #1 //CTR block 4k+10 + + eor x20, x20, x14 //AES block 4k+5 - round 10 high + stp x6, x7, [x2], #16 //AES block 4k+4 - store result + + eor x19, x19, x13 //AES block 4k+5 - round 10 low + stp x19, x20, [x2], #16 //AES block 4k+5 - store result + + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + b.lt .L128_dec_main_loop + +.L128_dec_prepretail: //PREPRETAIL + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + mov x21, v2.d[0] //AES block 4k+2 - mov low + mov d30, v5.d[1] //GHASH block 4k+1 - mid + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + mov x22, v2.d[1] //AES block 4k+2 - mov high + + eor v4.16b, v4.16b, v11.16b //PRE 1 + fmov d2, x10 //CTR block 4k+6 + rev64 v6.16b, v6.16b //GHASH block 4k+2 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + fmov v2.d[1], x9 //CTR block 4k+6 + + rev w9, w12 //CTR block 4k+7 + mov x23, v3.d[0] //AES block 4k+3 - mov low + eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d10, v17.d[1] //GHASH block 4k - mid + mov x24, v3.d[1] //AES block 4k+3 - mov high + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + + pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + mov d8, v4.d[1] //GHASH block 4k - mid + fmov d3, x10 //CTR block 4k+7 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + fmov v3.d[1], x9 //CTR block 4k+7 + + pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + rev64 v7.16b, v7.16b //GHASH block 4k+3 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low + + pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high + + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid + + pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high + movi v8.8b, #0xc2 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor x23, x23, x13 //AES block 4k+3 - round 10 low + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor x21, x21, x13 //AES block 4k+2 - round 10 low + eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + shl d8, d8, #56 //mod_constant + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + aese v1.16b, v27.16b //AES block 4k+5 - round 9 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + eor x24, x24, x14 //AES block 4k+3 - round 10 high + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + eor x22, x22, x14 //AES block 4k+2 - round 10 high + + aese v0.16b, v27.16b //AES block 4k+4 - round 9 + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + aese v2.16b, v27.16b //AES block 4k+6 - round 9 + add w12, w12, #1 //CTR block 4k+7 + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + + aese v3.16b, v27.16b //AES block 4k+7 - round 9 + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low +.L128_dec_tail: //TAIL + + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ld1 { v5.16b}, [x0], #16 //AES block 4k+4 - load ciphertext + + eor v0.16b, v5.16b, v0.16b //AES block 4k+4 - result + + mov x7, v0.d[1] //AES block 4k+4 - mov high + + mov x6, v0.d[0] //AES block 4k+4 - mov low + + cmp x5, #48 + + eor x7, x7, x14 //AES block 4k+4 - round 10 high + + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + eor x6, x6, x13 //AES block 4k+4 - round 10 low + b.gt .L128_dec_blocks_more_than_3 + + mov v3.16b, v2.16b + sub w12, w12, #1 + movi v11.8b, #0 + + movi v9.8b, #0 + mov v2.16b, v1.16b + + movi v10.8b, #0 + cmp x5, #32 + b.gt .L128_dec_blocks_more_than_2 + + cmp x5, #16 + + mov v3.16b, v1.16b + sub w12, w12, #1 + b.gt .L128_dec_blocks_more_than_1 + + sub w12, w12, #1 + b .L128_dec_blocks_less_than_1 +.L128_dec_blocks_more_than_3: //blocks left > 3 + rev64 v4.16b, v5.16b //GHASH final-3 block + ld1 { v5.16b}, [x0], #16 //AES final-2 block - load ciphertext + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + mov d10, v17.d[1] //GHASH final-3 block - mid + stp x6, x7, [x2], #16 //AES final-3 block - store result + eor v0.16b, v5.16b, v1.16b //AES final-2 block - result + + mov d22, v4.d[1] //GHASH final-3 block - mid + mov x7, v0.d[1] //AES final-2 block - mov high + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + mov x6, v0.d[0] //AES final-2 block - mov low + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + eor x7, x7, x14 //AES final-2 block - round 10 high + + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid + eor x6, x6, x13 //AES final-2 block - round 10 low +.L128_dec_blocks_more_than_2: //blocks left > 2 + + rev64 v4.16b, v5.16b //GHASH final-2 block + ld1 { v5.16b}, [x0], #16 //AES final-1 block - load ciphertext + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor v0.16b, v5.16b, v2.16b //AES final-1 block - result + stp x6, x7, [x2], #16 //AES final-2 block - store result + + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + mov x6, v0.d[0] //AES final-1 block - mov low + + mov x7, v0.d[1] //AES final-1 block - mov high + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + eor x6, x6, x13 //AES final-1 block - round 10 low + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid + eor x7, x7, x14 //AES final-1 block - round 10 high +.L128_dec_blocks_more_than_1: //blocks left > 1 + + rev64 v4.16b, v5.16b //GHASH final-1 block + + ld1 { v5.16b}, [x0], #16 //AES final block - load ciphertext + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + mov d22, v4.d[1] //GHASH final-1 block - mid + + eor v0.16b, v5.16b, v3.16b //AES final block - result + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + + stp x6, x7, [x2], #16 //AES final-1 block - store result + mov x6, v0.d[0] //AES final block - mov low + + mov x7, v0.d[1] //AES final block - mov high + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + movi v8.8b, #0 //suppress further partial tag feed in + + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + eor x7, x7, x14 //AES final block - round 10 high + + eor x6, x6, x13 //AES final block - round 10 low + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid +.L128_dec_blocks_less_than_1: //blocks left <= 1 + + mvn x14, xzr //rk10_h = 0xffffffffffffffff + and x1, x1, #127 //bit_length %= 128 + + mvn x13, xzr //rk10_l = 0xffffffffffffffff + sub x1, x1, #128 //bit_length -= 128 + + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + + and x1, x1, #127 //bit_length %= 128 + + lsr x14, x14, x1 //rk10_h is mask for top 64b of last block + cmp x1, #64 + + csel x10, x14, xzr, lt + csel x9, x13, x14, lt + + fmov d0, x9 //ctr0b is mask for last block + + mov v0.d[1], x10 + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + ldp x4, x5, [x2] //load existing bytes we need to not overwrite + + and x7, x7, x10 + + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + mov d8, v4.d[1] //GHASH final block - mid + + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + bic x4, x4, x9 //mask out low existing bytes + and x6, x6, x9 + + rev w9, w12 + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + bic x5, x5, x10 //mask out high existing bytes + shl d8, d8, #56 //mod_constant + + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + orr x6, x6, x4 + str w9, [x16, #12] //store the updated counter + + orr x7, x7, x5 + stp x6, x7, [x2] + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L128_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_128_kernel,.-aes_gcm_dec_128_kernel +.globl aes_gcm_enc_192_kernel +.type aes_gcm_enc_192_kernel,%function +.align 4 +aes_gcm_enc_192_kernel: + cbz x1, .L192_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 + + ldr q23, [x8, #80] //load rk5 + + ldr q22, [x8, #64] //load rk4 + + ldr q26, [x8, #128] //load rk8 + + lsr x12, x11, #32 + ldr q24, [x8, #96] //load rk6 + orr w11, w11, w11 + + ldr q25, [x8, #112] //load rk7 + rev w12, w12 //rev_ctr32 + + add w12, w12, #1 //increment rev_ctr32 + fmov d3, x10 //CTR block 3 + + rev w9, w12 //CTR block 1 + add w12, w12, #1 //CTR block 1 + fmov d1, x10 //CTR block 1 + + orr x9, x11, x9, lsl #32 //CTR block 1 + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + fmov d2, x10 //CTR block 2 + orr x9, x11, x9, lsl #32 //CTR block 2 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + orr x9, x11, x9, lsl #32 //CTR block 3 + ldr q18, [x8, #0] //load rk0 + + fmov v3.d[1], x9 //CTR block 3 + + ldr q21, [x8, #48] //load rk3 + + ldp x13, x14, [x8, #192] //load rk12 + + ldr q19, [x8, #16] //load rk1 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + ldr q29, [x8, #176] //load rk11 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ldr q15, [x3, #112] //load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ldr q20, [x8, #32] //load rk2 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + ldr q28, [x8, #160] //load rk10 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + ldr q12, [x3, #32] //load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + ldr q27, [x8, #144] //load rk9 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + ldr q14, [x3, #80] //load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + ldr q13, [x3, #64] //load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 0 - round 9 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 3 - round 9 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 2 - round 9 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 1 - round 9 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 0 - round 10 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 2 - round 10 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 1 - round 10 + lsr x5, x1, #3 //byte_len + mov x15, x5 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 3 - round 10 + sub x5, x5, #1 //byte_len - 1 + + eor v16.16b, v16.16b, v8.16b //h2k | h1k + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + eor v17.16b, v17.16b, v9.16b //h4k | h3k + + aese v2.16b, v29.16b //AES block 2 - round 11 + add x4, x0, x1, lsr #3 //end_input_ptr + add x5, x5, x0 + + aese v1.16b, v29.16b //AES block 1 - round 11 + cmp x0, x5 //check if we have <= 4 blocks + + aese v0.16b, v29.16b //AES block 0 - round 11 + add w12, w12, #1 //CTR block 3 + + aese v3.16b, v29.16b //AES block 3 - round 11 + b.ge .L192_enc_tail //handle tail + + rev w9, w12 //CTR block 4 + ldp x6, x7, [x0, #0] //AES block 0 - load plaintext + + orr x9, x11, x9, lsl #32 //CTR block 4 + ldp x21, x22, [x0, #32] //AES block 2 - load plaintext + + ldp x23, x24, [x0, #48] //AES block 3 - load plaintext + + ldp x19, x20, [x0, #16] //AES block 1 - load plaintext + add x0, x0, #64 //AES input_ptr update + cmp x0, x5 //check if we have <= 8 blocks + + eor x6, x6, x13 //AES block 0 - round 12 low + + eor x7, x7, x14 //AES block 0 - round 12 high + eor x22, x22, x14 //AES block 2 - round 12 high + fmov d4, x6 //AES block 0 - mov low + + eor x24, x24, x14 //AES block 3 - round 12 high + fmov v4.d[1], x7 //AES block 0 - mov high + + eor x21, x21, x13 //AES block 2 - round 12 low + eor x19, x19, x13 //AES block 1 - round 12 low + + fmov d5, x19 //AES block 1 - mov low + eor x20, x20, x14 //AES block 1 - round 12 high + + fmov v5.d[1], x20 //AES block 1 - mov high + + eor x23, x23, x13 //AES block 3 - round 12 low + fmov d6, x21 //AES block 2 - mov low + + add w12, w12, #1 //CTR block 4 + eor v4.16b, v4.16b, v0.16b //AES block 0 - result + fmov d0, x10 //CTR block 4 + + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + + orr x9, x11, x9, lsl #32 //CTR block 5 + add w12, w12, #1 //CTR block 5 + + fmov d7, x23 //AES block 3 - mov low + st1 { v4.16b}, [x2], #16 //AES block 0 - store result + + fmov v6.d[1], x22 //AES block 2 - mov high + + eor v5.16b, v5.16b, v1.16b //AES block 1 - result + fmov d1, x10 //CTR block 5 + st1 { v5.16b}, [x2], #16 //AES block 1 - store result + + fmov v7.d[1], x24 //AES block 3 - mov high + + fmov v1.d[1], x9 //CTR block 5 + rev w9, w12 //CTR block 6 + + orr x9, x11, x9, lsl #32 //CTR block 6 + + add w12, w12, #1 //CTR block 6 + eor v6.16b, v6.16b, v2.16b //AES block 2 - result + fmov d2, x10 //CTR block 6 + + fmov v2.d[1], x9 //CTR block 6 + rev w9, w12 //CTR block 7 + + orr x9, x11, x9, lsl #32 //CTR block 7 + st1 { v6.16b}, [x2], #16 //AES block 2 - store result + + eor v7.16b, v7.16b, v3.16b //AES block 3 - result + st1 { v7.16b}, [x2], #16 //AES block 3 - store result + b.ge .L192_enc_prepretail //do prepretail + +.L192_enc_main_loop: //main loop start + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + ldp x19, x20, [x0, #16] //AES block 4k+5 - load plaintext + + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + fmov d3, x10 //CTR block 4k+3 + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + fmov v3.d[1], x9 //CTR block 4k+3 + + pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + ldp x21, x22, [x0, #32] //AES block 4k+6 - load plaintext + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + ldp x23, x24, [x0, #48] //AES block 4k+3 - load plaintext + + pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + eor v4.16b, v4.16b, v11.16b //PRE 1 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor x24, x24, x14 //AES block 4k+3 - round 12 high + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + eor x21, x21, x13 //AES block 4k+6 - round 12 low + + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor x19, x19, x13 //AES block 4k+5 - round 12 low + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + mov d10, v17.d[1] //GHASH block 4k - mid + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + eor x20, x20, x14 //AES block 4k+5 - round 12 high + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + add w12, w12, #1 //CTR block 4k+3 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + eor x22, x22, x14 //AES block 4k+6 - round 12 high + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + eor x23, x23, x13 //AES block 4k+3 - round 12 low + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + rev w9, w12 //CTR block 4k+8 + + pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + ldp x6, x7, [x0, #0] //AES block 4k+4 - load plaintext + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + add x0, x0, #64 //AES input_ptr update + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + movi v8.8b, #0xc2 + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + eor x7, x7, x14 //AES block 4k+4 - round 12 high + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + eor x6, x6, x13 //AES block 4k+4 - round 12 low + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + shl d8, d8, #56 //mod_constant + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + fmov d5, x19 //AES block 4k+5 - mov low + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + fmov v5.d[1], x20 //AES block 4k+5 - mov high + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + cmp x0, x5 //.LOOP CONTROL + fmov d4, x6 //AES block 4k+4 - mov low + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + fmov v4.d[1], x7 //AES block 4k+4 - mov high + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + fmov d7, x23 //AES block 4k+3 - mov low + + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + add w12, w12, #1 //CTR block 4k+8 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + fmov v7.d[1], x24 //AES block 4k+3 - mov high + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + fmov d6, x21 //AES block 4k+6 - mov low + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + + aese v0.16b, v29.16b //AES block 4k+4 - round 11 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + + eor v4.16b, v4.16b, v0.16b //AES block 4k+4 - result + fmov d0, x10 //CTR block 4k+8 + + aese v1.16b, v29.16b //AES block 4k+5 - round 11 + fmov v0.d[1], x9 //CTR block 4k+8 + rev w9, w12 //CTR block 4k+9 + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + fmov v6.d[1], x22 //AES block 4k+6 - mov high + st1 { v4.16b}, [x2], #16 //AES block 4k+4 - store result + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + + eor v5.16b, v5.16b, v1.16b //AES block 4k+5 - result + add w12, w12, #1 //CTR block 4k+9 + fmov d1, x10 //CTR block 4k+9 + + aese v2.16b, v29.16b //AES block 4k+6 - round 11 + fmov v1.d[1], x9 //CTR block 4k+9 + rev w9, w12 //CTR block 4k+10 + + add w12, w12, #1 //CTR block 4k+10 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + + st1 { v5.16b}, [x2], #16 //AES block 4k+5 - store result + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + + aese v3.16b, v29.16b //AES block 4k+7 - round 11 + eor v6.16b, v6.16b, v2.16b //AES block 4k+6 - result + fmov d2, x10 //CTR block 4k+10 + + st1 { v6.16b}, [x2], #16 //AES block 4k+6 - store result + fmov v2.d[1], x9 //CTR block 4k+10 + rev w9, w12 //CTR block 4k+11 + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + orr x9, x11, x9, lsl #32 //CTR block 4k+11 + + eor v7.16b, v7.16b, v3.16b //AES block 4k+3 - result + st1 { v7.16b}, [x2], #16 //AES block 4k+3 - store result + b.lt .L192_enc_main_loop + +.L192_enc_prepretail: //PREPRETAIL + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + + fmov d3, x10 //CTR block 4k+3 + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + add w12, w12, #1 //CTR block 4k+3 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + + fmov v3.d[1], x9 //CTR block 4k+3 + eor v4.16b, v4.16b, v11.16b //PRE 1 + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + + pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high + + pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + movi v8.8b, #0xc2 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v9.16b //karatsuba tidy up + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + shl d8, d8, #56 //mod_constant + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + eor v10.16b, v10.16b, v11.16b + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + pmull v30.1q, v9.1d, v8.1d + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + ext v9.16b, v9.16b, v9.16b, #8 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v30.16b + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v9.16b + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + + pmull v30.1q, v10.1d, v8.1d + + ext v10.16b, v10.16b, v10.16b, #8 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + eor v11.16b, v11.16b, v30.16b + + aese v0.16b, v29.16b //AES block 4k+4 - round 11 + + aese v3.16b, v29.16b //AES block 4k+7 - round 11 + + aese v2.16b, v29.16b //AES block 4k+6 - round 11 + + aese v1.16b, v29.16b //AES block 4k+5 - round 11 + eor v11.16b, v11.16b, v10.16b +.L192_enc_tail: //TAIL + + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ldp x6, x7, [x0], #16 //AES block 4k+4 - load plaintext + + eor x6, x6, x13 //AES block 4k+4 - round 12 low + eor x7, x7, x14 //AES block 4k+4 - round 12 high + + fmov d4, x6 //AES block 4k+4 - mov low + + fmov v4.d[1], x7 //AES block 4k+4 - mov high + cmp x5, #48 + + eor v5.16b, v4.16b, v0.16b //AES block 4k+4 - result + + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + b.gt .L192_enc_blocks_more_than_3 + + sub w12, w12, #1 + movi v10.8b, #0 + + mov v3.16b, v2.16b + movi v9.8b, #0 + cmp x5, #32 + + mov v2.16b, v1.16b + movi v11.8b, #0 + b.gt .L192_enc_blocks_more_than_2 + + sub w12, w12, #1 + + mov v3.16b, v1.16b + cmp x5, #16 + b.gt .L192_enc_blocks_more_than_1 + + sub w12, w12, #1 + b .L192_enc_blocks_less_than_1 +.L192_enc_blocks_more_than_3: //blocks left > 3 + st1 { v5.16b}, [x2], #16 //AES final-3 block - store result + + ldp x6, x7, [x0], #16 //AES final-2 block - load input low & high + + rev64 v4.16b, v5.16b //GHASH final-3 block + + eor x6, x6, x13 //AES final-2 block - round 12 low + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor x7, x7, x14 //AES final-2 block - round 12 high + fmov d5, x6 //AES final-2 block - mov low + + fmov v5.d[1], x7 //AES final-2 block - mov high + + mov d22, v4.d[1] //GHASH final-3 block - mid + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + + mov d10, v17.d[1] //GHASH final-3 block - mid + + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid + eor v5.16b, v5.16b, v1.16b //AES final-2 block - result +.L192_enc_blocks_more_than_2: //blocks left > 2 + + st1 { v5.16b}, [x2], #16 //AES final-2 block - store result + + rev64 v4.16b, v5.16b //GHASH final-2 block + ldp x6, x7, [x0], #16 //AES final-1 block - load input low & high + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor x7, x7, x14 //AES final-1 block - round 12 high + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + eor x6, x6, x13 //AES final-1 block - round 12 low + + fmov d5, x6 //AES final-1 block - mov low + + fmov v5.d[1], x7 //AES final-1 block - mov high + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + + eor v5.16b, v5.16b, v2.16b //AES final-1 block - result + + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid +.L192_enc_blocks_more_than_1: //blocks left > 1 + + st1 { v5.16b}, [x2], #16 //AES final-1 block - store result + + ldp x6, x7, [x0], #16 //AES final block - load input low & high + + rev64 v4.16b, v5.16b //GHASH final-1 block + + eor x6, x6, x13 //AES final block - round 12 low + eor v4.16b, v4.16b, v8.16b //feed in partial tag + movi v8.8b, #0 //suppress further partial tag feed in + + mov d22, v4.d[1] //GHASH final-1 block - mid + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + eor x7, x7, x14 //AES final block - round 12 high + fmov d5, x6 //AES final block - mov low + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + fmov v5.d[1], x7 //AES final block - mov high + + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + + eor v5.16b, v5.16b, v3.16b //AES final block - result + + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low + + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid +.L192_enc_blocks_less_than_1: //blocks left <= 1 + + ld1 { v18.16b}, [x2] //load existing bytes where the possibly partial last block is to be stored + rev w9, w12 + and x1, x1, #127 //bit_length %= 128 + + sub x1, x1, #128 //bit_length -= 128 + mvn x14, xzr //rk12_h = 0xffffffffffffffff + + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + mvn x13, xzr //rk12_l = 0xffffffffffffffff + + and x1, x1, #127 //bit_length %= 128 + + lsr x14, x14, x1 //rk12_h is mask for top 64b of last block + cmp x1, #64 + + csel x6, x13, x14, lt + csel x7, x14, xzr, lt + + fmov d0, x6 //ctr0b is mask for last block + + fmov v0.d[1], x7 + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + mov d8, v4.d[1] //GHASH final block - mid + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + shl d8, d8, #56 //mod_constant + + bif v5.16b, v18.16b, v0.16b //insert existing bytes in top end of result before storing + + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + str w9, [x16, #12] //store the updated counter + + st1 { v5.16b}, [x2] //store all 16B + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L192_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_192_kernel,.-aes_gcm_enc_192_kernel +.globl aes_gcm_dec_192_kernel +.type aes_gcm_dec_192_kernel,%function +.align 4 +aes_gcm_dec_192_kernel: + cbz x1, .L192_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + add x4, x0, x1, lsr #3 //end_input_ptr + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 + + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + + ldr q18, [x8, #0] //load rk0 + + lsr x5, x1, #3 //byte_len + mov x15, x5 + ldr q20, [x8, #32] //load rk2 + + lsr x12, x11, #32 + orr w11, w11, w11 + fmov d3, x10 //CTR block 3 + + rev w12, w12 //rev_ctr32 + fmov d1, x10 //CTR block 1 + + add w12, w12, #1 //increment rev_ctr32 + ldr q19, [x8, #16] //load rk1 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + rev w9, w12 //CTR block 1 + + add w12, w12, #1 //CTR block 1 + orr x9, x11, x9, lsl #32 //CTR block 1 + ldr q21, [x8, #48] //load rk3 + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + fmov d2, x10 //CTR block 2 + orr x9, x11, x9, lsl #32 //CTR block 2 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + orr x9, x11, x9, lsl #32 //CTR block 3 + + fmov v3.d[1], x9 //CTR block 3 + + ldr q26, [x8, #128] //load rk8 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ldr q29, [x8, #176] //load rk11 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ldr q15, [x3, #112] //load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + ldr q13, [x3, #64] //load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + ldr q14, [x3, #80] //load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + ldp x13, x14, [x8, #192] //load rk12 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + ldr q12, [x3, #32] //load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + ldr q28, [x8, #160] //load rk10 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + ldr q27, [x8, #144] //load rk9 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + ldr q25, [x8, #112] //load rk7 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + ldr q22, [x8, #64] //load rk4 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + add w12, w12, #1 //CTR block 3 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + ldr q23, [x8, #80] //load rk5 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + ldr q24, [x8, #96] //load rk6 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 2 - round 9 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 3 - round 9 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + sub x5, x5, #1 //byte_len - 1 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 3 - round 10 + add x5, x5, x0 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 1 - round 9 + cmp x0, x5 //check if we have <= 4 blocks + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 0 - round 9 + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + + aese v3.16b, v29.16b //AES block 3 - round 11 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 2 - round 10 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 1 - round 10 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 0 - round 10 + eor v16.16b, v16.16b, v8.16b //h2k | h1k + + aese v2.16b, v29.16b //AES block 2 - round 11 + + aese v1.16b, v29.16b //AES block 1 - round 11 + eor v17.16b, v17.16b, v9.16b //h4k | h3k + + aese v0.16b, v29.16b //AES block 0 - round 11 + b.ge .L192_dec_tail //handle tail + + ldr q5, [x0, #16] //AES block 1 - load ciphertext + + ldr q4, [x0, #0] //AES block 0 - load ciphertext + + eor v1.16b, v5.16b, v1.16b //AES block 1 - result + + eor v0.16b, v4.16b, v0.16b //AES block 0 - result + rev w9, w12 //CTR block 4 + ldr q7, [x0, #48] //AES block 3 - load ciphertext + + ldr q6, [x0, #32] //AES block 2 - load ciphertext + + mov x19, v1.d[0] //AES block 1 - mov low + + mov x20, v1.d[1] //AES block 1 - mov high + + mov x6, v0.d[0] //AES block 0 - mov low + orr x9, x11, x9, lsl #32 //CTR block 4 + add w12, w12, #1 //CTR block 4 + + mov x7, v0.d[1] //AES block 0 - mov high + rev64 v4.16b, v4.16b //GHASH block 0 + add x0, x0, #64 //AES input_ptr update + + fmov d0, x10 //CTR block 4 + rev64 v5.16b, v5.16b //GHASH block 1 + cmp x0, x5 //check if we have <= 8 blocks + + eor x19, x19, x13 //AES block 1 - round 12 low + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + + orr x9, x11, x9, lsl #32 //CTR block 5 + fmov d1, x10 //CTR block 5 + eor x20, x20, x14 //AES block 1 - round 12 high + + add w12, w12, #1 //CTR block 5 + fmov v1.d[1], x9 //CTR block 5 + eor x6, x6, x13 //AES block 0 - round 12 low + + rev w9, w12 //CTR block 6 + eor x7, x7, x14 //AES block 0 - round 12 high + + stp x6, x7, [x2], #16 //AES block 0 - store result + orr x9, x11, x9, lsl #32 //CTR block 6 + + stp x19, x20, [x2], #16 //AES block 1 - store result + + add w12, w12, #1 //CTR block 6 + eor v2.16b, v6.16b, v2.16b //AES block 2 - result + b.ge .L192_dec_prepretail //do prepretail + +.L192_dec_main_loop: //main loop start + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + + pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + mov x21, v2.d[0] //AES block 4k+2 - mov low + + mov x22, v2.d[1] //AES block 4k+2 - mov high + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + rev64 v7.16b, v7.16b //GHASH block 4k+3 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + fmov d2, x10 //CTR block 4k+6 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + eor v4.16b, v4.16b, v11.16b //PRE 1 + + pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + fmov v2.d[1], x9 //CTR block 4k+6 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + mov x24, v3.d[1] //AES block 4k+3 - mov high + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + mov x23, v3.d[0] //AES block 4k+3 - mov low + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + fmov d3, x10 //CTR block 4k+7 + mov d8, v4.d[1] //GHASH block 4k - mid + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d10, v17.d[1] //GHASH block 4k - mid + rev w9, w12 //CTR block 4k+7 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + + fmov v3.d[1], x9 //CTR block 4k+7 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + eor x22, x22, x14 //AES block 4k+2 - round 12 high + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + rev64 v6.16b, v6.16b //GHASH block 4k+2 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low + eor x21, x21, x13 //AES block 4k+2 - round 12 low + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + movi v8.8b, #0xc2 + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + shl d8, d8, #56 //mod_constant + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + ldr q6, [x0, #32] //AES block 4k+6 - load ciphertext + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + ldr q7, [x0, #48] //AES block 4k+7 - load ciphertext + eor x23, x23, x13 //AES block 4k+3 - round 12 low + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v0.16b, v29.16b //AES block 4k+4 - round 11 + add w12, w12, #1 //CTR block 4k+7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + ldr q4, [x0, #0] //AES block 4k+4 - load ciphertext + + aese v1.16b, v29.16b //AES block 4k+5 - round 11 + ldr q5, [x0, #16] //AES block 4k+5 - load ciphertext + rev w9, w12 //CTR block 4k+8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + add x0, x0, #64 //AES input_ptr update + cmp x0, x5 //.LOOP CONTROL + + eor v0.16b, v4.16b, v0.16b //AES block 4k+4 - result + eor x24, x24, x14 //AES block 4k+3 - round 12 high + eor v1.16b, v5.16b, v1.16b //AES block 4k+5 - result + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + mov x19, v1.d[0] //AES block 4k+5 - mov low + + mov x6, v0.d[0] //AES block 4k+4 - mov low + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + rev64 v5.16b, v5.16b //GHASH block 4k+5 + + aese v2.16b, v29.16b //AES block 4k+6 - round 11 + mov x7, v0.d[1] //AES block 4k+4 - mov high + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + mov x20, v1.d[1] //AES block 4k+5 - mov high + + fmov d0, x10 //CTR block 4k+8 + add w12, w12, #1 //CTR block 4k+8 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + eor v2.16b, v6.16b, v2.16b //AES block 4k+6 - result + fmov v0.d[1], x9 //CTR block 4k+8 + rev w9, w12 //CTR block 4k+9 + + eor x6, x6, x13 //AES block 4k+4 - round 12 low + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + fmov d1, x10 //CTR block 4k+9 + add w12, w12, #1 //CTR block 4k+9 + eor x19, x19, x13 //AES block 4k+5 - round 12 low + + fmov v1.d[1], x9 //CTR block 4k+9 + rev w9, w12 //CTR block 4k+10 + eor x20, x20, x14 //AES block 4k+5 - round 12 high + + eor x7, x7, x14 //AES block 4k+4 - round 12 high + stp x6, x7, [x2], #16 //AES block 4k+4 - store result + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + + add w12, w12, #1 //CTR block 4k+10 + rev64 v4.16b, v4.16b //GHASH block 4k+4 + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + + aese v3.16b, v29.16b //AES block 4k+7 - round 11 + stp x19, x20, [x2], #16 //AES block 4k+5 - store result + b.lt .L192_dec_main_loop + +.L192_dec_prepretail: //PREPRETAIL + mov x22, v2.d[1] //AES block 4k+2 - mov high + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + mov x21, v2.d[0] //AES block 4k+2 - mov low + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + mov d10, v17.d[1] //GHASH block 4k - mid + + eor v4.16b, v4.16b, v11.16b //PRE 1 + fmov d2, x10 //CTR block 4k+6 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + mov x23, v3.d[0] //AES block 4k+3 - mov low + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + mov x24, v3.d[1] //AES block 4k+3 - mov high + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + fmov d3, x10 //CTR block 4k+7 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + rev64 v6.16b, v6.16b //GHASH block 4k+2 + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + fmov v2.d[1], x9 //CTR block 4k+6 + rev w9, w12 //CTR block 4k+7 + + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + eor x24, x24, x14 //AES block 4k+3 - round 12 high + fmov v3.d[1], x9 //CTR block 4k+7 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + eor x21, x21, x13 //AES block 4k+2 - round 12 low + + pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + eor x22, x22, x14 //AES block 4k+2 - round 12 high + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + eor x23, x23, x13 //AES block 4k+3 - round 12 low + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + rev64 v7.16b, v7.16b //GHASH block 4k+3 + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + add w12, w12, #1 //CTR block 4k+7 + + pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + mov d31, v6.d[1] //GHASH block 4k+2 - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high + + eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid + + pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + mov d30, v7.d[1] //GHASH block 4k+3 - mid + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + movi v8.8b, #0xc2 + + pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + shl d8, d8, #56 //mod_constant + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + + aese v0.16b, v29.16b + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + aese v2.16b, v29.16b + + aese v1.16b, v29.16b + + aese v3.16b, v29.16b + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low +.L192_dec_tail: //TAIL + + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ld1 { v5.16b}, [x0], #16 //AES block 4k+4 - load ciphertext + + eor v0.16b, v5.16b, v0.16b //AES block 4k+4 - result + + mov x7, v0.d[1] //AES block 4k+4 - mov high + + mov x6, v0.d[0] //AES block 4k+4 - mov low + + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + + cmp x5, #48 + + eor x7, x7, x14 //AES block 4k+4 - round 12 high + + eor x6, x6, x13 //AES block 4k+4 - round 12 low + b.gt .L192_dec_blocks_more_than_3 + + movi v11.8b, #0 + movi v9.8b, #0 + + mov v3.16b, v2.16b + mov v2.16b, v1.16b + sub w12, w12, #1 + + movi v10.8b, #0 + cmp x5, #32 + b.gt .L192_dec_blocks_more_than_2 + + mov v3.16b, v1.16b + cmp x5, #16 + sub w12, w12, #1 + + b.gt .L192_dec_blocks_more_than_1 + + sub w12, w12, #1 + b .L192_dec_blocks_less_than_1 +.L192_dec_blocks_more_than_3: //blocks left > 3 + rev64 v4.16b, v5.16b //GHASH final-3 block + ld1 { v5.16b}, [x0], #16 //AES final-2 block - load ciphertext + + stp x6, x7, [x2], #16 //AES final-3 block - store result + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor v0.16b, v5.16b, v1.16b //AES final-2 block - result + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + mov x6, v0.d[0] //AES final-2 block - mov low + mov d22, v4.d[1] //GHASH final-3 block - mid + + mov x7, v0.d[1] //AES final-2 block - mov high + + mov d10, v17.d[1] //GHASH final-3 block - mid + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + eor x6, x6, x13 //AES final-2 block - round 12 low + movi v8.8b, #0 //suppress further partial tag feed in + + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid + eor x7, x7, x14 //AES final-2 block - round 12 high +.L192_dec_blocks_more_than_2: //blocks left > 2 + + rev64 v4.16b, v5.16b //GHASH final-2 block + ld1 { v5.16b}, [x0], #16 //AES final-1 block - load ciphertext + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + movi v8.8b, #0 //suppress further partial tag feed in + + eor v0.16b, v5.16b, v2.16b //AES final-1 block - result + + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + + stp x6, x7, [x2], #16 //AES final-2 block - store result + + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + mov x7, v0.d[1] //AES final-1 block - mov high + + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + mov x6, v0.d[0] //AES final-1 block - mov low + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + eor x7, x7, x14 //AES final-1 block - round 12 high + + eor x6, x6, x13 //AES final-1 block - round 12 low + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid +.L192_dec_blocks_more_than_1: //blocks left > 1 + + rev64 v4.16b, v5.16b //GHASH final-1 block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + ld1 { v5.16b}, [x0], #16 //AES final block - load ciphertext + + mov d22, v4.d[1] //GHASH final-1 block - mid + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + + eor v0.16b, v5.16b, v3.16b //AES final block - result + stp x6, x7, [x2], #16 //AES final-1 block - store result + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + mov x7, v0.d[1] //AES final block - mov high + + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + mov x6, v0.d[0] //AES final block - mov low + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low + eor x7, x7, x14 //AES final block - round 12 high + + eor x6, x6, x13 //AES final block - round 12 low + + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid +.L192_dec_blocks_less_than_1: //blocks left <= 1 + + mvn x13, xzr //rk12_l = 0xffffffffffffffff + ldp x4, x5, [x2] //load existing bytes we need to not overwrite + and x1, x1, #127 //bit_length %= 128 + + sub x1, x1, #128 //bit_length -= 128 + + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + + and x1, x1, #127 //bit_length %= 128 + mvn x14, xzr //rk12_h = 0xffffffffffffffff + + lsr x14, x14, x1 //rk12_h is mask for top 64b of last block + cmp x1, #64 + + csel x9, x13, x14, lt + csel x10, x14, xzr, lt + + fmov d0, x9 //ctr0b is mask for last block + and x6, x6, x9 + bic x4, x4, x9 //mask out low existing bytes + + orr x6, x6, x4 + mov v0.d[1], x10 + + rev w9, w12 + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + str w9, [x16, #12] //store the updated counter + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + bic x5, x5, x10 //mask out high existing bytes + + and x7, x7, x10 + + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + mov d8, v4.d[1] //GHASH final block - mid + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + shl d8, d8, #56 //mod_constant + + eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up + + pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + orr x7, x7, x5 + stp x6, x7, [x2] + + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L192_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_192_kernel,.-aes_gcm_dec_192_kernel +.globl aes_gcm_enc_256_kernel +.type aes_gcm_enc_256_kernel,%function +.align 4 +aes_gcm_enc_256_kernel: + cbz x1, .L256_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + add x4, x0, x1, lsr #3 //end_input_ptr + lsr x5, x1, #3 //byte_len + mov x15, x5 + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 + + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + sub x5, x5, #1 //byte_len - 1 + + ldr q18, [x8, #0] //load rk0 + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + ldr q25, [x8, #112] //load rk7 + add x5, x5, x0 + + lsr x12, x11, #32 + fmov d2, x10 //CTR block 2 + orr w11, w11, w11 + + rev w12, w12 //rev_ctr32 + cmp x0, x5 //check if we have <= 4 blocks + fmov d1, x10 //CTR block 1 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + add w12, w12, #1 //increment rev_ctr32 + + rev w9, w12 //CTR block 1 + fmov d3, x10 //CTR block 3 + + orr x9, x11, x9, lsl #32 //CTR block 1 + add w12, w12, #1 //CTR block 1 + ldr q19, [x8, #16] //load rk1 + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + orr x9, x11, x9, lsl #32 //CTR block 2 + ldr q20, [x8, #32] //load rk2 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + orr x9, x11, x9, lsl #32 //CTR block 3 + + fmov v3.d[1], x9 //CTR block 3 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ldr q21, [x8, #48] //load rk3 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + ldr q24, [x8, #96] //load rk6 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ldr q23, [x8, #80] //load rk5 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + ldr q14, [x3, #80] //load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + ldr q31, [x8, #208] //load rk13 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + ldr q22, [x8, #64] //load rk4 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + ldr q13, [x3, #64] //load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + ldr q30, [x8, #192] //load rk12 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + ldr q15, [x3, #112] //load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + ldr q29, [x8, #176] //load rk11 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + ldr q26, [x8, #128] //load rk8 + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + add w12, w12, #1 //CTR block 3 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + ldp x13, x14, [x8, #224] //load rk14 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + ldr q27, [x8, #144] //load rk9 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + ldr q12, [x3, #32] //load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + ldr q28, [x8, #160] //load rk10 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 1 - round 9 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 2 - round 9 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 1 - round 10 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 3 - round 9 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 0 - round 9 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 2 - round 10 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 3 - round 10 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 1 - round 11 + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 2 - round 11 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 0 - round 10 + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 1 - round 12 + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 2 - round 12 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 0 - round 11 + eor v17.16b, v17.16b, v9.16b //h4k | h3k + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 3 - round 11 + + aese v2.16b, v31.16b //AES block 2 - round 13 + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 0 - round 12 + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 3 - round 12 + + aese v1.16b, v31.16b //AES block 1 - round 13 + + aese v0.16b, v31.16b //AES block 0 - round 13 + + aese v3.16b, v31.16b //AES block 3 - round 13 + eor v16.16b, v16.16b, v8.16b //h2k | h1k + b.ge .L256_enc_tail //handle tail + + ldp x19, x20, [x0, #16] //AES block 1 - load plaintext + + rev w9, w12 //CTR block 4 + ldp x6, x7, [x0, #0] //AES block 0 - load plaintext + + ldp x23, x24, [x0, #48] //AES block 3 - load plaintext + + ldp x21, x22, [x0, #32] //AES block 2 - load plaintext + add x0, x0, #64 //AES input_ptr update + + eor x19, x19, x13 //AES block 1 - round 14 low + eor x20, x20, x14 //AES block 1 - round 14 high + + fmov d5, x19 //AES block 1 - mov low + eor x6, x6, x13 //AES block 0 - round 14 low + + eor x7, x7, x14 //AES block 0 - round 14 high + eor x24, x24, x14 //AES block 3 - round 14 high + fmov d4, x6 //AES block 0 - mov low + + cmp x0, x5 //check if we have <= 8 blocks + fmov v4.d[1], x7 //AES block 0 - mov high + eor x23, x23, x13 //AES block 3 - round 14 low + + eor x21, x21, x13 //AES block 2 - round 14 low + fmov v5.d[1], x20 //AES block 1 - mov high + + fmov d6, x21 //AES block 2 - mov low + add w12, w12, #1 //CTR block 4 + + orr x9, x11, x9, lsl #32 //CTR block 4 + fmov d7, x23 //AES block 3 - mov low + eor x22, x22, x14 //AES block 2 - round 14 high + + fmov v6.d[1], x22 //AES block 2 - mov high + + eor v4.16b, v4.16b, v0.16b //AES block 0 - result + fmov d0, x10 //CTR block 4 + + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + add w12, w12, #1 //CTR block 5 + + eor v5.16b, v5.16b, v1.16b //AES block 1 - result + fmov d1, x10 //CTR block 5 + orr x9, x11, x9, lsl #32 //CTR block 5 + + fmov v1.d[1], x9 //CTR block 5 + rev w9, w12 //CTR block 6 + st1 { v4.16b}, [x2], #16 //AES block 0 - store result + + fmov v7.d[1], x24 //AES block 3 - mov high + orr x9, x11, x9, lsl #32 //CTR block 6 + eor v6.16b, v6.16b, v2.16b //AES block 2 - result + + st1 { v5.16b}, [x2], #16 //AES block 1 - store result + + add w12, w12, #1 //CTR block 6 + fmov d2, x10 //CTR block 6 + + fmov v2.d[1], x9 //CTR block 6 + st1 { v6.16b}, [x2], #16 //AES block 2 - store result + rev w9, w12 //CTR block 7 + + orr x9, x11, x9, lsl #32 //CTR block 7 + + eor v7.16b, v7.16b, v3.16b //AES block 3 - result + st1 { v7.16b}, [x2], #16 //AES block 3 - store result + b.ge .L256_enc_prepretail //do prepretail + +.L256_enc_main_loop: //main loop start + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + fmov d3, x10 //CTR block 4k+3 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + fmov v3.d[1], x9 //CTR block 4k+3 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + ldp x23, x24, [x0, #48] //AES block 4k+7 - load plaintext + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + ldp x21, x22, [x0, #32] //AES block 4k+6 - load plaintext + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + eor v4.16b, v4.16b, v11.16b //PRE 1 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor x23, x23, x13 //AES block 4k+7 - round 14 low + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + mov d10, v17.d[1] //GHASH block 4k - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + eor x22, x22, x14 //AES block 4k+6 - round 14 high + mov d8, v4.d[1] //GHASH block 4k - mid + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + mov d8, v6.d[1] //GHASH block 4k+2 - mid + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + ldp x19, x20, [x0, #16] //AES block 4k+5 - load plaintext + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + mov d4, v7.d[1] //GHASH block 4k+3 - mid + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low + + pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + eor v4.8b, v4.8b, v7.8b //GHASH block 4k+3 - mid + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + eor x19, x19, x13 //AES block 4k+5 - round 14 low + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + eor x21, x21, x13 //AES block 4k+6 - round 14 low + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + movi v8.8b, #0xc2 + + pmull v4.1q, v4.1d, v16.1d //GHASH block 4k+3 - mid + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + fmov d5, x19 //AES block 4k+5 - mov low + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + ldp x6, x7, [x0, #0] //AES block 4k+4 - load plaintext + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + shl d8, d8, #56 //mod_constant + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+3 - mid + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + add w12, w12, #1 //CTR block 4k+3 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 11 + eor v4.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 11 + add x0, x0, #64 //AES input_ptr update + + pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + rev w9, w12 //CTR block 4k+8 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + eor x6, x6, x13 //AES block 4k+4 - round 14 low + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 12 + eor v10.16b, v10.16b, v4.16b //MODULO - karatsuba tidy up + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + eor x7, x7, x14 //AES block 4k+4 - round 14 high + + fmov d4, x6 //AES block 4k+4 - mov low + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + eor v7.16b, v9.16b, v7.16b //MODULO - fold into mid + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 12 + eor x20, x20, x14 //AES block 4k+5 - round 14 high + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 11 + eor x24, x24, x14 //AES block 4k+7 - round 14 high + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 11 + add w12, w12, #1 //CTR block 4k+8 + + aese v0.16b, v31.16b //AES block 4k+4 - round 13 + fmov v4.d[1], x7 //AES block 4k+4 - mov high + eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 12 + fmov d7, x23 //AES block 4k+7 - mov low + + aese v1.16b, v31.16b //AES block 4k+5 - round 13 + fmov v5.d[1], x20 //AES block 4k+5 - mov high + + fmov d6, x21 //AES block 4k+6 - mov low + cmp x0, x5 //.LOOP CONTROL + + fmov v6.d[1], x22 //AES block 4k+6 - mov high + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + eor v4.16b, v4.16b, v0.16b //AES block 4k+4 - result + fmov d0, x10 //CTR block 4k+8 + + fmov v0.d[1], x9 //CTR block 4k+8 + rev w9, w12 //CTR block 4k+9 + add w12, w12, #1 //CTR block 4k+9 + + eor v5.16b, v5.16b, v1.16b //AES block 4k+5 - result + fmov d1, x10 //CTR block 4k+9 + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 12 + fmov v1.d[1], x9 //CTR block 4k+9 + + aese v2.16b, v31.16b //AES block 4k+6 - round 13 + rev w9, w12 //CTR block 4k+10 + st1 { v4.16b}, [x2], #16 //AES block 4k+4 - store result + + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + fmov v7.d[1], x24 //AES block 4k+7 - mov high + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + st1 { v5.16b}, [x2], #16 //AES block 4k+5 - store result + add w12, w12, #1 //CTR block 4k+10 + + aese v3.16b, v31.16b //AES block 4k+7 - round 13 + eor v6.16b, v6.16b, v2.16b //AES block 4k+6 - result + fmov d2, x10 //CTR block 4k+10 + + st1 { v6.16b}, [x2], #16 //AES block 4k+6 - store result + fmov v2.d[1], x9 //CTR block 4k+10 + rev w9, w12 //CTR block 4k+11 + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + orr x9, x11, x9, lsl #32 //CTR block 4k+11 + + eor v7.16b, v7.16b, v3.16b //AES block 4k+7 - result + st1 { v7.16b}, [x2], #16 //AES block 4k+7 - store result + b.lt .L256_enc_main_loop + +.L256_enc_prepretail: //PREPRETAIL + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free) + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + fmov d3, x10 //CTR block 4k+3 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free) + + fmov v3.d[1], x9 //CTR block 4k+3 + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + + eor v4.16b, v4.16b, v11.16b //PRE 1 + rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free) + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + + pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + mov d8, v6.d[1] //GHASH block 4k+2 - mid + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free) + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid + add w12, w12, #1 //CTR block 4k+3 + + pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low + ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high + mov d4, v7.d[1] //GHASH block 4k+3 - mid + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid + + eor v4.8b, v4.8b, v7.8b //GHASH block 4k+3 - mid + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + pmull v4.1q, v4.1d, v16.1d //GHASH block 4k+3 - mid + eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + shl d8, d8, #56 //mod_constant + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+3 - mid + + pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + eor v10.16b, v10.16b, v9.16b //karatsuba tidy up + + pmull v4.1q, v9.1d, v8.1d + ext v9.16b, v9.16b, v9.16b, #8 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + eor v10.16b, v10.16b, v11.16b + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 11 + eor v10.16b, v10.16b, v4.16b + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 12 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 11 + eor v10.16b, v10.16b, v9.16b + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 11 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 12 + + pmull v4.1q, v10.1d, v8.1d + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 11 + ext v10.16b, v10.16b, v10.16b, #8 + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 12 + + aese v1.16b, v31.16b //AES block 4k+5 - round 13 + eor v11.16b, v11.16b, v4.16b + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 12 + + aese v3.16b, v31.16b //AES block 4k+7 - round 13 + + aese v0.16b, v31.16b //AES block 4k+4 - round 13 + + aese v2.16b, v31.16b //AES block 4k+6 - round 13 + eor v11.16b, v11.16b, v10.16b +.L256_enc_tail: //TAIL + + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ldp x6, x7, [x0], #16 //AES block 4k+4 - load plaintext + + eor x6, x6, x13 //AES block 4k+4 - round 14 low + eor x7, x7, x14 //AES block 4k+4 - round 14 high + + cmp x5, #48 + fmov d4, x6 //AES block 4k+4 - mov low + + fmov v4.d[1], x7 //AES block 4k+4 - mov high + + eor v5.16b, v4.16b, v0.16b //AES block 4k+4 - result + b.gt .L256_enc_blocks_more_than_3 + + cmp x5, #32 + mov v3.16b, v2.16b + movi v11.8b, #0 + + movi v9.8b, #0 + sub w12, w12, #1 + + mov v2.16b, v1.16b + movi v10.8b, #0 + b.gt .L256_enc_blocks_more_than_2 + + mov v3.16b, v1.16b + sub w12, w12, #1 + cmp x5, #16 + + b.gt .L256_enc_blocks_more_than_1 + + sub w12, w12, #1 + b .L256_enc_blocks_less_than_1 +.L256_enc_blocks_more_than_3: //blocks left > 3 + st1 { v5.16b}, [x2], #16 //AES final-3 block - store result + + ldp x6, x7, [x0], #16 //AES final-2 block - load input low & high + + rev64 v4.16b, v5.16b //GHASH final-3 block + + eor x6, x6, x13 //AES final-2 block - round 14 low + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor x7, x7, x14 //AES final-2 block - round 14 high + + mov d22, v4.d[1] //GHASH final-3 block - mid + fmov d5, x6 //AES final-2 block - mov low + + fmov v5.d[1], x7 //AES final-2 block - mov high + + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + movi v8.8b, #0 //suppress further partial tag feed in + + mov d10, v17.d[1] //GHASH final-3 block - mid + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid + eor v5.16b, v5.16b, v1.16b //AES final-2 block - result +.L256_enc_blocks_more_than_2: //blocks left > 2 + + st1 { v5.16b}, [x2], #16 //AES final-2 block - store result + + ldp x6, x7, [x0], #16 //AES final-1 block - load input low & high + + rev64 v4.16b, v5.16b //GHASH final-2 block + + eor x6, x6, x13 //AES final-1 block - round 14 low + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + fmov d5, x6 //AES final-1 block - mov low + eor x7, x7, x14 //AES final-1 block - round 14 high + + fmov v5.d[1], x7 //AES final-1 block - mov high + + movi v8.8b, #0 //suppress further partial tag feed in + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + + eor v5.16b, v5.16b, v2.16b //AES final-1 block - result + + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid +.L256_enc_blocks_more_than_1: //blocks left > 1 + + st1 { v5.16b}, [x2], #16 //AES final-1 block - store result + + rev64 v4.16b, v5.16b //GHASH final-1 block + + ldp x6, x7, [x0], #16 //AES final block - load input low & high + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + movi v8.8b, #0 //suppress further partial tag feed in + + eor x6, x6, x13 //AES final block - round 14 low + mov d22, v4.d[1] //GHASH final-1 block - mid + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + eor x7, x7, x14 //AES final block - round 14 high + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + fmov d5, x6 //AES final block - mov low + + fmov v5.d[1], x7 //AES final block - mov high + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + + eor v5.16b, v5.16b, v3.16b //AES final block - result + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low +.L256_enc_blocks_less_than_1: //blocks left <= 1 + + and x1, x1, #127 //bit_length %= 128 + + mvn x13, xzr //rk14_l = 0xffffffffffffffff + sub x1, x1, #128 //bit_length -= 128 + + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + ld1 { v18.16b}, [x2] //load existing bytes where the possibly partial last block is to be stored + + mvn x14, xzr //rk14_h = 0xffffffffffffffff + and x1, x1, #127 //bit_length %= 128 + + lsr x14, x14, x1 //rk14_h is mask for top 64b of last block + cmp x1, #64 + + csel x6, x13, x14, lt + csel x7, x14, xzr, lt + + fmov d0, x6 //ctr0b is mask for last block + + fmov v0.d[1], x7 + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + bif v5.16b, v18.16b, v0.16b //insert existing bytes in top end of result before storing + + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + mov d8, v4.d[1] //GHASH final block - mid + rev w9, w12 + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v4.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + shl d8, d8, #56 //mod_constant + + eor v10.16b, v10.16b, v4.16b //MODULO - karatsuba tidy up + + pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + str w9, [x16, #12] //store the updated counter + + st1 { v5.16b}, [x2] //store all 16B + eor v11.16b, v11.16b, v9.16b //MODULO - fold into low + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L256_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_256_kernel,.-aes_gcm_enc_256_kernel +.globl aes_gcm_dec_256_kernel +.type aes_gcm_dec_256_kernel,%function +.align 4 +aes_gcm_dec_256_kernel: + cbz x1, .L256_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + lsr x5, x1, #3 //byte_len + mov x15, x5 + ldp x10, x11, [x16] //ctr96_b64, ctr96_t32 + + ldr q26, [x8, #128] //load rk8 + sub x5, x5, #1 //byte_len - 1 + + ldr q25, [x8, #112] //load rk7 + and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + add x4, x0, x1, lsr #3 //end_input_ptr + ldr q24, [x8, #96] //load rk6 + + lsr x12, x11, #32 + ldr q23, [x8, #80] //load rk5 + orr w11, w11, w11 + + ldr q21, [x8, #48] //load rk3 + add x5, x5, x0 + rev w12, w12 //rev_ctr32 + + add w12, w12, #1 //increment rev_ctr32 + fmov d3, x10 //CTR block 3 + + rev w9, w12 //CTR block 1 + add w12, w12, #1 //CTR block 1 + fmov d1, x10 //CTR block 1 + + orr x9, x11, x9, lsl #32 //CTR block 1 + ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible + + fmov v1.d[1], x9 //CTR block 1 + rev w9, w12 //CTR block 2 + add w12, w12, #1 //CTR block 2 + + fmov d2, x10 //CTR block 2 + orr x9, x11, x9, lsl #32 //CTR block 2 + + fmov v2.d[1], x9 //CTR block 2 + rev w9, w12 //CTR block 3 + + orr x9, x11, x9, lsl #32 //CTR block 3 + ldr q18, [x8, #0] //load rk0 + + fmov v3.d[1], x9 //CTR block 3 + add w12, w12, #1 //CTR block 3 + + ldr q22, [x8, #64] //load rk4 + + ldr q31, [x8, #208] //load rk13 + + ldr q19, [x8, #16] //load rk1 + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 0 - round 0 + ldr q14, [x3, #80] //load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 3 - round 0 + ldr q15, [x3, #112] //load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 1 - round 0 + ldr q13, [x3, #64] //load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 2 - round 0 + ldr q20, [x8, #32] //load rk2 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 0 - round 1 + ldp x13, x14, [x8, #224] //load rk14 + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 1 - round 1 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 2 - round 1 + ldr q27, [x8, #144] //load rk9 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 3 - round 1 + ldr q30, [x8, #192] //load rk12 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 0 - round 2 + ldr q12, [x3, #32] //load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 2 - round 2 + ldr q28, [x8, #160] //load rk10 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 3 - round 2 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 0 - round 3 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 1 - round 2 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 3 - round 3 + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 0 - round 4 + cmp x0, x5 //check if we have <= 4 blocks + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 2 - round 3 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 1 - round 3 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 3 - round 4 + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 2 - round 4 + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 1 - round 4 + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 3 - round 5 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 0 - round 5 + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 1 - round 5 + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 2 - round 5 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 0 - round 6 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 3 - round 6 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 1 - round 6 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 2 - round 6 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 0 - round 7 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 1 - round 7 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 3 - round 7 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 0 - round 8 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 2 - round 7 + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 3 - round 8 + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 1 - round 8 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 0 - round 9 + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 2 - round 8 + ldr q29, [x8, #176] //load rk11 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 1 - round 9 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 0 - round 10 + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 3 - round 9 + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 1 - round 10 + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 2 - round 9 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 3 - round 10 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 0 - round 11 + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 2 - round 10 + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 3 - round 11 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 1 - round 11 + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 2 - round 11 + + trn1 v9.2d, v14.2d, v15.2d //h4h | h3h + + trn2 v17.2d, v14.2d, v15.2d //h4l | h3l + + trn1 v8.2d, v12.2d, v13.2d //h2h | h1h + trn2 v16.2d, v12.2d, v13.2d //h2l | h1l + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 1 - round 12 + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 0 - round 12 + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 2 - round 12 + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 3 - round 12 + eor v17.16b, v17.16b, v9.16b //h4k | h3k + + aese v1.16b, v31.16b //AES block 1 - round 13 + + aese v2.16b, v31.16b //AES block 2 - round 13 + eor v16.16b, v16.16b, v8.16b //h2k | h1k + + aese v3.16b, v31.16b //AES block 3 - round 13 + + aese v0.16b, v31.16b //AES block 0 - round 13 + b.ge .L256_dec_tail //handle tail + + ldr q4, [x0, #0] //AES block 0 - load ciphertext + + ldr q5, [x0, #16] //AES block 1 - load ciphertext + + rev w9, w12 //CTR block 4 + + eor v0.16b, v4.16b, v0.16b //AES block 0 - result + + eor v1.16b, v5.16b, v1.16b //AES block 1 - result + rev64 v5.16b, v5.16b //GHASH block 1 + ldr q7, [x0, #48] //AES block 3 - load ciphertext + + mov x7, v0.d[1] //AES block 0 - mov high + + mov x6, v0.d[0] //AES block 0 - mov low + rev64 v4.16b, v4.16b //GHASH block 0 + add w12, w12, #1 //CTR block 4 + + fmov d0, x10 //CTR block 4 + orr x9, x11, x9, lsl #32 //CTR block 4 + + fmov v0.d[1], x9 //CTR block 4 + rev w9, w12 //CTR block 5 + add w12, w12, #1 //CTR block 5 + + mov x19, v1.d[0] //AES block 1 - mov low + + orr x9, x11, x9, lsl #32 //CTR block 5 + mov x20, v1.d[1] //AES block 1 - mov high + eor x7, x7, x14 //AES block 0 - round 14 high + + eor x6, x6, x13 //AES block 0 - round 14 low + stp x6, x7, [x2], #16 //AES block 0 - store result + fmov d1, x10 //CTR block 5 + + ldr q6, [x0, #32] //AES block 2 - load ciphertext + add x0, x0, #64 //AES input_ptr update + + fmov v1.d[1], x9 //CTR block 5 + rev w9, w12 //CTR block 6 + add w12, w12, #1 //CTR block 6 + + eor x19, x19, x13 //AES block 1 - round 14 low + orr x9, x11, x9, lsl #32 //CTR block 6 + + eor x20, x20, x14 //AES block 1 - round 14 high + stp x19, x20, [x2], #16 //AES block 1 - store result + + eor v2.16b, v6.16b, v2.16b //AES block 2 - result + cmp x0, x5 //check if we have <= 8 blocks + b.ge .L256_dec_prepretail //do prepretail + +.L256_dec_main_loop: //main loop start + mov x21, v2.d[0] //AES block 4k+2 - mov low + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + mov x22, v2.d[1] //AES block 4k+2 - mov high + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + fmov d2, x10 //CTR block 4k+6 + + fmov v2.d[1], x9 //CTR block 4k+6 + eor v4.16b, v4.16b, v11.16b //PRE 1 + rev w9, w12 //CTR block 4k+7 + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + mov x24, v3.d[1] //AES block 4k+3 - mov high + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + mov x23, v3.d[0] //AES block 4k+3 - mov low + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + mov d8, v4.d[1] //GHASH block 4k - mid + fmov d3, x10 //CTR block 4k+7 + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + fmov v3.d[1], x9 //CTR block 4k+7 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + eor x22, x22, x14 //AES block 4k+2 - round 14 high + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + rev64 v6.16b, v6.16b //GHASH block 4k+2 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + eor x21, x21, x13 //AES block 4k+2 - round 14 low + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + + pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + rev64 v7.16b, v7.16b //GHASH block 4k+3 + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + eor x23, x23, x13 //AES block 4k+3 - round 14 low + + pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + eor x24, x24, x14 //AES block 4k+3 - round 14 high + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + add w12, w12, #1 //CTR block 4k+7 + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + mov d8, v6.d[1] //GHASH block 4k+2 - mid + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + rev w9, w12 //CTR block 4k+8 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + add w12, w12, #1 //CTR block 4k+8 + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + + pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + mov d6, v7.d[1] //GHASH block 4k+3 - mid + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + + pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + + pmull v4.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + orr x9, x11, x9, lsl #32 //CTR block 4k+8 + eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + eor v6.8b, v6.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + + pmull v6.1q, v6.1d, v16.1d //GHASH block 4k+3 - mid + movi v8.8b, #0xc2 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + eor v11.16b, v11.16b, v4.16b //GHASH block 4k+3 - low + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 11 + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + shl d8, d8, #56 //mod_constant + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v6.16b //GHASH block 4k+3 - mid + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 12 + + pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + eor v6.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + ldr q4, [x0, #0] //AES block 4k+4 - load ciphertext + + aese v0.16b, v31.16b //AES block 4k+4 - round 13 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + eor v10.16b, v10.16b, v6.16b //MODULO - karatsuba tidy up + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + ldr q5, [x0, #16] //AES block 4k+5 - load ciphertext + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + eor v0.16b, v4.16b, v0.16b //AES block 4k+4 - result + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 11 + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + ldr q7, [x0, #48] //AES block 4k+7 - load ciphertext + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 12 + ldr q6, [x0, #32] //AES block 4k+6 - load ciphertext + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 11 + mov x7, v0.d[1] //AES block 4k+4 - mov high + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v1.16b, v31.16b //AES block 4k+5 - round 13 + add x0, x0, #64 //AES input_ptr update + mov x6, v0.d[0] //AES block 4k+4 - mov low + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 12 + fmov d0, x10 //CTR block 4k+8 + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 11 + fmov v0.d[1], x9 //CTR block 4k+8 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + eor v1.16b, v5.16b, v1.16b //AES block 4k+5 - result + rev w9, w12 //CTR block 4k+9 + + aese v2.16b, v31.16b //AES block 4k+6 - round 13 + orr x9, x11, x9, lsl #32 //CTR block 4k+9 + cmp x0, x5 //.LOOP CONTROL + + add w12, w12, #1 //CTR block 4k+9 + + eor x6, x6, x13 //AES block 4k+4 - round 14 low + eor x7, x7, x14 //AES block 4k+4 - round 14 high + + mov x20, v1.d[1] //AES block 4k+5 - mov high + eor v2.16b, v6.16b, v2.16b //AES block 4k+6 - result + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 12 + mov x19, v1.d[0] //AES block 4k+5 - mov low + + fmov d1, x10 //CTR block 4k+9 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + fmov v1.d[1], x9 //CTR block 4k+9 + rev w9, w12 //CTR block 4k+10 + add w12, w12, #1 //CTR block 4k+10 + + aese v3.16b, v31.16b //AES block 4k+7 - round 13 + orr x9, x11, x9, lsl #32 //CTR block 4k+10 + + rev64 v5.16b, v5.16b //GHASH block 4k+5 + eor x20, x20, x14 //AES block 4k+5 - round 14 high + stp x6, x7, [x2], #16 //AES block 4k+4 - store result + + eor x19, x19, x13 //AES block 4k+5 - round 14 low + stp x19, x20, [x2], #16 //AES block 4k+5 - store result + + rev64 v4.16b, v4.16b //GHASH block 4k+4 + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + b.lt .L256_dec_main_loop + + +.L256_dec_prepretail: //PREPRETAIL + ext v11.16b, v11.16b, v11.16b, #8 //PRE 0 + mov x21, v2.d[0] //AES block 4k+2 - mov low + eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result + + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 0 + mov x22, v2.d[1] //AES block 4k+2 - mov high + + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 0 + fmov d2, x10 //CTR block 4k+6 + + fmov v2.d[1], x9 //CTR block 4k+6 + rev w9, w12 //CTR block 4k+7 + eor v4.16b, v4.16b, v11.16b //PRE 1 + + rev64 v6.16b, v6.16b //GHASH block 4k+2 + orr x9, x11, x9, lsl #32 //CTR block 4k+7 + mov x23, v3.d[0] //AES block 4k+3 - mov low + + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 1 + mov x24, v3.d[1] //AES block 4k+3 - mov high + + pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low + mov d8, v4.d[1] //GHASH block 4k - mid + fmov d3, x10 //CTR block 4k+7 + + pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high + fmov v3.d[1], x9 //CTR block 4k+7 + + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 0 + mov d10, v17.d[1] //GHASH block 4k - mid + + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 1 + eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid + + pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high + + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 1 + rev64 v7.16b, v7.16b //GHASH block 4k+3 + + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 0 + + pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high + + pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low + + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 1 + mov d4, v5.d[1] //GHASH block 4k+1 - mid + + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 2 + + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 2 + eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low + + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 2 + + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 3 + mov d8, v6.d[1] //GHASH block 4k+2 - mid + + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 2 + eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid + + pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low + + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 4 + + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid + + pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid + + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low + + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 4 + + pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high + eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid + + pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high + + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid + + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 3 + + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 3 + eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high + + pmull v4.1q, v7.1d, v12.1d //GHASH block 4k+3 - low + + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 4 + mov d6, v7.d[1] //GHASH block 4k+3 - mid + + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 4 + + pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid + + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 5 + eor v6.8b, v6.8b, v7.8b //GHASH block 4k+3 - mid + + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 5 + + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid + + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 6 + + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 6 + eor v11.16b, v11.16b, v4.16b //GHASH block 4k+3 - low + + pmull v6.1q, v6.1d, v16.1d //GHASH block 4k+3 - mid + + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 7 + eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high + + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 7 + + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 7 + eor v10.16b, v10.16b, v6.16b //GHASH block 4k+3 - mid + + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 8 + + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 7 + eor v6.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 8 + + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 8 + shl d8, d8, #56 //mod_constant + + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 8 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 9 + eor v10.16b, v10.16b, v6.16b //MODULO - karatsuba tidy up + + pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 9 + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 9 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 9 + eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid + + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 10 + + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 10 + + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 10 + eor x22, x22, x14 //AES block 4k+2 - round 14 high + + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 10 + eor x23, x23, x13 //AES block 4k+3 - round 14 low + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 11 + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 11 + add w12, w12, #1 //CTR block 4k+7 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 11 + eor x21, x21, x13 //AES block 4k+2 - round 14 low + + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b //AES block 4k+6 - round 12 + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + eor x24, x24, x14 //AES block 4k+3 - round 14 high + + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 11 + stp x21, x22, [x2], #16 //AES block 4k+2 - store result + + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b //AES block 4k+5 - round 12 + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b //AES block 4k+4 - round 12 + stp x23, x24, [x2], #16 //AES block 4k+3 - store result + + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b //AES block 4k+7 - round 12 + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + aese v1.16b, v31.16b //AES block 4k+5 - round 13 + + aese v0.16b, v31.16b //AES block 4k+4 - round 13 + + aese v3.16b, v31.16b //AES block 4k+7 - round 13 + + aese v2.16b, v31.16b //AES block 4k+6 - round 13 + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low +.L256_dec_tail: //TAIL + + sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process + ld1 { v5.16b}, [x0], #16 //AES block 4k+4 - load ciphertext + + eor v0.16b, v5.16b, v0.16b //AES block 4k+4 - result + + mov x6, v0.d[0] //AES block 4k+4 - mov low + + mov x7, v0.d[1] //AES block 4k+4 - mov high + ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag + + cmp x5, #48 + + eor x6, x6, x13 //AES block 4k+4 - round 14 low + + eor x7, x7, x14 //AES block 4k+4 - round 14 high + b.gt .L256_dec_blocks_more_than_3 + + sub w12, w12, #1 + mov v3.16b, v2.16b + movi v10.8b, #0 + + movi v11.8b, #0 + cmp x5, #32 + + movi v9.8b, #0 + mov v2.16b, v1.16b + b.gt .L256_dec_blocks_more_than_2 + + sub w12, w12, #1 + + mov v3.16b, v1.16b + cmp x5, #16 + b.gt .L256_dec_blocks_more_than_1 + + sub w12, w12, #1 + b .L256_dec_blocks_less_than_1 +.L256_dec_blocks_more_than_3: //blocks left > 3 + rev64 v4.16b, v5.16b //GHASH final-3 block + ld1 { v5.16b}, [x0], #16 //AES final-2 block - load ciphertext + + stp x6, x7, [x2], #16 //AES final-3 block - store result + + mov d10, v17.d[1] //GHASH final-3 block - mid + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + eor v0.16b, v5.16b, v1.16b //AES final-2 block - result + + mov d22, v4.d[1] //GHASH final-3 block - mid + + mov x6, v0.d[0] //AES final-2 block - mov low + + mov x7, v0.d[1] //AES final-2 block - mov high + + eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid + + movi v8.8b, #0 //suppress further partial tag feed in + + pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high + + pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid + eor x6, x6, x13 //AES final-2 block - round 14 low + + pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low + eor x7, x7, x14 //AES final-2 block - round 14 high +.L256_dec_blocks_more_than_2: //blocks left > 2 + + rev64 v4.16b, v5.16b //GHASH final-2 block + ld1 { v5.16b}, [x0], #16 //AES final-1 block - load ciphertext + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + stp x6, x7, [x2], #16 //AES final-2 block - store result + + eor v0.16b, v5.16b, v2.16b //AES final-1 block - result + + mov d22, v4.d[1] //GHASH final-2 block - mid + + pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low + + pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high + + eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid + mov x6, v0.d[0] //AES final-1 block - mov low + + mov x7, v0.d[1] //AES final-1 block - mov high + eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low + movi v8.8b, #0 //suppress further partial tag feed in + + pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high + eor x6, x6, x13 //AES final-1 block - round 14 low + + eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid + eor x7, x7, x14 //AES final-1 block - round 14 high +.L256_dec_blocks_more_than_1: //blocks left > 1 + + stp x6, x7, [x2], #16 //AES final-1 block - store result + rev64 v4.16b, v5.16b //GHASH final-1 block + + ld1 { v5.16b}, [x0], #16 //AES final block - load ciphertext + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + movi v8.8b, #0 //suppress further partial tag feed in + + mov d22, v4.d[1] //GHASH final-1 block - mid + + eor v0.16b, v5.16b, v3.16b //AES final block - result + + pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high + + eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid + + pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low + mov x6, v0.d[0] //AES final block - mov low + + ins v22.d[1], v22.d[0] //GHASH final-1 block - mid + + mov x7, v0.d[1] //AES final block - mov high + + pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid + eor x6, x6, x13 //AES final block - round 14 low + + eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low + + eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high + + eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid + eor x7, x7, x14 //AES final block - round 14 high +.L256_dec_blocks_less_than_1: //blocks left <= 1 + + and x1, x1, #127 //bit_length %= 128 + mvn x14, xzr //rk14_h = 0xffffffffffffffff + + sub x1, x1, #128 //bit_length -= 128 + mvn x13, xzr //rk14_l = 0xffffffffffffffff + + ldp x4, x5, [x2] //load existing bytes we need to not overwrite + neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128]) + + and x1, x1, #127 //bit_length %= 128 + + lsr x14, x14, x1 //rk14_h is mask for top 64b of last block + cmp x1, #64 + + csel x9, x13, x14, lt + csel x10, x14, xzr, lt + + fmov d0, x9 //ctr0b is mask for last block + and x6, x6, x9 + + mov v0.d[1], x10 + bic x4, x4, x9 //mask out low existing bytes + + rev w9, w12 + + bic x5, x5, x10 //mask out high existing bytes + + orr x6, x6, x4 + + and x7, x7, x10 + + orr x7, x7, x5 + + and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits + + rev64 v4.16b, v5.16b //GHASH final block + + eor v4.16b, v4.16b, v8.16b //feed in partial tag + + pmull v21.1q, v4.1d, v12.1d //GHASH final block - low + + mov d8, v4.d[1] //GHASH final block - mid + + eor v8.8b, v8.8b, v4.8b //GHASH final block - mid + + pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high + + pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid + + eor v9.16b, v9.16b, v20.16b //GHASH final block - high + + eor v11.16b, v11.16b, v21.16b //GHASH final block - low + + eor v10.16b, v10.16b, v8.16b //GHASH final block - mid + movi v8.8b, #0xc2 + + eor v6.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up + + shl d8, d8, #56 //mod_constant + + eor v10.16b, v10.16b, v6.16b //MODULO - karatsuba tidy up + + pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid + + ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment + + eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid + + eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid + + pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low + + ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment + + eor v11.16b, v11.16b, v8.16b //MODULO - fold into low + + stp x6, x7, [x2] + + str w9, [x16, #12] //store the updated counter + + eor v11.16b, v11.16b, v10.16b //MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L256_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_256_kernel,.-aes_gcm_dec_256_kernel +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif diff --git a/crypto/openssl/crypto/modes/aesni-gcm-x86_64.S b/crypto/openssl/crypto/modes/aesni-gcm-x86_64.S new file mode 100644 index 000000000000..e3813bf7cea0 --- /dev/null +++ b/crypto/openssl/crypto/modes/aesni-gcm-x86_64.S @@ -0,0 +1,810 @@ +.text + +.type _aesni_ctr32_ghash_6x,@function +.align 32 +_aesni_ctr32_ghash_6x: +.cfi_startproc + vmovdqu 32(%r11),%xmm2 + subq $6,%rdx + vpxor %xmm4,%xmm4,%xmm4 + vmovdqu 0-128(%rcx),%xmm15 + vpaddb %xmm2,%xmm1,%xmm10 + vpaddb %xmm2,%xmm10,%xmm11 + vpaddb %xmm2,%xmm11,%xmm12 + vpaddb %xmm2,%xmm12,%xmm13 + vpaddb %xmm2,%xmm13,%xmm14 + vpxor %xmm15,%xmm1,%xmm9 + vmovdqu %xmm4,16+8(%rsp) + jmp .Loop6x + +.align 32 +.Loop6x: + addl $100663296,%ebx + jc .Lhandle_ctr32 + vmovdqu 0-32(%r9),%xmm3 + vpaddb %xmm2,%xmm14,%xmm1 + vpxor %xmm15,%xmm10,%xmm10 + vpxor %xmm15,%xmm11,%xmm11 + +.Lresume_ctr32: + vmovdqu %xmm1,(%r8) + vpclmulqdq $0x10,%xmm3,%xmm7,%xmm5 + vpxor %xmm15,%xmm12,%xmm12 + vmovups 16-128(%rcx),%xmm2 + vpclmulqdq $0x01,%xmm3,%xmm7,%xmm6 + xorq %r12,%r12 + cmpq %r14,%r15 + + vaesenc %xmm2,%xmm9,%xmm9 + vmovdqu 48+8(%rsp),%xmm0 + vpxor %xmm15,%xmm13,%xmm13 + vpclmulqdq $0x00,%xmm3,%xmm7,%xmm1 + vaesenc %xmm2,%xmm10,%xmm10 + vpxor %xmm15,%xmm14,%xmm14 + setnc %r12b + vpclmulqdq $0x11,%xmm3,%xmm7,%xmm7 + vaesenc %xmm2,%xmm11,%xmm11 + vmovdqu 16-32(%r9),%xmm3 + negq %r12 + vaesenc %xmm2,%xmm12,%xmm12 + vpxor %xmm5,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm3,%xmm0,%xmm5 + vpxor %xmm4,%xmm8,%xmm8 + vaesenc %xmm2,%xmm13,%xmm13 + vpxor %xmm5,%xmm1,%xmm4 + andq $0x60,%r12 + vmovups 32-128(%rcx),%xmm15 + vpclmulqdq $0x10,%xmm3,%xmm0,%xmm1 + vaesenc %xmm2,%xmm14,%xmm14 + + vpclmulqdq $0x01,%xmm3,%xmm0,%xmm2 + leaq (%r14,%r12,1),%r14 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor 16+8(%rsp),%xmm8,%xmm8 + vpclmulqdq $0x11,%xmm3,%xmm0,%xmm3 + vmovdqu 64+8(%rsp),%xmm0 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 88(%r14),%r13 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 80(%r14),%r12 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,32+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,40+8(%rsp) + vmovdqu 48-32(%r9),%xmm5 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 48-128(%rcx),%xmm15 + vpxor %xmm1,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm5,%xmm0,%xmm1 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm2,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm5,%xmm0,%xmm2 + vaesenc %xmm15,%xmm10,%xmm10 + vpxor %xmm3,%xmm7,%xmm7 + vpclmulqdq $0x01,%xmm5,%xmm0,%xmm3 + vaesenc %xmm15,%xmm11,%xmm11 + vpclmulqdq $0x11,%xmm5,%xmm0,%xmm5 + vmovdqu 80+8(%rsp),%xmm0 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqu 64-32(%r9),%xmm1 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 64-128(%rcx),%xmm15 + vpxor %xmm2,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm1,%xmm0,%xmm2 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm3,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm1,%xmm0,%xmm3 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 72(%r14),%r13 + vpxor %xmm5,%xmm7,%xmm7 + vpclmulqdq $0x01,%xmm1,%xmm0,%xmm5 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 64(%r14),%r12 + vpclmulqdq $0x11,%xmm1,%xmm0,%xmm1 + vmovdqu 96+8(%rsp),%xmm0 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,48+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,56+8(%rsp) + vpxor %xmm2,%xmm4,%xmm4 + vmovdqu 96-32(%r9),%xmm2 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 80-128(%rcx),%xmm15 + vpxor %xmm3,%xmm6,%xmm6 + vpclmulqdq $0x00,%xmm2,%xmm0,%xmm3 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm5,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm2,%xmm0,%xmm5 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 56(%r14),%r13 + vpxor %xmm1,%xmm7,%xmm7 + vpclmulqdq $0x01,%xmm2,%xmm0,%xmm1 + vpxor 112+8(%rsp),%xmm8,%xmm8 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 48(%r14),%r12 + vpclmulqdq $0x11,%xmm2,%xmm0,%xmm2 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,64+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,72+8(%rsp) + vpxor %xmm3,%xmm4,%xmm4 + vmovdqu 112-32(%r9),%xmm3 + vaesenc %xmm15,%xmm14,%xmm14 + + vmovups 96-128(%rcx),%xmm15 + vpxor %xmm5,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm3,%xmm8,%xmm5 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm1,%xmm6,%xmm6 + vpclmulqdq $0x01,%xmm3,%xmm8,%xmm1 + vaesenc %xmm15,%xmm10,%xmm10 + movbeq 40(%r14),%r13 + vpxor %xmm2,%xmm7,%xmm7 + vpclmulqdq $0x00,%xmm3,%xmm8,%xmm2 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 32(%r14),%r12 + vpclmulqdq $0x11,%xmm3,%xmm8,%xmm8 + vaesenc %xmm15,%xmm12,%xmm12 + movq %r13,80+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + movq %r12,88+8(%rsp) + vpxor %xmm5,%xmm6,%xmm6 + vaesenc %xmm15,%xmm14,%xmm14 + vpxor %xmm1,%xmm6,%xmm6 + + vmovups 112-128(%rcx),%xmm15 + vpslldq $8,%xmm6,%xmm5 + vpxor %xmm2,%xmm4,%xmm4 + vmovdqu 16(%r11),%xmm3 + + vaesenc %xmm15,%xmm9,%xmm9 + vpxor %xmm8,%xmm7,%xmm7 + vaesenc %xmm15,%xmm10,%xmm10 + vpxor %xmm5,%xmm4,%xmm4 + movbeq 24(%r14),%r13 + vaesenc %xmm15,%xmm11,%xmm11 + movbeq 16(%r14),%r12 + vpalignr $8,%xmm4,%xmm4,%xmm0 + vpclmulqdq $0x10,%xmm3,%xmm4,%xmm4 + movq %r13,96+8(%rsp) + vaesenc %xmm15,%xmm12,%xmm12 + movq %r12,104+8(%rsp) + vaesenc %xmm15,%xmm13,%xmm13 + vmovups 128-128(%rcx),%xmm1 + vaesenc %xmm15,%xmm14,%xmm14 + + vaesenc %xmm1,%xmm9,%xmm9 + vmovups 144-128(%rcx),%xmm15 + vaesenc %xmm1,%xmm10,%xmm10 + vpsrldq $8,%xmm6,%xmm6 + vaesenc %xmm1,%xmm11,%xmm11 + vpxor %xmm6,%xmm7,%xmm7 + vaesenc %xmm1,%xmm12,%xmm12 + vpxor %xmm0,%xmm4,%xmm4 + movbeq 8(%r14),%r13 + vaesenc %xmm1,%xmm13,%xmm13 + movbeq 0(%r14),%r12 + vaesenc %xmm1,%xmm14,%xmm14 + vmovups 160-128(%rcx),%xmm1 + cmpl $11,%ebp + jb .Lenc_tail + + vaesenc %xmm15,%xmm9,%xmm9 + vaesenc %xmm15,%xmm10,%xmm10 + vaesenc %xmm15,%xmm11,%xmm11 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vaesenc %xmm15,%xmm14,%xmm14 + + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + vmovups 176-128(%rcx),%xmm15 + vaesenc %xmm1,%xmm14,%xmm14 + vmovups 192-128(%rcx),%xmm1 + je .Lenc_tail + + vaesenc %xmm15,%xmm9,%xmm9 + vaesenc %xmm15,%xmm10,%xmm10 + vaesenc %xmm15,%xmm11,%xmm11 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vaesenc %xmm15,%xmm14,%xmm14 + + vaesenc %xmm1,%xmm9,%xmm9 + vaesenc %xmm1,%xmm10,%xmm10 + vaesenc %xmm1,%xmm11,%xmm11 + vaesenc %xmm1,%xmm12,%xmm12 + vaesenc %xmm1,%xmm13,%xmm13 + vmovups 208-128(%rcx),%xmm15 + vaesenc %xmm1,%xmm14,%xmm14 + vmovups 224-128(%rcx),%xmm1 + jmp .Lenc_tail + +.align 32 +.Lhandle_ctr32: + vmovdqu (%r11),%xmm0 + vpshufb %xmm0,%xmm1,%xmm6 + vmovdqu 48(%r11),%xmm5 + vpaddd 64(%r11),%xmm6,%xmm10 + vpaddd %xmm5,%xmm6,%xmm11 + vmovdqu 0-32(%r9),%xmm3 + vpaddd %xmm5,%xmm10,%xmm12 + vpshufb %xmm0,%xmm10,%xmm10 + vpaddd %xmm5,%xmm11,%xmm13 + vpshufb %xmm0,%xmm11,%xmm11 + vpxor %xmm15,%xmm10,%xmm10 + vpaddd %xmm5,%xmm12,%xmm14 + vpshufb %xmm0,%xmm12,%xmm12 + vpxor %xmm15,%xmm11,%xmm11 + vpaddd %xmm5,%xmm13,%xmm1 + vpshufb %xmm0,%xmm13,%xmm13 + vpshufb %xmm0,%xmm14,%xmm14 + vpshufb %xmm0,%xmm1,%xmm1 + jmp .Lresume_ctr32 + +.align 32 +.Lenc_tail: + vaesenc %xmm15,%xmm9,%xmm9 + vmovdqu %xmm7,16+8(%rsp) + vpalignr $8,%xmm4,%xmm4,%xmm8 + vaesenc %xmm15,%xmm10,%xmm10 + vpclmulqdq $0x10,%xmm3,%xmm4,%xmm4 + vpxor 0(%rdi),%xmm1,%xmm2 + vaesenc %xmm15,%xmm11,%xmm11 + vpxor 16(%rdi),%xmm1,%xmm0 + vaesenc %xmm15,%xmm12,%xmm12 + vpxor 32(%rdi),%xmm1,%xmm5 + vaesenc %xmm15,%xmm13,%xmm13 + vpxor 48(%rdi),%xmm1,%xmm6 + vaesenc %xmm15,%xmm14,%xmm14 + vpxor 64(%rdi),%xmm1,%xmm7 + vpxor 80(%rdi),%xmm1,%xmm3 + vmovdqu (%r8),%xmm1 + + vaesenclast %xmm2,%xmm9,%xmm9 + vmovdqu 32(%r11),%xmm2 + vaesenclast %xmm0,%xmm10,%xmm10 + vpaddb %xmm2,%xmm1,%xmm0 + movq %r13,112+8(%rsp) + leaq 96(%rdi),%rdi + vaesenclast %xmm5,%xmm11,%xmm11 + vpaddb %xmm2,%xmm0,%xmm5 + movq %r12,120+8(%rsp) + leaq 96(%rsi),%rsi + vmovdqu 0-128(%rcx),%xmm15 + vaesenclast %xmm6,%xmm12,%xmm12 + vpaddb %xmm2,%xmm5,%xmm6 + vaesenclast %xmm7,%xmm13,%xmm13 + vpaddb %xmm2,%xmm6,%xmm7 + vaesenclast %xmm3,%xmm14,%xmm14 + vpaddb %xmm2,%xmm7,%xmm3 + + addq $0x60,%r10 + subq $0x6,%rdx + jc .L6x_done + + vmovups %xmm9,-96(%rsi) + vpxor %xmm15,%xmm1,%xmm9 + vmovups %xmm10,-80(%rsi) + vmovdqa %xmm0,%xmm10 + vmovups %xmm11,-64(%rsi) + vmovdqa %xmm5,%xmm11 + vmovups %xmm12,-48(%rsi) + vmovdqa %xmm6,%xmm12 + vmovups %xmm13,-32(%rsi) + vmovdqa %xmm7,%xmm13 + vmovups %xmm14,-16(%rsi) + vmovdqa %xmm3,%xmm14 + vmovdqu 32+8(%rsp),%xmm7 + jmp .Loop6x + +.L6x_done: + vpxor 16+8(%rsp),%xmm8,%xmm8 + vpxor %xmm4,%xmm8,%xmm8 + + .byte 0xf3,0xc3 +.cfi_endproc +.size _aesni_ctr32_ghash_6x,.-_aesni_ctr32_ghash_6x +.globl aesni_gcm_decrypt +.type aesni_gcm_decrypt,@function +.align 32 +aesni_gcm_decrypt: +.cfi_startproc + xorq %r10,%r10 + cmpq $0x60,%rdx + jb .Lgcm_dec_abort + + leaq (%rsp),%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + vzeroupper + + vmovdqu (%r8),%xmm1 + addq $-128,%rsp + movl 12(%r8),%ebx + leaq .Lbswap_mask(%rip),%r11 + leaq -128(%rcx),%r14 + movq $0xf80,%r15 + vmovdqu (%r9),%xmm8 + andq $-128,%rsp + vmovdqu (%r11),%xmm0 + leaq 128(%rcx),%rcx + leaq 32+32(%r9),%r9 + movl 240-128(%rcx),%ebp + vpshufb %xmm0,%xmm8,%xmm8 + + andq %r15,%r14 + andq %rsp,%r15 + subq %r14,%r15 + jc .Ldec_no_key_aliasing + cmpq $768,%r15 + jnc .Ldec_no_key_aliasing + subq %r15,%rsp +.Ldec_no_key_aliasing: + + vmovdqu 80(%rdi),%xmm7 + leaq (%rdi),%r14 + vmovdqu 64(%rdi),%xmm4 + leaq -192(%rdi,%rdx,1),%r15 + vmovdqu 48(%rdi),%xmm5 + shrq $4,%rdx + xorq %r10,%r10 + vmovdqu 32(%rdi),%xmm6 + vpshufb %xmm0,%xmm7,%xmm7 + vmovdqu 16(%rdi),%xmm2 + vpshufb %xmm0,%xmm4,%xmm4 + vmovdqu (%rdi),%xmm3 + vpshufb %xmm0,%xmm5,%xmm5 + vmovdqu %xmm4,48(%rsp) + vpshufb %xmm0,%xmm6,%xmm6 + vmovdqu %xmm5,64(%rsp) + vpshufb %xmm0,%xmm2,%xmm2 + vmovdqu %xmm6,80(%rsp) + vpshufb %xmm0,%xmm3,%xmm3 + vmovdqu %xmm2,96(%rsp) + vmovdqu %xmm3,112(%rsp) + + call _aesni_ctr32_ghash_6x + + vmovups %xmm9,-96(%rsi) + vmovups %xmm10,-80(%rsi) + vmovups %xmm11,-64(%rsi) + vmovups %xmm12,-48(%rsi) + vmovups %xmm13,-32(%rsi) + vmovups %xmm14,-16(%rsi) + + vpshufb (%r11),%xmm8,%xmm8 + vmovdqu %xmm8,-64(%r9) + + vzeroupper + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lgcm_dec_abort: + movq %r10,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_gcm_decrypt,.-aesni_gcm_decrypt +.type _aesni_ctr32_6x,@function +.align 32 +_aesni_ctr32_6x: +.cfi_startproc + vmovdqu 0-128(%rcx),%xmm4 + vmovdqu 32(%r11),%xmm2 + leaq -1(%rbp),%r13 + vmovups 16-128(%rcx),%xmm15 + leaq 32-128(%rcx),%r12 + vpxor %xmm4,%xmm1,%xmm9 + addl $100663296,%ebx + jc .Lhandle_ctr32_2 + vpaddb %xmm2,%xmm1,%xmm10 + vpaddb %xmm2,%xmm10,%xmm11 + vpxor %xmm4,%xmm10,%xmm10 + vpaddb %xmm2,%xmm11,%xmm12 + vpxor %xmm4,%xmm11,%xmm11 + vpaddb %xmm2,%xmm12,%xmm13 + vpxor %xmm4,%xmm12,%xmm12 + vpaddb %xmm2,%xmm13,%xmm14 + vpxor %xmm4,%xmm13,%xmm13 + vpaddb %xmm2,%xmm14,%xmm1 + vpxor %xmm4,%xmm14,%xmm14 + jmp .Loop_ctr32 + +.align 16 +.Loop_ctr32: + vaesenc %xmm15,%xmm9,%xmm9 + vaesenc %xmm15,%xmm10,%xmm10 + vaesenc %xmm15,%xmm11,%xmm11 + vaesenc %xmm15,%xmm12,%xmm12 + vaesenc %xmm15,%xmm13,%xmm13 + vaesenc %xmm15,%xmm14,%xmm14 + vmovups (%r12),%xmm15 + leaq 16(%r12),%r12 + decl %r13d + jnz .Loop_ctr32 + + vmovdqu (%r12),%xmm3 + vaesenc %xmm15,%xmm9,%xmm9 + vpxor 0(%rdi),%xmm3,%xmm4 + vaesenc %xmm15,%xmm10,%xmm10 + vpxor 16(%rdi),%xmm3,%xmm5 + vaesenc %xmm15,%xmm11,%xmm11 + vpxor 32(%rdi),%xmm3,%xmm6 + vaesenc %xmm15,%xmm12,%xmm12 + vpxor 48(%rdi),%xmm3,%xmm8 + vaesenc %xmm15,%xmm13,%xmm13 + vpxor 64(%rdi),%xmm3,%xmm2 + vaesenc %xmm15,%xmm14,%xmm14 + vpxor 80(%rdi),%xmm3,%xmm3 + leaq 96(%rdi),%rdi + + vaesenclast %xmm4,%xmm9,%xmm9 + vaesenclast %xmm5,%xmm10,%xmm10 + vaesenclast %xmm6,%xmm11,%xmm11 + vaesenclast %xmm8,%xmm12,%xmm12 + vaesenclast %xmm2,%xmm13,%xmm13 + vaesenclast %xmm3,%xmm14,%xmm14 + vmovups %xmm9,0(%rsi) + vmovups %xmm10,16(%rsi) + vmovups %xmm11,32(%rsi) + vmovups %xmm12,48(%rsi) + vmovups %xmm13,64(%rsi) + vmovups %xmm14,80(%rsi) + leaq 96(%rsi),%rsi + + .byte 0xf3,0xc3 +.align 32 +.Lhandle_ctr32_2: + vpshufb %xmm0,%xmm1,%xmm6 + vmovdqu 48(%r11),%xmm5 + vpaddd 64(%r11),%xmm6,%xmm10 + vpaddd %xmm5,%xmm6,%xmm11 + vpaddd %xmm5,%xmm10,%xmm12 + vpshufb %xmm0,%xmm10,%xmm10 + vpaddd %xmm5,%xmm11,%xmm13 + vpshufb %xmm0,%xmm11,%xmm11 + vpxor %xmm4,%xmm10,%xmm10 + vpaddd %xmm5,%xmm12,%xmm14 + vpshufb %xmm0,%xmm12,%xmm12 + vpxor %xmm4,%xmm11,%xmm11 + vpaddd %xmm5,%xmm13,%xmm1 + vpshufb %xmm0,%xmm13,%xmm13 + vpxor %xmm4,%xmm12,%xmm12 + vpshufb %xmm0,%xmm14,%xmm14 + vpxor %xmm4,%xmm13,%xmm13 + vpshufb %xmm0,%xmm1,%xmm1 + vpxor %xmm4,%xmm14,%xmm14 + jmp .Loop_ctr32 +.cfi_endproc +.size _aesni_ctr32_6x,.-_aesni_ctr32_6x + +.globl aesni_gcm_encrypt +.type aesni_gcm_encrypt,@function +.align 32 +aesni_gcm_encrypt: +.cfi_startproc + xorq %r10,%r10 + cmpq $288,%rdx + jb .Lgcm_enc_abort + + leaq (%rsp),%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + vzeroupper + + vmovdqu (%r8),%xmm1 + addq $-128,%rsp + movl 12(%r8),%ebx + leaq .Lbswap_mask(%rip),%r11 + leaq -128(%rcx),%r14 + movq $0xf80,%r15 + leaq 128(%rcx),%rcx + vmovdqu (%r11),%xmm0 + andq $-128,%rsp + movl 240-128(%rcx),%ebp + + andq %r15,%r14 + andq %rsp,%r15 + subq %r14,%r15 + jc .Lenc_no_key_aliasing + cmpq $768,%r15 + jnc .Lenc_no_key_aliasing + subq %r15,%rsp +.Lenc_no_key_aliasing: + + leaq (%rsi),%r14 + leaq -192(%rsi,%rdx,1),%r15 + shrq $4,%rdx + + call _aesni_ctr32_6x + vpshufb %xmm0,%xmm9,%xmm8 + vpshufb %xmm0,%xmm10,%xmm2 + vmovdqu %xmm8,112(%rsp) + vpshufb %xmm0,%xmm11,%xmm4 + vmovdqu %xmm2,96(%rsp) + vpshufb %xmm0,%xmm12,%xmm5 + vmovdqu %xmm4,80(%rsp) + vpshufb %xmm0,%xmm13,%xmm6 + vmovdqu %xmm5,64(%rsp) + vpshufb %xmm0,%xmm14,%xmm7 + vmovdqu %xmm6,48(%rsp) + + call _aesni_ctr32_6x + + vmovdqu (%r9),%xmm8 + leaq 32+32(%r9),%r9 + subq $12,%rdx + movq $192,%r10 + vpshufb %xmm0,%xmm8,%xmm8 + + call _aesni_ctr32_ghash_6x + vmovdqu 32(%rsp),%xmm7 + vmovdqu (%r11),%xmm0 + vmovdqu 0-32(%r9),%xmm3 + vpunpckhqdq %xmm7,%xmm7,%xmm1 + vmovdqu 32-32(%r9),%xmm15 + vmovups %xmm9,-96(%rsi) + vpshufb %xmm0,%xmm9,%xmm9 + vpxor %xmm7,%xmm1,%xmm1 + vmovups %xmm10,-80(%rsi) + vpshufb %xmm0,%xmm10,%xmm10 + vmovups %xmm11,-64(%rsi) + vpshufb %xmm0,%xmm11,%xmm11 + vmovups %xmm12,-48(%rsi) + vpshufb %xmm0,%xmm12,%xmm12 + vmovups %xmm13,-32(%rsi) + vpshufb %xmm0,%xmm13,%xmm13 + vmovups %xmm14,-16(%rsi) + vpshufb %xmm0,%xmm14,%xmm14 + vmovdqu %xmm9,16(%rsp) + vmovdqu 48(%rsp),%xmm6 + vmovdqu 16-32(%r9),%xmm0 + vpunpckhqdq %xmm6,%xmm6,%xmm2 + vpclmulqdq $0x00,%xmm3,%xmm7,%xmm5 + vpxor %xmm6,%xmm2,%xmm2 + vpclmulqdq $0x11,%xmm3,%xmm7,%xmm7 + vpclmulqdq $0x00,%xmm15,%xmm1,%xmm1 + + vmovdqu 64(%rsp),%xmm9 + vpclmulqdq $0x00,%xmm0,%xmm6,%xmm4 + vmovdqu 48-32(%r9),%xmm3 + vpxor %xmm5,%xmm4,%xmm4 + vpunpckhqdq %xmm9,%xmm9,%xmm5 + vpclmulqdq $0x11,%xmm0,%xmm6,%xmm6 + vpxor %xmm9,%xmm5,%xmm5 + vpxor %xmm7,%xmm6,%xmm6 + vpclmulqdq $0x10,%xmm15,%xmm2,%xmm2 + vmovdqu 80-32(%r9),%xmm15 + vpxor %xmm1,%xmm2,%xmm2 + + vmovdqu 80(%rsp),%xmm1 + vpclmulqdq $0x00,%xmm3,%xmm9,%xmm7 + vmovdqu 64-32(%r9),%xmm0 + vpxor %xmm4,%xmm7,%xmm7 + vpunpckhqdq %xmm1,%xmm1,%xmm4 + vpclmulqdq $0x11,%xmm3,%xmm9,%xmm9 + vpxor %xmm1,%xmm4,%xmm4 + vpxor %xmm6,%xmm9,%xmm9 + vpclmulqdq $0x00,%xmm15,%xmm5,%xmm5 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu 96(%rsp),%xmm2 + vpclmulqdq $0x00,%xmm0,%xmm1,%xmm6 + vmovdqu 96-32(%r9),%xmm3 + vpxor %xmm7,%xmm6,%xmm6 + vpunpckhqdq %xmm2,%xmm2,%xmm7 + vpclmulqdq $0x11,%xmm0,%xmm1,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpxor %xmm9,%xmm1,%xmm1 + vpclmulqdq $0x10,%xmm15,%xmm4,%xmm4 + vmovdqu 128-32(%r9),%xmm15 + vpxor %xmm5,%xmm4,%xmm4 + + vpxor 112(%rsp),%xmm8,%xmm8 + vpclmulqdq $0x00,%xmm3,%xmm2,%xmm5 + vmovdqu 112-32(%r9),%xmm0 + vpunpckhqdq %xmm8,%xmm8,%xmm9 + vpxor %xmm6,%xmm5,%xmm5 + vpclmulqdq $0x11,%xmm3,%xmm2,%xmm2 + vpxor %xmm8,%xmm9,%xmm9 + vpxor %xmm1,%xmm2,%xmm2 + vpclmulqdq $0x00,%xmm15,%xmm7,%xmm7 + vpxor %xmm4,%xmm7,%xmm4 + + vpclmulqdq $0x00,%xmm0,%xmm8,%xmm6 + vmovdqu 0-32(%r9),%xmm3 + vpunpckhqdq %xmm14,%xmm14,%xmm1 + vpclmulqdq $0x11,%xmm0,%xmm8,%xmm8 + vpxor %xmm14,%xmm1,%xmm1 + vpxor %xmm5,%xmm6,%xmm5 + vpclmulqdq $0x10,%xmm15,%xmm9,%xmm9 + vmovdqu 32-32(%r9),%xmm15 + vpxor %xmm2,%xmm8,%xmm7 + vpxor %xmm4,%xmm9,%xmm6 + + vmovdqu 16-32(%r9),%xmm0 + vpxor %xmm5,%xmm7,%xmm9 + vpclmulqdq $0x00,%xmm3,%xmm14,%xmm4 + vpxor %xmm9,%xmm6,%xmm6 + vpunpckhqdq %xmm13,%xmm13,%xmm2 + vpclmulqdq $0x11,%xmm3,%xmm14,%xmm14 + vpxor %xmm13,%xmm2,%xmm2 + vpslldq $8,%xmm6,%xmm9 + vpclmulqdq $0x00,%xmm15,%xmm1,%xmm1 + vpxor %xmm9,%xmm5,%xmm8 + vpsrldq $8,%xmm6,%xmm6 + vpxor %xmm6,%xmm7,%xmm7 + + vpclmulqdq $0x00,%xmm0,%xmm13,%xmm5 + vmovdqu 48-32(%r9),%xmm3 + vpxor %xmm4,%xmm5,%xmm5 + vpunpckhqdq %xmm12,%xmm12,%xmm9 + vpclmulqdq $0x11,%xmm0,%xmm13,%xmm13 + vpxor %xmm12,%xmm9,%xmm9 + vpxor %xmm14,%xmm13,%xmm13 + vpalignr $8,%xmm8,%xmm8,%xmm14 + vpclmulqdq $0x10,%xmm15,%xmm2,%xmm2 + vmovdqu 80-32(%r9),%xmm15 + vpxor %xmm1,%xmm2,%xmm2 + + vpclmulqdq $0x00,%xmm3,%xmm12,%xmm4 + vmovdqu 64-32(%r9),%xmm0 + vpxor %xmm5,%xmm4,%xmm4 + vpunpckhqdq %xmm11,%xmm11,%xmm1 + vpclmulqdq $0x11,%xmm3,%xmm12,%xmm12 + vpxor %xmm11,%xmm1,%xmm1 + vpxor %xmm13,%xmm12,%xmm12 + vxorps 16(%rsp),%xmm7,%xmm7 + vpclmulqdq $0x00,%xmm15,%xmm9,%xmm9 + vpxor %xmm2,%xmm9,%xmm9 + + vpclmulqdq $0x10,16(%r11),%xmm8,%xmm8 + vxorps %xmm14,%xmm8,%xmm8 + + vpclmulqdq $0x00,%xmm0,%xmm11,%xmm5 + vmovdqu 96-32(%r9),%xmm3 + vpxor %xmm4,%xmm5,%xmm5 + vpunpckhqdq %xmm10,%xmm10,%xmm2 + vpclmulqdq $0x11,%xmm0,%xmm11,%xmm11 + vpxor %xmm10,%xmm2,%xmm2 + vpalignr $8,%xmm8,%xmm8,%xmm14 + vpxor %xmm12,%xmm11,%xmm11 + vpclmulqdq $0x10,%xmm15,%xmm1,%xmm1 + vmovdqu 128-32(%r9),%xmm15 + vpxor %xmm9,%xmm1,%xmm1 + + vxorps %xmm7,%xmm14,%xmm14 + vpclmulqdq $0x10,16(%r11),%xmm8,%xmm8 + vxorps %xmm14,%xmm8,%xmm8 + + vpclmulqdq $0x00,%xmm3,%xmm10,%xmm4 + vmovdqu 112-32(%r9),%xmm0 + vpxor %xmm5,%xmm4,%xmm4 + vpunpckhqdq %xmm8,%xmm8,%xmm9 + vpclmulqdq $0x11,%xmm3,%xmm10,%xmm10 + vpxor %xmm8,%xmm9,%xmm9 + vpxor %xmm11,%xmm10,%xmm10 + vpclmulqdq $0x00,%xmm15,%xmm2,%xmm2 + vpxor %xmm1,%xmm2,%xmm2 + + vpclmulqdq $0x00,%xmm0,%xmm8,%xmm5 + vpclmulqdq $0x11,%xmm0,%xmm8,%xmm7 + vpxor %xmm4,%xmm5,%xmm5 + vpclmulqdq $0x10,%xmm15,%xmm9,%xmm6 + vpxor %xmm10,%xmm7,%xmm7 + vpxor %xmm2,%xmm6,%xmm6 + + vpxor %xmm5,%xmm7,%xmm4 + vpxor %xmm4,%xmm6,%xmm6 + vpslldq $8,%xmm6,%xmm1 + vmovdqu 16(%r11),%xmm3 + vpsrldq $8,%xmm6,%xmm6 + vpxor %xmm1,%xmm5,%xmm8 + vpxor %xmm6,%xmm7,%xmm7 + + vpalignr $8,%xmm8,%xmm8,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm8,%xmm8 + vpxor %xmm2,%xmm8,%xmm8 + + vpalignr $8,%xmm8,%xmm8,%xmm2 + vpclmulqdq $0x10,%xmm3,%xmm8,%xmm8 + vpxor %xmm7,%xmm2,%xmm2 + vpxor %xmm2,%xmm8,%xmm8 + vpshufb (%r11),%xmm8,%xmm8 + vmovdqu %xmm8,-64(%r9) + + vzeroupper + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lgcm_enc_abort: + movq %r10,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size aesni_gcm_encrypt,.-aesni_gcm_encrypt +.align 64 +.Lbswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.Lpoly: +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 +.Lone_msb: +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 +.Ltwo_lsb: +.byte 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.Lone_lsb: +.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.byte 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/modes/asm/aes-gcm-armv8_64.pl b/crypto/openssl/crypto/modes/asm/aes-gcm-armv8_64.pl new file mode 100755 index 000000000000..3b9d5b651193 --- /dev/null +++ b/crypto/openssl/crypto/modes/asm/aes-gcm-armv8_64.pl @@ -0,0 +1,5722 @@ +#! /usr/bin/env perl +# Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# +#======================================================================== +# Written by Fangming Fang for the OpenSSL project, +# derived from https://github.com/ARM-software/AArch64cryptolib, original +# author Samuel Lee . 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/. +#======================================================================== +# +# Approach - assume we don't want to reload constants, so reserve ~half of vector register file for constants +# +# main loop to act on 4 16B blocks per iteration, and then do modulo of the accumulated intermediate hashes from the 4 blocks +# +# ____________________________________________________ +# | | +# | PRE | +# |____________________________________________________| +# | | | | +# | CTR block 4k+8 | AES block 4k+4 | GHASH block 4k+0 | +# |________________|________________|__________________| +# | | | | +# | CTR block 4k+9 | AES block 4k+5 | GHASH block 4k+1 | +# |________________|________________|__________________| +# | | | | +# | CTR block 4k+10| AES block 4k+6 | GHASH block 4k+2 | +# |________________|________________|__________________| +# | | | | +# | CTR block 4k+11| AES block 4k+7 | GHASH block 4k+3 | +# |________________|____(mostly)____|__________________| +# | | +# | MODULO | +# |____________________________________________________| +# +# PRE: +# Ensure previous generated intermediate hash is aligned and merged with result for GHASH 4k+0 +# EXT low_acc, low_acc, low_acc, #8 +# EOR res_curr (4k+0), res_curr (4k+0), low_acc +# +# CTR block: +# Increment and byte reverse counter in scalar registers and transfer to SIMD registers +# REV ctr32, rev_ctr32 +# ORR ctr64, constctr96_top32, ctr32, LSL #32 +# INS ctr_next.d[0], constctr96_bottom64 // Keeping this in scalar registers to free up space in SIMD RF +# INS ctr_next.d[1], ctr64X +# ADD rev_ctr32, #1 +# +# AES block: +# Do AES encryption/decryption on CTR block X and EOR it with input block X. Take 256 bytes key below for example. +# Doing small trick here of loading input in scalar registers, EORing with last key and then transferring +# Given we are very constrained in our ASIMD registers this is quite important +# +# Encrypt: +# LDR input_low, [ input_ptr ], #8 +# LDR input_high, [ input_ptr ], #8 +# EOR input_low, k14_low +# EOR input_high, k14_high +# INS res_curr.d[0], input_low +# INS res_curr.d[1], input_high +# AESE ctr_curr, k0; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k1; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k2; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k3; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k4; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k5; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k6; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k7; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k8; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k9; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k10; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k11; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k12; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k13 +# EOR res_curr, res_curr, ctr_curr +# ST1 { res_curr.16b }, [ output_ptr ], #16 +# +# Decrypt: +# AESE ctr_curr, k0; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k1; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k2; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k3; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k4; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k5; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k6; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k7; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k8; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k9; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k10; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k11; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k12; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k13 +# LDR res_curr, [ input_ptr ], #16 +# EOR res_curr, res_curr, ctr_curr +# MOV output_low, res_curr.d[0] +# MOV output_high, res_curr.d[1] +# EOR output_low, k14_low +# EOR output_high, k14_high +# STP output_low, output_high, [ output_ptr ], #16 +# +# GHASH block X: +# do 128b karatsuba polynomial multiplication on block +# We only have 64b->128b polynomial multipliers, naively that means we need to do 4 64b multiplies to generate a 128b +# +# multiplication: +# Pmull(A,B) == (Pmull(Ah,Bh)<<128 | Pmull(Al,Bl)) ^ (Pmull(Ah,Bl) ^ Pmull(Al,Bh))<<64 +# +# The idea behind Karatsuba multiplication is that we can do just 3 64b multiplies: +# Pmull(A,B) == (Pmull(Ah,Bh)<<128 | Pmull(Al,Bl)) ^ (Pmull(Ah^Al,Bh^Bl) ^ Pmull(Ah,Bh) ^ Pmull(Al,Bl))<<64 +# +# There is some complication here because the bit order of GHASH's PMULL is reversed compared to elsewhere, so we are +# multiplying with "twisted" powers of H +# +# Note: We can PMULL directly into the acc_x in first GHASH of the loop +# Note: For scheduling big cores we want to split the processing to happen over two loop iterations - otherwise the critical +# path latency dominates the performance +# +# This has a knock on effect on register pressure, so we have to be a bit more clever with our temporary registers +# than indicated here +# REV64 res_curr, res_curr +# INS t_m.d[0], res_curr.d[1] +# EOR t_m.8B, t_m.8B, res_curr.8B +# PMULL2 t_h, res_curr, HX +# PMULL t_l, res_curr, HX +# PMULL t_m, t_m, HX_k +# EOR acc_h, acc_h, t_h +# EOR acc_l, acc_l, t_l +# EOR acc_m, acc_m, t_m +# +# MODULO: take the partial accumulators (~representing sum of 256b multiplication results), from GHASH and do modulo reduction on them +# There is some complication here because the bit order of GHASH's PMULL is reversed compared to elsewhere, so we are doing modulo +# with a reversed constant +# EOR acc_m, acc_m, acc_h +# EOR acc_m, acc_m, acc_l // Finish off karatsuba processing +# PMULL t_mod, acc_h, mod_constant +# EXT acc_h, acc_h, acc_h, #8 +# EOR acc_m, acc_m, acc_h +# EOR acc_m, acc_m, t_mod +# PMULL acc_h, acc_m, mod_constant +# EXT acc_m, acc_m, acc_m, #8 +# EOR acc_l, acc_l, acc_h +# EOR acc_l, acc_l, acc_m + +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate ) or +die "can't locate arm-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +$input_ptr="x0"; #argument block +$bit_length="x1"; +$output_ptr="x2"; +$current_tag="x3"; +$counter="x16"; +$cc="x8"; + +{ +my ($end_input_ptr,$main_end_input_ptr,$input_l0,$input_h0)=map("x$_",(4..7)); +my ($input_l1,$input_h1,$input_l2,$input_h2,$input_l3,$input_h3)=map("x$_",(19..24)); +my ($output_l1,$output_h1,$output_l2,$output_h2,$output_l3,$output_h3)=map("x$_",(19..24)); +my ($output_l0,$output_h0)=map("x$_",(6..7)); + +my $ctr32w="w9"; +my ($ctr32x,$ctr96_b64x,$ctr96_t32x,$rctr32x,$rk10_l,$rk10_h,$len)=map("x$_",(9..15)); +my ($ctr96_t32w,$rctr32w)=map("w$_",(11..12)); + +my ($ctr0b,$ctr1b,$ctr2b,$ctr3b,$res0b,$res1b,$res2b,$res3b)=map("v$_.16b",(0..7)); +my ($ctr0,$ctr1,$ctr2,$ctr3,$res0,$res1,$res2,$res3)=map("v$_",(0..7)); +my ($ctr0d,$ctr1d,$ctr2d,$ctr3d,$res0d,$res1d,$res2d,$res3d)=map("d$_",(0..7)); +my ($res0q,$res1q,$res2q,$res3q)=map("q$_",(4..7)); + +my ($acc_hb,$acc_mb,$acc_lb)=map("v$_.16b",(9..11)); +my ($acc_h,$acc_m,$acc_l)=map("v$_",(9..11)); +my ($acc_hd,$acc_md,$acc_ld)=map("d$_",(9..11)); + +my ($h1,$h2,$h3,$h4,$h12k,$h34k)=map("v$_",(12..17)); +my ($h1q,$h2q,$h3q,$h4q)=map("q$_",(12..15)); +my ($h1b,$h2b,$h3b,$h4b)=map("v$_.16b",(12..15)); + +my $t0="v8"; +my $t0d="d8"; + +my ($t1,$t2,$t3)=map("v$_",(28..30)); +my ($t1d,$t2d,$t3d)=map("d$_",(28..30)); + +my $t4="v8"; +my $t4d="d8"; +my $t5="v28"; +my $t5d="d28"; +my $t6="v31"; +my $t6d="d31"; + +my $t7="v4"; +my $t7d="d4"; +my $t8="v29"; +my $t8d="d29"; +my $t9="v30"; +my $t9d="d30"; + +my ($ctr_t0,$ctr_t1,$ctr_t2,$ctr_t3)=map("v$_",(4..7)); +my ($ctr_t0d,$ctr_t1d,$ctr_t2d,$ctr_t3d)=map("d$_",(4..7)); +my ($ctr_t0b,$ctr_t1b,$ctr_t2b,$ctr_t3b)=map("v$_.16b",(4..7)); + +my $mod_constantd="d8"; +my $mod_constant="v8"; +my $mod_t="v31"; + +my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7,$rk8,$rk9)=map("v$_.16b",(18..27)); +my ($rk0q,$rk1q,$rk2q,$rk3q,$rk4q,$rk5q,$rk6q,$rk7q,$rk8q,$rk9q)=map("q$_",(18..27)); +my $rk2q1="v20.1q"; +my $rk3q1="v21.1q"; +my $rk4v="v22"; +my $rk4d="d22"; + +$code=<<___; +#include "arm_arch.h" + +#if __ARM_MAX_ARCH__>=8 +___ +$code.=".arch armv8-a+crypto\n.text\n" if ($flavour =~ /64/); +$code.=<<___ if ($flavour !~ /64/); +.fpu neon +#ifdef __thumb2__ +.syntax unified +.thumb +# define INST(a,b,c,d) $_byte c,0xef,a,b +#else +.code 32 +# define INST(a,b,c,d) $_byte a,b,c,0xf2 +#endif + +.text +___ + +######################################################################################### +# size_t aes_gcm_enc_128_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_enc_128_kernel +.type aes_gcm_enc_128_kernel,%function +.align 4 +aes_gcm_enc_128_kernel: + cbz x1, .L128_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + ldp $rk10_l, $rk10_h, [$cc, #160] @ load rk10 + + ld1 {$acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + + ldr $rk9q, [$cc, #144] @ load rk9 + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + + lsr $rctr32x, $ctr96_t32x, #32 + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + rev $rctr32w, $rctr32w @ rev_ctr32 + + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + ldr $rk0q, [$cc, #0] @ load rk0 + + rev $ctr32w, $rctr32w @ CTR block 1 + add $rctr32w, $rctr32w, #1 @ CTR block 1 + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + ldr $rk1q, [$cc, #16] @ load rk1 + + add $rctr32w, $rctr32w, #1 @ CTR block 3 + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $rk2q, [$cc, #32] @ load rk2 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + ldr $rk8q, [$cc, #128] @ load rk8 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + ldr $rk3q, [$cc, #48] @ load rk3 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + ldr $rk6q, [$cc, #96] @ load rk6 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ldr $rk7q, [$cc, #112] @ load rk7 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + ldr $rk5q, [$cc, #80] @ load rk5 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + ldr $rk4q, [$cc, #64] @ load rk4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + + aese $ctr2b, $rk9 @ AES block 2 - round 9 + + aese $ctr0b, $rk9 @ AES block 0 - round 9 + + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + + aese $ctr1b, $rk9 @ AES block 1 - round 9 + + aese $ctr3b, $rk9 @ AES block 3 - round 9 + b.ge .L128_enc_tail @ handle tail + + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 0 - load plaintext + + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 2 - load plaintext + + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 1 - load plaintext + + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 3 - load plaintext + + eor $input_l0, $input_l0, $rk10_l @ AES block 0 - round 10 low + eor $input_h0, $input_h0, $rk10_h @ AES block 0 - round 10 high + + eor $input_l2, $input_l2, $rk10_l @ AES block 2 - round 10 low + fmov $ctr_t0d, $input_l0 @ AES block 0 - mov low + + eor $input_l1, $input_l1, $rk10_l @ AES block 1 - round 10 low + eor $input_h2, $input_h2, $rk10_h @ AES block 2 - round 10 high + fmov $ctr_t0.d[1], $input_h0 @ AES block 0 - mov high + + fmov $ctr_t1d, $input_l1 @ AES block 1 - mov low + eor $input_h1, $input_h1, $rk10_h @ AES block 1 - round 10 high + + eor $input_l3, $input_l3, $rk10_l @ AES block 3 - round 10 low + fmov $ctr_t1.d[1], $input_h1 @ AES block 1 - mov high + + fmov $ctr_t2d, $input_l2 @ AES block 2 - mov low + eor $input_h3, $input_h3, $rk10_h @ AES block 3 - round 10 high + rev $ctr32w, $rctr32w @ CTR block 4 + + fmov $ctr_t2.d[1], $input_h2 @ AES block 2 - mov high + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + + eor $res0b, $ctr_t0b, $ctr0b @ AES block 0 - result + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + add $rctr32w, $rctr32w, #1 @ CTR block 4 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + + eor $res1b, $ctr_t1b, $ctr1b @ AES block 1 - result + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + + add $rctr32w, $rctr32w, #1 @ CTR block 5 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + + fmov $ctr_t3d, $input_l3 @ AES block 3 - mov low + rev $ctr32w, $rctr32w @ CTR block 6 + st1 { $res0b}, [$output_ptr], #16 @ AES block 0 - store result + + fmov $ctr_t3.d[1], $input_h3 @ AES block 3 - mov high + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + + add $rctr32w, $rctr32w, #1 @ CTR block 6 + eor $res2b, $ctr_t2b, $ctr2b @ AES block 2 - result + st1 { $res1b}, [$output_ptr], #16 @ AES block 1 - store result + + fmov $ctr2d, $ctr96_b64x @ CTR block 6 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + + fmov $ctr2.d[1], $ctr32x @ CTR block 6 + rev $ctr32w, $rctr32w @ CTR block 7 + st1 { $res2b}, [$output_ptr], #16 @ AES block 2 - store result + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 7 + + eor $res3b, $ctr_t3b, $ctr3b @ AES block 3 - result + st1 { $res3b}, [$output_ptr], #16 @ AES block 3 - store result + b.ge .L128_enc_prepretail @ do prepretail + + .L128_enc_main_loop: @ main loop start + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 4k+3 - load plaintext + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + eor $res0b, $res0b, $acc_lb @ PRE 1 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $input_h3, $input_h3, $rk10_h @ AES block 4k+3 - round 10 high + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 4k+4 - load plaintext + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + rev $ctr32w, $rctr32w @ CTR block 4k+8 + + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + eor $input_h0, $input_h0, $rk10_h @ AES block 4k+4 - round 10 high + + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + eor $input_l0, $input_l0, $rk10_l @ AES block 4k+4 - round 10 low + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + movi $mod_constant.8b, #0xc2 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 4k+5 - load plaintext + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 4k+6 - load plaintext + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + eor $input_l1, $input_l1, $rk10_l @ AES block 4k+5 - round 10 low + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + eor $input_l3, $input_l3, $rk10_l @ AES block 4k+3 - round 10 low + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + fmov $ctr_t3d, $input_l3 @ AES block 4k+3 - mov low + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + fmov $ctr_t1d, $input_l1 @ AES block 4k+5 - mov low + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + eor $input_h1, $input_h1, $rk10_h @ AES block 4k+5 - round 10 high + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + fmov $ctr_t1.d[1], $input_h1 @ AES block 4k+5 - mov high + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + fmov $ctr_t3.d[1], $input_h3 @ AES block 4k+3 - mov high + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr0b, $rk9 @ AES block 4k+4 - round 9 + eor $input_l2, $input_l2, $rk10_l @ AES block 4k+6 - round 10 low + eor $input_h2, $input_h2, $rk10_h @ AES block 4k+6 - round 10 high + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + fmov $ctr_t2d, $input_l2 @ AES block 4k+6 - mov low + + aese $ctr1b, $rk9 @ AES block 4k+5 - round 9 + fmov $ctr_t2.d[1], $input_h2 @ AES block 4k+6 - mov high + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + eor $res0b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + rev $ctr32w, $rctr32w @ CTR block 4k+9 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + eor $res1b, $ctr_t1b, $ctr1b @ AES block 4k+5 - result + + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + rev $ctr32w, $rctr32w @ CTR block 4k+10 + + aese $ctr2b, $rk9 @ AES block 4k+6 - round 9 + st1 { $res0b}, [$output_ptr], #16 @ AES block 4k+4 - store result + eor $res2b, $ctr_t2b, $ctr2b @ AES block 4k+6 - result + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + + aese $ctr3b, $rk9 @ AES block 4k+7 - round 9 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+10 + + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + st1 { $res1b}, [$output_ptr], #16 @ AES block 4k+5 - store result + + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+10 + st1 { $res2b}, [$output_ptr], #16 @ AES block 4k+6 - store result + rev $ctr32w, $rctr32w @ CTR block 4k+11 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+11 + eor $res3b, $ctr_t3b, $ctr3b @ AES block 4k+3 - result + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + st1 { $res3b}, [$output_ptr], #16 @ AES block 4k+3 - store result + b.lt .L128_enc_main_loop + + .L128_enc_prepretail: @ PREPRETAIL + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + eor $res0b, $res0b, $acc_lb @ PRE 1 + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + movi $mod_constant.8b, #0xc2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + pmull $t1.1q, $acc_h.1d, $mod_constant.1d + eor $acc_mb, $acc_mb, $acc_hb @ karatsuba tidy up + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + ext $acc_hb, $acc_hb, $acc_hb, #8 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + eor $acc_mb, $acc_mb, $acc_lb + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + eor $acc_mb, $acc_mb, $t1.16b + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + eor $acc_mb, $acc_mb, $acc_hb + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + + pmull $t1.1q, $acc_m.1d, $mod_constant.1d + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + ext $acc_mb, $acc_mb, $acc_mb, #8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $acc_lb, $acc_lb, $t1.16b + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + + aese $ctr3b, $rk9 @ AES block 4k+7 - round 9 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + + aese $ctr0b, $rk9 @ AES block 4k+4 - round 9 + + aese $ctr1b, $rk9 @ AES block 4k+5 - round 9 + eor $acc_lb, $acc_lb, $acc_mb + + aese $ctr2b, $rk9 @ AES block 4k+6 - round 9 + .L128_enc_tail: @ TAIL + + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES block 4k+4 - load plaintext + + cmp $main_end_input_ptr, #48 + + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + eor $input_l0, $input_l0, $rk10_l @ AES block 4k+4 - round 10 low + eor $input_h0, $input_h0, $rk10_h @ AES block 4k+4 - round 10 high + + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + + eor $res1b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + + b.gt .L128_enc_blocks_more_than_3 + + sub $rctr32w, $rctr32w, #1 + movi $acc_l.8b, #0 + mov $ctr3b, $ctr2b + + cmp $main_end_input_ptr, #32 + mov $ctr2b, $ctr1b + movi $acc_h.8b, #0 + + movi $acc_m.8b, #0 + b.gt .L128_enc_blocks_more_than_2 + + mov $ctr3b, $ctr1b + cmp $main_end_input_ptr, #16 + + sub $rctr32w, $rctr32w, #1 + b.gt .L128_enc_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L128_enc_blocks_less_than_1 + .L128_enc_blocks_more_than_3: @ blocks left > 3 + st1 { $res1b}, [$output_ptr], #16 @ AES final-3 block - store result + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-2 block - load input low & high + + rev64 $res0b, $res1b @ GHASH final-3 block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + eor $input_h0, $input_h0, $rk10_h @ AES final-2 block - round 10 high + eor $input_l0, $input_l0, $rk10_l @ AES final-2 block - round 10 low + + fmov $res1d, $input_l0 @ AES final-2 block - mov low + + movi $t0.8b, #0 @ suppress further partial tag feed in + fmov $res1.d[1], $input_h0 @ AES final-2 block - mov high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + + eor $res1b, $res1b, $ctr1b @ AES final-2 block - result + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + .L128_enc_blocks_more_than_2: @ blocks left > 2 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-2 block - store result + + rev64 $res0b, $res1b @ GHASH final-2 block + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-1 block - load input low & high + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $input_l0, $input_l0, $rk10_l @ AES final-1 block - round 10 low + + fmov $res1d, $input_l0 @ AES final-1 block - mov low + eor $input_h0, $input_h0, $rk10_h @ AES final-1 block - round 10 high + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + fmov $res1.d[1], $input_h0 @ AES final-1 block - mov high + + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + + eor $res1b, $res1b, $ctr2b @ AES final-1 block - result + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + .L128_enc_blocks_more_than_1: @ blocks left > 1 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-1 block - store result + + rev64 $res0b, $res1b @ GHASH final-1 block + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final block - load input low & high + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $input_h0, $input_h0, $rk10_h @ AES final block - round 10 high + eor $input_l0, $input_l0, $rk10_l @ AES final block - round 10 low + + fmov $res1d, $input_l0 @ AES final block - mov low + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + fmov $res1.d[1], $input_h0 @ AES final block - mov high + + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + + eor $res1b, $res1b, $ctr3b @ AES final block - result + + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + movi $t0.8b, #0 @ suppress further partial tag feed in + .L128_enc_blocks_less_than_1: @ blocks left <= 1 + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + mvn $rk10_l, xzr @ rk10_l = 0xffffffffffffffff + + mvn $rk10_h, xzr @ rk10_h = 0xffffffffffffffff + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + lsr $rk10_h, $rk10_h, $bit_length @ rk10_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $input_l0, $rk10_l, $rk10_h, lt + csel $input_h0, $rk10_h, xzr, lt + + fmov $ctr0d, $input_l0 @ ctr0b is mask for last block + + fmov $ctr0.d[1], $input_h0 + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + mov $t0d, $res0.d[1] @ GHASH final block - mid + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + ld1 { $rk0}, [$output_ptr] @ load existing bytes where the possibly partial last block is to be stored + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + + rev $ctr32w, $rctr32w + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + bif $res1b, $rk0, $ctr0b @ insert existing bytes in top end of result before storing + + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + st1 { $res1b}, [$output_ptr] @ store all 16B + + str $ctr32w, [$counter, #12] @ store the updated counter + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L128_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_128_kernel,.-aes_gcm_enc_128_kernel +___ + +######################################################################################### +# size_t aes_gcm_dec_128_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_dec_128_kernel +.type aes_gcm_dec_128_kernel,%function +.align 4 +aes_gcm_dec_128_kernel: + cbz x1, .L128_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + ldr $rk0q, [$cc, #0] @ load rk0 + + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + lsr $rctr32x, $ctr96_t32x, #32 + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + + ldr $rk1q, [$cc, #16] @ load rk1 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + rev $rctr32w, $rctr32w @ rev_ctr32 + + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + rev $ctr32w, $rctr32w @ CTR block 1 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + ldr $rk2q, [$cc, #32] @ load rk2 + add $rctr32w, $rctr32w, #1 @ CTR block 1 + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + add $rctr32w, $rctr32w, #1 @ CTR block 3 + + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $rk3q, [$cc, #48] @ load rk3 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + ldr $rk6q, [$cc, #96] @ load rk6 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $rk7q, [$cc, #112] @ load rk7 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ldr $rk4q, [$cc, #64] @ load rk4 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + ldp $rk10_l, $rk10_h, [$cc, #160] @ load rk10 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + ldr $rk5q, [$cc, #80] @ load rk5 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + ldr $rk9q, [$cc, #144] @ load rk9 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + ldr $rk8q, [$cc, #128] @ load rk8 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + aese $ctr2b, $rk9 @ AES block 2 - round 9 + + aese $ctr3b, $rk9 @ AES block 3 - round 9 + + aese $ctr0b, $rk9 @ AES block 0 - round 9 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + + aese $ctr1b, $rk9 @ AES block 1 - round 9 + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + b.ge .L128_dec_tail @ handle tail + + ldr $res1q, [$input_ptr, #16] @ AES block 1 - load ciphertext + + ldr $res0q, [$input_ptr, #0] @ AES block 0 - load ciphertext + + eor $ctr1b, $res1b, $ctr1b @ AES block 1 - result + ldr $res2q, [$input_ptr, #32] @ AES block 2 - load ciphertext + + eor $ctr0b, $res0b, $ctr0b @ AES block 0 - result + rev64 $res0b, $res0b @ GHASH block 0 + rev $ctr32w, $rctr32w @ CTR block 4 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + add $rctr32w, $rctr32w, #1 @ CTR block 4 + ldr $res3q, [$input_ptr, #48] @ AES block 3 - load ciphertext + + rev64 $res1b, $res1b @ GHASH block 1 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + mov $output_l1, $ctr1.d[0] @ AES block 1 - mov low + + mov $output_h1, $ctr1.d[1] @ AES block 1 - mov high + + mov $output_l0, $ctr0.d[0] @ AES block 0 - mov low + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + + mov $output_h0, $ctr0.d[1] @ AES block 0 - mov high + + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + eor $output_l1, $output_l1, $rk10_l @ AES block 1 - round 10 low + + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + add $rctr32w, $rctr32w, #1 @ CTR block 5 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + rev $ctr32w, $rctr32w @ CTR block 6 + add $rctr32w, $rctr32w, #1 @ CTR block 6 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + + eor $output_h1, $output_h1, $rk10_h @ AES block 1 - round 10 high + eor $output_l0, $output_l0, $rk10_l @ AES block 0 - round 10 low + eor $ctr2b, $res2b, $ctr2b @ AES block 2 - result + + eor $output_h0, $output_h0, $rk10_h @ AES block 0 - round 10 high + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 0 - store result + + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 1 - store result + b.ge .L128_dec_prepretail @ do prepretail + + .L128_dec_main_loop: @ main loop start + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + + rev64 $res2b, $res2b @ GHASH block 4k+2 + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + rev $ctr32w, $rctr32w @ CTR block 4k+7 + + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + eor $res0b, $res0b, $acc_lb @ PRE 1 + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + rev64 $res3b, $res3b @ GHASH block 4k+3 + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + eor $output_l3, $output_l3, $rk10_l @ AES block 4k+3 - round 10 low + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $output_h2, $output_h2, $rk10_h @ AES block 4k+2 - round 10 high + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + eor $output_h3, $output_h3, $rk10_h @ AES block 4k+3 - round 10 high + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + eor $output_l2, $output_l2, $rk10_l @ AES block 4k+2 - round 10 low + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + movi $mod_constant.8b, #0xc2 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + ldr $res0q, [$input_ptr, #0] @ AES block 4k+4 - load ciphertext + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + rev $ctr32w, $rctr32w @ CTR block 4k+8 + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + ldr $res1q, [$input_ptr, #16] @ AES block 4k+5 - load ciphertext + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr0b, $rk9 @ AES block 4k+4 - round 9 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr1b, $rk9 @ AES block 4k+5 - round 9 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + eor $ctr0b, $res0b, $ctr0b @ AES block 4k+4 - result + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + ldr $res2q, [$input_ptr, #32] @ AES block 4k+6 - load ciphertext + + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + eor $ctr1b, $res1b, $ctr1b @ AES block 4k+5 - result + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + ldr $res3q, [$input_ptr, #48] @ AES block 4k+3 - load ciphertext + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + rev64 $res1b, $res1b @ GHASH block 4k+5 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + rev $ctr32w, $rctr32w @ CTR block 4k+9 + + aese $ctr2b, $rk9 @ AES block 4k+6 - round 9 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + eor $output_h0, $output_h0, $rk10_h @ AES block 4k+4 - round 10 high + + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + mov $output_h1, $ctr1.d[1] @ AES block 4k+5 - mov high + eor $output_l0, $output_l0, $rk10_l @ AES block 4k+4 - round 10 low + + eor $ctr2b, $res2b, $ctr2b @ AES block 4k+6 - result + mov $output_l1, $ctr1.d[0] @ AES block 4k+5 - mov low + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + + aese $ctr3b, $rk9 @ AES block 4k+7 - round 9 + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + + rev64 $res0b, $res0b @ GHASH block 4k+4 + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + + rev $ctr32w, $rctr32w @ CTR block 4k+10 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + + eor $output_h1, $output_h1, $rk10_h @ AES block 4k+5 - round 10 high + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 4k+4 - store result + + eor $output_l1, $output_l1, $rk10_l @ AES block 4k+5 - round 10 low + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 4k+5 - store result + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + b.lt L128_dec_main_loop + + .L128_dec_prepretail: @ PREPRETAIL + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + + eor $res0b, $res0b, $acc_lb @ PRE 1 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + rev64 $res2b, $res2b @ GHASH block 4k+2 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + + rev $ctr32w, $rctr32w @ CTR block 4k+7 + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + rev64 $res3b, $res3b @ GHASH block 4k+3 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + movi $mod_constant.8b, #0xc2 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $output_l3, $output_l3, $rk10_l @ AES block 4k+3 - round 10 low + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $output_l2, $output_l2, $rk10_l @ AES block 4k+2 - round 10 low + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + aese $ctr1b, $rk9 @ AES block 4k+5 - round 9 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + eor $output_h3, $output_h3, $rk10_h @ AES block 4k+3 - round 10 high + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + eor $output_h2, $output_h2, $rk10_h @ AES block 4k+2 - round 10 high + + aese $ctr0b, $rk9 @ AES block 4k+4 - round 9 + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + aese $ctr2b, $rk9 @ AES block 4k+6 - round 9 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + + aese $ctr3b, $rk9 @ AES block 4k+7 - round 9 + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + .L128_dec_tail: @ TAIL + + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ld1 { $res1b}, [$input_ptr], #16 @ AES block 4k+4 - load ciphertext + + eor $ctr0b, $res1b, $ctr0b @ AES block 4k+4 - result + + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + + cmp $main_end_input_ptr, #48 + + eor $output_h0, $output_h0, $rk10_h @ AES block 4k+4 - round 10 high + + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + eor $output_l0, $output_l0, $rk10_l @ AES block 4k+4 - round 10 low + b.gt .L128_dec_blocks_more_than_3 + + mov $ctr3b, $ctr2b + sub $rctr32w, $rctr32w, #1 + movi $acc_l.8b, #0 + + movi $acc_h.8b, #0 + mov $ctr2b, $ctr1b + + movi $acc_m.8b, #0 + cmp $main_end_input_ptr, #32 + b.gt .L128_dec_blocks_more_than_2 + + cmp $main_end_input_ptr, #16 + + mov $ctr3b, $ctr1b + sub $rctr32w, $rctr32w, #1 + b.gt .L128_dec_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L128_dec_blocks_less_than_1 + .L128_dec_blocks_more_than_3: @ blocks left > 3 + rev64 $res0b, $res1b @ GHASH final-3 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-2 block - load ciphertext + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-3 block - store result + eor $ctr0b, $res1b, $ctr1b @ AES final-2 block - result + + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + mov $output_h0, $ctr0.d[1] @ AES final-2 block - mov high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + mov $output_l0, $ctr0.d[0] @ AES final-2 block - mov low + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + eor $output_h0, $output_h0, $rk10_h @ AES final-2 block - round 10 high + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + eor $output_l0, $output_l0, $rk10_l @ AES final-2 block - round 10 low + .L128_dec_blocks_more_than_2: @ blocks left > 2 + + rev64 $res0b, $res1b @ GHASH final-2 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-1 block - load ciphertext + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $ctr0b, $res1b, $ctr2b @ AES final-1 block - result + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-2 block - store result + + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + mov $output_l0, $ctr0.d[0] @ AES final-1 block - mov low + + mov $output_h0, $ctr0.d[1] @ AES final-1 block - mov high + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + eor $output_l0, $output_l0, $rk10_l @ AES final-1 block - round 10 low + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + eor $output_h0, $output_h0, $rk10_h @ AES final-1 block - round 10 high + .L128_dec_blocks_more_than_1: @ blocks left > 1 + + rev64 $res0b, $res1b @ GHASH final-1 block + + ld1 { $res1b}, [$input_ptr], #16 @ AES final block - load ciphertext + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + eor $ctr0b, $res1b, $ctr3b @ AES final block - result + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-1 block - store result + mov $output_l0, $ctr0.d[0] @ AES final block - mov low + + mov $output_h0, $ctr0.d[1] @ AES final block - mov high + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + movi $t0.8b, #0 @ suppress further partial tag feed in + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + eor $output_h0, $output_h0, $rk10_h @ AES final block - round 10 high + + eor $output_l0, $output_l0, $rk10_l @ AES final block - round 10 low + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + .L128_dec_blocks_less_than_1: @ blocks left <= 1 + + mvn $rk10_h, xzr @ rk10_h = 0xffffffffffffffff + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + mvn $rk10_l, xzr @ rk10_l = 0xffffffffffffffff + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + lsr $rk10_h, $rk10_h, $bit_length @ rk10_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $ctr96_b64x, $rk10_h, xzr, lt + csel $ctr32x, $rk10_l, $rk10_h, lt + + fmov $ctr0d, $ctr32x @ ctr0b is mask for last block + + mov $ctr0.d[1], $ctr96_b64x + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + ldp $end_input_ptr, $main_end_input_ptr, [$output_ptr] @ load existing bytes we need to not overwrite + + and $output_h0, $output_h0, $ctr96_b64x + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + mov $t0d, $res0.d[1] @ GHASH final block - mid + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + bic $end_input_ptr, $end_input_ptr, $ctr32x @ mask out low existing bytes + and $output_l0, $output_l0, $ctr32x + + rev $ctr32w, $rctr32w + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + bic $main_end_input_ptr, $main_end_input_ptr, $ctr96_b64x @ mask out high existing bytes + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + orr $output_l0, $output_l0, $end_input_ptr + str $ctr32w, [$counter, #12] @ store the updated counter + + orr $output_h0, $output_h0, $main_end_input_ptr + stp $output_l0, $output_h0, [$output_ptr] + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + + .L128_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_128_kernel,.-aes_gcm_dec_128_kernel +___ +} + +{ +my ($end_input_ptr,$main_end_input_ptr,$input_l0,$input_h0)=map("x$_",(4..7)); +my ($input_l1,$input_h1,$input_l2,$input_h2,$input_l3,$input_h3)=map("x$_",(19..24)); +my ($output_l1,$output_h1,$output_l2,$output_h2,$output_l3,$output_h3)=map("x$_",(19..24)); +my ($output_l0,$output_h0)=map("x$_",(6..7)); + +my $ctr32w="w9"; +my ($ctr32x,$ctr96_b64x,$ctr96_t32x,$rctr32x,$rk12_l,$rk12_h,$len)=map("x$_",(9..15)); +my ($ctr96_t32w,$rctr32w)=map("w$_",(11..12)); + +my ($ctr0b,$ctr1b,$ctr2b,$ctr3b,$res0b,$res1b,$res2b,$res3b)=map("v$_.16b",(0..7)); +my ($ctr0,$ctr1,$ctr2,$ctr3,$res0,$res1,$res2,$res3)=map("v$_",(0..7)); +my ($ctr0d,$ctr1d,$ctr2d,$ctr3d,$res0d,$res1d,$res2d,$res3d)=map("d$_",(0..7)); +my ($res0q,$res1q,$res2q,$res3q)=map("q$_",(4..7)); + +my ($acc_hb,$acc_mb,$acc_lb)=map("v$_.16b",(9..11)); +my ($acc_h,$acc_m,$acc_l)=map("v$_",(9..11)); +my ($acc_hd,$acc_md,$acc_ld)=map("d$_",(9..11)); + +my ($h1,$h2,$h3,$h4,$h12k,$h34k)=map("v$_",(12..17)); +my ($h1q,$h2q,$h3q,$h4q)=map("q$_",(12..15)); +my ($h1b,$h2b,$h3b,$h4b)=map("v$_.16b",(12..15)); + +my $t0="v8"; +my $t0d="d8"; +my $t3="v4"; +my $t3d="d4"; + +my ($t1,$t2)=map("v$_",(30..31)); +my ($t1d,$t2d)=map("d$_",(30..31)); + +my $t4="v30"; +my $t4d="d30"; +my $t5="v8"; +my $t5d="d8"; +my $t6="v31"; +my $t6d="d31"; + +my $t7="v5"; +my $t7d="d5"; +my $t8="v6"; +my $t8d="d6"; +my $t9="v30"; +my $t9d="d30"; + +my ($ctr_t0,$ctr_t1,$ctr_t2,$ctr_t3)=map("v$_",(4..7)); +my ($ctr_t0d,$ctr_t1d,$ctr_t2d,$ctr_t3d)=map("d$_",(4..7)); +my ($ctr_t0b,$ctr_t1b,$ctr_t2b,$ctr_t3b)=map("v$_.16b",(4..7)); + +my $mod_constantd="d8"; +my $mod_constant="v8"; +my $mod_t="v31"; + +my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7,$rk8,$rk9,$rk10,$rk11)=map("v$_.16b",(18..29)); +my ($rk0q,$rk1q,$rk2q,$rk3q,$rk4q,$rk5q,$rk6q,$rk7q,$rk8q,$rk9q,$rk10q,$rk11q)=map("q$_",(18..29)); +my $rk2q1="v20.1q"; +my $rk3q1="v21.1q"; +my $rk4v="v22"; +my $rk4d="d22"; + +######################################################################################### +# size_t aes_gcm_enc_192_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_enc_192_kernel +.type aes_gcm_enc_192_kernel,%function +.align 4 +aes_gcm_enc_192_kernel: + cbz x1, .L192_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + + ldr $rk5q, [$cc, #80] @ load rk5 + + ldr $rk4q, [$cc, #64] @ load rk4 + + ldr $rk8q, [$cc, #128] @ load rk8 + + lsr $rctr32x, $ctr96_t32x, #32 + ldr $rk6q, [$cc, #96] @ load rk6 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + + ldr $rk7q, [$cc, #112] @ load rk7 + rev $rctr32w, $rctr32w @ rev_ctr32 + + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + + rev $ctr32w, $rctr32w @ CTR block 1 + add $rctr32w, $rctr32w, #1 @ CTR block 1 + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + ldr $rk0q, [$cc, #0] @ load rk0 + + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + + ldr $rk3q, [$cc, #48] @ load rk3 + + ldp $rk12_l, $rk12_h, [$cc, #192] @ load rk12 + + ldr $rk1q, [$cc, #16] @ load rk1 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + ldr $rk11q, [$cc, #176] @ load rk11 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $rk2q, [$cc, #32] @ load rk2 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + ldr $rk10q, [$cc, #160] @ load rk10 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + ldr $rk9q, [$cc, #144] @ load rk9 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 9 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 9 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 9 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 9 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 10 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 10 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 10 + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 10 + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + + aese $ctr2b, $rk11 @ AES block 2 - round 11 + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + + aese $ctr1b, $rk11 @ AES block 1 - round 11 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + + aese $ctr0b, $rk11 @ AES block 0 - round 11 + add $rctr32w, $rctr32w, #1 @ CTR block 3 + + aese $ctr3b, $rk11 @ AES block 3 - round 11 + b.ge .L192_enc_tail @ handle tail + + rev $ctr32w, $rctr32w @ CTR block 4 + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 0 - load plaintext + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 2 - load plaintext + + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 3 - load plaintext + + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 1 - load plaintext + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + + eor $input_l0, $input_l0, $rk12_l @ AES block 0 - round 12 low + + eor $input_h0, $input_h0, $rk12_h @ AES block 0 - round 12 high + eor $input_h2, $input_h2, $rk12_h @ AES block 2 - round 12 high + fmov $ctr_t0d, $input_l0 @ AES block 0 - mov low + + eor $input_h3, $input_h3, $rk12_h @ AES block 3 - round 12 high + fmov $ctr_t0.d[1], $input_h0 @ AES block 0 - mov high + + eor $input_l2, $input_l2, $rk12_l @ AES block 2 - round 12 low + eor $input_l1, $input_l1, $rk12_l @ AES block 1 - round 12 low + + fmov $ctr_t1d, $input_l1 @ AES block 1 - mov low + eor $input_h1, $input_h1, $rk12_h @ AES block 1 - round 12 high + + fmov $ctr_t1.d[1], $input_h1 @ AES block 1 - mov high + + eor $input_l3, $input_l3, $rk12_l @ AES block 3 - round 12 low + fmov $ctr_t2d, $input_l2 @ AES block 2 - mov low + + add $rctr32w, $rctr32w, #1 @ CTR block 4 + eor $res0b, $ctr_t0b, $ctr0b @ AES block 0 - result + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + add $rctr32w, $rctr32w, #1 @ CTR block 5 + + fmov $ctr_t3d, $input_l3 @ AES block 3 - mov low + st1 { $res0b}, [$output_ptr], #16 @ AES block 0 - store result + + fmov $ctr_t2.d[1], $input_h2 @ AES block 2 - mov high + + eor $res1b, $ctr_t1b, $ctr1b @ AES block 1 - result + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + st1 { $res1b}, [$output_ptr], #16 @ AES block 1 - store result + + fmov $ctr_t3.d[1], $input_h3 @ AES block 3 - mov high + + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + rev $ctr32w, $rctr32w @ CTR block 6 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + + add $rctr32w, $rctr32w, #1 @ CTR block 6 + eor $res2b, $ctr_t2b, $ctr2b @ AES block 2 - result + fmov $ctr2d, $ctr96_b64x @ CTR block 6 + + fmov $ctr2.d[1], $ctr32x @ CTR block 6 + rev $ctr32w, $rctr32w @ CTR block 7 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 7 + st1 { $res2b}, [$output_ptr], #16 @ AES block 2 - store result + + eor $res3b, $ctr_t3b, $ctr3b @ AES block 3 - result + st1 { $res3b}, [$output_ptr], #16 @ AES block 3 - store result + b.ge .L192_enc_prepretail @ do prepretail + + .L192_enc_main_loop: @ main loop start + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 4k+5 - load plaintext + + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 4k+6 - load plaintext + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 4k+3 - load plaintext + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + eor $res0b, $res0b, $acc_lb @ PRE 1 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $input_h3, $input_h3, $rk12_h @ AES block 4k+3 - round 12 high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + eor $input_l2, $input_l2, $rk12_l @ AES block 4k+6 - round 12 low + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $input_l1, $input_l1, $rk12_l @ AES block 4k+5 - round 12 low + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + eor $input_h1, $input_h1, $rk12_h @ AES block 4k+5 - round 12 high + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $input_h2, $input_h2, $rk12_h @ AES block 4k+6 - round 12 high + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + eor $input_l3, $input_l3, $rk12_l @ AES block 4k+3 - round 12 low + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + rev $ctr32w, $rctr32w @ CTR block 4k+8 + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 4k+4 - load plaintext + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + movi $mod_constant.8b, #0xc2 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + eor $input_h0, $input_h0, $rk12_h @ AES block 4k+4 - round 12 high + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + eor $input_l0, $input_l0, $rk12_l @ AES block 4k+4 - round 12 low + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + fmov $ctr_t1d, $input_l1 @ AES block 4k+5 - mov low + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + fmov $ctr_t1.d[1], $input_h1 @ AES block 4k+5 - mov high + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + fmov $ctr_t3d, $input_l3 @ AES block 4k+3 - mov low + + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + fmov $ctr_t3.d[1], $input_h3 @ AES block 4k+3 - mov high + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + fmov $ctr_t2d, $input_l2 @ AES block 4k+6 - mov low + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + + aese $ctr0b, $rk11 @ AES block 4k+4 - round 11 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + + eor $res0b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + + aese $ctr1b, $rk11 @ AES block 4k+5 - round 11 + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + rev $ctr32w, $rctr32w @ CTR block 4k+9 + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + fmov $ctr_t2.d[1], $input_h2 @ AES block 4k+6 - mov high + st1 { $res0b}, [$output_ptr], #16 @ AES block 4k+4 - store result + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + + eor $res1b, $ctr_t1b, $ctr1b @ AES block 4k+5 - result + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + + aese $ctr2b, $rk11 @ AES block 4k+6 - round 11 + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + rev $ctr32w, $rctr32w @ CTR block 4k+10 + + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + + st1 { $res1b}, [$output_ptr], #16 @ AES block 4k+5 - store result + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + + aese $ctr3b, $rk11 @ AES block 4k+7 - round 11 + eor $res2b, $ctr_t2b, $ctr2b @ AES block 4k+6 - result + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+10 + + st1 { $res2b}, [$output_ptr], #16 @ AES block 4k+6 - store result + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+10 + rev $ctr32w, $rctr32w @ CTR block 4k+11 + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+11 + + eor $res3b, $ctr_t3b, $ctr3b @ AES block 4k+3 - result + st1 { $res3b}, [$output_ptr], #16 @ AES block 4k+3 - store result + b.lt .L192_enc_main_loop + + .L192_enc_prepretail: @ PREPRETAIL + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + eor $res0b, $res0b, $acc_lb @ PRE 1 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + movi $mod_constant.8b, #0xc2 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + eor $acc_mb, $acc_mb, $acc_hb @ karatsuba tidy up + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + eor $acc_mb, $acc_mb, $acc_lb + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + pmull $t1.1q, $acc_h.1d, $mod_constant.1d + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + ext $acc_hb, $acc_hb, $acc_hb, #8 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + eor $acc_mb, $acc_mb, $t1.16b + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + eor $acc_mb, $acc_mb, $acc_hb + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + + pmull $t1.1q, $acc_m.1d, $mod_constant.1d + + ext $acc_mb, $acc_mb, $acc_mb, #8 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + eor $acc_lb, $acc_lb, $t1.16b + + aese $ctr0b, $rk11 @ AES block 4k+4 - round 11 + + aese $ctr3b, $rk11 @ AES block 4k+7 - round 11 + + aese $ctr2b, $rk11 @ AES block 4k+6 - round 11 + + aese $ctr1b, $rk11 @ AES block 4k+5 - round 11 + eor $acc_lb, $acc_lb, $acc_mb + .L192_enc_tail: @ TAIL + + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES block 4k+4 - load plaintext + + eor $input_l0, $input_l0, $rk12_l @ AES block 4k+4 - round 12 low + eor $input_h0, $input_h0, $rk12_h @ AES block 4k+4 - round 12 high + + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + cmp $main_end_input_ptr, #48 + + eor $res1b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + b.gt .L192_enc_blocks_more_than_3 + + sub $rctr32w, $rctr32w, #1 + movi $acc_m.8b, #0 + + mov $ctr3b, $ctr2b + movi $acc_h.8b, #0 + cmp $main_end_input_ptr, #32 + + mov $ctr2b, $ctr1b + movi $acc_l.8b, #0 + b.gt .L192_enc_blocks_more_than_2 + + sub $rctr32w, $rctr32w, #1 + + mov $ctr3b, $ctr1b + cmp $main_end_input_ptr, #16 + b.gt .L192_enc_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L192_enc_blocks_less_than_1 + .L192_enc_blocks_more_than_3: @ blocks left > 3 + st1 { $res1b}, [$output_ptr], #16 @ AES final-3 block - store result + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-2 block - load input low & high + + rev64 $res0b, $res1b @ GHASH final-3 block + + eor $input_l0, $input_l0, $rk12_l @ AES final-2 block - round 12 low + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $input_h0, $input_h0, $rk12_h @ AES final-2 block - round 12 high + fmov $res1d, $input_l0 @ AES final-2 block - mov low + + fmov $res1.d[1], $input_h0 @ AES final-2 block - mov high + + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + eor $res1b, $res1b, $ctr1b @ AES final-2 block - result + .L192_enc_blocks_more_than_2: @ blocks left > 2 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-2 block - store result + + rev64 $res0b, $res1b @ GHASH final-2 block + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-1 block - load input low & high + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $input_h0, $input_h0, $rk12_h @ AES final-1 block - round 12 high + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + eor $input_l0, $input_l0, $rk12_l @ AES final-1 block - round 12 low + + fmov $res1d, $input_l0 @ AES final-1 block - mov low + + fmov $res1.d[1], $input_h0 @ AES final-1 block - mov high + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + + eor $res1b, $res1b, $ctr2b @ AES final-1 block - result + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + .L192_enc_blocks_more_than_1: @ blocks left > 1 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-1 block - store result + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final block - load input low & high + + rev64 $res0b, $res1b @ GHASH final-1 block + + eor $input_l0, $input_l0, $rk12_l @ AES final block - round 12 low + eor $res0b, $res0b, $t0.16b @ feed in partial tag + movi $t0.8b, #0 @ suppress further partial tag feed in + + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + eor $input_h0, $input_h0, $rk12_h @ AES final block - round 12 high + fmov $res1d, $input_l0 @ AES final block - mov low + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + fmov $res1.d[1], $input_h0 @ AES final block - mov high + + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + + eor $res1b, $res1b, $ctr3b @ AES final block - result + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + .L192_enc_blocks_less_than_1: @ blocks left <= 1 + + ld1 { $rk0}, [$output_ptr] @ load existing bytes where the possibly partial last block is to be stored + rev $ctr32w, $rctr32w + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + mvn $rk12_h, xzr @ rk12_h = 0xffffffffffffffff + + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + mvn $rk12_l, xzr @ rk12_l = 0xffffffffffffffff + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + lsr $rk12_h, $rk12_h, $bit_length @ rk12_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $input_l0, $rk12_l, $rk12_h, lt + csel $input_h0, $rk12_h, xzr, lt + + fmov $ctr0d, $input_l0 @ ctr0b is mask for last block + + fmov $ctr0.d[1], $input_h0 + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + mov $t0d, $res0.d[1] @ GHASH final block - mid + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + bif $res1b, $rk0, $ctr0b @ insert existing bytes in top end of result before storing + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + str $ctr32w, [$counter, #12] @ store the updated counter + + st1 { $res1b}, [$output_ptr] @ store all 16B + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L192_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_192_kernel,.-aes_gcm_enc_192_kernel +___ + +######################################################################################### +# size_t aes_gcm_dec_192_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_dec_192_kernel +.type aes_gcm_dec_192_kernel,%function +.align 4 +aes_gcm_dec_192_kernel: + cbz x1, .L192_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + + ldr $rk0q, [$cc, #0] @ load rk0 + + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + ldr $rk2q, [$cc, #32] @ load rk2 + + lsr $rctr32x, $ctr96_t32x, #32 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + + rev $rctr32w, $rctr32w @ rev_ctr32 + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + ldr $rk1q, [$cc, #16] @ load rk1 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + rev $ctr32w, $rctr32w @ CTR block 1 + + add $rctr32w, $rctr32w, #1 @ CTR block 1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + ldr $rk3q, [$cc, #48] @ load rk3 + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + + ldr $rk8q, [$cc, #128] @ load rk8 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $rk11q, [$cc, #176] @ load rk11 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ldp $rk12_l, $rk12_h, [$cc, #192] @ load rk12 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + ldr $rk10q, [$cc, #160] @ load rk10 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + ldr $rk9q, [$cc, #144] @ load rk9 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + ldr $rk7q, [$cc, #112] @ load rk7 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + ldr $rk4q, [$cc, #64] @ load rk4 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + add $rctr32w, $rctr32w, #1 @ CTR block 3 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + ldr $rk5q, [$cc, #80] @ load rk5 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + ldr $rk6q, [$cc, #96] @ load rk6 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 9 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 9 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 10 + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 9 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 9 + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + + aese $ctr3b, $rk11 @ AES block 3 - round 11 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 10 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 10 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 10 + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + + aese $ctr2b, $rk11 @ AES block 2 - round 11 + + aese $ctr1b, $rk11 @ AES block 1 - round 11 + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + + aese $ctr0b, $rk11 @ AES block 0 - round 11 + b.ge .L192_dec_tail @ handle tail + + ldr $res1q, [$input_ptr, #16] @ AES block 1 - load ciphertext + + ldr $res0q, [$input_ptr, #0] @ AES block 0 - load ciphertext + + eor $ctr1b, $res1b, $ctr1b @ AES block 1 - result + + eor $ctr0b, $res0b, $ctr0b @ AES block 0 - result + rev $ctr32w, $rctr32w @ CTR block 4 + ldr $res3q, [$input_ptr, #48] @ AES block 3 - load ciphertext + + ldr $res2q, [$input_ptr, #32] @ AES block 2 - load ciphertext + + mov $output_l1, $ctr1.d[0] @ AES block 1 - mov low + + mov $output_h1, $ctr1.d[1] @ AES block 1 - mov high + + mov $output_l0, $ctr0.d[0] @ AES block 0 - mov low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + add $rctr32w, $rctr32w, #1 @ CTR block 4 + + mov $output_h0, $ctr0.d[1] @ AES block 0 - mov high + rev64 $res0b, $res0b @ GHASH block 0 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + rev64 $res1b, $res1b @ GHASH block 1 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + + eor $output_l1, $output_l1, $rk12_l @ AES block 1 - round 12 low + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + eor $output_h1, $output_h1, $rk12_h @ AES block 1 - round 12 high + + add $rctr32w, $rctr32w, #1 @ CTR block 5 + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + eor $output_l0, $output_l0, $rk12_l @ AES block 0 - round 12 low + + rev $ctr32w, $rctr32w @ CTR block 6 + eor $output_h0, $output_h0, $rk12_h @ AES block 0 - round 12 high + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 0 - store result + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 1 - store result + + add $rctr32w, $rctr32w, #1 @ CTR block 6 + eor $ctr2b, $res2b, $ctr2b @ AES block 2 - result + b.ge .L192_dec_prepretail @ do prepretail + + .L192_dec_main_loop: @ main loop start + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + rev64 $res3b, $res3b @ GHASH block 4k+3 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + eor $res0b, $res0b, $acc_lb @ PRE 1 + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + rev $ctr32w, $rctr32w @ CTR block 4k+7 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + eor $output_h2, $output_h2, $rk12_h @ AES block 4k+2 - round 12 high + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + rev64 $res2b, $res2b @ GHASH block 4k+2 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + eor $output_l2, $output_l2, $rk12_l @ AES block 4k+2 - round 12 low + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + movi $mod_constant.8b, #0xc2 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + ldr $res2q, [$input_ptr, #32] @ AES block 4k+6 - load ciphertext + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + ldr $res3q, [$input_ptr, #48] @ AES block 4k+7 - load ciphertext + eor $output_l3, $output_l3, $rk12_l @ AES block 4k+3 - round 12 low + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr0b, $rk11 @ AES block 4k+4 - round 11 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + ldr $res0q, [$input_ptr, #0] @ AES block 4k+4 - load ciphertext + + aese $ctr1b, $rk11 @ AES block 4k+5 - round 11 + ldr $res1q, [$input_ptr, #16] @ AES block 4k+5 - load ciphertext + rev $ctr32w, $rctr32w @ CTR block 4k+8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + + eor $ctr0b, $res0b, $ctr0b @ AES block 4k+4 - result + eor $output_h3, $output_h3, $rk12_h @ AES block 4k+3 - round 12 high + eor $ctr1b, $res1b, $ctr1b @ AES block 4k+5 - result + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + mov $output_l1, $ctr1.d[0] @ AES block 4k+5 - mov low + + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + rev64 $res1b, $res1b @ GHASH block 4k+5 + + aese $ctr2b, $rk11 @ AES block 4k+6 - round 11 + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + mov $output_h1, $ctr1.d[1] @ AES block 4k+5 - mov high + + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + eor $ctr2b, $res2b, $ctr2b @ AES block 4k+6 - result + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + rev $ctr32w, $rctr32w @ CTR block 4k+9 + + eor $output_l0, $output_l0, $rk12_l @ AES block 4k+4 - round 12 low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + eor $output_l1, $output_l1, $rk12_l @ AES block 4k+5 - round 12 low + + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + rev $ctr32w, $rctr32w @ CTR block 4k+10 + eor $output_h1, $output_h1, $rk12_h @ AES block 4k+5 - round 12 high + + eor $output_h0, $output_h0, $rk12_h @ AES block 4k+4 - round 12 high + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 4k+4 - store result + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + rev64 $res0b, $res0b @ GHASH block 4k+4 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + + aese $ctr3b, $rk11 @ AES block 4k+7 - round 11 + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 4k+5 - store result + b.lt .L192_dec_main_loop + + .L192_dec_prepretail: @ PREPRETAIL + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + eor $res0b, $res0b, $acc_lb @ PRE 1 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + rev64 $res2b, $res2b @ GHASH block 4k+2 + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + rev $ctr32w, $rctr32w @ CTR block 4k+7 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + eor $output_h3, $output_h3, $rk12_h @ AES block 4k+3 - round 12 high + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + eor $output_l2, $output_l2, $rk12_l @ AES block 4k+2 - round 12 low + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + eor $output_h2, $output_h2, $rk12_h @ AES block 4k+2 - round 12 high + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + eor $output_l3, $output_l3, $rk12_l @ AES block 4k+3 - round 12 low + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + rev64 $res3b, $res3b @ GHASH block 4k+3 + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + movi $mod_constant.8b, #0xc2 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + + aese $ctr0b, $rk11 + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + aese $ctr2b, $rk11 + + aese $ctr1b, $rk11 + + aese $ctr3b, $rk11 + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + .L192_dec_tail: @ TAIL + + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ld1 { $res1b}, [$input_ptr], #16 @ AES block 4k+4 - load ciphertext + + eor $ctr0b, $res1b, $ctr0b @ AES block 4k+4 - result + + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + + cmp $main_end_input_ptr, #48 + + eor $output_h0, $output_h0, $rk12_h @ AES block 4k+4 - round 12 high + + eor $output_l0, $output_l0, $rk12_l @ AES block 4k+4 - round 12 low + b.gt .L192_dec_blocks_more_than_3 + + movi $acc_l.8b, #0 + movi $acc_h.8b, #0 + + mov $ctr3b, $ctr2b + mov $ctr2b, $ctr1b + sub $rctr32w, $rctr32w, #1 + + movi $acc_m.8b, #0 + cmp $main_end_input_ptr, #32 + b.gt .L192_dec_blocks_more_than_2 + + mov $ctr3b, $ctr1b + cmp $main_end_input_ptr, #16 + sub $rctr32w, $rctr32w, #1 + + b.gt .L192_dec_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L192_dec_blocks_less_than_1 + .L192_dec_blocks_more_than_3: @ blocks left > 3 + rev64 $res0b, $res1b @ GHASH final-3 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-2 block - load ciphertext + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-3 block - store result + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $ctr0b, $res1b, $ctr1b @ AES final-2 block - result + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + mov $output_l0, $ctr0.d[0] @ AES final-2 block - mov low + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + + mov $output_h0, $ctr0.d[1] @ AES final-2 block - mov high + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + eor $output_l0, $output_l0, $rk12_l @ AES final-2 block - round 12 low + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + eor $output_h0, $output_h0, $rk12_h @ AES final-2 block - round 12 high + .L192_dec_blocks_more_than_2: @ blocks left > 2 + + rev64 $res0b, $res1b @ GHASH final-2 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-1 block - load ciphertext + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + movi $t0.8b, #0 @ suppress further partial tag feed in + + eor $ctr0b, $res1b, $ctr2b @ AES final-1 block - result + + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-2 block - store result + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + mov $output_h0, $ctr0.d[1] @ AES final-1 block - mov high + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + mov $output_l0, $ctr0.d[0] @ AES final-1 block - mov low + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + eor $output_h0, $output_h0, $rk12_h @ AES final-1 block - round 12 high + + eor $output_l0, $output_l0, $rk12_l @ AES final-1 block - round 12 low + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + .L192_dec_blocks_more_than_1: @ blocks left > 1 + + rev64 $res0b, $res1b @ GHASH final-1 block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + ld1 { $res1b}, [$input_ptr], #16 @ AES final block - load ciphertext + + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + + eor $ctr0b, $res1b, $ctr3b @ AES final block - result + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-1 block - store result + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + mov $output_h0, $ctr0.d[1] @ AES final block - mov high + + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + mov $output_l0, $ctr0.d[0] @ AES final block - mov low + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + eor $output_h0, $output_h0, $rk12_h @ AES final block - round 12 high + + eor $output_l0, $output_l0, $rk12_l @ AES final block - round 12 low + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + .L192_dec_blocks_less_than_1: @ blocks left <= 1 + + mvn $rk12_l, xzr @ rk12_l = 0xffffffffffffffff + ldp $end_input_ptr, $main_end_input_ptr, [$output_ptr] @ load existing bytes we need to not overwrite + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + mvn $rk12_h, xzr @ rk12_h = 0xffffffffffffffff + + lsr $rk12_h, $rk12_h, $bit_length @ rk12_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $ctr32x, $rk12_l, $rk12_h, lt + csel $ctr96_b64x, $rk12_h, xzr, lt + + fmov $ctr0d, $ctr32x @ ctr0b is mask for last block + and $output_l0, $output_l0, $ctr32x + bic $end_input_ptr, $end_input_ptr, $ctr32x @ mask out low existing bytes + + orr $output_l0, $output_l0, $end_input_ptr + mov $ctr0.d[1], $ctr96_b64x + + rev $ctr32w, $rctr32w + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + str $ctr32w, [$counter, #12] @ store the updated counter + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + bic $main_end_input_ptr, $main_end_input_ptr, $ctr96_b64x @ mask out high existing bytes + + and $output_h0, $output_h0, $ctr96_b64x + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + mov $t0d, $res0.d[1] @ GHASH final block - mid + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + orr $output_h0, $output_h0, $main_end_input_ptr + stp $output_l0, $output_h0, [$output_ptr] + + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L192_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_192_kernel,.-aes_gcm_dec_192_kernel +___ +} + +{ +my ($end_input_ptr,$main_end_input_ptr,$input_l0,$input_h0)=map("x$_",(4..7)); +my ($input_l1,$input_h1,$input_l2,$input_h2,$input_l3,$input_h3)=map("x$_",(19..24)); +my ($output_l1,$output_h1,$output_l2,$output_h2,$output_l3,$output_h3)=map("x$_",(19..24)); +my ($output_l0,$output_h0)=map("x$_",(6..7)); + +my $ctr32w="w9"; +my ($ctr32x,$ctr96_b64x,$ctr96_t32x,$rctr32x,$rk14_l,$rk14_h,$len)=map("x$_",(9..15)); +my ($ctr96_t32w,$rctr32w)=map("w$_",(11..12)); + +my ($ctr0b,$ctr1b,$ctr2b,$ctr3b,$res0b,$res1b,$res2b,$res3b)=map("v$_.16b",(0..7)); +my ($ctr0,$ctr1,$ctr2,$ctr3,$res0,$res1,$res2,$res3)=map("v$_",(0..7)); +my ($ctr0d,$ctr1d,$ctr2d,$ctr3d,$res0d,$res1d,$res2d,$res3d)=map("d$_",(0..7)); +my ($res0q,$res1q,$res2q,$res3q)=map("q$_",(4..7)); + +my ($acc_hb,$acc_mb,$acc_lb)=map("v$_.16b",(9..11)); +my ($acc_h,$acc_m,$acc_l)=map("v$_",(9..11)); +my ($acc_hd,$acc_md,$acc_ld)=map("d$_",(9..11)); + +my ($h1,$h2,$h3,$h4,$h12k,$h34k)=map("v$_",(12..17)); +my ($h1q,$h2q,$h3q,$h4q)=map("q$_",(12..15)); +my ($h1b,$h2b,$h3b,$h4b)=map("v$_.16b",(12..15)); + +my $t0="v8"; +my $t0d="d8"; +my $t1="v4"; +my $t1d="d4"; +my $t2="v8"; +my $t2d="d8"; +my $t3="v4"; +my $t3d="d4"; +my $t4="v4"; +my $t4d="d4"; +my $t5="v5"; +my $t5d="d5"; +my $t6="v8"; +my $t6d="d8"; +my $t7="v5"; +my $t7d="d5"; +my $t8="v6"; +my $t8d="d6"; +my $t9="v4"; +my $t9d="d4"; + +my ($ctr_t0,$ctr_t1,$ctr_t2,$ctr_t3)=map("v$_",(4..7)); +my ($ctr_t0d,$ctr_t1d,$ctr_t2d,$ctr_t3d)=map("d$_",(4..7)); +my ($ctr_t0b,$ctr_t1b,$ctr_t2b,$ctr_t3b)=map("v$_.16b",(4..7)); + +my $mod_constantd="d8"; +my $mod_constant="v8"; +my $mod_t="v7"; + +my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7,$rk8,$rk9,$rk10,$rk11,$rk12,$rk13)=map("v$_.16b",(18..31)); +my ($rk0q,$rk1q,$rk2q,$rk3q,$rk4q,$rk5q,$rk6q,$rk7q,$rk8q,$rk9q,$rk10q,$rk11q,$rk12q,$rk13q)=map("q$_",(18..31)); +my $rk2q1="v20.1q"; +my $rk3q1="v21.1q"; +my $rk4v="v22"; +my $rk4d="d22"; + +######################################################################################### +# size_t aes_gcm_enc_256_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_enc_256_kernel +.type aes_gcm_enc_256_kernel,%function +.align 4 +aes_gcm_enc_256_kernel: + cbz x1, .L256_enc_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + + ldr $rk0q, [$cc, #0] @ load rk0 + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + ldr $rk7q, [$cc, #112] @ load rk7 + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + + lsr $rctr32x, $ctr96_t32x, #32 + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + + rev $rctr32w, $rctr32w @ rev_ctr32 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + + rev $ctr32w, $rctr32w @ CTR block 1 + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + add $rctr32w, $rctr32w, #1 @ CTR block 1 + ldr $rk1q, [$cc, #16] @ load rk1 + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + ldr $rk2q, [$cc, #32] @ load rk2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $rk3q, [$cc, #48] @ load rk3 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + ldr $rk6q, [$cc, #96] @ load rk6 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $rk5q, [$cc, #80] @ load rk5 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + ldr $rk13q, [$cc, #208] @ load rk13 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + ldr $rk4q, [$cc, #64] @ load rk4 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + ldr $rk12q, [$cc, #192] @ load rk12 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + ldr $rk11q, [$cc, #176] @ load rk11 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + ldr $rk8q, [$cc, #128] @ load rk8 + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + add $rctr32w, $rctr32w, #1 @ CTR block 3 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + ldp $rk14_l, $rk14_h, [$cc, #224] @ load rk14 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + ldr $rk9q, [$cc, #144] @ load rk9 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + ldr $rk10q, [$cc, #160] @ load rk10 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 9 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 9 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 10 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 9 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 9 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 10 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 10 + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 11 + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 11 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 10 + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 12 + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 12 + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 11 + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 11 + + aese $ctr2b, $rk13 @ AES block 2 - round 13 + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 12 + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 12 + + aese $ctr1b, $rk13 @ AES block 1 - round 13 + + aese $ctr0b, $rk13 @ AES block 0 - round 13 + + aese $ctr3b, $rk13 @ AES block 3 - round 13 + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + b.ge .L256_enc_tail @ handle tail + + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 1 - load plaintext + + rev $ctr32w, $rctr32w @ CTR block 4 + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 0 - load plaintext + + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 3 - load plaintext + + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 2 - load plaintext + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + eor $input_l1, $input_l1, $rk14_l @ AES block 1 - round 14 low + eor $input_h1, $input_h1, $rk14_h @ AES block 1 - round 14 high + + fmov $ctr_t1d, $input_l1 @ AES block 1 - mov low + eor $input_l0, $input_l0, $rk14_l @ AES block 0 - round 14 low + + eor $input_h0, $input_h0, $rk14_h @ AES block 0 - round 14 high + eor $input_h3, $input_h3, $rk14_h @ AES block 3 - round 14 high + fmov $ctr_t0d, $input_l0 @ AES block 0 - mov low + + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + fmov $ctr_t0.d[1], $input_h0 @ AES block 0 - mov high + eor $input_l3, $input_l3, $rk14_l @ AES block 3 - round 14 low + + eor $input_l2, $input_l2, $rk14_l @ AES block 2 - round 14 low + fmov $ctr_t1.d[1], $input_h1 @ AES block 1 - mov high + + fmov $ctr_t2d, $input_l2 @ AES block 2 - mov low + add $rctr32w, $rctr32w, #1 @ CTR block 4 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + fmov $ctr_t3d, $input_l3 @ AES block 3 - mov low + eor $input_h2, $input_h2, $rk14_h @ AES block 2 - round 14 high + + fmov $ctr_t2.d[1], $input_h2 @ AES block 2 - mov high + + eor $res0b, $ctr_t0b, $ctr0b @ AES block 0 - result + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + add $rctr32w, $rctr32w, #1 @ CTR block 5 + + eor $res1b, $ctr_t1b, $ctr1b @ AES block 1 - result + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + rev $ctr32w, $rctr32w @ CTR block 6 + st1 { $res0b}, [$output_ptr], #16 @ AES block 0 - store result + + fmov $ctr_t3.d[1], $input_h3 @ AES block 3 - mov high + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + eor $res2b, $ctr_t2b, $ctr2b @ AES block 2 - result + + st1 { $res1b}, [$output_ptr], #16 @ AES block 1 - store result + + add $rctr32w, $rctr32w, #1 @ CTR block 6 + fmov $ctr2d, $ctr96_b64x @ CTR block 6 + + fmov $ctr2.d[1], $ctr32x @ CTR block 6 + st1 { $res2b}, [$output_ptr], #16 @ AES block 2 - store result + rev $ctr32w, $rctr32w @ CTR block 7 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 7 + + eor $res3b, $ctr_t3b, $ctr3b @ AES block 3 - result + st1 { $res3b}, [$output_ptr], #16 @ AES block 3 - store result + b.ge L256_enc_prepretail @ do prepretail + + .L256_enc_main_loop: @ main loop start + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + ldp $input_l3, $input_h3, [$input_ptr, #48] @ AES block 4k+7 - load plaintext + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + ldp $input_l2, $input_h2, [$input_ptr, #32] @ AES block 4k+6 - load plaintext + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + eor $res0b, $res0b, $acc_lb @ PRE 1 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $input_l3, $input_l3, $rk14_l @ AES block 4k+7 - round 14 low + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + eor $input_h2, $input_h2, $rk14_h @ AES block 4k+6 - round 14 high + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + ldp $input_l1, $input_h1, [$input_ptr, #16] @ AES block 4k+5 - load plaintext + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + eor $input_l1, $input_l1, $rk14_l @ AES block 4k+5 - round 14 low + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + eor $input_l2, $input_l2, $rk14_l @ AES block 4k+6 - round 14 low + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + movi $mod_constant.8b, #0xc2 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + fmov $ctr_t1d, $input_l1 @ AES block 4k+5 - mov low + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + ldp $input_l0, $input_h0, [$input_ptr, #0] @ AES block 4k+4 - load plaintext + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 11 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 11 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + rev $ctr32w, $rctr32w @ CTR block 4k+8 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + eor $input_l0, $input_l0, $rk14_l @ AES block 4k+4 - round 14 low + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 12 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + eor $input_h0, $input_h0, $rk14_h @ AES block 4k+4 - round 14 high + + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + eor $mod_t.16b, $acc_hb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 12 + eor $input_h1, $input_h1, $rk14_h @ AES block 4k+5 - round 14 high + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 11 + eor $input_h3, $input_h3, $rk14_h @ AES block 4k+7 - round 14 high + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 11 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + + aese $ctr0b, $rk13 @ AES block 4k+4 - round 13 + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 12 + fmov $ctr_t3d, $input_l3 @ AES block 4k+7 - mov low + + aese $ctr1b, $rk13 @ AES block 4k+5 - round 13 + fmov $ctr_t1.d[1], $input_h1 @ AES block 4k+5 - mov high + + fmov $ctr_t2d, $input_l2 @ AES block 4k+6 - mov low + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + + fmov $ctr_t2.d[1], $input_h2 @ AES block 4k+6 - mov high + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + eor $res0b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + rev $ctr32w, $rctr32w @ CTR block 4k+9 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + + eor $res1b, $ctr_t1b, $ctr1b @ AES block 4k+5 - result + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 12 + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + + aese $ctr2b, $rk13 @ AES block 4k+6 - round 13 + rev $ctr32w, $rctr32w @ CTR block 4k+10 + st1 { $res0b}, [$output_ptr], #16 @ AES block 4k+4 - store result + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + fmov $ctr_t3.d[1], $input_h3 @ AES block 4k+7 - mov high + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + st1 { $res1b}, [$output_ptr], #16 @ AES block 4k+5 - store result + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + + aese $ctr3b, $rk13 @ AES block 4k+7 - round 13 + eor $res2b, $ctr_t2b, $ctr2b @ AES block 4k+6 - result + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+10 + + st1 { $res2b}, [$output_ptr], #16 @ AES block 4k+6 - store result + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+10 + rev $ctr32w, $rctr32w @ CTR block 4k+11 + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+11 + + eor $res3b, $ctr_t3b, $ctr3b @ AES block 4k+7 - result + st1 { $res3b}, [$output_ptr], #16 @ AES block 4k+7 - store result + b.lt L256_enc_main_loop + + .L256_enc_prepretail: @ PREPRETAIL + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + rev64 $res2b, $res2b @ GHASH block 4k+2 (t0, t1, and t2 free) + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+3 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + rev64 $res0b, $res0b @ GHASH block 4k (only t0 is free) + + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+3 + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + + eor $res0b, $res0b, $acc_lb @ PRE 1 + rev64 $res1b, $res1b @ GHASH block 4k+1 (t0 and t1 free) + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + rev64 $res3b, $res3b @ GHASH block 4k+3 (t0, t1, t2 and t3 free) + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + add $rctr32w, $rctr32w, #1 @ CTR block 4k+3 + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + movi $mod_constant.8b, #0xc2 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + eor $acc_mb, $acc_mb, $acc_hb @ karatsuba tidy up + + pmull $t1.1q, $acc_h.1d, $mod_constant.1d + ext $acc_hb, $acc_hb, $acc_hb, #8 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + eor $acc_mb, $acc_mb, $acc_lb + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 11 + eor $acc_mb, $acc_mb, $t1.16b + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 12 + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 11 + eor $acc_mb, $acc_mb, $acc_hb + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 11 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 12 + + pmull $t1.1q, $acc_m.1d, $mod_constant.1d + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 11 + ext $acc_mb, $acc_mb, $acc_mb, #8 + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 12 + + aese $ctr1b, $rk13 @ AES block 4k+5 - round 13 + eor $acc_lb, $acc_lb, $t1.16b + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 12 + + aese $ctr3b, $rk13 @ AES block 4k+7 - round 13 + + aese $ctr0b, $rk13 @ AES block 4k+4 - round 13 + + aese $ctr2b, $rk13 @ AES block 4k+6 - round 13 + eor $acc_lb, $acc_lb, $acc_mb + .L256_enc_tail: @ TAIL + + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES block 4k+4 - load plaintext + + eor $input_l0, $input_l0, $rk14_l @ AES block 4k+4 - round 14 low + eor $input_h0, $input_h0, $rk14_h @ AES block 4k+4 - round 14 high + + cmp $main_end_input_ptr, #48 + fmov $ctr_t0d, $input_l0 @ AES block 4k+4 - mov low + + fmov $ctr_t0.d[1], $input_h0 @ AES block 4k+4 - mov high + + eor $res1b, $ctr_t0b, $ctr0b @ AES block 4k+4 - result + b.gt .L256_enc_blocks_more_than_3 + + cmp $main_end_input_ptr, #32 + mov $ctr3b, $ctr2b + movi $acc_l.8b, #0 + + movi $acc_h.8b, #0 + sub $rctr32w, $rctr32w, #1 + + mov $ctr2b, $ctr1b + movi $acc_m.8b, #0 + b.gt .L256_enc_blocks_more_than_2 + + mov $ctr3b, $ctr1b + sub $rctr32w, $rctr32w, #1 + cmp $main_end_input_ptr, #16 + + b.gt .L256_enc_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L256_enc_blocks_less_than_1 + .L256_enc_blocks_more_than_3: @ blocks left > 3 + st1 { $res1b}, [$output_ptr], #16 @ AES final-3 block - store result + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-2 block - load input low & high + + rev64 $res0b, $res1b @ GHASH final-3 block + + eor $input_l0, $input_l0, $rk14_l @ AES final-2 block - round 14 low + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $input_h0, $input_h0, $rk14_h @ AES final-2 block - round 14 high + + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + fmov $res1d, $input_l0 @ AES final-2 block - mov low + + fmov $res1.d[1], $input_h0 @ AES final-2 block - mov high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + movi $t0.8b, #0 @ suppress further partial tag feed in + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + eor $res1b, $res1b, $ctr1b @ AES final-2 block - result + .L256_enc_blocks_more_than_2: @ blocks left > 2 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-2 block - store result + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final-1 block - load input low & high + + rev64 $res0b, $res1b @ GHASH final-2 block + + eor $input_l0, $input_l0, $rk14_l @ AES final-1 block - round 14 low + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + fmov $res1d, $input_l0 @ AES final-1 block - mov low + eor $input_h0, $input_h0, $rk14_h @ AES final-1 block - round 14 high + + fmov $res1.d[1], $input_h0 @ AES final-1 block - mov high + + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + + eor $res1b, $res1b, $ctr2b @ AES final-1 block - result + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + .L256_enc_blocks_more_than_1: @ blocks left > 1 + + st1 { $res1b}, [$output_ptr], #16 @ AES final-1 block - store result + + rev64 $res0b, $res1b @ GHASH final-1 block + + ldp $input_l0, $input_h0, [$input_ptr], #16 @ AES final block - load input low & high + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + movi $t0.8b, #0 @ suppress further partial tag feed in + + eor $input_l0, $input_l0, $rk14_l @ AES final block - round 14 low + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + eor $input_h0, $input_h0, $rk14_h @ AES final block - round 14 high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + fmov $res1d, $input_l0 @ AES final block - mov low + + fmov $res1.d[1], $input_h0 @ AES final block - mov high + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + + eor $res1b, $res1b, $ctr3b @ AES final block - result + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + .L256_enc_blocks_less_than_1: @ blocks left <= 1 + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + mvn $rk14_l, xzr @ rk14_l = 0xffffffffffffffff + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + ld1 { $rk0}, [$output_ptr] @ load existing bytes where the possibly partial last block is to be stored + + mvn $rk14_h, xzr @ rk14_h = 0xffffffffffffffff + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + lsr $rk14_h, $rk14_h, $bit_length @ rk14_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $input_l0, $rk14_l, $rk14_h, lt + csel $input_h0, $rk14_h, xzr, lt + + fmov $ctr0d, $input_l0 @ ctr0b is mask for last block + + fmov $ctr0.d[1], $input_h0 + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + bif $res1b, $rk0, $ctr0b @ insert existing bytes in top end of result before storing + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + mov $t0d, $res0.d[1] @ GHASH final block - mid + rev $ctr32w, $rctr32w + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + str $ctr32w, [$counter, #12] @ store the updated counter + + st1 { $res1b}, [$output_ptr] @ store all 16B + eor $acc_lb, $acc_lb, $acc_hb @ MODULO - fold into low + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L256_enc_ret: + mov w0, #0x0 + ret +.size aes_gcm_enc_256_kernel,.-aes_gcm_enc_256_kernel +___ + +{ +my $t8="v4"; +my $t8d="d4"; +my $t9="v6"; +my $t9d="d6"; +######################################################################################### +# size_t aes_gcm_dec_256_kernel(const unsigned char *in, +# size_t len, +# unsigned char *out, +# const void *key, +# unsigned char ivec[16], +# u64 *Xi); +# +$code.=<<___; +.global aes_gcm_dec_256_kernel +.type aes_gcm_dec_256_kernel,%function +.align 4 +aes_gcm_dec_256_kernel: + cbz x1, .L256_dec_ret + stp x19, x20, [sp, #-112]! + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp d8, d9, [sp, #48] + stp d10, d11, [sp, #64] + stp d12, d13, [sp, #80] + stp d14, d15, [sp, #96] + + lsr $main_end_input_ptr, $bit_length, #3 @ byte_len + mov $len, $main_end_input_ptr + ldp $ctr96_b64x, $ctr96_t32x, [$counter] @ ctr96_b64, ctr96_t32 + + ldr $rk8q, [$cc, #128] @ load rk8 + sub $main_end_input_ptr, $main_end_input_ptr, #1 @ byte_len - 1 + + ldr $rk7q, [$cc, #112] @ load rk7 + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 @ number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 @ end_input_ptr + ldr $rk6q, [$cc, #96] @ load rk6 + + lsr $rctr32x, $ctr96_t32x, #32 + ldr $rk5q, [$cc, #80] @ load rk5 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + + ldr $rk3q, [$cc, #48] @ load rk3 + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + rev $rctr32w, $rctr32w @ rev_ctr32 + + add $rctr32w, $rctr32w, #1 @ increment rev_ctr32 + fmov $ctr3d, $ctr96_b64x @ CTR block 3 + + rev $ctr32w, $rctr32w @ CTR block 1 + add $rctr32w, $rctr32w, #1 @ CTR block 1 + fmov $ctr1d, $ctr96_b64x @ CTR block 1 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 1 + ld1 { $ctr0b}, [$counter] @ special case vector load initial counter so we can start first AES block as quickly as possible + + fmov $ctr1.d[1], $ctr32x @ CTR block 1 + rev $ctr32w, $rctr32w @ CTR block 2 + add $rctr32w, $rctr32w, #1 @ CTR block 2 + + fmov $ctr2d, $ctr96_b64x @ CTR block 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 2 + + fmov $ctr2.d[1], $ctr32x @ CTR block 2 + rev $ctr32w, $rctr32w @ CTR block 3 + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 3 + ldr $rk0q, [$cc, #0] @ load rk0 + + fmov $ctr3.d[1], $ctr32x @ CTR block 3 + add $rctr32w, $rctr32w, #1 @ CTR block 3 + + ldr $rk4q, [$cc, #64] @ load rk4 + + ldr $rk13q, [$cc, #208] @ load rk13 + + ldr $rk1q, [$cc, #16] @ load rk1 + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 0 + ldr $h3q, [$current_tag, #80] @ load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 0 + ldr $h4q, [$current_tag, #112] @ load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 0 + ldr $h2q, [$current_tag, #64] @ load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 0 + ldr $rk2q, [$cc, #32] @ load rk2 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 1 + ldp $rk14_l, $rk14_h, [$cc, #224] @ load rk14 + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 1 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 1 + ldr $rk9q, [$cc, #144] @ load rk9 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 1 + ldr $rk12q, [$cc, #192] @ load rk12 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 2 + ldr $h1q, [$current_tag, #32] @ load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 2 + ldr $rk10q, [$cc, #160] @ load rk10 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 2 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 3 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 2 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 3 + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 4 + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 4 blocks + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 3 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 3 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 4 + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 4 + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 4 + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 5 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 5 + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 5 + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 5 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 6 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 6 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 6 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 6 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 7 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 7 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 7 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 8 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 7 + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 8 + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 8 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 9 + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 8 + ldr $rk11q, [$cc, #176] @ load rk11 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 9 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 10 + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 9 + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 10 + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 9 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 10 + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 11 + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 10 + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 11 + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 11 + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 11 + + trn1 $acc_h.2d, $h3.2d, $h4.2d @ h4h | h3h + + trn2 $h34k.2d, $h3.2d, $h4.2d @ h4l | h3l + + trn1 $t0.2d, $h1.2d, $h2.2d @ h2h | h1h + trn2 $h12k.2d, $h1.2d, $h2.2d @ h2l | h1l + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 1 - round 12 + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 0 - round 12 + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 2 - round 12 + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 3 - round 12 + eor $h34k.16b, $h34k.16b, $acc_h.16b @ h4k | h3k + + aese $ctr1b, $rk13 @ AES block 1 - round 13 + + aese $ctr2b, $rk13 @ AES block 2 - round 13 + eor $h12k.16b, $h12k.16b, $t0.16b @ h2k | h1k + + aese $ctr3b, $rk13 @ AES block 3 - round 13 + + aese $ctr0b, $rk13 @ AES block 0 - round 13 + b.ge .L256_dec_tail @ handle tail + + ldr $res0q, [$input_ptr, #0] @ AES block 0 - load ciphertext + + ldr $res1q, [$input_ptr, #16] @ AES block 1 - load ciphertext + + rev $ctr32w, $rctr32w @ CTR block 4 + + eor $ctr0b, $res0b, $ctr0b @ AES block 0 - result + + eor $ctr1b, $res1b, $ctr1b @ AES block 1 - result + rev64 $res1b, $res1b @ GHASH block 1 + ldr $res3q, [$input_ptr, #48] @ AES block 3 - load ciphertext + + mov $output_h0, $ctr0.d[1] @ AES block 0 - mov high + + mov $output_l0, $ctr0.d[0] @ AES block 0 - mov low + rev64 $res0b, $res0b @ GHASH block 0 + add $rctr32w, $rctr32w, #1 @ CTR block 4 + + fmov $ctr0d, $ctr96_b64x @ CTR block 4 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4 + + fmov $ctr0.d[1], $ctr32x @ CTR block 4 + rev $ctr32w, $rctr32w @ CTR block 5 + add $rctr32w, $rctr32w, #1 @ CTR block 5 + + mov $output_l1, $ctr1.d[0] @ AES block 1 - mov low + + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 5 + mov $output_h1, $ctr1.d[1] @ AES block 1 - mov high + eor $output_h0, $output_h0, $rk14_h @ AES block 0 - round 14 high + + eor $output_l0, $output_l0, $rk14_l @ AES block 0 - round 14 low + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 0 - store result + fmov $ctr1d, $ctr96_b64x @ CTR block 5 + + ldr $res2q, [$input_ptr, #32] @ AES block 2 - load ciphertext + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + + fmov $ctr1.d[1], $ctr32x @ CTR block 5 + rev $ctr32w, $rctr32w @ CTR block 6 + add $rctr32w, $rctr32w, #1 @ CTR block 6 + + eor $output_l1, $output_l1, $rk14_l @ AES block 1 - round 14 low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 6 + + eor $output_h1, $output_h1, $rk14_h @ AES block 1 - round 14 high + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 1 - store result + + eor $ctr2b, $res2b, $ctr2b @ AES block 2 - result + cmp $input_ptr, $main_end_input_ptr @ check if we have <= 8 blocks + b.ge .L256_dec_prepretail @ do prepretail + + .L256_dec_main_loop: @ main loop start + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + eor $res0b, $res0b, $acc_lb @ PRE 1 + rev $ctr32w, $rctr32w @ CTR block 4k+7 + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + eor $output_h2, $output_h2, $rk14_h @ AES block 4k+2 - round 14 high + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + rev64 $res2b, $res2b @ GHASH block 4k+2 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + eor $output_l2, $output_l2, $rk14_l @ AES block 4k+2 - round 14 low + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + rev64 $res3b, $res3b @ GHASH block 4k+3 + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + eor $output_l3, $output_l3, $rk14_l @ AES block 4k+3 - round 14 low + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + eor $output_h3, $output_h3, $rk14_h @ AES block 4k+3 - round 14 high + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + rev $ctr32w, $rctr32w @ CTR block 4k+8 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+8 + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+8 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + movi $mod_constant.8b, #0xc2 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 11 + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 12 + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + ldr $res0q, [$input_ptr, #0] @ AES block 4k+4 - load ciphertext + + aese $ctr0b, $rk13 @ AES block 4k+4 - round 13 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + ldr $res1q, [$input_ptr, #16] @ AES block 4k+5 - load ciphertext + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + eor $ctr0b, $res0b, $ctr0b @ AES block 4k+4 - result + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 11 + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + ldr $res3q, [$input_ptr, #48] @ AES block 4k+7 - load ciphertext + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 12 + ldr $res2q, [$input_ptr, #32] @ AES block 4k+6 - load ciphertext + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 11 + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr1b, $rk13 @ AES block 4k+5 - round 13 + add $input_ptr, $input_ptr, #64 @ AES input_ptr update + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 12 + fmov $ctr0d, $ctr96_b64x @ CTR block 4k+8 + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 11 + fmov $ctr0.d[1], $ctr32x @ CTR block 4k+8 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + eor $ctr1b, $res1b, $ctr1b @ AES block 4k+5 - result + rev $ctr32w, $rctr32w @ CTR block 4k+9 + + aese $ctr2b, $rk13 @ AES block 4k+6 - round 13 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+9 + cmp $input_ptr, $main_end_input_ptr @ LOOP CONTROL + + add $rctr32w, $rctr32w, #1 @ CTR block 4k+9 + + eor $output_l0, $output_l0, $rk14_l @ AES block 4k+4 - round 14 low + eor $output_h0, $output_h0, $rk14_h @ AES block 4k+4 - round 14 high + + mov $output_h1, $ctr1.d[1] @ AES block 4k+5 - mov high + eor $ctr2b, $res2b, $ctr2b @ AES block 4k+6 - result + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 12 + mov $output_l1, $ctr1.d[0] @ AES block 4k+5 - mov low + + fmov $ctr1d, $ctr96_b64x @ CTR block 4k+9 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + fmov $ctr1.d[1], $ctr32x @ CTR block 4k+9 + rev $ctr32w, $rctr32w @ CTR block 4k+10 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+10 + + aese $ctr3b, $rk13 @ AES block 4k+7 - round 13 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+10 + + rev64 $res1b, $res1b @ GHASH block 4k+5 + eor $output_h1, $output_h1, $rk14_h @ AES block 4k+5 - round 14 high + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES block 4k+4 - store result + + eor $output_l1, $output_l1, $rk14_l @ AES block 4k+5 - round 14 low + stp $output_l1, $output_h1, [$output_ptr], #16 @ AES block 4k+5 - store result + + rev64 $res0b, $res0b @ GHASH block 4k+4 + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + b.lt .L256_dec_main_loop + + + .L256_dec_prepretail: @ PREPRETAIL + ext $acc_lb, $acc_lb, $acc_lb, #8 @ PRE 0 + mov $output_l2, $ctr2.d[0] @ AES block 4k+2 - mov low + eor $ctr3b, $res3b, $ctr3b @ AES block 4k+3 - result + + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 0 + mov $output_h2, $ctr2.d[1] @ AES block 4k+2 - mov high + + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 0 + fmov $ctr2d, $ctr96_b64x @ CTR block 4k+6 + + fmov $ctr2.d[1], $ctr32x @ CTR block 4k+6 + rev $ctr32w, $rctr32w @ CTR block 4k+7 + eor $res0b, $res0b, $acc_lb @ PRE 1 + + rev64 $res2b, $res2b @ GHASH block 4k+2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 @ CTR block 4k+7 + mov $output_l3, $ctr3.d[0] @ AES block 4k+3 - mov low + + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 1 + mov $output_h3, $ctr3.d[1] @ AES block 4k+3 - mov high + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH block 4k - low + mov $t0d, $res0.d[1] @ GHASH block 4k - mid + fmov $ctr3d, $ctr96_b64x @ CTR block 4k+7 + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH block 4k - high + fmov $ctr3.d[1], $ctr32x @ CTR block 4k+7 + + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 0 + mov $acc_md, $h34k.d[1] @ GHASH block 4k - mid + + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 1 + eor $t0.8b, $t0.8b, $res0.8b @ GHASH block 4k - mid + + pmull2 $t1.1q, $res1.2d, $h3.2d @ GHASH block 4k+1 - high + + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 1 + rev64 $res3b, $res3b @ GHASH block 4k+3 + + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 0 + + pmull $acc_m.1q, $t0.1d, $acc_m.1d @ GHASH block 4k - mid + eor $acc_hb, $acc_hb, $t1.16b @ GHASH block 4k+1 - high + + pmull $t2.1q, $res1.1d, $h3.1d @ GHASH block 4k+1 - low + + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 1 + mov $t3d, $res1.d[1] @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 2 + + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 2 + eor $acc_lb, $acc_lb, $t2.16b @ GHASH block 4k+1 - low + + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 2 + + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 3 + mov $t6d, $res2.d[1] @ GHASH block 4k+2 - mid + + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 2 + eor $t3.8b, $t3.8b, $res1.8b @ GHASH block 4k+1 - mid + + pmull $t5.1q, $res2.1d, $h2.1d @ GHASH block 4k+2 - low + + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 4 + + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 3 + eor $t6.8b, $t6.8b, $res2.8b @ GHASH block 4k+2 - mid + + pmull $t3.1q, $t3.1d, $h34k.1d @ GHASH block 4k+1 - mid + + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 5 + eor $acc_lb, $acc_lb, $t5.16b @ GHASH block 4k+2 - low + + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 4 + + pmull2 $t7.1q, $res3.2d, $h1.2d @ GHASH block 4k+3 - high + eor $acc_mb, $acc_mb, $t3.16b @ GHASH block 4k+1 - mid + + pmull2 $t4.1q, $res2.2d, $h2.2d @ GHASH block 4k+2 - high + + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 5 + ins $t6.d[1], $t6.d[0] @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 3 + + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 3 + eor $acc_hb, $acc_hb, $t4.16b @ GHASH block 4k+2 - high + + pmull $t8.1q, $res3.1d, $h1.1d @ GHASH block 4k+3 - low + + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 4 + mov $t9d, $res3.d[1] @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 4 + + pmull2 $t6.1q, $t6.2d, $h12k.2d @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 5 + eor $t9.8b, $t9.8b, $res3.8b @ GHASH block 4k+3 - mid + + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 5 + + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 6 + eor $acc_mb, $acc_mb, $t6.16b @ GHASH block 4k+2 - mid + + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 6 + + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 6 + movi $mod_constant.8b, #0xc2 + + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 6 + eor $acc_lb, $acc_lb, $t8.16b @ GHASH block 4k+3 - low + + pmull $t9.1q, $t9.1d, $h12k.1d @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 7 + eor $acc_hb, $acc_hb, $t7.16b @ GHASH block 4k+3 - high + + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 7 + + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 7 + eor $acc_mb, $acc_mb, $t9.16b @ GHASH block 4k+3 - mid + + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 8 + + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 7 + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 8 + + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 8 + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 8 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 9 + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 9 + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 9 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 9 + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 10 + + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 10 + + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 10 + eor $output_h2, $output_h2, $rk14_h @ AES block 4k+2 - round 14 high + + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 10 + eor $output_l3, $output_l3, $rk14_l @ AES block 4k+3 - round 14 low + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 11 + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 11 + add $rctr32w, $rctr32w, #1 @ CTR block 4k+7 + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 11 + eor $output_l2, $output_l2, $rk14_l @ AES block 4k+2 - round 14 low + + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b @ AES block 4k+6 - round 12 + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + eor $output_h3, $output_h3, $rk14_h @ AES block 4k+3 - round 14 high + + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 11 + stp $output_l2, $output_h2, [$output_ptr], #16 @ AES block 4k+2 - store result + + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b @ AES block 4k+5 - round 12 + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b @ AES block 4k+4 - round 12 + stp $output_l3, $output_h3, [$output_ptr], #16 @ AES block 4k+3 - store result + + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b @ AES block 4k+7 - round 12 + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + aese $ctr1b, $rk13 @ AES block 4k+5 - round 13 + + aese $ctr0b, $rk13 @ AES block 4k+4 - round 13 + + aese $ctr3b, $rk13 @ AES block 4k+7 - round 13 + + aese $ctr2b, $rk13 @ AES block 4k+6 - round 13 + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + .L256_dec_tail: @ TAIL + + sub $main_end_input_ptr, $end_input_ptr, $input_ptr @ main_end_input_ptr is number of bytes left to process + ld1 { $res1b}, [$input_ptr], #16 @ AES block 4k+4 - load ciphertext + + eor $ctr0b, $res1b, $ctr0b @ AES block 4k+4 - result + + mov $output_l0, $ctr0.d[0] @ AES block 4k+4 - mov low + + mov $output_h0, $ctr0.d[1] @ AES block 4k+4 - mov high + ext $t0.16b, $acc_lb, $acc_lb, #8 @ prepare final partial tag + + cmp $main_end_input_ptr, #48 + + eor $output_l0, $output_l0, $rk14_l @ AES block 4k+4 - round 14 low + + eor $output_h0, $output_h0, $rk14_h @ AES block 4k+4 - round 14 high + b.gt .L256_dec_blocks_more_than_3 + + sub $rctr32w, $rctr32w, #1 + mov $ctr3b, $ctr2b + movi $acc_m.8b, #0 + + movi $acc_l.8b, #0 + cmp $main_end_input_ptr, #32 + + movi $acc_h.8b, #0 + mov $ctr2b, $ctr1b + b.gt .L256_dec_blocks_more_than_2 + + sub $rctr32w, $rctr32w, #1 + + mov $ctr3b, $ctr1b + cmp $main_end_input_ptr, #16 + b.gt .L256_dec_blocks_more_than_1 + + sub $rctr32w, $rctr32w, #1 + b .L256_dec_blocks_less_than_1 + .L256_dec_blocks_more_than_3: @ blocks left > 3 + rev64 $res0b, $res1b @ GHASH final-3 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-2 block - load ciphertext + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-3 block - store result + + mov $acc_md, $h34k.d[1] @ GHASH final-3 block - mid + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + eor $ctr0b, $res1b, $ctr1b @ AES final-2 block - result + + mov $rk4d, $res0.d[1] @ GHASH final-3 block - mid + + mov $output_l0, $ctr0.d[0] @ AES final-2 block - mov low + + mov $output_h0, $ctr0.d[1] @ AES final-2 block - mov high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-3 block - mid + + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull2 $acc_h.1q, $res0.2d, $h4.2d @ GHASH final-3 block - high + + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-3 block - mid + eor $output_l0, $output_l0, $rk14_l @ AES final-2 block - round 14 low + + pmull $acc_l.1q, $res0.1d, $h4.1d @ GHASH final-3 block - low + eor $output_h0, $output_h0, $rk14_h @ AES final-2 block - round 14 high + .L256_dec_blocks_more_than_2: @ blocks left > 2 + + rev64 $res0b, $res1b @ GHASH final-2 block + ld1 { $res1b}, [$input_ptr], #16 @ AES final-1 block - load ciphertext + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-2 block - store result + + eor $ctr0b, $res1b, $ctr2b @ AES final-1 block - result + + mov $rk4d, $res0.d[1] @ GHASH final-2 block - mid + + pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low + + pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid + mov $output_l0, $ctr0.d[0] @ AES final-1 block - mov low + + mov $output_h0, $ctr0.d[1] @ AES final-1 block - mov high + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low + movi $t0.8b, #0 @ suppress further partial tag feed in + + pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-2 block - high + eor $output_l0, $output_l0, $rk14_l @ AES final-1 block - round 14 low + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-2 block - mid + eor $output_h0, $output_h0, $rk14_h @ AES final-1 block - round 14 high + .L256_dec_blocks_more_than_1: @ blocks left > 1 + + stp $output_l0, $output_h0, [$output_ptr], #16 @ AES final-1 block - store result + rev64 $res0b, $res1b @ GHASH final-1 block + + ld1 { $res1b}, [$input_ptr], #16 @ AES final block - load ciphertext + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + movi $t0.8b, #0 @ suppress further partial tag feed in + + mov $rk4d, $res0.d[1] @ GHASH final-1 block - mid + + eor $ctr0b, $res1b, $ctr3b @ AES final block - result + + pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high + + eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-1 block - mid + + pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low + mov $output_l0, $ctr0.d[0] @ AES final block - mov low + + ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-1 block - mid + + mov $output_h0, $ctr0.d[1] @ AES final block - mov high + + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid + eor $output_l0, $output_l0, $rk14_l @ AES final block - round 14 low + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final-1 block - low + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high + + eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid + eor $output_h0, $output_h0, $rk14_h @ AES final block - round 14 high + .L256_dec_blocks_less_than_1: @ blocks left <= 1 + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + mvn $rk14_h, xzr @ rk14_h = 0xffffffffffffffff + + sub $bit_length, $bit_length, #128 @ bit_length -= 128 + mvn $rk14_l, xzr @ rk14_l = 0xffffffffffffffff + + ldp $end_input_ptr, $main_end_input_ptr, [$output_ptr] @ load existing bytes we need to not overwrite + neg $bit_length, $bit_length @ bit_length = 128 - #bits in input (in range [1,128]) + + and $bit_length, $bit_length, #127 @ bit_length %= 128 + + lsr $rk14_h, $rk14_h, $bit_length @ rk14_h is mask for top 64b of last block + cmp $bit_length, #64 + + csel $ctr32x, $rk14_l, $rk14_h, lt + csel $ctr96_b64x, $rk14_h, xzr, lt + + fmov $ctr0d, $ctr32x @ ctr0b is mask for last block + and $output_l0, $output_l0, $ctr32x + + mov $ctr0.d[1], $ctr96_b64x + bic $end_input_ptr, $end_input_ptr, $ctr32x @ mask out low existing bytes + + rev $ctr32w, $rctr32w + + bic $main_end_input_ptr, $main_end_input_ptr, $ctr96_b64x @ mask out high existing bytes + + orr $output_l0, $output_l0, $end_input_ptr + + and $output_h0, $output_h0, $ctr96_b64x + + orr $output_h0, $output_h0, $main_end_input_ptr + + and $res1b, $res1b, $ctr0b @ possibly partial last block has zeroes in highest bits + + rev64 $res0b, $res1b @ GHASH final block + + eor $res0b, $res0b, $t0.16b @ feed in partial tag + + pmull $rk3q1, $res0.1d, $h1.1d @ GHASH final block - low + + mov $t0d, $res0.d[1] @ GHASH final block - mid + + eor $t0.8b, $t0.8b, $res0.8b @ GHASH final block - mid + + pmull2 $rk2q1, $res0.2d, $h1.2d @ GHASH final block - high + + pmull $t0.1q, $t0.1d, $h12k.1d @ GHASH final block - mid + + eor $acc_hb, $acc_hb, $rk2 @ GHASH final block - high + + eor $acc_lb, $acc_lb, $rk3 @ GHASH final block - low + + eor $acc_mb, $acc_mb, $t0.16b @ GHASH final block - mid + movi $mod_constant.8b, #0xc2 + + eor $t9.16b, $acc_lb, $acc_hb @ MODULO - karatsuba tidy up + + shl $mod_constantd, $mod_constantd, #56 @ mod_constant + + eor $acc_mb, $acc_mb, $t9.16b @ MODULO - karatsuba tidy up + + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d @ MODULO - top 64b align with mid + + ext $acc_hb, $acc_hb, $acc_hb, #8 @ MODULO - other top alignment + + eor $acc_mb, $acc_mb, $mod_t.16b @ MODULO - fold into mid + + eor $acc_mb, $acc_mb, $acc_hb @ MODULO - fold into mid + + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d @ MODULO - mid 64b align with low + + ext $acc_mb, $acc_mb, $acc_mb, #8 @ MODULO - other mid alignment + + eor $acc_lb, $acc_lb, $mod_constant.16b @ MODULO - fold into low + + stp $output_l0, $output_h0, [$output_ptr] + + str $ctr32w, [$counter, #12] @ store the updated counter + + eor $acc_lb, $acc_lb, $acc_mb @ MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp d8, d9, [sp, #48] + ldp d10, d11, [sp, #64] + ldp d12, d13, [sp, #80] + ldp d14, d15, [sp, #96] + ldp x19, x20, [sp], #112 + ret + +.L256_dec_ret: + mov w0, #0x0 + ret +.size aes_gcm_dec_256_kernel,.-aes_gcm_dec_256_kernel +___ +} +} + +$code.=<<___; +.asciz "GHASH for ARMv8, CRYPTOGAMS by " +.align 2 +#endif +___ + +if ($flavour =~ /64/) { ######## 64-bit code + sub unvmov { + my $arg=shift; + + $arg =~ m/q([0-9]+)#(lo|hi),\s*q([0-9]+)#(lo|hi)/o && + sprintf "ins v%d.d[%d],v%d.d[%d]",$1<8?$1:$1+8,($2 eq "lo")?0:1, + $3<8?$3:$3+8,($4 eq "lo")?0:1; + } + foreach(split("\n",$code)) { + s/@\s/\/\//o; # old->new style commentary + print $_,"\n"; + } +} else { ######## 32-bit code + sub unvdup32 { + my $arg=shift; + + $arg =~ m/q([0-9]+),\s*q([0-9]+)\[([0-3])\]/o && + sprintf "vdup.32 q%d,d%d[%d]",$1,2*$2+($3>>1),$3&1; + } + sub unvpmullp64 { + my ($mnemonic,$arg)=@_; + + if ($arg =~ m/q([0-9]+),\s*q([0-9]+),\s*q([0-9]+)/o) { + my $word = 0xf2a00e00|(($1&7)<<13)|(($1&8)<<19) + |(($2&7)<<17)|(($2&8)<<4) + |(($3&7)<<1) |(($3&8)<<2); + $word |= 0x00010001 if ($mnemonic =~ "2"); + # since ARMv7 instructions are always encoded little-endian. + # correct solution is to use .inst directive, but older%%%% + # assemblers don't implement it:-( + sprintf "INST(0x%02x,0x%02x,0x%02x,0x%02x)\t@ %s %s", + $word&0xff,($word>>8)&0xff, + ($word>>16)&0xff,($word>>24)&0xff, + $mnemonic,$arg; + } + } + + foreach(split("\n",$code)) { + s/\b[wx]([0-9]+)\b/r$1/go; # new->old registers + s/\bv([0-9])\.[12468]+[bsd]\b/q$1/go; # new->old registers + s/\/\/\s?/@ /o; # new->old style commentary + + # fix up remaining new-style suffixes + s/\],#[0-9]+/]!/o; + + s/cclr\s+([^,]+),\s*([a-z]+)/mov.$2 $1,#0/o or + s/vdup\.32\s+(.*)/unvdup32($1)/geo or + s/v?(pmull2?)\.p64\s+(.*)/unvpmullp64($1,$2)/geo or + s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo or + s/^(\s+)b\./$1b/o or + s/^(\s+)ret/$1bx\tlr/o; + + if (s/^(\s+)mov\.([a-z]+)/$1mov$2/) { + print " it $2\n"; + } + + print $_,"\n"; + } +} + +close STDOUT or die "error closing STDOUT: $!"; # enforce flush diff --git a/crypto/openssl/crypto/modes/asm/aesni-gcm-x86_64.pl b/crypto/openssl/crypto/modes/asm/aesni-gcm-x86_64.pl index 60f03e4fe25b..eaf4d9c755fb 100755 --- a/crypto/openssl/crypto/modes/asm/aesni-gcm-x86_64.pl +++ b/crypto/openssl/crypto/modes/asm/aesni-gcm-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -40,9 +40,10 @@ # [1] http://rt.openssl.org/Ticket/Display.html?id=2900&user=guest&pass=guest # [2] http://www.intel.com/content/dam/www/public/us/en/documents/software-support/enabling-high-performance-gcm.pdf -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -70,7 +71,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0 $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if ($avx>1) {{{ diff --git a/crypto/openssl/crypto/modes/asm/ghash-armv4.pl b/crypto/openssl/crypto/modes/asm/ghash-armv4.pl index d84ac6f2bf43..044f86f143f9 100755 --- a/crypto/openssl/crypto/modes/asm/ghash-armv4.pl +++ b/crypto/openssl/crypto/modes/asm/ghash-armv4.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -78,9 +78,10 @@ # *native* byte order on current platform. See gcm128.c for working # example... -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -88,9 +89,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $Xi="r0"; # argument block @@ -142,7 +144,6 @@ ___ $code=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) || defined(__clang__) .syntax unified #define ldrplb ldrbpl @@ -154,6 +155,8 @@ $code=<<___; .code 32 #endif +.text + .type rem_4bit,%object .align 5 rem_4bit: diff --git a/crypto/openssl/crypto/modes/asm/ghash-c64xplus.pl b/crypto/openssl/crypto/modes/asm/ghash-c64xplus.pl index 5826dcbdfe64..ded2f779e669 100755 --- a/crypto/openssl/crypto/modes/asm/ghash-c64xplus.pl +++ b/crypto/openssl/crypto/modes/asm/ghash-c64xplus.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -26,8 +26,7 @@ # better, because theoretical [though not necessarily achievable] # estimate for "4-bit" table-driven implementation is ~12 cycles. -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; ($Xip,$Htable,$inp,$len)=("A4","B4","A6","B6"); # arguments diff --git a/crypto/openssl/crypto/modes/asm/ghash-ia64.pl b/crypto/openssl/crypto/modes/asm/ghash-ia64.pl index 6e29f995fa85..74b88176b842 100755 --- a/crypto/openssl/crypto/modes/asm/ghash-ia64.pl +++ b/crypto/openssl/crypto/modes/asm/ghash-ia64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 diff --git a/crypto/openssl/crypto/modes/asm/ghash-parisc.pl b/crypto/openssl/crypto/modes/asm/ghash-parisc.pl index d798b7abf490..7b5cc2f16e38 100755 --- a/crypto/openssl/crypto/modes/asm/ghash-parisc.pl +++ b/crypto/openssl/crypto/modes/asm/ghash-parisc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -27,9 +27,12 @@ # # Special thanks to polarhome.com for providing HP-UX account. -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/openssl/crypto/modes/asm/ghash-s390x.pl b/crypto/openssl/crypto/modes/asm/ghash-s390x.pl index 2f3ca295bdca..ba9c5b4a4f4f 100755 --- a/crypto/openssl/crypto/modes/asm/ghash-s390x.pl +++ b/crypto/openssl/crypto/modes/asm/ghash-s390x.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -44,7 +44,10 @@ # it's actually almost 2 times slower. Which is the reason why # KIMD-GHASH is not used in gcm_gmult_4bit. -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -54,8 +57,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $softonly=0; diff --git a/crypto/openssl/crypto/modes/asm/ghash-sparcv9.pl b/crypto/openssl/crypto/modes/asm/ghash-sparcv9.pl index ccebc74b4e97..e35064237f46 100755 --- a/crypto/openssl/crypto/modes/asm/ghash-sparcv9.pl +++ b/crypto/openssl/crypto/modes/asm/ghash-sparcv9.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -53,8 +53,7 @@ # saturates at ~15.5x single-process result on 8-core processor, # or ~20.5GBps per 2.85GHz socket. -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; $frame="STACK_FRAME"; $bias="STACK_BIAS"; @@ -81,7 +80,10 @@ $inp="%i2"; $len="%i3"; $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #ifdef __arch64__ .register %g2,#scratch diff --git a/crypto/openssl/crypto/modes/asm/ghash-x86.pl b/crypto/openssl/crypto/modes/asm/ghash-x86.pl index 4183d99b68b1..c796107c7f97 100755 --- a/crypto/openssl/crypto/modes/asm/ghash-x86.pl +++ b/crypto/openssl/crypto/modes/asm/ghash-x86.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -135,8 +135,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$x86only = $ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/modes/asm/ghash-x86_64.pl b/crypto/openssl/crypto/modes/asm/ghash-x86_64.pl index 9bdba41d1de5..6709f96492ed 100755 --- a/crypto/openssl/crypto/modes/asm/ghash-x86_64.pl +++ b/crypto/openssl/crypto/modes/asm/ghash-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -90,9 +90,10 @@ # # [1] http://rt.openssl.org/Ticket/Display.html?id=2900&user=guest&pass=guest -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -120,7 +121,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0 $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $do4xaggr=1; @@ -239,6 +241,7 @@ $code=<<___; .align 16 gcm_gmult_4bit: .cfi_startproc + endbranch push %rbx .cfi_push %rbx push %rbp # %rbp and others are pushed exclusively in @@ -286,6 +289,7 @@ $code.=<<___; .align 16 gcm_ghash_4bit: .cfi_startproc + endbranch push %rbx .cfi_push %rbx push %rbp @@ -612,6 +616,7 @@ $code.=<<___; .align 16 gcm_gmult_clmul: .cfi_startproc + endbranch .L_gmult_clmul: movdqu ($Xip),$Xi movdqa .Lbswap_mask(%rip),$T3 @@ -663,6 +668,7 @@ $code.=<<___; .align 32 gcm_ghash_clmul: .cfi_startproc + endbranch .L_ghash_clmul: ___ $code.=<<___ if ($win64); @@ -1166,6 +1172,7 @@ $code.=<<___; .align 32 gcm_gmult_avx: .cfi_startproc + endbranch jmp .L_gmult_clmul .cfi_endproc .size gcm_gmult_avx,.-gcm_gmult_avx @@ -1177,6 +1184,7 @@ $code.=<<___; .align 32 gcm_ghash_avx: .cfi_startproc + endbranch ___ if ($avx) { my ($Xip,$Htbl,$inp,$len)=@_4args; diff --git a/crypto/openssl/crypto/modes/asm/ghashp8-ppc.pl b/crypto/openssl/crypto/modes/asm/ghashp8-ppc.pl index 447472cb4592..20f611dabd43 100755 --- a/crypto/openssl/crypto/modes/asm/ghashp8-ppc.pl +++ b/crypto/openssl/crypto/modes/asm/ghashp8-ppc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -32,8 +32,10 @@ # aggregated reduction - by 170% or 2.7x (resulting in 0.55 cpb). # POWER9 delivers 0.51 cpb. -$flavour=shift; -$output =shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T=8; @@ -61,7 +63,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; my ($Xip,$Htbl,$inp,$len)=map("r$_",(3..6)); # argument block diff --git a/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl b/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl old mode 100755 new mode 100644 index 2072e49bdeea..b1d35d25b5b1 --- a/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl +++ b/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -42,18 +42,22 @@ # Denver 0.51 0.65 6.02 # Mongoose 0.65 1.10 8.06 # Kryo 0.76 1.16 8.00 +# ThunderX2 1.05 # # (*) presented for reference/comparison purposes; -$flavour = shift; -$output = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $Xi="x0"; # argument block @@ -66,18 +70,26 @@ $inc="x12"; { my ($Xl,$Xm,$Xh,$IN)=map("q$_",(0..3)); my ($t0,$t1,$t2,$xC2,$H,$Hhl,$H2)=map("q$_",(8..14)); +my $_byte = ($flavour =~ /win/ ? "DCB" : ".byte"); $code=<<___; #include "arm_arch.h" #if __ARM_MAX_ARCH__>=7 -.text ___ -# $code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/); -$code.=<<___ if ($flavour !~ /64/); +$code.=".arch armv8-a+crypto\n.text\n" if ($flavour =~ /64/); +$code.=<<___ if ($flavour !~ /64/); .fpu neon -.code 32 -#undef __thumb2__ +#ifdef __thumb2__ +.syntax unified +.thumb +# define INST(a,b,c,d) $_byte c,0xef,a,b +#else +.code 32 +# define INST(a,b,c,d) $_byte a,b,c,0xf2 +#endif + +.text ___ ################################################################################ @@ -752,7 +764,7 @@ if ($flavour =~ /64/) { ######## 64-bit code # since ARMv7 instructions are always encoded little-endian. # correct solution is to use .inst directive, but older # assemblers don't implement it:-( - sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s", + sprintf "INST(0x%02x,0x%02x,0x%02x,0x%02x)\t@ %s %s", $word&0xff,($word>>8)&0xff, ($word>>16)&0xff,($word>>24)&0xff, $mnemonic,$arg; @@ -767,13 +779,17 @@ if ($flavour =~ /64/) { ######## 64-bit code # fix up remaining new-style suffixes s/\],#[0-9]+/]!/o; - s/cclr\s+([^,]+),\s*([a-z]+)/mov$2 $1,#0/o or + s/cclr\s+([^,]+),\s*([a-z]+)/mov.$2 $1,#0/o or s/vdup\.32\s+(.*)/unvdup32($1)/geo or s/v?(pmull2?)\.p64\s+(.*)/unvpmullp64($1,$2)/geo or s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo or s/^(\s+)b\./$1b/o or s/^(\s+)ret/$1bx\tlr/o; + if (s/^(\s+)mov\.([a-z]+)/$1mov$2/) { + print " it $2\n"; + } + print $_,"\n"; } } diff --git a/crypto/openssl/crypto/modes/build.info b/crypto/openssl/crypto/modes/build.info index 821340eb909a..f3558fa1a465 100644 --- a/crypto/openssl/crypto/modes/build.info +++ b/crypto/openssl/crypto/modes/build.info @@ -1,30 +1,82 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - cbc128.c ctr128.c cts128.c cfb128.c ofb128.c gcm128.c \ - ccm128.c xts128.c wrap128.c ocb128.c \ - {- $target{modes_asm_src} -} + +$MODESASM= +IF[{- !$disabled{asm} -}] + $MODESASM_x86=ghash-x86.S + $MODESDEF_x86=GHASH_ASM + $MODESASM_x86_64=ghash-x86_64.s aesni-gcm-x86_64.s + $MODESDEF_x86_64=GHASH_ASM + + # ghash-ia64.s doesn't work on VMS + IF[{- $config{target} !~ /^vms-/ -}] + $MODESASM_ia64=ghash-ia64.s + $MODESDEF_ia64=GHASH_ASM + ENDIF + + $MODESASM_sparcv9=ghash-sparcv9.S + $MODESDEF_sparcv9=GHASH_ASM + + $MODESASM_alpha=ghash-alpha.S + $MODESDEF_alpha=GHASH_ASM + + $MODESASM_s390x=ghash-s390x.S + $MODESDEF_s390x=GHASH_ASM + + $MODESASM_armv4=ghash-armv4.S ghashv8-armx.S + $MODESDEF_armv4=GHASH_ASM + $MODESASM_aarch64=ghashv8-armx.S aes-gcm-armv8_64.S + $MODESDEF_aarch64= + + $MODESASM_parisc11=ghash-parisc.s + $MODESDEF_parisc11=GHASH_ASM + $MODESASM_parisc20_64=$MODESASM_parisc11 + $MODESDEF_parisc20_64=$MODESDEF_parisc11 + + $MODESASM_ppc32=ghashp8-ppc.s + $MODESDEF_ppc32= + $MODESASM_ppc64=$MODESASM_ppc32 + $MODESDEF_ppc64=$MODESDEF_ppc32 + + $MODESASM_c64xplus=ghash-c64xplus.s + $MODESDEF_c64xplus=GHASH_ASM + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$MODESASM_{- $target{asm_arch} -}] + $MODESASM=$MODESASM_{- $target{asm_arch} -} + $MODESDEF=$MODESDEF_{- $target{asm_arch} -} + ENDIF +ENDIF + +$COMMON=cbc128.c ctr128.c cfb128.c ofb128.c gcm128.c ccm128.c xts128.c \ + wrap128.c $MODESASM +SOURCE[../../libcrypto]=$COMMON \ + cts128.c ocb128.c siv128.c +SOURCE[../../providers/libfips.a]=$COMMON + +# Implementations are now spread across several libraries, so the defines +# need to be applied to all affected libraries and modules. +DEFINE[../../libcrypto]=$MODESDEF +DEFINE[../../providers/libfips.a]=$MODESDEF + INCLUDE[gcm128.o]=.. -GENERATE[ghash-ia64.s]=asm/ghash-ia64.pl $(LIB_CFLAGS) $(LIB_CPPFLAGS) -GENERATE[ghash-x86.s]=asm/ghash-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -GENERATE[ghash-x86_64.s]=asm/ghash-x86_64.pl $(PERLASM_SCHEME) -GENERATE[aesni-gcm-x86_64.s]=asm/aesni-gcm-x86_64.pl $(PERLASM_SCHEME) -GENERATE[ghash-sparcv9.S]=asm/ghash-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[ghash-ia64.s]=asm/ghash-ia64.pl +GENERATE[ghash-x86.S]=asm/ghash-x86.pl +GENERATE[ghash-x86_64.s]=asm/ghash-x86_64.pl +GENERATE[aesni-gcm-x86_64.s]=asm/aesni-gcm-x86_64.pl +GENERATE[ghash-sparcv9.S]=asm/ghash-sparcv9.pl INCLUDE[ghash-sparcv9.o]=.. -GENERATE[ghash-alpha.S]=asm/ghash-alpha.pl $(PERLASM_SCHEME) -GENERATE[ghash-parisc.s]=asm/ghash-parisc.pl $(PERLASM_SCHEME) -GENERATE[ghashp8-ppc.s]=asm/ghashp8-ppc.pl $(PERLASM_SCHEME) -GENERATE[ghash-armv4.S]=asm/ghash-armv4.pl $(PERLASM_SCHEME) +GENERATE[ghash-alpha.S]=asm/ghash-alpha.pl +GENERATE[ghash-parisc.s]=asm/ghash-parisc.pl +GENERATE[ghashp8-ppc.s]=asm/ghashp8-ppc.pl +GENERATE[ghash-armv4.S]=asm/ghash-armv4.pl INCLUDE[ghash-armv4.o]=.. -GENERATE[ghashv8-armx.S]=asm/ghashv8-armx.pl $(PERLASM_SCHEME) +GENERATE[ghashv8-armx.S]=asm/ghashv8-armx.pl INCLUDE[ghashv8-armx.o]=.. -GENERATE[ghash-s390x.S]=asm/ghash-s390x.pl $(PERLASM_SCHEME) +GENERATE[aes-gcm-armv8_64.S]=asm/aes-gcm-armv8_64.pl +INCLUDE[aes-gcm-armv8_64.o]=.. +GENERATE[ghash-s390x.S]=asm/ghash-s390x.pl INCLUDE[ghash-s390x.o]=.. - -BEGINRAW[Makefile] -# GNU make "catch all" -{- $builddir -}/ghash-%.S: {- $sourcedir -}/asm/ghash-%.pl - CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ -ENDRAW[Makefile] +GENERATE[ghash-c64xplus.S]=asm/ghash-c64xplus.pl diff --git a/crypto/openssl/crypto/modes/cbc128.c b/crypto/openssl/crypto/modes/cbc128.c index 15a14be70872..f3818032a490 100644 --- a/crypto/openssl/crypto/modes/cbc128.c +++ b/crypto/openssl/crypto/modes/cbc128.c @@ -1,15 +1,15 @@ /* * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include "modes_local.h" #include +#include +#include "crypto/modes.h" #if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC) # define STRICT_ALIGNMENT 0 diff --git a/crypto/openssl/crypto/modes/ccm128.c b/crypto/openssl/crypto/modes/ccm128.c index 655b10350201..eee7a69c3ab7 100644 --- a/crypto/openssl/crypto/modes/ccm128.c +++ b/crypto/openssl/crypto/modes/ccm128.c @@ -1,15 +1,15 @@ /* * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include "modes_local.h" #include +#include +#include "crypto/modes.h" #ifndef STRICT_ALIGNMENT # ifdef __GNUC__ diff --git a/crypto/openssl/crypto/modes/cfb128.c b/crypto/openssl/crypto/modes/cfb128.c index b2530007b6e4..2d37bcb586fd 100644 --- a/crypto/openssl/crypto/modes/cfb128.c +++ b/crypto/openssl/crypto/modes/cfb128.c @@ -1,15 +1,15 @@ /* - * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include "modes_local.h" #include +#include +#include "crypto/modes.h" #if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) typedef size_t size_t_aX __attribute((__aligned__(1))); @@ -30,6 +30,11 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, unsigned int n; size_t l = 0; + if (*num < 0) { + /* There is no good way to signal an error return from here */ + *num = -1; + return; + } n = *num; if (enc) { diff --git a/crypto/openssl/crypto/modes/ctr128.c b/crypto/openssl/crypto/modes/ctr128.c index 1ed7decedfd3..58014e76e275 100644 --- a/crypto/openssl/crypto/modes/ctr128.c +++ b/crypto/openssl/crypto/modes/ctr128.c @@ -1,15 +1,16 @@ /* - * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include "modes_local.h" #include +#include +#include "internal/endian.h" +#include "crypto/modes.h" #if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) typedef size_t size_t_aX __attribute((__aligned__(1))); @@ -39,14 +40,9 @@ static void ctr128_inc(unsigned char *counter) static void ctr128_inc_aligned(unsigned char *counter) { size_t *data, c, d, n; - const union { - long one; - char little; - } is_endian = { - 1 - }; - - if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) { + DECLARE_IS_ENDIAN; + + if (IS_LITTLE_ENDIAN || ((size_t)counter % sizeof(size_t)) != 0) { ctr128_inc(counter); return; } @@ -159,7 +155,7 @@ void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, { unsigned int n, ctr32; - n = *num; + n = *num; while (n && len) { *(out++) = *(in++) ^ ecount_buf[n]; diff --git a/crypto/openssl/crypto/modes/cts128.c b/crypto/openssl/crypto/modes/cts128.c index 9052e857764f..5600d9c54b1b 100644 --- a/crypto/openssl/crypto/modes/cts128.c +++ b/crypto/openssl/crypto/modes/cts128.c @@ -1,15 +1,15 @@ /* * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include "modes_local.h" #include +#include +#include "crypto/modes.h" /* * Trouble with Ciphertext Stealing, CTS, mode is that there is no diff --git a/crypto/openssl/crypto/modes/gcm128.c b/crypto/openssl/crypto/modes/gcm128.c index 8304efff48be..e7e719fc0e26 100644 --- a/crypto/openssl/crypto/modes/gcm128.c +++ b/crypto/openssl/crypto/modes/gcm128.c @@ -1,15 +1,17 @@ /* * Copyright 2010-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include "modes_local.h" #include +#include +#include "internal/cryptlib.h" +#include "internal/endian.h" +#include "crypto/modes.h" #if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) typedef size_t size_t_aX __attribute((__aligned__(1))); @@ -104,10 +106,7 @@ static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256]) u128 Z = { 0, 0 }; const u8 *xi = (const u8 *)Xi + 15; size_t rem, n = *xi; - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; static const size_t rem_8bit[256] = { PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246), PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E), @@ -193,7 +192,7 @@ static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256]) Z.hi ^= (u64)rem_8bit[rem] << 32; } - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { # ifdef BSWAP8 Xi[0] = BSWAP8(Z.hi); Xi[1] = BSWAP8(Z.lo); @@ -273,12 +272,9 @@ static void gcm_init_4bit(u128 Htable[16], u64 H[2]) */ { int j; - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) for (j = 0; j < 16; ++j) { V = Htable[j]; Htable[j].hi = V.lo; @@ -306,10 +302,7 @@ static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]) u128 Z; int cnt = 15; size_t rem, nlo, nhi; - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; nlo = ((const u8 *)Xi)[15]; nhi = nlo >> 4; @@ -349,7 +342,7 @@ static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]) Z.lo ^= Htable[nlo].lo; } - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { # ifdef BSWAP8 Xi[0] = BSWAP8(Z.hi); Xi[1] = BSWAP8(Z.lo); @@ -385,10 +378,7 @@ static void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], u128 Z; int cnt; size_t rem, nlo, nhi; - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; # if 1 do { @@ -527,7 +517,7 @@ static void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], Z.hi ^= ((u64)rem_8bit[rem << 4]) << 48; # endif - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { # ifdef BSWAP8 Xi[0] = BSWAP8(Z.hi); Xi[1] = BSWAP8(Z.lo); @@ -575,16 +565,13 @@ static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2]) long X; int i, j; const long *xi = (const long *)Xi; - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; V.hi = H[0]; /* H is in host byte order, no byte swapping */ V.lo = H[1]; for (j = 0; j < 16 / sizeof(long); ++j) { - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { if (sizeof(long) == 8) { # ifdef BSWAP8 X = (long)(BSWAP8(xi[j])); @@ -608,7 +595,7 @@ static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2]) } } - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { # ifdef BSWAP8 Xi[0] = BSWAP8(Z.hi); Xi[1] = BSWAP8(Z.lo); @@ -641,7 +628,6 @@ static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2]) defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) # define GHASH_ASM_X86_OR_64 # define GCM_FUNCREF_4BIT -extern unsigned int OPENSSL_ia32cap_P[]; void gcm_init_clmul(u128 Htable[16], const u64 Xi[2]); void gcm_gmult_clmul(u64 Xi[2], const u128 Htable[16]); @@ -688,16 +674,15 @@ void gcm_ghash_v8(u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len); # endif # elif defined(__sparc__) || defined(__sparc) -# include "sparc_arch.h" +# include "crypto/sparc_arch.h" # define GHASH_ASM_SPARC # define GCM_FUNCREF_4BIT -extern unsigned int OPENSSL_sparcv9cap_P[]; void gcm_init_vis3(u128 Htable[16], const u64 Xi[2]); void gcm_gmult_vis3(u64 Xi[2], const u128 Htable[16]); void gcm_ghash_vis3(u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len); # elif defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC)) -# include "ppc_arch.h" +# include "crypto/ppc_arch.h" # define GHASH_ASM_PPC # define GCM_FUNCREF_4BIT void gcm_init_p8(u128 Htable[16], const u64 Xi[2]); @@ -718,10 +703,7 @@ void gcm_ghash_p8(u64 Xi[2], const u128 Htable[16], const u8 *inp, void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) { - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; memset(ctx, 0, sizeof(*ctx)); ctx->block = block; @@ -729,7 +711,7 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) (*block) (ctx->H.c, ctx->H.c, key); - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { /* H is stored in host byte order */ #ifdef BSWAP8 ctx->H.u[0] = BSWAP8(ctx->H.u[0]); @@ -833,10 +815,7 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, size_t len) { - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; unsigned int ctr; #ifdef GCM_FUNCREF_4BIT void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; @@ -875,7 +854,7 @@ void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, GCM_MUL(ctx); } len0 <<= 3; - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { #ifdef BSWAP8 ctx->Xi.u[1] ^= BSWAP8(len0); #else @@ -894,7 +873,7 @@ void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, GCM_MUL(ctx); - if (is_endian.little) + if (IS_LITTLE_ENDIAN) #ifdef BSWAP4 ctr = BSWAP4(ctx->Xi.d[3]); #else @@ -913,7 +892,7 @@ void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, (*ctx->block) (ctx->Yi.c, ctx->EK0.c, ctx->key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) #ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); #else @@ -988,10 +967,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const unsigned char *in, unsigned char *out, size_t len) { - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; unsigned int n, ctr, mres; size_t i; u64 mlen = ctx->len.u[1]; @@ -1030,7 +1006,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, ctx->ares = 0; } - if (is_endian.little) + if (IS_LITTLE_ENDIAN) #ifdef BSWAP4 ctr = BSWAP4(ctx->Yi.d[3]); #else @@ -1091,7 +1067,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1118,7 +1094,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1141,7 +1117,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1160,7 +1136,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, if (len) { (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1191,7 +1167,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, if (n == 0) { (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) #ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); #else @@ -1223,10 +1199,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const unsigned char *in, unsigned char *out, size_t len) { - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; unsigned int n, ctr, mres; size_t i; u64 mlen = ctx->len.u[1]; @@ -1265,7 +1238,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, ctx->ares = 0; } - if (is_endian.little) + if (IS_LITTLE_ENDIAN) #ifdef BSWAP4 ctr = BSWAP4(ctx->Yi.d[3]); #else @@ -1329,7 +1302,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1354,7 +1327,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1376,7 +1349,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1398,7 +1371,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, if (len) { (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1432,7 +1405,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, if (n == 0) { (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) #ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); #else @@ -1469,10 +1442,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, #if defined(OPENSSL_SMALL_FOOTPRINT) return CRYPTO_gcm128_encrypt(ctx, in, out, len); #else - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; unsigned int n, ctr, mres; size_t i; u64 mlen = ctx->len.u[1]; @@ -1510,7 +1480,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, ctx->ares = 0; } - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctr = BSWAP4(ctx->Yi.d[3]); # else @@ -1558,7 +1528,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, while (len >= GHASH_CHUNK) { (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); ctr += GHASH_CHUNK / 16; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1578,7 +1548,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, (*stream) (in, out, j, key, ctx->Yi.c); ctr += (unsigned int)j; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1603,7 +1573,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, if (len) { (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1633,10 +1603,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, #if defined(OPENSSL_SMALL_FOOTPRINT) return CRYPTO_gcm128_decrypt(ctx, in, out, len); #else - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; unsigned int n, ctr, mres; size_t i; u64 mlen = ctx->len.u[1]; @@ -1674,7 +1641,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, ctx->ares = 0; } - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctr = BSWAP4(ctx->Yi.d[3]); # else @@ -1725,7 +1692,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, GHASH(ctx, in, GHASH_CHUNK); (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); ctr += GHASH_CHUNK / 16; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1757,7 +1724,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, # endif (*stream) (in, out, j, key, ctx->Yi.c); ctr += (unsigned int)j; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1772,7 +1739,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, if (len) { (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; - if (is_endian.little) + if (IS_LITTLE_ENDIAN) # ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); # else @@ -1800,10 +1767,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, size_t len) { - const union { - long one; - char little; - } is_endian = { 1 }; + DECLARE_IS_ENDIAN; u64 alen = ctx->len.u[0] << 3; u64 clen = ctx->len.u[1] << 3; #ifdef GCM_FUNCREF_4BIT @@ -1835,7 +1799,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, GCM_MUL(ctx); #endif - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { #ifdef BSWAP8 alen = BSWAP8(alen); clen = BSWAP8(clen); diff --git a/crypto/openssl/crypto/modes/ghash-x86.S b/crypto/openssl/crypto/modes/ghash-x86.S new file mode 100644 index 000000000000..9b3361acd3a5 --- /dev/null +++ b/crypto/openssl/crypto/modes/ghash-x86.S @@ -0,0 +1,1316 @@ +.text +.globl gcm_gmult_4bit_x86 +.type gcm_gmult_4bit_x86,@function +.align 16 +gcm_gmult_4bit_x86: +.L_gcm_gmult_4bit_x86_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + subl $84,%esp + movl 104(%esp),%edi + movl 108(%esp),%esi + movl (%edi),%ebp + movl 4(%edi),%edx + movl 8(%edi),%ecx + movl 12(%edi),%ebx + movl $0,16(%esp) + movl $471859200,20(%esp) + movl $943718400,24(%esp) + movl $610271232,28(%esp) + movl $1887436800,32(%esp) + movl $1822425088,36(%esp) + movl $1220542464,40(%esp) + movl $1423966208,44(%esp) + movl $3774873600,48(%esp) + movl $4246732800,52(%esp) + movl $3644850176,56(%esp) + movl $3311403008,60(%esp) + movl $2441084928,64(%esp) + movl $2376073216,68(%esp) + movl $2847932416,72(%esp) + movl $3051356160,76(%esp) + movl %ebp,(%esp) + movl %edx,4(%esp) + movl %ecx,8(%esp) + movl %ebx,12(%esp) + shrl $20,%ebx + andl $240,%ebx + movl 4(%esi,%ebx,1),%ebp + movl (%esi,%ebx,1),%edx + movl 12(%esi,%ebx,1),%ecx + movl 8(%esi,%ebx,1),%ebx + xorl %eax,%eax + movl $15,%edi + jmp .L000x86_loop +.align 16 +.L000x86_loop: + movb %bl,%al + shrdl $4,%ecx,%ebx + andb $15,%al + shrdl $4,%edx,%ecx + shrdl $4,%ebp,%edx + shrl $4,%ebp + xorl 16(%esp,%eax,4),%ebp + movb (%esp,%edi,1),%al + andb $240,%al + xorl 8(%esi,%eax,1),%ebx + xorl 12(%esi,%eax,1),%ecx + xorl (%esi,%eax,1),%edx + xorl 4(%esi,%eax,1),%ebp + decl %edi + js .L001x86_break + movb %bl,%al + shrdl $4,%ecx,%ebx + andb $15,%al + shrdl $4,%edx,%ecx + shrdl $4,%ebp,%edx + shrl $4,%ebp + xorl 16(%esp,%eax,4),%ebp + movb (%esp,%edi,1),%al + shlb $4,%al + xorl 8(%esi,%eax,1),%ebx + xorl 12(%esi,%eax,1),%ecx + xorl (%esi,%eax,1),%edx + xorl 4(%esi,%eax,1),%ebp + jmp .L000x86_loop +.align 16 +.L001x86_break: + bswap %ebx + bswap %ecx + bswap %edx + bswap %ebp + movl 104(%esp),%edi + movl %ebx,12(%edi) + movl %ecx,8(%edi) + movl %edx,4(%edi) + movl %ebp,(%edi) + addl $84,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size gcm_gmult_4bit_x86,.-.L_gcm_gmult_4bit_x86_begin +.globl gcm_ghash_4bit_x86 +.type gcm_ghash_4bit_x86,@function +.align 16 +gcm_ghash_4bit_x86: +.L_gcm_ghash_4bit_x86_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + subl $84,%esp + movl 104(%esp),%ebx + movl 108(%esp),%esi + movl 112(%esp),%edi + movl 116(%esp),%ecx + addl %edi,%ecx + movl %ecx,116(%esp) + movl (%ebx),%ebp + movl 4(%ebx),%edx + movl 8(%ebx),%ecx + movl 12(%ebx),%ebx + movl $0,16(%esp) + movl $471859200,20(%esp) + movl $943718400,24(%esp) + movl $610271232,28(%esp) + movl $1887436800,32(%esp) + movl $1822425088,36(%esp) + movl $1220542464,40(%esp) + movl $1423966208,44(%esp) + movl $3774873600,48(%esp) + movl $4246732800,52(%esp) + movl $3644850176,56(%esp) + movl $3311403008,60(%esp) + movl $2441084928,64(%esp) + movl $2376073216,68(%esp) + movl $2847932416,72(%esp) + movl $3051356160,76(%esp) +.align 16 +.L002x86_outer_loop: + xorl 12(%edi),%ebx + xorl 8(%edi),%ecx + xorl 4(%edi),%edx + xorl (%edi),%ebp + movl %ebx,12(%esp) + movl %ecx,8(%esp) + movl %edx,4(%esp) + movl %ebp,(%esp) + shrl $20,%ebx + andl $240,%ebx + movl 4(%esi,%ebx,1),%ebp + movl (%esi,%ebx,1),%edx + movl 12(%esi,%ebx,1),%ecx + movl 8(%esi,%ebx,1),%ebx + xorl %eax,%eax + movl $15,%edi + jmp .L003x86_loop +.align 16 +.L003x86_loop: + movb %bl,%al + shrdl $4,%ecx,%ebx + andb $15,%al + shrdl $4,%edx,%ecx + shrdl $4,%ebp,%edx + shrl $4,%ebp + xorl 16(%esp,%eax,4),%ebp + movb (%esp,%edi,1),%al + andb $240,%al + xorl 8(%esi,%eax,1),%ebx + xorl 12(%esi,%eax,1),%ecx + xorl (%esi,%eax,1),%edx + xorl 4(%esi,%eax,1),%ebp + decl %edi + js .L004x86_break + movb %bl,%al + shrdl $4,%ecx,%ebx + andb $15,%al + shrdl $4,%edx,%ecx + shrdl $4,%ebp,%edx + shrl $4,%ebp + xorl 16(%esp,%eax,4),%ebp + movb (%esp,%edi,1),%al + shlb $4,%al + xorl 8(%esi,%eax,1),%ebx + xorl 12(%esi,%eax,1),%ecx + xorl (%esi,%eax,1),%edx + xorl 4(%esi,%eax,1),%ebp + jmp .L003x86_loop +.align 16 +.L004x86_break: + bswap %ebx + bswap %ecx + bswap %edx + bswap %ebp + movl 112(%esp),%edi + leal 16(%edi),%edi + cmpl 116(%esp),%edi + movl %edi,112(%esp) + jb .L002x86_outer_loop + movl 104(%esp),%edi + movl %ebx,12(%edi) + movl %ecx,8(%edi) + movl %edx,4(%edi) + movl %ebp,(%edi) + addl $84,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size gcm_ghash_4bit_x86,.-.L_gcm_ghash_4bit_x86_begin +.globl gcm_gmult_4bit_mmx +.type gcm_gmult_4bit_mmx,@function +.align 16 +gcm_gmult_4bit_mmx: +.L_gcm_gmult_4bit_mmx_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%edi + movl 24(%esp),%esi + call .L005pic_point +.L005pic_point: + popl %eax + leal .Lrem_4bit-.L005pic_point(%eax),%eax + movzbl 15(%edi),%ebx + xorl %ecx,%ecx + movl %ebx,%edx + movb %dl,%cl + movl $14,%ebp + shlb $4,%cl + andl $240,%edx + movq 8(%esi,%ecx,1),%mm0 + movq (%esi,%ecx,1),%mm1 + movd %mm0,%ebx + jmp .L006mmx_loop +.align 16 +.L006mmx_loop: + psrlq $4,%mm0 + andl $15,%ebx + movq %mm1,%mm2 + psrlq $4,%mm1 + pxor 8(%esi,%edx,1),%mm0 + movb (%edi,%ebp,1),%cl + psllq $60,%mm2 + pxor (%eax,%ebx,8),%mm1 + decl %ebp + movd %mm0,%ebx + pxor (%esi,%edx,1),%mm1 + movl %ecx,%edx + pxor %mm2,%mm0 + js .L007mmx_break + shlb $4,%cl + andl $15,%ebx + psrlq $4,%mm0 + andl $240,%edx + movq %mm1,%mm2 + psrlq $4,%mm1 + pxor 8(%esi,%ecx,1),%mm0 + psllq $60,%mm2 + pxor (%eax,%ebx,8),%mm1 + movd %mm0,%ebx + pxor (%esi,%ecx,1),%mm1 + pxor %mm2,%mm0 + jmp .L006mmx_loop +.align 16 +.L007mmx_break: + shlb $4,%cl + andl $15,%ebx + psrlq $4,%mm0 + andl $240,%edx + movq %mm1,%mm2 + psrlq $4,%mm1 + pxor 8(%esi,%ecx,1),%mm0 + psllq $60,%mm2 + pxor (%eax,%ebx,8),%mm1 + movd %mm0,%ebx + pxor (%esi,%ecx,1),%mm1 + pxor %mm2,%mm0 + psrlq $4,%mm0 + andl $15,%ebx + movq %mm1,%mm2 + psrlq $4,%mm1 + pxor 8(%esi,%edx,1),%mm0 + psllq $60,%mm2 + pxor (%eax,%ebx,8),%mm1 + movd %mm0,%ebx + pxor (%esi,%edx,1),%mm1 + pxor %mm2,%mm0 + psrlq $32,%mm0 + movd %mm1,%edx + psrlq $32,%mm1 + movd %mm0,%ecx + movd %mm1,%ebp + bswap %ebx + bswap %edx + bswap %ecx + bswap %ebp + emms + movl %ebx,12(%edi) + movl %edx,4(%edi) + movl %ecx,8(%edi) + movl %ebp,(%edi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size gcm_gmult_4bit_mmx,.-.L_gcm_gmult_4bit_mmx_begin +.globl gcm_ghash_4bit_mmx +.type gcm_ghash_4bit_mmx,@function +.align 16 +gcm_ghash_4bit_mmx: +.L_gcm_ghash_4bit_mmx_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%eax + movl 24(%esp),%ebx + movl 28(%esp),%ecx + movl 32(%esp),%edx + movl %esp,%ebp + call .L008pic_point +.L008pic_point: + popl %esi + leal .Lrem_8bit-.L008pic_point(%esi),%esi + subl $544,%esp + andl $-64,%esp + subl $16,%esp + addl %ecx,%edx + movl %eax,544(%esp) + movl %edx,552(%esp) + movl %ebp,556(%esp) + addl $128,%ebx + leal 144(%esp),%edi + leal 400(%esp),%ebp + movl -120(%ebx),%edx + movq -120(%ebx),%mm0 + movq -128(%ebx),%mm3 + shll $4,%edx + movb %dl,(%esp) + movl -104(%ebx),%edx + movq -104(%ebx),%mm2 + movq -112(%ebx),%mm5 + movq %mm0,-128(%edi) + psrlq $4,%mm0 + movq %mm3,(%edi) + movq %mm3,%mm7 + psrlq $4,%mm3 + shll $4,%edx + movb %dl,1(%esp) + movl -88(%ebx),%edx + movq -88(%ebx),%mm1 + psllq $60,%mm7 + movq -96(%ebx),%mm4 + por %mm7,%mm0 + movq %mm2,-120(%edi) + psrlq $4,%mm2 + movq %mm5,8(%edi) + movq %mm5,%mm6 + movq %mm0,-128(%ebp) + psrlq $4,%mm5 + movq %mm3,(%ebp) + shll $4,%edx + movb %dl,2(%esp) + movl -72(%ebx),%edx + movq -72(%ebx),%mm0 + psllq $60,%mm6 + movq -80(%ebx),%mm3 + por %mm6,%mm2 + movq %mm1,-112(%edi) + psrlq $4,%mm1 + movq %mm4,16(%edi) + movq %mm4,%mm7 + movq %mm2,-120(%ebp) + psrlq $4,%mm4 + movq %mm5,8(%ebp) + shll $4,%edx + movb %dl,3(%esp) + movl -56(%ebx),%edx + movq -56(%ebx),%mm2 + psllq $60,%mm7 + movq -64(%ebx),%mm5 + por %mm7,%mm1 + movq %mm0,-104(%edi) + psrlq $4,%mm0 + movq %mm3,24(%edi) + movq %mm3,%mm6 + movq %mm1,-112(%ebp) + psrlq $4,%mm3 + movq %mm4,16(%ebp) + shll $4,%edx + movb %dl,4(%esp) + movl -40(%ebx),%edx + movq -40(%ebx),%mm1 + psllq $60,%mm6 + movq -48(%ebx),%mm4 + por %mm6,%mm0 + movq %mm2,-96(%edi) + psrlq $4,%mm2 + movq %mm5,32(%edi) + movq %mm5,%mm7 + movq %mm0,-104(%ebp) + psrlq $4,%mm5 + movq %mm3,24(%ebp) + shll $4,%edx + movb %dl,5(%esp) + movl -24(%ebx),%edx + movq -24(%ebx),%mm0 + psllq $60,%mm7 + movq -32(%ebx),%mm3 + por %mm7,%mm2 + movq %mm1,-88(%edi) + psrlq $4,%mm1 + movq %mm4,40(%edi) + movq %mm4,%mm6 + movq %mm2,-96(%ebp) + psrlq $4,%mm4 + movq %mm5,32(%ebp) + shll $4,%edx + movb %dl,6(%esp) + movl -8(%ebx),%edx + movq -8(%ebx),%mm2 + psllq $60,%mm6 + movq -16(%ebx),%mm5 + por %mm6,%mm1 + movq %mm0,-80(%edi) + psrlq $4,%mm0 + movq %mm3,48(%edi) + movq %mm3,%mm7 + movq %mm1,-88(%ebp) + psrlq $4,%mm3 + movq %mm4,40(%ebp) + shll $4,%edx + movb %dl,7(%esp) + movl 8(%ebx),%edx + movq 8(%ebx),%mm1 + psllq $60,%mm7 + movq (%ebx),%mm4 + por %mm7,%mm0 + movq %mm2,-72(%edi) + psrlq $4,%mm2 + movq %mm5,56(%edi) + movq %mm5,%mm6 + movq %mm0,-80(%ebp) + psrlq $4,%mm5 + movq %mm3,48(%ebp) + shll $4,%edx + movb %dl,8(%esp) + movl 24(%ebx),%edx + movq 24(%ebx),%mm0 + psllq $60,%mm6 + movq 16(%ebx),%mm3 + por %mm6,%mm2 + movq %mm1,-64(%edi) + psrlq $4,%mm1 + movq %mm4,64(%edi) + movq %mm4,%mm7 + movq %mm2,-72(%ebp) + psrlq $4,%mm4 + movq %mm5,56(%ebp) + shll $4,%edx + movb %dl,9(%esp) + movl 40(%ebx),%edx + movq 40(%ebx),%mm2 + psllq $60,%mm7 + movq 32(%ebx),%mm5 + por %mm7,%mm1 + movq %mm0,-56(%edi) + psrlq $4,%mm0 + movq %mm3,72(%edi) + movq %mm3,%mm6 + movq %mm1,-64(%ebp) + psrlq $4,%mm3 + movq %mm4,64(%ebp) + shll $4,%edx + movb %dl,10(%esp) + movl 56(%ebx),%edx + movq 56(%ebx),%mm1 + psllq $60,%mm6 + movq 48(%ebx),%mm4 + por %mm6,%mm0 + movq %mm2,-48(%edi) + psrlq $4,%mm2 + movq %mm5,80(%edi) + movq %mm5,%mm7 + movq %mm0,-56(%ebp) + psrlq $4,%mm5 + movq %mm3,72(%ebp) + shll $4,%edx + movb %dl,11(%esp) + movl 72(%ebx),%edx + movq 72(%ebx),%mm0 + psllq $60,%mm7 + movq 64(%ebx),%mm3 + por %mm7,%mm2 + movq %mm1,-40(%edi) + psrlq $4,%mm1 + movq %mm4,88(%edi) + movq %mm4,%mm6 + movq %mm2,-48(%ebp) + psrlq $4,%mm4 + movq %mm5,80(%ebp) + shll $4,%edx + movb %dl,12(%esp) + movl 88(%ebx),%edx + movq 88(%ebx),%mm2 + psllq $60,%mm6 + movq 80(%ebx),%mm5 + por %mm6,%mm1 + movq %mm0,-32(%edi) + psrlq $4,%mm0 + movq %mm3,96(%edi) + movq %mm3,%mm7 + movq %mm1,-40(%ebp) + psrlq $4,%mm3 + movq %mm4,88(%ebp) + shll $4,%edx + movb %dl,13(%esp) + movl 104(%ebx),%edx + movq 104(%ebx),%mm1 + psllq $60,%mm7 + movq 96(%ebx),%mm4 + por %mm7,%mm0 + movq %mm2,-24(%edi) + psrlq $4,%mm2 + movq %mm5,104(%edi) + movq %mm5,%mm6 + movq %mm0,-32(%ebp) + psrlq $4,%mm5 + movq %mm3,96(%ebp) + shll $4,%edx + movb %dl,14(%esp) + movl 120(%ebx),%edx + movq 120(%ebx),%mm0 + psllq $60,%mm6 + movq 112(%ebx),%mm3 + por %mm6,%mm2 + movq %mm1,-16(%edi) + psrlq $4,%mm1 + movq %mm4,112(%edi) + movq %mm4,%mm7 + movq %mm2,-24(%ebp) + psrlq $4,%mm4 + movq %mm5,104(%ebp) + shll $4,%edx + movb %dl,15(%esp) + psllq $60,%mm7 + por %mm7,%mm1 + movq %mm0,-8(%edi) + psrlq $4,%mm0 + movq %mm3,120(%edi) + movq %mm3,%mm6 + movq %mm1,-16(%ebp) + psrlq $4,%mm3 + movq %mm4,112(%ebp) + psllq $60,%mm6 + por %mm6,%mm0 + movq %mm0,-8(%ebp) + movq %mm3,120(%ebp) + movq (%eax),%mm6 + movl 8(%eax),%ebx + movl 12(%eax),%edx +.align 16 +.L009outer: + xorl 12(%ecx),%edx + xorl 8(%ecx),%ebx + pxor (%ecx),%mm6 + leal 16(%ecx),%ecx + movl %ebx,536(%esp) + movq %mm6,528(%esp) + movl %ecx,548(%esp) + xorl %eax,%eax + roll $8,%edx + movb %dl,%al + movl %eax,%ebp + andb $15,%al + shrl $4,%ebp + pxor %mm0,%mm0 + roll $8,%edx + pxor %mm1,%mm1 + pxor %mm2,%mm2 + movq 16(%esp,%eax,8),%mm7 + movq 144(%esp,%eax,8),%mm6 + movb %dl,%al + movd %mm7,%ebx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%edi + psrlq $8,%mm6 + pxor 272(%esp,%ebp,8),%mm7 + andb $15,%al + psllq $56,%mm3 + shrl $4,%edi + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%ebp,8),%mm6 + xorb (%esp,%ebp,1),%bl + movb %dl,%al + movd %mm7,%ecx + movzbl %bl,%ebx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%ebp + psrlq $8,%mm6 + pxor 272(%esp,%edi,8),%mm7 + andb $15,%al + psllq $56,%mm3 + shrl $4,%ebp + pinsrw $2,(%esi,%ebx,2),%mm2 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%edi,8),%mm6 + xorb (%esp,%edi,1),%cl + movb %dl,%al + movl 536(%esp),%edx + movd %mm7,%ebx + movzbl %cl,%ecx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%edi + psrlq $8,%mm6 + pxor 272(%esp,%ebp,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm2,%mm6 + shrl $4,%edi + pinsrw $2,(%esi,%ecx,2),%mm1 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%ebp,8),%mm6 + xorb (%esp,%ebp,1),%bl + movb %dl,%al + movd %mm7,%ecx + movzbl %bl,%ebx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%ebp + psrlq $8,%mm6 + pxor 272(%esp,%edi,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm1,%mm6 + shrl $4,%ebp + pinsrw $2,(%esi,%ebx,2),%mm0 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%edi,8),%mm6 + xorb (%esp,%edi,1),%cl + movb %dl,%al + movd %mm7,%ebx + movzbl %cl,%ecx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%edi + psrlq $8,%mm6 + pxor 272(%esp,%ebp,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm0,%mm6 + shrl $4,%edi + pinsrw $2,(%esi,%ecx,2),%mm2 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%ebp,8),%mm6 + xorb (%esp,%ebp,1),%bl + movb %dl,%al + movd %mm7,%ecx + movzbl %bl,%ebx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%ebp + psrlq $8,%mm6 + pxor 272(%esp,%edi,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm2,%mm6 + shrl $4,%ebp + pinsrw $2,(%esi,%ebx,2),%mm1 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%edi,8),%mm6 + xorb (%esp,%edi,1),%cl + movb %dl,%al + movl 532(%esp),%edx + movd %mm7,%ebx + movzbl %cl,%ecx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%edi + psrlq $8,%mm6 + pxor 272(%esp,%ebp,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm1,%mm6 + shrl $4,%edi + pinsrw $2,(%esi,%ecx,2),%mm0 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%ebp,8),%mm6 + xorb (%esp,%ebp,1),%bl + movb %dl,%al + movd %mm7,%ecx + movzbl %bl,%ebx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%ebp + psrlq $8,%mm6 + pxor 272(%esp,%edi,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm0,%mm6 + shrl $4,%ebp + pinsrw $2,(%esi,%ebx,2),%mm2 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%edi,8),%mm6 + xorb (%esp,%edi,1),%cl + movb %dl,%al + movd %mm7,%ebx + movzbl %cl,%ecx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%edi + psrlq $8,%mm6 + pxor 272(%esp,%ebp,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm2,%mm6 + shrl $4,%edi + pinsrw $2,(%esi,%ecx,2),%mm1 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%ebp,8),%mm6 + xorb (%esp,%ebp,1),%bl + movb %dl,%al + movd %mm7,%ecx + movzbl %bl,%ebx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%ebp + psrlq $8,%mm6 + pxor 272(%esp,%edi,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm1,%mm6 + shrl $4,%ebp + pinsrw $2,(%esi,%ebx,2),%mm0 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%edi,8),%mm6 + xorb (%esp,%edi,1),%cl + movb %dl,%al + movl 528(%esp),%edx + movd %mm7,%ebx + movzbl %cl,%ecx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%edi + psrlq $8,%mm6 + pxor 272(%esp,%ebp,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm0,%mm6 + shrl $4,%edi + pinsrw $2,(%esi,%ecx,2),%mm2 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%ebp,8),%mm6 + xorb (%esp,%ebp,1),%bl + movb %dl,%al + movd %mm7,%ecx + movzbl %bl,%ebx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%ebp + psrlq $8,%mm6 + pxor 272(%esp,%edi,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm2,%mm6 + shrl $4,%ebp + pinsrw $2,(%esi,%ebx,2),%mm1 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%edi,8),%mm6 + xorb (%esp,%edi,1),%cl + movb %dl,%al + movd %mm7,%ebx + movzbl %cl,%ecx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%edi + psrlq $8,%mm6 + pxor 272(%esp,%ebp,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm1,%mm6 + shrl $4,%edi + pinsrw $2,(%esi,%ecx,2),%mm0 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%ebp,8),%mm6 + xorb (%esp,%ebp,1),%bl + movb %dl,%al + movd %mm7,%ecx + movzbl %bl,%ebx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%ebp + psrlq $8,%mm6 + pxor 272(%esp,%edi,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm0,%mm6 + shrl $4,%ebp + pinsrw $2,(%esi,%ebx,2),%mm2 + pxor 16(%esp,%eax,8),%mm7 + roll $8,%edx + pxor 144(%esp,%eax,8),%mm6 + pxor %mm3,%mm7 + pxor 400(%esp,%edi,8),%mm6 + xorb (%esp,%edi,1),%cl + movb %dl,%al + movl 524(%esp),%edx + movd %mm7,%ebx + movzbl %cl,%ecx + psrlq $8,%mm7 + movq %mm6,%mm3 + movl %eax,%edi + psrlq $8,%mm6 + pxor 272(%esp,%ebp,8),%mm7 + andb $15,%al + psllq $56,%mm3 + pxor %mm2,%mm6 + shrl $4,%edi + pinsrw $2,(%esi,%ecx,2),%mm1 + pxor 16(%esp,%eax,8),%mm7 + pxor 144(%esp,%eax,8),%mm6 + xorb (%esp,%ebp,1),%bl + pxor %mm3,%mm7 + pxor 400(%esp,%ebp,8),%mm6 + movzbl %bl,%ebx + pxor %mm2,%mm2 + psllq $4,%mm1 + movd %mm7,%ecx + psrlq $4,%mm7 + movq %mm6,%mm3 + psrlq $4,%mm6 + shll $4,%ecx + pxor 16(%esp,%edi,8),%mm7 + psllq $60,%mm3 + movzbl %cl,%ecx + pxor %mm3,%mm7 + pxor 144(%esp,%edi,8),%mm6 + pinsrw $2,(%esi,%ebx,2),%mm0 + pxor %mm1,%mm6 + movd %mm7,%edx + pinsrw $3,(%esi,%ecx,2),%mm2 + psllq $12,%mm0 + pxor %mm0,%mm6 + psrlq $32,%mm7 + pxor %mm2,%mm6 + movl 548(%esp),%ecx + movd %mm7,%ebx + movq %mm6,%mm3 + psllw $8,%mm6 + psrlw $8,%mm3 + por %mm3,%mm6 + bswap %edx + pshufw $27,%mm6,%mm6 + bswap %ebx + cmpl 552(%esp),%ecx + jne .L009outer + movl 544(%esp),%eax + movl %edx,12(%eax) + movl %ebx,8(%eax) + movq %mm6,(%eax) + movl 556(%esp),%esp + emms + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size gcm_ghash_4bit_mmx,.-.L_gcm_ghash_4bit_mmx_begin +.globl gcm_init_clmul +.type gcm_init_clmul,@function +.align 16 +gcm_init_clmul: +.L_gcm_init_clmul_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl 4(%esp),%edx + movl 8(%esp),%eax + call .L010pic +.L010pic: + popl %ecx + leal .Lbswap-.L010pic(%ecx),%ecx + movdqu (%eax),%xmm2 + pshufd $78,%xmm2,%xmm2 + pshufd $255,%xmm2,%xmm4 + movdqa %xmm2,%xmm3 + psllq $1,%xmm2 + pxor %xmm5,%xmm5 + psrlq $63,%xmm3 + pcmpgtd %xmm4,%xmm5 + pslldq $8,%xmm3 + por %xmm3,%xmm2 + pand 16(%ecx),%xmm5 + pxor %xmm5,%xmm2 + movdqa %xmm2,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + xorps %xmm0,%xmm3 + xorps %xmm1,%xmm3 + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + pshufd $78,%xmm2,%xmm3 + pshufd $78,%xmm0,%xmm4 + pxor %xmm2,%xmm3 + movdqu %xmm2,(%edx) + pxor %xmm0,%xmm4 + movdqu %xmm0,16(%edx) +.byte 102,15,58,15,227,8 + movdqu %xmm4,32(%edx) + ret +.size gcm_init_clmul,.-.L_gcm_init_clmul_begin +.globl gcm_gmult_clmul +.type gcm_gmult_clmul,@function +.align 16 +gcm_gmult_clmul: +.L_gcm_gmult_clmul_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl 4(%esp),%eax + movl 8(%esp),%edx + call .L011pic +.L011pic: + popl %ecx + leal .Lbswap-.L011pic(%ecx),%ecx + movdqu (%eax),%xmm0 + movdqa (%ecx),%xmm5 + movups (%edx),%xmm2 +.byte 102,15,56,0,197 + movups 32(%edx),%xmm4 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + xorps %xmm0,%xmm3 + xorps %xmm1,%xmm3 + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,197 + movdqu %xmm0,(%eax) + ret +.size gcm_gmult_clmul,.-.L_gcm_gmult_clmul_begin +.globl gcm_ghash_clmul +.type gcm_ghash_clmul,@function +.align 16 +gcm_ghash_clmul: +.L_gcm_ghash_clmul_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%eax + movl 24(%esp),%edx + movl 28(%esp),%esi + movl 32(%esp),%ebx + call .L012pic +.L012pic: + popl %ecx + leal .Lbswap-.L012pic(%ecx),%ecx + movdqu (%eax),%xmm0 + movdqa (%ecx),%xmm5 + movdqu (%edx),%xmm2 +.byte 102,15,56,0,197 + subl $16,%ebx + jz .L013odd_tail + movdqu (%esi),%xmm3 + movdqu 16(%esi),%xmm6 +.byte 102,15,56,0,221 +.byte 102,15,56,0,245 + movdqu 32(%edx),%xmm5 + pxor %xmm3,%xmm0 + pshufd $78,%xmm6,%xmm3 + movdqa %xmm6,%xmm7 + pxor %xmm6,%xmm3 + leal 32(%esi),%esi +.byte 102,15,58,68,242,0 +.byte 102,15,58,68,250,17 +.byte 102,15,58,68,221,0 + movups 16(%edx),%xmm2 + nop + subl $32,%ebx + jbe .L014even_tail + jmp .L015mod_loop +.align 32 +.L015mod_loop: + pshufd $78,%xmm0,%xmm4 + movdqa %xmm0,%xmm1 + pxor %xmm0,%xmm4 + nop +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,229,16 + movups (%edx),%xmm2 + xorps %xmm6,%xmm0 + movdqa (%ecx),%xmm5 + xorps %xmm7,%xmm1 + movdqu (%esi),%xmm7 + pxor %xmm0,%xmm3 + movdqu 16(%esi),%xmm6 + pxor %xmm1,%xmm3 +.byte 102,15,56,0,253 + pxor %xmm3,%xmm4 + movdqa %xmm4,%xmm3 + psrldq $8,%xmm4 + pslldq $8,%xmm3 + pxor %xmm4,%xmm1 + pxor %xmm3,%xmm0 +.byte 102,15,56,0,245 + pxor %xmm7,%xmm1 + movdqa %xmm6,%xmm7 + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 +.byte 102,15,58,68,242,0 + movups 32(%edx),%xmm5 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + pshufd $78,%xmm7,%xmm3 + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm7,%xmm3 + pxor %xmm4,%xmm1 +.byte 102,15,58,68,250,17 + movups 16(%edx),%xmm2 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +.byte 102,15,58,68,221,0 + leal 32(%esi),%esi + subl $32,%ebx + ja .L015mod_loop +.L014even_tail: + pshufd $78,%xmm0,%xmm4 + movdqa %xmm0,%xmm1 + pxor %xmm0,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,229,16 + movdqa (%ecx),%xmm5 + xorps %xmm6,%xmm0 + xorps %xmm7,%xmm1 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + pxor %xmm3,%xmm4 + movdqa %xmm4,%xmm3 + psrldq $8,%xmm4 + pslldq $8,%xmm3 + pxor %xmm4,%xmm1 + pxor %xmm3,%xmm0 + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + testl %ebx,%ebx + jnz .L016done + movups (%edx),%xmm2 +.L013odd_tail: + movdqu (%esi),%xmm3 +.byte 102,15,56,0,221 + pxor %xmm3,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pshufd $78,%xmm2,%xmm4 + pxor %xmm0,%xmm3 + pxor %xmm2,%xmm4 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + xorps %xmm0,%xmm3 + xorps %xmm1,%xmm3 + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +.L016done: +.byte 102,15,56,0,197 + movdqu %xmm0,(%eax) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size gcm_ghash_clmul,.-.L_gcm_ghash_clmul_begin +.align 64 +.Lbswap: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,194 +.align 64 +.Lrem_8bit: +.value 0,450,900,582,1800,1738,1164,1358 +.value 3600,4050,3476,3158,2328,2266,2716,2910 +.value 7200,7650,8100,7782,6952,6890,6316,6510 +.value 4656,5106,4532,4214,5432,5370,5820,6014 +.value 14400,14722,15300,14854,16200,16010,15564,15630 +.value 13904,14226,13780,13334,12632,12442,13020,13086 +.value 9312,9634,10212,9766,9064,8874,8428,8494 +.value 10864,11186,10740,10294,11640,11450,12028,12094 +.value 28800,28994,29444,29382,30600,30282,29708,30158 +.value 32400,32594,32020,31958,31128,30810,31260,31710 +.value 27808,28002,28452,28390,27560,27242,26668,27118 +.value 25264,25458,24884,24822,26040,25722,26172,26622 +.value 18624,18690,19268,19078,20424,19978,19532,19854 +.value 18128,18194,17748,17558,16856,16410,16988,17310 +.value 21728,21794,22372,22182,21480,21034,20588,20910 +.value 23280,23346,22900,22710,24056,23610,24188,24510 +.value 57600,57538,57988,58182,58888,59338,58764,58446 +.value 61200,61138,60564,60758,59416,59866,60316,59998 +.value 64800,64738,65188,65382,64040,64490,63916,63598 +.value 62256,62194,61620,61814,62520,62970,63420,63102 +.value 55616,55426,56004,56070,56904,57226,56780,56334 +.value 55120,54930,54484,54550,53336,53658,54236,53790 +.value 50528,50338,50916,50982,49768,50090,49644,49198 +.value 52080,51890,51444,51510,52344,52666,53244,52798 +.value 37248,36930,37380,37830,38536,38730,38156,38094 +.value 40848,40530,39956,40406,39064,39258,39708,39646 +.value 36256,35938,36388,36838,35496,35690,35116,35054 +.value 33712,33394,32820,33270,33976,34170,34620,34558 +.value 43456,43010,43588,43910,44744,44810,44364,44174 +.value 42960,42514,42068,42390,41176,41242,41820,41630 +.value 46560,46114,46692,47014,45800,45866,45420,45230 +.value 48112,47666,47220,47542,48376,48442,49020,48830 +.align 64 +.Lrem_4bit: +.long 0,0,0,471859200,0,943718400,0,610271232 +.long 0,1887436800,0,1822425088,0,1220542464,0,1423966208 +.long 0,3774873600,0,4246732800,0,3644850176,0,3311403008 +.long 0,2441084928,0,2376073216,0,2847932416,0,3051356160 +.byte 71,72,65,83,72,32,102,111,114,32,120,56,54,44,32,67 +.byte 82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112 +.byte 112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62 +.byte 0 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/modes/ghash-x86_64.S b/crypto/openssl/crypto/modes/ghash-x86_64.S new file mode 100644 index 000000000000..29dd9b13e956 --- /dev/null +++ b/crypto/openssl/crypto/modes/ghash-x86_64.S @@ -0,0 +1,1874 @@ +.text + + +.globl gcm_gmult_4bit +.type gcm_gmult_4bit,@function +.align 16 +gcm_gmult_4bit: +.cfi_startproc +.byte 243,15,30,250 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $280,%rsp +.cfi_adjust_cfa_offset 280 +.Lgmult_prologue: + + movzbq 15(%rdi),%r8 + leaq .Lrem_4bit(%rip),%r11 + xorq %rax,%rax + xorq %rbx,%rbx + movb %r8b,%al + movb %r8b,%bl + shlb $4,%al + movq $14,%rcx + movq 8(%rsi,%rax,1),%r8 + movq (%rsi,%rax,1),%r9 + andb $0xf0,%bl + movq %r8,%rdx + jmp .Loop1 + +.align 16 +.Loop1: + shrq $4,%r8 + andq $0xf,%rdx + movq %r9,%r10 + movb (%rdi,%rcx,1),%al + shrq $4,%r9 + xorq 8(%rsi,%rbx,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rbx,1),%r9 + movb %al,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + shlb $4,%al + xorq %r10,%r8 + decq %rcx + js .Lbreak1 + + shrq $4,%r8 + andq $0xf,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rax,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rax,1),%r9 + andb $0xf0,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + xorq %r10,%r8 + jmp .Loop1 + +.align 16 +.Lbreak1: + shrq $4,%r8 + andq $0xf,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rax,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rax,1),%r9 + andb $0xf0,%bl + xorq (%r11,%rdx,8),%r9 + movq %r8,%rdx + xorq %r10,%r8 + + shrq $4,%r8 + andq $0xf,%rdx + movq %r9,%r10 + shrq $4,%r9 + xorq 8(%rsi,%rbx,1),%r8 + shlq $60,%r10 + xorq (%rsi,%rbx,1),%r9 + xorq %r10,%r8 + xorq (%r11,%rdx,8),%r9 + + bswapq %r8 + bswapq %r9 + movq %r8,8(%rdi) + movq %r9,(%rdi) + + leaq 280+48(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lgmult_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_gmult_4bit,.-gcm_gmult_4bit +.globl gcm_ghash_4bit +.type gcm_ghash_4bit,@function +.align 16 +gcm_ghash_4bit: +.cfi_startproc +.byte 243,15,30,250 + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $280,%rsp +.cfi_adjust_cfa_offset 280 +.Lghash_prologue: + movq %rdx,%r14 + movq %rcx,%r15 + subq $-128,%rsi + leaq 16+128(%rsp),%rbp + xorl %edx,%edx + movq 0+0-128(%rsi),%r8 + movq 0+8-128(%rsi),%rax + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq 16+0-128(%rsi),%r9 + shlb $4,%dl + movq 16+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,0(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,0(%rbp) + movq 32+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,0-128(%rbp) + movq 32+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,1(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,8(%rbp) + movq 48+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,8-128(%rbp) + movq 48+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,2(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,16(%rbp) + movq 64+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,16-128(%rbp) + movq 64+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,3(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,24(%rbp) + movq 80+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,24-128(%rbp) + movq 80+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,4(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,32(%rbp) + movq 96+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,32-128(%rbp) + movq 96+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,5(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,40(%rbp) + movq 112+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,40-128(%rbp) + movq 112+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,6(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,48(%rbp) + movq 128+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,48-128(%rbp) + movq 128+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,7(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,56(%rbp) + movq 144+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,56-128(%rbp) + movq 144+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,8(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,64(%rbp) + movq 160+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,64-128(%rbp) + movq 160+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,9(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,72(%rbp) + movq 176+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,72-128(%rbp) + movq 176+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,10(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,80(%rbp) + movq 192+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,80-128(%rbp) + movq 192+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,11(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,88(%rbp) + movq 208+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,88-128(%rbp) + movq 208+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,12(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,96(%rbp) + movq 224+0-128(%rsi),%r8 + shlb $4,%dl + movq %rax,96-128(%rbp) + movq 224+8-128(%rsi),%rax + shlq $60,%r10 + movb %dl,13(%rsp) + orq %r10,%rbx + movb %al,%dl + shrq $4,%rax + movq %r8,%r10 + shrq $4,%r8 + movq %r9,104(%rbp) + movq 240+0-128(%rsi),%r9 + shlb $4,%dl + movq %rbx,104-128(%rbp) + movq 240+8-128(%rsi),%rbx + shlq $60,%r10 + movb %dl,14(%rsp) + orq %r10,%rax + movb %bl,%dl + shrq $4,%rbx + movq %r9,%r10 + shrq $4,%r9 + movq %r8,112(%rbp) + shlb $4,%dl + movq %rax,112-128(%rbp) + shlq $60,%r10 + movb %dl,15(%rsp) + orq %r10,%rbx + movq %r9,120(%rbp) + movq %rbx,120-128(%rbp) + addq $-128,%rsi + movq 8(%rdi),%r8 + movq 0(%rdi),%r9 + addq %r14,%r15 + leaq .Lrem_8bit(%rip),%r11 + jmp .Louter_loop +.align 16 +.Louter_loop: + xorq (%r14),%r9 + movq 8(%r14),%rdx + leaq 16(%r14),%r14 + xorq %r8,%rdx + movq %r9,(%rdi) + movq %rdx,8(%rdi) + shrq $32,%rdx + xorq %rax,%rax + roll $8,%edx + movb %dl,%al + movzbl %dl,%ebx + shlb $4,%al + shrl $4,%ebx + roll $8,%edx + movq 8(%rsi,%rax,1),%r8 + movq (%rsi,%rax,1),%r9 + movb %dl,%al + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + xorq %r8,%r12 + movq %r9,%r10 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 8(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 4(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl 0(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + shrl $4,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r12,2),%r12 + movzbl %dl,%ebx + shlb $4,%al + movzbq (%rsp,%rcx,1),%r13 + shrl $4,%ebx + shlq $48,%r12 + xorq %r8,%r13 + movq %r9,%r10 + xorq %r12,%r9 + shrq $8,%r8 + movzbq %r13b,%r13 + shrq $8,%r9 + xorq -128(%rbp,%rcx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rcx,8),%r9 + roll $8,%edx + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + movb %dl,%al + xorq %r10,%r8 + movzwq (%r11,%r13,2),%r13 + movzbl %dl,%ecx + shlb $4,%al + movzbq (%rsp,%rbx,1),%r12 + andl $240,%ecx + shlq $48,%r13 + xorq %r8,%r12 + movq %r9,%r10 + xorq %r13,%r9 + shrq $8,%r8 + movzbq %r12b,%r12 + movl -4(%rdi),%edx + shrq $8,%r9 + xorq -128(%rbp,%rbx,8),%r8 + shlq $56,%r10 + xorq (%rbp,%rbx,8),%r9 + movzwq (%r11,%r12,2),%r12 + xorq 8(%rsi,%rax,1),%r8 + xorq (%rsi,%rax,1),%r9 + shlq $48,%r12 + xorq %r10,%r8 + xorq %r12,%r9 + movzbq %r8b,%r13 + shrq $4,%r8 + movq %r9,%r10 + shlb $4,%r13b + shrq $4,%r9 + xorq 8(%rsi,%rcx,1),%r8 + movzwq (%r11,%r13,2),%r13 + shlq $60,%r10 + xorq (%rsi,%rcx,1),%r9 + xorq %r10,%r8 + shlq $48,%r13 + bswapq %r8 + xorq %r13,%r9 + bswapq %r9 + cmpq %r15,%r14 + jb .Louter_loop + movq %r8,8(%rdi) + movq %r9,(%rdi) + + leaq 280+48(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq 0(%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lghash_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_ghash_4bit,.-gcm_ghash_4bit +.globl gcm_init_clmul +.type gcm_init_clmul,@function +.align 16 +gcm_init_clmul: +.cfi_startproc +.L_init_clmul: + movdqu (%rsi),%xmm2 + pshufd $78,%xmm2,%xmm2 + + + pshufd $255,%xmm2,%xmm4 + movdqa %xmm2,%xmm3 + psllq $1,%xmm2 + pxor %xmm5,%xmm5 + psrlq $63,%xmm3 + pcmpgtd %xmm4,%xmm5 + pslldq $8,%xmm3 + por %xmm3,%xmm2 + + + pand .L0x1c2_polynomial(%rip),%xmm5 + pxor %xmm5,%xmm2 + + + pshufd $78,%xmm2,%xmm6 + movdqa %xmm2,%xmm0 + pxor %xmm2,%xmm6 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,222,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + pshufd $78,%xmm2,%xmm3 + pshufd $78,%xmm0,%xmm4 + pxor %xmm2,%xmm3 + movdqu %xmm2,0(%rdi) + pxor %xmm0,%xmm4 + movdqu %xmm0,16(%rdi) +.byte 102,15,58,15,227,8 + movdqu %xmm4,32(%rdi) + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,222,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + movdqa %xmm0,%xmm5 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,222,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + pshufd $78,%xmm5,%xmm3 + pshufd $78,%xmm0,%xmm4 + pxor %xmm5,%xmm3 + movdqu %xmm5,48(%rdi) + pxor %xmm0,%xmm4 + movdqu %xmm0,64(%rdi) +.byte 102,15,58,15,227,8 + movdqu %xmm4,80(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_init_clmul,.-gcm_init_clmul +.globl gcm_gmult_clmul +.type gcm_gmult_clmul,@function +.align 16 +gcm_gmult_clmul: +.cfi_startproc +.byte 243,15,30,250 +.L_gmult_clmul: + movdqu (%rdi),%xmm0 + movdqa .Lbswap_mask(%rip),%xmm5 + movdqu (%rsi),%xmm2 + movdqu 32(%rsi),%xmm4 +.byte 102,15,56,0,197 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,220,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +.byte 102,15,56,0,197 + movdqu %xmm0,(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_gmult_clmul,.-gcm_gmult_clmul +.globl gcm_ghash_clmul +.type gcm_ghash_clmul,@function +.align 32 +gcm_ghash_clmul: +.cfi_startproc +.byte 243,15,30,250 +.L_ghash_clmul: + movdqa .Lbswap_mask(%rip),%xmm10 + + movdqu (%rdi),%xmm0 + movdqu (%rsi),%xmm2 + movdqu 32(%rsi),%xmm7 +.byte 102,65,15,56,0,194 + + subq $0x10,%rcx + jz .Lodd_tail + + movdqu 16(%rsi),%xmm6 + movl OPENSSL_ia32cap_P+4(%rip),%eax + cmpq $0x30,%rcx + jb .Lskip4x + + andl $71303168,%eax + cmpl $4194304,%eax + je .Lskip4x + + subq $0x30,%rcx + movq $0xA040608020C0E000,%rax + movdqu 48(%rsi),%xmm14 + movdqu 64(%rsi),%xmm15 + + + + + movdqu 48(%rdx),%xmm3 + movdqu 32(%rdx),%xmm11 +.byte 102,65,15,56,0,218 +.byte 102,69,15,56,0,218 + movdqa %xmm3,%xmm5 + pshufd $78,%xmm3,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,68,218,0 +.byte 102,15,58,68,234,17 +.byte 102,15,58,68,231,0 + + movdqa %xmm11,%xmm13 + pshufd $78,%xmm11,%xmm12 + pxor %xmm11,%xmm12 +.byte 102,68,15,58,68,222,0 +.byte 102,68,15,58,68,238,17 +.byte 102,68,15,58,68,231,16 + xorps %xmm11,%xmm3 + xorps %xmm13,%xmm5 + movups 80(%rsi),%xmm7 + xorps %xmm12,%xmm4 + + movdqu 16(%rdx),%xmm11 + movdqu 0(%rdx),%xmm8 +.byte 102,69,15,56,0,218 +.byte 102,69,15,56,0,194 + movdqa %xmm11,%xmm13 + pshufd $78,%xmm11,%xmm12 + pxor %xmm8,%xmm0 + pxor %xmm11,%xmm12 +.byte 102,69,15,58,68,222,0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm8 + pxor %xmm0,%xmm8 +.byte 102,69,15,58,68,238,17 +.byte 102,68,15,58,68,231,0 + xorps %xmm11,%xmm3 + xorps %xmm13,%xmm5 + + leaq 64(%rdx),%rdx + subq $0x40,%rcx + jc .Ltail4x + + jmp .Lmod4_loop +.align 32 +.Lmod4_loop: +.byte 102,65,15,58,68,199,0 + xorps %xmm12,%xmm4 + movdqu 48(%rdx),%xmm11 +.byte 102,69,15,56,0,218 +.byte 102,65,15,58,68,207,17 + xorps %xmm3,%xmm0 + movdqu 32(%rdx),%xmm3 + movdqa %xmm11,%xmm13 +.byte 102,68,15,58,68,199,16 + pshufd $78,%xmm11,%xmm12 + xorps %xmm5,%xmm1 + pxor %xmm11,%xmm12 +.byte 102,65,15,56,0,218 + movups 32(%rsi),%xmm7 + xorps %xmm4,%xmm8 +.byte 102,68,15,58,68,218,0 + pshufd $78,%xmm3,%xmm4 + + pxor %xmm0,%xmm8 + movdqa %xmm3,%xmm5 + pxor %xmm1,%xmm8 + pxor %xmm3,%xmm4 + movdqa %xmm8,%xmm9 +.byte 102,68,15,58,68,234,17 + pslldq $8,%xmm8 + psrldq $8,%xmm9 + pxor %xmm8,%xmm0 + movdqa .L7_mask(%rip),%xmm8 + pxor %xmm9,%xmm1 +.byte 102,76,15,110,200 + + pand %xmm0,%xmm8 +.byte 102,69,15,56,0,200 + pxor %xmm0,%xmm9 +.byte 102,68,15,58,68,231,0 + psllq $57,%xmm9 + movdqa %xmm9,%xmm8 + pslldq $8,%xmm9 +.byte 102,15,58,68,222,0 + psrldq $8,%xmm8 + pxor %xmm9,%xmm0 + pxor %xmm8,%xmm1 + movdqu 0(%rdx),%xmm8 + + movdqa %xmm0,%xmm9 + psrlq $1,%xmm0 +.byte 102,15,58,68,238,17 + xorps %xmm11,%xmm3 + movdqu 16(%rdx),%xmm11 +.byte 102,69,15,56,0,218 +.byte 102,15,58,68,231,16 + xorps %xmm13,%xmm5 + movups 80(%rsi),%xmm7 +.byte 102,69,15,56,0,194 + pxor %xmm9,%xmm1 + pxor %xmm0,%xmm9 + psrlq $5,%xmm0 + + movdqa %xmm11,%xmm13 + pxor %xmm12,%xmm4 + pshufd $78,%xmm11,%xmm12 + pxor %xmm9,%xmm0 + pxor %xmm8,%xmm1 + pxor %xmm11,%xmm12 +.byte 102,69,15,58,68,222,0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + movdqa %xmm0,%xmm1 +.byte 102,69,15,58,68,238,17 + xorps %xmm11,%xmm3 + pshufd $78,%xmm0,%xmm8 + pxor %xmm0,%xmm8 + +.byte 102,68,15,58,68,231,0 + xorps %xmm13,%xmm5 + + leaq 64(%rdx),%rdx + subq $0x40,%rcx + jnc .Lmod4_loop + +.Ltail4x: +.byte 102,65,15,58,68,199,0 +.byte 102,65,15,58,68,207,17 +.byte 102,68,15,58,68,199,16 + xorps %xmm12,%xmm4 + xorps %xmm3,%xmm0 + xorps %xmm5,%xmm1 + pxor %xmm0,%xmm1 + pxor %xmm4,%xmm8 + + pxor %xmm1,%xmm8 + pxor %xmm0,%xmm1 + + movdqa %xmm8,%xmm9 + psrldq $8,%xmm8 + pslldq $8,%xmm9 + pxor %xmm8,%xmm1 + pxor %xmm9,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + addq $0x40,%rcx + jz .Ldone + movdqu 32(%rsi),%xmm7 + subq $0x10,%rcx + jz .Lodd_tail +.Lskip4x: + + + + + + movdqu (%rdx),%xmm8 + movdqu 16(%rdx),%xmm3 +.byte 102,69,15,56,0,194 +.byte 102,65,15,56,0,218 + pxor %xmm8,%xmm0 + + movdqa %xmm3,%xmm5 + pshufd $78,%xmm3,%xmm4 + pxor %xmm3,%xmm4 +.byte 102,15,58,68,218,0 +.byte 102,15,58,68,234,17 +.byte 102,15,58,68,231,0 + + leaq 32(%rdx),%rdx + nop + subq $0x20,%rcx + jbe .Leven_tail + nop + jmp .Lmod_loop + +.align 32 +.Lmod_loop: + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm8 + pshufd $78,%xmm0,%xmm4 + pxor %xmm0,%xmm4 + +.byte 102,15,58,68,198,0 +.byte 102,15,58,68,206,17 +.byte 102,15,58,68,231,16 + + pxor %xmm3,%xmm0 + pxor %xmm5,%xmm1 + movdqu (%rdx),%xmm9 + pxor %xmm0,%xmm8 +.byte 102,69,15,56,0,202 + movdqu 16(%rdx),%xmm3 + + pxor %xmm1,%xmm8 + pxor %xmm9,%xmm1 + pxor %xmm8,%xmm4 +.byte 102,65,15,56,0,218 + movdqa %xmm4,%xmm8 + psrldq $8,%xmm8 + pslldq $8,%xmm4 + pxor %xmm8,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm3,%xmm5 + + movdqa %xmm0,%xmm9 + movdqa %xmm0,%xmm8 + psllq $5,%xmm0 + pxor %xmm0,%xmm8 +.byte 102,15,58,68,218,0 + psllq $1,%xmm0 + pxor %xmm8,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm8 + pslldq $8,%xmm0 + psrldq $8,%xmm8 + pxor %xmm9,%xmm0 + pshufd $78,%xmm5,%xmm4 + pxor %xmm8,%xmm1 + pxor %xmm5,%xmm4 + + movdqa %xmm0,%xmm9 + psrlq $1,%xmm0 +.byte 102,15,58,68,234,17 + pxor %xmm9,%xmm1 + pxor %xmm0,%xmm9 + psrlq $5,%xmm0 + pxor %xmm9,%xmm0 + leaq 32(%rdx),%rdx + psrlq $1,%xmm0 +.byte 102,15,58,68,231,0 + pxor %xmm1,%xmm0 + + subq $0x20,%rcx + ja .Lmod_loop + +.Leven_tail: + movdqa %xmm0,%xmm1 + movdqa %xmm4,%xmm8 + pshufd $78,%xmm0,%xmm4 + pxor %xmm0,%xmm4 + +.byte 102,15,58,68,198,0 +.byte 102,15,58,68,206,17 +.byte 102,15,58,68,231,16 + + pxor %xmm3,%xmm0 + pxor %xmm5,%xmm1 + pxor %xmm0,%xmm8 + pxor %xmm1,%xmm8 + pxor %xmm8,%xmm4 + movdqa %xmm4,%xmm8 + psrldq $8,%xmm8 + pslldq $8,%xmm4 + pxor %xmm8,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 + testq %rcx,%rcx + jnz .Ldone + +.Lodd_tail: + movdqu (%rdx),%xmm8 +.byte 102,69,15,56,0,194 + pxor %xmm8,%xmm0 + movdqa %xmm0,%xmm1 + pshufd $78,%xmm0,%xmm3 + pxor %xmm0,%xmm3 +.byte 102,15,58,68,194,0 +.byte 102,15,58,68,202,17 +.byte 102,15,58,68,223,0 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + + movdqa %xmm3,%xmm4 + psrldq $8,%xmm3 + pslldq $8,%xmm4 + pxor %xmm3,%xmm1 + pxor %xmm4,%xmm0 + + movdqa %xmm0,%xmm4 + movdqa %xmm0,%xmm3 + psllq $5,%xmm0 + pxor %xmm0,%xmm3 + psllq $1,%xmm0 + pxor %xmm3,%xmm0 + psllq $57,%xmm0 + movdqa %xmm0,%xmm3 + pslldq $8,%xmm0 + psrldq $8,%xmm3 + pxor %xmm4,%xmm0 + pxor %xmm3,%xmm1 + + + movdqa %xmm0,%xmm4 + psrlq $1,%xmm0 + pxor %xmm4,%xmm1 + pxor %xmm0,%xmm4 + psrlq $5,%xmm0 + pxor %xmm4,%xmm0 + psrlq $1,%xmm0 + pxor %xmm1,%xmm0 +.Ldone: +.byte 102,65,15,56,0,194 + movdqu %xmm0,(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_ghash_clmul,.-gcm_ghash_clmul +.globl gcm_init_avx +.type gcm_init_avx,@function +.align 32 +gcm_init_avx: +.cfi_startproc + vzeroupper + + vmovdqu (%rsi),%xmm2 + vpshufd $78,%xmm2,%xmm2 + + + vpshufd $255,%xmm2,%xmm4 + vpsrlq $63,%xmm2,%xmm3 + vpsllq $1,%xmm2,%xmm2 + vpxor %xmm5,%xmm5,%xmm5 + vpcmpgtd %xmm4,%xmm5,%xmm5 + vpslldq $8,%xmm3,%xmm3 + vpor %xmm3,%xmm2,%xmm2 + + + vpand .L0x1c2_polynomial(%rip),%xmm5,%xmm5 + vpxor %xmm5,%xmm2,%xmm2 + + vpunpckhqdq %xmm2,%xmm2,%xmm6 + vmovdqa %xmm2,%xmm0 + vpxor %xmm2,%xmm6,%xmm6 + movq $4,%r10 + jmp .Linit_start_avx +.align 32 +.Linit_loop_avx: + vpalignr $8,%xmm3,%xmm4,%xmm5 + vmovdqu %xmm5,-16(%rdi) + vpunpckhqdq %xmm0,%xmm0,%xmm3 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm2,%xmm0,%xmm1 + vpclmulqdq $0x00,%xmm2,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm3,%xmm3 + vpxor %xmm0,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + + vpslldq $8,%xmm3,%xmm4 + vpsrldq $8,%xmm3,%xmm3 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm3,%xmm1,%xmm1 + vpsllq $57,%xmm0,%xmm3 + vpsllq $62,%xmm0,%xmm4 + vpxor %xmm3,%xmm4,%xmm4 + vpsllq $63,%xmm0,%xmm3 + vpxor %xmm3,%xmm4,%xmm4 + vpslldq $8,%xmm4,%xmm3 + vpsrldq $8,%xmm4,%xmm4 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm4,%xmm1,%xmm1 + + vpsrlq $1,%xmm0,%xmm4 + vpxor %xmm0,%xmm1,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $5,%xmm4,%xmm4 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $1,%xmm0,%xmm0 + vpxor %xmm1,%xmm0,%xmm0 +.Linit_start_avx: + vmovdqa %xmm0,%xmm5 + vpunpckhqdq %xmm0,%xmm0,%xmm3 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm2,%xmm0,%xmm1 + vpclmulqdq $0x00,%xmm2,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm3,%xmm3 + vpxor %xmm0,%xmm1,%xmm4 + vpxor %xmm4,%xmm3,%xmm3 + + vpslldq $8,%xmm3,%xmm4 + vpsrldq $8,%xmm3,%xmm3 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm3,%xmm1,%xmm1 + vpsllq $57,%xmm0,%xmm3 + vpsllq $62,%xmm0,%xmm4 + vpxor %xmm3,%xmm4,%xmm4 + vpsllq $63,%xmm0,%xmm3 + vpxor %xmm3,%xmm4,%xmm4 + vpslldq $8,%xmm4,%xmm3 + vpsrldq $8,%xmm4,%xmm4 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm4,%xmm1,%xmm1 + + vpsrlq $1,%xmm0,%xmm4 + vpxor %xmm0,%xmm1,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $5,%xmm4,%xmm4 + vpxor %xmm4,%xmm0,%xmm0 + vpsrlq $1,%xmm0,%xmm0 + vpxor %xmm1,%xmm0,%xmm0 + vpshufd $78,%xmm5,%xmm3 + vpshufd $78,%xmm0,%xmm4 + vpxor %xmm5,%xmm3,%xmm3 + vmovdqu %xmm5,0(%rdi) + vpxor %xmm0,%xmm4,%xmm4 + vmovdqu %xmm0,16(%rdi) + leaq 48(%rdi),%rdi + subq $1,%r10 + jnz .Linit_loop_avx + + vpalignr $8,%xmm4,%xmm3,%xmm5 + vmovdqu %xmm5,-16(%rdi) + + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_init_avx,.-gcm_init_avx +.globl gcm_gmult_avx +.type gcm_gmult_avx,@function +.align 32 +gcm_gmult_avx: +.cfi_startproc +.byte 243,15,30,250 + jmp .L_gmult_clmul +.cfi_endproc +.size gcm_gmult_avx,.-gcm_gmult_avx +.globl gcm_ghash_avx +.type gcm_ghash_avx,@function +.align 32 +gcm_ghash_avx: +.cfi_startproc +.byte 243,15,30,250 + vzeroupper + + vmovdqu (%rdi),%xmm10 + leaq .L0x1c2_polynomial(%rip),%r10 + leaq 64(%rsi),%rsi + vmovdqu .Lbswap_mask(%rip),%xmm13 + vpshufb %xmm13,%xmm10,%xmm10 + cmpq $0x80,%rcx + jb .Lshort_avx + subq $0x80,%rcx + + vmovdqu 112(%rdx),%xmm14 + vmovdqu 0-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm14 + vmovdqu 32-64(%rsi),%xmm7 + + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vmovdqu 96(%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm14,%xmm9,%xmm9 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 16-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vmovdqu 80(%rdx),%xmm14 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + + vpshufb %xmm13,%xmm14,%xmm14 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 48-64(%rsi),%xmm6 + vpxor %xmm14,%xmm9,%xmm9 + vmovdqu 64(%rdx),%xmm15 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 80-64(%rsi),%xmm7 + + vpshufb %xmm13,%xmm15,%xmm15 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm1,%xmm4,%xmm4 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 64-64(%rsi),%xmm6 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + + vmovdqu 48(%rdx),%xmm14 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpxor %xmm4,%xmm1,%xmm1 + vpshufb %xmm13,%xmm14,%xmm14 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 96-64(%rsi),%xmm6 + vpxor %xmm5,%xmm2,%xmm2 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 128-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + + vmovdqu 32(%rdx),%xmm15 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm1,%xmm4,%xmm4 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 112-64(%rsi),%xmm6 + vpxor %xmm2,%xmm5,%xmm5 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + + vmovdqu 16(%rdx),%xmm14 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpxor %xmm4,%xmm1,%xmm1 + vpshufb %xmm13,%xmm14,%xmm14 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 144-64(%rsi),%xmm6 + vpxor %xmm5,%xmm2,%xmm2 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 176-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + + vmovdqu (%rdx),%xmm15 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm1,%xmm4,%xmm4 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 160-64(%rsi),%xmm6 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x10,%xmm7,%xmm9,%xmm2 + + leaq 128(%rdx),%rdx + cmpq $0x80,%rcx + jb .Ltail_avx + + vpxor %xmm10,%xmm15,%xmm15 + subq $0x80,%rcx + jmp .Loop8x_avx + +.align 32 +.Loop8x_avx: + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vmovdqu 112(%rdx),%xmm14 + vpxor %xmm0,%xmm3,%xmm3 + vpxor %xmm15,%xmm8,%xmm8 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm10 + vpshufb %xmm13,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm11 + vmovdqu 0-64(%rsi),%xmm6 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm12 + vmovdqu 32-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + + vmovdqu 96(%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpxor %xmm3,%xmm10,%xmm10 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vxorps %xmm4,%xmm11,%xmm11 + vmovdqu 16-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm5,%xmm12,%xmm12 + vxorps %xmm15,%xmm8,%xmm8 + + vmovdqu 80(%rdx),%xmm14 + vpxor %xmm10,%xmm12,%xmm12 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpxor %xmm11,%xmm12,%xmm12 + vpslldq $8,%xmm12,%xmm9 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vpsrldq $8,%xmm12,%xmm12 + vpxor %xmm9,%xmm10,%xmm10 + vmovdqu 48-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm14 + vxorps %xmm12,%xmm11,%xmm11 + vpxor %xmm1,%xmm4,%xmm4 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 80-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu 64(%rdx),%xmm15 + vpalignr $8,%xmm10,%xmm10,%xmm12 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpshufb %xmm13,%xmm15,%xmm15 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 64-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vxorps %xmm15,%xmm8,%xmm8 + vpxor %xmm5,%xmm2,%xmm2 + + vmovdqu 48(%rdx),%xmm14 + vpclmulqdq $0x10,(%r10),%xmm10,%xmm10 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpshufb %xmm13,%xmm14,%xmm14 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 96-64(%rsi),%xmm6 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 128-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu 32(%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpshufb %xmm13,%xmm15,%xmm15 + vpxor %xmm3,%xmm0,%xmm0 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 112-64(%rsi),%xmm6 + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm4,%xmm1,%xmm1 + vpclmulqdq $0x00,%xmm7,%xmm9,%xmm2 + vpxor %xmm15,%xmm8,%xmm8 + vpxor %xmm5,%xmm2,%xmm2 + vxorps %xmm12,%xmm10,%xmm10 + + vmovdqu 16(%rdx),%xmm14 + vpalignr $8,%xmm10,%xmm10,%xmm12 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm3 + vpshufb %xmm13,%xmm14,%xmm14 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm4 + vmovdqu 144-64(%rsi),%xmm6 + vpclmulqdq $0x10,(%r10),%xmm10,%xmm10 + vxorps %xmm11,%xmm12,%xmm12 + vpunpckhqdq %xmm14,%xmm14,%xmm9 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x10,%xmm7,%xmm8,%xmm5 + vmovdqu 176-64(%rsi),%xmm7 + vpxor %xmm14,%xmm9,%xmm9 + vpxor %xmm2,%xmm5,%xmm5 + + vmovdqu (%rdx),%xmm15 + vpclmulqdq $0x00,%xmm6,%xmm14,%xmm0 + vpshufb %xmm13,%xmm15,%xmm15 + vpclmulqdq $0x11,%xmm6,%xmm14,%xmm1 + vmovdqu 160-64(%rsi),%xmm6 + vpxor %xmm12,%xmm15,%xmm15 + vpclmulqdq $0x10,%xmm7,%xmm9,%xmm2 + vpxor %xmm10,%xmm15,%xmm15 + + leaq 128(%rdx),%rdx + subq $0x80,%rcx + jnc .Loop8x_avx + + addq $0x80,%rcx + jmp .Ltail_no_xor_avx + +.align 32 +.Lshort_avx: + vmovdqu -16(%rdx,%rcx,1),%xmm14 + leaq (%rdx,%rcx,1),%rdx + vmovdqu 0-64(%rsi),%xmm6 + vmovdqu 32-64(%rsi),%xmm7 + vpshufb %xmm13,%xmm14,%xmm15 + + vmovdqa %xmm0,%xmm3 + vmovdqa %xmm1,%xmm4 + vmovdqa %xmm2,%xmm5 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -32(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 16-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vpsrldq $8,%xmm7,%xmm7 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -48(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 48-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vmovdqu 80-64(%rsi),%xmm7 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -64(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 64-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vpsrldq $8,%xmm7,%xmm7 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -80(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 96-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vmovdqu 128-64(%rsi),%xmm7 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -96(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 112-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vpsrldq $8,%xmm7,%xmm7 + subq $0x10,%rcx + jz .Ltail_avx + + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vmovdqu -112(%rdx),%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vmovdqu 144-64(%rsi),%xmm6 + vpshufb %xmm13,%xmm14,%xmm15 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + vmovq 184-64(%rsi),%xmm7 + subq $0x10,%rcx + jmp .Ltail_avx + +.align 32 +.Ltail_avx: + vpxor %xmm10,%xmm15,%xmm15 +.Ltail_no_xor_avx: + vpunpckhqdq %xmm15,%xmm15,%xmm8 + vpxor %xmm0,%xmm3,%xmm3 + vpclmulqdq $0x00,%xmm6,%xmm15,%xmm0 + vpxor %xmm15,%xmm8,%xmm8 + vpxor %xmm1,%xmm4,%xmm4 + vpclmulqdq $0x11,%xmm6,%xmm15,%xmm1 + vpxor %xmm2,%xmm5,%xmm5 + vpclmulqdq $0x00,%xmm7,%xmm8,%xmm2 + + vmovdqu (%r10),%xmm12 + + vpxor %xmm0,%xmm3,%xmm10 + vpxor %xmm1,%xmm4,%xmm11 + vpxor %xmm2,%xmm5,%xmm5 + + vpxor %xmm10,%xmm5,%xmm5 + vpxor %xmm11,%xmm5,%xmm5 + vpslldq $8,%xmm5,%xmm9 + vpsrldq $8,%xmm5,%xmm5 + vpxor %xmm9,%xmm10,%xmm10 + vpxor %xmm5,%xmm11,%xmm11 + + vpclmulqdq $0x10,%xmm12,%xmm10,%xmm9 + vpalignr $8,%xmm10,%xmm10,%xmm10 + vpxor %xmm9,%xmm10,%xmm10 + + vpclmulqdq $0x10,%xmm12,%xmm10,%xmm9 + vpalignr $8,%xmm10,%xmm10,%xmm10 + vpxor %xmm11,%xmm10,%xmm10 + vpxor %xmm9,%xmm10,%xmm10 + + cmpq $0,%rcx + jne .Lshort_avx + + vpshufb %xmm13,%xmm10,%xmm10 + vmovdqu %xmm10,(%rdi) + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.size gcm_ghash_avx,.-gcm_ghash_avx +.align 64 +.Lbswap_mask: +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.L0x1c2_polynomial: +.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 +.L7_mask: +.long 7,0,7,0 +.L7_mask_poly: +.long 7,0,450,0 +.align 64 +.type .Lrem_4bit,@object +.Lrem_4bit: +.long 0,0,0,471859200,0,943718400,0,610271232 +.long 0,1887436800,0,1822425088,0,1220542464,0,1423966208 +.long 0,3774873600,0,4246732800,0,3644850176,0,3311403008 +.long 0,2441084928,0,2376073216,0,2847932416,0,3051356160 +.type .Lrem_8bit,@object +.Lrem_8bit: +.value 0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E +.value 0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E +.value 0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E +.value 0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E +.value 0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E +.value 0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E +.value 0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E +.value 0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E +.value 0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE +.value 0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE +.value 0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE +.value 0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE +.value 0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E +.value 0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E +.value 0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE +.value 0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE +.value 0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E +.value 0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E +.value 0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E +.value 0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E +.value 0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E +.value 0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E +.value 0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E +.value 0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E +.value 0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE +.value 0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE +.value 0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE +.value 0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE +.value 0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E +.value 0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E +.value 0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE +.value 0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE + +.byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/modes/ghashv8-armx.S b/crypto/openssl/crypto/modes/ghashv8-armx.S new file mode 100644 index 000000000000..acd52eb95686 --- /dev/null +++ b/crypto/openssl/crypto/modes/ghashv8-armx.S @@ -0,0 +1,552 @@ +#include "arm_arch.h" + +#if __ARM_MAX_ARCH__>=7 +.arch armv8-a+crypto +.text +.globl gcm_init_v8 +.type gcm_init_v8,%function +.align 4 +gcm_init_v8: + ld1 {v17.2d},[x1] //load input H + movi v19.16b,#0xe1 + shl v19.2d,v19.2d,#57 //0xc2.0 + ext v3.16b,v17.16b,v17.16b,#8 + ushr v18.2d,v19.2d,#63 + dup v17.4s,v17.s[1] + ext v16.16b,v18.16b,v19.16b,#8 //t0=0xc2....01 + ushr v18.2d,v3.2d,#63 + sshr v17.4s,v17.4s,#31 //broadcast carry bit + and v18.16b,v18.16b,v16.16b + shl v3.2d,v3.2d,#1 + ext v18.16b,v18.16b,v18.16b,#8 + and v16.16b,v16.16b,v17.16b + orr v3.16b,v3.16b,v18.16b //H<<<=1 + eor v20.16b,v3.16b,v16.16b //twisted H + st1 {v20.2d},[x0],#16 //store Htable[0] + + //calculate H^2 + ext v16.16b,v20.16b,v20.16b,#8 //Karatsuba pre-processing + pmull v0.1q,v20.1d,v20.1d + eor v16.16b,v16.16b,v20.16b + pmull2 v2.1q,v20.2d,v20.2d + pmull v1.1q,v16.1d,v16.1d + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v22.16b,v0.16b,v18.16b + + ext v17.16b,v22.16b,v22.16b,#8 //Karatsuba pre-processing + eor v17.16b,v17.16b,v22.16b + ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed + st1 {v21.2d,v22.2d},[x0],#32 //store Htable[1..2] + //calculate H^3 and H^4 + pmull v0.1q,v20.1d, v22.1d + pmull v5.1q,v22.1d,v22.1d + pmull2 v2.1q,v20.2d, v22.2d + pmull2 v7.1q,v22.2d,v22.2d + pmull v1.1q,v16.1d,v17.1d + pmull v6.1q,v17.1d,v17.1d + + ext v16.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + ext v17.16b,v5.16b,v7.16b,#8 + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v16.16b + eor v4.16b,v5.16b,v7.16b + eor v6.16b,v6.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase + eor v6.16b,v6.16b,v4.16b + pmull v4.1q,v5.1d,v19.1d + + ins v2.d[0],v1.d[1] + ins v7.d[0],v6.d[1] + ins v1.d[1],v0.d[0] + ins v6.d[1],v5.d[0] + eor v0.16b,v1.16b,v18.16b + eor v5.16b,v6.16b,v4.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase + ext v4.16b,v5.16b,v5.16b,#8 + pmull v0.1q,v0.1d,v19.1d + pmull v5.1q,v5.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v4.16b,v4.16b,v7.16b + eor v20.16b, v0.16b,v18.16b //H^3 + eor v22.16b,v5.16b,v4.16b //H^4 + + ext v16.16b,v20.16b, v20.16b,#8 //Karatsuba pre-processing + ext v17.16b,v22.16b,v22.16b,#8 + eor v16.16b,v16.16b,v20.16b + eor v17.16b,v17.16b,v22.16b + ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed + st1 {v20.2d,v21.2d,v22.2d},[x0] //store Htable[3..5] + ret +.size gcm_init_v8,.-gcm_init_v8 +.globl gcm_gmult_v8 +.type gcm_gmult_v8,%function +.align 4 +gcm_gmult_v8: + ld1 {v17.2d},[x0] //load Xi + movi v19.16b,#0xe1 + ld1 {v20.2d,v21.2d},[x1] //load twisted H, ... + shl v19.2d,v19.2d,#57 +#ifndef __ARMEB__ + rev64 v17.16b,v17.16b +#endif + ext v3.16b,v17.16b,v17.16b,#8 + + pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo + eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi + pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi) + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + +#ifndef __ARMEB__ + rev64 v0.16b,v0.16b +#endif + ext v0.16b,v0.16b,v0.16b,#8 + st1 {v0.2d},[x0] //write out Xi + + ret +.size gcm_gmult_v8,.-gcm_gmult_v8 +.globl gcm_ghash_v8 +.type gcm_ghash_v8,%function +.align 4 +gcm_ghash_v8: + cmp x3,#64 + b.hs .Lgcm_ghash_v8_4x + ld1 {v0.2d},[x0] //load [rotated] Xi + //"[rotated]" means that + //loaded value would have + //to be rotated in order to + //make it appear as in + //algorithm specification + subs x3,x3,#32 //see if x3 is 32 or larger + mov x12,#16 //x12 is used as post- + //increment for input pointer; + //as loop is modulo-scheduled + //x12 is zeroed just in time + //to preclude overstepping + //inp[len], which means that + //last block[s] are actually + //loaded twice, but last + //copy is not processed + ld1 {v20.2d,v21.2d},[x1],#32 //load twisted H, ..., H^2 + movi v19.16b,#0xe1 + ld1 {v22.2d},[x1] + csel x12,xzr,x12,eq //is it time to zero x12? + ext v0.16b,v0.16b,v0.16b,#8 //rotate Xi + ld1 {v16.2d},[x2],#16 //load [rotated] I[0] + shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant +#ifndef __ARMEB__ + rev64 v16.16b,v16.16b + rev64 v0.16b,v0.16b +#endif + ext v3.16b,v16.16b,v16.16b,#8 //rotate I[0] + b.lo .Lodd_tail_v8 //x3 was less than 32 + ld1 {v17.2d},[x2],x12 //load [rotated] I[1] +#ifndef __ARMEB__ + rev64 v17.16b,v17.16b +#endif + ext v7.16b,v17.16b,v17.16b,#8 + eor v3.16b,v3.16b,v0.16b //I[i]^=Xi + pmull v4.1q,v20.1d,v7.1d //H·Ii+1 + eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing + pmull2 v6.1q,v20.2d,v7.2d + b .Loop_mod2x_v8 + +.align 4 +.Loop_mod2x_v8: + ext v18.16b,v3.16b,v3.16b,#8 + subs x3,x3,#32 //is there more data? + pmull v0.1q,v22.1d,v3.1d //H^2.lo·Xi.lo + csel x12,xzr,x12,lo //is it time to zero x12? + + pmull v5.1q,v21.1d,v17.1d + eor v18.16b,v18.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v22.2d,v3.2d //H^2.hi·Xi.hi + eor v0.16b,v0.16b,v4.16b //accumulate + pmull2 v1.1q,v21.2d,v18.2d //(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi) + ld1 {v16.2d},[x2],x12 //load [rotated] I[i+2] + + eor v2.16b,v2.16b,v6.16b + csel x12,xzr,x12,eq //is it time to zero x12? + eor v1.16b,v1.16b,v5.16b + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v17.2d},[x2],x12 //load [rotated] I[i+3] +#ifndef __ARMEB__ + rev64 v16.16b,v16.16b +#endif + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + +#ifndef __ARMEB__ + rev64 v17.16b,v17.16b +#endif + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v7.16b,v17.16b,v17.16b,#8 + ext v3.16b,v16.16b,v16.16b,#8 + eor v0.16b,v1.16b,v18.16b + pmull v4.1q,v20.1d,v7.1d //H·Ii+1 + eor v3.16b,v3.16b,v2.16b //accumulate v3.16b early + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v3.16b,v3.16b,v18.16b + eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing + eor v3.16b,v3.16b,v0.16b + pmull2 v6.1q,v20.2d,v7.2d + b.hs .Loop_mod2x_v8 //there was at least 32 more bytes + + eor v2.16b,v2.16b,v18.16b + ext v3.16b,v16.16b,v16.16b,#8 //re-construct v3.16b + adds x3,x3,#32 //re-construct x3 + eor v0.16b,v0.16b,v2.16b //re-construct v0.16b + b.eq .Ldone_v8 //is x3 zero? +.Lodd_tail_v8: + ext v18.16b,v0.16b,v0.16b,#8 + eor v3.16b,v3.16b,v0.16b //inp^=Xi + eor v17.16b,v16.16b,v18.16b //v17.16b is rotated inp^Xi + + pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo + eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi + pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi) + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + +.Ldone_v8: +#ifndef __ARMEB__ + rev64 v0.16b,v0.16b +#endif + ext v0.16b,v0.16b,v0.16b,#8 + st1 {v0.2d},[x0] //write out Xi + + ret +.size gcm_ghash_v8,.-gcm_ghash_v8 +.type gcm_ghash_v8_4x,%function +.align 4 +gcm_ghash_v8_4x: +.Lgcm_ghash_v8_4x: + ld1 {v0.2d},[x0] //load [rotated] Xi + ld1 {v20.2d,v21.2d,v22.2d},[x1],#48 //load twisted H, ..., H^2 + movi v19.16b,#0xe1 + ld1 {v26.2d,v27.2d,v28.2d},[x1] //load twisted H^3, ..., H^4 + shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant + + ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 +#ifndef __ARMEB__ + rev64 v0.16b,v0.16b + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v7.16b,v7.16b + rev64 v4.16b,v4.16b +#endif + ext v25.16b,v7.16b,v7.16b,#8 + ext v24.16b,v6.16b,v6.16b,#8 + ext v23.16b,v5.16b,v5.16b,#8 + + pmull v29.1q,v20.1d,v25.1d //H·Ii+3 + eor v7.16b,v7.16b,v25.16b + pmull2 v31.1q,v20.2d,v25.2d + pmull v30.1q,v21.1d,v7.1d + + pmull v16.1q,v22.1d,v24.1d //H^2·Ii+2 + eor v6.16b,v6.16b,v24.16b + pmull2 v24.1q,v22.2d,v24.2d + pmull2 v6.1q,v21.2d,v6.2d + + eor v29.16b,v29.16b,v16.16b + eor v31.16b,v31.16b,v24.16b + eor v30.16b,v30.16b,v6.16b + + pmull v7.1q,v26.1d,v23.1d //H^3·Ii+1 + eor v5.16b,v5.16b,v23.16b + pmull2 v23.1q,v26.2d,v23.2d + pmull v5.1q,v27.1d,v5.1d + + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + eor v30.16b,v30.16b,v5.16b + + subs x3,x3,#128 + b.lo .Ltail4x + + b .Loop4x + +.align 4 +.Loop4x: + eor v16.16b,v4.16b,v0.16b + ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 + ext v3.16b,v16.16b,v16.16b,#8 +#ifndef __ARMEB__ + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v7.16b,v7.16b + rev64 v4.16b,v4.16b +#endif + + pmull v0.1q,v28.1d,v3.1d //H^4·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v28.2d,v3.2d + ext v25.16b,v7.16b,v7.16b,#8 + pmull2 v1.1q,v27.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + ext v24.16b,v6.16b,v6.16b,#8 + eor v1.16b,v1.16b,v30.16b + ext v23.16b,v5.16b,v5.16b,#8 + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + pmull v29.1q,v20.1d,v25.1d //H·Ii+3 + eor v7.16b,v7.16b,v25.16b + eor v1.16b,v1.16b,v17.16b + pmull2 v31.1q,v20.2d,v25.2d + eor v1.16b,v1.16b,v18.16b + pmull v30.1q,v21.1d,v7.1d + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + pmull v16.1q,v22.1d,v24.1d //H^2·Ii+2 + eor v6.16b,v6.16b,v24.16b + pmull2 v24.1q,v22.2d,v24.2d + eor v0.16b,v1.16b,v18.16b + pmull2 v6.1q,v21.2d,v6.2d + + eor v29.16b,v29.16b,v16.16b + eor v31.16b,v31.16b,v24.16b + eor v30.16b,v30.16b,v6.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + pmull v7.1q,v26.1d,v23.1d //H^3·Ii+1 + eor v5.16b,v5.16b,v23.16b + eor v18.16b,v18.16b,v2.16b + pmull2 v23.1q,v26.2d,v23.2d + pmull v5.1q,v27.1d,v5.1d + + eor v0.16b,v0.16b,v18.16b + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + ext v0.16b,v0.16b,v0.16b,#8 + eor v30.16b,v30.16b,v5.16b + + subs x3,x3,#64 + b.hs .Loop4x + +.Ltail4x: + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull v0.1q,v28.1d,v3.1d //H^4·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v28.2d,v3.2d + pmull2 v1.1q,v27.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + + adds x3,x3,#64 + b.eq .Ldone4x + + cmp x3,#32 + b.lo .Lone + b.eq .Ltwo +.Lthree: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d,v5.2d,v6.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __ARMEB__ + rev64 v5.16b,v5.16b + rev64 v6.16b,v6.16b + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v24.16b,v6.16b,v6.16b,#8 + ext v23.16b,v5.16b,v5.16b,#8 + eor v0.16b,v1.16b,v18.16b + + pmull v29.1q,v20.1d,v24.1d //H·Ii+2 + eor v6.16b,v6.16b,v24.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + pmull2 v31.1q,v20.2d,v24.2d + pmull v30.1q,v21.1d,v6.1d + eor v0.16b,v0.16b,v18.16b + pmull v7.1q,v22.1d,v23.1d //H^2·Ii+1 + eor v5.16b,v5.16b,v23.16b + ext v0.16b,v0.16b,v0.16b,#8 + + pmull2 v23.1q,v22.2d,v23.2d + eor v16.16b,v4.16b,v0.16b + pmull2 v5.1q,v21.2d,v5.2d + ext v3.16b,v16.16b,v16.16b,#8 + + eor v29.16b,v29.16b,v7.16b + eor v31.16b,v31.16b,v23.16b + eor v30.16b,v30.16b,v5.16b + + pmull v0.1q,v26.1d,v3.1d //H^3·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v26.2d,v3.2d + pmull v1.1q,v27.1d,v16.1d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + b .Ldone4x + +.align 4 +.Ltwo: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d,v5.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __ARMEB__ + rev64 v5.16b,v5.16b + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v23.16b,v5.16b,v5.16b,#8 + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + + pmull v29.1q,v20.1d,v23.1d //H·Ii+1 + eor v5.16b,v5.16b,v23.16b + + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull2 v31.1q,v20.2d,v23.2d + pmull v30.1q,v21.1d,v5.1d + + pmull v0.1q,v22.1d,v3.1d //H^2·(Xi+Ii) + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v22.2d,v3.2d + pmull2 v1.1q,v21.2d,v16.2d + + eor v0.16b,v0.16b,v29.16b + eor v2.16b,v2.16b,v31.16b + eor v1.16b,v1.16b,v30.16b + b .Ldone4x + +.align 4 +.Lone: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v4.2d},[x2] + eor v1.16b,v1.16b,v18.16b +#ifndef __ARMEB__ + rev64 v4.16b,v4.16b +#endif + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + + eor v16.16b,v4.16b,v0.16b + ext v3.16b,v16.16b,v16.16b,#8 + + pmull v0.1q,v20.1d,v3.1d + eor v16.16b,v16.16b,v3.16b + pmull2 v2.1q,v20.2d,v3.2d + pmull v1.1q,v21.1d,v16.1d + +.Ldone4x: + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + ext v0.16b,v0.16b,v0.16b,#8 + +#ifndef __ARMEB__ + rev64 v0.16b,v0.16b +#endif + st1 {v0.2d},[x0] //write out Xi + + ret +.size gcm_ghash_v8_4x,.-gcm_ghash_v8_4x +.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#endif diff --git a/crypto/openssl/crypto/modes/ocb128.c b/crypto/openssl/crypto/modes/ocb128.c index b39a55a1a145..b5202ba5bd56 100644 --- a/crypto/openssl/crypto/modes/ocb128.c +++ b/crypto/openssl/crypto/modes/ocb128.c @@ -1,7 +1,7 @@ /* - * Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,7 +10,7 @@ #include #include #include -#include "modes_local.h" +#include "crypto/modes.h" #ifndef OPENSSL_NO_OCB @@ -156,7 +156,7 @@ int CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec, ctx->l_index = 0; ctx->max_l_index = 5; if ((ctx->l = OPENSSL_malloc(ctx->max_l_index * 16)) == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_OCB128_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } @@ -203,7 +203,7 @@ int CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src, dest->keydec = keydec; if (src->l) { if ((dest->l = OPENSSL_malloc(src->max_l_index * 16)) == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_OCB128_COPY_CTX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } memcpy(dest->l, src->l, (src->l_index + 1) * 16); diff --git a/crypto/openssl/crypto/modes/ofb128.c b/crypto/openssl/crypto/modes/ofb128.c index a3469712b2de..d8319f861ed4 100644 --- a/crypto/openssl/crypto/modes/ofb128.c +++ b/crypto/openssl/crypto/modes/ofb128.c @@ -1,15 +1,15 @@ /* - * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include "modes_local.h" #include +#include +#include "crypto/modes.h" #if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) typedef size_t size_t_aX __attribute((__aligned__(1))); @@ -29,6 +29,11 @@ void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, unsigned int n; size_t l = 0; + if (*num < 0) { + /* There is no good way to signal an error return from here */ + *num = -1; + return; + } n = *num; #if !defined(OPENSSL_SMALL_FOOTPRINT) diff --git a/crypto/openssl/crypto/modes/siv128.c b/crypto/openssl/crypto/modes/siv128.c new file mode 100644 index 000000000000..e6348a8d3753 --- /dev/null +++ b/crypto/openssl/crypto/modes/siv128.c @@ -0,0 +1,393 @@ +/* + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include "internal/endian.h" +#include "crypto/modes.h" +#include "crypto/siv.h" + +#ifndef OPENSSL_NO_SIV + +__owur static ossl_inline uint32_t rotl8(uint32_t x) +{ + return (x << 8) | (x >> 24); +} + +__owur static ossl_inline uint32_t rotr8(uint32_t x) +{ + return (x >> 8) | (x << 24); +} + +__owur static ossl_inline uint64_t byteswap8(uint64_t x) +{ + uint32_t high = (uint32_t)(x >> 32); + uint32_t low = (uint32_t)x; + + high = (rotl8(high) & 0x00ff00ff) | (rotr8(high) & 0xff00ff00); + low = (rotl8(low) & 0x00ff00ff) | (rotr8(low) & 0xff00ff00); + return ((uint64_t)low) << 32 | (uint64_t)high; +} + +__owur static ossl_inline uint64_t siv128_getword(SIV_BLOCK const *b, size_t i) +{ + DECLARE_IS_ENDIAN; + + if (IS_LITTLE_ENDIAN) + return byteswap8(b->word[i]); + return b->word[i]; +} + +static ossl_inline void siv128_putword(SIV_BLOCK *b, size_t i, uint64_t x) +{ + DECLARE_IS_ENDIAN; + + if (IS_LITTLE_ENDIAN) + b->word[i] = byteswap8(x); + else + b->word[i] = x; +} + +static ossl_inline void siv128_xorblock(SIV_BLOCK *x, + SIV_BLOCK const *y) +{ + x->word[0] ^= y->word[0]; + x->word[1] ^= y->word[1]; +} + +/* + * Doubles |b|, which is 16 bytes representing an element + * of GF(2**128) modulo the irreducible polynomial + * x**128 + x**7 + x**2 + x + 1. + * Assumes two's-complement arithmetic + */ +static ossl_inline void siv128_dbl(SIV_BLOCK *b) +{ + uint64_t high = siv128_getword(b, 0); + uint64_t low = siv128_getword(b, 1); + uint64_t high_carry = high & (((uint64_t)1) << 63); + uint64_t low_carry = low & (((uint64_t)1) << 63); + int64_t low_mask = -((int64_t)(high_carry >> 63)) & 0x87; + uint64_t high_mask = low_carry >> 63; + + high = (high << 1) | high_mask; + low = (low << 1) ^ (uint64_t)low_mask; + siv128_putword(b, 0, high); + siv128_putword(b, 1, low); +} + +__owur static ossl_inline int siv128_do_s2v_p(SIV128_CONTEXT *ctx, SIV_BLOCK *out, + unsigned char const* in, size_t len) +{ + SIV_BLOCK t; + size_t out_len = sizeof(out->byte); + EVP_MAC_CTX *mac_ctx; + int ret = 0; + + mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init); + if (mac_ctx == NULL) + return 0; + + if (len >= SIV_LEN) { + if (!EVP_MAC_update(mac_ctx, in, len - SIV_LEN)) + goto err; + memcpy(&t, in + (len-SIV_LEN), SIV_LEN); + siv128_xorblock(&t, &ctx->d); + if (!EVP_MAC_update(mac_ctx, t.byte, SIV_LEN)) + goto err; + } else { + memset(&t, 0, sizeof(t)); + memcpy(&t, in, len); + t.byte[len] = 0x80; + siv128_dbl(&ctx->d); + siv128_xorblock(&t, &ctx->d); + if (!EVP_MAC_update(mac_ctx, t.byte, SIV_LEN)) + goto err; + } + if (!EVP_MAC_final(mac_ctx, out->byte, &out_len, sizeof(out->byte)) + || out_len != SIV_LEN) + goto err; + + ret = 1; + +err: + EVP_MAC_CTX_free(mac_ctx); + return ret; +} + + +__owur static ossl_inline int siv128_do_encrypt(EVP_CIPHER_CTX *ctx, unsigned char *out, + unsigned char const *in, size_t len, + SIV_BLOCK *icv) +{ + int out_len = (int)len; + + if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, icv->byte, 1)) + return 0; + return EVP_EncryptUpdate(ctx, out, &out_len, in, out_len); +} + +/* + * Create a new SIV128_CONTEXT + */ +SIV128_CONTEXT *ossl_siv128_new(const unsigned char *key, int klen, + EVP_CIPHER *cbc, EVP_CIPHER *ctr, + OSSL_LIB_CTX *libctx, const char *propq) +{ + SIV128_CONTEXT *ctx; + int ret; + + if ((ctx = OPENSSL_malloc(sizeof(*ctx))) != NULL) { + ret = ossl_siv128_init(ctx, key, klen, cbc, ctr, libctx, propq); + if (ret) + return ctx; + OPENSSL_free(ctx); + } + + return NULL; +} + +/* + * Initialise an existing SIV128_CONTEXT + */ +int ossl_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen, + const EVP_CIPHER *cbc, const EVP_CIPHER *ctr, + OSSL_LIB_CTX *libctx, const char *propq) +{ + static const unsigned char zero[SIV_LEN] = { 0 }; + size_t out_len = SIV_LEN; + EVP_MAC_CTX *mac_ctx = NULL; + OSSL_PARAM params[3]; + const char *cbc_name; + + if (ctx == NULL) + return 0; + + memset(&ctx->d, 0, sizeof(ctx->d)); + EVP_CIPHER_CTX_free(ctx->cipher_ctx); + EVP_MAC_CTX_free(ctx->mac_ctx_init); + EVP_MAC_free(ctx->mac); + ctx->mac = NULL; + ctx->cipher_ctx = NULL; + ctx->mac_ctx_init = NULL; + + if (key == NULL || cbc == NULL || ctr == NULL) + return 0; + + cbc_name = EVP_CIPHER_get0_name(cbc); + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, + (char *)cbc_name, 0); + params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (void *)key, klen); + params[2] = OSSL_PARAM_construct_end(); + + if ((ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL + || (ctx->mac = + EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, propq)) == NULL + || (ctx->mac_ctx_init = EVP_MAC_CTX_new(ctx->mac)) == NULL + || !EVP_MAC_CTX_set_params(ctx->mac_ctx_init, params) + || !EVP_EncryptInit_ex(ctx->cipher_ctx, ctr, NULL, key + klen, NULL) + || (mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init)) == NULL + || !EVP_MAC_update(mac_ctx, zero, sizeof(zero)) + || !EVP_MAC_final(mac_ctx, ctx->d.byte, &out_len, + sizeof(ctx->d.byte))) { + EVP_CIPHER_CTX_free(ctx->cipher_ctx); + EVP_MAC_CTX_free(ctx->mac_ctx_init); + EVP_MAC_CTX_free(mac_ctx); + EVP_MAC_free(ctx->mac); + return 0; + } + EVP_MAC_CTX_free(mac_ctx); + + ctx->final_ret = -1; + ctx->crypto_ok = 1; + + return 1; +} + +/* + * Copy an SIV128_CONTEXT object + */ +int ossl_siv128_copy_ctx(SIV128_CONTEXT *dest, SIV128_CONTEXT *src) +{ + memcpy(&dest->d, &src->d, sizeof(src->d)); + if (dest->cipher_ctx == NULL) { + dest->cipher_ctx = EVP_CIPHER_CTX_new(); + if (dest->cipher_ctx == NULL) + return 0; + } + if (!EVP_CIPHER_CTX_copy(dest->cipher_ctx, src->cipher_ctx)) + return 0; + EVP_MAC_CTX_free(dest->mac_ctx_init); + dest->mac_ctx_init = EVP_MAC_CTX_dup(src->mac_ctx_init); + if (dest->mac_ctx_init == NULL) + return 0; + dest->mac = src->mac; + if (dest->mac != NULL) + EVP_MAC_up_ref(dest->mac); + return 1; +} + +/* + * Provide any AAD. This can be called multiple times. + * Per RFC5297, the last piece of associated data + * is the nonce, but it's not treated special + */ +int ossl_siv128_aad(SIV128_CONTEXT *ctx, const unsigned char *aad, + size_t len) +{ + SIV_BLOCK mac_out; + size_t out_len = SIV_LEN; + EVP_MAC_CTX *mac_ctx; + + siv128_dbl(&ctx->d); + + if ((mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init)) == NULL + || !EVP_MAC_update(mac_ctx, aad, len) + || !EVP_MAC_final(mac_ctx, mac_out.byte, &out_len, + sizeof(mac_out.byte)) + || out_len != SIV_LEN) { + EVP_MAC_CTX_free(mac_ctx); + return 0; + } + EVP_MAC_CTX_free(mac_ctx); + + siv128_xorblock(&ctx->d, &mac_out); + + return 1; +} + +/* + * Provide any data to be encrypted. This can be called once. + */ +int ossl_siv128_encrypt(SIV128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len) +{ + SIV_BLOCK q; + + /* can only do one crypto operation */ + if (ctx->crypto_ok == 0) + return 0; + ctx->crypto_ok--; + + if (!siv128_do_s2v_p(ctx, &q, in, len)) + return 0; + + memcpy(ctx->tag.byte, &q, SIV_LEN); + q.byte[8] &= 0x7f; + q.byte[12] &= 0x7f; + + if (!siv128_do_encrypt(ctx->cipher_ctx, out, in, len, &q)) + return 0; + ctx->final_ret = 0; + return len; +} + +/* + * Provide any data to be decrypted. This can be called once. + */ +int ossl_siv128_decrypt(SIV128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len) +{ + unsigned char* p; + SIV_BLOCK t, q; + int i; + + /* can only do one crypto operation */ + if (ctx->crypto_ok == 0) + return 0; + ctx->crypto_ok--; + + memcpy(&q, ctx->tag.byte, SIV_LEN); + q.byte[8] &= 0x7f; + q.byte[12] &= 0x7f; + + if (!siv128_do_encrypt(ctx->cipher_ctx, out, in, len, &q) + || !siv128_do_s2v_p(ctx, &t, out, len)) + return 0; + + p = ctx->tag.byte; + for (i = 0; i < SIV_LEN; i++) + t.byte[i] ^= p[i]; + + if ((t.word[0] | t.word[1]) != 0) { + OPENSSL_cleanse(out, len); + return 0; + } + ctx->final_ret = 0; + return len; +} + +/* + * Return the already calculated final result. + */ +int ossl_siv128_finish(SIV128_CONTEXT *ctx) +{ + return ctx->final_ret; +} + +/* + * Set the tag + */ +int ossl_siv128_set_tag(SIV128_CONTEXT *ctx, const unsigned char *tag, size_t len) +{ + if (len != SIV_LEN) + return 0; + + /* Copy the tag from the supplied buffer */ + memcpy(ctx->tag.byte, tag, len); + return 1; +} + +/* + * Retrieve the calculated tag + */ +int ossl_siv128_get_tag(SIV128_CONTEXT *ctx, unsigned char *tag, size_t len) +{ + if (len != SIV_LEN) + return 0; + + /* Copy the tag into the supplied buffer */ + memcpy(tag, ctx->tag.byte, len); + return 1; +} + +/* + * Release all resources + */ +int ossl_siv128_cleanup(SIV128_CONTEXT *ctx) +{ + if (ctx != NULL) { + EVP_CIPHER_CTX_free(ctx->cipher_ctx); + ctx->cipher_ctx = NULL; + EVP_MAC_CTX_free(ctx->mac_ctx_init); + ctx->mac_ctx_init = NULL; + EVP_MAC_free(ctx->mac); + ctx->mac = NULL; + OPENSSL_cleanse(&ctx->d, sizeof(ctx->d)); + OPENSSL_cleanse(&ctx->tag, sizeof(ctx->tag)); + ctx->final_ret = -1; + ctx->crypto_ok = 1; + } + return 1; +} + +int ossl_siv128_speed(SIV128_CONTEXT *ctx, int arg) +{ + ctx->crypto_ok = (arg == 1) ? -1 : 1; + return 1; +} + +#endif /* OPENSSL_NO_SIV */ diff --git a/crypto/openssl/crypto/modes/wrap128.c b/crypto/openssl/crypto/modes/wrap128.c index d7e56cc260ad..a9622c16bd76 100644 --- a/crypto/openssl/crypto/modes/wrap128.c +++ b/crypto/openssl/crypto/modes/wrap128.c @@ -1,7 +1,7 @@ /* * Copyright 2013-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/modes/xts128.c b/crypto/openssl/crypto/modes/xts128.c index fe1626c62e10..55b81366bf82 100644 --- a/crypto/openssl/crypto/modes/xts128.c +++ b/crypto/openssl/crypto/modes/xts128.c @@ -1,15 +1,16 @@ /* * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include "modes_local.h" #include +#include +#include "internal/endian.h" +#include "crypto/modes.h" #ifndef STRICT_ALIGNMENT # ifdef __GNUC__ @@ -24,12 +25,7 @@ int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char *inp, unsigned char *out, size_t len, int enc) { - const union { - long one; - char little; - } is_endian = { - 1 - }; + DECLARE_IS_ENDIAN; union { u64 u[2]; u32 d[4]; @@ -72,7 +68,7 @@ int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, if (len == 0) return 0; - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { unsigned int carry, res; res = 0x87 & (((int)tweak.d[3]) >> 31); @@ -111,7 +107,7 @@ int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, u8 c[16]; } tweak1; - if (is_endian.little) { + if (IS_LITTLE_ENDIAN) { unsigned int carry, res; res = 0x87 & (((int)tweak.d[3]) >> 31); diff --git a/crypto/openssl/crypto/o_dir.c b/crypto/openssl/crypto/o_dir.c index fca9c75e0533..6857a2e17d4f 100644 --- a/crypto/openssl/crypto/o_dir.c +++ b/crypto/openssl/crypto/o_dir.c @@ -1,7 +1,7 @@ /* * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/o_fips.c b/crypto/openssl/crypto/o_fips.c deleted file mode 100644 index 050ea9c216cf..000000000000 --- a/crypto/openssl/crypto/o_fips.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2011-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 - */ - -#include "internal/cryptlib.h" - -int FIPS_mode(void) -{ - /* This version of the library does not support FIPS mode. */ - return 0; -} - -int FIPS_mode_set(int r) -{ - if (r == 0) - return 1; - CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED); - return 0; -} diff --git a/crypto/openssl/crypto/o_fopen.c b/crypto/openssl/crypto/o_fopen.c index 7d51ad725426..8095fffbe0c9 100644 --- a/crypto/openssl/crypto/o_fopen.c +++ b/crypto/openssl/crypto/o_fopen.c @@ -1,7 +1,7 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -88,7 +88,7 @@ FILE *openssl_fopen(const char *filename, const char *mode) char lastchar; if ((newname = OPENSSL_malloc(strlen(filename) + 1)) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_FOPEN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/openssl/crypto/o_init.c b/crypto/openssl/crypto/o_init.c index ed6b1303d8ad..a0b4256f78f6 100644 --- a/crypto/openssl/crypto/o_init.c +++ b/crypto/openssl/crypto/o_init.c @@ -1,7 +1,7 @@ /* * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/o_str.c b/crypto/openssl/crypto/o_str.c index eb9f21cc0c45..7fa487dd5fcd 100644 --- a/crypto/openssl/crypto/o_str.c +++ b/crypto/openssl/crypto/o_str.c @@ -1,28 +1,22 @@ /* - * Copyright 2003-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2003-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include "e_os.h" +#include #include #include +#include "crypto/ctype.h" #include "internal/cryptlib.h" -#include "internal/o_str.h" +#include "internal/thread_once.h" -int OPENSSL_memcmp(const void *v1, const void *v2, size_t n) -{ - const unsigned char *c1 = v1, *c2 = v2; - int ret = 0; - - while (n && (ret = *c1 - *c2) == 0) - n--, c1++, c2++; - - return ret; -} +#define DEFAULT_SEPARATOR ':' +#define CH_ZERO '\0' char *CRYPTO_strdup(const char *str, const char* file, int line) { @@ -49,7 +43,7 @@ char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line) ret = CRYPTO_malloc(maxlen + 1, file, line); if (ret) { memcpy(ret, str, maxlen); - ret[maxlen] = '\0'; + ret[maxlen] = CH_ZERO; } return ret; } @@ -63,7 +57,7 @@ void *CRYPTO_memdup(const void *data, size_t siz, const char* file, int line) ret = CRYPTO_malloc(siz, file, line); if (ret == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_MEMDUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return NULL; } return memcpy(ret, data, siz); @@ -73,7 +67,7 @@ size_t OPENSSL_strnlen(const char *str, size_t maxlen) { const char *p; - for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ; + for (p = str; maxlen-- != 0 && *p != CH_ZERO; ++p) ; return p - str; } @@ -86,7 +80,7 @@ size_t OPENSSL_strlcpy(char *dst, const char *src, size_t size) l++; } if (size) - *dst = '\0'; + *dst = CH_ZERO; return l + strlen(src); } @@ -141,81 +135,163 @@ int OPENSSL_hexchar2int(unsigned char c) return -1; } -/* - * Give a string of hex digits convert to a buffer - */ -unsigned char *OPENSSL_hexstr2buf(const char *str, long *len) +static int hexstr2buf_sep(unsigned char *buf, size_t buf_n, size_t *buflen, + const char *str, const char sep) { - unsigned char *hexbuf, *q; + unsigned char *q; unsigned char ch, cl; int chi, cli; const unsigned char *p; - size_t s; + size_t cnt; - s = strlen(str); - if ((hexbuf = OPENSSL_malloc(s >> 1)) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (p = (const unsigned char *)str, q = hexbuf; *p; ) { + for (p = (const unsigned char *)str, q = buf, cnt = 0; *p; ) { ch = *p++; - if (ch == ':') + /* A separator of CH_ZERO means there is no separator */ + if (ch == sep && sep != CH_ZERO) continue; cl = *p++; if (!cl) { - CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, - CRYPTO_R_ODD_NUMBER_OF_DIGITS); - OPENSSL_free(hexbuf); - return NULL; + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_ODD_NUMBER_OF_DIGITS); + return 0; } cli = OPENSSL_hexchar2int(cl); chi = OPENSSL_hexchar2int(ch); if (cli < 0 || chi < 0) { - OPENSSL_free(hexbuf); - CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT); - return NULL; + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_ILLEGAL_HEX_DIGIT); + return 0; + } + cnt++; + if (q != NULL) { + if (cnt > buf_n) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER); + return 0; + } + *q++ = (unsigned char)((chi << 4) | cli); } - *q++ = (unsigned char)((chi << 4) | cli); } - if (len) - *len = q - hexbuf; - return hexbuf; + if (buflen != NULL) + *buflen = cnt; + return 1; } /* - * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its - * hex representation @@@ (Contents of buffer are always kept in ASCII, also - * on EBCDIC machines) + * Given a string of hex digits convert to a buffer */ -char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len) +int OPENSSL_hexstr2buf_ex(unsigned char *buf, size_t buf_n, size_t *buflen, + const char *str, const char sep) +{ + return hexstr2buf_sep(buf, buf_n, buflen, str, sep); +} + +unsigned char *ossl_hexstr2buf_sep(const char *str, long *buflen, + const char sep) +{ + unsigned char *buf; + size_t buf_n, tmp_buflen; + + buf_n = strlen(str); + if (buf_n <= 1) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_HEX_STRING_TOO_SHORT); + return NULL; + } + buf_n /= 2; + if ((buf = OPENSSL_malloc(buf_n)) == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (buflen != NULL) + *buflen = 0; + tmp_buflen = 0; + if (hexstr2buf_sep(buf, buf_n, &tmp_buflen, str, sep)) { + if (buflen != NULL) + *buflen = (long)tmp_buflen; + return buf; + } + OPENSSL_free(buf); + return NULL; +} + +unsigned char *OPENSSL_hexstr2buf(const char *str, long *buflen) +{ + return ossl_hexstr2buf_sep(str, buflen, DEFAULT_SEPARATOR); +} + +static int buf2hexstr_sep(char *str, size_t str_n, size_t *strlength, + const unsigned char *buf, size_t buflen, + const char sep) { static const char hexdig[] = "0123456789ABCDEF"; - char *tmp, *q; const unsigned char *p; - int i; + char *q; + size_t i; + int has_sep = (sep != CH_ZERO); + size_t len = has_sep ? buflen * 3 : 1 + buflen * 2; - if (len == 0) - { - return OPENSSL_zalloc(1); - } + if (strlength != NULL) + *strlength = len; + if (str == NULL) + return 1; - if ((tmp = OPENSSL_malloc(len * 3)) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR, ERR_R_MALLOC_FAILURE); - return NULL; + if (str_n < (unsigned long)len) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER); + return 0; } - q = tmp; - for (i = 0, p = buffer; i < len; i++, p++) { + + q = str; + for (i = 0, p = buf; i < buflen; i++, p++) { *q++ = hexdig[(*p >> 4) & 0xf]; *q++ = hexdig[*p & 0xf]; - *q++ = ':'; + if (has_sep) + *q++ = sep; } - q[-1] = 0; + if (has_sep) + --q; + *q = CH_ZERO; + #ifdef CHARSET_EBCDIC - ebcdic2ascii(tmp, tmp, q - tmp - 1); + ebcdic2ascii(str, str, q - str - 1); #endif + return 1; +} - return tmp; +int OPENSSL_buf2hexstr_ex(char *str, size_t str_n, size_t *strlength, + const unsigned char *buf, size_t buflen, + const char sep) +{ + return buf2hexstr_sep(str, str_n, strlength, buf, buflen, sep); +} + +char *ossl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep) +{ + char *tmp; + size_t tmp_n; + + if (buflen == 0) + return OPENSSL_zalloc(1); + + tmp_n = (sep != CH_ZERO) ? buflen * 3 : 1 + buflen * 2; + if ((tmp = OPENSSL_malloc(tmp_n)) == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (buf2hexstr_sep(tmp, tmp_n, NULL, buf, buflen, sep)) + return tmp; + OPENSSL_free(tmp); + return NULL; +} + + +/* + * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its + * hex representation @@@ (Contents of buffer are always kept in ASCII, also + * on EBCDIC machines) + */ +char *OPENSSL_buf2hexstr(const unsigned char *buf, long buflen) +{ + return ossl_buf2hexstr_sep(buf, buflen, ':'); } int openssl_strerror_r(int errnum, char *buf, size_t buflen) @@ -265,3 +341,26 @@ int openssl_strerror_r(int errnum, char *buf, size_t buflen) return 1; #endif } + +int OPENSSL_strcasecmp(const char *s1, const char *s2) +{ + int t; + + while ((t = ossl_tolower(*s1) - ossl_tolower(*s2++)) == 0) + if (*s1++ == '\0') + return 0; + return t; +} + +int OPENSSL_strncasecmp(const char *s1, const char *s2, size_t n) +{ + int t; + size_t i; + + for (i = 0; i < n; i++) + if ((t = ossl_tolower(*s1) - ossl_tolower(*s2++)) != 0) + return t; + else if (*s1++ == '\0') + return 0; + return 0; +} diff --git a/crypto/openssl/crypto/o_time.c b/crypto/openssl/crypto/o_time.c index 3fa70c45af83..23ffe162453e 100644 --- a/crypto/openssl/crypto/o_time.c +++ b/crypto/openssl/crypto/o_time.c @@ -1,7 +1,7 @@ /* * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/objects/README b/crypto/openssl/crypto/objects/README deleted file mode 100644 index 700f9c5e54f9..000000000000 --- a/crypto/openssl/crypto/objects/README +++ /dev/null @@ -1,44 +0,0 @@ -objects.txt syntax ------------------- - -To cover all the naming hacks that were previously in objects.h needed some -kind of hacks in objects.txt. - -The basic syntax for adding an object is as follows: - - 1 2 3 4 : shortName : Long Name - - If Long Name contains only word characters and hyphen-minus - (0x2D) or full stop (0x2E) then Long Name is used as basis - for the base name in C. Otherwise, the shortName is used. - - The base name (let's call it 'base') will then be used to - create the C macros SN_base, LN_base, NID_base and OBJ_base. - - Note that if the base name contains spaces, dashes or periods, - those will be converted to underscore. - -Then there are some extra commands: - - !Alias foo 1 2 3 4 - - This just makes a name foo for an OID. The C macro - OBJ_foo will be created as a result. - - !Cname foo - - This makes sure that the name foo will be used as base name - in C. - - !module foo - 1 2 3 4 : shortName : Long Name - !global - - The !module command was meant to define a kind of modularity. - What it does is to make sure the module name is prepended - to the base name. !global turns this off. This construction - is not recursive. - -Lines starting with # are treated as comments, as well as any line starting -with ! and not matching the commands above. - diff --git a/crypto/openssl/crypto/objects/README.md b/crypto/openssl/crypto/objects/README.md new file mode 100644 index 000000000000..49c749887d2f --- /dev/null +++ b/crypto/openssl/crypto/objects/README.md @@ -0,0 +1,43 @@ +objects.txt syntax +================== + +To cover all the naming hacks that were previously in `objects.h` needed some +kind of hacks in `objects.txt`. + +The basic syntax for adding an object is as follows: + + 1 2 3 4 : shortName : Long Name + + If Long Name contains only word characters and hyphen-minus + (0x2D) or full stop (0x2E) then Long Name is used as basis + for the base name in C. Otherwise, the shortName is used. + + The base name (let's call it 'base') will then be used to + create the C macros SN_base, LN_base, NID_base and OBJ_base. + + Note that if the base name contains spaces, dashes or periods, + those will be converted to underscore. + +Then there are some extra commands: + + !Alias foo 1 2 3 4 + + This just makes a name foo for an OID. The C macro + OBJ_foo will be created as a result. + + !Cname foo + + This makes sure that the name foo will be used as base name + in C. + + !module foo + 1 2 3 4 : shortName : Long Name + !global + + The !module command was meant to define a kind of modularity. + What it does is to make sure the module name is prepended + to the base name. !global turns this off. This construction + is not recursive. + +Lines starting with `#` are treated as comments, as well as any line starting +with ! and not matching the commands above. diff --git a/crypto/openssl/crypto/objects/o_names.c b/crypto/openssl/crypto/objects/o_names.c index 872676ba2277..791f2b011e35 100644 --- a/crypto/openssl/crypto/objects/o_names.c +++ b/crypto/openssl/crypto/objects/o_names.c @@ -1,7 +1,7 @@ /* - * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -21,23 +21,6 @@ #include "obj_local.h" #include "e_os.h" -/* - * We define this wrapper for two reasons. Firstly, later versions of - * DEC C add linkage information to certain functions, which makes it - * tricky to use them as values to regular function pointers. - * Secondly, in the EDK2 build environment, the strcasecmp function is - * actually an external function with the Microsoft ABI, so we can't - * transparently assign function pointers to it. - */ -#if defined(OPENSSL_SYS_VMS_DECC) || defined(OPENSSL_SYS_UEFI) -static int obj_strcasecmp(const char *a, const char *b) -{ - return strcasecmp(a, b); -} -#else -#define obj_strcasecmp strcasecmp -#endif - /* * I use the ex_data stuff to manage the identifiers for the obj_name_types * that applications may define. I only really use the free function field. @@ -66,7 +49,6 @@ static int obj_name_cmp(const OBJ_NAME *a, const OBJ_NAME *b); static CRYPTO_ONCE init = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(o_names_init) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); names_lh = NULL; obj_lock = CRYPTO_THREAD_lock_new(); if (obj_lock != NULL) @@ -75,7 +57,6 @@ DEFINE_RUN_ONCE_STATIC(o_names_init) CRYPTO_THREAD_lock_free(obj_lock); obj_lock = NULL; } - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); return names_lh != NULL && obj_lock != NULL; } @@ -94,13 +75,11 @@ int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), if (!OBJ_NAME_init()) return 0; - CRYPTO_THREAD_write_lock(obj_lock); + if (!CRYPTO_THREAD_write_lock(obj_lock)) + return 0; - if (name_funcs_stack == NULL) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); + if (name_funcs_stack == NULL) name_funcs_stack = sk_NAME_FUNCS_new_null(); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - } if (name_funcs_stack == NULL) { /* ERROR */ goto out; @@ -108,23 +87,18 @@ int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), ret = names_type_num; names_type_num++; for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); name_funcs = OPENSSL_zalloc(sizeof(*name_funcs)); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); if (name_funcs == NULL) { - OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); ret = 0; goto out; } - name_funcs->hash_func = openssl_lh_strcasehash; - name_funcs->cmp_func = obj_strcasecmp; - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); - + name_funcs->hash_func = ossl_lh_strcasehash; + name_funcs->cmp_func = OPENSSL_strcasecmp; push = sk_NAME_FUNCS_push(name_funcs_stack, name_funcs); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); if (!push) { - OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); OPENSSL_free(name_funcs); ret = 0; goto out; @@ -154,7 +128,7 @@ static int obj_name_cmp(const OBJ_NAME *a, const OBJ_NAME *b) ret = sk_NAME_FUNCS_value(name_funcs_stack, a->type)->cmp_func(a->name, b->name); } else - ret = strcasecmp(a->name, b->name); + ret = OPENSSL_strcasecmp(a->name, b->name); } return ret; } @@ -169,7 +143,7 @@ static unsigned long obj_name_hash(const OBJ_NAME *a) sk_NAME_FUNCS_value(name_funcs_stack, a->type)->hash_func(a->name); } else { - ret = openssl_lh_strcasehash(a->name); + ret = ossl_lh_strcasehash(a->name); } ret ^= a->type; return ret; @@ -185,7 +159,8 @@ const char *OBJ_NAME_get(const char *name, int type) return NULL; if (!OBJ_NAME_init()) return NULL; - CRYPTO_THREAD_read_lock(obj_lock); + if (!CRYPTO_THREAD_read_lock(obj_lock)) + return NULL; alias = type & OBJ_NAME_ALIAS; type &= ~OBJ_NAME_ALIAS; @@ -231,7 +206,10 @@ int OBJ_NAME_add(const char *name, int type, const char *data) onp->type = type; onp->data = data; - CRYPTO_THREAD_write_lock(obj_lock); + if (!CRYPTO_THREAD_write_lock(obj_lock)) { + OPENSSL_free(onp); + return 0; + } ret = lh_OBJ_NAME_insert(names_lh, onp); if (ret != NULL) { @@ -270,7 +248,8 @@ int OBJ_NAME_remove(const char *name, int type) if (!OBJ_NAME_init()) return 0; - CRYPTO_THREAD_write_lock(obj_lock); + if (!CRYPTO_THREAD_write_lock(obj_lock)) + return 0; type &= ~OBJ_NAME_ALIAS; on.name = name; diff --git a/crypto/openssl/crypto/objects/obj_compat.h b/crypto/openssl/crypto/objects/obj_compat.h new file mode 100644 index 000000000000..7d890d1c0b85 --- /dev/null +++ b/crypto/openssl/crypto/objects/obj_compat.h @@ -0,0 +1,54 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_NO_DEPRECATED_3_0 + +#define SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm SN_magma_ctr_acpkm +#define NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm NID_magma_ctr_acpkm +#define OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm OBJ_magma_ctr_acpkm + +#define SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac SN_magma_ctr_acpkm_omac +#define NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac NID_magma_ctr_acpkm_omac +#define OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac OBJ_magma_ctr_acpkm_omac + +#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm SN_kuznyechik_ctr_acpkm +#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm NID_kuznyechik_ctr_acpkm +#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm OBJ_kuznyechik_ctr_acpkm + +#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac SN_kuznyechik_ctr_acpkm_omac +#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac NID_kuznyechik_ctr_acpkm_omac +#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac OBJ_kuznyechik_ctr_acpkm_omac + +#define SN_id_tc26_wrap_gostr3412_2015_magma_kexp15 SN_magma_kexp15 +#define NID_id_tc26_wrap_gostr3412_2015_magma_kexp15 NID_magma_kexp15 +#define OBJ_id_tc26_wrap_gostr3412_2015_magma_kexp15 OBJ_magma_kexp15 + +#define SN_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 SN_kuznyechik_kexp15 +#define NID_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 NID_kuznyechik_kexp15 +#define OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 OBJ_kuznyechik_kexp15 + +#define SN_grasshopper_ecb SN_kuznyechik_ecb +#define NID_grasshopper_ecb NID_kuznyechik_ecb + +#define SN_grasshopper_ctr SN_kuznyechik_ctr +#define NID_grasshopper_ctr NID_kuznyechik_ctr + +#define SN_grasshopper_ofb SN_kuznyechik_ofb +#define NID_grasshopper_ofb NID_kuznyechik_ofb + +#define SN_grasshopper_cbc SN_kuznyechik_cbc +#define NID_grasshopper_cbc NID_kuznyechik_cbc + +#define SN_grasshopper_cfb SN_kuznyechik_cfb +#define NID_grasshopper_cfb NID_kuznyechik_cfb + +#define SN_grasshopper_mac SN_kuznyechik_mac +#define NID_grasshopper_mac NID_kuznyechik_mac + +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ diff --git a/crypto/openssl/crypto/objects/obj_dat.c b/crypto/openssl/crypto/objects/obj_dat.c index 7e8de727f310..01cde00e98b7 100644 --- a/crypto/openssl/crypto/objects/obj_dat.c +++ b/crypto/openssl/crypto/objects/obj_dat.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -150,7 +150,7 @@ static void cleanup3_doall(ADDED_OBJ *a) OPENSSL_free(a); } -void obj_cleanup_int(void) +void ossl_obj_cleanup_int(void) { if (added == NULL) return; @@ -209,7 +209,7 @@ int OBJ_add_object(const ASN1_OBJECT *obj) return o->nid; err2: - OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); err: for (i = ADDED_DATA; i <= ADDED_NID; i++) OPENSSL_free(ao[i]); @@ -224,25 +224,27 @@ ASN1_OBJECT *OBJ_nid2obj(int n) if ((n >= 0) && (n < NUM_NID)) { if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { - OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); + ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID); return NULL; } return (ASN1_OBJECT *)&(nid_objs[n]); - } else if (added == NULL) { - OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); - return NULL; - } else { - ad.type = ADDED_NID; - ad.obj = &ob; - ob.nid = n; - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return adp->obj; - else { - OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); - return NULL; - } } + + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + + if (added == NULL) + return NULL; + + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return adp->obj; + + ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID); + return NULL; } const char *OBJ_nid2sn(int n) @@ -252,24 +254,27 @@ const char *OBJ_nid2sn(int n) if ((n >= 0) && (n < NUM_NID)) { if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { - OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); + ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID); return NULL; } return nid_objs[n].sn; - } else if (added == NULL) - return NULL; - else { - ad.type = ADDED_NID; - ad.obj = &ob; - ob.nid = n; - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return adp->obj->sn; - else { - OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); - return NULL; - } } + + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + + if (added == NULL) + return NULL; + + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return adp->obj->sn; + + ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID); + return NULL; } const char *OBJ_nid2ln(int n) @@ -279,24 +284,27 @@ const char *OBJ_nid2ln(int n) if ((n >= 0) && (n < NUM_NID)) { if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { - OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); + ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID); return NULL; } return nid_objs[n].ln; - } else if (added == NULL) - return NULL; - else { - ad.type = ADDED_NID; - ad.obj = &ob; - ob.nid = n; - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return adp->obj->ln; - else { - OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); - return NULL; - } } + + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + + if (added == NULL) + return NULL; + + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return adp->obj->ln; + + ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID); + return NULL; } static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp) @@ -328,6 +336,9 @@ int OBJ_obj2nid(const ASN1_OBJECT *a) if (a->length == 0) return NID_undef; + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + if (added != NULL) { ad.type = ADDED_DATA; ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */ @@ -361,6 +372,10 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) if (((nid = OBJ_sn2nid(s)) != NID_undef) || ((nid = OBJ_ln2nid(s)) != NID_undef)) return OBJ_nid2obj(nid); + if (!ossl_isdigit(*s)) { + ERR_raise(ERR_LIB_OBJ, OBJ_R_UNKNOWN_OBJECT_NAME); + return NULL; + } } /* Work out size of content octets */ @@ -378,7 +393,7 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) return NULL; if ((buf = OPENSSL_malloc(j)) == NULL) { - OBJerr(OBJ_F_OBJ_TXT2OBJ, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); return NULL; } @@ -545,6 +560,9 @@ int OBJ_ln2nid(const char *s) ADDED_OBJ ad, *adp; const unsigned int *op; + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + o.ln = s; if (added != NULL) { ad.type = ADDED_LNAME; @@ -566,6 +584,9 @@ int OBJ_sn2nid(const char *s) ADDED_OBJ ad, *adp; const unsigned int *op; + /* Make sure we've loaded config before checking for any "added" objects */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + o.sn = s; if (added != NULL) { ad.type = ADDED_SNAME; @@ -586,52 +607,32 @@ const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, return OBJ_bsearch_ex_(key, base, num, size, cmp, 0); } -const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num, +const void *OBJ_bsearch_ex_(const void *key, const void *base, int num, int size, int (*cmp) (const void *, const void *), int flags) { - const char *base = base_; - int l, h, i = 0, c = 0; - const char *p = NULL; + const char *p = ossl_bsearch(key, base, num, size, cmp, flags); - if (num == 0) - return NULL; - l = 0; - h = num; - while (l < h) { - i = (l + h) / 2; - p = &(base[i * size]); - c = (*cmp) (key, p); - if (c < 0) - h = i; - else if (c > 0) - l = i + 1; - else - break; - } #ifdef CHARSET_EBCDIC /* * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I * don't have perl (yet), we revert to a *LINEAR* search when the object * wasn't found in the binary search. */ - if (c != 0) { + if (p == NULL) { + const char *base_ = base; + int l, h, i = 0, c = 0; + for (i = 0; i < num; ++i) { - p = &(base[i * size]); + p = &(base_[i * size]); c = (*cmp) (key, p); - if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))) + if (c == 0 + || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))) return p; } } #endif - if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)) - p = NULL; - else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) { - while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0) - i--; - p = &(base[i * size]); - } return p; } @@ -696,7 +697,7 @@ int OBJ_create(const char *oid, const char *sn, const char *ln) /* Check to see if short or long name already present */ if ((sn != NULL && OBJ_sn2nid(sn) != NID_undef) || (ln != NULL && OBJ_ln2nid(ln) != NID_undef)) { - OBJerr(OBJ_F_OBJ_CREATE, OBJ_R_OID_EXISTS); + ERR_raise(ERR_LIB_OBJ, OBJ_R_OID_EXISTS); return 0; } @@ -707,11 +708,14 @@ int OBJ_create(const char *oid, const char *sn, const char *ln) /* If NID is not NID_undef then object already exists */ if (OBJ_obj2nid(tmpoid) != NID_undef) { - OBJerr(OBJ_F_OBJ_CREATE, OBJ_R_OID_EXISTS); + ERR_raise(ERR_LIB_OBJ, OBJ_R_OID_EXISTS); goto err; } tmpoid->nid = OBJ_new_nid(1); + if (tmpoid->nid == NID_undef) + goto err; + tmpoid->sn = (char *)sn; tmpoid->ln = (char *)ln; diff --git a/crypto/openssl/crypto/objects/obj_dat.h b/crypto/openssl/crypto/objects/obj_dat.h index 63bf69e4437d..59d156117a00 100644 --- a/crypto/openssl/crypto/objects/obj_dat.h +++ b/crypto/openssl/crypto/objects/obj_dat.h @@ -3,14 +3,14 @@ * Generated by crypto/objects/obj_dat.pl * * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ /* Serialized OID's */ -static const unsigned char so[7762] = { +static const unsigned char so[8076] = { 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ @@ -1061,24 +1061,63 @@ static const unsigned char so[7762] = { 0x2B,0x6F,0x02,0x8C,0x53, /* [ 7612] OBJ_ieee_siswg */ 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D, /* [ 7617] OBJ_sm2 */ 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x01, /* [ 7625] OBJ_id_tc26_cipher_gostr3412_2015_magma */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x01,0x01, /* [ 7633] OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x01,0x02, /* [ 7642] OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac */ + 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x01,0x01, /* [ 7633] OBJ_magma_ctr_acpkm */ + 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x01,0x02, /* [ 7642] OBJ_magma_ctr_acpkm_omac */ 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x02, /* [ 7651] OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x02,0x01, /* [ 7659] OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x02,0x02, /* [ 7668] OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac */ + 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x02,0x01, /* [ 7659] OBJ_kuznyechik_ctr_acpkm */ + 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x02,0x02, /* [ 7668] OBJ_kuznyechik_ctr_acpkm_omac */ 0x2A,0x85,0x03,0x07,0x01,0x01,0x07, /* [ 7677] OBJ_id_tc26_wrap */ 0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x01, /* [ 7684] OBJ_id_tc26_wrap_gostr3412_2015_magma */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x01,0x01, /* [ 7692] OBJ_id_tc26_wrap_gostr3412_2015_magma_kexp15 */ + 0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x01,0x01, /* [ 7692] OBJ_magma_kexp15 */ 0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x02, /* [ 7701] OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x02,0x01, /* [ 7709] OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 */ + 0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x02,0x01, /* [ 7709] OBJ_kuznyechik_kexp15 */ 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x02, /* [ 7718] OBJ_id_tc26_gost_3410_2012_256_paramSetB */ 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x03, /* [ 7727] OBJ_id_tc26_gost_3410_2012_256_paramSetC */ 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x04, /* [ 7736] OBJ_id_tc26_gost_3410_2012_256_paramSetD */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0C, /* [ 7745] OBJ_hmacWithSHA512_224 */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0D, /* [ 7753] OBJ_hmacWithSHA512_256 */ + 0x28,0xCC,0x45,0x03,0x04, /* [ 7761] OBJ_gmac */ + 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x13, /* [ 7766] OBJ_kmac128 */ + 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x14, /* [ 7775] OBJ_kmac256 */ + 0x2B,0x06,0x01,0x04,0x01,0x8D,0x3A,0x0C,0x02,0x01, /* [ 7784] OBJ_blake2bmac */ + 0x2B,0x06,0x01,0x04,0x01,0x8D,0x3A,0x0C,0x02,0x02, /* [ 7794] OBJ_blake2smac */ + 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [ 7804] OBJ_SM2_with_SM3 */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x09, /* [ 7812] OBJ_id_on_SmtpUTF8Mailbox */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x05, /* [ 7820] OBJ_XmppAddr */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x07, /* [ 7828] OBJ_SRVName */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x08, /* [ 7836] OBJ_NAIRealm */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1D, /* [ 7844] OBJ_cmcArchive */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1E, /* [ 7852] OBJ_id_kp_bgpsec_router */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1F, /* [ 7860] OBJ_id_kp_BrandIndicatorforMessageIdentification */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x20, /* [ 7868] OBJ_cmKGA */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x11, /* [ 7876] OBJ_id_it_caCerts */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x12, /* [ 7884] OBJ_id_it_rootCaKeyUpdate */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x13, /* [ 7892] OBJ_id_it_certReqTemplate */ + 0x2A,0x85,0x03,0x64,0x05, /* [ 7900] OBJ_OGRNIP */ + 0x2A,0x85,0x03,0x64,0x71, /* [ 7905] OBJ_classSignTool */ + 0x2A,0x85,0x03,0x64,0x71,0x01, /* [ 7910] OBJ_classSignToolKC1 */ + 0x2A,0x85,0x03,0x64,0x71,0x02, /* [ 7916] OBJ_classSignToolKC2 */ + 0x2A,0x85,0x03,0x64,0x71,0x03, /* [ 7922] OBJ_classSignToolKC3 */ + 0x2A,0x85,0x03,0x64,0x71,0x04, /* [ 7928] OBJ_classSignToolKB1 */ + 0x2A,0x85,0x03,0x64,0x71,0x05, /* [ 7934] OBJ_classSignToolKB2 */ + 0x2A,0x85,0x03,0x64,0x71,0x06, /* [ 7940] OBJ_classSignToolKA1 */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x18, /* [ 7946] OBJ_id_ct_routeOriginAuthz */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1A, /* [ 7957] OBJ_id_ct_rpkiManifest */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x23, /* [ 7968] OBJ_id_ct_rpkiGhostbusters */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x24, /* [ 7979] OBJ_id_ct_resourceTaggedAttest */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x0E, /* [ 7990] OBJ_id_cp */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x1C, /* [ 7997] OBJ_sbgp_ipAddrBlockv2 */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x1D, /* [ 8005] OBJ_sbgp_autonomousSysNumv2 */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x0E,0x02, /* [ 8013] OBJ_ipAddr_asNumber */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x0E,0x03, /* [ 8021] OBJ_ipAddr_asNumberv2 */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x0A, /* [ 8029] OBJ_rpkiManifest */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x0B, /* [ 8037] OBJ_signedObject */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x0D, /* [ 8045] OBJ_rpkiNotify */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x2F, /* [ 8053] OBJ_id_ct_geofeedCSVwithCRLF */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x30, /* [ 8064] OBJ_id_ct_signedChecklist */ }; -#define NUM_NID 1195 +#define NUM_NID 1248 static const ASN1_OBJECT nid_objs[NUM_NID] = { {"UNDEF", "undefined", NID_undef}, {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, @@ -2092,12 +2131,12 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"gost89-cbc", "gost89-cbc", NID_gost89_cbc}, {"gost89-ecb", "gost89-ecb", NID_gost89_ecb}, {"gost89-ctr", "gost89-ctr", NID_gost89_ctr}, - {"grasshopper-ecb", "grasshopper-ecb", NID_grasshopper_ecb}, - {"grasshopper-ctr", "grasshopper-ctr", NID_grasshopper_ctr}, - {"grasshopper-ofb", "grasshopper-ofb", NID_grasshopper_ofb}, - {"grasshopper-cbc", "grasshopper-cbc", NID_grasshopper_cbc}, - {"grasshopper-cfb", "grasshopper-cfb", NID_grasshopper_cfb}, - {"grasshopper-mac", "grasshopper-mac", NID_grasshopper_mac}, + {"kuznyechik-ecb", "kuznyechik-ecb", NID_kuznyechik_ecb}, + {"kuznyechik-ctr", "kuznyechik-ctr", NID_kuznyechik_ctr}, + {"kuznyechik-ofb", "kuznyechik-ofb", NID_kuznyechik_ofb}, + {"kuznyechik-cbc", "kuznyechik-cbc", NID_kuznyechik_cbc}, + {"kuznyechik-cfb", "kuznyechik-cfb", NID_kuznyechik_cfb}, + {"kuznyechik-mac", "kuznyechik-mac", NID_kuznyechik_mac}, {"ChaCha20-Poly1305", "chacha20-poly1305", NID_chacha20_poly1305}, {"ChaCha20", "chacha20", NID_chacha20}, {"tlsfeature", "TLS Feature", NID_tlsfeature, 8, &so[6619]}, @@ -2254,16 +2293,16 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"ieee-siswg", "IEEE Security in Storage Working Group", NID_ieee_siswg, 5, &so[7612]}, {"SM2", "sm2", NID_sm2, 8, &so[7617]}, {"id-tc26-cipher-gostr3412-2015-magma", "id-tc26-cipher-gostr3412-2015-magma", NID_id_tc26_cipher_gostr3412_2015_magma, 8, &so[7625]}, - {"id-tc26-cipher-gostr3412-2015-magma-ctracpkm", "id-tc26-cipher-gostr3412-2015-magma-ctracpkm", NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm, 9, &so[7633]}, - {"id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac", "id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac", NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac, 9, &so[7642]}, + {"magma-ctr-acpkm", "magma-ctr-acpkm", NID_magma_ctr_acpkm, 9, &so[7633]}, + {"magma-ctr-acpkm-omac", "magma-ctr-acpkm-omac", NID_magma_ctr_acpkm_omac, 9, &so[7642]}, {"id-tc26-cipher-gostr3412-2015-kuznyechik", "id-tc26-cipher-gostr3412-2015-kuznyechik", NID_id_tc26_cipher_gostr3412_2015_kuznyechik, 8, &so[7651]}, - {"id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm", "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm", NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm, 9, &so[7659]}, - {"id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm-omac", "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm-omac", NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac, 9, &so[7668]}, + {"kuznyechik-ctr-acpkm", "kuznyechik-ctr-acpkm", NID_kuznyechik_ctr_acpkm, 9, &so[7659]}, + {"kuznyechik-ctr-acpkm-omac", "kuznyechik-ctr-acpkm-omac", NID_kuznyechik_ctr_acpkm_omac, 9, &so[7668]}, {"id-tc26-wrap", "id-tc26-wrap", NID_id_tc26_wrap, 7, &so[7677]}, {"id-tc26-wrap-gostr3412-2015-magma", "id-tc26-wrap-gostr3412-2015-magma", NID_id_tc26_wrap_gostr3412_2015_magma, 8, &so[7684]}, - {"id-tc26-wrap-gostr3412-2015-magma-kexp15", "id-tc26-wrap-gostr3412-2015-magma-kexp15", NID_id_tc26_wrap_gostr3412_2015_magma_kexp15, 9, &so[7692]}, + {"magma-kexp15", "magma-kexp15", NID_magma_kexp15, 9, &so[7692]}, {"id-tc26-wrap-gostr3412-2015-kuznyechik", "id-tc26-wrap-gostr3412-2015-kuznyechik", NID_id_tc26_wrap_gostr3412_2015_kuznyechik, 8, &so[7701]}, - {"id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15", "id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15", NID_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15, 9, &so[7709]}, + {"kuznyechik-kexp15", "kuznyechik-kexp15", NID_kuznyechik_kexp15, 9, &so[7709]}, {"id-tc26-gost-3410-2012-256-paramSetB", "GOST R 34.10-2012 (256 bit) ParamSet B", NID_id_tc26_gost_3410_2012_256_paramSetB, 9, &so[7718]}, {"id-tc26-gost-3410-2012-256-paramSetC", "GOST R 34.10-2012 (256 bit) ParamSet C", NID_id_tc26_gost_3410_2012_256_paramSetC, 9, &so[7727]}, {"id-tc26-gost-3410-2012-256-paramSetD", "GOST R 34.10-2012 (256 bit) ParamSet D", NID_id_tc26_gost_3410_2012_256_paramSetD, 9, &so[7736]}, @@ -2275,9 +2314,62 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"magma-mac", "magma-mac", NID_magma_mac}, {"hmacWithSHA512-224", "hmacWithSHA512-224", NID_hmacWithSHA512_224, 8, &so[7745]}, {"hmacWithSHA512-256", "hmacWithSHA512-256", NID_hmacWithSHA512_256, 8, &so[7753]}, + {"GMAC", "gmac", NID_gmac, 5, &so[7761]}, + {"KMAC128", "kmac128", NID_kmac128, 9, &so[7766]}, + {"KMAC256", "kmac256", NID_kmac256, 9, &so[7775]}, + {"AES-128-SIV", "aes-128-siv", NID_aes_128_siv}, + {"AES-192-SIV", "aes-192-siv", NID_aes_192_siv}, + {"AES-256-SIV", "aes-256-siv", NID_aes_256_siv}, + {"BLAKE2BMAC", "blake2bmac", NID_blake2bmac, 10, &so[7784]}, + {"BLAKE2SMAC", "blake2smac", NID_blake2smac, 10, &so[7794]}, + {"SSHKDF", "sshkdf", NID_sshkdf}, + {"SM2-SM3", "SM2-with-SM3", NID_SM2_with_SM3, 8, &so[7804]}, + {"SSKDF", "sskdf", NID_sskdf}, + {"X963KDF", "x963kdf", NID_x963kdf}, + {"X942KDF", "x942kdf", NID_x942kdf}, + {"id-on-SmtpUTF8Mailbox", "Smtp UTF8 Mailbox", NID_id_on_SmtpUTF8Mailbox, 8, &so[7812]}, + {"id-on-xmppAddr", "XmppAddr", NID_XmppAddr, 8, &so[7820]}, + {"id-on-dnsSRV", "SRVName", NID_SRVName, 8, &so[7828]}, + {"id-on-NAIRealm", "NAIRealm", NID_NAIRealm, 8, &so[7836]}, + {"modp_1536", "modp_1536", NID_modp_1536}, + {"modp_2048", "modp_2048", NID_modp_2048}, + {"modp_3072", "modp_3072", NID_modp_3072}, + {"modp_4096", "modp_4096", NID_modp_4096}, + {"modp_6144", "modp_6144", NID_modp_6144}, + {"modp_8192", "modp_8192", NID_modp_8192}, + {"KxGOST18", "kx-gost18", NID_kx_gost18}, + {"cmcArchive", "CMC Archive Server", NID_cmcArchive, 8, &so[7844]}, + {"id-kp-bgpsec-router", "BGPsec Router", NID_id_kp_bgpsec_router, 8, &so[7852]}, + {"id-kp-BrandIndicatorforMessageIdentification", "Brand Indicator for Message Identification", NID_id_kp_BrandIndicatorforMessageIdentification, 8, &so[7860]}, + {"cmKGA", "Certificate Management Key Generation Authority", NID_cmKGA, 8, &so[7868]}, + {"id-it-caCerts", "id-it-caCerts", NID_id_it_caCerts, 8, &so[7876]}, + {"id-it-rootCaKeyUpdate", "id-it-rootCaKeyUpdate", NID_id_it_rootCaKeyUpdate, 8, &so[7884]}, + {"id-it-certReqTemplate", "id-it-certReqTemplate", NID_id_it_certReqTemplate, 8, &so[7892]}, + {"OGRNIP", "OGRNIP", NID_OGRNIP, 5, &so[7900]}, + {"classSignTool", "Class of Signing Tool", NID_classSignTool, 5, &so[7905]}, + {"classSignToolKC1", "Class of Signing Tool KC1", NID_classSignToolKC1, 6, &so[7910]}, + {"classSignToolKC2", "Class of Signing Tool KC2", NID_classSignToolKC2, 6, &so[7916]}, + {"classSignToolKC3", "Class of Signing Tool KC3", NID_classSignToolKC3, 6, &so[7922]}, + {"classSignToolKB1", "Class of Signing Tool KB1", NID_classSignToolKB1, 6, &so[7928]}, + {"classSignToolKB2", "Class of Signing Tool KB2", NID_classSignToolKB2, 6, &so[7934]}, + {"classSignToolKA1", "Class of Signing Tool KA1", NID_classSignToolKA1, 6, &so[7940]}, + {"id-ct-routeOriginAuthz", "id-ct-routeOriginAuthz", NID_id_ct_routeOriginAuthz, 11, &so[7946]}, + {"id-ct-rpkiManifest", "id-ct-rpkiManifest", NID_id_ct_rpkiManifest, 11, &so[7957]}, + {"id-ct-rpkiGhostbusters", "id-ct-rpkiGhostbusters", NID_id_ct_rpkiGhostbusters, 11, &so[7968]}, + {"id-ct-resourceTaggedAttest", "id-ct-resourceTaggedAttest", NID_id_ct_resourceTaggedAttest, 11, &so[7979]}, + {"id-cp", "id-cp", NID_id_cp, 7, &so[7990]}, + {"sbgp-ipAddrBlockv2", "sbgp-ipAddrBlockv2", NID_sbgp_ipAddrBlockv2, 8, &so[7997]}, + {"sbgp-autonomousSysNumv2", "sbgp-autonomousSysNumv2", NID_sbgp_autonomousSysNumv2, 8, &so[8005]}, + {"ipAddr-asNumber", "ipAddr-asNumber", NID_ipAddr_asNumber, 8, &so[8013]}, + {"ipAddr-asNumberv2", "ipAddr-asNumberv2", NID_ipAddr_asNumberv2, 8, &so[8021]}, + {"rpkiManifest", "RPKI Manifest", NID_rpkiManifest, 8, &so[8029]}, + {"signedObject", "Signed Object", NID_signedObject, 8, &so[8037]}, + {"rpkiNotify", "RPKI Notify", NID_rpkiNotify, 8, &so[8045]}, + {"id-ct-geofeedCSVwithCRLF", "id-ct-geofeedCSVwithCRLF", NID_id_ct_geofeedCSVwithCRLF, 11, &so[8053]}, + {"id-ct-signedChecklist", "id-ct-signedChecklist", NID_id_ct_signedChecklist, 11, &so[8064]}, }; -#define NUM_SN 1186 +#define NUM_SN 1239 static const unsigned int sn_objs[NUM_SN] = { 364, /* "AD_DVCS" */ 419, /* "AES-128-CBC" */ @@ -2290,6 +2382,7 @@ static const unsigned int sn_objs[NUM_SN] = { 418, /* "AES-128-ECB" */ 958, /* "AES-128-OCB" */ 420, /* "AES-128-OFB" */ + 1198, /* "AES-128-SIV" */ 913, /* "AES-128-XTS" */ 423, /* "AES-192-CBC" */ 917, /* "AES-192-CBC-HMAC-SHA1" */ @@ -2301,6 +2394,7 @@ static const unsigned int sn_objs[NUM_SN] = { 422, /* "AES-192-ECB" */ 959, /* "AES-192-OCB" */ 424, /* "AES-192-OFB" */ + 1199, /* "AES-192-SIV" */ 427, /* "AES-256-CBC" */ 918, /* "AES-256-CBC-HMAC-SHA1" */ 950, /* "AES-256-CBC-HMAC-SHA256" */ @@ -2311,6 +2405,7 @@ static const unsigned int sn_objs[NUM_SN] = { 426, /* "AES-256-ECB" */ 960, /* "AES-256-OCB" */ 428, /* "AES-256-OFB" */ + 1200, /* "AES-256-SIV" */ 914, /* "AES-256-XTS" */ 1066, /* "ARIA-128-CBC" */ 1120, /* "ARIA-128-CCM" */ @@ -2352,6 +2447,8 @@ static const unsigned int sn_objs[NUM_SN] = { 93, /* "BF-CFB" */ 92, /* "BF-ECB" */ 94, /* "BF-OFB" */ + 1201, /* "BLAKE2BMAC" */ + 1202, /* "BLAKE2SMAC" */ 1056, /* "BLAKE2b512" */ 1057, /* "BLAKE2s256" */ 14, /* "C" */ @@ -2424,6 +2521,7 @@ static const unsigned int sn_objs[NUM_SN] = { 297, /* "DVCS" */ 1087, /* "ED25519" */ 1088, /* "ED448" */ + 1195, /* "GMAC" */ 99, /* "GN" */ 1036, /* "HKDF" */ 855, /* "HMAC" */ @@ -2442,12 +2540,15 @@ static const unsigned int sn_objs[NUM_SN] = { 645, /* "ITU-T" */ 646, /* "JOINT-ISO-ITU-T" */ 773, /* "KISA" */ + 1196, /* "KMAC128" */ + 1197, /* "KMAC256" */ 1063, /* "KxANY" */ 1039, /* "KxDHE" */ 1041, /* "KxDHE-PSK" */ 1038, /* "KxECDHE" */ 1040, /* "KxECDHE-PSK" */ 1045, /* "KxGOST" */ + 1218, /* "KxGOST18" */ 1043, /* "KxPSK" */ 1037, /* "KxRSA" */ 1042, /* "KxRSA_PSK" */ @@ -2469,6 +2570,7 @@ static const unsigned int sn_objs[NUM_SN] = { 178, /* "OCSP" */ 180, /* "OCSPSigning" */ 1005, /* "OGRN" */ + 1226, /* "OGRNIP" */ 379, /* "ORG" */ 18, /* "OU" */ 749, /* "Oakley-EC2N-3" */ @@ -2543,6 +2645,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1100, /* "SHAKE128" */ 1101, /* "SHAKE256" */ 1172, /* "SM2" */ + 1204, /* "SM2-SM3" */ 1143, /* "SM3" */ 1134, /* "SM4-CBC" */ 1137, /* "SM4-CFB" */ @@ -2555,6 +2658,8 @@ static const unsigned int sn_objs[NUM_SN] = { 167, /* "SMIME-CAPS" */ 100, /* "SN" */ 1006, /* "SNILS" */ + 1203, /* "SSHKDF" */ + 1205, /* "SSKDF" */ 16, /* "ST" */ 143, /* "SXNetID" */ 1062, /* "SipHash" */ @@ -2567,6 +2672,8 @@ static const unsigned int sn_objs[NUM_SN] = { 378, /* "X500algorithms" */ 12, /* "X509" */ 184, /* "X9-57" */ + 1207, /* "X942KDF" */ + 1206, /* "X963KDF" */ 185, /* "X9cm" */ 125, /* "ZLIB" */ 478, /* "aRecord" */ @@ -2642,8 +2749,17 @@ static const unsigned int sn_objs[NUM_SN] = { 883, /* "certificateRevocationList" */ 54, /* "challengePassword" */ 407, /* "characteristic-two-field" */ + 1227, /* "classSignTool" */ + 1233, /* "classSignToolKA1" */ + 1231, /* "classSignToolKB1" */ + 1232, /* "classSignToolKB2" */ + 1228, /* "classSignToolKC1" */ + 1229, /* "classSignToolKC2" */ + 1230, /* "classSignToolKC3" */ 395, /* "clearance" */ 130, /* "clientAuth" */ + 1222, /* "cmKGA" */ + 1219, /* "cmcArchive" */ 1131, /* "cmcCA" */ 1132, /* "cmcRA" */ 131, /* "codeSigning" */ @@ -2748,12 +2864,6 @@ static const unsigned int sn_objs[NUM_SN] = { 1010, /* "gost89-ecb" */ 812, /* "gost94" */ 850, /* "gost94cc" */ - 1015, /* "grasshopper-cbc" */ - 1016, /* "grasshopper-cfb" */ - 1013, /* "grasshopper-ctr" */ - 1012, /* "grasshopper-ecb" */ - 1017, /* "grasshopper-mac" */ - 1014, /* "grasshopper-ofb" */ 1156, /* "hmacWithDstu34311" */ 797, /* "hmacWithMD5" */ 163, /* "hmacWithSHA1" */ @@ -2869,7 +2979,14 @@ static const unsigned int sn_objs[NUM_SN] = { 332, /* "id-cmc-senderNonce" */ 327, /* "id-cmc-statusInfo" */ 331, /* "id-cmc-transactionId" */ + 1238, /* "id-cp" */ 787, /* "id-ct-asciiTextWithCRLF" */ + 1246, /* "id-ct-geofeedCSVwithCRLF" */ + 1237, /* "id-ct-resourceTaggedAttest" */ + 1234, /* "id-ct-routeOriginAuthz" */ + 1236, /* "id-ct-rpkiGhostbusters" */ + 1235, /* "id-ct-rpkiManifest" */ + 1247, /* "id-ct-signedChecklist" */ 1060, /* "id-ct-xml" */ 1108, /* "id-dsa-with-sha3-224" */ 1109, /* "id-dsa-with-sha3-256" */ @@ -2889,8 +3006,10 @@ static const unsigned int sn_objs[NUM_SN] = { 1104, /* "id-hmacWithSHA3-384" */ 1105, /* "id-hmacWithSHA3-512" */ 260, /* "id-it" */ + 1223, /* "id-it-caCerts" */ 302, /* "id-it-caKeyUpdateInfo" */ 298, /* "id-it-caProtEncCert" */ + 1225, /* "id-it-certReqTemplate" */ 311, /* "id-it-confirmWaitTime" */ 303, /* "id-it-currentCRL" */ 300, /* "id-it-encKeyPairTypes" */ @@ -2900,12 +3019,15 @@ static const unsigned int sn_objs[NUM_SN] = { 312, /* "id-it-origPKIMessage" */ 301, /* "id-it-preferredSymmAlg" */ 309, /* "id-it-revPassphrase" */ + 1224, /* "id-it-rootCaKeyUpdate" */ 299, /* "id-it-signKeyPairTypes" */ 305, /* "id-it-subscriptionRequest" */ 306, /* "id-it-subscriptionResponse" */ 784, /* "id-it-suppLangTags" */ 304, /* "id-it-unsupportedOIDs" */ 128, /* "id-kp" */ + 1221, /* "id-kp-BrandIndicatorforMessageIdentification" */ + 1220, /* "id-kp-bgpsec-router" */ 280, /* "id-mod-attribute-cert" */ 274, /* "id-mod-cmc" */ 277, /* "id-mod-cmp" */ @@ -2919,8 +3041,12 @@ static const unsigned int sn_objs[NUM_SN] = { 279, /* "id-mod-qualified-cert-93" */ 281, /* "id-mod-timestamp-protocol" */ 264, /* "id-on" */ + 1211, /* "id-on-NAIRealm" */ + 1208, /* "id-on-SmtpUTF8Mailbox" */ + 1210, /* "id-on-dnsSRV" */ 858, /* "id-on-permanentIdentifier" */ 347, /* "id-on-personalData" */ + 1209, /* "id-on-xmppAddr" */ 265, /* "id-pda" */ 352, /* "id-pda-countryOfCitizenship" */ 353, /* "id-pda-countryOfResidence" */ @@ -3040,11 +3166,7 @@ static const unsigned int sn_objs[NUM_SN] = { 990, /* "id-tc26-cipher" */ 1001, /* "id-tc26-cipher-constants" */ 1176, /* "id-tc26-cipher-gostr3412-2015-kuznyechik" */ - 1177, /* "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm" */ - 1178, /* "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm-omac" */ 1173, /* "id-tc26-cipher-gostr3412-2015-magma" */ - 1174, /* "id-tc26-cipher-gostr3412-2015-magma-ctracpkm" */ - 1175, /* "id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac" */ 994, /* "id-tc26-constants" */ 981, /* "id-tc26-digest" */ 1000, /* "id-tc26-digest-constants" */ @@ -3070,9 +3192,7 @@ static const unsigned int sn_objs[NUM_SN] = { 986, /* "id-tc26-signwithdigest-gost3410-2012-512" */ 1179, /* "id-tc26-wrap" */ 1182, /* "id-tc26-wrap-gostr3412-2015-kuznyechik" */ - 1183, /* "id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15" */ 1180, /* "id-tc26-wrap-gostr3412-2015-magma" */ - 1181, /* "id-tc26-wrap-gostr3412-2015-magma-kexp15" */ 676, /* "identified-organization" */ 1170, /* "ieee" */ 1171, /* "ieee-siswg" */ @@ -3082,6 +3202,8 @@ static const unsigned int sn_objs[NUM_SN] = { 647, /* "international-organizations" */ 869, /* "internationaliSDNNumber" */ 142, /* "invalidityDate" */ + 1241, /* "ipAddr-asNumber" */ + 1242, /* "ipAddr-asNumberv2" */ 294, /* "ipsecEndSystem" */ 1022, /* "ipsecIKE" */ 295, /* "ipsecTunnel" */ @@ -3095,6 +3217,15 @@ static const unsigned int sn_objs[NUM_SN] = { 956, /* "jurisdictionST" */ 150, /* "keyBag" */ 83, /* "keyUsage" */ + 1015, /* "kuznyechik-cbc" */ + 1016, /* "kuznyechik-cfb" */ + 1013, /* "kuznyechik-ctr" */ + 1177, /* "kuznyechik-ctr-acpkm" */ + 1178, /* "kuznyechik-ctr-acpkm-omac" */ + 1012, /* "kuznyechik-ecb" */ + 1183, /* "kuznyechik-kexp15" */ + 1017, /* "kuznyechik-mac" */ + 1014, /* "kuznyechik-ofb" */ 477, /* "lastModifiedBy" */ 476, /* "lastModifiedTime" */ 157, /* "localKeyID" */ @@ -3102,7 +3233,10 @@ static const unsigned int sn_objs[NUM_SN] = { 1190, /* "magma-cbc" */ 1191, /* "magma-cfb" */ 1188, /* "magma-ctr" */ + 1174, /* "magma-ctr-acpkm" */ + 1175, /* "magma-ctr-acpkm-omac" */ 1187, /* "magma-ecb" */ + 1181, /* "magma-kexp15" */ 1192, /* "magma-mac" */ 1189, /* "magma-ofb" */ 460, /* "mail" */ @@ -3119,6 +3253,12 @@ static const unsigned int sn_objs[NUM_SN] = { 506, /* "mime-mhs-bodies" */ 505, /* "mime-mhs-headings" */ 488, /* "mobileTelephoneNumber" */ + 1212, /* "modp_1536" */ + 1213, /* "modp_2048" */ + 1214, /* "modp_3072" */ + 1215, /* "modp_4096" */ + 1216, /* "modp_6144" */ + 1217, /* "modp_8192" */ 136, /* "msCTLSign" */ 135, /* "msCodeCom" */ 134, /* "msCodeInd" */ @@ -3214,6 +3354,8 @@ static const unsigned int sn_objs[NUM_SN] = { 877, /* "roleOccupant" */ 448, /* "room" */ 463, /* "roomNumber" */ + 1243, /* "rpkiManifest" */ + 1245, /* "rpkiNotify" */ 6, /* "rsaEncryption" */ 644, /* "rsaOAEPEncryptionSET" */ 377, /* "rsaSignature" */ @@ -3221,7 +3363,9 @@ static const unsigned int sn_objs[NUM_SN] = { 482, /* "sOARecord" */ 155, /* "safeContentsBag" */ 291, /* "sbgp-autonomousSysNum" */ + 1240, /* "sbgp-autonomousSysNumv2" */ 290, /* "sbgp-ipAddrBlock" */ + 1239, /* "sbgp-ipAddrBlockv2" */ 292, /* "sbgp-routerIdentifier" */ 159, /* "sdsiCertificate" */ 859, /* "searchGuide" */ @@ -3400,6 +3544,7 @@ static const unsigned int sn_objs[NUM_SN] = { 604, /* "setext-pinAny" */ 603, /* "setext-pinSecure" */ 605, /* "setext-track2" */ + 1244, /* "signedObject" */ 52, /* "signingTime" */ 454, /* "simpleSecurityObject" */ 496, /* "singleLevelQuality" */ @@ -3467,7 +3612,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1093, /* "x509ExtAdmission" */ }; -#define NUM_LN 1186 +#define NUM_LN 1239 static const unsigned int ln_objs[NUM_LN] = { 363, /* "AD Time Stamping" */ 405, /* "ANSI X9.62" */ @@ -3475,16 +3620,27 @@ static const unsigned int ln_objs[NUM_LN] = { 910, /* "Any Extended Key Usage" */ 664, /* "Any language" */ 177, /* "Authority Information Access" */ + 1220, /* "BGPsec Router" */ 365, /* "Basic OCSP Response" */ 285, /* "Biometric Info" */ + 1221, /* "Brand Indicator for Message Identification" */ 179, /* "CA Issuers" */ 785, /* "CA Repository" */ + 1219, /* "CMC Archive Server" */ 1131, /* "CMC Certificate Authority" */ 1132, /* "CMC Registration Authority" */ 954, /* "CT Certificate SCTs" */ 952, /* "CT Precertificate Poison" */ 951, /* "CT Precertificate SCTs" */ 953, /* "CT Precertificate Signer" */ + 1222, /* "Certificate Management Key Generation Authority" */ + 1227, /* "Class of Signing Tool" */ + 1233, /* "Class of Signing Tool KA1" */ + 1231, /* "Class of Signing Tool KB1" */ + 1232, /* "Class of Signing Tool KB2" */ + 1228, /* "Class of Signing Tool KC1" */ + 1229, /* "Class of Signing Tool KC2" */ + 1230, /* "Class of Signing Tool KC3" */ 131, /* "Code Signing" */ 1024, /* "Ctrl/Provision WAP Termination" */ 1023, /* "Ctrl/provision WAP Access" */ @@ -3581,6 +3737,7 @@ static const unsigned int ln_objs[NUM_LN] = { 648, /* "Microsoft Smartcard Login" */ 136, /* "Microsoft Trust List Signing" */ 649, /* "Microsoft User Principal Name" */ + 1211, /* "NAIRealm" */ 393, /* "NULL" */ 404, /* "NULL" */ 72, /* "Netscape Base Url" */ @@ -3604,6 +3761,7 @@ static const unsigned int ln_objs[NUM_LN] = { 371, /* "OCSP Service Locator" */ 180, /* "OCSP Signing" */ 1005, /* "OGRN" */ + 1226, /* "OGRNIP" */ 161, /* "PBES2" */ 69, /* "PBKDF2" */ 162, /* "PBMAC1" */ @@ -3615,6 +3773,8 @@ static const unsigned int ln_objs[NUM_LN] = { 385, /* "Private" */ 1093, /* "Professional Information or basis for Admission" */ 663, /* "Proxy Certificate Information" */ + 1243, /* "RPKI Manifest" */ + 1245, /* "RPKI Notify" */ 1, /* "RSA Data Security, Inc." */ 2, /* "RSA Data Security, Inc. PKCS" */ 1116, /* "RSA-SHA3-224" */ @@ -3623,8 +3783,10 @@ static const unsigned int ln_objs[NUM_LN] = { 1119, /* "RSA-SHA3-512" */ 188, /* "S/MIME" */ 167, /* "S/MIME Capabilities" */ + 1204, /* "SM2-with-SM3" */ 1006, /* "SNILS" */ 387, /* "SNMPv2" */ + 1210, /* "SRVName" */ 1025, /* "SSH Client" */ 1026, /* "SSH Server" */ 512, /* "Secure Electronic Transactions" */ @@ -3634,9 +3796,11 @@ static const unsigned int ln_objs[NUM_LN] = { 1030, /* "Send Proxied Owner" */ 1028, /* "Send Proxied Router" */ 1027, /* "Send Router" */ + 1244, /* "Signed Object" */ 1033, /* "Signing KDC Response" */ 1008, /* "Signing Tool of Issuer" */ 1007, /* "Signing Tool of Subject" */ + 1208, /* "Smtp UTF8 Mailbox" */ 143, /* "Strong Extranet ID" */ 398, /* "Subject Information Access" */ 1020, /* "TLS Feature" */ @@ -3674,6 +3838,7 @@ static const unsigned int ln_objs[NUM_LN] = { 920, /* "X9.42 DH" */ 184, /* "X9.57" */ 185, /* "X9.57 CM ?" */ + 1209, /* "XmppAddr" */ 478, /* "aRecord" */ 289, /* "aaControls" */ 287, /* "ac-auditEntity" */ @@ -3694,6 +3859,7 @@ static const unsigned int ln_objs[NUM_LN] = { 895, /* "aes-128-gcm" */ 958, /* "aes-128-ocb" */ 420, /* "aes-128-ofb" */ + 1198, /* "aes-128-siv" */ 913, /* "aes-128-xts" */ 423, /* "aes-192-cbc" */ 917, /* "aes-192-cbc-hmac-sha1" */ @@ -3707,6 +3873,7 @@ static const unsigned int ln_objs[NUM_LN] = { 898, /* "aes-192-gcm" */ 959, /* "aes-192-ocb" */ 424, /* "aes-192-ofb" */ + 1199, /* "aes-192-siv" */ 427, /* "aes-256-cbc" */ 918, /* "aes-256-cbc-hmac-sha1" */ 950, /* "aes-256-cbc-hmac-sha256" */ @@ -3719,6 +3886,7 @@ static const unsigned int ln_objs[NUM_LN] = { 901, /* "aes-256-gcm" */ 960, /* "aes-256-ocb" */ 428, /* "aes-256-ofb" */ + 1200, /* "aes-256-siv" */ 914, /* "aes-256-xts" */ 376, /* "algorithm" */ 1066, /* "aria-128-cbc" */ @@ -3766,7 +3934,9 @@ static const unsigned int ln_objs[NUM_LN] = { 92, /* "bf-ecb" */ 94, /* "bf-ofb" */ 1056, /* "blake2b512" */ + 1201, /* "blake2bmac" */ 1057, /* "blake2s256" */ + 1202, /* "blake2smac" */ 921, /* "brainpoolP160r1" */ 922, /* "brainpoolP160t1" */ 923, /* "brainpoolP192r1" */ @@ -3961,18 +4131,13 @@ static const unsigned int ln_objs[NUM_LN] = { 509, /* "generationQualifier" */ 601, /* "generic cryptogram" */ 99, /* "givenName" */ + 1195, /* "gmac" */ 976, /* "gost-mac-12" */ 1009, /* "gost89-cbc" */ 814, /* "gost89-cnt" */ 975, /* "gost89-cnt-12" */ 1011, /* "gost89-ctr" */ 1010, /* "gost89-ecb" */ - 1015, /* "grasshopper-cbc" */ - 1016, /* "grasshopper-cfb" */ - 1013, /* "grasshopper-ctr" */ - 1012, /* "grasshopper-ecb" */ - 1017, /* "grasshopper-mac" */ - 1014, /* "grasshopper-ofb" */ 1036, /* "hkdf" */ 855, /* "hmac" */ 780, /* "hmac-md5" */ @@ -4075,14 +4240,23 @@ static const unsigned int ln_objs[NUM_LN] = { 332, /* "id-cmc-senderNonce" */ 327, /* "id-cmc-statusInfo" */ 331, /* "id-cmc-transactionId" */ + 1238, /* "id-cp" */ 787, /* "id-ct-asciiTextWithCRLF" */ + 1246, /* "id-ct-geofeedCSVwithCRLF" */ + 1237, /* "id-ct-resourceTaggedAttest" */ + 1234, /* "id-ct-routeOriginAuthz" */ + 1236, /* "id-ct-rpkiGhostbusters" */ + 1235, /* "id-ct-rpkiManifest" */ + 1247, /* "id-ct-signedChecklist" */ 1060, /* "id-ct-xml" */ 408, /* "id-ecPublicKey" */ 508, /* "id-hex-multipart-message" */ 507, /* "id-hex-partial-message" */ 260, /* "id-it" */ + 1223, /* "id-it-caCerts" */ 302, /* "id-it-caKeyUpdateInfo" */ 298, /* "id-it-caProtEncCert" */ + 1225, /* "id-it-certReqTemplate" */ 311, /* "id-it-confirmWaitTime" */ 303, /* "id-it-currentCRL" */ 300, /* "id-it-encKeyPairTypes" */ @@ -4092,6 +4266,7 @@ static const unsigned int ln_objs[NUM_LN] = { 312, /* "id-it-origPKIMessage" */ 301, /* "id-it-preferredSymmAlg" */ 309, /* "id-it-revPassphrase" */ + 1224, /* "id-it-rootCaKeyUpdate" */ 299, /* "id-it-signKeyPairTypes" */ 305, /* "id-it-subscriptionRequest" */ 306, /* "id-it-subscriptionResponse" */ @@ -4220,11 +4395,7 @@ static const unsigned int ln_objs[NUM_LN] = { 990, /* "id-tc26-cipher" */ 1001, /* "id-tc26-cipher-constants" */ 1176, /* "id-tc26-cipher-gostr3412-2015-kuznyechik" */ - 1177, /* "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm" */ - 1178, /* "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm-omac" */ 1173, /* "id-tc26-cipher-gostr3412-2015-magma" */ - 1174, /* "id-tc26-cipher-gostr3412-2015-magma-ctracpkm" */ - 1175, /* "id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac" */ 994, /* "id-tc26-constants" */ 981, /* "id-tc26-digest" */ 1000, /* "id-tc26-digest-constants" */ @@ -4237,9 +4408,7 @@ static const unsigned int ln_objs[NUM_LN] = { 984, /* "id-tc26-signwithdigest" */ 1179, /* "id-tc26-wrap" */ 1182, /* "id-tc26-wrap-gostr3412-2015-kuznyechik" */ - 1183, /* "id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15" */ 1180, /* "id-tc26-wrap-gostr3412-2015-magma" */ - 1181, /* "id-tc26-wrap-gostr3412-2015-magma-kexp15" */ 34, /* "idea-cbc" */ 35, /* "idea-cfb" */ 36, /* "idea-ecb" */ @@ -4249,6 +4418,8 @@ static const unsigned int ln_objs[NUM_LN] = { 461, /* "info" */ 101, /* "initials" */ 869, /* "internationaliSDNNumber" */ + 1241, /* "ipAddr-asNumber" */ + 1242, /* "ipAddr-asNumberv2" */ 1022, /* "ipsec Internet Key Exchange" */ 749, /* "ipsec3" */ 750, /* "ipsec4" */ @@ -4262,12 +4433,24 @@ static const unsigned int ln_objs[NUM_LN] = { 956, /* "jurisdictionStateOrProvinceName" */ 150, /* "keyBag" */ 773, /* "kisa" */ + 1196, /* "kmac128" */ + 1197, /* "kmac256" */ + 1015, /* "kuznyechik-cbc" */ + 1016, /* "kuznyechik-cfb" */ + 1013, /* "kuznyechik-ctr" */ + 1177, /* "kuznyechik-ctr-acpkm" */ + 1178, /* "kuznyechik-ctr-acpkm-omac" */ + 1012, /* "kuznyechik-ecb" */ + 1183, /* "kuznyechik-kexp15" */ + 1017, /* "kuznyechik-mac" */ + 1014, /* "kuznyechik-ofb" */ 1063, /* "kx-any" */ 1039, /* "kx-dhe" */ 1041, /* "kx-dhe-psk" */ 1038, /* "kx-ecdhe" */ 1040, /* "kx-ecdhe-psk" */ 1045, /* "kx-gost" */ + 1218, /* "kx-gost18" */ 1043, /* "kx-psk" */ 1037, /* "kx-rsa" */ 1042, /* "kx-rsa-psk" */ @@ -4280,7 +4463,10 @@ static const unsigned int ln_objs[NUM_LN] = { 1190, /* "magma-cbc" */ 1191, /* "magma-cfb" */ 1188, /* "magma-ctr" */ + 1174, /* "magma-ctr-acpkm" */ + 1175, /* "magma-ctr-acpkm-omac" */ 1187, /* "magma-ecb" */ + 1181, /* "magma-kexp15" */ 1192, /* "magma-mac" */ 1189, /* "magma-ofb" */ 493, /* "mailPreferenceOption" */ @@ -4303,6 +4489,12 @@ static const unsigned int ln_objs[NUM_LN] = { 506, /* "mime-mhs-bodies" */ 505, /* "mime-mhs-headings" */ 488, /* "mobileTelephoneNumber" */ + 1212, /* "modp_1536" */ + 1213, /* "modp_2048" */ + 1214, /* "modp_3072" */ + 1215, /* "modp_4096" */ + 1216, /* "modp_6144" */ + 1217, /* "modp_8192" */ 481, /* "nSRecord" */ 173, /* "name" */ 681, /* "onBasis" */ @@ -4409,7 +4601,9 @@ static const unsigned int ln_objs[NUM_LN] = { 482, /* "sOARecord" */ 155, /* "safeContentsBag" */ 291, /* "sbgp-autonomousSysNum" */ + 1240, /* "sbgp-autonomousSysNumv2" */ 290, /* "sbgp-ipAddrBlock" */ + 1239, /* "sbgp-ipAddrBlockv2" */ 292, /* "sbgp-routerIdentifier" */ 973, /* "scrypt" */ 159, /* "sdsiCertificate" */ @@ -4609,6 +4803,8 @@ static const unsigned int ln_objs[NUM_LN] = { 1139, /* "sm4-ctr" */ 1133, /* "sm4-ecb" */ 1135, /* "sm4-ofb" */ + 1203, /* "sshkdf" */ + 1205, /* "sskdf" */ 16, /* "stateOrProvinceName" */ 660, /* "streetAddress" */ 498, /* "subtreeMaximumQuality" */ @@ -4654,10 +4850,12 @@ static const unsigned int ln_objs[NUM_LN] = { 503, /* "x500UniqueIdentifier" */ 158, /* "x509Certificate" */ 160, /* "x509Crl" */ + 1207, /* "x942kdf" */ + 1206, /* "x963kdf" */ 125, /* "zlib compression" */ }; -#define NUM_OBJ 1071 +#define NUM_OBJ 1110 static const unsigned int obj_objs[NUM_OBJ] = { 0, /* OBJ_undef 0 */ 181, /* OBJ_iso 1 */ @@ -4904,14 +5102,17 @@ static const unsigned int obj_objs[NUM_OBJ] = { 637, /* OBJ_set_brand_Diners 2 23 42 8 30 */ 638, /* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */ 639, /* OBJ_set_brand_JCB 2 23 42 8 35 */ + 1195, /* OBJ_gmac 1 0 9797 3 4 */ 1141, /* OBJ_oscca 1 2 156 10197 */ 805, /* OBJ_cryptopro 1 2 643 2 2 */ 806, /* OBJ_cryptocom 1 2 643 2 9 */ 974, /* OBJ_id_tc26 1 2 643 7 1 */ 1005, /* OBJ_OGRN 1 2 643 100 1 */ 1006, /* OBJ_SNILS 1 2 643 100 3 */ + 1226, /* OBJ_OGRNIP 1 2 643 100 5 */ 1007, /* OBJ_subjectSignTool 1 2 643 100 111 */ 1008, /* OBJ_issuerSignTool 1 2 643 100 112 */ + 1227, /* OBJ_classSignTool 1 2 643 100 113 */ 184, /* OBJ_X9_57 1 2 840 10040 */ 405, /* OBJ_ansi_X9_62 1 2 840 10045 */ 389, /* OBJ_Enterprises 1 3 6 1 4 1 */ @@ -5000,6 +5201,12 @@ static const unsigned int obj_objs[NUM_OBJ] = { 818, /* OBJ_id_GostR3410_94DH 1 2 643 2 2 99 */ 977, /* OBJ_id_tc26_algorithms 1 2 643 7 1 1 */ 994, /* OBJ_id_tc26_constants 1 2 643 7 1 2 */ + 1228, /* OBJ_classSignToolKC1 1 2 643 100 113 1 */ + 1229, /* OBJ_classSignToolKC2 1 2 643 100 113 2 */ + 1230, /* OBJ_classSignToolKC3 1 2 643 100 113 3 */ + 1231, /* OBJ_classSignToolKB1 1 2 643 100 113 4 */ + 1232, /* OBJ_classSignToolKB2 1 2 643 100 113 5 */ + 1233, /* OBJ_classSignToolKA1 1 2 643 100 113 6 */ 1, /* OBJ_rsadsi 1 2 840 113549 */ 185, /* OBJ_X9cm 1 2 840 10040 4 */ 1031, /* OBJ_id_pkinit 1 3 6 1 5 2 3 */ @@ -5090,6 +5297,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { 266, /* OBJ_id_aca 1 3 6 1 5 5 7 10 */ 267, /* OBJ_id_qcs 1 3 6 1 5 5 7 11 */ 268, /* OBJ_id_cct 1 3 6 1 5 5 7 12 */ + 1238, /* OBJ_id_cp 1 3 6 1 5 5 7 14 */ 662, /* OBJ_id_ppl 1 3 6 1 5 5 7 21 */ 176, /* OBJ_id_ad 1 3 6 1 5 5 7 48 */ 507, /* OBJ_id_hex_partial_message 1 3 6 1 7 1 1 1 */ @@ -5126,6 +5334,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { 1139, /* OBJ_sm4_ctr 1 2 156 10197 1 104 7 */ 1172, /* OBJ_sm2 1 2 156 10197 1 301 */ 1143, /* OBJ_sm3 1 2 156 10197 1 401 */ + 1204, /* OBJ_SM2_with_SM3 1 2 156 10197 1 501 */ 1144, /* OBJ_sm3WithRSAEncryption 1 2 156 10197 1 504 */ 776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */ 777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */ @@ -5237,6 +5446,8 @@ static const unsigned int obj_objs[NUM_OBJ] = { 398, /* OBJ_sinfo_access 1 3 6 1 5 5 7 1 11 */ 663, /* OBJ_proxyCertInfo 1 3 6 1 5 5 7 1 14 */ 1020, /* OBJ_tlsfeature 1 3 6 1 5 5 7 1 24 */ + 1239, /* OBJ_sbgp_ipAddrBlockv2 1 3 6 1 5 5 7 1 28 */ + 1240, /* OBJ_sbgp_autonomousSysNumv2 1 3 6 1 5 5 7 1 29 */ 164, /* OBJ_id_qt_cps 1 3 6 1 5 5 7 2 1 */ 165, /* OBJ_id_qt_unotice 1 3 6 1 5 5 7 2 2 */ 293, /* OBJ_textNotice 1 3 6 1 5 5 7 2 3 */ @@ -5261,6 +5472,10 @@ static const unsigned int obj_objs[NUM_OBJ] = { 1030, /* OBJ_sendProxiedOwner 1 3 6 1 5 5 7 3 26 */ 1131, /* OBJ_cmcCA 1 3 6 1 5 5 7 3 27 */ 1132, /* OBJ_cmcRA 1 3 6 1 5 5 7 3 28 */ + 1219, /* OBJ_cmcArchive 1 3 6 1 5 5 7 3 29 */ + 1220, /* OBJ_id_kp_bgpsec_router 1 3 6 1 5 5 7 3 30 */ + 1221, /* OBJ_id_kp_BrandIndicatorforMessageIdentification 1 3 6 1 5 5 7 3 31 */ + 1222, /* OBJ_cmKGA 1 3 6 1 5 5 7 3 32 */ 298, /* OBJ_id_it_caProtEncCert 1 3 6 1 5 5 7 4 1 */ 299, /* OBJ_id_it_signKeyPairTypes 1 3 6 1 5 5 7 4 2 */ 300, /* OBJ_id_it_encKeyPairTypes 1 3 6 1 5 5 7 4 3 */ @@ -5277,6 +5492,9 @@ static const unsigned int obj_objs[NUM_OBJ] = { 311, /* OBJ_id_it_confirmWaitTime 1 3 6 1 5 5 7 4 14 */ 312, /* OBJ_id_it_origPKIMessage 1 3 6 1 5 5 7 4 15 */ 784, /* OBJ_id_it_suppLangTags 1 3 6 1 5 5 7 4 16 */ + 1223, /* OBJ_id_it_caCerts 1 3 6 1 5 5 7 4 17 */ + 1224, /* OBJ_id_it_rootCaKeyUpdate 1 3 6 1 5 5 7 4 18 */ + 1225, /* OBJ_id_it_certReqTemplate 1 3 6 1 5 5 7 4 19 */ 313, /* OBJ_id_regCtrl 1 3 6 1 5 5 7 5 1 */ 314, /* OBJ_id_regInfo 1 3 6 1 5 5 7 5 2 */ 323, /* OBJ_id_alg_des40 1 3 6 1 5 5 7 6 1 */ @@ -5305,6 +5523,10 @@ static const unsigned int obj_objs[NUM_OBJ] = { 346, /* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */ 347, /* OBJ_id_on_personalData 1 3 6 1 5 5 7 8 1 */ 858, /* OBJ_id_on_permanentIdentifier 1 3 6 1 5 5 7 8 3 */ + 1209, /* OBJ_XmppAddr 1 3 6 1 5 5 7 8 5 */ + 1210, /* OBJ_SRVName 1 3 6 1 5 5 7 8 7 */ + 1211, /* OBJ_NAIRealm 1 3 6 1 5 5 7 8 8 */ + 1208, /* OBJ_id_on_SmtpUTF8Mailbox 1 3 6 1 5 5 7 8 9 */ 348, /* OBJ_id_pda_dateOfBirth 1 3 6 1 5 5 7 9 1 */ 349, /* OBJ_id_pda_placeOfBirth 1 3 6 1 5 5 7 9 2 */ 351, /* OBJ_id_pda_gender 1 3 6 1 5 5 7 9 3 */ @@ -5320,6 +5542,8 @@ static const unsigned int obj_objs[NUM_OBJ] = { 360, /* OBJ_id_cct_crs 1 3 6 1 5 5 7 12 1 */ 361, /* OBJ_id_cct_PKIData 1 3 6 1 5 5 7 12 2 */ 362, /* OBJ_id_cct_PKIResponse 1 3 6 1 5 5 7 12 3 */ + 1241, /* OBJ_ipAddr_asNumber 1 3 6 1 5 5 7 14 2 */ + 1242, /* OBJ_ipAddr_asNumberv2 1 3 6 1 5 5 7 14 3 */ 664, /* OBJ_id_ppl_anyLanguage 1 3 6 1 5 5 7 21 0 */ 665, /* OBJ_id_ppl_inheritAll 1 3 6 1 5 5 7 21 1 */ 667, /* OBJ_Independent 1 3 6 1 5 5 7 21 2 */ @@ -5328,6 +5552,9 @@ static const unsigned int obj_objs[NUM_OBJ] = { 363, /* OBJ_ad_timeStamping 1 3 6 1 5 5 7 48 3 */ 364, /* OBJ_ad_dvcs 1 3 6 1 5 5 7 48 4 */ 785, /* OBJ_caRepository 1 3 6 1 5 5 7 48 5 */ + 1243, /* OBJ_rpkiManifest 1 3 6 1 5 5 7 48 10 */ + 1244, /* OBJ_signedObject 1 3 6 1 5 5 7 48 11 */ + 1245, /* OBJ_rpkiNotify 1 3 6 1 5 5 7 48 13 */ 780, /* OBJ_hmac_md5 1 3 6 1 5 5 8 1 1 */ 781, /* OBJ_hmac_sha1 1 3 6 1 5 5 8 1 2 */ 913, /* OBJ_aes_128_xts 1 3 111 2 1619 0 1 1 */ @@ -5359,12 +5586,12 @@ static const unsigned int obj_objs[NUM_OBJ] = { 1120, /* OBJ_aria_128_ccm 1 2 410 200046 1 1 37 */ 1121, /* OBJ_aria_192_ccm 1 2 410 200046 1 1 38 */ 1122, /* OBJ_aria_256_ccm 1 2 410 200046 1 1 39 */ - 1174, /* OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm 1 2 643 7 1 1 5 1 1 */ - 1175, /* OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac 1 2 643 7 1 1 5 1 2 */ - 1177, /* OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm 1 2 643 7 1 1 5 2 1 */ - 1178, /* OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac 1 2 643 7 1 1 5 2 2 */ - 1181, /* OBJ_id_tc26_wrap_gostr3412_2015_magma_kexp15 1 2 643 7 1 1 7 1 1 */ - 1183, /* OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1 2 643 7 1 1 7 2 1 */ + 1174, /* OBJ_magma_ctr_acpkm 1 2 643 7 1 1 5 1 1 */ + 1175, /* OBJ_magma_ctr_acpkm_omac 1 2 643 7 1 1 5 1 2 */ + 1177, /* OBJ_kuznyechik_ctr_acpkm 1 2 643 7 1 1 5 2 1 */ + 1178, /* OBJ_kuznyechik_ctr_acpkm_omac 1 2 643 7 1 1 5 2 2 */ + 1181, /* OBJ_magma_kexp15 1 2 643 7 1 1 7 1 1 */ + 1183, /* OBJ_kuznyechik_kexp15 1 2 643 7 1 1 7 2 1 */ 1148, /* OBJ_id_tc26_gost_3410_2012_256_paramSetA 1 2 643 7 1 2 1 1 1 */ 1184, /* OBJ_id_tc26_gost_3410_2012_256_paramSetB 1 2 643 7 1 2 1 1 2 */ 1185, /* OBJ_id_tc26_gost_3410_2012_256_paramSetC 1 2 643 7 1 2 1 1 3 */ @@ -5507,6 +5734,8 @@ static const unsigned int obj_objs[NUM_OBJ] = { 1103, /* OBJ_hmac_sha3_256 2 16 840 1 101 3 4 2 14 */ 1104, /* OBJ_hmac_sha3_384 2 16 840 1 101 3 4 2 15 */ 1105, /* OBJ_hmac_sha3_512 2 16 840 1 101 3 4 2 16 */ + 1196, /* OBJ_kmac128 2 16 840 1 101 3 4 2 19 */ + 1197, /* OBJ_kmac256 2 16 840 1 101 3 4 2 20 */ 802, /* OBJ_dsa_with_SHA224 2 16 840 1 101 3 4 3 1 */ 803, /* OBJ_dsa_with_SHA256 2 16 840 1 101 3 4 3 2 */ 1106, /* OBJ_dsa_with_SHA384 2 16 840 1 101 3 4 3 3 */ @@ -5624,6 +5853,8 @@ static const unsigned int obj_objs[NUM_OBJ] = { 138, /* OBJ_ms_efs 1 3 6 1 4 1 311 10 3 4 */ 648, /* OBJ_ms_smartcard_login 1 3 6 1 4 1 311 20 2 2 */ 649, /* OBJ_ms_upn 1 3 6 1 4 1 311 20 2 3 */ + 1201, /* OBJ_blake2bmac 1 3 6 1 4 1 1722 12 2 1 */ + 1202, /* OBJ_blake2smac 1 3 6 1 4 1 1722 12 2 2 */ 951, /* OBJ_ct_precert_scts 1 3 6 1 4 1 11129 2 4 2 */ 952, /* OBJ_ct_precert_poison 1 3 6 1 4 1 11129 2 4 3 */ 953, /* OBJ_ct_precert_signer 1 3 6 1 4 1 11129 2 4 4 */ @@ -5657,8 +5888,14 @@ static const unsigned int obj_objs[NUM_OBJ] = { 786, /* OBJ_id_smime_ct_compressedData 1 2 840 113549 1 9 16 1 9 */ 1058, /* OBJ_id_smime_ct_contentCollection 1 2 840 113549 1 9 16 1 19 */ 1059, /* OBJ_id_smime_ct_authEnvelopedData 1 2 840 113549 1 9 16 1 23 */ + 1234, /* OBJ_id_ct_routeOriginAuthz 1 2 840 113549 1 9 16 1 24 */ + 1235, /* OBJ_id_ct_rpkiManifest 1 2 840 113549 1 9 16 1 26 */ 787, /* OBJ_id_ct_asciiTextWithCRLF 1 2 840 113549 1 9 16 1 27 */ 1060, /* OBJ_id_ct_xml 1 2 840 113549 1 9 16 1 28 */ + 1236, /* OBJ_id_ct_rpkiGhostbusters 1 2 840 113549 1 9 16 1 35 */ + 1237, /* OBJ_id_ct_resourceTaggedAttest 1 2 840 113549 1 9 16 1 36 */ + 1246, /* OBJ_id_ct_geofeedCSVwithCRLF 1 2 840 113549 1 9 16 1 47 */ + 1247, /* OBJ_id_ct_signedChecklist 1 2 840 113549 1 9 16 1 48 */ 212, /* OBJ_id_smime_aa_receiptRequest 1 2 840 113549 1 9 16 2 1 */ 213, /* OBJ_id_smime_aa_securityLabel 1 2 840 113549 1 9 16 2 2 */ 214, /* OBJ_id_smime_aa_mlExpandHistory 1 2 840 113549 1 9 16 2 3 */ diff --git a/crypto/openssl/crypto/objects/obj_dat.pl b/crypto/openssl/crypto/objects/obj_dat.pl old mode 100755 new mode 100644 index e1b4a02f288f..60a5e5a6833e --- a/crypto/openssl/crypto/objects/obj_dat.pl +++ b/crypto/openssl/crypto/objects/obj_dat.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -159,7 +159,7 @@ print <<"EOF"; * Generated by crypto/objects/obj_dat.pl * * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved. - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/objects/obj_err.c b/crypto/openssl/crypto/objects/obj_err.c index be4f11ca208b..b4c8df09e66b 100644 --- a/crypto/openssl/crypto/objects/obj_err.c +++ b/crypto/openssl/crypto/objects/obj_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,37 +10,25 @@ #include #include +#include "crypto/objectserr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA OBJ_str_functs[] = { - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_ADD_OBJECT, 0), "OBJ_add_object"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_ADD_SIGID, 0), "OBJ_add_sigid"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_CREATE, 0), "OBJ_create"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_DUP, 0), "OBJ_dup"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_NAME_NEW_INDEX, 0), "OBJ_NAME_new_index"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_NID2LN, 0), "OBJ_nid2ln"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_NID2OBJ, 0), "OBJ_nid2obj"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_NID2SN, 0), "OBJ_nid2sn"}, - {ERR_PACK(ERR_LIB_OBJ, OBJ_F_OBJ_TXT2OBJ, 0), "OBJ_txt2obj"}, - {0, NULL} -}; - static const ERR_STRING_DATA OBJ_str_reasons[] = { {ERR_PACK(ERR_LIB_OBJ, 0, OBJ_R_OID_EXISTS), "oid exists"}, {ERR_PACK(ERR_LIB_OBJ, 0, OBJ_R_UNKNOWN_NID), "unknown nid"}, + {ERR_PACK(ERR_LIB_OBJ, 0, OBJ_R_UNKNOWN_OBJECT_NAME), + "unknown object name"}, {0, NULL} }; #endif -int ERR_load_OBJ_strings(void) +int ossl_err_load_OBJ_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL) { - ERR_load_strings_const(OBJ_str_functs); + if (ERR_reason_error_string(OBJ_str_reasons[0].error) == NULL) ERR_load_strings_const(OBJ_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/objects/obj_lib.c b/crypto/openssl/crypto/objects/obj_lib.c index 456a1598cec5..72c0c2c81dd9 100644 --- a/crypto/openssl/crypto/objects/obj_lib.c +++ b/crypto/openssl/crypto/objects/obj_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -25,7 +25,7 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) r = ASN1_OBJECT_new(); if (r == NULL) { - OBJerr(OBJ_F_OBJ_DUP, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_OBJ, ERR_R_ASN1_LIB); return NULL; } @@ -50,7 +50,7 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) return r; err: ASN1_OBJECT_free(r); - OBJerr(OBJ_F_OBJ_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/openssl/crypto/objects/obj_local.h b/crypto/openssl/crypto/objects/obj_local.h index a417f7c46ef6..4436b799fd3b 100644 --- a/crypto/openssl/crypto/objects/obj_local.h +++ b/crypto/openssl/crypto/objects/obj_local.h @@ -1,7 +1,7 @@ /* * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/objects/obj_mac.num b/crypto/openssl/crypto/objects/obj_mac.num index 1b6a9c61a1c8..c626558ad5c1 100644 --- a/crypto/openssl/crypto/objects/obj_mac.num +++ b/crypto/openssl/crypto/objects/obj_mac.num @@ -1009,12 +1009,12 @@ issuerSignTool 1008 gost89_cbc 1009 gost89_ecb 1010 gost89_ctr 1011 -grasshopper_ecb 1012 -grasshopper_ctr 1013 -grasshopper_ofb 1014 -grasshopper_cbc 1015 -grasshopper_cfb 1016 -grasshopper_mac 1017 +kuznyechik_ecb 1012 +kuznyechik_ctr 1013 +kuznyechik_ofb 1014 +kuznyechik_cbc 1015 +kuznyechik_cfb 1016 +kuznyechik_mac 1017 chacha20_poly1305 1018 chacha20 1019 tlsfeature 1020 @@ -1171,16 +1171,16 @@ ieee 1170 ieee_siswg 1171 sm2 1172 id_tc26_cipher_gostr3412_2015_magma 1173 -id_tc26_cipher_gostr3412_2015_magma_ctracpkm 1174 -id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac 1175 +magma_ctr_acpkm 1174 +magma_ctr_acpkm_omac 1175 id_tc26_cipher_gostr3412_2015_kuznyechik 1176 -id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm 1177 -id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac 1178 +kuznyechik_ctr_acpkm 1177 +kuznyechik_ctr_acpkm_omac 1178 id_tc26_wrap 1179 id_tc26_wrap_gostr3412_2015_magma 1180 -id_tc26_wrap_gostr3412_2015_magma_kexp15 1181 +magma_kexp15 1181 id_tc26_wrap_gostr3412_2015_kuznyechik 1182 -id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1183 +kuznyechik_kexp15 1183 id_tc26_gost_3410_2012_256_paramSetB 1184 id_tc26_gost_3410_2012_256_paramSetC 1185 id_tc26_gost_3410_2012_256_paramSetD 1186 @@ -1192,3 +1192,56 @@ magma_cfb 1191 magma_mac 1192 hmacWithSHA512_224 1193 hmacWithSHA512_256 1194 +gmac 1195 +kmac128 1196 +kmac256 1197 +aes_128_siv 1198 +aes_192_siv 1199 +aes_256_siv 1200 +blake2bmac 1201 +blake2smac 1202 +sshkdf 1203 +SM2_with_SM3 1204 +sskdf 1205 +x963kdf 1206 +x942kdf 1207 +id_on_SmtpUTF8Mailbox 1208 +XmppAddr 1209 +SRVName 1210 +NAIRealm 1211 +modp_1536 1212 +modp_2048 1213 +modp_3072 1214 +modp_4096 1215 +modp_6144 1216 +modp_8192 1217 +kx_gost18 1218 +cmcArchive 1219 +id_kp_bgpsec_router 1220 +id_kp_BrandIndicatorforMessageIdentification 1221 +cmKGA 1222 +id_it_caCerts 1223 +id_it_rootCaKeyUpdate 1224 +id_it_certReqTemplate 1225 +OGRNIP 1226 +classSignTool 1227 +classSignToolKC1 1228 +classSignToolKC2 1229 +classSignToolKC3 1230 +classSignToolKB1 1231 +classSignToolKB2 1232 +classSignToolKA1 1233 +id_ct_routeOriginAuthz 1234 +id_ct_rpkiManifest 1235 +id_ct_rpkiGhostbusters 1236 +id_ct_resourceTaggedAttest 1237 +id_cp 1238 +sbgp_ipAddrBlockv2 1239 +sbgp_autonomousSysNumv2 1240 +ipAddr_asNumber 1241 +ipAddr_asNumberv2 1242 +rpkiManifest 1243 +signedObject 1244 +rpkiNotify 1245 +id_ct_geofeedCSVwithCRLF 1246 +id_ct_signedChecklist 1247 diff --git a/crypto/openssl/crypto/objects/obj_xref.c b/crypto/openssl/crypto/objects/obj_xref.c index faf59eb20c83..da1035112f4f 100644 --- a/crypto/openssl/crypto/objects/obj_xref.c +++ b/crypto/openssl/crypto/objects/obj_xref.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -104,7 +104,7 @@ int OBJ_add_sigid(int signid, int dig_id, int pkey_id) if (sigx_app == NULL) return 0; if ((ntr = OPENSSL_malloc(sizeof(*ntr))) == NULL) { - OBJerr(OBJ_F_OBJ_ADD_SIGID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); return 0; } ntr->sign_id = signid; diff --git a/crypto/openssl/crypto/objects/obj_xref.h b/crypto/openssl/crypto/objects/obj_xref.h index 5ef094bbfd84..21a193ee98bc 100644 --- a/crypto/openssl/crypto/objects/obj_xref.h +++ b/crypto/openssl/crypto/objects/obj_xref.h @@ -2,9 +2,9 @@ * WARNING: do not edit! * Generated by objxref.pl * - * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -53,7 +53,7 @@ static const nid_triple sigoid_srt[] = { NID_id_GostR3410_94_cc}, {NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, NID_id_GostR3410_2001_cc}, - {NID_rsassaPss, NID_undef, NID_rsaEncryption}, + {NID_rsassaPss, NID_undef, NID_rsassaPss}, {NID_dhSinglePass_stdDH_sha1kdf_scheme, NID_sha1, NID_dh_std_kdf}, {NID_dhSinglePass_stdDH_sha224kdf_scheme, NID_sha224, NID_dh_std_kdf}, {NID_dhSinglePass_stdDH_sha256kdf_scheme, NID_sha256, NID_dh_std_kdf}, @@ -79,6 +79,7 @@ static const nid_triple sigoid_srt[] = { {NID_RSA_SHA3_256, NID_sha3_256, NID_rsaEncryption}, {NID_RSA_SHA3_384, NID_sha3_384, NID_rsaEncryption}, {NID_RSA_SHA3_512, NID_sha3_512, NID_rsaEncryption}, + {NID_SM2_with_SM3, NID_sm3, NID_sm2}, }; static const nid_triple *const sigoid_srt_xref[] = { @@ -125,4 +126,5 @@ static const nid_triple *const sigoid_srt_xref[] = { &sigoid_srt[45], &sigoid_srt[46], &sigoid_srt[47], + &sigoid_srt[48], }; diff --git a/crypto/openssl/crypto/objects/obj_xref.txt b/crypto/openssl/crypto/objects/obj_xref.txt index ca3e74461d6c..2a61d4db5927 100644 --- a/crypto/openssl/crypto/objects/obj_xref.txt +++ b/crypto/openssl/crypto/objects/obj_xref.txt @@ -20,7 +20,7 @@ RSA_SHA3_512 sha3_512 rsaEncryption # For PSS the digest algorithm can vary and depends on the included # AlgorithmIdentifier. The digest "undef" indicates the public key # method should handle this explicitly. -rsassaPss undef rsaEncryption +rsassaPss undef rsassaPss ED25519 undef ED25519 ED448 undef ED448 @@ -64,3 +64,5 @@ dhSinglePass_cofactorDH_sha224kdf_scheme sha224 dh_cofactor_kdf dhSinglePass_cofactorDH_sha256kdf_scheme sha256 dh_cofactor_kdf dhSinglePass_cofactorDH_sha384kdf_scheme sha384 dh_cofactor_kdf dhSinglePass_cofactorDH_sha512kdf_scheme sha512 dh_cofactor_kdf + +SM2_with_SM3 sm3 sm2 diff --git a/crypto/openssl/crypto/objects/objects.pl b/crypto/openssl/crypto/objects/objects.pl old mode 100755 new mode 100644 index 8b258d4df509..51bc248b3f00 --- a/crypto/openssl/crypto/objects/objects.pl +++ b/crypto/openssl/crypto/objects/objects.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -141,12 +141,16 @@ print <<"EOF"; * Generated by crypto/objects/objects.pl * * Copyright 2000-$YEAR The OpenSSL Project Authors. All Rights Reserved. - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#ifndef OPENSSL_OBJ_MAC_H +# define OPENSSL_OBJ_MAC_H +# pragma once + #define SN_undef "UNDEF" #define LN_undef "undefined" #define NID_undef 0 @@ -172,6 +176,11 @@ foreach (sort { $a <=> $b } keys %ordern) print expand("#define OBJ_$Cname\t\t$obj{$Cname}\n") if $obj{$Cname} ne ""; } +print <reqCert = cid; if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest.requestList, one)) { one->reqCert = NULL; /* do not free on error */ - goto err; + OCSP_ONEREQ_free(one); + return NULL; } return one; - err: - OCSP_ONEREQ_free(one); - return NULL; } /* Set requestorName from an X509_NAME structure */ - -int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm) +int OCSP_request_set1_name(OCSP_REQUEST *req, const X509_NAME *nm) { - GENERAL_NAME *gen; + GENERAL_NAME *gen = GENERAL_NAME_new(); - gen = GENERAL_NAME_new(); if (gen == NULL) return 0; if (!X509_NAME_set(&gen->d.directoryName, nm)) { @@ -66,25 +61,15 @@ int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm) } /* Add a certificate to an OCSP request */ - int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert) { - OCSP_SIGNATURE *sig; - if (req->optionalSignature == NULL) - req->optionalSignature = OCSP_SIGNATURE_new(); - sig = req->optionalSignature; - if (sig == NULL) + if (req->optionalSignature == NULL + && (req->optionalSignature = OCSP_SIGNATURE_new()) == NULL) return 0; if (cert == NULL) return 1; - if (sig->certs == NULL - && (sig->certs = sk_X509_new_null()) == NULL) - return 0; - - if (!sk_X509_push(sig->certs, cert)) - return 0; - X509_up_ref(cert); - return 1; + return ossl_x509_add_cert_new(&req->optionalSignature->certs, cert, + X509_ADD_FLAG_UP_REF); } /* @@ -92,39 +77,32 @@ int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert) * optional signers certificate and include one or more optional certificates * in the request. Behaves like PKCS7_sign(). */ - int OCSP_request_sign(OCSP_REQUEST *req, X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, STACK_OF(X509) *certs, unsigned long flags) { - int i; - X509 *x; - if (!OCSP_request_set1_name(req, X509_get_subject_name(signer))) goto err; if ((req->optionalSignature = OCSP_SIGNATURE_new()) == NULL) goto err; - if (key) { + if (key != NULL) { if (!X509_check_private_key(signer, key)) { - OCSPerr(OCSP_F_OCSP_REQUEST_SIGN, - OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + ERR_raise(ERR_LIB_OCSP, + OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); goto err; } - if (!OCSP_REQUEST_sign(req, key, dgst)) + if (!OCSP_REQUEST_sign(req, key, dgst, signer->libctx, signer->propq)) goto err; } - if (!(flags & OCSP_NOCERTS)) { - if (!OCSP_request_add1_cert(req, signer)) + if ((flags & OCSP_NOCERTS) == 0) { + if (!OCSP_request_add1_cert(req, signer) + || !X509_add_certs(req->optionalSignature->certs, certs, + X509_ADD_FLAG_UP_REF)) goto err; - for (i = 0; i < sk_X509_num(certs); i++) { - x = sk_X509_value(certs, i); - if (!OCSP_request_add1_cert(req, x)) - goto err; - } } return 1; @@ -135,7 +113,6 @@ int OCSP_request_sign(OCSP_REQUEST *req, } /* Get response status */ - int OCSP_response_status(OCSP_RESPONSE *resp) { return ASN1_ENUMERATED_get(resp->responseStatus); @@ -145,17 +122,16 @@ int OCSP_response_status(OCSP_RESPONSE *resp) * Extract basic response from OCSP_RESPONSE or NULL if no basic response * present. */ - OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp) { - OCSP_RESPBYTES *rb; - rb = resp->responseBytes; - if (!rb) { - OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA); + OCSP_RESPBYTES *rb = resp->responseBytes; + + if (rb == NULL) { + ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_RESPONSE_DATA); return NULL; } if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { - OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE); + ERR_raise(ERR_LIB_OCSP, OCSP_R_NOT_BASIC_RESPONSE); return NULL; } @@ -177,27 +153,24 @@ const OCSP_RESPDATA *OCSP_resp_get0_respdata(const OCSP_BASICRESP *bs) return &bs->tbsResponseData; } -/* - * Return number of OCSP_SINGLERESP responses present in a basic response. - */ +/* Return number of OCSP_SINGLERESP responses present in a basic response */ int OCSP_resp_count(OCSP_BASICRESP *bs) { - if (!bs) + if (bs == NULL) return -1; return sk_OCSP_SINGLERESP_num(bs->tbsResponseData.responses); } /* Extract an OCSP_SINGLERESP response with a given index */ - OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx) { - if (!bs) + if (bs == NULL) return NULL; return sk_OCSP_SINGLERESP_value(bs->tbsResponseData.responses, idx); } -const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP* bs) +const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP *bs) { return bs->tbsResponseData.producedAt; } @@ -246,13 +219,13 @@ int OCSP_resp_get1_id(const OCSP_BASICRESP *bs, } /* Look single response matching a given certificate ID */ - int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last) { int i; STACK_OF(OCSP_SINGLERESP) *sresp; OCSP_SINGLERESP *single; - if (!bs) + + if (bs == NULL) return -1; if (last < 0) last = 0; @@ -272,7 +245,6 @@ int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last) * revtime and reason values are only set if the certificate status is * revoked. Returns numerical value of status. */ - int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, ASN1_GENERALIZEDTIME **revtime, ASN1_GENERALIZEDTIME **thisupd, @@ -280,12 +252,14 @@ int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, { int ret; OCSP_CERTSTATUS *cst; - if (!single) + + if (single == NULL) return -1; cst = single->certStatus; ret = cst->type; if (ret == V_OCSP_CERTSTATUS_REVOKED) { OCSP_REVOKEDINFO *rev = cst->value.revoked; + if (revtime) *revtime = rev->revocationTime; if (reason) { @@ -295,9 +269,9 @@ int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, *reason = -1; } } - if (thisupd) + if (thisupd != NULL) *thisupd = single->thisUpdate; - if (nextupd) + if (nextupd != NULL) *nextupd = single->nextUpdate; return ret; } @@ -306,22 +280,21 @@ int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, * This function combines the previous ones: look up a certificate ID and if * found extract status information. Return 0 is successful. */ - int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, int *reason, ASN1_GENERALIZEDTIME **revtime, ASN1_GENERALIZEDTIME **thisupd, ASN1_GENERALIZEDTIME **nextupd) { - int i; + int i = OCSP_resp_find(bs, id, -1); OCSP_SINGLERESP *single; - i = OCSP_resp_find(bs, id, -1); + /* Maybe check for multiple responses and give an error? */ if (i < 0) return 0; single = OCSP_resp_get0(bs, i); i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd); - if (status) + if (status != NULL) *status = i; return 1; } @@ -334,21 +307,21 @@ int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, * accepting very old responses without a nextUpdate field an optional maxage * parameter specifies the maximum age the thisUpdate field can be. */ - int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec) { int ret = 1; time_t t_now, t_tmp; + time(&t_now); /* Check thisUpdate is valid and not more than nsec in the future */ if (!ASN1_GENERALIZEDTIME_check(thisupd)) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD); + ERR_raise(ERR_LIB_OCSP, OCSP_R_ERROR_IN_THISUPDATE_FIELD); ret = 0; } else { t_tmp = t_now + nsec; if (X509_cmp_time(thisupd, &t_tmp) > 0) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID); + ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_NOT_YET_VALID); ret = 0; } @@ -359,31 +332,30 @@ int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, if (maxsec >= 0) { t_tmp = t_now - maxsec; if (X509_cmp_time(thisupd, &t_tmp) < 0) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD); + ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_TOO_OLD); ret = 0; } } } - if (!nextupd) + if (nextupd == NULL) return ret; /* Check nextUpdate is valid and not more than nsec in the past */ if (!ASN1_GENERALIZEDTIME_check(nextupd)) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD); + ERR_raise(ERR_LIB_OCSP, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD); ret = 0; } else { t_tmp = t_now - nsec; if (X509_cmp_time(nextupd, &t_tmp) < 0) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED); + ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_EXPIRED); ret = 0; } } /* Also don't allow nextUpdate to precede thisUpdate */ if (ASN1_STRING_cmp(nextupd, thisupd) < 0) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, - OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE); + ERR_raise(ERR_LIB_OCSP, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE); ret = 0; } diff --git a/crypto/openssl/crypto/ocsp/ocsp_err.c b/crypto/openssl/crypto/ocsp/ocsp_err.c index 660e193665c1..c33a7d3e6b21 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_err.c +++ b/crypto/openssl/crypto/ocsp/ocsp_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,45 +10,22 @@ #include #include +#include "crypto/ocsperr.h" -#ifndef OPENSSL_NO_ERR +#ifndef OPENSSL_NO_OCSP -static const ERR_STRING_DATA OCSP_str_functs[] = { - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_D2I_OCSP_NONCE, 0), "d2i_ocsp_nonce"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_BASIC_ADD1_STATUS, 0), - "OCSP_basic_add1_status"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_BASIC_SIGN, 0), "OCSP_basic_sign"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_BASIC_SIGN_CTX, 0), - "OCSP_basic_sign_ctx"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_BASIC_VERIFY, 0), "OCSP_basic_verify"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_CERT_ID_NEW, 0), "OCSP_cert_id_new"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_CHECK_DELEGATED, 0), - "ocsp_check_delegated"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_CHECK_IDS, 0), "ocsp_check_ids"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_CHECK_ISSUER, 0), "ocsp_check_issuer"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_CHECK_VALIDITY, 0), - "OCSP_check_validity"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_MATCH_ISSUERID, 0), - "ocsp_match_issuerid"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_PARSE_URL, 0), "OCSP_parse_url"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_REQUEST_SIGN, 0), "OCSP_request_sign"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_REQUEST_VERIFY, 0), - "OCSP_request_verify"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_OCSP_RESPONSE_GET1_BASIC, 0), - "OCSP_response_get1_basic"}, - {ERR_PACK(ERR_LIB_OCSP, OCSP_F_PARSE_HTTP_LINE1, 0), "parse_http_line1"}, - {0, NULL} -}; +# ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA OCSP_str_reasons[] = { {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_DIGEST_ERR), "digest err"}, + {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_DIGEST_NAME_ERR), "digest name err"}, + {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_DIGEST_SIZE_ERR), "digest size err"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD), "error in nextupdate field"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ERROR_IN_THISUPDATE_FIELD), "error in thisupdate field"}, - {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ERROR_PARSING_URL), "error parsing url"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_MISSING_OCSPSIGNING_USAGE), "missing ocspsigning usage"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE), @@ -68,10 +45,6 @@ static const ERR_STRING_DATA OCSP_str_reasons[] = { "response contains no revocation data"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ROOT_CA_NOT_TRUSTED), "root ca not trusted"}, - {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_SERVER_RESPONSE_ERROR), - "server response error"}, - {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_SERVER_RESPONSE_PARSE_ERROR), - "server response parse error"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_SIGNATURE_FAILURE), "signature failure"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND), "signer certificate not found"}, @@ -87,15 +60,16 @@ static const ERR_STRING_DATA OCSP_str_reasons[] = { {0, NULL} }; -#endif +# endif -int ERR_load_OCSP_strings(void) +int ossl_err_load_OCSP_strings(void) { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL) { - ERR_load_strings_const(OCSP_str_functs); +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(OCSP_str_reasons[0].error) == NULL) ERR_load_strings_const(OCSP_str_reasons); - } -#endif +# endif return 1; } +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/ocsp/ocsp_ext.c b/crypto/openssl/crypto/ocsp/ocsp_ext.c index f6c387ffb7d7..9707ccb94f4c 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_ext.c +++ b/crypto/openssl/crypto/ocsp/ocsp_ext.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -268,8 +268,8 @@ static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, memcpy(tmpval, val, len); else if (RAND_bytes(tmpval, len) <= 0) goto err; - if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, - &os, 0, X509V3_ADD_REPLACE)) + if (X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, + &os, 0, X509V3_ADD_REPLACE) <= 0) goto err; ret = 1; err: @@ -430,7 +430,7 @@ X509_EXTENSION *OCSP_archive_cutoff_new(char *tim) * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This method * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. */ -X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, const char **urls) +X509_EXTENSION *OCSP_url_svcloc_new(const X509_NAME *issuer, const char **urls) { X509_EXTENSION *x = NULL; ASN1_IA5STRING *ia5 = NULL; diff --git a/crypto/openssl/crypto/ocsp/ocsp_ht.c b/crypto/openssl/crypto/ocsp/ocsp_ht.c deleted file mode 100644 index ba408bc86f98..000000000000 --- a/crypto/openssl/crypto/ocsp/ocsp_ht.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "e_os.h" -#include -#include -#include "crypto/ctype.h" -#include -#include -#include -#include -#include - -/* Stateful OCSP request code, supporting non-blocking I/O */ - -/* Opaque OCSP request status structure */ - -struct ocsp_req_ctx_st { - int state; /* Current I/O state */ - unsigned char *iobuf; /* Line buffer */ - int iobuflen; /* Line buffer length */ - BIO *io; /* BIO to perform I/O with */ - BIO *mem; /* Memory BIO response is built into */ - unsigned long asn1_len; /* ASN1 length of response */ - unsigned long max_resp_len; /* Maximum length of response */ -}; - -#define OCSP_MAX_RESP_LENGTH (100 * 1024) -#define OCSP_MAX_LINE_LEN 4096; - -/* OCSP states */ - -/* If set no reading should be performed */ -#define OHS_NOREAD 0x1000 -/* Error condition */ -#define OHS_ERROR (0 | OHS_NOREAD) -/* First line being read */ -#define OHS_FIRSTLINE 1 -/* MIME headers being read */ -#define OHS_HEADERS 2 -/* OCSP initial header (tag + length) being read */ -#define OHS_ASN1_HEADER 3 -/* OCSP content octets being read */ -#define OHS_ASN1_CONTENT 4 -/* First call: ready to start I/O */ -#define OHS_ASN1_WRITE_INIT (5 | OHS_NOREAD) -/* Request being sent */ -#define OHS_ASN1_WRITE (6 | OHS_NOREAD) -/* Request being flushed */ -#define OHS_ASN1_FLUSH (7 | OHS_NOREAD) -/* Completed */ -#define OHS_DONE (8 | OHS_NOREAD) -/* Headers set, no final \r\n included */ -#define OHS_HTTP_HEADER (9 | OHS_NOREAD) - -static int parse_http_line1(char *line); - -OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline) -{ - OCSP_REQ_CTX *rctx = OPENSSL_zalloc(sizeof(*rctx)); - - if (rctx == NULL) - return NULL; - rctx->state = OHS_ERROR; - rctx->max_resp_len = OCSP_MAX_RESP_LENGTH; - rctx->mem = BIO_new(BIO_s_mem()); - rctx->io = io; - if (maxline > 0) - rctx->iobuflen = maxline; - else - rctx->iobuflen = OCSP_MAX_LINE_LEN; - rctx->iobuf = OPENSSL_malloc(rctx->iobuflen); - if (rctx->iobuf == NULL || rctx->mem == NULL) { - OCSP_REQ_CTX_free(rctx); - return NULL; - } - return rctx; -} - -void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx) -{ - if (!rctx) - return; - BIO_free(rctx->mem); - OPENSSL_free(rctx->iobuf); - OPENSSL_free(rctx); -} - -BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx) -{ - return rctx->mem; -} - -void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len) -{ - if (len == 0) - rctx->max_resp_len = OCSP_MAX_RESP_LENGTH; - else - rctx->max_resp_len = len; -} - -int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, ASN1_VALUE *val) -{ - static const char req_hdr[] = - "Content-Type: application/ocsp-request\r\n" - "Content-Length: %d\r\n\r\n"; - int reqlen = ASN1_item_i2d(val, NULL, it); - if (BIO_printf(rctx->mem, req_hdr, reqlen) <= 0) - return 0; - if (ASN1_item_i2d_bio(it, rctx->mem, val) <= 0) - return 0; - rctx->state = OHS_ASN1_WRITE_INIT; - return 1; -} - -int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, - ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - int rv, len; - const unsigned char *p; - - rv = OCSP_REQ_CTX_nbio(rctx); - if (rv != 1) - return rv; - - len = BIO_get_mem_data(rctx->mem, &p); - *pval = ASN1_item_d2i(NULL, &p, len, it); - if (*pval == NULL) { - rctx->state = OHS_ERROR; - return 0; - } - return 1; -} - -int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path) -{ - static const char http_hdr[] = "%s %s HTTP/1.0\r\n"; - - if (!path) - path = "/"; - - if (BIO_printf(rctx->mem, http_hdr, op, path) <= 0) - return 0; - rctx->state = OHS_HTTP_HEADER; - return 1; -} - -int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req) -{ - return OCSP_REQ_CTX_i2d(rctx, ASN1_ITEM_rptr(OCSP_REQUEST), - (ASN1_VALUE *)req); -} - -int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, - const char *name, const char *value) -{ - if (!name) - return 0; - if (BIO_puts(rctx->mem, name) <= 0) - return 0; - if (value) { - if (BIO_write(rctx->mem, ": ", 2) != 2) - return 0; - if (BIO_puts(rctx->mem, value) <= 0) - return 0; - } - if (BIO_write(rctx->mem, "\r\n", 2) != 2) - return 0; - rctx->state = OHS_HTTP_HEADER; - return 1; -} - -OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, - int maxline) -{ - - OCSP_REQ_CTX *rctx = NULL; - rctx = OCSP_REQ_CTX_new(io, maxline); - if (rctx == NULL) - return NULL; - - if (!OCSP_REQ_CTX_http(rctx, "POST", path)) - goto err; - - if (req && !OCSP_REQ_CTX_set1_req(rctx, req)) - goto err; - - return rctx; - - err: - OCSP_REQ_CTX_free(rctx); - return NULL; -} - -/* - * Parse the HTTP response. This will look like this: "HTTP/1.0 200 OK". We - * need to obtain the numeric code and (optional) informational message. - */ - -static int parse_http_line1(char *line) -{ - int retcode; - char *p, *q, *r; - /* Skip to first white space (passed protocol info) */ - - for (p = line; *p && !ossl_isspace(*p); p++) - continue; - if (!*p) { - OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); - return 0; - } - - /* Skip past white space to start of response code */ - while (*p && ossl_isspace(*p)) - p++; - - if (!*p) { - OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); - return 0; - } - - /* Find end of response code: first whitespace after start of code */ - for (q = p; *q && !ossl_isspace(*q); q++) - continue; - - if (!*q) { - OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); - return 0; - } - - /* Set end of response code and start of message */ - *q++ = 0; - - /* Attempt to parse numeric code */ - retcode = strtoul(p, &r, 10); - - if (*r) - return 0; - - /* Skip over any leading white space in message */ - while (*q && ossl_isspace(*q)) - q++; - - if (*q) { - /* - * Finally zap any trailing white space in message (include CRLF) - */ - - /* We know q has a non white space character so this is OK */ - for (r = q + strlen(q) - 1; ossl_isspace(*r); r--) - *r = 0; - } - if (retcode != 200) { - OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR); - if (!*q) - ERR_add_error_data(2, "Code=", p); - else - ERR_add_error_data(4, "Code=", p, ",Reason=", q); - return 0; - } - - return 1; - -} - -int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx) -{ - int i, n; - const unsigned char *p; - next_io: - if (!(rctx->state & OHS_NOREAD)) { - n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen); - - if (n <= 0) { - if (BIO_should_retry(rctx->io)) - return -1; - return 0; - } - - /* Write data to memory BIO */ - - if (BIO_write(rctx->mem, rctx->iobuf, n) != n) - return 0; - } - - switch (rctx->state) { - case OHS_HTTP_HEADER: - /* Last operation was adding headers: need a final \r\n */ - if (BIO_write(rctx->mem, "\r\n", 2) != 2) { - rctx->state = OHS_ERROR; - return 0; - } - rctx->state = OHS_ASN1_WRITE_INIT; - - /* fall thru */ - case OHS_ASN1_WRITE_INIT: - rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); - rctx->state = OHS_ASN1_WRITE; - - /* fall thru */ - case OHS_ASN1_WRITE: - n = BIO_get_mem_data(rctx->mem, &p); - - i = BIO_write(rctx->io, p + (n - rctx->asn1_len), rctx->asn1_len); - - if (i <= 0) { - if (BIO_should_retry(rctx->io)) - return -1; - rctx->state = OHS_ERROR; - return 0; - } - - rctx->asn1_len -= i; - - if (rctx->asn1_len > 0) - goto next_io; - - rctx->state = OHS_ASN1_FLUSH; - - (void)BIO_reset(rctx->mem); - - /* fall thru */ - case OHS_ASN1_FLUSH: - - i = BIO_flush(rctx->io); - - if (i > 0) { - rctx->state = OHS_FIRSTLINE; - goto next_io; - } - - if (BIO_should_retry(rctx->io)) - return -1; - - rctx->state = OHS_ERROR; - return 0; - - case OHS_ERROR: - return 0; - - case OHS_FIRSTLINE: - case OHS_HEADERS: - - /* Attempt to read a line in */ - - next_line: - /* - * Due to &%^*$" memory BIO behaviour with BIO_gets we have to check - * there's a complete line in there before calling BIO_gets or we'll - * just get a partial read. - */ - n = BIO_get_mem_data(rctx->mem, &p); - if ((n <= 0) || !memchr(p, '\n', n)) { - if (n >= rctx->iobuflen) { - rctx->state = OHS_ERROR; - return 0; - } - goto next_io; - } - n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen); - - if (n <= 0) { - if (BIO_should_retry(rctx->mem)) - goto next_io; - rctx->state = OHS_ERROR; - return 0; - } - - /* Don't allow excessive lines */ - if (n == rctx->iobuflen) { - rctx->state = OHS_ERROR; - return 0; - } - - /* First line */ - if (rctx->state == OHS_FIRSTLINE) { - if (parse_http_line1((char *)rctx->iobuf)) { - rctx->state = OHS_HEADERS; - goto next_line; - } else { - rctx->state = OHS_ERROR; - return 0; - } - } else { - /* Look for blank line: end of headers */ - for (p = rctx->iobuf; *p; p++) { - if ((*p != '\r') && (*p != '\n')) - break; - } - if (*p) - goto next_line; - - rctx->state = OHS_ASN1_HEADER; - - } - - /* Fall thru */ - - case OHS_ASN1_HEADER: - /* - * Now reading ASN1 header: can read at least 2 bytes which is enough - * for ASN1 SEQUENCE header and either length field or at least the - * length of the length field. - */ - n = BIO_get_mem_data(rctx->mem, &p); - if (n < 2) - goto next_io; - - /* Check it is an ASN1 SEQUENCE */ - if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { - rctx->state = OHS_ERROR; - return 0; - } - - /* Check out length field */ - if (*p & 0x80) { - /* - * If MSB set on initial length octet we can now always read 6 - * octets: make sure we have them. - */ - if (n < 6) - goto next_io; - n = *p & 0x7F; - /* Not NDEF or excessive length */ - if (!n || (n > 4)) { - rctx->state = OHS_ERROR; - return 0; - } - p++; - rctx->asn1_len = 0; - for (i = 0; i < n; i++) { - rctx->asn1_len <<= 8; - rctx->asn1_len |= *p++; - } - - if (rctx->asn1_len > rctx->max_resp_len) { - rctx->state = OHS_ERROR; - return 0; - } - - rctx->asn1_len += n + 2; - } else - rctx->asn1_len = *p + 2; - - rctx->state = OHS_ASN1_CONTENT; - - /* Fall thru */ - - case OHS_ASN1_CONTENT: - n = BIO_get_mem_data(rctx->mem, NULL); - if (n < (int)rctx->asn1_len) - goto next_io; - - rctx->state = OHS_DONE; - return 1; - - case OHS_DONE: - return 1; - - } - - return 0; - -} - -int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx) -{ - return OCSP_REQ_CTX_nbio_d2i(rctx, - (ASN1_VALUE **)presp, - ASN1_ITEM_rptr(OCSP_RESPONSE)); -} - -/* Blocking OCSP request handler: now a special case of non-blocking I/O */ - -OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req) -{ - OCSP_RESPONSE *resp = NULL; - OCSP_REQ_CTX *ctx; - int rv; - - ctx = OCSP_sendreq_new(b, path, req, -1); - - if (ctx == NULL) - return NULL; - - do { - rv = OCSP_sendreq_nbio(&resp, ctx); - } while ((rv == -1) && BIO_should_retry(b)); - - OCSP_REQ_CTX_free(ctx); - - if (rv) - return resp; - - return NULL; -} diff --git a/crypto/openssl/crypto/ocsp/ocsp_http.c b/crypto/openssl/crypto/ocsp/ocsp_http.c new file mode 100644 index 000000000000..e8b6406d3c38 --- /dev/null +++ b/crypto/openssl/crypto/ocsp/ocsp_http.c @@ -0,0 +1,68 @@ +/* + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +#ifndef OPENSSL_NO_OCSP + +OSSL_HTTP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, + const OCSP_REQUEST *req, int buf_size) +{ + OSSL_HTTP_REQ_CTX *rctx = OSSL_HTTP_REQ_CTX_new(io, io, buf_size); + + if (rctx == NULL) + return NULL; + /*- + * by default: + * no bio_update_fn (and consequently no arg) + * no ssl + * no proxy + * no timeout (blocking indefinitely) + * no expected content type + * max_resp_len = 100 KiB + */ + if (!OSSL_HTTP_REQ_CTX_set_request_line(rctx, 1 /* POST */, + NULL, NULL, path)) + goto err; + /* by default, no extra headers */ + if (!OSSL_HTTP_REQ_CTX_set_expected(rctx, + NULL /* content_type */, 1 /* asn1 */, + 0 /* timeout */, 0 /* keep_alive */)) + goto err; + if (req != NULL + && !OSSL_HTTP_REQ_CTX_set1_req(rctx, "application/ocsp-request", + ASN1_ITEM_rptr(OCSP_REQUEST), + (const ASN1_VALUE *)req)) + goto err; + return rctx; + + err: + OSSL_HTTP_REQ_CTX_free(rctx); + return NULL; +} + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req) +{ + OCSP_RESPONSE *resp = NULL; + OSSL_HTTP_REQ_CTX *ctx; + BIO *mem; + + ctx = OCSP_sendreq_new(b, path, req, 0 /* default buf_size */); + if (ctx == NULL) + return NULL; + mem = OSSL_HTTP_REQ_CTX_exchange(ctx); + /* ASN1_item_d2i_bio handles NULL bio gracefully */ + resp = (OCSP_RESPONSE *)ASN1_item_d2i_bio(ASN1_ITEM_rptr(OCSP_RESPONSE), + mem, NULL); + + OSSL_HTTP_REQ_CTX_free(ctx); + return resp; +} +#endif /* !defined(OPENSSL_NO_OCSP) */ diff --git a/crypto/openssl/crypto/ocsp/ocsp_lib.c b/crypto/openssl/crypto/ocsp/ocsp_lib.c index 37ac6c03fd04..285634dec37b 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_lib.c +++ b/crypto/openssl/crypto/ocsp/ocsp_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -22,9 +22,10 @@ OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject, const X509 *issuer) { - X509_NAME *iname; + const X509_NAME *iname; const ASN1_INTEGER *serial; ASN1_BIT_STRING *ikey; + if (!dgst) dgst = EVP_sha1(); if (subject) { @@ -54,8 +55,8 @@ OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, alg = &cid->hashAlgorithm; ASN1_OBJECT_free(alg->algorithm); - if ((nid = EVP_MD_type(dgst)) == NID_undef) { - OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_UNKNOWN_NID); + if ((nid = EVP_MD_get_type(dgst)) == NID_undef) { + ERR_raise(ERR_LIB_OCSP, OCSP_R_UNKNOWN_NID); goto err; } if ((alg->algorithm = OBJ_nid2obj(nid)) == NULL) @@ -82,7 +83,7 @@ OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, } return cid; digerr: - OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_DIGEST_ERR); + ERR_raise(ERR_LIB_OCSP, OCSP_R_DIGEST_ERR); err: OCSP_CERTID_free(cid); return NULL; @@ -109,114 +110,4 @@ int OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b) return ASN1_INTEGER_cmp(&a->serialNumber, &b->serialNumber); } -/* - * Parse a URL and split it up into host, port and path components and - * whether it is SSL. - */ - -int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, - int *pssl) -{ - char *p, *buf; - - char *host, *port; - - *phost = NULL; - *pport = NULL; - *ppath = NULL; - - /* dup the buffer since we are going to mess with it */ - buf = OPENSSL_strdup(url); - if (!buf) - goto mem_err; - - /* Check for initial colon */ - p = strchr(buf, ':'); - - if (!p) - goto parse_err; - - *(p++) = '\0'; - - if (strcmp(buf, "http") == 0) { - *pssl = 0; - port = "80"; - } else if (strcmp(buf, "https") == 0) { - *pssl = 1; - port = "443"; - } else - goto parse_err; - - /* Check for double slash */ - if ((p[0] != '/') || (p[1] != '/')) - goto parse_err; - - p += 2; - - host = p; - - /* Check for trailing part of path */ - - p = strchr(p, '/'); - - if (!p) - *ppath = OPENSSL_strdup("/"); - else { - *ppath = OPENSSL_strdup(p); - /* Set start of path to 0 so hostname is valid */ - *p = '\0'; - } - - if (!*ppath) - goto mem_err; - - p = host; - if (host[0] == '[') { - /* ipv6 literal */ - host++; - p = strchr(host, ']'); - if (!p) - goto parse_err; - *p = '\0'; - p++; - } - - /* Look for optional ':' for port number */ - if ((p = strchr(p, ':'))) { - *p = 0; - port = p + 1; - } - - *pport = OPENSSL_strdup(port); - if (!*pport) - goto mem_err; - - *phost = OPENSSL_strdup(host); - - if (!*phost) - goto mem_err; - - OPENSSL_free(buf); - - return 1; - - mem_err: - OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE); - goto err; - - parse_err: - OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL); - - err: - OPENSSL_free(buf); - OPENSSL_free(*ppath); - *ppath = NULL; - OPENSSL_free(*pport); - *pport = NULL; - OPENSSL_free(*phost); - *phost = NULL; - return 0; - -} - IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID) diff --git a/crypto/openssl/crypto/ocsp/ocsp_local.h b/crypto/openssl/crypto/ocsp/ocsp_local.h index 36646fdfc97a..e1633403c685 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_local.h +++ b/crypto/openssl/crypto/ocsp/ocsp_local.h @@ -1,12 +1,14 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 "crypto/x509.h" /* for ossl_x509_add_cert_new() */ + /*- CertID ::= SEQUENCE { * hashAlgorithm AlgorithmIdentifier, * issuerNameHash OCTET STRING, -- Hash of Issuer's DN @@ -215,22 +217,30 @@ struct ocsp_service_locator_st { STACK_OF(ACCESS_DESCRIPTION) *locator; }; -# define OCSP_REQUEST_sign(o,pkey,md) \ - ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\ - &(o)->optionalSignature->signatureAlgorithm,NULL,\ - (o)->optionalSignature->signature,&(o)->tbsRequest,pkey,md) - -# define OCSP_BASICRESP_sign(o,pkey,md,d) \ - ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),&(o)->signatureAlgorithm,\ - NULL,(o)->signature,&(o)->tbsResponseData,pkey,md) - -# define OCSP_BASICRESP_sign_ctx(o,ctx,d) \ - ASN1_item_sign_ctx(ASN1_ITEM_rptr(OCSP_RESPDATA),&(o)->signatureAlgorithm,\ - NULL,(o)->signature,&(o)->tbsResponseData,ctx) - -# define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\ - &(a)->optionalSignature->signatureAlgorithm,\ - (a)->optionalSignature->signature,&(a)->tbsRequest,r) - -# define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\ - &(a)->signatureAlgorithm,(a)->signature,&(a)->tbsResponseData,r) +# define OCSP_REQUEST_sign(o, pkey, md, libctx, propq)\ + ASN1_item_sign_ex(ASN1_ITEM_rptr(OCSP_REQINFO),\ + &(o)->optionalSignature->signatureAlgorithm, NULL,\ + (o)->optionalSignature->signature, &(o)->tbsRequest,\ + NULL, pkey, md, libctx, propq) + +# define OCSP_BASICRESP_sign(o, pkey, md, d, libctx, propq)\ + ASN1_item_sign_ex(ASN1_ITEM_rptr(OCSP_RESPDATA),\ + &(o)->signatureAlgorithm, NULL,\ + (o)->signature, &(o)->tbsResponseData,\ + NULL, pkey, md, libctx, propq) + +# define OCSP_BASICRESP_sign_ctx(o, ctx, d)\ + ASN1_item_sign_ctx(ASN1_ITEM_rptr(OCSP_RESPDATA),\ + &(o)->signatureAlgorithm, NULL,\ + (o)->signature, &(o)->tbsResponseData, ctx) + +# define OCSP_REQUEST_verify(a, r, libctx, propq)\ + ASN1_item_verify_ex(ASN1_ITEM_rptr(OCSP_REQINFO),\ + &(a)->optionalSignature->signatureAlgorithm,\ + (a)->optionalSignature->signature, &(a)->tbsRequest,\ + NULL, r, libctx, propq) + +# define OCSP_BASICRESP_verify(a, r, libctx, propq)\ + ASN1_item_verify_ex(ASN1_ITEM_rptr(OCSP_RESPDATA),\ + &(a)->signatureAlgorithm, (a)->signature,\ + &(a)->tbsResponseData, NULL, r, libctx, propq) diff --git a/crypto/openssl/crypto/ocsp/ocsp_prn.c b/crypto/openssl/crypto/ocsp/ocsp_prn.c index 1965f2a183b3..654ddbc7fff3 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_prn.c +++ b/crypto/openssl/crypto/ocsp/ocsp_prn.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ocsp/ocsp_srv.c b/crypto/openssl/crypto/ocsp/ocsp_srv.c index e35fc52fd944..dbb6e760b20c 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_srv.c +++ b/crypto/openssl/crypto/ocsp/ocsp_srv.c @@ -1,7 +1,7 @@ /* - * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,7 +20,6 @@ * Utility functions related to sending OCSP responses and extracting * relevant information from the request. */ - int OCSP_request_onereq_count(OCSP_REQUEST *req) { return sk_OCSP_ONEREQ_num(req->tbsRequest.requestList); @@ -117,7 +116,7 @@ OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, switch (cs->type = status) { case V_OCSP_CERTSTATUS_REVOKED: if (!revtime) { - OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS, OCSP_R_NO_REVOKED_TIME); + ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_REVOKED_TIME); goto err; } if ((cs->value.revoked = ri = OCSP_REVOKEDINFO_new()) == NULL) @@ -155,17 +154,9 @@ OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, } /* Add a certificate to an OCSP request */ - int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert) { - if (resp->certs == NULL - && (resp->certs = sk_X509_new_null()) == NULL) - return 0; - - if (!sk_X509_push(resp->certs, cert)) - return 0; - X509_up_ref(cert); - return 1; + return ossl_x509_add_cert_new(&resp->certs, cert, X509_ADD_FLAG_UP_REF); } /* @@ -173,35 +164,28 @@ int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert) * set the responderID to the subject name in the signer's certificate, and * include one or more optional certificates in the response. */ - int OCSP_basic_sign_ctx(OCSP_BASICRESP *brsp, X509 *signer, EVP_MD_CTX *ctx, STACK_OF(X509) *certs, unsigned long flags) { - int i; OCSP_RESPID *rid; EVP_PKEY *pkey; - if (ctx == NULL || EVP_MD_CTX_pkey_ctx(ctx) == NULL) { - OCSPerr(OCSP_F_OCSP_BASIC_SIGN_CTX, OCSP_R_NO_SIGNER_KEY); + if (ctx == NULL || EVP_MD_CTX_get_pkey_ctx(ctx) == NULL) { + ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_SIGNER_KEY); goto err; } - pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); + pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx)); if (pkey == NULL || !X509_check_private_key(signer, pkey)) { - OCSPerr(OCSP_F_OCSP_BASIC_SIGN_CTX, - OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + ERR_raise(ERR_LIB_OCSP, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); goto err; } if (!(flags & OCSP_NOCERTS)) { - if (!OCSP_basic_add1_cert(brsp, signer)) + if (!OCSP_basic_add1_cert(brsp, signer) + || !X509_add_certs(brsp->certs, certs, X509_ADD_FLAG_UP_REF)) goto err; - for (i = 0; i < sk_X509_num(certs); i++) { - X509 *tmpcert = sk_X509_value(certs, i); - if (!OCSP_basic_add1_cert(brsp, tmpcert)) - goto err; - } } rid = &brsp->tbsResponseData.responderId; @@ -220,7 +204,6 @@ int OCSP_basic_sign_ctx(OCSP_BASICRESP *brsp, * Right now, I think that not doing double hashing is the right thing. * -- Richard Levitte */ - if (!OCSP_BASICRESP_sign_ctx(brsp, ctx, 0)) goto err; @@ -240,7 +223,8 @@ int OCSP_basic_sign(OCSP_BASICRESP *brsp, if (ctx == NULL) return 0; - if (!EVP_DigestSignInit(ctx, &pkctx, dgst, NULL, key)) { + if (!EVP_DigestSignInit_ex(ctx, &pkctx, EVP_MD_get0_name(dgst), + signer->libctx, signer->propq, key, NULL)) { EVP_MD_CTX_free(ctx); return 0; } @@ -259,45 +243,69 @@ int OCSP_RESPID_set_by_name(OCSP_RESPID *respid, X509 *cert) return 1; } -int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert) +int OCSP_RESPID_set_by_key_ex(OCSP_RESPID *respid, X509 *cert, + OSSL_LIB_CTX *libctx, const char *propq) { ASN1_OCTET_STRING *byKey = NULL; unsigned char md[SHA_DIGEST_LENGTH]; + EVP_MD *sha1 = EVP_MD_fetch(libctx, "SHA1", propq); + int ret = 0; - /* RFC2560 requires SHA1 */ - if (!X509_pubkey_digest(cert, EVP_sha1(), md, NULL)) + if (sha1 == NULL) return 0; + /* RFC2560 requires SHA1 */ + if (!X509_pubkey_digest(cert, sha1, md, NULL)) + goto err; + byKey = ASN1_OCTET_STRING_new(); if (byKey == NULL) - return 0; + goto err; if (!(ASN1_OCTET_STRING_set(byKey, md, SHA_DIGEST_LENGTH))) { ASN1_OCTET_STRING_free(byKey); - return 0; + goto err; } respid->type = V_OCSP_RESPID_KEY; respid->value.byKey = byKey; - return 1; + ret = 1; + err: + EVP_MD_free(sha1); + return ret; } -int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert) +int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert) { + if (cert == NULL) + return 0; + return OCSP_RESPID_set_by_key_ex(respid, cert, cert->libctx, cert->propq); +} + +int OCSP_RESPID_match_ex(OCSP_RESPID *respid, X509 *cert, OSSL_LIB_CTX *libctx, + const char *propq) +{ + EVP_MD *sha1 = NULL; + int ret = 0; + if (respid->type == V_OCSP_RESPID_KEY) { unsigned char md[SHA_DIGEST_LENGTH]; + sha1 = EVP_MD_fetch(libctx, "SHA1", propq); + if (sha1 == NULL) + goto err; + if (respid->value.byKey == NULL) - return 0; + goto err; /* RFC2560 requires SHA1 */ - if (!X509_pubkey_digest(cert, EVP_sha1(), md, NULL)) - return 0; + if (!X509_pubkey_digest(cert, sha1, md, NULL)) + goto err; - return (ASN1_STRING_length(respid->value.byKey) == SHA_DIGEST_LENGTH) - && (memcmp(ASN1_STRING_get0_data(respid->value.byKey), md, - SHA_DIGEST_LENGTH) == 0); + ret = (ASN1_STRING_length(respid->value.byKey) == SHA_DIGEST_LENGTH) + && (memcmp(ASN1_STRING_get0_data(respid->value.byKey), md, + SHA_DIGEST_LENGTH) == 0); } else if (respid->type == V_OCSP_RESPID_NAME) { if (respid->value.byName == NULL) return 0; @@ -306,5 +314,14 @@ int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert) X509_get_subject_name(cert)) == 0; } - return 0; + err: + EVP_MD_free(sha1); + return ret; +} + +int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert) +{ + if (cert == NULL) + return 0; + return OCSP_RESPID_match_ex(respid, cert, cert->libctx, cert->propq); } diff --git a/crypto/openssl/crypto/ocsp/ocsp_vfy.c b/crypto/openssl/crypto/ocsp/ocsp_vfy.c index e87b71c0c791..fa07539d7e86 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_vfy.c +++ b/crypto/openssl/crypto/ocsp/ocsp_vfy.c @@ -1,16 +1,17 @@ /* - * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#include #include -#include "ocsp_local.h" #include -#include +#include "internal/sizes.h" +#include "ocsp_local.h" static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, unsigned long flags); @@ -22,80 +23,107 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, STACK_OF(OCSP_SINGLERESP) *sresp); static int ocsp_check_delegated(X509 *x); static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, - X509_NAME *nm, STACK_OF(X509) *certs, + const X509_NAME *nm, STACK_OF(X509) *certs, unsigned long flags); -/* Verify a basic response message */ +/* Returns 1 on success, 0 on failure, or -1 on fatal error */ +static int ocsp_verify_signer(X509 *signer, int response, + X509_STORE *st, unsigned long flags, + STACK_OF(X509) *untrusted, STACK_OF(X509) **chain) +{ + X509_STORE_CTX *ctx = X509_STORE_CTX_new(); + X509_VERIFY_PARAM *vp; + int ret = -1; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_OCSP, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!X509_STORE_CTX_init(ctx, st, signer, untrusted)) { + ERR_raise(ERR_LIB_OCSP, ERR_R_X509_LIB); + goto end; + } + if ((vp = X509_STORE_CTX_get0_param(ctx)) == NULL) + goto end; + if ((flags & OCSP_PARTIAL_CHAIN) != 0) + X509_VERIFY_PARAM_set_flags(vp, X509_V_FLAG_PARTIAL_CHAIN); + if (response + && X509_get_ext_by_NID(signer, NID_id_pkix_OCSP_noCheck, -1) >= 0) + /* + * Locally disable revocation status checking for OCSP responder cert. + * Done here for CRLs; should be done also for OCSP-based checks. + */ + X509_VERIFY_PARAM_clear_flags(vp, X509_V_FLAG_CRL_CHECK); + X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER); + X509_STORE_CTX_set_trust(ctx, X509_TRUST_OCSP_REQUEST); + + ret = X509_verify_cert(ctx); + if (ret <= 0) { + int err = X509_STORE_CTX_get_error(ctx); + + ERR_raise_data(ERR_LIB_OCSP, OCSP_R_CERTIFICATE_VERIFY_ERROR, + "Verify error: %s", X509_verify_cert_error_string(err)); + goto end; + } + if (chain != NULL) + *chain = X509_STORE_CTX_get1_chain(ctx); + + end: + X509_STORE_CTX_free(ctx); + return ret; +} + +static int ocsp_verify(OCSP_REQUEST *req, OCSP_BASICRESP *bs, + X509 *signer, unsigned long flags) +{ + EVP_PKEY *skey; + int ret = 1; + + if ((flags & OCSP_NOSIGS) == 0) { + if ((skey = X509_get0_pubkey(signer)) == NULL) { + ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_SIGNER_KEY); + return -1; + } + if (req != NULL) + ret = OCSP_REQUEST_verify(req, skey, signer->libctx, signer->propq); + else + ret = OCSP_BASICRESP_verify(bs, skey, signer->libctx, signer->propq); + if (ret <= 0) + ERR_raise(ERR_LIB_OCSP, OCSP_R_SIGNATURE_FAILURE); + } + return ret; +} +/* Verify a basic response message */ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags) { X509 *signer, *x; STACK_OF(X509) *chain = NULL; STACK_OF(X509) *untrusted = NULL; - X509_STORE_CTX *ctx = NULL; - int i, ret = ocsp_find_signer(&signer, bs, certs, flags); + int ret = ocsp_find_signer(&signer, bs, certs, flags); - if (!ret) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, - OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); + if (ret == 0) { + ERR_raise(ERR_LIB_OCSP, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); goto end; } - ctx = X509_STORE_CTX_new(); - if (ctx == NULL) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); - goto f_err; - } - if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) + if ((ret == 2) && (flags & OCSP_TRUSTOTHER) != 0) flags |= OCSP_NOVERIFY; - if (!(flags & OCSP_NOSIGS)) { - EVP_PKEY *skey; - skey = X509_get0_pubkey(signer); - if (skey == NULL) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_NO_SIGNER_KEY); - goto err; - } - ret = OCSP_BASICRESP_verify(bs, skey, 0); - if (ret <= 0) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); - goto end; - } - } - if (!(flags & OCSP_NOVERIFY)) { - int init_res; - if (flags & OCSP_NOCHAIN) { - untrusted = NULL; - } else if (bs->certs && certs) { - untrusted = sk_X509_dup(bs->certs); - for (i = 0; i < sk_X509_num(certs); i++) { - if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); - goto f_err; - } - } - } else if (certs != NULL) { - untrusted = certs; - } else { - untrusted = bs->certs; - } - init_res = X509_STORE_CTX_init(ctx, st, signer, untrusted); - if (!init_res) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB); - goto f_err; - } - X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER); - ret = X509_verify_cert(ctx); - chain = X509_STORE_CTX_get1_chain(ctx); - if (ret <= 0) { - i = X509_STORE_CTX_get_error(ctx); - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, - OCSP_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(i)); - goto end; + if ((ret = ocsp_verify(NULL, bs, signer, flags)) <= 0) + goto end; + if ((flags & OCSP_NOVERIFY) == 0) { + ret = -1; + if ((flags & OCSP_NOCHAIN) == 0) { + if ((untrusted = sk_X509_dup(bs->certs)) == NULL) + goto end; + if (!X509_add_certs(untrusted, certs, X509_ADD_FLAG_DEFAULT)) + goto end; } - if (flags & OCSP_NOCHECKS) { + ret = ocsp_verify_signer(signer, 1, st, flags, untrusted, &chain); + if (ret <= 0) + goto end; + if ((flags & OCSP_NOCHECKS) != 0) { ret = 1; goto end; } @@ -113,38 +141,28 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, * Easy case: explicitly trusted. Get root CA and check for explicit * trust */ - if (flags & OCSP_NOEXPLICIT) + if ((flags & OCSP_NOEXPLICIT) != 0) goto end; x = sk_X509_value(chain, sk_X509_num(chain) - 1); if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED); - goto err; + ERR_raise(ERR_LIB_OCSP, OCSP_R_ROOT_CA_NOT_TRUSTED); + ret = 0; + goto end; } ret = 1; } + end: - X509_STORE_CTX_free(ctx); sk_X509_pop_free(chain, X509_free); - if (bs->certs && certs) - sk_X509_free(untrusted); + sk_X509_free(untrusted); return ret; - - err: - ret = 0; - goto end; - f_err: - ret = -1; - goto end; } int OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer, STACK_OF(X509) *extra_certs) { - int ret; - - ret = ocsp_find_signer(signer, bs, extra_certs, 0); - return (ret > 0) ? 1 : 0; + return ocsp_find_signer(signer, bs, extra_certs, 0) > 0; } static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, @@ -152,11 +170,12 @@ static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, { X509 *signer; OCSP_RESPID *rid = &bs->tbsResponseData.responderId; - if ((signer = ocsp_find_signer_sk(certs, rid))) { + + if ((signer = ocsp_find_signer_sk(certs, rid)) != NULL) { *psigner = signer; return 2; } - if (!(flags & OCSP_NOINTERN) && + if ((flags & OCSP_NOINTERN) == 0 && (signer = ocsp_find_signer_sk(bs->certs, rid))) { *psigner = signer; return 1; @@ -169,8 +188,9 @@ static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) { - int i; + int i, r; unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; + EVP_MD *md; X509 *x; /* Easy if lookup by name */ @@ -185,42 +205,47 @@ static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) keyhash = id->value.byKey->data; /* Calculate hash of each key and compare */ for (i = 0; i < sk_X509_num(certs); i++) { - x = sk_X509_value(certs, i); - X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); - if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) - return x; + if ((x = sk_X509_value(certs, i)) != NULL) { + if ((md = EVP_MD_fetch(x->libctx, SN_sha1, x->propq)) == NULL) + break; + r = X509_pubkey_digest(x, md, tmphash, NULL); + EVP_MD_free(md); + if (!r) + break; + if (memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH) == 0) + return x; + } } return NULL; } static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain) { - STACK_OF(OCSP_SINGLERESP) *sresp; + STACK_OF(OCSP_SINGLERESP) *sresp = bs->tbsResponseData.responses; X509 *signer, *sca; OCSP_CERTID *caid = NULL; - int i; - sresp = bs->tbsResponseData.responses; + int ret; if (sk_X509_num(chain) <= 0) { - OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN); + ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_CERTIFICATES_IN_CHAIN); return -1; } /* See if the issuer IDs match. */ - i = ocsp_check_ids(sresp, &caid); + ret = ocsp_check_ids(sresp, &caid); /* If ID mismatch or other error then return */ - if (i <= 0) - return i; + if (ret <= 0) + return ret; signer = sk_X509_value(chain, 0); /* Check to see if OCSP responder CA matches request CA */ if (sk_X509_num(chain) > 1) { sca = sk_X509_value(chain, 1); - i = ocsp_match_issuerid(sca, caid, sresp); - if (i < 0) - return i; - if (i) { + ret = ocsp_match_issuerid(sca, caid, sresp); + if (ret < 0) + return ret; + if (ret != 0) { /* We have a match, if extensions OK then success */ if (ocsp_check_delegated(signer)) return 1; @@ -246,15 +271,13 @@ static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) idcount = sk_OCSP_SINGLERESP_num(sresp); if (idcount <= 0) { - OCSPerr(OCSP_F_OCSP_CHECK_IDS, - OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA); + ERR_raise(ERR_LIB_OCSP, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA); return -1; } cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; *ret = NULL; - for (i = 1; i < idcount; i++) { tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; /* Check to see if IDs match */ @@ -273,52 +296,76 @@ static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) return 1; } +/* + * Match the certificate issuer ID. + * Returns -1 on fatal error, 0 if there is no match and 1 if there is a match. + */ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, STACK_OF(OCSP_SINGLERESP) *sresp) { + int ret = -1; + EVP_MD *dgst = NULL; + /* If only one ID to match then do it */ - if (cid) { - const EVP_MD *dgst; - X509_NAME *iname; + if (cid != NULL) { + char name[OSSL_MAX_NAME_SIZE]; + const X509_NAME *iname; int mdlen; unsigned char md[EVP_MAX_MD_SIZE]; - if ((dgst = EVP_get_digestbyobj(cid->hashAlgorithm.algorithm)) - == NULL) { - OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID, - OCSP_R_UNKNOWN_MESSAGE_DIGEST); - return -1; + + OBJ_obj2txt(name, sizeof(name), cid->hashAlgorithm.algorithm, 0); + + (void)ERR_set_mark(); + dgst = EVP_MD_fetch(NULL, name, NULL); + if (dgst == NULL) + dgst = (EVP_MD *)EVP_get_digestbyname(name); + + if (dgst == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_OCSP, OCSP_R_UNKNOWN_MESSAGE_DIGEST); + goto end; } + (void)ERR_pop_to_mark(); - mdlen = EVP_MD_size(dgst); - if (mdlen < 0) - return -1; - if ((cid->issuerNameHash.length != mdlen) || - (cid->issuerKeyHash.length != mdlen)) - return 0; + mdlen = EVP_MD_get_size(dgst); + if (mdlen < 0) { + ERR_raise(ERR_LIB_OCSP, OCSP_R_DIGEST_SIZE_ERR); + goto end; + } + if (cid->issuerNameHash.length != mdlen || + cid->issuerKeyHash.length != mdlen) { + ret = 0; + goto end; + } iname = X509_get_subject_name(cert); if (!X509_NAME_digest(iname, dgst, md, NULL)) - return -1; - if (memcmp(md, cid->issuerNameHash.data, mdlen)) - return 0; - X509_pubkey_digest(cert, dgst, md, NULL); - if (memcmp(md, cid->issuerKeyHash.data, mdlen)) - return 0; - - return 1; - + goto end; + if (memcmp(md, cid->issuerNameHash.data, mdlen) != 0) { + ret = 0; + goto end; + } + if (!X509_pubkey_digest(cert, dgst, md, NULL)) { + ERR_raise(ERR_LIB_OCSP, OCSP_R_DIGEST_ERR); + goto end; + } + ret = memcmp(md, cid->issuerKeyHash.data, mdlen) == 0; + goto end; } else { /* We have to match the whole lot */ - int i, ret; + int i; OCSP_CERTID *tmpid; + for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) { tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; ret = ocsp_match_issuerid(cert, tmpid, NULL); if (ret <= 0) return ret; } - return 1; } - + return 1; +end: + EVP_MD_free(dgst); + return ret; } static int ocsp_check_delegated(X509 *x) @@ -326,108 +373,66 @@ static int ocsp_check_delegated(X509 *x) if ((X509_get_extension_flags(x) & EXFLAG_XKUSAGE) && (X509_get_extended_key_usage(x) & XKU_OCSP_SIGN)) return 1; - OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE); + ERR_raise(ERR_LIB_OCSP, OCSP_R_MISSING_OCSPSIGNING_USAGE); return 0; } /* - * Verify an OCSP request. This is fortunately much easier than OCSP response - * verify. Just find the signers certificate and verify it against a given - * trust value. + * Verify an OCSP request. This is much easier than OCSP response verify. + * Just find the signer's certificate and verify it against a given trust value. + * Returns 1 on success, 0 on failure and on fatal error. */ - int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags) { X509 *signer; - X509_NAME *nm; + const X509_NAME *nm; GENERAL_NAME *gen; - int ret = 0; - X509_STORE_CTX *ctx = X509_STORE_CTX_new(); - - if (ctx == NULL) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } + int ret; if (!req->optionalSignature) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED); - goto err; + ERR_raise(ERR_LIB_OCSP, OCSP_R_REQUEST_NOT_SIGNED); + return 0; } gen = req->tbsRequest.requestorName; if (!gen || gen->type != GEN_DIRNAME) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, - OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); - goto err; + ERR_raise(ERR_LIB_OCSP, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); + return 0; /* not returning -1 here for backward compatibility*/ } nm = gen->d.directoryName; ret = ocsp_req_find_signer(&signer, req, nm, certs, flags); if (ret <= 0) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, - OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); - goto err; + ERR_raise(ERR_LIB_OCSP, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); + return 0; /* not returning -1 here for backward compatibility*/ } - if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) + if ((ret == 2) && (flags & OCSP_TRUSTOTHER) != 0) flags |= OCSP_NOVERIFY; - if (!(flags & OCSP_NOSIGS)) { - EVP_PKEY *skey; - skey = X509_get0_pubkey(signer); - ret = OCSP_REQUEST_verify(req, skey); - if (ret <= 0) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE); - goto err; - } - } - if (!(flags & OCSP_NOVERIFY)) { - int init_res; - if (flags & OCSP_NOCHAIN) - init_res = X509_STORE_CTX_init(ctx, store, signer, NULL); - else - init_res = X509_STORE_CTX_init(ctx, store, signer, - req->optionalSignature->certs); - if (!init_res) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB); - goto err; - } - - X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER); - X509_STORE_CTX_set_trust(ctx, X509_TRUST_OCSP_REQUEST); - ret = X509_verify_cert(ctx); - if (ret <= 0) { - ret = X509_STORE_CTX_get_error(ctx); - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, - OCSP_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(ret)); - goto err; - } - } - ret = 1; - goto end; - -err: - ret = 0; -end: - X509_STORE_CTX_free(ctx); - return ret; + if ((ret = ocsp_verify(req, NULL, signer, flags)) <= 0) + return 0; /* not returning 'ret' here for backward compatibility*/ + if ((flags & OCSP_NOVERIFY) != 0) + return 1; + return ocsp_verify_signer(signer, 0, store, flags, + (flags & OCSP_NOCHAIN) != 0 ? + NULL : req->optionalSignature->certs, NULL) > 0; + /* using '> 0' here to avoid breaking backward compatibility returning -1 */ } static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, - X509_NAME *nm, STACK_OF(X509) *certs, + const X509_NAME *nm, STACK_OF(X509) *certs, unsigned long flags) { X509 *signer; - if (!(flags & OCSP_NOINTERN)) { + + if ((flags & OCSP_NOINTERN) == 0) { signer = X509_find_by_subject(req->optionalSignature->certs, nm); - if (signer) { + if (signer != NULL) { *psigner = signer; return 1; } } - signer = X509_find_by_subject(certs, nm); - if (signer) { + if ((signer = X509_find_by_subject(certs, nm)) != NULL) { *psigner = signer; return 2; } diff --git a/crypto/openssl/crypto/ocsp/v3_ocsp.c b/crypto/openssl/crypto/ocsp/v3_ocsp.c index a174ce15a60d..2250208a1577 100644 --- a/crypto/openssl/crypto/ocsp/v3_ocsp.c +++ b/crypto/openssl/crypto/ocsp/v3_ocsp.c @@ -1,20 +1,20 @@ /* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -# include -# include "internal/cryptlib.h" -# include -# include -# include -# include "ocsp_local.h" -# include -# include "../x509v3/ext_dat.h" +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include "ocsp_local.h" +#include +#include "../x509/ext_dat.h" /* * OCSP extensions and a couple of CRL entry extensions @@ -28,7 +28,7 @@ static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out, int indent); static void *ocsp_nonce_new(void); -static int i2d_ocsp_nonce(void *a, unsigned char **pp); +static int i2d_ocsp_nonce(const void *a, unsigned char **pp); static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length); static void ocsp_nonce_free(void *a); static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, @@ -41,7 +41,7 @@ static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind); -const X509V3_EXT_METHOD v3_ocsp_crlid = { +const X509V3_EXT_METHOD ossl_v3_ocsp_crlid = { NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID), 0, 0, 0, 0, 0, 0, @@ -50,7 +50,7 @@ const X509V3_EXT_METHOD v3_ocsp_crlid = { NULL }; -const X509V3_EXT_METHOD v3_ocsp_acutoff = { +const X509V3_EXT_METHOD ossl_v3_ocsp_acutoff = { NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), 0, 0, 0, 0, 0, 0, @@ -59,7 +59,7 @@ const X509V3_EXT_METHOD v3_ocsp_acutoff = { NULL }; -const X509V3_EXT_METHOD v3_crl_invdate = { +const X509V3_EXT_METHOD ossl_v3_crl_invdate = { NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), 0, 0, 0, 0, 0, 0, @@ -68,7 +68,7 @@ const X509V3_EXT_METHOD v3_crl_invdate = { NULL }; -const X509V3_EXT_METHOD v3_crl_hold = { +const X509V3_EXT_METHOD ossl_v3_crl_hold = { NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT), 0, 0, 0, 0, 0, 0, @@ -77,7 +77,7 @@ const X509V3_EXT_METHOD v3_crl_hold = { NULL }; -const X509V3_EXT_METHOD v3_ocsp_nonce = { +const X509V3_EXT_METHOD ossl_v3_ocsp_nonce = { NID_id_pkix_OCSP_Nonce, 0, NULL, ocsp_nonce_new, ocsp_nonce_free, @@ -89,7 +89,7 @@ const X509V3_EXT_METHOD v3_ocsp_nonce = { NULL }; -const X509V3_EXT_METHOD v3_ocsp_nocheck = { +const X509V3_EXT_METHOD ossl_v3_ocsp_nocheck = { NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL), 0, 0, 0, 0, 0, s2i_ocsp_nocheck, @@ -98,7 +98,7 @@ const X509V3_EXT_METHOD v3_ocsp_nocheck = { NULL }; -const X509V3_EXT_METHOD v3_ocsp_serviceloc = { +const X509V3_EXT_METHOD ossl_v3_ocsp_serviceloc = { NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC), 0, 0, 0, 0, 0, 0, @@ -170,9 +170,9 @@ static void *ocsp_nonce_new(void) return ASN1_OCTET_STRING_new(); } -static int i2d_ocsp_nonce(void *a, unsigned char **pp) +static int i2d_ocsp_nonce(const void *a, unsigned char **pp) { - ASN1_OCTET_STRING *os = a; + const ASN1_OCTET_STRING *os = a; if (pp) { memcpy(*pp, os->data, os->length); *pp += os->length; @@ -203,7 +203,7 @@ static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length) err: if ((pos == NULL) || (*pos != os)) ASN1_OCTET_STRING_free(os); - OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OCSP, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/openssl/ssl/packet.c b/crypto/openssl/crypto/packet.c similarity index 76% rename from crypto/openssl/ssl/packet.c rename to crypto/openssl/crypto/packet.c index d6357495f53e..927bb3f80f6c 100644 --- a/crypto/openssl/ssl/packet.c +++ b/crypto/openssl/crypto/packet.c @@ -1,15 +1,15 @@ /* * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include "internal/cryptlib.h" -#include "packet_local.h" -#include +#include "internal/packet.h" +#include #define DEFAULT_BUF_SIZE 256 @@ -35,7 +35,10 @@ int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len, } #define GETBUF(p) (((p)->staticbuf != NULL) \ - ? (p)->staticbuf : (unsigned char *)(p)->buf->data) + ? (p)->staticbuf \ + : ((p)->buf != NULL \ + ? (unsigned char *)(p)->buf->data \ + : NULL)) int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes) { @@ -46,7 +49,7 @@ int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes) if (pkt->maxsize - pkt->written < len) return 0; - if (pkt->staticbuf == NULL && (pkt->buf->length - pkt->written < len)) { + if (pkt->buf != NULL && (pkt->buf->length - pkt->written < len)) { size_t newlen; size_t reflen; @@ -62,8 +65,11 @@ int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes) if (BUF_MEM_grow(pkt->buf, newlen) == 0) return 0; } - if (allocbytes != NULL) + if (allocbytes != NULL) { *allocbytes = WPACKET_get_curr(pkt); + if (pkt->endfirst && *allocbytes != NULL) + *allocbytes -= len; + } return 1; } @@ -71,10 +77,14 @@ int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes) int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len, unsigned char **allocbytes, size_t lenbytes) { + if (pkt->endfirst && lenbytes > 0) + return 0; + if (!WPACKET_reserve_bytes(pkt, lenbytes + len, allocbytes)) return 0; - *allocbytes += lenbytes; + if (*allocbytes != NULL) + *allocbytes += lenbytes; return 1; } @@ -95,7 +105,7 @@ static int wpacket_intern_init_len(WPACKET *pkt, size_t lenbytes) pkt->written = 0; if ((pkt->subs = OPENSSL_zalloc(sizeof(*pkt->subs))) == NULL) { - SSLerr(SSL_F_WPACKET_INTERN_INIT_LEN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } @@ -110,7 +120,7 @@ static int wpacket_intern_init_len(WPACKET *pkt, size_t lenbytes) pkt->subs = NULL; return 0; } - pkt->subs->packet_len = lenchars - GETBUF(pkt); + pkt->subs->packet_len = 0; return 1; } @@ -127,10 +137,25 @@ int WPACKET_init_static_len(WPACKET *pkt, unsigned char *buf, size_t len, pkt->staticbuf = buf; pkt->buf = NULL; pkt->maxsize = (max < len) ? max : len; + pkt->endfirst = 0; return wpacket_intern_init_len(pkt, lenbytes); } +int WPACKET_init_der(WPACKET *pkt, unsigned char *buf, size_t len) +{ + /* Internal API, so should not fail */ + if (!ossl_assert(buf != NULL && len > 0)) + return 0; + + pkt->staticbuf = buf; + pkt->buf = NULL; + pkt->maxsize = len; + pkt->endfirst = 1; + + return wpacket_intern_init_len(pkt, 0); +} + int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes) { /* Internal API, so should not fail */ @@ -140,6 +165,7 @@ int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes) pkt->staticbuf = NULL; pkt->buf = buf; pkt->maxsize = maxmaxsize(lenbytes); + pkt->endfirst = 0; return wpacket_intern_init_len(pkt, lenbytes); } @@ -149,6 +175,26 @@ int WPACKET_init(WPACKET *pkt, BUF_MEM *buf) return WPACKET_init_len(pkt, buf, 0); } +int WPACKET_init_null(WPACKET *pkt, size_t lenbytes) +{ + pkt->staticbuf = NULL; + pkt->buf = NULL; + pkt->maxsize = maxmaxsize(lenbytes); + pkt->endfirst = 0; + + return wpacket_intern_init_len(pkt, 0); +} + +int WPACKET_init_null_der(WPACKET *pkt) +{ + pkt->staticbuf = NULL; + pkt->buf = NULL; + pkt->maxsize = SIZE_MAX; + pkt->endfirst = 1; + + return wpacket_intern_init_len(pkt, 0); +} + int WPACKET_set_flags(WPACKET *pkt, unsigned int flags) { /* Internal API, so should not fail */ @@ -163,6 +209,9 @@ int WPACKET_set_flags(WPACKET *pkt, unsigned int flags) /* Store the |value| of length |len| at location |data| */ static int put_value(unsigned char *data, uint64_t value, size_t len) { + if (data == NULL) + return 1; + for (data += len - 1; len > 0; len--) { *data = (unsigned char)(value & 0xff); data--; @@ -209,10 +258,30 @@ static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose) } /* Write out the WPACKET length if needed */ - if (sub->lenbytes > 0 - && !put_value(&GETBUF(pkt)[sub->packet_len], packlen, + if (sub->lenbytes > 0) { + unsigned char *buf = GETBUF(pkt); + + if (buf != NULL + && !put_value(&buf[sub->packet_len], packlen, sub->lenbytes)) return 0; + } else if (pkt->endfirst && sub->parent != NULL + && (packlen != 0 + || (sub->flags + & WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) == 0)) { + size_t tmplen = packlen; + size_t numlenbytes = 1; + + while ((tmplen = tmplen >> 8) > 0) + numlenbytes++; + if (!WPACKET_put_bytes__(pkt, packlen, numlenbytes)) + return 0; + if (packlen > 0x7f) { + numlenbytes |= 0x80; + if (!WPACKET_put_bytes_u8(pkt, numlenbytes)) + return 0; + } + } if (doclose) { pkt->subs = sub->parent; @@ -278,8 +347,12 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes) if (!ossl_assert(pkt->subs != NULL)) return 0; + /* We don't support lenbytes greater than 0 when doing endfirst writing */ + if (lenbytes > 0 && pkt->endfirst) + return 0; + if ((sub = OPENSSL_zalloc(sizeof(*sub))) == NULL) { - SSLerr(SSL_F_WPACKET_START_SUB_PACKET_LEN__, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } @@ -293,10 +366,10 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes) return 1; } + sub->packet_len = pkt->written; + if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) return 0; - /* Convert to an offset in case the underlying BUF_MEM gets realloc'd */ - sub->packet_len = lenchars - GETBUF(pkt); return 1; } @@ -354,7 +427,8 @@ int WPACKET_memset(WPACKET *pkt, int ch, size_t len) if (!WPACKET_allocate_bytes(pkt, len, &dest)) return 0; - memset(dest, ch, len); + if (dest != NULL) + memset(dest, ch, len); return 1; } @@ -369,7 +443,8 @@ int WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len) if (!WPACKET_allocate_bytes(pkt, len, &dest)) return 0; - memcpy(dest, src, len); + if (dest != NULL) + memcpy(dest, src, len); return 1; } @@ -409,7 +484,20 @@ int WPACKET_get_length(WPACKET *pkt, size_t *len) unsigned char *WPACKET_get_curr(WPACKET *pkt) { - return GETBUF(pkt) + pkt->curr; + unsigned char *buf = GETBUF(pkt); + + if (buf == NULL) + return NULL; + + if (pkt->endfirst) + return buf + pkt->maxsize - pkt->curr; + + return buf + pkt->curr; +} + +int WPACKET_is_null_buf(WPACKET *pkt) +{ + return pkt->buf == NULL && pkt->staticbuf == NULL; } void WPACKET_cleanup(WPACKET *pkt) diff --git a/crypto/openssl/crypto/param_build.c b/crypto/openssl/crypto/param_build.c new file mode 100644 index 000000000000..51c8681f3be5 --- /dev/null +++ b/crypto/openssl/crypto/param_build.c @@ -0,0 +1,389 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include "internal/param_build_set.h" + +/* + * Special internal param type to indicate the end of an allocate OSSL_PARAM + * array. + */ + +typedef struct { + const char *key; + int type; + int secure; + size_t size; + size_t alloc_blocks; + const BIGNUM *bn; + const void *string; + union { + /* + * These fields are never directly addressed, but their sizes are + * imporant so that all native types can be copied here without overrun. + */ + ossl_intmax_t i; + ossl_uintmax_t u; + double d; + } num; +} OSSL_PARAM_BLD_DEF; + +DEFINE_STACK_OF(OSSL_PARAM_BLD_DEF) + +struct ossl_param_bld_st { + size_t total_blocks; + size_t secure_blocks; + STACK_OF(OSSL_PARAM_BLD_DEF) *params; +}; + +static OSSL_PARAM_BLD_DEF *param_push(OSSL_PARAM_BLD *bld, const char *key, + int size, size_t alloc, int type, + int secure) +{ + OSSL_PARAM_BLD_DEF *pd = OPENSSL_zalloc(sizeof(*pd)); + + if (pd == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; + } + pd->key = key; + pd->type = type; + pd->size = size; + pd->alloc_blocks = ossl_param_bytes_to_blocks(alloc); + if ((pd->secure = secure) != 0) + bld->secure_blocks += pd->alloc_blocks; + else + bld->total_blocks += pd->alloc_blocks; + if (sk_OSSL_PARAM_BLD_DEF_push(bld->params, pd) <= 0) { + OPENSSL_free(pd); + pd = NULL; + } + return pd; +} + +static int param_push_num(OSSL_PARAM_BLD *bld, const char *key, + void *num, size_t size, int type) +{ + OSSL_PARAM_BLD_DEF *pd = param_push(bld, key, size, size, type, 0); + + if (pd == NULL) + return 0; + if (size > sizeof(pd->num)) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_BYTES); + return 0; + } + memcpy(&pd->num, num, size); + return 1; +} + +OSSL_PARAM_BLD *OSSL_PARAM_BLD_new(void) +{ + OSSL_PARAM_BLD *r = OPENSSL_zalloc(sizeof(OSSL_PARAM_BLD)); + + if (r != NULL) { + r->params = sk_OSSL_PARAM_BLD_DEF_new_null(); + if (r->params == NULL) { + OPENSSL_free(r); + r = NULL; + } + } + return r; +} + +static void free_all_params(OSSL_PARAM_BLD *bld) +{ + int i, n = sk_OSSL_PARAM_BLD_DEF_num(bld->params); + + for (i = 0; i < n; i++) + OPENSSL_free(sk_OSSL_PARAM_BLD_DEF_pop(bld->params)); +} + +void OSSL_PARAM_BLD_free(OSSL_PARAM_BLD *bld) +{ + if (bld == NULL) + return; + free_all_params(bld); + sk_OSSL_PARAM_BLD_DEF_free(bld->params); + OPENSSL_free(bld); +} + +int OSSL_PARAM_BLD_push_int(OSSL_PARAM_BLD *bld, const char *key, int num) +{ + return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER); +} + +int OSSL_PARAM_BLD_push_uint(OSSL_PARAM_BLD *bld, const char *key, + unsigned int num) +{ + return param_push_num(bld, key, &num, sizeof(num), + OSSL_PARAM_UNSIGNED_INTEGER); +} + +int OSSL_PARAM_BLD_push_long(OSSL_PARAM_BLD *bld, const char *key, + long int num) +{ + return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER); +} + +int OSSL_PARAM_BLD_push_ulong(OSSL_PARAM_BLD *bld, const char *key, + unsigned long int num) +{ + return param_push_num(bld, key, &num, sizeof(num), + OSSL_PARAM_UNSIGNED_INTEGER); +} + +int OSSL_PARAM_BLD_push_int32(OSSL_PARAM_BLD *bld, const char *key, + int32_t num) +{ + return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER); +} + +int OSSL_PARAM_BLD_push_uint32(OSSL_PARAM_BLD *bld, const char *key, + uint32_t num) +{ + return param_push_num(bld, key, &num, sizeof(num), + OSSL_PARAM_UNSIGNED_INTEGER); +} + +int OSSL_PARAM_BLD_push_int64(OSSL_PARAM_BLD *bld, const char *key, + int64_t num) +{ + return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER); +} + +int OSSL_PARAM_BLD_push_uint64(OSSL_PARAM_BLD *bld, const char *key, + uint64_t num) +{ + return param_push_num(bld, key, &num, sizeof(num), + OSSL_PARAM_UNSIGNED_INTEGER); +} + +int OSSL_PARAM_BLD_push_size_t(OSSL_PARAM_BLD *bld, const char *key, + size_t num) +{ + return param_push_num(bld, key, &num, sizeof(num), + OSSL_PARAM_UNSIGNED_INTEGER); +} + +int OSSL_PARAM_BLD_push_time_t(OSSL_PARAM_BLD *bld, const char *key, + time_t num) +{ + return param_push_num(bld, key, &num, sizeof(num), + OSSL_PARAM_INTEGER); +} + +int OSSL_PARAM_BLD_push_double(OSSL_PARAM_BLD *bld, const char *key, + double num) +{ + return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_REAL); +} + +int OSSL_PARAM_BLD_push_BN(OSSL_PARAM_BLD *bld, const char *key, + const BIGNUM *bn) +{ + return OSSL_PARAM_BLD_push_BN_pad(bld, key, bn, + bn == NULL ? 0 : BN_num_bytes(bn)); +} + +int OSSL_PARAM_BLD_push_BN_pad(OSSL_PARAM_BLD *bld, const char *key, + const BIGNUM *bn, size_t sz) +{ + int n, secure = 0; + OSSL_PARAM_BLD_DEF *pd; + + if (bn != NULL) { + if (BN_is_negative(bn)) { + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_UNSUPPORTED, + "Negative big numbers are unsupported for OSSL_PARAM"); + return 0; + } + + n = BN_num_bytes(bn); + if (n < 0) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_ZERO_LENGTH_NUMBER); + return 0; + } + if (sz < (size_t)n) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER); + return 0; + } + if (BN_get_flags(bn, BN_FLG_SECURE) == BN_FLG_SECURE) + secure = 1; + + /* The BIGNUM is zero, we must transfer at least one byte */ + if (sz == 0) + sz++; + } + pd = param_push(bld, key, sz, sz, OSSL_PARAM_UNSIGNED_INTEGER, secure); + if (pd == NULL) + return 0; + pd->bn = bn; + return 1; +} + +int OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key, + const char *buf, size_t bsize) +{ + OSSL_PARAM_BLD_DEF *pd; + int secure; + + if (bsize == 0) { + bsize = strlen(buf); + } else if (bsize > INT_MAX) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG); + return 0; + } + secure = CRYPTO_secure_allocated(buf); + pd = param_push(bld, key, bsize, bsize + 1, OSSL_PARAM_UTF8_STRING, secure); + if (pd == NULL) + return 0; + pd->string = buf; + return 1; +} + +int OSSL_PARAM_BLD_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key, + char *buf, size_t bsize) +{ + OSSL_PARAM_BLD_DEF *pd; + + if (bsize == 0) { + bsize = strlen(buf); + } else if (bsize > INT_MAX) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG); + return 0; + } + pd = param_push(bld, key, bsize, sizeof(buf), OSSL_PARAM_UTF8_PTR, 0); + if (pd == NULL) + return 0; + pd->string = buf; + return 1; +} + +int OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD *bld, const char *key, + const void *buf, size_t bsize) +{ + OSSL_PARAM_BLD_DEF *pd; + int secure; + + if (bsize > INT_MAX) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG); + return 0; + } + secure = CRYPTO_secure_allocated(buf); + pd = param_push(bld, key, bsize, bsize, OSSL_PARAM_OCTET_STRING, secure); + if (pd == NULL) + return 0; + pd->string = buf; + return 1; +} + +int OSSL_PARAM_BLD_push_octet_ptr(OSSL_PARAM_BLD *bld, const char *key, + void *buf, size_t bsize) +{ + OSSL_PARAM_BLD_DEF *pd; + + if (bsize > INT_MAX) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG); + return 0; + } + pd = param_push(bld, key, bsize, sizeof(buf), OSSL_PARAM_OCTET_PTR, 0); + if (pd == NULL) + return 0; + pd->string = buf; + return 1; +} + +static OSSL_PARAM *param_bld_convert(OSSL_PARAM_BLD *bld, OSSL_PARAM *param, + OSSL_PARAM_ALIGNED_BLOCK *blk, + OSSL_PARAM_ALIGNED_BLOCK *secure) +{ + int i, num = sk_OSSL_PARAM_BLD_DEF_num(bld->params); + OSSL_PARAM_BLD_DEF *pd; + void *p; + + for (i = 0; i < num; i++) { + pd = sk_OSSL_PARAM_BLD_DEF_value(bld->params, i); + param[i].key = pd->key; + param[i].data_type = pd->type; + param[i].data_size = pd->size; + param[i].return_size = OSSL_PARAM_UNMODIFIED; + + if (pd->secure) { + p = secure; + secure += pd->alloc_blocks; + } else { + p = blk; + blk += pd->alloc_blocks; + } + param[i].data = p; + if (pd->bn != NULL) { + /* BIGNUM */ + BN_bn2nativepad(pd->bn, (unsigned char *)p, pd->size); + } else if (pd->type == OSSL_PARAM_OCTET_PTR + || pd->type == OSSL_PARAM_UTF8_PTR) { + /* PTR */ + *(const void **)p = pd->string; + } else if (pd->type == OSSL_PARAM_OCTET_STRING + || pd->type == OSSL_PARAM_UTF8_STRING) { + if (pd->string != NULL) + memcpy(p, pd->string, pd->size); + else + memset(p, 0, pd->size); + if (pd->type == OSSL_PARAM_UTF8_STRING) + ((char *)p)[pd->size] = '\0'; + } else { + /* Number, but could also be a NULL BIGNUM */ + if (pd->size > sizeof(pd->num)) + memset(p, 0, pd->size); + else if (pd->size > 0) + memcpy(p, &pd->num, pd->size); + } + } + param[i] = OSSL_PARAM_construct_end(); + return param + i; +} + +OSSL_PARAM *OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD *bld) +{ + OSSL_PARAM_ALIGNED_BLOCK *blk, *s = NULL; + OSSL_PARAM *params, *last; + const int num = sk_OSSL_PARAM_BLD_DEF_num(bld->params); + const size_t p_blks = ossl_param_bytes_to_blocks((1 + num) * sizeof(*params)); + const size_t total = OSSL_PARAM_ALIGN_SIZE * (p_blks + bld->total_blocks); + const size_t ss = OSSL_PARAM_ALIGN_SIZE * bld->secure_blocks; + + if (ss > 0) { + s = OPENSSL_secure_malloc(ss); + if (s == NULL) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_SECURE_MALLOC_FAILURE); + return NULL; + } + } + params = OPENSSL_malloc(total); + if (params == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + OPENSSL_secure_free(s); + return NULL; + } + blk = p_blks + (OSSL_PARAM_ALIGNED_BLOCK *)(params); + last = param_bld_convert(bld, params, blk, s); + ossl_param_set_secure_block(last, s, ss); + + /* Reset builder for reuse */ + bld->total_blocks = 0; + bld->secure_blocks = 0; + free_all_params(bld); + return params; +} diff --git a/crypto/openssl/crypto/param_build_set.c b/crypto/openssl/crypto/param_build_set.c new file mode 100644 index 000000000000..8b570ded96eb --- /dev/null +++ b/crypto/openssl/crypto/param_build_set.c @@ -0,0 +1,121 @@ +/* + * Copyright 2020-2021 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 + */ + +/* + * Key Management utility functions to share functionality between the export() + * and get_params() methods. + * export() uses OSSL_PARAM_BLD, and get_params() used the OSSL_PARAM[] to + * fill in parameter data for the same key and data fields. + */ + +#include +#include "internal/param_build_set.h" + +DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) + +int ossl_param_build_set_int(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, + const char *key, int num) +{ + if (bld != NULL) + return OSSL_PARAM_BLD_push_int(bld, key, num); + p = OSSL_PARAM_locate(p, key); + if (p != NULL) + return OSSL_PARAM_set_int(p, num); + return 1; +} + +int ossl_param_build_set_long(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, + const char *key, long num) +{ + if (bld != NULL) + return OSSL_PARAM_BLD_push_long(bld, key, num); + p = OSSL_PARAM_locate(p, key); + if (p != NULL) + return OSSL_PARAM_set_long(p, num); + return 1; +} + +int ossl_param_build_set_utf8_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, + const char *key, const char *buf) +{ + if (bld != NULL) + return OSSL_PARAM_BLD_push_utf8_string(bld, key, buf, 0); + p = OSSL_PARAM_locate(p, key); + if (p != NULL) + return OSSL_PARAM_set_utf8_string(p, buf); + return 1; +} + +int ossl_param_build_set_octet_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, + const char *key, + const unsigned char *data, + size_t data_len) +{ + if (bld != NULL) + return OSSL_PARAM_BLD_push_octet_string(bld, key, data, data_len); + + p = OSSL_PARAM_locate(p, key); + if (p != NULL) + return OSSL_PARAM_set_octet_string(p, data, data_len); + return 1; +} + +int ossl_param_build_set_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, + const char *key, const BIGNUM *bn, size_t sz) +{ + if (bld != NULL) + return OSSL_PARAM_BLD_push_BN_pad(bld, key, bn, sz); + p = OSSL_PARAM_locate(p, key); + if (p != NULL) { + if (sz > p->data_size) + return 0; + p->data_size = sz; + return OSSL_PARAM_set_BN(p, bn); + } + return 1; +} + +int ossl_param_build_set_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, + const char *key, const BIGNUM *bn) +{ + if (bld != NULL) + return OSSL_PARAM_BLD_push_BN(bld, key, bn); + + p = OSSL_PARAM_locate(p, key); + if (p != NULL) + return OSSL_PARAM_set_BN(p, bn) > 0; + return 1; +} + +int ossl_param_build_set_multi_key_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *params, + const char *names[], + STACK_OF(BIGNUM_const) *stk) +{ + int i, sz = sk_BIGNUM_const_num(stk); + OSSL_PARAM *p; + + + if (bld != NULL) { + for (i = 0; i < sz && names[i] != NULL; ++i) { + if (!OSSL_PARAM_BLD_push_BN(bld, names[i], + sk_BIGNUM_const_value(stk, i))) + return 0; + } + return 1; + } + + for (i = 0; i < sz && names[i] != NULL; ++i) { + p = OSSL_PARAM_locate(params, names[i]); + if (p != NULL) { + if (!OSSL_PARAM_set_BN(p, sk_BIGNUM_const_value(stk, i))) + return 0; + } + } + return 1; +} diff --git a/crypto/openssl/crypto/params.c b/crypto/openssl/crypto/params.c new file mode 100644 index 000000000000..5fd1e0028da9 --- /dev/null +++ b/crypto/openssl/crypto/params.c @@ -0,0 +1,1299 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/thread_once.h" +#include "internal/numbers.h" +#include "internal/endian.h" + +/* + * Return the number of bits in the mantissa of a double. This is used to + * shift a larger integral value to determine if it will exactly fit into a + * double. + */ +static unsigned int real_shift(void) +{ + return sizeof(double) == 4 ? 24 : 53; +} + +OSSL_PARAM *OSSL_PARAM_locate(OSSL_PARAM *p, const char *key) +{ + if (p != NULL && key != NULL) + for (; p->key != NULL; p++) + if (strcmp(key, p->key) == 0) + return p; + return NULL; +} + +const OSSL_PARAM *OSSL_PARAM_locate_const(const OSSL_PARAM *p, const char *key) +{ + return OSSL_PARAM_locate((OSSL_PARAM *)p, key); +} + +static OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type, + void *data, size_t data_size) +{ + OSSL_PARAM res; + + res.key = key; + res.data_type = data_type; + res.data = data; + res.data_size = data_size; + res.return_size = OSSL_PARAM_UNMODIFIED; + return res; +} + +int OSSL_PARAM_modified(const OSSL_PARAM *p) +{ + return p != NULL && p->return_size != OSSL_PARAM_UNMODIFIED; +} + +void OSSL_PARAM_set_all_unmodified(OSSL_PARAM *p) +{ + if (p != NULL) + while (p->key != NULL) + p++->return_size = OSSL_PARAM_UNMODIFIED; +} + +/* Return non-zero if the signed number is negative */ +static int is_negative(const void *number, size_t s) +{ + const unsigned char *n = number; + DECLARE_IS_ENDIAN; + + return 0x80 & (IS_BIG_ENDIAN ? n[0] : n[s - 1]); +} + +/* Check that all the bytes specified match the expected sign byte */ +static int check_sign_bytes(const unsigned char *p, size_t n, unsigned char s) +{ + size_t i; + + for (i = 0; i < n; i++) + if (p[i] != s) + return 0; + return 1; +} + +/* + * Copy an integer to another integer. + * Handle different length integers and signed and unsigned integers. + * Both integers are in native byte ordering. + */ +static int copy_integer(unsigned char *dest, size_t dest_len, + const unsigned char *src, size_t src_len, + unsigned char pad, int signed_int) +{ + size_t n; + DECLARE_IS_ENDIAN; + + if (IS_BIG_ENDIAN) { + if (src_len < dest_len) { + n = dest_len - src_len; + memset(dest, pad, n); + memcpy(dest + n, src, src_len); + } else { + n = src_len - dest_len; + if (!check_sign_bytes(src, n, pad) + /* + * Shortening a signed value must retain the correct sign. + * Avoiding this kind of thing: -253 = 0xff03 -> 0x03 = 3 + */ + || (signed_int && ((pad ^ src[n]) & 0x80) != 0)) + return 0; + memcpy(dest, src + n, dest_len); + } + } else /* IS_LITTLE_ENDIAN */ { + if (src_len < dest_len) { + n = dest_len - src_len; + memset(dest + src_len, pad, n); + memcpy(dest, src, src_len); + } else { + n = src_len - dest_len; + if (!check_sign_bytes(src + dest_len, n, pad) + /* + * Shortening a signed value must retain the correct sign. + * Avoiding this kind of thing: 130 = 0x0082 -> 0x82 = -126 + */ + || (signed_int && ((pad ^ src[dest_len - 1]) & 0x80) != 0)) + return 0; + memcpy(dest, src, dest_len); + } + } + return 1; +} + +/* Copy a signed number to a signed number of possibly different length */ +static int signed_from_signed(void *dest, size_t dest_len, + const void *src, size_t src_len) +{ + return copy_integer(dest, dest_len, src, src_len, + is_negative(src, src_len) ? 0xff : 0, 1); +} + +/* Copy an unsigned number to a signed number of possibly different length */ +static int signed_from_unsigned(void *dest, size_t dest_len, + const void *src, size_t src_len) +{ + return copy_integer(dest, dest_len, src, src_len, 0, 1); +} + +/* Copy a signed number to an unsigned number of possibly different length */ +static int unsigned_from_signed(void *dest, size_t dest_len, + const void *src, size_t src_len) +{ + if (is_negative(src, src_len)) + return 0; + return copy_integer(dest, dest_len, src, src_len, 0, 0); +} + +/* Copy an unsigned number to an unsigned number of possibly different length */ +static int unsigned_from_unsigned(void *dest, size_t dest_len, + const void *src, size_t src_len) +{ + return copy_integer(dest, dest_len, src, src_len, 0, 0); +} + +/* General purpose get integer parameter call that handles odd sizes */ +static int general_get_int(const OSSL_PARAM *p, void *val, size_t val_size) +{ + if (p->data_type == OSSL_PARAM_INTEGER) + return signed_from_signed(val, val_size, p->data, p->data_size); + if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) + return signed_from_unsigned(val, val_size, p->data, p->data_size); + return 0; +} + +/* General purpose set integer parameter call that handles odd sizes */ +static int general_set_int(OSSL_PARAM *p, void *val, size_t val_size) +{ + int r = 0; + + p->return_size = val_size; /* Expected size */ + if (p->data == NULL) + return 1; + if (p->data_type == OSSL_PARAM_INTEGER) + r = signed_from_signed(p->data, p->data_size, val, val_size); + else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) + r = unsigned_from_signed(p->data, p->data_size, val, val_size); + p->return_size = r ? p->data_size : val_size; + return r; +} + +/* General purpose get unsigned integer parameter call that handles odd sizes */ +static int general_get_uint(const OSSL_PARAM *p, void *val, size_t val_size) +{ + if (p->data_type == OSSL_PARAM_INTEGER) + return unsigned_from_signed(val, val_size, p->data, p->data_size); + if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) + return unsigned_from_unsigned(val, val_size, p->data, p->data_size); + return 0; +} + +/* General purpose set unsigned integer parameter call that handles odd sizes */ +static int general_set_uint(OSSL_PARAM *p, void *val, size_t val_size) +{ + int r = 0; + + p->return_size = val_size; /* Expected size */ + if (p->data == NULL) + return 1; + if (p->data_type == OSSL_PARAM_INTEGER) + r = signed_from_unsigned(p->data, p->data_size, val, val_size); + else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) + r = unsigned_from_unsigned(p->data, p->data_size, val, val_size); + p->return_size = r ? p->data_size : val_size; + return r; +} + +int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(int)) { + case sizeof(int32_t): + return OSSL_PARAM_get_int32(p, (int32_t *)val); + case sizeof(int64_t): + return OSSL_PARAM_get_int64(p, (int64_t *)val); + } +#endif + return general_get_int(p, val, sizeof(*val)); +} + +int OSSL_PARAM_set_int(OSSL_PARAM *p, int val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(int)) { + case sizeof(int32_t): + return OSSL_PARAM_set_int32(p, (int32_t)val); + case sizeof(int64_t): + return OSSL_PARAM_set_int64(p, (int64_t)val); + } +#endif + return general_set_int(p, &val, sizeof(val)); +} + +OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf) +{ + return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int)); +} + +int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(unsigned int)) { + case sizeof(uint32_t): + return OSSL_PARAM_get_uint32(p, (uint32_t *)val); + case sizeof(uint64_t): + return OSSL_PARAM_get_uint64(p, (uint64_t *)val); + } +#endif + return general_get_uint(p, val, sizeof(*val)); +} + +int OSSL_PARAM_set_uint(OSSL_PARAM *p, unsigned int val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(unsigned int)) { + case sizeof(uint32_t): + return OSSL_PARAM_set_uint32(p, (uint32_t)val); + case sizeof(uint64_t): + return OSSL_PARAM_set_uint64(p, (uint64_t)val); + } +#endif + return general_set_uint(p, &val, sizeof(val)); +} + +OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf) +{ + return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, + sizeof(unsigned int)); +} + +int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(long int)) { + case sizeof(int32_t): + return OSSL_PARAM_get_int32(p, (int32_t *)val); + case sizeof(int64_t): + return OSSL_PARAM_get_int64(p, (int64_t *)val); + } +#endif + return general_get_int(p, val, sizeof(*val)); +} + +int OSSL_PARAM_set_long(OSSL_PARAM *p, long int val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(long int)) { + case sizeof(int32_t): + return OSSL_PARAM_set_int32(p, (int32_t)val); + case sizeof(int64_t): + return OSSL_PARAM_set_int64(p, (int64_t)val); + } +#endif + return general_set_int(p, &val, sizeof(val)); +} + +OSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf) +{ + return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(long int)); +} + +int OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(unsigned long int)) { + case sizeof(uint32_t): + return OSSL_PARAM_get_uint32(p, (uint32_t *)val); + case sizeof(uint64_t): + return OSSL_PARAM_get_uint64(p, (uint64_t *)val); + } +#endif + return general_get_uint(p, val, sizeof(*val)); +} + +int OSSL_PARAM_set_ulong(OSSL_PARAM *p, unsigned long int val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(unsigned long int)) { + case sizeof(uint32_t): + return OSSL_PARAM_set_uint32(p, (uint32_t)val); + case sizeof(uint64_t): + return OSSL_PARAM_set_uint64(p, (uint64_t)val); + } +#endif + return general_set_uint(p, &val, sizeof(val)); +} + +OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf) +{ + return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, + sizeof(unsigned long int)); +} + +int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val) +{ + double d; + + if (val == NULL || p == NULL ) + return 0; + + if (p->data_type == OSSL_PARAM_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + int64_t i64; + + switch (p->data_size) { + case sizeof(int32_t): + *val = *(const int32_t *)p->data; + return 1; + case sizeof(int64_t): + i64 = *(const int64_t *)p->data; + if (i64 >= INT32_MIN && i64 <= INT32_MAX) { + *val = (int32_t)i64; + return 1; + } + return 0; + } +#endif + return general_get_int(p, val, sizeof(*val)); + + } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + uint32_t u32; + uint64_t u64; + + switch (p->data_size) { + case sizeof(uint32_t): + u32 = *(const uint32_t *)p->data; + if (u32 <= INT32_MAX) { + *val = (int32_t)u32; + return 1; + } + return 0; + case sizeof(uint64_t): + u64 = *(const uint64_t *)p->data; + if (u64 <= INT32_MAX) { + *val = (int32_t)u64; + return 1; + } + return 0; + } +#endif + return general_get_int(p, val, sizeof(*val)); + + } else if (p->data_type == OSSL_PARAM_REAL) { + switch (p->data_size) { + case sizeof(double): + d = *(const double *)p->data; + if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) { + *val = (int32_t)d; + return 1; + } + break; + } + } + return 0; +} + +int OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val) +{ + if (p == NULL) + return 0; + p->return_size = 0; + if (p->data_type == OSSL_PARAM_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + p->return_size = sizeof(int32_t); /* Minimum expected size */ + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(int32_t): + *(int32_t *)p->data = val; + return 1; + case sizeof(int64_t): + p->return_size = sizeof(int64_t); + *(int64_t *)p->data = (int64_t)val; + return 1; + } +#endif + return general_set_int(p, &val, sizeof(val)); + } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) { +#ifndef OPENSSL_SMALL_FOOTPRINT + p->return_size = sizeof(uint32_t); /* Minimum expected size */ + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(uint32_t): + *(uint32_t *)p->data = (uint32_t)val; + return 1; + case sizeof(uint64_t): + p->return_size = sizeof(uint64_t); + *(uint64_t *)p->data = (uint64_t)val; + return 1; + } +#endif + return general_set_int(p, &val, sizeof(val)); + } else if (p->data_type == OSSL_PARAM_REAL) { + p->return_size = sizeof(double); + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(double): + *(double *)p->data = (double)val; + return 1; + } + } + return 0; +} + +OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf) +{ + return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, + sizeof(int32_t)); +} + +int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val) +{ + double d; + + if (val == NULL || p == NULL) + return 0; + + if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + uint64_t u64; + + switch (p->data_size) { + case sizeof(uint32_t): + *val = *(const uint32_t *)p->data; + return 1; + case sizeof(uint64_t): + u64 = *(const uint64_t *)p->data; + if (u64 <= UINT32_MAX) { + *val = (uint32_t)u64; + return 1; + } + return 0; + } +#endif + return general_get_uint(p, val, sizeof(*val)); + } else if (p->data_type == OSSL_PARAM_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + int32_t i32; + int64_t i64; + + switch (p->data_size) { + case sizeof(int32_t): + i32 = *(const int32_t *)p->data; + if (i32 >= 0) { + *val = i32; + return 1; + } + return 0; + case sizeof(int64_t): + i64 = *(const int64_t *)p->data; + if (i64 >= 0 && i64 <= UINT32_MAX) { + *val = (uint32_t)i64; + return 1; + } + return 0; + } +#endif + return general_get_uint(p, val, sizeof(*val)); + } else if (p->data_type == OSSL_PARAM_REAL) { + switch (p->data_size) { + case sizeof(double): + d = *(const double *)p->data; + if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) { + *val = (uint32_t)d; + return 1; + } + break; + } + } + return 0; +} + +int OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val) +{ + if (p == NULL) + return 0; + p->return_size = 0; + + if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + p->return_size = sizeof(uint32_t); /* Minimum expected size */ + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(uint32_t): + *(uint32_t *)p->data = val; + return 1; + case sizeof(uint64_t): + p->return_size = sizeof(uint64_t); + *(uint64_t *)p->data = val; + return 1; + } +#endif + return general_set_uint(p, &val, sizeof(val)); + } else if (p->data_type == OSSL_PARAM_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + p->return_size = sizeof(int32_t); /* Minimum expected size */ + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(int32_t): + if (val <= INT32_MAX) { + *(int32_t *)p->data = (int32_t)val; + return 1; + } + return 0; + case sizeof(int64_t): + p->return_size = sizeof(int64_t); + *(int64_t *)p->data = (int64_t)val; + return 1; + } +#endif + return general_set_uint(p, &val, sizeof(val)); + } else if (p->data_type == OSSL_PARAM_REAL) { + p->return_size = sizeof(double); + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(double): + *(double *)p->data = (double)val; + return 1; + } + } + return 0; +} + +OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf) +{ + return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, + sizeof(uint32_t)); +} + +int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val) +{ + double d; + + if (val == NULL || p == NULL ) + return 0; + + if (p->data_type == OSSL_PARAM_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (p->data_size) { + case sizeof(int32_t): + *val = *(const int32_t *)p->data; + return 1; + case sizeof(int64_t): + *val = *(const int64_t *)p->data; + return 1; + } +#endif + return general_get_int(p, val, sizeof(*val)); + } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + uint64_t u64; + + switch (p->data_size) { + case sizeof(uint32_t): + *val = *(const uint32_t *)p->data; + return 1; + case sizeof(uint64_t): + u64 = *(const uint64_t *)p->data; + if (u64 <= INT64_MAX) { + *val = (int64_t)u64; + return 1; + } + return 0; + } +#endif + return general_get_int(p, val, sizeof(*val)); + } else if (p->data_type == OSSL_PARAM_REAL) { + switch (p->data_size) { + case sizeof(double): + d = *(const double *)p->data; + if (d >= INT64_MIN + /* + * By subtracting 65535 (2^16-1) we cancel the low order + * 15 bits of INT64_MAX to avoid using imprecise floating + * point values. + */ + && d < (double)(INT64_MAX - 65535) + 65536.0 + && d == (int64_t)d) { + *val = (int64_t)d; + return 1; + } + break; + } + } + return 0; +} + +int OSSL_PARAM_set_int64(OSSL_PARAM *p, int64_t val) +{ + uint64_t u64; + + if (p == NULL) + return 0; + p->return_size = 0; + if (p->data_type == OSSL_PARAM_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + p->return_size = sizeof(int64_t); /* Expected size */ + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(int32_t): + if (val >= INT32_MIN && val <= INT32_MAX) { + p->return_size = sizeof(int32_t); + *(int32_t *)p->data = (int32_t)val; + return 1; + } + return 0; + case sizeof(int64_t): + *(int64_t *)p->data = val; + return 1; + } +#endif + return general_set_int(p, &val, sizeof(val)); + } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) { +#ifndef OPENSSL_SMALL_FOOTPRINT + p->return_size = sizeof(uint64_t); /* Expected size */ + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(uint32_t): + if (val <= UINT32_MAX) { + p->return_size = sizeof(uint32_t); + *(uint32_t *)p->data = (uint32_t)val; + return 1; + } + return 0; + case sizeof(uint64_t): + *(uint64_t *)p->data = (uint64_t)val; + return 1; + } +#endif + return general_set_int(p, &val, sizeof(val)); + } else if (p->data_type == OSSL_PARAM_REAL) { + p->return_size = sizeof(double); + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(double): + u64 = val < 0 ? -val : val; + if ((u64 >> real_shift()) == 0) { + *(double *)p->data = (double)val; + return 1; + } + break; + } + } + return 0; +} + +OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf) +{ + return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t)); +} + +int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val) +{ + double d; + + if (val == NULL || p == NULL) + return 0; + + if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (p->data_size) { + case sizeof(uint32_t): + *val = *(const uint32_t *)p->data; + return 1; + case sizeof(uint64_t): + *val = *(const uint64_t *)p->data; + return 1; + } +#endif + return general_get_uint(p, val, sizeof(*val)); + } else if (p->data_type == OSSL_PARAM_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + int32_t i32; + int64_t i64; + + switch (p->data_size) { + case sizeof(int32_t): + i32 = *(const int32_t *)p->data; + if (i32 >= 0) { + *val = (uint64_t)i32; + return 1; + } + return 0; + case sizeof(int64_t): + i64 = *(const int64_t *)p->data; + if (i64 >= 0) { + *val = (uint64_t)i64; + return 1; + } + return 0; + } +#endif + return general_get_uint(p, val, sizeof(*val)); + } else if (p->data_type == OSSL_PARAM_REAL) { + switch (p->data_size) { + case sizeof(double): + d = *(const double *)p->data; + if (d >= 0 + /* + * By subtracting 65535 (2^16-1) we cancel the low order + * 15 bits of UINT64_MAX to avoid using imprecise floating + * point values. + */ + && d < (double)(UINT64_MAX - 65535) + 65536.0 + && d == (uint64_t)d) { + *val = (uint64_t)d; + return 1; + } + break; + } + } + return 0; +} + +int OSSL_PARAM_set_uint64(OSSL_PARAM *p, uint64_t val) +{ + if (p == NULL) + return 0; + p->return_size = 0; + + if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + p->return_size = sizeof(uint64_t); /* Expected size */ + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(uint32_t): + if (val <= UINT32_MAX) { + p->return_size = sizeof(uint32_t); + *(uint32_t *)p->data = (uint32_t)val; + return 1; + } + return 0; + case sizeof(uint64_t): + *(uint64_t *)p->data = val; + return 1; + } +#endif + return general_set_uint(p, &val, sizeof(val)); + } else if (p->data_type == OSSL_PARAM_INTEGER) { +#ifndef OPENSSL_SMALL_FOOTPRINT + p->return_size = sizeof(int64_t); /* Expected size */ + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(int32_t): + if (val <= INT32_MAX) { + p->return_size = sizeof(int32_t); + *(int32_t *)p->data = (int32_t)val; + return 1; + } + return 0; + case sizeof(int64_t): + if (val <= INT64_MAX) { + *(int64_t *)p->data = (int64_t)val; + return 1; + } + return 0; + } +#endif + return general_set_uint(p, &val, sizeof(val)); + } else if (p->data_type == OSSL_PARAM_REAL) { + p->return_size = sizeof(double); + switch (p->data_size) { + case sizeof(double): + if ((val >> real_shift()) == 0) { + *(double *)p->data = (double)val; + return 1; + } + break; + } + } + return 0; +} + +OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf) +{ + return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, + sizeof(uint64_t)); +} + +int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(size_t)) { + case sizeof(uint32_t): + return OSSL_PARAM_get_uint32(p, (uint32_t *)val); + case sizeof(uint64_t): + return OSSL_PARAM_get_uint64(p, (uint64_t *)val); + } +#endif + return general_get_uint(p, val, sizeof(*val)); +} + +int OSSL_PARAM_set_size_t(OSSL_PARAM *p, size_t val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(size_t)) { + case sizeof(uint32_t): + return OSSL_PARAM_set_uint32(p, (uint32_t)val); + case sizeof(uint64_t): + return OSSL_PARAM_set_uint64(p, (uint64_t)val); + } +#endif + return general_set_uint(p, &val, sizeof(val)); +} + +OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf) +{ + return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, + sizeof(size_t)); +} + +int OSSL_PARAM_get_time_t(const OSSL_PARAM *p, time_t *val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(time_t)) { + case sizeof(int32_t): + return OSSL_PARAM_get_int32(p, (int32_t *)val); + case sizeof(int64_t): + return OSSL_PARAM_get_int64(p, (int64_t *)val); + } +#endif + return general_get_int(p, val, sizeof(*val)); +} + +int OSSL_PARAM_set_time_t(OSSL_PARAM *p, time_t val) +{ +#ifndef OPENSSL_SMALL_FOOTPRINT + switch (sizeof(time_t)) { + case sizeof(int32_t): + return OSSL_PARAM_set_int32(p, (int32_t)val); + case sizeof(int64_t): + return OSSL_PARAM_set_int64(p, (int64_t)val); + } +#endif + return general_set_int(p, &val, sizeof(val)); +} + +OSSL_PARAM OSSL_PARAM_construct_time_t(const char *key, time_t *buf) +{ + return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(time_t)); +} + +int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val) +{ + BIGNUM *b; + + if (val == NULL + || p == NULL + || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER) + return 0; + + b = BN_native2bn(p->data, (int)p->data_size, *val); + if (b != NULL) { + *val = b; + return 1; + } + return 0; +} + +int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val) +{ + size_t bytes; + + if (p == NULL) + return 0; + p->return_size = 0; + if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER) + return 0; + + /* For the moment, only positive values are permitted */ + if (BN_is_negative(val)) + return 0; + + bytes = (size_t)BN_num_bytes(val); + /* We make sure that at least one byte is used, so zero is properly set */ + if (bytes == 0) + bytes++; + + p->return_size = bytes; + if (p->data == NULL) + return 1; + if (p->data_size >= bytes) { + p->return_size = p->data_size; + return BN_bn2nativepad(val, p->data, p->data_size) >= 0; + } + return 0; +} + +OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf, + size_t bsize) +{ + return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, + buf, bsize); +} + +int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val) +{ + int64_t i64; + uint64_t u64; + + if (val == NULL || p == NULL) + return 0; + + if (p->data_type == OSSL_PARAM_REAL) { + switch (p->data_size) { + case sizeof(double): + *val = *(const double *)p->data; + return 1; + } + } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { + switch (p->data_size) { + case sizeof(uint32_t): + *val = *(const uint32_t *)p->data; + return 1; + case sizeof(uint64_t): + u64 = *(const uint64_t *)p->data; + if ((u64 >> real_shift()) == 0) { + *val = (double)u64; + return 1; + } + break; + } + } else if (p->data_type == OSSL_PARAM_INTEGER) { + switch (p->data_size) { + case sizeof(int32_t): + *val = *(const int32_t *)p->data; + return 1; + case sizeof(int64_t): + i64 = *(const int64_t *)p->data; + u64 = i64 < 0 ? -i64 : i64; + if ((u64 >> real_shift()) == 0) { + *val = 0.0 + i64; + return 1; + } + break; + } + } + return 0; +} + +int OSSL_PARAM_set_double(OSSL_PARAM *p, double val) +{ + if (p == NULL) + return 0; + p->return_size = 0; + + if (p->data_type == OSSL_PARAM_REAL) { + p->return_size = sizeof(double); + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(double): + *(double *)p->data = val; + return 1; + } + } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER + && val == (uint64_t)val) { + p->return_size = sizeof(double); + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(uint32_t): + if (val >= 0 && val <= UINT32_MAX) { + p->return_size = sizeof(uint32_t); + *(uint32_t *)p->data = (uint32_t)val; + return 1; + } + break; + case sizeof(uint64_t): + if (val >= 0 + /* + * By subtracting 65535 (2^16-1) we cancel the low order + * 15 bits of UINT64_MAX to avoid using imprecise floating + * point values. + */ + && val < (double)(UINT64_MAX - 65535) + 65536.0) { + p->return_size = sizeof(uint64_t); + *(uint64_t *)p->data = (uint64_t)val; + return 1; + } + break; } + } else if (p->data_type == OSSL_PARAM_INTEGER && val == (int64_t)val) { + p->return_size = sizeof(double); + if (p->data == NULL) + return 1; + switch (p->data_size) { + case sizeof(int32_t): + if (val >= INT32_MIN && val <= INT32_MAX) { + p->return_size = sizeof(int32_t); + *(int32_t *)p->data = (int32_t)val; + return 1; + } + break; + case sizeof(int64_t): + if (val >= INT64_MIN + /* + * By subtracting 65535 (2^16-1) we cancel the low order + * 15 bits of INT64_MAX to avoid using imprecise floating + * point values. + */ + && val < (double)(INT64_MAX - 65535) + 65536.0) { + p->return_size = sizeof(int64_t); + *(int64_t *)p->data = (int64_t)val; + return 1; + } + break; + } + } + return 0; +} + +OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf) +{ + return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double)); +} + +static int get_string_internal(const OSSL_PARAM *p, void **val, + size_t *max_len, size_t *used_len, + unsigned int type) +{ + size_t sz, alloc_sz; + + if ((val == NULL && used_len == NULL) || p == NULL || p->data_type != type) + return 0; + + sz = p->data_size; + /* + * If the input size is 0, or the input string needs NUL byte + * termination, allocate an extra byte. + */ + alloc_sz = sz + (type == OSSL_PARAM_UTF8_STRING || sz == 0); + + if (used_len != NULL) + *used_len = sz; + + if (p->data == NULL) + return 0; + + if (val == NULL) + return 1; + + if (*val == NULL) { + char *const q = OPENSSL_malloc(alloc_sz); + + if (q == NULL) + return 0; + *val = q; + *max_len = alloc_sz; + } + + if (*max_len < sz) + return 0; + memcpy(*val, p->data, sz); + return 1; +} + +int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len) +{ + int ret = get_string_internal(p, (void **)val, &max_len, NULL, + OSSL_PARAM_UTF8_STRING); + + /* + * We try to ensure that the copied string is terminated with a + * NUL byte. That should be easy, just place a NUL byte at + * |((char*)*val)[p->data_size]|. + * Unfortunately, we have seen cases where |p->data_size| doesn't + * correctly reflect the length of the string, and just happens + * to be out of bounds according to |max_len|, so in that case, we + * make the extra step of trying to find the true length of the + * string that |p->data| points at, and use that as an index to + * place the NUL byte in |*val|. + */ + size_t data_length = p->data_size; + + if (ret == 0) + return 0; + if (data_length >= max_len) + data_length = OPENSSL_strnlen(p->data, data_length); + if (data_length >= max_len) + return 0; /* No space for a terminating NUL byte */ + (*val)[data_length] = '\0'; + + return ret; +} + +int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len, + size_t *used_len) +{ + return get_string_internal(p, val, &max_len, used_len, + OSSL_PARAM_OCTET_STRING); +} + +static int set_string_internal(OSSL_PARAM *p, const void *val, size_t len, + unsigned int type) +{ + p->return_size = len; + if (p->data == NULL) + return 1; + if (p->data_type != type || p->data_size < len) + return 0; + + memcpy(p->data, val, len); + /* If possible within the size of p->data, add a NUL terminator byte */ + if (type == OSSL_PARAM_UTF8_STRING && p->data_size > len) + ((char *)p->data)[len] = '\0'; + return 1; +} + +int OSSL_PARAM_set_utf8_string(OSSL_PARAM *p, const char *val) +{ + if (p == NULL) + return 0; + + p->return_size = 0; + if (val == NULL) + return 0; + return set_string_internal(p, val, strlen(val), OSSL_PARAM_UTF8_STRING); +} + +int OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val, + size_t len) +{ + if (p == NULL) + return 0; + + p->return_size = 0; + if (val == NULL) + return 0; + return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING); +} + +OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf, + size_t bsize) +{ + if (buf != NULL && bsize == 0) + bsize = strlen(buf); + return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize); +} + +OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf, + size_t bsize) +{ + return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize); +} + +static int get_ptr_internal(const OSSL_PARAM *p, const void **val, + size_t *used_len, unsigned int type) +{ + if (val == NULL || p == NULL || p->data_type != type) + return 0; + if (used_len != NULL) + *used_len = p->data_size; + *val = *(const void **)p->data; + return 1; +} + +int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val) +{ + return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR); +} + +int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val, + size_t *used_len) +{ + return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR); +} + +static int set_ptr_internal(OSSL_PARAM *p, const void *val, + unsigned int type, size_t len) +{ + p->return_size = len; + if (p->data_type != type) + return 0; + if (p->data != NULL) + *(const void **)p->data = val; + return 1; +} + +int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val) +{ + if (p == NULL) + return 0; + p->return_size = 0; + return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR, + val == NULL ? 0 : strlen(val)); +} + +int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val, + size_t used_len) +{ + if (p == NULL) + return 0; + p->return_size = 0; + return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len); +} + +OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf, + size_t bsize) +{ + return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, bsize); +} + +OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf, + size_t bsize) +{ + return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize); +} + +OSSL_PARAM OSSL_PARAM_construct_end(void) +{ + OSSL_PARAM end = OSSL_PARAM_END; + + return end; +} + +static int get_string_ptr_internal(const OSSL_PARAM *p, const void **val, + size_t *used_len, unsigned int type) +{ + if (val == NULL || p == NULL || p->data_type != type) + return 0; + if (used_len != NULL) + *used_len = p->data_size; + *val = p->data; + return 1; +} + +int OSSL_PARAM_get_utf8_string_ptr(const OSSL_PARAM *p, const char **val) +{ + return OSSL_PARAM_get_utf8_ptr(p, val) + || get_string_ptr_internal(p, (const void **)val, NULL, + OSSL_PARAM_UTF8_STRING); +} + +int OSSL_PARAM_get_octet_string_ptr(const OSSL_PARAM *p, const void **val, + size_t *used_len) +{ + return OSSL_PARAM_get_octet_ptr(p, val, used_len) + || get_string_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_STRING); +} diff --git a/crypto/openssl/crypto/params_dup.c b/crypto/openssl/crypto/params_dup.c new file mode 100644 index 000000000000..bc1546fc53cb --- /dev/null +++ b/crypto/openssl/crypto/params_dup.c @@ -0,0 +1,235 @@ +/* + * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "internal/param_build_set.h" + +#define OSSL_PARAM_ALLOCATED_END 127 +#define OSSL_PARAM_MERGE_LIST_MAX 128 + +#define OSSL_PARAM_BUF_PUBLIC 0 +#define OSSL_PARAM_BUF_SECURE 1 +#define OSSL_PARAM_BUF_MAX (OSSL_PARAM_BUF_SECURE + 1) + +typedef struct { + OSSL_PARAM_ALIGNED_BLOCK *alloc; /* The allocated buffer */ + OSSL_PARAM_ALIGNED_BLOCK *cur; /* Current position in the allocated buf */ + size_t blocks; /* Number of aligned blocks */ + size_t alloc_sz; /* The size of the allocated buffer (in bytes) */ +} OSSL_PARAM_BUF; + +size_t ossl_param_bytes_to_blocks(size_t bytes) +{ + return (bytes + OSSL_PARAM_ALIGN_SIZE - 1) / OSSL_PARAM_ALIGN_SIZE; +} + +static int ossl_param_buf_alloc(OSSL_PARAM_BUF *out, size_t extra_blocks, + int is_secure) +{ + size_t sz = OSSL_PARAM_ALIGN_SIZE * (extra_blocks + out->blocks); + + out->alloc = is_secure ? OPENSSL_secure_zalloc(sz) : OPENSSL_zalloc(sz); + if (out->alloc == NULL) { + ERR_raise(ERR_LIB_CRYPTO, is_secure ? CRYPTO_R_SECURE_MALLOC_FAILURE + : ERR_R_MALLOC_FAILURE); + return 0; + } + out->alloc_sz = sz; + out->cur = out->alloc + extra_blocks; + return 1; +} + +void ossl_param_set_secure_block(OSSL_PARAM *last, void *secure_buffer, + size_t secure_buffer_sz) +{ + last->key = NULL; + last->data_size = secure_buffer_sz; + last->data = secure_buffer; + last->data_type = OSSL_PARAM_ALLOCATED_END; +} + +static OSSL_PARAM *ossl_param_dup(const OSSL_PARAM *src, OSSL_PARAM *dst, + OSSL_PARAM_BUF buf[OSSL_PARAM_BUF_MAX], + int *param_count) +{ + const OSSL_PARAM *in; + int has_dst = (dst != NULL); + int is_secure; + size_t param_sz, blks; + + for (in = src; in->key != NULL; in++) { + is_secure = CRYPTO_secure_allocated(in->data); + if (has_dst) { + *dst = *in; + dst->data = buf[is_secure].cur; + } + + if (in->data_type == OSSL_PARAM_OCTET_PTR + || in->data_type == OSSL_PARAM_UTF8_PTR) { + param_sz = sizeof(in->data); + if (has_dst) + *((const void **)dst->data) = *(const void **)in->data; + } else { + param_sz = in->data_size; + if (has_dst) + memcpy(dst->data, in->data, param_sz); + } + if (in->data_type == OSSL_PARAM_UTF8_STRING) + param_sz++; /* NULL terminator */ + blks = ossl_param_bytes_to_blocks(param_sz); + + if (has_dst) { + dst++; + buf[is_secure].cur += blks; + } else { + buf[is_secure].blocks += blks; + } + if (param_count != NULL) + ++*param_count; + } + return dst; +} + +OSSL_PARAM *OSSL_PARAM_dup(const OSSL_PARAM *src) +{ + size_t param_blocks; + OSSL_PARAM_BUF buf[OSSL_PARAM_BUF_MAX]; + OSSL_PARAM *last, *dst; + int param_count = 1; /* Include terminator in the count */ + + if (src == NULL) + return NULL; + + memset(buf, 0, sizeof(buf)); + + /* First Pass: get the param_count and block sizes required */ + (void)ossl_param_dup(src, NULL, buf, ¶m_count); + + param_blocks = ossl_param_bytes_to_blocks(param_count * sizeof(*src)); + /* + * The allocated buffer consists of an array of OSSL_PARAM followed by + * aligned data bytes that the array elements will point to. + */ + if (!ossl_param_buf_alloc(&buf[OSSL_PARAM_BUF_PUBLIC], param_blocks, 0)) + return NULL; + + /* Allocate a secure memory buffer if required */ + if (buf[OSSL_PARAM_BUF_SECURE].blocks > 0 + && !ossl_param_buf_alloc(&buf[OSSL_PARAM_BUF_SECURE], 0, 1)) { + OPENSSL_free(buf[OSSL_PARAM_BUF_PUBLIC].alloc); + return NULL; + } + + dst = (OSSL_PARAM *)buf[OSSL_PARAM_BUF_PUBLIC].alloc; + last = ossl_param_dup(src, dst, buf, NULL); + /* Store the allocated secure memory buffer in the last param block */ + ossl_param_set_secure_block(last, buf[OSSL_PARAM_BUF_SECURE].alloc, + buf[OSSL_PARAM_BUF_SECURE].alloc_sz); + return dst; +} + +static int compare_params(const void *left, const void *right) +{ + const OSSL_PARAM *l = *(const OSSL_PARAM **)left; + const OSSL_PARAM *r = *(const OSSL_PARAM **)right; + + return OPENSSL_strcasecmp(l->key, r->key); +} + +OSSL_PARAM *OSSL_PARAM_merge(const OSSL_PARAM *p1, const OSSL_PARAM *p2) +{ + const OSSL_PARAM *list1[OSSL_PARAM_MERGE_LIST_MAX + 1]; + const OSSL_PARAM *list2[OSSL_PARAM_MERGE_LIST_MAX + 1]; + const OSSL_PARAM *p = NULL; + const OSSL_PARAM **p1cur, **p2cur; + OSSL_PARAM *params, *dst; + size_t list1_sz = 0, list2_sz = 0; + int diff; + + if (p1 == NULL && p2 == NULL) + return NULL; + + /* Copy p1 to list1 */ + if (p1 != NULL) { + for (p = p1; p->key != NULL && list1_sz < OSSL_PARAM_MERGE_LIST_MAX; p++) + list1[list1_sz++] = p; + } + list1[list1_sz] = NULL; + + /* copy p2 to a list2 */ + if (p2 != NULL) { + for (p = p2; p->key != NULL && list2_sz < OSSL_PARAM_MERGE_LIST_MAX; p++) + list2[list2_sz++] = p; + } + list2[list2_sz] = NULL; + if (list1_sz == 0 && list2_sz == 0) + return NULL; + + /* Sort the 2 lists */ + qsort(list1, list1_sz, sizeof(OSSL_PARAM *), compare_params); + qsort(list2, list2_sz, sizeof(OSSL_PARAM *), compare_params); + + /* Allocate enough space to store the merged parameters */ + params = OPENSSL_zalloc((list1_sz + list2_sz + 1) * sizeof(*p1)); + if (params == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; + } + dst = params; + p1cur = list1; + p2cur = list2; + while (1) { + /* If list1 is finished just tack list2 onto the end */ + if (*p1cur == NULL) { + do { + *dst++ = **p2cur; + p2cur++; + } while (*p2cur != NULL); + break; + } + /* If list2 is finished just tack list1 onto the end */ + if (*p2cur == NULL) { + do { + *dst++ = **p1cur; + p1cur++; + } while (*p1cur != NULL); + break; + } + /* consume the list element with the smaller key */ + diff = OPENSSL_strcasecmp((*p1cur)->key, (*p2cur)->key); + if (diff == 0) { + /* If the keys are the same then throw away the list1 element */ + *dst++ = **p2cur; + p2cur++; + p1cur++; + } else if (diff > 0) { + *dst++ = **p2cur; + p2cur++; + } else { + *dst++ = **p1cur; + p1cur++; + } + } + return params; +} + +void OSSL_PARAM_free(OSSL_PARAM *params) +{ + if (params != NULL) { + OSSL_PARAM *p; + + for (p = params; p->key != NULL; p++) + ; + if (p->data_type == OSSL_PARAM_ALLOCATED_END) + OPENSSL_secure_clear_free(p->data, p->data_size); + OPENSSL_free(params); + } +} diff --git a/crypto/openssl/crypto/params_from_text.c b/crypto/openssl/crypto/params_from_text.c new file mode 100644 index 000000000000..360f8933e135 --- /dev/null +++ b/crypto/openssl/crypto/params_from_text.c @@ -0,0 +1,230 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include + +/* + * When processing text to params, we're trying to be smart with numbers. + * Instead of handling each specific separate integer type, we use a bignum + * and ensure that it isn't larger than the expected size, and we then make + * sure it is the expected size... if there is one given. + * (if the size can be arbitrary, then we give whatever we have) + */ + +static int prepare_from_text(const OSSL_PARAM *paramdefs, const char *key, + const char *value, size_t value_n, + /* Output parameters */ + const OSSL_PARAM **paramdef, int *ishex, + size_t *buf_n, BIGNUM **tmpbn, int *found) +{ + const OSSL_PARAM *p; + size_t buf_bits; + int r; + + /* + * ishex is used to translate legacy style string controls in hex format + * to octet string parameters. + */ + *ishex = strncmp(key, "hex", 3) == 0; + + if (*ishex) + key += 3; + + p = *paramdef = OSSL_PARAM_locate_const(paramdefs, key); + if (found != NULL) + *found = p != NULL; + if (p == NULL) + return 0; + + switch (p->data_type) { + case OSSL_PARAM_INTEGER: + case OSSL_PARAM_UNSIGNED_INTEGER: + if (*ishex) + r = BN_hex2bn(tmpbn, value); + else + r = BN_asc2bn(tmpbn, value); + + if (r == 0 || *tmpbn == NULL) + return 0; + + if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER + && BN_is_negative(*tmpbn)) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_INVALID_NEGATIVE_VALUE); + return 0; + } + + /* + * 2's complement negate, part 1 + * + * BN_bn2nativepad puts the absolute value of the number in the + * buffer, i.e. if it's negative, we need to deal with it. We do + * it by subtracting 1 here and inverting the bytes in + * construct_from_text() below. + * To subtract 1 from an absolute value of a negative number we + * actually have to add 1: -3 - 1 = -4, |-3| = 3 + 1 = 4. + */ + if (p->data_type == OSSL_PARAM_INTEGER && BN_is_negative(*tmpbn) + && !BN_add_word(*tmpbn, 1)) { + return 0; + } + + buf_bits = (size_t)BN_num_bits(*tmpbn); + + /* + * Compensate for cases where the most significant bit in + * the resulting OSSL_PARAM buffer will be set after the + * BN_bn2nativepad() call, as the implied sign may not be + * correct after the second part of the 2's complement + * negation has been performed. + * We fix these cases by extending the buffer by one byte + * (8 bits), which will give some padding. The second part + * of the 2's complement negation will do the rest. + */ + if (p->data_type == OSSL_PARAM_INTEGER && buf_bits % 8 == 0) + buf_bits += 8; + + *buf_n = (buf_bits + 7) / 8; + + /* + * A zero data size means "arbitrary size", so only do the + * range checking if a size is specified. + */ + if (p->data_size > 0) { + if (buf_bits > p->data_size * 8) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER); + /* Since this is a different error, we don't break */ + return 0; + } + /* Change actual size to become the desired size. */ + *buf_n = p->data_size; + } + break; + case OSSL_PARAM_UTF8_STRING: + if (*ishex) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + *buf_n = strlen(value) + 1; + break; + case OSSL_PARAM_OCTET_STRING: + if (*ishex) { + *buf_n = strlen(value) >> 1; + } else { + *buf_n = value_n; + } + break; + } + + return 1; +} + +static int construct_from_text(OSSL_PARAM *to, const OSSL_PARAM *paramdef, + const char *value, size_t value_n, int ishex, + void *buf, size_t buf_n, BIGNUM *tmpbn) +{ + if (buf == NULL) + return 0; + + if (buf_n > 0) { + switch (paramdef->data_type) { + case OSSL_PARAM_INTEGER: + case OSSL_PARAM_UNSIGNED_INTEGER: + /* + { + if ((new_value = OPENSSL_malloc(new_value_n)) == NULL) { + BN_free(a); + break; + } + */ + + BN_bn2nativepad(tmpbn, buf, buf_n); + + /* + * 2's complement negation, part two. + * + * Because we did the first part on the BIGNUM itself, we can just + * invert all the bytes here and be done with it. + */ + if (paramdef->data_type == OSSL_PARAM_INTEGER + && BN_is_negative(tmpbn)) { + unsigned char *cp; + size_t i = buf_n; + + for (cp = buf; i-- > 0; cp++) + *cp ^= 0xFF; + } + break; + case OSSL_PARAM_UTF8_STRING: +#ifdef CHARSET_EBCDIC + ebcdic2ascii(buf, value, buf_n); +#else + strncpy(buf, value, buf_n); +#endif + /* Don't count the terminating NUL byte as data */ + buf_n--; + break; + case OSSL_PARAM_OCTET_STRING: + if (ishex) { + size_t l = 0; + + if (!OPENSSL_hexstr2buf_ex(buf, buf_n, &l, value, ':')) + return 0; + } else { + memcpy(buf, value, buf_n); + } + break; + } + } + + *to = *paramdef; + to->data = buf; + to->data_size = buf_n; + to->return_size = OSSL_PARAM_UNMODIFIED; + + return 1; +} + +int OSSL_PARAM_allocate_from_text(OSSL_PARAM *to, + const OSSL_PARAM *paramdefs, + const char *key, const char *value, + size_t value_n, int *found) +{ + const OSSL_PARAM *paramdef = NULL; + int ishex = 0; + void *buf = NULL; + size_t buf_n = 0; + BIGNUM *tmpbn = NULL; + int ok = 0; + + if (to == NULL || paramdefs == NULL) + return 0; + + if (!prepare_from_text(paramdefs, key, value, value_n, + ¶mdef, &ishex, &buf_n, &tmpbn, found)) + goto err; + + if ((buf = OPENSSL_zalloc(buf_n > 0 ? buf_n : 1)) == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + goto err; + } + + ok = construct_from_text(to, paramdef, value, value_n, ishex, + buf, buf_n, tmpbn); + BN_free(tmpbn); + if (!ok) + OPENSSL_free(buf); + return ok; + err: + BN_free(tmpbn); + return 0; +} diff --git a/crypto/openssl/crypto/pariscid.pl b/crypto/openssl/crypto/pariscid.pl index f4d364754a1f..bad337545740 100755 --- a/crypto/openssl/crypto/pariscid.pl +++ b/crypto/openssl/crypto/pariscid.pl @@ -1,15 +1,18 @@ #! /usr/bin/env perl # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/openssl/crypto/passphrase.c b/crypto/openssl/crypto/passphrase.c new file mode 100644 index 000000000000..fcc40f6dab53 --- /dev/null +++ b/crypto/openssl/crypto/passphrase.c @@ -0,0 +1,353 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/passphrase.h" + +void ossl_pw_clear_passphrase_data(struct ossl_passphrase_data_st *data) +{ + if (data != NULL) { + if (data->type == is_expl_passphrase) + OPENSSL_clear_free(data->_.expl_passphrase.passphrase_copy, + data->_.expl_passphrase.passphrase_len); + ossl_pw_clear_passphrase_cache(data); + memset(data, 0, sizeof(*data)); + } +} + +void ossl_pw_clear_passphrase_cache(struct ossl_passphrase_data_st *data) +{ + OPENSSL_clear_free(data->cached_passphrase, data->cached_passphrase_len); + data->cached_passphrase = NULL; +} + +int ossl_pw_set_passphrase(struct ossl_passphrase_data_st *data, + const unsigned char *passphrase, + size_t passphrase_len) +{ + if (!ossl_assert(data != NULL && passphrase != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ossl_pw_clear_passphrase_data(data); + data->type = is_expl_passphrase; + data->_.expl_passphrase.passphrase_copy = + passphrase_len != 0 ? OPENSSL_memdup(passphrase, passphrase_len) + : OPENSSL_malloc(1); + if (data->_.expl_passphrase.passphrase_copy == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + data->_.expl_passphrase.passphrase_len = passphrase_len; + return 1; +} + +int ossl_pw_set_pem_password_cb(struct ossl_passphrase_data_st *data, + pem_password_cb *cb, void *cbarg) +{ + if (!ossl_assert(data != NULL && cb != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ossl_pw_clear_passphrase_data(data); + data->type = is_pem_password; + data->_.pem_password.password_cb = cb; + data->_.pem_password.password_cbarg = cbarg; + return 1; +} + +int ossl_pw_set_ossl_passphrase_cb(struct ossl_passphrase_data_st *data, + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) +{ + if (!ossl_assert(data != NULL && cb != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ossl_pw_clear_passphrase_data(data); + data->type = is_ossl_passphrase; + data->_.ossl_passphrase.passphrase_cb = cb; + data->_.ossl_passphrase.passphrase_cbarg = cbarg; + return 1; +} + +int ossl_pw_set_ui_method(struct ossl_passphrase_data_st *data, + const UI_METHOD *ui_method, void *ui_data) +{ + if (!ossl_assert(data != NULL && ui_method != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ossl_pw_clear_passphrase_data(data); + data->type = is_ui_method; + data->_.ui_method.ui_method = ui_method; + data->_.ui_method.ui_method_data = ui_data; + return 1; +} + +int ossl_pw_enable_passphrase_caching(struct ossl_passphrase_data_st *data) +{ + data->flag_cache_passphrase = 1; + return 1; +} + +int ossl_pw_disable_passphrase_caching(struct ossl_passphrase_data_st *data) +{ + data->flag_cache_passphrase = 0; + return 1; +} + + +/*- + * UI_METHOD processor. It differs from UI_UTIL_read_pw() like this: + * + * 1. It constructs a prompt on its own, based on |prompt_info|. + * 2. It allocates a buffer for password and verification on its own + * to compensate for NUL terminator in UI password strings. + * 3. It raises errors. + * 4. It reports back the length of the prompted pass phrase. + */ +static int do_ui_passphrase(char *pass, size_t pass_size, size_t *pass_len, + const char *prompt_info, int verify, + const UI_METHOD *ui_method, void *ui_data) +{ + char *prompt = NULL, *ipass = NULL, *vpass = NULL; + int prompt_idx = -1, verify_idx = -1, res; + UI *ui = NULL; + int ret = 0; + + if (!ossl_assert(pass != NULL && pass_size != 0 && pass_len != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((ui = UI_new()) == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (ui_method != NULL) { + UI_set_method(ui, ui_method); + if (ui_data != NULL) + UI_add_user_data(ui, ui_data); + } + + /* Get an application constructed prompt */ + prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); + if (prompt == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + goto end; + } + + /* Get a buffer for verification prompt */ + ipass = OPENSSL_zalloc(pass_size + 1); + if (ipass == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + goto end; + } + + prompt_idx = UI_add_input_string(ui, prompt, + UI_INPUT_FLAG_DEFAULT_PWD, + ipass, 0, pass_size) - 1; + if (prompt_idx < 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB); + goto end; + } + + if (verify) { + /* Get a buffer for verification prompt */ + vpass = OPENSSL_zalloc(pass_size + 1); + if (vpass == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + goto end; + } + verify_idx = UI_add_verify_string(ui, prompt, + UI_INPUT_FLAG_DEFAULT_PWD, + vpass, 0, pass_size, + ipass) - 1; + if (verify_idx < 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB); + goto end; + } + } + + switch (UI_process(ui)) { + case -2: + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERRUPTED_OR_CANCELLED); + break; + case -1: + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB); + break; + default: + res = UI_get_result_length(ui, prompt_idx); + if (res < 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB); + break; + } + *pass_len = (size_t)res; + memcpy(pass, ipass, *pass_len); + ret = 1; + break; + } + + end: + OPENSSL_clear_free(vpass, pass_size + 1); + OPENSSL_clear_free(ipass, pass_size + 1); + OPENSSL_free(prompt); + UI_free(ui); + return ret; +} + +/* Central pw prompting dispatcher */ +int ossl_pw_get_passphrase(char *pass, size_t pass_size, size_t *pass_len, + const OSSL_PARAM params[], int verify, + struct ossl_passphrase_data_st *data) +{ + const char *source = NULL; + size_t source_len = 0; + const char *prompt_info = NULL; + const UI_METHOD *ui_method = NULL; + UI_METHOD *allocated_ui_method = NULL; + void *ui_data = NULL; + const OSSL_PARAM *p = NULL; + int ret; + + /* Handle explicit and cached passphrases */ + + if (data->type == is_expl_passphrase) { + source = data->_.expl_passphrase.passphrase_copy; + source_len = data->_.expl_passphrase.passphrase_len; + } else if (data->flag_cache_passphrase && data->cached_passphrase != NULL) { + source = data->cached_passphrase; + source_len = data->cached_passphrase_len; + } + + if (source != NULL) { + if (source_len > pass_size) + source_len = pass_size; + memcpy(pass, source, source_len); + *pass_len = source_len; + return 1; + } + + /* Handle the is_ossl_passphrase case... that's pretty direct */ + + if (data->type == is_ossl_passphrase) { + OSSL_PASSPHRASE_CALLBACK *cb = data->_.ossl_passphrase.passphrase_cb; + void *cbarg = data->_.ossl_passphrase.passphrase_cbarg; + + ret = cb(pass, pass_size, pass_len, params, cbarg); + goto do_cache; + } + + /* Handle the is_pem_password and is_ui_method cases */ + + if ((p = OSSL_PARAM_locate_const(params, + OSSL_PASSPHRASE_PARAM_INFO)) != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT, + "Prompt info data type incorrect"); + return 0; + } + prompt_info = p->data; + } + + if (data->type == is_pem_password) { + /* We use a UI wrapper for PEM */ + pem_password_cb *cb = data->_.pem_password.password_cb; + + ui_method = allocated_ui_method = + UI_UTIL_wrap_read_pem_callback(cb, verify); + ui_data = data->_.pem_password.password_cbarg; + + if (ui_method == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + } else if (data->type == is_ui_method) { + ui_method = data->_.ui_method.ui_method; + ui_data = data->_.ui_method.ui_method_data; + } + + if (ui_method == NULL) { + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT, + "No password method specified"); + return 0; + } + + ret = do_ui_passphrase(pass, pass_size, pass_len, prompt_info, verify, + ui_method, ui_data); + + UI_destroy_method(allocated_ui_method); + + do_cache: + if (ret && data->flag_cache_passphrase) { + if (data->cached_passphrase == NULL + || *pass_len > data->cached_passphrase_len) { + void *new_cache = + OPENSSL_clear_realloc(data->cached_passphrase, + data->cached_passphrase_len, + *pass_len + 1); + + if (new_cache == NULL) { + OPENSSL_cleanse(pass, *pass_len); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + data->cached_passphrase = new_cache; + } + memcpy(data->cached_passphrase, pass, *pass_len); + data->cached_passphrase[*pass_len] = '\0'; + data->cached_passphrase_len = *pass_len; + } + + return ret; +} + +static int ossl_pw_get_password(char *buf, int size, int rwflag, + void *userdata, const char *info) +{ + size_t password_len = 0; + OSSL_PARAM params[] = { + OSSL_PARAM_utf8_string(OSSL_PASSPHRASE_PARAM_INFO, NULL, 0), + OSSL_PARAM_END + }; + + params[0].data = (void *)info; + if (ossl_pw_get_passphrase(buf, (size_t)size, &password_len, params, + rwflag, userdata)) + return (int)password_len; + return -1; +} + +int ossl_pw_pem_password(char *buf, int size, int rwflag, void *userdata) +{ + return ossl_pw_get_password(buf, size, rwflag, userdata, "PEM"); +} + +int ossl_pw_pvk_password(char *buf, int size, int rwflag, void *userdata) +{ + return ossl_pw_get_password(buf, size, rwflag, userdata, "PVK"); +} + +int ossl_pw_passphrase_callback_enc(char *pass, size_t pass_size, + size_t *pass_len, + const OSSL_PARAM params[], void *arg) +{ + return ossl_pw_get_passphrase(pass, pass_size, pass_len, params, 1, arg); +} + +int ossl_pw_passphrase_callback_dec(char *pass, size_t pass_size, + size_t *pass_len, + const OSSL_PARAM params[], void *arg) +{ + return ossl_pw_get_passphrase(pass, pass_size, pass_len, params, 0, arg); +} diff --git a/crypto/openssl/crypto/pem/pem_all.c b/crypto/openssl/crypto/pem/pem_all.c index 9d57ee7cc2e5..222af64397b4 100644 --- a/crypto/openssl/crypto/pem/pem_all.c +++ b/crypto/openssl/crypto/pem/pem_all.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -17,10 +23,9 @@ #include #include #include +#include "pem_local.h" -#ifndef OPENSSL_NO_RSA static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); -#endif #ifndef OPENSSL_NO_DSA static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa); #endif @@ -33,11 +38,12 @@ IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ) IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) +IMPLEMENT_PEM_rw(X509_PUBKEY, X509_PUBKEY, PEM_STRING_PUBLIC, X509_PUBKEY) IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE, PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE) -#ifndef OPENSSL_NO_RSA +#ifndef OPENSSL_NO_DEPRECATED_3_0 /* * We treat RSA or DSA private keys as a special case. For private keys we * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract @@ -79,12 +85,8 @@ RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) # endif -IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, - RSAPrivateKey) - - -IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, - RSAPublicKey) +IMPLEMENT_PEM_write_cb(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey) +IMPLEMENT_PEM_rw(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY) #endif #ifndef OPENSSL_NO_DSA @@ -112,8 +114,7 @@ DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ } -IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, - DSAPrivateKey) +IMPLEMENT_PEM_write_cb(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey) IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) # ifndef OPENSSL_NO_STDIO DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) @@ -125,9 +126,11 @@ DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) # endif -IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) +IMPLEMENT_PEM_rw(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) #endif -#ifndef OPENSSL_NO_EC + +#ifndef OPENSSL_NO_DEPRECATED_3_0 +# ifndef OPENSSL_NO_EC static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey) { EC_KEY *dtmp; @@ -152,14 +155,14 @@ EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, return pkey_get_eckey(pktmp, key); /* will free pktmp */ } -IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, - ECPKParameters) +IMPLEMENT_PEM_rw(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, + ECPKParameters) IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey) IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) -# ifndef OPENSSL_NO_STDIO +# ifndef OPENSSL_NO_STDIO EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, void *u) { @@ -167,14 +170,57 @@ EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); return pkey_get_eckey(pktmp, eckey); /* will free pktmp */ } +# endif +# endif /* !OPENSSL_NO_EC */ +#endif /* !OPENSSL_NO_DEPRECATED_3_0 */ -# endif +#ifndef OPENSSL_NO_DH -#endif +IMPLEMENT_PEM_write(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) +IMPLEMENT_PEM_write(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) -#ifndef OPENSSL_NO_DH +/* Transparently read in PKCS#3 or X9.42 DH parameters */ + +DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) +{ + char *nm = NULL; + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + DH *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u)) + return NULL; + p = data; + + if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0) + ret = d2i_DHxparams(x, &p, len); + else + ret = d2i_DHparams(x, &p, len); + + if (ret == NULL) + ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); + OPENSSL_free(nm); + OPENSSL_free(data); + return ret; +} + +# ifndef OPENSSL_NO_STDIO +DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u) +{ + BIO *b; + DH *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_read_bio_DHparams(b, x, cb, u); + BIO_free(b); + return ret; +} +# endif -IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) -IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) #endif -IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) +IMPLEMENT_PEM_provided_write(PUBKEY, EVP_PKEY, pkey, PEM_STRING_PUBLIC, PUBKEY) diff --git a/crypto/openssl/crypto/pem/pem_err.c b/crypto/openssl/crypto/pem/pem_err.c index 0f3cb02407e6..5fa9fc09bec7 100644 --- a/crypto/openssl/crypto/pem/pem_err.c +++ b/crypto/openssl/crypto/pem/pem_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,68 +10,10 @@ #include #include +#include "crypto/pemerr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA PEM_str_functs[] = { - {ERR_PACK(ERR_LIB_PEM, PEM_F_B2I_DSS, 0), "b2i_dss"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_B2I_PVK_BIO, 0), "b2i_PVK_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_B2I_RSA, 0), "b2i_rsa"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_CHECK_BITLEN_DSA, 0), "check_bitlen_dsa"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_CHECK_BITLEN_RSA, 0), "check_bitlen_rsa"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_D2I_PKCS8PRIVATEKEY_BIO, 0), - "d2i_PKCS8PrivateKey_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_D2I_PKCS8PRIVATEKEY_FP, 0), - "d2i_PKCS8PrivateKey_fp"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_B2I, 0), "do_b2i"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_B2I_BIO, 0), "do_b2i_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_BLOB_HEADER, 0), "do_blob_header"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_I2B, 0), "do_i2b"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_PK8PKEY, 0), "do_pk8pkey"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_PK8PKEY_FP, 0), "do_pk8pkey_fp"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_PVK_BODY, 0), "do_PVK_body"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_DO_PVK_HEADER, 0), "do_PVK_header"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_GET_HEADER_AND_DATA, 0), - "get_header_and_data"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_GET_NAME, 0), "get_name"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_I2B_PVK, 0), "i2b_PVK"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_I2B_PVK_BIO, 0), "i2b_PVK_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_LOAD_IV, 0), "load_iv"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_ASN1_READ, 0), "PEM_ASN1_read"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_ASN1_READ_BIO, 0), "PEM_ASN1_read_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_ASN1_WRITE, 0), "PEM_ASN1_write"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_ASN1_WRITE_BIO, 0), "PEM_ASN1_write_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DEF_CALLBACK, 0), "PEM_def_callback"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, 0), "PEM_do_header"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_GET_EVP_CIPHER_INFO, 0), - "PEM_get_EVP_CIPHER_INFO"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ, 0), "PEM_read"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO, 0), "PEM_read_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_DHPARAMS, 0), - "PEM_read_bio_DHparams"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_EX, 0), "PEM_read_bio_ex"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_PARAMETERS, 0), - "PEM_read_bio_Parameters"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_PRIVATEKEY, 0), - "PEM_read_bio_PrivateKey"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_DHPARAMS, 0), "PEM_read_DHparams"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_PRIVATEKEY, 0), - "PEM_read_PrivateKey"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_SIGNFINAL, 0), "PEM_SignFinal"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_WRITE, 0), "PEM_write"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_WRITE_BIO, 0), "PEM_write_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_WRITE_BIO_PRIVATEKEY_TRADITIONAL, 0), - "PEM_write_bio_PrivateKey_traditional"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_WRITE_PRIVATEKEY, 0), - "PEM_write_PrivateKey"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_X509_INFO_READ, 0), "PEM_X509_INFO_read"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_X509_INFO_READ_BIO, 0), - "PEM_X509_INFO_read_bio"}, - {ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_X509_INFO_WRITE_BIO, 0), - "PEM_X509_INFO_write_bio"}, - {0, NULL} -}; - static const ERR_STRING_DATA PEM_str_reasons[] = { {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_BASE64_DECODE), "bad base64 decode"}, {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_DECRYPT), "bad decrypt"}, @@ -84,10 +26,14 @@ static const ERR_STRING_DATA PEM_str_reasons[] = { {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_CIPHER_IS_NULL), "cipher is null"}, {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_ERROR_CONVERTING_PRIVATE_KEY), "error converting private key"}, + {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_EXPECTING_DSS_KEY_BLOB), + "expecting dss key blob"}, {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_EXPECTING_PRIVATE_KEY_BLOB), "expecting private key blob"}, {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_EXPECTING_PUBLIC_KEY_BLOB), "expecting public key blob"}, + {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_EXPECTING_RSA_KEY_BLOB), + "expecting rsa key blob"}, {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_HEADER_TOO_LONG), "header too long"}, {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_INCONSISTENT_HEADER), "inconsistent header"}, @@ -118,13 +64,11 @@ static const ERR_STRING_DATA PEM_str_reasons[] = { #endif -int ERR_load_PEM_strings(void) +int ossl_err_load_PEM_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) { - ERR_load_strings_const(PEM_str_functs); + if (ERR_reason_error_string(PEM_str_reasons[0].error) == NULL) ERR_load_strings_const(PEM_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/pem/pem_info.c b/crypto/openssl/crypto/pem/pem_info.c index f90cb4465096..061c9b9f68c8 100644 --- a/crypto/openssl/crypto/pem/pem_info.c +++ b/crypto/openssl/crypto/pem/pem_info.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -16,30 +22,40 @@ #include #include #include +#include "crypto/evp.h" #ifndef OPENSSL_NO_STDIO -STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u) +STACK_OF(X509_INFO) +*PEM_X509_INFO_read_ex(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, + void *u, OSSL_LIB_CTX *libctx, const char *propq) { BIO *b; STACK_OF(X509_INFO) *ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_X509_INFO_READ, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_X509_INFO_read_bio(b, sk, cb, u); + ret = PEM_X509_INFO_read_bio_ex(b, sk, cb, u, libctx, propq); BIO_free(b); return ret; } + +STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u) +{ + return PEM_X509_INFO_read_ex(fp, sk, cb, u, NULL, NULL); +} #endif -STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u) +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, + const char *propq) { X509_INFO *xi = NULL; - char *name = NULL, *header = NULL; + char *name = NULL, *header = NULL, *str; void *pp; unsigned char *data = NULL; const unsigned char *p; @@ -51,7 +67,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, if (sk == NULL) { if ((ret = sk_X509_INFO_new_null()) == NULL) { - PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); goto err; } } else @@ -62,29 +78,22 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, for (;;) { raw = 0; ptype = 0; + ERR_set_mark(); i = PEM_read_bio(bp, &name, &header, &data, &len); if (i == 0) { error = ERR_GET_REASON(ERR_peek_last_error()); if (error == PEM_R_NO_START_LINE) { - ERR_clear_error(); + ERR_pop_to_mark(); break; } + ERR_clear_last_mark(); goto err; } + ERR_clear_last_mark(); start: - if ((strcmp(name, PEM_STRING_X509) == 0) || - (strcmp(name, PEM_STRING_X509_OLD) == 0)) { - d2i = (D2I_OF(void)) d2i_X509; - if (xi->x509 != NULL) { - if (!sk_X509_INFO_push(ret, xi)) - goto err; - if ((xi = X509_INFO_new()) == NULL) - goto err; - goto start; - } - pp = &(xi->x509); - } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) { - d2i = (D2I_OF(void)) d2i_X509_AUX; + if (strcmp(name, PEM_STRING_X509) == 0 + || strcmp(name, PEM_STRING_X509_OLD) == 0 + || strcmp(name, PEM_STRING_X509_TRUSTED) == 0) { if (xi->x509 != NULL) { if (!sk_X509_INFO_push(ret, xi)) goto err; @@ -92,6 +101,13 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, goto err; goto start; } + if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) + d2i = (D2I_OF(void)) d2i_X509_AUX; + else + d2i = (D2I_OF(void)) d2i_X509; + xi->x509 = X509_new_ex(libctx, propq); + if (xi->x509 == NULL) + goto err; pp = &(xi->x509); } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) { d2i = (D2I_OF(void)) d2i_X509_CRL; @@ -103,10 +119,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, goto start; } pp = &(xi->crl); - } else -#ifndef OPENSSL_NO_RSA - if (strcmp(name, PEM_STRING_RSA) == 0) { - d2i = (D2I_OF(void)) d2i_RSAPrivateKey; + } else if ((str = strstr(name, PEM_STRING_PKCS8INF)) != NULL) { if (xi->x_pkey != NULL) { if (!sk_X509_INFO_push(ret, xi)) goto err; @@ -114,66 +127,25 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, goto err; goto start; } - - xi->enc_data = NULL; - xi->enc_len = 0; - - xi->x_pkey = X509_PKEY_new(); - if (xi->x_pkey == NULL) - goto err; - ptype = EVP_PKEY_RSA; - pp = &xi->x_pkey->dec_pkey; - if ((int)strlen(header) > 10) /* assume encrypted */ - raw = 1; - } else -#endif -#ifndef OPENSSL_NO_DSA - if (strcmp(name, PEM_STRING_DSA) == 0) { - d2i = (D2I_OF(void)) d2i_DSAPrivateKey; - if (xi->x_pkey != NULL) { - if (!sk_X509_INFO_push(ret, xi)) - goto err; - if ((xi = X509_INFO_new()) == NULL) - goto err; - goto start; + if (str == name || strcmp(name, PEM_STRING_PKCS8) == 0) { + ptype = EVP_PKEY_NONE; + } else { + /* chop " PRIVATE KEY" */ + *--str = '\0'; + ptype = evp_pkey_name2type(name); } - xi->enc_data = NULL; xi->enc_len = 0; + d2i = (D2I_OF(void)) d2i_AutoPrivateKey; xi->x_pkey = X509_PKEY_new(); if (xi->x_pkey == NULL) goto err; - ptype = EVP_PKEY_DSA; pp = &xi->x_pkey->dec_pkey; - if ((int)strlen(header) > 10) /* assume encrypted */ + if ((int)strlen(header) > 10 /* assume encrypted */ + || strcmp(name, PEM_STRING_PKCS8) == 0) raw = 1; - } else -#endif -#ifndef OPENSSL_NO_EC - if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) { - d2i = (D2I_OF(void)) d2i_ECPrivateKey; - if (xi->x_pkey != NULL) { - if (!sk_X509_INFO_push(ret, xi)) - goto err; - if ((xi = X509_INFO_new()) == NULL) - goto err; - goto start; - } - - xi->enc_data = NULL; - xi->enc_len = 0; - - xi->x_pkey = X509_PKEY_new(); - if (xi->x_pkey == NULL) - goto err; - ptype = EVP_PKEY_EC; - pp = &xi->x_pkey->dec_pkey; - if ((int)strlen(header) > 10) /* assume encrypted */ - raw = 1; - } else -#endif - { + } else { /* unknown */ d2i = NULL; pp = NULL; } @@ -188,23 +160,22 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, goto err; p = data; if (ptype) { - if (!d2i_PrivateKey(ptype, pp, &p, len)) { - PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB); + if (d2i_PrivateKey_ex(ptype, pp, &p, len, + libctx, propq) == NULL) { + ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); goto err; } } else if (d2i(pp, &p, len) == NULL) { - PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); goto err; } - } else { /* encrypted RSA data */ + } else { /* encrypted key data */ if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher)) goto err; xi->enc_data = (char *)data; xi->enc_len = (int)len; data = NULL; } - } else { - /* unknown */ } OPENSSL_free(name); name = NULL; @@ -243,27 +214,33 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, return ret; } +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u) +{ + return PEM_X509_INFO_read_bio_ex(bp, sk, cb, u, NULL, NULL); +} + /* A TJH addition */ -int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, - unsigned char *kstr, int klen, +int PEM_X509_INFO_write_bio(BIO *bp, const X509_INFO *xi, EVP_CIPHER *enc, + const unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { int i, ret = 0; unsigned char *data = NULL; const char *objstr = NULL; char buf[PEM_BUFSIZE]; - unsigned char *iv = NULL; + const unsigned char *iv = NULL; if (enc != NULL) { - objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + objstr = EVP_CIPHER_get0_name(enc); if (objstr == NULL - /* - * Check "Proc-Type: 4,Encrypted\nDEK-Info: objstr,hex-iv\n" - * fits into buf - */ - || (strlen(objstr) + 23 + 2 * EVP_CIPHER_iv_length(enc) + 13) - > sizeof(buf)) { - PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER); + /* + * Check "Proc-Type: 4,Encrypted\nDEK-Info: objstr,hex-iv\n" + * fits into buf + */ + || strlen(objstr) + 23 + 2 * EVP_CIPHER_get_iv_length(enc) + 13 + > sizeof(buf)) { + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER); goto err; } } @@ -276,7 +253,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, if (xi->x_pkey != NULL) { if ((xi->enc_data != NULL) && (xi->enc_len > 0)) { if (enc == NULL) { - PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_CIPHER_IS_NULL); + ERR_raise(ERR_LIB_PEM, PEM_R_CIPHER_IS_NULL); goto err; } @@ -290,18 +267,17 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, * than what the user has passed us ... as we have to match * exactly for some strange reason */ - objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher)); + objstr = EVP_CIPHER_get0_name(xi->enc_cipher.cipher); if (objstr == NULL) { - PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, - PEM_R_UNSUPPORTED_CIPHER); + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER); goto err; } /* Create the right magic header stuff */ buf[0] = '\0'; PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); - PEM_dek_info(buf, objstr, EVP_CIPHER_iv_length(enc), - (char *)iv); + PEM_dek_info(buf, objstr, EVP_CIPHER_get_iv_length(enc), + (const char *)iv); /* use the normal code to write things out */ i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i); @@ -309,13 +285,11 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, goto err; } else { /* Add DSA/DH */ -#ifndef OPENSSL_NO_RSA /* normal optionally encrypted stuff */ if (PEM_write_bio_RSAPrivateKey(bp, EVP_PKEY_get0_RSA(xi->x_pkey->dec_pkey), enc, kstr, klen, cb, u) <= 0) goto err; -#endif } } diff --git a/crypto/openssl/crypto/pem/pem_lib.c b/crypto/openssl/crypto/pem/pem_lib.c index 14f9ca4aa4d6..6cd998f21669 100644 --- a/crypto/openssl/crypto/pem/pem_lib.c +++ b/crypto/openssl/crypto/pem/pem_lib.c @@ -1,12 +1,15 @@ /* * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include "crypto/ctype.h" #include @@ -26,7 +29,7 @@ static int load_iv(char **fromp, unsigned char *to, int num); static int check_pem(const char *nm, const char *name); -int pem_check_suffix(const char *pem_str, const char *suffix); +int ossl_pem_check_suffix(const char *pem_str, const char *suffix); int PEM_def_callback(char *buf, int num, int rwflag, void *userdata) { @@ -56,7 +59,7 @@ int PEM_def_callback(char *buf, int num, int rwflag, void *userdata) i = EVP_read_pw_string_min(buf, min_len, num, prompt, rwflag); if (i != 0) { - PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD); + ERR_raise(ERR_LIB_PEM, PEM_R_PROBLEMS_GETTING_PASSWORD); memset(buf, 0, (unsigned int)num); return -1; } @@ -80,7 +83,7 @@ void PEM_proc_type(char *buf, int type) BIO_snprintf(p, PEM_BUFSIZE - (size_t)(p - buf), "Proc-Type: 4,%s\n", str); } -void PEM_dek_info(char *buf, const char *type, int len, char *str) +void PEM_dek_info(char *buf, const char *type, int len, const char *str) { long i; char *p = buf + strlen(buf); @@ -110,7 +113,7 @@ void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, void *ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_ASN1_READ, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -135,7 +138,7 @@ static int check_pem(const char *nm, const char *name) return 1; if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) return 1; - slen = pem_check_suffix(nm, "PRIVATE KEY"); + slen = ossl_pem_check_suffix(nm, "PRIVATE KEY"); if (slen > 0) { /* * NB: ENGINE implementations won't contain a deprecated old @@ -151,7 +154,7 @@ static int check_pem(const char *nm, const char *name) if (strcmp(name, PEM_STRING_PARAMETERS) == 0) { int slen; const EVP_PKEY_ASN1_METHOD *ameth; - slen = pem_check_suffix(nm, "PARAMETERS"); + slen = ossl_pem_check_suffix(nm, "PARAMETERS"); if (slen > 0) { ENGINE *e; ameth = EVP_PKEY_asn1_find_str(&e, nm, slen); @@ -288,14 +291,15 @@ int PEM_bytes_read_bio_secmem(unsigned char **pdata, long *plen, char **pnm, #ifndef OPENSSL_NO_STDIO int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, - void *x, const EVP_CIPHER *enc, unsigned char *kstr, - int klen, pem_password_cb *callback, void *u) + const void *x, const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, + pem_password_cb *callback, void *u) { BIO *b; int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_ASN1_WRITE, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -306,8 +310,9 @@ int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, #endif int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, - void *x, const EVP_CIPHER *enc, unsigned char *kstr, - int klen, pem_password_cb *callback, void *u) + const void *x, const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, + pem_password_cb *callback, void *u) { EVP_CIPHER_CTX *ctx = NULL; int dsize = 0, i = 0, j = 0, ret = 0; @@ -318,22 +323,22 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, unsigned char iv[EVP_MAX_IV_LENGTH]; if (enc != NULL) { - objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); - if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0 - || EVP_CIPHER_iv_length(enc) > (int)sizeof(iv) + objstr = EVP_CIPHER_get0_name(enc); + if (objstr == NULL || EVP_CIPHER_get_iv_length(enc) == 0 + || EVP_CIPHER_get_iv_length(enc) > (int)sizeof(iv) /* * Check "Proc-Type: 4,Encrypted\nDEK-Info: objstr,hex-iv\n" * fits into buf */ - || (strlen(objstr) + 23 + 2 * EVP_CIPHER_iv_length(enc) + 13) + || strlen(objstr) + 23 + 2 * EVP_CIPHER_get_iv_length(enc) + 13 > sizeof(buf)) { - PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER); + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER); goto err; } } if ((dsize = i2d(x, NULL)) <= 0) { - PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); dsize = 0; goto err; } @@ -341,7 +346,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, /* actually it needs the cipher block size extra... */ data = OPENSSL_malloc((unsigned int)dsize + 20); if (data == NULL) { - PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); goto err; } p = data; @@ -354,7 +359,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, else klen = (*callback) (buf, PEM_BUFSIZE, 1, u); if (klen <= 0) { - PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_READ_KEY); + ERR_raise(ERR_LIB_PEM, PEM_R_READ_KEY); goto err; } #ifdef CHARSET_EBCDIC @@ -363,7 +368,8 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, #endif kstr = (unsigned char *)buf; } - if (RAND_bytes(iv, EVP_CIPHER_iv_length(enc)) <= 0) /* Generate a salt */ + /* Generate a salt */ + if (RAND_bytes(iv, EVP_CIPHER_get_iv_length(enc)) <= 0) goto err; /* * The 'iv' is used as the iv and as a salt. It is NOT taken from @@ -377,7 +383,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, buf[0] = '\0'; PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); - PEM_dek_info(buf, objstr, EVP_CIPHER_iv_length(enc), (char *)iv); + PEM_dek_info(buf, objstr, EVP_CIPHER_get_iv_length(enc), (char *)iv); /* k=strlen(buf); */ ret = 1; @@ -419,7 +425,7 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, #if LONG_MAX > INT_MAX /* Check that we did not truncate the length */ if (len > INT_MAX) { - PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_HEADER_TOO_LONG); + ERR_raise(ERR_LIB_PEM, PEM_R_HEADER_TOO_LONG); return 0; } #endif @@ -431,7 +437,7 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, else keylen = callback(buf, PEM_BUFSIZE, 0, u); if (keylen < 0) { - PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ); return 0; } #ifdef CHARSET_EBCDIC @@ -458,7 +464,7 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, if (ok) *plen += ilen; else - PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_DECRYPT); EVP_CIPHER_CTX_free(ctx); OPENSSL_cleanse((char *)buf, sizeof(buf)); @@ -493,7 +499,7 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) return 1; if (strncmp(header, ProcType, sizeof(ProcType)-1) != 0) { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_PROC_TYPE); + ERR_raise(ERR_LIB_PEM, PEM_R_NOT_PROC_TYPE); return 0; } header += sizeof(ProcType)-1; @@ -506,13 +512,13 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) /* We expect "ENCRYPTED" followed by optional white-space + line break */ if (strncmp(header, ENCRYPTED, sizeof(ENCRYPTED)-1) != 0 || strspn(header+sizeof(ENCRYPTED)-1, " \t\r\n") == 0) { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_ENCRYPTED); + ERR_raise(ERR_LIB_PEM, PEM_R_NOT_ENCRYPTED); return 0; } header += sizeof(ENCRYPTED)-1; header += strspn(header, " \t\r"); if (*header++ != '\n') { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_SHORT_HEADER); + ERR_raise(ERR_LIB_PEM, PEM_R_SHORT_HEADER); return 0; } @@ -521,7 +527,7 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) * We expect "DEK-Info: algo[,hex-parameters]" */ if (strncmp(header, DEKInfo, sizeof(DEKInfo)-1) != 0) { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_DEK_INFO); + ERR_raise(ERR_LIB_PEM, PEM_R_NOT_DEK_INFO); return 0; } header += sizeof(DEKInfo)-1; @@ -540,19 +546,19 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) header += strspn(header, " \t"); if (enc == NULL) { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_UNSUPPORTED_ENCRYPTION); + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_ENCRYPTION); return 0; } - ivlen = EVP_CIPHER_iv_length(enc); + ivlen = EVP_CIPHER_get_iv_length(enc); if (ivlen > 0 && *header++ != ',') { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_MISSING_DEK_IV); + ERR_raise(ERR_LIB_PEM, PEM_R_MISSING_DEK_IV); return 0; } else if (ivlen == 0 && *header == ',') { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_UNEXPECTED_DEK_IV); + ERR_raise(ERR_LIB_PEM, PEM_R_UNEXPECTED_DEK_IV); return 0; } - if (!load_iv(&header, cipher->iv, EVP_CIPHER_iv_length(enc))) + if (!load_iv(&header, cipher->iv, EVP_CIPHER_get_iv_length(enc))) return 0; return 1; @@ -570,7 +576,7 @@ static int load_iv(char **fromp, unsigned char *to, int num) for (i = 0; i < num; i++) { v = OPENSSL_hexchar2int(*from); if (v < 0) { - PEMerr(PEM_F_LOAD_IV, PEM_R_BAD_IV_CHARS); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_IV_CHARS); return 0; } from++; @@ -589,7 +595,7 @@ int PEM_write(FILE *fp, const char *name, const char *header, int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_WRITE, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -655,7 +661,7 @@ int PEM_write_bio(BIO *bp, const char *name, const char *header, err: if (retval == 0) - PEMerr(PEM_F_PEM_WRITE_BIO, reason); + ERR_raise(ERR_LIB_PEM, reason); EVP_ENCODE_CTX_free(ctx); OPENSSL_clear_free(buf, PEM_BUFSIZE * 8); return retval; @@ -669,7 +675,7 @@ int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_READ, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -680,9 +686,20 @@ int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, #endif /* Some helpers for PEM_read_bio_ex(). */ -static int sanitize_line(char *linebuf, int len, unsigned int flags) +static int sanitize_line(char *linebuf, int len, unsigned int flags, int first_call) { int i; + if (first_call) { + /* Other BOMs imply unsupported multibyte encoding, + * so don't strip them and let the error raise */ + const unsigned char utf8_bom[3] = {0xEF, 0xBB, 0xBF}; + + if (len > 3 && memcmp(linebuf, utf8_bom, 3) == 0) { + memmove(linebuf, linebuf + 3, len - 3); + linebuf[len - 3] = 0; + len -= 3; + } + } if (flags & PEM_FLAG_EAY_COMPATIBLE) { /* Strip trailing whitespace */ @@ -727,6 +744,7 @@ static int get_name(BIO *bp, char **name, unsigned int flags) char *linebuf; int ret = 0; int len; + int first_call = 1; /* * Need to hold trailing NUL (accounted for by BIO_gets() and the newline @@ -734,7 +752,7 @@ static int get_name(BIO *bp, char **name, unsigned int flags) */ linebuf = pem_malloc(LINESIZE + 1, flags); if (linebuf == NULL) { - PEMerr(PEM_F_GET_NAME, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); return 0; } @@ -742,12 +760,13 @@ static int get_name(BIO *bp, char **name, unsigned int flags) len = BIO_gets(bp, linebuf, LINESIZE); if (len <= 0) { - PEMerr(PEM_F_GET_NAME, PEM_R_NO_START_LINE); + ERR_raise(ERR_LIB_PEM, PEM_R_NO_START_LINE); goto err; } /* Strip trailing garbage and standardize ending. */ - len = sanitize_line(linebuf, len, flags & ~PEM_FLAG_ONLY_B64); + len = sanitize_line(linebuf, len, flags & ~PEM_FLAG_ONLY_B64, first_call); + first_call = 0; /* Allow leading empty or non-matching lines. */ } while (strncmp(linebuf, beginstr, BEGINLEN) != 0 @@ -757,7 +776,7 @@ static int get_name(BIO *bp, char **name, unsigned int flags) len = len - BEGINLEN - TAILLEN + 1; *name = pem_malloc(len, flags); if (*name == NULL) { - PEMerr(PEM_F_GET_NAME, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); goto err; } memcpy(*name, linebuf + BEGINLEN, len); @@ -801,15 +820,15 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, * that will be added by sanitize_line() (the extra '1'). */ linebuf = pem_malloc(LINESIZE + 1, flags); if (linebuf == NULL) { - PEMerr(PEM_F_GET_HEADER_AND_DATA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); return 0; } - for (;;) { + while(1) { flags_mask = ~0u; len = BIO_gets(bp, linebuf, LINESIZE); if (len <= 0) { - PEMerr(PEM_F_GET_HEADER_AND_DATA, PEM_R_BAD_END_LINE); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_END_LINE); goto err; } @@ -827,7 +846,7 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, } if (!strncmp(linebuf, endstr, ENDLEN) || got_header == IN_HEADER) flags_mask &= ~PEM_FLAG_ONLY_B64; - len = sanitize_line(linebuf, len, flags & flags_mask); + len = sanitize_line(linebuf, len, flags & flags_mask, 0); /* Check for end of header. */ if (linebuf[0] == '\n') { @@ -838,7 +857,7 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, if (!prev_partial_line_read) { if (got_header == POST_HEADER) { /* Another blank line is an error. */ - PEMerr(PEM_F_GET_HEADER_AND_DATA, PEM_R_BAD_END_LINE); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_END_LINE); goto err; } got_header = POST_HEADER; @@ -853,7 +872,7 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, namelen = strlen(name); if (strncmp(p, name, namelen) != 0 || strncmp(p + namelen, tailstr, TAILLEN) != 0) { - PEMerr(PEM_F_GET_HEADER_AND_DATA, PEM_R_BAD_END_LINE); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_END_LINE); goto err; } if (got_header == MAYBE_HEADER) { @@ -863,7 +882,7 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, break; } else if (end) { /* Malformed input; short line not at end of data. */ - PEMerr(PEM_F_GET_HEADER_AND_DATA, PEM_R_BAD_END_LINE); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_END_LINE); goto err; } /* @@ -911,7 +930,7 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header, *data = NULL; if ((flags & PEM_FLAG_EAY_COMPATIBLE) && (flags & PEM_FLAG_ONLY_B64)) { /* These two are mutually incompatible; bail out. */ - PEMerr(PEM_F_PEM_READ_BIO_EX, ERR_R_PASSED_INVALID_ARGUMENT); + ERR_raise(ERR_LIB_PEM, ERR_R_PASSED_INVALID_ARGUMENT); goto end; } bmeth = (flags & PEM_FLAG_SECURE) ? BIO_s_secmem() : BIO_s_mem(); @@ -919,7 +938,7 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header, headerB = BIO_new(bmeth); dataB = BIO_new(bmeth); if (headerB == NULL || dataB == NULL) { - PEMerr(PEM_F_PEM_READ_BIO_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); goto end; } @@ -937,7 +956,7 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header, ctx = EVP_ENCODE_CTX_new(); if (ctx == NULL) { - PEMerr(PEM_F_PEM_READ_BIO_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); goto end; } @@ -946,7 +965,7 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header, (unsigned char*)buf_mem->data, len) < 0 || EVP_DecodeFinal(ctx, (unsigned char*)&(buf_mem->data[len]), &taillen) < 0) { - PEMerr(PEM_F_PEM_READ_BIO_EX, PEM_R_BAD_BASE64_DECODE); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_BASE64_DECODE); goto end; } len += taillen; @@ -955,21 +974,24 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header, headerlen = BIO_get_mem_data(headerB, NULL); *header = pem_malloc(headerlen + 1, flags); *data = pem_malloc(len, flags); - if (*header == NULL || *data == NULL) { - pem_free(*header, flags, 0); - *header = NULL; - pem_free(*data, flags, 0); - *data = NULL; - goto end; - } - BIO_read(headerB, *header, headerlen); + if (*header == NULL || *data == NULL) + goto out_free; + if (headerlen != 0 && BIO_read(headerB, *header, headerlen) != headerlen) + goto out_free; (*header)[headerlen] = '\0'; - BIO_read(dataB, *data, len); + if (BIO_read(dataB, *data, len) != len) + goto out_free; *len_out = len; *name_out = name; name = NULL; ret = 1; + goto end; +out_free: + pem_free(*header, flags, 0); + *header = NULL; + pem_free(*data, flags, 0); + *data = NULL; end: EVP_ENCODE_CTX_free(ctx); pem_free(name, flags, 0); @@ -990,7 +1012,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, * string "RSA". */ -int pem_check_suffix(const char *pem_str, const char *suffix) +int ossl_pem_check_suffix(const char *pem_str, const char *suffix) { int pem_len = strlen(pem_str); int suffix_len = strlen(suffix); diff --git a/crypto/openssl/crypto/pem/pem_local.h b/crypto/openssl/crypto/pem/pem_local.h new file mode 100644 index 000000000000..5cc1c76fdbf7 --- /dev/null +++ b/crypto/openssl/crypto/pem/pem_local.h @@ -0,0 +1,167 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include + +/* + * Selectors, named according to the ASN.1 names used throughout libcrypto. + * + * Note that these are not absolutely mandatory, they are rather a wishlist + * of sorts. The provider implementations are free to make choices that + * make sense for them, based on these selectors. + * For example, the EC backend is likely to really just output the private + * key to a PKCS#8 structure, even thought PEM_SELECTION_PrivateKey specifies + * the public key as well. This is fine, as long as the corresponding + * decoding operation can return an object that contains what libcrypto + * expects. + */ +# define PEM_SELECTION_PUBKEY EVP_PKEY_PUBLIC_KEY +# define PEM_SELECTION_PrivateKey EVP_PKEY_KEYPAIR +# define PEM_SELECTION_Parameters EVP_PKEY_KEY_PARAMETERS + +/* + * Properties, named according to the ASN.1 names used throughout libcrypto. + */ +# define PEM_STRUCTURE_PUBKEY "SubjectPublicKeyInfo" +# define PEM_STRUCTURE_PrivateKey "PrivateKeyInfo" +# define PEM_STRUCTURE_Parameters "type-specific" + +# define PEM_STRUCTURE_RSAPrivateKey "type-specific" +# define PEM_STRUCTURE_RSAPublicKey "type-specific" + +/* Alternative IMPLEMENT macros for provided encoders */ + +# define IMPLEMENT_PEM_provided_write_body_vars(type, asn1, pq) \ + int ret = 0; \ + OSSL_ENCODER_CTX *ctx = \ + OSSL_ENCODER_CTX_new_for_##type(x, PEM_SELECTION_##asn1, \ + "PEM", PEM_STRUCTURE_##asn1, \ + (pq)); \ + \ + if (OSSL_ENCODER_CTX_get_num_encoders(ctx) == 0) { \ + OSSL_ENCODER_CTX_free(ctx); \ + goto legacy; \ + } +# define IMPLEMENT_PEM_provided_write_body_pass() \ + ret = 1; \ + if (kstr == NULL && cb == NULL) { \ + if (u != NULL) { \ + kstr = u; \ + klen = strlen(u); \ + } else { \ + cb = PEM_def_callback; \ + } \ + } \ + if (enc != NULL) { \ + ret = 0; \ + if (OSSL_ENCODER_CTX_set_cipher(ctx, EVP_CIPHER_get0_name(enc), \ + NULL)) { \ + ret = 1; \ + if (kstr != NULL \ + && !OSSL_ENCODER_CTX_set_passphrase(ctx, kstr, klen)) \ + ret = 0; \ + else if (cb != NULL \ + && !OSSL_ENCODER_CTX_set_pem_password_cb(ctx, \ + cb, u)) \ + ret = 0; \ + } \ + } \ + if (!ret) { \ + OSSL_ENCODER_CTX_free(ctx); \ + return 0; \ + } +# define IMPLEMENT_PEM_provided_write_body_main(type, outtype) \ + ret = OSSL_ENCODER_to_##outtype(ctx, out); \ + OSSL_ENCODER_CTX_free(ctx); \ + return ret +# define IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ + writename) \ + legacy: \ + return PEM_ASN1_##writename((i2d_of_void *)i2d_##asn1, str, out, \ + x, NULL, NULL, 0, NULL, NULL) +# define IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \ + writename) \ + legacy: \ + return PEM_ASN1_##writename##((i2d_of_void *)i2d_##asn1, str, out, \ + x, enc, kstr, klen, cb, u) + +# define IMPLEMENT_PEM_provided_write_to(name, TYPE, type, str, asn1, \ + OUTTYPE, outtype, writename) \ + PEM_write_fnsig(name, TYPE, OUTTYPE, writename) \ + { \ + IMPLEMENT_PEM_provided_write_body_vars(type, asn1, NULL); \ + IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ + IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ + writename); \ + } \ + PEM_write_ex_fnsig(name, TYPE, OUTTYPE, writename) \ + { \ + IMPLEMENT_PEM_provided_write_body_vars(type, asn1, propq); \ + IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ + IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ + writename); \ + } + + +# define IMPLEMENT_PEM_provided_write_cb_to(name, TYPE, type, str, asn1, \ + OUTTYPE, outtype, writename) \ + PEM_write_cb_fnsig(name, TYPE, OUTTYPE, writename) \ + { \ + IMPLEMENT_PEM_provided_write_body_vars(type, asn1, NULL); \ + IMPLEMENT_PEM_provided_write_body_pass(); \ + IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ + IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \ + writename); \ + } \ + PEM_write_ex_cb_fnsig(name, TYPE, OUTTYPE, writename) \ + { \ + IMPLEMENT_PEM_provided_write_body_vars(type, asn1, propq); \ + IMPLEMENT_PEM_provided_write_body_pass(); \ + IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ + IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ + writename); \ + } + +# ifdef OPENSSL_NO_STDIO + +# define IMPLEMENT_PEM_provided_write_fp(name, TYPE, type, str, asn1) +# define IMPLEMENT_PEM_provided_write_cb_fp(name, TYPE, type, str, asn1) + +# else + +# define IMPLEMENT_PEM_provided_write_fp(name, TYPE, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_to(name, TYPE, type, str, asn1, FILE, fp, write) +# define IMPLEMENT_PEM_provided_write_cb_fp(name, TYPE, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_cb_to(name, TYPE, type, str, asn1, FILE, fp, write) + +# endif + +# define IMPLEMENT_PEM_provided_write_bio(name, TYPE, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_to(name, TYPE, type, str, asn1, BIO, bio, write_bio) +# define IMPLEMENT_PEM_provided_write_cb_bio(name, TYPE, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_cb_to(name, TYPE, type, str, asn1, BIO, bio, write_bio) + +# define IMPLEMENT_PEM_provided_write(name, TYPE, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_bio(name, TYPE, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_fp(name, TYPE, type, str, asn1) + +# define IMPLEMENT_PEM_provided_write_cb(name, TYPE, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_cb_bio(name, TYPE, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_cb_fp(name, TYPE, type, str, asn1) + +# define IMPLEMENT_PEM_provided_rw(name, TYPE, type, str, asn1) \ + IMPLEMENT_PEM_read(name, TYPE, str, asn1) \ + IMPLEMENT_PEM_provided_write(name, TYPE, type, str, asn1) + +# define IMPLEMENT_PEM_provided_rw_cb(name, TYPE, type, str, asn1) \ + IMPLEMENT_PEM_read(name, TYPE, str, asn1) \ + IMPLEMENT_PEM_provided_write_cb(name, TYPE, type, str, asn1) + diff --git a/crypto/openssl/crypto/pem/pem_oth.c b/crypto/openssl/crypto/pem/pem_oth.c index 566205331f8a..db62246174e3 100644 --- a/crypto/openssl/crypto/pem/pem_oth.c +++ b/crypto/openssl/crypto/pem/pem_oth.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -30,7 +30,7 @@ void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, p = data; ret = d2i(x, &p, len); if (ret == NULL) - PEMerr(PEM_F_PEM_ASN1_READ_BIO, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); OPENSSL_free(data); return ret; } diff --git a/crypto/openssl/crypto/pem/pem_pk8.c b/crypto/openssl/crypto/pem/pem_pk8.c index ab6c4c6bde30..1592e351edef 100644 --- a/crypto/openssl/crypto/pem/pem_pk8.c +++ b/crypto/openssl/crypto/pem/pem_pk8.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,21 +9,27 @@ #include #include "internal/cryptlib.h" +#include #include #include #include #include #include #include +#include -static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, +static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u); + const char *kstr, int klen, + pem_password_cb *cb, void *u, + const char *propq); #ifndef OPENSSL_NO_STDIO -static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, +static int do_pk8pkey_fp(FILE *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u); + const char *kstr, int klen, + pem_password_cb *cb, void *u, + const char *propq); #endif /* * These functions write a private key in PKCS#8 format: it is a "drop in" @@ -32,81 +38,132 @@ static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. */ -int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid, + const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); + return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u, NULL); } -int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, +int PEM_write_bio_PKCS8PrivateKey(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, + const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); + return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u, NULL); } -int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, +int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, + const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); + return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u, NULL); } -int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, int nid, + const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); + return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u, NULL); } -static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, - const EVP_CIPHER *enc, char *kstr, int klen, - pem_password_cb *cb, void *u) +static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, const char *kstr, int klen, + pem_password_cb *cb, void *u, const char *propq) { - X509_SIG *p8; - PKCS8_PRIV_KEY_INFO *p8inf; - char buf[PEM_BUFSIZE]; - int ret; + int ret = 0; + const char *outtype = isder ? "DER" : "PEM"; + OSSL_ENCODER_CTX *ctx = + OSSL_ENCODER_CTX_new_for_pkey(x, OSSL_KEYMGMT_SELECT_ALL, + outtype, "PrivateKeyInfo", propq); - if ((p8inf = EVP_PKEY2PKCS8(x)) == NULL) { - PEMerr(PEM_F_DO_PK8PKEY, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + if (ctx == NULL) return 0; + + /* + * If no keystring or callback is set, OpenSSL traditionally uses the + * user's cb argument as a password string, or if that's NULL, it falls + * back on PEM_def_callback(). + */ + if (kstr == NULL && cb == NULL) { + if (u != NULL) { + kstr = u; + klen = strlen(u); + } else { + cb = PEM_def_callback; + } } - if (enc || (nid != -1)) { - if (!kstr) { - if (!cb) - klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); - else - klen = cb(buf, PEM_BUFSIZE, 1, u); - if (klen <= 0) { - PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return 0; - } - kstr = buf; + /* + * NOTE: There is no attempt to do a EVP_CIPHER_fetch() using the nid, + * since the nid is a PBE algorithm which can't be fetched currently. + * (e.g. NID_pbe_WithSHA1And2_Key_TripleDES_CBC). Just use the legacy + * path if the NID is passed. + */ + if (nid == -1 && OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0) { + ret = 1; + if (enc != NULL) { + ret = 0; + if (OSSL_ENCODER_CTX_set_cipher(ctx, EVP_CIPHER_get0_name(enc), + NULL)) { + const unsigned char *ukstr = (const unsigned char *)kstr; + + /* + * Try to pass the passphrase if one was given, or the + * passphrase callback if one was given. If none of them + * are given and that's wrong, we rely on the _to_bio() + * call to generate errors. + */ + ret = 1; + if (kstr != NULL + && !OSSL_ENCODER_CTX_set_passphrase(ctx, ukstr, klen)) + ret = 0; + else if (cb != NULL + && !OSSL_ENCODER_CTX_set_pem_password_cb(ctx, cb, u)) + ret = 0; + } } - p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); - if (kstr == buf) - OPENSSL_cleanse(buf, klen); - PKCS8_PRIV_KEY_INFO_free(p8inf); - if (p8 == NULL) - return 0; - if (isder) - ret = i2d_PKCS8_bio(bp, p8); - else - ret = PEM_write_bio_PKCS8(bp, p8); - X509_SIG_free(p8); - return ret; + ret = ret && OSSL_ENCODER_to_bio(ctx, bp); } else { - if (isder) - ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); - else - ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); + X509_SIG *p8; + PKCS8_PRIV_KEY_INFO *p8inf; + char buf[PEM_BUFSIZE]; + + ret = 0; + if ((p8inf = EVP_PKEY2PKCS8(x)) == NULL) { + ERR_raise(ERR_LIB_PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + goto legacy_end; + } + if (enc || (nid != -1)) { + if (kstr == NULL) { + klen = cb(buf, PEM_BUFSIZE, 1, u); + if (klen < 0) { + ERR_raise(ERR_LIB_PEM, PEM_R_READ_KEY); + goto legacy_end; + } + + kstr = buf; + } + p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); + if (kstr == buf) + OPENSSL_cleanse(buf, klen); + if (p8 == NULL) + goto legacy_end; + if (isder) + ret = i2d_PKCS8_bio(bp, p8); + else + ret = PEM_write_bio_PKCS8(bp, p8); + X509_SIG_free(p8); + } else { + if (isder) + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + else + ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); + } + legacy_end: PKCS8_PRIV_KEY_INFO_free(p8inf); - return ret; } + OSSL_ENCODER_CTX_free(ctx); + return ret; } EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, @@ -117,28 +174,29 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, int klen; EVP_PKEY *ret; char psbuf[PEM_BUFSIZE]; + p8 = d2i_PKCS8_bio(bp, NULL); - if (!p8) + if (p8 == NULL) return NULL; - if (cb) + if (cb != NULL) klen = cb(psbuf, PEM_BUFSIZE, 0, u); else klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); if (klen < 0) { - PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); return NULL; } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); OPENSSL_cleanse(psbuf, klen); - if (!p8inf) + if (p8inf == NULL) return NULL; ret = EVP_PKCS82PKEY(p8inf); PKCS8_PRIV_KEY_INFO_free(p8inf); if (!ret) return NULL; - if (x) { + if (x != NULL) { EVP_PKEY_free(*x); *x = ret; } @@ -147,45 +205,46 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, #ifndef OPENSSL_NO_STDIO -int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u) +int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, + const char *kstr, int klen, + pem_password_cb *cb, void *u) { - return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); + return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u, NULL); } -int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, int nid, + const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); + return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u, NULL); } -int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, int nid, + const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); + return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u, NULL); } -int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, - void *u) +int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, + const char *kstr, int klen, + pem_password_cb *cb, void *u) { - return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); + return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u, NULL); } -static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, - const EVP_CIPHER *enc, char *kstr, int klen, - pem_password_cb *cb, void *u) +static int do_pk8pkey_fp(FILE *fp, const EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, const char *kstr, int klen, + pem_password_cb *cb, void *u, const char *propq) { BIO *bp; int ret; if ((bp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { - PEMerr(PEM_F_DO_PK8PKEY_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); return 0; } - ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); + ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u, propq); BIO_free(bp); return ret; } @@ -197,7 +256,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, EVP_PKEY *ret; if ((bp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { - PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); return NULL; } ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); @@ -211,4 +270,4 @@ IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG) IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, - PKCS8_PRIV_KEY_INFO) + PKCS8_PRIV_KEY_INFO) diff --git a/crypto/openssl/crypto/pem/pem_pkey.c b/crypto/openssl/crypto/pem/pem_pkey.c index 4a9492724487..3e76852c67a4 100644 --- a/crypto/openssl/crypto/pem/pem_pkey.c +++ b/crypto/openssl/crypto/pem/pem_pkey.c @@ -1,14 +1,16 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include -#include "internal/cryptlib.h" #include #include #include @@ -17,13 +19,88 @@ #include #include #include +#include +#include +#include "internal/cryptlib.h" +#include "internal/passphrase.h" #include "crypto/asn1.h" +#include "crypto/x509.h" #include "crypto/evp.h" +#include "pem_local.h" -int pem_check_suffix(const char *pem_str, const char *suffix); +int ossl_pem_check_suffix(const char *pem_str, const char *suffix); -EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, - void *u) +static EVP_PKEY *pem_read_bio_key_decoder(BIO *bp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, + const char *propq, + int selection) +{ + EVP_PKEY *pkey = NULL; + OSSL_DECODER_CTX *dctx = NULL; + int pos, newpos; + + if ((pos = BIO_tell(bp)) < 0) + /* We can depend on BIO_tell() thanks to the BIO_f_readbuffer() */ + return NULL; + + dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "PEM", NULL, NULL, + selection, libctx, propq); + + if (dctx == NULL) + return NULL; + + if (cb == NULL) + cb = PEM_def_callback; + + if (!OSSL_DECODER_CTX_set_pem_password_cb(dctx, cb, u)) + goto err; + + ERR_set_mark(); + while (!OSSL_DECODER_from_bio(dctx, bp) || pkey == NULL) + if (BIO_eof(bp) != 0 || (newpos = BIO_tell(bp)) < 0 || newpos <= pos) { + ERR_clear_last_mark(); + goto err; + } else { + if (ERR_GET_REASON(ERR_peek_error()) == ERR_R_UNSUPPORTED) { + /* unsupported PEM data, try again */ + ERR_pop_to_mark(); + ERR_set_mark(); + } else { + /* other error, bail out */ + ERR_clear_last_mark(); + goto err; + } + pos = newpos; + } + ERR_pop_to_mark(); + + /* if we were asked for private key, the public key is optional */ + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) + selection = selection & ~OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + + if (!evp_keymgmt_util_has(pkey, selection)) { + EVP_PKEY_free(pkey); + pkey = NULL; + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS); + goto err; + } + + if (x != NULL) { + EVP_PKEY_free(*x); + *x = pkey; + } + + err: + OSSL_DECODER_CTX_free(dctx); + return pkey; +} + +static EVP_PKEY *pem_read_bio_key_legacy(BIO *bp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, + const char *propq, + int selection) { char *nm = NULL; const unsigned char *p = NULL; @@ -32,19 +109,37 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, int slen; EVP_PKEY *ret = NULL; - if (!PEM_bytes_read_bio_secmem(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, - cb, u)) - return NULL; + ERR_set_mark(); /* not interested in PEM read errors */ + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + if (!PEM_bytes_read_bio_secmem(&data, &len, &nm, + PEM_STRING_EVP_PKEY, + bp, cb, u)) { + ERR_pop_to_mark(); + return NULL; + } + } else { + const char *pem_string = PEM_STRING_PARAMETERS; + + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) + pem_string = PEM_STRING_PUBLIC; + if (!PEM_bytes_read_bio(&data, &len, &nm, + pem_string, + bp, cb, u)) { + ERR_pop_to_mark(); + return NULL; + } + } + ERR_clear_last_mark(); p = data; if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; - p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); - if (!p8inf) + + if ((p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len)) == NULL) goto p8err; - ret = EVP_PKCS82PKEY(p8inf); - if (x) { - EVP_PKEY_free((EVP_PKEY *)*x); + ret = evp_pkcs82pkey_legacy(p8inf, libctx, propq); + if (x != NULL) { + EVP_PKEY_free(*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); @@ -53,87 +148,43 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, X509_SIG *p8; int klen; char psbuf[PEM_BUFSIZE]; - p8 = d2i_X509_SIG(NULL, &p, len); - if (!p8) + + if ((p8 = d2i_X509_SIG(NULL, &p, len)) == NULL) goto p8err; - if (cb) + if (cb != NULL) klen = cb(psbuf, PEM_BUFSIZE, 0, u); else klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); if (klen < 0) { - PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); goto err; } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); OPENSSL_cleanse(psbuf, klen); - if (!p8inf) + if (p8inf == NULL) goto p8err; - ret = EVP_PKCS82PKEY(p8inf); - if (x) { - EVP_PKEY_free((EVP_PKEY *)*x); + ret = evp_pkcs82pkey_legacy(p8inf, libctx, propq); + if (x != NULL) { + EVP_PKEY_free(*x); *x = ret; } PKCS8_PRIV_KEY_INFO_free(p8inf); - } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) { + } else if ((slen = ossl_pem_check_suffix(nm, "PRIVATE KEY")) > 0) { const EVP_PKEY_ASN1_METHOD *ameth; ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); - if (!ameth || !ameth->old_priv_decode) + if (ameth == NULL || ameth->old_priv_decode == NULL) goto p8err; - ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len); - } - p8err: - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB); - err: - OPENSSL_secure_free(nm); - OPENSSL_secure_clear_free(data, len); - return ret; -} - -int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - if (x->ameth == NULL || x->ameth->priv_encode != NULL) - return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, - (char *)kstr, klen, cb, u); - return PEM_write_bio_PrivateKey_traditional(bp, x, enc, kstr, klen, cb, u); -} - -int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x, - const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - char pem_str[80]; - - if (x->ameth == NULL || x->ameth->old_priv_encode == NULL) { - PEMerr(PEM_F_PEM_WRITE_BIO_PRIVATEKEY_TRADITIONAL, - PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return 0; - } - BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str); - return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, - pem_str, bp, x, enc, kstr, klen, cb, u); -} - -EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) -{ - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - int slen; - EVP_PKEY *ret = NULL; - - if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS, - bp, 0, NULL)) - return NULL; - p = data; - - if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) { + ret = ossl_d2i_PrivateKey_legacy(ameth->pkey_id, x, &p, len, libctx, + propq); + } else if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) == 0 + && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { + /* Trying legacy PUBKEY decoding only if we do not want private key. */ + ret = ossl_d2i_PUBKEY_legacy(x, &p, len); + } else if ((selection & EVP_PKEY_KEYPAIR) == 0 + && (slen = ossl_pem_check_suffix(nm, "PARAMETERS")) > 0) { + /* Trying legacy params decoding only if we do not want a key. */ ret = EVP_PKEY_new(); if (ret == NULL) goto err; @@ -145,107 +196,245 @@ EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) goto err; } if (x) { - EVP_PKEY_free((EVP_PKEY *)*x); + EVP_PKEY_free(*x); *x = ret; } } + + p8err: + if (ret == NULL && ERR_peek_last_error() == 0) + /* ensure some error is reported but do not hide the real one */ + ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); err: - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS, ERR_R_ASN1_LIB); - OPENSSL_free(nm); - OPENSSL_free(data); + OPENSSL_secure_free(nm); + OPENSSL_secure_clear_free(data, len); return ret; } -int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x) +static EVP_PKEY *pem_read_bio_key(BIO *bp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, + const char *propq, + int selection) { - char pem_str[80]; - if (!x->ameth || !x->ameth->param_encode) - return 0; + EVP_PKEY *ret = NULL; + BIO *new_bio = NULL; + int pos; + struct ossl_passphrase_data_st pwdata = { 0 }; - BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str); - return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode, - pem_str, bp, x, NULL, NULL, 0, 0, NULL); + if ((pos = BIO_tell(bp)) < 0) { + new_bio = BIO_new(BIO_f_readbuffer()); + if (new_bio == NULL) + return NULL; + bp = BIO_push(new_bio, bp); + pos = BIO_tell(bp); + } + + if (cb == NULL) + cb = PEM_def_callback; + + if (!ossl_pw_set_pem_password_cb(&pwdata, cb, u) + || !ossl_pw_enable_passphrase_caching(&pwdata)) + goto err; + + ERR_set_mark(); + ret = pem_read_bio_key_decoder(bp, x, ossl_pw_pem_password, &pwdata, + libctx, propq, selection); + if (ret == NULL + && (BIO_seek(bp, pos) < 0 + || (ret = pem_read_bio_key_legacy(bp, x, + ossl_pw_pem_password, &pwdata, + libctx, propq, + selection)) == NULL)) + ERR_clear_last_mark(); + else + ERR_pop_to_mark(); + + err: + ossl_pw_clear_passphrase_data(&pwdata); + if (new_bio != NULL) { + BIO_pop(new_bio); + BIO_free(new_bio); + } + return ret; } -#ifndef OPENSSL_NO_STDIO -EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, +EVP_PKEY *PEM_read_bio_PUBKEY_ex(BIO *bp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return pem_read_bio_key(bp, x, cb, u, libctx, propq, + EVP_PKEY_PUBLIC_KEY); +} + +EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + return PEM_read_bio_PUBKEY_ex(bp, x, cb, u, NULL, NULL); +} + +#ifndef OPENSSL_NO_STDIO +EVP_PKEY *PEM_read_PUBKEY_ex(FILE *fp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq) { BIO *b; EVP_PKEY *ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_READ_PRIVATEKEY, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_read_bio_PrivateKey(b, x, cb, u); + ret = PEM_read_bio_PUBKEY_ex(b, x, cb, u, libctx, propq); BIO_free(b); return ret; } -int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) +EVP_PKEY *PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) { - BIO *b; + return PEM_read_PUBKEY_ex(fp, x, cb, u, NULL, NULL); +} +#endif + +EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return pem_read_bio_key(bp, x, cb, u, libctx, propq, + /* we also want the public key, if available */ + EVP_PKEY_KEYPAIR); +} + +EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + return PEM_read_bio_PrivateKey_ex(bp, x, cb, u, NULL, NULL); +} + +PEM_write_cb_ex_fnsig(PrivateKey, EVP_PKEY, BIO, write_bio) +{ + IMPLEMENT_PEM_provided_write_body_vars(pkey, PrivateKey, propq); + + IMPLEMENT_PEM_provided_write_body_pass(); + IMPLEMENT_PEM_provided_write_body_main(pkey, bio); + + legacy: + if (x != NULL && (x->ameth == NULL || x->ameth->priv_encode != NULL)) + return PEM_write_bio_PKCS8PrivateKey(out, x, enc, + (const char *)kstr, klen, cb, u); + return PEM_write_bio_PrivateKey_traditional(out, x, enc, kstr, klen, cb, u); +} + +PEM_write_cb_fnsig(PrivateKey, EVP_PKEY, BIO, write_bio) +{ + return PEM_write_bio_PrivateKey_ex(out, x, enc, kstr, klen, cb, u, + NULL, NULL); +} + +/* + * Note: there is no way to tell a provided pkey encoder to use "traditional" + * encoding. Therefore, if the pkey is provided, we try to take a copy + */ +int PEM_write_bio_PrivateKey_traditional(BIO *bp, const EVP_PKEY *x, + const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + char pem_str[80]; + EVP_PKEY *copy = NULL; int ret; - if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { - PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY, ERR_R_BUF_LIB); + if (x == NULL) + return 0; + + if (evp_pkey_is_assigned(x) + && evp_pkey_is_provided(x) + && evp_pkey_copy_downgraded(©, x)) + x = copy; + + if (x->ameth == NULL || x->ameth->old_priv_encode == NULL) { + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + EVP_PKEY_free(copy); return 0; } - ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); - BIO_free(b); + BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str); + ret = PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, + pem_str, bp, x, enc, kstr, klen, cb, u); + + EVP_PKEY_free(copy); return ret; } -#endif - -#ifndef OPENSSL_NO_DH +EVP_PKEY *PEM_read_bio_Parameters_ex(BIO *bp, EVP_PKEY **x, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return pem_read_bio_key(bp, x, NULL, NULL, libctx, propq, + EVP_PKEY_KEY_PARAMETERS); +} -/* Transparently read in PKCS#3 or X9.42 DH parameters */ +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) +{ + return PEM_read_bio_Parameters_ex(bp, x, NULL, NULL); +} -DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) +PEM_write_fnsig(Parameters, EVP_PKEY, BIO, write_bio) { - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - DH *ret = NULL; + char pem_str[80]; + IMPLEMENT_PEM_provided_write_body_vars(pkey, Parameters, NULL); - if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u)) - return NULL; - p = data; + IMPLEMENT_PEM_provided_write_body_main(pkey, bio); - if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0) - ret = d2i_DHxparams(x, &p, len); - else - ret = d2i_DHparams(x, &p, len); + legacy: + if (!x->ameth || !x->ameth->param_encode) + return 0; - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_DHPARAMS, ERR_R_ASN1_LIB); - OPENSSL_free(nm); - OPENSSL_free(data); - return ret; + BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str); + return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode, + pem_str, out, x, NULL, NULL, 0, 0, NULL); } -# ifndef OPENSSL_NO_STDIO -DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u) +#ifndef OPENSSL_NO_STDIO +EVP_PKEY *PEM_read_PrivateKey_ex(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u, OSSL_LIB_CTX *libctx, + const char *propq) { BIO *b; - DH *ret; + EVP_PKEY *ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_READ_DHPARAMS, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_read_bio_DHparams(b, x, cb, u); + ret = PEM_read_bio_PrivateKey_ex(b, x, cb, u, libctx, propq); + BIO_free(b); + return ret; +} + +EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + return PEM_read_PrivateKey_ex(fp, x, cb, u, NULL, NULL); +} + +PEM_write_cb_ex_fnsig(PrivateKey, EVP_PKEY, FILE, write) +{ + BIO *b; + int ret; + + if ((b = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) { + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); + return 0; + } + ret = PEM_write_bio_PrivateKey_ex(b, x, enc, kstr, klen, cb, u, + libctx, propq); BIO_free(b); return ret; } -# endif +PEM_write_cb_fnsig(PrivateKey, EVP_PKEY, FILE, write) +{ + return PEM_write_PrivateKey_ex(out, x, enc, kstr, klen, cb, u, NULL, NULL); +} #endif diff --git a/crypto/openssl/crypto/pem/pem_sign.c b/crypto/openssl/crypto/pem/pem_sign.c index 7e7b32ebf7d0..6ad8e4303721 100644 --- a/crypto/openssl/crypto/pem/pem_sign.c +++ b/crypto/openssl/crypto/pem/pem_sign.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,7 +19,8 @@ int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) return EVP_DigestInit_ex(ctx, type, NULL); } -int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count) +int PEM_SignUpdate(EVP_MD_CTX *ctx, + const unsigned char *data, unsigned int count) { return EVP_DigestUpdate(ctx, data, count); } @@ -31,9 +32,9 @@ int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, int i, ret = 0; unsigned int m_len; - m = OPENSSL_malloc(EVP_PKEY_size(pkey)); + m = OPENSSL_malloc(EVP_PKEY_get_size(pkey)); if (m == NULL) { - PEMerr(PEM_F_PEM_SIGNFINAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); goto err; } diff --git a/crypto/openssl/crypto/pem/pem_x509.c b/crypto/openssl/crypto/pem/pem_x509.c index 3a997564a23f..93978ee24558 100644 --- a/crypto/openssl/crypto/pem/pem_x509.c +++ b/crypto/openssl/crypto/pem/pem_x509.c @@ -1,7 +1,7 @@ /* * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/pem/pem_xaux.c b/crypto/openssl/crypto/pem/pem_xaux.c index 6d7e1db21afe..d416f088e398 100644 --- a/crypto/openssl/crypto/pem/pem_xaux.c +++ b/crypto/openssl/crypto/pem/pem_xaux.c @@ -1,7 +1,7 @@ /* * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/pem/pvkfmt.c b/crypto/openssl/crypto/pem/pvkfmt.c index a933b7c1813c..21b16f5928c1 100644 --- a/crypto/openssl/crypto/pem/pvkfmt.c +++ b/crypto/openssl/crypto/pem/pvkfmt.c @@ -1,7 +1,7 @@ /* - * Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,13 +12,20 @@ * and PRIVATEKEYBLOB). */ -#include "internal/cryptlib.h" +/* + * RSA and DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include -#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) -# include -# include +#include +#include +#include "internal/cryptlib.h" +#include "crypto/pem.h" +#include "crypto/evp.h" /* * Utility function: read a DWORD (4 byte unsigned integer) in little endian @@ -29,6 +36,7 @@ static unsigned int read_ledword(const unsigned char **in) { const unsigned char *p = *in; unsigned int ret; + ret = (unsigned int)*p++; ret |= (unsigned int)*p++ << 8; ret |= (unsigned int)*p++ << 16; @@ -51,6 +59,65 @@ static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) return 1; } +/* + * Create an EVP_PKEY from a type specific key. + * This takes ownership of |key|, as long as the |evp_type| is acceptable + * (EVP_PKEY_RSA or EVP_PKEY_DSA), even if the resulting EVP_PKEY wasn't + * created. + */ +#define isdss_to_evp_type(isdss) \ + (isdss == 0 ? EVP_PKEY_RSA : isdss == 1 ? EVP_PKEY_DSA : EVP_PKEY_NONE) +static EVP_PKEY *evp_pkey_new0_key(void *key, int evp_type) +{ + EVP_PKEY *pkey = NULL; + + /* + * It's assumed that if |key| is NULL, something went wrong elsewhere + * and suitable errors are already reported. + */ + if (key == NULL) + return NULL; + + if (!ossl_assert(evp_type == EVP_PKEY_RSA || evp_type == EVP_PKEY_DSA)) { + ERR_raise(ERR_LIB_PEM, ERR_R_INTERNAL_ERROR); + return NULL; + } + + if ((pkey = EVP_PKEY_new()) != NULL) { + switch (evp_type) { + case EVP_PKEY_RSA: + if (EVP_PKEY_set1_RSA(pkey, key)) + break; + EVP_PKEY_free(pkey); + pkey = NULL; + break; +#ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + if (EVP_PKEY_set1_DSA(pkey, key)) + break; + EVP_PKEY_free(pkey); + pkey = NULL; + break; +#endif + } + } + + switch (evp_type) { + case EVP_PKEY_RSA: + RSA_free(key); + break; +#ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + DSA_free(key); + break; +#endif + } + + if (pkey == NULL) + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + return pkey; +} + /* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */ # define MS_PUBLICKEYBLOB 0x6 @@ -66,9 +133,6 @@ static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) # define MS_KEYTYPE_KEYX 0x1 # define MS_KEYTYPE_SIGN 0x2 -/* Maximum length of a blob after header */ -# define BLOB_MAX_LENGTH 102400 - /* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */ # define MS_PVKMAGIC 0xb0b5f11eL /* Salt length for PVK files */ @@ -78,79 +142,115 @@ static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) /* Maximum salt length */ # define PVK_MAX_SALTLEN 10240 -static EVP_PKEY *b2i_rsa(const unsigned char **in, - unsigned int bitlen, int ispub); -static EVP_PKEY *b2i_dss(const unsigned char **in, - unsigned int bitlen, int ispub); - -static int do_blob_header(const unsigned char **in, unsigned int length, - unsigned int *pmagic, unsigned int *pbitlen, - int *pisdss, int *pispub) +/* + * Read the MSBLOB header and get relevant data from it. + * + * |pisdss| and |pispub| have a double role, as they can be used for + * discovery as well as to check the the blob meets expectations. + * |*pisdss| is the indicator for whether the key is a DSA key or not. + * |*pispub| is the indicator for whether the key is public or not. + * In both cases, the following input values apply: + * + * 0 Expected to not be what the variable indicates. + * 1 Expected to be what the variable indicates. + * -1 No expectations, this function will assign 0 or 1 depending on + * header data. + */ +int ossl_do_blob_header(const unsigned char **in, unsigned int length, + unsigned int *pmagic, unsigned int *pbitlen, + int *pisdss, int *pispub) { const unsigned char *p = *in; + if (length < 16) return 0; /* bType */ - if (*p == MS_PUBLICKEYBLOB) { + switch (*p) { + case MS_PUBLICKEYBLOB: if (*pispub == 0) { - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); + ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); return 0; } *pispub = 1; - } else if (*p == MS_PRIVATEKEYBLOB) { + break; + + case MS_PRIVATEKEYBLOB: if (*pispub == 1) { - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); + ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); return 0; } *pispub = 0; - } else + break; + + default: return 0; + } p++; /* Version */ if (*p++ != 0x2) { - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_VERSION_NUMBER); return 0; } /* Ignore reserved, aiKeyAlg */ p += 6; *pmagic = read_ledword(&p); *pbitlen = read_ledword(&p); - *pisdss = 0; - switch (*pmagic) { + /* Consistency check for private vs public */ + switch (*pmagic) { case MS_DSS1MAGIC: - *pisdss = 1; - /* fall thru */ case MS_RSA1MAGIC: if (*pispub == 0) { - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); + ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); return 0; } break; case MS_DSS2MAGIC: - *pisdss = 1; - /* fall thru */ case MS_RSA2MAGIC: if (*pispub == 1) { - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); + ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); return 0; } break; default: - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER); + return -1; + } + + /* Check that we got the expected type */ + switch (*pmagic) { + case MS_DSS1MAGIC: + case MS_DSS2MAGIC: + if (*pisdss == 0) { + ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_DSS_KEY_BLOB); + return 0; + } + *pisdss = 1; + break; + case MS_RSA1MAGIC: + case MS_RSA2MAGIC: + if (*pisdss == 1) { + ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_RSA_KEY_BLOB); + return 0; + } + *pisdss = 0; + break; + + default: + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER); return -1; } *in = p; return 1; } -static unsigned int blob_length(unsigned bitlen, int isdss, int ispub) +unsigned int ossl_blob_length(unsigned bitlen, int isdss, int ispub) { - unsigned int nbyte, hnbyte; - nbyte = (bitlen + 7) >> 3; - hnbyte = (bitlen + 15) >> 4; + unsigned int nbyte = (bitlen + 7) >> 3; + unsigned int hnbyte = (bitlen + 15) >> 4; + if (isdss) { /* @@ -179,84 +279,109 @@ static unsigned int blob_length(unsigned bitlen, int isdss, int ispub) } -static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length, - int ispub) +static void *do_b2i_key(const unsigned char **in, unsigned int length, + int *isdss, int *ispub) { const unsigned char *p = *in; unsigned int bitlen, magic; - int isdss; - if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) { - PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR); + void *key = NULL; + + if (ossl_do_blob_header(&p, length, &magic, &bitlen, isdss, ispub) <= 0) { + ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_HEADER_PARSE_ERROR); return NULL; } length -= 16; - if (length < blob_length(bitlen, isdss, ispub)) { - PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT); + if (length < ossl_blob_length(bitlen, *isdss, *ispub)) { + ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT); return NULL; } - if (isdss) - return b2i_dss(&p, bitlen, ispub); + if (!*isdss) + key = ossl_b2i_RSA_after_header(&p, bitlen, *ispub); +#ifndef OPENSSL_NO_DSA else - return b2i_rsa(&p, bitlen, ispub); + key = ossl_b2i_DSA_after_header(&p, bitlen, *ispub); +#endif + + if (key == NULL) { + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return NULL; + } + + return key; } -static EVP_PKEY *do_b2i_bio(BIO *in, int ispub) +EVP_PKEY *ossl_b2i(const unsigned char **in, unsigned int length, int *ispub) +{ + int isdss = -1; + void *key = do_b2i_key(in, length, &isdss, ispub); + + return evp_pkey_new0_key(key, isdss_to_evp_type(isdss)); +} + +EVP_PKEY *ossl_b2i_bio(BIO *in, int *ispub) { const unsigned char *p; unsigned char hdr_buf[16], *buf = NULL; unsigned int bitlen, magic, length; - int isdss; - EVP_PKEY *ret = NULL; + int isdss = -1; + void *key = NULL; + EVP_PKEY *pkey = NULL; + if (BIO_read(in, hdr_buf, 16) != 16) { - PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); + ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT); return NULL; } p = hdr_buf; - if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0) + if (ossl_do_blob_header(&p, 16, &magic, &bitlen, &isdss, ispub) <= 0) return NULL; - length = blob_length(bitlen, isdss, ispub); + length = ossl_blob_length(bitlen, isdss, *ispub); if (length > BLOB_MAX_LENGTH) { - PEMerr(PEM_F_DO_B2I_BIO, PEM_R_HEADER_TOO_LONG); + ERR_raise(ERR_LIB_PEM, PEM_R_HEADER_TOO_LONG); return NULL; } buf = OPENSSL_malloc(length); if (buf == NULL) { - PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); goto err; } p = buf; if (BIO_read(in, buf, length) != (int)length) { - PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); + ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT); goto err; } - if (isdss) - ret = b2i_dss(&p, bitlen, ispub); + if (!isdss) + key = ossl_b2i_RSA_after_header(&p, bitlen, *ispub); +#ifndef OPENSSL_NO_DSA else - ret = b2i_rsa(&p, bitlen, ispub); + key = ossl_b2i_DSA_after_header(&p, bitlen, *ispub); +#endif + if (key == NULL) { + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + goto err; + } + + pkey = evp_pkey_new0_key(key, isdss_to_evp_type(isdss)); err: OPENSSL_free(buf); - return ret; + return pkey; } -static EVP_PKEY *b2i_dss(const unsigned char **in, - unsigned int bitlen, int ispub) +#ifndef OPENSSL_NO_DSA +DSA *ossl_b2i_DSA_after_header(const unsigned char **in, unsigned int bitlen, + int ispub) { const unsigned char *p = *in; - EVP_PKEY *ret = NULL; DSA *dsa = NULL; BN_CTX *ctx = NULL; - unsigned int nbyte; BIGNUM *pbn = NULL, *qbn = NULL, *gbn = NULL, *priv_key = NULL; BIGNUM *pub_key = NULL; - - nbyte = (bitlen + 7) >> 3; + unsigned int nbyte = (bitlen + 7) >> 3; dsa = DSA_new(); - ret = EVP_PKEY_new(); - if (dsa == NULL || ret == NULL) + if (dsa == NULL) goto memerr; if (!read_lebn(&p, nbyte, &pbn)) goto memerr; @@ -297,39 +422,34 @@ static EVP_PKEY *b2i_dss(const unsigned char **in, goto memerr; pub_key = priv_key = NULL; - if (!EVP_PKEY_set1_DSA(ret, dsa)) - goto memerr; - DSA_free(dsa); *in = p; - return ret; + return dsa; memerr: - PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); DSA_free(dsa); BN_free(pbn); BN_free(qbn); BN_free(gbn); BN_free(pub_key); BN_free(priv_key); - EVP_PKEY_free(ret); BN_CTX_free(ctx); return NULL; } +#endif -static EVP_PKEY *b2i_rsa(const unsigned char **in, - unsigned int bitlen, int ispub) +RSA *ossl_b2i_RSA_after_header(const unsigned char **in, unsigned int bitlen, + int ispub) { const unsigned char *pin = *in; - EVP_PKEY *ret = NULL; BIGNUM *e = NULL, *n = NULL, *d = NULL; BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; RSA *rsa = NULL; - unsigned int nbyte, hnbyte; - nbyte = (bitlen + 7) >> 3; - hnbyte = (bitlen + 15) >> 4; + unsigned int nbyte = (bitlen + 7) >> 3; + unsigned int hnbyte = (bitlen + 15) >> 4; + rsa = RSA_new(); - ret = EVP_PKEY_new(); - if (rsa == NULL || ret == NULL) + if (rsa == NULL) goto memerr; e = BN_new(); if (e == NULL) @@ -362,13 +482,10 @@ static EVP_PKEY *b2i_rsa(const unsigned char **in, goto memerr; n = e = d = NULL; - if (!EVP_PKEY_set1_RSA(ret, rsa)) - goto memerr; - RSA_free(rsa); *in = pin; - return ret; + return rsa; memerr: - PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); BN_free(e); BN_free(n); BN_free(p); @@ -378,33 +495,41 @@ static EVP_PKEY *b2i_rsa(const unsigned char **in, BN_free(iqmp); BN_free(d); RSA_free(rsa); - EVP_PKEY_free(ret); return NULL; } EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length) { - return do_b2i(in, length, 0); + int ispub = 0; + + return ossl_b2i(in, length, &ispub); } EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length) { - return do_b2i(in, length, 1); + int ispub = 1; + + return ossl_b2i(in, length, &ispub); } EVP_PKEY *b2i_PrivateKey_bio(BIO *in) { - return do_b2i_bio(in, 0); + int ispub = 0; + + return ossl_b2i_bio(in, &ispub); } EVP_PKEY *b2i_PublicKey_bio(BIO *in) { - return do_b2i_bio(in, 1); + int ispub = 1; + + return ossl_b2i_bio(in, &ispub); } static void write_ledword(unsigned char **out, unsigned int dw) { unsigned char *p = *out; + *p++ = dw & 0xff; *p++ = (dw >> 8) & 0xff; *p++ = (dw >> 16) & 0xff; @@ -418,38 +543,43 @@ static void write_lebn(unsigned char **out, const BIGNUM *bn, int len) *out += len; } -static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic); -static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic); +static int check_bitlen_rsa(const RSA *rsa, int ispub, unsigned int *magic); +static void write_rsa(unsigned char **out, const RSA *rsa, int ispub); -static void write_rsa(unsigned char **out, RSA *rsa, int ispub); -static void write_dsa(unsigned char **out, DSA *dsa, int ispub); +#ifndef OPENSSL_NO_DSA +static int check_bitlen_dsa(const DSA *dsa, int ispub, unsigned int *magic); +static void write_dsa(unsigned char **out, const DSA *dsa, int ispub); +#endif -static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) +static int do_i2b(unsigned char **out, const EVP_PKEY *pk, int ispub) { unsigned char *p; - unsigned int bitlen, magic = 0, keyalg; - int outlen, noinc = 0; - int pktype = EVP_PKEY_id(pk); - if (pktype == EVP_PKEY_DSA) { - bitlen = check_bitlen_dsa(EVP_PKEY_get0_DSA(pk), ispub, &magic); - keyalg = MS_KEYALG_DSS_SIGN; - } else if (pktype == EVP_PKEY_RSA) { + unsigned int bitlen = 0, magic = 0, keyalg = 0; + int outlen = -1, noinc = 0; + + if (EVP_PKEY_is_a(pk, "RSA")) { bitlen = check_bitlen_rsa(EVP_PKEY_get0_RSA(pk), ispub, &magic); keyalg = MS_KEYALG_RSA_KEYX; - } else - return -1; - if (bitlen == 0) - return -1; - outlen = 16 + blob_length(bitlen, - keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); +#ifndef OPENSSL_NO_DSA + } else if (EVP_PKEY_is_a(pk, "DSA")) { + bitlen = check_bitlen_dsa(EVP_PKEY_get0_DSA(pk), ispub, &magic); + keyalg = MS_KEYALG_DSS_SIGN; +#endif + } + if (bitlen == 0) { + goto end; + } + outlen = 16 + + ossl_blob_length(bitlen, keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); if (out == NULL) - return outlen; + goto end; if (*out) p = *out; else { if ((p = OPENSSL_malloc(outlen)) == NULL) { - PEMerr(PEM_F_DO_I2B, ERR_R_MALLOC_FAILURE); - return -1; + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + outlen = -1; + goto end; } *out = p; noinc = 1; @@ -464,19 +594,23 @@ static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) write_ledword(&p, keyalg); write_ledword(&p, magic); write_ledword(&p, bitlen); - if (keyalg == MS_KEYALG_DSS_SIGN) - write_dsa(&p, EVP_PKEY_get0_DSA(pk), ispub); - else + if (keyalg == MS_KEYALG_RSA_KEYX) write_rsa(&p, EVP_PKEY_get0_RSA(pk), ispub); +#ifndef OPENSSL_NO_DSA + else + write_dsa(&p, EVP_PKEY_get0_DSA(pk), ispub); +#endif if (!noinc) *out += outlen; + end: return outlen; } -static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub) +static int do_i2b_bio(BIO *out, const EVP_PKEY *pk, int ispub) { unsigned char *tmp = NULL; int outlen, wrlen; + outlen = do_i2b(&tmp, pk, ispub); if (outlen < 0) return -1; @@ -487,35 +621,7 @@ static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub) return -1; } -static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic) -{ - int bitlen; - const BIGNUM *p = NULL, *q = NULL, *g = NULL; - const BIGNUM *pub_key = NULL, *priv_key = NULL; - - DSA_get0_pqg(dsa, &p, &q, &g); - DSA_get0_key(dsa, &pub_key, &priv_key); - bitlen = BN_num_bits(p); - if ((bitlen & 7) || (BN_num_bits(q) != 160) - || (BN_num_bits(g) > bitlen)) - goto badkey; - if (ispub) { - if (BN_num_bits(pub_key) > bitlen) - goto badkey; - *pmagic = MS_DSS1MAGIC; - } else { - if (BN_num_bits(priv_key) > 160) - goto badkey; - *pmagic = MS_DSS2MAGIC; - } - - return bitlen; - badkey: - PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); - return 0; -} - -static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) +static int check_bitlen_rsa(const RSA *rsa, int ispub, unsigned int *pmagic) { int nbyte, hnbyte, bitlen; const BIGNUM *e; @@ -551,11 +657,11 @@ static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) } return bitlen; badkey: - PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS); return 0; } -static void write_rsa(unsigned char **out, RSA *rsa, int ispub) +static void write_rsa(unsigned char **out, const RSA *rsa, int ispub) { int nbyte, hnbyte; const BIGNUM *n, *d, *e, *p, *q, *iqmp, *dmp1, *dmq1; @@ -577,7 +683,36 @@ static void write_rsa(unsigned char **out, RSA *rsa, int ispub) write_lebn(out, d, nbyte); } -static void write_dsa(unsigned char **out, DSA *dsa, int ispub) +#ifndef OPENSSL_NO_DSA +static int check_bitlen_dsa(const DSA *dsa, int ispub, unsigned int *pmagic) +{ + int bitlen; + const BIGNUM *p = NULL, *q = NULL, *g = NULL; + const BIGNUM *pub_key = NULL, *priv_key = NULL; + + DSA_get0_pqg(dsa, &p, &q, &g); + DSA_get0_key(dsa, &pub_key, &priv_key); + bitlen = BN_num_bits(p); + if ((bitlen & 7) || (BN_num_bits(q) != 160) + || (BN_num_bits(g) > bitlen)) + goto badkey; + if (ispub) { + if (BN_num_bits(pub_key) > bitlen) + goto badkey; + *pmagic = MS_DSS1MAGIC; + } else { + if (BN_num_bits(priv_key) > 160) + goto badkey; + *pmagic = MS_DSS2MAGIC; + } + + return bitlen; + badkey: + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS); + return 0; +} + +static void write_dsa(unsigned char **out, const DSA *dsa, int ispub) { int nbyte; const BIGNUM *p = NULL, *q = NULL, *g = NULL; @@ -598,38 +733,38 @@ static void write_dsa(unsigned char **out, DSA *dsa, int ispub) *out += 24; return; } +#endif -int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk) +int i2b_PrivateKey_bio(BIO *out, const EVP_PKEY *pk) { return do_i2b_bio(out, pk, 0); } -int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk) +int i2b_PublicKey_bio(BIO *out, const EVP_PKEY *pk) { return do_i2b_bio(out, pk, 1); } -# ifndef OPENSSL_NO_RC4 - -static int do_PVK_header(const unsigned char **in, unsigned int length, - int skip_magic, - unsigned int *psaltlen, unsigned int *pkeylen) +int ossl_do_PVK_header(const unsigned char **in, unsigned int length, + int skip_magic, + unsigned int *psaltlen, unsigned int *pkeylen) { const unsigned char *p = *in; unsigned int pvk_magic, is_encrypted; + if (skip_magic) { if (length < 20) { - PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); + ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT); return 0; } } else { if (length < 24) { - PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); + ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT); return 0; } pvk_magic = read_ledword(&p); if (pvk_magic != MS_PVKMAGIC) { - PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER); return 0; } } @@ -645,8 +780,8 @@ static int do_PVK_header(const unsigned char **in, unsigned int length, if (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN) return 0; - if (is_encrypted && !*psaltlen) { - PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER); + if (is_encrypted && *psaltlen == 0) { + ERR_raise(ERR_LIB_PEM, PEM_R_INCONSISTENT_HEADER); return 0; } @@ -654,64 +789,90 @@ static int do_PVK_header(const unsigned char **in, unsigned int length, return 1; } +#ifndef OPENSSL_NO_RC4 static int derive_pvk_key(unsigned char *key, const unsigned char *salt, unsigned int saltlen, - const unsigned char *pass, int passlen) + const unsigned char *pass, int passlen, + OSSL_LIB_CTX *libctx, const char *propq) { EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - int rv = 1; + int rv = 0; + EVP_MD *sha1 = NULL; + + if ((sha1 = EVP_MD_fetch(libctx, SN_sha1, propq)) == NULL) + goto err; + if (mctx == NULL - || !EVP_DigestInit_ex(mctx, EVP_sha1(), NULL) + || !EVP_DigestInit_ex(mctx, sha1, NULL) || !EVP_DigestUpdate(mctx, salt, saltlen) || !EVP_DigestUpdate(mctx, pass, passlen) || !EVP_DigestFinal_ex(mctx, key, NULL)) - rv = 0; + goto err; + rv = 1; +err: EVP_MD_CTX_free(mctx); + EVP_MD_free(sha1); return rv; } +#endif -static EVP_PKEY *do_PVK_body(const unsigned char **in, +static void *do_PVK_body_key(const unsigned char **in, unsigned int saltlen, unsigned int keylen, - pem_password_cb *cb, void *u) + pem_password_cb *cb, void *u, + int *isdss, int *ispub, + OSSL_LIB_CTX *libctx, const char *propq) { - EVP_PKEY *ret = NULL; const unsigned char *p = *in; - unsigned int magic; - unsigned char *enctmp = NULL, *q; + unsigned char *enctmp = NULL; unsigned char keybuf[20]; - + void *key = NULL; +#ifndef OPENSSL_NO_RC4 + EVP_CIPHER *rc4 = NULL; +#endif EVP_CIPHER_CTX *cctx = EVP_CIPHER_CTX_new(); + + if (cctx == NULL) { + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + if (saltlen) { +#ifndef OPENSSL_NO_RC4 + unsigned int magic; char psbuf[PEM_BUFSIZE]; int enctmplen, inlen; + unsigned char *q; + if (cb) inlen = cb(psbuf, PEM_BUFSIZE, 0, u); else inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); if (inlen < 0) { - PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ); goto err; } enctmp = OPENSSL_malloc(keylen + 8); if (enctmp == NULL) { - PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); goto err; } if (!derive_pvk_key(keybuf, p, saltlen, - (unsigned char *)psbuf, inlen)) + (unsigned char *)psbuf, inlen, libctx, propq)) goto err; p += saltlen; /* Copy BLOBHEADER across, decrypt rest */ memcpy(enctmp, p, 8); p += 8; if (keylen < 8) { - PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT); + ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT); goto err; } inlen = keylen - 8; q = enctmp + 8; - if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL)) + if ((rc4 = EVP_CIPHER_fetch(libctx, "RC4", propq)) == NULL) + goto err; + if (!EVP_DecryptInit_ex(cctx, rc4, NULL, keybuf, NULL)) goto err; if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen)) goto err; @@ -721,7 +882,7 @@ static EVP_PKEY *do_PVK_body(const unsigned char **in, if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { q = enctmp + 8; memset(keybuf + 5, 0, 11); - if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL)) + if (!EVP_DecryptInit_ex(cctx, rc4, NULL, keybuf, NULL)) goto err; if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen)) goto err; @@ -729,62 +890,124 @@ static EVP_PKEY *do_PVK_body(const unsigned char **in, goto err; magic = read_ledword((const unsigned char **)&q); if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { - PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_DECRYPT); goto err; } } p = enctmp; +#else + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER); + goto err; +#endif } - ret = b2i_PrivateKey(&p, keylen); + key = do_b2i_key(&p, keylen, isdss, ispub); err: EVP_CIPHER_CTX_free(cctx); +#ifndef OPENSSL_NO_RC4 + EVP_CIPHER_free(rc4); +#endif if (enctmp != NULL) { OPENSSL_cleanse(keybuf, sizeof(keybuf)); OPENSSL_free(enctmp); } - return ret; + return key; } -EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u) +static void *do_PVK_key_bio(BIO *in, pem_password_cb *cb, void *u, + int *isdss, int *ispub, + OSSL_LIB_CTX *libctx, const char *propq) { unsigned char pvk_hdr[24], *buf = NULL; const unsigned char *p; int buflen; - EVP_PKEY *ret = NULL; + void *key = NULL; unsigned int saltlen, keylen; + if (BIO_read(in, pvk_hdr, 24) != 24) { - PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); + ERR_raise(ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT); return NULL; } p = pvk_hdr; - if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen)) + if (!ossl_do_PVK_header(&p, 24, 0, &saltlen, &keylen)) return 0; buflen = (int)keylen + saltlen; buf = OPENSSL_malloc(buflen); if (buf == NULL) { - PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); return 0; } p = buf; if (BIO_read(in, buf, buflen) != buflen) { - PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); + ERR_raise(ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT); goto err; } - ret = do_PVK_body(&p, saltlen, keylen, cb, u); + key = do_PVK_body_key(&p, saltlen, keylen, cb, u, isdss, ispub, libctx, propq); err: OPENSSL_clear_free(buf, buflen); - return ret; + return key; +} + +#ifndef OPENSSL_NO_DSA +DSA *b2i_DSA_PVK_bio_ex(BIO *in, pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int isdss = 1; + int ispub = 0; /* PVK keys are always private */ + + return do_PVK_key_bio(in, cb, u, &isdss, &ispub, libctx, propq); +} + +DSA *b2i_DSA_PVK_bio(BIO *in, pem_password_cb *cb, void *u) +{ + return b2i_DSA_PVK_bio_ex(in, cb, u, NULL, NULL); +} +#endif + +RSA *b2i_RSA_PVK_bio_ex(BIO *in, pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int isdss = 0; + int ispub = 0; /* PVK keys are always private */ + + return do_PVK_key_bio(in, cb, u, &isdss, &ispub, libctx, propq); } -static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, - pem_password_cb *cb, void *u) +RSA *b2i_RSA_PVK_bio(BIO *in, pem_password_cb *cb, void *u) +{ + return b2i_RSA_PVK_bio_ex(in, cb, u, NULL, NULL); +} + +EVP_PKEY *b2i_PVK_bio_ex(BIO *in, pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int isdss = -1; + int ispub = -1; + void *key = do_PVK_key_bio(in, cb, u, &isdss, &ispub, NULL, NULL); + + return evp_pkey_new0_key(key, isdss_to_evp_type(isdss)); +} + +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u) { + return b2i_PVK_bio_ex(in, cb, u, NULL, NULL); +} + +static int i2b_PVK(unsigned char **out, const EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u, OSSL_LIB_CTX *libctx, + const char *propq) +{ + int ret = -1; int outlen = 24, pklen; - unsigned char *p = NULL, *start = NULL, *salt = NULL; + unsigned char *p = NULL, *start = NULL; EVP_CIPHER_CTX *cctx = NULL; +#ifndef OPENSSL_NO_RC4 + unsigned char *salt = NULL; + EVP_CIPHER *rc4 = NULL; +#endif + if (enclevel) outlen += PVK_SALTLEN; pklen = do_i2b(NULL, pk, 0); @@ -798,7 +1021,7 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, } else { start = p = OPENSSL_malloc(outlen); if (p == NULL) { - PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); return -1; } } @@ -809,21 +1032,26 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, write_ledword(&p, MS_PVKMAGIC); write_ledword(&p, 0); - if (EVP_PKEY_id(pk) == EVP_PKEY_DSA) - write_ledword(&p, MS_KEYTYPE_SIGN); - else + if (EVP_PKEY_get_id(pk) == EVP_PKEY_RSA) write_ledword(&p, MS_KEYTYPE_KEYX); +#ifndef OPENSSL_NO_DSA + else + write_ledword(&p, MS_KEYTYPE_SIGN); +#endif write_ledword(&p, enclevel ? 1 : 0); write_ledword(&p, enclevel ? PVK_SALTLEN : 0); write_ledword(&p, pklen); if (enclevel) { - if (RAND_bytes(p, PVK_SALTLEN) <= 0) +#ifndef OPENSSL_NO_RC4 + if (RAND_bytes_ex(libctx, p, PVK_SALTLEN, 0) <= 0) goto error; salt = p; p += PVK_SALTLEN; +#endif } do_i2b(&p, pk, 0); if (enclevel != 0) { +#ifndef OPENSSL_NO_RC4 char psbuf[PEM_BUFSIZE]; unsigned char keybuf[20]; int enctmplen, inlen; @@ -832,44 +1060,52 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, else inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u); if (inlen <= 0) { - PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ); + ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ); goto error; } if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, - (unsigned char *)psbuf, inlen)) + (unsigned char *)psbuf, inlen, libctx, propq)) + goto error; + if ((rc4 = EVP_CIPHER_fetch(libctx, "RC4", propq)) == NULL) goto error; if (enclevel == 1) memset(keybuf + 5, 0, 11); p = salt + PVK_SALTLEN + 8; - if (!EVP_EncryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL)) + if (!EVP_EncryptInit_ex(cctx, rc4, NULL, keybuf, NULL)) goto error; OPENSSL_cleanse(keybuf, 20); if (!EVP_EncryptUpdate(cctx, p, &enctmplen, p, pklen - 8)) goto error; if (!EVP_EncryptFinal_ex(cctx, p + enctmplen, &enctmplen)) goto error; +#else + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER); + goto error; +#endif } - EVP_CIPHER_CTX_free(cctx); - if (*out == NULL) *out = start; - - return outlen; - + ret = outlen; error: EVP_CIPHER_CTX_free(cctx); +#ifndef OPENSSL_NO_RC4 + EVP_CIPHER_free(rc4); +#endif if (*out == NULL) OPENSSL_free(start); - return -1; + + return ret; } -int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, - pem_password_cb *cb, void *u) +int i2b_PVK_bio_ex(BIO *out, const EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u, OSSL_LIB_CTX *libctx, + const char *propq) { unsigned char *tmp = NULL; int outlen, wrlen; - outlen = i2b_PVK(&tmp, pk, enclevel, cb, u); + + outlen = i2b_PVK(&tmp, pk, enclevel, cb, u, libctx, propq); if (outlen < 0) return -1; wrlen = BIO_write(out, tmp, outlen); @@ -877,10 +1113,13 @@ int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, if (wrlen == outlen) { return outlen; } - PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE); + ERR_raise(ERR_LIB_PEM, PEM_R_BIO_WRITE_FAILURE); return -1; } -# endif +int i2b_PVK_bio(BIO *out, const EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u) +{ + return i2b_PVK_bio_ex(out, pk, enclevel, cb, u, NULL, NULL); +} -#endif diff --git a/crypto/openssl/crypto/perlasm/README b/crypto/openssl/crypto/perlasm/README deleted file mode 100644 index 59f2c95515fe..000000000000 --- a/crypto/openssl/crypto/perlasm/README +++ /dev/null @@ -1,124 +0,0 @@ -The perl scripts in this directory are my 'hack' to generate -multiple different assembler formats via the one original script. - -The way to use this library is to start with adding the path to this directory -and then include it. - -push(@INC,"perlasm","../../perlasm"); -require "x86asm.pl"; - -The first thing we do is setup the file and type of assembler - -&asm_init($ARGV[0]); - -The first argument is the 'type'. Currently -'cpp', 'sol', 'a.out', 'elf' or 'win32'. -Argument 2 is the file name. - -The reciprocal function is -&asm_finish() which should be called at the end. - -There are 2 main 'packages'. x86ms.pl, which is the Microsoft assembler, -and x86unix.pl which is the unix (gas) version. - -Functions of interest are: -&external_label("des_SPtrans"); declare and external variable -&LB(reg); Low byte for a register -&HB(reg); High byte for a register -&BP(off,base,index,scale) Byte pointer addressing -&DWP(off,base,index,scale) Word pointer addressing -&stack_push(num) Basically a 'sub esp, num*4' with extra -&stack_pop(num) inverse of stack_push -&function_begin(name,extra) Start a function with pushing of - edi, esi, ebx and ebp. extra is extra win32 - external info that may be required. -&function_begin_B(name,extra) Same as normal function_begin but no pushing. -&function_end(name) Call at end of function. -&function_end_A(name) Standard pop and ret, for use inside functions -&function_end_B(name) Call at end but with pop or ret. -&swtmp(num) Address on stack temp word. -&wparam(num) Parameter number num, that was push - in C convention. This all works over pushes - and pops. -&comment("hello there") Put in a comment. -&label("loop") Refer to a label, normally a jmp target. -&set_label("loop") Set a label at this point. -&data_word(word) Put in a word of data. - -So how does this all hold together? Given - -int calc(int len, int *data) - { - int i,j=0; - - for (i=0; i) { if ($line =~ m/^\s*(#|@|\/\/)/) { print $line; next; } $line =~ s|/\*.*\*/||; # get rid of C-style comments... - $line =~ s|^\s+||; # ... and skip white spaces in beginning... + $line =~ s|^\s+||; # ... and skip whitespace in beginning... $line =~ s|\s+$||; # ... and at the end { diff --git a/crypto/openssl/crypto/perlasm/cbc.pl b/crypto/openssl/crypto/perlasm/cbc.pl index 01bafe457d68..ef09e0fd297a 100755 --- a/crypto/openssl/crypto/perlasm/cbc.pl +++ b/crypto/openssl/crypto/perlasm/cbc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -165,21 +165,28 @@ sub cbc &jmp_ptr($count); &set_label("ej7"); + &endbranch() &movb(&HB("edx"), &BP(6,$in,"",0)); &shl("edx",8); &set_label("ej6"); + &endbranch() &movb(&HB("edx"), &BP(5,$in,"",0)); &set_label("ej5"); + &endbranch() &movb(&LB("edx"), &BP(4,$in,"",0)); &set_label("ej4"); + &endbranch() &mov("ecx", &DWP(0,$in,"",0)); &jmp(&label("ejend")); &set_label("ej3"); + &endbranch() &movb(&HB("ecx"), &BP(2,$in,"",0)); &shl("ecx",8); &set_label("ej2"); + &endbranch() &movb(&HB("ecx"), &BP(1,$in,"",0)); &set_label("ej1"); + &endbranch() &movb(&LB("ecx"), &BP(0,$in,"",0)); &set_label("ejend"); diff --git a/crypto/openssl/crypto/perlasm/ppc-xlate.pl b/crypto/openssl/crypto/perlasm/ppc-xlate.pl index f1a7fa835fc2..2ee444045ff9 100755 --- a/crypto/openssl/crypto/perlasm/ppc-xlate.pl +++ b/crypto/openssl/crypto/perlasm/ppc-xlate.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -83,6 +83,10 @@ my $text = sub { $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64(le|v2)/); $ret; }; +my $p2align = sub { + my $ret = ($flavour =~ /aix64-as/) ? "" : ".p2align $line"; + $ret; +}; my $machine = sub { my $junk = shift; my $arch = shift; @@ -135,6 +139,72 @@ my $quad = sub { join("\n",@ret); }; +################################################################ +# vector register number hacking +################################################################ + +# It is convenient to be able to set a variable like: +# my $foo = "v33"; +# and use this in different contexts where: +# * a VSR (Vector-Scaler Register) number (i.e. "v33") is required +# * a VR (Vector Register) number (i.e. "v1") is required +# Map VSR numbering to VR number for certain vector instructions. + +# vs -> v if N > 32 +sub vsr2vr1 { + my $in = shift; + my ($prefix, $reg) = ($in =~ m/(\D*)(\d+)/); + + my $n = int($reg); + if ($n >= 32) { + $n -= 32; + } + + return "${prefix}${n}"; +} +# As above for first $num register args, returns list +sub _vsr2vr { + my $num = shift; + my @rest = @_; + my @subst = splice(@rest, 0, $num); + + @subst = map { vsr2vr1($_); } @subst; + + return (@subst, @rest); +} +# As above but 1st arg ($f) is extracted and reinserted after +# processing so that it can be ignored by a code generation function +# that consumes the result +sub vsr2vr_args { + my $num = shift; + my $f = shift; + + my @out = _vsr2vr($num, @_); + + return ($f, @out); +} +# As above but 1st arg is mnemonic, return formatted instruction +sub vsr2vr { + my $mnemonic = shift; + my $num = shift; + my $f = shift; + + my @out = _vsr2vr($num, @_); + + " ${mnemonic}${f} " . join(",", @out); +} + +# ISA 2.03 +my $vsel = sub { vsr2vr("vsel", 4, @_); }; +my $vsl = sub { vsr2vr("vsl", 3, @_); }; +my $vspltisb = sub { vsr2vr("vspltisb", 1, @_); }; +my $vspltisw = sub { vsr2vr("vspltisw", 1, @_); }; +my $vsr = sub { vsr2vr("vsr", 3, @_); }; +my $vsro = sub { vsr2vr("vsro", 3, @_); }; + +# ISA 3.0 +my $lxsd = sub { vsr2vr("lxsd", 1, @_); }; + ################################################################ # simplified mnemonics not handled by at least one assembler ################################################################ @@ -226,13 +296,18 @@ my $vpermdi = sub { # xxpermdi # PowerISA 2.07 stuff sub vcrypto_op { - my ($f, $vrt, $vra, $vrb, $op) = @_; + my ($f, $vrt, $vra, $vrb, $op) = vsr2vr_args(3, @_); " .long ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|$op; } sub vfour { my ($f, $vrt, $vra, $vrb, $vrc, $op) = @_; " .long ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|($vrc<<6)|$op; }; +sub vfour_vsr { + my ($f, $vrt, $vra, $vrb, $vrc, $op) = vsr2vr_args(4, @_); + " .long ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|($vrc<<6)|$op; +}; + my $vcipher = sub { vcrypto_op(@_, 1288); }; my $vcipherlast = sub { vcrypto_op(@_, 1289); }; my $vncipher = sub { vcrypto_op(@_, 1352); }; @@ -254,10 +329,10 @@ my $vsld = sub { vcrypto_op(@_, 1476); }; my $vsrd = sub { vcrypto_op(@_, 1732); }; my $vsubudm = sub { vcrypto_op(@_, 1216); }; my $vaddcuq = sub { vcrypto_op(@_, 320); }; -my $vaddeuqm = sub { vfour(@_,60); }; -my $vaddecuq = sub { vfour(@_,61); }; -my $vmrgew = sub { vfour(@_,0,1932); }; -my $vmrgow = sub { vfour(@_,0,1676); }; +my $vaddeuqm = sub { vfour_vsr(@_,60); }; +my $vaddecuq = sub { vfour_vsr(@_,61); }; +my $vmrgew = sub { vfour_vsr(@_,0,1932); }; +my $vmrgow = sub { vfour_vsr(@_,0,1676); }; my $mtsle = sub { my ($f, $arg) = @_; @@ -273,6 +348,8 @@ my $mtvrwz = sub { my ($f, $vrt, $ra) = @_; " .long ".sprintf "0x%X",(31<<26)|($vrt<<21)|($ra<<16)|(243<<1)|1; }; +my $lvwzx_u = sub { vsxmem_op(@_, 12); }; # lxsiwzx +my $stvwx_u = sub { vsxmem_op(@_, 140); }; # stxsiwx # PowerISA 3.0 stuff my $maddhdu = sub { vfour(@_,49); }; @@ -298,13 +375,13 @@ my $addex = sub { my ($f, $rt, $ra, $rb, $cy) = @_; # only cy==0 is specified in 3.0B " .long ".sprintf "0x%X",(31<<26)|($rt<<21)|($ra<<16)|($rb<<11)|($cy<<9)|(170<<1); }; -my $vmsumudm = sub { vfour(@_,35); }; +my $vmsumudm = sub { vfour_vsr(@_, 35); }; while($line=<>) { $line =~ s|[#!;].*$||; # get rid of asm-style comments... $line =~ s|/\*.*\*/||; # ... and C-style comments... - $line =~ s|^\s+||; # ... and skip white spaces in beginning... + $line =~ s|^\s+||; # ... and skip whitespaces in beginning... $line =~ s|\s+$||; # ... and at the end { diff --git a/crypto/openssl/crypto/perlasm/s390x.pm b/crypto/openssl/crypto/perlasm/s390x.pm new file mode 100644 index 000000000000..dbf48426813c --- /dev/null +++ b/crypto/openssl/crypto/perlasm/s390x.pm @@ -0,0 +1,3175 @@ +#!/usr/bin/env perl +# Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Copyright IBM Corp. 2018-2019 +# Author: Patrick Steuer + +package perlasm::s390x; + +use strict; +use warnings; +use bigint; +use Carp qw(confess); +use Exporter qw(import); + +our @EXPORT=qw(PERLASM_BEGIN PERLASM_END); +our @EXPORT_OK=qw(AUTOLOAD LABEL INCLUDE stfle stck); +our %EXPORT_TAGS=( + # store-clock-fast facility + SCF => [qw(stckf)], + # general-instruction-extension facility + GE => [qw(risbg)], + # extended-immediate facility + EI => [qw(clfi clgfi lt)], + # miscellaneous-instruction-extensions facility 1 + MI1 => [qw(risbgn)], + # message-security assist + MSA => [qw(kmac km kmc kimd klmd)], + # message-security-assist extension 4 + MSA4 => [qw(kmf kmo pcc kmctr)], + # message-security-assist extension 5 + MSA5 => [qw(ppno prno)], + # message-security-assist extension 8 + MSA8 => [qw(kma)], + # message-security-assist extension 9 + MSA9 => [qw(kdsa)], + # vector facility + VX => [qw(vgef vgeg vgbm vzero vone vgm vgmb vgmh vgmf vgmg + vl vlr vlrep vlrepb vlreph vlrepf vlrepg vleb vleh vlef vleg vleib + vleih vleif vleig vlgv vlgvb vlgvh vlgvf vlgvg vllez vllezb vllezh + vllezf vllezg vlm vlbb vlvg vlvgb vlvgh vlvgf vlvgg vlvgp + vll vmrh vmrhb vmrhh vmrhf vmrhg vmrl vmrlb vmrlh vmrlf vmrlg vpk + vpkh vpkf vpkg vpks vpksh vpksf vpksg vpkshs vpksfs vpksgs vpkls + vpklsh vpklsf vpklsg vpklshs vpklsfs vpklsgs vperm vpdi vrep vrepb + vreph vrepf vrepg vrepi vrepib vrepih vrepif vrepig vscef vsceg + vsel vseg vsegb vsegh vsegf vst vsteb vsteh vstef vsteg vstm vstl + vuph vuphb vuphh vuphf vuplh vuplhb vuplhh vuplhf vupl vuplb vuplhw + vuplf vupll vupllb vupllh vupllf va vab vah vaf vag vaq vacc vaccb + vacch vaccf vaccg vaccq vac vacq vaccc vacccq vn vnc vavg vavgb + vavgh vavgf vavgg vavgl vavglb vavglh vavglf vavglg vcksm vec_ vecb + vech vecf vecg vecl veclb veclh veclf veclg vceq vceqb vceqh vceqf + vceqg vceqbs vceqhs vceqfs vceqgs vch vchb vchh vchf vchg vchbs + vchhs vchfs vchgs vchl vchlb vchlh vchlf vchlg vchlbs vchlhs vchlfs + vchlgs vclz vclzb vclzh vclzf vclzg vctz vctzb vctzh vctzf vctzg + vx vgfm vgfmb vgfmh vgfmf vgfmg vgfma vgfmab vgfmah vgfmaf vgfmag + vlc vlcb vlch vlcf vlcg vlp vlpb vlph vlpf vlpg vmx vmxb vmxh vmxf + vmxg vmxl vmxlb vmxlh vmxlf vmxlg vmn vmnb vmnh vmnf vmng vmnl + vmnlb vmnlh vmnlf vmnlg vmal vmalb vmalhw vmalf vmah vmahb vmahh + vmahf vmalh vmalhb vmalhh vmalhf vmae vmaeb vmaeh vmaef vmale + vmaleb vmaleh vmalef vmao vmaob vmaoh vmaof vmalo vmalob vmaloh + vmalof vmh vmhb vmhh vmhf vmlh vmlhb vmlhh vmlhf vml vmlb vmlhw + vmlf vme vmeb vmeh vmef vmle vmleb vmleh vmlef vmo vmob vmoh vmof + vmlo vmlob vmloh vmlof vno vnot vo vpopct verllv verllvb verllvh + verllvf verllvg verll verllb verllh verllf verllg verim verimb + verimh verimf verimg veslv veslvb veslvh veslvf veslvg vesl veslb + veslh veslf veslg vesrav vesravb vesravh vesravf vesravg vesra + vesrab vesrah vesraf vesrag vesrlv vesrlvb vesrlvh vesrlvf vesrlvg + vesrl vesrlb vesrlh vesrlf vesrlg vsl vslb vsldb vsra vsrab vsrl + vsrlb vs vsb vsh vsf vsg vsq vscbi vscbib vscbih vscbif vscbig + vscbiq vsbi vsbiq vsbcbi vsbcbiq vsumg vsumgh vsumgf vsumq vsumqf + vsumqg vsum vsumb vsumh vtm vfae vfaeb vfaeh vfaef vfaebs vfaehs + vfaefs vfaezb vfaezh vfaezf vfaezbs vfaezhs vfaezfs vfee vfeeb + vfeeh vfeef vfeebs vfeehs vfeefs vfeezb vfeezh vfeezf vfeezbs + vfeezhs vfeezfs vfene vfeneb vfeneh vfenef vfenebs vfenehs vfenefs + vfenezb vfenezh vfenezf vfenezbs vfenezhs vfenezfs vistr vistrb + vistrh vistrf vistrbs vistrhs vistrfs vstrc vstrcb vstrch vstrcf + vstrcbs vstrchs vstrcfs vstrczb vstrczh vstrczf vstrczbs vstrczhs + vstrczfs vfa vfadb wfadb wfc wfcdb wfk wfkdb vfce vfcedb wfcedb + vfcedbs wfcedbs vfch vfchdb wfchdb vfchdbs wfchdbs vfche vfchedb + wfchedb vfchedbs wfchedbs vcdg vcdgb wcdgb vcdlg vcdlgb wcdlgb vcgd + vcgdb wcgdb vclgd vclgdb wclgdb vfd vfddb wfddb vfi vfidb wfidb + vlde vldeb wldeb vled vledb wledb vfm vfmdb wfmdb vfma vfmadb + wfmadb vfms vfmsdb wfmsdb vfpso vfpsodb wfpsodb vflcdb wflcdb + vflndb wflndb vflpdb wflpdb vfsq vfsqdb wfsqdb vfs vfsdb wfsdb + vftci vftcidb wftcidb)], + # vector-enhancements facility 1 + VXE => [qw(vbperm vllezlf vmsl vmslg vnx vnn voc vpopctb vpopcth + vpopctf vpopctg vfasb wfasb wfaxb wfcsb wfcxb wfksb wfkxb vfcesb + vfcesbs wfcesb wfcesbs wfcexb wfcexbs vfchsb vfchsbs wfchsb wfchsbs + wfchxb wfchxbs vfchesb vfchesbs wfchesb wfchesbs wfchexb wfchexbs + vfdsb wfdsb wfdxb vfisb wfisb wfixb vfll vflls wflls wflld vflr + vflrd wflrd wflrx vfmax vfmaxsb vfmaxdb wfmaxsb wfmaxdb wfmaxxb + vfmin vfminsb vfmindb wfminsb wfmindb wfminxb vfmsb wfmsb wfmxb + vfnma vfnms vfmasb wfmasb wfmaxb vfmssb wfmssb wfmsxb vfnmasb + vfnmadb wfnmasb wfnmadb wfnmaxb vfnmssb vfnmsdb wfnmssb wfnmsdb + wfnmsxb vfpsosb wfpsosb vflcsb wflcsb vflnsb wflnsb vflpsb wflpsb + vfpsoxb wfpsoxb vflcxb wflcxb vflnxb wflnxb vflpxb wflpxb vfsqsb + wfsqsb wfsqxb vfssb wfssb wfsxb vftcisb wftcisb wftcixb)], + # vector-packed-decimal facility + VXD => [qw(vlrlr vlrl vstrlr vstrl vap vcp vcvb vcvbg vcvd vcvdg vdp + vlip vmp vmsp vpkz vpsop vrp vsdp vsrp vsp vtp vupkz)], +); +Exporter::export_ok_tags(qw(SCF GE EI MI1 MSA MSA4 MSA5 MSA8 MSA9 VX VXE VXD)); + +our $AUTOLOAD; + +my $GR='(?:%r)?([0-9]|1[0-5])'; +my $VR='(?:%v)?([0-9]|1[0-9]|2[0-9]|3[0-1])'; + +my ($file,$out); + +sub PERLASM_BEGIN +{ + ($file,$out)=(shift,""); +} +sub PERLASM_END +{ + if (defined($file)) { + open(my $fd,'>',$file)||die("can't open $file: $!"); + print({$fd}$out); + close($fd); + } else { + print($out); + } +} + +sub AUTOLOAD { + confess(err("PARSE")) if (grep(!defined($_),@_)); + my $token; + for ($AUTOLOAD) { + $token=lc(".$1") if (/^.*::([A-Z_]+)$/);# uppercase: directive + $token="\t$1" if (/^.*::([a-z]+)$/); # lowercase: mnemonic + confess(err("PARSE")) if (!defined($token)); + } + $token.="\t" if ($#_>=0); + $out.=$token.join(',',@_)."\n"; +} + +sub LABEL { # label directive + confess(err("ARGNUM")) if ($#_!=0); + my ($label)=@_; + $out.="$label:\n"; +} + +sub INCLUDE { + confess(err("ARGNUM")) if ($#_!=0); + my ($file)=@_; + $out.="#include \"$file\"\n"; +} + +# +# Mnemonics +# + +sub stfle { + confess(err("ARGNUM")) if ($#_!=0); + S(0xb2b0,@_); +} + +sub stck { + confess(err("ARGNUM")) if ($#_!=0); + S(0xb205,@_); +} + +# store-clock-fast facility + +sub stckf { + confess(err("ARGNUM")) if ($#_!=0); + S(0xb27c,@_); +} + +# extended-immediate facility + +sub clfi { + confess(err("ARGNUM")) if ($#_!=1); + RILa(0xc2f,@_); +} + +sub clgfi { + confess(err("ARGNUM")) if ($#_!=1); + RILa(0xc2e,@_); +} + +sub lt { + confess(err("ARGNUM")) if ($#_!=1); + RXYa(0xe312,@_); +} + +# general-instruction-extension facility + +sub risbg { + confess(err("ARGNUM")) if ($#_<3||$#_>4); + RIEf(0xec55,@_); +} + +# miscellaneous-instruction-extensions facility 1 + +sub risbgn { + confess(err("ARGNUM")) if ($#_<3||$#_>4); + RIEf(0xec59,@_); +} + +# MSA + +sub kmac { + confess(err("ARGNUM")) if ($#_!=1); + RRE(0xb91e,@_); +} + +sub km { + confess(err("ARGNUM")) if ($#_!=1); + RRE(0xb92e,@_); +} + +sub kmc { + confess(err("ARGNUM")) if ($#_!=1); + RRE(0xb92f,@_); +} + +sub kimd { + confess(err("ARGNUM")) if ($#_!=1); + RRE(0xb93e,@_); +} + +sub klmd { + confess(err("ARGNUM")) if ($#_!=1); + RRE(0xb93f,@_); +} + +# MSA4 + +sub kmf { + confess(err("ARGNUM")) if ($#_!=1); + RRE(0xb92a,@_); +} + +sub kmo { + confess(err("ARGNUM")) if ($#_!=1); + RRE(0xb92b,@_); +} + +sub pcc { + confess(err("ARGNUM")) if ($#_!=-1); + RRE(0xb92c,@_); +} + +sub kmctr { + confess(err("ARGNUM")) if ($#_!=2); + RRFb(0xb92d,@_); +} + +# MSA5 + +sub prno { + ppno(@_); +} + +sub ppno { # deprecated, use prno + confess(err("ARGNUM")) if ($#_!=1); + RRE(0xb93c,@_); +} + +# MSA8 + +sub kma { + confess(err("ARGNUM")) if ($#_!=2); + RRFb(0xb929,@_); +} + +# MSA9 + +sub kdsa { + confess(err("ARGNUM")) if ($#_!=1); + RRE(0xb93a,@_); +} + +# VX - Support Instructions + +sub vgef { + confess(err("ARGNUM")) if ($#_!=2); + VRV(0xe713,@_); +} +sub vgeg { + confess(err("ARGNUM")) if ($#_!=2); + VRV(0xe712,@_); +} + +sub vgbm { + confess(err("ARGNUM")) if ($#_!=1); + VRIa(0xe744,@_); +} +sub vzero { + vgbm(@_,0); +} +sub vone { + vgbm(@_,0xffff); +} + +sub vgm { + confess(err("ARGNUM")) if ($#_!=3); + VRIb(0xe746,@_); +} +sub vgmb { + vgm(@_,0); +} +sub vgmh { + vgm(@_,1); +} +sub vgmf { + vgm(@_,2); +} +sub vgmg { + vgm(@_,3); +} + +sub vl { + confess(err("ARGNUM")) if ($#_<1||$#_>2); + VRX(0xe706,@_); +} + +sub vlr { + confess(err("ARGNUM")) if ($#_!=1); + VRRa(0xe756,@_); +} + +sub vlrep { + confess(err("ARGNUM")) if ($#_!=2); + VRX(0xe705,@_); +} +sub vlrepb { + vlrep(@_,0); +} +sub vlreph { + vlrep(@_,1); +} +sub vlrepf { + vlrep(@_,2); +} +sub vlrepg { + vlrep(@_,3); +} + +sub vleb { + confess(err("ARGNUM")) if ($#_!=2); + VRX(0xe700,@_); +} +sub vleh { + confess(err("ARGNUM")) if ($#_!=2); + VRX(0xe701,@_); +} +sub vlef { + confess(err("ARGNUM")) if ($#_!=2); + VRX(0xe703,@_); +} +sub vleg { + confess(err("ARGNUM")) if ($#_!=2); + VRX(0xe702,@_); +} + +sub vleib { + confess(err("ARGNUM")) if ($#_!=2); + VRIa(0xe740,@_); +} +sub vleih { + confess(err("ARGNUM")) if ($#_!=2); + VRIa(0xe741,@_); +} +sub vleif { + confess(err("ARGNUM")) if ($#_!=2); + VRIa(0xe743,@_); +} +sub vleig { + confess(err("ARGNUM")) if ($#_!=2); + VRIa(0xe742,@_); +} + +sub vlgv { + confess(err("ARGNUM")) if ($#_!=3); + VRSc(0xe721,@_); +} +sub vlgvb { + vlgv(@_,0); +} +sub vlgvh { + vlgv(@_,1); +} +sub vlgvf { + vlgv(@_,2); +} +sub vlgvg { + vlgv(@_,3); +} + +sub vllez { + confess(err("ARGNUM")) if ($#_!=2); + VRX(0xe704,@_); +} +sub vllezb { + vllez(@_,0); +} +sub vllezh { + vllez(@_,1); +} +sub vllezf { + vllez(@_,2); +} +sub vllezg { + vllez(@_,3); +} + +sub vlm { + confess(err("ARGNUM")) if ($#_<2||$#_>3); + VRSa(0xe736,@_); +} + +sub vlbb { + confess(err("ARGNUM")) if ($#_!=2); + VRX(0xe707,@_); +} + +sub vlvg { + confess(err("ARGNUM")) if ($#_!=3); + VRSb(0xe722,@_); +} +sub vlvgb { + vlvg(@_,0); +} +sub vlvgh { + vlvg(@_,1); +} +sub vlvgf { + vlvg(@_,2); +} +sub vlvgg { + vlvg(@_,3); +} + +sub vlvgp { + confess(err("ARGNUM")) if ($#_!=2); + VRRf(0xe762,@_); +} + +sub vll { + confess(err("ARGNUM")) if ($#_!=2); + VRSb(0xe737,@_); +} + +sub vmrh { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe761,@_); +} +sub vmrhb { + vmrh(@_,0); +} +sub vmrhh { + vmrh(@_,1); +} +sub vmrhf { + vmrh(@_,2); +} +sub vmrhg { + vmrh(@_,3); +} + +sub vmrl { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe760,@_); +} +sub vmrlb { + vmrl(@_,0); +} +sub vmrlh { + vmrl(@_,1); +} +sub vmrlf { + vmrl(@_,2); +} +sub vmrlg { + vmrl(@_,3); +} + +sub vpk { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe794,@_); +} +sub vpkh { + vpk(@_,1); +} +sub vpkf { + vpk(@_,2); +} +sub vpkg { + vpk(@_,3); +} + +sub vpks { + confess(err("ARGNUM")) if ($#_!=4); + VRRb(0xe797,@_); +} +sub vpksh { + vpks(@_,1,0); +} +sub vpksf { + vpks(@_,2,0); +} +sub vpksg { + vpks(@_,3,0); +} +sub vpkshs { + vpks(@_,1,1); +} +sub vpksfs { + vpks(@_,2,1); +} +sub vpksgs { + vpks(@_,3,1); +} + +sub vpkls { + confess(err("ARGNUM")) if ($#_!=4); + VRRb(0xe795,@_); +} +sub vpklsh { + vpkls(@_,1,0); +} +sub vpklsf { + vpkls(@_,2,0); +} +sub vpklsg { + vpkls(@_,3,0); +} +sub vpklshs { + vpkls(@_,1,1); +} +sub vpklsfs { + vpkls(@_,2,1); +} +sub vpklsgs { + vpkls(@_,3,1); +} + +sub vperm { + confess(err("ARGNUM")) if ($#_!=3); + VRRe(0xe78c,@_); +} + +sub vpdi { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe784,@_); +} + +sub vrep { + confess(err("ARGNUM")) if ($#_!=3); + VRIc(0xe74d,@_); +} +sub vrepb { + vrep(@_,0); +} +sub vreph { + vrep(@_,1); +} +sub vrepf { + vrep(@_,2); +} +sub vrepg { + vrep(@_,3); +} + +sub vrepi { + confess(err("ARGNUM")) if ($#_!=2); + VRIa(0xe745,@_); +} +sub vrepib { + vrepi(@_,0); +} +sub vrepih { + vrepi(@_,1); +} +sub vrepif { + vrepi(@_,2); +} +sub vrepig { + vrepi(@_,3); +} + +sub vscef { + confess(err("ARGNUM")) if ($#_!=2); + VRV(0xe71b,@_); +} +sub vsceg { + confess(err("ARGNUM")) if ($#_!=2); + VRV(0xe71a,@_); +} + +sub vsel { + confess(err("ARGNUM")) if ($#_!=3); + VRRe(0xe78d,@_); +} + +sub vseg { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe75f,@_); +} +sub vsegb { + vseg(@_,0); +} +sub vsegh { + vseg(@_,1); +} +sub vsegf { + vseg(@_,2); +} + +sub vst { + confess(err("ARGNUM")) if ($#_<1||$#_>2); + VRX(0xe70e,@_); +} + +sub vsteb { + confess(err("ARGNUM")) if ($#_!=2); + VRX(0xe708,@_); +} +sub vsteh { + confess(err("ARGNUM")) if ($#_!=2); + VRX(0xe709,@_); +} +sub vstef { + confess(err("ARGNUM")) if ($#_!=2); + VRX(0xe70b,@_); +} +sub vsteg { + confess(err("ARGNUM")) if ($#_!=2); + VRX(0xe70a,@_); +} + +sub vstm { + confess(err("ARGNUM")) if ($#_<2||$#_>3); + VRSa(0xe73e,@_); +} + +sub vstl { + confess(err("ARGNUM")) if ($#_!=2); + VRSb(0xe73f,@_); +} + +sub vuph { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe7d7,@_); +} +sub vuphb { + vuph(@_,0); +} +sub vuphh { + vuph(@_,1); +} +sub vuphf { + vuph(@_,2); +} + +sub vuplh { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe7d5,@_); +} +sub vuplhb { + vuplh(@_,0); +} +sub vuplhh { + vuplh(@_,1); +} +sub vuplhf { + vuplh(@_,2); +} + +sub vupl { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe7d6,@_); +} +sub vuplb { + vupl(@_,0); +} +sub vuplhw { + vupl(@_,1); +} +sub vuplf { + vupl(@_,2); +} + +sub vupll { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe7d4,@_); +} +sub vupllb { + vupll(@_,0); +} +sub vupllh { + vupll(@_,1); +} +sub vupllf { + vupll(@_,2); +} + +# VX - Integer Instructions + +sub va { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7f3,@_); +} +sub vab { + va(@_,0); +} +sub vah { + va(@_,1); +} +sub vaf { + va(@_,2); +} +sub vag { + va(@_,3); +} +sub vaq { + va(@_,4); +} + +sub vacc { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7f1,@_); +} +sub vaccb { + vacc(@_,0); +} +sub vacch { + vacc(@_,1); +} +sub vaccf { + vacc(@_,2); +} +sub vaccg { + vacc(@_,3); +} +sub vaccq { + vacc(@_,4); +} + +sub vac { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7bb,@_); +} +sub vacq { + vac(@_,4); +} + +sub vaccc { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7b9,@_); +} +sub vacccq { + vaccc(@_,4); +} + +sub vn { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe768,@_); +} + +sub vnc { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe769,@_); +} + +sub vavg { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7f2,@_); +} +sub vavgb { + vavg(@_,0); +} +sub vavgh { + vavg(@_,1); +} +sub vavgf { + vavg(@_,2); +} +sub vavgg { + vavg(@_,3); +} + +sub vavgl { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7f0,@_); +} +sub vavglb { + vavgl(@_,0); +} +sub vavglh { + vavgl(@_,1); +} +sub vavglf { + vavgl(@_,2); +} +sub vavglg { + vavgl(@_,3); +} + +sub vcksm { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe766,@_); +} + +sub vec_ { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe7db,@_); +} +sub vecb { + vec_(@_,0); +} +sub vech { + vec_(@_,1); +} +sub vecf { + vec_(@_,2); +} +sub vecg { + vec_(@_,3); +} + +sub vecl { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe7d9,@_); +} +sub veclb { + vecl(@_,0); +} +sub veclh { + vecl(@_,1); +} +sub veclf { + vecl(@_,2); +} +sub veclg { + vecl(@_,3); +} + +sub vceq { + confess(err("ARGNUM")) if ($#_!=4); + VRRb(0xe7f8,@_); +} +sub vceqb { + vceq(@_,0,0); +} +sub vceqh { + vceq(@_,1,0); +} +sub vceqf { + vceq(@_,2,0); +} +sub vceqg { + vceq(@_,3,0); +} +sub vceqbs { + vceq(@_,0,1); +} +sub vceqhs { + vceq(@_,1,1); +} +sub vceqfs { + vceq(@_,2,1); +} +sub vceqgs { + vceq(@_,3,1); +} + +sub vch { + confess(err("ARGNUM")) if ($#_!=4); + VRRb(0xe7fb,@_); +} +sub vchb { + vch(@_,0,0); +} +sub vchh { + vch(@_,1,0); +} +sub vchf { + vch(@_,2,0); +} +sub vchg { + vch(@_,3,0); +} +sub vchbs { + vch(@_,0,1); +} +sub vchhs { + vch(@_,1,1); +} +sub vchfs { + vch(@_,2,1); +} +sub vchgs { + vch(@_,3,1); +} + +sub vchl { + confess(err("ARGNUM")) if ($#_!=4); + VRRb(0xe7f9,@_); +} +sub vchlb { + vchl(@_,0,0); +} +sub vchlh { + vchl(@_,1,0); +} +sub vchlf { + vchl(@_,2,0); +} +sub vchlg { + vchl(@_,3,0); +} +sub vchlbs { + vchl(@_,0,1); +} +sub vchlhs { + vchl(@_,1,1); +} +sub vchlfs { + vchl(@_,2,1); +} +sub vchlgs { + vchl(@_,3,1); +} + +sub vclz { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe753,@_); +} +sub vclzb { + vclz(@_,0); +} +sub vclzh { + vclz(@_,1); +} +sub vclzf { + vclz(@_,2); +} +sub vclzg { + vclz(@_,3); +} + +sub vctz { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe752,@_); +} +sub vctzb { + vctz(@_,0); +} +sub vctzh { + vctz(@_,1); +} +sub vctzf { + vctz(@_,2); +} +sub vctzg { + vctz(@_,3); +} + +sub vx { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe76d,@_); +} + +sub vgfm { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7b4,@_); +} +sub vgfmb { + vgfm(@_,0); +} +sub vgfmh { + vgfm(@_,1); +} +sub vgfmf { + vgfm(@_,2); +} +sub vgfmg { + vgfm(@_,3); +} + +sub vgfma { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7bc,@_); +} +sub vgfmab { + vgfma(@_,0); +} +sub vgfmah { + vgfma(@_,1); +} +sub vgfmaf { + vgfma(@_,2); +} +sub vgfmag { + vgfma(@_,3); +} + +sub vlc { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe7de,@_); +} +sub vlcb { + vlc(@_,0); +} +sub vlch { + vlc(@_,1); +} +sub vlcf { + vlc(@_,2); +} +sub vlcg { + vlc(@_,3); +} + +sub vlp { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe7df,@_); +} +sub vlpb { + vlp(@_,0); +} +sub vlph { + vlp(@_,1); +} +sub vlpf { + vlp(@_,2); +} +sub vlpg { + vlp(@_,3); +} + +sub vmx { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7ff,@_); +} +sub vmxb { + vmx(@_,0); +} +sub vmxh { + vmx(@_,1); +} +sub vmxf { + vmx(@_,2); +} +sub vmxg { + vmx(@_,3); +} + +sub vmxl { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7fd,@_); +} +sub vmxlb { + vmxl(@_,0); +} +sub vmxlh { + vmxl(@_,1); +} +sub vmxlf { + vmxl(@_,2); +} +sub vmxlg { + vmxl(@_,3); +} + +sub vmn { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7fe,@_); +} +sub vmnb { + vmn(@_,0); +} +sub vmnh { + vmn(@_,1); +} +sub vmnf { + vmn(@_,2); +} +sub vmng { + vmn(@_,3); +} + +sub vmnl { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7fc,@_); +} +sub vmnlb { + vmnl(@_,0); +} +sub vmnlh { + vmnl(@_,1); +} +sub vmnlf { + vmnl(@_,2); +} +sub vmnlg { + vmnl(@_,3); +} + +sub vmal { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7aa,@_); +} +sub vmalb { + vmal(@_,0); +} +sub vmalhw { + vmal(@_,1); +} +sub vmalf { + vmal(@_,2); +} + +sub vmah { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7ab,@_); +} +sub vmahb { + vmah(@_,0); +} +sub vmahh { + vmah(@_,1); +} +sub vmahf { + vmah(@_,2); +} + +sub vmalh { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7a9,@_); +} +sub vmalhb { + vmalh(@_,0); +} +sub vmalhh { + vmalh(@_,1); +} +sub vmalhf { + vmalh(@_,2); +} + +sub vmae { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7ae,@_); +} +sub vmaeb { + vmae(@_,0); +} +sub vmaeh { + vmae(@_,1); +} +sub vmaef { + vmae(@_,2); +} + +sub vmale { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7ac,@_); +} +sub vmaleb { + vmale(@_,0); +} +sub vmaleh { + vmale(@_,1); +} +sub vmalef { + vmale(@_,2); +} + +sub vmao { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7af,@_); +} +sub vmaob { + vmao(@_,0); +} +sub vmaoh { + vmao(@_,1); +} +sub vmaof { + vmao(@_,2); +} + +sub vmalo { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7ad,@_); +} +sub vmalob { + vmalo(@_,0); +} +sub vmaloh { + vmalo(@_,1); +} +sub vmalof { + vmalo(@_,2); +} + +sub vmh { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7a3,@_); +} +sub vmhb { + vmh(@_,0); +} +sub vmhh { + vmh(@_,1); +} +sub vmhf { + vmh(@_,2); +} + +sub vmlh { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7a1,@_); +} +sub vmlhb { + vmlh(@_,0); +} +sub vmlhh { + vmlh(@_,1); +} +sub vmlhf { + vmlh(@_,2); +} + +sub vml { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7a2,@_); +} +sub vmlb { + vml(@_,0); +} +sub vmlhw { + vml(@_,1); +} +sub vmlf { + vml(@_,2); +} + +sub vme { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7a6,@_); +} +sub vmeb { + vme(@_,0); +} +sub vmeh { + vme(@_,1); +} +sub vmef { + vme(@_,2); +} + +sub vmle { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7a4,@_); +} +sub vmleb { + vmle(@_,0); +} +sub vmleh { + vmle(@_,1); +} +sub vmlef { + vmle(@_,2); +} + +sub vmo { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7a7,@_); +} +sub vmob { + vmo(@_,0); +} +sub vmoh { + vmo(@_,1); +} +sub vmof { + vmo(@_,2); +} + +sub vmlo { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7a5,@_); +} +sub vmlob { + vmlo(@_,0); +} +sub vmloh { + vmlo(@_,1); +} +sub vmlof { + vmlo(@_,2); +} + +sub vno { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe76b,@_); +} +sub vnot { + vno(@_,$_[1]); +} + +sub vo { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe76a,@_); +} + +sub vpopct { + confess(err("ARGNUM")) if ($#_!=2); + VRRa(0xe750,@_); +} + +sub verllv { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe773,@_); +} +sub verllvb { + verllv(@_,0); +} +sub verllvh { + verllv(@_,1); +} +sub verllvf { + verllv(@_,2); +} +sub verllvg { + verllv(@_,3); +} + +sub verll { + confess(err("ARGNUM")) if ($#_!=3); + VRSa(0xe733,@_); +} +sub verllb { + verll(@_,0); +} +sub verllh { + verll(@_,1); +} +sub verllf { + verll(@_,2); +} +sub verllg { + verll(@_,3); +} + +sub verim { + confess(err("ARGNUM")) if ($#_!=4); + VRId(0xe772,@_); +} +sub verimb { + verim(@_,0); +} +sub verimh { + verim(@_,1); +} +sub verimf { + verim(@_,2); +} +sub verimg { + verim(@_,3); +} + +sub veslv { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe770,@_); +} +sub veslvb { + veslv(@_,0); +} +sub veslvh { + veslv(@_,1); +} +sub veslvf { + veslv(@_,2); +} +sub veslvg { + veslv(@_,3); +} + +sub vesl { + confess(err("ARGNUM")) if ($#_!=3); + VRSa(0xe730,@_); +} +sub veslb { + vesl(@_,0); +} +sub veslh { + vesl(@_,1); +} +sub veslf { + vesl(@_,2); +} +sub veslg { + vesl(@_,3); +} + +sub vesrav { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe77a,@_); +} +sub vesravb { + vesrav(@_,0); +} +sub vesravh { + vesrav(@_,1); +} +sub vesravf { + vesrav(@_,2); +} +sub vesravg { + vesrav(@_,3); +} + +sub vesra { + confess(err("ARGNUM")) if ($#_!=3); + VRSa(0xe73a,@_); +} +sub vesrab { + vesra(@_,0); +} +sub vesrah { + vesra(@_,1); +} +sub vesraf { + vesra(@_,2); +} +sub vesrag { + vesra(@_,3); +} + +sub vesrlv { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe778,@_); +} +sub vesrlvb { + vesrlv(@_,0); +} +sub vesrlvh { + vesrlv(@_,1); +} +sub vesrlvf { + vesrlv(@_,2); +} +sub vesrlvg { + vesrlv(@_,3); +} + +sub vesrl { + confess(err("ARGNUM")) if ($#_!=3); + VRSa(0xe738,@_); +} +sub vesrlb { + vesrl(@_,0); +} +sub vesrlh { + vesrl(@_,1); +} +sub vesrlf { + vesrl(@_,2); +} +sub vesrlg { + vesrl(@_,3); +} + +sub vsl { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe774,@_); +} + +sub vslb { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe775,@_); +} + +sub vsldb { + confess(err("ARGNUM")) if ($#_!=3); + VRId(0xe777,@_); +} + +sub vsra { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe77e,@_); +} + +sub vsrab { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe77f,@_); +} + +sub vsrl { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe77c,@_); +} + +sub vsrlb { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe77d,@_); +} + +sub vs { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7f7,@_); +} +sub vsb { + vs(@_,0); +} +sub vsh { + vs(@_,1); +} +sub vsf { + vs(@_,2); +} +sub vsg { + vs(@_,3); +} +sub vsq { + vs(@_,4); +} + +sub vscbi { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe7f5,@_); +} +sub vscbib { + vscbi(@_,0); +} +sub vscbih { + vscbi(@_,1); +} +sub vscbif { + vscbi(@_,2); +} +sub vscbig { + vscbi(@_,3); +} +sub vscbiq { + vscbi(@_,4); +} + +sub vsbi { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7bf,@_); +} +sub vsbiq { + vsbi(@_,4); +} + +sub vsbcbi { + confess(err("ARGNUM")) if ($#_!=4); + VRRd(0xe7bd,@_); +} +sub vsbcbiq { + vsbcbi(@_,4); +} + +sub vsumg { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe765,@_); +} +sub vsumgh { + vsumg(@_,1); +} +sub vsumgf { + vsumg(@_,2); +} + +sub vsumq { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe767,@_); +} +sub vsumqf { + vsumq(@_,2); +} +sub vsumqg { + vsumq(@_,3); +} + +sub vsum { + confess(err("ARGNUM")) if ($#_!=3); + VRRc(0xe764,@_); +} +sub vsumb { + vsum(@_,0); +} +sub vsumh { + vsum(@_,1); +} + +sub vtm { + confess(err("ARGNUM")) if ($#_!=1); + VRRa(0xe7d8,@_); +} + +# VX - String Instructions + +sub vfae { + confess(err("ARGNUM")) if ($#_<3||$#_>4); + VRRb(0xe782,@_); +} +sub vfaeb { + vfae(@_[0..2],0,$_[3]); +} +sub vfaeh { + vfae(@_[0..2],1,$_[3]); +} +sub vfaef { + vfae(@_[0..2],2,$_[3]); +} +sub vfaebs { + $_[3]=0 if (!defined($_[3])); + vfae(@_[0..2],0,0x1|$_[3]); +} +sub vfaehs { + $_[3]=0 if (!defined($_[3])); + vfae(@_[0..2],1,0x1|$_[3]); +} +sub vfaefs { + $_[3]=0 if (!defined($_[3])); + vfae(@_[0..2],2,0x1|$_[3]); +} +sub vfaezb { + $_[3]=0 if (!defined($_[3])); + vfae(@_[0..2],0,0x2|$_[3]); +} +sub vfaezh { + $_[3]=0 if (!defined($_[3])); + vfae(@_[0..2],1,0x2|$_[3]); +} +sub vfaezf { + $_[3]=0 if (!defined($_[3])); + vfae(@_[0..2],2,0x2|$_[3]); +} +sub vfaezbs { + $_[3]=0 if (!defined($_[3])); + vfae(@_[0..2],0,0x3|$_[3]); +} +sub vfaezhs { + $_[3]=0 if (!defined($_[3])); + vfae(@_[0..2],1,0x3|$_[3]); +} +sub vfaezfs { + $_[3]=0 if (!defined($_[3])); + vfae(@_[0..2],2,0x3|$_[3]); +} + +sub vfee { + confess(err("ARGNUM")) if ($#_<3||$#_>4); + VRRb(0xe780,@_); +} +sub vfeeb { + vfee(@_[0..2],0,$_[3]); +} +sub vfeeh { + vfee(@_[0..2],1,$_[3]); +} +sub vfeef { + vfee(@_[0..2],2,$_[3]); +} +sub vfeebs { + vfee(@_,0,1); +} +sub vfeehs { + vfee(@_,1,1); +} +sub vfeefs { + vfee(@_,2,1); +} +sub vfeezb { + vfee(@_,0,2); +} +sub vfeezh { + vfee(@_,1,2); +} +sub vfeezf { + vfee(@_,2,2); +} +sub vfeezbs { + vfee(@_,0,3); +} +sub vfeezhs { + vfee(@_,1,3); +} +sub vfeezfs { + vfee(@_,2,3); +} + +sub vfene { + confess(err("ARGNUM")) if ($#_<3||$#_>4); + VRRb(0xe781,@_); +} +sub vfeneb { + vfene(@_[0..2],0,$_[3]); +} +sub vfeneh { + vfene(@_[0..2],1,$_[3]); +} +sub vfenef { + vfene(@_[0..2],2,$_[3]); +} +sub vfenebs { + vfene(@_,0,1); +} +sub vfenehs { + vfene(@_,1,1); +} +sub vfenefs { + vfene(@_,2,1); +} +sub vfenezb { + vfene(@_,0,2); +} +sub vfenezh { + vfene(@_,1,2); +} +sub vfenezf { + vfene(@_,2,2); +} +sub vfenezbs { + vfene(@_,0,3); +} +sub vfenezhs { + vfene(@_,1,3); +} +sub vfenezfs { + vfene(@_,2,3); +} + +sub vistr { + confess(err("ARGNUM")) if ($#_<2||$#_>3); + VRRa(0xe75c,@_[0..2],0,$_[3]); +} +sub vistrb { + vistr(@_[0..1],0,$_[2]); +} +sub vistrh { + vistr(@_[0..1],1,$_[2]); +} +sub vistrf { + vistr(@_[0..1],2,$_[2]); +} +sub vistrbs { + vistr(@_,0,1); +} +sub vistrhs { + vistr(@_,1,1); +} +sub vistrfs { + vistr(@_,2,1); +} + +sub vstrc { + confess(err("ARGNUM")) if ($#_<4||$#_>5); + VRRd(0xe78a,@_); +} +sub vstrcb { + vstrc(@_[0..3],0,$_[4]); +} +sub vstrch { + vstrc(@_[0..3],1,$_[4]); +} +sub vstrcf { + vstrc(@_[0..3],2,$_[4]); +} +sub vstrcbs { + $_[4]=0 if (!defined($_[4])); + vstrc(@_[0..3],0,0x1|$_[4]); +} +sub vstrchs { + $_[4]=0 if (!defined($_[4])); + vstrc(@_[0..3],1,0x1|$_[4]); +} +sub vstrcfs { + $_[4]=0 if (!defined($_[4])); + vstrc(@_[0..3],2,0x1|$_[4]); +} +sub vstrczb { + $_[4]=0 if (!defined($_[4])); + vstrc(@_[0..3],0,0x2|$_[4]); +} +sub vstrczh { + $_[4]=0 if (!defined($_[4])); + vstrc(@_[0..3],1,0x2|$_[4]); +} +sub vstrczf { + $_[4]=0 if (!defined($_[4])); + vstrc(@_[0..3],2,0x2|$_[4]); +} +sub vstrczbs { + $_[4]=0 if (!defined($_[4])); + vstrc(@_[0..3],0,0x3|$_[4]); +} +sub vstrczhs { + $_[4]=0 if (!defined($_[4])); + vstrc(@_[0..3],1,0x3|$_[4]); +} +sub vstrczfs { + $_[4]=0 if (!defined($_[4])); + vstrc(@_[0..3],2,0x3|$_[4]); +} + +# VX - Floating-point Instructions + +sub vfa { + confess(err("ARGNUM")) if ($#_!=4); + VRRc(0xe7e3,@_); +} +sub vfadb { + vfa(@_,3,0); +} +sub wfadb { + vfa(@_,3,8); +} + +sub wfc { + confess(err("ARGNUM")) if ($#_!=3); + VRRa(0xe7cb,@_); +} +sub wfcdb { + wfc(@_,3,0); +} + +sub wfk { + confess(err("ARGNUM")) if ($#_!=3); + VRRa(0xe7ca,@_); +} +sub wfksb { + wfk(@_,2,0); +} +sub wfkdb { + wfk(@_,3,0); +} +sub wfkxb { + wfk(@_,4,0); +} + +sub vfce { + confess(err("ARGNUM")) if ($#_!=5); + VRRc(0xe7e8,@_); +} +sub vfcedb { + vfce(@_,3,0,0); +} +sub vfcedbs { + vfce(@_,3,0,1); +} +sub wfcedb { + vfce(@_,3,8,0); +} +sub wfcedbs { + vfce(@_,3,8,1); +} + +sub vfch { + confess(err("ARGNUM")) if ($#_!=5); + VRRc(0xe7eb,@_); +} +sub vfchdb { + vfch(@_,3,0,0); +} +sub vfchdbs { + vfch(@_,3,0,1); +} +sub wfchdb { + vfch(@_,3,8,0); +} +sub wfchdbs { + vfch(@_,3,8,1); +} + +sub vfche { + confess(err("ARGNUM")) if ($#_!=5); + VRRc(0xe7ea,@_); +} +sub vfchedb { + vfche(@_,3,0,0); +} +sub vfchedbs { + vfche(@_,3,0,1); +} +sub wfchedb { + vfche(@_,3,8,0); +} +sub wfchedbs { + vfche(@_,3,8,1); +} + +sub vcdg { + confess(err("ARGNUM")) if ($#_!=4); + VRRa(0xe7c3,@_); +} +sub vcdgb { + vcdg(@_[0..1],3,@_[2..3]); +} +sub wcdgb { + vcdg(@_[0..1],3,0x8|$_[2],$_[3]); +} + +sub vcdlg { + confess(err("ARGNUM")) if ($#_!=4); + VRRa(0xe7c1,@_); +} +sub vcdlgb { + vcdlg(@_[0..1],3,@_[2..3]); +} +sub wcdlgb { + vcdlg(@_[0..1],3,0x8|$_[2],$_[3]); +} + +sub vcgd { + confess(err("ARGNUM")) if ($#_!=4); + VRRa(0xe7c2,@_); +} +sub vcgdb { + vcgd(@_[0..1],3,@_[2..3]); +} +sub wcgdb { + vcgd(@_[0..1],3,0x8|$_[2],$_[3]); +} + +sub vclgd { + confess(err("ARGNUM")) if ($#_!=4); + VRRa(0xe7c0,@_); +} +sub vclgdb { + vclgd(@_[0..1],3,@_[2..3]); +} +sub wclgdb { + vclgd(@_[0..1],3,0x8|$_[2],$_[3]); +} + +sub vfd { + confess(err("ARGNUM")) if ($#_!=4); + VRRc(0xe7e5,@_); +} +sub vfddb { + vfd(@_,3,0); +} +sub wfddb { + vfd(@_,3,8); +} + +sub vfi { + confess(err("ARGNUM")) if ($#_!=4); + VRRa(0xe7c7,@_); +} +sub vfidb { + vfi(@_[0..1],3,@_[2..3]); +} +sub wfidb { + vfi(@_[0..1],3,0x8|$_[2],$_[3]); +} + +sub vlde { # deprecated, use vfll + confess(err("ARGNUM")) if ($#_!=3); + VRRa(0xe7c4,@_); +} +sub vldeb { # deprecated, use vflls + vlde(@_,2,0); +} +sub wldeb { # deprecated, use wflls + vlde(@_,2,8); +} + +sub vled { # deprecated, use vflr + confess(err("ARGNUM")) if ($#_!=4); + VRRa(0xe7c5,@_); +} +sub vledb { # deprecated, use vflrd + vled(@_[0..1],3,@_[2..3]); +} +sub wledb { # deprecated, use wflrd + vled(@_[0..1],3,0x8|$_[2],$_[3]); +} + +sub vfm { + confess(err("ARGNUM")) if ($#_!=4); + VRRc(0xe7e7,@_); +} +sub vfmdb { + vfm(@_,3,0); +} +sub wfmdb { + vfm(@_,3,8); +} + +sub vfma { + confess(err("ARGNUM")) if ($#_!=5); + VRRe(0xe78f,@_); +} +sub vfmadb { + vfma(@_,0,3); +} +sub wfmadb { + vfma(@_,8,3); +} + +sub vfms { + confess(err("ARGNUM")) if ($#_!=5); + VRRe(0xe78e,@_); +} +sub vfmsdb { + vfms(@_,0,3); +} +sub wfmsdb { + vfms(@_,8,3); +} + +sub vfpso { + confess(err("ARGNUM")) if ($#_!=4); + VRRa(0xe7cc,@_); +} +sub vfpsodb { + vfpso(@_[0..1],3,0,$_[2]); +} +sub wfpsodb { + vfpso(@_[0..1],3,8,$_[2]); +} +sub vflcdb { + vfpso(@_,3,0,0); +} +sub wflcdb { + vfpso(@_,3,8,0); +} +sub vflndb { + vfpso(@_,3,0,1); +} +sub wflndb { + vfpso(@_,3,8,1); +} +sub vflpdb { + vfpso(@_,3,0,2); +} +sub wflpdb { + vfpso(@_,3,8,2); +} + +sub vfsq { + confess(err("ARGNUM")) if ($#_!=3); + VRRa(0xe7ce,@_); +} +sub vfsqdb { + vfsq(@_,3,0); +} +sub wfsqdb { + vfsq(@_,3,8); +} + +sub vfs { + confess(err("ARGNUM")) if ($#_!=4); + VRRc(0xe7e2,@_); +} +sub vfsdb { + vfs(@_,3,0); +} +sub wfsdb { + vfs(@_,3,8); +} + +sub vftci { + confess(err("ARGNUM")) if ($#_!=4); + VRIe(0xe74a,@_); +} +sub vftcidb { + vftci(@_,3,0); +} +sub wftcidb { + vftci(@_,3,8); +} + +# VXE - Support Instructions + +sub vbperm { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe785,@_); +} + +sub vllezlf { + vllez(@_,6); +} + +# VXE - Integer Instructions + +sub vmsl { + confess(err("ARGNUM")) if ($#_!=5); + VRRd(0xe7b8,@_); +} +sub vmslg { + vmsl(@_[0..3],3,$_[4]); +} + +sub vnx { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe76c,@_); +} + +sub vnn { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe76e,@_); +} + +sub voc { + confess(err("ARGNUM")) if ($#_!=2); + VRRc(0xe76f,@_); +} + +sub vpopctb { + vpopct(@_,0); +} +sub vpopcth { + vpopct(@_,1); +} +sub vpopctf { + vpopct(@_,2); +} +sub vpopctg { + vpopct(@_,3); +} + +# VXE - Floating-Point Instructions + +sub vfasb { + vfa(@_,2,0); +} +sub wfasb { + vfa(@_,2,8); +} +sub wfaxb { + vfa(@_,4,8); +} + +sub wfcsb { + wfc(@_,2,0); +} +sub wfcxb { + wfc(@_,4,0); +} + +sub vfcesb { + vfce(@_,2,0,0); +} +sub vfcesbs { + vfce(@_,2,0,1); +} +sub wfcesb { + vfce(@_,2,8,0); +} +sub wfcesbs { + vfce(@_,2,8,1); +} +sub wfcexb { + vfce(@_,4,8,0); +} +sub wfcexbs { + vfce(@_,4,8,1); +} + +sub vfchsb { + vfch(@_,2,0,0); +} +sub vfchsbs { + vfch(@_,2,0,1); +} +sub wfchsb { + vfch(@_,2,8,0); +} +sub wfchsbs { + vfch(@_,2,8,1); +} +sub wfchxb { + vfch(@_,4,8,0); +} +sub wfchxbs { + vfch(@_,4,8,1); +} + +sub vfchesb { + vfche(@_,2,0,0); +} +sub vfchesbs { + vfche(@_,2,0,1); +} +sub wfchesb { + vfche(@_,2,8,0); +} +sub wfchesbs { + vfche(@_,2,8,1); +} +sub wfchexb { + vfche(@_,4,8,0); +} +sub wfchexbs { + vfche(@_,4,8,1); +} + +sub vfdsb { + vfd(@_,2,0); +} +sub wfdsb { + vfd(@_,2,8); +} +sub wfdxb { + vfd(@_,4,8); +} + +sub vfisb { + vfi(@_[0..1],2,@_[2..3]); +} +sub wfisb { + vfi(@_[0..1],2,0x8|$_[2],$_[3]); +} +sub wfixb { + vfi(@_[0..1],4,0x8|$_[2],$_[3]); +} + +sub vfll { + vlde(@_); +} +sub vflls { + vfll(@_,2,0); +} +sub wflls { + vfll(@_,2,8); +} +sub wflld { + vfll(@_,3,8); +} + +sub vflr { + vled(@_); +} +sub vflrd { + vflr(@_[0..1],3,@_[2..3]); +} +sub wflrd { + vflr(@_[0..1],3,0x8|$_[2],$_[3]); +} +sub wflrx { + vflr(@_[0..1],4,0x8|$_[2],$_[3]); +} + +sub vfmax { + confess(err("ARGNUM")) if ($#_!=5); + VRRc(0xe7ef,@_); +} +sub vfmaxsb { + vfmax(@_[0..2],2,0,$_[3]); +} +sub vfmaxdb { + vfmax(@_[0..2],3,0,$_[3]); +} +sub wfmaxsb { + vfmax(@_[0..2],2,8,$_[3]); +} +sub wfmaxdb { + vfmax(@_[0..2],3,8,$_[3]); +} +sub wfmaxxb { + vfmax(@_[0..2],4,8,$_[3]); +} + +sub vfmin { + confess(err("ARGNUM")) if ($#_!=5); + VRRc(0xe7ee,@_); +} +sub vfminsb { + vfmin(@_[0..2],2,0,$_[5]); +} +sub vfmindb { + vfmin(@_[0..2],3,0,$_[5]); +} +sub wfminsb { + vfmin(@_[0..2],2,8,$_[5]); +} +sub wfmindb { + vfmin(@_[0..2],3,8,$_[5]); +} +sub wfminxb { + vfmin(@_[0..2],4,8,$_[5]); +} + +sub vfmsb { + vfm(@_,2,0); +} +sub wfmsb { + vfm(@_,2,8); +} +sub wfmxb { + vfm(@_,4,8); +} + +sub vfmasb { + vfma(@_,0,2); +} +sub wfmasb { + vfma(@_,8,2); +} +sub wfmaxb { + vfma(@_,8,4); +} + +sub vfmssb { + vfms(@_,0,2); +} +sub wfmssb { + vfms(@_,8,2); +} +sub wfmsxb { + vfms(@_,8,4); +} + +sub vfnma { + confess(err("ARGNUM")) if ($#_!=5); + VRRe(0xe79f,@_); +} +sub vfnmasb { + vfnma(@_,0,2); +} +sub vfnmadb { + vfnma(@_,0,3); +} +sub wfnmasb { + vfnma(@_,8,2); +} +sub wfnmadb { + vfnma(@_,8,3); +} +sub wfnmaxb { + vfnma(@_,8,4); +} + +sub vfnms { + confess(err("ARGNUM")) if ($#_!=5); + VRRe(0xe79e,@_); +} +sub vfnmssb { + vfnms(@_,0,2); +} +sub vfnmsdb { + vfnms(@_,0,3); +} +sub wfnmssb { + vfnms(@_,8,2); +} +sub wfnmsdb { + vfnms(@_,8,3); +} +sub wfnmsxb { + vfnms(@_,8,4); +} + +sub vfpsosb { + vfpso(@_[0..1],2,0,$_[2]); +} +sub wfpsosb { + vfpso(@_[0..1],2,8,$_[2]); +} +sub vflcsb { + vfpso(@_,2,0,0); +} +sub wflcsb { + vfpso(@_,2,8,0); +} +sub vflnsb { + vfpso(@_,2,0,1); +} +sub wflnsb { + vfpso(@_,2,8,1); +} +sub vflpsb { + vfpso(@_,2,0,2); +} +sub wflpsb { + vfpso(@_,2,8,2); +} +sub vfpsoxb { + vfpso(@_[0..1],4,0,$_[2]); +} +sub wfpsoxb { + vfpso(@_[0..1],4,8,$_[2]); +} +sub vflcxb { + vfpso(@_,4,0,0); +} +sub wflcxb { + vfpso(@_,4,8,0); +} +sub vflnxb { + vfpso(@_,4,0,1); +} +sub wflnxb { + vfpso(@_,4,8,1); +} +sub vflpxb { + vfpso(@_,4,0,2); +} +sub wflpxb { + vfpso(@_,4,8,2); +} + +sub vfsqsb { + vfsq(@_,2,0); +} +sub wfsqsb { + vfsq(@_,2,8); +} +sub wfsqxb { + vfsq(@_,4,8); +} + +sub vfssb { + vfs(@_,2,0); +} +sub wfssb { + vfs(@_,2,8); +} +sub wfsxb { + vfs(@_,4,8); +} + +sub vftcisb { + vftci(@_,2,0); +} +sub wftcisb { + vftci(@_,2,8); +} +sub wftcixb { + vftci(@_,4,8); +} + +# VXD - Support Instructions + +sub vlrlr { + confess(err("ARGNUM")) if ($#_!=2); + VRSd(0xe637,@_); +} + +sub vlrl { + confess(err("ARGNUM")) if ($#_!=2); + VSI(0xe635,@_); +} + +sub vstrlr { + confess(err("ARGNUM")) if ($#_!=2); + VRSd(0xe63f,@_); +} + +sub vstrl { + confess(err("ARGNUM")) if ($#_!=2); + VSI(0xe63d,@_); +} + +sub vap { + confess(err("ARGNUM")) if ($#_!=4); + VRIf(0xe671,@_); +} + +sub vcp { + confess(err("ARGNUM")) if ($#_!=2); + VRRh(0xe677,@_); +} + +sub vcvb { + confess(err("ARGNUM")) if ($#_!=2); + VRRi(0xe650,@_); +} + +sub vcvbg { + confess(err("ARGNUM")) if ($#_!=2); + VRRi(0xe652,@_); +} + +sub vcvd { + confess(err("ARGNUM")) if ($#_!=3); + VRIi(0xe658,@_); +} + +sub vcvdg { + confess(err("ARGNUM")) if ($#_!=3); + VRIi(0xe65a,@_); +} + +sub vdp { + confess(err("ARGNUM")) if ($#_!=4); + VRIf(0xe67a,@_); +} + +sub vlip { + confess(err("ARGNUM")) if ($#_!=2); + VRIh(0xe649,@_); +} + +sub vmp { + confess(err("ARGNUM")) if ($#_!=4); + VRIf(0xe678,@_); +} + +sub vmsp { + confess(err("ARGNUM")) if ($#_!=4); + VRIf(0xe679,@_); +} + +sub vpkz { + confess(err("ARGNUM")) if ($#_!=2); + VSI(0xe634,@_); +} + +sub vpsop { + confess(err("ARGNUM")) if ($#_!=4); + VRIg(0xe65b,@_); +} + +sub vrp { + confess(err("ARGNUM")) if ($#_!=4); + VRIf(0xe67b,@_); +} + +sub vsdp { + confess(err("ARGNUM")) if ($#_!=4); + VRIf(0xe67e,@_); +} + +sub vsrp { + confess(err("ARGNUM")) if ($#_!=4); + VRIg(0xe659,@_); +} + +sub vsp { + confess(err("ARGNUM")) if ($#_!=4); + VRIf(0xe673,@_); +} + +sub vtp { + confess(err("ARGNUM")) if ($#_!=0); + VRRg(0xe65f,@_); +} + +sub vupkz { + confess(err("ARGNUM")) if ($#_!=2); + VSI(0xe63c,@_); +} + +# +# Instruction Formats +# + +sub RIEf { + confess(err("ARGNUM")) if ($#_<4||5<$#_); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$r1,$r2,$i3,$i4,$i5)=(shift,get_R(shift),get_R(shift), + get_I(shift,8),get_I(shift,8), + get_I(shift,8)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",(($opcode>>8)<<8|$r1<<4|$r2)).","; + $out.=sprintf("%#06x",($i3<<8)|$i4).","; + $out.=sprintf("%#06x",($i5<<8)|($opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub RILa { + confess(err("ARGNUM")) if ($#_!=2); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$r1,$i2)=(shift,get_R(shift),get_I(shift,32)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",(($opcode>>4)<<8|$r1<<4|($opcode&0xf))).","; + $out.=sprintf("%#06x",($i2>>16)).","; + $out.=sprintf("%#06x",($i2&0xffff)); + $out.="\t# $memn\t$ops\n"; +} + +sub RRE { + confess(err("ARGNUM")) if ($#_<0||2<$#_); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$r1,$r2)=(shift,get_R(shift),get_R(shift)); + + $out.="\t.long\t".sprintf("%#010x",($opcode<<16|$r1<<4|$r2)); + $out.="\t# $memn"; + # RRE can have 0 ops e.g., pcc. + $out.="\t$ops" if ((defined($ops))&&($ops ne '')); + $out.="\n"; +} + +sub RRFb { + confess(err("ARGNUM")) if ($#_<3||4<$#_); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$r1,$r3,$r2,$m4)=(shift,get_R(shift),get_R(shift) + ,get_R(shift),get_M(shift)); + + $out.="\t.long\t" + .sprintf("%#010x",($opcode<<16|$r3<<12|$m4<<8|$r1<<4|$r2)); + $out.="\t# $memn\t$ops\n"; +} + +sub RXYa { + confess(err("ARGNUM")) if ($#_!=2); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$r1,$d2,$x2,$b2)=(shift,get_R(shift),get_DXB(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",(($opcode>>8)<<8|$r1<<4|$x2)).","; + $out.=sprintf("%#06x",($b2<<12|($d2&0xfff))).","; + $out.=sprintf("%#06x",(($d2>>12)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub S { + confess(err("ARGNUM")) if ($#_<0||1<$#_); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$d2,$b2)=(shift,get_DB(shift)); + + $out.="\t.long\t".sprintf("%#010x",($opcode<<16|$b2<<12|$d2)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRIa { + confess(err("ARGNUM")) if ($#_<2||3<$#_); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$i2,$m3)=(shift,get_V(shift),get_I(shift,16), + get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)).","; + $out.=sprintf("%#06x",$i2).","; + $out.=sprintf("%#06x",($m3<<12|RXB($v1)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRIb { + confess(err("ARGNUM")) if ($#_!=4); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$i2,$i3,$m4)=(shift,get_V(shift),get_I(shift,8), + ,get_I(shift,8),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)).","; + $out.=sprintf("%#06x",($i2<<8|$i3)).","; + $out.=sprintf("%#06x",($m4<<12|RXB($v1)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRIc { + confess(err("ARGNUM")) if ($#_!=4); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v3,$i2,$m4)=(shift,get_V(shift),get_V(shift), + ,get_I(shift,16),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|($v3&0xf)).","; + $out.=sprintf("%#06x",$i2).","; + $out.=sprintf("%#06x",($m4<<12|RXB($v1,$v3)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRId { + confess(err("ARGNUM")) if ($#_<4||$#_>5); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v2,$v3,$i4,$m5)=(shift,get_V(shift),get_V(shift), + ,get_V(shift),get_I(shift,8),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|($v2&0xf)).","; + $out.=sprintf("%#06x",(($v3&0xf)<<12|$i4)).","; + $out.=sprintf("%#06x",($m5<<12|RXB($v1,$v2,$v3)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRIe { + confess(err("ARGNUM")) if ($#_!=5); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v2,$i3,$m4,$m5)=(shift,get_V(shift),get_V(shift), + ,get_I(shift,12),get_M(shift),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|($v2&0xf)).","; + $out.=sprintf("%#06x",($i3<<4|$m5)).","; + $out.=sprintf("%#06x",($m4<<12|RXB($v1,$v2)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRIf { + confess(err("ARGNUM")) if ($#_!=5); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v2,$v3,$i4,$m5)=(shift,get_V(shift),get_V(shift), + ,get_V(shift),get_I(shift,8),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|($v2&0xf)).","; + $out.=sprintf("%#06x",(($v3&0xf)<<12|$m5<<4)|$i4>>4).","; + $out.=sprintf("%#06x",(($i4&0xf)<<12|RXB($v1,$v2,$v3)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRIg { + confess(err("ARGNUM")) if ($#_!=5); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v2,$i3,$i4,$m5)=(shift,get_V(shift),get_V(shift), + ,get_I(shift,8),get_I(shift,8),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|($v2&0xf)).","; + $out.=sprintf("%#06x",($i4<<8|$m5<<4|$i3>>4)).","; + $out.=sprintf("%#06x",(($i3&0xf)<<12|RXB($v1,$v2)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRIh { + confess(err("ARGNUM")) if ($#_!=3); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$i2,$i3)=(shift,get_V(shift),get_I(shift,16), + get_I(shift,4)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)).","; + $out.=sprintf("%#06x",$i2).","; + $out.=sprintf("%#06x",($i3<<12|RXB($v1)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRIi { + confess(err("ARGNUM")) if ($#_!=4); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$r2,$i3,$m4)=(shift,get_V(shift),get_R(shift), + ,get_I(shift,8),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4)|$r2).","; + $out.=sprintf("%#06x",($m4<<4|$i3>>4)).","; + $out.=sprintf("%#06x",(($i3&0xf)<<12|RXB($v1)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRRa { + confess(err("ARGNUM")) if ($#_<2||5<$#_); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v2,$m3,$m4,$m5)=(shift,get_V(shift),get_V(shift), + get_M(shift),get_M(shift),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; + $out.=sprintf("%#06x",($m5<<4|$m4)).","; + $out.=sprintf("%#06x",($m3<<12|RXB($v1,$v2)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRRb { + confess(err("ARGNUM")) if ($#_<3||5<$#_); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v2,$v3,$m4,$m5)=(shift,get_V(shift),get_V(shift), + get_V(shift),get_M(shift),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; + $out.=sprintf("%#06x",(($v3&0xf)<<12|$m5<<4)).","; + $out.=sprintf("%#06x",($m4<<12|RXB($v1,$v2,$v3)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRRc { + confess(err("ARGNUM")) if ($#_<3||6<$#_); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v2,$v3,$m4,$m5,$m6)=(shift,get_V(shift),get_V(shift), + get_V(shift),get_M(shift),get_M(shift),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; + $out.=sprintf("%#06x",(($v3&0xf)<<12|$m6<<4|$m5)).","; + $out.=sprintf("%#06x",($m4<<12|RXB($v1,$v2,$v3)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRRd { + confess(err("ARGNUM")) if ($#_<4||6<$#_); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v2,$v3,$v4,$m5,$m6)=(shift,get_V(shift),get_V(shift), + get_V(shift),get_V(shift),get_M(shift),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; + $out.=sprintf("%#06x",(($v3&0xf)<<12|$m5<<8|$m6<<4)).","; + $out.=sprintf("%#06x",(($v4&0xf)<<12|RXB($v1,$v2,$v3,$v4)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRRe { + confess(err("ARGNUM")) if ($#_<4||6<$#_); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v2,$v3,$v4,$m5,$m6)=(shift,get_V(shift),get_V(shift), + get_V(shift),get_V(shift),get_M(shift),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; + $out.=sprintf("%#06x",(($v3&0xf)<<12|$m6<<8|$m5)).","; + $out.=sprintf("%#06x",(($v4&0xf)<<12|RXB($v1,$v2,$v3,$v4)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRRf { + confess(err("ARGNUM")) if ($#_!=3); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$r2,$r3)=(shift,get_V(shift),get_R(shift), + get_R(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|$r2)).","; + $out.=sprintf("%#06x",($r3<<12)).","; + $out.=sprintf("%#06x",(RXB($v1)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRRg { + confess(err("ARGNUM")) if ($#_!=1); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1)=(shift,get_V(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf))).","; + $out.=sprintf("%#06x",0x0000).","; + $out.=sprintf("%#06x",(RXB(0,$v1)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRRh { + confess(err("ARGNUM")) if ($#_<2||$#_>3); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v2,$m3)=(shift,get_V(shift),get_V(shift), + get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf))).","; + $out.=sprintf("%#06x",(($v2&0xf)<<12|$m3<<4)).","; + $out.=sprintf("%#06x",(RXB(0,$v1,$v2)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRRi { + confess(err("ARGNUM")) if ($#_!=3); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$r1,$v2,$m3)=(shift,get_R(shift),get_V(shift), + get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|$r1<<4|($v2&0xf))).","; + $out.=sprintf("%#06x",($m3<<4))."\,"; + $out.=sprintf("%#06x",(RXB(0,$v2)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRSa { + confess(err("ARGNUM")) if ($#_<3||$#_>4); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$v3,$d2,$b2,$m4)=(shift,get_V(shift),get_V(shift), + get_DB(shift),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v3&0xf))).","; + $out.=sprintf("%#06x",($b2<<12|$d2)).","; + $out.=sprintf("%#06x",($m4<<12|RXB($v1,$v3)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRSb { + confess(err("ARGNUM")) if ($#_<3||$#_>4); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$r3,$d2,$b2,$m4)=(shift,get_V(shift),get_R(shift), + get_DB(shift),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|$r3)).","; + $out.=sprintf("%#06x",($b2<<12|$d2)).","; + $out.=sprintf("%#06x",($m4<<12|RXB($v1)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRSc { + confess(err("ARGNUM")) if ($#_!=4); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$r1,$v3,$d2,$b2,$m4)=(shift,get_R(shift),get_V(shift), + get_DB(shift),get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|$r1<<4|($v3&0xf))).","; + $out.=sprintf("%#06x",($b2<<12|$d2)).","; + $out.=sprintf("%#06x",($m4<<12|RXB(0,$v3)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRSd { + confess(err("ARGNUM")) if ($#_!=3); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$r3,$d2,$b2)=(shift,get_V(shift),get_R(shift), + get_DB(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|$r3)).","; + $out.=sprintf("%#06x",($b2<<12|$d2)).","; + $out.=sprintf("%#06x",(($v1&0xf)<<12|RXB(0,0,0,$v1)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRV { + confess(err("ARGNUM")) if ($#_<2||$#_>3); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$d2,$v2,$b2,$m3)=(shift,get_V(shift),get_DVB(shift), + get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($v2&0xf))).","; + $out.=sprintf("%#06x",($b2<<12|$d2)).","; + $out.=sprintf("%#06x",($m3<<12|RXB($v1,$v2)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VRX { + confess(err("ARGNUM")) if ($#_<2||$#_>3); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$d2,$x2,$b2,$m3)=(shift,get_V(shift),get_DXB(shift), + get_M(shift)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|($v1&0xf)<<4|($x2))).","; + $out.=sprintf("%#06x",($b2<<12|$d2)).","; + $out.=sprintf("%#06x",($m3<<12|RXB($v1)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +sub VSI { + confess(err("ARGNUM")) if ($#_!=3); + my $ops=join(',',@_[1..$#_]); + my $memn=(caller(1))[3]; + $memn=~s/^.*:://; + my ($opcode,$v1,$d2,$b2,$i3)=(shift,get_V(shift),get_DB(shift), + get_I(shift,8)); + + $out.="\t.word\t"; + $out.=sprintf("%#06x",($opcode&0xff00|$i3)).","; + $out.=sprintf("%#06x",($b2<<12|$d2)).","; + $out.=sprintf("%#06x",(($v1&0xf)<<12|RXB(0,0,0,$v1)<<8|$opcode&0xff)); + $out.="\t# $memn\t$ops\n"; +} + +# +# Internal +# + +sub get_R { + confess(err("ARGNUM")) if ($#_!=0); + my $r; + + for (shift) { + if (!defined) { + $r=0; + } elsif (/^$GR$/) { + $r=$1; + } else { + confess(err("PARSE")); + } + } + confess(err("ARGRANGE")) if ($r&~0xf); + + return $r; +} + +sub get_V { + confess(err("ARGNUM")) if ($#_!=0); + my $v; + + for (shift) { + if (!defined) { + $v=0; + } elsif (/^$VR$/) { + $v=$1; + } else { + confess(err("PARSE")); + } + } + confess(err("ARGRANGE")) if ($v&~0x1f); + + return $v; +} + +sub get_I { + confess(err("ARGNUM")) if ($#_!=1); + my ($i,$bits)=(shift,shift); + + $i=defined($i)?(eval($i)):(0); + confess(err("PARSE")) if (!defined($i)); + confess(err("ARGRANGE")) if (abs($i)&~(2**$bits-1)); + + return $i&(2**$bits-1); +} + +sub get_M { + confess(err("ARGNUM")) if ($#_!=0); + my $m=shift; + + $m=defined($m)?(eval($m)):(0); + confess(err("PARSE")) if (!defined($m)); + confess(err("ARGRANGE")) if ($m&~0xf); + + return $m; +} + +sub get_DB +{ + confess(err("ARGNUM")) if ($#_!=0); + my ($d,$b); + + for (shift) { + if (!defined) { + ($d,$b)=(0,0); + } elsif (/^(.+)\($GR\)$/) { + ($d,$b)=(eval($1),$2); + confess(err("PARSE")) if (!defined($d)); + } elsif (/^(.+)$/) { + ($d,$b)=(eval($1),0); + confess(err("PARSE")) if (!defined($d)); + } else { + confess(err("PARSE")); + } + } + confess(err("ARGRANGE")) if ($d&~0xfff||$b&~0xf); + + return ($d,$b); +} + +sub get_DVB +{ + confess(err("ARGNUM")) if ($#_!=0); + my ($d,$v,$b); + + for (shift) { + if (!defined) { + ($d,$v,$b)=(0,0,0); + } elsif (/^(.+)\($VR,$GR\)$/) { + ($d,$v,$b)=(eval($1),$2,$3); + confess(err("PARSE")) if (!defined($d)); + } elsif (/^(.+)\($GR\)$/) { + ($d,$v,$b)=(eval($1),0,$2); + confess(err("PARSE")) if (!defined($d)); + } elsif (/^(.+)$/) { + ($d,$v,$b)=(eval($1),0,0); + confess(err("PARSE")) if (!defined($d)); + } else { + confess(err("PARSE")); + } + } + confess(err("ARGRANGE")) if ($d&~0xfff||$v&~0x1f||$b&~0xf); + + return ($d,$v,$b); +} + +sub get_DXB +{ + confess(err("ARGNUM")) if ($#_!=0); + my ($d,$x,$b); + + for (shift) { + if (!defined) { + ($d,$x,$b)=(0,0,0); + } elsif (/^(.+)\($GR,$GR\)$/) { + ($d,$x,$b)=(eval($1),$2,$3); + confess(err("PARSE")) if (!defined($d)); + } elsif (/^(.+)\($GR\)$/) { + ($d,$x,$b)=(eval($1),0,$2); + confess(err("PARSE")) if (!defined($d)); + } elsif (/^(.+)$/) { + ($d,$x,$b)=(eval($1),0,0); + confess(err("PARSE")) if (!defined($d)); + } else { + confess(err("PARSE")); + } + } + confess(err("ARGRANGE")) if ($d&~0xfff||$x&~0xf||$b&~0xf); + + return ($d,$x,$b); +} + +sub RXB +{ + confess(err("ARGNUM")) if ($#_<0||3<$#_); + my $rxb=0; + + $rxb|=0x08 if (defined($_[0])&&($_[0]&0x10)); + $rxb|=0x04 if (defined($_[1])&&($_[1]&0x10)); + $rxb|=0x02 if (defined($_[2])&&($_[2]&0x10)); + $rxb|=0x01 if (defined($_[3])&&($_[3]&0x10)); + + return $rxb; +} + +sub err { + my %ERR = + ( + ARGNUM => 'Wrong number of arguments', + ARGRANGE=> 'Argument out of range', + PARSE => 'Parse error', + ); + confess($ERR{ARGNUM}) if ($#_!=0); + + return $ERR{$_[0]}; +} + +1; diff --git a/crypto/openssl/crypto/perlasm/sparcv9_modes.pl b/crypto/openssl/crypto/perlasm/sparcv9_modes.pl index b9922e031893..76a2727aba62 100755 --- a/crypto/openssl/crypto/perlasm/sparcv9_modes.pl +++ b/crypto/openssl/crypto/perlasm/sparcv9_modes.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 diff --git a/crypto/openssl/crypto/perlasm/x86_64-support.pl b/crypto/openssl/crypto/perlasm/x86_64-support.pl new file mode 100644 index 000000000000..0bacb7186469 --- /dev/null +++ b/crypto/openssl/crypto/perlasm/x86_64-support.pl @@ -0,0 +1,51 @@ +#! /usr/bin/env perl +# Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +package x86_64support; + +# require "x86_64-support.pl"; +# $ptr_size=&pointer_size($flavour); +# $ptr_reg=&pointer_register($flavour,$reg); + +sub ::pointer_size +{ + my($flavour)=@_; + my $ptr_size=8; $ptr_size=4 if ($flavour eq "elf32"); + return $ptr_size; +} + +sub ::pointer_register +{ + my($flavour,$reg)=@_; + if ($flavour eq "elf32") { + if ($reg eq "%rax") { + return "%eax"; + } elsif ($reg eq "%rbx") { + return "%ebx"; + } elsif ($reg eq "%rcx") { + return "%ecx"; + } elsif ($reg eq "%rdx") { + return "%edx"; + } elsif ($reg eq "%rdi") { + return "%edi"; + } elsif ($reg eq "%rsi") { + return "%esi"; + } elsif ($reg eq "%rbp") { + return "%ebp"; + } elsif ($reg eq "%rsp") { + return "%esp"; + } else { + return $reg."d"; + } + } else { + return $reg; + } +} + +1; diff --git a/crypto/openssl/crypto/perlasm/x86_64-xlate.pl b/crypto/openssl/crypto/perlasm/x86_64-xlate.pl index 59af6df9c200..1830b2556599 100755 --- a/crypto/openssl/crypto/perlasm/x86_64-xlate.pl +++ b/crypto/openssl/crypto/perlasm/x86_64-xlate.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -83,6 +83,10 @@ my $PTR=" PTR"; my $nasmref=2.03; my $nasm=0; +# GNU as indicator, as opposed to $gas, which indicates acceptable +# syntax +my $gnuas=0; + if ($flavour eq "mingw64") { $gas=1; $elf=0; $win64=1; $prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`; $prefix =~ s|\R$||; # Better chomp @@ -100,6 +104,51 @@ elsif (!$gas) $elf=0; $decor="\$L\$"; } +# Find out if we're using GNU as +elsif (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` + =~ /GNU assembler version ([2-9]\.[0-9]+)/) +{ + $gnuas=1; +} +elsif (`$ENV{CC} --version 2>/dev/null` + =~ /clang .*/) +{ + $gnuas=1; +} + +my $cet_property; +if ($flavour =~ /elf/) { + # Always generate .note.gnu.property section for ELF outputs to + # mark Intel CET support since all input files must be marked + # with Intel CET support in order for linker to mark output with + # Intel CET support. + my $p2align=3; $p2align=2 if ($flavour eq "elf32"); + my $section='.note.gnu.property, #alloc'; + $section='".note.gnu.property", "a"' if $gnuas; + $cet_property = <<_____; + .section $section + .p2align $p2align + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align $p2align + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align $p2align +4: +_____ +} my $current_segment; my $current_function; @@ -1151,7 +1200,7 @@ while(defined(my $line=<>)) { $line =~ s|[#!].*$||; # get rid of asm-style comments... $line =~ s|/\*.*\*/||; # ... and C-style comments... - $line =~ s|^\s+||; # ... and skip white spaces in beginning + $line =~ s|^\s+||; # ... and skip whitespaces in beginning $line =~ s|\s+$||; # ... and at the end if (my $label=label->re(\$line)) { print $label->out(); } @@ -1213,10 +1262,11 @@ while(defined(my $line=<>)) { print $line,"\n"; } +print "$cet_property" if ($cet_property); print "\n$current_segment\tENDS\n" if ($current_segment && $masm); print "END\n" if ($masm); -close STDOUT or die "error closing STDOUT: $!"; +close STDOUT or die "error closing STDOUT: $!;" ################################################# # Cross-reference x86_64 ABI "card" diff --git a/crypto/openssl/crypto/perlasm/x86asm.pl b/crypto/openssl/crypto/perlasm/x86asm.pl index 29dc1a2cfbc9..8dcde9eacaa3 100755 --- a/crypto/openssl/crypto/perlasm/x86asm.pl +++ b/crypto/openssl/crypto/perlasm/x86asm.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -174,7 +174,9 @@ sub ::vprotd sub ::endbranch { + &::generic("#ifdef __CET__\n"); &::data_byte(0xf3,0x0f,0x1e,0xfb); + &::generic("#endif\n"); } # label management diff --git a/crypto/openssl/crypto/perlasm/x86gas.pl b/crypto/openssl/crypto/perlasm/x86gas.pl index 5c7ea3880e4d..1b2b27c02286 100755 --- a/crypto/openssl/crypto/perlasm/x86gas.pl +++ b/crypto/openssl/crypto/perlasm/x86gas.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -124,6 +124,7 @@ sub ::function_begin_B push(@out,".align\t$align\n"); push(@out,"$func:\n"); push(@out,"$begin:\n") if ($global); + &::endbranch(); $::stack=4; } @@ -172,6 +173,26 @@ sub ::file_end else { push (@out,"$tmp\n"); } } push(@out,$initseg) if ($initseg); + if ($::elf) { + push(@out," + .section \".note.gnu.property\", \"a\" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz \"GNU\" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: +"); + } } sub ::data_byte { push(@out,".byte\t".join(',',@_)."\n"); } diff --git a/crypto/openssl/crypto/perlasm/x86masm.pl b/crypto/openssl/crypto/perlasm/x86masm.pl index dffee762115f..2dcd3f79f6ed 100755 --- a/crypto/openssl/crypto/perlasm/x86masm.pl +++ b/crypto/openssl/crypto/perlasm/x86masm.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 diff --git a/crypto/openssl/crypto/perlasm/x86nasm.pl b/crypto/openssl/crypto/perlasm/x86nasm.pl index 4e64dad92d12..7017b88e80a3 100755 --- a/crypto/openssl/crypto/perlasm/x86nasm.pl +++ b/crypto/openssl/crypto/perlasm/x86nasm.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 diff --git a/crypto/openssl/crypto/pkcs12/p12_add.c b/crypto/openssl/crypto/pkcs12/p12_add.c index af184c86af5d..6fd4184af5a5 100644 --- a/crypto/openssl/crypto/pkcs12/p12_add.c +++ b/crypto/openssl/crypto/pkcs12/p12_add.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,8 +9,11 @@ #include #include "internal/cryptlib.h" +#include +#include #include #include "p12_local.h" +#include "crypto/pkcs7/pk7_local.h" /* Pack an object into an OCTET STRING and turn into a safebag */ @@ -21,16 +24,16 @@ PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, PKCS12_SAFEBAG *safebag; if ((bag = PKCS12_BAGS_new()) == NULL) { - PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return NULL; } bag->type = OBJ_nid2obj(nid1); if (!ASN1_item_pack(obj, it, &bag->value.octet)) { - PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); goto err; } if ((safebag = PKCS12_SAFEBAG_new()) == NULL) { - PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); goto err; } safebag->value.bag = bag; @@ -48,17 +51,17 @@ PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk) PKCS7 *p7; if ((p7 = PKCS7_new()) == NULL) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return NULL; } p7->type = OBJ_nid2obj(NID_pkcs7_data); if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); goto err; } if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CANT_PACK_STRUCTURE); goto err; } return p7; @@ -72,8 +75,7 @@ PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk) STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) { if (!PKCS7_type_is_data(p7)) { - PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA, - PKCS12_R_CONTENT_TYPE_NOT_DATA); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA); return NULL; } return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS)); @@ -81,67 +83,91 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) /* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */ -PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, - unsigned char *salt, int saltlen, int iter, - STACK_OF(PKCS12_SAFEBAG) *bags) +PKCS7 *PKCS12_pack_p7encdata_ex(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + STACK_OF(PKCS12_SAFEBAG) *bags, + OSSL_LIB_CTX *ctx, const char *propq) { PKCS7 *p7; X509_ALGOR *pbe; - const EVP_CIPHER *pbe_ciph; + const EVP_CIPHER *pbe_ciph = NULL; + EVP_CIPHER *pbe_ciph_fetch = NULL; - if ((p7 = PKCS7_new()) == NULL) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); + if ((p7 = PKCS7_new_ex(ctx, propq)) == NULL) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return NULL; } if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, - PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE); goto err; } - pbe_ciph = EVP_get_cipherbynid(pbe_nid); + ERR_set_mark(); + pbe_ciph = pbe_ciph_fetch = EVP_CIPHER_fetch(ctx, OBJ_nid2sn(pbe_nid), propq); + if (pbe_ciph == NULL) + pbe_ciph = EVP_get_cipherbynid(pbe_nid); + ERR_pop_to_mark(); - if (pbe_ciph) - pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen); - else - pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); + if (pbe_ciph != NULL) { + pbe = PKCS5_pbe2_set_iv_ex(pbe_ciph, iter, salt, saltlen, NULL, -1, ctx); + } else { + pbe = PKCS5_pbe_set_ex(pbe_nid, iter, salt, saltlen, ctx); + } - if (!pbe) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); + if (pbe == NULL) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); goto err; } X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm); p7->d.encrypted->enc_data->algorithm = pbe; ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data); if (!(p7->d.encrypted->enc_data->enc_data = - PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, - passlen, bags, 1))) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR); + PKCS12_item_i2d_encrypt_ex(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, + passlen, bags, 1, ctx, propq))) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR); goto err; } + EVP_CIPHER_free(pbe_ciph_fetch); return p7; err: PKCS7_free(p7); + EVP_CIPHER_free(pbe_ciph_fetch); return NULL; } +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + STACK_OF(PKCS12_SAFEBAG) *bags) +{ + return PKCS12_pack_p7encdata_ex(pbe_nid, pass, passlen, salt, saltlen, + iter, bags, NULL, NULL); +} + STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen) { if (!PKCS7_type_is_encrypted(p7)) return NULL; - return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm, + return PKCS12_item_decrypt_d2i_ex(p7->d.encrypted->enc_data->algorithm, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, passlen, - p7->d.encrypted->enc_data->enc_data, 1); + p7->d.encrypted->enc_data->enc_data, 1, + p7->ctx.libctx, p7->ctx.propq); +} + +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey_ex(const PKCS12_SAFEBAG *bag, + const char *pass, int passlen, + OSSL_LIB_CTX *ctx, const char *propq) +{ + return PKCS8_decrypt_ex(bag->value.shkeybag, pass, passlen, ctx, propq); } PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag, const char *pass, int passlen) { - return PKCS8_decrypt(bag->value.shkeybag, pass, passlen); + return PKCS12_decrypt_skey_ex(bag, pass, passlen, NULL, NULL); } int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) @@ -154,11 +180,25 @@ int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12) { + STACK_OF(PKCS7) *p7s; + PKCS7 *p7; + int i; + if (!PKCS7_type_is_data(p12->authsafes)) { - PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES, - PKCS12_R_CONTENT_TYPE_NOT_DATA); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA); return NULL; } - return ASN1_item_unpack(p12->authsafes->d.data, - ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); + p7s = ASN1_item_unpack(p12->authsafes->d.data, + ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); + if (p7s != NULL) { + for (i = 0; i < sk_PKCS7_num(p7s); i++) { + p7 = sk_PKCS7_value(p7s, i); + if (!ossl_pkcs7_ctx_propagate(p12->authsafes, p7)) + goto err; + } + } + return p7s; +err: + sk_PKCS7_free(p7s); + return NULL; } diff --git a/crypto/openssl/crypto/pkcs12/p12_asn.c b/crypto/openssl/crypto/pkcs12/p12_asn.c index 88f145890cf6..aabbd38eefbe 100644 --- a/crypto/openssl/crypto/pkcs12/p12_asn.c +++ b/crypto/openssl/crypto/pkcs12/p12_asn.c @@ -1,7 +1,7 @@ /* * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/pkcs12/p12_attr.c b/crypto/openssl/crypto/pkcs12/p12_attr.c index a958fdf3465e..da228336eb60 100644 --- a/crypto/openssl/crypto/pkcs12/p12_attr.c +++ b/crypto/openssl/crypto/pkcs12/p12_attr.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -18,7 +18,7 @@ int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen) { if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID, - V_ASN1_OCTET_STRING, name, namelen)) + V_ASN1_OCTET_STRING, name, namelen) != NULL) return 1; else return 0; @@ -39,7 +39,7 @@ int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen) { if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, - MBSTRING_ASC, (unsigned char *)name, namelen)) + MBSTRING_ASC, (unsigned char *)name, namelen) != NULL) return 1; else return 0; @@ -49,7 +49,7 @@ int PKCS12_add_friendlyname_utf8(PKCS12_SAFEBAG *bag, const char *name, int namelen) { if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, - MBSTRING_UTF8, (unsigned char *)name, namelen)) + MBSTRING_UTF8, (unsigned char *)name, namelen) != NULL) return 1; else return 0; @@ -59,7 +59,7 @@ int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name, int namelen) { if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, - MBSTRING_BMP, name, namelen)) + MBSTRING_BMP, name, namelen) != NULL) return 1; else return 0; @@ -68,7 +68,25 @@ int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen) { if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name, - MBSTRING_ASC, (unsigned char *)name, namelen)) + MBSTRING_ASC, (unsigned char *)name, namelen) != NULL) + return 1; + else + return 0; +} + +int PKCS12_add1_attr_by_NID(PKCS12_SAFEBAG *bag, int nid, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, nid, type, bytes, len) != NULL) + return 1; + else + return 0; +} + +int PKCS12_add1_attr_by_txt(PKCS12_SAFEBAG *bag, const char *attrname, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&bag->attrib, attrname, type, bytes, len) != NULL) return 1; else return 0; diff --git a/crypto/openssl/crypto/pkcs12/p12_crpt.c b/crypto/openssl/crypto/pkcs12/p12_crpt.c index feef9d1fc4cb..57d1caecfce7 100644 --- a/crypto/openssl/crypto/pkcs12/p12_crpt.c +++ b/crypto/openssl/crypto/pkcs12/p12_crpt.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,6 +9,9 @@ #include #include "internal/cryptlib.h" +#include +#include +#include "crypto/evp.h" #include /* PKCS#12 PBE algorithms now in static table */ @@ -17,21 +20,16 @@ void PKCS12_PBE_add(void) { } -int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, - ASN1_TYPE *param, const EVP_CIPHER *cipher, - const EVP_MD *md, int en_de) +int PKCS12_PBE_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de, + OSSL_LIB_CTX *libctx, const char *propq) { PBEPARAM *pbe; int saltlen, iter, ret; unsigned char *salt; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; - int (*pkcs12_key_gen)(const char *pass, int passlen, - unsigned char *salt, int slen, - int id, int iter, int n, - unsigned char *out, - const EVP_MD *md_type); - - pkcs12_key_gen = PKCS12_key_gen_utf8; + unsigned char *piv = iv; if (cipher == NULL) return 0; @@ -40,31 +38,48 @@ int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param); if (pbe == NULL) { - PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); return 0; } - if (!pbe->iter) + if (pbe->iter == NULL) iter = 1; else iter = ASN1_INTEGER_get(pbe->iter); salt = pbe->salt->data; saltlen = pbe->salt->length; - if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_KEY_ID, - iter, EVP_CIPHER_key_length(cipher), key, md)) { - PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_KEY_GEN_ERROR); + if (!PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, PKCS12_KEY_ID, + iter, EVP_CIPHER_get_key_length(cipher), + key, md, + libctx, propq)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); PBEPARAM_free(pbe); return 0; } - if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_IV_ID, - iter, EVP_CIPHER_iv_length(cipher), iv, md)) { - PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_IV_GEN_ERROR); - PBEPARAM_free(pbe); - return 0; + if (EVP_CIPHER_get_iv_length(cipher) > 0) { + if (!PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, PKCS12_IV_ID, + iter, EVP_CIPHER_get_iv_length(cipher), + iv, md, + libctx, propq)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_IV_GEN_ERROR); + PBEPARAM_free(pbe); + return 0; + } + } else { + piv = NULL; } PBEPARAM_free(pbe); - ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de); + ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, piv, en_de); OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); return ret; } + +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de) +{ + return PKCS12_PBE_keyivgen_ex(ctx, pass, passlen, param, cipher, md, en_de, + NULL, NULL); +} + diff --git a/crypto/openssl/crypto/pkcs12/p12_crt.c b/crypto/openssl/crypto/pkcs12/p12_crt.c index bfcae3f697e9..00c71297463d 100644 --- a/crypto/openssl/crypto/pkcs12/p12_crt.c +++ b/crypto/openssl/crypto/pkcs12/p12_crt.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -28,9 +28,10 @@ static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid) return 1; } -PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, - STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, - int mac_iter, int keytype) +PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, + int iter, int mac_iter, int keytype, + OSSL_LIB_CTX *ctx, const char *propq) { PKCS12 *p12 = NULL; STACK_OF(PKCS7) *safes = NULL; @@ -41,21 +42,17 @@ PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 * unsigned int keyidlen = 0; /* Set defaults */ - if (!nid_cert) -#ifdef OPENSSL_NO_RC2 - nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; -#else - nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; -#endif - if (!nid_key) - nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + if (nid_cert == NID_undef) + nid_cert = NID_aes_256_cbc; + if (nid_key == NID_undef) + nid_key = NID_aes_256_cbc; if (!iter) iter = PKCS12_DEFAULT_ITER; if (!mac_iter) - mac_iter = 1; + mac_iter = PKCS12_DEFAULT_ITER; - if (!pkey && !cert && !ca) { - PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT); + if (pkey == NULL && cert == NULL && ca == NULL) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_ARGUMENT); return NULL; } @@ -80,14 +77,16 @@ PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 * goto err; } - if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass)) + if (bags && !PKCS12_add_safe_ex(&safes, bags, nid_cert, iter, pass, + ctx, propq)) goto err; sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = NULL; if (pkey) { - bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass); + bag = PKCS12_add_key_ex(&bags, pkey, keytype, iter, nid_key, pass, + ctx, propq); if (!bag) goto err; @@ -109,9 +108,9 @@ PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 * sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = NULL; - p12 = PKCS12_add_safes(safes, 0); + p12 = PKCS12_add_safes_ex(safes, 0, ctx, propq); - if (!p12) + if (p12 == NULL) goto err; sk_PKCS7_pop_free(safes, PKCS7_free); @@ -132,6 +131,14 @@ PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 * } +PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, + STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, + int mac_iter, int keytype) +{ + return PKCS12_create_ex(pass, name, pkey, cert, ca, nid_key, nid_cert, + iter, mac_iter, keytype, NULL, NULL); +} + PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert) { PKCS12_SAFEBAG *bag = NULL; @@ -169,9 +176,10 @@ PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert) } -PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, - EVP_PKEY *key, int key_usage, int iter, - int nid_key, const char *pass) +PKCS12_SAFEBAG *PKCS12_add_key_ex(STACK_OF(PKCS12_SAFEBAG) **pbags, + EVP_PKEY *key, int key_usage, int iter, + int nid_key, const char *pass, + OSSL_LIB_CTX *ctx, const char *propq) { PKCS12_SAFEBAG *bag = NULL; @@ -183,8 +191,8 @@ PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, if (key_usage && !PKCS8_add_keyusage(p8, key_usage)) goto err; if (nid_key != -1) { - bag = PKCS12_SAFEBAG_create_pkcs8_encrypt(nid_key, pass, -1, NULL, 0, - iter, p8); + bag = PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(nid_key, pass, -1, NULL, 0, + iter, p8, ctx, propq); PKCS8_PRIV_KEY_INFO_free(p8); } else bag = PKCS12_SAFEBAG_create0_p8inf(p8); @@ -203,19 +211,45 @@ PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, } -int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, - int nid_safe, int iter, const char *pass) +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, + EVP_PKEY *key, int key_usage, int iter, + int nid_key, const char *pass) +{ + return PKCS12_add_key_ex(pbags, key, key_usage, iter, nid_key, pass, + NULL, NULL); +} + +PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags, + int nid_type, const unsigned char *value, int len) +{ + PKCS12_SAFEBAG *bag = NULL; + + /* Add secret, storing the value as an octet string */ + if ((bag = PKCS12_SAFEBAG_create_secret(nid_type, V_ASN1_OCTET_STRING, value, len)) == NULL) + goto err; + + if (!pkcs12_add_bag(pbags, bag)) + goto err; + + return bag; + err: + PKCS12_SAFEBAG_free(bag); + return NULL; +} + +int PKCS12_add_safe_ex(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int nid_safe, int iter, const char *pass, + OSSL_LIB_CTX *ctx, const char *propq) { PKCS7 *p7 = NULL; int free_safes = 0; - if (!*psafes) { + if (*psafes == NULL) { *psafes = sk_PKCS7_new_null(); - if (!*psafes) + if (*psafes == NULL) return 0; free_safes = 1; - } else - free_safes = 0; + } if (nid_safe == 0) #ifdef OPENSSL_NO_RC2 @@ -227,8 +261,8 @@ int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, if (nid_safe == -1) p7 = PKCS12_pack_p7data(bags); else - p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags); - if (!p7) + p7 = PKCS12_pack_p7encdata_ex(nid_safe, pass, -1, NULL, 0, iter, bags, ctx, propq); + if (p7 == NULL) goto err; if (!sk_PKCS7_push(*psafes, p7)) @@ -243,22 +277,27 @@ int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, } PKCS7_free(p7); return 0; +} +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int nid_safe, int iter, const char *pass) +{ + return PKCS12_add_safe_ex(psafes, bags, nid_safe, iter, pass, NULL, NULL); } static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag) { - int free_bags; - if (!pbags) + int free_bags = 0; + + if (pbags == NULL) return 1; - if (!*pbags) { + if (*pbags == NULL) { *pbags = sk_PKCS12_SAFEBAG_new_null(); - if (!*pbags) + if (*pbags == NULL) return 0; free_bags = 1; - } else - free_bags = 0; + } if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) { if (free_bags) { @@ -272,14 +311,15 @@ static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, } -PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7) +PKCS12 *PKCS12_add_safes_ex(STACK_OF(PKCS7) *safes, int nid_p7, + OSSL_LIB_CTX *ctx, const char *propq) { PKCS12 *p12; + if (nid_p7 <= 0) nid_p7 = NID_pkcs7_data; - p12 = PKCS12_init(nid_p7); - - if (!p12) + p12 = PKCS12_init_ex(nid_p7, ctx, propq); + if (p12 == NULL) return NULL; if (!PKCS12_pack_authsafes(p12, safes)) { @@ -290,3 +330,8 @@ PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7) return p12; } + +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7) +{ + return PKCS12_add_safes_ex(safes, nid_p7, NULL, NULL); +} diff --git a/crypto/openssl/crypto/pkcs12/p12_decr.c b/crypto/openssl/crypto/pkcs12/p12_decr.c index 3c860584e80b..a5adafa954a3 100644 --- a/crypto/openssl/crypto/pkcs12/p12_decr.c +++ b/crypto/openssl/crypto/pkcs12/p12_decr.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,48 +10,72 @@ #include #include "internal/cryptlib.h" #include - -/* Define this to dump decrypted output to files called DERnnn */ -/* - * #define OPENSSL_DEBUG_DECRYPT - */ +#include /* * Encrypt/Decrypt a buffer based on password and algor, result in a * OPENSSL_malloc'ed buffer */ -unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, - const char *pass, int passlen, - const unsigned char *in, int inlen, - unsigned char **data, int *datalen, int en_de) +unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor, + const char *pass, int passlen, + const unsigned char *in, int inlen, + unsigned char **data, int *datalen, int en_de, + OSSL_LIB_CTX *libctx, const char *propq) { unsigned char *out = NULL; int outlen, i; EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + int max_out_len, mac_len = 0; if (ctx == NULL) { - PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); goto err; } - /* Decrypt data */ - if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen, - algor->parameter, ctx, en_de)) { - PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, - PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR); + /* Process data */ + if (!EVP_PBE_CipherInit_ex(algor->algorithm, pass, passlen, + algor->parameter, ctx, en_de, libctx, propq)) goto err; + + /* + * GOST algorithm specifics: + * OMAC algorithm calculate and encrypt MAC of the encrypted objects + * It's appended to encrypted text on encrypting + * MAC should be processed on decrypting separately from plain text + */ + max_out_len = inlen + EVP_CIPHER_CTX_get_block_size(ctx); + if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) + & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0) { + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, 0, &mac_len) < 0) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { + max_out_len += mac_len; + } else { + if (inlen < mac_len) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_UNSUPPORTED_PKCS12_MODE); + goto err; + } + inlen -= mac_len; + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + (int)mac_len, (unsigned char *)in+inlen) < 0) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR); + goto err; + } + } } - if ((out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(ctx))) - == NULL) { - PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE); + if ((out = OPENSSL_malloc(max_out_len)) == NULL) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_CipherUpdate(ctx, out, &i, in, inlen)) { OPENSSL_free(out); out = NULL; - PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_PKCS12, ERR_R_EVP_LIB); goto err; } @@ -59,11 +83,25 @@ unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, if (!EVP_CipherFinal_ex(ctx, out + i, &i)) { OPENSSL_free(out); out = NULL; - PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, - PKCS12_R_PKCS12_CIPHERFINAL_ERROR); + ERR_raise_data(ERR_LIB_PKCS12, PKCS12_R_PKCS12_CIPHERFINAL_ERROR, + passlen == 0 ? "empty password" + : "maybe wrong password"); goto err; } outlen += i; + if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) + & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, + (int)mac_len, out+outlen) < 0) { + OPENSSL_free(out); + out = NULL; + ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR); + goto err; + } + outlen += mac_len; + } + } if (datalen) *datalen = outlen; if (data) @@ -74,74 +112,85 @@ unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, } +unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, + const char *pass, int passlen, + const unsigned char *in, int inlen, + unsigned char **data, int *datalen, int en_de) +{ + return PKCS12_pbe_crypt_ex(algor, pass, passlen, in, inlen, data, datalen, + en_de, NULL, NULL); +} + /* * Decrypt an OCTET STRING and decode ASN1 structure if zbuf set zero buffer * after use. */ -void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it, - const char *pass, int passlen, - const ASN1_OCTET_STRING *oct, int zbuf) +void *PKCS12_item_decrypt_d2i_ex(const X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + const ASN1_OCTET_STRING *oct, int zbuf, + OSSL_LIB_CTX *libctx, + const char *propq) { - unsigned char *out; + unsigned char *out = NULL; const unsigned char *p; void *ret; - int outlen; + int outlen = 0; - if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length, - &out, &outlen, 0)) { - PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, - PKCS12_R_PKCS12_PBE_CRYPT_ERROR); + if (!PKCS12_pbe_crypt_ex(algor, pass, passlen, oct->data, oct->length, + &out, &outlen, 0, libctx, propq)) return NULL; - } p = out; -#ifdef OPENSSL_DEBUG_DECRYPT - { - FILE *op; - - char fname[30]; - static int fnm = 1; - sprintf(fname, "DER%d", fnm++); - op = fopen(fname, "wb"); - fwrite(p, 1, outlen, op); - fclose(op); - } -#endif + OSSL_TRACE_BEGIN(PKCS12_DECRYPT) { + BIO_printf(trc_out, "\n"); + BIO_dump(trc_out, out, outlen); + BIO_printf(trc_out, "\n"); + } OSSL_TRACE_END(PKCS12_DECRYPT); ret = ASN1_item_d2i(NULL, &p, outlen, it); if (zbuf) OPENSSL_cleanse(out, outlen); if (!ret) - PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, PKCS12_R_DECODE_ERROR); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); OPENSSL_free(out); return ret; } +void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + const ASN1_OCTET_STRING *oct, int zbuf) +{ + return PKCS12_item_decrypt_d2i_ex(algor, it, pass, passlen, oct, zbuf, + NULL, NULL); +} + /* * Encode ASN1 structure and encrypt, return OCTET STRING if zbuf set zero * encoding. */ -ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, - const ASN1_ITEM *it, - const char *pass, int passlen, - void *obj, int zbuf) +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt_ex(X509_ALGOR *algor, + const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf, + OSSL_LIB_CTX *ctx, + const char *propq) { ASN1_OCTET_STRING *oct = NULL; unsigned char *in = NULL; int inlen; if ((oct = ASN1_OCTET_STRING_new()) == NULL) { - PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); goto err; } inlen = ASN1_item_i2d(obj, &in, it); if (!in) { - PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCODE_ERROR); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR); goto err; } - if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data, - &oct->length, 1)) { - PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); + if (!PKCS12_pbe_crypt_ex(algor, pass, passlen, in, inlen, &oct->data, + &oct->length, 1, ctx, propq)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR); OPENSSL_free(in); goto err; } @@ -153,3 +202,11 @@ ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, ASN1_OCTET_STRING_free(oct); return NULL; } + +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf) +{ + return PKCS12_item_i2d_encrypt_ex(algor, it, pass, passlen, obj, zbuf, NULL, NULL); +} diff --git a/crypto/openssl/crypto/pkcs12/p12_init.c b/crypto/openssl/crypto/pkcs12/p12_init.c index 7ecc29ec0ce0..45aa2f9154b9 100644 --- a/crypto/openssl/crypto/pkcs12/p12_init.c +++ b/crypto/openssl/crypto/pkcs12/p12_init.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,30 +10,38 @@ #include #include "internal/cryptlib.h" #include +#include "crypto/pkcs7.h" #include "p12_local.h" /* Initialise a PKCS12 structure to take data */ -PKCS12 *PKCS12_init(int mode) +PKCS12 *PKCS12_init_ex(int mode, OSSL_LIB_CTX *ctx, const char *propq) { PKCS12 *pkcs12; if ((pkcs12 = PKCS12_new()) == NULL) { - PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return NULL; } if (!ASN1_INTEGER_set(pkcs12->version, 3)) goto err; pkcs12->authsafes->type = OBJ_nid2obj(mode); + + ossl_pkcs7_set0_libctx(pkcs12->authsafes, ctx); + if (!ossl_pkcs7_set1_propq(pkcs12->authsafes, propq)) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + goto err; + } + switch (mode) { case NID_pkcs7_data: if ((pkcs12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL) { - PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); goto err; } break; default: - PKCS12err(PKCS12_F_PKCS12_INIT, PKCS12_R_UNSUPPORTED_PKCS12_MODE); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_UNSUPPORTED_PKCS12_MODE); goto err; } return pkcs12; @@ -42,3 +50,9 @@ PKCS12 *PKCS12_init(int mode) PKCS12_free(pkcs12); return NULL; } + +PKCS12 *PKCS12_init(int mode) +{ + return PKCS12_init_ex(mode, NULL, NULL); +} + diff --git a/crypto/openssl/crypto/pkcs12/p12_key.c b/crypto/openssl/crypto/pkcs12/p12_key.c index 03eda2664251..41a2d7293e91 100644 --- a/crypto/openssl/crypto/pkcs12/p12_key.c +++ b/crypto/openssl/crypto/pkcs12/p12_key.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,173 +11,128 @@ #include "internal/cryptlib.h" #include #include +#include +#include +#include +#include "internal/provider.h" -/* Uncomment out this line to get debugging info about key generation */ -/* - * #define OPENSSL_DEBUG_KEYGEN - */ -#ifdef OPENSSL_DEBUG_KEYGEN -# include -extern BIO *bio_err; -void h__dump(unsigned char *p, int len); -#endif - -/* PKCS12 compatible key/IV generation */ -#ifndef min -# define min(a,b) ((a) < (b) ? (a) : (b)) -#endif - -int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, - int saltlen, int id, int iter, int n, - unsigned char *out, const EVP_MD *md_type) +int PKCS12_key_gen_asc_ex(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type, + OSSL_LIB_CTX *ctx, const char *propq) { int ret; unsigned char *unipass; int uniplen; - if (!pass) { + if (pass == NULL) { unipass = NULL; uniplen = 0; } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { - PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return 0; } - ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, - id, iter, n, out, md_type); - if (ret <= 0) - return 0; + ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter, + n, out, md_type, ctx, propq); OPENSSL_clear_free(unipass, uniplen); - return ret; + return ret > 0; } -int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt, - int saltlen, int id, int iter, int n, - unsigned char *out, const EVP_MD *md_type) +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type) +{ + return PKCS12_key_gen_asc_ex(pass, passlen, salt, saltlen, id, iter, n, + out, md_type, NULL, NULL); +} + +int PKCS12_key_gen_utf8_ex(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type, + OSSL_LIB_CTX *ctx, const char *propq) { int ret; unsigned char *unipass; int uniplen; - if (!pass) { + if (pass == NULL) { unipass = NULL; uniplen = 0; } else if (!OPENSSL_utf82uni(pass, passlen, &unipass, &uniplen)) { - PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UTF8, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return 0; } - ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, - id, iter, n, out, md_type); - if (ret <= 0) - return 0; + ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter, + n, out, md_type, ctx, propq); OPENSSL_clear_free(unipass, uniplen); - return ret; + return ret > 0; } -int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, - int saltlen, int id, int iter, int n, - unsigned char *out, const EVP_MD *md_type) +int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type) { - unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL; - int Slen, Plen, Ilen; - int i, j, u, v; - int ret = 0; - EVP_MD_CTX *ctx = NULL; -#ifdef OPENSSL_DEBUG_KEYGEN - unsigned char *tmpout = out; - int tmpn = n; -#endif + return PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, id, iter, n, + out, md_type, NULL, NULL); +} - ctx = EVP_MD_CTX_new(); - if (ctx == NULL) - goto err; +int PKCS12_key_gen_uni_ex(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int res = 0; + EVP_KDF *kdf; + EVP_KDF_CTX *ctx; + OSSL_PARAM params[6], *p = params; + + if (n <= 0) + return 0; -#ifdef OPENSSL_DEBUG_KEYGEN - fprintf(stderr, "KEYGEN DEBUG\n"); - fprintf(stderr, "ID %d, ITER %d\n", id, iter); - fprintf(stderr, "Password (length %d):\n", passlen); - h__dump(pass, passlen); - fprintf(stderr, "Salt (length %d):\n", saltlen); - h__dump(salt, saltlen); -#endif - v = EVP_MD_block_size(md_type); - u = EVP_MD_size(md_type); - if (u <= 0 || v <= 0) - goto err; - D = OPENSSL_malloc(v); - Ai = OPENSSL_malloc(u); - B = OPENSSL_malloc(v + 1); - Slen = v * ((saltlen + v - 1) / v); - if (passlen) - Plen = v * ((passlen + v - 1) / v); - else - Plen = 0; - Ilen = Slen + Plen; - I = OPENSSL_malloc(Ilen); - if (D == NULL || Ai == NULL || B == NULL || I == NULL) - goto err; - for (i = 0; i < v; i++) - D[i] = id; - p = I; - for (i = 0; i < Slen; i++) - *p++ = salt[i % saltlen]; - for (i = 0; i < Plen; i++) - *p++ = pass[i % passlen]; - for (;;) { - if (!EVP_DigestInit_ex(ctx, md_type, NULL) - || !EVP_DigestUpdate(ctx, D, v) - || !EVP_DigestUpdate(ctx, I, Ilen) - || !EVP_DigestFinal_ex(ctx, Ai, NULL)) - goto err; - for (j = 1; j < iter; j++) { - if (!EVP_DigestInit_ex(ctx, md_type, NULL) - || !EVP_DigestUpdate(ctx, Ai, u) - || !EVP_DigestFinal_ex(ctx, Ai, NULL)) - goto err; - } - memcpy(out, Ai, min(n, u)); - if (u >= n) { -#ifdef OPENSSL_DEBUG_KEYGEN - fprintf(stderr, "Output KEY (length %d)\n", tmpn); - h__dump(tmpout, tmpn); -#endif - ret = 1; - goto end; - } - n -= u; - out += u; - for (j = 0; j < v; j++) - B[j] = Ai[j % u]; - for (j = 0; j < Ilen; j += v) { - int k; - unsigned char *Ij = I + j; - uint16_t c = 1; + kdf = EVP_KDF_fetch(libctx, "PKCS12KDF", propq); + if (kdf == NULL) + return 0; + ctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (ctx == NULL) + return 0; - /* Work out Ij = Ij + B + 1 */ - for (k = v - 1; k >= 0; k--) { - c += Ij[k] + B[k]; - Ij[k] = (unsigned char)c; - c >>= 8; - } - } - } + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)EVP_MD_get0_name(md_type), + 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, + pass, passlen); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + salt, saltlen); + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS12_ID, &id); + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter); + *p = OSSL_PARAM_construct_end(); - err: - PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE); + OSSL_TRACE_BEGIN(PKCS12_KEYGEN) { + BIO_printf(trc_out, "PKCS12_key_gen_uni_ex(): ID %d, ITER %d\n", id, iter); + BIO_printf(trc_out, "Password (length %d):\n", passlen); + BIO_hex_string(trc_out, 0, passlen, pass, passlen); + BIO_printf(trc_out, "\n"); + BIO_printf(trc_out, "Salt (length %d):\n", saltlen); + BIO_hex_string(trc_out, 0, saltlen, salt, saltlen); + BIO_printf(trc_out, "\n"); + } OSSL_TRACE_END(PKCS12_KEYGEN); - end: - OPENSSL_free(Ai); - OPENSSL_free(B); - OPENSSL_free(D); - OPENSSL_free(I); - EVP_MD_CTX_free(ctx); - return ret; + if (EVP_KDF_derive(ctx, out, (size_t)n, params)) { + res = 1; + OSSL_TRACE_BEGIN(PKCS12_KEYGEN) { + BIO_printf(trc_out, "Output KEY (length %d)\n", n); + BIO_hex_string(trc_out, 0, n, out, n); + BIO_printf(trc_out, "\n"); + } OSSL_TRACE_END(PKCS12_KEYGEN); + } + EVP_KDF_CTX_free(ctx); + return res; } -#ifdef OPENSSL_DEBUG_KEYGEN -void h__dump(unsigned char *p, int len) +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type) { - for (; len--; p++) - fprintf(stderr, "%02X", *p); - fprintf(stderr, "\n"); + return PKCS12_key_gen_uni_ex(pass, passlen, salt, saltlen, id, iter, n, out, md_type, NULL, NULL); } -#endif diff --git a/crypto/openssl/crypto/pkcs12/p12_kiss.c b/crypto/openssl/crypto/pkcs12/p12_kiss.c index 7ab98385a7b0..229b34cf6429 100644 --- a/crypto/openssl/crypto/pkcs12/p12_kiss.c +++ b/crypto/openssl/crypto/pkcs12/p12_kiss.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,6 +10,7 @@ #include #include "internal/cryptlib.h" #include +#include "crypto/x509.h" /* for ossl_x509_add_cert_new() */ /* Simplified PKCS#12 routines */ @@ -25,8 +26,8 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, /* * Parse and decrypt a PKCS#12 structure returning user key, user cert and * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it - * should point to a valid STACK structure. pkey and cert can be passed - * uninitialised. + * should point to a valid STACK structure. pkey and/or cert may be NULL; + * if non-NULL the variables they point to can be passed uninitialised. */ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, @@ -35,16 +36,15 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) *ocerts = NULL; X509 *x = NULL; - if (pkey) + if (pkey != NULL) *pkey = NULL; - if (cert) + if (cert != NULL) *cert = NULL; /* Check for NULL PKCS12 structure */ - if (!p12) { - PKCS12err(PKCS12_F_PKCS12_PARSE, - PKCS12_R_INVALID_NULL_PKCS12_POINTER); + if (p12 == NULL) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_PKCS12_POINTER); return 0; } @@ -57,66 +57,70 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, * password are two different things... */ - if (!pass || !*pass) { - if (PKCS12_verify_mac(p12, NULL, 0)) + if (pass == NULL || *pass == '\0') { + if (!PKCS12_mac_present(p12) + || PKCS12_verify_mac(p12, NULL, 0)) pass = NULL; else if (PKCS12_verify_mac(p12, "", 0)) pass = ""; else { - PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE); goto err; } } else if (!PKCS12_verify_mac(p12, pass, -1)) { - PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE); goto err; } - /* Allocate stack for other certificates */ - ocerts = sk_X509_new_null(); - - if (!ocerts) { - PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); + /* If needed, allocate stack for other certificates */ + if ((cert != NULL || ca != NULL) + && (ocerts = sk_X509_new_null()) == NULL) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); goto err; } if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { - PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR); + int err = ERR_peek_last_error(); + + if (ERR_GET_LIB(err) != ERR_LIB_EVP + && ERR_GET_REASON(err) != EVP_R_UNSUPPORTED_ALGORITHM) + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR); goto err; } - while ((x = sk_X509_pop(ocerts))) { - if (pkey && *pkey && cert && !*cert) { + /* Split the certs in ocerts over *cert and *ca as far as requested */ + while ((x = sk_X509_shift(ocerts)) != NULL) { + if (pkey != NULL && *pkey != NULL + && cert != NULL && *cert == NULL) { + int match; + ERR_set_mark(); - if (X509_check_private_key(x, *pkey)) { + match = X509_check_private_key(x, *pkey); + ERR_pop_to_mark(); + if (match) { *cert = x; - x = NULL; + continue; } - ERR_pop_to_mark(); } - if (ca && x) { - if (!*ca) - *ca = sk_X509_new_null(); - if (!*ca) + if (ca != NULL) { + if (!ossl_x509_add_cert_new(ca, x, X509_ADD_FLAG_DEFAULT)) goto err; - if (!sk_X509_push(*ca, x)) - goto err; - x = NULL; + continue; } X509_free(x); } - - sk_X509_pop_free(ocerts, X509_free); + sk_X509_free(ocerts); return 1; err: - if (pkey) { + if (pkey != NULL) { EVP_PKEY_free(*pkey); *pkey = NULL; } - if (cert) { + if (cert != NULL) { X509_free(*cert); *cert = NULL; } @@ -128,6 +132,7 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, /* Parse the outer PKCS#12 structure */ +/* pkey and/or ocerts may be NULL */ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) { @@ -162,6 +167,7 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, return 1; } +/* pkey and/or ocerts may be NULL */ static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) { @@ -174,6 +180,7 @@ static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, return 1; } +/* pkey and/or ocerts may be NULL */ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) { @@ -191,7 +198,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, switch (PKCS12_SAFEBAG_get_nid(bag)) { case NID_keyBag: - if (!pkey || *pkey) + if (pkey == NULL || *pkey != NULL) return 1; *pkey = EVP_PKCS82PKEY(PKCS12_SAFEBAG_get0_p8inf(bag)); if (*pkey == NULL) @@ -199,7 +206,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, break; case NID_pkcs8ShroudedKeyBag: - if (!pkey || *pkey) + if (pkey == NULL || *pkey != NULL) return 1; if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL) return 0; @@ -210,7 +217,8 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, break; case NID_certBag: - if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate) + if (ocerts == NULL + || PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate) return 1; if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL) return 0; @@ -221,6 +229,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, if (fname) { int len, r; unsigned char *data; + len = ASN1_STRING_to_UTF8(&data, fname); if (len >= 0) { r = X509_alias_set1(x509, data, len); diff --git a/crypto/openssl/crypto/pkcs12/p12_local.h b/crypto/openssl/crypto/pkcs12/p12_local.h index 0b52f1e1fed9..acaa27b193fa 100644 --- a/crypto/openssl/crypto/pkcs12/p12_local.h +++ b/crypto/openssl/crypto/pkcs12/p12_local.h @@ -1,7 +1,7 @@ /* * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/pkcs12/p12_mutl.c b/crypto/openssl/crypto/pkcs12/p12_mutl.c index 3658003fe598..afdb8d688ba3 100644 --- a/crypto/openssl/crypto/pkcs12/p12_mutl.c +++ b/crypto/openssl/crypto/pkcs12/p12_mutl.c @@ -1,12 +1,18 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * HMAC low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -76,57 +82,75 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, const EVP_MD *md_type)) { int ret = 0; - const EVP_MD *md_type; + const EVP_MD *md; + EVP_MD *md_fetch; HMAC_CTX *hmac = NULL; unsigned char key[EVP_MAX_MD_SIZE], *salt; int saltlen, iter; + char md_name[80]; int md_size = 0; - int md_type_nid; + int md_nid; const X509_ALGOR *macalg; const ASN1_OBJECT *macoid; - if (pkcs12_key_gen == NULL) - pkcs12_key_gen = PKCS12_key_gen_utf8; - if (!PKCS7_type_is_data(p12->authsafes)) { - PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA); return 0; } salt = p12->mac->salt->data; saltlen = p12->mac->salt->length; - if (!p12->mac->iter) + if (p12->mac->iter == NULL) iter = 1; else iter = ASN1_INTEGER_get(p12->mac->iter); X509_SIG_get0(p12->mac->dinfo, &macalg, NULL); X509_ALGOR_get0(&macoid, NULL, NULL, macalg); - if ((md_type = EVP_get_digestbyobj(macoid)) == NULL) { - PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); + if (OBJ_obj2txt(md_name, sizeof(md_name), macoid, 0) < 0) + return 0; + md = md_fetch = EVP_MD_fetch(p12->authsafes->ctx.libctx, md_name, + p12->authsafes->ctx.propq); + if (md == NULL) + md = EVP_get_digestbynid(OBJ_obj2nid(macoid)); + + if (md == NULL) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); return 0; } - md_size = EVP_MD_size(md_type); - md_type_nid = EVP_MD_type(md_type); + md_size = EVP_MD_get_size(md); + md_nid = EVP_MD_get_type(md); if (md_size < 0) - return 0; - if ((md_type_nid == NID_id_GostR3411_94 - || md_type_nid == NID_id_GostR3411_2012_256 - || md_type_nid == NID_id_GostR3411_2012_512) + goto err; + if ((md_nid == NID_id_GostR3411_94 + || md_nid == NID_id_GostR3411_2012_256 + || md_nid == NID_id_GostR3411_2012_512) && ossl_safe_getenv("LEGACY_GOST_PKCS12") == NULL) { md_size = TK26_MAC_KEY_LEN; if (!pkcs12_gen_gost_mac_key(pass, passlen, salt, saltlen, iter, - md_size, key, md_type)) { - PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR); + md_size, key, md)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); goto err; } - } else - if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID, - iter, md_size, key, md_type)) { - PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR); - goto err; + } else { + if (pkcs12_key_gen != NULL) { + if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID, + iter, md_size, key, md)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); + goto err; + } + } else { + /* Default to UTF-8 password */ + if (!PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, PKCS12_MAC_ID, + iter, md_size, key, md, + p12->authsafes->ctx.libctx, + p12->authsafes->ctx.propq)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); + goto err; + } + } } if ((hmac = HMAC_CTX_new()) == NULL - || !HMAC_Init_ex(hmac, key, md_size, md_type, NULL) + || !HMAC_Init_ex(hmac, key, md_size, md, NULL) || !HMAC_Update(hmac, p12->authsafes->d.data->data, p12->authsafes->d.data->length) || !HMAC_Final(hmac, mac, maclen)) { @@ -137,6 +161,7 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, err: OPENSSL_cleanse(key, sizeof(key)); HMAC_CTX_free(hmac); + EVP_MD_free(md_fetch); return ret; } @@ -154,12 +179,11 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) const ASN1_OCTET_STRING *macoct; if (p12->mac == NULL) { - PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_ABSENT); return 0; } - if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, - PKCS12_key_gen_utf8)) { - PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR); + if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NULL)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); return 0; } X509_SIG_get0(p12->mac->dinfo, NULL, &macoct); @@ -180,23 +204,25 @@ int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, unsigned int maclen; ASN1_OCTET_STRING *macoct; - if (!md_type) - md_type = EVP_sha1(); + if (md_type == NULL) + /* No need to do a fetch as the md_type is used only to get a NID */ + md_type = EVP_sha256(); + if (!iter) + iter = PKCS12_DEFAULT_ITER; if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) { - PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_SETUP_ERROR); return 0; } /* * Note that output mac is forced to UTF-8... */ - if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, - PKCS12_key_gen_utf8)) { - PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR); + if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NULL)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); return 0; } X509_SIG_getm(p12->mac->dinfo, NULL, &macoct); if (!ASN1_OCTET_STRING_set(macoct, mac, maclen)) { - PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_STRING_SET_ERROR); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_STRING_SET_ERROR); return 0; } return 1; @@ -215,30 +241,34 @@ int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, return PKCS12_ERROR; if (iter > 1) { if ((p12->mac->iter = ASN1_INTEGER_new()) == NULL) { - PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return 0; } if (!ASN1_INTEGER_set(p12->mac->iter, iter)) { - PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return 0; } } - if (!saltlen) + if (saltlen == 0) saltlen = PKCS12_SALT_LEN; + else if (saltlen < 0) + return 0; if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) { - PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return 0; } p12->mac->salt->length = saltlen; - if (!salt) { - if (RAND_bytes(p12->mac->salt->data, saltlen) <= 0) + if (salt == NULL) { + if (RAND_bytes_ex(p12->authsafes->ctx.libctx, p12->mac->salt->data, + (size_t)saltlen, 0) <= 0) return 0; - } else + } else { memcpy(p12->mac->salt->data, salt, saltlen); + } X509_SIG_getm(p12->mac->dinfo, &macalg, NULL); - if (!X509_ALGOR_set0(macalg, OBJ_nid2obj(EVP_MD_type(md_type)), + if (!X509_ALGOR_set0(macalg, OBJ_nid2obj(EVP_MD_get_type(md_type)), V_ASN1_NULL, NULL)) { - PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/crypto/openssl/crypto/pkcs12/p12_npas.c b/crypto/openssl/crypto/pkcs12/p12_npas.c index 0334289a89fa..62230bc6187f 100644 --- a/crypto/openssl/crypto/pkcs12/p12_npas.c +++ b/crypto/openssl/crypto/pkcs12/p12_npas.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -33,21 +33,20 @@ int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass) { /* Check for NULL PKCS12 structure */ - if (!p12) { - PKCS12err(PKCS12_F_PKCS12_NEWPASS, - PKCS12_R_INVALID_NULL_PKCS12_POINTER); + if (p12 == NULL) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_PKCS12_POINTER); return 0; } /* Check the mac */ if (!PKCS12_verify_mac(p12, oldpass, -1)) { - PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_MAC_VERIFY_FAILURE); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE); return 0; } if (!newpass_p12(p12, oldpass, newpass)) { - PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_PARSE_ERROR); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR); return 0; } @@ -94,7 +93,7 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) else p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL, pbe_saltlen, pbe_iter, bags); - if (!p7new || !sk_PKCS7_push(newsafes, p7new)) + if (p7new == NULL || !sk_PKCS7_push(newsafes, p7new)) goto err; sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = NULL; @@ -157,8 +156,10 @@ static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, if ((p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)) == NULL) return 0; X509_SIG_get0(bag->value.shkeybag, &shalg, NULL); - if (!alg_get(shalg, &p8_nid, &p8_iter, &p8_saltlen)) + if (!alg_get(shalg, &p8_nid, &p8_iter, &p8_saltlen)) { + PKCS8_PRIV_KEY_INFO_free(p8); return 0; + } p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, p8_iter, p8); PKCS8_PRIV_KEY_INFO_free(p8); @@ -173,8 +174,9 @@ static int alg_get(const X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen) { PBEPARAM *pbe; + pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), alg->parameter); - if (!pbe) + if (pbe == NULL) return 0; *pnid = OBJ_obj2nid(alg->algorithm); *piter = ASN1_INTEGER_get(pbe->iter); diff --git a/crypto/openssl/crypto/pkcs12/p12_p8d.c b/crypto/openssl/crypto/pkcs12/p12_p8d.c index d926a77df87f..449336aa2df1 100644 --- a/crypto/openssl/crypto/pkcs12/p12_p8d.c +++ b/crypto/openssl/crypto/pkcs12/p12_p8d.c @@ -1,7 +1,7 @@ /* - * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,13 +11,22 @@ #include "internal/cryptlib.h" #include -PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass, - int passlen) +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt_ex(const X509_SIG *p8, const char *pass, + int passlen, OSSL_LIB_CTX *ctx, + const char *propq) { const X509_ALGOR *dalg; const ASN1_OCTET_STRING *doct; + X509_SIG_get0(p8, &dalg, &doct); - return PKCS12_item_decrypt_d2i(dalg, + return PKCS12_item_decrypt_d2i_ex(dalg, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass, - passlen, doct, 1); + passlen, doct, 1, ctx, propq); } + +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass, + int passlen) +{ + return PKCS8_decrypt_ex(p8, pass, passlen, NULL, NULL); +} + diff --git a/crypto/openssl/crypto/pkcs12/p12_p8e.c b/crypto/openssl/crypto/pkcs12/p12_p8e.c index 05fc388a9969..9c2753401786 100644 --- a/crypto/openssl/crypto/pkcs12/p12_p8e.c +++ b/crypto/openssl/crypto/pkcs12/p12_p8e.c @@ -1,7 +1,7 @@ /* - * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,30 +9,46 @@ #include #include "internal/cryptlib.h" +#include #include #include "crypto/x509.h" -X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, - const char *pass, int passlen, - unsigned char *salt, int saltlen, int iter, - PKCS8_PRIV_KEY_INFO *p8inf) +X509_SIG *PKCS8_encrypt_ex(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq) { X509_SIG *p8 = NULL; X509_ALGOR *pbe; - if (pbe_nid == -1) - pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen); - else if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) - pbe = PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, pbe_nid); - else { - ERR_clear_error(); - pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); + if (pbe_nid == -1) { + if (cipher == NULL) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + pbe = PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, NULL, -1, + libctx); + } else { + ERR_set_mark(); + if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) { + ERR_clear_last_mark(); + if (cipher == NULL) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + pbe = PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, NULL, + pbe_nid, libctx); + } else { + ERR_pop_to_mark(); + pbe = PKCS5_pbe_set_ex(pbe_nid, iter, salt, saltlen, libctx); + } } - if (!pbe) { - PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB); + if (pbe == NULL) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); return NULL; } - p8 = PKCS8_set0_pbe(pass, passlen, p8inf, pbe); + p8 = PKCS8_set0_pbe_ex(pass, passlen, p8inf, pbe, libctx, propq); if (p8 == NULL) { X509_ALGOR_free(pbe); return NULL; @@ -41,24 +57,34 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, return p8; } -X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen, - PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe) +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8inf) +{ + return PKCS8_encrypt_ex(pbe_nid, cipher, pass, passlen, salt, saltlen, iter, + p8inf, NULL, NULL); +} + +X509_SIG *PKCS8_set0_pbe_ex(const char *pass, int passlen, + PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe, + OSSL_LIB_CTX *ctx, const char *propq) { X509_SIG *p8; ASN1_OCTET_STRING *enckey; enckey = - PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), - pass, passlen, p8inf, 1); + PKCS12_item_i2d_encrypt_ex(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), + pass, passlen, p8inf, 1, ctx, propq); if (!enckey) { - PKCS12err(PKCS12_F_PKCS8_SET0_PBE, PKCS12_R_ENCRYPT_ERROR); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR); return NULL; } p8 = OPENSSL_zalloc(sizeof(*p8)); if (p8 == NULL) { - PKCS12err(PKCS12_F_PKCS8_SET0_PBE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); ASN1_OCTET_STRING_free(enckey); return NULL; } @@ -67,3 +93,9 @@ X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen, return p8; } + +X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen, + PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe) +{ + return PKCS8_set0_pbe_ex(pass, passlen, p8inf, pbe, NULL, NULL); +} diff --git a/crypto/openssl/crypto/pkcs12/p12_sbag.c b/crypto/openssl/crypto/pkcs12/p12_sbag.c index 7cf522786b03..7574c54120c7 100644 --- a/crypto/openssl/crypto/pkcs12/p12_sbag.c +++ b/crypto/openssl/crypto/pkcs12/p12_sbag.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,7 +12,7 @@ #include #include "p12_local.h" -#if OPENSSL_API_COMPAT < 0x10100000L +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid) { return PKCS12_get_attr_gen(bag->attrib, attr_nid); @@ -71,6 +71,16 @@ int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag) return OBJ_obj2nid(bag->value.bag->type); } +const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag) +{ + return bag->value.bag->type; +} + +const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag) +{ + return bag->value.bag->value.other; +} + X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag) { if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag) @@ -103,6 +113,60 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl) NID_x509Crl, NID_crlBag); } +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned char *value, int len) +{ + PKCS12_BAGS *bag; + PKCS12_SAFEBAG *safebag; + + if ((bag = PKCS12_BAGS_new()) == NULL) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + return NULL; + } + bag->type = OBJ_nid2obj(type); + + switch(vtype) { + case V_ASN1_OCTET_STRING: + { + ASN1_OCTET_STRING *strtmp = ASN1_OCTET_STRING_new(); + + if (strtmp == NULL) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + goto err; + } + /* Pack data into an octet string */ + if (!ASN1_OCTET_STRING_set(strtmp, value, len)) { + ASN1_OCTET_STRING_free(strtmp); + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR); + goto err; + } + bag->value.other = ASN1_TYPE_new(); + if (bag->value.other == NULL) { + ASN1_OCTET_STRING_free(strtmp); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + goto err; + } + ASN1_TYPE_set(bag->value.other, vtype, strtmp); + } + break; + + default: + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_TYPE); + goto err; + } + + if ((safebag = PKCS12_SAFEBAG_new()) == NULL) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + goto err; + } + safebag->value.bag = bag; + safebag->type = OBJ_nid2obj(NID_secretBag); + return safebag; + + err: + PKCS12_BAGS_free(bag); + return NULL; +} + /* Turn PKCS8 object into a keybag */ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8) @@ -110,7 +174,7 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8) PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new(); if (bag == NULL) { - PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return NULL; } bag->type = OBJ_nid2obj(NID_keyBag); @@ -126,7 +190,7 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8) /* Set up the safe bag */ if (bag == NULL) { - PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return NULL; } bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag); @@ -134,29 +198,51 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8) return bag; } -PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid, - const char *pass, - int passlen, - unsigned char *salt, - int saltlen, int iter, - PKCS8_PRIV_KEY_INFO *p8inf) +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(int pbe_nid, + const char *pass, + int passlen, + unsigned char *salt, + int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *ctx, + const char *propq) { - PKCS12_SAFEBAG *bag; - const EVP_CIPHER *pbe_ciph; + PKCS12_SAFEBAG *bag = NULL; + const EVP_CIPHER *pbe_ciph = NULL; + EVP_CIPHER *pbe_ciph_fetch = NULL; X509_SIG *p8; - pbe_ciph = EVP_get_cipherbynid(pbe_nid); - if (pbe_ciph) + ERR_set_mark(); + pbe_ciph = pbe_ciph_fetch = EVP_CIPHER_fetch(ctx, OBJ_nid2sn(pbe_nid), propq); + if (pbe_ciph == NULL) + pbe_ciph = EVP_get_cipherbynid(pbe_nid); + ERR_pop_to_mark(); + + if (pbe_ciph != NULL) pbe_nid = -1; - p8 = PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter, - p8inf); + p8 = PKCS8_encrypt_ex(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter, + p8inf, ctx, propq); if (p8 == NULL) - return NULL; + goto err; bag = PKCS12_SAFEBAG_create0_pkcs8(p8); if (bag == NULL) X509_SIG_free(p8); +err: + EVP_CIPHER_free(pbe_ciph_fetch); return bag; } + +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid, + const char *pass, + int passlen, + unsigned char *salt, + int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8inf) +{ + return PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(pbe_nid, pass, passlen, + salt, saltlen, iter, p8inf, + NULL, NULL); +} diff --git a/crypto/openssl/crypto/pkcs12/p12_utl.c b/crypto/openssl/crypto/pkcs12/p12_utl.c index 43b9e3a5941a..3afc8b2f13c9 100644 --- a/crypto/openssl/crypto/pkcs12/p12_utl.c +++ b/crypto/openssl/crypto/pkcs12/p12_utl.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -21,9 +21,11 @@ unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, if (asclen == -1) asclen = strlen(asc); + if (asclen < 0) + return NULL; ulen = asclen * 2 + 2; if ((unitmp = OPENSSL_malloc(ulen)) == NULL) { - PKCS12err(PKCS12_F_OPENSSL_ASC2UNI, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return NULL; } for (i = 0; i < ulen - 2; i += 2) { @@ -44,16 +46,19 @@ char *OPENSSL_uni2asc(const unsigned char *uni, int unilen) { int asclen, i; char *asctmp; + /* string must contain an even number of bytes */ if (unilen & 1) return NULL; + if (unilen < 0) + return NULL; asclen = unilen / 2; /* If no terminating zero allow for one */ if (!unilen || uni[unilen - 1]) asclen++; uni++; if ((asctmp = OPENSSL_malloc(asclen)) == NULL) { - PKCS12err(PKCS12_F_OPENSSL_UNI2ASC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return NULL; } for (i = 0; i < unilen; i += 2) @@ -115,7 +120,7 @@ unsigned char *OPENSSL_utf82uni(const char *asc, int asclen, ulen += 2; /* for trailing UTF16 zero */ if ((ret = OPENSSL_malloc(ulen)) == NULL) { - PKCS12err(PKCS12_F_OPENSSL_UTF82UNI, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return NULL; } /* re-run the loop writing down UTF-16 characters in big-endian order */ @@ -200,7 +205,7 @@ char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen) asclen++; if ((asctmp = OPENSSL_malloc(asclen)) == NULL) { - PKCS12err(PKCS12_F_OPENSSL_UNI2UTF8, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); return NULL; } @@ -219,13 +224,13 @@ char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen) return asctmp; } -int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12) +int i2d_PKCS12_bio(BIO *bp, const PKCS12 *p12) { return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12); } #ifndef OPENSSL_NO_STDIO -int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12) +int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12) { return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12); } diff --git a/crypto/openssl/crypto/pkcs12/pk12err.c b/crypto/openssl/crypto/pkcs12/pk12err.c index 38ce5197eeee..6e3ec78cd6ea 100644 --- a/crypto/openssl/crypto/pkcs12/pk12err.c +++ b/crypto/openssl/crypto/pkcs12/pk12err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,61 +10,10 @@ #include #include +#include "crypto/pkcs12err.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA PKCS12_str_functs[] = { - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_OPENSSL_ASC2UNI, 0), "OPENSSL_asc2uni"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_OPENSSL_UNI2ASC, 0), "OPENSSL_uni2asc"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_OPENSSL_UNI2UTF8, 0), - "OPENSSL_uni2utf8"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_OPENSSL_UTF82UNI, 0), - "OPENSSL_utf82uni"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_CREATE, 0), "PKCS12_create"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_GEN_MAC, 0), "PKCS12_gen_mac"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_INIT, 0), "PKCS12_init"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, 0), - "PKCS12_item_decrypt_d2i"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, 0), - "PKCS12_item_i2d_encrypt"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, 0), - "PKCS12_item_pack_safebag"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_KEY_GEN_ASC, 0), - "PKCS12_key_gen_asc"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_KEY_GEN_UNI, 0), - "PKCS12_key_gen_uni"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_KEY_GEN_UTF8, 0), - "PKCS12_key_gen_utf8"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_NEWPASS, 0), "PKCS12_newpass"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_PACK_P7DATA, 0), - "PKCS12_pack_p7data"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_PACK_P7ENCDATA, 0), - "PKCS12_pack_p7encdata"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_PARSE, 0), "PKCS12_parse"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_PBE_CRYPT, 0), - "PKCS12_pbe_crypt"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_PBE_KEYIVGEN, 0), - "PKCS12_PBE_keyivgen"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF, 0), - "PKCS12_SAFEBAG_create0_p8inf"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8, 0), - "PKCS12_SAFEBAG_create0_pkcs8"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT, 0), - "PKCS12_SAFEBAG_create_pkcs8_encrypt"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_SETUP_MAC, 0), - "PKCS12_setup_mac"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_SET_MAC, 0), "PKCS12_set_mac"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_UNPACK_AUTHSAFES, 0), - "PKCS12_unpack_authsafes"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_UNPACK_P7DATA, 0), - "PKCS12_unpack_p7data"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS12_VERIFY_MAC, 0), - "PKCS12_verify_mac"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS8_ENCRYPT, 0), "PKCS8_encrypt"}, - {ERR_PACK(ERR_LIB_PKCS12, PKCS12_F_PKCS8_SET0_PBE, 0), "PKCS8_set0_pbe"}, - {0, NULL} -}; - static const ERR_STRING_DATA PKCS12_str_reasons[] = { {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_CANT_PACK_STRUCTURE), "cant pack structure"}, @@ -79,6 +28,7 @@ static const ERR_STRING_DATA PKCS12_str_reasons[] = { "invalid null argument"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_INVALID_NULL_PKCS12_POINTER), "invalid null pkcs12 pointer"}, + {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_INVALID_TYPE), "invalid type"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_IV_GEN_ERROR), "iv gen error"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_KEY_GEN_ERROR), "key gen error"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_MAC_ABSENT), "mac absent"}, @@ -90,12 +40,8 @@ static const ERR_STRING_DATA PKCS12_str_reasons[] = { {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_MAC_VERIFY_FAILURE), "mac verify failure"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_PARSE_ERROR), "parse error"}, - {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR), - "pkcs12 algor cipherinit error"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_PKCS12_CIPHERFINAL_ERROR), "pkcs12 cipherfinal error"}, - {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_PKCS12_PBE_CRYPT_ERROR), - "pkcs12 pbe crypt error"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM), "unknown digest algorithm"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_UNSUPPORTED_PKCS12_MODE), @@ -105,13 +51,11 @@ static const ERR_STRING_DATA PKCS12_str_reasons[] = { #endif -int ERR_load_PKCS12_strings(void) +int ossl_err_load_PKCS12_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL) { - ERR_load_strings_const(PKCS12_str_functs); + if (ERR_reason_error_string(PKCS12_str_reasons[0].error) == NULL) ERR_load_strings_const(PKCS12_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/pkcs7/bio_pk7.c b/crypto/openssl/crypto/pkcs7/bio_pk7.c index 29feaa3544e3..414f0da1c615 100644 --- a/crypto/openssl/crypto/pkcs7/bio_pk7.c +++ b/crypto/openssl/crypto/pkcs7/bio_pk7.c @@ -1,7 +1,7 @@ /* * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/pkcs7/pk7_asn1.c b/crypto/openssl/crypto/pkcs7/pk7_asn1.c index cd9fb4f509f1..1cd867721ee1 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_asn1.c +++ b/crypto/openssl/crypto/pkcs7/pk7_asn1.c @@ -1,7 +1,7 @@ /* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,6 +12,7 @@ #include #include #include +#include "pk7_local.h" /* PKCS#7 ASN1 module */ @@ -62,7 +63,61 @@ ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = { ASN1_ADB_OBJECT(PKCS7) }ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7) -IMPLEMENT_ASN1_FUNCTIONS(PKCS7) +PKCS7 *d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len) +{ + PKCS7 *ret; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + + if (a != NULL && *a != NULL) { + libctx = (*a)->ctx.libctx; + propq = (*a)->ctx.propq; + } + + ret = (PKCS7 *)ASN1_item_d2i_ex((ASN1_VALUE **)a, in, len, (PKCS7_it()), + libctx, propq); + if (ret != NULL) + ossl_pkcs7_resolve_libctx(ret); + return ret; +} + +int i2d_PKCS7(const PKCS7 *a, unsigned char **out) +{ + return ASN1_item_i2d((const ASN1_VALUE *)a, out, (PKCS7_it()));\ +} + +PKCS7 *PKCS7_new(void) +{ + return (PKCS7 *)ASN1_item_new(ASN1_ITEM_rptr(PKCS7)); +} + +PKCS7 *PKCS7_new_ex(OSSL_LIB_CTX *libctx, const char *propq) +{ + PKCS7 *pkcs7 = (PKCS7 *)ASN1_item_new_ex(ASN1_ITEM_rptr(PKCS7), libctx, + propq); + + if (pkcs7 != NULL) { + pkcs7->ctx.libctx = libctx; + pkcs7->ctx.propq = NULL; + if (propq != NULL) { + pkcs7->ctx.propq = OPENSSL_strdup(propq); + if (pkcs7->ctx.propq == NULL) { + PKCS7_free(pkcs7); + pkcs7 = NULL; + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + } + } + } + return pkcs7; +} + +void PKCS7_free(PKCS7 *p7) +{ + if (p7 != NULL) { + OPENSSL_free(p7->ctx.propq); + ASN1_item_free((ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7)); + } +} IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7) diff --git a/crypto/openssl/crypto/pkcs7/pk7_attr.c b/crypto/openssl/crypto/pkcs7/pk7_attr.c index e90bf03c5247..e9904c5950c6 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_attr.c +++ b/crypto/openssl/crypto/pkcs7/pk7_attr.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -23,7 +23,7 @@ int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, ASN1_STRING *seq; if ((seq = ASN1_STRING_new()) == NULL) { - PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return 0; } seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data, @@ -53,7 +53,7 @@ int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) X509_ALGOR *alg; if ((alg = X509_ALGOR_new()) == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return 0; } ASN1_OBJECT_free(alg->algorithm); @@ -77,7 +77,7 @@ int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) } return 1; err: - PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); ASN1_INTEGER_free(nbit); X509_ALGOR_free(alg); return 0; @@ -96,8 +96,7 @@ int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid) int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t) { if (t == NULL && (t = X509_gmtime_adj(NULL, 0)) == NULL) { - PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return 0; } return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, diff --git a/crypto/openssl/crypto/pkcs7/pk7_doit.c b/crypto/openssl/crypto/pkcs7/pk7_doit.c index f63fbc50ea60..1cef67b211af 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_doit.c +++ b/crypto/openssl/crypto/pkcs7/pk7_doit.c @@ -1,25 +1,27 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include -#include "internal/cryptlib.h" #include #include #include #include #include +#include "internal/cryptlib.h" +#include "internal/sizes.h" +#include "pk7_local.h" static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, void *value); -static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid); +static ASN1_TYPE *get_attribute(const STACK_OF(X509_ATTRIBUTE) *sk, int nid); -static int PKCS7_type_is_other(PKCS7 *p7) +int PKCS7_type_is_other(PKCS7 *p7) { int isOther = 1; @@ -42,7 +44,7 @@ static int PKCS7_type_is_other(PKCS7 *p7) } -static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) +ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) { if (PKCS7_type_is_data(p7)) return p7->d.data; @@ -52,26 +54,46 @@ static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) return NULL; } -static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) +static int pkcs7_bio_add_digest(BIO **pbio, X509_ALGOR *alg, + const PKCS7_CTX *ctx) { BIO *btmp; + char name[OSSL_MAX_NAME_SIZE]; + EVP_MD *fetched = NULL; const EVP_MD *md; + if ((btmp = BIO_new(BIO_f_md())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); goto err; } - md = EVP_get_digestbyobj(alg->algorithm); + OBJ_obj2txt(name, sizeof(name), alg->algorithm, 0); + + (void)ERR_set_mark(); + fetched = EVP_MD_fetch(ossl_pkcs7_ctx_get0_libctx(ctx), name, + ossl_pkcs7_ctx_get0_propq(ctx)); + if (fetched != NULL) + md = fetched; + else + md = EVP_get_digestbyname(name); + if (md == NULL) { - PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE); + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } + (void)ERR_pop_to_mark(); - BIO_set_md(btmp, md); + if (BIO_set_md(btmp, md) <= 0) { + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); + EVP_MD_free(fetched); + goto err; + } + EVP_MD_free(fetched); if (*pbio == NULL) *pbio = btmp; else if (!BIO_push(*pbio, btmp)) { - PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); goto err; } btmp = NULL; @@ -81,7 +103,6 @@ static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) err: BIO_free(btmp); return 0; - } static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, @@ -92,32 +113,27 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, unsigned char *ek = NULL; int ret = 0; size_t eklen; + const PKCS7_CTX *ctx = ri->ctx; pkey = X509_get0_pubkey(ri->cert); - - if (!pkey) + if (pkey == NULL) return 0; - pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pctx) + pctx = EVP_PKEY_CTX_new_from_pkey(ossl_pkcs7_ctx_get0_libctx(ctx), pkey, + ossl_pkcs7_ctx_get0_propq(ctx)); + if (pctx == NULL) return 0; if (EVP_PKEY_encrypt_init(pctx) <= 0) goto err; - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, - EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) { - PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR); - goto err; - } - if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0) goto err; ek = OPENSSL_malloc(eklen); if (ek == NULL) { - PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); goto err; } @@ -143,22 +159,17 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, EVP_PKEY_CTX *pctx = NULL; unsigned char *ek = NULL; size_t eklen; - int ret = -1; + const PKCS7_CTX *ctx = ri->ctx; - pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pctx) + pctx = EVP_PKEY_CTX_new_from_pkey(ossl_pkcs7_ctx_get0_libctx(ctx), pkey, + ossl_pkcs7_ctx_get0_propq(ctx)); + if (pctx == NULL) return -1; if (EVP_PKEY_decrypt_init(pctx) <= 0) goto err; - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, - EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR); - goto err; - } - if (EVP_PKEY_decrypt(pctx, NULL, &eklen, ri->enc_key->data, ri->enc_key->length) <= 0) goto err; @@ -166,7 +177,7 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, ek = OPENSSL_malloc(eklen); if (ek == NULL) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); goto err; } @@ -175,7 +186,7 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, || eklen == 0 || (fixlen != 0 && eklen != fixlen)) { ret = 0; - PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); goto err; } @@ -198,17 +209,26 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) int i; BIO *out = NULL, *btmp = NULL; X509_ALGOR *xa = NULL; + EVP_CIPHER *fetched_cipher = NULL; + const EVP_CIPHER *cipher; const EVP_CIPHER *evp_cipher = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; X509_ALGOR *xalg = NULL; PKCS7_RECIP_INFO *ri = NULL; ASN1_OCTET_STRING *os = NULL; + const PKCS7_CTX *p7_ctx; + OSSL_LIB_CTX *libctx; + const char *propq; if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); return NULL; } + p7_ctx = ossl_pkcs7_get0_ctx(p7); + libctx = ossl_pkcs7_ctx_get0_libctx(p7_ctx); + propq = ossl_pkcs7_ctx_get0_propq(p7_ctx); + /* * The content field in the PKCS7 ContentInfo is optional, but that really * only applies to inner content (precisely, detached signatures). @@ -220,7 +240,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) * calling this method, so a NULL p7->d is always an error. */ if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); return NULL; } @@ -238,7 +258,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) xalg = p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; @@ -247,7 +267,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) xalg = p7->d.enveloped->enc_data->algorithm; evp_cipher = p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; @@ -258,15 +278,15 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) case NID_pkcs7_data: break; default: - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) - if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) + if (!pkcs7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i), p7_ctx)) goto err; - if (xa && !PKCS7_bio_add_digest(&out, xa)) + if (xa && !pkcs7_bio_add_digest(&out, xa, p7_ctx)) goto err; if (evp_cipher != NULL) { @@ -276,18 +296,33 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) EVP_CIPHER_CTX *ctx; if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); goto err; } BIO_get_cipher_ctx(btmp, &ctx); - keylen = EVP_CIPHER_key_length(evp_cipher); - ivlen = EVP_CIPHER_iv_length(evp_cipher); - xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); + keylen = EVP_CIPHER_get_key_length(evp_cipher); + ivlen = EVP_CIPHER_get_iv_length(evp_cipher); + xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_get_type(evp_cipher)); if (ivlen > 0) - if (RAND_bytes(iv, ivlen) <= 0) + if (RAND_bytes_ex(libctx, iv, ivlen, 0) <= 0) goto err; - if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) + + (void)ERR_set_mark(); + fetched_cipher = EVP_CIPHER_fetch(libctx, + EVP_CIPHER_get0_name(evp_cipher), + propq); + (void)ERR_pop_to_mark(); + if (fetched_cipher != NULL) + cipher = fetched_cipher; + else + cipher = evp_cipher; + + if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) <= 0) goto err; + + EVP_CIPHER_free(fetched_cipher); + fetched_cipher = NULL; + if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) goto err; if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) @@ -299,7 +334,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) if (xalg->parameter == NULL) goto err; } - if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) + if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) <= 0) goto err; } @@ -339,6 +374,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) return out; err: + EVP_CIPHER_free(fetched_cipher); BIO_free_all(out); BIO_free_all(btmp); return NULL; @@ -351,19 +387,21 @@ static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) X509_get_issuer_name(pcert)); if (ret) return ret; - return ASN1_INTEGER_cmp(X509_get_serialNumber(pcert), + return ASN1_INTEGER_cmp(X509_get0_serialNumber(pcert), ri->issuer_and_serial->serial); } /* int */ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { - int i, j; + int i, len; BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body = NULL; - const EVP_MD *evp_md; - const EVP_CIPHER *evp_cipher = NULL; + EVP_MD *evp_md = NULL; + const EVP_MD *md; + EVP_CIPHER *evp_cipher = NULL; + const EVP_CIPHER *cipher = NULL; EVP_CIPHER_CTX *evp_ctx = NULL; X509_ALGOR *enc_alg = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; @@ -371,14 +409,22 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) PKCS7_RECIP_INFO *ri = NULL; unsigned char *ek = NULL, *tkey = NULL; int eklen = 0, tkeylen = 0; + char name[OSSL_MAX_NAME_SIZE]; + const PKCS7_CTX *p7_ctx; + OSSL_LIB_CTX *libctx; + const char *propq; if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); return NULL; } + p7_ctx = ossl_pkcs7_get0_ctx(p7); + libctx = ossl_pkcs7_ctx_get0_libctx(p7_ctx); + propq = ossl_pkcs7_ctx_get0_propq(p7_ctx); + if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); return NULL; } @@ -395,8 +441,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) */ data_body = PKCS7_get_octet_string(p7->d.sign->contents); if (!PKCS7_is_detached(p7) && data_body == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_INVALID_SIGNED_DATA_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_SIGNED_DATA_TYPE); goto err; } md_sk = p7->d.sign->md_algs; @@ -407,33 +452,52 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) /* data_body is NULL if the optional EncryptedContent is missing. */ data_body = p7->d.signed_and_enveloped->enc_data->enc_data; enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; - evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); - if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + + OBJ_obj2txt(name, sizeof(name), enc_alg->algorithm, 0); + + (void)ERR_set_mark(); + evp_cipher = EVP_CIPHER_fetch(libctx, name, propq); + if (evp_cipher != NULL) + cipher = evp_cipher; + else + cipher = EVP_get_cipherbyname(name); + + if (cipher == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } + (void)ERR_pop_to_mark(); break; case NID_pkcs7_enveloped: rsk = p7->d.enveloped->recipientinfo; enc_alg = p7->d.enveloped->enc_data->algorithm; /* data_body is NULL if the optional EncryptedContent is missing. */ data_body = p7->d.enveloped->enc_data->enc_data; - evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); - if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + OBJ_obj2txt(name, sizeof(name), enc_alg->algorithm, 0); + + (void)ERR_set_mark(); + evp_cipher = EVP_CIPHER_fetch(libctx, name, propq); + if (evp_cipher != NULL) + cipher = evp_cipher; + else + cipher = EVP_get_cipherbyname(name); + + if (cipher == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } + (void)ERR_pop_to_mark(); break; default: - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } /* Detached content must be supplied via in_bio instead. */ if (data_body == NULL && in_bio == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); goto err; } @@ -442,19 +506,32 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { xa = sk_X509_ALGOR_value(md_sk, i); if ((btmp = BIO_new(BIO_f_md())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); goto err; } - j = OBJ_obj2nid(xa->algorithm); - evp_md = EVP_get_digestbynid(j); - if (evp_md == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_UNKNOWN_DIGEST_TYPE); + OBJ_obj2txt(name, sizeof(name), xa->algorithm, 0); + + (void)ERR_set_mark(); + evp_md = EVP_MD_fetch(libctx, name, propq); + if (evp_md != NULL) + md = evp_md; + else + md = EVP_get_digestbyname(name); + + if (md == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } + (void)ERR_pop_to_mark(); - BIO_set_md(btmp, evp_md); + if (BIO_set_md(btmp, md) <= 0) { + EVP_MD_free(evp_md); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); + goto err; + } + EVP_MD_free(evp_md); if (out == NULL) out = btmp; else @@ -463,9 +540,9 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } } - if (evp_cipher != NULL) { + if (cipher != NULL) { if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); goto err; } @@ -487,8 +564,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) ri = NULL; } if (ri == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); + ERR_raise(ERR_LIB_PKCS7, + PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto err; } } @@ -501,13 +578,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); - + ri->ctx = p7_ctx; if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, - EVP_CIPHER_key_length(evp_cipher)) < 0) + EVP_CIPHER_get_key_length(cipher)) < 0) goto err; ERR_clear_error(); } } else { + ri->ctx = p7_ctx; /* Only exit on fatal errors, not decrypt failure */ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0) goto err; @@ -516,12 +594,15 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) evp_ctx = NULL; BIO_get_cipher_ctx(etmp, &evp_ctx); - if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0) + if (EVP_CipherInit_ex(evp_ctx, cipher, NULL, NULL, NULL, 0) <= 0) goto err; - if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) + if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) <= 0) goto err; /* Generate random key as MMA defence */ - tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); + len = EVP_CIPHER_CTX_get_key_length(evp_ctx); + if (len <= 0) + goto err; + tkeylen = (size_t)len; tkey = OPENSSL_malloc(tkeylen); if (tkey == NULL) goto err; @@ -533,13 +614,13 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) tkey = NULL; } - if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { + if (eklen != EVP_CIPHER_CTX_get_key_length(evp_ctx)) { /* * Some S/MIME clients don't use the same key and effective key * length. The key length is determined by the size of the * decrypted RSA key. */ - if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { + if (EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen) <= 0) { /* Use random key as MMA defence */ OPENSSL_clear_free(ek, eklen); ek = tkey; @@ -579,9 +660,11 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } BIO_push(out, bio); bio = NULL; + EVP_CIPHER_free(evp_cipher); return out; err: + EVP_CIPHER_free(evp_cipher); OPENSSL_clear_free(ek, eklen); OPENSSL_clear_free(tkey, tkeylen); BIO_free_all(out); @@ -596,16 +679,15 @@ static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) for (;;) { bio = BIO_find_type(bio, BIO_TYPE_MD); if (bio == NULL) { - PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, - PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); return NULL; } BIO_get_md_ctx(bio, pmd); if (*pmd == NULL) { - PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_PKCS7, ERR_R_INTERNAL_ERROR); return NULL; } - if (EVP_MD_CTX_type(*pmd) == nid) + if (EVP_MD_CTX_get_type(*pmd) == nid) return bio; bio = BIO_next(bio); } @@ -620,18 +702,18 @@ static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) /* Add signing time if not already present */ if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { if (!PKCS7_add0_attrib_signing_time(si, NULL)) { - PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return 0; } } /* Add digest */ if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) { - PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); return 0; } if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) { - PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return 0; } @@ -652,20 +734,23 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; ASN1_OCTET_STRING *os = NULL; + const PKCS7_CTX *p7_ctx; if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); return 0; } + p7_ctx = ossl_pkcs7_get0_ctx(p7); + if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); return 0; } ctx_tmp = EVP_MD_CTX_new(); if (ctx_tmp == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return 0; } @@ -683,7 +768,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) if (os == NULL) { os = ASN1_OCTET_STRING_new(); if (os == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); goto err; } p7->d.signed_and_enveloped->enc_data->enc_data = os; @@ -695,7 +780,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) if (os == NULL) { os = ASN1_OCTET_STRING_new(); if (os == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); goto err; } p7->d.enveloped->enc_data->enc_data = os; @@ -723,7 +808,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) break; default: - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } @@ -760,14 +845,16 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) } else { unsigned char *abuf = NULL; unsigned int abuflen; - abuflen = EVP_PKEY_size(si->pkey); + abuflen = EVP_PKEY_get_size(si->pkey); abuf = OPENSSL_malloc(abuflen); if (abuf == NULL) goto err; - if (!EVP_SignFinal(ctx_tmp, abuf, &abuflen, si->pkey)) { + if (!EVP_SignFinal_ex(ctx_tmp, abuf, &abuflen, si->pkey, + ossl_pkcs7_ctx_get0_libctx(p7_ctx), + ossl_pkcs7_ctx_get0_propq(p7_ctx))) { OPENSSL_free(abuf); - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); goto err; } ASN1_STRING_set0(si->enc_digest, abuf, abuflen); @@ -797,7 +884,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) long contlen; btmp = BIO_find_type(bio, BIO_TYPE_MEM); if (btmp == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); goto err; } contlen = BIO_get_mem_data(btmp, &cont); @@ -824,6 +911,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) int alen; size_t siglen; const EVP_MD *md = NULL; + const PKCS7_CTX *ctx = si->ctx; md = EVP_get_digestbyobj(si->digest_alg->algorithm); if (md == NULL) @@ -831,19 +919,16 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) mctx = EVP_MD_CTX_new(); if (mctx == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); goto err; } - if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0) + if (EVP_DigestSignInit_ex(mctx, &pctx, EVP_MD_get0_name(md), + ossl_pkcs7_ctx_get0_libctx(ctx), + ossl_pkcs7_ctx_get0_propq(ctx), si->pkey, + NULL) <= 0) goto err; - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, - EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); - goto err; - } - alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); if (!abuf) @@ -860,12 +945,6 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0) goto err; - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, - EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); - goto err; - } - EVP_MD_CTX_free(mctx); ASN1_STRING_set0(si->enc_digest, abuf, siglen); @@ -876,7 +955,6 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) OPENSSL_free(abuf); EVP_MD_CTX_free(mctx); return 0; - } int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, @@ -888,12 +966,12 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, X509 *x509; if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); return 0; } if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); return 0; } @@ -902,7 +980,7 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, } else if (PKCS7_type_is_signedAndEnveloped(p7)) { cert = p7->d.signed_and_enveloped->cert; } else { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_PKCS7_TYPE); goto err; } /* XXXXXXXXXXXXXXXXXXXXXXX */ @@ -912,24 +990,21 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, /* were we able to find the cert in passed to us */ if (x509 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, - PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); goto err; } /* Lets verify */ if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_X509_LIB); goto err; } X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); i = X509_verify_cert(ctx); if (i <= 0) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); - X509_STORE_CTX_cleanup(ctx); + ERR_raise(ERR_LIB_PKCS7, ERR_R_X509_LIB); goto err; } - X509_STORE_CTX_cleanup(ctx); return PKCS7_signatureVerify(bio, p7, si, x509); err: @@ -941,20 +1016,25 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, { ASN1_OCTET_STRING *os; EVP_MD_CTX *mdc_tmp, *mdc; + const EVP_MD *md; + EVP_MD *fetched_md = NULL; int ret = 0, i; int md_type; STACK_OF(X509_ATTRIBUTE) *sk; BIO *btmp; EVP_PKEY *pkey; + const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7); + OSSL_LIB_CTX *libctx = ossl_pkcs7_ctx_get0_libctx(ctx); + const char *propq = ossl_pkcs7_ctx_get0_propq(ctx); mdc_tmp = EVP_MD_CTX_new(); if (mdc_tmp == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); goto err; } if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_PKCS7_TYPE); goto err; } @@ -964,22 +1044,21 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, for (;;) { if ((btmp == NULL) || ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, - PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } BIO_get_md_ctx(btmp, &mdc); if (mdc == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_PKCS7, ERR_R_INTERNAL_ERROR); goto err; } - if (EVP_MD_CTX_type(mdc) == md_type) + if (EVP_MD_CTX_get_type(mdc) == md_type) break; /* * Workaround for some broken clients that put the signature OID * instead of the digest OID in digest_alg->algorithm */ - if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) + if (EVP_MD_get_pkey_type(EVP_MD_CTX_get0_md(mdc)) == md_type) break; btmp = BIO_next(btmp); } @@ -1002,24 +1081,34 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, goto err; message_digest = PKCS7_digest_from_attributes(sk); if (!message_digest) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, - PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } if ((message_digest->length != (int)md_len) || (memcmp(message_digest->data, md_dat, md_len))) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_DIGEST_FAILURE); ret = -1; goto err; } - if (!EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL)) + (void)ERR_set_mark(); + fetched_md = EVP_MD_fetch(libctx, OBJ_nid2sn(md_type), propq); + + if (fetched_md != NULL) + md = fetched_md; + else + md = EVP_get_digestbynid(md_type); + + if (md == NULL || !EVP_VerifyInit_ex(mdc_tmp, md, NULL)) { + (void)ERR_clear_last_mark(); goto err; + } + (void)ERR_pop_to_mark(); alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); if (alen <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); ret = -1; goto err; } @@ -1031,20 +1120,21 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, os = si->enc_digest; pkey = X509_get0_pubkey(x509); - if (!pkey) { + if (pkey == NULL) { ret = -1; goto err; } - i = EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey); + i = EVP_VerifyFinal_ex(mdc_tmp, os->data, os->length, pkey, libctx, propq); if (i <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNATURE_FAILURE); ret = -1; goto err; } ret = 1; err: EVP_MD_CTX_free(mdc_tmp); + EVP_MD_free(fetched_md); return ret; } @@ -1068,17 +1158,17 @@ PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) return ri->issuer_and_serial; } -ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) +ASN1_TYPE *PKCS7_get_signed_attribute(const PKCS7_SIGNER_INFO *si, int nid) { return get_attribute(si->auth_attr, nid); } -ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) +ASN1_TYPE *PKCS7_get_attribute(const PKCS7_SIGNER_INFO *si, int nid) { return get_attribute(si->unauth_attr, nid); } -static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) +static ASN1_TYPE *get_attribute(const STACK_OF(X509_ATTRIBUTE) *sk, int nid) { int idx; X509_ATTRIBUTE *xa; diff --git a/crypto/openssl/crypto/pkcs7/pk7_lib.c b/crypto/openssl/crypto/pkcs7/pk7_lib.c index ec4d9abd587f..5ce591f758f7 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_lib.c +++ b/crypto/openssl/crypto/pkcs7/pk7_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,8 +11,11 @@ #include "internal/cryptlib.h" #include #include +#include #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/x509.h" /* for sk_X509_add1_cert() */ +#include "pk7_local.h" long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) { @@ -33,28 +36,28 @@ long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) p7->d.sign->contents->d.data = NULL; } } else { - PKCS7err(PKCS7_F_PKCS7_CTRL, - PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); + ERR_raise(ERR_LIB_PKCS7, + PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); ret = 0; } break; case PKCS7_OP_GET_DETACHED_SIGNATURE: if (nid == NID_pkcs7_signed) { - if (!p7->d.sign || !p7->d.sign->contents->d.ptr) + if (p7->d.sign == NULL || p7->d.sign->contents->d.ptr == NULL) ret = 1; else ret = 0; p7->detached = ret; } else { - PKCS7err(PKCS7_F_PKCS7_CTRL, - PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); + ERR_raise(ERR_LIB_PKCS7, + PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); ret = 0; } break; default: - PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_OPERATION); ret = 0; } return ret; @@ -96,7 +99,7 @@ int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) case NID_pkcs7_signedAndEnveloped: case NID_pkcs7_encrypted: default: - PKCS7err(PKCS7_F_PKCS7_SET_CONTENT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } return 1; @@ -167,7 +170,7 @@ int PKCS7_set_type(PKCS7 *p7, int type) goto err; break; default: - PKCS7err(PKCS7_F_PKCS7_SET_TYPE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } return 1; @@ -184,7 +187,8 @@ int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other) int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) { - int i, j, nid; + int i, j; + ASN1_OBJECT *obj; X509_ALGOR *alg; STACK_OF(PKCS7_SIGNER_INFO) *signer_sk; STACK_OF(X509_ALGOR) *md_sk; @@ -200,36 +204,45 @@ int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) md_sk = p7->d.signed_and_enveloped->md_algs; break; default: - PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); return 0; } - nid = OBJ_obj2nid(psi->digest_alg->algorithm); - + obj = psi->digest_alg->algorithm; /* If the digest is not currently listed, add it */ j = 0; for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { alg = sk_X509_ALGOR_value(md_sk, i); - if (OBJ_obj2nid(alg->algorithm) == nid) { + if (OBJ_cmp(obj, alg->algorithm) == 0) { j = 1; break; } } if (!j) { /* we need to add another algorithm */ + int nid; + if ((alg = X509_ALGOR_new()) == NULL || (alg->parameter = ASN1_TYPE_new()) == NULL) { X509_ALGOR_free(alg); - PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return 0; } - alg->algorithm = OBJ_nid2obj(nid); + /* + * If there is a constant copy of the ASN1 OBJECT in libcrypto, then + * use that. Otherwise, use a dynamically duplicated copy + */ + if ((nid = OBJ_obj2nid(obj)) != NID_undef) + alg->algorithm = OBJ_nid2obj(nid); + else + alg->algorithm = OBJ_dup(obj); alg->parameter->type = V_ASN1_NULL; - if (!sk_X509_ALGOR_push(md_sk, alg)) { + if (alg->algorithm == NULL || !sk_X509_ALGOR_push(md_sk, alg)) { X509_ALGOR_free(alg); return 0; } } + psi->ctx = ossl_pkcs7_get0_ctx(p7); if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi)) return 0; return 1; @@ -249,22 +262,11 @@ int PKCS7_add_certificate(PKCS7 *p7, X509 *x509) sk = &(p7->d.signed_and_enveloped->cert); break; default: - PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, PKCS7_R_WRONG_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); return 0; } - if (*sk == NULL) - *sk = sk_X509_new_null(); - if (*sk == NULL) { - PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE); - return 0; - } - X509_up_ref(x509); - if (!sk_X509_push(*sk, x509)) { - X509_free(x509); - return 0; - } - return 1; + return ossl_x509_add_cert_new(sk, x509, X509_ADD_FLAG_UP_REF); } int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) @@ -281,14 +283,14 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) sk = &(p7->d.signed_and_enveloped->crl); break; default: - PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); return 0; } if (*sk == NULL) *sk = sk_X509_CRL_new_null(); if (*sk == NULL) { - PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return 0; } @@ -300,6 +302,39 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) return 1; } +static int pkcs7_ecdsa_or_dsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, + int verify) +{ + if (verify == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + EVP_PKEY *pkey = si->pkey; + + PKCS7_SIGNER_INFO_get0_algs(si, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_get_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +} + +static int pkcs7_rsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, int verify) +{ + if (verify == 0) { + X509_ALGOR *alg = NULL; + + PKCS7_SIGNER_INFO_get0_algs(si, NULL, NULL, &alg); + if (alg != NULL) + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + } + return 1; +} + int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst) { @@ -318,7 +353,7 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, */ ASN1_INTEGER_free(p7i->issuer_and_serial->serial); if (!(p7i->issuer_and_serial->serial = - ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) + ASN1_INTEGER_dup(X509_get0_serialNumber(x509)))) goto err; /* lets keep the pkey around for a while */ @@ -327,21 +362,24 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, /* Set the algorithms */ - X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)), + X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_get_type(dgst)), V_ASN1_NULL, NULL); - if (pkey->ameth && pkey->ameth->pkey_ctrl) { + if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "DSA")) + return pkcs7_ecdsa_or_dsa_sign_verify_setup(p7i, 0); + if (EVP_PKEY_is_a(pkey, "RSA")) + return pkcs7_rsa_sign_verify_setup(p7i, 0); + + if (pkey->ameth != NULL && pkey->ameth->pkey_ctrl != NULL) { ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i); if (ret > 0) return 1; if (ret != -2) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, - PKCS7_R_SIGNING_CTRL_FAILURE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNING_CTRL_FAILURE); return 0; } } - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, - PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); err: return 0; } @@ -357,14 +395,14 @@ PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, goto err; dgst = EVP_get_digestbynid(def_nid); if (dgst == NULL) { - PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, PKCS7_R_NO_DEFAULT_DIGEST); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_DEFAULT_DIGEST); goto err; } } if ((si = PKCS7_SIGNER_INFO_new()) == NULL) goto err; - if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst)) + if (PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst) <= 0) goto err; if (!PKCS7_add_signer(p7, si)) goto err; @@ -374,11 +412,116 @@ PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, return NULL; } +static STACK_OF(X509) *pkcs7_get_signer_certs(const PKCS7 *p7) +{ + if (p7->d.ptr == NULL) + return NULL; + if (PKCS7_type_is_signed(p7)) + return p7->d.sign->cert; + if (PKCS7_type_is_signedAndEnveloped(p7)) + return p7->d.signed_and_enveloped->cert; + return NULL; +} + +static STACK_OF(PKCS7_RECIP_INFO) *pkcs7_get_recipient_info(const PKCS7 *p7) +{ + if (p7->d.ptr == NULL) + return NULL; + if (PKCS7_type_is_signedAndEnveloped(p7)) + return p7->d.signed_and_enveloped->recipientinfo; + if (PKCS7_type_is_enveloped(p7)) + return p7->d.enveloped->recipientinfo; + return NULL; +} + +/* + * Set up the library context into any loaded structure that needs it. + * i.e loaded X509 objects. + */ +void ossl_pkcs7_resolve_libctx(PKCS7 *p7) +{ + int i; + const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7); + OSSL_LIB_CTX *libctx = ossl_pkcs7_ctx_get0_libctx(ctx); + const char *propq = ossl_pkcs7_ctx_get0_propq(ctx); + STACK_OF(PKCS7_RECIP_INFO) *rinfos; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + STACK_OF(X509) *certs; + + if (ctx == NULL || p7->d.ptr == NULL) + return; + + rinfos = pkcs7_get_recipient_info(p7); + sinfos = PKCS7_get_signer_info(p7); + certs = pkcs7_get_signer_certs(p7); + + for (i = 0; i < sk_X509_num(certs); i++) + ossl_x509_set0_libctx(sk_X509_value(certs, i), libctx, propq); + + for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rinfos); i++) { + PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(rinfos, i); + + ossl_x509_set0_libctx(ri->cert, libctx, propq); + } + + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { + PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + + if (si != NULL) + si->ctx = ctx; + } +} + +const PKCS7_CTX *ossl_pkcs7_get0_ctx(const PKCS7 *p7) +{ + return p7 != NULL ? &p7->ctx : NULL; +} + +void ossl_pkcs7_set0_libctx(PKCS7 *p7, OSSL_LIB_CTX *ctx) +{ + p7->ctx.libctx = ctx; +} + +int ossl_pkcs7_set1_propq(PKCS7 *p7, const char *propq) +{ + if (p7->ctx.propq != NULL) { + OPENSSL_free(p7->ctx.propq); + p7->ctx.propq = NULL; + } + if (propq != NULL) { + p7->ctx.propq = OPENSSL_strdup(propq); + if (p7->ctx.propq == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + } + return 1; +} + +int ossl_pkcs7_ctx_propagate(const PKCS7 *from, PKCS7 *to) +{ + ossl_pkcs7_set0_libctx(to, from->ctx.libctx); + if (!ossl_pkcs7_set1_propq(to, from->ctx.propq)) + return 0; + + ossl_pkcs7_resolve_libctx(to); + return 1; +} + +OSSL_LIB_CTX *ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx) +{ + return ctx != NULL ? ctx->libctx : NULL; +} +const char *ossl_pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx) +{ + return ctx != NULL ? ctx->propq : NULL; +} + int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) { if (PKCS7_type_is_digest(p7)) { if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) { - PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return 0; } p7->d.digest->md->parameter->type = V_ASN1_NULL; @@ -386,7 +529,7 @@ int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) return 1; } - PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); return 1; } @@ -425,10 +568,11 @@ PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) if ((ri = PKCS7_RECIP_INFO_new()) == NULL) goto err; - if (!PKCS7_RECIP_INFO_set(ri, x509)) + if (PKCS7_RECIP_INFO_set(ri, x509) <= 0) goto err; if (!PKCS7_add_recipient_info(p7, ri)) goto err; + ri->ctx = ossl_pkcs7_get0_ctx(p7); return ri; err: PKCS7_RECIP_INFO_free(ri); @@ -449,8 +593,7 @@ int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) sk = p7->d.enveloped->recipientinfo; break; default: - PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO, - PKCS7_R_WRONG_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); return 0; } @@ -459,6 +602,18 @@ int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) return 1; } +static int pkcs7_rsa_encrypt_decrypt_setup(PKCS7_RECIP_INFO *ri, int decrypt) +{ + X509_ALGOR *alg = NULL; + + if (decrypt == 0) { + PKCS7_RECIP_INFO_get0_alg(ri, &alg); + if (alg != NULL) + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + } + return 1; +} + int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) { int ret; @@ -471,29 +626,38 @@ int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) ASN1_INTEGER_free(p7i->issuer_and_serial->serial); if (!(p7i->issuer_and_serial->serial = - ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) + ASN1_INTEGER_dup(X509_get0_serialNumber(x509)))) return 0; pkey = X509_get0_pubkey(x509); + if (pkey == NULL) + return 0; - if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) { - PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, - PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + if (EVP_PKEY_is_a(pkey, "RSA-PSS")) + return -2; + if (EVP_PKEY_is_a(pkey, "RSA")) { + if (pkcs7_rsa_encrypt_decrypt_setup(p7i, 0) <= 0) + goto err; + goto finished; + } + + if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) { + ERR_raise(ERR_LIB_PKCS7, + PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); goto err; } ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i); if (ret == -2) { - PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, - PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + ERR_raise(ERR_LIB_PKCS7, + PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); goto err; } if (ret <= 0) { - PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, - PKCS7_R_ENCRYPTION_CTRL_FAILURE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE); goto err; } - +finished: X509_up_ref(x509); p7i->cert = x509; @@ -528,22 +692,23 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) ec = p7->d.enveloped->enc_data; break; default: - PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); return 0; } /* Check cipher OID exists and has data in it */ - i = EVP_CIPHER_type(cipher); + i = EVP_CIPHER_get_type(cipher); if (i == NID_undef) { - PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, - PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); return 0; } ec->cipher = cipher; + ec->ctx = ossl_pkcs7_get0_ctx(p7); return 1; } +/* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */ int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) { ASN1_OCTET_STRING *os = NULL; diff --git a/crypto/openssl/crypto/pkcs7/pk7_local.h b/crypto/openssl/crypto/pkcs7/pk7_local.h new file mode 100644 index 000000000000..8deb342b7913 --- /dev/null +++ b/crypto/openssl/crypto/pkcs7/pk7_local.h @@ -0,0 +1,16 @@ +/* + * Copyright 2020-2021 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 "crypto/pkcs7.h" + +const PKCS7_CTX *ossl_pkcs7_get0_ctx(const PKCS7 *p7); +OSSL_LIB_CTX *ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx); +const char *ossl_pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx); + +int ossl_pkcs7_ctx_propagate(const PKCS7 *from, PKCS7 *to); diff --git a/crypto/openssl/crypto/pkcs7/pk7_mime.c b/crypto/openssl/crypto/pkcs7/pk7_mime.c index 19e6868148b8..49a0da5f819c 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_mime.c +++ b/crypto/openssl/crypto/pkcs7/pk7_mime.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,6 +11,7 @@ #include "internal/cryptlib.h" #include #include +#include "pk7_local.h" /* PKCS#7 wrappers round generalised stream and MIME routines */ @@ -30,6 +31,8 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) { STACK_OF(X509_ALGOR) *mdalgs; int ctype_nid = OBJ_obj2nid(p7->type); + const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7); + if (ctype_nid == NID_pkcs7_signed) mdalgs = p7->d.sign->md_algs; else @@ -37,12 +40,31 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) flags ^= SMIME_OLDMIME; - return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags, - ctype_nid, NID_undef, mdalgs, - ASN1_ITEM_rptr(PKCS7)); + return SMIME_write_ASN1_ex(bio, (ASN1_VALUE *)p7, data, flags, ctype_nid, + NID_undef, mdalgs, ASN1_ITEM_rptr(PKCS7), + ossl_pkcs7_ctx_get0_libctx(ctx), + ossl_pkcs7_ctx_get0_propq(ctx)); +} + +PKCS7 *SMIME_read_PKCS7_ex(BIO *bio, BIO **bcont, PKCS7 **p7) +{ + PKCS7 *ret; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + + if (p7 != NULL && *p7 != NULL) { + libctx = (*p7)->ctx.libctx; + propq = (*p7)->ctx.propq; + } + + ret = (PKCS7 *)SMIME_read_ASN1_ex(bio, 0, bcont, ASN1_ITEM_rptr(PKCS7), + (ASN1_VALUE **)p7, libctx, propq); + if (ret != NULL) + ossl_pkcs7_resolve_libctx(ret); + return ret; } PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont) { - return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7)); + return SMIME_read_PKCS7_ex(bio, bcont, NULL); } diff --git a/crypto/openssl/crypto/pkcs7/pk7_smime.c b/crypto/openssl/crypto/pkcs7/pk7_smime.c index a95db62178ed..4593da8f5b41 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_smime.c +++ b/crypto/openssl/crypto/pkcs7/pk7_smime.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,20 +13,22 @@ #include "internal/cryptlib.h" #include #include - +#include "pk7_local.h" #define BUFFERSIZE 4096 + static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); -PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, - BIO *data, int flags) +PKCS7 *PKCS7_sign_ex(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags, OSSL_LIB_CTX *libctx, + const char *propq) { PKCS7 *p7; int i; - if ((p7 = PKCS7_new()) == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE); + if ((p7 = PKCS7_new_ex(libctx, propq)) == NULL) { + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return NULL; } @@ -37,7 +39,7 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, goto err; if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) { - PKCS7err(PKCS7_F_PKCS7_SIGN, PKCS7_R_PKCS7_ADD_SIGNER_ERROR); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNER_ERROR); goto err; } @@ -62,28 +64,34 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, return NULL; } +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags) +{ + return PKCS7_sign_ex(signcert, pkey, certs, data, flags, NULL, NULL); +} + + int PKCS7_final(PKCS7 *p7, BIO *data, int flags) { BIO *p7bio; int ret = 0; if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) { - PKCS7err(PKCS7_F_PKCS7_FINAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return 0; } - SMIME_crlf_copy(data, p7bio, flags); + if (!SMIME_crlf_copy(data, p7bio, flags)) + goto err; (void)BIO_flush(p7bio); if (!PKCS7_dataFinal(p7, p7bio)) { - PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_PKCS7_DATASIGN); goto err; } - ret = 1; - - err: +err: BIO_free_all(p7bio); return ret; @@ -112,18 +120,19 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, { PKCS7_SIGNER_INFO *si = NULL; STACK_OF(X509_ALGOR) *smcap = NULL; + if (!X509_check_private_key(signcert, pkey)) { - PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, - PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + ERR_raise(ERR_LIB_PKCS7, + PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); return NULL; } if ((si = PKCS7_add_signature(p7, signcert, pkey, md)) == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, - PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); return NULL; } + si->ctx = ossl_pkcs7_get0_ctx(p7); if (!(flags & PKCS7_NOCERTS)) { if (!PKCS7_add_certificate(p7, signcert)) goto err; @@ -135,7 +144,7 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, /* Add SMIMECapabilities */ if (!(flags & PKCS7_NOSMIMECAP)) { if ((smcap = sk_X509_ALGOR_new_null()) == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); goto err; } if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) @@ -158,7 +167,8 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, if (flags & PKCS7_REUSE_DIGEST) { if (!pkcs7_copy_existing_digest(p7, si)) goto err; - if (!(flags & PKCS7_PARTIAL) && !PKCS7_SIGNER_INFO_sign(si)) + if (!(flags & PKCS7_PARTIAL) + && !PKCS7_SIGNER_INFO_sign(si)) goto err; } } @@ -193,11 +203,10 @@ static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) } - if (osdig) + if (osdig != NULL) return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); - PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, - PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); return 0; } @@ -213,20 +222,21 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, int i, j = 0, k, ret = 0; BIO *p7bio = NULL; BIO *tmpin = NULL, *tmpout = NULL; + const PKCS7_CTX *p7_ctx; - if (!p7) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER); + if (p7 == NULL) { + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); return 0; } if (!PKCS7_type_is_signed(p7)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); return 0; } /* Check for no data and no content: no data to verify signature */ if (PKCS7_get_detached(p7) && !indata) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); return 0; } @@ -239,7 +249,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, * process is different, but the existing PKCs7 verification works. */ if (!PKCS7_get_detached(p7) && indata) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CONTENT_AND_DATA_PRESENT); return 0; } } @@ -247,17 +257,18 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, sinfos = PKCS7_get_signer_info(p7); if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_SIGNATURES_ON_DATA); return 0; } signers = PKCS7_get0_signers(p7, certs, flags); - if (!signers) + if (signers == NULL) return 0; /* Now verify the certificates */ - - cert_ctx = X509_STORE_CTX_new(); + p7_ctx = ossl_pkcs7_get0_ctx(p7); + cert_ctx = X509_STORE_CTX_new_ex(ossl_pkcs7_ctx_get0_libctx(p7_ctx), + ossl_pkcs7_ctx_get0_propq(p7_ctx)); if (cert_ctx == NULL) goto err; if (!(flags & PKCS7_NOVERIFY)) @@ -266,12 +277,13 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, if (!(flags & PKCS7_NOCHAIN)) { if (!X509_STORE_CTX_init(cert_ctx, store, signer, p7->d.sign->cert)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_X509_LIB); goto err; } - X509_STORE_CTX_set_default(cert_ctx, "smime_sign"); + if (!X509_STORE_CTX_set_default(cert_ctx, "smime_sign")) + goto err; } else if (!X509_STORE_CTX_init(cert_ctx, store, signer, NULL)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); + ERR_raise(ERR_LIB_PKCS7, ERR_R_X509_LIB); goto err; } if (!(flags & PKCS7_NOCRL)) @@ -279,12 +291,10 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, i = X509_verify_cert(cert_ctx); if (i <= 0) j = X509_STORE_CTX_get_error(cert_ctx); - X509_STORE_CTX_cleanup(cert_ctx); if (i <= 0) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, - PKCS7_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(j)); + ERR_raise_data(ERR_LIB_PKCS7, PKCS7_R_CERTIFICATE_VERIFY_ERROR, + "Verify error: %s", + X509_verify_cert_error_string(j)); goto err; } /* Check for revocation status here */ @@ -303,7 +313,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, len = BIO_get_mem_data(indata, &ptr); tmpin = (len == 0) ? indata : BIO_new_mem_buf(ptr, len); if (tmpin == NULL) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); goto err; } } else @@ -314,7 +324,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, if (flags & PKCS7_TEXT) { if ((tmpout = BIO_new(BIO_s_mem())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); goto err; } BIO_set_mem_eof_return(tmpout, 0); @@ -323,7 +333,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, /* We now have to 'read' from p7bio to calculate digests etc. */ if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); goto err; } for (;;) { @@ -336,7 +346,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, if (flags & PKCS7_TEXT) { if (!SMIME_text(tmpout, out)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SMIME_TEXT_ERROR); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SMIME_TEXT_ERROR); BIO_free(tmpout); goto err; } @@ -350,7 +360,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, signer = sk_X509_value(signers, i); j = PKCS7_signatureVerify(p7bio, p7, si, signer); if (j <= 0) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNATURE_FAILURE); goto err; } } @@ -379,13 +389,13 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, X509 *signer; int i; - if (!p7) { - PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_INVALID_NULL_POINTER); + if (p7 == NULL) { + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); return NULL; } if (!PKCS7_type_is_signed(p7)) { - PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_WRONG_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); return NULL; } @@ -394,12 +404,12 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, sinfos = PKCS7_get_signer_info(p7); if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { - PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_NO_SIGNERS); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_SIGNERS); return 0; } if ((signers = sk_X509_new_null()) == NULL) { - PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return NULL; } @@ -417,8 +427,7 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, X509_find_by_issuer_and_serial(p7->d.sign->cert, ias->issuer, ias->serial); if (!signer) { - PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, - PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); sk_X509_free(signers); return 0; } @@ -433,29 +442,31 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, /* Build a complete PKCS#7 enveloped data */ -PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, - int flags) +PKCS7 *PKCS7_encrypt_ex(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, int flags, + OSSL_LIB_CTX *libctx, const char *propq) { PKCS7 *p7; BIO *p7bio = NULL; int i; X509 *x509; - if ((p7 = PKCS7_new()) == NULL) { - PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE); + + if ((p7 = PKCS7_new_ex(libctx, propq)) == NULL) { + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); return NULL; } if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) goto err; if (!PKCS7_set_cipher(p7, cipher)) { - PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_ERROR_SETTING_CIPHER); goto err; } for (i = 0; i < sk_X509_num(certs); i++) { x509 = sk_X509_value(certs, i); if (!PKCS7_add_recipient(p7, x509)) { - PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_ADDING_RECIPIENT); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_ERROR_ADDING_RECIPIENT); goto err; } } @@ -474,30 +485,37 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, } +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags) +{ + return PKCS7_encrypt_ex(certs, in, cipher, flags, NULL, NULL); +} + + int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) { BIO *tmpmem; int ret = 0, i; char *buf = NULL; - if (!p7) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER); + if (p7 == NULL) { + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); return 0; } if (!PKCS7_type_is_enveloped(p7)) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_WRONG_CONTENT_TYPE); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); return 0; } if (cert && !X509_check_private_key(cert, pkey)) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, - PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + ERR_raise(ERR_LIB_PKCS7, + PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); return 0; } if ((tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert)) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR); + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_DECRYPT_ERROR); return 0; } @@ -505,26 +523,26 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) BIO *tmpbuf, *bread; /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ if ((tmpbuf = BIO_new(BIO_f_buffer())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); BIO_free_all(tmpmem); return 0; } if ((bread = BIO_push(tmpbuf, tmpmem)) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); BIO_free_all(tmpbuf); BIO_free_all(tmpmem); return 0; } ret = SMIME_text(bread, data); if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { - if (!BIO_get_cipher_status(tmpmem)) + if (BIO_get_cipher_status(tmpmem) <= 0) ret = 0; } BIO_free_all(bread); return ret; } if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); goto err; } for (;;) { @@ -532,7 +550,7 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) if (i <= 0) { ret = 1; if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { - if (!BIO_get_cipher_status(tmpmem)) + if (BIO_get_cipher_status(tmpmem) <= 0) ret = 0; } diff --git a/crypto/openssl/crypto/pkcs7/pkcs7err.c b/crypto/openssl/crypto/pkcs7/pkcs7err.c index 07490c1a5878..cd839511e31c 100644 --- a/crypto/openssl/crypto/pkcs7/pkcs7err.c +++ b/crypto/openssl/crypto/pkcs7/pkcs7err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,66 +10,10 @@ #include #include +#include "crypto/pkcs7err.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA PKCS7_str_functs[] = { - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, 0), - "do_pkcs7_signed_attrib"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME, 0), - "PKCS7_add0_attrib_signing_time"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP, 0), - "PKCS7_add_attrib_smimecap"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_CERTIFICATE, 0), - "PKCS7_add_certificate"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_CRL, 0), "PKCS7_add_crl"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_RECIPIENT_INFO, 0), - "PKCS7_add_recipient_info"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_SIGNATURE, 0), - "PKCS7_add_signature"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ADD_SIGNER, 0), "PKCS7_add_signer"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_BIO_ADD_DIGEST, 0), - "PKCS7_bio_add_digest"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, 0), - "pkcs7_copy_existing_digest"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_CTRL, 0), "PKCS7_ctrl"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DATADECODE, 0), "PKCS7_dataDecode"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DATAFINAL, 0), "PKCS7_dataFinal"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DATAINIT, 0), "PKCS7_dataInit"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DATAVERIFY, 0), "PKCS7_dataVerify"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DECRYPT, 0), "PKCS7_decrypt"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_DECRYPT_RINFO, 0), - "pkcs7_decrypt_rinfo"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ENCODE_RINFO, 0), - "pkcs7_encode_rinfo"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_ENCRYPT, 0), "PKCS7_encrypt"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_FINAL, 0), "PKCS7_final"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_FIND_DIGEST, 0), - "PKCS7_find_digest"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_GET0_SIGNERS, 0), - "PKCS7_get0_signers"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_RECIP_INFO_SET, 0), - "PKCS7_RECIP_INFO_set"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SET_CIPHER, 0), "PKCS7_set_cipher"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SET_CONTENT, 0), - "PKCS7_set_content"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SET_DIGEST, 0), "PKCS7_set_digest"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SET_TYPE, 0), "PKCS7_set_type"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIGN, 0), "PKCS7_sign"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIGNATUREVERIFY, 0), - "PKCS7_signatureVerify"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIGNER_INFO_SET, 0), - "PKCS7_SIGNER_INFO_set"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIGNER_INFO_SIGN, 0), - "PKCS7_SIGNER_INFO_sign"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIGN_ADD_SIGNER, 0), - "PKCS7_sign_add_signer"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_SIMPLE_SMIMECAP, 0), - "PKCS7_simple_smimecap"}, - {ERR_PACK(ERR_LIB_PKCS7, PKCS7_F_PKCS7_VERIFY, 0), "PKCS7_verify"}, - {0, NULL} -}; - static const ERR_STRING_DATA PKCS7_str_reasons[] = { {ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, @@ -144,13 +88,11 @@ static const ERR_STRING_DATA PKCS7_str_reasons[] = { #endif -int ERR_load_PKCS7_strings(void) +int ossl_err_load_PKCS7_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL) { - ERR_load_strings_const(PKCS7_str_functs); + if (ERR_reason_error_string(PKCS7_str_reasons[0].error) == NULL) ERR_load_strings_const(PKCS7_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/poly1305/asm/poly1305-armv4.pl b/crypto/openssl/crypto/poly1305/asm/poly1305-armv4.pl index 70f46cd140aa..041bfd46e699 100755 --- a/crypto/openssl/crypto/poly1305/asm/poly1305-armv4.pl +++ b/crypto/openssl/crypto/poly1305/asm/poly1305-armv4.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -28,9 +28,10 @@ # the cost of 15/12% regression on Cortex-A5/A7, it's even possible # to improve Cortex-A9 result, but then A5/A7 loose more than 20%; -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -38,9 +39,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } ($ctx,$inp,$len,$padbit)=map("r$_",(0..3)); @@ -48,7 +50,6 @@ if ($flavour && $flavour ne "void") { $code.=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) .syntax unified .thumb @@ -56,6 +57,8 @@ $code.=<<___; .code 32 #endif +.text + .globl poly1305_emit .globl poly1305_blocks .globl poly1305_init @@ -100,8 +103,10 @@ poly1305_init: and r4,r4,r10 #if __ARM_MAX_ARCH__>=7 +# if !defined(_WIN32) ldr r12,[r11,r12] @ OPENSSL_armcap_P -# ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r12,[r12] # endif #endif @@ -116,32 +121,22 @@ poly1305_init: #if __ARM_MAX_ARCH__>=7 tst r12,#ARMV7_NEON @ check for NEON -# ifdef __APPLE__ - adr r9,poly1305_blocks_neon - adr r11,poly1305_blocks -# ifdef __thumb2__ - it ne -# endif +# ifdef __thumb2__ + adr r9,.Lpoly1305_blocks_neon + adr r11,.Lpoly1305_blocks + adr r12,.Lpoly1305_emit + adr r10,.Lpoly1305_emit_neon + itt ne movne r11,r9 - adr r12,poly1305_emit - adr r10,poly1305_emit_neon -# ifdef __thumb2__ - it ne -# endif movne r12,r10 + orr r11,r11,#1 @ thumb-ify address + orr r12,r12,#1 # else -# ifdef __thumb2__ - itete eq -# endif addeq r12,r11,#(.Lpoly1305_emit-.Lpoly1305_init) addne r12,r11,#(.Lpoly1305_emit_neon-.Lpoly1305_init) addeq r11,r11,#(.Lpoly1305_blocks-.Lpoly1305_init) addne r11,r11,#(.Lpoly1305_blocks_neon-.Lpoly1305_init) # endif -# ifdef __thumb2__ - orr r12,r12,#1 @ thumb-ify address - orr r11,r11,#1 -# endif #endif ldrb r9,[$inp,#11] orr r6,r6,r7,lsl#8 @@ -1232,7 +1227,11 @@ poly1305_emit_neon: .Lzeros: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.Lpoly1305_init +# endif #endif ___ } } diff --git a/crypto/openssl/crypto/poly1305/asm/poly1305-armv8.pl b/crypto/openssl/crypto/poly1305/asm/poly1305-armv8.pl index 2a42b64a929c..113a2151b6fa 100755 --- a/crypto/openssl/crypto/poly1305/asm/poly1305-armv8.pl +++ b/crypto/openssl/crypto/poly1305/asm/poly1305-armv8.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -29,20 +29,24 @@ # X-Gene 2.13/+68% 2.27 # Mongoose 1.77/+75% 1.12 # Kryo 2.70/+55% 1.13 +# ThunderX2 1.17/+95% 1.36 # # (*) estimate based on resources availability is less than 1.0, # i.e. measured result is worse than expected, presumably binary # translator is not almighty; -$flavour=shift; -$output=shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my ($ctx,$inp,$len,$padbit) = map("x$_",(0..3)); @@ -75,17 +79,12 @@ poly1305_init: csel x0,xzr,x0,eq b.eq .Lno_key -#ifdef __ILP32__ - ldrsw $t1,.LOPENSSL_armcap_P -#else - ldr $t1,.LOPENSSL_armcap_P -#endif - adr $t0,.LOPENSSL_armcap_P + adrp x17,OPENSSL_armcap_P + ldr w17,[x17,#:lo12:OPENSSL_armcap_P] ldp $r0,$r1,[$inp] // load key mov $s1,#0xfffffffc0fffffff movk $s1,#0x0fff,lsl#48 - ldr w17,[$t0,$t1] #ifdef __ARMEB__ rev $r0,$r0 // flip bytes rev $r1,$r1 @@ -97,10 +96,10 @@ poly1305_init: tst w17,#ARMV7_NEON - adr $d0,poly1305_blocks - adr $r0,poly1305_blocks_neon - adr $d1,poly1305_emit - adr $r1,poly1305_emit_neon + adr $d0,.Lpoly1305_blocks + adr $r0,.Lpoly1305_blocks_neon + adr $d1,.Lpoly1305_emit + adr $r1,.Lpoly1305_emit_neon csel $d0,$d0,$r0,eq csel $d1,$d1,$r1,eq @@ -119,6 +118,7 @@ poly1305_init: .type poly1305_blocks,%function .align 5 poly1305_blocks: +.Lpoly1305_blocks: ands $len,$len,#-16 b.eq .Lno_data @@ -183,6 +183,7 @@ poly1305_blocks: .type poly1305_emit,%function .align 5 poly1305_emit: +.Lpoly1305_emit: ldp $h0,$h1,[$ctx] // load hash base 2^64 ldr $h2,[$ctx,#16] ldp $t0,$t1,[$nonce] // load nonce @@ -289,10 +290,11 @@ poly1305_splat: .type poly1305_blocks_neon,%function .align 5 poly1305_blocks_neon: +.Lpoly1305_blocks_neon: ldr $is_base2_26,[$ctx,#24] cmp $len,#128 b.hs .Lblocks_neon - cbz $is_base2_26,poly1305_blocks + cbz $is_base2_26,.Lpoly1305_blocks .Lblocks_neon: .inst 0xd503233f // paciasp @@ -435,7 +437,7 @@ poly1305_blocks_neon: csel $in2,$zeros,$in2,lo mov x4,#1 - str x4,[$ctx,#-24] // set is_base2_26 + stur x4,[$ctx,#-24] // set is_base2_26 sub $ctx,$ctx,#48 // restore original $ctx b .Ldo_neon @@ -872,6 +874,7 @@ poly1305_blocks_neon: .type poly1305_emit_neon,%function .align 5 poly1305_emit_neon: +.Lpoly1305_emit_neon: ldr $is_base2_26,[$ctx,#24] cbz $is_base2_26,poly1305_emit @@ -924,12 +927,6 @@ poly1305_emit_neon: .align 5 .Lzeros: .long 0,0,0,0,0,0,0,0 -.LOPENSSL_armcap_P: -#ifdef __ILP32__ -.long OPENSSL_armcap_P-. -#else -.quad OPENSSL_armcap_P-. -#endif .asciz "Poly1305 for ARMv8, CRYPTOGAMS by " .align 2 ___ diff --git a/crypto/openssl/crypto/poly1305/asm/poly1305-c64xplus.pl b/crypto/openssl/crypto/poly1305/asm/poly1305-c64xplus.pl index 93fef37e605b..2bcdced7f45c 100755 --- a/crypto/openssl/crypto/poly1305/asm/poly1305-c64xplus.pl +++ b/crypto/openssl/crypto/poly1305/asm/poly1305-c64xplus.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -26,8 +26,7 @@ # time dependent on input length. This module on the other hand is free # from such limitation. -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; ($CTXA,$INPB,$LEN,$PADBIT)=("A4","B4","A6","B6"); ($H0,$H1,$H2,$H3,$H4,$H4a)=("A8","B8","A10","B10","B2",$LEN); diff --git a/crypto/openssl/crypto/poly1305/asm/poly1305-ia64.S b/crypto/openssl/crypto/poly1305/asm/poly1305-ia64.S new file mode 100644 index 000000000000..54d6454f0322 --- /dev/null +++ b/crypto/openssl/crypto/poly1305/asm/poly1305-ia64.S @@ -0,0 +1,365 @@ +// ==================================================================== +// Written by Andy Polyakov, @dot-asm, initially for use in the OpenSSL +// project. +// ==================================================================== +// +// Poly1305 for Itanium. +// +// January 2019 +// +// Performance was reported to be ~2.1 cycles per byte on Itanium 2. +// With exception for processors in 95xx family, which have higher +// floating-point instructions' latencies and deliver ~2.6 cpb. +// Comparison to compiler-generated code is not exactly fair, because +// of different radixes. But just for reference, it was observed to be +// >3x faster. Originally it was argued that floating-point base 2^32 +// implementation would be optimal. Upon closer look estimate for below +// integer base 2^64 implementation turned to be approximately same on +// Itanium 2. But floating-point code would be larger, and have higher +// overhead, which would negatively affect small-block performance... + +#if defined(_HPUX_SOURCE) +# if !defined(_LP64) +# define ADDP addp4 +# else +# define ADDP add +# endif +# define RUM rum +# define SUM sum +#else +# define ADDP add +# define RUM nop +# define SUM nop +#endif + +.text +.explicit + +.global poly1305_init# +.proc poly1305_init# +.align 64 +poly1305_init: + .prologue + .save ar.pfs,r2 +{ .mmi; alloc r2=ar.pfs,2,0,0,0 + cmp.eq p6,p7=0,r33 } // key == NULL? +{ .mmi; ADDP r9=8,r32 + ADDP r10=16,r32 + ADDP r32=0,r32 };; + .body +{ .mmi; st8 [r32]=r0,24 // ctx->h0 = 0 + st8 [r9]=r0 // ctx->h1 = 0 +(p7) ADDP r8=0,r33 } +{ .mib; st8 [r10]=r0 // ctx->h2 = 0 +(p6) mov r8=0 +(p6) br.ret.spnt b0 };; + +{ .mmi; ADDP r9=1,r33 + ADDP r10=2,r33 + ADDP r11=3,r33 };; +{ .mmi; ld1 r16=[r8],4 // load key, little-endian + ld1 r17=[r9],4 } +{ .mmi; ld1 r18=[r10],4 + ld1 r19=[r11],4 };; +{ .mmi; ld1 r20=[r8],4 + ld1 r21=[r9],4 } +{ .mmi; ld1 r22=[r10],4 + ld1 r23=[r11],4 + and r19=15,r19 };; +{ .mmi; ld1 r24=[r8],4 + ld1 r25=[r9],4 + and r20=-4,r20 } +{ .mmi; ld1 r26=[r10],4 + ld1 r27=[r11],4 + and r23=15,r23 };; +{ .mmi; ld1 r28=[r8],4 + ld1 r29=[r9],4 + and r24=-4,r24 } +{ .mmi; ld1 r30=[r10],4 + ld1 r31=[r11],4 + and r27=15,r27 };; + +{ .mii; and r28=-4,r28 + dep r16=r17,r16,8,8 + dep r18=r19,r18,8,8 };; +{ .mii; and r31=15,r31 + dep r16=r18,r16,16,16 + dep r20=r21,r20,8,8 };; +{ .mii; dep r16=r20,r16,32,16 + dep r22=r23,r22,8,8 };; +{ .mii; dep r16=r22,r16,48,16 + dep r24=r25,r24,8,8 };; +{ .mii; dep r26=r27,r26,8,8 + dep r28=r29,r28,8,8 };; +{ .mii; dep r24=r26,r24,16,16 + dep r30=r31,r30,8,8 };; +{ .mii; st8 [r32]=r16,8 // ctx->r0 + dep r24=r28,r24,32,16;; + dep r24=r30,r24,48,16 };; +{ .mii; st8 [r32]=r24,8 // ctx->r1 + shr.u r25=r24,2;; + add r25=r25,r24 };; +{ .mib; st8 [r32]=r25 // ctx->s1 + mov r8=0 + br.ret.sptk b0 };; +.endp poly1305_init# + +h0=r17; h1=r18; h2=r19; +i0=r20; i1=r21; +HF0=f8; HF1=f9; HF2=f10; +RF0=f11; RF1=f12; SF1=f13; + +.global poly1305_blocks# +.proc poly1305_blocks# +.align 64 +poly1305_blocks: + .prologue + .save ar.pfs,r2 +{ .mii; alloc r2=ar.pfs,4,1,0,0 + .save ar.lc,r3 + mov r3=ar.lc + .save pr,r36 + mov r36=pr } + + .body +{ .mmi; ADDP r8=0,r32 + ADDP r9=8,r32 + and r29=7,r33 };; +{ .mmi; ld8 h0=[r8],16 + ld8 h1=[r9],16 + and r33=-8,r33 };; +{ .mmi; ld8 h2=[r8],16 + ldf8 RF0=[r9],16 + shr.u r34=r34,4 };; +{ .mmi; ldf8 RF1=[r8],-32 + ldf8 SF1=[r9],-32 + cmp.ltu p16,p17=1,r34 };; +{ .mmi; +(p16) add r34=-2,r34 +(p17) mov r34=0 + ADDP r10=0,r33 } +{ .mii; ADDP r11=8,r33 +(p16) mov ar.ec=2 +(p17) mov ar.ec=1 };; +{ .mib; RUM 1<<1 // go little-endian + mov ar.lc=r34 + brp.loop.imp .Loop,.Lcend-16 } + +{ .mmi; cmp.eq p8,p7=0,r29 + cmp.eq p9,p0=1,r29 + cmp.eq p10,p0=2,r29 } +{ .mmi; cmp.eq p11,p0=3,r29 + cmp.eq p12,p0=4,r29 + cmp.eq p13,p0=5,r29 } +{ .mmi; cmp.eq p14,p0=6,r29 + cmp.eq p15,p0=7,r29 + add r16=16,r10 };; + +{ .mmb; +(p8) ld8 i0=[r10],16 // aligned input +(p8) ld8 i1=[r11],16 +(p8) br.cond.sptk .Loop };; + + // align first block + .pred.rel "mutex",p8,p9,p10,p11,p12,p13,p14,p15 +{ .mmi; (p7) ld8 r14=[r10],24 + (p7) ld8 r15=[r11],24 } + +{ .mii; (p7) ld8 r16=[r16] + nop.i 0;; + (p15) shrp i0=r15,r14,56 } +{ .mii; (p15) shrp i1=r16,r15,56 + (p14) shrp i0=r15,r14,48 } +{ .mii; (p14) shrp i1=r16,r15,48 + (p13) shrp i0=r15,r14,40 } +{ .mii; (p13) shrp i1=r16,r15,40 + (p12) shrp i0=r15,r14,32 } +{ .mii; (p12) shrp i1=r16,r15,32 + (p11) shrp i0=r15,r14,24 } +{ .mii; (p11) shrp i1=r16,r15,24 + (p10) shrp i0=r15,r14,16 } +{ .mii; (p10) shrp i1=r16,r15,16 + (p9) shrp i0=r15,r14,8 } +{ .mii; (p9) shrp i1=r16,r15,8 + mov r14=r16 };; + +.Loop: + .pred.rel "mutex",p8,p9,p10,p11,p12,p13,p14,p15 +{ .mmi; add h0=h0,i0 + add h1=h1,i1 + add h2=h2,r35 };; +{ .mmi; setf.sig HF0=h0 + cmp.ltu p6,p0=h0,i0 + cmp.ltu p7,p0=h1,i1 };; +{ .mmi; (p6) add h1=1,h1;; + setf.sig HF1=h1 + (p6) cmp.eq.or p7,p0=0,h1 };; +{ .mmi; (p7) add h2=1,h2;; + setf.sig HF2=h2 };; + +{ .mfi; (p16) ld8 r15=[r10],16 + xmpy.lu f32=HF0,RF0 } +{ .mfi; (p16) ld8 r16=[r11],16 + xmpy.hu f33=HF0,RF0 } +{ .mfi; xmpy.lu f36=HF0,RF1 } +{ .mfi; xmpy.hu f37=HF0,RF1 };; +{ .mfi; xmpy.lu f34=HF1,SF1 + (p15) shrp i0=r15,r14,56 } +{ .mfi; xmpy.hu f35=HF1,SF1 } +{ .mfi; xmpy.lu f38=HF1,RF0 + (p15) shrp i1=r16,r15,56 } +{ .mfi; xmpy.hu f39=HF1,RF0 } +{ .mfi; xmpy.lu f40=HF2,SF1 + (p14) shrp i0=r15,r14,48 } +{ .mfi; xmpy.lu f41=HF2,RF0 };; + +{ .mmi; getf.sig r22=f32 + getf.sig r23=f33 + (p14) shrp i1=r16,r15,48 } +{ .mmi; getf.sig r24=f34 + getf.sig r25=f35 + (p13) shrp i0=r15,r14,40 } +{ .mmi; getf.sig r26=f36 + getf.sig r27=f37 + (p13) shrp i1=r16,r15,40 } +{ .mmi; getf.sig r28=f38 + getf.sig r29=f39 + (p12) shrp i0=r15,r14,32 } +{ .mmi; getf.sig r30=f40 + getf.sig r31=f41 };; + +{ .mmi; add h0=r22,r24 + add r23=r23,r25 + (p12) shrp i1=r16,r15,32 } +{ .mmi; add h1=r26,r28 + add r27=r27,r29 + (p11) shrp i0=r15,r14,24 };; +{ .mmi; cmp.ltu p6,p0=h0,r24 + cmp.ltu p7,p0=h1,r28 + add r23=r23,r30 };; +{ .mmi; (p6) add r23=1,r23 + (p7) add r27=1,r27 + (p11) shrp i1=r16,r15,24 };; +{ .mmi; add h1=h1,r23;; + cmp.ltu p6,p7=h1,r23 + (p10) shrp i0=r15,r14,16 };; +{ .mmi; (p6) add h2=r31,r27,1 + (p7) add h2=r31,r27 + (p10) shrp i1=r16,r15,16 };; + +{ .mmi; (p8) mov i0=r15 + and r22=-4,h2 + shr.u r23=h2,2 };; +{ .mmi; add r22=r22,r23 + and h2=3,h2 + (p9) shrp i0=r15,r14,8 };; + +{ .mmi; add h0=h0,r22;; + cmp.ltu p6,p0=h0,r22 + (p9) shrp i1=r16,r15,8 };; +{ .mmi; (p8) mov i1=r16 + (p6) cmp.eq.unc p7,p0=-1,h1 + (p6) add h1=1,h1 };; +{ .mmb; (p7) add h2=1,h2 + mov r14=r16 + br.ctop.sptk .Loop };; +.Lcend: + +{ .mii; SUM 1<<1 // back to big-endian + mov ar.lc=r3 };; + +{ .mmi; st8 [r8]=h0,16 + st8 [r9]=h1 + mov pr=r36,0x1ffff };; +{ .mmb; st8 [r8]=h2 + rum 1<<5 + br.ret.sptk b0 };; +.endp poly1305_blocks# + +.global poly1305_emit# +.proc poly1305_emit# +.align 64 +poly1305_emit: + .prologue + .save ar.pfs,r2 +{ .mmi; alloc r2=ar.pfs,3,0,0,0 + ADDP r8=0,r32 + ADDP r9=8,r32 };; + + .body +{ .mmi; ld8 r16=[r8],16 // load hash + ld8 r17=[r9] + ADDP r10=0,r34 };; +{ .mmi; ld8 r18=[r8] + ld4 r24=[r10],8 // load nonce + ADDP r11=4,r34 };; + +{ .mmi; ld4 r25=[r11],8 + ld4 r26=[r10] + add r20=5,r16 };; + +{ .mmi; ld4 r27=[r11] + cmp.ltu p6,p7=r20,r16 + shl r25=r25,32 };; +{ .mmi; +(p6) add r21=1,r17 +(p7) add r21=0,r17 +(p6) cmp.eq.or.andcm p6,p7=-1,r17 };; +{ .mmi; +(p6) add r22=1,r18 +(p7) add r22=0,r18 + shl r27=r27,32 };; +{ .mmi; or r24=r24,r25 + or r26=r26,r27 + cmp.leu p6,p7=4,r22 };; +{ .mmi; +(p6) add r16=r20,r24 +(p7) add r16=r16,r24 +(p6) add r17=r21,r26 };; +{ .mii; +(p7) add r17=r17,r26 + cmp.ltu p6,p7=r16,r24;; +(p6) add r17=1,r17 };; + +{ .mmi; ADDP r8=0,r33 + ADDP r9=4,r33 + shr.u r20=r16,32 } +{ .mmi; ADDP r10=8,r33 + ADDP r11=12,r33 + shr.u r21=r17,32 };; + +{ .mmi; st1 [r8]=r16,1 // write mac, little-endian + st1 [r9]=r20,1 + shr.u r16=r16,8 } +{ .mii; st1 [r10]=r17,1 + shr.u r20=r20,8 + shr.u r17=r17,8 } +{ .mmi; st1 [r11]=r21,1 + shr.u r21=r21,8 };; + +{ .mmi; st1 [r8]=r16,1 + st1 [r9]=r20,1 + shr.u r16=r16,8 } +{ .mii; st1 [r10]=r17,1 + shr.u r20=r20,8 + shr.u r17=r17,8 } +{ .mmi; st1 [r11]=r21,1 + shr.u r21=r21,8 };; + +{ .mmi; st1 [r8]=r16,1 + st1 [r9]=r20,1 + shr.u r16=r16,8 } +{ .mii; st1 [r10]=r17,1 + shr.u r20=r20,8 + shr.u r17=r17,8 } +{ .mmi; st1 [r11]=r21,1 + shr.u r21=r21,8 };; + +{ .mmi; st1 [r8]=r16 + st1 [r9]=r20 } +{ .mmb; st1 [r10]=r17 + st1 [r11]=r21 + br.ret.sptk b0 };; +.endp poly1305_emit# + +stringz "Poly1305 for IA64, CRYPTOGAMS by \@dot-asm" diff --git a/crypto/openssl/crypto/poly1305/asm/poly1305-mips.pl b/crypto/openssl/crypto/poly1305/asm/poly1305-mips.pl index 965825dc3eda..6c0b3292d07c 100755 --- a/crypto/openssl/crypto/poly1305/asm/poly1305-mips.pl +++ b/crypto/openssl/crypto/poly1305/asm/poly1305-mips.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -56,7 +56,11 @@ # ###################################################################### -$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +# supported flavours are o32,n32,64,nubi32,nubi64, default is o32 +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : "o32"; die "MIPS64 only" unless ($flavour =~ /64|n32/i); @@ -431,7 +435,7 @@ poly1305_emit: ___ } -$output=pop and open STDOUT,">$output"; +$output and open STDOUT,">$output"; print $code; close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/poly1305/asm/poly1305-ppc.pl b/crypto/openssl/crypto/poly1305/asm/poly1305-ppc.pl index e5d6933ac4d5..9f86134d923f 100755 --- a/crypto/openssl/crypto/poly1305/asm/poly1305-ppc.pl +++ b/crypto/openssl/crypto/poly1305/asm/poly1305-ppc.pl @@ -1,17 +1,17 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 # # ==================================================================== -# Written by Andy Polyakov 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/. +# Written by Andy Polyakov, @dot-asm, initially for use in the OpenSSL +# project. The module is dual licensed under OpenSSL and CRYPTOGAMS +# licenses depending on where you obtain it. For further details see +# https://github.com/dot-asm/cryptogams/. # ==================================================================== # # This module implements Poly1305 hash for PowerPC. @@ -44,8 +44,18 @@ # # On side note, Power ISA 2.07 enables vector base 2^26 implementation, # and POWER8 might have capacity to break 1.0 cycle per byte barrier... +# +# January 2019 +# +# ... Unfortunately not:-( Estimate was a projection of ARM result, +# but ARM has vector multiply-n-add instruction, while PowerISA does +# not, not one usable in the context. Improvement is ~40% over -m64 +# result above and is ~1.43 on little-endian systems. -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -72,7 +82,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=24*$SIZE_T; @@ -99,6 +110,7 @@ $code.=<<___; std r0,0($ctx) # zero hash value std r0,8($ctx) std r0,16($ctx) + stw r0,24($ctx) # clear is_base2_26 $UCMP $inp,r0 beq- Lno_key @@ -140,6 +152,7 @@ Lno_key: .globl .poly1305_blocks .align 4 .poly1305_blocks: +Lpoly1305_blocks: srdi. $len,$len,4 beq- Labort @@ -238,60 +251,120 @@ Labort: .long 0 .byte 0,12,4,1,0x80,5,4,0 .size .poly1305_blocks,.-.poly1305_blocks +___ +{ +my ($h0,$h1,$h2,$h3,$h4,$t0) = map("r$_",(7..12)); +$code.=<<___; .globl .poly1305_emit -.align 4 +.align 5 .poly1305_emit: - ld $h0,0($ctx) # load hash - ld $h1,8($ctx) - ld $h2,16($ctx) - ld $padbit,0($nonce) # load nonce - ld $nonce,8($nonce) - - addic $d0,$h0,5 # compare to modulus - addze $d1,$h1 - addze $d2,$h2 - - srdi $mask,$d2,2 # did it carry/borrow? - neg $mask,$mask + lwz $h0,0($ctx) # load hash value base 2^26 + lwz $h1,4($ctx) + lwz $h2,8($ctx) + lwz $h3,12($ctx) + lwz $h4,16($ctx) + lwz r0,24($ctx) # is_base2_26 + + sldi $h1,$h1,26 # base 2^26 -> base 2^64 + sldi $t0,$h2,52 + srdi $h2,$h2,12 + sldi $h3,$h3,14 + add $h0,$h0,$h1 + addc $h0,$h0,$t0 + sldi $t0,$h4,40 + srdi $h4,$h4,24 + adde $h1,$h2,$h3 + addc $h1,$h1,$t0 + addze $h2,$h4 + + ld $h3,0($ctx) # load hash value base 2^64 + ld $h4,8($ctx) + ld $t0,16($ctx) + + neg r0,r0 + xor $h0,$h0,$h3 # choose between radixes + xor $h1,$h1,$h4 + xor $h2,$h2,$t0 + and $h0,$h0,r0 + and $h1,$h1,r0 + and $h2,$h2,r0 + xor $h0,$h0,$h3 + xor $h1,$h1,$h4 + xor $h2,$h2,$t0 + + addic $h3,$h0,5 # compare to modulus + addze $h4,$h1 + addze $t0,$h2 + + srdi $t0,$t0,2 # see if it carried/borrowed + neg $t0,$t0 + + andc $h0,$h0,$t0 + and $h3,$h3,$t0 + andc $h1,$h1,$t0 + and $h4,$h4,$t0 + or $h0,$h0,$h3 + or $h1,$h1,$h4 + + lwz $t0,4($nonce) + lwz $h2,12($nonce) + lwz $h3,0($nonce) + lwz $h4,8($nonce) + + insrdi $h3,$t0,32,0 + insrdi $h4,$h2,32,0 + + addc $h0,$h0,$h3 # accumulate nonce + adde $h1,$h1,$h4 + + addi $ctx,$mac,-1 + addi $mac,$mac,7 + + stbu $h0,1($ctx) # write [little-endian] result + srdi $h0,$h0,8 + stbu $h1,1($mac) + srdi $h1,$h1,8 + + stbu $h0,1($ctx) + srdi $h0,$h0,8 + stbu $h1,1($mac) + srdi $h1,$h1,8 + + stbu $h0,1($ctx) + srdi $h0,$h0,8 + stbu $h1,1($mac) + srdi $h1,$h1,8 + + stbu $h0,1($ctx) + srdi $h0,$h0,8 + stbu $h1,1($mac) + srdi $h1,$h1,8 + + stbu $h0,1($ctx) + srdi $h0,$h0,8 + stbu $h1,1($mac) + srdi $h1,$h1,8 + + stbu $h0,1($ctx) + srdi $h0,$h0,8 + stbu $h1,1($mac) + srdi $h1,$h1,8 + + stbu $h0,1($ctx) + srdi $h0,$h0,8 + stbu $h1,1($mac) + srdi $h1,$h1,8 + + stbu $h0,1($ctx) + stbu $h1,1($mac) - andc $h0,$h0,$mask - and $d0,$d0,$mask - andc $h1,$h1,$mask - and $d1,$d1,$mask - or $h0,$h0,$d0 - or $h1,$h1,$d1 -___ -$code.=<<___ if (!$LITTLE_ENDIAN); - rotldi $padbit,$padbit,32 # flip nonce words - rotldi $nonce,$nonce,32 -___ -$code.=<<___; - addc $h0,$h0,$padbit # accumulate nonce - adde $h1,$h1,$nonce -___ -$code.=<<___ if ($LITTLE_ENDIAN); - std $h0,0($mac) # write result - std $h1,8($mac) -___ -$code.=<<___ if (!$LITTLE_ENDIAN); - extrdi r0,$h0,32,0 - li $d0,4 - stwbrx $h0,0,$mac # write result - extrdi $h0,$h1,32,0 - li $d1,8 - stwbrx r0,$d0,$mac - li $d2,12 - stwbrx $h1,$d1,$mac - stwbrx $h0,$d2,$mac -___ -$code.=<<___; blr .long 0 .byte 0,12,0x14,0,0,0,3,0 .size .poly1305_emit,.-.poly1305_emit ___ - } else { +} } else { ############################################################################### # base 2^32 implementation @@ -309,6 +382,7 @@ $code.=<<___; stw r0,8($ctx) stw r0,12($ctx) stw r0,16($ctx) + stw r0,24($ctx) # clear is_base2_26 $UCMP $inp,r0 beq- Lno_key @@ -353,6 +427,7 @@ Lno_key: .globl .poly1305_blocks .align 4 .poly1305_blocks: +Lpoly1305_blocks: srwi. $len,$len,4 beq- Labort @@ -560,17 +635,389 @@ Labort: .long 0 .byte 0,12,4,1,0x80,18,4,0 .size .poly1305_blocks,.-.poly1305_blocks +___ +{ +my ($h0,$h1,$h2,$h3,$h4,$t0,$t1) = map("r$_",(6..12)); +$code.=<<___; .globl .poly1305_emit -.align 4 +.align 5 .poly1305_emit: - $STU $sp,-$FRAME($sp) + lwz r0,24($ctx) # is_base2_26 + lwz $h0,0($ctx) # load hash value + lwz $h1,4($ctx) + lwz $h2,8($ctx) + lwz $h3,12($ctx) + lwz $h4,16($ctx) + cmplwi r0,0 + beq Lemit_base2_32 + + slwi $t0,$h1,26 # base 2^26 -> base 2^32 + srwi $h1,$h1,6 + slwi $t1,$h2,20 + srwi $h2,$h2,12 + addc $h0,$h0,$t0 + slwi $t0,$h3,14 + srwi $h3,$h3,18 + adde $h1,$h1,$t1 + slwi $t1,$h4,8 + srwi $h4,$h4,24 + adde $h2,$h2,$t0 + adde $h3,$h3,$t1 + addze $h4,$h4 + +Lemit_base2_32: + addic r0,$h0,5 # compare to modulus + addze r0,$h1 + addze r0,$h2 + addze r0,$h3 + addze r0,$h4 + + srwi r0,r0,2 # see if it carried/borrowed + neg r0,r0 + andi. r0,r0,5 + + addc $h0,$h0,r0 + lwz r0,0($nonce) + addze $h1,$h1 + lwz $t0,4($nonce) + addze $h2,$h2 + lwz $t1,8($nonce) + addze $h3,$h3 + lwz $h4,12($nonce) + + addc $h0,$h0,r0 # accumulate nonce + adde $h1,$h1,$t0 + adde $h2,$h2,$t1 + adde $h3,$h3,$h4 + + addi $ctx,$mac,-1 + addi $mac,$mac,7 + + stbu $h0,1($ctx) # write [little-endian] result + srwi $h0,$h0,8 + stbu $h2,1($mac) + srwi $h2,$h2,8 + + stbu $h0,1($ctx) + srwi $h0,$h0,8 + stbu $h2,1($mac) + srwi $h2,$h2,8 + + stbu $h0,1($ctx) + srwi $h0,$h0,8 + stbu $h2,1($mac) + srwi $h2,$h2,8 + + stbu $h0,1($ctx) + stbu $h2,1($mac) + + stbu $h1,1($ctx) + srwi $h1,$h1,8 + stbu $h3,1($mac) + srwi $h3,$h3,8 + + stbu $h1,1($ctx) + srwi $h1,$h1,8 + stbu $h3,1($mac) + srwi $h3,$h3,8 + + stbu $h1,1($ctx) + srwi $h1,$h1,8 + stbu $h3,1($mac) + srwi $h3,$h3,8 + + stbu $h1,1($ctx) + stbu $h3,1($mac) + + blr + .long 0 + .byte 0,12,0x14,0,0,0,3,0 +.size .poly1305_emit,.-.poly1305_emit +___ +} } +{{{ +######################################################################## +# PowerISA 2.07/VSX section # +######################################################################## + +my $LOCALS= 6*$SIZE_T; +my $VSXFRAME = $LOCALS + 6*$SIZE_T; + $VSXFRAME += 128; # local variables + $VSXFRAME += 13*16; # v20-v31 offload + +my $BIG_ENDIAN = ($flavour !~ /le/) ? 4 : 0; + +######################################################################## +# Layout of opaque area is following: +# +# unsigned __int32 h[5]; # current hash value base 2^26 +# unsigned __int32 pad; +# unsigned __int32 is_base2_26, pad; +# unsigned __int64 r[2]; # key value base 2^64 +# struct { unsigned __int32 r^2, r^4, r^1, r^3; } r[9]; +# +# where r^n are base 2^26 digits of powers of multiplier key. There are +# 5 digits, but last four are interleaved with multiples of 5, totalling +# in 9 elements: r0, r1, 5*r1, r2, 5*r2, r3, 5*r3, r4, 5*r4. Order of +# powers is as they appear in register, not memory. + +my ($H0, $H1, $H2, $H3, $H4) = map("v$_",(0..4)); +my ($I0, $I1, $I2, $I3, $I4) = map("v$_",(5..9)); +my ($R0, $R1, $S1, $R2, $S2) = map("v$_",(10..14)); +my ($R3, $S3, $R4, $S4) = ($R1, $S1, $R2, $S2); +my ($ACC0, $ACC1, $ACC2, $ACC3, $ACC4) = map("v$_",(15..19)); +my ($T0, $T1, $T2, $T3, $T4) = map("v$_",(20..24)); +my ($_26,$_4,$_40,$_14,$mask26,$padbits,$I2perm) = map("v$_",(25..31)); +my ($x00,$x60,$x70,$x10,$x20,$x30,$x40,$x50) = (0, map("r$_",(7,8,27..31))); +my ($ctx_,$_ctx,$const) = map("r$_",(10..12)); + + if ($flavour =~ /64/) { +############################################################################### +# setup phase of poly1305_blocks_vsx is different on 32- and 64-bit platforms, +# but the base 2^26 computational part is same... + +my ($h0,$h1,$h2,$d0,$d1,$d2, $r0,$r1,$s1, $t0,$t1) = map("r$_",(6..11,27..31)); +my $mask = "r0"; + +$code.=<<___; +.globl .poly1305_blocks_vsx +.align 5 +.poly1305_blocks_vsx: + lwz r7,24($ctx) # is_base2_26 + cmpldi $len,128 + bge __poly1305_blocks_vsx + + neg r0,r7 # is_base2_26 as mask + lwz r7,0($ctx) # load hash base 2^26 + lwz r8,4($ctx) + lwz r9,8($ctx) + lwz r10,12($ctx) + lwz r11,16($ctx) + + sldi r8,r8,26 # base 2^26 -> base 2^64 + sldi r12,r9,52 + add r7,r7,r8 + srdi r9,r9,12 + sldi r10,r10,14 + addc r7,r7,r12 + sldi r8,r11,40 + adde r9,r9,r10 + srdi r11,r11,24 + addc r9,r9,r8 + addze r11,r11 + + ld r8,0($ctx) # load hash base 2^64 + ld r10,8($ctx) + ld r12,16($ctx) + + xor r7,r7,r8 # select between radixes + xor r9,r9,r10 + xor r11,r11,r12 + and r7,r7,r0 + and r9,r9,r0 + and r11,r11,r0 + xor r7,r7,r8 + xor r9,r9,r10 + xor r11,r11,r12 + + li r0,0 + std r7,0($ctx) # store hash base 2^64 + std r9,8($ctx) + std r11,16($ctx) + stw r0,24($ctx) # clear is_base2_26 + + b Lpoly1305_blocks + .long 0 + .byte 0,12,0x14,0,0,0,4,0 +.size .poly1305_blocks_vsx,.-.poly1305_blocks_vsx + +.align 5 +__poly1305_mul: + mulld $d0,$h0,$r0 # h0*r0 + mulhdu $d1,$h0,$r0 + + mulld $t0,$h1,$s1 # h1*5*r1 + mulhdu $t1,$h1,$s1 + addc $d0,$d0,$t0 + adde $d1,$d1,$t1 + + mulld $t0,$h0,$r1 # h0*r1 + mulhdu $d2,$h0,$r1 + addc $d1,$d1,$t0 + addze $d2,$d2 + + mulld $t0,$h1,$r0 # h1*r0 + mulhdu $t1,$h1,$r0 + addc $d1,$d1,$t0 + adde $d2,$d2,$t1 + + mulld $t0,$h2,$s1 # h2*5*r1 + mulld $t1,$h2,$r0 # h2*r0 + addc $d1,$d1,$t0 + adde $d2,$d2,$t1 + + andc $t0,$d2,$mask # final reduction step + and $h2,$d2,$mask + srdi $t1,$t0,2 + add $t0,$t0,$t1 + addc $h0,$d0,$t0 + addze $h1,$d1 + addze $h2,$h2 + + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 +.size __poly1305_mul,.-__poly1305_mul + +.align 5 +__poly1305_splat: + extrdi $d0,$h0,26,38 + extrdi $d1,$h0,26,12 + stw $d0,0x00($t1) + + extrdi $d2,$h0,12,0 + slwi $d0,$d1,2 + stw $d1,0x10($t1) + add $d0,$d0,$d1 # * 5 + stw $d0,0x20($t1) + + insrdi $d2,$h1,14,38 + slwi $d0,$d2,2 + stw $d2,0x30($t1) + add $d0,$d0,$d2 # * 5 + stw $d0,0x40($t1) + + extrdi $d1,$h1,26,24 + extrdi $d2,$h1,24,0 + slwi $d0,$d1,2 + stw $d1,0x50($t1) + add $d0,$d0,$d1 # * 5 + stw $d0,0x60($t1) + + insrdi $d2,$h2,3,37 + slwi $d0,$d2,2 + stw $d2,0x70($t1) + add $d0,$d0,$d2 # * 5 + stw $d0,0x80($t1) + + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 +.size __poly1305_splat,.-__poly1305_splat + +.align 5 +__poly1305_blocks_vsx: + $STU $sp,-$VSXFRAME($sp) mflr r0 - $PUSH r28,`$FRAME-$SIZE_T*4`($sp) - $PUSH r29,`$FRAME-$SIZE_T*3`($sp) - $PUSH r30,`$FRAME-$SIZE_T*2`($sp) - $PUSH r31,`$FRAME-$SIZE_T*1`($sp) - $PUSH r0,`$FRAME+$LRSAVE`($sp) + li r10,`15+$LOCALS+128` + li r11,`31+$LOCALS+128` + mfspr r12,256 + stvx v20,r10,$sp + addi r10,r10,32 + stvx v21,r11,$sp + addi r11,r11,32 + stvx v22,r10,$sp + addi r10,r10,32 + stvx v23,r10,$sp + addi r10,r10,32 + stvx v24,r11,$sp + addi r11,r11,32 + stvx v25,r10,$sp + addi r10,r10,32 + stvx v26,r10,$sp + addi r10,r10,32 + stvx v27,r11,$sp + addi r11,r11,32 + stvx v28,r10,$sp + addi r10,r10,32 + stvx v29,r11,$sp + addi r11,r11,32 + stvx v30,r10,$sp + stvx v31,r11,$sp + stw r12,`$VSXFRAME-$SIZE_T*5-4`($sp)# save vrsave + li r12,-1 + mtspr 256,r12 # preserve all AltiVec registers + $PUSH r27,`$VSXFRAME-$SIZE_T*5`($sp) + $PUSH r28,`$VSXFRAME-$SIZE_T*4`($sp) + $PUSH r29,`$VSXFRAME-$SIZE_T*3`($sp) + $PUSH r30,`$VSXFRAME-$SIZE_T*2`($sp) + $PUSH r31,`$VSXFRAME-$SIZE_T*1`($sp) + $PUSH r0,`$VSXFRAME+$LRSAVE`($sp) + + bl LPICmeup + + li $x10,0x10 + li $x20,0x20 + li $x30,0x30 + li $x40,0x40 + li $x50,0x50 + lvx_u $mask26,$x00,$const + lvx_u $_26,$x10,$const + lvx_u $_40,$x20,$const + lvx_u $I2perm,$x30,$const + lvx_u $padbits,$x40,$const + + cmplwi r7,0 # is_base2_26? + bne Lskip_init_vsx + + ld $r0,32($ctx) # load key base 2^64 + ld $r1,40($ctx) + srdi $s1,$r1,2 + li $mask,3 + add $s1,$s1,$r1 # s1 = r1 + r1>>2 + + mr $h0,$r0 # "calculate" r^1 + mr $h1,$r1 + li $h2,0 + addi $t1,$ctx,`48+(12^$BIG_ENDIAN)` + bl __poly1305_splat + + bl __poly1305_mul # calculate r^2 + addi $t1,$ctx,`48+(4^$BIG_ENDIAN)` + bl __poly1305_splat + + bl __poly1305_mul # calculate r^3 + addi $t1,$ctx,`48+(8^$BIG_ENDIAN)` + bl __poly1305_splat + + bl __poly1305_mul # calculate r^4 + addi $t1,$ctx,`48+(0^$BIG_ENDIAN)` + bl __poly1305_splat + + ld $h0,0($ctx) # load hash + ld $h1,8($ctx) + ld $h2,16($ctx) + + extrdi $d0,$h0,26,38 # base 2^64 -> base 2^26 + extrdi $d1,$h0,26,12 + extrdi $d2,$h0,12,0 + mtvrwz $H0,$d0 + insrdi $d2,$h1,14,38 + mtvrwz $H1,$d1 + extrdi $d1,$h1,26,24 + mtvrwz $H2,$d2 + extrdi $d2,$h1,24,0 + mtvrwz $H3,$d1 + insrdi $d2,$h2,3,37 + mtvrwz $H4,$d2 +___ + } else { +############################################################################### +# 32-bit initialization + +my ($h0,$h1,$h2,$h3,$h4,$t0,$t1) = map("r$_",(7..11,0,12)); +my ($R3,$S3,$R4,$S4)=($I1,$I2,$I3,$I4); + +$code.=<<___; +.globl .poly1305_blocks_vsx +.align 5 +.poly1305_blocks_vsx: + lwz r7,24($ctx) # is_base2_26 + cmplwi $len,128 + bge __poly1305_blocks_vsx + cmplwi r7,0 + beq Lpoly1305_blocks lwz $h0,0($ctx) # load hash lwz $h1,4($ctx) @@ -578,68 +1025,957 @@ Labort: lwz $h3,12($ctx) lwz $h4,16($ctx) - addic $d0,$h0,5 # compare to modulus - addze $d1,$h1 - addze $d2,$h2 - addze $d3,$h3 - addze $mask,$h4 + slwi $t0,$h1,26 # base 2^26 -> base 2^32 + srwi $h1,$h1,6 + slwi $t1,$h2,20 + srwi $h2,$h2,12 + addc $h0,$h0,$t0 + slwi $t0,$h3,14 + srwi $h3,$h3,18 + adde $h1,$h1,$t1 + slwi $t1,$h4,8 + srwi $h4,$h4,24 + adde $h2,$h2,$t0 + li $t0,0 + adde $h3,$h3,$t1 + addze $h4,$h4 - srwi $mask,$mask,2 # did it carry/borrow? - neg $mask,$mask + stw $h0,0($ctx) # store hash base 2^32 + stw $h1,4($ctx) + stw $h2,8($ctx) + stw $h3,12($ctx) + stw $h4,16($ctx) + stw $t0,24($ctx) # clear is_base2_26 - andc $h0,$h0,$mask - and $d0,$d0,$mask - andc $h1,$h1,$mask - and $d1,$d1,$mask - or $h0,$h0,$d0 - lwz $d0,0($nonce) # load nonce - andc $h2,$h2,$mask - and $d2,$d2,$mask - or $h1,$h1,$d1 - lwz $d1,4($nonce) - andc $h3,$h3,$mask - and $d3,$d3,$mask - or $h2,$h2,$d2 - lwz $d2,8($nonce) - or $h3,$h3,$d3 - lwz $d3,12($nonce) - - addc $h0,$h0,$d0 # accumulate nonce - adde $h1,$h1,$d1 - adde $h2,$h2,$d2 - adde $h3,$h3,$d3 -___ -$code.=<<___ if ($LITTLE_ENDIAN); - stw $h0,0($mac) # write result - stw $h1,4($mac) - stw $h2,8($mac) - stw $h3,12($mac) -___ -$code.=<<___ if (!$LITTLE_ENDIAN); - li $d1,4 - stwbrx $h0,0,$mac # write result - li $d2,8 - stwbrx $h1,$d1,$mac - li $d3,12 - stwbrx $h2,$d2,$mac - stwbrx $h3,$d3,$mac + b Lpoly1305_blocks + .long 0 + .byte 0,12,0x14,0,0,0,4,0 +.size .poly1305_blocks_vsx,.-.poly1305_blocks_vsx + +.align 5 +__poly1305_mul: + vmulouw $ACC0,$H0,$R0 + vmulouw $ACC1,$H1,$R0 + vmulouw $ACC2,$H2,$R0 + vmulouw $ACC3,$H3,$R0 + vmulouw $ACC4,$H4,$R0 + + vmulouw $T0,$H4,$S1 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H0,$R1 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H1,$R1 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H2,$R1 + vaddudm $ACC3,$ACC3,$T0 + vmulouw $T0,$H3,$R1 + vaddudm $ACC4,$ACC4,$T0 + + vmulouw $T0,$H3,$S2 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H4,$S2 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H0,$R2 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H1,$R2 + vaddudm $ACC3,$ACC3,$T0 + vmulouw $T0,$H2,$R2 + vaddudm $ACC4,$ACC4,$T0 + + vmulouw $T0,$H2,$S3 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H3,$S3 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H4,$S3 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H0,$R3 + vaddudm $ACC3,$ACC3,$T0 + vmulouw $T0,$H1,$R3 + vaddudm $ACC4,$ACC4,$T0 + + vmulouw $T0,$H1,$S4 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H2,$S4 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H3,$S4 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H4,$S4 + vaddudm $ACC3,$ACC3,$T0 + vmulouw $T0,$H0,$R4 + vaddudm $ACC4,$ACC4,$T0 + + ################################################################ + # lazy reduction + + vspltisb $T0,2 + vsrd $H4,$ACC3,$_26 + vsrd $H1,$ACC0,$_26 + vand $H3,$ACC3,$mask26 + vand $H0,$ACC0,$mask26 + vaddudm $H4,$H4,$ACC4 # h3 -> h4 + vaddudm $H1,$H1,$ACC1 # h0 -> h1 + + vsrd $ACC4,$H4,$_26 + vsrd $ACC1,$H1,$_26 + vand $H4,$H4,$mask26 + vand $H1,$H1,$mask26 + vaddudm $H0,$H0,$ACC4 + vaddudm $H2,$ACC2,$ACC1 # h1 -> h2 + + vsld $ACC4,$ACC4,$T0 # <<2 + vsrd $ACC2,$H2,$_26 + vand $H2,$H2,$mask26 + vaddudm $H0,$H0,$ACC4 # h4 -> h0 + vaddudm $H3,$H3,$ACC2 # h2 -> h3 + + vsrd $ACC0,$H0,$_26 + vsrd $ACC3,$H3,$_26 + vand $H0,$H0,$mask26 + vand $H3,$H3,$mask26 + vaddudm $H1,$H1,$ACC0 # h0 -> h1 + vaddudm $H4,$H4,$ACC3 # h3 -> h4 + + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 +.size __poly1305_mul,.-__poly1305_mul + +.align 5 +__poly1305_blocks_vsx: + $STU $sp,-$VSXFRAME($sp) + mflr r0 + li r10,`15+$LOCALS+128` + li r11,`31+$LOCALS+128` + mfspr r12,256 + stvx v20,r10,$sp + addi r10,r10,32 + stvx v21,r11,$sp + addi r11,r11,32 + stvx v22,r10,$sp + addi r10,r10,32 + stvx v23,r10,$sp + addi r10,r10,32 + stvx v24,r11,$sp + addi r11,r11,32 + stvx v25,r10,$sp + addi r10,r10,32 + stvx v26,r10,$sp + addi r10,r10,32 + stvx v27,r11,$sp + addi r11,r11,32 + stvx v28,r10,$sp + addi r10,r10,32 + stvx v29,r11,$sp + addi r11,r11,32 + stvx v30,r10,$sp + stvx v31,r11,$sp + stw r12,`$VSXFRAME-$SIZE_T*5-4`($sp)# save vrsave + li r12,-1 + mtspr 256,r12 # preserve all AltiVec registers + $PUSH r27,`$VSXFRAME-$SIZE_T*5`($sp) + $PUSH r28,`$VSXFRAME-$SIZE_T*4`($sp) + $PUSH r29,`$VSXFRAME-$SIZE_T*3`($sp) + $PUSH r30,`$VSXFRAME-$SIZE_T*2`($sp) + $PUSH r31,`$VSXFRAME-$SIZE_T*1`($sp) + $PUSH r0,`$VSXFRAME+$LRSAVE`($sp) + + bl LPICmeup + + li $x10,0x10 + li $x20,0x20 + li $x30,0x30 + li $x40,0x40 + li $x50,0x50 + lvx_u $mask26,$x00,$const + lvx_u $_26,$x10,$const + lvx_u $_40,$x20,$const + lvx_u $I2perm,$x30,$const + lvx_u $padbits,$x40,$const + + cmplwi r7,0 # is_base2_26? + bne Lskip_init_vsx + + lwz $h1,32($ctx) # load key base 2^32 + lwz $h2,36($ctx) + lwz $h3,40($ctx) + lwz $h4,44($ctx) + + extrwi $h0,$h1,26,6 # base 2^32 -> base 2^26 + extrwi $h1,$h1,6,0 + insrwi $h1,$h2,20,6 + extrwi $h2,$h2,12,0 + insrwi $h2,$h3,14,6 + extrwi $h3,$h3,18,0 + insrwi $h3,$h4,8,6 + extrwi $h4,$h4,24,0 + + mtvrwz $R0,$h0 + slwi $h0,$h1,2 + mtvrwz $R1,$h1 + add $h1,$h1,$h0 + mtvrwz $S1,$h1 + slwi $h1,$h2,2 + mtvrwz $R2,$h2 + add $h2,$h2,$h1 + mtvrwz $S2,$h2 + slwi $h2,$h3,2 + mtvrwz $R3,$h3 + add $h3,$h3,$h2 + mtvrwz $S3,$h3 + slwi $h3,$h4,2 + mtvrwz $R4,$h4 + add $h4,$h4,$h3 + mtvrwz $S4,$h4 + + vmr $H0,$R0 + vmr $H1,$R1 + vmr $H2,$R2 + vmr $H3,$R3 + vmr $H4,$R4 + + bl __poly1305_mul # r^1:- * r^1:- + + vpermdi $R0,$H0,$R0,0b00 + vpermdi $R1,$H1,$R1,0b00 + vpermdi $R2,$H2,$R2,0b00 + vpermdi $R3,$H3,$R3,0b00 + vpermdi $R4,$H4,$R4,0b00 + vpermdi $H0,$H0,$H0,0b00 + vpermdi $H1,$H1,$H1,0b00 + vpermdi $H2,$H2,$H2,0b00 + vpermdi $H3,$H3,$H3,0b00 + vpermdi $H4,$H4,$H4,0b00 + vsld $S1,$R1,$T0 # <<2 + vsld $S2,$R2,$T0 + vsld $S3,$R3,$T0 + vsld $S4,$R4,$T0 + vaddudm $S1,$S1,$R1 + vaddudm $S2,$S2,$R2 + vaddudm $S3,$S3,$R3 + vaddudm $S4,$S4,$R4 + + bl __poly1305_mul # r^2:r^2 * r^2:r^1 + + addi $h0,$ctx,0x60 + lwz $h1,0($ctx) # load hash + lwz $h2,4($ctx) + lwz $h3,8($ctx) + lwz $h4,12($ctx) + lwz $t0,16($ctx) + + vmrgow $R0,$R0,$H0 # r^2:r^4:r^1:r^3 + vmrgow $R1,$R1,$H1 + vmrgow $R2,$R2,$H2 + vmrgow $R3,$R3,$H3 + vmrgow $R4,$R4,$H4 + vslw $S1,$R1,$T0 # <<2 + vslw $S2,$R2,$T0 + vslw $S3,$R3,$T0 + vslw $S4,$R4,$T0 + vadduwm $S1,$S1,$R1 + vadduwm $S2,$S2,$R2 + vadduwm $S3,$S3,$R3 + vadduwm $S4,$S4,$R4 + + stvx_u $R0,$x30,$ctx + stvx_u $R1,$x40,$ctx + stvx_u $S1,$x50,$ctx + stvx_u $R2,$x00,$h0 + stvx_u $S2,$x10,$h0 + stvx_u $R3,$x20,$h0 + stvx_u $S3,$x30,$h0 + stvx_u $R4,$x40,$h0 + stvx_u $S4,$x50,$h0 + + extrwi $h0,$h1,26,6 # base 2^32 -> base 2^26 + extrwi $h1,$h1,6,0 + mtvrwz $H0,$h0 + insrwi $h1,$h2,20,6 + extrwi $h2,$h2,12,0 + mtvrwz $H1,$h1 + insrwi $h2,$h3,14,6 + extrwi $h3,$h3,18,0 + mtvrwz $H2,$h2 + insrwi $h3,$h4,8,6 + extrwi $h4,$h4,24,0 + mtvrwz $H3,$h3 + insrwi $h4,$t0,3,5 + mtvrwz $H4,$h4 ___ + } $code.=<<___; - $POP r28,`$FRAME-$SIZE_T*4`($sp) - $POP r29,`$FRAME-$SIZE_T*3`($sp) - $POP r30,`$FRAME-$SIZE_T*2`($sp) - $POP r31,`$FRAME-$SIZE_T*1`($sp) - addi $sp,$sp,$FRAME + li r0,1 + stw r0,24($ctx) # set is_base2_26 + b Loaded_vsx + +.align 4 +Lskip_init_vsx: + li $x10,4 + li $x20,8 + li $x30,12 + li $x40,16 + lvwzx_u $H0,$x00,$ctx + lvwzx_u $H1,$x10,$ctx + lvwzx_u $H2,$x20,$ctx + lvwzx_u $H3,$x30,$ctx + lvwzx_u $H4,$x40,$ctx + +Loaded_vsx: + li $x10,0x10 + li $x20,0x20 + li $x30,0x30 + li $x40,0x40 + li $x50,0x50 + li $x60,0x60 + li $x70,0x70 + addi $ctx_,$ctx,64 # &ctx->r[1] + addi $_ctx,$sp,`$LOCALS+15` # &ctx->r[1], r^2:r^4 shadow + + vxor $T0,$T0,$T0 # ensure second half is zero + vpermdi $H0,$H0,$T0,0b00 + vpermdi $H1,$H1,$T0,0b00 + vpermdi $H2,$H2,$T0,0b00 + vpermdi $H3,$H3,$T0,0b00 + vpermdi $H4,$H4,$T0,0b00 + + be?lvx_u $_4,$x50,$const # byte swap mask + lvx_u $T1,$x00,$inp # load first input block + lvx_u $T2,$x10,$inp + lvx_u $T3,$x20,$inp + lvx_u $T4,$x30,$inp + be?vperm $T1,$T1,$T1,$_4 + be?vperm $T2,$T2,$T2,$_4 + be?vperm $T3,$T3,$T3,$_4 + be?vperm $T4,$T4,$T4,$_4 + + vpermdi $I0,$T1,$T2,0b00 # smash input to base 2^26 + vspltisb $_4,4 + vperm $I2,$T1,$T2,$I2perm # 0x...0e0f0001...1e1f1011 + vspltisb $_14,14 + vpermdi $I3,$T1,$T2,0b11 + + vsrd $I1,$I0,$_26 + vsrd $I2,$I2,$_4 + vsrd $I4,$I3,$_40 + vsrd $I3,$I3,$_14 + vand $I0,$I0,$mask26 + vand $I1,$I1,$mask26 + vand $I2,$I2,$mask26 + vand $I3,$I3,$mask26 + + vpermdi $T1,$T3,$T4,0b00 + vperm $T2,$T3,$T4,$I2perm # 0x...0e0f0001...1e1f1011 + vpermdi $T3,$T3,$T4,0b11 + + vsrd $T0,$T1,$_26 + vsrd $T2,$T2,$_4 + vsrd $T4,$T3,$_40 + vsrd $T3,$T3,$_14 + vand $T1,$T1,$mask26 + vand $T0,$T0,$mask26 + vand $T2,$T2,$mask26 + vand $T3,$T3,$mask26 + + # inp[2]:inp[0]:inp[3]:inp[1] + vmrgow $I4,$T4,$I4 + vmrgow $I0,$T1,$I0 + vmrgow $I1,$T0,$I1 + vmrgow $I2,$T2,$I2 + vmrgow $I3,$T3,$I3 + vor $I4,$I4,$padbits + + lvx_splt $R0,$x30,$ctx # taking lvx_vsplt out of loop + lvx_splt $R1,$x00,$ctx_ # gives ~8% improvement + lvx_splt $S1,$x10,$ctx_ + lvx_splt $R2,$x20,$ctx_ + lvx_splt $S2,$x30,$ctx_ + lvx_splt $T1,$x40,$ctx_ + lvx_splt $T2,$x50,$ctx_ + lvx_splt $T3,$x60,$ctx_ + lvx_splt $T4,$x70,$ctx_ + stvx $R1,$x00,$_ctx + stvx $S1,$x10,$_ctx + stvx $R2,$x20,$_ctx + stvx $S2,$x30,$_ctx + stvx $T1,$x40,$_ctx + stvx $T2,$x50,$_ctx + stvx $T3,$x60,$_ctx + stvx $T4,$x70,$_ctx + + addi $inp,$inp,0x40 + addi $const,$const,0x50 + addi r0,$len,-64 + srdi r0,r0,6 + mtctr r0 + b Loop_vsx + +.align 4 +Loop_vsx: + ################################################################ + ## ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2 + ## ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r + ## \___________________/ + ## + ## Note that we start with inp[2:3]*r^2. This is because it + ## doesn't depend on reduction in previous iteration. + ################################################################ + ## d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4 + ## d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4 + ## d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4 + ## d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4 + ## d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4 + + vmuleuw $ACC0,$I0,$R0 + vmuleuw $ACC1,$I0,$R1 + vmuleuw $ACC2,$I0,$R2 + vmuleuw $ACC3,$I1,$R2 + + vmuleuw $T0,$I1,$R0 + vaddudm $ACC1,$ACC1,$T0 + vmuleuw $T0,$I1,$R1 + vaddudm $ACC2,$ACC2,$T0 + vmuleuw $ACC4,$I2,$R2 + vmuleuw $T0,$I4,$S1 + vaddudm $ACC0,$ACC0,$T0 + vmuleuw $T0,$I2,$R1 + vaddudm $ACC3,$ACC3,$T0 + lvx $S3,$x50,$_ctx + vmuleuw $T0,$I3,$R1 + vaddudm $ACC4,$ACC4,$T0 + lvx $R3,$x40,$_ctx + + vaddudm $H2,$H2,$I2 + vaddudm $H0,$H0,$I0 + vaddudm $H3,$H3,$I3 + vaddudm $H1,$H1,$I1 + vaddudm $H4,$H4,$I4 + + vmuleuw $T0,$I3,$S2 + vaddudm $ACC0,$ACC0,$T0 + vmuleuw $T0,$I4,$S2 + vaddudm $ACC1,$ACC1,$T0 + vmuleuw $T0,$I2,$R0 + vaddudm $ACC2,$ACC2,$T0 + vmuleuw $T0,$I3,$R0 + vaddudm $ACC3,$ACC3,$T0 + lvx $S4,$x70,$_ctx + vmuleuw $T0,$I4,$R0 + vaddudm $ACC4,$ACC4,$T0 + lvx $R4,$x60,$_ctx + + vmuleuw $T0,$I2,$S3 + vaddudm $ACC0,$ACC0,$T0 + vmuleuw $T0,$I3,$S3 + vaddudm $ACC1,$ACC1,$T0 + vmuleuw $T0,$I4,$S3 + vaddudm $ACC2,$ACC2,$T0 + vmuleuw $T0,$I0,$R3 + vaddudm $ACC3,$ACC3,$T0 + vmuleuw $T0,$I1,$R3 + vaddudm $ACC4,$ACC4,$T0 + + be?lvx_u $_4,$x00,$const # byte swap mask + lvx_u $T1,$x00,$inp # load next input block + lvx_u $T2,$x10,$inp + lvx_u $T3,$x20,$inp + lvx_u $T4,$x30,$inp + be?vperm $T1,$T1,$T1,$_4 + be?vperm $T2,$T2,$T2,$_4 + be?vperm $T3,$T3,$T3,$_4 + be?vperm $T4,$T4,$T4,$_4 + + vmuleuw $T0,$I1,$S4 + vaddudm $ACC0,$ACC0,$T0 + vmuleuw $T0,$I2,$S4 + vaddudm $ACC1,$ACC1,$T0 + vmuleuw $T0,$I3,$S4 + vaddudm $ACC2,$ACC2,$T0 + vmuleuw $T0,$I4,$S4 + vaddudm $ACC3,$ACC3,$T0 + vmuleuw $T0,$I0,$R4 + vaddudm $ACC4,$ACC4,$T0 + + vpermdi $I0,$T1,$T2,0b00 # smash input to base 2^26 + vspltisb $_4,4 + vperm $I2,$T1,$T2,$I2perm # 0x...0e0f0001...1e1f1011 + vpermdi $I3,$T1,$T2,0b11 + + # (hash + inp[0:1]) * r^4 + vmulouw $T0,$H0,$R0 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H1,$R0 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H2,$R0 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H3,$R0 + vaddudm $ACC3,$ACC3,$T0 + vmulouw $T0,$H4,$R0 + vaddudm $ACC4,$ACC4,$T0 + + vpermdi $T1,$T3,$T4,0b00 + vperm $T2,$T3,$T4,$I2perm # 0x...0e0f0001...1e1f1011 + vpermdi $T3,$T3,$T4,0b11 + + vmulouw $T0,$H2,$S3 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H3,$S3 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H4,$S3 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H0,$R3 + vaddudm $ACC3,$ACC3,$T0 + lvx $S1,$x10,$_ctx + vmulouw $T0,$H1,$R3 + vaddudm $ACC4,$ACC4,$T0 + lvx $R1,$x00,$_ctx + + vsrd $I1,$I0,$_26 + vsrd $I2,$I2,$_4 + vsrd $I4,$I3,$_40 + vsrd $I3,$I3,$_14 + + vmulouw $T0,$H1,$S4 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H2,$S4 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H3,$S4 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H4,$S4 + vaddudm $ACC3,$ACC3,$T0 + lvx $S2,$x30,$_ctx + vmulouw $T0,$H0,$R4 + vaddudm $ACC4,$ACC4,$T0 + lvx $R2,$x20,$_ctx + + vand $I0,$I0,$mask26 + vand $I1,$I1,$mask26 + vand $I2,$I2,$mask26 + vand $I3,$I3,$mask26 + + vmulouw $T0,$H4,$S1 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H0,$R1 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H1,$R1 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H2,$R1 + vaddudm $ACC3,$ACC3,$T0 + vmulouw $T0,$H3,$R1 + vaddudm $ACC4,$ACC4,$T0 + + vsrd $T2,$T2,$_4 + vsrd $_4,$T1,$_26 + vsrd $T4,$T3,$_40 + vsrd $T3,$T3,$_14 + + vmulouw $T0,$H3,$S2 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H4,$S2 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H0,$R2 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H1,$R2 + vaddudm $ACC3,$ACC3,$T0 + vmulouw $T0,$H2,$R2 + vaddudm $ACC4,$ACC4,$T0 + + vand $T1,$T1,$mask26 + vand $_4,$_4,$mask26 + vand $T2,$T2,$mask26 + vand $T3,$T3,$mask26 + + ################################################################ + # lazy reduction as discussed in "NEON crypto" by D.J. Bernstein + # and P. Schwabe + + vspltisb $T0,2 + vsrd $H4,$ACC3,$_26 + vsrd $H1,$ACC0,$_26 + vand $H3,$ACC3,$mask26 + vand $H0,$ACC0,$mask26 + vaddudm $H4,$H4,$ACC4 # h3 -> h4 + vaddudm $H1,$H1,$ACC1 # h0 -> h1 + + vmrgow $I4,$T4,$I4 + vmrgow $I0,$T1,$I0 + vmrgow $I1,$_4,$I1 + vmrgow $I2,$T2,$I2 + vmrgow $I3,$T3,$I3 + vor $I4,$I4,$padbits + + vsrd $ACC4,$H4,$_26 + vsrd $ACC1,$H1,$_26 + vand $H4,$H4,$mask26 + vand $H1,$H1,$mask26 + vaddudm $H0,$H0,$ACC4 + vaddudm $H2,$ACC2,$ACC1 # h1 -> h2 + + vsld $ACC4,$ACC4,$T0 # <<2 + vsrd $ACC2,$H2,$_26 + vand $H2,$H2,$mask26 + vaddudm $H0,$H0,$ACC4 # h4 -> h0 + vaddudm $H3,$H3,$ACC2 # h2 -> h3 + + vsrd $ACC0,$H0,$_26 + vsrd $ACC3,$H3,$_26 + vand $H0,$H0,$mask26 + vand $H3,$H3,$mask26 + vaddudm $H1,$H1,$ACC0 # h0 -> h1 + vaddudm $H4,$H4,$ACC3 # h3 -> h4 + + addi $inp,$inp,0x40 + bdnz Loop_vsx + + neg $len,$len + andi. $len,$len,0x30 + sub $inp,$inp,$len + + lvx_u $R0,$x30,$ctx # load all powers + lvx_u $R1,$x00,$ctx_ + lvx_u $S1,$x10,$ctx_ + lvx_u $R2,$x20,$ctx_ + lvx_u $S2,$x30,$ctx_ + +Last_vsx: + vmuleuw $ACC0,$I0,$R0 + vmuleuw $ACC1,$I1,$R0 + vmuleuw $ACC2,$I2,$R0 + vmuleuw $ACC3,$I3,$R0 + vmuleuw $ACC4,$I4,$R0 + + vmuleuw $T0,$I4,$S1 + vaddudm $ACC0,$ACC0,$T0 + vmuleuw $T0,$I0,$R1 + vaddudm $ACC1,$ACC1,$T0 + vmuleuw $T0,$I1,$R1 + vaddudm $ACC2,$ACC2,$T0 + vmuleuw $T0,$I2,$R1 + vaddudm $ACC3,$ACC3,$T0 + lvx_u $S3,$x50,$ctx_ + vmuleuw $T0,$I3,$R1 + vaddudm $ACC4,$ACC4,$T0 + lvx_u $R3,$x40,$ctx_ + + vaddudm $H2,$H2,$I2 + vaddudm $H0,$H0,$I0 + vaddudm $H3,$H3,$I3 + vaddudm $H1,$H1,$I1 + vaddudm $H4,$H4,$I4 + + vmuleuw $T0,$I3,$S2 + vaddudm $ACC0,$ACC0,$T0 + vmuleuw $T0,$I4,$S2 + vaddudm $ACC1,$ACC1,$T0 + vmuleuw $T0,$I0,$R2 + vaddudm $ACC2,$ACC2,$T0 + vmuleuw $T0,$I1,$R2 + vaddudm $ACC3,$ACC3,$T0 + lvx_u $S4,$x70,$ctx_ + vmuleuw $T0,$I2,$R2 + vaddudm $ACC4,$ACC4,$T0 + lvx_u $R4,$x60,$ctx_ + + vmuleuw $T0,$I2,$S3 + vaddudm $ACC0,$ACC0,$T0 + vmuleuw $T0,$I3,$S3 + vaddudm $ACC1,$ACC1,$T0 + vmuleuw $T0,$I4,$S3 + vaddudm $ACC2,$ACC2,$T0 + vmuleuw $T0,$I0,$R3 + vaddudm $ACC3,$ACC3,$T0 + vmuleuw $T0,$I1,$R3 + vaddudm $ACC4,$ACC4,$T0 + + vmuleuw $T0,$I1,$S4 + vaddudm $ACC0,$ACC0,$T0 + vmuleuw $T0,$I2,$S4 + vaddudm $ACC1,$ACC1,$T0 + vmuleuw $T0,$I3,$S4 + vaddudm $ACC2,$ACC2,$T0 + vmuleuw $T0,$I4,$S4 + vaddudm $ACC3,$ACC3,$T0 + vmuleuw $T0,$I0,$R4 + vaddudm $ACC4,$ACC4,$T0 + + # (hash + inp[0:1]) * r^4 + vmulouw $T0,$H0,$R0 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H1,$R0 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H2,$R0 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H3,$R0 + vaddudm $ACC3,$ACC3,$T0 + vmulouw $T0,$H4,$R0 + vaddudm $ACC4,$ACC4,$T0 + + vmulouw $T0,$H2,$S3 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H3,$S3 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H4,$S3 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H0,$R3 + vaddudm $ACC3,$ACC3,$T0 + lvx_u $S1,$x10,$ctx_ + vmulouw $T0,$H1,$R3 + vaddudm $ACC4,$ACC4,$T0 + lvx_u $R1,$x00,$ctx_ + + vmulouw $T0,$H1,$S4 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H2,$S4 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H3,$S4 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H4,$S4 + vaddudm $ACC3,$ACC3,$T0 + lvx_u $S2,$x30,$ctx_ + vmulouw $T0,$H0,$R4 + vaddudm $ACC4,$ACC4,$T0 + lvx_u $R2,$x20,$ctx_ + + vmulouw $T0,$H4,$S1 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H0,$R1 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H1,$R1 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H2,$R1 + vaddudm $ACC3,$ACC3,$T0 + vmulouw $T0,$H3,$R1 + vaddudm $ACC4,$ACC4,$T0 + + vmulouw $T0,$H3,$S2 + vaddudm $ACC0,$ACC0,$T0 + vmulouw $T0,$H4,$S2 + vaddudm $ACC1,$ACC1,$T0 + vmulouw $T0,$H0,$R2 + vaddudm $ACC2,$ACC2,$T0 + vmulouw $T0,$H1,$R2 + vaddudm $ACC3,$ACC3,$T0 + vmulouw $T0,$H2,$R2 + vaddudm $ACC4,$ACC4,$T0 + + ################################################################ + # horizontal addition + + vpermdi $H0,$ACC0,$ACC0,0b10 + vpermdi $H1,$ACC1,$ACC1,0b10 + vpermdi $H2,$ACC2,$ACC2,0b10 + vpermdi $H3,$ACC3,$ACC3,0b10 + vpermdi $H4,$ACC4,$ACC4,0b10 + vaddudm $ACC0,$ACC0,$H0 + vaddudm $ACC1,$ACC1,$H1 + vaddudm $ACC2,$ACC2,$H2 + vaddudm $ACC3,$ACC3,$H3 + vaddudm $ACC4,$ACC4,$H4 + + ################################################################ + # lazy reduction + + vspltisb $T0,2 + vsrd $H4,$ACC3,$_26 + vsrd $H1,$ACC0,$_26 + vand $H3,$ACC3,$mask26 + vand $H0,$ACC0,$mask26 + vaddudm $H4,$H4,$ACC4 # h3 -> h4 + vaddudm $H1,$H1,$ACC1 # h0 -> h1 + + vsrd $ACC4,$H4,$_26 + vsrd $ACC1,$H1,$_26 + vand $H4,$H4,$mask26 + vand $H1,$H1,$mask26 + vaddudm $H0,$H0,$ACC4 + vaddudm $H2,$ACC2,$ACC1 # h1 -> h2 + + vsld $ACC4,$ACC4,$T0 # <<2 + vsrd $ACC2,$H2,$_26 + vand $H2,$H2,$mask26 + vaddudm $H0,$H0,$ACC4 # h4 -> h0 + vaddudm $H3,$H3,$ACC2 # h2 -> h3 + + vsrd $ACC0,$H0,$_26 + vsrd $ACC3,$H3,$_26 + vand $H0,$H0,$mask26 + vand $H3,$H3,$mask26 + vaddudm $H1,$H1,$ACC0 # h0 -> h1 + vaddudm $H4,$H4,$ACC3 # h3 -> h4 + + beq Ldone_vsx + + add r6,$const,$len + + be?lvx_u $_4,$x00,$const # byte swap mask + lvx_u $T1,$x00,$inp # load last partial input block + lvx_u $T2,$x10,$inp + lvx_u $T3,$x20,$inp + lvx_u $T4,$x30,$inp + be?vperm $T1,$T1,$T1,$_4 + be?vperm $T2,$T2,$T2,$_4 + be?vperm $T3,$T3,$T3,$_4 + be?vperm $T4,$T4,$T4,$_4 + + vpermdi $I0,$T1,$T2,0b00 # smash input to base 2^26 + vspltisb $_4,4 + vperm $I2,$T1,$T2,$I2perm # 0x...0e0f0001...1e1f1011 + vpermdi $I3,$T1,$T2,0b11 + + vsrd $I1,$I0,$_26 + vsrd $I2,$I2,$_4 + vsrd $I4,$I3,$_40 + vsrd $I3,$I3,$_14 + vand $I0,$I0,$mask26 + vand $I1,$I1,$mask26 + vand $I2,$I2,$mask26 + vand $I3,$I3,$mask26 + + vpermdi $T0,$T3,$T4,0b00 + vperm $T1,$T3,$T4,$I2perm # 0x...0e0f0001...1e1f1011 + vpermdi $T2,$T3,$T4,0b11 + + lvx_u $ACC0,$x00,r6 + lvx_u $ACC1,$x30,r6 + + vsrd $T3,$T0,$_26 + vsrd $T1,$T1,$_4 + vsrd $T4,$T2,$_40 + vsrd $T2,$T2,$_14 + vand $T0,$T0,$mask26 + vand $T3,$T3,$mask26 + vand $T1,$T1,$mask26 + vand $T2,$T2,$mask26 + + # inp[2]:inp[0]:inp[3]:inp[1] + vmrgow $I4,$T4,$I4 + vmrgow $I0,$T0,$I0 + vmrgow $I1,$T3,$I1 + vmrgow $I2,$T1,$I2 + vmrgow $I3,$T2,$I3 + vor $I4,$I4,$padbits + + vperm $H0,$H0,$H0,$ACC0 # move hash to right lane + vand $I0,$I0, $ACC1 # mask redundant input lane[s] + vperm $H1,$H1,$H1,$ACC0 + vand $I1,$I1, $ACC1 + vperm $H2,$H2,$H2,$ACC0 + vand $I2,$I2, $ACC1 + vperm $H3,$H3,$H3,$ACC0 + vand $I3,$I3, $ACC1 + vperm $H4,$H4,$H4,$ACC0 + vand $I4,$I4, $ACC1 + + vaddudm $I0,$I0,$H0 # accumulate hash + vxor $H0,$H0,$H0 # wipe hash value + vaddudm $I1,$I1,$H1 + vxor $H1,$H1,$H1 + vaddudm $I2,$I2,$H2 + vxor $H2,$H2,$H2 + vaddudm $I3,$I3,$H3 + vxor $H3,$H3,$H3 + vaddudm $I4,$I4,$H4 + vxor $H4,$H4,$H4 + + xor. $len,$len,$len + b Last_vsx + +.align 4 +Ldone_vsx: + $POP r0,`$VSXFRAME+$LRSAVE`($sp) + li $x10,4 + li $x20,8 + li $x30,12 + li $x40,16 + stvwx_u $H0,$x00,$ctx # store hash + stvwx_u $H1,$x10,$ctx + stvwx_u $H2,$x20,$ctx + stvwx_u $H3,$x30,$ctx + stvwx_u $H4,$x40,$ctx + + lwz r12,`$VSXFRAME-$SIZE_T*5-4`($sp)# pull vrsave + mtlr r0 + li r10,`15+$LOCALS+128` + li r11,`31+$LOCALS+128` + mtspr 256,r12 # restore vrsave + lvx v20,r10,$sp + addi r10,r10,32 + lvx v21,r10,$sp + addi r10,r10,32 + lvx v22,r11,$sp + addi r11,r11,32 + lvx v23,r10,$sp + addi r10,r10,32 + lvx v24,r11,$sp + addi r11,r11,32 + lvx v25,r10,$sp + addi r10,r10,32 + lvx v26,r11,$sp + addi r11,r11,32 + lvx v27,r10,$sp + addi r10,r10,32 + lvx v28,r11,$sp + addi r11,r11,32 + lvx v29,r10,$sp + addi r10,r10,32 + lvx v30,r11,$sp + lvx v31,r10,$sp + $POP r27,`$VSXFRAME-$SIZE_T*5`($sp) + $POP r28,`$VSXFRAME-$SIZE_T*4`($sp) + $POP r29,`$VSXFRAME-$SIZE_T*3`($sp) + $POP r30,`$VSXFRAME-$SIZE_T*2`($sp) + $POP r31,`$VSXFRAME-$SIZE_T*1`($sp) + addi $sp,$sp,$VSXFRAME blr .long 0 - .byte 0,12,4,1,0x80,4,3,0 -.size .poly1305_emit,.-.poly1305_emit + .byte 0,12,0x04,1,0x80,5,4,0 + .long 0 +.size __poly1305_blocks_vsx,.-__poly1305_blocks_vsx + +.align 6 +LPICmeup: + mflr r0 + bcl 20,31,\$+4 + mflr $const # vvvvvv "distance" between . and 1st data entry + addi $const,$const,`64-8` + mtlr r0 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + .space `64-9*4` + +.quad 0x0000000003ffffff,0x0000000003ffffff # mask26 +.quad 0x000000000000001a,0x000000000000001a # _26 +.quad 0x0000000000000028,0x0000000000000028 # _40 +.quad 0x000000000e0f0001,0x000000001e1f1011 # I2perm +.quad 0x0100000001000000,0x0100000001000000 # padbits +.quad 0x0706050403020100,0x0f0e0d0c0b0a0908 # byte swap for big-endian + +.quad 0x0000000000000000,0x0000000004050607 # magic tail masks +.quad 0x0405060700000000,0x0000000000000000 +.quad 0x0000000000000000,0x0405060700000000 + +.quad 0xffffffff00000000,0xffffffffffffffff +.quad 0xffffffff00000000,0xffffffff00000000 +.quad 0x0000000000000000,0xffffffff00000000 ___ - } +}}} $code.=<<___; -.asciz "Poly1305 for PPC, CRYPTOGAMS by " +.asciz "Poly1305 for PPC, CRYPTOGAMS by \@dot-asm" ___ -$code =~ s/\`([^\`]*)\`/eval $1/gem; -print $code; +foreach (split("\n",$code)) { + s/\`([^\`]*)\`/eval($1)/ge; + + # instructions prefixed with '?' are endian-specific and need + # to be adjusted accordingly... + if ($flavour !~ /le$/) { # big-endian + s/be\?// or + s/le\?/#le#/ + } else { # little-endian + s/le\?// or + s/be\?/#be#/ + } + + print $_,"\n"; +} close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/poly1305/asm/poly1305-ppcfp.pl b/crypto/openssl/crypto/poly1305/asm/poly1305-ppcfp.pl index a9ab20714697..218708a46257 100755 --- a/crypto/openssl/crypto/poly1305/asm/poly1305-ppcfp.pl +++ b/crypto/openssl/crypto/poly1305/asm/poly1305-ppcfp.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -27,7 +27,10 @@ # POWER7 3.50/+30% # POWER8 3.75/+10% -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -54,7 +57,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $LOCALS=6*$SIZE_T; $FRAME=$LOCALS+6*8+18*8; diff --git a/crypto/openssl/crypto/poly1305/asm/poly1305-s390x.pl b/crypto/openssl/crypto/poly1305/asm/poly1305-s390x.pl index bcc8fd3b886a..4a93064ff663 100755 --- a/crypto/openssl/crypto/poly1305/asm/poly1305-s390x.pl +++ b/crypto/openssl/crypto/poly1305/asm/poly1305-s390x.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -24,204 +24,961 @@ # # On side note, z13 enables vector base 2^26 implementation... -$flavour = shift; +# +# January 2019 +# +# Add vx code path (base 2^26). +# +# Copyright IBM Corp. 2019 +# Author: Patrick Steuer +# +# January 2019 +# +# Add vector base 2^26 implementation. It's problematic to accurately +# measure performance, because reference system is hardly idle. But +# it's sub-cycle, i.e. less than 1 cycle per processed byte, and it's +# >=20% faster than IBM's submission on long inputs, and much faster on +# short ones, because calculation of key powers is postponed till we +# know that input is long enough to justify the additional overhead. + +use strict; +use FindBin qw($Bin); +use lib "$Bin/../.."; +use perlasm::s390x qw(:DEFAULT :GE :EI :MI1 :VX AUTOLOAD LABEL INCLUDE); + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +my ($z,$SIZE_T); if ($flavour =~ /3[12]/) { + $z=0; # S/390 ABI $SIZE_T=4; - $g=""; } else { + $z=1; # zSeries ABI $SIZE_T=8; - $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; - -$sp="%r15"; +my $stdframe=16*$SIZE_T+4*8; +my $sp="%r15"; my ($ctx,$inp,$len,$padbit) = map("%r$_",(2..5)); -$code.=<<___; -.text - -.globl poly1305_init -.type poly1305_init,\@function -.align 16 -poly1305_init: - lghi %r0,0 - lghi %r1,-1 - stg %r0,0($ctx) # zero hash value - stg %r0,8($ctx) - stg %r0,16($ctx) - - cl${g}r $inp,%r0 - je .Lno_key - - lrvg %r4,0($inp) # load little-endian key - lrvg %r5,8($inp) - - nihl %r1,0xffc0 # 0xffffffc0ffffffff - srlg %r0,%r1,4 # 0x0ffffffc0fffffff - srlg %r1,%r1,4 - nill %r1,0xfffc # 0x0ffffffc0ffffffc - - ngr %r4,%r0 - ngr %r5,%r1 - - stg %r4,32($ctx) - stg %r5,40($ctx) - -.Lno_key: - lghi %r2,0 - br %r14 -.size poly1305_init,.-poly1305_init -___ +PERLASM_BEGIN($output); + +INCLUDE ("s390x_arch.h"); +TEXT (); + +################ +# static void poly1305_init(void *ctx, const unsigned char key[16]) +{ +GLOBL ("poly1305_init"); +TYPE ("poly1305_init","\@function"); +ALIGN (16); +LABEL ("poly1305_init"); + lghi ("%r0",0); + lghi ("%r1",-1); + stg ("%r0","0($ctx)"); # zero hash value + stg ("%r0","8($ctx)"); + stg ("%r0","16($ctx)"); + st ("%r0","24($ctx)"); # clear is_base2_26 + lgr ("%r5",$ctx); # reassign $ctx + lghi ("%r2",0); + +&{$z? \&clgr:\&clr} ($inp,"%r0"); + je (".Lno_key"); + + lrvg ("%r2","0($inp)"); # load little-endian key + lrvg ("%r3","8($inp)"); + + nihl ("%r1",0xffc0); # 0xffffffc0ffffffff + srlg ("%r0","%r1",4); # 0x0ffffffc0fffffff + srlg ("%r1","%r1",4); + nill ("%r1",0xfffc); # 0x0ffffffc0ffffffc + + ngr ("%r2","%r0"); + ngr ("%r3","%r1"); + + stmg ("%r2","%r3","32(%r5)"); + + larl ("%r1","OPENSSL_s390xcap_P"); + lg ("%r0","16(%r1)"); + srlg ("%r0","%r0",62); + nill ("%r0",1); # extract vx bit + lcgr ("%r0","%r0"); + larl ("%r1",".Lpoly1305_blocks"); + larl ("%r2",".Lpoly1305_blocks_vx"); + larl ("%r3",".Lpoly1305_emit"); +&{$z? \&xgr:\&xr} ("%r2","%r1"); # select between scalar and vector +&{$z? \&ngr:\&nr} ("%r2","%r0"); +&{$z? \&xgr:\&xr} ("%r2","%r1"); +&{$z? \&stmg:\&stm} ("%r2","%r3","0(%r4)"); + lghi ("%r2",1); +LABEL (".Lno_key"); + br ("%r14"); +SIZE ("poly1305_init",".-poly1305_init"); +} + +################ +# static void poly1305_blocks(void *ctx, const unsigned char *inp, +# size_t len, u32 padbit) { my ($d0hi,$d0lo,$d1hi,$d1lo,$t0,$h0,$t1,$h1,$h2) = map("%r$_",(6..14)); my ($r0,$r1,$s1) = map("%r$_",(0..2)); -$code.=<<___; -.globl poly1305_blocks -.type poly1305_blocks,\@function -.align 16 -poly1305_blocks: - srl${g} $len,4 # fixed-up in 64-bit build - lghi %r0,0 - cl${g}r $len,%r0 - je .Lno_data - - stm${g} %r6,%r14,`6*$SIZE_T`($sp) - - llgfr $padbit,$padbit # clear upper half, much needed with - # non-64-bit ABI - lg $r0,32($ctx) # load key - lg $r1,40($ctx) - - lg $h0,0($ctx) # load hash value - lg $h1,8($ctx) - lg $h2,16($ctx) - - st$g $ctx,`2*$SIZE_T`($sp) # off-load $ctx - srlg $s1,$r1,2 - algr $s1,$r1 # s1 = r1 + r1>>2 - j .Loop - -.align 16 -.Loop: - lrvg $d0lo,0($inp) # load little-endian input - lrvg $d1lo,8($inp) - la $inp,16($inp) - - algr $d0lo,$h0 # accumulate input - alcgr $d1lo,$h1 - - lgr $h0,$d0lo - mlgr $d0hi,$r0 # h0*r0 -> $d0hi:$d0lo - lgr $h1,$d1lo - mlgr $d1hi,$s1 # h1*5*r1 -> $d1hi:$d1lo - - mlgr $t0,$r1 # h0*r1 -> $t0:$h0 - mlgr $t1,$r0 # h1*r0 -> $t1:$h1 - alcgr $h2,$padbit - - algr $d0lo,$d1lo - lgr $d1lo,$h2 - alcgr $d0hi,$d1hi - lghi $d1hi,0 - - algr $h1,$h0 - alcgr $t1,$t0 - - msgr $d1lo,$s1 # h2*s1 - msgr $h2,$r0 # h2*r0 - - algr $h1,$d1lo - alcgr $t1,$d1hi # $d1hi is zero - - algr $h1,$d0hi - alcgr $h2,$t1 - - lghi $h0,-4 # final reduction step - ngr $h0,$h2 - srlg $t0,$h2,2 - algr $h0,$t0 - lghi $t1,3 - ngr $h2,$t1 - - algr $h0,$d0lo - alcgr $h1,$d1hi # $d1hi is still zero - alcgr $h2,$d1hi # $d1hi is still zero - - brct$g $len,.Loop - - l$g $ctx,`2*$SIZE_T`($sp) # restore $ctx - - stg $h0,0($ctx) # store hash value - stg $h1,8($ctx) - stg $h2,16($ctx) - - lm${g} %r6,%r14,`6*$SIZE_T`($sp) -.Lno_data: - br %r14 -.size poly1305_blocks,.-poly1305_blocks -___ +GLOBL ("poly1305_blocks"); +TYPE ("poly1305_blocks","\@function"); +ALIGN (16); +LABEL ("poly1305_blocks"); +LABEL (".Lpoly1305_blocks"); +&{$z? \<gr:\<r} ("%r0",$len); + jz (".Lno_data"); + +&{$z? \&stmg:\&stm} ("%r6","%r14","6*$SIZE_T($sp)"); + + lg ($h0,"0($ctx)"); # load hash value + lg ($h1,"8($ctx)"); + lg ($h2,"16($ctx)"); + +LABEL (".Lpoly1305_blocks_entry"); +if ($z) { + srlg ($len,$len,4); +} else { + srl ($len,4); +} + llgfr ($padbit,$padbit); # clear upper half, much needed with + # non-64-bit ABI + lg ($r0,"32($ctx)"); # load key + lg ($r1,"40($ctx)"); + +&{$z? \&stg:\&st} ($ctx,"2*$SIZE_T($sp)"); # off-load $ctx + srlg ($s1,$r1,2); + algr ($s1,$r1); # s1 = r1 + r1>>2 + j (".Loop"); + +ALIGN (16); +LABEL (".Loop"); + lrvg ($d0lo,"0($inp)"); # load little-endian input + lrvg ($d1lo,"8($inp)"); + la ($inp,"16($inp)"); + + algr ($d0lo,$h0); # accumulate input + alcgr ($d1lo,$h1); + alcgr ($h2,$padbit); + + lgr ($h0,$d0lo); + mlgr ($d0hi,$r0); # h0*r0 -> $d0hi:$d0lo + lgr ($h1,$d1lo); + mlgr ($d1hi,$s1); # h1*5*r1 -> $d1hi:$d1lo + + mlgr ($t0,$r1); # h0*r1 -> $t0:$h0 + mlgr ($t1,$r0); # h1*r0 -> $t1:$h1 + + algr ($d0lo,$d1lo); + lgr ($d1lo,$h2); + alcgr ($d0hi,$d1hi); + lghi ($d1hi,0); + + algr ($h1,$h0); + alcgr ($t1,$t0); + + msgr ($d1lo,$s1); # h2*s1 + msgr ($h2,$r0); # h2*r0 + + algr ($h1,$d1lo); + alcgr ($t1,$d1hi); # $d1hi is zero + + algr ($h1,$d0hi); + alcgr ($h2,$t1); + + lghi ($h0,-4); # final reduction step + ngr ($h0,$h2); + srlg ($t0,$h2,2); + algr ($h0,$t0); + lghi ($t1,3); + ngr ($h2,$t1); + + algr ($h0,$d0lo); + alcgr ($h1,$d1hi); # $d1hi is still zero + alcgr ($h2,$d1hi); # $d1hi is still zero + +&{$z? \&brctg:\&brct} ($len,".Loop"); + +&{$z? \&lg:\&l} ($ctx,"2*$SIZE_T($sp)");# restore $ctx + + stg ($h0,"0($ctx)"); # store hash value + stg ($h1,"8($ctx)"); + stg ($h2,"16($ctx)"); + +&{$z? \&lmg:\&lm} ("%r6","%r14","6*$SIZE_T($sp)"); +LABEL (".Lno_data"); + br ("%r14"); +SIZE ("poly1305_blocks",".-poly1305_blocks"); +} + +################ +# static void poly1305_blocks_vx(void *ctx, const unsigned char *inp, +# size_t len, u32 padbit) +{ +my ($H0, $H1, $H2, $H3, $H4) = map("%v$_",(0..4)); +my ($I0, $I1, $I2, $I3, $I4) = map("%v$_",(5..9)); +my ($R0, $R1, $S1, $R2, $S2) = map("%v$_",(10..14)); +my ($R3, $S3, $R4, $S4) = map("%v$_",(15..18)); +my ($ACC0, $ACC1, $ACC2, $ACC3, $ACC4) = map("%v$_",(19..23)); +my ($T1, $T2, $T3, $T4) = map("%v$_",(24..27)); +my ($mask26,$bswaplo,$bswaphi,$bswapmi) = map("%v$_",(28..31)); + +my ($d2,$d0,$h0,$d1,$h1,$h2)=map("%r$_",(9..14)); + +TYPE ("poly1305_blocks_vx","\@function"); +ALIGN (16); +LABEL ("poly1305_blocks_vx"); +LABEL (".Lpoly1305_blocks_vx"); +&{$z? \&clgfi:\&clfi} ($len,128); + jhe ("__poly1305_blocks_vx"); + +&{$z? \&stmg:\&stm} ("%r6","%r14","6*$SIZE_T($sp)"); + + lg ($d0,"0($ctx)"); + lg ($d1,"8($ctx)"); + lg ($d2,"16($ctx)"); + + llgfr ("%r0",$d0); # base 2^26 -> base 2^64 + srlg ($h0,$d0,32); + llgfr ("%r1",$d1); + srlg ($h1,$d1,32); + srlg ($h2,$d2,32); + + sllg ("%r0","%r0",26); + algr ($h0,"%r0"); + sllg ("%r0",$h1,52); + srlg ($h1,$h1,12); + sllg ("%r1","%r1",14); + algr ($h0,"%r0"); + alcgr ($h1,"%r1"); + sllg ("%r0",$h2,40); + srlg ($h2,$h2,24); + lghi ("%r1",0); + algr ($h1,"%r0"); + alcgr ($h2,"%r1"); + + llgf ("%r0","24($ctx)"); # is_base2_26 + lcgr ("%r0","%r0"); + + xgr ($h0,$d0); # choose between radixes + xgr ($h1,$d1); + xgr ($h2,$d2); + ngr ($h0,"%r0"); + ngr ($h1,"%r0"); + ngr ($h2,"%r0"); + xgr ($h0,$d0); + xgr ($h1,$d1); + xgr ($h2,$d2); + + lhi ("%r0",0); + st ("%r0","24($ctx)"); # clear is_base2_26 + + j (".Lpoly1305_blocks_entry"); +SIZE ("poly1305_blocks_vx",".-poly1305_blocks_vx"); + +TYPE ("__poly1305_mul","\@function"); +ALIGN (16); +LABEL ("__poly1305_mul"); + vmlof ($ACC0,$H0,$R0); + vmlof ($ACC1,$H0,$R1); + vmlof ($ACC2,$H0,$R2); + vmlof ($ACC3,$H0,$R3); + vmlof ($ACC4,$H0,$R4); + + vmalof ($ACC0,$H1,$S4,$ACC0); + vmalof ($ACC1,$H1,$R0,$ACC1); + vmalof ($ACC2,$H1,$R1,$ACC2); + vmalof ($ACC3,$H1,$R2,$ACC3); + vmalof ($ACC4,$H1,$R3,$ACC4); + + vmalof ($ACC0,$H2,$S3,$ACC0); + vmalof ($ACC1,$H2,$S4,$ACC1); + vmalof ($ACC2,$H2,$R0,$ACC2); + vmalof ($ACC3,$H2,$R1,$ACC3); + vmalof ($ACC4,$H2,$R2,$ACC4); + + vmalof ($ACC0,$H3,$S2,$ACC0); + vmalof ($ACC1,$H3,$S3,$ACC1); + vmalof ($ACC2,$H3,$S4,$ACC2); + vmalof ($ACC3,$H3,$R0,$ACC3); + vmalof ($ACC4,$H3,$R1,$ACC4); + + vmalof ($ACC0,$H4,$S1,$ACC0); + vmalof ($ACC1,$H4,$S2,$ACC1); + vmalof ($ACC2,$H4,$S3,$ACC2); + vmalof ($ACC3,$H4,$S4,$ACC3); + vmalof ($ACC4,$H4,$R0,$ACC4); + + ################################################################ + # lazy reduction + + vesrlg ($H4,$ACC3,26); + vesrlg ($H1,$ACC0,26); + vn ($H3,$ACC3,$mask26); + vn ($H0,$ACC0,$mask26); + vag ($H4,$H4,$ACC4); # h3 -> h4 + vag ($H1,$H1,$ACC1); # h0 -> h1 + + vesrlg ($ACC4,$H4,26); + vesrlg ($ACC1,$H1,26); + vn ($H4,$H4,$mask26); + vn ($H1,$H1,$mask26); + vag ($H0,$H0,$ACC4); + vag ($H2,$ACC2,$ACC1); # h1 -> h2 + + veslg ($ACC4,$ACC4,2); # <<2 + vesrlg ($ACC2,$H2,26); + vn ($H2,$H2,$mask26); + vag ($H0,$H0,$ACC4); # h4 -> h0 + vag ($H3,$H3,$ACC2); # h2 -> h3 + + vesrlg ($ACC0,$H0,26); + vesrlg ($ACC3,$H3,26); + vn ($H0,$H0,$mask26); + vn ($H3,$H3,$mask26); + vag ($H1,$H1,$ACC0); # h0 -> h1 + vag ($H4,$H4,$ACC3); # h3 -> h4 + br ("%r14"); +SIZE ("__poly1305_mul",".-__poly1305_mul"); + +TYPE ("__poly1305_blocks_vx","\@function"); +ALIGN (16); +LABEL ("__poly1305_blocks_vx"); +&{$z? \&lgr:\&lr} ("%r0",$sp); +&{$z? \&stmg:\&stm} ("%r10","%r15","10*$SIZE_T($sp)"); +if (!$z) { + std ("%f4","16*$SIZE_T+2*8($sp)"); + std ("%f6","16*$SIZE_T+3*8($sp)"); + ahi ($sp,-$stdframe); + st ("%r0","0($sp)"); # back-chain + + llgfr ($len,$len); # so that srlg works on $len +} else { + aghi ($sp,"-($stdframe+8*8)"); + stg ("%r0","0($sp)"); # back-chain + + std ("%f8","$stdframe+0*8($sp)"); + std ("%f9","$stdframe+1*8($sp)"); + std ("%f10","$stdframe+2*8($sp)"); + std ("%f11","$stdframe+3*8($sp)"); + std ("%f12","$stdframe+4*8($sp)"); + std ("%f13","$stdframe+5*8($sp)"); + std ("%f14","$stdframe+6*8($sp)"); + std ("%f15","$stdframe+7*8($sp)"); +} + larl ("%r1",".Lconst"); + vgmg ($mask26,38,63); + vlm ($bswaplo,$bswapmi,"16(%r1)"); + + < ("%r0","24($ctx)"); # is_base2_26? + jnz (".Lskip_init"); + + lg ($h0,"32($ctx)"); # load key base 2^64 + lg ($h1,"40($ctx)"); + + risbg ($d0,$h0,38,0x80+63,38); # base 2^64 -> 2^26 + srlg ($d1,$h0,52); + risbg ($h0,$h0,38,0x80+63,0); + vlvgg ($R0,$h0,0); + risbg ($d1,$h1,38,51,12); + vlvgg ($R1,$d0,0); + risbg ($d0,$h1,38,63,50); + vlvgg ($R2,$d1,0); + srlg ($d1,$h1,40); + vlvgg ($R3,$d0,0); + vlvgg ($R4,$d1,0); + + veslg ($S1,$R1,2); + veslg ($S2,$R2,2); + veslg ($S3,$R3,2); + veslg ($S4,$R4,2); + vlr ($H0,$R0); + vlr ($H1,$R1); + vlr ($H2,$R2); + vlr ($H3,$R3); + vlr ($H4,$R4); + vag ($S1,$S1,$R1); # * 5 + vag ($S2,$S2,$R2); + vag ($S3,$S3,$R3); + vag ($S4,$S4,$R4); + + brasl ("%r14","__poly1305_mul"); # r^1:- * r^1:- + + vpdi ($R0,$H0,$R0,0); # r^2:r^1 + vpdi ($R1,$H1,$R1,0); + vpdi ($R2,$H2,$R2,0); + vpdi ($R3,$H3,$R3,0); + vpdi ($R4,$H4,$R4,0); + vpdi ($H0,$H0,$H0,0); # r^2:r^2 + vpdi ($H1,$H1,$H1,0); + vpdi ($H2,$H2,$H2,0); + vpdi ($H3,$H3,$H3,0); + vpdi ($H4,$H4,$H4,0); + veslg ($S1,$R1,2); + veslg ($S2,$R2,2); + veslg ($S3,$R3,2); + veslg ($S4,$R4,2); + vag ($S1,$S1,$R1); # * 5 + vag ($S2,$S2,$R2); + vag ($S3,$S3,$R3); + vag ($S4,$S4,$R4); + + brasl ("%r14,__poly1305_mul"); # r^2:r^2 * r^2:r^1 + + vl ($I0,"0(%r1)"); # borrow $I0 + vperm ($R0,$R0,$H0,$I0); # r^2:r^4:r^1:r^3 + vperm ($R1,$R1,$H1,$I0); + vperm ($R2,$R2,$H2,$I0); + vperm ($R3,$R3,$H3,$I0); + vperm ($R4,$R4,$H4,$I0); + veslf ($S1,$R1,2); + veslf ($S2,$R2,2); + veslf ($S3,$R3,2); + veslf ($S4,$R4,2); + vaf ($S1,$S1,$R1); # * 5 + vaf ($S2,$S2,$R2); + vaf ($S3,$S3,$R3); + vaf ($S4,$S4,$R4); + + lg ($h0,"0($ctx)"); # load hash base 2^64 + lg ($h1,"8($ctx)"); + lg ($h2,"16($ctx)"); + + vzero ($H0); + vzero ($H1); + vzero ($H2); + vzero ($H3); + vzero ($H4); + + risbg ($d0,$h0,38,0x80+63,38); # base 2^64 -> 2^26 + srlg ($d1,$h0,52); + risbg ($h0,$h0,38,0x80+63,0); + vlvgg ($H0,$h0,0); + risbg ($d1,$h1,38,51,12); + vlvgg ($H1,$d0,0); + risbg ($d0,$h1,38,63,50); + vlvgg ($H2,$d1,0); + srlg ($d1,$h1,40); + vlvgg ($H3,$d0,0); + risbg ($d1,$h2,37,39,24); + vlvgg ($H4,$d1,0); + + lhi ("%r0",1); + st ("%r0","24($ctx)"); # set is_base2_26 + + vstm ($R0,$S4,"48($ctx)"); # save key schedule base 2^26 + + vpdi ($R0,$R0,$R0,0); # broadcast r^2:r^4 + vpdi ($R1,$R1,$R1,0); + vpdi ($S1,$S1,$S1,0); + vpdi ($R2,$R2,$R2,0); + vpdi ($S2,$S2,$S2,0); + vpdi ($R3,$R3,$R3,0); + vpdi ($S3,$S3,$S3,0); + vpdi ($R4,$R4,$R4,0); + vpdi ($S4,$S4,$S4,0); + + j (".Loaded_hash"); + +ALIGN (16); +LABEL (".Lskip_init"); + vllezf ($H0,"0($ctx)"); # load hash base 2^26 + vllezf ($H1,"4($ctx)"); + vllezf ($H2,"8($ctx)"); + vllezf ($H3,"12($ctx)"); + vllezf ($H4,"16($ctx)"); + + vlrepg ($R0,"0x30($ctx)"); # broadcast r^2:r^4 + vlrepg ($R1,"0x40($ctx)"); + vlrepg ($S1,"0x50($ctx)"); + vlrepg ($R2,"0x60($ctx)"); + vlrepg ($S2,"0x70($ctx)"); + vlrepg ($R3,"0x80($ctx)"); + vlrepg ($S3,"0x90($ctx)"); + vlrepg ($R4,"0xa0($ctx)"); + vlrepg ($S4,"0xb0($ctx)"); + +LABEL (".Loaded_hash"); + vzero ($I1); + vzero ($I3); + + vlm ($T1,$T4,"0x00($inp)"); # load first input block + la ($inp,"0x40($inp)"); + vgmg ($mask26,6,31); + vgmf ($I4,5,5); # padbit<<2 + + vperm ($I0,$T3,$T4,$bswaplo); + vperm ($I2,$T3,$T4,$bswapmi); + vperm ($T3,$T3,$T4,$bswaphi); + + verimg ($I1,$I0,$mask26,6); # >>26 + veslg ($I0,$I0,32); + veslg ($I2,$I2,28); # >>4 + verimg ($I3,$T3,$mask26,18); # >>14 + verimg ($I4,$T3,$mask26,58); # >>38 + vn ($I0,$I0,$mask26); + vn ($I2,$I2,$mask26); + vesrlf ($I4,$I4,2); # >>2 + + vgmg ($mask26,38,63); + vperm ($T3,$T1,$T2,$bswaplo); + vperm ($T4,$T1,$T2,$bswaphi); + vperm ($T2,$T1,$T2,$bswapmi); + + verimg ($I0,$T3,$mask26,0); + verimg ($I1,$T3,$mask26,38); # >>26 + verimg ($I2,$T2,$mask26,60); # >>4 + verimg ($I3,$T4,$mask26,50); # >>14 + vesrlg ($T4,$T4,40); + vo ($I4,$I4,$T4); + + srlg ("%r0",$len,6); +&{$z? \&aghi:\&ahi} ("%r0",-1); + +ALIGN (16); +LABEL (".Loop_vx"); + vmlef ($ACC0,$I0,$R0); + vmlef ($ACC1,$I0,$R1); + vmlef ($ACC2,$I0,$R2); + vmlef ($ACC3,$I0,$R3); + vmlef ($ACC4,$I0,$R4); + + vmalef ($ACC0,$I1,$S4,$ACC0); + vmalef ($ACC1,$I1,$R0,$ACC1); + vmalef ($ACC2,$I1,$R1,$ACC2); + vmalef ($ACC3,$I1,$R2,$ACC3); + vmalef ($ACC4,$I1,$R3,$ACC4); + + vaf ($H2,$H2,$I2); + vaf ($H0,$H0,$I0); + vaf ($H3,$H3,$I3); + vaf ($H1,$H1,$I1); + vaf ($H4,$H4,$I4); + + vmalef ($ACC0,$I2,$S3,$ACC0); + vmalef ($ACC1,$I2,$S4,$ACC1); + vmalef ($ACC2,$I2,$R0,$ACC2); + vmalef ($ACC3,$I2,$R1,$ACC3); + vmalef ($ACC4,$I2,$R2,$ACC4); + + vlm ($T1,$T4,"0x00($inp)"); # load next input block + la ($inp,"0x40($inp)"); + vgmg ($mask26,6,31); + + vmalef ($ACC0,$I3,$S2,$ACC0); + vmalef ($ACC1,$I3,$S3,$ACC1); + vmalef ($ACC2,$I3,$S4,$ACC2); + vmalef ($ACC3,$I3,$R0,$ACC3); + vmalef ($ACC4,$I3,$R1,$ACC4); + + vperm ($I0,$T3,$T4,$bswaplo); + vperm ($I2,$T3,$T4,$bswapmi); + vperm ($T3,$T3,$T4,$bswaphi); + + vmalef ($ACC0,$I4,$S1,$ACC0); + vmalef ($ACC1,$I4,$S2,$ACC1); + vmalef ($ACC2,$I4,$S3,$ACC2); + vmalef ($ACC3,$I4,$S4,$ACC3); + vmalef ($ACC4,$I4,$R0,$ACC4); + + verimg ($I1,$I0,$mask26,6); # >>26 + veslg ($I0,$I0,32); + veslg ($I2,$I2,28); # >>4 + verimg ($I3,$T3,$mask26,18); # >>14 + + vmalof ($ACC0,$H0,$R0,$ACC0); + vmalof ($ACC1,$H0,$R1,$ACC1); + vmalof ($ACC2,$H0,$R2,$ACC2); + vmalof ($ACC3,$H0,$R3,$ACC3); + vmalof ($ACC4,$H0,$R4,$ACC4); + + vgmf ($I4,5,5); # padbit<<2 + verimg ($I4,$T3,$mask26,58); # >>38 + vn ($I0,$I0,$mask26); + vn ($I2,$I2,$mask26); + vesrlf ($I4,$I4,2); # >>2 + + vmalof ($ACC0,$H1,$S4,$ACC0); + vmalof ($ACC1,$H1,$R0,$ACC1); + vmalof ($ACC2,$H1,$R1,$ACC2); + vmalof ($ACC3,$H1,$R2,$ACC3); + vmalof ($ACC4,$H1,$R3,$ACC4); + + vgmg ($mask26,38,63); + vperm ($T3,$T1,$T2,$bswaplo); + vperm ($T4,$T1,$T2,$bswaphi); + vperm ($T2,$T1,$T2,$bswapmi); + + vmalof ($ACC0,$H2,$S3,$ACC0); + vmalof ($ACC1,$H2,$S4,$ACC1); + vmalof ($ACC2,$H2,$R0,$ACC2); + vmalof ($ACC3,$H2,$R1,$ACC3); + vmalof ($ACC4,$H2,$R2,$ACC4); + + verimg ($I0,$T3,$mask26,0); + verimg ($I1,$T3,$mask26,38); # >>26 + verimg ($I2,$T2,$mask26,60); # >>4 + + vmalof ($ACC0,$H3,$S2,$ACC0); + vmalof ($ACC1,$H3,$S3,$ACC1); + vmalof ($ACC2,$H3,$S4,$ACC2); + vmalof ($ACC3,$H3,$R0,$ACC3); + vmalof ($ACC4,$H3,$R1,$ACC4); + + verimg ($I3,$T4,$mask26,50); # >>14 + vesrlg ($T4,$T4,40); + vo ($I4,$I4,$T4); + + vmalof ($ACC0,$H4,$S1,$ACC0); + vmalof ($ACC1,$H4,$S2,$ACC1); + vmalof ($ACC2,$H4,$S3,$ACC2); + vmalof ($ACC3,$H4,$S4,$ACC3); + vmalof ($ACC4,$H4,$R0,$ACC4); + + ################################################################ + # lazy reduction as discussed in "NEON crypto" by D.J. Bernstein + # and P. Schwabe + + vesrlg ($H4,$ACC3,26); + vesrlg ($H1,$ACC0,26); + vn ($H3,$ACC3,$mask26); + vn ($H0,$ACC0,$mask26); + vag ($H4,$H4,$ACC4); # h3 -> h4 + vag ($H1,$H1,$ACC1); # h0 -> h1 + + vesrlg ($ACC4,$H4,26); + vesrlg ($ACC1,$H1,26); + vn ($H4,$H4,$mask26); + vn ($H1,$H1,$mask26); + vag ($H0,$H0,$ACC4); + vag ($H2,$ACC2,$ACC1); # h1 -> h2 + + veslg ($ACC4,$ACC4,2); # <<2 + vesrlg ($ACC2,$H2,26); + vn ($H2,$H2,$mask26); + vag ($H0,$H0,$ACC4); # h4 -> h0 + vag ($H3,$H3,$ACC2); # h2 -> h3 + + vesrlg ($ACC0,$H0,26); + vesrlg ($ACC3,$H3,26); + vn ($H0,$H0,$mask26); + vn ($H3,$H3,$mask26); + vag ($H1,$H1,$ACC0); # h0 -> h1 + vag ($H4,$H4,$ACC3); # h3 -> h4 + +&{$z? \&brctg:\&brct} ("%r0",".Loop_vx"); + + vlm ($R0,$S4,"48($ctx)"); # load all powers + + lghi ("%r0",0x30); +&{$z? \&lcgr:\&lcr} ($len,$len); +&{$z? \&ngr:\&nr} ($len,"%r0"); +&{$z? \&slgr:\&slr} ($inp,$len); + +LABEL (".Last"); + vmlef ($ACC0,$I0,$R0); + vmlef ($ACC1,$I0,$R1); + vmlef ($ACC2,$I0,$R2); + vmlef ($ACC3,$I0,$R3); + vmlef ($ACC4,$I0,$R4); + + vmalef ($ACC0,$I1,$S4,$ACC0); + vmalef ($ACC1,$I1,$R0,$ACC1); + vmalef ($ACC2,$I1,$R1,$ACC2); + vmalef ($ACC3,$I1,$R2,$ACC3); + vmalef ($ACC4,$I1,$R3,$ACC4); + + vaf ($H0,$H0,$I0); + vaf ($H1,$H1,$I1); + vaf ($H2,$H2,$I2); + vaf ($H3,$H3,$I3); + vaf ($H4,$H4,$I4); + + vmalef ($ACC0,$I2,$S3,$ACC0); + vmalef ($ACC1,$I2,$S4,$ACC1); + vmalef ($ACC2,$I2,$R0,$ACC2); + vmalef ($ACC3,$I2,$R1,$ACC3); + vmalef ($ACC4,$I2,$R2,$ACC4); + + vmalef ($ACC0,$I3,$S2,$ACC0); + vmalef ($ACC1,$I3,$S3,$ACC1); + vmalef ($ACC2,$I3,$S4,$ACC2); + vmalef ($ACC3,$I3,$R0,$ACC3); + vmalef ($ACC4,$I3,$R1,$ACC4); + + vmalef ($ACC0,$I4,$S1,$ACC0); + vmalef ($ACC1,$I4,$S2,$ACC1); + vmalef ($ACC2,$I4,$S3,$ACC2); + vmalef ($ACC3,$I4,$S4,$ACC3); + vmalef ($ACC4,$I4,$R0,$ACC4); + + vmalof ($ACC0,$H0,$R0,$ACC0); + vmalof ($ACC1,$H0,$R1,$ACC1); + vmalof ($ACC2,$H0,$R2,$ACC2); + vmalof ($ACC3,$H0,$R3,$ACC3); + vmalof ($ACC4,$H0,$R4,$ACC4); + + vmalof ($ACC0,$H1,$S4,$ACC0); + vmalof ($ACC1,$H1,$R0,$ACC1); + vmalof ($ACC2,$H1,$R1,$ACC2); + vmalof ($ACC3,$H1,$R2,$ACC3); + vmalof ($ACC4,$H1,$R3,$ACC4); + + vmalof ($ACC0,$H2,$S3,$ACC0); + vmalof ($ACC1,$H2,$S4,$ACC1); + vmalof ($ACC2,$H2,$R0,$ACC2); + vmalof ($ACC3,$H2,$R1,$ACC3); + vmalof ($ACC4,$H2,$R2,$ACC4); + + vmalof ($ACC0,$H3,$S2,$ACC0); + vmalof ($ACC1,$H3,$S3,$ACC1); + vmalof ($ACC2,$H3,$S4,$ACC2); + vmalof ($ACC3,$H3,$R0,$ACC3); + vmalof ($ACC4,$H3,$R1,$ACC4); + + vmalof ($ACC0,$H4,$S1,$ACC0); + vmalof ($ACC1,$H4,$S2,$ACC1); + vmalof ($ACC2,$H4,$S3,$ACC2); + vmalof ($ACC3,$H4,$S4,$ACC3); + vmalof ($ACC4,$H4,$R0,$ACC4); + + ################################################################ + # horizontal addition + + vzero ($H0); + vsumqg ($ACC0,$ACC0,$H0); + vsumqg ($ACC1,$ACC1,$H0); + vsumqg ($ACC2,$ACC2,$H0); + vsumqg ($ACC3,$ACC3,$H0); + vsumqg ($ACC4,$ACC4,$H0); + + ################################################################ + # lazy reduction + + vesrlg ($H4,$ACC3,26); + vesrlg ($H1,$ACC0,26); + vn ($H3,$ACC3,$mask26); + vn ($H0,$ACC0,$mask26); + vag ($H4,$H4,$ACC4); # h3 -> h4 + vag ($H1,$H1,$ACC1); # h0 -> h1 + + vesrlg ($ACC4,$H4,26); + vesrlg ($ACC1,$H1,26); + vn ($H4,$H4,$mask26); + vn ($H1,$H1,$mask26); + vag ($H0,$H0,$ACC4); + vag ($H2,$ACC2,$ACC1); # h1 -> h2 + + veslg ($ACC4,$ACC4,2); # <<2 + vesrlg ($ACC2,$H2,26); + vn ($H2,$H2,$mask26); + vag ($H0,$H0,$ACC4); # h4 -> h0 + vag ($H3,$H3,$ACC2); # h2 -> h3 + + vesrlg ($ACC0,$H0,26); + vesrlg ($ACC3,$H3,26); + vn ($H0,$H0,$mask26); + vn ($H3,$H3,$mask26); + vag ($H1,$H1,$ACC0); # h0 -> h1 + vag ($H4,$H4,$ACC3); # h3 -> h4 + +&{$z? \&clgfi:\&clfi} ($len,0); + je (".Ldone"); + + vlm ($T1,$T4,"0x00($inp)"); # load last partial block + vgmg ($mask26,6,31); + vgmf ($I4,5,5); # padbit<<2 + + vperm ($I0,$T3,$T4,$bswaplo); + vperm ($I2,$T3,$T4,$bswapmi); + vperm ($T3,$T3,$T4,$bswaphi); + + vl ($ACC0,"0x30($len,%r1)"); # borrow $ACC0,1 + vl ($ACC1,"0x60($len,%r1)"); + + verimg ($I1,$I0,$mask26,6); # >>26 + veslg ($I0,$I0,32); + veslg ($I2,$I2,28); # >>4 + verimg ($I3,$T3,$mask26,18); # >>14 + verimg ($I4,$T3,$mask26,58); # >>38 + vn ($I0,$I0,$mask26); + vn ($I2,$I2,$mask26); + vesrlf ($I4,$I4,2); # >>2 + + vgmg ($mask26,38,63); + vperm ($T3,$T1,$T2,$bswaplo); + vperm ($T4,$T1,$T2,$bswaphi); + vperm ($T2,$T1,$T2,$bswapmi); + + verimg ($I0,$T3,$mask26,0); + verimg ($I1,$T3,$mask26,38); # >>26 + verimg ($I2,$T2,$mask26,60); # >>4 + verimg ($I3,$T4,$mask26,50); # >>14 + vesrlg ($T4,$T4,40); + vo ($I4,$I4,$T4); + + vperm ($H0,$H0,$H0,$ACC0); # move hash to right lane + vn ($I0,$I0,$ACC1); # mask redundant lane[s] + vperm ($H1,$H1,$H1,$ACC0); + vn ($I1,$I1,$ACC1); + vperm ($H2,$H2,$H2,$ACC0); + vn ($I2,$I2,$ACC1); + vperm ($H3,$H3,$H3,$ACC0); + vn ($I3,$I3,$ACC1); + vperm ($H4,$H4,$H4,$ACC0); + vn ($I4,$I4,$ACC1); + + vaf ($I0,$I0,$H0); # accumulate hash + vzero ($H0); # wipe hash value + vaf ($I1,$I1,$H1); + vzero ($H1); + vaf ($I2,$I2,$H2); + vzero ($H2); + vaf ($I3,$I3,$H3); + vzero ($H3); + vaf ($I4,$I4,$H4); + vzero ($H4); + +&{$z? \&lghi:\&lhi} ($len,0); + j (".Last"); + # I don't bother to tell apart cases when only one multiplication + # pass is sufficient, because I argue that mispredicted branch + # penalties are comparable to overhead of sometimes redundant + # multiplication pass... + +LABEL (".Ldone"); + vstef ($H0,"0($ctx)",3); # store hash base 2^26 + vstef ($H1,"4($ctx)",3); + vstef ($H2,"8($ctx)",3); + vstef ($H3,"12($ctx)",3); + vstef ($H4,"16($ctx)",3); + +if ($z) { + ld ("%f8","$stdframe+0*8($sp)"); + ld ("%f9","$stdframe+1*8($sp)"); + ld ("%f10","$stdframe+2*8($sp)"); + ld ("%f11","$stdframe+3*8($sp)"); + ld ("%f12","$stdframe+4*8($sp)"); + ld ("%f13","$stdframe+5*8($sp)"); + ld ("%f14","$stdframe+6*8($sp)"); + ld ("%f15","$stdframe+7*8($sp)"); +&{$z? \&lmg:\&lm} ("%r10","%r15","$stdframe+8*8+10*$SIZE_T($sp)"); +} else { + ld ("%f4","$stdframe+16*$SIZE_T+2*8($sp)"); + ld ("%f6","$stdframe+16*$SIZE_T+3*8($sp)"); +&{$z? \&lmg:\&lm} ("%r10","%r15","$stdframe+10*$SIZE_T($sp)"); +} + br ("%r14"); +SIZE ("__poly1305_blocks_vx",".-__poly1305_blocks_vx"); } + +################ +# static void poly1305_emit(void *ctx, unsigned char mac[16], +# const u32 nonce[4]) { my ($mac,$nonce)=($inp,$len); -my ($h0,$h1,$h2,$d0,$d1)=map("%r$_",(5..9)); - -$code.=<<___; -.globl poly1305_emit -.type poly1305_emit,\@function -.align 16 -poly1305_emit: - stm${g} %r6,%r9,`6*$SIZE_T`($sp) - - lg $h0,0($ctx) - lg $h1,8($ctx) - lg $h2,16($ctx) - - lghi %r0,5 - lghi %r1,0 - lgr $d0,$h0 - lgr $d1,$h1 - - algr $h0,%r0 # compare to modulus - alcgr $h1,%r1 - alcgr $h2,%r1 - - srlg $h2,$h2,2 # did it borrow/carry? - slgr %r1,$h2 # 0-$h2>>2 - lg $h2,0($nonce) # load nonce - lghi %r0,-1 - lg $ctx,8($nonce) - xgr %r0,%r1 # ~%r1 - - ngr $h0,%r1 - ngr $d0,%r0 - ngr $h1,%r1 - ngr $d1,%r0 - ogr $h0,$d0 - rllg $d0,$h2,32 # flip nonce words - ogr $h1,$d1 - rllg $d1,$ctx,32 - - algr $h0,$d0 # accumulate nonce - alcgr $h1,$d1 - - strvg $h0,0($mac) # write little-endian result - strvg $h1,8($mac) - - lm${g} %r6,%r9,`6*$SIZE_T`($sp) - br %r14 -.size poly1305_emit,.-poly1305_emit - -.string "Poly1305 for s390x, CRYPTOGAMS by " -___ +my ($h0,$h1,$h2,$d0,$d1,$d2)=map("%r$_",(5..10)); + +GLOBL ("poly1305_emit"); +TYPE ("poly1305_emit","\@function"); +ALIGN (16); +LABEL ("poly1305_emit"); +LABEL (".Lpoly1305_emit"); +&{$z? \&stmg:\&stm} ("%r6","%r10","6*$SIZE_T($sp)"); + + lg ($d0,"0($ctx)"); + lg ($d1,"8($ctx)"); + lg ($d2,"16($ctx)"); + + llgfr ("%r0",$d0); # base 2^26 -> base 2^64 + srlg ($h0,$d0,32); + llgfr ("%r1",$d1); + srlg ($h1,$d1,32); + srlg ($h2,$d2,32); + + sllg ("%r0","%r0",26); + algr ($h0,"%r0"); + sllg ("%r0",$h1,52); + srlg ($h1,$h1,12); + sllg ("%r1","%r1",14); + algr ($h0,"%r0"); + alcgr ($h1,"%r1"); + sllg ("%r0",$h2,40); + srlg ($h2,$h2,24); + lghi ("%r1",0); + algr ($h1,"%r0"); + alcgr ($h2,"%r1"); + + llgf ("%r0","24($ctx)"); # is_base2_26 + lcgr ("%r0","%r0"); + + xgr ($h0,$d0); # choose between radixes + xgr ($h1,$d1); + xgr ($h2,$d2); + ngr ($h0,"%r0"); + ngr ($h1,"%r0"); + ngr ($h2,"%r0"); + xgr ($h0,$d0); + xgr ($h1,$d1); + xgr ($h2,$d2); + + lghi ("%r0",5); + lgr ($d0,$h0); + lgr ($d1,$h1); + + algr ($h0,"%r0"); # compare to modulus + alcgr ($h1,"%r1"); + alcgr ($h2,"%r1"); + + srlg ($h2,$h2,2); # did it borrow/carry? + slgr ("%r1",$h2); # 0-$h2>>2 + lg ($d2,"0($nonce)"); # load nonce + lg ($ctx,"8($nonce)"); + + xgr ($h0,$d0); + xgr ($h1,$d1); + ngr ($h0,"%r1"); + ngr ($h1,"%r1"); + xgr ($h0,$d0); + rllg ($d0,$d2,32); # flip nonce words + xgr ($h1,$d1); + rllg ($d1,$ctx,32); + + algr ($h0,$d0); # accumulate nonce + alcgr ($h1,$d1); + + strvg ($h0,"0($mac)"); # write little-endian result + strvg ($h1,"8($mac)"); + +&{$z? \&lmg:\&lm} ("%r6","%r10","6*$SIZE_T($sp)"); + br ("%r14"); +SIZE ("poly1305_emit",".-poly1305_emit"); } -$code =~ s/\`([^\`]*)\`/eval $1/gem; -$code =~ s/\b(srlg\s+)(%r[0-9]+\s*,)\s*([0-9]+)/$1$2$2$3/gm; +################ + +ALIGN (16); +LABEL (".Lconst"); +LONG (0x04050607,0x14151617,0x0c0d0e0f,0x1c1d1e1f); # merge odd +LONG (0x07060504,0x03020100,0x17161514,0x13121110); # byte swap masks +LONG (0x0f0e0d0c,0x0b0a0908,0x1f1e1d1c,0x1b1a1918); +LONG (0x00000000,0x09080706,0x00000000,0x19181716); + +LONG (0x00000000,0x00000000,0x00000000,0x0c0d0e0f); # magic tail masks +LONG (0x0c0d0e0f,0x00000000,0x00000000,0x00000000); +LONG (0x00000000,0x00000000,0x0c0d0e0f,0x00000000); + +LONG (0xffffffff,0x00000000,0xffffffff,0xffffffff); +LONG (0xffffffff,0x00000000,0xffffffff,0x00000000); +LONG (0x00000000,0x00000000,0xffffffff,0x00000000); + +STRING ("\"Poly1305 for s390x, CRYPTOGAMS by \""); -print $code; -close STDOUT or die "error closing STDOUT: $!"; +PERLASM_END(); diff --git a/crypto/openssl/crypto/poly1305/asm/poly1305-sparcv9.pl b/crypto/openssl/crypto/poly1305/asm/poly1305-sparcv9.pl index 997e0d8344c6..dc592a07acac 100755 --- a/crypto/openssl/crypto/poly1305/asm/poly1305-sparcv9.pl +++ b/crypto/openssl/crypto/poly1305/asm/poly1305-sparcv9.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -41,19 +41,21 @@ # (***) Multi-process benchmark saturates at ~12.5x single-process # result on 8-core processor, or ~21GBps per 2.85GHz socket. -my $output = pop; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; + +open STDOUT,">$output" if $output; my ($ctx,$inp,$len,$padbit,$shl,$shr) = map("%i$_",(0..5)); my ($r0,$r1,$r2,$r3,$s1,$s2,$s3,$h4) = map("%l$_",(0..7)); my ($h0,$h1,$h2,$h3, $t0,$t1,$t2) = map("%o$_",(0..5,7)); my ($d0,$d1,$d2,$d3) = map("%g$_",(1..4)); -my $output = pop; -open STDOUT,">$stdout"; - $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #ifdef __arch64__ .register %g2,#scratch diff --git a/crypto/openssl/crypto/poly1305/asm/poly1305-x86.pl b/crypto/openssl/crypto/poly1305/asm/poly1305-x86.pl index 2ae16a230b66..c91d01fb3ba4 100755 --- a/crypto/openssl/crypto/poly1305/asm/poly1305-x86.pl +++ b/crypto/openssl/crypto/poly1305/asm/poly1305-x86.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -47,8 +47,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/poly1305/asm/poly1305-x86_64.pl b/crypto/openssl/crypto/poly1305/asm/poly1305-x86_64.pl index 5f834d8faf2a..fa9bfb7a7b81 100755 --- a/crypto/openssl/crypto/poly1305/asm/poly1305-x86_64.pl +++ b/crypto/openssl/crypto/poly1305/asm/poly1305-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -63,9 +63,10 @@ # (***) strangely enough performance seems to vary from core to core, # listed result is best case; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -94,7 +95,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0 $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my ($ctx,$inp,$len,$padbit)=("%rdi","%rsi","%rdx","%rcx"); @@ -2806,6 +2808,7 @@ $code.=<<___; .align 32 poly1305_blocks_vpmadd52: .cfi_startproc + endbranch shr \$4,$len jz .Lno_data_vpmadd52 # too short @@ -3739,6 +3742,7 @@ $code.=<<___; .align 32 poly1305_emit_base2_44: .cfi_startproc + endbranch mov 0($ctx),%r8 # load hash value mov 8($ctx),%r9 mov 16($ctx),%r10 diff --git a/crypto/openssl/crypto/poly1305/build.info b/crypto/openssl/crypto/poly1305/build.info index 4e4dcca521f6..e359a2225df5 100644 --- a/crypto/openssl/crypto/poly1305/build.info +++ b/crypto/openssl/crypto/poly1305/build.info @@ -1,25 +1,53 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - poly1305_pmeth.c \ - poly1305_ameth.c \ - poly1305.c {- $target{poly1305_asm_src} -} -GENERATE[poly1305-sparcv9.S]=asm/poly1305-sparcv9.pl $(PERLASM_SCHEME) +$POLY1305ASM= +IF[{- !$disabled{asm} -}] + $POLY1305ASM_x86=poly1305-x86.S + $POLY1305ASM_x86_64=poly1305-x86_64.s + + $POLY1305ASM_ia64=poly1305-ia64.s + + $POLY1305ASM_sparcv9=poly1305-sparcv9.S + + $POLY1305ASM_mips64=poly1305-mips.S + + $POLY1305ASM_s390x=poly1305-s390x.S + + $POLY1305ASM_armv4=poly1305-armv4.S + $POLY1305ASM_aarch64=poly1305-armv8.S + + $POLY1305ASM_ppc32=poly1305_ppc.c poly1305-ppc.s poly1305-ppcfp.s + $POLY1305ASM_ppc64=$POLY1305ASM_ppc32 + + $POLY1305ASM_c64xplus=poly1305-c64xplus.s + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$POLY1305ASM_{- $target{asm_arch} -}] + $POLY1305ASM=$POLY1305ASM_{- $target{asm_arch} -} + $POLY1305DEF=POLY1305_ASM + ENDIF +ENDIF + +SOURCE[../../libcrypto]=poly1305.c $POLY1305ASM + +# Implementations are now spread across several libraries, so the defines +# need to be applied to all affected libraries and modules. +DEFINE[../../libcrypto]=$POLY1305DEF + +GENERATE[poly1305-sparcv9.S]=asm/poly1305-sparcv9.pl INCLUDE[poly1305-sparcv9.o]=.. -GENERATE[poly1305-x86.s]=asm/poly1305-x86.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -GENERATE[poly1305-x86_64.s]=asm/poly1305-x86_64.pl $(PERLASM_SCHEME) -GENERATE[poly1305-ppc.s]=asm/poly1305-ppc.pl $(PERLASM_SCHEME) -GENERATE[poly1305-ppcfp.s]=asm/poly1305-ppcfp.pl $(PERLASM_SCHEME) -GENERATE[poly1305-armv4.S]=asm/poly1305-armv4.pl $(PERLASM_SCHEME) +GENERATE[poly1305-x86.S]=asm/poly1305-x86.pl +GENERATE[poly1305-x86_64.s]=asm/poly1305-x86_64.pl +GENERATE[poly1305-ia64.s]=asm/poly1305-ia64.S +GENERATE[poly1305-ppc.s]=asm/poly1305-ppc.pl +GENERATE[poly1305-ppcfp.s]=asm/poly1305-ppcfp.pl +GENERATE[poly1305-armv4.S]=asm/poly1305-armv4.pl INCLUDE[poly1305-armv4.o]=.. -GENERATE[poly1305-armv8.S]=asm/poly1305-armv8.pl $(PERLASM_SCHEME) +GENERATE[poly1305-armv8.S]=asm/poly1305-armv8.pl INCLUDE[poly1305-armv8.o]=.. -GENERATE[poly1305-mips.S]=asm/poly1305-mips.pl $(PERLASM_SCHEME) +GENERATE[poly1305-mips.S]=asm/poly1305-mips.pl INCLUDE[poly1305-mips.o]=.. -GENERATE[poly1305-s390x.S]=asm/poly1305-s390x.pl $(PERLASM_SCHEME) - -BEGINRAW[Makefile(unix)] -{- $builddir -}/poly1305-%.S: {- $sourcedir -}/asm/poly1305-%.pl - CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ -ENDRAW[Makefile(unix)] +GENERATE[poly1305-c64xplus.S]=asm/poly1305-c64xplus.pl +INCLUDE[poly1305-s390x.o]=.. +GENERATE[poly1305-s390x.S]=asm/poly1305-s390x.pl diff --git a/crypto/openssl/crypto/poly1305/poly1305-armv8.S b/crypto/openssl/crypto/poly1305/poly1305-armv8.S new file mode 100644 index 000000000000..ea8f39022405 --- /dev/null +++ b/crypto/openssl/crypto/poly1305/poly1305-armv8.S @@ -0,0 +1,863 @@ +#include "arm_arch.h" + +.text + +// forward "declarations" are required for Apple + +.hidden OPENSSL_armcap_P +.globl poly1305_init +.hidden poly1305_init +.globl poly1305_blocks +.hidden poly1305_blocks +.globl poly1305_emit +.hidden poly1305_emit + +.type poly1305_init,%function +.align 5 +poly1305_init: + cmp x1,xzr + stp xzr,xzr,[x0] // zero hash value + stp xzr,xzr,[x0,#16] // [along with is_base2_26] + + csel x0,xzr,x0,eq + b.eq .Lno_key + + adrp x17,OPENSSL_armcap_P + ldr w17,[x17,#:lo12:OPENSSL_armcap_P] + + ldp x7,x8,[x1] // load key + mov x9,#0xfffffffc0fffffff + movk x9,#0x0fff,lsl#48 +#ifdef __ARMEB__ + rev x7,x7 // flip bytes + rev x8,x8 +#endif + and x7,x7,x9 // &=0ffffffc0fffffff + and x9,x9,#-4 + and x8,x8,x9 // &=0ffffffc0ffffffc + stp x7,x8,[x0,#32] // save key value + + tst w17,#ARMV7_NEON + + adr x12,.Lpoly1305_blocks + adr x7,.Lpoly1305_blocks_neon + adr x13,.Lpoly1305_emit + adr x8,.Lpoly1305_emit_neon + + csel x12,x12,x7,eq + csel x13,x13,x8,eq + +#ifdef __ILP32__ + stp w12,w13,[x2] +#else + stp x12,x13,[x2] +#endif + + mov x0,#1 +.Lno_key: + ret +.size poly1305_init,.-poly1305_init + +.type poly1305_blocks,%function +.align 5 +poly1305_blocks: +.Lpoly1305_blocks: + ands x2,x2,#-16 + b.eq .Lno_data + + ldp x4,x5,[x0] // load hash value + ldp x7,x8,[x0,#32] // load key value + ldr x6,[x0,#16] + add x9,x8,x8,lsr#2 // s1 = r1 + (r1 >> 2) + b .Loop + +.align 5 +.Loop: + ldp x10,x11,[x1],#16 // load input + sub x2,x2,#16 +#ifdef __ARMEB__ + rev x10,x10 + rev x11,x11 +#endif + adds x4,x4,x10 // accumulate input + adcs x5,x5,x11 + + mul x12,x4,x7 // h0*r0 + adc x6,x6,x3 + umulh x13,x4,x7 + + mul x10,x5,x9 // h1*5*r1 + umulh x11,x5,x9 + + adds x12,x12,x10 + mul x10,x4,x8 // h0*r1 + adc x13,x13,x11 + umulh x14,x4,x8 + + adds x13,x13,x10 + mul x10,x5,x7 // h1*r0 + adc x14,x14,xzr + umulh x11,x5,x7 + + adds x13,x13,x10 + mul x10,x6,x9 // h2*5*r1 + adc x14,x14,x11 + mul x11,x6,x7 // h2*r0 + + adds x13,x13,x10 + adc x14,x14,x11 + + and x10,x14,#-4 // final reduction + and x6,x14,#3 + add x10,x10,x14,lsr#2 + adds x4,x12,x10 + adcs x5,x13,xzr + adc x6,x6,xzr + + cbnz x2,.Loop + + stp x4,x5,[x0] // store hash value + str x6,[x0,#16] + +.Lno_data: + ret +.size poly1305_blocks,.-poly1305_blocks + +.type poly1305_emit,%function +.align 5 +poly1305_emit: +.Lpoly1305_emit: + ldp x4,x5,[x0] // load hash base 2^64 + ldr x6,[x0,#16] + ldp x10,x11,[x2] // load nonce + + adds x12,x4,#5 // compare to modulus + adcs x13,x5,xzr + adc x14,x6,xzr + + tst x14,#-4 // see if it's carried/borrowed + + csel x4,x4,x12,eq + csel x5,x5,x13,eq + +#ifdef __ARMEB__ + ror x10,x10,#32 // flip nonce words + ror x11,x11,#32 +#endif + adds x4,x4,x10 // accumulate nonce + adc x5,x5,x11 +#ifdef __ARMEB__ + rev x4,x4 // flip output bytes + rev x5,x5 +#endif + stp x4,x5,[x1] // write result + + ret +.size poly1305_emit,.-poly1305_emit +.type poly1305_mult,%function +.align 5 +poly1305_mult: + mul x12,x4,x7 // h0*r0 + umulh x13,x4,x7 + + mul x10,x5,x9 // h1*5*r1 + umulh x11,x5,x9 + + adds x12,x12,x10 + mul x10,x4,x8 // h0*r1 + adc x13,x13,x11 + umulh x14,x4,x8 + + adds x13,x13,x10 + mul x10,x5,x7 // h1*r0 + adc x14,x14,xzr + umulh x11,x5,x7 + + adds x13,x13,x10 + mul x10,x6,x9 // h2*5*r1 + adc x14,x14,x11 + mul x11,x6,x7 // h2*r0 + + adds x13,x13,x10 + adc x14,x14,x11 + + and x10,x14,#-4 // final reduction + and x6,x14,#3 + add x10,x10,x14,lsr#2 + adds x4,x12,x10 + adcs x5,x13,xzr + adc x6,x6,xzr + + ret +.size poly1305_mult,.-poly1305_mult + +.type poly1305_splat,%function +.align 5 +poly1305_splat: + and x12,x4,#0x03ffffff // base 2^64 -> base 2^26 + ubfx x13,x4,#26,#26 + extr x14,x5,x4,#52 + and x14,x14,#0x03ffffff + ubfx x15,x5,#14,#26 + extr x16,x6,x5,#40 + + str w12,[x0,#16*0] // r0 + add w12,w13,w13,lsl#2 // r1*5 + str w13,[x0,#16*1] // r1 + add w13,w14,w14,lsl#2 // r2*5 + str w12,[x0,#16*2] // s1 + str w14,[x0,#16*3] // r2 + add w14,w15,w15,lsl#2 // r3*5 + str w13,[x0,#16*4] // s2 + str w15,[x0,#16*5] // r3 + add w15,w16,w16,lsl#2 // r4*5 + str w14,[x0,#16*6] // s3 + str w16,[x0,#16*7] // r4 + str w15,[x0,#16*8] // s4 + + ret +.size poly1305_splat,.-poly1305_splat + +.type poly1305_blocks_neon,%function +.align 5 +poly1305_blocks_neon: +.Lpoly1305_blocks_neon: + ldr x17,[x0,#24] + cmp x2,#128 + b.hs .Lblocks_neon + cbz x17,.Lpoly1305_blocks + +.Lblocks_neon: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + + ands x2,x2,#-16 + b.eq .Lno_data_neon + + cbz x17,.Lbase2_64_neon + + ldp w10,w11,[x0] // load hash value base 2^26 + ldp w12,w13,[x0,#8] + ldr w14,[x0,#16] + + tst x2,#31 + b.eq .Leven_neon + + ldp x7,x8,[x0,#32] // load key value + + add x4,x10,x11,lsl#26 // base 2^26 -> base 2^64 + lsr x5,x12,#12 + adds x4,x4,x12,lsl#52 + add x5,x5,x13,lsl#14 + adc x5,x5,xzr + lsr x6,x14,#24 + adds x5,x5,x14,lsl#40 + adc x14,x6,xzr // can be partially reduced... + + ldp x12,x13,[x1],#16 // load input + sub x2,x2,#16 + add x9,x8,x8,lsr#2 // s1 = r1 + (r1 >> 2) + + and x10,x14,#-4 // ... so reduce + and x6,x14,#3 + add x10,x10,x14,lsr#2 + adds x4,x4,x10 + adcs x5,x5,xzr + adc x6,x6,xzr + +#ifdef __ARMEB__ + rev x12,x12 + rev x13,x13 +#endif + adds x4,x4,x12 // accumulate input + adcs x5,x5,x13 + adc x6,x6,x3 + + bl poly1305_mult + ldr x30,[sp,#8] + + cbz x3,.Lstore_base2_64_neon + + and x10,x4,#0x03ffffff // base 2^64 -> base 2^26 + ubfx x11,x4,#26,#26 + extr x12,x5,x4,#52 + and x12,x12,#0x03ffffff + ubfx x13,x5,#14,#26 + extr x14,x6,x5,#40 + + cbnz x2,.Leven_neon + + stp w10,w11,[x0] // store hash value base 2^26 + stp w12,w13,[x0,#8] + str w14,[x0,#16] + b .Lno_data_neon + +.align 4 +.Lstore_base2_64_neon: + stp x4,x5,[x0] // store hash value base 2^64 + stp x6,xzr,[x0,#16] // note that is_base2_26 is zeroed + b .Lno_data_neon + +.align 4 +.Lbase2_64_neon: + ldp x7,x8,[x0,#32] // load key value + + ldp x4,x5,[x0] // load hash value base 2^64 + ldr x6,[x0,#16] + + tst x2,#31 + b.eq .Linit_neon + + ldp x12,x13,[x1],#16 // load input + sub x2,x2,#16 + add x9,x8,x8,lsr#2 // s1 = r1 + (r1 >> 2) +#ifdef __ARMEB__ + rev x12,x12 + rev x13,x13 +#endif + adds x4,x4,x12 // accumulate input + adcs x5,x5,x13 + adc x6,x6,x3 + + bl poly1305_mult + +.Linit_neon: + and x10,x4,#0x03ffffff // base 2^64 -> base 2^26 + ubfx x11,x4,#26,#26 + extr x12,x5,x4,#52 + and x12,x12,#0x03ffffff + ubfx x13,x5,#14,#26 + extr x14,x6,x5,#40 + + stp d8,d9,[sp,#16] // meet ABI requirements + stp d10,d11,[sp,#32] + stp d12,d13,[sp,#48] + stp d14,d15,[sp,#64] + + fmov d24,x10 + fmov d25,x11 + fmov d26,x12 + fmov d27,x13 + fmov d28,x14 + + ////////////////////////////////// initialize r^n table + mov x4,x7 // r^1 + add x9,x8,x8,lsr#2 // s1 = r1 + (r1 >> 2) + mov x5,x8 + mov x6,xzr + add x0,x0,#48+12 + bl poly1305_splat + + bl poly1305_mult // r^2 + sub x0,x0,#4 + bl poly1305_splat + + bl poly1305_mult // r^3 + sub x0,x0,#4 + bl poly1305_splat + + bl poly1305_mult // r^4 + sub x0,x0,#4 + bl poly1305_splat + ldr x30,[sp,#8] + + add x16,x1,#32 + adr x17,.Lzeros + subs x2,x2,#64 + csel x16,x17,x16,lo + + mov x4,#1 + stur x4,[x0,#-24] // set is_base2_26 + sub x0,x0,#48 // restore original x0 + b .Ldo_neon + +.align 4 +.Leven_neon: + add x16,x1,#32 + adr x17,.Lzeros + subs x2,x2,#64 + csel x16,x17,x16,lo + + stp d8,d9,[sp,#16] // meet ABI requirements + stp d10,d11,[sp,#32] + stp d12,d13,[sp,#48] + stp d14,d15,[sp,#64] + + fmov d24,x10 + fmov d25,x11 + fmov d26,x12 + fmov d27,x13 + fmov d28,x14 + +.Ldo_neon: + ldp x8,x12,[x16],#16 // inp[2:3] (or zero) + ldp x9,x13,[x16],#48 + + lsl x3,x3,#24 + add x15,x0,#48 + +#ifdef __ARMEB__ + rev x8,x8 + rev x12,x12 + rev x9,x9 + rev x13,x13 +#endif + and x4,x8,#0x03ffffff // base 2^64 -> base 2^26 + and x5,x9,#0x03ffffff + ubfx x6,x8,#26,#26 + ubfx x7,x9,#26,#26 + add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32 + extr x8,x12,x8,#52 + extr x9,x13,x9,#52 + add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32 + fmov d14,x4 + and x8,x8,#0x03ffffff + and x9,x9,#0x03ffffff + ubfx x10,x12,#14,#26 + ubfx x11,x13,#14,#26 + add x12,x3,x12,lsr#40 + add x13,x3,x13,lsr#40 + add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32 + fmov d15,x6 + add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32 + add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32 + fmov d16,x8 + fmov d17,x10 + fmov d18,x12 + + ldp x8,x12,[x1],#16 // inp[0:1] + ldp x9,x13,[x1],#48 + + ld1 {v0.4s,v1.4s,v2.4s,v3.4s},[x15],#64 + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[x15],#64 + ld1 {v8.4s},[x15] + +#ifdef __ARMEB__ + rev x8,x8 + rev x12,x12 + rev x9,x9 + rev x13,x13 +#endif + and x4,x8,#0x03ffffff // base 2^64 -> base 2^26 + and x5,x9,#0x03ffffff + ubfx x6,x8,#26,#26 + ubfx x7,x9,#26,#26 + add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32 + extr x8,x12,x8,#52 + extr x9,x13,x9,#52 + add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32 + fmov d9,x4 + and x8,x8,#0x03ffffff + and x9,x9,#0x03ffffff + ubfx x10,x12,#14,#26 + ubfx x11,x13,#14,#26 + add x12,x3,x12,lsr#40 + add x13,x3,x13,lsr#40 + add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32 + fmov d10,x6 + add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32 + add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32 + movi v31.2d,#-1 + fmov d11,x8 + fmov d12,x10 + fmov d13,x12 + ushr v31.2d,v31.2d,#38 + + b.ls .Lskip_loop + +.align 4 +.Loop_neon: + //////////////////////////////////////////////////////////////// + // ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2 + // ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r + // ___________________/ + // ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2 + // ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r + // ___________________/ ____________________/ + // + // Note that we start with inp[2:3]*r^2. This is because it + // doesn't depend on reduction in previous iteration. + //////////////////////////////////////////////////////////////// + // d4 = h0*r4 + h1*r3 + h2*r2 + h3*r1 + h4*r0 + // d3 = h0*r3 + h1*r2 + h2*r1 + h3*r0 + h4*5*r4 + // d2 = h0*r2 + h1*r1 + h2*r0 + h3*5*r4 + h4*5*r3 + // d1 = h0*r1 + h1*r0 + h2*5*r4 + h3*5*r3 + h4*5*r2 + // d0 = h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1 + + subs x2,x2,#64 + umull v23.2d,v14.2s,v7.s[2] + csel x16,x17,x16,lo + umull v22.2d,v14.2s,v5.s[2] + umull v21.2d,v14.2s,v3.s[2] + ldp x8,x12,[x16],#16 // inp[2:3] (or zero) + umull v20.2d,v14.2s,v1.s[2] + ldp x9,x13,[x16],#48 + umull v19.2d,v14.2s,v0.s[2] +#ifdef __ARMEB__ + rev x8,x8 + rev x12,x12 + rev x9,x9 + rev x13,x13 +#endif + + umlal v23.2d,v15.2s,v5.s[2] + and x4,x8,#0x03ffffff // base 2^64 -> base 2^26 + umlal v22.2d,v15.2s,v3.s[2] + and x5,x9,#0x03ffffff + umlal v21.2d,v15.2s,v1.s[2] + ubfx x6,x8,#26,#26 + umlal v20.2d,v15.2s,v0.s[2] + ubfx x7,x9,#26,#26 + umlal v19.2d,v15.2s,v8.s[2] + add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32 + + umlal v23.2d,v16.2s,v3.s[2] + extr x8,x12,x8,#52 + umlal v22.2d,v16.2s,v1.s[2] + extr x9,x13,x9,#52 + umlal v21.2d,v16.2s,v0.s[2] + add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32 + umlal v20.2d,v16.2s,v8.s[2] + fmov d14,x4 + umlal v19.2d,v16.2s,v6.s[2] + and x8,x8,#0x03ffffff + + umlal v23.2d,v17.2s,v1.s[2] + and x9,x9,#0x03ffffff + umlal v22.2d,v17.2s,v0.s[2] + ubfx x10,x12,#14,#26 + umlal v21.2d,v17.2s,v8.s[2] + ubfx x11,x13,#14,#26 + umlal v20.2d,v17.2s,v6.s[2] + add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32 + umlal v19.2d,v17.2s,v4.s[2] + fmov d15,x6 + + add v11.2s,v11.2s,v26.2s + add x12,x3,x12,lsr#40 + umlal v23.2d,v18.2s,v0.s[2] + add x13,x3,x13,lsr#40 + umlal v22.2d,v18.2s,v8.s[2] + add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32 + umlal v21.2d,v18.2s,v6.s[2] + add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32 + umlal v20.2d,v18.2s,v4.s[2] + fmov d16,x8 + umlal v19.2d,v18.2s,v2.s[2] + fmov d17,x10 + + //////////////////////////////////////////////////////////////// + // (hash+inp[0:1])*r^4 and accumulate + + add v9.2s,v9.2s,v24.2s + fmov d18,x12 + umlal v22.2d,v11.2s,v1.s[0] + ldp x8,x12,[x1],#16 // inp[0:1] + umlal v19.2d,v11.2s,v6.s[0] + ldp x9,x13,[x1],#48 + umlal v23.2d,v11.2s,v3.s[0] + umlal v20.2d,v11.2s,v8.s[0] + umlal v21.2d,v11.2s,v0.s[0] +#ifdef __ARMEB__ + rev x8,x8 + rev x12,x12 + rev x9,x9 + rev x13,x13 +#endif + + add v10.2s,v10.2s,v25.2s + umlal v22.2d,v9.2s,v5.s[0] + umlal v23.2d,v9.2s,v7.s[0] + and x4,x8,#0x03ffffff // base 2^64 -> base 2^26 + umlal v21.2d,v9.2s,v3.s[0] + and x5,x9,#0x03ffffff + umlal v19.2d,v9.2s,v0.s[0] + ubfx x6,x8,#26,#26 + umlal v20.2d,v9.2s,v1.s[0] + ubfx x7,x9,#26,#26 + + add v12.2s,v12.2s,v27.2s + add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32 + umlal v22.2d,v10.2s,v3.s[0] + extr x8,x12,x8,#52 + umlal v23.2d,v10.2s,v5.s[0] + extr x9,x13,x9,#52 + umlal v19.2d,v10.2s,v8.s[0] + add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32 + umlal v21.2d,v10.2s,v1.s[0] + fmov d9,x4 + umlal v20.2d,v10.2s,v0.s[0] + and x8,x8,#0x03ffffff + + add v13.2s,v13.2s,v28.2s + and x9,x9,#0x03ffffff + umlal v22.2d,v12.2s,v0.s[0] + ubfx x10,x12,#14,#26 + umlal v19.2d,v12.2s,v4.s[0] + ubfx x11,x13,#14,#26 + umlal v23.2d,v12.2s,v1.s[0] + add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32 + umlal v20.2d,v12.2s,v6.s[0] + fmov d10,x6 + umlal v21.2d,v12.2s,v8.s[0] + add x12,x3,x12,lsr#40 + + umlal v22.2d,v13.2s,v8.s[0] + add x13,x3,x13,lsr#40 + umlal v19.2d,v13.2s,v2.s[0] + add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32 + umlal v23.2d,v13.2s,v0.s[0] + add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32 + umlal v20.2d,v13.2s,v4.s[0] + fmov d11,x8 + umlal v21.2d,v13.2s,v6.s[0] + fmov d12,x10 + fmov d13,x12 + + ///////////////////////////////////////////////////////////////// + // lazy reduction as discussed in "NEON crypto" by D.J. Bernstein + // and P. Schwabe + // + // [see discussion in poly1305-armv4 module] + + ushr v29.2d,v22.2d,#26 + xtn v27.2s,v22.2d + ushr v30.2d,v19.2d,#26 + and v19.16b,v19.16b,v31.16b + add v23.2d,v23.2d,v29.2d // h3 -> h4 + bic v27.2s,#0xfc,lsl#24 // &=0x03ffffff + add v20.2d,v20.2d,v30.2d // h0 -> h1 + + ushr v29.2d,v23.2d,#26 + xtn v28.2s,v23.2d + ushr v30.2d,v20.2d,#26 + xtn v25.2s,v20.2d + bic v28.2s,#0xfc,lsl#24 + add v21.2d,v21.2d,v30.2d // h1 -> h2 + + add v19.2d,v19.2d,v29.2d + shl v29.2d,v29.2d,#2 + shrn v30.2s,v21.2d,#26 + xtn v26.2s,v21.2d + add v19.2d,v19.2d,v29.2d // h4 -> h0 + bic v25.2s,#0xfc,lsl#24 + add v27.2s,v27.2s,v30.2s // h2 -> h3 + bic v26.2s,#0xfc,lsl#24 + + shrn v29.2s,v19.2d,#26 + xtn v24.2s,v19.2d + ushr v30.2s,v27.2s,#26 + bic v27.2s,#0xfc,lsl#24 + bic v24.2s,#0xfc,lsl#24 + add v25.2s,v25.2s,v29.2s // h0 -> h1 + add v28.2s,v28.2s,v30.2s // h3 -> h4 + + b.hi .Loop_neon + +.Lskip_loop: + dup v16.2d,v16.d[0] + add v11.2s,v11.2s,v26.2s + + //////////////////////////////////////////////////////////////// + // multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1 + + adds x2,x2,#32 + b.ne .Long_tail + + dup v16.2d,v11.d[0] + add v14.2s,v9.2s,v24.2s + add v17.2s,v12.2s,v27.2s + add v15.2s,v10.2s,v25.2s + add v18.2s,v13.2s,v28.2s + +.Long_tail: + dup v14.2d,v14.d[0] + umull2 v19.2d,v16.4s,v6.4s + umull2 v22.2d,v16.4s,v1.4s + umull2 v23.2d,v16.4s,v3.4s + umull2 v21.2d,v16.4s,v0.4s + umull2 v20.2d,v16.4s,v8.4s + + dup v15.2d,v15.d[0] + umlal2 v19.2d,v14.4s,v0.4s + umlal2 v21.2d,v14.4s,v3.4s + umlal2 v22.2d,v14.4s,v5.4s + umlal2 v23.2d,v14.4s,v7.4s + umlal2 v20.2d,v14.4s,v1.4s + + dup v17.2d,v17.d[0] + umlal2 v19.2d,v15.4s,v8.4s + umlal2 v22.2d,v15.4s,v3.4s + umlal2 v21.2d,v15.4s,v1.4s + umlal2 v23.2d,v15.4s,v5.4s + umlal2 v20.2d,v15.4s,v0.4s + + dup v18.2d,v18.d[0] + umlal2 v22.2d,v17.4s,v0.4s + umlal2 v23.2d,v17.4s,v1.4s + umlal2 v19.2d,v17.4s,v4.4s + umlal2 v20.2d,v17.4s,v6.4s + umlal2 v21.2d,v17.4s,v8.4s + + umlal2 v22.2d,v18.4s,v8.4s + umlal2 v19.2d,v18.4s,v2.4s + umlal2 v23.2d,v18.4s,v0.4s + umlal2 v20.2d,v18.4s,v4.4s + umlal2 v21.2d,v18.4s,v6.4s + + b.eq .Lshort_tail + + //////////////////////////////////////////////////////////////// + // (hash+inp[0:1])*r^4:r^3 and accumulate + + add v9.2s,v9.2s,v24.2s + umlal v22.2d,v11.2s,v1.2s + umlal v19.2d,v11.2s,v6.2s + umlal v23.2d,v11.2s,v3.2s + umlal v20.2d,v11.2s,v8.2s + umlal v21.2d,v11.2s,v0.2s + + add v10.2s,v10.2s,v25.2s + umlal v22.2d,v9.2s,v5.2s + umlal v19.2d,v9.2s,v0.2s + umlal v23.2d,v9.2s,v7.2s + umlal v20.2d,v9.2s,v1.2s + umlal v21.2d,v9.2s,v3.2s + + add v12.2s,v12.2s,v27.2s + umlal v22.2d,v10.2s,v3.2s + umlal v19.2d,v10.2s,v8.2s + umlal v23.2d,v10.2s,v5.2s + umlal v20.2d,v10.2s,v0.2s + umlal v21.2d,v10.2s,v1.2s + + add v13.2s,v13.2s,v28.2s + umlal v22.2d,v12.2s,v0.2s + umlal v19.2d,v12.2s,v4.2s + umlal v23.2d,v12.2s,v1.2s + umlal v20.2d,v12.2s,v6.2s + umlal v21.2d,v12.2s,v8.2s + + umlal v22.2d,v13.2s,v8.2s + umlal v19.2d,v13.2s,v2.2s + umlal v23.2d,v13.2s,v0.2s + umlal v20.2d,v13.2s,v4.2s + umlal v21.2d,v13.2s,v6.2s + +.Lshort_tail: + //////////////////////////////////////////////////////////////// + // horizontal add + + addp v22.2d,v22.2d,v22.2d + ldp d8,d9,[sp,#16] // meet ABI requirements + addp v19.2d,v19.2d,v19.2d + ldp d10,d11,[sp,#32] + addp v23.2d,v23.2d,v23.2d + ldp d12,d13,[sp,#48] + addp v20.2d,v20.2d,v20.2d + ldp d14,d15,[sp,#64] + addp v21.2d,v21.2d,v21.2d + + //////////////////////////////////////////////////////////////// + // lazy reduction, but without narrowing + + ushr v29.2d,v22.2d,#26 + and v22.16b,v22.16b,v31.16b + ushr v30.2d,v19.2d,#26 + and v19.16b,v19.16b,v31.16b + + add v23.2d,v23.2d,v29.2d // h3 -> h4 + add v20.2d,v20.2d,v30.2d // h0 -> h1 + + ushr v29.2d,v23.2d,#26 + and v23.16b,v23.16b,v31.16b + ushr v30.2d,v20.2d,#26 + and v20.16b,v20.16b,v31.16b + add v21.2d,v21.2d,v30.2d // h1 -> h2 + + add v19.2d,v19.2d,v29.2d + shl v29.2d,v29.2d,#2 + ushr v30.2d,v21.2d,#26 + and v21.16b,v21.16b,v31.16b + add v19.2d,v19.2d,v29.2d // h4 -> h0 + add v22.2d,v22.2d,v30.2d // h2 -> h3 + + ushr v29.2d,v19.2d,#26 + and v19.16b,v19.16b,v31.16b + ushr v30.2d,v22.2d,#26 + and v22.16b,v22.16b,v31.16b + add v20.2d,v20.2d,v29.2d // h0 -> h1 + add v23.2d,v23.2d,v30.2d // h3 -> h4 + + //////////////////////////////////////////////////////////////// + // write the result, can be partially reduced + + st4 {v19.s,v20.s,v21.s,v22.s}[0],[x0],#16 + st1 {v23.s}[0],[x0] + +.Lno_data_neon: + ldr x29,[sp],#80 +.inst 0xd50323bf // autiasp + ret +.size poly1305_blocks_neon,.-poly1305_blocks_neon + +.type poly1305_emit_neon,%function +.align 5 +poly1305_emit_neon: +.Lpoly1305_emit_neon: + ldr x17,[x0,#24] + cbz x17,poly1305_emit + + ldp w10,w11,[x0] // load hash value base 2^26 + ldp w12,w13,[x0,#8] + ldr w14,[x0,#16] + + add x4,x10,x11,lsl#26 // base 2^26 -> base 2^64 + lsr x5,x12,#12 + adds x4,x4,x12,lsl#52 + add x5,x5,x13,lsl#14 + adc x5,x5,xzr + lsr x6,x14,#24 + adds x5,x5,x14,lsl#40 + adc x6,x6,xzr // can be partially reduced... + + ldp x10,x11,[x2] // load nonce + + and x12,x6,#-4 // ... so reduce + add x12,x12,x6,lsr#2 + and x6,x6,#3 + adds x4,x4,x12 + adcs x5,x5,xzr + adc x6,x6,xzr + + adds x12,x4,#5 // compare to modulus + adcs x13,x5,xzr + adc x14,x6,xzr + + tst x14,#-4 // see if it's carried/borrowed + + csel x4,x4,x12,eq + csel x5,x5,x13,eq + +#ifdef __ARMEB__ + ror x10,x10,#32 // flip nonce words + ror x11,x11,#32 +#endif + adds x4,x4,x10 // accumulate nonce + adc x5,x5,x11 +#ifdef __ARMEB__ + rev x4,x4 // flip output bytes + rev x5,x5 +#endif + stp x4,x5,[x1] // write result + + ret +.size poly1305_emit_neon,.-poly1305_emit_neon + +.align 5 +.Lzeros: +.long 0,0,0,0,0,0,0,0 +.byte 80,111,108,121,49,51,48,53,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 diff --git a/crypto/openssl/crypto/poly1305/poly1305-x86.S b/crypto/openssl/crypto/poly1305/poly1305-x86.S new file mode 100644 index 000000000000..e76632cd1e70 --- /dev/null +++ b/crypto/openssl/crypto/poly1305/poly1305-x86.S @@ -0,0 +1,1967 @@ +.text +.align 64 +.globl poly1305_init +.type poly1305_init,@function +.align 16 +poly1305_init: +.L_poly1305_init_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%edi + movl 24(%esp),%esi + movl 28(%esp),%ebp + xorl %eax,%eax + movl %eax,(%edi) + movl %eax,4(%edi) + movl %eax,8(%edi) + movl %eax,12(%edi) + movl %eax,16(%edi) + movl %eax,20(%edi) + cmpl $0,%esi + je .L000nokey + call .L001pic_point +.L001pic_point: + popl %ebx + leal poly1305_blocks-.L001pic_point(%ebx),%eax + leal poly1305_emit-.L001pic_point(%ebx),%edx + leal OPENSSL_ia32cap_P-.L001pic_point(%ebx),%edi + movl (%edi),%ecx + andl $83886080,%ecx + cmpl $83886080,%ecx + jne .L002no_sse2 + leal _poly1305_blocks_sse2-.L001pic_point(%ebx),%eax + leal _poly1305_emit_sse2-.L001pic_point(%ebx),%edx + movl 8(%edi),%ecx + testl $32,%ecx + jz .L002no_sse2 + leal _poly1305_blocks_avx2-.L001pic_point(%ebx),%eax +.L002no_sse2: + movl 20(%esp),%edi + movl %eax,(%ebp) + movl %edx,4(%ebp) + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + andl $268435455,%eax + andl $268435452,%ebx + andl $268435452,%ecx + andl $268435452,%edx + movl %eax,24(%edi) + movl %ebx,28(%edi) + movl %ecx,32(%edi) + movl %edx,36(%edi) + movl $1,%eax +.L000nokey: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size poly1305_init,.-.L_poly1305_init_begin +.globl poly1305_blocks +.type poly1305_blocks,@function +.align 16 +poly1305_blocks: +.L_poly1305_blocks_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%edi + movl 24(%esp),%esi + movl 28(%esp),%ecx +.Lenter_blocks: + andl $-15,%ecx + jz .L003nodata + subl $64,%esp + movl 24(%edi),%eax + movl 28(%edi),%ebx + leal (%esi,%ecx,1),%ebp + movl 32(%edi),%ecx + movl 36(%edi),%edx + movl %ebp,92(%esp) + movl %esi,%ebp + movl %eax,36(%esp) + movl %ebx,%eax + shrl $2,%eax + movl %ebx,40(%esp) + addl %ebx,%eax + movl %ecx,%ebx + shrl $2,%ebx + movl %ecx,44(%esp) + addl %ecx,%ebx + movl %edx,%ecx + shrl $2,%ecx + movl %edx,48(%esp) + addl %edx,%ecx + movl %eax,52(%esp) + movl %ebx,56(%esp) + movl %ecx,60(%esp) + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%esi + movl 16(%edi),%edi + jmp .L004loop +.align 32 +.L004loop: + addl (%ebp),%eax + adcl 4(%ebp),%ebx + adcl 8(%ebp),%ecx + adcl 12(%ebp),%esi + leal 16(%ebp),%ebp + adcl 96(%esp),%edi + movl %eax,(%esp) + movl %esi,12(%esp) + mull 36(%esp) + movl %edi,16(%esp) + movl %eax,%edi + movl %ebx,%eax + movl %edx,%esi + mull 60(%esp) + addl %eax,%edi + movl %ecx,%eax + adcl %edx,%esi + mull 56(%esp) + addl %eax,%edi + movl 12(%esp),%eax + adcl %edx,%esi + mull 52(%esp) + addl %eax,%edi + movl (%esp),%eax + adcl %edx,%esi + mull 40(%esp) + movl %edi,20(%esp) + xorl %edi,%edi + addl %eax,%esi + movl %ebx,%eax + adcl %edx,%edi + mull 36(%esp) + addl %eax,%esi + movl %ecx,%eax + adcl %edx,%edi + mull 60(%esp) + addl %eax,%esi + movl 12(%esp),%eax + adcl %edx,%edi + mull 56(%esp) + addl %eax,%esi + movl 16(%esp),%eax + adcl %edx,%edi + imull 52(%esp),%eax + addl %eax,%esi + movl (%esp),%eax + adcl $0,%edi + mull 44(%esp) + movl %esi,24(%esp) + xorl %esi,%esi + addl %eax,%edi + movl %ebx,%eax + adcl %edx,%esi + mull 40(%esp) + addl %eax,%edi + movl %ecx,%eax + adcl %edx,%esi + mull 36(%esp) + addl %eax,%edi + movl 12(%esp),%eax + adcl %edx,%esi + mull 60(%esp) + addl %eax,%edi + movl 16(%esp),%eax + adcl %edx,%esi + imull 56(%esp),%eax + addl %eax,%edi + movl (%esp),%eax + adcl $0,%esi + mull 48(%esp) + movl %edi,28(%esp) + xorl %edi,%edi + addl %eax,%esi + movl %ebx,%eax + adcl %edx,%edi + mull 44(%esp) + addl %eax,%esi + movl %ecx,%eax + adcl %edx,%edi + mull 40(%esp) + addl %eax,%esi + movl 12(%esp),%eax + adcl %edx,%edi + mull 36(%esp) + addl %eax,%esi + movl 16(%esp),%ecx + adcl %edx,%edi + movl %ecx,%edx + imull 60(%esp),%ecx + addl %ecx,%esi + movl 20(%esp),%eax + adcl $0,%edi + imull 36(%esp),%edx + addl %edi,%edx + movl 24(%esp),%ebx + movl 28(%esp),%ecx + movl %edx,%edi + shrl $2,%edx + andl $3,%edi + leal (%edx,%edx,4),%edx + addl %edx,%eax + adcl $0,%ebx + adcl $0,%ecx + adcl $0,%esi + adcl $0,%edi + cmpl 92(%esp),%ebp + jne .L004loop + movl 84(%esp),%edx + addl $64,%esp + movl %eax,(%edx) + movl %ebx,4(%edx) + movl %ecx,8(%edx) + movl %esi,12(%edx) + movl %edi,16(%edx) +.L003nodata: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size poly1305_blocks,.-.L_poly1305_blocks_begin +.globl poly1305_emit +.type poly1305_emit,@function +.align 16 +poly1305_emit: +.L_poly1305_emit_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%ebp +.Lenter_emit: + movl 24(%esp),%edi + movl (%ebp),%eax + movl 4(%ebp),%ebx + movl 8(%ebp),%ecx + movl 12(%ebp),%edx + movl 16(%ebp),%esi + addl $5,%eax + adcl $0,%ebx + adcl $0,%ecx + adcl $0,%edx + adcl $0,%esi + shrl $2,%esi + negl %esi + andl %esi,%eax + andl %esi,%ebx + andl %esi,%ecx + andl %esi,%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + notl %esi + movl (%ebp),%eax + movl 4(%ebp),%ebx + movl 8(%ebp),%ecx + movl 12(%ebp),%edx + movl 28(%esp),%ebp + andl %esi,%eax + andl %esi,%ebx + andl %esi,%ecx + andl %esi,%edx + orl (%edi),%eax + orl 4(%edi),%ebx + orl 8(%edi),%ecx + orl 12(%edi),%edx + addl (%ebp),%eax + adcl 4(%ebp),%ebx + adcl 8(%ebp),%ecx + adcl 12(%ebp),%edx + movl %eax,(%edi) + movl %ebx,4(%edi) + movl %ecx,8(%edi) + movl %edx,12(%edi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size poly1305_emit,.-.L_poly1305_emit_begin +.align 32 +.type _poly1305_init_sse2,@function +.align 16 +_poly1305_init_sse2: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movdqu 24(%edi),%xmm4 + leal 48(%edi),%edi + movl %esp,%ebp + subl $224,%esp + andl $-16,%esp + movq 64(%ebx),%xmm7 + movdqa %xmm4,%xmm0 + movdqa %xmm4,%xmm1 + movdqa %xmm4,%xmm2 + pand %xmm7,%xmm0 + psrlq $26,%xmm1 + psrldq $6,%xmm2 + pand %xmm7,%xmm1 + movdqa %xmm2,%xmm3 + psrlq $4,%xmm2 + psrlq $30,%xmm3 + pand %xmm7,%xmm2 + pand %xmm7,%xmm3 + psrldq $13,%xmm4 + leal 144(%esp),%edx + movl $2,%ecx +.L005square: + movdqa %xmm0,(%esp) + movdqa %xmm1,16(%esp) + movdqa %xmm2,32(%esp) + movdqa %xmm3,48(%esp) + movdqa %xmm4,64(%esp) + movdqa %xmm1,%xmm6 + movdqa %xmm2,%xmm5 + pslld $2,%xmm6 + pslld $2,%xmm5 + paddd %xmm1,%xmm6 + paddd %xmm2,%xmm5 + movdqa %xmm6,80(%esp) + movdqa %xmm5,96(%esp) + movdqa %xmm3,%xmm6 + movdqa %xmm4,%xmm5 + pslld $2,%xmm6 + pslld $2,%xmm5 + paddd %xmm3,%xmm6 + paddd %xmm4,%xmm5 + movdqa %xmm6,112(%esp) + movdqa %xmm5,128(%esp) + pshufd $68,%xmm0,%xmm6 + movdqa %xmm1,%xmm5 + pshufd $68,%xmm1,%xmm1 + pshufd $68,%xmm2,%xmm2 + pshufd $68,%xmm3,%xmm3 + pshufd $68,%xmm4,%xmm4 + movdqa %xmm6,(%edx) + movdqa %xmm1,16(%edx) + movdqa %xmm2,32(%edx) + movdqa %xmm3,48(%edx) + movdqa %xmm4,64(%edx) + pmuludq %xmm0,%xmm4 + pmuludq %xmm0,%xmm3 + pmuludq %xmm0,%xmm2 + pmuludq %xmm0,%xmm1 + pmuludq %xmm6,%xmm0 + movdqa %xmm5,%xmm6 + pmuludq 48(%edx),%xmm5 + movdqa %xmm6,%xmm7 + pmuludq 32(%edx),%xmm6 + paddq %xmm5,%xmm4 + movdqa %xmm7,%xmm5 + pmuludq 16(%edx),%xmm7 + paddq %xmm6,%xmm3 + movdqa 80(%esp),%xmm6 + pmuludq (%edx),%xmm5 + paddq %xmm7,%xmm2 + pmuludq 64(%edx),%xmm6 + movdqa 32(%esp),%xmm7 + paddq %xmm5,%xmm1 + movdqa %xmm7,%xmm5 + pmuludq 32(%edx),%xmm7 + paddq %xmm6,%xmm0 + movdqa %xmm5,%xmm6 + pmuludq 16(%edx),%xmm5 + paddq %xmm7,%xmm4 + movdqa 96(%esp),%xmm7 + pmuludq (%edx),%xmm6 + paddq %xmm5,%xmm3 + movdqa %xmm7,%xmm5 + pmuludq 64(%edx),%xmm7 + paddq %xmm6,%xmm2 + pmuludq 48(%edx),%xmm5 + movdqa 48(%esp),%xmm6 + paddq %xmm7,%xmm1 + movdqa %xmm6,%xmm7 + pmuludq 16(%edx),%xmm6 + paddq %xmm5,%xmm0 + movdqa 112(%esp),%xmm5 + pmuludq (%edx),%xmm7 + paddq %xmm6,%xmm4 + movdqa %xmm5,%xmm6 + pmuludq 64(%edx),%xmm5 + paddq %xmm7,%xmm3 + movdqa %xmm6,%xmm7 + pmuludq 48(%edx),%xmm6 + paddq %xmm5,%xmm2 + pmuludq 32(%edx),%xmm7 + movdqa 64(%esp),%xmm5 + paddq %xmm6,%xmm1 + movdqa 128(%esp),%xmm6 + pmuludq (%edx),%xmm5 + paddq %xmm7,%xmm0 + movdqa %xmm6,%xmm7 + pmuludq 64(%edx),%xmm6 + paddq %xmm5,%xmm4 + movdqa %xmm7,%xmm5 + pmuludq 16(%edx),%xmm7 + paddq %xmm6,%xmm3 + movdqa %xmm5,%xmm6 + pmuludq 32(%edx),%xmm5 + paddq %xmm7,%xmm0 + pmuludq 48(%edx),%xmm6 + movdqa 64(%ebx),%xmm7 + paddq %xmm5,%xmm1 + paddq %xmm6,%xmm2 + movdqa %xmm3,%xmm5 + pand %xmm7,%xmm3 + psrlq $26,%xmm5 + paddq %xmm4,%xmm5 + movdqa %xmm0,%xmm6 + pand %xmm7,%xmm0 + psrlq $26,%xmm6 + movdqa %xmm5,%xmm4 + paddq %xmm1,%xmm6 + psrlq $26,%xmm5 + pand %xmm7,%xmm4 + movdqa %xmm6,%xmm1 + psrlq $26,%xmm6 + paddd %xmm5,%xmm0 + psllq $2,%xmm5 + paddq %xmm2,%xmm6 + paddq %xmm0,%xmm5 + pand %xmm7,%xmm1 + movdqa %xmm6,%xmm2 + psrlq $26,%xmm6 + pand %xmm7,%xmm2 + paddd %xmm3,%xmm6 + movdqa %xmm5,%xmm0 + psrlq $26,%xmm5 + movdqa %xmm6,%xmm3 + psrlq $26,%xmm6 + pand %xmm7,%xmm0 + paddd %xmm5,%xmm1 + pand %xmm7,%xmm3 + paddd %xmm6,%xmm4 + decl %ecx + jz .L006square_break + punpcklqdq (%esp),%xmm0 + punpcklqdq 16(%esp),%xmm1 + punpcklqdq 32(%esp),%xmm2 + punpcklqdq 48(%esp),%xmm3 + punpcklqdq 64(%esp),%xmm4 + jmp .L005square +.L006square_break: + psllq $32,%xmm0 + psllq $32,%xmm1 + psllq $32,%xmm2 + psllq $32,%xmm3 + psllq $32,%xmm4 + por (%esp),%xmm0 + por 16(%esp),%xmm1 + por 32(%esp),%xmm2 + por 48(%esp),%xmm3 + por 64(%esp),%xmm4 + pshufd $141,%xmm0,%xmm0 + pshufd $141,%xmm1,%xmm1 + pshufd $141,%xmm2,%xmm2 + pshufd $141,%xmm3,%xmm3 + pshufd $141,%xmm4,%xmm4 + movdqu %xmm0,(%edi) + movdqu %xmm1,16(%edi) + movdqu %xmm2,32(%edi) + movdqu %xmm3,48(%edi) + movdqu %xmm4,64(%edi) + movdqa %xmm1,%xmm6 + movdqa %xmm2,%xmm5 + pslld $2,%xmm6 + pslld $2,%xmm5 + paddd %xmm1,%xmm6 + paddd %xmm2,%xmm5 + movdqu %xmm6,80(%edi) + movdqu %xmm5,96(%edi) + movdqa %xmm3,%xmm6 + movdqa %xmm4,%xmm5 + pslld $2,%xmm6 + pslld $2,%xmm5 + paddd %xmm3,%xmm6 + paddd %xmm4,%xmm5 + movdqu %xmm6,112(%edi) + movdqu %xmm5,128(%edi) + movl %ebp,%esp + leal -48(%edi),%edi + ret +.size _poly1305_init_sse2,.-_poly1305_init_sse2 +.align 32 +.type _poly1305_blocks_sse2,@function +.align 16 +_poly1305_blocks_sse2: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%edi + movl 24(%esp),%esi + movl 28(%esp),%ecx + movl 20(%edi),%eax + andl $-16,%ecx + jz .L007nodata + cmpl $64,%ecx + jae .L008enter_sse2 + testl %eax,%eax + jz .Lenter_blocks +.align 16 +.L008enter_sse2: + call .L009pic_point +.L009pic_point: + popl %ebx + leal .Lconst_sse2-.L009pic_point(%ebx),%ebx + testl %eax,%eax + jnz .L010base2_26 + call _poly1305_init_sse2 + movl (%edi),%eax + movl 3(%edi),%ecx + movl 6(%edi),%edx + movl 9(%edi),%esi + movl 13(%edi),%ebp + movl $1,20(%edi) + shrl $2,%ecx + andl $67108863,%eax + shrl $4,%edx + andl $67108863,%ecx + shrl $6,%esi + andl $67108863,%edx + movd %eax,%xmm0 + movd %ecx,%xmm1 + movd %edx,%xmm2 + movd %esi,%xmm3 + movd %ebp,%xmm4 + movl 24(%esp),%esi + movl 28(%esp),%ecx + jmp .L011base2_32 +.align 16 +.L010base2_26: + movd (%edi),%xmm0 + movd 4(%edi),%xmm1 + movd 8(%edi),%xmm2 + movd 12(%edi),%xmm3 + movd 16(%edi),%xmm4 + movdqa 64(%ebx),%xmm7 +.L011base2_32: + movl 32(%esp),%eax + movl %esp,%ebp + subl $528,%esp + andl $-16,%esp + leal 48(%edi),%edi + shll $24,%eax + testl $31,%ecx + jz .L012even + movdqu (%esi),%xmm6 + leal 16(%esi),%esi + movdqa %xmm6,%xmm5 + pand %xmm7,%xmm6 + paddd %xmm6,%xmm0 + movdqa %xmm5,%xmm6 + psrlq $26,%xmm5 + psrldq $6,%xmm6 + pand %xmm7,%xmm5 + paddd %xmm5,%xmm1 + movdqa %xmm6,%xmm5 + psrlq $4,%xmm6 + pand %xmm7,%xmm6 + paddd %xmm6,%xmm2 + movdqa %xmm5,%xmm6 + psrlq $30,%xmm5 + pand %xmm7,%xmm5 + psrldq $7,%xmm6 + paddd %xmm5,%xmm3 + movd %eax,%xmm5 + paddd %xmm6,%xmm4 + movd 12(%edi),%xmm6 + paddd %xmm5,%xmm4 + movdqa %xmm0,(%esp) + movdqa %xmm1,16(%esp) + movdqa %xmm2,32(%esp) + movdqa %xmm3,48(%esp) + movdqa %xmm4,64(%esp) + pmuludq %xmm6,%xmm0 + pmuludq %xmm6,%xmm1 + pmuludq %xmm6,%xmm2 + movd 28(%edi),%xmm5 + pmuludq %xmm6,%xmm3 + pmuludq %xmm6,%xmm4 + movdqa %xmm5,%xmm6 + pmuludq 48(%esp),%xmm5 + movdqa %xmm6,%xmm7 + pmuludq 32(%esp),%xmm6 + paddq %xmm5,%xmm4 + movdqa %xmm7,%xmm5 + pmuludq 16(%esp),%xmm7 + paddq %xmm6,%xmm3 + movd 92(%edi),%xmm6 + pmuludq (%esp),%xmm5 + paddq %xmm7,%xmm2 + pmuludq 64(%esp),%xmm6 + movd 44(%edi),%xmm7 + paddq %xmm5,%xmm1 + movdqa %xmm7,%xmm5 + pmuludq 32(%esp),%xmm7 + paddq %xmm6,%xmm0 + movdqa %xmm5,%xmm6 + pmuludq 16(%esp),%xmm5 + paddq %xmm7,%xmm4 + movd 108(%edi),%xmm7 + pmuludq (%esp),%xmm6 + paddq %xmm5,%xmm3 + movdqa %xmm7,%xmm5 + pmuludq 64(%esp),%xmm7 + paddq %xmm6,%xmm2 + pmuludq 48(%esp),%xmm5 + movd 60(%edi),%xmm6 + paddq %xmm7,%xmm1 + movdqa %xmm6,%xmm7 + pmuludq 16(%esp),%xmm6 + paddq %xmm5,%xmm0 + movd 124(%edi),%xmm5 + pmuludq (%esp),%xmm7 + paddq %xmm6,%xmm4 + movdqa %xmm5,%xmm6 + pmuludq 64(%esp),%xmm5 + paddq %xmm7,%xmm3 + movdqa %xmm6,%xmm7 + pmuludq 48(%esp),%xmm6 + paddq %xmm5,%xmm2 + pmuludq 32(%esp),%xmm7 + movd 76(%edi),%xmm5 + paddq %xmm6,%xmm1 + movd 140(%edi),%xmm6 + pmuludq (%esp),%xmm5 + paddq %xmm7,%xmm0 + movdqa %xmm6,%xmm7 + pmuludq 64(%esp),%xmm6 + paddq %xmm5,%xmm4 + movdqa %xmm7,%xmm5 + pmuludq 16(%esp),%xmm7 + paddq %xmm6,%xmm3 + movdqa %xmm5,%xmm6 + pmuludq 32(%esp),%xmm5 + paddq %xmm7,%xmm0 + pmuludq 48(%esp),%xmm6 + movdqa 64(%ebx),%xmm7 + paddq %xmm5,%xmm1 + paddq %xmm6,%xmm2 + movdqa %xmm3,%xmm5 + pand %xmm7,%xmm3 + psrlq $26,%xmm5 + paddq %xmm4,%xmm5 + movdqa %xmm0,%xmm6 + pand %xmm7,%xmm0 + psrlq $26,%xmm6 + movdqa %xmm5,%xmm4 + paddq %xmm1,%xmm6 + psrlq $26,%xmm5 + pand %xmm7,%xmm4 + movdqa %xmm6,%xmm1 + psrlq $26,%xmm6 + paddd %xmm5,%xmm0 + psllq $2,%xmm5 + paddq %xmm2,%xmm6 + paddq %xmm0,%xmm5 + pand %xmm7,%xmm1 + movdqa %xmm6,%xmm2 + psrlq $26,%xmm6 + pand %xmm7,%xmm2 + paddd %xmm3,%xmm6 + movdqa %xmm5,%xmm0 + psrlq $26,%xmm5 + movdqa %xmm6,%xmm3 + psrlq $26,%xmm6 + pand %xmm7,%xmm0 + paddd %xmm5,%xmm1 + pand %xmm7,%xmm3 + paddd %xmm6,%xmm4 + subl $16,%ecx + jz .L013done +.L012even: + leal 384(%esp),%edx + leal -32(%esi),%eax + subl $64,%ecx + movdqu (%edi),%xmm5 + pshufd $68,%xmm5,%xmm6 + cmovbl %eax,%esi + pshufd $238,%xmm5,%xmm5 + movdqa %xmm6,(%edx) + leal 160(%esp),%eax + movdqu 16(%edi),%xmm6 + movdqa %xmm5,-144(%edx) + pshufd $68,%xmm6,%xmm5 + pshufd $238,%xmm6,%xmm6 + movdqa %xmm5,16(%edx) + movdqu 32(%edi),%xmm5 + movdqa %xmm6,-128(%edx) + pshufd $68,%xmm5,%xmm6 + pshufd $238,%xmm5,%xmm5 + movdqa %xmm6,32(%edx) + movdqu 48(%edi),%xmm6 + movdqa %xmm5,-112(%edx) + pshufd $68,%xmm6,%xmm5 + pshufd $238,%xmm6,%xmm6 + movdqa %xmm5,48(%edx) + movdqu 64(%edi),%xmm5 + movdqa %xmm6,-96(%edx) + pshufd $68,%xmm5,%xmm6 + pshufd $238,%xmm5,%xmm5 + movdqa %xmm6,64(%edx) + movdqu 80(%edi),%xmm6 + movdqa %xmm5,-80(%edx) + pshufd $68,%xmm6,%xmm5 + pshufd $238,%xmm6,%xmm6 + movdqa %xmm5,80(%edx) + movdqu 96(%edi),%xmm5 + movdqa %xmm6,-64(%edx) + pshufd $68,%xmm5,%xmm6 + pshufd $238,%xmm5,%xmm5 + movdqa %xmm6,96(%edx) + movdqu 112(%edi),%xmm6 + movdqa %xmm5,-48(%edx) + pshufd $68,%xmm6,%xmm5 + pshufd $238,%xmm6,%xmm6 + movdqa %xmm5,112(%edx) + movdqu 128(%edi),%xmm5 + movdqa %xmm6,-32(%edx) + pshufd $68,%xmm5,%xmm6 + pshufd $238,%xmm5,%xmm5 + movdqa %xmm6,128(%edx) + movdqa %xmm5,-16(%edx) + movdqu 32(%esi),%xmm5 + movdqu 48(%esi),%xmm6 + leal 32(%esi),%esi + movdqa %xmm2,112(%esp) + movdqa %xmm3,128(%esp) + movdqa %xmm4,144(%esp) + movdqa %xmm5,%xmm2 + movdqa %xmm6,%xmm3 + psrldq $6,%xmm2 + psrldq $6,%xmm3 + movdqa %xmm5,%xmm4 + punpcklqdq %xmm3,%xmm2 + punpckhqdq %xmm6,%xmm4 + punpcklqdq %xmm6,%xmm5 + movdqa %xmm2,%xmm3 + psrlq $4,%xmm2 + psrlq $30,%xmm3 + movdqa %xmm5,%xmm6 + psrlq $40,%xmm4 + psrlq $26,%xmm6 + pand %xmm7,%xmm5 + pand %xmm7,%xmm6 + pand %xmm7,%xmm2 + pand %xmm7,%xmm3 + por (%ebx),%xmm4 + movdqa %xmm0,80(%esp) + movdqa %xmm1,96(%esp) + jbe .L014skip_loop + jmp .L015loop +.align 32 +.L015loop: + movdqa -144(%edx),%xmm7 + movdqa %xmm6,16(%eax) + movdqa %xmm2,32(%eax) + movdqa %xmm3,48(%eax) + movdqa %xmm4,64(%eax) + movdqa %xmm5,%xmm1 + pmuludq %xmm7,%xmm5 + movdqa %xmm6,%xmm0 + pmuludq %xmm7,%xmm6 + pmuludq %xmm7,%xmm2 + pmuludq %xmm7,%xmm3 + pmuludq %xmm7,%xmm4 + pmuludq -16(%edx),%xmm0 + movdqa %xmm1,%xmm7 + pmuludq -128(%edx),%xmm1 + paddq %xmm5,%xmm0 + movdqa %xmm7,%xmm5 + pmuludq -112(%edx),%xmm7 + paddq %xmm6,%xmm1 + movdqa %xmm5,%xmm6 + pmuludq -96(%edx),%xmm5 + paddq %xmm7,%xmm2 + movdqa 16(%eax),%xmm7 + pmuludq -80(%edx),%xmm6 + paddq %xmm5,%xmm3 + movdqa %xmm7,%xmm5 + pmuludq -128(%edx),%xmm7 + paddq %xmm6,%xmm4 + movdqa %xmm5,%xmm6 + pmuludq -112(%edx),%xmm5 + paddq %xmm7,%xmm2 + movdqa 32(%eax),%xmm7 + pmuludq -96(%edx),%xmm6 + paddq %xmm5,%xmm3 + movdqa %xmm7,%xmm5 + pmuludq -32(%edx),%xmm7 + paddq %xmm6,%xmm4 + movdqa %xmm5,%xmm6 + pmuludq -16(%edx),%xmm5 + paddq %xmm7,%xmm0 + movdqa %xmm6,%xmm7 + pmuludq -128(%edx),%xmm6 + paddq %xmm5,%xmm1 + movdqa 48(%eax),%xmm5 + pmuludq -112(%edx),%xmm7 + paddq %xmm6,%xmm3 + movdqa %xmm5,%xmm6 + pmuludq -48(%edx),%xmm5 + paddq %xmm7,%xmm4 + movdqa %xmm6,%xmm7 + pmuludq -32(%edx),%xmm6 + paddq %xmm5,%xmm0 + movdqa %xmm7,%xmm5 + pmuludq -16(%edx),%xmm7 + paddq %xmm6,%xmm1 + movdqa 64(%eax),%xmm6 + pmuludq -128(%edx),%xmm5 + paddq %xmm7,%xmm2 + movdqa %xmm6,%xmm7 + pmuludq -16(%edx),%xmm6 + paddq %xmm5,%xmm4 + movdqa %xmm7,%xmm5 + pmuludq -64(%edx),%xmm7 + paddq %xmm6,%xmm3 + movdqa %xmm5,%xmm6 + pmuludq -48(%edx),%xmm5 + paddq %xmm7,%xmm0 + movdqa 64(%ebx),%xmm7 + pmuludq -32(%edx),%xmm6 + paddq %xmm5,%xmm1 + paddq %xmm6,%xmm2 + movdqu -32(%esi),%xmm5 + movdqu -16(%esi),%xmm6 + leal 32(%esi),%esi + movdqa %xmm2,32(%esp) + movdqa %xmm3,48(%esp) + movdqa %xmm4,64(%esp) + movdqa %xmm5,%xmm2 + movdqa %xmm6,%xmm3 + psrldq $6,%xmm2 + psrldq $6,%xmm3 + movdqa %xmm5,%xmm4 + punpcklqdq %xmm3,%xmm2 + punpckhqdq %xmm6,%xmm4 + punpcklqdq %xmm6,%xmm5 + movdqa %xmm2,%xmm3 + psrlq $4,%xmm2 + psrlq $30,%xmm3 + movdqa %xmm5,%xmm6 + psrlq $40,%xmm4 + psrlq $26,%xmm6 + pand %xmm7,%xmm5 + pand %xmm7,%xmm6 + pand %xmm7,%xmm2 + pand %xmm7,%xmm3 + por (%ebx),%xmm4 + leal -32(%esi),%eax + subl $64,%ecx + paddd 80(%esp),%xmm5 + paddd 96(%esp),%xmm6 + paddd 112(%esp),%xmm2 + paddd 128(%esp),%xmm3 + paddd 144(%esp),%xmm4 + cmovbl %eax,%esi + leal 160(%esp),%eax + movdqa (%edx),%xmm7 + movdqa %xmm1,16(%esp) + movdqa %xmm6,16(%eax) + movdqa %xmm2,32(%eax) + movdqa %xmm3,48(%eax) + movdqa %xmm4,64(%eax) + movdqa %xmm5,%xmm1 + pmuludq %xmm7,%xmm5 + paddq %xmm0,%xmm5 + movdqa %xmm6,%xmm0 + pmuludq %xmm7,%xmm6 + pmuludq %xmm7,%xmm2 + pmuludq %xmm7,%xmm3 + pmuludq %xmm7,%xmm4 + paddq 16(%esp),%xmm6 + paddq 32(%esp),%xmm2 + paddq 48(%esp),%xmm3 + paddq 64(%esp),%xmm4 + pmuludq 128(%edx),%xmm0 + movdqa %xmm1,%xmm7 + pmuludq 16(%edx),%xmm1 + paddq %xmm5,%xmm0 + movdqa %xmm7,%xmm5 + pmuludq 32(%edx),%xmm7 + paddq %xmm6,%xmm1 + movdqa %xmm5,%xmm6 + pmuludq 48(%edx),%xmm5 + paddq %xmm7,%xmm2 + movdqa 16(%eax),%xmm7 + pmuludq 64(%edx),%xmm6 + paddq %xmm5,%xmm3 + movdqa %xmm7,%xmm5 + pmuludq 16(%edx),%xmm7 + paddq %xmm6,%xmm4 + movdqa %xmm5,%xmm6 + pmuludq 32(%edx),%xmm5 + paddq %xmm7,%xmm2 + movdqa 32(%eax),%xmm7 + pmuludq 48(%edx),%xmm6 + paddq %xmm5,%xmm3 + movdqa %xmm7,%xmm5 + pmuludq 112(%edx),%xmm7 + paddq %xmm6,%xmm4 + movdqa %xmm5,%xmm6 + pmuludq 128(%edx),%xmm5 + paddq %xmm7,%xmm0 + movdqa %xmm6,%xmm7 + pmuludq 16(%edx),%xmm6 + paddq %xmm5,%xmm1 + movdqa 48(%eax),%xmm5 + pmuludq 32(%edx),%xmm7 + paddq %xmm6,%xmm3 + movdqa %xmm5,%xmm6 + pmuludq 96(%edx),%xmm5 + paddq %xmm7,%xmm4 + movdqa %xmm6,%xmm7 + pmuludq 112(%edx),%xmm6 + paddq %xmm5,%xmm0 + movdqa %xmm7,%xmm5 + pmuludq 128(%edx),%xmm7 + paddq %xmm6,%xmm1 + movdqa 64(%eax),%xmm6 + pmuludq 16(%edx),%xmm5 + paddq %xmm7,%xmm2 + movdqa %xmm6,%xmm7 + pmuludq 128(%edx),%xmm6 + paddq %xmm5,%xmm4 + movdqa %xmm7,%xmm5 + pmuludq 80(%edx),%xmm7 + paddq %xmm6,%xmm3 + movdqa %xmm5,%xmm6 + pmuludq 96(%edx),%xmm5 + paddq %xmm7,%xmm0 + movdqa 64(%ebx),%xmm7 + pmuludq 112(%edx),%xmm6 + paddq %xmm5,%xmm1 + paddq %xmm6,%xmm2 + movdqa %xmm3,%xmm5 + pand %xmm7,%xmm3 + psrlq $26,%xmm5 + paddq %xmm4,%xmm5 + movdqa %xmm0,%xmm6 + pand %xmm7,%xmm0 + psrlq $26,%xmm6 + movdqa %xmm5,%xmm4 + paddq %xmm1,%xmm6 + psrlq $26,%xmm5 + pand %xmm7,%xmm4 + movdqa %xmm6,%xmm1 + psrlq $26,%xmm6 + paddd %xmm5,%xmm0 + psllq $2,%xmm5 + paddq %xmm2,%xmm6 + paddq %xmm0,%xmm5 + pand %xmm7,%xmm1 + movdqa %xmm6,%xmm2 + psrlq $26,%xmm6 + pand %xmm7,%xmm2 + paddd %xmm3,%xmm6 + movdqa %xmm5,%xmm0 + psrlq $26,%xmm5 + movdqa %xmm6,%xmm3 + psrlq $26,%xmm6 + pand %xmm7,%xmm0 + paddd %xmm5,%xmm1 + pand %xmm7,%xmm3 + paddd %xmm6,%xmm4 + movdqu 32(%esi),%xmm5 + movdqu 48(%esi),%xmm6 + leal 32(%esi),%esi + movdqa %xmm2,112(%esp) + movdqa %xmm3,128(%esp) + movdqa %xmm4,144(%esp) + movdqa %xmm5,%xmm2 + movdqa %xmm6,%xmm3 + psrldq $6,%xmm2 + psrldq $6,%xmm3 + movdqa %xmm5,%xmm4 + punpcklqdq %xmm3,%xmm2 + punpckhqdq %xmm6,%xmm4 + punpcklqdq %xmm6,%xmm5 + movdqa %xmm2,%xmm3 + psrlq $4,%xmm2 + psrlq $30,%xmm3 + movdqa %xmm5,%xmm6 + psrlq $40,%xmm4 + psrlq $26,%xmm6 + pand %xmm7,%xmm5 + pand %xmm7,%xmm6 + pand %xmm7,%xmm2 + pand %xmm7,%xmm3 + por (%ebx),%xmm4 + movdqa %xmm0,80(%esp) + movdqa %xmm1,96(%esp) + ja .L015loop +.L014skip_loop: + pshufd $16,-144(%edx),%xmm7 + addl $32,%ecx + jnz .L016long_tail + paddd %xmm0,%xmm5 + paddd %xmm1,%xmm6 + paddd 112(%esp),%xmm2 + paddd 128(%esp),%xmm3 + paddd 144(%esp),%xmm4 +.L016long_tail: + movdqa %xmm5,(%eax) + movdqa %xmm6,16(%eax) + movdqa %xmm2,32(%eax) + movdqa %xmm3,48(%eax) + movdqa %xmm4,64(%eax) + pmuludq %xmm7,%xmm5 + pmuludq %xmm7,%xmm6 + pmuludq %xmm7,%xmm2 + movdqa %xmm5,%xmm0 + pshufd $16,-128(%edx),%xmm5 + pmuludq %xmm7,%xmm3 + movdqa %xmm6,%xmm1 + pmuludq %xmm7,%xmm4 + movdqa %xmm5,%xmm6 + pmuludq 48(%eax),%xmm5 + movdqa %xmm6,%xmm7 + pmuludq 32(%eax),%xmm6 + paddq %xmm5,%xmm4 + movdqa %xmm7,%xmm5 + pmuludq 16(%eax),%xmm7 + paddq %xmm6,%xmm3 + pshufd $16,-64(%edx),%xmm6 + pmuludq (%eax),%xmm5 + paddq %xmm7,%xmm2 + pmuludq 64(%eax),%xmm6 + pshufd $16,-112(%edx),%xmm7 + paddq %xmm5,%xmm1 + movdqa %xmm7,%xmm5 + pmuludq 32(%eax),%xmm7 + paddq %xmm6,%xmm0 + movdqa %xmm5,%xmm6 + pmuludq 16(%eax),%xmm5 + paddq %xmm7,%xmm4 + pshufd $16,-48(%edx),%xmm7 + pmuludq (%eax),%xmm6 + paddq %xmm5,%xmm3 + movdqa %xmm7,%xmm5 + pmuludq 64(%eax),%xmm7 + paddq %xmm6,%xmm2 + pmuludq 48(%eax),%xmm5 + pshufd $16,-96(%edx),%xmm6 + paddq %xmm7,%xmm1 + movdqa %xmm6,%xmm7 + pmuludq 16(%eax),%xmm6 + paddq %xmm5,%xmm0 + pshufd $16,-32(%edx),%xmm5 + pmuludq (%eax),%xmm7 + paddq %xmm6,%xmm4 + movdqa %xmm5,%xmm6 + pmuludq 64(%eax),%xmm5 + paddq %xmm7,%xmm3 + movdqa %xmm6,%xmm7 + pmuludq 48(%eax),%xmm6 + paddq %xmm5,%xmm2 + pmuludq 32(%eax),%xmm7 + pshufd $16,-80(%edx),%xmm5 + paddq %xmm6,%xmm1 + pshufd $16,-16(%edx),%xmm6 + pmuludq (%eax),%xmm5 + paddq %xmm7,%xmm0 + movdqa %xmm6,%xmm7 + pmuludq 64(%eax),%xmm6 + paddq %xmm5,%xmm4 + movdqa %xmm7,%xmm5 + pmuludq 16(%eax),%xmm7 + paddq %xmm6,%xmm3 + movdqa %xmm5,%xmm6 + pmuludq 32(%eax),%xmm5 + paddq %xmm7,%xmm0 + pmuludq 48(%eax),%xmm6 + movdqa 64(%ebx),%xmm7 + paddq %xmm5,%xmm1 + paddq %xmm6,%xmm2 + jz .L017short_tail + movdqu -32(%esi),%xmm5 + movdqu -16(%esi),%xmm6 + leal 32(%esi),%esi + movdqa %xmm2,32(%esp) + movdqa %xmm3,48(%esp) + movdqa %xmm4,64(%esp) + movdqa %xmm5,%xmm2 + movdqa %xmm6,%xmm3 + psrldq $6,%xmm2 + psrldq $6,%xmm3 + movdqa %xmm5,%xmm4 + punpcklqdq %xmm3,%xmm2 + punpckhqdq %xmm6,%xmm4 + punpcklqdq %xmm6,%xmm5 + movdqa %xmm2,%xmm3 + psrlq $4,%xmm2 + psrlq $30,%xmm3 + movdqa %xmm5,%xmm6 + psrlq $40,%xmm4 + psrlq $26,%xmm6 + pand %xmm7,%xmm5 + pand %xmm7,%xmm6 + pand %xmm7,%xmm2 + pand %xmm7,%xmm3 + por (%ebx),%xmm4 + pshufd $16,(%edx),%xmm7 + paddd 80(%esp),%xmm5 + paddd 96(%esp),%xmm6 + paddd 112(%esp),%xmm2 + paddd 128(%esp),%xmm3 + paddd 144(%esp),%xmm4 + movdqa %xmm5,(%esp) + pmuludq %xmm7,%xmm5 + movdqa %xmm6,16(%esp) + pmuludq %xmm7,%xmm6 + paddq %xmm5,%xmm0 + movdqa %xmm2,%xmm5 + pmuludq %xmm7,%xmm2 + paddq %xmm6,%xmm1 + movdqa %xmm3,%xmm6 + pmuludq %xmm7,%xmm3 + paddq 32(%esp),%xmm2 + movdqa %xmm5,32(%esp) + pshufd $16,16(%edx),%xmm5 + paddq 48(%esp),%xmm3 + movdqa %xmm6,48(%esp) + movdqa %xmm4,%xmm6 + pmuludq %xmm7,%xmm4 + paddq 64(%esp),%xmm4 + movdqa %xmm6,64(%esp) + movdqa %xmm5,%xmm6 + pmuludq 48(%esp),%xmm5 + movdqa %xmm6,%xmm7 + pmuludq 32(%esp),%xmm6 + paddq %xmm5,%xmm4 + movdqa %xmm7,%xmm5 + pmuludq 16(%esp),%xmm7 + paddq %xmm6,%xmm3 + pshufd $16,80(%edx),%xmm6 + pmuludq (%esp),%xmm5 + paddq %xmm7,%xmm2 + pmuludq 64(%esp),%xmm6 + pshufd $16,32(%edx),%xmm7 + paddq %xmm5,%xmm1 + movdqa %xmm7,%xmm5 + pmuludq 32(%esp),%xmm7 + paddq %xmm6,%xmm0 + movdqa %xmm5,%xmm6 + pmuludq 16(%esp),%xmm5 + paddq %xmm7,%xmm4 + pshufd $16,96(%edx),%xmm7 + pmuludq (%esp),%xmm6 + paddq %xmm5,%xmm3 + movdqa %xmm7,%xmm5 + pmuludq 64(%esp),%xmm7 + paddq %xmm6,%xmm2 + pmuludq 48(%esp),%xmm5 + pshufd $16,48(%edx),%xmm6 + paddq %xmm7,%xmm1 + movdqa %xmm6,%xmm7 + pmuludq 16(%esp),%xmm6 + paddq %xmm5,%xmm0 + pshufd $16,112(%edx),%xmm5 + pmuludq (%esp),%xmm7 + paddq %xmm6,%xmm4 + movdqa %xmm5,%xmm6 + pmuludq 64(%esp),%xmm5 + paddq %xmm7,%xmm3 + movdqa %xmm6,%xmm7 + pmuludq 48(%esp),%xmm6 + paddq %xmm5,%xmm2 + pmuludq 32(%esp),%xmm7 + pshufd $16,64(%edx),%xmm5 + paddq %xmm6,%xmm1 + pshufd $16,128(%edx),%xmm6 + pmuludq (%esp),%xmm5 + paddq %xmm7,%xmm0 + movdqa %xmm6,%xmm7 + pmuludq 64(%esp),%xmm6 + paddq %xmm5,%xmm4 + movdqa %xmm7,%xmm5 + pmuludq 16(%esp),%xmm7 + paddq %xmm6,%xmm3 + movdqa %xmm5,%xmm6 + pmuludq 32(%esp),%xmm5 + paddq %xmm7,%xmm0 + pmuludq 48(%esp),%xmm6 + movdqa 64(%ebx),%xmm7 + paddq %xmm5,%xmm1 + paddq %xmm6,%xmm2 +.L017short_tail: + pshufd $78,%xmm4,%xmm6 + pshufd $78,%xmm3,%xmm5 + paddq %xmm6,%xmm4 + paddq %xmm5,%xmm3 + pshufd $78,%xmm0,%xmm6 + pshufd $78,%xmm1,%xmm5 + paddq %xmm6,%xmm0 + paddq %xmm5,%xmm1 + pshufd $78,%xmm2,%xmm6 + movdqa %xmm3,%xmm5 + pand %xmm7,%xmm3 + psrlq $26,%xmm5 + paddq %xmm6,%xmm2 + paddq %xmm4,%xmm5 + movdqa %xmm0,%xmm6 + pand %xmm7,%xmm0 + psrlq $26,%xmm6 + movdqa %xmm5,%xmm4 + paddq %xmm1,%xmm6 + psrlq $26,%xmm5 + pand %xmm7,%xmm4 + movdqa %xmm6,%xmm1 + psrlq $26,%xmm6 + paddd %xmm5,%xmm0 + psllq $2,%xmm5 + paddq %xmm2,%xmm6 + paddq %xmm0,%xmm5 + pand %xmm7,%xmm1 + movdqa %xmm6,%xmm2 + psrlq $26,%xmm6 + pand %xmm7,%xmm2 + paddd %xmm3,%xmm6 + movdqa %xmm5,%xmm0 + psrlq $26,%xmm5 + movdqa %xmm6,%xmm3 + psrlq $26,%xmm6 + pand %xmm7,%xmm0 + paddd %xmm5,%xmm1 + pand %xmm7,%xmm3 + paddd %xmm6,%xmm4 +.L013done: + movd %xmm0,-48(%edi) + movd %xmm1,-44(%edi) + movd %xmm2,-40(%edi) + movd %xmm3,-36(%edi) + movd %xmm4,-32(%edi) + movl %ebp,%esp +.L007nodata: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size _poly1305_blocks_sse2,.-_poly1305_blocks_sse2 +.align 32 +.type _poly1305_emit_sse2,@function +.align 16 +_poly1305_emit_sse2: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%ebp + cmpl $0,20(%ebp) + je .Lenter_emit + movl (%ebp),%eax + movl 4(%ebp),%edi + movl 8(%ebp),%ecx + movl 12(%ebp),%edx + movl 16(%ebp),%esi + movl %edi,%ebx + shll $26,%edi + shrl $6,%ebx + addl %edi,%eax + movl %ecx,%edi + adcl $0,%ebx + shll $20,%edi + shrl $12,%ecx + addl %edi,%ebx + movl %edx,%edi + adcl $0,%ecx + shll $14,%edi + shrl $18,%edx + addl %edi,%ecx + movl %esi,%edi + adcl $0,%edx + shll $8,%edi + shrl $24,%esi + addl %edi,%edx + adcl $0,%esi + movl %esi,%edi + andl $3,%esi + shrl $2,%edi + leal (%edi,%edi,4),%ebp + movl 24(%esp),%edi + addl %ebp,%eax + movl 28(%esp),%ebp + adcl $0,%ebx + adcl $0,%ecx + adcl $0,%edx + adcl $0,%esi + movd %eax,%xmm0 + addl $5,%eax + movd %ebx,%xmm1 + adcl $0,%ebx + movd %ecx,%xmm2 + adcl $0,%ecx + movd %edx,%xmm3 + adcl $0,%edx + adcl $0,%esi + shrl $2,%esi + negl %esi + andl %esi,%eax + andl %esi,%ebx + andl %esi,%ecx + andl %esi,%edx + movl %eax,(%edi) + movd %xmm0,%eax + movl %ebx,4(%edi) + movd %xmm1,%ebx + movl %ecx,8(%edi) + movd %xmm2,%ecx + movl %edx,12(%edi) + movd %xmm3,%edx + notl %esi + andl %esi,%eax + andl %esi,%ebx + orl (%edi),%eax + andl %esi,%ecx + orl 4(%edi),%ebx + andl %esi,%edx + orl 8(%edi),%ecx + orl 12(%edi),%edx + addl (%ebp),%eax + adcl 4(%ebp),%ebx + movl %eax,(%edi) + adcl 8(%ebp),%ecx + movl %ebx,4(%edi) + adcl 12(%ebp),%edx + movl %ecx,8(%edi) + movl %edx,12(%edi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size _poly1305_emit_sse2,.-_poly1305_emit_sse2 +.align 32 +.type _poly1305_init_avx2,@function +.align 16 +_poly1305_init_avx2: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + vmovdqu 24(%edi),%xmm4 + leal 48(%edi),%edi + movl %esp,%ebp + subl $224,%esp + andl $-16,%esp + vmovdqa 64(%ebx),%xmm7 + vpand %xmm7,%xmm4,%xmm0 + vpsrlq $26,%xmm4,%xmm1 + vpsrldq $6,%xmm4,%xmm3 + vpand %xmm7,%xmm1,%xmm1 + vpsrlq $4,%xmm3,%xmm2 + vpsrlq $30,%xmm3,%xmm3 + vpand %xmm7,%xmm2,%xmm2 + vpand %xmm7,%xmm3,%xmm3 + vpsrldq $13,%xmm4,%xmm4 + leal 144(%esp),%edx + movl $2,%ecx +.L018square: + vmovdqa %xmm0,(%esp) + vmovdqa %xmm1,16(%esp) + vmovdqa %xmm2,32(%esp) + vmovdqa %xmm3,48(%esp) + vmovdqa %xmm4,64(%esp) + vpslld $2,%xmm1,%xmm6 + vpslld $2,%xmm2,%xmm5 + vpaddd %xmm1,%xmm6,%xmm6 + vpaddd %xmm2,%xmm5,%xmm5 + vmovdqa %xmm6,80(%esp) + vmovdqa %xmm5,96(%esp) + vpslld $2,%xmm3,%xmm6 + vpslld $2,%xmm4,%xmm5 + vpaddd %xmm3,%xmm6,%xmm6 + vpaddd %xmm4,%xmm5,%xmm5 + vmovdqa %xmm6,112(%esp) + vmovdqa %xmm5,128(%esp) + vpshufd $68,%xmm0,%xmm5 + vmovdqa %xmm1,%xmm6 + vpshufd $68,%xmm1,%xmm1 + vpshufd $68,%xmm2,%xmm2 + vpshufd $68,%xmm3,%xmm3 + vpshufd $68,%xmm4,%xmm4 + vmovdqa %xmm5,(%edx) + vmovdqa %xmm1,16(%edx) + vmovdqa %xmm2,32(%edx) + vmovdqa %xmm3,48(%edx) + vmovdqa %xmm4,64(%edx) + vpmuludq %xmm0,%xmm4,%xmm4 + vpmuludq %xmm0,%xmm3,%xmm3 + vpmuludq %xmm0,%xmm2,%xmm2 + vpmuludq %xmm0,%xmm1,%xmm1 + vpmuludq %xmm0,%xmm5,%xmm0 + vpmuludq 48(%edx),%xmm6,%xmm5 + vpaddq %xmm5,%xmm4,%xmm4 + vpmuludq 32(%edx),%xmm6,%xmm7 + vpaddq %xmm7,%xmm3,%xmm3 + vpmuludq 16(%edx),%xmm6,%xmm5 + vpaddq %xmm5,%xmm2,%xmm2 + vmovdqa 80(%esp),%xmm7 + vpmuludq (%edx),%xmm6,%xmm6 + vpaddq %xmm6,%xmm1,%xmm1 + vmovdqa 32(%esp),%xmm5 + vpmuludq 64(%edx),%xmm7,%xmm7 + vpaddq %xmm7,%xmm0,%xmm0 + vpmuludq 32(%edx),%xmm5,%xmm6 + vpaddq %xmm6,%xmm4,%xmm4 + vpmuludq 16(%edx),%xmm5,%xmm7 + vpaddq %xmm7,%xmm3,%xmm3 + vmovdqa 96(%esp),%xmm6 + vpmuludq (%edx),%xmm5,%xmm5 + vpaddq %xmm5,%xmm2,%xmm2 + vpmuludq 64(%edx),%xmm6,%xmm7 + vpaddq %xmm7,%xmm1,%xmm1 + vmovdqa 48(%esp),%xmm5 + vpmuludq 48(%edx),%xmm6,%xmm6 + vpaddq %xmm6,%xmm0,%xmm0 + vpmuludq 16(%edx),%xmm5,%xmm7 + vpaddq %xmm7,%xmm4,%xmm4 + vmovdqa 112(%esp),%xmm6 + vpmuludq (%edx),%xmm5,%xmm5 + vpaddq %xmm5,%xmm3,%xmm3 + vpmuludq 64(%edx),%xmm6,%xmm7 + vpaddq %xmm7,%xmm2,%xmm2 + vpmuludq 48(%edx),%xmm6,%xmm5 + vpaddq %xmm5,%xmm1,%xmm1 + vmovdqa 64(%esp),%xmm7 + vpmuludq 32(%edx),%xmm6,%xmm6 + vpaddq %xmm6,%xmm0,%xmm0 + vmovdqa 128(%esp),%xmm5 + vpmuludq (%edx),%xmm7,%xmm7 + vpaddq %xmm7,%xmm4,%xmm4 + vpmuludq 64(%edx),%xmm5,%xmm6 + vpaddq %xmm6,%xmm3,%xmm3 + vpmuludq 16(%edx),%xmm5,%xmm7 + vpaddq %xmm7,%xmm0,%xmm0 + vpmuludq 32(%edx),%xmm5,%xmm6 + vpaddq %xmm6,%xmm1,%xmm1 + vmovdqa 64(%ebx),%xmm7 + vpmuludq 48(%edx),%xmm5,%xmm5 + vpaddq %xmm5,%xmm2,%xmm2 + vpsrlq $26,%xmm3,%xmm5 + vpand %xmm7,%xmm3,%xmm3 + vpsrlq $26,%xmm0,%xmm6 + vpand %xmm7,%xmm0,%xmm0 + vpaddq %xmm5,%xmm4,%xmm4 + vpaddq %xmm6,%xmm1,%xmm1 + vpsrlq $26,%xmm4,%xmm5 + vpand %xmm7,%xmm4,%xmm4 + vpsrlq $26,%xmm1,%xmm6 + vpand %xmm7,%xmm1,%xmm1 + vpaddq %xmm6,%xmm2,%xmm2 + vpaddd %xmm5,%xmm0,%xmm0 + vpsllq $2,%xmm5,%xmm5 + vpsrlq $26,%xmm2,%xmm6 + vpand %xmm7,%xmm2,%xmm2 + vpaddd %xmm5,%xmm0,%xmm0 + vpaddd %xmm6,%xmm3,%xmm3 + vpsrlq $26,%xmm3,%xmm6 + vpsrlq $26,%xmm0,%xmm5 + vpand %xmm7,%xmm0,%xmm0 + vpand %xmm7,%xmm3,%xmm3 + vpaddd %xmm5,%xmm1,%xmm1 + vpaddd %xmm6,%xmm4,%xmm4 + decl %ecx + jz .L019square_break + vpunpcklqdq (%esp),%xmm0,%xmm0 + vpunpcklqdq 16(%esp),%xmm1,%xmm1 + vpunpcklqdq 32(%esp),%xmm2,%xmm2 + vpunpcklqdq 48(%esp),%xmm3,%xmm3 + vpunpcklqdq 64(%esp),%xmm4,%xmm4 + jmp .L018square +.L019square_break: + vpsllq $32,%xmm0,%xmm0 + vpsllq $32,%xmm1,%xmm1 + vpsllq $32,%xmm2,%xmm2 + vpsllq $32,%xmm3,%xmm3 + vpsllq $32,%xmm4,%xmm4 + vpor (%esp),%xmm0,%xmm0 + vpor 16(%esp),%xmm1,%xmm1 + vpor 32(%esp),%xmm2,%xmm2 + vpor 48(%esp),%xmm3,%xmm3 + vpor 64(%esp),%xmm4,%xmm4 + vpshufd $141,%xmm0,%xmm0 + vpshufd $141,%xmm1,%xmm1 + vpshufd $141,%xmm2,%xmm2 + vpshufd $141,%xmm3,%xmm3 + vpshufd $141,%xmm4,%xmm4 + vmovdqu %xmm0,(%edi) + vmovdqu %xmm1,16(%edi) + vmovdqu %xmm2,32(%edi) + vmovdqu %xmm3,48(%edi) + vmovdqu %xmm4,64(%edi) + vpslld $2,%xmm1,%xmm6 + vpslld $2,%xmm2,%xmm5 + vpaddd %xmm1,%xmm6,%xmm6 + vpaddd %xmm2,%xmm5,%xmm5 + vmovdqu %xmm6,80(%edi) + vmovdqu %xmm5,96(%edi) + vpslld $2,%xmm3,%xmm6 + vpslld $2,%xmm4,%xmm5 + vpaddd %xmm3,%xmm6,%xmm6 + vpaddd %xmm4,%xmm5,%xmm5 + vmovdqu %xmm6,112(%edi) + vmovdqu %xmm5,128(%edi) + movl %ebp,%esp + leal -48(%edi),%edi + ret +.size _poly1305_init_avx2,.-_poly1305_init_avx2 +.align 32 +.type _poly1305_blocks_avx2,@function +.align 16 +_poly1305_blocks_avx2: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%edi + movl 24(%esp),%esi + movl 28(%esp),%ecx + movl 20(%edi),%eax + andl $-16,%ecx + jz .L020nodata + cmpl $64,%ecx + jae .L021enter_avx2 + testl %eax,%eax + jz .Lenter_blocks +.L021enter_avx2: + vzeroupper + call .L022pic_point +.L022pic_point: + popl %ebx + leal .Lconst_sse2-.L022pic_point(%ebx),%ebx + testl %eax,%eax + jnz .L023base2_26 + call _poly1305_init_avx2 + movl (%edi),%eax + movl 3(%edi),%ecx + movl 6(%edi),%edx + movl 9(%edi),%esi + movl 13(%edi),%ebp + shrl $2,%ecx + andl $67108863,%eax + shrl $4,%edx + andl $67108863,%ecx + shrl $6,%esi + andl $67108863,%edx + movl %eax,(%edi) + movl %ecx,4(%edi) + movl %edx,8(%edi) + movl %esi,12(%edi) + movl %ebp,16(%edi) + movl $1,20(%edi) + movl 24(%esp),%esi + movl 28(%esp),%ecx +.L023base2_26: + movl 32(%esp),%eax + movl %esp,%ebp + subl $448,%esp + andl $-512,%esp + vmovdqu 48(%edi),%xmm0 + leal 288(%esp),%edx + vmovdqu 64(%edi),%xmm1 + vmovdqu 80(%edi),%xmm2 + vmovdqu 96(%edi),%xmm3 + vmovdqu 112(%edi),%xmm4 + leal 48(%edi),%edi + vpermq $64,%ymm0,%ymm0 + vpermq $64,%ymm1,%ymm1 + vpermq $64,%ymm2,%ymm2 + vpermq $64,%ymm3,%ymm3 + vpermq $64,%ymm4,%ymm4 + vpshufd $200,%ymm0,%ymm0 + vpshufd $200,%ymm1,%ymm1 + vpshufd $200,%ymm2,%ymm2 + vpshufd $200,%ymm3,%ymm3 + vpshufd $200,%ymm4,%ymm4 + vmovdqa %ymm0,-128(%edx) + vmovdqu 80(%edi),%xmm0 + vmovdqa %ymm1,-96(%edx) + vmovdqu 96(%edi),%xmm1 + vmovdqa %ymm2,-64(%edx) + vmovdqu 112(%edi),%xmm2 + vmovdqa %ymm3,-32(%edx) + vmovdqu 128(%edi),%xmm3 + vmovdqa %ymm4,(%edx) + vpermq $64,%ymm0,%ymm0 + vpermq $64,%ymm1,%ymm1 + vpermq $64,%ymm2,%ymm2 + vpermq $64,%ymm3,%ymm3 + vpshufd $200,%ymm0,%ymm0 + vpshufd $200,%ymm1,%ymm1 + vpshufd $200,%ymm2,%ymm2 + vpshufd $200,%ymm3,%ymm3 + vmovdqa %ymm0,32(%edx) + vmovd -48(%edi),%xmm0 + vmovdqa %ymm1,64(%edx) + vmovd -44(%edi),%xmm1 + vmovdqa %ymm2,96(%edx) + vmovd -40(%edi),%xmm2 + vmovdqa %ymm3,128(%edx) + vmovd -36(%edi),%xmm3 + vmovd -32(%edi),%xmm4 + vmovdqa 64(%ebx),%ymm7 + negl %eax + testl $63,%ecx + jz .L024even + movl %ecx,%edx + andl $-64,%ecx + andl $63,%edx + vmovdqu (%esi),%xmm5 + cmpl $32,%edx + jb .L025one + vmovdqu 16(%esi),%xmm6 + je .L026two + vinserti128 $1,32(%esi),%ymm5,%ymm5 + leal 48(%esi),%esi + leal 8(%ebx),%ebx + leal 296(%esp),%edx + jmp .L027tail +.L026two: + leal 32(%esi),%esi + leal 16(%ebx),%ebx + leal 304(%esp),%edx + jmp .L027tail +.L025one: + leal 16(%esi),%esi + vpxor %ymm6,%ymm6,%ymm6 + leal 32(%ebx,%eax,8),%ebx + leal 312(%esp),%edx + jmp .L027tail +.align 32 +.L024even: + vmovdqu (%esi),%xmm5 + vmovdqu 16(%esi),%xmm6 + vinserti128 $1,32(%esi),%ymm5,%ymm5 + vinserti128 $1,48(%esi),%ymm6,%ymm6 + leal 64(%esi),%esi + subl $64,%ecx + jz .L027tail +.L028loop: + vmovdqa %ymm2,64(%esp) + vpsrldq $6,%ymm5,%ymm2 + vmovdqa %ymm0,(%esp) + vpsrldq $6,%ymm6,%ymm0 + vmovdqa %ymm1,32(%esp) + vpunpckhqdq %ymm6,%ymm5,%ymm1 + vpunpcklqdq %ymm6,%ymm5,%ymm5 + vpunpcklqdq %ymm0,%ymm2,%ymm2 + vpsrlq $30,%ymm2,%ymm0 + vpsrlq $4,%ymm2,%ymm2 + vpsrlq $26,%ymm5,%ymm6 + vpsrlq $40,%ymm1,%ymm1 + vpand %ymm7,%ymm2,%ymm2 + vpand %ymm7,%ymm5,%ymm5 + vpand %ymm7,%ymm6,%ymm6 + vpand %ymm7,%ymm0,%ymm0 + vpor (%ebx),%ymm1,%ymm1 + vpaddq 64(%esp),%ymm2,%ymm2 + vpaddq (%esp),%ymm5,%ymm5 + vpaddq 32(%esp),%ymm6,%ymm6 + vpaddq %ymm3,%ymm0,%ymm0 + vpaddq %ymm4,%ymm1,%ymm1 + vpmuludq -96(%edx),%ymm2,%ymm3 + vmovdqa %ymm6,32(%esp) + vpmuludq -64(%edx),%ymm2,%ymm4 + vmovdqa %ymm0,96(%esp) + vpmuludq 96(%edx),%ymm2,%ymm0 + vmovdqa %ymm1,128(%esp) + vpmuludq 128(%edx),%ymm2,%ymm1 + vpmuludq -128(%edx),%ymm2,%ymm2 + vpmuludq -32(%edx),%ymm5,%ymm7 + vpaddq %ymm7,%ymm3,%ymm3 + vpmuludq (%edx),%ymm5,%ymm6 + vpaddq %ymm6,%ymm4,%ymm4 + vpmuludq -128(%edx),%ymm5,%ymm7 + vpaddq %ymm7,%ymm0,%ymm0 + vmovdqa 32(%esp),%ymm7 + vpmuludq -96(%edx),%ymm5,%ymm6 + vpaddq %ymm6,%ymm1,%ymm1 + vpmuludq -64(%edx),%ymm5,%ymm5 + vpaddq %ymm5,%ymm2,%ymm2 + vpmuludq -64(%edx),%ymm7,%ymm6 + vpaddq %ymm6,%ymm3,%ymm3 + vpmuludq -32(%edx),%ymm7,%ymm5 + vpaddq %ymm5,%ymm4,%ymm4 + vpmuludq 128(%edx),%ymm7,%ymm6 + vpaddq %ymm6,%ymm0,%ymm0 + vmovdqa 96(%esp),%ymm6 + vpmuludq -128(%edx),%ymm7,%ymm5 + vpaddq %ymm5,%ymm1,%ymm1 + vpmuludq -96(%edx),%ymm7,%ymm7 + vpaddq %ymm7,%ymm2,%ymm2 + vpmuludq -128(%edx),%ymm6,%ymm5 + vpaddq %ymm5,%ymm3,%ymm3 + vpmuludq -96(%edx),%ymm6,%ymm7 + vpaddq %ymm7,%ymm4,%ymm4 + vpmuludq 64(%edx),%ymm6,%ymm5 + vpaddq %ymm5,%ymm0,%ymm0 + vmovdqa 128(%esp),%ymm5 + vpmuludq 96(%edx),%ymm6,%ymm7 + vpaddq %ymm7,%ymm1,%ymm1 + vpmuludq 128(%edx),%ymm6,%ymm6 + vpaddq %ymm6,%ymm2,%ymm2 + vpmuludq 128(%edx),%ymm5,%ymm7 + vpaddq %ymm7,%ymm3,%ymm3 + vpmuludq 32(%edx),%ymm5,%ymm6 + vpaddq %ymm6,%ymm0,%ymm0 + vpmuludq -128(%edx),%ymm5,%ymm7 + vpaddq %ymm7,%ymm4,%ymm4 + vmovdqa 64(%ebx),%ymm7 + vpmuludq 64(%edx),%ymm5,%ymm6 + vpaddq %ymm6,%ymm1,%ymm1 + vpmuludq 96(%edx),%ymm5,%ymm5 + vpaddq %ymm5,%ymm2,%ymm2 + vpsrlq $26,%ymm3,%ymm5 + vpand %ymm7,%ymm3,%ymm3 + vpsrlq $26,%ymm0,%ymm6 + vpand %ymm7,%ymm0,%ymm0 + vpaddq %ymm5,%ymm4,%ymm4 + vpaddq %ymm6,%ymm1,%ymm1 + vpsrlq $26,%ymm4,%ymm5 + vpand %ymm7,%ymm4,%ymm4 + vpsrlq $26,%ymm1,%ymm6 + vpand %ymm7,%ymm1,%ymm1 + vpaddq %ymm6,%ymm2,%ymm2 + vpaddq %ymm5,%ymm0,%ymm0 + vpsllq $2,%ymm5,%ymm5 + vpsrlq $26,%ymm2,%ymm6 + vpand %ymm7,%ymm2,%ymm2 + vpaddq %ymm5,%ymm0,%ymm0 + vpaddq %ymm6,%ymm3,%ymm3 + vpsrlq $26,%ymm3,%ymm6 + vpsrlq $26,%ymm0,%ymm5 + vpand %ymm7,%ymm0,%ymm0 + vpand %ymm7,%ymm3,%ymm3 + vpaddq %ymm5,%ymm1,%ymm1 + vpaddq %ymm6,%ymm4,%ymm4 + vmovdqu (%esi),%xmm5 + vmovdqu 16(%esi),%xmm6 + vinserti128 $1,32(%esi),%ymm5,%ymm5 + vinserti128 $1,48(%esi),%ymm6,%ymm6 + leal 64(%esi),%esi + subl $64,%ecx + jnz .L028loop +.L027tail: + vmovdqa %ymm2,64(%esp) + vpsrldq $6,%ymm5,%ymm2 + vmovdqa %ymm0,(%esp) + vpsrldq $6,%ymm6,%ymm0 + vmovdqa %ymm1,32(%esp) + vpunpckhqdq %ymm6,%ymm5,%ymm1 + vpunpcklqdq %ymm6,%ymm5,%ymm5 + vpunpcklqdq %ymm0,%ymm2,%ymm2 + vpsrlq $30,%ymm2,%ymm0 + vpsrlq $4,%ymm2,%ymm2 + vpsrlq $26,%ymm5,%ymm6 + vpsrlq $40,%ymm1,%ymm1 + vpand %ymm7,%ymm2,%ymm2 + vpand %ymm7,%ymm5,%ymm5 + vpand %ymm7,%ymm6,%ymm6 + vpand %ymm7,%ymm0,%ymm0 + vpor (%ebx),%ymm1,%ymm1 + andl $-64,%ebx + vpaddq 64(%esp),%ymm2,%ymm2 + vpaddq (%esp),%ymm5,%ymm5 + vpaddq 32(%esp),%ymm6,%ymm6 + vpaddq %ymm3,%ymm0,%ymm0 + vpaddq %ymm4,%ymm1,%ymm1 + vpmuludq -92(%edx),%ymm2,%ymm3 + vmovdqa %ymm6,32(%esp) + vpmuludq -60(%edx),%ymm2,%ymm4 + vmovdqa %ymm0,96(%esp) + vpmuludq 100(%edx),%ymm2,%ymm0 + vmovdqa %ymm1,128(%esp) + vpmuludq 132(%edx),%ymm2,%ymm1 + vpmuludq -124(%edx),%ymm2,%ymm2 + vpmuludq -28(%edx),%ymm5,%ymm7 + vpaddq %ymm7,%ymm3,%ymm3 + vpmuludq 4(%edx),%ymm5,%ymm6 + vpaddq %ymm6,%ymm4,%ymm4 + vpmuludq -124(%edx),%ymm5,%ymm7 + vpaddq %ymm7,%ymm0,%ymm0 + vmovdqa 32(%esp),%ymm7 + vpmuludq -92(%edx),%ymm5,%ymm6 + vpaddq %ymm6,%ymm1,%ymm1 + vpmuludq -60(%edx),%ymm5,%ymm5 + vpaddq %ymm5,%ymm2,%ymm2 + vpmuludq -60(%edx),%ymm7,%ymm6 + vpaddq %ymm6,%ymm3,%ymm3 + vpmuludq -28(%edx),%ymm7,%ymm5 + vpaddq %ymm5,%ymm4,%ymm4 + vpmuludq 132(%edx),%ymm7,%ymm6 + vpaddq %ymm6,%ymm0,%ymm0 + vmovdqa 96(%esp),%ymm6 + vpmuludq -124(%edx),%ymm7,%ymm5 + vpaddq %ymm5,%ymm1,%ymm1 + vpmuludq -92(%edx),%ymm7,%ymm7 + vpaddq %ymm7,%ymm2,%ymm2 + vpmuludq -124(%edx),%ymm6,%ymm5 + vpaddq %ymm5,%ymm3,%ymm3 + vpmuludq -92(%edx),%ymm6,%ymm7 + vpaddq %ymm7,%ymm4,%ymm4 + vpmuludq 68(%edx),%ymm6,%ymm5 + vpaddq %ymm5,%ymm0,%ymm0 + vmovdqa 128(%esp),%ymm5 + vpmuludq 100(%edx),%ymm6,%ymm7 + vpaddq %ymm7,%ymm1,%ymm1 + vpmuludq 132(%edx),%ymm6,%ymm6 + vpaddq %ymm6,%ymm2,%ymm2 + vpmuludq 132(%edx),%ymm5,%ymm7 + vpaddq %ymm7,%ymm3,%ymm3 + vpmuludq 36(%edx),%ymm5,%ymm6 + vpaddq %ymm6,%ymm0,%ymm0 + vpmuludq -124(%edx),%ymm5,%ymm7 + vpaddq %ymm7,%ymm4,%ymm4 + vmovdqa 64(%ebx),%ymm7 + vpmuludq 68(%edx),%ymm5,%ymm6 + vpaddq %ymm6,%ymm1,%ymm1 + vpmuludq 100(%edx),%ymm5,%ymm5 + vpaddq %ymm5,%ymm2,%ymm2 + vpsrldq $8,%ymm4,%ymm5 + vpsrldq $8,%ymm3,%ymm6 + vpaddq %ymm5,%ymm4,%ymm4 + vpsrldq $8,%ymm0,%ymm5 + vpaddq %ymm6,%ymm3,%ymm3 + vpsrldq $8,%ymm1,%ymm6 + vpaddq %ymm5,%ymm0,%ymm0 + vpsrldq $8,%ymm2,%ymm5 + vpaddq %ymm6,%ymm1,%ymm1 + vpermq $2,%ymm4,%ymm6 + vpaddq %ymm5,%ymm2,%ymm2 + vpermq $2,%ymm3,%ymm5 + vpaddq %ymm6,%ymm4,%ymm4 + vpermq $2,%ymm0,%ymm6 + vpaddq %ymm5,%ymm3,%ymm3 + vpermq $2,%ymm1,%ymm5 + vpaddq %ymm6,%ymm0,%ymm0 + vpermq $2,%ymm2,%ymm6 + vpaddq %ymm5,%ymm1,%ymm1 + vpaddq %ymm6,%ymm2,%ymm2 + vpsrlq $26,%ymm3,%ymm5 + vpand %ymm7,%ymm3,%ymm3 + vpsrlq $26,%ymm0,%ymm6 + vpand %ymm7,%ymm0,%ymm0 + vpaddq %ymm5,%ymm4,%ymm4 + vpaddq %ymm6,%ymm1,%ymm1 + vpsrlq $26,%ymm4,%ymm5 + vpand %ymm7,%ymm4,%ymm4 + vpsrlq $26,%ymm1,%ymm6 + vpand %ymm7,%ymm1,%ymm1 + vpaddq %ymm6,%ymm2,%ymm2 + vpaddq %ymm5,%ymm0,%ymm0 + vpsllq $2,%ymm5,%ymm5 + vpsrlq $26,%ymm2,%ymm6 + vpand %ymm7,%ymm2,%ymm2 + vpaddq %ymm5,%ymm0,%ymm0 + vpaddq %ymm6,%ymm3,%ymm3 + vpsrlq $26,%ymm3,%ymm6 + vpsrlq $26,%ymm0,%ymm5 + vpand %ymm7,%ymm0,%ymm0 + vpand %ymm7,%ymm3,%ymm3 + vpaddq %ymm5,%ymm1,%ymm1 + vpaddq %ymm6,%ymm4,%ymm4 + cmpl $0,%ecx + je .L029done + vpshufd $252,%xmm0,%xmm0 + leal 288(%esp),%edx + vpshufd $252,%xmm1,%xmm1 + vpshufd $252,%xmm2,%xmm2 + vpshufd $252,%xmm3,%xmm3 + vpshufd $252,%xmm4,%xmm4 + jmp .L024even +.align 16 +.L029done: + vmovd %xmm0,-48(%edi) + vmovd %xmm1,-44(%edi) + vmovd %xmm2,-40(%edi) + vmovd %xmm3,-36(%edi) + vmovd %xmm4,-32(%edi) + vzeroupper + movl %ebp,%esp +.L020nodata: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size _poly1305_blocks_avx2,.-_poly1305_blocks_avx2 +.align 64 +.Lconst_sse2: +.long 16777216,0,16777216,0,16777216,0,16777216,0 +.long 0,0,0,0,0,0,0,0 +.long 67108863,0,67108863,0,67108863,0,67108863,0 +.long 268435455,268435452,268435452,268435452 +.byte 80,111,108,121,49,51,48,53,32,102,111,114,32,120,56,54 +.byte 44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32 +.byte 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111 +.byte 114,103,62,0 +.align 4 +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/poly1305/poly1305-x86_64.S b/crypto/openssl/crypto/poly1305/poly1305-x86_64.S new file mode 100644 index 000000000000..9f9df19a3707 --- /dev/null +++ b/crypto/openssl/crypto/poly1305/poly1305-x86_64.S @@ -0,0 +1,2089 @@ +.text + + + +.globl poly1305_init +.hidden poly1305_init +.globl poly1305_blocks +.hidden poly1305_blocks +.globl poly1305_emit +.hidden poly1305_emit + +.type poly1305_init,@function +.align 32 +poly1305_init: +.cfi_startproc + xorq %rax,%rax + movq %rax,0(%rdi) + movq %rax,8(%rdi) + movq %rax,16(%rdi) + + cmpq $0,%rsi + je .Lno_key + + leaq poly1305_blocks(%rip),%r10 + leaq poly1305_emit(%rip),%r11 + movq OPENSSL_ia32cap_P+4(%rip),%r9 + leaq poly1305_blocks_avx(%rip),%rax + leaq poly1305_emit_avx(%rip),%rcx + btq $28,%r9 + cmovcq %rax,%r10 + cmovcq %rcx,%r11 + leaq poly1305_blocks_avx2(%rip),%rax + btq $37,%r9 + cmovcq %rax,%r10 + movq $0x0ffffffc0fffffff,%rax + movq $0x0ffffffc0ffffffc,%rcx + andq 0(%rsi),%rax + andq 8(%rsi),%rcx + movq %rax,24(%rdi) + movq %rcx,32(%rdi) + movq %r10,0(%rdx) + movq %r11,8(%rdx) + movl $1,%eax +.Lno_key: + .byte 0xf3,0xc3 +.cfi_endproc +.size poly1305_init,.-poly1305_init + +.type poly1305_blocks,@function +.align 32 +poly1305_blocks: +.cfi_startproc +.Lblocks: + shrq $4,%rdx + jz .Lno_data + + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lblocks_body: + + movq %rdx,%r15 + + movq 24(%rdi),%r11 + movq 32(%rdi),%r13 + + movq 0(%rdi),%r14 + movq 8(%rdi),%rbx + movq 16(%rdi),%rbp + + movq %r13,%r12 + shrq $2,%r13 + movq %r12,%rax + addq %r12,%r13 + jmp .Loop + +.align 32 +.Loop: + addq 0(%rsi),%r14 + adcq 8(%rsi),%rbx + leaq 16(%rsi),%rsi + adcq %rcx,%rbp + mulq %r14 + movq %rax,%r9 + movq %r11,%rax + movq %rdx,%r10 + + mulq %r14 + movq %rax,%r14 + movq %r11,%rax + movq %rdx,%r8 + + mulq %rbx + addq %rax,%r9 + movq %r13,%rax + adcq %rdx,%r10 + + mulq %rbx + movq %rbp,%rbx + addq %rax,%r14 + adcq %rdx,%r8 + + imulq %r13,%rbx + addq %rbx,%r9 + movq %r8,%rbx + adcq $0,%r10 + + imulq %r11,%rbp + addq %r9,%rbx + movq $-4,%rax + adcq %rbp,%r10 + + andq %r10,%rax + movq %r10,%rbp + shrq $2,%r10 + andq $3,%rbp + addq %r10,%rax + addq %rax,%r14 + adcq $0,%rbx + adcq $0,%rbp + movq %r12,%rax + decq %r15 + jnz .Loop + + movq %r14,0(%rdi) + movq %rbx,8(%rdi) + movq %rbp,16(%rdi) + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbp +.cfi_restore %rbp + movq 40(%rsp),%rbx +.cfi_restore %rbx + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lno_data: +.Lblocks_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size poly1305_blocks,.-poly1305_blocks + +.type poly1305_emit,@function +.align 32 +poly1305_emit: +.cfi_startproc +.Lemit: + movq 0(%rdi),%r8 + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + + movq %r8,%rax + addq $5,%r8 + movq %r9,%rcx + adcq $0,%r9 + adcq $0,%r10 + shrq $2,%r10 + cmovnzq %r8,%rax + cmovnzq %r9,%rcx + + addq 0(%rdx),%rax + adcq 8(%rdx),%rcx + movq %rax,0(%rsi) + movq %rcx,8(%rsi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size poly1305_emit,.-poly1305_emit +.type __poly1305_block,@function +.align 32 +__poly1305_block: +.cfi_startproc + mulq %r14 + movq %rax,%r9 + movq %r11,%rax + movq %rdx,%r10 + + mulq %r14 + movq %rax,%r14 + movq %r11,%rax + movq %rdx,%r8 + + mulq %rbx + addq %rax,%r9 + movq %r13,%rax + adcq %rdx,%r10 + + mulq %rbx + movq %rbp,%rbx + addq %rax,%r14 + adcq %rdx,%r8 + + imulq %r13,%rbx + addq %rbx,%r9 + movq %r8,%rbx + adcq $0,%r10 + + imulq %r11,%rbp + addq %r9,%rbx + movq $-4,%rax + adcq %rbp,%r10 + + andq %r10,%rax + movq %r10,%rbp + shrq $2,%r10 + andq $3,%rbp + addq %r10,%rax + addq %rax,%r14 + adcq $0,%rbx + adcq $0,%rbp + .byte 0xf3,0xc3 +.cfi_endproc +.size __poly1305_block,.-__poly1305_block + +.type __poly1305_init_avx,@function +.align 32 +__poly1305_init_avx: +.cfi_startproc + movq %r11,%r14 + movq %r12,%rbx + xorq %rbp,%rbp + + leaq 48+64(%rdi),%rdi + + movq %r12,%rax + call __poly1305_block + + movl $0x3ffffff,%eax + movl $0x3ffffff,%edx + movq %r14,%r8 + andl %r14d,%eax + movq %r11,%r9 + andl %r11d,%edx + movl %eax,-64(%rdi) + shrq $26,%r8 + movl %edx,-60(%rdi) + shrq $26,%r9 + + movl $0x3ffffff,%eax + movl $0x3ffffff,%edx + andl %r8d,%eax + andl %r9d,%edx + movl %eax,-48(%rdi) + leal (%rax,%rax,4),%eax + movl %edx,-44(%rdi) + leal (%rdx,%rdx,4),%edx + movl %eax,-32(%rdi) + shrq $26,%r8 + movl %edx,-28(%rdi) + shrq $26,%r9 + + movq %rbx,%rax + movq %r12,%rdx + shlq $12,%rax + shlq $12,%rdx + orq %r8,%rax + orq %r9,%rdx + andl $0x3ffffff,%eax + andl $0x3ffffff,%edx + movl %eax,-16(%rdi) + leal (%rax,%rax,4),%eax + movl %edx,-12(%rdi) + leal (%rdx,%rdx,4),%edx + movl %eax,0(%rdi) + movq %rbx,%r8 + movl %edx,4(%rdi) + movq %r12,%r9 + + movl $0x3ffffff,%eax + movl $0x3ffffff,%edx + shrq $14,%r8 + shrq $14,%r9 + andl %r8d,%eax + andl %r9d,%edx + movl %eax,16(%rdi) + leal (%rax,%rax,4),%eax + movl %edx,20(%rdi) + leal (%rdx,%rdx,4),%edx + movl %eax,32(%rdi) + shrq $26,%r8 + movl %edx,36(%rdi) + shrq $26,%r9 + + movq %rbp,%rax + shlq $24,%rax + orq %rax,%r8 + movl %r8d,48(%rdi) + leaq (%r8,%r8,4),%r8 + movl %r9d,52(%rdi) + leaq (%r9,%r9,4),%r9 + movl %r8d,64(%rdi) + movl %r9d,68(%rdi) + + movq %r12,%rax + call __poly1305_block + + movl $0x3ffffff,%eax + movq %r14,%r8 + andl %r14d,%eax + shrq $26,%r8 + movl %eax,-52(%rdi) + + movl $0x3ffffff,%edx + andl %r8d,%edx + movl %edx,-36(%rdi) + leal (%rdx,%rdx,4),%edx + shrq $26,%r8 + movl %edx,-20(%rdi) + + movq %rbx,%rax + shlq $12,%rax + orq %r8,%rax + andl $0x3ffffff,%eax + movl %eax,-4(%rdi) + leal (%rax,%rax,4),%eax + movq %rbx,%r8 + movl %eax,12(%rdi) + + movl $0x3ffffff,%edx + shrq $14,%r8 + andl %r8d,%edx + movl %edx,28(%rdi) + leal (%rdx,%rdx,4),%edx + shrq $26,%r8 + movl %edx,44(%rdi) + + movq %rbp,%rax + shlq $24,%rax + orq %rax,%r8 + movl %r8d,60(%rdi) + leaq (%r8,%r8,4),%r8 + movl %r8d,76(%rdi) + + movq %r12,%rax + call __poly1305_block + + movl $0x3ffffff,%eax + movq %r14,%r8 + andl %r14d,%eax + shrq $26,%r8 + movl %eax,-56(%rdi) + + movl $0x3ffffff,%edx + andl %r8d,%edx + movl %edx,-40(%rdi) + leal (%rdx,%rdx,4),%edx + shrq $26,%r8 + movl %edx,-24(%rdi) + + movq %rbx,%rax + shlq $12,%rax + orq %r8,%rax + andl $0x3ffffff,%eax + movl %eax,-8(%rdi) + leal (%rax,%rax,4),%eax + movq %rbx,%r8 + movl %eax,8(%rdi) + + movl $0x3ffffff,%edx + shrq $14,%r8 + andl %r8d,%edx + movl %edx,24(%rdi) + leal (%rdx,%rdx,4),%edx + shrq $26,%r8 + movl %edx,40(%rdi) + + movq %rbp,%rax + shlq $24,%rax + orq %rax,%r8 + movl %r8d,56(%rdi) + leaq (%r8,%r8,4),%r8 + movl %r8d,72(%rdi) + + leaq -48-64(%rdi),%rdi + .byte 0xf3,0xc3 +.cfi_endproc +.size __poly1305_init_avx,.-__poly1305_init_avx + +.type poly1305_blocks_avx,@function +.align 32 +poly1305_blocks_avx: +.cfi_startproc + movl 20(%rdi),%r8d + cmpq $128,%rdx + jae .Lblocks_avx + testl %r8d,%r8d + jz .Lblocks + +.Lblocks_avx: + andq $-16,%rdx + jz .Lno_data_avx + + vzeroupper + + testl %r8d,%r8d + jz .Lbase2_64_avx + + testq $31,%rdx + jz .Leven_avx + + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lblocks_avx_body: + + movq %rdx,%r15 + + movq 0(%rdi),%r8 + movq 8(%rdi),%r9 + movl 16(%rdi),%ebp + + movq 24(%rdi),%r11 + movq 32(%rdi),%r13 + + + movl %r8d,%r14d + andq $-2147483648,%r8 + movq %r9,%r12 + movl %r9d,%ebx + andq $-2147483648,%r9 + + shrq $6,%r8 + shlq $52,%r12 + addq %r8,%r14 + shrq $12,%rbx + shrq $18,%r9 + addq %r12,%r14 + adcq %r9,%rbx + + movq %rbp,%r8 + shlq $40,%r8 + shrq $24,%rbp + addq %r8,%rbx + adcq $0,%rbp + + movq $-4,%r9 + movq %rbp,%r8 + andq %rbp,%r9 + shrq $2,%r8 + andq $3,%rbp + addq %r9,%r8 + addq %r8,%r14 + adcq $0,%rbx + adcq $0,%rbp + + movq %r13,%r12 + movq %r13,%rax + shrq $2,%r13 + addq %r12,%r13 + + addq 0(%rsi),%r14 + adcq 8(%rsi),%rbx + leaq 16(%rsi),%rsi + adcq %rcx,%rbp + + call __poly1305_block + + testq %rcx,%rcx + jz .Lstore_base2_64_avx + + + movq %r14,%rax + movq %r14,%rdx + shrq $52,%r14 + movq %rbx,%r11 + movq %rbx,%r12 + shrq $26,%rdx + andq $0x3ffffff,%rax + shlq $12,%r11 + andq $0x3ffffff,%rdx + shrq $14,%rbx + orq %r11,%r14 + shlq $24,%rbp + andq $0x3ffffff,%r14 + shrq $40,%r12 + andq $0x3ffffff,%rbx + orq %r12,%rbp + + subq $16,%r15 + jz .Lstore_base2_26_avx + + vmovd %eax,%xmm0 + vmovd %edx,%xmm1 + vmovd %r14d,%xmm2 + vmovd %ebx,%xmm3 + vmovd %ebp,%xmm4 + jmp .Lproceed_avx + +.align 32 +.Lstore_base2_64_avx: + movq %r14,0(%rdi) + movq %rbx,8(%rdi) + movq %rbp,16(%rdi) + jmp .Ldone_avx + +.align 16 +.Lstore_base2_26_avx: + movl %eax,0(%rdi) + movl %edx,4(%rdi) + movl %r14d,8(%rdi) + movl %ebx,12(%rdi) + movl %ebp,16(%rdi) +.align 16 +.Ldone_avx: + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbp +.cfi_restore %rbp + movq 40(%rsp),%rbx +.cfi_restore %rbx + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lno_data_avx: +.Lblocks_avx_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc + +.align 32 +.Lbase2_64_avx: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lbase2_64_avx_body: + + movq %rdx,%r15 + + movq 24(%rdi),%r11 + movq 32(%rdi),%r13 + + movq 0(%rdi),%r14 + movq 8(%rdi),%rbx + movl 16(%rdi),%ebp + + movq %r13,%r12 + movq %r13,%rax + shrq $2,%r13 + addq %r12,%r13 + + testq $31,%rdx + jz .Linit_avx + + addq 0(%rsi),%r14 + adcq 8(%rsi),%rbx + leaq 16(%rsi),%rsi + adcq %rcx,%rbp + subq $16,%r15 + + call __poly1305_block + +.Linit_avx: + + movq %r14,%rax + movq %r14,%rdx + shrq $52,%r14 + movq %rbx,%r8 + movq %rbx,%r9 + shrq $26,%rdx + andq $0x3ffffff,%rax + shlq $12,%r8 + andq $0x3ffffff,%rdx + shrq $14,%rbx + orq %r8,%r14 + shlq $24,%rbp + andq $0x3ffffff,%r14 + shrq $40,%r9 + andq $0x3ffffff,%rbx + orq %r9,%rbp + + vmovd %eax,%xmm0 + vmovd %edx,%xmm1 + vmovd %r14d,%xmm2 + vmovd %ebx,%xmm3 + vmovd %ebp,%xmm4 + movl $1,20(%rdi) + + call __poly1305_init_avx + +.Lproceed_avx: + movq %r15,%rdx + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbp +.cfi_restore %rbp + movq 40(%rsp),%rbx +.cfi_restore %rbx + leaq 48(%rsp),%rax + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lbase2_64_avx_epilogue: + jmp .Ldo_avx +.cfi_endproc + +.align 32 +.Leven_avx: +.cfi_startproc + vmovd 0(%rdi),%xmm0 + vmovd 4(%rdi),%xmm1 + vmovd 8(%rdi),%xmm2 + vmovd 12(%rdi),%xmm3 + vmovd 16(%rdi),%xmm4 + +.Ldo_avx: + leaq -88(%rsp),%r11 +.cfi_def_cfa %r11,0x60 + subq $0x178,%rsp + subq $64,%rdx + leaq -32(%rsi),%rax + cmovcq %rax,%rsi + + vmovdqu 48(%rdi),%xmm14 + leaq 112(%rdi),%rdi + leaq .Lconst(%rip),%rcx + + + + vmovdqu 32(%rsi),%xmm5 + vmovdqu 48(%rsi),%xmm6 + vmovdqa 64(%rcx),%xmm15 + + vpsrldq $6,%xmm5,%xmm7 + vpsrldq $6,%xmm6,%xmm8 + vpunpckhqdq %xmm6,%xmm5,%xmm9 + vpunpcklqdq %xmm6,%xmm5,%xmm5 + vpunpcklqdq %xmm8,%xmm7,%xmm8 + + vpsrlq $40,%xmm9,%xmm9 + vpsrlq $26,%xmm5,%xmm6 + vpand %xmm15,%xmm5,%xmm5 + vpsrlq $4,%xmm8,%xmm7 + vpand %xmm15,%xmm6,%xmm6 + vpsrlq $30,%xmm8,%xmm8 + vpand %xmm15,%xmm7,%xmm7 + vpand %xmm15,%xmm8,%xmm8 + vpor 32(%rcx),%xmm9,%xmm9 + + jbe .Lskip_loop_avx + + + vmovdqu -48(%rdi),%xmm11 + vmovdqu -32(%rdi),%xmm12 + vpshufd $0xEE,%xmm14,%xmm13 + vpshufd $0x44,%xmm14,%xmm10 + vmovdqa %xmm13,-144(%r11) + vmovdqa %xmm10,0(%rsp) + vpshufd $0xEE,%xmm11,%xmm14 + vmovdqu -16(%rdi),%xmm10 + vpshufd $0x44,%xmm11,%xmm11 + vmovdqa %xmm14,-128(%r11) + vmovdqa %xmm11,16(%rsp) + vpshufd $0xEE,%xmm12,%xmm13 + vmovdqu 0(%rdi),%xmm11 + vpshufd $0x44,%xmm12,%xmm12 + vmovdqa %xmm13,-112(%r11) + vmovdqa %xmm12,32(%rsp) + vpshufd $0xEE,%xmm10,%xmm14 + vmovdqu 16(%rdi),%xmm12 + vpshufd $0x44,%xmm10,%xmm10 + vmovdqa %xmm14,-96(%r11) + vmovdqa %xmm10,48(%rsp) + vpshufd $0xEE,%xmm11,%xmm13 + vmovdqu 32(%rdi),%xmm10 + vpshufd $0x44,%xmm11,%xmm11 + vmovdqa %xmm13,-80(%r11) + vmovdqa %xmm11,64(%rsp) + vpshufd $0xEE,%xmm12,%xmm14 + vmovdqu 48(%rdi),%xmm11 + vpshufd $0x44,%xmm12,%xmm12 + vmovdqa %xmm14,-64(%r11) + vmovdqa %xmm12,80(%rsp) + vpshufd $0xEE,%xmm10,%xmm13 + vmovdqu 64(%rdi),%xmm12 + vpshufd $0x44,%xmm10,%xmm10 + vmovdqa %xmm13,-48(%r11) + vmovdqa %xmm10,96(%rsp) + vpshufd $0xEE,%xmm11,%xmm14 + vpshufd $0x44,%xmm11,%xmm11 + vmovdqa %xmm14,-32(%r11) + vmovdqa %xmm11,112(%rsp) + vpshufd $0xEE,%xmm12,%xmm13 + vmovdqa 0(%rsp),%xmm14 + vpshufd $0x44,%xmm12,%xmm12 + vmovdqa %xmm13,-16(%r11) + vmovdqa %xmm12,128(%rsp) + + jmp .Loop_avx + +.align 32 +.Loop_avx: + + + + + + + + + + + + + + + + + + + + + vpmuludq %xmm5,%xmm14,%xmm10 + vpmuludq %xmm6,%xmm14,%xmm11 + vmovdqa %xmm2,32(%r11) + vpmuludq %xmm7,%xmm14,%xmm12 + vmovdqa 16(%rsp),%xmm2 + vpmuludq %xmm8,%xmm14,%xmm13 + vpmuludq %xmm9,%xmm14,%xmm14 + + vmovdqa %xmm0,0(%r11) + vpmuludq 32(%rsp),%xmm9,%xmm0 + vmovdqa %xmm1,16(%r11) + vpmuludq %xmm8,%xmm2,%xmm1 + vpaddq %xmm0,%xmm10,%xmm10 + vpaddq %xmm1,%xmm14,%xmm14 + vmovdqa %xmm3,48(%r11) + vpmuludq %xmm7,%xmm2,%xmm0 + vpmuludq %xmm6,%xmm2,%xmm1 + vpaddq %xmm0,%xmm13,%xmm13 + vmovdqa 48(%rsp),%xmm3 + vpaddq %xmm1,%xmm12,%xmm12 + vmovdqa %xmm4,64(%r11) + vpmuludq %xmm5,%xmm2,%xmm2 + vpmuludq %xmm7,%xmm3,%xmm0 + vpaddq %xmm2,%xmm11,%xmm11 + + vmovdqa 64(%rsp),%xmm4 + vpaddq %xmm0,%xmm14,%xmm14 + vpmuludq %xmm6,%xmm3,%xmm1 + vpmuludq %xmm5,%xmm3,%xmm3 + vpaddq %xmm1,%xmm13,%xmm13 + vmovdqa 80(%rsp),%xmm2 + vpaddq %xmm3,%xmm12,%xmm12 + vpmuludq %xmm9,%xmm4,%xmm0 + vpmuludq %xmm8,%xmm4,%xmm4 + vpaddq %xmm0,%xmm11,%xmm11 + vmovdqa 96(%rsp),%xmm3 + vpaddq %xmm4,%xmm10,%xmm10 + + vmovdqa 128(%rsp),%xmm4 + vpmuludq %xmm6,%xmm2,%xmm1 + vpmuludq %xmm5,%xmm2,%xmm2 + vpaddq %xmm1,%xmm14,%xmm14 + vpaddq %xmm2,%xmm13,%xmm13 + vpmuludq %xmm9,%xmm3,%xmm0 + vpmuludq %xmm8,%xmm3,%xmm1 + vpaddq %xmm0,%xmm12,%xmm12 + vmovdqu 0(%rsi),%xmm0 + vpaddq %xmm1,%xmm11,%xmm11 + vpmuludq %xmm7,%xmm3,%xmm3 + vpmuludq %xmm7,%xmm4,%xmm7 + vpaddq %xmm3,%xmm10,%xmm10 + + vmovdqu 16(%rsi),%xmm1 + vpaddq %xmm7,%xmm11,%xmm11 + vpmuludq %xmm8,%xmm4,%xmm8 + vpmuludq %xmm9,%xmm4,%xmm9 + vpsrldq $6,%xmm0,%xmm2 + vpaddq %xmm8,%xmm12,%xmm12 + vpaddq %xmm9,%xmm13,%xmm13 + vpsrldq $6,%xmm1,%xmm3 + vpmuludq 112(%rsp),%xmm5,%xmm9 + vpmuludq %xmm6,%xmm4,%xmm5 + vpunpckhqdq %xmm1,%xmm0,%xmm4 + vpaddq %xmm9,%xmm14,%xmm14 + vmovdqa -144(%r11),%xmm9 + vpaddq %xmm5,%xmm10,%xmm10 + + vpunpcklqdq %xmm1,%xmm0,%xmm0 + vpunpcklqdq %xmm3,%xmm2,%xmm3 + + + vpsrldq $5,%xmm4,%xmm4 + vpsrlq $26,%xmm0,%xmm1 + vpand %xmm15,%xmm0,%xmm0 + vpsrlq $4,%xmm3,%xmm2 + vpand %xmm15,%xmm1,%xmm1 + vpand 0(%rcx),%xmm4,%xmm4 + vpsrlq $30,%xmm3,%xmm3 + vpand %xmm15,%xmm2,%xmm2 + vpand %xmm15,%xmm3,%xmm3 + vpor 32(%rcx),%xmm4,%xmm4 + + vpaddq 0(%r11),%xmm0,%xmm0 + vpaddq 16(%r11),%xmm1,%xmm1 + vpaddq 32(%r11),%xmm2,%xmm2 + vpaddq 48(%r11),%xmm3,%xmm3 + vpaddq 64(%r11),%xmm4,%xmm4 + + leaq 32(%rsi),%rax + leaq 64(%rsi),%rsi + subq $64,%rdx + cmovcq %rax,%rsi + + + + + + + + + + + vpmuludq %xmm0,%xmm9,%xmm5 + vpmuludq %xmm1,%xmm9,%xmm6 + vpaddq %xmm5,%xmm10,%xmm10 + vpaddq %xmm6,%xmm11,%xmm11 + vmovdqa -128(%r11),%xmm7 + vpmuludq %xmm2,%xmm9,%xmm5 + vpmuludq %xmm3,%xmm9,%xmm6 + vpaddq %xmm5,%xmm12,%xmm12 + vpaddq %xmm6,%xmm13,%xmm13 + vpmuludq %xmm4,%xmm9,%xmm9 + vpmuludq -112(%r11),%xmm4,%xmm5 + vpaddq %xmm9,%xmm14,%xmm14 + + vpaddq %xmm5,%xmm10,%xmm10 + vpmuludq %xmm2,%xmm7,%xmm6 + vpmuludq %xmm3,%xmm7,%xmm5 + vpaddq %xmm6,%xmm13,%xmm13 + vmovdqa -96(%r11),%xmm8 + vpaddq %xmm5,%xmm14,%xmm14 + vpmuludq %xmm1,%xmm7,%xmm6 + vpmuludq %xmm0,%xmm7,%xmm7 + vpaddq %xmm6,%xmm12,%xmm12 + vpaddq %xmm7,%xmm11,%xmm11 + + vmovdqa -80(%r11),%xmm9 + vpmuludq %xmm2,%xmm8,%xmm5 + vpmuludq %xmm1,%xmm8,%xmm6 + vpaddq %xmm5,%xmm14,%xmm14 + vpaddq %xmm6,%xmm13,%xmm13 + vmovdqa -64(%r11),%xmm7 + vpmuludq %xmm0,%xmm8,%xmm8 + vpmuludq %xmm4,%xmm9,%xmm5 + vpaddq %xmm8,%xmm12,%xmm12 + vpaddq %xmm5,%xmm11,%xmm11 + vmovdqa -48(%r11),%xmm8 + vpmuludq %xmm3,%xmm9,%xmm9 + vpmuludq %xmm1,%xmm7,%xmm6 + vpaddq %xmm9,%xmm10,%xmm10 + + vmovdqa -16(%r11),%xmm9 + vpaddq %xmm6,%xmm14,%xmm14 + vpmuludq %xmm0,%xmm7,%xmm7 + vpmuludq %xmm4,%xmm8,%xmm5 + vpaddq %xmm7,%xmm13,%xmm13 + vpaddq %xmm5,%xmm12,%xmm12 + vmovdqu 32(%rsi),%xmm5 + vpmuludq %xmm3,%xmm8,%xmm7 + vpmuludq %xmm2,%xmm8,%xmm8 + vpaddq %xmm7,%xmm11,%xmm11 + vmovdqu 48(%rsi),%xmm6 + vpaddq %xmm8,%xmm10,%xmm10 + + vpmuludq %xmm2,%xmm9,%xmm2 + vpmuludq %xmm3,%xmm9,%xmm3 + vpsrldq $6,%xmm5,%xmm7 + vpaddq %xmm2,%xmm11,%xmm11 + vpmuludq %xmm4,%xmm9,%xmm4 + vpsrldq $6,%xmm6,%xmm8 + vpaddq %xmm3,%xmm12,%xmm2 + vpaddq %xmm4,%xmm13,%xmm3 + vpmuludq -32(%r11),%xmm0,%xmm4 + vpmuludq %xmm1,%xmm9,%xmm0 + vpunpckhqdq %xmm6,%xmm5,%xmm9 + vpaddq %xmm4,%xmm14,%xmm4 + vpaddq %xmm0,%xmm10,%xmm0 + + vpunpcklqdq %xmm6,%xmm5,%xmm5 + vpunpcklqdq %xmm8,%xmm7,%xmm8 + + + vpsrldq $5,%xmm9,%xmm9 + vpsrlq $26,%xmm5,%xmm6 + vmovdqa 0(%rsp),%xmm14 + vpand %xmm15,%xmm5,%xmm5 + vpsrlq $4,%xmm8,%xmm7 + vpand %xmm15,%xmm6,%xmm6 + vpand 0(%rcx),%xmm9,%xmm9 + vpsrlq $30,%xmm8,%xmm8 + vpand %xmm15,%xmm7,%xmm7 + vpand %xmm15,%xmm8,%xmm8 + vpor 32(%rcx),%xmm9,%xmm9 + + + + + + vpsrlq $26,%xmm3,%xmm13 + vpand %xmm15,%xmm3,%xmm3 + vpaddq %xmm13,%xmm4,%xmm4 + + vpsrlq $26,%xmm0,%xmm10 + vpand %xmm15,%xmm0,%xmm0 + vpaddq %xmm10,%xmm11,%xmm1 + + vpsrlq $26,%xmm4,%xmm10 + vpand %xmm15,%xmm4,%xmm4 + + vpsrlq $26,%xmm1,%xmm11 + vpand %xmm15,%xmm1,%xmm1 + vpaddq %xmm11,%xmm2,%xmm2 + + vpaddq %xmm10,%xmm0,%xmm0 + vpsllq $2,%xmm10,%xmm10 + vpaddq %xmm10,%xmm0,%xmm0 + + vpsrlq $26,%xmm2,%xmm12 + vpand %xmm15,%xmm2,%xmm2 + vpaddq %xmm12,%xmm3,%xmm3 + + vpsrlq $26,%xmm0,%xmm10 + vpand %xmm15,%xmm0,%xmm0 + vpaddq %xmm10,%xmm1,%xmm1 + + vpsrlq $26,%xmm3,%xmm13 + vpand %xmm15,%xmm3,%xmm3 + vpaddq %xmm13,%xmm4,%xmm4 + + ja .Loop_avx + +.Lskip_loop_avx: + + + + vpshufd $0x10,%xmm14,%xmm14 + addq $32,%rdx + jnz .Long_tail_avx + + vpaddq %xmm2,%xmm7,%xmm7 + vpaddq %xmm0,%xmm5,%xmm5 + vpaddq %xmm1,%xmm6,%xmm6 + vpaddq %xmm3,%xmm8,%xmm8 + vpaddq %xmm4,%xmm9,%xmm9 + +.Long_tail_avx: + vmovdqa %xmm2,32(%r11) + vmovdqa %xmm0,0(%r11) + vmovdqa %xmm1,16(%r11) + vmovdqa %xmm3,48(%r11) + vmovdqa %xmm4,64(%r11) + + + + + + + + vpmuludq %xmm7,%xmm14,%xmm12 + vpmuludq %xmm5,%xmm14,%xmm10 + vpshufd $0x10,-48(%rdi),%xmm2 + vpmuludq %xmm6,%xmm14,%xmm11 + vpmuludq %xmm8,%xmm14,%xmm13 + vpmuludq %xmm9,%xmm14,%xmm14 + + vpmuludq %xmm8,%xmm2,%xmm0 + vpaddq %xmm0,%xmm14,%xmm14 + vpshufd $0x10,-32(%rdi),%xmm3 + vpmuludq %xmm7,%xmm2,%xmm1 + vpaddq %xmm1,%xmm13,%xmm13 + vpshufd $0x10,-16(%rdi),%xmm4 + vpmuludq %xmm6,%xmm2,%xmm0 + vpaddq %xmm0,%xmm12,%xmm12 + vpmuludq %xmm5,%xmm2,%xmm2 + vpaddq %xmm2,%xmm11,%xmm11 + vpmuludq %xmm9,%xmm3,%xmm3 + vpaddq %xmm3,%xmm10,%xmm10 + + vpshufd $0x10,0(%rdi),%xmm2 + vpmuludq %xmm7,%xmm4,%xmm1 + vpaddq %xmm1,%xmm14,%xmm14 + vpmuludq %xmm6,%xmm4,%xmm0 + vpaddq %xmm0,%xmm13,%xmm13 + vpshufd $0x10,16(%rdi),%xmm3 + vpmuludq %xmm5,%xmm4,%xmm4 + vpaddq %xmm4,%xmm12,%xmm12 + vpmuludq %xmm9,%xmm2,%xmm1 + vpaddq %xmm1,%xmm11,%xmm11 + vpshufd $0x10,32(%rdi),%xmm4 + vpmuludq %xmm8,%xmm2,%xmm2 + vpaddq %xmm2,%xmm10,%xmm10 + + vpmuludq %xmm6,%xmm3,%xmm0 + vpaddq %xmm0,%xmm14,%xmm14 + vpmuludq %xmm5,%xmm3,%xmm3 + vpaddq %xmm3,%xmm13,%xmm13 + vpshufd $0x10,48(%rdi),%xmm2 + vpmuludq %xmm9,%xmm4,%xmm1 + vpaddq %xmm1,%xmm12,%xmm12 + vpshufd $0x10,64(%rdi),%xmm3 + vpmuludq %xmm8,%xmm4,%xmm0 + vpaddq %xmm0,%xmm11,%xmm11 + vpmuludq %xmm7,%xmm4,%xmm4 + vpaddq %xmm4,%xmm10,%xmm10 + + vpmuludq %xmm5,%xmm2,%xmm2 + vpaddq %xmm2,%xmm14,%xmm14 + vpmuludq %xmm9,%xmm3,%xmm1 + vpaddq %xmm1,%xmm13,%xmm13 + vpmuludq %xmm8,%xmm3,%xmm0 + vpaddq %xmm0,%xmm12,%xmm12 + vpmuludq %xmm7,%xmm3,%xmm1 + vpaddq %xmm1,%xmm11,%xmm11 + vpmuludq %xmm6,%xmm3,%xmm3 + vpaddq %xmm3,%xmm10,%xmm10 + + jz .Lshort_tail_avx + + vmovdqu 0(%rsi),%xmm0 + vmovdqu 16(%rsi),%xmm1 + + vpsrldq $6,%xmm0,%xmm2 + vpsrldq $6,%xmm1,%xmm3 + vpunpckhqdq %xmm1,%xmm0,%xmm4 + vpunpcklqdq %xmm1,%xmm0,%xmm0 + vpunpcklqdq %xmm3,%xmm2,%xmm3 + + vpsrlq $40,%xmm4,%xmm4 + vpsrlq $26,%xmm0,%xmm1 + vpand %xmm15,%xmm0,%xmm0 + vpsrlq $4,%xmm3,%xmm2 + vpand %xmm15,%xmm1,%xmm1 + vpsrlq $30,%xmm3,%xmm3 + vpand %xmm15,%xmm2,%xmm2 + vpand %xmm15,%xmm3,%xmm3 + vpor 32(%rcx),%xmm4,%xmm4 + + vpshufd $0x32,-64(%rdi),%xmm9 + vpaddq 0(%r11),%xmm0,%xmm0 + vpaddq 16(%r11),%xmm1,%xmm1 + vpaddq 32(%r11),%xmm2,%xmm2 + vpaddq 48(%r11),%xmm3,%xmm3 + vpaddq 64(%r11),%xmm4,%xmm4 + + + + + vpmuludq %xmm0,%xmm9,%xmm5 + vpaddq %xmm5,%xmm10,%xmm10 + vpmuludq %xmm1,%xmm9,%xmm6 + vpaddq %xmm6,%xmm11,%xmm11 + vpmuludq %xmm2,%xmm9,%xmm5 + vpaddq %xmm5,%xmm12,%xmm12 + vpshufd $0x32,-48(%rdi),%xmm7 + vpmuludq %xmm3,%xmm9,%xmm6 + vpaddq %xmm6,%xmm13,%xmm13 + vpmuludq %xmm4,%xmm9,%xmm9 + vpaddq %xmm9,%xmm14,%xmm14 + + vpmuludq %xmm3,%xmm7,%xmm5 + vpaddq %xmm5,%xmm14,%xmm14 + vpshufd $0x32,-32(%rdi),%xmm8 + vpmuludq %xmm2,%xmm7,%xmm6 + vpaddq %xmm6,%xmm13,%xmm13 + vpshufd $0x32,-16(%rdi),%xmm9 + vpmuludq %xmm1,%xmm7,%xmm5 + vpaddq %xmm5,%xmm12,%xmm12 + vpmuludq %xmm0,%xmm7,%xmm7 + vpaddq %xmm7,%xmm11,%xmm11 + vpmuludq %xmm4,%xmm8,%xmm8 + vpaddq %xmm8,%xmm10,%xmm10 + + vpshufd $0x32,0(%rdi),%xmm7 + vpmuludq %xmm2,%xmm9,%xmm6 + vpaddq %xmm6,%xmm14,%xmm14 + vpmuludq %xmm1,%xmm9,%xmm5 + vpaddq %xmm5,%xmm13,%xmm13 + vpshufd $0x32,16(%rdi),%xmm8 + vpmuludq %xmm0,%xmm9,%xmm9 + vpaddq %xmm9,%xmm12,%xmm12 + vpmuludq %xmm4,%xmm7,%xmm6 + vpaddq %xmm6,%xmm11,%xmm11 + vpshufd $0x32,32(%rdi),%xmm9 + vpmuludq %xmm3,%xmm7,%xmm7 + vpaddq %xmm7,%xmm10,%xmm10 + + vpmuludq %xmm1,%xmm8,%xmm5 + vpaddq %xmm5,%xmm14,%xmm14 + vpmuludq %xmm0,%xmm8,%xmm8 + vpaddq %xmm8,%xmm13,%xmm13 + vpshufd $0x32,48(%rdi),%xmm7 + vpmuludq %xmm4,%xmm9,%xmm6 + vpaddq %xmm6,%xmm12,%xmm12 + vpshufd $0x32,64(%rdi),%xmm8 + vpmuludq %xmm3,%xmm9,%xmm5 + vpaddq %xmm5,%xmm11,%xmm11 + vpmuludq %xmm2,%xmm9,%xmm9 + vpaddq %xmm9,%xmm10,%xmm10 + + vpmuludq %xmm0,%xmm7,%xmm7 + vpaddq %xmm7,%xmm14,%xmm14 + vpmuludq %xmm4,%xmm8,%xmm6 + vpaddq %xmm6,%xmm13,%xmm13 + vpmuludq %xmm3,%xmm8,%xmm5 + vpaddq %xmm5,%xmm12,%xmm12 + vpmuludq %xmm2,%xmm8,%xmm6 + vpaddq %xmm6,%xmm11,%xmm11 + vpmuludq %xmm1,%xmm8,%xmm8 + vpaddq %xmm8,%xmm10,%xmm10 + +.Lshort_tail_avx: + + + + vpsrldq $8,%xmm14,%xmm9 + vpsrldq $8,%xmm13,%xmm8 + vpsrldq $8,%xmm11,%xmm6 + vpsrldq $8,%xmm10,%xmm5 + vpsrldq $8,%xmm12,%xmm7 + vpaddq %xmm8,%xmm13,%xmm13 + vpaddq %xmm9,%xmm14,%xmm14 + vpaddq %xmm5,%xmm10,%xmm10 + vpaddq %xmm6,%xmm11,%xmm11 + vpaddq %xmm7,%xmm12,%xmm12 + + + + + vpsrlq $26,%xmm13,%xmm3 + vpand %xmm15,%xmm13,%xmm13 + vpaddq %xmm3,%xmm14,%xmm14 + + vpsrlq $26,%xmm10,%xmm0 + vpand %xmm15,%xmm10,%xmm10 + vpaddq %xmm0,%xmm11,%xmm11 + + vpsrlq $26,%xmm14,%xmm4 + vpand %xmm15,%xmm14,%xmm14 + + vpsrlq $26,%xmm11,%xmm1 + vpand %xmm15,%xmm11,%xmm11 + vpaddq %xmm1,%xmm12,%xmm12 + + vpaddq %xmm4,%xmm10,%xmm10 + vpsllq $2,%xmm4,%xmm4 + vpaddq %xmm4,%xmm10,%xmm10 + + vpsrlq $26,%xmm12,%xmm2 + vpand %xmm15,%xmm12,%xmm12 + vpaddq %xmm2,%xmm13,%xmm13 + + vpsrlq $26,%xmm10,%xmm0 + vpand %xmm15,%xmm10,%xmm10 + vpaddq %xmm0,%xmm11,%xmm11 + + vpsrlq $26,%xmm13,%xmm3 + vpand %xmm15,%xmm13,%xmm13 + vpaddq %xmm3,%xmm14,%xmm14 + + vmovd %xmm10,-112(%rdi) + vmovd %xmm11,-108(%rdi) + vmovd %xmm12,-104(%rdi) + vmovd %xmm13,-100(%rdi) + vmovd %xmm14,-96(%rdi) + leaq 88(%r11),%rsp +.cfi_def_cfa %rsp,8 + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.size poly1305_blocks_avx,.-poly1305_blocks_avx + +.type poly1305_emit_avx,@function +.align 32 +poly1305_emit_avx: +.cfi_startproc + cmpl $0,20(%rdi) + je .Lemit + + movl 0(%rdi),%eax + movl 4(%rdi),%ecx + movl 8(%rdi),%r8d + movl 12(%rdi),%r11d + movl 16(%rdi),%r10d + + shlq $26,%rcx + movq %r8,%r9 + shlq $52,%r8 + addq %rcx,%rax + shrq $12,%r9 + addq %rax,%r8 + adcq $0,%r9 + + shlq $14,%r11 + movq %r10,%rax + shrq $24,%r10 + addq %r11,%r9 + shlq $40,%rax + addq %rax,%r9 + adcq $0,%r10 + + movq %r10,%rax + movq %r10,%rcx + andq $3,%r10 + shrq $2,%rax + andq $-4,%rcx + addq %rcx,%rax + addq %rax,%r8 + adcq $0,%r9 + adcq $0,%r10 + + movq %r8,%rax + addq $5,%r8 + movq %r9,%rcx + adcq $0,%r9 + adcq $0,%r10 + shrq $2,%r10 + cmovnzq %r8,%rax + cmovnzq %r9,%rcx + + addq 0(%rdx),%rax + adcq 8(%rdx),%rcx + movq %rax,0(%rsi) + movq %rcx,8(%rsi) + + .byte 0xf3,0xc3 +.cfi_endproc +.size poly1305_emit_avx,.-poly1305_emit_avx +.type poly1305_blocks_avx2,@function +.align 32 +poly1305_blocks_avx2: +.cfi_startproc + movl 20(%rdi),%r8d + cmpq $128,%rdx + jae .Lblocks_avx2 + testl %r8d,%r8d + jz .Lblocks + +.Lblocks_avx2: + andq $-16,%rdx + jz .Lno_data_avx2 + + vzeroupper + + testl %r8d,%r8d + jz .Lbase2_64_avx2 + + testq $63,%rdx + jz .Leven_avx2 + + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lblocks_avx2_body: + + movq %rdx,%r15 + + movq 0(%rdi),%r8 + movq 8(%rdi),%r9 + movl 16(%rdi),%ebp + + movq 24(%rdi),%r11 + movq 32(%rdi),%r13 + + + movl %r8d,%r14d + andq $-2147483648,%r8 + movq %r9,%r12 + movl %r9d,%ebx + andq $-2147483648,%r9 + + shrq $6,%r8 + shlq $52,%r12 + addq %r8,%r14 + shrq $12,%rbx + shrq $18,%r9 + addq %r12,%r14 + adcq %r9,%rbx + + movq %rbp,%r8 + shlq $40,%r8 + shrq $24,%rbp + addq %r8,%rbx + adcq $0,%rbp + + movq $-4,%r9 + movq %rbp,%r8 + andq %rbp,%r9 + shrq $2,%r8 + andq $3,%rbp + addq %r9,%r8 + addq %r8,%r14 + adcq $0,%rbx + adcq $0,%rbp + + movq %r13,%r12 + movq %r13,%rax + shrq $2,%r13 + addq %r12,%r13 + +.Lbase2_26_pre_avx2: + addq 0(%rsi),%r14 + adcq 8(%rsi),%rbx + leaq 16(%rsi),%rsi + adcq %rcx,%rbp + subq $16,%r15 + + call __poly1305_block + movq %r12,%rax + + testq $63,%r15 + jnz .Lbase2_26_pre_avx2 + + testq %rcx,%rcx + jz .Lstore_base2_64_avx2 + + + movq %r14,%rax + movq %r14,%rdx + shrq $52,%r14 + movq %rbx,%r11 + movq %rbx,%r12 + shrq $26,%rdx + andq $0x3ffffff,%rax + shlq $12,%r11 + andq $0x3ffffff,%rdx + shrq $14,%rbx + orq %r11,%r14 + shlq $24,%rbp + andq $0x3ffffff,%r14 + shrq $40,%r12 + andq $0x3ffffff,%rbx + orq %r12,%rbp + + testq %r15,%r15 + jz .Lstore_base2_26_avx2 + + vmovd %eax,%xmm0 + vmovd %edx,%xmm1 + vmovd %r14d,%xmm2 + vmovd %ebx,%xmm3 + vmovd %ebp,%xmm4 + jmp .Lproceed_avx2 + +.align 32 +.Lstore_base2_64_avx2: + movq %r14,0(%rdi) + movq %rbx,8(%rdi) + movq %rbp,16(%rdi) + jmp .Ldone_avx2 + +.align 16 +.Lstore_base2_26_avx2: + movl %eax,0(%rdi) + movl %edx,4(%rdi) + movl %r14d,8(%rdi) + movl %ebx,12(%rdi) + movl %ebp,16(%rdi) +.align 16 +.Ldone_avx2: + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbp +.cfi_restore %rbp + movq 40(%rsp),%rbx +.cfi_restore %rbx + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lno_data_avx2: +.Lblocks_avx2_epilogue: + .byte 0xf3,0xc3 +.cfi_endproc + +.align 32 +.Lbase2_64_avx2: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 +.Lbase2_64_avx2_body: + + movq %rdx,%r15 + + movq 24(%rdi),%r11 + movq 32(%rdi),%r13 + + movq 0(%rdi),%r14 + movq 8(%rdi),%rbx + movl 16(%rdi),%ebp + + movq %r13,%r12 + movq %r13,%rax + shrq $2,%r13 + addq %r12,%r13 + + testq $63,%rdx + jz .Linit_avx2 + +.Lbase2_64_pre_avx2: + addq 0(%rsi),%r14 + adcq 8(%rsi),%rbx + leaq 16(%rsi),%rsi + adcq %rcx,%rbp + subq $16,%r15 + + call __poly1305_block + movq %r12,%rax + + testq $63,%r15 + jnz .Lbase2_64_pre_avx2 + +.Linit_avx2: + + movq %r14,%rax + movq %r14,%rdx + shrq $52,%r14 + movq %rbx,%r8 + movq %rbx,%r9 + shrq $26,%rdx + andq $0x3ffffff,%rax + shlq $12,%r8 + andq $0x3ffffff,%rdx + shrq $14,%rbx + orq %r8,%r14 + shlq $24,%rbp + andq $0x3ffffff,%r14 + shrq $40,%r9 + andq $0x3ffffff,%rbx + orq %r9,%rbp + + vmovd %eax,%xmm0 + vmovd %edx,%xmm1 + vmovd %r14d,%xmm2 + vmovd %ebx,%xmm3 + vmovd %ebp,%xmm4 + movl $1,20(%rdi) + + call __poly1305_init_avx + +.Lproceed_avx2: + movq %r15,%rdx + movl OPENSSL_ia32cap_P+8(%rip),%r10d + movl $3221291008,%r11d + + movq 0(%rsp),%r15 +.cfi_restore %r15 + movq 8(%rsp),%r14 +.cfi_restore %r14 + movq 16(%rsp),%r13 +.cfi_restore %r13 + movq 24(%rsp),%r12 +.cfi_restore %r12 + movq 32(%rsp),%rbp +.cfi_restore %rbp + movq 40(%rsp),%rbx +.cfi_restore %rbx + leaq 48(%rsp),%rax + leaq 48(%rsp),%rsp +.cfi_adjust_cfa_offset -48 +.Lbase2_64_avx2_epilogue: + jmp .Ldo_avx2 +.cfi_endproc + +.align 32 +.Leven_avx2: +.cfi_startproc + movl OPENSSL_ia32cap_P+8(%rip),%r10d + vmovd 0(%rdi),%xmm0 + vmovd 4(%rdi),%xmm1 + vmovd 8(%rdi),%xmm2 + vmovd 12(%rdi),%xmm3 + vmovd 16(%rdi),%xmm4 + +.Ldo_avx2: + leaq -8(%rsp),%r11 +.cfi_def_cfa %r11,16 + subq $0x128,%rsp + leaq .Lconst(%rip),%rcx + leaq 48+64(%rdi),%rdi + vmovdqa 96(%rcx),%ymm7 + + + vmovdqu -64(%rdi),%xmm9 + andq $-512,%rsp + vmovdqu -48(%rdi),%xmm10 + vmovdqu -32(%rdi),%xmm6 + vmovdqu -16(%rdi),%xmm11 + vmovdqu 0(%rdi),%xmm12 + vmovdqu 16(%rdi),%xmm13 + leaq 144(%rsp),%rax + vmovdqu 32(%rdi),%xmm14 + vpermd %ymm9,%ymm7,%ymm9 + vmovdqu 48(%rdi),%xmm15 + vpermd %ymm10,%ymm7,%ymm10 + vmovdqu 64(%rdi),%xmm5 + vpermd %ymm6,%ymm7,%ymm6 + vmovdqa %ymm9,0(%rsp) + vpermd %ymm11,%ymm7,%ymm11 + vmovdqa %ymm10,32-144(%rax) + vpermd %ymm12,%ymm7,%ymm12 + vmovdqa %ymm6,64-144(%rax) + vpermd %ymm13,%ymm7,%ymm13 + vmovdqa %ymm11,96-144(%rax) + vpermd %ymm14,%ymm7,%ymm14 + vmovdqa %ymm12,128-144(%rax) + vpermd %ymm15,%ymm7,%ymm15 + vmovdqa %ymm13,160-144(%rax) + vpermd %ymm5,%ymm7,%ymm5 + vmovdqa %ymm14,192-144(%rax) + vmovdqa %ymm15,224-144(%rax) + vmovdqa %ymm5,256-144(%rax) + vmovdqa 64(%rcx),%ymm5 + + + + vmovdqu 0(%rsi),%xmm7 + vmovdqu 16(%rsi),%xmm8 + vinserti128 $1,32(%rsi),%ymm7,%ymm7 + vinserti128 $1,48(%rsi),%ymm8,%ymm8 + leaq 64(%rsi),%rsi + + vpsrldq $6,%ymm7,%ymm9 + vpsrldq $6,%ymm8,%ymm10 + vpunpckhqdq %ymm8,%ymm7,%ymm6 + vpunpcklqdq %ymm10,%ymm9,%ymm9 + vpunpcklqdq %ymm8,%ymm7,%ymm7 + + vpsrlq $30,%ymm9,%ymm10 + vpsrlq $4,%ymm9,%ymm9 + vpsrlq $26,%ymm7,%ymm8 + vpsrlq $40,%ymm6,%ymm6 + vpand %ymm5,%ymm9,%ymm9 + vpand %ymm5,%ymm7,%ymm7 + vpand %ymm5,%ymm8,%ymm8 + vpand %ymm5,%ymm10,%ymm10 + vpor 32(%rcx),%ymm6,%ymm6 + + vpaddq %ymm2,%ymm9,%ymm2 + subq $64,%rdx + jz .Ltail_avx2 + jmp .Loop_avx2 + +.align 32 +.Loop_avx2: + + + + + + + + + vpaddq %ymm0,%ymm7,%ymm0 + vmovdqa 0(%rsp),%ymm7 + vpaddq %ymm1,%ymm8,%ymm1 + vmovdqa 32(%rsp),%ymm8 + vpaddq %ymm3,%ymm10,%ymm3 + vmovdqa 96(%rsp),%ymm9 + vpaddq %ymm4,%ymm6,%ymm4 + vmovdqa 48(%rax),%ymm10 + vmovdqa 112(%rax),%ymm5 + + + + + + + + + + + + + + + + + vpmuludq %ymm2,%ymm7,%ymm13 + vpmuludq %ymm2,%ymm8,%ymm14 + vpmuludq %ymm2,%ymm9,%ymm15 + vpmuludq %ymm2,%ymm10,%ymm11 + vpmuludq %ymm2,%ymm5,%ymm12 + + vpmuludq %ymm0,%ymm8,%ymm6 + vpmuludq %ymm1,%ymm8,%ymm2 + vpaddq %ymm6,%ymm12,%ymm12 + vpaddq %ymm2,%ymm13,%ymm13 + vpmuludq %ymm3,%ymm8,%ymm6 + vpmuludq 64(%rsp),%ymm4,%ymm2 + vpaddq %ymm6,%ymm15,%ymm15 + vpaddq %ymm2,%ymm11,%ymm11 + vmovdqa -16(%rax),%ymm8 + + vpmuludq %ymm0,%ymm7,%ymm6 + vpmuludq %ymm1,%ymm7,%ymm2 + vpaddq %ymm6,%ymm11,%ymm11 + vpaddq %ymm2,%ymm12,%ymm12 + vpmuludq %ymm3,%ymm7,%ymm6 + vpmuludq %ymm4,%ymm7,%ymm2 + vmovdqu 0(%rsi),%xmm7 + vpaddq %ymm6,%ymm14,%ymm14 + vpaddq %ymm2,%ymm15,%ymm15 + vinserti128 $1,32(%rsi),%ymm7,%ymm7 + + vpmuludq %ymm3,%ymm8,%ymm6 + vpmuludq %ymm4,%ymm8,%ymm2 + vmovdqu 16(%rsi),%xmm8 + vpaddq %ymm6,%ymm11,%ymm11 + vpaddq %ymm2,%ymm12,%ymm12 + vmovdqa 16(%rax),%ymm2 + vpmuludq %ymm1,%ymm9,%ymm6 + vpmuludq %ymm0,%ymm9,%ymm9 + vpaddq %ymm6,%ymm14,%ymm14 + vpaddq %ymm9,%ymm13,%ymm13 + vinserti128 $1,48(%rsi),%ymm8,%ymm8 + leaq 64(%rsi),%rsi + + vpmuludq %ymm1,%ymm2,%ymm6 + vpmuludq %ymm0,%ymm2,%ymm2 + vpsrldq $6,%ymm7,%ymm9 + vpaddq %ymm6,%ymm15,%ymm15 + vpaddq %ymm2,%ymm14,%ymm14 + vpmuludq %ymm3,%ymm10,%ymm6 + vpmuludq %ymm4,%ymm10,%ymm2 + vpsrldq $6,%ymm8,%ymm10 + vpaddq %ymm6,%ymm12,%ymm12 + vpaddq %ymm2,%ymm13,%ymm13 + vpunpckhqdq %ymm8,%ymm7,%ymm6 + + vpmuludq %ymm3,%ymm5,%ymm3 + vpmuludq %ymm4,%ymm5,%ymm4 + vpunpcklqdq %ymm8,%ymm7,%ymm7 + vpaddq %ymm3,%ymm13,%ymm2 + vpaddq %ymm4,%ymm14,%ymm3 + vpunpcklqdq %ymm10,%ymm9,%ymm10 + vpmuludq 80(%rax),%ymm0,%ymm4 + vpmuludq %ymm1,%ymm5,%ymm0 + vmovdqa 64(%rcx),%ymm5 + vpaddq %ymm4,%ymm15,%ymm4 + vpaddq %ymm0,%ymm11,%ymm0 + + + + + vpsrlq $26,%ymm3,%ymm14 + vpand %ymm5,%ymm3,%ymm3 + vpaddq %ymm14,%ymm4,%ymm4 + + vpsrlq $26,%ymm0,%ymm11 + vpand %ymm5,%ymm0,%ymm0 + vpaddq %ymm11,%ymm12,%ymm1 + + vpsrlq $26,%ymm4,%ymm15 + vpand %ymm5,%ymm4,%ymm4 + + vpsrlq $4,%ymm10,%ymm9 + + vpsrlq $26,%ymm1,%ymm12 + vpand %ymm5,%ymm1,%ymm1 + vpaddq %ymm12,%ymm2,%ymm2 + + vpaddq %ymm15,%ymm0,%ymm0 + vpsllq $2,%ymm15,%ymm15 + vpaddq %ymm15,%ymm0,%ymm0 + + vpand %ymm5,%ymm9,%ymm9 + vpsrlq $26,%ymm7,%ymm8 + + vpsrlq $26,%ymm2,%ymm13 + vpand %ymm5,%ymm2,%ymm2 + vpaddq %ymm13,%ymm3,%ymm3 + + vpaddq %ymm9,%ymm2,%ymm2 + vpsrlq $30,%ymm10,%ymm10 + + vpsrlq $26,%ymm0,%ymm11 + vpand %ymm5,%ymm0,%ymm0 + vpaddq %ymm11,%ymm1,%ymm1 + + vpsrlq $40,%ymm6,%ymm6 + + vpsrlq $26,%ymm3,%ymm14 + vpand %ymm5,%ymm3,%ymm3 + vpaddq %ymm14,%ymm4,%ymm4 + + vpand %ymm5,%ymm7,%ymm7 + vpand %ymm5,%ymm8,%ymm8 + vpand %ymm5,%ymm10,%ymm10 + vpor 32(%rcx),%ymm6,%ymm6 + + subq $64,%rdx + jnz .Loop_avx2 + +.byte 0x66,0x90 +.Ltail_avx2: + + + + + + + + vpaddq %ymm0,%ymm7,%ymm0 + vmovdqu 4(%rsp),%ymm7 + vpaddq %ymm1,%ymm8,%ymm1 + vmovdqu 36(%rsp),%ymm8 + vpaddq %ymm3,%ymm10,%ymm3 + vmovdqu 100(%rsp),%ymm9 + vpaddq %ymm4,%ymm6,%ymm4 + vmovdqu 52(%rax),%ymm10 + vmovdqu 116(%rax),%ymm5 + + vpmuludq %ymm2,%ymm7,%ymm13 + vpmuludq %ymm2,%ymm8,%ymm14 + vpmuludq %ymm2,%ymm9,%ymm15 + vpmuludq %ymm2,%ymm10,%ymm11 + vpmuludq %ymm2,%ymm5,%ymm12 + + vpmuludq %ymm0,%ymm8,%ymm6 + vpmuludq %ymm1,%ymm8,%ymm2 + vpaddq %ymm6,%ymm12,%ymm12 + vpaddq %ymm2,%ymm13,%ymm13 + vpmuludq %ymm3,%ymm8,%ymm6 + vpmuludq 68(%rsp),%ymm4,%ymm2 + vpaddq %ymm6,%ymm15,%ymm15 + vpaddq %ymm2,%ymm11,%ymm11 + + vpmuludq %ymm0,%ymm7,%ymm6 + vpmuludq %ymm1,%ymm7,%ymm2 + vpaddq %ymm6,%ymm11,%ymm11 + vmovdqu -12(%rax),%ymm8 + vpaddq %ymm2,%ymm12,%ymm12 + vpmuludq %ymm3,%ymm7,%ymm6 + vpmuludq %ymm4,%ymm7,%ymm2 + vpaddq %ymm6,%ymm14,%ymm14 + vpaddq %ymm2,%ymm15,%ymm15 + + vpmuludq %ymm3,%ymm8,%ymm6 + vpmuludq %ymm4,%ymm8,%ymm2 + vpaddq %ymm6,%ymm11,%ymm11 + vpaddq %ymm2,%ymm12,%ymm12 + vmovdqu 20(%rax),%ymm2 + vpmuludq %ymm1,%ymm9,%ymm6 + vpmuludq %ymm0,%ymm9,%ymm9 + vpaddq %ymm6,%ymm14,%ymm14 + vpaddq %ymm9,%ymm13,%ymm13 + + vpmuludq %ymm1,%ymm2,%ymm6 + vpmuludq %ymm0,%ymm2,%ymm2 + vpaddq %ymm6,%ymm15,%ymm15 + vpaddq %ymm2,%ymm14,%ymm14 + vpmuludq %ymm3,%ymm10,%ymm6 + vpmuludq %ymm4,%ymm10,%ymm2 + vpaddq %ymm6,%ymm12,%ymm12 + vpaddq %ymm2,%ymm13,%ymm13 + + vpmuludq %ymm3,%ymm5,%ymm3 + vpmuludq %ymm4,%ymm5,%ymm4 + vpaddq %ymm3,%ymm13,%ymm2 + vpaddq %ymm4,%ymm14,%ymm3 + vpmuludq 84(%rax),%ymm0,%ymm4 + vpmuludq %ymm1,%ymm5,%ymm0 + vmovdqa 64(%rcx),%ymm5 + vpaddq %ymm4,%ymm15,%ymm4 + vpaddq %ymm0,%ymm11,%ymm0 + + + + + vpsrldq $8,%ymm12,%ymm8 + vpsrldq $8,%ymm2,%ymm9 + vpsrldq $8,%ymm3,%ymm10 + vpsrldq $8,%ymm4,%ymm6 + vpsrldq $8,%ymm0,%ymm7 + vpaddq %ymm8,%ymm12,%ymm12 + vpaddq %ymm9,%ymm2,%ymm2 + vpaddq %ymm10,%ymm3,%ymm3 + vpaddq %ymm6,%ymm4,%ymm4 + vpaddq %ymm7,%ymm0,%ymm0 + + vpermq $0x2,%ymm3,%ymm10 + vpermq $0x2,%ymm4,%ymm6 + vpermq $0x2,%ymm0,%ymm7 + vpermq $0x2,%ymm12,%ymm8 + vpermq $0x2,%ymm2,%ymm9 + vpaddq %ymm10,%ymm3,%ymm3 + vpaddq %ymm6,%ymm4,%ymm4 + vpaddq %ymm7,%ymm0,%ymm0 + vpaddq %ymm8,%ymm12,%ymm12 + vpaddq %ymm9,%ymm2,%ymm2 + + + + + vpsrlq $26,%ymm3,%ymm14 + vpand %ymm5,%ymm3,%ymm3 + vpaddq %ymm14,%ymm4,%ymm4 + + vpsrlq $26,%ymm0,%ymm11 + vpand %ymm5,%ymm0,%ymm0 + vpaddq %ymm11,%ymm12,%ymm1 + + vpsrlq $26,%ymm4,%ymm15 + vpand %ymm5,%ymm4,%ymm4 + + vpsrlq $26,%ymm1,%ymm12 + vpand %ymm5,%ymm1,%ymm1 + vpaddq %ymm12,%ymm2,%ymm2 + + vpaddq %ymm15,%ymm0,%ymm0 + vpsllq $2,%ymm15,%ymm15 + vpaddq %ymm15,%ymm0,%ymm0 + + vpsrlq $26,%ymm2,%ymm13 + vpand %ymm5,%ymm2,%ymm2 + vpaddq %ymm13,%ymm3,%ymm3 + + vpsrlq $26,%ymm0,%ymm11 + vpand %ymm5,%ymm0,%ymm0 + vpaddq %ymm11,%ymm1,%ymm1 + + vpsrlq $26,%ymm3,%ymm14 + vpand %ymm5,%ymm3,%ymm3 + vpaddq %ymm14,%ymm4,%ymm4 + + vmovd %xmm0,-112(%rdi) + vmovd %xmm1,-108(%rdi) + vmovd %xmm2,-104(%rdi) + vmovd %xmm3,-100(%rdi) + vmovd %xmm4,-96(%rdi) + leaq 8(%r11),%rsp +.cfi_def_cfa %rsp,8 + vzeroupper + .byte 0xf3,0xc3 +.cfi_endproc +.size poly1305_blocks_avx2,.-poly1305_blocks_avx2 +.align 64 +.Lconst: +.Lmask24: +.long 0x0ffffff,0,0x0ffffff,0,0x0ffffff,0,0x0ffffff,0 +.L129: +.long 16777216,0,16777216,0,16777216,0,16777216,0 +.Lmask26: +.long 0x3ffffff,0,0x3ffffff,0,0x3ffffff,0,0x3ffffff,0 +.Lpermd_avx2: +.long 2,2,2,3,2,0,2,1 +.Lpermd_avx512: +.long 0,0,0,1, 0,2,0,3, 0,4,0,5, 0,6,0,7 + +.L2_44_inp_permd: +.long 0,1,1,2,2,3,7,7 +.L2_44_inp_shift: +.quad 0,12,24,64 +.L2_44_mask: +.quad 0xfffffffffff,0xfffffffffff,0x3ffffffffff,0xffffffffffffffff +.L2_44_shift_rgt: +.quad 44,44,42,64 +.L2_44_shift_lft: +.quad 8,8,10,64 + +.align 64 +.Lx_mask44: +.quad 0xfffffffffff,0xfffffffffff,0xfffffffffff,0xfffffffffff +.quad 0xfffffffffff,0xfffffffffff,0xfffffffffff,0xfffffffffff +.Lx_mask42: +.quad 0x3ffffffffff,0x3ffffffffff,0x3ffffffffff,0x3ffffffffff +.quad 0x3ffffffffff,0x3ffffffffff,0x3ffffffffff,0x3ffffffffff +.byte 80,111,108,121,49,51,48,53,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 16 +.globl xor128_encrypt_n_pad +.type xor128_encrypt_n_pad,@function +.align 16 +xor128_encrypt_n_pad: +.cfi_startproc + subq %rdx,%rsi + subq %rdx,%rdi + movq %rcx,%r10 + shrq $4,%rcx + jz .Ltail_enc + nop +.Loop_enc_xmm: + movdqu (%rsi,%rdx,1),%xmm0 + pxor (%rdx),%xmm0 + movdqu %xmm0,(%rdi,%rdx,1) + movdqa %xmm0,(%rdx) + leaq 16(%rdx),%rdx + decq %rcx + jnz .Loop_enc_xmm + + andq $15,%r10 + jz .Ldone_enc + +.Ltail_enc: + movq $16,%rcx + subq %r10,%rcx + xorl %eax,%eax +.Loop_enc_byte: + movb (%rsi,%rdx,1),%al + xorb (%rdx),%al + movb %al,(%rdi,%rdx,1) + movb %al,(%rdx) + leaq 1(%rdx),%rdx + decq %r10 + jnz .Loop_enc_byte + + xorl %eax,%eax +.Loop_enc_pad: + movb %al,(%rdx) + leaq 1(%rdx),%rdx + decq %rcx + jnz .Loop_enc_pad + +.Ldone_enc: + movq %rdx,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size xor128_encrypt_n_pad,.-xor128_encrypt_n_pad + +.globl xor128_decrypt_n_pad +.type xor128_decrypt_n_pad,@function +.align 16 +xor128_decrypt_n_pad: +.cfi_startproc + subq %rdx,%rsi + subq %rdx,%rdi + movq %rcx,%r10 + shrq $4,%rcx + jz .Ltail_dec + nop +.Loop_dec_xmm: + movdqu (%rsi,%rdx,1),%xmm0 + movdqa (%rdx),%xmm1 + pxor %xmm0,%xmm1 + movdqu %xmm1,(%rdi,%rdx,1) + movdqa %xmm0,(%rdx) + leaq 16(%rdx),%rdx + decq %rcx + jnz .Loop_dec_xmm + + pxor %xmm1,%xmm1 + andq $15,%r10 + jz .Ldone_dec + +.Ltail_dec: + movq $16,%rcx + subq %r10,%rcx + xorl %eax,%eax + xorq %r11,%r11 +.Loop_dec_byte: + movb (%rsi,%rdx,1),%r11b + movb (%rdx),%al + xorb %r11b,%al + movb %al,(%rdi,%rdx,1) + movb %r11b,(%rdx) + leaq 1(%rdx),%rdx + decq %r10 + jnz .Loop_dec_byte + + xorl %eax,%eax +.Loop_dec_pad: + movb %al,(%rdx) + leaq 1(%rdx),%rdx + decq %rcx + jnz .Loop_dec_pad + +.Ldone_dec: + movq %rdx,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size xor128_decrypt_n_pad,.-xor128_decrypt_n_pad + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/poly1305/poly1305.c b/crypto/openssl/crypto/poly1305/poly1305.c index e7f5b92c8f3d..b3bf2b117bbf 100644 --- a/crypto/openssl/crypto/poly1305/poly1305.c +++ b/crypto/openssl/crypto/poly1305/poly1305.c @@ -1,7 +1,7 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,7 +12,6 @@ #include #include "crypto/poly1305.h" -#include "poly1305_local.h" size_t Poly1305_ctx_size(void) { @@ -95,11 +94,10 @@ poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, u32 padbit); (a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(a) * 8 - 1) \ ) -# if (defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16) && \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__==8) +# if defined(INT64_MAX) && defined(INT128_MAX) typedef unsigned long u64; -typedef __uint128_t u128; +typedef uint128_t u128; typedef struct { u64 h[3]; diff --git a/crypto/openssl/crypto/poly1305/poly1305_ameth.c b/crypto/openssl/crypto/poly1305/poly1305_ameth.c deleted file mode 100644 index 0dddf79626e3..000000000000 --- a/crypto/openssl/crypto/poly1305/poly1305_ameth.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" -#include -#include "crypto/asn1.h" -#include "crypto/poly1305.h" -#include "poly1305_local.h" -#include "crypto/evp.h" - -/* - * POLY1305 "ASN1" method. This is just here to indicate the maximum - * POLY1305 output length and to free up a POLY1305 key. - */ - -static int poly1305_size(const EVP_PKEY *pkey) -{ - return POLY1305_DIGEST_SIZE; -} - -static void poly1305_key_free(EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey); - if (os != NULL) { - if (os->data != NULL) - OPENSSL_cleanse(os->data, os->length); - ASN1_OCTET_STRING_free(os); - } -} - -static int poly1305_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - /* nothing, (including ASN1_PKEY_CTRL_DEFAULT_MD_NID), is supported */ - return -2; -} - -static int poly1305_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ - return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b)) == 0; -} - -static int poly1305_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, - size_t len) -{ - ASN1_OCTET_STRING *os; - - if (pkey->pkey.ptr != NULL || len != POLY1305_KEY_SIZE) - return 0; - - os = ASN1_OCTET_STRING_new(); - if (os == NULL) - return 0; - - if (!ASN1_OCTET_STRING_set(os, priv, len)) { - ASN1_OCTET_STRING_free(os); - return 0; - } - - pkey->pkey.ptr = os; - return 1; -} - -static int poly1305_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, - size_t *len) -{ - ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; - - if (priv == NULL) { - *len = POLY1305_KEY_SIZE; - return 1; - } - - if (os == NULL || *len < POLY1305_KEY_SIZE) - return 0; - - memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os)); - *len = POLY1305_KEY_SIZE; - - return 1; -} - -const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth = { - EVP_PKEY_POLY1305, - EVP_PKEY_POLY1305, - 0, - - "POLY1305", - "OpenSSL POLY1305 method", - - 0, 0, poly1305_pkey_public_cmp, 0, - - 0, 0, 0, - - poly1305_size, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, - - poly1305_key_free, - poly1305_pkey_ctrl, - NULL, - NULL, - - NULL, - NULL, - NULL, - - NULL, - NULL, - NULL, - - poly1305_set_priv_key, - NULL, - poly1305_get_priv_key, - NULL, -}; diff --git a/crypto/openssl/crypto/poly1305/poly1305_base2_44.c b/crypto/openssl/crypto/poly1305/poly1305_base2_44.c index b6313d01ba4e..a71e5e86e6b9 100644 --- a/crypto/openssl/crypto/poly1305/poly1305_base2_44.c +++ b/crypto/openssl/crypto/poly1305/poly1305_base2_44.c @@ -1,7 +1,7 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -18,7 +18,7 @@ typedef unsigned char u8; typedef unsigned int u32; typedef unsigned long u64; -typedef unsigned __int128 u128; +typedef uint128_t u128; typedef struct { u64 h[3]; diff --git a/crypto/openssl/crypto/poly1305/poly1305_ieee754.c b/crypto/openssl/crypto/poly1305/poly1305_ieee754.c index 7cfd968645ff..110feb4d5720 100644 --- a/crypto/openssl/crypto/poly1305/poly1305_ieee754.c +++ b/crypto/openssl/crypto/poly1305/poly1305_ieee754.c @@ -1,7 +1,7 @@ /* * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/poly1305/poly1305_local.h b/crypto/openssl/crypto/poly1305/poly1305_local.h deleted file mode 100644 index 6d4d9dc5b621..000000000000 --- a/crypto/openssl/crypto/poly1305/poly1305_local.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2015-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 - */ - -typedef void (*poly1305_blocks_f) (void *ctx, const unsigned char *inp, - size_t len, unsigned int padbit); -typedef void (*poly1305_emit_f) (void *ctx, unsigned char mac[16], - const unsigned int nonce[4]); - -struct poly1305_context { - double opaque[24]; /* large enough to hold internal state, declared - * 'double' to ensure at least 64-bit invariant - * alignment across all platforms and - * configurations */ - unsigned int nonce[4]; - unsigned char data[POLY1305_BLOCK_SIZE]; - size_t num; - struct { - poly1305_blocks_f blocks; - poly1305_emit_f emit; - } func; -}; diff --git a/crypto/openssl/crypto/poly1305/poly1305_pmeth.c b/crypto/openssl/crypto/poly1305/poly1305_pmeth.c deleted file mode 100644 index 49a799a12f51..000000000000 --- a/crypto/openssl/crypto/poly1305/poly1305_pmeth.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" -#include -#include -#include -#include -#include "crypto/poly1305.h" -#include "poly1305_local.h" -#include "crypto/evp.h" - -/* POLY1305 pkey context structure */ - -typedef struct { - ASN1_OCTET_STRING ktmp; /* Temp storage for key */ - POLY1305 ctx; -} POLY1305_PKEY_CTX; - -static int pkey_poly1305_init(EVP_PKEY_CTX *ctx) -{ - POLY1305_PKEY_CTX *pctx; - - if ((pctx = OPENSSL_zalloc(sizeof(*pctx))) == NULL) { - CRYPTOerr(CRYPTO_F_PKEY_POLY1305_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - pctx->ktmp.type = V_ASN1_OCTET_STRING; - - EVP_PKEY_CTX_set_data(ctx, pctx); - EVP_PKEY_CTX_set0_keygen_info(ctx, NULL, 0); - return 1; -} - -static void pkey_poly1305_cleanup(EVP_PKEY_CTX *ctx) -{ - POLY1305_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx); - - if (pctx != NULL) { - OPENSSL_clear_free(pctx->ktmp.data, pctx->ktmp.length); - OPENSSL_clear_free(pctx, sizeof(*pctx)); - EVP_PKEY_CTX_set_data(ctx, NULL); - } -} - -static int pkey_poly1305_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - POLY1305_PKEY_CTX *sctx, *dctx; - - /* allocate memory for dst->data and a new POLY1305_CTX in dst->data->ctx */ - if (!pkey_poly1305_init(dst)) - return 0; - sctx = EVP_PKEY_CTX_get_data(src); - dctx = EVP_PKEY_CTX_get_data(dst); - if (ASN1_STRING_get0_data(&sctx->ktmp) != NULL && - !ASN1_STRING_copy(&dctx->ktmp, &sctx->ktmp)) { - /* cleanup and free the POLY1305_PKEY_CTX in dst->data */ - pkey_poly1305_cleanup(dst); - return 0; - } - memcpy(&dctx->ctx, &sctx->ctx, sizeof(POLY1305)); - return 1; -} - -static int pkey_poly1305_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *key; - POLY1305_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx); - - if (ASN1_STRING_get0_data(&pctx->ktmp) == NULL) - return 0; - key = ASN1_OCTET_STRING_dup(&pctx->ktmp); - if (key == NULL) - return 0; - return EVP_PKEY_assign_POLY1305(pkey, key); -} - -static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - POLY1305_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx)); - - Poly1305_Update(&pctx->ctx, data, count); - return 1; -} - -static int poly1305_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -{ - POLY1305_PKEY_CTX *pctx = ctx->data; - ASN1_OCTET_STRING *key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; - - if (key->length != POLY1305_KEY_SIZE) - return 0; - EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); - EVP_MD_CTX_set_update_fn(mctx, int_update); - Poly1305_Init(&pctx->ctx, key->data); - return 1; -} -static int poly1305_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - EVP_MD_CTX *mctx) -{ - POLY1305_PKEY_CTX *pctx = ctx->data; - - *siglen = POLY1305_DIGEST_SIZE; - if (sig != NULL) - Poly1305_Final(&pctx->ctx, sig); - return 1; -} - -static int pkey_poly1305_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - POLY1305_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx); - const unsigned char *key; - size_t len; - - switch (type) { - - case EVP_PKEY_CTRL_MD: - /* ignore */ - break; - - case EVP_PKEY_CTRL_SET_MAC_KEY: - case EVP_PKEY_CTRL_DIGESTINIT: - if (type == EVP_PKEY_CTRL_SET_MAC_KEY) { - /* user explicitly setting the key */ - key = p2; - len = p1; - } else { - /* user indirectly setting the key via EVP_DigestSignInit */ - key = EVP_PKEY_get0_poly1305(EVP_PKEY_CTX_get0_pkey(ctx), &len); - } - if (key == NULL || len != POLY1305_KEY_SIZE || - !ASN1_OCTET_STRING_set(&pctx->ktmp, key, len)) - return 0; - Poly1305_Init(&pctx->ctx, ASN1_STRING_get0_data(&pctx->ktmp)); - break; - - default: - return -2; - - } - return 1; -} - -static int pkey_poly1305_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (value == NULL) - return 0; - if (strcmp(type, "key") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); - if (strcmp(type, "hexkey") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); - return -2; -} - -const EVP_PKEY_METHOD poly1305_pkey_meth = { - EVP_PKEY_POLY1305, - EVP_PKEY_FLAG_SIGCTX_CUSTOM, /* we don't deal with a separate MD */ - pkey_poly1305_init, - pkey_poly1305_copy, - pkey_poly1305_cleanup, - - 0, 0, - - 0, - pkey_poly1305_keygen, - - 0, 0, - - 0, 0, - - 0, 0, - - poly1305_signctx_init, - poly1305_signctx, - - 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_poly1305_ctrl, - pkey_poly1305_ctrl_str -}; diff --git a/crypto/openssl/crypto/poly1305/poly1305_ppc.c b/crypto/openssl/crypto/poly1305/poly1305_ppc.c new file mode 100644 index 000000000000..4e4e3d1994f1 --- /dev/null +++ b/crypto/openssl/crypto/poly1305/poly1305_ppc.c @@ -0,0 +1,47 @@ +/* + * Copyright 2009-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/poly1305.h" +#include "crypto/ppc_arch.h" + +void poly1305_init_int(void *ctx, const unsigned char key[16]); +void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, + unsigned int padbit); +void poly1305_emit(void *ctx, unsigned char mac[16], + const unsigned int nonce[4]); +void poly1305_init_fpu(void *ctx, const unsigned char key[16]); +void poly1305_blocks_fpu(void *ctx, const unsigned char *inp, size_t len, + unsigned int padbit); +void poly1305_emit_fpu(void *ctx, unsigned char mac[16], + const unsigned int nonce[4]); +void poly1305_init_vsx(void *ctx, const unsigned char key[16]); +void poly1305_blocks_vsx(void *ctx, const unsigned char *inp, size_t len, + unsigned int padbit); +void poly1305_emit_vsx(void *ctx, unsigned char mac[16], + const unsigned int nonce[4]); +int poly1305_init(void *ctx, const unsigned char key[16], void *func[2]); +int poly1305_init(void *ctx, const unsigned char key[16], void *func[2]) +{ + if (OPENSSL_ppccap_P & PPC_CRYPTO207) { + poly1305_init_int(ctx, key); + func[0] = (void*)(uintptr_t)poly1305_blocks_vsx; + func[1] = (void*)(uintptr_t)poly1305_emit; + } else if (sizeof(size_t) == 4 && (OPENSSL_ppccap_P & PPC_FPU)) { + poly1305_init_fpu(ctx, key); + func[0] = (void*)(uintptr_t)poly1305_blocks_fpu; + func[1] = (void*)(uintptr_t)poly1305_emit_fpu; + } else { + poly1305_init_int(ctx, key); + func[0] = (void*)(uintptr_t)poly1305_blocks; + func[1] = (void*)(uintptr_t)poly1305_emit; + } + return 1; +} diff --git a/crypto/openssl/crypto/ppccap.c b/crypto/openssl/crypto/ppccap.c index 23bcf1f46e2e..8bcfed25e057 100644 --- a/crypto/openssl/crypto/ppccap.c +++ b/crypto/openssl/crypto/ppccap.c @@ -1,7 +1,7 @@ /* * Copyright 2009-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -27,135 +27,13 @@ # include #endif #include -#include -#include -#include -#include "bn/bn_local.h" - -#include "ppc_arch.h" +#include "internal/cryptlib.h" +#include "crypto/ppc_arch.h" unsigned int OPENSSL_ppccap_P = 0; static sigset_t all_masked; -#ifdef OPENSSL_BN_ASM_MONT -int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, int num) -{ - int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, int num); - int bn_mul4x_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, int num); - - if (num < 4) - return 0; - - if ((num & 3) == 0) - return bn_mul4x_mont_int(rp, ap, bp, np, n0, num); - - /* - * There used to be [optional] call to bn_mul_mont_fpu64 here, - * but above subroutine is faster on contemporary processors. - * Formulation means that there might be old processors where - * FPU code path would be faster, POWER6 perhaps, but there was - * no opportunity to figure it out... - */ - - return bn_mul_mont_int(rp, ap, bp, np, n0, num); -} -#endif - -void sha256_block_p8(void *ctx, const void *inp, size_t len); -void sha256_block_ppc(void *ctx, const void *inp, size_t len); -void sha256_block_data_order(void *ctx, const void *inp, size_t len); -void sha256_block_data_order(void *ctx, const void *inp, size_t len) -{ - OPENSSL_ppccap_P & PPC_CRYPTO207 ? sha256_block_p8(ctx, inp, len) : - sha256_block_ppc(ctx, inp, len); -} - -void sha512_block_p8(void *ctx, const void *inp, size_t len); -void sha512_block_ppc(void *ctx, const void *inp, size_t len); -void sha512_block_data_order(void *ctx, const void *inp, size_t len); -void sha512_block_data_order(void *ctx, const void *inp, size_t len) -{ - OPENSSL_ppccap_P & PPC_CRYPTO207 ? sha512_block_p8(ctx, inp, len) : - sha512_block_ppc(ctx, inp, len); -} - -#ifndef OPENSSL_NO_CHACHA -void ChaCha20_ctr32_int(unsigned char *out, const unsigned char *inp, - size_t len, const unsigned int key[8], - const unsigned int counter[4]); -void ChaCha20_ctr32_vmx(unsigned char *out, const unsigned char *inp, - size_t len, const unsigned int key[8], - const unsigned int counter[4]); -void ChaCha20_ctr32_vsx(unsigned char *out, const unsigned char *inp, - size_t len, const unsigned int key[8], - const unsigned int counter[4]); -void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, - size_t len, const unsigned int key[8], - const unsigned int counter[4]) -{ - OPENSSL_ppccap_P & PPC_CRYPTO207 - ? ChaCha20_ctr32_vsx(out, inp, len, key, counter) - : OPENSSL_ppccap_P & PPC_ALTIVEC - ? ChaCha20_ctr32_vmx(out, inp, len, key, counter) - : ChaCha20_ctr32_int(out, inp, len, key, counter); -} -#endif - -#ifndef OPENSSL_NO_POLY1305 -void poly1305_init_int(void *ctx, const unsigned char key[16]); -void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, - unsigned int padbit); -void poly1305_emit(void *ctx, unsigned char mac[16], - const unsigned int nonce[4]); -void poly1305_init_fpu(void *ctx, const unsigned char key[16]); -void poly1305_blocks_fpu(void *ctx, const unsigned char *inp, size_t len, - unsigned int padbit); -void poly1305_emit_fpu(void *ctx, unsigned char mac[16], - const unsigned int nonce[4]); -int poly1305_init(void *ctx, const unsigned char key[16], void *func[2]); -int poly1305_init(void *ctx, const unsigned char key[16], void *func[2]) -{ - if (sizeof(size_t) == 4 && (OPENSSL_ppccap_P & PPC_FPU)) { - poly1305_init_fpu(ctx, key); - func[0] = (void*)(uintptr_t)poly1305_blocks_fpu; - func[1] = (void*)(uintptr_t)poly1305_emit_fpu; - } else { - poly1305_init_int(ctx, key); - func[0] = (void*)(uintptr_t)poly1305_blocks; - func[1] = (void*)(uintptr_t)poly1305_emit; - } - return 1; -} -#endif - -#ifdef ECP_NISTZ256_ASM -void ecp_nistz256_mul_mont(unsigned long res[4], const unsigned long a[4], - const unsigned long b[4]); - -void ecp_nistz256_to_mont(unsigned long res[4], const unsigned long in[4]); -void ecp_nistz256_to_mont(unsigned long res[4], const unsigned long in[4]) -{ - static const unsigned long RR[] = { 0x0000000000000003U, - 0xfffffffbffffffffU, - 0xfffffffffffffffeU, - 0x00000004fffffffdU }; - - ecp_nistz256_mul_mont(res, in, RR); -} - -void ecp_nistz256_from_mont(unsigned long res[4], const unsigned long in[4]); -void ecp_nistz256_from_mont(unsigned long res[4], const unsigned long in[4]) -{ - static const unsigned long one[] = { 1, 0, 0, 0 }; - - ecp_nistz256_mul_mont(res, in, one); -} -#endif - static sigjmp_buf ill_jmp; static void ill_handler(int sig) { @@ -239,18 +117,14 @@ static unsigned long getauxval(unsigned long key) #endif /* I wish was universally available */ -#ifndef AT_HWCAP -# define AT_HWCAP 16 /* AT_HWCAP */ -#endif +#define HWCAP 16 /* AT_HWCAP */ #define HWCAP_PPC64 (1U << 30) #define HWCAP_ALTIVEC (1U << 28) #define HWCAP_FPU (1U << 27) #define HWCAP_POWER6_EXT (1U << 9) #define HWCAP_VSX (1U << 7) -#ifndef AT_HWCAP2 -# define AT_HWCAP2 26 /* AT_HWCAP2 */ -#endif +#define HWCAP2 26 /* AT_HWCAP2 */ #define HWCAP_VEC_CRYPTO (1U << 25) #define HWCAP_ARCH_3_00 (1U << 23) @@ -341,8 +215,8 @@ void OPENSSL_cpuid_setup(void) #ifdef OSSL_IMPLEMENT_GETAUXVAL { - unsigned long hwcap = getauxval(AT_HWCAP); - unsigned long hwcap2 = getauxval(AT_HWCAP2); + unsigned long hwcap = getauxval(HWCAP); + unsigned long hwcap2 = getauxval(HWCAP2); if (hwcap & HWCAP_FPU) { OPENSSL_ppccap_P |= PPC_FPU; diff --git a/crypto/openssl/crypto/ppccpuid.pl b/crypto/openssl/crypto/ppccpuid.pl index 2065cbb84b10..c6555df5d8e3 100755 --- a/crypto/openssl/crypto/ppccpuid.pl +++ b/crypto/openssl/crypto/ppccpuid.pl @@ -1,20 +1,24 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or ( $xlate="${dir}perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; if ($flavour=~/64/) { $CMPLI="cmpldi"; diff --git a/crypto/openssl/crypto/property/README.md b/crypto/openssl/crypto/property/README.md new file mode 100644 index 000000000000..9d97a6987305 --- /dev/null +++ b/crypto/openssl/crypto/property/README.md @@ -0,0 +1,94 @@ +Selecting algorithm implementations by properties +================================================= + +Properties are associated with algorithms and are used to select between +different implementations dynamically. + +This implementation is based on a number of assumptions: + +* Property definition is uncommon. I.e. providers will be loaded and + unloaded relatively infrequently, if at all. + +* The number of distinct property names will be small. + +* Providers will often give the same implementation properties to most or + all of their implemented algorithms. E.g. the FIPS property would be set + across an entire provider. Likewise for, hardware, accelerated, software, + HSM and, perhaps, constant_time. + +* There are a lot of algorithm implementations, therefore property + definitions should be space efficient. However... + +* ... property queries are very common. These must be fast. + +* Property queries come from a small set and are reused many times typically. + I.e. an application tends to use the same set of queries over and over, + rather than spanning a wide variety of queries. + +* Property queries can never add new property definitions. + +Some consequences of these assumptions are: + +* That definition is uncommon and queries are very common, we can treat + the property definitions as almost immutable. Specifically, a query can + never change the state of the definitions. + +* That definition is uncommon and needs to be space efficient, it will + be feasible to use a hash table to contain the names (and possibly also + values) of all properties and to reference these instead of duplicating + strings. Moreover, such a data structure need not be garbage collected. + By converting strings to integers using a structure such as this, string + comparison degenerates to integer comparison. Additionally, lists of + properties can be sorted by the string index which makes comparisons linear + time rather than quadratic time - the O(n log n) sort cost being amortised. + +* A cache for property definitions is also viable, if only implementation + properties are used and not algorithm properties, or at least these are + maintained separately. This cache would be a hash table, indexed by + the property definition string, and algorithms with the same properties + would share their definition structure. Again, reducing space use. + +* A query cache is desirable. This would be a hash table keyed by the + algorithm identifier and the entire query string and it would map to + the chosen algorithm. When a provider is loaded or unloaded, this cache + must be invalidated. The cache will also be invalidated when the global + properties are changed as doing so removes the need to index on both the + global and requested property strings. + +The implementation: + +* [property_lock.c](property_lock.c) + contains some wrapper functions to handle the global + lock more easily. The global lock is held for short periods of time with + per algorithm locking being used for longer intervals. + +* [property_string.c](property_string.c) + contains the string cache which converts property + names and values to small integer indices. Names and values are stored in + separate hash tables. The two Boolean values, the strings "yes" and "no", + are populated as the first two members of the value table. All property + names reserved by OpenSSL are also populated here. No functions are + provided to convert from an index back to the original string (this can be + done by maintaining parallel stacks of strings if required). + +* [property_parse.c](property_parse.c) + contains the property definition and query parsers. + These convert ASCII strings into lists of properties. The resulting + lists are sorted by the name index. Some additional utility functions + for dealing with property lists are also included: comparison of a query + against a definition and merging two queries into a single larger query. + +* [property.c](property.c) + contains the main APIs for defining and using properties. + Algorithms are discovered from their NID and a query string. + The results are cached. + + The caching of query results has to be efficient but it must also be robust + against a denial of service attack. The cache cannot be permitted to grow + without bounds and must garbage collect under-used entries. The garbage + collection does not have to be exact. + +* [defn_cache.c](defn_cache.c) + contains a cache that maps property definition strings to + parsed properties. It is used by property.c to improve performance when + the same definition appears multiple times. diff --git a/crypto/openssl/crypto/property/build.info b/crypto/openssl/crypto/property/build.info new file mode 100644 index 000000000000..12a6b8c9de22 --- /dev/null +++ b/crypto/openssl/crypto/property/build.info @@ -0,0 +1,4 @@ +LIBS=../../libcrypto +$COMMON=property_string.c property_parse.c property_query.c property.c defn_cache.c +SOURCE[../../libcrypto]=$COMMON property_err.c +SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/openssl/crypto/property/defn_cache.c b/crypto/openssl/crypto/property/defn_cache.c new file mode 100644 index 000000000000..b43f2d247ef6 --- /dev/null +++ b/crypto/openssl/crypto/property/defn_cache.c @@ -0,0 +1,143 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "internal/propertyerr.h" +#include "internal/property.h" +#include "internal/core.h" +#include "property_local.h" + +/* + * Implement a property definition cache. + * These functions assume that they are called under a write lock. + * No attempt is made to clean out the cache, except when it is shut down. + */ + +typedef struct { + const char *prop; + OSSL_PROPERTY_LIST *defn; + char body[1]; +} PROPERTY_DEFN_ELEM; + +DEFINE_LHASH_OF(PROPERTY_DEFN_ELEM); + +static unsigned long property_defn_hash(const PROPERTY_DEFN_ELEM *a) +{ + return OPENSSL_LH_strhash(a->prop); +} + +static int property_defn_cmp(const PROPERTY_DEFN_ELEM *a, + const PROPERTY_DEFN_ELEM *b) +{ + return strcmp(a->prop, b->prop); +} + +static void property_defn_free(PROPERTY_DEFN_ELEM *elem) +{ + ossl_property_free(elem->defn); + OPENSSL_free(elem); +} + +static void property_defns_free(void *vproperty_defns) +{ + LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = vproperty_defns; + + if (property_defns != NULL) { + lh_PROPERTY_DEFN_ELEM_doall(property_defns, + &property_defn_free); + lh_PROPERTY_DEFN_ELEM_free(property_defns); + } +} + +static void *property_defns_new(OSSL_LIB_CTX *ctx) { + return lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash, &property_defn_cmp); +} + +static const OSSL_LIB_CTX_METHOD property_defns_method = { + OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, + property_defns_new, + property_defns_free, +}; + +OSSL_PROPERTY_LIST *ossl_prop_defn_get(OSSL_LIB_CTX *ctx, const char *prop) +{ + PROPERTY_DEFN_ELEM elem, *r; + LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns; + + property_defns = ossl_lib_ctx_get_data(ctx, + OSSL_LIB_CTX_PROPERTY_DEFN_INDEX, + &property_defns_method); + if (property_defns == NULL || !ossl_lib_ctx_read_lock(ctx)) + return NULL; + + elem.prop = prop; + r = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem); + ossl_lib_ctx_unlock(ctx); + if (r == NULL || !ossl_assert(r->defn != NULL)) + return NULL; + return r->defn; +} + +/* + * Cache the property list for a given property string *pl. + * If an entry already exists in the cache *pl is freed and + * overwritten with the existing entry from the cache. + */ +int ossl_prop_defn_set(OSSL_LIB_CTX *ctx, const char *prop, + OSSL_PROPERTY_LIST **pl) +{ + PROPERTY_DEFN_ELEM elem, *old, *p = NULL; + size_t len; + LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns; + int res = 1; + + property_defns = ossl_lib_ctx_get_data(ctx, + OSSL_LIB_CTX_PROPERTY_DEFN_INDEX, + &property_defns_method); + if (property_defns == NULL) + return 0; + + if (prop == NULL) + return 1; + + if (!ossl_lib_ctx_write_lock(ctx)) + return 0; + elem.prop = prop; + if (pl == NULL) { + lh_PROPERTY_DEFN_ELEM_delete(property_defns, &elem); + goto end; + } + /* check if property definition is in the cache already */ + if ((p = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem)) != NULL) { + ossl_property_free(*pl); + *pl = p->defn; + goto end; + } + len = strlen(prop); + p = OPENSSL_malloc(sizeof(*p) + len); + if (p != NULL) { + p->prop = p->body; + p->defn = *pl; + memcpy(p->body, prop, len + 1); + old = lh_PROPERTY_DEFN_ELEM_insert(property_defns, p); + if (!ossl_assert(old == NULL)) + /* This should not happen. An existing entry is handled above. */ + goto end; + if (!lh_PROPERTY_DEFN_ELEM_error(property_defns)) + goto end; + } + OPENSSL_free(p); + res = 0; + end: + ossl_lib_ctx_unlock(ctx); + return res; +} diff --git a/crypto/openssl/crypto/property/property.c b/crypto/openssl/crypto/property/property.c new file mode 100644 index 000000000000..844c25cee936 --- /dev/null +++ b/crypto/openssl/crypto/property/property.c @@ -0,0 +1,769 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/core.h" +#include "internal/property.h" +#include "internal/provider.h" +#include "internal/tsan_assist.h" +#include "crypto/ctype.h" +#include +#include +#include "internal/thread_once.h" +#include "crypto/lhash.h" +#include "crypto/sparse_array.h" +#include "property_local.h" + +/* + * The number of elements in the query cache before we initiate a flush. + * If reducing this, also ensure the stochastic test in test/property_test.c + * isn't likely to fail. + */ +#define IMPL_CACHE_FLUSH_THRESHOLD 500 + +typedef struct { + void *method; + int (*up_ref)(void *); + void (*free)(void *); +} METHOD; + +typedef struct { + const OSSL_PROVIDER *provider; + OSSL_PROPERTY_LIST *properties; + METHOD method; +} IMPLEMENTATION; + +DEFINE_STACK_OF(IMPLEMENTATION) + +typedef struct { + const OSSL_PROVIDER *provider; + const char *query; + METHOD method; + char body[1]; +} QUERY; + +DEFINE_LHASH_OF(QUERY); + +typedef struct { + int nid; + STACK_OF(IMPLEMENTATION) *impls; + LHASH_OF(QUERY) *cache; +} ALGORITHM; + +struct ossl_method_store_st { + OSSL_LIB_CTX *ctx; + SPARSE_ARRAY_OF(ALGORITHM) *algs; + /* + * Lock to protect the |algs| array from concurrent writing, when + * individual implementations or queries are inserted. This is used + * by the appropriate functions here. + */ + CRYPTO_RWLOCK *lock; + /* + * Lock to reserve the whole store. This is used when fetching a set + * of algorithms, via these functions, found in crypto/core_fetch.c: + * ossl_method_construct_reserve_store() + * ossl_method_construct_unreserve_store() + */ + CRYPTO_RWLOCK *biglock; + + /* query cache specific values */ + + /* Count of the query cache entries for all algs */ + size_t cache_nelem; + + /* Flag: 1 if query cache entries for all algs need flushing */ + int cache_need_flush; +}; + +typedef struct { + LHASH_OF(QUERY) *cache; + size_t nelem; + uint32_t seed; + unsigned char using_global_seed; +} IMPL_CACHE_FLUSH; + +DEFINE_SPARSE_ARRAY_OF(ALGORITHM); + +typedef struct ossl_global_properties_st { + OSSL_PROPERTY_LIST *list; +#ifndef FIPS_MODULE + unsigned int no_mirrored : 1; +#endif +} OSSL_GLOBAL_PROPERTIES; + +static void ossl_method_cache_flush_alg(OSSL_METHOD_STORE *store, + ALGORITHM *alg); +static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid); + +/* Global properties are stored per library context */ +static void ossl_ctx_global_properties_free(void *vglobp) +{ + OSSL_GLOBAL_PROPERTIES *globp = vglobp; + + if (globp != NULL) { + ossl_property_free(globp->list); + OPENSSL_free(globp); + } +} + +static void *ossl_ctx_global_properties_new(OSSL_LIB_CTX *ctx) +{ + return OPENSSL_zalloc(sizeof(OSSL_GLOBAL_PROPERTIES)); +} + +static const OSSL_LIB_CTX_METHOD ossl_ctx_global_properties_method = { + OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, + ossl_ctx_global_properties_new, + ossl_ctx_global_properties_free, +}; + +OSSL_PROPERTY_LIST **ossl_ctx_global_properties(OSSL_LIB_CTX *libctx, + int loadconfig) +{ + OSSL_GLOBAL_PROPERTIES *globp; + +#ifndef FIPS_MODULE + if (loadconfig && !OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL)) + return NULL; +#endif + globp = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_GLOBAL_PROPERTIES, + &ossl_ctx_global_properties_method); + + return globp != NULL ? &globp->list : NULL; +} + +#ifndef FIPS_MODULE +int ossl_global_properties_no_mirrored(OSSL_LIB_CTX *libctx) +{ + OSSL_GLOBAL_PROPERTIES *globp + = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_GLOBAL_PROPERTIES, + &ossl_ctx_global_properties_method); + + return globp != NULL && globp->no_mirrored ? 1 : 0; +} + +void ossl_global_properties_stop_mirroring(OSSL_LIB_CTX *libctx) +{ + OSSL_GLOBAL_PROPERTIES *globp + = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_GLOBAL_PROPERTIES, + &ossl_ctx_global_properties_method); + + if (globp != NULL) + globp->no_mirrored = 1; +} +#endif + +static int ossl_method_up_ref(METHOD *method) +{ + return (*method->up_ref)(method->method); +} + +static void ossl_method_free(METHOD *method) +{ + (*method->free)(method->method); +} + +static __owur int ossl_property_read_lock(OSSL_METHOD_STORE *p) +{ + return p != NULL ? CRYPTO_THREAD_read_lock(p->lock) : 0; +} + +static __owur int ossl_property_write_lock(OSSL_METHOD_STORE *p) +{ + return p != NULL ? CRYPTO_THREAD_write_lock(p->lock) : 0; +} + +static int ossl_property_unlock(OSSL_METHOD_STORE *p) +{ + return p != 0 ? CRYPTO_THREAD_unlock(p->lock) : 0; +} + +static unsigned long query_hash(const QUERY *a) +{ + return OPENSSL_LH_strhash(a->query); +} + +static int query_cmp(const QUERY *a, const QUERY *b) +{ + int res = strcmp(a->query, b->query); + + if (res == 0 && a->provider != NULL && b->provider != NULL) + res = b->provider > a->provider ? 1 + : b->provider < a->provider ? -1 + : 0; + return res; +} + +static void impl_free(IMPLEMENTATION *impl) +{ + if (impl != NULL) { + ossl_method_free(&impl->method); + OPENSSL_free(impl); + } +} + +static void impl_cache_free(QUERY *elem) +{ + if (elem != NULL) { + ossl_method_free(&elem->method); + OPENSSL_free(elem); + } +} + +static void impl_cache_flush_alg(ossl_uintmax_t idx, ALGORITHM *alg) +{ + lh_QUERY_doall(alg->cache, &impl_cache_free); + lh_QUERY_flush(alg->cache); +} + +static void alg_cleanup(ossl_uintmax_t idx, ALGORITHM *a, void *arg) +{ + OSSL_METHOD_STORE *store = arg; + + if (a != NULL) { + sk_IMPLEMENTATION_pop_free(a->impls, &impl_free); + lh_QUERY_doall(a->cache, &impl_cache_free); + lh_QUERY_free(a->cache); + OPENSSL_free(a); + } + if (store != NULL) + ossl_sa_ALGORITHM_set(store->algs, idx, NULL); +} + +/* + * The OSSL_LIB_CTX param here allows access to underlying property data needed + * for computation + */ +OSSL_METHOD_STORE *ossl_method_store_new(OSSL_LIB_CTX *ctx) +{ + OSSL_METHOD_STORE *res; + + res = OPENSSL_zalloc(sizeof(*res)); + if (res != NULL) { + res->ctx = ctx; + if ((res->algs = ossl_sa_ALGORITHM_new()) == NULL + || (res->lock = CRYPTO_THREAD_lock_new()) == NULL + || (res->biglock = CRYPTO_THREAD_lock_new()) == NULL) { + ossl_method_store_free(res); + return NULL; + } + } + return res; +} + +void ossl_method_store_free(OSSL_METHOD_STORE *store) +{ + if (store != NULL) { + if (store->algs != NULL) + ossl_sa_ALGORITHM_doall_arg(store->algs, &alg_cleanup, store); + ossl_sa_ALGORITHM_free(store->algs); + CRYPTO_THREAD_lock_free(store->lock); + CRYPTO_THREAD_lock_free(store->biglock); + OPENSSL_free(store); + } +} + +int ossl_method_lock_store(OSSL_METHOD_STORE *store) +{ + return store != NULL ? CRYPTO_THREAD_write_lock(store->biglock) : 0; +} + +int ossl_method_unlock_store(OSSL_METHOD_STORE *store) +{ + return store != NULL ? CRYPTO_THREAD_unlock(store->biglock) : 0; +} + +static ALGORITHM *ossl_method_store_retrieve(OSSL_METHOD_STORE *store, int nid) +{ + return ossl_sa_ALGORITHM_get(store->algs, nid); +} + +static int ossl_method_store_insert(OSSL_METHOD_STORE *store, ALGORITHM *alg) +{ + return ossl_sa_ALGORITHM_set(store->algs, alg->nid, alg); +} + +int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov, + int nid, const char *properties, void *method, + int (*method_up_ref)(void *), + void (*method_destruct)(void *)) +{ + ALGORITHM *alg = NULL; + IMPLEMENTATION *impl; + int ret = 0; + int i; + + if (nid <= 0 || method == NULL || store == NULL) + return 0; + if (properties == NULL) + properties = ""; + + if (!ossl_assert(prov != NULL)) + return 0; + + /* Create new entry */ + impl = OPENSSL_malloc(sizeof(*impl)); + if (impl == NULL) + return 0; + impl->method.method = method; + impl->method.up_ref = method_up_ref; + impl->method.free = method_destruct; + if (!ossl_method_up_ref(&impl->method)) { + OPENSSL_free(impl); + return 0; + } + impl->provider = prov; + + /* Insert into the hash table if required */ + if (!ossl_property_write_lock(store)) { + OPENSSL_free(impl); + return 0; + } + ossl_method_cache_flush(store, nid); + if ((impl->properties = ossl_prop_defn_get(store->ctx, properties)) == NULL) { + impl->properties = ossl_parse_property(store->ctx, properties); + if (impl->properties == NULL) + goto err; + if (!ossl_prop_defn_set(store->ctx, properties, &impl->properties)) { + ossl_property_free(impl->properties); + impl->properties = NULL; + goto err; + } + } + + alg = ossl_method_store_retrieve(store, nid); + if (alg == NULL) { + if ((alg = OPENSSL_zalloc(sizeof(*alg))) == NULL + || (alg->impls = sk_IMPLEMENTATION_new_null()) == NULL + || (alg->cache = lh_QUERY_new(&query_hash, &query_cmp)) == NULL) + goto err; + alg->nid = nid; + if (!ossl_method_store_insert(store, alg)) + goto err; + } + + /* Push onto stack if there isn't one there already */ + for (i = 0; i < sk_IMPLEMENTATION_num(alg->impls); i++) { + const IMPLEMENTATION *tmpimpl = sk_IMPLEMENTATION_value(alg->impls, i); + + if (tmpimpl->provider == impl->provider + && tmpimpl->properties == impl->properties) + break; + } + if (i == sk_IMPLEMENTATION_num(alg->impls) + && sk_IMPLEMENTATION_push(alg->impls, impl)) + ret = 1; + ossl_property_unlock(store); + if (ret == 0) + impl_free(impl); + return ret; + +err: + ossl_property_unlock(store); + alg_cleanup(0, alg, NULL); + impl_free(impl); + return 0; +} + +int ossl_method_store_remove(OSSL_METHOD_STORE *store, int nid, + const void *method) +{ + ALGORITHM *alg = NULL; + int i; + + if (nid <= 0 || method == NULL || store == NULL) + return 0; + + if (!ossl_property_write_lock(store)) + return 0; + ossl_method_cache_flush(store, nid); + alg = ossl_method_store_retrieve(store, nid); + if (alg == NULL) { + ossl_property_unlock(store); + return 0; + } + + /* + * A sorting find then a delete could be faster but these stacks should be + * relatively small, so we avoid the overhead. Sorting could also surprise + * users when result orderings change (even though they are not guaranteed). + */ + for (i = 0; i < sk_IMPLEMENTATION_num(alg->impls); i++) { + IMPLEMENTATION *impl = sk_IMPLEMENTATION_value(alg->impls, i); + + if (impl->method.method == method) { + impl_free(impl); + (void)sk_IMPLEMENTATION_delete(alg->impls, i); + ossl_property_unlock(store); + return 1; + } + } + ossl_property_unlock(store); + return 0; +} + +struct alg_cleanup_by_provider_data_st { + OSSL_METHOD_STORE *store; + const OSSL_PROVIDER *prov; +}; + +static void +alg_cleanup_by_provider(ossl_uintmax_t idx, ALGORITHM *alg, void *arg) +{ + struct alg_cleanup_by_provider_data_st *data = arg; + int i, count; + + /* + * We walk the stack backwards, to avoid having to deal with stack shifts + * caused by deletion + */ + for (count = 0, i = sk_IMPLEMENTATION_num(alg->impls); i-- > 0;) { + IMPLEMENTATION *impl = sk_IMPLEMENTATION_value(alg->impls, i); + + if (impl->provider == data->prov) { + impl_free(impl); + (void)sk_IMPLEMENTATION_delete(alg->impls, i); + count++; + } + } + + /* + * If we removed any implementation, we also clear the whole associated + * cache, 'cause that's the sensible thing to do. + * There's no point flushing the cache entries where we didn't remove + * any implementation, though. + */ + if (count > 0) + ossl_method_cache_flush_alg(data->store, alg); +} + +int ossl_method_store_remove_all_provided(OSSL_METHOD_STORE *store, + const OSSL_PROVIDER *prov) +{ + struct alg_cleanup_by_provider_data_st data; + + if (!ossl_property_write_lock(store)) + return 0; + data.prov = prov; + data.store = store; + ossl_sa_ALGORITHM_doall_arg(store->algs, &alg_cleanup_by_provider, &data); + ossl_property_unlock(store); + return 1; +} + +static void alg_do_one(ALGORITHM *alg, IMPLEMENTATION *impl, + void (*fn)(int id, void *method, void *fnarg), + void *fnarg) +{ + fn(alg->nid, impl->method.method, fnarg); +} + +struct alg_do_each_data_st { + void (*fn)(int id, void *method, void *fnarg); + void *fnarg; +}; + +static void alg_do_each(ossl_uintmax_t idx, ALGORITHM *alg, void *arg) +{ + struct alg_do_each_data_st *data = arg; + int i, end = sk_IMPLEMENTATION_num(alg->impls); + + for (i = 0; i < end; i++) { + IMPLEMENTATION *impl = sk_IMPLEMENTATION_value(alg->impls, i); + + alg_do_one(alg, impl, data->fn, data->fnarg); + } +} + +void ossl_method_store_do_all(OSSL_METHOD_STORE *store, + void (*fn)(int id, void *method, void *fnarg), + void *fnarg) +{ + struct alg_do_each_data_st data; + + data.fn = fn; + data.fnarg = fnarg; + if (store != NULL) + ossl_sa_ALGORITHM_doall_arg(store->algs, alg_do_each, &data); +} + +int ossl_method_store_fetch(OSSL_METHOD_STORE *store, + int nid, const char *prop_query, + const OSSL_PROVIDER **prov_rw, void **method) +{ + OSSL_PROPERTY_LIST **plp; + ALGORITHM *alg; + IMPLEMENTATION *impl, *best_impl = NULL; + OSSL_PROPERTY_LIST *pq = NULL, *p2 = NULL; + const OSSL_PROVIDER *prov = prov_rw != NULL ? *prov_rw : NULL; + int ret = 0; + int j, best = -1, score, optional; + +#ifndef FIPS_MODULE + if (!OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL)) + return 0; +#endif + + if (nid <= 0 || method == NULL || store == NULL) + return 0; + + /* This only needs to be a read lock, because the query won't create anything */ + if (!ossl_property_read_lock(store)) + return 0; + alg = ossl_method_store_retrieve(store, nid); + if (alg == NULL) { + ossl_property_unlock(store); + return 0; + } + + if (prop_query != NULL) + p2 = pq = ossl_parse_query(store->ctx, prop_query, 0); + plp = ossl_ctx_global_properties(store->ctx, 0); + if (plp != NULL && *plp != NULL) { + if (pq == NULL) { + pq = *plp; + } else { + p2 = ossl_property_merge(pq, *plp); + ossl_property_free(pq); + if (p2 == NULL) + goto fin; + pq = p2; + } + } + + if (pq == NULL) { + for (j = 0; j < sk_IMPLEMENTATION_num(alg->impls); j++) { + if ((impl = sk_IMPLEMENTATION_value(alg->impls, j)) != NULL + && (prov == NULL || impl->provider == prov)) { + best_impl = impl; + ret = 1; + break; + } + } + goto fin; + } + optional = ossl_property_has_optional(pq); + for (j = 0; j < sk_IMPLEMENTATION_num(alg->impls); j++) { + if ((impl = sk_IMPLEMENTATION_value(alg->impls, j)) != NULL + && (prov == NULL || impl->provider == prov)) { + score = ossl_property_match_count(pq, impl->properties); + if (score > best) { + best_impl = impl; + best = score; + ret = 1; + if (!optional) + goto fin; + } + } + } +fin: + if (ret && ossl_method_up_ref(&best_impl->method)) { + *method = best_impl->method.method; + if (prov_rw != NULL) + *prov_rw = best_impl->provider; + } else { + ret = 0; + } + ossl_property_unlock(store); + ossl_property_free(p2); + return ret; +} + +static void ossl_method_cache_flush_alg(OSSL_METHOD_STORE *store, + ALGORITHM *alg) +{ + store->cache_nelem -= lh_QUERY_num_items(alg->cache); + impl_cache_flush_alg(0, alg); +} + +static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid) +{ + ALGORITHM *alg = ossl_method_store_retrieve(store, nid); + + if (alg != NULL) + ossl_method_cache_flush_alg(store, alg); +} + +int ossl_method_store_cache_flush_all(OSSL_METHOD_STORE *store) +{ + if (!ossl_property_write_lock(store)) + return 0; + ossl_sa_ALGORITHM_doall(store->algs, &impl_cache_flush_alg); + store->cache_nelem = 0; + ossl_property_unlock(store); + return 1; +} + +IMPLEMENT_LHASH_DOALL_ARG(QUERY, IMPL_CACHE_FLUSH); + +/* + * Flush an element from the query cache (perhaps). + * + * In order to avoid taking a write lock or using atomic operations + * to keep accurate least recently used (LRU) or least frequently used + * (LFU) information, the procedure used here is to stochastically + * flush approximately half the cache. + * + * This procedure isn't ideal, LRU or LFU would be better. However, + * in normal operation, reaching a full cache would be unexpected. + * It means that no steady state of algorithm queries has been reached. + * That is, it is most likely an attack of some form. A suboptimal clearance + * strategy that doesn't degrade performance of the normal case is + * preferable to a more refined approach that imposes a performance + * impact. + */ +static void impl_cache_flush_cache(QUERY *c, IMPL_CACHE_FLUSH *state) +{ + uint32_t n; + + /* + * Implement the 32 bit xorshift as suggested by George Marsaglia in: + * https://doi.org/10.18637/jss.v008.i14 + * + * This is a very fast PRNG so there is no need to extract bits one at a + * time and use the entire value each time. + */ + n = state->seed; + n ^= n << 13; + n ^= n >> 17; + n ^= n << 5; + state->seed = n; + + if ((n & 1) != 0) + impl_cache_free(lh_QUERY_delete(state->cache, c)); + else + state->nelem++; +} + +static void impl_cache_flush_one_alg(ossl_uintmax_t idx, ALGORITHM *alg, + void *v) +{ + IMPL_CACHE_FLUSH *state = (IMPL_CACHE_FLUSH *)v; + + state->cache = alg->cache; + lh_QUERY_doall_IMPL_CACHE_FLUSH(state->cache, &impl_cache_flush_cache, + state); +} + +static void ossl_method_cache_flush_some(OSSL_METHOD_STORE *store) +{ + IMPL_CACHE_FLUSH state; + static TSAN_QUALIFIER uint32_t global_seed = 1; + + state.nelem = 0; + state.using_global_seed = 0; + if ((state.seed = OPENSSL_rdtsc()) == 0) { + /* If there is no timer available, seed another way */ + state.using_global_seed = 1; + state.seed = tsan_load(&global_seed); + } + store->cache_need_flush = 0; + ossl_sa_ALGORITHM_doall_arg(store->algs, &impl_cache_flush_one_alg, &state); + store->cache_nelem = state.nelem; + /* Without a timer, update the global seed */ + if (state.using_global_seed) + tsan_store(&global_seed, state.seed); +} + +int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov, + int nid, const char *prop_query, void **method) +{ + ALGORITHM *alg; + QUERY elem, *r; + int res = 0; + + if (nid <= 0 || store == NULL || prop_query == NULL) + return 0; + + if (!ossl_property_read_lock(store)) + return 0; + alg = ossl_method_store_retrieve(store, nid); + if (alg == NULL) + goto err; + + elem.query = prop_query; + elem.provider = prov; + r = lh_QUERY_retrieve(alg->cache, &elem); + if (r == NULL) + goto err; + if (ossl_method_up_ref(&r->method)) { + *method = r->method.method; + res = 1; + } +err: + ossl_property_unlock(store); + return res; +} + +int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov, + int nid, const char *prop_query, void *method, + int (*method_up_ref)(void *), + void (*method_destruct)(void *)) +{ + QUERY elem, *old, *p = NULL; + ALGORITHM *alg; + size_t len; + int res = 1; + + if (nid <= 0 || store == NULL || prop_query == NULL) + return 0; + + if (!ossl_assert(prov != NULL)) + return 0; + + if (!ossl_property_write_lock(store)) + return 0; + if (store->cache_need_flush) + ossl_method_cache_flush_some(store); + alg = ossl_method_store_retrieve(store, nid); + if (alg == NULL) + goto err; + + if (method == NULL) { + elem.query = prop_query; + elem.provider = prov; + if ((old = lh_QUERY_delete(alg->cache, &elem)) != NULL) { + impl_cache_free(old); + store->cache_nelem--; + } + goto end; + } + p = OPENSSL_malloc(sizeof(*p) + (len = strlen(prop_query))); + if (p != NULL) { + p->query = p->body; + p->provider = prov; + p->method.method = method; + p->method.up_ref = method_up_ref; + p->method.free = method_destruct; + if (!ossl_method_up_ref(&p->method)) + goto err; + memcpy((char *)p->query, prop_query, len + 1); + if ((old = lh_QUERY_insert(alg->cache, p)) != NULL) { + impl_cache_free(old); + goto end; + } + if (!lh_QUERY_error(alg->cache)) { + if (++store->cache_nelem >= IMPL_CACHE_FLUSH_THRESHOLD) + store->cache_need_flush = 1; + goto end; + } + ossl_method_free(&p->method); + } +err: + res = 0; + OPENSSL_free(p); +end: + ossl_property_unlock(store); + return res; +} diff --git a/crypto/openssl/crypto/property/property_err.c b/crypto/openssl/crypto/property/property_err.c new file mode 100644 index 000000000000..9a25d602282e --- /dev/null +++ b/crypto/openssl/crypto/property/property_err.c @@ -0,0 +1,46 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/propertyerr.h" + +#ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA PROP_str_reasons[] = { + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NAME_TOO_LONG), "name too long"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_ASCII_CHARACTER), + "not an ascii character"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_HEXADECIMAL_DIGIT), + "not an hexadecimal digit"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_IDENTIFIER), "not an identifier"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_OCTAL_DIGIT), + "not an octal digit"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_A_DECIMAL_DIGIT), + "not a decimal digit"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_MATCHING_STRING_DELIMITER), + "no matching string delimiter"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_VALUE), "no value"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_PARSE_FAILED), "parse failed"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_STRING_TOO_LONG), "string too long"}, + {ERR_PACK(ERR_LIB_PROP, 0, PROP_R_TRAILING_CHARACTERS), + "trailing characters"}, + {0, NULL} +}; + +#endif + +int ossl_err_load_PROP_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(PROP_str_reasons[0].error) == NULL) + ERR_load_strings_const(PROP_str_reasons); +#endif + return 1; +} diff --git a/crypto/openssl/crypto/property/property_local.h b/crypto/openssl/crypto/property/property_local.h new file mode 100644 index 000000000000..797fb3bf5f2b --- /dev/null +++ b/crypto/openssl/crypto/property/property_local.h @@ -0,0 +1,55 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/property.h" + +typedef int OSSL_PROPERTY_IDX; + +typedef enum { + OSSL_PROPERTY_OPER_EQ, OSSL_PROPERTY_OPER_NE, OSSL_PROPERTY_OVERRIDE +} OSSL_PROPERTY_OPER; + +struct ossl_property_definition_st { + OSSL_PROPERTY_IDX name_idx; + OSSL_PROPERTY_TYPE type; + OSSL_PROPERTY_OPER oper; + unsigned int optional : 1; + union { + int64_t int_val; /* Signed integer */ + OSSL_PROPERTY_IDX str_val; /* String */ + } v; +}; + +struct ossl_property_list_st { + int num_properties; + unsigned int has_optional : 1; + OSSL_PROPERTY_DEFINITION properties[1]; +}; + +#define OSSL_PROPERTY_TRUE 1 +#define OSSL_PROPERTY_FALSE 2 + +/* Property string functions */ +OSSL_PROPERTY_IDX ossl_property_name(OSSL_LIB_CTX *ctx, const char *s, + int create); +const char *ossl_property_name_str(OSSL_LIB_CTX *ctx, OSSL_PROPERTY_IDX idx); +OSSL_PROPERTY_IDX ossl_property_value(OSSL_LIB_CTX *ctx, const char *s, + int create); +const char *ossl_property_value_str(OSSL_LIB_CTX *ctx, OSSL_PROPERTY_IDX idx); + +/* Property list functions */ +void ossl_property_free(OSSL_PROPERTY_LIST *p); +int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query); + +/* Property definition cache functions */ +OSSL_PROPERTY_LIST *ossl_prop_defn_get(OSSL_LIB_CTX *ctx, const char *prop); +int ossl_prop_defn_set(OSSL_LIB_CTX *ctx, const char *prop, + OSSL_PROPERTY_LIST **pl); diff --git a/crypto/openssl/crypto/property/property_parse.c b/crypto/openssl/crypto/property/property_parse.c new file mode 100644 index 000000000000..ca2bd33381bf --- /dev/null +++ b/crypto/openssl/crypto/property/property_parse.c @@ -0,0 +1,706 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/propertyerr.h" +#include "internal/property.h" +#include "crypto/ctype.h" +#include "internal/nelem.h" +#include "property_local.h" +#include "e_os.h" + +DEFINE_STACK_OF(OSSL_PROPERTY_DEFINITION) + +static const char *skip_space(const char *s) +{ + while (ossl_isspace(*s)) + s++; + return s; +} + +static int match_ch(const char *t[], char m) +{ + const char *s = *t; + + if (*s == m) { + *t = skip_space(s + 1); + return 1; + } + return 0; +} + +#define MATCH(s, m) match(s, m, sizeof(m) - 1) + +static int match(const char *t[], const char m[], size_t m_len) +{ + const char *s = *t; + + if (OPENSSL_strncasecmp(s, m, m_len) == 0) { + *t = skip_space(s + m_len); + return 1; + } + return 0; +} + +static int parse_name(OSSL_LIB_CTX *ctx, const char *t[], int create, + OSSL_PROPERTY_IDX *idx) +{ + char name[100]; + int err = 0; + size_t i = 0; + const char *s = *t; + int user_name = 0; + + for (;;) { + if (!ossl_isalpha(*s)) { + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_IDENTIFIER, + "HERE-->%s", *t); + return 0; + } + do { + if (i < sizeof(name) - 1) + name[i++] = ossl_tolower(*s); + else + err = 1; + } while (*++s == '_' || ossl_isalnum(*s)); + if (*s != '.') + break; + user_name = 1; + if (i < sizeof(name) - 1) + name[i++] = *s; + else + err = 1; + s++; + } + name[i] = '\0'; + if (err) { + ERR_raise_data(ERR_LIB_PROP, PROP_R_NAME_TOO_LONG, "HERE-->%s", *t); + return 0; + } + *t = skip_space(s); + *idx = ossl_property_name(ctx, name, user_name && create); + return 1; +} + +static int parse_number(const char *t[], OSSL_PROPERTY_DEFINITION *res) +{ + const char *s = *t; + int64_t v = 0; + + if (!ossl_isdigit(*s)) + return 0; + do { + v = v * 10 + (*s++ - '0'); + } while (ossl_isdigit(*s)); + if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_A_DECIMAL_DIGIT, + "HERE-->%s", *t); + return 0; + } + *t = skip_space(s); + res->type = OSSL_PROPERTY_TYPE_NUMBER; + res->v.int_val = v; + return 1; +} + +static int parse_hex(const char *t[], OSSL_PROPERTY_DEFINITION *res) +{ + const char *s = *t; + int64_t v = 0; + + if (!ossl_isxdigit(*s)) + return 0; + do { + v <<= 4; + if (ossl_isdigit(*s)) + v += *s - '0'; + else + v += ossl_tolower(*s) - 'a'; + } while (ossl_isxdigit(*++s)); + if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_HEXADECIMAL_DIGIT, + "HERE-->%s", *t); + return 0; + } + *t = skip_space(s); + res->type = OSSL_PROPERTY_TYPE_NUMBER; + res->v.int_val = v; + return 1; +} + +static int parse_oct(const char *t[], OSSL_PROPERTY_DEFINITION *res) +{ + const char *s = *t; + int64_t v = 0; + + if (*s == '9' || *s == '8' || !ossl_isdigit(*s)) + return 0; + do { + v = (v << 3) + (*s - '0'); + } while (ossl_isdigit(*++s) && *s != '9' && *s != '8'); + if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_OCTAL_DIGIT, + "HERE-->%s", *t); + return 0; + } + *t = skip_space(s); + res->type = OSSL_PROPERTY_TYPE_NUMBER; + res->v.int_val = v; + return 1; +} + +static int parse_string(OSSL_LIB_CTX *ctx, const char *t[], char delim, + OSSL_PROPERTY_DEFINITION *res, const int create) +{ + char v[1000]; + const char *s = *t; + size_t i = 0; + int err = 0; + + while (*s != '\0' && *s != delim) { + if (i < sizeof(v) - 1) + v[i++] = *s; + else + err = 1; + s++; + } + if (*s == '\0') { + ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_MATCHING_STRING_DELIMITER, + "HERE-->%c%s", delim, *t); + return 0; + } + v[i] = '\0'; + if (err) { + ERR_raise_data(ERR_LIB_PROP, PROP_R_STRING_TOO_LONG, "HERE-->%s", *t); + } else { + res->v.str_val = ossl_property_value(ctx, v, create); + } + *t = skip_space(s + 1); + res->type = OSSL_PROPERTY_TYPE_STRING; + return !err; +} + +static int parse_unquoted(OSSL_LIB_CTX *ctx, const char *t[], + OSSL_PROPERTY_DEFINITION *res, const int create) +{ + char v[1000]; + const char *s = *t; + size_t i = 0; + int err = 0; + + if (*s == '\0' || *s == ',') + return 0; + while (ossl_isprint(*s) && !ossl_isspace(*s) && *s != ',') { + if (i < sizeof(v) - 1) + v[i++] = ossl_tolower(*s); + else + err = 1; + s++; + } + if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_ASCII_CHARACTER, + "HERE-->%s", s); + return 0; + } + v[i] = 0; + if (err) + ERR_raise_data(ERR_LIB_PROP, PROP_R_STRING_TOO_LONG, "HERE-->%s", *t); + else if ((res->v.str_val = ossl_property_value(ctx, v, create)) == 0) + err = 1; + *t = skip_space(s); + res->type = OSSL_PROPERTY_TYPE_STRING; + return !err; +} + +static int parse_value(OSSL_LIB_CTX *ctx, const char *t[], + OSSL_PROPERTY_DEFINITION *res, int create) +{ + const char *s = *t; + int r = 0; + + if (*s == '"' || *s == '\'') { + s++; + r = parse_string(ctx, &s, s[-1], res, create); + } else if (*s == '+') { + s++; + r = parse_number(&s, res); + } else if (*s == '-') { + s++; + r = parse_number(&s, res); + res->v.int_val = -res->v.int_val; + } else if (*s == '0' && s[1] == 'x') { + s += 2; + r = parse_hex(&s, res); + } else if (*s == '0' && ossl_isdigit(s[1])) { + s++; + r = parse_oct(&s, res); + } else if (ossl_isdigit(*s)) { + return parse_number(t, res); + } else if (ossl_isalpha(*s)) + return parse_unquoted(ctx, t, res, create); + if (r) + *t = s; + return r; +} + +static int pd_compare(const OSSL_PROPERTY_DEFINITION *const *p1, + const OSSL_PROPERTY_DEFINITION *const *p2) +{ + const OSSL_PROPERTY_DEFINITION *pd1 = *p1; + const OSSL_PROPERTY_DEFINITION *pd2 = *p2; + + if (pd1->name_idx < pd2->name_idx) + return -1; + if (pd1->name_idx > pd2->name_idx) + return 1; + return 0; +} + +static void pd_free(OSSL_PROPERTY_DEFINITION *pd) +{ + OPENSSL_free(pd); +} + +/* + * Convert a stack of property definitions and queries into a fixed array. + * The items are sorted for efficient query. The stack is not freed. + * This function also checks for duplicated names and returns an error if + * any exist. + */ +static OSSL_PROPERTY_LIST * +stack_to_property_list(OSSL_LIB_CTX *ctx, + STACK_OF(OSSL_PROPERTY_DEFINITION) *sk) +{ + const int n = sk_OSSL_PROPERTY_DEFINITION_num(sk); + OSSL_PROPERTY_LIST *r; + OSSL_PROPERTY_IDX prev_name_idx = 0; + int i; + + r = OPENSSL_malloc(sizeof(*r) + + (n <= 0 ? 0 : n - 1) * sizeof(r->properties[0])); + if (r != NULL) { + sk_OSSL_PROPERTY_DEFINITION_sort(sk); + + r->has_optional = 0; + for (i = 0; i < n; i++) { + r->properties[i] = *sk_OSSL_PROPERTY_DEFINITION_value(sk, i); + r->has_optional |= r->properties[i].optional; + + /* Check for duplicated names */ + if (i > 0 && r->properties[i].name_idx == prev_name_idx) { + OPENSSL_free(r); + ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED, + "Duplicated name `%s'", + ossl_property_name_str(ctx, prev_name_idx)); + return NULL; + } + prev_name_idx = r->properties[i].name_idx; + } + r->num_properties = n; + } + return r; +} + +OSSL_PROPERTY_LIST *ossl_parse_property(OSSL_LIB_CTX *ctx, const char *defn) +{ + OSSL_PROPERTY_DEFINITION *prop = NULL; + OSSL_PROPERTY_LIST *res = NULL; + STACK_OF(OSSL_PROPERTY_DEFINITION) *sk; + const char *s = defn; + int done; + + if (s == NULL || (sk = sk_OSSL_PROPERTY_DEFINITION_new(&pd_compare)) == NULL) + return NULL; + + s = skip_space(s); + done = *s == '\0'; + while (!done) { + const char *start = s; + + prop = OPENSSL_malloc(sizeof(*prop)); + if (prop == NULL) + goto err; + memset(&prop->v, 0, sizeof(prop->v)); + prop->optional = 0; + if (!parse_name(ctx, &s, 1, &prop->name_idx)) + goto err; + prop->oper = OSSL_PROPERTY_OPER_EQ; + if (prop->name_idx == 0) { + ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED, + "Unknown name HERE-->%s", start); + goto err; + } + if (match_ch(&s, '=')) { + if (!parse_value(ctx, &s, prop, 1)) { + ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_VALUE, + "HERE-->%s", start); + goto err; + } + } else { + /* A name alone means a true Boolean */ + prop->type = OSSL_PROPERTY_TYPE_STRING; + prop->v.str_val = OSSL_PROPERTY_TRUE; + } + + if (!sk_OSSL_PROPERTY_DEFINITION_push(sk, prop)) + goto err; + prop = NULL; + done = !match_ch(&s, ','); + } + if (*s != '\0') { + ERR_raise_data(ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS, + "HERE-->%s", s); + goto err; + } + res = stack_to_property_list(ctx, sk); + +err: + OPENSSL_free(prop); + sk_OSSL_PROPERTY_DEFINITION_pop_free(sk, &pd_free); + return res; +} + +OSSL_PROPERTY_LIST *ossl_parse_query(OSSL_LIB_CTX *ctx, const char *s, + int create_values) +{ + STACK_OF(OSSL_PROPERTY_DEFINITION) *sk; + OSSL_PROPERTY_LIST *res = NULL; + OSSL_PROPERTY_DEFINITION *prop = NULL; + int done; + + if (s == NULL || (sk = sk_OSSL_PROPERTY_DEFINITION_new(&pd_compare)) == NULL) + return NULL; + + s = skip_space(s); + done = *s == '\0'; + while (!done) { + prop = OPENSSL_malloc(sizeof(*prop)); + if (prop == NULL) + goto err; + memset(&prop->v, 0, sizeof(prop->v)); + + if (match_ch(&s, '-')) { + prop->oper = OSSL_PROPERTY_OVERRIDE; + prop->optional = 0; + if (!parse_name(ctx, &s, 1, &prop->name_idx)) + goto err; + goto skip_value; + } + prop->optional = match_ch(&s, '?'); + if (!parse_name(ctx, &s, 1, &prop->name_idx)) + goto err; + + if (match_ch(&s, '=')) { + prop->oper = OSSL_PROPERTY_OPER_EQ; + } else if (MATCH(&s, "!=")) { + prop->oper = OSSL_PROPERTY_OPER_NE; + } else { + /* A name alone is a Boolean comparison for true */ + prop->oper = OSSL_PROPERTY_OPER_EQ; + prop->type = OSSL_PROPERTY_TYPE_STRING; + prop->v.str_val = OSSL_PROPERTY_TRUE; + goto skip_value; + } + if (!parse_value(ctx, &s, prop, create_values)) + prop->type = OSSL_PROPERTY_TYPE_VALUE_UNDEFINED; + +skip_value: + if (!sk_OSSL_PROPERTY_DEFINITION_push(sk, prop)) + goto err; + prop = NULL; + done = !match_ch(&s, ','); + } + if (*s != '\0') { + ERR_raise_data(ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS, + "HERE-->%s", s); + goto err; + } + res = stack_to_property_list(ctx, sk); + +err: + OPENSSL_free(prop); + sk_OSSL_PROPERTY_DEFINITION_pop_free(sk, &pd_free); + return res; +} + +/* + * Compare a query against a definition. + * Return the number of clauses matched or -1 if a mandatory clause is false. + */ +int ossl_property_match_count(const OSSL_PROPERTY_LIST *query, + const OSSL_PROPERTY_LIST *defn) +{ + const OSSL_PROPERTY_DEFINITION *const q = query->properties; + const OSSL_PROPERTY_DEFINITION *const d = defn->properties; + int i = 0, j = 0, matches = 0; + OSSL_PROPERTY_OPER oper; + + while (i < query->num_properties) { + if ((oper = q[i].oper) == OSSL_PROPERTY_OVERRIDE) { + i++; + continue; + } + if (j < defn->num_properties) { + if (q[i].name_idx > d[j].name_idx) { /* skip defn, not in query */ + j++; + continue; + } + if (q[i].name_idx == d[j].name_idx) { /* both in defn and query */ + const int eq = q[i].type == d[j].type + && memcmp(&q[i].v, &d[j].v, sizeof(q[i].v)) == 0; + + if ((eq && oper == OSSL_PROPERTY_OPER_EQ) + || (!eq && oper == OSSL_PROPERTY_OPER_NE)) + matches++; + else if (!q[i].optional) + return -1; + i++; + j++; + continue; + } + } + + /* + * Handle the cases of a missing value and a query with no corresponding + * definition. The former fails for any comparison except inequality, + * the latter is treated as a comparison against the Boolean false. + */ + if (q[i].type == OSSL_PROPERTY_TYPE_VALUE_UNDEFINED) { + if (oper == OSSL_PROPERTY_OPER_NE) + matches++; + else if (!q[i].optional) + return -1; + } else if (q[i].type != OSSL_PROPERTY_TYPE_STRING + || (oper == OSSL_PROPERTY_OPER_EQ + && q[i].v.str_val != OSSL_PROPERTY_FALSE) + || (oper == OSSL_PROPERTY_OPER_NE + && q[i].v.str_val == OSSL_PROPERTY_FALSE)) { + if (!q[i].optional) + return -1; + } else { + matches++; + } + i++; + } + return matches; +} + +void ossl_property_free(OSSL_PROPERTY_LIST *p) +{ + OPENSSL_free(p); +} + +/* + * Merge two property lists. + * If there is a common name, the one from the first list is used. + */ +OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a, + const OSSL_PROPERTY_LIST *b) +{ + const OSSL_PROPERTY_DEFINITION *const ap = a->properties; + const OSSL_PROPERTY_DEFINITION *const bp = b->properties; + const OSSL_PROPERTY_DEFINITION *copy; + OSSL_PROPERTY_LIST *r; + int i, j, n; + const int t = a->num_properties + b->num_properties; + + r = OPENSSL_malloc(sizeof(*r) + + (t == 0 ? 0 : t - 1) * sizeof(r->properties[0])); + if (r == NULL) + return NULL; + + r->has_optional = 0; + for (i = j = n = 0; i < a->num_properties || j < b->num_properties; n++) { + if (i >= a->num_properties) { + copy = &bp[j++]; + } else if (j >= b->num_properties) { + copy = &ap[i++]; + } else if (ap[i].name_idx <= bp[j].name_idx) { + if (ap[i].name_idx == bp[j].name_idx) + j++; + copy = &ap[i++]; + } else { + copy = &bp[j++]; + } + memcpy(r->properties + n, copy, sizeof(r->properties[0])); + r->has_optional |= copy->optional; + } + r->num_properties = n; + if (n != t) + r = OPENSSL_realloc(r, sizeof(*r) + (n - 1) * sizeof(r->properties[0])); + return r; +} + +int ossl_property_parse_init(OSSL_LIB_CTX *ctx) +{ + static const char *const predefined_names[] = { + "provider", /* Name of provider (default, legacy, fips) */ + "version", /* Version number of this provider */ + "fips", /* FIPS validated or FIPS supporting algorithm */ + "output", /* Output type for encoders */ + "input", /* Input type for decoders */ + "structure", /* Structure name for encoders and decoders */ + }; + size_t i; + + for (i = 0; i < OSSL_NELEM(predefined_names); i++) + if (ossl_property_name(ctx, predefined_names[i], 1) == 0) + goto err; + + /* + * Pre-populate the two Boolean values. We must do them before any other + * values and in this order so that we get the same index as the global + * OSSL_PROPERTY_TRUE and OSSL_PROPERTY_FALSE values + */ + if ((ossl_property_value(ctx, "yes", 1) != OSSL_PROPERTY_TRUE) + || (ossl_property_value(ctx, "no", 1) != OSSL_PROPERTY_FALSE)) + goto err; + + return 1; +err: + return 0; +} + +static void put_char(char ch, char **buf, size_t *remain, size_t *needed) +{ + if (*remain == 0) { + ++*needed; + return; + } + if (*remain == 1) + **buf = '\0'; + else + **buf = ch; + ++*buf; + ++*needed; + --*remain; +} + +static void put_str(const char *str, char **buf, size_t *remain, size_t *needed) +{ + size_t olen, len; + + len = olen = strlen(str); + *needed += len; + + if (*remain == 0) + return; + + if (*remain < len + 1) + len = *remain - 1; + + if (len > 0) { + memcpy(*buf, str, len); + *buf += len; + *remain -= len; + } + + if (len < olen && *remain == 1) { + **buf = '\0'; + ++*buf; + --*remain; + } +} + +static void put_num(int64_t val, char **buf, size_t *remain, size_t *needed) +{ + int64_t tmpval = val; + size_t len = 1; + + if (tmpval < 0) { + len++; + tmpval = -tmpval; + } + for (; tmpval > 9; len++, tmpval /= 10); + + *needed += len; + + if (*remain == 0) + return; + + BIO_snprintf(*buf, *remain, "%lld", (long long int)val); + if (*remain < len) { + *buf += *remain; + *remain = 0; + } else { + *buf += len; + *remain -= len; + } +} + +size_t ossl_property_list_to_string(OSSL_LIB_CTX *ctx, + const OSSL_PROPERTY_LIST *list, char *buf, + size_t bufsize) +{ + int i; + const OSSL_PROPERTY_DEFINITION *prop = NULL; + size_t needed = 0; + const char *val; + + if (list == NULL) { + if (bufsize > 0) + *buf = '\0'; + return 1; + } + if (list->num_properties != 0) + prop = &list->properties[list->num_properties - 1]; + for (i = 0; i < list->num_properties; i++, prop--) { + /* Skip invalid names */ + if (prop->name_idx == 0) + continue; + + if (needed > 0) + put_char(',', &buf, &bufsize, &needed); + + if (prop->optional) + put_char('?', &buf, &bufsize, &needed); + else if (prop->oper == OSSL_PROPERTY_OVERRIDE) + put_char('-', &buf, &bufsize, &needed); + + val = ossl_property_name_str(ctx, prop->name_idx); + if (val == NULL) + return 0; + put_str(val, &buf, &bufsize, &needed); + + switch (prop->oper) { + case OSSL_PROPERTY_OPER_NE: + put_char('!', &buf, &bufsize, &needed); + /* fall through */ + case OSSL_PROPERTY_OPER_EQ: + put_char('=', &buf, &bufsize, &needed); + /* put value */ + switch (prop->type) { + case OSSL_PROPERTY_TYPE_STRING: + val = ossl_property_value_str(ctx, prop->v.str_val); + if (val == NULL) + return 0; + put_str(val, &buf, &bufsize, &needed); + break; + + case OSSL_PROPERTY_TYPE_NUMBER: + put_num(prop->v.int_val, &buf, &bufsize, &needed); + break; + + default: + return 0; + } + break; + default: + /* do nothing */ + break; + } + } + + put_char('\0', &buf, &bufsize, &needed); + return needed; +} diff --git a/crypto/openssl/crypto/property/property_query.c b/crypto/openssl/crypto/property/property_query.c new file mode 100644 index 000000000000..28cc704840a4 --- /dev/null +++ b/crypto/openssl/crypto/property/property_query.c @@ -0,0 +1,82 @@ +/* + * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/propertyerr.h" +#include "internal/property.h" +#include "property_local.h" + +static int property_idx_cmp(const void *keyp, const void *compare) +{ + OSSL_PROPERTY_IDX key = *(const OSSL_PROPERTY_IDX *)keyp; + const OSSL_PROPERTY_DEFINITION *defn = + (const OSSL_PROPERTY_DEFINITION *)compare; + + return key - defn->name_idx; +} + +const OSSL_PROPERTY_DEFINITION * +ossl_property_find_property(const OSSL_PROPERTY_LIST *list, + OSSL_LIB_CTX *libctx, const char *name) +{ + OSSL_PROPERTY_IDX name_idx; + + if (list == NULL || name == NULL + || (name_idx = ossl_property_name(libctx, name, 0)) == 0) + return NULL; + + return ossl_bsearch(&name_idx, list->properties, list->num_properties, + sizeof(*list->properties), &property_idx_cmp, 0); +} + +OSSL_PROPERTY_TYPE ossl_property_get_type(const OSSL_PROPERTY_DEFINITION *prop) +{ + return prop->type; +} + +const char *ossl_property_get_string_value(OSSL_LIB_CTX *libctx, + const OSSL_PROPERTY_DEFINITION *prop) +{ + const char *value = NULL; + + if (prop != NULL && prop->type == OSSL_PROPERTY_TYPE_STRING) + value = ossl_property_value_str(libctx, prop->v.str_val); + return value; +} + +int64_t ossl_property_get_number_value(const OSSL_PROPERTY_DEFINITION *prop) +{ + int64_t value = 0; + + if (prop != NULL && prop->type == OSSL_PROPERTY_TYPE_NUMBER) + value = prop->v.int_val; + return value; +} + +/* Does a property query have any optional clauses */ +int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query) +{ + return query->has_optional ? 1 : 0; +} + +int ossl_property_is_enabled(OSSL_LIB_CTX *ctx, const char *property_name, + const OSSL_PROPERTY_LIST *prop_list) +{ + const OSSL_PROPERTY_DEFINITION *prop; + + prop = ossl_property_find_property(prop_list, ctx, property_name); + /* Do a separate check for override as it does not set type */ + if (prop == NULL || prop->optional || prop->oper == OSSL_PROPERTY_OVERRIDE) + return 0; + return (prop->type == OSSL_PROPERTY_TYPE_STRING + && ((prop->oper == OSSL_PROPERTY_OPER_EQ + && prop->v.str_val == OSSL_PROPERTY_TRUE) + || (prop->oper == OSSL_PROPERTY_OPER_NE + && prop->v.str_val != OSSL_PROPERTY_TRUE))); +} + diff --git a/crypto/openssl/crypto/property/property_string.c b/crypto/openssl/crypto/property/property_string.c new file mode 100644 index 000000000000..ef87a6a78235 --- /dev/null +++ b/crypto/openssl/crypto/property/property_string.c @@ -0,0 +1,246 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "crypto/lhash.h" +#include "property_local.h" + +/* + * Property strings are a consolidation of all strings seen by the property + * subsystem. There are two name spaces to keep property names separate from + * property values (numeric values are not expected to be cached however). + * They allow a rapid conversion from a string to a unique index and any + * subsequent string comparison can be done via an integer compare. + * + * This implementation uses OpenSSL's standard hash table. There are more + * space and time efficient algorithms if this becomes a bottleneck. + */ + +typedef struct { + const char *s; + OSSL_PROPERTY_IDX idx; + char body[1]; +} PROPERTY_STRING; + +DEFINE_LHASH_OF(PROPERTY_STRING); +typedef LHASH_OF(PROPERTY_STRING) PROP_TABLE; + +typedef struct { + CRYPTO_RWLOCK *lock; + PROP_TABLE *prop_names; + PROP_TABLE *prop_values; + OSSL_PROPERTY_IDX prop_name_idx; + OSSL_PROPERTY_IDX prop_value_idx; +} PROPERTY_STRING_DATA; + +static unsigned long property_hash(const PROPERTY_STRING *a) +{ + return OPENSSL_LH_strhash(a->s); +} + +static int property_cmp(const PROPERTY_STRING *a, const PROPERTY_STRING *b) +{ + return strcmp(a->s, b->s); +} + +static void property_free(PROPERTY_STRING *ps) +{ + OPENSSL_free(ps); +} + +static void property_table_free(PROP_TABLE **pt) +{ + PROP_TABLE *t = *pt; + + if (t != NULL) { + lh_PROPERTY_STRING_doall(t, &property_free); + lh_PROPERTY_STRING_free(t); + *pt = NULL; + } +} + +static void property_string_data_free(void *vpropdata) +{ + PROPERTY_STRING_DATA *propdata = vpropdata; + + if (propdata == NULL) + return; + + CRYPTO_THREAD_lock_free(propdata->lock); + property_table_free(&propdata->prop_names); + property_table_free(&propdata->prop_values); + propdata->prop_name_idx = propdata->prop_value_idx = 0; + + OPENSSL_free(propdata); +} + +static void *property_string_data_new(OSSL_LIB_CTX *ctx) { + PROPERTY_STRING_DATA *propdata = OPENSSL_zalloc(sizeof(*propdata)); + + if (propdata == NULL) + return NULL; + + propdata->lock = CRYPTO_THREAD_lock_new(); + if (propdata->lock == NULL) + goto err; + + propdata->prop_names = lh_PROPERTY_STRING_new(&property_hash, + &property_cmp); + if (propdata->prop_names == NULL) + goto err; + + propdata->prop_values = lh_PROPERTY_STRING_new(&property_hash, + &property_cmp); + if (propdata->prop_values == NULL) + goto err; + + return propdata; + +err: + property_string_data_free(propdata); + return NULL; +} + +static const OSSL_LIB_CTX_METHOD property_string_data_method = { + OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, + property_string_data_new, + property_string_data_free, +}; + +static PROPERTY_STRING *new_property_string(const char *s, + OSSL_PROPERTY_IDX *pidx) +{ + const size_t l = strlen(s); + PROPERTY_STRING *ps = OPENSSL_malloc(sizeof(*ps) + l); + + if (ps != NULL) { + memcpy(ps->body, s, l + 1); + ps->s = ps->body; + ps->idx = ++*pidx; + if (ps->idx == 0) { + OPENSSL_free(ps); + return NULL; + } + } + return ps; +} + +static OSSL_PROPERTY_IDX ossl_property_string(CRYPTO_RWLOCK *lock, + PROP_TABLE *t, + OSSL_PROPERTY_IDX *pidx, + const char *s) +{ + PROPERTY_STRING p, *ps, *ps_new; + + p.s = s; + if (!CRYPTO_THREAD_read_lock(lock)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UNABLE_TO_GET_READ_LOCK); + return 0; + } + ps = lh_PROPERTY_STRING_retrieve(t, &p); + if (ps == NULL && pidx != NULL) { + CRYPTO_THREAD_unlock(lock); + if (!CRYPTO_THREAD_write_lock(lock)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UNABLE_TO_GET_WRITE_LOCK); + return 0; + } + ps = lh_PROPERTY_STRING_retrieve(t, &p); + if (ps == NULL && (ps_new = new_property_string(s, pidx)) != NULL) { + lh_PROPERTY_STRING_insert(t, ps_new); + if (lh_PROPERTY_STRING_error(t)) { + property_free(ps_new); + CRYPTO_THREAD_unlock(lock); + return 0; + } + ps = ps_new; + } + } + CRYPTO_THREAD_unlock(lock); + return ps != NULL ? ps->idx : 0; +} + +struct find_str_st { + const char *str; + OSSL_PROPERTY_IDX idx; +}; + +static void find_str_fn(PROPERTY_STRING *prop, void *vfindstr) +{ + struct find_str_st *findstr = vfindstr; + + if (prop->idx == findstr->idx) + findstr->str = prop->s; +} + +static const char *ossl_property_str(int name, OSSL_LIB_CTX *ctx, + OSSL_PROPERTY_IDX idx) +{ + struct find_str_st findstr; + PROPERTY_STRING_DATA *propdata + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_PROPERTY_STRING_INDEX, + &property_string_data_method); + + if (propdata == NULL) + return NULL; + + findstr.str = NULL; + findstr.idx = idx; + + if (!CRYPTO_THREAD_read_lock(propdata->lock)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UNABLE_TO_GET_READ_LOCK); + return NULL; + } + lh_PROPERTY_STRING_doall_arg(name ? propdata->prop_names + : propdata->prop_values, + find_str_fn, &findstr); + CRYPTO_THREAD_unlock(propdata->lock); + + return findstr.str; +} + +OSSL_PROPERTY_IDX ossl_property_name(OSSL_LIB_CTX *ctx, const char *s, + int create) +{ + PROPERTY_STRING_DATA *propdata + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_PROPERTY_STRING_INDEX, + &property_string_data_method); + + if (propdata == NULL) + return 0; + return ossl_property_string(propdata->lock, propdata->prop_names, + create ? &propdata->prop_name_idx : NULL, + s); +} + +const char *ossl_property_name_str(OSSL_LIB_CTX *ctx, OSSL_PROPERTY_IDX idx) +{ + return ossl_property_str(1, ctx, idx); +} + +OSSL_PROPERTY_IDX ossl_property_value(OSSL_LIB_CTX *ctx, const char *s, + int create) +{ + PROPERTY_STRING_DATA *propdata + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_PROPERTY_STRING_INDEX, + &property_string_data_method); + + if (propdata == NULL) + return 0; + return ossl_property_string(propdata->lock, propdata->prop_values, + create ? &propdata->prop_value_idx : NULL, + s); +} + +const char *ossl_property_value_str(OSSL_LIB_CTX *ctx, OSSL_PROPERTY_IDX idx) +{ + return ossl_property_str(0, ctx, idx); +} diff --git a/crypto/openssl/crypto/provider.c b/crypto/openssl/crypto/provider.c new file mode 100644 index 000000000000..114b42692940 --- /dev/null +++ b/crypto/openssl/crypto/provider.c @@ -0,0 +1,149 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include "internal/provider.h" +#include "provider_local.h" + +OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name, + int retain_fallbacks) +{ + OSSL_PROVIDER *prov = NULL, *actual; + int isnew = 0; + + /* Find it or create it */ + if ((prov = ossl_provider_find(libctx, name, 0)) == NULL) { + if ((prov = ossl_provider_new(libctx, name, NULL, 0)) == NULL) + return NULL; + isnew = 1; + } + + if (!ossl_provider_activate(prov, 1, 0)) { + ossl_provider_free(prov); + return NULL; + } + + actual = prov; + if (isnew && !ossl_provider_add_to_store(prov, &actual, retain_fallbacks)) { + ossl_provider_deactivate(prov, 1); + ossl_provider_free(prov); + return NULL; + } + if (actual != prov) { + if (!ossl_provider_activate(actual, 1, 0)) { + ossl_provider_free(actual); + return NULL; + } + } + + return actual; +} + +OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name) +{ + /* Any attempt to load a provider disables auto-loading of defaults */ + if (ossl_provider_disable_fallback_loading(libctx)) + return OSSL_PROVIDER_try_load(libctx, name, 0); + return NULL; +} + +int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov) +{ + if (!ossl_provider_deactivate(prov, 1)) + return 0; + ossl_provider_free(prov); + return 1; +} + +const OSSL_PARAM *OSSL_PROVIDER_gettable_params(const OSSL_PROVIDER *prov) +{ + return ossl_provider_gettable_params(prov); +} + +int OSSL_PROVIDER_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) +{ + return ossl_provider_get_params(prov, params); +} + +const OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov, + int operation_id, + int *no_cache) +{ + return ossl_provider_query_operation(prov, operation_id, no_cache); +} + +void OSSL_PROVIDER_unquery_operation(const OSSL_PROVIDER *prov, + int operation_id, + const OSSL_ALGORITHM *algs) +{ + ossl_provider_unquery_operation(prov, operation_id, algs); +} + +void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov) +{ + return ossl_provider_prov_ctx(prov); +} + +const OSSL_DISPATCH *OSSL_PROVIDER_get0_dispatch(const OSSL_PROVIDER *prov) +{ + return ossl_provider_get0_dispatch(prov); +} + +int OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov) +{ + return ossl_provider_self_test(prov); +} + +int OSSL_PROVIDER_get_capabilities(const OSSL_PROVIDER *prov, + const char *capability, + OSSL_CALLBACK *cb, + void *arg) +{ + return ossl_provider_get_capabilities(prov, capability, cb, arg); +} + +int OSSL_PROVIDER_add_builtin(OSSL_LIB_CTX *libctx, const char *name, + OSSL_provider_init_fn *init_fn) +{ + OSSL_PROVIDER_INFO entry; + + if (name == NULL || init_fn == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + memset(&entry, 0, sizeof(entry)); + entry.name = OPENSSL_strdup(name); + if (entry.name == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + entry.init = init_fn; + if (!ossl_provider_info_add_to_store(libctx, &entry)) { + ossl_provider_info_clear(&entry); + return 0; + } + return 1; +} + +const char *OSSL_PROVIDER_get0_name(const OSSL_PROVIDER *prov) +{ + return ossl_provider_name(prov); +} + +int OSSL_PROVIDER_do_all(OSSL_LIB_CTX *ctx, + int (*cb)(OSSL_PROVIDER *provider, + void *cbdata), + void *cbdata) +{ + return ossl_provider_doall_activated(ctx, cb, cbdata); +} diff --git a/crypto/openssl/crypto/provider_child.c b/crypto/openssl/crypto/provider_child.c new file mode 100644 index 000000000000..861bcb035baa --- /dev/null +++ b/crypto/openssl/crypto/provider_child.c @@ -0,0 +1,328 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include "internal/provider.h" +#include "internal/cryptlib.h" +#include "crypto/evp.h" + +DEFINE_STACK_OF(OSSL_PROVIDER) + +struct child_prov_globals { + const OSSL_CORE_HANDLE *handle; + const OSSL_CORE_HANDLE *curr_prov; + CRYPTO_RWLOCK *lock; + OSSL_FUNC_core_get_libctx_fn *c_get_libctx; + OSSL_FUNC_provider_register_child_cb_fn *c_provider_register_child_cb; + OSSL_FUNC_provider_deregister_child_cb_fn *c_provider_deregister_child_cb; + OSSL_FUNC_provider_name_fn *c_prov_name; + OSSL_FUNC_provider_get0_provider_ctx_fn *c_prov_get0_provider_ctx; + OSSL_FUNC_provider_get0_dispatch_fn *c_prov_get0_dispatch; + OSSL_FUNC_provider_up_ref_fn *c_prov_up_ref; + OSSL_FUNC_provider_free_fn *c_prov_free; +}; + +static void *child_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx) +{ + return OPENSSL_zalloc(sizeof(struct child_prov_globals)); +} + +static void child_prov_ossl_ctx_free(void *vgbl) +{ + struct child_prov_globals *gbl = vgbl; + + CRYPTO_THREAD_lock_free(gbl->lock); + OPENSSL_free(gbl); +} + +static const OSSL_LIB_CTX_METHOD child_prov_ossl_ctx_method = { + OSSL_LIB_CTX_METHOD_LOW_PRIORITY, + child_prov_ossl_ctx_new, + child_prov_ossl_ctx_free, +}; + +static OSSL_provider_init_fn ossl_child_provider_init; + +static int ossl_child_provider_init(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in, + const OSSL_DISPATCH **out, + void **provctx) +{ + OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL; + OSSL_LIB_CTX *ctx; + struct child_prov_globals *gbl; + + for (; in->function_id != 0; in++) { + switch (in->function_id) { + case OSSL_FUNC_CORE_GET_LIBCTX: + c_get_libctx = OSSL_FUNC_core_get_libctx(in); + break; + default: + /* Just ignore anything we don't understand */ + break; + } + } + + if (c_get_libctx == NULL) + return 0; + + /* + * We need an OSSL_LIB_CTX but c_get_libctx returns OPENSSL_CORE_CTX. We are + * a built-in provider and so we can get away with this cast. Normal + * providers can't do this. + */ + ctx = (OSSL_LIB_CTX *)c_get_libctx(handle); + + gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return 0; + + *provctx = gbl->c_prov_get0_provider_ctx(gbl->curr_prov); + *out = gbl->c_prov_get0_dispatch(gbl->curr_prov); + + return 1; +} + +static int provider_create_child_cb(const OSSL_CORE_HANDLE *prov, void *cbdata) +{ + OSSL_LIB_CTX *ctx = cbdata; + struct child_prov_globals *gbl; + const char *provname; + OSSL_PROVIDER *cprov; + int ret = 0; + + gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return 0; + + if (!CRYPTO_THREAD_write_lock(gbl->lock)) + return 0; + + provname = gbl->c_prov_name(prov); + + /* + * We're operating under a lock so we can store the "current" provider in + * the global data. + */ + gbl->curr_prov = prov; + + if ((cprov = ossl_provider_find(ctx, provname, 1)) != NULL) { + /* + * We free the newly created ref. We rely on the provider sticking around + * in the provider store. + */ + ossl_provider_free(cprov); + + /* + * The provider already exists. It could be a previously created child, + * or it could have been explicitly loaded. If explicitly loaded we + * ignore it - i.e. we don't start treating it like a child. + */ + if (!ossl_provider_activate(cprov, 0, 1)) + goto err; + } else { + /* + * Create it - passing 1 as final param so we don't try and recursively + * init children + */ + if ((cprov = ossl_provider_new(ctx, provname, ossl_child_provider_init, + 1)) == NULL) + goto err; + + if (!ossl_provider_activate(cprov, 0, 0)) { + ossl_provider_free(cprov); + goto err; + } + + if (!ossl_provider_set_child(cprov, prov) + || !ossl_provider_add_to_store(cprov, NULL, 0)) { + ossl_provider_deactivate(cprov, 0); + ossl_provider_free(cprov); + goto err; + } + } + + ret = 1; + err: + CRYPTO_THREAD_unlock(gbl->lock); + return ret; +} + +static int provider_remove_child_cb(const OSSL_CORE_HANDLE *prov, void *cbdata) +{ + OSSL_LIB_CTX *ctx = cbdata; + struct child_prov_globals *gbl; + const char *provname; + OSSL_PROVIDER *cprov; + + gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return 0; + + provname = gbl->c_prov_name(prov); + cprov = ossl_provider_find(ctx, provname, 1); + if (cprov == NULL) + return 0; + /* + * ossl_provider_find ups the ref count, so we free it again here. We can + * rely on the provider store reference count. + */ + ossl_provider_free(cprov); + if (ossl_provider_is_child(cprov) + && !ossl_provider_deactivate(cprov, 1)) + return 0; + + return 1; +} + +static int provider_global_props_cb(const char *props, void *cbdata) +{ + OSSL_LIB_CTX *ctx = cbdata; + + return evp_set_default_properties_int(ctx, props, 0, 1); +} + +int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx, + const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in) +{ + struct child_prov_globals *gbl; + + if (ctx == NULL) + return 0; + + gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return 0; + + gbl->handle = handle; + for (; in->function_id != 0; in++) { + switch (in->function_id) { + case OSSL_FUNC_CORE_GET_LIBCTX: + gbl->c_get_libctx = OSSL_FUNC_core_get_libctx(in); + break; + case OSSL_FUNC_PROVIDER_REGISTER_CHILD_CB: + gbl->c_provider_register_child_cb + = OSSL_FUNC_provider_register_child_cb(in); + break; + case OSSL_FUNC_PROVIDER_DEREGISTER_CHILD_CB: + gbl->c_provider_deregister_child_cb + = OSSL_FUNC_provider_deregister_child_cb(in); + break; + case OSSL_FUNC_PROVIDER_NAME: + gbl->c_prov_name = OSSL_FUNC_provider_name(in); + break; + case OSSL_FUNC_PROVIDER_GET0_PROVIDER_CTX: + gbl->c_prov_get0_provider_ctx + = OSSL_FUNC_provider_get0_provider_ctx(in); + break; + case OSSL_FUNC_PROVIDER_GET0_DISPATCH: + gbl->c_prov_get0_dispatch = OSSL_FUNC_provider_get0_dispatch(in); + break; + case OSSL_FUNC_PROVIDER_UP_REF: + gbl->c_prov_up_ref + = OSSL_FUNC_provider_up_ref(in); + break; + case OSSL_FUNC_PROVIDER_FREE: + gbl->c_prov_free = OSSL_FUNC_provider_free(in); + break; + default: + /* Just ignore anything we don't understand */ + break; + } + } + + if (gbl->c_get_libctx == NULL + || gbl->c_provider_register_child_cb == NULL + || gbl->c_prov_name == NULL + || gbl->c_prov_get0_provider_ctx == NULL + || gbl->c_prov_get0_dispatch == NULL + || gbl->c_prov_up_ref == NULL + || gbl->c_prov_free == NULL) + return 0; + + gbl->lock = CRYPTO_THREAD_lock_new(); + if (gbl->lock == NULL) + return 0; + + if (!gbl->c_provider_register_child_cb(gbl->handle, + provider_create_child_cb, + provider_remove_child_cb, + provider_global_props_cb, + ctx)) + return 0; + + return 1; +} + +void ossl_provider_deinit_child(OSSL_LIB_CTX *ctx) +{ + struct child_prov_globals *gbl + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return; + + gbl->c_provider_deregister_child_cb(gbl->handle); +} + +/* + * ossl_provider_up_ref_parent() and ossl_provider_free_parent() do + * nothing in "self-referencing" child providers, i.e. when the parent + * of the child provider is the same as the provider where this child + * provider was created. + * This allows the teardown function in the parent provider to be called + * at the correct moment. + * For child providers in other providers, the reference count is done to + * ensure that cross referencing is recorded. These should be cleared up + * through that providers teardown, as part of freeing its child libctx. + */ + +int ossl_provider_up_ref_parent(OSSL_PROVIDER *prov, int activate) +{ + struct child_prov_globals *gbl; + const OSSL_CORE_HANDLE *parent_handle; + + gbl = ossl_lib_ctx_get_data(ossl_provider_libctx(prov), + OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return 0; + + parent_handle = ossl_provider_get_parent(prov); + if (parent_handle == gbl->handle) + return 1; + return gbl->c_prov_up_ref(parent_handle, activate); +} + +int ossl_provider_free_parent(OSSL_PROVIDER *prov, int deactivate) +{ + struct child_prov_globals *gbl; + const OSSL_CORE_HANDLE *parent_handle; + + gbl = ossl_lib_ctx_get_data(ossl_provider_libctx(prov), + OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return 0; + + parent_handle = ossl_provider_get_parent(prov); + if (parent_handle == gbl->handle) + return 1; + return gbl->c_prov_free(ossl_provider_get_parent(prov), deactivate); +} diff --git a/crypto/openssl/crypto/provider_conf.c b/crypto/openssl/crypto/provider_conf.c new file mode 100644 index 000000000000..c13c887c3d4a --- /dev/null +++ b/crypto/openssl/crypto/provider_conf.c @@ -0,0 +1,316 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include "internal/provider.h" +#include "internal/cryptlib.h" +#include "provider_local.h" + +DEFINE_STACK_OF(OSSL_PROVIDER) + +/* PROVIDER config module */ + +typedef struct { + CRYPTO_RWLOCK *lock; + STACK_OF(OSSL_PROVIDER) *activated_providers; +} PROVIDER_CONF_GLOBAL; + +static void *prov_conf_ossl_ctx_new(OSSL_LIB_CTX *libctx) +{ + PROVIDER_CONF_GLOBAL *pcgbl = OPENSSL_zalloc(sizeof(*pcgbl)); + + if (pcgbl == NULL) + return NULL; + + pcgbl->lock = CRYPTO_THREAD_lock_new(); + if (pcgbl->lock == NULL) { + OPENSSL_free(pcgbl); + return NULL; + } + + return pcgbl; +} + +static void prov_conf_ossl_ctx_free(void *vpcgbl) +{ + PROVIDER_CONF_GLOBAL *pcgbl = vpcgbl; + + sk_OSSL_PROVIDER_pop_free(pcgbl->activated_providers, + ossl_provider_free); + + OSSL_TRACE(CONF, "Cleaned up providers\n"); + CRYPTO_THREAD_lock_free(pcgbl->lock); + OPENSSL_free(pcgbl); +} + +static const OSSL_LIB_CTX_METHOD provider_conf_ossl_ctx_method = { + /* Must be freed before the provider store is freed */ + OSSL_LIB_CTX_METHOD_PRIORITY_2, + prov_conf_ossl_ctx_new, + prov_conf_ossl_ctx_free, +}; + +static const char *skip_dot(const char *name) +{ + const char *p = strchr(name, '.'); + + if (p != NULL) + return p + 1; + return name; +} + +static int provider_conf_params(OSSL_PROVIDER *prov, + OSSL_PROVIDER_INFO *provinfo, + const char *name, const char *value, + const CONF *cnf) +{ + STACK_OF(CONF_VALUE) *sect; + int ok = 1; + + sect = NCONF_get_section(cnf, value); + if (sect != NULL) { + int i; + char buffer[512]; + size_t buffer_len = 0; + + OSSL_TRACE1(CONF, "Provider params: start section %s\n", value); + + if (name != NULL) { + OPENSSL_strlcpy(buffer, name, sizeof(buffer)); + OPENSSL_strlcat(buffer, ".", sizeof(buffer)); + buffer_len = strlen(buffer); + } + + for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { + CONF_VALUE *sectconf = sk_CONF_VALUE_value(sect, i); + + if (buffer_len + strlen(sectconf->name) >= sizeof(buffer)) + return 0; + buffer[buffer_len] = '\0'; + OPENSSL_strlcat(buffer, sectconf->name, sizeof(buffer)); + if (!provider_conf_params(prov, provinfo, buffer, sectconf->value, + cnf)) + return 0; + } + + OSSL_TRACE1(CONF, "Provider params: finish section %s\n", value); + } else { + OSSL_TRACE2(CONF, "Provider params: %s = %s\n", name, value); + if (prov != NULL) + ok = ossl_provider_add_parameter(prov, name, value); + else + ok = ossl_provider_info_add_parameter(provinfo, name, value); + } + + return ok; +} + +static int prov_already_activated(const char *name, + STACK_OF(OSSL_PROVIDER) *activated) +{ + int i, max; + + if (activated == NULL) + return 0; + + max = sk_OSSL_PROVIDER_num(activated); + for (i = 0; i < max; i++) { + OSSL_PROVIDER *tstprov = sk_OSSL_PROVIDER_value(activated, i); + + if (strcmp(OSSL_PROVIDER_get0_name(tstprov), name) == 0) { + return 1; + } + } + + return 0; +} + +static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name, + const char *value, const CONF *cnf) +{ + int i; + STACK_OF(CONF_VALUE) *ecmds; + int soft = 0; + OSSL_PROVIDER *prov = NULL, *actual = NULL; + const char *path = NULL; + long activate = 0; + int ok = 0; + + name = skip_dot(name); + OSSL_TRACE1(CONF, "Configuring provider %s\n", name); + /* Value is a section containing PROVIDER commands */ + ecmds = NCONF_get_section(cnf, value); + + if (!ecmds) { + ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_SECTION_ERROR, + "section=%s not found", value); + return 0; + } + + /* Find the needed data first */ + for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) { + CONF_VALUE *ecmd = sk_CONF_VALUE_value(ecmds, i); + const char *confname = skip_dot(ecmd->name); + const char *confvalue = ecmd->value; + + OSSL_TRACE2(CONF, "Provider command: %s = %s\n", + confname, confvalue); + + /* First handle some special pseudo confs */ + + /* Override provider name to use */ + if (strcmp(confname, "identity") == 0) + name = confvalue; + else if (strcmp(confname, "soft_load") == 0) + soft = 1; + /* Load a dynamic PROVIDER */ + else if (strcmp(confname, "module") == 0) + path = confvalue; + else if (strcmp(confname, "activate") == 0) + activate = 1; + } + + if (activate) { + PROVIDER_CONF_GLOBAL *pcgbl + = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_PROVIDER_CONF_INDEX, + &provider_conf_ossl_ctx_method); + + if (pcgbl == NULL || !CRYPTO_THREAD_write_lock(pcgbl->lock)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + if (!prov_already_activated(name, pcgbl->activated_providers)) { + /* + * There is an attempt to activate a provider, so we should disable + * loading of fallbacks. Otherwise a misconfiguration could mean the + * intended provider does not get loaded. Subsequent fetches could + * then fallback to the default provider - which may be the wrong + * thing. + */ + if (!ossl_provider_disable_fallback_loading(libctx)) { + CRYPTO_THREAD_unlock(pcgbl->lock); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + prov = ossl_provider_find(libctx, name, 1); + if (prov == NULL) + prov = ossl_provider_new(libctx, name, NULL, 1); + if (prov == NULL) { + CRYPTO_THREAD_unlock(pcgbl->lock); + if (soft) + ERR_clear_error(); + return 0; + } + + if (path != NULL) + ossl_provider_set_module_path(prov, path); + + ok = provider_conf_params(prov, NULL, NULL, value, cnf); + + if (ok) { + if (!ossl_provider_activate(prov, 1, 0)) { + ok = 0; + } else if (!ossl_provider_add_to_store(prov, &actual, 0)) { + ossl_provider_deactivate(prov, 1); + ok = 0; + } else if (actual != prov + && !ossl_provider_activate(actual, 1, 0)) { + ossl_provider_free(actual); + ok = 0; + } else { + if (pcgbl->activated_providers == NULL) + pcgbl->activated_providers = sk_OSSL_PROVIDER_new_null(); + if (pcgbl->activated_providers == NULL + || !sk_OSSL_PROVIDER_push(pcgbl->activated_providers, + actual)) { + ossl_provider_deactivate(actual, 1); + ossl_provider_free(actual); + ok = 0; + } else { + ok = 1; + } + } + } + if (!ok) + ossl_provider_free(prov); + } + CRYPTO_THREAD_unlock(pcgbl->lock); + } else { + OSSL_PROVIDER_INFO entry; + + memset(&entry, 0, sizeof(entry)); + ok = 1; + if (name != NULL) { + entry.name = OPENSSL_strdup(name); + if (entry.name == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ok = 0; + } + } + if (ok && path != NULL) { + entry.path = OPENSSL_strdup(path); + if (entry.path == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ok = 0; + } + } + if (ok) + ok = provider_conf_params(NULL, &entry, NULL, value, cnf); + if (ok && (entry.path != NULL || entry.parameters != NULL)) + ok = ossl_provider_info_add_to_store(libctx, &entry); + if (!ok || (entry.path == NULL && entry.parameters == NULL)) { + ossl_provider_info_clear(&entry); + } + + } + + /* + * Even if ok is 0, we still return success. Failure to load a provider is + * not fatal. We want to continue to load the rest of the config file. + */ + return 1; +} + +static int provider_conf_init(CONF_IMODULE *md, const CONF *cnf) +{ + STACK_OF(CONF_VALUE) *elist; + CONF_VALUE *cval; + int i; + + OSSL_TRACE1(CONF, "Loading providers module: section %s\n", + CONF_imodule_get_value(md)); + + /* Value is a section containing PROVIDERs to configure */ + elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); + + if (!elist) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_SECTION_ERROR); + return 0; + } + + for (i = 0; i < sk_CONF_VALUE_num(elist); i++) { + cval = sk_CONF_VALUE_value(elist, i); + if (!provider_conf_load(NCONF_get0_libctx((CONF *)cnf), + cval->name, cval->value, cnf)) + return 0; + } + + return 1; +} + +void ossl_provider_add_conf_module(void) +{ + OSSL_TRACE(CONF, "Adding config module 'providers'\n"); + CONF_module_add("providers", provider_conf_init, NULL); +} diff --git a/crypto/openssl/crypto/provider_core.c b/crypto/openssl/crypto/provider_core.c new file mode 100644 index 000000000000..7a1232812162 --- /dev/null +++ b/crypto/openssl/crypto/provider_core.c @@ -0,0 +1,2171 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include "crypto/cryptlib.h" +#ifndef FIPS_MODULE +#include "crypto/decoder.h" /* ossl_decoder_store_cache_flush */ +#include "crypto/encoder.h" /* ossl_encoder_store_cache_flush */ +#include "crypto/store.h" /* ossl_store_loader_store_cache_flush */ +#endif +#include "crypto/evp.h" /* evp_method_store_cache_flush */ +#include "crypto/rand.h" +#include "internal/nelem.h" +#include "internal/thread_once.h" +#include "internal/provider.h" +#include "internal/refcount.h" +#include "internal/bio.h" +#include "internal/core.h" +#include "provider_local.h" +#ifndef FIPS_MODULE +# include +#endif + +/* + * This file defines and uses a number of different structures: + * + * OSSL_PROVIDER (provider_st): Used to represent all information related to a + * single instance of a provider. + * + * provider_store_st: Holds information about the collection of providers that + * are available within the current library context (OSSL_LIB_CTX). It also + * holds configuration information about providers that could be loaded at some + * future point. + * + * OSSL_PROVIDER_CHILD_CB: An instance of this structure holds the callbacks + * that have been registered for a child library context and the associated + * provider that registered those callbacks. + * + * Where a child library context exists then it has its own instance of the + * provider store. Each provider that exists in the parent provider store, has + * an associated child provider in the child library context's provider store. + * As providers get activated or deactivated this needs to be mirrored in the + * associated child providers. + * + * LOCKING + * ======= + * + * There are a number of different locks used in this file and it is important + * to understand how they should be used in order to avoid deadlocks. + * + * Fields within a structure can often be "write once" on creation, and then + * "read many". Creation of a structure is done by a single thread, and + * therefore no lock is required for the "write once/read many" fields. It is + * safe for multiple threads to read these fields without a lock, because they + * will never be changed. + * + * However some fields may be changed after a structure has been created and + * shared between multiple threads. Where this is the case a lock is required. + * + * The locks available are: + * + * The provider flag_lock: Used to control updates to the various provider + * "flags" (flag_initialized, flag_activated, flag_fallback) and associated + * "counts" (activatecnt). + * + * The provider refcnt_lock: Only ever used to control updates to the provider + * refcnt value. + * + * The provider optbits_lock: Used to control access to the provider's + * operation_bits and operation_bits_sz fields. + * + * The store default_path_lock: Used to control access to the provider store's + * default search path value (default_path) + * + * The store lock: Used to control the stack of provider's held within the + * provider store, as well as the stack of registered child provider callbacks. + * + * As a general rule-of-thumb it is best to: + * - keep the scope of the code that is protected by a lock to the absolute + * minimum possible; + * - try to keep the scope of the lock to within a single function (i.e. avoid + * making calls to other functions while holding a lock); + * - try to only ever hold one lock at a time. + * + * Unfortunately, it is not always possible to stick to the above guidelines. + * Where they are not adhered to there is always a danger of inadvertently + * introducing the possibility of deadlock. The following rules MUST be adhered + * to in order to avoid that: + * - Holding multiple locks at the same time is only allowed for the + * provider store lock, the provider flag_lock and the provider refcnt_lock. + * - When holding multiple locks they must be acquired in the following order of + * precedence: + * 1) provider store lock + * 2) provider flag_lock + * 3) provider refcnt_lock + * - When releasing locks they must be released in the reverse order to which + * they were acquired + * - No locks may be held when making an upcall. NOTE: Some common functions + * can make upcalls as part of their normal operation. If you need to call + * some other function while holding a lock make sure you know whether it + * will make any upcalls or not. For example ossl_provider_up_ref() can call + * ossl_provider_up_ref_parent() which can call the c_prov_up_ref() upcall. + * - It is permissible to hold the store and flag locks when calling child + * provider callbacks. No other locks may be held during such callbacks. + */ + +static OSSL_PROVIDER *provider_new(const char *name, + OSSL_provider_init_fn *init_function, + STACK_OF(INFOPAIR) *parameters); + +/*- + * Provider Object structure + * ========================= + */ + +#ifndef FIPS_MODULE +typedef struct { + OSSL_PROVIDER *prov; + int (*create_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata); + int (*remove_cb)(const OSSL_CORE_HANDLE *provider, void *cbdata); + int (*global_props_cb)(const char *props, void *cbdata); + void *cbdata; +} OSSL_PROVIDER_CHILD_CB; +DEFINE_STACK_OF(OSSL_PROVIDER_CHILD_CB) +#endif + +struct provider_store_st; /* Forward declaration */ + +struct ossl_provider_st { + /* Flag bits */ + unsigned int flag_initialized:1; + unsigned int flag_activated:1; + unsigned int flag_fallback:1; /* Can be used as fallback */ + + /* Getting and setting the flags require synchronization */ + CRYPTO_RWLOCK *flag_lock; + + /* OpenSSL library side data */ + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *refcnt_lock; /* For the ref counter */ + int activatecnt; + char *name; + char *path; + DSO *module; + OSSL_provider_init_fn *init_function; + STACK_OF(INFOPAIR) *parameters; + OSSL_LIB_CTX *libctx; /* The library context this instance is in */ + struct provider_store_st *store; /* The store this instance belongs to */ +#ifndef FIPS_MODULE + /* + * In the FIPS module inner provider, this isn't needed, since the + * error upcalls are always direct calls to the outer provider. + */ + int error_lib; /* ERR library number, one for each provider */ +# ifndef OPENSSL_NO_ERR + ERR_STRING_DATA *error_strings; /* Copy of what the provider gives us */ +# endif +#endif + + /* Provider side functions */ + OSSL_FUNC_provider_teardown_fn *teardown; + OSSL_FUNC_provider_gettable_params_fn *gettable_params; + OSSL_FUNC_provider_get_params_fn *get_params; + OSSL_FUNC_provider_get_capabilities_fn *get_capabilities; + OSSL_FUNC_provider_self_test_fn *self_test; + OSSL_FUNC_provider_query_operation_fn *query_operation; + OSSL_FUNC_provider_unquery_operation_fn *unquery_operation; + + /* + * Cache of bit to indicate of query_operation() has been called on + * a specific operation or not. + */ + unsigned char *operation_bits; + size_t operation_bits_sz; + CRYPTO_RWLOCK *opbits_lock; + +#ifndef FIPS_MODULE + /* Whether this provider is the child of some other provider */ + const OSSL_CORE_HANDLE *handle; + unsigned int ischild:1; +#endif + + /* Provider side data */ + void *provctx; + const OSSL_DISPATCH *dispatch; +}; +DEFINE_STACK_OF(OSSL_PROVIDER) + +static int ossl_provider_cmp(const OSSL_PROVIDER * const *a, + const OSSL_PROVIDER * const *b) +{ + return strcmp((*a)->name, (*b)->name); +} + +/*- + * Provider Object store + * ===================== + * + * The Provider Object store is a library context object, and therefore needs + * an index. + */ + +struct provider_store_st { + OSSL_LIB_CTX *libctx; + STACK_OF(OSSL_PROVIDER) *providers; + STACK_OF(OSSL_PROVIDER_CHILD_CB) *child_cbs; + CRYPTO_RWLOCK *default_path_lock; + CRYPTO_RWLOCK *lock; + char *default_path; + OSSL_PROVIDER_INFO *provinfo; + size_t numprovinfo; + size_t provinfosz; + unsigned int use_fallbacks:1; + unsigned int freeing:1; +}; + +/* + * provider_deactivate_free() is a wrapper around ossl_provider_deactivate() + * and ossl_provider_free(), called as needed. + * Since this is only called when the provider store is being emptied, we + * don't need to care about any lock. + */ +static void provider_deactivate_free(OSSL_PROVIDER *prov) +{ + if (prov->flag_activated) + ossl_provider_deactivate(prov, 1); + ossl_provider_free(prov); +} + +#ifndef FIPS_MODULE +static void ossl_provider_child_cb_free(OSSL_PROVIDER_CHILD_CB *cb) +{ + OPENSSL_free(cb); +} +#endif + +static void infopair_free(INFOPAIR *pair) +{ + OPENSSL_free(pair->name); + OPENSSL_free(pair->value); + OPENSSL_free(pair); +} + +static INFOPAIR *infopair_copy(const INFOPAIR *src) +{ + INFOPAIR *dest = OPENSSL_zalloc(sizeof(*dest)); + + if (dest == NULL) + return NULL; + if (src->name != NULL) { + dest->name = OPENSSL_strdup(src->name); + if (dest->name == NULL) + goto err; + } + if (src->value != NULL) { + dest->value = OPENSSL_strdup(src->value); + if (dest->value == NULL) + goto err; + } + return dest; + err: + OPENSSL_free(dest->name); + OPENSSL_free(dest); + return NULL; +} + +void ossl_provider_info_clear(OSSL_PROVIDER_INFO *info) +{ + OPENSSL_free(info->name); + OPENSSL_free(info->path); + sk_INFOPAIR_pop_free(info->parameters, infopair_free); +} + +static void provider_store_free(void *vstore) +{ + struct provider_store_st *store = vstore; + size_t i; + + if (store == NULL) + return; + store->freeing = 1; + OPENSSL_free(store->default_path); + sk_OSSL_PROVIDER_pop_free(store->providers, provider_deactivate_free); +#ifndef FIPS_MODULE + sk_OSSL_PROVIDER_CHILD_CB_pop_free(store->child_cbs, + ossl_provider_child_cb_free); +#endif + CRYPTO_THREAD_lock_free(store->default_path_lock); + CRYPTO_THREAD_lock_free(store->lock); + for (i = 0; i < store->numprovinfo; i++) + ossl_provider_info_clear(&store->provinfo[i]); + OPENSSL_free(store->provinfo); + OPENSSL_free(store); +} + +static void *provider_store_new(OSSL_LIB_CTX *ctx) +{ + struct provider_store_st *store = OPENSSL_zalloc(sizeof(*store)); + + if (store == NULL + || (store->providers = sk_OSSL_PROVIDER_new(ossl_provider_cmp)) == NULL + || (store->default_path_lock = CRYPTO_THREAD_lock_new()) == NULL +#ifndef FIPS_MODULE + || (store->child_cbs = sk_OSSL_PROVIDER_CHILD_CB_new_null()) == NULL +#endif + || (store->lock = CRYPTO_THREAD_lock_new()) == NULL) { + provider_store_free(store); + return NULL; + } + store->libctx = ctx; + store->use_fallbacks = 1; + + return store; +} + +static const OSSL_LIB_CTX_METHOD provider_store_method = { + /* Needs to be freed before the child provider data is freed */ + OSSL_LIB_CTX_METHOD_PRIORITY_1, + provider_store_new, + provider_store_free, +}; + +static struct provider_store_st *get_provider_store(OSSL_LIB_CTX *libctx) +{ + struct provider_store_st *store = NULL; + + store = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_PROVIDER_STORE_INDEX, + &provider_store_method); + if (store == NULL) + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return store; +} + +int ossl_provider_disable_fallback_loading(OSSL_LIB_CTX *libctx) +{ + struct provider_store_st *store; + + if ((store = get_provider_store(libctx)) != NULL) { + if (!CRYPTO_THREAD_write_lock(store->lock)) + return 0; + store->use_fallbacks = 0; + CRYPTO_THREAD_unlock(store->lock); + return 1; + } + return 0; +} + +#define BUILTINS_BLOCK_SIZE 10 + +int ossl_provider_info_add_to_store(OSSL_LIB_CTX *libctx, + OSSL_PROVIDER_INFO *entry) +{ + struct provider_store_st *store = get_provider_store(libctx); + int ret = 0; + + if (entry->name == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (store == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!CRYPTO_THREAD_write_lock(store->lock)) + return 0; + if (store->provinfosz == 0) { + store->provinfo = OPENSSL_zalloc(sizeof(*store->provinfo) + * BUILTINS_BLOCK_SIZE); + if (store->provinfo == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + goto err; + } + store->provinfosz = BUILTINS_BLOCK_SIZE; + } else if (store->numprovinfo == store->provinfosz) { + OSSL_PROVIDER_INFO *tmpbuiltins; + size_t newsz = store->provinfosz + BUILTINS_BLOCK_SIZE; + + tmpbuiltins = OPENSSL_realloc(store->provinfo, + sizeof(*store->provinfo) * newsz); + if (tmpbuiltins == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + goto err; + } + store->provinfo = tmpbuiltins; + store->provinfosz = newsz; + } + store->provinfo[store->numprovinfo] = *entry; + store->numprovinfo++; + + ret = 1; + err: + CRYPTO_THREAD_unlock(store->lock); + return ret; +} + +OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name, + int noconfig) +{ + struct provider_store_st *store = NULL; + OSSL_PROVIDER *prov = NULL; + + if ((store = get_provider_store(libctx)) != NULL) { + OSSL_PROVIDER tmpl = { 0, }; + int i; + +#ifndef FIPS_MODULE + /* + * Make sure any providers are loaded from config before we try to find + * them. + */ + if (!noconfig) { + if (ossl_lib_ctx_is_default(libctx)) + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + } +#endif + + tmpl.name = (char *)name; + /* + * A "find" operation can sort the stack, and therefore a write lock is + * required. + */ + if (!CRYPTO_THREAD_write_lock(store->lock)) + return NULL; + if ((i = sk_OSSL_PROVIDER_find(store->providers, &tmpl)) != -1) + prov = sk_OSSL_PROVIDER_value(store->providers, i); + CRYPTO_THREAD_unlock(store->lock); + if (prov != NULL && !ossl_provider_up_ref(prov)) + prov = NULL; + } + + return prov; +} + +/*- + * Provider Object methods + * ======================= + */ + +static OSSL_PROVIDER *provider_new(const char *name, + OSSL_provider_init_fn *init_function, + STACK_OF(INFOPAIR) *parameters) +{ + OSSL_PROVIDER *prov = NULL; + + if ((prov = OPENSSL_zalloc(sizeof(*prov))) == NULL +#ifndef HAVE_ATOMICS + || (prov->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL +#endif + ) { + OPENSSL_free(prov); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + prov->refcnt = 1; /* 1 One reference to be returned */ + + if ((prov->opbits_lock = CRYPTO_THREAD_lock_new()) == NULL + || (prov->flag_lock = CRYPTO_THREAD_lock_new()) == NULL + || (prov->name = OPENSSL_strdup(name)) == NULL + || (prov->parameters = sk_INFOPAIR_deep_copy(parameters, + infopair_copy, + infopair_free)) == NULL) { + ossl_provider_free(prov); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + prov->init_function = init_function; + + return prov; +} + +int ossl_provider_up_ref(OSSL_PROVIDER *prov) +{ + int ref = 0; + + if (CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock) <= 0) + return 0; + +#ifndef FIPS_MODULE + if (prov->ischild) { + if (!ossl_provider_up_ref_parent(prov, 0)) { + ossl_provider_free(prov); + return 0; + } + } +#endif + + return ref; +} + +#ifndef FIPS_MODULE +static int provider_up_ref_intern(OSSL_PROVIDER *prov, int activate) +{ + if (activate) + return ossl_provider_activate(prov, 1, 0); + + return ossl_provider_up_ref(prov); +} + +static int provider_free_intern(OSSL_PROVIDER *prov, int deactivate) +{ + if (deactivate) + return ossl_provider_deactivate(prov, 1); + + ossl_provider_free(prov); + return 1; +} +#endif + +/* + * We assume that the requested provider does not already exist in the store. + * The caller should check. If it does exist then adding it to the store later + * will fail. + */ +OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, + OSSL_provider_init_fn *init_function, + int noconfig) +{ + struct provider_store_st *store = NULL; + OSSL_PROVIDER_INFO template; + OSSL_PROVIDER *prov = NULL; + + if ((store = get_provider_store(libctx)) == NULL) + return NULL; + + memset(&template, 0, sizeof(template)); + if (init_function == NULL) { + const OSSL_PROVIDER_INFO *p; + size_t i; + + /* Check if this is a predefined builtin provider */ + for (p = ossl_predefined_providers; p->name != NULL; p++) { + if (strcmp(p->name, name) == 0) { + template = *p; + break; + } + } + if (p->name == NULL) { + /* Check if this is a user added builtin provider */ + if (!CRYPTO_THREAD_read_lock(store->lock)) + return NULL; + for (i = 0, p = store->provinfo; i < store->numprovinfo; p++, i++) { + if (strcmp(p->name, name) == 0) { + template = *p; + break; + } + } + CRYPTO_THREAD_unlock(store->lock); + } + } else { + template.init = init_function; + } + + /* provider_new() generates an error, so no need here */ + if ((prov = provider_new(name, template.init, template.parameters)) == NULL) + return NULL; + + prov->libctx = libctx; +#ifndef FIPS_MODULE + prov->error_lib = ERR_get_next_error_library(); +#endif + + /* + * At this point, the provider is only partially "loaded". To be + * fully "loaded", ossl_provider_activate() must also be called and it must + * then be added to the provider store. + */ + + return prov; +} + +/* Assumes that the store lock is held */ +static int create_provider_children(OSSL_PROVIDER *prov) +{ + int ret = 1; +#ifndef FIPS_MODULE + struct provider_store_st *store = prov->store; + OSSL_PROVIDER_CHILD_CB *child_cb; + int i, max; + + max = sk_OSSL_PROVIDER_CHILD_CB_num(store->child_cbs); + for (i = 0; i < max; i++) { + /* + * This is newly activated (activatecnt == 1), so we need to + * create child providers as necessary. + */ + child_cb = sk_OSSL_PROVIDER_CHILD_CB_value(store->child_cbs, i); + ret &= child_cb->create_cb((OSSL_CORE_HANDLE *)prov, child_cb->cbdata); + } +#endif + + return ret; +} + +int ossl_provider_add_to_store(OSSL_PROVIDER *prov, OSSL_PROVIDER **actualprov, + int retain_fallbacks) +{ + struct provider_store_st *store; + int idx; + OSSL_PROVIDER tmpl = { 0, }; + OSSL_PROVIDER *actualtmp = NULL; + + if (actualprov != NULL) + *actualprov = NULL; + + if ((store = get_provider_store(prov->libctx)) == NULL) + return 0; + + if (!CRYPTO_THREAD_write_lock(store->lock)) + return 0; + + tmpl.name = (char *)prov->name; + idx = sk_OSSL_PROVIDER_find(store->providers, &tmpl); + if (idx == -1) + actualtmp = prov; + else + actualtmp = sk_OSSL_PROVIDER_value(store->providers, idx); + + if (idx == -1) { + if (sk_OSSL_PROVIDER_push(store->providers, prov) == 0) + goto err; + prov->store = store; + if (!create_provider_children(prov)) { + sk_OSSL_PROVIDER_delete_ptr(store->providers, prov); + goto err; + } + if (!retain_fallbacks) + store->use_fallbacks = 0; + } + + CRYPTO_THREAD_unlock(store->lock); + + if (actualprov != NULL) { + if (!ossl_provider_up_ref(actualtmp)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + actualtmp = NULL; + return 0; + } + *actualprov = actualtmp; + } + + if (idx >= 0) { + /* + * The provider is already in the store. Probably two threads + * independently initialised their own provider objects with the same + * name and raced to put them in the store. This thread lost. We + * deactivate the one we just created and use the one that already + * exists instead. + * If we get here then we know we did not create provider children + * above, so we inform ossl_provider_deactivate not to attempt to remove + * any. + */ + ossl_provider_deactivate(prov, 0); + ossl_provider_free(prov); + } + + return 1; + + err: + CRYPTO_THREAD_unlock(store->lock); + return 0; +} + +void ossl_provider_free(OSSL_PROVIDER *prov) +{ + if (prov != NULL) { + int ref = 0; + + CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock); + + /* + * When the refcount drops to zero, we clean up the provider. + * Note that this also does teardown, which may seem late, + * considering that init happens on first activation. However, + * there may be other structures hanging on to the provider after + * the last deactivation and may therefore need full access to the + * provider's services. Therefore, we deinit late. + */ + if (ref == 0) { + if (prov->flag_initialized) { + ossl_provider_teardown(prov); +#ifndef OPENSSL_NO_ERR +# ifndef FIPS_MODULE + if (prov->error_strings != NULL) { + ERR_unload_strings(prov->error_lib, prov->error_strings); + OPENSSL_free(prov->error_strings); + prov->error_strings = NULL; + } +# endif +#endif + OPENSSL_free(prov->operation_bits); + prov->operation_bits = NULL; + prov->operation_bits_sz = 0; + prov->flag_initialized = 0; + } + +#ifndef FIPS_MODULE + /* + * We deregister thread handling whether or not the provider was + * initialized. If init was attempted but was not successful then + * the provider may still have registered a thread handler. + */ + ossl_init_thread_deregister(prov); + DSO_free(prov->module); +#endif + OPENSSL_free(prov->name); + OPENSSL_free(prov->path); + sk_INFOPAIR_pop_free(prov->parameters, infopair_free); + CRYPTO_THREAD_lock_free(prov->opbits_lock); + CRYPTO_THREAD_lock_free(prov->flag_lock); +#ifndef HAVE_ATOMICS + CRYPTO_THREAD_lock_free(prov->refcnt_lock); +#endif + OPENSSL_free(prov); + } +#ifndef FIPS_MODULE + else if (prov->ischild) { + ossl_provider_free_parent(prov, 0); + } +#endif + } +} + +/* Setters */ +int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path) +{ + OPENSSL_free(prov->path); + prov->path = NULL; + if (module_path == NULL) + return 1; + if ((prov->path = OPENSSL_strdup(module_path)) != NULL) + return 1; + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; +} + +static int infopair_add(STACK_OF(INFOPAIR) **infopairsk, const char *name, + const char *value) +{ + INFOPAIR *pair = NULL; + + if ((pair = OPENSSL_zalloc(sizeof(*pair))) != NULL + && (*infopairsk != NULL + || (*infopairsk = sk_INFOPAIR_new_null()) != NULL) + && (pair->name = OPENSSL_strdup(name)) != NULL + && (pair->value = OPENSSL_strdup(value)) != NULL + && sk_INFOPAIR_push(*infopairsk, pair) > 0) + return 1; + + if (pair != NULL) { + OPENSSL_free(pair->name); + OPENSSL_free(pair->value); + OPENSSL_free(pair); + } + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; +} + +int ossl_provider_add_parameter(OSSL_PROVIDER *prov, + const char *name, const char *value) +{ + return infopair_add(&prov->parameters, name, value); +} + +int ossl_provider_info_add_parameter(OSSL_PROVIDER_INFO *provinfo, + const char *name, + const char *value) +{ + return infopair_add(&provinfo->parameters, name, value); +} + +/* + * Provider activation. + * + * What "activation" means depends on the provider form; for built in + * providers (in the library or the application alike), the provider + * can already be considered to be loaded, all that's needed is to + * initialize it. However, for dynamically loadable provider modules, + * we must first load that module. + * + * Built in modules are distinguished from dynamically loaded modules + * with an already assigned init function. + */ +static const OSSL_DISPATCH *core_dispatch; /* Define further down */ + +int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *libctx, + const char *path) +{ + struct provider_store_st *store; + char *p = NULL; + + if (path != NULL) { + p = OPENSSL_strdup(path); + if (p == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + } + if ((store = get_provider_store(libctx)) != NULL + && CRYPTO_THREAD_write_lock(store->default_path_lock)) { + OPENSSL_free(store->default_path); + store->default_path = p; + CRYPTO_THREAD_unlock(store->default_path_lock); + return 1; + } + OPENSSL_free(p); + return 0; +} + +/* + * Internal version that doesn't affect the store flags, and thereby avoid + * locking. Direct callers must remember to set the store flags when + * appropriate. + */ +static int provider_init(OSSL_PROVIDER *prov) +{ + const OSSL_DISPATCH *provider_dispatch = NULL; + void *tmp_provctx = NULL; /* safety measure */ +#ifndef OPENSSL_NO_ERR +# ifndef FIPS_MODULE + OSSL_FUNC_provider_get_reason_strings_fn *p_get_reason_strings = NULL; +# endif +#endif + int ok = 0; + + if (!ossl_assert(!prov->flag_initialized)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto end; + } + + /* + * If the init function isn't set, it indicates that this provider is + * a loadable module. + */ + if (prov->init_function == NULL) { +#ifdef FIPS_MODULE + goto end; +#else + if (prov->module == NULL) { + char *allocated_path = NULL; + const char *module_path = NULL; + char *merged_path = NULL; + const char *load_dir = NULL; + char *allocated_load_dir = NULL; + struct provider_store_st *store; + + if ((prov->module = DSO_new()) == NULL) { + /* DSO_new() generates an error already */ + goto end; + } + + if ((store = get_provider_store(prov->libctx)) == NULL + || !CRYPTO_THREAD_read_lock(store->default_path_lock)) + goto end; + + if (store->default_path != NULL) { + allocated_load_dir = OPENSSL_strdup(store->default_path); + CRYPTO_THREAD_unlock(store->default_path_lock); + if (allocated_load_dir == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + goto end; + } + load_dir = allocated_load_dir; + } else { + CRYPTO_THREAD_unlock(store->default_path_lock); + } + + if (load_dir == NULL) { + load_dir = ossl_safe_getenv("OPENSSL_MODULES"); + if (load_dir == NULL) + load_dir = MODULESDIR; + } + + DSO_ctrl(prov->module, DSO_CTRL_SET_FLAGS, + DSO_FLAG_NAME_TRANSLATION_EXT_ONLY, NULL); + + module_path = prov->path; + if (module_path == NULL) + module_path = allocated_path = + DSO_convert_filename(prov->module, prov->name); + if (module_path != NULL) + merged_path = DSO_merge(prov->module, module_path, load_dir); + + if (merged_path == NULL + || (DSO_load(prov->module, merged_path, NULL, 0)) == NULL) { + DSO_free(prov->module); + prov->module = NULL; + } + + OPENSSL_free(merged_path); + OPENSSL_free(allocated_path); + OPENSSL_free(allocated_load_dir); + } + + if (prov->module == NULL) { + /* DSO has already recorded errors, this is just a tracepoint */ + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_DSO_LIB, + "name=%s", prov->name); + goto end; + } + + prov->init_function = (OSSL_provider_init_fn *) + DSO_bind_func(prov->module, "OSSL_provider_init"); +#endif + } + + /* Check for and call the initialise function for the provider. */ + if (prov->init_function == NULL) { + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_UNSUPPORTED, + "name=%s, provider has no provider init function", + prov->name); + goto end; + } + + if (!prov->init_function((OSSL_CORE_HANDLE *)prov, core_dispatch, + &provider_dispatch, &tmp_provctx)) { + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL, + "name=%s", prov->name); + goto end; + } + prov->provctx = tmp_provctx; + prov->dispatch = provider_dispatch; + + for (; provider_dispatch->function_id != 0; provider_dispatch++) { + switch (provider_dispatch->function_id) { + case OSSL_FUNC_PROVIDER_TEARDOWN: + prov->teardown = + OSSL_FUNC_provider_teardown(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_GETTABLE_PARAMS: + prov->gettable_params = + OSSL_FUNC_provider_gettable_params(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_GET_PARAMS: + prov->get_params = + OSSL_FUNC_provider_get_params(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_SELF_TEST: + prov->self_test = + OSSL_FUNC_provider_self_test(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_GET_CAPABILITIES: + prov->get_capabilities = + OSSL_FUNC_provider_get_capabilities(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_QUERY_OPERATION: + prov->query_operation = + OSSL_FUNC_provider_query_operation(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_UNQUERY_OPERATION: + prov->unquery_operation = + OSSL_FUNC_provider_unquery_operation(provider_dispatch); + break; +#ifndef OPENSSL_NO_ERR +# ifndef FIPS_MODULE + case OSSL_FUNC_PROVIDER_GET_REASON_STRINGS: + p_get_reason_strings = + OSSL_FUNC_provider_get_reason_strings(provider_dispatch); + break; +# endif +#endif + } + } + +#ifndef OPENSSL_NO_ERR +# ifndef FIPS_MODULE + if (p_get_reason_strings != NULL) { + const OSSL_ITEM *reasonstrings = p_get_reason_strings(prov->provctx); + size_t cnt, cnt2; + + /* + * ERR_load_strings() handles ERR_STRING_DATA rather than OSSL_ITEM, + * although they are essentially the same type. + * Furthermore, ERR_load_strings() patches the array's error number + * with the error library number, so we need to make a copy of that + * array either way. + */ + cnt = 0; + while (reasonstrings[cnt].id != 0) { + if (ERR_GET_LIB(reasonstrings[cnt].id) != 0) + goto end; + cnt++; + } + cnt++; /* One for the terminating item */ + + /* Allocate one extra item for the "library" name */ + prov->error_strings = + OPENSSL_zalloc(sizeof(ERR_STRING_DATA) * (cnt + 1)); + if (prov->error_strings == NULL) + goto end; + + /* + * Set the "library" name. + */ + prov->error_strings[0].error = ERR_PACK(prov->error_lib, 0, 0); + prov->error_strings[0].string = prov->name; + /* + * Copy reasonstrings item 0..cnt-1 to prov->error_trings positions + * 1..cnt. + */ + for (cnt2 = 1; cnt2 <= cnt; cnt2++) { + prov->error_strings[cnt2].error = (int)reasonstrings[cnt2-1].id; + prov->error_strings[cnt2].string = reasonstrings[cnt2-1].ptr; + } + + ERR_load_strings(prov->error_lib, prov->error_strings); + } +# endif +#endif + + /* With this flag set, this provider has become fully "loaded". */ + prov->flag_initialized = 1; + ok = 1; + + end: + return ok; +} + +/* + * Deactivate a provider. If upcalls is 0 then we suppress any upcalls to a + * parent provider. If removechildren is 0 then we suppress any calls to remove + * child providers. + * Return -1 on failure and the activation count on success + */ +static int provider_deactivate(OSSL_PROVIDER *prov, int upcalls, + int removechildren) +{ + int count; + struct provider_store_st *store; +#ifndef FIPS_MODULE + int freeparent = 0; +#endif + int lock = 1; + + if (!ossl_assert(prov != NULL)) + return -1; + + /* + * No need to lock if we've got no store because we've not been shared with + * other threads. + */ + store = get_provider_store(prov->libctx); + if (store == NULL) + lock = 0; + + if (lock && !CRYPTO_THREAD_read_lock(store->lock)) + return -1; + if (lock && !CRYPTO_THREAD_write_lock(prov->flag_lock)) { + CRYPTO_THREAD_unlock(store->lock); + return -1; + } + +#ifndef FIPS_MODULE + if (prov->activatecnt >= 2 && prov->ischild && upcalls) { + /* + * We have had a direct activation in this child libctx so we need to + * now down the ref count in the parent provider. We do the actual down + * ref outside of the flag_lock, since it could involve getting other + * locks. + */ + freeparent = 1; + } +#endif + + if ((count = --prov->activatecnt) < 1) + prov->flag_activated = 0; +#ifndef FIPS_MODULE + else + removechildren = 0; +#endif + +#ifndef FIPS_MODULE + if (removechildren && store != NULL) { + int i, max = sk_OSSL_PROVIDER_CHILD_CB_num(store->child_cbs); + OSSL_PROVIDER_CHILD_CB *child_cb; + + for (i = 0; i < max; i++) { + child_cb = sk_OSSL_PROVIDER_CHILD_CB_value(store->child_cbs, i); + child_cb->remove_cb((OSSL_CORE_HANDLE *)prov, child_cb->cbdata); + } + } +#endif + if (lock) { + CRYPTO_THREAD_unlock(prov->flag_lock); + CRYPTO_THREAD_unlock(store->lock); + } +#ifndef FIPS_MODULE + if (freeparent) + ossl_provider_free_parent(prov, 1); +#endif + + /* We don't deinit here, that's done in ossl_provider_free() */ + return count; +} + +/* + * Activate a provider. + * Return -1 on failure and the activation count on success + */ +static int provider_activate(OSSL_PROVIDER *prov, int lock, int upcalls) +{ + int count = -1; + struct provider_store_st *store; + int ret = 1; + + store = prov->store; + /* + * If the provider hasn't been added to the store, then we don't need + * any locks because we've not shared it with other threads. + */ + if (store == NULL) { + lock = 0; + if (!provider_init(prov)) + return -1; + } + +#ifndef FIPS_MODULE + if (prov->ischild && upcalls && !ossl_provider_up_ref_parent(prov, 1)) + return -1; +#endif + + if (lock && !CRYPTO_THREAD_read_lock(store->lock)) { +#ifndef FIPS_MODULE + if (prov->ischild && upcalls) + ossl_provider_free_parent(prov, 1); +#endif + return -1; + } + + if (lock && !CRYPTO_THREAD_write_lock(prov->flag_lock)) { + CRYPTO_THREAD_unlock(store->lock); +#ifndef FIPS_MODULE + if (prov->ischild && upcalls) + ossl_provider_free_parent(prov, 1); +#endif + return -1; + } + + count = ++prov->activatecnt; + prov->flag_activated = 1; + + if (prov->activatecnt == 1 && store != NULL) { + ret = create_provider_children(prov); + } + if (lock) { + CRYPTO_THREAD_unlock(prov->flag_lock); + CRYPTO_THREAD_unlock(store->lock); + } + + if (!ret) + return -1; + + return count; +} + +static int provider_flush_store_cache(const OSSL_PROVIDER *prov) +{ + struct provider_store_st *store; + int freeing; + + if ((store = get_provider_store(prov->libctx)) == NULL) + return 0; + + if (!CRYPTO_THREAD_read_lock(store->lock)) + return 0; + freeing = store->freeing; + CRYPTO_THREAD_unlock(store->lock); + + if (!freeing) { + int acc + = evp_method_store_cache_flush(prov->libctx) +#ifndef FIPS_MODULE + + ossl_encoder_store_cache_flush(prov->libctx) + + ossl_decoder_store_cache_flush(prov->libctx) + + ossl_store_loader_store_cache_flush(prov->libctx) +#endif + ; + +#ifndef FIPS_MODULE + return acc == 4; +#else + return acc == 1; +#endif + } + return 1; +} + +static int provider_remove_store_methods(OSSL_PROVIDER *prov) +{ + struct provider_store_st *store; + int freeing; + + if ((store = get_provider_store(prov->libctx)) == NULL) + return 0; + + if (!CRYPTO_THREAD_read_lock(store->lock)) + return 0; + freeing = store->freeing; + CRYPTO_THREAD_unlock(store->lock); + + if (!freeing) { + int acc; + + if (!CRYPTO_THREAD_write_lock(prov->opbits_lock)) + return 0; + OPENSSL_free(prov->operation_bits); + prov->operation_bits = NULL; + prov->operation_bits_sz = 0; + CRYPTO_THREAD_unlock(prov->opbits_lock); + + acc = evp_method_store_remove_all_provided(prov) +#ifndef FIPS_MODULE + + ossl_encoder_store_remove_all_provided(prov) + + ossl_decoder_store_remove_all_provided(prov) + + ossl_store_loader_store_remove_all_provided(prov) +#endif + ; + +#ifndef FIPS_MODULE + return acc == 4; +#else + return acc == 1; +#endif + } + return 1; +} + +int ossl_provider_activate(OSSL_PROVIDER *prov, int upcalls, int aschild) +{ + int count; + + if (prov == NULL) + return 0; +#ifndef FIPS_MODULE + /* + * If aschild is true, then we only actually do the activation if the + * provider is a child. If its not, this is still success. + */ + if (aschild && !prov->ischild) + return 1; +#endif + if ((count = provider_activate(prov, 1, upcalls)) > 0) + return count == 1 ? provider_flush_store_cache(prov) : 1; + + return 0; +} + +int ossl_provider_deactivate(OSSL_PROVIDER *prov, int removechildren) +{ + int count; + + if (prov == NULL + || (count = provider_deactivate(prov, 1, removechildren)) < 0) + return 0; + return count == 0 ? provider_remove_store_methods(prov) : 1; +} + +void *ossl_provider_ctx(const OSSL_PROVIDER *prov) +{ + return prov != NULL ? prov->provctx : NULL; +} + +/* + * This function only does something once when store->use_fallbacks == 1, + * and then sets store->use_fallbacks = 0, so the second call and so on is + * effectively a no-op. + */ +static int provider_activate_fallbacks(struct provider_store_st *store) +{ + int use_fallbacks; + int activated_fallback_count = 0; + int ret = 0; + const OSSL_PROVIDER_INFO *p; + + if (!CRYPTO_THREAD_read_lock(store->lock)) + return 0; + use_fallbacks = store->use_fallbacks; + CRYPTO_THREAD_unlock(store->lock); + if (!use_fallbacks) + return 1; + + if (!CRYPTO_THREAD_write_lock(store->lock)) + return 0; + /* Check again, just in case another thread changed it */ + use_fallbacks = store->use_fallbacks; + if (!use_fallbacks) { + CRYPTO_THREAD_unlock(store->lock); + return 1; + } + + for (p = ossl_predefined_providers; p->name != NULL; p++) { + OSSL_PROVIDER *prov = NULL; + + if (!p->is_fallback) + continue; + /* + * We use the internal constructor directly here, + * otherwise we get a call loop + */ + prov = provider_new(p->name, p->init, NULL); + if (prov == NULL) + goto err; + prov->libctx = store->libctx; +#ifndef FIPS_MODULE + prov->error_lib = ERR_get_next_error_library(); +#endif + + /* + * We are calling provider_activate while holding the store lock. This + * means the init function will be called while holding a lock. Normally + * we try to avoid calling a user callback while holding a lock. + * However, fallbacks are never third party providers so we accept this. + */ + if (provider_activate(prov, 0, 0) < 0) { + ossl_provider_free(prov); + goto err; + } + prov->store = store; + if (sk_OSSL_PROVIDER_push(store->providers, prov) == 0) { + ossl_provider_free(prov); + goto err; + } + activated_fallback_count++; + } + + if (activated_fallback_count > 0) { + store->use_fallbacks = 0; + ret = 1; + } + err: + CRYPTO_THREAD_unlock(store->lock); + return ret; +} + +int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx, + int (*cb)(OSSL_PROVIDER *provider, + void *cbdata), + void *cbdata) +{ + int ret = 0, curr, max, ref = 0; + struct provider_store_st *store = get_provider_store(ctx); + STACK_OF(OSSL_PROVIDER) *provs = NULL; + +#ifndef FIPS_MODULE + /* + * Make sure any providers are loaded from config before we try to use + * them. + */ + if (ossl_lib_ctx_is_default(ctx)) + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); +#endif + + if (store == NULL) + return 1; + if (!provider_activate_fallbacks(store)) + return 0; + + /* + * Under lock, grab a copy of the provider list and up_ref each + * provider so that they don't disappear underneath us. + */ + if (!CRYPTO_THREAD_read_lock(store->lock)) + return 0; + provs = sk_OSSL_PROVIDER_dup(store->providers); + if (provs == NULL) { + CRYPTO_THREAD_unlock(store->lock); + return 0; + } + max = sk_OSSL_PROVIDER_num(provs); + /* + * We work backwards through the stack so that we can safely delete items + * as we go. + */ + for (curr = max - 1; curr >= 0; curr--) { + OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, curr); + + if (!CRYPTO_THREAD_write_lock(prov->flag_lock)) + goto err_unlock; + if (prov->flag_activated) { + /* + * We call CRYPTO_UP_REF directly rather than ossl_provider_up_ref + * to avoid upping the ref count on the parent provider, which we + * must not do while holding locks. + */ + if (CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock) <= 0) { + CRYPTO_THREAD_unlock(prov->flag_lock); + goto err_unlock; + } + /* + * It's already activated, but we up the activated count to ensure + * it remains activated until after we've called the user callback. + * We do this with no locking (because we already hold the locks) + * and no upcalls (which must not be called when locks are held). In + * theory this could mean the parent provider goes inactive, whilst + * still activated in the child for a short period. That's ok. + */ + if (provider_activate(prov, 0, 0) < 0) { + CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock); + CRYPTO_THREAD_unlock(prov->flag_lock); + goto err_unlock; + } + } else { + sk_OSSL_PROVIDER_delete(provs, curr); + max--; + } + CRYPTO_THREAD_unlock(prov->flag_lock); + } + CRYPTO_THREAD_unlock(store->lock); + + /* + * Now, we sweep through all providers not under lock + */ + for (curr = 0; curr < max; curr++) { + OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, curr); + + if (!cb(prov, cbdata)) { + curr = -1; + goto finish; + } + } + curr = -1; + + ret = 1; + goto finish; + + err_unlock: + CRYPTO_THREAD_unlock(store->lock); + finish: + /* + * The pop_free call doesn't do what we want on an error condition. We + * either start from the first item in the stack, or part way through if + * we only processed some of the items. + */ + for (curr++; curr < max; curr++) { + OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, curr); + + provider_deactivate(prov, 0, 1); + /* + * As above where we did the up-ref, we don't call ossl_provider_free + * to avoid making upcalls. There should always be at least one ref + * to the provider in the store, so this should never drop to 0. + */ + CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock); + /* + * Not much we can do if this assert ever fails. So we don't use + * ossl_assert here. + */ + assert(ref > 0); + } + sk_OSSL_PROVIDER_free(provs); + return ret; +} + +int OSSL_PROVIDER_available(OSSL_LIB_CTX *libctx, const char *name) +{ + OSSL_PROVIDER *prov = NULL; + int available = 0; + struct provider_store_st *store = get_provider_store(libctx); + + if (store == NULL || !provider_activate_fallbacks(store)) + return 0; + + prov = ossl_provider_find(libctx, name, 0); + if (prov != NULL) { + if (!CRYPTO_THREAD_read_lock(prov->flag_lock)) + return 0; + available = prov->flag_activated; + CRYPTO_THREAD_unlock(prov->flag_lock); + ossl_provider_free(prov); + } + return available; +} + +/* Setters of Provider Object data */ +int ossl_provider_set_fallback(OSSL_PROVIDER *prov) +{ + if (prov == NULL) + return 0; + + prov->flag_fallback = 1; + return 1; +} + +/* Getters of Provider Object data */ +const char *ossl_provider_name(const OSSL_PROVIDER *prov) +{ + return prov->name; +} + +const DSO *ossl_provider_dso(const OSSL_PROVIDER *prov) +{ + return prov->module; +} + +const char *ossl_provider_module_name(const OSSL_PROVIDER *prov) +{ +#ifdef FIPS_MODULE + return NULL; +#else + return DSO_get_filename(prov->module); +#endif +} + +const char *ossl_provider_module_path(const OSSL_PROVIDER *prov) +{ +#ifdef FIPS_MODULE + return NULL; +#else + /* FIXME: Ensure it's a full path */ + return DSO_get_filename(prov->module); +#endif +} + +void *ossl_provider_prov_ctx(const OSSL_PROVIDER *prov) +{ + if (prov != NULL) + return prov->provctx; + + return NULL; +} + +const OSSL_DISPATCH *ossl_provider_get0_dispatch(const OSSL_PROVIDER *prov) +{ + if (prov != NULL) + return prov->dispatch; + + return NULL; +} + +OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov) +{ + return prov != NULL ? prov->libctx : NULL; +} + +/* Wrappers around calls to the provider */ +void ossl_provider_teardown(const OSSL_PROVIDER *prov) +{ + if (prov->teardown != NULL +#ifndef FIPS_MODULE + && !prov->ischild +#endif + ) + prov->teardown(prov->provctx); +} + +const OSSL_PARAM *ossl_provider_gettable_params(const OSSL_PROVIDER *prov) +{ + return prov->gettable_params == NULL + ? NULL : prov->gettable_params(prov->provctx); +} + +int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) +{ + return prov->get_params == NULL + ? 0 : prov->get_params(prov->provctx, params); +} + +int ossl_provider_self_test(const OSSL_PROVIDER *prov) +{ + int ret; + + if (prov->self_test == NULL) + return 1; + ret = prov->self_test(prov->provctx); + if (ret == 0) + (void)provider_remove_store_methods((OSSL_PROVIDER *)prov); + return ret; +} + +int ossl_provider_get_capabilities(const OSSL_PROVIDER *prov, + const char *capability, + OSSL_CALLBACK *cb, + void *arg) +{ + return prov->get_capabilities == NULL + ? 1 : prov->get_capabilities(prov->provctx, capability, cb, arg); +} + +const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, + int operation_id, + int *no_cache) +{ + const OSSL_ALGORITHM *res; + + if (prov->query_operation == NULL) + return NULL; + res = prov->query_operation(prov->provctx, operation_id, no_cache); +#if defined(OPENSSL_NO_CACHED_FETCH) + /* Forcing the non-caching of queries */ + if (no_cache != NULL) + *no_cache = 1; +#endif + return res; +} + +void ossl_provider_unquery_operation(const OSSL_PROVIDER *prov, + int operation_id, + const OSSL_ALGORITHM *algs) +{ + if (prov->unquery_operation != NULL) + prov->unquery_operation(prov->provctx, operation_id, algs); +} + +int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum) +{ + size_t byte = bitnum / 8; + unsigned char bit = (1 << (bitnum % 8)) & 0xFF; + + if (!CRYPTO_THREAD_write_lock(provider->opbits_lock)) + return 0; + if (provider->operation_bits_sz <= byte) { + unsigned char *tmp = OPENSSL_realloc(provider->operation_bits, + byte + 1); + + if (tmp == NULL) { + CRYPTO_THREAD_unlock(provider->opbits_lock); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + provider->operation_bits = tmp; + memset(provider->operation_bits + provider->operation_bits_sz, + '\0', byte + 1 - provider->operation_bits_sz); + provider->operation_bits_sz = byte + 1; + } + provider->operation_bits[byte] |= bit; + CRYPTO_THREAD_unlock(provider->opbits_lock); + return 1; +} + +int ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum, + int *result) +{ + size_t byte = bitnum / 8; + unsigned char bit = (1 << (bitnum % 8)) & 0xFF; + + if (!ossl_assert(result != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + *result = 0; + if (!CRYPTO_THREAD_read_lock(provider->opbits_lock)) + return 0; + if (provider->operation_bits_sz > byte) + *result = ((provider->operation_bits[byte] & bit) != 0); + CRYPTO_THREAD_unlock(provider->opbits_lock); + return 1; +} + +#ifndef FIPS_MODULE +const OSSL_CORE_HANDLE *ossl_provider_get_parent(OSSL_PROVIDER *prov) +{ + return prov->handle; +} + +int ossl_provider_is_child(const OSSL_PROVIDER *prov) +{ + return prov->ischild; +} + +int ossl_provider_set_child(OSSL_PROVIDER *prov, const OSSL_CORE_HANDLE *handle) +{ + prov->handle = handle; + prov->ischild = 1; + + return 1; +} + +int ossl_provider_default_props_update(OSSL_LIB_CTX *libctx, const char *props) +{ +#ifndef FIPS_MODULE + struct provider_store_st *store = NULL; + int i, max; + OSSL_PROVIDER_CHILD_CB *child_cb; + + if ((store = get_provider_store(libctx)) == NULL) + return 0; + + if (!CRYPTO_THREAD_read_lock(store->lock)) + return 0; + + max = sk_OSSL_PROVIDER_CHILD_CB_num(store->child_cbs); + for (i = 0; i < max; i++) { + child_cb = sk_OSSL_PROVIDER_CHILD_CB_value(store->child_cbs, i); + child_cb->global_props_cb(props, child_cb->cbdata); + } + + CRYPTO_THREAD_unlock(store->lock); +#endif + return 1; +} + +static int ossl_provider_register_child_cb(const OSSL_CORE_HANDLE *handle, + int (*create_cb)( + const OSSL_CORE_HANDLE *provider, + void *cbdata), + int (*remove_cb)( + const OSSL_CORE_HANDLE *provider, + void *cbdata), + int (*global_props_cb)( + const char *props, + void *cbdata), + void *cbdata) +{ + /* + * This is really an OSSL_PROVIDER that we created and cast to + * OSSL_CORE_HANDLE originally. Therefore it is safe to cast it back. + */ + OSSL_PROVIDER *thisprov = (OSSL_PROVIDER *)handle; + OSSL_PROVIDER *prov; + OSSL_LIB_CTX *libctx = thisprov->libctx; + struct provider_store_st *store = NULL; + int ret = 0, i, max; + OSSL_PROVIDER_CHILD_CB *child_cb; + char *propsstr = NULL; + + if ((store = get_provider_store(libctx)) == NULL) + return 0; + + child_cb = OPENSSL_malloc(sizeof(*child_cb)); + if (child_cb == NULL) + return 0; + child_cb->prov = thisprov; + child_cb->create_cb = create_cb; + child_cb->remove_cb = remove_cb; + child_cb->global_props_cb = global_props_cb; + child_cb->cbdata = cbdata; + + if (!CRYPTO_THREAD_write_lock(store->lock)) { + OPENSSL_free(child_cb); + return 0; + } + propsstr = evp_get_global_properties_str(libctx, 0); + + if (propsstr != NULL) { + global_props_cb(propsstr, cbdata); + OPENSSL_free(propsstr); + } + max = sk_OSSL_PROVIDER_num(store->providers); + for (i = 0; i < max; i++) { + int activated; + + prov = sk_OSSL_PROVIDER_value(store->providers, i); + + if (!CRYPTO_THREAD_read_lock(prov->flag_lock)) + break; + activated = prov->flag_activated; + CRYPTO_THREAD_unlock(prov->flag_lock); + /* + * We hold the store lock while calling the user callback. This means + * that the user callback must be short and simple and not do anything + * likely to cause a deadlock. We don't hold the flag_lock during this + * call. In theory this means that another thread could deactivate it + * while we are calling create. This is ok because the other thread + * will also call remove_cb, but won't be able to do so until we release + * the store lock. + */ + if (activated && !create_cb((OSSL_CORE_HANDLE *)prov, cbdata)) + break; + } + if (i == max) { + /* Success */ + ret = sk_OSSL_PROVIDER_CHILD_CB_push(store->child_cbs, child_cb); + } + if (i != max || ret <= 0) { + /* Failed during creation. Remove everything we just added */ + for (; i >= 0; i--) { + prov = sk_OSSL_PROVIDER_value(store->providers, i); + remove_cb((OSSL_CORE_HANDLE *)prov, cbdata); + } + OPENSSL_free(child_cb); + ret = 0; + } + CRYPTO_THREAD_unlock(store->lock); + + return ret; +} + +static void ossl_provider_deregister_child_cb(const OSSL_CORE_HANDLE *handle) +{ + /* + * This is really an OSSL_PROVIDER that we created and cast to + * OSSL_CORE_HANDLE originally. Therefore it is safe to cast it back. + */ + OSSL_PROVIDER *thisprov = (OSSL_PROVIDER *)handle; + OSSL_LIB_CTX *libctx = thisprov->libctx; + struct provider_store_st *store = NULL; + int i, max; + OSSL_PROVIDER_CHILD_CB *child_cb; + + if ((store = get_provider_store(libctx)) == NULL) + return; + + if (!CRYPTO_THREAD_write_lock(store->lock)) + return; + max = sk_OSSL_PROVIDER_CHILD_CB_num(store->child_cbs); + for (i = 0; i < max; i++) { + child_cb = sk_OSSL_PROVIDER_CHILD_CB_value(store->child_cbs, i); + if (child_cb->prov == thisprov) { + /* Found an entry */ + sk_OSSL_PROVIDER_CHILD_CB_delete(store->child_cbs, i); + OPENSSL_free(child_cb); + break; + } + } + CRYPTO_THREAD_unlock(store->lock); +} +#endif + +/*- + * Core functions for the provider + * =============================== + * + * This is the set of functions that the core makes available to the provider + */ + +/* + * This returns a list of Provider Object parameters with their types, for + * discovery. We do not expect that many providers will use this, but one + * never knows. + */ +static const OSSL_PARAM param_types[] = { + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_CORE_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_CORE_PROV_NAME, OSSL_PARAM_UTF8_PTR, + NULL, 0), +#ifndef FIPS_MODULE + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_CORE_MODULE_FILENAME, OSSL_PARAM_UTF8_PTR, + NULL, 0), +#endif + OSSL_PARAM_END +}; + +/* + * Forward declare all the functions that are provided aa dispatch. + * This ensures that the compiler will complain if they aren't defined + * with the correct signature. + */ +static OSSL_FUNC_core_gettable_params_fn core_gettable_params; +static OSSL_FUNC_core_get_params_fn core_get_params; +static OSSL_FUNC_core_get_libctx_fn core_get_libctx; +static OSSL_FUNC_core_thread_start_fn core_thread_start; +#ifndef FIPS_MODULE +static OSSL_FUNC_core_new_error_fn core_new_error; +static OSSL_FUNC_core_set_error_debug_fn core_set_error_debug; +static OSSL_FUNC_core_vset_error_fn core_vset_error; +static OSSL_FUNC_core_set_error_mark_fn core_set_error_mark; +static OSSL_FUNC_core_clear_last_error_mark_fn core_clear_last_error_mark; +static OSSL_FUNC_core_pop_error_to_mark_fn core_pop_error_to_mark; +OSSL_FUNC_BIO_new_file_fn ossl_core_bio_new_file; +OSSL_FUNC_BIO_new_membuf_fn ossl_core_bio_new_mem_buf; +OSSL_FUNC_BIO_read_ex_fn ossl_core_bio_read_ex; +OSSL_FUNC_BIO_write_ex_fn ossl_core_bio_write_ex; +OSSL_FUNC_BIO_gets_fn ossl_core_bio_gets; +OSSL_FUNC_BIO_puts_fn ossl_core_bio_puts; +OSSL_FUNC_BIO_up_ref_fn ossl_core_bio_up_ref; +OSSL_FUNC_BIO_free_fn ossl_core_bio_free; +OSSL_FUNC_BIO_vprintf_fn ossl_core_bio_vprintf; +OSSL_FUNC_BIO_vsnprintf_fn BIO_vsnprintf; +static OSSL_FUNC_self_test_cb_fn core_self_test_get_callback; +OSSL_FUNC_get_entropy_fn ossl_rand_get_entropy; +OSSL_FUNC_cleanup_entropy_fn ossl_rand_cleanup_entropy; +OSSL_FUNC_get_nonce_fn ossl_rand_get_nonce; +OSSL_FUNC_cleanup_nonce_fn ossl_rand_cleanup_nonce; +#endif +OSSL_FUNC_CRYPTO_malloc_fn CRYPTO_malloc; +OSSL_FUNC_CRYPTO_zalloc_fn CRYPTO_zalloc; +OSSL_FUNC_CRYPTO_free_fn CRYPTO_free; +OSSL_FUNC_CRYPTO_clear_free_fn CRYPTO_clear_free; +OSSL_FUNC_CRYPTO_realloc_fn CRYPTO_realloc; +OSSL_FUNC_CRYPTO_clear_realloc_fn CRYPTO_clear_realloc; +OSSL_FUNC_CRYPTO_secure_malloc_fn CRYPTO_secure_malloc; +OSSL_FUNC_CRYPTO_secure_zalloc_fn CRYPTO_secure_zalloc; +OSSL_FUNC_CRYPTO_secure_free_fn CRYPTO_secure_free; +OSSL_FUNC_CRYPTO_secure_clear_free_fn CRYPTO_secure_clear_free; +OSSL_FUNC_CRYPTO_secure_allocated_fn CRYPTO_secure_allocated; +OSSL_FUNC_OPENSSL_cleanse_fn OPENSSL_cleanse; +#ifndef FIPS_MODULE +OSSL_FUNC_provider_register_child_cb_fn ossl_provider_register_child_cb; +OSSL_FUNC_provider_deregister_child_cb_fn ossl_provider_deregister_child_cb; +static OSSL_FUNC_provider_name_fn core_provider_get0_name; +static OSSL_FUNC_provider_get0_provider_ctx_fn core_provider_get0_provider_ctx; +static OSSL_FUNC_provider_get0_dispatch_fn core_provider_get0_dispatch; +static OSSL_FUNC_provider_up_ref_fn core_provider_up_ref_intern; +static OSSL_FUNC_provider_free_fn core_provider_free_intern; +static OSSL_FUNC_core_obj_add_sigid_fn core_obj_add_sigid; +static OSSL_FUNC_core_obj_create_fn core_obj_create; +#endif + +static const OSSL_PARAM *core_gettable_params(const OSSL_CORE_HANDLE *handle) +{ + return param_types; +} + +static int core_get_params(const OSSL_CORE_HANDLE *handle, OSSL_PARAM params[]) +{ + int i; + OSSL_PARAM *p; + /* + * We created this object originally and we know it is actually an + * OSSL_PROVIDER *, so the cast is safe + */ + OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle; + + if ((p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_CORE_VERSION)) != NULL) + OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR); + if ((p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_CORE_PROV_NAME)) != NULL) + OSSL_PARAM_set_utf8_ptr(p, prov->name); + +#ifndef FIPS_MODULE + if ((p = OSSL_PARAM_locate(params, + OSSL_PROV_PARAM_CORE_MODULE_FILENAME)) != NULL) + OSSL_PARAM_set_utf8_ptr(p, ossl_provider_module_path(prov)); +#endif + + if (prov->parameters == NULL) + return 1; + + for (i = 0; i < sk_INFOPAIR_num(prov->parameters); i++) { + INFOPAIR *pair = sk_INFOPAIR_value(prov->parameters, i); + + if ((p = OSSL_PARAM_locate(params, pair->name)) != NULL) + OSSL_PARAM_set_utf8_ptr(p, pair->value); + } + return 1; +} + +static OPENSSL_CORE_CTX *core_get_libctx(const OSSL_CORE_HANDLE *handle) +{ + /* + * We created this object originally and we know it is actually an + * OSSL_PROVIDER *, so the cast is safe + */ + OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle; + + /* + * Using ossl_provider_libctx would be wrong as that returns + * NULL for |prov| == NULL and NULL libctx has a special meaning + * that does not apply here. Here |prov| == NULL can happen only in + * case of a coding error. + */ + assert(prov != NULL); + return (OPENSSL_CORE_CTX *)prov->libctx; +} + +static int core_thread_start(const OSSL_CORE_HANDLE *handle, + OSSL_thread_stop_handler_fn handfn, + void *arg) +{ + /* + * We created this object originally and we know it is actually an + * OSSL_PROVIDER *, so the cast is safe + */ + OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle; + + return ossl_init_thread_start(prov, arg, handfn); +} + +/* + * The FIPS module inner provider doesn't implement these. They aren't + * needed there, since the FIPS module upcalls are always the outer provider + * ones. + */ +#ifndef FIPS_MODULE +/* + * These error functions should use |handle| to select the proper + * library context to report in the correct error stack if error + * stacks become tied to the library context. + * We cannot currently do that since there's no support for it in the + * ERR subsystem. + */ +static void core_new_error(const OSSL_CORE_HANDLE *handle) +{ + ERR_new(); +} + +static void core_set_error_debug(const OSSL_CORE_HANDLE *handle, + const char *file, int line, const char *func) +{ + ERR_set_debug(file, line, func); +} + +static void core_vset_error(const OSSL_CORE_HANDLE *handle, + uint32_t reason, const char *fmt, va_list args) +{ + /* + * We created this object originally and we know it is actually an + * OSSL_PROVIDER *, so the cast is safe + */ + OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle; + + /* + * If the uppermost 8 bits are non-zero, it's an OpenSSL library + * error and will be treated as such. Otherwise, it's a new style + * provider error and will be treated as such. + */ + if (ERR_GET_LIB(reason) != 0) { + ERR_vset_error(ERR_GET_LIB(reason), ERR_GET_REASON(reason), fmt, args); + } else { + ERR_vset_error(prov->error_lib, (int)reason, fmt, args); + } +} + +static int core_set_error_mark(const OSSL_CORE_HANDLE *handle) +{ + return ERR_set_mark(); +} + +static int core_clear_last_error_mark(const OSSL_CORE_HANDLE *handle) +{ + return ERR_clear_last_mark(); +} + +static int core_pop_error_to_mark(const OSSL_CORE_HANDLE *handle) +{ + return ERR_pop_to_mark(); +} + +static void core_self_test_get_callback(OPENSSL_CORE_CTX *libctx, + OSSL_CALLBACK **cb, void **cbarg) +{ + OSSL_SELF_TEST_get_callback((OSSL_LIB_CTX *)libctx, cb, cbarg); +} + +static const char *core_provider_get0_name(const OSSL_CORE_HANDLE *prov) +{ + return OSSL_PROVIDER_get0_name((const OSSL_PROVIDER *)prov); +} + +static void *core_provider_get0_provider_ctx(const OSSL_CORE_HANDLE *prov) +{ + return OSSL_PROVIDER_get0_provider_ctx((const OSSL_PROVIDER *)prov); +} + +static const OSSL_DISPATCH * +core_provider_get0_dispatch(const OSSL_CORE_HANDLE *prov) +{ + return OSSL_PROVIDER_get0_dispatch((const OSSL_PROVIDER *)prov); +} + +static int core_provider_up_ref_intern(const OSSL_CORE_HANDLE *prov, + int activate) +{ + return provider_up_ref_intern((OSSL_PROVIDER *)prov, activate); +} + +static int core_provider_free_intern(const OSSL_CORE_HANDLE *prov, + int deactivate) +{ + return provider_free_intern((OSSL_PROVIDER *)prov, deactivate); +} + +static int core_obj_add_sigid(const OSSL_CORE_HANDLE *prov, + const char *sign_name, const char *digest_name, + const char *pkey_name) +{ + int sign_nid = OBJ_txt2nid(sign_name); + int digest_nid = NID_undef; + int pkey_nid = OBJ_txt2nid(pkey_name); + + if (digest_name != NULL && digest_name[0] != '\0' + && (digest_nid = OBJ_txt2nid(digest_name)) == NID_undef) + return 0; + + if (sign_nid == NID_undef) + return 0; + + /* + * Check if it already exists. This is a success if so (even if we don't + * have nids for the digest/pkey) + */ + if (OBJ_find_sigid_algs(sign_nid, NULL, NULL)) + return 1; + + if (pkey_nid == NID_undef) + return 0; + + return OBJ_add_sigid(sign_nid, digest_nid, pkey_nid); +} + +static int core_obj_create(const OSSL_CORE_HANDLE *prov, const char *oid, + const char *sn, const char *ln) +{ + /* Check if it already exists and create it if not */ + return OBJ_txt2nid(oid) != NID_undef + || OBJ_create(oid, sn, ln) != NID_undef; +} +#endif /* FIPS_MODULE */ + +/* + * Functions provided by the core. + */ +static const OSSL_DISPATCH core_dispatch_[] = { + { OSSL_FUNC_CORE_GETTABLE_PARAMS, (void (*)(void))core_gettable_params }, + { OSSL_FUNC_CORE_GET_PARAMS, (void (*)(void))core_get_params }, + { OSSL_FUNC_CORE_GET_LIBCTX, (void (*)(void))core_get_libctx }, + { OSSL_FUNC_CORE_THREAD_START, (void (*)(void))core_thread_start }, +#ifndef FIPS_MODULE + { OSSL_FUNC_CORE_NEW_ERROR, (void (*)(void))core_new_error }, + { OSSL_FUNC_CORE_SET_ERROR_DEBUG, (void (*)(void))core_set_error_debug }, + { OSSL_FUNC_CORE_VSET_ERROR, (void (*)(void))core_vset_error }, + { OSSL_FUNC_CORE_SET_ERROR_MARK, (void (*)(void))core_set_error_mark }, + { OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK, + (void (*)(void))core_clear_last_error_mark }, + { OSSL_FUNC_CORE_POP_ERROR_TO_MARK, (void (*)(void))core_pop_error_to_mark }, + { OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))ossl_core_bio_new_file }, + { OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))ossl_core_bio_new_mem_buf }, + { OSSL_FUNC_BIO_READ_EX, (void (*)(void))ossl_core_bio_read_ex }, + { OSSL_FUNC_BIO_WRITE_EX, (void (*)(void))ossl_core_bio_write_ex }, + { OSSL_FUNC_BIO_GETS, (void (*)(void))ossl_core_bio_gets }, + { OSSL_FUNC_BIO_PUTS, (void (*)(void))ossl_core_bio_puts }, + { OSSL_FUNC_BIO_CTRL, (void (*)(void))ossl_core_bio_ctrl }, + { OSSL_FUNC_BIO_UP_REF, (void (*)(void))ossl_core_bio_up_ref }, + { OSSL_FUNC_BIO_FREE, (void (*)(void))ossl_core_bio_free }, + { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))ossl_core_bio_vprintf }, + { OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf }, + { OSSL_FUNC_SELF_TEST_CB, (void (*)(void))core_self_test_get_callback }, + { OSSL_FUNC_GET_ENTROPY, (void (*)(void))ossl_rand_get_entropy }, + { OSSL_FUNC_CLEANUP_ENTROPY, (void (*)(void))ossl_rand_cleanup_entropy }, + { OSSL_FUNC_GET_NONCE, (void (*)(void))ossl_rand_get_nonce }, + { OSSL_FUNC_CLEANUP_NONCE, (void (*)(void))ossl_rand_cleanup_nonce }, +#endif + { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc }, + { OSSL_FUNC_CRYPTO_ZALLOC, (void (*)(void))CRYPTO_zalloc }, + { OSSL_FUNC_CRYPTO_FREE, (void (*)(void))CRYPTO_free }, + { OSSL_FUNC_CRYPTO_CLEAR_FREE, (void (*)(void))CRYPTO_clear_free }, + { OSSL_FUNC_CRYPTO_REALLOC, (void (*)(void))CRYPTO_realloc }, + { OSSL_FUNC_CRYPTO_CLEAR_REALLOC, (void (*)(void))CRYPTO_clear_realloc }, + { OSSL_FUNC_CRYPTO_SECURE_MALLOC, (void (*)(void))CRYPTO_secure_malloc }, + { OSSL_FUNC_CRYPTO_SECURE_ZALLOC, (void (*)(void))CRYPTO_secure_zalloc }, + { OSSL_FUNC_CRYPTO_SECURE_FREE, (void (*)(void))CRYPTO_secure_free }, + { OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE, + (void (*)(void))CRYPTO_secure_clear_free }, + { OSSL_FUNC_CRYPTO_SECURE_ALLOCATED, + (void (*)(void))CRYPTO_secure_allocated }, + { OSSL_FUNC_OPENSSL_CLEANSE, (void (*)(void))OPENSSL_cleanse }, +#ifndef FIPS_MODULE + { OSSL_FUNC_PROVIDER_REGISTER_CHILD_CB, + (void (*)(void))ossl_provider_register_child_cb }, + { OSSL_FUNC_PROVIDER_DEREGISTER_CHILD_CB, + (void (*)(void))ossl_provider_deregister_child_cb }, + { OSSL_FUNC_PROVIDER_NAME, + (void (*)(void))core_provider_get0_name }, + { OSSL_FUNC_PROVIDER_GET0_PROVIDER_CTX, + (void (*)(void))core_provider_get0_provider_ctx }, + { OSSL_FUNC_PROVIDER_GET0_DISPATCH, + (void (*)(void))core_provider_get0_dispatch }, + { OSSL_FUNC_PROVIDER_UP_REF, + (void (*)(void))core_provider_up_ref_intern }, + { OSSL_FUNC_PROVIDER_FREE, + (void (*)(void))core_provider_free_intern }, + { OSSL_FUNC_CORE_OBJ_ADD_SIGID, (void (*)(void))core_obj_add_sigid }, + { OSSL_FUNC_CORE_OBJ_CREATE, (void (*)(void))core_obj_create }, +#endif + { 0, NULL } +}; +static const OSSL_DISPATCH *core_dispatch = core_dispatch_; diff --git a/crypto/openssl/crypto/provider_local.h b/crypto/openssl/crypto/provider_local.h new file mode 100644 index 000000000000..e0bcbcb9f94e --- /dev/null +++ b/crypto/openssl/crypto/provider_local.h @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2021 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 + +typedef struct { + char *name; + char *value; +} INFOPAIR; +DEFINE_STACK_OF(INFOPAIR) + +typedef struct { + char *name; + char *path; + OSSL_provider_init_fn *init; + STACK_OF(INFOPAIR) *parameters; + unsigned int is_fallback:1; +} OSSL_PROVIDER_INFO; + +extern const OSSL_PROVIDER_INFO ossl_predefined_providers[]; + +void ossl_provider_info_clear(OSSL_PROVIDER_INFO *info); +int ossl_provider_info_add_to_store(OSSL_LIB_CTX *libctx, + OSSL_PROVIDER_INFO *entry); +int ossl_provider_info_add_parameter(OSSL_PROVIDER_INFO *provinfo, + const char *name, + const char *value); diff --git a/crypto/openssl/crypto/provider_predefined.c b/crypto/openssl/crypto/provider_predefined.c new file mode 100644 index 000000000000..068e0b7cd96a --- /dev/null +++ b/crypto/openssl/crypto/provider_predefined.c @@ -0,0 +1,32 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "provider_local.h" + +OSSL_provider_init_fn ossl_default_provider_init; +OSSL_provider_init_fn ossl_base_provider_init; +OSSL_provider_init_fn ossl_null_provider_init; +OSSL_provider_init_fn ossl_fips_intern_provider_init; +#ifdef STATIC_LEGACY +OSSL_provider_init_fn ossl_legacy_provider_init; +#endif +const OSSL_PROVIDER_INFO ossl_predefined_providers[] = { +#ifdef FIPS_MODULE + { "fips", NULL, ossl_fips_intern_provider_init, NULL, 1 }, +#else + { "default", NULL, ossl_default_provider_init, NULL, 1 }, +# ifdef STATIC_LEGACY + { "legacy", NULL, ossl_legacy_provider_init, NULL, 0 }, +# endif + { "base", NULL, ossl_base_provider_init, NULL, 0 }, + { "null", NULL, ossl_null_provider_init, NULL, 0 }, +#endif + { NULL, NULL, NULL, NULL, 0 } +}; diff --git a/crypto/openssl/crypto/punycode.c b/crypto/openssl/crypto/punycode.c new file mode 100644 index 000000000000..2de32dc18873 --- /dev/null +++ b/crypto/openssl/crypto/punycode.c @@ -0,0 +1,332 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "crypto/punycode.h" + +static const unsigned int base = 36; +static const unsigned int tmin = 1; +static const unsigned int tmax = 26; +static const unsigned int skew = 38; +static const unsigned int damp = 700; +static const unsigned int initial_bias = 72; +static const unsigned int initial_n = 0x80; +static const unsigned int maxint = 0xFFFFFFFF; +static const char delimiter = '-'; + +#define LABEL_BUF_SIZE 512 + +/*- + * Pseudocode: + * + * function adapt(delta,numpoints,firsttime): + * if firsttime then let delta = delta div damp + * else let delta = delta div 2 + * let delta = delta + (delta div numpoints) + * let k = 0 + * while delta > ((base - tmin) * tmax) div 2 do begin + * let delta = delta div (base - tmin) + * let k = k + base + * end + * return k + (((base - tmin + 1) * delta) div (delta + skew)) + */ + +static int adapt(unsigned int delta, unsigned int numpoints, + unsigned int firsttime) +{ + unsigned int k = 0; + + delta = (firsttime) ? delta / damp : delta / 2; + delta = delta + delta / numpoints; + + while (delta > ((base - tmin) * tmax) / 2) { + delta = delta / (base - tmin); + k = k + base; + } + + return k + (((base - tmin + 1) * delta) / (delta + skew)); +} + +static ossl_inline int is_basic(unsigned int a) +{ + return (a < 0x80) ? 1 : 0; +} + +/*- + * code points digit-values + * ------------ ---------------------- + * 41..5A (A-Z) = 0 to 25, respectively + * 61..7A (a-z) = 0 to 25, respectively + * 30..39 (0-9) = 26 to 35, respectively + */ +static ossl_inline int digit_decoded(const unsigned char a) +{ + if (a >= 0x41 && a <= 0x5A) + return a - 0x41; + + if (a >= 0x61 && a <= 0x7A) + return a - 0x61; + + if (a >= 0x30 && a <= 0x39) + return a - 0x30 + 26; + + return -1; +} + +/*- + * Pseudocode: + * + * function ossl_punycode_decode + * let n = initial_n + * let i = 0 + * let bias = initial_bias + * let output = an empty string indexed from 0 + * consume all code points before the last delimiter (if there is one) + * and copy them to output, fail on any non-basic code point + * if more than zero code points were consumed then consume one more + * (which will be the last delimiter) + * while the input is not exhausted do begin + * let oldi = i + * let w = 1 + * for k = base to infinity in steps of base do begin + * consume a code point, or fail if there was none to consume + * let digit = the code point's digit-value, fail if it has none + * let i = i + digit * w, fail on overflow + * let t = tmin if k <= bias {+ tmin}, or + * tmax if k >= bias + tmax, or k - bias otherwise + * if digit < t then break + * let w = w * (base - t), fail on overflow + * end + * let bias = adapt(i - oldi, length(output) + 1, test oldi is 0?) + * let n = n + i div (length(output) + 1), fail on overflow + * let i = i mod (length(output) + 1) + * {if n is a basic code point then fail} + * insert n into output at position i + * increment i + * end + */ + +int ossl_punycode_decode(const char *pEncoded, const size_t enc_len, + unsigned int *pDecoded, unsigned int *pout_length) +{ + unsigned int n = initial_n; + unsigned int i = 0; + unsigned int bias = initial_bias; + size_t processed_in = 0, written_out = 0; + unsigned int max_out = *pout_length; + unsigned int basic_count = 0; + unsigned int loop; + + for (loop = 0; loop < enc_len; loop++) { + if (pEncoded[loop] == delimiter) + basic_count = loop; + } + + if (basic_count > 0) { + if (basic_count > max_out) + return 0; + + for (loop = 0; loop < basic_count; loop++) { + if (is_basic(pEncoded[loop]) == 0) + return 0; + + pDecoded[loop] = pEncoded[loop]; + written_out++; + } + processed_in = basic_count + 1; + } + + for (loop = processed_in; loop < enc_len;) { + unsigned int oldi = i; + unsigned int w = 1; + unsigned int k, t; + int digit; + + for (k = base;; k += base) { + if (loop >= enc_len) + return 0; + + digit = digit_decoded(pEncoded[loop]); + loop++; + + if (digit < 0) + return 0; + if ((unsigned int)digit > (maxint - i) / w) + return 0; + + i = i + digit * w; + t = (k <= bias) ? tmin : (k >= bias + tmax) ? tmax : k - bias; + + if ((unsigned int)digit < t) + break; + + if (w > maxint / (base - t)) + return 0; + w = w * (base - t); + } + + bias = adapt(i - oldi, written_out + 1, (oldi == 0)); + if (i / (written_out + 1) > maxint - n) + return 0; + n = n + i / (written_out + 1); + i %= (written_out + 1); + + if (written_out >= max_out) + return 0; + + memmove(pDecoded + i + 1, pDecoded + i, + (written_out - i) * sizeof(*pDecoded)); + pDecoded[i] = n; + i++; + written_out++; + } + + *pout_length = written_out; + return 1; +} + +/* + * Encode a code point using UTF-8 + * return number of bytes on success, 0 on failure + * (also produces U+FFFD, which uses 3 bytes on failure) + */ +static int codepoint2utf8(unsigned char *out, unsigned long utf) +{ + if (utf <= 0x7F) { + /* Plain ASCII */ + out[0] = (unsigned char)utf; + out[1] = 0; + return 1; + } else if (utf <= 0x07FF) { + /* 2-byte unicode */ + out[0] = (unsigned char)(((utf >> 6) & 0x1F) | 0xC0); + out[1] = (unsigned char)(((utf >> 0) & 0x3F) | 0x80); + out[2] = 0; + return 2; + } else if (utf <= 0xFFFF) { + /* 3-byte unicode */ + out[0] = (unsigned char)(((utf >> 12) & 0x0F) | 0xE0); + out[1] = (unsigned char)(((utf >> 6) & 0x3F) | 0x80); + out[2] = (unsigned char)(((utf >> 0) & 0x3F) | 0x80); + out[3] = 0; + return 3; + } else if (utf <= 0x10FFFF) { + /* 4-byte unicode */ + out[0] = (unsigned char)(((utf >> 18) & 0x07) | 0xF0); + out[1] = (unsigned char)(((utf >> 12) & 0x3F) | 0x80); + out[2] = (unsigned char)(((utf >> 6) & 0x3F) | 0x80); + out[3] = (unsigned char)(((utf >> 0) & 0x3F) | 0x80); + out[4] = 0; + return 4; + } else { + /* error - use replacement character */ + out[0] = (unsigned char)0xEF; + out[1] = (unsigned char)0xBF; + out[2] = (unsigned char)0xBD; + out[3] = 0; + return 0; + } +} + +/*- + * Return values: + * 1 - ok, *outlen contains valid buf length + * 0 - ok but buf was too short, *outlen contains valid buf length + * -1 - bad string passed + */ + +int ossl_a2ulabel(const char *in, char *out, size_t *outlen) +{ + /*- + * Domain name has some parts consisting of ASCII chars joined with dot. + * If a part is shorter than 5 chars, it becomes U-label as is. + * If it does not start with xn--, it becomes U-label as is. + * Otherwise we try to decode it. + */ + char *outptr = out; + const char *inptr = in; + size_t size = 0, maxsize; + int result = 1; + unsigned int i, j; + unsigned int buf[LABEL_BUF_SIZE]; /* It's a hostname */ + + if (out == NULL) { + result = 0; + maxsize = 0; + } else { + maxsize = *outlen; + } + +#define PUSHC(c) \ + do \ + if (size++ < maxsize) \ + *outptr++ = c; \ + else \ + result = 0; \ + while (0) + + while (1) { + char *tmpptr = strchr(inptr, '.'); + size_t delta = tmpptr != NULL ? (size_t)(tmpptr - inptr) : strlen(inptr); + + if (strncmp(inptr, "xn--", 4) != 0) { + for (i = 0; i < delta + 1; i++) + PUSHC(inptr[i]); + } else { + unsigned int bufsize = LABEL_BUF_SIZE; + + if (ossl_punycode_decode(inptr + 4, delta - 4, buf, &bufsize) <= 0) + return -1; + + for (i = 0; i < bufsize; i++) { + unsigned char seed[6]; + size_t utfsize = codepoint2utf8(seed, buf[i]); + + if (utfsize == 0) + return -1; + + for (j = 0; j < utfsize; j++) + PUSHC(seed[j]); + } + + PUSHC(tmpptr != NULL ? '.' : '\0'); + } + + if (tmpptr == NULL) + break; + + inptr = tmpptr + 1; + } +#undef PUSHC + + *outlen = size; + return result; +} + +/*- + * a MUST be A-label + * u MUST be U-label + * Returns 0 if compared values are equal + * 1 if not + * -1 in case of errors + */ + +int ossl_a2ucompare(const char *a, const char *u) +{ + char a_ulabel[LABEL_BUF_SIZE + 1]; + size_t a_size = sizeof(a_ulabel); + + if (ossl_a2ulabel(a, a_ulabel, &a_size) <= 0) + return -1; + + return strcmp(a_ulabel, u) != 0; +} diff --git a/crypto/openssl/crypto/rand/build.info b/crypto/openssl/crypto/rand/build.info index a4e7900bdbff..a74282516f24 100644 --- a/crypto/openssl/crypto/rand/build.info +++ b/crypto/openssl/crypto/rand/build.info @@ -1,6 +1,14 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - randfile.c rand_lib.c rand_err.c rand_egd.c \ - rand_win.c rand_unix.c rand_vms.c drbg_lib.c drbg_ctr.c -INCLUDE[drbg_ctr.o]=../modes +$COMMON=rand_lib.c +$CRYPTO=randfile.c rand_err.c rand_deprecated.c prov_seed.c rand_pool.c + +IF[{- !$disabled{'egd'} -}] + $CRYPTO=$CRYPTO rand_egd.c +ENDIF +IF[{- !$disabled{'deprecated-3.0'} -}] + $CRYPTO=$CRYPTO rand_meth.c +ENDIF + +SOURCE[../../libcrypto]=$COMMON $CRYPTO +SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/openssl/crypto/rand/drbg_ctr.c b/crypto/openssl/crypto/rand/drbg_ctr.c deleted file mode 100644 index a757d0a258ab..000000000000 --- a/crypto/openssl/crypto/rand/drbg_ctr.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include "modes_local.h" -#include "internal/thread_once.h" -#include "rand_local.h" - -/* - * Implementation of NIST SP 800-90A CTR DRBG. - */ - -static void inc_128(RAND_DRBG_CTR *ctr) -{ - unsigned char *p = &ctr->V[0]; - u32 n = 16, c = 1; - - do { - --n; - c += p[n]; - p[n] = (u8)c; - c >>= 8; - } while (n); -} - -static void ctr_XOR(RAND_DRBG_CTR *ctr, const unsigned char *in, size_t inlen) -{ - size_t i, n; - - if (in == NULL || inlen == 0) - return; - - /* - * Any zero padding will have no effect on the result as we - * are XORing. So just process however much input we have. - */ - n = inlen < ctr->keylen ? inlen : ctr->keylen; - for (i = 0; i < n; i++) - ctr->K[i] ^= in[i]; - if (inlen <= ctr->keylen) - return; - - n = inlen - ctr->keylen; - if (n > 16) { - /* Should never happen */ - n = 16; - } - for (i = 0; i < n; i++) - ctr->V[i] ^= in[i + ctr->keylen]; -} - -/* - * Process a complete block using BCC algorithm of SP 800-90A 10.3.3 - */ -__owur static int ctr_BCC_block(RAND_DRBG_CTR *ctr, unsigned char *out, - const unsigned char *in, int len) -{ - int i, outlen = AES_BLOCK_SIZE; - - for (i = 0; i < len; i++) - out[i] ^= in[i]; - - if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len) - || outlen != len) - return 0; - return 1; -} - - -/* - * Handle several BCC operations for as much data as we need for K and X - */ -__owur static int ctr_BCC_blocks(RAND_DRBG_CTR *ctr, const unsigned char *in) -{ - unsigned char in_tmp[48]; - unsigned char num_of_blk = 2; - - memcpy(in_tmp, in, 16); - memcpy(in_tmp + 16, in, 16); - if (ctr->keylen != 16) { - memcpy(in_tmp + 32, in, 16); - num_of_blk = 3; - } - return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk); -} - -/* - * Initialise BCC blocks: these have the value 0,1,2 in leftmost positions: - * see 10.3.1 stage 7. - */ -__owur static int ctr_BCC_init(RAND_DRBG_CTR *ctr) -{ - unsigned char bltmp[48] = {0}; - unsigned char num_of_blk; - - memset(ctr->KX, 0, 48); - num_of_blk = ctr->keylen == 16 ? 2 : 3; - bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1; - bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2; - return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE); -} - -/* - * Process several blocks into BCC algorithm, some possibly partial - */ -__owur static int ctr_BCC_update(RAND_DRBG_CTR *ctr, - const unsigned char *in, size_t inlen) -{ - if (in == NULL || inlen == 0) - return 1; - - /* If we have partial block handle it first */ - if (ctr->bltmp_pos) { - size_t left = 16 - ctr->bltmp_pos; - - /* If we now have a complete block process it */ - if (inlen >= left) { - memcpy(ctr->bltmp + ctr->bltmp_pos, in, left); - if (!ctr_BCC_blocks(ctr, ctr->bltmp)) - return 0; - ctr->bltmp_pos = 0; - inlen -= left; - in += left; - } - } - - /* Process zero or more complete blocks */ - for (; inlen >= 16; in += 16, inlen -= 16) { - if (!ctr_BCC_blocks(ctr, in)) - return 0; - } - - /* Copy any remaining partial block to the temporary buffer */ - if (inlen > 0) { - memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen); - ctr->bltmp_pos += inlen; - } - return 1; -} - -__owur static int ctr_BCC_final(RAND_DRBG_CTR *ctr) -{ - if (ctr->bltmp_pos) { - memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos); - if (!ctr_BCC_blocks(ctr, ctr->bltmp)) - return 0; - } - return 1; -} - -__owur static int ctr_df(RAND_DRBG_CTR *ctr, - const unsigned char *in1, size_t in1len, - const unsigned char *in2, size_t in2len, - const unsigned char *in3, size_t in3len) -{ - static unsigned char c80 = 0x80; - size_t inlen; - unsigned char *p = ctr->bltmp; - int outlen = AES_BLOCK_SIZE; - - if (!ctr_BCC_init(ctr)) - return 0; - if (in1 == NULL) - in1len = 0; - if (in2 == NULL) - in2len = 0; - if (in3 == NULL) - in3len = 0; - inlen = in1len + in2len + in3len; - /* Initialise L||N in temporary block */ - *p++ = (inlen >> 24) & 0xff; - *p++ = (inlen >> 16) & 0xff; - *p++ = (inlen >> 8) & 0xff; - *p++ = inlen & 0xff; - - /* NB keylen is at most 32 bytes */ - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p = (unsigned char)((ctr->keylen + 16) & 0xff); - ctr->bltmp_pos = 8; - if (!ctr_BCC_update(ctr, in1, in1len) - || !ctr_BCC_update(ctr, in2, in2len) - || !ctr_BCC_update(ctr, in3, in3len) - || !ctr_BCC_update(ctr, &c80, 1) - || !ctr_BCC_final(ctr)) - return 0; - /* Set up key K */ - if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1)) - return 0; - /* X follows key K */ - if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen, - AES_BLOCK_SIZE) - || outlen != AES_BLOCK_SIZE) - return 0; - if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX, - AES_BLOCK_SIZE) - || outlen != AES_BLOCK_SIZE) - return 0; - if (ctr->keylen != 16) - if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen, - ctr->KX + 16, AES_BLOCK_SIZE) - || outlen != AES_BLOCK_SIZE) - return 0; - return 1; -} - -/* - * NB the no-df Update in SP800-90A specifies a constant input length - * of seedlen, however other uses of this algorithm pad the input with - * zeroes if necessary and have up to two parameters XORed together, - * so we handle both cases in this function instead. - */ -__owur static int ctr_update(RAND_DRBG *drbg, - const unsigned char *in1, size_t in1len, - const unsigned char *in2, size_t in2len, - const unsigned char *nonce, size_t noncelen) -{ - RAND_DRBG_CTR *ctr = &drbg->data.ctr; - int outlen = AES_BLOCK_SIZE; - unsigned char V_tmp[48], out[48]; - unsigned char len; - - /* correct key is already set up. */ - memcpy(V_tmp, ctr->V, 16); - inc_128(ctr); - memcpy(V_tmp + 16, ctr->V, 16); - if (ctr->keylen == 16) { - len = 32; - } else { - inc_128(ctr); - memcpy(V_tmp + 32, ctr->V, 16); - len = 48; - } - if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len) - || outlen != len) - return 0; - memcpy(ctr->K, out, ctr->keylen); - memcpy(ctr->V, out + ctr->keylen, 16); - - if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) { - /* If no input reuse existing derived value */ - if (in1 != NULL || nonce != NULL || in2 != NULL) - if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len)) - return 0; - /* If this a reuse input in1len != 0 */ - if (in1len) - ctr_XOR(ctr, ctr->KX, drbg->seedlen); - } else { - ctr_XOR(ctr, in1, in1len); - ctr_XOR(ctr, in2, in2len); - } - - if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1) - || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1)) - return 0; - return 1; -} - -__owur static int drbg_ctr_instantiate(RAND_DRBG *drbg, - const unsigned char *entropy, size_t entropylen, - const unsigned char *nonce, size_t noncelen, - const unsigned char *pers, size_t perslen) -{ - RAND_DRBG_CTR *ctr = &drbg->data.ctr; - - if (entropy == NULL) - return 0; - - memset(ctr->K, 0, sizeof(ctr->K)); - memset(ctr->V, 0, sizeof(ctr->V)); - if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)) - return 0; - - inc_128(ctr); - if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen)) - return 0; - return 1; -} - -__owur static int drbg_ctr_reseed(RAND_DRBG *drbg, - const unsigned char *entropy, size_t entropylen, - const unsigned char *adin, size_t adinlen) -{ - RAND_DRBG_CTR *ctr = &drbg->data.ctr; - - if (entropy == NULL) - return 0; - - inc_128(ctr); - if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0)) - return 0; - return 1; -} - -static void ctr96_inc(unsigned char *counter) -{ - u32 n = 12, c = 1; - - do { - --n; - c += counter[n]; - counter[n] = (u8)c; - c >>= 8; - } while (n); -} - -__owur static int drbg_ctr_generate(RAND_DRBG *drbg, - unsigned char *out, size_t outlen, - const unsigned char *adin, size_t adinlen) -{ - RAND_DRBG_CTR *ctr = &drbg->data.ctr; - unsigned int ctr32, blocks; - int outl, buflen; - - if (adin != NULL && adinlen != 0) { - inc_128(ctr); - - if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0)) - return 0; - /* This means we reuse derived value */ - if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) { - adin = NULL; - adinlen = 1; - } - } else { - adinlen = 0; - } - - inc_128(ctr); - - if (outlen == 0) { - inc_128(ctr); - - if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0)) - return 0; - return 1; - } - - memset(out, 0, outlen); - - do { - if (!EVP_CipherInit_ex(ctr->ctx_ctr, - NULL, NULL, NULL, ctr->V, -1)) - return 0; - - /*- - * outlen has type size_t while EVP_CipherUpdate takes an - * int argument and thus cannot be guaranteed to process more - * than 2^31-1 bytes at a time. We process such huge generate - * requests in 2^30 byte chunks, which is the greatest multiple - * of AES block size lower than or equal to 2^31-1. - */ - buflen = outlen > (1U << 30) ? (1U << 30) : outlen; - blocks = (buflen + 15) / 16; - - ctr32 = GETU32(ctr->V + 12) + blocks; - if (ctr32 < blocks) { - /* 32-bit counter overflow into V. */ - if (ctr32 != 0) { - blocks -= ctr32; - buflen = blocks * 16; - ctr32 = 0; - } - ctr96_inc(ctr->V); - } - PUTU32(ctr->V + 12, ctr32); - - if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen) - || outl != buflen) - return 0; - - out += buflen; - outlen -= buflen; - } while (outlen); - - if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0)) - return 0; - return 1; -} - -static int drbg_ctr_uninstantiate(RAND_DRBG *drbg) -{ - EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_ecb); - EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_ctr); - EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_df); - OPENSSL_cleanse(&drbg->data.ctr, sizeof(drbg->data.ctr)); - return 1; -} - -static RAND_DRBG_METHOD drbg_ctr_meth = { - drbg_ctr_instantiate, - drbg_ctr_reseed, - drbg_ctr_generate, - drbg_ctr_uninstantiate -}; - -int drbg_ctr_init(RAND_DRBG *drbg) -{ - RAND_DRBG_CTR *ctr = &drbg->data.ctr; - size_t keylen; - - switch (drbg->type) { - default: - /* This can't happen, but silence the compiler warning. */ - return 0; - case NID_aes_128_ctr: - keylen = 16; - ctr->cipher_ecb = EVP_aes_128_ecb(); - ctr->cipher_ctr = EVP_aes_128_ctr(); - break; - case NID_aes_192_ctr: - keylen = 24; - ctr->cipher_ecb = EVP_aes_192_ecb(); - ctr->cipher_ctr = EVP_aes_192_ctr(); - break; - case NID_aes_256_ctr: - keylen = 32; - ctr->cipher_ecb = EVP_aes_256_ecb(); - ctr->cipher_ctr = EVP_aes_256_ctr(); - break; - } - - drbg->meth = &drbg_ctr_meth; - - ctr->keylen = keylen; - if (ctr->ctx_ecb == NULL) - ctr->ctx_ecb = EVP_CIPHER_CTX_new(); - if (ctr->ctx_ctr == NULL) - ctr->ctx_ctr = EVP_CIPHER_CTX_new(); - if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL - || !EVP_CipherInit_ex(ctr->ctx_ecb, - ctr->cipher_ecb, NULL, NULL, NULL, 1) - || !EVP_CipherInit_ex(ctr->ctx_ctr, - ctr->cipher_ctr, NULL, NULL, NULL, 1)) - return 0; - - drbg->meth = &drbg_ctr_meth; - drbg->strength = keylen * 8; - drbg->seedlen = keylen + 16; - - if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) { - /* df initialisation */ - static const unsigned char df_key[32] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f - }; - - if (ctr->ctx_df == NULL) - ctr->ctx_df = EVP_CIPHER_CTX_new(); - if (ctr->ctx_df == NULL) - return 0; - /* Set key schedule for df_key */ - if (!EVP_CipherInit_ex(ctr->ctx_df, - ctr->cipher_ecb, NULL, df_key, NULL, 1)) - return 0; - - drbg->min_entropylen = ctr->keylen; - drbg->max_entropylen = DRBG_MAX_LENGTH; - drbg->min_noncelen = drbg->min_entropylen / 2; - drbg->max_noncelen = DRBG_MAX_LENGTH; - drbg->max_perslen = DRBG_MAX_LENGTH; - drbg->max_adinlen = DRBG_MAX_LENGTH; - } else { - drbg->min_entropylen = drbg->seedlen; - drbg->max_entropylen = drbg->seedlen; - /* Nonce not used */ - drbg->min_noncelen = 0; - drbg->max_noncelen = 0; - drbg->max_perslen = drbg->seedlen; - drbg->max_adinlen = drbg->seedlen; - } - - drbg->max_request = 1 << 16; - - return 1; -} diff --git a/crypto/openssl/crypto/rand/drbg_lib.c b/crypto/openssl/crypto/rand/drbg_lib.c deleted file mode 100644 index d32fa80cf89d..000000000000 --- a/crypto/openssl/crypto/rand/drbg_lib.c +++ /dev/null @@ -1,1148 +0,0 @@ -/* - * Copyright 2011-2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include "rand_local.h" -#include "internal/thread_once.h" -#include "crypto/rand.h" -#include "crypto/cryptlib.h" - -/* - * Support framework for NIST SP 800-90A DRBG - * - * See manual page RAND_DRBG(7) for a general overview. - * - * The OpenSSL model is to have new and free functions, and that new - * does all initialization. That is not the NIST model, which has - * instantiation and un-instantiate, and re-use within a new/free - * lifecycle. (No doubt this comes from the desire to support hardware - * DRBG, where allocation of resources on something like an HSM is - * a much bigger deal than just re-setting an allocated resource.) - */ - -/* - * The three shared DRBG instances - * - * There are three shared DRBG instances: , , and . - */ - -/* - * The DRBG - * - * Not used directly by the application, only for reseeding the two other - * DRBGs. It reseeds itself by pulling either randomness from os entropy - * sources or by consuming randomness which was added by RAND_add(). - * - * The DRBG is a global instance which is accessed concurrently by - * all threads. The necessary locking is managed automatically by its child - * DRBG instances during reseeding. - */ -static RAND_DRBG *master_drbg; -/* - * The DRBG - * - * Used by default for generating random bytes using RAND_bytes(). - * - * The DRBG is thread-local, i.e., there is one instance per thread. - */ -static CRYPTO_THREAD_LOCAL public_drbg; -/* - * The DRBG - * - * Used by default for generating private keys using RAND_priv_bytes() - * - * The DRBG is thread-local, i.e., there is one instance per thread. - */ -static CRYPTO_THREAD_LOCAL private_drbg; - - - -/* NIST SP 800-90A DRBG recommends the use of a personalization string. */ -static const char ossl_pers_string[] = "OpenSSL NIST SP 800-90A DRBG"; - -static CRYPTO_ONCE rand_drbg_init = CRYPTO_ONCE_STATIC_INIT; - - - -static int rand_drbg_type = RAND_DRBG_TYPE; -static unsigned int rand_drbg_flags = RAND_DRBG_FLAGS; - -static unsigned int master_reseed_interval = MASTER_RESEED_INTERVAL; -static unsigned int slave_reseed_interval = SLAVE_RESEED_INTERVAL; - -static time_t master_reseed_time_interval = MASTER_RESEED_TIME_INTERVAL; -static time_t slave_reseed_time_interval = SLAVE_RESEED_TIME_INTERVAL; - -/* A logical OR of all used DRBG flag bits (currently there is only one) */ -static const unsigned int rand_drbg_used_flags = - RAND_DRBG_FLAG_CTR_NO_DF; - -static RAND_DRBG *drbg_setup(RAND_DRBG *parent); - -static RAND_DRBG *rand_drbg_new(int secure, - int type, - unsigned int flags, - RAND_DRBG *parent); - -/* - * Set/initialize |drbg| to be of type |type|, with optional |flags|. - * - * If |type| and |flags| are zero, use the defaults - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags) -{ - int ret = 1; - - if (type == 0 && flags == 0) { - type = rand_drbg_type; - flags = rand_drbg_flags; - } - - /* If set is called multiple times - clear the old one */ - if (drbg->type != 0 && (type != drbg->type || flags != drbg->flags)) { - drbg->meth->uninstantiate(drbg); - rand_pool_free(drbg->adin_pool); - drbg->adin_pool = NULL; - } - - drbg->state = DRBG_UNINITIALISED; - drbg->flags = flags; - drbg->type = type; - - switch (type) { - default: - drbg->type = 0; - drbg->flags = 0; - drbg->meth = NULL; - RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE); - return 0; - case 0: - /* Uninitialized; that's okay. */ - drbg->meth = NULL; - return 1; - case NID_aes_128_ctr: - case NID_aes_192_ctr: - case NID_aes_256_ctr: - ret = drbg_ctr_init(drbg); - break; - } - - if (ret == 0) { - drbg->state = DRBG_ERROR; - RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_ERROR_INITIALISING_DRBG); - } - return ret; -} - -/* - * Set/initialize default |type| and |flag| for new drbg instances. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set_defaults(int type, unsigned int flags) -{ - int ret = 1; - - switch (type) { - default: - RANDerr(RAND_F_RAND_DRBG_SET_DEFAULTS, RAND_R_UNSUPPORTED_DRBG_TYPE); - return 0; - case NID_aes_128_ctr: - case NID_aes_192_ctr: - case NID_aes_256_ctr: - break; - } - - if ((flags & ~rand_drbg_used_flags) != 0) { - RANDerr(RAND_F_RAND_DRBG_SET_DEFAULTS, RAND_R_UNSUPPORTED_DRBG_FLAGS); - return 0; - } - - rand_drbg_type = type; - rand_drbg_flags = flags; - - return ret; -} - - -/* - * Allocate memory and initialize a new DRBG. The DRBG is allocated on - * the secure heap if |secure| is nonzero and the secure heap is enabled. - * The |parent|, if not NULL, will be used as random source for reseeding. - * - * Returns a pointer to the new DRBG instance on success, NULL on failure. - */ -static RAND_DRBG *rand_drbg_new(int secure, - int type, - unsigned int flags, - RAND_DRBG *parent) -{ - RAND_DRBG *drbg = secure ? OPENSSL_secure_zalloc(sizeof(*drbg)) - : OPENSSL_zalloc(sizeof(*drbg)); - - if (drbg == NULL) { - RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - - drbg->secure = secure && CRYPTO_secure_allocated(drbg); - drbg->fork_id = openssl_get_fork_id(); - drbg->parent = parent; - - if (parent == NULL) { - drbg->get_entropy = rand_drbg_get_entropy; - drbg->cleanup_entropy = rand_drbg_cleanup_entropy; -#ifndef RAND_DRBG_GET_RANDOM_NONCE - drbg->get_nonce = rand_drbg_get_nonce; - drbg->cleanup_nonce = rand_drbg_cleanup_nonce; -#endif - - drbg->reseed_interval = master_reseed_interval; - drbg->reseed_time_interval = master_reseed_time_interval; - } else { - drbg->get_entropy = rand_drbg_get_entropy; - drbg->cleanup_entropy = rand_drbg_cleanup_entropy; - /* - * Do not provide nonce callbacks, the child DRBGs will - * obtain their nonce using random bits from the parent. - */ - - drbg->reseed_interval = slave_reseed_interval; - drbg->reseed_time_interval = slave_reseed_time_interval; - } - - if (RAND_DRBG_set(drbg, type, flags) == 0) - goto err; - - if (parent != NULL) { - rand_drbg_lock(parent); - if (drbg->strength > parent->strength) { - /* - * We currently don't support the algorithm from NIST SP 800-90C - * 10.1.2 to use a weaker DRBG as source - */ - rand_drbg_unlock(parent); - RANDerr(RAND_F_RAND_DRBG_NEW, RAND_R_PARENT_STRENGTH_TOO_WEAK); - goto err; - } - rand_drbg_unlock(parent); - } - - return drbg; - - err: - RAND_DRBG_free(drbg); - - return NULL; -} - -RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent) -{ - return rand_drbg_new(0, type, flags, parent); -} - -RAND_DRBG *RAND_DRBG_secure_new(int type, unsigned int flags, RAND_DRBG *parent) -{ - return rand_drbg_new(1, type, flags, parent); -} - -/* - * Uninstantiate |drbg| and free all memory. - */ -void RAND_DRBG_free(RAND_DRBG *drbg) -{ - if (drbg == NULL) - return; - - if (drbg->meth != NULL) - drbg->meth->uninstantiate(drbg); - rand_pool_free(drbg->adin_pool); - CRYPTO_THREAD_lock_free(drbg->lock); - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data); - - if (drbg->secure) - OPENSSL_secure_clear_free(drbg, sizeof(*drbg)); - else - OPENSSL_clear_free(drbg, sizeof(*drbg)); -} - -/* - * Instantiate |drbg|, after it has been initialized. Use |pers| and - * |perslen| as prediction-resistance input. - * - * Requires that drbg->lock is already locked for write, if non-null. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_instantiate(RAND_DRBG *drbg, - const unsigned char *pers, size_t perslen) -{ - unsigned char *nonce = NULL, *entropy = NULL; - size_t noncelen = 0, entropylen = 0; - size_t min_entropy = drbg->strength; - size_t min_entropylen = drbg->min_entropylen; - size_t max_entropylen = drbg->max_entropylen; - - if (perslen > drbg->max_perslen) { - RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, - RAND_R_PERSONALISATION_STRING_TOO_LONG); - goto end; - } - - if (drbg->meth == NULL) { - RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, - RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED); - goto end; - } - - if (drbg->state != DRBG_UNINITIALISED) { - RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, - drbg->state == DRBG_ERROR ? RAND_R_IN_ERROR_STATE - : RAND_R_ALREADY_INSTANTIATED); - goto end; - } - - drbg->state = DRBG_ERROR; - - /* - * 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 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) { - min_entropy += drbg->strength / 2; - min_entropylen += drbg->min_noncelen; - max_entropylen += drbg->max_noncelen; - } - - if (drbg->get_entropy != NULL) - entropylen = drbg->get_entropy(drbg, &entropy, min_entropy, - min_entropylen, max_entropylen, 0); - if (entropylen < min_entropylen - || entropylen > max_entropylen) { - RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_RETRIEVING_ENTROPY); - goto end; - } - - if (drbg->min_noncelen > 0 && drbg->get_nonce != NULL) { - noncelen = drbg->get_nonce(drbg, &nonce, drbg->strength / 2, - drbg->min_noncelen, drbg->max_noncelen); - if (noncelen < drbg->min_noncelen || noncelen > drbg->max_noncelen) { - RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_RETRIEVING_NONCE); - goto end; - } - } - - if (!drbg->meth->instantiate(drbg, entropy, entropylen, - nonce, noncelen, pers, perslen)) { - RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_INSTANTIATING_DRBG); - goto end; - } - - drbg->state = DRBG_READY; - drbg->generate_counter = 1; - drbg->reseed_time = time(NULL); - if (drbg->enable_reseed_propagation && drbg->parent == NULL) - tsan_counter(&drbg->reseed_counter); - - end: - if (entropy != NULL && drbg->cleanup_entropy != NULL) - drbg->cleanup_entropy(drbg, entropy, entropylen); - if (nonce != NULL && drbg->cleanup_nonce != NULL) - drbg->cleanup_nonce(drbg, nonce, noncelen); - if (drbg->state == DRBG_READY) - return 1; - return 0; -} - -/* - * Uninstantiate |drbg|. Must be instantiated before it can be used. - * - * Requires that drbg->lock is already locked for write, if non-null. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_uninstantiate(RAND_DRBG *drbg) -{ - if (drbg->meth == NULL) { - drbg->state = DRBG_ERROR; - RANDerr(RAND_F_RAND_DRBG_UNINSTANTIATE, - RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED); - return 0; - } - - /* Clear the entire drbg->ctr struct, then reset some important - * members of the drbg->ctr struct (e.g. keysize, df_ks) to their - * initial values. - */ - drbg->meth->uninstantiate(drbg); - return RAND_DRBG_set(drbg, drbg->type, drbg->flags); -} - -/* - * Reseed |drbg|, mixing in the specified data - * - * Requires that drbg->lock is already locked for write, if non-null. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_reseed(RAND_DRBG *drbg, - const unsigned char *adin, size_t adinlen, - int prediction_resistance) -{ - unsigned char *entropy = NULL; - size_t entropylen = 0; - - if (drbg->state == DRBG_ERROR) { - RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_IN_ERROR_STATE); - return 0; - } - if (drbg->state == DRBG_UNINITIALISED) { - RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_NOT_INSTANTIATED); - return 0; - } - - if (adin == NULL) { - adinlen = 0; - } else if (adinlen > drbg->max_adinlen) { - RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_ADDITIONAL_INPUT_TOO_LONG); - return 0; - } - - drbg->state = DRBG_ERROR; - if (drbg->get_entropy != NULL) - entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength, - drbg->min_entropylen, - drbg->max_entropylen, - prediction_resistance); - if (entropylen < drbg->min_entropylen - || entropylen > drbg->max_entropylen) { - RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_ERROR_RETRIEVING_ENTROPY); - goto end; - } - - if (!drbg->meth->reseed(drbg, entropy, entropylen, adin, adinlen)) - goto end; - - drbg->state = DRBG_READY; - drbg->generate_counter = 1; - drbg->reseed_time = time(NULL); - if (drbg->enable_reseed_propagation && drbg->parent == NULL) - tsan_counter(&drbg->reseed_counter); - - end: - if (entropy != NULL && drbg->cleanup_entropy != NULL) - drbg->cleanup_entropy(drbg, entropy, entropylen); - if (drbg->state == DRBG_READY) - return 1; - return 0; -} - -/* - * Restart |drbg|, using the specified entropy or additional input - * - * Tries its best to get the drbg instantiated by all means, - * regardless of its current state. - * - * Optionally, a |buffer| of |len| random bytes can be passed, - * which is assumed to contain at least |entropy| bits of entropy. - * - * If |entropy| > 0, the buffer content is used as entropy input. - * - * If |entropy| == 0, the buffer content is used as additional input - * - * Returns 1 on success, 0 on failure. - * - * This function is used internally only. - */ -int rand_drbg_restart(RAND_DRBG *drbg, - const unsigned char *buffer, size_t len, size_t entropy) -{ - int reseeded = 0; - const unsigned char *adin = NULL; - size_t adinlen = 0; - - if (drbg->seed_pool != NULL) { - RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR); - drbg->state = DRBG_ERROR; - rand_pool_free(drbg->seed_pool); - drbg->seed_pool = NULL; - return 0; - } - - if (buffer != NULL) { - if (entropy > 0) { - if (drbg->max_entropylen < len) { - RANDerr(RAND_F_RAND_DRBG_RESTART, - RAND_R_ENTROPY_INPUT_TOO_LONG); - drbg->state = DRBG_ERROR; - return 0; - } - - if (entropy > 8 * len) { - RANDerr(RAND_F_RAND_DRBG_RESTART, RAND_R_ENTROPY_OUT_OF_RANGE); - drbg->state = DRBG_ERROR; - return 0; - } - - /* will be picked up by the rand_drbg_get_entropy() callback */ - drbg->seed_pool = rand_pool_attach(buffer, len, entropy); - if (drbg->seed_pool == NULL) - return 0; - } else { - if (drbg->max_adinlen < len) { - RANDerr(RAND_F_RAND_DRBG_RESTART, - RAND_R_ADDITIONAL_INPUT_TOO_LONG); - drbg->state = DRBG_ERROR; - return 0; - } - adin = buffer; - adinlen = len; - } - } - - /* repair error state */ - if (drbg->state == DRBG_ERROR) - RAND_DRBG_uninstantiate(drbg); - - /* repair uninitialized state */ - if (drbg->state == DRBG_UNINITIALISED) { - /* reinstantiate drbg */ - RAND_DRBG_instantiate(drbg, - (const unsigned char *) ossl_pers_string, - sizeof(ossl_pers_string) - 1); - /* already reseeded. prevent second reseeding below */ - reseeded = (drbg->state == DRBG_READY); - } - - /* refresh current state if entropy or additional input has been provided */ - if (drbg->state == DRBG_READY) { - if (adin != NULL) { - /* - * mix in additional input without reseeding - * - * Similar to RAND_DRBG_reseed(), but the provided additional - * data |adin| is mixed into the current state without pulling - * entropy from the trusted entropy source using get_entropy(). - * This is not a reseeding in the strict sense of NIST SP 800-90A. - */ - drbg->meth->reseed(drbg, adin, adinlen, NULL, 0); - } else if (reseeded == 0) { - /* do a full reseeding if it has not been done yet above */ - if (!RAND_DRBG_reseed(drbg, NULL, 0, 0)) { - RANDerr(RAND_F_RAND_DRBG_RESTART, RAND_R_RESEED_ERROR); - } - } - } - - rand_pool_free(drbg->seed_pool); - drbg->seed_pool = NULL; - - return drbg->state == DRBG_READY; -} - -/* - * Generate |outlen| bytes into the buffer at |out|. Reseed if we need - * to or if |prediction_resistance| is set. Additional input can be - * sent in |adin| and |adinlen|. - * - * Requires that drbg->lock is already locked for write, if non-null. - * - * Returns 1 on success, 0 on failure. - * - */ -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) { - /* try to recover from previous errors */ - rand_drbg_restart(drbg, NULL, 0, 0); - - if (drbg->state == DRBG_ERROR) { - RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_IN_ERROR_STATE); - return 0; - } - if (drbg->state == DRBG_UNINITIALISED) { - RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_NOT_INSTANTIATED); - return 0; - } - } - - if (outlen > drbg->max_request) { - RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_REQUEST_TOO_LARGE_FOR_DRBG); - return 0; - } - if (adinlen > drbg->max_adinlen) { - RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_ADDITIONAL_INPUT_TOO_LONG); - return 0; - } - - fork_id = openssl_get_fork_id(); - - if (drbg->fork_id != fork_id) { - drbg->fork_id = fork_id; - reseed_required = 1; - } - - if (drbg->reseed_interval > 0) { - if (drbg->generate_counter >= drbg->reseed_interval) - reseed_required = 1; - } - if (drbg->reseed_time_interval > 0) { - time_t now = time(NULL); - if (now < drbg->reseed_time - || now - drbg->reseed_time >= drbg->reseed_time_interval) - reseed_required = 1; - } - if (drbg->enable_reseed_propagation && drbg->parent != NULL) { - if (drbg->reseed_counter != tsan_load(&drbg->parent->reseed_counter)) - reseed_required = 1; - } - - if (reseed_required || prediction_resistance) { - if (!RAND_DRBG_reseed(drbg, adin, adinlen, prediction_resistance)) { - RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_RESEED_ERROR); - return 0; - } - adin = NULL; - adinlen = 0; - } - - if (!drbg->meth->generate(drbg, out, outlen, adin, adinlen)) { - drbg->state = DRBG_ERROR; - RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_GENERATE_ERROR); - return 0; - } - - drbg->generate_counter++; - - return 1; -} - -/* - * Generates |outlen| random bytes and stores them in |out|. It will - * using the given |drbg| to generate the bytes. - * - * Requires that drbg->lock is already locked for write, if non-null. - * - * Returns 1 on success 0 on failure. - */ -int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen) -{ - unsigned char *additional = NULL; - size_t additional_len; - size_t chunk; - size_t ret = 0; - - if (drbg->adin_pool == NULL) { - if (drbg->type == 0) - goto err; - drbg->adin_pool = rand_pool_new(0, 0, 0, drbg->max_adinlen); - if (drbg->adin_pool == NULL) - goto err; - } - - additional_len = rand_drbg_get_additional_data(drbg->adin_pool, - &additional); - - for ( ; outlen > 0; outlen -= chunk, out += chunk) { - chunk = outlen; - if (chunk > drbg->max_request) - chunk = drbg->max_request; - ret = RAND_DRBG_generate(drbg, out, chunk, 0, additional, additional_len); - if (!ret) - goto err; - } - ret = 1; - - err: - if (additional != NULL) - rand_drbg_cleanup_additional_data(drbg->adin_pool, additional); - - return ret; -} - -/* - * Set the RAND_DRBG callbacks for obtaining entropy and nonce. - * - * Setting the callbacks is allowed only if the drbg has not been - * initialized yet. Otherwise, the operation will fail. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set_callbacks(RAND_DRBG *drbg, - RAND_DRBG_get_entropy_fn get_entropy, - RAND_DRBG_cleanup_entropy_fn cleanup_entropy, - RAND_DRBG_get_nonce_fn get_nonce, - RAND_DRBG_cleanup_nonce_fn cleanup_nonce) -{ - if (drbg->state != DRBG_UNINITIALISED) - return 0; - drbg->get_entropy = get_entropy; - drbg->cleanup_entropy = cleanup_entropy; - drbg->get_nonce = get_nonce; - drbg->cleanup_nonce = cleanup_nonce; - return 1; -} - -/* - * Set the reseed interval. - * - * The drbg will reseed automatically whenever the number of generate - * requests exceeds the given reseed interval. If the reseed interval - * is 0, then this feature is disabled. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, unsigned int interval) -{ - if (interval > MAX_RESEED_INTERVAL) - return 0; - drbg->reseed_interval = interval; - return 1; -} - -/* - * Set the reseed time interval. - * - * The drbg will reseed automatically whenever the time elapsed since - * the last reseeding exceeds the given reseed time interval. For safety, - * a reseeding will also occur if the clock has been reset to a smaller - * value. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval) -{ - if (interval > MAX_RESEED_TIME_INTERVAL) - return 0; - drbg->reseed_time_interval = interval; - return 1; -} - -/* - * Set the default values for reseed (time) intervals of new DRBG instances - * - * The default values can be set independently for master DRBG instances - * (without a parent) and slave DRBG instances (with parent). - * - * Returns 1 on success, 0 on failure. - */ - -int RAND_DRBG_set_reseed_defaults( - unsigned int _master_reseed_interval, - unsigned int _slave_reseed_interval, - time_t _master_reseed_time_interval, - time_t _slave_reseed_time_interval - ) -{ - if (_master_reseed_interval > MAX_RESEED_INTERVAL - || _slave_reseed_interval > MAX_RESEED_INTERVAL) - return 0; - - if (_master_reseed_time_interval > MAX_RESEED_TIME_INTERVAL - || _slave_reseed_time_interval > MAX_RESEED_TIME_INTERVAL) - return 0; - - master_reseed_interval = _master_reseed_interval; - slave_reseed_interval = _slave_reseed_interval; - - master_reseed_time_interval = _master_reseed_time_interval; - slave_reseed_time_interval = _slave_reseed_time_interval; - - return 1; -} - -/* - * Locks the given drbg. Locking a drbg which does not have locking - * enabled is considered a successful no-op. - * - * Returns 1 on success, 0 on failure. - */ -int rand_drbg_lock(RAND_DRBG *drbg) -{ - if (drbg->lock != NULL) - return CRYPTO_THREAD_write_lock(drbg->lock); - - return 1; -} - -/* - * Unlocks the given drbg. Unlocking a drbg which does not have locking - * enabled is considered a successful no-op. - * - * Returns 1 on success, 0 on failure. - */ -int rand_drbg_unlock(RAND_DRBG *drbg) -{ - if (drbg->lock != NULL) - return CRYPTO_THREAD_unlock(drbg->lock); - - return 1; -} - -/* - * Enables locking for the given drbg - * - * Locking can only be enabled if the random generator - * is in the uninitialized state. - * - * Returns 1 on success, 0 on failure. - */ -int rand_drbg_enable_locking(RAND_DRBG *drbg) -{ - if (drbg->state != DRBG_UNINITIALISED) { - RANDerr(RAND_F_RAND_DRBG_ENABLE_LOCKING, - RAND_R_DRBG_ALREADY_INITIALIZED); - return 0; - } - - if (drbg->lock == NULL) { - if (drbg->parent != NULL && drbg->parent->lock == NULL) { - RANDerr(RAND_F_RAND_DRBG_ENABLE_LOCKING, - RAND_R_PARENT_LOCKING_NOT_ENABLED); - return 0; - } - - drbg->lock = CRYPTO_THREAD_lock_new(); - if (drbg->lock == NULL) { - RANDerr(RAND_F_RAND_DRBG_ENABLE_LOCKING, - RAND_R_FAILED_TO_CREATE_LOCK); - return 0; - } - } - - return 1; -} - -/* - * Get and set the EXDATA - */ -int RAND_DRBG_set_ex_data(RAND_DRBG *drbg, int idx, void *arg) -{ - return CRYPTO_set_ex_data(&drbg->ex_data, idx, arg); -} - -void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx) -{ - return CRYPTO_get_ex_data(&drbg->ex_data, idx); -} - - -/* - * The following functions provide a RAND_METHOD that works on the - * global DRBG. They lock. - */ - -/* - * Allocates a new global DRBG on the secure heap (if enabled) and - * initializes it with default settings. - * - * Returns a pointer to the new DRBG instance on success, NULL on failure. - */ -static RAND_DRBG *drbg_setup(RAND_DRBG *parent) -{ - RAND_DRBG *drbg; - - drbg = RAND_DRBG_secure_new(rand_drbg_type, rand_drbg_flags, parent); - if (drbg == NULL) - return NULL; - - /* Only the master DRBG needs to have a lock */ - if (parent == NULL && rand_drbg_enable_locking(drbg) == 0) - goto err; - - /* enable reseed propagation */ - drbg->enable_reseed_propagation = 1; - drbg->reseed_counter = 1; - - /* - * Ignore instantiation error to support just-in-time instantiation. - * - * The state of the drbg will be checked in RAND_DRBG_generate() and - * an automatic recovery is attempted. - */ - (void)RAND_DRBG_instantiate(drbg, - (const unsigned char *) ossl_pers_string, - sizeof(ossl_pers_string) - 1); - return drbg; - -err: - RAND_DRBG_free(drbg); - return NULL; -} - -/* - * Initialize the global DRBGs on first use. - * Returns 1 on success, 0 on failure. - */ -DEFINE_RUN_ONCE_STATIC(do_rand_drbg_init) -{ - /* - * ensure that libcrypto is initialized, otherwise the - * DRBG locks are not cleaned up properly - */ - if (!OPENSSL_init_crypto(0, NULL)) - return 0; - - if (!CRYPTO_THREAD_init_local(&private_drbg, NULL)) - return 0; - - if (!CRYPTO_THREAD_init_local(&public_drbg, NULL)) - goto err1; - - master_drbg = drbg_setup(NULL); - if (master_drbg == NULL) - goto err2; - - return 1; - -err2: - CRYPTO_THREAD_cleanup_local(&public_drbg); -err1: - CRYPTO_THREAD_cleanup_local(&private_drbg); - return 0; -} - -/* Clean up the global DRBGs before exit */ -void rand_drbg_cleanup_int(void) -{ - if (master_drbg != NULL) { - RAND_DRBG_free(master_drbg); - master_drbg = NULL; - - CRYPTO_THREAD_cleanup_local(&private_drbg); - CRYPTO_THREAD_cleanup_local(&public_drbg); - } -} - -void drbg_delete_thread_state(void) -{ - RAND_DRBG *drbg; - - drbg = CRYPTO_THREAD_get_local(&public_drbg); - CRYPTO_THREAD_set_local(&public_drbg, NULL); - RAND_DRBG_free(drbg); - - drbg = CRYPTO_THREAD_get_local(&private_drbg); - CRYPTO_THREAD_set_local(&private_drbg, NULL); - RAND_DRBG_free(drbg); -} - -/* Implements the default OpenSSL RAND_bytes() method */ -static int drbg_bytes(unsigned char *out, int count) -{ - int ret; - RAND_DRBG *drbg = RAND_DRBG_get0_public(); - - if (drbg == NULL) - return 0; - - ret = RAND_DRBG_bytes(drbg, out, count); - - return ret; -} - -/* - * Calculates the minimum length of a full entropy buffer - * which is necessary to seed (i.e. instantiate) the DRBG - * successfully. - */ -size_t rand_drbg_seedlen(RAND_DRBG *drbg) -{ - /* - * If no os entropy source is available then RAND_seed(buffer, bufsize) - * is expected to succeed if and only if the buffer length satisfies - * the following requirements, which follow from the calculations - * in RAND_DRBG_instantiate(). - */ - size_t min_entropy = drbg->strength; - size_t min_entropylen = drbg->min_entropylen; - - /* - * Extra entropy for the random nonce in the absence of a - * get_nonce callback, see comment in RAND_DRBG_instantiate(). - */ - if (drbg->min_noncelen > 0 && drbg->get_nonce == NULL) { - min_entropy += drbg->strength / 2; - min_entropylen += drbg->min_noncelen; - } - - /* - * Convert entropy requirement from bits to bytes - * (dividing by 8 without rounding upwards, because - * all entropy requirements are divisible by 8). - */ - min_entropy >>= 3; - - /* Return a value that satisfies both requirements */ - return min_entropy > min_entropylen ? min_entropy : min_entropylen; -} - -/* Implements the default OpenSSL RAND_add() method */ -static int drbg_add(const void *buf, int num, double randomness) -{ - int ret = 0; - RAND_DRBG *drbg = RAND_DRBG_get0_master(); - size_t buflen; - size_t seedlen; - - if (drbg == NULL) - return 0; - - if (num < 0 || randomness < 0.0) - return 0; - - rand_drbg_lock(drbg); - seedlen = rand_drbg_seedlen(drbg); - - buflen = (size_t)num; - - if (buflen < seedlen || randomness < (double) seedlen) { -#if defined(OPENSSL_RAND_SEED_NONE) - /* - * If no os entropy source is available, a reseeding will fail - * inevitably. So we use a trick to mix the buffer contents into - * the DRBG state without forcing a reseeding: we generate a - * dummy random byte, using the buffer content as additional data. - * Note: This won't work with RAND_DRBG_FLAG_CTR_NO_DF. - */ - unsigned char dummy[1]; - - ret = RAND_DRBG_generate(drbg, dummy, sizeof(dummy), 0, buf, buflen); - rand_drbg_unlock(drbg); - return ret; -#else - /* - * If an os entropy source is available then we declare the buffer content - * as additional data by setting randomness to zero and trigger a regular - * reseeding. - */ - randomness = 0.0; -#endif - } - - - if (randomness > (double)seedlen) { - /* - * The purpose of this check is to bound |randomness| by a - * relatively small value in order to prevent an integer - * overflow when multiplying by 8 in the rand_drbg_restart() - * call below. Note that randomness is measured in bytes, - * not bits, so this value corresponds to eight times the - * security strength. - */ - randomness = (double)seedlen; - } - - ret = rand_drbg_restart(drbg, buf, buflen, (size_t)(8 * randomness)); - rand_drbg_unlock(drbg); - - return ret; -} - -/* Implements the default OpenSSL RAND_seed() method */ -static int drbg_seed(const void *buf, int num) -{ - return drbg_add(buf, num, num); -} - -/* Implements the default OpenSSL RAND_status() method */ -static int drbg_status(void) -{ - int ret; - RAND_DRBG *drbg = RAND_DRBG_get0_master(); - - if (drbg == NULL) - return 0; - - rand_drbg_lock(drbg); - ret = drbg->state == DRBG_READY ? 1 : 0; - rand_drbg_unlock(drbg); - return ret; -} - -/* - * Get the master DRBG. - * Returns pointer to the DRBG on success, NULL on failure. - * - */ -RAND_DRBG *RAND_DRBG_get0_master(void) -{ - if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init)) - return NULL; - - return master_drbg; -} - -/* - * Get the public DRBG. - * Returns pointer to the DRBG on success, NULL on failure. - */ -RAND_DRBG *RAND_DRBG_get0_public(void) -{ - RAND_DRBG *drbg; - - if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init)) - return NULL; - - drbg = CRYPTO_THREAD_get_local(&public_drbg); - if (drbg == NULL) { - if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND)) - return NULL; - drbg = drbg_setup(master_drbg); - CRYPTO_THREAD_set_local(&public_drbg, drbg); - } - return drbg; -} - -/* - * Get the private DRBG. - * Returns pointer to the DRBG on success, NULL on failure. - */ -RAND_DRBG *RAND_DRBG_get0_private(void) -{ - RAND_DRBG *drbg; - - if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init)) - return NULL; - - drbg = CRYPTO_THREAD_get_local(&private_drbg); - if (drbg == NULL) { - if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND)) - return NULL; - drbg = drbg_setup(master_drbg); - CRYPTO_THREAD_set_local(&private_drbg, drbg); - } - return drbg; -} - -RAND_METHOD rand_meth = { - drbg_seed, - drbg_bytes, - NULL, - drbg_add, - drbg_bytes, - drbg_status -}; - -RAND_METHOD *RAND_OpenSSL(void) -{ - return &rand_meth; -} diff --git a/crypto/openssl/crypto/rand/prov_seed.c b/crypto/openssl/crypto/rand/prov_seed.c new file mode 100644 index 000000000000..96c499c95709 --- /dev/null +++ b/crypto/openssl/crypto/rand/prov_seed.c @@ -0,0 +1,76 @@ +/* + * Copyright 2020-2022 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 "crypto/rand.h" +#include "crypto/rand_pool.h" +#include +#include + +size_t ossl_rand_get_entropy(ossl_unused const OSSL_CORE_HANDLE *handle, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len) +{ + size_t ret = 0; + size_t entropy_available; + RAND_POOL *pool; + + pool = ossl_rand_pool_new(entropy, 1, min_len, max_len); + if (pool == NULL) { + ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* Get entropy by polling system entropy sources. */ + entropy_available = ossl_pool_acquire_entropy(pool); + + if (entropy_available > 0) { + ret = ossl_rand_pool_length(pool); + *pout = ossl_rand_pool_detach(pool); + } + + ossl_rand_pool_free(pool); + return ret; +} + +void ossl_rand_cleanup_entropy(ossl_unused const OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len) +{ + OPENSSL_secure_clear_free(buf, len); +} + +size_t ossl_rand_get_nonce(ossl_unused const OSSL_CORE_HANDLE *handle, + unsigned char **pout, size_t min_len, size_t max_len, + const void *salt, size_t salt_len) +{ + size_t ret = 0; + RAND_POOL *pool; + + pool = ossl_rand_pool_new(0, 0, min_len, max_len); + if (pool == NULL) { + ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!ossl_pool_add_nonce_data(pool)) + goto err; + + if (salt != NULL && !ossl_rand_pool_add(pool, salt, salt_len, 0)) + goto err; + ret = ossl_rand_pool_length(pool); + *pout = ossl_rand_pool_detach(pool); + err: + ossl_rand_pool_free(pool); + return ret; +} + +void ossl_rand_cleanup_nonce(ossl_unused const OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len) +{ + OPENSSL_clear_free(buf, len); +} diff --git a/crypto/openssl/crypto/rand/rand_deprecated.c b/crypto/openssl/crypto/rand/rand_deprecated.c new file mode 100644 index 000000000000..dd69f1beb726 --- /dev/null +++ b/crypto/openssl/crypto/rand/rand_deprecated.c @@ -0,0 +1,35 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include + +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# include +# if OPENSSL_API_COMPAT < 0x10100000L + +# define DEPRECATED_RAND_FUNCTIONS_DEFINED + +int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) +{ + RAND_poll(); + return RAND_status(); +} + +void RAND_screen(void) +{ + RAND_poll(); +} +# endif +#endif + +#ifndef DEPRECATED_RAND_FUNCTIONS_DEFINED +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/rand/rand_egd.c b/crypto/openssl/crypto/rand/rand_egd.c index da3017df3142..1699e7f38f0f 100644 --- a/crypto/openssl/crypto/rand/rand_egd.c +++ b/crypto/openssl/crypto/rand/rand_egd.c @@ -1,26 +1,23 @@ /* - * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 -#ifdef OPENSSL_NO_EGD -NON_EMPTY_TRANSLATION_UNIT -#else -# include -# include -# include +#include +#include +#include /* * Query an EGD */ -# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_UEFI) +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_UEFI) int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) { return -1; @@ -36,26 +33,78 @@ int RAND_egd_bytes(const char *path, int bytes) return -1; } -# else +#else -# include OPENSSL_UNISTD -# include -# include -# include -# ifndef NO_SYS_UN_H -# ifdef OPENSSL_SYS_VXWORKS -# include -# else -# include -# endif -# else +# include +# include +# include +# include +# ifndef NO_SYS_UN_H +# include +# else struct sockaddr_un { short sun_family; /* AF_UNIX */ char sun_path[108]; /* path name (gag) */ }; -# endif /* NO_SYS_UN_H */ -# include -# include +# endif /* NO_SYS_UN_H */ +# include +# include + +# if defined(OPENSSL_SYS_TANDEM) +/* + * HPNS: + * + * This code forces the use of compatibility mode if required on HPE NonStop + * when coreutils PRNGD is used and then restores the previous mode + * after establishing the socket. This is not required on x86 where hardware + * randomization should be used instead of EGD available as of OpenSSL 3.0. + * Use --with-rand-seed=rdcpu when configuring x86 with 3.0 and above. + * + * Needs review: + * + * The better long-term solution is to either run two EGD's each in one of + * the two modes or revise the EGD code to listen on two different sockets + * (each in one of the two modes) or use the hardware randomizer. + */ +_variable +int hpns_socket(int family, + int type, + int protocol, + char* transport) +{ + int socket_rc; + char current_transport[20]; + +# define AF_UNIX_PORTABILITY "$ZAFN2" +# define AF_UNIX_COMPATIBILITY "$ZPLS" + + if (!_arg_present(transport) || transport == NULL || transport[0] == '\0') + return socket(family, type, protocol); + + socket_transport_name_get(AF_UNIX, current_transport, 20); + + if (strcmp(current_transport,transport) == 0) + return socket(family, type, protocol); + + /* set the requested socket transport */ + if (socket_transport_name_set(AF_UNIX, transport)) + return -1; + + socket_rc = socket(family,type,protocol); + + /* set mode back to what it was */ + if (socket_transport_name_set(AF_UNIX, current_transport)) + return -1; + + return socket_rc; +} + +/*#define socket(a,b,c,...) hpns_socket(a,b,c,__VA_ARGS__) */ + +static int hpns_connect_attempt = 0; + +# endif /* defined(OPENSSL_SYS_HPNS) */ + int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) { @@ -74,7 +123,11 @@ int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) return -1; strcpy(addr.sun_path, path); i = offsetof(struct sockaddr_un, sun_path) + strlen(path); +#if defined(OPENSSL_SYS_TANDEM) + fd = hpns_socket(AF_UNIX, SOCK_STREAM, 0, AF_UNIX_COMPATIBILITY); +#else fd = socket(AF_UNIX, SOCK_STREAM, 0); +#endif if (fd == -1 || (fp = fdopen(fd, "r+")) == NULL) return -1; setbuf(fp, NULL); @@ -83,26 +136,38 @@ int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) for ( ; ; ) { if (connect(fd, (struct sockaddr *)&addr, i) == 0) break; -# ifdef EISCONN +# ifdef EISCONN if (errno == EISCONN) break; -# endif +# endif switch (errno) { -# ifdef EINTR +# ifdef EINTR case EINTR: -# endif -# ifdef EAGAIN +# endif +# ifdef EAGAIN case EAGAIN: -# endif -# ifdef EINPROGRESS +# endif +# ifdef EINPROGRESS case EINPROGRESS: -# endif -# ifdef EALREADY +# endif +# ifdef EALREADY case EALREADY: -# endif +# endif /* No error, try again */ break; default: +# if defined(OPENSSL_SYS_TANDEM) + if (hpns_connect_attempt == 0) { + /* try the other kind of AF_UNIX socket */ + close(fd); + fd = hpns_socket(AF_UNIX, SOCK_STREAM, 0, AF_UNIX_PORTABILITY); + if (fd == -1) + return -1; + ++hpns_connect_attempt; + break; /* try the connect again */ + } +# endif + ret = -1; goto err; } @@ -153,6 +218,4 @@ int RAND_egd(const char *path) return RAND_egd_bytes(path, 255); } -# endif - #endif diff --git a/crypto/openssl/crypto/rand/rand_err.c b/crypto/openssl/crypto/rand/rand_err.c index a3ae5f53c295..b9c2bf1760f5 100644 --- a/crypto/openssl/crypto/rand/rand_err.c +++ b/crypto/openssl/crypto/rand/rand_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,52 +10,10 @@ #include #include +#include "crypto/randerr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA RAND_str_functs[] = { - {ERR_PACK(ERR_LIB_RAND, RAND_F_DATA_COLLECT_METHOD, 0), - "data_collect_method"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_BYTES, 0), "drbg_bytes"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_GET_ENTROPY, 0), "drbg_get_entropy"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_SETUP, 0), "drbg_setup"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_GET_ENTROPY, 0), "get_entropy"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_BYTES, 0), "RAND_bytes"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_ENABLE_LOCKING, 0), - "rand_drbg_enable_locking"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GENERATE, 0), - "RAND_DRBG_generate"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GET_ENTROPY, 0), - "rand_drbg_get_entropy"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GET_NONCE, 0), - "rand_drbg_get_nonce"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_INSTANTIATE, 0), - "RAND_DRBG_instantiate"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_NEW, 0), "RAND_DRBG_new"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESEED, 0), "RAND_DRBG_reseed"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESTART, 0), "rand_drbg_restart"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_SET, 0), "RAND_DRBG_set"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_SET_DEFAULTS, 0), - "RAND_DRBG_set_defaults"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_UNINSTANTIATE, 0), - "RAND_DRBG_uninstantiate"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_LOAD_FILE, 0), "RAND_load_file"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ACQUIRE_ENTROPY, 0), - "rand_pool_acquire_entropy"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD, 0), "rand_pool_add"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD_BEGIN, 0), - "rand_pool_add_begin"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD_END, 0), "rand_pool_add_end"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ATTACH, 0), "rand_pool_attach"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_BYTES_NEEDED, 0), - "rand_pool_bytes_needed"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_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_PSEUDO_BYTES, 0), "RAND_pseudo_bytes"}, - {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_WRITE_FILE, 0), "RAND_write_file"}, - {0, NULL} -}; - static const ERR_STRING_DATA RAND_str_reasons[] = { {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ADDITIONAL_INPUT_TOO_LONG), "additional input too long"}, @@ -90,6 +48,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = { "Function not implemented"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_FWRITE_ERROR), "Error writing file"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_GENERATE_ERROR), "generate error"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_INSUFFICIENT_DRBG_STRENGTH), + "insufficient drbg strength"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_INTERNAL_ERROR), "internal error"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_IN_ERROR_STATE), "in error state"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NOT_A_REGULAR_FILE), @@ -118,6 +78,16 @@ static const ERR_STRING_DATA RAND_str_reasons[] = { "too little nonce requested"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_TOO_MUCH_NONCE_REQUESTED), "too much nonce requested"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_CREATE_DRBG), + "unable to create drbg"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_FETCH_DRBG), + "unable to fetch drbg"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER), + "unable to get parent reseed prop counter"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_STRENGTH), + "unable to get parent strength"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_LOCK_PARENT), + "unable to lock parent"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_FLAGS), "unsupported drbg flags"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_TYPE), @@ -127,13 +97,11 @@ static const ERR_STRING_DATA RAND_str_reasons[] = { #endif -int ERR_load_RAND_strings(void) +int ossl_err_load_RAND_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) { - ERR_load_strings_const(RAND_str_functs); + if (ERR_reason_error_string(RAND_str_reasons[0].error) == NULL) ERR_load_strings_const(RAND_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/rand/rand_lib.c b/crypto/openssl/crypto/rand/rand_lib.c index 3fdb56cb0024..f341d915db76 100644 --- a/crypto/openssl/crypto/rand/rand_lib.c +++ b/crypto/openssl/crypto/rand/rand_lib.c @@ -1,348 +1,83 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include -#include -#include "internal/cryptlib.h" +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include #include -#include "crypto/rand.h" -#include +#include +#include "internal/cryptlib.h" #include "internal/thread_once.h" +#include "crypto/rand.h" +#include "crypto/cryptlib.h" #include "rand_local.h" -#include "e_os.h" -#ifndef OPENSSL_NO_ENGINE +#ifndef FIPS_MODULE +# include +# include +# include +# include +# include +# include +# include "crypto/rand_pool.h" +# include "prov/seeding.h" +# include "e_os.h" + +# ifndef OPENSSL_NO_ENGINE /* non-NULL if default_RAND_meth is ENGINE-provided */ static ENGINE *funct_ref; static CRYPTO_RWLOCK *rand_engine_lock; -#endif +# endif +# ifndef OPENSSL_NO_DEPRECATED_3_0 static CRYPTO_RWLOCK *rand_meth_lock; static const RAND_METHOD *default_RAND_meth; +# endif static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT; -static CRYPTO_RWLOCK *rand_nonce_lock; -static int rand_nonce_count; - static int rand_inited = 0; -#ifdef OPENSSL_RAND_SEED_RDTSC -/* - * IMPORTANT NOTE: It is not currently possible to use this code - * because we are not sure about the amount of randomness it provides. - * Some SP900 tests have been run, but there is internal skepticism. - * So for now this code is not used. - */ -# error "RDTSC enabled? Should not be possible!" - -/* - * Acquire entropy from high-speed clock - * - * Since we get some randomness from the low-order bits of the - * high-speed clock, it can help. - * - * Returns the total entropy count, if it exceeds the requested - * entropy count. Otherwise, returns an entropy count of 0. - */ -size_t rand_acquire_entropy_from_tsc(RAND_POOL *pool) -{ - unsigned char c; - int i; - - if ((OPENSSL_ia32cap_P[0] & (1 << 4)) != 0) { - for (i = 0; i < TSC_READ_COUNT; i++) { - c = (unsigned char)(OPENSSL_rdtsc() & 0xFF); - rand_pool_add(pool, &c, 1, 4); - } - } - return rand_pool_entropy_available(pool); -} -#endif - -#ifdef OPENSSL_RAND_SEED_RDCPU -size_t OPENSSL_ia32_rdseed_bytes(unsigned char *buf, size_t len); -size_t OPENSSL_ia32_rdrand_bytes(unsigned char *buf, size_t len); - -extern unsigned int OPENSSL_ia32cap_P[]; - -/* - * Acquire entropy using Intel-specific cpu instructions - * - * Uses the RDSEED instruction if available, otherwise uses - * RDRAND if available. - * - * For the differences between RDSEED and RDRAND, and why RDSEED - * is the preferred choice, see https://goo.gl/oK3KcN - * - * Returns the total entropy count, if it exceeds the requested - * entropy count. Otherwise, returns an entropy count of 0. - */ -size_t rand_acquire_entropy_from_cpu(RAND_POOL *pool) -{ - size_t bytes_needed; - unsigned char *buffer; - - bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); - if (bytes_needed > 0) { - buffer = rand_pool_add_begin(pool, bytes_needed); - - if (buffer != NULL) { - /* Whichever comes first, use RDSEED, RDRAND or nothing */ - if ((OPENSSL_ia32cap_P[2] & (1 << 18)) != 0) { - if (OPENSSL_ia32_rdseed_bytes(buffer, bytes_needed) - == bytes_needed) { - rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed); - } - } else if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) { - if (OPENSSL_ia32_rdrand_bytes(buffer, bytes_needed) - == bytes_needed) { - rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed); - } - } else { - rand_pool_add_end(pool, 0, 0); - } - } - } - - return rand_pool_entropy_available(pool); -} -#endif - - -/* - * Implements the get_entropy() callback (see RAND_DRBG_set_callbacks()) - * - * If the DRBG has a parent, then the required amount of entropy input - * is fetched using the parent's RAND_DRBG_generate(). - * - * Otherwise, the entropy is polled from the system entropy sources - * using rand_pool_acquire_entropy(). - * - * If a random pool has been added to the DRBG using RAND_add(), then - * its entropy will be used up first. - */ -size_t rand_drbg_get_entropy(RAND_DRBG *drbg, - unsigned char **pout, - int entropy, size_t min_len, size_t max_len, - int prediction_resistance) -{ - size_t ret = 0; - size_t entropy_available = 0; - RAND_POOL *pool; - - if (drbg->parent != NULL && drbg->strength > drbg->parent->strength) { - /* - * We currently don't support the algorithm from NIST SP 800-90C - * 10.1.2 to use a weaker DRBG as source - */ - RANDerr(RAND_F_RAND_DRBG_GET_ENTROPY, RAND_R_PARENT_STRENGTH_TOO_WEAK); - return 0; - } - - if (drbg->seed_pool != NULL) { - pool = drbg->seed_pool; - pool->entropy_requested = entropy; - } else { - pool = rand_pool_new(entropy, drbg->secure, min_len, max_len); - if (pool == NULL) - return 0; - } - - if (drbg->parent != NULL) { - size_t bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); - unsigned char *buffer = rand_pool_add_begin(pool, bytes_needed); - - if (buffer != NULL) { - size_t bytes = 0; - - /* - * 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.) - */ - rand_drbg_lock(drbg->parent); - if (RAND_DRBG_generate(drbg->parent, - buffer, bytes_needed, - prediction_resistance, - (unsigned char *)&drbg, sizeof(drbg)) != 0) { - bytes = bytes_needed; - if (drbg->enable_reseed_propagation) - tsan_store(&drbg->reseed_counter, - tsan_load(&drbg->parent->reseed_counter)); - } - rand_drbg_unlock(drbg->parent); - - rand_pool_add_end(pool, bytes, 8 * bytes); - entropy_available = rand_pool_entropy_available(pool); - } - - } else { - if (prediction_resistance) { - /* - * We don't have any entropy sources that comply with the NIST - * standard to provide prediction resistance (see NIST SP 800-90C, - * Section 5.4). - */ - RANDerr(RAND_F_RAND_DRBG_GET_ENTROPY, - RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED); - goto err; - } - - /* Get entropy by polling system entropy sources. */ - entropy_available = rand_pool_acquire_entropy(pool); - } - - if (entropy_available > 0) { - ret = rand_pool_length(pool); - *pout = rand_pool_detach(pool); - } - - err: - if (drbg->seed_pool == NULL) - rand_pool_free(pool); - return ret; -} - -/* - * Implements the cleanup_entropy() callback (see RAND_DRBG_set_callbacks()) - * - */ -void rand_drbg_cleanup_entropy(RAND_DRBG *drbg, - unsigned char *out, size_t outlen) -{ - if (drbg->seed_pool == NULL) { - if (drbg->secure) - OPENSSL_secure_clear_free(out, outlen); - else - OPENSSL_clear_free(out, outlen); - } -} - - -/* - * Implements the get_nonce() callback (see RAND_DRBG_set_callbacks()) - * - */ -size_t rand_drbg_get_nonce(RAND_DRBG *drbg, - unsigned char **pout, - int entropy, size_t min_len, size_t max_len) -{ - size_t ret = 0; - RAND_POOL *pool; - - struct { - void * instance; - int count; - } data; - - memset(&data, 0, sizeof(data)); - pool = rand_pool_new(0, 0, min_len, max_len); - if (pool == NULL) - return 0; - - if (rand_pool_add_nonce_data(pool) == 0) - goto err; - - data.instance = drbg; - CRYPTO_atomic_add(&rand_nonce_count, 1, &data.count, rand_nonce_lock); - - if (rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0) == 0) - goto err; - - ret = rand_pool_length(pool); - *pout = rand_pool_detach(pool); - - err: - rand_pool_free(pool); - - return ret; -} - -/* - * Implements the cleanup_nonce() callback (see RAND_DRBG_set_callbacks()) - * - */ -void rand_drbg_cleanup_nonce(RAND_DRBG *drbg, - unsigned char *out, size_t outlen) -{ - OPENSSL_clear_free(out, outlen); -} - -/* - * Generate additional data that can be used for the drbg. The data does - * not need to contain entropy, but it's useful if it contains at least - * some bits that are unpredictable. - * - * Returns 0 on failure. - * - * On success it allocates a buffer at |*pout| and returns the length of - * the data. The buffer should get freed using OPENSSL_secure_clear_free(). - */ -size_t rand_drbg_get_additional_data(RAND_POOL *pool, unsigned char **pout) -{ - size_t ret = 0; - - if (rand_pool_add_additional_data(pool) == 0) - goto err; - - ret = rand_pool_length(pool); - *pout = rand_pool_detach(pool); - - err: - return ret; -} - -void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out) -{ - rand_pool_reattach(pool, out); -} - DEFINE_RUN_ONCE_STATIC(do_rand_init) { -#ifndef OPENSSL_NO_ENGINE +# ifndef OPENSSL_NO_ENGINE rand_engine_lock = CRYPTO_THREAD_lock_new(); if (rand_engine_lock == NULL) return 0; -#endif +# endif +# ifndef OPENSSL_NO_DEPRECATED_3_0 rand_meth_lock = CRYPTO_THREAD_lock_new(); if (rand_meth_lock == NULL) - goto err1; - - rand_nonce_lock = CRYPTO_THREAD_lock_new(); - if (rand_nonce_lock == NULL) - goto err2; + goto err; +# endif - if (!rand_pool_init()) - goto err3; + if (!ossl_rand_pool_init()) + goto err; rand_inited = 1; return 1; -err3: - CRYPTO_THREAD_lock_free(rand_nonce_lock); - rand_nonce_lock = NULL; -err2: + err: +# ifndef OPENSSL_NO_DEPRECATED_3_0 CRYPTO_THREAD_lock_free(rand_meth_lock); rand_meth_lock = NULL; -err1: -#ifndef OPENSSL_NO_ENGINE +# endif +# ifndef OPENSSL_NO_ENGINE CRYPTO_THREAD_lock_free(rand_engine_lock); rand_engine_lock = NULL; -#endif +# endif return 0; } -void rand_cleanup_int(void) +void ossl_rand_cleanup_int(void) { +# ifndef OPENSSL_NO_DEPRECATED_3_0 const RAND_METHOD *meth = default_RAND_meth; if (!rand_inited) @@ -351,26 +86,29 @@ void rand_cleanup_int(void) if (meth != NULL && meth->cleanup != NULL) meth->cleanup(); RAND_set_rand_method(NULL); - rand_pool_cleanup(); -#ifndef OPENSSL_NO_ENGINE +# endif + ossl_rand_pool_cleanup(); +# ifndef OPENSSL_NO_ENGINE CRYPTO_THREAD_lock_free(rand_engine_lock); rand_engine_lock = NULL; -#endif +# endif +# ifndef OPENSSL_NO_DEPRECATED_3_0 CRYPTO_THREAD_lock_free(rand_meth_lock); rand_meth_lock = NULL; - CRYPTO_THREAD_lock_free(rand_nonce_lock); - rand_nonce_lock = NULL; +# endif + ossl_release_default_drbg_ctx(); rand_inited = 0; } /* * RAND_close_seed_files() ensures that any seed file descriptors are - * closed after use. + * closed after use. This only applies to libcrypto/default provider, + * it does not apply to other providers. */ void RAND_keep_random_devices_open(int keep) { if (RUN_ONCE(&rand_init, do_rand_init)) - rand_pool_keep_random_devices_open(keep); + ossl_rand_pool_keep_random_devices_open(keep); } /* @@ -382,588 +120,725 @@ void RAND_keep_random_devices_open(int keep) */ int RAND_poll(void) { - int ret = 0; - - RAND_POOL *pool = NULL; - +# ifndef OPENSSL_NO_DEPRECATED_3_0 const RAND_METHOD *meth = RAND_get_rand_method(); + int ret = meth == RAND_OpenSSL(); if (meth == NULL) return 0; - if (meth == RAND_OpenSSL()) { - /* fill random pool and seed the master DRBG */ - RAND_DRBG *drbg = RAND_DRBG_get0_master(); - - if (drbg == NULL) - return 0; - - rand_drbg_lock(drbg); - ret = rand_drbg_restart(drbg, NULL, 0, 0); - rand_drbg_unlock(drbg); - - return ret; - - } else { + if (!ret) { /* fill random pool and seed the current legacy RNG */ - pool = rand_pool_new(RAND_DRBG_STRENGTH, 1, - (RAND_DRBG_STRENGTH + 7) / 8, - RAND_POOL_MAX_LENGTH); + RAND_POOL *pool = ossl_rand_pool_new(RAND_DRBG_STRENGTH, 1, + (RAND_DRBG_STRENGTH + 7) / 8, + RAND_POOL_MAX_LENGTH); + if (pool == NULL) return 0; - if (rand_pool_acquire_entropy(pool) == 0) + if (ossl_pool_acquire_entropy(pool) == 0) goto err; if (meth->add == NULL - || meth->add(rand_pool_buffer(pool), - rand_pool_length(pool), - (rand_pool_entropy(pool) / 8.0)) == 0) + || meth->add(ossl_rand_pool_buffer(pool), + ossl_rand_pool_length(pool), + (ossl_rand_pool_entropy(pool) / 8.0)) == 0) goto err; ret = 1; + err: + ossl_rand_pool_free(pool); } - -err: - rand_pool_free(pool); return ret; +# else + static const char salt[] = "polling"; + + RAND_seed(salt, sizeof(salt)); + return 1; +# endif } -/* - * Allocate memory and initialize a new random pool - */ +# ifndef OPENSSL_NO_DEPRECATED_3_0 +static int rand_set_rand_method_internal(const RAND_METHOD *meth, + ossl_unused ENGINE *e) +{ + if (!RUN_ONCE(&rand_init, do_rand_init)) + return 0; + + if (!CRYPTO_THREAD_write_lock(rand_meth_lock)) + return 0; +# ifndef OPENSSL_NO_ENGINE + ENGINE_finish(funct_ref); + funct_ref = e; +# endif + default_RAND_meth = meth; + CRYPTO_THREAD_unlock(rand_meth_lock); + return 1; +} -RAND_POOL *rand_pool_new(int entropy_requested, int secure, - size_t min_len, size_t max_len) +int RAND_set_rand_method(const RAND_METHOD *meth) +{ + return rand_set_rand_method_internal(meth, NULL); +} + +const RAND_METHOD *RAND_get_rand_method(void) { - RAND_POOL *pool; - size_t min_alloc_size = RAND_POOL_MIN_ALLOCATION(secure); + const RAND_METHOD *tmp_meth = NULL; if (!RUN_ONCE(&rand_init, do_rand_init)) return NULL; - pool = OPENSSL_zalloc(sizeof(*pool)); - if (pool == NULL) { - RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_THREAD_write_lock(rand_meth_lock)) return NULL; + if (default_RAND_meth == NULL) { +# ifndef OPENSSL_NO_ENGINE + ENGINE *e; + + /* If we have an engine that can do RAND, use it. */ + if ((e = ENGINE_get_default_RAND()) != NULL + && (tmp_meth = ENGINE_get_RAND(e)) != NULL) { + funct_ref = e; + default_RAND_meth = tmp_meth; + } else { + ENGINE_finish(e); + default_RAND_meth = &ossl_rand_meth; + } +# else + default_RAND_meth = &ossl_rand_meth; +# endif } + tmp_meth = default_RAND_meth; + CRYPTO_THREAD_unlock(rand_meth_lock); + return tmp_meth; +} - 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 !defined(OPENSSL_NO_ENGINE) +int RAND_set_rand_engine(ENGINE *engine) +{ + const RAND_METHOD *tmp_meth = NULL; - if (secure) - pool->buffer = OPENSSL_secure_zalloc(pool->alloc_len); - else - pool->buffer = OPENSSL_zalloc(pool->alloc_len); + if (!RUN_ONCE(&rand_init, do_rand_init)) + return 0; - if (pool->buffer == NULL) { - RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE); - goto err; + if (engine != NULL) { + if (!ENGINE_init(engine)) + return 0; + tmp_meth = ENGINE_get_RAND(engine); + if (tmp_meth == NULL) { + ENGINE_finish(engine); + return 0; + } + } + if (!CRYPTO_THREAD_write_lock(rand_engine_lock)) { + ENGINE_finish(engine); + return 0; } - pool->entropy_requested = entropy_requested; - pool->secure = secure; - - return pool; - -err: - OPENSSL_free(pool); - return NULL; + /* This function releases any prior ENGINE so call it first */ + rand_set_rand_method_internal(tmp_meth, engine); + CRYPTO_THREAD_unlock(rand_engine_lock); + return 1; } +# endif +# endif /* OPENSSL_NO_DEPRECATED_3_0 */ -/* - * Attach new random pool to the given buffer - * - * This function is intended to be used only for feeding random data - * provided by RAND_add() and RAND_seed() into the DRBG. - */ -RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len, - size_t entropy) +void RAND_seed(const void *buf, int num) { - RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool)); + EVP_RAND_CTX *drbg; +# ifndef OPENSSL_NO_DEPRECATED_3_0 + const RAND_METHOD *meth = RAND_get_rand_method(); - if (pool == NULL) { - RANDerr(RAND_F_RAND_POOL_ATTACH, ERR_R_MALLOC_FAILURE); - return NULL; + if (meth != NULL && meth->seed != NULL) { + meth->seed(buf, num); + return; } +# endif - /* - * The const needs to be cast away, but attached buffers will not be - * modified (in contrary to allocated buffers which are zeroed and - * freed in the end). - */ - pool->buffer = (unsigned char *) buffer; - pool->len = len; + drbg = RAND_get0_primary(NULL); + if (drbg != NULL && num > 0) + EVP_RAND_reseed(drbg, 0, NULL, 0, buf, num); +} + +void RAND_add(const void *buf, int num, double randomness) +{ + EVP_RAND_CTX *drbg; +# ifndef OPENSSL_NO_DEPRECATED_3_0 + const RAND_METHOD *meth = RAND_get_rand_method(); - pool->attached = 1; + if (meth != NULL && meth->add != NULL) { + meth->add(buf, num, randomness); + return; + } +# endif + drbg = RAND_get0_primary(NULL); + if (drbg != NULL && num > 0) + EVP_RAND_reseed(drbg, 0, NULL, 0, buf, num); +} - pool->min_len = pool->max_len = pool->alloc_len = pool->len; - pool->entropy = entropy; +# if !defined(OPENSSL_NO_DEPRECATED_1_1_0) +int RAND_pseudo_bytes(unsigned char *buf, int num) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); - return pool; + if (meth != NULL && meth->pseudorand != NULL) + return meth->pseudorand(buf, num); + ERR_raise(ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED); + return -1; } +# endif -/* - * Free |pool|, securely erasing its buffer. - */ -void rand_pool_free(RAND_POOL *pool) +int RAND_status(void) { - if (pool == NULL) - return; + EVP_RAND_CTX *rand; +# ifndef OPENSSL_NO_DEPRECATED_3_0 + const RAND_METHOD *meth = RAND_get_rand_method(); - /* - * Although it would be advisable from a cryptographical viewpoint, - * we are not allowed to clear attached buffers, since they are passed - * to rand_pool_attach() as `const unsigned char*`. - * (see corresponding comment in rand_pool_attach()). - */ - if (!pool->attached) { - if (pool->secure) - OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len); - else - OPENSSL_clear_free(pool->buffer, pool->alloc_len); - } + if (meth != NULL && meth != RAND_OpenSSL()) + return meth->status != NULL ? meth->status() : 0; +# endif - OPENSSL_free(pool); + if ((rand = RAND_get0_primary(NULL)) == NULL) + return 0; + return EVP_RAND_get_state(rand) == EVP_RAND_STATE_READY; } +# else /* !FIPS_MODULE */ -/* - * Return the |pool|'s buffer to the caller (readonly). - */ -const unsigned char *rand_pool_buffer(RAND_POOL *pool) +# ifndef OPENSSL_NO_DEPRECATED_3_0 +const RAND_METHOD *RAND_get_rand_method(void) { - return pool->buffer; + return NULL; } +# endif +#endif /* !FIPS_MODULE */ /* - * Return the |pool|'s entropy to the caller. + * This function is not part of RAND_METHOD, so if we're not using + * the default method, then just call RAND_bytes(). Otherwise make + * sure we're instantiated and use the private DRBG. */ -size_t rand_pool_entropy(RAND_POOL *pool) +int RAND_priv_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num, + unsigned int strength) { - return pool->entropy; + EVP_RAND_CTX *rand; +#if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE) + const RAND_METHOD *meth = RAND_get_rand_method(); + + if (meth != NULL && meth != RAND_OpenSSL()) { + if (meth->bytes != NULL) + return meth->bytes(buf, num); + ERR_raise(ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED); + return -1; + } +#endif + + rand = RAND_get0_private(ctx); + if (rand != NULL) + return EVP_RAND_generate(rand, buf, num, strength, 0, NULL, 0); + + return 0; } -/* - * Return the |pool|'s buffer length to the caller. - */ -size_t rand_pool_length(RAND_POOL *pool) +int RAND_priv_bytes(unsigned char *buf, int num) { - return pool->len; + if (num < 0) + return 0; + return RAND_priv_bytes_ex(NULL, buf, (size_t)num, 0); } -/* - * Detach the |pool| buffer and return it to the caller. - * It's the responsibility of the caller to free the buffer - * using OPENSSL_secure_clear_free() or to re-attach it - * again to the pool using rand_pool_reattach(). - */ -unsigned char *rand_pool_detach(RAND_POOL *pool) +int RAND_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num, + unsigned int strength) { - unsigned char *ret = pool->buffer; - pool->buffer = NULL; - pool->entropy = 0; - return ret; + EVP_RAND_CTX *rand; +#if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE) + const RAND_METHOD *meth = RAND_get_rand_method(); + + if (meth != NULL && meth != RAND_OpenSSL()) { + if (meth->bytes != NULL) + return meth->bytes(buf, num); + ERR_raise(ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED); + return -1; + } +#endif + + rand = RAND_get0_public(ctx); + if (rand != NULL) + return EVP_RAND_generate(rand, buf, num, strength, 0, NULL, 0); + + return 0; } -/* - * Re-attach the |pool| buffer. It is only allowed to pass - * the |buffer| which was previously detached from the same pool. - */ -void rand_pool_reattach(RAND_POOL *pool, unsigned char *buffer) +int RAND_bytes(unsigned char *buf, int num) { - pool->buffer = buffer; - OPENSSL_cleanse(pool->buffer, pool->len); - pool->len = 0; + if (num < 0) + return 0; + return RAND_bytes_ex(NULL, buf, (size_t)num, 0); } -/* - * If |entropy_factor| bits contain 1 bit of entropy, how many bytes does one - * need to obtain at least |bits| bits of entropy? - */ -#define ENTROPY_TO_BYTES(bits, entropy_factor) \ - (((bits) * (entropy_factor) + 7) / 8) +typedef struct rand_global_st { + /* + * The three shared DRBG instances + * + * There are three shared DRBG instances: , , and + * . The and DRBGs are secondary ones. + * These are used for non-secret (e.g. nonces) and secret + * (e.g. private keys) data respectively. + */ + CRYPTO_RWLOCK *lock; + + EVP_RAND_CTX *seed; + + /* + * The DRBG + * + * Not used directly by the application, only for reseeding the two other + * DRBGs. It reseeds itself by pulling either randomness from os entropy + * sources or by consuming randomness which was added by RAND_add(). + * + * The DRBG is a global instance which is accessed concurrently by + * all threads. The necessary locking is managed automatically by its child + * DRBG instances during reseeding. + */ + EVP_RAND_CTX *primary; + + /* + * The DRBG + * + * Used by default for generating random bytes using RAND_bytes(). + * + * The secondary DRBG is thread-local, i.e., there is one instance + * per thread. + */ + CRYPTO_THREAD_LOCAL public; + + /* + * The DRBG + * + * Used by default for generating private keys using RAND_priv_bytes() + * + * The secondary DRBG is thread-local, i.e., there is one + * instance per thread. + */ + CRYPTO_THREAD_LOCAL private; + /* Which RNG is being used by default and it's configuration settings */ + char *rng_name; + char *rng_cipher; + char *rng_digest; + char *rng_propq; + + /* Allow the randomness source to be changed */ + char *seed_name; + char *seed_propq; +} RAND_GLOBAL; /* - * Checks whether the |pool|'s entropy is available to the caller. - * This is the case when entropy count and buffer length are high enough. - * Returns - * - * |entropy| if the entropy count and buffer size is large enough - * 0 otherwise + * Initialize the OSSL_LIB_CTX global DRBGs on first use. + * Returns the allocated global data on success or NULL on failure. */ -size_t rand_pool_entropy_available(RAND_POOL *pool) +static void *rand_ossl_ctx_new(OSSL_LIB_CTX *libctx) { - if (pool->entropy < pool->entropy_requested) - return 0; + RAND_GLOBAL *dgbl = OPENSSL_zalloc(sizeof(*dgbl)); - if (pool->len < pool->min_len) - return 0; + if (dgbl == NULL) + return NULL; - return pool->entropy; -} +#ifndef FIPS_MODULE + /* + * We need to ensure that base libcrypto thread handling has been + * initialised. + */ + OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL); +#endif -/* - * Returns the (remaining) amount of entropy needed to fill - * the random pool. - */ + dgbl->lock = CRYPTO_THREAD_lock_new(); + if (dgbl->lock == NULL) + goto err1; -size_t rand_pool_entropy_needed(RAND_POOL *pool) -{ - if (pool->entropy < pool->entropy_requested) - return pool->entropy_requested - pool->entropy; + if (!CRYPTO_THREAD_init_local(&dgbl->private, NULL)) + goto err1; - return 0; + if (!CRYPTO_THREAD_init_local(&dgbl->public, NULL)) + goto err2; + + return dgbl; + + err2: + CRYPTO_THREAD_cleanup_local(&dgbl->private); + err1: + CRYPTO_THREAD_lock_free(dgbl->lock); + OPENSSL_free(dgbl); + return NULL; } -/* Increase the allocation size -- not usable for an attached pool */ -static int rand_pool_grow(RAND_POOL *pool, size_t len) +void ossl_rand_ctx_free(void *vdgbl) { - if (len > pool->alloc_len - pool->len) { - unsigned char *p; - const size_t limit = pool->max_len / 2; - size_t newlen = pool->alloc_len; + RAND_GLOBAL *dgbl = vdgbl; - if (pool->attached || len > pool->max_len - pool->len) { - RANDerr(RAND_F_RAND_POOL_GROW, ERR_R_INTERNAL_ERROR); - return 0; - } + if (dgbl == NULL) + return; - do - newlen = newlen < limit ? newlen * 2 : pool->max_len; - while (len > newlen - pool->len); + CRYPTO_THREAD_lock_free(dgbl->lock); + CRYPTO_THREAD_cleanup_local(&dgbl->private); + CRYPTO_THREAD_cleanup_local(&dgbl->public); + EVP_RAND_CTX_free(dgbl->primary); + EVP_RAND_CTX_free(dgbl->seed); + OPENSSL_free(dgbl->rng_name); + OPENSSL_free(dgbl->rng_cipher); + OPENSSL_free(dgbl->rng_digest); + OPENSSL_free(dgbl->rng_propq); + OPENSSL_free(dgbl->seed_name); + OPENSSL_free(dgbl->seed_propq); - 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; + OPENSSL_free(dgbl); } -/* - * Returns the number of bytes needed to fill the pool, assuming - * the input has 1 / |entropy_factor| entropy bits per data bit. - * In case of an error, 0 is returned. - */ +static const OSSL_LIB_CTX_METHOD rand_drbg_ossl_ctx_method = { + OSSL_LIB_CTX_METHOD_PRIORITY_2, + rand_ossl_ctx_new, + ossl_rand_ctx_free, +}; -size_t rand_pool_bytes_needed(RAND_POOL *pool, unsigned int entropy_factor) +static RAND_GLOBAL *rand_get_global(OSSL_LIB_CTX *libctx) { - size_t bytes_needed; - size_t entropy_needed = rand_pool_entropy_needed(pool); - - if (entropy_factor < 1) { - RANDerr(RAND_F_RAND_POOL_BYTES_NEEDED, RAND_R_ARGUMENT_OUT_OF_RANGE); - return 0; - } - - bytes_needed = ENTROPY_TO_BYTES(entropy_needed, entropy_factor); + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DRBG_INDEX, + &rand_drbg_ossl_ctx_method); +} - if (bytes_needed > pool->max_len - pool->len) { - /* not enough space left */ - RANDerr(RAND_F_RAND_POOL_BYTES_NEEDED, RAND_R_RANDOM_POOL_OVERFLOW); - return 0; - } +static void rand_delete_thread_state(void *arg) +{ + OSSL_LIB_CTX *ctx = arg; + RAND_GLOBAL *dgbl = rand_get_global(ctx); + EVP_RAND_CTX *rand; - if (pool->len < pool->min_len && - bytes_needed < pool->min_len - pool->len) - /* to meet the min_len requirement */ - bytes_needed = pool->min_len - pool->len; + if (dgbl == NULL) + return; - /* - * 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; - } + rand = CRYPTO_THREAD_get_local(&dgbl->public); + CRYPTO_THREAD_set_local(&dgbl->public, NULL); + EVP_RAND_CTX_free(rand); - return bytes_needed; + rand = CRYPTO_THREAD_get_local(&dgbl->private); + CRYPTO_THREAD_set_local(&dgbl->private, NULL); + EVP_RAND_CTX_free(rand); } -/* Returns the remaining number of bytes available */ -size_t rand_pool_bytes_remaining(RAND_POOL *pool) +#ifndef FIPS_MODULE +static EVP_RAND_CTX *rand_new_seed(OSSL_LIB_CTX *libctx) { - return pool->max_len - pool->len; -} + EVP_RAND *rand; + RAND_GLOBAL *dgbl = rand_get_global(libctx); + EVP_RAND_CTX *ctx; + char *name; -/* - * Add random bytes to the random pool. - * - * It is expected that the |buffer| contains |len| bytes of - * random input which contains at least |entropy| bits of - * randomness. - * - * Returns 1 if the added amount is adequate, otherwise 0 - */ -int rand_pool_add(RAND_POOL *pool, - const unsigned char *buffer, size_t len, size_t entropy) -{ - if (len > pool->max_len - pool->len) { - RANDerr(RAND_F_RAND_POOL_ADD, RAND_R_ENTROPY_INPUT_TOO_LONG); - return 0; + if (dgbl == NULL) + return NULL; + name = dgbl->seed_name != NULL ? dgbl->seed_name : "SEED-SRC"; + rand = EVP_RAND_fetch(libctx, name, dgbl->seed_propq); + if (rand == NULL) { + ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG); + return NULL; } - - if (pool->buffer == NULL) { - RANDerr(RAND_F_RAND_POOL_ADD, ERR_R_INTERNAL_ERROR); - return 0; + ctx = EVP_RAND_CTX_new(rand, NULL); + EVP_RAND_free(rand); + if (ctx == NULL) { + ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG); + return NULL; } - - 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; + if (!EVP_RAND_instantiate(ctx, 0, 0, NULL, 0, NULL)) { + ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG); + EVP_RAND_CTX_free(ctx); + return NULL; } - - return 1; + return ctx; } +#endif -/* - * Start to add random bytes to the random pool in-place. - * - * Reserves the next |len| bytes for adding random bytes in-place - * and returns a pointer to the buffer. - * The caller is allowed to copy up to |len| bytes into the buffer. - * If |len| == 0 this is considered a no-op and a NULL pointer - * is returned without producing an error message. - * - * After updating the buffer, rand_pool_add_end() needs to be called - * to finish the update operation (see next comment). - */ -unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len) +static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent, + unsigned int reseed_interval, + time_t reseed_time_interval) { - if (len == 0) - return NULL; + EVP_RAND *rand; + RAND_GLOBAL *dgbl = rand_get_global(libctx); + EVP_RAND_CTX *ctx; + OSSL_PARAM params[7], *p = params; + char *name, *cipher; - if (len > pool->max_len - pool->len) { - RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, RAND_R_RANDOM_POOL_OVERFLOW); + if (dgbl == NULL) + return NULL; + name = dgbl->rng_name != NULL ? dgbl->rng_name : "CTR-DRBG"; + rand = EVP_RAND_fetch(libctx, name, dgbl->rng_propq); + if (rand == NULL) { + ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG); return NULL; } - - if (pool->buffer == NULL) { - RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, ERR_R_INTERNAL_ERROR); + ctx = EVP_RAND_CTX_new(rand, parent); + EVP_RAND_free(rand); + if (ctx == NULL) { + ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG); 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. + * Rather than trying to decode the DRBG settings, just pass them through + * and rely on the other end to ignore those it doesn't care about. */ - if (!rand_pool_grow(pool, len)) + cipher = dgbl->rng_cipher != NULL ? dgbl->rng_cipher : "AES-256-CTR"; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER, + cipher, 0); + if (dgbl->rng_digest != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST, + dgbl->rng_digest, 0); + if (dgbl->rng_propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, + dgbl->rng_propq, 0); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_MAC, "HMAC", 0); + *p++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, + &reseed_interval); + *p++ = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, + &reseed_time_interval); + *p = OSSL_PARAM_construct_end(); + if (!EVP_RAND_instantiate(ctx, 0, 0, NULL, 0, params)) { + ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG); + EVP_RAND_CTX_free(ctx); return NULL; - - return pool->buffer + pool->len; + } + return ctx; } /* - * Finish to add random bytes to the random pool in-place. + * Get the primary random generator. + * Returns pointer to its EVP_RAND_CTX on success, NULL on failure. * - * Finishes an in-place update of the random pool started by - * rand_pool_add_begin() (see previous comment). - * It is expected that |len| bytes of random input have been added - * to the buffer which contain at least |entropy| bits of randomness. - * It is allowed to add less bytes than originally reserved. */ -int rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy) +EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx) { - if (len > pool->alloc_len - pool->len) { - RANDerr(RAND_F_RAND_POOL_ADD_END, RAND_R_RANDOM_POOL_OVERFLOW); - return 0; - } + RAND_GLOBAL *dgbl = rand_get_global(ctx); + EVP_RAND_CTX *ret; - if (len > 0) { - pool->len += len; - pool->entropy += entropy; - } - - return 1; -} + if (dgbl == NULL) + return NULL; -int RAND_set_rand_method(const RAND_METHOD *meth) -{ - if (!RUN_ONCE(&rand_init, do_rand_init)) - return 0; + if (!CRYPTO_THREAD_read_lock(dgbl->lock)) + return NULL; - CRYPTO_THREAD_write_lock(rand_meth_lock); -#ifndef OPENSSL_NO_ENGINE - ENGINE_finish(funct_ref); - funct_ref = NULL; -#endif - default_RAND_meth = meth; - CRYPTO_THREAD_unlock(rand_meth_lock); - return 1; -} + ret = dgbl->primary; + CRYPTO_THREAD_unlock(dgbl->lock); -const RAND_METHOD *RAND_get_rand_method(void) -{ - const RAND_METHOD *tmp_meth = NULL; + if (ret != NULL) + return ret; - if (!RUN_ONCE(&rand_init, do_rand_init)) + if (!CRYPTO_THREAD_write_lock(dgbl->lock)) return NULL; - CRYPTO_THREAD_write_lock(rand_meth_lock); - if (default_RAND_meth == NULL) { -#ifndef OPENSSL_NO_ENGINE - ENGINE *e; + ret = dgbl->primary; + if (ret != NULL) { + CRYPTO_THREAD_unlock(dgbl->lock); + return ret; + } - /* If we have an engine that can do RAND, use it. */ - if ((e = ENGINE_get_default_RAND()) != NULL - && (tmp_meth = ENGINE_get_RAND(e)) != NULL) { - funct_ref = e; - default_RAND_meth = tmp_meth; - } else { - ENGINE_finish(e); - default_RAND_meth = &rand_meth; - } -#else - default_RAND_meth = &rand_meth; +#ifndef FIPS_MODULE + if (dgbl->seed == NULL) { + ERR_set_mark(); + dgbl->seed = rand_new_seed(ctx); + ERR_pop_to_mark(); + } #endif + + ret = dgbl->primary = rand_new_drbg(ctx, dgbl->seed, + PRIMARY_RESEED_INTERVAL, + PRIMARY_RESEED_TIME_INTERVAL); + /* + * The primary DRBG may be shared between multiple threads so we must + * enable locking. + */ + if (ret != NULL && !EVP_RAND_enable_locking(ret)) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_LOCKING); + EVP_RAND_CTX_free(ret); + ret = dgbl->primary = NULL; } - tmp_meth = default_RAND_meth; - CRYPTO_THREAD_unlock(rand_meth_lock); - return tmp_meth; + CRYPTO_THREAD_unlock(dgbl->lock); + + return ret; } -#ifndef OPENSSL_NO_ENGINE -int RAND_set_rand_engine(ENGINE *engine) +/* + * Get the public random generator. + * Returns pointer to its EVP_RAND_CTX on success, NULL on failure. + */ +EVP_RAND_CTX *RAND_get0_public(OSSL_LIB_CTX *ctx) { - const RAND_METHOD *tmp_meth = NULL; + RAND_GLOBAL *dgbl = rand_get_global(ctx); + EVP_RAND_CTX *rand, *primary; - if (!RUN_ONCE(&rand_init, do_rand_init)) - return 0; + if (dgbl == NULL) + return NULL; - if (engine != NULL) { - if (!ENGINE_init(engine)) - return 0; - tmp_meth = ENGINE_get_RAND(engine); - if (tmp_meth == NULL) { - ENGINE_finish(engine); - return 0; - } + rand = CRYPTO_THREAD_get_local(&dgbl->public); + if (rand == NULL) { + primary = RAND_get0_primary(ctx); + if (primary == NULL) + return NULL; + + ctx = ossl_lib_ctx_get_concrete(ctx); + /* + * If the private is also NULL then this is the first time we've + * used this thread. + */ + if (CRYPTO_THREAD_get_local(&dgbl->private) == NULL + && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state)) + return NULL; + rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL, + SECONDARY_RESEED_TIME_INTERVAL); + CRYPTO_THREAD_set_local(&dgbl->public, rand); } - CRYPTO_THREAD_write_lock(rand_engine_lock); - /* This function releases any prior ENGINE so call it first */ - RAND_set_rand_method(tmp_meth); - funct_ref = engine; - CRYPTO_THREAD_unlock(rand_engine_lock); - return 1; + return rand; } -#endif -void RAND_seed(const void *buf, int num) +/* + * Get the private random generator. + * Returns pointer to its EVP_RAND_CTX on success, NULL on failure. + */ +EVP_RAND_CTX *RAND_get0_private(OSSL_LIB_CTX *ctx) { - const RAND_METHOD *meth = RAND_get_rand_method(); + RAND_GLOBAL *dgbl = rand_get_global(ctx); + EVP_RAND_CTX *rand, *primary; - if (meth != NULL && meth->seed != NULL) - meth->seed(buf, num); + if (dgbl == NULL) + return NULL; + + rand = CRYPTO_THREAD_get_local(&dgbl->private); + if (rand == NULL) { + primary = RAND_get0_primary(ctx); + if (primary == NULL) + return NULL; + + ctx = ossl_lib_ctx_get_concrete(ctx); + /* + * If the public is also NULL then this is the first time we've + * used this thread. + */ + if (CRYPTO_THREAD_get_local(&dgbl->public) == NULL + && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state)) + return NULL; + rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL, + SECONDARY_RESEED_TIME_INTERVAL); + CRYPTO_THREAD_set_local(&dgbl->private, rand); + } + return rand; } -void RAND_add(const void *buf, int num, double randomness) +#ifndef FIPS_MODULE +static int random_set_string(char **p, const char *s) { - const RAND_METHOD *meth = RAND_get_rand_method(); + char *d = NULL; - if (meth != NULL && meth->add != NULL) - meth->add(buf, num, randomness); + if (s != NULL) { + d = OPENSSL_strdup(s); + if (d == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + } + OPENSSL_free(*p); + *p = d; + return 1; } /* - * This function is not part of RAND_METHOD, so if we're not using - * the default method, then just call RAND_bytes(). Otherwise make - * sure we're instantiated and use the private DRBG. + * Load the DRBG definitions from a configuration file. */ -int RAND_priv_bytes(unsigned char *buf, int num) +static int random_conf_init(CONF_IMODULE *md, const CONF *cnf) { - const RAND_METHOD *meth = RAND_get_rand_method(); - RAND_DRBG *drbg; + STACK_OF(CONF_VALUE) *elist; + CONF_VALUE *cval; + RAND_GLOBAL *dgbl = rand_get_global(NCONF_get0_libctx((CONF *)cnf)); + int i, r = 1; - if (meth != NULL && meth != RAND_OpenSSL()) - return RAND_bytes(buf, num); + OSSL_TRACE1(CONF, "Loading random module: section %s\n", + CONF_imodule_get_value(md)); - drbg = RAND_DRBG_get0_private(); - if (drbg != NULL) - return RAND_DRBG_bytes(drbg, buf, num); + /* Value is a section containing RANDOM configuration */ + elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); + if (elist == NULL) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_RANDOM_SECTION_ERROR); + return 0; + } - return 0; + if (dgbl == NULL) + return 0; + + for (i = 0; i < sk_CONF_VALUE_num(elist); i++) { + cval = sk_CONF_VALUE_value(elist, i); + if (OPENSSL_strcasecmp(cval->name, "random") == 0) { + if (!random_set_string(&dgbl->rng_name, cval->value)) + return 0; + } else if (OPENSSL_strcasecmp(cval->name, "cipher") == 0) { + if (!random_set_string(&dgbl->rng_cipher, cval->value)) + return 0; + } else if (OPENSSL_strcasecmp(cval->name, "digest") == 0) { + if (!random_set_string(&dgbl->rng_digest, cval->value)) + return 0; + } else if (OPENSSL_strcasecmp(cval->name, "properties") == 0) { + if (!random_set_string(&dgbl->rng_propq, cval->value)) + return 0; + } else if (OPENSSL_strcasecmp(cval->name, "seed") == 0) { + if (!random_set_string(&dgbl->seed_name, cval->value)) + return 0; + } else if (OPENSSL_strcasecmp(cval->name, "seed_properties") == 0) { + if (!random_set_string(&dgbl->seed_propq, cval->value)) + return 0; + } else { + ERR_raise_data(ERR_LIB_CRYPTO, + CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION, + "name=%s, value=%s", cval->name, cval->value); + r = 0; + } + } + return r; } -int RAND_bytes(unsigned char *buf, int num) + +static void random_conf_deinit(CONF_IMODULE *md) { - const RAND_METHOD *meth = RAND_get_rand_method(); + OSSL_TRACE(CONF, "Cleaned up random\n"); +} - if (meth != NULL && meth->bytes != NULL) - return meth->bytes(buf, num); - RANDerr(RAND_F_RAND_BYTES, RAND_R_FUNC_NOT_IMPLEMENTED); - return -1; +void ossl_random_add_conf_module(void) +{ + OSSL_TRACE(CONF, "Adding config module 'random'\n"); + CONF_module_add("random", random_conf_init, random_conf_deinit); } -#if OPENSSL_API_COMPAT < 0x10100000L -int RAND_pseudo_bytes(unsigned char *buf, int num) +int RAND_set_DRBG_type(OSSL_LIB_CTX *ctx, const char *drbg, const char *propq, + const char *cipher, const char *digest) { - const RAND_METHOD *meth = RAND_get_rand_method(); + RAND_GLOBAL *dgbl = rand_get_global(ctx); - if (meth != NULL && meth->pseudorand != NULL) - return meth->pseudorand(buf, num); - RANDerr(RAND_F_RAND_PSEUDO_BYTES, RAND_R_FUNC_NOT_IMPLEMENTED); - return -1; + if (dgbl == NULL) + return 0; + if (dgbl->primary != NULL) { + ERR_raise(ERR_LIB_CRYPTO, RAND_R_ALREADY_INSTANTIATED); + return 0; + } + return random_set_string(&dgbl->rng_name, drbg) + && random_set_string(&dgbl->rng_propq, propq) + && random_set_string(&dgbl->rng_cipher, cipher) + && random_set_string(&dgbl->rng_digest, digest); } -#endif -int RAND_status(void) +int RAND_set_seed_source_type(OSSL_LIB_CTX *ctx, const char *seed, + const char *propq) { - const RAND_METHOD *meth = RAND_get_rand_method(); + RAND_GLOBAL *dgbl = rand_get_global(ctx); - if (meth != NULL && meth->status != NULL) - return meth->status(); - return 0; + if (dgbl == NULL) + return 0; + if (dgbl->primary != NULL) { + ERR_raise(ERR_LIB_CRYPTO, RAND_R_ALREADY_INSTANTIATED); + return 0; + } + return random_set_string(&dgbl->seed_name, seed) + && random_set_string(&dgbl->seed_propq, propq); } + +#endif diff --git a/crypto/openssl/crypto/rand/rand_local.h b/crypto/openssl/crypto/rand/rand_local.h index a5de5252dcdc..31428f20c85e 100644 --- a/crypto/openssl/crypto/rand/rand_local.h +++ b/crypto/openssl/crypto/rand/rand_local.h @@ -1,7 +1,7 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,292 +15,19 @@ # include # include # include -# include +# include # include "internal/tsan_assist.h" - -# include "internal/numbers.h" - -/* How many times to read the TSC as a randomness source. */ -# define TSC_READ_COUNT 4 - -/* Maximum reseed intervals */ -# define MAX_RESEED_INTERVAL (1 << 24) -# define MAX_RESEED_TIME_INTERVAL (1 << 20) /* approx. 12 days */ +# include "crypto/rand.h" /* Default reseed intervals */ -# define MASTER_RESEED_INTERVAL (1 << 8) -# define SLAVE_RESEED_INTERVAL (1 << 16) -# define MASTER_RESEED_TIME_INTERVAL (60*60) /* 1 hour */ -# define SLAVE_RESEED_TIME_INTERVAL (7*60) /* 7 minutes */ - - - -/* - * Maximum input size for the DRBG (entropy, nonce, personalization string) - * - * NIST SP800 90Ar1 allows a maximum of (1 << 35) bits i.e., (1 << 32) bytes. - * - * We lower it to 'only' INT32_MAX bytes, which is equivalent to 2 gigabytes. - */ -# define DRBG_MAX_LENGTH INT32_MAX - - -/* - * Maximum allocation size for RANDOM_POOL buffers - * - * The max_len value for the buffer provided to the rand_drbg_get_entropy() - * callback is currently 2^31 bytes (2 gigabytes), if a derivation function - * is used. Since this is much too large to be allocated, the rand_pool_new() - * function chooses more modest values as default pool length, bounded - * by RAND_POOL_MIN_LENGTH and RAND_POOL_MAX_LENGTH - * - * The choice of the RAND_POOL_FACTOR is large enough such that the - * RAND_POOL can store a random input which has a lousy entropy rate of - * 8/256 (= 0.03125) bits per byte. This input will be sent through the - * derivation function which 'compresses' the low quality input into a - * high quality output. - * - * The factor 1.5 below is the pessimistic estimate for the extra amount - * of entropy required when no get_nonce() callback is defined. - */ -# define RAND_POOL_FACTOR 256 -# define RAND_POOL_MAX_LENGTH (RAND_POOL_FACTOR * \ - 3 * (RAND_DRBG_STRENGTH / 16)) -/* - * = (RAND_POOL_FACTOR * \ - * 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 chosen 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 { - DRBG_UNINITIALISED, - DRBG_READY, - DRBG_ERROR -} DRBG_STATUS; - - -/* instantiate */ -typedef int (*RAND_DRBG_instantiate_fn)(RAND_DRBG *ctx, - const unsigned char *ent, - size_t entlen, - const unsigned char *nonce, - size_t noncelen, - const unsigned char *pers, - size_t perslen); -/* reseed */ -typedef int (*RAND_DRBG_reseed_fn)(RAND_DRBG *ctx, - const unsigned char *ent, - size_t entlen, - const unsigned char *adin, - size_t adinlen); -/* generate output */ -typedef int (*RAND_DRBG_generate_fn)(RAND_DRBG *ctx, - unsigned char *out, - size_t outlen, - const unsigned char *adin, - size_t adinlen); -/* uninstantiate */ -typedef int (*RAND_DRBG_uninstantiate_fn)(RAND_DRBG *ctx); - - -/* - * The DRBG methods - */ - -typedef struct rand_drbg_method_st { - RAND_DRBG_instantiate_fn instantiate; - RAND_DRBG_reseed_fn reseed; - RAND_DRBG_generate_fn generate; - RAND_DRBG_uninstantiate_fn uninstantiate; -} RAND_DRBG_METHOD; - - -/* - * The state of a DRBG AES-CTR. - */ -typedef struct rand_drbg_ctr_st { - EVP_CIPHER_CTX *ctx_ecb; - EVP_CIPHER_CTX *ctx_ctr; - EVP_CIPHER_CTX *ctx_df; - const EVP_CIPHER *cipher_ecb; - const EVP_CIPHER *cipher_ctr; - size_t keylen; - unsigned char K[32]; - unsigned char V[16]; - /* Temporary block storage used by ctr_df */ - unsigned char bltmp[16]; - size_t bltmp_pos; - unsigned char KX[48]; -} RAND_DRBG_CTR; - - -/* - * The 'random pool' acts as a dumb container for collecting random - * input from various entropy sources. The pool has no knowledge about - * whether its randomness is fed into a legacy RAND_METHOD via RAND_add() - * or into a new style RAND_DRBG. It is the callers duty to 1) initialize the - * random pool, 2) pass it to the polling callbacks, 3) seed the RNG, and - * 4) cleanup the random pool again. - * - * The random pool contains no locking mechanism because its scope and - * lifetime is intended to be restricted to a single stack frame. - */ -struct rand_pool_st { - unsigned char *buffer; /* points to the beginning of the random pool */ - 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 */ -}; - -/* - * The state of all types of DRBGs, even though we only have CTR mode - * right now. - */ -struct rand_drbg_st { - CRYPTO_RWLOCK *lock; - RAND_DRBG *parent; - int secure; /* 1: allocated on the secure heap, 0: otherwise */ - int type; /* the nid of the underlying algorithm */ - /* - * 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_id; - unsigned short flags; /* various external flags */ - - /* - * The random_data is used by RAND_add()/drbg_add() to attach random - * data to the global drbg, such that the rand_drbg_get_entropy() callback - * can pull it during instantiation and reseeding. This is necessary to - * reconcile the different philosophies of the RAND and the RAND_DRBG - * with respect to how randomness is added to the RNG during reseeding - * (see PR #4328). - */ - struct rand_pool_st *seed_pool; - - /* - * Auxiliary pool for additional data. - */ - struct rand_pool_st *adin_pool; - - /* - * The following parameters are setup by the per-type "init" function. - * - * Currently the only type is CTR_DRBG, its init function is drbg_ctr_init(). - * - * The parameters are closely related to the ones described in - * section '10.2.1 CTR_DRBG' of [NIST SP 800-90Ar1], with one - * crucial difference: In the NIST standard, all counts are given - * in bits, whereas in OpenSSL entropy counts are given in bits - * and buffer lengths are given in bytes. - * - * Since this difference has lead to some confusion in the past, - * (see [GitHub Issue #2443], formerly [rt.openssl.org #4055]) - * the 'len' suffix has been added to all buffer sizes for - * clarification. - */ - - int strength; - size_t max_request; - size_t min_entropylen, max_entropylen; - size_t min_noncelen, max_noncelen; - size_t max_perslen, max_adinlen; - - /* Counts the number of generate requests since the last reseed. */ - unsigned int generate_counter; - /* - * Maximum number of generate requests until a reseed is required. - * This value is ignored if it is zero. - */ - unsigned int reseed_interval; - /* Stores the time when the last reseeding occurred */ - time_t reseed_time; - /* - * Specifies the maximum time interval (in seconds) between reseeds. - * This value is ignored if it is zero. - */ - time_t reseed_time_interval; - - /* - * Enables reseed propagation (see following comment) - */ - unsigned int enable_reseed_propagation; - - /* - * Counts the number of reseeds since instantiation. - * This value is ignored if enable_reseed_propagation is zero. - * - * This counter is used only for seed propagation from the DRBG - * to its two children, the and DRBG. This feature is - * very special and its sole purpose is to ensure that any randomness which - * is added by RAND_add() or RAND_seed() will have an immediate effect on - * the output of RAND_bytes() resp. RAND_priv_bytes(). - */ - TSAN_QUALIFIER unsigned int reseed_counter; - - size_t seedlen; - DRBG_STATUS state; - - /* Application data, mainly used in the KATs. */ - CRYPTO_EX_DATA ex_data; - - /* Implementation specific data (currently only one implementation) */ - union { - RAND_DRBG_CTR ctr; - } data; - - /* Implementation specific methods */ - RAND_DRBG_METHOD *meth; - - /* Callback functions. See comments in rand_lib.c */ - RAND_DRBG_get_entropy_fn get_entropy; - RAND_DRBG_cleanup_entropy_fn cleanup_entropy; - RAND_DRBG_get_nonce_fn get_nonce; - RAND_DRBG_cleanup_nonce_fn cleanup_nonce; -}; +# define PRIMARY_RESEED_INTERVAL (1 << 8) +# define SECONDARY_RESEED_INTERVAL (1 << 16) +# define PRIMARY_RESEED_TIME_INTERVAL (60 * 60) /* 1 hour */ +# define SECONDARY_RESEED_TIME_INTERVAL (7 * 60) /* 7 minutes */ +# ifndef FIPS_MODULE /* The global RAND method, and the global buffer and DRBG instance. */ -extern RAND_METHOD rand_meth; - -/* DRBG helpers */ -int rand_drbg_restart(RAND_DRBG *drbg, - const unsigned char *buffer, size_t len, size_t entropy); -size_t rand_drbg_seedlen(RAND_DRBG *drbg); -/* locking api */ -int rand_drbg_lock(RAND_DRBG *drbg); -int rand_drbg_unlock(RAND_DRBG *drbg); -int rand_drbg_enable_locking(RAND_DRBG *drbg); - - -/* initializes the AES-CTR DRBG implementation */ -int drbg_ctr_init(RAND_DRBG *drbg); +extern RAND_METHOD ossl_rand_meth; +# endif #endif diff --git a/crypto/openssl/crypto/rand/rand_meth.c b/crypto/openssl/crypto/rand/rand_meth.c new file mode 100644 index 000000000000..276763057db2 --- /dev/null +++ b/crypto/openssl/crypto/rand/rand_meth.c @@ -0,0 +1,65 @@ +/* + * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "rand_local.h" + +/* Implements the default OpenSSL RAND_add() method */ +static int drbg_add(const void *buf, int num, double randomness) +{ + EVP_RAND_CTX *drbg = RAND_get0_primary(NULL); + + if (drbg == NULL || num <= 0) + return 0; + + return EVP_RAND_reseed(drbg, 0, NULL, 0, buf, num); +} + +/* Implements the default OpenSSL RAND_seed() method */ +static int drbg_seed(const void *buf, int num) +{ + return drbg_add(buf, num, num); +} + +/* Implements the default OpenSSL RAND_status() method */ +static int drbg_status(void) +{ + EVP_RAND_CTX *drbg = RAND_get0_primary(NULL); + + if (drbg == NULL) + return 0; + + return EVP_RAND_get_state(drbg) == EVP_RAND_STATE_READY ? 1 : 0; +} + +/* Implements the default OpenSSL RAND_bytes() method */ +static int drbg_bytes(unsigned char *out, int count) +{ + EVP_RAND_CTX *drbg = RAND_get0_public(NULL); + + if (drbg == NULL) + return 0; + + return EVP_RAND_generate(drbg, out, count, 0, 0, NULL, 0); +} + +RAND_METHOD ossl_rand_meth = { + drbg_seed, + drbg_bytes, + NULL, + drbg_add, + drbg_bytes, + drbg_status +}; + +RAND_METHOD *RAND_OpenSSL(void) +{ + return &ossl_rand_meth; +} diff --git a/crypto/openssl/crypto/rand/rand_pool.c b/crypto/openssl/crypto/rand/rand_pool.c new file mode 100644 index 000000000000..55f14be60e63 --- /dev/null +++ b/crypto/openssl/crypto/rand/rand_pool.c @@ -0,0 +1,412 @@ +/* + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/cryptlib.h" +#include +#include "crypto/rand.h" +#include +#include "internal/thread_once.h" +#include "crypto/rand_pool.h" + +/* + * Allocate memory and initialize a new random pool + */ +RAND_POOL *ossl_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) { + ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + return NULL; + } + + 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); + + if (pool->buffer == NULL) { + ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + goto err; + } + + pool->entropy_requested = entropy_requested; + pool->secure = secure; + return pool; + +err: + OPENSSL_free(pool); + return NULL; +} + +/* + * Attach new random pool to the given buffer + * + * This function is intended to be used only for feeding random data + * provided by RAND_add() and RAND_seed() into the DRBG. + */ +RAND_POOL *ossl_rand_pool_attach(const unsigned char *buffer, size_t len, + size_t entropy) +{ + RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool)); + + if (pool == NULL) { + ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* + * The const needs to be cast away, but attached buffers will not be + * modified (in contrary to allocated buffers which are zeroed and + * freed in the end). + */ + pool->buffer = (unsigned char *) buffer; + pool->len = len; + + pool->attached = 1; + + pool->min_len = pool->max_len = pool->alloc_len = pool->len; + pool->entropy = entropy; + + return pool; +} + +/* + * Free |pool|, securely erasing its buffer. + */ +void ossl_rand_pool_free(RAND_POOL *pool) +{ + if (pool == NULL) + return; + + /* + * Although it would be advisable from a cryptographical viewpoint, + * we are not allowed to clear attached buffers, since they are passed + * to ossl_rand_pool_attach() as `const unsigned char*`. + * (see corresponding comment in ossl_rand_pool_attach()). + */ + 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); +} + +/* + * Return the |pool|'s buffer to the caller (readonly). + */ +const unsigned char *ossl_rand_pool_buffer(RAND_POOL *pool) +{ + return pool->buffer; +} + +/* + * Return the |pool|'s entropy to the caller. + */ +size_t ossl_rand_pool_entropy(RAND_POOL *pool) +{ + return pool->entropy; +} + +/* + * Return the |pool|'s buffer length to the caller. + */ +size_t ossl_rand_pool_length(RAND_POOL *pool) +{ + return pool->len; +} + +/* + * Detach the |pool| buffer and return it to the caller. + * It's the responsibility of the caller to free the buffer + * using OPENSSL_secure_clear_free() or to re-attach it + * again to the pool using ossl_rand_pool_reattach(). + */ +unsigned char *ossl_rand_pool_detach(RAND_POOL *pool) +{ + unsigned char *ret = pool->buffer; + pool->buffer = NULL; + pool->entropy = 0; + return ret; +} + +/* + * Re-attach the |pool| buffer. It is only allowed to pass + * the |buffer| which was previously detached from the same pool. + */ +void ossl_rand_pool_reattach(RAND_POOL *pool, unsigned char *buffer) +{ + pool->buffer = buffer; + OPENSSL_cleanse(pool->buffer, pool->len); + pool->len = 0; +} + +/* + * If |entropy_factor| bits contain 1 bit of entropy, how many bytes does one + * need to obtain at least |bits| bits of entropy? + */ +#define ENTROPY_TO_BYTES(bits, entropy_factor) \ + (((bits) * (entropy_factor) + 7) / 8) + + +/* + * Checks whether the |pool|'s entropy is available to the caller. + * This is the case when entropy count and buffer length are high enough. + * Returns + * + * |entropy| if the entropy count and buffer size is large enough + * 0 otherwise + */ +size_t ossl_rand_pool_entropy_available(RAND_POOL *pool) +{ + if (pool->entropy < pool->entropy_requested) + return 0; + + if (pool->len < pool->min_len) + return 0; + + return pool->entropy; +} + +/* + * Returns the (remaining) amount of entropy needed to fill + * the random pool. + */ + +size_t ossl_rand_pool_entropy_needed(RAND_POOL *pool) +{ + if (pool->entropy < pool->entropy_requested) + return pool->entropy_requested - pool->entropy; + + 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) { + ERR_raise(ERR_LIB_RAND, 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) { + ERR_raise(ERR_LIB_RAND, 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. + * In case of an error, 0 is returned. + */ + +size_t ossl_rand_pool_bytes_needed(RAND_POOL *pool, unsigned int entropy_factor) +{ + size_t bytes_needed; + size_t entropy_needed = ossl_rand_pool_entropy_needed(pool); + + if (entropy_factor < 1) { + ERR_raise(ERR_LIB_RAND, RAND_R_ARGUMENT_OUT_OF_RANGE); + return 0; + } + + bytes_needed = ENTROPY_TO_BYTES(entropy_needed, entropy_factor); + + if (bytes_needed > pool->max_len - pool->len) { + /* not enough space left */ + ERR_raise(ERR_LIB_RAND, RAND_R_RANDOM_POOL_OVERFLOW); + return 0; + } + + if (pool->len < pool->min_len && + bytes_needed < pool->min_len - pool->len) + /* 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 + * ossl_rand_pool_add_begin, ossl_rand_pool_add_end or ossl_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; +} + +/* Returns the remaining number of bytes available */ +size_t ossl_rand_pool_bytes_remaining(RAND_POOL *pool) +{ + return pool->max_len - pool->len; +} + +/* + * Add random bytes to the random pool. + * + * It is expected that the |buffer| contains |len| bytes of + * random input which contains at least |entropy| bits of + * randomness. + * + * Returns 1 if the added amount is adequate, otherwise 0 + */ +int ossl_rand_pool_add(RAND_POOL *pool, + const unsigned char *buffer, size_t len, size_t entropy) +{ + if (len > pool->max_len - pool->len) { + ERR_raise(ERR_LIB_RAND, RAND_R_ENTROPY_INPUT_TOO_LONG); + return 0; + } + + if (pool->buffer == NULL) { + ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (len > 0) { + /* + * This is to protect us from accidentally passing the buffer + * returned from ossl_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) { + ERR_raise(ERR_LIB_RAND, 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 ossl_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; + } + + return 1; +} + +/* + * Start to add random bytes to the random pool in-place. + * + * Reserves the next |len| bytes for adding random bytes in-place + * and returns a pointer to the buffer. + * The caller is allowed to copy up to |len| bytes into the buffer. + * If |len| == 0 this is considered a no-op and a NULL pointer + * is returned without producing an error message. + * + * After updating the buffer, ossl_rand_pool_add_end() needs to be called + * to finish the update operation (see next comment). + */ +unsigned char *ossl_rand_pool_add_begin(RAND_POOL *pool, size_t len) +{ + if (len == 0) + return NULL; + + if (len > pool->max_len - pool->len) { + ERR_raise(ERR_LIB_RAND, RAND_R_RANDOM_POOL_OVERFLOW); + return NULL; + } + + if (pool->buffer == NULL) { + ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR); + return NULL; + } + + /* + * As long as the allocation request stays within the limits given + * by ossl_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; +} + +/* + * Finish to add random bytes to the random pool in-place. + * + * Finishes an in-place update of the random pool started by + * ossl_rand_pool_add_begin() (see previous comment). + * It is expected that |len| bytes of random input have been added + * to the buffer which contain at least |entropy| bits of randomness. + * It is allowed to add less bytes than originally reserved. + */ +int ossl_rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy) +{ + if (len > pool->alloc_len - pool->len) { + ERR_raise(ERR_LIB_RAND, RAND_R_RANDOM_POOL_OVERFLOW); + return 0; + } + + if (len > 0) { + pool->len += len; + pool->entropy += entropy; + } + + return 1; +} diff --git a/crypto/openssl/crypto/rand/randfile.c b/crypto/openssl/crypto/rand/randfile.c index 229ce864a312..82f41637387b 100644 --- a/crypto/openssl/crypto/rand/randfile.c +++ b/crypto/openssl/crypto/rand/randfile.c @@ -1,12 +1,21 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +#if defined (__TANDEM) && defined (_SPT_MODEL_) +/* + * These definitions have to come first in SPT due to scoping of the + * declarations in c99 associated with SPT use of stat. + */ +# include +# include +#endif + #include "internal/cryptlib.h" #include @@ -16,7 +25,6 @@ #include #include -#include #include #ifdef OPENSSL_SYS_VMS @@ -95,15 +103,15 @@ int RAND_load_file(const char *file, long bytes) return 0; if ((in = openssl_fopen(file, "rb")) == NULL) { - RANDerr(RAND_F_RAND_LOAD_FILE, RAND_R_CANNOT_OPEN_FILE); - ERR_add_error_data(2, "Filename=", file); + ERR_raise_data(ERR_LIB_RAND, RAND_R_CANNOT_OPEN_FILE, + "Filename=%s", file); return -1; } #ifndef OPENSSL_NO_POSIX_IO if (fstat(fileno(in), &sb) < 0) { - RANDerr(RAND_F_RAND_LOAD_FILE, RAND_R_INTERNAL_ERROR); - ERR_add_error_data(2, "Filename=", file); + ERR_raise_data(ERR_LIB_RAND, RAND_R_INTERNAL_ERROR, + "Filename=%s", file); fclose(in); return -1; } @@ -163,8 +171,7 @@ int RAND_load_file(const char *file, long bytes) OPENSSL_cleanse(buf, sizeof(buf)); fclose(in); if (!RAND_status()) { - RANDerr(RAND_F_RAND_LOAD_FILE, RAND_R_RESEED_ERROR); - ERR_add_error_data(2, "Filename=", file); + ERR_raise_data(ERR_LIB_RAND, RAND_R_RESEED_ERROR, "Filename=%s", file); return -1; } @@ -180,8 +187,8 @@ int RAND_write_file(const char *file) struct stat sb; if (stat(file, &sb) >= 0 && !S_ISREG(sb.st_mode)) { - RANDerr(RAND_F_RAND_WRITE_FILE, RAND_R_NOT_A_REGULAR_FILE); - ERR_add_error_data(2, "Filename=", file); + ERR_raise_data(ERR_LIB_RAND, RAND_R_NOT_A_REGULAR_FILE, + "Filename=%s", file); return -1; } #endif @@ -230,8 +237,8 @@ int RAND_write_file(const char *file) if (out == NULL) out = openssl_fopen(file, "wb"); if (out == NULL) { - RANDerr(RAND_F_RAND_WRITE_FILE, RAND_R_CANNOT_OPEN_FILE); - ERR_add_error_data(2, "Filename=", file); + ERR_raise_data(ERR_LIB_RAND, RAND_R_CANNOT_OPEN_FILE, + "Filename=%s", file); return -1; } diff --git a/crypto/openssl/crypto/rc2/build.info b/crypto/openssl/crypto/rc2/build.info index 47a3fd0d4e35..d1f0ff9c7b69 100644 --- a/crypto/openssl/crypto/rc2/build.info +++ b/crypto/openssl/crypto/rc2/build.info @@ -1,3 +1,11 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - rc2_ecb.c rc2_skey.c rc2_cbc.c rc2cfb64.c rc2ofb64.c + +$ALL=rc2_ecb.c rc2_skey.c rc2_cbc.c rc2cfb64.c rc2ofb64.c + +SOURCE[../../libcrypto]=$ALL + +# When all deprecated symbols are removed, libcrypto doesn't export the +# rc2 functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=$ALL +ENDIF diff --git a/crypto/openssl/crypto/rc2/rc2_cbc.c b/crypto/openssl/crypto/rc2/rc2_cbc.c index 17e86f690e01..d37093fcc76c 100644 --- a/crypto/openssl/crypto/rc2/rc2_cbc.c +++ b/crypto/openssl/crypto/rc2/rc2_cbc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc2_local.h" diff --git a/crypto/openssl/crypto/rc2/rc2_ecb.c b/crypto/openssl/crypto/rc2/rc2_ecb.c index 8d9927cd5858..8861d05673b9 100644 --- a/crypto/openssl/crypto/rc2/rc2_ecb.c +++ b/crypto/openssl/crypto/rc2/rc2_ecb.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc2_local.h" #include diff --git a/crypto/openssl/crypto/rc2/rc2_local.h b/crypto/openssl/crypto/rc2/rc2_local.h index e4dad947872c..8faa7b840a54 100644 --- a/crypto/openssl/crypto/rc2/rc2_local.h +++ b/crypto/openssl/crypto/rc2/rc2_local.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/rc2/rc2_skey.c b/crypto/openssl/crypto/rc2/rc2_skey.c index 60ebd42f2636..e43b84af1715 100644 --- a/crypto/openssl/crypto/rc2/rc2_skey.c +++ b/crypto/openssl/crypto/rc2/rc2_skey.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc2_local.h" @@ -41,8 +47,8 @@ static const unsigned char key_table[256] = { /* * It has come to my attention that there are 2 versions of the RC2 key - * schedule. One which is normal, and anther which has a hook to use a - * reduced key length. BSAFE uses the 'retarded' version. What I previously + * schedule. One which is normal, and another which has a hook to use a + * reduced key length. BSAFE uses the latter version. What I previously * shipped is the same as specifying 1024 for the 'bits' parameter. Bsafe * uses a version where the bits parameter is the same as len*8 */ diff --git a/crypto/openssl/crypto/rc2/rc2cfb64.c b/crypto/openssl/crypto/rc2/rc2cfb64.c index 8d1c3a4d8f66..19612d933383 100644 --- a/crypto/openssl/crypto/rc2/rc2cfb64.c +++ b/crypto/openssl/crypto/rc2/rc2cfb64.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc2_local.h" diff --git a/crypto/openssl/crypto/rc2/rc2ofb64.c b/crypto/openssl/crypto/rc2/rc2ofb64.c index 61b2c56434bf..82c34b3aab02 100644 --- a/crypto/openssl/crypto/rc2/rc2ofb64.c +++ b/crypto/openssl/crypto/rc2/rc2ofb64.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC2 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc2_local.h" diff --git a/crypto/openssl/crypto/rc4/asm/rc4-586.pl b/crypto/openssl/crypto/rc4/asm/rc4-586.pl index 3a936de1f9a7..1fae93ae1a70 100755 --- a/crypto/openssl/crypto/rc4/asm/rc4-586.pl +++ b/crypto/openssl/crypto/rc4/asm/rc4-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1998-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -68,8 +68,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0],$x86only = $ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/rc4/asm/rc4-c64xplus.pl b/crypto/openssl/crypto/rc4/asm/rc4-c64xplus.pl index b12d044af465..bd1745f1f32b 100755 --- a/crypto/openssl/crypto/rc4/asm/rc4-c64xplus.pl +++ b/crypto/openssl/crypto/rc4/asm/rc4-c64xplus.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -186,7 +186,6 @@ rc4_options: .align 4 ___ -$output=pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; print $code; close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl b/crypto/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl index 7aa5c21bd836..90c94dcb5e3d 100755 --- a/crypto/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl +++ b/crypto/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -27,7 +27,7 @@ # minimize register usage, which was used as "main thread" with RC4 # weaved into it, one RC4 round per one MD5 round. In addition to the # stiched subroutine the script can generate standalone replacement -# md5_block_asm_data_order and RC4. Below are performance numbers in +# ossl_md5_block_asm_data_order and RC4. Below are performance numbers in # cycles per processed byte, less is better, for these the standalone # subroutines, sum of them, and stitched one: # @@ -53,9 +53,10 @@ my $D="#" if (!$md5); # if set to "#", MD5 is stitched into RC4(), # to be able to use 'openssl speed rc4' for # benchmarking the stitched subroutine... -my $flavour = shift; -my $output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -64,7 +65,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs); @@ -74,7 +76,7 @@ if ($rc4 && !$md5) { $func="RC4"; $nargs=4; } elsif ($md5 && !$rc4) { ($ctx,$inp,$len) = ("%rdi","%rsi","%rdx"); - $func="md5_block_asm_data_order"; $nargs=3; + $func="ossl_md5_block_asm_data_order"; $nargs=3; } else { ($dat,$in0,$out,$ctx,$inp,$len) = ("%rdi","%rsi","%rdx","%rcx","%r8","%r9"); $func="rc4_md5_enc"; $nargs=6; diff --git a/crypto/openssl/crypto/rc4/asm/rc4-parisc.pl b/crypto/openssl/crypto/rc4/asm/rc4-parisc.pl index 631e742b739d..9a38674a59f5 100755 --- a/crypto/openssl/crypto/rc4/asm/rc4-parisc.pl +++ b/crypto/openssl/crypto/rc4/asm/rc4-parisc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -27,9 +27,12 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/openssl/crypto/rc4/asm/rc4-s390x.pl b/crypto/openssl/crypto/rc4/asm/rc4-s390x.pl index dded0b75e7f9..d5250f57f192 100755 --- a/crypto/openssl/crypto/rc4/asm/rc4-s390x.pl +++ b/crypto/openssl/crypto/rc4/asm/rc4-s390x.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -30,7 +30,10 @@ # remains z/Architecture specific. On z990 it was measured to perform # 50% better than code generated by gcc 4.3. -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -40,8 +43,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $rp="%r14"; $sp="%r15"; diff --git a/crypto/openssl/crypto/rc4/asm/rc4-x86_64.pl b/crypto/openssl/crypto/rc4/asm/rc4-x86_64.pl index 423eb5b4a997..5a903f5739e1 100755 --- a/crypto/openssl/crypto/rc4/asm/rc4-x86_64.pl +++ b/crypto/openssl/crypto/rc4/asm/rc4-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -111,9 +111,10 @@ # but more than likely at the cost of the others (see rc4-586.pl # to get the idea)... -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -122,7 +123,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $dat="%rdi"; # arg1 @@ -140,6 +142,7 @@ $code=<<___; .align 16 RC4: .cfi_startproc + endbranch or $len,$len jne .Lentry ret @@ -455,6 +458,7 @@ $code.=<<___; .align 16 RC4_set_key: .cfi_startproc + endbranch lea 8($dat),$dat lea ($inp,$len),$inp neg $len @@ -529,6 +533,7 @@ RC4_set_key: .align 16 RC4_options: .cfi_startproc + endbranch lea .Lopts(%rip),%rax mov OPENSSL_ia32cap_P(%rip),%edx bt \$20,%edx diff --git a/crypto/openssl/crypto/rc4/build.info b/crypto/openssl/crypto/rc4/build.info index 913942b5e980..68b3c73f55b0 100644 --- a/crypto/openssl/crypto/rc4/build.info +++ b/crypto/openssl/crypto/rc4/build.info @@ -1,20 +1,36 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - {- $target{rc4_asm_src} -} -GENERATE[rc4-586.s]=asm/rc4-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[rc4-586.s]=../perlasm/x86asm.pl +$RC4ASM=rc4_enc.c rc4_skey.c +IF[{- !$disabled{asm} -}] + $RC4ASM_x86=rc4-586.S + $RC4ASM_x86_64=rc4-x86_64.s rc4-md5-x86_64.s + $RC4ASM_s390x=rc4-s390x.s + $RC4ASM_parisc11=rc4-parisc.s + $RC4ASM_parisc20_64=$RC4ASM_parisc11 + $RC4ASM_c64xplus=rc4-c64xplus.s -GENERATE[rc4-x86_64.s]=asm/rc4-x86_64.pl $(PERLASM_SCHEME) -GENERATE[rc4-md5-x86_64.s]=asm/rc4-md5-x86_64.pl $(PERLASM_SCHEME) + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$RC4ASM_{- $target{asm_arch} -}] + $RC4ASM=$RC4ASM_{- $target{asm_arch} -} + $RC4DEF=RC4_ASM + ENDIF +ENDIF -GENERATE[rc4-parisc.s]=asm/rc4-parisc.pl $(PERLASM_SCHEME) +SOURCE[../../libcrypto]=$RC4ASM -GENERATE[rc4-s390x.s]=asm/rc4-s390x.pl $(PERLASM_SCHEME) +# When all deprecated symbols are removed, libcrypto doesn't export the +# rc4 functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=$RC4ASM +ENDIF -BEGINRAW[Makefile] -# GNU make "catch all" -{- $builddir -}/rc4-%.s: {- $sourcedir -}/asm/rc4-%.pl - CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ -ENDRAW[Makefile] +GENERATE[rc4-586.S]=asm/rc4-586.pl +DEPEND[rc4-586.S]=../perlasm/x86asm.pl + +GENERATE[rc4-x86_64.s]=asm/rc4-x86_64.pl +GENERATE[rc4-md5-x86_64.s]=asm/rc4-md5-x86_64.pl + +GENERATE[rc4-parisc.s]=asm/rc4-parisc.pl +GENERATE[rc4-c64xplus.s]=asm/rc4-c64xplus.pl +GENERATE[rc4-s390x.s]=asm/rc4-s390x.pl diff --git a/crypto/openssl/crypto/rc4/rc4-586.S b/crypto/openssl/crypto/rc4/rc4-586.S new file mode 100644 index 000000000000..a10b047a7ecd --- /dev/null +++ b/crypto/openssl/crypto/rc4/rc4-586.S @@ -0,0 +1,412 @@ +.text +.globl RC4 +.type RC4,@function +.align 16 +RC4: +.L_RC4_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%edi + movl 24(%esp),%edx + movl 28(%esp),%esi + movl 32(%esp),%ebp + xorl %eax,%eax + xorl %ebx,%ebx + cmpl $0,%edx + je .L000abort + movb (%edi),%al + movb 4(%edi),%bl + addl $8,%edi + leal (%esi,%edx,1),%ecx + subl %esi,%ebp + movl %ecx,24(%esp) + incb %al + cmpl $-1,256(%edi) + je .L001RC4_CHAR + movl (%edi,%eax,4),%ecx + andl $-4,%edx + jz .L002loop1 + movl %ebp,32(%esp) + testl $-8,%edx + jz .L003go4loop4 + call .L004PIC_me_up +.L004PIC_me_up: + popl %ebp + leal OPENSSL_ia32cap_P-.L004PIC_me_up(%ebp),%ebp + btl $26,(%ebp) + jnc .L003go4loop4 + movl 32(%esp),%ebp + andl $-8,%edx + leal -8(%esi,%edx,1),%edx + movl %edx,-4(%edi) + addb %cl,%bl + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + incl %eax + addl %ecx,%edx + movzbl %al,%eax + movzbl %dl,%edx + movq (%esi),%mm0 + movl (%edi,%eax,4),%ecx + movd (%edi,%edx,4),%mm2 + jmp .L005loop_mmx_enter +.align 16 +.L006loop_mmx: + addb %cl,%bl + psllq $56,%mm1 + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + incl %eax + addl %ecx,%edx + movzbl %al,%eax + movzbl %dl,%edx + pxor %mm1,%mm2 + movq (%esi),%mm0 + movq %mm2,-8(%ebp,%esi,1) + movl (%edi,%eax,4),%ecx + movd (%edi,%edx,4),%mm2 +.L005loop_mmx_enter: + addb %cl,%bl + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + incl %eax + addl %ecx,%edx + movzbl %al,%eax + movzbl %dl,%edx + pxor %mm0,%mm2 + movl (%edi,%eax,4),%ecx + movd (%edi,%edx,4),%mm1 + addb %cl,%bl + psllq $8,%mm1 + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + incl %eax + addl %ecx,%edx + movzbl %al,%eax + movzbl %dl,%edx + pxor %mm1,%mm2 + movl (%edi,%eax,4),%ecx + movd (%edi,%edx,4),%mm1 + addb %cl,%bl + psllq $16,%mm1 + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + incl %eax + addl %ecx,%edx + movzbl %al,%eax + movzbl %dl,%edx + pxor %mm1,%mm2 + movl (%edi,%eax,4),%ecx + movd (%edi,%edx,4),%mm1 + addb %cl,%bl + psllq $24,%mm1 + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + incl %eax + addl %ecx,%edx + movzbl %al,%eax + movzbl %dl,%edx + pxor %mm1,%mm2 + movl (%edi,%eax,4),%ecx + movd (%edi,%edx,4),%mm1 + addb %cl,%bl + psllq $32,%mm1 + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + incl %eax + addl %ecx,%edx + movzbl %al,%eax + movzbl %dl,%edx + pxor %mm1,%mm2 + movl (%edi,%eax,4),%ecx + movd (%edi,%edx,4),%mm1 + addb %cl,%bl + psllq $40,%mm1 + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + incl %eax + addl %ecx,%edx + movzbl %al,%eax + movzbl %dl,%edx + pxor %mm1,%mm2 + movl (%edi,%eax,4),%ecx + movd (%edi,%edx,4),%mm1 + addb %cl,%bl + psllq $48,%mm1 + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + incl %eax + addl %ecx,%edx + movzbl %al,%eax + movzbl %dl,%edx + pxor %mm1,%mm2 + movl (%edi,%eax,4),%ecx + movd (%edi,%edx,4),%mm1 + movl %ebx,%edx + xorl %ebx,%ebx + movb %dl,%bl + cmpl -4(%edi),%esi + leal 8(%esi),%esi + jb .L006loop_mmx + psllq $56,%mm1 + pxor %mm1,%mm2 + movq %mm2,-8(%ebp,%esi,1) + emms + cmpl 24(%esp),%esi + je .L007done + jmp .L002loop1 +.align 16 +.L003go4loop4: + leal -4(%esi,%edx,1),%edx + movl %edx,28(%esp) +.L008loop4: + addb %cl,%bl + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + addl %ecx,%edx + incb %al + andl $255,%edx + movl (%edi,%eax,4),%ecx + movl (%edi,%edx,4),%ebp + addb %cl,%bl + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + addl %ecx,%edx + incb %al + andl $255,%edx + rorl $8,%ebp + movl (%edi,%eax,4),%ecx + orl (%edi,%edx,4),%ebp + addb %cl,%bl + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + addl %ecx,%edx + incb %al + andl $255,%edx + rorl $8,%ebp + movl (%edi,%eax,4),%ecx + orl (%edi,%edx,4),%ebp + addb %cl,%bl + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + addl %ecx,%edx + incb %al + andl $255,%edx + rorl $8,%ebp + movl 32(%esp),%ecx + orl (%edi,%edx,4),%ebp + rorl $8,%ebp + xorl (%esi),%ebp + cmpl 28(%esp),%esi + movl %ebp,(%ecx,%esi,1) + leal 4(%esi),%esi + movl (%edi,%eax,4),%ecx + jb .L008loop4 + cmpl 24(%esp),%esi + je .L007done + movl 32(%esp),%ebp +.align 16 +.L002loop1: + addb %cl,%bl + movl (%edi,%ebx,4),%edx + movl %ecx,(%edi,%ebx,4) + movl %edx,(%edi,%eax,4) + addl %ecx,%edx + incb %al + andl $255,%edx + movl (%edi,%edx,4),%edx + xorb (%esi),%dl + leal 1(%esi),%esi + movl (%edi,%eax,4),%ecx + cmpl 24(%esp),%esi + movb %dl,-1(%ebp,%esi,1) + jb .L002loop1 + jmp .L007done +.align 16 +.L001RC4_CHAR: + movzbl (%edi,%eax,1),%ecx +.L009cloop1: + addb %cl,%bl + movzbl (%edi,%ebx,1),%edx + movb %cl,(%edi,%ebx,1) + movb %dl,(%edi,%eax,1) + addb %cl,%dl + movzbl (%edi,%edx,1),%edx + addb $1,%al + xorb (%esi),%dl + leal 1(%esi),%esi + movzbl (%edi,%eax,1),%ecx + cmpl 24(%esp),%esi + movb %dl,-1(%ebp,%esi,1) + jb .L009cloop1 +.L007done: + decb %al + movl %ebx,-4(%edi) + movb %al,-8(%edi) +.L000abort: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size RC4,.-.L_RC4_begin +.globl RC4_set_key +.type RC4_set_key,@function +.align 16 +RC4_set_key: +.L_RC4_set_key_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%edi + movl 24(%esp),%ebp + movl 28(%esp),%esi + call .L010PIC_me_up +.L010PIC_me_up: + popl %edx + leal OPENSSL_ia32cap_P-.L010PIC_me_up(%edx),%edx + leal 8(%edi),%edi + leal (%esi,%ebp,1),%esi + negl %ebp + xorl %eax,%eax + movl %ebp,-4(%edi) + btl $20,(%edx) + jc .L011c1stloop +.align 16 +.L012w1stloop: + movl %eax,(%edi,%eax,4) + addb $1,%al + jnc .L012w1stloop + xorl %ecx,%ecx + xorl %edx,%edx +.align 16 +.L013w2ndloop: + movl (%edi,%ecx,4),%eax + addb (%esi,%ebp,1),%dl + addb %al,%dl + addl $1,%ebp + movl (%edi,%edx,4),%ebx + jnz .L014wnowrap + movl -4(%edi),%ebp +.L014wnowrap: + movl %eax,(%edi,%edx,4) + movl %ebx,(%edi,%ecx,4) + addb $1,%cl + jnc .L013w2ndloop + jmp .L015exit +.align 16 +.L011c1stloop: + movb %al,(%edi,%eax,1) + addb $1,%al + jnc .L011c1stloop + xorl %ecx,%ecx + xorl %edx,%edx + xorl %ebx,%ebx +.align 16 +.L016c2ndloop: + movb (%edi,%ecx,1),%al + addb (%esi,%ebp,1),%dl + addb %al,%dl + addl $1,%ebp + movb (%edi,%edx,1),%bl + jnz .L017cnowrap + movl -4(%edi),%ebp +.L017cnowrap: + movb %al,(%edi,%edx,1) + movb %bl,(%edi,%ecx,1) + addb $1,%cl + jnc .L016c2ndloop + movl $-1,256(%edi) +.L015exit: + xorl %eax,%eax + movl %eax,-8(%edi) + movl %eax,-4(%edi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size RC4_set_key,.-.L_RC4_set_key_begin +.globl RC4_options +.type RC4_options,@function +.align 16 +RC4_options: +.L_RC4_options_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + call .L018pic_point +.L018pic_point: + popl %eax + leal .L019opts-.L018pic_point(%eax),%eax + call .L020PIC_me_up +.L020PIC_me_up: + popl %edx + leal OPENSSL_ia32cap_P-.L020PIC_me_up(%edx),%edx + movl (%edx),%edx + btl $20,%edx + jc .L0211xchar + btl $26,%edx + jnc .L022ret + addl $25,%eax + ret +.L0211xchar: + addl $12,%eax +.L022ret: + ret +.align 64 +.L019opts: +.byte 114,99,52,40,52,120,44,105,110,116,41,0 +.byte 114,99,52,40,49,120,44,99,104,97,114,41,0 +.byte 114,99,52,40,56,120,44,109,109,120,41,0 +.byte 82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89 +.byte 80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114 +.byte 111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 +.size RC4_options,.-.L_RC4_options_begin +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/rc4/rc4-md5-x86_64.S b/crypto/openssl/crypto/rc4/rc4-md5-x86_64.S new file mode 100644 index 000000000000..f1b9eddac4e3 --- /dev/null +++ b/crypto/openssl/crypto/rc4/rc4-md5-x86_64.S @@ -0,0 +1,1302 @@ +.text +.align 16 + +.globl rc4_md5_enc +.type rc4_md5_enc,@function +rc4_md5_enc: +.cfi_startproc + cmpq $0,%r9 + je .Labort + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + subq $40,%rsp +.cfi_adjust_cfa_offset 40 +.Lbody: + movq %rcx,%r11 + movq %r9,%r12 + movq %rsi,%r13 + movq %rdx,%r14 + movq %r8,%r15 + xorq %rbp,%rbp + xorq %rcx,%rcx + + leaq 8(%rdi),%rdi + movb -8(%rdi),%bpl + movb -4(%rdi),%cl + + incb %bpl + subq %r13,%r14 + movl (%rdi,%rbp,4),%eax + addb %al,%cl + leaq (%rdi,%rbp,4),%rsi + shlq $6,%r12 + addq %r15,%r12 + movq %r12,16(%rsp) + + movq %r11,24(%rsp) + movl 0(%r11),%r8d + movl 4(%r11),%r9d + movl 8(%r11),%r10d + movl 12(%r11),%r11d + jmp .Loop + +.align 16 +.Loop: + movl %r8d,0(%rsp) + movl %r9d,4(%rsp) + movl %r10d,8(%rsp) + movl %r11d,%r12d + movl %r11d,12(%rsp) + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 0(%r15),%r8d + addb %dl,%al + movl 4(%rsi),%ebx + addl $3614090360,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,0(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 4(%r15),%r11d + addb %dl,%bl + movl 8(%rsi),%eax + addl $3905402710,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,4(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 8(%r15),%r10d + addb %dl,%al + movl 12(%rsi),%ebx + addl $606105819,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,8(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 12(%r15),%r9d + addb %dl,%bl + movl 16(%rsi),%eax + addl $3250441966,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,12(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 16(%r15),%r8d + addb %dl,%al + movl 20(%rsi),%ebx + addl $4118548399,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,16(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 20(%r15),%r11d + addb %dl,%bl + movl 24(%rsi),%eax + addl $1200080426,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,20(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 24(%r15),%r10d + addb %dl,%al + movl 28(%rsi),%ebx + addl $2821735955,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,24(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 28(%r15),%r9d + addb %dl,%bl + movl 32(%rsi),%eax + addl $4249261313,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,28(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 32(%r15),%r8d + addb %dl,%al + movl 36(%rsi),%ebx + addl $1770035416,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,32(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 36(%r15),%r11d + addb %dl,%bl + movl 40(%rsi),%eax + addl $2336552879,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,36(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 40(%r15),%r10d + addb %dl,%al + movl 44(%rsi),%ebx + addl $4294925233,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,40(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 44(%r15),%r9d + addb %dl,%bl + movl 48(%rsi),%eax + addl $2304563134,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,44(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 48(%r15),%r8d + addb %dl,%al + movl 52(%rsi),%ebx + addl $1804603682,%r8d + xorl %r11d,%r12d + movzbl %al,%eax + movl %edx,48(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $7,%r8d + movl %r10d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 52(%r15),%r11d + addb %dl,%bl + movl 56(%rsi),%eax + addl $4254626195,%r11d + xorl %r10d,%r12d + movzbl %bl,%ebx + movl %edx,52(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $12,%r11d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 56(%r15),%r10d + addb %dl,%al + movl 60(%rsi),%ebx + addl $2792965006,%r10d + xorl %r9d,%r12d + movzbl %al,%eax + movl %edx,56(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $17,%r10d + movl %r8d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu (%r13),%xmm2 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 60(%r15),%r9d + addb %dl,%bl + movl 64(%rsi),%eax + addl $1236535329,%r9d + xorl %r8d,%r12d + movzbl %bl,%ebx + movl %edx,60(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $22,%r9d + movl %r10d,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + psllq $8,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm1,%xmm2 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 4(%r15),%r8d + addb %dl,%al + movl 68(%rsi),%ebx + addl $4129170786,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,64(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 24(%r15),%r11d + addb %dl,%bl + movl 72(%rsi),%eax + addl $3225465664,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,68(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 44(%r15),%r10d + addb %dl,%al + movl 76(%rsi),%ebx + addl $643717713,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,72(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 0(%r15),%r9d + addb %dl,%bl + movl 80(%rsi),%eax + addl $3921069994,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,76(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 20(%r15),%r8d + addb %dl,%al + movl 84(%rsi),%ebx + addl $3593408605,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,80(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 40(%r15),%r11d + addb %dl,%bl + movl 88(%rsi),%eax + addl $38016083,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,84(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 60(%r15),%r10d + addb %dl,%al + movl 92(%rsi),%ebx + addl $3634488961,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,88(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 16(%r15),%r9d + addb %dl,%bl + movl 96(%rsi),%eax + addl $3889429448,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,92(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 36(%r15),%r8d + addb %dl,%al + movl 100(%rsi),%ebx + addl $568446438,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,96(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 56(%r15),%r11d + addb %dl,%bl + movl 104(%rsi),%eax + addl $3275163606,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,100(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 12(%r15),%r10d + addb %dl,%al + movl 108(%rsi),%ebx + addl $4107603335,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,104(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 32(%r15),%r9d + addb %dl,%bl + movl 112(%rsi),%eax + addl $1163531501,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,108(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r10d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r11d,%r12d + addl 52(%r15),%r8d + addb %dl,%al + movl 116(%rsi),%ebx + addl $2850285829,%r8d + xorl %r10d,%r12d + movzbl %al,%eax + movl %edx,112(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $5,%r8d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r10d,%r12d + addl 8(%r15),%r11d + addb %dl,%bl + movl 120(%rsi),%eax + addl $4243563512,%r11d + xorl %r9d,%r12d + movzbl %bl,%ebx + movl %edx,116(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $9,%r11d + movl %r8d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + andl %r9d,%r12d + addl 28(%r15),%r10d + addb %dl,%al + movl 124(%rsi),%ebx + addl $1735328473,%r10d + xorl %r8d,%r12d + movzbl %al,%eax + movl %edx,120(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $14,%r10d + movl %r11d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 16(%r13),%xmm3 + addb $32,%bpl + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + andl %r8d,%r12d + addl 48(%r15),%r9d + addb %dl,%bl + movl 0(%rdi,%rbp,4),%eax + addl $2368359562,%r9d + xorl %r11d,%r12d + movzbl %bl,%ebx + movl %edx,124(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $20,%r9d + movl %r11d,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movq %rcx,%rsi + xorq %rcx,%rcx + movb %sil,%cl + leaq (%rdi,%rbp,4),%rsi + psllq $8,%xmm1 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 20(%r15),%r8d + addb %dl,%al + movl 4(%rsi),%ebx + addl $4294588738,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,0(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 32(%r15),%r11d + addb %dl,%bl + movl 8(%rsi),%eax + addl $2272392833,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,4(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 44(%r15),%r10d + addb %dl,%al + movl 12(%rsi),%ebx + addl $1839030562,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,8(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 56(%r15),%r9d + addb %dl,%bl + movl 16(%rsi),%eax + addl $4259657740,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,12(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 4(%r15),%r8d + addb %dl,%al + movl 20(%rsi),%ebx + addl $2763975236,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,16(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 16(%r15),%r11d + addb %dl,%bl + movl 24(%rsi),%eax + addl $1272893353,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,20(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 28(%r15),%r10d + addb %dl,%al + movl 28(%rsi),%ebx + addl $4139469664,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,24(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 40(%r15),%r9d + addb %dl,%bl + movl 32(%rsi),%eax + addl $3200236656,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,28(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 52(%r15),%r8d + addb %dl,%al + movl 36(%rsi),%ebx + addl $681279174,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,32(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 0(%r15),%r11d + addb %dl,%bl + movl 40(%rsi),%eax + addl $3936430074,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,36(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 12(%r15),%r10d + addb %dl,%al + movl 44(%rsi),%ebx + addl $3572445317,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,40(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 24(%r15),%r9d + addb %dl,%bl + movl 48(%rsi),%eax + addl $76029189,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,44(%rsi) + addb %al,%cl + roll $23,%r9d + movl %r11d,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r9d,%r12d + addl 36(%r15),%r8d + addb %dl,%al + movl 52(%rsi),%ebx + addl $3654602809,%r8d + movzbl %al,%eax + addl %r12d,%r8d + movl %edx,48(%rsi) + addb %bl,%cl + roll $4,%r8d + movl %r10d,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r8d,%r12d + addl 48(%r15),%r11d + addb %dl,%bl + movl 56(%rsi),%eax + addl $3873151461,%r11d + movzbl %bl,%ebx + addl %r12d,%r11d + movl %edx,52(%rsi) + addb %al,%cl + roll $11,%r11d + movl %r9d,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %eax,(%rdi,%rcx,4) + xorl %r11d,%r12d + addl 60(%r15),%r10d + addb %dl,%al + movl 60(%rsi),%ebx + addl $530742520,%r10d + movzbl %al,%eax + addl %r12d,%r10d + movl %edx,56(%rsi) + addb %bl,%cl + roll $16,%r10d + movl %r8d,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 32(%r13),%xmm4 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %ebx,(%rdi,%rcx,4) + xorl %r10d,%r12d + addl 8(%r15),%r9d + addb %dl,%bl + movl 64(%rsi),%eax + addl $3299628645,%r9d + movzbl %bl,%ebx + addl %r12d,%r9d + movl %edx,60(%rsi) + addb %al,%cl + roll $23,%r9d + movl $-1,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + psllq $8,%xmm1 + pxor %xmm0,%xmm4 + pxor %xmm1,%xmm4 + pxor %xmm0,%xmm0 + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 0(%r15),%r8d + addb %dl,%al + movl 68(%rsi),%ebx + addl $4096336452,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,64(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + movd (%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + pxor %xmm1,%xmm1 + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 28(%r15),%r11d + addb %dl,%bl + movl 72(%rsi),%eax + addl $1126891415,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,68(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + movd (%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 56(%r15),%r10d + addb %dl,%al + movl 76(%rsi),%ebx + addl $2878612391,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,72(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $1,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 20(%r15),%r9d + addb %dl,%bl + movl 80(%rsi),%eax + addl $4237533241,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,76(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $1,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 48(%r15),%r8d + addb %dl,%al + movl 84(%rsi),%ebx + addl $1700485571,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,80(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $2,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 12(%r15),%r11d + addb %dl,%bl + movl 88(%rsi),%eax + addl $2399980690,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,84(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $2,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 40(%r15),%r10d + addb %dl,%al + movl 92(%rsi),%ebx + addl $4293915773,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,88(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $3,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 4(%r15),%r9d + addb %dl,%bl + movl 96(%rsi),%eax + addl $2240044497,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,92(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $3,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 32(%r15),%r8d + addb %dl,%al + movl 100(%rsi),%ebx + addl $1873313359,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,96(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $4,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 60(%r15),%r11d + addb %dl,%bl + movl 104(%rsi),%eax + addl $4264355552,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,100(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $4,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 24(%r15),%r10d + addb %dl,%al + movl 108(%rsi),%ebx + addl $2734768916,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,104(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $5,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 52(%r15),%r9d + addb %dl,%bl + movl 112(%rsi),%eax + addl $1309151649,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,108(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $5,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movl (%rdi,%rcx,4),%edx + xorl %r11d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r9d,%r12d + addl 16(%r15),%r8d + addb %dl,%al + movl 116(%rsi),%ebx + addl $4149444226,%r8d + movzbl %al,%eax + xorl %r10d,%r12d + movl %edx,112(%rsi) + addl %r12d,%r8d + addb %bl,%cl + roll $6,%r8d + movl $-1,%r12d + pinsrw $6,(%rdi,%rax,4),%xmm0 + + addl %r9d,%r8d + movl (%rdi,%rcx,4),%edx + xorl %r10d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r8d,%r12d + addl 44(%r15),%r11d + addb %dl,%bl + movl 120(%rsi),%eax + addl $3174756917,%r11d + movzbl %bl,%ebx + xorl %r9d,%r12d + movl %edx,116(%rsi) + addl %r12d,%r11d + addb %al,%cl + roll $10,%r11d + movl $-1,%r12d + pinsrw $6,(%rdi,%rbx,4),%xmm1 + + addl %r8d,%r11d + movl (%rdi,%rcx,4),%edx + xorl %r9d,%r12d + movl %eax,(%rdi,%rcx,4) + orl %r11d,%r12d + addl 8(%r15),%r10d + addb %dl,%al + movl 124(%rsi),%ebx + addl $718787259,%r10d + movzbl %al,%eax + xorl %r8d,%r12d + movl %edx,120(%rsi) + addl %r12d,%r10d + addb %bl,%cl + roll $15,%r10d + movl $-1,%r12d + pinsrw $7,(%rdi,%rax,4),%xmm0 + + addl %r11d,%r10d + movdqu 48(%r13),%xmm5 + addb $32,%bpl + movl (%rdi,%rcx,4),%edx + xorl %r8d,%r12d + movl %ebx,(%rdi,%rcx,4) + orl %r10d,%r12d + addl 36(%r15),%r9d + addb %dl,%bl + movl 0(%rdi,%rbp,4),%eax + addl $3951481745,%r9d + movzbl %bl,%ebx + xorl %r11d,%r12d + movl %edx,124(%rsi) + addl %r12d,%r9d + addb %al,%cl + roll $21,%r9d + movl $-1,%r12d + pinsrw $7,(%rdi,%rbx,4),%xmm1 + + addl %r10d,%r9d + movq %rbp,%rsi + xorq %rbp,%rbp + movb %sil,%bpl + movq %rcx,%rsi + xorq %rcx,%rcx + movb %sil,%cl + leaq (%rdi,%rbp,4),%rsi + psllq $8,%xmm1 + pxor %xmm0,%xmm5 + pxor %xmm1,%xmm5 + addl 0(%rsp),%r8d + addl 4(%rsp),%r9d + addl 8(%rsp),%r10d + addl 12(%rsp),%r11d + + movdqu %xmm2,(%r14,%r13,1) + movdqu %xmm3,16(%r14,%r13,1) + movdqu %xmm4,32(%r14,%r13,1) + movdqu %xmm5,48(%r14,%r13,1) + leaq 64(%r15),%r15 + leaq 64(%r13),%r13 + cmpq 16(%rsp),%r15 + jb .Loop + + movq 24(%rsp),%r12 + subb %al,%cl + movl %r8d,0(%r12) + movl %r9d,4(%r12) + movl %r10d,8(%r12) + movl %r11d,12(%r12) + subb $1,%bpl + movl %ebp,-8(%rdi) + movl %ecx,-4(%rdi) + + movq 40(%rsp),%r15 +.cfi_restore %r15 + movq 48(%rsp),%r14 +.cfi_restore %r14 + movq 56(%rsp),%r13 +.cfi_restore %r13 + movq 64(%rsp),%r12 +.cfi_restore %r12 + movq 72(%rsp),%rbp +.cfi_restore %rbp + movq 80(%rsp),%rbx +.cfi_restore %rbx + leaq 88(%rsp),%rsp +.cfi_adjust_cfa_offset -88 +.Lepilogue: +.Labort: + .byte 0xf3,0xc3 +.cfi_endproc +.size rc4_md5_enc,.-rc4_md5_enc + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/rc4/rc4-x86_64.S b/crypto/openssl/crypto/rc4/rc4-x86_64.S new file mode 100644 index 000000000000..20dac93ddfe9 --- /dev/null +++ b/crypto/openssl/crypto/rc4/rc4-x86_64.S @@ -0,0 +1,656 @@ +.text + + +.globl RC4 +.type RC4,@function +.align 16 +RC4: +.cfi_startproc +.byte 243,15,30,250 + orq %rsi,%rsi + jne .Lentry + .byte 0xf3,0xc3 +.Lentry: + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-24 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-32 +.Lprologue: + movq %rsi,%r11 + movq %rdx,%r12 + movq %rcx,%r13 + xorq %r10,%r10 + xorq %rcx,%rcx + + leaq 8(%rdi),%rdi + movb -8(%rdi),%r10b + movb -4(%rdi),%cl + cmpl $-1,256(%rdi) + je .LRC4_CHAR + movl OPENSSL_ia32cap_P(%rip),%r8d + xorq %rbx,%rbx + incb %r10b + subq %r10,%rbx + subq %r12,%r13 + movl (%rdi,%r10,4),%eax + testq $-16,%r11 + jz .Lloop1 + btl $30,%r8d + jc .Lintel + andq $7,%rbx + leaq 1(%r10),%rsi + jz .Loop8 + subq %rbx,%r11 +.Loop8_warmup: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r12,%r13,1) + leaq 1(%r12),%r12 + decq %rbx + jnz .Loop8_warmup + + leaq 1(%r10),%rsi + jmp .Loop8 +.align 16 +.Loop8: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 0(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,0(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 4(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,4(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 8(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,8(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 12(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,12(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 16(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,16(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl 20(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,20(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl 24(%rdi,%rsi,4),%ebx + rorq $8,%r8 + movl %edx,24(%rdi,%r10,4) + addb %al,%dl + movb (%rdi,%rdx,4),%r8b + addb $8,%sil + addb %bl,%cl + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + movl -4(%rdi,%rsi,4),%eax + rorq $8,%r8 + movl %edx,28(%rdi,%r10,4) + addb %bl,%dl + movb (%rdi,%rdx,4),%r8b + addb $8,%r10b + rorq $8,%r8 + subq $8,%r11 + + xorq (%r12),%r8 + movq %r8,(%r12,%r13,1) + leaq 8(%r12),%r12 + + testq $-8,%r11 + jnz .Loop8 + cmpq $0,%r11 + jne .Lloop1 + jmp .Lexit + +.align 16 +.Lintel: + testq $-32,%r11 + jz .Lloop1 + andq $15,%rbx + jz .Loop16_is_hot + subq %rbx,%r11 +.Loop16_warmup: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r12,%r13,1) + leaq 1(%r12),%r12 + decq %rbx + jnz .Loop16_warmup + + movq %rcx,%rbx + xorq %rcx,%rcx + movb %bl,%cl + +.Loop16_is_hot: + leaq (%rdi,%r10,4),%rsi + addb %al,%cl + movl (%rdi,%rcx,4),%edx + pxor %xmm0,%xmm0 + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 4(%rsi),%ebx + movzbl %al,%eax + movl %edx,0(%rsi) + addb %bl,%cl + pinsrw $0,(%rdi,%rax,4),%xmm0 + jmp .Loop16_enter +.align 16 +.Loop16: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + pxor %xmm0,%xmm2 + psllq $8,%xmm1 + pxor %xmm0,%xmm0 + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 4(%rsi),%ebx + movzbl %al,%eax + movl %edx,0(%rsi) + pxor %xmm1,%xmm2 + addb %bl,%cl + pinsrw $0,(%rdi,%rax,4),%xmm0 + movdqu %xmm2,(%r12,%r13,1) + leaq 16(%r12),%r12 +.Loop16_enter: + movl (%rdi,%rcx,4),%edx + pxor %xmm1,%xmm1 + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 8(%rsi),%eax + movzbl %bl,%ebx + movl %edx,4(%rsi) + addb %al,%cl + pinsrw $0,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 12(%rsi),%ebx + movzbl %al,%eax + movl %edx,8(%rsi) + addb %bl,%cl + pinsrw $1,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 16(%rsi),%eax + movzbl %bl,%ebx + movl %edx,12(%rsi) + addb %al,%cl + pinsrw $1,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 20(%rsi),%ebx + movzbl %al,%eax + movl %edx,16(%rsi) + addb %bl,%cl + pinsrw $2,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 24(%rsi),%eax + movzbl %bl,%ebx + movl %edx,20(%rsi) + addb %al,%cl + pinsrw $2,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 28(%rsi),%ebx + movzbl %al,%eax + movl %edx,24(%rsi) + addb %bl,%cl + pinsrw $3,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 32(%rsi),%eax + movzbl %bl,%ebx + movl %edx,28(%rsi) + addb %al,%cl + pinsrw $3,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 36(%rsi),%ebx + movzbl %al,%eax + movl %edx,32(%rsi) + addb %bl,%cl + pinsrw $4,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 40(%rsi),%eax + movzbl %bl,%ebx + movl %edx,36(%rsi) + addb %al,%cl + pinsrw $4,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 44(%rsi),%ebx + movzbl %al,%eax + movl %edx,40(%rsi) + addb %bl,%cl + pinsrw $5,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 48(%rsi),%eax + movzbl %bl,%ebx + movl %edx,44(%rsi) + addb %al,%cl + pinsrw $5,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 52(%rsi),%ebx + movzbl %al,%eax + movl %edx,48(%rsi) + addb %bl,%cl + pinsrw $6,(%rdi,%rax,4),%xmm0 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movl 56(%rsi),%eax + movzbl %bl,%ebx + movl %edx,52(%rsi) + addb %al,%cl + pinsrw $6,(%rdi,%rbx,4),%xmm1 + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + addb %dl,%al + movl 60(%rsi),%ebx + movzbl %al,%eax + movl %edx,56(%rsi) + addb %bl,%cl + pinsrw $7,(%rdi,%rax,4),%xmm0 + addb $16,%r10b + movdqu (%r12),%xmm2 + movl (%rdi,%rcx,4),%edx + movl %ebx,(%rdi,%rcx,4) + addb %dl,%bl + movzbl %bl,%ebx + movl %edx,60(%rsi) + leaq (%rdi,%r10,4),%rsi + pinsrw $7,(%rdi,%rbx,4),%xmm1 + movl (%rsi),%eax + movq %rcx,%rbx + xorq %rcx,%rcx + subq $16,%r11 + movb %bl,%cl + testq $-16,%r11 + jnz .Loop16 + + psllq $8,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm1,%xmm2 + movdqu %xmm2,(%r12,%r13,1) + leaq 16(%r12),%r12 + + cmpq $0,%r11 + jne .Lloop1 + jmp .Lexit + +.align 16 +.Lloop1: + addb %al,%cl + movl (%rdi,%rcx,4),%edx + movl %eax,(%rdi,%rcx,4) + movl %edx,(%rdi,%r10,4) + addb %dl,%al + incb %r10b + movl (%rdi,%rax,4),%edx + movl (%rdi,%r10,4),%eax + xorb (%r12),%dl + movb %dl,(%r12,%r13,1) + leaq 1(%r12),%r12 + decq %r11 + jnz .Lloop1 + jmp .Lexit + +.align 16 +.LRC4_CHAR: + addb $1,%r10b + movzbl (%rdi,%r10,1),%eax + testq $-8,%r11 + jz .Lcloop1 + jmp .Lcloop8 +.align 16 +.Lcloop8: + movl (%r12),%r8d + movl 4(%r12),%r9d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov0 + movq %rax,%rbx +.Lcmov0: + addb %al,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov1 + movq %rbx,%rax +.Lcmov1: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov2 + movq %rax,%rbx +.Lcmov2: + addb %al,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov3 + movq %rbx,%rax +.Lcmov3: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r8b + rorl $8,%r8d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov4 + movq %rax,%rbx +.Lcmov4: + addb %al,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov5 + movq %rbx,%rax +.Lcmov5: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %al,%cl + leaq 1(%r10),%rsi + movzbl (%rdi,%rcx,1),%edx + movzbl %sil,%esi + movzbl (%rdi,%rsi,1),%ebx + movb %al,(%rdi,%rcx,1) + cmpq %rsi,%rcx + movb %dl,(%rdi,%r10,1) + jne .Lcmov6 + movq %rax,%rbx +.Lcmov6: + addb %al,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + addb %bl,%cl + leaq 1(%rsi),%r10 + movzbl (%rdi,%rcx,1),%edx + movzbl %r10b,%r10d + movzbl (%rdi,%r10,1),%eax + movb %bl,(%rdi,%rcx,1) + cmpq %r10,%rcx + movb %dl,(%rdi,%rsi,1) + jne .Lcmov7 + movq %rbx,%rax +.Lcmov7: + addb %bl,%dl + xorb (%rdi,%rdx,1),%r9b + rorl $8,%r9d + leaq -8(%r11),%r11 + movl %r8d,(%r13) + leaq 8(%r12),%r12 + movl %r9d,4(%r13) + leaq 8(%r13),%r13 + + testq $-8,%r11 + jnz .Lcloop8 + cmpq $0,%r11 + jne .Lcloop1 + jmp .Lexit +.align 16 +.Lcloop1: + addb %al,%cl + movzbl %cl,%ecx + movzbl (%rdi,%rcx,1),%edx + movb %al,(%rdi,%rcx,1) + movb %dl,(%rdi,%r10,1) + addb %al,%dl + addb $1,%r10b + movzbl %dl,%edx + movzbl %r10b,%r10d + movzbl (%rdi,%rdx,1),%edx + movzbl (%rdi,%r10,1),%eax + xorb (%r12),%dl + leaq 1(%r12),%r12 + movb %dl,(%r13) + leaq 1(%r13),%r13 + subq $1,%r11 + jnz .Lcloop1 + jmp .Lexit + +.align 16 +.Lexit: + subb $1,%r10b + movl %r10d,-8(%rdi) + movl %ecx,-4(%rdi) + + movq (%rsp),%r13 +.cfi_restore %r13 + movq 8(%rsp),%r12 +.cfi_restore %r12 + movq 16(%rsp),%rbx +.cfi_restore %rbx + addq $24,%rsp +.cfi_adjust_cfa_offset -24 +.Lepilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size RC4,.-RC4 +.globl RC4_set_key +.type RC4_set_key,@function +.align 16 +RC4_set_key: +.cfi_startproc +.byte 243,15,30,250 + leaq 8(%rdi),%rdi + leaq (%rdx,%rsi,1),%rdx + negq %rsi + movq %rsi,%rcx + xorl %eax,%eax + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + + movl OPENSSL_ia32cap_P(%rip),%r8d + btl $20,%r8d + jc .Lc1stloop + jmp .Lw1stloop + +.align 16 +.Lw1stloop: + movl %eax,(%rdi,%rax,4) + addb $1,%al + jnc .Lw1stloop + + xorq %r9,%r9 + xorq %r8,%r8 +.align 16 +.Lw2ndloop: + movl (%rdi,%r9,4),%r10d + addb (%rdx,%rsi,1),%r8b + addb %r10b,%r8b + addq $1,%rsi + movl (%rdi,%r8,4),%r11d + cmovzq %rcx,%rsi + movl %r10d,(%rdi,%r8,4) + movl %r11d,(%rdi,%r9,4) + addb $1,%r9b + jnc .Lw2ndloop + jmp .Lexit_key + +.align 16 +.Lc1stloop: + movb %al,(%rdi,%rax,1) + addb $1,%al + jnc .Lc1stloop + + xorq %r9,%r9 + xorq %r8,%r8 +.align 16 +.Lc2ndloop: + movb (%rdi,%r9,1),%r10b + addb (%rdx,%rsi,1),%r8b + addb %r10b,%r8b + addq $1,%rsi + movb (%rdi,%r8,1),%r11b + jnz .Lcnowrap + movq %rcx,%rsi +.Lcnowrap: + movb %r10b,(%rdi,%r8,1) + movb %r11b,(%rdi,%r9,1) + addb $1,%r9b + jnc .Lc2ndloop + movl $-1,256(%rdi) + +.align 16 +.Lexit_key: + xorl %eax,%eax + movl %eax,-8(%rdi) + movl %eax,-4(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size RC4_set_key,.-RC4_set_key + +.globl RC4_options +.type RC4_options,@function +.align 16 +RC4_options: +.cfi_startproc +.byte 243,15,30,250 + leaq .Lopts(%rip),%rax + movl OPENSSL_ia32cap_P(%rip),%edx + btl $20,%edx + jc .L8xchar + btl $30,%edx + jnc .Ldone + addq $25,%rax + .byte 0xf3,0xc3 +.L8xchar: + addq $12,%rax +.Ldone: + .byte 0xf3,0xc3 +.cfi_endproc +.align 64 +.Lopts: +.byte 114,99,52,40,56,120,44,105,110,116,41,0 +.byte 114,99,52,40,56,120,44,99,104,97,114,41,0 +.byte 114,99,52,40,49,54,120,44,105,110,116,41,0 +.byte 82,67,52,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 +.size RC4_options,.-RC4_options + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/rc4/rc4_enc.c b/crypto/openssl/crypto/rc4/rc4_enc.c index 09ef6a896f07..4015332757e3 100644 --- a/crypto/openssl/crypto/rc4/rc4_enc.c +++ b/crypto/openssl/crypto/rc4/rc4_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC4 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc4_local.h" diff --git a/crypto/openssl/crypto/rc4/rc4_local.h b/crypto/openssl/crypto/rc4/rc4_local.h index e739be4be793..f8cf9a89b3eb 100644 --- a/crypto/openssl/crypto/rc4/rc4_local.h +++ b/crypto/openssl/crypto/rc4/rc4_local.h @@ -1,7 +1,7 @@ /* * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/rc4/rc4_skey.c b/crypto/openssl/crypto/rc4/rc4_skey.c index 100eb79c2ada..3797eff3e2b7 100644 --- a/crypto/openssl/crypto/rc4/rc4_skey.c +++ b/crypto/openssl/crypto/rc4/rc4_skey.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC4 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc4_local.h" #include diff --git a/crypto/openssl/crypto/rc5/asm/rc5-586.pl b/crypto/openssl/crypto/rc5/asm/rc5-586.pl index af11be816259..6def6fcacb0f 100755 --- a/crypto/openssl/crypto/rc5/asm/rc5-586.pl +++ b/crypto/openssl/crypto/rc5/asm/rc5-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -12,8 +12,7 @@ push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; require "cbc.pl"; -$output = pop; -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/openssl/crypto/rc5/build.info b/crypto/openssl/crypto/rc5/build.info index 928a62cd85bf..1b396252bb5c 100644 --- a/crypto/openssl/crypto/rc5/build.info +++ b/crypto/openssl/crypto/rc5/build.info @@ -1,7 +1,26 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - rc5_skey.c rc5_ecb.c {- $target{rc5_asm_src} -} rc5cfb64.c rc5ofb64.c -GENERATE[rc5-586.s]=asm/rc5-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) -DEPEND[rc5-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl +$RC5ASM=rc5_enc.c +IF[{- !$disabled{asm} -}] + $RC5ASM_x86=rc5-586.S + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$RC5ASM_{- $target{asm_arch} -}] + $RC5ASM=$RC5ASM_{- $target{asm_arch} -} + $RC5DEF=RC5_ASM + ENDIF +ENDIF + +$ALL=rc5_skey.c rc5_ecb.c $RC5ASM rc5cfb64.c rc5ofb64.c + +SOURCE[../../libcrypto]=$ALL + +# When all deprecated symbols are removed, libcrypto doesn't export the +# rc5 functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=$ALL +ENDIF + +GENERATE[rc5-586.S]=asm/rc5-586.pl +DEPEND[rc5-586.S]=../perlasm/x86asm.pl ../perlasm/cbc.pl diff --git a/crypto/openssl/crypto/rc5/rc5_ecb.c b/crypto/openssl/crypto/rc5/rc5_ecb.c index 94ec646390dd..e533b9ea7e19 100644 --- a/crypto/openssl/crypto/rc5/rc5_ecb.c +++ b/crypto/openssl/crypto/rc5/rc5_ecb.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc5_local.h" #include diff --git a/crypto/openssl/crypto/rc5/rc5_enc.c b/crypto/openssl/crypto/rc5/rc5_enc.c index 75ddeb2eaf2b..2f9feee0e0f8 100644 --- a/crypto/openssl/crypto/rc5/rc5_enc.c +++ b/crypto/openssl/crypto/rc5/rc5_enc.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include #include "rc5_local.h" diff --git a/crypto/openssl/crypto/rc5/rc5_local.h b/crypto/openssl/crypto/rc5/rc5_local.h index 41130fe33be4..df7df608dc07 100644 --- a/crypto/openssl/crypto/rc5/rc5_local.h +++ b/crypto/openssl/crypto/rc5/rc5_local.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/rc5/rc5_skey.c b/crypto/openssl/crypto/rc5/rc5_skey.c index b2e6bbb1af24..a08b940badf6 100644 --- a/crypto/openssl/crypto/rc5/rc5_skey.c +++ b/crypto/openssl/crypto/rc5/rc5_skey.c @@ -1,21 +1,30 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc5_local.h" -void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, - int rounds) +int RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, + int rounds) { RC5_32_INT L[64], l, ll, A, B, *S, k; int i, j, m, c, t, ii, jj; + if (len > 255) + return 0; + if ((rounds != RC5_16_ROUNDS) && (rounds != RC5_12_ROUNDS) && (rounds != RC5_8_ROUNDS)) rounds = RC5_16_ROUNDS; @@ -58,4 +67,6 @@ void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, if (++jj >= c) jj = 0; } + + return 1; } diff --git a/crypto/openssl/crypto/rc5/rc5cfb64.c b/crypto/openssl/crypto/rc5/rc5cfb64.c index cfce7ec1e84c..9088eb7eddae 100644 --- a/crypto/openssl/crypto/rc5/rc5cfb64.c +++ b/crypto/openssl/crypto/rc5/rc5cfb64.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc5_local.h" diff --git a/crypto/openssl/crypto/rc5/rc5ofb64.c b/crypto/openssl/crypto/rc5/rc5ofb64.c index 224eb968579c..b1128b1f4806 100644 --- a/crypto/openssl/crypto/rc5/rc5ofb64.c +++ b/crypto/openssl/crypto/rc5/rc5ofb64.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RC5 low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + #include #include "rc5_local.h" diff --git a/crypto/openssl/crypto/ripemd/asm/rmd-586.pl b/crypto/openssl/crypto/ripemd/asm/rmd-586.pl index e8d02812ba5e..354bf44e20a1 100755 --- a/crypto/openssl/crypto/ripemd/asm/rmd-586.pl +++ b/crypto/openssl/crypto/ripemd/asm/rmd-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -16,8 +16,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/openssl/crypto/ripemd/build.info b/crypto/openssl/crypto/ripemd/build.info index a4a894e2d1f9..17acec0bedcf 100644 --- a/crypto/openssl/crypto/ripemd/build.info +++ b/crypto/openssl/crypto/ripemd/build.info @@ -1,7 +1,29 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - rmd_dgst.c rmd_one.c {- $target{rmd160_asm_src} -} -GENERATE[rmd-586.s]=asm/rmd-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) -DEPEND[rmd-586.s]=../perlasm/x86asm.pl +$RMD160ASM= +IF[{- !$disabled{asm} -}] + $RMD160ASM_x86=rmd-586.S + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$RMD160ASM_{- $target{asm_arch} -}] + $RMD160ASM=$RMD160ASM_{- $target{asm_arch} -} + $RMD160DEF=RMD160_ASM + ENDIF +ENDIF + +# Implementations are now spread across several libraries, so the defines +# need to be applied to all affected libraries and modules + +SOURCE[../../libcrypto]=rmd_dgst.c rmd_one.c $RMD160ASM +DEFINE[../../libcrypto]=$RMD160DEF + +# When all deprecated symbols are removed, libcrypto doesn't export the +# RIPEMD160 functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=rmd_dgst.c rmd_one.c $RMD160ASM + DEFINE[../../providers/liblegacy.a]=$RMD160DEF +ENDIF + +GENERATE[rmd-586.S]=asm/rmd-586.pl +DEPEND[rmd-586.S]=../perlasm/x86asm.pl diff --git a/crypto/openssl/crypto/ripemd/rmd-586.S b/crypto/openssl/crypto/ripemd/rmd-586.S new file mode 100644 index 000000000000..4f3ea459c99d --- /dev/null +++ b/crypto/openssl/crypto/ripemd/rmd-586.S @@ -0,0 +1,1986 @@ +.text +.globl ripemd160_block_asm_data_order +.type ripemd160_block_asm_data_order,@function +.align 16 +ripemd160_block_asm_data_order: +.L_ripemd160_block_asm_data_order_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl 4(%esp),%edx + movl 8(%esp),%eax + pushl %esi + movl (%edx),%ecx + pushl %edi + movl 4(%edx),%esi + pushl %ebp + movl 8(%edx),%edi + pushl %ebx + subl $108,%esp +.L000start: + + movl (%eax),%ebx + movl 4(%eax),%ebp + movl %ebx,(%esp) + movl %ebp,4(%esp) + movl 8(%eax),%ebx + movl 12(%eax),%ebp + movl %ebx,8(%esp) + movl %ebp,12(%esp) + movl 16(%eax),%ebx + movl 20(%eax),%ebp + movl %ebx,16(%esp) + movl %ebp,20(%esp) + movl 24(%eax),%ebx + movl 28(%eax),%ebp + movl %ebx,24(%esp) + movl %ebp,28(%esp) + movl 32(%eax),%ebx + movl 36(%eax),%ebp + movl %ebx,32(%esp) + movl %ebp,36(%esp) + movl 40(%eax),%ebx + movl 44(%eax),%ebp + movl %ebx,40(%esp) + movl %ebp,44(%esp) + movl 48(%eax),%ebx + movl 52(%eax),%ebp + movl %ebx,48(%esp) + movl %ebp,52(%esp) + movl 56(%eax),%ebx + movl 60(%eax),%ebp + movl %ebx,56(%esp) + movl %ebp,60(%esp) + movl %edi,%eax + movl 12(%edx),%ebx + movl 16(%edx),%ebp + + xorl %ebx,%eax + movl (%esp),%edx + xorl %esi,%eax + addl %edx,%ecx + roll $10,%edi + addl %eax,%ecx + movl %esi,%eax + roll $11,%ecx + addl %ebp,%ecx + + xorl %edi,%eax + movl 4(%esp),%edx + xorl %ecx,%eax + addl %eax,%ebp + movl %ecx,%eax + roll $10,%esi + addl %edx,%ebp + xorl %esi,%eax + roll $14,%ebp + addl %ebx,%ebp + + movl 8(%esp),%edx + xorl %ebp,%eax + addl %edx,%ebx + roll $10,%ecx + addl %eax,%ebx + movl %ebp,%eax + roll $15,%ebx + addl %edi,%ebx + + xorl %ecx,%eax + movl 12(%esp),%edx + xorl %ebx,%eax + addl %eax,%edi + movl %ebx,%eax + roll $10,%ebp + addl %edx,%edi + xorl %ebp,%eax + roll $12,%edi + addl %esi,%edi + + movl 16(%esp),%edx + xorl %edi,%eax + addl %edx,%esi + roll $10,%ebx + addl %eax,%esi + movl %edi,%eax + roll $5,%esi + addl %ecx,%esi + + xorl %ebx,%eax + movl 20(%esp),%edx + xorl %esi,%eax + addl %eax,%ecx + movl %esi,%eax + roll $10,%edi + addl %edx,%ecx + xorl %edi,%eax + roll $8,%ecx + addl %ebp,%ecx + + movl 24(%esp),%edx + xorl %ecx,%eax + addl %edx,%ebp + roll $10,%esi + addl %eax,%ebp + movl %ecx,%eax + roll $7,%ebp + addl %ebx,%ebp + + xorl %esi,%eax + movl 28(%esp),%edx + xorl %ebp,%eax + addl %eax,%ebx + movl %ebp,%eax + roll $10,%ecx + addl %edx,%ebx + xorl %ecx,%eax + roll $9,%ebx + addl %edi,%ebx + + movl 32(%esp),%edx + xorl %ebx,%eax + addl %edx,%edi + roll $10,%ebp + addl %eax,%edi + movl %ebx,%eax + roll $11,%edi + addl %esi,%edi + + xorl %ebp,%eax + movl 36(%esp),%edx + xorl %edi,%eax + addl %eax,%esi + movl %edi,%eax + roll $10,%ebx + addl %edx,%esi + xorl %ebx,%eax + roll $13,%esi + addl %ecx,%esi + + movl 40(%esp),%edx + xorl %esi,%eax + addl %edx,%ecx + roll $10,%edi + addl %eax,%ecx + movl %esi,%eax + roll $14,%ecx + addl %ebp,%ecx + + xorl %edi,%eax + movl 44(%esp),%edx + xorl %ecx,%eax + addl %eax,%ebp + movl %ecx,%eax + roll $10,%esi + addl %edx,%ebp + xorl %esi,%eax + roll $15,%ebp + addl %ebx,%ebp + + movl 48(%esp),%edx + xorl %ebp,%eax + addl %edx,%ebx + roll $10,%ecx + addl %eax,%ebx + movl %ebp,%eax + roll $6,%ebx + addl %edi,%ebx + + xorl %ecx,%eax + movl 52(%esp),%edx + xorl %ebx,%eax + addl %eax,%edi + movl %ebx,%eax + roll $10,%ebp + addl %edx,%edi + xorl %ebp,%eax + roll $7,%edi + addl %esi,%edi + + movl 56(%esp),%edx + xorl %edi,%eax + addl %edx,%esi + roll $10,%ebx + addl %eax,%esi + movl %edi,%eax + roll $9,%esi + addl %ecx,%esi + + xorl %ebx,%eax + movl 60(%esp),%edx + xorl %esi,%eax + addl %eax,%ecx + movl $-1,%eax + roll $10,%edi + addl %edx,%ecx + movl 28(%esp),%edx + roll $8,%ecx + addl %ebp,%ecx + + addl %edx,%ebp + movl %esi,%edx + subl %ecx,%eax + andl %ecx,%edx + andl %edi,%eax + orl %eax,%edx + movl 16(%esp),%eax + roll $10,%esi + leal 1518500249(%ebp,%edx,1),%ebp + movl $-1,%edx + roll $7,%ebp + addl %ebx,%ebp + + addl %eax,%ebx + movl %ecx,%eax + subl %ebp,%edx + andl %ebp,%eax + andl %esi,%edx + orl %edx,%eax + movl 52(%esp),%edx + roll $10,%ecx + leal 1518500249(%ebx,%eax,1),%ebx + movl $-1,%eax + roll $6,%ebx + addl %edi,%ebx + + addl %edx,%edi + movl %ebp,%edx + subl %ebx,%eax + andl %ebx,%edx + andl %ecx,%eax + orl %eax,%edx + movl 4(%esp),%eax + roll $10,%ebp + leal 1518500249(%edi,%edx,1),%edi + movl $-1,%edx + roll $8,%edi + addl %esi,%edi + + addl %eax,%esi + movl %ebx,%eax + subl %edi,%edx + andl %edi,%eax + andl %ebp,%edx + orl %edx,%eax + movl 40(%esp),%edx + roll $10,%ebx + leal 1518500249(%esi,%eax,1),%esi + movl $-1,%eax + roll $13,%esi + addl %ecx,%esi + + addl %edx,%ecx + movl %edi,%edx + subl %esi,%eax + andl %esi,%edx + andl %ebx,%eax + orl %eax,%edx + movl 24(%esp),%eax + roll $10,%edi + leal 1518500249(%ecx,%edx,1),%ecx + movl $-1,%edx + roll $11,%ecx + addl %ebp,%ecx + + addl %eax,%ebp + movl %esi,%eax + subl %ecx,%edx + andl %ecx,%eax + andl %edi,%edx + orl %edx,%eax + movl 60(%esp),%edx + roll $10,%esi + leal 1518500249(%ebp,%eax,1),%ebp + movl $-1,%eax + roll $9,%ebp + addl %ebx,%ebp + + addl %edx,%ebx + movl %ecx,%edx + subl %ebp,%eax + andl %ebp,%edx + andl %esi,%eax + orl %eax,%edx + movl 12(%esp),%eax + roll $10,%ecx + leal 1518500249(%ebx,%edx,1),%ebx + movl $-1,%edx + roll $7,%ebx + addl %edi,%ebx + + addl %eax,%edi + movl %ebp,%eax + subl %ebx,%edx + andl %ebx,%eax + andl %ecx,%edx + orl %edx,%eax + movl 48(%esp),%edx + roll $10,%ebp + leal 1518500249(%edi,%eax,1),%edi + movl $-1,%eax + roll $15,%edi + addl %esi,%edi + + addl %edx,%esi + movl %ebx,%edx + subl %edi,%eax + andl %edi,%edx + andl %ebp,%eax + orl %eax,%edx + movl (%esp),%eax + roll $10,%ebx + leal 1518500249(%esi,%edx,1),%esi + movl $-1,%edx + roll $7,%esi + addl %ecx,%esi + + addl %eax,%ecx + movl %edi,%eax + subl %esi,%edx + andl %esi,%eax + andl %ebx,%edx + orl %edx,%eax + movl 36(%esp),%edx + roll $10,%edi + leal 1518500249(%ecx,%eax,1),%ecx + movl $-1,%eax + roll $12,%ecx + addl %ebp,%ecx + + addl %edx,%ebp + movl %esi,%edx + subl %ecx,%eax + andl %ecx,%edx + andl %edi,%eax + orl %eax,%edx + movl 20(%esp),%eax + roll $10,%esi + leal 1518500249(%ebp,%edx,1),%ebp + movl $-1,%edx + roll $15,%ebp + addl %ebx,%ebp + + addl %eax,%ebx + movl %ecx,%eax + subl %ebp,%edx + andl %ebp,%eax + andl %esi,%edx + orl %edx,%eax + movl 8(%esp),%edx + roll $10,%ecx + leal 1518500249(%ebx,%eax,1),%ebx + movl $-1,%eax + roll $9,%ebx + addl %edi,%ebx + + addl %edx,%edi + movl %ebp,%edx + subl %ebx,%eax + andl %ebx,%edx + andl %ecx,%eax + orl %eax,%edx + movl 56(%esp),%eax + roll $10,%ebp + leal 1518500249(%edi,%edx,1),%edi + movl $-1,%edx + roll $11,%edi + addl %esi,%edi + + addl %eax,%esi + movl %ebx,%eax + subl %edi,%edx + andl %edi,%eax + andl %ebp,%edx + orl %edx,%eax + movl 44(%esp),%edx + roll $10,%ebx + leal 1518500249(%esi,%eax,1),%esi + movl $-1,%eax + roll $7,%esi + addl %ecx,%esi + + addl %edx,%ecx + movl %edi,%edx + subl %esi,%eax + andl %esi,%edx + andl %ebx,%eax + orl %eax,%edx + movl 32(%esp),%eax + roll $10,%edi + leal 1518500249(%ecx,%edx,1),%ecx + movl $-1,%edx + roll $13,%ecx + addl %ebp,%ecx + + addl %eax,%ebp + movl %esi,%eax + subl %ecx,%edx + andl %ecx,%eax + andl %edi,%edx + orl %edx,%eax + movl $-1,%edx + roll $10,%esi + leal 1518500249(%ebp,%eax,1),%ebp + subl %ecx,%edx + roll $12,%ebp + addl %ebx,%ebp + + movl 12(%esp),%eax + orl %ebp,%edx + addl %eax,%ebx + xorl %esi,%edx + movl $-1,%eax + roll $10,%ecx + leal 1859775393(%ebx,%edx,1),%ebx + subl %ebp,%eax + roll $11,%ebx + addl %edi,%ebx + + movl 40(%esp),%edx + orl %ebx,%eax + addl %edx,%edi + xorl %ecx,%eax + movl $-1,%edx + roll $10,%ebp + leal 1859775393(%edi,%eax,1),%edi + subl %ebx,%edx + roll $13,%edi + addl %esi,%edi + + movl 56(%esp),%eax + orl %edi,%edx + addl %eax,%esi + xorl %ebp,%edx + movl $-1,%eax + roll $10,%ebx + leal 1859775393(%esi,%edx,1),%esi + subl %edi,%eax + roll $6,%esi + addl %ecx,%esi + + movl 16(%esp),%edx + orl %esi,%eax + addl %edx,%ecx + xorl %ebx,%eax + movl $-1,%edx + roll $10,%edi + leal 1859775393(%ecx,%eax,1),%ecx + subl %esi,%edx + roll $7,%ecx + addl %ebp,%ecx + + movl 36(%esp),%eax + orl %ecx,%edx + addl %eax,%ebp + xorl %edi,%edx + movl $-1,%eax + roll $10,%esi + leal 1859775393(%ebp,%edx,1),%ebp + subl %ecx,%eax + roll $14,%ebp + addl %ebx,%ebp + + movl 60(%esp),%edx + orl %ebp,%eax + addl %edx,%ebx + xorl %esi,%eax + movl $-1,%edx + roll $10,%ecx + leal 1859775393(%ebx,%eax,1),%ebx + subl %ebp,%edx + roll $9,%ebx + addl %edi,%ebx + + movl 32(%esp),%eax + orl %ebx,%edx + addl %eax,%edi + xorl %ecx,%edx + movl $-1,%eax + roll $10,%ebp + leal 1859775393(%edi,%edx,1),%edi + subl %ebx,%eax + roll $13,%edi + addl %esi,%edi + + movl 4(%esp),%edx + orl %edi,%eax + addl %edx,%esi + xorl %ebp,%eax + movl $-1,%edx + roll $10,%ebx + leal 1859775393(%esi,%eax,1),%esi + subl %edi,%edx + roll $15,%esi + addl %ecx,%esi + + movl 8(%esp),%eax + orl %esi,%edx + addl %eax,%ecx + xorl %ebx,%edx + movl $-1,%eax + roll $10,%edi + leal 1859775393(%ecx,%edx,1),%ecx + subl %esi,%eax + roll $14,%ecx + addl %ebp,%ecx + + movl 28(%esp),%edx + orl %ecx,%eax + addl %edx,%ebp + xorl %edi,%eax + movl $-1,%edx + roll $10,%esi + leal 1859775393(%ebp,%eax,1),%ebp + subl %ecx,%edx + roll $8,%ebp + addl %ebx,%ebp + + movl (%esp),%eax + orl %ebp,%edx + addl %eax,%ebx + xorl %esi,%edx + movl $-1,%eax + roll $10,%ecx + leal 1859775393(%ebx,%edx,1),%ebx + subl %ebp,%eax + roll $13,%ebx + addl %edi,%ebx + + movl 24(%esp),%edx + orl %ebx,%eax + addl %edx,%edi + xorl %ecx,%eax + movl $-1,%edx + roll $10,%ebp + leal 1859775393(%edi,%eax,1),%edi + subl %ebx,%edx + roll $6,%edi + addl %esi,%edi + + movl 52(%esp),%eax + orl %edi,%edx + addl %eax,%esi + xorl %ebp,%edx + movl $-1,%eax + roll $10,%ebx + leal 1859775393(%esi,%edx,1),%esi + subl %edi,%eax + roll $5,%esi + addl %ecx,%esi + + movl 44(%esp),%edx + orl %esi,%eax + addl %edx,%ecx + xorl %ebx,%eax + movl $-1,%edx + roll $10,%edi + leal 1859775393(%ecx,%eax,1),%ecx + subl %esi,%edx + roll $12,%ecx + addl %ebp,%ecx + + movl 20(%esp),%eax + orl %ecx,%edx + addl %eax,%ebp + xorl %edi,%edx + movl $-1,%eax + roll $10,%esi + leal 1859775393(%ebp,%edx,1),%ebp + subl %ecx,%eax + roll $7,%ebp + addl %ebx,%ebp + + movl 48(%esp),%edx + orl %ebp,%eax + addl %edx,%ebx + xorl %esi,%eax + movl $-1,%edx + roll $10,%ecx + leal 1859775393(%ebx,%eax,1),%ebx + movl %ecx,%eax + roll $5,%ebx + addl %edi,%ebx + + subl %ecx,%edx + andl %ebx,%eax + andl %ebp,%edx + orl %eax,%edx + movl 4(%esp),%eax + roll $10,%ebp + leal 2400959708(%edi,%edx,1),%edi + movl $-1,%edx + addl %eax,%edi + movl %ebp,%eax + roll $11,%edi + addl %esi,%edi + + subl %ebp,%edx + andl %edi,%eax + andl %ebx,%edx + orl %eax,%edx + movl 36(%esp),%eax + roll $10,%ebx + leal 2400959708(%esi,%edx,1),%esi + movl $-1,%edx + addl %eax,%esi + movl %ebx,%eax + roll $12,%esi + addl %ecx,%esi + + subl %ebx,%edx + andl %esi,%eax + andl %edi,%edx + orl %eax,%edx + movl 44(%esp),%eax + roll $10,%edi + leal 2400959708(%ecx,%edx,1),%ecx + movl $-1,%edx + addl %eax,%ecx + movl %edi,%eax + roll $14,%ecx + addl %ebp,%ecx + + subl %edi,%edx + andl %ecx,%eax + andl %esi,%edx + orl %eax,%edx + movl 40(%esp),%eax + roll $10,%esi + leal 2400959708(%ebp,%edx,1),%ebp + movl $-1,%edx + addl %eax,%ebp + movl %esi,%eax + roll $15,%ebp + addl %ebx,%ebp + + subl %esi,%edx + andl %ebp,%eax + andl %ecx,%edx + orl %eax,%edx + movl (%esp),%eax + roll $10,%ecx + leal 2400959708(%ebx,%edx,1),%ebx + movl $-1,%edx + addl %eax,%ebx + movl %ecx,%eax + roll $14,%ebx + addl %edi,%ebx + + subl %ecx,%edx + andl %ebx,%eax + andl %ebp,%edx + orl %eax,%edx + movl 32(%esp),%eax + roll $10,%ebp + leal 2400959708(%edi,%edx,1),%edi + movl $-1,%edx + addl %eax,%edi + movl %ebp,%eax + roll $15,%edi + addl %esi,%edi + + subl %ebp,%edx + andl %edi,%eax + andl %ebx,%edx + orl %eax,%edx + movl 48(%esp),%eax + roll $10,%ebx + leal 2400959708(%esi,%edx,1),%esi + movl $-1,%edx + addl %eax,%esi + movl %ebx,%eax + roll $9,%esi + addl %ecx,%esi + + subl %ebx,%edx + andl %esi,%eax + andl %edi,%edx + orl %eax,%edx + movl 16(%esp),%eax + roll $10,%edi + leal 2400959708(%ecx,%edx,1),%ecx + movl $-1,%edx + addl %eax,%ecx + movl %edi,%eax + roll $8,%ecx + addl %ebp,%ecx + + subl %edi,%edx + andl %ecx,%eax + andl %esi,%edx + orl %eax,%edx + movl 52(%esp),%eax + roll $10,%esi + leal 2400959708(%ebp,%edx,1),%ebp + movl $-1,%edx + addl %eax,%ebp + movl %esi,%eax + roll $9,%ebp + addl %ebx,%ebp + + subl %esi,%edx + andl %ebp,%eax + andl %ecx,%edx + orl %eax,%edx + movl 12(%esp),%eax + roll $10,%ecx + leal 2400959708(%ebx,%edx,1),%ebx + movl $-1,%edx + addl %eax,%ebx + movl %ecx,%eax + roll $14,%ebx + addl %edi,%ebx + + subl %ecx,%edx + andl %ebx,%eax + andl %ebp,%edx + orl %eax,%edx + movl 28(%esp),%eax + roll $10,%ebp + leal 2400959708(%edi,%edx,1),%edi + movl $-1,%edx + addl %eax,%edi + movl %ebp,%eax + roll $5,%edi + addl %esi,%edi + + subl %ebp,%edx + andl %edi,%eax + andl %ebx,%edx + orl %eax,%edx + movl 60(%esp),%eax + roll $10,%ebx + leal 2400959708(%esi,%edx,1),%esi + movl $-1,%edx + addl %eax,%esi + movl %ebx,%eax + roll $6,%esi + addl %ecx,%esi + + subl %ebx,%edx + andl %esi,%eax + andl %edi,%edx + orl %eax,%edx + movl 56(%esp),%eax + roll $10,%edi + leal 2400959708(%ecx,%edx,1),%ecx + movl $-1,%edx + addl %eax,%ecx + movl %edi,%eax + roll $8,%ecx + addl %ebp,%ecx + + subl %edi,%edx + andl %ecx,%eax + andl %esi,%edx + orl %eax,%edx + movl 20(%esp),%eax + roll $10,%esi + leal 2400959708(%ebp,%edx,1),%ebp + movl $-1,%edx + addl %eax,%ebp + movl %esi,%eax + roll $6,%ebp + addl %ebx,%ebp + + subl %esi,%edx + andl %ebp,%eax + andl %ecx,%edx + orl %eax,%edx + movl 24(%esp),%eax + roll $10,%ecx + leal 2400959708(%ebx,%edx,1),%ebx + movl $-1,%edx + addl %eax,%ebx + movl %ecx,%eax + roll $5,%ebx + addl %edi,%ebx + + subl %ecx,%edx + andl %ebx,%eax + andl %ebp,%edx + orl %eax,%edx + movl 8(%esp),%eax + roll $10,%ebp + leal 2400959708(%edi,%edx,1),%edi + movl $-1,%edx + addl %eax,%edi + subl %ebp,%edx + roll $12,%edi + addl %esi,%edi + + movl 16(%esp),%eax + orl %ebx,%edx + addl %eax,%esi + xorl %edi,%edx + movl $-1,%eax + roll $10,%ebx + leal 2840853838(%esi,%edx,1),%esi + subl %ebx,%eax + roll $9,%esi + addl %ecx,%esi + + movl (%esp),%edx + orl %edi,%eax + addl %edx,%ecx + xorl %esi,%eax + movl $-1,%edx + roll $10,%edi + leal 2840853838(%ecx,%eax,1),%ecx + subl %edi,%edx + roll $15,%ecx + addl %ebp,%ecx + + movl 20(%esp),%eax + orl %esi,%edx + addl %eax,%ebp + xorl %ecx,%edx + movl $-1,%eax + roll $10,%esi + leal 2840853838(%ebp,%edx,1),%ebp + subl %esi,%eax + roll $5,%ebp + addl %ebx,%ebp + + movl 36(%esp),%edx + orl %ecx,%eax + addl %edx,%ebx + xorl %ebp,%eax + movl $-1,%edx + roll $10,%ecx + leal 2840853838(%ebx,%eax,1),%ebx + subl %ecx,%edx + roll $11,%ebx + addl %edi,%ebx + + movl 28(%esp),%eax + orl %ebp,%edx + addl %eax,%edi + xorl %ebx,%edx + movl $-1,%eax + roll $10,%ebp + leal 2840853838(%edi,%edx,1),%edi + subl %ebp,%eax + roll $6,%edi + addl %esi,%edi + + movl 48(%esp),%edx + orl %ebx,%eax + addl %edx,%esi + xorl %edi,%eax + movl $-1,%edx + roll $10,%ebx + leal 2840853838(%esi,%eax,1),%esi + subl %ebx,%edx + roll $8,%esi + addl %ecx,%esi + + movl 8(%esp),%eax + orl %edi,%edx + addl %eax,%ecx + xorl %esi,%edx + movl $-1,%eax + roll $10,%edi + leal 2840853838(%ecx,%edx,1),%ecx + subl %edi,%eax + roll $13,%ecx + addl %ebp,%ecx + + movl 40(%esp),%edx + orl %esi,%eax + addl %edx,%ebp + xorl %ecx,%eax + movl $-1,%edx + roll $10,%esi + leal 2840853838(%ebp,%eax,1),%ebp + subl %esi,%edx + roll $12,%ebp + addl %ebx,%ebp + + movl 56(%esp),%eax + orl %ecx,%edx + addl %eax,%ebx + xorl %ebp,%edx + movl $-1,%eax + roll $10,%ecx + leal 2840853838(%ebx,%edx,1),%ebx + subl %ecx,%eax + roll $5,%ebx + addl %edi,%ebx + + movl 4(%esp),%edx + orl %ebp,%eax + addl %edx,%edi + xorl %ebx,%eax + movl $-1,%edx + roll $10,%ebp + leal 2840853838(%edi,%eax,1),%edi + subl %ebp,%edx + roll $12,%edi + addl %esi,%edi + + movl 12(%esp),%eax + orl %ebx,%edx + addl %eax,%esi + xorl %edi,%edx + movl $-1,%eax + roll $10,%ebx + leal 2840853838(%esi,%edx,1),%esi + subl %ebx,%eax + roll $13,%esi + addl %ecx,%esi + + movl 32(%esp),%edx + orl %edi,%eax + addl %edx,%ecx + xorl %esi,%eax + movl $-1,%edx + roll $10,%edi + leal 2840853838(%ecx,%eax,1),%ecx + subl %edi,%edx + roll $14,%ecx + addl %ebp,%ecx + + movl 44(%esp),%eax + orl %esi,%edx + addl %eax,%ebp + xorl %ecx,%edx + movl $-1,%eax + roll $10,%esi + leal 2840853838(%ebp,%edx,1),%ebp + subl %esi,%eax + roll $11,%ebp + addl %ebx,%ebp + + movl 24(%esp),%edx + orl %ecx,%eax + addl %edx,%ebx + xorl %ebp,%eax + movl $-1,%edx + roll $10,%ecx + leal 2840853838(%ebx,%eax,1),%ebx + subl %ecx,%edx + roll $8,%ebx + addl %edi,%ebx + + movl 60(%esp),%eax + orl %ebp,%edx + addl %eax,%edi + xorl %ebx,%edx + movl $-1,%eax + roll $10,%ebp + leal 2840853838(%edi,%edx,1),%edi + subl %ebp,%eax + roll $5,%edi + addl %esi,%edi + + movl 52(%esp),%edx + orl %ebx,%eax + addl %edx,%esi + xorl %edi,%eax + movl 128(%esp),%edx + roll $10,%ebx + leal 2840853838(%esi,%eax,1),%esi + movl %ecx,64(%esp) + roll $6,%esi + addl %ecx,%esi + movl (%edx),%ecx + movl %esi,68(%esp) + movl %edi,72(%esp) + movl 4(%edx),%esi + movl %ebx,76(%esp) + movl 8(%edx),%edi + movl %ebp,80(%esp) + movl 12(%edx),%ebx + movl 16(%edx),%ebp + + movl $-1,%edx + subl %ebx,%edx + movl 20(%esp),%eax + orl %edi,%edx + addl %eax,%ecx + xorl %esi,%edx + movl $-1,%eax + roll $10,%edi + leal 1352829926(%ecx,%edx,1),%ecx + subl %edi,%eax + roll $8,%ecx + addl %ebp,%ecx + + movl 56(%esp),%edx + orl %esi,%eax + addl %edx,%ebp + xorl %ecx,%eax + movl $-1,%edx + roll $10,%esi + leal 1352829926(%ebp,%eax,1),%ebp + subl %esi,%edx + roll $9,%ebp + addl %ebx,%ebp + + movl 28(%esp),%eax + orl %ecx,%edx + addl %eax,%ebx + xorl %ebp,%edx + movl $-1,%eax + roll $10,%ecx + leal 1352829926(%ebx,%edx,1),%ebx + subl %ecx,%eax + roll $9,%ebx + addl %edi,%ebx + + movl (%esp),%edx + orl %ebp,%eax + addl %edx,%edi + xorl %ebx,%eax + movl $-1,%edx + roll $10,%ebp + leal 1352829926(%edi,%eax,1),%edi + subl %ebp,%edx + roll $11,%edi + addl %esi,%edi + + movl 36(%esp),%eax + orl %ebx,%edx + addl %eax,%esi + xorl %edi,%edx + movl $-1,%eax + roll $10,%ebx + leal 1352829926(%esi,%edx,1),%esi + subl %ebx,%eax + roll $13,%esi + addl %ecx,%esi + + movl 8(%esp),%edx + orl %edi,%eax + addl %edx,%ecx + xorl %esi,%eax + movl $-1,%edx + roll $10,%edi + leal 1352829926(%ecx,%eax,1),%ecx + subl %edi,%edx + roll $15,%ecx + addl %ebp,%ecx + + movl 44(%esp),%eax + orl %esi,%edx + addl %eax,%ebp + xorl %ecx,%edx + movl $-1,%eax + roll $10,%esi + leal 1352829926(%ebp,%edx,1),%ebp + subl %esi,%eax + roll $15,%ebp + addl %ebx,%ebp + + movl 16(%esp),%edx + orl %ecx,%eax + addl %edx,%ebx + xorl %ebp,%eax + movl $-1,%edx + roll $10,%ecx + leal 1352829926(%ebx,%eax,1),%ebx + subl %ecx,%edx + roll $5,%ebx + addl %edi,%ebx + + movl 52(%esp),%eax + orl %ebp,%edx + addl %eax,%edi + xorl %ebx,%edx + movl $-1,%eax + roll $10,%ebp + leal 1352829926(%edi,%edx,1),%edi + subl %ebp,%eax + roll $7,%edi + addl %esi,%edi + + movl 24(%esp),%edx + orl %ebx,%eax + addl %edx,%esi + xorl %edi,%eax + movl $-1,%edx + roll $10,%ebx + leal 1352829926(%esi,%eax,1),%esi + subl %ebx,%edx + roll $7,%esi + addl %ecx,%esi + + movl 60(%esp),%eax + orl %edi,%edx + addl %eax,%ecx + xorl %esi,%edx + movl $-1,%eax + roll $10,%edi + leal 1352829926(%ecx,%edx,1),%ecx + subl %edi,%eax + roll $8,%ecx + addl %ebp,%ecx + + movl 32(%esp),%edx + orl %esi,%eax + addl %edx,%ebp + xorl %ecx,%eax + movl $-1,%edx + roll $10,%esi + leal 1352829926(%ebp,%eax,1),%ebp + subl %esi,%edx + roll $11,%ebp + addl %ebx,%ebp + + movl 4(%esp),%eax + orl %ecx,%edx + addl %eax,%ebx + xorl %ebp,%edx + movl $-1,%eax + roll $10,%ecx + leal 1352829926(%ebx,%edx,1),%ebx + subl %ecx,%eax + roll $14,%ebx + addl %edi,%ebx + + movl 40(%esp),%edx + orl %ebp,%eax + addl %edx,%edi + xorl %ebx,%eax + movl $-1,%edx + roll $10,%ebp + leal 1352829926(%edi,%eax,1),%edi + subl %ebp,%edx + roll $14,%edi + addl %esi,%edi + + movl 12(%esp),%eax + orl %ebx,%edx + addl %eax,%esi + xorl %edi,%edx + movl $-1,%eax + roll $10,%ebx + leal 1352829926(%esi,%edx,1),%esi + subl %ebx,%eax + roll $12,%esi + addl %ecx,%esi + + movl 48(%esp),%edx + orl %edi,%eax + addl %edx,%ecx + xorl %esi,%eax + movl $-1,%edx + roll $10,%edi + leal 1352829926(%ecx,%eax,1),%ecx + movl %edi,%eax + roll $6,%ecx + addl %ebp,%ecx + + subl %edi,%edx + andl %ecx,%eax + andl %esi,%edx + orl %eax,%edx + movl 24(%esp),%eax + roll $10,%esi + leal 1548603684(%ebp,%edx,1),%ebp + movl $-1,%edx + addl %eax,%ebp + movl %esi,%eax + roll $9,%ebp + addl %ebx,%ebp + + subl %esi,%edx + andl %ebp,%eax + andl %ecx,%edx + orl %eax,%edx + movl 44(%esp),%eax + roll $10,%ecx + leal 1548603684(%ebx,%edx,1),%ebx + movl $-1,%edx + addl %eax,%ebx + movl %ecx,%eax + roll $13,%ebx + addl %edi,%ebx + + subl %ecx,%edx + andl %ebx,%eax + andl %ebp,%edx + orl %eax,%edx + movl 12(%esp),%eax + roll $10,%ebp + leal 1548603684(%edi,%edx,1),%edi + movl $-1,%edx + addl %eax,%edi + movl %ebp,%eax + roll $15,%edi + addl %esi,%edi + + subl %ebp,%edx + andl %edi,%eax + andl %ebx,%edx + orl %eax,%edx + movl 28(%esp),%eax + roll $10,%ebx + leal 1548603684(%esi,%edx,1),%esi + movl $-1,%edx + addl %eax,%esi + movl %ebx,%eax + roll $7,%esi + addl %ecx,%esi + + subl %ebx,%edx + andl %esi,%eax + andl %edi,%edx + orl %eax,%edx + movl (%esp),%eax + roll $10,%edi + leal 1548603684(%ecx,%edx,1),%ecx + movl $-1,%edx + addl %eax,%ecx + movl %edi,%eax + roll $12,%ecx + addl %ebp,%ecx + + subl %edi,%edx + andl %ecx,%eax + andl %esi,%edx + orl %eax,%edx + movl 52(%esp),%eax + roll $10,%esi + leal 1548603684(%ebp,%edx,1),%ebp + movl $-1,%edx + addl %eax,%ebp + movl %esi,%eax + roll $8,%ebp + addl %ebx,%ebp + + subl %esi,%edx + andl %ebp,%eax + andl %ecx,%edx + orl %eax,%edx + movl 20(%esp),%eax + roll $10,%ecx + leal 1548603684(%ebx,%edx,1),%ebx + movl $-1,%edx + addl %eax,%ebx + movl %ecx,%eax + roll $9,%ebx + addl %edi,%ebx + + subl %ecx,%edx + andl %ebx,%eax + andl %ebp,%edx + orl %eax,%edx + movl 40(%esp),%eax + roll $10,%ebp + leal 1548603684(%edi,%edx,1),%edi + movl $-1,%edx + addl %eax,%edi + movl %ebp,%eax + roll $11,%edi + addl %esi,%edi + + subl %ebp,%edx + andl %edi,%eax + andl %ebx,%edx + orl %eax,%edx + movl 56(%esp),%eax + roll $10,%ebx + leal 1548603684(%esi,%edx,1),%esi + movl $-1,%edx + addl %eax,%esi + movl %ebx,%eax + roll $7,%esi + addl %ecx,%esi + + subl %ebx,%edx + andl %esi,%eax + andl %edi,%edx + orl %eax,%edx + movl 60(%esp),%eax + roll $10,%edi + leal 1548603684(%ecx,%edx,1),%ecx + movl $-1,%edx + addl %eax,%ecx + movl %edi,%eax + roll $7,%ecx + addl %ebp,%ecx + + subl %edi,%edx + andl %ecx,%eax + andl %esi,%edx + orl %eax,%edx + movl 32(%esp),%eax + roll $10,%esi + leal 1548603684(%ebp,%edx,1),%ebp + movl $-1,%edx + addl %eax,%ebp + movl %esi,%eax + roll $12,%ebp + addl %ebx,%ebp + + subl %esi,%edx + andl %ebp,%eax + andl %ecx,%edx + orl %eax,%edx + movl 48(%esp),%eax + roll $10,%ecx + leal 1548603684(%ebx,%edx,1),%ebx + movl $-1,%edx + addl %eax,%ebx + movl %ecx,%eax + roll $7,%ebx + addl %edi,%ebx + + subl %ecx,%edx + andl %ebx,%eax + andl %ebp,%edx + orl %eax,%edx + movl 16(%esp),%eax + roll $10,%ebp + leal 1548603684(%edi,%edx,1),%edi + movl $-1,%edx + addl %eax,%edi + movl %ebp,%eax + roll $6,%edi + addl %esi,%edi + + subl %ebp,%edx + andl %edi,%eax + andl %ebx,%edx + orl %eax,%edx + movl 36(%esp),%eax + roll $10,%ebx + leal 1548603684(%esi,%edx,1),%esi + movl $-1,%edx + addl %eax,%esi + movl %ebx,%eax + roll $15,%esi + addl %ecx,%esi + + subl %ebx,%edx + andl %esi,%eax + andl %edi,%edx + orl %eax,%edx + movl 4(%esp),%eax + roll $10,%edi + leal 1548603684(%ecx,%edx,1),%ecx + movl $-1,%edx + addl %eax,%ecx + movl %edi,%eax + roll $13,%ecx + addl %ebp,%ecx + + subl %edi,%edx + andl %ecx,%eax + andl %esi,%edx + orl %eax,%edx + movl 8(%esp),%eax + roll $10,%esi + leal 1548603684(%ebp,%edx,1),%ebp + movl $-1,%edx + addl %eax,%ebp + subl %ecx,%edx + roll $11,%ebp + addl %ebx,%ebp + + movl 60(%esp),%eax + orl %ebp,%edx + addl %eax,%ebx + xorl %esi,%edx + movl $-1,%eax + roll $10,%ecx + leal 1836072691(%ebx,%edx,1),%ebx + subl %ebp,%eax + roll $9,%ebx + addl %edi,%ebx + + movl 20(%esp),%edx + orl %ebx,%eax + addl %edx,%edi + xorl %ecx,%eax + movl $-1,%edx + roll $10,%ebp + leal 1836072691(%edi,%eax,1),%edi + subl %ebx,%edx + roll $7,%edi + addl %esi,%edi + + movl 4(%esp),%eax + orl %edi,%edx + addl %eax,%esi + xorl %ebp,%edx + movl $-1,%eax + roll $10,%ebx + leal 1836072691(%esi,%edx,1),%esi + subl %edi,%eax + roll $15,%esi + addl %ecx,%esi + + movl 12(%esp),%edx + orl %esi,%eax + addl %edx,%ecx + xorl %ebx,%eax + movl $-1,%edx + roll $10,%edi + leal 1836072691(%ecx,%eax,1),%ecx + subl %esi,%edx + roll $11,%ecx + addl %ebp,%ecx + + movl 28(%esp),%eax + orl %ecx,%edx + addl %eax,%ebp + xorl %edi,%edx + movl $-1,%eax + roll $10,%esi + leal 1836072691(%ebp,%edx,1),%ebp + subl %ecx,%eax + roll $8,%ebp + addl %ebx,%ebp + + movl 56(%esp),%edx + orl %ebp,%eax + addl %edx,%ebx + xorl %esi,%eax + movl $-1,%edx + roll $10,%ecx + leal 1836072691(%ebx,%eax,1),%ebx + subl %ebp,%edx + roll $6,%ebx + addl %edi,%ebx + + movl 24(%esp),%eax + orl %ebx,%edx + addl %eax,%edi + xorl %ecx,%edx + movl $-1,%eax + roll $10,%ebp + leal 1836072691(%edi,%edx,1),%edi + subl %ebx,%eax + roll $6,%edi + addl %esi,%edi + + movl 36(%esp),%edx + orl %edi,%eax + addl %edx,%esi + xorl %ebp,%eax + movl $-1,%edx + roll $10,%ebx + leal 1836072691(%esi,%eax,1),%esi + subl %edi,%edx + roll $14,%esi + addl %ecx,%esi + + movl 44(%esp),%eax + orl %esi,%edx + addl %eax,%ecx + xorl %ebx,%edx + movl $-1,%eax + roll $10,%edi + leal 1836072691(%ecx,%edx,1),%ecx + subl %esi,%eax + roll $12,%ecx + addl %ebp,%ecx + + movl 32(%esp),%edx + orl %ecx,%eax + addl %edx,%ebp + xorl %edi,%eax + movl $-1,%edx + roll $10,%esi + leal 1836072691(%ebp,%eax,1),%ebp + subl %ecx,%edx + roll $13,%ebp + addl %ebx,%ebp + + movl 48(%esp),%eax + orl %ebp,%edx + addl %eax,%ebx + xorl %esi,%edx + movl $-1,%eax + roll $10,%ecx + leal 1836072691(%ebx,%edx,1),%ebx + subl %ebp,%eax + roll $5,%ebx + addl %edi,%ebx + + movl 8(%esp),%edx + orl %ebx,%eax + addl %edx,%edi + xorl %ecx,%eax + movl $-1,%edx + roll $10,%ebp + leal 1836072691(%edi,%eax,1),%edi + subl %ebx,%edx + roll $14,%edi + addl %esi,%edi + + movl 40(%esp),%eax + orl %edi,%edx + addl %eax,%esi + xorl %ebp,%edx + movl $-1,%eax + roll $10,%ebx + leal 1836072691(%esi,%edx,1),%esi + subl %edi,%eax + roll $13,%esi + addl %ecx,%esi + + movl (%esp),%edx + orl %esi,%eax + addl %edx,%ecx + xorl %ebx,%eax + movl $-1,%edx + roll $10,%edi + leal 1836072691(%ecx,%eax,1),%ecx + subl %esi,%edx + roll $13,%ecx + addl %ebp,%ecx + + movl 16(%esp),%eax + orl %ecx,%edx + addl %eax,%ebp + xorl %edi,%edx + movl $-1,%eax + roll $10,%esi + leal 1836072691(%ebp,%edx,1),%ebp + subl %ecx,%eax + roll $7,%ebp + addl %ebx,%ebp + + movl 52(%esp),%edx + orl %ebp,%eax + addl %edx,%ebx + xorl %esi,%eax + movl 32(%esp),%edx + roll $10,%ecx + leal 1836072691(%ebx,%eax,1),%ebx + movl $-1,%eax + roll $5,%ebx + addl %edi,%ebx + + addl %edx,%edi + movl %ebp,%edx + subl %ebx,%eax + andl %ebx,%edx + andl %ecx,%eax + orl %eax,%edx + movl 24(%esp),%eax + roll $10,%ebp + leal 2053994217(%edi,%edx,1),%edi + movl $-1,%edx + roll $15,%edi + addl %esi,%edi + + addl %eax,%esi + movl %ebx,%eax + subl %edi,%edx + andl %edi,%eax + andl %ebp,%edx + orl %edx,%eax + movl 16(%esp),%edx + roll $10,%ebx + leal 2053994217(%esi,%eax,1),%esi + movl $-1,%eax + roll $5,%esi + addl %ecx,%esi + + addl %edx,%ecx + movl %edi,%edx + subl %esi,%eax + andl %esi,%edx + andl %ebx,%eax + orl %eax,%edx + movl 4(%esp),%eax + roll $10,%edi + leal 2053994217(%ecx,%edx,1),%ecx + movl $-1,%edx + roll $8,%ecx + addl %ebp,%ecx + + addl %eax,%ebp + movl %esi,%eax + subl %ecx,%edx + andl %ecx,%eax + andl %edi,%edx + orl %edx,%eax + movl 12(%esp),%edx + roll $10,%esi + leal 2053994217(%ebp,%eax,1),%ebp + movl $-1,%eax + roll $11,%ebp + addl %ebx,%ebp + + addl %edx,%ebx + movl %ecx,%edx + subl %ebp,%eax + andl %ebp,%edx + andl %esi,%eax + orl %eax,%edx + movl 44(%esp),%eax + roll $10,%ecx + leal 2053994217(%ebx,%edx,1),%ebx + movl $-1,%edx + roll $14,%ebx + addl %edi,%ebx + + addl %eax,%edi + movl %ebp,%eax + subl %ebx,%edx + andl %ebx,%eax + andl %ecx,%edx + orl %edx,%eax + movl 60(%esp),%edx + roll $10,%ebp + leal 2053994217(%edi,%eax,1),%edi + movl $-1,%eax + roll $14,%edi + addl %esi,%edi + + addl %edx,%esi + movl %ebx,%edx + subl %edi,%eax + andl %edi,%edx + andl %ebp,%eax + orl %eax,%edx + movl (%esp),%eax + roll $10,%ebx + leal 2053994217(%esi,%edx,1),%esi + movl $-1,%edx + roll $6,%esi + addl %ecx,%esi + + addl %eax,%ecx + movl %edi,%eax + subl %esi,%edx + andl %esi,%eax + andl %ebx,%edx + orl %edx,%eax + movl 20(%esp),%edx + roll $10,%edi + leal 2053994217(%ecx,%eax,1),%ecx + movl $-1,%eax + roll $14,%ecx + addl %ebp,%ecx + + addl %edx,%ebp + movl %esi,%edx + subl %ecx,%eax + andl %ecx,%edx + andl %edi,%eax + orl %eax,%edx + movl 48(%esp),%eax + roll $10,%esi + leal 2053994217(%ebp,%edx,1),%ebp + movl $-1,%edx + roll $6,%ebp + addl %ebx,%ebp + + addl %eax,%ebx + movl %ecx,%eax + subl %ebp,%edx + andl %ebp,%eax + andl %esi,%edx + orl %edx,%eax + movl 8(%esp),%edx + roll $10,%ecx + leal 2053994217(%ebx,%eax,1),%ebx + movl $-1,%eax + roll $9,%ebx + addl %edi,%ebx + + addl %edx,%edi + movl %ebp,%edx + subl %ebx,%eax + andl %ebx,%edx + andl %ecx,%eax + orl %eax,%edx + movl 52(%esp),%eax + roll $10,%ebp + leal 2053994217(%edi,%edx,1),%edi + movl $-1,%edx + roll $12,%edi + addl %esi,%edi + + addl %eax,%esi + movl %ebx,%eax + subl %edi,%edx + andl %edi,%eax + andl %ebp,%edx + orl %edx,%eax + movl 36(%esp),%edx + roll $10,%ebx + leal 2053994217(%esi,%eax,1),%esi + movl $-1,%eax + roll $9,%esi + addl %ecx,%esi + + addl %edx,%ecx + movl %edi,%edx + subl %esi,%eax + andl %esi,%edx + andl %ebx,%eax + orl %eax,%edx + movl 28(%esp),%eax + roll $10,%edi + leal 2053994217(%ecx,%edx,1),%ecx + movl $-1,%edx + roll $12,%ecx + addl %ebp,%ecx + + addl %eax,%ebp + movl %esi,%eax + subl %ecx,%edx + andl %ecx,%eax + andl %edi,%edx + orl %edx,%eax + movl 40(%esp),%edx + roll $10,%esi + leal 2053994217(%ebp,%eax,1),%ebp + movl $-1,%eax + roll $5,%ebp + addl %ebx,%ebp + + addl %edx,%ebx + movl %ecx,%edx + subl %ebp,%eax + andl %ebp,%edx + andl %esi,%eax + orl %eax,%edx + movl 56(%esp),%eax + roll $10,%ecx + leal 2053994217(%ebx,%edx,1),%ebx + movl $-1,%edx + roll $15,%ebx + addl %edi,%ebx + + addl %eax,%edi + movl %ebp,%eax + subl %ebx,%edx + andl %ebx,%eax + andl %ecx,%edx + orl %eax,%edx + movl %ebx,%eax + roll $10,%ebp + leal 2053994217(%edi,%edx,1),%edi + xorl %ebp,%eax + roll $8,%edi + addl %esi,%edi + + movl 48(%esp),%edx + xorl %edi,%eax + addl %edx,%esi + roll $10,%ebx + addl %eax,%esi + movl %edi,%eax + roll $8,%esi + addl %ecx,%esi + + xorl %ebx,%eax + movl 60(%esp),%edx + xorl %esi,%eax + addl %eax,%ecx + movl %esi,%eax + roll $10,%edi + addl %edx,%ecx + xorl %edi,%eax + roll $5,%ecx + addl %ebp,%ecx + + movl 40(%esp),%edx + xorl %ecx,%eax + addl %edx,%ebp + roll $10,%esi + addl %eax,%ebp + movl %ecx,%eax + roll $12,%ebp + addl %ebx,%ebp + + xorl %esi,%eax + movl 16(%esp),%edx + xorl %ebp,%eax + addl %eax,%ebx + movl %ebp,%eax + roll $10,%ecx + addl %edx,%ebx + xorl %ecx,%eax + roll $9,%ebx + addl %edi,%ebx + + movl 4(%esp),%edx + xorl %ebx,%eax + addl %edx,%edi + roll $10,%ebp + addl %eax,%edi + movl %ebx,%eax + roll $12,%edi + addl %esi,%edi + + xorl %ebp,%eax + movl 20(%esp),%edx + xorl %edi,%eax + addl %eax,%esi + movl %edi,%eax + roll $10,%ebx + addl %edx,%esi + xorl %ebx,%eax + roll $5,%esi + addl %ecx,%esi + + movl 32(%esp),%edx + xorl %esi,%eax + addl %edx,%ecx + roll $10,%edi + addl %eax,%ecx + movl %esi,%eax + roll $14,%ecx + addl %ebp,%ecx + + xorl %edi,%eax + movl 28(%esp),%edx + xorl %ecx,%eax + addl %eax,%ebp + movl %ecx,%eax + roll $10,%esi + addl %edx,%ebp + xorl %esi,%eax + roll $6,%ebp + addl %ebx,%ebp + + movl 24(%esp),%edx + xorl %ebp,%eax + addl %edx,%ebx + roll $10,%ecx + addl %eax,%ebx + movl %ebp,%eax + roll $8,%ebx + addl %edi,%ebx + + xorl %ecx,%eax + movl 8(%esp),%edx + xorl %ebx,%eax + addl %eax,%edi + movl %ebx,%eax + roll $10,%ebp + addl %edx,%edi + xorl %ebp,%eax + roll $13,%edi + addl %esi,%edi + + movl 52(%esp),%edx + xorl %edi,%eax + addl %edx,%esi + roll $10,%ebx + addl %eax,%esi + movl %edi,%eax + roll $6,%esi + addl %ecx,%esi + + xorl %ebx,%eax + movl 56(%esp),%edx + xorl %esi,%eax + addl %eax,%ecx + movl %esi,%eax + roll $10,%edi + addl %edx,%ecx + xorl %edi,%eax + roll $5,%ecx + addl %ebp,%ecx + + movl (%esp),%edx + xorl %ecx,%eax + addl %edx,%ebp + roll $10,%esi + addl %eax,%ebp + movl %ecx,%eax + roll $15,%ebp + addl %ebx,%ebp + + xorl %esi,%eax + movl 12(%esp),%edx + xorl %ebp,%eax + addl %eax,%ebx + movl %ebp,%eax + roll $10,%ecx + addl %edx,%ebx + xorl %ecx,%eax + roll $13,%ebx + addl %edi,%ebx + + movl 36(%esp),%edx + xorl %ebx,%eax + addl %edx,%edi + roll $10,%ebp + addl %eax,%edi + movl %ebx,%eax + roll $11,%edi + addl %esi,%edi + + xorl %ebp,%eax + movl 44(%esp),%edx + xorl %edi,%eax + addl %eax,%esi + roll $10,%ebx + addl %edx,%esi + movl 128(%esp),%edx + roll $11,%esi + addl %ecx,%esi + movl 4(%edx),%eax + addl %eax,%ebx + movl 72(%esp),%eax + addl %eax,%ebx + movl 8(%edx),%eax + addl %eax,%ebp + movl 76(%esp),%eax + addl %eax,%ebp + movl 12(%edx),%eax + addl %eax,%ecx + movl 80(%esp),%eax + addl %eax,%ecx + movl 16(%edx),%eax + addl %eax,%esi + movl 64(%esp),%eax + addl %eax,%esi + movl (%edx),%eax + addl %eax,%edi + movl 68(%esp),%eax + addl %eax,%edi + movl 136(%esp),%eax + movl %ebx,(%edx) + movl %ebp,4(%edx) + movl %ecx,8(%edx) + subl $1,%eax + movl %esi,12(%edx) + movl %edi,16(%edx) + jle .L001get_out + movl %eax,136(%esp) + movl %ecx,%edi + movl 132(%esp),%eax + movl %ebx,%ecx + addl $64,%eax + movl %ebp,%esi + movl %eax,132(%esp) + jmp .L000start +.L001get_out: + addl $108,%esp + popl %ebx + popl %ebp + popl %edi + popl %esi + ret +.size ripemd160_block_asm_data_order,.-.L_ripemd160_block_asm_data_order_begin + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/ripemd/rmd_dgst.c b/crypto/openssl/crypto/ripemd/rmd_dgst.c index e9e440f18c10..77b9d32d2b14 100644 --- a/crypto/openssl/crypto/ripemd/rmd_dgst.c +++ b/crypto/openssl/crypto/ripemd/rmd_dgst.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RIPEMD160 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "rmd_local.h" #include diff --git a/crypto/openssl/crypto/ripemd/rmd_local.h b/crypto/openssl/crypto/ripemd/rmd_local.h index f3604e349006..325cb98cc309 100644 --- a/crypto/openssl/crypto/ripemd/rmd_local.h +++ b/crypto/openssl/crypto/ripemd/rmd_local.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ripemd/rmd_one.c b/crypto/openssl/crypto/ripemd/rmd_one.c index cc01f15c7f1c..dcd7bae1dc89 100644 --- a/crypto/openssl/crypto/ripemd/rmd_one.c +++ b/crypto/openssl/crypto/ripemd/rmd_one.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RIPEMD160 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/openssl/crypto/ripemd/rmdconst.h b/crypto/openssl/crypto/ripemd/rmdconst.h index b81013239bbe..0e19410ade10 100644 --- a/crypto/openssl/crypto/ripemd/rmdconst.h +++ b/crypto/openssl/crypto/ripemd/rmdconst.h @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/rsa/build.info b/crypto/openssl/crypto/rsa/build.info index 87f924922f63..ad3370db397c 100644 --- a/crypto/openssl/crypto/rsa/build.info +++ b/crypto/openssl/crypto/rsa/build.info @@ -1,6 +1,22 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_saos.c rsa_err.c \ - rsa_pk1.c rsa_ssl.c rsa_none.c rsa_oaep.c rsa_chk.c \ - rsa_pss.c rsa_x931.c rsa_asn1.c rsa_depr.c rsa_ameth.c rsa_prn.c \ - rsa_pmeth.c rsa_crpt.c rsa_x931g.c rsa_meth.c rsa_mp.c + +$COMMON=rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_pk1.c \ + rsa_none.c rsa_oaep.c rsa_chk.c rsa_pss.c rsa_x931.c rsa_crpt.c \ + rsa_sp800_56b_gen.c rsa_sp800_56b_check.c rsa_backend.c \ + rsa_mp_names.c rsa_schemes.c + +SOURCE[../../libcrypto]=$COMMON\ + rsa_saos.c rsa_err.c rsa_asn1.c rsa_ameth.c rsa_prn.c \ + rsa_pmeth.c rsa_meth.c rsa_mp.c +IF[{- !$disabled{'deprecated-0.9.8'} -}] + SOURCE[../../libcrypto]=rsa_depr.c +ENDIF +IF[{- !$disabled{'deprecated-3.0'} -}] + SOURCE[../../libcrypto]=rsa_x931g.c +ENDIF + +SOURCE[../../providers/libfips.a]=$COMMON + +IF[{- !$disabled{'acvp-tests'} -}] + SOURCE[../../providers/libfips.a]=rsa_acvp_test_params.c +ENDIF diff --git a/crypto/openssl/crypto/rsa/rsa_acvp_test_params.c b/crypto/openssl/crypto/rsa/rsa_acvp_test_params.c new file mode 100644 index 000000000000..fddc1e099412 --- /dev/null +++ b/crypto/openssl/crypto/rsa/rsa_acvp_test_params.c @@ -0,0 +1,167 @@ +/* + * Copyright 2020-2021 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 /* memcpy */ +#include +#include +#include "crypto/rsa.h" +#include "rsa_local.h" + +int ossl_rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]) +{ + const OSSL_PARAM *p, *s; + OSSL_PARAM *d, *alloc = NULL; + int ret = 1; + + static const OSSL_PARAM settable[] = { + OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XP, NULL, 0), + OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XP1, NULL, 0), + OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XP2, NULL, 0), + OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XQ, NULL, 0), + OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XQ1, NULL, 0), + OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XQ2, NULL, 0), + OSSL_PARAM_END + }; + + /* Assume the first element is a required field if this feature is used */ + p = OSSL_PARAM_locate_const(src, settable[0].key); + if (p == NULL) + return 1; + + /* Zeroing here means the terminator is always set at the end */ + alloc = OPENSSL_zalloc(sizeof(settable)); + if (alloc == NULL) + return 0; + + d = alloc; + for (s = settable; s->key != NULL; ++s) { + /* If src contains a key from settable then copy the src to the dest */ + p = OSSL_PARAM_locate_const(src, s->key); + if (p != NULL) { + *d = *s; /* shallow copy from the static settable[] */ + d->data_size = p->data_size; + d->data = OPENSSL_memdup(p->data, p->data_size); + if (d->data == NULL) + ret = 0; + ++d; + } + } + if (ret == 0) { + ossl_rsa_acvp_test_gen_params_free(alloc); + alloc = NULL; + } + if (*dst != NULL) + ossl_rsa_acvp_test_gen_params_free(*dst); + *dst = alloc; + return ret; +} + +void ossl_rsa_acvp_test_gen_params_free(OSSL_PARAM *dst) +{ + OSSL_PARAM *p; + + if (dst == NULL) + return; + + for (p = dst; p->key != NULL; ++p) { + OPENSSL_free(p->data); + p->data = NULL; + } + OPENSSL_free(dst); +} + +int ossl_rsa_acvp_test_set_params(RSA *r, const OSSL_PARAM params[]) +{ + RSA_ACVP_TEST *t; + const OSSL_PARAM *p; + + if (r->acvp_test != NULL) { + ossl_rsa_acvp_test_free(r->acvp_test); + r->acvp_test = NULL; + } + + t = OPENSSL_zalloc(sizeof(*t)); + if (t == NULL) + return 0; + + /* Set the input parameters */ + if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP1)) != NULL + && !OSSL_PARAM_get_BN(p, &t->Xp1)) + goto err; + if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP2)) != NULL + && !OSSL_PARAM_get_BN(p, &t->Xp2)) + goto err; + if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP)) != NULL + && !OSSL_PARAM_get_BN(p, &t->Xp)) + goto err; + if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ1)) != NULL + && !OSSL_PARAM_get_BN(p, &t->Xq1)) + goto err; + if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ2)) != NULL + && !OSSL_PARAM_get_BN(p, &t->Xq2)) + goto err; + if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ)) != NULL + && !OSSL_PARAM_get_BN(p, &t->Xq)) + goto err; + + /* Setup the output parameters */ + t->p1 = BN_new(); + t->p2 = BN_new(); + t->q1 = BN_new(); + t->q2 = BN_new(); + r->acvp_test = t; + return 1; +err: + ossl_rsa_acvp_test_free(t); + return 0; +} + +int ossl_rsa_acvp_test_get_params(RSA *r, OSSL_PARAM params[]) +{ + RSA_ACVP_TEST *t; + OSSL_PARAM *p; + + if (r == NULL) + return 0; + + t = r->acvp_test; + if (t != NULL) { + if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_P1)) != NULL + && !OSSL_PARAM_set_BN(p, t->p1)) + return 0; + if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_P2)) != NULL + && !OSSL_PARAM_set_BN(p, t->p2)) + return 0; + if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_Q1)) != NULL + && !OSSL_PARAM_set_BN(p, t->q1)) + return 0; + if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_Q2)) != NULL + && !OSSL_PARAM_set_BN(p, t->q2)) + return 0; + } + return 1; +} + +void ossl_rsa_acvp_test_free(RSA_ACVP_TEST *t) +{ + if (t != NULL) { + BN_free(t->Xp1); + BN_free(t->Xp2); + BN_free(t->Xp); + BN_free(t->Xq1); + BN_free(t->Xq2); + BN_free(t->Xq); + BN_free(t->p1); + BN_free(t->p2); + BN_free(t->q1); + BN_free(t->q2); + OPENSSL_free(t); + } +} + diff --git a/crypto/openssl/crypto/rsa/rsa_ameth.c b/crypto/openssl/crypto/rsa/rsa_ameth.c index 2c9c46ea53c8..61ec53d4244c 100644 --- a/crypto/openssl/crypto/rsa/rsa_ameth.c +++ b/crypto/openssl/crypto/rsa/rsa_ameth.c @@ -1,31 +1,30 @@ /* - * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include #include #include -#include +#include +#include #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/rsa.h" #include "rsa_local.h" -#ifndef OPENSSL_NO_CMS -static int rsa_cms_sign(CMS_SignerInfo *si); -static int rsa_cms_verify(CMS_SignerInfo *si); -static int rsa_cms_decrypt(CMS_RecipientInfo *ri); -static int rsa_cms_encrypt(CMS_RecipientInfo *ri); -#endif - -static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg); - /* Set any parameters associated with pkey */ static int rsa_param_encode(const EVP_PKEY *pkey, ASN1_STRING **pstr, int *pstrtype) @@ -34,7 +33,7 @@ static int rsa_param_encode(const EVP_PKEY *pkey, *pstr = NULL; /* If RSA it's just NULL type */ - if (pkey->ameth->pkey_id != EVP_PKEY_RSA_PSS) { + if (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK) != RSA_FLAG_TYPE_RSASSAPSS) { *pstrtype = V_ASN1_NULL; return 1; } @@ -51,27 +50,6 @@ static int rsa_param_encode(const EVP_PKEY *pkey, return 1; } /* Decode any parameters and set them in RSA structure */ -static int rsa_param_decode(RSA *rsa, const X509_ALGOR *alg) -{ - const ASN1_OBJECT *algoid; - const void *algp; - int algptype; - - X509_ALGOR_get0(&algoid, &algptype, &algp, alg); - if (OBJ_obj2nid(algoid) != EVP_PKEY_RSA_PSS) - return 1; - if (algptype == V_ASN1_UNDEF) - return 1; - if (algptype != V_ASN1_SEQUENCE) { - RSAerr(RSA_F_RSA_PARAM_DECODE, RSA_R_INVALID_PSS_PARAMETERS); - return 0; - } - rsa->pss = rsa_pss_decode(alg); - if (rsa->pss == NULL) - return 0; - return 1; -} - static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { unsigned char *penc = NULL; @@ -92,7 +70,7 @@ static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) return 0; } -static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +static int rsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) { const unsigned char *p; int pklen; @@ -101,14 +79,26 @@ static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &alg, pubkey)) return 0; - if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) { - RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); + if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) return 0; - } - if (!rsa_param_decode(rsa, alg)) { + if (!ossl_rsa_param_decode(rsa, alg)) { RSA_free(rsa); return 0; } + + RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); + switch (pkey->ameth->pkey_id) { + case EVP_PKEY_RSA: + RSA_set_flags(rsa, RSA_FLAG_TYPE_RSA); + break; + case EVP_PKEY_RSA_PSS: + RSA_set_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS); + break; + default: + /* Leave the type bits zero */ + break; + } + if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa)) { RSA_free(rsa); return 0; @@ -138,10 +128,8 @@ static int old_rsa_priv_decode(EVP_PKEY *pkey, { RSA *rsa; - if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) { - RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB); + if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) return 0; - } EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); return 1; } @@ -163,14 +151,14 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); if (rklen <= 0) { - RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); ASN1_STRING_free(str); return 0; } if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, strtype, str, rk, rklen)) { - RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); ASN1_STRING_free(str); OPENSSL_clear_free(rk, rklen); return 0; @@ -181,24 +169,14 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) static int rsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) { - const unsigned char *p; - RSA *rsa; - int pklen; - const X509_ALGOR *alg; + int ret = 0; + RSA *rsa = ossl_rsa_key_from_pkcs8(p8, NULL, NULL); - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &alg, p8)) - return 0; - rsa = d2i_RSAPrivateKey(NULL, &p, pklen); - if (rsa == NULL) { - RSAerr(RSA_F_RSA_PRIV_DECODE, ERR_R_RSA_LIB); - return 0; + if (rsa != NULL) { + ret = 1; + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); } - if (!rsa_param_decode(rsa, alg)) { - RSA_free(rsa); - return 0; - } - EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); - return 1; + return ret; } static int int_rsa_size(const EVP_PKEY *pkey) @@ -221,14 +199,6 @@ static void int_rsa_free(EVP_PKEY *pkey) RSA_free(pkey->pkey.rsa); } -static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) -{ - if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) - return NULL; - return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR), - alg->parameter); -} - static int rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, int indent) { @@ -280,7 +250,7 @@ static int rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, goto err; if (BIO_puts(bp, " with ") <= 0) goto err; - maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + maskHash = ossl_x509_algor_mgf1_decode(pss->maskGenAlgorithm); if (maskHash != NULL) { if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) goto err; @@ -311,7 +281,7 @@ static int rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, if (pss->trailerField) { if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) goto err; - } else if (BIO_puts(bp, "BC (default)") <= 0) { + } else if (BIO_puts(bp, "01 (default)") <= 0) { goto err; } BIO_puts(bp, "\n"); @@ -425,39 +395,18 @@ static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, return pkey_rsa_print(bp, pkey, indent, 1); } -static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg) -{ - RSA_PSS_PARAMS *pss; - - pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_PSS_PARAMS), - alg->parameter); - - if (pss == NULL) - return NULL; - - if (pss->maskGenAlgorithm != NULL) { - pss->maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); - if (pss->maskHash == NULL) { - RSA_PSS_PARAMS_free(pss); - return NULL; - } - } - - return pss; -} - static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) { if (OBJ_obj2nid(sigalg->algorithm) == EVP_PKEY_RSA_PSS) { int rv; - RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); + RSA_PSS_PARAMS *pss = ossl_rsa_pss_decode(sigalg); rv = rsa_pss_param_print(bp, 0, pss, indent); RSA_PSS_PARAMS_free(pss); if (!rv) return 0; - } else if (!sig && BIO_puts(bp, "\n") <= 0) { + } else if (BIO_puts(bp, "\n") <= 0) { return 0; } if (sig) @@ -467,56 +416,19 @@ 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) { - - case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) - PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); - break; - - case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: - if (pkey_is_pss(pkey)) - return -2; - if (arg1 == 0) - PKCS7_RECIP_INFO_get0_alg(arg2, &alg); - break; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) - return rsa_cms_sign(arg2); - else if (arg1 == 1) - return rsa_cms_verify(arg2); - break; - - case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (pkey_is_pss(pkey)) - return -2; - if (arg1 == 0) - return rsa_cms_encrypt(arg2); - else if (arg1 == 1) - return rsa_cms_decrypt(arg2); - break; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - if (pkey_is_pss(pkey)) - return -2; - *(int *)arg2 = CMS_RECIPINFO_TRANS; - return 1; -#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); + if (!ossl_rsa_pss_get_param(pkey->pkey.rsa->pss, &md, &mgf1md, + &min_saltlen)) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); return 0; } - *(int *)arg2 = EVP_MD_type(md); + *(int *)arg2 = EVP_MD_get_type(md); /* Return of 2 indicates this MD is mandatory */ return 2; } @@ -525,66 +437,7 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) default: return -2; - } - - if (alg) - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - - return 1; - -} - -/* allocate and set algorithm ID from EVP_MD, default SHA1 */ -static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) -{ - if (md == NULL || EVP_MD_type(md) == NID_sha1) - return 1; - *palg = X509_ALGOR_new(); - if (*palg == NULL) - return 0; - X509_ALGOR_set_md(*palg, md); - return 1; -} - -/* Allocate and set MGF1 algorithm ID from EVP_MD */ -static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) -{ - X509_ALGOR *algtmp = NULL; - ASN1_STRING *stmp = NULL; - - *palg = NULL; - if (mgf1md == NULL || EVP_MD_type(mgf1md) == NID_sha1) - return 1; - /* need to embed algorithm ID inside another */ - if (!rsa_md_to_algor(&algtmp, mgf1md)) - goto err; - if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL) - goto err; - *palg = X509_ALGOR_new(); - if (*palg == NULL) - goto err; - X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); - stmp = NULL; - err: - ASN1_STRING_free(stmp); - X509_ALGOR_free(algtmp); - if (*palg) - return 1; - return 0; -} - -/* convert algorithm ID to EVP_MD, default SHA1 */ -static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) -{ - const EVP_MD *md; - - if (!alg) - return EVP_sha1(); - md = EVP_get_digestbyobj(alg->algorithm); - if (md == NULL) - RSAerr(RSA_F_RSA_ALGOR_TO_MD, RSA_R_UNKNOWN_DIGEST); - return md; } /* @@ -602,23 +455,23 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) return NULL; if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) return NULL; - if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) + if (EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen) <= 0) return NULL; if (saltlen == -1) { - saltlen = EVP_MD_size(sigmd); + saltlen = EVP_MD_get_size(sigmd); } else if (saltlen == -2 || saltlen == -3) { - saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; - if ((EVP_PKEY_bits(pk) & 0x7) == 1) + saltlen = EVP_PKEY_get_size(pk) - EVP_MD_get_size(sigmd) - 2; + if ((EVP_PKEY_get_bits(pk) & 0x7) == 1) saltlen--; if (saltlen < 0) return NULL; } - return rsa_pss_params_create(sigmd, mgf1md, saltlen); + return ossl_rsa_pss_params_create(sigmd, mgf1md, saltlen); } -RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, - const EVP_MD *mgf1md, int saltlen) +RSA_PSS_PARAMS *ossl_rsa_pss_params_create(const EVP_MD *sigmd, + const EVP_MD *mgf1md, int saltlen) { RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); @@ -631,13 +484,13 @@ RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) goto err; } - if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd)) + if (!ossl_x509_algor_new_from_md(&pss->hashAlgorithm, sigmd)) goto err; if (mgf1md == NULL) mgf1md = sigmd; - if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) + if (!ossl_x509_algor_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) goto err; - if (!rsa_md_to_algor(&pss->maskHash, mgf1md)) + if (!ossl_x509_algor_new_from_md(&pss->maskHash, mgf1md)) goto err; return pss; err: @@ -645,7 +498,7 @@ RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, return NULL; } -static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) +ASN1_STRING *ossl_rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) { RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx); ASN1_STRING *os; @@ -664,8 +517,8 @@ static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) * passed to pkctx instead. */ -static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, - X509_ALGOR *sigalg, EVP_PKEY *pkey) +int ossl_rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, + const X509_ALGOR *sigalg, EVP_PKEY *pkey) { int rv = -1; int saltlen; @@ -674,14 +527,14 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); + ERR_raise(ERR_LIB_RSA, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } /* Decode PSS parameters */ - pss = rsa_pss_decode(sigalg); + pss = ossl_rsa_pss_decode(sigalg); - if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS); + if (!ossl_rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS); goto err; } @@ -693,8 +546,8 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, const EVP_MD *checkmd; if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) goto err; - if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH); + if (EVP_MD_get_type(md) != EVP_MD_get_type(checkmd)) { + ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_DOES_NOT_MATCH); goto err; } } @@ -715,143 +568,99 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, return rv; } -int rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, - const EVP_MD **pmgf1md, int *psaltlen) +static int rsa_pss_verify_param(const EVP_MD **pmd, const EVP_MD **pmgf1md, + int *psaltlen, int *ptrailerField) { - if (pss == NULL) + if (psaltlen != NULL && *psaltlen < 0) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_SALT_LENGTH); return 0; - *pmd = rsa_algor_to_md(pss->hashAlgorithm); - if (*pmd == NULL) - return 0; - *pmgf1md = rsa_algor_to_md(pss->maskHash); - if (*pmgf1md == NULL) - return 0; - if (pss->saltLength) { - *psaltlen = ASN1_INTEGER_get(pss->saltLength); - if (*psaltlen < 0) { - RSAerr(RSA_F_RSA_PSS_GET_PARAM, RSA_R_INVALID_SALT_LENGTH); - return 0; - } - } else { - *psaltlen = 20; } - /* * low-level routines support only trailer field 0xbc (value 1) and * PKCS#1 says we should reject any other value anyway. */ - if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { - RSAerr(RSA_F_RSA_PSS_GET_PARAM, RSA_R_INVALID_TRAILER); + if (ptrailerField != NULL && *ptrailerField != 1) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_TRAILER); return 0; } - return 1; } -#ifndef OPENSSL_NO_CMS -static int rsa_cms_verify(CMS_SignerInfo *si) +int ossl_rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, + const EVP_MD **pmgf1md, int *psaltlen) { - int nid, nid2; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); - - CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); - nid = OBJ_obj2nid(alg->algorithm); - if (nid == EVP_PKEY_RSA_PSS) - return rsa_pss_to_ctx(NULL, pkctx, alg, NULL); - /* Only PSS allowed for PSS keys */ - if (pkey_ctx_is_pss(pkctx)) { - RSAerr(RSA_F_RSA_CMS_VERIFY, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); - return 0; - } - if (nid == NID_rsaEncryption) - return 1; - /* Workaround for some implementation that use a signature OID */ - if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { - if (nid2 == NID_rsaEncryption) - return 1; - } - return 0; + /* + * Callers do not care about the trailer field, and yet, we must + * pass it from get_param to verify_param, since the latter checks + * its value. + * + * When callers start caring, it's a simple thing to add another + * argument to this function. + */ + int trailerField = 0; + + return ossl_rsa_pss_get_param_unverified(pss, pmd, pmgf1md, psaltlen, + &trailerField) + && rsa_pss_verify_param(pmd, pmgf1md, psaltlen, &trailerField); } -#endif /* * Customised RSA item verification routine. This is called when a signature * is encountered requiring special handling. We currently only handle PSS. */ -static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, - EVP_PKEY *pkey) +static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, + const void *asn, const X509_ALGOR *sigalg, + const ASN1_BIT_STRING *sig, EVP_PKEY *pkey) { /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { - RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); + ERR_raise(ERR_LIB_RSA, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } - if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { + if (ossl_rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { /* Carry on */ return 2; } return -1; } -#ifndef OPENSSL_NO_CMS -static int rsa_cms_sign(CMS_SignerInfo *si) -{ - int pad_mode = RSA_PKCS1_PADDING; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); - ASN1_STRING *os = NULL; - - CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); - if (pkctx) { - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) - return 0; - } - if (pad_mode == RSA_PKCS1_PADDING) { - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - return 1; - } - /* We don't support it */ - if (pad_mode != RSA_PKCS1_PSS_PADDING) - return 0; - os = rsa_ctx_to_pss_string(pkctx); - if (!os) - return 0; - X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os); - return 1; -} -#endif - -static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, +static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig) { int pad_mode; - EVP_PKEY_CTX *pkctx = EVP_MD_CTX_pkey_ctx(ctx); + EVP_PKEY_CTX *pkctx = EVP_MD_CTX_get_pkey_ctx(ctx); if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) return 0; if (pad_mode == RSA_PKCS1_PADDING) return 2; if (pad_mode == RSA_PKCS1_PSS_PADDING) { - ASN1_STRING *os1 = NULL; - os1 = rsa_ctx_to_pss_string(pkctx); - if (!os1) + unsigned char aid[128]; + size_t aid_len = 0; + OSSL_PARAM params[2]; + + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_SIGNATURE_PARAM_ALGORITHM_ID, aid, sizeof(aid)); + params[1] = OSSL_PARAM_construct_end(); + + if (EVP_PKEY_CTX_get_params(pkctx, params) <= 0) return 0; - /* Duplicate parameters if we have to */ - if (alg2) { - ASN1_STRING *os2 = ASN1_STRING_dup(os1); - if (!os2) { - ASN1_STRING_free(os1); + if ((aid_len = params[0].return_size) == 0) + return 0; + + if (alg1 != NULL) { + const unsigned char *pp = aid; + if (d2i_X509_ALGOR(&alg1, &pp, aid_len) == NULL) return 0; - } - X509_ALGOR_set0(alg2, OBJ_nid2obj(EVP_PKEY_RSA_PSS), - V_ASN1_SEQUENCE, os2); } - X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_RSA_PSS), - V_ASN1_SEQUENCE, os1); + if (alg2 != NULL) { + const unsigned char *pp = aid; + if (d2i_X509_ALGOR(&alg2, &pp, aid_len) == NULL) + return 0; + } + return 3; } return 2; @@ -865,26 +674,45 @@ static int rsa_sig_info_set(X509_SIG_INFO *siginf, const X509_ALGOR *sigalg, uint32_t flags; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_PSS_PARAMS *pss; + int secbits; /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) return 0; /* Decode PSS parameters */ - pss = rsa_pss_decode(sigalg); - if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) + pss = ossl_rsa_pss_decode(sigalg); + if (!ossl_rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) goto err; - mdnid = EVP_MD_type(md); + mdnid = EVP_MD_get_type(md); /* * For TLS need SHA256, SHA384 or SHA512, digest and MGF1 digest must * match and salt length must equal digest size */ if ((mdnid == NID_sha256 || mdnid == NID_sha384 || mdnid == NID_sha512) - && mdnid == EVP_MD_type(mgf1md) && saltlen == EVP_MD_size(md)) + && mdnid == EVP_MD_get_type(mgf1md) + && saltlen == EVP_MD_get_size(md)) flags = X509_SIG_INFO_TLS; else flags = 0; /* Note: security bits half number of digest bits */ - X509_SIG_INFO_set(siginf, mdnid, EVP_PKEY_RSA_PSS, EVP_MD_size(md) * 4, + secbits = EVP_MD_get_size(md) * 4; + /* + * SHA1 and MD5 are known to be broken. Reduce security bits so that + * they're no longer accepted at security level 1. The real values don't + * really matter as long as they're lower than 80, which is our security + * level 1. + * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack for SHA1 at + * 2^63.4 + * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf + * puts a chosen-prefix attack for MD5 at 2^39. + */ + if (mdnid == NID_sha1) + secbits = 64; + else if (mdnid == NID_md5_sha1) + secbits = 68; + else if (mdnid == NID_md5) + secbits = 39; + X509_SIG_INFO_set(siginf, mdnid, EVP_PKEY_RSA_PSS, secbits, flags); rv = 1; err: @@ -892,170 +720,193 @@ static int rsa_sig_info_set(X509_SIG_INFO *siginf, const X509_ALGOR *sigalg, return rv; } -#ifndef OPENSSL_NO_CMS -static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg) +static int rsa_pkey_check(const EVP_PKEY *pkey) { - RSA_OAEP_PARAMS *oaep; - - oaep = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS), - alg->parameter); - - if (oaep == NULL) - return NULL; - - if (oaep->maskGenFunc != NULL) { - oaep->maskHash = rsa_mgf1_decode(oaep->maskGenFunc); - if (oaep->maskHash == NULL) { - RSA_OAEP_PARAMS_free(oaep); - return NULL; - } - } - return oaep; + return RSA_check_key_ex(pkey->pkey.rsa, NULL); } -static int rsa_cms_decrypt(CMS_RecipientInfo *ri) +static size_t rsa_pkey_dirty_cnt(const EVP_PKEY *pkey) { - EVP_PKEY_CTX *pkctx; - X509_ALGOR *cmsalg; - int nid; - int rv = -1; - unsigned char *label = NULL; - int labellen = 0; - const EVP_MD *mgf1md = NULL, *md = NULL; - RSA_OAEP_PARAMS *oaep; + return pkey->pkey.rsa->dirty_cnt; +} - pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (pkctx == NULL) - return 0; - if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) - return -1; - nid = OBJ_obj2nid(cmsalg->algorithm); - if (nid == NID_rsaEncryption) - return 1; - if (nid != NID_rsaesOaep) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE); - return -1; - } - /* Decode OAEP parameters */ - oaep = rsa_oaep_decode(cmsalg); +/* + * There is no need to do RSA_test_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS) + * checks in this method since the caller tests EVP_KEYMGMT_is_a() first. + */ +static int rsa_int_export_to(const EVP_PKEY *from, int rsa_type, + void *to_keydata, + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) +{ + RSA *rsa = from->pkey.rsa; + OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new(); + OSSL_PARAM *params = NULL; + int selection = 0; + int rv = 0; - if (oaep == NULL) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS); + if (tmpl == NULL) + return 0; + /* Public parameters must always be present */ + if (RSA_get0_n(rsa) == NULL || RSA_get0_e(rsa) == NULL) goto err; - } - mgf1md = rsa_algor_to_md(oaep->maskHash); - if (mgf1md == NULL) - goto err; - md = rsa_algor_to_md(oaep->hashFunc); - if (md == NULL) + if (!ossl_rsa_todata(rsa, tmpl, NULL, 1)) goto err; - if (oaep->pSourceFunc != NULL) { - X509_ALGOR *plab = oaep->pSourceFunc; + selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; + if (RSA_get0_d(rsa) != NULL) + selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY; + + if (rsa->pss != NULL) { + const EVP_MD *md = NULL, *mgf1md = NULL; + int md_nid, mgf1md_nid, saltlen, trailerfield; + RSA_PSS_PARAMS_30 pss_params; - if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE); + if (!ossl_rsa_pss_get_param_unverified(rsa->pss, &md, &mgf1md, + &saltlen, &trailerfield)) goto err; - } - if (plab->parameter->type != V_ASN1_OCTET_STRING) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL); + md_nid = EVP_MD_get_type(md); + mgf1md_nid = EVP_MD_get_type(mgf1md); + if (!ossl_rsa_pss_params_30_set_defaults(&pss_params) + || !ossl_rsa_pss_params_30_set_hashalg(&pss_params, md_nid) + || !ossl_rsa_pss_params_30_set_maskgenhashalg(&pss_params, + mgf1md_nid) + || !ossl_rsa_pss_params_30_set_saltlen(&pss_params, saltlen) + || !ossl_rsa_pss_params_30_todata(&pss_params, tmpl, NULL)) goto err; - } - - label = plab->parameter->value.octet_string->data; - /* Stop label being freed when OAEP parameters are freed */ - plab->parameter->value.octet_string->data = NULL; - labellen = plab->parameter->value.octet_string->length; + selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS; } - if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) - goto err; - if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) - goto err; - if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) - goto err; - if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) + if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) goto err; - /* Carry on */ - rv = 1; + + /* We export, the provider imports */ + rv = importer(to_keydata, selection, params); err: - RSA_OAEP_PARAMS_free(oaep); + OSSL_PARAM_free(params); + OSSL_PARAM_BLD_free(tmpl); return rv; } -static int rsa_cms_encrypt(CMS_RecipientInfo *ri) +static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, + int rsa_type) { - const EVP_MD *md, *mgf1md; - RSA_OAEP_PARAMS *oaep = NULL; - ASN1_STRING *os = NULL; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; - unsigned char *label; + EVP_PKEY_CTX *pctx = vpctx; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); + RSA *rsa = ossl_rsa_new_with_ctx(pctx->libctx); + RSA_PSS_PARAMS_30 rsa_pss_params = { 0, }; + int pss_defaults_set = 0; + int ok = 0; - if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0) + if (rsa == NULL) { + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); return 0; - if (pkctx) { - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) - return 0; - } - if (pad_mode == RSA_PKCS1_PADDING) { - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - return 1; } - /* Not supported */ - if (pad_mode != RSA_PKCS1_OAEP_PADDING) - return 0; - if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) - goto err; - if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) - goto err; - labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); - if (labellen < 0) - goto err; - oaep = RSA_OAEP_PARAMS_new(); - if (oaep == NULL) - goto err; - if (!rsa_md_to_algor(&oaep->hashFunc, md)) - goto err; - if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) + + RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); + RSA_set_flags(rsa, rsa_type); + + if (!ossl_rsa_pss_params_30_fromdata(&rsa_pss_params, &pss_defaults_set, + params, pctx->libctx)) goto err; - if (labellen > 0) { - ASN1_OCTET_STRING *los; - oaep->pSourceFunc = X509_ALGOR_new(); - if (oaep->pSourceFunc == NULL) - goto err; - los = ASN1_OCTET_STRING_new(); - if (los == NULL) - goto err; - if (!ASN1_OCTET_STRING_set(los, label, labellen)) { - ASN1_OCTET_STRING_free(los); + + switch (rsa_type) { + case RSA_FLAG_TYPE_RSA: + /* + * Were PSS parameters filled in? + * In that case, something's wrong + */ + if (!ossl_rsa_pss_params_30_is_unrestricted(&rsa_pss_params)) goto err; + break; + case RSA_FLAG_TYPE_RSASSAPSS: + /* + * Were PSS parameters filled in? In that case, create the old + * RSA_PSS_PARAMS structure. Otherwise, this is an unrestricted key. + */ + if (!ossl_rsa_pss_params_30_is_unrestricted(&rsa_pss_params)) { + /* Create the older RSA_PSS_PARAMS from RSA_PSS_PARAMS_30 data */ + int mdnid = ossl_rsa_pss_params_30_hashalg(&rsa_pss_params); + int mgf1mdnid = ossl_rsa_pss_params_30_maskgenhashalg(&rsa_pss_params); + int saltlen = ossl_rsa_pss_params_30_saltlen(&rsa_pss_params); + const EVP_MD *md = EVP_get_digestbynid(mdnid); + const EVP_MD *mgf1md = EVP_get_digestbynid(mgf1mdnid); + + if ((rsa->pss = ossl_rsa_pss_params_create(md, mgf1md, + saltlen)) == NULL) + goto err; } - X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), - V_ASN1_OCTET_STRING, los); + break; + default: + /* RSA key sub-types we don't know how to handle yet */ + goto err; } - /* create string with pss parameter encoding. */ - if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) - goto err; - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); - os = NULL; - rv = 1; + + if (!ossl_rsa_fromdata(rsa, params, 1)) + goto err; + + switch (rsa_type) { + case RSA_FLAG_TYPE_RSA: + ok = EVP_PKEY_assign_RSA(pkey, rsa); + break; + case RSA_FLAG_TYPE_RSASSAPSS: + ok = EVP_PKEY_assign(pkey, EVP_PKEY_RSA_PSS, rsa); + break; + } + err: - RSA_OAEP_PARAMS_free(oaep); - ASN1_STRING_free(os); - return rv; + if (!ok) + RSA_free(rsa); + return ok; } -#endif -static int rsa_pkey_check(const EVP_PKEY *pkey) +static int rsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) { - return RSA_check_key_ex(pkey->pkey.rsa, NULL); + return rsa_int_export_to(from, RSA_FLAG_TYPE_RSA, to_keydata, + importer, libctx, propq); +} + +static int rsa_pss_pkey_export_to(const EVP_PKEY *from, void *to_keydata, + OSSL_FUNC_keymgmt_import_fn *importer, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return rsa_int_export_to(from, RSA_FLAG_TYPE_RSASSAPSS, to_keydata, + importer, libctx, propq); +} + +static int rsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx) +{ + return rsa_int_import_from(params, vpctx, RSA_FLAG_TYPE_RSA); +} + +static int rsa_pss_pkey_import_from(const OSSL_PARAM params[], void *vpctx) +{ + return rsa_int_import_from(params, vpctx, RSA_FLAG_TYPE_RSASSAPSS); +} + +static int rsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) +{ + RSA *rsa = from->pkey.rsa; + RSA *dupkey = NULL; + int ret; + + if (rsa != NULL) { + dupkey = ossl_rsa_dup(rsa, OSSL_KEYMGMT_SELECT_ALL); + if (dupkey == NULL) + return 0; + } + + ret = EVP_PKEY_assign(to, from->type, dupkey); + if (!ret) + RSA_free(dupkey); + return ret; } -const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = { +const EVP_PKEY_ASN1_METHOD ossl_rsa_asn1_meths[2] = { { EVP_PKEY_RSA, EVP_PKEY_RSA, @@ -1087,7 +938,15 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = { rsa_item_verify, rsa_item_sign, rsa_sig_info_set, - rsa_pkey_check + rsa_pkey_check, + + 0, 0, + 0, 0, 0, 0, + + rsa_pkey_dirty_cnt, + rsa_pkey_export_to, + rsa_pkey_import_from, + rsa_pkey_copy }, { @@ -1096,7 +955,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = { ASN1_PKEY_ALIAS} }; -const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = { +const EVP_PKEY_ASN1_METHOD ossl_rsa_pss_asn1_meth = { EVP_PKEY_RSA_PSS, EVP_PKEY_RSA_PSS, ASN1_PKEY_SIGPARAM_NULL, @@ -1125,6 +984,14 @@ const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = { 0, 0, rsa_item_verify, rsa_item_sign, - 0, - rsa_pkey_check + rsa_sig_info_set, + rsa_pkey_check, + + 0, 0, + 0, 0, 0, 0, + + rsa_pkey_dirty_cnt, + rsa_pss_pkey_export_to, + rsa_pss_pkey_import_from, + rsa_pkey_copy }; diff --git a/crypto/openssl/crypto/rsa/rsa_asn1.c b/crypto/openssl/crypto/rsa/rsa_asn1.c index e8df8d762e16..c14cdf415e9d 100644 --- a/crypto/openssl/crypto/rsa/rsa_asn1.c +++ b/crypto/openssl/crypto/rsa/rsa_asn1.c @@ -1,12 +1,18 @@ /* - * Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -36,7 +42,7 @@ static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, /* not a multi-prime key, skip */ return 1; } - return (rsa_multip_calc_product((RSA *)*pval) == 1) ? 2 : 0; + return (ossl_rsa_multip_calc_product((RSA *)*pval) == 1) ? 2 : 0; } return 1; } @@ -86,6 +92,7 @@ ASN1_SEQUENCE_cb(RSA_PSS_PARAMS, rsa_pss_cb) = { } ASN1_SEQUENCE_END_cb(RSA_PSS_PARAMS, RSA_PSS_PARAMS) IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS) +IMPLEMENT_ASN1_DUP_FUNCTION(RSA_PSS_PARAMS) /* Free up maskHash */ static int rsa_oaep_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, @@ -106,16 +113,16 @@ ASN1_SEQUENCE_cb(RSA_OAEP_PARAMS, rsa_oaep_cb) = { IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(RSA, RSAPrivateKey, RSAPrivateKey) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(RSA, RSAPublicKey, RSAPublicKey) -RSA *RSAPublicKey_dup(RSA *rsa) +RSA *RSAPublicKey_dup(const RSA *rsa) { return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa); } -RSA *RSAPrivateKey_dup(RSA *rsa) +RSA *RSAPrivateKey_dup(const RSA *rsa) { return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa); } diff --git a/crypto/openssl/crypto/rsa/rsa_backend.c b/crypto/openssl/crypto/rsa/rsa_backend.c new file mode 100644 index 000000000000..58187fa2ef59 --- /dev/null +++ b/crypto/openssl/crypto/rsa/rsa_backend.c @@ -0,0 +1,595 @@ +/* + * Copyright 2020-2022 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 + */ + +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include +#ifndef FIPS_MODULE +# include +# include "crypto/asn1.h" +#endif +#include "internal/sizes.h" +#include "internal/param_build_set.h" +#include "crypto/rsa.h" +#include "rsa_local.h" + +/* + * The intention with the "backend" source file is to offer backend support + * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider + * implementations alike. + */ + +DEFINE_STACK_OF(BIGNUM) + +static int collect_numbers(STACK_OF(BIGNUM) *numbers, + const OSSL_PARAM params[], const char *names[]) +{ + const OSSL_PARAM *p = NULL; + int i; + + if (numbers == NULL) + return 0; + + for (i = 0; names[i] != NULL; i++){ + p = OSSL_PARAM_locate_const(params, names[i]); + if (p != NULL) { + BIGNUM *tmp = NULL; + + if (!OSSL_PARAM_get_BN(p, &tmp)) + return 0; + if (sk_BIGNUM_push(numbers, tmp) == 0) { + BN_clear_free(tmp); + return 0; + } + } + } + + return 1; +} + +int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private) +{ + const OSSL_PARAM *param_n, *param_e, *param_d = NULL; + BIGNUM *n = NULL, *e = NULL, *d = NULL; + STACK_OF(BIGNUM) *factors = NULL, *exps = NULL, *coeffs = NULL; + int is_private = 0; + + if (rsa == NULL) + return 0; + + param_n = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N); + param_e = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E); + if (include_private) + param_d = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D); + + if ((param_n != NULL && !OSSL_PARAM_get_BN(param_n, &n)) + || (param_e != NULL && !OSSL_PARAM_get_BN(param_e, &e)) + || (param_d != NULL && !OSSL_PARAM_get_BN(param_d, &d))) + goto err; + + is_private = (d != NULL); + + if (!RSA_set0_key(rsa, n, e, d)) + goto err; + n = e = d = NULL; + + if (is_private) { + if (!collect_numbers(factors = sk_BIGNUM_new_null(), params, + ossl_rsa_mp_factor_names) + || !collect_numbers(exps = sk_BIGNUM_new_null(), params, + ossl_rsa_mp_exp_names) + || !collect_numbers(coeffs = sk_BIGNUM_new_null(), params, + ossl_rsa_mp_coeff_names)) + goto err; + + /* It's ok if this private key just has n, e and d */ + if (sk_BIGNUM_num(factors) != 0 + && !ossl_rsa_set0_all_params(rsa, factors, exps, coeffs)) + goto err; + } + + + sk_BIGNUM_free(factors); + sk_BIGNUM_free(exps); + sk_BIGNUM_free(coeffs); + return 1; + + err: + BN_free(n); + BN_free(e); + BN_free(d); + sk_BIGNUM_pop_free(factors, BN_free); + sk_BIGNUM_pop_free(exps, BN_free); + sk_BIGNUM_pop_free(coeffs, BN_free); + return 0; +} + +DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) + +int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[], + int include_private) +{ + int ret = 0; + const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL; + STACK_OF(BIGNUM_const) *factors = sk_BIGNUM_const_new_null(); + STACK_OF(BIGNUM_const) *exps = sk_BIGNUM_const_new_null(); + STACK_OF(BIGNUM_const) *coeffs = sk_BIGNUM_const_new_null(); + + if (rsa == NULL || factors == NULL || exps == NULL || coeffs == NULL) + goto err; + + RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); + ossl_rsa_get0_all_params(rsa, factors, exps, coeffs); + + if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_N, rsa_n) + || !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_E, rsa_e)) + goto err; + + /* Check private key data integrity */ + if (include_private && rsa_d != NULL) { + int numprimes = sk_BIGNUM_const_num(factors); + int numexps = sk_BIGNUM_const_num(exps); + int numcoeffs = sk_BIGNUM_const_num(coeffs); + + /* + * It's permissible to have zero primes, i.e. no CRT params. + * Otherwise, there must be at least two, as many exponents, + * and one coefficient less. + */ + if (numprimes != 0 + && (numprimes < 2 || numexps < 2 || numcoeffs < 1)) + goto err; + + if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_D, + rsa_d) + || !ossl_param_build_set_multi_key_bn(bld, params, + ossl_rsa_mp_factor_names, + factors) + || !ossl_param_build_set_multi_key_bn(bld, params, + ossl_rsa_mp_exp_names, exps) + || !ossl_param_build_set_multi_key_bn(bld, params, + ossl_rsa_mp_coeff_names, + coeffs)) + goto err; + } + +#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) + /* The acvp test results are not meant for export so check for bld == NULL */ + if (bld == NULL) + ossl_rsa_acvp_test_get_params(rsa, params); +#endif + ret = 1; + err: + sk_BIGNUM_const_free(factors); + sk_BIGNUM_const_free(exps); + sk_BIGNUM_const_free(coeffs); + return ret; +} + +int ossl_rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss, + OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) +{ + if (!ossl_rsa_pss_params_30_is_unrestricted(pss)) { + int hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss); + int maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(pss); + int maskgenhashalg_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss); + int saltlen = ossl_rsa_pss_params_30_saltlen(pss); + int default_hashalg_nid = ossl_rsa_pss_params_30_hashalg(NULL); + int default_maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(NULL); + int default_maskgenhashalg_nid = + ossl_rsa_pss_params_30_maskgenhashalg(NULL); + const char *mdname = + (hashalg_nid == default_hashalg_nid + ? NULL : ossl_rsa_oaeppss_nid2name(hashalg_nid)); + const char *mgfname = + (maskgenalg_nid == default_maskgenalg_nid + ? NULL : ossl_rsa_oaeppss_nid2name(maskgenalg_nid)); + const char *mgf1mdname = + (maskgenhashalg_nid == default_maskgenhashalg_nid + ? NULL : ossl_rsa_oaeppss_nid2name(maskgenhashalg_nid)); + const char *key_md = OSSL_PKEY_PARAM_RSA_DIGEST; + const char *key_mgf = OSSL_PKEY_PARAM_RSA_MASKGENFUNC; + const char *key_mgf1_md = OSSL_PKEY_PARAM_RSA_MGF1_DIGEST; + const char *key_saltlen = OSSL_PKEY_PARAM_RSA_PSS_SALTLEN; + + /* + * To ensure that the key isn't seen as unrestricted by the recipient, + * we make sure that at least one PSS-related parameter is passed, even + * if it has a default value; saltlen. + */ + if ((mdname != NULL + && !ossl_param_build_set_utf8_string(bld, params, key_md, mdname)) + || (mgfname != NULL + && !ossl_param_build_set_utf8_string(bld, params, + key_mgf, mgfname)) + || (mgf1mdname != NULL + && !ossl_param_build_set_utf8_string(bld, params, + key_mgf1_md, mgf1mdname)) + || (!ossl_param_build_set_int(bld, params, key_saltlen, saltlen))) + return 0; + } + return 1; +} + +int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, + int *defaults_set, + const OSSL_PARAM params[], + OSSL_LIB_CTX *libctx) +{ + const OSSL_PARAM *param_md, *param_mgf, *param_mgf1md, *param_saltlen; + const OSSL_PARAM *param_propq; + const char *propq = NULL; + EVP_MD *md = NULL, *mgf1md = NULL; + int saltlen; + int ret = 0; + + if (pss_params == NULL) + return 0; + param_propq = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST_PROPS); + param_md = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST); + param_mgf = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_MASKGENFUNC); + param_mgf1md = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_MGF1_DIGEST); + param_saltlen = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_PSS_SALTLEN); + + if (param_propq != NULL) { + if (param_propq->data_type == OSSL_PARAM_UTF8_STRING) + propq = param_propq->data; + } + /* + * If we get any of the parameters, we know we have at least some + * restrictions, so we start by setting default values, and let each + * parameter override their specific restriction data. + */ + if (!*defaults_set + && (param_md != NULL || param_mgf != NULL || param_mgf1md != NULL + || param_saltlen != NULL)) { + if (!ossl_rsa_pss_params_30_set_defaults(pss_params)) + return 0; + *defaults_set = 1; + } + + if (param_mgf != NULL) { + int default_maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(NULL); + const char *mgfname = NULL; + + if (param_mgf->data_type == OSSL_PARAM_UTF8_STRING) + mgfname = param_mgf->data; + else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mgfname)) + return 0; + + if (OPENSSL_strcasecmp(param_mgf->data, + ossl_rsa_mgf_nid2name(default_maskgenalg_nid)) != 0) + return 0; + } + + /* + * We're only interested in the NIDs that correspond to the MDs, so the + * exact propquery is unimportant in the EVP_MD_fetch() calls below. + */ + + if (param_md != NULL) { + const char *mdname = NULL; + + if (param_md->data_type == OSSL_PARAM_UTF8_STRING) + mdname = param_md->data; + else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mdname)) + goto err; + + if ((md = EVP_MD_fetch(libctx, mdname, propq)) == NULL + || !ossl_rsa_pss_params_30_set_hashalg(pss_params, + ossl_rsa_oaeppss_md2nid(md))) + goto err; + } + + if (param_mgf1md != NULL) { + const char *mgf1mdname = NULL; + + if (param_mgf1md->data_type == OSSL_PARAM_UTF8_STRING) + mgf1mdname = param_mgf1md->data; + else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mgf1mdname)) + goto err; + + if ((mgf1md = EVP_MD_fetch(libctx, mgf1mdname, propq)) == NULL + || !ossl_rsa_pss_params_30_set_maskgenhashalg( + pss_params, ossl_rsa_oaeppss_md2nid(mgf1md))) + goto err; + } + + if (param_saltlen != NULL) { + if (!OSSL_PARAM_get_int(param_saltlen, &saltlen) + || !ossl_rsa_pss_params_30_set_saltlen(pss_params, saltlen)) + goto err; + } + + ret = 1; + + err: + EVP_MD_free(md); + EVP_MD_free(mgf1md); + return ret; +} + +int ossl_rsa_is_foreign(const RSA *rsa) +{ +#ifndef FIPS_MODULE + if (rsa->engine != NULL || RSA_get_method(rsa) != RSA_PKCS1_OpenSSL()) + return 1; +#endif + return 0; +} + +static ossl_inline int rsa_bn_dup_check(BIGNUM **out, const BIGNUM *f) +{ + if (f != NULL && (*out = BN_dup(f)) == NULL) + return 0; + return 1; +} + +RSA *ossl_rsa_dup(const RSA *rsa, int selection) +{ + RSA *dupkey = NULL; +#ifndef FIPS_MODULE + int pnum, i; +#endif + + /* Do not try to duplicate foreign RSA keys */ + if (ossl_rsa_is_foreign(rsa)) + return NULL; + + if ((dupkey = ossl_rsa_new_with_ctx(rsa->libctx)) == NULL) + return NULL; + + /* public key */ + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { + if (!rsa_bn_dup_check(&dupkey->n, rsa->n)) + goto err; + if (!rsa_bn_dup_check(&dupkey->e, rsa->e)) + goto err; + } + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + + /* private key */ + if (!rsa_bn_dup_check(&dupkey->d, rsa->d)) + goto err; + + /* factors and crt params */ + if (!rsa_bn_dup_check(&dupkey->p, rsa->p)) + goto err; + if (!rsa_bn_dup_check(&dupkey->q, rsa->q)) + goto err; + if (!rsa_bn_dup_check(&dupkey->dmp1, rsa->dmp1)) + goto err; + if (!rsa_bn_dup_check(&dupkey->dmq1, rsa->dmq1)) + goto err; + if (!rsa_bn_dup_check(&dupkey->iqmp, rsa->iqmp)) + goto err; + } + + dupkey->version = rsa->version; + dupkey->flags = rsa->flags; + /* we always copy the PSS parameters regardless of selection */ + dupkey->pss_params = rsa->pss_params; + +#ifndef FIPS_MODULE + /* multiprime */ + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 + && (pnum = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) > 0) { + dupkey->prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum); + if (dupkey->prime_infos == NULL) + goto err; + for (i = 0; i < pnum; i++) { + const RSA_PRIME_INFO *pinfo = NULL; + RSA_PRIME_INFO *duppinfo = NULL; + + if ((duppinfo = OPENSSL_zalloc(sizeof(*duppinfo))) == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + /* push first so cleanup in error case works */ + (void)sk_RSA_PRIME_INFO_push(dupkey->prime_infos, duppinfo); + + pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); + if (!rsa_bn_dup_check(&duppinfo->r, pinfo->r)) + goto err; + if (!rsa_bn_dup_check(&duppinfo->d, pinfo->d)) + goto err; + if (!rsa_bn_dup_check(&duppinfo->t, pinfo->t)) + goto err; + } + if (!ossl_rsa_multip_calc_product(dupkey)) + goto err; + } + + if (rsa->pss != NULL) { + dupkey->pss = RSA_PSS_PARAMS_dup(rsa->pss); + if (rsa->pss->maskGenAlgorithm != NULL + && dupkey->pss->maskGenAlgorithm == NULL) { + dupkey->pss->maskHash = ossl_x509_algor_mgf1_decode(rsa->pss->maskGenAlgorithm); + if (dupkey->pss->maskHash == NULL) + goto err; + } + } + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_RSA, + &dupkey->ex_data, &rsa->ex_data)) + goto err; +#endif + + return dupkey; + + err: + RSA_free(dupkey); + return NULL; +} + +#ifndef FIPS_MODULE +RSA_PSS_PARAMS *ossl_rsa_pss_decode(const X509_ALGOR *alg) +{ + RSA_PSS_PARAMS *pss; + + pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_PSS_PARAMS), + alg->parameter); + + if (pss == NULL) + return NULL; + + if (pss->maskGenAlgorithm != NULL) { + pss->maskHash = ossl_x509_algor_mgf1_decode(pss->maskGenAlgorithm); + if (pss->maskHash == NULL) { + RSA_PSS_PARAMS_free(pss); + return NULL; + } + } + + return pss; +} + +static int ossl_rsa_sync_to_pss_params_30(RSA *rsa) +{ + const RSA_PSS_PARAMS *legacy_pss = NULL; + RSA_PSS_PARAMS_30 *pss = NULL; + + if (rsa != NULL + && (legacy_pss = RSA_get0_pss_params(rsa)) != NULL + && (pss = ossl_rsa_get0_pss_params_30(rsa)) != NULL) { + const EVP_MD *md = NULL, *mgf1md = NULL; + int md_nid, mgf1md_nid, saltlen, trailerField; + RSA_PSS_PARAMS_30 pss_params; + + /* + * We don't care about the validity of the fields here, we just + * want to synchronise values. Verifying here makes it impossible + * to even read a key with invalid values, making it hard to test + * a bad situation. + * + * Other routines use ossl_rsa_pss_get_param(), so the values will + * be checked, eventually. + */ + if (!ossl_rsa_pss_get_param_unverified(legacy_pss, &md, &mgf1md, + &saltlen, &trailerField)) + return 0; + md_nid = EVP_MD_get_type(md); + mgf1md_nid = EVP_MD_get_type(mgf1md); + if (!ossl_rsa_pss_params_30_set_defaults(&pss_params) + || !ossl_rsa_pss_params_30_set_hashalg(&pss_params, md_nid) + || !ossl_rsa_pss_params_30_set_maskgenhashalg(&pss_params, + mgf1md_nid) + || !ossl_rsa_pss_params_30_set_saltlen(&pss_params, saltlen) + || !ossl_rsa_pss_params_30_set_trailerfield(&pss_params, + trailerField)) + return 0; + *pss = pss_params; + } + return 1; +} + +int ossl_rsa_pss_get_param_unverified(const RSA_PSS_PARAMS *pss, + const EVP_MD **pmd, const EVP_MD **pmgf1md, + int *psaltlen, int *ptrailerField) +{ + RSA_PSS_PARAMS_30 pss_params; + + /* Get the defaults from the ONE place */ + (void)ossl_rsa_pss_params_30_set_defaults(&pss_params); + + if (pss == NULL) + return 0; + *pmd = ossl_x509_algor_get_md(pss->hashAlgorithm); + if (*pmd == NULL) + return 0; + *pmgf1md = ossl_x509_algor_get_md(pss->maskHash); + if (*pmgf1md == NULL) + return 0; + if (pss->saltLength) + *psaltlen = ASN1_INTEGER_get(pss->saltLength); + else + *psaltlen = ossl_rsa_pss_params_30_saltlen(&pss_params); + if (pss->trailerField) + *ptrailerField = ASN1_INTEGER_get(pss->trailerField); + else + *ptrailerField = ossl_rsa_pss_params_30_trailerfield(&pss_params);; + + return 1; +} + +int ossl_rsa_param_decode(RSA *rsa, const X509_ALGOR *alg) +{ + RSA_PSS_PARAMS *pss; + const ASN1_OBJECT *algoid; + const void *algp; + int algptype; + + X509_ALGOR_get0(&algoid, &algptype, &algp, alg); + if (OBJ_obj2nid(algoid) != EVP_PKEY_RSA_PSS) + return 1; + if (algptype == V_ASN1_UNDEF) + return 1; + if (algptype != V_ASN1_SEQUENCE) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS); + return 0; + } + if ((pss = ossl_rsa_pss_decode(alg)) == NULL + || !ossl_rsa_set0_pss_params(rsa, pss)) { + RSA_PSS_PARAMS_free(pss); + return 0; + } + if (!ossl_rsa_sync_to_pss_params_30(rsa)) + return 0; + return 1; +} + +RSA *ossl_rsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const unsigned char *p; + RSA *rsa; + int pklen; + const X509_ALGOR *alg; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &alg, p8inf)) + return 0; + rsa = d2i_RSAPrivateKey(NULL, &p, pklen); + if (rsa == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_RSA_LIB); + return NULL; + } + if (!ossl_rsa_param_decode(rsa, alg)) { + RSA_free(rsa); + return NULL; + } + + RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); + switch (OBJ_obj2nid(alg->algorithm)) { + case EVP_PKEY_RSA: + RSA_set_flags(rsa, RSA_FLAG_TYPE_RSA); + break; + case EVP_PKEY_RSA_PSS: + RSA_set_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS); + break; + default: + /* Leave the type bits zero */ + break; + } + + return rsa; +} +#endif diff --git a/crypto/openssl/crypto/rsa/rsa_chk.c b/crypto/openssl/crypto/rsa/rsa_chk.c index b4ba7fce3ffb..cccc2d5bac2a 100644 --- a/crypto/openssl/crypto/rsa/rsa_chk.c +++ b/crypto/openssl/crypto/rsa/rsa_chk.c @@ -1,22 +1,25 @@ /* - * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include +#include "crypto/rsa.h" #include "rsa_local.h" -int RSA_check_key(const RSA *key) -{ - return RSA_check_key_ex(key, NULL); -} - -int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) +#ifndef FIPS_MODULE +static int rsa_validate_keypair_multiprime(const RSA *key, BN_GENCB *cb) { BIGNUM *i, *j, *k, *l, *m; BN_CTX *ctx; @@ -25,7 +28,7 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) if (key->p == NULL || key->q == NULL || key->n == NULL || key->e == NULL || key->d == NULL) { - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_VALUE_MISSING); + ERR_raise(ERR_LIB_RSA, RSA_R_VALUE_MISSING); return 0; } @@ -33,8 +36,8 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) if (key->version == RSA_ASN1_VERSION_MULTI) { ex_primes = sk_RSA_PRIME_INFO_num(key->prime_infos); if (ex_primes <= 0 - || (ex_primes + 2) > rsa_multip_cap(BN_num_bits(key->n))) { - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_INVALID_MULTI_PRIME_KEY); + || (ex_primes + 2) > ossl_rsa_multip_cap(BN_num_bits(key->n))) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MULTI_PRIME_KEY); return 0; } } @@ -44,41 +47,41 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) k = BN_new(); l = BN_new(); m = BN_new(); - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(key->libctx); if (i == NULL || j == NULL || k == NULL || l == NULL || m == NULL || ctx == NULL) { ret = -1; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } if (BN_is_one(key->e)) { ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_E_VALUE); } if (!BN_is_odd(key->e)) { ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_E_VALUE); } /* p prime? */ - if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, cb) != 1) { + if (BN_check_prime(key->p, ctx, cb) != 1) { ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_P_NOT_PRIME); + ERR_raise(ERR_LIB_RSA, RSA_R_P_NOT_PRIME); } /* q prime? */ - if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, cb) != 1) { + if (BN_check_prime(key->q, ctx, cb) != 1) { ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_Q_NOT_PRIME); + ERR_raise(ERR_LIB_RSA, RSA_R_Q_NOT_PRIME); } /* r_i prime? */ for (idx = 0; idx < ex_primes; idx++) { pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx); - if (BN_is_prime_ex(pinfo->r, BN_prime_checks, NULL, cb) != 1) { + if (BN_check_prime(pinfo->r, ctx, cb) != 1) { ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_R_NOT_PRIME); + ERR_raise(ERR_LIB_RSA, RSA_R_MP_R_NOT_PRIME); } } @@ -97,10 +100,9 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) if (BN_cmp(i, key->n) != 0) { ret = 0; if (ex_primes) - RSAerr(RSA_F_RSA_CHECK_KEY_EX, - RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES); + ERR_raise(ERR_LIB_RSA, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES); else - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_N_DOES_NOT_EQUAL_P_Q); + ERR_raise(ERR_LIB_RSA, RSA_R_N_DOES_NOT_EQUAL_P_Q); } /* d*e = 1 mod \lambda(n)? */ @@ -148,7 +150,7 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) if (!BN_is_one(i)) { ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_D_E_NOT_CONGRUENT_TO_1); + ERR_raise(ERR_LIB_RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1); } if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { @@ -163,7 +165,7 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) } if (BN_cmp(j, key->dmp1) != 0) { ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMP1_NOT_CONGRUENT_TO_D); + ERR_raise(ERR_LIB_RSA, RSA_R_DMP1_NOT_CONGRUENT_TO_D); } /* dmq1 = d mod (q-1)? */ @@ -177,7 +179,7 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) } if (BN_cmp(j, key->dmq1) != 0) { ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); + ERR_raise(ERR_LIB_RSA, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); } /* iqmp = q^-1 mod p? */ @@ -187,7 +189,7 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) } if (BN_cmp(i, key->iqmp) != 0) { ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_IQMP_NOT_INVERSE_OF_Q); + ERR_raise(ERR_LIB_RSA, RSA_R_IQMP_NOT_INVERSE_OF_Q); } } @@ -204,7 +206,7 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) } if (BN_cmp(j, pinfo->d) != 0) { ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D); + ERR_raise(ERR_LIB_RSA, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D); } /* t_i = R_i ^ -1 mod r_i ? */ if (!BN_mod_inverse(i, pinfo->pp, pinfo->r, ctx)) { @@ -213,7 +215,7 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) } if (BN_cmp(i, pinfo->t) != 0) { ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R); + ERR_raise(ERR_LIB_RSA, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R); } } @@ -226,3 +228,39 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) BN_CTX_free(ctx); return ret; } +#endif /* FIPS_MODULE */ + +int ossl_rsa_validate_public(const RSA *key) +{ + return ossl_rsa_sp800_56b_check_public(key); +} + +int ossl_rsa_validate_private(const RSA *key) +{ + return ossl_rsa_sp800_56b_check_private(key); +} + +int ossl_rsa_validate_pairwise(const RSA *key) +{ +#ifdef FIPS_MODULE + return ossl_rsa_sp800_56b_check_keypair(key, NULL, -1, RSA_bits(key)); +#else + return rsa_validate_keypair_multiprime(key, NULL) > 0; +#endif +} + +int RSA_check_key(const RSA *key) +{ + return RSA_check_key_ex(key, NULL); +} + +int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) +{ +#ifdef FIPS_MODULE + return ossl_rsa_validate_public(key) + && ossl_rsa_validate_private(key) + && ossl_rsa_validate_pairwise(key); +#else + return rsa_validate_keypair_multiprime(key, cb); +#endif /* FIPS_MODULE */ +} diff --git a/crypto/openssl/crypto/rsa/rsa_crpt.c b/crypto/openssl/crypto/rsa/rsa_crpt.c index f1131ce9e0ad..6bc6aafcc893 100644 --- a/crypto/openssl/crypto/rsa/rsa_crpt.c +++ b/crypto/openssl/crypto/rsa/rsa_crpt.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include "internal/cryptlib.h" @@ -114,7 +120,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) BN_BLINDING *ret = NULL; if (in_ctx == NULL) { - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(rsa->libctx)) == NULL) return 0; } else { ctx = in_ctx; @@ -123,14 +129,14 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) BN_CTX_start(ctx); e = BN_CTX_get(ctx); if (e == NULL) { - RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } if (rsa->e == NULL) { e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); if (e == NULL) { - RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); + ERR_raise(ERR_LIB_RSA, RSA_R_NO_PUBLIC_EXPONENT); goto err; } } else { @@ -141,7 +147,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) BIGNUM *n = BN_new(); if (n == NULL) { - RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); @@ -152,7 +158,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) BN_free(n); } if (ret == NULL) { - RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB); goto err; } diff --git a/crypto/openssl/crypto/rsa/rsa_depr.c b/crypto/openssl/crypto/rsa/rsa_depr.c index 21e0562525d0..3cc89b26a99c 100644 --- a/crypto/openssl/crypto/rsa/rsa_depr.c +++ b/crypto/openssl/crypto/rsa/rsa_depr.c @@ -1,7 +1,7 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,17 +12,19 @@ * "new" versions). */ -#include -#if OPENSSL_API_COMPAT >= 0x00908000L -NON_EMPTY_TRANSLATION_UNIT +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" -#else +#include -# include -# include -# include "internal/cryptlib.h" -# include -# include +#include +#include +#include "internal/cryptlib.h" +#include +#include RSA *RSA_generate_key(int bits, unsigned long e_value, void (*callback) (int, int, void *), void *cb_arg) @@ -58,4 +60,3 @@ RSA *RSA_generate_key(int bits, unsigned long e_value, BN_GENCB_free(cb); return 0; } -#endif diff --git a/crypto/openssl/crypto/rsa/rsa_err.c b/crypto/openssl/crypto/rsa/rsa_err.c index 0687c1e62602..269971c07b8d 100644 --- a/crypto/openssl/crypto/rsa/rsa_err.c +++ b/crypto/openssl/crypto/rsa/rsa_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,102 +10,10 @@ #include #include +#include "crypto/rsaerr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA RSA_str_functs[] = { - {ERR_PACK(ERR_LIB_RSA, RSA_F_CHECK_PADDING_MD, 0), "check_padding_md"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_ENCODE_PKCS1, 0), "encode_pkcs1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_INT_RSA_VERIFY, 0), "int_rsa_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_OLD_RSA_PRIV_DECODE, 0), - "old_rsa_priv_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_PSS_INIT, 0), "pkey_pss_init"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, 0), "pkey_rsa_ctrl"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL_STR, 0), "pkey_rsa_ctrl_str"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_SIGN, 0), "pkey_rsa_sign"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_VERIFY, 0), "pkey_rsa_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_VERIFYRECOVER, 0), - "pkey_rsa_verifyrecover"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_ALGOR_TO_MD, 0), "rsa_algor_to_md"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_BUILTIN_KEYGEN, 0), "rsa_builtin_keygen"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CHECK_KEY, 0), "RSA_check_key"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CHECK_KEY_EX, 0), "RSA_check_key_ex"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_DECRYPT, 0), "rsa_cms_decrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_CMS_VERIFY, 0), "rsa_cms_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_ITEM_VERIFY, 0), "rsa_item_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_DUP, 0), "RSA_meth_dup"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_NEW, 0), "RSA_meth_new"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_METH_SET1_NAME, 0), "RSA_meth_set1_name"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_MGF1_TO_MD, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_MULTIP_INFO_NEW, 0), - "rsa_multip_info_new"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NEW_METHOD, 0), "RSA_new_method"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_DECRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_ENCRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PUBLIC_DECRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_NULL_PUBLIC_ENCRYPT, 0), ""}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, 0), - "rsa_ossl_private_decrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, 0), - "rsa_ossl_private_encrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, 0), - "rsa_ossl_public_decrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, 0), - "rsa_ossl_public_encrypt"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_NONE, 0), - "RSA_padding_add_none"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, 0), - "RSA_padding_add_PKCS1_OAEP"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, 0), - "RSA_padding_add_PKCS1_OAEP_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_PSS, 0), - "RSA_padding_add_PKCS1_PSS"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, 0), - "RSA_padding_add_PKCS1_PSS_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1, 0), - "RSA_padding_add_PKCS1_type_1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2, 0), - "RSA_padding_add_PKCS1_type_2"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_SSLV23, 0), - "RSA_padding_add_SSLv23"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_ADD_X931, 0), - "RSA_padding_add_X931"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_NONE, 0), - "RSA_padding_check_none"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, 0), - "RSA_padding_check_PKCS1_OAEP"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, 0), - "RSA_padding_check_PKCS1_OAEP_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, 0), - "RSA_padding_check_PKCS1_type_1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, 0), - "RSA_padding_check_PKCS1_type_2"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_SSLV23, 0), - "RSA_padding_check_SSLv23"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PADDING_CHECK_X931, 0), - "RSA_padding_check_X931"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PARAM_DECODE, 0), "rsa_param_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT, 0), "RSA_print"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRINT_FP, 0), "RSA_print_fp"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_DECODE, 0), "rsa_priv_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PRIV_ENCODE, 0), "rsa_priv_encode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_GET_PARAM, 0), "rsa_pss_get_param"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PSS_TO_CTX, 0), "rsa_pss_to_ctx"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_PUB_DECODE, 0), "rsa_pub_decode"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SETUP_BLINDING, 0), "RSA_setup_blinding"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN, 0), "RSA_sign"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_SIGN_ASN1_OCTET_STRING, 0), - "RSA_sign_ASN1_OCTET_STRING"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY, 0), "RSA_verify"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, 0), - "RSA_verify_ASN1_OCTET_STRING"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, 0), - "RSA_verify_PKCS1_PSS_mgf1"}, - {ERR_PACK(ERR_LIB_RSA, RSA_F_SETUP_TBUF, 0), "setup_tbuf"}, - {0, NULL} -}; - static const ERR_STRING_DATA RSA_str_reasons[] = { {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_ALGORITHM_MISMATCH), "algorithm mismatch"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_E_VALUE), "bad e value"}, @@ -146,10 +54,14 @@ static const ERR_STRING_DATA RSA_str_reasons[] = { {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_DIGEST_LENGTH), "invalid digest length"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_HEADER), "invalid header"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_KEYPAIR), "invalid keypair"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_KEY_LENGTH), "invalid key length"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_LABEL), "invalid label"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_LENGTH), "invalid length"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MESSAGE_LENGTH), "invalid message length"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MGF1_MD), "invalid mgf1 md"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MODULUS), "invalid modulus"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MULTI_PRIME_KEY), "invalid multi prime key"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_OAEP_PARAMETERS), @@ -161,8 +73,10 @@ static const ERR_STRING_DATA RSA_str_reasons[] = { "invalid pss parameters"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PSS_SALTLEN), "invalid pss saltlen"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_REQUEST), "invalid request"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_SALT_LENGTH), "invalid salt length"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_STRENGTH), "invalid strength"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_TRAILER), "invalid trailer"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_X931_DIGEST), "invalid x931 digest"}, @@ -195,12 +109,18 @@ static const ERR_STRING_DATA RSA_str_reasons[] = { "operation not supported for this keytype"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PADDING_CHECK_FAILED), "padding check failed"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PAIRWISE_TEST_FAILURE), + "pairwise test failure"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PKCS_DECODING_ERROR), "pkcs decoding error"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PSS_SALTLEN_TOO_SMALL), "pss saltlen too small"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PUB_EXPONENT_OUT_OF_RANGE), + "pub exponent out of range"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_P_NOT_PRIME), "p not prime"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_Q_NOT_PRIME), "q not prime"}, + {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT), + "randomness source strength insufficient"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED), "rsa operations not supported"}, {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_SLEN_CHECK_FAILED), @@ -236,13 +156,11 @@ static const ERR_STRING_DATA RSA_str_reasons[] = { #endif -int ERR_load_RSA_strings(void) +int ossl_err_load_RSA_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) { - ERR_load_strings_const(RSA_str_functs); + if (ERR_reason_error_string(RSA_str_reasons[0].error) == NULL) ERR_load_strings_const(RSA_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/rsa/rsa_gen.c b/crypto/openssl/crypto/rsa/rsa_gen.c index 29056a62a1ae..e0d139d3121c 100644 --- a/crypto/openssl/crypto/rsa/rsa_gen.c +++ b/crypto/openssl/crypto/rsa/rsa_gen.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,14 +13,23 @@ * Geoff */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include "internal/cryptlib.h" #include +#include +#include "prov/providercommon.h" #include "rsa_local.h" -static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, - BN_GENCB *cb); +static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg); +static int rsa_keygen(OSSL_LIB_CTX *libctx, RSA *rsa, int bits, int primes, + BIGNUM *e_value, BN_GENCB *cb, int pairwise_test); /* * NB: this wrapper would normally be placed in rsa_lib.c and the static @@ -41,6 +50,7 @@ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, BIGNUM *e_value, BN_GENCB *cb) { +#ifndef FIPS_MODULE /* multi-prime is only supported with the builtin key generation */ if (rsa->meth->rsa_multi_prime_keygen != NULL) { return rsa->meth->rsa_multi_prime_keygen(rsa, bits, primes, @@ -57,35 +67,43 @@ int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, else return 0; } - - return rsa_builtin_keygen(rsa, bits, primes, e_value, cb); +#endif /* FIPS_MODULE */ + return rsa_keygen(rsa->libctx, rsa, bits, primes, e_value, cb, 0); } -static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, - BN_GENCB *cb) +#ifndef FIPS_MODULE +static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes, + BIGNUM *e_value, BN_GENCB *cb) { BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *tmp, *prime; - int ok = -1, n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0; + int n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0; int i = 0, quo = 0, rmd = 0, adj = 0, retries = 0; RSA_PRIME_INFO *pinfo = NULL; STACK_OF(RSA_PRIME_INFO) *prime_infos = NULL; BN_CTX *ctx = NULL; BN_ULONG bitst = 0; unsigned long error = 0; + int ok = -1; if (bits < RSA_MIN_MODULUS_BITS) { ok = 0; /* we set our own err */ - RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); + ERR_raise(ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL); goto err; } - if (primes < RSA_DEFAULT_PRIME_NUM || primes > rsa_multip_cap(bits)) { + /* A bad value for e can cause infinite loops */ + if (e_value != NULL && !ossl_rsa_check_public_exponent(e_value)) { + ERR_raise(ERR_LIB_RSA, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); + return 0; + } + + if (primes < RSA_DEFAULT_PRIME_NUM || primes > ossl_rsa_multip_cap(bits)) { ok = 0; /* we set our own err */ - RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_PRIME_NUM_INVALID); + ERR_raise(ERR_LIB_RSA, RSA_R_KEY_PRIME_NUM_INVALID); goto err; } - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(rsa->libctx); if (ctx == NULL) goto err; BN_CTX_start(ctx); @@ -102,23 +120,31 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, for (i = 0; i < primes; i++) bitsr[i] = (i < rmd) ? quo + 1 : quo; + rsa->dirty_cnt++; + /* We need the RSA components non-NULL */ if (!rsa->n && ((rsa->n = BN_new()) == NULL)) goto err; if (!rsa->d && ((rsa->d = BN_secure_new()) == NULL)) goto err; + BN_set_flags(rsa->d, BN_FLG_CONSTTIME); if (!rsa->e && ((rsa->e = BN_new()) == NULL)) goto err; if (!rsa->p && ((rsa->p = BN_secure_new()) == NULL)) goto err; + BN_set_flags(rsa->p, BN_FLG_CONSTTIME); if (!rsa->q && ((rsa->q = BN_secure_new()) == NULL)) goto err; + BN_set_flags(rsa->q, BN_FLG_CONSTTIME); if (!rsa->dmp1 && ((rsa->dmp1 = BN_secure_new()) == NULL)) goto err; + BN_set_flags(rsa->dmp1, BN_FLG_CONSTTIME); if (!rsa->dmq1 && ((rsa->dmq1 = BN_secure_new()) == NULL)) goto err; + BN_set_flags(rsa->dmq1, BN_FLG_CONSTTIME); if (!rsa->iqmp && ((rsa->iqmp = BN_secure_new()) == NULL)) goto err; + BN_set_flags(rsa->iqmp, BN_FLG_CONSTTIME); /* initialize multi-prime components */ if (primes > RSA_DEFAULT_PRIME_NUM) { @@ -128,13 +154,14 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, goto err; if (rsa->prime_infos != NULL) { /* could this happen? */ - sk_RSA_PRIME_INFO_pop_free(rsa->prime_infos, rsa_multip_info_free); + sk_RSA_PRIME_INFO_pop_free(rsa->prime_infos, + ossl_rsa_multip_info_free); } rsa->prime_infos = prime_infos; /* prime_info from 2 to |primes| -1 */ for (i = 2; i < primes; i++) { - pinfo = rsa_multip_info_new(); + pinfo = ossl_rsa_multip_info_new(); if (pinfo == NULL) goto err; (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo); @@ -161,7 +188,8 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, for (;;) { redo: - if (!BN_generate_prime_ex(prime, bitsr[i] + adj, 0, NULL, NULL, cb)) + if (!BN_generate_prime_ex2(prime, bitsr[i] + adj, 0, NULL, NULL, + cb, ctx)) goto err; /* * prime should not be equal to p, q, r_3... @@ -384,10 +412,118 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value, ok = 1; err: if (ok == -1) { - RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN); + ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB); ok = 0; } BN_CTX_end(ctx); BN_CTX_free(ctx); return ok; } +#endif /* FIPS_MODULE */ + +static int rsa_keygen(OSSL_LIB_CTX *libctx, RSA *rsa, int bits, int primes, + BIGNUM *e_value, BN_GENCB *cb, int pairwise_test) +{ + int ok = 0; + +#ifdef FIPS_MODULE + ok = ossl_rsa_sp800_56b_generate_key(rsa, bits, e_value, cb); + pairwise_test = 1; /* FIPS MODE needs to always run the pairwise test */ +#else + /* + * Only multi-prime keys or insecure keys with a small key length or a + * public exponent <= 2^16 will use the older rsa_multiprime_keygen(). + */ + if (primes == 2 + && bits >= 2048 + && (e_value == NULL || BN_num_bits(e_value) > 16)) + ok = ossl_rsa_sp800_56b_generate_key(rsa, bits, e_value, cb); + else + ok = rsa_multiprime_keygen(rsa, bits, primes, e_value, cb); +#endif /* FIPS_MODULE */ + + if (pairwise_test && ok > 0) { + OSSL_CALLBACK *stcb = NULL; + void *stcbarg = NULL; + + OSSL_SELF_TEST_get_callback(libctx, &stcb, &stcbarg); + ok = rsa_keygen_pairwise_test(rsa, stcb, stcbarg); + if (!ok) { + ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); + /* Clear intermediate results */ + BN_clear_free(rsa->d); + BN_clear_free(rsa->p); + BN_clear_free(rsa->q); + BN_clear_free(rsa->dmp1); + BN_clear_free(rsa->dmq1); + BN_clear_free(rsa->iqmp); + rsa->d = NULL; + rsa->p = NULL; + rsa->q = NULL; + rsa->dmp1 = NULL; + rsa->dmq1 = NULL; + rsa->iqmp = NULL; + } + } + return ok; +} + +/* + * For RSA key generation it is not known whether the key pair will be used + * for key transport or signatures. FIPS 140-2 IG 9.9 states that in this case + * either a signature verification OR an encryption operation may be used to + * perform the pairwise consistency check. The simpler encrypt/decrypt operation + * has been chosen for this case. + */ +static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg) +{ + int ret = 0; + unsigned int ciphertxt_len; + unsigned char *ciphertxt = NULL; + const unsigned char plaintxt[16] = {0}; + unsigned char *decoded = NULL; + unsigned int decoded_len; + unsigned int plaintxt_len = (unsigned int)sizeof(plaintxt_len); + int padding = RSA_PKCS1_PADDING; + OSSL_SELF_TEST *st = NULL; + + st = OSSL_SELF_TEST_new(cb, cbarg); + if (st == NULL) + goto err; + OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, + OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1); + + ciphertxt_len = RSA_size(rsa); + /* + * RSA_private_encrypt() and RSA_private_decrypt() requires the 'to' + * parameter to be a maximum of RSA_size() - allocate space for both. + */ + ciphertxt = OPENSSL_zalloc(ciphertxt_len * 2); + if (ciphertxt == NULL) + goto err; + decoded = ciphertxt + ciphertxt_len; + + ciphertxt_len = RSA_public_encrypt(plaintxt_len, plaintxt, ciphertxt, rsa, + padding); + if (ciphertxt_len <= 0) + goto err; + if (ciphertxt_len == plaintxt_len + && memcmp(ciphertxt, plaintxt, plaintxt_len) == 0) + goto err; + + OSSL_SELF_TEST_oncorrupt_byte(st, ciphertxt); + + decoded_len = RSA_private_decrypt(ciphertxt_len, ciphertxt, decoded, rsa, + padding); + if (decoded_len != plaintxt_len + || memcmp(decoded, plaintxt, decoded_len) != 0) + goto err; + + ret = 1; +err: + OSSL_SELF_TEST_onend(st, ret); + OSSL_SELF_TEST_free(st); + OPENSSL_free(ciphertxt); + + return ret; +} diff --git a/crypto/openssl/crypto/rsa/rsa_lib.c b/crypto/openssl/crypto/rsa/rsa_lib.c index 63fd1a6db492..449097b8b27a 100644 --- a/crypto/openssl/crypto/rsa/rsa_lib.c +++ b/crypto/openssl/crypto/rsa/rsa_lib.c @@ -1,25 +1,39 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include +#include +#ifndef FIPS_MODULE +# include +#endif +#include +#include #include "internal/cryptlib.h" #include "internal/refcount.h" #include "crypto/bn.h" -#include -#include #include "crypto/evp.h" +#include "crypto/rsa.h" +#include "crypto/security_bits.h" #include "rsa_local.h" +static RSA *rsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx); + +#ifndef FIPS_MODULE RSA *RSA_new(void) { - return RSA_new_method(NULL); + return rsa_new_intern(NULL, NULL); } const RSA_METHOD *RSA_get_method(const RSA *rsa) @@ -48,28 +62,40 @@ int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) } RSA *RSA_new_method(ENGINE *engine) +{ + return rsa_new_intern(engine, NULL); +} +#endif + +RSA *ossl_rsa_new_with_ctx(OSSL_LIB_CTX *libctx) +{ + return rsa_new_intern(NULL, libctx); +} + +static RSA *rsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) { RSA *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return NULL; } ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } + ret->libctx = libctx; ret->meth = RSA_get_default_method(); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; if (engine) { if (!ENGINE_init(engine)) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_RSA, ERR_R_ENGINE_LIB); goto err; } ret->engine = engine; @@ -79,19 +105,21 @@ RSA *RSA_new_method(ENGINE *engine) if (ret->engine) { ret->meth = ENGINE_get_RSA(ret->engine); if (ret->meth == NULL) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + ERR_raise(ERR_LIB_RSA, ERR_R_ENGINE_LIB); goto err; } } #endif ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; +#ifndef FIPS_MODULE if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { goto err; } +#endif if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_INIT_FAIL); + ERR_raise(ERR_LIB_RSA, ERR_R_INIT_FAIL); goto err; } @@ -117,11 +145,13 @@ void RSA_free(RSA *r) if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) ENGINE_finish(r->engine); #endif +#ifndef FIPS_MODULE CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); +#endif CRYPTO_THREAD_lock_free(r->lock); @@ -133,11 +163,17 @@ void RSA_free(RSA *r) BN_clear_free(r->dmp1); BN_clear_free(r->dmq1); BN_clear_free(r->iqmp); + +#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) + ossl_rsa_acvp_test_free(r->acvp_test); +#endif + +#ifndef FIPS_MODULE RSA_PSS_PARAMS_free(r->pss); - sk_RSA_PRIME_INFO_pop_free(r->prime_infos, rsa_multip_info_free); + sk_RSA_PRIME_INFO_pop_free(r->prime_infos, ossl_rsa_multip_info_free); +#endif BN_BLINDING_free(r->blinding); BN_BLINDING_free(r->mt_blinding); - OPENSSL_free(r->bignum_data); OPENSSL_free(r); } @@ -153,6 +189,17 @@ int RSA_up_ref(RSA *r) return i > 1 ? 1 : 0; } +OSSL_LIB_CTX *ossl_rsa_get0_libctx(RSA *r) +{ + return r->libctx; +} + +void ossl_rsa_set0_libctx(RSA *r, OSSL_LIB_CTX *libctx) +{ + r->libctx = libctx; +} + +#ifndef FIPS_MODULE int RSA_set_ex_data(RSA *r, int idx, void *arg) { return CRYPTO_set_ex_data(&r->ex_data, idx, arg); @@ -162,19 +209,184 @@ void *RSA_get_ex_data(const RSA *r, int idx) { return CRYPTO_get_ex_data(&r->ex_data, idx); } +#endif + +/* + * Define a scaling constant for our fixed point arithmetic. + * This value must be a power of two because the base two logarithm code + * makes this assumption. The exponent must also be a multiple of three so + * that the scale factor has an exact cube root. Finally, the scale factor + * should not be so large that a multiplication of two scaled numbers + * overflows a 64 bit unsigned integer. + */ +static const unsigned int scale = 1 << 18; +static const unsigned int cbrt_scale = 1 << (2 * 18 / 3); + +/* Define some constants, none exceed 32 bits */ +static const unsigned int log_2 = 0x02c5c8; /* scale * log(2) */ +static const unsigned int log_e = 0x05c551; /* scale * log2(M_E) */ +static const unsigned int c1_923 = 0x07b126; /* scale * 1.923 */ +static const unsigned int c4_690 = 0x12c28f; /* scale * 4.690 */ + +/* + * Multiply two scaled integers together and rescale the result. + */ +static ossl_inline uint64_t mul2(uint64_t a, uint64_t b) +{ + return a * b / scale; +} + +/* + * Calculate the cube root of a 64 bit scaled integer. + * Although the cube root of a 64 bit number does fit into a 32 bit unsigned + * integer, this is not guaranteed after scaling, so this function has a + * 64 bit return. This uses the shifting nth root algorithm with some + * algebraic simplifications. + */ +static uint64_t icbrt64(uint64_t x) +{ + uint64_t r = 0; + uint64_t b; + int s; + + for (s = 63; s >= 0; s -= 3) { + r <<= 1; + b = 3 * r * (r + 1) + 1; + if ((x >> s) >= b) { + x -= b << s; + r++; + } + } + return r * cbrt_scale; +} + +/* + * Calculate the natural logarithm of a 64 bit scaled integer. + * This is done by calculating a base two logarithm and scaling. + * The maximum logarithm (base 2) is 64 and this reduces base e, so + * a 32 bit result should not overflow. The argument passed must be + * greater than unity so we don't need to handle negative results. + */ +static uint32_t ilog_e(uint64_t v) +{ + uint32_t i, r = 0; + + /* + * Scale down the value into the range 1 .. 2. + * + * If fractional numbers need to be processed, another loop needs + * to go here that checks v < scale and if so multiplies it by 2 and + * reduces r by scale. This also means making r signed. + */ + while (v >= 2 * scale) { + v >>= 1; + r += scale; + } + for (i = scale / 2; i != 0; i /= 2) { + v = mul2(v, v); + if (v >= 2 * scale) { + v >>= 1; + r += i; + } + } + r = (r * (uint64_t)scale) / log_e; + return r; +} + +/* + * NIST SP 800-56B rev 2 Appendix D: Maximum Security Strength Estimates for IFC + * Modulus Lengths. + * + * Note that this formula is also referred to in SP800-56A rev3 Appendix D: + * for FFC safe prime groups for modp and ffdhe. + * After Table 25 and Table 26 it refers to + * "The maximum security strength estimates were calculated using the formula in + * Section 7.5 of the FIPS 140 IG and rounded to the nearest multiple of eight + * bits". + * + * The formula is: + * + * E = \frac{1.923 \sqrt[3]{nBits \cdot log_e(2)} + * \cdot(log_e(nBits \cdot log_e(2))^{2/3} - 4.69}{log_e(2)} + * The two cube roots are merged together here. + */ +uint16_t ossl_ifc_ffc_compute_security_bits(int n) +{ + uint64_t x; + uint32_t lx; + uint16_t y, cap; + + /* + * Look for common values as listed in standards. + * These values are not exactly equal to the results from the formulae in + * the standards but are defined to be canonical. + */ + switch (n) { + case 2048: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */ + return 112; + case 3072: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */ + return 128; + case 4096: /* SP 800-56B rev 2 Appendix D */ + return 152; + case 6144: /* SP 800-56B rev 2 Appendix D */ + return 176; + case 7680: /* FIPS 140-2 IG 7.5 */ + return 192; + case 8192: /* SP 800-56B rev 2 Appendix D */ + return 200; + case 15360: /* FIPS 140-2 IG 7.5 */ + return 256; + } + + /* + * The first incorrect result (i.e. not accurate or off by one low) occurs + * for n = 699668. The true value here is 1200. Instead of using this n + * as the check threshold, the smallest n such that the correct result is + * 1200 is used instead. + */ + if (n >= 687737) + return 1200; + if (n < 8) + return 0; + + /* + * To ensure that the output is non-decreasing with respect to n, + * a cap needs to be applied to the two values where the function over + * estimates the strength (according to the above fast path). + */ + if (n <= 7680) + cap = 192; + else if (n <= 15360) + cap = 256; + else + cap = 1200; + + x = n * (uint64_t)log_2; + lx = ilog_e(x); + y = (uint16_t)((mul2(c1_923, icbrt64(mul2(mul2(x, lx), lx))) - c4_690) + / log_2); + y = (y + 4) & ~7; + if (y > cap) + y = cap; + return y; +} + + int RSA_security_bits(const RSA *rsa) { int bits = BN_num_bits(rsa->n); +#ifndef FIPS_MODULE if (rsa->version == RSA_ASN1_VERSION_MULTI) { /* This ought to mean that we have private key at hand. */ int ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos); - if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(bits)) + if (ex_primes <= 0 || (ex_primes + 2) > ossl_rsa_multip_cap(bits)) return 0; } - return BN_security_bits(bits, -1); +#endif + return ossl_ifc_ffc_compute_security_bits(bits); } int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) @@ -200,6 +412,7 @@ int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) r->d = d; BN_set_flags(r->d, BN_FLG_CONSTTIME); } + r->dirty_cnt++; return 1; } @@ -223,6 +436,7 @@ int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) r->q = q; BN_set_flags(r->q, BN_FLG_CONSTTIME); } + r->dirty_cnt++; return 1; } @@ -252,10 +466,12 @@ int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) r->iqmp = iqmp; BN_set_flags(r->iqmp, BN_FLG_CONSTTIME); } + r->dirty_cnt++; return 1; } +#ifndef FIPS_MODULE /* * Is it better to export RSA_PRIME_INFO structure * and related functions to let user pass a triplet? @@ -278,7 +494,7 @@ int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], old = r->prime_infos; for (i = 0; i < pnum; i++) { - pinfo = rsa_multip_info_new(); + pinfo = ossl_rsa_multip_info_new(); if (pinfo == NULL) goto err; if (primes[i] != NULL && exps[i] != NULL && coeffs[i] != NULL) { @@ -292,7 +508,7 @@ int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], BN_set_flags(pinfo->d, BN_FLG_CONSTTIME); BN_set_flags(pinfo->t, BN_FLG_CONSTTIME); } else { - rsa_multip_info_free(pinfo); + ossl_rsa_multip_info_free(pinfo); goto err; } (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo); @@ -300,7 +516,7 @@ int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], r->prime_infos = prime_infos; - if (!rsa_multip_calc_product(r)) { + if (!ossl_rsa_multip_calc_product(r)) { r->prime_infos = old; goto err; } @@ -312,17 +528,19 @@ int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], * be freed in that case. So currently, stay consistent * with other *set0* functions: just free it... */ - sk_RSA_PRIME_INFO_pop_free(old, rsa_multip_info_free); + sk_RSA_PRIME_INFO_pop_free(old, ossl_rsa_multip_info_free); } r->version = RSA_ASN1_VERSION_MULTI; + r->dirty_cnt++; return 1; err: /* r, d, t should not be freed */ - sk_RSA_PRIME_INFO_pop_free(prime_infos, rsa_multip_info_free_ex); + sk_RSA_PRIME_INFO_pop_free(prime_infos, ossl_rsa_multip_info_free_ex); return 0; } +#endif void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) @@ -343,6 +561,7 @@ void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) *q = r->q; } +#ifndef FIPS_MODULE int RSA_get_multi_prime_extra_count(const RSA *r) { int pnum; @@ -372,6 +591,7 @@ int RSA_get0_multi_prime_factors(const RSA *r, const BIGNUM *primes[]) return 1; } +#endif void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, @@ -385,6 +605,7 @@ void RSA_get0_crt_params(const RSA *r, *iqmp = r->iqmp; } +#ifndef FIPS_MODULE int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[], const BIGNUM *coeffs[]) { @@ -410,6 +631,7 @@ int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[], return 1; } +#endif const BIGNUM *RSA_get0_n(const RSA *r) { @@ -453,7 +675,29 @@ const BIGNUM *RSA_get0_iqmp(const RSA *r) const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r) { +#ifdef FIPS_MODULE + return NULL; +#else return r->pss; +#endif +} + +/* Internal */ +int ossl_rsa_set0_pss_params(RSA *r, RSA_PSS_PARAMS *pss) +{ +#ifdef FIPS_MODULE + return 0; +#else + RSA_PSS_PARAMS_free(r->pss); + r->pss = pss; + return 1; +#endif +} + +/* Internal */ +RSA_PSS_PARAMS_30 *ossl_rsa_get0_pss_params_30(RSA *r) +{ + return &r->pss_params; } void RSA_clear_flags(RSA *r, int flags) @@ -477,6 +721,7 @@ int RSA_get_version(RSA *r) return r->version; } +#ifndef FIPS_MODULE ENGINE *RSA_get0_engine(const RSA *r) { return r->engine; @@ -491,3 +736,547 @@ int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2) return -1; return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2); } +#endif + +DEFINE_STACK_OF(BIGNUM) + +int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, + const STACK_OF(BIGNUM) *exps, + const STACK_OF(BIGNUM) *coeffs) +{ +#ifndef FIPS_MODULE + STACK_OF(RSA_PRIME_INFO) *prime_infos, *old_infos = NULL; +#endif + int pnum; + + if (primes == NULL || exps == NULL || coeffs == NULL) + return 0; + + pnum = sk_BIGNUM_num(primes); + if (pnum < 2 + || pnum != sk_BIGNUM_num(exps) + || pnum != sk_BIGNUM_num(coeffs) + 1) + return 0; + + if (!RSA_set0_factors(r, sk_BIGNUM_value(primes, 0), + sk_BIGNUM_value(primes, 1)) + || !RSA_set0_crt_params(r, sk_BIGNUM_value(exps, 0), + sk_BIGNUM_value(exps, 1), + sk_BIGNUM_value(coeffs, 0))) + return 0; + +#ifndef FIPS_MODULE + old_infos = r->prime_infos; +#endif + + if (pnum > 2) { +#ifndef FIPS_MODULE + int i; + + prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum); + if (prime_infos == NULL) + return 0; + + for (i = 2; i < pnum; i++) { + BIGNUM *prime = sk_BIGNUM_value(primes, i); + BIGNUM *exp = sk_BIGNUM_value(exps, i); + BIGNUM *coeff = sk_BIGNUM_value(coeffs, i - 1); + RSA_PRIME_INFO *pinfo = NULL; + + if (!ossl_assert(prime != NULL && exp != NULL && coeff != NULL)) + goto err; + + /* Using ossl_rsa_multip_info_new() is wasteful, so allocate directly */ + if ((pinfo = OPENSSL_zalloc(sizeof(*pinfo))) == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + pinfo->r = prime; + pinfo->d = exp; + pinfo->t = coeff; + BN_set_flags(pinfo->r, BN_FLG_CONSTTIME); + BN_set_flags(pinfo->d, BN_FLG_CONSTTIME); + BN_set_flags(pinfo->t, BN_FLG_CONSTTIME); + (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo); + } + + r->prime_infos = prime_infos; + + if (!ossl_rsa_multip_calc_product(r)) { + r->prime_infos = old_infos; + goto err; + } +#else + return 0; +#endif + } + +#ifndef FIPS_MODULE + if (old_infos != NULL) { + /* + * This is hard to deal with, since the old infos could + * also be set by this function and r, d, t should not + * be freed in that case. So currently, stay consistent + * with other *set0* functions: just free it... + */ + sk_RSA_PRIME_INFO_pop_free(old_infos, ossl_rsa_multip_info_free); + } +#endif + + r->version = pnum > 2 ? RSA_ASN1_VERSION_MULTI : RSA_ASN1_VERSION_DEFAULT; + r->dirty_cnt++; + + return 1; +#ifndef FIPS_MODULE + err: + /* r, d, t should not be freed */ + sk_RSA_PRIME_INFO_pop_free(prime_infos, ossl_rsa_multip_info_free_ex); + return 0; +#endif +} + +DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) + +int ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, + STACK_OF(BIGNUM_const) *exps, + STACK_OF(BIGNUM_const) *coeffs) +{ +#ifndef FIPS_MODULE + RSA_PRIME_INFO *pinfo; + int i, pnum; +#endif + + if (r == NULL) + return 0; + + /* If |p| is NULL, there are no CRT parameters */ + if (RSA_get0_p(r) == NULL) + return 1; + + sk_BIGNUM_const_push(primes, RSA_get0_p(r)); + sk_BIGNUM_const_push(primes, RSA_get0_q(r)); + sk_BIGNUM_const_push(exps, RSA_get0_dmp1(r)); + sk_BIGNUM_const_push(exps, RSA_get0_dmq1(r)); + sk_BIGNUM_const_push(coeffs, RSA_get0_iqmp(r)); + +#ifndef FIPS_MODULE + pnum = RSA_get_multi_prime_extra_count(r); + for (i = 0; i < pnum; i++) { + pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i); + sk_BIGNUM_const_push(primes, pinfo->r); + sk_BIGNUM_const_push(exps, pinfo->d); + sk_BIGNUM_const_push(coeffs, pinfo->t); + } +#endif + + return 1; +} + +#ifndef FIPS_MODULE +/* Helpers to set or get diverse hash algorithm names */ +static int int_set_rsa_md_name(EVP_PKEY_CTX *ctx, + /* For checks */ + int keytype, int optype, + /* For EVP_PKEY_CTX_set_params() */ + const char *mdkey, const char *mdname, + const char *propkey, const char *mdprops) +{ + OSSL_PARAM params[3], *p = params; + + if (ctx == NULL || mdname == NULL || (ctx->operation & optype) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + switch (keytype) { + case -1: + if (!EVP_PKEY_CTX_is_a(ctx, "RSA") + && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS")) + return -1; + break; + default: + if (!EVP_PKEY_CTX_is_a(ctx, evp_pkey_type2name(keytype))) + return -1; + break; + } + + /* Cast away the const. This is read only so should be safe */ + *p++ = OSSL_PARAM_construct_utf8_string(mdkey, (char *)mdname, 0); + if (evp_pkey_ctx_is_provided(ctx) && mdprops != NULL) { + /* Cast away the const. This is read only so should be safe */ + *p++ = OSSL_PARAM_construct_utf8_string(propkey, (char *)mdprops, 0); + } + *p++ = OSSL_PARAM_construct_end(); + + return evp_pkey_ctx_set_params_strict(ctx, params); +} + +/* Helpers to set or get diverse hash algorithm names */ +static int int_get_rsa_md_name(EVP_PKEY_CTX *ctx, + /* For checks */ + int keytype, int optype, + /* For EVP_PKEY_CTX_get_params() */ + const char *mdkey, + char *mdname, size_t mdnamesize) +{ + OSSL_PARAM params[2], *p = params; + + if (ctx == NULL || mdname == NULL || (ctx->operation & optype) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + switch (keytype) { + case -1: + if (!EVP_PKEY_CTX_is_a(ctx, "RSA") + && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS")) + return -1; + break; + default: + if (!EVP_PKEY_CTX_is_a(ctx, evp_pkey_type2name(keytype))) + return -1; + break; + } + + /* Cast away the const. This is read only so should be safe */ + *p++ = OSSL_PARAM_construct_utf8_string(mdkey, (char *)mdname, mdnamesize); + *p++ = OSSL_PARAM_construct_end(); + + return evp_pkey_ctx_get_params_strict(ctx, params); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode) +{ + return RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, + pad_mode, NULL); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode) +{ + return RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, + 0, pad_mode); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_rsa_pss_keygen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_MD, 0, (void *)(md)); +} + +int EVP_PKEY_CTX_set_rsa_pss_keygen_md_name(EVP_PKEY_CTX *ctx, + const char *mdname, + const char *mdprops) +{ + return int_set_rsa_md_name(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, + OSSL_PKEY_PARAM_RSA_DIGEST, mdname, + OSSL_PKEY_PARAM_RSA_DIGEST_PROPS, mdprops); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)(md)); +} + +int EVP_PKEY_CTX_set_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, const char *mdname, + const char *mdprops) +{ + return + int_set_rsa_md_name(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, mdname, + OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS, mdprops); +} + +int EVP_PKEY_CTX_get_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, char *name, + size_t namesize) +{ + return int_get_rsa_md_name(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, + name, namesize); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)md); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)); +} + +int EVP_PKEY_CTX_set_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, const char *mdname, + const char *mdprops) +{ + return int_set_rsa_md_name(ctx, -1, + EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG, + OSSL_PKEY_PARAM_MGF1_DIGEST, mdname, + OSSL_PKEY_PARAM_MGF1_PROPERTIES, mdprops); +} + +int EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name, + size_t namesize) +{ + return int_get_rsa_md_name(ctx, -1, + EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG, + OSSL_PKEY_PARAM_MGF1_DIGEST, name, namesize); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)); +} + +int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md_name(EVP_PKEY_CTX *ctx, + const char *mdname) +{ + return int_set_rsa_md_name(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, + OSSL_PKEY_PARAM_MGF1_DIGEST, mdname, + NULL, NULL); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) +{ + return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)(md)); +} + +int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen) +{ + OSSL_PARAM rsa_params[2], *p = rsa_params; + int ret; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (!EVP_PKEY_CTX_is_a(ctx, "RSA")) + return -1; + + /* Cast away the const. This is read only so should be safe */ + *p++ = OSSL_PARAM_construct_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, + (void *)label, (size_t)llen); + *p++ = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, rsa_params); + if (ret <= 0) + return ret; + + /* Ownership is supposed to be transfered to the callee. */ + OPENSSL_free(label); + return 1; +} + +int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label) +{ + OSSL_PARAM rsa_params[2], *p = rsa_params; + size_t labellen; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (!EVP_PKEY_CTX_is_a(ctx, "RSA")) + return -1; + + *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, + (void **)label, 0); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_get_params(ctx, rsa_params)) + return -1; + + labellen = rsa_params[0].return_size; + if (labellen > INT_MAX) + return -1; + + return (int)labellen; +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen) +{ + /* + * For some reason, the optype was set to this: + * + * EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY + * + * However, we do use RSA-PSS with the whole gamut of diverse signature + * and verification operations, so the optype gets upgraded to this: + * + * EVP_PKEY_OP_TYPE_SIG + */ + return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, saltlen, NULL); +} + +/* + * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper, + * simply because that's easier. + */ +int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen) +{ + /* + * Because of circumstances, the optype is updated from: + * + * EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY + * + * to: + * + * EVP_PKEY_OP_TYPE_SIG + */ + return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, saltlen); +} + +int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int saltlen) +{ + OSSL_PARAM pad_params[2], *p = pad_params; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + if (!EVP_PKEY_CTX_is_a(ctx, "RSA-PSS")) + return -1; + + *p++ = OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, + &saltlen); + *p++ = OSSL_PARAM_construct_end(); + + return evp_pkey_ctx_set_params_strict(ctx, pad_params); +} + +int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) +{ + OSSL_PARAM params[2], *p = params; + size_t bits2 = bits; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (!EVP_PKEY_CTX_is_a(ctx, "RSA") + && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS")) + return -1; + + *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits2); + *p++ = OSSL_PARAM_construct_end(); + + return evp_pkey_ctx_set_params_strict(ctx, params); +} + +int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp) +{ + int ret = RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp); + + /* + * Satisfy memory semantics for pre-3.0 callers of + * EVP_PKEY_CTX_set_rsa_keygen_pubexp(): their expectation is that input + * pubexp BIGNUM becomes managed by the EVP_PKEY_CTX on success. + */ + if (ret > 0 && evp_pkey_ctx_is_provided(ctx)) { + BN_free(ctx->rsa_pubexp); + ctx->rsa_pubexp = pubexp; + } + + return ret; +} + +int EVP_PKEY_CTX_set1_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp) +{ + int ret = 0; + + /* + * When we're dealing with a provider, there's no need to duplicate + * pubexp, as it gets copied when transforming to an OSSL_PARAM anyway. + */ + if (evp_pkey_ctx_is_legacy(ctx)) { + pubexp = BN_dup(pubexp); + if (pubexp == NULL) + return 0; + } + ret = EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp); + if (evp_pkey_ctx_is_legacy(ctx) && ret <= 0) + BN_free(pubexp); + return ret; +} + +int EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes) +{ + OSSL_PARAM params[2], *p = params; + size_t primes2 = primes; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA return error */ + if (!EVP_PKEY_CTX_is_a(ctx, "RSA") + && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS")) + return -1; + + *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_PRIMES, &primes2); + *p++ = OSSL_PARAM_construct_end(); + + return evp_pkey_ctx_set_params_strict(ctx, params); +} +#endif diff --git a/crypto/openssl/crypto/rsa/rsa_local.h b/crypto/openssl/crypto/rsa/rsa_local.h index 2b94462a94c6..ea70da05ad78 100644 --- a/crypto/openssl/crypto/rsa/rsa_local.h +++ b/crypto/openssl/crypto/rsa/rsa_local.h @@ -1,17 +1,19 @@ /* - * Copyright 2006-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 +#ifndef OSSL_CRYPTO_RSA_LOCAL_H +#define OSSL_CRYPTO_RSA_LOCAL_H + #include "internal/refcount.h" +#include "crypto/rsa.h" #define RSA_MAX_PRIME_NUM 5 -#define RSA_MIN_MODULUS_BITS 512 typedef struct rsa_prime_info_st { BIGNUM *r; @@ -25,12 +27,34 @@ typedef struct rsa_prime_info_st { DECLARE_ASN1_ITEM(RSA_PRIME_INFO) DEFINE_STACK_OF(RSA_PRIME_INFO) +#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) +struct rsa_acvp_test_st { + /* optional inputs */ + BIGNUM *Xp1; + BIGNUM *Xp2; + BIGNUM *Xq1; + BIGNUM *Xq2; + BIGNUM *Xp; + BIGNUM *Xq; + + /* optional outputs */ + BIGNUM *p1; + BIGNUM *p2; + BIGNUM *q1; + BIGNUM *q2; +}; +#endif + struct rsa_st { /* - * The first parameter is used to pickup errors where this is passed - * instead of an EVP_PKEY, it is set to 0 + * #legacy + * The first field is used to pickup errors where this is passed + * instead of an EVP_PKEY. It is always zero. + * THIS MUST REMAIN THE FIRST FIELD. */ - int pad; + int dummy_zero; + + OSSL_LIB_CTX *libctx; int32_t version; const RSA_METHOD *meth; /* functional reference if 'meth' is ENGINE-provided */ @@ -43,26 +67,37 @@ struct rsa_st { BIGNUM *dmp1; BIGNUM *dmq1; BIGNUM *iqmp; + + /* + * If a PSS only key this contains the parameter restrictions. + * There are two structures for the same thing, used in different cases. + */ + /* This is used uniquely by OpenSSL provider implementations. */ + RSA_PSS_PARAMS_30 pss_params; + +#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) + RSA_ACVP_TEST *acvp_test; +#endif + +#ifndef FIPS_MODULE + /* This is used uniquely by rsa_ameth.c and rsa_pmeth.c. */ + RSA_PSS_PARAMS *pss; /* for multi-prime RSA, defined in RFC 8017 */ STACK_OF(RSA_PRIME_INFO) *prime_infos; - /* If a PSS only key this contains the parameter restrictions */ - RSA_PSS_PARAMS *pss; - /* be careful using this if the RSA structure is shared */ + /* Be careful using this if the RSA structure is shared */ CRYPTO_EX_DATA ex_data; +#endif CRYPTO_REF_COUNT references; int flags; /* Used to cache montgomery values */ BN_MONT_CTX *_method_mod_n; BN_MONT_CTX *_method_mod_p; BN_MONT_CTX *_method_mod_q; - /* - * all BIGNUM values are actually in the following data, if it is not - * NULL - */ - char *bignum_data; BN_BLINDING *blinding; BN_BLINDING *mt_blinding; CRYPTO_RWLOCK *lock; + + int dirty_cnt; }; struct rsa_meth_st { @@ -92,7 +127,7 @@ struct rsa_meth_st { * New sign and verify functions: some libraries don't allow arbitrary * data to be signed/verified: this allows them to be used. Note: for * this to work the RSA_public_decrypt() and RSA_private_encrypt() should - * *NOT* be used RSA_sign(), RSA_verify() should be used instead. + * *NOT* be used. RSA_sign(), RSA_verify() should be used instead. */ int (*rsa_sign) (int type, const unsigned char *m, unsigned int m_length, @@ -112,21 +147,50 @@ struct rsa_meth_st { BIGNUM *e, BN_GENCB *cb); }; -extern int int_rsa_verify(int dtype, const unsigned char *m, - unsigned int m_len, unsigned char *rm, - size_t *prm_len, const unsigned char *sigbuf, - size_t siglen, RSA *rsa); /* Macros to test if a pkey or ctx is for a PSS key */ #define pkey_is_pss(pkey) (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS) #define pkey_ctx_is_pss(ctx) (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) -RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, - const EVP_MD *mgf1md, int saltlen); -int rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, - const EVP_MD **pmgf1md, int *psaltlen); +RSA_PSS_PARAMS *ossl_rsa_pss_params_create(const EVP_MD *sigmd, + const EVP_MD *mgf1md, int saltlen); +int ossl_rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, + const EVP_MD **pmgf1md, int *psaltlen); /* internal function to clear and free multi-prime parameters */ -void rsa_multip_info_free_ex(RSA_PRIME_INFO *pinfo); -void rsa_multip_info_free(RSA_PRIME_INFO *pinfo); -RSA_PRIME_INFO *rsa_multip_info_new(void); -int rsa_multip_calc_product(RSA *rsa); -int rsa_multip_cap(int bits); +void ossl_rsa_multip_info_free_ex(RSA_PRIME_INFO *pinfo); +void ossl_rsa_multip_info_free(RSA_PRIME_INFO *pinfo); +RSA_PRIME_INFO *ossl_rsa_multip_info_new(void); +int ossl_rsa_multip_calc_product(RSA *rsa); +int ossl_rsa_multip_cap(int bits); + +int ossl_rsa_sp800_56b_validate_strength(int nbits, int strength); +int ossl_rsa_check_pminusq_diff(BIGNUM *diff, const BIGNUM *p, const BIGNUM *q, + int nbits); +int ossl_rsa_get_lcm(BN_CTX *ctx, const BIGNUM *p, const BIGNUM *q, + BIGNUM *lcm, BIGNUM *gcd, BIGNUM *p1, BIGNUM *q1, + BIGNUM *p1q1); + +int ossl_rsa_check_public_exponent(const BIGNUM *e); +int ossl_rsa_check_private_exponent(const RSA *rsa, int nbits, BN_CTX *ctx); +int ossl_rsa_check_prime_factor(BIGNUM *p, BIGNUM *e, int nbits, BN_CTX *ctx); +int ossl_rsa_check_prime_factor_range(const BIGNUM *p, int nbits, BN_CTX *ctx); +int ossl_rsa_check_crt_components(const RSA *rsa, BN_CTX *ctx); + +int ossl_rsa_sp800_56b_pairwise_test(RSA *rsa, BN_CTX *ctx); +int ossl_rsa_sp800_56b_check_public(const RSA *rsa); +int ossl_rsa_sp800_56b_check_private(const RSA *rsa); +int ossl_rsa_sp800_56b_check_keypair(const RSA *rsa, const BIGNUM *efixed, + int strength, int nbits); +int ossl_rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, + BN_GENCB *cb); + +int ossl_rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits, + const BIGNUM *e, BN_CTX *ctx); +int ossl_rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, + int nbits, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb); + +int ossl_rsa_padding_add_PKCS1_type_2_ex(OSSL_LIB_CTX *libctx, unsigned char *to, + int tlen, const unsigned char *from, + int flen); + +#endif /* OSSL_CRYPTO_RSA_LOCAL_H */ diff --git a/crypto/openssl/crypto/rsa/rsa_meth.c b/crypto/openssl/crypto/rsa/rsa_meth.c index 2845b79db8ef..82f13bb35976 100644 --- a/crypto/openssl/crypto/rsa/rsa_meth.c +++ b/crypto/openssl/crypto/rsa/rsa_meth.c @@ -1,12 +1,18 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "rsa_local.h" #include @@ -25,7 +31,7 @@ RSA_METHOD *RSA_meth_new(const char *name, int flags) OPENSSL_free(meth); } - RSAerr(RSA_F_RSA_METH_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -51,7 +57,7 @@ RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth) OPENSSL_free(ret); } - RSAerr(RSA_F_RSA_METH_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -65,7 +71,7 @@ int RSA_meth_set1_name(RSA_METHOD *meth, const char *name) char *tmpname = OPENSSL_strdup(name); if (tmpname == NULL) { - RSAerr(RSA_F_RSA_METH_SET1_NAME, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/crypto/openssl/crypto/rsa/rsa_mp.c b/crypto/openssl/crypto/rsa/rsa_mp.c index 44dda8f800bc..f827c0a2f8fd 100644 --- a/crypto/openssl/crypto/rsa/rsa_mp.c +++ b/crypto/openssl/crypto/rsa/rsa_mp.c @@ -1,8 +1,8 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 BaishanCloud. All rights reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,29 +12,29 @@ #include #include "rsa_local.h" -void rsa_multip_info_free_ex(RSA_PRIME_INFO *pinfo) +void ossl_rsa_multip_info_free_ex(RSA_PRIME_INFO *pinfo) { /* free pp and pinfo only */ BN_clear_free(pinfo->pp); OPENSSL_free(pinfo); } -void rsa_multip_info_free(RSA_PRIME_INFO *pinfo) +void ossl_rsa_multip_info_free(RSA_PRIME_INFO *pinfo) { - /* free a RSA_PRIME_INFO structure */ + /* free an RSA_PRIME_INFO structure */ BN_clear_free(pinfo->r); BN_clear_free(pinfo->d); BN_clear_free(pinfo->t); - rsa_multip_info_free_ex(pinfo); + ossl_rsa_multip_info_free_ex(pinfo); } -RSA_PRIME_INFO *rsa_multip_info_new(void) +RSA_PRIME_INFO *ossl_rsa_multip_info_new(void) { RSA_PRIME_INFO *pinfo; - /* create a RSA_PRIME_INFO structure */ + /* create an RSA_PRIME_INFO structure */ if ((pinfo = OPENSSL_zalloc(sizeof(RSA_PRIME_INFO))) == NULL) { - RSAerr(RSA_F_RSA_MULTIP_INFO_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return NULL; } if ((pinfo->r = BN_secure_new()) == NULL) @@ -58,7 +58,7 @@ RSA_PRIME_INFO *rsa_multip_info_new(void) } /* Refill products of primes */ -int rsa_multip_calc_product(RSA *rsa) +int ossl_rsa_multip_calc_product(RSA *rsa) { RSA_PRIME_INFO *pinfo; BIGNUM *p1 = NULL, *p2 = NULL; @@ -97,7 +97,7 @@ int rsa_multip_calc_product(RSA *rsa) return rv; } -int rsa_multip_cap(int bits) +int ossl_rsa_multip_cap(int bits) { int cap = 5; diff --git a/crypto/openssl/crypto/rsa/rsa_mp_names.c b/crypto/openssl/crypto/rsa/rsa_mp_names.c new file mode 100644 index 000000000000..8291b79e7afd --- /dev/null +++ b/crypto/openssl/crypto/rsa/rsa_mp_names.c @@ -0,0 +1,76 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "crypto/rsa.h" + +/* + * The following tables are constants used during RSA parameter building + * operations. It is easier to point to one of these fixed strings than have + * to dynamically add and generate the names on the fly. + */ + +/* + * A fixed table of names for the RSA prime factors starting with + * P,Q and up to 8 additional primes. + */ +const char *ossl_rsa_mp_factor_names[] = { + OSSL_PKEY_PARAM_RSA_FACTOR1, + OSSL_PKEY_PARAM_RSA_FACTOR2, +#ifndef FIPS_MODULE + OSSL_PKEY_PARAM_RSA_FACTOR3, + OSSL_PKEY_PARAM_RSA_FACTOR4, + OSSL_PKEY_PARAM_RSA_FACTOR5, + OSSL_PKEY_PARAM_RSA_FACTOR6, + OSSL_PKEY_PARAM_RSA_FACTOR7, + OSSL_PKEY_PARAM_RSA_FACTOR8, + OSSL_PKEY_PARAM_RSA_FACTOR9, + OSSL_PKEY_PARAM_RSA_FACTOR10, +#endif + NULL +}; + +/* + * A fixed table of names for the RSA exponents starting with + * DP,DQ and up to 8 additional exponents. + */ +const char *ossl_rsa_mp_exp_names[] = { + OSSL_PKEY_PARAM_RSA_EXPONENT1, + OSSL_PKEY_PARAM_RSA_EXPONENT2, +#ifndef FIPS_MODULE + OSSL_PKEY_PARAM_RSA_EXPONENT3, + OSSL_PKEY_PARAM_RSA_EXPONENT4, + OSSL_PKEY_PARAM_RSA_EXPONENT5, + OSSL_PKEY_PARAM_RSA_EXPONENT6, + OSSL_PKEY_PARAM_RSA_EXPONENT7, + OSSL_PKEY_PARAM_RSA_EXPONENT8, + OSSL_PKEY_PARAM_RSA_EXPONENT9, + OSSL_PKEY_PARAM_RSA_EXPONENT10, +#endif + NULL +}; + +/* + * A fixed table of names for the RSA coefficients starting with + * QINV and up to 8 additional exponents. + */ +const char *ossl_rsa_mp_coeff_names[] = { + OSSL_PKEY_PARAM_RSA_COEFFICIENT1, +#ifndef FIPS_MODULE + OSSL_PKEY_PARAM_RSA_COEFFICIENT2, + OSSL_PKEY_PARAM_RSA_COEFFICIENT3, + OSSL_PKEY_PARAM_RSA_COEFFICIENT4, + OSSL_PKEY_PARAM_RSA_COEFFICIENT5, + OSSL_PKEY_PARAM_RSA_COEFFICIENT6, + OSSL_PKEY_PARAM_RSA_COEFFICIENT7, + OSSL_PKEY_PARAM_RSA_COEFFICIENT8, + OSSL_PKEY_PARAM_RSA_COEFFICIENT9, +#endif + NULL +}; diff --git a/crypto/openssl/crypto/rsa/rsa_none.c b/crypto/openssl/crypto/rsa/rsa_none.c index f16cc67066d7..df93525fc5b8 100644 --- a/crypto/openssl/crypto/rsa/rsa_none.c +++ b/crypto/openssl/crypto/rsa/rsa_none.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" #include #include @@ -15,12 +21,12 @@ int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *from, int flen) { if (flen > tlen) { - RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return 0; } if (flen < tlen) { - RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE); return 0; } @@ -33,7 +39,7 @@ int RSA_padding_check_none(unsigned char *to, int tlen, { if (flen > tlen) { - RSAerr(RSA_F_RSA_PADDING_CHECK_NONE, RSA_R_DATA_TOO_LARGE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE); return -1; } diff --git a/crypto/openssl/crypto/rsa/rsa_oaep.c b/crypto/openssl/crypto/rsa/rsa_oaep.c index 302360a96415..d9be1a4f98c7 100644 --- a/crypto/openssl/crypto/rsa/rsa_oaep.c +++ b/crypto/openssl/crypto/rsa/rsa_oaep.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,6 +20,12 @@ * one-wayness. For the RSA function, this is an equivalent notion. */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "internal/constant_time.h" #include @@ -34,14 +40,23 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, const unsigned char *from, int flen, const unsigned char *param, int plen) { - return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen, - param, plen, NULL, NULL); + return ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(NULL, to, tlen, from, flen, + param, plen, NULL, NULL); } -int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, - const unsigned char *from, int flen, - const unsigned char *param, int plen, - const EVP_MD *md, const EVP_MD *mgf1md) +/* + * Perform the padding as per NIST 800-56B 7.2.2.3 + * from (K) is the key material. + * param (A) is the additional input. + * Step numbers are included here but not in the constant time inverse below + * to avoid complicating an already difficult enough function. + */ +int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(OSSL_LIB_CTX *libctx, + unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, + int plen, const EVP_MD *md, + const EVP_MD *mgf1md) { int rv = 0; int i, emlen = tlen - 1; @@ -50,51 +65,69 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, unsigned char seedmask[EVP_MAX_MD_SIZE]; int mdlen, dbmask_len = 0; - if (md == NULL) + if (md == NULL) { +#ifndef FIPS_MODULE md = EVP_sha1(); +#else + ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER); + return 0; +#endif + } if (mgf1md == NULL) mgf1md = md; - mdlen = EVP_MD_size(md); + mdlen = EVP_MD_get_size(md); + if (mdlen <= 0) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_LENGTH); + return 0; + } + /* step 2b: check KLen > nLen - 2 HLen - 2 */ if (flen > emlen - 2 * mdlen - 1) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return 0; } if (emlen < 2 * mdlen + 1) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, - RSA_R_KEY_SIZE_TOO_SMALL); + ERR_raise(ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL); return 0; } + /* step 3i: EM = 00000000 || maskedMGF || maskedDB */ to[0] = 0; seed = to + 1; db = to + mdlen + 1; + /* step 3a: hash the additional input */ if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) goto err; + /* step 3b: zero bytes array of length nLen - KLen - 2 HLen -2 */ memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1); + /* step 3c: DB = HA || PS || 00000001 || K */ db[emlen - flen - mdlen - 1] = 0x01; memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen); - if (RAND_bytes(seed, mdlen) <= 0) + /* step 3d: generate random byte string */ + if (RAND_bytes_ex(libctx, seed, mdlen, 0) <= 0) goto err; dbmask_len = emlen - mdlen; dbmask = OPENSSL_malloc(dbmask_len); if (dbmask == NULL) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } + /* step 3e: dbMask = MGF(mgfSeed, nLen - HLen - 1) */ if (PKCS1_MGF1(dbmask, dbmask_len, seed, mdlen, mgf1md) < 0) goto err; + /* step 3f: maskedDB = DB XOR dbMask */ for (i = 0; i < dbmask_len; i++) db[i] ^= dbmask[i]; + /* step 3g: mgfSeed = MGF(maskedDB, HLen) */ if (PKCS1_MGF1(seedmask, mdlen, db, dbmask_len, mgf1md) < 0) goto err; + /* stepo 3h: maskedMGFSeed = mgfSeed XOR mgfSeedMask */ for (i = 0; i < mdlen; i++) seed[i] ^= seedmask[i]; rv = 1; @@ -105,6 +138,15 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, return rv; } +int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md) +{ + return ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(NULL, to, tlen, from, flen, + param, plen, md, mgf1md); +} + int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, const unsigned char *from, int flen, int num, const unsigned char *param, int plen) @@ -130,12 +172,19 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, phash[EVP_MAX_MD_SIZE]; int mdlen; - if (md == NULL) + if (md == NULL) { +#ifndef FIPS_MODULE md = EVP_sha1(); +#else + ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER); + return -1; +#endif + } + if (mgf1md == NULL) mgf1md = md; - mdlen = EVP_MD_size(md); + mdlen = EVP_MD_get_size(md); if (tlen <= 0 || flen <= 0) return -1; @@ -148,22 +197,20 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, * This does not leak any side-channel information. */ if (num < flen || num < 2 * mdlen + 2) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, - RSA_R_OAEP_DECODING_ERROR); + ERR_raise(ERR_LIB_RSA, RSA_R_OAEP_DECODING_ERROR); return -1; } dblen = num - mdlen - 1; db = OPENSSL_malloc(dblen); if (db == NULL) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto cleanup; } em = OPENSSL_malloc(num); if (em == NULL) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto cleanup; } @@ -255,13 +302,18 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, to[i] = constant_time_select_8(mask, db[i + mdlen + 1], to[i]); } +#ifndef FIPS_MODULE /* * To avoid chosen ciphertext attacks, the error message should not * reveal which kind of decoding error happened. + * + * This trick doesn't work in the FIPS provider because libcrypto manages + * the error stack. Instead we opt not to put an error on the stack at all + * in case of padding failure in the FIPS provider. */ - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, - RSA_R_OAEP_DECODING_ERROR); + ERR_raise(ERR_LIB_RSA, RSA_R_OAEP_DECODING_ERROR); err_clear_last_constant_time(1 & good); +#endif cleanup: OPENSSL_cleanse(seed, sizeof(seed)); OPENSSL_clear_free(db, dblen); @@ -270,6 +322,13 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, return constant_time_select_int(good, mlen, -1); } +/* + * Mask Generation Function corresponding to section 7.2.2.2 of NIST SP 800-56B. + * The variables are named differently to NIST: + * mask (T) and len (maskLen)are the returned mask. + * seed (mgfSeed). + * The range checking steps inm the process are performed outside. + */ int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen, const EVP_MD *dgst) { @@ -282,14 +341,17 @@ int PKCS1_MGF1(unsigned char *mask, long len, if (c == NULL) goto err; - mdlen = EVP_MD_size(dgst); + mdlen = EVP_MD_get_size(dgst); if (mdlen < 0) goto err; + /* step 4 */ for (i = 0; outlen < len; i++) { + /* step 4a: D = I2BS(counter, 4) */ cnt[0] = (unsigned char)((i >> 24) & 255); cnt[1] = (unsigned char)((i >> 16) & 255); cnt[2] = (unsigned char)((i >> 8)) & 255; cnt[3] = (unsigned char)(i & 255); + /* step 4b: T =T || hash(mgfSeed || D) */ if (!EVP_DigestInit_ex(c, dgst, NULL) || !EVP_DigestUpdate(c, seed, seedlen) || !EVP_DigestUpdate(c, cnt, 4)) diff --git a/crypto/openssl/crypto/rsa/rsa_ossl.c b/crypto/openssl/crypto/rsa/rsa_ossl.c index 2e3ee4ab33dc..96fed3ca597c 100644 --- a/crypto/openssl/crypto/rsa/rsa_ossl.c +++ b/crypto/openssl/crypto/rsa/rsa_ossl.c @@ -1,12 +1,18 @@ /* * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "internal/cryptlib.h" #include "crypto/bn.h" #include "rsa_local.h" @@ -74,24 +80,24 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, BN_CTX *ctx = NULL; if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); + ERR_raise(ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE); return -1; } if (BN_ucmp(rsa->n, rsa->e) <= 0) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_E_VALUE); return -1; } /* for large moduli, enforce exponent limit */ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_E_VALUE); return -1; } } - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(rsa->libctx)) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -99,25 +105,25 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (ret == NULL || buf == NULL) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } switch (padding) { case RSA_PKCS1_PADDING: - i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); + i = ossl_rsa_padding_add_PKCS1_type_2_ex(rsa->libctx, buf, num, + from, flen); break; case RSA_PKCS1_OAEP_PADDING: - i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); - break; - case RSA_SSLV23_PADDING: - i = RSA_padding_add_SSLv23(buf, num, from, flen); + i = ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(rsa->libctx, buf, num, + from, flen, NULL, 0, + NULL, NULL); break; case RSA_NO_PADDING: i = RSA_padding_add_none(buf, num, from, flen); break; default: - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + ERR_raise(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (i <= 0) @@ -128,8 +134,7 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, if (BN_ucmp(f, rsa->n) >= 0) { /* usually the padding functions would catch this */ - RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } @@ -158,7 +163,8 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) { BN_BLINDING *ret; - CRYPTO_THREAD_write_lock(rsa->lock); + if (!CRYPTO_THREAD_write_lock(rsa->lock)) + return NULL; if (rsa->blinding == NULL) { rsa->blinding = RSA_setup_blinding(rsa, ctx); @@ -207,7 +213,9 @@ static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, */ int ret; - BN_BLINDING_lock(b); + if (!BN_BLINDING_lock(b)) + return 0; + ret = BN_BLINDING_convert_ex(f, unblind, b, ctx); BN_BLINDING_unlock(b); @@ -246,7 +254,7 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(rsa->libctx)) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -254,7 +262,7 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (ret == NULL || buf == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } @@ -268,9 +276,8 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, case RSA_NO_PADDING: i = RSA_padding_add_none(buf, num, from, flen); break; - case RSA_SSLV23_PADDING: default: - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + ERR_raise(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (i <= 0) @@ -281,8 +288,7 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, if (BN_ucmp(f, rsa->n) >= 0) { /* usually the padding functions would catch this */ - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } @@ -294,14 +300,14 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) @@ -318,11 +324,11 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, } else { BIGNUM *d = BN_new(); if (d == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } if (rsa->d == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_MISSING_PRIVATE_KEY); + ERR_raise(ERR_LIB_RSA, RSA_R_MISSING_PRIVATE_KEY); BN_free(d); goto err; } @@ -380,7 +386,7 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(rsa->libctx)) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -388,7 +394,7 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (ret == NULL || buf == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } @@ -397,8 +403,7 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, * top '0' bytes */ if (flen > num) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, - RSA_R_DATA_GREATER_THAN_MOD_LEN); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_GREATER_THAN_MOD_LEN); goto err; } @@ -407,22 +412,21 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, goto err; if (BN_ucmp(f, rsa->n) >= 0) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) @@ -440,11 +444,11 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, } else { BIGNUM *d = BN_new(); if (d == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } if (rsa->d == NULL) { - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_MISSING_PRIVATE_KEY); + ERR_raise(ERR_LIB_RSA, RSA_R_MISSING_PRIVATE_KEY); BN_free(d); goto err; } @@ -487,18 +491,22 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, case RSA_PKCS1_OAEP_PADDING: r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); break; - case RSA_SSLV23_PADDING: - r = RSA_padding_check_SSLv23(to, num, buf, j, num); - break; case RSA_NO_PADDING: memcpy(to, buf, (r = j)); break; default: - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + ERR_raise(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } - RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); +#ifndef FIPS_MODULE + /* + * This trick doesn't work in the FIPS provider because libcrypto manages + * the error stack. Instead we opt not to put an error on the stack at all + * in case of padding failure in the FIPS provider. + */ + ERR_raise(ERR_LIB_RSA, RSA_R_PADDING_CHECK_FAILED); err_clear_last_constant_time(1 & ~constant_time_msb(r)); +#endif err: BN_CTX_end(ctx); @@ -517,24 +525,24 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, BN_CTX *ctx = NULL; if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); + ERR_raise(ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE); return -1; } if (BN_ucmp(rsa->n, rsa->e) <= 0) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_E_VALUE); return -1; } /* for large moduli, enforce exponent limit */ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_E_VALUE); return -1; } } - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(rsa->libctx)) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -542,7 +550,7 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (ret == NULL || buf == NULL) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } @@ -551,7 +559,7 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, * top '0' bytes */ if (flen > num) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_GREATER_THAN_MOD_LEN); goto err; } @@ -559,8 +567,7 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, goto err; if (BN_ucmp(f, rsa->n) >= 0) { - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } @@ -578,6 +585,8 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, goto err; i = BN_bn2binpad(ret, buf, num); + if (i < 0) + goto err; switch (padding) { case RSA_PKCS1_PADDING: @@ -590,11 +599,11 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, memcpy(to, buf, (r = i)); break; default: - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + ERR_raise(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) - RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_PADDING_CHECK_FAILED); + ERR_raise(ERR_LIB_RSA, RSA_R_PADDING_CHECK_FAILED); err: BN_CTX_end(ctx); @@ -605,23 +614,31 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { - BIGNUM *r1, *m1, *vrfy, *r2, *m[RSA_MAX_PRIME_NUM - 2]; - int ret = 0, i, ex_primes = 0, smooth = 0; + BIGNUM *r1, *m1, *vrfy; + int ret = 0, smooth = 0; +#ifndef FIPS_MODULE + BIGNUM *r2, *m[RSA_MAX_PRIME_NUM - 2]; + int i, ex_primes = 0; RSA_PRIME_INFO *pinfo; +#endif BN_CTX_start(ctx); r1 = BN_CTX_get(ctx); +#ifndef FIPS_MODULE r2 = BN_CTX_get(ctx); +#endif m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); if (vrfy == NULL) goto err; +#ifndef FIPS_MODULE if (rsa->version == RSA_ASN1_VERSION_MULTI && ((ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) <= 0 || ex_primes > RSA_MAX_PRIME_NUM - 2)) goto err; +#endif if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { BIGNUM *factor = BN_new(); @@ -642,6 +659,7 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) BN_free(factor); goto err; } +#ifndef FIPS_MODULE for (i = 0; i < ex_primes; i++) { pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); BN_with_flags(factor, pinfo->r, BN_FLG_CONSTTIME); @@ -650,13 +668,16 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) goto err; } } +#endif /* * We MUST free |factor| before any further use of the prime factors */ BN_free(factor); - smooth = (ex_primes == 0) - && (rsa->meth->bn_mod_exp == BN_mod_exp_mont) + smooth = (rsa->meth->bn_mod_exp == BN_mod_exp_mont) +#ifndef FIPS_MODULE + && (ex_primes == 0) +#endif && (BN_num_bits(rsa->q) == BN_num_bits(rsa->p)); } @@ -676,15 +697,20 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) if (/* m1 = I moq q */ !bn_from_mont_fixed_top(m1, I, rsa->_method_mod_q, ctx) || !bn_to_mont_fixed_top(m1, m1, rsa->_method_mod_q, ctx) - /* m1 = m1^dmq1 mod q */ - || !BN_mod_exp_mont_consttime(m1, m1, rsa->dmq1, rsa->q, ctx, - rsa->_method_mod_q) /* r1 = I mod p */ || !bn_from_mont_fixed_top(r1, I, rsa->_method_mod_p, ctx) || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) - /* r1 = r1^dmp1 mod p */ - || !BN_mod_exp_mont_consttime(r1, r1, rsa->dmp1, rsa->p, ctx, - rsa->_method_mod_p) + /* + * Use parallel exponentiations optimization if possible, + * otherwise fallback to two sequential exponentiations: + * m1 = m1^dmq1 mod q + * r1 = r1^dmp1 mod p + */ + || !BN_mod_exp_mont_consttime_x2(m1, m1, rsa->dmq1, rsa->q, + rsa->_method_mod_q, + r1, r1, rsa->dmp1, rsa->p, + rsa->_method_mod_p, + ctx) /* r1 = (r1 - m1) mod p */ /* * bn_mod_sub_fixed_top is not regular modular subtraction, @@ -762,16 +788,7 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) BN_free(dmp1); } - /* - * calculate m_i in multi-prime case - * - * TODO: - * 1. squash the following two loops and calculate |m_i| there. - * 2. remove cc and reuse |c|. - * 3. remove |dmq1| and |dmp1| in previous block and use |di|. - * - * If these things are done, the code will be more readable. - */ +#ifndef FIPS_MODULE if (ex_primes > 0) { BIGNUM *di = BN_new(), *cc = BN_new(); @@ -811,6 +828,7 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) BN_free(cc); BN_free(di); } +#endif if (!BN_sub(r0, r0, m1)) goto err; @@ -854,6 +872,7 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) if (!BN_add(r0, r1, m1)) goto err; +#ifndef FIPS_MODULE /* add m_i to m in multi-prime case */ if (ex_primes > 0) { BIGNUM *pr2 = BN_new(); @@ -896,6 +915,7 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) } BN_free(pr2); } +#endif tail: if (rsa->e && rsa->n) { @@ -971,15 +991,18 @@ static int rsa_ossl_init(RSA *rsa) static int rsa_ossl_finish(RSA *rsa) { +#ifndef FIPS_MODULE int i; RSA_PRIME_INFO *pinfo; - BN_MONT_CTX_free(rsa->_method_mod_n); - BN_MONT_CTX_free(rsa->_method_mod_p); - BN_MONT_CTX_free(rsa->_method_mod_q); for (i = 0; i < sk_RSA_PRIME_INFO_num(rsa->prime_infos); i++) { pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); BN_MONT_CTX_free(pinfo->m); } +#endif + + BN_MONT_CTX_free(rsa->_method_mod_n); + BN_MONT_CTX_free(rsa->_method_mod_p); + BN_MONT_CTX_free(rsa->_method_mod_q); return 1; } diff --git a/crypto/openssl/crypto/rsa/rsa_pk1.c b/crypto/openssl/crypto/rsa/rsa_pk1.c index a3d0b7cef81e..51507fc030a7 100644 --- a/crypto/openssl/crypto/rsa/rsa_pk1.c +++ b/crypto/openssl/crypto/rsa/rsa_pk1.c @@ -1,19 +1,29 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "internal/constant_time.h" #include -#include "internal/cryptlib.h" #include #include #include +/* Just for the SSL_MAX_MASTER_KEY_LENGTH value */ +#include +#include "internal/cryptlib.h" +#include "crypto/rsa.h" +#include "rsa_local.h" int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, const unsigned char *from, int flen) @@ -22,8 +32,7 @@ int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, unsigned char *p; if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return 0; } @@ -63,16 +72,14 @@ int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, /* Accept inputs with and without the leading 0-byte. */ if (num == flen) { if ((*p++) != 0x00) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_INVALID_PADDING); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING); return -1; } flen--; } if ((num != (flen + 1)) || (*(p++) != 0x01)) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_BLOCK_TYPE_IS_NOT_01); + ERR_raise(ERR_LIB_RSA, RSA_R_BLOCK_TYPE_IS_NOT_01); return -1; } @@ -84,8 +91,7 @@ int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, p++; break; } else { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_BAD_FIXED_HEADER_DECRYPT); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT); return -1; } } @@ -93,20 +99,18 @@ int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, } if (i == j) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_NULL_BEFORE_BLOCK_MISSING); + ERR_raise(ERR_LIB_RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING); return -1; } if (i < 8) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_BAD_PAD_BYTE_COUNT); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_PAD_BYTE_COUNT); return -1; } i++; /* Skip over the '\0' */ j -= i; if (j > tlen) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, RSA_R_DATA_TOO_LARGE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE); return -1; } memcpy(to, p, (unsigned int)j); @@ -114,15 +118,18 @@ int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, return j; } -int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, - const unsigned char *from, int flen) +int ossl_rsa_padding_add_PKCS1_type_2_ex(OSSL_LIB_CTX *libctx, unsigned char *to, + int tlen, const unsigned char *from, + int flen) { int i, j; unsigned char *p; if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } else if (flen < 0) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_LENGTH); return 0; } @@ -134,12 +141,12 @@ int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, /* pad out with non-zero random data */ j = tlen - 3 - flen; - if (RAND_bytes(p, j) <= 0) + if (RAND_bytes_ex(libctx, p, j, 0) <= 0) return 0; for (i = 0; i < j; i++) { if (*p == '\0') do { - if (RAND_bytes(p, 1) <= 0) + if (RAND_bytes_ex(libctx, p, 1, 0) <= 0) return 0; } while (*p == '\0'); p++; @@ -151,6 +158,12 @@ int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, return 1; } +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + return ossl_rsa_padding_add_PKCS1_type_2_ex(NULL, to, tlen, from, flen); +} + int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, const unsigned char *from, int flen, int num) @@ -170,14 +183,13 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, */ if (flen > num || num < RSA_PKCS1_PADDING_SIZE) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, - RSA_R_PKCS_DECODING_ERROR); + ERR_raise(ERR_LIB_RSA, RSA_R_PKCS_DECODING_ERROR); return -1; } em = OPENSSL_malloc(num); if (em == NULL) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return -1; } /* @@ -248,8 +260,137 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, } OPENSSL_clear_free(em, num); - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR); +#ifndef FIPS_MODULE + /* + * This trick doesn't work in the FIPS provider because libcrypto manages + * the error stack. Instead we opt not to put an error on the stack at all + * in case of padding failure in the FIPS provider. + */ + ERR_raise(ERR_LIB_RSA, RSA_R_PKCS_DECODING_ERROR); err_clear_last_constant_time(1 & good); +#endif return constant_time_select_int(good, mlen, -1); } + +/* + * ossl_rsa_padding_check_PKCS1_type_2_TLS() checks and removes the PKCS1 type 2 + * padding from a decrypted RSA message in a TLS signature. The result is stored + * in the buffer pointed to by |to| which should be |tlen| bytes long. |tlen| + * must be at least SSL_MAX_MASTER_KEY_LENGTH. The original decrypted message + * should be stored in |from| which must be |flen| bytes in length and padded + * such that |flen == RSA_size()|. The TLS protocol version that the client + * originally requested should be passed in |client_version|. Some buggy clients + * can exist which use the negotiated version instead of the originally + * requested protocol version. If it is necessary to work around this bug then + * the negotiated protocol version can be passed in |alt_version|, otherwise 0 + * should be passed. + * + * If the passed message is publicly invalid or some other error that can be + * treated in non-constant time occurs then -1 is returned. On success the + * length of the decrypted data is returned. This will always be + * SSL_MAX_MASTER_KEY_LENGTH. If an error occurs that should be treated in + * constant time then this function will appear to return successfully, but the + * decrypted data will be randomly generated (as per + * https://tools.ietf.org/html/rfc5246#section-7.4.7.1). + */ +int ossl_rsa_padding_check_PKCS1_type_2_TLS(OSSL_LIB_CTX *libctx, + unsigned char *to, size_t tlen, + const unsigned char *from, + size_t flen, int client_version, + int alt_version) +{ + unsigned int i, good, version_good; + unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; + + /* + * If these checks fail then either the message in publicly invalid, or + * we've been called incorrectly. We can fail immediately. + */ + if (flen < RSA_PKCS1_PADDING_SIZE + SSL_MAX_MASTER_KEY_LENGTH + || tlen < SSL_MAX_MASTER_KEY_LENGTH) { + ERR_raise(ERR_LIB_RSA, RSA_R_PKCS_DECODING_ERROR); + return -1; + } + + /* + * Generate a random premaster secret to use in the event that we fail + * to decrypt. + */ + if (RAND_priv_bytes_ex(libctx, rand_premaster_secret, + sizeof(rand_premaster_secret), 0) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + return -1; + } + + good = constant_time_is_zero(from[0]); + good &= constant_time_eq(from[1], 2); + + /* Check we have the expected padding data */ + for (i = 2; i < flen - SSL_MAX_MASTER_KEY_LENGTH - 1; i++) + good &= ~constant_time_is_zero_8(from[i]); + good &= constant_time_is_zero_8(from[flen - SSL_MAX_MASTER_KEY_LENGTH - 1]); + + + /* + * If the version in the decrypted pre-master secret is correct then + * version_good will be 0xff, otherwise it'll be zero. The + * Klima-Pokorny-Rosa extension of Bleichenbacher's attack + * (http://eprint.iacr.org/2003/052/) exploits the version number + * check as a "bad version oracle". Thus version checks are done in + * constant time and are treated like any other decryption error. + */ + version_good = + constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH], + (client_version >> 8) & 0xff); + version_good &= + constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH + 1], + client_version & 0xff); + + /* + * The premaster secret must contain the same version number as the + * ClientHello to detect version rollback attacks (strangely, the + * protocol does not offer such protection for DH ciphersuites). + * However, buggy clients exist that send the negotiated protocol + * version instead if the server does not support the requested + * protocol version. If SSL_OP_TLS_ROLLBACK_BUG is set then we tolerate + * such clients. In that case alt_version will be non-zero and set to + * the negotiated version. + */ + if (alt_version > 0) { + unsigned int workaround_good; + + workaround_good = + constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH], + (alt_version >> 8) & 0xff); + workaround_good &= + constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH + 1], + alt_version & 0xff); + version_good |= workaround_good; + } + + good &= version_good; + + + /* + * Now copy the result over to the to buffer if good, or random data if + * not good. + */ + for (i = 0; i < SSL_MAX_MASTER_KEY_LENGTH; i++) { + to[i] = + constant_time_select_8(good, + from[flen - SSL_MAX_MASTER_KEY_LENGTH + i], + rand_premaster_secret[i]); + } + + /* + * We must not leak whether a decryption failure occurs because of + * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, + * section 7.4.7.1). The code follows that advice of the TLS RFC and + * generates a random premaster secret for the case that the decrypt + * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 + * So, whether we actually succeeded or not, return success. + */ + + return SSL_MAX_MASTER_KEY_LENGTH; +} diff --git a/crypto/openssl/crypto/rsa/rsa_pmeth.c b/crypto/openssl/crypto/rsa/rsa_pmeth.c index 0eb21c8af975..44c819a5c3ce 100644 --- a/crypto/openssl/crypto/rsa/rsa_pmeth.c +++ b/crypto/openssl/crypto/rsa/rsa_pmeth.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "internal/constant_time.h" #include @@ -19,6 +25,7 @@ #include #include #include "crypto/evp.h" +#include "crypto/rsa.h" #include "rsa_local.h" /* RSA pkey context structure */ @@ -72,7 +79,7 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx) return 1; } -static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +static int pkey_rsa_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) { RSA_PKEY_CTX *dctx, *sctx; @@ -89,6 +96,7 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) dctx->pad_mode = sctx->pad_mode; dctx->md = sctx->md; dctx->mgf1md = sctx->mgf1md; + dctx->saltlen = sctx->saltlen; if (sctx->oaep_label) { OPENSSL_free(dctx->oaep_label); dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen); @@ -103,8 +111,9 @@ static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) { if (ctx->tbuf != NULL) return 1; - if ((ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey))) == NULL) { - RSAerr(RSA_F_SETUP_TBUF, ERR_R_MALLOC_FAILURE); + if ((ctx->tbuf = + OPENSSL_malloc(RSA_size(EVP_PKEY_get0_RSA(pk->pkey)))) == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -127,40 +136,44 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, { int ret; RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; + /* + * Discard const. Its marked as const because this may be a cached copy of + * the "real" key. These calls don't make any modifications that need to + * be reflected back in the "original" key. + */ + RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey); if (rctx->md) { - if (tbslen != (size_t)EVP_MD_size(rctx->md)) { - RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); + if (tbslen != (size_t)EVP_MD_get_size(rctx->md)) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH); return -1; } - if (EVP_MD_type(rctx->md) == NID_mdc2) { + if (EVP_MD_get_type(rctx->md) == NID_mdc2) { unsigned int sltmp; if (rctx->pad_mode != RSA_PKCS1_PADDING) return -1; - ret = RSA_sign_ASN1_OCTET_STRING(0, - tbs, tbslen, sig, &sltmp, rsa); + ret = RSA_sign_ASN1_OCTET_STRING(0, tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) return ret; ret = sltmp; } else if (rctx->pad_mode == RSA_X931_PADDING) { - if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) { - RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL); + if ((size_t)RSA_size(rsa) < tbslen + 1) { + ERR_raise(ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL); return -1; } if (!setup_tbuf(rctx, ctx)) { - RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return -1; } memcpy(rctx->tbuf, tbs, tbslen); - rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md)); + rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_get_type(rctx->md)); ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, sig, rsa, RSA_X931_PADDING); } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { unsigned int sltmp; - ret = RSA_sign(EVP_MD_type(rctx->md), + ret = RSA_sign(EVP_MD_get_type(rctx->md), tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) return ret; @@ -179,8 +192,7 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, return -1; } } else { - ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, - rctx->pad_mode); + ret = RSA_private_encrypt(tbslen, tbs, sig, rsa, rctx->pad_mode); } if (ret < 0) return ret; @@ -194,34 +206,37 @@ static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, { int ret; RSA_PKEY_CTX *rctx = ctx->data; + /* + * Discard const. Its marked as const because this may be a cached copy of + * the "real" key. These calls don't make any modifications that need to + * be reflected back in the "original" key. + */ + RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey); if (rctx->md) { if (rctx->pad_mode == RSA_X931_PADDING) { if (!setup_tbuf(rctx, ctx)) return -1; - ret = RSA_public_decrypt(siglen, sig, - rctx->tbuf, ctx->pkey->pkey.rsa, + ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, rsa, RSA_X931_PADDING); if (ret < 1) return 0; ret--; - if (rctx->tbuf[ret] != RSA_X931_hash_id(EVP_MD_type(rctx->md))) { - RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, - RSA_R_ALGORITHM_MISMATCH); + if (rctx->tbuf[ret] != RSA_X931_hash_id(EVP_MD_get_type(rctx->md))) { + ERR_raise(ERR_LIB_RSA, RSA_R_ALGORITHM_MISMATCH); return 0; } - if (ret != EVP_MD_size(rctx->md)) { - RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, - RSA_R_INVALID_DIGEST_LENGTH); + if (ret != EVP_MD_get_size(rctx->md)) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH); return 0; } if (rout) memcpy(rout, rctx->tbuf, ret); } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { size_t sltmp; - ret = int_rsa_verify(EVP_MD_type(rctx->md), - NULL, 0, rout, &sltmp, - sig, siglen, ctx->pkey->pkey.rsa); + ret = ossl_rsa_verify(EVP_MD_get_type(rctx->md), + NULL, 0, rout, &sltmp, + sig, siglen, rsa); if (ret <= 0) return 0; ret = sltmp; @@ -229,8 +244,7 @@ static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, return -1; } } else { - ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa, - rctx->pad_mode); + ret = RSA_public_decrypt(siglen, sig, rout, rsa, rctx->pad_mode); } if (ret < 0) return ret; @@ -243,15 +257,20 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const unsigned char *tbs, size_t tbslen) { RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; + /* + * Discard const. Its marked as const because this may be a cached copy of + * the "real" key. These calls don't make any modifications that need to + * be reflected back in the "original" key. + */ + RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey); size_t rslen; if (rctx->md) { if (rctx->pad_mode == RSA_PKCS1_PADDING) - return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, + return RSA_verify(EVP_MD_get_type(rctx->md), tbs, tbslen, sig, siglen, rsa); - if (tbslen != (size_t)EVP_MD_size(rctx->md)) { - RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); + if (tbslen != (size_t)EVP_MD_get_size(rctx->md)) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH); return -1; } if (rctx->pad_mode == RSA_X931_PADDING) { @@ -296,9 +315,15 @@ static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, { int ret; RSA_PKEY_CTX *rctx = ctx->data; + /* + * Discard const. Its marked as const because this may be a cached copy of + * the "real" key. These calls don't make any modifications that need to + * be reflected back in the "original" key. + */ + RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey); if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { - int klen = RSA_size(ctx->pkey->pkey.rsa); + int klen = RSA_size(rsa); if (!setup_tbuf(rctx, ctx)) return -1; if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen, @@ -307,11 +332,9 @@ static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, rctx->oaep_labellen, rctx->md, rctx->mgf1md)) return -1; - ret = RSA_public_encrypt(klen, rctx->tbuf, out, - ctx->pkey->pkey.rsa, RSA_NO_PADDING); + ret = RSA_public_encrypt(klen, rctx->tbuf, out, rsa, RSA_NO_PADDING); } else { - ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa, - rctx->pad_mode); + ret = RSA_public_encrypt(inlen, in, out, rsa, rctx->pad_mode); } if (ret < 0) return ret; @@ -325,12 +348,17 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, { int ret; RSA_PKEY_CTX *rctx = ctx->data; + /* + * Discard const. Its marked as const because this may be a cached copy of + * the "real" key. These calls don't make any modifications that need to + * be reflected back in the "original" key. + */ + RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey); if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { if (!setup_tbuf(rctx, ctx)) return -1; - ret = RSA_private_decrypt(inlen, in, rctx->tbuf, - ctx->pkey->pkey.rsa, RSA_NO_PADDING); + ret = RSA_private_decrypt(inlen, in, rctx->tbuf, rsa, RSA_NO_PADDING); if (ret <= 0) return ret; ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf, @@ -339,8 +367,7 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, rctx->oaep_labellen, rctx->md, rctx->mgf1md); } else { - ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa, - rctx->pad_mode); + ret = RSA_private_decrypt(inlen, in, out, rsa, rctx->pad_mode); } *outlen = constant_time_select_s(constant_time_msb_s(ret), *outlen, ret); ret = constant_time_select_int(constant_time_msb(ret), ret, 1); @@ -354,16 +381,16 @@ static int check_padding_md(const EVP_MD *md, int padding) if (!md) return 1; - mdnid = EVP_MD_type(md); + mdnid = EVP_MD_get_type(md); if (padding == RSA_NO_PADDING) { - RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE); return 0; } if (padding == RSA_X931_PADDING) { if (RSA_X931_hash_id(mdnid) == -1) { - RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_X931_DIGEST); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_X931_DIGEST); return 0; } } else { @@ -374,6 +401,8 @@ static int check_padding_md(const EVP_MD *md, int padding) case NID_sha256: case NID_sha384: case NID_sha512: + case NID_sha512_224: + case NID_sha512_256: case NID_md5: case NID_md5_sha1: case NID_md2: @@ -387,7 +416,7 @@ static int check_padding_md(const EVP_MD *md, int padding) return 1; default: - RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_DIGEST); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_DIGEST); return 0; } @@ -424,8 +453,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; } bad_pad: - RSAerr(RSA_F_PKEY_RSA_CTRL, - RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + ERR_raise(ERR_LIB_RSA, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return -2; case EVP_PKEY_CTRL_GET_RSA_PADDING: @@ -435,7 +463,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_SALTLEN); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { @@ -446,13 +474,13 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) if (rsa_pss_restricted(rctx)) { if (p1 == RSA_PSS_SALTLEN_AUTO && ctx->operation == EVP_PKEY_OP_VERIFY) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_SALTLEN); return -2; } if ((p1 == RSA_PSS_SALTLEN_DIGEST - && rctx->min_saltlen > EVP_MD_size(rctx->md)) + && rctx->min_saltlen > EVP_MD_get_size(rctx->md)) || (p1 >= 0 && p1 < rctx->min_saltlen)) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_PSS_SALTLEN_TOO_SMALL); + ERR_raise(ERR_LIB_RSA, RSA_R_PSS_SALTLEN_TOO_SMALL); return 0; } } @@ -462,7 +490,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: if (p1 < RSA_MIN_MODULUS_BITS) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL); + ERR_raise(ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL); return -2; } rctx->nbits = p1; @@ -470,7 +498,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || BN_is_one((BIGNUM *)p2)) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_BAD_E_VALUE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_E_VALUE); return -2; } BN_free(rctx->pub_exp); @@ -479,7 +507,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES: if (p1 < RSA_DEFAULT_PRIME_NUM || p1 > RSA_MAX_PRIME_NUM) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_PRIME_NUM_INVALID); + ERR_raise(ERR_LIB_RSA, RSA_R_KEY_PRIME_NUM_INVALID); return -2; } rctx->primes = p1; @@ -488,7 +516,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_RSA_OAEP_MD: case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) @@ -501,9 +529,9 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) if (!check_padding_md(p2, rctx->pad_mode)) return 0; if (rsa_pss_restricted(rctx)) { - if (EVP_MD_type(rctx->md) == EVP_MD_type(p2)) + if (EVP_MD_get_type(rctx->md) == EVP_MD_get_type(p2)) return 1; - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_DIGEST_NOT_ALLOWED); + ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED); return 0; } rctx->md = p2; @@ -517,7 +545,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MGF1_MD); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { @@ -527,9 +555,9 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) *(const EVP_MD **)p2 = rctx->md; } else { if (rsa_pss_restricted(rctx)) { - if (EVP_MD_type(rctx->mgf1md) == EVP_MD_type(p2)) + if (EVP_MD_get_type(rctx->mgf1md) == EVP_MD_get_type(p2)) return 1; - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_MGF1_DIGEST_NOT_ALLOWED); + ERR_raise(ERR_LIB_RSA, RSA_R_MGF1_DIGEST_NOT_ALLOWED); return 0; } rctx->mgf1md = p2; @@ -538,7 +566,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_RSA_OAEP_LABEL: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE); return -2; } OPENSSL_free(rctx->oaep_label); @@ -553,7 +581,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE); return -2; } *(unsigned char **)p2 = rctx->oaep_label; @@ -576,8 +604,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; /* fall through */ case EVP_PKEY_CTRL_PEER_KEY: - RSAerr(RSA_F_PKEY_RSA_CTRL, - RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ERR_raise(ERR_LIB_RSA, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; default: @@ -590,7 +617,7 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { if (value == NULL) { - RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); + ERR_raise(ERR_LIB_RSA, RSA_R_VALUE_MISSING); return 0; } if (strcmp(type, "rsa_padding_mode") == 0) { @@ -598,8 +625,6 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, if (strcmp(value, "pkcs1") == 0) { pm = RSA_PKCS1_PADDING; - } else if (strcmp(value, "sslv23") == 0) { - pm = RSA_SSLV23_PADDING; } else if (strcmp(value, "none") == 0) { pm = RSA_NO_PADDING; } else if (strcmp(value, "oeap") == 0) { @@ -611,7 +636,7 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, } else if (strcmp(value, "pss") == 0) { pm = RSA_PKCS1_PSS_PADDING; } else { - RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); + ERR_raise(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE); return -2; } return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); @@ -643,9 +668,8 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, BIGNUM *pubexp = NULL; if (!BN_asc2bn(&pubexp, value)) return 0; - ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); - if (ret <= 0) - BN_free(pubexp); + ret = EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, pubexp); + BN_free(pubexp); return ret; } @@ -708,8 +732,9 @@ static int rsa_set_pss_param(RSA *rsa, EVP_PKEY_CTX *ctx) /* If all parameters are default values don't set pss */ if (rctx->md == NULL && rctx->mgf1md == NULL && rctx->saltlen == -2) return 1; - rsa->pss = rsa_pss_params_create(rctx->md, rctx->mgf1md, - rctx->saltlen == -2 ? 0 : rctx->saltlen); + rsa->pss = ossl_rsa_pss_params_create(rctx->md, rctx->mgf1md, + rctx->saltlen == -2 + ? 0 : rctx->saltlen); if (rsa->pss == NULL) return 0; return 1; @@ -754,7 +779,7 @@ static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) return ret; } -const EVP_PKEY_METHOD rsa_pkey_meth = { +static const EVP_PKEY_METHOD rsa_pkey_meth = { EVP_PKEY_RSA, EVP_PKEY_FLAG_AUTOARGLEN, pkey_rsa_init, @@ -789,6 +814,11 @@ const EVP_PKEY_METHOD rsa_pkey_meth = { pkey_rsa_ctrl_str }; +const EVP_PKEY_METHOD *ossl_rsa_pkey_method(void) +{ + return &rsa_pkey_meth; +} + /* * Called for PSS sign or verify initialisation: checks PSS parameter * sanity and sets any restrictions on key usage. @@ -796,7 +826,7 @@ const EVP_PKEY_METHOD rsa_pkey_meth = { static int pkey_pss_init(EVP_PKEY_CTX *ctx) { - RSA *rsa; + const RSA *rsa; RSA_PKEY_CTX *rctx = ctx->data; const EVP_MD *md; const EVP_MD *mgf1md; @@ -805,20 +835,20 @@ static int pkey_pss_init(EVP_PKEY_CTX *ctx) /* Should never happen */ if (!pkey_ctx_is_pss(ctx)) return 0; - rsa = ctx->pkey->pkey.rsa; + rsa = EVP_PKEY_get0_RSA(ctx->pkey); /* If no restrictions just return */ if (rsa->pss == NULL) return 1; /* Get and check parameters */ - if (!rsa_pss_get_param(rsa->pss, &md, &mgf1md, &min_saltlen)) + if (!ossl_rsa_pss_get_param(rsa->pss, &md, &mgf1md, &min_saltlen)) return 0; /* See if minimum salt length exceeds maximum possible */ - max_saltlen = RSA_size(rsa) - EVP_MD_size(md); + max_saltlen = RSA_size(rsa) - EVP_MD_get_size(md); if ((RSA_bits(rsa) & 0x7) == 1) max_saltlen--; if (min_saltlen > max_saltlen) { - RSAerr(RSA_F_PKEY_PSS_INIT, RSA_R_INVALID_SALT_LENGTH); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_SALT_LENGTH); return 0; } @@ -836,7 +866,7 @@ static int pkey_pss_init(EVP_PKEY_CTX *ctx) return 1; } -const EVP_PKEY_METHOD rsa_pss_pkey_meth = { +static const EVP_PKEY_METHOD rsa_pss_pkey_meth = { EVP_PKEY_RSA_PSS, EVP_PKEY_FLAG_AUTOARGLEN, pkey_rsa_init, @@ -859,3 +889,8 @@ const EVP_PKEY_METHOD rsa_pss_pkey_meth = { pkey_rsa_ctrl, pkey_rsa_ctrl_str }; + +const EVP_PKEY_METHOD *ossl_rsa_pss_pkey_method(void) +{ + return &rsa_pss_pkey_meth; +} diff --git a/crypto/openssl/crypto/rsa/rsa_prn.c b/crypto/openssl/crypto/rsa/rsa_prn.c index 23df448a5212..3a9892ebdd4a 100644 --- a/crypto/openssl/crypto/rsa/rsa_prn.c +++ b/crypto/openssl/crypto/rsa/rsa_prn.c @@ -1,12 +1,18 @@ /* * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -19,7 +25,7 @@ int RSA_print_fp(FILE *fp, const RSA *x, int off) int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_RSA, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); diff --git a/crypto/openssl/crypto/rsa/rsa_pss.c b/crypto/openssl/crypto/rsa/rsa_pss.c index 40ce1c4d378a..33874bfef8a2 100644 --- a/crypto/openssl/crypto/rsa/rsa_pss.c +++ b/crypto/openssl/crypto/rsa/rsa_pss.c @@ -1,12 +1,18 @@ /* - * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -47,7 +53,7 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, if (mgf1Hash == NULL) mgf1Hash = Hash; - hLen = EVP_MD_size(Hash); + hLen = EVP_MD_get_size(Hash); if (hLen < 0) goto err; /*- @@ -60,14 +66,14 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, if (sLen == RSA_PSS_SALTLEN_DIGEST) { sLen = hLen; } else if (sLen < RSA_PSS_SALTLEN_MAX) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + ERR_raise(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED); goto err; } MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; emLen = RSA_size(rsa); if (EM[0] & (0xFF << MSBits)) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID); + ERR_raise(ERR_LIB_RSA, RSA_R_FIRST_OCTET_INVALID); goto err; } if (MSBits == 0) { @@ -75,24 +81,24 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, emLen--; } if (emLen < hLen + 2) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE); goto err; } if (sLen == RSA_PSS_SALTLEN_MAX) { sLen = emLen - hLen - 2; } else if (sLen > emLen - hLen - 2) { /* sLen can be small negative */ - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE); goto err; } if (EM[emLen - 1] != 0xbc) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID); + ERR_raise(ERR_LIB_RSA, RSA_R_LAST_OCTET_INVALID); goto err; } maskedDBLen = emLen - hLen - 1; H = EM + maskedDBLen; DB = OPENSSL_malloc(maskedDBLen); if (DB == NULL) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) @@ -103,11 +109,13 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, DB[0] &= 0xFF >> (8 - MSBits); for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ; if (DB[i++] != 0x1) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED); + ERR_raise(ERR_LIB_RSA, RSA_R_SLEN_RECOVERY_FAILED); goto err; } if (sLen != RSA_PSS_SALTLEN_AUTO && (maskedDBLen - i) != sLen) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + ERR_raise_data(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED, + "expected: %d retrieved: %d", sLen, + maskedDBLen - i); goto err; } if (!EVP_DigestInit_ex(ctx, Hash, NULL) @@ -121,7 +129,7 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, if (!EVP_DigestFinal_ex(ctx, H_, NULL)) goto err; if (memcmp(H_, H, hLen)) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_SIGNATURE); ret = 0; } else { ret = 1; @@ -156,7 +164,7 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, if (mgf1Hash == NULL) mgf1Hash = Hash; - hLen = EVP_MD_size(Hash); + hLen = EVP_MD_get_size(Hash); if (hLen < 0) goto err; /*- @@ -171,7 +179,7 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, } else if (sLen == RSA_PSS_SALTLEN_MAX_SIGN) { sLen = RSA_PSS_SALTLEN_MAX; } else if (sLen < RSA_PSS_SALTLEN_MAX) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + ERR_raise(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED); goto err; } @@ -182,25 +190,22 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, emLen--; } if (emLen < hLen + 2) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } if (sLen == RSA_PSS_SALTLEN_MAX) { sLen = emLen - hLen - 2; } else if (sLen > emLen - hLen - 2) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } if (sLen > 0) { salt = OPENSSL_malloc(sLen); if (salt == NULL) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } - if (RAND_bytes(salt, sLen) <= 0) + if (RAND_bytes_ex(rsa->libctx, salt, sLen, 0) <= 0) goto err; } maskedDBLen = emLen - hLen - 1; @@ -250,6 +255,142 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, } +/* + * The defaults for PSS restrictions are defined in RFC 8017, A.2.3 RSASSA-PSS + * (https://tools.ietf.org/html/rfc8017#appendix-A.2.3): + * + * If the default values of the hashAlgorithm, maskGenAlgorithm, and + * trailerField fields of RSASSA-PSS-params are used, then the algorithm + * identifier will have the following value: + * + * rSASSA-PSS-Default-Identifier RSASSA-AlgorithmIdentifier ::= { + * algorithm id-RSASSA-PSS, + * parameters RSASSA-PSS-params : { + * hashAlgorithm sha1, + * maskGenAlgorithm mgf1SHA1, + * saltLength 20, + * trailerField trailerFieldBC + * } + * } + * + * RSASSA-AlgorithmIdentifier ::= AlgorithmIdentifier { + * {PKCS1Algorithms} + * } + */ +static const RSA_PSS_PARAMS_30 default_RSASSA_PSS_params = { + NID_sha1, /* default hashAlgorithm */ + { + NID_mgf1, /* default maskGenAlgorithm */ + NID_sha1 /* default MGF1 hash */ + }, + 20, /* default saltLength */ + 1 /* default trailerField (0xBC) */ +}; + +int ossl_rsa_pss_params_30_set_defaults(RSA_PSS_PARAMS_30 *rsa_pss_params) +{ + if (rsa_pss_params == NULL) + return 0; + *rsa_pss_params = default_RSASSA_PSS_params; + return 1; +} + +int ossl_rsa_pss_params_30_is_unrestricted(const RSA_PSS_PARAMS_30 *rsa_pss_params) +{ + static RSA_PSS_PARAMS_30 pss_params_cmp = { 0, }; + + return rsa_pss_params == NULL + || memcmp(rsa_pss_params, &pss_params_cmp, + sizeof(*rsa_pss_params)) == 0; +} + +int ossl_rsa_pss_params_30_copy(RSA_PSS_PARAMS_30 *to, + const RSA_PSS_PARAMS_30 *from) +{ + memcpy(to, from, sizeof(*to)); + return 1; +} + +int ossl_rsa_pss_params_30_set_hashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, + int hashalg_nid) +{ + if (rsa_pss_params == NULL) + return 0; + rsa_pss_params->hash_algorithm_nid = hashalg_nid; + return 1; +} + +int ossl_rsa_pss_params_30_set_maskgenalg(RSA_PSS_PARAMS_30 *rsa_pss_params, + int maskgenalg_nid) +{ + if (rsa_pss_params == NULL) + return 0; + rsa_pss_params->mask_gen.algorithm_nid = maskgenalg_nid; + return 1; +} + +int ossl_rsa_pss_params_30_set_maskgenhashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, + int maskgenhashalg_nid) +{ + if (rsa_pss_params == NULL) + return 0; + rsa_pss_params->mask_gen.hash_algorithm_nid = maskgenhashalg_nid; + return 1; +} + +int ossl_rsa_pss_params_30_set_saltlen(RSA_PSS_PARAMS_30 *rsa_pss_params, + int saltlen) +{ + if (rsa_pss_params == NULL) + return 0; + rsa_pss_params->salt_len = saltlen; + return 1; +} + +int ossl_rsa_pss_params_30_set_trailerfield(RSA_PSS_PARAMS_30 *rsa_pss_params, + int trailerfield) +{ + if (rsa_pss_params == NULL) + return 0; + rsa_pss_params->trailer_field = trailerfield; + return 1; +} + +int ossl_rsa_pss_params_30_hashalg(const RSA_PSS_PARAMS_30 *rsa_pss_params) +{ + if (rsa_pss_params == NULL) + return default_RSASSA_PSS_params.hash_algorithm_nid; + return rsa_pss_params->hash_algorithm_nid; +} + +int ossl_rsa_pss_params_30_maskgenalg(const RSA_PSS_PARAMS_30 *rsa_pss_params) +{ + if (rsa_pss_params == NULL) + return default_RSASSA_PSS_params.mask_gen.algorithm_nid; + return rsa_pss_params->mask_gen.algorithm_nid; +} + +int ossl_rsa_pss_params_30_maskgenhashalg(const RSA_PSS_PARAMS_30 *rsa_pss_params) +{ + if (rsa_pss_params == NULL) + return default_RSASSA_PSS_params.hash_algorithm_nid; + return rsa_pss_params->mask_gen.hash_algorithm_nid; +} + +int ossl_rsa_pss_params_30_saltlen(const RSA_PSS_PARAMS_30 *rsa_pss_params) +{ + if (rsa_pss_params == NULL) + return default_RSASSA_PSS_params.salt_len; + return rsa_pss_params->salt_len; +} + +int ossl_rsa_pss_params_30_trailerfield(const RSA_PSS_PARAMS_30 *rsa_pss_params) +{ + if (rsa_pss_params == NULL) + return default_RSASSA_PSS_params.trailer_field; + return rsa_pss_params->trailer_field; +} + #if defined(_MSC_VER) # pragma optimize("",on) #endif diff --git a/crypto/openssl/crypto/rsa/rsa_saos.c b/crypto/openssl/crypto/rsa/rsa_saos.c index 8336f32f1687..58fa50785bd5 100644 --- a/crypto/openssl/crypto/rsa/rsa_saos.c +++ b/crypto/openssl/crypto/rsa/rsa_saos.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -30,13 +36,12 @@ int RSA_sign_ASN1_OCTET_STRING(int type, i = i2d_ASN1_OCTET_STRING(&sig, NULL); j = RSA_size(rsa); if (i > (j - RSA_PKCS1_PADDING_SIZE)) { - RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, - RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); return 0; } s = OPENSSL_malloc((unsigned int)j + 1); if (s == NULL) { - RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return 0; } p = s; @@ -62,14 +67,13 @@ int RSA_verify_ASN1_OCTET_STRING(int dtype, ASN1_OCTET_STRING *sig = NULL; if (siglen != (unsigned int)RSA_size(rsa)) { - RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, - RSA_R_WRONG_SIGNATURE_LENGTH); + ERR_raise(ERR_LIB_RSA, RSA_R_WRONG_SIGNATURE_LENGTH); return 0; } s = OPENSSL_malloc((unsigned int)siglen); if (s == NULL) { - RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); @@ -84,7 +88,7 @@ int RSA_verify_ASN1_OCTET_STRING(int dtype, if (((unsigned int)sig->length != m_len) || (memcmp(m, sig->data, m_len) != 0)) { - RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, RSA_R_BAD_SIGNATURE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_SIGNATURE); } else { ret = 1; } diff --git a/crypto/openssl/crypto/rsa/rsa_schemes.c b/crypto/openssl/crypto/rsa/rsa_schemes.c new file mode 100644 index 000000000000..98ab13956dbb --- /dev/null +++ b/crypto/openssl/crypto/rsa/rsa_schemes.c @@ -0,0 +1,86 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/nelem.h" +#include "crypto/rsa.h" + +static int meth2nid(const void *meth, + int (*meth_is_a)(const void *meth, const char *name), + const OSSL_ITEM *items, size_t items_n) +{ + size_t i; + + if (meth != NULL) + for (i = 0; i < items_n; i++) + if (meth_is_a(meth, items[i].ptr)) + return (int)items[i].id; + return NID_undef; +} + +static const char *nid2name(int meth, const OSSL_ITEM *items, size_t items_n) +{ + size_t i; + + for (i = 0; i < items_n; i++) + if (meth == (int)items[i].id) + return items[i].ptr; + return NULL; +} + +/* + * The list of permitted hash functions are taken from + * https://tools.ietf.org/html/rfc8017#appendix-A.2.1: + * + * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= { + * { OID id-sha1 PARAMETERS NULL }| + * { OID id-sha224 PARAMETERS NULL }| + * { OID id-sha256 PARAMETERS NULL }| + * { OID id-sha384 PARAMETERS NULL }| + * { OID id-sha512 PARAMETERS NULL }| + * { OID id-sha512-224 PARAMETERS NULL }| + * { OID id-sha512-256 PARAMETERS NULL }, + * ... -- Allows for future expansion -- + * } + */ +static const OSSL_ITEM oaeppss_name_nid_map[] = { + { NID_sha1, OSSL_DIGEST_NAME_SHA1 }, + { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 }, + { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 }, + { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 }, + { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 }, + { NID_sha512_224, OSSL_DIGEST_NAME_SHA2_512_224 }, + { NID_sha512_256, OSSL_DIGEST_NAME_SHA2_512_256 }, +}; + +static int md_is_a(const void *md, const char *name) +{ + return EVP_MD_is_a(md, name); +} + +int ossl_rsa_oaeppss_md2nid(const EVP_MD *md) +{ + return meth2nid(md, md_is_a, + oaeppss_name_nid_map, OSSL_NELEM(oaeppss_name_nid_map)); +} + +const char *ossl_rsa_oaeppss_nid2name(int md) +{ + return nid2name(md, oaeppss_name_nid_map, OSSL_NELEM(oaeppss_name_nid_map)); +} + +const char *ossl_rsa_mgf_nid2name(int mgf) +{ + if (mgf == NID_mgf1) + return SN_mgf1; + return NULL; +} diff --git a/crypto/openssl/crypto/rsa/rsa_sign.c b/crypto/openssl/crypto/rsa/rsa_sign.c index 7fc69361bf0a..5745513c2f8e 100644 --- a/crypto/openssl/crypto/rsa/rsa_sign.c +++ b/crypto/openssl/crypto/rsa/rsa_sign.c @@ -1,81 +1,287 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include #include #include -#include -#include "crypto/x509.h" +#ifndef FIPS_MODULE +# ifndef OPENSSL_NO_MD2 +# include /* uses MD2_DIGEST_LENGTH */ +# endif +# ifndef OPENSSL_NO_MD4 +# include /* uses MD4_DIGEST_LENGTH */ +# endif +# ifndef OPENSSL_NO_MD5 +# include /* uses MD5_DIGEST_LENGTH */ +# endif +# ifndef OPENSSL_NO_MDC2 +# include /* uses MDC2_DIGEST_LENGTH */ +# endif +# ifndef OPENSSL_NO_RMD160 +# include /* uses RIPEMD160_DIGEST_LENGTH */ +# endif +#endif +#include /* uses SHA???_DIGEST_LENGTH */ +#include "crypto/rsa.h" #include "rsa_local.h" +/* + * The general purpose ASN1 code is not available inside the FIPS provider. + * To remove the dependency RSASSA-PKCS1-v1_5 DigestInfo encodings can be + * treated as a special case by pregenerating the required ASN1 encoding. + * This encoding will also be shared by the default provider. + * + * The EMSA-PKCS1-v1_5 encoding method includes an ASN.1 value of type + * DigestInfo, where the type DigestInfo has the syntax + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithm, + * digest OCTET STRING + * } + * + * DigestAlgorithm ::= AlgorithmIdentifier { + * {PKCS1-v1-5DigestAlgorithms} + * } + * + * The AlgorithmIdentifier is a sequence containing the digest OID and + * parameters (a value of type NULL). + * + * The ENCODE_DIGESTINFO_SHA() and ENCODE_DIGESTINFO_MD() macros define an + * initialized array containing the DER encoded DigestInfo for the specified + * SHA or MD digest. The content of the OCTET STRING is not included. + * |name| is the digest name. + * |n| is last byte in the encoded OID for the digest. + * |sz| is the digest length in bytes. It must not be greater than 110. + */ + +#define ASN1_SEQUENCE 0x30 +#define ASN1_OCTET_STRING 0x04 +#define ASN1_NULL 0x05 +#define ASN1_OID 0x06 + +/* SHA OIDs are of the form: (2 16 840 1 101 3 4 2 |n|) */ +#define ENCODE_DIGESTINFO_SHA(name, n, sz) \ +static const unsigned char digestinfo_##name##_der[] = { \ + ASN1_SEQUENCE, 0x11 + sz, \ + ASN1_SEQUENCE, 0x0d, \ + ASN1_OID, 0x09, 2 * 40 + 16, 0x86, 0x48, 1, 101, 3, 4, 2, n, \ + ASN1_NULL, 0x00, \ + ASN1_OCTET_STRING, sz \ +}; + +/* MD2, MD4 and MD5 OIDs are of the form: (1 2 840 113549 2 |n|) */ +#define ENCODE_DIGESTINFO_MD(name, n, sz) \ +static const unsigned char digestinfo_##name##_der[] = { \ + ASN1_SEQUENCE, 0x10 + sz, \ + ASN1_SEQUENCE, 0x0c, \ + ASN1_OID, 0x08, 1 * 40 + 2, 0x86, 0x48, 0x86, 0xf7, 0x0d, 2, n, \ + ASN1_NULL, 0x00, \ + ASN1_OCTET_STRING, sz \ +}; + +#ifndef FIPS_MODULE +# ifndef OPENSSL_NO_MD2 +ENCODE_DIGESTINFO_MD(md2, 0x02, MD2_DIGEST_LENGTH) +# endif +# ifndef OPENSSL_NO_MD4 +ENCODE_DIGESTINFO_MD(md4, 0x03, MD4_DIGEST_LENGTH) +# endif +# ifndef OPENSSL_NO_MD5 +ENCODE_DIGESTINFO_MD(md5, 0x05, MD5_DIGEST_LENGTH) +# endif +# ifndef OPENSSL_NO_MDC2 +/* MDC-2 (2 5 8 3 101) */ +static const unsigned char digestinfo_mdc2_der[] = { + ASN1_SEQUENCE, 0x0c + MDC2_DIGEST_LENGTH, + ASN1_SEQUENCE, 0x08, + ASN1_OID, 0x04, 2 * 40 + 5, 8, 3, 101, + ASN1_NULL, 0x00, + ASN1_OCTET_STRING, MDC2_DIGEST_LENGTH +}; +# endif +# ifndef OPENSSL_NO_RMD160 +/* RIPEMD160 (1 3 36 3 2 1) */ +static const unsigned char digestinfo_ripemd160_der[] = { + ASN1_SEQUENCE, 0x0d + RIPEMD160_DIGEST_LENGTH, + ASN1_SEQUENCE, 0x09, + ASN1_OID, 0x05, 1 * 40 + 3, 36, 3, 2, 1, + ASN1_NULL, 0x00, + ASN1_OCTET_STRING, RIPEMD160_DIGEST_LENGTH +}; +# endif +#endif /* FIPS_MODULE */ + +/* SHA-1 (1 3 14 3 2 26) */ +static const unsigned char digestinfo_sha1_der[] = { + ASN1_SEQUENCE, 0x0d + SHA_DIGEST_LENGTH, + ASN1_SEQUENCE, 0x09, + ASN1_OID, 0x05, 1 * 40 + 3, 14, 3, 2, 26, + ASN1_NULL, 0x00, + ASN1_OCTET_STRING, SHA_DIGEST_LENGTH +}; + +ENCODE_DIGESTINFO_SHA(sha256, 0x01, SHA256_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha384, 0x02, SHA384_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha512, 0x03, SHA512_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha224, 0x04, SHA224_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha512_224, 0x05, SHA224_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha512_256, 0x06, SHA256_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha3_224, 0x07, SHA224_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha3_256, 0x08, SHA256_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha3_384, 0x09, SHA384_DIGEST_LENGTH) +ENCODE_DIGESTINFO_SHA(sha3_512, 0x0a, SHA512_DIGEST_LENGTH) + +#define MD_CASE(name) \ + case NID_##name: \ + *len = sizeof(digestinfo_##name##_der); \ + return digestinfo_##name##_der; + +const unsigned char *ossl_rsa_digestinfo_encoding(int md_nid, size_t *len) +{ + switch (md_nid) { +#ifndef FIPS_MODULE +# ifndef OPENSSL_NO_MDC2 + MD_CASE(mdc2) +# endif +# ifndef OPENSSL_NO_MD2 + MD_CASE(md2) +# endif +# ifndef OPENSSL_NO_MD4 + MD_CASE(md4) +# endif +# ifndef OPENSSL_NO_MD5 + MD_CASE(md5) +# endif +# ifndef OPENSSL_NO_RMD160 + MD_CASE(ripemd160) +# endif +#endif /* FIPS_MODULE */ + MD_CASE(sha1) + MD_CASE(sha224) + MD_CASE(sha256) + MD_CASE(sha384) + MD_CASE(sha512) + MD_CASE(sha512_224) + MD_CASE(sha512_256) + MD_CASE(sha3_224) + MD_CASE(sha3_256) + MD_CASE(sha3_384) + MD_CASE(sha3_512) + default: + return NULL; + } +} + +#define MD_NID_CASE(name, sz) \ + case NID_##name: \ + return sz; + +static int digest_sz_from_nid(int nid) +{ + switch (nid) { +#ifndef FIPS_MODULE +# ifndef OPENSSL_NO_MDC2 + MD_NID_CASE(mdc2, MDC2_DIGEST_LENGTH) +# endif +# ifndef OPENSSL_NO_MD2 + MD_NID_CASE(md2, MD2_DIGEST_LENGTH) +# endif +# ifndef OPENSSL_NO_MD4 + MD_NID_CASE(md4, MD4_DIGEST_LENGTH) +# endif +# ifndef OPENSSL_NO_MD5 + MD_NID_CASE(md5, MD5_DIGEST_LENGTH) +# endif +# ifndef OPENSSL_NO_RMD160 + MD_NID_CASE(ripemd160, RIPEMD160_DIGEST_LENGTH) +# endif +#endif /* FIPS_MODULE */ + MD_NID_CASE(sha1, SHA_DIGEST_LENGTH) + MD_NID_CASE(sha224, SHA224_DIGEST_LENGTH) + MD_NID_CASE(sha256, SHA256_DIGEST_LENGTH) + MD_NID_CASE(sha384, SHA384_DIGEST_LENGTH) + MD_NID_CASE(sha512, SHA512_DIGEST_LENGTH) + MD_NID_CASE(sha512_224, SHA224_DIGEST_LENGTH) + MD_NID_CASE(sha512_256, SHA256_DIGEST_LENGTH) + MD_NID_CASE(sha3_224, SHA224_DIGEST_LENGTH) + MD_NID_CASE(sha3_256, SHA256_DIGEST_LENGTH) + MD_NID_CASE(sha3_384, SHA384_DIGEST_LENGTH) + MD_NID_CASE(sha3_512, SHA512_DIGEST_LENGTH) + default: + return 0; + } +} + + /* Size of an SSL signature: MD5+SHA1 */ #define SSL_SIG_LENGTH 36 /* - * encode_pkcs1 encodes a DigestInfo prefix of hash |type| and digest |m|, as + * Encodes a DigestInfo prefix of hash |type| and digest |m|, as * described in EMSA-PKCS1-v1_5-ENCODE, RFC 3447 section 9.2 step 2. This * encodes the DigestInfo (T and tLen) but does not add the padding. * * On success, it returns one and sets |*out| to a newly allocated buffer * containing the result and |*out_len| to its length. The caller must free - * |*out| with |OPENSSL_free|. Otherwise, it returns zero. + * |*out| with OPENSSL_free(). Otherwise, it returns zero. */ -static int encode_pkcs1(unsigned char **out, int *out_len, int type, - const unsigned char *m, unsigned int m_len) +static int encode_pkcs1(unsigned char **out, size_t *out_len, int type, + const unsigned char *m, size_t m_len) { - X509_SIG sig; - X509_ALGOR algor; - ASN1_TYPE parameter; - ASN1_OCTET_STRING digest; - uint8_t *der = NULL; - int len; - - sig.algor = &algor; - sig.algor->algorithm = OBJ_nid2obj(type); - if (sig.algor->algorithm == NULL) { - RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_UNKNOWN_ALGORITHM_TYPE); + size_t di_prefix_len, dig_info_len; + const unsigned char *di_prefix; + unsigned char *dig_info; + + if (type == NID_undef) { + ERR_raise(ERR_LIB_RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE); return 0; } - if (OBJ_length(sig.algor->algorithm) == 0) { - RSAerr(RSA_F_ENCODE_PKCS1, - RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); + di_prefix = ossl_rsa_digestinfo_encoding(type, &di_prefix_len); + if (di_prefix == NULL) { + ERR_raise(ERR_LIB_RSA, + RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); return 0; } - parameter.type = V_ASN1_NULL; - parameter.value.ptr = NULL; - sig.algor->parameter = ¶meter; - - sig.digest = &digest; - sig.digest->data = (unsigned char *)m; - sig.digest->length = m_len; - - len = i2d_X509_SIG(&sig, &der); - if (len < 0) + dig_info_len = di_prefix_len + m_len; + dig_info = OPENSSL_malloc(dig_info_len); + if (dig_info == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return 0; + } + memcpy(dig_info, di_prefix, di_prefix_len); + memcpy(dig_info + di_prefix_len, m, m_len); - *out = der; - *out_len = len; + *out = dig_info; + *out_len = dig_info_len; return 1; } int RSA_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa) { - int encrypt_len, encoded_len = 0, ret = 0; + int encrypt_len, ret = 0; + size_t encoded_len = 0; unsigned char *tmps = NULL; const unsigned char *encoded = NULL; - if (rsa->meth->rsa_sign) { - return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); - } +#ifndef FIPS_MODULE + if (rsa->meth->rsa_sign != NULL) + return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa) > 0; +#endif /* FIPS_MODULE */ /* Compute the encoded digest. */ if (type == NID_md5_sha1) { @@ -85,7 +291,7 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, * RSASSA-PKCS1-v1_5. */ if (m_len != SSL_SIG_LENGTH) { - RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH); return 0; } encoded_len = SSL_SIG_LENGTH; @@ -96,11 +302,11 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, encoded = tmps; } - if (encoded_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE) { - RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + if (encoded_len + RSA_PKCS1_PADDING_SIZE > (size_t)RSA_size(rsa)) { + ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); goto err; } - encrypt_len = RSA_private_encrypt(encoded_len, encoded, sigret, rsa, + encrypt_len = RSA_private_encrypt((int)encoded_len, encoded, sigret, rsa, RSA_PKCS1_PADDING); if (encrypt_len <= 0) goto err; @@ -109,42 +315,46 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, ret = 1; err: - OPENSSL_clear_free(tmps, (size_t)encoded_len); + OPENSSL_clear_free(tmps, encoded_len); return ret; } /* - * int_rsa_verify verifies an RSA signature in |sigbuf| using |rsa|. It may be - * called in two modes. If |rm| is NULL, it verifies the signature for digest - * |m|. Otherwise, it recovers the digest from the signature, writing the digest - * to |rm| and the length to |*prm_len|. |type| is the NID of the digest - * algorithm to use. It returns one on successful verification and zero - * otherwise. + * Verify an RSA signature in |sigbuf| using |rsa|. + * |type| is the NID of the digest algorithm to use. + * If |rm| is NULL, it verifies the signature for digest |m|, otherwise + * it recovers the digest from the signature, writing the digest to |rm| and + * the length to |*prm_len|. + * + * It returns one on successful verification or zero otherwise. */ -int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, - unsigned char *rm, size_t *prm_len, - const unsigned char *sigbuf, size_t siglen, RSA *rsa) +int ossl_rsa_verify(int type, const unsigned char *m, unsigned int m_len, + unsigned char *rm, size_t *prm_len, + const unsigned char *sigbuf, size_t siglen, RSA *rsa) { - int decrypt_len, ret = 0, encoded_len = 0; + int len, ret = 0; + size_t decrypt_len, encoded_len = 0; unsigned char *decrypt_buf = NULL, *encoded = NULL; if (siglen != (size_t)RSA_size(rsa)) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH); + ERR_raise(ERR_LIB_RSA, RSA_R_WRONG_SIGNATURE_LENGTH); return 0; } /* Recover the encoded digest. */ decrypt_buf = OPENSSL_malloc(siglen); if (decrypt_buf == NULL) { - RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } - decrypt_len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa, - RSA_PKCS1_PADDING); - if (decrypt_len <= 0) + len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa, + RSA_PKCS1_PADDING); + if (len <= 0) goto err; + decrypt_len = len; +#ifndef FIPS_MODULE if (type == NID_md5_sha1) { /* * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and @@ -152,7 +362,7 @@ int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, * RSASSA-PKCS1-v1_5. */ if (decrypt_len != SSL_SIG_LENGTH) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_SIGNATURE); goto err; } @@ -161,12 +371,12 @@ int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, *prm_len = SSL_SIG_LENGTH; } else { if (m_len != SSL_SIG_LENGTH) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH); goto err; } if (memcmp(decrypt_buf, m, SSL_SIG_LENGTH) != 0) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_SIGNATURE); goto err; } } @@ -181,31 +391,31 @@ int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, *prm_len = 16; } else { if (m_len != 16) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH); goto err; } if (memcmp(m, decrypt_buf + 2, 16) != 0) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_SIGNATURE); goto err; } } - } else { + } else +#endif /* FIPS_MODULE */ + { /* * If recovering the digest, extract a digest-sized output from the end * of |decrypt_buf| for |encode_pkcs1|, then compare the decryption * output as in a standard verification. */ if (rm != NULL) { - const EVP_MD *md = EVP_get_digestbynid(type); - if (md == NULL) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_UNKNOWN_ALGORITHM_TYPE); - goto err; - } + len = digest_sz_from_nid(type); - m_len = EVP_MD_size(md); - if (m_len > (size_t)decrypt_len) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); + if (len <= 0) + goto err; + m_len = (unsigned int)len; + if (m_len > decrypt_len) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH); goto err; } m = decrypt_buf + decrypt_len - m_len; @@ -216,8 +426,8 @@ int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, goto err; if (encoded_len != decrypt_len - || memcmp(encoded, decrypt_buf, encoded_len) != 0) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + || memcmp(encoded, decrypt_buf, encoded_len) != 0) { + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_SIGNATURE); goto err; } @@ -231,7 +441,7 @@ int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, ret = 1; err: - OPENSSL_clear_free(encoded, (size_t)encoded_len); + OPENSSL_clear_free(encoded, encoded_len); OPENSSL_clear_free(decrypt_buf, siglen); return ret; } @@ -240,9 +450,8 @@ int RSA_verify(int type, const unsigned char *m, unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen, RSA *rsa) { - if (rsa->meth->rsa_verify) { + if (rsa->meth->rsa_verify != NULL) return rsa->meth->rsa_verify(type, m, m_len, sigbuf, siglen, rsa); - } - return int_rsa_verify(type, m, m_len, NULL, NULL, sigbuf, siglen, rsa); + return ossl_rsa_verify(type, m, m_len, NULL, NULL, sigbuf, siglen, rsa); } diff --git a/crypto/openssl/crypto/rsa/rsa_sp800_56b_check.c b/crypto/openssl/crypto/rsa/rsa_sp800_56b_check.c new file mode 100644 index 000000000000..fc8f19b48770 --- /dev/null +++ b/crypto/openssl/crypto/rsa/rsa_sp800_56b_check.c @@ -0,0 +1,437 @@ +/* + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/bn.h" +#include "rsa_local.h" + +/* + * Part of the RSA keypair test. + * Check the Chinese Remainder Theorem components are valid. + * + * See SP800-5bBr1 + * 6.4.1.2.3: rsakpv1-crt Step 7 + * 6.4.1.3.3: rsakpv2-crt Step 7 + */ +int ossl_rsa_check_crt_components(const RSA *rsa, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *r = NULL, *p1 = NULL, *q1 = NULL; + + /* check if only some of the crt components are set */ + if (rsa->dmp1 == NULL || rsa->dmq1 == NULL || rsa->iqmp == NULL) { + if (rsa->dmp1 != NULL || rsa->dmq1 != NULL || rsa->iqmp != NULL) + return 0; + return 1; /* return ok if all components are NULL */ + } + + BN_CTX_start(ctx); + r = BN_CTX_get(ctx); + p1 = BN_CTX_get(ctx); + q1 = BN_CTX_get(ctx); + if (q1 != NULL) { + BN_set_flags(r, BN_FLG_CONSTTIME); + BN_set_flags(p1, BN_FLG_CONSTTIME); + BN_set_flags(q1, BN_FLG_CONSTTIME); + ret = 1; + } else { + ret = 0; + } + ret = ret + /* p1 = p -1 */ + && (BN_copy(p1, rsa->p) != NULL) + && BN_sub_word(p1, 1) + /* q1 = q - 1 */ + && (BN_copy(q1, rsa->q) != NULL) + && BN_sub_word(q1, 1) + /* (a) 1 < dP < (p – 1). */ + && (BN_cmp(rsa->dmp1, BN_value_one()) > 0) + && (BN_cmp(rsa->dmp1, p1) < 0) + /* (b) 1 < dQ < (q - 1). */ + && (BN_cmp(rsa->dmq1, BN_value_one()) > 0) + && (BN_cmp(rsa->dmq1, q1) < 0) + /* (c) 1 < qInv < p */ + && (BN_cmp(rsa->iqmp, BN_value_one()) > 0) + && (BN_cmp(rsa->iqmp, rsa->p) < 0) + /* (d) 1 = (dP . e) mod (p - 1)*/ + && BN_mod_mul(r, rsa->dmp1, rsa->e, p1, ctx) + && BN_is_one(r) + /* (e) 1 = (dQ . e) mod (q - 1) */ + && BN_mod_mul(r, rsa->dmq1, rsa->e, q1, ctx) + && BN_is_one(r) + /* (f) 1 = (qInv . q) mod p */ + && BN_mod_mul(r, rsa->iqmp, rsa->q, rsa->p, ctx) + && BN_is_one(r); + BN_clear(r); + BN_clear(p1); + BN_clear(q1); + BN_CTX_end(ctx); + return ret; +} + +/* + * Part of the RSA keypair test. + * Check that (√2)(2^(nbits/2 - 1) <= p <= 2^(nbits/2) - 1 + * + * See SP800-5bBr1 6.4.1.2.1 Part 5 (c) & (g) - used for both p and q. + * + * (√2)(2^(nbits/2 - 1) = (√2/2)(2^(nbits/2)) + */ +int ossl_rsa_check_prime_factor_range(const BIGNUM *p, int nbits, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *low; + int shift; + + nbits >>= 1; + shift = nbits - BN_num_bits(&ossl_bn_inv_sqrt_2); + + /* Upper bound check */ + if (BN_num_bits(p) != nbits) + return 0; + + BN_CTX_start(ctx); + low = BN_CTX_get(ctx); + if (low == NULL) + goto err; + + /* set low = (√2)(2^(nbits/2 - 1) */ + if (!BN_copy(low, &ossl_bn_inv_sqrt_2)) + goto err; + + if (shift >= 0) { + /* + * We don't have all the bits. ossl_bn_inv_sqrt_2 contains a rounded up + * value, so there is a very low probability that we'll reject a valid + * value. + */ + if (!BN_lshift(low, low, shift)) + goto err; + } else if (!BN_rshift(low, low, -shift)) { + goto err; + } + if (BN_cmp(p, low) <= 0) + goto err; + ret = 1; +err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Part of the RSA keypair test. + * Check the prime factor (for either p or q) + * i.e: p is prime AND GCD(p - 1, e) = 1 + * + * See SP800-56Br1 6.4.1.2.3 Step 5 (a to d) & (e to h). + */ +int ossl_rsa_check_prime_factor(BIGNUM *p, BIGNUM *e, int nbits, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *p1 = NULL, *gcd = NULL; + + /* (Steps 5 a-b) prime test */ + if (BN_check_prime(p, ctx, NULL) != 1 + /* (Step 5c) (√2)(2^(nbits/2 - 1) <= p <= 2^(nbits/2 - 1) */ + || ossl_rsa_check_prime_factor_range(p, nbits, ctx) != 1) + return 0; + + BN_CTX_start(ctx); + p1 = BN_CTX_get(ctx); + gcd = BN_CTX_get(ctx); + if (gcd != NULL) { + BN_set_flags(p1, BN_FLG_CONSTTIME); + BN_set_flags(gcd, BN_FLG_CONSTTIME); + ret = 1; + } else { + ret = 0; + } + ret = ret + /* (Step 5d) GCD(p-1, e) = 1 */ + && (BN_copy(p1, p) != NULL) + && BN_sub_word(p1, 1) + && BN_gcd(gcd, p1, e, ctx) + && BN_is_one(gcd); + + BN_clear(p1); + BN_CTX_end(ctx); + return ret; +} + +/* + * See SP800-56Br1 6.4.1.2.3 Part 6(a-b) Check the private exponent d + * satisfies: + * (Step 6a) 2^(nBit/2) < d < LCM(p–1, q–1). + * (Step 6b) 1 = (d*e) mod LCM(p–1, q–1) + */ +int ossl_rsa_check_private_exponent(const RSA *rsa, int nbits, BN_CTX *ctx) +{ + int ret; + BIGNUM *r, *p1, *q1, *lcm, *p1q1, *gcd; + + /* (Step 6a) 2^(nbits/2) < d */ + if (BN_num_bits(rsa->d) <= (nbits >> 1)) + return 0; + + BN_CTX_start(ctx); + r = BN_CTX_get(ctx); + p1 = BN_CTX_get(ctx); + q1 = BN_CTX_get(ctx); + lcm = BN_CTX_get(ctx); + p1q1 = BN_CTX_get(ctx); + gcd = BN_CTX_get(ctx); + if (gcd != NULL) { + BN_set_flags(r, BN_FLG_CONSTTIME); + BN_set_flags(p1, BN_FLG_CONSTTIME); + BN_set_flags(q1, BN_FLG_CONSTTIME); + BN_set_flags(lcm, BN_FLG_CONSTTIME); + BN_set_flags(p1q1, BN_FLG_CONSTTIME); + BN_set_flags(gcd, BN_FLG_CONSTTIME); + ret = 1; + } else { + ret = 0; + } + ret = (ret + /* LCM(p - 1, q - 1) */ + && (ossl_rsa_get_lcm(ctx, rsa->p, rsa->q, lcm, gcd, p1, q1, + p1q1) == 1) + /* (Step 6a) d < LCM(p - 1, q - 1) */ + && (BN_cmp(rsa->d, lcm) < 0) + /* (Step 6b) 1 = (e . d) mod LCM(p - 1, q - 1) */ + && BN_mod_mul(r, rsa->e, rsa->d, lcm, ctx) + && BN_is_one(r)); + + BN_clear(r); + BN_clear(p1); + BN_clear(q1); + BN_clear(lcm); + BN_clear(gcd); + BN_CTX_end(ctx); + return ret; +} + +/* + * Check exponent is odd. + * For FIPS also check the bit length is in the range [17..256] + */ +int ossl_rsa_check_public_exponent(const BIGNUM *e) +{ +#ifdef FIPS_MODULE + int bitlen; + + bitlen = BN_num_bits(e); + return (BN_is_odd(e) && bitlen > 16 && bitlen < 257); +#else + /* Allow small exponents larger than 1 for legacy purposes */ + return BN_is_odd(e) && BN_cmp(e, BN_value_one()) > 0; +#endif /* FIPS_MODULE */ +} + +/* + * SP800-56Br1 6.4.1.2.1 (Step 5i): |p - q| > 2^(nbits/2 - 100) + * i.e- numbits(p-q-1) > (nbits/2 -100) + */ +int ossl_rsa_check_pminusq_diff(BIGNUM *diff, const BIGNUM *p, const BIGNUM *q, + int nbits) +{ + int bitlen = (nbits >> 1) - 100; + + if (!BN_sub(diff, p, q)) + return -1; + BN_set_negative(diff, 0); + + if (BN_is_zero(diff)) + return 0; + + if (!BN_sub_word(diff, 1)) + return -1; + return (BN_num_bits(diff) > bitlen); +} + +/* + * return LCM(p-1, q-1) + * + * Caller should ensure that lcm, gcd, p1, q1, p1q1 are flagged with + * BN_FLG_CONSTTIME. + */ +int ossl_rsa_get_lcm(BN_CTX *ctx, const BIGNUM *p, const BIGNUM *q, + BIGNUM *lcm, BIGNUM *gcd, BIGNUM *p1, BIGNUM *q1, + BIGNUM *p1q1) +{ + return BN_sub(p1, p, BN_value_one()) /* p-1 */ + && BN_sub(q1, q, BN_value_one()) /* q-1 */ + && BN_mul(p1q1, p1, q1, ctx) /* (p-1)(q-1) */ + && BN_gcd(gcd, p1, q1, ctx) + && BN_div(lcm, NULL, p1q1, gcd, ctx); /* LCM((p-1, q-1)) */ +} + +/* + * SP800-56Br1 6.4.2.2 Partial Public Key Validation for RSA refers to + * SP800-89 5.3.3 (Explicit) Partial Public Key Validation for RSA + * caveat is that the modulus must be as specified in SP800-56Br1 + */ +int ossl_rsa_sp800_56b_check_public(const RSA *rsa) +{ + int ret = 0, status; + int nbits; + BN_CTX *ctx = NULL; + BIGNUM *gcd = NULL; + + if (rsa->n == NULL || rsa->e == NULL) + return 0; + + nbits = BN_num_bits(rsa->n); +#ifdef FIPS_MODULE + /* + * (Step a): modulus must be 2048 or 3072 (caveat from SP800-56Br1) + * NOTE: changed to allow keys >= 2048 + */ + if (!ossl_rsa_sp800_56b_validate_strength(nbits, -1)) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_KEY_LENGTH); + return 0; + } +#endif + if (!BN_is_odd(rsa->n)) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MODULUS); + return 0; + } + /* (Steps b-c): 2^16 < e < 2^256, n and e must be odd */ + if (!ossl_rsa_check_public_exponent(rsa->e)) { + ERR_raise(ERR_LIB_RSA, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); + return 0; + } + + ctx = BN_CTX_new_ex(rsa->libctx); + gcd = BN_new(); + if (ctx == NULL || gcd == NULL) + goto err; + + /* (Steps d-f): + * The modulus is composite, but not a power of a prime. + * The modulus has no factors smaller than 752. + */ + if (!BN_gcd(gcd, rsa->n, ossl_bn_get0_small_factors(), ctx) + || !BN_is_one(gcd)) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MODULUS); + goto err; + } + + ret = ossl_bn_miller_rabin_is_prime(rsa->n, 0, ctx, NULL, 1, &status); +#ifdef FIPS_MODULE + if (ret != 1 || status != BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME) { +#else + if (ret != 1 || (status != BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME + && (nbits >= RSA_MIN_MODULUS_BITS + || status != BN_PRIMETEST_COMPOSITE_WITH_FACTOR))) { +#endif + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MODULUS); + ret = 0; + goto err; + } + + ret = 1; +err: + BN_free(gcd); + BN_CTX_free(ctx); + return ret; +} + +/* + * Perform validation of the RSA private key to check that 0 < D < N. + */ +int ossl_rsa_sp800_56b_check_private(const RSA *rsa) +{ + if (rsa->d == NULL || rsa->n == NULL) + return 0; + return BN_cmp(rsa->d, BN_value_one()) >= 0 && BN_cmp(rsa->d, rsa->n) < 0; +} + +/* + * RSA key pair validation. + * + * SP800-56Br1. + * 6.4.1.2 "RSAKPV1 Family: RSA Key - Pair Validation with a Fixed Exponent" + * 6.4.1.3 "RSAKPV2 Family: RSA Key - Pair Validation with a Random Exponent" + * + * It uses: + * 6.4.1.2.3 "rsakpv1 - crt" + * 6.4.1.3.3 "rsakpv2 - crt" + */ +int ossl_rsa_sp800_56b_check_keypair(const RSA *rsa, const BIGNUM *efixed, + int strength, int nbits) +{ + int ret = 0; + BN_CTX *ctx = NULL; + BIGNUM *r = NULL; + + if (rsa->p == NULL + || rsa->q == NULL + || rsa->e == NULL + || rsa->d == NULL + || rsa->n == NULL) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_REQUEST); + return 0; + } + /* (Step 1): Check Ranges */ + if (!ossl_rsa_sp800_56b_validate_strength(nbits, strength)) + return 0; + + /* If the exponent is known */ + if (efixed != NULL) { + /* (2): Check fixed exponent matches public exponent. */ + if (BN_cmp(efixed, rsa->e) != 0) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_REQUEST); + return 0; + } + } + /* (Step 1.c): e is odd integer 65537 <= e < 2^256 */ + if (!ossl_rsa_check_public_exponent(rsa->e)) { + /* exponent out of range */ + ERR_raise(ERR_LIB_RSA, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); + return 0; + } + /* (Step 3.b): check the modulus */ + if (nbits != BN_num_bits(rsa->n)) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_KEYPAIR); + return 0; + } + + ctx = BN_CTX_new_ex(rsa->libctx); + if (ctx == NULL) + return 0; + + BN_CTX_start(ctx); + r = BN_CTX_get(ctx); + if (r == NULL || !BN_mul(r, rsa->p, rsa->q, ctx)) + goto err; + /* (Step 4.c): Check n = pq */ + if (BN_cmp(rsa->n, r) != 0) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_REQUEST); + goto err; + } + + /* (Step 5): check prime factors p & q */ + ret = ossl_rsa_check_prime_factor(rsa->p, rsa->e, nbits, ctx) + && ossl_rsa_check_prime_factor(rsa->q, rsa->e, nbits, ctx) + && (ossl_rsa_check_pminusq_diff(r, rsa->p, rsa->q, nbits) > 0) + /* (Step 6): Check the private exponent d */ + && ossl_rsa_check_private_exponent(rsa, nbits, ctx) + /* 6.4.1.2.3 (Step 7): Check the CRT components */ + && ossl_rsa_check_crt_components(rsa, ctx); + if (ret != 1) + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_KEYPAIR); + +err: + BN_clear(r); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; +} diff --git a/crypto/openssl/crypto/rsa/rsa_sp800_56b_gen.c b/crypto/openssl/crypto/rsa/rsa_sp800_56b_gen.c new file mode 100644 index 000000000000..df2240555bfd --- /dev/null +++ b/crypto/openssl/crypto/rsa/rsa_sp800_56b_gen.c @@ -0,0 +1,440 @@ +/* + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include "crypto/bn.h" +#include "crypto/security_bits.h" +#include "rsa_local.h" + +#define RSA_FIPS1864_MIN_KEYGEN_KEYSIZE 2048 +#define RSA_FIPS1864_MIN_KEYGEN_STRENGTH 112 + +/* + * Generate probable primes 'p' & 'q'. See FIPS 186-4 Section B.3.6 + * "Generation of Probable Primes with Conditions Based on Auxiliary Probable + * Primes". + * + * Params: + * rsa Object used to store primes p & q. + * test Object used for CAVS testing only.that contains.. + * p1, p2 The returned auxiliary primes for p. + * If NULL they are not returned. + * Xpout An optionally returned random number used during generation of p. + * Xp An optional passed in value (that is random number used during + * generation of p). + * Xp1, Xp2 Optionally passed in randomly generated numbers from which + * auxiliary primes p1 & p2 are calculated. If NULL these values + * are generated internally. + * q1, q2 The returned auxiliary primes for q. + * If NULL they are not returned. + * Xqout An optionally returned random number used during generation of q. + * Xq An optional passed in value (that is random number used during + * generation of q). + * Xq1, Xq2 Optionally passed in randomly generated numbers from which + * auxiliary primes q1 & q2 are calculated. If NULL these values + * are generated internally. + * nbits The key size in bits (The size of the modulus n). + * e The public exponent. + * ctx A BN_CTX object. + * cb An optional BIGNUM callback. + * Returns: 1 if successful, or 0 otherwise. + * Notes: + * p1, p2, q1, q2, Xpout, Xqout are returned if they are not NULL. + * Xp, Xp1, Xp2, Xq, Xq1, Xq2 are optionally passed in. + * (Required for CAVS testing). + */ +int ossl_rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, + int nbits, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb) +{ + int ret = 0, ok; + /* Temp allocated BIGNUMS */ + BIGNUM *Xpo = NULL, *Xqo = NULL, *tmp = NULL; + /* Intermediate BIGNUMS that can be returned for testing */ + BIGNUM *p1 = NULL, *p2 = NULL; + BIGNUM *q1 = NULL, *q2 = NULL; + /* Intermediate BIGNUMS that can be input for testing */ + BIGNUM *Xpout = NULL, *Xqout = NULL; + BIGNUM *Xp = NULL, *Xp1 = NULL, *Xp2 = NULL; + BIGNUM *Xq = NULL, *Xq1 = NULL, *Xq2 = NULL; + +#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) + if (test != NULL) { + Xp1 = test->Xp1; + Xp2 = test->Xp2; + Xq1 = test->Xq1; + Xq2 = test->Xq2; + Xp = test->Xp; + Xq = test->Xq; + p1 = test->p1; + p2 = test->p2; + q1 = test->q1; + q2 = test->q2; + } +#endif + + /* (Step 1) Check key length + * NOTE: SP800-131A Rev1 Disallows key lengths of < 2048 bits for RSA + * Signature Generation and Key Agree/Transport. + */ + if (nbits < RSA_FIPS1864_MIN_KEYGEN_KEYSIZE) { + ERR_raise(ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + if (!ossl_rsa_check_public_exponent(e)) { + ERR_raise(ERR_LIB_RSA, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); + return 0; + } + + /* (Step 3) Determine strength and check rand generator strength is ok - + * this step is redundant because the generator always returns a higher + * strength than is required. + */ + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + Xpo = (Xpout != NULL) ? Xpout : BN_CTX_get(ctx); + Xqo = (Xqout != NULL) ? Xqout : BN_CTX_get(ctx); + if (tmp == NULL || Xpo == NULL || Xqo == NULL) + goto err; + BN_set_flags(Xpo, BN_FLG_CONSTTIME); + BN_set_flags(Xqo, BN_FLG_CONSTTIME); + + if (rsa->p == NULL) + rsa->p = BN_secure_new(); + if (rsa->q == NULL) + rsa->q = BN_secure_new(); + if (rsa->p == NULL || rsa->q == NULL) + goto err; + BN_set_flags(rsa->p, BN_FLG_CONSTTIME); + BN_set_flags(rsa->q, BN_FLG_CONSTTIME); + + /* (Step 4) Generate p, Xp */ + if (!ossl_bn_rsa_fips186_4_gen_prob_primes(rsa->p, Xpo, p1, p2, Xp, Xp1, Xp2, + nbits, e, ctx, cb)) + goto err; + for(;;) { + /* (Step 5) Generate q, Xq*/ + if (!ossl_bn_rsa_fips186_4_gen_prob_primes(rsa->q, Xqo, q1, q2, Xq, Xq1, + Xq2, nbits, e, ctx, cb)) + goto err; + + /* (Step 6) |Xp - Xq| > 2^(nbitlen/2 - 100) */ + ok = ossl_rsa_check_pminusq_diff(tmp, Xpo, Xqo, nbits); + if (ok < 0) + goto err; + if (ok == 0) + continue; + + /* (Step 6) |p - q| > 2^(nbitlen/2 - 100) */ + ok = ossl_rsa_check_pminusq_diff(tmp, rsa->p, rsa->q, nbits); + if (ok < 0) + goto err; + if (ok == 0) + continue; + break; /* successfully finished */ + } + rsa->dirty_cnt++; + ret = 1; +err: + /* Zeroize any internally generated values that are not returned */ + if (Xpo != Xpout) + BN_clear(Xpo); + if (Xqo != Xqout) + BN_clear(Xqo); + BN_clear(tmp); + + BN_CTX_end(ctx); + return ret; +} + +/* + * Validates the RSA key size based on the target strength. + * See SP800-56Br1 6.3.1.1 (Steps 1a-1b) + * + * Params: + * nbits The key size in bits. + * strength The target strength in bits. -1 means the target + * strength is unknown. + * Returns: 1 if the key size matches the target strength, or 0 otherwise. + */ +int ossl_rsa_sp800_56b_validate_strength(int nbits, int strength) +{ + int s = (int)ossl_ifc_ffc_compute_security_bits(nbits); + +#ifdef FIPS_MODULE + if (s < RSA_FIPS1864_MIN_KEYGEN_STRENGTH) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MODULUS); + return 0; + } +#endif + if (strength != -1 && s != strength) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_STRENGTH); + return 0; + } + return 1; +} + +/* + * Validate that the random bit generator is of sufficient strength to generate + * a key of the specified length. + */ +static int rsa_validate_rng_strength(EVP_RAND_CTX *rng, int nbits) +{ + if (rng == NULL) + return 0; +#ifdef FIPS_MODULE + /* + * This should become mainstream once similar tests are added to the other + * key generations and once there is a way to disable these checks. + */ + if (EVP_RAND_get_strength(rng) < ossl_ifc_ffc_compute_security_bits(nbits)) { + ERR_raise(ERR_LIB_RSA, + RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT); + return 0; + } +#endif + return 1; +} + +/* + * + * Using p & q, calculate other required parameters such as n, d. + * as well as the CRT parameters dP, dQ, qInv. + * + * See SP800-56Br1 + * 6.3.1.1 rsakpg1 - basic (Steps 3-4) + * 6.3.1.3 rsakpg1 - crt (Step 5) + * + * Params: + * rsa An rsa object. + * nbits The key size. + * e The public exponent. + * ctx A BN_CTX object. + * Notes: + * There is a small chance that the generated d will be too small. + * Returns: -1 = error, + * 0 = d is too small, + * 1 = success. + */ +int ossl_rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits, + const BIGNUM *e, BN_CTX *ctx) +{ + int ret = -1; + BIGNUM *p1, *q1, *lcm, *p1q1, *gcd; + + BN_CTX_start(ctx); + p1 = BN_CTX_get(ctx); + q1 = BN_CTX_get(ctx); + lcm = BN_CTX_get(ctx); + p1q1 = BN_CTX_get(ctx); + gcd = BN_CTX_get(ctx); + if (gcd == NULL) + goto err; + + BN_set_flags(p1, BN_FLG_CONSTTIME); + BN_set_flags(q1, BN_FLG_CONSTTIME); + BN_set_flags(lcm, BN_FLG_CONSTTIME); + BN_set_flags(p1q1, BN_FLG_CONSTTIME); + BN_set_flags(gcd, BN_FLG_CONSTTIME); + + /* LCM((p-1, q-1)) */ + if (ossl_rsa_get_lcm(ctx, rsa->p, rsa->q, lcm, gcd, p1, q1, p1q1) != 1) + goto err; + + /* copy e */ + BN_free(rsa->e); + rsa->e = BN_dup(e); + if (rsa->e == NULL) + goto err; + + BN_clear_free(rsa->d); + /* (Step 3) d = (e^-1) mod (LCM(p-1, q-1)) */ + rsa->d = BN_secure_new(); + if (rsa->d == NULL) + goto err; + BN_set_flags(rsa->d, BN_FLG_CONSTTIME); + if (BN_mod_inverse(rsa->d, e, lcm, ctx) == NULL) + goto err; + + /* (Step 3) return an error if d is too small */ + if (BN_num_bits(rsa->d) <= (nbits >> 1)) { + ret = 0; + goto err; + } + + /* (Step 4) n = pq */ + if (rsa->n == NULL) + rsa->n = BN_new(); + if (rsa->n == NULL || !BN_mul(rsa->n, rsa->p, rsa->q, ctx)) + goto err; + + /* (Step 5a) dP = d mod (p-1) */ + if (rsa->dmp1 == NULL) + rsa->dmp1 = BN_secure_new(); + if (rsa->dmp1 == NULL) + goto err; + BN_set_flags(rsa->dmp1, BN_FLG_CONSTTIME); + if (!BN_mod(rsa->dmp1, rsa->d, p1, ctx)) + goto err; + + /* (Step 5b) dQ = d mod (q-1) */ + if (rsa->dmq1 == NULL) + rsa->dmq1 = BN_secure_new(); + if (rsa->dmq1 == NULL) + goto err; + BN_set_flags(rsa->dmq1, BN_FLG_CONSTTIME); + if (!BN_mod(rsa->dmq1, rsa->d, q1, ctx)) + goto err; + + /* (Step 5c) qInv = (inverse of q) mod p */ + BN_free(rsa->iqmp); + rsa->iqmp = BN_secure_new(); + if (rsa->iqmp == NULL) + goto err; + BN_set_flags(rsa->iqmp, BN_FLG_CONSTTIME); + if (BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx) == NULL) + goto err; + + rsa->dirty_cnt++; + ret = 1; +err: + if (ret != 1) { + BN_free(rsa->e); + rsa->e = NULL; + BN_free(rsa->d); + rsa->d = NULL; + BN_free(rsa->n); + rsa->n = NULL; + BN_free(rsa->iqmp); + rsa->iqmp = NULL; + BN_free(rsa->dmq1); + rsa->dmq1 = NULL; + BN_free(rsa->dmp1); + rsa->dmp1 = NULL; + } + BN_clear(p1); + BN_clear(q1); + BN_clear(lcm); + BN_clear(p1q1); + BN_clear(gcd); + + BN_CTX_end(ctx); + return ret; +} + +/* + * Generate a SP800-56B RSA key. + * + * See SP800-56Br1 6.3.1 "RSA Key-Pair Generation with a Fixed Public Exponent" + * 6.3.1.1 rsakpg1 - basic + * 6.3.1.3 rsakpg1 - crt + * + * See also FIPS 186-4 Section B.3.6 + * "Generation of Probable Primes with Conditions Based on Auxiliary + * Probable Primes." + * + * Params: + * rsa The rsa object. + * nbits The intended key size in bits. + * efixed The public exponent. If NULL a default of 65537 is used. + * cb An optional BIGNUM callback. + * Returns: 1 if successfully generated otherwise it returns 0. + */ +int ossl_rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, + BN_GENCB *cb) +{ + int ret = 0; + int ok; + BN_CTX *ctx = NULL; + BIGNUM *e = NULL; + RSA_ACVP_TEST *info = NULL; + +#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) + info = rsa->acvp_test; +#endif + + /* (Steps 1a-1b) : Currently ignores the strength check */ + if (!ossl_rsa_sp800_56b_validate_strength(nbits, -1)) + return 0; + + /* Check that the RNG is capable of generating a key this large */ + if (!rsa_validate_rng_strength(RAND_get0_private(rsa->libctx), nbits)) + return 0; + + ctx = BN_CTX_new_ex(rsa->libctx); + if (ctx == NULL) + return 0; + + /* Set default if e is not passed in */ + if (efixed == NULL) { + e = BN_new(); + if (e == NULL || !BN_set_word(e, 65537)) + goto err; + } else { + e = (BIGNUM *)efixed; + } + /* (Step 1c) fixed exponent is checked later .*/ + + for (;;) { + /* (Step 2) Generate prime factors */ + if (!ossl_rsa_fips186_4_gen_prob_primes(rsa, info, nbits, e, ctx, cb)) + goto err; + /* (Steps 3-5) Compute params d, n, dP, dQ, qInv */ + ok = ossl_rsa_sp800_56b_derive_params_from_pq(rsa, nbits, e, ctx); + if (ok < 0) + goto err; + if (ok > 0) + break; + /* Gets here if computed d is too small - so try again */ + } + + /* (Step 6) Do pairwise test - optional validity test has been omitted */ + ret = ossl_rsa_sp800_56b_pairwise_test(rsa, ctx); +err: + if (efixed == NULL) + BN_free(e); + BN_CTX_free(ctx); + return ret; +} + +/* + * See SP800-56Br1 6.3.1.3 (Step 6) Perform a pair-wise consistency test by + * verifying that: k = (k^e)^d mod n for some integer k where 1 < k < n-1. + * + * Returns 1 if the RSA key passes the pairwise test or 0 it it fails. + */ +int ossl_rsa_sp800_56b_pairwise_test(RSA *rsa, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *k, *tmp; + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + k = BN_CTX_get(ctx); + if (k == NULL) + goto err; + BN_set_flags(k, BN_FLG_CONSTTIME); + + ret = (BN_set_word(k, 2) + && BN_mod_exp(tmp, k, rsa->e, rsa->n, ctx) + && BN_mod_exp(tmp, tmp, rsa->d, rsa->n, ctx) + && BN_cmp(k, tmp) == 0); + if (ret == 0) + ERR_raise(ERR_LIB_RSA, RSA_R_PAIRWISE_TEST_FAILURE); +err: + BN_CTX_end(ctx); + return ret; +} diff --git a/crypto/openssl/crypto/rsa/rsa_ssl.c b/crypto/openssl/crypto/rsa/rsa_ssl.c deleted file mode 100644 index e1c755ae460b..000000000000 --- a/crypto/openssl/crypto/rsa/rsa_ssl.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" -#include -#include -#include -#include "internal/constant_time.h" - -int RSA_padding_add_SSLv23(unsigned char *to, int tlen, - const unsigned char *from, int flen) -{ - int i, j; - unsigned char *p; - - if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { - RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return 0; - } - - p = (unsigned char *)to; - - *(p++) = 0; - *(p++) = 2; /* Public Key BT (Block Type) */ - - /* pad out with non-zero random data */ - j = tlen - 3 - 8 - flen; - - if (RAND_bytes(p, j) <= 0) - return 0; - for (i = 0; i < j; i++) { - if (*p == '\0') - do { - if (RAND_bytes(p, 1) <= 0) - return 0; - } while (*p == '\0'); - p++; - } - - memset(p, 3, 8); - p += 8; - *(p++) = '\0'; - - memcpy(p, from, (unsigned int)flen); - return 1; -} - -/* - * Copy of RSA_padding_check_PKCS1_type_2 with a twist that rejects padding - * if nul delimiter is preceded by 8 consecutive 0x03 bytes. It also - * preserves error code reporting for backward compatibility. - */ -int RSA_padding_check_SSLv23(unsigned char *to, int tlen, - const unsigned char *from, int flen, int num) -{ - int i; - /* |em| is the encoded message, zero-padded to exactly |num| bytes */ - unsigned char *em = NULL; - unsigned int good, found_zero_byte, mask, threes_in_row; - int zero_index = 0, msg_index, mlen = -1, err; - - if (tlen <= 0 || flen <= 0) - return -1; - - if (flen > num || num < RSA_PKCS1_PADDING_SIZE) { - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL); - return -1; - } - - em = OPENSSL_malloc(num); - if (em == NULL) { - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, ERR_R_MALLOC_FAILURE); - return -1; - } - /* - * Caller is encouraged to pass zero-padded message created with - * BN_bn2binpad. Trouble is that since we can't read out of |from|'s - * bounds, it's impossible to have an invariant memory access pattern - * in case |from| was not zero-padded in advance. - */ - for (from += flen, em += num, i = 0; i < num; i++) { - mask = ~constant_time_is_zero(flen); - flen -= 1 & mask; - from -= 1 & mask; - *--em = *from & mask; - } - - good = constant_time_is_zero(em[0]); - good &= constant_time_eq(em[1], 2); - err = constant_time_select_int(good, 0, RSA_R_BLOCK_TYPE_IS_NOT_02); - mask = ~good; - - /* scan over padding data */ - found_zero_byte = 0; - threes_in_row = 0; - for (i = 2; i < num; i++) { - unsigned int equals0 = constant_time_is_zero(em[i]); - - zero_index = constant_time_select_int(~found_zero_byte & equals0, - i, zero_index); - found_zero_byte |= equals0; - - threes_in_row += 1 & ~found_zero_byte; - threes_in_row &= found_zero_byte | constant_time_eq(em[i], 3); - } - - /* - * PS must be at least 8 bytes long, and it starts two bytes into |em|. - * If we never found a 0-byte, then |zero_index| is 0 and the check - * also fails. - */ - good &= constant_time_ge(zero_index, 2 + 8); - err = constant_time_select_int(mask | good, err, - RSA_R_NULL_BEFORE_BLOCK_MISSING); - mask = ~good; - - /* - * Reject if nul delimiter is preceded by 8 consecutive 0x03 bytes. Note - * that RFC5246 incorrectly states this the other way around, i.e. reject - * if it is not preceded by 8 consecutive 0x03 bytes. However this is - * corrected in subsequent errata for that RFC. - */ - good &= constant_time_lt(threes_in_row, 8); - err = constant_time_select_int(mask | good, err, - RSA_R_SSLV3_ROLLBACK_ATTACK); - mask = ~good; - - /* - * Skip the zero byte. This is incorrect if we never found a zero-byte - * but in this case we also do not copy the message out. - */ - msg_index = zero_index + 1; - mlen = num - msg_index; - - /* - * For good measure, do this check in constant time as well. - */ - good &= constant_time_ge(tlen, mlen); - err = constant_time_select_int(mask | good, err, RSA_R_DATA_TOO_LARGE); - - /* - * Move the result in-place by |num|-RSA_PKCS1_PADDING_SIZE-|mlen| bytes to the left. - * Then if |good| move |mlen| bytes from |em|+RSA_PKCS1_PADDING_SIZE to |to|. - * Otherwise leave |to| unchanged. - * Copy the memory back in a way that does not reveal the size of - * the data being copied via a timing side channel. This requires copying - * parts of the buffer multiple times based on the bits set in the real - * length. Clear bits do a non-copy with identical access pattern. - * The loop below has overall complexity of O(N*log(N)). - */ - tlen = constant_time_select_int(constant_time_lt(num - RSA_PKCS1_PADDING_SIZE, tlen), - num - RSA_PKCS1_PADDING_SIZE, tlen); - for (msg_index = 1; msg_index < num - RSA_PKCS1_PADDING_SIZE; msg_index <<= 1) { - mask = ~constant_time_eq(msg_index & (num - RSA_PKCS1_PADDING_SIZE - mlen), 0); - for (i = RSA_PKCS1_PADDING_SIZE; i < num - msg_index; i++) - em[i] = constant_time_select_8(mask, em[i + msg_index], em[i]); - } - for (i = 0; i < tlen; i++) { - mask = good & constant_time_lt(i, mlen); - to[i] = constant_time_select_8(mask, em[i + RSA_PKCS1_PADDING_SIZE], to[i]); - } - - OPENSSL_clear_free(em, num); - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, err); - err_clear_last_constant_time(1 & good); - - return constant_time_select_int(good, mlen, -1); -} diff --git a/crypto/openssl/crypto/rsa/rsa_x931.c b/crypto/openssl/crypto/rsa/rsa_x931.c index 7b0486c0f263..9d331ab9a7f3 100644 --- a/crypto/openssl/crypto/rsa/rsa_x931.c +++ b/crypto/openssl/crypto/rsa/rsa_x931.c @@ -1,12 +1,18 @@ /* - * Copyright 2005-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include @@ -27,7 +33,7 @@ int RSA_padding_add_X931(unsigned char *to, int tlen, j = tlen - flen - 2; if (j < 0) { - RSAerr(RSA_F_RSA_PADDING_ADD_X931, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return -1; } @@ -58,7 +64,7 @@ int RSA_padding_check_X931(unsigned char *to, int tlen, p = from; if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B))) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_HEADER); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_HEADER); return -1; } @@ -69,7 +75,7 @@ int RSA_padding_check_X931(unsigned char *to, int tlen, if (c == 0xBA) break; if (c != 0xBB) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING); return -1; } } @@ -77,7 +83,7 @@ int RSA_padding_check_X931(unsigned char *to, int tlen, j -= i; if (i == 0) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING); return -1; } @@ -86,7 +92,7 @@ int RSA_padding_check_X931(unsigned char *to, int tlen, } if (p[j] != 0xCC) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER); + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_TRAILER); return -1; } diff --git a/crypto/openssl/crypto/rsa/rsa_x931g.c b/crypto/openssl/crypto/rsa/rsa_x931g.c index 322cd14a840d..5a309a98c347 100644 --- a/crypto/openssl/crypto/rsa/rsa_x931g.c +++ b/crypto/openssl/crypto/rsa/rsa_x931g.c @@ -1,12 +1,18 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include @@ -131,6 +137,7 @@ int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, if (rsa->iqmp == NULL) goto err; + rsa->dirty_cnt++; ret = 1; err: BN_CTX_end(ctx); @@ -184,6 +191,7 @@ int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) goto error; + rsa->dirty_cnt++; ok = 1; error: diff --git a/crypto/openssl/crypto/s390x_arch.h b/crypto/openssl/crypto/s390x_arch.h index 64e7ebb5662e..a7bde67d90f5 100644 --- a/crypto/openssl/crypto/s390x_arch.h +++ b/crypto/openssl/crypto/s390x_arch.h @@ -1,7 +1,7 @@ /* * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -26,6 +26,29 @@ void s390x_kmf(const unsigned char *in, size_t len, unsigned char *out, unsigned int fc, void *param); void s390x_kma(const unsigned char *aad, size_t alen, const unsigned char *in, size_t len, unsigned char *out, unsigned int fc, void *param); +int s390x_pcc(unsigned int fc, void *param); +int s390x_kdsa(unsigned int fc, void *param, const unsigned char *in, + size_t len); + +void s390x_flip_endian32(unsigned char dst[32], const unsigned char src[32]); +void s390x_flip_endian64(unsigned char dst[64], const unsigned char src[64]); + +int s390x_x25519_mul(unsigned char u_dst[32], + const unsigned char u_src[32], + const unsigned char d_src[32]); +int s390x_x448_mul(unsigned char u_dst[56], + const unsigned char u_src[56], + const unsigned char d_src[56]); +int s390x_ed25519_mul(unsigned char x_dst[32], + unsigned char y_dst[32], + const unsigned char x_src[32], + const unsigned char y_src[32], + const unsigned char d_src[32]); +int s390x_ed448_mul(unsigned char x_dst[57], + unsigned char y_dst[57], + const unsigned char x_src[57], + const unsigned char y_src[57], + const unsigned char d_src[57]); /* * The field elements of OPENSSL_s390xcap_P are the 64-bit words returned by @@ -45,6 +68,8 @@ struct OPENSSL_s390xcap_st { unsigned long long kmf[2]; unsigned long long prno[2]; unsigned long long kma[2]; + unsigned long long pcc[2]; + unsigned long long kdsa[2]; }; #if defined(__GNUC__) && defined(__linux) @@ -52,55 +77,97 @@ __attribute__ ((visibility("hidden"))) #endif extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; +/* Max number of 64-bit words currently returned by STFLE */ +# define S390X_STFLE_MAX 3 + /* convert facility bit number or function code to bit mask */ -# define S390X_CAPBIT(i) (1ULL << (63 - (i) % 64)) +# define S390X_CAPBIT(i) (1ULL << (63 - (i) % 64)) # endif /* OPENSSL_s390xcap_P offsets [bytes] */ -# define S390X_STFLE 0x00 -# define S390X_KIMD 0x20 -# define S390X_KLMD 0x30 -# define S390X_KM 0x40 -# define S390X_KMC 0x50 -# define S390X_KMAC 0x60 -# define S390X_KMCTR 0x70 -# define S390X_KMO 0x80 -# define S390X_KMF 0x90 -# define S390X_PRNO 0xa0 -# define S390X_KMA 0xb0 +# define S390X_STFLE 0x00 +# define S390X_KIMD 0x20 +# define S390X_KLMD 0x30 +# define S390X_KM 0x40 +# define S390X_KMC 0x50 +# define S390X_KMAC 0x60 +# define S390X_KMCTR 0x70 +# define S390X_KMO 0x80 +# define S390X_KMF 0x90 +# define S390X_PRNO 0xa0 +# define S390X_KMA 0xb0 +# define S390X_PCC 0xc0 +# define S390X_KDSA 0xd0 /* Facility Bit Numbers */ -# define S390X_VX 129 -# define S390X_VXD 134 -# define S390X_VXE 135 +# define S390X_MSA 17 /* message-security-assist */ +# define S390X_STCKF 25 /* store-clock-fast */ +# define S390X_MSA5 57 /* message-security-assist-ext. 5 */ +# define S390X_MSA3 76 /* message-security-assist-ext. 3 */ +# define S390X_MSA4 77 /* message-security-assist-ext. 4 */ +# define S390X_VX 129 /* vector */ +# define S390X_VXD 134 /* vector packed decimal */ +# define S390X_VXE 135 /* vector enhancements 1 */ +# define S390X_MSA8 146 /* message-security-assist-ext. 8 */ +# define S390X_MSA9 155 /* message-security-assist-ext. 9 */ /* Function Codes */ /* all instructions */ -# define S390X_QUERY 0 +# define S390X_QUERY 0 /* kimd/klmd */ -# define S390X_SHA3_224 32 -# define S390X_SHA3_256 33 -# define S390X_SHA3_384 34 -# define S390X_SHA3_512 35 -# define S390X_SHAKE_128 36 -# define S390X_SHAKE_256 37 -# define S390X_GHASH 65 +# define S390X_SHA_1 1 +# define S390X_SHA_256 2 +# define S390X_SHA_512 3 +# define S390X_SHA3_224 32 +# define S390X_SHA3_256 33 +# define S390X_SHA3_384 34 +# define S390X_SHA3_512 35 +# define S390X_SHAKE_128 36 +# define S390X_SHAKE_256 37 +# define S390X_GHASH 65 /* km/kmc/kmac/kmctr/kmo/kmf/kma */ -# define S390X_AES_128 18 -# define S390X_AES_192 19 -# define S390X_AES_256 20 +# define S390X_AES_128 18 +# define S390X_AES_192 19 +# define S390X_AES_256 20 + +/* km */ +# define S390X_XTS_AES_128 50 +# define S390X_XTS_AES_256 52 /* prno */ -# define S390X_TRNG 114 +# define S390X_SHA_512_DRNG 3 +# define S390X_TRNG 114 + +/* pcc */ +# define S390X_SCALAR_MULTIPLY_P256 64 +# define S390X_SCALAR_MULTIPLY_P384 65 +# define S390X_SCALAR_MULTIPLY_P521 66 +# define S390X_SCALAR_MULTIPLY_ED25519 72 +# define S390X_SCALAR_MULTIPLY_ED448 73 +# define S390X_SCALAR_MULTIPLY_X25519 80 +# define S390X_SCALAR_MULTIPLY_X448 81 + +/* kdsa */ +# define S390X_ECDSA_VERIFY_P256 1 +# define S390X_ECDSA_VERIFY_P384 2 +# define S390X_ECDSA_VERIFY_P521 3 +# define S390X_ECDSA_SIGN_P256 9 +# define S390X_ECDSA_SIGN_P384 10 +# define S390X_ECDSA_SIGN_P521 11 +# define S390X_EDDSA_VERIFY_ED25519 32 +# define S390X_EDDSA_VERIFY_ED448 36 +# define S390X_EDDSA_SIGN_ED25519 40 +# define S390X_EDDSA_SIGN_ED448 44 /* Register 0 Flags */ -# define S390X_DECRYPT 0x80 -# define S390X_KMA_LPC 0x100 -# define S390X_KMA_LAAD 0x200 -# define S390X_KMA_HS 0x400 +# define S390X_DECRYPT 0x80 +# define S390X_KMA_LPC 0x100 +# define S390X_KMA_LAAD 0x200 +# define S390X_KMA_HS 0x400 +# define S390X_KDSA_D 0x80 #endif diff --git a/crypto/openssl/crypto/s390xcap.c b/crypto/openssl/crypto/s390xcap.c index 1097c703b4fb..ea38ff8f0856 100644 --- a/crypto/openssl/crypto/s390xcap.c +++ b/crypto/openssl/crypto/s390xcap.c @@ -1,7 +1,7 @@ /* * Copyright 2010-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,16 +13,64 @@ #include #include #include "internal/cryptlib.h" +#include "crypto/ctype.h" #include "s390x_arch.h" +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +# if __GLIBC_PREREQ(2, 16) +# include +# if defined(HWCAP_S390_STFLE) && defined(HWCAP_S390_VX) +# define OSSL_IMPLEMENT_GETAUXVAL +# endif +# endif +#endif + +#define LEN 128 +#define STR_(S) #S +#define STR(S) STR_(S) + +#define TOK_FUNC(NAME) \ + (sscanf(tok_begin, \ + " " STR(NAME) " : %" STR(LEN) "[^:] : " \ + "%" STR(LEN) "s %" STR(LEN) "s ", \ + tok[0], tok[1], tok[2]) == 2) { \ + \ + off = (tok[0][0] == '~') ? 1 : 0; \ + if (sscanf(tok[0] + off, "%llx", &cap->NAME[0]) != 1) \ + goto ret; \ + if (off) \ + cap->NAME[0] = ~cap->NAME[0]; \ + \ + off = (tok[1][0] == '~') ? 1 : 0; \ + if (sscanf(tok[1] + off, "%llx", &cap->NAME[1]) != 1) \ + goto ret; \ + if (off) \ + cap->NAME[1] = ~cap->NAME[1]; \ + } + +#define TOK_CPU(NAME) \ + (sscanf(tok_begin, \ + " %" STR(LEN) "s %" STR(LEN) "s ", \ + tok[0], tok[1]) == 1 \ + && !strcmp(tok[0], #NAME)) { \ + memcpy(cap, &NAME, sizeof(*cap)); \ + } + +#ifndef OSSL_IMPLEMENT_GETAUXVAL static sigjmp_buf ill_jmp; static void ill_handler(int sig) { siglongjmp(ill_jmp, sig); } -void OPENSSL_s390x_facilities(void); void OPENSSL_vx_probe(void); +#endif + +static const char *env; +static int parse_env(struct OPENSSL_s390xcap_st *cap); + +void OPENSSL_s390x_facilities(void); +void OPENSSL_s390x_functions(void); struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; @@ -31,8 +79,7 @@ __attribute__ ((visibility("hidden"))) #endif void OPENSSL_cpuid_setup(void) { - sigset_t oset; - struct sigaction ill_act, oact_ill, oact_fpe; + struct OPENSSL_s390xcap_st cap; if (OPENSSL_s390xcap_P.stfle[0]) return; @@ -40,31 +87,659 @@ void OPENSSL_cpuid_setup(void) /* set a bit that will not be tested later */ OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0); - memset(&ill_act, 0, sizeof(ill_act)); - ill_act.sa_handler = ill_handler; - sigfillset(&ill_act.sa_mask); - sigdelset(&ill_act.sa_mask, SIGILL); - sigdelset(&ill_act.sa_mask, SIGFPE); - sigdelset(&ill_act.sa_mask, SIGTRAP); - sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); - sigaction(SIGILL, &ill_act, &oact_ill); - sigaction(SIGFPE, &ill_act, &oact_fpe); - - /* protection against missing store-facility-list-extended */ - if (sigsetjmp(ill_jmp, 1) == 0) - OPENSSL_s390x_facilities(); - - /* protection against disabled vector facility */ - if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX)) - && (sigsetjmp(ill_jmp, 1) == 0)) { - OPENSSL_vx_probe(); - } else { - OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) - | S390X_CAPBIT(S390X_VXD) - | S390X_CAPBIT(S390X_VXE)); +#if defined(OSSL_IMPLEMENT_GETAUXVAL) + { + const unsigned long hwcap = getauxval(AT_HWCAP); + + /* protection against missing store-facility-list-extended */ + if (hwcap & HWCAP_S390_STFLE) + OPENSSL_s390x_facilities(); + + /* protection against disabled vector facility */ + if (!(hwcap & HWCAP_S390_VX)) { + OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) + | S390X_CAPBIT(S390X_VXD) + | S390X_CAPBIT(S390X_VXE)); + } + } +#else + { + sigset_t oset; + struct sigaction ill_act, oact_ill, oact_fpe; + + memset(&ill_act, 0, sizeof(ill_act)); + ill_act.sa_handler = ill_handler; + sigfillset(&ill_act.sa_mask); + sigdelset(&ill_act.sa_mask, SIGILL); + sigdelset(&ill_act.sa_mask, SIGFPE); + sigdelset(&ill_act.sa_mask, SIGTRAP); + + sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); + sigaction(SIGILL, &ill_act, &oact_ill); + sigaction(SIGFPE, &ill_act, &oact_fpe); + + /* protection against missing store-facility-list-extended */ + if (sigsetjmp(ill_jmp, 1) == 0) + OPENSSL_s390x_facilities(); + + /* protection against disabled vector facility */ + if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX)) + && (sigsetjmp(ill_jmp, 1) == 0)) { + OPENSSL_vx_probe(); + } else { + OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) + | S390X_CAPBIT(S390X_VXD) + | S390X_CAPBIT(S390X_VXE)); + } + + sigaction(SIGFPE, &oact_fpe, NULL); + sigaction(SIGILL, &oact_ill, NULL); + sigprocmask(SIG_SETMASK, &oset, NULL); + } +#endif + + env = getenv("OPENSSL_s390xcap"); + if (env != NULL) { + if (!parse_env(&cap)) + env = NULL; + } + + if (env != NULL) { + OPENSSL_s390xcap_P.stfle[0] &= cap.stfle[0]; + OPENSSL_s390xcap_P.stfle[1] &= cap.stfle[1]; + OPENSSL_s390xcap_P.stfle[2] &= cap.stfle[2]; + } + + OPENSSL_s390x_functions(); /* check OPENSSL_s390xcap_P.stfle */ + + if (env != NULL) { + OPENSSL_s390xcap_P.kimd[0] &= cap.kimd[0]; + OPENSSL_s390xcap_P.kimd[1] &= cap.kimd[1]; + OPENSSL_s390xcap_P.klmd[0] &= cap.klmd[0]; + OPENSSL_s390xcap_P.klmd[1] &= cap.klmd[1]; + OPENSSL_s390xcap_P.km[0] &= cap.km[0]; + OPENSSL_s390xcap_P.km[1] &= cap.km[1]; + OPENSSL_s390xcap_P.kmc[0] &= cap.kmc[0]; + OPENSSL_s390xcap_P.kmc[1] &= cap.kmc[1]; + OPENSSL_s390xcap_P.kmac[0] &= cap.kmac[0]; + OPENSSL_s390xcap_P.kmac[1] &= cap.kmac[1]; + OPENSSL_s390xcap_P.kmctr[0] &= cap.kmctr[0]; + OPENSSL_s390xcap_P.kmctr[1] &= cap.kmctr[1]; + OPENSSL_s390xcap_P.kmo[0] &= cap.kmo[0]; + OPENSSL_s390xcap_P.kmo[1] &= cap.kmo[1]; + OPENSSL_s390xcap_P.kmf[0] &= cap.kmf[0]; + OPENSSL_s390xcap_P.kmf[1] &= cap.kmf[1]; + OPENSSL_s390xcap_P.prno[0] &= cap.prno[0]; + OPENSSL_s390xcap_P.prno[1] &= cap.prno[1]; + OPENSSL_s390xcap_P.kma[0] &= cap.kma[0]; + OPENSSL_s390xcap_P.kma[1] &= cap.kma[1]; + OPENSSL_s390xcap_P.pcc[0] &= cap.pcc[0]; + OPENSSL_s390xcap_P.pcc[1] &= cap.pcc[1]; + OPENSSL_s390xcap_P.kdsa[0] &= cap.kdsa[0]; + OPENSSL_s390xcap_P.kdsa[1] &= cap.kdsa[1]; + } +} + +static int parse_env(struct OPENSSL_s390xcap_st *cap) +{ + /*- + * CPU model data + * (only the STFLE- and QUERY-bits relevant to libcrypto are set) + */ + + /*- + * z900 (2000) - z/Architecture POP SA22-7832-00 + * Facility detection would fail on real hw (no STFLE). + */ + static const struct OPENSSL_s390xcap_st z900 = { + /*.stfle = */{0ULL, 0ULL, 0ULL, 0ULL}, + /*.kimd = */{0ULL, 0ULL}, + /*.klmd = */{0ULL, 0ULL}, + /*.km = */{0ULL, 0ULL}, + /*.kmc = */{0ULL, 0ULL}, + /*.kmac = */{0ULL, 0ULL}, + /*.kmctr = */{0ULL, 0ULL}, + /*.kmo = */{0ULL, 0ULL}, + /*.kmf = */{0ULL, 0ULL}, + /*.prno = */{0ULL, 0ULL}, + /*.kma = */{0ULL, 0ULL}, + /*.pcc = */{0ULL, 0ULL}, + /*.kdsa = */{0ULL, 0ULL}, + }; + + /*- + * z990 (2003) - z/Architecture POP SA22-7832-02 + * Implements MSA. Facility detection would fail on real hw (no STFLE). + */ + static const struct OPENSSL_s390xcap_st z990 = { + /*.stfle = */{S390X_CAPBIT(S390X_MSA), + 0ULL, 0ULL, 0ULL}, + /*.kimd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1), + 0ULL}, + /*.klmd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1), + 0ULL}, + /*.km = */{S390X_CAPBIT(S390X_QUERY), + 0ULL}, + /*.kmc = */{S390X_CAPBIT(S390X_QUERY), + 0ULL}, + /*.kmac = */{S390X_CAPBIT(S390X_QUERY), + 0ULL}, + /*.kmctr = */{0ULL, 0ULL}, + /*.kmo = */{0ULL, 0ULL}, + /*.kmf = */{0ULL, 0ULL}, + /*.prno = */{0ULL, 0ULL}, + /*.kma = */{0ULL, 0ULL}, + /*.pcc = */{0ULL, 0ULL}, + /*.kdsa = */{0ULL, 0ULL}, + }; + + /*- + * z9 (2005) - z/Architecture POP SA22-7832-04 + * Implements MSA and MSA1. + */ + static const struct OPENSSL_s390xcap_st z9 = { + /*.stfle = */{S390X_CAPBIT(S390X_MSA) + | S390X_CAPBIT(S390X_STCKF), + 0ULL, 0ULL, 0ULL}, + /*.kimd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256), + 0ULL}, + /*.klmd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256), + 0ULL}, + /*.km = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128), + 0ULL}, + /*.kmc = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128), + 0ULL}, + /*.kmac = */{S390X_CAPBIT(S390X_QUERY), + 0ULL}, + /*.kmctr = */{0ULL, 0ULL}, + /*.kmo = */{0ULL, 0ULL}, + /*.kmf = */{0ULL, 0ULL}, + /*.prno = */{0ULL, 0ULL}, + /*.kma = */{0ULL, 0ULL}, + /*.pcc = */{0ULL, 0ULL}, + /*.kdsa = */{0ULL, 0ULL}, + }; + + /*- + * z10 (2008) - z/Architecture POP SA22-7832-06 + * Implements MSA and MSA1-2. + */ + static const struct OPENSSL_s390xcap_st z10 = { + /*.stfle = */{S390X_CAPBIT(S390X_MSA) + | S390X_CAPBIT(S390X_STCKF), + 0ULL, 0ULL, 0ULL}, + /*.kimd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512), + 0ULL}, + /*.klmd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512), + 0ULL}, + /*.km = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmc = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmac = */{S390X_CAPBIT(S390X_QUERY), + 0ULL}, + /*.kmctr = */{0ULL, 0ULL}, + /*.kmo = */{0ULL, 0ULL}, + /*.kmf = */{0ULL, 0ULL}, + /*.prno = */{0ULL, 0ULL}, + /*.kma = */{0ULL, 0ULL}, + /*.pcc = */{0ULL, 0ULL}, + /*.kdsa = */{0ULL, 0ULL}, + }; + + /*- + * z196 (2010) - z/Architecture POP SA22-7832-08 + * Implements MSA and MSA1-4. + */ + static const struct OPENSSL_s390xcap_st z196 = { + /*.stfle = */{S390X_CAPBIT(S390X_MSA) + | S390X_CAPBIT(S390X_STCKF), + S390X_CAPBIT(S390X_MSA3) + | S390X_CAPBIT(S390X_MSA4), + 0ULL, 0ULL}, + /*.kimd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512), + S390X_CAPBIT(S390X_GHASH)}, + /*.klmd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512), + 0ULL}, + /*.km = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256) + | S390X_CAPBIT(S390X_XTS_AES_128) + | S390X_CAPBIT(S390X_XTS_AES_256), + 0ULL}, + /*.kmc = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmac = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmctr = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmo = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmf = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.prno = */{0ULL, 0ULL}, + /*.kma = */{0ULL, 0ULL}, + /*.pcc = */{S390X_CAPBIT(S390X_QUERY), + 0ULL}, + /*.kdsa = */{0ULL, 0ULL}, + }; + + /*- + * zEC12 (2012) - z/Architecture POP SA22-7832-09 + * Implements MSA and MSA1-4. + */ + static const struct OPENSSL_s390xcap_st zEC12 = { + /*.stfle = */{S390X_CAPBIT(S390X_MSA) + | S390X_CAPBIT(S390X_STCKF), + S390X_CAPBIT(S390X_MSA3) + | S390X_CAPBIT(S390X_MSA4), + 0ULL, 0ULL}, + /*.kimd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512), + S390X_CAPBIT(S390X_GHASH)}, + /*.klmd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512), + 0ULL}, + /*.km = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256) + | S390X_CAPBIT(S390X_XTS_AES_128) + | S390X_CAPBIT(S390X_XTS_AES_256), + 0ULL}, + /*.kmc = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmac = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmctr = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmo = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmf = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.prno = */{0ULL, 0ULL}, + /*.kma = */{0ULL, 0ULL}, + /*.pcc = */{S390X_CAPBIT(S390X_QUERY), + 0ULL}, + /*.kdsa = */{0ULL, 0ULL}, + }; + + /*- + * z13 (2015) - z/Architecture POP SA22-7832-10 + * Implements MSA and MSA1-5. + */ + static const struct OPENSSL_s390xcap_st z13 = { + /*.stfle = */{S390X_CAPBIT(S390X_MSA) + | S390X_CAPBIT(S390X_STCKF) + | S390X_CAPBIT(S390X_MSA5), + S390X_CAPBIT(S390X_MSA3) + | S390X_CAPBIT(S390X_MSA4), + S390X_CAPBIT(S390X_VX), + 0ULL}, + /*.kimd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512), + S390X_CAPBIT(S390X_GHASH)}, + /*.klmd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512), + 0ULL}, + /*.km = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256) + | S390X_CAPBIT(S390X_XTS_AES_128) + | S390X_CAPBIT(S390X_XTS_AES_256), + 0ULL}, + /*.kmc = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmac = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmctr = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmo = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmf = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.prno = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_512_DRNG), + 0ULL}, + /*.kma = */{0ULL, 0ULL}, + /*.pcc = */{S390X_CAPBIT(S390X_QUERY), + 0ULL}, + /*.kdsa = */{0ULL, 0ULL}, + }; + + /*- + * z14 (2017) - z/Architecture POP SA22-7832-11 + * Implements MSA and MSA1-8. + */ + static const struct OPENSSL_s390xcap_st z14 = { + /*.stfle = */{S390X_CAPBIT(S390X_MSA) + | S390X_CAPBIT(S390X_STCKF) + | S390X_CAPBIT(S390X_MSA5), + S390X_CAPBIT(S390X_MSA3) + | S390X_CAPBIT(S390X_MSA4), + S390X_CAPBIT(S390X_VX) + | S390X_CAPBIT(S390X_VXD) + | S390X_CAPBIT(S390X_VXE) + | S390X_CAPBIT(S390X_MSA8), + 0ULL}, + /*.kimd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512) + | S390X_CAPBIT(S390X_SHA3_224) + | S390X_CAPBIT(S390X_SHA3_256) + | S390X_CAPBIT(S390X_SHA3_384) + | S390X_CAPBIT(S390X_SHA3_512) + | S390X_CAPBIT(S390X_SHAKE_128) + | S390X_CAPBIT(S390X_SHAKE_256), + S390X_CAPBIT(S390X_GHASH)}, + /*.klmd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512) + | S390X_CAPBIT(S390X_SHA3_224) + | S390X_CAPBIT(S390X_SHA3_256) + | S390X_CAPBIT(S390X_SHA3_384) + | S390X_CAPBIT(S390X_SHA3_512) + | S390X_CAPBIT(S390X_SHAKE_128) + | S390X_CAPBIT(S390X_SHAKE_256), + 0ULL}, + /*.km = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256) + | S390X_CAPBIT(S390X_XTS_AES_128) + | S390X_CAPBIT(S390X_XTS_AES_256), + 0ULL}, + /*.kmc = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmac = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmctr = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmo = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmf = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.prno = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_512_DRNG), + S390X_CAPBIT(S390X_TRNG)}, + /*.kma = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.pcc = */{S390X_CAPBIT(S390X_QUERY), + 0ULL}, + /*.kdsa = */{0ULL, 0ULL}, + }; + + /*- + * z15 (2019) - z/Architecture POP SA22-7832-12 + * Implements MSA and MSA1-9. + */ + static const struct OPENSSL_s390xcap_st z15 = { + /*.stfle = */{S390X_CAPBIT(S390X_MSA) + | S390X_CAPBIT(S390X_STCKF) + | S390X_CAPBIT(S390X_MSA5), + S390X_CAPBIT(S390X_MSA3) + | S390X_CAPBIT(S390X_MSA4), + S390X_CAPBIT(S390X_VX) + | S390X_CAPBIT(S390X_VXD) + | S390X_CAPBIT(S390X_VXE) + | S390X_CAPBIT(S390X_MSA8) + | S390X_CAPBIT(S390X_MSA9), + 0ULL}, + /*.kimd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512) + | S390X_CAPBIT(S390X_SHA3_224) + | S390X_CAPBIT(S390X_SHA3_256) + | S390X_CAPBIT(S390X_SHA3_384) + | S390X_CAPBIT(S390X_SHA3_512) + | S390X_CAPBIT(S390X_SHAKE_128) + | S390X_CAPBIT(S390X_SHAKE_256), + S390X_CAPBIT(S390X_GHASH)}, + /*.klmd = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_1) + | S390X_CAPBIT(S390X_SHA_256) + | S390X_CAPBIT(S390X_SHA_512) + | S390X_CAPBIT(S390X_SHA3_224) + | S390X_CAPBIT(S390X_SHA3_256) + | S390X_CAPBIT(S390X_SHA3_384) + | S390X_CAPBIT(S390X_SHA3_512) + | S390X_CAPBIT(S390X_SHAKE_128) + | S390X_CAPBIT(S390X_SHAKE_256), + 0ULL}, + /*.km = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256) + | S390X_CAPBIT(S390X_XTS_AES_128) + | S390X_CAPBIT(S390X_XTS_AES_256), + 0ULL}, + /*.kmc = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmac = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmctr = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmo = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.kmf = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.prno = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_SHA_512_DRNG), + S390X_CAPBIT(S390X_TRNG)}, + /*.kma = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_AES_128) + | S390X_CAPBIT(S390X_AES_192) + | S390X_CAPBIT(S390X_AES_256), + 0ULL}, + /*.pcc = */{S390X_CAPBIT(S390X_QUERY), + S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P256) + | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P384) + | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P521) + | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519) + | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448) + | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519) + | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)}, + /*.kdsa = */{S390X_CAPBIT(S390X_QUERY) + | S390X_CAPBIT(S390X_ECDSA_VERIFY_P256) + | S390X_CAPBIT(S390X_ECDSA_VERIFY_P384) + | S390X_CAPBIT(S390X_ECDSA_VERIFY_P521) + | S390X_CAPBIT(S390X_ECDSA_SIGN_P256) + | S390X_CAPBIT(S390X_ECDSA_SIGN_P384) + | S390X_CAPBIT(S390X_ECDSA_SIGN_P521) + | S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519) + | S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448) + | S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519) + | S390X_CAPBIT(S390X_EDDSA_SIGN_ED448), + 0ULL}, + }; + + char *tok_begin, *tok_end, *buff, tok[S390X_STFLE_MAX][LEN + 1]; + int rc, off, i, n; + + buff = malloc(strlen(env) + 1); + if (buff == NULL) + return 0; + + rc = 0; + memset(cap, ~0, sizeof(*cap)); + strcpy(buff, env); + + tok_begin = buff + strspn(buff, ";"); + strtok(tok_begin, ";"); + tok_end = strtok(NULL, ";"); + + while (tok_begin != NULL) { + /* stfle token */ + if ((n = sscanf(tok_begin, + " stfle : %" STR(LEN) "[^:] : " + "%" STR(LEN) "[^:] : %" STR(LEN) "s ", + tok[0], tok[1], tok[2]))) { + for (i = 0; i < n; i++) { + off = (tok[i][0] == '~') ? 1 : 0; + if (sscanf(tok[i] + off, "%llx", &cap->stfle[i]) != 1) + goto ret; + if (off) + cap->stfle[i] = ~cap->stfle[i]; + } + } + + /* query function tokens */ + else if TOK_FUNC(kimd) + else if TOK_FUNC(klmd) + else if TOK_FUNC(km) + else if TOK_FUNC(kmc) + else if TOK_FUNC(kmac) + else if TOK_FUNC(kmctr) + else if TOK_FUNC(kmo) + else if TOK_FUNC(kmf) + else if TOK_FUNC(prno) + else if TOK_FUNC(kma) + else if TOK_FUNC(pcc) + else if TOK_FUNC(kdsa) + + /* CPU model tokens */ + else if TOK_CPU(z900) + else if TOK_CPU(z990) + else if TOK_CPU(z9) + else if TOK_CPU(z10) + else if TOK_CPU(z196) + else if TOK_CPU(zEC12) + else if TOK_CPU(z13) + else if TOK_CPU(z14) + else if TOK_CPU(z15) + + /* whitespace(ignored) or invalid tokens */ + else { + while (*tok_begin != '\0') { + if (!ossl_isspace(*tok_begin)) + goto ret; + tok_begin++; + } + } + + tok_begin = tok_end; + tok_end = strtok(NULL, ";"); } - sigaction(SIGFPE, &oact_fpe, NULL); - sigaction(SIGILL, &oact_ill, NULL); - sigprocmask(SIG_SETMASK, &oset, NULL); + rc = 1; +ret: + free(buff); + return rc; } diff --git a/crypto/openssl/crypto/s390xcpuid.pl b/crypto/openssl/crypto/s390xcpuid.pl index 5cbb962530c5..560a2f09e97e 100755 --- a/crypto/openssl/crypto/s390xcpuid.pl +++ b/crypto/openssl/crypto/s390xcpuid.pl @@ -1,12 +1,15 @@ #! /usr/bin/env perl # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -16,8 +19,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $ra="%r14"; $sp="%r15"; @@ -38,7 +40,26 @@ OPENSSL_s390x_facilities: stg %r0,S390X_STFLE+8(%r4) # wipe capability vectors stg %r0,S390X_STFLE+16(%r4) stg %r0,S390X_STFLE+24(%r4) - stg %r0,S390X_KIMD(%r4) + + .long 0xb2b04000 # stfle 0(%r4) + brc 8,.Ldone + lghi %r0,1 + .long 0xb2b04000 # stfle 0(%r4) + brc 8,.Ldone + lghi %r0,2 + .long 0xb2b04000 # stfle 0(%r4) +.Ldone: + br $ra +.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities + +.globl OPENSSL_s390x_functions +.type OPENSSL_s390x_functions,\@function +.align 16 +OPENSSL_s390x_functions: + lghi %r0,0 + larl %r4,OPENSSL_s390xcap_P + + stg %r0,S390X_KIMD(%r4) # wipe capability vectors stg %r0,S390X_KIMD+8(%r4) stg %r0,S390X_KLMD(%r4) stg %r0,S390X_KLMD+8(%r4) @@ -58,16 +79,13 @@ OPENSSL_s390x_facilities: stg %r0,S390X_PRNO+8(%r4) stg %r0,S390X_KMA(%r4) stg %r0,S390X_KMA+8(%r4) + stg %r0,S390X_PCC(%r4) + stg %r0,S390X_PCC+8(%r4) + stg %r0,S390X_KDSA(%r4) + stg %r0,S390X_KDSA+8(%r4) - .long 0xb2b04000 # stfle 0(%r4) - brc 8,.Ldone - lghi %r0,1 - .long 0xb2b04000 # stfle 0(%r4) - brc 8,.Ldone - lghi %r0,2 - .long 0xb2b04000 # stfle 0(%r4) -.Ldone: lmg %r2,%r3,S390X_STFLE(%r4) + tmhl %r2,0x4000 # check for message-security-assist jz .Lret @@ -91,6 +109,13 @@ OPENSSL_s390x_facilities: la %r1,S390X_KMAC(%r4) .long 0xb91e0042 # kmac %r4,%r2 + tmhh %r3,0x0008 # check for message-security-assist-3 + jz .Lret + + lghi %r0,S390X_QUERY # query pcc capability vector + la %r1,S390X_PCC(%r4) + .long 0xb92c0000 # pcc + tmhh %r3,0x0004 # check for message-security-assist-4 jz .Lret @@ -114,6 +139,7 @@ OPENSSL_s390x_facilities: .long 0xb93c0042 # prno %r4,%r2 lg %r2,S390X_STFLE+16(%r4) + tmhl %r2,0x2000 # check for message-security-assist-8 jz .Lret @@ -121,9 +147,16 @@ OPENSSL_s390x_facilities: la %r1,S390X_KMA(%r4) .long 0xb9294022 # kma %r2,%r4,%r2 + tmhl %r2,0x0010 # check for message-security-assist-9 + jz .Lret + + lghi %r0,S390X_QUERY # query kdsa capability vector + la %r1,S390X_KDSA(%r4) + .long 0xb93a0002 # kdsa %r0,%r2 + .Lret: br $ra -.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities +.size OPENSSL_s390x_functions,.-OPENSSL_s390x_functions .globl OPENSSL_rdtsc .type OPENSSL_rdtsc,\@function @@ -411,6 +444,113 @@ s390x_kma: ___ } +################ +# int s390x_pcc(unsigned int fc, void *param) +{ +my ($fc,$param) = map("%r$_",(2..3)); +$code.=<<___; +.globl s390x_pcc +.type s390x_pcc,\@function +.align 16 +s390x_pcc: + lr %r0,$fc + l${g}r %r1,$param + lhi %r2,0 + + .long 0xb92c0000 # pcc + brc 1,.-4 # pay attention to "partial completion" + brc 7,.Lpcc_err # if CC==0 return 0, else return 1 +.Lpcc_out: + br $ra +.Lpcc_err: + lhi %r2,1 + j .Lpcc_out +.size s390x_pcc,.-s390x_pcc +___ +} + +################ +# int s390x_kdsa(unsigned int fc, void *param, +# const unsigned char *in, size_t len) +{ +my ($fc,$param,$in,$len) = map("%r$_",(2..5)); +$code.=<<___; +.globl s390x_kdsa +.type s390x_kdsa,\@function +.align 16 +s390x_kdsa: + lr %r0,$fc + l${g}r %r1,$param + lhi %r2,0 + + .long 0xb93a0004 # kdsa %r0,$in + brc 1,.-4 # pay attention to "partial completion" + brc 7,.Lkdsa_err # if CC==0 return 0, else return 1 +.Lkdsa_out: + br $ra +.Lkdsa_err: + lhi %r2,1 + j .Lkdsa_out +.size s390x_kdsa,.-s390x_kdsa +___ +} + +################ +# void s390x_flip_endian32(unsigned char dst[32], const unsigned char src[32]) +{ +my ($dst,$src) = map("%r$_",(2..3)); +$code.=<<___; +.globl s390x_flip_endian32 +.type s390x_flip_endian32,\@function +.align 16 +s390x_flip_endian32: + lrvg %r0,0($src) + lrvg %r1,8($src) + lrvg %r4,16($src) + lrvg %r5,24($src) + stg %r0,24($dst) + stg %r1,16($dst) + stg %r4,8($dst) + stg %r5,0($dst) + br $ra +.size s390x_flip_endian32,.-s390x_flip_endian32 +___ +} + +################ +# void s390x_flip_endian64(unsigned char dst[64], const unsigned char src[64]) +{ +my ($dst,$src) = map("%r$_",(2..3)); +$code.=<<___; +.globl s390x_flip_endian64 +.type s390x_flip_endian64,\@function +.align 16 +s390x_flip_endian64: + stmg %r6,%r9,6*$SIZE_T($sp) + + lrvg %r0,0($src) + lrvg %r1,8($src) + lrvg %r4,16($src) + lrvg %r5,24($src) + lrvg %r6,32($src) + lrvg %r7,40($src) + lrvg %r8,48($src) + lrvg %r9,56($src) + stg %r0,56($dst) + stg %r1,48($dst) + stg %r4,40($dst) + stg %r5,32($dst) + stg %r6,24($dst) + stg %r7,16($dst) + stg %r8,8($dst) + stg %r9,0($dst) + + lmg %r6,%r9,6*$SIZE_T($sp) + br $ra +.size s390x_flip_endian64,.-s390x_flip_endian64 +___ +} + $code.=<<___; .section .init brasl $ra,OPENSSL_cpuid_setup diff --git a/crypto/openssl/crypto/seed/build.info b/crypto/openssl/crypto/seed/build.info index abdcbcaa94e5..f513654ecb67 100644 --- a/crypto/openssl/crypto/seed/build.info +++ b/crypto/openssl/crypto/seed/build.info @@ -1,2 +1,10 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=seed.c seed_ecb.c seed_cbc.c seed_cfb.c seed_ofb.c +$ALL=seed.c seed_ecb.c seed_cbc.c seed_cfb.c seed_ofb.c + +SOURCE[../../libcrypto]=$ALL + +# When all deprecated symbols are removed, libcrypto doesn't export the +# seed functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=$ALL +ENDIF diff --git a/crypto/openssl/crypto/seed/seed.c b/crypto/openssl/crypto/seed/seed.c index c3a1f183a5cc..de3b3958ea60 100644 --- a/crypto/openssl/crypto/seed/seed.c +++ b/crypto/openssl/crypto/seed/seed.c @@ -1,7 +1,7 @@ /* - * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -34,6 +34,12 @@ */ #ifndef OPENSSL_NO_SEED +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + # include # include # include diff --git a/crypto/openssl/crypto/seed/seed_cbc.c b/crypto/openssl/crypto/seed/seed_cbc.c index c9a4fe217b9b..d5a324fd4443 100644 --- a/crypto/openssl/crypto/seed/seed_cbc.c +++ b/crypto/openssl/crypto/seed/seed_cbc.c @@ -1,12 +1,18 @@ /* - * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/openssl/crypto/seed/seed_cfb.c b/crypto/openssl/crypto/seed/seed_cfb.c index 2aee1ffe39a6..24fbfbf746e3 100644 --- a/crypto/openssl/crypto/seed/seed_cfb.c +++ b/crypto/openssl/crypto/seed/seed_cfb.c @@ -1,12 +1,18 @@ /* - * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/openssl/crypto/seed/seed_ecb.c b/crypto/openssl/crypto/seed/seed_ecb.c index b6e301ccdaac..9f357511cd94 100644 --- a/crypto/openssl/crypto/seed/seed_ecb.c +++ b/crypto/openssl/crypto/seed/seed_ecb.c @@ -1,12 +1,18 @@ /* - * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, diff --git a/crypto/openssl/crypto/seed/seed_local.h b/crypto/openssl/crypto/seed/seed_local.h index e3681f8bd455..dd40ee69deb6 100644 --- a/crypto/openssl/crypto/seed/seed_local.h +++ b/crypto/openssl/crypto/seed/seed_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -35,7 +35,7 @@ #ifndef OSSL_CRYPTO_SEED_LOCAL_H # define OSSL_CRYPTO_SEED_LOCAL_H -# include "openssl/e_os2.h" +# include # include # ifdef SEED_LONG /* need 32-bit type */ diff --git a/crypto/openssl/crypto/seed/seed_ofb.c b/crypto/openssl/crypto/seed/seed_ofb.c index b45554058501..b2e905331d9f 100644 --- a/crypto/openssl/crypto/seed/seed_ofb.c +++ b/crypto/openssl/crypto/seed/seed_ofb.c @@ -1,12 +1,18 @@ /* - * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * SEED low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include diff --git a/crypto/openssl/crypto/self_test_core.c b/crypto/openssl/crypto/self_test_core.c new file mode 100644 index 000000000000..dad4be208a4a --- /dev/null +++ b/crypto/openssl/crypto/self_test_core.c @@ -0,0 +1,172 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "internal/cryptlib.h" + +typedef struct self_test_cb_st +{ + OSSL_CALLBACK *cb; + void *cbarg; +} SELF_TEST_CB; + +struct ossl_self_test_st +{ + /* local state variables */ + const char *phase; + const char *type; + const char *desc; + OSSL_CALLBACK *cb; + + /* callback related variables used to pass the state back to the user */ + OSSL_PARAM params[4]; + void *cb_arg; +}; + +#ifndef FIPS_MODULE +static void *self_test_set_callback_new(OSSL_LIB_CTX *ctx) +{ + SELF_TEST_CB *stcb; + + stcb = OPENSSL_zalloc(sizeof(*stcb)); + return stcb; +} + +static void self_test_set_callback_free(void *stcb) +{ + OPENSSL_free(stcb); +} + +static const OSSL_LIB_CTX_METHOD self_test_set_callback_method = { + OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, + self_test_set_callback_new, + self_test_set_callback_free, +}; + +static SELF_TEST_CB *get_self_test_callback(OSSL_LIB_CTX *libctx) +{ + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_SELF_TEST_CB_INDEX, + &self_test_set_callback_method); +} + +void OSSL_SELF_TEST_set_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK *cb, + void *cbarg) +{ + SELF_TEST_CB *stcb = get_self_test_callback(libctx); + + if (stcb != NULL) { + stcb->cb = cb; + stcb->cbarg = cbarg; + } +} + +void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb, + void **cbarg) +{ + SELF_TEST_CB *stcb = get_self_test_callback(libctx); + + if (cb != NULL) + *cb = (stcb != NULL ? stcb->cb : NULL); + if (cbarg != NULL) + *cbarg = (stcb != NULL ? stcb->cbarg : NULL); +} +#endif /* FIPS_MODULE */ + +static void self_test_setparams(OSSL_SELF_TEST *st) +{ + size_t n = 0; + + if (st->cb != NULL) { + st->params[n++] = + OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_PHASE, + (char *)st->phase, 0); + st->params[n++] = + OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_TYPE, + (char *)st->type, 0); + st->params[n++] = + OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_DESC, + (char *)st->desc, 0); + } + st->params[n++] = OSSL_PARAM_construct_end(); +} + +OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg) +{ + OSSL_SELF_TEST *ret = OPENSSL_zalloc(sizeof(*ret)); + + if (ret == NULL) + return NULL; + + ret->cb = cb; + ret->cb_arg = cbarg; + ret->phase = ""; + ret->type = ""; + ret->desc = ""; + self_test_setparams(ret); + return ret; +} + +void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st) +{ + OPENSSL_free(st); +} + +/* Can be used during application testing to log that a test has started. */ +void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type, + const char *desc) +{ + if (st != NULL && st->cb != NULL) { + st->phase = OSSL_SELF_TEST_PHASE_START; + st->type = type; + st->desc = desc; + self_test_setparams(st); + (void)st->cb(st->params, st->cb_arg); + } +} + +/* + * Can be used during application testing to log that a test has either + * passed or failed. + */ +void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret) +{ + if (st != NULL && st->cb != NULL) { + st->phase = + (ret == 1 ? OSSL_SELF_TEST_PHASE_PASS : OSSL_SELF_TEST_PHASE_FAIL); + self_test_setparams(st); + (void)st->cb(st->params, st->cb_arg); + + st->phase = OSSL_SELF_TEST_PHASE_NONE; + st->type = OSSL_SELF_TEST_TYPE_NONE; + st->desc = OSSL_SELF_TEST_DESC_NONE; + } +} + +/* + * Used for failure testing. + * + * Call the applications SELF_TEST_cb() if it exists. + * If the application callback decides to return 0 then the first byte of 'bytes' + * is modified (corrupted). This is used to modify output signatures or + * ciphertext before they are verified or decrypted. + */ +int OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes) +{ + if (st != NULL && st->cb != NULL) { + st->phase = OSSL_SELF_TEST_PHASE_CORRUPT; + self_test_setparams(st); + if (!st->cb(st->params, st->cb_arg)) { + bytes[0] ^= 1; + return 1; + } + } + return 0; +} diff --git a/crypto/openssl/crypto/sha/asm/keccak1600-armv4.pl b/crypto/openssl/crypto/sha/asm/keccak1600-armv4.pl index 39fe559e974b..eaad86d39ddf 100755 --- a/crypto/openssl/crypto/sha/asm/keccak1600-armv4.pl +++ b/crypto/openssl/crypto/sha/asm/keccak1600-armv4.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -70,9 +70,10 @@ # Cortex-Mx, x>=3. Otherwise, non-NEON results for NEON-capable # processors are presented mostly for reference purposes. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -80,9 +81,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } my @C = map("r$_",(0..9)); @@ -113,8 +115,6 @@ my @T = map([ 8*$_, 8*($_+1), 8*($_+2), 8*($_+3), 8*($_+4) ], (30,35,40,45,50)); $code.=<<___; #include "arm_arch.h" -.text - #if defined(__thumb2__) .syntax unified .thumb @@ -122,6 +122,8 @@ $code.=<<___; .code 32 #endif +.text + .type iotas32, %object .align 5 iotas32: @@ -691,7 +693,14 @@ ___ $code.=<<___; blo .Lround2x +#if __ARM_ARCH__>=5 ldr pc,[sp,#440] +#else + ldr lr,[sp,#440] + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif .size KeccakF1600_int,.-KeccakF1600_int .type KeccakF1600, %function @@ -730,7 +739,14 @@ KeccakF1600: stmia @E[1], {@C[0]-@C[9]} add sp,sp,#440+20 +#if __ARM_ARCH__>=5 ldmia sp!,{r4-r11,pc} +#else + ldmia sp!,{r4-r11,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif .size KeccakF1600,.-KeccakF1600 ___ { my ($A_flat,$inp,$len,$bsz) = map("r$_",(10..12,14)); @@ -905,7 +921,14 @@ SHA3_absorb: .Labsorb_abort: add sp,sp,#456+32 mov r0,$len @ return value +#if __ARM_ARCH__>=5 ldmia sp!,{r4-r12,pc} +#else + ldmia sp!,{r4-r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif .size SHA3_absorb,.-SHA3_absorb ___ } @@ -1055,7 +1078,14 @@ SHA3_squeeze: .align 4 .Lsqueeze_done: add sp,sp,#24 +#if __ARM_ARCH__>=5 ldmia sp!,{r4-r10,pc} +#else + ldmia sp!,{r4-r10,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif .size SHA3_squeeze,.-SHA3_squeeze ___ } @@ -1265,7 +1295,7 @@ KeccakF1600_neon: subs r3, r3, #1 bne .Loop_neon - bx lr + ret .size KeccakF1600_neon,.-KeccakF1600_neon .global SHA3_absorb_neon diff --git a/crypto/openssl/crypto/sha/asm/keccak1600-armv8.pl b/crypto/openssl/crypto/sha/asm/keccak1600-armv8.pl index ce5df4d6de1b..65102e7c292f 100755 --- a/crypto/openssl/crypto/sha/asm/keccak1600-armv8.pl +++ b/crypto/openssl/crypto/sha/asm/keccak1600-armv8.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -51,6 +51,7 @@ # Kryo 12 # Denver 7.8 # Apple A7 7.2 +# ThunderX2 9.7 # # (*) Corresponds to SHA3-256. No improvement coefficients are listed # because they vary too much from compiler to compiler. Newer @@ -58,15 +59,18 @@ # Cortex-A57 to 25% on Cortex-A53. While in comparison to older # compiler this code is at least 2x faster... -$flavour = shift; -$output = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my @rhotates = ([ 0, 1, 62, 28, 27 ], @@ -541,30 +545,28 @@ my @A = map([ "v".$_.".16b", "v".($_+1).".16b", "v".($_+2).".16b", (0, 5, 10, 15, 20)); my @C = map("v$_.16b", (25..31)); +my @D = @C[4,5,6,2,3]; $code.=<<___; .type KeccakF1600_ce,%function .align 5 KeccakF1600_ce: - mov x9,#12 + mov x9,#24 adr x10,iotas b .Loop_ce .align 4 .Loop_ce: -___ -for($i=0; $i<2; $i++) { -$code.=<<___; ////////////////////////////////////////////////// Theta - eor3 $C[0],$A[0][0],$A[1][0],$A[2][0] - eor3 $C[1],$A[0][1],$A[1][1],$A[2][1] - eor3 $C[2],$A[0][2],$A[1][2],$A[2][2] - eor3 $C[3],$A[0][3],$A[1][3],$A[2][3] - eor3 $C[4],$A[0][4],$A[1][4],$A[2][4] - eor3 $C[0],$C[0], $A[3][0],$A[4][0] - eor3 $C[1],$C[1], $A[3][1],$A[4][1] - eor3 $C[2],$C[2], $A[3][2],$A[4][2] - eor3 $C[3],$C[3], $A[3][3],$A[4][3] - eor3 $C[4],$C[4], $A[3][4],$A[4][4] + eor3 $C[0],$A[4][0],$A[3][0],$A[2][0] + eor3 $C[1],$A[4][1],$A[3][1],$A[2][1] + eor3 $C[2],$A[4][2],$A[3][2],$A[2][2] + eor3 $C[3],$A[4][3],$A[3][3],$A[2][3] + eor3 $C[4],$A[4][4],$A[3][4],$A[2][4] + eor3 $C[0],$C[0], $A[1][0],$A[0][0] + eor3 $C[1],$C[1], $A[1][1],$A[0][1] + eor3 $C[2],$C[2], $A[1][2],$A[0][2] + eor3 $C[3],$C[3], $A[1][3],$A[0][3] + eor3 $C[4],$C[4], $A[1][4],$A[0][4] rax1 $C[5],$C[0],$C[2] // D[1] rax1 $C[6],$C[1],$C[3] // D[2] @@ -573,81 +575,75 @@ $code.=<<___; rax1 $C[4],$C[4],$C[1] // D[0] ////////////////////////////////////////////////// Theta+Rho+Pi - xar $C[0], $A[1][1],$C[5],#64-$rhotates[1][1] // C[0]=A[0][1] - xar $A[1][1],$A[1][4],$C[3],#64-$rhotates[1][4] - xar $A[1][4],$A[4][2],$C[6],#64-$rhotates[4][2] - xar $A[4][2],$A[2][4],$C[3],#64-$rhotates[2][4] - xar $A[2][4],$A[4][0],$C[4],#64-$rhotates[4][0] + xar $C[0], $A[0][1],$D[1],#64-$rhotates[0][1] // C[0]=A[2][0] - xar $A[4][0],$A[0][2],$C[6],#64-$rhotates[0][2] + xar $A[0][1],$A[1][1],$D[1],#64-$rhotates[1][1] + xar $A[1][1],$A[1][4],$D[4],#64-$rhotates[1][4] + xar $A[1][4],$A[4][2],$D[2],#64-$rhotates[4][2] + xar $A[4][2],$A[2][4],$D[4],#64-$rhotates[2][4] + xar $A[2][4],$A[4][0],$D[0],#64-$rhotates[4][0] - xar $A[0][2],$A[2][2],$C[6],#64-$rhotates[2][2] - xar $A[2][2],$A[2][3],$C[2],#64-$rhotates[2][3] - xar $A[2][3],$A[3][4],$C[3],#64-$rhotates[3][4] - xar $A[3][4],$A[4][3],$C[2],#64-$rhotates[4][3] - xar $A[4][3],$A[3][0],$C[4],#64-$rhotates[3][0] + xar $C[1], $A[0][2],$D[2],#64-$rhotates[0][2] // C[1]=A[4][0] - xar $A[3][0],$A[0][4],$C[3],#64-$rhotates[0][4] + xar $A[0][2],$A[2][2],$D[2],#64-$rhotates[2][2] + xar $A[2][2],$A[2][3],$D[3],#64-$rhotates[2][3] + xar $A[2][3],$A[3][4],$D[4],#64-$rhotates[3][4] + xar $A[3][4],$A[4][3],$D[3],#64-$rhotates[4][3] + xar $A[4][3],$A[3][0],$D[0],#64-$rhotates[3][0] - eor $A[0][0],$A[0][0],$C[4] - ldr x11,[x10],#8 + xar $A[3][0],$A[0][4],$D[4],#64-$rhotates[0][4] - xar $C[1], $A[3][3],$C[2],#64-$rhotates[3][3] // C[1]=A[0][3] - xar $A[3][3],$A[3][2],$C[6],#64-$rhotates[3][2] - xar $A[3][2],$A[2][1],$C[5],#64-$rhotates[2][1] - xar $A[2][1],$A[1][2],$C[6],#64-$rhotates[1][2] - xar $A[1][2],$A[2][0],$C[4],#64-$rhotates[2][0] + xar $D[4], $A[4][4],$D[4],#64-$rhotates[4][4] // D[4]=A[0][4] + xar $A[4][4],$A[4][1],$D[1],#64-$rhotates[4][1] + xar $A[1][3],$A[1][3],$D[3],#64-$rhotates[1][3] // A[1][3]=A[4][1] + xar $A[0][4],$A[3][1],$D[1],#64-$rhotates[3][1] // A[0][4]=A[1][3] + xar $A[3][1],$A[1][0],$D[0],#64-$rhotates[1][0] - xar $A[2][0],$A[0][1],$C[5],#64-$rhotates[0][1] // * + xar $A[1][0],$A[0][3],$D[3],#64-$rhotates[0][3] - xar $A[0][4],$A[4][4],$C[3],#64-$rhotates[4][4] - xar $A[4][4],$A[4][1],$C[5],#64-$rhotates[4][1] - xar $A[4][1],$A[1][3],$C[2],#64-$rhotates[1][3] - xar $A[1][3],$A[3][1],$C[5],#64-$rhotates[3][1] - xar $A[3][1],$A[1][0],$C[4],#64-$rhotates[1][0] + eor $A[0][0],$A[0][0],$D[0] - xar $C[2], $A[0][3],$C[2],#64-$rhotates[0][3] // C[2]=A[1][0] + xar $D[3], $A[3][3],$D[3],#64-$rhotates[3][3] // D[3]=A[0][3] + xar $A[0][3],$A[3][2],$D[2],#64-$rhotates[3][2] // A[0][3]=A[3][3] + xar $D[1], $A[2][1],$D[1],#64-$rhotates[2][1] // D[1]=A[3][2] + xar $D[2], $A[1][2],$D[2],#64-$rhotates[1][2] // D[2]=A[2][1] + xar $D[0], $A[2][0],$D[0],#64-$rhotates[2][0] // D[0]=A[1][2] ////////////////////////////////////////////////// Chi+Iota - dup $C[6],x11 // borrow C[6] - bcax $C[3], $A[0][0],$A[0][2],$C[0] // * - bcax $A[0][1],$C[0], $C[1], $A[0][2] // * - bcax $A[0][2],$A[0][2],$A[0][4],$C[1] - bcax $A[0][3],$C[1], $A[0][0],$A[0][4] - bcax $A[0][4],$A[0][4],$C[0], $A[0][0] - - bcax $A[1][0],$C[2], $A[1][2],$A[1][1] // * - bcax $C[0], $A[1][1],$A[1][3],$A[1][2] // * - bcax $A[1][2],$A[1][2],$A[1][4],$A[1][3] - bcax $A[1][3],$A[1][3],$C[2], $A[1][4] - bcax $A[1][4],$A[1][4],$A[1][1],$C[2] - - eor $A[0][0],$C[3],$C[6] // Iota - - bcax $C[1], $A[2][0],$A[2][2],$A[2][1] // * - bcax $C[2], $A[2][1],$A[2][3],$A[2][2] // * - bcax $A[2][2],$A[2][2],$A[2][4],$A[2][3] - bcax $A[2][3],$A[2][3],$A[2][0],$A[2][4] - bcax $A[2][4],$A[2][4],$A[2][1],$A[2][0] + bcax $A[4][0],$C[1], $A[4][2],$A[1][3] // A[1][3]=A[4][1] + bcax $A[4][1],$A[1][3],$A[4][3],$A[4][2] // A[1][3]=A[4][1] + bcax $A[4][2],$A[4][2],$A[4][4],$A[4][3] + bcax $A[4][3],$A[4][3],$C[1], $A[4][4] + bcax $A[4][4],$A[4][4],$A[1][3],$C[1] // A[1][3]=A[4][1] + + ld1r {$C[1]},[x10],#8 - bcax $C[3], $A[3][0],$A[3][2],$A[3][1] // * - bcax $C[4], $A[3][1],$A[3][3],$A[3][2] // * - bcax $A[3][2],$A[3][2],$A[3][4],$A[3][3] - bcax $A[3][3],$A[3][3],$A[3][0],$A[3][4] + bcax $A[3][2],$D[1], $A[3][4],$A[0][3] // A[0][3]=A[3][3] + bcax $A[3][3],$A[0][3],$A[3][0],$A[3][4] // A[0][3]=A[3][3] bcax $A[3][4],$A[3][4],$A[3][1],$A[3][0] + bcax $A[3][0],$A[3][0],$D[1], $A[3][1] + bcax $A[3][1],$A[3][1],$A[0][3],$D[1] // A[0][3]=A[3][3] + + bcax $A[2][0],$C[0], $A[2][2],$D[2] + bcax $A[2][1],$D[2], $A[2][3],$A[2][2] + bcax $A[2][2],$A[2][2],$A[2][4],$A[2][3] + bcax $A[2][3],$A[2][3],$C[0], $A[2][4] + bcax $A[2][4],$A[2][4],$D[2], $C[0] + + bcax $A[1][2],$D[0], $A[1][4],$A[0][4] // A[0][4]=A[1][3] + bcax $A[1][3],$A[0][4],$A[1][0],$A[1][4] // A[0][4]=A[1][3] + bcax $A[1][4],$A[1][4],$A[1][1],$A[1][0] + bcax $A[1][0],$A[1][0],$D[0], $A[1][1] + bcax $A[1][1],$A[1][1],$A[0][4],$D[0] // A[0][4]=A[1][3] + + bcax $A[0][3],$D[3], $A[0][0],$D[4] + bcax $A[0][4],$D[4], $A[0][1],$A[0][0] + bcax $A[0][0],$A[0][0],$A[0][2],$A[0][1] + bcax $A[0][1],$A[0][1],$D[3], $A[0][2] + bcax $A[0][2],$A[0][2],$D[4], $D[3] + + eor $A[0][0],$A[0][0],$C[1] - bcax $C[5], $A[4][0],$A[4][2],$A[4][1] // * - bcax $C[6], $A[4][1],$A[4][3],$A[4][2] // * - bcax $A[4][2],$A[4][2],$A[4][4],$A[4][3] - bcax $A[4][3],$A[4][3],$A[4][0],$A[4][4] - bcax $A[4][4],$A[4][4],$A[4][1],$A[4][0] -___ - ( $A[1][1], $C[0]) = ( $C[0], $A[1][1]); - ($A[2][0],$A[2][1], $C[1],$C[2]) = ($C[1],$C[2], $A[2][0],$A[2][1]); - ($A[3][0],$A[3][1], $C[3],$C[4]) = ($C[3],$C[4], $A[3][0],$A[3][1]); - ($A[4][0],$A[4][1], $C[5],$C[6]) = ($C[5],$C[6], $A[4][0],$A[4][1]); -} -$code.=<<___; subs x9,x9,#1 bne .Loop_ce @@ -871,7 +867,7 @@ foreach(split("\n",$code)) { s/\`([^\`]*)\`/eval($1)/ge; - m/\bdup\b/ and s/\.16b/.2d/g or + m/\bld1r\b/ and s/\.16b/.2d/g or s/\b(eor3|rax1|xar|bcax)\s+(v.*)/unsha3($1,$2)/ge; print $_,"\n"; diff --git a/crypto/openssl/crypto/sha/asm/keccak1600-avx2.pl b/crypto/openssl/crypto/sha/asm/keccak1600-avx2.pl index 6104caf4ff1f..84682289bf7a 100755 --- a/crypto/openssl/crypto/sha/asm/keccak1600-avx2.pl +++ b/crypto/openssl/crypto/sha/asm/keccak1600-avx2.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -476,7 +476,6 @@ iotas: .asciz "Keccak-1600 absorb and squeeze for AVX2, CRYPTOGAMS by " ___ -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; print $code; close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/sha/asm/keccak1600-avx512.pl b/crypto/openssl/crypto/sha/asm/keccak1600-avx512.pl index 6bfff7881756..85d6e7ffe424 100755 --- a/crypto/openssl/crypto/sha/asm/keccak1600-avx512.pl +++ b/crypto/openssl/crypto/sha/asm/keccak1600-avx512.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -545,7 +545,6 @@ iotas: .asciz "Keccak-1600 absorb and squeeze for AVX-512F, CRYPTOGAMS by " ___ -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; print $code; close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/sha/asm/keccak1600-avx512vl.pl b/crypto/openssl/crypto/sha/asm/keccak1600-avx512vl.pl index 446706fc67d1..73e75f363f20 100755 --- a/crypto/openssl/crypto/sha/asm/keccak1600-avx512vl.pl +++ b/crypto/openssl/crypto/sha/asm/keccak1600-avx512vl.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -386,7 +386,6 @@ iotas: .asciz "Keccak-1600 absorb and squeeze for AVX512VL, CRYPTOGAMS by " ___ -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; print $code; close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/sha/asm/keccak1600-c64x.pl b/crypto/openssl/crypto/sha/asm/keccak1600-c64x.pl index 4d1bbee2cfdd..0a9dec85c299 100755 --- a/crypto/openssl/crypto/sha/asm/keccak1600-c64x.pl +++ b/crypto/openssl/crypto/sha/asm/keccak1600-c64x.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -879,7 +879,6 @@ iotas: .align 4 ___ -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; print $code; close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/openssl/crypto/sha/asm/keccak1600-mmx.pl b/crypto/openssl/crypto/sha/asm/keccak1600-mmx.pl index 353f1e147c3b..7657a23a9c27 100755 --- a/crypto/openssl/crypto/sha/asm/keccak1600-mmx.pl +++ b/crypto/openssl/crypto/sha/asm/keccak1600-mmx.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -65,8 +65,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/sha/asm/keccak1600-ppc64.pl b/crypto/openssl/crypto/sha/asm/keccak1600-ppc64.pl index 11b6329f09c0..83f8d8ef337b 100755 --- a/crypto/openssl/crypto/sha/asm/keccak1600-ppc64.pl +++ b/crypto/openssl/crypto/sha/asm/keccak1600-ppc64.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -27,17 +27,20 @@ # # r=1088(*) # -# PPC970/G5 14.6/+120% -# POWER7 10.3/+100% -# POWER8 11.5/+85% -# POWER9 9.4/+45% +# PPC970/G5 14.0/+130% +# POWER7 9.7/+110% +# POWER8 10.6/+100% +# POWER9 8.2/+66% # # (*) Corresponds to SHA3-256. Percentage after slash is improvement # over gcc-4.x-generated KECCAK_1X_ALT code. Newer compilers do # much better (but watch out for them generating code specific # to processor they execute on). -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -53,7 +56,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=24*$SIZE_T+6*$SIZE_T+32; $LOCALS=6*$SIZE_T; @@ -384,19 +388,19 @@ KeccakF1600: .type dword_le_load,\@function .align 5 dword_le_load: - lbzu r0,1(r3) - lbzu r4,1(r3) - lbzu r5,1(r3) + lbz r0,1(r3) + lbz r4,2(r3) + lbz r5,3(r3) insrdi r0,r4,8,48 - lbzu r4,1(r3) + lbz r4,4(r3) insrdi r0,r5,8,40 - lbzu r5,1(r3) + lbz r5,5(r3) insrdi r0,r4,8,32 - lbzu r4,1(r3) + lbz r4,6(r3) insrdi r0,r5,8,24 - lbzu r5,1(r3) + lbz r5,7(r3) insrdi r0,r4,8,16 - lbzu r4,1(r3) + lbzu r4,8(r3) insrdi r0,r5,8,8 insrdi r0,r4,8,0 blr @@ -657,21 +661,21 @@ SHA3_squeeze: ${UCMP}i $len,8 blt .Lsqueeze_tail - stbu r0,1($out) + stb r0,1($out) srdi r0,r0,8 - stbu r0,1($out) + stb r0,2($out) srdi r0,r0,8 - stbu r0,1($out) + stb r0,3($out) srdi r0,r0,8 - stbu r0,1($out) + stb r0,4($out) srdi r0,r0,8 - stbu r0,1($out) + stb r0,5($out) srdi r0,r0,8 - stbu r0,1($out) + stb r0,6($out) srdi r0,r0,8 - stbu r0,1($out) + stb r0,7($out) srdi r0,r0,8 - stbu r0,1($out) + stbu r0,8($out) subic. $len,$len,8 beq .Lsqueeze_done diff --git a/crypto/openssl/crypto/sha/asm/keccak1600-s390x.pl b/crypto/openssl/crypto/sha/asm/keccak1600-s390x.pl index a7d819a59057..86233c7e38f2 100755 --- a/crypto/openssl/crypto/sha/asm/keccak1600-s390x.pl +++ b/crypto/openssl/crypto/sha/asm/keccak1600-s390x.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -30,7 +30,10 @@ # amount of instruction and assumed instruction issue rate. It's ~2.5x # faster than compiler-generated code. -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -40,8 +43,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; my @A = map([ 8*$_, 8*($_+1), 8*($_+2), 8*($_+3), 8*($_+4) ], (0,5,10,15,20)); diff --git a/crypto/openssl/crypto/sha/asm/keccak1600-x86_64.pl b/crypto/openssl/crypto/sha/asm/keccak1600-x86_64.pl index b1a7e65e6baa..02f0116014d6 100755 --- a/crypto/openssl/crypto/sha/asm/keccak1600-x86_64.pl +++ b/crypto/openssl/crypto/sha/asm/keccak1600-x86_64.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -50,9 +50,10 @@ # improved by 14% by replacing rotates with double-precision # shift with same register as source and destination. -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -61,7 +62,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; my @A = map([ 8*$_-100, 8*($_+1)-100, 8*($_+2)-100, diff --git a/crypto/openssl/crypto/sha/asm/keccak1600p8-ppc.pl b/crypto/openssl/crypto/sha/asm/keccak1600p8-ppc.pl index c04c7deafeda..7554c87f2083 100755 --- a/crypto/openssl/crypto/sha/asm/keccak1600p8-ppc.pl +++ b/crypto/openssl/crypto/sha/asm/keccak1600p8-ppc.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -25,7 +25,10 @@ # successor can achieve higher scalar instruction issue rate, then # this module will loose... And it does on POWER9 with 12.0 vs. 9.4. -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -48,7 +51,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=6*$SIZE_T+13*16; # 13*16 is for v20-v31 offload diff --git a/crypto/openssl/crypto/sha/asm/sha1-586.pl b/crypto/openssl/crypto/sha/asm/sha1-586.pl index b72869b86d4a..00350324a117 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-586.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 1998-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -123,8 +123,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/sha/asm/sha1-armv4-large.pl b/crypto/openssl/crypto/sha/asm/sha1-armv4-large.pl index 52d426bb29f8..6a2e12bf17d7 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-armv4-large.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-armv4-large.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -75,9 +75,10 @@ # # Add ARMv8 code path performing at 2.35 cpb on Apple A7. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -85,9 +86,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $ctx="r0"; @@ -187,7 +189,6 @@ ___ $code=<<___; #include "arm_arch.h" -.text #if defined(__thumb2__) .syntax unified .thumb @@ -195,6 +196,8 @@ $code=<<___; .code 32 #endif +.text + .global sha1_block_data_order .type sha1_block_data_order,%function @@ -202,12 +205,14 @@ $code=<<___; sha1_block_data_order: #if __ARM_MAX_ARCH__>=7 .Lsha1_block: - adr r3,.Lsha1_block ldr r12,.LOPENSSL_armcap +# if !defined(_WIN32) + adr r3,.Lsha1_block ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r12,[r12] -#endif +# endif tst r12,#ARMV8_SHA1 bne .LARMv8 tst r12,#ARMV7_NEON @@ -311,7 +316,11 @@ $code.=<<___; .LK_60_79: .word 0xca62c1d6 #if __ARM_MAX_ARCH__>=7 .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.Lsha1_block +# endif #endif .asciz "SHA1 block transform for ARMv4/NEON/ARMv8, CRYPTOGAMS by " .align 5 @@ -613,14 +622,15 @@ my ($ABCD,$E,$E0,$E1)=map("q$_",(0..3)); my @MSG=map("q$_",(4..7)); my @Kxx=map("q$_",(8..11)); my ($W0,$W1,$ABCD_SAVE)=map("q$_",(12..14)); +my $_byte = ($flavour =~ /win/ ? "DCB" : ".byte"); $code.=<<___; #if __ARM_MAX_ARCH__>=7 # if defined(__thumb2__) -# define INST(a,b,c,d) .byte c,d|0xf,a,b +# define INST(a,b,c,d) $_byte c,d|0xf,a,b # else -# define INST(a,b,c,d) .byte a,b,c,d|0x10 +# define INST(a,b,c,d) $_byte a,b,c,d|0x10 # endif .type sha1_block_data_order_armv8,%function diff --git a/crypto/openssl/crypto/sha/asm/sha1-armv8.pl b/crypto/openssl/crypto/sha/asm/sha1-armv8.pl index 557cabc018e0..cdea8845af85 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-armv8.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-armv8.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -27,20 +27,24 @@ # X-Gene 8.80 (+200%) # Mongoose 2.05 6.50 (+160%) # Kryo 1.88 8.00 (+90%) +# ThunderX2 2.64 6.36 (+150%) # # (*) Software results are presented mostly for reference purposes. # (**) Keep in mind that Denver relies on binary translation, which # optimizes compiler output at run-time. -$flavour = shift; -$output = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; -open OUT,"| \"$^X\" $xlate $flavour $output"; +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $1"; *STDOUT=*OUT; ($ctx,$inp,$num)=("x0","x1","x2"); @@ -58,10 +62,10 @@ $code.=<<___ if ($i<15 && !($i&1)); lsr @Xx[$i+1],@Xx[$i],#32 ___ $code.=<<___ if ($i<14 && !($i&1)); - ldr @Xx[$i+2],[$inp,#`($i+2)*4-64`] + ldur @Xx[$i+2],[$inp,#`($i+2)*4-64`] ___ $code.=<<___ if ($i<14 && ($i&1)); -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror @Xx[$i+1],@Xx[$i+1],#32 #else rev32 @Xx[$i+1],@Xx[$i+1] @@ -171,24 +175,20 @@ ___ } $code.=<<___; -#include "arm_arch.h" +#ifndef __KERNEL__ +# include "arm_arch.h" +.extern OPENSSL_armcap_P +.hidden OPENSSL_armcap_P +#endif .text -.extern OPENSSL_armcap_P -.hidden OPENSSL_armcap_P .globl sha1_block_data_order .type sha1_block_data_order,%function .align 6 sha1_block_data_order: -#ifdef __ILP32__ - ldrsw x16,.LOPENSSL_armcap_P -#else - ldr x16,.LOPENSSL_armcap_P -#endif - adr x17,.LOPENSSL_armcap_P - add x16,x16,x17 - ldr w16,[x16] + adrp x16,OPENSSL_armcap_P + ldr w16,[x16,#:lo12:OPENSSL_armcap_P] tst w16,#ARMV8_SHA1 b.ne .Lv8_entry @@ -209,7 +209,7 @@ sha1_block_data_order: movz $K,#0x7999 sub $num,$num,#1 movk $K,#0x5a82,lsl#16 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror $Xx[0],@Xx[0],#32 #else rev32 @Xx[0],@Xx[0] @@ -322,12 +322,6 @@ $code.=<<___; .long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39 .long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59 .long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79 -.LOPENSSL_armcap_P: -#ifdef __ILP32__ -.long OPENSSL_armcap_P-. -#else -.quad OPENSSL_armcap_P-. -#endif .asciz "SHA1 block transform for ARMv8, CRYPTOGAMS by " .align 2 ___ diff --git a/crypto/openssl/crypto/sha/asm/sha1-c64xplus.pl b/crypto/openssl/crypto/sha/asm/sha1-c64xplus.pl index ceec503a9829..6a97da2b5702 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-c64xplus.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-c64xplus.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -32,8 +32,7 @@ # service routines are expected to preserve it and for own well-being # zero it upon entry. -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; ($CTX,$INP,$NUM) = ("A4","B4","A6"); # arguments diff --git a/crypto/openssl/crypto/sha/asm/sha1-ia64.pl b/crypto/openssl/crypto/sha/asm/sha1-ia64.pl index bf1d2ebeb0ab..f1b412dcf2e3 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-ia64.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-ia64.pl @@ -1,7 +1,7 @@ #! /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 +# 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 @@ -21,7 +21,8 @@ # Performance under big-endian OS such as HP-UX is 179MBps*1GHz, which # is >50% better than HP C and >2x better than gcc. -$output = pop; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; $code=<<___; .ident \"sha1-ia64.s, version 1.3\" diff --git a/crypto/openssl/crypto/sha/asm/sha1-mb-x86_64.pl b/crypto/openssl/crypto/sha/asm/sha1-mb-x86_64.pl index 47c588715163..67faba136d05 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-mb-x86_64.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-mb-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -38,9 +38,10 @@ # in real-life application are somewhat lower, e.g. for 2KB # fragments they range from 30% to 100% (on Haswell); -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -49,6 +50,11 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86_64-support.pl"; + +$ptr_size=&pointer_size($flavour); + $avx=0; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` @@ -70,7 +76,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0 $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; # void sha1_multi_block ( @@ -87,6 +94,7 @@ $inp="%rsi"; # 2nd arg $num="%edx"; @ptr=map("%r$_",(8..11)); $Tbl="%rbp"; +$inp_elm_size=2*$ptr_size; @V=($A,$B,$C,$D,$E)=map("%xmm$_",(0..4)); ($t0,$t1,$t2,$t3,$tx)=map("%xmm$_",(5..9)); @@ -407,9 +415,12 @@ $code.=<<___; xor $num,$num ___ for($i=0;$i<4;$i++) { + $ptr_reg=&pointer_register($flavour,@ptr[$i]); $code.=<<___; - mov `16*$i+0`($inp),@ptr[$i] # input pointer - mov `16*$i+8`($inp),%ecx # number of blocks + # input pointer + mov `$inp_elm_size*$i+0`($inp),$ptr_reg + # number of blocks + mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx cmp $num,%ecx cmovg %ecx,$num # find maximum test %ecx,%ecx @@ -486,7 +497,7 @@ $code.=<<___; mov `$REG_SZ*17+8`(%rsp),$num lea $REG_SZ($ctx),$ctx - lea `16*$REG_SZ/4`($inp),$inp + lea `$inp_elm_size*$REG_SZ/4`($inp),$inp dec $num jnz .Loop_grande @@ -564,9 +575,12 @@ $code.=<<___; xor $num,$num ___ for($i=0;$i<2;$i++) { + $ptr_reg=&pointer_register($flavour,@ptr[$i]); $code.=<<___; - mov `16*$i+0`($inp),@ptr[$i] # input pointer - mov `16*$i+8`($inp),%ecx # number of blocks + # input pointer + mov `$inp_elm_size*$i+0`($inp),$ptr_reg + # number of blocks + mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx cmp $num,%ecx cmovg %ecx,$num # find maximum test %ecx,%ecx @@ -749,7 +763,7 @@ $code.=<<___; movq $E0,0x80-0x40($ctx) # e1.e0 lea `$REG_SZ/2`($ctx),$ctx - lea `16*2`($inp),$inp + lea `$inp_elm_size*2`($inp),$inp dec $num jnz .Loop_grande_shaext @@ -1069,9 +1083,12 @@ $code.=<<___; xor $num,$num ___ for($i=0;$i<4;$i++) { + $ptr_reg=&pointer_register($flavour,@ptr[$i]); $code.=<<___; - mov `16*$i+0`($inp),@ptr[$i] # input pointer - mov `16*$i+8`($inp),%ecx # number of blocks + # input pointer + mov `$inp_elm_size*$i+0`($inp),$ptr_reg + # number of blocks + mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx cmp $num,%ecx cmovg %ecx,$num # find maximum test %ecx,%ecx @@ -1142,7 +1159,7 @@ $code.=<<___; mov `$REG_SZ*17+8`(%rsp),$num lea $REG_SZ($ctx),$ctx - lea `16*$REG_SZ/4`($inp),$inp + lea `$inp_elm_size*$REG_SZ/4`($inp),$inp dec $num jnz .Loop_grande_avx @@ -1238,9 +1255,12 @@ $code.=<<___; lea `$REG_SZ*16`(%rsp),%rbx ___ for($i=0;$i<8;$i++) { + $ptr_reg=&pointer_register($flavour,@ptr[$i]); $code.=<<___; - mov `16*$i+0`($inp),@ptr[$i] # input pointer - mov `16*$i+8`($inp),%ecx # number of blocks + # input pointer + mov `$inp_elm_size*$i+0`($inp),$ptr_reg + # number of blocks + mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx cmp $num,%ecx cmovg %ecx,$num # find maximum test %ecx,%ecx @@ -1311,7 +1331,7 @@ $code.=<<___; #mov `$REG_SZ*17+8`(%rsp),$num #lea $REG_SZ($ctx),$ctx - #lea `16*$REG_SZ/4`($inp),$inp + #lea `$inp_elm_size*$REG_SZ/4`($inp),$inp #dec $num #jnz .Loop_grande_avx2 diff --git a/crypto/openssl/crypto/sha/asm/sha1-mips.pl b/crypto/openssl/crypto/sha/asm/sha1-mips.pl index c293cd3bfa4e..b41dd7a5d269 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-mips.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-mips.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -52,8 +52,12 @@ # ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); # ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); # ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); -# -$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +# supported flavours are o32,n32,64,nubi32,nubi64, default is o32 +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : "o32"; if ($flavour =~ /64|n32/i) { $PTR_ADD="daddu"; # incidentally works even on n32 @@ -77,8 +81,7 @@ if ($flavour =~ /64|n32/i) { $big_endian=(`echo MIPSEB | $ENV{CC} -E -`=~/MIPSEB/)?0:1 if ($ENV{CC}); -for (@ARGV) { $output=$_ if (/\w[\w\-]*\.\w+$/); } -open STDOUT,">$output"; +$output and open STDOUT,">$output"; if (!defined($big_endian)) { $big_endian=(unpack('L',pack('N',1))==1); } diff --git a/crypto/openssl/crypto/sha/asm/sha1-parisc.pl b/crypto/openssl/crypto/sha/asm/sha1-parisc.pl index 70ef7956abfa..9eb98e8036a3 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-parisc.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-parisc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -26,9 +26,12 @@ # # Special thanks to polarhome.com for providing HP-UX account. -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/openssl/crypto/sha/asm/sha1-ppc.pl b/crypto/openssl/crypto/sha/asm/sha1-ppc.pl index 650a62912008..acea2e94f392 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-ppc.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-ppc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -26,7 +26,10 @@ # PPC970,gcc-4.0.0 +76% +59% # Power6,xlc-7 +68% +33% -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T =8; @@ -53,7 +56,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; $FRAME=24*$SIZE_T+64; $LOCALS=6*$SIZE_T; diff --git a/crypto/openssl/crypto/sha/asm/sha1-s390x.pl b/crypto/openssl/crypto/sha/asm/sha1-s390x.pl index 653a6cb50a8a..d870e0078eb8 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-s390x.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-s390x.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -40,7 +40,10 @@ $kimdfunc=1; # magic function code for kimd instruction -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -50,8 +53,7 @@ if ($flavour =~ /3[12]/) { $g="g"; } -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output and open STDOUT,">$output"; $K_00_39="%r0"; $K=$K_00_39; $K_40_79="%r1"; diff --git a/crypto/openssl/crypto/sha/asm/sha1-sparcv9.pl b/crypto/openssl/crypto/sha/asm/sha1-sparcv9.pl index 8c23d85a3d09..904eda646558 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-sparcv9.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-sparcv9.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -32,8 +32,7 @@ # single-process result on 8-core processor, or ~9GBps per 2.85GHz # socket. -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; @X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7"); $rot1m="%g2"; @@ -188,7 +187,10 @@ ___ } $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #ifdef __arch64__ .register %g2,#scratch diff --git a/crypto/openssl/crypto/sha/asm/sha1-sparcv9a.pl b/crypto/openssl/crypto/sha/asm/sha1-sparcv9a.pl index 4e90da4b8bc9..1b7a7f9c912b 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-sparcv9a.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-sparcv9a.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -47,8 +47,7 @@ for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } if ($bits==64) { $bias=2047; $frame=192; } else { $bias=0; $frame=112; } -$output=shift; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; $ctx="%i0"; $inp="%i1"; diff --git a/crypto/openssl/crypto/sha/asm/sha1-thumb.pl b/crypto/openssl/crypto/sha/asm/sha1-thumb.pl index b53e0bee052d..aece5ea0cddb 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-thumb.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-thumb.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -26,8 +26,7 @@ # by over 40%, while code increases by only 10% or 32 bytes. But once # again, the goal was to establish _size_ benchmark, not performance. -$output=shift; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; $inline=0; #$cheat_on_binutils=1; diff --git a/crypto/openssl/crypto/sha/asm/sha1-x86_64.pl b/crypto/openssl/crypto/sha/asm/sha1-x86_64.pl index 89146d137b9b..c66b8fca875e 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-x86_64.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -93,9 +93,10 @@ # because SSSE3 code is compiled unconditionally; # (**) SHAEXT result -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -126,7 +127,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0 $shaext=1; ### set to zero if compiling for 1.0.1 $avx=1 if (!$shaext && $avx); -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; $ctx="%rdi"; # 1st arg diff --git a/crypto/openssl/crypto/sha/asm/sha256-586.pl b/crypto/openssl/crypto/sha/asm/sha256-586.pl index 7523dbc165fa..8e19cd875e3f 100755 --- a/crypto/openssl/crypto/sha/asm/sha256-586.pl +++ b/crypto/openssl/crypto/sha/asm/sha256-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -73,8 +73,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/sha/asm/sha256-armv4.pl b/crypto/openssl/crypto/sha/asm/sha256-armv4.pl index d120febb4832..e8af05c2981f 100755 --- a/crypto/openssl/crypto/sha/asm/sha256-armv4.pl +++ b/crypto/openssl/crypto/sha/asm/sha256-armv4.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -44,9 +44,10 @@ # # Add ARMv8 code path performing at 2.0 cpb on Apple A7. -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -54,9 +55,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $ctx="r0"; $t0="r0"; @@ -181,7 +183,6 @@ $code=<<___; # define __ARM_MAX_ARCH__ 7 #endif -.text #if defined(__thumb2__) .syntax unified .thumb @@ -189,6 +190,8 @@ $code=<<___; .code 32 #endif +.text + .type K256,%object .align 5 K256: @@ -212,7 +215,11 @@ K256: .word 0 @ terminator #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.Lsha256_block_data_order +# endif #endif .align 5 @@ -227,10 +234,12 @@ sha256_block_data_order: #endif #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) ldr r12,.LOPENSSL_armcap +# if !defined(_WIN32) ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r12,[r12] -#endif +# endif tst r12,#ARMV8_SHA256 bne .LARMv8 tst r12,#ARMV7_NEON @@ -598,14 +607,15 @@ my ($ABCD,$EFGH,$abcd)=map("q$_",(0..2)); my @MSG=map("q$_",(8..11)); my ($W0,$W1,$ABCD_SAVE,$EFGH_SAVE)=map("q$_",(12..15)); my $Ktbl="r3"; +my $_byte = ($flavour =~ /win/ ? "DCB" : ".byte"); $code.=<<___; #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) # if defined(__thumb2__) -# define INST(a,b,c,d) .byte c,d|0xc,a,b +# define INST(a,b,c,d) $_byte c,d|0xc,a,b # else -# define INST(a,b,c,d) .byte a,b,c,d +# define INST(a,b,c,d) $_byte a,b,c,d # endif .type sha256_block_data_order_armv8,%function diff --git a/crypto/openssl/crypto/sha/asm/sha256-c64xplus.pl b/crypto/openssl/crypto/sha/asm/sha256-c64xplus.pl index b2d00e4fb1ab..13fd45fd762d 100755 --- a/crypto/openssl/crypto/sha/asm/sha256-c64xplus.pl +++ b/crypto/openssl/crypto/sha/asm/sha256-c64xplus.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -26,8 +26,7 @@ # service routines are expected to preserve it and for own well-being # zero it upon entry. -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +$output = pop and open STDOUT,">$output"; ($CTXA,$INP,$NUM) = ("A4","B4","A6"); # arguments $K256="A3"; diff --git a/crypto/openssl/crypto/sha/asm/sha256-mb-x86_64.pl b/crypto/openssl/crypto/sha/asm/sha256-mb-x86_64.pl index c8cc6efac95c..fa2ca86046cc 100755 --- a/crypto/openssl/crypto/sha/asm/sha256-mb-x86_64.pl +++ b/crypto/openssl/crypto/sha/asm/sha256-mb-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -39,9 +39,10 @@ # in real-life application are somewhat lower, e.g. for 2KB # fragments they range from 75% to 130% (on Haswell); -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -50,6 +51,11 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86_64-support.pl"; + +$ptr_size=&pointer_size($flavour); + $avx=0; if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` @@ -71,7 +77,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0 $avx = ($2>=3.0) + ($2>3.0); } -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; # void sha256_multi_block ( @@ -91,6 +98,7 @@ $inp="%rsi"; # 2nd arg $num="%edx"; # 3rd arg @ptr=map("%r$_",(8..11)); $Tbl="%rbp"; +$inp_elm_size=2*$ptr_size; @V=($A,$B,$C,$D,$E,$F,$G,$H)=map("%xmm$_",(8..15)); ($t1,$t2,$t3,$axb,$bxc,$Xi,$Xn,$sigma)=map("%xmm$_",(0..7)); @@ -289,9 +297,12 @@ $code.=<<___; xor $num,$num ___ for($i=0;$i<4;$i++) { + $ptr_reg=&pointer_register($flavour,@ptr[$i]); $code.=<<___; - mov `16*$i+0`($inp),@ptr[$i] # input pointer - mov `16*$i+8`($inp),%ecx # number of blocks + # input pointer + mov `$inp_elm_size*$i+0`($inp),$ptr_reg + # number of blocks + mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx cmp $num,%ecx cmovg %ecx,$num # find maximum test %ecx,%ecx @@ -390,7 +401,7 @@ $code.=<<___; mov `$REG_SZ*17+8`(%rsp),$num lea $REG_SZ($ctx),$ctx - lea `16*$REG_SZ/4`($inp),$inp + lea `$inp_elm_size*$REG_SZ/4`($inp),$inp dec $num jnz .Loop_grande @@ -468,9 +479,12 @@ $code.=<<___; xor $num,$num ___ for($i=0;$i<2;$i++) { + $ptr_reg=&pointer_register($flavour,@ptr[$i]); $code.=<<___; - mov `16*$i+0`($inp),@ptr[$i] # input pointer - mov `16*$i+8`($inp),%ecx # number of blocks + # input pointer + mov `$inp_elm_size*$i+0`($inp),$ptr_reg + # number of blocks + mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx cmp $num,%ecx cmovg %ecx,$num # find maximum test %ecx,%ecx @@ -751,7 +765,7 @@ $code.=<<___; movq @MSG0[1],0xe0-0x80($ctx) # H1.H0 lea `$REG_SZ/2`($ctx),$ctx - lea `16*2`($inp),$inp + lea `$inp_elm_size*2`($inp),$inp dec $num jnz .Loop_grande_shaext @@ -988,9 +1002,12 @@ $code.=<<___; xor $num,$num ___ for($i=0;$i<4;$i++) { + $ptr_reg=&pointer_register($flavour,@ptr[$i]); $code.=<<___; - mov `16*$i+0`($inp),@ptr[$i] # input pointer - mov `16*$i+8`($inp),%ecx # number of blocks + # input pointer + mov `$inp_elm_size*$i+0`($inp),$ptr_reg + # number of blocks + mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx cmp $num,%ecx cmovg %ecx,$num # find maximum test %ecx,%ecx @@ -1087,7 +1104,7 @@ $code.=<<___; mov `$REG_SZ*17+8`(%rsp),$num lea $REG_SZ($ctx),$ctx - lea `16*$REG_SZ/4`($inp),$inp + lea `$inp_elm_size*$REG_SZ/4`($inp),$inp dec $num jnz .Loop_grande_avx @@ -1178,9 +1195,12 @@ $code.=<<___; lea `$REG_SZ*16`(%rsp),%rbx ___ for($i=0;$i<8;$i++) { + $ptr_reg=&pointer_register($flavour,@ptr[$i]); $code.=<<___; - mov `16*$i+0`($inp),@ptr[$i] # input pointer - mov `16*$i+8`($inp),%ecx # number of blocks + # input pointer + mov `$inp_elm_size*$i+0`($inp),$ptr_reg + # number of blocks + mov `$inp_elm_size*$i+$ptr_size`($inp),%ecx cmp $num,%ecx cmovg %ecx,$num # find maximum test %ecx,%ecx @@ -1277,7 +1297,7 @@ $code.=<<___; #mov `$REG_SZ*17+8`(%rsp),$num #lea $REG_SZ($ctx),$ctx - #lea `16*$REG_SZ/4`($inp),$inp + #lea `$inp_elm_size*$REG_SZ/4`($inp),$inp #dec $num #jnz .Loop_grande_avx2 diff --git a/crypto/openssl/crypto/sha/asm/sha512-586.pl b/crypto/openssl/crypto/sha/asm/sha512-586.pl index 66b6e96f9ded..c25e773b0aa3 100755 --- a/crypto/openssl/crypto/sha/asm/sha512-586.pl +++ b/crypto/openssl/crypto/sha/asm/sha512-586.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -59,8 +59,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); diff --git a/crypto/openssl/crypto/sha/asm/sha512-armv4.pl b/crypto/openssl/crypto/sha/asm/sha512-armv4.pl index e9c5e0ce7687..1751c671e6d8 100755 --- a/crypto/openssl/crypto/sha/asm/sha512-armv4.pl +++ b/crypto/openssl/crypto/sha/asm/sha512-armv4.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -57,9 +57,10 @@ $hi="HI"; $lo="LO"; # ==================================================================== -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -67,9 +68,10 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open STDOUT,"| \"$^X\" $xlate $flavour $output"; + open STDOUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } $ctx="r0"; # parameter block @@ -196,6 +198,9 @@ $code.=<<___; add $Ktbl,$Ktbl,#8 ___ } + +my $_word = ($flavour =~ /win/ ? "DCDU" : ".word"); + $code=<<___; #ifndef __KERNEL__ # include "arm_arch.h" @@ -211,14 +216,13 @@ $code=<<___; #ifdef __ARMEL__ # define LO 0 # define HI 4 -# define WORD64(hi0,lo0,hi1,lo1) .word lo0,hi0, lo1,hi1 +# define WORD64(hi0,lo0,hi1,lo1) $_word lo0,hi0, lo1,hi1 #else # define HI 0 # define LO 4 -# define WORD64(hi0,lo0,hi1,lo1) .word hi0,lo0, hi1,lo1 +# define WORD64(hi0,lo0,hi1,lo1) $_word hi0,lo0, hi1,lo1 #endif -.text #if defined(__thumb2__) .syntax unified .thumb @@ -227,6 +231,8 @@ $code=<<___; .code 32 #endif +.text + .type K512,%object .align 5 K512: @@ -273,7 +279,11 @@ WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) .size K512,.-K512 #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) .LOPENSSL_armcap: +# ifdef _WIN32 +.word OPENSSL_armcap_P +# else .word OPENSSL_armcap_P-.Lsha512_block_data_order +# endif .skip 32-4 #else .skip 32 @@ -290,10 +300,12 @@ sha512_block_data_order: #endif #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) ldr r12,.LOPENSSL_armcap +# if !defined(_WIN32) ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ +# endif +# if defined(__APPLE__) || defined(_WIN32) ldr r12,[r12] -#endif +# endif tst r12,#ARMV7_NEON bne .LNEON #endif diff --git a/crypto/openssl/crypto/sha/asm/sha512-armv8.pl b/crypto/openssl/crypto/sha/asm/sha512-armv8.pl index 3188c905ea2d..6bcff0b7d3f3 100755 --- a/crypto/openssl/crypto/sha/asm/sha512-armv8.pl +++ b/crypto/openssl/crypto/sha/asm/sha512-armv8.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -28,6 +28,7 @@ # X-Gene 20.0 (+100%) 12.8 (+300%(***)) # Mongoose 2.36 13.0 (+50%) 8.36 (+33%) # Kryo 1.92 17.4 (+30%) 11.2 (+8%) +# ThunderX2 2.54 13.2 (+40%) 8.40 (+18%) # # (*) Software SHA256 results are of lesser relevance, presented # mostly for informational purposes. @@ -53,8 +54,10 @@ # deliver much less improvement, likely *negative* on Cortex-A5x. # Which is why NEON support is limited to SHA256.] -$output=pop; -$flavour=pop; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour && $flavour ne "void") { $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; @@ -62,10 +65,11 @@ if ($flavour && $flavour ne "void") { ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or die "can't locate arm-xlate.pl"; - open OUT,"| \"$^X\" $xlate $flavour $output"; + open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; } else { - open STDOUT,">$output"; + $output and open STDOUT,">$output"; } if ($output =~ /512/) { @@ -188,25 +192,19 @@ ___ $code.=<<___; #ifndef __KERNEL__ # include "arm_arch.h" +.extern OPENSSL_armcap_P +.hidden OPENSSL_armcap_P #endif .text -.extern OPENSSL_armcap_P -.hidden OPENSSL_armcap_P .globl $func .type $func,%function .align 6 $func: #ifndef __KERNEL__ -# ifdef __ILP32__ - ldrsw x16,.LOPENSSL_armcap_P -# else - ldr x16,.LOPENSSL_armcap_P -# endif - adr x17,.LOPENSSL_armcap_P - add x16,x16,x17 - ldr w16,[x16] + adrp x16,OPENSSL_armcap_P + ldr w16,[x16,#:lo12:OPENSSL_armcap_P] ___ $code.=<<___ if ($SZ==4); tst w16,#ARMV8_SHA256 @@ -354,15 +352,6 @@ $code.=<<___ if ($SZ==4); ___ $code.=<<___; .size .LK$BITS,.-.LK$BITS -#ifndef __KERNEL__ -.align 3 -.LOPENSSL_armcap_P: -# ifdef __ILP32__ - .long OPENSSL_armcap_P-. -# else - .quad OPENSSL_armcap_P-. -# endif -#endif .asciz "SHA$BITS block transform for ARMv8, CRYPTOGAMS by " .align 2 ___ diff --git a/crypto/openssl/crypto/sha/asm/sha512-c64xplus.pl b/crypto/openssl/crypto/sha/asm/sha512-c64xplus.pl index 4263fb1349aa..867f2a42d65b 100755 --- a/crypto/openssl/crypto/sha/asm/sha512-c64xplus.pl +++ b/crypto/openssl/crypto/sha/asm/sha512-c64xplus.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -29,8 +29,7 @@ # service routines are expected to preserve it and for own well-being # zero it upon entry. -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} -open STDOUT,">$output"; +($output = pop) =~ m|\.\w+$| and open STDOUT,">$output"; ($CTXA,$INP,$NUM) = ("A4","B4","A6"); # arguments $K512="A3"; diff --git a/crypto/openssl/crypto/sha/asm/sha512-ia64.pl b/crypto/openssl/crypto/sha/asm/sha512-ia64.pl index 356a46aced78..e147f2682d5b 100755 --- a/crypto/openssl/crypto/sha/asm/sha512-ia64.pl +++ b/crypto/openssl/crypto/sha/asm/sha512-ia64.pl @@ -1,7 +1,7 @@ #! /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 +# 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 @@ -75,9 +75,10 @@ # To generate code, pass the file name with either 256 or 512 in its # name and compiler flags. -$output=pop; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; -if ($output =~ /512.*\.[s|asm]/) { +if ($output =~ /512.*\.[s|asm]/i) { $SZ=8; $BITS=8*$SZ; $LDW="ld8"; @@ -91,7 +92,7 @@ if ($output =~ /512.*\.[s|asm]/) { @sigma0=(1, 8, 7); @sigma1=(19,61, 6); $rounds=80; -} elsif ($output =~ /256.*\.[s|asm]/) { +} elsif ($output =~ /256.*\.[s|asm]/i) { $SZ=4; $BITS=8*$SZ; $LDW="ld4"; @@ -107,7 +108,7 @@ if ($output =~ /512.*\.[s|asm]/) { $rounds=64; } else { die "nonsense $output"; } -open STDOUT,">$output" || die "can't open $output: $!"; +$output and (open STDOUT,">$output" or die "can't open $output: $!"); if ($^O eq "hpux") { $ADDP="addp4"; diff --git a/crypto/openssl/crypto/sha/asm/sha512-mips.pl b/crypto/openssl/crypto/sha/asm/sha512-mips.pl index 15acd5308dda..573bb574fc6d 100755 --- a/crypto/openssl/crypto/sha/asm/sha512-mips.pl +++ b/crypto/openssl/crypto/sha/asm/sha512-mips.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -56,7 +56,14 @@ # ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); # ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); # -$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64 +# if $output doesn't have an extension, it's not an output file +# so use it for $flavour. + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +# supported flavours are o32,n32,64,nubi32,nubi64, default is o32 +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : "o32"; if ($flavour =~ /64|n32/i) { $PTR_LA="dla"; @@ -83,7 +90,6 @@ $pf = ($flavour =~ /nubi/i) ? $t0 : $t2; $big_endian=(`echo MIPSEB | $ENV{CC} -E -`=~/MIPSEB/)?0:1 if ($ENV{CC}); -for (@ARGV) { $output=$_ if (/\w[\w\-]*\.\w+$/); } open STDOUT,">$output"; if (!defined($big_endian)) { $big_endian=(unpack('L',pack('N',1))==1); } diff --git a/crypto/openssl/crypto/sha/asm/sha512-parisc.pl b/crypto/openssl/crypto/sha/asm/sha512-parisc.pl index 132f1db8eb9e..d0e5a4d5cec2 100755 --- a/crypto/openssl/crypto/sha/asm/sha512-parisc.pl +++ b/crypto/openssl/crypto/sha/asm/sha512-parisc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -32,9 +32,12 @@ # # Special thanks to polarhome.com for providing HP-UX account. -$flavour = shift; -$output = shift; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$output and open STDOUT,">$output"; if ($flavour =~ /64/) { $LEVEL ="2.0W"; diff --git a/crypto/openssl/crypto/sha/asm/sha512-ppc.pl b/crypto/openssl/crypto/sha/asm/sha512-ppc.pl index 265ecfa58c87..966713936e62 100755 --- a/crypto/openssl/crypto/sha/asm/sha512-ppc.pl +++ b/crypto/openssl/crypto/sha/asm/sha512-ppc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -41,8 +41,10 @@ # block signals prior calling this routine. For the record, in 32-bit # context R2 serves as TLS pointer, while in 64-bit context - R13. -$flavour=shift; -$output =shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T=8; @@ -69,7 +71,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; if ($output =~ /512/) { $func="sha512_block_ppc"; diff --git a/crypto/openssl/crypto/sha/asm/sha512-s390x.pl b/crypto/openssl/crypto/sha/asm/sha512-s390x.pl index 9752fed4ea26..bc8ab0ca9fdd 100755 --- a/crypto/openssl/crypto/sha/asm/sha512-s390x.pl +++ b/crypto/openssl/crypto/sha/asm/sha512-s390x.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -43,7 +43,10 @@ # remains z/Architecture specific. On z990 SHA256 was measured to # perform 2.4x and SHA512 - 13x better than code generated by gcc 4.3. -$flavour = shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /3[12]/) { $SIZE_T=4; @@ -71,7 +74,6 @@ $tbl="%r13"; $T1="%r14"; $sp="%r15"; -while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} open STDOUT,">$output"; if ($output =~ /512/) { diff --git a/crypto/openssl/crypto/sha/asm/sha512-sparcv9.pl b/crypto/openssl/crypto/sha/asm/sha512-sparcv9.pl index 54429d34e398..6bf366ef1241 100755 --- a/crypto/openssl/crypto/sha/asm/sha512-sparcv9.pl +++ b/crypto/openssl/crypto/sha/asm/sha512-sparcv9.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -56,8 +56,10 @@ # saturates at 11.5x single-process result on 8-core processor, or # ~11/16GBps per 2.85GHz socket. -$output=pop; -open STDOUT,">$output"; +# $output is the last argument if it looks like a file (it has an extension) +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; + +$output and open STDOUT,">$output"; if ($output =~ /512/) { $label="512"; @@ -392,7 +394,10 @@ ___ } if ($SZ==8); $code.=<<___; -#include "sparc_arch.h" +#ifndef __ASSEMBLER__ +# define __ASSEMBLER__ 1 +#endif +#include "crypto/sparc_arch.h" #ifdef __arch64__ .register %g2,#scratch diff --git a/crypto/openssl/crypto/sha/asm/sha512-x86_64.pl b/crypto/openssl/crypto/sha/asm/sha512-x86_64.pl index ad37850e6130..1bd0256954b3 100755 --- a/crypto/openssl/crypto/sha/asm/sha512-x86_64.pl +++ b/crypto/openssl/crypto/sha/asm/sha512-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -10,7 +10,7 @@ # ==================================================================== # Written by Andy Polyakov for the OpenSSL # project. Rights for redistribution and usage in source and binary -# forms are granted according to the OpenSSL license. +# forms are granted according to the License. # ==================================================================== # # sha256/512_block procedure for x86_64. @@ -109,9 +109,10 @@ # below certain limit makes no difference/sense; to conserve # space SHA256 XOP code path is therefore omitted; -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -142,7 +143,8 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0 $shaext=1; ### set to zero if compiling for 1.0.1 $avx=1 if (!$shaext && $avx); -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; if ($output =~ /512/) { diff --git a/crypto/openssl/crypto/sha/asm/sha512p8-ppc.pl b/crypto/openssl/crypto/sha/asm/sha512p8-ppc.pl index 3f202964261d..97df14ef4ccd 100755 --- a/crypto/openssl/crypto/sha/asm/sha512p8-ppc.pl +++ b/crypto/openssl/crypto/sha/asm/sha512p8-ppc.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -40,8 +40,10 @@ # SHA256 9.7 [15.8] 11.2 [12.5] # SHA512 6.1 [10.3] 7.0 [7.9] -$flavour=shift; -$output =shift; +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; if ($flavour =~ /64/) { $SIZE_T=8; @@ -64,7 +66,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; -open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; +open STDOUT,"| $^X $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; if ($output =~ /512/) { $bits=512; diff --git a/crypto/openssl/crypto/sha/build.info b/crypto/openssl/crypto/sha/build.info index 5dd5a9941d34..d61f7de9b6bd 100644 --- a/crypto/openssl/crypto/sha/build.info +++ b/crypto/openssl/crypto/sha/build.info @@ -1,89 +1,176 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - sha1dgst.c sha1_one.c sha256.c sha512.c {- $target{sha1_asm_src} -} \ - {- $target{keccak1600_asm_src} -} - -GENERATE[sha1-586.s]=asm/sha1-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[sha1-586.s]=../perlasm/x86asm.pl -GENERATE[sha256-586.s]=asm/sha256-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[sha256-586.s]=../perlasm/x86asm.pl -GENERATE[sha512-586.s]=asm/sha512-586.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[sha512-586.s]=../perlasm/x86asm.pl - -GENERATE[sha1-ia64.s]=asm/sha1-ia64.pl $(LIB_CFLAGS) $(LIB_CPPFLAGS) -GENERATE[sha256-ia64.s]=asm/sha512-ia64.pl $(LIB_CFLAGS) $(LIB_CPPFLAGS) -GENERATE[sha512-ia64.s]=asm/sha512-ia64.pl $(LIB_CFLAGS) $(LIB_CPPFLAGS) - -GENERATE[sha1-alpha.S]=asm/sha1-alpha.pl $(PERLASM_SCHEME) - -GENERATE[sha1-x86_64.s]=asm/sha1-x86_64.pl $(PERLASM_SCHEME) -GENERATE[sha1-mb-x86_64.s]=asm/sha1-mb-x86_64.pl $(PERLASM_SCHEME) -GENERATE[sha256-x86_64.s]=asm/sha512-x86_64.pl $(PERLASM_SCHEME) -GENERATE[sha256-mb-x86_64.s]=asm/sha256-mb-x86_64.pl $(PERLASM_SCHEME) -GENERATE[sha512-x86_64.s]=asm/sha512-x86_64.pl $(PERLASM_SCHEME) -GENERATE[keccak1600-x86_64.s]=asm/keccak1600-x86_64.pl $(PERLASM_SCHEME) - -GENERATE[sha1-sparcv9.S]=asm/sha1-sparcv9.pl $(PERLASM_SCHEME) + +$SHA1ASM= +IF[{- !$disabled{asm} -}] + $SHA1ASM_x86=sha1-586.S sha256-586.S sha512-586.S + $SHA1DEF_x86=SHA1_ASM SHA256_ASM SHA512_ASM + $SHA1ASM_x86_64=\ + sha1-x86_64.s sha256-x86_64.s sha512-x86_64.s sha1-mb-x86_64.s \ + sha256-mb-x86_64.s + $SHA1DEF_x86_64=SHA1_ASM SHA256_ASM SHA512_ASM + + $SHA1ASM_ia64=sha1-ia64.s sha256-ia64.s sha512-ia64.s + $SHA1DEF_ia64=SHA1_ASM SHA256_ASM SHA512_ASM + + $SHA1ASM_sparcv9=sha1-sparcv9.S sha256-sparcv9.S sha512-sparcv9.S + $SHA1DEF_sparcv9=SHA1_ASM SHA256_ASM SHA512_ASM + + $SHA1ASM_alpha=sha1-alpha.S + $SHA1DEF_alpha=SHA1_ASM + + $SHA1ASM_mips32=sha1-mips.S sha256-mips.S + $SHA1DEF_mips32=SHA1_ASM SHA256_ASM + $SHA1ASM_mips64=$SHA1ASM_mips32 sha512-mips.S + $SHA1DEF_mips64=$SHA1DEF_mips32 SHA512_ASM + + $SHA1ASM_s390x=sha1-s390x.S sha256-s390x.S sha512-s390x.S + $SHA1DEF_s390x=SHA1_ASM SHA256_ASM SHA512_ASM + + $SHA1ASM_armv4=sha1-armv4-large.S sha256-armv4.S sha512-armv4.S + $SHA1DEF_armv4=SHA1_ASM SHA256_ASM SHA512_ASM + $SHA1ASM_aarch64=sha1-armv8.S sha256-armv8.S sha512-armv8.S + $SHA1DEF_aarch64=SHA1_ASM SHA256_ASM SHA512_ASM + + $SHA1ASM_parisc11=sha1-parisc.s sha256-parisc.s sha512-parisc.s + $SHA1DEF_parisc11=SHA1_ASM SHA256_ASM SHA512_ASM + $SHA1ASM_parisc20_64=$SHA1ASM_parisc11 + $SHA1DEF_parisc20_64=$SHA1DEF_parisc11 + + $SHA1ASM_ppc32=\ + sha_ppc.c sha1-ppc.s sha256-ppc.s sha512-ppc.s sha256p8-ppc.s \ + sha512p8-ppc.s + $SHA1DEF_ppc32=SHA1_ASM SHA256_ASM SHA512_ASM + $SHA1ASM_ppc64=$SHA1ASM_ppc32 + $SHA1DEF_ppc64=$SHA1DEF_ppc32 + + $SHA1ASM_c64xplus=sha1-c64xplus.s sha256-c64xplus.s sha512-c64xplus.s + $SHA1DEF_c64xplus=SHA1_ASM SHA256_ASM SHA512_ASM + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$SHA1ASM_{- $target{asm_arch} -}] + $SHA1ASM=$SHA1ASM_{- $target{asm_arch} -} + $SHA1DEF=$SHA1DEF_{- $target{asm_arch} -} + ENDIF +ENDIF + +$KECCAK1600ASM=keccak1600.c +IF[{- !$disabled{asm} -}] + $KECCAK1600ASM_x86= + $KECCAK1600ASM_x86_64=keccak1600-x86_64.s + + $KECCAK1600ASM_s390x=keccak1600-s390x.S + + $KECCAK1600ASM_armv4=keccak1600-armv4.S + $KECCAK1600ASM_aarch64=keccak1600-armv8.S + + $KECCAK1600ASM_ppc64=keccak1600-ppc64.s + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$KECCAK1600ASM_{- $target{asm_arch} -}] + $KECCAK1600ASM=$KECCAK1600ASM_{- $target{asm_arch} -} + $KECCAK1600DEF=KECCAK1600_ASM + ENDIF +ENDIF + +$COMMON=sha1dgst.c sha256.c sha512.c sha3.c $SHA1ASM $KECCAK1600ASM +SOURCE[../../libcrypto]=$COMMON sha1_one.c +SOURCE[../../providers/libfips.a]= $COMMON + +# Implementations are now spread across several libraries, so the defines +# need to be applied to all affected libraries and modules. +DEFINE[../../libcrypto]=$SHA1DEF $KECCAK1600DEF +DEFINE[../../providers/libfips.a]=$SHA1DEF $KECCAK1600DEF +DEFINE[../../providers/libdefault.a]=$SHA1DEF $KECCAK1600DEF +# We only need to include the SHA1DEF and KECCAK1600DEF stuff in the +# legacy provider when it's a separate module and it's dynamically +# linked with libcrypto. Otherwise, it already gets everything that +# the static libcrypto.a has, and doesn't need it added again. +IF[{- !$disabled{module} && !$disabled{shared} -}] + DEFINE[../providers/liblegacy.a]=$SHA1DEF $KECCAK1600DEF +ENDIF + +GENERATE[sha1-586.S]=asm/sha1-586.pl +DEPEND[sha1-586.S]=../perlasm/x86asm.pl +GENERATE[sha256-586.S]=asm/sha256-586.pl +DEPEND[sha256-586.S]=../perlasm/x86asm.pl +GENERATE[sha512-586.S]=asm/sha512-586.pl +DEPEND[sha512-586.S]=../perlasm/x86asm.pl + +GENERATE[sha1-ia64.s]=asm/sha1-ia64.pl +GENERATE[sha256-ia64.s]=asm/sha512-ia64.pl +GENERATE[sha512-ia64.s]=asm/sha512-ia64.pl + +GENERATE[sha1-alpha.S]=asm/sha1-alpha.pl + +GENERATE[sha1-x86_64.s]=asm/sha1-x86_64.pl +GENERATE[sha1-mb-x86_64.s]=asm/sha1-mb-x86_64.pl +GENERATE[sha256-x86_64.s]=asm/sha512-x86_64.pl +GENERATE[sha256-mb-x86_64.s]=asm/sha256-mb-x86_64.pl +GENERATE[sha512-x86_64.s]=asm/sha512-x86_64.pl +GENERATE[keccak1600-x86_64.s]=asm/keccak1600-x86_64.pl + +GENERATE[sha1-sparcv9a.S]=asm/sha1-sparcv9a.pl +GENERATE[sha1-sparcv9.S]=asm/sha1-sparcv9.pl INCLUDE[sha1-sparcv9.o]=.. -GENERATE[sha256-sparcv9.S]=asm/sha512-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[sha256-sparcv9.S]=asm/sha512-sparcv9.pl INCLUDE[sha256-sparcv9.o]=.. -GENERATE[sha512-sparcv9.S]=asm/sha512-sparcv9.pl $(PERLASM_SCHEME) +GENERATE[sha512-sparcv9.S]=asm/sha512-sparcv9.pl INCLUDE[sha512-sparcv9.o]=.. -GENERATE[sha1-ppc.s]=asm/sha1-ppc.pl $(PERLASM_SCHEME) -GENERATE[sha256-ppc.s]=asm/sha512-ppc.pl $(PERLASM_SCHEME) -GENERATE[sha512-ppc.s]=asm/sha512-ppc.pl $(PERLASM_SCHEME) -GENERATE[sha256p8-ppc.s]=asm/sha512p8-ppc.pl $(PERLASM_SCHEME) -GENERATE[sha512p8-ppc.s]=asm/sha512p8-ppc.pl $(PERLASM_SCHEME) -GENERATE[keccak1600-ppc64.s]=asm/keccak1600-ppc64.pl $(PERLASM_SCHEME) +GENERATE[sha1-ppc.s]=asm/sha1-ppc.pl +GENERATE[sha256-ppc.s]=asm/sha512-ppc.pl +GENERATE[sha512-ppc.s]=asm/sha512-ppc.pl +GENERATE[sha256p8-ppc.s]=asm/sha512p8-ppc.pl +GENERATE[sha512p8-ppc.s]=asm/sha512p8-ppc.pl +GENERATE[keccak1600-ppc64.s]=asm/keccak1600-ppc64.pl -GENERATE[sha1-parisc.s]=asm/sha1-parisc.pl $(PERLASM_SCHEME) -GENERATE[sha256-parisc.s]=asm/sha512-parisc.pl $(PERLASM_SCHEME) -GENERATE[sha512-parisc.s]=asm/sha512-parisc.pl $(PERLASM_SCHEME) +GENERATE[sha1-parisc.s]=asm/sha1-parisc.pl +GENERATE[sha256-parisc.s]=asm/sha512-parisc.pl +GENERATE[sha512-parisc.s]=asm/sha512-parisc.pl -GENERATE[sha1-mips.S]=asm/sha1-mips.pl $(PERLASM_SCHEME) +GENERATE[sha1-mips.S]=asm/sha1-mips.pl INCLUDE[sha1-mips.o]=.. -GENERATE[sha256-mips.S]=asm/sha512-mips.pl $(PERLASM_SCHEME) +GENERATE[sha256-mips.S]=asm/sha512-mips.pl INCLUDE[sha256-mips.o]=.. -GENERATE[sha512-mips.S]=asm/sha512-mips.pl $(PERLASM_SCHEME) +GENERATE[sha512-mips.S]=asm/sha512-mips.pl INCLUDE[sha512-mips.o]=.. -GENERATE[sha1-armv4-large.S]=asm/sha1-armv4-large.pl $(PERLASM_SCHEME) +GENERATE[sha1-armv4-large.S]=asm/sha1-armv4-large.pl INCLUDE[sha1-armv4-large.o]=.. -GENERATE[sha256-armv4.S]=asm/sha256-armv4.pl $(PERLASM_SCHEME) +GENERATE[sha256-armv4.S]=asm/sha256-armv4.pl INCLUDE[sha256-armv4.o]=.. -GENERATE[sha512-armv4.S]=asm/sha512-armv4.pl $(PERLASM_SCHEME) +GENERATE[sha512-armv4.S]=asm/sha512-armv4.pl INCLUDE[sha512-armv4.o]=.. -GENERATE[keccak1600-armv4.S]=asm/keccak1600-armv4.pl $(PERLASM_SCHEME) +GENERATE[keccak1600-armv4.S]=asm/keccak1600-armv4.pl INCLUDE[keccak1600-armv4.o]=.. -GENERATE[sha1-armv8.S]=asm/sha1-armv8.pl $(PERLASM_SCHEME) +GENERATE[sha1-armv8.S]=asm/sha1-armv8.pl INCLUDE[sha1-armv8.o]=.. -GENERATE[sha256-armv8.S]=asm/sha512-armv8.pl $(PERLASM_SCHEME) +GENERATE[sha256-armv8.S]=asm/sha512-armv8.pl INCLUDE[sha256-armv8.o]=.. -GENERATE[sha512-armv8.S]=asm/sha512-armv8.pl $(PERLASM_SCHEME) +GENERATE[sha512-armv8.S]=asm/sha512-armv8.pl INCLUDE[sha512-armv8.o]=.. -GENERATE[keccak1600-armv8.S]=asm/keccak1600-armv8.pl $(PERLASM_SCHEME) +GENERATE[keccak1600-armv8.S]=asm/keccak1600-armv8.pl -GENERATE[sha1-s390x.S]=asm/sha1-s390x.pl $(PERLASM_SCHEME) +GENERATE[sha1-s390x.S]=asm/sha1-s390x.pl INCLUDE[sha1-s390x.o]=.. -GENERATE[sha256-s390x.S]=asm/sha512-s390x.pl $(PERLASM_SCHEME) +GENERATE[sha256-s390x.S]=asm/sha512-s390x.pl INCLUDE[sha256-s390x.o]=.. -GENERATE[sha512-s390x.S]=asm/sha512-s390x.pl $(PERLASM_SCHEME) +GENERATE[sha512-s390x.S]=asm/sha512-s390x.pl INCLUDE[sha512-s390x.o]=.. -GENERATE[keccak1600-s390x.S]=asm/keccak1600-s390x.pl $(PERLASM_SCHEME) - -BEGINRAW[Makefile(unix)] -##### SHA assembler implementations - -# GNU make "catch all" -{- $builddir -}/sha1-%.S: {- $sourcedir -}/asm/sha1-%.pl - CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ -{- $builddir -}/sha256-%.S: {- $sourcedir -}/asm/sha512-%.pl - CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ -{- $builddir -}/sha512-%.S: {- $sourcedir -}/asm/sha512-%.pl - CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@ -ENDRAW[Makefile(unix)] +GENERATE[keccak1600-s390x.S]=asm/keccak1600-s390x.pl + +GENERATE[sha1-c64xplus.S]=asm/sha1-c64xplus.pl +GENERATE[sha256-c64xplus.S]=asm/sha256-c64xplus.pl +GENERATE[sha512-c64xplus.S]=asm/sha512-c64xplus.pl +GENERATE[keccak1600-c64x.S]=asm/keccak1600-c64x.pl + +# These are not yet used +GENERATE[keccak1600-avx2.S]=asm/keccak1600-avx2.pl +GENERATE[keccak1600-avx512.S]=asm/keccak1600-avx512.pl +GENERATE[keccak1600-avx512vl.S]=asm/keccak1600-avx512vl.pl +GENERATE[keccak1600-mmx.S]=asm/keccak1600-mmx.pl +GENERATE[keccak1600p8-ppc.S]=asm/keccak1600p8-ppc.pl +GENERATE[sha1-thumb.S]=asm/sha1-thumb.pl diff --git a/crypto/openssl/crypto/sha/keccak1600-armv8.S b/crypto/openssl/crypto/sha/keccak1600-armv8.S new file mode 100644 index 000000000000..3a3385e28580 --- /dev/null +++ b/crypto/openssl/crypto/sha/keccak1600-armv8.S @@ -0,0 +1,1009 @@ +.text + +.align 8 // strategic alignment and padding that allows to use + // address value as loop termination condition... +.quad 0,0,0,0,0,0,0,0 +.type iotas,%object +iotas: +.quad 0x0000000000000001 +.quad 0x0000000000008082 +.quad 0x800000000000808a +.quad 0x8000000080008000 +.quad 0x000000000000808b +.quad 0x0000000080000001 +.quad 0x8000000080008081 +.quad 0x8000000000008009 +.quad 0x000000000000008a +.quad 0x0000000000000088 +.quad 0x0000000080008009 +.quad 0x000000008000000a +.quad 0x000000008000808b +.quad 0x800000000000008b +.quad 0x8000000000008089 +.quad 0x8000000000008003 +.quad 0x8000000000008002 +.quad 0x8000000000000080 +.quad 0x000000000000800a +.quad 0x800000008000000a +.quad 0x8000000080008081 +.quad 0x8000000000008080 +.quad 0x0000000080000001 +.quad 0x8000000080008008 +.size iotas,.-iotas +.type KeccakF1600_int,%function +.align 5 +KeccakF1600_int: + adr x28,iotas +.inst 0xd503233f // paciasp + stp x28,x30,[sp,#16] // 32 bytes on top are mine + b .Loop +.align 4 +.Loop: + ////////////////////////////////////////// Theta + eor x26,x0,x5 + stp x4,x9,[sp,#0] // offload pair... + eor x27,x1,x6 + eor x28,x2,x7 + eor x30,x3,x8 + eor x4,x4,x9 + eor x26,x26,x10 + eor x27,x27,x11 + eor x28,x28,x12 + eor x30,x30,x13 + eor x4,x4,x14 + eor x26,x26,x15 + eor x27,x27,x16 + eor x28,x28,x17 + eor x30,x30,x25 + eor x4,x4,x19 + eor x26,x26,x20 + eor x28,x28,x22 + eor x27,x27,x21 + eor x30,x30,x23 + eor x4,x4,x24 + + eor x9,x26,x28,ror#63 + + eor x1,x1,x9 + eor x6,x6,x9 + eor x11,x11,x9 + eor x16,x16,x9 + eor x21,x21,x9 + + eor x9,x27,x30,ror#63 + eor x28,x28,x4,ror#63 + eor x30,x30,x26,ror#63 + eor x4,x4,x27,ror#63 + + eor x27, x2,x9 // mov x27,x2 + eor x7,x7,x9 + eor x12,x12,x9 + eor x17,x17,x9 + eor x22,x22,x9 + + eor x0,x0,x4 + eor x5,x5,x4 + eor x10,x10,x4 + eor x15,x15,x4 + eor x20,x20,x4 + ldp x4,x9,[sp,#0] // re-load offloaded data + eor x26, x3,x28 // mov x26,x3 + eor x8,x8,x28 + eor x13,x13,x28 + eor x25,x25,x28 + eor x23,x23,x28 + + eor x28, x4,x30 // mov x28,x4 + eor x9,x9,x30 + eor x14,x14,x30 + eor x19,x19,x30 + eor x24,x24,x30 + + ////////////////////////////////////////// Rho+Pi + mov x30,x1 + ror x1,x6,#64-44 + //mov x27,x2 + ror x2,x12,#64-43 + //mov x26,x3 + ror x3,x25,#64-21 + //mov x28,x4 + ror x4,x24,#64-14 + + ror x6,x9,#64-20 + ror x12,x13,#64-25 + ror x25,x17,#64-15 + ror x24,x21,#64-2 + + ror x9,x22,#64-61 + ror x13,x19,#64-8 + ror x17,x11,#64-10 + ror x21,x8,#64-55 + + ror x22,x14,#64-39 + ror x19,x23,#64-56 + ror x11,x7,#64-6 + ror x8,x16,#64-45 + + ror x14,x20,#64-18 + ror x23,x15,#64-41 + ror x7,x10,#64-3 + ror x16,x5,#64-36 + + ror x5,x26,#64-28 + ror x10,x30,#64-1 + ror x15,x28,#64-27 + ror x20,x27,#64-62 + + ////////////////////////////////////////// Chi+Iota + bic x26,x2,x1 + bic x27,x3,x2 + bic x28,x0,x4 + bic x30,x1,x0 + eor x0,x0,x26 + bic x26,x4,x3 + eor x1,x1,x27 + ldr x27,[sp,#16] + eor x3,x3,x28 + eor x4,x4,x30 + eor x2,x2,x26 + ldr x30,[x27],#8 // Iota[i++] + + bic x26,x7,x6 + tst x27,#255 // are we done? + str x27,[sp,#16] + bic x27,x8,x7 + bic x28,x5,x9 + eor x0,x0,x30 // A[0][0] ^= Iota + bic x30,x6,x5 + eor x5,x5,x26 + bic x26,x9,x8 + eor x6,x6,x27 + eor x8,x8,x28 + eor x9,x9,x30 + eor x7,x7,x26 + + bic x26,x12,x11 + bic x27,x13,x12 + bic x28,x10,x14 + bic x30,x11,x10 + eor x10,x10,x26 + bic x26,x14,x13 + eor x11,x11,x27 + eor x13,x13,x28 + eor x14,x14,x30 + eor x12,x12,x26 + + bic x26,x17,x16 + bic x27,x25,x17 + bic x28,x15,x19 + bic x30,x16,x15 + eor x15,x15,x26 + bic x26,x19,x25 + eor x16,x16,x27 + eor x25,x25,x28 + eor x19,x19,x30 + eor x17,x17,x26 + + bic x26,x22,x21 + bic x27,x23,x22 + bic x28,x20,x24 + bic x30,x21,x20 + eor x20,x20,x26 + bic x26,x24,x23 + eor x21,x21,x27 + eor x23,x23,x28 + eor x24,x24,x30 + eor x22,x22,x26 + + bne .Loop + + ldr x30,[sp,#24] +.inst 0xd50323bf // autiasp + ret +.size KeccakF1600_int,.-KeccakF1600_int + +.type KeccakF1600,%function +.align 5 +KeccakF1600: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#48 + + str x0,[sp,#32] // offload argument + mov x26,x0 + ldp x0,x1,[x0,#16*0] + ldp x2,x3,[x26,#16*1] + ldp x4,x5,[x26,#16*2] + ldp x6,x7,[x26,#16*3] + ldp x8,x9,[x26,#16*4] + ldp x10,x11,[x26,#16*5] + ldp x12,x13,[x26,#16*6] + ldp x14,x15,[x26,#16*7] + ldp x16,x17,[x26,#16*8] + ldp x25,x19,[x26,#16*9] + ldp x20,x21,[x26,#16*10] + ldp x22,x23,[x26,#16*11] + ldr x24,[x26,#16*12] + + bl KeccakF1600_int + + ldr x26,[sp,#32] + stp x0,x1,[x26,#16*0] + stp x2,x3,[x26,#16*1] + stp x4,x5,[x26,#16*2] + stp x6,x7,[x26,#16*3] + stp x8,x9,[x26,#16*4] + stp x10,x11,[x26,#16*5] + stp x12,x13,[x26,#16*6] + stp x14,x15,[x26,#16*7] + stp x16,x17,[x26,#16*8] + stp x25,x19,[x26,#16*9] + stp x20,x21,[x26,#16*10] + stp x22,x23,[x26,#16*11] + str x24,[x26,#16*12] + + ldp x19,x20,[x29,#16] + add sp,sp,#48 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size KeccakF1600,.-KeccakF1600 + +.globl SHA3_absorb +.type SHA3_absorb,%function +.align 5 +SHA3_absorb: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#64 + + stp x0,x1,[sp,#32] // offload arguments + stp x2,x3,[sp,#48] + + mov x26,x0 // uint64_t A[5][5] + mov x27,x1 // const void *inp + mov x28,x2 // size_t len + mov x30,x3 // size_t bsz + ldp x0,x1,[x26,#16*0] + ldp x2,x3,[x26,#16*1] + ldp x4,x5,[x26,#16*2] + ldp x6,x7,[x26,#16*3] + ldp x8,x9,[x26,#16*4] + ldp x10,x11,[x26,#16*5] + ldp x12,x13,[x26,#16*6] + ldp x14,x15,[x26,#16*7] + ldp x16,x17,[x26,#16*8] + ldp x25,x19,[x26,#16*9] + ldp x20,x21,[x26,#16*10] + ldp x22,x23,[x26,#16*11] + ldr x24,[x26,#16*12] + b .Loop_absorb + +.align 4 +.Loop_absorb: + subs x26,x28,x30 // len - bsz + blo .Labsorbed + + str x26,[sp,#48] // save len - bsz + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x0,x0,x26 + cmp x30,#8*(0+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x1,x1,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x2,x2,x26 + cmp x30,#8*(2+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x3,x3,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x4,x4,x26 + cmp x30,#8*(4+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x5,x5,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x6,x6,x26 + cmp x30,#8*(6+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x7,x7,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x8,x8,x26 + cmp x30,#8*(8+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x9,x9,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x10,x10,x26 + cmp x30,#8*(10+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x11,x11,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x12,x12,x26 + cmp x30,#8*(12+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x13,x13,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x14,x14,x26 + cmp x30,#8*(14+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x15,x15,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x16,x16,x26 + cmp x30,#8*(16+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x17,x17,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x25,x25,x26 + cmp x30,#8*(18+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x19,x19,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x20,x20,x26 + cmp x30,#8*(20+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x21,x21,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x22,x22,x26 + cmp x30,#8*(22+2) + blo .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x23,x23,x26 + beq .Lprocess_block + ldr x26,[x27],#8 // *inp++ +#ifdef __AARCH64EB__ + rev x26,x26 +#endif + eor x24,x24,x26 + +.Lprocess_block: + str x27,[sp,#40] // save inp + + bl KeccakF1600_int + + ldr x27,[sp,#40] // restore arguments + ldp x28,x30,[sp,#48] + b .Loop_absorb + +.align 4 +.Labsorbed: + ldr x27,[sp,#32] + stp x0,x1,[x27,#16*0] + stp x2,x3,[x27,#16*1] + stp x4,x5,[x27,#16*2] + stp x6,x7,[x27,#16*3] + stp x8,x9,[x27,#16*4] + stp x10,x11,[x27,#16*5] + stp x12,x13,[x27,#16*6] + stp x14,x15,[x27,#16*7] + stp x16,x17,[x27,#16*8] + stp x25,x19,[x27,#16*9] + stp x20,x21,[x27,#16*10] + stp x22,x23,[x27,#16*11] + str x24,[x27,#16*12] + + mov x0,x28 // return value + ldp x19,x20,[x29,#16] + add sp,sp,#64 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size SHA3_absorb,.-SHA3_absorb +.globl SHA3_squeeze +.type SHA3_squeeze,%function +.align 5 +SHA3_squeeze: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-48]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + + mov x19,x0 // put aside arguments + mov x20,x1 + mov x21,x2 + mov x22,x3 + +.Loop_squeeze: + ldr x4,[x0],#8 + cmp x21,#8 + blo .Lsqueeze_tail +#ifdef __AARCH64EB__ + rev x4,x4 +#endif + str x4,[x20],#8 + subs x21,x21,#8 + beq .Lsqueeze_done + + subs x3,x3,#8 + bhi .Loop_squeeze + + mov x0,x19 + bl KeccakF1600 + mov x0,x19 + mov x3,x22 + b .Loop_squeeze + +.align 4 +.Lsqueeze_tail: + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + lsr x4,x4,#8 + subs x21,x21,#1 + beq .Lsqueeze_done + strb w4,[x20],#1 + +.Lsqueeze_done: + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x29,x30,[sp],#48 +.inst 0xd50323bf // autiasp + ret +.size SHA3_squeeze,.-SHA3_squeeze +.type KeccakF1600_ce,%function +.align 5 +KeccakF1600_ce: + mov x9,#24 + adr x10,iotas + b .Loop_ce +.align 4 +.Loop_ce: + ////////////////////////////////////////////////// Theta +.inst 0xce0f2a99 //eor3 v25.16b,v20.16b,v15.16b,v10.16b +.inst 0xce102eba //eor3 v26.16b,v21.16b,v16.16b,v11.16b +.inst 0xce1132db //eor3 v27.16b,v22.16b,v17.16b,v12.16b +.inst 0xce1236fc //eor3 v28.16b,v23.16b,v18.16b,v13.16b +.inst 0xce133b1d //eor3 v29.16b,v24.16b,v19.16b,v14.16b +.inst 0xce050339 //eor3 v25.16b,v25.16b, v5.16b,v0.16b +.inst 0xce06075a //eor3 v26.16b,v26.16b, v6.16b,v1.16b +.inst 0xce070b7b //eor3 v27.16b,v27.16b, v7.16b,v2.16b +.inst 0xce080f9c //eor3 v28.16b,v28.16b, v8.16b,v3.16b +.inst 0xce0913bd //eor3 v29.16b,v29.16b, v9.16b,v4.16b + +.inst 0xce7b8f3e //rax1 v30.16b,v25.16b,v27.16b // D[1] +.inst 0xce7c8f5f //rax1 v31.16b,v26.16b,v28.16b // D[2] +.inst 0xce7d8f7b //rax1 v27.16b,v27.16b,v29.16b // D[3] +.inst 0xce798f9c //rax1 v28.16b,v28.16b,v25.16b // D[4] +.inst 0xce7a8fbd //rax1 v29.16b,v29.16b,v26.16b // D[0] + + ////////////////////////////////////////////////// Theta+Rho+Pi +.inst 0xce9efc39 //xar v25.16b, v1.16b,v30.16b,#64-1 // C[0]=A[2][0] + +.inst 0xce9e50c1 //xar v1.16b,v6.16b,v30.16b,#64-44 +.inst 0xce9cb126 //xar v6.16b,v9.16b,v28.16b,#64-20 +.inst 0xce9f0ec9 //xar v9.16b,v22.16b,v31.16b,#64-61 +.inst 0xce9c65d6 //xar v22.16b,v14.16b,v28.16b,#64-39 +.inst 0xce9dba8e //xar v14.16b,v20.16b,v29.16b,#64-18 + +.inst 0xce9f085a //xar v26.16b, v2.16b,v31.16b,#64-62 // C[1]=A[4][0] + +.inst 0xce9f5582 //xar v2.16b,v12.16b,v31.16b,#64-43 +.inst 0xce9b9dac //xar v12.16b,v13.16b,v27.16b,#64-25 +.inst 0xce9ce26d //xar v13.16b,v19.16b,v28.16b,#64-8 +.inst 0xce9b22f3 //xar v19.16b,v23.16b,v27.16b,#64-56 +.inst 0xce9d5df7 //xar v23.16b,v15.16b,v29.16b,#64-41 + +.inst 0xce9c948f //xar v15.16b,v4.16b,v28.16b,#64-27 + +.inst 0xce9ccb1c //xar v28.16b, v24.16b,v28.16b,#64-14 // D[4]=A[0][4] +.inst 0xce9efab8 //xar v24.16b,v21.16b,v30.16b,#64-2 +.inst 0xce9b2508 //xar v8.16b,v8.16b,v27.16b,#64-55 // A[1][3]=A[4][1] +.inst 0xce9e4e04 //xar v4.16b,v16.16b,v30.16b,#64-45 // A[0][4]=A[1][3] +.inst 0xce9d70b0 //xar v16.16b,v5.16b,v29.16b,#64-36 + +.inst 0xce9b9065 //xar v5.16b,v3.16b,v27.16b,#64-28 + + eor v0.16b,v0.16b,v29.16b + +.inst 0xce9bae5b //xar v27.16b, v18.16b,v27.16b,#64-21 // D[3]=A[0][3] +.inst 0xce9fc623 //xar v3.16b,v17.16b,v31.16b,#64-15 // A[0][3]=A[3][3] +.inst 0xce9ed97e //xar v30.16b, v11.16b,v30.16b,#64-10 // D[1]=A[3][2] +.inst 0xce9fe8ff //xar v31.16b, v7.16b,v31.16b,#64-6 // D[2]=A[2][1] +.inst 0xce9df55d //xar v29.16b, v10.16b,v29.16b,#64-3 // D[0]=A[1][2] + + ////////////////////////////////////////////////// Chi+Iota +.inst 0xce362354 //bcax v20.16b,v26.16b, v22.16b,v8.16b // A[1][3]=A[4][1] +.inst 0xce375915 //bcax v21.16b,v8.16b,v23.16b,v22.16b // A[1][3]=A[4][1] +.inst 0xce385ed6 //bcax v22.16b,v22.16b,v24.16b,v23.16b +.inst 0xce3a62f7 //bcax v23.16b,v23.16b,v26.16b, v24.16b +.inst 0xce286b18 //bcax v24.16b,v24.16b,v8.16b,v26.16b // A[1][3]=A[4][1] + + ld1r {v26.2d},[x10],#8 + +.inst 0xce330fd1 //bcax v17.16b,v30.16b, v19.16b,v3.16b // A[0][3]=A[3][3] +.inst 0xce2f4c72 //bcax v18.16b,v3.16b,v15.16b,v19.16b // A[0][3]=A[3][3] +.inst 0xce303e73 //bcax v19.16b,v19.16b,v16.16b,v15.16b +.inst 0xce3e41ef //bcax v15.16b,v15.16b,v30.16b, v16.16b +.inst 0xce237a10 //bcax v16.16b,v16.16b,v3.16b,v30.16b // A[0][3]=A[3][3] + +.inst 0xce2c7f2a //bcax v10.16b,v25.16b, v12.16b,v31.16b +.inst 0xce2d33eb //bcax v11.16b,v31.16b, v13.16b,v12.16b +.inst 0xce2e358c //bcax v12.16b,v12.16b,v14.16b,v13.16b +.inst 0xce3939ad //bcax v13.16b,v13.16b,v25.16b, v14.16b +.inst 0xce3f65ce //bcax v14.16b,v14.16b,v31.16b, v25.16b + +.inst 0xce2913a7 //bcax v7.16b,v29.16b, v9.16b,v4.16b // A[0][4]=A[1][3] +.inst 0xce252488 //bcax v8.16b,v4.16b,v5.16b,v9.16b // A[0][4]=A[1][3] +.inst 0xce261529 //bcax v9.16b,v9.16b,v6.16b,v5.16b +.inst 0xce3d18a5 //bcax v5.16b,v5.16b,v29.16b, v6.16b +.inst 0xce2474c6 //bcax v6.16b,v6.16b,v4.16b,v29.16b // A[0][4]=A[1][3] + +.inst 0xce207363 //bcax v3.16b,v27.16b, v0.16b,v28.16b +.inst 0xce210384 //bcax v4.16b,v28.16b, v1.16b,v0.16b +.inst 0xce220400 //bcax v0.16b,v0.16b,v2.16b,v1.16b +.inst 0xce3b0821 //bcax v1.16b,v1.16b,v27.16b, v2.16b +.inst 0xce3c6c42 //bcax v2.16b,v2.16b,v28.16b, v27.16b + + eor v0.16b,v0.16b,v26.16b + + subs x9,x9,#1 + bne .Loop_ce + + ret +.size KeccakF1600_ce,.-KeccakF1600_ce + +.type KeccakF1600_cext,%function +.align 5 +KeccakF1600_cext: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp d8,d9,[sp,#16] // per ABI requirement + stp d10,d11,[sp,#32] + stp d12,d13,[sp,#48] + stp d14,d15,[sp,#64] + ldp d0,d1,[x0,#8*0] + ldp d2,d3,[x0,#8*2] + ldp d4,d5,[x0,#8*4] + ldp d6,d7,[x0,#8*6] + ldp d8,d9,[x0,#8*8] + ldp d10,d11,[x0,#8*10] + ldp d12,d13,[x0,#8*12] + ldp d14,d15,[x0,#8*14] + ldp d16,d17,[x0,#8*16] + ldp d18,d19,[x0,#8*18] + ldp d20,d21,[x0,#8*20] + ldp d22,d23,[x0,#8*22] + ldr d24,[x0,#8*24] + bl KeccakF1600_ce + ldr x30,[sp,#8] + stp d0,d1,[x0,#8*0] + stp d2,d3,[x0,#8*2] + stp d4,d5,[x0,#8*4] + stp d6,d7,[x0,#8*6] + stp d8,d9,[x0,#8*8] + stp d10,d11,[x0,#8*10] + stp d12,d13,[x0,#8*12] + stp d14,d15,[x0,#8*14] + stp d16,d17,[x0,#8*16] + stp d18,d19,[x0,#8*18] + stp d20,d21,[x0,#8*20] + stp d22,d23,[x0,#8*22] + str d24,[x0,#8*24] + + ldp d8,d9,[sp,#16] + ldp d10,d11,[sp,#32] + ldp d12,d13,[sp,#48] + ldp d14,d15,[sp,#64] + ldr x29,[sp],#80 +.inst 0xd50323bf // autiasp + ret +.size KeccakF1600_cext,.-KeccakF1600_cext +.globl SHA3_absorb_cext +.type SHA3_absorb_cext,%function +.align 5 +SHA3_absorb_cext: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp d8,d9,[sp,#16] // per ABI requirement + stp d10,d11,[sp,#32] + stp d12,d13,[sp,#48] + stp d14,d15,[sp,#64] + ldp d0,d1,[x0,#8*0] + ldp d2,d3,[x0,#8*2] + ldp d4,d5,[x0,#8*4] + ldp d6,d7,[x0,#8*6] + ldp d8,d9,[x0,#8*8] + ldp d10,d11,[x0,#8*10] + ldp d12,d13,[x0,#8*12] + ldp d14,d15,[x0,#8*14] + ldp d16,d17,[x0,#8*16] + ldp d18,d19,[x0,#8*18] + ldp d20,d21,[x0,#8*20] + ldp d22,d23,[x0,#8*22] + ldr d24,[x0,#8*24] + b .Loop_absorb_ce + +.align 4 +.Loop_absorb_ce: + subs x2,x2,x3 // len - bsz + blo .Labsorbed_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v0.16b,v0.16b,v31.16b + cmp x3,#8*(0+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v1.16b,v1.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v2.16b,v2.16b,v31.16b + cmp x3,#8*(2+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v3.16b,v3.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v4.16b,v4.16b,v31.16b + cmp x3,#8*(4+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v5.16b,v5.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v6.16b,v6.16b,v31.16b + cmp x3,#8*(6+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v7.16b,v7.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v8.16b,v8.16b,v31.16b + cmp x3,#8*(8+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v9.16b,v9.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v10.16b,v10.16b,v31.16b + cmp x3,#8*(10+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v11.16b,v11.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v12.16b,v12.16b,v31.16b + cmp x3,#8*(12+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v13.16b,v13.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v14.16b,v14.16b,v31.16b + cmp x3,#8*(14+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v15.16b,v15.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v16.16b,v16.16b,v31.16b + cmp x3,#8*(16+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v17.16b,v17.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v18.16b,v18.16b,v31.16b + cmp x3,#8*(18+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v19.16b,v19.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v20.16b,v20.16b,v31.16b + cmp x3,#8*(20+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v21.16b,v21.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v22.16b,v22.16b,v31.16b + cmp x3,#8*(22+2) + blo .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v23.16b,v23.16b,v31.16b + beq .Lprocess_block_ce + ldr d31,[x1],#8 // *inp++ +#ifdef __AARCH64EB__ + rev64 v31.16b,v31.16b +#endif + eor v24.16b,v24.16b,v31.16b + +.Lprocess_block_ce: + + bl KeccakF1600_ce + + b .Loop_absorb_ce + +.align 4 +.Labsorbed_ce: + stp d0,d1,[x0,#8*0] + stp d2,d3,[x0,#8*2] + stp d4,d5,[x0,#8*4] + stp d6,d7,[x0,#8*6] + stp d8,d9,[x0,#8*8] + stp d10,d11,[x0,#8*10] + stp d12,d13,[x0,#8*12] + stp d14,d15,[x0,#8*14] + stp d16,d17,[x0,#8*16] + stp d18,d19,[x0,#8*18] + stp d20,d21,[x0,#8*20] + stp d22,d23,[x0,#8*22] + str d24,[x0,#8*24] + add x0,x2,x3 // return value + + ldp d8,d9,[sp,#16] + ldp d10,d11,[sp,#32] + ldp d12,d13,[sp,#48] + ldp d14,d15,[sp,#64] + ldp x29,x30,[sp],#80 +.inst 0xd50323bf // autiasp + ret +.size SHA3_absorb_cext,.-SHA3_absorb_cext +.globl SHA3_squeeze_cext +.type SHA3_squeeze_cext,%function +.align 5 +SHA3_squeeze_cext: +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + mov x9,x0 + mov x10,x3 + +.Loop_squeeze_ce: + ldr x4,[x9],#8 + cmp x2,#8 + blo .Lsqueeze_tail_ce +#ifdef __AARCH64EB__ + rev x4,x4 +#endif + str x4,[x1],#8 + beq .Lsqueeze_done_ce + + sub x2,x2,#8 + subs x10,x10,#8 + bhi .Loop_squeeze_ce + + bl KeccakF1600_cext + ldr x30,[sp,#8] + mov x9,x0 + mov x10,x3 + b .Loop_squeeze_ce + +.align 4 +.Lsqueeze_tail_ce: + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + lsr x4,x4,#8 + subs x2,x2,#1 + beq .Lsqueeze_done_ce + strb w4,[x1],#1 + +.Lsqueeze_done_ce: + ldr x29,[sp],#16 +.inst 0xd50323bf // autiasp + ret +.size SHA3_squeeze_cext,.-SHA3_squeeze_cext +.byte 75,101,99,99,97,107,45,49,54,48,48,32,97,98,115,111,114,98,32,97,110,100,32,115,113,117,101,101,122,101,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 diff --git a/crypto/openssl/crypto/sha/keccak1600-x86_64.S b/crypto/openssl/crypto/sha/keccak1600-x86_64.S new file mode 100644 index 000000000000..bb5222b73bc0 --- /dev/null +++ b/crypto/openssl/crypto/sha/keccak1600-x86_64.S @@ -0,0 +1,545 @@ +.text + +.type __KeccakF1600,@function +.align 32 +__KeccakF1600: +.cfi_startproc + movq 60(%rdi),%rax + movq 68(%rdi),%rbx + movq 76(%rdi),%rcx + movq 84(%rdi),%rdx + movq 92(%rdi),%rbp + jmp .Loop + +.align 32 +.Loop: + movq -100(%rdi),%r8 + movq -52(%rdi),%r9 + movq -4(%rdi),%r10 + movq 44(%rdi),%r11 + + xorq -84(%rdi),%rcx + xorq -76(%rdi),%rdx + xorq %r8,%rax + xorq -92(%rdi),%rbx + xorq -44(%rdi),%rcx + xorq -60(%rdi),%rax + movq %rbp,%r12 + xorq -68(%rdi),%rbp + + xorq %r10,%rcx + xorq -20(%rdi),%rax + xorq -36(%rdi),%rdx + xorq %r9,%rbx + xorq -28(%rdi),%rbp + + xorq 36(%rdi),%rcx + xorq 20(%rdi),%rax + xorq 4(%rdi),%rdx + xorq -12(%rdi),%rbx + xorq 12(%rdi),%rbp + + movq %rcx,%r13 + rolq $1,%rcx + xorq %rax,%rcx + xorq %r11,%rdx + + rolq $1,%rax + xorq %rdx,%rax + xorq 28(%rdi),%rbx + + rolq $1,%rdx + xorq %rbx,%rdx + xorq 52(%rdi),%rbp + + rolq $1,%rbx + xorq %rbp,%rbx + + rolq $1,%rbp + xorq %r13,%rbp + xorq %rcx,%r9 + xorq %rdx,%r10 + rolq $44,%r9 + xorq %rbp,%r11 + xorq %rax,%r12 + rolq $43,%r10 + xorq %rbx,%r8 + movq %r9,%r13 + rolq $21,%r11 + orq %r10,%r9 + xorq %r8,%r9 + rolq $14,%r12 + + xorq (%r15),%r9 + leaq 8(%r15),%r15 + + movq %r12,%r14 + andq %r11,%r12 + movq %r9,-100(%rsi) + xorq %r10,%r12 + notq %r10 + movq %r12,-84(%rsi) + + orq %r11,%r10 + movq 76(%rdi),%r12 + xorq %r13,%r10 + movq %r10,-92(%rsi) + + andq %r8,%r13 + movq -28(%rdi),%r9 + xorq %r14,%r13 + movq -20(%rdi),%r10 + movq %r13,-68(%rsi) + + orq %r8,%r14 + movq -76(%rdi),%r8 + xorq %r11,%r14 + movq 28(%rdi),%r11 + movq %r14,-76(%rsi) + + + xorq %rbp,%r8 + xorq %rdx,%r12 + rolq $28,%r8 + xorq %rcx,%r11 + xorq %rax,%r9 + rolq $61,%r12 + rolq $45,%r11 + xorq %rbx,%r10 + rolq $20,%r9 + movq %r8,%r13 + orq %r12,%r8 + rolq $3,%r10 + + xorq %r11,%r8 + movq %r8,-36(%rsi) + + movq %r9,%r14 + andq %r13,%r9 + movq -92(%rdi),%r8 + xorq %r12,%r9 + notq %r12 + movq %r9,-28(%rsi) + + orq %r11,%r12 + movq -44(%rdi),%r9 + xorq %r10,%r12 + movq %r12,-44(%rsi) + + andq %r10,%r11 + movq 60(%rdi),%r12 + xorq %r14,%r11 + movq %r11,-52(%rsi) + + orq %r10,%r14 + movq 4(%rdi),%r10 + xorq %r13,%r14 + movq 52(%rdi),%r11 + movq %r14,-60(%rsi) + + + xorq %rbp,%r10 + xorq %rax,%r11 + rolq $25,%r10 + xorq %rdx,%r9 + rolq $8,%r11 + xorq %rbx,%r12 + rolq $6,%r9 + xorq %rcx,%r8 + rolq $18,%r12 + movq %r10,%r13 + andq %r11,%r10 + rolq $1,%r8 + + notq %r11 + xorq %r9,%r10 + movq %r10,-12(%rsi) + + movq %r12,%r14 + andq %r11,%r12 + movq -12(%rdi),%r10 + xorq %r13,%r12 + movq %r12,-4(%rsi) + + orq %r9,%r13 + movq 84(%rdi),%r12 + xorq %r8,%r13 + movq %r13,-20(%rsi) + + andq %r8,%r9 + xorq %r14,%r9 + movq %r9,12(%rsi) + + orq %r8,%r14 + movq -60(%rdi),%r9 + xorq %r11,%r14 + movq 36(%rdi),%r11 + movq %r14,4(%rsi) + + + movq -68(%rdi),%r8 + + xorq %rcx,%r10 + xorq %rdx,%r11 + rolq $10,%r10 + xorq %rbx,%r9 + rolq $15,%r11 + xorq %rbp,%r12 + rolq $36,%r9 + xorq %rax,%r8 + rolq $56,%r12 + movq %r10,%r13 + orq %r11,%r10 + rolq $27,%r8 + + notq %r11 + xorq %r9,%r10 + movq %r10,28(%rsi) + + movq %r12,%r14 + orq %r11,%r12 + xorq %r13,%r12 + movq %r12,36(%rsi) + + andq %r9,%r13 + xorq %r8,%r13 + movq %r13,20(%rsi) + + orq %r8,%r9 + xorq %r14,%r9 + movq %r9,52(%rsi) + + andq %r14,%r8 + xorq %r11,%r8 + movq %r8,44(%rsi) + + + xorq -84(%rdi),%rdx + xorq -36(%rdi),%rbp + rolq $62,%rdx + xorq 68(%rdi),%rcx + rolq $55,%rbp + xorq 12(%rdi),%rax + rolq $2,%rcx + xorq 20(%rdi),%rbx + xchgq %rsi,%rdi + rolq $39,%rax + rolq $41,%rbx + movq %rdx,%r13 + andq %rbp,%rdx + notq %rbp + xorq %rcx,%rdx + movq %rdx,92(%rdi) + + movq %rax,%r14 + andq %rbp,%rax + xorq %r13,%rax + movq %rax,60(%rdi) + + orq %rcx,%r13 + xorq %rbx,%r13 + movq %r13,84(%rdi) + + andq %rbx,%rcx + xorq %r14,%rcx + movq %rcx,76(%rdi) + + orq %r14,%rbx + xorq %rbp,%rbx + movq %rbx,68(%rdi) + + movq %rdx,%rbp + movq %r13,%rdx + + testq $255,%r15 + jnz .Loop + + leaq -192(%r15),%r15 + .byte 0xf3,0xc3 +.cfi_endproc +.size __KeccakF1600,.-__KeccakF1600 + +.type KeccakF1600,@function +.align 32 +KeccakF1600: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + + leaq 100(%rdi),%rdi + subq $200,%rsp +.cfi_adjust_cfa_offset 200 + + notq -92(%rdi) + notq -84(%rdi) + notq -36(%rdi) + notq -4(%rdi) + notq 36(%rdi) + notq 60(%rdi) + + leaq iotas(%rip),%r15 + leaq 100(%rsp),%rsi + + call __KeccakF1600 + + notq -92(%rdi) + notq -84(%rdi) + notq -36(%rdi) + notq -4(%rdi) + notq 36(%rdi) + notq 60(%rdi) + leaq -100(%rdi),%rdi + + addq $200,%rsp +.cfi_adjust_cfa_offset -200 + + popq %r15 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r15 + popq %r14 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r14 + popq %r13 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r13 + popq %r12 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r12 + popq %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbp + popq %rbx +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbx + .byte 0xf3,0xc3 +.cfi_endproc +.size KeccakF1600,.-KeccakF1600 +.globl SHA3_absorb +.type SHA3_absorb,@function +.align 32 +SHA3_absorb: +.cfi_startproc + pushq %rbx +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r15,-56 + + leaq 100(%rdi),%rdi + subq $232,%rsp +.cfi_adjust_cfa_offset 232 + + movq %rsi,%r9 + leaq 100(%rsp),%rsi + + notq -92(%rdi) + notq -84(%rdi) + notq -36(%rdi) + notq -4(%rdi) + notq 36(%rdi) + notq 60(%rdi) + leaq iotas(%rip),%r15 + + movq %rcx,216-100(%rsi) + +.Loop_absorb: + cmpq %rcx,%rdx + jc .Ldone_absorb + + shrq $3,%rcx + leaq -100(%rdi),%r8 + +.Lblock_absorb: + movq (%r9),%rax + leaq 8(%r9),%r9 + xorq (%r8),%rax + leaq 8(%r8),%r8 + subq $8,%rdx + movq %rax,-8(%r8) + subq $1,%rcx + jnz .Lblock_absorb + + movq %r9,200-100(%rsi) + movq %rdx,208-100(%rsi) + call __KeccakF1600 + movq 200-100(%rsi),%r9 + movq 208-100(%rsi),%rdx + movq 216-100(%rsi),%rcx + jmp .Loop_absorb + +.align 32 +.Ldone_absorb: + movq %rdx,%rax + + notq -92(%rdi) + notq -84(%rdi) + notq -36(%rdi) + notq -4(%rdi) + notq 36(%rdi) + notq 60(%rdi) + + addq $232,%rsp +.cfi_adjust_cfa_offset -232 + + popq %r15 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r15 + popq %r14 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r14 + popq %r13 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r13 + popq %r12 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r12 + popq %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbp + popq %rbx +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbx + .byte 0xf3,0xc3 +.cfi_endproc +.size SHA3_absorb,.-SHA3_absorb +.globl SHA3_squeeze +.type SHA3_squeeze,@function +.align 32 +SHA3_squeeze: +.cfi_startproc + pushq %r12 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r12,-16 + pushq %r13 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r13,-24 + pushq %r14 +.cfi_adjust_cfa_offset 8 +.cfi_offset %r14,-32 + + shrq $3,%rcx + movq %rdi,%r8 + movq %rsi,%r12 + movq %rdx,%r13 + movq %rcx,%r14 + jmp .Loop_squeeze + +.align 32 +.Loop_squeeze: + cmpq $8,%r13 + jb .Ltail_squeeze + + movq (%r8),%rax + leaq 8(%r8),%r8 + movq %rax,(%r12) + leaq 8(%r12),%r12 + subq $8,%r13 + jz .Ldone_squeeze + + subq $1,%rcx + jnz .Loop_squeeze + + call KeccakF1600 + movq %rdi,%r8 + movq %r14,%rcx + jmp .Loop_squeeze + +.Ltail_squeeze: + movq %r8,%rsi + movq %r12,%rdi + movq %r13,%rcx +.byte 0xf3,0xa4 + +.Ldone_squeeze: + popq %r14 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r14 + popq %r13 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r13 + popq %r12 +.cfi_adjust_cfa_offset -8 +.cfi_restore %r13 + .byte 0xf3,0xc3 +.cfi_endproc +.size SHA3_squeeze,.-SHA3_squeeze +.align 256 +.quad 0,0,0,0,0,0,0,0 +.type iotas,@object +iotas: +.quad 0x0000000000000001 +.quad 0x0000000000008082 +.quad 0x800000000000808a +.quad 0x8000000080008000 +.quad 0x000000000000808b +.quad 0x0000000080000001 +.quad 0x8000000080008081 +.quad 0x8000000000008009 +.quad 0x000000000000008a +.quad 0x0000000000000088 +.quad 0x0000000080008009 +.quad 0x000000008000000a +.quad 0x000000008000808b +.quad 0x800000000000008b +.quad 0x8000000000008089 +.quad 0x8000000000008003 +.quad 0x8000000000008002 +.quad 0x8000000000000080 +.quad 0x000000000000800a +.quad 0x800000008000000a +.quad 0x8000000080008081 +.quad 0x8000000000008080 +.quad 0x0000000080000001 +.quad 0x8000000080008008 +.size iotas,.-iotas +.byte 75,101,99,99,97,107,45,49,54,48,48,32,97,98,115,111,114,98,32,97,110,100,32,115,113,117,101,101,122,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/sha/keccak1600.c b/crypto/openssl/crypto/sha/keccak1600.c index 55a44023d51a..ccbf12b1c60d 100644 --- a/crypto/openssl/crypto/sha/keccak1600.c +++ b/crypto/openssl/crypto/sha/keccak1600.c @@ -1,7 +1,7 @@ /* - * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -25,7 +25,14 @@ void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r); # define KECCAK_2X /* default to KECCAK_2X variant */ #endif -#if defined(__i386) || defined(__i386__) || defined(_M_IX86) +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + (defined(__x86_64) && !defined(__BMI__)) || defined(_M_X64) || \ + defined(__mips) || defined(__riscv) || defined(__s390__) || \ + defined(__EMSCRIPTEN__) +/* + * These don't have "and with complement" instruction, so minimize amount + * of "not"-s. Implemented only in the [default] KECCAK_2X variant. + */ # define KECCAK_COMPLEMENTING_TRANSFORM #endif @@ -1083,7 +1090,7 @@ size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len, } /* - * SHA3_squeeze is called once at the end to generate |out| hash value + * sha3_squeeze is called once at the end to generate |out| hash value * of |len| bytes. */ void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r) diff --git a/crypto/openssl/crypto/sha/sha1-586.S b/crypto/openssl/crypto/sha/sha1-586.S new file mode 100644 index 000000000000..4b60a71ee833 --- /dev/null +++ b/crypto/openssl/crypto/sha/sha1-586.S @@ -0,0 +1,4006 @@ +.text +.globl sha1_block_data_order +.type sha1_block_data_order,@function +.align 16 +sha1_block_data_order: +.L_sha1_block_data_order_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + call .L000pic_point +.L000pic_point: + popl %ebp + leal OPENSSL_ia32cap_P-.L000pic_point(%ebp),%esi + leal .LK_XX_XX-.L000pic_point(%ebp),%ebp + movl (%esi),%eax + movl 4(%esi),%edx + testl $512,%edx + jz .L001x86 + movl 8(%esi),%ecx + testl $16777216,%eax + jz .L001x86 + testl $536870912,%ecx + jnz .Lshaext_shortcut + andl $268435456,%edx + andl $1073741824,%eax + orl %edx,%eax + cmpl $1342177280,%eax + je .Lavx_shortcut + jmp .Lssse3_shortcut +.align 16 +.L001x86: + movl 20(%esp),%ebp + movl 24(%esp),%esi + movl 28(%esp),%eax + subl $76,%esp + shll $6,%eax + addl %esi,%eax + movl %eax,104(%esp) + movl 16(%ebp),%edi + jmp .L002loop +.align 16 +.L002loop: + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,(%esp) + movl %ebx,4(%esp) + movl %ecx,8(%esp) + movl %edx,12(%esp) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,16(%esp) + movl %ebx,20(%esp) + movl %ecx,24(%esp) + movl %edx,28(%esp) + movl 32(%esi),%eax + movl 36(%esi),%ebx + movl 40(%esi),%ecx + movl 44(%esi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,32(%esp) + movl %ebx,36(%esp) + movl %ecx,40(%esp) + movl %edx,44(%esp) + movl 48(%esi),%eax + movl 52(%esi),%ebx + movl 56(%esi),%ecx + movl 60(%esi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + movl %eax,48(%esp) + movl %ebx,52(%esp) + movl %ecx,56(%esp) + movl %edx,60(%esp) + movl %esi,100(%esp) + movl (%ebp),%eax + movl 4(%ebp),%ebx + movl 8(%ebp),%ecx + movl 12(%ebp),%edx + + movl %ecx,%esi + movl %eax,%ebp + roll $5,%ebp + xorl %edx,%esi + addl %edi,%ebp + movl (%esp),%edi + andl %ebx,%esi + rorl $2,%ebx + xorl %edx,%esi + leal 1518500249(%ebp,%edi,1),%ebp + addl %esi,%ebp + + movl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ecx,%edi + addl %edx,%ebp + movl 4(%esp),%edx + andl %eax,%edi + rorl $2,%eax + xorl %ecx,%edi + leal 1518500249(%ebp,%edx,1),%ebp + addl %edi,%ebp + + movl %eax,%edx + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%edx + addl %ecx,%ebp + movl 8(%esp),%ecx + andl %esi,%edx + rorl $2,%esi + xorl %ebx,%edx + leal 1518500249(%ebp,%ecx,1),%ebp + addl %edx,%ebp + + movl %esi,%ecx + movl %ebp,%edx + roll $5,%ebp + xorl %eax,%ecx + addl %ebx,%ebp + movl 12(%esp),%ebx + andl %edi,%ecx + rorl $2,%edi + xorl %eax,%ecx + leal 1518500249(%ebp,%ebx,1),%ebp + addl %ecx,%ebp + + movl %edi,%ebx + movl %ebp,%ecx + roll $5,%ebp + xorl %esi,%ebx + addl %eax,%ebp + movl 16(%esp),%eax + andl %edx,%ebx + rorl $2,%edx + xorl %esi,%ebx + leal 1518500249(%ebp,%eax,1),%ebp + addl %ebx,%ebp + + movl %edx,%eax + movl %ebp,%ebx + roll $5,%ebp + xorl %edi,%eax + addl %esi,%ebp + movl 20(%esp),%esi + andl %ecx,%eax + rorl $2,%ecx + xorl %edi,%eax + leal 1518500249(%ebp,%esi,1),%ebp + addl %eax,%ebp + + movl %ecx,%esi + movl %ebp,%eax + roll $5,%ebp + xorl %edx,%esi + addl %edi,%ebp + movl 24(%esp),%edi + andl %ebx,%esi + rorl $2,%ebx + xorl %edx,%esi + leal 1518500249(%ebp,%edi,1),%ebp + addl %esi,%ebp + + movl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ecx,%edi + addl %edx,%ebp + movl 28(%esp),%edx + andl %eax,%edi + rorl $2,%eax + xorl %ecx,%edi + leal 1518500249(%ebp,%edx,1),%ebp + addl %edi,%ebp + + movl %eax,%edx + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%edx + addl %ecx,%ebp + movl 32(%esp),%ecx + andl %esi,%edx + rorl $2,%esi + xorl %ebx,%edx + leal 1518500249(%ebp,%ecx,1),%ebp + addl %edx,%ebp + + movl %esi,%ecx + movl %ebp,%edx + roll $5,%ebp + xorl %eax,%ecx + addl %ebx,%ebp + movl 36(%esp),%ebx + andl %edi,%ecx + rorl $2,%edi + xorl %eax,%ecx + leal 1518500249(%ebp,%ebx,1),%ebp + addl %ecx,%ebp + + movl %edi,%ebx + movl %ebp,%ecx + roll $5,%ebp + xorl %esi,%ebx + addl %eax,%ebp + movl 40(%esp),%eax + andl %edx,%ebx + rorl $2,%edx + xorl %esi,%ebx + leal 1518500249(%ebp,%eax,1),%ebp + addl %ebx,%ebp + + movl %edx,%eax + movl %ebp,%ebx + roll $5,%ebp + xorl %edi,%eax + addl %esi,%ebp + movl 44(%esp),%esi + andl %ecx,%eax + rorl $2,%ecx + xorl %edi,%eax + leal 1518500249(%ebp,%esi,1),%ebp + addl %eax,%ebp + + movl %ecx,%esi + movl %ebp,%eax + roll $5,%ebp + xorl %edx,%esi + addl %edi,%ebp + movl 48(%esp),%edi + andl %ebx,%esi + rorl $2,%ebx + xorl %edx,%esi + leal 1518500249(%ebp,%edi,1),%ebp + addl %esi,%ebp + + movl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + xorl %ecx,%edi + addl %edx,%ebp + movl 52(%esp),%edx + andl %eax,%edi + rorl $2,%eax + xorl %ecx,%edi + leal 1518500249(%ebp,%edx,1),%ebp + addl %edi,%ebp + + movl %eax,%edx + movl %ebp,%edi + roll $5,%ebp + xorl %ebx,%edx + addl %ecx,%ebp + movl 56(%esp),%ecx + andl %esi,%edx + rorl $2,%esi + xorl %ebx,%edx + leal 1518500249(%ebp,%ecx,1),%ebp + addl %edx,%ebp + + movl %esi,%ecx + movl %ebp,%edx + roll $5,%ebp + xorl %eax,%ecx + addl %ebx,%ebp + movl 60(%esp),%ebx + andl %edi,%ecx + rorl $2,%edi + xorl %eax,%ecx + leal 1518500249(%ebp,%ebx,1),%ebp + movl (%esp),%ebx + addl %ebp,%ecx + + movl %edi,%ebp + xorl 8(%esp),%ebx + xorl %esi,%ebp + xorl 32(%esp),%ebx + andl %edx,%ebp + xorl 52(%esp),%ebx + roll $1,%ebx + xorl %esi,%ebp + addl %ebp,%eax + movl %ecx,%ebp + rorl $2,%edx + movl %ebx,(%esp) + roll $5,%ebp + leal 1518500249(%ebx,%eax,1),%ebx + movl 4(%esp),%eax + addl %ebp,%ebx + + movl %edx,%ebp + xorl 12(%esp),%eax + xorl %edi,%ebp + xorl 36(%esp),%eax + andl %ecx,%ebp + xorl 56(%esp),%eax + roll $1,%eax + xorl %edi,%ebp + addl %ebp,%esi + movl %ebx,%ebp + rorl $2,%ecx + movl %eax,4(%esp) + roll $5,%ebp + leal 1518500249(%eax,%esi,1),%eax + movl 8(%esp),%esi + addl %ebp,%eax + + movl %ecx,%ebp + xorl 16(%esp),%esi + xorl %edx,%ebp + xorl 40(%esp),%esi + andl %ebx,%ebp + xorl 60(%esp),%esi + roll $1,%esi + xorl %edx,%ebp + addl %ebp,%edi + movl %eax,%ebp + rorl $2,%ebx + movl %esi,8(%esp) + roll $5,%ebp + leal 1518500249(%esi,%edi,1),%esi + movl 12(%esp),%edi + addl %ebp,%esi + + movl %ebx,%ebp + xorl 20(%esp),%edi + xorl %ecx,%ebp + xorl 44(%esp),%edi + andl %eax,%ebp + xorl (%esp),%edi + roll $1,%edi + xorl %ecx,%ebp + addl %ebp,%edx + movl %esi,%ebp + rorl $2,%eax + movl %edi,12(%esp) + roll $5,%ebp + leal 1518500249(%edi,%edx,1),%edi + movl 16(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 24(%esp),%edx + xorl %eax,%ebp + xorl 48(%esp),%edx + xorl %ebx,%ebp + xorl 4(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,16(%esp) + leal 1859775393(%edx,%ecx,1),%edx + movl 20(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 28(%esp),%ecx + xorl %esi,%ebp + xorl 52(%esp),%ecx + xorl %eax,%ebp + xorl 8(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,20(%esp) + leal 1859775393(%ecx,%ebx,1),%ecx + movl 24(%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 32(%esp),%ebx + xorl %edi,%ebp + xorl 56(%esp),%ebx + xorl %esi,%ebp + xorl 12(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,24(%esp) + leal 1859775393(%ebx,%eax,1),%ebx + movl 28(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 36(%esp),%eax + xorl %edx,%ebp + xorl 60(%esp),%eax + xorl %edi,%ebp + xorl 16(%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + movl %eax,28(%esp) + leal 1859775393(%eax,%esi,1),%eax + movl 32(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl 40(%esp),%esi + xorl %ecx,%ebp + xorl (%esp),%esi + xorl %edx,%ebp + xorl 20(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,32(%esp) + leal 1859775393(%esi,%edi,1),%esi + movl 36(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 44(%esp),%edi + xorl %ebx,%ebp + xorl 4(%esp),%edi + xorl %ecx,%ebp + xorl 24(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,36(%esp) + leal 1859775393(%edi,%edx,1),%edi + movl 40(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 48(%esp),%edx + xorl %eax,%ebp + xorl 8(%esp),%edx + xorl %ebx,%ebp + xorl 28(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,40(%esp) + leal 1859775393(%edx,%ecx,1),%edx + movl 44(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 52(%esp),%ecx + xorl %esi,%ebp + xorl 12(%esp),%ecx + xorl %eax,%ebp + xorl 32(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,44(%esp) + leal 1859775393(%ecx,%ebx,1),%ecx + movl 48(%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 56(%esp),%ebx + xorl %edi,%ebp + xorl 16(%esp),%ebx + xorl %esi,%ebp + xorl 36(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,48(%esp) + leal 1859775393(%ebx,%eax,1),%ebx + movl 52(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 60(%esp),%eax + xorl %edx,%ebp + xorl 20(%esp),%eax + xorl %edi,%ebp + xorl 40(%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + movl %eax,52(%esp) + leal 1859775393(%eax,%esi,1),%eax + movl 56(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl (%esp),%esi + xorl %ecx,%ebp + xorl 24(%esp),%esi + xorl %edx,%ebp + xorl 44(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,56(%esp) + leal 1859775393(%esi,%edi,1),%esi + movl 60(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 4(%esp),%edi + xorl %ebx,%ebp + xorl 28(%esp),%edi + xorl %ecx,%ebp + xorl 48(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,60(%esp) + leal 1859775393(%edi,%edx,1),%edi + movl (%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 8(%esp),%edx + xorl %eax,%ebp + xorl 32(%esp),%edx + xorl %ebx,%ebp + xorl 52(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,(%esp) + leal 1859775393(%edx,%ecx,1),%edx + movl 4(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 12(%esp),%ecx + xorl %esi,%ebp + xorl 36(%esp),%ecx + xorl %eax,%ebp + xorl 56(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,4(%esp) + leal 1859775393(%ecx,%ebx,1),%ecx + movl 8(%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 16(%esp),%ebx + xorl %edi,%ebp + xorl 40(%esp),%ebx + xorl %esi,%ebp + xorl 60(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,8(%esp) + leal 1859775393(%ebx,%eax,1),%ebx + movl 12(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 20(%esp),%eax + xorl %edx,%ebp + xorl 44(%esp),%eax + xorl %edi,%ebp + xorl (%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + movl %eax,12(%esp) + leal 1859775393(%eax,%esi,1),%eax + movl 16(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl 24(%esp),%esi + xorl %ecx,%ebp + xorl 48(%esp),%esi + xorl %edx,%ebp + xorl 4(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,16(%esp) + leal 1859775393(%esi,%edi,1),%esi + movl 20(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 28(%esp),%edi + xorl %ebx,%ebp + xorl 52(%esp),%edi + xorl %ecx,%ebp + xorl 8(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,20(%esp) + leal 1859775393(%edi,%edx,1),%edi + movl 24(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 32(%esp),%edx + xorl %eax,%ebp + xorl 56(%esp),%edx + xorl %ebx,%ebp + xorl 12(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,24(%esp) + leal 1859775393(%edx,%ecx,1),%edx + movl 28(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 36(%esp),%ecx + xorl %esi,%ebp + xorl 60(%esp),%ecx + xorl %eax,%ebp + xorl 16(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,28(%esp) + leal 1859775393(%ecx,%ebx,1),%ecx + movl 32(%esp),%ebx + addl %ebp,%ecx + + movl %edi,%ebp + xorl 40(%esp),%ebx + xorl %esi,%ebp + xorl (%esp),%ebx + andl %edx,%ebp + xorl 20(%esp),%ebx + roll $1,%ebx + addl %eax,%ebp + rorl $2,%edx + movl %ecx,%eax + roll $5,%eax + movl %ebx,32(%esp) + leal 2400959708(%ebx,%ebp,1),%ebx + movl %edi,%ebp + addl %eax,%ebx + andl %esi,%ebp + movl 36(%esp),%eax + addl %ebp,%ebx + + movl %edx,%ebp + xorl 44(%esp),%eax + xorl %edi,%ebp + xorl 4(%esp),%eax + andl %ecx,%ebp + xorl 24(%esp),%eax + roll $1,%eax + addl %esi,%ebp + rorl $2,%ecx + movl %ebx,%esi + roll $5,%esi + movl %eax,36(%esp) + leal 2400959708(%eax,%ebp,1),%eax + movl %edx,%ebp + addl %esi,%eax + andl %edi,%ebp + movl 40(%esp),%esi + addl %ebp,%eax + + movl %ecx,%ebp + xorl 48(%esp),%esi + xorl %edx,%ebp + xorl 8(%esp),%esi + andl %ebx,%ebp + xorl 28(%esp),%esi + roll $1,%esi + addl %edi,%ebp + rorl $2,%ebx + movl %eax,%edi + roll $5,%edi + movl %esi,40(%esp) + leal 2400959708(%esi,%ebp,1),%esi + movl %ecx,%ebp + addl %edi,%esi + andl %edx,%ebp + movl 44(%esp),%edi + addl %ebp,%esi + + movl %ebx,%ebp + xorl 52(%esp),%edi + xorl %ecx,%ebp + xorl 12(%esp),%edi + andl %eax,%ebp + xorl 32(%esp),%edi + roll $1,%edi + addl %edx,%ebp + rorl $2,%eax + movl %esi,%edx + roll $5,%edx + movl %edi,44(%esp) + leal 2400959708(%edi,%ebp,1),%edi + movl %ebx,%ebp + addl %edx,%edi + andl %ecx,%ebp + movl 48(%esp),%edx + addl %ebp,%edi + + movl %eax,%ebp + xorl 56(%esp),%edx + xorl %ebx,%ebp + xorl 16(%esp),%edx + andl %esi,%ebp + xorl 36(%esp),%edx + roll $1,%edx + addl %ecx,%ebp + rorl $2,%esi + movl %edi,%ecx + roll $5,%ecx + movl %edx,48(%esp) + leal 2400959708(%edx,%ebp,1),%edx + movl %eax,%ebp + addl %ecx,%edx + andl %ebx,%ebp + movl 52(%esp),%ecx + addl %ebp,%edx + + movl %esi,%ebp + xorl 60(%esp),%ecx + xorl %eax,%ebp + xorl 20(%esp),%ecx + andl %edi,%ebp + xorl 40(%esp),%ecx + roll $1,%ecx + addl %ebx,%ebp + rorl $2,%edi + movl %edx,%ebx + roll $5,%ebx + movl %ecx,52(%esp) + leal 2400959708(%ecx,%ebp,1),%ecx + movl %esi,%ebp + addl %ebx,%ecx + andl %eax,%ebp + movl 56(%esp),%ebx + addl %ebp,%ecx + + movl %edi,%ebp + xorl (%esp),%ebx + xorl %esi,%ebp + xorl 24(%esp),%ebx + andl %edx,%ebp + xorl 44(%esp),%ebx + roll $1,%ebx + addl %eax,%ebp + rorl $2,%edx + movl %ecx,%eax + roll $5,%eax + movl %ebx,56(%esp) + leal 2400959708(%ebx,%ebp,1),%ebx + movl %edi,%ebp + addl %eax,%ebx + andl %esi,%ebp + movl 60(%esp),%eax + addl %ebp,%ebx + + movl %edx,%ebp + xorl 4(%esp),%eax + xorl %edi,%ebp + xorl 28(%esp),%eax + andl %ecx,%ebp + xorl 48(%esp),%eax + roll $1,%eax + addl %esi,%ebp + rorl $2,%ecx + movl %ebx,%esi + roll $5,%esi + movl %eax,60(%esp) + leal 2400959708(%eax,%ebp,1),%eax + movl %edx,%ebp + addl %esi,%eax + andl %edi,%ebp + movl (%esp),%esi + addl %ebp,%eax + + movl %ecx,%ebp + xorl 8(%esp),%esi + xorl %edx,%ebp + xorl 32(%esp),%esi + andl %ebx,%ebp + xorl 52(%esp),%esi + roll $1,%esi + addl %edi,%ebp + rorl $2,%ebx + movl %eax,%edi + roll $5,%edi + movl %esi,(%esp) + leal 2400959708(%esi,%ebp,1),%esi + movl %ecx,%ebp + addl %edi,%esi + andl %edx,%ebp + movl 4(%esp),%edi + addl %ebp,%esi + + movl %ebx,%ebp + xorl 12(%esp),%edi + xorl %ecx,%ebp + xorl 36(%esp),%edi + andl %eax,%ebp + xorl 56(%esp),%edi + roll $1,%edi + addl %edx,%ebp + rorl $2,%eax + movl %esi,%edx + roll $5,%edx + movl %edi,4(%esp) + leal 2400959708(%edi,%ebp,1),%edi + movl %ebx,%ebp + addl %edx,%edi + andl %ecx,%ebp + movl 8(%esp),%edx + addl %ebp,%edi + + movl %eax,%ebp + xorl 16(%esp),%edx + xorl %ebx,%ebp + xorl 40(%esp),%edx + andl %esi,%ebp + xorl 60(%esp),%edx + roll $1,%edx + addl %ecx,%ebp + rorl $2,%esi + movl %edi,%ecx + roll $5,%ecx + movl %edx,8(%esp) + leal 2400959708(%edx,%ebp,1),%edx + movl %eax,%ebp + addl %ecx,%edx + andl %ebx,%ebp + movl 12(%esp),%ecx + addl %ebp,%edx + + movl %esi,%ebp + xorl 20(%esp),%ecx + xorl %eax,%ebp + xorl 44(%esp),%ecx + andl %edi,%ebp + xorl (%esp),%ecx + roll $1,%ecx + addl %ebx,%ebp + rorl $2,%edi + movl %edx,%ebx + roll $5,%ebx + movl %ecx,12(%esp) + leal 2400959708(%ecx,%ebp,1),%ecx + movl %esi,%ebp + addl %ebx,%ecx + andl %eax,%ebp + movl 16(%esp),%ebx + addl %ebp,%ecx + + movl %edi,%ebp + xorl 24(%esp),%ebx + xorl %esi,%ebp + xorl 48(%esp),%ebx + andl %edx,%ebp + xorl 4(%esp),%ebx + roll $1,%ebx + addl %eax,%ebp + rorl $2,%edx + movl %ecx,%eax + roll $5,%eax + movl %ebx,16(%esp) + leal 2400959708(%ebx,%ebp,1),%ebx + movl %edi,%ebp + addl %eax,%ebx + andl %esi,%ebp + movl 20(%esp),%eax + addl %ebp,%ebx + + movl %edx,%ebp + xorl 28(%esp),%eax + xorl %edi,%ebp + xorl 52(%esp),%eax + andl %ecx,%ebp + xorl 8(%esp),%eax + roll $1,%eax + addl %esi,%ebp + rorl $2,%ecx + movl %ebx,%esi + roll $5,%esi + movl %eax,20(%esp) + leal 2400959708(%eax,%ebp,1),%eax + movl %edx,%ebp + addl %esi,%eax + andl %edi,%ebp + movl 24(%esp),%esi + addl %ebp,%eax + + movl %ecx,%ebp + xorl 32(%esp),%esi + xorl %edx,%ebp + xorl 56(%esp),%esi + andl %ebx,%ebp + xorl 12(%esp),%esi + roll $1,%esi + addl %edi,%ebp + rorl $2,%ebx + movl %eax,%edi + roll $5,%edi + movl %esi,24(%esp) + leal 2400959708(%esi,%ebp,1),%esi + movl %ecx,%ebp + addl %edi,%esi + andl %edx,%ebp + movl 28(%esp),%edi + addl %ebp,%esi + + movl %ebx,%ebp + xorl 36(%esp),%edi + xorl %ecx,%ebp + xorl 60(%esp),%edi + andl %eax,%ebp + xorl 16(%esp),%edi + roll $1,%edi + addl %edx,%ebp + rorl $2,%eax + movl %esi,%edx + roll $5,%edx + movl %edi,28(%esp) + leal 2400959708(%edi,%ebp,1),%edi + movl %ebx,%ebp + addl %edx,%edi + andl %ecx,%ebp + movl 32(%esp),%edx + addl %ebp,%edi + + movl %eax,%ebp + xorl 40(%esp),%edx + xorl %ebx,%ebp + xorl (%esp),%edx + andl %esi,%ebp + xorl 20(%esp),%edx + roll $1,%edx + addl %ecx,%ebp + rorl $2,%esi + movl %edi,%ecx + roll $5,%ecx + movl %edx,32(%esp) + leal 2400959708(%edx,%ebp,1),%edx + movl %eax,%ebp + addl %ecx,%edx + andl %ebx,%ebp + movl 36(%esp),%ecx + addl %ebp,%edx + + movl %esi,%ebp + xorl 44(%esp),%ecx + xorl %eax,%ebp + xorl 4(%esp),%ecx + andl %edi,%ebp + xorl 24(%esp),%ecx + roll $1,%ecx + addl %ebx,%ebp + rorl $2,%edi + movl %edx,%ebx + roll $5,%ebx + movl %ecx,36(%esp) + leal 2400959708(%ecx,%ebp,1),%ecx + movl %esi,%ebp + addl %ebx,%ecx + andl %eax,%ebp + movl 40(%esp),%ebx + addl %ebp,%ecx + + movl %edi,%ebp + xorl 48(%esp),%ebx + xorl %esi,%ebp + xorl 8(%esp),%ebx + andl %edx,%ebp + xorl 28(%esp),%ebx + roll $1,%ebx + addl %eax,%ebp + rorl $2,%edx + movl %ecx,%eax + roll $5,%eax + movl %ebx,40(%esp) + leal 2400959708(%ebx,%ebp,1),%ebx + movl %edi,%ebp + addl %eax,%ebx + andl %esi,%ebp + movl 44(%esp),%eax + addl %ebp,%ebx + + movl %edx,%ebp + xorl 52(%esp),%eax + xorl %edi,%ebp + xorl 12(%esp),%eax + andl %ecx,%ebp + xorl 32(%esp),%eax + roll $1,%eax + addl %esi,%ebp + rorl $2,%ecx + movl %ebx,%esi + roll $5,%esi + movl %eax,44(%esp) + leal 2400959708(%eax,%ebp,1),%eax + movl %edx,%ebp + addl %esi,%eax + andl %edi,%ebp + movl 48(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl 56(%esp),%esi + xorl %ecx,%ebp + xorl 16(%esp),%esi + xorl %edx,%ebp + xorl 36(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,48(%esp) + leal 3395469782(%esi,%edi,1),%esi + movl 52(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 60(%esp),%edi + xorl %ebx,%ebp + xorl 20(%esp),%edi + xorl %ecx,%ebp + xorl 40(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,52(%esp) + leal 3395469782(%edi,%edx,1),%edi + movl 56(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl (%esp),%edx + xorl %eax,%ebp + xorl 24(%esp),%edx + xorl %ebx,%ebp + xorl 44(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,56(%esp) + leal 3395469782(%edx,%ecx,1),%edx + movl 60(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 4(%esp),%ecx + xorl %esi,%ebp + xorl 28(%esp),%ecx + xorl %eax,%ebp + xorl 48(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,60(%esp) + leal 3395469782(%ecx,%ebx,1),%ecx + movl (%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 8(%esp),%ebx + xorl %edi,%ebp + xorl 32(%esp),%ebx + xorl %esi,%ebp + xorl 52(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,(%esp) + leal 3395469782(%ebx,%eax,1),%ebx + movl 4(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 12(%esp),%eax + xorl %edx,%ebp + xorl 36(%esp),%eax + xorl %edi,%ebp + xorl 56(%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + movl %eax,4(%esp) + leal 3395469782(%eax,%esi,1),%eax + movl 8(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl 16(%esp),%esi + xorl %ecx,%ebp + xorl 40(%esp),%esi + xorl %edx,%ebp + xorl 60(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,8(%esp) + leal 3395469782(%esi,%edi,1),%esi + movl 12(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 20(%esp),%edi + xorl %ebx,%ebp + xorl 44(%esp),%edi + xorl %ecx,%ebp + xorl (%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,12(%esp) + leal 3395469782(%edi,%edx,1),%edi + movl 16(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 24(%esp),%edx + xorl %eax,%ebp + xorl 48(%esp),%edx + xorl %ebx,%ebp + xorl 4(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,16(%esp) + leal 3395469782(%edx,%ecx,1),%edx + movl 20(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 28(%esp),%ecx + xorl %esi,%ebp + xorl 52(%esp),%ecx + xorl %eax,%ebp + xorl 8(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,20(%esp) + leal 3395469782(%ecx,%ebx,1),%ecx + movl 24(%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 32(%esp),%ebx + xorl %edi,%ebp + xorl 56(%esp),%ebx + xorl %esi,%ebp + xorl 12(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,24(%esp) + leal 3395469782(%ebx,%eax,1),%ebx + movl 28(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 36(%esp),%eax + xorl %edx,%ebp + xorl 60(%esp),%eax + xorl %edi,%ebp + xorl 16(%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + movl %eax,28(%esp) + leal 3395469782(%eax,%esi,1),%eax + movl 32(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl 40(%esp),%esi + xorl %ecx,%ebp + xorl (%esp),%esi + xorl %edx,%ebp + xorl 20(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + movl %esi,32(%esp) + leal 3395469782(%esi,%edi,1),%esi + movl 36(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 44(%esp),%edi + xorl %ebx,%ebp + xorl 4(%esp),%edi + xorl %ecx,%ebp + xorl 24(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + movl %edi,36(%esp) + leal 3395469782(%edi,%edx,1),%edi + movl 40(%esp),%edx + addl %ebp,%edi + + movl %esi,%ebp + xorl 48(%esp),%edx + xorl %eax,%ebp + xorl 8(%esp),%edx + xorl %ebx,%ebp + xorl 28(%esp),%edx + roll $1,%edx + addl %ebp,%ecx + rorl $2,%esi + movl %edi,%ebp + roll $5,%ebp + movl %edx,40(%esp) + leal 3395469782(%edx,%ecx,1),%edx + movl 44(%esp),%ecx + addl %ebp,%edx + + movl %edi,%ebp + xorl 52(%esp),%ecx + xorl %esi,%ebp + xorl 12(%esp),%ecx + xorl %eax,%ebp + xorl 32(%esp),%ecx + roll $1,%ecx + addl %ebp,%ebx + rorl $2,%edi + movl %edx,%ebp + roll $5,%ebp + movl %ecx,44(%esp) + leal 3395469782(%ecx,%ebx,1),%ecx + movl 48(%esp),%ebx + addl %ebp,%ecx + + movl %edx,%ebp + xorl 56(%esp),%ebx + xorl %edi,%ebp + xorl 16(%esp),%ebx + xorl %esi,%ebp + xorl 36(%esp),%ebx + roll $1,%ebx + addl %ebp,%eax + rorl $2,%edx + movl %ecx,%ebp + roll $5,%ebp + movl %ebx,48(%esp) + leal 3395469782(%ebx,%eax,1),%ebx + movl 52(%esp),%eax + addl %ebp,%ebx + + movl %ecx,%ebp + xorl 60(%esp),%eax + xorl %edx,%ebp + xorl 20(%esp),%eax + xorl %edi,%ebp + xorl 40(%esp),%eax + roll $1,%eax + addl %ebp,%esi + rorl $2,%ecx + movl %ebx,%ebp + roll $5,%ebp + leal 3395469782(%eax,%esi,1),%eax + movl 56(%esp),%esi + addl %ebp,%eax + + movl %ebx,%ebp + xorl (%esp),%esi + xorl %ecx,%ebp + xorl 24(%esp),%esi + xorl %edx,%ebp + xorl 44(%esp),%esi + roll $1,%esi + addl %ebp,%edi + rorl $2,%ebx + movl %eax,%ebp + roll $5,%ebp + leal 3395469782(%esi,%edi,1),%esi + movl 60(%esp),%edi + addl %ebp,%esi + + movl %eax,%ebp + xorl 4(%esp),%edi + xorl %ebx,%ebp + xorl 28(%esp),%edi + xorl %ecx,%ebp + xorl 48(%esp),%edi + roll $1,%edi + addl %ebp,%edx + rorl $2,%eax + movl %esi,%ebp + roll $5,%ebp + leal 3395469782(%edi,%edx,1),%edi + addl %ebp,%edi + movl 96(%esp),%ebp + movl 100(%esp),%edx + addl (%ebp),%edi + addl 4(%ebp),%esi + addl 8(%ebp),%eax + addl 12(%ebp),%ebx + addl 16(%ebp),%ecx + movl %edi,(%ebp) + addl $64,%edx + movl %esi,4(%ebp) + cmpl 104(%esp),%edx + movl %eax,8(%ebp) + movl %ecx,%edi + movl %ebx,12(%ebp) + movl %edx,%esi + movl %ecx,16(%ebp) + jb .L002loop + addl $76,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size sha1_block_data_order,.-.L_sha1_block_data_order_begin +.type _sha1_block_data_order_shaext,@function +.align 16 +_sha1_block_data_order_shaext: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + call .L003pic_point +.L003pic_point: + popl %ebp + leal .LK_XX_XX-.L003pic_point(%ebp),%ebp +.Lshaext_shortcut: + movl 20(%esp),%edi + movl %esp,%ebx + movl 24(%esp),%esi + movl 28(%esp),%ecx + subl $32,%esp + movdqu (%edi),%xmm0 + movd 16(%edi),%xmm1 + andl $-32,%esp + movdqa 80(%ebp),%xmm3 + movdqu (%esi),%xmm4 + pshufd $27,%xmm0,%xmm0 + movdqu 16(%esi),%xmm5 + pshufd $27,%xmm1,%xmm1 + movdqu 32(%esi),%xmm6 +.byte 102,15,56,0,227 + movdqu 48(%esi),%xmm7 +.byte 102,15,56,0,235 +.byte 102,15,56,0,243 +.byte 102,15,56,0,251 + jmp .L004loop_shaext +.align 16 +.L004loop_shaext: + decl %ecx + leal 64(%esi),%eax + movdqa %xmm1,(%esp) + paddd %xmm4,%xmm1 + cmovnel %eax,%esi + movdqa %xmm0,16(%esp) +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,0 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,0 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,1 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,1 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,2 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,2 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 + movdqu (%esi),%xmm4 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,3 +.byte 15,56,200,213 + movdqu 16(%esi),%xmm5 +.byte 102,15,56,0,227 + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 +.byte 15,56,200,206 + movdqu 32(%esi),%xmm6 +.byte 102,15,56,0,235 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,3 +.byte 15,56,200,215 + movdqu 48(%esi),%xmm7 +.byte 102,15,56,0,243 + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 + movdqa (%esp),%xmm2 +.byte 102,15,56,0,251 +.byte 15,56,200,202 + paddd 16(%esp),%xmm0 + jnz .L004loop_shaext + pshufd $27,%xmm0,%xmm0 + pshufd $27,%xmm1,%xmm1 + movdqu %xmm0,(%edi) + movd %xmm1,16(%edi) + movl %ebx,%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size _sha1_block_data_order_shaext,.-_sha1_block_data_order_shaext +.type _sha1_block_data_order_ssse3,@function +.align 16 +_sha1_block_data_order_ssse3: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + call .L005pic_point +.L005pic_point: + popl %ebp + leal .LK_XX_XX-.L005pic_point(%ebp),%ebp +.Lssse3_shortcut: + movdqa (%ebp),%xmm7 + movdqa 16(%ebp),%xmm0 + movdqa 32(%ebp),%xmm1 + movdqa 48(%ebp),%xmm2 + movdqa 64(%ebp),%xmm6 + movl 20(%esp),%edi + movl 24(%esp),%ebp + movl 28(%esp),%edx + movl %esp,%esi + subl $208,%esp + andl $-64,%esp + movdqa %xmm0,112(%esp) + movdqa %xmm1,128(%esp) + movdqa %xmm2,144(%esp) + shll $6,%edx + movdqa %xmm7,160(%esp) + addl %ebp,%edx + movdqa %xmm6,176(%esp) + addl $64,%ebp + movl %edi,192(%esp) + movl %ebp,196(%esp) + movl %edx,200(%esp) + movl %esi,204(%esp) + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl 16(%edi),%edi + movl %ebx,%esi + movdqu -64(%ebp),%xmm0 + movdqu -48(%ebp),%xmm1 + movdqu -32(%ebp),%xmm2 + movdqu -16(%ebp),%xmm3 +.byte 102,15,56,0,198 +.byte 102,15,56,0,206 +.byte 102,15,56,0,214 + movdqa %xmm7,96(%esp) +.byte 102,15,56,0,222 + paddd %xmm7,%xmm0 + paddd %xmm7,%xmm1 + paddd %xmm7,%xmm2 + movdqa %xmm0,(%esp) + psubd %xmm7,%xmm0 + movdqa %xmm1,16(%esp) + psubd %xmm7,%xmm1 + movdqa %xmm2,32(%esp) + movl %ecx,%ebp + psubd %xmm7,%xmm2 + xorl %edx,%ebp + pshufd $238,%xmm0,%xmm4 + andl %ebp,%esi + jmp .L006loop +.align 16 +.L006loop: + rorl $2,%ebx + xorl %edx,%esi + movl %eax,%ebp + punpcklqdq %xmm1,%xmm4 + movdqa %xmm3,%xmm6 + addl (%esp),%edi + xorl %ecx,%ebx + paddd %xmm3,%xmm7 + movdqa %xmm0,64(%esp) + roll $5,%eax + addl %esi,%edi + psrldq $4,%xmm6 + andl %ebx,%ebp + xorl %ecx,%ebx + pxor %xmm0,%xmm4 + addl %eax,%edi + rorl $7,%eax + pxor %xmm2,%xmm6 + xorl %ecx,%ebp + movl %edi,%esi + addl 4(%esp),%edx + pxor %xmm6,%xmm4 + xorl %ebx,%eax + roll $5,%edi + movdqa %xmm7,48(%esp) + addl %ebp,%edx + andl %eax,%esi + movdqa %xmm4,%xmm0 + xorl %ebx,%eax + addl %edi,%edx + rorl $7,%edi + movdqa %xmm4,%xmm6 + xorl %ebx,%esi + pslldq $12,%xmm0 + paddd %xmm4,%xmm4 + movl %edx,%ebp + addl 8(%esp),%ecx + psrld $31,%xmm6 + xorl %eax,%edi + roll $5,%edx + movdqa %xmm0,%xmm7 + addl %esi,%ecx + andl %edi,%ebp + xorl %eax,%edi + psrld $30,%xmm0 + addl %edx,%ecx + rorl $7,%edx + por %xmm6,%xmm4 + xorl %eax,%ebp + movl %ecx,%esi + addl 12(%esp),%ebx + pslld $2,%xmm7 + xorl %edi,%edx + roll $5,%ecx + pxor %xmm0,%xmm4 + movdqa 96(%esp),%xmm0 + addl %ebp,%ebx + andl %edx,%esi + pxor %xmm7,%xmm4 + pshufd $238,%xmm1,%xmm5 + xorl %edi,%edx + addl %ecx,%ebx + rorl $7,%ecx + xorl %edi,%esi + movl %ebx,%ebp + punpcklqdq %xmm2,%xmm5 + movdqa %xmm4,%xmm7 + addl 16(%esp),%eax + xorl %edx,%ecx + paddd %xmm4,%xmm0 + movdqa %xmm1,80(%esp) + roll $5,%ebx + addl %esi,%eax + psrldq $4,%xmm7 + andl %ecx,%ebp + xorl %edx,%ecx + pxor %xmm1,%xmm5 + addl %ebx,%eax + rorl $7,%ebx + pxor %xmm3,%xmm7 + xorl %edx,%ebp + movl %eax,%esi + addl 20(%esp),%edi + pxor %xmm7,%xmm5 + xorl %ecx,%ebx + roll $5,%eax + movdqa %xmm0,(%esp) + addl %ebp,%edi + andl %ebx,%esi + movdqa %xmm5,%xmm1 + xorl %ecx,%ebx + addl %eax,%edi + rorl $7,%eax + movdqa %xmm5,%xmm7 + xorl %ecx,%esi + pslldq $12,%xmm1 + paddd %xmm5,%xmm5 + movl %edi,%ebp + addl 24(%esp),%edx + psrld $31,%xmm7 + xorl %ebx,%eax + roll $5,%edi + movdqa %xmm1,%xmm0 + addl %esi,%edx + andl %eax,%ebp + xorl %ebx,%eax + psrld $30,%xmm1 + addl %edi,%edx + rorl $7,%edi + por %xmm7,%xmm5 + xorl %ebx,%ebp + movl %edx,%esi + addl 28(%esp),%ecx + pslld $2,%xmm0 + xorl %eax,%edi + roll $5,%edx + pxor %xmm1,%xmm5 + movdqa 112(%esp),%xmm1 + addl %ebp,%ecx + andl %edi,%esi + pxor %xmm0,%xmm5 + pshufd $238,%xmm2,%xmm6 + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%edx + xorl %eax,%esi + movl %ecx,%ebp + punpcklqdq %xmm3,%xmm6 + movdqa %xmm5,%xmm0 + addl 32(%esp),%ebx + xorl %edi,%edx + paddd %xmm5,%xmm1 + movdqa %xmm2,96(%esp) + roll $5,%ecx + addl %esi,%ebx + psrldq $4,%xmm0 + andl %edx,%ebp + xorl %edi,%edx + pxor %xmm2,%xmm6 + addl %ecx,%ebx + rorl $7,%ecx + pxor %xmm4,%xmm0 + xorl %edi,%ebp + movl %ebx,%esi + addl 36(%esp),%eax + pxor %xmm0,%xmm6 + xorl %edx,%ecx + roll $5,%ebx + movdqa %xmm1,16(%esp) + addl %ebp,%eax + andl %ecx,%esi + movdqa %xmm6,%xmm2 + xorl %edx,%ecx + addl %ebx,%eax + rorl $7,%ebx + movdqa %xmm6,%xmm0 + xorl %edx,%esi + pslldq $12,%xmm2 + paddd %xmm6,%xmm6 + movl %eax,%ebp + addl 40(%esp),%edi + psrld $31,%xmm0 + xorl %ecx,%ebx + roll $5,%eax + movdqa %xmm2,%xmm1 + addl %esi,%edi + andl %ebx,%ebp + xorl %ecx,%ebx + psrld $30,%xmm2 + addl %eax,%edi + rorl $7,%eax + por %xmm0,%xmm6 + xorl %ecx,%ebp + movdqa 64(%esp),%xmm0 + movl %edi,%esi + addl 44(%esp),%edx + pslld $2,%xmm1 + xorl %ebx,%eax + roll $5,%edi + pxor %xmm2,%xmm6 + movdqa 112(%esp),%xmm2 + addl %ebp,%edx + andl %eax,%esi + pxor %xmm1,%xmm6 + pshufd $238,%xmm3,%xmm7 + xorl %ebx,%eax + addl %edi,%edx + rorl $7,%edi + xorl %ebx,%esi + movl %edx,%ebp + punpcklqdq %xmm4,%xmm7 + movdqa %xmm6,%xmm1 + addl 48(%esp),%ecx + xorl %eax,%edi + paddd %xmm6,%xmm2 + movdqa %xmm3,64(%esp) + roll $5,%edx + addl %esi,%ecx + psrldq $4,%xmm1 + andl %edi,%ebp + xorl %eax,%edi + pxor %xmm3,%xmm7 + addl %edx,%ecx + rorl $7,%edx + pxor %xmm5,%xmm1 + xorl %eax,%ebp + movl %ecx,%esi + addl 52(%esp),%ebx + pxor %xmm1,%xmm7 + xorl %edi,%edx + roll $5,%ecx + movdqa %xmm2,32(%esp) + addl %ebp,%ebx + andl %edx,%esi + movdqa %xmm7,%xmm3 + xorl %edi,%edx + addl %ecx,%ebx + rorl $7,%ecx + movdqa %xmm7,%xmm1 + xorl %edi,%esi + pslldq $12,%xmm3 + paddd %xmm7,%xmm7 + movl %ebx,%ebp + addl 56(%esp),%eax + psrld $31,%xmm1 + xorl %edx,%ecx + roll $5,%ebx + movdqa %xmm3,%xmm2 + addl %esi,%eax + andl %ecx,%ebp + xorl %edx,%ecx + psrld $30,%xmm3 + addl %ebx,%eax + rorl $7,%ebx + por %xmm1,%xmm7 + xorl %edx,%ebp + movdqa 80(%esp),%xmm1 + movl %eax,%esi + addl 60(%esp),%edi + pslld $2,%xmm2 + xorl %ecx,%ebx + roll $5,%eax + pxor %xmm3,%xmm7 + movdqa 112(%esp),%xmm3 + addl %ebp,%edi + andl %ebx,%esi + pxor %xmm2,%xmm7 + pshufd $238,%xmm6,%xmm2 + xorl %ecx,%ebx + addl %eax,%edi + rorl $7,%eax + pxor %xmm4,%xmm0 + punpcklqdq %xmm7,%xmm2 + xorl %ecx,%esi + movl %edi,%ebp + addl (%esp),%edx + pxor %xmm1,%xmm0 + movdqa %xmm4,80(%esp) + xorl %ebx,%eax + roll $5,%edi + movdqa %xmm3,%xmm4 + addl %esi,%edx + paddd %xmm7,%xmm3 + andl %eax,%ebp + pxor %xmm2,%xmm0 + xorl %ebx,%eax + addl %edi,%edx + rorl $7,%edi + xorl %ebx,%ebp + movdqa %xmm0,%xmm2 + movdqa %xmm3,48(%esp) + movl %edx,%esi + addl 4(%esp),%ecx + xorl %eax,%edi + roll $5,%edx + pslld $2,%xmm0 + addl %ebp,%ecx + andl %edi,%esi + psrld $30,%xmm2 + xorl %eax,%edi + addl %edx,%ecx + rorl $7,%edx + xorl %eax,%esi + movl %ecx,%ebp + addl 8(%esp),%ebx + xorl %edi,%edx + roll $5,%ecx + por %xmm2,%xmm0 + addl %esi,%ebx + andl %edx,%ebp + movdqa 96(%esp),%xmm2 + xorl %edi,%edx + addl %ecx,%ebx + addl 12(%esp),%eax + xorl %edi,%ebp + movl %ebx,%esi + pshufd $238,%xmm7,%xmm3 + roll $5,%ebx + addl %ebp,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + addl 16(%esp),%edi + pxor %xmm5,%xmm1 + punpcklqdq %xmm0,%xmm3 + xorl %ecx,%esi + movl %eax,%ebp + roll $5,%eax + pxor %xmm2,%xmm1 + movdqa %xmm5,96(%esp) + addl %esi,%edi + xorl %ecx,%ebp + movdqa %xmm4,%xmm5 + rorl $7,%ebx + paddd %xmm0,%xmm4 + addl %eax,%edi + pxor %xmm3,%xmm1 + addl 20(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + roll $5,%edi + movdqa %xmm1,%xmm3 + movdqa %xmm4,(%esp) + addl %ebp,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %edi,%edx + pslld $2,%xmm1 + addl 24(%esp),%ecx + xorl %eax,%esi + psrld $30,%xmm3 + movl %edx,%ebp + roll $5,%edx + addl %esi,%ecx + xorl %eax,%ebp + rorl $7,%edi + addl %edx,%ecx + por %xmm3,%xmm1 + addl 28(%esp),%ebx + xorl %edi,%ebp + movdqa 64(%esp),%xmm3 + movl %ecx,%esi + roll $5,%ecx + addl %ebp,%ebx + xorl %edi,%esi + rorl $7,%edx + pshufd $238,%xmm0,%xmm4 + addl %ecx,%ebx + addl 32(%esp),%eax + pxor %xmm6,%xmm2 + punpcklqdq %xmm1,%xmm4 + xorl %edx,%esi + movl %ebx,%ebp + roll $5,%ebx + pxor %xmm3,%xmm2 + movdqa %xmm6,64(%esp) + addl %esi,%eax + xorl %edx,%ebp + movdqa 128(%esp),%xmm6 + rorl $7,%ecx + paddd %xmm1,%xmm5 + addl %ebx,%eax + pxor %xmm4,%xmm2 + addl 36(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + roll $5,%eax + movdqa %xmm2,%xmm4 + movdqa %xmm5,16(%esp) + addl %ebp,%edi + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%edi + pslld $2,%xmm2 + addl 40(%esp),%edx + xorl %ebx,%esi + psrld $30,%xmm4 + movl %edi,%ebp + roll $5,%edi + addl %esi,%edx + xorl %ebx,%ebp + rorl $7,%eax + addl %edi,%edx + por %xmm4,%xmm2 + addl 44(%esp),%ecx + xorl %eax,%ebp + movdqa 80(%esp),%xmm4 + movl %edx,%esi + roll $5,%edx + addl %ebp,%ecx + xorl %eax,%esi + rorl $7,%edi + pshufd $238,%xmm1,%xmm5 + addl %edx,%ecx + addl 48(%esp),%ebx + pxor %xmm7,%xmm3 + punpcklqdq %xmm2,%xmm5 + xorl %edi,%esi + movl %ecx,%ebp + roll $5,%ecx + pxor %xmm4,%xmm3 + movdqa %xmm7,80(%esp) + addl %esi,%ebx + xorl %edi,%ebp + movdqa %xmm6,%xmm7 + rorl $7,%edx + paddd %xmm2,%xmm6 + addl %ecx,%ebx + pxor %xmm5,%xmm3 + addl 52(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + roll $5,%ebx + movdqa %xmm3,%xmm5 + movdqa %xmm6,32(%esp) + addl %ebp,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + pslld $2,%xmm3 + addl 56(%esp),%edi + xorl %ecx,%esi + psrld $30,%xmm5 + movl %eax,%ebp + roll $5,%eax + addl %esi,%edi + xorl %ecx,%ebp + rorl $7,%ebx + addl %eax,%edi + por %xmm5,%xmm3 + addl 60(%esp),%edx + xorl %ebx,%ebp + movdqa 96(%esp),%xmm5 + movl %edi,%esi + roll $5,%edi + addl %ebp,%edx + xorl %ebx,%esi + rorl $7,%eax + pshufd $238,%xmm2,%xmm6 + addl %edi,%edx + addl (%esp),%ecx + pxor %xmm0,%xmm4 + punpcklqdq %xmm3,%xmm6 + xorl %eax,%esi + movl %edx,%ebp + roll $5,%edx + pxor %xmm5,%xmm4 + movdqa %xmm0,96(%esp) + addl %esi,%ecx + xorl %eax,%ebp + movdqa %xmm7,%xmm0 + rorl $7,%edi + paddd %xmm3,%xmm7 + addl %edx,%ecx + pxor %xmm6,%xmm4 + addl 4(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + roll $5,%ecx + movdqa %xmm4,%xmm6 + movdqa %xmm7,48(%esp) + addl %ebp,%ebx + xorl %edi,%esi + rorl $7,%edx + addl %ecx,%ebx + pslld $2,%xmm4 + addl 8(%esp),%eax + xorl %edx,%esi + psrld $30,%xmm6 + movl %ebx,%ebp + roll $5,%ebx + addl %esi,%eax + xorl %edx,%ebp + rorl $7,%ecx + addl %ebx,%eax + por %xmm6,%xmm4 + addl 12(%esp),%edi + xorl %ecx,%ebp + movdqa 64(%esp),%xmm6 + movl %eax,%esi + roll $5,%eax + addl %ebp,%edi + xorl %ecx,%esi + rorl $7,%ebx + pshufd $238,%xmm3,%xmm7 + addl %eax,%edi + addl 16(%esp),%edx + pxor %xmm1,%xmm5 + punpcklqdq %xmm4,%xmm7 + xorl %ebx,%esi + movl %edi,%ebp + roll $5,%edi + pxor %xmm6,%xmm5 + movdqa %xmm1,64(%esp) + addl %esi,%edx + xorl %ebx,%ebp + movdqa %xmm0,%xmm1 + rorl $7,%eax + paddd %xmm4,%xmm0 + addl %edi,%edx + pxor %xmm7,%xmm5 + addl 20(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + roll $5,%edx + movdqa %xmm5,%xmm7 + movdqa %xmm0,(%esp) + addl %ebp,%ecx + xorl %eax,%esi + rorl $7,%edi + addl %edx,%ecx + pslld $2,%xmm5 + addl 24(%esp),%ebx + xorl %edi,%esi + psrld $30,%xmm7 + movl %ecx,%ebp + roll $5,%ecx + addl %esi,%ebx + xorl %edi,%ebp + rorl $7,%edx + addl %ecx,%ebx + por %xmm7,%xmm5 + addl 28(%esp),%eax + movdqa 80(%esp),%xmm7 + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%ebp + roll $5,%ebx + pshufd $238,%xmm4,%xmm0 + addl %ebp,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 32(%esp),%edi + pxor %xmm2,%xmm6 + punpcklqdq %xmm5,%xmm0 + andl %ecx,%esi + xorl %edx,%ecx + rorl $7,%ebx + pxor %xmm7,%xmm6 + movdqa %xmm2,80(%esp) + movl %eax,%ebp + xorl %ecx,%esi + roll $5,%eax + movdqa %xmm1,%xmm2 + addl %esi,%edi + paddd %xmm5,%xmm1 + xorl %ebx,%ebp + pxor %xmm0,%xmm6 + xorl %ecx,%ebx + addl %eax,%edi + addl 36(%esp),%edx + andl %ebx,%ebp + movdqa %xmm6,%xmm0 + movdqa %xmm1,16(%esp) + xorl %ecx,%ebx + rorl $7,%eax + movl %edi,%esi + xorl %ebx,%ebp + roll $5,%edi + pslld $2,%xmm6 + addl %ebp,%edx + xorl %eax,%esi + psrld $30,%xmm0 + xorl %ebx,%eax + addl %edi,%edx + addl 40(%esp),%ecx + andl %eax,%esi + xorl %ebx,%eax + rorl $7,%edi + por %xmm0,%xmm6 + movl %edx,%ebp + xorl %eax,%esi + movdqa 96(%esp),%xmm0 + roll $5,%edx + addl %esi,%ecx + xorl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + pshufd $238,%xmm5,%xmm1 + addl 44(%esp),%ebx + andl %edi,%ebp + xorl %eax,%edi + rorl $7,%edx + movl %ecx,%esi + xorl %edi,%ebp + roll $5,%ecx + addl %ebp,%ebx + xorl %edx,%esi + xorl %edi,%edx + addl %ecx,%ebx + addl 48(%esp),%eax + pxor %xmm3,%xmm7 + punpcklqdq %xmm6,%xmm1 + andl %edx,%esi + xorl %edi,%edx + rorl $7,%ecx + pxor %xmm0,%xmm7 + movdqa %xmm3,96(%esp) + movl %ebx,%ebp + xorl %edx,%esi + roll $5,%ebx + movdqa 144(%esp),%xmm3 + addl %esi,%eax + paddd %xmm6,%xmm2 + xorl %ecx,%ebp + pxor %xmm1,%xmm7 + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%esp),%edi + andl %ecx,%ebp + movdqa %xmm7,%xmm1 + movdqa %xmm2,32(%esp) + xorl %edx,%ecx + rorl $7,%ebx + movl %eax,%esi + xorl %ecx,%ebp + roll $5,%eax + pslld $2,%xmm7 + addl %ebp,%edi + xorl %ebx,%esi + psrld $30,%xmm1 + xorl %ecx,%ebx + addl %eax,%edi + addl 56(%esp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + rorl $7,%eax + por %xmm1,%xmm7 + movl %edi,%ebp + xorl %ebx,%esi + movdqa 64(%esp),%xmm1 + roll $5,%edi + addl %esi,%edx + xorl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + pshufd $238,%xmm6,%xmm2 + addl 60(%esp),%ecx + andl %eax,%ebp + xorl %ebx,%eax + rorl $7,%edi + movl %edx,%esi + xorl %eax,%ebp + roll $5,%edx + addl %ebp,%ecx + xorl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + addl (%esp),%ebx + pxor %xmm4,%xmm0 + punpcklqdq %xmm7,%xmm2 + andl %edi,%esi + xorl %eax,%edi + rorl $7,%edx + pxor %xmm1,%xmm0 + movdqa %xmm4,64(%esp) + movl %ecx,%ebp + xorl %edi,%esi + roll $5,%ecx + movdqa %xmm3,%xmm4 + addl %esi,%ebx + paddd %xmm7,%xmm3 + xorl %edx,%ebp + pxor %xmm2,%xmm0 + xorl %edi,%edx + addl %ecx,%ebx + addl 4(%esp),%eax + andl %edx,%ebp + movdqa %xmm0,%xmm2 + movdqa %xmm3,48(%esp) + xorl %edi,%edx + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%ebp + roll $5,%ebx + pslld $2,%xmm0 + addl %ebp,%eax + xorl %ecx,%esi + psrld $30,%xmm2 + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%esp),%edi + andl %ecx,%esi + xorl %edx,%ecx + rorl $7,%ebx + por %xmm2,%xmm0 + movl %eax,%ebp + xorl %ecx,%esi + movdqa 80(%esp),%xmm2 + roll $5,%eax + addl %esi,%edi + xorl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + pshufd $238,%xmm7,%xmm3 + addl 12(%esp),%edx + andl %ebx,%ebp + xorl %ecx,%ebx + rorl $7,%eax + movl %edi,%esi + xorl %ebx,%ebp + roll $5,%edi + addl %ebp,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %edi,%edx + addl 16(%esp),%ecx + pxor %xmm5,%xmm1 + punpcklqdq %xmm0,%xmm3 + andl %eax,%esi + xorl %ebx,%eax + rorl $7,%edi + pxor %xmm2,%xmm1 + movdqa %xmm5,80(%esp) + movl %edx,%ebp + xorl %eax,%esi + roll $5,%edx + movdqa %xmm4,%xmm5 + addl %esi,%ecx + paddd %xmm0,%xmm4 + xorl %edi,%ebp + pxor %xmm3,%xmm1 + xorl %eax,%edi + addl %edx,%ecx + addl 20(%esp),%ebx + andl %edi,%ebp + movdqa %xmm1,%xmm3 + movdqa %xmm4,(%esp) + xorl %eax,%edi + rorl $7,%edx + movl %ecx,%esi + xorl %edi,%ebp + roll $5,%ecx + pslld $2,%xmm1 + addl %ebp,%ebx + xorl %edx,%esi + psrld $30,%xmm3 + xorl %edi,%edx + addl %ecx,%ebx + addl 24(%esp),%eax + andl %edx,%esi + xorl %edi,%edx + rorl $7,%ecx + por %xmm3,%xmm1 + movl %ebx,%ebp + xorl %edx,%esi + movdqa 96(%esp),%xmm3 + roll $5,%ebx + addl %esi,%eax + xorl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + pshufd $238,%xmm0,%xmm4 + addl 28(%esp),%edi + andl %ecx,%ebp + xorl %edx,%ecx + rorl $7,%ebx + movl %eax,%esi + xorl %ecx,%ebp + roll $5,%eax + addl %ebp,%edi + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%edi + addl 32(%esp),%edx + pxor %xmm6,%xmm2 + punpcklqdq %xmm1,%xmm4 + andl %ebx,%esi + xorl %ecx,%ebx + rorl $7,%eax + pxor %xmm3,%xmm2 + movdqa %xmm6,96(%esp) + movl %edi,%ebp + xorl %ebx,%esi + roll $5,%edi + movdqa %xmm5,%xmm6 + addl %esi,%edx + paddd %xmm1,%xmm5 + xorl %eax,%ebp + pxor %xmm4,%xmm2 + xorl %ebx,%eax + addl %edi,%edx + addl 36(%esp),%ecx + andl %eax,%ebp + movdqa %xmm2,%xmm4 + movdqa %xmm5,16(%esp) + xorl %ebx,%eax + rorl $7,%edi + movl %edx,%esi + xorl %eax,%ebp + roll $5,%edx + pslld $2,%xmm2 + addl %ebp,%ecx + xorl %edi,%esi + psrld $30,%xmm4 + xorl %eax,%edi + addl %edx,%ecx + addl 40(%esp),%ebx + andl %edi,%esi + xorl %eax,%edi + rorl $7,%edx + por %xmm4,%xmm2 + movl %ecx,%ebp + xorl %edi,%esi + movdqa 64(%esp),%xmm4 + roll $5,%ecx + addl %esi,%ebx + xorl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + pshufd $238,%xmm1,%xmm5 + addl 44(%esp),%eax + andl %edx,%ebp + xorl %edi,%edx + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%ebp + roll $5,%ebx + addl %ebp,%eax + xorl %edx,%esi + addl %ebx,%eax + addl 48(%esp),%edi + pxor %xmm7,%xmm3 + punpcklqdq %xmm2,%xmm5 + xorl %ecx,%esi + movl %eax,%ebp + roll $5,%eax + pxor %xmm4,%xmm3 + movdqa %xmm7,64(%esp) + addl %esi,%edi + xorl %ecx,%ebp + movdqa %xmm6,%xmm7 + rorl $7,%ebx + paddd %xmm2,%xmm6 + addl %eax,%edi + pxor %xmm5,%xmm3 + addl 52(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + roll $5,%edi + movdqa %xmm3,%xmm5 + movdqa %xmm6,32(%esp) + addl %ebp,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %edi,%edx + pslld $2,%xmm3 + addl 56(%esp),%ecx + xorl %eax,%esi + psrld $30,%xmm5 + movl %edx,%ebp + roll $5,%edx + addl %esi,%ecx + xorl %eax,%ebp + rorl $7,%edi + addl %edx,%ecx + por %xmm5,%xmm3 + addl 60(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + roll $5,%ecx + addl %ebp,%ebx + xorl %edi,%esi + rorl $7,%edx + addl %ecx,%ebx + addl (%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + roll $5,%ebx + addl %esi,%eax + xorl %edx,%ebp + rorl $7,%ecx + paddd %xmm3,%xmm7 + addl %ebx,%eax + addl 4(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + movdqa %xmm7,48(%esp) + roll $5,%eax + addl %ebp,%edi + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%edi + addl 8(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + roll $5,%edi + addl %esi,%edx + xorl %ebx,%ebp + rorl $7,%eax + addl %edi,%edx + addl 12(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + roll $5,%edx + addl %ebp,%ecx + xorl %eax,%esi + rorl $7,%edi + addl %edx,%ecx + movl 196(%esp),%ebp + cmpl 200(%esp),%ebp + je .L007done + movdqa 160(%esp),%xmm7 + movdqa 176(%esp),%xmm6 + movdqu (%ebp),%xmm0 + movdqu 16(%ebp),%xmm1 + movdqu 32(%ebp),%xmm2 + movdqu 48(%ebp),%xmm3 + addl $64,%ebp +.byte 102,15,56,0,198 + movl %ebp,196(%esp) + movdqa %xmm7,96(%esp) + addl 16(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + roll $5,%ecx + addl %esi,%ebx + xorl %edi,%ebp + rorl $7,%edx +.byte 102,15,56,0,206 + addl %ecx,%ebx + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + paddd %xmm7,%xmm0 + roll $5,%ebx + addl %ebp,%eax + xorl %edx,%esi + rorl $7,%ecx + movdqa %xmm0,(%esp) + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + psubd %xmm7,%xmm0 + roll $5,%eax + addl %esi,%edi + xorl %ecx,%ebp + rorl $7,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + roll $5,%edi + addl %ebp,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + roll $5,%edx + addl %esi,%ecx + xorl %eax,%ebp + rorl $7,%edi +.byte 102,15,56,0,214 + addl %edx,%ecx + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + paddd %xmm7,%xmm1 + roll $5,%ecx + addl %ebp,%ebx + xorl %edi,%esi + rorl $7,%edx + movdqa %xmm1,16(%esp) + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + psubd %xmm7,%xmm1 + roll $5,%ebx + addl %esi,%eax + xorl %edx,%ebp + rorl $7,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + roll $5,%eax + addl %ebp,%edi + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + roll $5,%edi + addl %esi,%edx + xorl %ebx,%ebp + rorl $7,%eax +.byte 102,15,56,0,222 + addl %edi,%edx + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + paddd %xmm7,%xmm2 + roll $5,%edx + addl %ebp,%ecx + xorl %eax,%esi + rorl $7,%edi + movdqa %xmm2,32(%esp) + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + psubd %xmm7,%xmm2 + roll $5,%ecx + addl %esi,%ebx + xorl %edi,%ebp + rorl $7,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + roll $5,%ebx + addl %ebp,%eax + rorl $7,%ecx + addl %ebx,%eax + movl 192(%esp),%ebp + addl (%ebp),%eax + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,8(%ebp) + movl %ecx,%ebx + movl %edx,12(%ebp) + xorl %edx,%ebx + movl %edi,16(%ebp) + movl %esi,%ebp + pshufd $238,%xmm0,%xmm4 + andl %ebx,%esi + movl %ebp,%ebx + jmp .L006loop +.align 16 +.L007done: + addl 16(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + roll $5,%ecx + addl %esi,%ebx + xorl %edi,%ebp + rorl $7,%edx + addl %ecx,%ebx + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + roll $5,%ebx + addl %ebp,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + roll $5,%eax + addl %esi,%edi + xorl %ecx,%ebp + rorl $7,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + roll $5,%edi + addl %ebp,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + roll $5,%edx + addl %esi,%ecx + xorl %eax,%ebp + rorl $7,%edi + addl %edx,%ecx + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + roll $5,%ecx + addl %ebp,%ebx + xorl %edi,%esi + rorl $7,%edx + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + roll $5,%ebx + addl %esi,%eax + xorl %edx,%ebp + rorl $7,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + roll $5,%eax + addl %ebp,%edi + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + roll $5,%edi + addl %esi,%edx + xorl %ebx,%ebp + rorl $7,%eax + addl %edi,%edx + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + roll $5,%edx + addl %ebp,%ecx + xorl %eax,%esi + rorl $7,%edi + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + roll $5,%ecx + addl %esi,%ebx + xorl %edi,%ebp + rorl $7,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + roll $5,%ebx + addl %ebp,%eax + rorl $7,%ecx + addl %ebx,%eax + movl 192(%esp),%ebp + addl (%ebp),%eax + movl 204(%esp),%esp + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,8(%ebp) + movl %edx,12(%ebp) + movl %edi,16(%ebp) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size _sha1_block_data_order_ssse3,.-_sha1_block_data_order_ssse3 +.type _sha1_block_data_order_avx,@function +.align 16 +_sha1_block_data_order_avx: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + call .L008pic_point +.L008pic_point: + popl %ebp + leal .LK_XX_XX-.L008pic_point(%ebp),%ebp +.Lavx_shortcut: + vzeroall + vmovdqa (%ebp),%xmm7 + vmovdqa 16(%ebp),%xmm0 + vmovdqa 32(%ebp),%xmm1 + vmovdqa 48(%ebp),%xmm2 + vmovdqa 64(%ebp),%xmm6 + movl 20(%esp),%edi + movl 24(%esp),%ebp + movl 28(%esp),%edx + movl %esp,%esi + subl $208,%esp + andl $-64,%esp + vmovdqa %xmm0,112(%esp) + vmovdqa %xmm1,128(%esp) + vmovdqa %xmm2,144(%esp) + shll $6,%edx + vmovdqa %xmm7,160(%esp) + addl %ebp,%edx + vmovdqa %xmm6,176(%esp) + addl $64,%ebp + movl %edi,192(%esp) + movl %ebp,196(%esp) + movl %edx,200(%esp) + movl %esi,204(%esp) + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + movl 16(%edi),%edi + movl %ebx,%esi + vmovdqu -64(%ebp),%xmm0 + vmovdqu -48(%ebp),%xmm1 + vmovdqu -32(%ebp),%xmm2 + vmovdqu -16(%ebp),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + vpshufb %xmm6,%xmm1,%xmm1 + vpshufb %xmm6,%xmm2,%xmm2 + vmovdqa %xmm7,96(%esp) + vpshufb %xmm6,%xmm3,%xmm3 + vpaddd %xmm7,%xmm0,%xmm4 + vpaddd %xmm7,%xmm1,%xmm5 + vpaddd %xmm7,%xmm2,%xmm6 + vmovdqa %xmm4,(%esp) + movl %ecx,%ebp + vmovdqa %xmm5,16(%esp) + xorl %edx,%ebp + vmovdqa %xmm6,32(%esp) + andl %ebp,%esi + jmp .L009loop +.align 16 +.L009loop: + shrdl $2,%ebx,%ebx + xorl %edx,%esi + vpalignr $8,%xmm0,%xmm1,%xmm4 + movl %eax,%ebp + addl (%esp),%edi + vpaddd %xmm3,%xmm7,%xmm7 + vmovdqa %xmm0,64(%esp) + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrldq $4,%xmm3,%xmm6 + addl %esi,%edi + andl %ebx,%ebp + vpxor %xmm0,%xmm4,%xmm4 + xorl %ecx,%ebx + addl %eax,%edi + vpxor %xmm2,%xmm6,%xmm6 + shrdl $7,%eax,%eax + xorl %ecx,%ebp + vmovdqa %xmm7,48(%esp) + movl %edi,%esi + addl 4(%esp),%edx + vpxor %xmm6,%xmm4,%xmm4 + xorl %ebx,%eax + shldl $5,%edi,%edi + addl %ebp,%edx + andl %eax,%esi + vpsrld $31,%xmm4,%xmm6 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%esi + vpslldq $12,%xmm4,%xmm0 + vpaddd %xmm4,%xmm4,%xmm4 + movl %edx,%ebp + addl 8(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpsrld $30,%xmm0,%xmm7 + vpor %xmm6,%xmm4,%xmm4 + addl %esi,%ecx + andl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + vpslld $2,%xmm0,%xmm0 + shrdl $7,%edx,%edx + xorl %eax,%ebp + vpxor %xmm7,%xmm4,%xmm4 + movl %ecx,%esi + addl 12(%esp),%ebx + xorl %edi,%edx + shldl $5,%ecx,%ecx + vpxor %xmm0,%xmm4,%xmm4 + addl %ebp,%ebx + andl %edx,%esi + vmovdqa 96(%esp),%xmm0 + xorl %edi,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %edi,%esi + vpalignr $8,%xmm1,%xmm2,%xmm5 + movl %ebx,%ebp + addl 16(%esp),%eax + vpaddd %xmm4,%xmm0,%xmm0 + vmovdqa %xmm1,80(%esp) + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrldq $4,%xmm4,%xmm7 + addl %esi,%eax + andl %ecx,%ebp + vpxor %xmm1,%xmm5,%xmm5 + xorl %edx,%ecx + addl %ebx,%eax + vpxor %xmm3,%xmm7,%xmm7 + shrdl $7,%ebx,%ebx + xorl %edx,%ebp + vmovdqa %xmm0,(%esp) + movl %eax,%esi + addl 20(%esp),%edi + vpxor %xmm7,%xmm5,%xmm5 + xorl %ecx,%ebx + shldl $5,%eax,%eax + addl %ebp,%edi + andl %ebx,%esi + vpsrld $31,%xmm5,%xmm7 + xorl %ecx,%ebx + addl %eax,%edi + shrdl $7,%eax,%eax + xorl %ecx,%esi + vpslldq $12,%xmm5,%xmm1 + vpaddd %xmm5,%xmm5,%xmm5 + movl %edi,%ebp + addl 24(%esp),%edx + xorl %ebx,%eax + shldl $5,%edi,%edi + vpsrld $30,%xmm1,%xmm0 + vpor %xmm7,%xmm5,%xmm5 + addl %esi,%edx + andl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + vpslld $2,%xmm1,%xmm1 + shrdl $7,%edi,%edi + xorl %ebx,%ebp + vpxor %xmm0,%xmm5,%xmm5 + movl %edx,%esi + addl 28(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpxor %xmm1,%xmm5,%xmm5 + addl %ebp,%ecx + andl %edi,%esi + vmovdqa 112(%esp),%xmm1 + xorl %eax,%edi + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + vpalignr $8,%xmm2,%xmm3,%xmm6 + movl %ecx,%ebp + addl 32(%esp),%ebx + vpaddd %xmm5,%xmm1,%xmm1 + vmovdqa %xmm2,96(%esp) + xorl %edi,%edx + shldl $5,%ecx,%ecx + vpsrldq $4,%xmm5,%xmm0 + addl %esi,%ebx + andl %edx,%ebp + vpxor %xmm2,%xmm6,%xmm6 + xorl %edi,%edx + addl %ecx,%ebx + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%ecx,%ecx + xorl %edi,%ebp + vmovdqa %xmm1,16(%esp) + movl %ebx,%esi + addl 36(%esp),%eax + vpxor %xmm0,%xmm6,%xmm6 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + addl %ebp,%eax + andl %ecx,%esi + vpsrld $31,%xmm6,%xmm0 + xorl %edx,%ecx + addl %ebx,%eax + shrdl $7,%ebx,%ebx + xorl %edx,%esi + vpslldq $12,%xmm6,%xmm2 + vpaddd %xmm6,%xmm6,%xmm6 + movl %eax,%ebp + addl 40(%esp),%edi + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm1 + vpor %xmm0,%xmm6,%xmm6 + addl %esi,%edi + andl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + vpslld $2,%xmm2,%xmm2 + vmovdqa 64(%esp),%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%ebp + vpxor %xmm1,%xmm6,%xmm6 + movl %edi,%esi + addl 44(%esp),%edx + xorl %ebx,%eax + shldl $5,%edi,%edi + vpxor %xmm2,%xmm6,%xmm6 + addl %ebp,%edx + andl %eax,%esi + vmovdqa 112(%esp),%xmm2 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%esi + vpalignr $8,%xmm3,%xmm4,%xmm7 + movl %edx,%ebp + addl 48(%esp),%ecx + vpaddd %xmm6,%xmm2,%xmm2 + vmovdqa %xmm3,64(%esp) + xorl %eax,%edi + shldl $5,%edx,%edx + vpsrldq $4,%xmm6,%xmm1 + addl %esi,%ecx + andl %edi,%ebp + vpxor %xmm3,%xmm7,%xmm7 + xorl %eax,%edi + addl %edx,%ecx + vpxor %xmm5,%xmm1,%xmm1 + shrdl $7,%edx,%edx + xorl %eax,%ebp + vmovdqa %xmm2,32(%esp) + movl %ecx,%esi + addl 52(%esp),%ebx + vpxor %xmm1,%xmm7,%xmm7 + xorl %edi,%edx + shldl $5,%ecx,%ecx + addl %ebp,%ebx + andl %edx,%esi + vpsrld $31,%xmm7,%xmm1 + xorl %edi,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %edi,%esi + vpslldq $12,%xmm7,%xmm3 + vpaddd %xmm7,%xmm7,%xmm7 + movl %ebx,%ebp + addl 56(%esp),%eax + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm2 + vpor %xmm1,%xmm7,%xmm7 + addl %esi,%eax + andl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + vmovdqa 80(%esp),%xmm1 + shrdl $7,%ebx,%ebx + xorl %edx,%ebp + vpxor %xmm2,%xmm7,%xmm7 + movl %eax,%esi + addl 60(%esp),%edi + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpxor %xmm3,%xmm7,%xmm7 + addl %ebp,%edi + andl %ebx,%esi + vmovdqa 112(%esp),%xmm3 + xorl %ecx,%ebx + addl %eax,%edi + vpalignr $8,%xmm6,%xmm7,%xmm2 + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%esi + movl %edi,%ebp + addl (%esp),%edx + vpxor %xmm1,%xmm0,%xmm0 + vmovdqa %xmm4,80(%esp) + xorl %ebx,%eax + shldl $5,%edi,%edi + vmovdqa %xmm3,%xmm4 + vpaddd %xmm7,%xmm3,%xmm3 + addl %esi,%edx + andl %eax,%ebp + vpxor %xmm2,%xmm0,%xmm0 + xorl %ebx,%eax + addl %edi,%edx + shrdl $7,%edi,%edi + xorl %ebx,%ebp + vpsrld $30,%xmm0,%xmm2 + vmovdqa %xmm3,48(%esp) + movl %edx,%esi + addl 4(%esp),%ecx + xorl %eax,%edi + shldl $5,%edx,%edx + vpslld $2,%xmm0,%xmm0 + addl %ebp,%ecx + andl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + movl %ecx,%ebp + addl 8(%esp),%ebx + vpor %xmm2,%xmm0,%xmm0 + xorl %edi,%edx + shldl $5,%ecx,%ecx + vmovdqa 96(%esp),%xmm2 + addl %esi,%ebx + andl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 12(%esp),%eax + xorl %edi,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm7,%xmm0,%xmm3 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm5,96(%esp) + addl %esi,%edi + xorl %ecx,%ebp + vmovdqa %xmm4,%xmm5 + vpaddd %xmm0,%xmm4,%xmm4 + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpxor %xmm3,%xmm1,%xmm1 + addl 20(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + vpsrld $30,%xmm1,%xmm3 + vmovdqa %xmm4,(%esp) + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpslld $2,%xmm1,%xmm1 + addl 24(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vpor %xmm3,%xmm1,%xmm1 + addl 28(%esp),%ebx + xorl %edi,%ebp + vmovdqa 64(%esp),%xmm3 + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpalignr $8,%xmm0,%xmm1,%xmm4 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + vpxor %xmm3,%xmm2,%xmm2 + vmovdqa %xmm6,64(%esp) + addl %esi,%eax + xorl %edx,%ebp + vmovdqa 128(%esp),%xmm6 + vpaddd %xmm1,%xmm5,%xmm5 + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpxor %xmm4,%xmm2,%xmm2 + addl 36(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm4 + vmovdqa %xmm5,16(%esp) + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpslld $2,%xmm2,%xmm2 + addl 40(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + vpor %xmm4,%xmm2,%xmm2 + addl 44(%esp),%ecx + xorl %eax,%ebp + vmovdqa 80(%esp),%xmm4 + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + vpalignr $8,%xmm1,%xmm2,%xmm5 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + vpxor %xmm4,%xmm3,%xmm3 + vmovdqa %xmm7,80(%esp) + addl %esi,%ebx + xorl %edi,%ebp + vmovdqa %xmm6,%xmm7 + vpaddd %xmm2,%xmm6,%xmm6 + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpxor %xmm5,%xmm3,%xmm3 + addl 52(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm5 + vmovdqa %xmm6,32(%esp) + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + addl 56(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpor %xmm5,%xmm3,%xmm3 + addl 60(%esp),%edx + xorl %ebx,%ebp + vmovdqa 96(%esp),%xmm5 + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpalignr $8,%xmm2,%xmm3,%xmm6 + vpxor %xmm0,%xmm4,%xmm4 + addl (%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + vpxor %xmm5,%xmm4,%xmm4 + vmovdqa %xmm0,96(%esp) + addl %esi,%ecx + xorl %eax,%ebp + vmovdqa %xmm7,%xmm0 + vpaddd %xmm3,%xmm7,%xmm7 + shrdl $7,%edi,%edi + addl %edx,%ecx + vpxor %xmm6,%xmm4,%xmm4 + addl 4(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + vpsrld $30,%xmm4,%xmm6 + vmovdqa %xmm7,48(%esp) + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpslld $2,%xmm4,%xmm4 + addl 8(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpor %xmm6,%xmm4,%xmm4 + addl 12(%esp),%edi + xorl %ecx,%ebp + vmovdqa 64(%esp),%xmm6 + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpalignr $8,%xmm3,%xmm4,%xmm7 + vpxor %xmm1,%xmm5,%xmm5 + addl 16(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + vpxor %xmm6,%xmm5,%xmm5 + vmovdqa %xmm1,64(%esp) + addl %esi,%edx + xorl %ebx,%ebp + vmovdqa %xmm0,%xmm1 + vpaddd %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + addl %edi,%edx + vpxor %xmm7,%xmm5,%xmm5 + addl 20(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + vpsrld $30,%xmm5,%xmm7 + vmovdqa %xmm0,(%esp) + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + vpslld $2,%xmm5,%xmm5 + addl 24(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpor %xmm7,%xmm5,%xmm5 + addl 28(%esp),%eax + vmovdqa 80(%esp),%xmm7 + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm4,%xmm5,%xmm0 + vpxor %xmm2,%xmm6,%xmm6 + addl 32(%esp),%edi + andl %ecx,%esi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vpxor %xmm7,%xmm6,%xmm6 + vmovdqa %xmm2,80(%esp) + movl %eax,%ebp + xorl %ecx,%esi + vmovdqa %xmm1,%xmm2 + vpaddd %xmm5,%xmm1,%xmm1 + shldl $5,%eax,%eax + addl %esi,%edi + vpxor %xmm0,%xmm6,%xmm6 + xorl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + addl 36(%esp),%edx + vpsrld $30,%xmm6,%xmm0 + vmovdqa %xmm1,16(%esp) + andl %ebx,%ebp + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %edi,%esi + vpslld $2,%xmm6,%xmm6 + xorl %ebx,%ebp + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %edi,%edx + addl 40(%esp),%ecx + andl %eax,%esi + vpor %xmm0,%xmm6,%xmm6 + xorl %ebx,%eax + shrdl $7,%edi,%edi + vmovdqa 96(%esp),%xmm0 + movl %edx,%ebp + xorl %eax,%esi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + addl 44(%esp),%ebx + andl %edi,%ebp + xorl %eax,%edi + shrdl $7,%edx,%edx + movl %ecx,%esi + xorl %edi,%ebp + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edx,%esi + xorl %edi,%edx + addl %ecx,%ebx + vpalignr $8,%xmm5,%xmm6,%xmm1 + vpxor %xmm3,%xmm7,%xmm7 + addl 48(%esp),%eax + andl %edx,%esi + xorl %edi,%edx + shrdl $7,%ecx,%ecx + vpxor %xmm0,%xmm7,%xmm7 + vmovdqa %xmm3,96(%esp) + movl %ebx,%ebp + xorl %edx,%esi + vmovdqa 144(%esp),%xmm3 + vpaddd %xmm6,%xmm2,%xmm2 + shldl $5,%ebx,%ebx + addl %esi,%eax + vpxor %xmm1,%xmm7,%xmm7 + xorl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%esp),%edi + vpsrld $30,%xmm7,%xmm1 + vmovdqa %xmm2,32(%esp) + andl %ecx,%ebp + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + vpslld $2,%xmm7,%xmm7 + xorl %ecx,%ebp + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%edi + addl 56(%esp),%edx + andl %ebx,%esi + vpor %xmm1,%xmm7,%xmm7 + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vmovdqa 64(%esp),%xmm1 + movl %edi,%ebp + xorl %ebx,%esi + shldl $5,%edi,%edi + addl %esi,%edx + xorl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + addl 60(%esp),%ecx + andl %eax,%ebp + xorl %ebx,%eax + shrdl $7,%edi,%edi + movl %edx,%esi + xorl %eax,%ebp + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + vpalignr $8,%xmm6,%xmm7,%xmm2 + vpxor %xmm4,%xmm0,%xmm0 + addl (%esp),%ebx + andl %edi,%esi + xorl %eax,%edi + shrdl $7,%edx,%edx + vpxor %xmm1,%xmm0,%xmm0 + vmovdqa %xmm4,64(%esp) + movl %ecx,%ebp + xorl %edi,%esi + vmovdqa %xmm3,%xmm4 + vpaddd %xmm7,%xmm3,%xmm3 + shldl $5,%ecx,%ecx + addl %esi,%ebx + vpxor %xmm2,%xmm0,%xmm0 + xorl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 4(%esp),%eax + vpsrld $30,%xmm0,%xmm2 + vmovdqa %xmm3,48(%esp) + andl %edx,%ebp + xorl %edi,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + vpslld $2,%xmm0,%xmm0 + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%esp),%edi + andl %ecx,%esi + vpor %xmm2,%xmm0,%xmm0 + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vmovdqa 80(%esp),%xmm2 + movl %eax,%ebp + xorl %ecx,%esi + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ebx,%ebp + xorl %ecx,%ebx + addl %eax,%edi + addl 12(%esp),%edx + andl %ebx,%ebp + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %edi,%esi + xorl %ebx,%ebp + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %edi,%edx + vpalignr $8,%xmm7,%xmm0,%xmm3 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%esp),%ecx + andl %eax,%esi + xorl %ebx,%eax + shrdl $7,%edi,%edi + vpxor %xmm2,%xmm1,%xmm1 + vmovdqa %xmm5,80(%esp) + movl %edx,%ebp + xorl %eax,%esi + vmovdqa %xmm4,%xmm5 + vpaddd %xmm0,%xmm4,%xmm4 + shldl $5,%edx,%edx + addl %esi,%ecx + vpxor %xmm3,%xmm1,%xmm1 + xorl %edi,%ebp + xorl %eax,%edi + addl %edx,%ecx + addl 20(%esp),%ebx + vpsrld $30,%xmm1,%xmm3 + vmovdqa %xmm4,(%esp) + andl %edi,%ebp + xorl %eax,%edi + shrdl $7,%edx,%edx + movl %ecx,%esi + vpslld $2,%xmm1,%xmm1 + xorl %edi,%ebp + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edx,%esi + xorl %edi,%edx + addl %ecx,%ebx + addl 24(%esp),%eax + andl %edx,%esi + vpor %xmm3,%xmm1,%xmm1 + xorl %edi,%edx + shrdl $7,%ecx,%ecx + vmovdqa 96(%esp),%xmm3 + movl %ebx,%ebp + xorl %edx,%esi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %ecx,%ebp + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%esp),%edi + andl %ecx,%ebp + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + xorl %ecx,%ebp + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%edi + vpalignr $8,%xmm0,%xmm1,%xmm4 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%esp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vpxor %xmm3,%xmm2,%xmm2 + vmovdqa %xmm6,96(%esp) + movl %edi,%ebp + xorl %ebx,%esi + vmovdqa %xmm5,%xmm6 + vpaddd %xmm1,%xmm5,%xmm5 + shldl $5,%edi,%edi + addl %esi,%edx + vpxor %xmm4,%xmm2,%xmm2 + xorl %eax,%ebp + xorl %ebx,%eax + addl %edi,%edx + addl 36(%esp),%ecx + vpsrld $30,%xmm2,%xmm4 + vmovdqa %xmm5,16(%esp) + andl %eax,%ebp + xorl %ebx,%eax + shrdl $7,%edi,%edi + movl %edx,%esi + vpslld $2,%xmm2,%xmm2 + xorl %eax,%ebp + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %edi,%esi + xorl %eax,%edi + addl %edx,%ecx + addl 40(%esp),%ebx + andl %edi,%esi + vpor %xmm4,%xmm2,%xmm2 + xorl %eax,%edi + shrdl $7,%edx,%edx + vmovdqa 64(%esp),%xmm4 + movl %ecx,%ebp + xorl %edi,%esi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edx,%ebp + xorl %edi,%edx + addl %ecx,%ebx + addl 44(%esp),%eax + andl %edx,%ebp + xorl %edi,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%ebp + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + addl %ebx,%eax + vpalignr $8,%xmm1,%xmm2,%xmm5 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + vpxor %xmm4,%xmm3,%xmm3 + vmovdqa %xmm7,64(%esp) + addl %esi,%edi + xorl %ecx,%ebp + vmovdqa %xmm6,%xmm7 + vpaddd %xmm2,%xmm6,%xmm6 + shrdl $7,%ebx,%ebx + addl %eax,%edi + vpxor %xmm5,%xmm3,%xmm3 + addl 52(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + vpsrld $30,%xmm3,%xmm5 + vmovdqa %xmm6,32(%esp) + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + vpslld $2,%xmm3,%xmm3 + addl 56(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vpor %xmm5,%xmm3,%xmm3 + addl 60(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl (%esp),%eax + vpaddd %xmm3,%xmm7,%xmm7 + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + vmovdqa %xmm7,48(%esp) + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 4(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 8(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + addl 12(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + movl 196(%esp),%ebp + cmpl 200(%esp),%ebp + je .L010done + vmovdqa 160(%esp),%xmm7 + vmovdqa 176(%esp),%xmm6 + vmovdqu (%ebp),%xmm0 + vmovdqu 16(%ebp),%xmm1 + vmovdqu 32(%ebp),%xmm2 + vmovdqu 48(%ebp),%xmm3 + addl $64,%ebp + vpshufb %xmm6,%xmm0,%xmm0 + movl %ebp,196(%esp) + vmovdqa %xmm7,96(%esp) + addl 16(%esp),%ebx + xorl %edi,%esi + vpshufb %xmm6,%xmm1,%xmm1 + movl %ecx,%ebp + shldl $5,%ecx,%ecx + vpaddd %xmm7,%xmm0,%xmm4 + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + vmovdqa %xmm4,(%esp) + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + vpshufb %xmm6,%xmm2,%xmm2 + movl %edx,%ebp + shldl $5,%edx,%edx + vpaddd %xmm7,%xmm1,%xmm5 + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + vmovdqa %xmm5,16(%esp) + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + vpshufb %xmm6,%xmm3,%xmm3 + movl %edi,%ebp + shldl $5,%edi,%edi + vpaddd %xmm7,%xmm2,%xmm6 + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + vmovdqa %xmm6,32(%esp) + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + movl 192(%esp),%ebp + addl (%ebp),%eax + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,%ebx + movl %ecx,8(%ebp) + xorl %edx,%ebx + movl %edx,12(%ebp) + movl %edi,16(%ebp) + movl %esi,%ebp + andl %ebx,%esi + movl %ebp,%ebx + jmp .L009loop +.align 16 +.L010done: + addl 16(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 20(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%esp),%edi + xorl %ecx,%esi + movl %eax,%ebp + shldl $5,%eax,%eax + addl %esi,%edi + xorl %ecx,%ebp + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 28(%esp),%edx + xorl %ebx,%ebp + movl %edi,%esi + shldl $5,%edi,%edi + addl %ebp,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %edi,%edx + addl 32(%esp),%ecx + xorl %eax,%esi + movl %edx,%ebp + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%ebp + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 36(%esp),%ebx + xorl %edi,%ebp + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %ebp,%ebx + xorl %edi,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%esp),%eax + xorl %edx,%esi + movl %ebx,%ebp + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%ebp + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%esp),%edi + xorl %ecx,%ebp + movl %eax,%esi + shldl $5,%eax,%eax + addl %ebp,%edi + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%edi + addl 48(%esp),%edx + xorl %ebx,%esi + movl %edi,%ebp + shldl $5,%edi,%edi + addl %esi,%edx + xorl %ebx,%ebp + shrdl $7,%eax,%eax + addl %edi,%edx + addl 52(%esp),%ecx + xorl %eax,%ebp + movl %edx,%esi + shldl $5,%edx,%edx + addl %ebp,%ecx + xorl %eax,%esi + shrdl $7,%edi,%edi + addl %edx,%ecx + addl 56(%esp),%ebx + xorl %edi,%esi + movl %ecx,%ebp + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edi,%ebp + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%esp),%eax + xorl %edx,%ebp + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %ebp,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vzeroall + movl 192(%esp),%ebp + addl (%ebp),%eax + movl 204(%esp),%esp + addl 4(%ebp),%esi + addl 8(%ebp),%ecx + movl %eax,(%ebp) + addl 12(%ebp),%edx + movl %esi,4(%ebp) + addl 16(%ebp),%edi + movl %ecx,8(%ebp) + movl %edx,12(%ebp) + movl %edi,16(%ebp) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size _sha1_block_data_order_avx,.-_sha1_block_data_order_avx +.align 64 +.LK_XX_XX: +.long 1518500249,1518500249,1518500249,1518500249 +.long 1859775393,1859775393,1859775393,1859775393 +.long 2400959708,2400959708,2400959708,2400959708 +.long 3395469782,3395469782,3395469782,3395469782 +.long 66051,67438087,134810123,202182159 +.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115 +.byte 102,111,114,109,32,102,111,114,32,120,56,54,44,32,67,82 +.byte 89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112 +.byte 114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/sha/sha1-armv8.S b/crypto/openssl/crypto/sha/sha1-armv8.S new file mode 100644 index 000000000000..a3cb53020a00 --- /dev/null +++ b/crypto/openssl/crypto/sha/sha1-armv8.S @@ -0,0 +1,1211 @@ +#ifndef __KERNEL__ +# include "arm_arch.h" + +.hidden OPENSSL_armcap_P +#endif + +.text + +.globl sha1_block_data_order +.type sha1_block_data_order,%function +.align 6 +sha1_block_data_order: + adrp x16,OPENSSL_armcap_P + ldr w16,[x16,#:lo12:OPENSSL_armcap_P] + tst w16,#ARMV8_SHA1 + b.ne .Lv8_entry + + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + + ldp w20,w21,[x0] + ldp w22,w23,[x0,#8] + ldr w24,[x0,#16] + +.Loop: + ldr x3,[x1],#64 + movz w28,#0x7999 + sub x2,x2,#1 + movk w28,#0x5a82,lsl#16 +#ifdef __AARCH64EB__ + ror x3,x3,#32 +#else + rev32 x3,x3 +#endif + add w24,w24,w28 // warm it up + add w24,w24,w3 + lsr x4,x3,#32 + ldur x5,[x1,#-56] + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w4 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x5,x5,#32 +#else + rev32 x5,x5 +#endif + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w5 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + lsr x6,x5,#32 + ldur x7,[x1,#-48] + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w6 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x7,x7,#32 +#else + rev32 x7,x7 +#endif + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w7 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + lsr x8,x7,#32 + ldur x9,[x1,#-40] + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + add w24,w24,w8 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x9,x9,#32 +#else + rev32 x9,x9 +#endif + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w9 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + lsr x10,x9,#32 + ldur x11,[x1,#-32] + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w10 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x11,x11,#32 +#else + rev32 x11,x11 +#endif + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w11 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + lsr x12,x11,#32 + ldur x13,[x1,#-24] + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w12 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x13,x13,#32 +#else + rev32 x13,x13 +#endif + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + add w24,w24,w13 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + lsr x14,x13,#32 + ldur x15,[x1,#-16] + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w14 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x15,x15,#32 +#else + rev32 x15,x15 +#endif + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w15 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + lsr x16,x15,#32 + ldur x17,[x1,#-8] + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w16 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) +#ifdef __AARCH64EB__ + ror x17,x17,#32 +#else + rev32 x17,x17 +#endif + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w17 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + lsr x19,x17,#32 + eor w3,w3,w5 + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + eor w3,w3,w11 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + eor w3,w3,w16 + ror w22,w22,#2 + add w24,w24,w19 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + eor w4,w4,w12 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + eor w4,w4,w17 + ror w21,w21,#2 + add w23,w23,w3 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + eor w5,w5,w13 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + eor w5,w5,w19 + ror w20,w20,#2 + add w22,w22,w4 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + eor w6,w6,w14 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + eor w6,w6,w3 + ror w24,w24,#2 + add w21,w21,w5 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + eor w7,w7,w15 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + eor w7,w7,w4 + ror w23,w23,#2 + add w20,w20,w6 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w7,w7,#31 + movz w28,#0xeba1 + movk w28,#0x6ed9,lsl#16 + eor w8,w8,w10 + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + eor w8,w8,w16 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + eor w8,w8,w5 + ror w22,w22,#2 + add w24,w24,w7 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w9,w9,w6 + add w23,w23,w8 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w10,w10,w7 + add w22,w22,w9 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w11,w11,w8 + add w21,w21,w10 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w11,w11,#31 + eor w12,w12,w14 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w12,w12,w9 + add w20,w20,w11 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w12,w12,#31 + eor w13,w13,w15 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w13,w13,w5 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w13,w13,w10 + add w24,w24,w12 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w13,w13,#31 + eor w14,w14,w16 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w14,w14,w6 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w14,w14,w11 + add w23,w23,w13 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w14,w14,#31 + eor w15,w15,w17 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w15,w15,w7 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w15,w15,w12 + add w22,w22,w14 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w15,w15,#31 + eor w16,w16,w19 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w16,w16,w8 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w16,w16,w13 + add w21,w21,w15 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w17,w17,w14 + add w20,w20,w16 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w19,w19,w15 + add w24,w24,w17 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w19,w19,#31 + eor w3,w3,w5 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w3,w3,w11 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w3,w3,w16 + add w23,w23,w19 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w4,w4,w12 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w4,w4,w17 + add w22,w22,w3 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w5,w5,w13 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w5,w5,w19 + add w21,w21,w4 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w6,w6,w14 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w6,w6,w3 + add w20,w20,w5 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w7,w7,w15 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w7,w7,w4 + add w24,w24,w6 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w7,w7,#31 + eor w8,w8,w10 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w8,w8,w16 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w8,w8,w5 + add w23,w23,w7 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w9,w9,w6 + add w22,w22,w8 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w10,w10,w7 + add w21,w21,w9 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w11,w11,w8 + add w20,w20,w10 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w11,w11,#31 + movz w28,#0xbcdc + movk w28,#0x8f1b,lsl#16 + eor w12,w12,w14 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w12,w12,w9 + add w24,w24,w11 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w12,w12,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w13,w13,w15 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w13,w13,w5 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w13,w13,w10 + add w23,w23,w12 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w13,w13,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w14,w14,w16 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w14,w14,w6 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w14,w14,w11 + add w22,w22,w13 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w14,w14,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w15,w15,w17 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w15,w15,w7 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w15,w15,w12 + add w21,w21,w14 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w15,w15,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w16,w16,w19 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w16,w16,w8 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w16,w16,w13 + add w20,w20,w15 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w16,w16,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w17,w17,w3 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w17,w17,w9 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w17,w17,w14 + add w24,w24,w16 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w17,w17,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w19,w19,w4 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w19,w19,w10 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w19,w19,w15 + add w23,w23,w17 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w19,w19,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w3,w3,w5 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w3,w3,w11 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w3,w3,w16 + add w22,w22,w19 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w3,w3,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w4,w4,w6 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w4,w4,w12 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w4,w4,w17 + add w21,w21,w3 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w4,w4,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w5,w5,w7 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w5,w5,w13 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w5,w5,w19 + add w20,w20,w4 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w5,w5,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w6,w6,w8 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w6,w6,w14 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w6,w6,w3 + add w24,w24,w5 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w6,w6,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w7,w7,w9 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w7,w7,w15 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w7,w7,w4 + add w23,w23,w6 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w7,w7,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w8,w8,w10 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w8,w8,w16 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w8,w8,w5 + add w22,w22,w7 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w8,w8,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w9,w9,w11 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w9,w9,w17 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w9,w9,w6 + add w21,w21,w8 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w9,w9,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w10,w10,w12 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w10,w10,w19 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w10,w10,w7 + add w20,w20,w9 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w10,w10,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w11,w11,w13 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w11,w11,w3 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w11,w11,w8 + add w24,w24,w10 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w11,w11,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w12,w12,w14 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w12,w12,w4 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w12,w12,w9 + add w23,w23,w11 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w12,w12,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w13,w13,w15 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w13,w13,w5 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w13,w13,w10 + add w22,w22,w12 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w13,w13,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w14,w14,w16 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w14,w14,w6 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w14,w14,w11 + add w21,w21,w13 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w14,w14,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w15,w15,w17 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w15,w15,w7 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w15,w15,w12 + add w20,w20,w14 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w15,w15,#31 + movz w28,#0xc1d6 + movk w28,#0xca62,lsl#16 + orr w25,w22,w23 + and w26,w22,w23 + eor w16,w16,w19 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w16,w16,w8 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w16,w16,w13 + add w24,w24,w15 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w17,w17,w14 + add w23,w23,w16 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w19,w19,w15 + add w22,w22,w17 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w19,w19,#31 + eor w3,w3,w5 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w3,w3,w11 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w3,w3,w16 + add w21,w21,w19 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w4,w4,w12 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w4,w4,w17 + add w20,w20,w3 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w5,w5,w13 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w5,w5,w19 + add w24,w24,w4 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w6,w6,w14 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w6,w6,w3 + add w23,w23,w5 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w7,w7,w15 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w7,w7,w4 + add w22,w22,w6 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w7,w7,#31 + eor w8,w8,w10 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w8,w8,w16 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w8,w8,w5 + add w21,w21,w7 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w9,w9,w6 + add w20,w20,w8 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w10,w10,w7 + add w24,w24,w9 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w11,w11,w8 + add w23,w23,w10 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w11,w11,#31 + eor w12,w12,w14 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w12,w12,w9 + add w22,w22,w11 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w12,w12,#31 + eor w13,w13,w15 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w13,w13,w5 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w13,w13,w10 + add w21,w21,w12 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w13,w13,#31 + eor w14,w14,w16 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w14,w14,w6 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w14,w14,w11 + add w20,w20,w13 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w14,w14,#31 + eor w15,w15,w17 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w15,w15,w7 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w15,w15,w12 + add w24,w24,w14 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w15,w15,#31 + eor w16,w16,w19 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w16,w16,w8 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w16,w16,w13 + add w23,w23,w15 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w17,w17,w14 + add w22,w22,w16 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w19,w19,w15 + add w21,w21,w17 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w19,w19,#31 + ldp w4,w5,[x0] + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w19 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ldp w6,w7,[x0,#8] + eor w25,w24,w22 + ror w27,w21,#27 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + ldr w8,[x0,#16] + add w20,w20,w25 // e+=F(b,c,d) + add w21,w21,w5 + add w22,w22,w6 + add w20,w20,w4 + add w23,w23,w7 + add w24,w24,w8 + stp w20,w21,[x0] + stp w22,w23,[x0,#8] + str w24,[x0,#16] + cbnz x2,.Loop + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp x25,x26,[sp,#64] + ldp x27,x28,[sp,#80] + ldr x29,[sp],#96 + ret +.size sha1_block_data_order,.-sha1_block_data_order +.type sha1_block_armv8,%function +.align 6 +sha1_block_armv8: +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + adr x4,.Lconst + eor v1.16b,v1.16b,v1.16b + ld1 {v0.4s},[x0],#16 + ld1 {v1.s}[0],[x0] + sub x0,x0,#16 + ld1 {v16.4s,v17.4s,v18.4s,v19.4s},[x4] + +.Loop_hw: + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + sub x2,x2,#1 + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + + add v20.4s,v16.4s,v4.4s + rev32 v6.16b,v6.16b + orr v22.16b,v0.16b,v0.16b // offload + + add v21.4s,v16.4s,v5.4s + rev32 v7.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b +.inst 0x5e140020 //sha1c v0.16b,v1.16b,v20.4s // 0 + add v20.4s,v16.4s,v6.4s +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 1 +.inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s + add v21.4s,v16.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 2 +.inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s + add v20.4s,v16.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 3 +.inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 4 +.inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s + add v20.4s,v17.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 5 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 6 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v17.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 7 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 8 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 9 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v18.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 10 +.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 11 +.inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s + add v21.4s,v18.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 12 +.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 13 +.inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v7.4s +.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b +.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 14 +.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v19.4s,v4.4s +.inst 0x5e281885 //sha1su1 v5.16b,v4.16b +.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 15 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v5.4s +.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b +.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 16 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v19.4s,v6.4s +.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 17 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v7.4s + +.inst 0x5e280803 //sha1h v3.16b,v0.16b // 18 +.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + +.inst 0x5e280802 //sha1h v2.16b,v0.16b // 19 +.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + + add v1.4s,v1.4s,v2.4s + add v0.4s,v0.4s,v22.4s + + cbnz x2,.Loop_hw + + st1 {v0.4s},[x0],#16 + st1 {v1.s}[0],[x0] + + ldr x29,[sp],#16 + ret +.size sha1_block_armv8,.-sha1_block_armv8 +.align 6 +.Lconst: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 //K_00_19 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59 +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79 +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 diff --git a/crypto/openssl/crypto/sha/sha1-mb-x86_64.S b/crypto/openssl/crypto/sha/sha1-mb-x86_64.S new file mode 100644 index 000000000000..b835e0b6c959 --- /dev/null +++ b/crypto/openssl/crypto/sha/sha1-mb-x86_64.S @@ -0,0 +1,7324 @@ +.text + + + +.globl sha1_multi_block +.type sha1_multi_block,@function +.align 32 +sha1_multi_block: +.cfi_startproc + movq OPENSSL_ia32cap_P+4(%rip),%rcx + btq $61,%rcx + jc _shaext_shortcut + testl $268435456,%ecx + jnz _avx_shortcut + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbx,-24 + subq $288,%rsp + andq $-256,%rsp + movq %rax,272(%rsp) +.cfi_escape 0x0f,0x06,0x77,0x90,0x02,0x06,0x23,0x08 +.Lbody: + leaq K_XX_XX(%rip),%rbp + leaq 256(%rsp),%rbx + +.Loop_grande: + movl %edx,280(%rsp) + xorl %edx,%edx + + movq 0(%rsi),%r8 + + movl 8(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,0(%rbx) + cmovleq %rbp,%r8 + + movq 16(%rsi),%r9 + + movl 24(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,4(%rbx) + cmovleq %rbp,%r9 + + movq 32(%rsi),%r10 + + movl 40(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,8(%rbx) + cmovleq %rbp,%r10 + + movq 48(%rsi),%r11 + + movl 56(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,12(%rbx) + cmovleq %rbp,%r11 + testl %edx,%edx + jz .Ldone + + movdqu 0(%rdi),%xmm10 + leaq 128(%rsp),%rax + movdqu 32(%rdi),%xmm11 + movdqu 64(%rdi),%xmm12 + movdqu 96(%rdi),%xmm13 + movdqu 128(%rdi),%xmm14 + movdqa 96(%rbp),%xmm5 + movdqa -32(%rbp),%xmm15 + jmp .Loop + +.align 32 +.Loop: + movd (%r8),%xmm0 + leaq 64(%r8),%r8 + movd (%r9),%xmm2 + leaq 64(%r9),%r9 + movd (%r10),%xmm3 + leaq 64(%r10),%r10 + movd (%r11),%xmm4 + leaq 64(%r11),%r11 + punpckldq %xmm3,%xmm0 + movd -60(%r8),%xmm1 + punpckldq %xmm4,%xmm2 + movd -60(%r9),%xmm9 + punpckldq %xmm2,%xmm0 + movd -60(%r10),%xmm8 +.byte 102,15,56,0,197 + movd -60(%r11),%xmm7 + punpckldq %xmm8,%xmm1 + movdqa %xmm10,%xmm8 + paddd %xmm15,%xmm14 + punpckldq %xmm7,%xmm9 + movdqa %xmm11,%xmm7 + movdqa %xmm11,%xmm6 + pslld $5,%xmm8 + pandn %xmm13,%xmm7 + pand %xmm12,%xmm6 + punpckldq %xmm9,%xmm1 + movdqa %xmm10,%xmm9 + + movdqa %xmm0,0-128(%rax) + paddd %xmm0,%xmm14 + movd -56(%r8),%xmm2 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm11,%xmm7 + + por %xmm9,%xmm8 + movd -56(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm14 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 +.byte 102,15,56,0,205 + movd -56(%r10),%xmm8 + por %xmm7,%xmm11 + movd -56(%r11),%xmm7 + punpckldq %xmm8,%xmm2 + movdqa %xmm14,%xmm8 + paddd %xmm15,%xmm13 + punpckldq %xmm7,%xmm9 + movdqa %xmm10,%xmm7 + movdqa %xmm10,%xmm6 + pslld $5,%xmm8 + pandn %xmm12,%xmm7 + pand %xmm11,%xmm6 + punpckldq %xmm9,%xmm2 + movdqa %xmm14,%xmm9 + + movdqa %xmm1,16-128(%rax) + paddd %xmm1,%xmm13 + movd -52(%r8),%xmm3 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm10,%xmm7 + + por %xmm9,%xmm8 + movd -52(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm13 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 +.byte 102,15,56,0,213 + movd -52(%r10),%xmm8 + por %xmm7,%xmm10 + movd -52(%r11),%xmm7 + punpckldq %xmm8,%xmm3 + movdqa %xmm13,%xmm8 + paddd %xmm15,%xmm12 + punpckldq %xmm7,%xmm9 + movdqa %xmm14,%xmm7 + movdqa %xmm14,%xmm6 + pslld $5,%xmm8 + pandn %xmm11,%xmm7 + pand %xmm10,%xmm6 + punpckldq %xmm9,%xmm3 + movdqa %xmm13,%xmm9 + + movdqa %xmm2,32-128(%rax) + paddd %xmm2,%xmm12 + movd -48(%r8),%xmm4 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm14,%xmm7 + + por %xmm9,%xmm8 + movd -48(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm12 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 +.byte 102,15,56,0,221 + movd -48(%r10),%xmm8 + por %xmm7,%xmm14 + movd -48(%r11),%xmm7 + punpckldq %xmm8,%xmm4 + movdqa %xmm12,%xmm8 + paddd %xmm15,%xmm11 + punpckldq %xmm7,%xmm9 + movdqa %xmm13,%xmm7 + movdqa %xmm13,%xmm6 + pslld $5,%xmm8 + pandn %xmm10,%xmm7 + pand %xmm14,%xmm6 + punpckldq %xmm9,%xmm4 + movdqa %xmm12,%xmm9 + + movdqa %xmm3,48-128(%rax) + paddd %xmm3,%xmm11 + movd -44(%r8),%xmm0 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm13,%xmm7 + + por %xmm9,%xmm8 + movd -44(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm11 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 +.byte 102,15,56,0,229 + movd -44(%r10),%xmm8 + por %xmm7,%xmm13 + movd -44(%r11),%xmm7 + punpckldq %xmm8,%xmm0 + movdqa %xmm11,%xmm8 + paddd %xmm15,%xmm10 + punpckldq %xmm7,%xmm9 + movdqa %xmm12,%xmm7 + movdqa %xmm12,%xmm6 + pslld $5,%xmm8 + pandn %xmm14,%xmm7 + pand %xmm13,%xmm6 + punpckldq %xmm9,%xmm0 + movdqa %xmm11,%xmm9 + + movdqa %xmm4,64-128(%rax) + paddd %xmm4,%xmm10 + movd -40(%r8),%xmm1 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm12,%xmm7 + + por %xmm9,%xmm8 + movd -40(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm10 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 +.byte 102,15,56,0,197 + movd -40(%r10),%xmm8 + por %xmm7,%xmm12 + movd -40(%r11),%xmm7 + punpckldq %xmm8,%xmm1 + movdqa %xmm10,%xmm8 + paddd %xmm15,%xmm14 + punpckldq %xmm7,%xmm9 + movdqa %xmm11,%xmm7 + movdqa %xmm11,%xmm6 + pslld $5,%xmm8 + pandn %xmm13,%xmm7 + pand %xmm12,%xmm6 + punpckldq %xmm9,%xmm1 + movdqa %xmm10,%xmm9 + + movdqa %xmm0,80-128(%rax) + paddd %xmm0,%xmm14 + movd -36(%r8),%xmm2 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm11,%xmm7 + + por %xmm9,%xmm8 + movd -36(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm14 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 +.byte 102,15,56,0,205 + movd -36(%r10),%xmm8 + por %xmm7,%xmm11 + movd -36(%r11),%xmm7 + punpckldq %xmm8,%xmm2 + movdqa %xmm14,%xmm8 + paddd %xmm15,%xmm13 + punpckldq %xmm7,%xmm9 + movdqa %xmm10,%xmm7 + movdqa %xmm10,%xmm6 + pslld $5,%xmm8 + pandn %xmm12,%xmm7 + pand %xmm11,%xmm6 + punpckldq %xmm9,%xmm2 + movdqa %xmm14,%xmm9 + + movdqa %xmm1,96-128(%rax) + paddd %xmm1,%xmm13 + movd -32(%r8),%xmm3 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm10,%xmm7 + + por %xmm9,%xmm8 + movd -32(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm13 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 +.byte 102,15,56,0,213 + movd -32(%r10),%xmm8 + por %xmm7,%xmm10 + movd -32(%r11),%xmm7 + punpckldq %xmm8,%xmm3 + movdqa %xmm13,%xmm8 + paddd %xmm15,%xmm12 + punpckldq %xmm7,%xmm9 + movdqa %xmm14,%xmm7 + movdqa %xmm14,%xmm6 + pslld $5,%xmm8 + pandn %xmm11,%xmm7 + pand %xmm10,%xmm6 + punpckldq %xmm9,%xmm3 + movdqa %xmm13,%xmm9 + + movdqa %xmm2,112-128(%rax) + paddd %xmm2,%xmm12 + movd -28(%r8),%xmm4 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm14,%xmm7 + + por %xmm9,%xmm8 + movd -28(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm12 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 +.byte 102,15,56,0,221 + movd -28(%r10),%xmm8 + por %xmm7,%xmm14 + movd -28(%r11),%xmm7 + punpckldq %xmm8,%xmm4 + movdqa %xmm12,%xmm8 + paddd %xmm15,%xmm11 + punpckldq %xmm7,%xmm9 + movdqa %xmm13,%xmm7 + movdqa %xmm13,%xmm6 + pslld $5,%xmm8 + pandn %xmm10,%xmm7 + pand %xmm14,%xmm6 + punpckldq %xmm9,%xmm4 + movdqa %xmm12,%xmm9 + + movdqa %xmm3,128-128(%rax) + paddd %xmm3,%xmm11 + movd -24(%r8),%xmm0 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm13,%xmm7 + + por %xmm9,%xmm8 + movd -24(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm11 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 +.byte 102,15,56,0,229 + movd -24(%r10),%xmm8 + por %xmm7,%xmm13 + movd -24(%r11),%xmm7 + punpckldq %xmm8,%xmm0 + movdqa %xmm11,%xmm8 + paddd %xmm15,%xmm10 + punpckldq %xmm7,%xmm9 + movdqa %xmm12,%xmm7 + movdqa %xmm12,%xmm6 + pslld $5,%xmm8 + pandn %xmm14,%xmm7 + pand %xmm13,%xmm6 + punpckldq %xmm9,%xmm0 + movdqa %xmm11,%xmm9 + + movdqa %xmm4,144-128(%rax) + paddd %xmm4,%xmm10 + movd -20(%r8),%xmm1 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm12,%xmm7 + + por %xmm9,%xmm8 + movd -20(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm10 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 +.byte 102,15,56,0,197 + movd -20(%r10),%xmm8 + por %xmm7,%xmm12 + movd -20(%r11),%xmm7 + punpckldq %xmm8,%xmm1 + movdqa %xmm10,%xmm8 + paddd %xmm15,%xmm14 + punpckldq %xmm7,%xmm9 + movdqa %xmm11,%xmm7 + movdqa %xmm11,%xmm6 + pslld $5,%xmm8 + pandn %xmm13,%xmm7 + pand %xmm12,%xmm6 + punpckldq %xmm9,%xmm1 + movdqa %xmm10,%xmm9 + + movdqa %xmm0,160-128(%rax) + paddd %xmm0,%xmm14 + movd -16(%r8),%xmm2 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm11,%xmm7 + + por %xmm9,%xmm8 + movd -16(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm14 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 +.byte 102,15,56,0,205 + movd -16(%r10),%xmm8 + por %xmm7,%xmm11 + movd -16(%r11),%xmm7 + punpckldq %xmm8,%xmm2 + movdqa %xmm14,%xmm8 + paddd %xmm15,%xmm13 + punpckldq %xmm7,%xmm9 + movdqa %xmm10,%xmm7 + movdqa %xmm10,%xmm6 + pslld $5,%xmm8 + pandn %xmm12,%xmm7 + pand %xmm11,%xmm6 + punpckldq %xmm9,%xmm2 + movdqa %xmm14,%xmm9 + + movdqa %xmm1,176-128(%rax) + paddd %xmm1,%xmm13 + movd -12(%r8),%xmm3 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm10,%xmm7 + + por %xmm9,%xmm8 + movd -12(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm13 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 +.byte 102,15,56,0,213 + movd -12(%r10),%xmm8 + por %xmm7,%xmm10 + movd -12(%r11),%xmm7 + punpckldq %xmm8,%xmm3 + movdqa %xmm13,%xmm8 + paddd %xmm15,%xmm12 + punpckldq %xmm7,%xmm9 + movdqa %xmm14,%xmm7 + movdqa %xmm14,%xmm6 + pslld $5,%xmm8 + pandn %xmm11,%xmm7 + pand %xmm10,%xmm6 + punpckldq %xmm9,%xmm3 + movdqa %xmm13,%xmm9 + + movdqa %xmm2,192-128(%rax) + paddd %xmm2,%xmm12 + movd -8(%r8),%xmm4 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm14,%xmm7 + + por %xmm9,%xmm8 + movd -8(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm12 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 +.byte 102,15,56,0,221 + movd -8(%r10),%xmm8 + por %xmm7,%xmm14 + movd -8(%r11),%xmm7 + punpckldq %xmm8,%xmm4 + movdqa %xmm12,%xmm8 + paddd %xmm15,%xmm11 + punpckldq %xmm7,%xmm9 + movdqa %xmm13,%xmm7 + movdqa %xmm13,%xmm6 + pslld $5,%xmm8 + pandn %xmm10,%xmm7 + pand %xmm14,%xmm6 + punpckldq %xmm9,%xmm4 + movdqa %xmm12,%xmm9 + + movdqa %xmm3,208-128(%rax) + paddd %xmm3,%xmm11 + movd -4(%r8),%xmm0 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm13,%xmm7 + + por %xmm9,%xmm8 + movd -4(%r9),%xmm9 + pslld $30,%xmm7 + paddd %xmm6,%xmm11 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 +.byte 102,15,56,0,229 + movd -4(%r10),%xmm8 + por %xmm7,%xmm13 + movdqa 0-128(%rax),%xmm1 + movd -4(%r11),%xmm7 + punpckldq %xmm8,%xmm0 + movdqa %xmm11,%xmm8 + paddd %xmm15,%xmm10 + punpckldq %xmm7,%xmm9 + movdqa %xmm12,%xmm7 + movdqa %xmm12,%xmm6 + pslld $5,%xmm8 + prefetcht0 63(%r8) + pandn %xmm14,%xmm7 + pand %xmm13,%xmm6 + punpckldq %xmm9,%xmm0 + movdqa %xmm11,%xmm9 + + movdqa %xmm4,224-128(%rax) + paddd %xmm4,%xmm10 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + movdqa %xmm12,%xmm7 + prefetcht0 63(%r9) + + por %xmm9,%xmm8 + pslld $30,%xmm7 + paddd %xmm6,%xmm10 + prefetcht0 63(%r10) + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 +.byte 102,15,56,0,197 + prefetcht0 63(%r11) + por %xmm7,%xmm12 + movdqa 16-128(%rax),%xmm2 + pxor %xmm3,%xmm1 + movdqa 32-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + pxor 128-128(%rax),%xmm1 + paddd %xmm15,%xmm14 + movdqa %xmm11,%xmm7 + pslld $5,%xmm8 + pxor %xmm3,%xmm1 + movdqa %xmm11,%xmm6 + pandn %xmm13,%xmm7 + movdqa %xmm1,%xmm5 + pand %xmm12,%xmm6 + movdqa %xmm10,%xmm9 + psrld $31,%xmm5 + paddd %xmm1,%xmm1 + + movdqa %xmm0,240-128(%rax) + paddd %xmm0,%xmm14 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + + movdqa %xmm11,%xmm7 + por %xmm9,%xmm8 + pslld $30,%xmm7 + paddd %xmm6,%xmm14 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 48-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + pxor 144-128(%rax),%xmm2 + paddd %xmm15,%xmm13 + movdqa %xmm10,%xmm7 + pslld $5,%xmm8 + pxor %xmm4,%xmm2 + movdqa %xmm10,%xmm6 + pandn %xmm12,%xmm7 + movdqa %xmm2,%xmm5 + pand %xmm11,%xmm6 + movdqa %xmm14,%xmm9 + psrld $31,%xmm5 + paddd %xmm2,%xmm2 + + movdqa %xmm1,0-128(%rax) + paddd %xmm1,%xmm13 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + + movdqa %xmm10,%xmm7 + por %xmm9,%xmm8 + pslld $30,%xmm7 + paddd %xmm6,%xmm13 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 64-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + pxor 160-128(%rax),%xmm3 + paddd %xmm15,%xmm12 + movdqa %xmm14,%xmm7 + pslld $5,%xmm8 + pxor %xmm0,%xmm3 + movdqa %xmm14,%xmm6 + pandn %xmm11,%xmm7 + movdqa %xmm3,%xmm5 + pand %xmm10,%xmm6 + movdqa %xmm13,%xmm9 + psrld $31,%xmm5 + paddd %xmm3,%xmm3 + + movdqa %xmm2,16-128(%rax) + paddd %xmm2,%xmm12 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + + movdqa %xmm14,%xmm7 + por %xmm9,%xmm8 + pslld $30,%xmm7 + paddd %xmm6,%xmm12 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 80-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + pxor 176-128(%rax),%xmm4 + paddd %xmm15,%xmm11 + movdqa %xmm13,%xmm7 + pslld $5,%xmm8 + pxor %xmm1,%xmm4 + movdqa %xmm13,%xmm6 + pandn %xmm10,%xmm7 + movdqa %xmm4,%xmm5 + pand %xmm14,%xmm6 + movdqa %xmm12,%xmm9 + psrld $31,%xmm5 + paddd %xmm4,%xmm4 + + movdqa %xmm3,32-128(%rax) + paddd %xmm3,%xmm11 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + + movdqa %xmm13,%xmm7 + por %xmm9,%xmm8 + pslld $30,%xmm7 + paddd %xmm6,%xmm11 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 96-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + pxor 192-128(%rax),%xmm0 + paddd %xmm15,%xmm10 + movdqa %xmm12,%xmm7 + pslld $5,%xmm8 + pxor %xmm2,%xmm0 + movdqa %xmm12,%xmm6 + pandn %xmm14,%xmm7 + movdqa %xmm0,%xmm5 + pand %xmm13,%xmm6 + movdqa %xmm11,%xmm9 + psrld $31,%xmm5 + paddd %xmm0,%xmm0 + + movdqa %xmm4,48-128(%rax) + paddd %xmm4,%xmm10 + psrld $27,%xmm9 + pxor %xmm7,%xmm6 + + movdqa %xmm12,%xmm7 + por %xmm9,%xmm8 + pslld $30,%xmm7 + paddd %xmm6,%xmm10 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + movdqa 0(%rbp),%xmm15 + pxor %xmm3,%xmm1 + movdqa 112-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm6 + pxor 208-128(%rax),%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + pxor %xmm11,%xmm6 + + movdqa %xmm10,%xmm9 + movdqa %xmm0,64-128(%rax) + paddd %xmm0,%xmm14 + pxor %xmm3,%xmm1 + psrld $27,%xmm9 + pxor %xmm12,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm1,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm14 + paddd %xmm1,%xmm1 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 128-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm6 + pxor 224-128(%rax),%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + pxor %xmm10,%xmm6 + + movdqa %xmm14,%xmm9 + movdqa %xmm1,80-128(%rax) + paddd %xmm1,%xmm13 + pxor %xmm4,%xmm2 + psrld $27,%xmm9 + pxor %xmm11,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm2,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm13 + paddd %xmm2,%xmm2 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 144-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm6 + pxor 240-128(%rax),%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + pxor %xmm14,%xmm6 + + movdqa %xmm13,%xmm9 + movdqa %xmm2,96-128(%rax) + paddd %xmm2,%xmm12 + pxor %xmm0,%xmm3 + psrld $27,%xmm9 + pxor %xmm10,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm3,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm12 + paddd %xmm3,%xmm3 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 160-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm6 + pxor 0-128(%rax),%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + pxor %xmm13,%xmm6 + + movdqa %xmm12,%xmm9 + movdqa %xmm3,112-128(%rax) + paddd %xmm3,%xmm11 + pxor %xmm1,%xmm4 + psrld $27,%xmm9 + pxor %xmm14,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm4,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm11 + paddd %xmm4,%xmm4 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 176-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + movdqa %xmm14,%xmm6 + pxor 16-128(%rax),%xmm0 + paddd %xmm15,%xmm10 + pslld $5,%xmm8 + pxor %xmm12,%xmm6 + + movdqa %xmm11,%xmm9 + movdqa %xmm4,128-128(%rax) + paddd %xmm4,%xmm10 + pxor %xmm2,%xmm0 + psrld $27,%xmm9 + pxor %xmm13,%xmm6 + movdqa %xmm12,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm0,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm10 + paddd %xmm0,%xmm0 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + pxor %xmm3,%xmm1 + movdqa 192-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm6 + pxor 32-128(%rax),%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + pxor %xmm11,%xmm6 + + movdqa %xmm10,%xmm9 + movdqa %xmm0,144-128(%rax) + paddd %xmm0,%xmm14 + pxor %xmm3,%xmm1 + psrld $27,%xmm9 + pxor %xmm12,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm1,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm14 + paddd %xmm1,%xmm1 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 208-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm6 + pxor 48-128(%rax),%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + pxor %xmm10,%xmm6 + + movdqa %xmm14,%xmm9 + movdqa %xmm1,160-128(%rax) + paddd %xmm1,%xmm13 + pxor %xmm4,%xmm2 + psrld $27,%xmm9 + pxor %xmm11,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm2,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm13 + paddd %xmm2,%xmm2 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 224-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm6 + pxor 64-128(%rax),%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + pxor %xmm14,%xmm6 + + movdqa %xmm13,%xmm9 + movdqa %xmm2,176-128(%rax) + paddd %xmm2,%xmm12 + pxor %xmm0,%xmm3 + psrld $27,%xmm9 + pxor %xmm10,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm3,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm12 + paddd %xmm3,%xmm3 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 240-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm6 + pxor 80-128(%rax),%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + pxor %xmm13,%xmm6 + + movdqa %xmm12,%xmm9 + movdqa %xmm3,192-128(%rax) + paddd %xmm3,%xmm11 + pxor %xmm1,%xmm4 + psrld $27,%xmm9 + pxor %xmm14,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm4,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm11 + paddd %xmm4,%xmm4 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 0-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + movdqa %xmm14,%xmm6 + pxor 96-128(%rax),%xmm0 + paddd %xmm15,%xmm10 + pslld $5,%xmm8 + pxor %xmm12,%xmm6 + + movdqa %xmm11,%xmm9 + movdqa %xmm4,208-128(%rax) + paddd %xmm4,%xmm10 + pxor %xmm2,%xmm0 + psrld $27,%xmm9 + pxor %xmm13,%xmm6 + movdqa %xmm12,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm0,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm10 + paddd %xmm0,%xmm0 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + pxor %xmm3,%xmm1 + movdqa 16-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm6 + pxor 112-128(%rax),%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + pxor %xmm11,%xmm6 + + movdqa %xmm10,%xmm9 + movdqa %xmm0,224-128(%rax) + paddd %xmm0,%xmm14 + pxor %xmm3,%xmm1 + psrld $27,%xmm9 + pxor %xmm12,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm1,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm14 + paddd %xmm1,%xmm1 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 32-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm6 + pxor 128-128(%rax),%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + pxor %xmm10,%xmm6 + + movdqa %xmm14,%xmm9 + movdqa %xmm1,240-128(%rax) + paddd %xmm1,%xmm13 + pxor %xmm4,%xmm2 + psrld $27,%xmm9 + pxor %xmm11,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm2,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm13 + paddd %xmm2,%xmm2 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 48-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm6 + pxor 144-128(%rax),%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + pxor %xmm14,%xmm6 + + movdqa %xmm13,%xmm9 + movdqa %xmm2,0-128(%rax) + paddd %xmm2,%xmm12 + pxor %xmm0,%xmm3 + psrld $27,%xmm9 + pxor %xmm10,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm3,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm12 + paddd %xmm3,%xmm3 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 64-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm6 + pxor 160-128(%rax),%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + pxor %xmm13,%xmm6 + + movdqa %xmm12,%xmm9 + movdqa %xmm3,16-128(%rax) + paddd %xmm3,%xmm11 + pxor %xmm1,%xmm4 + psrld $27,%xmm9 + pxor %xmm14,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm4,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm11 + paddd %xmm4,%xmm4 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 80-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + movdqa %xmm14,%xmm6 + pxor 176-128(%rax),%xmm0 + paddd %xmm15,%xmm10 + pslld $5,%xmm8 + pxor %xmm12,%xmm6 + + movdqa %xmm11,%xmm9 + movdqa %xmm4,32-128(%rax) + paddd %xmm4,%xmm10 + pxor %xmm2,%xmm0 + psrld $27,%xmm9 + pxor %xmm13,%xmm6 + movdqa %xmm12,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm0,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm10 + paddd %xmm0,%xmm0 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + pxor %xmm3,%xmm1 + movdqa 96-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm6 + pxor 192-128(%rax),%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + pxor %xmm11,%xmm6 + + movdqa %xmm10,%xmm9 + movdqa %xmm0,48-128(%rax) + paddd %xmm0,%xmm14 + pxor %xmm3,%xmm1 + psrld $27,%xmm9 + pxor %xmm12,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm1,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm14 + paddd %xmm1,%xmm1 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 112-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm6 + pxor 208-128(%rax),%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + pxor %xmm10,%xmm6 + + movdqa %xmm14,%xmm9 + movdqa %xmm1,64-128(%rax) + paddd %xmm1,%xmm13 + pxor %xmm4,%xmm2 + psrld $27,%xmm9 + pxor %xmm11,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm2,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm13 + paddd %xmm2,%xmm2 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 128-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm6 + pxor 224-128(%rax),%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + pxor %xmm14,%xmm6 + + movdqa %xmm13,%xmm9 + movdqa %xmm2,80-128(%rax) + paddd %xmm2,%xmm12 + pxor %xmm0,%xmm3 + psrld $27,%xmm9 + pxor %xmm10,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm3,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm12 + paddd %xmm3,%xmm3 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 144-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm6 + pxor 240-128(%rax),%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + pxor %xmm13,%xmm6 + + movdqa %xmm12,%xmm9 + movdqa %xmm3,96-128(%rax) + paddd %xmm3,%xmm11 + pxor %xmm1,%xmm4 + psrld $27,%xmm9 + pxor %xmm14,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm4,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm11 + paddd %xmm4,%xmm4 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 160-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + movdqa %xmm14,%xmm6 + pxor 0-128(%rax),%xmm0 + paddd %xmm15,%xmm10 + pslld $5,%xmm8 + pxor %xmm12,%xmm6 + + movdqa %xmm11,%xmm9 + movdqa %xmm4,112-128(%rax) + paddd %xmm4,%xmm10 + pxor %xmm2,%xmm0 + psrld $27,%xmm9 + pxor %xmm13,%xmm6 + movdqa %xmm12,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm0,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm10 + paddd %xmm0,%xmm0 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + movdqa 32(%rbp),%xmm15 + pxor %xmm3,%xmm1 + movdqa 176-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm7 + pxor 16-128(%rax),%xmm1 + pxor %xmm3,%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + movdqa %xmm10,%xmm9 + pand %xmm12,%xmm7 + + movdqa %xmm13,%xmm6 + movdqa %xmm1,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm14 + pxor %xmm12,%xmm6 + + movdqa %xmm0,128-128(%rax) + paddd %xmm0,%xmm14 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm11,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + paddd %xmm1,%xmm1 + paddd %xmm6,%xmm14 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 192-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm7 + pxor 32-128(%rax),%xmm2 + pxor %xmm4,%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + movdqa %xmm14,%xmm9 + pand %xmm11,%xmm7 + + movdqa %xmm12,%xmm6 + movdqa %xmm2,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm13 + pxor %xmm11,%xmm6 + + movdqa %xmm1,144-128(%rax) + paddd %xmm1,%xmm13 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm10,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + paddd %xmm2,%xmm2 + paddd %xmm6,%xmm13 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 208-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm7 + pxor 48-128(%rax),%xmm3 + pxor %xmm0,%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + movdqa %xmm13,%xmm9 + pand %xmm10,%xmm7 + + movdqa %xmm11,%xmm6 + movdqa %xmm3,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm12 + pxor %xmm10,%xmm6 + + movdqa %xmm2,160-128(%rax) + paddd %xmm2,%xmm12 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm14,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + paddd %xmm3,%xmm3 + paddd %xmm6,%xmm12 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 224-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm7 + pxor 64-128(%rax),%xmm4 + pxor %xmm1,%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + movdqa %xmm12,%xmm9 + pand %xmm14,%xmm7 + + movdqa %xmm10,%xmm6 + movdqa %xmm4,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm11 + pxor %xmm14,%xmm6 + + movdqa %xmm3,176-128(%rax) + paddd %xmm3,%xmm11 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm13,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + paddd %xmm4,%xmm4 + paddd %xmm6,%xmm11 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 240-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + movdqa %xmm14,%xmm7 + pxor 80-128(%rax),%xmm0 + pxor %xmm2,%xmm0 + paddd %xmm15,%xmm10 + pslld $5,%xmm8 + movdqa %xmm11,%xmm9 + pand %xmm13,%xmm7 + + movdqa %xmm14,%xmm6 + movdqa %xmm0,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm10 + pxor %xmm13,%xmm6 + + movdqa %xmm4,192-128(%rax) + paddd %xmm4,%xmm10 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm12,%xmm6 + movdqa %xmm12,%xmm7 + + pslld $30,%xmm7 + paddd %xmm0,%xmm0 + paddd %xmm6,%xmm10 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + pxor %xmm3,%xmm1 + movdqa 0-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm7 + pxor 96-128(%rax),%xmm1 + pxor %xmm3,%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + movdqa %xmm10,%xmm9 + pand %xmm12,%xmm7 + + movdqa %xmm13,%xmm6 + movdqa %xmm1,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm14 + pxor %xmm12,%xmm6 + + movdqa %xmm0,208-128(%rax) + paddd %xmm0,%xmm14 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm11,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + paddd %xmm1,%xmm1 + paddd %xmm6,%xmm14 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 16-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm7 + pxor 112-128(%rax),%xmm2 + pxor %xmm4,%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + movdqa %xmm14,%xmm9 + pand %xmm11,%xmm7 + + movdqa %xmm12,%xmm6 + movdqa %xmm2,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm13 + pxor %xmm11,%xmm6 + + movdqa %xmm1,224-128(%rax) + paddd %xmm1,%xmm13 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm10,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + paddd %xmm2,%xmm2 + paddd %xmm6,%xmm13 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 32-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm7 + pxor 128-128(%rax),%xmm3 + pxor %xmm0,%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + movdqa %xmm13,%xmm9 + pand %xmm10,%xmm7 + + movdqa %xmm11,%xmm6 + movdqa %xmm3,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm12 + pxor %xmm10,%xmm6 + + movdqa %xmm2,240-128(%rax) + paddd %xmm2,%xmm12 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm14,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + paddd %xmm3,%xmm3 + paddd %xmm6,%xmm12 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 48-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm7 + pxor 144-128(%rax),%xmm4 + pxor %xmm1,%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + movdqa %xmm12,%xmm9 + pand %xmm14,%xmm7 + + movdqa %xmm10,%xmm6 + movdqa %xmm4,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm11 + pxor %xmm14,%xmm6 + + movdqa %xmm3,0-128(%rax) + paddd %xmm3,%xmm11 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm13,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + paddd %xmm4,%xmm4 + paddd %xmm6,%xmm11 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 64-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + movdqa %xmm14,%xmm7 + pxor 160-128(%rax),%xmm0 + pxor %xmm2,%xmm0 + paddd %xmm15,%xmm10 + pslld $5,%xmm8 + movdqa %xmm11,%xmm9 + pand %xmm13,%xmm7 + + movdqa %xmm14,%xmm6 + movdqa %xmm0,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm10 + pxor %xmm13,%xmm6 + + movdqa %xmm4,16-128(%rax) + paddd %xmm4,%xmm10 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm12,%xmm6 + movdqa %xmm12,%xmm7 + + pslld $30,%xmm7 + paddd %xmm0,%xmm0 + paddd %xmm6,%xmm10 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + pxor %xmm3,%xmm1 + movdqa 80-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm7 + pxor 176-128(%rax),%xmm1 + pxor %xmm3,%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + movdqa %xmm10,%xmm9 + pand %xmm12,%xmm7 + + movdqa %xmm13,%xmm6 + movdqa %xmm1,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm14 + pxor %xmm12,%xmm6 + + movdqa %xmm0,32-128(%rax) + paddd %xmm0,%xmm14 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm11,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + paddd %xmm1,%xmm1 + paddd %xmm6,%xmm14 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 96-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm7 + pxor 192-128(%rax),%xmm2 + pxor %xmm4,%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + movdqa %xmm14,%xmm9 + pand %xmm11,%xmm7 + + movdqa %xmm12,%xmm6 + movdqa %xmm2,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm13 + pxor %xmm11,%xmm6 + + movdqa %xmm1,48-128(%rax) + paddd %xmm1,%xmm13 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm10,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + paddd %xmm2,%xmm2 + paddd %xmm6,%xmm13 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 112-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm7 + pxor 208-128(%rax),%xmm3 + pxor %xmm0,%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + movdqa %xmm13,%xmm9 + pand %xmm10,%xmm7 + + movdqa %xmm11,%xmm6 + movdqa %xmm3,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm12 + pxor %xmm10,%xmm6 + + movdqa %xmm2,64-128(%rax) + paddd %xmm2,%xmm12 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm14,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + paddd %xmm3,%xmm3 + paddd %xmm6,%xmm12 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 128-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm7 + pxor 224-128(%rax),%xmm4 + pxor %xmm1,%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + movdqa %xmm12,%xmm9 + pand %xmm14,%xmm7 + + movdqa %xmm10,%xmm6 + movdqa %xmm4,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm11 + pxor %xmm14,%xmm6 + + movdqa %xmm3,80-128(%rax) + paddd %xmm3,%xmm11 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm13,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + paddd %xmm4,%xmm4 + paddd %xmm6,%xmm11 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 144-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + movdqa %xmm14,%xmm7 + pxor 240-128(%rax),%xmm0 + pxor %xmm2,%xmm0 + paddd %xmm15,%xmm10 + pslld $5,%xmm8 + movdqa %xmm11,%xmm9 + pand %xmm13,%xmm7 + + movdqa %xmm14,%xmm6 + movdqa %xmm0,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm10 + pxor %xmm13,%xmm6 + + movdqa %xmm4,96-128(%rax) + paddd %xmm4,%xmm10 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm12,%xmm6 + movdqa %xmm12,%xmm7 + + pslld $30,%xmm7 + paddd %xmm0,%xmm0 + paddd %xmm6,%xmm10 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + pxor %xmm3,%xmm1 + movdqa 160-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm7 + pxor 0-128(%rax),%xmm1 + pxor %xmm3,%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + movdqa %xmm10,%xmm9 + pand %xmm12,%xmm7 + + movdqa %xmm13,%xmm6 + movdqa %xmm1,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm14 + pxor %xmm12,%xmm6 + + movdqa %xmm0,112-128(%rax) + paddd %xmm0,%xmm14 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm11,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + paddd %xmm1,%xmm1 + paddd %xmm6,%xmm14 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 176-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm7 + pxor 16-128(%rax),%xmm2 + pxor %xmm4,%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + movdqa %xmm14,%xmm9 + pand %xmm11,%xmm7 + + movdqa %xmm12,%xmm6 + movdqa %xmm2,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm13 + pxor %xmm11,%xmm6 + + movdqa %xmm1,128-128(%rax) + paddd %xmm1,%xmm13 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm10,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + paddd %xmm2,%xmm2 + paddd %xmm6,%xmm13 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 192-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm7 + pxor 32-128(%rax),%xmm3 + pxor %xmm0,%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + movdqa %xmm13,%xmm9 + pand %xmm10,%xmm7 + + movdqa %xmm11,%xmm6 + movdqa %xmm3,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm12 + pxor %xmm10,%xmm6 + + movdqa %xmm2,144-128(%rax) + paddd %xmm2,%xmm12 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm14,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + paddd %xmm3,%xmm3 + paddd %xmm6,%xmm12 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 208-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm7 + pxor 48-128(%rax),%xmm4 + pxor %xmm1,%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + movdqa %xmm12,%xmm9 + pand %xmm14,%xmm7 + + movdqa %xmm10,%xmm6 + movdqa %xmm4,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm11 + pxor %xmm14,%xmm6 + + movdqa %xmm3,160-128(%rax) + paddd %xmm3,%xmm11 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm13,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + paddd %xmm4,%xmm4 + paddd %xmm6,%xmm11 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 224-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + movdqa %xmm14,%xmm7 + pxor 64-128(%rax),%xmm0 + pxor %xmm2,%xmm0 + paddd %xmm15,%xmm10 + pslld $5,%xmm8 + movdqa %xmm11,%xmm9 + pand %xmm13,%xmm7 + + movdqa %xmm14,%xmm6 + movdqa %xmm0,%xmm5 + psrld $27,%xmm9 + paddd %xmm7,%xmm10 + pxor %xmm13,%xmm6 + + movdqa %xmm4,176-128(%rax) + paddd %xmm4,%xmm10 + por %xmm9,%xmm8 + psrld $31,%xmm5 + pand %xmm12,%xmm6 + movdqa %xmm12,%xmm7 + + pslld $30,%xmm7 + paddd %xmm0,%xmm0 + paddd %xmm6,%xmm10 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + movdqa 64(%rbp),%xmm15 + pxor %xmm3,%xmm1 + movdqa 240-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm6 + pxor 80-128(%rax),%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + pxor %xmm11,%xmm6 + + movdqa %xmm10,%xmm9 + movdqa %xmm0,192-128(%rax) + paddd %xmm0,%xmm14 + pxor %xmm3,%xmm1 + psrld $27,%xmm9 + pxor %xmm12,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm1,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm14 + paddd %xmm1,%xmm1 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 0-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm6 + pxor 96-128(%rax),%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + pxor %xmm10,%xmm6 + + movdqa %xmm14,%xmm9 + movdqa %xmm1,208-128(%rax) + paddd %xmm1,%xmm13 + pxor %xmm4,%xmm2 + psrld $27,%xmm9 + pxor %xmm11,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm2,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm13 + paddd %xmm2,%xmm2 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 16-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm6 + pxor 112-128(%rax),%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + pxor %xmm14,%xmm6 + + movdqa %xmm13,%xmm9 + movdqa %xmm2,224-128(%rax) + paddd %xmm2,%xmm12 + pxor %xmm0,%xmm3 + psrld $27,%xmm9 + pxor %xmm10,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm3,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm12 + paddd %xmm3,%xmm3 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 32-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm6 + pxor 128-128(%rax),%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + pxor %xmm13,%xmm6 + + movdqa %xmm12,%xmm9 + movdqa %xmm3,240-128(%rax) + paddd %xmm3,%xmm11 + pxor %xmm1,%xmm4 + psrld $27,%xmm9 + pxor %xmm14,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm4,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm11 + paddd %xmm4,%xmm4 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 48-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + movdqa %xmm14,%xmm6 + pxor 144-128(%rax),%xmm0 + paddd %xmm15,%xmm10 + pslld $5,%xmm8 + pxor %xmm12,%xmm6 + + movdqa %xmm11,%xmm9 + movdqa %xmm4,0-128(%rax) + paddd %xmm4,%xmm10 + pxor %xmm2,%xmm0 + psrld $27,%xmm9 + pxor %xmm13,%xmm6 + movdqa %xmm12,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm0,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm10 + paddd %xmm0,%xmm0 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + pxor %xmm3,%xmm1 + movdqa 64-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm6 + pxor 160-128(%rax),%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + pxor %xmm11,%xmm6 + + movdqa %xmm10,%xmm9 + movdqa %xmm0,16-128(%rax) + paddd %xmm0,%xmm14 + pxor %xmm3,%xmm1 + psrld $27,%xmm9 + pxor %xmm12,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm1,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm14 + paddd %xmm1,%xmm1 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 80-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm6 + pxor 176-128(%rax),%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + pxor %xmm10,%xmm6 + + movdqa %xmm14,%xmm9 + movdqa %xmm1,32-128(%rax) + paddd %xmm1,%xmm13 + pxor %xmm4,%xmm2 + psrld $27,%xmm9 + pxor %xmm11,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm2,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm13 + paddd %xmm2,%xmm2 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 96-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm6 + pxor 192-128(%rax),%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + pxor %xmm14,%xmm6 + + movdqa %xmm13,%xmm9 + movdqa %xmm2,48-128(%rax) + paddd %xmm2,%xmm12 + pxor %xmm0,%xmm3 + psrld $27,%xmm9 + pxor %xmm10,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm3,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm12 + paddd %xmm3,%xmm3 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 112-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm6 + pxor 208-128(%rax),%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + pxor %xmm13,%xmm6 + + movdqa %xmm12,%xmm9 + movdqa %xmm3,64-128(%rax) + paddd %xmm3,%xmm11 + pxor %xmm1,%xmm4 + psrld $27,%xmm9 + pxor %xmm14,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm4,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm11 + paddd %xmm4,%xmm4 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 128-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + movdqa %xmm14,%xmm6 + pxor 224-128(%rax),%xmm0 + paddd %xmm15,%xmm10 + pslld $5,%xmm8 + pxor %xmm12,%xmm6 + + movdqa %xmm11,%xmm9 + movdqa %xmm4,80-128(%rax) + paddd %xmm4,%xmm10 + pxor %xmm2,%xmm0 + psrld $27,%xmm9 + pxor %xmm13,%xmm6 + movdqa %xmm12,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm0,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm10 + paddd %xmm0,%xmm0 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + pxor %xmm3,%xmm1 + movdqa 144-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm6 + pxor 240-128(%rax),%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + pxor %xmm11,%xmm6 + + movdqa %xmm10,%xmm9 + movdqa %xmm0,96-128(%rax) + paddd %xmm0,%xmm14 + pxor %xmm3,%xmm1 + psrld $27,%xmm9 + pxor %xmm12,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm1,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm14 + paddd %xmm1,%xmm1 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 160-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm6 + pxor 0-128(%rax),%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + pxor %xmm10,%xmm6 + + movdqa %xmm14,%xmm9 + movdqa %xmm1,112-128(%rax) + paddd %xmm1,%xmm13 + pxor %xmm4,%xmm2 + psrld $27,%xmm9 + pxor %xmm11,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm2,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm13 + paddd %xmm2,%xmm2 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 176-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm6 + pxor 16-128(%rax),%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + pxor %xmm14,%xmm6 + + movdqa %xmm13,%xmm9 + paddd %xmm2,%xmm12 + pxor %xmm0,%xmm3 + psrld $27,%xmm9 + pxor %xmm10,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm3,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm12 + paddd %xmm3,%xmm3 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 192-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm6 + pxor 32-128(%rax),%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + pxor %xmm13,%xmm6 + + movdqa %xmm12,%xmm9 + paddd %xmm3,%xmm11 + pxor %xmm1,%xmm4 + psrld $27,%xmm9 + pxor %xmm14,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm4,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm11 + paddd %xmm4,%xmm4 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + pxor %xmm2,%xmm0 + movdqa 208-128(%rax),%xmm2 + + movdqa %xmm11,%xmm8 + movdqa %xmm14,%xmm6 + pxor 48-128(%rax),%xmm0 + paddd %xmm15,%xmm10 + pslld $5,%xmm8 + pxor %xmm12,%xmm6 + + movdqa %xmm11,%xmm9 + paddd %xmm4,%xmm10 + pxor %xmm2,%xmm0 + psrld $27,%xmm9 + pxor %xmm13,%xmm6 + movdqa %xmm12,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm0,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm10 + paddd %xmm0,%xmm0 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm5,%xmm0 + por %xmm7,%xmm12 + pxor %xmm3,%xmm1 + movdqa 224-128(%rax),%xmm3 + + movdqa %xmm10,%xmm8 + movdqa %xmm13,%xmm6 + pxor 64-128(%rax),%xmm1 + paddd %xmm15,%xmm14 + pslld $5,%xmm8 + pxor %xmm11,%xmm6 + + movdqa %xmm10,%xmm9 + paddd %xmm0,%xmm14 + pxor %xmm3,%xmm1 + psrld $27,%xmm9 + pxor %xmm12,%xmm6 + movdqa %xmm11,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm1,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm14 + paddd %xmm1,%xmm1 + + psrld $2,%xmm11 + paddd %xmm8,%xmm14 + por %xmm5,%xmm1 + por %xmm7,%xmm11 + pxor %xmm4,%xmm2 + movdqa 240-128(%rax),%xmm4 + + movdqa %xmm14,%xmm8 + movdqa %xmm12,%xmm6 + pxor 80-128(%rax),%xmm2 + paddd %xmm15,%xmm13 + pslld $5,%xmm8 + pxor %xmm10,%xmm6 + + movdqa %xmm14,%xmm9 + paddd %xmm1,%xmm13 + pxor %xmm4,%xmm2 + psrld $27,%xmm9 + pxor %xmm11,%xmm6 + movdqa %xmm10,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm2,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm13 + paddd %xmm2,%xmm2 + + psrld $2,%xmm10 + paddd %xmm8,%xmm13 + por %xmm5,%xmm2 + por %xmm7,%xmm10 + pxor %xmm0,%xmm3 + movdqa 0-128(%rax),%xmm0 + + movdqa %xmm13,%xmm8 + movdqa %xmm11,%xmm6 + pxor 96-128(%rax),%xmm3 + paddd %xmm15,%xmm12 + pslld $5,%xmm8 + pxor %xmm14,%xmm6 + + movdqa %xmm13,%xmm9 + paddd %xmm2,%xmm12 + pxor %xmm0,%xmm3 + psrld $27,%xmm9 + pxor %xmm10,%xmm6 + movdqa %xmm14,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm3,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm12 + paddd %xmm3,%xmm3 + + psrld $2,%xmm14 + paddd %xmm8,%xmm12 + por %xmm5,%xmm3 + por %xmm7,%xmm14 + pxor %xmm1,%xmm4 + movdqa 16-128(%rax),%xmm1 + + movdqa %xmm12,%xmm8 + movdqa %xmm10,%xmm6 + pxor 112-128(%rax),%xmm4 + paddd %xmm15,%xmm11 + pslld $5,%xmm8 + pxor %xmm13,%xmm6 + + movdqa %xmm12,%xmm9 + paddd %xmm3,%xmm11 + pxor %xmm1,%xmm4 + psrld $27,%xmm9 + pxor %xmm14,%xmm6 + movdqa %xmm13,%xmm7 + + pslld $30,%xmm7 + movdqa %xmm4,%xmm5 + por %xmm9,%xmm8 + psrld $31,%xmm5 + paddd %xmm6,%xmm11 + paddd %xmm4,%xmm4 + + psrld $2,%xmm13 + paddd %xmm8,%xmm11 + por %xmm5,%xmm4 + por %xmm7,%xmm13 + movdqa %xmm11,%xmm8 + paddd %xmm15,%xmm10 + movdqa %xmm14,%xmm6 + pslld $5,%xmm8 + pxor %xmm12,%xmm6 + + movdqa %xmm11,%xmm9 + paddd %xmm4,%xmm10 + psrld $27,%xmm9 + movdqa %xmm12,%xmm7 + pxor %xmm13,%xmm6 + + pslld $30,%xmm7 + por %xmm9,%xmm8 + paddd %xmm6,%xmm10 + + psrld $2,%xmm12 + paddd %xmm8,%xmm10 + por %xmm7,%xmm12 + movdqa (%rbx),%xmm0 + movl $1,%ecx + cmpl 0(%rbx),%ecx + pxor %xmm8,%xmm8 + cmovgeq %rbp,%r8 + cmpl 4(%rbx),%ecx + movdqa %xmm0,%xmm1 + cmovgeq %rbp,%r9 + cmpl 8(%rbx),%ecx + pcmpgtd %xmm8,%xmm1 + cmovgeq %rbp,%r10 + cmpl 12(%rbx),%ecx + paddd %xmm1,%xmm0 + cmovgeq %rbp,%r11 + + movdqu 0(%rdi),%xmm6 + pand %xmm1,%xmm10 + movdqu 32(%rdi),%xmm7 + pand %xmm1,%xmm11 + paddd %xmm6,%xmm10 + movdqu 64(%rdi),%xmm8 + pand %xmm1,%xmm12 + paddd %xmm7,%xmm11 + movdqu 96(%rdi),%xmm9 + pand %xmm1,%xmm13 + paddd %xmm8,%xmm12 + movdqu 128(%rdi),%xmm5 + pand %xmm1,%xmm14 + movdqu %xmm10,0(%rdi) + paddd %xmm9,%xmm13 + movdqu %xmm11,32(%rdi) + paddd %xmm5,%xmm14 + movdqu %xmm12,64(%rdi) + movdqu %xmm13,96(%rdi) + movdqu %xmm14,128(%rdi) + + movdqa %xmm0,(%rbx) + movdqa 96(%rbp),%xmm5 + movdqa -32(%rbp),%xmm15 + decl %edx + jnz .Loop + + movl 280(%rsp),%edx + leaq 16(%rdi),%rdi + leaq 64(%rsi),%rsi + decl %edx + jnz .Loop_grande + +.Ldone: + movq 272(%rsp),%rax +.cfi_def_cfa %rax,8 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_multi_block,.-sha1_multi_block +.type sha1_multi_block_shaext,@function +.align 32 +sha1_multi_block_shaext: +.cfi_startproc +_shaext_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + subq $288,%rsp + shll $1,%edx + andq $-256,%rsp + leaq 64(%rdi),%rdi + movq %rax,272(%rsp) +.Lbody_shaext: + leaq 256(%rsp),%rbx + movdqa K_XX_XX+128(%rip),%xmm3 + +.Loop_grande_shaext: + movl %edx,280(%rsp) + xorl %edx,%edx + + movq 0(%rsi),%r8 + + movl 8(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,0(%rbx) + cmovleq %rsp,%r8 + + movq 16(%rsi),%r9 + + movl 24(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,4(%rbx) + cmovleq %rsp,%r9 + testl %edx,%edx + jz .Ldone_shaext + + movq 0-64(%rdi),%xmm0 + movq 32-64(%rdi),%xmm4 + movq 64-64(%rdi),%xmm5 + movq 96-64(%rdi),%xmm6 + movq 128-64(%rdi),%xmm7 + + punpckldq %xmm4,%xmm0 + punpckldq %xmm6,%xmm5 + + movdqa %xmm0,%xmm8 + punpcklqdq %xmm5,%xmm0 + punpckhqdq %xmm5,%xmm8 + + pshufd $63,%xmm7,%xmm1 + pshufd $127,%xmm7,%xmm9 + pshufd $27,%xmm0,%xmm0 + pshufd $27,%xmm8,%xmm8 + jmp .Loop_shaext + +.align 32 +.Loop_shaext: + movdqu 0(%r8),%xmm4 + movdqu 0(%r9),%xmm11 + movdqu 16(%r8),%xmm5 + movdqu 16(%r9),%xmm12 + movdqu 32(%r8),%xmm6 +.byte 102,15,56,0,227 + movdqu 32(%r9),%xmm13 +.byte 102,68,15,56,0,219 + movdqu 48(%r8),%xmm7 + leaq 64(%r8),%r8 +.byte 102,15,56,0,235 + movdqu 48(%r9),%xmm14 + leaq 64(%r9),%r9 +.byte 102,68,15,56,0,227 + + movdqa %xmm1,80(%rsp) + paddd %xmm4,%xmm1 + movdqa %xmm9,112(%rsp) + paddd %xmm11,%xmm9 + movdqa %xmm0,64(%rsp) + movdqa %xmm0,%xmm2 + movdqa %xmm8,96(%rsp) + movdqa %xmm8,%xmm10 +.byte 15,58,204,193,0 +.byte 15,56,200,213 +.byte 69,15,58,204,193,0 +.byte 69,15,56,200,212 +.byte 102,15,56,0,243 + prefetcht0 127(%r8) +.byte 15,56,201,229 +.byte 102,68,15,56,0,235 + prefetcht0 127(%r9) +.byte 69,15,56,201,220 + +.byte 102,15,56,0,251 + movdqa %xmm0,%xmm1 +.byte 102,68,15,56,0,243 + movdqa %xmm8,%xmm9 +.byte 15,58,204,194,0 +.byte 15,56,200,206 +.byte 69,15,58,204,194,0 +.byte 69,15,56,200,205 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 + pxor %xmm13,%xmm11 +.byte 69,15,56,201,229 + movdqa %xmm0,%xmm2 + movdqa %xmm8,%xmm10 +.byte 15,58,204,193,0 +.byte 15,56,200,215 +.byte 69,15,58,204,193,0 +.byte 69,15,56,200,214 +.byte 15,56,202,231 +.byte 69,15,56,202,222 + pxor %xmm7,%xmm5 +.byte 15,56,201,247 + pxor %xmm14,%xmm12 +.byte 69,15,56,201,238 + movdqa %xmm0,%xmm1 + movdqa %xmm8,%xmm9 +.byte 15,58,204,194,0 +.byte 15,56,200,204 +.byte 69,15,58,204,194,0 +.byte 69,15,56,200,203 +.byte 15,56,202,236 +.byte 69,15,56,202,227 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 + pxor %xmm11,%xmm13 +.byte 69,15,56,201,243 + movdqa %xmm0,%xmm2 + movdqa %xmm8,%xmm10 +.byte 15,58,204,193,0 +.byte 15,56,200,213 +.byte 69,15,58,204,193,0 +.byte 69,15,56,200,212 +.byte 15,56,202,245 +.byte 69,15,56,202,236 + pxor %xmm5,%xmm7 +.byte 15,56,201,229 + pxor %xmm12,%xmm14 +.byte 69,15,56,201,220 + movdqa %xmm0,%xmm1 + movdqa %xmm8,%xmm9 +.byte 15,58,204,194,1 +.byte 15,56,200,206 +.byte 69,15,58,204,194,1 +.byte 69,15,56,200,205 +.byte 15,56,202,254 +.byte 69,15,56,202,245 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 + pxor %xmm13,%xmm11 +.byte 69,15,56,201,229 + movdqa %xmm0,%xmm2 + movdqa %xmm8,%xmm10 +.byte 15,58,204,193,1 +.byte 15,56,200,215 +.byte 69,15,58,204,193,1 +.byte 69,15,56,200,214 +.byte 15,56,202,231 +.byte 69,15,56,202,222 + pxor %xmm7,%xmm5 +.byte 15,56,201,247 + pxor %xmm14,%xmm12 +.byte 69,15,56,201,238 + movdqa %xmm0,%xmm1 + movdqa %xmm8,%xmm9 +.byte 15,58,204,194,1 +.byte 15,56,200,204 +.byte 69,15,58,204,194,1 +.byte 69,15,56,200,203 +.byte 15,56,202,236 +.byte 69,15,56,202,227 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 + pxor %xmm11,%xmm13 +.byte 69,15,56,201,243 + movdqa %xmm0,%xmm2 + movdqa %xmm8,%xmm10 +.byte 15,58,204,193,1 +.byte 15,56,200,213 +.byte 69,15,58,204,193,1 +.byte 69,15,56,200,212 +.byte 15,56,202,245 +.byte 69,15,56,202,236 + pxor %xmm5,%xmm7 +.byte 15,56,201,229 + pxor %xmm12,%xmm14 +.byte 69,15,56,201,220 + movdqa %xmm0,%xmm1 + movdqa %xmm8,%xmm9 +.byte 15,58,204,194,1 +.byte 15,56,200,206 +.byte 69,15,58,204,194,1 +.byte 69,15,56,200,205 +.byte 15,56,202,254 +.byte 69,15,56,202,245 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 + pxor %xmm13,%xmm11 +.byte 69,15,56,201,229 + movdqa %xmm0,%xmm2 + movdqa %xmm8,%xmm10 +.byte 15,58,204,193,2 +.byte 15,56,200,215 +.byte 69,15,58,204,193,2 +.byte 69,15,56,200,214 +.byte 15,56,202,231 +.byte 69,15,56,202,222 + pxor %xmm7,%xmm5 +.byte 15,56,201,247 + pxor %xmm14,%xmm12 +.byte 69,15,56,201,238 + movdqa %xmm0,%xmm1 + movdqa %xmm8,%xmm9 +.byte 15,58,204,194,2 +.byte 15,56,200,204 +.byte 69,15,58,204,194,2 +.byte 69,15,56,200,203 +.byte 15,56,202,236 +.byte 69,15,56,202,227 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 + pxor %xmm11,%xmm13 +.byte 69,15,56,201,243 + movdqa %xmm0,%xmm2 + movdqa %xmm8,%xmm10 +.byte 15,58,204,193,2 +.byte 15,56,200,213 +.byte 69,15,58,204,193,2 +.byte 69,15,56,200,212 +.byte 15,56,202,245 +.byte 69,15,56,202,236 + pxor %xmm5,%xmm7 +.byte 15,56,201,229 + pxor %xmm12,%xmm14 +.byte 69,15,56,201,220 + movdqa %xmm0,%xmm1 + movdqa %xmm8,%xmm9 +.byte 15,58,204,194,2 +.byte 15,56,200,206 +.byte 69,15,58,204,194,2 +.byte 69,15,56,200,205 +.byte 15,56,202,254 +.byte 69,15,56,202,245 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 + pxor %xmm13,%xmm11 +.byte 69,15,56,201,229 + movdqa %xmm0,%xmm2 + movdqa %xmm8,%xmm10 +.byte 15,58,204,193,2 +.byte 15,56,200,215 +.byte 69,15,58,204,193,2 +.byte 69,15,56,200,214 +.byte 15,56,202,231 +.byte 69,15,56,202,222 + pxor %xmm7,%xmm5 +.byte 15,56,201,247 + pxor %xmm14,%xmm12 +.byte 69,15,56,201,238 + movdqa %xmm0,%xmm1 + movdqa %xmm8,%xmm9 +.byte 15,58,204,194,3 +.byte 15,56,200,204 +.byte 69,15,58,204,194,3 +.byte 69,15,56,200,203 +.byte 15,56,202,236 +.byte 69,15,56,202,227 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 + pxor %xmm11,%xmm13 +.byte 69,15,56,201,243 + movdqa %xmm0,%xmm2 + movdqa %xmm8,%xmm10 +.byte 15,58,204,193,3 +.byte 15,56,200,213 +.byte 69,15,58,204,193,3 +.byte 69,15,56,200,212 +.byte 15,56,202,245 +.byte 69,15,56,202,236 + pxor %xmm5,%xmm7 + pxor %xmm12,%xmm14 + + movl $1,%ecx + pxor %xmm4,%xmm4 + cmpl 0(%rbx),%ecx + cmovgeq %rsp,%r8 + + movdqa %xmm0,%xmm1 + movdqa %xmm8,%xmm9 +.byte 15,58,204,194,3 +.byte 15,56,200,206 +.byte 69,15,58,204,194,3 +.byte 69,15,56,200,205 +.byte 15,56,202,254 +.byte 69,15,56,202,245 + + cmpl 4(%rbx),%ecx + cmovgeq %rsp,%r9 + movq (%rbx),%xmm6 + + movdqa %xmm0,%xmm2 + movdqa %xmm8,%xmm10 +.byte 15,58,204,193,3 +.byte 15,56,200,215 +.byte 69,15,58,204,193,3 +.byte 69,15,56,200,214 + + pshufd $0x00,%xmm6,%xmm11 + pshufd $0x55,%xmm6,%xmm12 + movdqa %xmm6,%xmm7 + pcmpgtd %xmm4,%xmm11 + pcmpgtd %xmm4,%xmm12 + + movdqa %xmm0,%xmm1 + movdqa %xmm8,%xmm9 +.byte 15,58,204,194,3 +.byte 15,56,200,204 +.byte 69,15,58,204,194,3 +.byte 68,15,56,200,204 + + pcmpgtd %xmm4,%xmm7 + pand %xmm11,%xmm0 + pand %xmm11,%xmm1 + pand %xmm12,%xmm8 + pand %xmm12,%xmm9 + paddd %xmm7,%xmm6 + + paddd 64(%rsp),%xmm0 + paddd 80(%rsp),%xmm1 + paddd 96(%rsp),%xmm8 + paddd 112(%rsp),%xmm9 + + movq %xmm6,(%rbx) + decl %edx + jnz .Loop_shaext + + movl 280(%rsp),%edx + + pshufd $27,%xmm0,%xmm0 + pshufd $27,%xmm8,%xmm8 + + movdqa %xmm0,%xmm6 + punpckldq %xmm8,%xmm0 + punpckhdq %xmm8,%xmm6 + punpckhdq %xmm9,%xmm1 + movq %xmm0,0-64(%rdi) + psrldq $8,%xmm0 + movq %xmm6,64-64(%rdi) + psrldq $8,%xmm6 + movq %xmm0,32-64(%rdi) + psrldq $8,%xmm1 + movq %xmm6,96-64(%rdi) + movq %xmm1,128-64(%rdi) + + leaq 8(%rdi),%rdi + leaq 32(%rsi),%rsi + decl %edx + jnz .Loop_grande_shaext + +.Ldone_shaext: + + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_shaext: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_multi_block_shaext,.-sha1_multi_block_shaext +.type sha1_multi_block_avx,@function +.align 32 +sha1_multi_block_avx: +.cfi_startproc +_avx_shortcut: + shrq $32,%rcx + cmpl $2,%edx + jb .Lavx + testl $32,%ecx + jnz _avx2_shortcut + jmp .Lavx +.align 32 +.Lavx: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + subq $288,%rsp + andq $-256,%rsp + movq %rax,272(%rsp) +.cfi_escape 0x0f,0x06,0x77,0x90,0x02,0x06,0x23,0x08 +.Lbody_avx: + leaq K_XX_XX(%rip),%rbp + leaq 256(%rsp),%rbx + + vzeroupper +.Loop_grande_avx: + movl %edx,280(%rsp) + xorl %edx,%edx + + movq 0(%rsi),%r8 + + movl 8(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,0(%rbx) + cmovleq %rbp,%r8 + + movq 16(%rsi),%r9 + + movl 24(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,4(%rbx) + cmovleq %rbp,%r9 + + movq 32(%rsi),%r10 + + movl 40(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,8(%rbx) + cmovleq %rbp,%r10 + + movq 48(%rsi),%r11 + + movl 56(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,12(%rbx) + cmovleq %rbp,%r11 + testl %edx,%edx + jz .Ldone_avx + + vmovdqu 0(%rdi),%xmm10 + leaq 128(%rsp),%rax + vmovdqu 32(%rdi),%xmm11 + vmovdqu 64(%rdi),%xmm12 + vmovdqu 96(%rdi),%xmm13 + vmovdqu 128(%rdi),%xmm14 + vmovdqu 96(%rbp),%xmm5 + jmp .Loop_avx + +.align 32 +.Loop_avx: + vmovdqa -32(%rbp),%xmm15 + vmovd (%r8),%xmm0 + leaq 64(%r8),%r8 + vmovd (%r9),%xmm2 + leaq 64(%r9),%r9 + vpinsrd $1,(%r10),%xmm0,%xmm0 + leaq 64(%r10),%r10 + vpinsrd $1,(%r11),%xmm2,%xmm2 + leaq 64(%r11),%r11 + vmovd -60(%r8),%xmm1 + vpunpckldq %xmm2,%xmm0,%xmm0 + vmovd -60(%r9),%xmm9 + vpshufb %xmm5,%xmm0,%xmm0 + vpinsrd $1,-60(%r10),%xmm1,%xmm1 + vpinsrd $1,-60(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm14,%xmm14 + vpslld $5,%xmm10,%xmm8 + vpandn %xmm13,%xmm11,%xmm7 + vpand %xmm12,%xmm11,%xmm6 + + vmovdqa %xmm0,0-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpunpckldq %xmm9,%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -56(%r8),%xmm2 + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -56(%r9),%xmm9 + vpaddd %xmm6,%xmm14,%xmm14 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpshufb %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpinsrd $1,-56(%r10),%xmm2,%xmm2 + vpinsrd $1,-56(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm13,%xmm13 + vpslld $5,%xmm14,%xmm8 + vpandn %xmm12,%xmm10,%xmm7 + vpand %xmm11,%xmm10,%xmm6 + + vmovdqa %xmm1,16-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpunpckldq %xmm9,%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -52(%r8),%xmm3 + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -52(%r9),%xmm9 + vpaddd %xmm6,%xmm13,%xmm13 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpshufb %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpinsrd $1,-52(%r10),%xmm3,%xmm3 + vpinsrd $1,-52(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm12,%xmm12 + vpslld $5,%xmm13,%xmm8 + vpandn %xmm11,%xmm14,%xmm7 + vpand %xmm10,%xmm14,%xmm6 + + vmovdqa %xmm2,32-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpunpckldq %xmm9,%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -48(%r8),%xmm4 + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -48(%r9),%xmm9 + vpaddd %xmm6,%xmm12,%xmm12 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpshufb %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpinsrd $1,-48(%r10),%xmm4,%xmm4 + vpinsrd $1,-48(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm11,%xmm11 + vpslld $5,%xmm12,%xmm8 + vpandn %xmm10,%xmm13,%xmm7 + vpand %xmm14,%xmm13,%xmm6 + + vmovdqa %xmm3,48-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpunpckldq %xmm9,%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -44(%r8),%xmm0 + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -44(%r9),%xmm9 + vpaddd %xmm6,%xmm11,%xmm11 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpshufb %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpinsrd $1,-44(%r10),%xmm0,%xmm0 + vpinsrd $1,-44(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm10,%xmm10 + vpslld $5,%xmm11,%xmm8 + vpandn %xmm14,%xmm12,%xmm7 + vpand %xmm13,%xmm12,%xmm6 + + vmovdqa %xmm4,64-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpunpckldq %xmm9,%xmm0,%xmm0 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -40(%r8),%xmm1 + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -40(%r9),%xmm9 + vpaddd %xmm6,%xmm10,%xmm10 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpshufb %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vpinsrd $1,-40(%r10),%xmm1,%xmm1 + vpinsrd $1,-40(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm14,%xmm14 + vpslld $5,%xmm10,%xmm8 + vpandn %xmm13,%xmm11,%xmm7 + vpand %xmm12,%xmm11,%xmm6 + + vmovdqa %xmm0,80-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpunpckldq %xmm9,%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -36(%r8),%xmm2 + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -36(%r9),%xmm9 + vpaddd %xmm6,%xmm14,%xmm14 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpshufb %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpinsrd $1,-36(%r10),%xmm2,%xmm2 + vpinsrd $1,-36(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm13,%xmm13 + vpslld $5,%xmm14,%xmm8 + vpandn %xmm12,%xmm10,%xmm7 + vpand %xmm11,%xmm10,%xmm6 + + vmovdqa %xmm1,96-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpunpckldq %xmm9,%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -32(%r8),%xmm3 + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -32(%r9),%xmm9 + vpaddd %xmm6,%xmm13,%xmm13 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpshufb %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpinsrd $1,-32(%r10),%xmm3,%xmm3 + vpinsrd $1,-32(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm12,%xmm12 + vpslld $5,%xmm13,%xmm8 + vpandn %xmm11,%xmm14,%xmm7 + vpand %xmm10,%xmm14,%xmm6 + + vmovdqa %xmm2,112-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpunpckldq %xmm9,%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -28(%r8),%xmm4 + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -28(%r9),%xmm9 + vpaddd %xmm6,%xmm12,%xmm12 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpshufb %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpinsrd $1,-28(%r10),%xmm4,%xmm4 + vpinsrd $1,-28(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm11,%xmm11 + vpslld $5,%xmm12,%xmm8 + vpandn %xmm10,%xmm13,%xmm7 + vpand %xmm14,%xmm13,%xmm6 + + vmovdqa %xmm3,128-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpunpckldq %xmm9,%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -24(%r8),%xmm0 + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -24(%r9),%xmm9 + vpaddd %xmm6,%xmm11,%xmm11 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpshufb %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpinsrd $1,-24(%r10),%xmm0,%xmm0 + vpinsrd $1,-24(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm10,%xmm10 + vpslld $5,%xmm11,%xmm8 + vpandn %xmm14,%xmm12,%xmm7 + vpand %xmm13,%xmm12,%xmm6 + + vmovdqa %xmm4,144-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpunpckldq %xmm9,%xmm0,%xmm0 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -20(%r8),%xmm1 + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -20(%r9),%xmm9 + vpaddd %xmm6,%xmm10,%xmm10 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpshufb %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vpinsrd $1,-20(%r10),%xmm1,%xmm1 + vpinsrd $1,-20(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm14,%xmm14 + vpslld $5,%xmm10,%xmm8 + vpandn %xmm13,%xmm11,%xmm7 + vpand %xmm12,%xmm11,%xmm6 + + vmovdqa %xmm0,160-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpunpckldq %xmm9,%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -16(%r8),%xmm2 + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -16(%r9),%xmm9 + vpaddd %xmm6,%xmm14,%xmm14 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpshufb %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpinsrd $1,-16(%r10),%xmm2,%xmm2 + vpinsrd $1,-16(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm13,%xmm13 + vpslld $5,%xmm14,%xmm8 + vpandn %xmm12,%xmm10,%xmm7 + vpand %xmm11,%xmm10,%xmm6 + + vmovdqa %xmm1,176-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpunpckldq %xmm9,%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -12(%r8),%xmm3 + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -12(%r9),%xmm9 + vpaddd %xmm6,%xmm13,%xmm13 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpshufb %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpinsrd $1,-12(%r10),%xmm3,%xmm3 + vpinsrd $1,-12(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm12,%xmm12 + vpslld $5,%xmm13,%xmm8 + vpandn %xmm11,%xmm14,%xmm7 + vpand %xmm10,%xmm14,%xmm6 + + vmovdqa %xmm2,192-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpunpckldq %xmm9,%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -8(%r8),%xmm4 + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -8(%r9),%xmm9 + vpaddd %xmm6,%xmm12,%xmm12 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpshufb %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpinsrd $1,-8(%r10),%xmm4,%xmm4 + vpinsrd $1,-8(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm11,%xmm11 + vpslld $5,%xmm12,%xmm8 + vpandn %xmm10,%xmm13,%xmm7 + vpand %xmm14,%xmm13,%xmm6 + + vmovdqa %xmm3,208-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpunpckldq %xmm9,%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vmovd -4(%r8),%xmm0 + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vmovd -4(%r9),%xmm9 + vpaddd %xmm6,%xmm11,%xmm11 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpshufb %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vmovdqa 0-128(%rax),%xmm1 + vpinsrd $1,-4(%r10),%xmm0,%xmm0 + vpinsrd $1,-4(%r11),%xmm9,%xmm9 + vpaddd %xmm15,%xmm10,%xmm10 + prefetcht0 63(%r8) + vpslld $5,%xmm11,%xmm8 + vpandn %xmm14,%xmm12,%xmm7 + vpand %xmm13,%xmm12,%xmm6 + + vmovdqa %xmm4,224-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpunpckldq %xmm9,%xmm0,%xmm0 + vpsrld $27,%xmm11,%xmm9 + prefetcht0 63(%r9) + vpxor %xmm7,%xmm6,%xmm6 + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + prefetcht0 63(%r10) + vpaddd %xmm6,%xmm10,%xmm10 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + prefetcht0 63(%r11) + vpshufb %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vmovdqa 16-128(%rax),%xmm2 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 32-128(%rax),%xmm3 + + vpaddd %xmm15,%xmm14,%xmm14 + vpslld $5,%xmm10,%xmm8 + vpandn %xmm13,%xmm11,%xmm7 + + vpand %xmm12,%xmm11,%xmm6 + + vmovdqa %xmm0,240-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpxor 128-128(%rax),%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm14,%xmm14 + + vpsrld $31,%xmm1,%xmm5 + vpaddd %xmm1,%xmm1,%xmm1 + + vpsrld $2,%xmm11,%xmm11 + + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 48-128(%rax),%xmm4 + + vpaddd %xmm15,%xmm13,%xmm13 + vpslld $5,%xmm14,%xmm8 + vpandn %xmm12,%xmm10,%xmm7 + + vpand %xmm11,%xmm10,%xmm6 + + vmovdqa %xmm1,0-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpxor 144-128(%rax),%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm13,%xmm13 + + vpsrld $31,%xmm2,%xmm5 + vpaddd %xmm2,%xmm2,%xmm2 + + vpsrld $2,%xmm10,%xmm10 + + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 64-128(%rax),%xmm0 + + vpaddd %xmm15,%xmm12,%xmm12 + vpslld $5,%xmm13,%xmm8 + vpandn %xmm11,%xmm14,%xmm7 + + vpand %xmm10,%xmm14,%xmm6 + + vmovdqa %xmm2,16-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpxor 160-128(%rax),%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm12,%xmm12 + + vpsrld $31,%xmm3,%xmm5 + vpaddd %xmm3,%xmm3,%xmm3 + + vpsrld $2,%xmm14,%xmm14 + + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 80-128(%rax),%xmm1 + + vpaddd %xmm15,%xmm11,%xmm11 + vpslld $5,%xmm12,%xmm8 + vpandn %xmm10,%xmm13,%xmm7 + + vpand %xmm14,%xmm13,%xmm6 + + vmovdqa %xmm3,32-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpxor 176-128(%rax),%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm11,%xmm11 + + vpsrld $31,%xmm4,%xmm5 + vpaddd %xmm4,%xmm4,%xmm4 + + vpsrld $2,%xmm13,%xmm13 + + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 96-128(%rax),%xmm2 + + vpaddd %xmm15,%xmm10,%xmm10 + vpslld $5,%xmm11,%xmm8 + vpandn %xmm14,%xmm12,%xmm7 + + vpand %xmm13,%xmm12,%xmm6 + + vmovdqa %xmm4,48-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpxor 192-128(%rax),%xmm0,%xmm0 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm7,%xmm6,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm10,%xmm10 + + vpsrld $31,%xmm0,%xmm5 + vpaddd %xmm0,%xmm0,%xmm0 + + vpsrld $2,%xmm12,%xmm12 + + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vmovdqa 0(%rbp),%xmm15 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 112-128(%rax),%xmm3 + + vpslld $5,%xmm10,%xmm8 + vpaddd %xmm15,%xmm14,%xmm14 + vpxor %xmm11,%xmm13,%xmm6 + vmovdqa %xmm0,64-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpxor 208-128(%rax),%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm6,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm14,%xmm14 + vpsrld $31,%xmm1,%xmm5 + vpaddd %xmm1,%xmm1,%xmm1 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 128-128(%rax),%xmm4 + + vpslld $5,%xmm14,%xmm8 + vpaddd %xmm15,%xmm13,%xmm13 + vpxor %xmm10,%xmm12,%xmm6 + vmovdqa %xmm1,80-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpxor 224-128(%rax),%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm6,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm13,%xmm13 + vpsrld $31,%xmm2,%xmm5 + vpaddd %xmm2,%xmm2,%xmm2 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 144-128(%rax),%xmm0 + + vpslld $5,%xmm13,%xmm8 + vpaddd %xmm15,%xmm12,%xmm12 + vpxor %xmm14,%xmm11,%xmm6 + vmovdqa %xmm2,96-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpxor 240-128(%rax),%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm6,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm12,%xmm12 + vpsrld $31,%xmm3,%xmm5 + vpaddd %xmm3,%xmm3,%xmm3 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 160-128(%rax),%xmm1 + + vpslld $5,%xmm12,%xmm8 + vpaddd %xmm15,%xmm11,%xmm11 + vpxor %xmm13,%xmm10,%xmm6 + vmovdqa %xmm3,112-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpxor 0-128(%rax),%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm11,%xmm11 + vpsrld $31,%xmm4,%xmm5 + vpaddd %xmm4,%xmm4,%xmm4 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 176-128(%rax),%xmm2 + + vpslld $5,%xmm11,%xmm8 + vpaddd %xmm15,%xmm10,%xmm10 + vpxor %xmm12,%xmm14,%xmm6 + vmovdqa %xmm4,128-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpxor 16-128(%rax),%xmm0,%xmm0 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm13,%xmm6,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm10,%xmm10 + vpsrld $31,%xmm0,%xmm5 + vpaddd %xmm0,%xmm0,%xmm0 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 192-128(%rax),%xmm3 + + vpslld $5,%xmm10,%xmm8 + vpaddd %xmm15,%xmm14,%xmm14 + vpxor %xmm11,%xmm13,%xmm6 + vmovdqa %xmm0,144-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpxor 32-128(%rax),%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm6,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm14,%xmm14 + vpsrld $31,%xmm1,%xmm5 + vpaddd %xmm1,%xmm1,%xmm1 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 208-128(%rax),%xmm4 + + vpslld $5,%xmm14,%xmm8 + vpaddd %xmm15,%xmm13,%xmm13 + vpxor %xmm10,%xmm12,%xmm6 + vmovdqa %xmm1,160-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpxor 48-128(%rax),%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm6,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm13,%xmm13 + vpsrld $31,%xmm2,%xmm5 + vpaddd %xmm2,%xmm2,%xmm2 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 224-128(%rax),%xmm0 + + vpslld $5,%xmm13,%xmm8 + vpaddd %xmm15,%xmm12,%xmm12 + vpxor %xmm14,%xmm11,%xmm6 + vmovdqa %xmm2,176-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpxor 64-128(%rax),%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm6,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm12,%xmm12 + vpsrld $31,%xmm3,%xmm5 + vpaddd %xmm3,%xmm3,%xmm3 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 240-128(%rax),%xmm1 + + vpslld $5,%xmm12,%xmm8 + vpaddd %xmm15,%xmm11,%xmm11 + vpxor %xmm13,%xmm10,%xmm6 + vmovdqa %xmm3,192-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpxor 80-128(%rax),%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm11,%xmm11 + vpsrld $31,%xmm4,%xmm5 + vpaddd %xmm4,%xmm4,%xmm4 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 0-128(%rax),%xmm2 + + vpslld $5,%xmm11,%xmm8 + vpaddd %xmm15,%xmm10,%xmm10 + vpxor %xmm12,%xmm14,%xmm6 + vmovdqa %xmm4,208-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpxor 96-128(%rax),%xmm0,%xmm0 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm13,%xmm6,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm10,%xmm10 + vpsrld $31,%xmm0,%xmm5 + vpaddd %xmm0,%xmm0,%xmm0 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 16-128(%rax),%xmm3 + + vpslld $5,%xmm10,%xmm8 + vpaddd %xmm15,%xmm14,%xmm14 + vpxor %xmm11,%xmm13,%xmm6 + vmovdqa %xmm0,224-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpxor 112-128(%rax),%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm6,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm14,%xmm14 + vpsrld $31,%xmm1,%xmm5 + vpaddd %xmm1,%xmm1,%xmm1 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 32-128(%rax),%xmm4 + + vpslld $5,%xmm14,%xmm8 + vpaddd %xmm15,%xmm13,%xmm13 + vpxor %xmm10,%xmm12,%xmm6 + vmovdqa %xmm1,240-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpxor 128-128(%rax),%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm6,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm13,%xmm13 + vpsrld $31,%xmm2,%xmm5 + vpaddd %xmm2,%xmm2,%xmm2 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 48-128(%rax),%xmm0 + + vpslld $5,%xmm13,%xmm8 + vpaddd %xmm15,%xmm12,%xmm12 + vpxor %xmm14,%xmm11,%xmm6 + vmovdqa %xmm2,0-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpxor 144-128(%rax),%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm6,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm12,%xmm12 + vpsrld $31,%xmm3,%xmm5 + vpaddd %xmm3,%xmm3,%xmm3 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 64-128(%rax),%xmm1 + + vpslld $5,%xmm12,%xmm8 + vpaddd %xmm15,%xmm11,%xmm11 + vpxor %xmm13,%xmm10,%xmm6 + vmovdqa %xmm3,16-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpxor 160-128(%rax),%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm11,%xmm11 + vpsrld $31,%xmm4,%xmm5 + vpaddd %xmm4,%xmm4,%xmm4 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 80-128(%rax),%xmm2 + + vpslld $5,%xmm11,%xmm8 + vpaddd %xmm15,%xmm10,%xmm10 + vpxor %xmm12,%xmm14,%xmm6 + vmovdqa %xmm4,32-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpxor 176-128(%rax),%xmm0,%xmm0 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm13,%xmm6,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm10,%xmm10 + vpsrld $31,%xmm0,%xmm5 + vpaddd %xmm0,%xmm0,%xmm0 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 96-128(%rax),%xmm3 + + vpslld $5,%xmm10,%xmm8 + vpaddd %xmm15,%xmm14,%xmm14 + vpxor %xmm11,%xmm13,%xmm6 + vmovdqa %xmm0,48-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpxor 192-128(%rax),%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm6,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm14,%xmm14 + vpsrld $31,%xmm1,%xmm5 + vpaddd %xmm1,%xmm1,%xmm1 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 112-128(%rax),%xmm4 + + vpslld $5,%xmm14,%xmm8 + vpaddd %xmm15,%xmm13,%xmm13 + vpxor %xmm10,%xmm12,%xmm6 + vmovdqa %xmm1,64-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpxor 208-128(%rax),%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm6,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm13,%xmm13 + vpsrld $31,%xmm2,%xmm5 + vpaddd %xmm2,%xmm2,%xmm2 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 128-128(%rax),%xmm0 + + vpslld $5,%xmm13,%xmm8 + vpaddd %xmm15,%xmm12,%xmm12 + vpxor %xmm14,%xmm11,%xmm6 + vmovdqa %xmm2,80-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpxor 224-128(%rax),%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm6,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm12,%xmm12 + vpsrld $31,%xmm3,%xmm5 + vpaddd %xmm3,%xmm3,%xmm3 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 144-128(%rax),%xmm1 + + vpslld $5,%xmm12,%xmm8 + vpaddd %xmm15,%xmm11,%xmm11 + vpxor %xmm13,%xmm10,%xmm6 + vmovdqa %xmm3,96-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpxor 240-128(%rax),%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm11,%xmm11 + vpsrld $31,%xmm4,%xmm5 + vpaddd %xmm4,%xmm4,%xmm4 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 160-128(%rax),%xmm2 + + vpslld $5,%xmm11,%xmm8 + vpaddd %xmm15,%xmm10,%xmm10 + vpxor %xmm12,%xmm14,%xmm6 + vmovdqa %xmm4,112-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpxor 0-128(%rax),%xmm0,%xmm0 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm13,%xmm6,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm10,%xmm10 + vpsrld $31,%xmm0,%xmm5 + vpaddd %xmm0,%xmm0,%xmm0 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vmovdqa 32(%rbp),%xmm15 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 176-128(%rax),%xmm3 + + vpaddd %xmm15,%xmm14,%xmm14 + vpslld $5,%xmm10,%xmm8 + vpand %xmm12,%xmm13,%xmm7 + vpxor 16-128(%rax),%xmm1,%xmm1 + + vpaddd %xmm7,%xmm14,%xmm14 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm13,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vmovdqu %xmm0,128-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm1,%xmm5 + vpand %xmm11,%xmm6,%xmm6 + vpaddd %xmm1,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpaddd %xmm6,%xmm14,%xmm14 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 192-128(%rax),%xmm4 + + vpaddd %xmm15,%xmm13,%xmm13 + vpslld $5,%xmm14,%xmm8 + vpand %xmm11,%xmm12,%xmm7 + vpxor 32-128(%rax),%xmm2,%xmm2 + + vpaddd %xmm7,%xmm13,%xmm13 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm12,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vmovdqu %xmm1,144-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm2,%xmm5 + vpand %xmm10,%xmm6,%xmm6 + vpaddd %xmm2,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpaddd %xmm6,%xmm13,%xmm13 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 208-128(%rax),%xmm0 + + vpaddd %xmm15,%xmm12,%xmm12 + vpslld $5,%xmm13,%xmm8 + vpand %xmm10,%xmm11,%xmm7 + vpxor 48-128(%rax),%xmm3,%xmm3 + + vpaddd %xmm7,%xmm12,%xmm12 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm11,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vmovdqu %xmm2,160-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm3,%xmm5 + vpand %xmm14,%xmm6,%xmm6 + vpaddd %xmm3,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpaddd %xmm6,%xmm12,%xmm12 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 224-128(%rax),%xmm1 + + vpaddd %xmm15,%xmm11,%xmm11 + vpslld $5,%xmm12,%xmm8 + vpand %xmm14,%xmm10,%xmm7 + vpxor 64-128(%rax),%xmm4,%xmm4 + + vpaddd %xmm7,%xmm11,%xmm11 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm10,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vmovdqu %xmm3,176-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm4,%xmm5 + vpand %xmm13,%xmm6,%xmm6 + vpaddd %xmm4,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpaddd %xmm6,%xmm11,%xmm11 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 240-128(%rax),%xmm2 + + vpaddd %xmm15,%xmm10,%xmm10 + vpslld $5,%xmm11,%xmm8 + vpand %xmm13,%xmm14,%xmm7 + vpxor 80-128(%rax),%xmm0,%xmm0 + + vpaddd %xmm7,%xmm10,%xmm10 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm13,%xmm14,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + vmovdqu %xmm4,192-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm0,%xmm5 + vpand %xmm12,%xmm6,%xmm6 + vpaddd %xmm0,%xmm0,%xmm0 + + vpslld $30,%xmm12,%xmm7 + vpaddd %xmm6,%xmm10,%xmm10 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 0-128(%rax),%xmm3 + + vpaddd %xmm15,%xmm14,%xmm14 + vpslld $5,%xmm10,%xmm8 + vpand %xmm12,%xmm13,%xmm7 + vpxor 96-128(%rax),%xmm1,%xmm1 + + vpaddd %xmm7,%xmm14,%xmm14 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm13,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vmovdqu %xmm0,208-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm1,%xmm5 + vpand %xmm11,%xmm6,%xmm6 + vpaddd %xmm1,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpaddd %xmm6,%xmm14,%xmm14 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 16-128(%rax),%xmm4 + + vpaddd %xmm15,%xmm13,%xmm13 + vpslld $5,%xmm14,%xmm8 + vpand %xmm11,%xmm12,%xmm7 + vpxor 112-128(%rax),%xmm2,%xmm2 + + vpaddd %xmm7,%xmm13,%xmm13 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm12,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vmovdqu %xmm1,224-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm2,%xmm5 + vpand %xmm10,%xmm6,%xmm6 + vpaddd %xmm2,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpaddd %xmm6,%xmm13,%xmm13 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 32-128(%rax),%xmm0 + + vpaddd %xmm15,%xmm12,%xmm12 + vpslld $5,%xmm13,%xmm8 + vpand %xmm10,%xmm11,%xmm7 + vpxor 128-128(%rax),%xmm3,%xmm3 + + vpaddd %xmm7,%xmm12,%xmm12 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm11,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vmovdqu %xmm2,240-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm3,%xmm5 + vpand %xmm14,%xmm6,%xmm6 + vpaddd %xmm3,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpaddd %xmm6,%xmm12,%xmm12 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 48-128(%rax),%xmm1 + + vpaddd %xmm15,%xmm11,%xmm11 + vpslld $5,%xmm12,%xmm8 + vpand %xmm14,%xmm10,%xmm7 + vpxor 144-128(%rax),%xmm4,%xmm4 + + vpaddd %xmm7,%xmm11,%xmm11 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm10,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vmovdqu %xmm3,0-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm4,%xmm5 + vpand %xmm13,%xmm6,%xmm6 + vpaddd %xmm4,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpaddd %xmm6,%xmm11,%xmm11 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 64-128(%rax),%xmm2 + + vpaddd %xmm15,%xmm10,%xmm10 + vpslld $5,%xmm11,%xmm8 + vpand %xmm13,%xmm14,%xmm7 + vpxor 160-128(%rax),%xmm0,%xmm0 + + vpaddd %xmm7,%xmm10,%xmm10 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm13,%xmm14,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + vmovdqu %xmm4,16-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm0,%xmm5 + vpand %xmm12,%xmm6,%xmm6 + vpaddd %xmm0,%xmm0,%xmm0 + + vpslld $30,%xmm12,%xmm7 + vpaddd %xmm6,%xmm10,%xmm10 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 80-128(%rax),%xmm3 + + vpaddd %xmm15,%xmm14,%xmm14 + vpslld $5,%xmm10,%xmm8 + vpand %xmm12,%xmm13,%xmm7 + vpxor 176-128(%rax),%xmm1,%xmm1 + + vpaddd %xmm7,%xmm14,%xmm14 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm13,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vmovdqu %xmm0,32-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm1,%xmm5 + vpand %xmm11,%xmm6,%xmm6 + vpaddd %xmm1,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpaddd %xmm6,%xmm14,%xmm14 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 96-128(%rax),%xmm4 + + vpaddd %xmm15,%xmm13,%xmm13 + vpslld $5,%xmm14,%xmm8 + vpand %xmm11,%xmm12,%xmm7 + vpxor 192-128(%rax),%xmm2,%xmm2 + + vpaddd %xmm7,%xmm13,%xmm13 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm12,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vmovdqu %xmm1,48-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm2,%xmm5 + vpand %xmm10,%xmm6,%xmm6 + vpaddd %xmm2,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpaddd %xmm6,%xmm13,%xmm13 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 112-128(%rax),%xmm0 + + vpaddd %xmm15,%xmm12,%xmm12 + vpslld $5,%xmm13,%xmm8 + vpand %xmm10,%xmm11,%xmm7 + vpxor 208-128(%rax),%xmm3,%xmm3 + + vpaddd %xmm7,%xmm12,%xmm12 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm11,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vmovdqu %xmm2,64-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm3,%xmm5 + vpand %xmm14,%xmm6,%xmm6 + vpaddd %xmm3,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpaddd %xmm6,%xmm12,%xmm12 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 128-128(%rax),%xmm1 + + vpaddd %xmm15,%xmm11,%xmm11 + vpslld $5,%xmm12,%xmm8 + vpand %xmm14,%xmm10,%xmm7 + vpxor 224-128(%rax),%xmm4,%xmm4 + + vpaddd %xmm7,%xmm11,%xmm11 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm10,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vmovdqu %xmm3,80-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm4,%xmm5 + vpand %xmm13,%xmm6,%xmm6 + vpaddd %xmm4,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpaddd %xmm6,%xmm11,%xmm11 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 144-128(%rax),%xmm2 + + vpaddd %xmm15,%xmm10,%xmm10 + vpslld $5,%xmm11,%xmm8 + vpand %xmm13,%xmm14,%xmm7 + vpxor 240-128(%rax),%xmm0,%xmm0 + + vpaddd %xmm7,%xmm10,%xmm10 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm13,%xmm14,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + vmovdqu %xmm4,96-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm0,%xmm5 + vpand %xmm12,%xmm6,%xmm6 + vpaddd %xmm0,%xmm0,%xmm0 + + vpslld $30,%xmm12,%xmm7 + vpaddd %xmm6,%xmm10,%xmm10 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 160-128(%rax),%xmm3 + + vpaddd %xmm15,%xmm14,%xmm14 + vpslld $5,%xmm10,%xmm8 + vpand %xmm12,%xmm13,%xmm7 + vpxor 0-128(%rax),%xmm1,%xmm1 + + vpaddd %xmm7,%xmm14,%xmm14 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm13,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vmovdqu %xmm0,112-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm1,%xmm5 + vpand %xmm11,%xmm6,%xmm6 + vpaddd %xmm1,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpaddd %xmm6,%xmm14,%xmm14 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 176-128(%rax),%xmm4 + + vpaddd %xmm15,%xmm13,%xmm13 + vpslld $5,%xmm14,%xmm8 + vpand %xmm11,%xmm12,%xmm7 + vpxor 16-128(%rax),%xmm2,%xmm2 + + vpaddd %xmm7,%xmm13,%xmm13 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm12,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vmovdqu %xmm1,128-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm2,%xmm5 + vpand %xmm10,%xmm6,%xmm6 + vpaddd %xmm2,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpaddd %xmm6,%xmm13,%xmm13 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 192-128(%rax),%xmm0 + + vpaddd %xmm15,%xmm12,%xmm12 + vpslld $5,%xmm13,%xmm8 + vpand %xmm10,%xmm11,%xmm7 + vpxor 32-128(%rax),%xmm3,%xmm3 + + vpaddd %xmm7,%xmm12,%xmm12 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm11,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vmovdqu %xmm2,144-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm3,%xmm5 + vpand %xmm14,%xmm6,%xmm6 + vpaddd %xmm3,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpaddd %xmm6,%xmm12,%xmm12 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 208-128(%rax),%xmm1 + + vpaddd %xmm15,%xmm11,%xmm11 + vpslld $5,%xmm12,%xmm8 + vpand %xmm14,%xmm10,%xmm7 + vpxor 48-128(%rax),%xmm4,%xmm4 + + vpaddd %xmm7,%xmm11,%xmm11 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm10,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vmovdqu %xmm3,160-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm4,%xmm5 + vpand %xmm13,%xmm6,%xmm6 + vpaddd %xmm4,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpaddd %xmm6,%xmm11,%xmm11 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 224-128(%rax),%xmm2 + + vpaddd %xmm15,%xmm10,%xmm10 + vpslld $5,%xmm11,%xmm8 + vpand %xmm13,%xmm14,%xmm7 + vpxor 64-128(%rax),%xmm0,%xmm0 + + vpaddd %xmm7,%xmm10,%xmm10 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm13,%xmm14,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + vmovdqu %xmm4,176-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpor %xmm9,%xmm8,%xmm8 + vpsrld $31,%xmm0,%xmm5 + vpand %xmm12,%xmm6,%xmm6 + vpaddd %xmm0,%xmm0,%xmm0 + + vpslld $30,%xmm12,%xmm7 + vpaddd %xmm6,%xmm10,%xmm10 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vmovdqa 64(%rbp),%xmm15 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 240-128(%rax),%xmm3 + + vpslld $5,%xmm10,%xmm8 + vpaddd %xmm15,%xmm14,%xmm14 + vpxor %xmm11,%xmm13,%xmm6 + vmovdqa %xmm0,192-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpxor 80-128(%rax),%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm6,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm14,%xmm14 + vpsrld $31,%xmm1,%xmm5 + vpaddd %xmm1,%xmm1,%xmm1 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 0-128(%rax),%xmm4 + + vpslld $5,%xmm14,%xmm8 + vpaddd %xmm15,%xmm13,%xmm13 + vpxor %xmm10,%xmm12,%xmm6 + vmovdqa %xmm1,208-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpxor 96-128(%rax),%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm6,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm13,%xmm13 + vpsrld $31,%xmm2,%xmm5 + vpaddd %xmm2,%xmm2,%xmm2 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 16-128(%rax),%xmm0 + + vpslld $5,%xmm13,%xmm8 + vpaddd %xmm15,%xmm12,%xmm12 + vpxor %xmm14,%xmm11,%xmm6 + vmovdqa %xmm2,224-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpxor 112-128(%rax),%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm6,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm12,%xmm12 + vpsrld $31,%xmm3,%xmm5 + vpaddd %xmm3,%xmm3,%xmm3 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 32-128(%rax),%xmm1 + + vpslld $5,%xmm12,%xmm8 + vpaddd %xmm15,%xmm11,%xmm11 + vpxor %xmm13,%xmm10,%xmm6 + vmovdqa %xmm3,240-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpxor 128-128(%rax),%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm11,%xmm11 + vpsrld $31,%xmm4,%xmm5 + vpaddd %xmm4,%xmm4,%xmm4 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 48-128(%rax),%xmm2 + + vpslld $5,%xmm11,%xmm8 + vpaddd %xmm15,%xmm10,%xmm10 + vpxor %xmm12,%xmm14,%xmm6 + vmovdqa %xmm4,0-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpxor 144-128(%rax),%xmm0,%xmm0 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm13,%xmm6,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm10,%xmm10 + vpsrld $31,%xmm0,%xmm5 + vpaddd %xmm0,%xmm0,%xmm0 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 64-128(%rax),%xmm3 + + vpslld $5,%xmm10,%xmm8 + vpaddd %xmm15,%xmm14,%xmm14 + vpxor %xmm11,%xmm13,%xmm6 + vmovdqa %xmm0,16-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpxor 160-128(%rax),%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm6,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm14,%xmm14 + vpsrld $31,%xmm1,%xmm5 + vpaddd %xmm1,%xmm1,%xmm1 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 80-128(%rax),%xmm4 + + vpslld $5,%xmm14,%xmm8 + vpaddd %xmm15,%xmm13,%xmm13 + vpxor %xmm10,%xmm12,%xmm6 + vmovdqa %xmm1,32-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpxor 176-128(%rax),%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm6,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm13,%xmm13 + vpsrld $31,%xmm2,%xmm5 + vpaddd %xmm2,%xmm2,%xmm2 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 96-128(%rax),%xmm0 + + vpslld $5,%xmm13,%xmm8 + vpaddd %xmm15,%xmm12,%xmm12 + vpxor %xmm14,%xmm11,%xmm6 + vmovdqa %xmm2,48-128(%rax) + vpaddd %xmm2,%xmm12,%xmm12 + vpxor 192-128(%rax),%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm6,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm12,%xmm12 + vpsrld $31,%xmm3,%xmm5 + vpaddd %xmm3,%xmm3,%xmm3 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 112-128(%rax),%xmm1 + + vpslld $5,%xmm12,%xmm8 + vpaddd %xmm15,%xmm11,%xmm11 + vpxor %xmm13,%xmm10,%xmm6 + vmovdqa %xmm3,64-128(%rax) + vpaddd %xmm3,%xmm11,%xmm11 + vpxor 208-128(%rax),%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm11,%xmm11 + vpsrld $31,%xmm4,%xmm5 + vpaddd %xmm4,%xmm4,%xmm4 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 128-128(%rax),%xmm2 + + vpslld $5,%xmm11,%xmm8 + vpaddd %xmm15,%xmm10,%xmm10 + vpxor %xmm12,%xmm14,%xmm6 + vmovdqa %xmm4,80-128(%rax) + vpaddd %xmm4,%xmm10,%xmm10 + vpxor 224-128(%rax),%xmm0,%xmm0 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm13,%xmm6,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm10,%xmm10 + vpsrld $31,%xmm0,%xmm5 + vpaddd %xmm0,%xmm0,%xmm0 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 144-128(%rax),%xmm3 + + vpslld $5,%xmm10,%xmm8 + vpaddd %xmm15,%xmm14,%xmm14 + vpxor %xmm11,%xmm13,%xmm6 + vmovdqa %xmm0,96-128(%rax) + vpaddd %xmm0,%xmm14,%xmm14 + vpxor 240-128(%rax),%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm6,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm14,%xmm14 + vpsrld $31,%xmm1,%xmm5 + vpaddd %xmm1,%xmm1,%xmm1 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 160-128(%rax),%xmm4 + + vpslld $5,%xmm14,%xmm8 + vpaddd %xmm15,%xmm13,%xmm13 + vpxor %xmm10,%xmm12,%xmm6 + vmovdqa %xmm1,112-128(%rax) + vpaddd %xmm1,%xmm13,%xmm13 + vpxor 0-128(%rax),%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm6,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm13,%xmm13 + vpsrld $31,%xmm2,%xmm5 + vpaddd %xmm2,%xmm2,%xmm2 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 176-128(%rax),%xmm0 + + vpslld $5,%xmm13,%xmm8 + vpaddd %xmm15,%xmm12,%xmm12 + vpxor %xmm14,%xmm11,%xmm6 + vpaddd %xmm2,%xmm12,%xmm12 + vpxor 16-128(%rax),%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm6,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm12,%xmm12 + vpsrld $31,%xmm3,%xmm5 + vpaddd %xmm3,%xmm3,%xmm3 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 192-128(%rax),%xmm1 + + vpslld $5,%xmm12,%xmm8 + vpaddd %xmm15,%xmm11,%xmm11 + vpxor %xmm13,%xmm10,%xmm6 + vpaddd %xmm3,%xmm11,%xmm11 + vpxor 32-128(%rax),%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm11,%xmm11 + vpsrld $31,%xmm4,%xmm5 + vpaddd %xmm4,%xmm4,%xmm4 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpxor %xmm2,%xmm0,%xmm0 + vmovdqa 208-128(%rax),%xmm2 + + vpslld $5,%xmm11,%xmm8 + vpaddd %xmm15,%xmm10,%xmm10 + vpxor %xmm12,%xmm14,%xmm6 + vpaddd %xmm4,%xmm10,%xmm10 + vpxor 48-128(%rax),%xmm0,%xmm0 + vpsrld $27,%xmm11,%xmm9 + vpxor %xmm13,%xmm6,%xmm6 + vpxor %xmm2,%xmm0,%xmm0 + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm10,%xmm10 + vpsrld $31,%xmm0,%xmm5 + vpaddd %xmm0,%xmm0,%xmm0 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm5,%xmm0,%xmm0 + vpor %xmm7,%xmm12,%xmm12 + vpxor %xmm3,%xmm1,%xmm1 + vmovdqa 224-128(%rax),%xmm3 + + vpslld $5,%xmm10,%xmm8 + vpaddd %xmm15,%xmm14,%xmm14 + vpxor %xmm11,%xmm13,%xmm6 + vpaddd %xmm0,%xmm14,%xmm14 + vpxor 64-128(%rax),%xmm1,%xmm1 + vpsrld $27,%xmm10,%xmm9 + vpxor %xmm12,%xmm6,%xmm6 + vpxor %xmm3,%xmm1,%xmm1 + + vpslld $30,%xmm11,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm14,%xmm14 + vpsrld $31,%xmm1,%xmm5 + vpaddd %xmm1,%xmm1,%xmm1 + + vpsrld $2,%xmm11,%xmm11 + vpaddd %xmm8,%xmm14,%xmm14 + vpor %xmm5,%xmm1,%xmm1 + vpor %xmm7,%xmm11,%xmm11 + vpxor %xmm4,%xmm2,%xmm2 + vmovdqa 240-128(%rax),%xmm4 + + vpslld $5,%xmm14,%xmm8 + vpaddd %xmm15,%xmm13,%xmm13 + vpxor %xmm10,%xmm12,%xmm6 + vpaddd %xmm1,%xmm13,%xmm13 + vpxor 80-128(%rax),%xmm2,%xmm2 + vpsrld $27,%xmm14,%xmm9 + vpxor %xmm11,%xmm6,%xmm6 + vpxor %xmm4,%xmm2,%xmm2 + + vpslld $30,%xmm10,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm13,%xmm13 + vpsrld $31,%xmm2,%xmm5 + vpaddd %xmm2,%xmm2,%xmm2 + + vpsrld $2,%xmm10,%xmm10 + vpaddd %xmm8,%xmm13,%xmm13 + vpor %xmm5,%xmm2,%xmm2 + vpor %xmm7,%xmm10,%xmm10 + vpxor %xmm0,%xmm3,%xmm3 + vmovdqa 0-128(%rax),%xmm0 + + vpslld $5,%xmm13,%xmm8 + vpaddd %xmm15,%xmm12,%xmm12 + vpxor %xmm14,%xmm11,%xmm6 + vpaddd %xmm2,%xmm12,%xmm12 + vpxor 96-128(%rax),%xmm3,%xmm3 + vpsrld $27,%xmm13,%xmm9 + vpxor %xmm10,%xmm6,%xmm6 + vpxor %xmm0,%xmm3,%xmm3 + + vpslld $30,%xmm14,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm12,%xmm12 + vpsrld $31,%xmm3,%xmm5 + vpaddd %xmm3,%xmm3,%xmm3 + + vpsrld $2,%xmm14,%xmm14 + vpaddd %xmm8,%xmm12,%xmm12 + vpor %xmm5,%xmm3,%xmm3 + vpor %xmm7,%xmm14,%xmm14 + vpxor %xmm1,%xmm4,%xmm4 + vmovdqa 16-128(%rax),%xmm1 + + vpslld $5,%xmm12,%xmm8 + vpaddd %xmm15,%xmm11,%xmm11 + vpxor %xmm13,%xmm10,%xmm6 + vpaddd %xmm3,%xmm11,%xmm11 + vpxor 112-128(%rax),%xmm4,%xmm4 + vpsrld $27,%xmm12,%xmm9 + vpxor %xmm14,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm4 + + vpslld $30,%xmm13,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm11,%xmm11 + vpsrld $31,%xmm4,%xmm5 + vpaddd %xmm4,%xmm4,%xmm4 + + vpsrld $2,%xmm13,%xmm13 + vpaddd %xmm8,%xmm11,%xmm11 + vpor %xmm5,%xmm4,%xmm4 + vpor %xmm7,%xmm13,%xmm13 + vpslld $5,%xmm11,%xmm8 + vpaddd %xmm15,%xmm10,%xmm10 + vpxor %xmm12,%xmm14,%xmm6 + + vpsrld $27,%xmm11,%xmm9 + vpaddd %xmm4,%xmm10,%xmm10 + vpxor %xmm13,%xmm6,%xmm6 + + vpslld $30,%xmm12,%xmm7 + vpor %xmm9,%xmm8,%xmm8 + vpaddd %xmm6,%xmm10,%xmm10 + + vpsrld $2,%xmm12,%xmm12 + vpaddd %xmm8,%xmm10,%xmm10 + vpor %xmm7,%xmm12,%xmm12 + movl $1,%ecx + cmpl 0(%rbx),%ecx + cmovgeq %rbp,%r8 + cmpl 4(%rbx),%ecx + cmovgeq %rbp,%r9 + cmpl 8(%rbx),%ecx + cmovgeq %rbp,%r10 + cmpl 12(%rbx),%ecx + cmovgeq %rbp,%r11 + vmovdqu (%rbx),%xmm6 + vpxor %xmm8,%xmm8,%xmm8 + vmovdqa %xmm6,%xmm7 + vpcmpgtd %xmm8,%xmm7,%xmm7 + vpaddd %xmm7,%xmm6,%xmm6 + + vpand %xmm7,%xmm10,%xmm10 + vpand %xmm7,%xmm11,%xmm11 + vpaddd 0(%rdi),%xmm10,%xmm10 + vpand %xmm7,%xmm12,%xmm12 + vpaddd 32(%rdi),%xmm11,%xmm11 + vpand %xmm7,%xmm13,%xmm13 + vpaddd 64(%rdi),%xmm12,%xmm12 + vpand %xmm7,%xmm14,%xmm14 + vpaddd 96(%rdi),%xmm13,%xmm13 + vpaddd 128(%rdi),%xmm14,%xmm14 + vmovdqu %xmm10,0(%rdi) + vmovdqu %xmm11,32(%rdi) + vmovdqu %xmm12,64(%rdi) + vmovdqu %xmm13,96(%rdi) + vmovdqu %xmm14,128(%rdi) + + vmovdqu %xmm6,(%rbx) + vmovdqu 96(%rbp),%xmm5 + decl %edx + jnz .Loop_avx + + movl 280(%rsp),%edx + leaq 16(%rdi),%rdi + leaq 64(%rsi),%rsi + decl %edx + jnz .Loop_grande_avx + +.Ldone_avx: + movq 272(%rsp),%rax +.cfi_def_cfa %rax,8 + vzeroupper + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_multi_block_avx,.-sha1_multi_block_avx +.type sha1_multi_block_avx2,@function +.align 32 +sha1_multi_block_avx2: +.cfi_startproc +_avx2_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + subq $576,%rsp + andq $-256,%rsp + movq %rax,544(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xa0,0x04,0x06,0x23,0x08 +.Lbody_avx2: + leaq K_XX_XX(%rip),%rbp + shrl $1,%edx + + vzeroupper +.Loop_grande_avx2: + movl %edx,552(%rsp) + xorl %edx,%edx + leaq 512(%rsp),%rbx + + movq 0(%rsi),%r12 + + movl 8(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,0(%rbx) + cmovleq %rbp,%r12 + + movq 16(%rsi),%r13 + + movl 24(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,4(%rbx) + cmovleq %rbp,%r13 + + movq 32(%rsi),%r14 + + movl 40(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,8(%rbx) + cmovleq %rbp,%r14 + + movq 48(%rsi),%r15 + + movl 56(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,12(%rbx) + cmovleq %rbp,%r15 + + movq 64(%rsi),%r8 + + movl 72(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,16(%rbx) + cmovleq %rbp,%r8 + + movq 80(%rsi),%r9 + + movl 88(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,20(%rbx) + cmovleq %rbp,%r9 + + movq 96(%rsi),%r10 + + movl 104(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,24(%rbx) + cmovleq %rbp,%r10 + + movq 112(%rsi),%r11 + + movl 120(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,28(%rbx) + cmovleq %rbp,%r11 + vmovdqu 0(%rdi),%ymm0 + leaq 128(%rsp),%rax + vmovdqu 32(%rdi),%ymm1 + leaq 256+128(%rsp),%rbx + vmovdqu 64(%rdi),%ymm2 + vmovdqu 96(%rdi),%ymm3 + vmovdqu 128(%rdi),%ymm4 + vmovdqu 96(%rbp),%ymm9 + jmp .Loop_avx2 + +.align 32 +.Loop_avx2: + vmovdqa -32(%rbp),%ymm15 + vmovd (%r12),%xmm10 + leaq 64(%r12),%r12 + vmovd (%r8),%xmm12 + leaq 64(%r8),%r8 + vmovd (%r13),%xmm7 + leaq 64(%r13),%r13 + vmovd (%r9),%xmm6 + leaq 64(%r9),%r9 + vpinsrd $1,(%r14),%xmm10,%xmm10 + leaq 64(%r14),%r14 + vpinsrd $1,(%r10),%xmm12,%xmm12 + leaq 64(%r10),%r10 + vpinsrd $1,(%r15),%xmm7,%xmm7 + leaq 64(%r15),%r15 + vpunpckldq %ymm7,%ymm10,%ymm10 + vpinsrd $1,(%r11),%xmm6,%xmm6 + leaq 64(%r11),%r11 + vpunpckldq %ymm6,%ymm12,%ymm12 + vmovd -60(%r12),%xmm11 + vinserti128 $1,%xmm12,%ymm10,%ymm10 + vmovd -60(%r8),%xmm8 + vpshufb %ymm9,%ymm10,%ymm10 + vmovd -60(%r13),%xmm7 + vmovd -60(%r9),%xmm6 + vpinsrd $1,-60(%r14),%xmm11,%xmm11 + vpinsrd $1,-60(%r10),%xmm8,%xmm8 + vpinsrd $1,-60(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm11,%ymm11 + vpinsrd $1,-60(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm4,%ymm4 + vpslld $5,%ymm0,%ymm7 + vpandn %ymm3,%ymm1,%ymm6 + vpand %ymm2,%ymm1,%ymm5 + + vmovdqa %ymm10,0-128(%rax) + vpaddd %ymm10,%ymm4,%ymm4 + vinserti128 $1,%xmm8,%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -56(%r12),%xmm12 + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -56(%r8),%xmm8 + vpaddd %ymm5,%ymm4,%ymm4 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpshufb %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vmovd -56(%r13),%xmm7 + vmovd -56(%r9),%xmm6 + vpinsrd $1,-56(%r14),%xmm12,%xmm12 + vpinsrd $1,-56(%r10),%xmm8,%xmm8 + vpinsrd $1,-56(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm12,%ymm12 + vpinsrd $1,-56(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm3,%ymm3 + vpslld $5,%ymm4,%ymm7 + vpandn %ymm2,%ymm0,%ymm6 + vpand %ymm1,%ymm0,%ymm5 + + vmovdqa %ymm11,32-128(%rax) + vpaddd %ymm11,%ymm3,%ymm3 + vinserti128 $1,%xmm8,%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -52(%r12),%xmm13 + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -52(%r8),%xmm8 + vpaddd %ymm5,%ymm3,%ymm3 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpshufb %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vmovd -52(%r13),%xmm7 + vmovd -52(%r9),%xmm6 + vpinsrd $1,-52(%r14),%xmm13,%xmm13 + vpinsrd $1,-52(%r10),%xmm8,%xmm8 + vpinsrd $1,-52(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm13,%ymm13 + vpinsrd $1,-52(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm2,%ymm2 + vpslld $5,%ymm3,%ymm7 + vpandn %ymm1,%ymm4,%ymm6 + vpand %ymm0,%ymm4,%ymm5 + + vmovdqa %ymm12,64-128(%rax) + vpaddd %ymm12,%ymm2,%ymm2 + vinserti128 $1,%xmm8,%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -48(%r12),%xmm14 + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -48(%r8),%xmm8 + vpaddd %ymm5,%ymm2,%ymm2 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpshufb %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vmovd -48(%r13),%xmm7 + vmovd -48(%r9),%xmm6 + vpinsrd $1,-48(%r14),%xmm14,%xmm14 + vpinsrd $1,-48(%r10),%xmm8,%xmm8 + vpinsrd $1,-48(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm14,%ymm14 + vpinsrd $1,-48(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm1,%ymm1 + vpslld $5,%ymm2,%ymm7 + vpandn %ymm0,%ymm3,%ymm6 + vpand %ymm4,%ymm3,%ymm5 + + vmovdqa %ymm13,96-128(%rax) + vpaddd %ymm13,%ymm1,%ymm1 + vinserti128 $1,%xmm8,%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -44(%r12),%xmm10 + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -44(%r8),%xmm8 + vpaddd %ymm5,%ymm1,%ymm1 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpshufb %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vmovd -44(%r13),%xmm7 + vmovd -44(%r9),%xmm6 + vpinsrd $1,-44(%r14),%xmm10,%xmm10 + vpinsrd $1,-44(%r10),%xmm8,%xmm8 + vpinsrd $1,-44(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm10,%ymm10 + vpinsrd $1,-44(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm0,%ymm0 + vpslld $5,%ymm1,%ymm7 + vpandn %ymm4,%ymm2,%ymm6 + vpand %ymm3,%ymm2,%ymm5 + + vmovdqa %ymm14,128-128(%rax) + vpaddd %ymm14,%ymm0,%ymm0 + vinserti128 $1,%xmm8,%ymm10,%ymm10 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -40(%r12),%xmm11 + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -40(%r8),%xmm8 + vpaddd %ymm5,%ymm0,%ymm0 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpshufb %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vmovd -40(%r13),%xmm7 + vmovd -40(%r9),%xmm6 + vpinsrd $1,-40(%r14),%xmm11,%xmm11 + vpinsrd $1,-40(%r10),%xmm8,%xmm8 + vpinsrd $1,-40(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm11,%ymm11 + vpinsrd $1,-40(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm4,%ymm4 + vpslld $5,%ymm0,%ymm7 + vpandn %ymm3,%ymm1,%ymm6 + vpand %ymm2,%ymm1,%ymm5 + + vmovdqa %ymm10,160-128(%rax) + vpaddd %ymm10,%ymm4,%ymm4 + vinserti128 $1,%xmm8,%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -36(%r12),%xmm12 + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -36(%r8),%xmm8 + vpaddd %ymm5,%ymm4,%ymm4 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpshufb %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vmovd -36(%r13),%xmm7 + vmovd -36(%r9),%xmm6 + vpinsrd $1,-36(%r14),%xmm12,%xmm12 + vpinsrd $1,-36(%r10),%xmm8,%xmm8 + vpinsrd $1,-36(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm12,%ymm12 + vpinsrd $1,-36(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm3,%ymm3 + vpslld $5,%ymm4,%ymm7 + vpandn %ymm2,%ymm0,%ymm6 + vpand %ymm1,%ymm0,%ymm5 + + vmovdqa %ymm11,192-128(%rax) + vpaddd %ymm11,%ymm3,%ymm3 + vinserti128 $1,%xmm8,%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -32(%r12),%xmm13 + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -32(%r8),%xmm8 + vpaddd %ymm5,%ymm3,%ymm3 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpshufb %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vmovd -32(%r13),%xmm7 + vmovd -32(%r9),%xmm6 + vpinsrd $1,-32(%r14),%xmm13,%xmm13 + vpinsrd $1,-32(%r10),%xmm8,%xmm8 + vpinsrd $1,-32(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm13,%ymm13 + vpinsrd $1,-32(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm2,%ymm2 + vpslld $5,%ymm3,%ymm7 + vpandn %ymm1,%ymm4,%ymm6 + vpand %ymm0,%ymm4,%ymm5 + + vmovdqa %ymm12,224-128(%rax) + vpaddd %ymm12,%ymm2,%ymm2 + vinserti128 $1,%xmm8,%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -28(%r12),%xmm14 + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -28(%r8),%xmm8 + vpaddd %ymm5,%ymm2,%ymm2 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpshufb %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vmovd -28(%r13),%xmm7 + vmovd -28(%r9),%xmm6 + vpinsrd $1,-28(%r14),%xmm14,%xmm14 + vpinsrd $1,-28(%r10),%xmm8,%xmm8 + vpinsrd $1,-28(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm14,%ymm14 + vpinsrd $1,-28(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm1,%ymm1 + vpslld $5,%ymm2,%ymm7 + vpandn %ymm0,%ymm3,%ymm6 + vpand %ymm4,%ymm3,%ymm5 + + vmovdqa %ymm13,256-256-128(%rbx) + vpaddd %ymm13,%ymm1,%ymm1 + vinserti128 $1,%xmm8,%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -24(%r12),%xmm10 + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -24(%r8),%xmm8 + vpaddd %ymm5,%ymm1,%ymm1 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpshufb %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vmovd -24(%r13),%xmm7 + vmovd -24(%r9),%xmm6 + vpinsrd $1,-24(%r14),%xmm10,%xmm10 + vpinsrd $1,-24(%r10),%xmm8,%xmm8 + vpinsrd $1,-24(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm10,%ymm10 + vpinsrd $1,-24(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm0,%ymm0 + vpslld $5,%ymm1,%ymm7 + vpandn %ymm4,%ymm2,%ymm6 + vpand %ymm3,%ymm2,%ymm5 + + vmovdqa %ymm14,288-256-128(%rbx) + vpaddd %ymm14,%ymm0,%ymm0 + vinserti128 $1,%xmm8,%ymm10,%ymm10 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -20(%r12),%xmm11 + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -20(%r8),%xmm8 + vpaddd %ymm5,%ymm0,%ymm0 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpshufb %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vmovd -20(%r13),%xmm7 + vmovd -20(%r9),%xmm6 + vpinsrd $1,-20(%r14),%xmm11,%xmm11 + vpinsrd $1,-20(%r10),%xmm8,%xmm8 + vpinsrd $1,-20(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm11,%ymm11 + vpinsrd $1,-20(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm4,%ymm4 + vpslld $5,%ymm0,%ymm7 + vpandn %ymm3,%ymm1,%ymm6 + vpand %ymm2,%ymm1,%ymm5 + + vmovdqa %ymm10,320-256-128(%rbx) + vpaddd %ymm10,%ymm4,%ymm4 + vinserti128 $1,%xmm8,%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -16(%r12),%xmm12 + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -16(%r8),%xmm8 + vpaddd %ymm5,%ymm4,%ymm4 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpshufb %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vmovd -16(%r13),%xmm7 + vmovd -16(%r9),%xmm6 + vpinsrd $1,-16(%r14),%xmm12,%xmm12 + vpinsrd $1,-16(%r10),%xmm8,%xmm8 + vpinsrd $1,-16(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm12,%ymm12 + vpinsrd $1,-16(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm3,%ymm3 + vpslld $5,%ymm4,%ymm7 + vpandn %ymm2,%ymm0,%ymm6 + vpand %ymm1,%ymm0,%ymm5 + + vmovdqa %ymm11,352-256-128(%rbx) + vpaddd %ymm11,%ymm3,%ymm3 + vinserti128 $1,%xmm8,%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -12(%r12),%xmm13 + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -12(%r8),%xmm8 + vpaddd %ymm5,%ymm3,%ymm3 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpshufb %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vmovd -12(%r13),%xmm7 + vmovd -12(%r9),%xmm6 + vpinsrd $1,-12(%r14),%xmm13,%xmm13 + vpinsrd $1,-12(%r10),%xmm8,%xmm8 + vpinsrd $1,-12(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm13,%ymm13 + vpinsrd $1,-12(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm2,%ymm2 + vpslld $5,%ymm3,%ymm7 + vpandn %ymm1,%ymm4,%ymm6 + vpand %ymm0,%ymm4,%ymm5 + + vmovdqa %ymm12,384-256-128(%rbx) + vpaddd %ymm12,%ymm2,%ymm2 + vinserti128 $1,%xmm8,%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -8(%r12),%xmm14 + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -8(%r8),%xmm8 + vpaddd %ymm5,%ymm2,%ymm2 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpshufb %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vmovd -8(%r13),%xmm7 + vmovd -8(%r9),%xmm6 + vpinsrd $1,-8(%r14),%xmm14,%xmm14 + vpinsrd $1,-8(%r10),%xmm8,%xmm8 + vpinsrd $1,-8(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm14,%ymm14 + vpinsrd $1,-8(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm1,%ymm1 + vpslld $5,%ymm2,%ymm7 + vpandn %ymm0,%ymm3,%ymm6 + vpand %ymm4,%ymm3,%ymm5 + + vmovdqa %ymm13,416-256-128(%rbx) + vpaddd %ymm13,%ymm1,%ymm1 + vinserti128 $1,%xmm8,%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vmovd -4(%r12),%xmm10 + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vmovd -4(%r8),%xmm8 + vpaddd %ymm5,%ymm1,%ymm1 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpshufb %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vmovdqa 0-128(%rax),%ymm11 + vmovd -4(%r13),%xmm7 + vmovd -4(%r9),%xmm6 + vpinsrd $1,-4(%r14),%xmm10,%xmm10 + vpinsrd $1,-4(%r10),%xmm8,%xmm8 + vpinsrd $1,-4(%r15),%xmm7,%xmm7 + vpunpckldq %ymm7,%ymm10,%ymm10 + vpinsrd $1,-4(%r11),%xmm6,%xmm6 + vpunpckldq %ymm6,%ymm8,%ymm8 + vpaddd %ymm15,%ymm0,%ymm0 + prefetcht0 63(%r12) + vpslld $5,%ymm1,%ymm7 + vpandn %ymm4,%ymm2,%ymm6 + vpand %ymm3,%ymm2,%ymm5 + + vmovdqa %ymm14,448-256-128(%rbx) + vpaddd %ymm14,%ymm0,%ymm0 + vinserti128 $1,%xmm8,%ymm10,%ymm10 + vpsrld $27,%ymm1,%ymm8 + prefetcht0 63(%r13) + vpxor %ymm6,%ymm5,%ymm5 + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + prefetcht0 63(%r14) + vpaddd %ymm5,%ymm0,%ymm0 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + prefetcht0 63(%r15) + vpshufb %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vmovdqa 32-128(%rax),%ymm12 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 64-128(%rax),%ymm13 + + vpaddd %ymm15,%ymm4,%ymm4 + vpslld $5,%ymm0,%ymm7 + vpandn %ymm3,%ymm1,%ymm6 + prefetcht0 63(%r8) + vpand %ymm2,%ymm1,%ymm5 + + vmovdqa %ymm10,480-256-128(%rbx) + vpaddd %ymm10,%ymm4,%ymm4 + vpxor 256-256-128(%rbx),%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + prefetcht0 63(%r9) + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm4,%ymm4 + prefetcht0 63(%r10) + vpsrld $31,%ymm11,%ymm9 + vpaddd %ymm11,%ymm11,%ymm11 + + vpsrld $2,%ymm1,%ymm1 + prefetcht0 63(%r11) + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 96-128(%rax),%ymm14 + + vpaddd %ymm15,%ymm3,%ymm3 + vpslld $5,%ymm4,%ymm7 + vpandn %ymm2,%ymm0,%ymm6 + + vpand %ymm1,%ymm0,%ymm5 + + vmovdqa %ymm11,0-128(%rax) + vpaddd %ymm11,%ymm3,%ymm3 + vpxor 288-256-128(%rbx),%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm3,%ymm3 + + vpsrld $31,%ymm12,%ymm9 + vpaddd %ymm12,%ymm12,%ymm12 + + vpsrld $2,%ymm0,%ymm0 + + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 128-128(%rax),%ymm10 + + vpaddd %ymm15,%ymm2,%ymm2 + vpslld $5,%ymm3,%ymm7 + vpandn %ymm1,%ymm4,%ymm6 + + vpand %ymm0,%ymm4,%ymm5 + + vmovdqa %ymm12,32-128(%rax) + vpaddd %ymm12,%ymm2,%ymm2 + vpxor 320-256-128(%rbx),%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm2,%ymm2 + + vpsrld $31,%ymm13,%ymm9 + vpaddd %ymm13,%ymm13,%ymm13 + + vpsrld $2,%ymm4,%ymm4 + + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 160-128(%rax),%ymm11 + + vpaddd %ymm15,%ymm1,%ymm1 + vpslld $5,%ymm2,%ymm7 + vpandn %ymm0,%ymm3,%ymm6 + + vpand %ymm4,%ymm3,%ymm5 + + vmovdqa %ymm13,64-128(%rax) + vpaddd %ymm13,%ymm1,%ymm1 + vpxor 352-256-128(%rbx),%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm1,%ymm1 + + vpsrld $31,%ymm14,%ymm9 + vpaddd %ymm14,%ymm14,%ymm14 + + vpsrld $2,%ymm3,%ymm3 + + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 192-128(%rax),%ymm12 + + vpaddd %ymm15,%ymm0,%ymm0 + vpslld $5,%ymm1,%ymm7 + vpandn %ymm4,%ymm2,%ymm6 + + vpand %ymm3,%ymm2,%ymm5 + + vmovdqa %ymm14,96-128(%rax) + vpaddd %ymm14,%ymm0,%ymm0 + vpxor 384-256-128(%rbx),%ymm10,%ymm10 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm6,%ymm5,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm0,%ymm0 + + vpsrld $31,%ymm10,%ymm9 + vpaddd %ymm10,%ymm10,%ymm10 + + vpsrld $2,%ymm2,%ymm2 + + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vmovdqa 0(%rbp),%ymm15 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 224-128(%rax),%ymm13 + + vpslld $5,%ymm0,%ymm7 + vpaddd %ymm15,%ymm4,%ymm4 + vpxor %ymm1,%ymm3,%ymm5 + vmovdqa %ymm10,128-128(%rax) + vpaddd %ymm10,%ymm4,%ymm4 + vpxor 416-256-128(%rbx),%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm5,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm4,%ymm4 + vpsrld $31,%ymm11,%ymm9 + vpaddd %ymm11,%ymm11,%ymm11 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 256-256-128(%rbx),%ymm14 + + vpslld $5,%ymm4,%ymm7 + vpaddd %ymm15,%ymm3,%ymm3 + vpxor %ymm0,%ymm2,%ymm5 + vmovdqa %ymm11,160-128(%rax) + vpaddd %ymm11,%ymm3,%ymm3 + vpxor 448-256-128(%rbx),%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm3,%ymm3 + vpsrld $31,%ymm12,%ymm9 + vpaddd %ymm12,%ymm12,%ymm12 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 288-256-128(%rbx),%ymm10 + + vpslld $5,%ymm3,%ymm7 + vpaddd %ymm15,%ymm2,%ymm2 + vpxor %ymm4,%ymm1,%ymm5 + vmovdqa %ymm12,192-128(%rax) + vpaddd %ymm12,%ymm2,%ymm2 + vpxor 480-256-128(%rbx),%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm5,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm2,%ymm2 + vpsrld $31,%ymm13,%ymm9 + vpaddd %ymm13,%ymm13,%ymm13 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 320-256-128(%rbx),%ymm11 + + vpslld $5,%ymm2,%ymm7 + vpaddd %ymm15,%ymm1,%ymm1 + vpxor %ymm3,%ymm0,%ymm5 + vmovdqa %ymm13,224-128(%rax) + vpaddd %ymm13,%ymm1,%ymm1 + vpxor 0-128(%rax),%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm5,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm1,%ymm1 + vpsrld $31,%ymm14,%ymm9 + vpaddd %ymm14,%ymm14,%ymm14 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 352-256-128(%rbx),%ymm12 + + vpslld $5,%ymm1,%ymm7 + vpaddd %ymm15,%ymm0,%ymm0 + vpxor %ymm2,%ymm4,%ymm5 + vmovdqa %ymm14,256-256-128(%rbx) + vpaddd %ymm14,%ymm0,%ymm0 + vpxor 32-128(%rax),%ymm10,%ymm10 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm3,%ymm5,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm0,%ymm0 + vpsrld $31,%ymm10,%ymm9 + vpaddd %ymm10,%ymm10,%ymm10 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 384-256-128(%rbx),%ymm13 + + vpslld $5,%ymm0,%ymm7 + vpaddd %ymm15,%ymm4,%ymm4 + vpxor %ymm1,%ymm3,%ymm5 + vmovdqa %ymm10,288-256-128(%rbx) + vpaddd %ymm10,%ymm4,%ymm4 + vpxor 64-128(%rax),%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm5,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm4,%ymm4 + vpsrld $31,%ymm11,%ymm9 + vpaddd %ymm11,%ymm11,%ymm11 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 416-256-128(%rbx),%ymm14 + + vpslld $5,%ymm4,%ymm7 + vpaddd %ymm15,%ymm3,%ymm3 + vpxor %ymm0,%ymm2,%ymm5 + vmovdqa %ymm11,320-256-128(%rbx) + vpaddd %ymm11,%ymm3,%ymm3 + vpxor 96-128(%rax),%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm3,%ymm3 + vpsrld $31,%ymm12,%ymm9 + vpaddd %ymm12,%ymm12,%ymm12 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 448-256-128(%rbx),%ymm10 + + vpslld $5,%ymm3,%ymm7 + vpaddd %ymm15,%ymm2,%ymm2 + vpxor %ymm4,%ymm1,%ymm5 + vmovdqa %ymm12,352-256-128(%rbx) + vpaddd %ymm12,%ymm2,%ymm2 + vpxor 128-128(%rax),%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm5,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm2,%ymm2 + vpsrld $31,%ymm13,%ymm9 + vpaddd %ymm13,%ymm13,%ymm13 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 480-256-128(%rbx),%ymm11 + + vpslld $5,%ymm2,%ymm7 + vpaddd %ymm15,%ymm1,%ymm1 + vpxor %ymm3,%ymm0,%ymm5 + vmovdqa %ymm13,384-256-128(%rbx) + vpaddd %ymm13,%ymm1,%ymm1 + vpxor 160-128(%rax),%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm5,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm1,%ymm1 + vpsrld $31,%ymm14,%ymm9 + vpaddd %ymm14,%ymm14,%ymm14 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 0-128(%rax),%ymm12 + + vpslld $5,%ymm1,%ymm7 + vpaddd %ymm15,%ymm0,%ymm0 + vpxor %ymm2,%ymm4,%ymm5 + vmovdqa %ymm14,416-256-128(%rbx) + vpaddd %ymm14,%ymm0,%ymm0 + vpxor 192-128(%rax),%ymm10,%ymm10 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm3,%ymm5,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm0,%ymm0 + vpsrld $31,%ymm10,%ymm9 + vpaddd %ymm10,%ymm10,%ymm10 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 32-128(%rax),%ymm13 + + vpslld $5,%ymm0,%ymm7 + vpaddd %ymm15,%ymm4,%ymm4 + vpxor %ymm1,%ymm3,%ymm5 + vmovdqa %ymm10,448-256-128(%rbx) + vpaddd %ymm10,%ymm4,%ymm4 + vpxor 224-128(%rax),%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm5,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm4,%ymm4 + vpsrld $31,%ymm11,%ymm9 + vpaddd %ymm11,%ymm11,%ymm11 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 64-128(%rax),%ymm14 + + vpslld $5,%ymm4,%ymm7 + vpaddd %ymm15,%ymm3,%ymm3 + vpxor %ymm0,%ymm2,%ymm5 + vmovdqa %ymm11,480-256-128(%rbx) + vpaddd %ymm11,%ymm3,%ymm3 + vpxor 256-256-128(%rbx),%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm3,%ymm3 + vpsrld $31,%ymm12,%ymm9 + vpaddd %ymm12,%ymm12,%ymm12 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 96-128(%rax),%ymm10 + + vpslld $5,%ymm3,%ymm7 + vpaddd %ymm15,%ymm2,%ymm2 + vpxor %ymm4,%ymm1,%ymm5 + vmovdqa %ymm12,0-128(%rax) + vpaddd %ymm12,%ymm2,%ymm2 + vpxor 288-256-128(%rbx),%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm5,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm2,%ymm2 + vpsrld $31,%ymm13,%ymm9 + vpaddd %ymm13,%ymm13,%ymm13 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 128-128(%rax),%ymm11 + + vpslld $5,%ymm2,%ymm7 + vpaddd %ymm15,%ymm1,%ymm1 + vpxor %ymm3,%ymm0,%ymm5 + vmovdqa %ymm13,32-128(%rax) + vpaddd %ymm13,%ymm1,%ymm1 + vpxor 320-256-128(%rbx),%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm5,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm1,%ymm1 + vpsrld $31,%ymm14,%ymm9 + vpaddd %ymm14,%ymm14,%ymm14 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 160-128(%rax),%ymm12 + + vpslld $5,%ymm1,%ymm7 + vpaddd %ymm15,%ymm0,%ymm0 + vpxor %ymm2,%ymm4,%ymm5 + vmovdqa %ymm14,64-128(%rax) + vpaddd %ymm14,%ymm0,%ymm0 + vpxor 352-256-128(%rbx),%ymm10,%ymm10 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm3,%ymm5,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm0,%ymm0 + vpsrld $31,%ymm10,%ymm9 + vpaddd %ymm10,%ymm10,%ymm10 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 192-128(%rax),%ymm13 + + vpslld $5,%ymm0,%ymm7 + vpaddd %ymm15,%ymm4,%ymm4 + vpxor %ymm1,%ymm3,%ymm5 + vmovdqa %ymm10,96-128(%rax) + vpaddd %ymm10,%ymm4,%ymm4 + vpxor 384-256-128(%rbx),%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm5,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm4,%ymm4 + vpsrld $31,%ymm11,%ymm9 + vpaddd %ymm11,%ymm11,%ymm11 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 224-128(%rax),%ymm14 + + vpslld $5,%ymm4,%ymm7 + vpaddd %ymm15,%ymm3,%ymm3 + vpxor %ymm0,%ymm2,%ymm5 + vmovdqa %ymm11,128-128(%rax) + vpaddd %ymm11,%ymm3,%ymm3 + vpxor 416-256-128(%rbx),%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm3,%ymm3 + vpsrld $31,%ymm12,%ymm9 + vpaddd %ymm12,%ymm12,%ymm12 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 256-256-128(%rbx),%ymm10 + + vpslld $5,%ymm3,%ymm7 + vpaddd %ymm15,%ymm2,%ymm2 + vpxor %ymm4,%ymm1,%ymm5 + vmovdqa %ymm12,160-128(%rax) + vpaddd %ymm12,%ymm2,%ymm2 + vpxor 448-256-128(%rbx),%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm5,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm2,%ymm2 + vpsrld $31,%ymm13,%ymm9 + vpaddd %ymm13,%ymm13,%ymm13 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 288-256-128(%rbx),%ymm11 + + vpslld $5,%ymm2,%ymm7 + vpaddd %ymm15,%ymm1,%ymm1 + vpxor %ymm3,%ymm0,%ymm5 + vmovdqa %ymm13,192-128(%rax) + vpaddd %ymm13,%ymm1,%ymm1 + vpxor 480-256-128(%rbx),%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm5,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm1,%ymm1 + vpsrld $31,%ymm14,%ymm9 + vpaddd %ymm14,%ymm14,%ymm14 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 320-256-128(%rbx),%ymm12 + + vpslld $5,%ymm1,%ymm7 + vpaddd %ymm15,%ymm0,%ymm0 + vpxor %ymm2,%ymm4,%ymm5 + vmovdqa %ymm14,224-128(%rax) + vpaddd %ymm14,%ymm0,%ymm0 + vpxor 0-128(%rax),%ymm10,%ymm10 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm3,%ymm5,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm0,%ymm0 + vpsrld $31,%ymm10,%ymm9 + vpaddd %ymm10,%ymm10,%ymm10 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vmovdqa 32(%rbp),%ymm15 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 352-256-128(%rbx),%ymm13 + + vpaddd %ymm15,%ymm4,%ymm4 + vpslld $5,%ymm0,%ymm7 + vpand %ymm2,%ymm3,%ymm6 + vpxor 32-128(%rax),%ymm11,%ymm11 + + vpaddd %ymm6,%ymm4,%ymm4 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm3,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vmovdqu %ymm10,256-256-128(%rbx) + vpaddd %ymm10,%ymm4,%ymm4 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm11,%ymm9 + vpand %ymm1,%ymm5,%ymm5 + vpaddd %ymm11,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpaddd %ymm5,%ymm4,%ymm4 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 384-256-128(%rbx),%ymm14 + + vpaddd %ymm15,%ymm3,%ymm3 + vpslld $5,%ymm4,%ymm7 + vpand %ymm1,%ymm2,%ymm6 + vpxor 64-128(%rax),%ymm12,%ymm12 + + vpaddd %ymm6,%ymm3,%ymm3 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm2,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vmovdqu %ymm11,288-256-128(%rbx) + vpaddd %ymm11,%ymm3,%ymm3 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm12,%ymm9 + vpand %ymm0,%ymm5,%ymm5 + vpaddd %ymm12,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpaddd %ymm5,%ymm3,%ymm3 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 416-256-128(%rbx),%ymm10 + + vpaddd %ymm15,%ymm2,%ymm2 + vpslld $5,%ymm3,%ymm7 + vpand %ymm0,%ymm1,%ymm6 + vpxor 96-128(%rax),%ymm13,%ymm13 + + vpaddd %ymm6,%ymm2,%ymm2 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm1,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vmovdqu %ymm12,320-256-128(%rbx) + vpaddd %ymm12,%ymm2,%ymm2 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm13,%ymm9 + vpand %ymm4,%ymm5,%ymm5 + vpaddd %ymm13,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpaddd %ymm5,%ymm2,%ymm2 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 448-256-128(%rbx),%ymm11 + + vpaddd %ymm15,%ymm1,%ymm1 + vpslld $5,%ymm2,%ymm7 + vpand %ymm4,%ymm0,%ymm6 + vpxor 128-128(%rax),%ymm14,%ymm14 + + vpaddd %ymm6,%ymm1,%ymm1 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm0,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vmovdqu %ymm13,352-256-128(%rbx) + vpaddd %ymm13,%ymm1,%ymm1 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm14,%ymm9 + vpand %ymm3,%ymm5,%ymm5 + vpaddd %ymm14,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpaddd %ymm5,%ymm1,%ymm1 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 480-256-128(%rbx),%ymm12 + + vpaddd %ymm15,%ymm0,%ymm0 + vpslld $5,%ymm1,%ymm7 + vpand %ymm3,%ymm4,%ymm6 + vpxor 160-128(%rax),%ymm10,%ymm10 + + vpaddd %ymm6,%ymm0,%ymm0 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm3,%ymm4,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + vmovdqu %ymm14,384-256-128(%rbx) + vpaddd %ymm14,%ymm0,%ymm0 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm10,%ymm9 + vpand %ymm2,%ymm5,%ymm5 + vpaddd %ymm10,%ymm10,%ymm10 + + vpslld $30,%ymm2,%ymm6 + vpaddd %ymm5,%ymm0,%ymm0 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 0-128(%rax),%ymm13 + + vpaddd %ymm15,%ymm4,%ymm4 + vpslld $5,%ymm0,%ymm7 + vpand %ymm2,%ymm3,%ymm6 + vpxor 192-128(%rax),%ymm11,%ymm11 + + vpaddd %ymm6,%ymm4,%ymm4 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm3,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vmovdqu %ymm10,416-256-128(%rbx) + vpaddd %ymm10,%ymm4,%ymm4 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm11,%ymm9 + vpand %ymm1,%ymm5,%ymm5 + vpaddd %ymm11,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpaddd %ymm5,%ymm4,%ymm4 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 32-128(%rax),%ymm14 + + vpaddd %ymm15,%ymm3,%ymm3 + vpslld $5,%ymm4,%ymm7 + vpand %ymm1,%ymm2,%ymm6 + vpxor 224-128(%rax),%ymm12,%ymm12 + + vpaddd %ymm6,%ymm3,%ymm3 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm2,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vmovdqu %ymm11,448-256-128(%rbx) + vpaddd %ymm11,%ymm3,%ymm3 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm12,%ymm9 + vpand %ymm0,%ymm5,%ymm5 + vpaddd %ymm12,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpaddd %ymm5,%ymm3,%ymm3 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 64-128(%rax),%ymm10 + + vpaddd %ymm15,%ymm2,%ymm2 + vpslld $5,%ymm3,%ymm7 + vpand %ymm0,%ymm1,%ymm6 + vpxor 256-256-128(%rbx),%ymm13,%ymm13 + + vpaddd %ymm6,%ymm2,%ymm2 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm1,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vmovdqu %ymm12,480-256-128(%rbx) + vpaddd %ymm12,%ymm2,%ymm2 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm13,%ymm9 + vpand %ymm4,%ymm5,%ymm5 + vpaddd %ymm13,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpaddd %ymm5,%ymm2,%ymm2 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 96-128(%rax),%ymm11 + + vpaddd %ymm15,%ymm1,%ymm1 + vpslld $5,%ymm2,%ymm7 + vpand %ymm4,%ymm0,%ymm6 + vpxor 288-256-128(%rbx),%ymm14,%ymm14 + + vpaddd %ymm6,%ymm1,%ymm1 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm0,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vmovdqu %ymm13,0-128(%rax) + vpaddd %ymm13,%ymm1,%ymm1 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm14,%ymm9 + vpand %ymm3,%ymm5,%ymm5 + vpaddd %ymm14,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpaddd %ymm5,%ymm1,%ymm1 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 128-128(%rax),%ymm12 + + vpaddd %ymm15,%ymm0,%ymm0 + vpslld $5,%ymm1,%ymm7 + vpand %ymm3,%ymm4,%ymm6 + vpxor 320-256-128(%rbx),%ymm10,%ymm10 + + vpaddd %ymm6,%ymm0,%ymm0 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm3,%ymm4,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + vmovdqu %ymm14,32-128(%rax) + vpaddd %ymm14,%ymm0,%ymm0 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm10,%ymm9 + vpand %ymm2,%ymm5,%ymm5 + vpaddd %ymm10,%ymm10,%ymm10 + + vpslld $30,%ymm2,%ymm6 + vpaddd %ymm5,%ymm0,%ymm0 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 160-128(%rax),%ymm13 + + vpaddd %ymm15,%ymm4,%ymm4 + vpslld $5,%ymm0,%ymm7 + vpand %ymm2,%ymm3,%ymm6 + vpxor 352-256-128(%rbx),%ymm11,%ymm11 + + vpaddd %ymm6,%ymm4,%ymm4 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm3,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vmovdqu %ymm10,64-128(%rax) + vpaddd %ymm10,%ymm4,%ymm4 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm11,%ymm9 + vpand %ymm1,%ymm5,%ymm5 + vpaddd %ymm11,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpaddd %ymm5,%ymm4,%ymm4 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 192-128(%rax),%ymm14 + + vpaddd %ymm15,%ymm3,%ymm3 + vpslld $5,%ymm4,%ymm7 + vpand %ymm1,%ymm2,%ymm6 + vpxor 384-256-128(%rbx),%ymm12,%ymm12 + + vpaddd %ymm6,%ymm3,%ymm3 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm2,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vmovdqu %ymm11,96-128(%rax) + vpaddd %ymm11,%ymm3,%ymm3 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm12,%ymm9 + vpand %ymm0,%ymm5,%ymm5 + vpaddd %ymm12,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpaddd %ymm5,%ymm3,%ymm3 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 224-128(%rax),%ymm10 + + vpaddd %ymm15,%ymm2,%ymm2 + vpslld $5,%ymm3,%ymm7 + vpand %ymm0,%ymm1,%ymm6 + vpxor 416-256-128(%rbx),%ymm13,%ymm13 + + vpaddd %ymm6,%ymm2,%ymm2 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm1,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vmovdqu %ymm12,128-128(%rax) + vpaddd %ymm12,%ymm2,%ymm2 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm13,%ymm9 + vpand %ymm4,%ymm5,%ymm5 + vpaddd %ymm13,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpaddd %ymm5,%ymm2,%ymm2 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 256-256-128(%rbx),%ymm11 + + vpaddd %ymm15,%ymm1,%ymm1 + vpslld $5,%ymm2,%ymm7 + vpand %ymm4,%ymm0,%ymm6 + vpxor 448-256-128(%rbx),%ymm14,%ymm14 + + vpaddd %ymm6,%ymm1,%ymm1 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm0,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vmovdqu %ymm13,160-128(%rax) + vpaddd %ymm13,%ymm1,%ymm1 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm14,%ymm9 + vpand %ymm3,%ymm5,%ymm5 + vpaddd %ymm14,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpaddd %ymm5,%ymm1,%ymm1 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 288-256-128(%rbx),%ymm12 + + vpaddd %ymm15,%ymm0,%ymm0 + vpslld $5,%ymm1,%ymm7 + vpand %ymm3,%ymm4,%ymm6 + vpxor 480-256-128(%rbx),%ymm10,%ymm10 + + vpaddd %ymm6,%ymm0,%ymm0 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm3,%ymm4,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + vmovdqu %ymm14,192-128(%rax) + vpaddd %ymm14,%ymm0,%ymm0 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm10,%ymm9 + vpand %ymm2,%ymm5,%ymm5 + vpaddd %ymm10,%ymm10,%ymm10 + + vpslld $30,%ymm2,%ymm6 + vpaddd %ymm5,%ymm0,%ymm0 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 320-256-128(%rbx),%ymm13 + + vpaddd %ymm15,%ymm4,%ymm4 + vpslld $5,%ymm0,%ymm7 + vpand %ymm2,%ymm3,%ymm6 + vpxor 0-128(%rax),%ymm11,%ymm11 + + vpaddd %ymm6,%ymm4,%ymm4 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm3,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vmovdqu %ymm10,224-128(%rax) + vpaddd %ymm10,%ymm4,%ymm4 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm11,%ymm9 + vpand %ymm1,%ymm5,%ymm5 + vpaddd %ymm11,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpaddd %ymm5,%ymm4,%ymm4 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 352-256-128(%rbx),%ymm14 + + vpaddd %ymm15,%ymm3,%ymm3 + vpslld $5,%ymm4,%ymm7 + vpand %ymm1,%ymm2,%ymm6 + vpxor 32-128(%rax),%ymm12,%ymm12 + + vpaddd %ymm6,%ymm3,%ymm3 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm2,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vmovdqu %ymm11,256-256-128(%rbx) + vpaddd %ymm11,%ymm3,%ymm3 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm12,%ymm9 + vpand %ymm0,%ymm5,%ymm5 + vpaddd %ymm12,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpaddd %ymm5,%ymm3,%ymm3 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 384-256-128(%rbx),%ymm10 + + vpaddd %ymm15,%ymm2,%ymm2 + vpslld $5,%ymm3,%ymm7 + vpand %ymm0,%ymm1,%ymm6 + vpxor 64-128(%rax),%ymm13,%ymm13 + + vpaddd %ymm6,%ymm2,%ymm2 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm1,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vmovdqu %ymm12,288-256-128(%rbx) + vpaddd %ymm12,%ymm2,%ymm2 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm13,%ymm9 + vpand %ymm4,%ymm5,%ymm5 + vpaddd %ymm13,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpaddd %ymm5,%ymm2,%ymm2 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 416-256-128(%rbx),%ymm11 + + vpaddd %ymm15,%ymm1,%ymm1 + vpslld $5,%ymm2,%ymm7 + vpand %ymm4,%ymm0,%ymm6 + vpxor 96-128(%rax),%ymm14,%ymm14 + + vpaddd %ymm6,%ymm1,%ymm1 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm0,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vmovdqu %ymm13,320-256-128(%rbx) + vpaddd %ymm13,%ymm1,%ymm1 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm14,%ymm9 + vpand %ymm3,%ymm5,%ymm5 + vpaddd %ymm14,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpaddd %ymm5,%ymm1,%ymm1 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 448-256-128(%rbx),%ymm12 + + vpaddd %ymm15,%ymm0,%ymm0 + vpslld $5,%ymm1,%ymm7 + vpand %ymm3,%ymm4,%ymm6 + vpxor 128-128(%rax),%ymm10,%ymm10 + + vpaddd %ymm6,%ymm0,%ymm0 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm3,%ymm4,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + vmovdqu %ymm14,352-256-128(%rbx) + vpaddd %ymm14,%ymm0,%ymm0 + vpor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm10,%ymm9 + vpand %ymm2,%ymm5,%ymm5 + vpaddd %ymm10,%ymm10,%ymm10 + + vpslld $30,%ymm2,%ymm6 + vpaddd %ymm5,%ymm0,%ymm0 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vmovdqa 64(%rbp),%ymm15 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 480-256-128(%rbx),%ymm13 + + vpslld $5,%ymm0,%ymm7 + vpaddd %ymm15,%ymm4,%ymm4 + vpxor %ymm1,%ymm3,%ymm5 + vmovdqa %ymm10,384-256-128(%rbx) + vpaddd %ymm10,%ymm4,%ymm4 + vpxor 160-128(%rax),%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm5,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm4,%ymm4 + vpsrld $31,%ymm11,%ymm9 + vpaddd %ymm11,%ymm11,%ymm11 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 0-128(%rax),%ymm14 + + vpslld $5,%ymm4,%ymm7 + vpaddd %ymm15,%ymm3,%ymm3 + vpxor %ymm0,%ymm2,%ymm5 + vmovdqa %ymm11,416-256-128(%rbx) + vpaddd %ymm11,%ymm3,%ymm3 + vpxor 192-128(%rax),%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm3,%ymm3 + vpsrld $31,%ymm12,%ymm9 + vpaddd %ymm12,%ymm12,%ymm12 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 32-128(%rax),%ymm10 + + vpslld $5,%ymm3,%ymm7 + vpaddd %ymm15,%ymm2,%ymm2 + vpxor %ymm4,%ymm1,%ymm5 + vmovdqa %ymm12,448-256-128(%rbx) + vpaddd %ymm12,%ymm2,%ymm2 + vpxor 224-128(%rax),%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm5,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm2,%ymm2 + vpsrld $31,%ymm13,%ymm9 + vpaddd %ymm13,%ymm13,%ymm13 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 64-128(%rax),%ymm11 + + vpslld $5,%ymm2,%ymm7 + vpaddd %ymm15,%ymm1,%ymm1 + vpxor %ymm3,%ymm0,%ymm5 + vmovdqa %ymm13,480-256-128(%rbx) + vpaddd %ymm13,%ymm1,%ymm1 + vpxor 256-256-128(%rbx),%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm5,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm1,%ymm1 + vpsrld $31,%ymm14,%ymm9 + vpaddd %ymm14,%ymm14,%ymm14 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 96-128(%rax),%ymm12 + + vpslld $5,%ymm1,%ymm7 + vpaddd %ymm15,%ymm0,%ymm0 + vpxor %ymm2,%ymm4,%ymm5 + vmovdqa %ymm14,0-128(%rax) + vpaddd %ymm14,%ymm0,%ymm0 + vpxor 288-256-128(%rbx),%ymm10,%ymm10 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm3,%ymm5,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm0,%ymm0 + vpsrld $31,%ymm10,%ymm9 + vpaddd %ymm10,%ymm10,%ymm10 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 128-128(%rax),%ymm13 + + vpslld $5,%ymm0,%ymm7 + vpaddd %ymm15,%ymm4,%ymm4 + vpxor %ymm1,%ymm3,%ymm5 + vmovdqa %ymm10,32-128(%rax) + vpaddd %ymm10,%ymm4,%ymm4 + vpxor 320-256-128(%rbx),%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm5,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm4,%ymm4 + vpsrld $31,%ymm11,%ymm9 + vpaddd %ymm11,%ymm11,%ymm11 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 160-128(%rax),%ymm14 + + vpslld $5,%ymm4,%ymm7 + vpaddd %ymm15,%ymm3,%ymm3 + vpxor %ymm0,%ymm2,%ymm5 + vmovdqa %ymm11,64-128(%rax) + vpaddd %ymm11,%ymm3,%ymm3 + vpxor 352-256-128(%rbx),%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm3,%ymm3 + vpsrld $31,%ymm12,%ymm9 + vpaddd %ymm12,%ymm12,%ymm12 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 192-128(%rax),%ymm10 + + vpslld $5,%ymm3,%ymm7 + vpaddd %ymm15,%ymm2,%ymm2 + vpxor %ymm4,%ymm1,%ymm5 + vmovdqa %ymm12,96-128(%rax) + vpaddd %ymm12,%ymm2,%ymm2 + vpxor 384-256-128(%rbx),%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm5,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm2,%ymm2 + vpsrld $31,%ymm13,%ymm9 + vpaddd %ymm13,%ymm13,%ymm13 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 224-128(%rax),%ymm11 + + vpslld $5,%ymm2,%ymm7 + vpaddd %ymm15,%ymm1,%ymm1 + vpxor %ymm3,%ymm0,%ymm5 + vmovdqa %ymm13,128-128(%rax) + vpaddd %ymm13,%ymm1,%ymm1 + vpxor 416-256-128(%rbx),%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm5,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm1,%ymm1 + vpsrld $31,%ymm14,%ymm9 + vpaddd %ymm14,%ymm14,%ymm14 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 256-256-128(%rbx),%ymm12 + + vpslld $5,%ymm1,%ymm7 + vpaddd %ymm15,%ymm0,%ymm0 + vpxor %ymm2,%ymm4,%ymm5 + vmovdqa %ymm14,160-128(%rax) + vpaddd %ymm14,%ymm0,%ymm0 + vpxor 448-256-128(%rbx),%ymm10,%ymm10 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm3,%ymm5,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm0,%ymm0 + vpsrld $31,%ymm10,%ymm9 + vpaddd %ymm10,%ymm10,%ymm10 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 288-256-128(%rbx),%ymm13 + + vpslld $5,%ymm0,%ymm7 + vpaddd %ymm15,%ymm4,%ymm4 + vpxor %ymm1,%ymm3,%ymm5 + vmovdqa %ymm10,192-128(%rax) + vpaddd %ymm10,%ymm4,%ymm4 + vpxor 480-256-128(%rbx),%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm5,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm4,%ymm4 + vpsrld $31,%ymm11,%ymm9 + vpaddd %ymm11,%ymm11,%ymm11 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 320-256-128(%rbx),%ymm14 + + vpslld $5,%ymm4,%ymm7 + vpaddd %ymm15,%ymm3,%ymm3 + vpxor %ymm0,%ymm2,%ymm5 + vmovdqa %ymm11,224-128(%rax) + vpaddd %ymm11,%ymm3,%ymm3 + vpxor 0-128(%rax),%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm3,%ymm3 + vpsrld $31,%ymm12,%ymm9 + vpaddd %ymm12,%ymm12,%ymm12 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 352-256-128(%rbx),%ymm10 + + vpslld $5,%ymm3,%ymm7 + vpaddd %ymm15,%ymm2,%ymm2 + vpxor %ymm4,%ymm1,%ymm5 + vpaddd %ymm12,%ymm2,%ymm2 + vpxor 32-128(%rax),%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm5,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm2,%ymm2 + vpsrld $31,%ymm13,%ymm9 + vpaddd %ymm13,%ymm13,%ymm13 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 384-256-128(%rbx),%ymm11 + + vpslld $5,%ymm2,%ymm7 + vpaddd %ymm15,%ymm1,%ymm1 + vpxor %ymm3,%ymm0,%ymm5 + vpaddd %ymm13,%ymm1,%ymm1 + vpxor 64-128(%rax),%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm5,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm1,%ymm1 + vpsrld $31,%ymm14,%ymm9 + vpaddd %ymm14,%ymm14,%ymm14 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpxor %ymm12,%ymm10,%ymm10 + vmovdqa 416-256-128(%rbx),%ymm12 + + vpslld $5,%ymm1,%ymm7 + vpaddd %ymm15,%ymm0,%ymm0 + vpxor %ymm2,%ymm4,%ymm5 + vpaddd %ymm14,%ymm0,%ymm0 + vpxor 96-128(%rax),%ymm10,%ymm10 + vpsrld $27,%ymm1,%ymm8 + vpxor %ymm3,%ymm5,%ymm5 + vpxor %ymm12,%ymm10,%ymm10 + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm0,%ymm0 + vpsrld $31,%ymm10,%ymm9 + vpaddd %ymm10,%ymm10,%ymm10 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm9,%ymm10,%ymm10 + vpor %ymm6,%ymm2,%ymm2 + vpxor %ymm13,%ymm11,%ymm11 + vmovdqa 448-256-128(%rbx),%ymm13 + + vpslld $5,%ymm0,%ymm7 + vpaddd %ymm15,%ymm4,%ymm4 + vpxor %ymm1,%ymm3,%ymm5 + vpaddd %ymm10,%ymm4,%ymm4 + vpxor 128-128(%rax),%ymm11,%ymm11 + vpsrld $27,%ymm0,%ymm8 + vpxor %ymm2,%ymm5,%ymm5 + vpxor %ymm13,%ymm11,%ymm11 + + vpslld $30,%ymm1,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm4,%ymm4 + vpsrld $31,%ymm11,%ymm9 + vpaddd %ymm11,%ymm11,%ymm11 + + vpsrld $2,%ymm1,%ymm1 + vpaddd %ymm7,%ymm4,%ymm4 + vpor %ymm9,%ymm11,%ymm11 + vpor %ymm6,%ymm1,%ymm1 + vpxor %ymm14,%ymm12,%ymm12 + vmovdqa 480-256-128(%rbx),%ymm14 + + vpslld $5,%ymm4,%ymm7 + vpaddd %ymm15,%ymm3,%ymm3 + vpxor %ymm0,%ymm2,%ymm5 + vpaddd %ymm11,%ymm3,%ymm3 + vpxor 160-128(%rax),%ymm12,%ymm12 + vpsrld $27,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm14,%ymm12,%ymm12 + + vpslld $30,%ymm0,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm3,%ymm3 + vpsrld $31,%ymm12,%ymm9 + vpaddd %ymm12,%ymm12,%ymm12 + + vpsrld $2,%ymm0,%ymm0 + vpaddd %ymm7,%ymm3,%ymm3 + vpor %ymm9,%ymm12,%ymm12 + vpor %ymm6,%ymm0,%ymm0 + vpxor %ymm10,%ymm13,%ymm13 + vmovdqa 0-128(%rax),%ymm10 + + vpslld $5,%ymm3,%ymm7 + vpaddd %ymm15,%ymm2,%ymm2 + vpxor %ymm4,%ymm1,%ymm5 + vpaddd %ymm12,%ymm2,%ymm2 + vpxor 192-128(%rax),%ymm13,%ymm13 + vpsrld $27,%ymm3,%ymm8 + vpxor %ymm0,%ymm5,%ymm5 + vpxor %ymm10,%ymm13,%ymm13 + + vpslld $30,%ymm4,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm2,%ymm2 + vpsrld $31,%ymm13,%ymm9 + vpaddd %ymm13,%ymm13,%ymm13 + + vpsrld $2,%ymm4,%ymm4 + vpaddd %ymm7,%ymm2,%ymm2 + vpor %ymm9,%ymm13,%ymm13 + vpor %ymm6,%ymm4,%ymm4 + vpxor %ymm11,%ymm14,%ymm14 + vmovdqa 32-128(%rax),%ymm11 + + vpslld $5,%ymm2,%ymm7 + vpaddd %ymm15,%ymm1,%ymm1 + vpxor %ymm3,%ymm0,%ymm5 + vpaddd %ymm13,%ymm1,%ymm1 + vpxor 224-128(%rax),%ymm14,%ymm14 + vpsrld $27,%ymm2,%ymm8 + vpxor %ymm4,%ymm5,%ymm5 + vpxor %ymm11,%ymm14,%ymm14 + + vpslld $30,%ymm3,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm1,%ymm1 + vpsrld $31,%ymm14,%ymm9 + vpaddd %ymm14,%ymm14,%ymm14 + + vpsrld $2,%ymm3,%ymm3 + vpaddd %ymm7,%ymm1,%ymm1 + vpor %ymm9,%ymm14,%ymm14 + vpor %ymm6,%ymm3,%ymm3 + vpslld $5,%ymm1,%ymm7 + vpaddd %ymm15,%ymm0,%ymm0 + vpxor %ymm2,%ymm4,%ymm5 + + vpsrld $27,%ymm1,%ymm8 + vpaddd %ymm14,%ymm0,%ymm0 + vpxor %ymm3,%ymm5,%ymm5 + + vpslld $30,%ymm2,%ymm6 + vpor %ymm8,%ymm7,%ymm7 + vpaddd %ymm5,%ymm0,%ymm0 + + vpsrld $2,%ymm2,%ymm2 + vpaddd %ymm7,%ymm0,%ymm0 + vpor %ymm6,%ymm2,%ymm2 + movl $1,%ecx + leaq 512(%rsp),%rbx + cmpl 0(%rbx),%ecx + cmovgeq %rbp,%r12 + cmpl 4(%rbx),%ecx + cmovgeq %rbp,%r13 + cmpl 8(%rbx),%ecx + cmovgeq %rbp,%r14 + cmpl 12(%rbx),%ecx + cmovgeq %rbp,%r15 + cmpl 16(%rbx),%ecx + cmovgeq %rbp,%r8 + cmpl 20(%rbx),%ecx + cmovgeq %rbp,%r9 + cmpl 24(%rbx),%ecx + cmovgeq %rbp,%r10 + cmpl 28(%rbx),%ecx + cmovgeq %rbp,%r11 + vmovdqu (%rbx),%ymm5 + vpxor %ymm7,%ymm7,%ymm7 + vmovdqa %ymm5,%ymm6 + vpcmpgtd %ymm7,%ymm6,%ymm6 + vpaddd %ymm6,%ymm5,%ymm5 + + vpand %ymm6,%ymm0,%ymm0 + vpand %ymm6,%ymm1,%ymm1 + vpaddd 0(%rdi),%ymm0,%ymm0 + vpand %ymm6,%ymm2,%ymm2 + vpaddd 32(%rdi),%ymm1,%ymm1 + vpand %ymm6,%ymm3,%ymm3 + vpaddd 64(%rdi),%ymm2,%ymm2 + vpand %ymm6,%ymm4,%ymm4 + vpaddd 96(%rdi),%ymm3,%ymm3 + vpaddd 128(%rdi),%ymm4,%ymm4 + vmovdqu %ymm0,0(%rdi) + vmovdqu %ymm1,32(%rdi) + vmovdqu %ymm2,64(%rdi) + vmovdqu %ymm3,96(%rdi) + vmovdqu %ymm4,128(%rdi) + + vmovdqu %ymm5,(%rbx) + leaq 256+128(%rsp),%rbx + vmovdqu 96(%rbp),%ymm9 + decl %edx + jnz .Loop_avx2 + + + + + + + +.Ldone_avx2: + movq 544(%rsp),%rax +.cfi_def_cfa %rax,8 + vzeroupper + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx2: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_multi_block_avx2,.-sha1_multi_block_avx2 + +.align 256 +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +K_XX_XX: +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.byte 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 +.byte 83,72,65,49,32,109,117,108,116,105,45,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/sha/sha1-x86_64.S b/crypto/openssl/crypto/sha/sha1-x86_64.S new file mode 100644 index 000000000000..85e9a2909f8a --- /dev/null +++ b/crypto/openssl/crypto/sha/sha1-x86_64.S @@ -0,0 +1,5471 @@ +.text + + +.globl sha1_block_data_order +.type sha1_block_data_order,@function +.align 16 +sha1_block_data_order: +.cfi_startproc + movl OPENSSL_ia32cap_P+0(%rip),%r9d + movl OPENSSL_ia32cap_P+4(%rip),%r8d + movl OPENSSL_ia32cap_P+8(%rip),%r10d + testl $512,%r8d + jz .Lialu + testl $536870912,%r10d + jnz _shaext_shortcut + andl $296,%r10d + cmpl $296,%r10d + je _avx2_shortcut + andl $268435456,%r8d + andl $1073741824,%r9d + orl %r9d,%r8d + cmpl $1342177280,%r8d + je _avx_shortcut + jmp _ssse3_shortcut + +.align 16 +.Lialu: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + movq %rdi,%r8 + subq $72,%rsp + movq %rsi,%r9 + andq $-64,%rsp + movq %rdx,%r10 + movq %rax,64(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xc0,0x00,0x06,0x23,0x08 +.Lprologue: + + movl 0(%r8),%esi + movl 4(%r8),%edi + movl 8(%r8),%r11d + movl 12(%r8),%r12d + movl 16(%r8),%r13d + jmp .Lloop + +.align 16 +.Lloop: + movl 0(%r9),%edx + bswapl %edx + movl 4(%r9),%ebp + movl %r12d,%eax + movl %edx,0(%rsp) + movl %esi,%ecx + bswapl %ebp + xorl %r11d,%eax + roll $5,%ecx + andl %edi,%eax + leal 1518500249(%rdx,%r13,1),%r13d + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl 8(%r9),%r14d + movl %r11d,%eax + movl %ebp,4(%rsp) + movl %r13d,%ecx + bswapl %r14d + xorl %edi,%eax + roll $5,%ecx + andl %esi,%eax + leal 1518500249(%rbp,%r12,1),%r12d + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl 12(%r9),%edx + movl %edi,%eax + movl %r14d,8(%rsp) + movl %r12d,%ecx + bswapl %edx + xorl %esi,%eax + roll $5,%ecx + andl %r13d,%eax + leal 1518500249(%r14,%r11,1),%r11d + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl 16(%r9),%ebp + movl %esi,%eax + movl %edx,12(%rsp) + movl %r11d,%ecx + bswapl %ebp + xorl %r13d,%eax + roll $5,%ecx + andl %r12d,%eax + leal 1518500249(%rdx,%rdi,1),%edi + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl 20(%r9),%r14d + movl %r13d,%eax + movl %ebp,16(%rsp) + movl %edi,%ecx + bswapl %r14d + xorl %r12d,%eax + roll $5,%ecx + andl %r11d,%eax + leal 1518500249(%rbp,%rsi,1),%esi + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl 24(%r9),%edx + movl %r12d,%eax + movl %r14d,20(%rsp) + movl %esi,%ecx + bswapl %edx + xorl %r11d,%eax + roll $5,%ecx + andl %edi,%eax + leal 1518500249(%r14,%r13,1),%r13d + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl 28(%r9),%ebp + movl %r11d,%eax + movl %edx,24(%rsp) + movl %r13d,%ecx + bswapl %ebp + xorl %edi,%eax + roll $5,%ecx + andl %esi,%eax + leal 1518500249(%rdx,%r12,1),%r12d + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl 32(%r9),%r14d + movl %edi,%eax + movl %ebp,28(%rsp) + movl %r12d,%ecx + bswapl %r14d + xorl %esi,%eax + roll $5,%ecx + andl %r13d,%eax + leal 1518500249(%rbp,%r11,1),%r11d + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl 36(%r9),%edx + movl %esi,%eax + movl %r14d,32(%rsp) + movl %r11d,%ecx + bswapl %edx + xorl %r13d,%eax + roll $5,%ecx + andl %r12d,%eax + leal 1518500249(%r14,%rdi,1),%edi + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl 40(%r9),%ebp + movl %r13d,%eax + movl %edx,36(%rsp) + movl %edi,%ecx + bswapl %ebp + xorl %r12d,%eax + roll $5,%ecx + andl %r11d,%eax + leal 1518500249(%rdx,%rsi,1),%esi + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + movl 44(%r9),%r14d + movl %r12d,%eax + movl %ebp,40(%rsp) + movl %esi,%ecx + bswapl %r14d + xorl %r11d,%eax + roll $5,%ecx + andl %edi,%eax + leal 1518500249(%rbp,%r13,1),%r13d + addl %ecx,%r13d + xorl %r12d,%eax + roll $30,%edi + addl %eax,%r13d + movl 48(%r9),%edx + movl %r11d,%eax + movl %r14d,44(%rsp) + movl %r13d,%ecx + bswapl %edx + xorl %edi,%eax + roll $5,%ecx + andl %esi,%eax + leal 1518500249(%r14,%r12,1),%r12d + addl %ecx,%r12d + xorl %r11d,%eax + roll $30,%esi + addl %eax,%r12d + movl 52(%r9),%ebp + movl %edi,%eax + movl %edx,48(%rsp) + movl %r12d,%ecx + bswapl %ebp + xorl %esi,%eax + roll $5,%ecx + andl %r13d,%eax + leal 1518500249(%rdx,%r11,1),%r11d + addl %ecx,%r11d + xorl %edi,%eax + roll $30,%r13d + addl %eax,%r11d + movl 56(%r9),%r14d + movl %esi,%eax + movl %ebp,52(%rsp) + movl %r11d,%ecx + bswapl %r14d + xorl %r13d,%eax + roll $5,%ecx + andl %r12d,%eax + leal 1518500249(%rbp,%rdi,1),%edi + addl %ecx,%edi + xorl %esi,%eax + roll $30,%r12d + addl %eax,%edi + movl 60(%r9),%edx + movl %r13d,%eax + movl %r14d,56(%rsp) + movl %edi,%ecx + bswapl %edx + xorl %r12d,%eax + roll $5,%ecx + andl %r11d,%eax + leal 1518500249(%r14,%rsi,1),%esi + addl %ecx,%esi + xorl %r13d,%eax + roll $30,%r11d + addl %eax,%esi + xorl 0(%rsp),%ebp + movl %r12d,%eax + movl %edx,60(%rsp) + movl %esi,%ecx + xorl 8(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 32(%rsp),%ebp + andl %edi,%eax + leal 1518500249(%rdx,%r13,1),%r13d + roll $30,%edi + xorl %r12d,%eax + addl %ecx,%r13d + roll $1,%ebp + addl %eax,%r13d + xorl 4(%rsp),%r14d + movl %r11d,%eax + movl %ebp,0(%rsp) + movl %r13d,%ecx + xorl 12(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 36(%rsp),%r14d + andl %esi,%eax + leal 1518500249(%rbp,%r12,1),%r12d + roll $30,%esi + xorl %r11d,%eax + addl %ecx,%r12d + roll $1,%r14d + addl %eax,%r12d + xorl 8(%rsp),%edx + movl %edi,%eax + movl %r14d,4(%rsp) + movl %r12d,%ecx + xorl 16(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 40(%rsp),%edx + andl %r13d,%eax + leal 1518500249(%r14,%r11,1),%r11d + roll $30,%r13d + xorl %edi,%eax + addl %ecx,%r11d + roll $1,%edx + addl %eax,%r11d + xorl 12(%rsp),%ebp + movl %esi,%eax + movl %edx,8(%rsp) + movl %r11d,%ecx + xorl 20(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 44(%rsp),%ebp + andl %r12d,%eax + leal 1518500249(%rdx,%rdi,1),%edi + roll $30,%r12d + xorl %esi,%eax + addl %ecx,%edi + roll $1,%ebp + addl %eax,%edi + xorl 16(%rsp),%r14d + movl %r13d,%eax + movl %ebp,12(%rsp) + movl %edi,%ecx + xorl 24(%rsp),%r14d + xorl %r12d,%eax + roll $5,%ecx + xorl 48(%rsp),%r14d + andl %r11d,%eax + leal 1518500249(%rbp,%rsi,1),%esi + roll $30,%r11d + xorl %r13d,%eax + addl %ecx,%esi + roll $1,%r14d + addl %eax,%esi + xorl 20(%rsp),%edx + movl %edi,%eax + movl %r14d,16(%rsp) + movl %esi,%ecx + xorl 28(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 52(%rsp),%edx + leal 1859775393(%r14,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + xorl 24(%rsp),%ebp + movl %esi,%eax + movl %edx,20(%rsp) + movl %r13d,%ecx + xorl 32(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 56(%rsp),%ebp + leal 1859775393(%rdx,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + xorl 28(%rsp),%r14d + movl %r13d,%eax + movl %ebp,24(%rsp) + movl %r12d,%ecx + xorl 36(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 60(%rsp),%r14d + leal 1859775393(%rbp,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%r14d + xorl 32(%rsp),%edx + movl %r12d,%eax + movl %r14d,28(%rsp) + movl %r11d,%ecx + xorl 40(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 0(%rsp),%edx + leal 1859775393(%r14,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + xorl 36(%rsp),%ebp + movl %r11d,%eax + movl %edx,32(%rsp) + movl %edi,%ecx + xorl 44(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 4(%rsp),%ebp + leal 1859775393(%rdx,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + xorl 40(%rsp),%r14d + movl %edi,%eax + movl %ebp,36(%rsp) + movl %esi,%ecx + xorl 48(%rsp),%r14d + xorl %r12d,%eax + roll $5,%ecx + xorl 8(%rsp),%r14d + leal 1859775393(%rbp,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%r14d + xorl 44(%rsp),%edx + movl %esi,%eax + movl %r14d,40(%rsp) + movl %r13d,%ecx + xorl 52(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + xorl 12(%rsp),%edx + leal 1859775393(%r14,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + xorl 48(%rsp),%ebp + movl %r13d,%eax + movl %edx,44(%rsp) + movl %r12d,%ecx + xorl 56(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + xorl 16(%rsp),%ebp + leal 1859775393(%rdx,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + xorl 52(%rsp),%r14d + movl %r12d,%eax + movl %ebp,48(%rsp) + movl %r11d,%ecx + xorl 60(%rsp),%r14d + xorl %esi,%eax + roll $5,%ecx + xorl 20(%rsp),%r14d + leal 1859775393(%rbp,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%r14d + xorl 56(%rsp),%edx + movl %r11d,%eax + movl %r14d,52(%rsp) + movl %edi,%ecx + xorl 0(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + xorl 24(%rsp),%edx + leal 1859775393(%r14,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + xorl 60(%rsp),%ebp + movl %edi,%eax + movl %edx,56(%rsp) + movl %esi,%ecx + xorl 4(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + xorl 28(%rsp),%ebp + leal 1859775393(%rdx,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + xorl 0(%rsp),%r14d + movl %esi,%eax + movl %ebp,60(%rsp) + movl %r13d,%ecx + xorl 8(%rsp),%r14d + xorl %r11d,%eax + roll $5,%ecx + xorl 32(%rsp),%r14d + leal 1859775393(%rbp,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%r14d + xorl 4(%rsp),%edx + movl %r13d,%eax + movl %r14d,0(%rsp) + movl %r12d,%ecx + xorl 12(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 36(%rsp),%edx + leal 1859775393(%r14,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + xorl 8(%rsp),%ebp + movl %r12d,%eax + movl %edx,4(%rsp) + movl %r11d,%ecx + xorl 16(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 40(%rsp),%ebp + leal 1859775393(%rdx,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + xorl 12(%rsp),%r14d + movl %r11d,%eax + movl %ebp,8(%rsp) + movl %edi,%ecx + xorl 20(%rsp),%r14d + xorl %r13d,%eax + roll $5,%ecx + xorl 44(%rsp),%r14d + leal 1859775393(%rbp,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%r14d + xorl 16(%rsp),%edx + movl %edi,%eax + movl %r14d,12(%rsp) + movl %esi,%ecx + xorl 24(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 48(%rsp),%edx + leal 1859775393(%r14,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + xorl 20(%rsp),%ebp + movl %esi,%eax + movl %edx,16(%rsp) + movl %r13d,%ecx + xorl 28(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 52(%rsp),%ebp + leal 1859775393(%rdx,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + xorl 24(%rsp),%r14d + movl %r13d,%eax + movl %ebp,20(%rsp) + movl %r12d,%ecx + xorl 32(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 56(%rsp),%r14d + leal 1859775393(%rbp,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%r14d + xorl 28(%rsp),%edx + movl %r12d,%eax + movl %r14d,24(%rsp) + movl %r11d,%ecx + xorl 36(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 60(%rsp),%edx + leal 1859775393(%r14,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + xorl 32(%rsp),%ebp + movl %r11d,%eax + movl %edx,28(%rsp) + movl %edi,%ecx + xorl 40(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 0(%rsp),%ebp + leal 1859775393(%rdx,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + xorl 36(%rsp),%r14d + movl %r12d,%eax + movl %ebp,32(%rsp) + movl %r12d,%ebx + xorl 44(%rsp),%r14d + andl %r11d,%eax + movl %esi,%ecx + xorl 4(%rsp),%r14d + leal -1894007588(%rbp,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%r14d + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 40(%rsp),%edx + movl %r11d,%eax + movl %r14d,36(%rsp) + movl %r11d,%ebx + xorl 48(%rsp),%edx + andl %edi,%eax + movl %r13d,%ecx + xorl 8(%rsp),%edx + leal -1894007588(%r14,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%edx + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 44(%rsp),%ebp + movl %edi,%eax + movl %edx,40(%rsp) + movl %edi,%ebx + xorl 52(%rsp),%ebp + andl %esi,%eax + movl %r12d,%ecx + xorl 12(%rsp),%ebp + leal -1894007588(%rdx,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%ebp + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 48(%rsp),%r14d + movl %esi,%eax + movl %ebp,44(%rsp) + movl %esi,%ebx + xorl 56(%rsp),%r14d + andl %r13d,%eax + movl %r11d,%ecx + xorl 16(%rsp),%r14d + leal -1894007588(%rbp,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%r14d + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 52(%rsp),%edx + movl %r13d,%eax + movl %r14d,48(%rsp) + movl %r13d,%ebx + xorl 60(%rsp),%edx + andl %r12d,%eax + movl %edi,%ecx + xorl 20(%rsp),%edx + leal -1894007588(%r14,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%edx + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 56(%rsp),%ebp + movl %r12d,%eax + movl %edx,52(%rsp) + movl %r12d,%ebx + xorl 0(%rsp),%ebp + andl %r11d,%eax + movl %esi,%ecx + xorl 24(%rsp),%ebp + leal -1894007588(%rdx,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%ebp + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 60(%rsp),%r14d + movl %r11d,%eax + movl %ebp,56(%rsp) + movl %r11d,%ebx + xorl 4(%rsp),%r14d + andl %edi,%eax + movl %r13d,%ecx + xorl 28(%rsp),%r14d + leal -1894007588(%rbp,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%r14d + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 0(%rsp),%edx + movl %edi,%eax + movl %r14d,60(%rsp) + movl %edi,%ebx + xorl 8(%rsp),%edx + andl %esi,%eax + movl %r12d,%ecx + xorl 32(%rsp),%edx + leal -1894007588(%r14,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%edx + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 4(%rsp),%ebp + movl %esi,%eax + movl %edx,0(%rsp) + movl %esi,%ebx + xorl 12(%rsp),%ebp + andl %r13d,%eax + movl %r11d,%ecx + xorl 36(%rsp),%ebp + leal -1894007588(%rdx,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%ebp + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 8(%rsp),%r14d + movl %r13d,%eax + movl %ebp,4(%rsp) + movl %r13d,%ebx + xorl 16(%rsp),%r14d + andl %r12d,%eax + movl %edi,%ecx + xorl 40(%rsp),%r14d + leal -1894007588(%rbp,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%r14d + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 12(%rsp),%edx + movl %r12d,%eax + movl %r14d,8(%rsp) + movl %r12d,%ebx + xorl 20(%rsp),%edx + andl %r11d,%eax + movl %esi,%ecx + xorl 44(%rsp),%edx + leal -1894007588(%r14,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%edx + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 16(%rsp),%ebp + movl %r11d,%eax + movl %edx,12(%rsp) + movl %r11d,%ebx + xorl 24(%rsp),%ebp + andl %edi,%eax + movl %r13d,%ecx + xorl 48(%rsp),%ebp + leal -1894007588(%rdx,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%ebp + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 20(%rsp),%r14d + movl %edi,%eax + movl %ebp,16(%rsp) + movl %edi,%ebx + xorl 28(%rsp),%r14d + andl %esi,%eax + movl %r12d,%ecx + xorl 52(%rsp),%r14d + leal -1894007588(%rbp,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%r14d + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 24(%rsp),%edx + movl %esi,%eax + movl %r14d,20(%rsp) + movl %esi,%ebx + xorl 32(%rsp),%edx + andl %r13d,%eax + movl %r11d,%ecx + xorl 56(%rsp),%edx + leal -1894007588(%r14,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%edx + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 28(%rsp),%ebp + movl %r13d,%eax + movl %edx,24(%rsp) + movl %r13d,%ebx + xorl 36(%rsp),%ebp + andl %r12d,%eax + movl %edi,%ecx + xorl 60(%rsp),%ebp + leal -1894007588(%rdx,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%ebp + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 32(%rsp),%r14d + movl %r12d,%eax + movl %ebp,28(%rsp) + movl %r12d,%ebx + xorl 40(%rsp),%r14d + andl %r11d,%eax + movl %esi,%ecx + xorl 0(%rsp),%r14d + leal -1894007588(%rbp,%r13,1),%r13d + xorl %r11d,%ebx + roll $5,%ecx + addl %eax,%r13d + roll $1,%r14d + andl %edi,%ebx + addl %ecx,%r13d + roll $30,%edi + addl %ebx,%r13d + xorl 36(%rsp),%edx + movl %r11d,%eax + movl %r14d,32(%rsp) + movl %r11d,%ebx + xorl 44(%rsp),%edx + andl %edi,%eax + movl %r13d,%ecx + xorl 4(%rsp),%edx + leal -1894007588(%r14,%r12,1),%r12d + xorl %edi,%ebx + roll $5,%ecx + addl %eax,%r12d + roll $1,%edx + andl %esi,%ebx + addl %ecx,%r12d + roll $30,%esi + addl %ebx,%r12d + xorl 40(%rsp),%ebp + movl %edi,%eax + movl %edx,36(%rsp) + movl %edi,%ebx + xorl 48(%rsp),%ebp + andl %esi,%eax + movl %r12d,%ecx + xorl 8(%rsp),%ebp + leal -1894007588(%rdx,%r11,1),%r11d + xorl %esi,%ebx + roll $5,%ecx + addl %eax,%r11d + roll $1,%ebp + andl %r13d,%ebx + addl %ecx,%r11d + roll $30,%r13d + addl %ebx,%r11d + xorl 44(%rsp),%r14d + movl %esi,%eax + movl %ebp,40(%rsp) + movl %esi,%ebx + xorl 52(%rsp),%r14d + andl %r13d,%eax + movl %r11d,%ecx + xorl 12(%rsp),%r14d + leal -1894007588(%rbp,%rdi,1),%edi + xorl %r13d,%ebx + roll $5,%ecx + addl %eax,%edi + roll $1,%r14d + andl %r12d,%ebx + addl %ecx,%edi + roll $30,%r12d + addl %ebx,%edi + xorl 48(%rsp),%edx + movl %r13d,%eax + movl %r14d,44(%rsp) + movl %r13d,%ebx + xorl 56(%rsp),%edx + andl %r12d,%eax + movl %edi,%ecx + xorl 16(%rsp),%edx + leal -1894007588(%r14,%rsi,1),%esi + xorl %r12d,%ebx + roll $5,%ecx + addl %eax,%esi + roll $1,%edx + andl %r11d,%ebx + addl %ecx,%esi + roll $30,%r11d + addl %ebx,%esi + xorl 52(%rsp),%ebp + movl %edi,%eax + movl %edx,48(%rsp) + movl %esi,%ecx + xorl 60(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + xorl 20(%rsp),%ebp + leal -899497514(%rdx,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + xorl 56(%rsp),%r14d + movl %esi,%eax + movl %ebp,52(%rsp) + movl %r13d,%ecx + xorl 0(%rsp),%r14d + xorl %r11d,%eax + roll $5,%ecx + xorl 24(%rsp),%r14d + leal -899497514(%rbp,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%r14d + xorl 60(%rsp),%edx + movl %r13d,%eax + movl %r14d,56(%rsp) + movl %r12d,%ecx + xorl 4(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 28(%rsp),%edx + leal -899497514(%r14,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + xorl 0(%rsp),%ebp + movl %r12d,%eax + movl %edx,60(%rsp) + movl %r11d,%ecx + xorl 8(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 32(%rsp),%ebp + leal -899497514(%rdx,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + xorl 4(%rsp),%r14d + movl %r11d,%eax + movl %ebp,0(%rsp) + movl %edi,%ecx + xorl 12(%rsp),%r14d + xorl %r13d,%eax + roll $5,%ecx + xorl 36(%rsp),%r14d + leal -899497514(%rbp,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%r14d + xorl 8(%rsp),%edx + movl %edi,%eax + movl %r14d,4(%rsp) + movl %esi,%ecx + xorl 16(%rsp),%edx + xorl %r12d,%eax + roll $5,%ecx + xorl 40(%rsp),%edx + leal -899497514(%r14,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%edx + xorl 12(%rsp),%ebp + movl %esi,%eax + movl %edx,8(%rsp) + movl %r13d,%ecx + xorl 20(%rsp),%ebp + xorl %r11d,%eax + roll $5,%ecx + xorl 44(%rsp),%ebp + leal -899497514(%rdx,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%ebp + xorl 16(%rsp),%r14d + movl %r13d,%eax + movl %ebp,12(%rsp) + movl %r12d,%ecx + xorl 24(%rsp),%r14d + xorl %edi,%eax + roll $5,%ecx + xorl 48(%rsp),%r14d + leal -899497514(%rbp,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%r14d + xorl 20(%rsp),%edx + movl %r12d,%eax + movl %r14d,16(%rsp) + movl %r11d,%ecx + xorl 28(%rsp),%edx + xorl %esi,%eax + roll $5,%ecx + xorl 52(%rsp),%edx + leal -899497514(%r14,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%edx + xorl 24(%rsp),%ebp + movl %r11d,%eax + movl %edx,20(%rsp) + movl %edi,%ecx + xorl 32(%rsp),%ebp + xorl %r13d,%eax + roll $5,%ecx + xorl 56(%rsp),%ebp + leal -899497514(%rdx,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%ebp + xorl 28(%rsp),%r14d + movl %edi,%eax + movl %ebp,24(%rsp) + movl %esi,%ecx + xorl 36(%rsp),%r14d + xorl %r12d,%eax + roll $5,%ecx + xorl 60(%rsp),%r14d + leal -899497514(%rbp,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%r14d + xorl 32(%rsp),%edx + movl %esi,%eax + movl %r14d,28(%rsp) + movl %r13d,%ecx + xorl 40(%rsp),%edx + xorl %r11d,%eax + roll $5,%ecx + xorl 0(%rsp),%edx + leal -899497514(%r14,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%edx + xorl 36(%rsp),%ebp + movl %r13d,%eax + + movl %r12d,%ecx + xorl 44(%rsp),%ebp + xorl %edi,%eax + roll $5,%ecx + xorl 4(%rsp),%ebp + leal -899497514(%rdx,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%ebp + xorl 40(%rsp),%r14d + movl %r12d,%eax + + movl %r11d,%ecx + xorl 48(%rsp),%r14d + xorl %esi,%eax + roll $5,%ecx + xorl 8(%rsp),%r14d + leal -899497514(%rbp,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%r14d + xorl 44(%rsp),%edx + movl %r11d,%eax + + movl %edi,%ecx + xorl 52(%rsp),%edx + xorl %r13d,%eax + roll $5,%ecx + xorl 12(%rsp),%edx + leal -899497514(%r14,%rsi,1),%esi + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + roll $1,%edx + xorl 48(%rsp),%ebp + movl %edi,%eax + + movl %esi,%ecx + xorl 56(%rsp),%ebp + xorl %r12d,%eax + roll $5,%ecx + xorl 16(%rsp),%ebp + leal -899497514(%rdx,%r13,1),%r13d + xorl %r11d,%eax + addl %ecx,%r13d + roll $30,%edi + addl %eax,%r13d + roll $1,%ebp + xorl 52(%rsp),%r14d + movl %esi,%eax + + movl %r13d,%ecx + xorl 60(%rsp),%r14d + xorl %r11d,%eax + roll $5,%ecx + xorl 20(%rsp),%r14d + leal -899497514(%rbp,%r12,1),%r12d + xorl %edi,%eax + addl %ecx,%r12d + roll $30,%esi + addl %eax,%r12d + roll $1,%r14d + xorl 56(%rsp),%edx + movl %r13d,%eax + + movl %r12d,%ecx + xorl 0(%rsp),%edx + xorl %edi,%eax + roll $5,%ecx + xorl 24(%rsp),%edx + leal -899497514(%r14,%r11,1),%r11d + xorl %esi,%eax + addl %ecx,%r11d + roll $30,%r13d + addl %eax,%r11d + roll $1,%edx + xorl 60(%rsp),%ebp + movl %r12d,%eax + + movl %r11d,%ecx + xorl 4(%rsp),%ebp + xorl %esi,%eax + roll $5,%ecx + xorl 28(%rsp),%ebp + leal -899497514(%rdx,%rdi,1),%edi + xorl %r13d,%eax + addl %ecx,%edi + roll $30,%r12d + addl %eax,%edi + roll $1,%ebp + movl %r11d,%eax + movl %edi,%ecx + xorl %r13d,%eax + leal -899497514(%rbp,%rsi,1),%esi + roll $5,%ecx + xorl %r12d,%eax + addl %ecx,%esi + roll $30,%r11d + addl %eax,%esi + addl 0(%r8),%esi + addl 4(%r8),%edi + addl 8(%r8),%r11d + addl 12(%r8),%r12d + addl 16(%r8),%r13d + movl %esi,0(%r8) + movl %edi,4(%r8) + movl %r11d,8(%r8) + movl %r12d,12(%r8) + movl %r13d,16(%r8) + + subq $1,%r10 + leaq 64(%r9),%r9 + jnz .Lloop + + movq 64(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_block_data_order,.-sha1_block_data_order +.type sha1_block_data_order_shaext,@function +.align 32 +sha1_block_data_order_shaext: +_shaext_shortcut: +.cfi_startproc + movdqu (%rdi),%xmm0 + movd 16(%rdi),%xmm1 + movdqa K_XX_XX+160(%rip),%xmm3 + + movdqu (%rsi),%xmm4 + pshufd $27,%xmm0,%xmm0 + movdqu 16(%rsi),%xmm5 + pshufd $27,%xmm1,%xmm1 + movdqu 32(%rsi),%xmm6 +.byte 102,15,56,0,227 + movdqu 48(%rsi),%xmm7 +.byte 102,15,56,0,235 +.byte 102,15,56,0,243 + movdqa %xmm1,%xmm9 +.byte 102,15,56,0,251 + jmp .Loop_shaext + +.align 16 +.Loop_shaext: + decq %rdx + leaq 64(%rsi),%r8 + paddd %xmm4,%xmm1 + cmovneq %r8,%rsi + movdqa %xmm0,%xmm8 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,0 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,0 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,0 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,1 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,1 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,1 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,2 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 +.byte 15,56,201,229 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,213 + pxor %xmm6,%xmm4 +.byte 15,56,201,238 +.byte 15,56,202,231 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,2 +.byte 15,56,200,206 + pxor %xmm7,%xmm5 +.byte 15,56,202,236 +.byte 15,56,201,247 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,2 +.byte 15,56,200,215 + pxor %xmm4,%xmm6 +.byte 15,56,201,252 +.byte 15,56,202,245 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 +.byte 15,56,200,204 + pxor %xmm5,%xmm7 +.byte 15,56,202,254 + movdqu (%rsi),%xmm4 + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,3 +.byte 15,56,200,213 + movdqu 16(%rsi),%xmm5 +.byte 102,15,56,0,227 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 +.byte 15,56,200,206 + movdqu 32(%rsi),%xmm6 +.byte 102,15,56,0,235 + + movdqa %xmm0,%xmm2 +.byte 15,58,204,193,3 +.byte 15,56,200,215 + movdqu 48(%rsi),%xmm7 +.byte 102,15,56,0,243 + + movdqa %xmm0,%xmm1 +.byte 15,58,204,194,3 +.byte 65,15,56,200,201 +.byte 102,15,56,0,251 + + paddd %xmm8,%xmm0 + movdqa %xmm1,%xmm9 + + jnz .Loop_shaext + + pshufd $27,%xmm0,%xmm0 + pshufd $27,%xmm1,%xmm1 + movdqu %xmm0,(%rdi) + movd %xmm1,16(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_block_data_order_shaext,.-sha1_block_data_order_shaext +.type sha1_block_data_order_ssse3,@function +.align 16 +sha1_block_data_order_ssse3: +_ssse3_shortcut: +.cfi_startproc + movq %rsp,%r11 +.cfi_def_cfa_register %r11 + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + leaq -64(%rsp),%rsp + andq $-64,%rsp + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + shlq $6,%r10 + addq %r9,%r10 + leaq K_XX_XX+64(%rip),%r14 + + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl %ebx,%esi + movl 16(%r8),%ebp + movl %ecx,%edi + xorl %edx,%edi + andl %edi,%esi + + movdqa 64(%r14),%xmm6 + movdqa -64(%r14),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 +.byte 102,15,56,0,206 +.byte 102,15,56,0,214 + addq $64,%r9 + paddd %xmm9,%xmm0 +.byte 102,15,56,0,222 + paddd %xmm9,%xmm1 + paddd %xmm9,%xmm2 + movdqa %xmm0,0(%rsp) + psubd %xmm9,%xmm0 + movdqa %xmm1,16(%rsp) + psubd %xmm9,%xmm1 + movdqa %xmm2,32(%rsp) + psubd %xmm9,%xmm2 + jmp .Loop_ssse3 +.align 16 +.Loop_ssse3: + rorl $2,%ebx + pshufd $238,%xmm0,%xmm4 + xorl %edx,%esi + movdqa %xmm3,%xmm8 + paddd %xmm3,%xmm9 + movl %eax,%edi + addl 0(%rsp),%ebp + punpcklqdq %xmm1,%xmm4 + xorl %ecx,%ebx + roll $5,%eax + addl %esi,%ebp + psrldq $4,%xmm8 + andl %ebx,%edi + xorl %ecx,%ebx + pxor %xmm0,%xmm4 + addl %eax,%ebp + rorl $7,%eax + pxor %xmm2,%xmm8 + xorl %ecx,%edi + movl %ebp,%esi + addl 4(%rsp),%edx + pxor %xmm8,%xmm4 + xorl %ebx,%eax + roll $5,%ebp + movdqa %xmm9,48(%rsp) + addl %edi,%edx + andl %eax,%esi + movdqa %xmm4,%xmm10 + xorl %ebx,%eax + addl %ebp,%edx + rorl $7,%ebp + movdqa %xmm4,%xmm8 + xorl %ebx,%esi + pslldq $12,%xmm10 + paddd %xmm4,%xmm4 + movl %edx,%edi + addl 8(%rsp),%ecx + psrld $31,%xmm8 + xorl %eax,%ebp + roll $5,%edx + addl %esi,%ecx + movdqa %xmm10,%xmm9 + andl %ebp,%edi + xorl %eax,%ebp + psrld $30,%xmm10 + addl %edx,%ecx + rorl $7,%edx + por %xmm8,%xmm4 + xorl %eax,%edi + movl %ecx,%esi + addl 12(%rsp),%ebx + pslld $2,%xmm9 + pxor %xmm10,%xmm4 + xorl %ebp,%edx + movdqa -64(%r14),%xmm10 + roll $5,%ecx + addl %edi,%ebx + andl %edx,%esi + pxor %xmm9,%xmm4 + xorl %ebp,%edx + addl %ecx,%ebx + rorl $7,%ecx + pshufd $238,%xmm1,%xmm5 + xorl %ebp,%esi + movdqa %xmm4,%xmm9 + paddd %xmm4,%xmm10 + movl %ebx,%edi + addl 16(%rsp),%eax + punpcklqdq %xmm2,%xmm5 + xorl %edx,%ecx + roll $5,%ebx + addl %esi,%eax + psrldq $4,%xmm9 + andl %ecx,%edi + xorl %edx,%ecx + pxor %xmm1,%xmm5 + addl %ebx,%eax + rorl $7,%ebx + pxor %xmm3,%xmm9 + xorl %edx,%edi + movl %eax,%esi + addl 20(%rsp),%ebp + pxor %xmm9,%xmm5 + xorl %ecx,%ebx + roll $5,%eax + movdqa %xmm10,0(%rsp) + addl %edi,%ebp + andl %ebx,%esi + movdqa %xmm5,%xmm8 + xorl %ecx,%ebx + addl %eax,%ebp + rorl $7,%eax + movdqa %xmm5,%xmm9 + xorl %ecx,%esi + pslldq $12,%xmm8 + paddd %xmm5,%xmm5 + movl %ebp,%edi + addl 24(%rsp),%edx + psrld $31,%xmm9 + xorl %ebx,%eax + roll $5,%ebp + addl %esi,%edx + movdqa %xmm8,%xmm10 + andl %eax,%edi + xorl %ebx,%eax + psrld $30,%xmm8 + addl %ebp,%edx + rorl $7,%ebp + por %xmm9,%xmm5 + xorl %ebx,%edi + movl %edx,%esi + addl 28(%rsp),%ecx + pslld $2,%xmm10 + pxor %xmm8,%xmm5 + xorl %eax,%ebp + movdqa -32(%r14),%xmm8 + roll $5,%edx + addl %edi,%ecx + andl %ebp,%esi + pxor %xmm10,%xmm5 + xorl %eax,%ebp + addl %edx,%ecx + rorl $7,%edx + pshufd $238,%xmm2,%xmm6 + xorl %eax,%esi + movdqa %xmm5,%xmm10 + paddd %xmm5,%xmm8 + movl %ecx,%edi + addl 32(%rsp),%ebx + punpcklqdq %xmm3,%xmm6 + xorl %ebp,%edx + roll $5,%ecx + addl %esi,%ebx + psrldq $4,%xmm10 + andl %edx,%edi + xorl %ebp,%edx + pxor %xmm2,%xmm6 + addl %ecx,%ebx + rorl $7,%ecx + pxor %xmm4,%xmm10 + xorl %ebp,%edi + movl %ebx,%esi + addl 36(%rsp),%eax + pxor %xmm10,%xmm6 + xorl %edx,%ecx + roll $5,%ebx + movdqa %xmm8,16(%rsp) + addl %edi,%eax + andl %ecx,%esi + movdqa %xmm6,%xmm9 + xorl %edx,%ecx + addl %ebx,%eax + rorl $7,%ebx + movdqa %xmm6,%xmm10 + xorl %edx,%esi + pslldq $12,%xmm9 + paddd %xmm6,%xmm6 + movl %eax,%edi + addl 40(%rsp),%ebp + psrld $31,%xmm10 + xorl %ecx,%ebx + roll $5,%eax + addl %esi,%ebp + movdqa %xmm9,%xmm8 + andl %ebx,%edi + xorl %ecx,%ebx + psrld $30,%xmm9 + addl %eax,%ebp + rorl $7,%eax + por %xmm10,%xmm6 + xorl %ecx,%edi + movl %ebp,%esi + addl 44(%rsp),%edx + pslld $2,%xmm8 + pxor %xmm9,%xmm6 + xorl %ebx,%eax + movdqa -32(%r14),%xmm9 + roll $5,%ebp + addl %edi,%edx + andl %eax,%esi + pxor %xmm8,%xmm6 + xorl %ebx,%eax + addl %ebp,%edx + rorl $7,%ebp + pshufd $238,%xmm3,%xmm7 + xorl %ebx,%esi + movdqa %xmm6,%xmm8 + paddd %xmm6,%xmm9 + movl %edx,%edi + addl 48(%rsp),%ecx + punpcklqdq %xmm4,%xmm7 + xorl %eax,%ebp + roll $5,%edx + addl %esi,%ecx + psrldq $4,%xmm8 + andl %ebp,%edi + xorl %eax,%ebp + pxor %xmm3,%xmm7 + addl %edx,%ecx + rorl $7,%edx + pxor %xmm5,%xmm8 + xorl %eax,%edi + movl %ecx,%esi + addl 52(%rsp),%ebx + pxor %xmm8,%xmm7 + xorl %ebp,%edx + roll $5,%ecx + movdqa %xmm9,32(%rsp) + addl %edi,%ebx + andl %edx,%esi + movdqa %xmm7,%xmm10 + xorl %ebp,%edx + addl %ecx,%ebx + rorl $7,%ecx + movdqa %xmm7,%xmm8 + xorl %ebp,%esi + pslldq $12,%xmm10 + paddd %xmm7,%xmm7 + movl %ebx,%edi + addl 56(%rsp),%eax + psrld $31,%xmm8 + xorl %edx,%ecx + roll $5,%ebx + addl %esi,%eax + movdqa %xmm10,%xmm9 + andl %ecx,%edi + xorl %edx,%ecx + psrld $30,%xmm10 + addl %ebx,%eax + rorl $7,%ebx + por %xmm8,%xmm7 + xorl %edx,%edi + movl %eax,%esi + addl 60(%rsp),%ebp + pslld $2,%xmm9 + pxor %xmm10,%xmm7 + xorl %ecx,%ebx + movdqa -32(%r14),%xmm10 + roll $5,%eax + addl %edi,%ebp + andl %ebx,%esi + pxor %xmm9,%xmm7 + pshufd $238,%xmm6,%xmm9 + xorl %ecx,%ebx + addl %eax,%ebp + rorl $7,%eax + pxor %xmm4,%xmm0 + xorl %ecx,%esi + movl %ebp,%edi + addl 0(%rsp),%edx + punpcklqdq %xmm7,%xmm9 + xorl %ebx,%eax + roll $5,%ebp + pxor %xmm1,%xmm0 + addl %esi,%edx + andl %eax,%edi + movdqa %xmm10,%xmm8 + xorl %ebx,%eax + paddd %xmm7,%xmm10 + addl %ebp,%edx + pxor %xmm9,%xmm0 + rorl $7,%ebp + xorl %ebx,%edi + movl %edx,%esi + addl 4(%rsp),%ecx + movdqa %xmm0,%xmm9 + xorl %eax,%ebp + roll $5,%edx + movdqa %xmm10,48(%rsp) + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + pslld $2,%xmm0 + addl %edx,%ecx + rorl $7,%edx + psrld $30,%xmm9 + xorl %eax,%esi + movl %ecx,%edi + addl 8(%rsp),%ebx + por %xmm9,%xmm0 + xorl %ebp,%edx + roll $5,%ecx + pshufd $238,%xmm7,%xmm10 + addl %esi,%ebx + andl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + pxor %xmm5,%xmm1 + addl 16(%rsp),%ebp + xorl %ecx,%esi + punpcklqdq %xmm0,%xmm10 + movl %eax,%edi + roll $5,%eax + pxor %xmm2,%xmm1 + addl %esi,%ebp + xorl %ecx,%edi + movdqa %xmm8,%xmm9 + rorl $7,%ebx + paddd %xmm0,%xmm8 + addl %eax,%ebp + pxor %xmm10,%xmm1 + addl 20(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm1,%xmm10 + addl %edi,%edx + xorl %ebx,%esi + movdqa %xmm8,0(%rsp) + rorl $7,%eax + addl %ebp,%edx + addl 24(%rsp),%ecx + pslld $2,%xmm1 + xorl %eax,%esi + movl %edx,%edi + psrld $30,%xmm10 + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + por %xmm10,%xmm1 + addl %edx,%ecx + addl 28(%rsp),%ebx + pshufd $238,%xmm0,%xmm8 + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + pxor %xmm6,%xmm2 + addl 32(%rsp),%eax + xorl %edx,%esi + punpcklqdq %xmm1,%xmm8 + movl %ebx,%edi + roll $5,%ebx + pxor %xmm3,%xmm2 + addl %esi,%eax + xorl %edx,%edi + movdqa 0(%r14),%xmm10 + rorl $7,%ecx + paddd %xmm1,%xmm9 + addl %ebx,%eax + pxor %xmm8,%xmm2 + addl 36(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + movdqa %xmm2,%xmm8 + addl %edi,%ebp + xorl %ecx,%esi + movdqa %xmm9,16(%rsp) + rorl $7,%ebx + addl %eax,%ebp + addl 40(%rsp),%edx + pslld $2,%xmm2 + xorl %ebx,%esi + movl %ebp,%edi + psrld $30,%xmm8 + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + por %xmm8,%xmm2 + addl %ebp,%edx + addl 44(%rsp),%ecx + pshufd $238,%xmm1,%xmm9 + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + pxor %xmm7,%xmm3 + addl 48(%rsp),%ebx + xorl %ebp,%esi + punpcklqdq %xmm2,%xmm9 + movl %ecx,%edi + roll $5,%ecx + pxor %xmm4,%xmm3 + addl %esi,%ebx + xorl %ebp,%edi + movdqa %xmm10,%xmm8 + rorl $7,%edx + paddd %xmm2,%xmm10 + addl %ecx,%ebx + pxor %xmm9,%xmm3 + addl 52(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + movdqa %xmm3,%xmm9 + addl %edi,%eax + xorl %edx,%esi + movdqa %xmm10,32(%rsp) + rorl $7,%ecx + addl %ebx,%eax + addl 56(%rsp),%ebp + pslld $2,%xmm3 + xorl %ecx,%esi + movl %eax,%edi + psrld $30,%xmm9 + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + por %xmm9,%xmm3 + addl %eax,%ebp + addl 60(%rsp),%edx + pshufd $238,%xmm2,%xmm10 + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + pxor %xmm0,%xmm4 + addl 0(%rsp),%ecx + xorl %eax,%esi + punpcklqdq %xmm3,%xmm10 + movl %edx,%edi + roll $5,%edx + pxor %xmm5,%xmm4 + addl %esi,%ecx + xorl %eax,%edi + movdqa %xmm8,%xmm9 + rorl $7,%ebp + paddd %xmm3,%xmm8 + addl %edx,%ecx + pxor %xmm10,%xmm4 + addl 4(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + movdqa %xmm4,%xmm10 + addl %edi,%ebx + xorl %ebp,%esi + movdqa %xmm8,48(%rsp) + rorl $7,%edx + addl %ecx,%ebx + addl 8(%rsp),%eax + pslld $2,%xmm4 + xorl %edx,%esi + movl %ebx,%edi + psrld $30,%xmm10 + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + por %xmm10,%xmm4 + addl %ebx,%eax + addl 12(%rsp),%ebp + pshufd $238,%xmm3,%xmm8 + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + pxor %xmm1,%xmm5 + addl 16(%rsp),%edx + xorl %ebx,%esi + punpcklqdq %xmm4,%xmm8 + movl %ebp,%edi + roll $5,%ebp + pxor %xmm6,%xmm5 + addl %esi,%edx + xorl %ebx,%edi + movdqa %xmm9,%xmm10 + rorl $7,%eax + paddd %xmm4,%xmm9 + addl %ebp,%edx + pxor %xmm8,%xmm5 + addl 20(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + movdqa %xmm5,%xmm8 + addl %edi,%ecx + xorl %eax,%esi + movdqa %xmm9,0(%rsp) + rorl $7,%ebp + addl %edx,%ecx + addl 24(%rsp),%ebx + pslld $2,%xmm5 + xorl %ebp,%esi + movl %ecx,%edi + psrld $30,%xmm8 + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + por %xmm8,%xmm5 + addl %ecx,%ebx + addl 28(%rsp),%eax + pshufd $238,%xmm4,%xmm9 + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%edi + roll $5,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + pxor %xmm2,%xmm6 + addl 32(%rsp),%ebp + andl %ecx,%esi + xorl %edx,%ecx + rorl $7,%ebx + punpcklqdq %xmm5,%xmm9 + movl %eax,%edi + xorl %ecx,%esi + pxor %xmm7,%xmm6 + roll $5,%eax + addl %esi,%ebp + movdqa %xmm10,%xmm8 + xorl %ebx,%edi + paddd %xmm5,%xmm10 + xorl %ecx,%ebx + pxor %xmm9,%xmm6 + addl %eax,%ebp + addl 36(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + rorl $7,%eax + movdqa %xmm6,%xmm9 + movl %ebp,%esi + xorl %ebx,%edi + movdqa %xmm10,16(%rsp) + roll $5,%ebp + addl %edi,%edx + xorl %eax,%esi + pslld $2,%xmm6 + xorl %ebx,%eax + addl %ebp,%edx + psrld $30,%xmm9 + addl 40(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + por %xmm9,%xmm6 + rorl $7,%ebp + movl %edx,%edi + xorl %eax,%esi + roll $5,%edx + pshufd $238,%xmm5,%xmm10 + addl %esi,%ecx + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 44(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + rorl $7,%edx + movl %ecx,%esi + xorl %ebp,%edi + roll $5,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + pxor %xmm3,%xmm7 + addl 48(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + rorl $7,%ecx + punpcklqdq %xmm6,%xmm10 + movl %ebx,%edi + xorl %edx,%esi + pxor %xmm0,%xmm7 + roll $5,%ebx + addl %esi,%eax + movdqa 32(%r14),%xmm9 + xorl %ecx,%edi + paddd %xmm6,%xmm8 + xorl %edx,%ecx + pxor %xmm10,%xmm7 + addl %ebx,%eax + addl 52(%rsp),%ebp + andl %ecx,%edi + xorl %edx,%ecx + rorl $7,%ebx + movdqa %xmm7,%xmm10 + movl %eax,%esi + xorl %ecx,%edi + movdqa %xmm8,32(%rsp) + roll $5,%eax + addl %edi,%ebp + xorl %ebx,%esi + pslld $2,%xmm7 + xorl %ecx,%ebx + addl %eax,%ebp + psrld $30,%xmm10 + addl 56(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + por %xmm10,%xmm7 + rorl $7,%eax + movl %ebp,%edi + xorl %ebx,%esi + roll $5,%ebp + pshufd $238,%xmm6,%xmm8 + addl %esi,%edx + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 60(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + rorl $7,%ebp + movl %edx,%esi + xorl %eax,%edi + roll $5,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + pxor %xmm4,%xmm0 + addl 0(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + rorl $7,%edx + punpcklqdq %xmm7,%xmm8 + movl %ecx,%edi + xorl %ebp,%esi + pxor %xmm1,%xmm0 + roll $5,%ecx + addl %esi,%ebx + movdqa %xmm9,%xmm10 + xorl %edx,%edi + paddd %xmm7,%xmm9 + xorl %ebp,%edx + pxor %xmm8,%xmm0 + addl %ecx,%ebx + addl 4(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + rorl $7,%ecx + movdqa %xmm0,%xmm8 + movl %ebx,%esi + xorl %edx,%edi + movdqa %xmm9,48(%rsp) + roll $5,%ebx + addl %edi,%eax + xorl %ecx,%esi + pslld $2,%xmm0 + xorl %edx,%ecx + addl %ebx,%eax + psrld $30,%xmm8 + addl 8(%rsp),%ebp + andl %ecx,%esi + xorl %edx,%ecx + por %xmm8,%xmm0 + rorl $7,%ebx + movl %eax,%edi + xorl %ecx,%esi + roll $5,%eax + pshufd $238,%xmm7,%xmm9 + addl %esi,%ebp + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 12(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + rorl $7,%eax + movl %ebp,%esi + xorl %ebx,%edi + roll $5,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + pxor %xmm5,%xmm1 + addl 16(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + rorl $7,%ebp + punpcklqdq %xmm0,%xmm9 + movl %edx,%edi + xorl %eax,%esi + pxor %xmm2,%xmm1 + roll $5,%edx + addl %esi,%ecx + movdqa %xmm10,%xmm8 + xorl %ebp,%edi + paddd %xmm0,%xmm10 + xorl %eax,%ebp + pxor %xmm9,%xmm1 + addl %edx,%ecx + addl 20(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + rorl $7,%edx + movdqa %xmm1,%xmm9 + movl %ecx,%esi + xorl %ebp,%edi + movdqa %xmm10,0(%rsp) + roll $5,%ecx + addl %edi,%ebx + xorl %edx,%esi + pslld $2,%xmm1 + xorl %ebp,%edx + addl %ecx,%ebx + psrld $30,%xmm9 + addl 24(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + por %xmm9,%xmm1 + rorl $7,%ecx + movl %ebx,%edi + xorl %edx,%esi + roll $5,%ebx + pshufd $238,%xmm0,%xmm10 + addl %esi,%eax + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%rsp),%ebp + andl %ecx,%edi + xorl %edx,%ecx + rorl $7,%ebx + movl %eax,%esi + xorl %ecx,%edi + roll $5,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + pxor %xmm6,%xmm2 + addl 32(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + rorl $7,%eax + punpcklqdq %xmm1,%xmm10 + movl %ebp,%edi + xorl %ebx,%esi + pxor %xmm3,%xmm2 + roll $5,%ebp + addl %esi,%edx + movdqa %xmm8,%xmm9 + xorl %eax,%edi + paddd %xmm1,%xmm8 + xorl %ebx,%eax + pxor %xmm10,%xmm2 + addl %ebp,%edx + addl 36(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + rorl $7,%ebp + movdqa %xmm2,%xmm10 + movl %edx,%esi + xorl %eax,%edi + movdqa %xmm8,16(%rsp) + roll $5,%edx + addl %edi,%ecx + xorl %ebp,%esi + pslld $2,%xmm2 + xorl %eax,%ebp + addl %edx,%ecx + psrld $30,%xmm10 + addl 40(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + por %xmm10,%xmm2 + rorl $7,%edx + movl %ecx,%edi + xorl %ebp,%esi + roll $5,%ecx + pshufd $238,%xmm1,%xmm8 + addl %esi,%ebx + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 44(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + rorl $7,%ecx + movl %ebx,%esi + xorl %edx,%edi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + addl %ebx,%eax + pxor %xmm7,%xmm3 + addl 48(%rsp),%ebp + xorl %ecx,%esi + punpcklqdq %xmm2,%xmm8 + movl %eax,%edi + roll $5,%eax + pxor %xmm4,%xmm3 + addl %esi,%ebp + xorl %ecx,%edi + movdqa %xmm9,%xmm10 + rorl $7,%ebx + paddd %xmm2,%xmm9 + addl %eax,%ebp + pxor %xmm8,%xmm3 + addl 52(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + movdqa %xmm3,%xmm8 + addl %edi,%edx + xorl %ebx,%esi + movdqa %xmm9,32(%rsp) + rorl $7,%eax + addl %ebp,%edx + addl 56(%rsp),%ecx + pslld $2,%xmm3 + xorl %eax,%esi + movl %edx,%edi + psrld $30,%xmm8 + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + por %xmm8,%xmm3 + addl %edx,%ecx + addl 60(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + addl 0(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + paddd %xmm3,%xmm10 + addl %esi,%eax + xorl %edx,%edi + movdqa %xmm10,48(%rsp) + rorl $7,%ecx + addl %ebx,%eax + addl 4(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 8(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + addl %ebp,%edx + addl 12(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + cmpq %r10,%r9 + je .Ldone_ssse3 + movdqa 64(%r14),%xmm6 + movdqa -64(%r14),%xmm9 + movdqu 0(%r9),%xmm0 + movdqu 16(%r9),%xmm1 + movdqu 32(%r9),%xmm2 + movdqu 48(%r9),%xmm3 +.byte 102,15,56,0,198 + addq $64,%r9 + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi +.byte 102,15,56,0,206 + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + paddd %xmm9,%xmm0 + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + movdqa %xmm0,0(%rsp) + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + psubd %xmm9,%xmm0 + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi +.byte 102,15,56,0,214 + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + paddd %xmm9,%xmm1 + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + movdqa %xmm1,16(%rsp) + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + psubd %xmm9,%xmm1 + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi +.byte 102,15,56,0,222 + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + paddd %xmm9,%xmm2 + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + movdqa %xmm2,32(%rsp) + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + psubd %xmm9,%xmm2 + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + rorl $7,%ecx + addl %ebx,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + addl 12(%r8),%edx + movl %eax,0(%r8) + addl 16(%r8),%ebp + movl %esi,4(%r8) + movl %esi,%ebx + movl %ecx,8(%r8) + movl %ecx,%edi + movl %edx,12(%r8) + xorl %edx,%edi + movl %ebp,16(%r8) + andl %edi,%esi + jmp .Loop_ssse3 + +.align 16 +.Ldone_ssse3: + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + xorl %edx,%esi + rorl $7,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + roll $5,%eax + addl %esi,%ebp + xorl %ecx,%edi + rorl $7,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + roll $5,%ebp + addl %edi,%edx + xorl %ebx,%esi + rorl $7,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + roll $5,%edx + addl %esi,%ecx + xorl %eax,%edi + rorl $7,%ebp + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + roll $5,%ecx + addl %edi,%ebx + xorl %ebp,%esi + rorl $7,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + roll $5,%ebx + addl %esi,%eax + xorl %edx,%edi + rorl $7,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + roll $5,%eax + addl %edi,%ebp + xorl %ecx,%esi + rorl $7,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + roll $5,%ebp + addl %esi,%edx + xorl %ebx,%edi + rorl $7,%eax + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + roll $5,%edx + addl %edi,%ecx + xorl %eax,%esi + rorl $7,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + roll $5,%ecx + addl %esi,%ebx + xorl %ebp,%edi + rorl $7,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + roll $5,%ebx + addl %edi,%eax + rorl $7,%ecx + addl %ebx,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + movl %eax,0(%r8) + addl 12(%r8),%edx + movl %esi,4(%r8) + addl 16(%r8),%ebp + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + movq -40(%r11),%r14 +.cfi_restore %r14 + movq -32(%r11),%r13 +.cfi_restore %r13 + movq -24(%r11),%r12 +.cfi_restore %r12 + movq -16(%r11),%rbp +.cfi_restore %rbp + movq -8(%r11),%rbx +.cfi_restore %rbx + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_ssse3: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3 +.type sha1_block_data_order_avx,@function +.align 16 +sha1_block_data_order_avx: +_avx_shortcut: +.cfi_startproc + movq %rsp,%r11 +.cfi_def_cfa_register %r11 + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + leaq -64(%rsp),%rsp + vzeroupper + andq $-64,%rsp + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + shlq $6,%r10 + addq %r9,%r10 + leaq K_XX_XX+64(%rip),%r14 + + movl 0(%r8),%eax + movl 4(%r8),%ebx + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl %ebx,%esi + movl 16(%r8),%ebp + movl %ecx,%edi + xorl %edx,%edi + andl %edi,%esi + + vmovdqa 64(%r14),%xmm6 + vmovdqa -64(%r14),%xmm11 + vmovdqu 0(%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + addq $64,%r9 + vpshufb %xmm6,%xmm1,%xmm1 + vpshufb %xmm6,%xmm2,%xmm2 + vpshufb %xmm6,%xmm3,%xmm3 + vpaddd %xmm11,%xmm0,%xmm4 + vpaddd %xmm11,%xmm1,%xmm5 + vpaddd %xmm11,%xmm2,%xmm6 + vmovdqa %xmm4,0(%rsp) + vmovdqa %xmm5,16(%rsp) + vmovdqa %xmm6,32(%rsp) + jmp .Loop_avx +.align 16 +.Loop_avx: + shrdl $2,%ebx,%ebx + xorl %edx,%esi + vpalignr $8,%xmm0,%xmm1,%xmm4 + movl %eax,%edi + addl 0(%rsp),%ebp + vpaddd %xmm3,%xmm11,%xmm9 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrldq $4,%xmm3,%xmm8 + addl %esi,%ebp + andl %ebx,%edi + vpxor %xmm0,%xmm4,%xmm4 + xorl %ecx,%ebx + addl %eax,%ebp + vpxor %xmm2,%xmm8,%xmm8 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 4(%rsp),%edx + vpxor %xmm8,%xmm4,%xmm4 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vmovdqa %xmm9,48(%rsp) + addl %edi,%edx + andl %eax,%esi + vpsrld $31,%xmm4,%xmm8 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpslldq $12,%xmm4,%xmm10 + vpaddd %xmm4,%xmm4,%xmm4 + movl %edx,%edi + addl 8(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm4,%xmm4 + addl %esi,%ecx + andl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm4,%xmm4 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 12(%rsp),%ebx + vpxor %xmm10,%xmm4,%xmm4 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %edi,%ebx + andl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpalignr $8,%xmm1,%xmm2,%xmm5 + movl %ebx,%edi + addl 16(%rsp),%eax + vpaddd %xmm4,%xmm11,%xmm9 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrldq $4,%xmm4,%xmm8 + addl %esi,%eax + andl %ecx,%edi + vpxor %xmm1,%xmm5,%xmm5 + xorl %edx,%ecx + addl %ebx,%eax + vpxor %xmm3,%xmm8,%xmm8 + shrdl $7,%ebx,%ebx + xorl %edx,%edi + movl %eax,%esi + addl 20(%rsp),%ebp + vpxor %xmm8,%xmm5,%xmm5 + xorl %ecx,%ebx + shldl $5,%eax,%eax + vmovdqa %xmm9,0(%rsp) + addl %edi,%ebp + andl %ebx,%esi + vpsrld $31,%xmm5,%xmm8 + xorl %ecx,%ebx + addl %eax,%ebp + shrdl $7,%eax,%eax + xorl %ecx,%esi + vpslldq $12,%xmm5,%xmm10 + vpaddd %xmm5,%xmm5,%xmm5 + movl %ebp,%edi + addl 24(%rsp),%edx + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm5,%xmm5 + addl %esi,%edx + andl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm5,%xmm5 + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + movl %edx,%esi + addl 28(%rsp),%ecx + vpxor %xmm10,%xmm5,%xmm5 + xorl %eax,%ebp + shldl $5,%edx,%edx + vmovdqa -32(%r14),%xmm11 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + vpalignr $8,%xmm2,%xmm3,%xmm6 + movl %ecx,%edi + addl 32(%rsp),%ebx + vpaddd %xmm5,%xmm11,%xmm9 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vpsrldq $4,%xmm5,%xmm8 + addl %esi,%ebx + andl %edx,%edi + vpxor %xmm2,%xmm6,%xmm6 + xorl %ebp,%edx + addl %ecx,%ebx + vpxor %xmm4,%xmm8,%xmm8 + shrdl $7,%ecx,%ecx + xorl %ebp,%edi + movl %ebx,%esi + addl 36(%rsp),%eax + vpxor %xmm8,%xmm6,%xmm6 + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vmovdqa %xmm9,16(%rsp) + addl %edi,%eax + andl %ecx,%esi + vpsrld $31,%xmm6,%xmm8 + xorl %edx,%ecx + addl %ebx,%eax + shrdl $7,%ebx,%ebx + xorl %edx,%esi + vpslldq $12,%xmm6,%xmm10 + vpaddd %xmm6,%xmm6,%xmm6 + movl %eax,%edi + addl 40(%rsp),%ebp + xorl %ecx,%ebx + shldl $5,%eax,%eax + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm6,%xmm6 + addl %esi,%ebp + andl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm6,%xmm6 + shrdl $7,%eax,%eax + xorl %ecx,%edi + movl %ebp,%esi + addl 44(%rsp),%edx + vpxor %xmm10,%xmm6,%xmm6 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + addl %edi,%edx + andl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%esi + vpalignr $8,%xmm3,%xmm4,%xmm7 + movl %edx,%edi + addl 48(%rsp),%ecx + vpaddd %xmm6,%xmm11,%xmm9 + xorl %eax,%ebp + shldl $5,%edx,%edx + vpsrldq $4,%xmm6,%xmm8 + addl %esi,%ecx + andl %ebp,%edi + vpxor %xmm3,%xmm7,%xmm7 + xorl %eax,%ebp + addl %edx,%ecx + vpxor %xmm5,%xmm8,%xmm8 + shrdl $7,%edx,%edx + xorl %eax,%edi + movl %ecx,%esi + addl 52(%rsp),%ebx + vpxor %xmm8,%xmm7,%xmm7 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + vmovdqa %xmm9,32(%rsp) + addl %edi,%ebx + andl %edx,%esi + vpsrld $31,%xmm7,%xmm8 + xorl %ebp,%edx + addl %ecx,%ebx + shrdl $7,%ecx,%ecx + xorl %ebp,%esi + vpslldq $12,%xmm7,%xmm10 + vpaddd %xmm7,%xmm7,%xmm7 + movl %ebx,%edi + addl 56(%rsp),%eax + xorl %edx,%ecx + shldl $5,%ebx,%ebx + vpsrld $30,%xmm10,%xmm9 + vpor %xmm8,%xmm7,%xmm7 + addl %esi,%eax + andl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + vpslld $2,%xmm10,%xmm10 + vpxor %xmm9,%xmm7,%xmm7 + shrdl $7,%ebx,%ebx + xorl %edx,%edi + movl %eax,%esi + addl 60(%rsp),%ebp + vpxor %xmm10,%xmm7,%xmm7 + xorl %ecx,%ebx + shldl $5,%eax,%eax + addl %edi,%ebp + andl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + shrdl $7,%eax,%eax + xorl %ecx,%esi + movl %ebp,%edi + addl 0(%rsp),%edx + vpxor %xmm1,%xmm0,%xmm0 + xorl %ebx,%eax + shldl $5,%ebp,%ebp + vpaddd %xmm7,%xmm11,%xmm9 + addl %esi,%edx + andl %eax,%edi + vpxor %xmm8,%xmm0,%xmm0 + xorl %ebx,%eax + addl %ebp,%edx + shrdl $7,%ebp,%ebp + xorl %ebx,%edi + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + movl %edx,%esi + addl 4(%rsp),%ecx + xorl %eax,%ebp + shldl $5,%edx,%edx + vpslld $2,%xmm0,%xmm0 + addl %edi,%ecx + andl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + shrdl $7,%edx,%edx + xorl %eax,%esi + movl %ecx,%edi + addl 8(%rsp),%ebx + vpor %xmm8,%xmm0,%xmm0 + xorl %ebp,%edx + shldl $5,%ecx,%ecx + addl %esi,%ebx + andl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 12(%rsp),%eax + xorl %ebp,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm2,%xmm1,%xmm1 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm0,%xmm11,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm1,%xmm1 + addl 20(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm1,%xmm1 + addl 24(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm1,%xmm1 + addl 28(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + vpxor %xmm3,%xmm2,%xmm2 + addl %esi,%eax + xorl %edx,%edi + vpaddd %xmm1,%xmm11,%xmm9 + vmovdqa 0(%r14),%xmm11 + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpxor %xmm8,%xmm2,%xmm2 + addl 36(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpslld $2,%xmm2,%xmm2 + addl 40(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpor %xmm8,%xmm2,%xmm2 + addl 44(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebx + xorl %ebp,%edi + vpaddd %xmm2,%xmm11,%xmm9 + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpalignr $8,%xmm2,%xmm3,%xmm8 + vpxor %xmm0,%xmm4,%xmm4 + addl 0(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + vpxor %xmm5,%xmm4,%xmm4 + addl %esi,%ecx + xorl %eax,%edi + vpaddd %xmm3,%xmm11,%xmm9 + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpxor %xmm8,%xmm4,%xmm4 + addl 4(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + vpsrld $30,%xmm4,%xmm8 + vmovdqa %xmm9,48(%rsp) + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpslld $2,%xmm4,%xmm4 + addl 8(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vpor %xmm8,%xmm4,%xmm4 + addl 12(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm3,%xmm4,%xmm8 + vpxor %xmm1,%xmm5,%xmm5 + addl 16(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpxor %xmm6,%xmm5,%xmm5 + addl %esi,%edx + xorl %ebx,%edi + vpaddd %xmm4,%xmm11,%xmm9 + shrdl $7,%eax,%eax + addl %ebp,%edx + vpxor %xmm8,%xmm5,%xmm5 + addl 20(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + vpsrld $30,%xmm5,%xmm8 + vmovdqa %xmm9,0(%rsp) + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpslld $2,%xmm5,%xmm5 + addl 24(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vpor %xmm8,%xmm5,%xmm5 + addl 28(%rsp),%eax + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + vpalignr $8,%xmm4,%xmm5,%xmm8 + vpxor %xmm2,%xmm6,%xmm6 + addl 32(%rsp),%ebp + andl %ecx,%esi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + vpxor %xmm7,%xmm6,%xmm6 + movl %eax,%edi + xorl %ecx,%esi + vpaddd %xmm5,%xmm11,%xmm9 + shldl $5,%eax,%eax + addl %esi,%ebp + vpxor %xmm8,%xmm6,%xmm6 + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 36(%rsp),%edx + vpsrld $30,%xmm6,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + vpslld $2,%xmm6,%xmm6 + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + addl 40(%rsp),%ecx + andl %eax,%esi + vpor %xmm8,%xmm6,%xmm6 + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%edi + xorl %eax,%esi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 44(%rsp),%ebx + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%esi + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + vpalignr $8,%xmm5,%xmm6,%xmm8 + vpxor %xmm3,%xmm7,%xmm7 + addl 48(%rsp),%eax + andl %edx,%esi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + vpxor %xmm0,%xmm7,%xmm7 + movl %ebx,%edi + xorl %edx,%esi + vpaddd %xmm6,%xmm11,%xmm9 + vmovdqa 32(%r14),%xmm11 + shldl $5,%ebx,%ebx + addl %esi,%eax + vpxor %xmm8,%xmm7,%xmm7 + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 52(%rsp),%ebp + vpsrld $30,%xmm7,%xmm8 + vmovdqa %xmm9,32(%rsp) + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + vpslld $2,%xmm7,%xmm7 + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + addl 56(%rsp),%edx + andl %ebx,%esi + vpor %xmm8,%xmm7,%xmm7 + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%edi + xorl %ebx,%esi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 60(%rsp),%ecx + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + vpalignr $8,%xmm6,%xmm7,%xmm8 + vpxor %xmm4,%xmm0,%xmm0 + addl 0(%rsp),%ebx + andl %ebp,%esi + xorl %eax,%ebp + shrdl $7,%edx,%edx + vpxor %xmm1,%xmm0,%xmm0 + movl %ecx,%edi + xorl %ebp,%esi + vpaddd %xmm7,%xmm11,%xmm9 + shldl $5,%ecx,%ecx + addl %esi,%ebx + vpxor %xmm8,%xmm0,%xmm0 + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 4(%rsp),%eax + vpsrld $30,%xmm0,%xmm8 + vmovdqa %xmm9,48(%rsp) + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + vpslld $2,%xmm0,%xmm0 + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %ecx,%esi + xorl %edx,%ecx + addl %ebx,%eax + addl 8(%rsp),%ebp + andl %ecx,%esi + vpor %xmm8,%xmm0,%xmm0 + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%edi + xorl %ecx,%esi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ebx,%edi + xorl %ecx,%ebx + addl %eax,%ebp + addl 12(%rsp),%edx + andl %ebx,%edi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + movl %ebp,%esi + xorl %ebx,%edi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %eax,%esi + xorl %ebx,%eax + addl %ebp,%edx + vpalignr $8,%xmm7,%xmm0,%xmm8 + vpxor %xmm5,%xmm1,%xmm1 + addl 16(%rsp),%ecx + andl %eax,%esi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + vpxor %xmm2,%xmm1,%xmm1 + movl %edx,%edi + xorl %eax,%esi + vpaddd %xmm0,%xmm11,%xmm9 + shldl $5,%edx,%edx + addl %esi,%ecx + vpxor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edi + xorl %eax,%ebp + addl %edx,%ecx + addl 20(%rsp),%ebx + vpsrld $30,%xmm1,%xmm8 + vmovdqa %xmm9,0(%rsp) + andl %ebp,%edi + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%esi + vpslld $2,%xmm1,%xmm1 + xorl %ebp,%edi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %edx,%esi + xorl %ebp,%edx + addl %ecx,%ebx + addl 24(%rsp),%eax + andl %edx,%esi + vpor %xmm8,%xmm1,%xmm1 + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%edi + xorl %edx,%esi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %ecx,%edi + xorl %edx,%ecx + addl %ebx,%eax + addl 28(%rsp),%ebp + andl %ecx,%edi + xorl %edx,%ecx + shrdl $7,%ebx,%ebx + movl %eax,%esi + xorl %ecx,%edi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ebx,%esi + xorl %ecx,%ebx + addl %eax,%ebp + vpalignr $8,%xmm0,%xmm1,%xmm8 + vpxor %xmm6,%xmm2,%xmm2 + addl 32(%rsp),%edx + andl %ebx,%esi + xorl %ecx,%ebx + shrdl $7,%eax,%eax + vpxor %xmm3,%xmm2,%xmm2 + movl %ebp,%edi + xorl %ebx,%esi + vpaddd %xmm1,%xmm11,%xmm9 + shldl $5,%ebp,%ebp + addl %esi,%edx + vpxor %xmm8,%xmm2,%xmm2 + xorl %eax,%edi + xorl %ebx,%eax + addl %ebp,%edx + addl 36(%rsp),%ecx + vpsrld $30,%xmm2,%xmm8 + vmovdqa %xmm9,16(%rsp) + andl %eax,%edi + xorl %ebx,%eax + shrdl $7,%ebp,%ebp + movl %edx,%esi + vpslld $2,%xmm2,%xmm2 + xorl %eax,%edi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %ebp,%esi + xorl %eax,%ebp + addl %edx,%ecx + addl 40(%rsp),%ebx + andl %ebp,%esi + vpor %xmm8,%xmm2,%xmm2 + xorl %eax,%ebp + shrdl $7,%edx,%edx + movl %ecx,%edi + xorl %ebp,%esi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %edx,%edi + xorl %ebp,%edx + addl %ecx,%ebx + addl 44(%rsp),%eax + andl %edx,%edi + xorl %ebp,%edx + shrdl $7,%ecx,%ecx + movl %ebx,%esi + xorl %edx,%edi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + addl %ebx,%eax + vpalignr $8,%xmm1,%xmm2,%xmm8 + vpxor %xmm7,%xmm3,%xmm3 + addl 48(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + vpxor %xmm4,%xmm3,%xmm3 + addl %esi,%ebp + xorl %ecx,%edi + vpaddd %xmm2,%xmm11,%xmm9 + shrdl $7,%ebx,%ebx + addl %eax,%ebp + vpxor %xmm8,%xmm3,%xmm3 + addl 52(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + vpsrld $30,%xmm3,%xmm8 + vmovdqa %xmm9,32(%rsp) + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + vpslld $2,%xmm3,%xmm3 + addl 56(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vpor %xmm8,%xmm3,%xmm3 + addl 60(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 0(%rsp),%eax + vpaddd %xmm3,%xmm11,%xmm9 + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + vmovdqa %xmm9,48(%rsp) + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 4(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 8(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 12(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + cmpq %r10,%r9 + je .Ldone_avx + vmovdqa 64(%r14),%xmm6 + vmovdqa -64(%r14),%xmm11 + vmovdqu 0(%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + vpshufb %xmm6,%xmm0,%xmm0 + addq $64,%r9 + addl 16(%rsp),%ebx + xorl %ebp,%esi + vpshufb %xmm6,%xmm1,%xmm1 + movl %ecx,%edi + shldl $5,%ecx,%ecx + vpaddd %xmm11,%xmm0,%xmm4 + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + vmovdqa %xmm4,0(%rsp) + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + vpshufb %xmm6,%xmm2,%xmm2 + movl %edx,%edi + shldl $5,%edx,%edx + vpaddd %xmm11,%xmm1,%xmm5 + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + vmovdqa %xmm5,16(%rsp) + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + vpshufb %xmm6,%xmm3,%xmm3 + movl %ebp,%edi + shldl $5,%ebp,%ebp + vpaddd %xmm11,%xmm2,%xmm6 + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + vmovdqa %xmm6,32(%rsp) + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + addl 12(%r8),%edx + movl %eax,0(%r8) + addl 16(%r8),%ebp + movl %esi,4(%r8) + movl %esi,%ebx + movl %ecx,8(%r8) + movl %ecx,%edi + movl %edx,12(%r8) + xorl %edx,%edi + movl %ebp,16(%r8) + andl %edi,%esi + jmp .Loop_avx + +.align 16 +.Ldone_avx: + addl 16(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 20(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + xorl %edx,%esi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 24(%rsp),%ebp + xorl %ecx,%esi + movl %eax,%edi + shldl $5,%eax,%eax + addl %esi,%ebp + xorl %ecx,%edi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 28(%rsp),%edx + xorl %ebx,%edi + movl %ebp,%esi + shldl $5,%ebp,%ebp + addl %edi,%edx + xorl %ebx,%esi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 32(%rsp),%ecx + xorl %eax,%esi + movl %edx,%edi + shldl $5,%edx,%edx + addl %esi,%ecx + xorl %eax,%edi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 36(%rsp),%ebx + xorl %ebp,%edi + movl %ecx,%esi + shldl $5,%ecx,%ecx + addl %edi,%ebx + xorl %ebp,%esi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 40(%rsp),%eax + xorl %edx,%esi + movl %ebx,%edi + shldl $5,%ebx,%ebx + addl %esi,%eax + xorl %edx,%edi + shrdl $7,%ecx,%ecx + addl %ebx,%eax + addl 44(%rsp),%ebp + xorl %ecx,%edi + movl %eax,%esi + shldl $5,%eax,%eax + addl %edi,%ebp + xorl %ecx,%esi + shrdl $7,%ebx,%ebx + addl %eax,%ebp + addl 48(%rsp),%edx + xorl %ebx,%esi + movl %ebp,%edi + shldl $5,%ebp,%ebp + addl %esi,%edx + xorl %ebx,%edi + shrdl $7,%eax,%eax + addl %ebp,%edx + addl 52(%rsp),%ecx + xorl %eax,%edi + movl %edx,%esi + shldl $5,%edx,%edx + addl %edi,%ecx + xorl %eax,%esi + shrdl $7,%ebp,%ebp + addl %edx,%ecx + addl 56(%rsp),%ebx + xorl %ebp,%esi + movl %ecx,%edi + shldl $5,%ecx,%ecx + addl %esi,%ebx + xorl %ebp,%edi + shrdl $7,%edx,%edx + addl %ecx,%ebx + addl 60(%rsp),%eax + xorl %edx,%edi + movl %ebx,%esi + shldl $5,%ebx,%ebx + addl %edi,%eax + shrdl $7,%ecx,%ecx + addl %ebx,%eax + vzeroupper + + addl 0(%r8),%eax + addl 4(%r8),%esi + addl 8(%r8),%ecx + movl %eax,0(%r8) + addl 12(%r8),%edx + movl %esi,4(%r8) + addl 16(%r8),%ebp + movl %ecx,8(%r8) + movl %edx,12(%r8) + movl %ebp,16(%r8) + movq -40(%r11),%r14 +.cfi_restore %r14 + movq -32(%r11),%r13 +.cfi_restore %r13 + movq -24(%r11),%r12 +.cfi_restore %r12 + movq -16(%r11),%rbp +.cfi_restore %rbp + movq -8(%r11),%rbx +.cfi_restore %rbx + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_block_data_order_avx,.-sha1_block_data_order_avx +.type sha1_block_data_order_avx2,@function +.align 16 +sha1_block_data_order_avx2: +_avx2_shortcut: +.cfi_startproc + movq %rsp,%r11 +.cfi_def_cfa_register %r11 + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + vzeroupper + movq %rdi,%r8 + movq %rsi,%r9 + movq %rdx,%r10 + + leaq -640(%rsp),%rsp + shlq $6,%r10 + leaq 64(%r9),%r13 + andq $-128,%rsp + addq %r9,%r10 + leaq K_XX_XX+64(%rip),%r14 + + movl 0(%r8),%eax + cmpq %r10,%r13 + cmovaeq %r9,%r13 + movl 4(%r8),%ebp + movl 8(%r8),%ecx + movl 12(%r8),%edx + movl 16(%r8),%esi + vmovdqu 64(%r14),%ymm6 + + vmovdqu (%r9),%xmm0 + vmovdqu 16(%r9),%xmm1 + vmovdqu 32(%r9),%xmm2 + vmovdqu 48(%r9),%xmm3 + leaq 64(%r9),%r9 + vinserti128 $1,(%r13),%ymm0,%ymm0 + vinserti128 $1,16(%r13),%ymm1,%ymm1 + vpshufb %ymm6,%ymm0,%ymm0 + vinserti128 $1,32(%r13),%ymm2,%ymm2 + vpshufb %ymm6,%ymm1,%ymm1 + vinserti128 $1,48(%r13),%ymm3,%ymm3 + vpshufb %ymm6,%ymm2,%ymm2 + vmovdqu -64(%r14),%ymm11 + vpshufb %ymm6,%ymm3,%ymm3 + + vpaddd %ymm11,%ymm0,%ymm4 + vpaddd %ymm11,%ymm1,%ymm5 + vmovdqu %ymm4,0(%rsp) + vpaddd %ymm11,%ymm2,%ymm6 + vmovdqu %ymm5,32(%rsp) + vpaddd %ymm11,%ymm3,%ymm7 + vmovdqu %ymm6,64(%rsp) + vmovdqu %ymm7,96(%rsp) + vpalignr $8,%ymm0,%ymm1,%ymm4 + vpsrldq $4,%ymm3,%ymm8 + vpxor %ymm0,%ymm4,%ymm4 + vpxor %ymm2,%ymm8,%ymm8 + vpxor %ymm8,%ymm4,%ymm4 + vpsrld $31,%ymm4,%ymm8 + vpslldq $12,%ymm4,%ymm10 + vpaddd %ymm4,%ymm4,%ymm4 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm4,%ymm4 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm4,%ymm4 + vpxor %ymm10,%ymm4,%ymm4 + vpaddd %ymm11,%ymm4,%ymm9 + vmovdqu %ymm9,128(%rsp) + vpalignr $8,%ymm1,%ymm2,%ymm5 + vpsrldq $4,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm3,%ymm8,%ymm8 + vpxor %ymm8,%ymm5,%ymm5 + vpsrld $31,%ymm5,%ymm8 + vmovdqu -32(%r14),%ymm11 + vpslldq $12,%ymm5,%ymm10 + vpaddd %ymm5,%ymm5,%ymm5 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm5,%ymm5 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm5,%ymm5 + vpxor %ymm10,%ymm5,%ymm5 + vpaddd %ymm11,%ymm5,%ymm9 + vmovdqu %ymm9,160(%rsp) + vpalignr $8,%ymm2,%ymm3,%ymm6 + vpsrldq $4,%ymm5,%ymm8 + vpxor %ymm2,%ymm6,%ymm6 + vpxor %ymm4,%ymm8,%ymm8 + vpxor %ymm8,%ymm6,%ymm6 + vpsrld $31,%ymm6,%ymm8 + vpslldq $12,%ymm6,%ymm10 + vpaddd %ymm6,%ymm6,%ymm6 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm6,%ymm6 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm6,%ymm6 + vpxor %ymm10,%ymm6,%ymm6 + vpaddd %ymm11,%ymm6,%ymm9 + vmovdqu %ymm9,192(%rsp) + vpalignr $8,%ymm3,%ymm4,%ymm7 + vpsrldq $4,%ymm6,%ymm8 + vpxor %ymm3,%ymm7,%ymm7 + vpxor %ymm5,%ymm8,%ymm8 + vpxor %ymm8,%ymm7,%ymm7 + vpsrld $31,%ymm7,%ymm8 + vpslldq $12,%ymm7,%ymm10 + vpaddd %ymm7,%ymm7,%ymm7 + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm7,%ymm7 + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm7,%ymm7 + vpxor %ymm10,%ymm7,%ymm7 + vpaddd %ymm11,%ymm7,%ymm9 + vmovdqu %ymm9,224(%rsp) + leaq 128(%rsp),%r13 + jmp .Loop_avx2 +.align 32 +.Loop_avx2: + rorxl $2,%ebp,%ebx + andnl %edx,%ebp,%edi + andl %ecx,%ebp + xorl %edi,%ebp + jmp .Lalign32_1 +.align 32 +.Lalign32_1: + vpalignr $8,%ymm6,%ymm7,%ymm8 + vpxor %ymm4,%ymm0,%ymm0 + addl -128(%r13),%esi + andnl %ecx,%eax,%edi + vpxor %ymm1,%ymm0,%ymm0 + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + vpxor %ymm8,%ymm0,%ymm0 + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + vpsrld $30,%ymm0,%ymm8 + vpslld $2,%ymm0,%ymm0 + addl -124(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + vpor %ymm8,%ymm0,%ymm0 + addl %r12d,%edx + xorl %edi,%esi + addl -120(%r13),%ecx + andnl %ebp,%edx,%edi + vpaddd %ymm11,%ymm0,%ymm9 + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + vmovdqu %ymm9,256(%rsp) + addl %r12d,%ecx + xorl %edi,%edx + addl -116(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl -96(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + vpalignr $8,%ymm7,%ymm0,%ymm8 + vpxor %ymm5,%ymm1,%ymm1 + addl -92(%r13),%eax + andnl %edx,%ebp,%edi + vpxor %ymm2,%ymm1,%ymm1 + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + vpxor %ymm8,%ymm1,%ymm1 + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + vpsrld $30,%ymm1,%ymm8 + vpslld $2,%ymm1,%ymm1 + addl -88(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + vpor %ymm8,%ymm1,%ymm1 + addl %r12d,%esi + xorl %edi,%eax + addl -84(%r13),%edx + andnl %ebx,%esi,%edi + vpaddd %ymm11,%ymm1,%ymm9 + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + vmovdqu %ymm9,288(%rsp) + addl %r12d,%edx + xorl %edi,%esi + addl -64(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -60(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + vpalignr $8,%ymm0,%ymm1,%ymm8 + vpxor %ymm6,%ymm2,%ymm2 + addl -56(%r13),%ebp + andnl %esi,%ebx,%edi + vpxor %ymm3,%ymm2,%ymm2 + vmovdqu 0(%r14),%ymm11 + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + vpxor %ymm8,%ymm2,%ymm2 + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + vpsrld $30,%ymm2,%ymm8 + vpslld $2,%ymm2,%ymm2 + addl -52(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + vpor %ymm8,%ymm2,%ymm2 + addl %r12d,%eax + xorl %edi,%ebp + addl -32(%r13),%esi + andnl %ecx,%eax,%edi + vpaddd %ymm11,%ymm2,%ymm9 + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + vmovdqu %ymm9,320(%rsp) + addl %r12d,%esi + xorl %edi,%eax + addl -28(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -24(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + vpalignr $8,%ymm1,%ymm2,%ymm8 + vpxor %ymm7,%ymm3,%ymm3 + addl -20(%r13),%ebx + andnl %eax,%ecx,%edi + vpxor %ymm4,%ymm3,%ymm3 + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + vpxor %ymm8,%ymm3,%ymm3 + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + vpsrld $30,%ymm3,%ymm8 + vpslld $2,%ymm3,%ymm3 + addl 0(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + vpor %ymm8,%ymm3,%ymm3 + addl %r12d,%ebp + xorl %edi,%ebx + addl 4(%r13),%eax + andnl %edx,%ebp,%edi + vpaddd %ymm11,%ymm3,%ymm9 + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + vmovdqu %ymm9,352(%rsp) + addl %r12d,%eax + xorl %edi,%ebp + addl 8(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl 12(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + vpalignr $8,%ymm2,%ymm3,%ymm8 + vpxor %ymm0,%ymm4,%ymm4 + addl 32(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + vpxor %ymm5,%ymm4,%ymm4 + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + vpxor %ymm8,%ymm4,%ymm4 + addl %r12d,%ecx + xorl %ebp,%edx + addl 36(%r13),%ebx + vpsrld $30,%ymm4,%ymm8 + vpslld $2,%ymm4,%ymm4 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + vpor %ymm8,%ymm4,%ymm4 + addl 40(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + vpaddd %ymm11,%ymm4,%ymm9 + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 44(%r13),%eax + vmovdqu %ymm9,384(%rsp) + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl 64(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vpalignr $8,%ymm3,%ymm4,%ymm8 + vpxor %ymm1,%ymm5,%ymm5 + addl 68(%r13),%edx + leal (%rdx,%rax,1),%edx + vpxor %ymm6,%ymm5,%ymm5 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + vpxor %ymm8,%ymm5,%ymm5 + addl %r12d,%edx + xorl %ebx,%esi + addl 72(%r13),%ecx + vpsrld $30,%ymm5,%ymm8 + vpslld $2,%ymm5,%ymm5 + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + vpor %ymm8,%ymm5,%ymm5 + addl 76(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + vpaddd %ymm11,%ymm5,%ymm9 + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl 96(%r13),%ebp + vmovdqu %ymm9,416(%rsp) + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 100(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpalignr $8,%ymm4,%ymm5,%ymm8 + vpxor %ymm2,%ymm6,%ymm6 + addl 104(%r13),%esi + leal (%rsi,%rbp,1),%esi + vpxor %ymm7,%ymm6,%ymm6 + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + vpxor %ymm8,%ymm6,%ymm6 + addl %r12d,%esi + xorl %ecx,%eax + addl 108(%r13),%edx + leaq 256(%r13),%r13 + vpsrld $30,%ymm6,%ymm8 + vpslld $2,%ymm6,%ymm6 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + vpor %ymm8,%ymm6,%ymm6 + addl -128(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + vpaddd %ymm11,%ymm6,%ymm9 + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -124(%r13),%ebx + vmovdqu %ymm9,448(%rsp) + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -120(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vpalignr $8,%ymm5,%ymm6,%ymm8 + vpxor %ymm3,%ymm7,%ymm7 + addl -116(%r13),%eax + leal (%rax,%rbx,1),%eax + vpxor %ymm0,%ymm7,%ymm7 + vmovdqu 32(%r14),%ymm11 + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + vpxor %ymm8,%ymm7,%ymm7 + addl %r12d,%eax + xorl %edx,%ebp + addl -96(%r13),%esi + vpsrld $30,%ymm7,%ymm8 + vpslld $2,%ymm7,%ymm7 + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vpor %ymm8,%ymm7,%ymm7 + addl -92(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpaddd %ymm11,%ymm7,%ymm9 + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -88(%r13),%ecx + vmovdqu %ymm9,480(%rsp) + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -84(%r13),%ebx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + jmp .Lalign32_2 +.align 32 +.Lalign32_2: + vpalignr $8,%ymm6,%ymm7,%ymm8 + vpxor %ymm4,%ymm0,%ymm0 + addl -64(%r13),%ebp + xorl %esi,%ecx + vpxor %ymm1,%ymm0,%ymm0 + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + vpxor %ymm8,%ymm0,%ymm0 + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + vpsrld $30,%ymm0,%ymm8 + vpslld $2,%ymm0,%ymm0 + addl %r12d,%ebp + andl %edi,%ebx + addl -60(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + vpor %ymm8,%ymm0,%ymm0 + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + vpaddd %ymm11,%ymm0,%ymm9 + addl %r12d,%eax + andl %edi,%ebp + addl -56(%r13),%esi + xorl %ecx,%ebp + vmovdqu %ymm9,512(%rsp) + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl -52(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + addl -32(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + andl %edi,%edx + vpalignr $8,%ymm7,%ymm0,%ymm8 + vpxor %ymm5,%ymm1,%ymm1 + addl -28(%r13),%ebx + xorl %eax,%edx + vpxor %ymm2,%ymm1,%ymm1 + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + vpxor %ymm8,%ymm1,%ymm1 + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + vpsrld $30,%ymm1,%ymm8 + vpslld $2,%ymm1,%ymm1 + addl %r12d,%ebx + andl %edi,%ecx + addl -24(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + vpor %ymm8,%ymm1,%ymm1 + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + vpaddd %ymm11,%ymm1,%ymm9 + addl %r12d,%ebp + andl %edi,%ebx + addl -20(%r13),%eax + xorl %edx,%ebx + vmovdqu %ymm9,544(%rsp) + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 0(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl 4(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + vpalignr $8,%ymm0,%ymm1,%ymm8 + vpxor %ymm6,%ymm2,%ymm2 + addl 8(%r13),%ecx + xorl %ebp,%esi + vpxor %ymm3,%ymm2,%ymm2 + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + vpxor %ymm8,%ymm2,%ymm2 + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + vpsrld $30,%ymm2,%ymm8 + vpslld $2,%ymm2,%ymm2 + addl %r12d,%ecx + andl %edi,%edx + addl 12(%r13),%ebx + xorl %eax,%edx + movl %esi,%edi + xorl %eax,%edi + vpor %ymm8,%ymm2,%ymm2 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + vpaddd %ymm11,%ymm2,%ymm9 + addl %r12d,%ebx + andl %edi,%ecx + addl 32(%r13),%ebp + xorl %esi,%ecx + vmovdqu %ymm9,576(%rsp) + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 36(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 40(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + vpalignr $8,%ymm1,%ymm2,%ymm8 + vpxor %ymm7,%ymm3,%ymm3 + addl 44(%r13),%edx + xorl %ebx,%eax + vpxor %ymm4,%ymm3,%ymm3 + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + vpxor %ymm8,%ymm3,%ymm3 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + vpsrld $30,%ymm3,%ymm8 + vpslld $2,%ymm3,%ymm3 + addl %r12d,%edx + andl %edi,%esi + addl 64(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + vpor %ymm8,%ymm3,%ymm3 + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + vpaddd %ymm11,%ymm3,%ymm9 + addl %r12d,%ecx + andl %edi,%edx + addl 68(%r13),%ebx + xorl %eax,%edx + vmovdqu %ymm9,608(%rsp) + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + addl 72(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 76(%r13),%eax + xorl %edx,%ebx + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl 96(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl 100(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl 104(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl 108(%r13),%ebx + leaq 256(%r13),%r13 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -128(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -124(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -120(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -116(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -96(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -92(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -88(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -84(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -64(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -60(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -56(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -52(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -32(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -28(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -24(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -20(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + addl %r12d,%edx + leaq 128(%r9),%r13 + leaq 128(%r9),%rdi + cmpq %r10,%r13 + cmovaeq %r9,%r13 + + + addl 0(%r8),%edx + addl 4(%r8),%esi + addl 8(%r8),%ebp + movl %edx,0(%r8) + addl 12(%r8),%ebx + movl %esi,4(%r8) + movl %edx,%eax + addl 16(%r8),%ecx + movl %ebp,%r12d + movl %ebp,8(%r8) + movl %ebx,%edx + + movl %ebx,12(%r8) + movl %esi,%ebp + movl %ecx,16(%r8) + + movl %ecx,%esi + movl %r12d,%ecx + + + cmpq %r10,%r9 + je .Ldone_avx2 + vmovdqu 64(%r14),%ymm6 + cmpq %r10,%rdi + ja .Last_avx2 + + vmovdqu -64(%rdi),%xmm0 + vmovdqu -48(%rdi),%xmm1 + vmovdqu -32(%rdi),%xmm2 + vmovdqu -16(%rdi),%xmm3 + vinserti128 $1,0(%r13),%ymm0,%ymm0 + vinserti128 $1,16(%r13),%ymm1,%ymm1 + vinserti128 $1,32(%r13),%ymm2,%ymm2 + vinserti128 $1,48(%r13),%ymm3,%ymm3 + jmp .Last_avx2 + +.align 32 +.Last_avx2: + leaq 128+16(%rsp),%r13 + rorxl $2,%ebp,%ebx + andnl %edx,%ebp,%edi + andl %ecx,%ebp + xorl %edi,%ebp + subq $-128,%r9 + addl -128(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl -124(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -120(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -116(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl -96(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + addl -92(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + addl -88(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl -84(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -64(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -60(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl -56(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + addl -52(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + addl -32(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl -28(%r13),%edx + andnl %ebx,%esi,%edi + addl %eax,%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + andl %ebp,%esi + addl %r12d,%edx + xorl %edi,%esi + addl -24(%r13),%ecx + andnl %ebp,%edx,%edi + addl %esi,%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + andl %eax,%edx + addl %r12d,%ecx + xorl %edi,%edx + addl -20(%r13),%ebx + andnl %eax,%ecx,%edi + addl %edx,%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + andl %esi,%ecx + addl %r12d,%ebx + xorl %edi,%ecx + addl 0(%r13),%ebp + andnl %esi,%ebx,%edi + addl %ecx,%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + andl %edx,%ebx + addl %r12d,%ebp + xorl %edi,%ebx + addl 4(%r13),%eax + andnl %edx,%ebp,%edi + addl %ebx,%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + andl %ecx,%ebp + addl %r12d,%eax + xorl %edi,%ebp + addl 8(%r13),%esi + andnl %ecx,%eax,%edi + addl %ebp,%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + andl %ebx,%eax + addl %r12d,%esi + xorl %edi,%eax + addl 12(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl 32(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl 36(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl 40(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 44(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl 64(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vmovdqu -64(%r14),%ymm11 + vpshufb %ymm6,%ymm0,%ymm0 + addl 68(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl 72(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl 76(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl 96(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl 100(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpshufb %ymm6,%ymm1,%ymm1 + vpaddd %ymm11,%ymm0,%ymm8 + addl 104(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl 108(%r13),%edx + leaq 256(%r13),%r13 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -128(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -124(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -120(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vmovdqu %ymm8,0(%rsp) + vpshufb %ymm6,%ymm2,%ymm2 + vpaddd %ymm11,%ymm1,%ymm9 + addl -116(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -96(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -92(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + addl -88(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -84(%r13),%ebx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + vmovdqu %ymm9,32(%rsp) + vpshufb %ymm6,%ymm3,%ymm3 + vpaddd %ymm11,%ymm2,%ymm6 + addl -64(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl -60(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl -56(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl -52(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + addl -32(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + andl %edi,%edx + jmp .Lalign32_3 +.align 32 +.Lalign32_3: + vmovdqu %ymm6,64(%rsp) + vpaddd %ymm11,%ymm3,%ymm7 + addl -28(%r13),%ebx + xorl %eax,%edx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + addl -24(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl -20(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 0(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + addl 4(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + andl %edi,%esi + vmovdqu %ymm7,96(%rsp) + addl 8(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + andl %edi,%edx + addl 12(%r13),%ebx + xorl %eax,%edx + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + andl %edi,%ecx + addl 32(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 36(%r13),%eax + xorl %edx,%ebx + movl %ecx,%edi + xorl %edx,%edi + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + andl %edi,%ebp + addl 40(%r13),%esi + xorl %ecx,%ebp + movl %ebx,%edi + xorl %ecx,%edi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + andl %edi,%eax + vpalignr $8,%ymm0,%ymm1,%ymm4 + addl 44(%r13),%edx + xorl %ebx,%eax + movl %ebp,%edi + xorl %ebx,%edi + vpsrldq $4,%ymm3,%ymm8 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpxor %ymm0,%ymm4,%ymm4 + vpxor %ymm2,%ymm8,%ymm8 + xorl %ebp,%esi + addl %r12d,%edx + vpxor %ymm8,%ymm4,%ymm4 + andl %edi,%esi + addl 64(%r13),%ecx + xorl %ebp,%esi + movl %eax,%edi + vpsrld $31,%ymm4,%ymm8 + xorl %ebp,%edi + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + vpslldq $12,%ymm4,%ymm10 + vpaddd %ymm4,%ymm4,%ymm4 + rorxl $2,%edx,%esi + xorl %eax,%edx + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm4,%ymm4 + addl %r12d,%ecx + andl %edi,%edx + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm4,%ymm4 + addl 68(%r13),%ebx + xorl %eax,%edx + vpxor %ymm10,%ymm4,%ymm4 + movl %esi,%edi + xorl %eax,%edi + leal (%rbx,%rdx,1),%ebx + vpaddd %ymm11,%ymm4,%ymm9 + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + vmovdqu %ymm9,128(%rsp) + addl %r12d,%ebx + andl %edi,%ecx + addl 72(%r13),%ebp + xorl %esi,%ecx + movl %edx,%edi + xorl %esi,%edi + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + andl %edi,%ebx + addl 76(%r13),%eax + xorl %edx,%ebx + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpalignr $8,%ymm1,%ymm2,%ymm5 + addl 96(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + vpsrldq $4,%ymm4,%ymm8 + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + vpxor %ymm1,%ymm5,%ymm5 + vpxor %ymm3,%ymm8,%ymm8 + addl 100(%r13),%edx + leal (%rdx,%rax,1),%edx + vpxor %ymm8,%ymm5,%ymm5 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + xorl %ebp,%esi + addl %r12d,%edx + vpsrld $31,%ymm5,%ymm8 + vmovdqu -32(%r14),%ymm11 + xorl %ebx,%esi + addl 104(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + vpslldq $12,%ymm5,%ymm10 + vpaddd %ymm5,%ymm5,%ymm5 + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm5,%ymm5 + xorl %eax,%edx + addl %r12d,%ecx + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm5,%ymm5 + xorl %ebp,%edx + addl 108(%r13),%ebx + leaq 256(%r13),%r13 + vpxor %ymm10,%ymm5,%ymm5 + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + vpaddd %ymm11,%ymm5,%ymm9 + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + vmovdqu %ymm9,160(%rsp) + addl -128(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vpalignr $8,%ymm2,%ymm3,%ymm6 + addl -124(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + vpsrldq $4,%ymm5,%ymm8 + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + vpxor %ymm2,%ymm6,%ymm6 + vpxor %ymm4,%ymm8,%ymm8 + addl -120(%r13),%esi + leal (%rsi,%rbp,1),%esi + vpxor %ymm8,%ymm6,%ymm6 + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + vpsrld $31,%ymm6,%ymm8 + xorl %ecx,%eax + addl -116(%r13),%edx + leal (%rdx,%rax,1),%edx + vpslldq $12,%ymm6,%ymm10 + vpaddd %ymm6,%ymm6,%ymm6 + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm6,%ymm6 + xorl %ebp,%esi + addl %r12d,%edx + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm6,%ymm6 + xorl %ebx,%esi + addl -96(%r13),%ecx + vpxor %ymm10,%ymm6,%ymm6 + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + vpaddd %ymm11,%ymm6,%ymm9 + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + vmovdqu %ymm9,192(%rsp) + addl -92(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + vpalignr $8,%ymm3,%ymm4,%ymm7 + addl -88(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + vpsrldq $4,%ymm6,%ymm8 + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + vpxor %ymm3,%ymm7,%ymm7 + vpxor %ymm5,%ymm8,%ymm8 + addl -84(%r13),%eax + leal (%rax,%rbx,1),%eax + vpxor %ymm8,%ymm7,%ymm7 + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + vpsrld $31,%ymm7,%ymm8 + xorl %edx,%ebp + addl -64(%r13),%esi + leal (%rsi,%rbp,1),%esi + vpslldq $12,%ymm7,%ymm10 + vpaddd %ymm7,%ymm7,%ymm7 + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + vpsrld $30,%ymm10,%ymm9 + vpor %ymm8,%ymm7,%ymm7 + xorl %ebx,%eax + addl %r12d,%esi + vpslld $2,%ymm10,%ymm10 + vpxor %ymm9,%ymm7,%ymm7 + xorl %ecx,%eax + addl -60(%r13),%edx + vpxor %ymm10,%ymm7,%ymm7 + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + rorxl $2,%esi,%eax + vpaddd %ymm11,%ymm7,%ymm9 + xorl %ebp,%esi + addl %r12d,%edx + xorl %ebx,%esi + vmovdqu %ymm9,224(%rsp) + addl -56(%r13),%ecx + leal (%rcx,%rsi,1),%ecx + rorxl $27,%edx,%r12d + rorxl $2,%edx,%esi + xorl %eax,%edx + addl %r12d,%ecx + xorl %ebp,%edx + addl -52(%r13),%ebx + leal (%rbx,%rdx,1),%ebx + rorxl $27,%ecx,%r12d + rorxl $2,%ecx,%edx + xorl %esi,%ecx + addl %r12d,%ebx + xorl %eax,%ecx + addl -32(%r13),%ebp + leal (%rcx,%rbp,1),%ebp + rorxl $27,%ebx,%r12d + rorxl $2,%ebx,%ecx + xorl %edx,%ebx + addl %r12d,%ebp + xorl %esi,%ebx + addl -28(%r13),%eax + leal (%rax,%rbx,1),%eax + rorxl $27,%ebp,%r12d + rorxl $2,%ebp,%ebx + xorl %ecx,%ebp + addl %r12d,%eax + xorl %edx,%ebp + addl -24(%r13),%esi + leal (%rsi,%rbp,1),%esi + rorxl $27,%eax,%r12d + rorxl $2,%eax,%ebp + xorl %ebx,%eax + addl %r12d,%esi + xorl %ecx,%eax + addl -20(%r13),%edx + leal (%rdx,%rax,1),%edx + rorxl $27,%esi,%r12d + addl %r12d,%edx + leaq 128(%rsp),%r13 + + + addl 0(%r8),%edx + addl 4(%r8),%esi + addl 8(%r8),%ebp + movl %edx,0(%r8) + addl 12(%r8),%ebx + movl %esi,4(%r8) + movl %edx,%eax + addl 16(%r8),%ecx + movl %ebp,%r12d + movl %ebp,8(%r8) + movl %ebx,%edx + + movl %ebx,12(%r8) + movl %esi,%ebp + movl %ecx,16(%r8) + + movl %ecx,%esi + movl %r12d,%ecx + + + cmpq %r10,%r9 + jbe .Loop_avx2 + +.Ldone_avx2: + vzeroupper + movq -40(%r11),%r14 +.cfi_restore %r14 + movq -32(%r11),%r13 +.cfi_restore %r13 + movq -24(%r11),%r12 +.cfi_restore %r12 + movq -16(%r11),%rbp +.cfi_restore %rbp + movq -8(%r11),%rbx +.cfi_restore %rbx + leaq (%r11),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx2: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha1_block_data_order_avx2,.-sha1_block_data_order_avx2 +.align 64 +K_XX_XX: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.byte 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 +.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 64 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/sha/sha1_one.c b/crypto/openssl/crypto/sha/sha1_one.c index e5b38211d2da..d1fa3d84f12a 100644 --- a/crypto/openssl/crypto/sha/sha1_one.c +++ b/crypto/openssl/crypto/sha/sha1_one.c @@ -1,18 +1,26 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * SHA-1 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include #include +#include +#include "crypto/sha.h" -unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) +unsigned char *ossl_sha1(const unsigned char *d, size_t n, unsigned char *md) { SHA_CTX c; static unsigned char m[SHA_DIGEST_LENGTH]; @@ -26,3 +34,48 @@ unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) OPENSSL_cleanse(&c, sizeof(c)); return md; } + +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) +{ + static unsigned char m[SHA_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + return EVP_Q_digest(NULL, "SHA1", NULL, d, n, md, NULL) ? md : NULL; +} + +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md) +{ + static unsigned char m[SHA224_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + return EVP_Q_digest(NULL, "SHA224", NULL, d, n, md, NULL) ? md : NULL; +} + +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) +{ + static unsigned char m[SHA256_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + return EVP_Q_digest(NULL, "SHA256", NULL, d, n, md, NULL) ? md : NULL; +} + +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md) +{ + static unsigned char m[SHA384_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + return EVP_Q_digest(NULL, "SHA384", NULL, d, n, md, NULL) ? md : NULL; +} + +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md) +{ + static unsigned char m[SHA512_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + return EVP_Q_digest(NULL, "SHA512", NULL, d, n, md, NULL) ? md : NULL; +} diff --git a/crypto/openssl/crypto/sha/sha1dgst.c b/crypto/openssl/crypto/sha/sha1dgst.c index 7965829e64b0..65d7e62e58e7 100644 --- a/crypto/openssl/crypto/sha/sha1dgst.c +++ b/crypto/openssl/crypto/sha/sha1dgst.c @@ -1,17 +1,80 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * SHA-1 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include -# include +#include +#include +#include /* The implementation is in ../md32_common.h */ -# include "sha_local.h" +#include "sha_local.h" +#include "crypto/sha.h" + +int ossl_sha1_ctrl(SHA_CTX *sha1, int cmd, int mslen, void *ms) +{ + unsigned char padtmp[40]; + unsigned char sha1tmp[SHA_DIGEST_LENGTH]; + + if (cmd != EVP_CTRL_SSL3_MASTER_SECRET) + return -2; + + if (sha1 == NULL) + return 0; + + /* SSLv3 client auth handling: see RFC-6101 5.6.8 */ + if (mslen != 48) + return 0; + + /* At this point hash contains all handshake messages, update + * with master secret and pad_1. + */ + + if (SHA1_Update(sha1, ms, mslen) <= 0) + return 0; + + /* Set padtmp to pad_1 value */ + memset(padtmp, 0x36, sizeof(padtmp)); + + if (!SHA1_Update(sha1, padtmp, sizeof(padtmp))) + return 0; + + if (!SHA1_Final(sha1tmp, sha1)) + return 0; + + /* Reinitialise context */ + + if (!SHA1_Init(sha1)) + return 0; + + if (SHA1_Update(sha1, ms, mslen) <= 0) + return 0; + + /* Set padtmp to pad_2 value */ + memset(padtmp, 0x5c, sizeof(padtmp)); + + if (!SHA1_Update(sha1, padtmp, sizeof(padtmp))) + return 0; + + if (!SHA1_Update(sha1, sha1tmp, sizeof(sha1tmp))) + return 0; + + /* Now when ctx is finalised it will return the SSL v3 hash value */ + OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp)); + + return 1; +} diff --git a/crypto/openssl/crypto/sha/sha256-586.S b/crypto/openssl/crypto/sha/sha256-586.S new file mode 100644 index 000000000000..c8599bd582c6 --- /dev/null +++ b/crypto/openssl/crypto/sha/sha256-586.S @@ -0,0 +1,6804 @@ +.text +.globl sha256_block_data_order +.type sha256_block_data_order,@function +.align 16 +sha256_block_data_order: +.L_sha256_block_data_order_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl %esp,%ebx + call .L000pic_point +.L000pic_point: + popl %ebp + leal .L001K256-.L000pic_point(%ebp),%ebp + subl $16,%esp + andl $-64,%esp + shll $6,%eax + addl %edi,%eax + movl %esi,(%esp) + movl %edi,4(%esp) + movl %eax,8(%esp) + movl %ebx,12(%esp) + leal OPENSSL_ia32cap_P-.L001K256(%ebp),%edx + movl (%edx),%ecx + movl 4(%edx),%ebx + testl $1048576,%ecx + jnz .L002loop + movl 8(%edx),%edx + testl $16777216,%ecx + jz .L003no_xmm + andl $1073741824,%ecx + andl $268435968,%ebx + testl $536870912,%edx + jnz .L004shaext + orl %ebx,%ecx + andl $1342177280,%ecx + cmpl $1342177280,%ecx + je .L005AVX + testl $512,%ebx + jnz .L006SSSE3 +.L003no_xmm: + subl %edi,%eax + cmpl $256,%eax + jae .L007unrolled + jmp .L002loop +.align 16 +.L002loop: + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + bswap %eax + movl 12(%edi),%edx + bswap %ebx + pushl %eax + bswap %ecx + pushl %ebx + bswap %edx + pushl %ecx + pushl %edx + movl 16(%edi),%eax + movl 20(%edi),%ebx + movl 24(%edi),%ecx + bswap %eax + movl 28(%edi),%edx + bswap %ebx + pushl %eax + bswap %ecx + pushl %ebx + bswap %edx + pushl %ecx + pushl %edx + movl 32(%edi),%eax + movl 36(%edi),%ebx + movl 40(%edi),%ecx + bswap %eax + movl 44(%edi),%edx + bswap %ebx + pushl %eax + bswap %ecx + pushl %ebx + bswap %edx + pushl %ecx + pushl %edx + movl 48(%edi),%eax + movl 52(%edi),%ebx + movl 56(%edi),%ecx + bswap %eax + movl 60(%edi),%edx + bswap %ebx + pushl %eax + bswap %ecx + pushl %ebx + bswap %edx + pushl %ecx + pushl %edx + addl $64,%edi + leal -36(%esp),%esp + movl %edi,104(%esp) + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edi + movl %ebx,8(%esp) + xorl %ecx,%ebx + movl %ecx,12(%esp) + movl %edi,16(%esp) + movl %ebx,(%esp) + movl 16(%esi),%edx + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edi + movl %ebx,24(%esp) + movl %ecx,28(%esp) + movl %edi,32(%esp) +.align 16 +.L00800_15: + movl %edx,%ecx + movl 24(%esp),%esi + rorl $14,%ecx + movl 28(%esp),%edi + xorl %edx,%ecx + xorl %edi,%esi + movl 96(%esp),%ebx + rorl $5,%ecx + andl %edx,%esi + movl %edx,20(%esp) + xorl %ecx,%edx + addl 32(%esp),%ebx + xorl %edi,%esi + rorl $6,%edx + movl %eax,%ecx + addl %esi,%ebx + rorl $9,%ecx + addl %edx,%ebx + movl 8(%esp),%edi + xorl %eax,%ecx + movl %eax,4(%esp) + leal -4(%esp),%esp + rorl $11,%ecx + movl (%ebp),%esi + xorl %eax,%ecx + movl 20(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %esi,%ebx + movl %eax,(%esp) + addl %ebx,%edx + andl 4(%esp),%eax + addl %ecx,%ebx + xorl %edi,%eax + addl $4,%ebp + addl %ebx,%eax + cmpl $3248222580,%esi + jne .L00800_15 + movl 156(%esp),%ecx + jmp .L00916_63 +.align 16 +.L00916_63: + movl %ecx,%ebx + movl 104(%esp),%esi + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 160(%esp),%ebx + shrl $10,%edi + addl 124(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 24(%esp),%esi + rorl $14,%ecx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %edx,%ecx + xorl %edi,%esi + movl %ebx,96(%esp) + rorl $5,%ecx + andl %edx,%esi + movl %edx,20(%esp) + xorl %ecx,%edx + addl 32(%esp),%ebx + xorl %edi,%esi + rorl $6,%edx + movl %eax,%ecx + addl %esi,%ebx + rorl $9,%ecx + addl %edx,%ebx + movl 8(%esp),%edi + xorl %eax,%ecx + movl %eax,4(%esp) + leal -4(%esp),%esp + rorl $11,%ecx + movl (%ebp),%esi + xorl %eax,%ecx + movl 20(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %esi,%ebx + movl %eax,(%esp) + addl %ebx,%edx + andl 4(%esp),%eax + addl %ecx,%ebx + xorl %edi,%eax + movl 156(%esp),%ecx + addl $4,%ebp + addl %ebx,%eax + cmpl $3329325298,%esi + jne .L00916_63 + movl 356(%esp),%esi + movl 8(%esp),%ebx + movl 16(%esp),%ecx + addl (%esi),%eax + addl 4(%esi),%ebx + addl 8(%esi),%edi + addl 12(%esi),%ecx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %edi,8(%esi) + movl %ecx,12(%esi) + movl 24(%esp),%eax + movl 28(%esp),%ebx + movl 32(%esp),%ecx + movl 360(%esp),%edi + addl 16(%esi),%edx + addl 20(%esi),%eax + addl 24(%esi),%ebx + addl 28(%esi),%ecx + movl %edx,16(%esi) + movl %eax,20(%esi) + movl %ebx,24(%esi) + movl %ecx,28(%esi) + leal 356(%esp),%esp + subl $256,%ebp + cmpl 8(%esp),%edi + jb .L002loop + movl 12(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 64 +.L001K256: +.long 1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298 +.long 66051,67438087,134810123,202182159 +.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97 +.byte 110,115,102,111,114,109,32,102,111,114,32,120,56,54,44,32 +.byte 67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97 +.byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103 +.byte 62,0 +.align 16 +.L007unrolled: + leal -96(%esp),%esp + movl (%esi),%eax + movl 4(%esi),%ebp + movl 8(%esi),%ecx + movl 12(%esi),%ebx + movl %ebp,4(%esp) + xorl %ecx,%ebp + movl %ecx,8(%esp) + movl %ebx,12(%esp) + movl 16(%esi),%edx + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%esi + movl %ebx,20(%esp) + movl %ecx,24(%esp) + movl %esi,28(%esp) + jmp .L010grand_loop +.align 16 +.L010grand_loop: + movl (%edi),%ebx + movl 4(%edi),%ecx + bswap %ebx + movl 8(%edi),%esi + bswap %ecx + movl %ebx,32(%esp) + bswap %esi + movl %ecx,36(%esp) + movl %esi,40(%esp) + movl 12(%edi),%ebx + movl 16(%edi),%ecx + bswap %ebx + movl 20(%edi),%esi + bswap %ecx + movl %ebx,44(%esp) + bswap %esi + movl %ecx,48(%esp) + movl %esi,52(%esp) + movl 24(%edi),%ebx + movl 28(%edi),%ecx + bswap %ebx + movl 32(%edi),%esi + bswap %ecx + movl %ebx,56(%esp) + bswap %esi + movl %ecx,60(%esp) + movl %esi,64(%esp) + movl 36(%edi),%ebx + movl 40(%edi),%ecx + bswap %ebx + movl 44(%edi),%esi + bswap %ecx + movl %ebx,68(%esp) + bswap %esi + movl %ecx,72(%esp) + movl %esi,76(%esp) + movl 48(%edi),%ebx + movl 52(%edi),%ecx + bswap %ebx + movl 56(%edi),%esi + bswap %ecx + movl %ebx,80(%esp) + bswap %esi + movl %ecx,84(%esp) + movl %esi,88(%esp) + movl 60(%edi),%ebx + addl $64,%edi + bswap %ebx + movl %edi,100(%esp) + movl %ebx,92(%esp) + movl %edx,%ecx + movl 20(%esp),%esi + rorl $14,%edx + movl 24(%esp),%edi + xorl %ecx,%edx + movl 32(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1116352408(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 16(%esp),%ecx + rorl $14,%edx + movl 20(%esp),%edi + xorl %esi,%edx + movl 36(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1899447441(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 12(%esp),%esi + rorl $14,%edx + movl 16(%esp),%edi + xorl %ecx,%edx + movl 40(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3049323471(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 8(%esp),%ecx + rorl $14,%edx + movl 12(%esp),%edi + xorl %esi,%edx + movl 44(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3921009573(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 4(%esp),%esi + rorl $14,%edx + movl 8(%esp),%edi + xorl %ecx,%edx + movl 48(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 961987163(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl (%esp),%ecx + rorl $14,%edx + movl 4(%esp),%edi + xorl %esi,%edx + movl 52(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1508970993(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 28(%esp),%esi + rorl $14,%edx + movl (%esp),%edi + xorl %ecx,%edx + movl 56(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2453635748(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 24(%esp),%ecx + rorl $14,%edx + movl 28(%esp),%edi + xorl %esi,%edx + movl 60(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2870763221(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 20(%esp),%esi + rorl $14,%edx + movl 24(%esp),%edi + xorl %ecx,%edx + movl 64(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3624381080(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 16(%esp),%ecx + rorl $14,%edx + movl 20(%esp),%edi + xorl %esi,%edx + movl 68(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 310598401(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 12(%esp),%esi + rorl $14,%edx + movl 16(%esp),%edi + xorl %ecx,%edx + movl 72(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 607225278(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 8(%esp),%ecx + rorl $14,%edx + movl 12(%esp),%edi + xorl %esi,%edx + movl 76(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1426881987(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 4(%esp),%esi + rorl $14,%edx + movl 8(%esp),%edi + xorl %ecx,%edx + movl 80(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1925078388(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl (%esp),%ecx + rorl $14,%edx + movl 4(%esp),%edi + xorl %esi,%edx + movl 84(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2162078206(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl %edx,%ecx + movl 28(%esp),%esi + rorl $14,%edx + movl (%esp),%edi + xorl %ecx,%edx + movl 88(%esp),%ebx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2614888103(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl %edx,%esi + movl 24(%esp),%ecx + rorl $14,%edx + movl 28(%esp),%edi + xorl %esi,%edx + movl 92(%esp),%ebx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3248222580(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 36(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 88(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 32(%esp),%ebx + shrl $10,%edi + addl 68(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,32(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3835390401(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 40(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 92(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 36(%esp),%ebx + shrl $10,%edi + addl 72(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,36(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 4022224774(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 44(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 32(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 40(%esp),%ebx + shrl $10,%edi + addl 76(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,40(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 264347078(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 48(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 36(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 44(%esp),%ebx + shrl $10,%edi + addl 80(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,44(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 604807628(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 52(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 40(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 48(%esp),%ebx + shrl $10,%edi + addl 84(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,48(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 770255983(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 56(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 44(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 52(%esp),%ebx + shrl $10,%edi + addl 88(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,52(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1249150122(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 60(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 48(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 56(%esp),%ebx + shrl $10,%edi + addl 92(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + movl %ebx,56(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1555081692(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 64(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 52(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 60(%esp),%ebx + shrl $10,%edi + addl 32(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + movl %ebx,60(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1996064986(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 68(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 56(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 64(%esp),%ebx + shrl $10,%edi + addl 36(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,64(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2554220882(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 72(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 60(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 68(%esp),%ebx + shrl $10,%edi + addl 40(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,68(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2821834349(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 76(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 64(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 72(%esp),%ebx + shrl $10,%edi + addl 44(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,72(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2952996808(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 80(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 68(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 76(%esp),%ebx + shrl $10,%edi + addl 48(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,76(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3210313671(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 84(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 72(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 80(%esp),%ebx + shrl $10,%edi + addl 52(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,80(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3336571891(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 88(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 76(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 84(%esp),%ebx + shrl $10,%edi + addl 56(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,84(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3584528711(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 92(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 80(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 88(%esp),%ebx + shrl $10,%edi + addl 60(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + movl %ebx,88(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 113926993(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 32(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 84(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 92(%esp),%ebx + shrl $10,%edi + addl 64(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + movl %ebx,92(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 338241895(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 36(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 88(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 32(%esp),%ebx + shrl $10,%edi + addl 68(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,32(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 666307205(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 40(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 92(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 36(%esp),%ebx + shrl $10,%edi + addl 72(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,36(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 773529912(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 44(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 32(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 40(%esp),%ebx + shrl $10,%edi + addl 76(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,40(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1294757372(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 48(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 36(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 44(%esp),%ebx + shrl $10,%edi + addl 80(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,44(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1396182291(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 52(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 40(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 48(%esp),%ebx + shrl $10,%edi + addl 84(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,48(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1695183700(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 56(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 44(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 52(%esp),%ebx + shrl $10,%edi + addl 88(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,52(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1986661051(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 60(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 48(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 56(%esp),%ebx + shrl $10,%edi + addl 92(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + movl %ebx,56(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2177026350(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 64(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 52(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 60(%esp),%ebx + shrl $10,%edi + addl 32(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + movl %ebx,60(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2456956037(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 68(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 56(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 64(%esp),%ebx + shrl $10,%edi + addl 36(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,64(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2730485921(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 72(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 60(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 68(%esp),%ebx + shrl $10,%edi + addl 40(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,68(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2820302411(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 76(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 64(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 72(%esp),%ebx + shrl $10,%edi + addl 44(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,72(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3259730800(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 80(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 68(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 76(%esp),%ebx + shrl $10,%edi + addl 48(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,76(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3345764771(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 84(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 72(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 80(%esp),%ebx + shrl $10,%edi + addl 52(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,80(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3516065817(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 88(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 76(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 84(%esp),%ebx + shrl $10,%edi + addl 56(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,84(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3600352804(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 92(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 80(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 88(%esp),%ebx + shrl $10,%edi + addl 60(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + movl %ebx,88(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 4094571909(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 32(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 84(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 92(%esp),%ebx + shrl $10,%edi + addl 64(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + movl %ebx,92(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 275423344(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 36(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 88(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 32(%esp),%ebx + shrl $10,%edi + addl 68(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,32(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 430227734(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 40(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 92(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 36(%esp),%ebx + shrl $10,%edi + addl 72(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,36(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 506948616(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 44(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 32(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 40(%esp),%ebx + shrl $10,%edi + addl 76(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,40(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 659060556(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 48(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 36(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 44(%esp),%ebx + shrl $10,%edi + addl 80(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,44(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 883997877(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 52(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 40(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 48(%esp),%ebx + shrl $10,%edi + addl 84(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,48(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 958139571(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 56(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 44(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 52(%esp),%ebx + shrl $10,%edi + addl 88(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,52(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1322822218(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 60(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 48(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 56(%esp),%ebx + shrl $10,%edi + addl 92(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + movl %ebx,56(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1537002063(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 64(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 52(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 60(%esp),%ebx + shrl $10,%edi + addl 32(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + movl %ebx,60(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 1747873779(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 68(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 56(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 64(%esp),%ebx + shrl $10,%edi + addl 36(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 20(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 24(%esp),%edi + xorl %ecx,%edx + movl %ebx,64(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + addl 28(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 4(%esp),%edi + xorl %eax,%ecx + movl %eax,(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 1955562222(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 72(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 12(%esp),%edx + addl %ecx,%ebp + movl 60(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 68(%esp),%ebx + shrl $10,%edi + addl 40(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 16(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 20(%esp),%edi + xorl %esi,%edx + movl %ebx,68(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,12(%esp) + xorl %esi,%edx + addl 24(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl (%esp),%edi + xorl %ebp,%esi + movl %ebp,28(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2024104815(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 76(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 8(%esp),%edx + addl %esi,%eax + movl 64(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 72(%esp),%ebx + shrl $10,%edi + addl 44(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 12(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 16(%esp),%edi + xorl %ecx,%edx + movl %ebx,72(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + addl 20(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 28(%esp),%edi + xorl %eax,%ecx + movl %eax,24(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2227730452(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 80(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 4(%esp),%edx + addl %ecx,%ebp + movl 68(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 76(%esp),%ebx + shrl $10,%edi + addl 48(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 8(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 12(%esp),%edi + xorl %esi,%edx + movl %ebx,76(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,4(%esp) + xorl %esi,%edx + addl 16(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 24(%esp),%edi + xorl %ebp,%esi + movl %ebp,20(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2361852424(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 84(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl (%esp),%edx + addl %esi,%eax + movl 72(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 80(%esp),%ebx + shrl $10,%edi + addl 52(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 4(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl 8(%esp),%edi + xorl %ecx,%edx + movl %ebx,80(%esp) + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + addl 12(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 20(%esp),%edi + xorl %eax,%ecx + movl %eax,16(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 2428436474(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 88(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 28(%esp),%edx + addl %ecx,%ebp + movl 76(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 84(%esp),%ebx + shrl $10,%edi + addl 56(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl (%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 4(%esp),%edi + xorl %esi,%edx + movl %ebx,84(%esp) + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,28(%esp) + xorl %esi,%edx + addl 8(%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 16(%esp),%edi + xorl %ebp,%esi + movl %ebp,12(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 2756734187(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + movl 92(%esp),%ecx + rorl $2,%esi + addl %edx,%eax + addl 24(%esp),%edx + addl %esi,%eax + movl 80(%esp),%esi + movl %ecx,%ebx + rorl $11,%ecx + movl %esi,%edi + rorl $2,%esi + xorl %ebx,%ecx + shrl $3,%ebx + rorl $7,%ecx + xorl %edi,%esi + xorl %ecx,%ebx + rorl $17,%esi + addl 88(%esp),%ebx + shrl $10,%edi + addl 60(%esp),%ebx + movl %edx,%ecx + xorl %esi,%edi + movl 28(%esp),%esi + rorl $14,%edx + addl %edi,%ebx + movl (%esp),%edi + xorl %ecx,%edx + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + addl 4(%esp),%ebx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%ebx + rorl $9,%ecx + movl %eax,%esi + movl 12(%esp),%edi + xorl %eax,%ecx + movl %eax,8(%esp) + xorl %edi,%eax + rorl $11,%ecx + andl %eax,%ebp + leal 3204031479(%ebx,%edx,1),%edx + xorl %esi,%ecx + xorl %edi,%ebp + movl 32(%esp),%esi + rorl $2,%ecx + addl %edx,%ebp + addl 20(%esp),%edx + addl %ecx,%ebp + movl 84(%esp),%ecx + movl %esi,%ebx + rorl $11,%esi + movl %ecx,%edi + rorl $2,%ecx + xorl %ebx,%esi + shrl $3,%ebx + rorl $7,%esi + xorl %edi,%ecx + xorl %esi,%ebx + rorl $17,%ecx + addl 92(%esp),%ebx + shrl $10,%edi + addl 64(%esp),%ebx + movl %edx,%esi + xorl %ecx,%edi + movl 24(%esp),%ecx + rorl $14,%edx + addl %edi,%ebx + movl 28(%esp),%edi + xorl %esi,%edx + xorl %edi,%ecx + rorl $5,%edx + andl %esi,%ecx + movl %esi,20(%esp) + xorl %esi,%edx + addl (%esp),%ebx + xorl %ecx,%edi + rorl $6,%edx + movl %ebp,%esi + addl %edi,%ebx + rorl $9,%esi + movl %ebp,%ecx + movl 8(%esp),%edi + xorl %ebp,%esi + movl %ebp,4(%esp) + xorl %edi,%ebp + rorl $11,%esi + andl %ebp,%eax + leal 3329325298(%ebx,%edx,1),%edx + xorl %ecx,%esi + xorl %edi,%eax + rorl $2,%esi + addl %edx,%eax + addl 16(%esp),%edx + addl %esi,%eax + movl 96(%esp),%esi + xorl %edi,%ebp + movl 12(%esp),%ecx + addl (%esi),%eax + addl 4(%esi),%ebp + addl 8(%esi),%edi + addl 12(%esi),%ecx + movl %eax,(%esi) + movl %ebp,4(%esi) + movl %edi,8(%esi) + movl %ecx,12(%esi) + movl %ebp,4(%esp) + xorl %edi,%ebp + movl %edi,8(%esp) + movl %ecx,12(%esp) + movl 20(%esp),%edi + movl 24(%esp),%ebx + movl 28(%esp),%ecx + addl 16(%esi),%edx + addl 20(%esi),%edi + addl 24(%esi),%ebx + addl 28(%esi),%ecx + movl %edx,16(%esi) + movl %edi,20(%esi) + movl %ebx,24(%esi) + movl %ecx,28(%esi) + movl %edi,20(%esp) + movl 100(%esp),%edi + movl %ebx,24(%esp) + movl %ecx,28(%esp) + cmpl 104(%esp),%edi + jb .L010grand_loop + movl 108(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 32 +.L004shaext: + subl $32,%esp + movdqu (%esi),%xmm1 + leal 128(%ebp),%ebp + movdqu 16(%esi),%xmm2 + movdqa 128(%ebp),%xmm7 + pshufd $27,%xmm1,%xmm0 + pshufd $177,%xmm1,%xmm1 + pshufd $27,%xmm2,%xmm2 +.byte 102,15,58,15,202,8 + punpcklqdq %xmm0,%xmm2 + jmp .L011loop_shaext +.align 16 +.L011loop_shaext: + movdqu (%edi),%xmm3 + movdqu 16(%edi),%xmm4 + movdqu 32(%edi),%xmm5 +.byte 102,15,56,0,223 + movdqu 48(%edi),%xmm6 + movdqa %xmm2,16(%esp) + movdqa -128(%ebp),%xmm0 + paddd %xmm3,%xmm0 +.byte 102,15,56,0,231 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + nop + movdqa %xmm1,(%esp) +.byte 15,56,203,202 + movdqa -112(%ebp),%xmm0 + paddd %xmm4,%xmm0 +.byte 102,15,56,0,239 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + leal 64(%edi),%edi +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa -96(%ebp),%xmm0 + paddd %xmm5,%xmm0 +.byte 102,15,56,0,247 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa -80(%ebp),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa -64(%ebp),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa -48(%ebp),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa -32(%ebp),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa -16(%ebp),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa (%ebp),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 16(%ebp),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa 32(%ebp),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa 48(%ebp),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 64(%ebp),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 80(%ebp),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 +.byte 15,56,203,202 + paddd %xmm7,%xmm6 + movdqa 96(%ebp),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 +.byte 15,56,205,245 + movdqa 128(%ebp),%xmm7 +.byte 15,56,203,202 + movdqa 112(%ebp),%xmm0 + paddd %xmm6,%xmm0 + nop +.byte 15,56,203,209 + pshufd $14,%xmm0,%xmm0 + cmpl %edi,%eax + nop +.byte 15,56,203,202 + paddd 16(%esp),%xmm2 + paddd (%esp),%xmm1 + jnz .L011loop_shaext + pshufd $177,%xmm2,%xmm2 + pshufd $27,%xmm1,%xmm7 + pshufd $177,%xmm1,%xmm1 + punpckhqdq %xmm2,%xmm1 +.byte 102,15,58,15,215,8 + movl 44(%esp),%esp + movdqu %xmm1,(%esi) + movdqu %xmm2,16(%esi) + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 32 +.L006SSSE3: + leal -96(%esp),%esp + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edi + movl %ebx,4(%esp) + xorl %ecx,%ebx + movl %ecx,8(%esp) + movl %edi,12(%esp) + movl 16(%esi),%edx + movl 20(%esi),%edi + movl 24(%esi),%ecx + movl 28(%esi),%esi + movl %edi,20(%esp) + movl 100(%esp),%edi + movl %ecx,24(%esp) + movl %esi,28(%esp) + movdqa 256(%ebp),%xmm7 + jmp .L012grand_ssse3 +.align 16 +.L012grand_ssse3: + movdqu (%edi),%xmm0 + movdqu 16(%edi),%xmm1 + movdqu 32(%edi),%xmm2 + movdqu 48(%edi),%xmm3 + addl $64,%edi +.byte 102,15,56,0,199 + movl %edi,100(%esp) +.byte 102,15,56,0,207 + movdqa (%ebp),%xmm4 +.byte 102,15,56,0,215 + movdqa 16(%ebp),%xmm5 + paddd %xmm0,%xmm4 +.byte 102,15,56,0,223 + movdqa 32(%ebp),%xmm6 + paddd %xmm1,%xmm5 + movdqa 48(%ebp),%xmm7 + movdqa %xmm4,32(%esp) + paddd %xmm2,%xmm6 + movdqa %xmm5,48(%esp) + paddd %xmm3,%xmm7 + movdqa %xmm6,64(%esp) + movdqa %xmm7,80(%esp) + jmp .L013ssse3_00_47 +.align 16 +.L013ssse3_00_47: + addl $64,%ebp + movl %edx,%ecx + movdqa %xmm1,%xmm4 + rorl $14,%edx + movl 20(%esp),%esi + movdqa %xmm3,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi +.byte 102,15,58,15,224,4 + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi +.byte 102,15,58,15,250,4 + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + movdqa %xmm4,%xmm5 + rorl $6,%edx + movl %eax,%ecx + movdqa %xmm4,%xmm6 + addl %edi,%edx + movl 4(%esp),%edi + psrld $3,%xmm4 + movl %eax,%esi + rorl $9,%ecx + paddd %xmm7,%xmm0 + movl %eax,(%esp) + xorl %eax,%ecx + psrld $7,%xmm6 + xorl %edi,%eax + addl 28(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + pshufd $250,%xmm3,%xmm7 + xorl %esi,%ecx + addl 32(%esp),%edx + pslld $14,%xmm5 + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + psrld $11,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm5,%xmm4 + movl 16(%esp),%esi + xorl %ecx,%edx + pslld $11,%xmm5 + movl 20(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + pxor %xmm6,%xmm4 + andl %ecx,%esi + movl %ecx,12(%esp) + movdqa %xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + pxor %xmm5,%xmm4 + movl %ebx,%ecx + addl %edi,%edx + psrld $10,%xmm7 + movl (%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm4,%xmm0 + movl %ebx,28(%esp) + xorl %ebx,%ecx + psrlq $17,%xmm6 + xorl %edi,%ebx + addl 24(%esp),%edx + rorl $11,%ecx + pxor %xmm6,%xmm7 + andl %ebx,%eax + xorl %esi,%ecx + psrlq $2,%xmm6 + addl 36(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + pshufd $128,%xmm7,%xmm7 + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + psrldq $8,%xmm7 + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + paddd %xmm7,%xmm0 + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,24(%esp) + pshufd $80,%xmm0,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + movdqa %xmm7,%xmm6 + rorl $11,%ecx + psrld $10,%xmm7 + andl %eax,%ebx + psrlq $17,%xmm6 + xorl %esi,%ecx + addl 40(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + psrlq $2,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm6,%xmm7 + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + pshufd $8,%xmm7,%xmm7 + xorl %edi,%esi + rorl $5,%edx + movdqa (%ebp),%xmm6 + andl %ecx,%esi + movl %ecx,4(%esp) + pslldq $8,%xmm7 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm7,%xmm0 + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + paddd %xmm0,%xmm6 + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movdqa %xmm6,32(%esp) + movl %edx,%ecx + movdqa %xmm2,%xmm4 + rorl $14,%edx + movl 4(%esp),%esi + movdqa %xmm0,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi +.byte 102,15,58,15,225,4 + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi +.byte 102,15,58,15,251,4 + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + movdqa %xmm4,%xmm5 + rorl $6,%edx + movl %eax,%ecx + movdqa %xmm4,%xmm6 + addl %edi,%edx + movl 20(%esp),%edi + psrld $3,%xmm4 + movl %eax,%esi + rorl $9,%ecx + paddd %xmm7,%xmm1 + movl %eax,16(%esp) + xorl %eax,%ecx + psrld $7,%xmm6 + xorl %edi,%eax + addl 12(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + pshufd $250,%xmm0,%xmm7 + xorl %esi,%ecx + addl 48(%esp),%edx + pslld $14,%xmm5 + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + psrld $11,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm5,%xmm4 + movl (%esp),%esi + xorl %ecx,%edx + pslld $11,%xmm5 + movl 4(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + pxor %xmm6,%xmm4 + andl %ecx,%esi + movl %ecx,28(%esp) + movdqa %xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + pxor %xmm5,%xmm4 + movl %ebx,%ecx + addl %edi,%edx + psrld $10,%xmm7 + movl 16(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm4,%xmm1 + movl %ebx,12(%esp) + xorl %ebx,%ecx + psrlq $17,%xmm6 + xorl %edi,%ebx + addl 8(%esp),%edx + rorl $11,%ecx + pxor %xmm6,%xmm7 + andl %ebx,%eax + xorl %esi,%ecx + psrlq $2,%xmm6 + addl 52(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + pshufd $128,%xmm7,%xmm7 + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + psrldq $8,%xmm7 + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + paddd %xmm7,%xmm1 + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,8(%esp) + pshufd $80,%xmm1,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + movdqa %xmm7,%xmm6 + rorl $11,%ecx + psrld $10,%xmm7 + andl %eax,%ebx + psrlq $17,%xmm6 + xorl %esi,%ecx + addl 56(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + psrlq $2,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm6,%xmm7 + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + pshufd $8,%xmm7,%xmm7 + xorl %edi,%esi + rorl $5,%edx + movdqa 16(%ebp),%xmm6 + andl %ecx,%esi + movl %ecx,20(%esp) + pslldq $8,%xmm7 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm7,%xmm1 + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + paddd %xmm1,%xmm6 + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movdqa %xmm6,48(%esp) + movl %edx,%ecx + movdqa %xmm3,%xmm4 + rorl $14,%edx + movl 20(%esp),%esi + movdqa %xmm1,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi +.byte 102,15,58,15,226,4 + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi +.byte 102,15,58,15,248,4 + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + movdqa %xmm4,%xmm5 + rorl $6,%edx + movl %eax,%ecx + movdqa %xmm4,%xmm6 + addl %edi,%edx + movl 4(%esp),%edi + psrld $3,%xmm4 + movl %eax,%esi + rorl $9,%ecx + paddd %xmm7,%xmm2 + movl %eax,(%esp) + xorl %eax,%ecx + psrld $7,%xmm6 + xorl %edi,%eax + addl 28(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + pshufd $250,%xmm1,%xmm7 + xorl %esi,%ecx + addl 64(%esp),%edx + pslld $14,%xmm5 + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + psrld $11,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm5,%xmm4 + movl 16(%esp),%esi + xorl %ecx,%edx + pslld $11,%xmm5 + movl 20(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + pxor %xmm6,%xmm4 + andl %ecx,%esi + movl %ecx,12(%esp) + movdqa %xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + pxor %xmm5,%xmm4 + movl %ebx,%ecx + addl %edi,%edx + psrld $10,%xmm7 + movl (%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm4,%xmm2 + movl %ebx,28(%esp) + xorl %ebx,%ecx + psrlq $17,%xmm6 + xorl %edi,%ebx + addl 24(%esp),%edx + rorl $11,%ecx + pxor %xmm6,%xmm7 + andl %ebx,%eax + xorl %esi,%ecx + psrlq $2,%xmm6 + addl 68(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + pshufd $128,%xmm7,%xmm7 + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + psrldq $8,%xmm7 + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + paddd %xmm7,%xmm2 + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,24(%esp) + pshufd $80,%xmm2,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + movdqa %xmm7,%xmm6 + rorl $11,%ecx + psrld $10,%xmm7 + andl %eax,%ebx + psrlq $17,%xmm6 + xorl %esi,%ecx + addl 72(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + psrlq $2,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm6,%xmm7 + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + pshufd $8,%xmm7,%xmm7 + xorl %edi,%esi + rorl $5,%edx + movdqa 32(%ebp),%xmm6 + andl %ecx,%esi + movl %ecx,4(%esp) + pslldq $8,%xmm7 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm7,%xmm2 + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + paddd %xmm2,%xmm6 + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movdqa %xmm6,64(%esp) + movl %edx,%ecx + movdqa %xmm0,%xmm4 + rorl $14,%edx + movl 4(%esp),%esi + movdqa %xmm2,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi +.byte 102,15,58,15,227,4 + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi +.byte 102,15,58,15,249,4 + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + movdqa %xmm4,%xmm5 + rorl $6,%edx + movl %eax,%ecx + movdqa %xmm4,%xmm6 + addl %edi,%edx + movl 20(%esp),%edi + psrld $3,%xmm4 + movl %eax,%esi + rorl $9,%ecx + paddd %xmm7,%xmm3 + movl %eax,16(%esp) + xorl %eax,%ecx + psrld $7,%xmm6 + xorl %edi,%eax + addl 12(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + pshufd $250,%xmm2,%xmm7 + xorl %esi,%ecx + addl 80(%esp),%edx + pslld $14,%xmm5 + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + psrld $11,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm5,%xmm4 + movl (%esp),%esi + xorl %ecx,%edx + pslld $11,%xmm5 + movl 4(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + pxor %xmm6,%xmm4 + andl %ecx,%esi + movl %ecx,28(%esp) + movdqa %xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + pxor %xmm5,%xmm4 + movl %ebx,%ecx + addl %edi,%edx + psrld $10,%xmm7 + movl 16(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm4,%xmm3 + movl %ebx,12(%esp) + xorl %ebx,%ecx + psrlq $17,%xmm6 + xorl %edi,%ebx + addl 8(%esp),%edx + rorl $11,%ecx + pxor %xmm6,%xmm7 + andl %ebx,%eax + xorl %esi,%ecx + psrlq $2,%xmm6 + addl 84(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + pshufd $128,%xmm7,%xmm7 + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + psrldq $8,%xmm7 + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + paddd %xmm7,%xmm3 + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,8(%esp) + pshufd $80,%xmm3,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + movdqa %xmm7,%xmm6 + rorl $11,%ecx + psrld $10,%xmm7 + andl %eax,%ebx + psrlq $17,%xmm6 + xorl %esi,%ecx + addl 88(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + pxor %xmm6,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + psrlq $2,%xmm6 + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + pxor %xmm6,%xmm7 + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + pshufd $8,%xmm7,%xmm7 + xorl %edi,%esi + rorl $5,%edx + movdqa 48(%ebp),%xmm6 + andl %ecx,%esi + movl %ecx,20(%esp) + pslldq $8,%xmm7 + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + paddd %xmm7,%xmm3 + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + paddd %xmm3,%xmm6 + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movdqa %xmm6,80(%esp) + cmpl $66051,64(%ebp) + jne .L013ssse3_00_47 + movl %edx,%ecx + rorl $14,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 32(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 36(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 40(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 48(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 52(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 56(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 64(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 68(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 72(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 80(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 84(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + rorl $14,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + rorl $9,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + rorl $11,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 88(%esp),%edx + xorl %edi,%ebx + rorl $2,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + rorl $14,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + rorl $5,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + rorl $6,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + rorl $9,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + rorl $11,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + rorl $2,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl 96(%esp),%esi + xorl %edi,%ebx + movl 12(%esp),%ecx + addl (%esi),%eax + addl 4(%esi),%ebx + addl 8(%esi),%edi + addl 12(%esi),%ecx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %edi,8(%esi) + movl %ecx,12(%esi) + movl %ebx,4(%esp) + xorl %edi,%ebx + movl %edi,8(%esp) + movl %ecx,12(%esp) + movl 20(%esp),%edi + movl 24(%esp),%ecx + addl 16(%esi),%edx + addl 20(%esi),%edi + addl 24(%esi),%ecx + movl %edx,16(%esi) + movl %edi,20(%esi) + movl %edi,20(%esp) + movl 28(%esp),%edi + movl %ecx,24(%esi) + addl 28(%esi),%edi + movl %ecx,24(%esp) + movl %edi,28(%esi) + movl %edi,28(%esp) + movl 100(%esp),%edi + movdqa 64(%ebp),%xmm7 + subl $192,%ebp + cmpl 104(%esp),%edi + jb .L012grand_ssse3 + movl 108(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 32 +.L005AVX: + andl $264,%edx + cmpl $264,%edx + je .L014AVX_BMI + leal -96(%esp),%esp + vzeroall + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edi + movl %ebx,4(%esp) + xorl %ecx,%ebx + movl %ecx,8(%esp) + movl %edi,12(%esp) + movl 16(%esi),%edx + movl 20(%esi),%edi + movl 24(%esi),%ecx + movl 28(%esi),%esi + movl %edi,20(%esp) + movl 100(%esp),%edi + movl %ecx,24(%esp) + movl %esi,28(%esp) + vmovdqa 256(%ebp),%xmm7 + jmp .L015grand_avx +.align 32 +.L015grand_avx: + vmovdqu (%edi),%xmm0 + vmovdqu 16(%edi),%xmm1 + vmovdqu 32(%edi),%xmm2 + vmovdqu 48(%edi),%xmm3 + addl $64,%edi + vpshufb %xmm7,%xmm0,%xmm0 + movl %edi,100(%esp) + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd (%ebp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 16(%ebp),%xmm1,%xmm5 + vpaddd 32(%ebp),%xmm2,%xmm6 + vpaddd 48(%ebp),%xmm3,%xmm7 + vmovdqa %xmm4,32(%esp) + vmovdqa %xmm5,48(%esp) + vmovdqa %xmm6,64(%esp) + vmovdqa %xmm7,80(%esp) + jmp .L016avx_00_47 +.align 16 +.L016avx_00_47: + addl $64,%ebp + vpalignr $4,%xmm0,%xmm1,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + vpalignr $4,%xmm2,%xmm3,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + vpaddd %xmm7,%xmm0,%xmm0 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + vpshufd $250,%xmm3,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 32(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + vpaddd %xmm4,%xmm0,%xmm0 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 36(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + vpaddd %xmm7,%xmm0,%xmm0 + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm0,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 40(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm0,%xmm0 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + vpaddd (%ebp),%xmm0,%xmm6 + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,32(%esp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + vpalignr $4,%xmm3,%xmm0,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + vpaddd %xmm7,%xmm1,%xmm1 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + vpshufd $250,%xmm0,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 48(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + vpaddd %xmm4,%xmm1,%xmm1 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 52(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + vpaddd %xmm7,%xmm1,%xmm1 + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm1,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 56(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm1,%xmm1 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + vpaddd 16(%ebp),%xmm1,%xmm6 + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,48(%esp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + vpalignr $4,%xmm0,%xmm1,%xmm7 + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + vpaddd %xmm7,%xmm2,%xmm2 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + vpshufd $250,%xmm1,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 64(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + vpaddd %xmm4,%xmm2,%xmm2 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 68(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + vpaddd %xmm7,%xmm2,%xmm2 + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm2,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 72(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm2,%xmm2 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + vpaddd 32(%ebp),%xmm2,%xmm6 + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,64(%esp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + vpalignr $4,%xmm1,%xmm2,%xmm7 + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + vpaddd %xmm7,%xmm3,%xmm3 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrld $3,%xmm4,%xmm7 + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + vpslld $14,%xmm4,%xmm5 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + vpshufd $250,%xmm2,%xmm7 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpsrld $11,%xmm6,%xmm6 + addl 80(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpxor %xmm5,%xmm4,%xmm4 + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + vpslld $11,%xmm5,%xmm5 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + vpxor %xmm6,%xmm4,%xmm4 + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + vpsrld $10,%xmm7,%xmm6 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + vpxor %xmm5,%xmm4,%xmm4 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + vpaddd %xmm4,%xmm3,%xmm3 + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + vpxor %xmm5,%xmm6,%xmm6 + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + vpsrlq $19,%xmm7,%xmm7 + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + addl 84(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + vpshufd $132,%xmm6,%xmm7 + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + vpsrldq $8,%xmm7,%xmm7 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + vpaddd %xmm7,%xmm3,%xmm3 + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + vpshufd $80,%xmm3,%xmm7 + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + vpsrld $10,%xmm7,%xmm6 + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + vpsrlq $17,%xmm7,%xmm5 + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + vpxor %xmm5,%xmm6,%xmm6 + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + vpsrlq $19,%xmm7,%xmm7 + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + vpshufd $232,%xmm6,%xmm7 + addl 88(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + vpslldq $8,%xmm7,%xmm7 + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + vpaddd %xmm7,%xmm3,%xmm3 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + vpaddd 48(%ebp),%xmm3,%xmm6 + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + vmovdqa %xmm6,80(%esp) + cmpl $66051,64(%ebp) + jne .L016avx_00_47 + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 32(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 36(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 40(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 44(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 48(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 52(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 56(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 60(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 20(%esp),%esi + xorl %ecx,%edx + movl 24(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,16(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 4(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 64(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 12(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 16(%esp),%esi + xorl %ecx,%edx + movl 20(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,12(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl (%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,28(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 68(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 8(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 12(%esp),%esi + xorl %ecx,%edx + movl 16(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,8(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 28(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,24(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 72(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 4(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 8(%esp),%esi + xorl %ecx,%edx + movl 12(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,4(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 24(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,20(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 76(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl (%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 4(%esp),%esi + xorl %ecx,%edx + movl 8(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 20(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,16(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 80(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 28(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl (%esp),%esi + xorl %ecx,%edx + movl 4(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,28(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 16(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,12(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 84(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 24(%esp),%edx + addl %ecx,%eax + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 28(%esp),%esi + xorl %ecx,%edx + movl (%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,24(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %eax,%ecx + addl %edi,%edx + movl 12(%esp),%edi + movl %eax,%esi + shrdl $9,%ecx,%ecx + movl %eax,8(%esp) + xorl %eax,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + shrdl $11,%ecx,%ecx + andl %eax,%ebx + xorl %esi,%ecx + addl 88(%esp),%edx + xorl %edi,%ebx + shrdl $2,%ecx,%ecx + addl %edx,%ebx + addl 20(%esp),%edx + addl %ecx,%ebx + movl %edx,%ecx + shrdl $14,%edx,%edx + movl 24(%esp),%esi + xorl %ecx,%edx + movl 28(%esp),%edi + xorl %edi,%esi + shrdl $5,%edx,%edx + andl %ecx,%esi + movl %ecx,20(%esp) + xorl %ecx,%edx + xorl %esi,%edi + shrdl $6,%edx,%edx + movl %ebx,%ecx + addl %edi,%edx + movl 8(%esp),%edi + movl %ebx,%esi + shrdl $9,%ecx,%ecx + movl %ebx,4(%esp) + xorl %ebx,%ecx + xorl %edi,%ebx + addl (%esp),%edx + shrdl $11,%ecx,%ecx + andl %ebx,%eax + xorl %esi,%ecx + addl 92(%esp),%edx + xorl %edi,%eax + shrdl $2,%ecx,%ecx + addl %edx,%eax + addl 16(%esp),%edx + addl %ecx,%eax + movl 96(%esp),%esi + xorl %edi,%ebx + movl 12(%esp),%ecx + addl (%esi),%eax + addl 4(%esi),%ebx + addl 8(%esi),%edi + addl 12(%esi),%ecx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %edi,8(%esi) + movl %ecx,12(%esi) + movl %ebx,4(%esp) + xorl %edi,%ebx + movl %edi,8(%esp) + movl %ecx,12(%esp) + movl 20(%esp),%edi + movl 24(%esp),%ecx + addl 16(%esi),%edx + addl 20(%esi),%edi + addl 24(%esi),%ecx + movl %edx,16(%esi) + movl %edi,20(%esi) + movl %edi,20(%esp) + movl 28(%esp),%edi + movl %ecx,24(%esi) + addl 28(%esi),%edi + movl %ecx,24(%esp) + movl %edi,28(%esi) + movl %edi,28(%esp) + movl 100(%esp),%edi + vmovdqa 64(%ebp),%xmm7 + subl $192,%ebp + cmpl 104(%esp),%edi + jb .L015grand_avx + movl 108(%esp),%esp + vzeroall + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 32 +.L014AVX_BMI: + leal -96(%esp),%esp + vzeroall + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edi + movl %ebx,4(%esp) + xorl %ecx,%ebx + movl %ecx,8(%esp) + movl %edi,12(%esp) + movl 16(%esi),%edx + movl 20(%esi),%edi + movl 24(%esi),%ecx + movl 28(%esi),%esi + movl %edi,20(%esp) + movl 100(%esp),%edi + movl %ecx,24(%esp) + movl %esi,28(%esp) + vmovdqa 256(%ebp),%xmm7 + jmp .L017grand_avx_bmi +.align 32 +.L017grand_avx_bmi: + vmovdqu (%edi),%xmm0 + vmovdqu 16(%edi),%xmm1 + vmovdqu 32(%edi),%xmm2 + vmovdqu 48(%edi),%xmm3 + addl $64,%edi + vpshufb %xmm7,%xmm0,%xmm0 + movl %edi,100(%esp) + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd (%ebp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 16(%ebp),%xmm1,%xmm5 + vpaddd 32(%ebp),%xmm2,%xmm6 + vpaddd 48(%ebp),%xmm3,%xmm7 + vmovdqa %xmm4,32(%esp) + vmovdqa %xmm5,48(%esp) + vmovdqa %xmm6,64(%esp) + vmovdqa %xmm7,80(%esp) + jmp .L018avx_bmi_00_47 +.align 16 +.L018avx_bmi_00_47: + addl $64,%ebp + vpalignr $4,%xmm0,%xmm1,%xmm4 + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,16(%esp) + vpalignr $4,%xmm2,%xmm3,%xmm7 + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 24(%esp),%edx,%esi + vpsrld $7,%xmm4,%xmm6 + xorl %edi,%ecx + andl 20(%esp),%edx + movl %eax,(%esp) + vpaddd %xmm7,%xmm0,%xmm0 + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + vpsrld $3,%xmm4,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + vpslld $14,%xmm4,%xmm5 + movl 4(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + vpxor %xmm6,%xmm7,%xmm4 + addl 28(%esp),%edx + andl %eax,%ebx + addl 32(%esp),%edx + vpshufd $250,%xmm3,%xmm7 + xorl %edi,%ebx + addl %edx,%ecx + addl 12(%esp),%edx + vpsrld $11,%xmm6,%xmm6 + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpxor %xmm5,%xmm4,%xmm4 + movl %edx,12(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpslld $11,%xmm5,%xmm5 + andnl 20(%esp),%edx,%esi + xorl %edi,%ecx + andl 16(%esp),%edx + vpxor %xmm6,%xmm4,%xmm4 + movl %ebx,28(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + vpsrld $10,%xmm7,%xmm6 + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + vpxor %xmm5,%xmm4,%xmm4 + movl (%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + vpsrlq $17,%xmm7,%xmm5 + addl 24(%esp),%edx + andl %ebx,%eax + addl 36(%esp),%edx + vpaddd %xmm4,%xmm0,%xmm0 + xorl %edi,%eax + addl %edx,%ecx + addl 8(%esp),%edx + vpxor %xmm5,%xmm6,%xmm6 + leal (%eax,%ecx,1),%eax + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpsrlq $19,%xmm7,%xmm7 + movl %edx,8(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + andnl 16(%esp),%edx,%esi + xorl %edi,%ecx + andl 12(%esp),%edx + vpshufd $132,%xmm6,%xmm7 + movl %eax,24(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + vpsrldq $8,%xmm7,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + vpaddd %xmm7,%xmm0,%xmm0 + movl 28(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + vpshufd $80,%xmm0,%xmm7 + addl 20(%esp),%edx + andl %eax,%ebx + addl 40(%esp),%edx + vpsrld $10,%xmm7,%xmm6 + xorl %edi,%ebx + addl %edx,%ecx + addl 4(%esp),%edx + vpsrlq $17,%xmm7,%xmm5 + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpxor %xmm5,%xmm6,%xmm6 + movl %edx,4(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpsrlq $19,%xmm7,%xmm7 + andnl 12(%esp),%edx,%esi + xorl %edi,%ecx + andl 8(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + movl %ebx,20(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + vpshufd $232,%xmm6,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + vpslldq $8,%xmm7,%xmm7 + movl 24(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + vpaddd %xmm7,%xmm0,%xmm0 + addl 16(%esp),%edx + andl %ebx,%eax + addl 44(%esp),%edx + vpaddd (%ebp),%xmm0,%xmm6 + xorl %edi,%eax + addl %edx,%ecx + addl (%esp),%edx + leal (%eax,%ecx,1),%eax + vmovdqa %xmm6,32(%esp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,(%esp) + vpalignr $4,%xmm3,%xmm0,%xmm7 + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 8(%esp),%edx,%esi + vpsrld $7,%xmm4,%xmm6 + xorl %edi,%ecx + andl 4(%esp),%edx + movl %eax,16(%esp) + vpaddd %xmm7,%xmm1,%xmm1 + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + vpsrld $3,%xmm4,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + vpslld $14,%xmm4,%xmm5 + movl 20(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + vpxor %xmm6,%xmm7,%xmm4 + addl 12(%esp),%edx + andl %eax,%ebx + addl 48(%esp),%edx + vpshufd $250,%xmm0,%xmm7 + xorl %edi,%ebx + addl %edx,%ecx + addl 28(%esp),%edx + vpsrld $11,%xmm6,%xmm6 + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpxor %xmm5,%xmm4,%xmm4 + movl %edx,28(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpslld $11,%xmm5,%xmm5 + andnl 4(%esp),%edx,%esi + xorl %edi,%ecx + andl (%esp),%edx + vpxor %xmm6,%xmm4,%xmm4 + movl %ebx,12(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + vpsrld $10,%xmm7,%xmm6 + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + vpxor %xmm5,%xmm4,%xmm4 + movl 16(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + vpsrlq $17,%xmm7,%xmm5 + addl 8(%esp),%edx + andl %ebx,%eax + addl 52(%esp),%edx + vpaddd %xmm4,%xmm1,%xmm1 + xorl %edi,%eax + addl %edx,%ecx + addl 24(%esp),%edx + vpxor %xmm5,%xmm6,%xmm6 + leal (%eax,%ecx,1),%eax + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpsrlq $19,%xmm7,%xmm7 + movl %edx,24(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + andnl (%esp),%edx,%esi + xorl %edi,%ecx + andl 28(%esp),%edx + vpshufd $132,%xmm6,%xmm7 + movl %eax,8(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + vpsrldq $8,%xmm7,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + vpaddd %xmm7,%xmm1,%xmm1 + movl 12(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + vpshufd $80,%xmm1,%xmm7 + addl 4(%esp),%edx + andl %eax,%ebx + addl 56(%esp),%edx + vpsrld $10,%xmm7,%xmm6 + xorl %edi,%ebx + addl %edx,%ecx + addl 20(%esp),%edx + vpsrlq $17,%xmm7,%xmm5 + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpxor %xmm5,%xmm6,%xmm6 + movl %edx,20(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpsrlq $19,%xmm7,%xmm7 + andnl 28(%esp),%edx,%esi + xorl %edi,%ecx + andl 24(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + movl %ebx,4(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + vpshufd $232,%xmm6,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + vpslldq $8,%xmm7,%xmm7 + movl 8(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + vpaddd %xmm7,%xmm1,%xmm1 + addl (%esp),%edx + andl %ebx,%eax + addl 60(%esp),%edx + vpaddd 16(%ebp),%xmm1,%xmm6 + xorl %edi,%eax + addl %edx,%ecx + addl 16(%esp),%edx + leal (%eax,%ecx,1),%eax + vmovdqa %xmm6,48(%esp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,16(%esp) + vpalignr $4,%xmm0,%xmm1,%xmm7 + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 24(%esp),%edx,%esi + vpsrld $7,%xmm4,%xmm6 + xorl %edi,%ecx + andl 20(%esp),%edx + movl %eax,(%esp) + vpaddd %xmm7,%xmm2,%xmm2 + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + vpsrld $3,%xmm4,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + vpslld $14,%xmm4,%xmm5 + movl 4(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + vpxor %xmm6,%xmm7,%xmm4 + addl 28(%esp),%edx + andl %eax,%ebx + addl 64(%esp),%edx + vpshufd $250,%xmm1,%xmm7 + xorl %edi,%ebx + addl %edx,%ecx + addl 12(%esp),%edx + vpsrld $11,%xmm6,%xmm6 + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpxor %xmm5,%xmm4,%xmm4 + movl %edx,12(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpslld $11,%xmm5,%xmm5 + andnl 20(%esp),%edx,%esi + xorl %edi,%ecx + andl 16(%esp),%edx + vpxor %xmm6,%xmm4,%xmm4 + movl %ebx,28(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + vpsrld $10,%xmm7,%xmm6 + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + vpxor %xmm5,%xmm4,%xmm4 + movl (%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + vpsrlq $17,%xmm7,%xmm5 + addl 24(%esp),%edx + andl %ebx,%eax + addl 68(%esp),%edx + vpaddd %xmm4,%xmm2,%xmm2 + xorl %edi,%eax + addl %edx,%ecx + addl 8(%esp),%edx + vpxor %xmm5,%xmm6,%xmm6 + leal (%eax,%ecx,1),%eax + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpsrlq $19,%xmm7,%xmm7 + movl %edx,8(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + andnl 16(%esp),%edx,%esi + xorl %edi,%ecx + andl 12(%esp),%edx + vpshufd $132,%xmm6,%xmm7 + movl %eax,24(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + vpsrldq $8,%xmm7,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + vpaddd %xmm7,%xmm2,%xmm2 + movl 28(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + vpshufd $80,%xmm2,%xmm7 + addl 20(%esp),%edx + andl %eax,%ebx + addl 72(%esp),%edx + vpsrld $10,%xmm7,%xmm6 + xorl %edi,%ebx + addl %edx,%ecx + addl 4(%esp),%edx + vpsrlq $17,%xmm7,%xmm5 + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpxor %xmm5,%xmm6,%xmm6 + movl %edx,4(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpsrlq $19,%xmm7,%xmm7 + andnl 12(%esp),%edx,%esi + xorl %edi,%ecx + andl 8(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + movl %ebx,20(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + vpshufd $232,%xmm6,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + vpslldq $8,%xmm7,%xmm7 + movl 24(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + vpaddd %xmm7,%xmm2,%xmm2 + addl 16(%esp),%edx + andl %ebx,%eax + addl 76(%esp),%edx + vpaddd 32(%ebp),%xmm2,%xmm6 + xorl %edi,%eax + addl %edx,%ecx + addl (%esp),%edx + leal (%eax,%ecx,1),%eax + vmovdqa %xmm6,64(%esp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,(%esp) + vpalignr $4,%xmm1,%xmm2,%xmm7 + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 8(%esp),%edx,%esi + vpsrld $7,%xmm4,%xmm6 + xorl %edi,%ecx + andl 4(%esp),%edx + movl %eax,16(%esp) + vpaddd %xmm7,%xmm3,%xmm3 + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + vpsrld $3,%xmm4,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + vpslld $14,%xmm4,%xmm5 + movl 20(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + vpxor %xmm6,%xmm7,%xmm4 + addl 12(%esp),%edx + andl %eax,%ebx + addl 80(%esp),%edx + vpshufd $250,%xmm2,%xmm7 + xorl %edi,%ebx + addl %edx,%ecx + addl 28(%esp),%edx + vpsrld $11,%xmm6,%xmm6 + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpxor %xmm5,%xmm4,%xmm4 + movl %edx,28(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpslld $11,%xmm5,%xmm5 + andnl 4(%esp),%edx,%esi + xorl %edi,%ecx + andl (%esp),%edx + vpxor %xmm6,%xmm4,%xmm4 + movl %ebx,12(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + vpsrld $10,%xmm7,%xmm6 + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + vpxor %xmm5,%xmm4,%xmm4 + movl 16(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + vpsrlq $17,%xmm7,%xmm5 + addl 8(%esp),%edx + andl %ebx,%eax + addl 84(%esp),%edx + vpaddd %xmm4,%xmm3,%xmm3 + xorl %edi,%eax + addl %edx,%ecx + addl 24(%esp),%edx + vpxor %xmm5,%xmm6,%xmm6 + leal (%eax,%ecx,1),%eax + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpsrlq $19,%xmm7,%xmm7 + movl %edx,24(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpxor %xmm7,%xmm6,%xmm6 + andnl (%esp),%edx,%esi + xorl %edi,%ecx + andl 28(%esp),%edx + vpshufd $132,%xmm6,%xmm7 + movl %eax,8(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + vpsrldq $8,%xmm7,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + vpaddd %xmm7,%xmm3,%xmm3 + movl 12(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + vpshufd $80,%xmm3,%xmm7 + addl 4(%esp),%edx + andl %eax,%ebx + addl 88(%esp),%edx + vpsrld $10,%xmm7,%xmm6 + xorl %edi,%ebx + addl %edx,%ecx + addl 20(%esp),%edx + vpsrlq $17,%xmm7,%xmm5 + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + vpxor %xmm5,%xmm6,%xmm6 + movl %edx,20(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + vpsrlq $19,%xmm7,%xmm7 + andnl 28(%esp),%edx,%esi + xorl %edi,%ecx + andl 24(%esp),%edx + vpxor %xmm7,%xmm6,%xmm6 + movl %ebx,4(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + vpshufd $232,%xmm6,%xmm7 + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + vpslldq $8,%xmm7,%xmm7 + movl 8(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + vpaddd %xmm7,%xmm3,%xmm3 + addl (%esp),%edx + andl %ebx,%eax + addl 92(%esp),%edx + vpaddd 48(%ebp),%xmm3,%xmm6 + xorl %edi,%eax + addl %edx,%ecx + addl 16(%esp),%edx + leal (%eax,%ecx,1),%eax + vmovdqa %xmm6,80(%esp) + cmpl $66051,64(%ebp) + jne .L018avx_bmi_00_47 + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,16(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 24(%esp),%edx,%esi + xorl %edi,%ecx + andl 20(%esp),%edx + movl %eax,(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + movl 4(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + andl %eax,%ebx + addl 32(%esp),%edx + xorl %edi,%ebx + addl %edx,%ecx + addl 12(%esp),%edx + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,12(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 20(%esp),%edx,%esi + xorl %edi,%ecx + andl 16(%esp),%edx + movl %ebx,28(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + movl (%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + andl %ebx,%eax + addl 36(%esp),%edx + xorl %edi,%eax + addl %edx,%ecx + addl 8(%esp),%edx + leal (%eax,%ecx,1),%eax + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,8(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 16(%esp),%edx,%esi + xorl %edi,%ecx + andl 12(%esp),%edx + movl %eax,24(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + movl 28(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + andl %eax,%ebx + addl 40(%esp),%edx + xorl %edi,%ebx + addl %edx,%ecx + addl 4(%esp),%edx + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,4(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 12(%esp),%edx,%esi + xorl %edi,%ecx + andl 8(%esp),%edx + movl %ebx,20(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + movl 24(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + andl %ebx,%eax + addl 44(%esp),%edx + xorl %edi,%eax + addl %edx,%ecx + addl (%esp),%edx + leal (%eax,%ecx,1),%eax + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 8(%esp),%edx,%esi + xorl %edi,%ecx + andl 4(%esp),%edx + movl %eax,16(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + movl 20(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + andl %eax,%ebx + addl 48(%esp),%edx + xorl %edi,%ebx + addl %edx,%ecx + addl 28(%esp),%edx + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,28(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 4(%esp),%edx,%esi + xorl %edi,%ecx + andl (%esp),%edx + movl %ebx,12(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + movl 16(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + andl %ebx,%eax + addl 52(%esp),%edx + xorl %edi,%eax + addl %edx,%ecx + addl 24(%esp),%edx + leal (%eax,%ecx,1),%eax + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,24(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl (%esp),%edx,%esi + xorl %edi,%ecx + andl 28(%esp),%edx + movl %eax,8(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + movl 12(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + andl %eax,%ebx + addl 56(%esp),%edx + xorl %edi,%ebx + addl %edx,%ecx + addl 20(%esp),%edx + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,20(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 28(%esp),%edx,%esi + xorl %edi,%ecx + andl 24(%esp),%edx + movl %ebx,4(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + movl 8(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + addl (%esp),%edx + andl %ebx,%eax + addl 60(%esp),%edx + xorl %edi,%eax + addl %edx,%ecx + addl 16(%esp),%edx + leal (%eax,%ecx,1),%eax + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,16(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 24(%esp),%edx,%esi + xorl %edi,%ecx + andl 20(%esp),%edx + movl %eax,(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + movl 4(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + addl 28(%esp),%edx + andl %eax,%ebx + addl 64(%esp),%edx + xorl %edi,%ebx + addl %edx,%ecx + addl 12(%esp),%edx + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,12(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 20(%esp),%edx,%esi + xorl %edi,%ecx + andl 16(%esp),%edx + movl %ebx,28(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + movl (%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + addl 24(%esp),%edx + andl %ebx,%eax + addl 68(%esp),%edx + xorl %edi,%eax + addl %edx,%ecx + addl 8(%esp),%edx + leal (%eax,%ecx,1),%eax + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,8(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 16(%esp),%edx,%esi + xorl %edi,%ecx + andl 12(%esp),%edx + movl %eax,24(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + movl 28(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + addl 20(%esp),%edx + andl %eax,%ebx + addl 72(%esp),%edx + xorl %edi,%ebx + addl %edx,%ecx + addl 4(%esp),%edx + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,4(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 12(%esp),%edx,%esi + xorl %edi,%ecx + andl 8(%esp),%edx + movl %ebx,20(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + movl 24(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + addl 16(%esp),%edx + andl %ebx,%eax + addl 76(%esp),%edx + xorl %edi,%eax + addl %edx,%ecx + addl (%esp),%edx + leal (%eax,%ecx,1),%eax + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 8(%esp),%edx,%esi + xorl %edi,%ecx + andl 4(%esp),%edx + movl %eax,16(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + movl 20(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + addl 12(%esp),%edx + andl %eax,%ebx + addl 80(%esp),%edx + xorl %edi,%ebx + addl %edx,%ecx + addl 28(%esp),%edx + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,28(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 4(%esp),%edx,%esi + xorl %edi,%ecx + andl (%esp),%edx + movl %ebx,12(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + movl 16(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + addl 8(%esp),%edx + andl %ebx,%eax + addl 84(%esp),%edx + xorl %edi,%eax + addl %edx,%ecx + addl 24(%esp),%edx + leal (%eax,%ecx,1),%eax + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,24(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl (%esp),%edx,%esi + xorl %edi,%ecx + andl 28(%esp),%edx + movl %eax,8(%esp) + orl %esi,%edx + rorxl $2,%eax,%edi + rorxl $13,%eax,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%eax,%ecx + xorl %edi,%esi + movl 12(%esp),%edi + xorl %esi,%ecx + xorl %edi,%eax + addl 4(%esp),%edx + andl %eax,%ebx + addl 88(%esp),%edx + xorl %edi,%ebx + addl %edx,%ecx + addl 20(%esp),%edx + leal (%ebx,%ecx,1),%ebx + rorxl $6,%edx,%ecx + rorxl $11,%edx,%esi + movl %edx,20(%esp) + rorxl $25,%edx,%edi + xorl %esi,%ecx + andnl 28(%esp),%edx,%esi + xorl %edi,%ecx + andl 24(%esp),%edx + movl %ebx,4(%esp) + orl %esi,%edx + rorxl $2,%ebx,%edi + rorxl $13,%ebx,%esi + leal (%edx,%ecx,1),%edx + rorxl $22,%ebx,%ecx + xorl %edi,%esi + movl 8(%esp),%edi + xorl %esi,%ecx + xorl %edi,%ebx + addl (%esp),%edx + andl %ebx,%eax + addl 92(%esp),%edx + xorl %edi,%eax + addl %edx,%ecx + addl 16(%esp),%edx + leal (%eax,%ecx,1),%eax + movl 96(%esp),%esi + xorl %edi,%ebx + movl 12(%esp),%ecx + addl (%esi),%eax + addl 4(%esi),%ebx + addl 8(%esi),%edi + addl 12(%esi),%ecx + movl %eax,(%esi) + movl %ebx,4(%esi) + movl %edi,8(%esi) + movl %ecx,12(%esi) + movl %ebx,4(%esp) + xorl %edi,%ebx + movl %edi,8(%esp) + movl %ecx,12(%esp) + movl 20(%esp),%edi + movl 24(%esp),%ecx + addl 16(%esi),%edx + addl 20(%esi),%edi + addl 24(%esi),%ecx + movl %edx,16(%esi) + movl %edi,20(%esi) + movl %edi,20(%esp) + movl 28(%esp),%edi + movl %ecx,24(%esi) + addl 28(%esi),%edi + movl %ecx,24(%esp) + movl %edi,28(%esi) + movl %edi,28(%esp) + movl 100(%esp),%edi + vmovdqa 64(%ebp),%xmm7 + subl $192,%ebp + cmpl 104(%esp),%edi + jb .L017grand_avx_bmi + movl 108(%esp),%esp + vzeroall + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size sha256_block_data_order,.-.L_sha256_block_data_order_begin +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/sha/sha256-armv8.S b/crypto/openssl/crypto/sha/sha256-armv8.S new file mode 100644 index 000000000000..e0965b668ddc --- /dev/null +++ b/crypto/openssl/crypto/sha/sha256-armv8.S @@ -0,0 +1,2051 @@ +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License 2.0 (the "License"). You may not use +// this file except in compliance with the License. You can obtain a copy +// in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html + +// ==================================================================== +// Written by Andy Polyakov 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/. +// +// Permission to use under GPLv2 terms is granted. +// ==================================================================== +// +// SHA256/512 for ARMv8. +// +// Performance in cycles per processed byte and improvement coefficient +// over code generated with "default" compiler: +// +// SHA256-hw SHA256(*) SHA512 +// Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**)) +// Cortex-A53 2.38 15.5 (+115%) 10.0 (+150%(***)) +// Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***)) +// Denver 2.01 10.5 (+26%) 6.70 (+8%) +// X-Gene 20.0 (+100%) 12.8 (+300%(***)) +// Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) +// ThunderX2 2.54 13.2 (+40%) 8.40 (+18%) +// +// (*) Software SHA256 results are of lesser relevance, presented +// mostly for informational purposes. +// (**) The result is a trade-off: it's possible to improve it by +// 10% (or by 1 cycle per round), but at the cost of 20% loss +// on Cortex-A53 (or by 4 cycles per round). +// (***) Super-impressive coefficients over gcc-generated code are +// indication of some compiler "pathology", most notably code +// generated with -mgeneral-regs-only is significantly faster +// and the gap is only 40-90%. +// +// October 2016. +// +// Originally it was reckoned that it makes no sense to implement NEON +// version of SHA256 for 64-bit processors. This is because performance +// improvement on most wide-spread Cortex-A5x processors was observed +// to be marginal, same on Cortex-A53 and ~10% on A57. But then it was +// observed that 32-bit NEON SHA256 performs significantly better than +// 64-bit scalar version on *some* of the more recent processors. As +// result 64-bit NEON version of SHA256 was added to provide best +// all-round performance. For example it executes ~30% faster on X-Gene +// and Mongoose. [For reference, NEON version of SHA512 is bound to +// deliver much less improvement, likely *negative* on Cortex-A5x. +// Which is why NEON support is limited to SHA256.] + +// $output is the last argument if it looks like a file (it has an extension) +// $flavour is the first argument if it doesn't look like a file +#ifndef __KERNEL__ +# include "arm_arch.h" + +.hidden OPENSSL_armcap_P +#endif + +.text + +.globl sha256_block_data_order +.type sha256_block_data_order,%function +.align 6 +sha256_block_data_order: +#ifndef __KERNEL__ + adrp x16,OPENSSL_armcap_P + ldr w16,[x16,#:lo12:OPENSSL_armcap_P] + tst w16,#ARMV8_SHA256 + b.ne .Lv8_entry + tst w16,#ARMV7_NEON + b.ne .Lneon_entry +#endif +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#4*4 + + ldp w20,w21,[x0] // load context + ldp w22,w23,[x0,#2*4] + ldp w24,w25,[x0,#4*4] + add x2,x1,x2,lsl#6 // end of input + ldp w26,w27,[x0,#6*4] + adr x30,.LK256 + stp x0,x2,[x29,#96] + +.Loop: + ldp w3,w4,[x1],#2*4 + ldr w19,[x30],#4 // *K++ + eor w28,w21,w22 // magic seed + str x1,[x29,#112] +#ifndef __AARCH64EB__ + rev w3,w3 // 0 +#endif + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + eor w6,w24,w24,ror#14 + and w17,w25,w24 + bic w19,w26,w24 + add w27,w27,w3 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w6,ror#11 // Sigma1(e) + ror w6,w20,#2 + add w27,w27,w17 // h+=Ch(e,f,g) + eor w17,w20,w20,ror#9 + add w27,w27,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w23,w23,w27 // d+=h + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w6,w17,ror#13 // Sigma0(a) + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w4,w4 // 1 +#endif + ldp w5,w6,[x1],#2*4 + add w27,w27,w17 // h+=Sigma0(a) + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + eor w7,w23,w23,ror#14 + and w17,w24,w23 + bic w28,w25,w23 + add w26,w26,w4 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w7,ror#11 // Sigma1(e) + ror w7,w27,#2 + add w26,w26,w17 // h+=Ch(e,f,g) + eor w17,w27,w27,ror#9 + add w26,w26,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w22,w22,w26 // d+=h + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w7,w17,ror#13 // Sigma0(a) + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w5,w5 // 2 +#endif + add w26,w26,w17 // h+=Sigma0(a) + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + eor w8,w22,w22,ror#14 + and w17,w23,w22 + bic w19,w24,w22 + add w25,w25,w5 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w8,ror#11 // Sigma1(e) + ror w8,w26,#2 + add w25,w25,w17 // h+=Ch(e,f,g) + eor w17,w26,w26,ror#9 + add w25,w25,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w21,w21,w25 // d+=h + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w8,w17,ror#13 // Sigma0(a) + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w6,w6 // 3 +#endif + ldp w7,w8,[x1],#2*4 + add w25,w25,w17 // h+=Sigma0(a) + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + eor w9,w21,w21,ror#14 + and w17,w22,w21 + bic w28,w23,w21 + add w24,w24,w6 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w9,ror#11 // Sigma1(e) + ror w9,w25,#2 + add w24,w24,w17 // h+=Ch(e,f,g) + eor w17,w25,w25,ror#9 + add w24,w24,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w20,w20,w24 // d+=h + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w9,w17,ror#13 // Sigma0(a) + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w7,w7 // 4 +#endif + add w24,w24,w17 // h+=Sigma0(a) + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + eor w10,w20,w20,ror#14 + and w17,w21,w20 + bic w19,w22,w20 + add w23,w23,w7 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w10,ror#11 // Sigma1(e) + ror w10,w24,#2 + add w23,w23,w17 // h+=Ch(e,f,g) + eor w17,w24,w24,ror#9 + add w23,w23,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w27,w27,w23 // d+=h + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w10,w17,ror#13 // Sigma0(a) + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w8,w8 // 5 +#endif + ldp w9,w10,[x1],#2*4 + add w23,w23,w17 // h+=Sigma0(a) + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + eor w11,w27,w27,ror#14 + and w17,w20,w27 + bic w28,w21,w27 + add w22,w22,w8 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w11,ror#11 // Sigma1(e) + ror w11,w23,#2 + add w22,w22,w17 // h+=Ch(e,f,g) + eor w17,w23,w23,ror#9 + add w22,w22,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w26,w26,w22 // d+=h + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w11,w17,ror#13 // Sigma0(a) + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w9,w9 // 6 +#endif + add w22,w22,w17 // h+=Sigma0(a) + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + eor w12,w26,w26,ror#14 + and w17,w27,w26 + bic w19,w20,w26 + add w21,w21,w9 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w12,ror#11 // Sigma1(e) + ror w12,w22,#2 + add w21,w21,w17 // h+=Ch(e,f,g) + eor w17,w22,w22,ror#9 + add w21,w21,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w25,w25,w21 // d+=h + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w12,w17,ror#13 // Sigma0(a) + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w10,w10 // 7 +#endif + ldp w11,w12,[x1],#2*4 + add w21,w21,w17 // h+=Sigma0(a) + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + eor w13,w25,w25,ror#14 + and w17,w26,w25 + bic w28,w27,w25 + add w20,w20,w10 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w13,ror#11 // Sigma1(e) + ror w13,w21,#2 + add w20,w20,w17 // h+=Ch(e,f,g) + eor w17,w21,w21,ror#9 + add w20,w20,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w24,w24,w20 // d+=h + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w13,w17,ror#13 // Sigma0(a) + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w20,w20,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w11,w11 // 8 +#endif + add w20,w20,w17 // h+=Sigma0(a) + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + eor w14,w24,w24,ror#14 + and w17,w25,w24 + bic w19,w26,w24 + add w27,w27,w11 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w14,ror#11 // Sigma1(e) + ror w14,w20,#2 + add w27,w27,w17 // h+=Ch(e,f,g) + eor w17,w20,w20,ror#9 + add w27,w27,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w23,w23,w27 // d+=h + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w14,w17,ror#13 // Sigma0(a) + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w12,w12 // 9 +#endif + ldp w13,w14,[x1],#2*4 + add w27,w27,w17 // h+=Sigma0(a) + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + eor w15,w23,w23,ror#14 + and w17,w24,w23 + bic w28,w25,w23 + add w26,w26,w12 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w15,ror#11 // Sigma1(e) + ror w15,w27,#2 + add w26,w26,w17 // h+=Ch(e,f,g) + eor w17,w27,w27,ror#9 + add w26,w26,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w22,w22,w26 // d+=h + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w15,w17,ror#13 // Sigma0(a) + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w13,w13 // 10 +#endif + add w26,w26,w17 // h+=Sigma0(a) + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + eor w0,w22,w22,ror#14 + and w17,w23,w22 + bic w19,w24,w22 + add w25,w25,w13 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w0,ror#11 // Sigma1(e) + ror w0,w26,#2 + add w25,w25,w17 // h+=Ch(e,f,g) + eor w17,w26,w26,ror#9 + add w25,w25,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w21,w21,w25 // d+=h + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w0,w17,ror#13 // Sigma0(a) + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w14,w14 // 11 +#endif + ldp w15,w0,[x1],#2*4 + add w25,w25,w17 // h+=Sigma0(a) + str w6,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + eor w6,w21,w21,ror#14 + and w17,w22,w21 + bic w28,w23,w21 + add w24,w24,w14 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w6,ror#11 // Sigma1(e) + ror w6,w25,#2 + add w24,w24,w17 // h+=Ch(e,f,g) + eor w17,w25,w25,ror#9 + add w24,w24,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w20,w20,w24 // d+=h + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w6,w17,ror#13 // Sigma0(a) + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w15,w15 // 12 +#endif + add w24,w24,w17 // h+=Sigma0(a) + str w7,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + eor w7,w20,w20,ror#14 + and w17,w21,w20 + bic w19,w22,w20 + add w23,w23,w15 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w7,ror#11 // Sigma1(e) + ror w7,w24,#2 + add w23,w23,w17 // h+=Ch(e,f,g) + eor w17,w24,w24,ror#9 + add w23,w23,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w27,w27,w23 // d+=h + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w7,w17,ror#13 // Sigma0(a) + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w0,w0 // 13 +#endif + ldp w1,w2,[x1] + add w23,w23,w17 // h+=Sigma0(a) + str w8,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + eor w8,w27,w27,ror#14 + and w17,w20,w27 + bic w28,w21,w27 + add w22,w22,w0 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w8,ror#11 // Sigma1(e) + ror w8,w23,#2 + add w22,w22,w17 // h+=Ch(e,f,g) + eor w17,w23,w23,ror#9 + add w22,w22,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w26,w26,w22 // d+=h + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w8,w17,ror#13 // Sigma0(a) + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w1,w1 // 14 +#endif + ldr w6,[sp,#12] + add w22,w22,w17 // h+=Sigma0(a) + str w9,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + eor w9,w26,w26,ror#14 + and w17,w27,w26 + bic w19,w20,w26 + add w21,w21,w1 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w9,ror#11 // Sigma1(e) + ror w9,w22,#2 + add w21,w21,w17 // h+=Ch(e,f,g) + eor w17,w22,w22,ror#9 + add w21,w21,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w25,w25,w21 // d+=h + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w9,w17,ror#13 // Sigma0(a) + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev w2,w2 // 15 +#endif + ldr w7,[sp,#0] + add w21,w21,w17 // h+=Sigma0(a) + str w10,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w9,w4,#7 + and w17,w26,w25 + ror w8,w1,#17 + bic w28,w27,w25 + ror w10,w21,#2 + add w20,w20,w2 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w9,w9,w4,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w10,w10,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w8,w8,w1,ror#19 + eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w10,w21,ror#22 // Sigma0(a) + eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) + add w3,w3,w12 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w3,w3,w9 + add w20,w20,w17 // h+=Sigma0(a) + add w3,w3,w8 +.Loop_16_xx: + ldr w8,[sp,#4] + str w11,[sp,#0] + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + ror w10,w5,#7 + and w17,w25,w24 + ror w9,w2,#17 + bic w19,w26,w24 + ror w11,w20,#2 + add w27,w27,w3 // h+=X[i] + eor w16,w16,w24,ror#11 + eor w10,w10,w5,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w24,ror#25 // Sigma1(e) + eor w11,w11,w20,ror#13 + add w27,w27,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w9,w9,w2,ror#19 + eor w10,w10,w5,lsr#3 // sigma0(X[i+1]) + add w27,w27,w16 // h+=Sigma1(e) + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w11,w20,ror#22 // Sigma0(a) + eor w9,w9,w2,lsr#10 // sigma1(X[i+14]) + add w4,w4,w13 + add w23,w23,w27 // d+=h + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w4,w4,w10 + add w27,w27,w17 // h+=Sigma0(a) + add w4,w4,w9 + ldr w9,[sp,#8] + str w12,[sp,#4] + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + ror w11,w6,#7 + and w17,w24,w23 + ror w10,w3,#17 + bic w28,w25,w23 + ror w12,w27,#2 + add w26,w26,w4 // h+=X[i] + eor w16,w16,w23,ror#11 + eor w11,w11,w6,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w23,ror#25 // Sigma1(e) + eor w12,w12,w27,ror#13 + add w26,w26,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w10,w10,w3,ror#19 + eor w11,w11,w6,lsr#3 // sigma0(X[i+1]) + add w26,w26,w16 // h+=Sigma1(e) + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w12,w27,ror#22 // Sigma0(a) + eor w10,w10,w3,lsr#10 // sigma1(X[i+14]) + add w5,w5,w14 + add w22,w22,w26 // d+=h + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w5,w5,w11 + add w26,w26,w17 // h+=Sigma0(a) + add w5,w5,w10 + ldr w10,[sp,#12] + str w13,[sp,#8] + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + ror w12,w7,#7 + and w17,w23,w22 + ror w11,w4,#17 + bic w19,w24,w22 + ror w13,w26,#2 + add w25,w25,w5 // h+=X[i] + eor w16,w16,w22,ror#11 + eor w12,w12,w7,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w22,ror#25 // Sigma1(e) + eor w13,w13,w26,ror#13 + add w25,w25,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w11,w11,w4,ror#19 + eor w12,w12,w7,lsr#3 // sigma0(X[i+1]) + add w25,w25,w16 // h+=Sigma1(e) + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w13,w26,ror#22 // Sigma0(a) + eor w11,w11,w4,lsr#10 // sigma1(X[i+14]) + add w6,w6,w15 + add w21,w21,w25 // d+=h + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w6,w6,w12 + add w25,w25,w17 // h+=Sigma0(a) + add w6,w6,w11 + ldr w11,[sp,#0] + str w14,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + ror w13,w8,#7 + and w17,w22,w21 + ror w12,w5,#17 + bic w28,w23,w21 + ror w14,w25,#2 + add w24,w24,w6 // h+=X[i] + eor w16,w16,w21,ror#11 + eor w13,w13,w8,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w21,ror#25 // Sigma1(e) + eor w14,w14,w25,ror#13 + add w24,w24,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w12,w12,w5,ror#19 + eor w13,w13,w8,lsr#3 // sigma0(X[i+1]) + add w24,w24,w16 // h+=Sigma1(e) + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w14,w25,ror#22 // Sigma0(a) + eor w12,w12,w5,lsr#10 // sigma1(X[i+14]) + add w7,w7,w0 + add w20,w20,w24 // d+=h + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w7,w7,w13 + add w24,w24,w17 // h+=Sigma0(a) + add w7,w7,w12 + ldr w12,[sp,#4] + str w15,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + ror w14,w9,#7 + and w17,w21,w20 + ror w13,w6,#17 + bic w19,w22,w20 + ror w15,w24,#2 + add w23,w23,w7 // h+=X[i] + eor w16,w16,w20,ror#11 + eor w14,w14,w9,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w20,ror#25 // Sigma1(e) + eor w15,w15,w24,ror#13 + add w23,w23,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w13,w13,w6,ror#19 + eor w14,w14,w9,lsr#3 // sigma0(X[i+1]) + add w23,w23,w16 // h+=Sigma1(e) + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w15,w24,ror#22 // Sigma0(a) + eor w13,w13,w6,lsr#10 // sigma1(X[i+14]) + add w8,w8,w1 + add w27,w27,w23 // d+=h + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w8,w8,w14 + add w23,w23,w17 // h+=Sigma0(a) + add w8,w8,w13 + ldr w13,[sp,#8] + str w0,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + ror w15,w10,#7 + and w17,w20,w27 + ror w14,w7,#17 + bic w28,w21,w27 + ror w0,w23,#2 + add w22,w22,w8 // h+=X[i] + eor w16,w16,w27,ror#11 + eor w15,w15,w10,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w27,ror#25 // Sigma1(e) + eor w0,w0,w23,ror#13 + add w22,w22,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w14,w14,w7,ror#19 + eor w15,w15,w10,lsr#3 // sigma0(X[i+1]) + add w22,w22,w16 // h+=Sigma1(e) + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w0,w23,ror#22 // Sigma0(a) + eor w14,w14,w7,lsr#10 // sigma1(X[i+14]) + add w9,w9,w2 + add w26,w26,w22 // d+=h + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w9,w9,w15 + add w22,w22,w17 // h+=Sigma0(a) + add w9,w9,w14 + ldr w14,[sp,#12] + str w1,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + ror w0,w11,#7 + and w17,w27,w26 + ror w15,w8,#17 + bic w19,w20,w26 + ror w1,w22,#2 + add w21,w21,w9 // h+=X[i] + eor w16,w16,w26,ror#11 + eor w0,w0,w11,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w26,ror#25 // Sigma1(e) + eor w1,w1,w22,ror#13 + add w21,w21,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w15,w15,w8,ror#19 + eor w0,w0,w11,lsr#3 // sigma0(X[i+1]) + add w21,w21,w16 // h+=Sigma1(e) + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w1,w22,ror#22 // Sigma0(a) + eor w15,w15,w8,lsr#10 // sigma1(X[i+14]) + add w10,w10,w3 + add w25,w25,w21 // d+=h + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w10,w10,w0 + add w21,w21,w17 // h+=Sigma0(a) + add w10,w10,w15 + ldr w15,[sp,#0] + str w2,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w1,w12,#7 + and w17,w26,w25 + ror w0,w9,#17 + bic w28,w27,w25 + ror w2,w21,#2 + add w20,w20,w10 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w1,w1,w12,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w2,w2,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w0,w0,w9,ror#19 + eor w1,w1,w12,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w2,w21,ror#22 // Sigma0(a) + eor w0,w0,w9,lsr#10 // sigma1(X[i+14]) + add w11,w11,w4 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w11,w11,w1 + add w20,w20,w17 // h+=Sigma0(a) + add w11,w11,w0 + ldr w0,[sp,#4] + str w3,[sp,#0] + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + ror w2,w13,#7 + and w17,w25,w24 + ror w1,w10,#17 + bic w19,w26,w24 + ror w3,w20,#2 + add w27,w27,w11 // h+=X[i] + eor w16,w16,w24,ror#11 + eor w2,w2,w13,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w24,ror#25 // Sigma1(e) + eor w3,w3,w20,ror#13 + add w27,w27,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w1,w1,w10,ror#19 + eor w2,w2,w13,lsr#3 // sigma0(X[i+1]) + add w27,w27,w16 // h+=Sigma1(e) + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w3,w20,ror#22 // Sigma0(a) + eor w1,w1,w10,lsr#10 // sigma1(X[i+14]) + add w12,w12,w5 + add w23,w23,w27 // d+=h + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w12,w12,w2 + add w27,w27,w17 // h+=Sigma0(a) + add w12,w12,w1 + ldr w1,[sp,#8] + str w4,[sp,#4] + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + ror w3,w14,#7 + and w17,w24,w23 + ror w2,w11,#17 + bic w28,w25,w23 + ror w4,w27,#2 + add w26,w26,w12 // h+=X[i] + eor w16,w16,w23,ror#11 + eor w3,w3,w14,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w23,ror#25 // Sigma1(e) + eor w4,w4,w27,ror#13 + add w26,w26,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w2,w2,w11,ror#19 + eor w3,w3,w14,lsr#3 // sigma0(X[i+1]) + add w26,w26,w16 // h+=Sigma1(e) + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w4,w27,ror#22 // Sigma0(a) + eor w2,w2,w11,lsr#10 // sigma1(X[i+14]) + add w13,w13,w6 + add w22,w22,w26 // d+=h + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w13,w13,w3 + add w26,w26,w17 // h+=Sigma0(a) + add w13,w13,w2 + ldr w2,[sp,#12] + str w5,[sp,#8] + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + ror w4,w15,#7 + and w17,w23,w22 + ror w3,w12,#17 + bic w19,w24,w22 + ror w5,w26,#2 + add w25,w25,w13 // h+=X[i] + eor w16,w16,w22,ror#11 + eor w4,w4,w15,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w22,ror#25 // Sigma1(e) + eor w5,w5,w26,ror#13 + add w25,w25,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w3,w3,w12,ror#19 + eor w4,w4,w15,lsr#3 // sigma0(X[i+1]) + add w25,w25,w16 // h+=Sigma1(e) + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w5,w26,ror#22 // Sigma0(a) + eor w3,w3,w12,lsr#10 // sigma1(X[i+14]) + add w14,w14,w7 + add w21,w21,w25 // d+=h + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w14,w14,w4 + add w25,w25,w17 // h+=Sigma0(a) + add w14,w14,w3 + ldr w3,[sp,#0] + str w6,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + ror w5,w0,#7 + and w17,w22,w21 + ror w4,w13,#17 + bic w28,w23,w21 + ror w6,w25,#2 + add w24,w24,w14 // h+=X[i] + eor w16,w16,w21,ror#11 + eor w5,w5,w0,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w21,ror#25 // Sigma1(e) + eor w6,w6,w25,ror#13 + add w24,w24,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w4,w4,w13,ror#19 + eor w5,w5,w0,lsr#3 // sigma0(X[i+1]) + add w24,w24,w16 // h+=Sigma1(e) + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w6,w25,ror#22 // Sigma0(a) + eor w4,w4,w13,lsr#10 // sigma1(X[i+14]) + add w15,w15,w8 + add w20,w20,w24 // d+=h + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w15,w15,w5 + add w24,w24,w17 // h+=Sigma0(a) + add w15,w15,w4 + ldr w4,[sp,#4] + str w7,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + ror w6,w1,#7 + and w17,w21,w20 + ror w5,w14,#17 + bic w19,w22,w20 + ror w7,w24,#2 + add w23,w23,w15 // h+=X[i] + eor w16,w16,w20,ror#11 + eor w6,w6,w1,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w20,ror#25 // Sigma1(e) + eor w7,w7,w24,ror#13 + add w23,w23,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w5,w5,w14,ror#19 + eor w6,w6,w1,lsr#3 // sigma0(X[i+1]) + add w23,w23,w16 // h+=Sigma1(e) + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w7,w24,ror#22 // Sigma0(a) + eor w5,w5,w14,lsr#10 // sigma1(X[i+14]) + add w0,w0,w9 + add w27,w27,w23 // d+=h + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w0,w0,w6 + add w23,w23,w17 // h+=Sigma0(a) + add w0,w0,w5 + ldr w5,[sp,#8] + str w8,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + ror w7,w2,#7 + and w17,w20,w27 + ror w6,w15,#17 + bic w28,w21,w27 + ror w8,w23,#2 + add w22,w22,w0 // h+=X[i] + eor w16,w16,w27,ror#11 + eor w7,w7,w2,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w27,ror#25 // Sigma1(e) + eor w8,w8,w23,ror#13 + add w22,w22,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w6,w6,w15,ror#19 + eor w7,w7,w2,lsr#3 // sigma0(X[i+1]) + add w22,w22,w16 // h+=Sigma1(e) + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w8,w23,ror#22 // Sigma0(a) + eor w6,w6,w15,lsr#10 // sigma1(X[i+14]) + add w1,w1,w10 + add w26,w26,w22 // d+=h + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w1,w1,w7 + add w22,w22,w17 // h+=Sigma0(a) + add w1,w1,w6 + ldr w6,[sp,#12] + str w9,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + ror w8,w3,#7 + and w17,w27,w26 + ror w7,w0,#17 + bic w19,w20,w26 + ror w9,w22,#2 + add w21,w21,w1 // h+=X[i] + eor w16,w16,w26,ror#11 + eor w8,w8,w3,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w26,ror#25 // Sigma1(e) + eor w9,w9,w22,ror#13 + add w21,w21,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w7,w7,w0,ror#19 + eor w8,w8,w3,lsr#3 // sigma0(X[i+1]) + add w21,w21,w16 // h+=Sigma1(e) + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w9,w22,ror#22 // Sigma0(a) + eor w7,w7,w0,lsr#10 // sigma1(X[i+14]) + add w2,w2,w11 + add w25,w25,w21 // d+=h + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w2,w2,w8 + add w21,w21,w17 // h+=Sigma0(a) + add w2,w2,w7 + ldr w7,[sp,#0] + str w10,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w9,w4,#7 + and w17,w26,w25 + ror w8,w1,#17 + bic w28,w27,w25 + ror w10,w21,#2 + add w20,w20,w2 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w9,w9,w4,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w10,w10,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w8,w8,w1,ror#19 + eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w10,w21,ror#22 // Sigma0(a) + eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) + add w3,w3,w12 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w3,w3,w9 + add w20,w20,w17 // h+=Sigma0(a) + add w3,w3,w8 + cbnz w19,.Loop_16_xx + + ldp x0,x2,[x29,#96] + ldr x1,[x29,#112] + sub x30,x30,#260 // rewind + + ldp w3,w4,[x0] + ldp w5,w6,[x0,#2*4] + add x1,x1,#14*4 // advance input pointer + ldp w7,w8,[x0,#4*4] + add w20,w20,w3 + ldp w9,w10,[x0,#6*4] + add w21,w21,w4 + add w22,w22,w5 + add w23,w23,w6 + stp w20,w21,[x0] + add w24,w24,w7 + add w25,w25,w8 + stp w22,w23,[x0,#2*4] + add w26,w26,w9 + add w27,w27,w10 + cmp x1,x2 + stp w24,w25,[x0,#4*4] + stp w26,w27,[x0,#6*4] + b.ne .Loop + + ldp x19,x20,[x29,#16] + add sp,sp,#4*4 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size sha256_block_data_order,.-sha256_block_data_order + +.align 6 +.type .LK256,%object +.LK256: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.long 0 //terminator +.size .LK256,.-.LK256 +.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#ifndef __KERNEL__ +.type sha256_block_armv8,%function +.align 6 +sha256_block_armv8: +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v0.4s,v1.4s},[x0] + adr x3,.LK256 + +.Loop_hw: + ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64 + sub x2,x2,#1 + ld1 {v16.4s},[x3],#16 + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b + orr v18.16b,v0.16b,v0.16b // offload + orr v19.16b,v1.16b,v1.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s +.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s +.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s +.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s +.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s +.inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s +.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + + ld1 {v17.4s},[x3] + add v16.4s,v16.4s,v6.4s + sub x3,x3,#64*4-16 // rewind + orr v2.16b,v0.16b,v0.16b +.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s +.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + + add v17.4s,v17.4s,v7.4s + orr v2.16b,v0.16b,v0.16b +.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s +.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + + add v0.4s,v0.4s,v18.4s + add v1.4s,v1.4s,v19.4s + + cbnz x2,.Loop_hw + + st1 {v0.4s,v1.4s},[x0] + + ldr x29,[sp],#16 + ret +.size sha256_block_armv8,.-sha256_block_armv8 +#endif +#ifdef __KERNEL__ +.globl sha256_block_neon +#endif +.type sha256_block_neon,%function +.align 4 +sha256_block_neon: +.Lneon_entry: + stp x29, x30, [sp, #-16]! + mov x29, sp + sub sp,sp,#16*4 + + adr x16,.LK256 + add x2,x1,x2,lsl#6 // len to point at the end of inp + + ld1 {v0.16b},[x1], #16 + ld1 {v1.16b},[x1], #16 + ld1 {v2.16b},[x1], #16 + ld1 {v3.16b},[x1], #16 + ld1 {v4.4s},[x16], #16 + ld1 {v5.4s},[x16], #16 + ld1 {v6.4s},[x16], #16 + ld1 {v7.4s},[x16], #16 + rev32 v0.16b,v0.16b // yes, even on + rev32 v1.16b,v1.16b // big-endian + rev32 v2.16b,v2.16b + rev32 v3.16b,v3.16b + mov x17,sp + add v4.4s,v4.4s,v0.4s + add v5.4s,v5.4s,v1.4s + add v6.4s,v6.4s,v2.4s + st1 {v4.4s,v5.4s},[x17], #32 + add v7.4s,v7.4s,v3.4s + st1 {v6.4s,v7.4s},[x17] + sub x17,x17,#32 + + ldp w3,w4,[x0] + ldp w5,w6,[x0,#8] + ldp w7,w8,[x0,#16] + ldp w9,w10,[x0,#24] + ldr w12,[sp,#0] + mov w13,wzr + eor w14,w4,w5 + mov w15,wzr + b .L_00_48 + +.align 4 +.L_00_48: + ext v4.16b,v0.16b,v1.16b,#4 + add w10,w10,w12 + add w3,w3,w15 + and w12,w8,w7 + bic w15,w9,w7 + ext v7.16b,v2.16b,v3.16b,#4 + eor w11,w7,w7,ror#5 + add w3,w3,w13 + mov d19,v3.d[1] + orr w12,w12,w15 + eor w11,w11,w7,ror#19 + ushr v6.4s,v4.4s,#7 + eor w15,w3,w3,ror#11 + ushr v5.4s,v4.4s,#3 + add w10,w10,w12 + add v0.4s,v0.4s,v7.4s + ror w11,w11,#6 + sli v6.4s,v4.4s,#25 + eor w13,w3,w4 + eor w15,w15,w3,ror#20 + ushr v7.4s,v4.4s,#18 + add w10,w10,w11 + ldr w12,[sp,#4] + and w14,w14,w13 + eor v5.16b,v5.16b,v6.16b + ror w15,w15,#2 + add w6,w6,w10 + sli v7.4s,v4.4s,#14 + eor w14,w14,w4 + ushr v16.4s,v19.4s,#17 + add w9,w9,w12 + add w10,w10,w15 + and w12,w7,w6 + eor v5.16b,v5.16b,v7.16b + bic w15,w8,w6 + eor w11,w6,w6,ror#5 + sli v16.4s,v19.4s,#15 + add w10,w10,w14 + orr w12,w12,w15 + ushr v17.4s,v19.4s,#10 + eor w11,w11,w6,ror#19 + eor w15,w10,w10,ror#11 + ushr v7.4s,v19.4s,#19 + add w9,w9,w12 + ror w11,w11,#6 + add v0.4s,v0.4s,v5.4s + eor w14,w10,w3 + eor w15,w15,w10,ror#20 + sli v7.4s,v19.4s,#13 + add w9,w9,w11 + ldr w12,[sp,#8] + and w13,w13,w14 + eor v17.16b,v17.16b,v16.16b + ror w15,w15,#2 + add w5,w5,w9 + eor w13,w13,w3 + eor v17.16b,v17.16b,v7.16b + add w8,w8,w12 + add w9,w9,w15 + and w12,w6,w5 + add v0.4s,v0.4s,v17.4s + bic w15,w7,w5 + eor w11,w5,w5,ror#5 + add w9,w9,w13 + ushr v18.4s,v0.4s,#17 + orr w12,w12,w15 + ushr v19.4s,v0.4s,#10 + eor w11,w11,w5,ror#19 + eor w15,w9,w9,ror#11 + sli v18.4s,v0.4s,#15 + add w8,w8,w12 + ushr v17.4s,v0.4s,#19 + ror w11,w11,#6 + eor w13,w9,w10 + eor v19.16b,v19.16b,v18.16b + eor w15,w15,w9,ror#20 + add w8,w8,w11 + sli v17.4s,v0.4s,#13 + ldr w12,[sp,#12] + and w14,w14,w13 + ror w15,w15,#2 + ld1 {v4.4s},[x16], #16 + add w4,w4,w8 + eor v19.16b,v19.16b,v17.16b + eor w14,w14,w10 + eor v17.16b,v17.16b,v17.16b + add w7,w7,w12 + add w8,w8,w15 + and w12,w5,w4 + mov v17.d[1],v19.d[0] + bic w15,w6,w4 + eor w11,w4,w4,ror#5 + add w8,w8,w14 + add v0.4s,v0.4s,v17.4s + orr w12,w12,w15 + eor w11,w11,w4,ror#19 + eor w15,w8,w8,ror#11 + add v4.4s,v4.4s,v0.4s + add w7,w7,w12 + ror w11,w11,#6 + eor w14,w8,w9 + eor w15,w15,w8,ror#20 + add w7,w7,w11 + ldr w12,[sp,#16] + and w13,w13,w14 + ror w15,w15,#2 + add w3,w3,w7 + eor w13,w13,w9 + st1 {v4.4s},[x17], #16 + ext v4.16b,v1.16b,v2.16b,#4 + add w6,w6,w12 + add w7,w7,w15 + and w12,w4,w3 + bic w15,w5,w3 + ext v7.16b,v3.16b,v0.16b,#4 + eor w11,w3,w3,ror#5 + add w7,w7,w13 + mov d19,v0.d[1] + orr w12,w12,w15 + eor w11,w11,w3,ror#19 + ushr v6.4s,v4.4s,#7 + eor w15,w7,w7,ror#11 + ushr v5.4s,v4.4s,#3 + add w6,w6,w12 + add v1.4s,v1.4s,v7.4s + ror w11,w11,#6 + sli v6.4s,v4.4s,#25 + eor w13,w7,w8 + eor w15,w15,w7,ror#20 + ushr v7.4s,v4.4s,#18 + add w6,w6,w11 + ldr w12,[sp,#20] + and w14,w14,w13 + eor v5.16b,v5.16b,v6.16b + ror w15,w15,#2 + add w10,w10,w6 + sli v7.4s,v4.4s,#14 + eor w14,w14,w8 + ushr v16.4s,v19.4s,#17 + add w5,w5,w12 + add w6,w6,w15 + and w12,w3,w10 + eor v5.16b,v5.16b,v7.16b + bic w15,w4,w10 + eor w11,w10,w10,ror#5 + sli v16.4s,v19.4s,#15 + add w6,w6,w14 + orr w12,w12,w15 + ushr v17.4s,v19.4s,#10 + eor w11,w11,w10,ror#19 + eor w15,w6,w6,ror#11 + ushr v7.4s,v19.4s,#19 + add w5,w5,w12 + ror w11,w11,#6 + add v1.4s,v1.4s,v5.4s + eor w14,w6,w7 + eor w15,w15,w6,ror#20 + sli v7.4s,v19.4s,#13 + add w5,w5,w11 + ldr w12,[sp,#24] + and w13,w13,w14 + eor v17.16b,v17.16b,v16.16b + ror w15,w15,#2 + add w9,w9,w5 + eor w13,w13,w7 + eor v17.16b,v17.16b,v7.16b + add w4,w4,w12 + add w5,w5,w15 + and w12,w10,w9 + add v1.4s,v1.4s,v17.4s + bic w15,w3,w9 + eor w11,w9,w9,ror#5 + add w5,w5,w13 + ushr v18.4s,v1.4s,#17 + orr w12,w12,w15 + ushr v19.4s,v1.4s,#10 + eor w11,w11,w9,ror#19 + eor w15,w5,w5,ror#11 + sli v18.4s,v1.4s,#15 + add w4,w4,w12 + ushr v17.4s,v1.4s,#19 + ror w11,w11,#6 + eor w13,w5,w6 + eor v19.16b,v19.16b,v18.16b + eor w15,w15,w5,ror#20 + add w4,w4,w11 + sli v17.4s,v1.4s,#13 + ldr w12,[sp,#28] + and w14,w14,w13 + ror w15,w15,#2 + ld1 {v4.4s},[x16], #16 + add w8,w8,w4 + eor v19.16b,v19.16b,v17.16b + eor w14,w14,w6 + eor v17.16b,v17.16b,v17.16b + add w3,w3,w12 + add w4,w4,w15 + and w12,w9,w8 + mov v17.d[1],v19.d[0] + bic w15,w10,w8 + eor w11,w8,w8,ror#5 + add w4,w4,w14 + add v1.4s,v1.4s,v17.4s + orr w12,w12,w15 + eor w11,w11,w8,ror#19 + eor w15,w4,w4,ror#11 + add v4.4s,v4.4s,v1.4s + add w3,w3,w12 + ror w11,w11,#6 + eor w14,w4,w5 + eor w15,w15,w4,ror#20 + add w3,w3,w11 + ldr w12,[sp,#32] + and w13,w13,w14 + ror w15,w15,#2 + add w7,w7,w3 + eor w13,w13,w5 + st1 {v4.4s},[x17], #16 + ext v4.16b,v2.16b,v3.16b,#4 + add w10,w10,w12 + add w3,w3,w15 + and w12,w8,w7 + bic w15,w9,w7 + ext v7.16b,v0.16b,v1.16b,#4 + eor w11,w7,w7,ror#5 + add w3,w3,w13 + mov d19,v1.d[1] + orr w12,w12,w15 + eor w11,w11,w7,ror#19 + ushr v6.4s,v4.4s,#7 + eor w15,w3,w3,ror#11 + ushr v5.4s,v4.4s,#3 + add w10,w10,w12 + add v2.4s,v2.4s,v7.4s + ror w11,w11,#6 + sli v6.4s,v4.4s,#25 + eor w13,w3,w4 + eor w15,w15,w3,ror#20 + ushr v7.4s,v4.4s,#18 + add w10,w10,w11 + ldr w12,[sp,#36] + and w14,w14,w13 + eor v5.16b,v5.16b,v6.16b + ror w15,w15,#2 + add w6,w6,w10 + sli v7.4s,v4.4s,#14 + eor w14,w14,w4 + ushr v16.4s,v19.4s,#17 + add w9,w9,w12 + add w10,w10,w15 + and w12,w7,w6 + eor v5.16b,v5.16b,v7.16b + bic w15,w8,w6 + eor w11,w6,w6,ror#5 + sli v16.4s,v19.4s,#15 + add w10,w10,w14 + orr w12,w12,w15 + ushr v17.4s,v19.4s,#10 + eor w11,w11,w6,ror#19 + eor w15,w10,w10,ror#11 + ushr v7.4s,v19.4s,#19 + add w9,w9,w12 + ror w11,w11,#6 + add v2.4s,v2.4s,v5.4s + eor w14,w10,w3 + eor w15,w15,w10,ror#20 + sli v7.4s,v19.4s,#13 + add w9,w9,w11 + ldr w12,[sp,#40] + and w13,w13,w14 + eor v17.16b,v17.16b,v16.16b + ror w15,w15,#2 + add w5,w5,w9 + eor w13,w13,w3 + eor v17.16b,v17.16b,v7.16b + add w8,w8,w12 + add w9,w9,w15 + and w12,w6,w5 + add v2.4s,v2.4s,v17.4s + bic w15,w7,w5 + eor w11,w5,w5,ror#5 + add w9,w9,w13 + ushr v18.4s,v2.4s,#17 + orr w12,w12,w15 + ushr v19.4s,v2.4s,#10 + eor w11,w11,w5,ror#19 + eor w15,w9,w9,ror#11 + sli v18.4s,v2.4s,#15 + add w8,w8,w12 + ushr v17.4s,v2.4s,#19 + ror w11,w11,#6 + eor w13,w9,w10 + eor v19.16b,v19.16b,v18.16b + eor w15,w15,w9,ror#20 + add w8,w8,w11 + sli v17.4s,v2.4s,#13 + ldr w12,[sp,#44] + and w14,w14,w13 + ror w15,w15,#2 + ld1 {v4.4s},[x16], #16 + add w4,w4,w8 + eor v19.16b,v19.16b,v17.16b + eor w14,w14,w10 + eor v17.16b,v17.16b,v17.16b + add w7,w7,w12 + add w8,w8,w15 + and w12,w5,w4 + mov v17.d[1],v19.d[0] + bic w15,w6,w4 + eor w11,w4,w4,ror#5 + add w8,w8,w14 + add v2.4s,v2.4s,v17.4s + orr w12,w12,w15 + eor w11,w11,w4,ror#19 + eor w15,w8,w8,ror#11 + add v4.4s,v4.4s,v2.4s + add w7,w7,w12 + ror w11,w11,#6 + eor w14,w8,w9 + eor w15,w15,w8,ror#20 + add w7,w7,w11 + ldr w12,[sp,#48] + and w13,w13,w14 + ror w15,w15,#2 + add w3,w3,w7 + eor w13,w13,w9 + st1 {v4.4s},[x17], #16 + ext v4.16b,v3.16b,v0.16b,#4 + add w6,w6,w12 + add w7,w7,w15 + and w12,w4,w3 + bic w15,w5,w3 + ext v7.16b,v1.16b,v2.16b,#4 + eor w11,w3,w3,ror#5 + add w7,w7,w13 + mov d19,v2.d[1] + orr w12,w12,w15 + eor w11,w11,w3,ror#19 + ushr v6.4s,v4.4s,#7 + eor w15,w7,w7,ror#11 + ushr v5.4s,v4.4s,#3 + add w6,w6,w12 + add v3.4s,v3.4s,v7.4s + ror w11,w11,#6 + sli v6.4s,v4.4s,#25 + eor w13,w7,w8 + eor w15,w15,w7,ror#20 + ushr v7.4s,v4.4s,#18 + add w6,w6,w11 + ldr w12,[sp,#52] + and w14,w14,w13 + eor v5.16b,v5.16b,v6.16b + ror w15,w15,#2 + add w10,w10,w6 + sli v7.4s,v4.4s,#14 + eor w14,w14,w8 + ushr v16.4s,v19.4s,#17 + add w5,w5,w12 + add w6,w6,w15 + and w12,w3,w10 + eor v5.16b,v5.16b,v7.16b + bic w15,w4,w10 + eor w11,w10,w10,ror#5 + sli v16.4s,v19.4s,#15 + add w6,w6,w14 + orr w12,w12,w15 + ushr v17.4s,v19.4s,#10 + eor w11,w11,w10,ror#19 + eor w15,w6,w6,ror#11 + ushr v7.4s,v19.4s,#19 + add w5,w5,w12 + ror w11,w11,#6 + add v3.4s,v3.4s,v5.4s + eor w14,w6,w7 + eor w15,w15,w6,ror#20 + sli v7.4s,v19.4s,#13 + add w5,w5,w11 + ldr w12,[sp,#56] + and w13,w13,w14 + eor v17.16b,v17.16b,v16.16b + ror w15,w15,#2 + add w9,w9,w5 + eor w13,w13,w7 + eor v17.16b,v17.16b,v7.16b + add w4,w4,w12 + add w5,w5,w15 + and w12,w10,w9 + add v3.4s,v3.4s,v17.4s + bic w15,w3,w9 + eor w11,w9,w9,ror#5 + add w5,w5,w13 + ushr v18.4s,v3.4s,#17 + orr w12,w12,w15 + ushr v19.4s,v3.4s,#10 + eor w11,w11,w9,ror#19 + eor w15,w5,w5,ror#11 + sli v18.4s,v3.4s,#15 + add w4,w4,w12 + ushr v17.4s,v3.4s,#19 + ror w11,w11,#6 + eor w13,w5,w6 + eor v19.16b,v19.16b,v18.16b + eor w15,w15,w5,ror#20 + add w4,w4,w11 + sli v17.4s,v3.4s,#13 + ldr w12,[sp,#60] + and w14,w14,w13 + ror w15,w15,#2 + ld1 {v4.4s},[x16], #16 + add w8,w8,w4 + eor v19.16b,v19.16b,v17.16b + eor w14,w14,w6 + eor v17.16b,v17.16b,v17.16b + add w3,w3,w12 + add w4,w4,w15 + and w12,w9,w8 + mov v17.d[1],v19.d[0] + bic w15,w10,w8 + eor w11,w8,w8,ror#5 + add w4,w4,w14 + add v3.4s,v3.4s,v17.4s + orr w12,w12,w15 + eor w11,w11,w8,ror#19 + eor w15,w4,w4,ror#11 + add v4.4s,v4.4s,v3.4s + add w3,w3,w12 + ror w11,w11,#6 + eor w14,w4,w5 + eor w15,w15,w4,ror#20 + add w3,w3,w11 + ldr w12,[x16] + and w13,w13,w14 + ror w15,w15,#2 + add w7,w7,w3 + eor w13,w13,w5 + st1 {v4.4s},[x17], #16 + cmp w12,#0 // check for K256 terminator + ldr w12,[sp,#0] + sub x17,x17,#64 + bne .L_00_48 + + sub x16,x16,#256 // rewind x16 + cmp x1,x2 + mov x17, #64 + csel x17, x17, xzr, eq + sub x1,x1,x17 // avoid SEGV + mov x17,sp + add w10,w10,w12 + add w3,w3,w15 + and w12,w8,w7 + ld1 {v0.16b},[x1],#16 + bic w15,w9,w7 + eor w11,w7,w7,ror#5 + ld1 {v4.4s},[x16],#16 + add w3,w3,w13 + orr w12,w12,w15 + eor w11,w11,w7,ror#19 + eor w15,w3,w3,ror#11 + rev32 v0.16b,v0.16b + add w10,w10,w12 + ror w11,w11,#6 + eor w13,w3,w4 + eor w15,w15,w3,ror#20 + add v4.4s,v4.4s,v0.4s + add w10,w10,w11 + ldr w12,[sp,#4] + and w14,w14,w13 + ror w15,w15,#2 + add w6,w6,w10 + eor w14,w14,w4 + add w9,w9,w12 + add w10,w10,w15 + and w12,w7,w6 + bic w15,w8,w6 + eor w11,w6,w6,ror#5 + add w10,w10,w14 + orr w12,w12,w15 + eor w11,w11,w6,ror#19 + eor w15,w10,w10,ror#11 + add w9,w9,w12 + ror w11,w11,#6 + eor w14,w10,w3 + eor w15,w15,w10,ror#20 + add w9,w9,w11 + ldr w12,[sp,#8] + and w13,w13,w14 + ror w15,w15,#2 + add w5,w5,w9 + eor w13,w13,w3 + add w8,w8,w12 + add w9,w9,w15 + and w12,w6,w5 + bic w15,w7,w5 + eor w11,w5,w5,ror#5 + add w9,w9,w13 + orr w12,w12,w15 + eor w11,w11,w5,ror#19 + eor w15,w9,w9,ror#11 + add w8,w8,w12 + ror w11,w11,#6 + eor w13,w9,w10 + eor w15,w15,w9,ror#20 + add w8,w8,w11 + ldr w12,[sp,#12] + and w14,w14,w13 + ror w15,w15,#2 + add w4,w4,w8 + eor w14,w14,w10 + add w7,w7,w12 + add w8,w8,w15 + and w12,w5,w4 + bic w15,w6,w4 + eor w11,w4,w4,ror#5 + add w8,w8,w14 + orr w12,w12,w15 + eor w11,w11,w4,ror#19 + eor w15,w8,w8,ror#11 + add w7,w7,w12 + ror w11,w11,#6 + eor w14,w8,w9 + eor w15,w15,w8,ror#20 + add w7,w7,w11 + ldr w12,[sp,#16] + and w13,w13,w14 + ror w15,w15,#2 + add w3,w3,w7 + eor w13,w13,w9 + st1 {v4.4s},[x17], #16 + add w6,w6,w12 + add w7,w7,w15 + and w12,w4,w3 + ld1 {v1.16b},[x1],#16 + bic w15,w5,w3 + eor w11,w3,w3,ror#5 + ld1 {v4.4s},[x16],#16 + add w7,w7,w13 + orr w12,w12,w15 + eor w11,w11,w3,ror#19 + eor w15,w7,w7,ror#11 + rev32 v1.16b,v1.16b + add w6,w6,w12 + ror w11,w11,#6 + eor w13,w7,w8 + eor w15,w15,w7,ror#20 + add v4.4s,v4.4s,v1.4s + add w6,w6,w11 + ldr w12,[sp,#20] + and w14,w14,w13 + ror w15,w15,#2 + add w10,w10,w6 + eor w14,w14,w8 + add w5,w5,w12 + add w6,w6,w15 + and w12,w3,w10 + bic w15,w4,w10 + eor w11,w10,w10,ror#5 + add w6,w6,w14 + orr w12,w12,w15 + eor w11,w11,w10,ror#19 + eor w15,w6,w6,ror#11 + add w5,w5,w12 + ror w11,w11,#6 + eor w14,w6,w7 + eor w15,w15,w6,ror#20 + add w5,w5,w11 + ldr w12,[sp,#24] + and w13,w13,w14 + ror w15,w15,#2 + add w9,w9,w5 + eor w13,w13,w7 + add w4,w4,w12 + add w5,w5,w15 + and w12,w10,w9 + bic w15,w3,w9 + eor w11,w9,w9,ror#5 + add w5,w5,w13 + orr w12,w12,w15 + eor w11,w11,w9,ror#19 + eor w15,w5,w5,ror#11 + add w4,w4,w12 + ror w11,w11,#6 + eor w13,w5,w6 + eor w15,w15,w5,ror#20 + add w4,w4,w11 + ldr w12,[sp,#28] + and w14,w14,w13 + ror w15,w15,#2 + add w8,w8,w4 + eor w14,w14,w6 + add w3,w3,w12 + add w4,w4,w15 + and w12,w9,w8 + bic w15,w10,w8 + eor w11,w8,w8,ror#5 + add w4,w4,w14 + orr w12,w12,w15 + eor w11,w11,w8,ror#19 + eor w15,w4,w4,ror#11 + add w3,w3,w12 + ror w11,w11,#6 + eor w14,w4,w5 + eor w15,w15,w4,ror#20 + add w3,w3,w11 + ldr w12,[sp,#32] + and w13,w13,w14 + ror w15,w15,#2 + add w7,w7,w3 + eor w13,w13,w5 + st1 {v4.4s},[x17], #16 + add w10,w10,w12 + add w3,w3,w15 + and w12,w8,w7 + ld1 {v2.16b},[x1],#16 + bic w15,w9,w7 + eor w11,w7,w7,ror#5 + ld1 {v4.4s},[x16],#16 + add w3,w3,w13 + orr w12,w12,w15 + eor w11,w11,w7,ror#19 + eor w15,w3,w3,ror#11 + rev32 v2.16b,v2.16b + add w10,w10,w12 + ror w11,w11,#6 + eor w13,w3,w4 + eor w15,w15,w3,ror#20 + add v4.4s,v4.4s,v2.4s + add w10,w10,w11 + ldr w12,[sp,#36] + and w14,w14,w13 + ror w15,w15,#2 + add w6,w6,w10 + eor w14,w14,w4 + add w9,w9,w12 + add w10,w10,w15 + and w12,w7,w6 + bic w15,w8,w6 + eor w11,w6,w6,ror#5 + add w10,w10,w14 + orr w12,w12,w15 + eor w11,w11,w6,ror#19 + eor w15,w10,w10,ror#11 + add w9,w9,w12 + ror w11,w11,#6 + eor w14,w10,w3 + eor w15,w15,w10,ror#20 + add w9,w9,w11 + ldr w12,[sp,#40] + and w13,w13,w14 + ror w15,w15,#2 + add w5,w5,w9 + eor w13,w13,w3 + add w8,w8,w12 + add w9,w9,w15 + and w12,w6,w5 + bic w15,w7,w5 + eor w11,w5,w5,ror#5 + add w9,w9,w13 + orr w12,w12,w15 + eor w11,w11,w5,ror#19 + eor w15,w9,w9,ror#11 + add w8,w8,w12 + ror w11,w11,#6 + eor w13,w9,w10 + eor w15,w15,w9,ror#20 + add w8,w8,w11 + ldr w12,[sp,#44] + and w14,w14,w13 + ror w15,w15,#2 + add w4,w4,w8 + eor w14,w14,w10 + add w7,w7,w12 + add w8,w8,w15 + and w12,w5,w4 + bic w15,w6,w4 + eor w11,w4,w4,ror#5 + add w8,w8,w14 + orr w12,w12,w15 + eor w11,w11,w4,ror#19 + eor w15,w8,w8,ror#11 + add w7,w7,w12 + ror w11,w11,#6 + eor w14,w8,w9 + eor w15,w15,w8,ror#20 + add w7,w7,w11 + ldr w12,[sp,#48] + and w13,w13,w14 + ror w15,w15,#2 + add w3,w3,w7 + eor w13,w13,w9 + st1 {v4.4s},[x17], #16 + add w6,w6,w12 + add w7,w7,w15 + and w12,w4,w3 + ld1 {v3.16b},[x1],#16 + bic w15,w5,w3 + eor w11,w3,w3,ror#5 + ld1 {v4.4s},[x16],#16 + add w7,w7,w13 + orr w12,w12,w15 + eor w11,w11,w3,ror#19 + eor w15,w7,w7,ror#11 + rev32 v3.16b,v3.16b + add w6,w6,w12 + ror w11,w11,#6 + eor w13,w7,w8 + eor w15,w15,w7,ror#20 + add v4.4s,v4.4s,v3.4s + add w6,w6,w11 + ldr w12,[sp,#52] + and w14,w14,w13 + ror w15,w15,#2 + add w10,w10,w6 + eor w14,w14,w8 + add w5,w5,w12 + add w6,w6,w15 + and w12,w3,w10 + bic w15,w4,w10 + eor w11,w10,w10,ror#5 + add w6,w6,w14 + orr w12,w12,w15 + eor w11,w11,w10,ror#19 + eor w15,w6,w6,ror#11 + add w5,w5,w12 + ror w11,w11,#6 + eor w14,w6,w7 + eor w15,w15,w6,ror#20 + add w5,w5,w11 + ldr w12,[sp,#56] + and w13,w13,w14 + ror w15,w15,#2 + add w9,w9,w5 + eor w13,w13,w7 + add w4,w4,w12 + add w5,w5,w15 + and w12,w10,w9 + bic w15,w3,w9 + eor w11,w9,w9,ror#5 + add w5,w5,w13 + orr w12,w12,w15 + eor w11,w11,w9,ror#19 + eor w15,w5,w5,ror#11 + add w4,w4,w12 + ror w11,w11,#6 + eor w13,w5,w6 + eor w15,w15,w5,ror#20 + add w4,w4,w11 + ldr w12,[sp,#60] + and w14,w14,w13 + ror w15,w15,#2 + add w8,w8,w4 + eor w14,w14,w6 + add w3,w3,w12 + add w4,w4,w15 + and w12,w9,w8 + bic w15,w10,w8 + eor w11,w8,w8,ror#5 + add w4,w4,w14 + orr w12,w12,w15 + eor w11,w11,w8,ror#19 + eor w15,w4,w4,ror#11 + add w3,w3,w12 + ror w11,w11,#6 + eor w14,w4,w5 + eor w15,w15,w4,ror#20 + add w3,w3,w11 + and w13,w13,w14 + ror w15,w15,#2 + add w7,w7,w3 + eor w13,w13,w5 + st1 {v4.4s},[x17], #16 + add w3,w3,w15 // h+=Sigma0(a) from the past + ldp w11,w12,[x0,#0] + add w3,w3,w13 // h+=Maj(a,b,c) from the past + ldp w13,w14,[x0,#8] + add w3,w3,w11 // accumulate + add w4,w4,w12 + ldp w11,w12,[x0,#16] + add w5,w5,w13 + add w6,w6,w14 + ldp w13,w14,[x0,#24] + add w7,w7,w11 + add w8,w8,w12 + ldr w12,[sp,#0] + stp w3,w4,[x0,#0] + add w9,w9,w13 + mov w13,wzr + stp w5,w6,[x0,#8] + add w10,w10,w14 + stp w7,w8,[x0,#16] + eor w14,w4,w5 + stp w9,w10,[x0,#24] + mov w15,wzr + mov x17,sp + b.ne .L_00_48 + + ldr x29,[x29] + add sp,sp,#16*4+16 + ret +.size sha256_block_neon,.-sha256_block_neon diff --git a/crypto/openssl/crypto/sha/sha256-mb-x86_64.S b/crypto/openssl/crypto/sha/sha256-mb-x86_64.S new file mode 100644 index 000000000000..8ac342f9ceb6 --- /dev/null +++ b/crypto/openssl/crypto/sha/sha256-mb-x86_64.S @@ -0,0 +1,8005 @@ +.text + + + +.globl sha256_multi_block +.type sha256_multi_block,@function +.align 32 +sha256_multi_block: +.cfi_startproc + movq OPENSSL_ia32cap_P+4(%rip),%rcx + btq $61,%rcx + jc _shaext_shortcut + testl $268435456,%ecx + jnz _avx_shortcut + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + subq $288,%rsp + andq $-256,%rsp + movq %rax,272(%rsp) +.cfi_escape 0x0f,0x06,0x77,0x90,0x02,0x06,0x23,0x08 +.Lbody: + leaq K256+128(%rip),%rbp + leaq 256(%rsp),%rbx + leaq 128(%rdi),%rdi + +.Loop_grande: + movl %edx,280(%rsp) + xorl %edx,%edx + + movq 0(%rsi),%r8 + + movl 8(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,0(%rbx) + cmovleq %rbp,%r8 + + movq 16(%rsi),%r9 + + movl 24(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,4(%rbx) + cmovleq %rbp,%r9 + + movq 32(%rsi),%r10 + + movl 40(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,8(%rbx) + cmovleq %rbp,%r10 + + movq 48(%rsi),%r11 + + movl 56(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,12(%rbx) + cmovleq %rbp,%r11 + testl %edx,%edx + jz .Ldone + + movdqu 0-128(%rdi),%xmm8 + leaq 128(%rsp),%rax + movdqu 32-128(%rdi),%xmm9 + movdqu 64-128(%rdi),%xmm10 + movdqu 96-128(%rdi),%xmm11 + movdqu 128-128(%rdi),%xmm12 + movdqu 160-128(%rdi),%xmm13 + movdqu 192-128(%rdi),%xmm14 + movdqu 224-128(%rdi),%xmm15 + movdqu .Lpbswap(%rip),%xmm6 + jmp .Loop + +.align 32 +.Loop: + movdqa %xmm10,%xmm4 + pxor %xmm9,%xmm4 + movd 0(%r8),%xmm5 + movd 0(%r9),%xmm0 + movd 0(%r10),%xmm1 + movd 0(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm12,%xmm7 +.byte 102,15,56,0,238 + movdqa %xmm12,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm12,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,0-128(%rax) + paddd %xmm15,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -128(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm12,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm12,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm14,%xmm0 + pand %xmm13,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm8,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm8,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm9,%xmm3 + movdqa %xmm8,%xmm7 + pslld $10,%xmm2 + pxor %xmm8,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm9,%xmm15 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm15 + paddd %xmm5,%xmm11 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm15 + paddd %xmm7,%xmm15 + movd 4(%r8),%xmm5 + movd 4(%r9),%xmm0 + movd 4(%r10),%xmm1 + movd 4(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm11,%xmm7 + + movdqa %xmm11,%xmm2 +.byte 102,15,56,0,238 + psrld $6,%xmm7 + movdqa %xmm11,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,16-128(%rax) + paddd %xmm14,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -96(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm11,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm11,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm13,%xmm0 + pand %xmm12,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm15,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm15,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm4,%xmm0 + movdqa %xmm8,%xmm4 + movdqa %xmm15,%xmm7 + pslld $10,%xmm2 + pxor %xmm15,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm8,%xmm14 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm14 + paddd %xmm5,%xmm10 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm14 + paddd %xmm7,%xmm14 + movd 8(%r8),%xmm5 + movd 8(%r9),%xmm0 + movd 8(%r10),%xmm1 + movd 8(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm10,%xmm7 +.byte 102,15,56,0,238 + movdqa %xmm10,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm10,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,32-128(%rax) + paddd %xmm13,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -64(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm10,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm10,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm12,%xmm0 + pand %xmm11,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm14,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm14,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm15,%xmm3 + movdqa %xmm14,%xmm7 + pslld $10,%xmm2 + pxor %xmm14,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm15,%xmm13 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm13 + paddd %xmm5,%xmm9 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm13 + paddd %xmm7,%xmm13 + movd 12(%r8),%xmm5 + movd 12(%r9),%xmm0 + movd 12(%r10),%xmm1 + movd 12(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm9,%xmm7 + + movdqa %xmm9,%xmm2 +.byte 102,15,56,0,238 + psrld $6,%xmm7 + movdqa %xmm9,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,48-128(%rax) + paddd %xmm12,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -32(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm9,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm9,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm11,%xmm0 + pand %xmm10,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm13,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm13,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm4,%xmm0 + movdqa %xmm14,%xmm4 + movdqa %xmm13,%xmm7 + pslld $10,%xmm2 + pxor %xmm13,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm14,%xmm12 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm12 + paddd %xmm5,%xmm8 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm12 + paddd %xmm7,%xmm12 + movd 16(%r8),%xmm5 + movd 16(%r9),%xmm0 + movd 16(%r10),%xmm1 + movd 16(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm8,%xmm7 +.byte 102,15,56,0,238 + movdqa %xmm8,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm8,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,64-128(%rax) + paddd %xmm11,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 0(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm8,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm8,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm10,%xmm0 + pand %xmm9,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm12,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm12,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm13,%xmm3 + movdqa %xmm12,%xmm7 + pslld $10,%xmm2 + pxor %xmm12,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm13,%xmm11 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm11 + paddd %xmm5,%xmm15 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm11 + paddd %xmm7,%xmm11 + movd 20(%r8),%xmm5 + movd 20(%r9),%xmm0 + movd 20(%r10),%xmm1 + movd 20(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm15,%xmm7 + + movdqa %xmm15,%xmm2 +.byte 102,15,56,0,238 + psrld $6,%xmm7 + movdqa %xmm15,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,80-128(%rax) + paddd %xmm10,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 32(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm15,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm15,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm9,%xmm0 + pand %xmm8,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm11,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm11,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm4,%xmm0 + movdqa %xmm12,%xmm4 + movdqa %xmm11,%xmm7 + pslld $10,%xmm2 + pxor %xmm11,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm12,%xmm10 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm10 + paddd %xmm5,%xmm14 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm10 + paddd %xmm7,%xmm10 + movd 24(%r8),%xmm5 + movd 24(%r9),%xmm0 + movd 24(%r10),%xmm1 + movd 24(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm14,%xmm7 +.byte 102,15,56,0,238 + movdqa %xmm14,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm14,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,96-128(%rax) + paddd %xmm9,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 64(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm14,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm14,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm8,%xmm0 + pand %xmm15,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm10,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm10,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm11,%xmm3 + movdqa %xmm10,%xmm7 + pslld $10,%xmm2 + pxor %xmm10,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm11,%xmm9 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm9 + paddd %xmm5,%xmm13 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm9 + paddd %xmm7,%xmm9 + movd 28(%r8),%xmm5 + movd 28(%r9),%xmm0 + movd 28(%r10),%xmm1 + movd 28(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm13,%xmm7 + + movdqa %xmm13,%xmm2 +.byte 102,15,56,0,238 + psrld $6,%xmm7 + movdqa %xmm13,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,112-128(%rax) + paddd %xmm8,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 96(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm13,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm13,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm15,%xmm0 + pand %xmm14,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm9,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm9,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm4,%xmm0 + movdqa %xmm10,%xmm4 + movdqa %xmm9,%xmm7 + pslld $10,%xmm2 + pxor %xmm9,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm10,%xmm8 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm8 + paddd %xmm5,%xmm12 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm8 + paddd %xmm7,%xmm8 + leaq 256(%rbp),%rbp + movd 32(%r8),%xmm5 + movd 32(%r9),%xmm0 + movd 32(%r10),%xmm1 + movd 32(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm12,%xmm7 +.byte 102,15,56,0,238 + movdqa %xmm12,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm12,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,128-128(%rax) + paddd %xmm15,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -128(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm12,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm12,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm14,%xmm0 + pand %xmm13,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm8,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm8,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm9,%xmm3 + movdqa %xmm8,%xmm7 + pslld $10,%xmm2 + pxor %xmm8,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm9,%xmm15 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm15 + paddd %xmm5,%xmm11 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm15 + paddd %xmm7,%xmm15 + movd 36(%r8),%xmm5 + movd 36(%r9),%xmm0 + movd 36(%r10),%xmm1 + movd 36(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm11,%xmm7 + + movdqa %xmm11,%xmm2 +.byte 102,15,56,0,238 + psrld $6,%xmm7 + movdqa %xmm11,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,144-128(%rax) + paddd %xmm14,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -96(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm11,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm11,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm13,%xmm0 + pand %xmm12,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm15,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm15,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm4,%xmm0 + movdqa %xmm8,%xmm4 + movdqa %xmm15,%xmm7 + pslld $10,%xmm2 + pxor %xmm15,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm8,%xmm14 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm14 + paddd %xmm5,%xmm10 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm14 + paddd %xmm7,%xmm14 + movd 40(%r8),%xmm5 + movd 40(%r9),%xmm0 + movd 40(%r10),%xmm1 + movd 40(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm10,%xmm7 +.byte 102,15,56,0,238 + movdqa %xmm10,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm10,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,160-128(%rax) + paddd %xmm13,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -64(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm10,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm10,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm12,%xmm0 + pand %xmm11,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm14,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm14,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm15,%xmm3 + movdqa %xmm14,%xmm7 + pslld $10,%xmm2 + pxor %xmm14,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm15,%xmm13 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm13 + paddd %xmm5,%xmm9 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm13 + paddd %xmm7,%xmm13 + movd 44(%r8),%xmm5 + movd 44(%r9),%xmm0 + movd 44(%r10),%xmm1 + movd 44(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm9,%xmm7 + + movdqa %xmm9,%xmm2 +.byte 102,15,56,0,238 + psrld $6,%xmm7 + movdqa %xmm9,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,176-128(%rax) + paddd %xmm12,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -32(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm9,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm9,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm11,%xmm0 + pand %xmm10,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm13,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm13,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm4,%xmm0 + movdqa %xmm14,%xmm4 + movdqa %xmm13,%xmm7 + pslld $10,%xmm2 + pxor %xmm13,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm14,%xmm12 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm12 + paddd %xmm5,%xmm8 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm12 + paddd %xmm7,%xmm12 + movd 48(%r8),%xmm5 + movd 48(%r9),%xmm0 + movd 48(%r10),%xmm1 + movd 48(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm8,%xmm7 +.byte 102,15,56,0,238 + movdqa %xmm8,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm8,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,192-128(%rax) + paddd %xmm11,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 0(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm8,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm8,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm10,%xmm0 + pand %xmm9,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm12,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm12,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm13,%xmm3 + movdqa %xmm12,%xmm7 + pslld $10,%xmm2 + pxor %xmm12,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm13,%xmm11 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm11 + paddd %xmm5,%xmm15 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm11 + paddd %xmm7,%xmm11 + movd 52(%r8),%xmm5 + movd 52(%r9),%xmm0 + movd 52(%r10),%xmm1 + movd 52(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm15,%xmm7 + + movdqa %xmm15,%xmm2 +.byte 102,15,56,0,238 + psrld $6,%xmm7 + movdqa %xmm15,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,208-128(%rax) + paddd %xmm10,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 32(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm15,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm15,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm9,%xmm0 + pand %xmm8,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm11,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm11,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm4,%xmm0 + movdqa %xmm12,%xmm4 + movdqa %xmm11,%xmm7 + pslld $10,%xmm2 + pxor %xmm11,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm12,%xmm10 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm10 + paddd %xmm5,%xmm14 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm10 + paddd %xmm7,%xmm10 + movd 56(%r8),%xmm5 + movd 56(%r9),%xmm0 + movd 56(%r10),%xmm1 + movd 56(%r11),%xmm2 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm14,%xmm7 +.byte 102,15,56,0,238 + movdqa %xmm14,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm14,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,224-128(%rax) + paddd %xmm9,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 64(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm14,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm14,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm8,%xmm0 + pand %xmm15,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm10,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm10,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm11,%xmm3 + movdqa %xmm10,%xmm7 + pslld $10,%xmm2 + pxor %xmm10,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm11,%xmm9 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm9 + paddd %xmm5,%xmm13 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm9 + paddd %xmm7,%xmm9 + movd 60(%r8),%xmm5 + leaq 64(%r8),%r8 + movd 60(%r9),%xmm0 + leaq 64(%r9),%r9 + movd 60(%r10),%xmm1 + leaq 64(%r10),%r10 + movd 60(%r11),%xmm2 + leaq 64(%r11),%r11 + punpckldq %xmm1,%xmm5 + punpckldq %xmm2,%xmm0 + punpckldq %xmm0,%xmm5 + movdqa %xmm13,%xmm7 + + movdqa %xmm13,%xmm2 +.byte 102,15,56,0,238 + psrld $6,%xmm7 + movdqa %xmm13,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,240-128(%rax) + paddd %xmm8,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 96(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm13,%xmm0 + prefetcht0 63(%r8) + pxor %xmm2,%xmm7 + movdqa %xmm13,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm15,%xmm0 + pand %xmm14,%xmm4 + pxor %xmm1,%xmm7 + + prefetcht0 63(%r9) + movdqa %xmm9,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm9,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm4,%xmm0 + movdqa %xmm10,%xmm4 + movdqa %xmm9,%xmm7 + pslld $10,%xmm2 + pxor %xmm9,%xmm4 + + prefetcht0 63(%r10) + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + prefetcht0 63(%r11) + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm10,%xmm8 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm8 + paddd %xmm5,%xmm12 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm8 + paddd %xmm7,%xmm8 + leaq 256(%rbp),%rbp + movdqu 0-128(%rax),%xmm5 + movl $3,%ecx + jmp .Loop_16_xx +.align 32 +.Loop_16_xx: + movdqa 16-128(%rax),%xmm6 + paddd 144-128(%rax),%xmm5 + + movdqa %xmm6,%xmm7 + movdqa %xmm6,%xmm1 + psrld $3,%xmm7 + movdqa %xmm6,%xmm2 + + psrld $7,%xmm1 + movdqa 224-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm3 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm3,%xmm1 + + psrld $17,%xmm3 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + psrld $19-17,%xmm3 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm3,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm5 + movdqa %xmm12,%xmm7 + + movdqa %xmm12,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm12,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,0-128(%rax) + paddd %xmm15,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -128(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm12,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm12,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm14,%xmm0 + pand %xmm13,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm8,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm8,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm9,%xmm3 + movdqa %xmm8,%xmm7 + pslld $10,%xmm2 + pxor %xmm8,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm9,%xmm15 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm15 + paddd %xmm5,%xmm11 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm15 + paddd %xmm7,%xmm15 + movdqa 32-128(%rax),%xmm5 + paddd 160-128(%rax),%xmm6 + + movdqa %xmm5,%xmm7 + movdqa %xmm5,%xmm1 + psrld $3,%xmm7 + movdqa %xmm5,%xmm2 + + psrld $7,%xmm1 + movdqa 240-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm4 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm4,%xmm1 + + psrld $17,%xmm4 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + psrld $19-17,%xmm4 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm6 + movdqa %xmm11,%xmm7 + + movdqa %xmm11,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm11,%xmm1 + pslld $7,%xmm2 + movdqa %xmm6,16-128(%rax) + paddd %xmm14,%xmm6 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -96(%rbp),%xmm6 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm11,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm11,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm13,%xmm0 + pand %xmm12,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm15,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm15,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + movdqa %xmm8,%xmm4 + movdqa %xmm15,%xmm7 + pslld $10,%xmm2 + pxor %xmm15,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm6 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm8,%xmm14 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm14 + paddd %xmm6,%xmm10 + pxor %xmm2,%xmm7 + + paddd %xmm6,%xmm14 + paddd %xmm7,%xmm14 + movdqa 48-128(%rax),%xmm6 + paddd 176-128(%rax),%xmm5 + + movdqa %xmm6,%xmm7 + movdqa %xmm6,%xmm1 + psrld $3,%xmm7 + movdqa %xmm6,%xmm2 + + psrld $7,%xmm1 + movdqa 0-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm3 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm3,%xmm1 + + psrld $17,%xmm3 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + psrld $19-17,%xmm3 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm3,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm5 + movdqa %xmm10,%xmm7 + + movdqa %xmm10,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm10,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,32-128(%rax) + paddd %xmm13,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -64(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm10,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm10,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm12,%xmm0 + pand %xmm11,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm14,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm14,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm15,%xmm3 + movdqa %xmm14,%xmm7 + pslld $10,%xmm2 + pxor %xmm14,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm15,%xmm13 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm13 + paddd %xmm5,%xmm9 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm13 + paddd %xmm7,%xmm13 + movdqa 64-128(%rax),%xmm5 + paddd 192-128(%rax),%xmm6 + + movdqa %xmm5,%xmm7 + movdqa %xmm5,%xmm1 + psrld $3,%xmm7 + movdqa %xmm5,%xmm2 + + psrld $7,%xmm1 + movdqa 16-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm4 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm4,%xmm1 + + psrld $17,%xmm4 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + psrld $19-17,%xmm4 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm6 + movdqa %xmm9,%xmm7 + + movdqa %xmm9,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm9,%xmm1 + pslld $7,%xmm2 + movdqa %xmm6,48-128(%rax) + paddd %xmm12,%xmm6 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -32(%rbp),%xmm6 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm9,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm9,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm11,%xmm0 + pand %xmm10,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm13,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm13,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + movdqa %xmm14,%xmm4 + movdqa %xmm13,%xmm7 + pslld $10,%xmm2 + pxor %xmm13,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm6 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm14,%xmm12 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm12 + paddd %xmm6,%xmm8 + pxor %xmm2,%xmm7 + + paddd %xmm6,%xmm12 + paddd %xmm7,%xmm12 + movdqa 80-128(%rax),%xmm6 + paddd 208-128(%rax),%xmm5 + + movdqa %xmm6,%xmm7 + movdqa %xmm6,%xmm1 + psrld $3,%xmm7 + movdqa %xmm6,%xmm2 + + psrld $7,%xmm1 + movdqa 32-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm3 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm3,%xmm1 + + psrld $17,%xmm3 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + psrld $19-17,%xmm3 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm3,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm5 + movdqa %xmm8,%xmm7 + + movdqa %xmm8,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm8,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,64-128(%rax) + paddd %xmm11,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 0(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm8,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm8,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm10,%xmm0 + pand %xmm9,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm12,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm12,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm13,%xmm3 + movdqa %xmm12,%xmm7 + pslld $10,%xmm2 + pxor %xmm12,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm13,%xmm11 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm11 + paddd %xmm5,%xmm15 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm11 + paddd %xmm7,%xmm11 + movdqa 96-128(%rax),%xmm5 + paddd 224-128(%rax),%xmm6 + + movdqa %xmm5,%xmm7 + movdqa %xmm5,%xmm1 + psrld $3,%xmm7 + movdqa %xmm5,%xmm2 + + psrld $7,%xmm1 + movdqa 48-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm4 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm4,%xmm1 + + psrld $17,%xmm4 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + psrld $19-17,%xmm4 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm6 + movdqa %xmm15,%xmm7 + + movdqa %xmm15,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm15,%xmm1 + pslld $7,%xmm2 + movdqa %xmm6,80-128(%rax) + paddd %xmm10,%xmm6 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 32(%rbp),%xmm6 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm15,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm15,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm9,%xmm0 + pand %xmm8,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm11,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm11,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + movdqa %xmm12,%xmm4 + movdqa %xmm11,%xmm7 + pslld $10,%xmm2 + pxor %xmm11,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm6 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm12,%xmm10 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm10 + paddd %xmm6,%xmm14 + pxor %xmm2,%xmm7 + + paddd %xmm6,%xmm10 + paddd %xmm7,%xmm10 + movdqa 112-128(%rax),%xmm6 + paddd 240-128(%rax),%xmm5 + + movdqa %xmm6,%xmm7 + movdqa %xmm6,%xmm1 + psrld $3,%xmm7 + movdqa %xmm6,%xmm2 + + psrld $7,%xmm1 + movdqa 64-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm3 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm3,%xmm1 + + psrld $17,%xmm3 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + psrld $19-17,%xmm3 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm3,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm5 + movdqa %xmm14,%xmm7 + + movdqa %xmm14,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm14,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,96-128(%rax) + paddd %xmm9,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 64(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm14,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm14,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm8,%xmm0 + pand %xmm15,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm10,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm10,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm11,%xmm3 + movdqa %xmm10,%xmm7 + pslld $10,%xmm2 + pxor %xmm10,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm11,%xmm9 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm9 + paddd %xmm5,%xmm13 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm9 + paddd %xmm7,%xmm9 + movdqa 128-128(%rax),%xmm5 + paddd 0-128(%rax),%xmm6 + + movdqa %xmm5,%xmm7 + movdqa %xmm5,%xmm1 + psrld $3,%xmm7 + movdqa %xmm5,%xmm2 + + psrld $7,%xmm1 + movdqa 80-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm4 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm4,%xmm1 + + psrld $17,%xmm4 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + psrld $19-17,%xmm4 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm6 + movdqa %xmm13,%xmm7 + + movdqa %xmm13,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm13,%xmm1 + pslld $7,%xmm2 + movdqa %xmm6,112-128(%rax) + paddd %xmm8,%xmm6 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 96(%rbp),%xmm6 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm13,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm13,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm15,%xmm0 + pand %xmm14,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm9,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm9,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + movdqa %xmm10,%xmm4 + movdqa %xmm9,%xmm7 + pslld $10,%xmm2 + pxor %xmm9,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm6 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm10,%xmm8 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm8 + paddd %xmm6,%xmm12 + pxor %xmm2,%xmm7 + + paddd %xmm6,%xmm8 + paddd %xmm7,%xmm8 + leaq 256(%rbp),%rbp + movdqa 144-128(%rax),%xmm6 + paddd 16-128(%rax),%xmm5 + + movdqa %xmm6,%xmm7 + movdqa %xmm6,%xmm1 + psrld $3,%xmm7 + movdqa %xmm6,%xmm2 + + psrld $7,%xmm1 + movdqa 96-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm3 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm3,%xmm1 + + psrld $17,%xmm3 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + psrld $19-17,%xmm3 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm3,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm5 + movdqa %xmm12,%xmm7 + + movdqa %xmm12,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm12,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,128-128(%rax) + paddd %xmm15,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -128(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm12,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm12,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm14,%xmm0 + pand %xmm13,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm8,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm8,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm9,%xmm3 + movdqa %xmm8,%xmm7 + pslld $10,%xmm2 + pxor %xmm8,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm9,%xmm15 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm15 + paddd %xmm5,%xmm11 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm15 + paddd %xmm7,%xmm15 + movdqa 160-128(%rax),%xmm5 + paddd 32-128(%rax),%xmm6 + + movdqa %xmm5,%xmm7 + movdqa %xmm5,%xmm1 + psrld $3,%xmm7 + movdqa %xmm5,%xmm2 + + psrld $7,%xmm1 + movdqa 112-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm4 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm4,%xmm1 + + psrld $17,%xmm4 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + psrld $19-17,%xmm4 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm6 + movdqa %xmm11,%xmm7 + + movdqa %xmm11,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm11,%xmm1 + pslld $7,%xmm2 + movdqa %xmm6,144-128(%rax) + paddd %xmm14,%xmm6 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -96(%rbp),%xmm6 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm11,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm11,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm13,%xmm0 + pand %xmm12,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm15,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm15,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + movdqa %xmm8,%xmm4 + movdqa %xmm15,%xmm7 + pslld $10,%xmm2 + pxor %xmm15,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm6 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm8,%xmm14 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm14 + paddd %xmm6,%xmm10 + pxor %xmm2,%xmm7 + + paddd %xmm6,%xmm14 + paddd %xmm7,%xmm14 + movdqa 176-128(%rax),%xmm6 + paddd 48-128(%rax),%xmm5 + + movdqa %xmm6,%xmm7 + movdqa %xmm6,%xmm1 + psrld $3,%xmm7 + movdqa %xmm6,%xmm2 + + psrld $7,%xmm1 + movdqa 128-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm3 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm3,%xmm1 + + psrld $17,%xmm3 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + psrld $19-17,%xmm3 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm3,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm5 + movdqa %xmm10,%xmm7 + + movdqa %xmm10,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm10,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,160-128(%rax) + paddd %xmm13,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -64(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm10,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm10,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm12,%xmm0 + pand %xmm11,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm14,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm14,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm15,%xmm3 + movdqa %xmm14,%xmm7 + pslld $10,%xmm2 + pxor %xmm14,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm15,%xmm13 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm13 + paddd %xmm5,%xmm9 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm13 + paddd %xmm7,%xmm13 + movdqa 192-128(%rax),%xmm5 + paddd 64-128(%rax),%xmm6 + + movdqa %xmm5,%xmm7 + movdqa %xmm5,%xmm1 + psrld $3,%xmm7 + movdqa %xmm5,%xmm2 + + psrld $7,%xmm1 + movdqa 144-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm4 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm4,%xmm1 + + psrld $17,%xmm4 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + psrld $19-17,%xmm4 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm6 + movdqa %xmm9,%xmm7 + + movdqa %xmm9,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm9,%xmm1 + pslld $7,%xmm2 + movdqa %xmm6,176-128(%rax) + paddd %xmm12,%xmm6 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd -32(%rbp),%xmm6 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm9,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm9,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm11,%xmm0 + pand %xmm10,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm13,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm13,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + movdqa %xmm14,%xmm4 + movdqa %xmm13,%xmm7 + pslld $10,%xmm2 + pxor %xmm13,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm6 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm14,%xmm12 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm12 + paddd %xmm6,%xmm8 + pxor %xmm2,%xmm7 + + paddd %xmm6,%xmm12 + paddd %xmm7,%xmm12 + movdqa 208-128(%rax),%xmm6 + paddd 80-128(%rax),%xmm5 + + movdqa %xmm6,%xmm7 + movdqa %xmm6,%xmm1 + psrld $3,%xmm7 + movdqa %xmm6,%xmm2 + + psrld $7,%xmm1 + movdqa 160-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm3 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm3,%xmm1 + + psrld $17,%xmm3 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + psrld $19-17,%xmm3 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm3,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm5 + movdqa %xmm8,%xmm7 + + movdqa %xmm8,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm8,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,192-128(%rax) + paddd %xmm11,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 0(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm8,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm8,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm10,%xmm0 + pand %xmm9,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm12,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm12,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm13,%xmm3 + movdqa %xmm12,%xmm7 + pslld $10,%xmm2 + pxor %xmm12,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm13,%xmm11 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm11 + paddd %xmm5,%xmm15 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm11 + paddd %xmm7,%xmm11 + movdqa 224-128(%rax),%xmm5 + paddd 96-128(%rax),%xmm6 + + movdqa %xmm5,%xmm7 + movdqa %xmm5,%xmm1 + psrld $3,%xmm7 + movdqa %xmm5,%xmm2 + + psrld $7,%xmm1 + movdqa 176-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm4 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm4,%xmm1 + + psrld $17,%xmm4 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + psrld $19-17,%xmm4 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm6 + movdqa %xmm15,%xmm7 + + movdqa %xmm15,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm15,%xmm1 + pslld $7,%xmm2 + movdqa %xmm6,208-128(%rax) + paddd %xmm10,%xmm6 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 32(%rbp),%xmm6 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm15,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm15,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm9,%xmm0 + pand %xmm8,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm11,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm11,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + movdqa %xmm12,%xmm4 + movdqa %xmm11,%xmm7 + pslld $10,%xmm2 + pxor %xmm11,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm6 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm12,%xmm10 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm10 + paddd %xmm6,%xmm14 + pxor %xmm2,%xmm7 + + paddd %xmm6,%xmm10 + paddd %xmm7,%xmm10 + movdqa 240-128(%rax),%xmm6 + paddd 112-128(%rax),%xmm5 + + movdqa %xmm6,%xmm7 + movdqa %xmm6,%xmm1 + psrld $3,%xmm7 + movdqa %xmm6,%xmm2 + + psrld $7,%xmm1 + movdqa 192-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm3 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm3,%xmm1 + + psrld $17,%xmm3 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + psrld $19-17,%xmm3 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm3,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm5 + movdqa %xmm14,%xmm7 + + movdqa %xmm14,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm14,%xmm1 + pslld $7,%xmm2 + movdqa %xmm5,224-128(%rax) + paddd %xmm9,%xmm5 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 64(%rbp),%xmm5 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm14,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm14,%xmm3 + pslld $26-21,%xmm2 + pandn %xmm8,%xmm0 + pand %xmm15,%xmm3 + pxor %xmm1,%xmm7 + + + movdqa %xmm10,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm10,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm5 + pxor %xmm3,%xmm0 + movdqa %xmm11,%xmm3 + movdqa %xmm10,%xmm7 + pslld $10,%xmm2 + pxor %xmm10,%xmm3 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm5 + pslld $19-10,%xmm2 + pand %xmm3,%xmm4 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm11,%xmm9 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm4,%xmm9 + paddd %xmm5,%xmm13 + pxor %xmm2,%xmm7 + + paddd %xmm5,%xmm9 + paddd %xmm7,%xmm9 + movdqa 0-128(%rax),%xmm5 + paddd 128-128(%rax),%xmm6 + + movdqa %xmm5,%xmm7 + movdqa %xmm5,%xmm1 + psrld $3,%xmm7 + movdqa %xmm5,%xmm2 + + psrld $7,%xmm1 + movdqa 208-128(%rax),%xmm0 + pslld $14,%xmm2 + pxor %xmm1,%xmm7 + psrld $18-7,%xmm1 + movdqa %xmm0,%xmm4 + pxor %xmm2,%xmm7 + pslld $25-14,%xmm2 + pxor %xmm1,%xmm7 + psrld $10,%xmm0 + movdqa %xmm4,%xmm1 + + psrld $17,%xmm4 + pxor %xmm2,%xmm7 + pslld $13,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + psrld $19-17,%xmm4 + pxor %xmm1,%xmm0 + pslld $15-13,%xmm1 + pxor %xmm4,%xmm0 + pxor %xmm1,%xmm0 + paddd %xmm0,%xmm6 + movdqa %xmm13,%xmm7 + + movdqa %xmm13,%xmm2 + + psrld $6,%xmm7 + movdqa %xmm13,%xmm1 + pslld $7,%xmm2 + movdqa %xmm6,240-128(%rax) + paddd %xmm8,%xmm6 + + psrld $11,%xmm1 + pxor %xmm2,%xmm7 + pslld $21-7,%xmm2 + paddd 96(%rbp),%xmm6 + pxor %xmm1,%xmm7 + + psrld $25-11,%xmm1 + movdqa %xmm13,%xmm0 + + pxor %xmm2,%xmm7 + movdqa %xmm13,%xmm4 + pslld $26-21,%xmm2 + pandn %xmm15,%xmm0 + pand %xmm14,%xmm4 + pxor %xmm1,%xmm7 + + + movdqa %xmm9,%xmm1 + pxor %xmm2,%xmm7 + movdqa %xmm9,%xmm2 + psrld $2,%xmm1 + paddd %xmm7,%xmm6 + pxor %xmm4,%xmm0 + movdqa %xmm10,%xmm4 + movdqa %xmm9,%xmm7 + pslld $10,%xmm2 + pxor %xmm9,%xmm4 + + + psrld $13,%xmm7 + pxor %xmm2,%xmm1 + paddd %xmm0,%xmm6 + pslld $19-10,%xmm2 + pand %xmm4,%xmm3 + pxor %xmm7,%xmm1 + + + psrld $22-13,%xmm7 + pxor %xmm2,%xmm1 + movdqa %xmm10,%xmm8 + pslld $30-19,%xmm2 + pxor %xmm1,%xmm7 + pxor %xmm3,%xmm8 + paddd %xmm6,%xmm12 + pxor %xmm2,%xmm7 + + paddd %xmm6,%xmm8 + paddd %xmm7,%xmm8 + leaq 256(%rbp),%rbp + decl %ecx + jnz .Loop_16_xx + + movl $1,%ecx + leaq K256+128(%rip),%rbp + + movdqa (%rbx),%xmm7 + cmpl 0(%rbx),%ecx + pxor %xmm0,%xmm0 + cmovgeq %rbp,%r8 + cmpl 4(%rbx),%ecx + movdqa %xmm7,%xmm6 + cmovgeq %rbp,%r9 + cmpl 8(%rbx),%ecx + pcmpgtd %xmm0,%xmm6 + cmovgeq %rbp,%r10 + cmpl 12(%rbx),%ecx + paddd %xmm6,%xmm7 + cmovgeq %rbp,%r11 + + movdqu 0-128(%rdi),%xmm0 + pand %xmm6,%xmm8 + movdqu 32-128(%rdi),%xmm1 + pand %xmm6,%xmm9 + movdqu 64-128(%rdi),%xmm2 + pand %xmm6,%xmm10 + movdqu 96-128(%rdi),%xmm5 + pand %xmm6,%xmm11 + paddd %xmm0,%xmm8 + movdqu 128-128(%rdi),%xmm0 + pand %xmm6,%xmm12 + paddd %xmm1,%xmm9 + movdqu 160-128(%rdi),%xmm1 + pand %xmm6,%xmm13 + paddd %xmm2,%xmm10 + movdqu 192-128(%rdi),%xmm2 + pand %xmm6,%xmm14 + paddd %xmm5,%xmm11 + movdqu 224-128(%rdi),%xmm5 + pand %xmm6,%xmm15 + paddd %xmm0,%xmm12 + paddd %xmm1,%xmm13 + movdqu %xmm8,0-128(%rdi) + paddd %xmm2,%xmm14 + movdqu %xmm9,32-128(%rdi) + paddd %xmm5,%xmm15 + movdqu %xmm10,64-128(%rdi) + movdqu %xmm11,96-128(%rdi) + movdqu %xmm12,128-128(%rdi) + movdqu %xmm13,160-128(%rdi) + movdqu %xmm14,192-128(%rdi) + movdqu %xmm15,224-128(%rdi) + + movdqa %xmm7,(%rbx) + movdqa .Lpbswap(%rip),%xmm6 + decl %edx + jnz .Loop + + movl 280(%rsp),%edx + leaq 16(%rdi),%rdi + leaq 64(%rsi),%rsi + decl %edx + jnz .Loop_grande + +.Ldone: + movq 272(%rsp),%rax +.cfi_def_cfa %rax,8 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_multi_block,.-sha256_multi_block +.type sha256_multi_block_shaext,@function +.align 32 +sha256_multi_block_shaext: +.cfi_startproc +_shaext_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + subq $288,%rsp + shll $1,%edx + andq $-256,%rsp + leaq 128(%rdi),%rdi + movq %rax,272(%rsp) +.Lbody_shaext: + leaq 256(%rsp),%rbx + leaq K256_shaext+128(%rip),%rbp + +.Loop_grande_shaext: + movl %edx,280(%rsp) + xorl %edx,%edx + + movq 0(%rsi),%r8 + + movl 8(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,0(%rbx) + cmovleq %rsp,%r8 + + movq 16(%rsi),%r9 + + movl 24(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,4(%rbx) + cmovleq %rsp,%r9 + testl %edx,%edx + jz .Ldone_shaext + + movq 0-128(%rdi),%xmm12 + movq 32-128(%rdi),%xmm4 + movq 64-128(%rdi),%xmm13 + movq 96-128(%rdi),%xmm5 + movq 128-128(%rdi),%xmm8 + movq 160-128(%rdi),%xmm9 + movq 192-128(%rdi),%xmm10 + movq 224-128(%rdi),%xmm11 + + punpckldq %xmm4,%xmm12 + punpckldq %xmm5,%xmm13 + punpckldq %xmm9,%xmm8 + punpckldq %xmm11,%xmm10 + movdqa K256_shaext-16(%rip),%xmm3 + + movdqa %xmm12,%xmm14 + movdqa %xmm13,%xmm15 + punpcklqdq %xmm8,%xmm12 + punpcklqdq %xmm10,%xmm13 + punpckhqdq %xmm8,%xmm14 + punpckhqdq %xmm10,%xmm15 + + pshufd $27,%xmm12,%xmm12 + pshufd $27,%xmm13,%xmm13 + pshufd $27,%xmm14,%xmm14 + pshufd $27,%xmm15,%xmm15 + jmp .Loop_shaext + +.align 32 +.Loop_shaext: + movdqu 0(%r8),%xmm4 + movdqu 0(%r9),%xmm8 + movdqu 16(%r8),%xmm5 + movdqu 16(%r9),%xmm9 + movdqu 32(%r8),%xmm6 +.byte 102,15,56,0,227 + movdqu 32(%r9),%xmm10 +.byte 102,68,15,56,0,195 + movdqu 48(%r8),%xmm7 + leaq 64(%r8),%r8 + movdqu 48(%r9),%xmm11 + leaq 64(%r9),%r9 + + movdqa 0-128(%rbp),%xmm0 +.byte 102,15,56,0,235 + paddd %xmm4,%xmm0 + pxor %xmm12,%xmm4 + movdqa %xmm0,%xmm1 + movdqa 0-128(%rbp),%xmm2 +.byte 102,68,15,56,0,203 + paddd %xmm8,%xmm2 + movdqa %xmm13,80(%rsp) +.byte 69,15,56,203,236 + pxor %xmm14,%xmm8 + movdqa %xmm2,%xmm0 + movdqa %xmm15,112(%rsp) +.byte 69,15,56,203,254 + pshufd $0x0e,%xmm1,%xmm0 + pxor %xmm12,%xmm4 + movdqa %xmm12,64(%rsp) +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + pxor %xmm14,%xmm8 + movdqa %xmm14,96(%rsp) + movdqa 16-128(%rbp),%xmm1 + paddd %xmm5,%xmm1 +.byte 102,15,56,0,243 +.byte 69,15,56,203,247 + + movdqa %xmm1,%xmm0 + movdqa 16-128(%rbp),%xmm2 + paddd %xmm9,%xmm2 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + prefetcht0 127(%r8) +.byte 102,15,56,0,251 +.byte 102,68,15,56,0,211 + prefetcht0 127(%r9) +.byte 69,15,56,203,254 + pshufd $0x0e,%xmm1,%xmm0 +.byte 102,68,15,56,0,219 +.byte 15,56,204,229 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 32-128(%rbp),%xmm1 + paddd %xmm6,%xmm1 +.byte 69,15,56,203,247 + + movdqa %xmm1,%xmm0 + movdqa 32-128(%rbp),%xmm2 + paddd %xmm10,%xmm2 +.byte 69,15,56,203,236 +.byte 69,15,56,204,193 + movdqa %xmm2,%xmm0 + movdqa %xmm7,%xmm3 +.byte 69,15,56,203,254 + pshufd $0x0e,%xmm1,%xmm0 +.byte 102,15,58,15,222,4 + paddd %xmm3,%xmm4 + movdqa %xmm11,%xmm3 +.byte 102,65,15,58,15,218,4 +.byte 15,56,204,238 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 48-128(%rbp),%xmm1 + paddd %xmm7,%xmm1 +.byte 69,15,56,203,247 +.byte 69,15,56,204,202 + + movdqa %xmm1,%xmm0 + movdqa 48-128(%rbp),%xmm2 + paddd %xmm3,%xmm8 + paddd %xmm11,%xmm2 +.byte 15,56,205,231 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movdqa %xmm4,%xmm3 +.byte 102,15,58,15,223,4 +.byte 69,15,56,203,254 +.byte 69,15,56,205,195 + pshufd $0x0e,%xmm1,%xmm0 + paddd %xmm3,%xmm5 + movdqa %xmm8,%xmm3 +.byte 102,65,15,58,15,219,4 +.byte 15,56,204,247 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 64-128(%rbp),%xmm1 + paddd %xmm4,%xmm1 +.byte 69,15,56,203,247 +.byte 69,15,56,204,211 + movdqa %xmm1,%xmm0 + movdqa 64-128(%rbp),%xmm2 + paddd %xmm3,%xmm9 + paddd %xmm8,%xmm2 +.byte 15,56,205,236 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movdqa %xmm5,%xmm3 +.byte 102,15,58,15,220,4 +.byte 69,15,56,203,254 +.byte 69,15,56,205,200 + pshufd $0x0e,%xmm1,%xmm0 + paddd %xmm3,%xmm6 + movdqa %xmm9,%xmm3 +.byte 102,65,15,58,15,216,4 +.byte 15,56,204,252 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 80-128(%rbp),%xmm1 + paddd %xmm5,%xmm1 +.byte 69,15,56,203,247 +.byte 69,15,56,204,216 + movdqa %xmm1,%xmm0 + movdqa 80-128(%rbp),%xmm2 + paddd %xmm3,%xmm10 + paddd %xmm9,%xmm2 +.byte 15,56,205,245 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movdqa %xmm6,%xmm3 +.byte 102,15,58,15,221,4 +.byte 69,15,56,203,254 +.byte 69,15,56,205,209 + pshufd $0x0e,%xmm1,%xmm0 + paddd %xmm3,%xmm7 + movdqa %xmm10,%xmm3 +.byte 102,65,15,58,15,217,4 +.byte 15,56,204,229 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 96-128(%rbp),%xmm1 + paddd %xmm6,%xmm1 +.byte 69,15,56,203,247 +.byte 69,15,56,204,193 + movdqa %xmm1,%xmm0 + movdqa 96-128(%rbp),%xmm2 + paddd %xmm3,%xmm11 + paddd %xmm10,%xmm2 +.byte 15,56,205,254 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movdqa %xmm7,%xmm3 +.byte 102,15,58,15,222,4 +.byte 69,15,56,203,254 +.byte 69,15,56,205,218 + pshufd $0x0e,%xmm1,%xmm0 + paddd %xmm3,%xmm4 + movdqa %xmm11,%xmm3 +.byte 102,65,15,58,15,218,4 +.byte 15,56,204,238 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 112-128(%rbp),%xmm1 + paddd %xmm7,%xmm1 +.byte 69,15,56,203,247 +.byte 69,15,56,204,202 + movdqa %xmm1,%xmm0 + movdqa 112-128(%rbp),%xmm2 + paddd %xmm3,%xmm8 + paddd %xmm11,%xmm2 +.byte 15,56,205,231 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movdqa %xmm4,%xmm3 +.byte 102,15,58,15,223,4 +.byte 69,15,56,203,254 +.byte 69,15,56,205,195 + pshufd $0x0e,%xmm1,%xmm0 + paddd %xmm3,%xmm5 + movdqa %xmm8,%xmm3 +.byte 102,65,15,58,15,219,4 +.byte 15,56,204,247 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 128-128(%rbp),%xmm1 + paddd %xmm4,%xmm1 +.byte 69,15,56,203,247 +.byte 69,15,56,204,211 + movdqa %xmm1,%xmm0 + movdqa 128-128(%rbp),%xmm2 + paddd %xmm3,%xmm9 + paddd %xmm8,%xmm2 +.byte 15,56,205,236 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movdqa %xmm5,%xmm3 +.byte 102,15,58,15,220,4 +.byte 69,15,56,203,254 +.byte 69,15,56,205,200 + pshufd $0x0e,%xmm1,%xmm0 + paddd %xmm3,%xmm6 + movdqa %xmm9,%xmm3 +.byte 102,65,15,58,15,216,4 +.byte 15,56,204,252 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 144-128(%rbp),%xmm1 + paddd %xmm5,%xmm1 +.byte 69,15,56,203,247 +.byte 69,15,56,204,216 + movdqa %xmm1,%xmm0 + movdqa 144-128(%rbp),%xmm2 + paddd %xmm3,%xmm10 + paddd %xmm9,%xmm2 +.byte 15,56,205,245 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movdqa %xmm6,%xmm3 +.byte 102,15,58,15,221,4 +.byte 69,15,56,203,254 +.byte 69,15,56,205,209 + pshufd $0x0e,%xmm1,%xmm0 + paddd %xmm3,%xmm7 + movdqa %xmm10,%xmm3 +.byte 102,65,15,58,15,217,4 +.byte 15,56,204,229 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 160-128(%rbp),%xmm1 + paddd %xmm6,%xmm1 +.byte 69,15,56,203,247 +.byte 69,15,56,204,193 + movdqa %xmm1,%xmm0 + movdqa 160-128(%rbp),%xmm2 + paddd %xmm3,%xmm11 + paddd %xmm10,%xmm2 +.byte 15,56,205,254 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movdqa %xmm7,%xmm3 +.byte 102,15,58,15,222,4 +.byte 69,15,56,203,254 +.byte 69,15,56,205,218 + pshufd $0x0e,%xmm1,%xmm0 + paddd %xmm3,%xmm4 + movdqa %xmm11,%xmm3 +.byte 102,65,15,58,15,218,4 +.byte 15,56,204,238 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 176-128(%rbp),%xmm1 + paddd %xmm7,%xmm1 +.byte 69,15,56,203,247 +.byte 69,15,56,204,202 + movdqa %xmm1,%xmm0 + movdqa 176-128(%rbp),%xmm2 + paddd %xmm3,%xmm8 + paddd %xmm11,%xmm2 +.byte 15,56,205,231 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movdqa %xmm4,%xmm3 +.byte 102,15,58,15,223,4 +.byte 69,15,56,203,254 +.byte 69,15,56,205,195 + pshufd $0x0e,%xmm1,%xmm0 + paddd %xmm3,%xmm5 + movdqa %xmm8,%xmm3 +.byte 102,65,15,58,15,219,4 +.byte 15,56,204,247 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 192-128(%rbp),%xmm1 + paddd %xmm4,%xmm1 +.byte 69,15,56,203,247 +.byte 69,15,56,204,211 + movdqa %xmm1,%xmm0 + movdqa 192-128(%rbp),%xmm2 + paddd %xmm3,%xmm9 + paddd %xmm8,%xmm2 +.byte 15,56,205,236 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movdqa %xmm5,%xmm3 +.byte 102,15,58,15,220,4 +.byte 69,15,56,203,254 +.byte 69,15,56,205,200 + pshufd $0x0e,%xmm1,%xmm0 + paddd %xmm3,%xmm6 + movdqa %xmm9,%xmm3 +.byte 102,65,15,58,15,216,4 +.byte 15,56,204,252 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 208-128(%rbp),%xmm1 + paddd %xmm5,%xmm1 +.byte 69,15,56,203,247 +.byte 69,15,56,204,216 + movdqa %xmm1,%xmm0 + movdqa 208-128(%rbp),%xmm2 + paddd %xmm3,%xmm10 + paddd %xmm9,%xmm2 +.byte 15,56,205,245 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movdqa %xmm6,%xmm3 +.byte 102,15,58,15,221,4 +.byte 69,15,56,203,254 +.byte 69,15,56,205,209 + pshufd $0x0e,%xmm1,%xmm0 + paddd %xmm3,%xmm7 + movdqa %xmm10,%xmm3 +.byte 102,65,15,58,15,217,4 + nop +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 224-128(%rbp),%xmm1 + paddd %xmm6,%xmm1 +.byte 69,15,56,203,247 + + movdqa %xmm1,%xmm0 + movdqa 224-128(%rbp),%xmm2 + paddd %xmm3,%xmm11 + paddd %xmm10,%xmm2 +.byte 15,56,205,254 + nop +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + movl $1,%ecx + pxor %xmm6,%xmm6 +.byte 69,15,56,203,254 +.byte 69,15,56,205,218 + pshufd $0x0e,%xmm1,%xmm0 + movdqa 240-128(%rbp),%xmm1 + paddd %xmm7,%xmm1 + movq (%rbx),%xmm7 + nop +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + movdqa 240-128(%rbp),%xmm2 + paddd %xmm11,%xmm2 +.byte 69,15,56,203,247 + + movdqa %xmm1,%xmm0 + cmpl 0(%rbx),%ecx + cmovgeq %rsp,%r8 + cmpl 4(%rbx),%ecx + cmovgeq %rsp,%r9 + pshufd $0x00,%xmm7,%xmm9 +.byte 69,15,56,203,236 + movdqa %xmm2,%xmm0 + pshufd $0x55,%xmm7,%xmm10 + movdqa %xmm7,%xmm11 +.byte 69,15,56,203,254 + pshufd $0x0e,%xmm1,%xmm0 + pcmpgtd %xmm6,%xmm9 + pcmpgtd %xmm6,%xmm10 +.byte 69,15,56,203,229 + pshufd $0x0e,%xmm2,%xmm0 + pcmpgtd %xmm6,%xmm11 + movdqa K256_shaext-16(%rip),%xmm3 +.byte 69,15,56,203,247 + + pand %xmm9,%xmm13 + pand %xmm10,%xmm15 + pand %xmm9,%xmm12 + pand %xmm10,%xmm14 + paddd %xmm7,%xmm11 + + paddd 80(%rsp),%xmm13 + paddd 112(%rsp),%xmm15 + paddd 64(%rsp),%xmm12 + paddd 96(%rsp),%xmm14 + + movq %xmm11,(%rbx) + decl %edx + jnz .Loop_shaext + + movl 280(%rsp),%edx + + pshufd $27,%xmm12,%xmm12 + pshufd $27,%xmm13,%xmm13 + pshufd $27,%xmm14,%xmm14 + pshufd $27,%xmm15,%xmm15 + + movdqa %xmm12,%xmm5 + movdqa %xmm13,%xmm6 + punpckldq %xmm14,%xmm12 + punpckhdq %xmm14,%xmm5 + punpckldq %xmm15,%xmm13 + punpckhdq %xmm15,%xmm6 + + movq %xmm12,0-128(%rdi) + psrldq $8,%xmm12 + movq %xmm5,128-128(%rdi) + psrldq $8,%xmm5 + movq %xmm12,32-128(%rdi) + movq %xmm5,160-128(%rdi) + + movq %xmm13,64-128(%rdi) + psrldq $8,%xmm13 + movq %xmm6,192-128(%rdi) + psrldq $8,%xmm6 + movq %xmm13,96-128(%rdi) + movq %xmm6,224-128(%rdi) + + leaq 8(%rdi),%rdi + leaq 32(%rsi),%rsi + decl %edx + jnz .Loop_grande_shaext + +.Ldone_shaext: + + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_shaext: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_multi_block_shaext,.-sha256_multi_block_shaext +.type sha256_multi_block_avx,@function +.align 32 +sha256_multi_block_avx: +.cfi_startproc +_avx_shortcut: + shrq $32,%rcx + cmpl $2,%edx + jb .Lavx + testl $32,%ecx + jnz _avx2_shortcut + jmp .Lavx +.align 32 +.Lavx: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + subq $288,%rsp + andq $-256,%rsp + movq %rax,272(%rsp) +.cfi_escape 0x0f,0x06,0x77,0x90,0x02,0x06,0x23,0x08 +.Lbody_avx: + leaq K256+128(%rip),%rbp + leaq 256(%rsp),%rbx + leaq 128(%rdi),%rdi + +.Loop_grande_avx: + movl %edx,280(%rsp) + xorl %edx,%edx + + movq 0(%rsi),%r8 + + movl 8(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,0(%rbx) + cmovleq %rbp,%r8 + + movq 16(%rsi),%r9 + + movl 24(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,4(%rbx) + cmovleq %rbp,%r9 + + movq 32(%rsi),%r10 + + movl 40(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,8(%rbx) + cmovleq %rbp,%r10 + + movq 48(%rsi),%r11 + + movl 56(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,12(%rbx) + cmovleq %rbp,%r11 + testl %edx,%edx + jz .Ldone_avx + + vmovdqu 0-128(%rdi),%xmm8 + leaq 128(%rsp),%rax + vmovdqu 32-128(%rdi),%xmm9 + vmovdqu 64-128(%rdi),%xmm10 + vmovdqu 96-128(%rdi),%xmm11 + vmovdqu 128-128(%rdi),%xmm12 + vmovdqu 160-128(%rdi),%xmm13 + vmovdqu 192-128(%rdi),%xmm14 + vmovdqu 224-128(%rdi),%xmm15 + vmovdqu .Lpbswap(%rip),%xmm6 + jmp .Loop_avx + +.align 32 +.Loop_avx: + vpxor %xmm9,%xmm10,%xmm4 + vmovd 0(%r8),%xmm5 + vmovd 0(%r9),%xmm0 + vpinsrd $1,0(%r10),%xmm5,%xmm5 + vpinsrd $1,0(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm12,%xmm7 + vpslld $26,%xmm12,%xmm2 + vmovdqu %xmm5,0-128(%rax) + vpaddd %xmm15,%xmm5,%xmm5 + + vpsrld $11,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm12,%xmm2 + vpaddd -128(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm12,%xmm2 + vpandn %xmm14,%xmm12,%xmm0 + vpand %xmm13,%xmm12,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm8,%xmm15 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm8,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm8,%xmm9,%xmm3 + + vpxor %xmm1,%xmm15,%xmm15 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm8,%xmm1 + + vpslld $19,%xmm8,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm15,%xmm7 + + vpsrld $22,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm8,%xmm2 + vpxor %xmm4,%xmm9,%xmm15 + vpaddd %xmm5,%xmm11,%xmm11 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm15,%xmm15 + vpaddd %xmm7,%xmm15,%xmm15 + vmovd 4(%r8),%xmm5 + vmovd 4(%r9),%xmm0 + vpinsrd $1,4(%r10),%xmm5,%xmm5 + vpinsrd $1,4(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm11,%xmm7 + vpslld $26,%xmm11,%xmm2 + vmovdqu %xmm5,16-128(%rax) + vpaddd %xmm14,%xmm5,%xmm5 + + vpsrld $11,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm11,%xmm2 + vpaddd -96(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm11,%xmm2 + vpandn %xmm13,%xmm11,%xmm0 + vpand %xmm12,%xmm11,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm15,%xmm14 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm15,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm15,%xmm8,%xmm4 + + vpxor %xmm1,%xmm14,%xmm14 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm15,%xmm1 + + vpslld $19,%xmm15,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm14,%xmm7 + + vpsrld $22,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm15,%xmm2 + vpxor %xmm3,%xmm8,%xmm14 + vpaddd %xmm5,%xmm10,%xmm10 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm14,%xmm14 + vpaddd %xmm7,%xmm14,%xmm14 + vmovd 8(%r8),%xmm5 + vmovd 8(%r9),%xmm0 + vpinsrd $1,8(%r10),%xmm5,%xmm5 + vpinsrd $1,8(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm10,%xmm7 + vpslld $26,%xmm10,%xmm2 + vmovdqu %xmm5,32-128(%rax) + vpaddd %xmm13,%xmm5,%xmm5 + + vpsrld $11,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm10,%xmm2 + vpaddd -64(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm10,%xmm2 + vpandn %xmm12,%xmm10,%xmm0 + vpand %xmm11,%xmm10,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm14,%xmm13 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm14,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm14,%xmm15,%xmm3 + + vpxor %xmm1,%xmm13,%xmm13 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm14,%xmm1 + + vpslld $19,%xmm14,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm13,%xmm7 + + vpsrld $22,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm14,%xmm2 + vpxor %xmm4,%xmm15,%xmm13 + vpaddd %xmm5,%xmm9,%xmm9 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm13,%xmm13 + vpaddd %xmm7,%xmm13,%xmm13 + vmovd 12(%r8),%xmm5 + vmovd 12(%r9),%xmm0 + vpinsrd $1,12(%r10),%xmm5,%xmm5 + vpinsrd $1,12(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm9,%xmm7 + vpslld $26,%xmm9,%xmm2 + vmovdqu %xmm5,48-128(%rax) + vpaddd %xmm12,%xmm5,%xmm5 + + vpsrld $11,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm9,%xmm2 + vpaddd -32(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm9,%xmm2 + vpandn %xmm11,%xmm9,%xmm0 + vpand %xmm10,%xmm9,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm13,%xmm12 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm13,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm13,%xmm14,%xmm4 + + vpxor %xmm1,%xmm12,%xmm12 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm13,%xmm1 + + vpslld $19,%xmm13,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm12,%xmm7 + + vpsrld $22,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm13,%xmm2 + vpxor %xmm3,%xmm14,%xmm12 + vpaddd %xmm5,%xmm8,%xmm8 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm12,%xmm12 + vpaddd %xmm7,%xmm12,%xmm12 + vmovd 16(%r8),%xmm5 + vmovd 16(%r9),%xmm0 + vpinsrd $1,16(%r10),%xmm5,%xmm5 + vpinsrd $1,16(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm8,%xmm7 + vpslld $26,%xmm8,%xmm2 + vmovdqu %xmm5,64-128(%rax) + vpaddd %xmm11,%xmm5,%xmm5 + + vpsrld $11,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm8,%xmm2 + vpaddd 0(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm8,%xmm2 + vpandn %xmm10,%xmm8,%xmm0 + vpand %xmm9,%xmm8,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm12,%xmm11 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm12,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm12,%xmm13,%xmm3 + + vpxor %xmm1,%xmm11,%xmm11 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm12,%xmm1 + + vpslld $19,%xmm12,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm11,%xmm7 + + vpsrld $22,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm12,%xmm2 + vpxor %xmm4,%xmm13,%xmm11 + vpaddd %xmm5,%xmm15,%xmm15 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm11,%xmm11 + vpaddd %xmm7,%xmm11,%xmm11 + vmovd 20(%r8),%xmm5 + vmovd 20(%r9),%xmm0 + vpinsrd $1,20(%r10),%xmm5,%xmm5 + vpinsrd $1,20(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm15,%xmm7 + vpslld $26,%xmm15,%xmm2 + vmovdqu %xmm5,80-128(%rax) + vpaddd %xmm10,%xmm5,%xmm5 + + vpsrld $11,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm15,%xmm2 + vpaddd 32(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm15,%xmm2 + vpandn %xmm9,%xmm15,%xmm0 + vpand %xmm8,%xmm15,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm11,%xmm10 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm11,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm11,%xmm12,%xmm4 + + vpxor %xmm1,%xmm10,%xmm10 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm11,%xmm1 + + vpslld $19,%xmm11,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm10,%xmm7 + + vpsrld $22,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm11,%xmm2 + vpxor %xmm3,%xmm12,%xmm10 + vpaddd %xmm5,%xmm14,%xmm14 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm10,%xmm10 + vpaddd %xmm7,%xmm10,%xmm10 + vmovd 24(%r8),%xmm5 + vmovd 24(%r9),%xmm0 + vpinsrd $1,24(%r10),%xmm5,%xmm5 + vpinsrd $1,24(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm14,%xmm7 + vpslld $26,%xmm14,%xmm2 + vmovdqu %xmm5,96-128(%rax) + vpaddd %xmm9,%xmm5,%xmm5 + + vpsrld $11,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm14,%xmm2 + vpaddd 64(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm14,%xmm2 + vpandn %xmm8,%xmm14,%xmm0 + vpand %xmm15,%xmm14,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm10,%xmm9 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm10,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm10,%xmm11,%xmm3 + + vpxor %xmm1,%xmm9,%xmm9 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm10,%xmm1 + + vpslld $19,%xmm10,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm9,%xmm7 + + vpsrld $22,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm10,%xmm2 + vpxor %xmm4,%xmm11,%xmm9 + vpaddd %xmm5,%xmm13,%xmm13 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm9,%xmm9 + vpaddd %xmm7,%xmm9,%xmm9 + vmovd 28(%r8),%xmm5 + vmovd 28(%r9),%xmm0 + vpinsrd $1,28(%r10),%xmm5,%xmm5 + vpinsrd $1,28(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm13,%xmm7 + vpslld $26,%xmm13,%xmm2 + vmovdqu %xmm5,112-128(%rax) + vpaddd %xmm8,%xmm5,%xmm5 + + vpsrld $11,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm13,%xmm2 + vpaddd 96(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm13,%xmm2 + vpandn %xmm15,%xmm13,%xmm0 + vpand %xmm14,%xmm13,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm9,%xmm8 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm9,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm9,%xmm10,%xmm4 + + vpxor %xmm1,%xmm8,%xmm8 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm9,%xmm1 + + vpslld $19,%xmm9,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm8,%xmm7 + + vpsrld $22,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm9,%xmm2 + vpxor %xmm3,%xmm10,%xmm8 + vpaddd %xmm5,%xmm12,%xmm12 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm8,%xmm8 + vpaddd %xmm7,%xmm8,%xmm8 + addq $256,%rbp + vmovd 32(%r8),%xmm5 + vmovd 32(%r9),%xmm0 + vpinsrd $1,32(%r10),%xmm5,%xmm5 + vpinsrd $1,32(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm12,%xmm7 + vpslld $26,%xmm12,%xmm2 + vmovdqu %xmm5,128-128(%rax) + vpaddd %xmm15,%xmm5,%xmm5 + + vpsrld $11,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm12,%xmm2 + vpaddd -128(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm12,%xmm2 + vpandn %xmm14,%xmm12,%xmm0 + vpand %xmm13,%xmm12,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm8,%xmm15 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm8,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm8,%xmm9,%xmm3 + + vpxor %xmm1,%xmm15,%xmm15 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm8,%xmm1 + + vpslld $19,%xmm8,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm15,%xmm7 + + vpsrld $22,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm8,%xmm2 + vpxor %xmm4,%xmm9,%xmm15 + vpaddd %xmm5,%xmm11,%xmm11 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm15,%xmm15 + vpaddd %xmm7,%xmm15,%xmm15 + vmovd 36(%r8),%xmm5 + vmovd 36(%r9),%xmm0 + vpinsrd $1,36(%r10),%xmm5,%xmm5 + vpinsrd $1,36(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm11,%xmm7 + vpslld $26,%xmm11,%xmm2 + vmovdqu %xmm5,144-128(%rax) + vpaddd %xmm14,%xmm5,%xmm5 + + vpsrld $11,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm11,%xmm2 + vpaddd -96(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm11,%xmm2 + vpandn %xmm13,%xmm11,%xmm0 + vpand %xmm12,%xmm11,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm15,%xmm14 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm15,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm15,%xmm8,%xmm4 + + vpxor %xmm1,%xmm14,%xmm14 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm15,%xmm1 + + vpslld $19,%xmm15,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm14,%xmm7 + + vpsrld $22,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm15,%xmm2 + vpxor %xmm3,%xmm8,%xmm14 + vpaddd %xmm5,%xmm10,%xmm10 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm14,%xmm14 + vpaddd %xmm7,%xmm14,%xmm14 + vmovd 40(%r8),%xmm5 + vmovd 40(%r9),%xmm0 + vpinsrd $1,40(%r10),%xmm5,%xmm5 + vpinsrd $1,40(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm10,%xmm7 + vpslld $26,%xmm10,%xmm2 + vmovdqu %xmm5,160-128(%rax) + vpaddd %xmm13,%xmm5,%xmm5 + + vpsrld $11,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm10,%xmm2 + vpaddd -64(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm10,%xmm2 + vpandn %xmm12,%xmm10,%xmm0 + vpand %xmm11,%xmm10,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm14,%xmm13 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm14,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm14,%xmm15,%xmm3 + + vpxor %xmm1,%xmm13,%xmm13 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm14,%xmm1 + + vpslld $19,%xmm14,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm13,%xmm7 + + vpsrld $22,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm14,%xmm2 + vpxor %xmm4,%xmm15,%xmm13 + vpaddd %xmm5,%xmm9,%xmm9 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm13,%xmm13 + vpaddd %xmm7,%xmm13,%xmm13 + vmovd 44(%r8),%xmm5 + vmovd 44(%r9),%xmm0 + vpinsrd $1,44(%r10),%xmm5,%xmm5 + vpinsrd $1,44(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm9,%xmm7 + vpslld $26,%xmm9,%xmm2 + vmovdqu %xmm5,176-128(%rax) + vpaddd %xmm12,%xmm5,%xmm5 + + vpsrld $11,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm9,%xmm2 + vpaddd -32(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm9,%xmm2 + vpandn %xmm11,%xmm9,%xmm0 + vpand %xmm10,%xmm9,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm13,%xmm12 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm13,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm13,%xmm14,%xmm4 + + vpxor %xmm1,%xmm12,%xmm12 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm13,%xmm1 + + vpslld $19,%xmm13,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm12,%xmm7 + + vpsrld $22,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm13,%xmm2 + vpxor %xmm3,%xmm14,%xmm12 + vpaddd %xmm5,%xmm8,%xmm8 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm12,%xmm12 + vpaddd %xmm7,%xmm12,%xmm12 + vmovd 48(%r8),%xmm5 + vmovd 48(%r9),%xmm0 + vpinsrd $1,48(%r10),%xmm5,%xmm5 + vpinsrd $1,48(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm8,%xmm7 + vpslld $26,%xmm8,%xmm2 + vmovdqu %xmm5,192-128(%rax) + vpaddd %xmm11,%xmm5,%xmm5 + + vpsrld $11,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm8,%xmm2 + vpaddd 0(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm8,%xmm2 + vpandn %xmm10,%xmm8,%xmm0 + vpand %xmm9,%xmm8,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm12,%xmm11 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm12,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm12,%xmm13,%xmm3 + + vpxor %xmm1,%xmm11,%xmm11 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm12,%xmm1 + + vpslld $19,%xmm12,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm11,%xmm7 + + vpsrld $22,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm12,%xmm2 + vpxor %xmm4,%xmm13,%xmm11 + vpaddd %xmm5,%xmm15,%xmm15 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm11,%xmm11 + vpaddd %xmm7,%xmm11,%xmm11 + vmovd 52(%r8),%xmm5 + vmovd 52(%r9),%xmm0 + vpinsrd $1,52(%r10),%xmm5,%xmm5 + vpinsrd $1,52(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm15,%xmm7 + vpslld $26,%xmm15,%xmm2 + vmovdqu %xmm5,208-128(%rax) + vpaddd %xmm10,%xmm5,%xmm5 + + vpsrld $11,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm15,%xmm2 + vpaddd 32(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm15,%xmm2 + vpandn %xmm9,%xmm15,%xmm0 + vpand %xmm8,%xmm15,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm11,%xmm10 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm11,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm11,%xmm12,%xmm4 + + vpxor %xmm1,%xmm10,%xmm10 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm11,%xmm1 + + vpslld $19,%xmm11,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm10,%xmm7 + + vpsrld $22,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm11,%xmm2 + vpxor %xmm3,%xmm12,%xmm10 + vpaddd %xmm5,%xmm14,%xmm14 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm10,%xmm10 + vpaddd %xmm7,%xmm10,%xmm10 + vmovd 56(%r8),%xmm5 + vmovd 56(%r9),%xmm0 + vpinsrd $1,56(%r10),%xmm5,%xmm5 + vpinsrd $1,56(%r11),%xmm0,%xmm0 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm14,%xmm7 + vpslld $26,%xmm14,%xmm2 + vmovdqu %xmm5,224-128(%rax) + vpaddd %xmm9,%xmm5,%xmm5 + + vpsrld $11,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm14,%xmm2 + vpaddd 64(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm14,%xmm2 + vpandn %xmm8,%xmm14,%xmm0 + vpand %xmm15,%xmm14,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm10,%xmm9 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm10,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm10,%xmm11,%xmm3 + + vpxor %xmm1,%xmm9,%xmm9 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm10,%xmm1 + + vpslld $19,%xmm10,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm9,%xmm7 + + vpsrld $22,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm10,%xmm2 + vpxor %xmm4,%xmm11,%xmm9 + vpaddd %xmm5,%xmm13,%xmm13 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm9,%xmm9 + vpaddd %xmm7,%xmm9,%xmm9 + vmovd 60(%r8),%xmm5 + leaq 64(%r8),%r8 + vmovd 60(%r9),%xmm0 + leaq 64(%r9),%r9 + vpinsrd $1,60(%r10),%xmm5,%xmm5 + leaq 64(%r10),%r10 + vpinsrd $1,60(%r11),%xmm0,%xmm0 + leaq 64(%r11),%r11 + vpunpckldq %xmm0,%xmm5,%xmm5 + vpshufb %xmm6,%xmm5,%xmm5 + vpsrld $6,%xmm13,%xmm7 + vpslld $26,%xmm13,%xmm2 + vmovdqu %xmm5,240-128(%rax) + vpaddd %xmm8,%xmm5,%xmm5 + + vpsrld $11,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm13,%xmm2 + vpaddd 96(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + prefetcht0 63(%r8) + vpslld $7,%xmm13,%xmm2 + vpandn %xmm15,%xmm13,%xmm0 + vpand %xmm14,%xmm13,%xmm4 + prefetcht0 63(%r9) + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm9,%xmm8 + vpxor %xmm2,%xmm7,%xmm7 + prefetcht0 63(%r10) + vpslld $30,%xmm9,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm9,%xmm10,%xmm4 + prefetcht0 63(%r11) + vpxor %xmm1,%xmm8,%xmm8 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm9,%xmm1 + + vpslld $19,%xmm9,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm8,%xmm7 + + vpsrld $22,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm9,%xmm2 + vpxor %xmm3,%xmm10,%xmm8 + vpaddd %xmm5,%xmm12,%xmm12 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm8,%xmm8 + vpaddd %xmm7,%xmm8,%xmm8 + addq $256,%rbp + vmovdqu 0-128(%rax),%xmm5 + movl $3,%ecx + jmp .Loop_16_xx_avx +.align 32 +.Loop_16_xx_avx: + vmovdqu 16-128(%rax),%xmm6 + vpaddd 144-128(%rax),%xmm5,%xmm5 + + vpsrld $3,%xmm6,%xmm7 + vpsrld $7,%xmm6,%xmm1 + vpslld $25,%xmm6,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm6,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm6,%xmm2 + vmovdqu 224-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm5,%xmm5 + vpxor %xmm1,%xmm3,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm5,%xmm5 + vpsrld $6,%xmm12,%xmm7 + vpslld $26,%xmm12,%xmm2 + vmovdqu %xmm5,0-128(%rax) + vpaddd %xmm15,%xmm5,%xmm5 + + vpsrld $11,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm12,%xmm2 + vpaddd -128(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm12,%xmm2 + vpandn %xmm14,%xmm12,%xmm0 + vpand %xmm13,%xmm12,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm8,%xmm15 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm8,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm8,%xmm9,%xmm3 + + vpxor %xmm1,%xmm15,%xmm15 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm8,%xmm1 + + vpslld $19,%xmm8,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm15,%xmm7 + + vpsrld $22,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm8,%xmm2 + vpxor %xmm4,%xmm9,%xmm15 + vpaddd %xmm5,%xmm11,%xmm11 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm15,%xmm15 + vpaddd %xmm7,%xmm15,%xmm15 + vmovdqu 32-128(%rax),%xmm5 + vpaddd 160-128(%rax),%xmm6,%xmm6 + + vpsrld $3,%xmm5,%xmm7 + vpsrld $7,%xmm5,%xmm1 + vpslld $25,%xmm5,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm5,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm5,%xmm2 + vmovdqu 240-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm6,%xmm6 + vpsrld $6,%xmm11,%xmm7 + vpslld $26,%xmm11,%xmm2 + vmovdqu %xmm6,16-128(%rax) + vpaddd %xmm14,%xmm6,%xmm6 + + vpsrld $11,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm11,%xmm2 + vpaddd -96(%rbp),%xmm6,%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm11,%xmm2 + vpandn %xmm13,%xmm11,%xmm0 + vpand %xmm12,%xmm11,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm15,%xmm14 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm15,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm15,%xmm8,%xmm4 + + vpxor %xmm1,%xmm14,%xmm14 + vpaddd %xmm7,%xmm6,%xmm6 + + vpsrld $13,%xmm15,%xmm1 + + vpslld $19,%xmm15,%xmm2 + vpaddd %xmm0,%xmm6,%xmm6 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm14,%xmm7 + + vpsrld $22,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm15,%xmm2 + vpxor %xmm3,%xmm8,%xmm14 + vpaddd %xmm6,%xmm10,%xmm10 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm6,%xmm14,%xmm14 + vpaddd %xmm7,%xmm14,%xmm14 + vmovdqu 48-128(%rax),%xmm6 + vpaddd 176-128(%rax),%xmm5,%xmm5 + + vpsrld $3,%xmm6,%xmm7 + vpsrld $7,%xmm6,%xmm1 + vpslld $25,%xmm6,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm6,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm6,%xmm2 + vmovdqu 0-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm5,%xmm5 + vpxor %xmm1,%xmm3,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm5,%xmm5 + vpsrld $6,%xmm10,%xmm7 + vpslld $26,%xmm10,%xmm2 + vmovdqu %xmm5,32-128(%rax) + vpaddd %xmm13,%xmm5,%xmm5 + + vpsrld $11,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm10,%xmm2 + vpaddd -64(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm10,%xmm2 + vpandn %xmm12,%xmm10,%xmm0 + vpand %xmm11,%xmm10,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm14,%xmm13 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm14,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm14,%xmm15,%xmm3 + + vpxor %xmm1,%xmm13,%xmm13 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm14,%xmm1 + + vpslld $19,%xmm14,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm13,%xmm7 + + vpsrld $22,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm14,%xmm2 + vpxor %xmm4,%xmm15,%xmm13 + vpaddd %xmm5,%xmm9,%xmm9 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm13,%xmm13 + vpaddd %xmm7,%xmm13,%xmm13 + vmovdqu 64-128(%rax),%xmm5 + vpaddd 192-128(%rax),%xmm6,%xmm6 + + vpsrld $3,%xmm5,%xmm7 + vpsrld $7,%xmm5,%xmm1 + vpslld $25,%xmm5,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm5,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm5,%xmm2 + vmovdqu 16-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm6,%xmm6 + vpsrld $6,%xmm9,%xmm7 + vpslld $26,%xmm9,%xmm2 + vmovdqu %xmm6,48-128(%rax) + vpaddd %xmm12,%xmm6,%xmm6 + + vpsrld $11,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm9,%xmm2 + vpaddd -32(%rbp),%xmm6,%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm9,%xmm2 + vpandn %xmm11,%xmm9,%xmm0 + vpand %xmm10,%xmm9,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm13,%xmm12 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm13,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm13,%xmm14,%xmm4 + + vpxor %xmm1,%xmm12,%xmm12 + vpaddd %xmm7,%xmm6,%xmm6 + + vpsrld $13,%xmm13,%xmm1 + + vpslld $19,%xmm13,%xmm2 + vpaddd %xmm0,%xmm6,%xmm6 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm12,%xmm7 + + vpsrld $22,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm13,%xmm2 + vpxor %xmm3,%xmm14,%xmm12 + vpaddd %xmm6,%xmm8,%xmm8 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm6,%xmm12,%xmm12 + vpaddd %xmm7,%xmm12,%xmm12 + vmovdqu 80-128(%rax),%xmm6 + vpaddd 208-128(%rax),%xmm5,%xmm5 + + vpsrld $3,%xmm6,%xmm7 + vpsrld $7,%xmm6,%xmm1 + vpslld $25,%xmm6,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm6,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm6,%xmm2 + vmovdqu 32-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm5,%xmm5 + vpxor %xmm1,%xmm3,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm5,%xmm5 + vpsrld $6,%xmm8,%xmm7 + vpslld $26,%xmm8,%xmm2 + vmovdqu %xmm5,64-128(%rax) + vpaddd %xmm11,%xmm5,%xmm5 + + vpsrld $11,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm8,%xmm2 + vpaddd 0(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm8,%xmm2 + vpandn %xmm10,%xmm8,%xmm0 + vpand %xmm9,%xmm8,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm12,%xmm11 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm12,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm12,%xmm13,%xmm3 + + vpxor %xmm1,%xmm11,%xmm11 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm12,%xmm1 + + vpslld $19,%xmm12,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm11,%xmm7 + + vpsrld $22,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm12,%xmm2 + vpxor %xmm4,%xmm13,%xmm11 + vpaddd %xmm5,%xmm15,%xmm15 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm11,%xmm11 + vpaddd %xmm7,%xmm11,%xmm11 + vmovdqu 96-128(%rax),%xmm5 + vpaddd 224-128(%rax),%xmm6,%xmm6 + + vpsrld $3,%xmm5,%xmm7 + vpsrld $7,%xmm5,%xmm1 + vpslld $25,%xmm5,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm5,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm5,%xmm2 + vmovdqu 48-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm6,%xmm6 + vpsrld $6,%xmm15,%xmm7 + vpslld $26,%xmm15,%xmm2 + vmovdqu %xmm6,80-128(%rax) + vpaddd %xmm10,%xmm6,%xmm6 + + vpsrld $11,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm15,%xmm2 + vpaddd 32(%rbp),%xmm6,%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm15,%xmm2 + vpandn %xmm9,%xmm15,%xmm0 + vpand %xmm8,%xmm15,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm11,%xmm10 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm11,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm11,%xmm12,%xmm4 + + vpxor %xmm1,%xmm10,%xmm10 + vpaddd %xmm7,%xmm6,%xmm6 + + vpsrld $13,%xmm11,%xmm1 + + vpslld $19,%xmm11,%xmm2 + vpaddd %xmm0,%xmm6,%xmm6 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm10,%xmm7 + + vpsrld $22,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm11,%xmm2 + vpxor %xmm3,%xmm12,%xmm10 + vpaddd %xmm6,%xmm14,%xmm14 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm6,%xmm10,%xmm10 + vpaddd %xmm7,%xmm10,%xmm10 + vmovdqu 112-128(%rax),%xmm6 + vpaddd 240-128(%rax),%xmm5,%xmm5 + + vpsrld $3,%xmm6,%xmm7 + vpsrld $7,%xmm6,%xmm1 + vpslld $25,%xmm6,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm6,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm6,%xmm2 + vmovdqu 64-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm5,%xmm5 + vpxor %xmm1,%xmm3,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm5,%xmm5 + vpsrld $6,%xmm14,%xmm7 + vpslld $26,%xmm14,%xmm2 + vmovdqu %xmm5,96-128(%rax) + vpaddd %xmm9,%xmm5,%xmm5 + + vpsrld $11,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm14,%xmm2 + vpaddd 64(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm14,%xmm2 + vpandn %xmm8,%xmm14,%xmm0 + vpand %xmm15,%xmm14,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm10,%xmm9 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm10,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm10,%xmm11,%xmm3 + + vpxor %xmm1,%xmm9,%xmm9 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm10,%xmm1 + + vpslld $19,%xmm10,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm9,%xmm7 + + vpsrld $22,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm10,%xmm2 + vpxor %xmm4,%xmm11,%xmm9 + vpaddd %xmm5,%xmm13,%xmm13 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm9,%xmm9 + vpaddd %xmm7,%xmm9,%xmm9 + vmovdqu 128-128(%rax),%xmm5 + vpaddd 0-128(%rax),%xmm6,%xmm6 + + vpsrld $3,%xmm5,%xmm7 + vpsrld $7,%xmm5,%xmm1 + vpslld $25,%xmm5,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm5,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm5,%xmm2 + vmovdqu 80-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm6,%xmm6 + vpsrld $6,%xmm13,%xmm7 + vpslld $26,%xmm13,%xmm2 + vmovdqu %xmm6,112-128(%rax) + vpaddd %xmm8,%xmm6,%xmm6 + + vpsrld $11,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm13,%xmm2 + vpaddd 96(%rbp),%xmm6,%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm13,%xmm2 + vpandn %xmm15,%xmm13,%xmm0 + vpand %xmm14,%xmm13,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm9,%xmm8 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm9,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm9,%xmm10,%xmm4 + + vpxor %xmm1,%xmm8,%xmm8 + vpaddd %xmm7,%xmm6,%xmm6 + + vpsrld $13,%xmm9,%xmm1 + + vpslld $19,%xmm9,%xmm2 + vpaddd %xmm0,%xmm6,%xmm6 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm8,%xmm7 + + vpsrld $22,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm9,%xmm2 + vpxor %xmm3,%xmm10,%xmm8 + vpaddd %xmm6,%xmm12,%xmm12 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm6,%xmm8,%xmm8 + vpaddd %xmm7,%xmm8,%xmm8 + addq $256,%rbp + vmovdqu 144-128(%rax),%xmm6 + vpaddd 16-128(%rax),%xmm5,%xmm5 + + vpsrld $3,%xmm6,%xmm7 + vpsrld $7,%xmm6,%xmm1 + vpslld $25,%xmm6,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm6,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm6,%xmm2 + vmovdqu 96-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm5,%xmm5 + vpxor %xmm1,%xmm3,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm5,%xmm5 + vpsrld $6,%xmm12,%xmm7 + vpslld $26,%xmm12,%xmm2 + vmovdqu %xmm5,128-128(%rax) + vpaddd %xmm15,%xmm5,%xmm5 + + vpsrld $11,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm12,%xmm2 + vpaddd -128(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm12,%xmm2 + vpandn %xmm14,%xmm12,%xmm0 + vpand %xmm13,%xmm12,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm8,%xmm15 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm8,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm8,%xmm9,%xmm3 + + vpxor %xmm1,%xmm15,%xmm15 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm8,%xmm1 + + vpslld $19,%xmm8,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm15,%xmm7 + + vpsrld $22,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm8,%xmm2 + vpxor %xmm4,%xmm9,%xmm15 + vpaddd %xmm5,%xmm11,%xmm11 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm15,%xmm15 + vpaddd %xmm7,%xmm15,%xmm15 + vmovdqu 160-128(%rax),%xmm5 + vpaddd 32-128(%rax),%xmm6,%xmm6 + + vpsrld $3,%xmm5,%xmm7 + vpsrld $7,%xmm5,%xmm1 + vpslld $25,%xmm5,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm5,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm5,%xmm2 + vmovdqu 112-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm6,%xmm6 + vpsrld $6,%xmm11,%xmm7 + vpslld $26,%xmm11,%xmm2 + vmovdqu %xmm6,144-128(%rax) + vpaddd %xmm14,%xmm6,%xmm6 + + vpsrld $11,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm11,%xmm2 + vpaddd -96(%rbp),%xmm6,%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm11,%xmm2 + vpandn %xmm13,%xmm11,%xmm0 + vpand %xmm12,%xmm11,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm15,%xmm14 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm15,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm15,%xmm8,%xmm4 + + vpxor %xmm1,%xmm14,%xmm14 + vpaddd %xmm7,%xmm6,%xmm6 + + vpsrld $13,%xmm15,%xmm1 + + vpslld $19,%xmm15,%xmm2 + vpaddd %xmm0,%xmm6,%xmm6 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm14,%xmm7 + + vpsrld $22,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm15,%xmm2 + vpxor %xmm3,%xmm8,%xmm14 + vpaddd %xmm6,%xmm10,%xmm10 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm6,%xmm14,%xmm14 + vpaddd %xmm7,%xmm14,%xmm14 + vmovdqu 176-128(%rax),%xmm6 + vpaddd 48-128(%rax),%xmm5,%xmm5 + + vpsrld $3,%xmm6,%xmm7 + vpsrld $7,%xmm6,%xmm1 + vpslld $25,%xmm6,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm6,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm6,%xmm2 + vmovdqu 128-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm5,%xmm5 + vpxor %xmm1,%xmm3,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm5,%xmm5 + vpsrld $6,%xmm10,%xmm7 + vpslld $26,%xmm10,%xmm2 + vmovdqu %xmm5,160-128(%rax) + vpaddd %xmm13,%xmm5,%xmm5 + + vpsrld $11,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm10,%xmm2 + vpaddd -64(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm10,%xmm2 + vpandn %xmm12,%xmm10,%xmm0 + vpand %xmm11,%xmm10,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm14,%xmm13 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm14,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm14,%xmm15,%xmm3 + + vpxor %xmm1,%xmm13,%xmm13 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm14,%xmm1 + + vpslld $19,%xmm14,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm13,%xmm7 + + vpsrld $22,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm14,%xmm2 + vpxor %xmm4,%xmm15,%xmm13 + vpaddd %xmm5,%xmm9,%xmm9 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm13,%xmm13 + vpaddd %xmm7,%xmm13,%xmm13 + vmovdqu 192-128(%rax),%xmm5 + vpaddd 64-128(%rax),%xmm6,%xmm6 + + vpsrld $3,%xmm5,%xmm7 + vpsrld $7,%xmm5,%xmm1 + vpslld $25,%xmm5,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm5,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm5,%xmm2 + vmovdqu 144-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm6,%xmm6 + vpsrld $6,%xmm9,%xmm7 + vpslld $26,%xmm9,%xmm2 + vmovdqu %xmm6,176-128(%rax) + vpaddd %xmm12,%xmm6,%xmm6 + + vpsrld $11,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm9,%xmm2 + vpaddd -32(%rbp),%xmm6,%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm9,%xmm2 + vpandn %xmm11,%xmm9,%xmm0 + vpand %xmm10,%xmm9,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm13,%xmm12 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm13,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm13,%xmm14,%xmm4 + + vpxor %xmm1,%xmm12,%xmm12 + vpaddd %xmm7,%xmm6,%xmm6 + + vpsrld $13,%xmm13,%xmm1 + + vpslld $19,%xmm13,%xmm2 + vpaddd %xmm0,%xmm6,%xmm6 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm12,%xmm7 + + vpsrld $22,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm13,%xmm2 + vpxor %xmm3,%xmm14,%xmm12 + vpaddd %xmm6,%xmm8,%xmm8 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm6,%xmm12,%xmm12 + vpaddd %xmm7,%xmm12,%xmm12 + vmovdqu 208-128(%rax),%xmm6 + vpaddd 80-128(%rax),%xmm5,%xmm5 + + vpsrld $3,%xmm6,%xmm7 + vpsrld $7,%xmm6,%xmm1 + vpslld $25,%xmm6,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm6,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm6,%xmm2 + vmovdqu 160-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm5,%xmm5 + vpxor %xmm1,%xmm3,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm5,%xmm5 + vpsrld $6,%xmm8,%xmm7 + vpslld $26,%xmm8,%xmm2 + vmovdqu %xmm5,192-128(%rax) + vpaddd %xmm11,%xmm5,%xmm5 + + vpsrld $11,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm8,%xmm2 + vpaddd 0(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm8,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm8,%xmm2 + vpandn %xmm10,%xmm8,%xmm0 + vpand %xmm9,%xmm8,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm12,%xmm11 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm12,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm12,%xmm13,%xmm3 + + vpxor %xmm1,%xmm11,%xmm11 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm12,%xmm1 + + vpslld $19,%xmm12,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm11,%xmm7 + + vpsrld $22,%xmm12,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm12,%xmm2 + vpxor %xmm4,%xmm13,%xmm11 + vpaddd %xmm5,%xmm15,%xmm15 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm11,%xmm11 + vpaddd %xmm7,%xmm11,%xmm11 + vmovdqu 224-128(%rax),%xmm5 + vpaddd 96-128(%rax),%xmm6,%xmm6 + + vpsrld $3,%xmm5,%xmm7 + vpsrld $7,%xmm5,%xmm1 + vpslld $25,%xmm5,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm5,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm5,%xmm2 + vmovdqu 176-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm6,%xmm6 + vpsrld $6,%xmm15,%xmm7 + vpslld $26,%xmm15,%xmm2 + vmovdqu %xmm6,208-128(%rax) + vpaddd %xmm10,%xmm6,%xmm6 + + vpsrld $11,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm15,%xmm2 + vpaddd 32(%rbp),%xmm6,%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm15,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm15,%xmm2 + vpandn %xmm9,%xmm15,%xmm0 + vpand %xmm8,%xmm15,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm11,%xmm10 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm11,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm11,%xmm12,%xmm4 + + vpxor %xmm1,%xmm10,%xmm10 + vpaddd %xmm7,%xmm6,%xmm6 + + vpsrld $13,%xmm11,%xmm1 + + vpslld $19,%xmm11,%xmm2 + vpaddd %xmm0,%xmm6,%xmm6 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm10,%xmm7 + + vpsrld $22,%xmm11,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm11,%xmm2 + vpxor %xmm3,%xmm12,%xmm10 + vpaddd %xmm6,%xmm14,%xmm14 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm6,%xmm10,%xmm10 + vpaddd %xmm7,%xmm10,%xmm10 + vmovdqu 240-128(%rax),%xmm6 + vpaddd 112-128(%rax),%xmm5,%xmm5 + + vpsrld $3,%xmm6,%xmm7 + vpsrld $7,%xmm6,%xmm1 + vpslld $25,%xmm6,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm6,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm6,%xmm2 + vmovdqu 192-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm5,%xmm5 + vpxor %xmm1,%xmm3,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm5,%xmm5 + vpsrld $6,%xmm14,%xmm7 + vpslld $26,%xmm14,%xmm2 + vmovdqu %xmm5,224-128(%rax) + vpaddd %xmm9,%xmm5,%xmm5 + + vpsrld $11,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm14,%xmm2 + vpaddd 64(%rbp),%xmm5,%xmm5 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm14,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm14,%xmm2 + vpandn %xmm8,%xmm14,%xmm0 + vpand %xmm15,%xmm14,%xmm3 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm10,%xmm9 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm10,%xmm1 + vpxor %xmm3,%xmm0,%xmm0 + vpxor %xmm10,%xmm11,%xmm3 + + vpxor %xmm1,%xmm9,%xmm9 + vpaddd %xmm7,%xmm5,%xmm5 + + vpsrld $13,%xmm10,%xmm1 + + vpslld $19,%xmm10,%xmm2 + vpaddd %xmm0,%xmm5,%xmm5 + vpand %xmm3,%xmm4,%xmm4 + + vpxor %xmm1,%xmm9,%xmm7 + + vpsrld $22,%xmm10,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm10,%xmm2 + vpxor %xmm4,%xmm11,%xmm9 + vpaddd %xmm5,%xmm13,%xmm13 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm5,%xmm9,%xmm9 + vpaddd %xmm7,%xmm9,%xmm9 + vmovdqu 0-128(%rax),%xmm5 + vpaddd 128-128(%rax),%xmm6,%xmm6 + + vpsrld $3,%xmm5,%xmm7 + vpsrld $7,%xmm5,%xmm1 + vpslld $25,%xmm5,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $18,%xmm5,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $14,%xmm5,%xmm2 + vmovdqu 208-128(%rax),%xmm0 + vpsrld $10,%xmm0,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + vpsrld $17,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $15,%xmm0,%xmm2 + vpaddd %xmm7,%xmm6,%xmm6 + vpxor %xmm1,%xmm4,%xmm7 + vpsrld $19,%xmm0,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $13,%xmm0,%xmm2 + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + vpaddd %xmm7,%xmm6,%xmm6 + vpsrld $6,%xmm13,%xmm7 + vpslld $26,%xmm13,%xmm2 + vmovdqu %xmm6,240-128(%rax) + vpaddd %xmm8,%xmm6,%xmm6 + + vpsrld $11,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + vpslld $21,%xmm13,%xmm2 + vpaddd 96(%rbp),%xmm6,%xmm6 + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $25,%xmm13,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $7,%xmm13,%xmm2 + vpandn %xmm15,%xmm13,%xmm0 + vpand %xmm14,%xmm13,%xmm4 + + vpxor %xmm1,%xmm7,%xmm7 + + vpsrld $2,%xmm9,%xmm8 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $30,%xmm9,%xmm1 + vpxor %xmm4,%xmm0,%xmm0 + vpxor %xmm9,%xmm10,%xmm4 + + vpxor %xmm1,%xmm8,%xmm8 + vpaddd %xmm7,%xmm6,%xmm6 + + vpsrld $13,%xmm9,%xmm1 + + vpslld $19,%xmm9,%xmm2 + vpaddd %xmm0,%xmm6,%xmm6 + vpand %xmm4,%xmm3,%xmm3 + + vpxor %xmm1,%xmm8,%xmm7 + + vpsrld $22,%xmm9,%xmm1 + vpxor %xmm2,%xmm7,%xmm7 + + vpslld $10,%xmm9,%xmm2 + vpxor %xmm3,%xmm10,%xmm8 + vpaddd %xmm6,%xmm12,%xmm12 + + vpxor %xmm1,%xmm7,%xmm7 + vpxor %xmm2,%xmm7,%xmm7 + + vpaddd %xmm6,%xmm8,%xmm8 + vpaddd %xmm7,%xmm8,%xmm8 + addq $256,%rbp + decl %ecx + jnz .Loop_16_xx_avx + + movl $1,%ecx + leaq K256+128(%rip),%rbp + cmpl 0(%rbx),%ecx + cmovgeq %rbp,%r8 + cmpl 4(%rbx),%ecx + cmovgeq %rbp,%r9 + cmpl 8(%rbx),%ecx + cmovgeq %rbp,%r10 + cmpl 12(%rbx),%ecx + cmovgeq %rbp,%r11 + vmovdqa (%rbx),%xmm7 + vpxor %xmm0,%xmm0,%xmm0 + vmovdqa %xmm7,%xmm6 + vpcmpgtd %xmm0,%xmm6,%xmm6 + vpaddd %xmm6,%xmm7,%xmm7 + + vmovdqu 0-128(%rdi),%xmm0 + vpand %xmm6,%xmm8,%xmm8 + vmovdqu 32-128(%rdi),%xmm1 + vpand %xmm6,%xmm9,%xmm9 + vmovdqu 64-128(%rdi),%xmm2 + vpand %xmm6,%xmm10,%xmm10 + vmovdqu 96-128(%rdi),%xmm5 + vpand %xmm6,%xmm11,%xmm11 + vpaddd %xmm0,%xmm8,%xmm8 + vmovdqu 128-128(%rdi),%xmm0 + vpand %xmm6,%xmm12,%xmm12 + vpaddd %xmm1,%xmm9,%xmm9 + vmovdqu 160-128(%rdi),%xmm1 + vpand %xmm6,%xmm13,%xmm13 + vpaddd %xmm2,%xmm10,%xmm10 + vmovdqu 192-128(%rdi),%xmm2 + vpand %xmm6,%xmm14,%xmm14 + vpaddd %xmm5,%xmm11,%xmm11 + vmovdqu 224-128(%rdi),%xmm5 + vpand %xmm6,%xmm15,%xmm15 + vpaddd %xmm0,%xmm12,%xmm12 + vpaddd %xmm1,%xmm13,%xmm13 + vmovdqu %xmm8,0-128(%rdi) + vpaddd %xmm2,%xmm14,%xmm14 + vmovdqu %xmm9,32-128(%rdi) + vpaddd %xmm5,%xmm15,%xmm15 + vmovdqu %xmm10,64-128(%rdi) + vmovdqu %xmm11,96-128(%rdi) + vmovdqu %xmm12,128-128(%rdi) + vmovdqu %xmm13,160-128(%rdi) + vmovdqu %xmm14,192-128(%rdi) + vmovdqu %xmm15,224-128(%rdi) + + vmovdqu %xmm7,(%rbx) + vmovdqu .Lpbswap(%rip),%xmm6 + decl %edx + jnz .Loop_avx + + movl 280(%rsp),%edx + leaq 16(%rdi),%rdi + leaq 64(%rsi),%rsi + decl %edx + jnz .Loop_grande_avx + +.Ldone_avx: + movq 272(%rsp),%rax +.cfi_def_cfa %rax,8 + vzeroupper + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_multi_block_avx,.-sha256_multi_block_avx +.type sha256_multi_block_avx2,@function +.align 32 +sha256_multi_block_avx2: +.cfi_startproc +_avx2_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + subq $576,%rsp + andq $-256,%rsp + movq %rax,544(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xa0,0x04,0x06,0x23,0x08 +.Lbody_avx2: + leaq K256+128(%rip),%rbp + leaq 128(%rdi),%rdi + +.Loop_grande_avx2: + movl %edx,552(%rsp) + xorl %edx,%edx + leaq 512(%rsp),%rbx + + movq 0(%rsi),%r12 + + movl 8(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,0(%rbx) + cmovleq %rbp,%r12 + + movq 16(%rsi),%r13 + + movl 24(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,4(%rbx) + cmovleq %rbp,%r13 + + movq 32(%rsi),%r14 + + movl 40(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,8(%rbx) + cmovleq %rbp,%r14 + + movq 48(%rsi),%r15 + + movl 56(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,12(%rbx) + cmovleq %rbp,%r15 + + movq 64(%rsi),%r8 + + movl 72(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,16(%rbx) + cmovleq %rbp,%r8 + + movq 80(%rsi),%r9 + + movl 88(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,20(%rbx) + cmovleq %rbp,%r9 + + movq 96(%rsi),%r10 + + movl 104(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,24(%rbx) + cmovleq %rbp,%r10 + + movq 112(%rsi),%r11 + + movl 120(%rsi),%ecx + cmpl %edx,%ecx + cmovgl %ecx,%edx + testl %ecx,%ecx + movl %ecx,28(%rbx) + cmovleq %rbp,%r11 + vmovdqu 0-128(%rdi),%ymm8 + leaq 128(%rsp),%rax + vmovdqu 32-128(%rdi),%ymm9 + leaq 256+128(%rsp),%rbx + vmovdqu 64-128(%rdi),%ymm10 + vmovdqu 96-128(%rdi),%ymm11 + vmovdqu 128-128(%rdi),%ymm12 + vmovdqu 160-128(%rdi),%ymm13 + vmovdqu 192-128(%rdi),%ymm14 + vmovdqu 224-128(%rdi),%ymm15 + vmovdqu .Lpbswap(%rip),%ymm6 + jmp .Loop_avx2 + +.align 32 +.Loop_avx2: + vpxor %ymm9,%ymm10,%ymm4 + vmovd 0(%r12),%xmm5 + vmovd 0(%r8),%xmm0 + vmovd 0(%r13),%xmm1 + vmovd 0(%r9),%xmm2 + vpinsrd $1,0(%r14),%xmm5,%xmm5 + vpinsrd $1,0(%r10),%xmm0,%xmm0 + vpinsrd $1,0(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,0(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm12,%ymm7 + vpslld $26,%ymm12,%ymm2 + vmovdqu %ymm5,0-128(%rax) + vpaddd %ymm15,%ymm5,%ymm5 + + vpsrld $11,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm12,%ymm2 + vpaddd -128(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm12,%ymm2 + vpandn %ymm14,%ymm12,%ymm0 + vpand %ymm13,%ymm12,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm8,%ymm15 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm8,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm8,%ymm9,%ymm3 + + vpxor %ymm1,%ymm15,%ymm15 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm8,%ymm1 + + vpslld $19,%ymm8,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm15,%ymm7 + + vpsrld $22,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm8,%ymm2 + vpxor %ymm4,%ymm9,%ymm15 + vpaddd %ymm5,%ymm11,%ymm11 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm15,%ymm15 + vpaddd %ymm7,%ymm15,%ymm15 + vmovd 4(%r12),%xmm5 + vmovd 4(%r8),%xmm0 + vmovd 4(%r13),%xmm1 + vmovd 4(%r9),%xmm2 + vpinsrd $1,4(%r14),%xmm5,%xmm5 + vpinsrd $1,4(%r10),%xmm0,%xmm0 + vpinsrd $1,4(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,4(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm11,%ymm7 + vpslld $26,%ymm11,%ymm2 + vmovdqu %ymm5,32-128(%rax) + vpaddd %ymm14,%ymm5,%ymm5 + + vpsrld $11,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm11,%ymm2 + vpaddd -96(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm11,%ymm2 + vpandn %ymm13,%ymm11,%ymm0 + vpand %ymm12,%ymm11,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm15,%ymm14 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm15,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm15,%ymm8,%ymm4 + + vpxor %ymm1,%ymm14,%ymm14 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm15,%ymm1 + + vpslld $19,%ymm15,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm14,%ymm7 + + vpsrld $22,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm15,%ymm2 + vpxor %ymm3,%ymm8,%ymm14 + vpaddd %ymm5,%ymm10,%ymm10 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm14,%ymm14 + vpaddd %ymm7,%ymm14,%ymm14 + vmovd 8(%r12),%xmm5 + vmovd 8(%r8),%xmm0 + vmovd 8(%r13),%xmm1 + vmovd 8(%r9),%xmm2 + vpinsrd $1,8(%r14),%xmm5,%xmm5 + vpinsrd $1,8(%r10),%xmm0,%xmm0 + vpinsrd $1,8(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,8(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm10,%ymm7 + vpslld $26,%ymm10,%ymm2 + vmovdqu %ymm5,64-128(%rax) + vpaddd %ymm13,%ymm5,%ymm5 + + vpsrld $11,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm10,%ymm2 + vpaddd -64(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm10,%ymm2 + vpandn %ymm12,%ymm10,%ymm0 + vpand %ymm11,%ymm10,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm14,%ymm13 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm14,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm14,%ymm15,%ymm3 + + vpxor %ymm1,%ymm13,%ymm13 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm14,%ymm1 + + vpslld $19,%ymm14,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm13,%ymm7 + + vpsrld $22,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm14,%ymm2 + vpxor %ymm4,%ymm15,%ymm13 + vpaddd %ymm5,%ymm9,%ymm9 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm13,%ymm13 + vpaddd %ymm7,%ymm13,%ymm13 + vmovd 12(%r12),%xmm5 + vmovd 12(%r8),%xmm0 + vmovd 12(%r13),%xmm1 + vmovd 12(%r9),%xmm2 + vpinsrd $1,12(%r14),%xmm5,%xmm5 + vpinsrd $1,12(%r10),%xmm0,%xmm0 + vpinsrd $1,12(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,12(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm9,%ymm7 + vpslld $26,%ymm9,%ymm2 + vmovdqu %ymm5,96-128(%rax) + vpaddd %ymm12,%ymm5,%ymm5 + + vpsrld $11,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm9,%ymm2 + vpaddd -32(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm9,%ymm2 + vpandn %ymm11,%ymm9,%ymm0 + vpand %ymm10,%ymm9,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm13,%ymm12 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm13,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm13,%ymm14,%ymm4 + + vpxor %ymm1,%ymm12,%ymm12 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm13,%ymm1 + + vpslld $19,%ymm13,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm12,%ymm7 + + vpsrld $22,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm13,%ymm2 + vpxor %ymm3,%ymm14,%ymm12 + vpaddd %ymm5,%ymm8,%ymm8 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm12,%ymm12 + vpaddd %ymm7,%ymm12,%ymm12 + vmovd 16(%r12),%xmm5 + vmovd 16(%r8),%xmm0 + vmovd 16(%r13),%xmm1 + vmovd 16(%r9),%xmm2 + vpinsrd $1,16(%r14),%xmm5,%xmm5 + vpinsrd $1,16(%r10),%xmm0,%xmm0 + vpinsrd $1,16(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,16(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm8,%ymm7 + vpslld $26,%ymm8,%ymm2 + vmovdqu %ymm5,128-128(%rax) + vpaddd %ymm11,%ymm5,%ymm5 + + vpsrld $11,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm8,%ymm2 + vpaddd 0(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm8,%ymm2 + vpandn %ymm10,%ymm8,%ymm0 + vpand %ymm9,%ymm8,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm12,%ymm11 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm12,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm12,%ymm13,%ymm3 + + vpxor %ymm1,%ymm11,%ymm11 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm12,%ymm1 + + vpslld $19,%ymm12,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm11,%ymm7 + + vpsrld $22,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm12,%ymm2 + vpxor %ymm4,%ymm13,%ymm11 + vpaddd %ymm5,%ymm15,%ymm15 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm11,%ymm11 + vpaddd %ymm7,%ymm11,%ymm11 + vmovd 20(%r12),%xmm5 + vmovd 20(%r8),%xmm0 + vmovd 20(%r13),%xmm1 + vmovd 20(%r9),%xmm2 + vpinsrd $1,20(%r14),%xmm5,%xmm5 + vpinsrd $1,20(%r10),%xmm0,%xmm0 + vpinsrd $1,20(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,20(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm15,%ymm7 + vpslld $26,%ymm15,%ymm2 + vmovdqu %ymm5,160-128(%rax) + vpaddd %ymm10,%ymm5,%ymm5 + + vpsrld $11,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm15,%ymm2 + vpaddd 32(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm15,%ymm2 + vpandn %ymm9,%ymm15,%ymm0 + vpand %ymm8,%ymm15,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm11,%ymm10 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm11,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm11,%ymm12,%ymm4 + + vpxor %ymm1,%ymm10,%ymm10 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm11,%ymm1 + + vpslld $19,%ymm11,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm10,%ymm7 + + vpsrld $22,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm11,%ymm2 + vpxor %ymm3,%ymm12,%ymm10 + vpaddd %ymm5,%ymm14,%ymm14 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm10,%ymm10 + vpaddd %ymm7,%ymm10,%ymm10 + vmovd 24(%r12),%xmm5 + vmovd 24(%r8),%xmm0 + vmovd 24(%r13),%xmm1 + vmovd 24(%r9),%xmm2 + vpinsrd $1,24(%r14),%xmm5,%xmm5 + vpinsrd $1,24(%r10),%xmm0,%xmm0 + vpinsrd $1,24(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,24(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm14,%ymm7 + vpslld $26,%ymm14,%ymm2 + vmovdqu %ymm5,192-128(%rax) + vpaddd %ymm9,%ymm5,%ymm5 + + vpsrld $11,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm14,%ymm2 + vpaddd 64(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm14,%ymm2 + vpandn %ymm8,%ymm14,%ymm0 + vpand %ymm15,%ymm14,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm10,%ymm9 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm10,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm10,%ymm11,%ymm3 + + vpxor %ymm1,%ymm9,%ymm9 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm10,%ymm1 + + vpslld $19,%ymm10,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm9,%ymm7 + + vpsrld $22,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm10,%ymm2 + vpxor %ymm4,%ymm11,%ymm9 + vpaddd %ymm5,%ymm13,%ymm13 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm9,%ymm9 + vpaddd %ymm7,%ymm9,%ymm9 + vmovd 28(%r12),%xmm5 + vmovd 28(%r8),%xmm0 + vmovd 28(%r13),%xmm1 + vmovd 28(%r9),%xmm2 + vpinsrd $1,28(%r14),%xmm5,%xmm5 + vpinsrd $1,28(%r10),%xmm0,%xmm0 + vpinsrd $1,28(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,28(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm13,%ymm7 + vpslld $26,%ymm13,%ymm2 + vmovdqu %ymm5,224-128(%rax) + vpaddd %ymm8,%ymm5,%ymm5 + + vpsrld $11,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm13,%ymm2 + vpaddd 96(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm13,%ymm2 + vpandn %ymm15,%ymm13,%ymm0 + vpand %ymm14,%ymm13,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm9,%ymm8 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm9,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm9,%ymm10,%ymm4 + + vpxor %ymm1,%ymm8,%ymm8 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm9,%ymm1 + + vpslld $19,%ymm9,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm8,%ymm7 + + vpsrld $22,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm9,%ymm2 + vpxor %ymm3,%ymm10,%ymm8 + vpaddd %ymm5,%ymm12,%ymm12 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm8,%ymm8 + vpaddd %ymm7,%ymm8,%ymm8 + addq $256,%rbp + vmovd 32(%r12),%xmm5 + vmovd 32(%r8),%xmm0 + vmovd 32(%r13),%xmm1 + vmovd 32(%r9),%xmm2 + vpinsrd $1,32(%r14),%xmm5,%xmm5 + vpinsrd $1,32(%r10),%xmm0,%xmm0 + vpinsrd $1,32(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,32(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm12,%ymm7 + vpslld $26,%ymm12,%ymm2 + vmovdqu %ymm5,256-256-128(%rbx) + vpaddd %ymm15,%ymm5,%ymm5 + + vpsrld $11,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm12,%ymm2 + vpaddd -128(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm12,%ymm2 + vpandn %ymm14,%ymm12,%ymm0 + vpand %ymm13,%ymm12,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm8,%ymm15 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm8,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm8,%ymm9,%ymm3 + + vpxor %ymm1,%ymm15,%ymm15 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm8,%ymm1 + + vpslld $19,%ymm8,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm15,%ymm7 + + vpsrld $22,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm8,%ymm2 + vpxor %ymm4,%ymm9,%ymm15 + vpaddd %ymm5,%ymm11,%ymm11 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm15,%ymm15 + vpaddd %ymm7,%ymm15,%ymm15 + vmovd 36(%r12),%xmm5 + vmovd 36(%r8),%xmm0 + vmovd 36(%r13),%xmm1 + vmovd 36(%r9),%xmm2 + vpinsrd $1,36(%r14),%xmm5,%xmm5 + vpinsrd $1,36(%r10),%xmm0,%xmm0 + vpinsrd $1,36(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,36(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm11,%ymm7 + vpslld $26,%ymm11,%ymm2 + vmovdqu %ymm5,288-256-128(%rbx) + vpaddd %ymm14,%ymm5,%ymm5 + + vpsrld $11,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm11,%ymm2 + vpaddd -96(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm11,%ymm2 + vpandn %ymm13,%ymm11,%ymm0 + vpand %ymm12,%ymm11,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm15,%ymm14 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm15,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm15,%ymm8,%ymm4 + + vpxor %ymm1,%ymm14,%ymm14 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm15,%ymm1 + + vpslld $19,%ymm15,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm14,%ymm7 + + vpsrld $22,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm15,%ymm2 + vpxor %ymm3,%ymm8,%ymm14 + vpaddd %ymm5,%ymm10,%ymm10 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm14,%ymm14 + vpaddd %ymm7,%ymm14,%ymm14 + vmovd 40(%r12),%xmm5 + vmovd 40(%r8),%xmm0 + vmovd 40(%r13),%xmm1 + vmovd 40(%r9),%xmm2 + vpinsrd $1,40(%r14),%xmm5,%xmm5 + vpinsrd $1,40(%r10),%xmm0,%xmm0 + vpinsrd $1,40(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,40(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm10,%ymm7 + vpslld $26,%ymm10,%ymm2 + vmovdqu %ymm5,320-256-128(%rbx) + vpaddd %ymm13,%ymm5,%ymm5 + + vpsrld $11,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm10,%ymm2 + vpaddd -64(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm10,%ymm2 + vpandn %ymm12,%ymm10,%ymm0 + vpand %ymm11,%ymm10,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm14,%ymm13 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm14,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm14,%ymm15,%ymm3 + + vpxor %ymm1,%ymm13,%ymm13 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm14,%ymm1 + + vpslld $19,%ymm14,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm13,%ymm7 + + vpsrld $22,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm14,%ymm2 + vpxor %ymm4,%ymm15,%ymm13 + vpaddd %ymm5,%ymm9,%ymm9 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm13,%ymm13 + vpaddd %ymm7,%ymm13,%ymm13 + vmovd 44(%r12),%xmm5 + vmovd 44(%r8),%xmm0 + vmovd 44(%r13),%xmm1 + vmovd 44(%r9),%xmm2 + vpinsrd $1,44(%r14),%xmm5,%xmm5 + vpinsrd $1,44(%r10),%xmm0,%xmm0 + vpinsrd $1,44(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,44(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm9,%ymm7 + vpslld $26,%ymm9,%ymm2 + vmovdqu %ymm5,352-256-128(%rbx) + vpaddd %ymm12,%ymm5,%ymm5 + + vpsrld $11,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm9,%ymm2 + vpaddd -32(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm9,%ymm2 + vpandn %ymm11,%ymm9,%ymm0 + vpand %ymm10,%ymm9,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm13,%ymm12 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm13,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm13,%ymm14,%ymm4 + + vpxor %ymm1,%ymm12,%ymm12 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm13,%ymm1 + + vpslld $19,%ymm13,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm12,%ymm7 + + vpsrld $22,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm13,%ymm2 + vpxor %ymm3,%ymm14,%ymm12 + vpaddd %ymm5,%ymm8,%ymm8 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm12,%ymm12 + vpaddd %ymm7,%ymm12,%ymm12 + vmovd 48(%r12),%xmm5 + vmovd 48(%r8),%xmm0 + vmovd 48(%r13),%xmm1 + vmovd 48(%r9),%xmm2 + vpinsrd $1,48(%r14),%xmm5,%xmm5 + vpinsrd $1,48(%r10),%xmm0,%xmm0 + vpinsrd $1,48(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,48(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm8,%ymm7 + vpslld $26,%ymm8,%ymm2 + vmovdqu %ymm5,384-256-128(%rbx) + vpaddd %ymm11,%ymm5,%ymm5 + + vpsrld $11,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm8,%ymm2 + vpaddd 0(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm8,%ymm2 + vpandn %ymm10,%ymm8,%ymm0 + vpand %ymm9,%ymm8,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm12,%ymm11 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm12,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm12,%ymm13,%ymm3 + + vpxor %ymm1,%ymm11,%ymm11 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm12,%ymm1 + + vpslld $19,%ymm12,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm11,%ymm7 + + vpsrld $22,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm12,%ymm2 + vpxor %ymm4,%ymm13,%ymm11 + vpaddd %ymm5,%ymm15,%ymm15 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm11,%ymm11 + vpaddd %ymm7,%ymm11,%ymm11 + vmovd 52(%r12),%xmm5 + vmovd 52(%r8),%xmm0 + vmovd 52(%r13),%xmm1 + vmovd 52(%r9),%xmm2 + vpinsrd $1,52(%r14),%xmm5,%xmm5 + vpinsrd $1,52(%r10),%xmm0,%xmm0 + vpinsrd $1,52(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,52(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm15,%ymm7 + vpslld $26,%ymm15,%ymm2 + vmovdqu %ymm5,416-256-128(%rbx) + vpaddd %ymm10,%ymm5,%ymm5 + + vpsrld $11,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm15,%ymm2 + vpaddd 32(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm15,%ymm2 + vpandn %ymm9,%ymm15,%ymm0 + vpand %ymm8,%ymm15,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm11,%ymm10 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm11,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm11,%ymm12,%ymm4 + + vpxor %ymm1,%ymm10,%ymm10 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm11,%ymm1 + + vpslld $19,%ymm11,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm10,%ymm7 + + vpsrld $22,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm11,%ymm2 + vpxor %ymm3,%ymm12,%ymm10 + vpaddd %ymm5,%ymm14,%ymm14 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm10,%ymm10 + vpaddd %ymm7,%ymm10,%ymm10 + vmovd 56(%r12),%xmm5 + vmovd 56(%r8),%xmm0 + vmovd 56(%r13),%xmm1 + vmovd 56(%r9),%xmm2 + vpinsrd $1,56(%r14),%xmm5,%xmm5 + vpinsrd $1,56(%r10),%xmm0,%xmm0 + vpinsrd $1,56(%r15),%xmm1,%xmm1 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,56(%r11),%xmm2,%xmm2 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm14,%ymm7 + vpslld $26,%ymm14,%ymm2 + vmovdqu %ymm5,448-256-128(%rbx) + vpaddd %ymm9,%ymm5,%ymm5 + + vpsrld $11,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm14,%ymm2 + vpaddd 64(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm14,%ymm2 + vpandn %ymm8,%ymm14,%ymm0 + vpand %ymm15,%ymm14,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm10,%ymm9 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm10,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm10,%ymm11,%ymm3 + + vpxor %ymm1,%ymm9,%ymm9 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm10,%ymm1 + + vpslld $19,%ymm10,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm9,%ymm7 + + vpsrld $22,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm10,%ymm2 + vpxor %ymm4,%ymm11,%ymm9 + vpaddd %ymm5,%ymm13,%ymm13 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm9,%ymm9 + vpaddd %ymm7,%ymm9,%ymm9 + vmovd 60(%r12),%xmm5 + leaq 64(%r12),%r12 + vmovd 60(%r8),%xmm0 + leaq 64(%r8),%r8 + vmovd 60(%r13),%xmm1 + leaq 64(%r13),%r13 + vmovd 60(%r9),%xmm2 + leaq 64(%r9),%r9 + vpinsrd $1,60(%r14),%xmm5,%xmm5 + leaq 64(%r14),%r14 + vpinsrd $1,60(%r10),%xmm0,%xmm0 + leaq 64(%r10),%r10 + vpinsrd $1,60(%r15),%xmm1,%xmm1 + leaq 64(%r15),%r15 + vpunpckldq %ymm1,%ymm5,%ymm5 + vpinsrd $1,60(%r11),%xmm2,%xmm2 + leaq 64(%r11),%r11 + vpunpckldq %ymm2,%ymm0,%ymm0 + vinserti128 $1,%xmm0,%ymm5,%ymm5 + vpshufb %ymm6,%ymm5,%ymm5 + vpsrld $6,%ymm13,%ymm7 + vpslld $26,%ymm13,%ymm2 + vmovdqu %ymm5,480-256-128(%rbx) + vpaddd %ymm8,%ymm5,%ymm5 + + vpsrld $11,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm13,%ymm2 + vpaddd 96(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + prefetcht0 63(%r12) + vpslld $7,%ymm13,%ymm2 + vpandn %ymm15,%ymm13,%ymm0 + vpand %ymm14,%ymm13,%ymm4 + prefetcht0 63(%r13) + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm9,%ymm8 + vpxor %ymm2,%ymm7,%ymm7 + prefetcht0 63(%r14) + vpslld $30,%ymm9,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm9,%ymm10,%ymm4 + prefetcht0 63(%r15) + vpxor %ymm1,%ymm8,%ymm8 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm9,%ymm1 + prefetcht0 63(%r8) + vpslld $19,%ymm9,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm4,%ymm3,%ymm3 + prefetcht0 63(%r9) + vpxor %ymm1,%ymm8,%ymm7 + + vpsrld $22,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + prefetcht0 63(%r10) + vpslld $10,%ymm9,%ymm2 + vpxor %ymm3,%ymm10,%ymm8 + vpaddd %ymm5,%ymm12,%ymm12 + prefetcht0 63(%r11) + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm8,%ymm8 + vpaddd %ymm7,%ymm8,%ymm8 + addq $256,%rbp + vmovdqu 0-128(%rax),%ymm5 + movl $3,%ecx + jmp .Loop_16_xx_avx2 +.align 32 +.Loop_16_xx_avx2: + vmovdqu 32-128(%rax),%ymm6 + vpaddd 288-256-128(%rbx),%ymm5,%ymm5 + + vpsrld $3,%ymm6,%ymm7 + vpsrld $7,%ymm6,%ymm1 + vpslld $25,%ymm6,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm6,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm6,%ymm2 + vmovdqu 448-256-128(%rbx),%ymm0 + vpsrld $10,%ymm0,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm5,%ymm5 + vpxor %ymm1,%ymm3,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm5,%ymm5 + vpsrld $6,%ymm12,%ymm7 + vpslld $26,%ymm12,%ymm2 + vmovdqu %ymm5,0-128(%rax) + vpaddd %ymm15,%ymm5,%ymm5 + + vpsrld $11,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm12,%ymm2 + vpaddd -128(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm12,%ymm2 + vpandn %ymm14,%ymm12,%ymm0 + vpand %ymm13,%ymm12,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm8,%ymm15 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm8,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm8,%ymm9,%ymm3 + + vpxor %ymm1,%ymm15,%ymm15 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm8,%ymm1 + + vpslld $19,%ymm8,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm15,%ymm7 + + vpsrld $22,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm8,%ymm2 + vpxor %ymm4,%ymm9,%ymm15 + vpaddd %ymm5,%ymm11,%ymm11 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm15,%ymm15 + vpaddd %ymm7,%ymm15,%ymm15 + vmovdqu 64-128(%rax),%ymm5 + vpaddd 320-256-128(%rbx),%ymm6,%ymm6 + + vpsrld $3,%ymm5,%ymm7 + vpsrld $7,%ymm5,%ymm1 + vpslld $25,%ymm5,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm5,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm5,%ymm2 + vmovdqu 480-256-128(%rbx),%ymm0 + vpsrld $10,%ymm0,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm6,%ymm6 + vpxor %ymm1,%ymm4,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm6,%ymm6 + vpsrld $6,%ymm11,%ymm7 + vpslld $26,%ymm11,%ymm2 + vmovdqu %ymm6,32-128(%rax) + vpaddd %ymm14,%ymm6,%ymm6 + + vpsrld $11,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm11,%ymm2 + vpaddd -96(%rbp),%ymm6,%ymm6 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm11,%ymm2 + vpandn %ymm13,%ymm11,%ymm0 + vpand %ymm12,%ymm11,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm15,%ymm14 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm15,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm15,%ymm8,%ymm4 + + vpxor %ymm1,%ymm14,%ymm14 + vpaddd %ymm7,%ymm6,%ymm6 + + vpsrld $13,%ymm15,%ymm1 + + vpslld $19,%ymm15,%ymm2 + vpaddd %ymm0,%ymm6,%ymm6 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm14,%ymm7 + + vpsrld $22,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm15,%ymm2 + vpxor %ymm3,%ymm8,%ymm14 + vpaddd %ymm6,%ymm10,%ymm10 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm6,%ymm14,%ymm14 + vpaddd %ymm7,%ymm14,%ymm14 + vmovdqu 96-128(%rax),%ymm6 + vpaddd 352-256-128(%rbx),%ymm5,%ymm5 + + vpsrld $3,%ymm6,%ymm7 + vpsrld $7,%ymm6,%ymm1 + vpslld $25,%ymm6,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm6,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm6,%ymm2 + vmovdqu 0-128(%rax),%ymm0 + vpsrld $10,%ymm0,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm5,%ymm5 + vpxor %ymm1,%ymm3,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm5,%ymm5 + vpsrld $6,%ymm10,%ymm7 + vpslld $26,%ymm10,%ymm2 + vmovdqu %ymm5,64-128(%rax) + vpaddd %ymm13,%ymm5,%ymm5 + + vpsrld $11,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm10,%ymm2 + vpaddd -64(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm10,%ymm2 + vpandn %ymm12,%ymm10,%ymm0 + vpand %ymm11,%ymm10,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm14,%ymm13 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm14,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm14,%ymm15,%ymm3 + + vpxor %ymm1,%ymm13,%ymm13 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm14,%ymm1 + + vpslld $19,%ymm14,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm13,%ymm7 + + vpsrld $22,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm14,%ymm2 + vpxor %ymm4,%ymm15,%ymm13 + vpaddd %ymm5,%ymm9,%ymm9 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm13,%ymm13 + vpaddd %ymm7,%ymm13,%ymm13 + vmovdqu 128-128(%rax),%ymm5 + vpaddd 384-256-128(%rbx),%ymm6,%ymm6 + + vpsrld $3,%ymm5,%ymm7 + vpsrld $7,%ymm5,%ymm1 + vpslld $25,%ymm5,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm5,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm5,%ymm2 + vmovdqu 32-128(%rax),%ymm0 + vpsrld $10,%ymm0,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm6,%ymm6 + vpxor %ymm1,%ymm4,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm6,%ymm6 + vpsrld $6,%ymm9,%ymm7 + vpslld $26,%ymm9,%ymm2 + vmovdqu %ymm6,96-128(%rax) + vpaddd %ymm12,%ymm6,%ymm6 + + vpsrld $11,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm9,%ymm2 + vpaddd -32(%rbp),%ymm6,%ymm6 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm9,%ymm2 + vpandn %ymm11,%ymm9,%ymm0 + vpand %ymm10,%ymm9,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm13,%ymm12 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm13,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm13,%ymm14,%ymm4 + + vpxor %ymm1,%ymm12,%ymm12 + vpaddd %ymm7,%ymm6,%ymm6 + + vpsrld $13,%ymm13,%ymm1 + + vpslld $19,%ymm13,%ymm2 + vpaddd %ymm0,%ymm6,%ymm6 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm12,%ymm7 + + vpsrld $22,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm13,%ymm2 + vpxor %ymm3,%ymm14,%ymm12 + vpaddd %ymm6,%ymm8,%ymm8 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm6,%ymm12,%ymm12 + vpaddd %ymm7,%ymm12,%ymm12 + vmovdqu 160-128(%rax),%ymm6 + vpaddd 416-256-128(%rbx),%ymm5,%ymm5 + + vpsrld $3,%ymm6,%ymm7 + vpsrld $7,%ymm6,%ymm1 + vpslld $25,%ymm6,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm6,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm6,%ymm2 + vmovdqu 64-128(%rax),%ymm0 + vpsrld $10,%ymm0,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm5,%ymm5 + vpxor %ymm1,%ymm3,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm5,%ymm5 + vpsrld $6,%ymm8,%ymm7 + vpslld $26,%ymm8,%ymm2 + vmovdqu %ymm5,128-128(%rax) + vpaddd %ymm11,%ymm5,%ymm5 + + vpsrld $11,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm8,%ymm2 + vpaddd 0(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm8,%ymm2 + vpandn %ymm10,%ymm8,%ymm0 + vpand %ymm9,%ymm8,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm12,%ymm11 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm12,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm12,%ymm13,%ymm3 + + vpxor %ymm1,%ymm11,%ymm11 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm12,%ymm1 + + vpslld $19,%ymm12,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm11,%ymm7 + + vpsrld $22,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm12,%ymm2 + vpxor %ymm4,%ymm13,%ymm11 + vpaddd %ymm5,%ymm15,%ymm15 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm11,%ymm11 + vpaddd %ymm7,%ymm11,%ymm11 + vmovdqu 192-128(%rax),%ymm5 + vpaddd 448-256-128(%rbx),%ymm6,%ymm6 + + vpsrld $3,%ymm5,%ymm7 + vpsrld $7,%ymm5,%ymm1 + vpslld $25,%ymm5,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm5,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm5,%ymm2 + vmovdqu 96-128(%rax),%ymm0 + vpsrld $10,%ymm0,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm6,%ymm6 + vpxor %ymm1,%ymm4,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm6,%ymm6 + vpsrld $6,%ymm15,%ymm7 + vpslld $26,%ymm15,%ymm2 + vmovdqu %ymm6,160-128(%rax) + vpaddd %ymm10,%ymm6,%ymm6 + + vpsrld $11,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm15,%ymm2 + vpaddd 32(%rbp),%ymm6,%ymm6 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm15,%ymm2 + vpandn %ymm9,%ymm15,%ymm0 + vpand %ymm8,%ymm15,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm11,%ymm10 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm11,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm11,%ymm12,%ymm4 + + vpxor %ymm1,%ymm10,%ymm10 + vpaddd %ymm7,%ymm6,%ymm6 + + vpsrld $13,%ymm11,%ymm1 + + vpslld $19,%ymm11,%ymm2 + vpaddd %ymm0,%ymm6,%ymm6 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm10,%ymm7 + + vpsrld $22,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm11,%ymm2 + vpxor %ymm3,%ymm12,%ymm10 + vpaddd %ymm6,%ymm14,%ymm14 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm6,%ymm10,%ymm10 + vpaddd %ymm7,%ymm10,%ymm10 + vmovdqu 224-128(%rax),%ymm6 + vpaddd 480-256-128(%rbx),%ymm5,%ymm5 + + vpsrld $3,%ymm6,%ymm7 + vpsrld $7,%ymm6,%ymm1 + vpslld $25,%ymm6,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm6,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm6,%ymm2 + vmovdqu 128-128(%rax),%ymm0 + vpsrld $10,%ymm0,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm5,%ymm5 + vpxor %ymm1,%ymm3,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm5,%ymm5 + vpsrld $6,%ymm14,%ymm7 + vpslld $26,%ymm14,%ymm2 + vmovdqu %ymm5,192-128(%rax) + vpaddd %ymm9,%ymm5,%ymm5 + + vpsrld $11,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm14,%ymm2 + vpaddd 64(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm14,%ymm2 + vpandn %ymm8,%ymm14,%ymm0 + vpand %ymm15,%ymm14,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm10,%ymm9 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm10,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm10,%ymm11,%ymm3 + + vpxor %ymm1,%ymm9,%ymm9 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm10,%ymm1 + + vpslld $19,%ymm10,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm9,%ymm7 + + vpsrld $22,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm10,%ymm2 + vpxor %ymm4,%ymm11,%ymm9 + vpaddd %ymm5,%ymm13,%ymm13 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm9,%ymm9 + vpaddd %ymm7,%ymm9,%ymm9 + vmovdqu 256-256-128(%rbx),%ymm5 + vpaddd 0-128(%rax),%ymm6,%ymm6 + + vpsrld $3,%ymm5,%ymm7 + vpsrld $7,%ymm5,%ymm1 + vpslld $25,%ymm5,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm5,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm5,%ymm2 + vmovdqu 160-128(%rax),%ymm0 + vpsrld $10,%ymm0,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm6,%ymm6 + vpxor %ymm1,%ymm4,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm6,%ymm6 + vpsrld $6,%ymm13,%ymm7 + vpslld $26,%ymm13,%ymm2 + vmovdqu %ymm6,224-128(%rax) + vpaddd %ymm8,%ymm6,%ymm6 + + vpsrld $11,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm13,%ymm2 + vpaddd 96(%rbp),%ymm6,%ymm6 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm13,%ymm2 + vpandn %ymm15,%ymm13,%ymm0 + vpand %ymm14,%ymm13,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm9,%ymm8 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm9,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm9,%ymm10,%ymm4 + + vpxor %ymm1,%ymm8,%ymm8 + vpaddd %ymm7,%ymm6,%ymm6 + + vpsrld $13,%ymm9,%ymm1 + + vpslld $19,%ymm9,%ymm2 + vpaddd %ymm0,%ymm6,%ymm6 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm8,%ymm7 + + vpsrld $22,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm9,%ymm2 + vpxor %ymm3,%ymm10,%ymm8 + vpaddd %ymm6,%ymm12,%ymm12 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm6,%ymm8,%ymm8 + vpaddd %ymm7,%ymm8,%ymm8 + addq $256,%rbp + vmovdqu 288-256-128(%rbx),%ymm6 + vpaddd 32-128(%rax),%ymm5,%ymm5 + + vpsrld $3,%ymm6,%ymm7 + vpsrld $7,%ymm6,%ymm1 + vpslld $25,%ymm6,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm6,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm6,%ymm2 + vmovdqu 192-128(%rax),%ymm0 + vpsrld $10,%ymm0,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm5,%ymm5 + vpxor %ymm1,%ymm3,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm5,%ymm5 + vpsrld $6,%ymm12,%ymm7 + vpslld $26,%ymm12,%ymm2 + vmovdqu %ymm5,256-256-128(%rbx) + vpaddd %ymm15,%ymm5,%ymm5 + + vpsrld $11,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm12,%ymm2 + vpaddd -128(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm12,%ymm2 + vpandn %ymm14,%ymm12,%ymm0 + vpand %ymm13,%ymm12,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm8,%ymm15 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm8,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm8,%ymm9,%ymm3 + + vpxor %ymm1,%ymm15,%ymm15 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm8,%ymm1 + + vpslld $19,%ymm8,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm15,%ymm7 + + vpsrld $22,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm8,%ymm2 + vpxor %ymm4,%ymm9,%ymm15 + vpaddd %ymm5,%ymm11,%ymm11 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm15,%ymm15 + vpaddd %ymm7,%ymm15,%ymm15 + vmovdqu 320-256-128(%rbx),%ymm5 + vpaddd 64-128(%rax),%ymm6,%ymm6 + + vpsrld $3,%ymm5,%ymm7 + vpsrld $7,%ymm5,%ymm1 + vpslld $25,%ymm5,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm5,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm5,%ymm2 + vmovdqu 224-128(%rax),%ymm0 + vpsrld $10,%ymm0,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm6,%ymm6 + vpxor %ymm1,%ymm4,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm6,%ymm6 + vpsrld $6,%ymm11,%ymm7 + vpslld $26,%ymm11,%ymm2 + vmovdqu %ymm6,288-256-128(%rbx) + vpaddd %ymm14,%ymm6,%ymm6 + + vpsrld $11,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm11,%ymm2 + vpaddd -96(%rbp),%ymm6,%ymm6 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm11,%ymm2 + vpandn %ymm13,%ymm11,%ymm0 + vpand %ymm12,%ymm11,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm15,%ymm14 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm15,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm15,%ymm8,%ymm4 + + vpxor %ymm1,%ymm14,%ymm14 + vpaddd %ymm7,%ymm6,%ymm6 + + vpsrld $13,%ymm15,%ymm1 + + vpslld $19,%ymm15,%ymm2 + vpaddd %ymm0,%ymm6,%ymm6 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm14,%ymm7 + + vpsrld $22,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm15,%ymm2 + vpxor %ymm3,%ymm8,%ymm14 + vpaddd %ymm6,%ymm10,%ymm10 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm6,%ymm14,%ymm14 + vpaddd %ymm7,%ymm14,%ymm14 + vmovdqu 352-256-128(%rbx),%ymm6 + vpaddd 96-128(%rax),%ymm5,%ymm5 + + vpsrld $3,%ymm6,%ymm7 + vpsrld $7,%ymm6,%ymm1 + vpslld $25,%ymm6,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm6,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm6,%ymm2 + vmovdqu 256-256-128(%rbx),%ymm0 + vpsrld $10,%ymm0,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm5,%ymm5 + vpxor %ymm1,%ymm3,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm5,%ymm5 + vpsrld $6,%ymm10,%ymm7 + vpslld $26,%ymm10,%ymm2 + vmovdqu %ymm5,320-256-128(%rbx) + vpaddd %ymm13,%ymm5,%ymm5 + + vpsrld $11,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm10,%ymm2 + vpaddd -64(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm10,%ymm2 + vpandn %ymm12,%ymm10,%ymm0 + vpand %ymm11,%ymm10,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm14,%ymm13 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm14,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm14,%ymm15,%ymm3 + + vpxor %ymm1,%ymm13,%ymm13 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm14,%ymm1 + + vpslld $19,%ymm14,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm13,%ymm7 + + vpsrld $22,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm14,%ymm2 + vpxor %ymm4,%ymm15,%ymm13 + vpaddd %ymm5,%ymm9,%ymm9 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm13,%ymm13 + vpaddd %ymm7,%ymm13,%ymm13 + vmovdqu 384-256-128(%rbx),%ymm5 + vpaddd 128-128(%rax),%ymm6,%ymm6 + + vpsrld $3,%ymm5,%ymm7 + vpsrld $7,%ymm5,%ymm1 + vpslld $25,%ymm5,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm5,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm5,%ymm2 + vmovdqu 288-256-128(%rbx),%ymm0 + vpsrld $10,%ymm0,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm6,%ymm6 + vpxor %ymm1,%ymm4,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm6,%ymm6 + vpsrld $6,%ymm9,%ymm7 + vpslld $26,%ymm9,%ymm2 + vmovdqu %ymm6,352-256-128(%rbx) + vpaddd %ymm12,%ymm6,%ymm6 + + vpsrld $11,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm9,%ymm2 + vpaddd -32(%rbp),%ymm6,%ymm6 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm9,%ymm2 + vpandn %ymm11,%ymm9,%ymm0 + vpand %ymm10,%ymm9,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm13,%ymm12 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm13,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm13,%ymm14,%ymm4 + + vpxor %ymm1,%ymm12,%ymm12 + vpaddd %ymm7,%ymm6,%ymm6 + + vpsrld $13,%ymm13,%ymm1 + + vpslld $19,%ymm13,%ymm2 + vpaddd %ymm0,%ymm6,%ymm6 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm12,%ymm7 + + vpsrld $22,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm13,%ymm2 + vpxor %ymm3,%ymm14,%ymm12 + vpaddd %ymm6,%ymm8,%ymm8 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm6,%ymm12,%ymm12 + vpaddd %ymm7,%ymm12,%ymm12 + vmovdqu 416-256-128(%rbx),%ymm6 + vpaddd 160-128(%rax),%ymm5,%ymm5 + + vpsrld $3,%ymm6,%ymm7 + vpsrld $7,%ymm6,%ymm1 + vpslld $25,%ymm6,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm6,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm6,%ymm2 + vmovdqu 320-256-128(%rbx),%ymm0 + vpsrld $10,%ymm0,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm5,%ymm5 + vpxor %ymm1,%ymm3,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm5,%ymm5 + vpsrld $6,%ymm8,%ymm7 + vpslld $26,%ymm8,%ymm2 + vmovdqu %ymm5,384-256-128(%rbx) + vpaddd %ymm11,%ymm5,%ymm5 + + vpsrld $11,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm8,%ymm2 + vpaddd 0(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm8,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm8,%ymm2 + vpandn %ymm10,%ymm8,%ymm0 + vpand %ymm9,%ymm8,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm12,%ymm11 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm12,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm12,%ymm13,%ymm3 + + vpxor %ymm1,%ymm11,%ymm11 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm12,%ymm1 + + vpslld $19,%ymm12,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm11,%ymm7 + + vpsrld $22,%ymm12,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm12,%ymm2 + vpxor %ymm4,%ymm13,%ymm11 + vpaddd %ymm5,%ymm15,%ymm15 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm11,%ymm11 + vpaddd %ymm7,%ymm11,%ymm11 + vmovdqu 448-256-128(%rbx),%ymm5 + vpaddd 192-128(%rax),%ymm6,%ymm6 + + vpsrld $3,%ymm5,%ymm7 + vpsrld $7,%ymm5,%ymm1 + vpslld $25,%ymm5,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm5,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm5,%ymm2 + vmovdqu 352-256-128(%rbx),%ymm0 + vpsrld $10,%ymm0,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm6,%ymm6 + vpxor %ymm1,%ymm4,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm6,%ymm6 + vpsrld $6,%ymm15,%ymm7 + vpslld $26,%ymm15,%ymm2 + vmovdqu %ymm6,416-256-128(%rbx) + vpaddd %ymm10,%ymm6,%ymm6 + + vpsrld $11,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm15,%ymm2 + vpaddd 32(%rbp),%ymm6,%ymm6 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm15,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm15,%ymm2 + vpandn %ymm9,%ymm15,%ymm0 + vpand %ymm8,%ymm15,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm11,%ymm10 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm11,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm11,%ymm12,%ymm4 + + vpxor %ymm1,%ymm10,%ymm10 + vpaddd %ymm7,%ymm6,%ymm6 + + vpsrld $13,%ymm11,%ymm1 + + vpslld $19,%ymm11,%ymm2 + vpaddd %ymm0,%ymm6,%ymm6 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm10,%ymm7 + + vpsrld $22,%ymm11,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm11,%ymm2 + vpxor %ymm3,%ymm12,%ymm10 + vpaddd %ymm6,%ymm14,%ymm14 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm6,%ymm10,%ymm10 + vpaddd %ymm7,%ymm10,%ymm10 + vmovdqu 480-256-128(%rbx),%ymm6 + vpaddd 224-128(%rax),%ymm5,%ymm5 + + vpsrld $3,%ymm6,%ymm7 + vpsrld $7,%ymm6,%ymm1 + vpslld $25,%ymm6,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm6,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm6,%ymm2 + vmovdqu 384-256-128(%rbx),%ymm0 + vpsrld $10,%ymm0,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm5,%ymm5 + vpxor %ymm1,%ymm3,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm5,%ymm5 + vpsrld $6,%ymm14,%ymm7 + vpslld $26,%ymm14,%ymm2 + vmovdqu %ymm5,448-256-128(%rbx) + vpaddd %ymm9,%ymm5,%ymm5 + + vpsrld $11,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm14,%ymm2 + vpaddd 64(%rbp),%ymm5,%ymm5 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm14,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm14,%ymm2 + vpandn %ymm8,%ymm14,%ymm0 + vpand %ymm15,%ymm14,%ymm3 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm10,%ymm9 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm10,%ymm1 + vpxor %ymm3,%ymm0,%ymm0 + vpxor %ymm10,%ymm11,%ymm3 + + vpxor %ymm1,%ymm9,%ymm9 + vpaddd %ymm7,%ymm5,%ymm5 + + vpsrld $13,%ymm10,%ymm1 + + vpslld $19,%ymm10,%ymm2 + vpaddd %ymm0,%ymm5,%ymm5 + vpand %ymm3,%ymm4,%ymm4 + + vpxor %ymm1,%ymm9,%ymm7 + + vpsrld $22,%ymm10,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm10,%ymm2 + vpxor %ymm4,%ymm11,%ymm9 + vpaddd %ymm5,%ymm13,%ymm13 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm5,%ymm9,%ymm9 + vpaddd %ymm7,%ymm9,%ymm9 + vmovdqu 0-128(%rax),%ymm5 + vpaddd 256-256-128(%rbx),%ymm6,%ymm6 + + vpsrld $3,%ymm5,%ymm7 + vpsrld $7,%ymm5,%ymm1 + vpslld $25,%ymm5,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $18,%ymm5,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $14,%ymm5,%ymm2 + vmovdqu 416-256-128(%rbx),%ymm0 + vpsrld $10,%ymm0,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + vpsrld $17,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $15,%ymm0,%ymm2 + vpaddd %ymm7,%ymm6,%ymm6 + vpxor %ymm1,%ymm4,%ymm7 + vpsrld $19,%ymm0,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $13,%ymm0,%ymm2 + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + vpaddd %ymm7,%ymm6,%ymm6 + vpsrld $6,%ymm13,%ymm7 + vpslld $26,%ymm13,%ymm2 + vmovdqu %ymm6,480-256-128(%rbx) + vpaddd %ymm8,%ymm6,%ymm6 + + vpsrld $11,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + vpslld $21,%ymm13,%ymm2 + vpaddd 96(%rbp),%ymm6,%ymm6 + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $25,%ymm13,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $7,%ymm13,%ymm2 + vpandn %ymm15,%ymm13,%ymm0 + vpand %ymm14,%ymm13,%ymm4 + + vpxor %ymm1,%ymm7,%ymm7 + + vpsrld $2,%ymm9,%ymm8 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $30,%ymm9,%ymm1 + vpxor %ymm4,%ymm0,%ymm0 + vpxor %ymm9,%ymm10,%ymm4 + + vpxor %ymm1,%ymm8,%ymm8 + vpaddd %ymm7,%ymm6,%ymm6 + + vpsrld $13,%ymm9,%ymm1 + + vpslld $19,%ymm9,%ymm2 + vpaddd %ymm0,%ymm6,%ymm6 + vpand %ymm4,%ymm3,%ymm3 + + vpxor %ymm1,%ymm8,%ymm7 + + vpsrld $22,%ymm9,%ymm1 + vpxor %ymm2,%ymm7,%ymm7 + + vpslld $10,%ymm9,%ymm2 + vpxor %ymm3,%ymm10,%ymm8 + vpaddd %ymm6,%ymm12,%ymm12 + + vpxor %ymm1,%ymm7,%ymm7 + vpxor %ymm2,%ymm7,%ymm7 + + vpaddd %ymm6,%ymm8,%ymm8 + vpaddd %ymm7,%ymm8,%ymm8 + addq $256,%rbp + decl %ecx + jnz .Loop_16_xx_avx2 + + movl $1,%ecx + leaq 512(%rsp),%rbx + leaq K256+128(%rip),%rbp + cmpl 0(%rbx),%ecx + cmovgeq %rbp,%r12 + cmpl 4(%rbx),%ecx + cmovgeq %rbp,%r13 + cmpl 8(%rbx),%ecx + cmovgeq %rbp,%r14 + cmpl 12(%rbx),%ecx + cmovgeq %rbp,%r15 + cmpl 16(%rbx),%ecx + cmovgeq %rbp,%r8 + cmpl 20(%rbx),%ecx + cmovgeq %rbp,%r9 + cmpl 24(%rbx),%ecx + cmovgeq %rbp,%r10 + cmpl 28(%rbx),%ecx + cmovgeq %rbp,%r11 + vmovdqa (%rbx),%ymm7 + vpxor %ymm0,%ymm0,%ymm0 + vmovdqa %ymm7,%ymm6 + vpcmpgtd %ymm0,%ymm6,%ymm6 + vpaddd %ymm6,%ymm7,%ymm7 + + vmovdqu 0-128(%rdi),%ymm0 + vpand %ymm6,%ymm8,%ymm8 + vmovdqu 32-128(%rdi),%ymm1 + vpand %ymm6,%ymm9,%ymm9 + vmovdqu 64-128(%rdi),%ymm2 + vpand %ymm6,%ymm10,%ymm10 + vmovdqu 96-128(%rdi),%ymm5 + vpand %ymm6,%ymm11,%ymm11 + vpaddd %ymm0,%ymm8,%ymm8 + vmovdqu 128-128(%rdi),%ymm0 + vpand %ymm6,%ymm12,%ymm12 + vpaddd %ymm1,%ymm9,%ymm9 + vmovdqu 160-128(%rdi),%ymm1 + vpand %ymm6,%ymm13,%ymm13 + vpaddd %ymm2,%ymm10,%ymm10 + vmovdqu 192-128(%rdi),%ymm2 + vpand %ymm6,%ymm14,%ymm14 + vpaddd %ymm5,%ymm11,%ymm11 + vmovdqu 224-128(%rdi),%ymm5 + vpand %ymm6,%ymm15,%ymm15 + vpaddd %ymm0,%ymm12,%ymm12 + vpaddd %ymm1,%ymm13,%ymm13 + vmovdqu %ymm8,0-128(%rdi) + vpaddd %ymm2,%ymm14,%ymm14 + vmovdqu %ymm9,32-128(%rdi) + vpaddd %ymm5,%ymm15,%ymm15 + vmovdqu %ymm10,64-128(%rdi) + vmovdqu %ymm11,96-128(%rdi) + vmovdqu %ymm12,128-128(%rdi) + vmovdqu %ymm13,160-128(%rdi) + vmovdqu %ymm14,192-128(%rdi) + vmovdqu %ymm15,224-128(%rdi) + + vmovdqu %ymm7,(%rbx) + leaq 256+128(%rsp),%rbx + vmovdqu .Lpbswap(%rip),%ymm6 + decl %edx + jnz .Loop_avx2 + + + + + + + +.Ldone_avx2: + movq 544(%rsp),%rax +.cfi_def_cfa %rax,8 + vzeroupper + movq -48(%rax),%r15 +.cfi_restore %r15 + movq -40(%rax),%r14 +.cfi_restore %r14 + movq -32(%rax),%r13 +.cfi_restore %r13 + movq -24(%rax),%r12 +.cfi_restore %r12 + movq -16(%rax),%rbp +.cfi_restore %rbp + movq -8(%rax),%rbx +.cfi_restore %rbx + leaq (%rax),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx2: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_multi_block_avx2,.-sha256_multi_block_avx2 +.align 256 +K256: +.long 1116352408,1116352408,1116352408,1116352408 +.long 1116352408,1116352408,1116352408,1116352408 +.long 1899447441,1899447441,1899447441,1899447441 +.long 1899447441,1899447441,1899447441,1899447441 +.long 3049323471,3049323471,3049323471,3049323471 +.long 3049323471,3049323471,3049323471,3049323471 +.long 3921009573,3921009573,3921009573,3921009573 +.long 3921009573,3921009573,3921009573,3921009573 +.long 961987163,961987163,961987163,961987163 +.long 961987163,961987163,961987163,961987163 +.long 1508970993,1508970993,1508970993,1508970993 +.long 1508970993,1508970993,1508970993,1508970993 +.long 2453635748,2453635748,2453635748,2453635748 +.long 2453635748,2453635748,2453635748,2453635748 +.long 2870763221,2870763221,2870763221,2870763221 +.long 2870763221,2870763221,2870763221,2870763221 +.long 3624381080,3624381080,3624381080,3624381080 +.long 3624381080,3624381080,3624381080,3624381080 +.long 310598401,310598401,310598401,310598401 +.long 310598401,310598401,310598401,310598401 +.long 607225278,607225278,607225278,607225278 +.long 607225278,607225278,607225278,607225278 +.long 1426881987,1426881987,1426881987,1426881987 +.long 1426881987,1426881987,1426881987,1426881987 +.long 1925078388,1925078388,1925078388,1925078388 +.long 1925078388,1925078388,1925078388,1925078388 +.long 2162078206,2162078206,2162078206,2162078206 +.long 2162078206,2162078206,2162078206,2162078206 +.long 2614888103,2614888103,2614888103,2614888103 +.long 2614888103,2614888103,2614888103,2614888103 +.long 3248222580,3248222580,3248222580,3248222580 +.long 3248222580,3248222580,3248222580,3248222580 +.long 3835390401,3835390401,3835390401,3835390401 +.long 3835390401,3835390401,3835390401,3835390401 +.long 4022224774,4022224774,4022224774,4022224774 +.long 4022224774,4022224774,4022224774,4022224774 +.long 264347078,264347078,264347078,264347078 +.long 264347078,264347078,264347078,264347078 +.long 604807628,604807628,604807628,604807628 +.long 604807628,604807628,604807628,604807628 +.long 770255983,770255983,770255983,770255983 +.long 770255983,770255983,770255983,770255983 +.long 1249150122,1249150122,1249150122,1249150122 +.long 1249150122,1249150122,1249150122,1249150122 +.long 1555081692,1555081692,1555081692,1555081692 +.long 1555081692,1555081692,1555081692,1555081692 +.long 1996064986,1996064986,1996064986,1996064986 +.long 1996064986,1996064986,1996064986,1996064986 +.long 2554220882,2554220882,2554220882,2554220882 +.long 2554220882,2554220882,2554220882,2554220882 +.long 2821834349,2821834349,2821834349,2821834349 +.long 2821834349,2821834349,2821834349,2821834349 +.long 2952996808,2952996808,2952996808,2952996808 +.long 2952996808,2952996808,2952996808,2952996808 +.long 3210313671,3210313671,3210313671,3210313671 +.long 3210313671,3210313671,3210313671,3210313671 +.long 3336571891,3336571891,3336571891,3336571891 +.long 3336571891,3336571891,3336571891,3336571891 +.long 3584528711,3584528711,3584528711,3584528711 +.long 3584528711,3584528711,3584528711,3584528711 +.long 113926993,113926993,113926993,113926993 +.long 113926993,113926993,113926993,113926993 +.long 338241895,338241895,338241895,338241895 +.long 338241895,338241895,338241895,338241895 +.long 666307205,666307205,666307205,666307205 +.long 666307205,666307205,666307205,666307205 +.long 773529912,773529912,773529912,773529912 +.long 773529912,773529912,773529912,773529912 +.long 1294757372,1294757372,1294757372,1294757372 +.long 1294757372,1294757372,1294757372,1294757372 +.long 1396182291,1396182291,1396182291,1396182291 +.long 1396182291,1396182291,1396182291,1396182291 +.long 1695183700,1695183700,1695183700,1695183700 +.long 1695183700,1695183700,1695183700,1695183700 +.long 1986661051,1986661051,1986661051,1986661051 +.long 1986661051,1986661051,1986661051,1986661051 +.long 2177026350,2177026350,2177026350,2177026350 +.long 2177026350,2177026350,2177026350,2177026350 +.long 2456956037,2456956037,2456956037,2456956037 +.long 2456956037,2456956037,2456956037,2456956037 +.long 2730485921,2730485921,2730485921,2730485921 +.long 2730485921,2730485921,2730485921,2730485921 +.long 2820302411,2820302411,2820302411,2820302411 +.long 2820302411,2820302411,2820302411,2820302411 +.long 3259730800,3259730800,3259730800,3259730800 +.long 3259730800,3259730800,3259730800,3259730800 +.long 3345764771,3345764771,3345764771,3345764771 +.long 3345764771,3345764771,3345764771,3345764771 +.long 3516065817,3516065817,3516065817,3516065817 +.long 3516065817,3516065817,3516065817,3516065817 +.long 3600352804,3600352804,3600352804,3600352804 +.long 3600352804,3600352804,3600352804,3600352804 +.long 4094571909,4094571909,4094571909,4094571909 +.long 4094571909,4094571909,4094571909,4094571909 +.long 275423344,275423344,275423344,275423344 +.long 275423344,275423344,275423344,275423344 +.long 430227734,430227734,430227734,430227734 +.long 430227734,430227734,430227734,430227734 +.long 506948616,506948616,506948616,506948616 +.long 506948616,506948616,506948616,506948616 +.long 659060556,659060556,659060556,659060556 +.long 659060556,659060556,659060556,659060556 +.long 883997877,883997877,883997877,883997877 +.long 883997877,883997877,883997877,883997877 +.long 958139571,958139571,958139571,958139571 +.long 958139571,958139571,958139571,958139571 +.long 1322822218,1322822218,1322822218,1322822218 +.long 1322822218,1322822218,1322822218,1322822218 +.long 1537002063,1537002063,1537002063,1537002063 +.long 1537002063,1537002063,1537002063,1537002063 +.long 1747873779,1747873779,1747873779,1747873779 +.long 1747873779,1747873779,1747873779,1747873779 +.long 1955562222,1955562222,1955562222,1955562222 +.long 1955562222,1955562222,1955562222,1955562222 +.long 2024104815,2024104815,2024104815,2024104815 +.long 2024104815,2024104815,2024104815,2024104815 +.long 2227730452,2227730452,2227730452,2227730452 +.long 2227730452,2227730452,2227730452,2227730452 +.long 2361852424,2361852424,2361852424,2361852424 +.long 2361852424,2361852424,2361852424,2361852424 +.long 2428436474,2428436474,2428436474,2428436474 +.long 2428436474,2428436474,2428436474,2428436474 +.long 2756734187,2756734187,2756734187,2756734187 +.long 2756734187,2756734187,2756734187,2756734187 +.long 3204031479,3204031479,3204031479,3204031479 +.long 3204031479,3204031479,3204031479,3204031479 +.long 3329325298,3329325298,3329325298,3329325298 +.long 3329325298,3329325298,3329325298,3329325298 +.Lpbswap: +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +K256_shaext: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.byte 83,72,65,50,53,54,32,109,117,108,116,105,45,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/sha/sha256-x86_64.S b/crypto/openssl/crypto/sha/sha256-x86_64.S new file mode 100644 index 000000000000..e82bbec164f8 --- /dev/null +++ b/crypto/openssl/crypto/sha/sha256-x86_64.S @@ -0,0 +1,5477 @@ +.text + + +.globl sha256_block_data_order +.type sha256_block_data_order,@function +.align 16 +sha256_block_data_order: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%r11 + movl 0(%r11),%r9d + movl 4(%r11),%r10d + movl 8(%r11),%r11d + testl $536870912,%r11d + jnz _shaext_shortcut + andl $296,%r11d + cmpl $296,%r11d + je .Lavx2_shortcut + andl $1073741824,%r9d + andl $268435968,%r10d + orl %r9d,%r10d + cmpl $1342177792,%r10d + je .Lavx_shortcut + testl $512,%r10d + jnz .Lssse3_shortcut + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + shlq $4,%rdx + subq $64+32,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %rax,88(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xd8,0x00,0x06,0x23,0x08 +.Lprologue: + + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + jmp .Lloop + +.align 16 +.Lloop: + movl %ebx,%edi + leaq K256(%rip),%rbp + xorl %ecx,%edi + movl 0(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,0(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + addl %r14d,%r11d + movl 4(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,4(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + addl %r14d,%r10d + movl 8(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,8(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + addl %r14d,%r9d + movl 12(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,12(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + addl %r14d,%r8d + movl 16(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,16(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + addl %r14d,%edx + movl 20(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,20(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + addl %r14d,%ecx + movl 24(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,24(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + addl %r14d,%ebx + movl 28(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,28(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + addl %r14d,%eax + movl 32(%rsi),%r12d + movl %r8d,%r13d + movl %eax,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,32(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + addl %r14d,%r11d + movl 36(%rsi),%r12d + movl %edx,%r13d + movl %r11d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,36(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + addl %r14d,%r10d + movl 40(%rsi),%r12d + movl %ecx,%r13d + movl %r10d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,40(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + addl %r14d,%r9d + movl 44(%rsi),%r12d + movl %ebx,%r13d + movl %r9d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,44(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + addl %r14d,%r8d + movl 48(%rsi),%r12d + movl %eax,%r13d + movl %r8d,%r14d + bswapl %r12d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,48(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + addl %r14d,%edx + movl 52(%rsi),%r12d + movl %r11d,%r13d + movl %edx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,52(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + addl %r14d,%ecx + movl 56(%rsi),%r12d + movl %r10d,%r13d + movl %ecx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,56(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + addl %r14d,%ebx + movl 60(%rsi),%r12d + movl %r9d,%r13d + movl %ebx,%r14d + bswapl %r12d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,60(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + jmp .Lrounds_16_xx +.align 16 +.Lrounds_16_xx: + movl 4(%rsp),%r13d + movl 56(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%eax + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 36(%rsp),%r12d + + addl 0(%rsp),%r12d + movl %r8d,%r13d + addl %r15d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,0(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + movl 8(%rsp),%r13d + movl 60(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r11d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 40(%rsp),%r12d + + addl 4(%rsp),%r12d + movl %edx,%r13d + addl %edi,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,4(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + movl 12(%rsp),%r13d + movl 0(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r10d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 44(%rsp),%r12d + + addl 8(%rsp),%r12d + movl %ecx,%r13d + addl %r15d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,8(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + movl 16(%rsp),%r13d + movl 4(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r9d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 48(%rsp),%r12d + + addl 12(%rsp),%r12d + movl %ebx,%r13d + addl %edi,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,12(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + movl 20(%rsp),%r13d + movl 8(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r8d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 52(%rsp),%r12d + + addl 16(%rsp),%r12d + movl %eax,%r13d + addl %r15d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,16(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + movl 24(%rsp),%r13d + movl 12(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%edx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 56(%rsp),%r12d + + addl 20(%rsp),%r12d + movl %r11d,%r13d + addl %edi,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,20(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + movl 28(%rsp),%r13d + movl 16(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ecx + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 60(%rsp),%r12d + + addl 24(%rsp),%r12d + movl %r10d,%r13d + addl %r15d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,24(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + movl 32(%rsp),%r13d + movl 20(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ebx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 0(%rsp),%r12d + + addl 28(%rsp),%r12d + movl %r9d,%r13d + addl %edi,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,28(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + movl 36(%rsp),%r13d + movl 24(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%eax + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 4(%rsp),%r12d + + addl 32(%rsp),%r12d + movl %r8d,%r13d + addl %r15d,%r12d + movl %eax,%r14d + rorl $14,%r13d + movl %r9d,%r15d + + xorl %r8d,%r13d + rorl $9,%r14d + xorl %r10d,%r15d + + movl %r12d,32(%rsp) + xorl %eax,%r14d + andl %r8d,%r15d + + rorl $5,%r13d + addl %r11d,%r12d + xorl %r10d,%r15d + + rorl $11,%r14d + xorl %r8d,%r13d + addl %r15d,%r12d + + movl %eax,%r15d + addl (%rbp),%r12d + xorl %eax,%r14d + + xorl %ebx,%r15d + rorl $6,%r13d + movl %ebx,%r11d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r11d + addl %r12d,%edx + addl %r12d,%r11d + + leaq 4(%rbp),%rbp + movl 40(%rsp),%r13d + movl 28(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r11d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 8(%rsp),%r12d + + addl 36(%rsp),%r12d + movl %edx,%r13d + addl %edi,%r12d + movl %r11d,%r14d + rorl $14,%r13d + movl %r8d,%edi + + xorl %edx,%r13d + rorl $9,%r14d + xorl %r9d,%edi + + movl %r12d,36(%rsp) + xorl %r11d,%r14d + andl %edx,%edi + + rorl $5,%r13d + addl %r10d,%r12d + xorl %r9d,%edi + + rorl $11,%r14d + xorl %edx,%r13d + addl %edi,%r12d + + movl %r11d,%edi + addl (%rbp),%r12d + xorl %r11d,%r14d + + xorl %eax,%edi + rorl $6,%r13d + movl %eax,%r10d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r10d + addl %r12d,%ecx + addl %r12d,%r10d + + leaq 4(%rbp),%rbp + movl 44(%rsp),%r13d + movl 32(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r10d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 12(%rsp),%r12d + + addl 40(%rsp),%r12d + movl %ecx,%r13d + addl %r15d,%r12d + movl %r10d,%r14d + rorl $14,%r13d + movl %edx,%r15d + + xorl %ecx,%r13d + rorl $9,%r14d + xorl %r8d,%r15d + + movl %r12d,40(%rsp) + xorl %r10d,%r14d + andl %ecx,%r15d + + rorl $5,%r13d + addl %r9d,%r12d + xorl %r8d,%r15d + + rorl $11,%r14d + xorl %ecx,%r13d + addl %r15d,%r12d + + movl %r10d,%r15d + addl (%rbp),%r12d + xorl %r10d,%r14d + + xorl %r11d,%r15d + rorl $6,%r13d + movl %r11d,%r9d + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%r9d + addl %r12d,%ebx + addl %r12d,%r9d + + leaq 4(%rbp),%rbp + movl 48(%rsp),%r13d + movl 36(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r9d + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 16(%rsp),%r12d + + addl 44(%rsp),%r12d + movl %ebx,%r13d + addl %edi,%r12d + movl %r9d,%r14d + rorl $14,%r13d + movl %ecx,%edi + + xorl %ebx,%r13d + rorl $9,%r14d + xorl %edx,%edi + + movl %r12d,44(%rsp) + xorl %r9d,%r14d + andl %ebx,%edi + + rorl $5,%r13d + addl %r8d,%r12d + xorl %edx,%edi + + rorl $11,%r14d + xorl %ebx,%r13d + addl %edi,%r12d + + movl %r9d,%edi + addl (%rbp),%r12d + xorl %r9d,%r14d + + xorl %r10d,%edi + rorl $6,%r13d + movl %r10d,%r8d + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%r8d + addl %r12d,%eax + addl %r12d,%r8d + + leaq 20(%rbp),%rbp + movl 52(%rsp),%r13d + movl 40(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%r8d + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 20(%rsp),%r12d + + addl 48(%rsp),%r12d + movl %eax,%r13d + addl %r15d,%r12d + movl %r8d,%r14d + rorl $14,%r13d + movl %ebx,%r15d + + xorl %eax,%r13d + rorl $9,%r14d + xorl %ecx,%r15d + + movl %r12d,48(%rsp) + xorl %r8d,%r14d + andl %eax,%r15d + + rorl $5,%r13d + addl %edx,%r12d + xorl %ecx,%r15d + + rorl $11,%r14d + xorl %eax,%r13d + addl %r15d,%r12d + + movl %r8d,%r15d + addl (%rbp),%r12d + xorl %r8d,%r14d + + xorl %r9d,%r15d + rorl $6,%r13d + movl %r9d,%edx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%edx + addl %r12d,%r11d + addl %r12d,%edx + + leaq 4(%rbp),%rbp + movl 56(%rsp),%r13d + movl 44(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%edx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 24(%rsp),%r12d + + addl 52(%rsp),%r12d + movl %r11d,%r13d + addl %edi,%r12d + movl %edx,%r14d + rorl $14,%r13d + movl %eax,%edi + + xorl %r11d,%r13d + rorl $9,%r14d + xorl %ebx,%edi + + movl %r12d,52(%rsp) + xorl %edx,%r14d + andl %r11d,%edi + + rorl $5,%r13d + addl %ecx,%r12d + xorl %ebx,%edi + + rorl $11,%r14d + xorl %r11d,%r13d + addl %edi,%r12d + + movl %edx,%edi + addl (%rbp),%r12d + xorl %edx,%r14d + + xorl %r8d,%edi + rorl $6,%r13d + movl %r8d,%ecx + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%ecx + addl %r12d,%r10d + addl %r12d,%ecx + + leaq 4(%rbp),%rbp + movl 60(%rsp),%r13d + movl 48(%rsp),%r15d + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ecx + movl %r15d,%r14d + rorl $2,%r15d + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%r15d + shrl $10,%r14d + + rorl $17,%r15d + xorl %r13d,%r12d + xorl %r14d,%r15d + addl 28(%rsp),%r12d + + addl 56(%rsp),%r12d + movl %r10d,%r13d + addl %r15d,%r12d + movl %ecx,%r14d + rorl $14,%r13d + movl %r11d,%r15d + + xorl %r10d,%r13d + rorl $9,%r14d + xorl %eax,%r15d + + movl %r12d,56(%rsp) + xorl %ecx,%r14d + andl %r10d,%r15d + + rorl $5,%r13d + addl %ebx,%r12d + xorl %eax,%r15d + + rorl $11,%r14d + xorl %r10d,%r13d + addl %r15d,%r12d + + movl %ecx,%r15d + addl (%rbp),%r12d + xorl %ecx,%r14d + + xorl %edx,%r15d + rorl $6,%r13d + movl %edx,%ebx + + andl %r15d,%edi + rorl $2,%r14d + addl %r13d,%r12d + + xorl %edi,%ebx + addl %r12d,%r9d + addl %r12d,%ebx + + leaq 4(%rbp),%rbp + movl 0(%rsp),%r13d + movl 52(%rsp),%edi + + movl %r13d,%r12d + rorl $11,%r13d + addl %r14d,%ebx + movl %edi,%r14d + rorl $2,%edi + + xorl %r12d,%r13d + shrl $3,%r12d + rorl $7,%r13d + xorl %r14d,%edi + shrl $10,%r14d + + rorl $17,%edi + xorl %r13d,%r12d + xorl %r14d,%edi + addl 32(%rsp),%r12d + + addl 60(%rsp),%r12d + movl %r9d,%r13d + addl %edi,%r12d + movl %ebx,%r14d + rorl $14,%r13d + movl %r10d,%edi + + xorl %r9d,%r13d + rorl $9,%r14d + xorl %r11d,%edi + + movl %r12d,60(%rsp) + xorl %ebx,%r14d + andl %r9d,%edi + + rorl $5,%r13d + addl %eax,%r12d + xorl %r11d,%edi + + rorl $11,%r14d + xorl %r9d,%r13d + addl %edi,%r12d + + movl %ebx,%edi + addl (%rbp),%r12d + xorl %ebx,%r14d + + xorl %ecx,%edi + rorl $6,%r13d + movl %ecx,%eax + + andl %edi,%r15d + rorl $2,%r14d + addl %r13d,%r12d + + xorl %r15d,%eax + addl %r12d,%r8d + addl %r12d,%eax + + leaq 20(%rbp),%rbp + cmpb $0,3(%rbp) + jnz .Lrounds_16_xx + + movq 64+0(%rsp),%rdi + addl %r14d,%eax + leaq 64(%rsi),%rsi + + addl 0(%rdi),%eax + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb .Lloop + + movq 88(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_block_data_order,.-sha256_block_data_order +.align 64 +.type K256,@object +K256: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 + +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f +.long 0x03020100,0x0b0a0908,0xffffffff,0xffffffff +.long 0x03020100,0x0b0a0908,0xffffffff,0xffffffff +.long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 +.long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 +.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.type sha256_block_data_order_shaext,@function +.align 64 +sha256_block_data_order_shaext: +_shaext_shortcut: +.cfi_startproc + leaq K256+128(%rip),%rcx + movdqu (%rdi),%xmm1 + movdqu 16(%rdi),%xmm2 + movdqa 512-128(%rcx),%xmm7 + + pshufd $0x1b,%xmm1,%xmm0 + pshufd $0xb1,%xmm1,%xmm1 + pshufd $0x1b,%xmm2,%xmm2 + movdqa %xmm7,%xmm8 +.byte 102,15,58,15,202,8 + punpcklqdq %xmm0,%xmm2 + jmp .Loop_shaext + +.align 16 +.Loop_shaext: + movdqu (%rsi),%xmm3 + movdqu 16(%rsi),%xmm4 + movdqu 32(%rsi),%xmm5 +.byte 102,15,56,0,223 + movdqu 48(%rsi),%xmm6 + + movdqa 0-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 102,15,56,0,231 + movdqa %xmm2,%xmm10 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + nop + movdqa %xmm1,%xmm9 +.byte 15,56,203,202 + + movdqa 32-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 102,15,56,0,239 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + leaq 64(%rsi),%rsi +.byte 15,56,204,220 +.byte 15,56,203,202 + + movdqa 64-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 102,15,56,0,247 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + + movdqa 96-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 128-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 160-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa 192-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa 224-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 256-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 288-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa 320-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa 352-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 384-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 416-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 +.byte 15,56,203,202 + paddd %xmm7,%xmm6 + + movdqa 448-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 +.byte 15,56,205,245 + movdqa %xmm8,%xmm7 +.byte 15,56,203,202 + + movdqa 480-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 + nop +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + decq %rdx + nop +.byte 15,56,203,202 + + paddd %xmm10,%xmm2 + paddd %xmm9,%xmm1 + jnz .Loop_shaext + + pshufd $0xb1,%xmm2,%xmm2 + pshufd $0x1b,%xmm1,%xmm7 + pshufd $0xb1,%xmm1,%xmm1 + punpckhqdq %xmm2,%xmm1 +.byte 102,15,58,15,215,8 + + movdqu %xmm1,(%rdi) + movdqu %xmm2,16(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_block_data_order_shaext,.-sha256_block_data_order_shaext +.type sha256_block_data_order_ssse3,@function +.align 64 +sha256_block_data_order_ssse3: +.cfi_startproc +.Lssse3_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + shlq $4,%rdx + subq $96,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %rax,88(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xd8,0x00,0x06,0x23,0x08 +.Lprologue_ssse3: + + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + + + jmp .Lloop_ssse3 +.align 16 +.Lloop_ssse3: + movdqa K256+512(%rip),%xmm7 + movdqu 0(%rsi),%xmm0 + movdqu 16(%rsi),%xmm1 + movdqu 32(%rsi),%xmm2 +.byte 102,15,56,0,199 + movdqu 48(%rsi),%xmm3 + leaq K256(%rip),%rbp +.byte 102,15,56,0,207 + movdqa 0(%rbp),%xmm4 + movdqa 32(%rbp),%xmm5 +.byte 102,15,56,0,215 + paddd %xmm0,%xmm4 + movdqa 64(%rbp),%xmm6 +.byte 102,15,56,0,223 + movdqa 96(%rbp),%xmm7 + paddd %xmm1,%xmm5 + paddd %xmm2,%xmm6 + paddd %xmm3,%xmm7 + movdqa %xmm4,0(%rsp) + movl %eax,%r14d + movdqa %xmm5,16(%rsp) + movl %ebx,%edi + movdqa %xmm6,32(%rsp) + xorl %ecx,%edi + movdqa %xmm7,48(%rsp) + movl %r8d,%r13d + jmp .Lssse3_00_47 + +.align 16 +.Lssse3_00_47: + subq $-128,%rbp + rorl $14,%r13d + movdqa %xmm1,%xmm4 + movl %r14d,%eax + movl %r9d,%r12d + movdqa %xmm3,%xmm7 + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d +.byte 102,15,58,15,224,4 + andl %r8d,%r12d + xorl %r8d,%r13d +.byte 102,15,58,15,250,4 + addl 0(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %ebx,%r15d + addl %r12d,%r11d + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + paddd %xmm7,%xmm0 + rorl $2,%r14d + addl %r11d,%edx + psrld $7,%xmm6 + addl %edi,%r11d + movl %edx,%r13d + pshufd $250,%xmm3,%xmm7 + addl %r11d,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%r11d + movl %r8d,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %r11d,%r14d + pxor %xmm5,%xmm4 + andl %edx,%r12d + xorl %edx,%r13d + pslld $11,%xmm5 + addl 4(%rsp),%r10d + movl %r11d,%edi + pxor %xmm6,%xmm4 + xorl %r9d,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %eax,%edi + addl %r12d,%r10d + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + psrld $10,%xmm7 + addl %r13d,%r10d + xorl %eax,%r15d + paddd %xmm4,%xmm0 + rorl $2,%r14d + addl %r10d,%ecx + psrlq $17,%xmm6 + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %ecx,%r13d + xorl %r8d,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + psrldq $8,%xmm7 + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + paddd %xmm7,%xmm0 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + pshufd $80,%xmm0,%xmm7 + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + movdqa %xmm7,%xmm6 + addl %edi,%r9d + movl %ebx,%r13d + psrld $10,%xmm7 + addl %r9d,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%r9d + movl %ecx,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + psrlq $2,%xmm6 + andl %ebx,%r12d + xorl %ebx,%r13d + addl 12(%rsp),%r8d + pxor %xmm6,%xmm7 + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %r10d,%edi + addl %r12d,%r8d + movdqa 0(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + paddd %xmm7,%xmm0 + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + paddd %xmm0,%xmm6 + movl %eax,%r13d + addl %r8d,%r14d + movdqa %xmm6,0(%rsp) + rorl $14,%r13d + movdqa %xmm2,%xmm4 + movl %r14d,%r8d + movl %ebx,%r12d + movdqa %xmm0,%xmm7 + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d +.byte 102,15,58,15,225,4 + andl %eax,%r12d + xorl %eax,%r13d +.byte 102,15,58,15,251,4 + addl 16(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %r9d,%r15d + addl %r12d,%edx + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + paddd %xmm7,%xmm1 + rorl $2,%r14d + addl %edx,%r11d + psrld $7,%xmm6 + addl %edi,%edx + movl %r11d,%r13d + pshufd $250,%xmm0,%xmm7 + addl %edx,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%edx + movl %eax,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %edx,%r14d + pxor %xmm5,%xmm4 + andl %r11d,%r12d + xorl %r11d,%r13d + pslld $11,%xmm5 + addl 20(%rsp),%ecx + movl %edx,%edi + pxor %xmm6,%xmm4 + xorl %ebx,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %r8d,%edi + addl %r12d,%ecx + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + psrld $10,%xmm7 + addl %r13d,%ecx + xorl %r8d,%r15d + paddd %xmm4,%xmm1 + rorl $2,%r14d + addl %ecx,%r10d + psrlq $17,%xmm6 + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %r10d,%r13d + xorl %eax,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + psrldq $8,%xmm7 + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + paddd %xmm7,%xmm1 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + pshufd $80,%xmm1,%xmm7 + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + movdqa %xmm7,%xmm6 + addl %edi,%ebx + movl %r9d,%r13d + psrld $10,%xmm7 + addl %ebx,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%ebx + movl %r10d,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + psrlq $2,%xmm6 + andl %r9d,%r12d + xorl %r9d,%r13d + addl 28(%rsp),%eax + pxor %xmm6,%xmm7 + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %ecx,%edi + addl %r12d,%eax + movdqa 32(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + paddd %xmm7,%xmm1 + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + paddd %xmm1,%xmm6 + movl %r8d,%r13d + addl %eax,%r14d + movdqa %xmm6,16(%rsp) + rorl $14,%r13d + movdqa %xmm3,%xmm4 + movl %r14d,%eax + movl %r9d,%r12d + movdqa %xmm1,%xmm7 + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d +.byte 102,15,58,15,226,4 + andl %r8d,%r12d + xorl %r8d,%r13d +.byte 102,15,58,15,248,4 + addl 32(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %ebx,%r15d + addl %r12d,%r11d + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + paddd %xmm7,%xmm2 + rorl $2,%r14d + addl %r11d,%edx + psrld $7,%xmm6 + addl %edi,%r11d + movl %edx,%r13d + pshufd $250,%xmm1,%xmm7 + addl %r11d,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%r11d + movl %r8d,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %r11d,%r14d + pxor %xmm5,%xmm4 + andl %edx,%r12d + xorl %edx,%r13d + pslld $11,%xmm5 + addl 36(%rsp),%r10d + movl %r11d,%edi + pxor %xmm6,%xmm4 + xorl %r9d,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %eax,%edi + addl %r12d,%r10d + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + psrld $10,%xmm7 + addl %r13d,%r10d + xorl %eax,%r15d + paddd %xmm4,%xmm2 + rorl $2,%r14d + addl %r10d,%ecx + psrlq $17,%xmm6 + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %ecx,%r13d + xorl %r8d,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + psrldq $8,%xmm7 + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + paddd %xmm7,%xmm2 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + pshufd $80,%xmm2,%xmm7 + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + movdqa %xmm7,%xmm6 + addl %edi,%r9d + movl %ebx,%r13d + psrld $10,%xmm7 + addl %r9d,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%r9d + movl %ecx,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + psrlq $2,%xmm6 + andl %ebx,%r12d + xorl %ebx,%r13d + addl 44(%rsp),%r8d + pxor %xmm6,%xmm7 + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %r10d,%edi + addl %r12d,%r8d + movdqa 64(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + paddd %xmm7,%xmm2 + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + paddd %xmm2,%xmm6 + movl %eax,%r13d + addl %r8d,%r14d + movdqa %xmm6,32(%rsp) + rorl $14,%r13d + movdqa %xmm0,%xmm4 + movl %r14d,%r8d + movl %ebx,%r12d + movdqa %xmm2,%xmm7 + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d +.byte 102,15,58,15,227,4 + andl %eax,%r12d + xorl %eax,%r13d +.byte 102,15,58,15,249,4 + addl 48(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + movdqa %xmm4,%xmm5 + xorl %r9d,%r15d + addl %r12d,%edx + movdqa %xmm4,%xmm6 + rorl $6,%r13d + andl %r15d,%edi + psrld $3,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + paddd %xmm7,%xmm3 + rorl $2,%r14d + addl %edx,%r11d + psrld $7,%xmm6 + addl %edi,%edx + movl %r11d,%r13d + pshufd $250,%xmm2,%xmm7 + addl %edx,%r14d + rorl $14,%r13d + pslld $14,%xmm5 + movl %r14d,%edx + movl %eax,%r12d + pxor %xmm6,%xmm4 + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + psrld $11,%xmm6 + xorl %edx,%r14d + pxor %xmm5,%xmm4 + andl %r11d,%r12d + xorl %r11d,%r13d + pslld $11,%xmm5 + addl 52(%rsp),%ecx + movl %edx,%edi + pxor %xmm6,%xmm4 + xorl %ebx,%r12d + rorl $11,%r14d + movdqa %xmm7,%xmm6 + xorl %r8d,%edi + addl %r12d,%ecx + pxor %xmm5,%xmm4 + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + psrld $10,%xmm7 + addl %r13d,%ecx + xorl %r8d,%r15d + paddd %xmm4,%xmm3 + rorl $2,%r14d + addl %ecx,%r10d + psrlq $17,%xmm6 + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + pxor %xmm6,%xmm7 + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + psrlq $2,%xmm6 + xorl %r10d,%r13d + xorl %eax,%r12d + pxor %xmm6,%xmm7 + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + pshufd $128,%xmm7,%xmm7 + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + psrldq $8,%xmm7 + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + paddd %xmm7,%xmm3 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + pshufd $80,%xmm3,%xmm7 + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + movdqa %xmm7,%xmm6 + addl %edi,%ebx + movl %r9d,%r13d + psrld $10,%xmm7 + addl %ebx,%r14d + rorl $14,%r13d + psrlq $17,%xmm6 + movl %r14d,%ebx + movl %r10d,%r12d + pxor %xmm6,%xmm7 + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + psrlq $2,%xmm6 + andl %r9d,%r12d + xorl %r9d,%r13d + addl 60(%rsp),%eax + pxor %xmm6,%xmm7 + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + pshufd $8,%xmm7,%xmm7 + xorl %ecx,%edi + addl %r12d,%eax + movdqa 96(%rbp),%xmm6 + rorl $6,%r13d + andl %edi,%r15d + pslldq $8,%xmm7 + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + paddd %xmm7,%xmm3 + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + paddd %xmm3,%xmm6 + movl %r8d,%r13d + addl %eax,%r14d + movdqa %xmm6,48(%rsp) + cmpb $0,131(%rbp) + jne .Lssse3_00_47 + rorl $14,%r13d + movl %r14d,%eax + movl %r9d,%r12d + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + rorl $6,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + rorl $2,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + rorl $14,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + rorl $11,%r14d + xorl %eax,%edi + addl %r12d,%r10d + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + rorl $2,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + rorl $14,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + rorl $6,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + rorl $14,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + rorl $6,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + rorl $2,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + rorl $14,%r13d + movl %r14d,%edx + movl %eax,%r12d + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + rorl $11,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + rorl $2,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + rorl $14,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + xorl %ecx,%edi + addl %r12d,%eax + rorl $6,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + rorl $14,%r13d + movl %r14d,%eax + movl %r9d,%r12d + rorl $9,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + rorl $5,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + rorl $11,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + rorl $6,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + rorl $2,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + rorl $14,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + rorl $9,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + rorl $5,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + rorl $11,%r14d + xorl %eax,%edi + addl %r12d,%r10d + rorl $6,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + rorl $2,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + rorl $14,%r13d + movl %r14d,%r10d + movl %edx,%r12d + rorl $9,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + rorl $5,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + rorl $11,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + rorl $6,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + rorl $2,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + rorl $14,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + rorl $9,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + rorl $5,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + rorl $11,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + rorl $6,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + rorl $2,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + rorl $14,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + rorl $9,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + rorl $5,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + rorl $11,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + rorl $6,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + rorl $2,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + rorl $14,%r13d + movl %r14d,%edx + movl %eax,%r12d + rorl $9,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + rorl $5,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + rorl $11,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + rorl $6,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + rorl $2,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + rorl $14,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + rorl $9,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + rorl $5,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + rorl $11,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + rorl $6,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + rorl $2,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + rorl $14,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + rorl $9,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + rorl $5,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + rorl $11,%r14d + xorl %ecx,%edi + addl %r12d,%eax + rorl $6,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + rorl $2,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + movq 64+0(%rsp),%rdi + movl %r14d,%eax + + addl 0(%rdi),%eax + leaq 64(%rsi),%rsi + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb .Lloop_ssse3 + + movq 88(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_ssse3: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_block_data_order_ssse3,.-sha256_block_data_order_ssse3 +.type sha256_block_data_order_avx,@function +.align 64 +sha256_block_data_order_avx: +.cfi_startproc +.Lavx_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + shlq $4,%rdx + subq $96,%rsp + leaq (%rsi,%rdx,4),%rdx + andq $-64,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %rax,88(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xd8,0x00,0x06,0x23,0x08 +.Lprologue_avx: + + vzeroupper + movl 0(%rdi),%eax + movl 4(%rdi),%ebx + movl 8(%rdi),%ecx + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + vmovdqa K256+512+32(%rip),%xmm8 + vmovdqa K256+512+64(%rip),%xmm9 + jmp .Lloop_avx +.align 16 +.Lloop_avx: + vmovdqa K256+512(%rip),%xmm7 + vmovdqu 0(%rsi),%xmm0 + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm7,%xmm0,%xmm0 + leaq K256(%rip),%rbp + vpshufb %xmm7,%xmm1,%xmm1 + vpshufb %xmm7,%xmm2,%xmm2 + vpaddd 0(%rbp),%xmm0,%xmm4 + vpshufb %xmm7,%xmm3,%xmm3 + vpaddd 32(%rbp),%xmm1,%xmm5 + vpaddd 64(%rbp),%xmm2,%xmm6 + vpaddd 96(%rbp),%xmm3,%xmm7 + vmovdqa %xmm4,0(%rsp) + movl %eax,%r14d + vmovdqa %xmm5,16(%rsp) + movl %ebx,%edi + vmovdqa %xmm6,32(%rsp) + xorl %ecx,%edi + vmovdqa %xmm7,48(%rsp) + movl %r8d,%r13d + jmp .Lavx_00_47 + +.align 16 +.Lavx_00_47: + subq $-128,%rbp + vpalignr $4,%xmm0,%xmm1,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm2,%xmm3,%xmm7 + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm0,%xmm0 + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + vpshufd $250,%xmm3,%xmm7 + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm0,%xmm0 + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpaddd %xmm6,%xmm0,%xmm0 + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + vpshufd $80,%xmm0,%xmm7 + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + vpaddd %xmm6,%xmm0,%xmm0 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpaddd 0(%rbp),%xmm0,%xmm6 + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,0(%rsp) + vpalignr $4,%xmm1,%xmm2,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm3,%xmm0,%xmm7 + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm1,%xmm1 + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + vpshufd $250,%xmm0,%xmm7 + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm1,%xmm1 + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpaddd %xmm6,%xmm1,%xmm1 + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + vpshufd $80,%xmm1,%xmm7 + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + vpxor %xmm7,%xmm6,%xmm6 + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + vpaddd %xmm6,%xmm1,%xmm1 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpaddd 32(%rbp),%xmm1,%xmm6 + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,16(%rsp) + vpalignr $4,%xmm2,%xmm3,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + vpalignr $4,%xmm0,%xmm1,%xmm7 + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + vpaddd %xmm7,%xmm2,%xmm2 + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + vpshufd $250,%xmm1,%xmm7 + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + vpsrld $11,%xmm6,%xmm6 + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + vpaddd %xmm4,%xmm2,%xmm2 + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + vpxor %xmm7,%xmm6,%xmm6 + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + vpaddd %xmm6,%xmm2,%xmm2 + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + vpshufd $80,%xmm2,%xmm7 + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + vpxor %xmm7,%xmm6,%xmm6 + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + vpaddd %xmm6,%xmm2,%xmm2 + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + vpaddd 64(%rbp),%xmm2,%xmm6 + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + vmovdqa %xmm6,32(%rsp) + vpalignr $4,%xmm3,%xmm0,%xmm4 + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + vpalignr $4,%xmm1,%xmm2,%xmm7 + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + vpsrld $7,%xmm4,%xmm6 + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + vpaddd %xmm7,%xmm3,%xmm3 + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + vpsrld $3,%xmm4,%xmm7 + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + vpslld $14,%xmm4,%xmm5 + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + vpxor %xmm6,%xmm7,%xmm4 + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + vpshufd $250,%xmm2,%xmm7 + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + vpsrld $11,%xmm6,%xmm6 + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + vpxor %xmm5,%xmm4,%xmm4 + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + vpslld $11,%xmm5,%xmm5 + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + vpxor %xmm6,%xmm4,%xmm4 + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + vpsrld $10,%xmm7,%xmm6 + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + vpxor %xmm5,%xmm4,%xmm4 + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + vpsrlq $17,%xmm7,%xmm7 + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + vpaddd %xmm4,%xmm3,%xmm3 + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + vpxor %xmm7,%xmm6,%xmm6 + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + vpsrlq $2,%xmm7,%xmm7 + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + vpxor %xmm7,%xmm6,%xmm6 + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + vpshufb %xmm8,%xmm6,%xmm6 + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + vpaddd %xmm6,%xmm3,%xmm3 + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + vpshufd $80,%xmm3,%xmm7 + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + vpsrld $10,%xmm7,%xmm6 + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + vpsrlq $17,%xmm7,%xmm7 + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + vpxor %xmm7,%xmm6,%xmm6 + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + vpsrlq $2,%xmm7,%xmm7 + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + vpxor %xmm7,%xmm6,%xmm6 + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + vpshufb %xmm9,%xmm6,%xmm6 + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + vpaddd %xmm6,%xmm3,%xmm3 + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + vpaddd 96(%rbp),%xmm3,%xmm6 + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + vmovdqa %xmm6,48(%rsp) + cmpb $0,131(%rbp) + jne .Lavx_00_47 + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 0(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 4(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 8(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 12(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 16(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 20(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 24(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 28(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%eax + movl %r9d,%r12d + shrdl $9,%r14d,%r14d + xorl %r8d,%r13d + xorl %r10d,%r12d + shrdl $5,%r13d,%r13d + xorl %eax,%r14d + andl %r8d,%r12d + xorl %r8d,%r13d + addl 32(%rsp),%r11d + movl %eax,%r15d + xorl %r10d,%r12d + shrdl $11,%r14d,%r14d + xorl %ebx,%r15d + addl %r12d,%r11d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %eax,%r14d + addl %r13d,%r11d + xorl %ebx,%edi + shrdl $2,%r14d,%r14d + addl %r11d,%edx + addl %edi,%r11d + movl %edx,%r13d + addl %r11d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r11d + movl %r8d,%r12d + shrdl $9,%r14d,%r14d + xorl %edx,%r13d + xorl %r9d,%r12d + shrdl $5,%r13d,%r13d + xorl %r11d,%r14d + andl %edx,%r12d + xorl %edx,%r13d + addl 36(%rsp),%r10d + movl %r11d,%edi + xorl %r9d,%r12d + shrdl $11,%r14d,%r14d + xorl %eax,%edi + addl %r12d,%r10d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r11d,%r14d + addl %r13d,%r10d + xorl %eax,%r15d + shrdl $2,%r14d,%r14d + addl %r10d,%ecx + addl %r15d,%r10d + movl %ecx,%r13d + addl %r10d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r10d + movl %edx,%r12d + shrdl $9,%r14d,%r14d + xorl %ecx,%r13d + xorl %r8d,%r12d + shrdl $5,%r13d,%r13d + xorl %r10d,%r14d + andl %ecx,%r12d + xorl %ecx,%r13d + addl 40(%rsp),%r9d + movl %r10d,%r15d + xorl %r8d,%r12d + shrdl $11,%r14d,%r14d + xorl %r11d,%r15d + addl %r12d,%r9d + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r10d,%r14d + addl %r13d,%r9d + xorl %r11d,%edi + shrdl $2,%r14d,%r14d + addl %r9d,%ebx + addl %edi,%r9d + movl %ebx,%r13d + addl %r9d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r9d + movl %ecx,%r12d + shrdl $9,%r14d,%r14d + xorl %ebx,%r13d + xorl %edx,%r12d + shrdl $5,%r13d,%r13d + xorl %r9d,%r14d + andl %ebx,%r12d + xorl %ebx,%r13d + addl 44(%rsp),%r8d + movl %r9d,%edi + xorl %edx,%r12d + shrdl $11,%r14d,%r14d + xorl %r10d,%edi + addl %r12d,%r8d + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %r9d,%r14d + addl %r13d,%r8d + xorl %r10d,%r15d + shrdl $2,%r14d,%r14d + addl %r8d,%eax + addl %r15d,%r8d + movl %eax,%r13d + addl %r8d,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%r8d + movl %ebx,%r12d + shrdl $9,%r14d,%r14d + xorl %eax,%r13d + xorl %ecx,%r12d + shrdl $5,%r13d,%r13d + xorl %r8d,%r14d + andl %eax,%r12d + xorl %eax,%r13d + addl 48(%rsp),%edx + movl %r8d,%r15d + xorl %ecx,%r12d + shrdl $11,%r14d,%r14d + xorl %r9d,%r15d + addl %r12d,%edx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %r8d,%r14d + addl %r13d,%edx + xorl %r9d,%edi + shrdl $2,%r14d,%r14d + addl %edx,%r11d + addl %edi,%edx + movl %r11d,%r13d + addl %edx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%edx + movl %eax,%r12d + shrdl $9,%r14d,%r14d + xorl %r11d,%r13d + xorl %ebx,%r12d + shrdl $5,%r13d,%r13d + xorl %edx,%r14d + andl %r11d,%r12d + xorl %r11d,%r13d + addl 52(%rsp),%ecx + movl %edx,%edi + xorl %ebx,%r12d + shrdl $11,%r14d,%r14d + xorl %r8d,%edi + addl %r12d,%ecx + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %edx,%r14d + addl %r13d,%ecx + xorl %r8d,%r15d + shrdl $2,%r14d,%r14d + addl %ecx,%r10d + addl %r15d,%ecx + movl %r10d,%r13d + addl %ecx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ecx + movl %r11d,%r12d + shrdl $9,%r14d,%r14d + xorl %r10d,%r13d + xorl %eax,%r12d + shrdl $5,%r13d,%r13d + xorl %ecx,%r14d + andl %r10d,%r12d + xorl %r10d,%r13d + addl 56(%rsp),%ebx + movl %ecx,%r15d + xorl %eax,%r12d + shrdl $11,%r14d,%r14d + xorl %edx,%r15d + addl %r12d,%ebx + shrdl $6,%r13d,%r13d + andl %r15d,%edi + xorl %ecx,%r14d + addl %r13d,%ebx + xorl %edx,%edi + shrdl $2,%r14d,%r14d + addl %ebx,%r9d + addl %edi,%ebx + movl %r9d,%r13d + addl %ebx,%r14d + shrdl $14,%r13d,%r13d + movl %r14d,%ebx + movl %r10d,%r12d + shrdl $9,%r14d,%r14d + xorl %r9d,%r13d + xorl %r11d,%r12d + shrdl $5,%r13d,%r13d + xorl %ebx,%r14d + andl %r9d,%r12d + xorl %r9d,%r13d + addl 60(%rsp),%eax + movl %ebx,%edi + xorl %r11d,%r12d + shrdl $11,%r14d,%r14d + xorl %ecx,%edi + addl %r12d,%eax + shrdl $6,%r13d,%r13d + andl %edi,%r15d + xorl %ebx,%r14d + addl %r13d,%eax + xorl %ecx,%r15d + shrdl $2,%r14d,%r14d + addl %eax,%r8d + addl %r15d,%eax + movl %r8d,%r13d + addl %eax,%r14d + movq 64+0(%rsp),%rdi + movl %r14d,%eax + + addl 0(%rdi),%eax + leaq 64(%rsi),%rsi + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + jb .Lloop_avx + + movq 88(%rsp),%rsi +.cfi_def_cfa %rsi,8 + vzeroupper + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_block_data_order_avx,.-sha256_block_data_order_avx +.type sha256_block_data_order_avx2,@function +.align 64 +sha256_block_data_order_avx2: +.cfi_startproc +.Lavx2_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + subq $544,%rsp + shlq $4,%rdx + andq $-1024,%rsp + leaq (%rsi,%rdx,4),%rdx + addq $448,%rsp + movq %rdi,64+0(%rsp) + movq %rsi,64+8(%rsp) + movq %rdx,64+16(%rsp) + movq %rax,88(%rsp) +.cfi_escape 0x0f,0x06,0x77,0xd8,0x00,0x06,0x23,0x08 +.Lprologue_avx2: + + vzeroupper + subq $-64,%rsi + movl 0(%rdi),%eax + movq %rsi,%r12 + movl 4(%rdi),%ebx + cmpq %rdx,%rsi + movl 8(%rdi),%ecx + cmoveq %rsp,%r12 + movl 12(%rdi),%edx + movl 16(%rdi),%r8d + movl 20(%rdi),%r9d + movl 24(%rdi),%r10d + movl 28(%rdi),%r11d + vmovdqa K256+512+32(%rip),%ymm8 + vmovdqa K256+512+64(%rip),%ymm9 + jmp .Loop_avx2 +.align 16 +.Loop_avx2: + vmovdqa K256+512(%rip),%ymm7 + vmovdqu -64+0(%rsi),%xmm0 + vmovdqu -64+16(%rsi),%xmm1 + vmovdqu -64+32(%rsi),%xmm2 + vmovdqu -64+48(%rsi),%xmm3 + + vinserti128 $1,(%r12),%ymm0,%ymm0 + vinserti128 $1,16(%r12),%ymm1,%ymm1 + vpshufb %ymm7,%ymm0,%ymm0 + vinserti128 $1,32(%r12),%ymm2,%ymm2 + vpshufb %ymm7,%ymm1,%ymm1 + vinserti128 $1,48(%r12),%ymm3,%ymm3 + + leaq K256(%rip),%rbp + vpshufb %ymm7,%ymm2,%ymm2 + vpaddd 0(%rbp),%ymm0,%ymm4 + vpshufb %ymm7,%ymm3,%ymm3 + vpaddd 32(%rbp),%ymm1,%ymm5 + vpaddd 64(%rbp),%ymm2,%ymm6 + vpaddd 96(%rbp),%ymm3,%ymm7 + vmovdqa %ymm4,0(%rsp) + xorl %r14d,%r14d + vmovdqa %ymm5,32(%rsp) + + movq 88(%rsp),%rdi +.cfi_def_cfa %rdi,8 + leaq -64(%rsp),%rsp + + + + movq %rdi,-8(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x78,0x06,0x23,0x08 + movl %ebx,%edi + vmovdqa %ymm6,0(%rsp) + xorl %ecx,%edi + vmovdqa %ymm7,32(%rsp) + movl %r9d,%r12d + subq $-32*4,%rbp + jmp .Lavx2_00_47 + +.align 16 +.Lavx2_00_47: + leaq -64(%rsp),%rsp +.cfi_escape 0x0f,0x05,0x77,0x38,0x06,0x23,0x08 + + pushq 64-8(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x00,0x06,0x23,0x08 + leaq 8(%rsp),%rsp +.cfi_escape 0x0f,0x05,0x77,0x78,0x06,0x23,0x08 + vpalignr $4,%ymm0,%ymm1,%ymm4 + addl 0+128(%rsp),%r11d + andl %r8d,%r12d + rorxl $25,%r8d,%r13d + vpalignr $4,%ymm2,%ymm3,%ymm7 + rorxl $11,%r8d,%r15d + leal (%rax,%r14,1),%eax + leal (%r11,%r12,1),%r11d + vpsrld $7,%ymm4,%ymm6 + andnl %r10d,%r8d,%r12d + xorl %r15d,%r13d + rorxl $6,%r8d,%r14d + vpaddd %ymm7,%ymm0,%ymm0 + leal (%r11,%r12,1),%r11d + xorl %r14d,%r13d + movl %eax,%r15d + vpsrld $3,%ymm4,%ymm7 + rorxl $22,%eax,%r12d + leal (%r11,%r13,1),%r11d + xorl %ebx,%r15d + vpslld $14,%ymm4,%ymm5 + rorxl $13,%eax,%r14d + rorxl $2,%eax,%r13d + leal (%rdx,%r11,1),%edx + vpxor %ymm6,%ymm7,%ymm4 + andl %r15d,%edi + xorl %r12d,%r14d + xorl %ebx,%edi + vpshufd $250,%ymm3,%ymm7 + xorl %r13d,%r14d + leal (%r11,%rdi,1),%r11d + movl %r8d,%r12d + vpsrld $11,%ymm6,%ymm6 + addl 4+128(%rsp),%r10d + andl %edx,%r12d + rorxl $25,%edx,%r13d + vpxor %ymm5,%ymm4,%ymm4 + rorxl $11,%edx,%edi + leal (%r11,%r14,1),%r11d + leal (%r10,%r12,1),%r10d + vpslld $11,%ymm5,%ymm5 + andnl %r9d,%edx,%r12d + xorl %edi,%r13d + rorxl $6,%edx,%r14d + vpxor %ymm6,%ymm4,%ymm4 + leal (%r10,%r12,1),%r10d + xorl %r14d,%r13d + movl %r11d,%edi + vpsrld $10,%ymm7,%ymm6 + rorxl $22,%r11d,%r12d + leal (%r10,%r13,1),%r10d + xorl %eax,%edi + vpxor %ymm5,%ymm4,%ymm4 + rorxl $13,%r11d,%r14d + rorxl $2,%r11d,%r13d + leal (%rcx,%r10,1),%ecx + vpsrlq $17,%ymm7,%ymm7 + andl %edi,%r15d + xorl %r12d,%r14d + xorl %eax,%r15d + vpaddd %ymm4,%ymm0,%ymm0 + xorl %r13d,%r14d + leal (%r10,%r15,1),%r10d + movl %edx,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 8+128(%rsp),%r9d + andl %ecx,%r12d + rorxl $25,%ecx,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%ecx,%r15d + leal (%r10,%r14,1),%r10d + leal (%r9,%r12,1),%r9d + vpxor %ymm7,%ymm6,%ymm6 + andnl %r8d,%ecx,%r12d + xorl %r15d,%r13d + rorxl $6,%ecx,%r14d + vpshufb %ymm8,%ymm6,%ymm6 + leal (%r9,%r12,1),%r9d + xorl %r14d,%r13d + movl %r10d,%r15d + vpaddd %ymm6,%ymm0,%ymm0 + rorxl $22,%r10d,%r12d + leal (%r9,%r13,1),%r9d + xorl %r11d,%r15d + vpshufd $80,%ymm0,%ymm7 + rorxl $13,%r10d,%r14d + rorxl $2,%r10d,%r13d + leal (%rbx,%r9,1),%ebx + vpsrld $10,%ymm7,%ymm6 + andl %r15d,%edi + xorl %r12d,%r14d + xorl %r11d,%edi + vpsrlq $17,%ymm7,%ymm7 + xorl %r13d,%r14d + leal (%r9,%rdi,1),%r9d + movl %ecx,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 12+128(%rsp),%r8d + andl %ebx,%r12d + rorxl $25,%ebx,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%ebx,%edi + leal (%r9,%r14,1),%r9d + leal (%r8,%r12,1),%r8d + vpxor %ymm7,%ymm6,%ymm6 + andnl %edx,%ebx,%r12d + xorl %edi,%r13d + rorxl $6,%ebx,%r14d + vpshufb %ymm9,%ymm6,%ymm6 + leal (%r8,%r12,1),%r8d + xorl %r14d,%r13d + movl %r9d,%edi + vpaddd %ymm6,%ymm0,%ymm0 + rorxl $22,%r9d,%r12d + leal (%r8,%r13,1),%r8d + xorl %r10d,%edi + vpaddd 0(%rbp),%ymm0,%ymm6 + rorxl $13,%r9d,%r14d + rorxl $2,%r9d,%r13d + leal (%rax,%r8,1),%eax + andl %edi,%r15d + xorl %r12d,%r14d + xorl %r10d,%r15d + xorl %r13d,%r14d + leal (%r8,%r15,1),%r8d + movl %ebx,%r12d + vmovdqa %ymm6,0(%rsp) + vpalignr $4,%ymm1,%ymm2,%ymm4 + addl 32+128(%rsp),%edx + andl %eax,%r12d + rorxl $25,%eax,%r13d + vpalignr $4,%ymm3,%ymm0,%ymm7 + rorxl $11,%eax,%r15d + leal (%r8,%r14,1),%r8d + leal (%rdx,%r12,1),%edx + vpsrld $7,%ymm4,%ymm6 + andnl %ecx,%eax,%r12d + xorl %r15d,%r13d + rorxl $6,%eax,%r14d + vpaddd %ymm7,%ymm1,%ymm1 + leal (%rdx,%r12,1),%edx + xorl %r14d,%r13d + movl %r8d,%r15d + vpsrld $3,%ymm4,%ymm7 + rorxl $22,%r8d,%r12d + leal (%rdx,%r13,1),%edx + xorl %r9d,%r15d + vpslld $14,%ymm4,%ymm5 + rorxl $13,%r8d,%r14d + rorxl $2,%r8d,%r13d + leal (%r11,%rdx,1),%r11d + vpxor %ymm6,%ymm7,%ymm4 + andl %r15d,%edi + xorl %r12d,%r14d + xorl %r9d,%edi + vpshufd $250,%ymm0,%ymm7 + xorl %r13d,%r14d + leal (%rdx,%rdi,1),%edx + movl %eax,%r12d + vpsrld $11,%ymm6,%ymm6 + addl 36+128(%rsp),%ecx + andl %r11d,%r12d + rorxl $25,%r11d,%r13d + vpxor %ymm5,%ymm4,%ymm4 + rorxl $11,%r11d,%edi + leal (%rdx,%r14,1),%edx + leal (%rcx,%r12,1),%ecx + vpslld $11,%ymm5,%ymm5 + andnl %ebx,%r11d,%r12d + xorl %edi,%r13d + rorxl $6,%r11d,%r14d + vpxor %ymm6,%ymm4,%ymm4 + leal (%rcx,%r12,1),%ecx + xorl %r14d,%r13d + movl %edx,%edi + vpsrld $10,%ymm7,%ymm6 + rorxl $22,%edx,%r12d + leal (%rcx,%r13,1),%ecx + xorl %r8d,%edi + vpxor %ymm5,%ymm4,%ymm4 + rorxl $13,%edx,%r14d + rorxl $2,%edx,%r13d + leal (%r10,%rcx,1),%r10d + vpsrlq $17,%ymm7,%ymm7 + andl %edi,%r15d + xorl %r12d,%r14d + xorl %r8d,%r15d + vpaddd %ymm4,%ymm1,%ymm1 + xorl %r13d,%r14d + leal (%rcx,%r15,1),%ecx + movl %r11d,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 40+128(%rsp),%ebx + andl %r10d,%r12d + rorxl $25,%r10d,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%r10d,%r15d + leal (%rcx,%r14,1),%ecx + leal (%rbx,%r12,1),%ebx + vpxor %ymm7,%ymm6,%ymm6 + andnl %eax,%r10d,%r12d + xorl %r15d,%r13d + rorxl $6,%r10d,%r14d + vpshufb %ymm8,%ymm6,%ymm6 + leal (%rbx,%r12,1),%ebx + xorl %r14d,%r13d + movl %ecx,%r15d + vpaddd %ymm6,%ymm1,%ymm1 + rorxl $22,%ecx,%r12d + leal (%rbx,%r13,1),%ebx + xorl %edx,%r15d + vpshufd $80,%ymm1,%ymm7 + rorxl $13,%ecx,%r14d + rorxl $2,%ecx,%r13d + leal (%r9,%rbx,1),%r9d + vpsrld $10,%ymm7,%ymm6 + andl %r15d,%edi + xorl %r12d,%r14d + xorl %edx,%edi + vpsrlq $17,%ymm7,%ymm7 + xorl %r13d,%r14d + leal (%rbx,%rdi,1),%ebx + movl %r10d,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 44+128(%rsp),%eax + andl %r9d,%r12d + rorxl $25,%r9d,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%r9d,%edi + leal (%rbx,%r14,1),%ebx + leal (%rax,%r12,1),%eax + vpxor %ymm7,%ymm6,%ymm6 + andnl %r11d,%r9d,%r12d + xorl %edi,%r13d + rorxl $6,%r9d,%r14d + vpshufb %ymm9,%ymm6,%ymm6 + leal (%rax,%r12,1),%eax + xorl %r14d,%r13d + movl %ebx,%edi + vpaddd %ymm6,%ymm1,%ymm1 + rorxl $22,%ebx,%r12d + leal (%rax,%r13,1),%eax + xorl %ecx,%edi + vpaddd 32(%rbp),%ymm1,%ymm6 + rorxl $13,%ebx,%r14d + rorxl $2,%ebx,%r13d + leal (%r8,%rax,1),%r8d + andl %edi,%r15d + xorl %r12d,%r14d + xorl %ecx,%r15d + xorl %r13d,%r14d + leal (%rax,%r15,1),%eax + movl %r9d,%r12d + vmovdqa %ymm6,32(%rsp) + leaq -64(%rsp),%rsp +.cfi_escape 0x0f,0x05,0x77,0x38,0x06,0x23,0x08 + + pushq 64-8(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x00,0x06,0x23,0x08 + leaq 8(%rsp),%rsp +.cfi_escape 0x0f,0x05,0x77,0x78,0x06,0x23,0x08 + vpalignr $4,%ymm2,%ymm3,%ymm4 + addl 0+128(%rsp),%r11d + andl %r8d,%r12d + rorxl $25,%r8d,%r13d + vpalignr $4,%ymm0,%ymm1,%ymm7 + rorxl $11,%r8d,%r15d + leal (%rax,%r14,1),%eax + leal (%r11,%r12,1),%r11d + vpsrld $7,%ymm4,%ymm6 + andnl %r10d,%r8d,%r12d + xorl %r15d,%r13d + rorxl $6,%r8d,%r14d + vpaddd %ymm7,%ymm2,%ymm2 + leal (%r11,%r12,1),%r11d + xorl %r14d,%r13d + movl %eax,%r15d + vpsrld $3,%ymm4,%ymm7 + rorxl $22,%eax,%r12d + leal (%r11,%r13,1),%r11d + xorl %ebx,%r15d + vpslld $14,%ymm4,%ymm5 + rorxl $13,%eax,%r14d + rorxl $2,%eax,%r13d + leal (%rdx,%r11,1),%edx + vpxor %ymm6,%ymm7,%ymm4 + andl %r15d,%edi + xorl %r12d,%r14d + xorl %ebx,%edi + vpshufd $250,%ymm1,%ymm7 + xorl %r13d,%r14d + leal (%r11,%rdi,1),%r11d + movl %r8d,%r12d + vpsrld $11,%ymm6,%ymm6 + addl 4+128(%rsp),%r10d + andl %edx,%r12d + rorxl $25,%edx,%r13d + vpxor %ymm5,%ymm4,%ymm4 + rorxl $11,%edx,%edi + leal (%r11,%r14,1),%r11d + leal (%r10,%r12,1),%r10d + vpslld $11,%ymm5,%ymm5 + andnl %r9d,%edx,%r12d + xorl %edi,%r13d + rorxl $6,%edx,%r14d + vpxor %ymm6,%ymm4,%ymm4 + leal (%r10,%r12,1),%r10d + xorl %r14d,%r13d + movl %r11d,%edi + vpsrld $10,%ymm7,%ymm6 + rorxl $22,%r11d,%r12d + leal (%r10,%r13,1),%r10d + xorl %eax,%edi + vpxor %ymm5,%ymm4,%ymm4 + rorxl $13,%r11d,%r14d + rorxl $2,%r11d,%r13d + leal (%rcx,%r10,1),%ecx + vpsrlq $17,%ymm7,%ymm7 + andl %edi,%r15d + xorl %r12d,%r14d + xorl %eax,%r15d + vpaddd %ymm4,%ymm2,%ymm2 + xorl %r13d,%r14d + leal (%r10,%r15,1),%r10d + movl %edx,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 8+128(%rsp),%r9d + andl %ecx,%r12d + rorxl $25,%ecx,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%ecx,%r15d + leal (%r10,%r14,1),%r10d + leal (%r9,%r12,1),%r9d + vpxor %ymm7,%ymm6,%ymm6 + andnl %r8d,%ecx,%r12d + xorl %r15d,%r13d + rorxl $6,%ecx,%r14d + vpshufb %ymm8,%ymm6,%ymm6 + leal (%r9,%r12,1),%r9d + xorl %r14d,%r13d + movl %r10d,%r15d + vpaddd %ymm6,%ymm2,%ymm2 + rorxl $22,%r10d,%r12d + leal (%r9,%r13,1),%r9d + xorl %r11d,%r15d + vpshufd $80,%ymm2,%ymm7 + rorxl $13,%r10d,%r14d + rorxl $2,%r10d,%r13d + leal (%rbx,%r9,1),%ebx + vpsrld $10,%ymm7,%ymm6 + andl %r15d,%edi + xorl %r12d,%r14d + xorl %r11d,%edi + vpsrlq $17,%ymm7,%ymm7 + xorl %r13d,%r14d + leal (%r9,%rdi,1),%r9d + movl %ecx,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 12+128(%rsp),%r8d + andl %ebx,%r12d + rorxl $25,%ebx,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%ebx,%edi + leal (%r9,%r14,1),%r9d + leal (%r8,%r12,1),%r8d + vpxor %ymm7,%ymm6,%ymm6 + andnl %edx,%ebx,%r12d + xorl %edi,%r13d + rorxl $6,%ebx,%r14d + vpshufb %ymm9,%ymm6,%ymm6 + leal (%r8,%r12,1),%r8d + xorl %r14d,%r13d + movl %r9d,%edi + vpaddd %ymm6,%ymm2,%ymm2 + rorxl $22,%r9d,%r12d + leal (%r8,%r13,1),%r8d + xorl %r10d,%edi + vpaddd 64(%rbp),%ymm2,%ymm6 + rorxl $13,%r9d,%r14d + rorxl $2,%r9d,%r13d + leal (%rax,%r8,1),%eax + andl %edi,%r15d + xorl %r12d,%r14d + xorl %r10d,%r15d + xorl %r13d,%r14d + leal (%r8,%r15,1),%r8d + movl %ebx,%r12d + vmovdqa %ymm6,0(%rsp) + vpalignr $4,%ymm3,%ymm0,%ymm4 + addl 32+128(%rsp),%edx + andl %eax,%r12d + rorxl $25,%eax,%r13d + vpalignr $4,%ymm1,%ymm2,%ymm7 + rorxl $11,%eax,%r15d + leal (%r8,%r14,1),%r8d + leal (%rdx,%r12,1),%edx + vpsrld $7,%ymm4,%ymm6 + andnl %ecx,%eax,%r12d + xorl %r15d,%r13d + rorxl $6,%eax,%r14d + vpaddd %ymm7,%ymm3,%ymm3 + leal (%rdx,%r12,1),%edx + xorl %r14d,%r13d + movl %r8d,%r15d + vpsrld $3,%ymm4,%ymm7 + rorxl $22,%r8d,%r12d + leal (%rdx,%r13,1),%edx + xorl %r9d,%r15d + vpslld $14,%ymm4,%ymm5 + rorxl $13,%r8d,%r14d + rorxl $2,%r8d,%r13d + leal (%r11,%rdx,1),%r11d + vpxor %ymm6,%ymm7,%ymm4 + andl %r15d,%edi + xorl %r12d,%r14d + xorl %r9d,%edi + vpshufd $250,%ymm2,%ymm7 + xorl %r13d,%r14d + leal (%rdx,%rdi,1),%edx + movl %eax,%r12d + vpsrld $11,%ymm6,%ymm6 + addl 36+128(%rsp),%ecx + andl %r11d,%r12d + rorxl $25,%r11d,%r13d + vpxor %ymm5,%ymm4,%ymm4 + rorxl $11,%r11d,%edi + leal (%rdx,%r14,1),%edx + leal (%rcx,%r12,1),%ecx + vpslld $11,%ymm5,%ymm5 + andnl %ebx,%r11d,%r12d + xorl %edi,%r13d + rorxl $6,%r11d,%r14d + vpxor %ymm6,%ymm4,%ymm4 + leal (%rcx,%r12,1),%ecx + xorl %r14d,%r13d + movl %edx,%edi + vpsrld $10,%ymm7,%ymm6 + rorxl $22,%edx,%r12d + leal (%rcx,%r13,1),%ecx + xorl %r8d,%edi + vpxor %ymm5,%ymm4,%ymm4 + rorxl $13,%edx,%r14d + rorxl $2,%edx,%r13d + leal (%r10,%rcx,1),%r10d + vpsrlq $17,%ymm7,%ymm7 + andl %edi,%r15d + xorl %r12d,%r14d + xorl %r8d,%r15d + vpaddd %ymm4,%ymm3,%ymm3 + xorl %r13d,%r14d + leal (%rcx,%r15,1),%ecx + movl %r11d,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 40+128(%rsp),%ebx + andl %r10d,%r12d + rorxl $25,%r10d,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%r10d,%r15d + leal (%rcx,%r14,1),%ecx + leal (%rbx,%r12,1),%ebx + vpxor %ymm7,%ymm6,%ymm6 + andnl %eax,%r10d,%r12d + xorl %r15d,%r13d + rorxl $6,%r10d,%r14d + vpshufb %ymm8,%ymm6,%ymm6 + leal (%rbx,%r12,1),%ebx + xorl %r14d,%r13d + movl %ecx,%r15d + vpaddd %ymm6,%ymm3,%ymm3 + rorxl $22,%ecx,%r12d + leal (%rbx,%r13,1),%ebx + xorl %edx,%r15d + vpshufd $80,%ymm3,%ymm7 + rorxl $13,%ecx,%r14d + rorxl $2,%ecx,%r13d + leal (%r9,%rbx,1),%r9d + vpsrld $10,%ymm7,%ymm6 + andl %r15d,%edi + xorl %r12d,%r14d + xorl %edx,%edi + vpsrlq $17,%ymm7,%ymm7 + xorl %r13d,%r14d + leal (%rbx,%rdi,1),%ebx + movl %r10d,%r12d + vpxor %ymm7,%ymm6,%ymm6 + addl 44+128(%rsp),%eax + andl %r9d,%r12d + rorxl $25,%r9d,%r13d + vpsrlq $2,%ymm7,%ymm7 + rorxl $11,%r9d,%edi + leal (%rbx,%r14,1),%ebx + leal (%rax,%r12,1),%eax + vpxor %ymm7,%ymm6,%ymm6 + andnl %r11d,%r9d,%r12d + xorl %edi,%r13d + rorxl $6,%r9d,%r14d + vpshufb %ymm9,%ymm6,%ymm6 + leal (%rax,%r12,1),%eax + xorl %r14d,%r13d + movl %ebx,%edi + vpaddd %ymm6,%ymm3,%ymm3 + rorxl $22,%ebx,%r12d + leal (%rax,%r13,1),%eax + xorl %ecx,%edi + vpaddd 96(%rbp),%ymm3,%ymm6 + rorxl $13,%ebx,%r14d + rorxl $2,%ebx,%r13d + leal (%r8,%rax,1),%r8d + andl %edi,%r15d + xorl %r12d,%r14d + xorl %ecx,%r15d + xorl %r13d,%r14d + leal (%rax,%r15,1),%eax + movl %r9d,%r12d + vmovdqa %ymm6,32(%rsp) + leaq 128(%rbp),%rbp + cmpb $0,3(%rbp) + jne .Lavx2_00_47 + addl 0+64(%rsp),%r11d + andl %r8d,%r12d + rorxl $25,%r8d,%r13d + rorxl $11,%r8d,%r15d + leal (%rax,%r14,1),%eax + leal (%r11,%r12,1),%r11d + andnl %r10d,%r8d,%r12d + xorl %r15d,%r13d + rorxl $6,%r8d,%r14d + leal (%r11,%r12,1),%r11d + xorl %r14d,%r13d + movl %eax,%r15d + rorxl $22,%eax,%r12d + leal (%r11,%r13,1),%r11d + xorl %ebx,%r15d + rorxl $13,%eax,%r14d + rorxl $2,%eax,%r13d + leal (%rdx,%r11,1),%edx + andl %r15d,%edi + xorl %r12d,%r14d + xorl %ebx,%edi + xorl %r13d,%r14d + leal (%r11,%rdi,1),%r11d + movl %r8d,%r12d + addl 4+64(%rsp),%r10d + andl %edx,%r12d + rorxl $25,%edx,%r13d + rorxl $11,%edx,%edi + leal (%r11,%r14,1),%r11d + leal (%r10,%r12,1),%r10d + andnl %r9d,%edx,%r12d + xorl %edi,%r13d + rorxl $6,%edx,%r14d + leal (%r10,%r12,1),%r10d + xorl %r14d,%r13d + movl %r11d,%edi + rorxl $22,%r11d,%r12d + leal (%r10,%r13,1),%r10d + xorl %eax,%edi + rorxl $13,%r11d,%r14d + rorxl $2,%r11d,%r13d + leal (%rcx,%r10,1),%ecx + andl %edi,%r15d + xorl %r12d,%r14d + xorl %eax,%r15d + xorl %r13d,%r14d + leal (%r10,%r15,1),%r10d + movl %edx,%r12d + addl 8+64(%rsp),%r9d + andl %ecx,%r12d + rorxl $25,%ecx,%r13d + rorxl $11,%ecx,%r15d + leal (%r10,%r14,1),%r10d + leal (%r9,%r12,1),%r9d + andnl %r8d,%ecx,%r12d + xorl %r15d,%r13d + rorxl $6,%ecx,%r14d + leal (%r9,%r12,1),%r9d + xorl %r14d,%r13d + movl %r10d,%r15d + rorxl $22,%r10d,%r12d + leal (%r9,%r13,1),%r9d + xorl %r11d,%r15d + rorxl $13,%r10d,%r14d + rorxl $2,%r10d,%r13d + leal (%rbx,%r9,1),%ebx + andl %r15d,%edi + xorl %r12d,%r14d + xorl %r11d,%edi + xorl %r13d,%r14d + leal (%r9,%rdi,1),%r9d + movl %ecx,%r12d + addl 12+64(%rsp),%r8d + andl %ebx,%r12d + rorxl $25,%ebx,%r13d + rorxl $11,%ebx,%edi + leal (%r9,%r14,1),%r9d + leal (%r8,%r12,1),%r8d + andnl %edx,%ebx,%r12d + xorl %edi,%r13d + rorxl $6,%ebx,%r14d + leal (%r8,%r12,1),%r8d + xorl %r14d,%r13d + movl %r9d,%edi + rorxl $22,%r9d,%r12d + leal (%r8,%r13,1),%r8d + xorl %r10d,%edi + rorxl $13,%r9d,%r14d + rorxl $2,%r9d,%r13d + leal (%rax,%r8,1),%eax + andl %edi,%r15d + xorl %r12d,%r14d + xorl %r10d,%r15d + xorl %r13d,%r14d + leal (%r8,%r15,1),%r8d + movl %ebx,%r12d + addl 32+64(%rsp),%edx + andl %eax,%r12d + rorxl $25,%eax,%r13d + rorxl $11,%eax,%r15d + leal (%r8,%r14,1),%r8d + leal (%rdx,%r12,1),%edx + andnl %ecx,%eax,%r12d + xorl %r15d,%r13d + rorxl $6,%eax,%r14d + leal (%rdx,%r12,1),%edx + xorl %r14d,%r13d + movl %r8d,%r15d + rorxl $22,%r8d,%r12d + leal (%rdx,%r13,1),%edx + xorl %r9d,%r15d + rorxl $13,%r8d,%r14d + rorxl $2,%r8d,%r13d + leal (%r11,%rdx,1),%r11d + andl %r15d,%edi + xorl %r12d,%r14d + xorl %r9d,%edi + xorl %r13d,%r14d + leal (%rdx,%rdi,1),%edx + movl %eax,%r12d + addl 36+64(%rsp),%ecx + andl %r11d,%r12d + rorxl $25,%r11d,%r13d + rorxl $11,%r11d,%edi + leal (%rdx,%r14,1),%edx + leal (%rcx,%r12,1),%ecx + andnl %ebx,%r11d,%r12d + xorl %edi,%r13d + rorxl $6,%r11d,%r14d + leal (%rcx,%r12,1),%ecx + xorl %r14d,%r13d + movl %edx,%edi + rorxl $22,%edx,%r12d + leal (%rcx,%r13,1),%ecx + xorl %r8d,%edi + rorxl $13,%edx,%r14d + rorxl $2,%edx,%r13d + leal (%r10,%rcx,1),%r10d + andl %edi,%r15d + xorl %r12d,%r14d + xorl %r8d,%r15d + xorl %r13d,%r14d + leal (%rcx,%r15,1),%ecx + movl %r11d,%r12d + addl 40+64(%rsp),%ebx + andl %r10d,%r12d + rorxl $25,%r10d,%r13d + rorxl $11,%r10d,%r15d + leal (%rcx,%r14,1),%ecx + leal (%rbx,%r12,1),%ebx + andnl %eax,%r10d,%r12d + xorl %r15d,%r13d + rorxl $6,%r10d,%r14d + leal (%rbx,%r12,1),%ebx + xorl %r14d,%r13d + movl %ecx,%r15d + rorxl $22,%ecx,%r12d + leal (%rbx,%r13,1),%ebx + xorl %edx,%r15d + rorxl $13,%ecx,%r14d + rorxl $2,%ecx,%r13d + leal (%r9,%rbx,1),%r9d + andl %r15d,%edi + xorl %r12d,%r14d + xorl %edx,%edi + xorl %r13d,%r14d + leal (%rbx,%rdi,1),%ebx + movl %r10d,%r12d + addl 44+64(%rsp),%eax + andl %r9d,%r12d + rorxl $25,%r9d,%r13d + rorxl $11,%r9d,%edi + leal (%rbx,%r14,1),%ebx + leal (%rax,%r12,1),%eax + andnl %r11d,%r9d,%r12d + xorl %edi,%r13d + rorxl $6,%r9d,%r14d + leal (%rax,%r12,1),%eax + xorl %r14d,%r13d + movl %ebx,%edi + rorxl $22,%ebx,%r12d + leal (%rax,%r13,1),%eax + xorl %ecx,%edi + rorxl $13,%ebx,%r14d + rorxl $2,%ebx,%r13d + leal (%r8,%rax,1),%r8d + andl %edi,%r15d + xorl %r12d,%r14d + xorl %ecx,%r15d + xorl %r13d,%r14d + leal (%rax,%r15,1),%eax + movl %r9d,%r12d + addl 0(%rsp),%r11d + andl %r8d,%r12d + rorxl $25,%r8d,%r13d + rorxl $11,%r8d,%r15d + leal (%rax,%r14,1),%eax + leal (%r11,%r12,1),%r11d + andnl %r10d,%r8d,%r12d + xorl %r15d,%r13d + rorxl $6,%r8d,%r14d + leal (%r11,%r12,1),%r11d + xorl %r14d,%r13d + movl %eax,%r15d + rorxl $22,%eax,%r12d + leal (%r11,%r13,1),%r11d + xorl %ebx,%r15d + rorxl $13,%eax,%r14d + rorxl $2,%eax,%r13d + leal (%rdx,%r11,1),%edx + andl %r15d,%edi + xorl %r12d,%r14d + xorl %ebx,%edi + xorl %r13d,%r14d + leal (%r11,%rdi,1),%r11d + movl %r8d,%r12d + addl 4(%rsp),%r10d + andl %edx,%r12d + rorxl $25,%edx,%r13d + rorxl $11,%edx,%edi + leal (%r11,%r14,1),%r11d + leal (%r10,%r12,1),%r10d + andnl %r9d,%edx,%r12d + xorl %edi,%r13d + rorxl $6,%edx,%r14d + leal (%r10,%r12,1),%r10d + xorl %r14d,%r13d + movl %r11d,%edi + rorxl $22,%r11d,%r12d + leal (%r10,%r13,1),%r10d + xorl %eax,%edi + rorxl $13,%r11d,%r14d + rorxl $2,%r11d,%r13d + leal (%rcx,%r10,1),%ecx + andl %edi,%r15d + xorl %r12d,%r14d + xorl %eax,%r15d + xorl %r13d,%r14d + leal (%r10,%r15,1),%r10d + movl %edx,%r12d + addl 8(%rsp),%r9d + andl %ecx,%r12d + rorxl $25,%ecx,%r13d + rorxl $11,%ecx,%r15d + leal (%r10,%r14,1),%r10d + leal (%r9,%r12,1),%r9d + andnl %r8d,%ecx,%r12d + xorl %r15d,%r13d + rorxl $6,%ecx,%r14d + leal (%r9,%r12,1),%r9d + xorl %r14d,%r13d + movl %r10d,%r15d + rorxl $22,%r10d,%r12d + leal (%r9,%r13,1),%r9d + xorl %r11d,%r15d + rorxl $13,%r10d,%r14d + rorxl $2,%r10d,%r13d + leal (%rbx,%r9,1),%ebx + andl %r15d,%edi + xorl %r12d,%r14d + xorl %r11d,%edi + xorl %r13d,%r14d + leal (%r9,%rdi,1),%r9d + movl %ecx,%r12d + addl 12(%rsp),%r8d + andl %ebx,%r12d + rorxl $25,%ebx,%r13d + rorxl $11,%ebx,%edi + leal (%r9,%r14,1),%r9d + leal (%r8,%r12,1),%r8d + andnl %edx,%ebx,%r12d + xorl %edi,%r13d + rorxl $6,%ebx,%r14d + leal (%r8,%r12,1),%r8d + xorl %r14d,%r13d + movl %r9d,%edi + rorxl $22,%r9d,%r12d + leal (%r8,%r13,1),%r8d + xorl %r10d,%edi + rorxl $13,%r9d,%r14d + rorxl $2,%r9d,%r13d + leal (%rax,%r8,1),%eax + andl %edi,%r15d + xorl %r12d,%r14d + xorl %r10d,%r15d + xorl %r13d,%r14d + leal (%r8,%r15,1),%r8d + movl %ebx,%r12d + addl 32(%rsp),%edx + andl %eax,%r12d + rorxl $25,%eax,%r13d + rorxl $11,%eax,%r15d + leal (%r8,%r14,1),%r8d + leal (%rdx,%r12,1),%edx + andnl %ecx,%eax,%r12d + xorl %r15d,%r13d + rorxl $6,%eax,%r14d + leal (%rdx,%r12,1),%edx + xorl %r14d,%r13d + movl %r8d,%r15d + rorxl $22,%r8d,%r12d + leal (%rdx,%r13,1),%edx + xorl %r9d,%r15d + rorxl $13,%r8d,%r14d + rorxl $2,%r8d,%r13d + leal (%r11,%rdx,1),%r11d + andl %r15d,%edi + xorl %r12d,%r14d + xorl %r9d,%edi + xorl %r13d,%r14d + leal (%rdx,%rdi,1),%edx + movl %eax,%r12d + addl 36(%rsp),%ecx + andl %r11d,%r12d + rorxl $25,%r11d,%r13d + rorxl $11,%r11d,%edi + leal (%rdx,%r14,1),%edx + leal (%rcx,%r12,1),%ecx + andnl %ebx,%r11d,%r12d + xorl %edi,%r13d + rorxl $6,%r11d,%r14d + leal (%rcx,%r12,1),%ecx + xorl %r14d,%r13d + movl %edx,%edi + rorxl $22,%edx,%r12d + leal (%rcx,%r13,1),%ecx + xorl %r8d,%edi + rorxl $13,%edx,%r14d + rorxl $2,%edx,%r13d + leal (%r10,%rcx,1),%r10d + andl %edi,%r15d + xorl %r12d,%r14d + xorl %r8d,%r15d + xorl %r13d,%r14d + leal (%rcx,%r15,1),%ecx + movl %r11d,%r12d + addl 40(%rsp),%ebx + andl %r10d,%r12d + rorxl $25,%r10d,%r13d + rorxl $11,%r10d,%r15d + leal (%rcx,%r14,1),%ecx + leal (%rbx,%r12,1),%ebx + andnl %eax,%r10d,%r12d + xorl %r15d,%r13d + rorxl $6,%r10d,%r14d + leal (%rbx,%r12,1),%ebx + xorl %r14d,%r13d + movl %ecx,%r15d + rorxl $22,%ecx,%r12d + leal (%rbx,%r13,1),%ebx + xorl %edx,%r15d + rorxl $13,%ecx,%r14d + rorxl $2,%ecx,%r13d + leal (%r9,%rbx,1),%r9d + andl %r15d,%edi + xorl %r12d,%r14d + xorl %edx,%edi + xorl %r13d,%r14d + leal (%rbx,%rdi,1),%ebx + movl %r10d,%r12d + addl 44(%rsp),%eax + andl %r9d,%r12d + rorxl $25,%r9d,%r13d + rorxl $11,%r9d,%edi + leal (%rbx,%r14,1),%ebx + leal (%rax,%r12,1),%eax + andnl %r11d,%r9d,%r12d + xorl %edi,%r13d + rorxl $6,%r9d,%r14d + leal (%rax,%r12,1),%eax + xorl %r14d,%r13d + movl %ebx,%edi + rorxl $22,%ebx,%r12d + leal (%rax,%r13,1),%eax + xorl %ecx,%edi + rorxl $13,%ebx,%r14d + rorxl $2,%ebx,%r13d + leal (%r8,%rax,1),%r8d + andl %edi,%r15d + xorl %r12d,%r14d + xorl %ecx,%r15d + xorl %r13d,%r14d + leal (%rax,%r15,1),%eax + movl %r9d,%r12d + movq 512(%rsp),%rdi + addl %r14d,%eax + + leaq 448(%rsp),%rbp + + addl 0(%rdi),%eax + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + addl 24(%rdi),%r10d + addl 28(%rdi),%r11d + + movl %eax,0(%rdi) + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + + cmpq 80(%rbp),%rsi + je .Ldone_avx2 + + xorl %r14d,%r14d + movl %ebx,%edi + xorl %ecx,%edi + movl %r9d,%r12d + jmp .Lower_avx2 +.align 16 +.Lower_avx2: + addl 0+16(%rbp),%r11d + andl %r8d,%r12d + rorxl $25,%r8d,%r13d + rorxl $11,%r8d,%r15d + leal (%rax,%r14,1),%eax + leal (%r11,%r12,1),%r11d + andnl %r10d,%r8d,%r12d + xorl %r15d,%r13d + rorxl $6,%r8d,%r14d + leal (%r11,%r12,1),%r11d + xorl %r14d,%r13d + movl %eax,%r15d + rorxl $22,%eax,%r12d + leal (%r11,%r13,1),%r11d + xorl %ebx,%r15d + rorxl $13,%eax,%r14d + rorxl $2,%eax,%r13d + leal (%rdx,%r11,1),%edx + andl %r15d,%edi + xorl %r12d,%r14d + xorl %ebx,%edi + xorl %r13d,%r14d + leal (%r11,%rdi,1),%r11d + movl %r8d,%r12d + addl 4+16(%rbp),%r10d + andl %edx,%r12d + rorxl $25,%edx,%r13d + rorxl $11,%edx,%edi + leal (%r11,%r14,1),%r11d + leal (%r10,%r12,1),%r10d + andnl %r9d,%edx,%r12d + xorl %edi,%r13d + rorxl $6,%edx,%r14d + leal (%r10,%r12,1),%r10d + xorl %r14d,%r13d + movl %r11d,%edi + rorxl $22,%r11d,%r12d + leal (%r10,%r13,1),%r10d + xorl %eax,%edi + rorxl $13,%r11d,%r14d + rorxl $2,%r11d,%r13d + leal (%rcx,%r10,1),%ecx + andl %edi,%r15d + xorl %r12d,%r14d + xorl %eax,%r15d + xorl %r13d,%r14d + leal (%r10,%r15,1),%r10d + movl %edx,%r12d + addl 8+16(%rbp),%r9d + andl %ecx,%r12d + rorxl $25,%ecx,%r13d + rorxl $11,%ecx,%r15d + leal (%r10,%r14,1),%r10d + leal (%r9,%r12,1),%r9d + andnl %r8d,%ecx,%r12d + xorl %r15d,%r13d + rorxl $6,%ecx,%r14d + leal (%r9,%r12,1),%r9d + xorl %r14d,%r13d + movl %r10d,%r15d + rorxl $22,%r10d,%r12d + leal (%r9,%r13,1),%r9d + xorl %r11d,%r15d + rorxl $13,%r10d,%r14d + rorxl $2,%r10d,%r13d + leal (%rbx,%r9,1),%ebx + andl %r15d,%edi + xorl %r12d,%r14d + xorl %r11d,%edi + xorl %r13d,%r14d + leal (%r9,%rdi,1),%r9d + movl %ecx,%r12d + addl 12+16(%rbp),%r8d + andl %ebx,%r12d + rorxl $25,%ebx,%r13d + rorxl $11,%ebx,%edi + leal (%r9,%r14,1),%r9d + leal (%r8,%r12,1),%r8d + andnl %edx,%ebx,%r12d + xorl %edi,%r13d + rorxl $6,%ebx,%r14d + leal (%r8,%r12,1),%r8d + xorl %r14d,%r13d + movl %r9d,%edi + rorxl $22,%r9d,%r12d + leal (%r8,%r13,1),%r8d + xorl %r10d,%edi + rorxl $13,%r9d,%r14d + rorxl $2,%r9d,%r13d + leal (%rax,%r8,1),%eax + andl %edi,%r15d + xorl %r12d,%r14d + xorl %r10d,%r15d + xorl %r13d,%r14d + leal (%r8,%r15,1),%r8d + movl %ebx,%r12d + addl 32+16(%rbp),%edx + andl %eax,%r12d + rorxl $25,%eax,%r13d + rorxl $11,%eax,%r15d + leal (%r8,%r14,1),%r8d + leal (%rdx,%r12,1),%edx + andnl %ecx,%eax,%r12d + xorl %r15d,%r13d + rorxl $6,%eax,%r14d + leal (%rdx,%r12,1),%edx + xorl %r14d,%r13d + movl %r8d,%r15d + rorxl $22,%r8d,%r12d + leal (%rdx,%r13,1),%edx + xorl %r9d,%r15d + rorxl $13,%r8d,%r14d + rorxl $2,%r8d,%r13d + leal (%r11,%rdx,1),%r11d + andl %r15d,%edi + xorl %r12d,%r14d + xorl %r9d,%edi + xorl %r13d,%r14d + leal (%rdx,%rdi,1),%edx + movl %eax,%r12d + addl 36+16(%rbp),%ecx + andl %r11d,%r12d + rorxl $25,%r11d,%r13d + rorxl $11,%r11d,%edi + leal (%rdx,%r14,1),%edx + leal (%rcx,%r12,1),%ecx + andnl %ebx,%r11d,%r12d + xorl %edi,%r13d + rorxl $6,%r11d,%r14d + leal (%rcx,%r12,1),%ecx + xorl %r14d,%r13d + movl %edx,%edi + rorxl $22,%edx,%r12d + leal (%rcx,%r13,1),%ecx + xorl %r8d,%edi + rorxl $13,%edx,%r14d + rorxl $2,%edx,%r13d + leal (%r10,%rcx,1),%r10d + andl %edi,%r15d + xorl %r12d,%r14d + xorl %r8d,%r15d + xorl %r13d,%r14d + leal (%rcx,%r15,1),%ecx + movl %r11d,%r12d + addl 40+16(%rbp),%ebx + andl %r10d,%r12d + rorxl $25,%r10d,%r13d + rorxl $11,%r10d,%r15d + leal (%rcx,%r14,1),%ecx + leal (%rbx,%r12,1),%ebx + andnl %eax,%r10d,%r12d + xorl %r15d,%r13d + rorxl $6,%r10d,%r14d + leal (%rbx,%r12,1),%ebx + xorl %r14d,%r13d + movl %ecx,%r15d + rorxl $22,%ecx,%r12d + leal (%rbx,%r13,1),%ebx + xorl %edx,%r15d + rorxl $13,%ecx,%r14d + rorxl $2,%ecx,%r13d + leal (%r9,%rbx,1),%r9d + andl %r15d,%edi + xorl %r12d,%r14d + xorl %edx,%edi + xorl %r13d,%r14d + leal (%rbx,%rdi,1),%ebx + movl %r10d,%r12d + addl 44+16(%rbp),%eax + andl %r9d,%r12d + rorxl $25,%r9d,%r13d + rorxl $11,%r9d,%edi + leal (%rbx,%r14,1),%ebx + leal (%rax,%r12,1),%eax + andnl %r11d,%r9d,%r12d + xorl %edi,%r13d + rorxl $6,%r9d,%r14d + leal (%rax,%r12,1),%eax + xorl %r14d,%r13d + movl %ebx,%edi + rorxl $22,%ebx,%r12d + leal (%rax,%r13,1),%eax + xorl %ecx,%edi + rorxl $13,%ebx,%r14d + rorxl $2,%ebx,%r13d + leal (%r8,%rax,1),%r8d + andl %edi,%r15d + xorl %r12d,%r14d + xorl %ecx,%r15d + xorl %r13d,%r14d + leal (%rax,%r15,1),%eax + movl %r9d,%r12d + leaq -64(%rbp),%rbp + cmpq %rsp,%rbp + jae .Lower_avx2 + + movq 512(%rsp),%rdi + addl %r14d,%eax + + leaq 448(%rsp),%rsp + +.cfi_escape 0x0f,0x06,0x77,0xd8,0x00,0x06,0x23,0x08 + + addl 0(%rdi),%eax + addl 4(%rdi),%ebx + addl 8(%rdi),%ecx + addl 12(%rdi),%edx + addl 16(%rdi),%r8d + addl 20(%rdi),%r9d + leaq 128(%rsi),%rsi + addl 24(%rdi),%r10d + movq %rsi,%r12 + addl 28(%rdi),%r11d + cmpq 64+16(%rsp),%rsi + + movl %eax,0(%rdi) + cmoveq %rsp,%r12 + movl %ebx,4(%rdi) + movl %ecx,8(%rdi) + movl %edx,12(%rdi) + movl %r8d,16(%rdi) + movl %r9d,20(%rdi) + movl %r10d,24(%rdi) + movl %r11d,28(%rdi) + + jbe .Loop_avx2 + leaq (%rsp),%rbp + + +.cfi_escape 0x0f,0x06,0x76,0xd8,0x00,0x06,0x23,0x08 + +.Ldone_avx2: + movq 88(%rbp),%rsi +.cfi_def_cfa %rsi,8 + vzeroupper + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx2: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_block_data_order_avx2,.-sha256_block_data_order_avx2 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/sha/sha256.c b/crypto/openssl/crypto/sha/sha256.c index 11050ba54714..5845c389379e 100644 --- a/crypto/openssl/crypto/sha/sha256.c +++ b/crypto/openssl/crypto/sha/sha256.c @@ -1,12 +1,18 @@ /* - * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * SHA256 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include @@ -15,6 +21,7 @@ #include #include #include +#include "internal/endian.h" int SHA224_Init(SHA256_CTX *c) { @@ -46,34 +53,6 @@ int SHA256_Init(SHA256_CTX *c) return 1; } -unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md) -{ - SHA256_CTX c; - static unsigned char m[SHA224_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - SHA224_Init(&c); - SHA256_Update(&c, d, n); - SHA256_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); - return md; -} - -unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) -{ - SHA256_CTX c; - static unsigned char m[SHA256_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - SHA256_Init(&c); - SHA256_Update(&c, d, n); - SHA256_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); - return md; -} - int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) { return SHA256_Update(c, data, len); @@ -250,12 +229,7 @@ static void sha256_block_data_order(SHA256_CTX *ctx, const void *in, SHA_LONG X[16]; int i; const unsigned char *data = in; - const union { - long one; - char little; - } is_endian = { - 1 - }; + DECLARE_IS_ENDIAN; while (num--) { @@ -268,7 +242,7 @@ static void sha256_block_data_order(SHA256_CTX *ctx, const void *in, g = ctx->h[6]; h = ctx->h[7]; - if (!is_endian.little && sizeof(SHA_LONG) == 4 + if (!IS_LITTLE_ENDIAN && sizeof(SHA_LONG) == 4 && ((size_t)in % 4) == 0) { const SHA_LONG *W = (const SHA_LONG *)data; diff --git a/crypto/openssl/crypto/sha/sha3.c b/crypto/openssl/crypto/sha/sha3.c new file mode 100644 index 000000000000..633bc2e1208b --- /dev/null +++ b/crypto/openssl/crypto/sha/sha3.c @@ -0,0 +1,109 @@ +/* + * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/sha3.h" + +void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r); + +void ossl_sha3_reset(KECCAK1600_CTX *ctx) +{ + memset(ctx->A, 0, sizeof(ctx->A)); + ctx->bufsz = 0; +} + +int ossl_sha3_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen) +{ + size_t bsz = SHA3_BLOCKSIZE(bitlen); + + if (bsz <= sizeof(ctx->buf)) { + ossl_sha3_reset(ctx); + ctx->block_size = bsz; + ctx->md_size = bitlen / 8; + ctx->pad = pad; + return 1; + } + + return 0; +} + +int ossl_keccak_kmac_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen) +{ + int ret = ossl_sha3_init(ctx, pad, bitlen); + + if (ret) + ctx->md_size *= 2; + return ret; +} + +int ossl_sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len) +{ + const unsigned char *inp = _inp; + size_t bsz = ctx->block_size; + size_t num, rem; + + if (len == 0) + return 1; + + if ((num = ctx->bufsz) != 0) { /* process intermediate buffer? */ + rem = bsz - num; + + if (len < rem) { + memcpy(ctx->buf + num, inp, len); + ctx->bufsz += len; + return 1; + } + /* + * We have enough data to fill or overflow the intermediate + * buffer. So we append |rem| bytes and process the block, + * leaving the rest for later processing... + */ + memcpy(ctx->buf + num, inp, rem); + inp += rem, len -= rem; + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz); + ctx->bufsz = 0; + /* ctx->buf is processed, ctx->num is guaranteed to be zero */ + } + + if (len >= bsz) + rem = SHA3_absorb(ctx->A, inp, len, bsz); + else + rem = len; + + if (rem) { + memcpy(ctx->buf, inp + len - rem, rem); + ctx->bufsz = rem; + } + + return 1; +} + +int ossl_sha3_final(unsigned char *md, KECCAK1600_CTX *ctx) +{ + size_t bsz = ctx->block_size; + size_t num = ctx->bufsz; + + if (ctx->md_size == 0) + return 1; + + /* + * Pad the data with 10*1. Note that |num| can be |bsz - 1| + * in which case both byte operations below are performed on + * same byte... + */ + memset(ctx->buf + num, 0, bsz - num); + ctx->buf[num] = ctx->pad; + ctx->buf[bsz - 1] |= 0x80; + + (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz); + + SHA3_squeeze(ctx->A, md, ctx->md_size, bsz); + + return 1; +} diff --git a/crypto/openssl/crypto/sha/sha512-586.S b/crypto/openssl/crypto/sha/sha512-586.S new file mode 100644 index 000000000000..99d198dd91dc --- /dev/null +++ b/crypto/openssl/crypto/sha/sha512-586.S @@ -0,0 +1,2850 @@ +.text +.globl sha512_block_data_order +.type sha512_block_data_order,@function +.align 16 +sha512_block_data_order: +.L_sha512_block_data_order_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%eax + movl %esp,%ebx + call .L000pic_point +.L000pic_point: + popl %ebp + leal .L001K512-.L000pic_point(%ebp),%ebp + subl $16,%esp + andl $-64,%esp + shll $7,%eax + addl %edi,%eax + movl %esi,(%esp) + movl %edi,4(%esp) + movl %eax,8(%esp) + movl %ebx,12(%esp) + leal OPENSSL_ia32cap_P-.L001K512(%ebp),%edx + movl (%edx),%ecx + testl $67108864,%ecx + jz .L002loop_x86 + movl 4(%edx),%edx + movq (%esi),%mm0 + andl $16777216,%ecx + movq 8(%esi),%mm1 + andl $512,%edx + movq 16(%esi),%mm2 + orl %edx,%ecx + movq 24(%esi),%mm3 + movq 32(%esi),%mm4 + movq 40(%esi),%mm5 + movq 48(%esi),%mm6 + movq 56(%esi),%mm7 + cmpl $16777728,%ecx + je .L003SSSE3 + subl $80,%esp + jmp .L004loop_sse2 +.align 16 +.L004loop_sse2: + movq %mm1,8(%esp) + movq %mm2,16(%esp) + movq %mm3,24(%esp) + movq %mm5,40(%esp) + movq %mm6,48(%esp) + pxor %mm1,%mm2 + movq %mm7,56(%esp) + movq %mm0,%mm3 + movl (%edi),%eax + movl 4(%edi),%ebx + addl $8,%edi + movl $15,%edx + bswap %eax + bswap %ebx + jmp .L00500_14_sse2 +.align 16 +.L00500_14_sse2: + movd %eax,%mm1 + movl (%edi),%eax + movd %ebx,%mm7 + movl 4(%edi),%ebx + addl $8,%edi + bswap %eax + bswap %ebx + punpckldq %mm1,%mm7 + movq %mm4,%mm1 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + movq %mm3,%mm0 + movq %mm7,72(%esp) + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + paddq (%ebp),%mm7 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + subl $8,%esp + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 40(%esp),%mm5 + paddq %mm2,%mm3 + movq %mm0,%mm2 + addl $8,%ebp + paddq %mm6,%mm3 + movq 48(%esp),%mm6 + decl %edx + jnz .L00500_14_sse2 + movd %eax,%mm1 + movd %ebx,%mm7 + punpckldq %mm1,%mm7 + movq %mm4,%mm1 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + movq %mm3,%mm0 + movq %mm7,72(%esp) + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + paddq (%ebp),%mm7 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + subl $8,%esp + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 192(%esp),%mm7 + paddq %mm2,%mm3 + movq %mm0,%mm2 + addl $8,%ebp + paddq %mm6,%mm3 + pxor %mm0,%mm0 + movl $32,%edx + jmp .L00616_79_sse2 +.align 16 +.L00616_79_sse2: + movq 88(%esp),%mm5 + movq %mm7,%mm1 + psrlq $1,%mm7 + movq %mm5,%mm6 + psrlq $6,%mm5 + psllq $56,%mm1 + paddq %mm3,%mm0 + movq %mm7,%mm3 + psrlq $6,%mm7 + pxor %mm1,%mm3 + psllq $7,%mm1 + pxor %mm7,%mm3 + psrlq $1,%mm7 + pxor %mm1,%mm3 + movq %mm5,%mm1 + psrlq $13,%mm5 + pxor %mm3,%mm7 + psllq $3,%mm6 + pxor %mm5,%mm1 + paddq 200(%esp),%mm7 + pxor %mm6,%mm1 + psrlq $42,%mm5 + paddq 128(%esp),%mm7 + pxor %mm5,%mm1 + psllq $42,%mm6 + movq 40(%esp),%mm5 + pxor %mm6,%mm1 + movq 48(%esp),%mm6 + paddq %mm1,%mm7 + movq %mm4,%mm1 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + movq %mm7,72(%esp) + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + paddq (%ebp),%mm7 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + subl $8,%esp + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 192(%esp),%mm7 + paddq %mm6,%mm2 + addl $8,%ebp + movq 88(%esp),%mm5 + movq %mm7,%mm1 + psrlq $1,%mm7 + movq %mm5,%mm6 + psrlq $6,%mm5 + psllq $56,%mm1 + paddq %mm3,%mm2 + movq %mm7,%mm3 + psrlq $6,%mm7 + pxor %mm1,%mm3 + psllq $7,%mm1 + pxor %mm7,%mm3 + psrlq $1,%mm7 + pxor %mm1,%mm3 + movq %mm5,%mm1 + psrlq $13,%mm5 + pxor %mm3,%mm7 + psllq $3,%mm6 + pxor %mm5,%mm1 + paddq 200(%esp),%mm7 + pxor %mm6,%mm1 + psrlq $42,%mm5 + paddq 128(%esp),%mm7 + pxor %mm5,%mm1 + psllq $42,%mm6 + movq 40(%esp),%mm5 + pxor %mm6,%mm1 + movq 48(%esp),%mm6 + paddq %mm1,%mm7 + movq %mm4,%mm1 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + movq %mm7,72(%esp) + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + paddq (%ebp),%mm7 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + subl $8,%esp + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 192(%esp),%mm7 + paddq %mm6,%mm0 + addl $8,%ebp + decl %edx + jnz .L00616_79_sse2 + paddq %mm3,%mm0 + movq 8(%esp),%mm1 + movq 24(%esp),%mm3 + movq 40(%esp),%mm5 + movq 48(%esp),%mm6 + movq 56(%esp),%mm7 + pxor %mm1,%mm2 + paddq (%esi),%mm0 + paddq 8(%esi),%mm1 + paddq 16(%esi),%mm2 + paddq 24(%esi),%mm3 + paddq 32(%esi),%mm4 + paddq 40(%esi),%mm5 + paddq 48(%esi),%mm6 + paddq 56(%esi),%mm7 + movl $640,%eax + movq %mm0,(%esi) + movq %mm1,8(%esi) + movq %mm2,16(%esi) + movq %mm3,24(%esi) + movq %mm4,32(%esi) + movq %mm5,40(%esi) + movq %mm6,48(%esi) + movq %mm7,56(%esi) + leal (%esp,%eax,1),%esp + subl %eax,%ebp + cmpl 88(%esp),%edi + jb .L004loop_sse2 + movl 92(%esp),%esp + emms + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 32 +.L003SSSE3: + leal -64(%esp),%edx + subl $256,%esp + movdqa 640(%ebp),%xmm1 + movdqu (%edi),%xmm0 +.byte 102,15,56,0,193 + movdqa (%ebp),%xmm3 + movdqa %xmm1,%xmm2 + movdqu 16(%edi),%xmm1 + paddq %xmm0,%xmm3 +.byte 102,15,56,0,202 + movdqa %xmm3,-128(%edx) + movdqa 16(%ebp),%xmm4 + movdqa %xmm2,%xmm3 + movdqu 32(%edi),%xmm2 + paddq %xmm1,%xmm4 +.byte 102,15,56,0,211 + movdqa %xmm4,-112(%edx) + movdqa 32(%ebp),%xmm5 + movdqa %xmm3,%xmm4 + movdqu 48(%edi),%xmm3 + paddq %xmm2,%xmm5 +.byte 102,15,56,0,220 + movdqa %xmm5,-96(%edx) + movdqa 48(%ebp),%xmm6 + movdqa %xmm4,%xmm5 + movdqu 64(%edi),%xmm4 + paddq %xmm3,%xmm6 +.byte 102,15,56,0,229 + movdqa %xmm6,-80(%edx) + movdqa 64(%ebp),%xmm7 + movdqa %xmm5,%xmm6 + movdqu 80(%edi),%xmm5 + paddq %xmm4,%xmm7 +.byte 102,15,56,0,238 + movdqa %xmm7,-64(%edx) + movdqa %xmm0,(%edx) + movdqa 80(%ebp),%xmm0 + movdqa %xmm6,%xmm7 + movdqu 96(%edi),%xmm6 + paddq %xmm5,%xmm0 +.byte 102,15,56,0,247 + movdqa %xmm0,-48(%edx) + movdqa %xmm1,16(%edx) + movdqa 96(%ebp),%xmm1 + movdqa %xmm7,%xmm0 + movdqu 112(%edi),%xmm7 + paddq %xmm6,%xmm1 +.byte 102,15,56,0,248 + movdqa %xmm1,-32(%edx) + movdqa %xmm2,32(%edx) + movdqa 112(%ebp),%xmm2 + movdqa (%edx),%xmm0 + paddq %xmm7,%xmm2 + movdqa %xmm2,-16(%edx) + nop +.align 32 +.L007loop_ssse3: + movdqa 16(%edx),%xmm2 + movdqa %xmm3,48(%edx) + leal 128(%ebp),%ebp + movq %mm1,8(%esp) + movl %edi,%ebx + movq %mm2,16(%esp) + leal 128(%edi),%edi + movq %mm3,24(%esp) + cmpl %eax,%edi + movq %mm5,40(%esp) + cmovbl %edi,%ebx + movq %mm6,48(%esp) + movl $4,%ecx + pxor %mm1,%mm2 + movq %mm7,56(%esp) + pxor %mm3,%mm3 + jmp .L00800_47_ssse3 +.align 32 +.L00800_47_ssse3: + movdqa %xmm5,%xmm3 + movdqa %xmm2,%xmm1 +.byte 102,15,58,15,208,8 + movdqa %xmm4,(%edx) +.byte 102,15,58,15,220,8 + movdqa %xmm2,%xmm4 + psrlq $7,%xmm2 + paddq %xmm3,%xmm0 + movdqa %xmm4,%xmm3 + psrlq $1,%xmm4 + psllq $56,%xmm3 + pxor %xmm4,%xmm2 + psrlq $7,%xmm4 + pxor %xmm3,%xmm2 + psllq $7,%xmm3 + pxor %xmm4,%xmm2 + movdqa %xmm7,%xmm4 + pxor %xmm3,%xmm2 + movdqa %xmm7,%xmm3 + psrlq $6,%xmm4 + paddq %xmm2,%xmm0 + movdqa %xmm7,%xmm2 + psrlq $19,%xmm3 + psllq $3,%xmm2 + pxor %xmm3,%xmm4 + psrlq $42,%xmm3 + pxor %xmm2,%xmm4 + psllq $42,%xmm2 + pxor %xmm3,%xmm4 + movdqa 32(%edx),%xmm3 + pxor %xmm2,%xmm4 + movdqa (%ebp),%xmm2 + movq %mm4,%mm1 + paddq %xmm4,%xmm0 + movq -128(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + paddq %xmm0,%xmm2 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 32(%esp),%mm5 + paddq %mm6,%mm2 + movq 40(%esp),%mm6 + movq %mm4,%mm1 + movq -120(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,24(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,56(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 48(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 16(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq (%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 24(%esp),%mm5 + paddq %mm6,%mm0 + movq 32(%esp),%mm6 + movdqa %xmm2,-128(%edx) + movdqa %xmm6,%xmm4 + movdqa %xmm3,%xmm2 +.byte 102,15,58,15,217,8 + movdqa %xmm5,16(%edx) +.byte 102,15,58,15,229,8 + movdqa %xmm3,%xmm5 + psrlq $7,%xmm3 + paddq %xmm4,%xmm1 + movdqa %xmm5,%xmm4 + psrlq $1,%xmm5 + psllq $56,%xmm4 + pxor %xmm5,%xmm3 + psrlq $7,%xmm5 + pxor %xmm4,%xmm3 + psllq $7,%xmm4 + pxor %xmm5,%xmm3 + movdqa %xmm0,%xmm5 + pxor %xmm4,%xmm3 + movdqa %xmm0,%xmm4 + psrlq $6,%xmm5 + paddq %xmm3,%xmm1 + movdqa %xmm0,%xmm3 + psrlq $19,%xmm4 + psllq $3,%xmm3 + pxor %xmm4,%xmm5 + psrlq $42,%xmm4 + pxor %xmm3,%xmm5 + psllq $42,%xmm3 + pxor %xmm4,%xmm5 + movdqa 48(%edx),%xmm4 + pxor %xmm3,%xmm5 + movdqa 16(%ebp),%xmm3 + movq %mm4,%mm1 + paddq %xmm5,%xmm1 + movq -112(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,16(%esp) + paddq %xmm1,%xmm3 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,48(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 40(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 8(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 56(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 16(%esp),%mm5 + paddq %mm6,%mm2 + movq 24(%esp),%mm6 + movq %mm4,%mm1 + movq -104(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,8(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,40(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 32(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq (%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 48(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 8(%esp),%mm5 + paddq %mm6,%mm0 + movq 16(%esp),%mm6 + movdqa %xmm3,-112(%edx) + movdqa %xmm7,%xmm5 + movdqa %xmm4,%xmm3 +.byte 102,15,58,15,226,8 + movdqa %xmm6,32(%edx) +.byte 102,15,58,15,238,8 + movdqa %xmm4,%xmm6 + psrlq $7,%xmm4 + paddq %xmm5,%xmm2 + movdqa %xmm6,%xmm5 + psrlq $1,%xmm6 + psllq $56,%xmm5 + pxor %xmm6,%xmm4 + psrlq $7,%xmm6 + pxor %xmm5,%xmm4 + psllq $7,%xmm5 + pxor %xmm6,%xmm4 + movdqa %xmm1,%xmm6 + pxor %xmm5,%xmm4 + movdqa %xmm1,%xmm5 + psrlq $6,%xmm6 + paddq %xmm4,%xmm2 + movdqa %xmm1,%xmm4 + psrlq $19,%xmm5 + psllq $3,%xmm4 + pxor %xmm5,%xmm6 + psrlq $42,%xmm5 + pxor %xmm4,%xmm6 + psllq $42,%xmm4 + pxor %xmm5,%xmm6 + movdqa (%edx),%xmm5 + pxor %xmm4,%xmm6 + movdqa 32(%ebp),%xmm4 + movq %mm4,%mm1 + paddq %xmm6,%xmm2 + movq -96(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,(%esp) + paddq %xmm2,%xmm4 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,32(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 24(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 56(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 40(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq (%esp),%mm5 + paddq %mm6,%mm2 + movq 8(%esp),%mm6 + movq %mm4,%mm1 + movq -88(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,56(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,24(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 16(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 48(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 32(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 56(%esp),%mm5 + paddq %mm6,%mm0 + movq (%esp),%mm6 + movdqa %xmm4,-96(%edx) + movdqa %xmm0,%xmm6 + movdqa %xmm5,%xmm4 +.byte 102,15,58,15,235,8 + movdqa %xmm7,48(%edx) +.byte 102,15,58,15,247,8 + movdqa %xmm5,%xmm7 + psrlq $7,%xmm5 + paddq %xmm6,%xmm3 + movdqa %xmm7,%xmm6 + psrlq $1,%xmm7 + psllq $56,%xmm6 + pxor %xmm7,%xmm5 + psrlq $7,%xmm7 + pxor %xmm6,%xmm5 + psllq $7,%xmm6 + pxor %xmm7,%xmm5 + movdqa %xmm2,%xmm7 + pxor %xmm6,%xmm5 + movdqa %xmm2,%xmm6 + psrlq $6,%xmm7 + paddq %xmm5,%xmm3 + movdqa %xmm2,%xmm5 + psrlq $19,%xmm6 + psllq $3,%xmm5 + pxor %xmm6,%xmm7 + psrlq $42,%xmm6 + pxor %xmm5,%xmm7 + psllq $42,%xmm5 + pxor %xmm6,%xmm7 + movdqa 16(%edx),%xmm6 + pxor %xmm5,%xmm7 + movdqa 48(%ebp),%xmm5 + movq %mm4,%mm1 + paddq %xmm7,%xmm3 + movq -80(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,48(%esp) + paddq %xmm3,%xmm5 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,16(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 8(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 40(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 24(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 48(%esp),%mm5 + paddq %mm6,%mm2 + movq 56(%esp),%mm6 + movq %mm4,%mm1 + movq -72(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,40(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,8(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq (%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 32(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 16(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 40(%esp),%mm5 + paddq %mm6,%mm0 + movq 48(%esp),%mm6 + movdqa %xmm5,-80(%edx) + movdqa %xmm1,%xmm7 + movdqa %xmm6,%xmm5 +.byte 102,15,58,15,244,8 + movdqa %xmm0,(%edx) +.byte 102,15,58,15,248,8 + movdqa %xmm6,%xmm0 + psrlq $7,%xmm6 + paddq %xmm7,%xmm4 + movdqa %xmm0,%xmm7 + psrlq $1,%xmm0 + psllq $56,%xmm7 + pxor %xmm0,%xmm6 + psrlq $7,%xmm0 + pxor %xmm7,%xmm6 + psllq $7,%xmm7 + pxor %xmm0,%xmm6 + movdqa %xmm3,%xmm0 + pxor %xmm7,%xmm6 + movdqa %xmm3,%xmm7 + psrlq $6,%xmm0 + paddq %xmm6,%xmm4 + movdqa %xmm3,%xmm6 + psrlq $19,%xmm7 + psllq $3,%xmm6 + pxor %xmm7,%xmm0 + psrlq $42,%xmm7 + pxor %xmm6,%xmm0 + psllq $42,%xmm6 + pxor %xmm7,%xmm0 + movdqa 32(%edx),%xmm7 + pxor %xmm6,%xmm0 + movdqa 64(%ebp),%xmm6 + movq %mm4,%mm1 + paddq %xmm0,%xmm4 + movq -64(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + paddq %xmm4,%xmm6 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 32(%esp),%mm5 + paddq %mm6,%mm2 + movq 40(%esp),%mm6 + movq %mm4,%mm1 + movq -56(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,24(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,56(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 48(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 16(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq (%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 24(%esp),%mm5 + paddq %mm6,%mm0 + movq 32(%esp),%mm6 + movdqa %xmm6,-64(%edx) + movdqa %xmm2,%xmm0 + movdqa %xmm7,%xmm6 +.byte 102,15,58,15,253,8 + movdqa %xmm1,16(%edx) +.byte 102,15,58,15,193,8 + movdqa %xmm7,%xmm1 + psrlq $7,%xmm7 + paddq %xmm0,%xmm5 + movdqa %xmm1,%xmm0 + psrlq $1,%xmm1 + psllq $56,%xmm0 + pxor %xmm1,%xmm7 + psrlq $7,%xmm1 + pxor %xmm0,%xmm7 + psllq $7,%xmm0 + pxor %xmm1,%xmm7 + movdqa %xmm4,%xmm1 + pxor %xmm0,%xmm7 + movdqa %xmm4,%xmm0 + psrlq $6,%xmm1 + paddq %xmm7,%xmm5 + movdqa %xmm4,%xmm7 + psrlq $19,%xmm0 + psllq $3,%xmm7 + pxor %xmm0,%xmm1 + psrlq $42,%xmm0 + pxor %xmm7,%xmm1 + psllq $42,%xmm7 + pxor %xmm0,%xmm1 + movdqa 48(%edx),%xmm0 + pxor %xmm7,%xmm1 + movdqa 80(%ebp),%xmm7 + movq %mm4,%mm1 + paddq %xmm1,%xmm5 + movq -48(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,16(%esp) + paddq %xmm5,%xmm7 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,48(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 40(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 8(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 56(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 16(%esp),%mm5 + paddq %mm6,%mm2 + movq 24(%esp),%mm6 + movq %mm4,%mm1 + movq -40(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,8(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,40(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 32(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq (%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 48(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 8(%esp),%mm5 + paddq %mm6,%mm0 + movq 16(%esp),%mm6 + movdqa %xmm7,-48(%edx) + movdqa %xmm3,%xmm1 + movdqa %xmm0,%xmm7 +.byte 102,15,58,15,198,8 + movdqa %xmm2,32(%edx) +.byte 102,15,58,15,202,8 + movdqa %xmm0,%xmm2 + psrlq $7,%xmm0 + paddq %xmm1,%xmm6 + movdqa %xmm2,%xmm1 + psrlq $1,%xmm2 + psllq $56,%xmm1 + pxor %xmm2,%xmm0 + psrlq $7,%xmm2 + pxor %xmm1,%xmm0 + psllq $7,%xmm1 + pxor %xmm2,%xmm0 + movdqa %xmm5,%xmm2 + pxor %xmm1,%xmm0 + movdqa %xmm5,%xmm1 + psrlq $6,%xmm2 + paddq %xmm0,%xmm6 + movdqa %xmm5,%xmm0 + psrlq $19,%xmm1 + psllq $3,%xmm0 + pxor %xmm1,%xmm2 + psrlq $42,%xmm1 + pxor %xmm0,%xmm2 + psllq $42,%xmm0 + pxor %xmm1,%xmm2 + movdqa (%edx),%xmm1 + pxor %xmm0,%xmm2 + movdqa 96(%ebp),%xmm0 + movq %mm4,%mm1 + paddq %xmm2,%xmm6 + movq -32(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,(%esp) + paddq %xmm6,%xmm0 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,32(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 24(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 56(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 40(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq (%esp),%mm5 + paddq %mm6,%mm2 + movq 8(%esp),%mm6 + movq %mm4,%mm1 + movq -24(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,56(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,24(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 16(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 48(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 32(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 56(%esp),%mm5 + paddq %mm6,%mm0 + movq (%esp),%mm6 + movdqa %xmm0,-32(%edx) + movdqa %xmm4,%xmm2 + movdqa %xmm1,%xmm0 +.byte 102,15,58,15,207,8 + movdqa %xmm3,48(%edx) +.byte 102,15,58,15,211,8 + movdqa %xmm1,%xmm3 + psrlq $7,%xmm1 + paddq %xmm2,%xmm7 + movdqa %xmm3,%xmm2 + psrlq $1,%xmm3 + psllq $56,%xmm2 + pxor %xmm3,%xmm1 + psrlq $7,%xmm3 + pxor %xmm2,%xmm1 + psllq $7,%xmm2 + pxor %xmm3,%xmm1 + movdqa %xmm6,%xmm3 + pxor %xmm2,%xmm1 + movdqa %xmm6,%xmm2 + psrlq $6,%xmm3 + paddq %xmm1,%xmm7 + movdqa %xmm6,%xmm1 + psrlq $19,%xmm2 + psllq $3,%xmm1 + pxor %xmm2,%xmm3 + psrlq $42,%xmm2 + pxor %xmm1,%xmm3 + psllq $42,%xmm1 + pxor %xmm2,%xmm3 + movdqa 16(%edx),%xmm2 + pxor %xmm1,%xmm3 + movdqa 112(%ebp),%xmm1 + movq %mm4,%mm1 + paddq %xmm3,%xmm7 + movq -16(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,48(%esp) + paddq %xmm7,%xmm1 + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,16(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 8(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 40(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 24(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 48(%esp),%mm5 + paddq %mm6,%mm2 + movq 56(%esp),%mm6 + movq %mm4,%mm1 + movq -8(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,40(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,8(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq (%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 32(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 16(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 40(%esp),%mm5 + paddq %mm6,%mm0 + movq 48(%esp),%mm6 + movdqa %xmm1,-16(%edx) + leal 128(%ebp),%ebp + decl %ecx + jnz .L00800_47_ssse3 + movdqa (%ebp),%xmm1 + leal -640(%ebp),%ebp + movdqu (%ebx),%xmm0 +.byte 102,15,56,0,193 + movdqa (%ebp),%xmm3 + movdqa %xmm1,%xmm2 + movdqu 16(%ebx),%xmm1 + paddq %xmm0,%xmm3 +.byte 102,15,56,0,202 + movq %mm4,%mm1 + movq -128(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 32(%esp),%mm5 + paddq %mm6,%mm2 + movq 40(%esp),%mm6 + movq %mm4,%mm1 + movq -120(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,24(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,56(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 48(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 16(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq (%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 24(%esp),%mm5 + paddq %mm6,%mm0 + movq 32(%esp),%mm6 + movdqa %xmm3,-128(%edx) + movdqa 16(%ebp),%xmm4 + movdqa %xmm2,%xmm3 + movdqu 32(%ebx),%xmm2 + paddq %xmm1,%xmm4 +.byte 102,15,56,0,211 + movq %mm4,%mm1 + movq -112(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,16(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,48(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 40(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 8(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 56(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 16(%esp),%mm5 + paddq %mm6,%mm2 + movq 24(%esp),%mm6 + movq %mm4,%mm1 + movq -104(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,8(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,40(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 32(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq (%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 48(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 8(%esp),%mm5 + paddq %mm6,%mm0 + movq 16(%esp),%mm6 + movdqa %xmm4,-112(%edx) + movdqa 32(%ebp),%xmm5 + movdqa %xmm3,%xmm4 + movdqu 48(%ebx),%xmm3 + paddq %xmm2,%xmm5 +.byte 102,15,56,0,220 + movq %mm4,%mm1 + movq -96(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,32(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 24(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 56(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 40(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq (%esp),%mm5 + paddq %mm6,%mm2 + movq 8(%esp),%mm6 + movq %mm4,%mm1 + movq -88(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,56(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,24(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 16(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 48(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 32(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 56(%esp),%mm5 + paddq %mm6,%mm0 + movq (%esp),%mm6 + movdqa %xmm5,-96(%edx) + movdqa 48(%ebp),%xmm6 + movdqa %xmm4,%xmm5 + movdqu 64(%ebx),%xmm4 + paddq %xmm3,%xmm6 +.byte 102,15,56,0,229 + movq %mm4,%mm1 + movq -80(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,48(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,16(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 8(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 40(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 24(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 48(%esp),%mm5 + paddq %mm6,%mm2 + movq 56(%esp),%mm6 + movq %mm4,%mm1 + movq -72(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,40(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,8(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq (%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 32(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 16(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 40(%esp),%mm5 + paddq %mm6,%mm0 + movq 48(%esp),%mm6 + movdqa %xmm6,-80(%edx) + movdqa 64(%ebp),%xmm7 + movdqa %xmm5,%xmm6 + movdqu 80(%ebx),%xmm5 + paddq %xmm4,%xmm7 +.byte 102,15,56,0,238 + movq %mm4,%mm1 + movq -64(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,32(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 56(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 24(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 8(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 32(%esp),%mm5 + paddq %mm6,%mm2 + movq 40(%esp),%mm6 + movq %mm4,%mm1 + movq -56(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,24(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,56(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 48(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 16(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq (%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 24(%esp),%mm5 + paddq %mm6,%mm0 + movq 32(%esp),%mm6 + movdqa %xmm7,-64(%edx) + movdqa %xmm0,(%edx) + movdqa 80(%ebp),%xmm0 + movdqa %xmm6,%xmm7 + movdqu 96(%ebx),%xmm6 + paddq %xmm5,%xmm0 +.byte 102,15,56,0,247 + movq %mm4,%mm1 + movq -48(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,16(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,48(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 40(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 8(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 56(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 16(%esp),%mm5 + paddq %mm6,%mm2 + movq 24(%esp),%mm6 + movq %mm4,%mm1 + movq -40(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,8(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,40(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 32(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq (%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 48(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 8(%esp),%mm5 + paddq %mm6,%mm0 + movq 16(%esp),%mm6 + movdqa %xmm0,-48(%edx) + movdqa %xmm1,16(%edx) + movdqa 96(%ebp),%xmm1 + movdqa %xmm7,%xmm0 + movdqu 112(%ebx),%xmm7 + paddq %xmm6,%xmm1 +.byte 102,15,56,0,248 + movq %mm4,%mm1 + movq -32(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,32(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 24(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 56(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 40(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq (%esp),%mm5 + paddq %mm6,%mm2 + movq 8(%esp),%mm6 + movq %mm4,%mm1 + movq -24(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,56(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,24(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 16(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 48(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 32(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 56(%esp),%mm5 + paddq %mm6,%mm0 + movq (%esp),%mm6 + movdqa %xmm1,-32(%edx) + movdqa %xmm2,32(%edx) + movdqa 112(%ebp),%xmm2 + movdqa (%edx),%xmm0 + paddq %xmm7,%xmm2 + movq %mm4,%mm1 + movq -16(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,48(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm0 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm0,16(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq 8(%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 40(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm0,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm0,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 24(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm0,%mm2 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + pxor %mm7,%mm6 + movq 48(%esp),%mm5 + paddq %mm6,%mm2 + movq 56(%esp),%mm6 + movq %mm4,%mm1 + movq -8(%edx),%mm7 + pxor %mm6,%mm5 + psrlq $14,%mm1 + movq %mm4,40(%esp) + pand %mm4,%mm5 + psllq $23,%mm4 + paddq %mm3,%mm2 + movq %mm1,%mm3 + psrlq $4,%mm1 + pxor %mm6,%mm5 + pxor %mm4,%mm3 + psllq $23,%mm4 + pxor %mm1,%mm3 + movq %mm2,8(%esp) + paddq %mm5,%mm7 + pxor %mm4,%mm3 + psrlq $23,%mm1 + paddq (%esp),%mm7 + pxor %mm1,%mm3 + psllq $4,%mm4 + pxor %mm4,%mm3 + movq 32(%esp),%mm4 + paddq %mm7,%mm3 + movq %mm2,%mm5 + psrlq $28,%mm5 + paddq %mm3,%mm4 + movq %mm2,%mm6 + movq %mm5,%mm7 + psllq $25,%mm6 + movq 16(%esp),%mm1 + psrlq $6,%mm5 + pxor %mm6,%mm7 + psllq $5,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm2 + psrlq $5,%mm5 + pxor %mm6,%mm7 + pand %mm2,%mm0 + psllq $6,%mm6 + pxor %mm5,%mm7 + pxor %mm1,%mm0 + pxor %mm7,%mm6 + movq 40(%esp),%mm5 + paddq %mm6,%mm0 + movq 48(%esp),%mm6 + movdqa %xmm2,-16(%edx) + movq 8(%esp),%mm1 + paddq %mm3,%mm0 + movq 24(%esp),%mm3 + movq 56(%esp),%mm7 + pxor %mm1,%mm2 + paddq (%esi),%mm0 + paddq 8(%esi),%mm1 + paddq 16(%esi),%mm2 + paddq 24(%esi),%mm3 + paddq 32(%esi),%mm4 + paddq 40(%esi),%mm5 + paddq 48(%esi),%mm6 + paddq 56(%esi),%mm7 + movq %mm0,(%esi) + movq %mm1,8(%esi) + movq %mm2,16(%esi) + movq %mm3,24(%esi) + movq %mm4,32(%esi) + movq %mm5,40(%esi) + movq %mm6,48(%esi) + movq %mm7,56(%esi) + cmpl %eax,%edi + jb .L007loop_ssse3 + movl 76(%edx),%esp + emms + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 16 +.L002loop_x86: + movl (%edi),%eax + movl 4(%edi),%ebx + movl 8(%edi),%ecx + movl 12(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 16(%edi),%eax + movl 20(%edi),%ebx + movl 24(%edi),%ecx + movl 28(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 32(%edi),%eax + movl 36(%edi),%ebx + movl 40(%edi),%ecx + movl 44(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 48(%edi),%eax + movl 52(%edi),%ebx + movl 56(%edi),%ecx + movl 60(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 64(%edi),%eax + movl 68(%edi),%ebx + movl 72(%edi),%ecx + movl 76(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 80(%edi),%eax + movl 84(%edi),%ebx + movl 88(%edi),%ecx + movl 92(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 96(%edi),%eax + movl 100(%edi),%ebx + movl 104(%edi),%ecx + movl 108(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl 112(%edi),%eax + movl 116(%edi),%ebx + movl 120(%edi),%ecx + movl 124(%edi),%edx + bswap %eax + bswap %ebx + bswap %ecx + bswap %edx + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + addl $128,%edi + subl $72,%esp + movl %edi,204(%esp) + leal 8(%esp),%edi + movl $16,%ecx +.long 2784229001 +.align 16 +.L00900_15_x86: + movl 40(%esp),%ecx + movl 44(%esp),%edx + movl %ecx,%esi + shrl $9,%ecx + movl %edx,%edi + shrl $9,%edx + movl %ecx,%ebx + shll $14,%esi + movl %edx,%eax + shll $14,%edi + xorl %esi,%ebx + shrl $5,%ecx + xorl %edi,%eax + shrl $5,%edx + xorl %ecx,%eax + shll $4,%esi + xorl %edx,%ebx + shll $4,%edi + xorl %esi,%ebx + shrl $4,%ecx + xorl %edi,%eax + shrl $4,%edx + xorl %ecx,%eax + shll $5,%esi + xorl %edx,%ebx + shll $5,%edi + xorl %esi,%eax + xorl %edi,%ebx + movl 48(%esp),%ecx + movl 52(%esp),%edx + movl 56(%esp),%esi + movl 60(%esp),%edi + addl 64(%esp),%eax + adcl 68(%esp),%ebx + xorl %esi,%ecx + xorl %edi,%edx + andl 40(%esp),%ecx + andl 44(%esp),%edx + addl 192(%esp),%eax + adcl 196(%esp),%ebx + xorl %esi,%ecx + xorl %edi,%edx + movl (%ebp),%esi + movl 4(%ebp),%edi + addl %ecx,%eax + adcl %edx,%ebx + movl 32(%esp),%ecx + movl 36(%esp),%edx + addl %esi,%eax + adcl %edi,%ebx + movl %eax,(%esp) + movl %ebx,4(%esp) + addl %ecx,%eax + adcl %edx,%ebx + movl 8(%esp),%ecx + movl 12(%esp),%edx + movl %eax,32(%esp) + movl %ebx,36(%esp) + movl %ecx,%esi + shrl $2,%ecx + movl %edx,%edi + shrl $2,%edx + movl %ecx,%ebx + shll $4,%esi + movl %edx,%eax + shll $4,%edi + xorl %esi,%ebx + shrl $5,%ecx + xorl %edi,%eax + shrl $5,%edx + xorl %ecx,%ebx + shll $21,%esi + xorl %edx,%eax + shll $21,%edi + xorl %esi,%eax + shrl $21,%ecx + xorl %edi,%ebx + shrl $21,%edx + xorl %ecx,%eax + shll $5,%esi + xorl %edx,%ebx + shll $5,%edi + xorl %esi,%eax + xorl %edi,%ebx + movl 8(%esp),%ecx + movl 12(%esp),%edx + movl 16(%esp),%esi + movl 20(%esp),%edi + addl (%esp),%eax + adcl 4(%esp),%ebx + orl %esi,%ecx + orl %edi,%edx + andl 24(%esp),%ecx + andl 28(%esp),%edx + andl 8(%esp),%esi + andl 12(%esp),%edi + orl %esi,%ecx + orl %edi,%edx + addl %ecx,%eax + adcl %edx,%ebx + movl %eax,(%esp) + movl %ebx,4(%esp) + movb (%ebp),%dl + subl $8,%esp + leal 8(%ebp),%ebp + cmpb $148,%dl + jne .L00900_15_x86 +.align 16 +.L01016_79_x86: + movl 312(%esp),%ecx + movl 316(%esp),%edx + movl %ecx,%esi + shrl $1,%ecx + movl %edx,%edi + shrl $1,%edx + movl %ecx,%eax + shll $24,%esi + movl %edx,%ebx + shll $24,%edi + xorl %esi,%ebx + shrl $6,%ecx + xorl %edi,%eax + shrl $6,%edx + xorl %ecx,%eax + shll $7,%esi + xorl %edx,%ebx + shll $1,%edi + xorl %esi,%ebx + shrl $1,%ecx + xorl %edi,%eax + shrl $1,%edx + xorl %ecx,%eax + shll $6,%edi + xorl %edx,%ebx + xorl %edi,%eax + movl %eax,(%esp) + movl %ebx,4(%esp) + movl 208(%esp),%ecx + movl 212(%esp),%edx + movl %ecx,%esi + shrl $6,%ecx + movl %edx,%edi + shrl $6,%edx + movl %ecx,%eax + shll $3,%esi + movl %edx,%ebx + shll $3,%edi + xorl %esi,%eax + shrl $13,%ecx + xorl %edi,%ebx + shrl $13,%edx + xorl %ecx,%eax + shll $10,%esi + xorl %edx,%ebx + shll $10,%edi + xorl %esi,%ebx + shrl $10,%ecx + xorl %edi,%eax + shrl $10,%edx + xorl %ecx,%ebx + shll $13,%edi + xorl %edx,%eax + xorl %edi,%eax + movl 320(%esp),%ecx + movl 324(%esp),%edx + addl (%esp),%eax + adcl 4(%esp),%ebx + movl 248(%esp),%esi + movl 252(%esp),%edi + addl %ecx,%eax + adcl %edx,%ebx + addl %esi,%eax + adcl %edi,%ebx + movl %eax,192(%esp) + movl %ebx,196(%esp) + movl 40(%esp),%ecx + movl 44(%esp),%edx + movl %ecx,%esi + shrl $9,%ecx + movl %edx,%edi + shrl $9,%edx + movl %ecx,%ebx + shll $14,%esi + movl %edx,%eax + shll $14,%edi + xorl %esi,%ebx + shrl $5,%ecx + xorl %edi,%eax + shrl $5,%edx + xorl %ecx,%eax + shll $4,%esi + xorl %edx,%ebx + shll $4,%edi + xorl %esi,%ebx + shrl $4,%ecx + xorl %edi,%eax + shrl $4,%edx + xorl %ecx,%eax + shll $5,%esi + xorl %edx,%ebx + shll $5,%edi + xorl %esi,%eax + xorl %edi,%ebx + movl 48(%esp),%ecx + movl 52(%esp),%edx + movl 56(%esp),%esi + movl 60(%esp),%edi + addl 64(%esp),%eax + adcl 68(%esp),%ebx + xorl %esi,%ecx + xorl %edi,%edx + andl 40(%esp),%ecx + andl 44(%esp),%edx + addl 192(%esp),%eax + adcl 196(%esp),%ebx + xorl %esi,%ecx + xorl %edi,%edx + movl (%ebp),%esi + movl 4(%ebp),%edi + addl %ecx,%eax + adcl %edx,%ebx + movl 32(%esp),%ecx + movl 36(%esp),%edx + addl %esi,%eax + adcl %edi,%ebx + movl %eax,(%esp) + movl %ebx,4(%esp) + addl %ecx,%eax + adcl %edx,%ebx + movl 8(%esp),%ecx + movl 12(%esp),%edx + movl %eax,32(%esp) + movl %ebx,36(%esp) + movl %ecx,%esi + shrl $2,%ecx + movl %edx,%edi + shrl $2,%edx + movl %ecx,%ebx + shll $4,%esi + movl %edx,%eax + shll $4,%edi + xorl %esi,%ebx + shrl $5,%ecx + xorl %edi,%eax + shrl $5,%edx + xorl %ecx,%ebx + shll $21,%esi + xorl %edx,%eax + shll $21,%edi + xorl %esi,%eax + shrl $21,%ecx + xorl %edi,%ebx + shrl $21,%edx + xorl %ecx,%eax + shll $5,%esi + xorl %edx,%ebx + shll $5,%edi + xorl %esi,%eax + xorl %edi,%ebx + movl 8(%esp),%ecx + movl 12(%esp),%edx + movl 16(%esp),%esi + movl 20(%esp),%edi + addl (%esp),%eax + adcl 4(%esp),%ebx + orl %esi,%ecx + orl %edi,%edx + andl 24(%esp),%ecx + andl 28(%esp),%edx + andl 8(%esp),%esi + andl 12(%esp),%edi + orl %esi,%ecx + orl %edi,%edx + addl %ecx,%eax + adcl %edx,%ebx + movl %eax,(%esp) + movl %ebx,4(%esp) + movb (%ebp),%dl + subl $8,%esp + leal 8(%ebp),%ebp + cmpb $23,%dl + jne .L01016_79_x86 + movl 840(%esp),%esi + movl 844(%esp),%edi + movl (%esi),%eax + movl 4(%esi),%ebx + movl 8(%esi),%ecx + movl 12(%esi),%edx + addl 8(%esp),%eax + adcl 12(%esp),%ebx + movl %eax,(%esi) + movl %ebx,4(%esi) + addl 16(%esp),%ecx + adcl 20(%esp),%edx + movl %ecx,8(%esi) + movl %edx,12(%esi) + movl 16(%esi),%eax + movl 20(%esi),%ebx + movl 24(%esi),%ecx + movl 28(%esi),%edx + addl 24(%esp),%eax + adcl 28(%esp),%ebx + movl %eax,16(%esi) + movl %ebx,20(%esi) + addl 32(%esp),%ecx + adcl 36(%esp),%edx + movl %ecx,24(%esi) + movl %edx,28(%esi) + movl 32(%esi),%eax + movl 36(%esi),%ebx + movl 40(%esi),%ecx + movl 44(%esi),%edx + addl 40(%esp),%eax + adcl 44(%esp),%ebx + movl %eax,32(%esi) + movl %ebx,36(%esi) + addl 48(%esp),%ecx + adcl 52(%esp),%edx + movl %ecx,40(%esi) + movl %edx,44(%esi) + movl 48(%esi),%eax + movl 52(%esi),%ebx + movl 56(%esi),%ecx + movl 60(%esi),%edx + addl 56(%esp),%eax + adcl 60(%esp),%ebx + movl %eax,48(%esi) + movl %ebx,52(%esi) + addl 64(%esp),%ecx + adcl 68(%esp),%edx + movl %ecx,56(%esi) + movl %edx,60(%esi) + addl $840,%esp + subl $640,%ebp + cmpl 8(%esp),%edi + jb .L002loop_x86 + movl 12(%esp),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 64 +.L001K512: +.long 3609767458,1116352408 +.long 602891725,1899447441 +.long 3964484399,3049323471 +.long 2173295548,3921009573 +.long 4081628472,961987163 +.long 3053834265,1508970993 +.long 2937671579,2453635748 +.long 3664609560,2870763221 +.long 2734883394,3624381080 +.long 1164996542,310598401 +.long 1323610764,607225278 +.long 3590304994,1426881987 +.long 4068182383,1925078388 +.long 991336113,2162078206 +.long 633803317,2614888103 +.long 3479774868,3248222580 +.long 2666613458,3835390401 +.long 944711139,4022224774 +.long 2341262773,264347078 +.long 2007800933,604807628 +.long 1495990901,770255983 +.long 1856431235,1249150122 +.long 3175218132,1555081692 +.long 2198950837,1996064986 +.long 3999719339,2554220882 +.long 766784016,2821834349 +.long 2566594879,2952996808 +.long 3203337956,3210313671 +.long 1034457026,3336571891 +.long 2466948901,3584528711 +.long 3758326383,113926993 +.long 168717936,338241895 +.long 1188179964,666307205 +.long 1546045734,773529912 +.long 1522805485,1294757372 +.long 2643833823,1396182291 +.long 2343527390,1695183700 +.long 1014477480,1986661051 +.long 1206759142,2177026350 +.long 344077627,2456956037 +.long 1290863460,2730485921 +.long 3158454273,2820302411 +.long 3505952657,3259730800 +.long 106217008,3345764771 +.long 3606008344,3516065817 +.long 1432725776,3600352804 +.long 1467031594,4094571909 +.long 851169720,275423344 +.long 3100823752,430227734 +.long 1363258195,506948616 +.long 3750685593,659060556 +.long 3785050280,883997877 +.long 3318307427,958139571 +.long 3812723403,1322822218 +.long 2003034995,1537002063 +.long 3602036899,1747873779 +.long 1575990012,1955562222 +.long 1125592928,2024104815 +.long 2716904306,2227730452 +.long 442776044,2361852424 +.long 593698344,2428436474 +.long 3733110249,2756734187 +.long 2999351573,3204031479 +.long 3815920427,3329325298 +.long 3928383900,3391569614 +.long 566280711,3515267271 +.long 3454069534,3940187606 +.long 4000239992,4118630271 +.long 1914138554,116418474 +.long 2731055270,174292421 +.long 3203993006,289380356 +.long 320620315,460393269 +.long 587496836,685471733 +.long 1086792851,852142971 +.long 365543100,1017036298 +.long 2618297676,1126000580 +.long 3409855158,1288033470 +.long 4234509866,1501505948 +.long 987167468,1607167915 +.long 1246189591,1816402316 +.long 67438087,66051 +.long 202182159,134810123 +.size sha512_block_data_order,.-.L_sha512_block_data_order_begin +.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97 +.byte 110,115,102,111,114,109,32,102,111,114,32,120,56,54,44,32 +.byte 67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97 +.byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103 +.byte 62,0 +.comm OPENSSL_ia32cap_P,16,4 + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/sha/sha512-armv8.S b/crypto/openssl/crypto/sha/sha512-armv8.S new file mode 100644 index 000000000000..79914442633b --- /dev/null +++ b/crypto/openssl/crypto/sha/sha512-armv8.S @@ -0,0 +1,1606 @@ +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License 2.0 (the "License"). You may not use +// this file except in compliance with the License. You can obtain a copy +// in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html + +// ==================================================================== +// Written by Andy Polyakov 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/. +// +// Permission to use under GPLv2 terms is granted. +// ==================================================================== +// +// SHA256/512 for ARMv8. +// +// Performance in cycles per processed byte and improvement coefficient +// over code generated with "default" compiler: +// +// SHA256-hw SHA256(*) SHA512 +// Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**)) +// Cortex-A53 2.38 15.5 (+115%) 10.0 (+150%(***)) +// Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***)) +// Denver 2.01 10.5 (+26%) 6.70 (+8%) +// X-Gene 20.0 (+100%) 12.8 (+300%(***)) +// Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) +// ThunderX2 2.54 13.2 (+40%) 8.40 (+18%) +// +// (*) Software SHA256 results are of lesser relevance, presented +// mostly for informational purposes. +// (**) The result is a trade-off: it's possible to improve it by +// 10% (or by 1 cycle per round), but at the cost of 20% loss +// on Cortex-A53 (or by 4 cycles per round). +// (***) Super-impressive coefficients over gcc-generated code are +// indication of some compiler "pathology", most notably code +// generated with -mgeneral-regs-only is significantly faster +// and the gap is only 40-90%. +// +// October 2016. +// +// Originally it was reckoned that it makes no sense to implement NEON +// version of SHA256 for 64-bit processors. This is because performance +// improvement on most wide-spread Cortex-A5x processors was observed +// to be marginal, same on Cortex-A53 and ~10% on A57. But then it was +// observed that 32-bit NEON SHA256 performs significantly better than +// 64-bit scalar version on *some* of the more recent processors. As +// result 64-bit NEON version of SHA256 was added to provide best +// all-round performance. For example it executes ~30% faster on X-Gene +// and Mongoose. [For reference, NEON version of SHA512 is bound to +// deliver much less improvement, likely *negative* on Cortex-A5x. +// Which is why NEON support is limited to SHA256.] + +// $output is the last argument if it looks like a file (it has an extension) +// $flavour is the first argument if it doesn't look like a file +#ifndef __KERNEL__ +# include "arm_arch.h" + +.hidden OPENSSL_armcap_P +#endif + +.text + +.globl sha512_block_data_order +.type sha512_block_data_order,%function +.align 6 +sha512_block_data_order: +#ifndef __KERNEL__ + adrp x16,OPENSSL_armcap_P + ldr w16,[x16,#:lo12:OPENSSL_armcap_P] + tst w16,#ARMV8_SHA512 + b.ne .Lv8_entry +#endif +.inst 0xd503233f // paciasp + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#4*8 + + ldp x20,x21,[x0] // load context + ldp x22,x23,[x0,#2*8] + ldp x24,x25,[x0,#4*8] + add x2,x1,x2,lsl#7 // end of input + ldp x26,x27,[x0,#6*8] + adr x30,.LK512 + stp x0,x2,[x29,#96] + +.Loop: + ldp x3,x4,[x1],#2*8 + ldr x19,[x30],#8 // *K++ + eor x28,x21,x22 // magic seed + str x1,[x29,#112] +#ifndef __AARCH64EB__ + rev x3,x3 // 0 +#endif + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + eor x6,x24,x24,ror#23 + and x17,x25,x24 + bic x19,x26,x24 + add x27,x27,x3 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x6,ror#18 // Sigma1(e) + ror x6,x20,#28 + add x27,x27,x17 // h+=Ch(e,f,g) + eor x17,x20,x20,ror#5 + add x27,x27,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x23,x23,x27 // d+=h + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x6,x17,ror#34 // Sigma0(a) + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x4,x4 // 1 +#endif + ldp x5,x6,[x1],#2*8 + add x27,x27,x17 // h+=Sigma0(a) + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + eor x7,x23,x23,ror#23 + and x17,x24,x23 + bic x28,x25,x23 + add x26,x26,x4 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x7,ror#18 // Sigma1(e) + ror x7,x27,#28 + add x26,x26,x17 // h+=Ch(e,f,g) + eor x17,x27,x27,ror#5 + add x26,x26,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x22,x22,x26 // d+=h + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x7,x17,ror#34 // Sigma0(a) + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x5,x5 // 2 +#endif + add x26,x26,x17 // h+=Sigma0(a) + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + eor x8,x22,x22,ror#23 + and x17,x23,x22 + bic x19,x24,x22 + add x25,x25,x5 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x8,ror#18 // Sigma1(e) + ror x8,x26,#28 + add x25,x25,x17 // h+=Ch(e,f,g) + eor x17,x26,x26,ror#5 + add x25,x25,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x21,x21,x25 // d+=h + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x8,x17,ror#34 // Sigma0(a) + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x6,x6 // 3 +#endif + ldp x7,x8,[x1],#2*8 + add x25,x25,x17 // h+=Sigma0(a) + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + eor x9,x21,x21,ror#23 + and x17,x22,x21 + bic x28,x23,x21 + add x24,x24,x6 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x9,ror#18 // Sigma1(e) + ror x9,x25,#28 + add x24,x24,x17 // h+=Ch(e,f,g) + eor x17,x25,x25,ror#5 + add x24,x24,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x20,x20,x24 // d+=h + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x9,x17,ror#34 // Sigma0(a) + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x7,x7 // 4 +#endif + add x24,x24,x17 // h+=Sigma0(a) + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + eor x10,x20,x20,ror#23 + and x17,x21,x20 + bic x19,x22,x20 + add x23,x23,x7 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x10,ror#18 // Sigma1(e) + ror x10,x24,#28 + add x23,x23,x17 // h+=Ch(e,f,g) + eor x17,x24,x24,ror#5 + add x23,x23,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x27,x27,x23 // d+=h + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x10,x17,ror#34 // Sigma0(a) + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x8,x8 // 5 +#endif + ldp x9,x10,[x1],#2*8 + add x23,x23,x17 // h+=Sigma0(a) + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + eor x11,x27,x27,ror#23 + and x17,x20,x27 + bic x28,x21,x27 + add x22,x22,x8 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x11,ror#18 // Sigma1(e) + ror x11,x23,#28 + add x22,x22,x17 // h+=Ch(e,f,g) + eor x17,x23,x23,ror#5 + add x22,x22,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x26,x26,x22 // d+=h + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x11,x17,ror#34 // Sigma0(a) + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x9,x9 // 6 +#endif + add x22,x22,x17 // h+=Sigma0(a) + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + eor x12,x26,x26,ror#23 + and x17,x27,x26 + bic x19,x20,x26 + add x21,x21,x9 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x12,ror#18 // Sigma1(e) + ror x12,x22,#28 + add x21,x21,x17 // h+=Ch(e,f,g) + eor x17,x22,x22,ror#5 + add x21,x21,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x25,x25,x21 // d+=h + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x12,x17,ror#34 // Sigma0(a) + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x10,x10 // 7 +#endif + ldp x11,x12,[x1],#2*8 + add x21,x21,x17 // h+=Sigma0(a) + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + eor x13,x25,x25,ror#23 + and x17,x26,x25 + bic x28,x27,x25 + add x20,x20,x10 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x13,ror#18 // Sigma1(e) + ror x13,x21,#28 + add x20,x20,x17 // h+=Ch(e,f,g) + eor x17,x21,x21,ror#5 + add x20,x20,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x24,x24,x20 // d+=h + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x13,x17,ror#34 // Sigma0(a) + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x20,x20,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x11,x11 // 8 +#endif + add x20,x20,x17 // h+=Sigma0(a) + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + eor x14,x24,x24,ror#23 + and x17,x25,x24 + bic x19,x26,x24 + add x27,x27,x11 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x14,ror#18 // Sigma1(e) + ror x14,x20,#28 + add x27,x27,x17 // h+=Ch(e,f,g) + eor x17,x20,x20,ror#5 + add x27,x27,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x23,x23,x27 // d+=h + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x14,x17,ror#34 // Sigma0(a) + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x12,x12 // 9 +#endif + ldp x13,x14,[x1],#2*8 + add x27,x27,x17 // h+=Sigma0(a) + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + eor x15,x23,x23,ror#23 + and x17,x24,x23 + bic x28,x25,x23 + add x26,x26,x12 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x15,ror#18 // Sigma1(e) + ror x15,x27,#28 + add x26,x26,x17 // h+=Ch(e,f,g) + eor x17,x27,x27,ror#5 + add x26,x26,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x22,x22,x26 // d+=h + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x15,x17,ror#34 // Sigma0(a) + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x13,x13 // 10 +#endif + add x26,x26,x17 // h+=Sigma0(a) + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + eor x0,x22,x22,ror#23 + and x17,x23,x22 + bic x19,x24,x22 + add x25,x25,x13 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x0,ror#18 // Sigma1(e) + ror x0,x26,#28 + add x25,x25,x17 // h+=Ch(e,f,g) + eor x17,x26,x26,ror#5 + add x25,x25,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x21,x21,x25 // d+=h + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x0,x17,ror#34 // Sigma0(a) + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x14,x14 // 11 +#endif + ldp x15,x0,[x1],#2*8 + add x25,x25,x17 // h+=Sigma0(a) + str x6,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + eor x6,x21,x21,ror#23 + and x17,x22,x21 + bic x28,x23,x21 + add x24,x24,x14 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x6,ror#18 // Sigma1(e) + ror x6,x25,#28 + add x24,x24,x17 // h+=Ch(e,f,g) + eor x17,x25,x25,ror#5 + add x24,x24,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x20,x20,x24 // d+=h + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x6,x17,ror#34 // Sigma0(a) + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x15,x15 // 12 +#endif + add x24,x24,x17 // h+=Sigma0(a) + str x7,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + eor x7,x20,x20,ror#23 + and x17,x21,x20 + bic x19,x22,x20 + add x23,x23,x15 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x7,ror#18 // Sigma1(e) + ror x7,x24,#28 + add x23,x23,x17 // h+=Ch(e,f,g) + eor x17,x24,x24,ror#5 + add x23,x23,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x27,x27,x23 // d+=h + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x7,x17,ror#34 // Sigma0(a) + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x0,x0 // 13 +#endif + ldp x1,x2,[x1] + add x23,x23,x17 // h+=Sigma0(a) + str x8,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + eor x8,x27,x27,ror#23 + and x17,x20,x27 + bic x28,x21,x27 + add x22,x22,x0 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x8,ror#18 // Sigma1(e) + ror x8,x23,#28 + add x22,x22,x17 // h+=Ch(e,f,g) + eor x17,x23,x23,ror#5 + add x22,x22,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x26,x26,x22 // d+=h + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x8,x17,ror#34 // Sigma0(a) + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x1,x1 // 14 +#endif + ldr x6,[sp,#24] + add x22,x22,x17 // h+=Sigma0(a) + str x9,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + eor x9,x26,x26,ror#23 + and x17,x27,x26 + bic x19,x20,x26 + add x21,x21,x1 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x9,ror#18 // Sigma1(e) + ror x9,x22,#28 + add x21,x21,x17 // h+=Ch(e,f,g) + eor x17,x22,x22,ror#5 + add x21,x21,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x25,x25,x21 // d+=h + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x9,x17,ror#34 // Sigma0(a) + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) +#ifndef __AARCH64EB__ + rev x2,x2 // 15 +#endif + ldr x7,[sp,#0] + add x21,x21,x17 // h+=Sigma0(a) + str x10,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x9,x4,#1 + and x17,x26,x25 + ror x8,x1,#19 + bic x28,x27,x25 + ror x10,x21,#28 + add x20,x20,x2 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x9,x9,x4,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x10,x10,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x8,x8,x1,ror#61 + eor x9,x9,x4,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x10,x21,ror#39 // Sigma0(a) + eor x8,x8,x1,lsr#6 // sigma1(X[i+14]) + add x3,x3,x12 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x3,x3,x9 + add x20,x20,x17 // h+=Sigma0(a) + add x3,x3,x8 +.Loop_16_xx: + ldr x8,[sp,#8] + str x11,[sp,#0] + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + ror x10,x5,#1 + and x17,x25,x24 + ror x9,x2,#19 + bic x19,x26,x24 + ror x11,x20,#28 + add x27,x27,x3 // h+=X[i] + eor x16,x16,x24,ror#18 + eor x10,x10,x5,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x24,ror#41 // Sigma1(e) + eor x11,x11,x20,ror#34 + add x27,x27,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x9,x9,x2,ror#61 + eor x10,x10,x5,lsr#7 // sigma0(X[i+1]) + add x27,x27,x16 // h+=Sigma1(e) + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x11,x20,ror#39 // Sigma0(a) + eor x9,x9,x2,lsr#6 // sigma1(X[i+14]) + add x4,x4,x13 + add x23,x23,x27 // d+=h + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x4,x4,x10 + add x27,x27,x17 // h+=Sigma0(a) + add x4,x4,x9 + ldr x9,[sp,#16] + str x12,[sp,#8] + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + ror x11,x6,#1 + and x17,x24,x23 + ror x10,x3,#19 + bic x28,x25,x23 + ror x12,x27,#28 + add x26,x26,x4 // h+=X[i] + eor x16,x16,x23,ror#18 + eor x11,x11,x6,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x23,ror#41 // Sigma1(e) + eor x12,x12,x27,ror#34 + add x26,x26,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x10,x10,x3,ror#61 + eor x11,x11,x6,lsr#7 // sigma0(X[i+1]) + add x26,x26,x16 // h+=Sigma1(e) + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x12,x27,ror#39 // Sigma0(a) + eor x10,x10,x3,lsr#6 // sigma1(X[i+14]) + add x5,x5,x14 + add x22,x22,x26 // d+=h + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x5,x5,x11 + add x26,x26,x17 // h+=Sigma0(a) + add x5,x5,x10 + ldr x10,[sp,#24] + str x13,[sp,#16] + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + ror x12,x7,#1 + and x17,x23,x22 + ror x11,x4,#19 + bic x19,x24,x22 + ror x13,x26,#28 + add x25,x25,x5 // h+=X[i] + eor x16,x16,x22,ror#18 + eor x12,x12,x7,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x22,ror#41 // Sigma1(e) + eor x13,x13,x26,ror#34 + add x25,x25,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x11,x11,x4,ror#61 + eor x12,x12,x7,lsr#7 // sigma0(X[i+1]) + add x25,x25,x16 // h+=Sigma1(e) + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x13,x26,ror#39 // Sigma0(a) + eor x11,x11,x4,lsr#6 // sigma1(X[i+14]) + add x6,x6,x15 + add x21,x21,x25 // d+=h + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x6,x6,x12 + add x25,x25,x17 // h+=Sigma0(a) + add x6,x6,x11 + ldr x11,[sp,#0] + str x14,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + ror x13,x8,#1 + and x17,x22,x21 + ror x12,x5,#19 + bic x28,x23,x21 + ror x14,x25,#28 + add x24,x24,x6 // h+=X[i] + eor x16,x16,x21,ror#18 + eor x13,x13,x8,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x21,ror#41 // Sigma1(e) + eor x14,x14,x25,ror#34 + add x24,x24,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x12,x12,x5,ror#61 + eor x13,x13,x8,lsr#7 // sigma0(X[i+1]) + add x24,x24,x16 // h+=Sigma1(e) + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x14,x25,ror#39 // Sigma0(a) + eor x12,x12,x5,lsr#6 // sigma1(X[i+14]) + add x7,x7,x0 + add x20,x20,x24 // d+=h + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x7,x7,x13 + add x24,x24,x17 // h+=Sigma0(a) + add x7,x7,x12 + ldr x12,[sp,#8] + str x15,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + ror x14,x9,#1 + and x17,x21,x20 + ror x13,x6,#19 + bic x19,x22,x20 + ror x15,x24,#28 + add x23,x23,x7 // h+=X[i] + eor x16,x16,x20,ror#18 + eor x14,x14,x9,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x20,ror#41 // Sigma1(e) + eor x15,x15,x24,ror#34 + add x23,x23,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x13,x13,x6,ror#61 + eor x14,x14,x9,lsr#7 // sigma0(X[i+1]) + add x23,x23,x16 // h+=Sigma1(e) + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x15,x24,ror#39 // Sigma0(a) + eor x13,x13,x6,lsr#6 // sigma1(X[i+14]) + add x8,x8,x1 + add x27,x27,x23 // d+=h + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x8,x8,x14 + add x23,x23,x17 // h+=Sigma0(a) + add x8,x8,x13 + ldr x13,[sp,#16] + str x0,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + ror x15,x10,#1 + and x17,x20,x27 + ror x14,x7,#19 + bic x28,x21,x27 + ror x0,x23,#28 + add x22,x22,x8 // h+=X[i] + eor x16,x16,x27,ror#18 + eor x15,x15,x10,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x27,ror#41 // Sigma1(e) + eor x0,x0,x23,ror#34 + add x22,x22,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x14,x14,x7,ror#61 + eor x15,x15,x10,lsr#7 // sigma0(X[i+1]) + add x22,x22,x16 // h+=Sigma1(e) + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x0,x23,ror#39 // Sigma0(a) + eor x14,x14,x7,lsr#6 // sigma1(X[i+14]) + add x9,x9,x2 + add x26,x26,x22 // d+=h + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x9,x9,x15 + add x22,x22,x17 // h+=Sigma0(a) + add x9,x9,x14 + ldr x14,[sp,#24] + str x1,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + ror x0,x11,#1 + and x17,x27,x26 + ror x15,x8,#19 + bic x19,x20,x26 + ror x1,x22,#28 + add x21,x21,x9 // h+=X[i] + eor x16,x16,x26,ror#18 + eor x0,x0,x11,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x26,ror#41 // Sigma1(e) + eor x1,x1,x22,ror#34 + add x21,x21,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x15,x15,x8,ror#61 + eor x0,x0,x11,lsr#7 // sigma0(X[i+1]) + add x21,x21,x16 // h+=Sigma1(e) + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x1,x22,ror#39 // Sigma0(a) + eor x15,x15,x8,lsr#6 // sigma1(X[i+14]) + add x10,x10,x3 + add x25,x25,x21 // d+=h + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x10,x10,x0 + add x21,x21,x17 // h+=Sigma0(a) + add x10,x10,x15 + ldr x15,[sp,#0] + str x2,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x1,x12,#1 + and x17,x26,x25 + ror x0,x9,#19 + bic x28,x27,x25 + ror x2,x21,#28 + add x20,x20,x10 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x1,x1,x12,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x2,x2,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x0,x0,x9,ror#61 + eor x1,x1,x12,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x2,x21,ror#39 // Sigma0(a) + eor x0,x0,x9,lsr#6 // sigma1(X[i+14]) + add x11,x11,x4 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x11,x11,x1 + add x20,x20,x17 // h+=Sigma0(a) + add x11,x11,x0 + ldr x0,[sp,#8] + str x3,[sp,#0] + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + ror x2,x13,#1 + and x17,x25,x24 + ror x1,x10,#19 + bic x19,x26,x24 + ror x3,x20,#28 + add x27,x27,x11 // h+=X[i] + eor x16,x16,x24,ror#18 + eor x2,x2,x13,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x24,ror#41 // Sigma1(e) + eor x3,x3,x20,ror#34 + add x27,x27,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x1,x1,x10,ror#61 + eor x2,x2,x13,lsr#7 // sigma0(X[i+1]) + add x27,x27,x16 // h+=Sigma1(e) + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x3,x20,ror#39 // Sigma0(a) + eor x1,x1,x10,lsr#6 // sigma1(X[i+14]) + add x12,x12,x5 + add x23,x23,x27 // d+=h + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x12,x12,x2 + add x27,x27,x17 // h+=Sigma0(a) + add x12,x12,x1 + ldr x1,[sp,#16] + str x4,[sp,#8] + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + ror x3,x14,#1 + and x17,x24,x23 + ror x2,x11,#19 + bic x28,x25,x23 + ror x4,x27,#28 + add x26,x26,x12 // h+=X[i] + eor x16,x16,x23,ror#18 + eor x3,x3,x14,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x23,ror#41 // Sigma1(e) + eor x4,x4,x27,ror#34 + add x26,x26,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x2,x2,x11,ror#61 + eor x3,x3,x14,lsr#7 // sigma0(X[i+1]) + add x26,x26,x16 // h+=Sigma1(e) + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x4,x27,ror#39 // Sigma0(a) + eor x2,x2,x11,lsr#6 // sigma1(X[i+14]) + add x13,x13,x6 + add x22,x22,x26 // d+=h + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x13,x13,x3 + add x26,x26,x17 // h+=Sigma0(a) + add x13,x13,x2 + ldr x2,[sp,#24] + str x5,[sp,#16] + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + ror x4,x15,#1 + and x17,x23,x22 + ror x3,x12,#19 + bic x19,x24,x22 + ror x5,x26,#28 + add x25,x25,x13 // h+=X[i] + eor x16,x16,x22,ror#18 + eor x4,x4,x15,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x22,ror#41 // Sigma1(e) + eor x5,x5,x26,ror#34 + add x25,x25,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x3,x3,x12,ror#61 + eor x4,x4,x15,lsr#7 // sigma0(X[i+1]) + add x25,x25,x16 // h+=Sigma1(e) + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x5,x26,ror#39 // Sigma0(a) + eor x3,x3,x12,lsr#6 // sigma1(X[i+14]) + add x14,x14,x7 + add x21,x21,x25 // d+=h + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x14,x14,x4 + add x25,x25,x17 // h+=Sigma0(a) + add x14,x14,x3 + ldr x3,[sp,#0] + str x6,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + ror x5,x0,#1 + and x17,x22,x21 + ror x4,x13,#19 + bic x28,x23,x21 + ror x6,x25,#28 + add x24,x24,x14 // h+=X[i] + eor x16,x16,x21,ror#18 + eor x5,x5,x0,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x21,ror#41 // Sigma1(e) + eor x6,x6,x25,ror#34 + add x24,x24,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x4,x4,x13,ror#61 + eor x5,x5,x0,lsr#7 // sigma0(X[i+1]) + add x24,x24,x16 // h+=Sigma1(e) + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x6,x25,ror#39 // Sigma0(a) + eor x4,x4,x13,lsr#6 // sigma1(X[i+14]) + add x15,x15,x8 + add x20,x20,x24 // d+=h + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x15,x15,x5 + add x24,x24,x17 // h+=Sigma0(a) + add x15,x15,x4 + ldr x4,[sp,#8] + str x7,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + ror x6,x1,#1 + and x17,x21,x20 + ror x5,x14,#19 + bic x19,x22,x20 + ror x7,x24,#28 + add x23,x23,x15 // h+=X[i] + eor x16,x16,x20,ror#18 + eor x6,x6,x1,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x20,ror#41 // Sigma1(e) + eor x7,x7,x24,ror#34 + add x23,x23,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x5,x5,x14,ror#61 + eor x6,x6,x1,lsr#7 // sigma0(X[i+1]) + add x23,x23,x16 // h+=Sigma1(e) + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x7,x24,ror#39 // Sigma0(a) + eor x5,x5,x14,lsr#6 // sigma1(X[i+14]) + add x0,x0,x9 + add x27,x27,x23 // d+=h + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x0,x0,x6 + add x23,x23,x17 // h+=Sigma0(a) + add x0,x0,x5 + ldr x5,[sp,#16] + str x8,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + ror x7,x2,#1 + and x17,x20,x27 + ror x6,x15,#19 + bic x28,x21,x27 + ror x8,x23,#28 + add x22,x22,x0 // h+=X[i] + eor x16,x16,x27,ror#18 + eor x7,x7,x2,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x27,ror#41 // Sigma1(e) + eor x8,x8,x23,ror#34 + add x22,x22,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x6,x6,x15,ror#61 + eor x7,x7,x2,lsr#7 // sigma0(X[i+1]) + add x22,x22,x16 // h+=Sigma1(e) + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x8,x23,ror#39 // Sigma0(a) + eor x6,x6,x15,lsr#6 // sigma1(X[i+14]) + add x1,x1,x10 + add x26,x26,x22 // d+=h + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x1,x1,x7 + add x22,x22,x17 // h+=Sigma0(a) + add x1,x1,x6 + ldr x6,[sp,#24] + str x9,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + ror x8,x3,#1 + and x17,x27,x26 + ror x7,x0,#19 + bic x19,x20,x26 + ror x9,x22,#28 + add x21,x21,x1 // h+=X[i] + eor x16,x16,x26,ror#18 + eor x8,x8,x3,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x26,ror#41 // Sigma1(e) + eor x9,x9,x22,ror#34 + add x21,x21,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x7,x7,x0,ror#61 + eor x8,x8,x3,lsr#7 // sigma0(X[i+1]) + add x21,x21,x16 // h+=Sigma1(e) + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x9,x22,ror#39 // Sigma0(a) + eor x7,x7,x0,lsr#6 // sigma1(X[i+14]) + add x2,x2,x11 + add x25,x25,x21 // d+=h + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x2,x2,x8 + add x21,x21,x17 // h+=Sigma0(a) + add x2,x2,x7 + ldr x7,[sp,#0] + str x10,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x9,x4,#1 + and x17,x26,x25 + ror x8,x1,#19 + bic x28,x27,x25 + ror x10,x21,#28 + add x20,x20,x2 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x9,x9,x4,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x10,x10,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x8,x8,x1,ror#61 + eor x9,x9,x4,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x10,x21,ror#39 // Sigma0(a) + eor x8,x8,x1,lsr#6 // sigma1(X[i+14]) + add x3,x3,x12 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x3,x3,x9 + add x20,x20,x17 // h+=Sigma0(a) + add x3,x3,x8 + cbnz x19,.Loop_16_xx + + ldp x0,x2,[x29,#96] + ldr x1,[x29,#112] + sub x30,x30,#648 // rewind + + ldp x3,x4,[x0] + ldp x5,x6,[x0,#2*8] + add x1,x1,#14*8 // advance input pointer + ldp x7,x8,[x0,#4*8] + add x20,x20,x3 + ldp x9,x10,[x0,#6*8] + add x21,x21,x4 + add x22,x22,x5 + add x23,x23,x6 + stp x20,x21,[x0] + add x24,x24,x7 + add x25,x25,x8 + stp x22,x23,[x0,#2*8] + add x26,x26,x9 + add x27,x27,x10 + cmp x1,x2 + stp x24,x25,[x0,#4*8] + stp x26,x27,[x0,#6*8] + b.ne .Loop + + ldp x19,x20,[x29,#16] + add sp,sp,#4*8 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 +.inst 0xd50323bf // autiasp + ret +.size sha512_block_data_order,.-sha512_block_data_order + +.align 6 +.type .LK512,%object +.LK512: +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +.quad 0 // terminator +.size .LK512,.-.LK512 +.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.align 2 +#ifndef __KERNEL__ +.type sha512_block_armv8,%function +.align 6 +sha512_block_armv8: +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x1],#64 // load input + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + + ld1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // load context + adr x3,.LK512 + + rev64 v16.16b,v16.16b + rev64 v17.16b,v17.16b + rev64 v18.16b,v18.16b + rev64 v19.16b,v19.16b + rev64 v20.16b,v20.16b + rev64 v21.16b,v21.16b + rev64 v22.16b,v22.16b + rev64 v23.16b,v23.16b + b .Loop_hw + +.align 4 +.Loop_hw: + ld1 {v24.2d},[x3],#16 + subs x2,x2,#1 + sub x4,x1,#128 + orr v26.16b,v0.16b,v0.16b // offload + orr v27.16b,v1.16b,v1.16b + orr v28.16b,v2.16b,v2.16b + orr v29.16b,v3.16b,v3.16b + csel x1,x1,x4,ne // conditional rewind + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v16.2d + ld1 {v16.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v16.16b,v16.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v17.2d + ld1 {v17.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v17.16b,v17.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v18.2d + ld1 {v18.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v18.16b,v18.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v19.2d + ld1 {v19.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b + rev64 v19.16b,v19.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v20.2d + ld1 {v20.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b + rev64 v20.16b,v20.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v21.2d + ld1 {v21.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v21.16b,v21.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v22.2d + ld1 {v22.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v22.16b,v22.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + sub x3,x3,#80*8 // rewind + add v25.2d,v25.2d,v23.2d + ld1 {v23.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v23.16b,v23.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v0.2d,v0.2d,v26.2d // accumulate + add v1.2d,v1.2d,v27.2d + add v2.2d,v2.2d,v28.2d + add v3.2d,v3.2d,v29.2d + + cbnz x2,.Loop_hw + + st1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // store context + + ldr x29,[sp],#16 + ret +.size sha512_block_armv8,.-sha512_block_armv8 +#endif diff --git a/crypto/openssl/crypto/sha/sha512-x86_64.S b/crypto/openssl/crypto/sha/sha512-x86_64.S new file mode 100644 index 000000000000..a76d017ba764 --- /dev/null +++ b/crypto/openssl/crypto/sha/sha512-x86_64.S @@ -0,0 +1,5482 @@ +.text + + +.globl sha512_block_data_order +.type sha512_block_data_order,@function +.align 16 +sha512_block_data_order: +.cfi_startproc + leaq OPENSSL_ia32cap_P(%rip),%r11 + movl 0(%r11),%r9d + movl 4(%r11),%r10d + movl 8(%r11),%r11d + testl $2048,%r10d + jnz .Lxop_shortcut + andl $296,%r11d + cmpl $296,%r11d + je .Lavx2_shortcut + andl $1073741824,%r9d + andl $268435968,%r10d + orl %r9d,%r10d + cmpl $1342177792,%r10d + je .Lavx_shortcut + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + shlq $4,%rdx + subq $128+32,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %rax,152(%rsp) +.cfi_escape 0x0f,0x06,0x77,0x98,0x01,0x06,0x23,0x08 +.Lprologue: + + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp .Lloop + +.align 16 +.Lloop: + movq %rbx,%rdi + leaq K512(%rip),%rbp + xorq %rcx,%rdi + movq 0(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,0(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + addq %r14,%r11 + movq 8(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,8(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + addq %r14,%r10 + movq 16(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,16(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + addq %r14,%r9 + movq 24(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,24(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + addq %r14,%r8 + movq 32(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,32(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + addq %r14,%rdx + movq 40(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,40(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + addq %r14,%rcx + movq 48(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,48(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + addq %r14,%rbx + movq 56(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,56(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + addq %r14,%rax + movq 64(%rsi),%r12 + movq %r8,%r13 + movq %rax,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,64(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + addq %r14,%r11 + movq 72(%rsi),%r12 + movq %rdx,%r13 + movq %r11,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,72(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + addq %r14,%r10 + movq 80(%rsi),%r12 + movq %rcx,%r13 + movq %r10,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,80(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + addq %r14,%r9 + movq 88(%rsi),%r12 + movq %rbx,%r13 + movq %r9,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,88(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + addq %r14,%r8 + movq 96(%rsi),%r12 + movq %rax,%r13 + movq %r8,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,96(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + addq %r14,%rdx + movq 104(%rsi),%r12 + movq %r11,%r13 + movq %rdx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,104(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + addq %r14,%rcx + movq 112(%rsi),%r12 + movq %r10,%r13 + movq %rcx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,112(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + addq %r14,%rbx + movq 120(%rsi),%r12 + movq %r9,%r13 + movq %rbx,%r14 + bswapq %r12 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,120(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + jmp .Lrounds_16_xx +.align 16 +.Lrounds_16_xx: + movq 8(%rsp),%r13 + movq 112(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rax + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 72(%rsp),%r12 + + addq 0(%rsp),%r12 + movq %r8,%r13 + addq %r15,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,0(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + movq 16(%rsp),%r13 + movq 120(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r11 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 80(%rsp),%r12 + + addq 8(%rsp),%r12 + movq %rdx,%r13 + addq %rdi,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,8(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + movq 24(%rsp),%r13 + movq 0(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r10 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 88(%rsp),%r12 + + addq 16(%rsp),%r12 + movq %rcx,%r13 + addq %r15,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,16(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + movq 32(%rsp),%r13 + movq 8(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r9 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 96(%rsp),%r12 + + addq 24(%rsp),%r12 + movq %rbx,%r13 + addq %rdi,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,24(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + movq 40(%rsp),%r13 + movq 16(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r8 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 104(%rsp),%r12 + + addq 32(%rsp),%r12 + movq %rax,%r13 + addq %r15,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,32(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + movq 48(%rsp),%r13 + movq 24(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rdx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 112(%rsp),%r12 + + addq 40(%rsp),%r12 + movq %r11,%r13 + addq %rdi,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,40(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + movq 56(%rsp),%r13 + movq 32(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rcx + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 120(%rsp),%r12 + + addq 48(%rsp),%r12 + movq %r10,%r13 + addq %r15,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,48(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + movq 64(%rsp),%r13 + movq 40(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rbx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 0(%rsp),%r12 + + addq 56(%rsp),%r12 + movq %r9,%r13 + addq %rdi,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,56(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + movq 72(%rsp),%r13 + movq 48(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rax + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 8(%rsp),%r12 + + addq 64(%rsp),%r12 + movq %r8,%r13 + addq %r15,%r12 + movq %rax,%r14 + rorq $23,%r13 + movq %r9,%r15 + + xorq %r8,%r13 + rorq $5,%r14 + xorq %r10,%r15 + + movq %r12,64(%rsp) + xorq %rax,%r14 + andq %r8,%r15 + + rorq $4,%r13 + addq %r11,%r12 + xorq %r10,%r15 + + rorq $6,%r14 + xorq %r8,%r13 + addq %r15,%r12 + + movq %rax,%r15 + addq (%rbp),%r12 + xorq %rax,%r14 + + xorq %rbx,%r15 + rorq $14,%r13 + movq %rbx,%r11 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r11 + addq %r12,%rdx + addq %r12,%r11 + + leaq 8(%rbp),%rbp + movq 80(%rsp),%r13 + movq 56(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r11 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 16(%rsp),%r12 + + addq 72(%rsp),%r12 + movq %rdx,%r13 + addq %rdi,%r12 + movq %r11,%r14 + rorq $23,%r13 + movq %r8,%rdi + + xorq %rdx,%r13 + rorq $5,%r14 + xorq %r9,%rdi + + movq %r12,72(%rsp) + xorq %r11,%r14 + andq %rdx,%rdi + + rorq $4,%r13 + addq %r10,%r12 + xorq %r9,%rdi + + rorq $6,%r14 + xorq %rdx,%r13 + addq %rdi,%r12 + + movq %r11,%rdi + addq (%rbp),%r12 + xorq %r11,%r14 + + xorq %rax,%rdi + rorq $14,%r13 + movq %rax,%r10 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r10 + addq %r12,%rcx + addq %r12,%r10 + + leaq 24(%rbp),%rbp + movq 88(%rsp),%r13 + movq 64(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r10 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 24(%rsp),%r12 + + addq 80(%rsp),%r12 + movq %rcx,%r13 + addq %r15,%r12 + movq %r10,%r14 + rorq $23,%r13 + movq %rdx,%r15 + + xorq %rcx,%r13 + rorq $5,%r14 + xorq %r8,%r15 + + movq %r12,80(%rsp) + xorq %r10,%r14 + andq %rcx,%r15 + + rorq $4,%r13 + addq %r9,%r12 + xorq %r8,%r15 + + rorq $6,%r14 + xorq %rcx,%r13 + addq %r15,%r12 + + movq %r10,%r15 + addq (%rbp),%r12 + xorq %r10,%r14 + + xorq %r11,%r15 + rorq $14,%r13 + movq %r11,%r9 + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%r9 + addq %r12,%rbx + addq %r12,%r9 + + leaq 8(%rbp),%rbp + movq 96(%rsp),%r13 + movq 72(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r9 + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 32(%rsp),%r12 + + addq 88(%rsp),%r12 + movq %rbx,%r13 + addq %rdi,%r12 + movq %r9,%r14 + rorq $23,%r13 + movq %rcx,%rdi + + xorq %rbx,%r13 + rorq $5,%r14 + xorq %rdx,%rdi + + movq %r12,88(%rsp) + xorq %r9,%r14 + andq %rbx,%rdi + + rorq $4,%r13 + addq %r8,%r12 + xorq %rdx,%rdi + + rorq $6,%r14 + xorq %rbx,%r13 + addq %rdi,%r12 + + movq %r9,%rdi + addq (%rbp),%r12 + xorq %r9,%r14 + + xorq %r10,%rdi + rorq $14,%r13 + movq %r10,%r8 + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%r8 + addq %r12,%rax + addq %r12,%r8 + + leaq 24(%rbp),%rbp + movq 104(%rsp),%r13 + movq 80(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%r8 + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 40(%rsp),%r12 + + addq 96(%rsp),%r12 + movq %rax,%r13 + addq %r15,%r12 + movq %r8,%r14 + rorq $23,%r13 + movq %rbx,%r15 + + xorq %rax,%r13 + rorq $5,%r14 + xorq %rcx,%r15 + + movq %r12,96(%rsp) + xorq %r8,%r14 + andq %rax,%r15 + + rorq $4,%r13 + addq %rdx,%r12 + xorq %rcx,%r15 + + rorq $6,%r14 + xorq %rax,%r13 + addq %r15,%r12 + + movq %r8,%r15 + addq (%rbp),%r12 + xorq %r8,%r14 + + xorq %r9,%r15 + rorq $14,%r13 + movq %r9,%rdx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rdx + addq %r12,%r11 + addq %r12,%rdx + + leaq 8(%rbp),%rbp + movq 112(%rsp),%r13 + movq 88(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rdx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 48(%rsp),%r12 + + addq 104(%rsp),%r12 + movq %r11,%r13 + addq %rdi,%r12 + movq %rdx,%r14 + rorq $23,%r13 + movq %rax,%rdi + + xorq %r11,%r13 + rorq $5,%r14 + xorq %rbx,%rdi + + movq %r12,104(%rsp) + xorq %rdx,%r14 + andq %r11,%rdi + + rorq $4,%r13 + addq %rcx,%r12 + xorq %rbx,%rdi + + rorq $6,%r14 + xorq %r11,%r13 + addq %rdi,%r12 + + movq %rdx,%rdi + addq (%rbp),%r12 + xorq %rdx,%r14 + + xorq %r8,%rdi + rorq $14,%r13 + movq %r8,%rcx + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rcx + addq %r12,%r10 + addq %r12,%rcx + + leaq 24(%rbp),%rbp + movq 120(%rsp),%r13 + movq 96(%rsp),%r15 + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rcx + movq %r15,%r14 + rorq $42,%r15 + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%r15 + shrq $6,%r14 + + rorq $19,%r15 + xorq %r13,%r12 + xorq %r14,%r15 + addq 56(%rsp),%r12 + + addq 112(%rsp),%r12 + movq %r10,%r13 + addq %r15,%r12 + movq %rcx,%r14 + rorq $23,%r13 + movq %r11,%r15 + + xorq %r10,%r13 + rorq $5,%r14 + xorq %rax,%r15 + + movq %r12,112(%rsp) + xorq %rcx,%r14 + andq %r10,%r15 + + rorq $4,%r13 + addq %rbx,%r12 + xorq %rax,%r15 + + rorq $6,%r14 + xorq %r10,%r13 + addq %r15,%r12 + + movq %rcx,%r15 + addq (%rbp),%r12 + xorq %rcx,%r14 + + xorq %rdx,%r15 + rorq $14,%r13 + movq %rdx,%rbx + + andq %r15,%rdi + rorq $28,%r14 + addq %r13,%r12 + + xorq %rdi,%rbx + addq %r12,%r9 + addq %r12,%rbx + + leaq 8(%rbp),%rbp + movq 0(%rsp),%r13 + movq 104(%rsp),%rdi + + movq %r13,%r12 + rorq $7,%r13 + addq %r14,%rbx + movq %rdi,%r14 + rorq $42,%rdi + + xorq %r12,%r13 + shrq $7,%r12 + rorq $1,%r13 + xorq %r14,%rdi + shrq $6,%r14 + + rorq $19,%rdi + xorq %r13,%r12 + xorq %r14,%rdi + addq 64(%rsp),%r12 + + addq 120(%rsp),%r12 + movq %r9,%r13 + addq %rdi,%r12 + movq %rbx,%r14 + rorq $23,%r13 + movq %r10,%rdi + + xorq %r9,%r13 + rorq $5,%r14 + xorq %r11,%rdi + + movq %r12,120(%rsp) + xorq %rbx,%r14 + andq %r9,%rdi + + rorq $4,%r13 + addq %rax,%r12 + xorq %r11,%rdi + + rorq $6,%r14 + xorq %r9,%r13 + addq %rdi,%r12 + + movq %rbx,%rdi + addq (%rbp),%r12 + xorq %rbx,%r14 + + xorq %rcx,%rdi + rorq $14,%r13 + movq %rcx,%rax + + andq %rdi,%r15 + rorq $28,%r14 + addq %r13,%r12 + + xorq %r15,%rax + addq %r12,%r8 + addq %r12,%rax + + leaq 24(%rbp),%rbp + cmpb $0,7(%rbp) + jnz .Lrounds_16_xx + + movq 128+0(%rsp),%rdi + addq %r14,%rax + leaq 128(%rsi),%rsi + + addq 0(%rdi),%rax + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb .Lloop + + movq 152(%rsp),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha512_block_data_order,.-sha512_block_data_order +.align 64 +.type K512,@object +K512: +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0x428a2f98d728ae22,0x7137449123ef65cd +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x3956c25bf348b538,0x59f111f1b605d019 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0xd807aa98a3030242,0x12835b0145706fbe +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0x9bdc06a725c71235,0xc19bf174cf692694 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0x983e5152ee66dfab,0xa831c66d2db43210 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x06ca6351e003826f,0x142929670a0e6e70 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x650a73548baf63de,0x766a0abb3c77b2a8 +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0x81c2c92e47edaee6,0x92722c851482353b +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xc24b8b70d0f89791,0xc76c51a30654be30 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xd192e819d6ef5218,0xd69906245565a910 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0xf40e35855771202a,0x106aa07032bbd1b8 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x748f82ee5defb2fc,0x78a5636f43172f60 +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0x90befffa23631e28,0xa4506cebde82bde9 +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xca273eceea26619c,0xd186b8c721c0c207 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x113f9804bef90dae,0x1b710b35131c471b +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x28db77f523047d84,0x32caab7b40c72493 +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 + +.quad 0x0001020304050607,0x08090a0b0c0d0e0f +.quad 0x0001020304050607,0x08090a0b0c0d0e0f +.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.type sha512_block_data_order_xop,@function +.align 64 +sha512_block_data_order_xop: +.cfi_startproc +.Lxop_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + shlq $4,%rdx + subq $160,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %rax,152(%rsp) +.cfi_escape 0x0f,0x06,0x77,0x98,0x01,0x06,0x23,0x08 +.Lprologue_xop: + + vzeroupper + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp .Lloop_xop +.align 16 +.Lloop_xop: + vmovdqa K512+1280(%rip),%xmm11 + vmovdqu 0(%rsi),%xmm0 + leaq K512+128(%rip),%rbp + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vpshufb %xmm11,%xmm0,%xmm0 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm11,%xmm1,%xmm1 + vmovdqu 64(%rsi),%xmm4 + vpshufb %xmm11,%xmm2,%xmm2 + vmovdqu 80(%rsi),%xmm5 + vpshufb %xmm11,%xmm3,%xmm3 + vmovdqu 96(%rsi),%xmm6 + vpshufb %xmm11,%xmm4,%xmm4 + vmovdqu 112(%rsi),%xmm7 + vpshufb %xmm11,%xmm5,%xmm5 + vpaddq -128(%rbp),%xmm0,%xmm8 + vpshufb %xmm11,%xmm6,%xmm6 + vpaddq -96(%rbp),%xmm1,%xmm9 + vpshufb %xmm11,%xmm7,%xmm7 + vpaddq -64(%rbp),%xmm2,%xmm10 + vpaddq -32(%rbp),%xmm3,%xmm11 + vmovdqa %xmm8,0(%rsp) + vpaddq 0(%rbp),%xmm4,%xmm8 + vmovdqa %xmm9,16(%rsp) + vpaddq 32(%rbp),%xmm5,%xmm9 + vmovdqa %xmm10,32(%rsp) + vpaddq 64(%rbp),%xmm6,%xmm10 + vmovdqa %xmm11,48(%rsp) + vpaddq 96(%rbp),%xmm7,%xmm11 + vmovdqa %xmm8,64(%rsp) + movq %rax,%r14 + vmovdqa %xmm9,80(%rsp) + movq %rbx,%rdi + vmovdqa %xmm10,96(%rsp) + xorq %rcx,%rdi + vmovdqa %xmm11,112(%rsp) + movq %r8,%r13 + jmp .Lxop_00_47 + +.align 16 +.Lxop_00_47: + addq $256,%rbp + vpalignr $8,%xmm0,%xmm1,%xmm8 + rorq $23,%r13 + movq %r14,%rax + vpalignr $8,%xmm4,%xmm5,%xmm11 + movq %r9,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r8,%r13 + xorq %r10,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rax,%r14 + vpaddq %xmm11,%xmm0,%xmm0 + andq %r8,%r12 + xorq %r8,%r13 + addq 0(%rsp),%r11 + movq %rax,%r15 +.byte 143,72,120,195,209,7 + xorq %r10,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,223,3 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm7,%xmm10 + addq %r11,%rdx + addq %rdi,%r11 + vpaddq %xmm8,%xmm0,%xmm0 + movq %rdx,%r13 + addq %r11,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r11 + vpxor %xmm10,%xmm11,%xmm11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + vpaddq %xmm11,%xmm0,%xmm0 + addq 8(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + vpaddq -128(%rbp),%xmm0,%xmm10 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,0(%rsp) + vpalignr $8,%xmm1,%xmm2,%xmm8 + rorq $23,%r13 + movq %r14,%r10 + vpalignr $8,%xmm5,%xmm6,%xmm11 + movq %rdx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rcx,%r13 + xorq %r8,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r10,%r14 + vpaddq %xmm11,%xmm1,%xmm1 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 16(%rsp),%r9 + movq %r10,%r15 +.byte 143,72,120,195,209,7 + xorq %r8,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,216,3 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm0,%xmm10 + addq %r9,%rbx + addq %rdi,%r9 + vpaddq %xmm8,%xmm1,%xmm1 + movq %rbx,%r13 + addq %r9,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r9 + vpxor %xmm10,%xmm11,%xmm11 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + vpaddq %xmm11,%xmm1,%xmm1 + addq 24(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + vpaddq -96(%rbp),%xmm1,%xmm10 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,16(%rsp) + vpalignr $8,%xmm2,%xmm3,%xmm8 + rorq $23,%r13 + movq %r14,%r8 + vpalignr $8,%xmm6,%xmm7,%xmm11 + movq %rbx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rax,%r13 + xorq %rcx,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r8,%r14 + vpaddq %xmm11,%xmm2,%xmm2 + andq %rax,%r12 + xorq %rax,%r13 + addq 32(%rsp),%rdx + movq %r8,%r15 +.byte 143,72,120,195,209,7 + xorq %rcx,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,217,3 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm1,%xmm10 + addq %rdx,%r11 + addq %rdi,%rdx + vpaddq %xmm8,%xmm2,%xmm2 + movq %r11,%r13 + addq %rdx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rdx + vpxor %xmm10,%xmm11,%xmm11 + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + vpaddq %xmm11,%xmm2,%xmm2 + addq 40(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + vpaddq -64(%rbp),%xmm2,%xmm10 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,32(%rsp) + vpalignr $8,%xmm3,%xmm4,%xmm8 + rorq $23,%r13 + movq %r14,%rcx + vpalignr $8,%xmm7,%xmm0,%xmm11 + movq %r11,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r10,%r13 + xorq %rax,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rcx,%r14 + vpaddq %xmm11,%xmm3,%xmm3 + andq %r10,%r12 + xorq %r10,%r13 + addq 48(%rsp),%rbx + movq %rcx,%r15 +.byte 143,72,120,195,209,7 + xorq %rax,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,218,3 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm2,%xmm10 + addq %rbx,%r9 + addq %rdi,%rbx + vpaddq %xmm8,%xmm3,%xmm3 + movq %r9,%r13 + addq %rbx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rbx + vpxor %xmm10,%xmm11,%xmm11 + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + vpaddq %xmm11,%xmm3,%xmm3 + addq 56(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + vpaddq -32(%rbp),%xmm3,%xmm10 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,48(%rsp) + vpalignr $8,%xmm4,%xmm5,%xmm8 + rorq $23,%r13 + movq %r14,%rax + vpalignr $8,%xmm0,%xmm1,%xmm11 + movq %r9,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r8,%r13 + xorq %r10,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rax,%r14 + vpaddq %xmm11,%xmm4,%xmm4 + andq %r8,%r12 + xorq %r8,%r13 + addq 64(%rsp),%r11 + movq %rax,%r15 +.byte 143,72,120,195,209,7 + xorq %r10,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,219,3 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm3,%xmm10 + addq %r11,%rdx + addq %rdi,%r11 + vpaddq %xmm8,%xmm4,%xmm4 + movq %rdx,%r13 + addq %r11,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r11 + vpxor %xmm10,%xmm11,%xmm11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + vpaddq %xmm11,%xmm4,%xmm4 + addq 72(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + vpaddq 0(%rbp),%xmm4,%xmm10 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,64(%rsp) + vpalignr $8,%xmm5,%xmm6,%xmm8 + rorq $23,%r13 + movq %r14,%r10 + vpalignr $8,%xmm1,%xmm2,%xmm11 + movq %rdx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rcx,%r13 + xorq %r8,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r10,%r14 + vpaddq %xmm11,%xmm5,%xmm5 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 80(%rsp),%r9 + movq %r10,%r15 +.byte 143,72,120,195,209,7 + xorq %r8,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,220,3 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm4,%xmm10 + addq %r9,%rbx + addq %rdi,%r9 + vpaddq %xmm8,%xmm5,%xmm5 + movq %rbx,%r13 + addq %r9,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%r9 + vpxor %xmm10,%xmm11,%xmm11 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + vpaddq %xmm11,%xmm5,%xmm5 + addq 88(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + vpaddq 32(%rbp),%xmm5,%xmm10 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,80(%rsp) + vpalignr $8,%xmm6,%xmm7,%xmm8 + rorq $23,%r13 + movq %r14,%r8 + vpalignr $8,%xmm2,%xmm3,%xmm11 + movq %rbx,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %rax,%r13 + xorq %rcx,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %r8,%r14 + vpaddq %xmm11,%xmm6,%xmm6 + andq %rax,%r12 + xorq %rax,%r13 + addq 96(%rsp),%rdx + movq %r8,%r15 +.byte 143,72,120,195,209,7 + xorq %rcx,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,221,3 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm5,%xmm10 + addq %rdx,%r11 + addq %rdi,%rdx + vpaddq %xmm8,%xmm6,%xmm6 + movq %r11,%r13 + addq %rdx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rdx + vpxor %xmm10,%xmm11,%xmm11 + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + vpaddq %xmm11,%xmm6,%xmm6 + addq 104(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + vpaddq 64(%rbp),%xmm6,%xmm10 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,96(%rsp) + vpalignr $8,%xmm7,%xmm0,%xmm8 + rorq $23,%r13 + movq %r14,%rcx + vpalignr $8,%xmm3,%xmm4,%xmm11 + movq %r11,%r12 + rorq $5,%r14 +.byte 143,72,120,195,200,56 + xorq %r10,%r13 + xorq %rax,%r12 + vpsrlq $7,%xmm8,%xmm8 + rorq $4,%r13 + xorq %rcx,%r14 + vpaddq %xmm11,%xmm7,%xmm7 + andq %r10,%r12 + xorq %r10,%r13 + addq 112(%rsp),%rbx + movq %rcx,%r15 +.byte 143,72,120,195,209,7 + xorq %rax,%r12 + rorq $6,%r14 + vpxor %xmm9,%xmm8,%xmm8 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi +.byte 143,104,120,195,222,3 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + rorq $28,%r14 + vpsrlq $6,%xmm6,%xmm10 + addq %rbx,%r9 + addq %rdi,%rbx + vpaddq %xmm8,%xmm7,%xmm7 + movq %r9,%r13 + addq %rbx,%r14 +.byte 143,72,120,195,203,42 + rorq $23,%r13 + movq %r14,%rbx + vpxor %xmm10,%xmm11,%xmm11 + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm9,%xmm11,%xmm11 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + vpaddq %xmm11,%xmm7,%xmm7 + addq 120(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + vpaddq 96(%rbp),%xmm7,%xmm10 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,112(%rsp) + cmpb $0,135(%rbp) + jne .Lxop_00_47 + rorq $23,%r13 + movq %r14,%rax + movq %r9,%r12 + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + rorq $4,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 0(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + rorq $6,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + rorq $28,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + rorq $23,%r13 + movq %r14,%r11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 8(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + rorq $23,%r13 + movq %r14,%r10 + movq %rdx,%r12 + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + rorq $4,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 16(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + rorq $6,%r14 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + rorq $28,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + rorq $23,%r13 + movq %r14,%r9 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 24(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + rorq $23,%r13 + movq %r14,%r8 + movq %rbx,%r12 + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + rorq $4,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 32(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + rorq $6,%r14 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + rorq $28,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + rorq $23,%r13 + movq %r14,%rdx + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 40(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + rorq $23,%r13 + movq %r14,%rcx + movq %r11,%r12 + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + rorq $4,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 48(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + rorq $6,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + rorq $28,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + rorq $23,%r13 + movq %r14,%rbx + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 56(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + rorq $23,%r13 + movq %r14,%rax + movq %r9,%r12 + rorq $5,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + rorq $4,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 64(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + rorq $6,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + rorq $14,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + rorq $28,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + rorq $23,%r13 + movq %r14,%r11 + movq %r8,%r12 + rorq $5,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + rorq $4,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 72(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + rorq $6,%r14 + xorq %rax,%rdi + addq %r12,%r10 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + rorq $28,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + rorq $23,%r13 + movq %r14,%r10 + movq %rdx,%r12 + rorq $5,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + rorq $4,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 80(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + rorq $6,%r14 + xorq %r11,%r15 + addq %r12,%r9 + rorq $14,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + rorq $28,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + rorq $23,%r13 + movq %r14,%r9 + movq %rcx,%r12 + rorq $5,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + rorq $4,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 88(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + rorq $6,%r14 + xorq %r10,%rdi + addq %r12,%r8 + rorq $14,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + rorq $28,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + rorq $23,%r13 + movq %r14,%r8 + movq %rbx,%r12 + rorq $5,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + rorq $4,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 96(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + rorq $6,%r14 + xorq %r9,%r15 + addq %r12,%rdx + rorq $14,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + rorq $28,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + rorq $23,%r13 + movq %r14,%rdx + movq %rax,%r12 + rorq $5,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + rorq $4,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 104(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + rorq $6,%r14 + xorq %r8,%rdi + addq %r12,%rcx + rorq $14,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + rorq $28,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + rorq $23,%r13 + movq %r14,%rcx + movq %r11,%r12 + rorq $5,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + rorq $4,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 112(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + rorq $6,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + rorq $14,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + rorq $28,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + rorq $23,%r13 + movq %r14,%rbx + movq %r10,%r12 + rorq $5,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + rorq $4,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 120(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + rorq $6,%r14 + xorq %rcx,%rdi + addq %r12,%rax + rorq $14,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + rorq $28,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + movq 128+0(%rsp),%rdi + movq %r14,%rax + + addq 0(%rdi),%rax + leaq 128(%rsi),%rsi + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb .Lloop_xop + + movq 152(%rsp),%rsi +.cfi_def_cfa %rsi,8 + vzeroupper + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_xop: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha512_block_data_order_xop,.-sha512_block_data_order_xop +.type sha512_block_data_order_avx,@function +.align 64 +sha512_block_data_order_avx: +.cfi_startproc +.Lavx_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + shlq $4,%rdx + subq $160,%rsp + leaq (%rsi,%rdx,8),%rdx + andq $-64,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %rax,152(%rsp) +.cfi_escape 0x0f,0x06,0x77,0x98,0x01,0x06,0x23,0x08 +.Lprologue_avx: + + vzeroupper + movq 0(%rdi),%rax + movq 8(%rdi),%rbx + movq 16(%rdi),%rcx + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp .Lloop_avx +.align 16 +.Lloop_avx: + vmovdqa K512+1280(%rip),%xmm11 + vmovdqu 0(%rsi),%xmm0 + leaq K512+128(%rip),%rbp + vmovdqu 16(%rsi),%xmm1 + vmovdqu 32(%rsi),%xmm2 + vpshufb %xmm11,%xmm0,%xmm0 + vmovdqu 48(%rsi),%xmm3 + vpshufb %xmm11,%xmm1,%xmm1 + vmovdqu 64(%rsi),%xmm4 + vpshufb %xmm11,%xmm2,%xmm2 + vmovdqu 80(%rsi),%xmm5 + vpshufb %xmm11,%xmm3,%xmm3 + vmovdqu 96(%rsi),%xmm6 + vpshufb %xmm11,%xmm4,%xmm4 + vmovdqu 112(%rsi),%xmm7 + vpshufb %xmm11,%xmm5,%xmm5 + vpaddq -128(%rbp),%xmm0,%xmm8 + vpshufb %xmm11,%xmm6,%xmm6 + vpaddq -96(%rbp),%xmm1,%xmm9 + vpshufb %xmm11,%xmm7,%xmm7 + vpaddq -64(%rbp),%xmm2,%xmm10 + vpaddq -32(%rbp),%xmm3,%xmm11 + vmovdqa %xmm8,0(%rsp) + vpaddq 0(%rbp),%xmm4,%xmm8 + vmovdqa %xmm9,16(%rsp) + vpaddq 32(%rbp),%xmm5,%xmm9 + vmovdqa %xmm10,32(%rsp) + vpaddq 64(%rbp),%xmm6,%xmm10 + vmovdqa %xmm11,48(%rsp) + vpaddq 96(%rbp),%xmm7,%xmm11 + vmovdqa %xmm8,64(%rsp) + movq %rax,%r14 + vmovdqa %xmm9,80(%rsp) + movq %rbx,%rdi + vmovdqa %xmm10,96(%rsp) + xorq %rcx,%rdi + vmovdqa %xmm11,112(%rsp) + movq %r8,%r13 + jmp .Lavx_00_47 + +.align 16 +.Lavx_00_47: + addq $256,%rbp + vpalignr $8,%xmm0,%xmm1,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rax + vpalignr $8,%xmm4,%xmm5,%xmm11 + movq %r9,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r8,%r13 + xorq %r10,%r12 + vpaddq %xmm11,%xmm0,%xmm0 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r8,%r12 + xorq %r8,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 0(%rsp),%r11 + movq %rax,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rbx,%r15 + addq %r12,%r11 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm7,%xmm11 + addq %r11,%rdx + addq %rdi,%r11 + vpxor %xmm9,%xmm8,%xmm8 + movq %rdx,%r13 + addq %r11,%r14 + vpsllq $3,%xmm7,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r11 + vpaddq %xmm8,%xmm0,%xmm0 + movq %r8,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm7,%xmm9 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rdx,%r12 + xorq %rdx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 8(%rsp),%r10 + movq %r11,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r9,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rax,%rdi + addq %r12,%r10 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm0,%xmm0 + xorq %r11,%r14 + addq %r13,%r10 + vpaddq -128(%rbp),%xmm0,%xmm10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,0(%rsp) + vpalignr $8,%xmm1,%xmm2,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r10 + vpalignr $8,%xmm5,%xmm6,%xmm11 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rcx,%r13 + xorq %r8,%r12 + vpaddq %xmm11,%xmm1,%xmm1 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rcx,%r12 + xorq %rcx,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 16(%rsp),%r9 + movq %r10,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r11,%r15 + addq %r12,%r9 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm0,%xmm11 + addq %r9,%rbx + addq %rdi,%r9 + vpxor %xmm9,%xmm8,%xmm8 + movq %rbx,%r13 + addq %r9,%r14 + vpsllq $3,%xmm0,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r9 + vpaddq %xmm8,%xmm1,%xmm1 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm0,%xmm9 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rbx,%r12 + xorq %rbx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 24(%rsp),%r8 + movq %r9,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r10,%rdi + addq %r12,%r8 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm1,%xmm1 + xorq %r9,%r14 + addq %r13,%r8 + vpaddq -96(%rbp),%xmm1,%xmm10 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,16(%rsp) + vpalignr $8,%xmm2,%xmm3,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r8 + vpalignr $8,%xmm6,%xmm7,%xmm11 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rax,%r13 + xorq %rcx,%r12 + vpaddq %xmm11,%xmm2,%xmm2 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rax,%r12 + xorq %rax,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 32(%rsp),%rdx + movq %r8,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r9,%r15 + addq %r12,%rdx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm1,%xmm11 + addq %rdx,%r11 + addq %rdi,%rdx + vpxor %xmm9,%xmm8,%xmm8 + movq %r11,%r13 + addq %rdx,%r14 + vpsllq $3,%xmm1,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rdx + vpaddq %xmm8,%xmm2,%xmm2 + movq %rax,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm1,%xmm9 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r11,%r12 + xorq %r11,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 40(%rsp),%rcx + movq %rdx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r8,%rdi + addq %r12,%rcx + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm2,%xmm2 + xorq %rdx,%r14 + addq %r13,%rcx + vpaddq -64(%rbp),%xmm2,%xmm10 + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,32(%rsp) + vpalignr $8,%xmm3,%xmm4,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rcx + vpalignr $8,%xmm7,%xmm0,%xmm11 + movq %r11,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r10,%r13 + xorq %rax,%r12 + vpaddq %xmm11,%xmm3,%xmm3 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r10,%r12 + xorq %r10,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 48(%rsp),%rbx + movq %rcx,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rdx,%r15 + addq %r12,%rbx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm2,%xmm11 + addq %rbx,%r9 + addq %rdi,%rbx + vpxor %xmm9,%xmm8,%xmm8 + movq %r9,%r13 + addq %rbx,%r14 + vpsllq $3,%xmm2,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rbx + vpaddq %xmm8,%xmm3,%xmm3 + movq %r10,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm2,%xmm9 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r9,%r12 + xorq %r9,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 56(%rsp),%rax + movq %rbx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r11,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rcx,%rdi + addq %r12,%rax + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm3,%xmm3 + xorq %rbx,%r14 + addq %r13,%rax + vpaddq -32(%rbp),%xmm3,%xmm10 + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,48(%rsp) + vpalignr $8,%xmm4,%xmm5,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rax + vpalignr $8,%xmm0,%xmm1,%xmm11 + movq %r9,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r8,%r13 + xorq %r10,%r12 + vpaddq %xmm11,%xmm4,%xmm4 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r8,%r12 + xorq %r8,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 64(%rsp),%r11 + movq %rax,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rbx,%r15 + addq %r12,%r11 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rax,%r14 + addq %r13,%r11 + vpxor %xmm10,%xmm8,%xmm8 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm3,%xmm11 + addq %r11,%rdx + addq %rdi,%r11 + vpxor %xmm9,%xmm8,%xmm8 + movq %rdx,%r13 + addq %r11,%r14 + vpsllq $3,%xmm3,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r11 + vpaddq %xmm8,%xmm4,%xmm4 + movq %r8,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm3,%xmm9 + xorq %rdx,%r13 + xorq %r9,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rdx,%r12 + xorq %rdx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 72(%rsp),%r10 + movq %r11,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r9,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rax,%rdi + addq %r12,%r10 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm4,%xmm4 + xorq %r11,%r14 + addq %r13,%r10 + vpaddq 0(%rbp),%xmm4,%xmm10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + vmovdqa %xmm10,64(%rsp) + vpalignr $8,%xmm5,%xmm6,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r10 + vpalignr $8,%xmm1,%xmm2,%xmm11 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rcx,%r13 + xorq %r8,%r12 + vpaddq %xmm11,%xmm5,%xmm5 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rcx,%r12 + xorq %rcx,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 80(%rsp),%r9 + movq %r10,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r11,%r15 + addq %r12,%r9 + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r10,%r14 + addq %r13,%r9 + vpxor %xmm10,%xmm8,%xmm8 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm4,%xmm11 + addq %r9,%rbx + addq %rdi,%r9 + vpxor %xmm9,%xmm8,%xmm8 + movq %rbx,%r13 + addq %r9,%r14 + vpsllq $3,%xmm4,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%r9 + vpaddq %xmm8,%xmm5,%xmm5 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm4,%xmm9 + xorq %rbx,%r13 + xorq %rdx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %rbx,%r12 + xorq %rbx,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 88(%rsp),%r8 + movq %r9,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r10,%rdi + addq %r12,%r8 + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm5,%xmm5 + xorq %r9,%r14 + addq %r13,%r8 + vpaddq 32(%rbp),%xmm5,%xmm10 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + vmovdqa %xmm10,80(%rsp) + vpalignr $8,%xmm6,%xmm7,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%r8 + vpalignr $8,%xmm2,%xmm3,%xmm11 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %rax,%r13 + xorq %rcx,%r12 + vpaddq %xmm11,%xmm6,%xmm6 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %rax,%r12 + xorq %rax,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 96(%rsp),%rdx + movq %r8,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %r9,%r15 + addq %r12,%rdx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %r8,%r14 + addq %r13,%rdx + vpxor %xmm10,%xmm8,%xmm8 + xorq %r9,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm5,%xmm11 + addq %rdx,%r11 + addq %rdi,%rdx + vpxor %xmm9,%xmm8,%xmm8 + movq %r11,%r13 + addq %rdx,%r14 + vpsllq $3,%xmm5,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rdx + vpaddq %xmm8,%xmm6,%xmm6 + movq %rax,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm5,%xmm9 + xorq %r11,%r13 + xorq %rbx,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r11,%r12 + xorq %r11,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 104(%rsp),%rcx + movq %rdx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %r8,%rdi + addq %r12,%rcx + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm6,%xmm6 + xorq %rdx,%r14 + addq %r13,%rcx + vpaddq 64(%rbp),%xmm6,%xmm10 + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + vmovdqa %xmm10,96(%rsp) + vpalignr $8,%xmm7,%xmm0,%xmm8 + shrdq $23,%r13,%r13 + movq %r14,%rcx + vpalignr $8,%xmm3,%xmm4,%xmm11 + movq %r11,%r12 + shrdq $5,%r14,%r14 + vpsrlq $1,%xmm8,%xmm10 + xorq %r10,%r13 + xorq %rax,%r12 + vpaddq %xmm11,%xmm7,%xmm7 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + vpsrlq $7,%xmm8,%xmm11 + andq %r10,%r12 + xorq %r10,%r13 + vpsllq $56,%xmm8,%xmm9 + addq 112(%rsp),%rbx + movq %rcx,%r15 + vpxor %xmm10,%xmm11,%xmm8 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + vpsrlq $7,%xmm10,%xmm10 + xorq %rdx,%r15 + addq %r12,%rbx + vpxor %xmm9,%xmm8,%xmm8 + shrdq $14,%r13,%r13 + andq %r15,%rdi + vpsllq $7,%xmm9,%xmm9 + xorq %rcx,%r14 + addq %r13,%rbx + vpxor %xmm10,%xmm8,%xmm8 + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + vpsrlq $6,%xmm6,%xmm11 + addq %rbx,%r9 + addq %rdi,%rbx + vpxor %xmm9,%xmm8,%xmm8 + movq %r9,%r13 + addq %rbx,%r14 + vpsllq $3,%xmm6,%xmm10 + shrdq $23,%r13,%r13 + movq %r14,%rbx + vpaddq %xmm8,%xmm7,%xmm7 + movq %r10,%r12 + shrdq $5,%r14,%r14 + vpsrlq $19,%xmm6,%xmm9 + xorq %r9,%r13 + xorq %r11,%r12 + vpxor %xmm10,%xmm11,%xmm11 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + vpsllq $42,%xmm10,%xmm10 + andq %r9,%r12 + xorq %r9,%r13 + vpxor %xmm9,%xmm11,%xmm11 + addq 120(%rsp),%rax + movq %rbx,%rdi + vpsrlq $42,%xmm9,%xmm9 + xorq %r11,%r12 + shrdq $6,%r14,%r14 + vpxor %xmm10,%xmm11,%xmm11 + xorq %rcx,%rdi + addq %r12,%rax + vpxor %xmm9,%xmm11,%xmm11 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + vpaddq %xmm11,%xmm7,%xmm7 + xorq %rbx,%r14 + addq %r13,%rax + vpaddq 96(%rbp),%xmm7,%xmm10 + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + vmovdqa %xmm10,112(%rsp) + cmpb $0,135(%rbp) + jne .Lavx_00_47 + shrdq $23,%r13,%r13 + movq %r14,%rax + movq %r9,%r12 + shrdq $5,%r14,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 0(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r11 + movq %r8,%r12 + shrdq $5,%r14,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 8(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + shrdq $6,%r14,%r14 + xorq %rax,%rdi + addq %r12,%r10 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r10 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 16(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + xorq %r11,%r15 + addq %r12,%r9 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r9 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 24(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + xorq %r10,%rdi + addq %r12,%r8 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r8 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 32(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + xorq %r9,%r15 + addq %r12,%rdx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + shrdq $28,%r14,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rdx + movq %rax,%r12 + shrdq $5,%r14,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 40(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + xorq %r8,%rdi + addq %r12,%rcx + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rcx + movq %r11,%r12 + shrdq $5,%r14,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 48(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rbx + movq %r10,%r12 + shrdq $5,%r14,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 56(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + shrdq $6,%r14,%r14 + xorq %rcx,%rdi + addq %r12,%rax + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rax + movq %r9,%r12 + shrdq $5,%r14,%r14 + xorq %r8,%r13 + xorq %r10,%r12 + shrdq $4,%r13,%r13 + xorq %rax,%r14 + andq %r8,%r12 + xorq %r8,%r13 + addq 64(%rsp),%r11 + movq %rax,%r15 + xorq %r10,%r12 + shrdq $6,%r14,%r14 + xorq %rbx,%r15 + addq %r12,%r11 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rax,%r14 + addq %r13,%r11 + xorq %rbx,%rdi + shrdq $28,%r14,%r14 + addq %r11,%rdx + addq %rdi,%r11 + movq %rdx,%r13 + addq %r11,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r11 + movq %r8,%r12 + shrdq $5,%r14,%r14 + xorq %rdx,%r13 + xorq %r9,%r12 + shrdq $4,%r13,%r13 + xorq %r11,%r14 + andq %rdx,%r12 + xorq %rdx,%r13 + addq 72(%rsp),%r10 + movq %r11,%rdi + xorq %r9,%r12 + shrdq $6,%r14,%r14 + xorq %rax,%rdi + addq %r12,%r10 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r11,%r14 + addq %r13,%r10 + xorq %rax,%r15 + shrdq $28,%r14,%r14 + addq %r10,%rcx + addq %r15,%r10 + movq %rcx,%r13 + addq %r10,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r10 + movq %rdx,%r12 + shrdq $5,%r14,%r14 + xorq %rcx,%r13 + xorq %r8,%r12 + shrdq $4,%r13,%r13 + xorq %r10,%r14 + andq %rcx,%r12 + xorq %rcx,%r13 + addq 80(%rsp),%r9 + movq %r10,%r15 + xorq %r8,%r12 + shrdq $6,%r14,%r14 + xorq %r11,%r15 + addq %r12,%r9 + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r10,%r14 + addq %r13,%r9 + xorq %r11,%rdi + shrdq $28,%r14,%r14 + addq %r9,%rbx + addq %rdi,%r9 + movq %rbx,%r13 + addq %r9,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r9 + movq %rcx,%r12 + shrdq $5,%r14,%r14 + xorq %rbx,%r13 + xorq %rdx,%r12 + shrdq $4,%r13,%r13 + xorq %r9,%r14 + andq %rbx,%r12 + xorq %rbx,%r13 + addq 88(%rsp),%r8 + movq %r9,%rdi + xorq %rdx,%r12 + shrdq $6,%r14,%r14 + xorq %r10,%rdi + addq %r12,%r8 + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %r9,%r14 + addq %r13,%r8 + xorq %r10,%r15 + shrdq $28,%r14,%r14 + addq %r8,%rax + addq %r15,%r8 + movq %rax,%r13 + addq %r8,%r14 + shrdq $23,%r13,%r13 + movq %r14,%r8 + movq %rbx,%r12 + shrdq $5,%r14,%r14 + xorq %rax,%r13 + xorq %rcx,%r12 + shrdq $4,%r13,%r13 + xorq %r8,%r14 + andq %rax,%r12 + xorq %rax,%r13 + addq 96(%rsp),%rdx + movq %r8,%r15 + xorq %rcx,%r12 + shrdq $6,%r14,%r14 + xorq %r9,%r15 + addq %r12,%rdx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %r8,%r14 + addq %r13,%rdx + xorq %r9,%rdi + shrdq $28,%r14,%r14 + addq %rdx,%r11 + addq %rdi,%rdx + movq %r11,%r13 + addq %rdx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rdx + movq %rax,%r12 + shrdq $5,%r14,%r14 + xorq %r11,%r13 + xorq %rbx,%r12 + shrdq $4,%r13,%r13 + xorq %rdx,%r14 + andq %r11,%r12 + xorq %r11,%r13 + addq 104(%rsp),%rcx + movq %rdx,%rdi + xorq %rbx,%r12 + shrdq $6,%r14,%r14 + xorq %r8,%rdi + addq %r12,%rcx + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rdx,%r14 + addq %r13,%rcx + xorq %r8,%r15 + shrdq $28,%r14,%r14 + addq %rcx,%r10 + addq %r15,%rcx + movq %r10,%r13 + addq %rcx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rcx + movq %r11,%r12 + shrdq $5,%r14,%r14 + xorq %r10,%r13 + xorq %rax,%r12 + shrdq $4,%r13,%r13 + xorq %rcx,%r14 + andq %r10,%r12 + xorq %r10,%r13 + addq 112(%rsp),%rbx + movq %rcx,%r15 + xorq %rax,%r12 + shrdq $6,%r14,%r14 + xorq %rdx,%r15 + addq %r12,%rbx + shrdq $14,%r13,%r13 + andq %r15,%rdi + xorq %rcx,%r14 + addq %r13,%rbx + xorq %rdx,%rdi + shrdq $28,%r14,%r14 + addq %rbx,%r9 + addq %rdi,%rbx + movq %r9,%r13 + addq %rbx,%r14 + shrdq $23,%r13,%r13 + movq %r14,%rbx + movq %r10,%r12 + shrdq $5,%r14,%r14 + xorq %r9,%r13 + xorq %r11,%r12 + shrdq $4,%r13,%r13 + xorq %rbx,%r14 + andq %r9,%r12 + xorq %r9,%r13 + addq 120(%rsp),%rax + movq %rbx,%rdi + xorq %r11,%r12 + shrdq $6,%r14,%r14 + xorq %rcx,%rdi + addq %r12,%rax + shrdq $14,%r13,%r13 + andq %rdi,%r15 + xorq %rbx,%r14 + addq %r13,%rax + xorq %rcx,%r15 + shrdq $28,%r14,%r14 + addq %rax,%r8 + addq %r15,%rax + movq %r8,%r13 + addq %rax,%r14 + movq 128+0(%rsp),%rdi + movq %r14,%rax + + addq 0(%rdi),%rax + leaq 128(%rsi),%rsi + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + jb .Lloop_avx + + movq 152(%rsp),%rsi +.cfi_def_cfa %rsi,8 + vzeroupper + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha512_block_data_order_avx,.-sha512_block_data_order_avx +.type sha512_block_data_order_avx2,@function +.align 64 +sha512_block_data_order_avx2: +.cfi_startproc +.Lavx2_shortcut: + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + subq $1312,%rsp + shlq $4,%rdx + andq $-2048,%rsp + leaq (%rsi,%rdx,8),%rdx + addq $1152,%rsp + movq %rdi,128+0(%rsp) + movq %rsi,128+8(%rsp) + movq %rdx,128+16(%rsp) + movq %rax,152(%rsp) +.cfi_escape 0x0f,0x06,0x77,0x98,0x01,0x06,0x23,0x08 +.Lprologue_avx2: + + vzeroupper + subq $-128,%rsi + movq 0(%rdi),%rax + movq %rsi,%r12 + movq 8(%rdi),%rbx + cmpq %rdx,%rsi + movq 16(%rdi),%rcx + cmoveq %rsp,%r12 + movq 24(%rdi),%rdx + movq 32(%rdi),%r8 + movq 40(%rdi),%r9 + movq 48(%rdi),%r10 + movq 56(%rdi),%r11 + jmp .Loop_avx2 +.align 16 +.Loop_avx2: + vmovdqu -128(%rsi),%xmm0 + vmovdqu -128+16(%rsi),%xmm1 + vmovdqu -128+32(%rsi),%xmm2 + leaq K512+128(%rip),%rbp + vmovdqu -128+48(%rsi),%xmm3 + vmovdqu -128+64(%rsi),%xmm4 + vmovdqu -128+80(%rsi),%xmm5 + vmovdqu -128+96(%rsi),%xmm6 + vmovdqu -128+112(%rsi),%xmm7 + + vmovdqa 1152(%rbp),%ymm10 + vinserti128 $1,(%r12),%ymm0,%ymm0 + vinserti128 $1,16(%r12),%ymm1,%ymm1 + vpshufb %ymm10,%ymm0,%ymm0 + vinserti128 $1,32(%r12),%ymm2,%ymm2 + vpshufb %ymm10,%ymm1,%ymm1 + vinserti128 $1,48(%r12),%ymm3,%ymm3 + vpshufb %ymm10,%ymm2,%ymm2 + vinserti128 $1,64(%r12),%ymm4,%ymm4 + vpshufb %ymm10,%ymm3,%ymm3 + vinserti128 $1,80(%r12),%ymm5,%ymm5 + vpshufb %ymm10,%ymm4,%ymm4 + vinserti128 $1,96(%r12),%ymm6,%ymm6 + vpshufb %ymm10,%ymm5,%ymm5 + vinserti128 $1,112(%r12),%ymm7,%ymm7 + + vpaddq -128(%rbp),%ymm0,%ymm8 + vpshufb %ymm10,%ymm6,%ymm6 + vpaddq -96(%rbp),%ymm1,%ymm9 + vpshufb %ymm10,%ymm7,%ymm7 + vpaddq -64(%rbp),%ymm2,%ymm10 + vpaddq -32(%rbp),%ymm3,%ymm11 + vmovdqa %ymm8,0(%rsp) + vpaddq 0(%rbp),%ymm4,%ymm8 + vmovdqa %ymm9,32(%rsp) + vpaddq 32(%rbp),%ymm5,%ymm9 + vmovdqa %ymm10,64(%rsp) + vpaddq 64(%rbp),%ymm6,%ymm10 + vmovdqa %ymm11,96(%rsp) + + movq 152(%rsp),%rdi +.cfi_def_cfa %rdi,8 + leaq -128(%rsp),%rsp + + + + movq %rdi,-8(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x78,0x06,0x23,0x08 + vpaddq 96(%rbp),%ymm7,%ymm11 + vmovdqa %ymm8,0(%rsp) + xorq %r14,%r14 + vmovdqa %ymm9,32(%rsp) + movq %rbx,%rdi + vmovdqa %ymm10,64(%rsp) + xorq %rcx,%rdi + vmovdqa %ymm11,96(%rsp) + movq %r9,%r12 + addq $32*8,%rbp + jmp .Lavx2_00_47 + +.align 16 +.Lavx2_00_47: + leaq -128(%rsp),%rsp +.cfi_escape 0x0f,0x06,0x77,0xf8,0x00,0x06,0x23,0x08 + + pushq 128-8(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x00,0x06,0x23,0x08 + leaq 8(%rsp),%rsp +.cfi_escape 0x0f,0x05,0x77,0x78,0x06,0x23,0x08 + vpalignr $8,%ymm0,%ymm1,%ymm8 + addq 0+256(%rsp),%r11 + andq %r8,%r12 + rorxq $41,%r8,%r13 + vpalignr $8,%ymm4,%ymm5,%ymm11 + rorxq $18,%r8,%r15 + leaq (%rax,%r14,1),%rax + leaq (%r11,%r12,1),%r11 + vpsrlq $1,%ymm8,%ymm10 + andnq %r10,%r8,%r12 + xorq %r15,%r13 + rorxq $14,%r8,%r14 + vpaddq %ymm11,%ymm0,%ymm0 + vpsrlq $7,%ymm8,%ymm11 + leaq (%r11,%r12,1),%r11 + xorq %r14,%r13 + movq %rax,%r15 + vpsllq $56,%ymm8,%ymm9 + vpxor %ymm10,%ymm11,%ymm8 + rorxq $39,%rax,%r12 + leaq (%r11,%r13,1),%r11 + xorq %rbx,%r15 + vpsrlq $7,%ymm10,%ymm10 + vpxor %ymm9,%ymm8,%ymm8 + rorxq $34,%rax,%r14 + rorxq $28,%rax,%r13 + leaq (%rdx,%r11,1),%rdx + vpsllq $7,%ymm9,%ymm9 + vpxor %ymm10,%ymm8,%ymm8 + andq %r15,%rdi + xorq %r12,%r14 + xorq %rbx,%rdi + vpsrlq $6,%ymm7,%ymm11 + vpxor %ymm9,%ymm8,%ymm8 + xorq %r13,%r14 + leaq (%r11,%rdi,1),%r11 + movq %r8,%r12 + vpsllq $3,%ymm7,%ymm10 + vpaddq %ymm8,%ymm0,%ymm0 + addq 8+256(%rsp),%r10 + andq %rdx,%r12 + rorxq $41,%rdx,%r13 + vpsrlq $19,%ymm7,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + rorxq $18,%rdx,%rdi + leaq (%r11,%r14,1),%r11 + leaq (%r10,%r12,1),%r10 + vpsllq $42,%ymm10,%ymm10 + vpxor %ymm9,%ymm11,%ymm11 + andnq %r9,%rdx,%r12 + xorq %rdi,%r13 + rorxq $14,%rdx,%r14 + vpsrlq $42,%ymm9,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + leaq (%r10,%r12,1),%r10 + xorq %r14,%r13 + movq %r11,%rdi + vpxor %ymm9,%ymm11,%ymm11 + rorxq $39,%r11,%r12 + leaq (%r10,%r13,1),%r10 + xorq %rax,%rdi + vpaddq %ymm11,%ymm0,%ymm0 + rorxq $34,%r11,%r14 + rorxq $28,%r11,%r13 + leaq (%rcx,%r10,1),%rcx + vpaddq -128(%rbp),%ymm0,%ymm10 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %rax,%r15 + xorq %r13,%r14 + leaq (%r10,%r15,1),%r10 + movq %rdx,%r12 + vmovdqa %ymm10,0(%rsp) + vpalignr $8,%ymm1,%ymm2,%ymm8 + addq 32+256(%rsp),%r9 + andq %rcx,%r12 + rorxq $41,%rcx,%r13 + vpalignr $8,%ymm5,%ymm6,%ymm11 + rorxq $18,%rcx,%r15 + leaq (%r10,%r14,1),%r10 + leaq (%r9,%r12,1),%r9 + vpsrlq $1,%ymm8,%ymm10 + andnq %r8,%rcx,%r12 + xorq %r15,%r13 + rorxq $14,%rcx,%r14 + vpaddq %ymm11,%ymm1,%ymm1 + vpsrlq $7,%ymm8,%ymm11 + leaq (%r9,%r12,1),%r9 + xorq %r14,%r13 + movq %r10,%r15 + vpsllq $56,%ymm8,%ymm9 + vpxor %ymm10,%ymm11,%ymm8 + rorxq $39,%r10,%r12 + leaq (%r9,%r13,1),%r9 + xorq %r11,%r15 + vpsrlq $7,%ymm10,%ymm10 + vpxor %ymm9,%ymm8,%ymm8 + rorxq $34,%r10,%r14 + rorxq $28,%r10,%r13 + leaq (%rbx,%r9,1),%rbx + vpsllq $7,%ymm9,%ymm9 + vpxor %ymm10,%ymm8,%ymm8 + andq %r15,%rdi + xorq %r12,%r14 + xorq %r11,%rdi + vpsrlq $6,%ymm0,%ymm11 + vpxor %ymm9,%ymm8,%ymm8 + xorq %r13,%r14 + leaq (%r9,%rdi,1),%r9 + movq %rcx,%r12 + vpsllq $3,%ymm0,%ymm10 + vpaddq %ymm8,%ymm1,%ymm1 + addq 40+256(%rsp),%r8 + andq %rbx,%r12 + rorxq $41,%rbx,%r13 + vpsrlq $19,%ymm0,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + rorxq $18,%rbx,%rdi + leaq (%r9,%r14,1),%r9 + leaq (%r8,%r12,1),%r8 + vpsllq $42,%ymm10,%ymm10 + vpxor %ymm9,%ymm11,%ymm11 + andnq %rdx,%rbx,%r12 + xorq %rdi,%r13 + rorxq $14,%rbx,%r14 + vpsrlq $42,%ymm9,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + leaq (%r8,%r12,1),%r8 + xorq %r14,%r13 + movq %r9,%rdi + vpxor %ymm9,%ymm11,%ymm11 + rorxq $39,%r9,%r12 + leaq (%r8,%r13,1),%r8 + xorq %r10,%rdi + vpaddq %ymm11,%ymm1,%ymm1 + rorxq $34,%r9,%r14 + rorxq $28,%r9,%r13 + leaq (%rax,%r8,1),%rax + vpaddq -96(%rbp),%ymm1,%ymm10 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %r10,%r15 + xorq %r13,%r14 + leaq (%r8,%r15,1),%r8 + movq %rbx,%r12 + vmovdqa %ymm10,32(%rsp) + vpalignr $8,%ymm2,%ymm3,%ymm8 + addq 64+256(%rsp),%rdx + andq %rax,%r12 + rorxq $41,%rax,%r13 + vpalignr $8,%ymm6,%ymm7,%ymm11 + rorxq $18,%rax,%r15 + leaq (%r8,%r14,1),%r8 + leaq (%rdx,%r12,1),%rdx + vpsrlq $1,%ymm8,%ymm10 + andnq %rcx,%rax,%r12 + xorq %r15,%r13 + rorxq $14,%rax,%r14 + vpaddq %ymm11,%ymm2,%ymm2 + vpsrlq $7,%ymm8,%ymm11 + leaq (%rdx,%r12,1),%rdx + xorq %r14,%r13 + movq %r8,%r15 + vpsllq $56,%ymm8,%ymm9 + vpxor %ymm10,%ymm11,%ymm8 + rorxq $39,%r8,%r12 + leaq (%rdx,%r13,1),%rdx + xorq %r9,%r15 + vpsrlq $7,%ymm10,%ymm10 + vpxor %ymm9,%ymm8,%ymm8 + rorxq $34,%r8,%r14 + rorxq $28,%r8,%r13 + leaq (%r11,%rdx,1),%r11 + vpsllq $7,%ymm9,%ymm9 + vpxor %ymm10,%ymm8,%ymm8 + andq %r15,%rdi + xorq %r12,%r14 + xorq %r9,%rdi + vpsrlq $6,%ymm1,%ymm11 + vpxor %ymm9,%ymm8,%ymm8 + xorq %r13,%r14 + leaq (%rdx,%rdi,1),%rdx + movq %rax,%r12 + vpsllq $3,%ymm1,%ymm10 + vpaddq %ymm8,%ymm2,%ymm2 + addq 72+256(%rsp),%rcx + andq %r11,%r12 + rorxq $41,%r11,%r13 + vpsrlq $19,%ymm1,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + rorxq $18,%r11,%rdi + leaq (%rdx,%r14,1),%rdx + leaq (%rcx,%r12,1),%rcx + vpsllq $42,%ymm10,%ymm10 + vpxor %ymm9,%ymm11,%ymm11 + andnq %rbx,%r11,%r12 + xorq %rdi,%r13 + rorxq $14,%r11,%r14 + vpsrlq $42,%ymm9,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + leaq (%rcx,%r12,1),%rcx + xorq %r14,%r13 + movq %rdx,%rdi + vpxor %ymm9,%ymm11,%ymm11 + rorxq $39,%rdx,%r12 + leaq (%rcx,%r13,1),%rcx + xorq %r8,%rdi + vpaddq %ymm11,%ymm2,%ymm2 + rorxq $34,%rdx,%r14 + rorxq $28,%rdx,%r13 + leaq (%r10,%rcx,1),%r10 + vpaddq -64(%rbp),%ymm2,%ymm10 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %r8,%r15 + xorq %r13,%r14 + leaq (%rcx,%r15,1),%rcx + movq %r11,%r12 + vmovdqa %ymm10,64(%rsp) + vpalignr $8,%ymm3,%ymm4,%ymm8 + addq 96+256(%rsp),%rbx + andq %r10,%r12 + rorxq $41,%r10,%r13 + vpalignr $8,%ymm7,%ymm0,%ymm11 + rorxq $18,%r10,%r15 + leaq (%rcx,%r14,1),%rcx + leaq (%rbx,%r12,1),%rbx + vpsrlq $1,%ymm8,%ymm10 + andnq %rax,%r10,%r12 + xorq %r15,%r13 + rorxq $14,%r10,%r14 + vpaddq %ymm11,%ymm3,%ymm3 + vpsrlq $7,%ymm8,%ymm11 + leaq (%rbx,%r12,1),%rbx + xorq %r14,%r13 + movq %rcx,%r15 + vpsllq $56,%ymm8,%ymm9 + vpxor %ymm10,%ymm11,%ymm8 + rorxq $39,%rcx,%r12 + leaq (%rbx,%r13,1),%rbx + xorq %rdx,%r15 + vpsrlq $7,%ymm10,%ymm10 + vpxor %ymm9,%ymm8,%ymm8 + rorxq $34,%rcx,%r14 + rorxq $28,%rcx,%r13 + leaq (%r9,%rbx,1),%r9 + vpsllq $7,%ymm9,%ymm9 + vpxor %ymm10,%ymm8,%ymm8 + andq %r15,%rdi + xorq %r12,%r14 + xorq %rdx,%rdi + vpsrlq $6,%ymm2,%ymm11 + vpxor %ymm9,%ymm8,%ymm8 + xorq %r13,%r14 + leaq (%rbx,%rdi,1),%rbx + movq %r10,%r12 + vpsllq $3,%ymm2,%ymm10 + vpaddq %ymm8,%ymm3,%ymm3 + addq 104+256(%rsp),%rax + andq %r9,%r12 + rorxq $41,%r9,%r13 + vpsrlq $19,%ymm2,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + rorxq $18,%r9,%rdi + leaq (%rbx,%r14,1),%rbx + leaq (%rax,%r12,1),%rax + vpsllq $42,%ymm10,%ymm10 + vpxor %ymm9,%ymm11,%ymm11 + andnq %r11,%r9,%r12 + xorq %rdi,%r13 + rorxq $14,%r9,%r14 + vpsrlq $42,%ymm9,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + leaq (%rax,%r12,1),%rax + xorq %r14,%r13 + movq %rbx,%rdi + vpxor %ymm9,%ymm11,%ymm11 + rorxq $39,%rbx,%r12 + leaq (%rax,%r13,1),%rax + xorq %rcx,%rdi + vpaddq %ymm11,%ymm3,%ymm3 + rorxq $34,%rbx,%r14 + rorxq $28,%rbx,%r13 + leaq (%r8,%rax,1),%r8 + vpaddq -32(%rbp),%ymm3,%ymm10 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %rcx,%r15 + xorq %r13,%r14 + leaq (%rax,%r15,1),%rax + movq %r9,%r12 + vmovdqa %ymm10,96(%rsp) + leaq -128(%rsp),%rsp +.cfi_escape 0x0f,0x06,0x77,0xf8,0x00,0x06,0x23,0x08 + + pushq 128-8(%rsp) +.cfi_escape 0x0f,0x05,0x77,0x00,0x06,0x23,0x08 + leaq 8(%rsp),%rsp +.cfi_escape 0x0f,0x05,0x77,0x78,0x06,0x23,0x08 + vpalignr $8,%ymm4,%ymm5,%ymm8 + addq 0+256(%rsp),%r11 + andq %r8,%r12 + rorxq $41,%r8,%r13 + vpalignr $8,%ymm0,%ymm1,%ymm11 + rorxq $18,%r8,%r15 + leaq (%rax,%r14,1),%rax + leaq (%r11,%r12,1),%r11 + vpsrlq $1,%ymm8,%ymm10 + andnq %r10,%r8,%r12 + xorq %r15,%r13 + rorxq $14,%r8,%r14 + vpaddq %ymm11,%ymm4,%ymm4 + vpsrlq $7,%ymm8,%ymm11 + leaq (%r11,%r12,1),%r11 + xorq %r14,%r13 + movq %rax,%r15 + vpsllq $56,%ymm8,%ymm9 + vpxor %ymm10,%ymm11,%ymm8 + rorxq $39,%rax,%r12 + leaq (%r11,%r13,1),%r11 + xorq %rbx,%r15 + vpsrlq $7,%ymm10,%ymm10 + vpxor %ymm9,%ymm8,%ymm8 + rorxq $34,%rax,%r14 + rorxq $28,%rax,%r13 + leaq (%rdx,%r11,1),%rdx + vpsllq $7,%ymm9,%ymm9 + vpxor %ymm10,%ymm8,%ymm8 + andq %r15,%rdi + xorq %r12,%r14 + xorq %rbx,%rdi + vpsrlq $6,%ymm3,%ymm11 + vpxor %ymm9,%ymm8,%ymm8 + xorq %r13,%r14 + leaq (%r11,%rdi,1),%r11 + movq %r8,%r12 + vpsllq $3,%ymm3,%ymm10 + vpaddq %ymm8,%ymm4,%ymm4 + addq 8+256(%rsp),%r10 + andq %rdx,%r12 + rorxq $41,%rdx,%r13 + vpsrlq $19,%ymm3,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + rorxq $18,%rdx,%rdi + leaq (%r11,%r14,1),%r11 + leaq (%r10,%r12,1),%r10 + vpsllq $42,%ymm10,%ymm10 + vpxor %ymm9,%ymm11,%ymm11 + andnq %r9,%rdx,%r12 + xorq %rdi,%r13 + rorxq $14,%rdx,%r14 + vpsrlq $42,%ymm9,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + leaq (%r10,%r12,1),%r10 + xorq %r14,%r13 + movq %r11,%rdi + vpxor %ymm9,%ymm11,%ymm11 + rorxq $39,%r11,%r12 + leaq (%r10,%r13,1),%r10 + xorq %rax,%rdi + vpaddq %ymm11,%ymm4,%ymm4 + rorxq $34,%r11,%r14 + rorxq $28,%r11,%r13 + leaq (%rcx,%r10,1),%rcx + vpaddq 0(%rbp),%ymm4,%ymm10 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %rax,%r15 + xorq %r13,%r14 + leaq (%r10,%r15,1),%r10 + movq %rdx,%r12 + vmovdqa %ymm10,0(%rsp) + vpalignr $8,%ymm5,%ymm6,%ymm8 + addq 32+256(%rsp),%r9 + andq %rcx,%r12 + rorxq $41,%rcx,%r13 + vpalignr $8,%ymm1,%ymm2,%ymm11 + rorxq $18,%rcx,%r15 + leaq (%r10,%r14,1),%r10 + leaq (%r9,%r12,1),%r9 + vpsrlq $1,%ymm8,%ymm10 + andnq %r8,%rcx,%r12 + xorq %r15,%r13 + rorxq $14,%rcx,%r14 + vpaddq %ymm11,%ymm5,%ymm5 + vpsrlq $7,%ymm8,%ymm11 + leaq (%r9,%r12,1),%r9 + xorq %r14,%r13 + movq %r10,%r15 + vpsllq $56,%ymm8,%ymm9 + vpxor %ymm10,%ymm11,%ymm8 + rorxq $39,%r10,%r12 + leaq (%r9,%r13,1),%r9 + xorq %r11,%r15 + vpsrlq $7,%ymm10,%ymm10 + vpxor %ymm9,%ymm8,%ymm8 + rorxq $34,%r10,%r14 + rorxq $28,%r10,%r13 + leaq (%rbx,%r9,1),%rbx + vpsllq $7,%ymm9,%ymm9 + vpxor %ymm10,%ymm8,%ymm8 + andq %r15,%rdi + xorq %r12,%r14 + xorq %r11,%rdi + vpsrlq $6,%ymm4,%ymm11 + vpxor %ymm9,%ymm8,%ymm8 + xorq %r13,%r14 + leaq (%r9,%rdi,1),%r9 + movq %rcx,%r12 + vpsllq $3,%ymm4,%ymm10 + vpaddq %ymm8,%ymm5,%ymm5 + addq 40+256(%rsp),%r8 + andq %rbx,%r12 + rorxq $41,%rbx,%r13 + vpsrlq $19,%ymm4,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + rorxq $18,%rbx,%rdi + leaq (%r9,%r14,1),%r9 + leaq (%r8,%r12,1),%r8 + vpsllq $42,%ymm10,%ymm10 + vpxor %ymm9,%ymm11,%ymm11 + andnq %rdx,%rbx,%r12 + xorq %rdi,%r13 + rorxq $14,%rbx,%r14 + vpsrlq $42,%ymm9,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + leaq (%r8,%r12,1),%r8 + xorq %r14,%r13 + movq %r9,%rdi + vpxor %ymm9,%ymm11,%ymm11 + rorxq $39,%r9,%r12 + leaq (%r8,%r13,1),%r8 + xorq %r10,%rdi + vpaddq %ymm11,%ymm5,%ymm5 + rorxq $34,%r9,%r14 + rorxq $28,%r9,%r13 + leaq (%rax,%r8,1),%rax + vpaddq 32(%rbp),%ymm5,%ymm10 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %r10,%r15 + xorq %r13,%r14 + leaq (%r8,%r15,1),%r8 + movq %rbx,%r12 + vmovdqa %ymm10,32(%rsp) + vpalignr $8,%ymm6,%ymm7,%ymm8 + addq 64+256(%rsp),%rdx + andq %rax,%r12 + rorxq $41,%rax,%r13 + vpalignr $8,%ymm2,%ymm3,%ymm11 + rorxq $18,%rax,%r15 + leaq (%r8,%r14,1),%r8 + leaq (%rdx,%r12,1),%rdx + vpsrlq $1,%ymm8,%ymm10 + andnq %rcx,%rax,%r12 + xorq %r15,%r13 + rorxq $14,%rax,%r14 + vpaddq %ymm11,%ymm6,%ymm6 + vpsrlq $7,%ymm8,%ymm11 + leaq (%rdx,%r12,1),%rdx + xorq %r14,%r13 + movq %r8,%r15 + vpsllq $56,%ymm8,%ymm9 + vpxor %ymm10,%ymm11,%ymm8 + rorxq $39,%r8,%r12 + leaq (%rdx,%r13,1),%rdx + xorq %r9,%r15 + vpsrlq $7,%ymm10,%ymm10 + vpxor %ymm9,%ymm8,%ymm8 + rorxq $34,%r8,%r14 + rorxq $28,%r8,%r13 + leaq (%r11,%rdx,1),%r11 + vpsllq $7,%ymm9,%ymm9 + vpxor %ymm10,%ymm8,%ymm8 + andq %r15,%rdi + xorq %r12,%r14 + xorq %r9,%rdi + vpsrlq $6,%ymm5,%ymm11 + vpxor %ymm9,%ymm8,%ymm8 + xorq %r13,%r14 + leaq (%rdx,%rdi,1),%rdx + movq %rax,%r12 + vpsllq $3,%ymm5,%ymm10 + vpaddq %ymm8,%ymm6,%ymm6 + addq 72+256(%rsp),%rcx + andq %r11,%r12 + rorxq $41,%r11,%r13 + vpsrlq $19,%ymm5,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + rorxq $18,%r11,%rdi + leaq (%rdx,%r14,1),%rdx + leaq (%rcx,%r12,1),%rcx + vpsllq $42,%ymm10,%ymm10 + vpxor %ymm9,%ymm11,%ymm11 + andnq %rbx,%r11,%r12 + xorq %rdi,%r13 + rorxq $14,%r11,%r14 + vpsrlq $42,%ymm9,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + leaq (%rcx,%r12,1),%rcx + xorq %r14,%r13 + movq %rdx,%rdi + vpxor %ymm9,%ymm11,%ymm11 + rorxq $39,%rdx,%r12 + leaq (%rcx,%r13,1),%rcx + xorq %r8,%rdi + vpaddq %ymm11,%ymm6,%ymm6 + rorxq $34,%rdx,%r14 + rorxq $28,%rdx,%r13 + leaq (%r10,%rcx,1),%r10 + vpaddq 64(%rbp),%ymm6,%ymm10 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %r8,%r15 + xorq %r13,%r14 + leaq (%rcx,%r15,1),%rcx + movq %r11,%r12 + vmovdqa %ymm10,64(%rsp) + vpalignr $8,%ymm7,%ymm0,%ymm8 + addq 96+256(%rsp),%rbx + andq %r10,%r12 + rorxq $41,%r10,%r13 + vpalignr $8,%ymm3,%ymm4,%ymm11 + rorxq $18,%r10,%r15 + leaq (%rcx,%r14,1),%rcx + leaq (%rbx,%r12,1),%rbx + vpsrlq $1,%ymm8,%ymm10 + andnq %rax,%r10,%r12 + xorq %r15,%r13 + rorxq $14,%r10,%r14 + vpaddq %ymm11,%ymm7,%ymm7 + vpsrlq $7,%ymm8,%ymm11 + leaq (%rbx,%r12,1),%rbx + xorq %r14,%r13 + movq %rcx,%r15 + vpsllq $56,%ymm8,%ymm9 + vpxor %ymm10,%ymm11,%ymm8 + rorxq $39,%rcx,%r12 + leaq (%rbx,%r13,1),%rbx + xorq %rdx,%r15 + vpsrlq $7,%ymm10,%ymm10 + vpxor %ymm9,%ymm8,%ymm8 + rorxq $34,%rcx,%r14 + rorxq $28,%rcx,%r13 + leaq (%r9,%rbx,1),%r9 + vpsllq $7,%ymm9,%ymm9 + vpxor %ymm10,%ymm8,%ymm8 + andq %r15,%rdi + xorq %r12,%r14 + xorq %rdx,%rdi + vpsrlq $6,%ymm6,%ymm11 + vpxor %ymm9,%ymm8,%ymm8 + xorq %r13,%r14 + leaq (%rbx,%rdi,1),%rbx + movq %r10,%r12 + vpsllq $3,%ymm6,%ymm10 + vpaddq %ymm8,%ymm7,%ymm7 + addq 104+256(%rsp),%rax + andq %r9,%r12 + rorxq $41,%r9,%r13 + vpsrlq $19,%ymm6,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + rorxq $18,%r9,%rdi + leaq (%rbx,%r14,1),%rbx + leaq (%rax,%r12,1),%rax + vpsllq $42,%ymm10,%ymm10 + vpxor %ymm9,%ymm11,%ymm11 + andnq %r11,%r9,%r12 + xorq %rdi,%r13 + rorxq $14,%r9,%r14 + vpsrlq $42,%ymm9,%ymm9 + vpxor %ymm10,%ymm11,%ymm11 + leaq (%rax,%r12,1),%rax + xorq %r14,%r13 + movq %rbx,%rdi + vpxor %ymm9,%ymm11,%ymm11 + rorxq $39,%rbx,%r12 + leaq (%rax,%r13,1),%rax + xorq %rcx,%rdi + vpaddq %ymm11,%ymm7,%ymm7 + rorxq $34,%rbx,%r14 + rorxq $28,%rbx,%r13 + leaq (%r8,%rax,1),%r8 + vpaddq 96(%rbp),%ymm7,%ymm10 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %rcx,%r15 + xorq %r13,%r14 + leaq (%rax,%r15,1),%rax + movq %r9,%r12 + vmovdqa %ymm10,96(%rsp) + leaq 256(%rbp),%rbp + cmpb $0,-121(%rbp) + jne .Lavx2_00_47 + addq 0+128(%rsp),%r11 + andq %r8,%r12 + rorxq $41,%r8,%r13 + rorxq $18,%r8,%r15 + leaq (%rax,%r14,1),%rax + leaq (%r11,%r12,1),%r11 + andnq %r10,%r8,%r12 + xorq %r15,%r13 + rorxq $14,%r8,%r14 + leaq (%r11,%r12,1),%r11 + xorq %r14,%r13 + movq %rax,%r15 + rorxq $39,%rax,%r12 + leaq (%r11,%r13,1),%r11 + xorq %rbx,%r15 + rorxq $34,%rax,%r14 + rorxq $28,%rax,%r13 + leaq (%rdx,%r11,1),%rdx + andq %r15,%rdi + xorq %r12,%r14 + xorq %rbx,%rdi + xorq %r13,%r14 + leaq (%r11,%rdi,1),%r11 + movq %r8,%r12 + addq 8+128(%rsp),%r10 + andq %rdx,%r12 + rorxq $41,%rdx,%r13 + rorxq $18,%rdx,%rdi + leaq (%r11,%r14,1),%r11 + leaq (%r10,%r12,1),%r10 + andnq %r9,%rdx,%r12 + xorq %rdi,%r13 + rorxq $14,%rdx,%r14 + leaq (%r10,%r12,1),%r10 + xorq %r14,%r13 + movq %r11,%rdi + rorxq $39,%r11,%r12 + leaq (%r10,%r13,1),%r10 + xorq %rax,%rdi + rorxq $34,%r11,%r14 + rorxq $28,%r11,%r13 + leaq (%rcx,%r10,1),%rcx + andq %rdi,%r15 + xorq %r12,%r14 + xorq %rax,%r15 + xorq %r13,%r14 + leaq (%r10,%r15,1),%r10 + movq %rdx,%r12 + addq 32+128(%rsp),%r9 + andq %rcx,%r12 + rorxq $41,%rcx,%r13 + rorxq $18,%rcx,%r15 + leaq (%r10,%r14,1),%r10 + leaq (%r9,%r12,1),%r9 + andnq %r8,%rcx,%r12 + xorq %r15,%r13 + rorxq $14,%rcx,%r14 + leaq (%r9,%r12,1),%r9 + xorq %r14,%r13 + movq %r10,%r15 + rorxq $39,%r10,%r12 + leaq (%r9,%r13,1),%r9 + xorq %r11,%r15 + rorxq $34,%r10,%r14 + rorxq $28,%r10,%r13 + leaq (%rbx,%r9,1),%rbx + andq %r15,%rdi + xorq %r12,%r14 + xorq %r11,%rdi + xorq %r13,%r14 + leaq (%r9,%rdi,1),%r9 + movq %rcx,%r12 + addq 40+128(%rsp),%r8 + andq %rbx,%r12 + rorxq $41,%rbx,%r13 + rorxq $18,%rbx,%rdi + leaq (%r9,%r14,1),%r9 + leaq (%r8,%r12,1),%r8 + andnq %rdx,%rbx,%r12 + xorq %rdi,%r13 + rorxq $14,%rbx,%r14 + leaq (%r8,%r12,1),%r8 + xorq %r14,%r13 + movq %r9,%rdi + rorxq $39,%r9,%r12 + leaq (%r8,%r13,1),%r8 + xorq %r10,%rdi + rorxq $34,%r9,%r14 + rorxq $28,%r9,%r13 + leaq (%rax,%r8,1),%rax + andq %rdi,%r15 + xorq %r12,%r14 + xorq %r10,%r15 + xorq %r13,%r14 + leaq (%r8,%r15,1),%r8 + movq %rbx,%r12 + addq 64+128(%rsp),%rdx + andq %rax,%r12 + rorxq $41,%rax,%r13 + rorxq $18,%rax,%r15 + leaq (%r8,%r14,1),%r8 + leaq (%rdx,%r12,1),%rdx + andnq %rcx,%rax,%r12 + xorq %r15,%r13 + rorxq $14,%rax,%r14 + leaq (%rdx,%r12,1),%rdx + xorq %r14,%r13 + movq %r8,%r15 + rorxq $39,%r8,%r12 + leaq (%rdx,%r13,1),%rdx + xorq %r9,%r15 + rorxq $34,%r8,%r14 + rorxq $28,%r8,%r13 + leaq (%r11,%rdx,1),%r11 + andq %r15,%rdi + xorq %r12,%r14 + xorq %r9,%rdi + xorq %r13,%r14 + leaq (%rdx,%rdi,1),%rdx + movq %rax,%r12 + addq 72+128(%rsp),%rcx + andq %r11,%r12 + rorxq $41,%r11,%r13 + rorxq $18,%r11,%rdi + leaq (%rdx,%r14,1),%rdx + leaq (%rcx,%r12,1),%rcx + andnq %rbx,%r11,%r12 + xorq %rdi,%r13 + rorxq $14,%r11,%r14 + leaq (%rcx,%r12,1),%rcx + xorq %r14,%r13 + movq %rdx,%rdi + rorxq $39,%rdx,%r12 + leaq (%rcx,%r13,1),%rcx + xorq %r8,%rdi + rorxq $34,%rdx,%r14 + rorxq $28,%rdx,%r13 + leaq (%r10,%rcx,1),%r10 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %r8,%r15 + xorq %r13,%r14 + leaq (%rcx,%r15,1),%rcx + movq %r11,%r12 + addq 96+128(%rsp),%rbx + andq %r10,%r12 + rorxq $41,%r10,%r13 + rorxq $18,%r10,%r15 + leaq (%rcx,%r14,1),%rcx + leaq (%rbx,%r12,1),%rbx + andnq %rax,%r10,%r12 + xorq %r15,%r13 + rorxq $14,%r10,%r14 + leaq (%rbx,%r12,1),%rbx + xorq %r14,%r13 + movq %rcx,%r15 + rorxq $39,%rcx,%r12 + leaq (%rbx,%r13,1),%rbx + xorq %rdx,%r15 + rorxq $34,%rcx,%r14 + rorxq $28,%rcx,%r13 + leaq (%r9,%rbx,1),%r9 + andq %r15,%rdi + xorq %r12,%r14 + xorq %rdx,%rdi + xorq %r13,%r14 + leaq (%rbx,%rdi,1),%rbx + movq %r10,%r12 + addq 104+128(%rsp),%rax + andq %r9,%r12 + rorxq $41,%r9,%r13 + rorxq $18,%r9,%rdi + leaq (%rbx,%r14,1),%rbx + leaq (%rax,%r12,1),%rax + andnq %r11,%r9,%r12 + xorq %rdi,%r13 + rorxq $14,%r9,%r14 + leaq (%rax,%r12,1),%rax + xorq %r14,%r13 + movq %rbx,%rdi + rorxq $39,%rbx,%r12 + leaq (%rax,%r13,1),%rax + xorq %rcx,%rdi + rorxq $34,%rbx,%r14 + rorxq $28,%rbx,%r13 + leaq (%r8,%rax,1),%r8 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %rcx,%r15 + xorq %r13,%r14 + leaq (%rax,%r15,1),%rax + movq %r9,%r12 + addq 0(%rsp),%r11 + andq %r8,%r12 + rorxq $41,%r8,%r13 + rorxq $18,%r8,%r15 + leaq (%rax,%r14,1),%rax + leaq (%r11,%r12,1),%r11 + andnq %r10,%r8,%r12 + xorq %r15,%r13 + rorxq $14,%r8,%r14 + leaq (%r11,%r12,1),%r11 + xorq %r14,%r13 + movq %rax,%r15 + rorxq $39,%rax,%r12 + leaq (%r11,%r13,1),%r11 + xorq %rbx,%r15 + rorxq $34,%rax,%r14 + rorxq $28,%rax,%r13 + leaq (%rdx,%r11,1),%rdx + andq %r15,%rdi + xorq %r12,%r14 + xorq %rbx,%rdi + xorq %r13,%r14 + leaq (%r11,%rdi,1),%r11 + movq %r8,%r12 + addq 8(%rsp),%r10 + andq %rdx,%r12 + rorxq $41,%rdx,%r13 + rorxq $18,%rdx,%rdi + leaq (%r11,%r14,1),%r11 + leaq (%r10,%r12,1),%r10 + andnq %r9,%rdx,%r12 + xorq %rdi,%r13 + rorxq $14,%rdx,%r14 + leaq (%r10,%r12,1),%r10 + xorq %r14,%r13 + movq %r11,%rdi + rorxq $39,%r11,%r12 + leaq (%r10,%r13,1),%r10 + xorq %rax,%rdi + rorxq $34,%r11,%r14 + rorxq $28,%r11,%r13 + leaq (%rcx,%r10,1),%rcx + andq %rdi,%r15 + xorq %r12,%r14 + xorq %rax,%r15 + xorq %r13,%r14 + leaq (%r10,%r15,1),%r10 + movq %rdx,%r12 + addq 32(%rsp),%r9 + andq %rcx,%r12 + rorxq $41,%rcx,%r13 + rorxq $18,%rcx,%r15 + leaq (%r10,%r14,1),%r10 + leaq (%r9,%r12,1),%r9 + andnq %r8,%rcx,%r12 + xorq %r15,%r13 + rorxq $14,%rcx,%r14 + leaq (%r9,%r12,1),%r9 + xorq %r14,%r13 + movq %r10,%r15 + rorxq $39,%r10,%r12 + leaq (%r9,%r13,1),%r9 + xorq %r11,%r15 + rorxq $34,%r10,%r14 + rorxq $28,%r10,%r13 + leaq (%rbx,%r9,1),%rbx + andq %r15,%rdi + xorq %r12,%r14 + xorq %r11,%rdi + xorq %r13,%r14 + leaq (%r9,%rdi,1),%r9 + movq %rcx,%r12 + addq 40(%rsp),%r8 + andq %rbx,%r12 + rorxq $41,%rbx,%r13 + rorxq $18,%rbx,%rdi + leaq (%r9,%r14,1),%r9 + leaq (%r8,%r12,1),%r8 + andnq %rdx,%rbx,%r12 + xorq %rdi,%r13 + rorxq $14,%rbx,%r14 + leaq (%r8,%r12,1),%r8 + xorq %r14,%r13 + movq %r9,%rdi + rorxq $39,%r9,%r12 + leaq (%r8,%r13,1),%r8 + xorq %r10,%rdi + rorxq $34,%r9,%r14 + rorxq $28,%r9,%r13 + leaq (%rax,%r8,1),%rax + andq %rdi,%r15 + xorq %r12,%r14 + xorq %r10,%r15 + xorq %r13,%r14 + leaq (%r8,%r15,1),%r8 + movq %rbx,%r12 + addq 64(%rsp),%rdx + andq %rax,%r12 + rorxq $41,%rax,%r13 + rorxq $18,%rax,%r15 + leaq (%r8,%r14,1),%r8 + leaq (%rdx,%r12,1),%rdx + andnq %rcx,%rax,%r12 + xorq %r15,%r13 + rorxq $14,%rax,%r14 + leaq (%rdx,%r12,1),%rdx + xorq %r14,%r13 + movq %r8,%r15 + rorxq $39,%r8,%r12 + leaq (%rdx,%r13,1),%rdx + xorq %r9,%r15 + rorxq $34,%r8,%r14 + rorxq $28,%r8,%r13 + leaq (%r11,%rdx,1),%r11 + andq %r15,%rdi + xorq %r12,%r14 + xorq %r9,%rdi + xorq %r13,%r14 + leaq (%rdx,%rdi,1),%rdx + movq %rax,%r12 + addq 72(%rsp),%rcx + andq %r11,%r12 + rorxq $41,%r11,%r13 + rorxq $18,%r11,%rdi + leaq (%rdx,%r14,1),%rdx + leaq (%rcx,%r12,1),%rcx + andnq %rbx,%r11,%r12 + xorq %rdi,%r13 + rorxq $14,%r11,%r14 + leaq (%rcx,%r12,1),%rcx + xorq %r14,%r13 + movq %rdx,%rdi + rorxq $39,%rdx,%r12 + leaq (%rcx,%r13,1),%rcx + xorq %r8,%rdi + rorxq $34,%rdx,%r14 + rorxq $28,%rdx,%r13 + leaq (%r10,%rcx,1),%r10 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %r8,%r15 + xorq %r13,%r14 + leaq (%rcx,%r15,1),%rcx + movq %r11,%r12 + addq 96(%rsp),%rbx + andq %r10,%r12 + rorxq $41,%r10,%r13 + rorxq $18,%r10,%r15 + leaq (%rcx,%r14,1),%rcx + leaq (%rbx,%r12,1),%rbx + andnq %rax,%r10,%r12 + xorq %r15,%r13 + rorxq $14,%r10,%r14 + leaq (%rbx,%r12,1),%rbx + xorq %r14,%r13 + movq %rcx,%r15 + rorxq $39,%rcx,%r12 + leaq (%rbx,%r13,1),%rbx + xorq %rdx,%r15 + rorxq $34,%rcx,%r14 + rorxq $28,%rcx,%r13 + leaq (%r9,%rbx,1),%r9 + andq %r15,%rdi + xorq %r12,%r14 + xorq %rdx,%rdi + xorq %r13,%r14 + leaq (%rbx,%rdi,1),%rbx + movq %r10,%r12 + addq 104(%rsp),%rax + andq %r9,%r12 + rorxq $41,%r9,%r13 + rorxq $18,%r9,%rdi + leaq (%rbx,%r14,1),%rbx + leaq (%rax,%r12,1),%rax + andnq %r11,%r9,%r12 + xorq %rdi,%r13 + rorxq $14,%r9,%r14 + leaq (%rax,%r12,1),%rax + xorq %r14,%r13 + movq %rbx,%rdi + rorxq $39,%rbx,%r12 + leaq (%rax,%r13,1),%rax + xorq %rcx,%rdi + rorxq $34,%rbx,%r14 + rorxq $28,%rbx,%r13 + leaq (%r8,%rax,1),%r8 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %rcx,%r15 + xorq %r13,%r14 + leaq (%rax,%r15,1),%rax + movq %r9,%r12 + movq 1280(%rsp),%rdi + addq %r14,%rax + + leaq 1152(%rsp),%rbp + + addq 0(%rdi),%rax + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + addq 48(%rdi),%r10 + addq 56(%rdi),%r11 + + movq %rax,0(%rdi) + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + + cmpq 144(%rbp),%rsi + je .Ldone_avx2 + + xorq %r14,%r14 + movq %rbx,%rdi + xorq %rcx,%rdi + movq %r9,%r12 + jmp .Lower_avx2 +.align 16 +.Lower_avx2: + addq 0+16(%rbp),%r11 + andq %r8,%r12 + rorxq $41,%r8,%r13 + rorxq $18,%r8,%r15 + leaq (%rax,%r14,1),%rax + leaq (%r11,%r12,1),%r11 + andnq %r10,%r8,%r12 + xorq %r15,%r13 + rorxq $14,%r8,%r14 + leaq (%r11,%r12,1),%r11 + xorq %r14,%r13 + movq %rax,%r15 + rorxq $39,%rax,%r12 + leaq (%r11,%r13,1),%r11 + xorq %rbx,%r15 + rorxq $34,%rax,%r14 + rorxq $28,%rax,%r13 + leaq (%rdx,%r11,1),%rdx + andq %r15,%rdi + xorq %r12,%r14 + xorq %rbx,%rdi + xorq %r13,%r14 + leaq (%r11,%rdi,1),%r11 + movq %r8,%r12 + addq 8+16(%rbp),%r10 + andq %rdx,%r12 + rorxq $41,%rdx,%r13 + rorxq $18,%rdx,%rdi + leaq (%r11,%r14,1),%r11 + leaq (%r10,%r12,1),%r10 + andnq %r9,%rdx,%r12 + xorq %rdi,%r13 + rorxq $14,%rdx,%r14 + leaq (%r10,%r12,1),%r10 + xorq %r14,%r13 + movq %r11,%rdi + rorxq $39,%r11,%r12 + leaq (%r10,%r13,1),%r10 + xorq %rax,%rdi + rorxq $34,%r11,%r14 + rorxq $28,%r11,%r13 + leaq (%rcx,%r10,1),%rcx + andq %rdi,%r15 + xorq %r12,%r14 + xorq %rax,%r15 + xorq %r13,%r14 + leaq (%r10,%r15,1),%r10 + movq %rdx,%r12 + addq 32+16(%rbp),%r9 + andq %rcx,%r12 + rorxq $41,%rcx,%r13 + rorxq $18,%rcx,%r15 + leaq (%r10,%r14,1),%r10 + leaq (%r9,%r12,1),%r9 + andnq %r8,%rcx,%r12 + xorq %r15,%r13 + rorxq $14,%rcx,%r14 + leaq (%r9,%r12,1),%r9 + xorq %r14,%r13 + movq %r10,%r15 + rorxq $39,%r10,%r12 + leaq (%r9,%r13,1),%r9 + xorq %r11,%r15 + rorxq $34,%r10,%r14 + rorxq $28,%r10,%r13 + leaq (%rbx,%r9,1),%rbx + andq %r15,%rdi + xorq %r12,%r14 + xorq %r11,%rdi + xorq %r13,%r14 + leaq (%r9,%rdi,1),%r9 + movq %rcx,%r12 + addq 40+16(%rbp),%r8 + andq %rbx,%r12 + rorxq $41,%rbx,%r13 + rorxq $18,%rbx,%rdi + leaq (%r9,%r14,1),%r9 + leaq (%r8,%r12,1),%r8 + andnq %rdx,%rbx,%r12 + xorq %rdi,%r13 + rorxq $14,%rbx,%r14 + leaq (%r8,%r12,1),%r8 + xorq %r14,%r13 + movq %r9,%rdi + rorxq $39,%r9,%r12 + leaq (%r8,%r13,1),%r8 + xorq %r10,%rdi + rorxq $34,%r9,%r14 + rorxq $28,%r9,%r13 + leaq (%rax,%r8,1),%rax + andq %rdi,%r15 + xorq %r12,%r14 + xorq %r10,%r15 + xorq %r13,%r14 + leaq (%r8,%r15,1),%r8 + movq %rbx,%r12 + addq 64+16(%rbp),%rdx + andq %rax,%r12 + rorxq $41,%rax,%r13 + rorxq $18,%rax,%r15 + leaq (%r8,%r14,1),%r8 + leaq (%rdx,%r12,1),%rdx + andnq %rcx,%rax,%r12 + xorq %r15,%r13 + rorxq $14,%rax,%r14 + leaq (%rdx,%r12,1),%rdx + xorq %r14,%r13 + movq %r8,%r15 + rorxq $39,%r8,%r12 + leaq (%rdx,%r13,1),%rdx + xorq %r9,%r15 + rorxq $34,%r8,%r14 + rorxq $28,%r8,%r13 + leaq (%r11,%rdx,1),%r11 + andq %r15,%rdi + xorq %r12,%r14 + xorq %r9,%rdi + xorq %r13,%r14 + leaq (%rdx,%rdi,1),%rdx + movq %rax,%r12 + addq 72+16(%rbp),%rcx + andq %r11,%r12 + rorxq $41,%r11,%r13 + rorxq $18,%r11,%rdi + leaq (%rdx,%r14,1),%rdx + leaq (%rcx,%r12,1),%rcx + andnq %rbx,%r11,%r12 + xorq %rdi,%r13 + rorxq $14,%r11,%r14 + leaq (%rcx,%r12,1),%rcx + xorq %r14,%r13 + movq %rdx,%rdi + rorxq $39,%rdx,%r12 + leaq (%rcx,%r13,1),%rcx + xorq %r8,%rdi + rorxq $34,%rdx,%r14 + rorxq $28,%rdx,%r13 + leaq (%r10,%rcx,1),%r10 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %r8,%r15 + xorq %r13,%r14 + leaq (%rcx,%r15,1),%rcx + movq %r11,%r12 + addq 96+16(%rbp),%rbx + andq %r10,%r12 + rorxq $41,%r10,%r13 + rorxq $18,%r10,%r15 + leaq (%rcx,%r14,1),%rcx + leaq (%rbx,%r12,1),%rbx + andnq %rax,%r10,%r12 + xorq %r15,%r13 + rorxq $14,%r10,%r14 + leaq (%rbx,%r12,1),%rbx + xorq %r14,%r13 + movq %rcx,%r15 + rorxq $39,%rcx,%r12 + leaq (%rbx,%r13,1),%rbx + xorq %rdx,%r15 + rorxq $34,%rcx,%r14 + rorxq $28,%rcx,%r13 + leaq (%r9,%rbx,1),%r9 + andq %r15,%rdi + xorq %r12,%r14 + xorq %rdx,%rdi + xorq %r13,%r14 + leaq (%rbx,%rdi,1),%rbx + movq %r10,%r12 + addq 104+16(%rbp),%rax + andq %r9,%r12 + rorxq $41,%r9,%r13 + rorxq $18,%r9,%rdi + leaq (%rbx,%r14,1),%rbx + leaq (%rax,%r12,1),%rax + andnq %r11,%r9,%r12 + xorq %rdi,%r13 + rorxq $14,%r9,%r14 + leaq (%rax,%r12,1),%rax + xorq %r14,%r13 + movq %rbx,%rdi + rorxq $39,%rbx,%r12 + leaq (%rax,%r13,1),%rax + xorq %rcx,%rdi + rorxq $34,%rbx,%r14 + rorxq $28,%rbx,%r13 + leaq (%r8,%rax,1),%r8 + andq %rdi,%r15 + xorq %r12,%r14 + xorq %rcx,%r15 + xorq %r13,%r14 + leaq (%rax,%r15,1),%rax + movq %r9,%r12 + leaq -128(%rbp),%rbp + cmpq %rsp,%rbp + jae .Lower_avx2 + + movq 1280(%rsp),%rdi + addq %r14,%rax + + leaq 1152(%rsp),%rsp + +.cfi_escape 0x0f,0x06,0x77,0x98,0x01,0x06,0x23,0x08 + + addq 0(%rdi),%rax + addq 8(%rdi),%rbx + addq 16(%rdi),%rcx + addq 24(%rdi),%rdx + addq 32(%rdi),%r8 + addq 40(%rdi),%r9 + leaq 256(%rsi),%rsi + addq 48(%rdi),%r10 + movq %rsi,%r12 + addq 56(%rdi),%r11 + cmpq 128+16(%rsp),%rsi + + movq %rax,0(%rdi) + cmoveq %rsp,%r12 + movq %rbx,8(%rdi) + movq %rcx,16(%rdi) + movq %rdx,24(%rdi) + movq %r8,32(%rdi) + movq %r9,40(%rdi) + movq %r10,48(%rdi) + movq %r11,56(%rdi) + + jbe .Loop_avx2 + leaq (%rsp),%rbp + + +.cfi_escape 0x0f,0x06,0x76,0x98,0x01,0x06,0x23,0x08 + +.Ldone_avx2: + movq 152(%rbp),%rsi +.cfi_def_cfa %rsi,8 + vzeroupper + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue_avx2: + .byte 0xf3,0xc3 +.cfi_endproc +.size sha512_block_data_order_avx2,.-sha512_block_data_order_avx2 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/sha/sha512.c b/crypto/openssl/crypto/sha/sha512.c index ca1f387a64f8..ff035c469f94 100644 --- a/crypto/openssl/crypto/sha/sha512.c +++ b/crypto/openssl/crypto/sha/sha512.c @@ -1,12 +1,19 @@ /* - * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * SHA512 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include #include /*- * IMPLEMENTATION NOTES. @@ -60,6 +67,14 @@ # define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA #endif +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define U64(C) C##UI64 +#elif defined(__arch64__) +# define U64(C) C##UL +#else +# define U64(C) C##ULL +#endif + int sha512_224_init(SHA512_CTX *c) { c->h[0] = U64(0x8c3d37c819544da2); @@ -323,34 +338,6 @@ void SHA512_Transform(SHA512_CTX *c, const unsigned char *data) sha512_block_data_order(c, data, 1); } -unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md) -{ - SHA512_CTX c; - static unsigned char m[SHA384_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - SHA384_Init(&c); - SHA512_Update(&c, d, n); - SHA512_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); - return md; -} - -unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md) -{ - SHA512_CTX c; - static unsigned char m[SHA512_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - SHA512_Init(&c); - SHA512_Update(&c, d, n); - SHA512_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); - return md; -} - #ifndef SHA512_ASM static const SHA_LONG64 K512[80] = { U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd), diff --git a/crypto/openssl/crypto/sha/sha_local.h b/crypto/openssl/crypto/sha/sha_local.h index 6edb9ef1d27e..81de72ba4f90 100644 --- a/crypto/openssl/crypto/sha/sha_local.h +++ b/crypto/openssl/crypto/sha/sha_local.h @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,6 +12,7 @@ #include #include +#include "internal/endian.h" #define DATA_ORDER_IS_BIG_ENDIAN @@ -151,14 +152,9 @@ static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num) E = c->h4; for (;;) { - const union { - long one; - char little; - } is_endian = { - 1 - }; - - if (!is_endian.little && sizeof(SHA_LONG) == 4 + DECLARE_IS_ENDIAN; + + if (!IS_LITTLE_ENDIAN && sizeof(SHA_LONG) == 4 && ((size_t)p % 4) == 0) { const SHA_LONG *W = (const SHA_LONG *)data; diff --git a/crypto/openssl/crypto/sha/sha_ppc.c b/crypto/openssl/crypto/sha/sha_ppc.c new file mode 100644 index 000000000000..accf19d8a231 --- /dev/null +++ b/crypto/openssl/crypto/sha/sha_ppc.c @@ -0,0 +1,33 @@ +/* + * Copyright 2009-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +#include +#include +#include "crypto/ppc_arch.h" + +void sha256_block_p8(void *ctx, const void *inp, size_t len); +void sha256_block_ppc(void *ctx, const void *inp, size_t len); +void sha256_block_data_order(void *ctx, const void *inp, size_t len); +void sha256_block_data_order(void *ctx, const void *inp, size_t len) +{ + OPENSSL_ppccap_P & PPC_CRYPTO207 ? sha256_block_p8(ctx, inp, len) : + sha256_block_ppc(ctx, inp, len); +} + +void sha512_block_p8(void *ctx, const void *inp, size_t len); +void sha512_block_ppc(void *ctx, const void *inp, size_t len); +void sha512_block_data_order(void *ctx, const void *inp, size_t len); +void sha512_block_data_order(void *ctx, const void *inp, size_t len) +{ + OPENSSL_ppccap_P & PPC_CRYPTO207 ? sha512_block_p8(ctx, inp, len) : + sha512_block_ppc(ctx, inp, len); +} diff --git a/crypto/openssl/crypto/siphash/build.info b/crypto/openssl/crypto/siphash/build.info index 4166344a5bfb..432b6f5ec355 100644 --- a/crypto/openssl/crypto/siphash/build.info +++ b/crypto/openssl/crypto/siphash/build.info @@ -1,5 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - siphash.c \ - siphash_pmeth.c \ - siphash_ameth.c + siphash.c diff --git a/crypto/openssl/crypto/siphash/siphash.c b/crypto/openssl/crypto/siphash/siphash.c index 07d94c1e6e59..57f61c1db1a5 100644 --- a/crypto/openssl/crypto/siphash/siphash.c +++ b/crypto/openssl/crypto/siphash/siphash.c @@ -1,7 +1,7 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -28,11 +28,6 @@ #include #include "crypto/siphash.h" -#include "siphash_local.h" - -/* default: SipHash-2-4 */ -#define SIPHASH_C_ROUNDS 2 -#define SIPHASH_D_ROUNDS 4 #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) @@ -146,7 +141,7 @@ void SipHash_Update(SIPHASH *ctx, const unsigned char *in, size_t inlen) uint64_t m; const uint8_t *end; int left; - int i; + unsigned int i; uint64_t v0 = ctx->v0; uint64_t v1 = ctx->v1; uint64_t v2 = ctx->v2; @@ -202,14 +197,14 @@ void SipHash_Update(SIPHASH *ctx, const unsigned char *in, size_t inlen) int SipHash_Final(SIPHASH *ctx, unsigned char *out, size_t outlen) { /* finalize hash */ - int i; + unsigned int i; uint64_t b = ctx->total_inlen << 56; uint64_t v0 = ctx->v0; uint64_t v1 = ctx->v1; uint64_t v2 = ctx->v2; uint64_t v3 = ctx->v3; - if (outlen != (size_t)ctx->hash_size) + if (ctx->crounds == 0 || outlen == 0 || outlen != (size_t)ctx->hash_size) return 0; switch (ctx->len) { diff --git a/crypto/openssl/crypto/siphash/siphash_ameth.c b/crypto/openssl/crypto/siphash/siphash_ameth.c deleted file mode 100644 index 7fce76390ef4..000000000000 --- a/crypto/openssl/crypto/siphash/siphash_ameth.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" -#include -#include "crypto/asn1.h" -#include "crypto/siphash.h" -#include "siphash_local.h" -#include "crypto/evp.h" - -/* - * SIPHASH "ASN1" method. This is just here to indicate the maximum - * SIPHASH output length and to free up a SIPHASH key. - */ - -static int siphash_size(const EVP_PKEY *pkey) -{ - return SIPHASH_MAX_DIGEST_SIZE; -} - -static void siphash_key_free(EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey); - - if (os != NULL) { - if (os->data != NULL) - OPENSSL_cleanse(os->data, os->length); - ASN1_OCTET_STRING_free(os); - } -} - -static int siphash_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - /* nothing (including ASN1_PKEY_CTRL_DEFAULT_MD_NID), is supported */ - return -2; -} - -static int siphash_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ - return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b)) == 0; -} - -static int siphash_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, - size_t len) -{ - ASN1_OCTET_STRING *os; - - if (pkey->pkey.ptr != NULL || len != SIPHASH_KEY_SIZE) - return 0; - - os = ASN1_OCTET_STRING_new(); - if (os == NULL) - return 0; - - if (!ASN1_OCTET_STRING_set(os, priv, len)) { - ASN1_OCTET_STRING_free(os); - return 0; - } - - pkey->pkey.ptr = os; - return 1; -} - -static int siphash_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, - size_t *len) -{ - ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; - - if (priv == NULL) { - *len = SIPHASH_KEY_SIZE; - return 1; - } - - if (os == NULL || *len < SIPHASH_KEY_SIZE) - return 0; - - memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os)); - *len = SIPHASH_KEY_SIZE; - - return 1; -} - -const EVP_PKEY_ASN1_METHOD siphash_asn1_meth = { - EVP_PKEY_SIPHASH, - EVP_PKEY_SIPHASH, - 0, - - "SIPHASH", - "OpenSSL SIPHASH method", - - 0, 0, siphash_pkey_public_cmp, 0, - - 0, 0, 0, - - siphash_size, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, - - siphash_key_free, - siphash_pkey_ctrl, - NULL, - NULL, - - NULL, - NULL, - NULL, - - NULL, - NULL, - NULL, - - siphash_set_priv_key, - NULL, - siphash_get_priv_key, - NULL, -}; diff --git a/crypto/openssl/crypto/siphash/siphash_local.h b/crypto/openssl/crypto/siphash/siphash_local.h deleted file mode 100644 index 5ad34764634d..000000000000 --- a/crypto/openssl/crypto/siphash/siphash_local.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2017 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 - */ - -/* Based on https://131002.net/siphash C reference implementation */ - -struct siphash_st { - uint64_t total_inlen; - uint64_t v0; - uint64_t v1; - uint64_t v2; - uint64_t v3; - unsigned int len; - int hash_size; - int crounds; - int drounds; - unsigned char leavings[SIPHASH_BLOCK_SIZE]; -}; diff --git a/crypto/openssl/crypto/siphash/siphash_pmeth.c b/crypto/openssl/crypto/siphash/siphash_pmeth.c deleted file mode 100644 index 0c7d2c61902c..000000000000 --- a/crypto/openssl/crypto/siphash/siphash_pmeth.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" -#include -#include -#include -#include -#include "crypto/siphash.h" -#include "siphash_local.h" -#include "crypto/evp.h" - -/* SIPHASH pkey context structure */ - -typedef struct siphash_pkey_ctx_st { - ASN1_OCTET_STRING ktmp; /* Temp storage for key */ - SIPHASH ctx; -} SIPHASH_PKEY_CTX; - -static int pkey_siphash_init(EVP_PKEY_CTX *ctx) -{ - SIPHASH_PKEY_CTX *pctx; - - if ((pctx = OPENSSL_zalloc(sizeof(*pctx))) == NULL) { - CRYPTOerr(CRYPTO_F_PKEY_SIPHASH_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - pctx->ktmp.type = V_ASN1_OCTET_STRING; - - EVP_PKEY_CTX_set_data(ctx, pctx); - EVP_PKEY_CTX_set0_keygen_info(ctx, NULL, 0); - return 1; -} - -static void pkey_siphash_cleanup(EVP_PKEY_CTX *ctx) -{ - SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx); - - if (pctx != NULL) { - OPENSSL_clear_free(pctx->ktmp.data, pctx->ktmp.length); - OPENSSL_clear_free(pctx, sizeof(*pctx)); - EVP_PKEY_CTX_set_data(ctx, NULL); - } -} - -static int pkey_siphash_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - SIPHASH_PKEY_CTX *sctx, *dctx; - - /* allocate memory for dst->data and a new SIPHASH_CTX in dst->data->ctx */ - if (!pkey_siphash_init(dst)) - return 0; - sctx = EVP_PKEY_CTX_get_data(src); - dctx = EVP_PKEY_CTX_get_data(dst); - if (ASN1_STRING_get0_data(&sctx->ktmp) != NULL && - !ASN1_STRING_copy(&dctx->ktmp, &sctx->ktmp)) { - /* cleanup and free the SIPHASH_PKEY_CTX in dst->data */ - pkey_siphash_cleanup(dst); - return 0; - } - memcpy(&dctx->ctx, &sctx->ctx, sizeof(SIPHASH)); - return 1; -} - -static int pkey_siphash_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *key; - SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx); - - if (ASN1_STRING_get0_data(&pctx->ktmp) == NULL) - return 0; - key = ASN1_OCTET_STRING_dup(&pctx->ktmp); - if (key == NULL) - return 0; - return EVP_PKEY_assign_SIPHASH(pkey, key); -} - -static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx)); - - SipHash_Update(&pctx->ctx, data, count); - return 1; -} - -static int siphash_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -{ - SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx); - const unsigned char* key; - size_t len; - - key = EVP_PKEY_get0_siphash(EVP_PKEY_CTX_get0_pkey(ctx), &len); - if (key == NULL || len != SIPHASH_KEY_SIZE) - return 0; - EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); - EVP_MD_CTX_set_update_fn(mctx, int_update); - return SipHash_Init(&pctx->ctx, key, 0, 0); -} -static int siphash_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - EVP_MD_CTX *mctx) -{ - SIPHASH_PKEY_CTX *pctx = ctx->data; - - *siglen = SipHash_hash_size(&pctx->ctx); - if (sig != NULL) - return SipHash_Final(&pctx->ctx, sig, *siglen); - return 1; -} - -static int pkey_siphash_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx); - const unsigned char *key; - size_t len; - - switch (type) { - - case EVP_PKEY_CTRL_MD: - /* ignore */ - break; - - case EVP_PKEY_CTRL_SET_DIGEST_SIZE: - return SipHash_set_hash_size(&pctx->ctx, p1); - - case EVP_PKEY_CTRL_SET_MAC_KEY: - case EVP_PKEY_CTRL_DIGESTINIT: - if (type == EVP_PKEY_CTRL_SET_MAC_KEY) { - /* user explicitly setting the key */ - key = p2; - len = p1; - } else { - /* user indirectly setting the key via EVP_DigestSignInit */ - key = EVP_PKEY_get0_siphash(EVP_PKEY_CTX_get0_pkey(ctx), &len); - } - if (key == NULL || len != SIPHASH_KEY_SIZE || - !ASN1_OCTET_STRING_set(&pctx->ktmp, key, len)) - return 0; - /* use default rounds (2,4) */ - return SipHash_Init(&pctx->ctx, ASN1_STRING_get0_data(&pctx->ktmp), - 0, 0); - - default: - return -2; - - } - return 1; -} - -static int pkey_siphash_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (value == NULL) - return 0; - if (strcmp(type, "digestsize") == 0) { - size_t hash_size = atoi(value); - - return pkey_siphash_ctrl(ctx, EVP_PKEY_CTRL_SET_DIGEST_SIZE, hash_size, - NULL); - } - if (strcmp(type, "key") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); - if (strcmp(type, "hexkey") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); - return -2; -} - -const EVP_PKEY_METHOD siphash_pkey_meth = { - EVP_PKEY_SIPHASH, - EVP_PKEY_FLAG_SIGCTX_CUSTOM, /* we don't deal with a separate MD */ - pkey_siphash_init, - pkey_siphash_copy, - pkey_siphash_cleanup, - - 0, 0, - - 0, - pkey_siphash_keygen, - - 0, 0, - - 0, 0, - - 0, 0, - - siphash_signctx_init, - siphash_signctx, - - 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_siphash_ctrl, - pkey_siphash_ctrl_str -}; diff --git a/crypto/openssl/crypto/sm2/build.info b/crypto/openssl/crypto/sm2/build.info index be76d96d3160..a50d08d0bc9a 100644 --- a/crypto/openssl/crypto/sm2/build.info +++ b/crypto/openssl/crypto/sm2/build.info @@ -1,5 +1,5 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - sm2_sign.c sm2_crypt.c sm2_err.c sm2_pmeth.c + sm2_sign.c sm2_crypt.c sm2_err.c sm2_key.c diff --git a/crypto/openssl/crypto/sm2/sm2_crypt.c b/crypto/openssl/crypto/sm2/sm2_crypt.c index 83b97f4edc88..5318c6199f68 100644 --- a/crypto/openssl/crypto/sm2/sm2_crypt.c +++ b/crypto/openssl/crypto/sm2/sm2_crypt.c @@ -3,15 +3,21 @@ * Copyright 2017 Ribose Inc. All Rights Reserved. * Ported from Ribose contributions from Botan. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "crypto/sm2.h" #include "crypto/sm2err.h" -#include "crypto/ec.h" /* ecdh_KDF_X9_63() */ +#include "crypto/ec.h" /* ossl_ecdh_kdf_X9_63() */ #include #include #include @@ -61,14 +67,15 @@ static size_t ec_field_size(const EC_GROUP *group) return field_size; } -int sm2_plaintext_size(const unsigned char *ct, size_t ct_size, size_t *pt_size) +int ossl_sm2_plaintext_size(const unsigned char *ct, size_t ct_size, + size_t *pt_size) { struct SM2_Ciphertext_st *sm2_ctext = NULL; sm2_ctext = d2i_SM2_Ciphertext(NULL, &ct, ct_size); if (sm2_ctext == NULL) { - SM2err(SM2_F_SM2_PLAINTEXT_SIZE, SM2_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_ENCODING); return 0; } @@ -78,11 +85,11 @@ int sm2_plaintext_size(const unsigned char *ct, size_t ct_size, size_t *pt_size) return 1; } -int sm2_ciphertext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len, - size_t *ct_size) +int ossl_sm2_ciphertext_size(const EC_KEY *key, const EVP_MD *digest, + size_t msg_len, size_t *ct_size) { const size_t field_size = ec_field_size(EC_KEY_get0_group(key)); - const int md_size = EVP_MD_size(digest); + const int md_size = EVP_MD_get_size(digest); size_t sz; if (field_size == 0 || md_size < 0) @@ -98,10 +105,10 @@ int sm2_ciphertext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len, return 1; } -int sm2_encrypt(const EC_KEY *key, - const EVP_MD *digest, - const uint8_t *msg, - size_t msg_len, uint8_t *ciphertext_buf, size_t *ciphertext_len) +int ossl_sm2_encrypt(const EC_KEY *key, + const EVP_MD *digest, + const uint8_t *msg, size_t msg_len, + uint8_t *ciphertext_buf, size_t *ciphertext_len) { int rc = 0, ciphertext_leni; size_t i; @@ -122,28 +129,31 @@ int sm2_encrypt(const EC_KEY *key, uint8_t *x2y2 = NULL; uint8_t *C3 = NULL; size_t field_size; - const int C3_size = EVP_MD_size(digest); + const int C3_size = EVP_MD_get_size(digest); + EVP_MD *fetched_digest = NULL; + OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key); + const char *propq = ossl_ec_key_get0_propq(key); /* NULL these before any "goto done" */ ctext_struct.C2 = NULL; ctext_struct.C3 = NULL; if (hash == NULL || C3_size <= 0) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } field_size = ec_field_size(group); if (field_size == 0) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } kG = EC_POINT_new(group); kP = EC_POINT_new(group); - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(libctx); if (kG == NULL || kP == NULL || ctx == NULL) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } @@ -155,7 +165,7 @@ int sm2_encrypt(const EC_KEY *key, y2 = BN_CTX_get(ctx); if (y2 == NULL) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } @@ -163,14 +173,14 @@ int sm2_encrypt(const EC_KEY *key, C3 = OPENSSL_zalloc(C3_size); if (x2y2 == NULL || C3 == NULL) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } memset(ciphertext_buf, 0, *ciphertext_len); - if (!BN_priv_rand_range(k, order)) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR); + if (!BN_priv_rand_range_ex(k, order, 0, ctx)) { + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } @@ -178,38 +188,43 @@ int sm2_encrypt(const EC_KEY *key, || !EC_POINT_get_affine_coordinates(group, kG, x1, y1, ctx) || !EC_POINT_mul(group, kP, NULL, P, k, ctx) || !EC_POINT_get_affine_coordinates(group, kP, x2, y2, ctx)) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB); goto done; } if (BN_bn2binpad(x2, x2y2, field_size) < 0 || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } msg_mask = OPENSSL_zalloc(msg_len); if (msg_mask == NULL) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } /* X9.63 with no salt happens to match the KDF used in SM2 */ - if (!ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, - digest)) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB); + if (!ossl_ecdh_kdf_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, + digest, libctx, propq)) { + ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); goto done; } for (i = 0; i != msg_len; ++i) msg_mask[i] ^= msg[i]; - if (EVP_DigestInit(hash, digest) == 0 + fetched_digest = EVP_MD_fetch(libctx, EVP_MD_get0_name(digest), propq); + if (fetched_digest == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); + goto done; + } + if (EVP_DigestInit(hash, fetched_digest) == 0 || EVP_DigestUpdate(hash, x2y2, field_size) == 0 || EVP_DigestUpdate(hash, msg, msg_len) == 0 || EVP_DigestUpdate(hash, x2y2 + field_size, field_size) == 0 || EVP_DigestFinal(hash, C3, NULL) == 0) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); goto done; } @@ -219,19 +234,19 @@ int sm2_encrypt(const EC_KEY *key, ctext_struct.C2 = ASN1_OCTET_STRING_new(); if (ctext_struct.C3 == NULL || ctext_struct.C2 == NULL) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } if (!ASN1_OCTET_STRING_set(ctext_struct.C3, C3, C3_size) || !ASN1_OCTET_STRING_set(ctext_struct.C2, msg_mask, msg_len)) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } ciphertext_leni = i2d_SM2_Ciphertext(&ctext_struct, &ciphertext_buf); /* Ensure cast to size_t is safe */ if (ciphertext_leni < 0) { - SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } *ciphertext_len = (size_t)ciphertext_leni; @@ -239,6 +254,7 @@ int sm2_encrypt(const EC_KEY *key, rc = 1; done: + EVP_MD_free(fetched_digest); ASN1_OCTET_STRING_free(ctext_struct.C2); ASN1_OCTET_STRING_free(ctext_struct.C3); OPENSSL_free(msg_mask); @@ -251,10 +267,10 @@ int sm2_encrypt(const EC_KEY *key, return rc; } -int sm2_decrypt(const EC_KEY *key, - const EVP_MD *digest, - const uint8_t *ciphertext, - size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len) +int ossl_sm2_decrypt(const EC_KEY *key, + const EVP_MD *digest, + const uint8_t *ciphertext, size_t ciphertext_len, + uint8_t *ptext_buf, size_t *ptext_len) { int rc = 0; int i; @@ -267,12 +283,14 @@ int sm2_decrypt(const EC_KEY *key, uint8_t *x2y2 = NULL; uint8_t *computed_C3 = NULL; const size_t field_size = ec_field_size(group); - const int hash_size = EVP_MD_size(digest); + const int hash_size = EVP_MD_get_size(digest); uint8_t *msg_mask = NULL; const uint8_t *C2 = NULL; const uint8_t *C3 = NULL; int msg_len = 0; EVP_MD_CTX *hash = NULL; + OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key); + const char *propq = ossl_ec_key_get0_propq(key); if (field_size == 0 || hash_size <= 0) goto done; @@ -282,12 +300,12 @@ int sm2_decrypt(const EC_KEY *key, sm2_ctext = d2i_SM2_Ciphertext(NULL, &ciphertext, ciphertext_len); if (sm2_ctext == NULL) { - SM2err(SM2_F_SM2_DECRYPT, SM2_R_ASN1_ERROR); + ERR_raise(ERR_LIB_SM2, SM2_R_ASN1_ERROR); goto done; } if (sm2_ctext->C3->length != hash_size) { - SM2err(SM2_F_SM2_DECRYPT, SM2_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_ENCODING); goto done; } @@ -295,13 +313,13 @@ int sm2_decrypt(const EC_KEY *key, C3 = sm2_ctext->C3->data; msg_len = sm2_ctext->C2->length; if (*ptext_len < (size_t)msg_len) { - SM2err(SM2_F_SM2_DECRYPT, SM2_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_SM2, SM2_R_BUFFER_TOO_SMALL); goto done; } - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(libctx); if (ctx == NULL) { - SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } @@ -310,7 +328,7 @@ int sm2_decrypt(const EC_KEY *key, y2 = BN_CTX_get(ctx); if (y2 == NULL) { - SM2err(SM2_F_SM2_DECRYPT, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } @@ -319,13 +337,13 @@ int sm2_decrypt(const EC_KEY *key, computed_C3 = OPENSSL_zalloc(hash_size); if (msg_mask == NULL || x2y2 == NULL || computed_C3 == NULL) { - SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } C1 = EC_POINT_new(group); if (C1 == NULL) { - SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } @@ -334,15 +352,15 @@ int sm2_decrypt(const EC_KEY *key, || !EC_POINT_mul(group, C1, NULL, C1, EC_KEY_get0_private_key(key), ctx) || !EC_POINT_get_affine_coordinates(group, C1, x2, y2, ctx)) { - SM2err(SM2_F_SM2_DECRYPT, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB); goto done; } if (BN_bn2binpad(x2, x2y2, field_size) < 0 || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0 - || !ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, - digest)) { - SM2err(SM2_F_SM2_DECRYPT, ERR_R_INTERNAL_ERROR); + || !ossl_ecdh_kdf_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, + NULL, 0, digest, libctx, propq)) { + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } @@ -351,7 +369,7 @@ int sm2_decrypt(const EC_KEY *key, hash = EVP_MD_CTX_new(); if (hash == NULL) { - SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } @@ -360,12 +378,12 @@ int sm2_decrypt(const EC_KEY *key, || !EVP_DigestUpdate(hash, ptext_buf, msg_len) || !EVP_DigestUpdate(hash, x2y2 + field_size, field_size) || !EVP_DigestFinal(hash, computed_C3, NULL)) { - SM2err(SM2_F_SM2_DECRYPT, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); goto done; } if (CRYPTO_memcmp(computed_C3, C3, hash_size) != 0) { - SM2err(SM2_F_SM2_DECRYPT, SM2_R_INVALID_DIGEST); + ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_DIGEST); goto done; } diff --git a/crypto/openssl/crypto/sm2/sm2_err.c b/crypto/openssl/crypto/sm2/sm2_err.c index e5973e9c7140..d420d4e597d1 100644 --- a/crypto/openssl/crypto/sm2/sm2_err.c +++ b/crypto/openssl/crypto/sm2/sm2_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,31 +11,9 @@ #include #include "crypto/sm2err.h" -#ifndef OPENSSL_NO_ERR +#ifndef OPENSSL_NO_SM2 -static const ERR_STRING_DATA SM2_str_functs[] = { - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_COPY, 0), "pkey_sm2_copy"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_CTRL, 0), "pkey_sm2_ctrl"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_CTRL_STR, 0), "pkey_sm2_ctrl_str"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_DIGEST_CUSTOM, 0), - "pkey_sm2_digest_custom"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_INIT, 0), "pkey_sm2_init"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_SIGN, 0), "pkey_sm2_sign"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_MSG_HASH, 0), - "sm2_compute_msg_hash"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_USERID_DIGEST, 0), - "sm2_compute_userid_digest"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_Z_DIGEST, 0), - "sm2_compute_z_digest"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_DECRYPT, 0), "sm2_decrypt"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_ENCRYPT, 0), "sm2_encrypt"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_PLAINTEXT_SIZE, 0), "sm2_plaintext_size"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIGN, 0), "sm2_sign"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIG_GEN, 0), "sm2_sig_gen"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIG_VERIFY, 0), "sm2_sig_verify"}, - {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_VERIFY, 0), "sm2_verify"}, - {0, NULL} -}; +# ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA SM2_str_reasons[] = { {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ASN1_ERROR), "asn1 error"}, @@ -50,20 +28,23 @@ static const ERR_STRING_DATA SM2_str_reasons[] = { "invalid digest type"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_ENCODING), "invalid encoding"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_FIELD), "invalid field"}, + {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_PRIVATE_KEY), + "invalid private key"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PARAMETERS_SET), "no parameters set"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_USER_ID_TOO_LARGE), "user id too large"}, {0, NULL} }; -#endif +# endif -int ERR_load_SM2_strings(void) +int ossl_err_load_SM2_strings(void) { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(SM2_str_functs[0].error) == NULL) { - ERR_load_strings_const(SM2_str_functs); +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(SM2_str_reasons[0].error) == NULL) ERR_load_strings_const(SM2_str_reasons); - } -#endif +# endif return 1; } +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/sm2/sm2_key.c b/crypto/openssl/crypto/sm2/sm2_key.c new file mode 100644 index 000000000000..9d0b9208facf --- /dev/null +++ b/crypto/openssl/crypto/sm2/sm2_key.c @@ -0,0 +1,51 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/deprecated.h" /* to be able to use EC_KEY and EC_GROUP */ + +#include +#include "crypto/sm2err.h" +#include "crypto/sm2.h" +#include /* EC_KEY and EC_GROUP functions */ + +/* + * SM2 key generation is implemented within ec_generate_key() in + * crypto/ec/ec_key.c + */ + +int ossl_sm2_key_private_check(const EC_KEY *eckey) +{ + int ret = 0; + BIGNUM *max = NULL; + const EC_GROUP *group = NULL; + const BIGNUM *priv_key = NULL, *order = NULL; + + if (eckey == NULL + || (group = EC_KEY_get0_group(eckey)) == NULL + || (priv_key = EC_KEY_get0_private_key(eckey)) == NULL + || (order = EC_GROUP_get0_order(group)) == NULL ) { + ERR_raise(ERR_LIB_SM2, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* range of SM2 private key is [1, n-1) */ + max = BN_dup(order); + if (max == NULL || !BN_sub_word(max, 1)) + goto end; + if (BN_cmp(priv_key, BN_value_one()) < 0 + || BN_cmp(priv_key, max) >= 0) { + ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_PRIVATE_KEY); + goto end; + } + ret = 1; + + end: + BN_free(max); + return ret; +} diff --git a/crypto/openssl/crypto/sm2/sm2_pmeth.c b/crypto/openssl/crypto/sm2/sm2_pmeth.c deleted file mode 100644 index 0e722b910b57..000000000000 --- a/crypto/openssl/crypto/sm2/sm2_pmeth.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "internal/cryptlib.h" -#include -#include -#include -#include "crypto/evp.h" -#include "crypto/sm2.h" -#include "crypto/sm2err.h" - -/* EC pkey context structure */ - -typedef struct { - /* Key and paramgen group */ - EC_GROUP *gen_group; - /* message digest */ - const EVP_MD *md; - /* Distinguishing Identifier, ISO/IEC 15946-3 */ - uint8_t *id; - size_t id_len; - /* id_set indicates if the 'id' field is set (1) or not (0) */ - int id_set; -} SM2_PKEY_CTX; - -static int pkey_sm2_init(EVP_PKEY_CTX *ctx) -{ - SM2_PKEY_CTX *smctx; - - if ((smctx = OPENSSL_zalloc(sizeof(*smctx))) == NULL) { - SM2err(SM2_F_PKEY_SM2_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - - ctx->data = smctx; - return 1; -} - -static void pkey_sm2_cleanup(EVP_PKEY_CTX *ctx) -{ - SM2_PKEY_CTX *smctx = ctx->data; - - if (smctx != NULL) { - EC_GROUP_free(smctx->gen_group); - OPENSSL_free(smctx->id); - OPENSSL_free(smctx); - ctx->data = NULL; - } -} - -static int pkey_sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - SM2_PKEY_CTX *dctx, *sctx; - - if (!pkey_sm2_init(dst)) - return 0; - sctx = src->data; - dctx = dst->data; - if (sctx->gen_group != NULL) { - dctx->gen_group = EC_GROUP_dup(sctx->gen_group); - if (dctx->gen_group == NULL) { - pkey_sm2_cleanup(dst); - return 0; - } - } - if (sctx->id != NULL) { - dctx->id = OPENSSL_malloc(sctx->id_len); - if (dctx->id == NULL) { - SM2err(SM2_F_PKEY_SM2_COPY, ERR_R_MALLOC_FAILURE); - pkey_sm2_cleanup(dst); - return 0; - } - memcpy(dctx->id, sctx->id, sctx->id_len); - } - dctx->id_len = sctx->id_len; - dctx->id_set = sctx->id_set; - dctx->md = sctx->md; - - return 1; -} - -static int pkey_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - const unsigned char *tbs, size_t tbslen) -{ - int ret; - unsigned int sltmp; - EC_KEY *ec = ctx->pkey->pkey.ec; - const int sig_sz = ECDSA_size(ctx->pkey->pkey.ec); - - if (sig_sz <= 0) { - return 0; - } - - if (sig == NULL) { - *siglen = (size_t)sig_sz; - return 1; - } - - if (*siglen < (size_t)sig_sz) { - SM2err(SM2_F_PKEY_SM2_SIGN, SM2_R_BUFFER_TOO_SMALL); - return 0; - } - - ret = sm2_sign(tbs, tbslen, sig, &sltmp, ec); - - if (ret <= 0) - return ret; - *siglen = (size_t)sltmp; - return 1; -} - -static int pkey_sm2_verify(EVP_PKEY_CTX *ctx, - const unsigned char *sig, size_t siglen, - const unsigned char *tbs, size_t tbslen) -{ - EC_KEY *ec = ctx->pkey->pkey.ec; - - return sm2_verify(tbs, tbslen, sig, siglen, ec); -} - -static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen) -{ - EC_KEY *ec = ctx->pkey->pkey.ec; - SM2_PKEY_CTX *dctx = ctx->data; - const EVP_MD *md = (dctx->md == NULL) ? EVP_sm3() : dctx->md; - - if (out == NULL) { - if (!sm2_ciphertext_size(ec, md, inlen, outlen)) - return -1; - else - return 1; - } - - return sm2_encrypt(ec, md, in, inlen, out, outlen); -} - -static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen) -{ - EC_KEY *ec = ctx->pkey->pkey.ec; - SM2_PKEY_CTX *dctx = ctx->data; - const EVP_MD *md = (dctx->md == NULL) ? EVP_sm3() : dctx->md; - - if (out == NULL) { - if (!sm2_plaintext_size(in, inlen, outlen)) - return -1; - else - return 1; - } - - return sm2_decrypt(ec, md, in, inlen, out, outlen); -} - -static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - SM2_PKEY_CTX *smctx = ctx->data; - EC_GROUP *group; - uint8_t *tmp_id; - - switch (type) { - case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: - group = EC_GROUP_new_by_curve_name(p1); - if (group == NULL) { - SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_INVALID_CURVE); - return 0; - } - EC_GROUP_free(smctx->gen_group); - smctx->gen_group = group; - return 1; - - case EVP_PKEY_CTRL_EC_PARAM_ENC: - if (smctx->gen_group == NULL) { - SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_NO_PARAMETERS_SET); - return 0; - } - EC_GROUP_set_asn1_flag(smctx->gen_group, p1); - return 1; - - case EVP_PKEY_CTRL_MD: - smctx->md = p2; - return 1; - - case EVP_PKEY_CTRL_GET_MD: - *(const EVP_MD **)p2 = smctx->md; - return 1; - - case EVP_PKEY_CTRL_SET1_ID: - if (p1 > 0) { - tmp_id = OPENSSL_malloc(p1); - if (tmp_id == NULL) { - SM2err(SM2_F_PKEY_SM2_CTRL, ERR_R_MALLOC_FAILURE); - return 0; - } - memcpy(tmp_id, p2, p1); - OPENSSL_free(smctx->id); - smctx->id = tmp_id; - } else { - /* set null-ID */ - OPENSSL_free(smctx->id); - smctx->id = NULL; - } - smctx->id_len = (size_t)p1; - smctx->id_set = 1; - return 1; - - case EVP_PKEY_CTRL_GET1_ID: - memcpy(p2, smctx->id, smctx->id_len); - return 1; - - case EVP_PKEY_CTRL_GET1_ID_LEN: - *(size_t *)p2 = smctx->id_len; - return 1; - - case EVP_PKEY_CTRL_DIGESTINIT: - /* nothing to be inited, this is to suppress the error... */ - return 1; - - default: - return -2; - } -} - -static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (strcmp(type, "ec_paramgen_curve") == 0) { - int nid = NID_undef; - - if (((nid = EC_curve_nist2nid(value)) == NID_undef) - && ((nid = OBJ_sn2nid(value)) == NID_undef) - && ((nid = OBJ_ln2nid(value)) == NID_undef)) { - SM2err(SM2_F_PKEY_SM2_CTRL_STR, SM2_R_INVALID_CURVE); - return 0; - } - return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); - } else if (strcmp(type, "ec_param_enc") == 0) { - int param_enc; - - if (strcmp(value, "explicit") == 0) - param_enc = 0; - else if (strcmp(value, "named_curve") == 0) - param_enc = OPENSSL_EC_NAMED_CURVE; - else - return -2; - return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc); - } - - return -2; -} - -static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -{ - uint8_t z[EVP_MAX_MD_SIZE]; - SM2_PKEY_CTX *smctx = ctx->data; - EC_KEY *ec = ctx->pkey->pkey.ec; - const EVP_MD *md = EVP_MD_CTX_md(mctx); - int mdlen = EVP_MD_size(md); - - if (!smctx->id_set) { - /* - * An ID value must be set. The specifications are not clear whether a - * NULL is allowed. We only allow it if set explicitly for maximum - * flexibility. - */ - SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_ID_NOT_SET); - return 0; - } - - if (mdlen < 0) { - SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_INVALID_DIGEST); - return 0; - } - - /* get hashed prefix 'z' of tbs message */ - if (!sm2_compute_z_digest(z, md, smctx->id, smctx->id_len, ec)) - return 0; - - return EVP_DigestUpdate(mctx, z, (size_t)mdlen); -} - -const EVP_PKEY_METHOD sm2_pkey_meth = { - EVP_PKEY_SM2, - 0, - pkey_sm2_init, - pkey_sm2_copy, - pkey_sm2_cleanup, - - 0, - 0, - - 0, - 0, - - 0, - pkey_sm2_sign, - - 0, - pkey_sm2_verify, - - 0, 0, - - 0, 0, 0, 0, - - 0, - pkey_sm2_encrypt, - - 0, - pkey_sm2_decrypt, - - 0, - 0, - pkey_sm2_ctrl, - pkey_sm2_ctrl_str, - - 0, 0, - - 0, 0, 0, - - pkey_sm2_digest_custom -}; diff --git a/crypto/openssl/crypto/sm2/sm2_sign.c b/crypto/openssl/crypto/sm2/sm2_sign.c index 683f03f93580..5861f420fb66 100644 --- a/crypto/openssl/crypto/sm2/sm2_sign.c +++ b/crypto/openssl/crypto/sm2/sm2_sign.c @@ -1,17 +1,19 @@ /* - * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 Ribose Inc. All Rights Reserved. * Ported from Ribose contributions from Botan. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#include "internal/deprecated.h" + #include "crypto/sm2.h" #include "crypto/sm2err.h" -#include "crypto/ec.h" /* ec_group_do_inverse_ord() */ +#include "crypto/ec.h" /* ossl_ec_group_do_inverse_ord() */ #include "internal/numbers.h" #include #include @@ -19,11 +21,11 @@ #include #include -int sm2_compute_z_digest(uint8_t *out, - const EVP_MD *digest, - const uint8_t *id, - const size_t id_len, - const EC_KEY *key) +int ossl_sm2_compute_z_digest(uint8_t *out, + const EVP_MD *digest, + const uint8_t *id, + const size_t id_len, + const EC_KEY *key) { int rc = 0; const EC_GROUP *group = EC_KEY_get0_group(key); @@ -42,9 +44,9 @@ int sm2_compute_z_digest(uint8_t *out, uint8_t e_byte = 0; hash = EVP_MD_CTX_new(); - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(key)); if (hash == NULL || ctx == NULL) { - SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } @@ -57,12 +59,12 @@ int sm2_compute_z_digest(uint8_t *out, yA = BN_CTX_get(ctx); if (yA == NULL) { - SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } if (!EVP_DigestInit(hash, digest)) { - SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); goto done; } @@ -70,7 +72,7 @@ int sm2_compute_z_digest(uint8_t *out, if (id_len >= (UINT16_MAX / 8)) { /* too large */ - SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, SM2_R_ID_TOO_LARGE); + ERR_raise(ERR_LIB_SM2, SM2_R_ID_TOO_LARGE); goto done; } @@ -78,29 +80,29 @@ int sm2_compute_z_digest(uint8_t *out, e_byte = entl >> 8; if (!EVP_DigestUpdate(hash, &e_byte, 1)) { - SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); goto done; } e_byte = entl & 0xFF; if (!EVP_DigestUpdate(hash, &e_byte, 1)) { - SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); goto done; } if (id_len > 0 && !EVP_DigestUpdate(hash, id, id_len)) { - SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); goto done; } if (!EC_GROUP_get_curve(group, p, a, b, ctx)) { - SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB); goto done; } p_bytes = BN_num_bytes(p); buf = OPENSSL_zalloc(p_bytes); if (buf == NULL) { - SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } @@ -123,7 +125,7 @@ int sm2_compute_z_digest(uint8_t *out, || BN_bn2binpad(yA, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || !EVP_DigestFinal(hash, out, NULL)) { - SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } @@ -143,40 +145,50 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest, const uint8_t *msg, size_t msg_len) { EVP_MD_CTX *hash = EVP_MD_CTX_new(); - const int md_size = EVP_MD_size(digest); + const int md_size = EVP_MD_get_size(digest); uint8_t *z = NULL; BIGNUM *e = NULL; + EVP_MD *fetched_digest = NULL; + OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key); + const char *propq = ossl_ec_key_get0_propq(key); if (md_size < 0) { - SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, SM2_R_INVALID_DIGEST); + ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_DIGEST); goto done; } z = OPENSSL_zalloc(md_size); if (hash == NULL || z == NULL) { - SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } - if (!sm2_compute_z_digest(z, digest, id, id_len, key)) { + fetched_digest = EVP_MD_fetch(libctx, EVP_MD_get0_name(digest), propq); + if (fetched_digest == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); + goto done; + } + + if (!ossl_sm2_compute_z_digest(z, fetched_digest, id, id_len, key)) { /* SM2err already called */ goto done; } - if (!EVP_DigestInit(hash, digest) + if (!EVP_DigestInit(hash, fetched_digest) || !EVP_DigestUpdate(hash, z, md_size) || !EVP_DigestUpdate(hash, msg, msg_len) /* reuse z buffer to hold H(Z || M) */ || !EVP_DigestFinal(hash, z, NULL)) { - SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); goto done; } e = BN_bin2bn(z, md_size, NULL); if (e == NULL) - SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); done: + EVP_MD_free(fetched_digest); OPENSSL_free(z); EVP_MD_CTX_free(hash); return e; @@ -196,11 +208,12 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) BIGNUM *s = NULL; BIGNUM *x1 = NULL; BIGNUM *tmp = NULL; + OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key); kG = EC_POINT_new(group); - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(libctx); if (kG == NULL || ctx == NULL) { - SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } @@ -210,7 +223,7 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) x1 = BN_CTX_get(ctx); tmp = BN_CTX_get(ctx); if (tmp == NULL) { - SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } @@ -222,13 +235,22 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) s = BN_new(); if (r == NULL || s == NULL) { - SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } + /* + * A3: Generate a random number k in [1,n-1] using random number generators; + * A4: Compute (x1,y1)=[k]G, and convert the type of data x1 to be integer + * as specified in clause 4.2.8 of GM/T 0003.1-2012; + * A5: Compute r=(e+x1) mod n. If r=0 or r+k=n, then go to A3; + * A6: Compute s=(1/(1+dA)*(k-r*dA)) mod n. If s=0, then go to A3; + * A7: Convert the type of data (r,s) to be bit strings according to the details + * in clause 4.2.2 of GM/T 0003.1-2012. Then the signature of message M is (r,s). + */ for (;;) { - if (!BN_priv_rand_range(k, order)) { - SM2err(SM2_F_SM2_SIG_GEN, ERR_R_INTERNAL_ERROR); + if (!BN_priv_rand_range_ex(k, order, 0, ctx)) { + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } @@ -236,7 +258,7 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) || !EC_POINT_get_affine_coordinates(group, kG, x1, NULL, ctx) || !BN_mod_add(r, e, x1, order, ctx)) { - SM2err(SM2_F_SM2_SIG_GEN, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } @@ -245,7 +267,7 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) continue; if (!BN_add(rk, r, k)) { - SM2err(SM2_F_SM2_SIG_GEN, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } @@ -253,17 +275,21 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) continue; if (!BN_add(s, dA, BN_value_one()) - || !ec_group_do_inverse_ord(group, s, s, ctx) + || !ossl_ec_group_do_inverse_ord(group, s, s, ctx) || !BN_mod_mul(tmp, dA, r, order, ctx) || !BN_sub(tmp, k, tmp) || !BN_mod_mul(s, s, tmp, order, ctx)) { - SM2err(SM2_F_SM2_SIG_GEN, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } + /* try again if s == 0 */ + if (BN_is_zero(s)) + continue; + sig = ECDSA_SIG_new(); if (sig == NULL) { - SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } @@ -295,11 +321,12 @@ static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, BIGNUM *x1 = NULL; const BIGNUM *r = NULL; const BIGNUM *s = NULL; + OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key); - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(libctx); pt = EC_POINT_new(group); if (ctx == NULL || pt == NULL) { - SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } @@ -307,7 +334,7 @@ static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, t = BN_CTX_get(ctx); x1 = BN_CTX_get(ctx); if (x1 == NULL) { - SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } @@ -327,28 +354,28 @@ static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, || BN_cmp(s, BN_value_one()) < 0 || BN_cmp(order, r) <= 0 || BN_cmp(order, s) <= 0) { - SM2err(SM2_F_SM2_SIG_VERIFY, SM2_R_BAD_SIGNATURE); + ERR_raise(ERR_LIB_SM2, SM2_R_BAD_SIGNATURE); goto done; } if (!BN_mod_add(t, r, s, order, ctx)) { - SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } if (BN_is_zero(t)) { - SM2err(SM2_F_SM2_SIG_VERIFY, SM2_R_BAD_SIGNATURE); + ERR_raise(ERR_LIB_SM2, SM2_R_BAD_SIGNATURE); goto done; } if (!EC_POINT_mul(group, pt, s, EC_KEY_get0_public_key(key), t, ctx) || !EC_POINT_get_affine_coordinates(group, pt, x1, NULL, ctx)) { - SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_EC_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB); goto done; } if (!BN_mod_add(t, e, x1, order, ctx)) { - SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } @@ -361,11 +388,11 @@ static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, return ret; } -ECDSA_SIG *sm2_do_sign(const EC_KEY *key, - const EVP_MD *digest, - const uint8_t *id, - const size_t id_len, - const uint8_t *msg, size_t msg_len) +ECDSA_SIG *ossl_sm2_do_sign(const EC_KEY *key, + const EVP_MD *digest, + const uint8_t *id, + const size_t id_len, + const uint8_t *msg, size_t msg_len) { BIGNUM *e = NULL; ECDSA_SIG *sig = NULL; @@ -383,12 +410,12 @@ ECDSA_SIG *sm2_do_sign(const EC_KEY *key, return sig; } -int sm2_do_verify(const EC_KEY *key, - const EVP_MD *digest, - const ECDSA_SIG *sig, - const uint8_t *id, - const size_t id_len, - const uint8_t *msg, size_t msg_len) +int ossl_sm2_do_verify(const EC_KEY *key, + const EVP_MD *digest, + const ECDSA_SIG *sig, + const uint8_t *id, + const size_t id_len, + const uint8_t *msg, size_t msg_len) { BIGNUM *e = NULL; int ret = 0; @@ -406,8 +433,9 @@ int sm2_do_verify(const EC_KEY *key, return ret; } -int sm2_sign(const unsigned char *dgst, int dgstlen, - unsigned char *sig, unsigned int *siglen, EC_KEY *eckey) +int ossl_sm2_internal_sign(const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, + EC_KEY *eckey) { BIGNUM *e = NULL; ECDSA_SIG *s = NULL; @@ -416,15 +444,19 @@ int sm2_sign(const unsigned char *dgst, int dgstlen, e = BN_bin2bn(dgst, dgstlen, NULL); if (e == NULL) { - SM2err(SM2_F_SM2_SIGN, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } s = sm2_sig_gen(eckey, e); + if (s == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); + goto done; + } sigleni = i2d_ECDSA_SIG(s, &sig); if (sigleni < 0) { - SM2err(SM2_F_SM2_SIGN, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; } *siglen = (unsigned int)sigleni; @@ -437,8 +469,9 @@ int sm2_sign(const unsigned char *dgst, int dgstlen, return ret; } -int sm2_verify(const unsigned char *dgst, int dgstlen, - const unsigned char *sig, int sig_len, EC_KEY *eckey) +int ossl_sm2_internal_verify(const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int sig_len, + EC_KEY *eckey) { ECDSA_SIG *s = NULL; BIGNUM *e = NULL; @@ -449,23 +482,23 @@ int sm2_verify(const unsigned char *dgst, int dgstlen, s = ECDSA_SIG_new(); if (s == NULL) { - SM2err(SM2_F_SM2_VERIFY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); goto done; } if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) { - SM2err(SM2_F_SM2_VERIFY, SM2_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_ENCODING); goto done; } /* Ensure signature uses DER and doesn't have trailing garbage */ derlen = i2d_ECDSA_SIG(s, &der); if (derlen != sig_len || memcmp(sig, der, derlen) != 0) { - SM2err(SM2_F_SM2_VERIFY, SM2_R_INVALID_ENCODING); + ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_ENCODING); goto done; } e = BN_bin2bn(dgst, dgstlen, NULL); if (e == NULL) { - SM2err(SM2_F_SM2_VERIFY, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } diff --git a/crypto/openssl/crypto/sm3/build.info b/crypto/openssl/crypto/sm3/build.info index 6009b1949eb6..eca68216f27e 100644 --- a/crypto/openssl/crypto/sm3/build.info +++ b/crypto/openssl/crypto/sm3/build.info @@ -1,2 +1,5 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=sm3.c m_sm3.c + +IF[{- !$disabled{sm3} -}] + SOURCE[../../libcrypto]=sm3.c legacy_sm3.c +ENDIF \ No newline at end of file diff --git a/crypto/openssl/crypto/sm3/legacy_sm3.c b/crypto/openssl/crypto/sm3/legacy_sm3.c new file mode 100644 index 000000000000..c81f3b4ab45d --- /dev/null +++ b/crypto/openssl/crypto/sm3/legacy_sm3.c @@ -0,0 +1,31 @@ +/* + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017 Ribose Inc. 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 "crypto/evp.h" +#include "../evp/legacy_meth.h" +#include "internal/sm3.h" + +IMPLEMENT_LEGACY_EVP_MD_METH_LC(sm3_int, ossl_sm3) + +static const EVP_MD sm3_md = { + NID_sm3, + NID_sm3WithRSAEncryption, + SM3_DIGEST_LENGTH, + 0, + EVP_ORIG_GLOBAL, + LEGACY_EVP_MD_METH_TABLE(sm3_int_init, sm3_int_update, sm3_int_final, NULL, + SM3_CBLOCK), +}; + +const EVP_MD *EVP_sm3(void) +{ + return &sm3_md; +} diff --git a/crypto/openssl/crypto/sm3/m_sm3.c b/crypto/openssl/crypto/sm3/m_sm3.c deleted file mode 100644 index 7e54f4298431..000000000000 --- a/crypto/openssl/crypto/sm3/m_sm3.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. - * Copyright 2017 Ribose Inc. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "internal/cryptlib.h" - -#ifndef OPENSSL_NO_SM3 -# include -# include "crypto/evp.h" -# include "crypto/sm3.h" - -static int init(EVP_MD_CTX *ctx) -{ - return sm3_init(EVP_MD_CTX_md_data(ctx)); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return sm3_update(EVP_MD_CTX_md_data(ctx), data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return sm3_final(md, EVP_MD_CTX_md_data(ctx)); -} - -static const EVP_MD sm3_md = { - NID_sm3, - NID_sm3WithRSAEncryption, - SM3_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - SM3_CBLOCK, - sizeof(EVP_MD *) + sizeof(SM3_CTX), -}; - -const EVP_MD *EVP_sm3(void) -{ - return &sm3_md; -} - -#endif diff --git a/crypto/openssl/crypto/sm3/sm3.c b/crypto/openssl/crypto/sm3/sm3.c index d78292b4c5b7..ff78fb763e00 100644 --- a/crypto/openssl/crypto/sm3/sm3.c +++ b/crypto/openssl/crypto/sm3/sm3.c @@ -1,9 +1,9 @@ /* - * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 Ribose Inc. All Rights Reserved. * Ported from Ribose contributions from Botan. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,7 +12,7 @@ #include #include "sm3_local.h" -int sm3_init(SM3_CTX *c) +int ossl_sm3_init(SM3_CTX *c) { memset(c, 0, sizeof(*c)); c->A = SM3_A; @@ -26,7 +26,7 @@ int sm3_init(SM3_CTX *c) return 1; } -void sm3_block_data_order(SM3_CTX *ctx, const void *p, size_t num) +void ossl_sm3_block_data_order(SM3_CTX *ctx, const void *p, size_t num) { const unsigned char *data = p; register unsigned MD32_REG_T A, B, C, D, E, F, G, H; @@ -193,4 +193,3 @@ void sm3_block_data_order(SM3_CTX *ctx, const void *p, size_t num) ctx->H ^= H; } } - diff --git a/crypto/openssl/crypto/sm3/sm3_local.h b/crypto/openssl/crypto/sm3/sm3_local.h index 7171de510de3..6daeb878a887 100644 --- a/crypto/openssl/crypto/sm3/sm3_local.h +++ b/crypto/openssl/crypto/sm3/sm3_local.h @@ -1,25 +1,25 @@ /* - * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 Ribose Inc. All Rights Reserved. * Ported from Ribose contributions from Botan. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include -#include "crypto/sm3.h" +#include "internal/sm3.h" #define DATA_ORDER_IS_BIG_ENDIAN #define HASH_LONG SM3_WORD #define HASH_CTX SM3_CTX #define HASH_CBLOCK SM3_CBLOCK -#define HASH_UPDATE sm3_update -#define HASH_TRANSFORM sm3_transform -#define HASH_FINAL sm3_final +#define HASH_UPDATE ossl_sm3_update +#define HASH_TRANSFORM ossl_sm3_transform +#define HASH_FINAL ossl_sm3_final #define HASH_MAKE_STRING(c, s) \ do { \ unsigned long ll; \ @@ -32,9 +32,10 @@ ll=(c)->G; (void)HOST_l2c(ll, (s)); \ ll=(c)->H; (void)HOST_l2c(ll, (s)); \ } while (0) -#define HASH_BLOCK_DATA_ORDER sm3_block_data_order +#define HASH_BLOCK_DATA_ORDER ossl_sm3_block_data_order -void sm3_transform(SM3_CTX *c, const unsigned char *data); +void ossl_sm3_block_data_order(SM3_CTX *c, const void *p, size_t num); +void ossl_sm3_transform(SM3_CTX *c, const unsigned char *data); #include "crypto/md32_common.h" diff --git a/crypto/openssl/crypto/sm4/sm4.c b/crypto/openssl/crypto/sm4/sm4.c index 5750e763319a..1e11ee650632 100644 --- a/crypto/openssl/crypto/sm4/sm4.c +++ b/crypto/openssl/crypto/sm4/sm4.c @@ -1,9 +1,9 @@ /* - * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 Ribose Inc. All Rights Reserved. * Ported from Ribose contributions from Botan. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -129,7 +129,7 @@ static ossl_inline uint32_t SM4_T(uint32_t X) rotl(SM4_SBOX_T[(uint8_t)X], 8); } -int SM4_set_key(const uint8_t *key, SM4_KEY *ks) +int ossl_sm4_set_key(const uint8_t *key, SM4_KEY *ks) { /* * Family Key @@ -184,7 +184,7 @@ int SM4_set_key(const uint8_t *key, SM4_KEY *ks) B3 ^= F(B0 ^ B1 ^ B2 ^ ks->rk[k3]); \ } while(0) -void SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks) +void ossl_sm4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks) { uint32_t B0 = load_u32_be(in, 0); uint32_t B1 = load_u32_be(in, 1); @@ -210,7 +210,7 @@ void SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks) store_u32_be(B0, out + 12); } -void SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks) +void ossl_sm4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks) { uint32_t B0 = load_u32_be(in, 0); uint32_t B1 = load_u32_be(in, 1); diff --git a/crypto/openssl/crypto/sparccpuid.S b/crypto/openssl/crypto/sparccpuid.S index 95acd2f9d4d2..4771dd508793 100644 --- a/crypto/openssl/crypto/sparccpuid.S +++ b/crypto/openssl/crypto/sparccpuid.S @@ -1,6 +1,6 @@ ! Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. ! -! Licensed under the OpenSSL license (the "License"). You may not use +! 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 diff --git a/crypto/openssl/crypto/sparcv9cap.c b/crypto/openssl/crypto/sparcv9cap.c index b3cb3d4be958..53c0c3e0456b 100644 --- a/crypto/openssl/crypto/sparcv9cap.c +++ b/crypto/openssl/crypto/sparcv9cap.c @@ -1,7 +1,7 @@ /* * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -16,78 +16,13 @@ #include #include #include "internal/cryptlib.h" -#include "bn/bn_local.h" /* for definition of bn_mul_mont */ - -#include "sparc_arch.h" +#include "crypto/sparc_arch.h" #if defined(__GNUC__) && defined(__linux) __attribute__ ((visibility("hidden"))) #endif unsigned int OPENSSL_sparcv9cap_P[2] = { SPARCV9_TICK_PRIVILEGED, 0 }; -int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, int num) -{ - int bn_mul_mont_vis3(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, int num); - int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, int num); - int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, int num); - - if (!(num & 1) && num >= 6) { - if ((num & 15) == 0 && num <= 64 && - (OPENSSL_sparcv9cap_P[1] & (CFR_MONTMUL | CFR_MONTSQR)) == - (CFR_MONTMUL | CFR_MONTSQR)) { - typedef int (*bn_mul_mont_f) (BN_ULONG *rp, const BN_ULONG *ap, - const BN_ULONG *bp, - const BN_ULONG *np, - const BN_ULONG *n0); - int bn_mul_mont_t4_8(BN_ULONG *rp, const BN_ULONG *ap, - const BN_ULONG *bp, const BN_ULONG *np, - const BN_ULONG *n0); - int bn_mul_mont_t4_16(BN_ULONG *rp, const BN_ULONG *ap, - const BN_ULONG *bp, const BN_ULONG *np, - const BN_ULONG *n0); - int bn_mul_mont_t4_24(BN_ULONG *rp, const BN_ULONG *ap, - const BN_ULONG *bp, const BN_ULONG *np, - const BN_ULONG *n0); - int bn_mul_mont_t4_32(BN_ULONG *rp, const BN_ULONG *ap, - const BN_ULONG *bp, const BN_ULONG *np, - const BN_ULONG *n0); - static const bn_mul_mont_f funcs[4] = { - bn_mul_mont_t4_8, bn_mul_mont_t4_16, - bn_mul_mont_t4_24, bn_mul_mont_t4_32 - }; - bn_mul_mont_f worker = funcs[num / 16 - 1]; - - if ((*worker) (rp, ap, bp, np, n0)) - return 1; - /* retry once and fall back */ - if ((*worker) (rp, ap, bp, np, n0)) - return 1; - return bn_mul_mont_vis3(rp, ap, bp, np, n0, num); - } - if ((OPENSSL_sparcv9cap_P[0] & SPARCV9_VIS3)) - return bn_mul_mont_vis3(rp, ap, bp, np, n0, num); - else if (num >= 8 && - /* - * bn_mul_mont_fpu doesn't use FMADD, we just use the - * flag to detect when FPU path is preferable in cases - * when current heuristics is unreliable. [it works - * out because FMADD-capable processors where FPU - * code path is undesirable are also VIS3-capable and - * VIS3 code path takes precedence.] - */ - ( (OPENSSL_sparcv9cap_P[0] & SPARCV9_FMADD) || - (OPENSSL_sparcv9cap_P[0] & - (SPARCV9_PREFER_FPU | SPARCV9_VIS1)) == - (SPARCV9_PREFER_FPU | SPARCV9_VIS1) )) - return bn_mul_mont_fpu(rp, ap, bp, np, n0, num); - } - return bn_mul_mont_int(rp, ap, bp, np, n0, num); -} - unsigned long _sparcv9_rdtick(void); void _sparcv9_vis1_probe(void); unsigned long _sparcv9_vis1_instrument(void); diff --git a/crypto/openssl/crypto/sparse_array.c b/crypto/openssl/crypto/sparse_array.c new file mode 100644 index 000000000000..bbbc9cdb3696 --- /dev/null +++ b/crypto/openssl/crypto/sparse_array.c @@ -0,0 +1,216 @@ +/* + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "crypto/sparse_array.h" + +/* + * How many bits are used to index each level in the tree structure? + * This setting determines the number of pointers stored in each node of the + * tree used to represent the sparse array. Having more pointers reduces the + * depth of the tree but potentially wastes more memory. That is, this is a + * direct space versus time tradeoff. + * + * The default is to use four bits which means that the are 16 + * pointers in each tree node. + * + * The library builder is also permitted to define other sizes in the closed + * interval [2, sizeof(ossl_uintmax_t) * 8]. Space use generally scales + * exponentially with the block size, although the implementation only + * creates enough blocks to support the largest used index. The depth is: + * ceil(log_2(largest index) / 2^{block size}) + * E.g. with a block size of 4, and a largest index of 1000, the depth + * will be three. + */ +#ifndef OPENSSL_SA_BLOCK_BITS +# define OPENSSL_SA_BLOCK_BITS 4 +#elif OPENSSL_SA_BLOCK_BITS < 2 || OPENSSL_SA_BLOCK_BITS > (BN_BITS2 - 1) +# error OPENSSL_SA_BLOCK_BITS is out of range +#endif + +/* + * From the number of bits, work out: + * the number of pointers in a tree node; + * a bit mask to quickly extract an index and + * the maximum depth of the tree structure. + */ +#define SA_BLOCK_MAX (1 << OPENSSL_SA_BLOCK_BITS) +#define SA_BLOCK_MASK (SA_BLOCK_MAX - 1) +#define SA_BLOCK_MAX_LEVELS (((int)sizeof(ossl_uintmax_t) * 8 \ + + OPENSSL_SA_BLOCK_BITS - 1) \ + / OPENSSL_SA_BLOCK_BITS) + +struct sparse_array_st { + int levels; + ossl_uintmax_t top; + size_t nelem; + void **nodes; +}; + +OPENSSL_SA *ossl_sa_new(void) +{ + OPENSSL_SA *res = OPENSSL_zalloc(sizeof(*res)); + + return res; +} + +static void sa_doall(const OPENSSL_SA *sa, void (*node)(void **), + void (*leaf)(ossl_uintmax_t, void *, void *), void *arg) +{ + int i[SA_BLOCK_MAX_LEVELS]; + void *nodes[SA_BLOCK_MAX_LEVELS]; + ossl_uintmax_t idx = 0; + int l = 0; + + i[0] = 0; + nodes[0] = sa->nodes; + while (l >= 0) { + const int n = i[l]; + void ** const p = nodes[l]; + + if (n >= SA_BLOCK_MAX) { + if (p != NULL && node != NULL) + (*node)(p); + l--; + idx >>= OPENSSL_SA_BLOCK_BITS; + } else { + i[l] = n + 1; + if (p != NULL && p[n] != NULL) { + idx = (idx & ~SA_BLOCK_MASK) | n; + if (l < sa->levels - 1) { + i[++l] = 0; + nodes[l] = p[n]; + idx <<= OPENSSL_SA_BLOCK_BITS; + } else if (leaf != NULL) { + (*leaf)(idx, p[n], arg); + } + } + } + } +} + +static void sa_free_node(void **p) +{ + OPENSSL_free(p); +} + +static void sa_free_leaf(ossl_uintmax_t n, void *p, void *arg) +{ + OPENSSL_free(p); +} + +void ossl_sa_free(OPENSSL_SA *sa) +{ + if (sa != NULL) { + sa_doall(sa, &sa_free_node, NULL, NULL); + OPENSSL_free(sa); + } +} + +void ossl_sa_free_leaves(OPENSSL_SA *sa) +{ + sa_doall(sa, &sa_free_node, &sa_free_leaf, NULL); + OPENSSL_free(sa); +} + +/* Wrap this in a structure to avoid compiler warnings */ +struct trampoline_st { + void (*func)(ossl_uintmax_t, void *); +}; + +static void trampoline(ossl_uintmax_t n, void *l, void *arg) +{ + ((const struct trampoline_st *)arg)->func(n, l); +} + +void ossl_sa_doall(const OPENSSL_SA *sa, void (*leaf)(ossl_uintmax_t, void *)) +{ + struct trampoline_st tramp; + + tramp.func = leaf; + if (sa != NULL) + sa_doall(sa, NULL, &trampoline, &tramp); +} + +void ossl_sa_doall_arg(const OPENSSL_SA *sa, + void (*leaf)(ossl_uintmax_t, void *, void *), + void *arg) +{ + if (sa != NULL) + sa_doall(sa, NULL, leaf, arg); +} + +size_t ossl_sa_num(const OPENSSL_SA *sa) +{ + return sa == NULL ? 0 : sa->nelem; +} + +void *ossl_sa_get(const OPENSSL_SA *sa, ossl_uintmax_t n) +{ + int level; + void **p, *r = NULL; + + if (sa == NULL || sa->nelem == 0) + return NULL; + + if (n <= sa->top) { + p = sa->nodes; + for (level = sa->levels - 1; p != NULL && level > 0; level--) + p = (void **)p[(n >> (OPENSSL_SA_BLOCK_BITS * level)) + & SA_BLOCK_MASK]; + r = p == NULL ? NULL : p[n & SA_BLOCK_MASK]; + } + return r; +} + +static ossl_inline void **alloc_node(void) +{ + return OPENSSL_zalloc(SA_BLOCK_MAX * sizeof(void *)); +} + +int ossl_sa_set(OPENSSL_SA *sa, ossl_uintmax_t posn, void *val) +{ + int i, level = 1; + ossl_uintmax_t n = posn; + void **p; + + if (sa == NULL) + return 0; + + for (level = 1; level < SA_BLOCK_MAX_LEVELS; level++) + if ((n >>= OPENSSL_SA_BLOCK_BITS) == 0) + break; + + for (;sa->levels < level; sa->levels++) { + p = alloc_node(); + if (p == NULL) + return 0; + p[0] = sa->nodes; + sa->nodes = p; + } + if (sa->top < posn) + sa->top = posn; + + p = sa->nodes; + for (level = sa->levels - 1; level > 0; level--) { + i = (posn >> (OPENSSL_SA_BLOCK_BITS * level)) & SA_BLOCK_MASK; + if (p[i] == NULL && (p[i] = alloc_node()) == NULL) + return 0; + p = p[i]; + } + p += posn & SA_BLOCK_MASK; + if (val == NULL && *p != NULL) + sa->nelem--; + else if (val != NULL && *p == NULL) + sa->nelem++; + *p = val; + return 1; +} diff --git a/crypto/openssl/crypto/srp/srp_lib.c b/crypto/openssl/crypto/srp/srp_lib.c index ce3504825c53..df0d3720ff0d 100644 --- a/crypto/openssl/crypto/srp/srp_lib.c +++ b/crypto/openssl/crypto/srp/srp_lib.c @@ -2,7 +2,7 @@ * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2004, EdelKey Project. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,6 +11,9 @@ * for the EdelKey project. */ +/* All the SRP APIs in this file are deprecated */ +#define OPENSSL_SUPPRESS_DEPRECATED + #ifndef OPENSSL_NO_SRP # include "internal/cryptlib.h" # include @@ -20,39 +23,54 @@ /* calculate = SHA1(PAD(x) || PAD(y)) */ -static BIGNUM *srp_Calc_xy(const BIGNUM *x, const BIGNUM *y, const BIGNUM *N) +static BIGNUM *srp_Calc_xy(const BIGNUM *x, const BIGNUM *y, const BIGNUM *N, + OSSL_LIB_CTX *libctx, const char *propq) { unsigned char digest[SHA_DIGEST_LENGTH]; unsigned char *tmp = NULL; int numN = BN_num_bytes(N); BIGNUM *res = NULL; + EVP_MD *sha1 = EVP_MD_fetch(libctx, "SHA1", propq); - if (x != N && BN_ucmp(x, N) >= 0) + if (sha1 == NULL) return NULL; + + if (x != N && BN_ucmp(x, N) >= 0) + goto err; if (y != N && BN_ucmp(y, N) >= 0) - return NULL; + goto err; if ((tmp = OPENSSL_malloc(numN * 2)) == NULL) goto err; if (BN_bn2binpad(x, tmp, numN) < 0 || BN_bn2binpad(y, tmp + numN, numN) < 0 - || !EVP_Digest(tmp, numN * 2, digest, NULL, EVP_sha1(), NULL)) + || !EVP_Digest(tmp, numN * 2, digest, NULL, sha1, NULL)) goto err; res = BN_bin2bn(digest, sizeof(digest), NULL); err: + EVP_MD_free(sha1); OPENSSL_free(tmp); return res; } -static BIGNUM *srp_Calc_k(const BIGNUM *N, const BIGNUM *g) +static BIGNUM *srp_Calc_k(const BIGNUM *N, const BIGNUM *g, + OSSL_LIB_CTX *libctx, + const char *propq) { - /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */ - return srp_Calc_xy(N, g, N); + /* k = SHA1(N | PAD(g)) -- tls-srp RFC 5054 */ + return srp_Calc_xy(N, g, N, libctx, propq); +} + +BIGNUM *SRP_Calc_u_ex(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N, + OSSL_LIB_CTX *libctx, const char *propq) +{ + /* u = SHA1(PAD(A) || PAD(B) ) -- tls-srp RFC 5054 */ + return srp_Calc_xy(A, B, N, libctx, propq); } BIGNUM *SRP_Calc_u(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N) { - /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */ - return srp_Calc_xy(A, B, N); + /* u = SHA1(PAD(A) || PAD(B) ) -- tls-srp RFC 5054 */ + return srp_Calc_xy(A, B, N, NULL, NULL); } BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u, @@ -85,15 +103,15 @@ BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u, return S; } -BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, - const BIGNUM *v) +BIGNUM *SRP_Calc_B_ex(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, + const BIGNUM *v, OSSL_LIB_CTX *libctx, const char *propq) { BIGNUM *kv = NULL, *gb = NULL; BIGNUM *B = NULL, *k = NULL; BN_CTX *bn_ctx; if (b == NULL || N == NULL || g == NULL || v == NULL || - (bn_ctx = BN_CTX_new()) == NULL) + (bn_ctx = BN_CTX_new_ex(libctx)) == NULL) return NULL; if ((kv = BN_new()) == NULL || @@ -103,7 +121,7 @@ BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, /* B = g**b + k*v */ if (!BN_mod_exp(gb, g, b, N, bn_ctx) - || (k = srp_Calc_k(N, g)) == NULL + || (k = srp_Calc_k(N, g, libctx, propq)) == NULL || !BN_mod_mul(kv, v, k, N, bn_ctx) || !BN_mod_add(B, gb, kv, N, bn_ctx)) { BN_free(B); @@ -117,12 +135,20 @@ BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, return B; } -BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass) +BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, + const BIGNUM *v) +{ + return SRP_Calc_B_ex(b, N, g, v, NULL, NULL); +} + +BIGNUM *SRP_Calc_x_ex(const BIGNUM *s, const char *user, const char *pass, + OSSL_LIB_CTX *libctx, const char *propq) { unsigned char dig[SHA_DIGEST_LENGTH]; EVP_MD_CTX *ctxt; unsigned char *cs = NULL; BIGNUM *res = NULL; + EVP_MD *sha1 = NULL; if ((s == NULL) || (user == NULL) || (pass == NULL)) return NULL; @@ -133,12 +159,16 @@ BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass) if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL) goto err; - if (!EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL) + sha1 = EVP_MD_fetch(libctx, "SHA1", propq); + if (sha1 == NULL) + goto err; + + if (!EVP_DigestInit_ex(ctxt, sha1, NULL) || !EVP_DigestUpdate(ctxt, user, strlen(user)) || !EVP_DigestUpdate(ctxt, ":", 1) || !EVP_DigestUpdate(ctxt, pass, strlen(pass)) || !EVP_DigestFinal_ex(ctxt, dig, NULL) - || !EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL)) + || !EVP_DigestInit_ex(ctxt, sha1, NULL)) goto err; if (BN_bn2bin(s, cs) < 0) goto err; @@ -152,11 +182,17 @@ BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass) res = BN_bin2bn(dig, sizeof(dig), NULL); err: + EVP_MD_free(sha1); OPENSSL_free(cs); EVP_MD_CTX_free(ctxt); return res; } +BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass) +{ + return SRP_Calc_x_ex(s, user, pass, NULL, NULL); +} + BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g) { BN_CTX *bn_ctx; @@ -173,15 +209,16 @@ BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g) return A; } -BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, - const BIGNUM *x, const BIGNUM *a, const BIGNUM *u) +BIGNUM *SRP_Calc_client_key_ex(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, + const BIGNUM *x, const BIGNUM *a, const BIGNUM *u, + OSSL_LIB_CTX *libctx, const char *propq) { BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *k = NULL, *K = NULL; BIGNUM *xtmp = NULL; BN_CTX *bn_ctx; if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL - || a == NULL || (bn_ctx = BN_CTX_new()) == NULL) + || a == NULL || (bn_ctx = BN_CTX_new_ex(libctx)) == NULL) return NULL; if ((tmp = BN_new()) == NULL || @@ -194,7 +231,7 @@ BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, BN_set_flags(tmp, BN_FLG_CONSTTIME); if (!BN_mod_exp(tmp, g, xtmp, N, bn_ctx)) goto err; - if ((k = srp_Calc_k(N, g)) == NULL) + if ((k = srp_Calc_k(N, g, libctx, propq)) == NULL) goto err; if (!BN_mod_mul(tmp2, tmp, k, N, bn_ctx)) goto err; @@ -220,6 +257,12 @@ BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, return K; } +BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, + const BIGNUM *x, const BIGNUM *a, const BIGNUM *u) +{ + return SRP_Calc_client_key_ex(N, B, g, x, a, u, NULL, NULL); +} + int SRP_Verify_B_mod_N(const BIGNUM *B, const BIGNUM *N) { BIGNUM *r; @@ -248,26 +291,26 @@ int SRP_Verify_A_mod_N(const BIGNUM *A, const BIGNUM *N) } static SRP_gN knowngN[] = { - {"8192", &bn_generator_19, &bn_group_8192}, - {"6144", &bn_generator_5, &bn_group_6144}, - {"4096", &bn_generator_5, &bn_group_4096}, - {"3072", &bn_generator_5, &bn_group_3072}, - {"2048", &bn_generator_2, &bn_group_2048}, - {"1536", &bn_generator_2, &bn_group_1536}, - {"1024", &bn_generator_2, &bn_group_1024}, + {"8192", &ossl_bn_generator_19, &ossl_bn_group_8192}, + {"6144", &ossl_bn_generator_5, &ossl_bn_group_6144}, + {"4096", &ossl_bn_generator_5, &ossl_bn_group_4096}, + {"3072", &ossl_bn_generator_5, &ossl_bn_group_3072}, + {"2048", &ossl_bn_generator_2, &ossl_bn_group_2048}, + {"1536", &ossl_bn_generator_2, &ossl_bn_group_1536}, + {"1024", &ossl_bn_generator_2, &ossl_bn_group_1024}, }; # define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN) /* * Check if G and N are known parameters. The values have been generated - * from the ietf-tls-srp draft version 8 + * from the IETF RFC 5054 */ char *SRP_check_known_gN_param(const BIGNUM *g, const BIGNUM *N) { size_t i; if ((g == NULL) || (N == NULL)) - return 0; + return NULL; for (i = 0; i < KNOWN_GN_NUMBER; i++) { if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0) diff --git a/crypto/openssl/crypto/srp/srp_vfy.c b/crypto/openssl/crypto/srp/srp_vfy.c index 394e1180dfa4..e8beb60d278a 100644 --- a/crypto/openssl/crypto/srp/srp_vfy.c +++ b/crypto/openssl/crypto/srp/srp_vfy.c @@ -2,7 +2,7 @@ * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2004, EdelKey Project. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,6 +11,9 @@ * for the EdelKey project. */ +/* All the SRP APIs in this file are deprecated */ +#define OPENSSL_SUPPRESS_DEPRECATED + #ifndef OPENSSL_NO_SRP # include "internal/cryptlib.h" # include "crypto/evp.h" @@ -184,12 +187,12 @@ void SRP_user_pwd_free(SRP_user_pwd *user_pwd) OPENSSL_free(user_pwd); } -static SRP_user_pwd *SRP_user_pwd_new(void) +SRP_user_pwd *SRP_user_pwd_new(void) { SRP_user_pwd *ret; if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { - /* SRPerr(SRP_F_SRP_USER_PWD_NEW, ERR_R_MALLOC_FAILURE); */ /*ckerr_ignore*/ + /* ERR_raise(ERR_LIB_SRP, ERR_R_MALLOC_FAILURE); */ /*ckerr_ignore*/ return NULL; } ret->N = NULL; @@ -201,16 +204,18 @@ static SRP_user_pwd *SRP_user_pwd_new(void) return ret; } -static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g, - const BIGNUM *N) +void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g, + const BIGNUM *N) { vinfo->N = N; vinfo->g = g; } -static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id, - const char *info) +int SRP_user_pwd_set1_ids(SRP_user_pwd *vinfo, const char *id, + const char *info) { + OPENSSL_free(vinfo->id); + OPENSSL_free(vinfo->info); if (id != NULL && NULL == (vinfo->id = OPENSSL_strdup(id))) return 0; return (info == NULL || NULL != (vinfo->info = OPENSSL_strdup(info))); @@ -243,8 +248,10 @@ static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s, return 0; } -static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v) +int SRP_user_pwd_set0_sv(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v) { + BN_free(vinfo->s); + BN_clear_free(vinfo->v); vinfo->v = v; vinfo->s = s; return (vinfo->s != NULL && vinfo->v != NULL); @@ -260,8 +267,8 @@ static SRP_user_pwd *srp_user_pwd_dup(SRP_user_pwd *src) return NULL; SRP_user_pwd_set_gN(ret, src->g, src->N); - if (!SRP_user_pwd_set_ids(ret, src->id, src->info) - || !SRP_user_pwd_set_sv_BN(ret, BN_dup(src->s), BN_dup(src->v))) { + if (!SRP_user_pwd_set1_ids(ret, src->id, src->info) + || !SRP_user_pwd_set0_sv(ret, BN_dup(src->s), BN_dup(src->v))) { SRP_user_pwd_free(ret); return NULL; } @@ -340,12 +347,13 @@ static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab) int i; SRP_gN *gN; - if (gN_tab != NULL) + if (gN_tab != NULL) { for (i = 0; i < sk_SRP_gN_num(gN_tab); i++) { gN = sk_SRP_gN_value(gN_tab, i); if (gN && (id == NULL || strcmp(gN->id, id) == 0)) return gN; } + } return SRP_get_default_gN(id); } @@ -374,9 +382,13 @@ static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch) } /* - * this function parses verifier file. Format is: - * string(index):base64(N):base64(g):0 - * string(username):base64(v):base64(salt):int(index) + * This function parses the verifier file generated by the srp app. + * The format for each entry is: + * V base64(verifier) base64(salt) username gNid userinfo(optional) + * or + * I base64(N) base64(g) + * Note that base64 is the SRP variant of base64 encoding described + * in t_fromb64(). */ int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file) @@ -441,7 +453,7 @@ int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file) goto err; SRP_user_pwd_set_gN(user_pwd, lgN->g, lgN->N); - if (!SRP_user_pwd_set_ids + if (!SRP_user_pwd_set1_ids (user_pwd, pp[DB_srpid], pp[DB_srpinfo])) goto err; @@ -509,7 +521,14 @@ static SRP_user_pwd *find_user(SRP_VBASE *vb, char *username) return NULL; } -# if OPENSSL_API_COMPAT < 0x10100000L +int SRP_VBASE_add0_user(SRP_VBASE *vb, SRP_user_pwd *user_pwd) +{ + if (sk_SRP_user_pwd_push(vb->users_pwd, user_pwd) <= 0) + return 0; + return 1; +} + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 /* * DEPRECATED: use SRP_VBASE_get1_by_user instead. * This method ignores the configured seed and fails for an unknown user. @@ -532,6 +551,7 @@ SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username) unsigned char digv[SHA_DIGEST_LENGTH]; unsigned char digs[SHA_DIGEST_LENGTH]; EVP_MD_CTX *ctxt = NULL; + EVP_MD *md = NULL; if (vb == NULL) return NULL; @@ -550,26 +570,32 @@ SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username) SRP_user_pwd_set_gN(user, vb->default_g, vb->default_N); - if (!SRP_user_pwd_set_ids(user, username, NULL)) + if (!SRP_user_pwd_set1_ids(user, username, NULL)) goto err; if (RAND_priv_bytes(digv, SHA_DIGEST_LENGTH) <= 0) goto err; + md = EVP_MD_fetch(NULL, SN_sha1, NULL); + if (md == NULL) + goto err; ctxt = EVP_MD_CTX_new(); if (ctxt == NULL - || !EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL) + || !EVP_DigestInit_ex(ctxt, md, NULL) || !EVP_DigestUpdate(ctxt, vb->seed_key, strlen(vb->seed_key)) || !EVP_DigestUpdate(ctxt, username, strlen(username)) || !EVP_DigestFinal_ex(ctxt, digs, NULL)) goto err; EVP_MD_CTX_free(ctxt); ctxt = NULL; - if (SRP_user_pwd_set_sv_BN(user, - BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL), - BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL))) + EVP_MD_free(md); + md = NULL; + if (SRP_user_pwd_set0_sv(user, + BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL), + BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL))) return user; err: + EVP_MD_free(md); EVP_MD_CTX_free(ctxt); SRP_user_pwd_free(user); return NULL; @@ -578,8 +604,9 @@ SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username) /* * create a verifier (*salt,*verifier,g and N are in base64) */ -char *SRP_create_verifier(const char *user, const char *pass, char **salt, - char **verifier, const char *N, const char *g) +char *SRP_create_verifier_ex(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g, + OSSL_LIB_CTX *libctx, const char *propq) { int len; char *result = NULL, *vf = NULL; @@ -609,7 +636,7 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt, g_bn = g_bn_alloc; defgNid = "*"; } else { - SRP_gN *gN = SRP_get_gN_by_id(g, NULL); + SRP_gN *gN = SRP_get_default_gN(g); if (gN == NULL) goto err; N_bn = gN->N; @@ -618,7 +645,7 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt, } if (*salt == NULL) { - if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0) + if (RAND_bytes_ex(libctx, tmp2, SRP_RANDOM_SALT_LEN, 0) <= 0) goto err; s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); @@ -630,7 +657,8 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt, if (s == NULL) goto err; - if (!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) + if (!SRP_create_verifier_BN_ex(user, pass, &s, &v, N_bn, g_bn, libctx, + propq)) goto err; if (BN_bn2bin(v, tmp) < 0) @@ -667,6 +695,12 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt, return result; } +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g) +{ + return SRP_create_verifier_ex(user, pass, salt, verifier, N, g, NULL, NULL); +} + /* * create a verifier (*salt,*verifier,g and N are BIGNUMs). If *salt != NULL * then the provided salt will be used. On successful exit *verifier will point @@ -676,13 +710,14 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt, * The caller is responsible for freeing the allocated *salt and *verifier * BIGNUMS. */ -int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, - BIGNUM **verifier, const BIGNUM *N, - const BIGNUM *g) +int SRP_create_verifier_BN_ex(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, const BIGNUM *N, + const BIGNUM *g, OSSL_LIB_CTX *libctx, + const char *propq) { int result = 0; BIGNUM *x = NULL; - BN_CTX *bn_ctx = BN_CTX_new(); + BN_CTX *bn_ctx = BN_CTX_new_ex(libctx); unsigned char tmp2[MAX_LEN]; BIGNUM *salttmp = NULL, *verif; @@ -693,7 +728,7 @@ int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, goto err; if (*salt == NULL) { - if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0) + if (RAND_bytes_ex(libctx, tmp2, SRP_RANDOM_SALT_LEN, 0) <= 0) goto err; salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); @@ -703,7 +738,7 @@ int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, salttmp = *salt; } - x = SRP_Calc_x(salttmp, user, pass); + x = SRP_Calc_x_ex(salttmp, user, pass, libctx, propq); if (x == NULL) goto err; @@ -728,4 +763,11 @@ int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, return result; } +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, const BIGNUM *N, + const BIGNUM *g) +{ + return SRP_create_verifier_BN_ex(user, pass, salt, verifier, N, g, NULL, + NULL); +} #endif diff --git a/crypto/openssl/crypto/stack/build.info b/crypto/openssl/crypto/stack/build.info index e5870210ac38..23d83a6f111b 100644 --- a/crypto/openssl/crypto/stack/build.info +++ b/crypto/openssl/crypto/stack/build.info @@ -1,2 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=stack.c +SOURCE[../../providers/libfips.a]=stack.c diff --git a/crypto/openssl/crypto/stack/stack.c b/crypto/openssl/crypto/stack/stack.c index 975515db5972..51080b876797 100644 --- a/crypto/openssl/crypto/stack/stack.c +++ b/crypto/openssl/crypto/stack/stack.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,7 +11,6 @@ #include "internal/cryptlib.h" #include "internal/numbers.h" #include -#include #include #include /* For ossl_inline */ @@ -20,8 +19,7 @@ */ static const int min_nodes = 4; static const int max_nodes = SIZE_MAX / sizeof(void *) < INT_MAX - ? (int)(SIZE_MAX / sizeof(void *)) - : INT_MAX; + ? (int)(SIZE_MAX / sizeof(void *)) : INT_MAX; struct stack_st { int num; @@ -31,7 +29,8 @@ struct stack_st { OPENSSL_sk_compfunc comp; }; -OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_compfunc c) +OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, + OPENSSL_sk_compfunc c) { OPENSSL_sk_compfunc old = sk->comp; @@ -46,46 +45,58 @@ OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk) { OPENSSL_STACK *ret; - if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_SK_DUP, ERR_R_MALLOC_FAILURE); - return NULL; - } + if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) + goto err; - /* direct structure assignment */ - *ret = *sk; + if (sk == NULL) { + ret->num = 0; + ret->sorted = 0; + ret->comp = NULL; + } else { + /* direct structure assignment */ + *ret = *sk; + } - if (sk->num == 0) { + if (sk == NULL || sk->num == 0) { /* postpone |ret->data| allocation */ ret->data = NULL; ret->num_alloc = 0; return ret; } + /* duplicate |sk->data| content */ - if ((ret->data = OPENSSL_malloc(sizeof(*ret->data) * sk->num_alloc)) == NULL) + ret->data = OPENSSL_malloc(sizeof(*ret->data) * sk->num_alloc); + if (ret->data == NULL) goto err; memcpy(ret->data, sk->data, sizeof(void *) * sk->num); return ret; + err: + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); OPENSSL_sk_free(ret); return NULL; } OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk, - OPENSSL_sk_copyfunc copy_func, - OPENSSL_sk_freefunc free_func) + OPENSSL_sk_copyfunc copy_func, + OPENSSL_sk_freefunc free_func) { OPENSSL_STACK *ret; int i; - if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_SK_DEEP_COPY, ERR_R_MALLOC_FAILURE); - return NULL; - } + if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) + goto err; - /* direct structure assignment */ - *ret = *sk; + if (sk == NULL) { + ret->num = 0; + ret->sorted = 0; + ret->comp = NULL; + } else { + /* direct structure assignment */ + *ret = *sk; + } - if (sk->num == 0) { + if (sk == NULL || sk->num == 0) { /* postpone |ret| data allocation */ ret->data = NULL; ret->num_alloc = 0; @@ -94,10 +105,8 @@ OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk, ret->num_alloc = sk->num > min_nodes ? sk->num : min_nodes; ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc); - if (ret->data == NULL) { - OPENSSL_free(ret); - return NULL; - } + if (ret->data == NULL) + goto err; for (i = 0; i < ret->num; ++i) { if (sk->data[i] == NULL) @@ -106,11 +115,15 @@ OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk, while (--i >= 0) if (ret->data[i] != NULL) free_func((void *)ret->data[i]); - OPENSSL_sk_free(ret); - return NULL; + goto err; } } return ret; + + err: + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + OPENSSL_sk_free(ret); + return NULL; } OPENSSL_STACK *OPENSSL_sk_new_null(void) @@ -163,8 +176,10 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact) int num_alloc; /* Check to see the reservation isn't exceeding the hard limit */ - if (n > max_nodes - st->num) + if (n > max_nodes - st->num) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS); return 0; + } /* Figure out the new size */ num_alloc = st->num + n; @@ -178,7 +193,7 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact) * so |num_alloc| value is |n| or |min_nodes| if greater than |n|. */ if ((st->data = OPENSSL_zalloc(sizeof(void *) * num_alloc)) == NULL) { - CRYPTOerr(CRYPTO_F_SK_RESERVE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } st->num_alloc = num_alloc; @@ -189,15 +204,19 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact) if (num_alloc <= st->num_alloc) return 1; num_alloc = compute_growth(num_alloc, st->num_alloc); - if (num_alloc == 0) + if (num_alloc == 0) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS); return 0; + } } else if (num_alloc == st->num_alloc) { return 1; } tmpdata = OPENSSL_realloc((void *)st->data, sizeof(void *) * num_alloc); - if (tmpdata == NULL) + if (tmpdata == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; + } st->data = tmpdata; st->num_alloc = num_alloc; @@ -208,8 +227,10 @@ OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n) { OPENSSL_STACK *st = OPENSSL_zalloc(sizeof(OPENSSL_STACK)); - if (st == NULL) + if (st == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return NULL; + } st->comp = c; @@ -226,8 +247,10 @@ OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n) int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n) { - if (st == NULL) + if (st == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); return 0; + } if (n < 0) return 1; @@ -236,8 +259,14 @@ int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n) int OPENSSL_sk_insert(OPENSSL_STACK *st, const void *data, int loc) { - if (st == NULL || st->num == max_nodes) + if (st == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); return 0; + } + if (st->num == max_nodes) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS); + return 0; + } if (!sk_reserve(st, 1, 0)) return 0; @@ -259,8 +288,8 @@ static ossl_inline void *internal_delete(OPENSSL_STACK *st, int loc) const void *ret = st->data[loc]; if (loc != st->num - 1) - memmove(&st->data[loc], &st->data[loc + 1], - sizeof(st->data[0]) * (st->num - loc - 1)); + memmove(&st->data[loc], &st->data[loc + 1], + sizeof(st->data[0]) * (st->num - loc - 1)); st->num--; return (void *)ret; @@ -270,6 +299,9 @@ void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p) { int i; + if (st == NULL) + return NULL; + for (i = 0; i < st->num; i++) if (st->data[i] == p) return internal_delete(st, i); @@ -285,7 +317,7 @@ void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc) } static int internal_find(OPENSSL_STACK *st, const void *data, - int ret_val_options) + int ret_val_options, int *pnum) { const void *r; int i; @@ -295,8 +327,13 @@ static int internal_find(OPENSSL_STACK *st, const void *data, if (st->comp == NULL) { for (i = 0; i < st->num; i++) - if (st->data[i] == data) + if (st->data[i] == data) { + if (pnum != NULL) + *pnum = 1; return i; + } + if (pnum != NULL) + *pnum = 0; return -1; } @@ -307,20 +344,41 @@ static int internal_find(OPENSSL_STACK *st, const void *data, } if (data == NULL) return -1; - r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp, - ret_val_options); + if (pnum != NULL) + ret_val_options |= OSSL_BSEARCH_FIRST_VALUE_ON_MATCH; + r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp, + ret_val_options); + + if (pnum != NULL) { + *pnum = 0; + if (r != NULL) { + const void **p = (const void **)r; + + while (p < st->data + st->num) { + if (st->comp(&data, p) != 0) + break; + ++*pnum; + ++p; + } + } + } return r == NULL ? -1 : (int)((const void **)r - st->data); } int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data) { - return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); + return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH, NULL); } int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data) { - return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); + return internal_find(st, data, OSSL_BSEARCH_VALUE_ON_NOMATCH, NULL); +} + +int OPENSSL_sk_find_all(OPENSSL_STACK *st, const void *data, int *pnum) +{ + return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH, pnum); } int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data) @@ -391,8 +449,15 @@ void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i) void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data) { - if (st == NULL || i < 0 || i >= st->num) + if (st == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); return NULL; + } + if (i < 0 || i >= st->num) { + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT, + "i=%d", i); + return NULL; + } st->data[i] = data; st->sorted = 0; return (void *)st->data[i]; diff --git a/crypto/openssl/crypto/store/build.info b/crypto/openssl/crypto/store/build.info index 7d882f313ea5..43d9e544a01f 100644 --- a/crypto/openssl/crypto/store/build.info +++ b/crypto/openssl/crypto/store/build.info @@ -1,4 +1,7 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - store_err.c store_init.c store_lib.c store_register.c store_strings.c \ - loader_file.c + store_err.c store_lib.c store_result.c store_strings.c store_meth.c + +IF[{- !$disabled{'deprecated-3.0'} -}] + SOURCE[../../libcrypto]=store_init.c store_register.c +ENDIF diff --git a/crypto/openssl/crypto/store/store_err.c b/crypto/openssl/crypto/store/store_err.c index 5a8a8404dd9b..ec62b358c589 100644 --- a/crypto/openssl/crypto/store/store_err.c +++ b/crypto/openssl/crypto/store/store_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,84 +10,10 @@ #include #include +#include "crypto/storeerr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA OSSL_STORE_str_functs[] = { - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_CTRL, 0), "file_ctrl"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_FIND, 0), "file_find"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_GET_PASS, 0), - "file_get_pass"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_LOAD, 0), "file_load"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_LOAD_TRY_DECODE, 0), - "file_load_try_decode"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_NAME_TO_URI, 0), - "file_name_to_uri"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_OPEN, 0), "file_open"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO, 0), - "ossl_store_attach_pem_bio"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_EXPECT, 0), - "OSSL_STORE_expect"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT, 0), - "ossl_store_file_attach_pem_bio_int"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_FIND, 0), - "OSSL_STORE_find"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT, 0), - "ossl_store_get0_loader_int"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT, 0), - "OSSL_STORE_INFO_get1_CERT"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL, 0), - "OSSL_STORE_INFO_get1_CRL"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME, 0), - "OSSL_STORE_INFO_get1_NAME"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION, 0), - "OSSL_STORE_INFO_get1_NAME_description"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS, 0), - "OSSL_STORE_INFO_get1_PARAMS"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY, 0), - "OSSL_STORE_INFO_get1_PKEY"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT, 0), - "OSSL_STORE_INFO_new_CERT"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL, 0), - "OSSL_STORE_INFO_new_CRL"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED, 0), - "ossl_store_info_new_EMBEDDED"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME, 0), - "OSSL_STORE_INFO_new_NAME"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS, 0), - "OSSL_STORE_INFO_new_PARAMS"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY, 0), - "OSSL_STORE_INFO_new_PKEY"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION, 0), - "OSSL_STORE_INFO_set0_NAME_description"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INIT_ONCE, 0), - "ossl_store_init_once"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_LOADER_NEW, 0), - "OSSL_STORE_LOADER_new"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_OPEN, 0), - "OSSL_STORE_open"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_OPEN_INT, 0), ""}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT, 0), - "ossl_store_register_loader_int"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS, 0), - "OSSL_STORE_SEARCH_by_alias"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL, 0), - "OSSL_STORE_SEARCH_by_issuer_serial"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT, 0), - "OSSL_STORE_SEARCH_by_key_fingerprint"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME, 0), - "OSSL_STORE_SEARCH_by_name"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT, 0), - "ossl_store_unregister_loader_int"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_TRY_DECODE_PARAMS, 0), - "try_decode_params"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_TRY_DECODE_PKCS12, 0), - "try_decode_PKCS12"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED, 0), - "try_decode_PKCS8Encrypted"}, - {0, NULL} -}; - static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = { {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE), "ambiguous content type"}, @@ -107,10 +33,15 @@ static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = { {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_CERTIFICATE), "not a certificate"}, {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_CRL), "not a crl"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_KEY), "not a key"}, {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_NAME), "not a name"}, + {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_PRIVATE_KEY), + "not a private key"}, + {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_PUBLIC_KEY), + "not a public key"}, {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_PARAMETERS), "not parameters"}, + {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NO_LOADERS_FOUND), + "no loaders found"}, {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR), "passphrase callback error"}, {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE), @@ -134,13 +65,11 @@ static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = { #endif -int ERR_load_OSSL_STORE_strings(void) +int ossl_err_load_OSSL_STORE_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(OSSL_STORE_str_functs[0].error) == NULL) { - ERR_load_strings_const(OSSL_STORE_str_functs); + if (ERR_reason_error_string(OSSL_STORE_str_reasons[0].error) == NULL) ERR_load_strings_const(OSSL_STORE_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/store/store_init.c b/crypto/openssl/crypto/store/store_init.c index 0103c8db8aaf..9df8ef12a241 100644 --- a/crypto/openssl/crypto/store/store_init.c +++ b/crypto/openssl/crypto/store/store_init.c @@ -1,32 +1,15 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include #include "crypto/store.h" #include "store_local.h" -static CRYPTO_ONCE store_init = CRYPTO_ONCE_STATIC_INIT; -DEFINE_RUN_ONCE_STATIC(do_store_init) -{ - return OPENSSL_init_crypto(0, NULL) - && ossl_store_file_loader_init(); -} - -int ossl_store_init_once(void) -{ - if (!RUN_ONCE(&store_init, do_store_init)) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INIT_ONCE, ERR_R_MALLOC_FAILURE); - return 0; - } - return 1; -} - void ossl_store_cleanup_int(void) { ossl_store_destroy_loaders_int(); diff --git a/crypto/openssl/crypto/store/store_lib.c b/crypto/openssl/crypto/store/store_lib.c index fb71f84725b1..5ff927862916 100644 --- a/crypto/openssl/crypto/store/store_lib.c +++ b/crypto/openssl/crypto/store/store_lib.c @@ -1,48 +1,78 @@ /* - * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#include "e_os.h" #include #include #include +/* We need to use some STORE deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include "e_os.h" #include #include +#include +#include +#include +#include #include #include "internal/thread_once.h" +#include "internal/cryptlib.h" +#include "internal/provider.h" +#include "internal/bio.h" #include "crypto/store.h" #include "store_local.h" -struct ossl_store_ctx_st { - const OSSL_STORE_LOADER *loader; - OSSL_STORE_LOADER_CTX *loader_ctx; - const UI_METHOD *ui_method; - void *ui_data; - OSSL_STORE_post_process_info_fn post_process; - void *post_process_data; - int expected_type; - - /* 0 before the first STORE_load(), 1 otherwise */ - int loading; -}; - -OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, - void *ui_data, - OSSL_STORE_post_process_info_fn post_process, - void *post_process_data) +static int ossl_store_close_it(OSSL_STORE_CTX *ctx); + +static int loader_set_params(OSSL_STORE_LOADER *loader, + OSSL_STORE_LOADER_CTX *loader_ctx, + const OSSL_PARAM params[], const char *propq) +{ + if (params != NULL) { + if (!loader->p_set_ctx_params(loader_ctx, params)) + return 0; + } + + if (propq != NULL) { + OSSL_PARAM propp[2]; + + if (OSSL_PARAM_locate_const(params, + OSSL_STORE_PARAM_PROPERTIES) != NULL) + /* use the propq from params */ + return 1; + + propp[0] = OSSL_PARAM_construct_utf8_string(OSSL_STORE_PARAM_PROPERTIES, + (char *)propq, 0); + propp[1] = OSSL_PARAM_construct_end(); + + if (!loader->p_set_ctx_params(loader_ctx, propp)) + return 0; + } + return 1; +} + +OSSL_STORE_CTX * +OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, + const UI_METHOD *ui_method, void *ui_data, + const OSSL_PARAM params[], + OSSL_STORE_post_process_info_fn post_process, + void *post_process_data) { const OSSL_STORE_LOADER *loader = NULL; + OSSL_STORE_LOADER *fetched_loader = NULL; OSSL_STORE_LOADER_CTX *loader_ctx = NULL; OSSL_STORE_CTX *ctx = NULL; - char scheme_copy[256], *p, *schemes[2]; + char *propq_copy = NULL; + int no_loader_found = 1; + char scheme_copy[256], *p, *schemes[2], *scheme = NULL; size_t schemes_n = 0; size_t i; @@ -63,7 +93,7 @@ OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy)); if ((p = strchr(scheme_copy, ':')) != NULL) { *p++ = '\0'; - if (strcasecmp(scheme_copy, "file") != 0) { + if (OPENSSL_strcasecmp(scheme_copy, "file") != 0) { if (strncmp(p, "//", 2) == 0) schemes_n--; /* Invalidate the file scheme */ schemes[schemes_n++] = scheme_copy; @@ -72,23 +102,83 @@ OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, ERR_set_mark(); - /* Try each scheme until we find one that could open the URI */ + /* + * Try each scheme until we find one that could open the URI. + * + * For each scheme, we look for the engine implementation first, and + * failing that, we then try to fetch a provided implementation. + * This is consistent with how we handle legacy / engine implementations + * elsewhere. + */ for (i = 0; loader_ctx == NULL && i < schemes_n; i++) { - if ((loader = ossl_store_get0_loader_int(schemes[i])) != NULL) - loader_ctx = loader->open(loader, uri, ui_method, ui_data); + scheme = schemes[i]; + OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if ((loader = ossl_store_get0_loader_int(scheme)) != NULL) { + no_loader_found = 0; + if (loader->open_ex != NULL) + loader_ctx = loader->open_ex(loader, uri, libctx, propq, + ui_method, ui_data); + else + loader_ctx = loader->open(loader, uri, ui_method, ui_data); + } +#endif + if (loader == NULL + && (fetched_loader = + OSSL_STORE_LOADER_fetch(libctx, scheme, propq)) != NULL) { + const OSSL_PROVIDER *provider = + OSSL_STORE_LOADER_get0_provider(fetched_loader); + void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); + + no_loader_found = 0; + loader_ctx = fetched_loader->p_open(provctx, uri); + if (loader_ctx == NULL) { + OSSL_STORE_LOADER_free(fetched_loader); + fetched_loader = NULL; + } else if(!loader_set_params(fetched_loader, loader_ctx, + params, propq)) { + (void)fetched_loader->p_close(loader_ctx); + OSSL_STORE_LOADER_free(fetched_loader); + fetched_loader = NULL; + } + loader = fetched_loader; + } } + + if (no_loader_found) + /* + * It's assumed that ossl_store_get0_loader_int() and + * OSSL_STORE_LOADER_fetch() report their own errors + */ + goto err; + + OSSL_TRACE1(STORE, "Found loader for scheme %s\n", scheme); + if (loader_ctx == NULL) + /* + * It's assumed that the loader's open() method reports its own + * errors + */ goto err; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_OPEN, ERR_R_MALLOC_FAILURE); + OSSL_TRACE2(STORE, "Opened %s => %p\n", uri, (void *)loader_ctx); + + if ((propq != NULL && (propq_copy = OPENSSL_strdup(propq)) == NULL) + || (ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); goto err; } + if (ui_method != NULL + && (!ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data) + || !ossl_pw_enable_passphrase_caching(&ctx->pwdata))) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); + goto err; + } + ctx->properties = propq_copy; + ctx->fetched_loader = fetched_loader; ctx->loader = loader; ctx->loader_ctx = loader_ctx; - ctx->ui_method = ui_method; - ctx->ui_data = ui_data; ctx->post_process = post_process; ctx->post_process_data = post_process_data; @@ -104,16 +194,39 @@ OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, err: ERR_clear_last_mark(); if (loader_ctx != NULL) { + /* + * Temporary structure so OSSL_STORE_close() can work even when + * |ctx| couldn't be allocated properly + */ + OSSL_STORE_CTX tmpctx = { NULL, }; + + tmpctx.fetched_loader = fetched_loader; + tmpctx.loader = loader; + tmpctx.loader_ctx = loader_ctx; + /* * We ignore a returned error because we will return NULL anyway in * this case, so if something goes wrong when closing, that'll simply * just add another entry on the error stack. */ - (void)loader->close(loader_ctx); + (void)ossl_store_close_it(&tmpctx); } + OSSL_STORE_LOADER_free(fetched_loader); + OPENSSL_free(propq_copy); + OPENSSL_free(ctx); return NULL; } +OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, + const UI_METHOD *ui_method, void *ui_data, + OSSL_STORE_post_process_info_fn post_process, + void *post_process_data) +{ + return OSSL_STORE_open_ex(uri, NULL, NULL, ui_method, ui_data, NULL, + post_process, post_process_data); +} + +#ifndef OPENSSL_NO_DEPRECATED_3_0 int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...) { va_list args; @@ -128,39 +241,161 @@ int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...) int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args) { - if (ctx->loader->ctrl != NULL) + if (ctx->fetched_loader != NULL) { + if (ctx->fetched_loader->p_set_ctx_params != NULL) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + switch (cmd) { + case OSSL_STORE_C_USE_SECMEM: + { + int on = *(va_arg(args, int *)); + + params[0] = OSSL_PARAM_construct_int("use_secmem", &on); + } + break; + default: + break; + } + + return ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, + params); + } + } else if (ctx->loader->ctrl != NULL) { return ctx->loader->ctrl(ctx->loader_ctx, cmd, args); - return 0; + } + + /* + * If the fetched loader doesn't have a set_ctx_params or a ctrl, it's as + * if there was one that ignored our params, which usually returns 1. + */ + return 1; } +#endif int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type) { + int ret = 1; + + if (ctx == NULL + || expected_type < 0 || expected_type > OSSL_STORE_INFO_CRL) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } if (ctx->loading) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_EXPECT, - OSSL_STORE_R_LOADING_STARTED); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED); return 0; } ctx->expected_type = expected_type; - if (ctx->loader->expect != NULL) - return ctx->loader->expect(ctx->loader_ctx, expected_type); - return 1; + if (ctx->fetched_loader != NULL + && ctx->fetched_loader->p_set_ctx_params != NULL) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_int(OSSL_STORE_PARAM_EXPECT, &expected_type); + ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, params); + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL + && ctx->loader->expect != NULL) { + ret = ctx->loader->expect(ctx->loader_ctx, expected_type); + } +#endif + return ret; } -int OSSL_STORE_find(OSSL_STORE_CTX *ctx, OSSL_STORE_SEARCH *search) +int OSSL_STORE_find(OSSL_STORE_CTX *ctx, const OSSL_STORE_SEARCH *search) { + int ret = 1; + if (ctx->loading) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FIND, - OSSL_STORE_R_LOADING_STARTED); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED); return 0; } - if (ctx->loader->find == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FIND, - OSSL_STORE_R_UNSUPPORTED_OPERATION); + if (search == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER); return 0; } - return ctx->loader->find(ctx->loader_ctx, search); + if (ctx->fetched_loader != NULL) { + OSSL_PARAM_BLD *bld; + OSSL_PARAM *params; + /* OSSL_STORE_SEARCH_BY_NAME, OSSL_STORE_SEARCH_BY_ISSUER_SERIAL*/ + void *name_der = NULL; + int name_der_sz; + /* OSSL_STORE_SEARCH_BY_ISSUER_SERIAL */ + BIGNUM *number = NULL; + + if (ctx->fetched_loader->p_set_ctx_params == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION); + return 0; + } + + if ((bld = OSSL_PARAM_BLD_new()) == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + return 0; + } + + ret = 0; /* Assume the worst */ + + switch (search->search_type) { + case OSSL_STORE_SEARCH_BY_NAME: + if ((name_der_sz = i2d_X509_NAME(search->name, + (unsigned char **)&name_der)) > 0 + && OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_STORE_PARAM_SUBJECT, + name_der, name_der_sz)) + ret = 1; + break; + case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL: + if ((name_der_sz = i2d_X509_NAME(search->name, + (unsigned char **)&name_der)) > 0 + && (number = ASN1_INTEGER_to_BN(search->serial, NULL)) != NULL + && OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_STORE_PARAM_ISSUER, + name_der, name_der_sz) + && OSSL_PARAM_BLD_push_BN(bld, OSSL_STORE_PARAM_SERIAL, + number)) + ret = 1; + break; + case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT: + if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_DIGEST, + EVP_MD_get0_name(search->digest), + 0) + && OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_STORE_PARAM_FINGERPRINT, + search->string, + search->stringlength)) + ret = 1; + break; + case OSSL_STORE_SEARCH_BY_ALIAS: + if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_ALIAS, + (char *)search->string, + search->stringlength)) + ret = 1; + break; + } + if (ret) { + params = OSSL_PARAM_BLD_to_param(bld); + ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, + params); + OSSL_PARAM_free(params); + } + OSSL_PARAM_BLD_free(bld); + OPENSSL_free(name_der); + BN_free(number); + } else { +#ifndef OPENSSL_NO_DEPRECATED_3_0 + /* legacy loader section */ + if (ctx->loader->find == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION); + return 0; + } + ret = ctx->loader->find(ctx->loader_ctx, search); +#endif + } + + return ret; } OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) @@ -172,7 +407,42 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) if (OSSL_STORE_eof(ctx)) return NULL; - v = ctx->loader->load(ctx->loader_ctx, ctx->ui_method, ctx->ui_data); + if (ctx->loader != NULL) + OSSL_TRACE(STORE, "Loading next object\n"); + + if (ctx->cached_info != NULL + && sk_OSSL_STORE_INFO_num(ctx->cached_info) == 0) { + sk_OSSL_STORE_INFO_free(ctx->cached_info); + ctx->cached_info = NULL; + } + + if (ctx->cached_info != NULL) { + v = sk_OSSL_STORE_INFO_shift(ctx->cached_info); + } else { + if (ctx->fetched_loader != NULL) { + struct ossl_load_result_data_st load_data; + + load_data.v = NULL; + load_data.ctx = ctx; + + if (!ctx->fetched_loader->p_load(ctx->loader_ctx, + ossl_store_handle_load_result, + &load_data, + ossl_pw_passphrase_callback_dec, + &ctx->pwdata)) { + if (!OSSL_STORE_eof(ctx)) + ctx->error_flag = 1; + return NULL; + } + v = load_data.v; + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL) + v = ctx->loader->load(ctx->loader_ctx, + ctx->pwdata._.ui_method.ui_method, + ctx->pwdata._.ui_method.ui_method_data); +#endif + } if (ctx->post_process != NULL && v != NULL) { v = ctx->post_process(v, ctx->post_process_data); @@ -185,17 +455,13 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) goto again; } + /* Clear any internally cached passphrase */ + (void)ossl_pw_clear_passphrase_cache(&ctx->pwdata); + if (v != NULL && ctx->expected_type != 0) { int returned_type = OSSL_STORE_INFO_get_type(v); if (returned_type != OSSL_STORE_INFO_NAME && returned_type != 0) { - /* - * Soft assert here so those who want to harsly weed out faulty - * loaders can do so using a debugging version of libcrypto. - */ - if (ctx->loader->expect != NULL) - assert(ctx->expected_type == returned_type); - if (ctx->expected_type != returned_type) { OSSL_STORE_INFO_free(v); goto again; @@ -203,29 +469,67 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) } } + if (v != NULL) + OSSL_TRACE1(STORE, "Got a %s\n", + OSSL_STORE_INFO_type_string(OSSL_STORE_INFO_get_type(v))); + return v; } int OSSL_STORE_error(OSSL_STORE_CTX *ctx) { - return ctx->loader->error(ctx->loader_ctx); + int ret = 1; + + if (ctx->fetched_loader != NULL) + ret = ctx->error_flag; +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL) + ret = ctx->loader->error(ctx->loader_ctx); +#endif + return ret; } int OSSL_STORE_eof(OSSL_STORE_CTX *ctx) { - return ctx->loader->eof(ctx->loader_ctx); + int ret = 1; + + if (ctx->fetched_loader != NULL) + ret = ctx->loader->p_eof(ctx->loader_ctx); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL) + ret = ctx->loader->eof(ctx->loader_ctx); +#endif + return ret != 0; } -int OSSL_STORE_close(OSSL_STORE_CTX *ctx) +static int ossl_store_close_it(OSSL_STORE_CTX *ctx) { - int loader_ret; + int ret = 0; if (ctx == NULL) return 1; - loader_ret = ctx->loader->close(ctx->loader_ctx); + OSSL_TRACE1(STORE, "Closing %p\n", (void *)ctx->loader_ctx); + + if (ctx->fetched_loader != NULL) + ret = ctx->loader->p_close(ctx->loader_ctx); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL) + ret = ctx->loader->closefn(ctx->loader_ctx); +#endif + + sk_OSSL_STORE_INFO_pop_free(ctx->cached_info, OSSL_STORE_INFO_free); + OSSL_STORE_LOADER_free(ctx->fetched_loader); + OPENSSL_free(ctx->properties); + ossl_pw_clear_passphrase_data(&ctx->pwdata); + return ret; +} + +int OSSL_STORE_close(OSSL_STORE_CTX *ctx) +{ + int ret = ossl_store_close_it(ctx); OPENSSL_free(ctx); - return loader_ret; + return ret; } /* @@ -235,7 +539,7 @@ int OSSL_STORE_close(OSSL_STORE_CTX *ctx) * 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) +OSSL_STORE_INFO *OSSL_STORE_INFO_new(int type, void *data) { OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info)); @@ -249,11 +553,10 @@ static OSSL_STORE_INFO *store_info_new(int type, void *data) OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name) { - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_NAME, NULL); + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_NAME, NULL); if (info == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -266,8 +569,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name) int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc) { if (info->type != OSSL_STORE_INFO_NAME) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION, - ERR_R_PASSED_INVALID_ARGUMENT); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } @@ -277,41 +579,46 @@ int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc) } OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params) { - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PARAMS, params); + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PARAMS, params); if (info == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + return info; +} + +OSSL_STORE_INFO *OSSL_STORE_INFO_new_PUBKEY(EVP_PKEY *pkey) +{ + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PUBKEY, pkey); + + if (info == NULL) + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return info; } OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey) { - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PKEY, pkey); + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PKEY, pkey); if (info == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return info; } OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509) { - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CERT, x509); + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CERT, x509); if (info == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return info; } OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl) { - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CRL, crl); + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CRL, crl); if (info == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return info; } @@ -323,6 +630,13 @@ int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info) return info->type; } +void *OSSL_STORE_INFO_get0_data(int type, const OSSL_STORE_INFO *info) +{ + if (info->type == type) + return info->_.data; + return NULL; +} + const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info) { if (info->type == OSSL_STORE_INFO_NAME) @@ -336,12 +650,10 @@ char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info) char *ret = OPENSSL_strdup(info->_.name.name); if (ret == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return ret; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME, - OSSL_STORE_R_NOT_A_NAME); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); return NULL; } @@ -359,12 +671,10 @@ char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info) ? info->_.name.desc : ""); if (ret == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return ret; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION, - OSSL_STORE_R_NOT_A_NAME); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); return NULL; } @@ -381,8 +691,24 @@ EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info) EVP_PKEY_up_ref(info->_.params); return info->_.params; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS, - OSSL_STORE_R_NOT_PARAMETERS); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_PARAMETERS); + return NULL; +} + +EVP_PKEY *OSSL_STORE_INFO_get0_PUBKEY(const OSSL_STORE_INFO *info) +{ + if (info->type == OSSL_STORE_INFO_PUBKEY) + return info->_.pubkey; + return NULL; +} + +EVP_PKEY *OSSL_STORE_INFO_get1_PUBKEY(const OSSL_STORE_INFO *info) +{ + if (info->type == OSSL_STORE_INFO_PUBKEY) { + EVP_PKEY_up_ref(info->_.pubkey); + return info->_.pubkey; + } + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PUBLIC_KEY); return NULL; } @@ -399,8 +725,7 @@ EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info) EVP_PKEY_up_ref(info->_.pkey); return info->_.pkey; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY, - OSSL_STORE_R_NOT_A_KEY); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PRIVATE_KEY); return NULL; } @@ -417,8 +742,7 @@ X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info) X509_up_ref(info->_.x509); return info->_.x509; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT, - OSSL_STORE_R_NOT_A_CERTIFICATE); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CERTIFICATE); return NULL; } @@ -435,8 +759,7 @@ X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info) X509_CRL_up_ref(info->_.crl); return info->_.crl; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL, - OSSL_STORE_R_NOT_A_CRL); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CRL); return NULL; } @@ -447,10 +770,6 @@ void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info) { if (info != NULL) { switch (info->type) { - case OSSL_STORE_INFO_EMBEDDED: - BUF_MEM_free(info->_.embedded.blob); - OPENSSL_free(info->_.embedded.pem_name); - break; case OSSL_STORE_INFO_NAME: OPENSSL_free(info->_.name.name); OPENSSL_free(info->_.name.desc); @@ -458,6 +777,9 @@ void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info) case OSSL_STORE_INFO_PARAMS: EVP_PKEY_free(info->_.params); break; + case OSSL_STORE_INFO_PUBKEY: + EVP_PKEY_free(info->_.pubkey); + break; case OSSL_STORE_INFO_PKEY: EVP_PKEY_free(info->_.pkey); break; @@ -474,12 +796,55 @@ void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info) int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type) { - OSSL_STORE_SEARCH tmp_search; - - if (ctx->loader->find == NULL) - return 0; - tmp_search.search_type = search_type; - return ctx->loader->find(NULL, &tmp_search); + int ret = 0; + + if (ctx->fetched_loader != NULL) { + void *provctx = + ossl_provider_ctx(OSSL_STORE_LOADER_get0_provider(ctx->fetched_loader)); + const OSSL_PARAM *params; + const OSSL_PARAM *p_subject = NULL; + const OSSL_PARAM *p_issuer = NULL; + const OSSL_PARAM *p_serial = NULL; + const OSSL_PARAM *p_fingerprint = NULL; + const OSSL_PARAM *p_alias = NULL; + + if (ctx->fetched_loader->p_settable_ctx_params == NULL) + return 0; + + params = ctx->fetched_loader->p_settable_ctx_params(provctx); + p_subject = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SUBJECT); + p_issuer = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ISSUER); + p_serial = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SERIAL); + p_fingerprint = + OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_FINGERPRINT); + p_alias = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ALIAS); + + switch (search_type) { + case OSSL_STORE_SEARCH_BY_NAME: + ret = (p_subject != NULL); + break; + case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL: + ret = (p_issuer != NULL && p_serial != NULL); + break; + case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT: + ret = (p_fingerprint != NULL); + break; + case OSSL_STORE_SEARCH_BY_ALIAS: + ret = (p_alias != NULL); + break; + } + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL) { + OSSL_STORE_SEARCH tmp_search; + + if (ctx->loader->find == NULL) + return 0; + tmp_search.search_type = search_type; + ret = ctx->loader->find(NULL, &tmp_search); + } +#endif + return ret; } /* Search term constructors */ @@ -488,8 +853,7 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name) OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); if (search == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -499,13 +863,12 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name) } OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, - const ASN1_INTEGER *serial) + const ASN1_INTEGER *serial) { OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); if (search == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -522,20 +885,17 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); if (search == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } - if (digest != NULL && len != (size_t)EVP_MD_size(digest)) { - char buf1[20], buf2[20]; - - BIO_snprintf(buf1, sizeof(buf1), "%d", EVP_MD_size(digest)); - BIO_snprintf(buf2, sizeof(buf2), "%zu", len); - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT, - OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST); - ERR_add_error_data(5, EVP_MD_name(digest), " size is ", buf1, - ", fingerprint size is ", buf2); + if (digest != NULL && len != (size_t)EVP_MD_get_size(digest)) { + ERR_raise_data(ERR_LIB_OSSL_STORE, + OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST, + "%s size is %d, fingerprint size is %zu", + EVP_MD_get0_name(digest), EVP_MD_get_size(digest), len); + OPENSSL_free(search); + return NULL; } search->search_type = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT; @@ -550,8 +910,7 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias) OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); if (search == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -573,13 +932,13 @@ int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion) return criterion->search_type; } -X509_NAME *OSSL_STORE_SEARCH_get0_name(OSSL_STORE_SEARCH *criterion) +X509_NAME *OSSL_STORE_SEARCH_get0_name(const OSSL_STORE_SEARCH *criterion) { return criterion->name; } const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH - *criterion) + *criterion) { return criterion->serial; } @@ -601,85 +960,80 @@ const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion) return criterion->digest; } -/* Internal functions */ -OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name, - BUF_MEM *embedded) +OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, + OSSL_LIB_CTX *libctx, const char *propq, + const UI_METHOD *ui_method, void *ui_data, + const OSSL_PARAM params[], + OSSL_STORE_post_process_info_fn post_process, + void *post_process_data) { - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_EMBEDDED, NULL); - - if (info == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED, - ERR_R_MALLOC_FAILURE); - return NULL; - } + const OSSL_STORE_LOADER *loader = NULL; + OSSL_STORE_LOADER *fetched_loader = NULL; + OSSL_STORE_LOADER_CTX *loader_ctx = NULL; + OSSL_STORE_CTX *ctx = NULL; - info->_.embedded.blob = embedded; - info->_.embedded.pem_name = - new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name); + if (scheme == NULL) + scheme = "file"; - if (new_pem_name != NULL && info->_.embedded.pem_name == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED, - ERR_R_MALLOC_FAILURE); - OSSL_STORE_INFO_free(info); - info = NULL; + OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme); + ERR_set_mark(); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if ((loader = ossl_store_get0_loader_int(scheme)) != NULL) + loader_ctx = loader->attach(loader, bp, libctx, propq, + ui_method, ui_data); +#endif + if (loader == NULL + && (fetched_loader = + OSSL_STORE_LOADER_fetch(libctx, scheme, propq)) != NULL) { + const OSSL_PROVIDER *provider = + OSSL_STORE_LOADER_get0_provider(fetched_loader); + void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); + OSSL_CORE_BIO *cbio = ossl_core_bio_new_from_bio(bp); + + if (cbio == NULL + || (loader_ctx = fetched_loader->p_attach(provctx, cbio)) == NULL) { + OSSL_STORE_LOADER_free(fetched_loader); + fetched_loader = NULL; + } else if (!loader_set_params(fetched_loader, loader_ctx, + params, propq)) { + (void)fetched_loader->p_close(loader_ctx); + OSSL_STORE_LOADER_free(fetched_loader); + fetched_loader = NULL; + } + loader = fetched_loader; + ossl_core_bio_free(cbio); } - return info; -} - -BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info) -{ - if (info->type == OSSL_STORE_INFO_EMBEDDED) - return info->_.embedded.blob; - return NULL; -} - -char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info) -{ - if (info->type == OSSL_STORE_INFO_EMBEDDED) - return info->_.embedded.pem_name; - return NULL; -} - -OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method, - void *ui_data) -{ - OSSL_STORE_CTX *ctx = NULL; - const OSSL_STORE_LOADER *loader = NULL; - OSSL_STORE_LOADER_CTX *loader_ctx = NULL; + if (loader_ctx == NULL) { + ERR_clear_last_mark(); + return NULL; + } - if ((loader = ossl_store_get0_loader_int("file")) == NULL - || ((loader_ctx = ossl_store_file_attach_pem_bio_int(bp)) == NULL)) - goto done; if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO, - ERR_R_MALLOC_FAILURE); - goto done; + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (ui_method != NULL + && !ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data)) { + ERR_clear_last_mark(); + OPENSSL_free(ctx); + return NULL; } + ctx->fetched_loader = fetched_loader; ctx->loader = loader; ctx->loader_ctx = loader_ctx; - loader_ctx = NULL; - ctx->ui_method = ui_method; - ctx->ui_data = ui_data; - ctx->post_process = NULL; - ctx->post_process_data = NULL; - - done: - if (loader_ctx != NULL) - /* - * We ignore a returned error because we will return NULL anyway in - * this case, so if something goes wrong when closing, that'll simply - * just add another entry on the error stack. - */ - (void)loader->close(loader_ctx); - return ctx; -} + ctx->post_process = post_process; + ctx->post_process_data = post_process_data; -int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx) -{ - int loader_ret = ossl_store_file_detach_pem_bio_int(ctx->loader_ctx); + /* + * ossl_store_get0_loader_int will raise an error if the loader for the + * the scheme cannot be retrieved. But if a loader was successfully + * fetched then we remove this error from the error stack. + */ + ERR_pop_to_mark(); - OPENSSL_free(ctx); - return loader_ret; + return ctx; } diff --git a/crypto/openssl/crypto/store/store_local.h b/crypto/openssl/crypto/store/store_local.h index 369dcb33f2d6..8f817fd514bb 100644 --- a/crypto/openssl/crypto/store/store_local.h +++ b/crypto/openssl/crypto/store/store_local.h @@ -1,19 +1,22 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#include #include "internal/thread_once.h" +#include "internal/refcount.h" #include #include #include #include #include #include +#include "internal/passphrase.h" /*- * OSSL_STORE_INFO stuff @@ -25,42 +28,20 @@ struct ossl_store_info_st { union { void *data; /* used internally as generic pointer */ - struct { - BUF_MEM *blob; - char *pem_name; - } embedded; /* when type == OSSL_STORE_INFO_EMBEDDED */ - struct { char *name; char *desc; } name; /* when type == OSSL_STORE_INFO_NAME */ EVP_PKEY *params; /* when type == OSSL_STORE_INFO_PARAMS */ + EVP_PKEY *pubkey; /* when type == OSSL_STORE_INFO_PUBKEY */ EVP_PKEY *pkey; /* when type == OSSL_STORE_INFO_PKEY */ X509 *x509; /* when type == OSSL_STORE_INFO_CERT */ X509_CRL *crl; /* when type == OSSL_STORE_INFO_CRL */ } _; }; - DEFINE_STACK_OF(OSSL_STORE_INFO) -/* - * EMBEDDED is a special type of OSSL_STORE_INFO, specially for the file - * handlers. It should never reach a calling application or any engine. - * However, it can be used by a FILE_HANDLER's try_decode function to signal - * that it has decoded the incoming blob into a new blob, and that the - * attempted decoding should be immediately restarted with the new blob, using - * the new PEM name. - */ -/* - * Because this is an internal type, we don't make it public. - */ -#define OSSL_STORE_INFO_EMBEDDED -1 -OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name, - BUF_MEM *embedded); -BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info); -char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info); - /*- * OSSL_STORE_SEARCH stuff * ----------------------- @@ -99,29 +80,78 @@ OSSL_STORE_LOADER *ossl_store_unregister_loader_int(const char *scheme); /* loader stuff */ struct ossl_store_loader_st { +#ifndef OPENSSL_NO_DEPRECATED_3_0 + /* Legacy stuff */ const char *scheme; ENGINE *engine; OSSL_STORE_open_fn open; + OSSL_STORE_attach_fn attach; OSSL_STORE_ctrl_fn ctrl; OSSL_STORE_expect_fn expect; OSSL_STORE_find_fn find; OSSL_STORE_load_fn load; OSSL_STORE_eof_fn eof; OSSL_STORE_error_fn error; - OSSL_STORE_close_fn close; + OSSL_STORE_close_fn closefn; + OSSL_STORE_open_ex_fn open_ex; +#endif + + /* Provider stuff */ + OSSL_PROVIDER *prov; + int scheme_id; + const char *propdef; + const char *description; + + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_FUNC_store_open_fn *p_open; + OSSL_FUNC_store_attach_fn *p_attach; + OSSL_FUNC_store_settable_ctx_params_fn *p_settable_ctx_params; + OSSL_FUNC_store_set_ctx_params_fn *p_set_ctx_params; + OSSL_FUNC_store_load_fn *p_load; + OSSL_FUNC_store_eof_fn *p_eof; + OSSL_FUNC_store_close_fn *p_close; + OSSL_FUNC_store_export_object_fn *p_export_object; }; DEFINE_LHASH_OF(OSSL_STORE_LOADER); const OSSL_STORE_LOADER *ossl_store_get0_loader_int(const char *scheme); void ossl_store_destroy_loaders_int(void); +#ifdef OPENSSL_NO_DEPRECATED_3_0 +/* struct ossl_store_loader_ctx_st is defined differently by each loader */ +typedef struct ossl_store_loader_ctx_st OSSL_STORE_LOADER_CTX; +#endif + /*- - * OSSL_STORE init stuff + * OSSL_STORE_CTX stuff * --------------------- */ -int ossl_store_init_once(void); -int ossl_store_file_loader_init(void); +struct ossl_store_ctx_st { + const OSSL_STORE_LOADER *loader; /* legacy */ + OSSL_STORE_LOADER *fetched_loader; + OSSL_STORE_LOADER_CTX *loader_ctx; + OSSL_STORE_post_process_info_fn post_process; + void *post_process_data; + int expected_type; + + char *properties; + + /* 0 before the first STORE_load(), 1 otherwise */ + int loading; + /* 1 on load error, only valid for fetched loaders */ + int error_flag; + + /* + * Cache of stuff, to be able to return the contents of a PKCS#12 + * blob, one object at a time. + */ + STACK_OF(OSSL_STORE_INFO) *cached_info; + + struct ossl_passphrase_data_st pwdata; +}; /*- * 'file' scheme stuff @@ -130,3 +160,21 @@ int ossl_store_file_loader_init(void); OSSL_STORE_LOADER_CTX *ossl_store_file_attach_pem_bio_int(BIO *bp); int ossl_store_file_detach_pem_bio_int(OSSL_STORE_LOADER_CTX *ctx); + +/*- + * Provider stuff + * ------------------- + */ +OSSL_STORE_LOADER *ossl_store_loader_fetch(OSSL_LIB_CTX *libctx, + const char *scheme, + const char *properties); +OSSL_STORE_LOADER *ossl_store_loader_fetch_by_number(OSSL_LIB_CTX *libctx, + int scheme_id, + const char *properties); + +/* Standard function to handle the result from OSSL_FUNC_store_load() */ +struct ossl_load_result_data_st { + OSSL_STORE_INFO *v; /* To be filled in */ + OSSL_STORE_CTX *ctx; +}; +OSSL_CALLBACK ossl_store_handle_load_result; diff --git a/crypto/openssl/crypto/store/store_meth.c b/crypto/openssl/crypto/store/store_meth.c new file mode 100644 index 000000000000..a5b0d1b0957c --- /dev/null +++ b/crypto/openssl/crypto/store/store_meth.c @@ -0,0 +1,538 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "crypto/store.h" +#include "internal/core.h" +#include "internal/namemap.h" +#include "internal/property.h" +#include "internal/provider.h" +#include "store_local.h" + +int OSSL_STORE_LOADER_up_ref(OSSL_STORE_LOADER *loader) +{ + int ref = 0; + + if (loader->prov != NULL) + CRYPTO_UP_REF(&loader->refcnt, &ref, loader->lock); + return 1; +} + +void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader) +{ + if (loader != NULL && loader->prov != NULL) { + int i; + + CRYPTO_DOWN_REF(&loader->refcnt, &i, loader->lock); + if (i > 0) + return; + ossl_provider_free(loader->prov); + CRYPTO_THREAD_lock_free(loader->lock); + } + OPENSSL_free(loader); +} + +/* + * OSSL_STORE_LOADER_new() expects the scheme as a constant string, + * which we currently don't have, so we need an alternative allocator. + */ +static OSSL_STORE_LOADER *new_loader(OSSL_PROVIDER *prov) +{ + OSSL_STORE_LOADER *loader; + + if ((loader = OPENSSL_zalloc(sizeof(*loader))) == NULL + || (loader->lock = CRYPTO_THREAD_lock_new()) == NULL) { + OPENSSL_free(loader); + return NULL; + } + loader->prov = prov; + ossl_provider_up_ref(prov); + loader->refcnt = 1; + + return loader; +} + +static int up_ref_loader(void *method) +{ + return OSSL_STORE_LOADER_up_ref(method); +} + +static void free_loader(void *method) +{ + OSSL_STORE_LOADER_free(method); +} + +/* Permanent loader method store, constructor and destructor */ +static void loader_store_free(void *vstore) +{ + ossl_method_store_free(vstore); +} + +static void *loader_store_new(OSSL_LIB_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + +static const OSSL_LIB_CTX_METHOD loader_store_method = { + /* We want loader_store to be cleaned up before the provider store */ + OSSL_LIB_CTX_METHOD_PRIORITY_2, + loader_store_new, + loader_store_free, +}; + +/* Data to be passed through ossl_method_construct() */ +struct loader_data_st { + OSSL_LIB_CTX *libctx; + int scheme_id; /* For get_loader_from_store() */ + const char *scheme; /* For get_loader_from_store() */ + const char *propquery; /* For get_loader_from_store() */ + + OSSL_METHOD_STORE *tmp_store; /* For get_tmp_loader_store() */ + + unsigned int flag_construct_error_occurred : 1; +}; + +/* + * Generic routines to fetch / create OSSL_STORE methods with + * ossl_method_construct() + */ + +/* Temporary loader method store, constructor and destructor */ +static void *get_tmp_loader_store(void *data) +{ + struct loader_data_st *methdata = data; + + if (methdata->tmp_store == NULL) + methdata->tmp_store = ossl_method_store_new(methdata->libctx); + return methdata->tmp_store; +} + + static void dealloc_tmp_loader_store(void *store) +{ + if (store != NULL) + ossl_method_store_free(store); +} + +/* Get the permanent loader store */ +static OSSL_METHOD_STORE *get_loader_store(OSSL_LIB_CTX *libctx) +{ + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX, + &loader_store_method); +} + +static int reserve_loader_store(void *store, void *data) +{ + struct loader_data_st *methdata = data; + + if (store == NULL + && (store = get_loader_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_lock_store(store); +} + +static int unreserve_loader_store(void *store, void *data) +{ + struct loader_data_st *methdata = data; + + if (store == NULL + && (store = get_loader_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_unlock_store(store); +} + +/* Get loader methods from a store, or put one in */ +static void *get_loader_from_store(void *store, const OSSL_PROVIDER **prov, + void *data) +{ + struct loader_data_st *methdata = data; + void *method = NULL; + int id; + + if ((id = methdata->scheme_id) == 0) { + OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx); + + id = ossl_namemap_name2num(namemap, methdata->scheme); + } + + if (store == NULL + && (store = get_loader_store(methdata->libctx)) == NULL) + return NULL; + + if (!ossl_method_store_fetch(store, id, methdata->propquery, prov, &method)) + return NULL; + return method; +} + +static int put_loader_in_store(void *store, void *method, + const OSSL_PROVIDER *prov, + const char *scheme, const char *propdef, + void *data) +{ + struct loader_data_st *methdata = data; + OSSL_NAMEMAP *namemap; + int id; + + if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL + || (id = ossl_namemap_name2num(namemap, scheme)) == 0) + return 0; + + if (store == NULL && (store = get_loader_store(methdata->libctx)) == NULL) + return 0; + + return ossl_method_store_add(store, prov, id, propdef, method, + up_ref_loader, free_loader); +} + +static void *loader_from_algorithm(int scheme_id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + OSSL_STORE_LOADER *loader = NULL; + const OSSL_DISPATCH *fns = algodef->implementation; + + if ((loader = new_loader(prov)) == NULL) + return NULL; + loader->scheme_id = scheme_id; + loader->propdef = algodef->property_definition; + loader->description = algodef->algorithm_description; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_STORE_OPEN: + if (loader->p_open == NULL) + loader->p_open = OSSL_FUNC_store_open(fns); + break; + case OSSL_FUNC_STORE_ATTACH: + if (loader->p_attach == NULL) + loader->p_attach = OSSL_FUNC_store_attach(fns); + break; + case OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS: + if (loader->p_settable_ctx_params == NULL) + loader->p_settable_ctx_params = + OSSL_FUNC_store_settable_ctx_params(fns); + break; + case OSSL_FUNC_STORE_SET_CTX_PARAMS: + if (loader->p_set_ctx_params == NULL) + loader->p_set_ctx_params = OSSL_FUNC_store_set_ctx_params(fns); + break; + case OSSL_FUNC_STORE_LOAD: + if (loader->p_load == NULL) + loader->p_load = OSSL_FUNC_store_load(fns); + break; + case OSSL_FUNC_STORE_EOF: + if (loader->p_eof == NULL) + loader->p_eof = OSSL_FUNC_store_eof(fns); + break; + case OSSL_FUNC_STORE_CLOSE: + if (loader->p_close == NULL) + loader->p_close = OSSL_FUNC_store_close(fns); + break; + case OSSL_FUNC_STORE_EXPORT_OBJECT: + if (loader->p_export_object == NULL) + loader->p_export_object = OSSL_FUNC_store_export_object(fns); + break; + } + } + + if ((loader->p_open == NULL && loader->p_attach == NULL) + || loader->p_load == NULL + || loader->p_eof == NULL + || loader->p_close == NULL) { + /* Only set_ctx_params is optionaal */ + OSSL_STORE_LOADER_free(loader); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADER_INCOMPLETE); + return NULL; + } + return loader; +} + +/* + * The core fetching functionality passes the scheme of the implementation. + * This function is responsible to getting an identity number for them, + * then call loader_from_algorithm() with that identity number. + */ +static void *construct_loader(const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov, void *data) +{ + /* + * This function is only called if get_loader_from_store() returned + * NULL, so it's safe to say that of all the spots to create a new + * namemap entry, this is it. Should the scheme already exist there, we + * know that ossl_namemap_add() will return its corresponding number. + */ + struct loader_data_st *methdata = data; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *scheme = algodef->algorithm_names; + int id = ossl_namemap_add_name(namemap, 0, scheme); + void *method = NULL; + + if (id != 0) + method = loader_from_algorithm(id, algodef, prov); + + /* + * Flag to indicate that there was actual construction errors. This + * helps inner_loader_fetch() determine what error it should + * record on inaccessible algorithms. + */ + if (method == NULL) + methdata->flag_construct_error_occurred = 1; + + return method; +} + +/* Intermediary function to avoid ugly casts, used below */ +static void destruct_loader(void *method, void *data) +{ + OSSL_STORE_LOADER_free(method); +} + +/* Fetching support. Can fetch by numeric identity or by scheme */ +static OSSL_STORE_LOADER * +inner_loader_fetch(struct loader_data_st *methdata, int id, + const char *scheme, const char *properties) +{ + OSSL_METHOD_STORE *store = get_loader_store(methdata->libctx); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx); + const char *const propq = properties != NULL ? properties : ""; + void *method = NULL; + int unsupported = 0; + + if (store == NULL || namemap == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + + /* + * If we have been passed both an id and a scheme, we have an + * internal programming error. + */ + if (!ossl_assert(id == 0 || scheme == NULL)) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_INTERNAL_ERROR); + return NULL; + } + + /* If we haven't received a name id yet, try to get one for the name */ + if (id == 0 && scheme != NULL) + id = ossl_namemap_name2num(namemap, scheme); + + /* + * If we haven't found the name yet, chances are that the algorithm to + * be fetched is unsupported. + */ + if (id == 0) + unsupported = 1; + + if (id == 0 + || !ossl_method_store_cache_get(store, NULL, id, propq, &method)) { + OSSL_METHOD_CONSTRUCT_METHOD mcm = { + get_tmp_loader_store, + reserve_loader_store, + unreserve_loader_store, + get_loader_from_store, + put_loader_in_store, + construct_loader, + destruct_loader + }; + OSSL_PROVIDER *prov = NULL; + + methdata->scheme_id = id; + methdata->scheme = scheme; + methdata->propquery = propq; + methdata->flag_construct_error_occurred = 0; + if ((method = ossl_method_construct(methdata->libctx, OSSL_OP_STORE, + &prov, 0 /* !force_cache */, + &mcm, methdata)) != NULL) { + /* + * If construction did create a method for us, we know that there + * is a correct scheme_id, since those have already been calculated + * in get_loader_from_store() and put_loader_in_store() above. + */ + if (id == 0) + id = ossl_namemap_name2num(namemap, scheme); + ossl_method_store_cache_set(store, prov, id, propq, method, + up_ref_loader, free_loader); + } + + /* + * If we never were in the constructor, the algorithm to be fetched + * is unsupported. + */ + unsupported = !methdata->flag_construct_error_occurred; + } + + if ((id != 0 || scheme != NULL) && method == NULL) { + int code = unsupported ? ERR_R_UNSUPPORTED : ERR_R_FETCH_FAILED; + const char *helpful_msg = + unsupported + ? ( "No store loader found. For standard store loaders you need " + "at least one of the default or base providers available. " + "Did you forget to load them? Info: " ) + : ""; + + if (scheme == NULL) + scheme = ossl_namemap_num2name(namemap, id, 0); + ERR_raise_data(ERR_LIB_OSSL_STORE, code, + "%s%s, Scheme (%s : %d), Properties (%s)", + helpful_msg, + ossl_lib_ctx_get_descriptor(methdata->libctx), + scheme == NULL ? "" : scheme, id, + properties == NULL ? "" : properties); + } + + return method; +} + +OSSL_STORE_LOADER *OSSL_STORE_LOADER_fetch(OSSL_LIB_CTX *libctx, + const char *scheme, + const char *properties) +{ + struct loader_data_st methdata; + void *method; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + method = inner_loader_fetch(&methdata, 0, scheme, properties); + dealloc_tmp_loader_store(methdata.tmp_store); + return method; +} + +OSSL_STORE_LOADER *ossl_store_loader_fetch_by_number(OSSL_LIB_CTX *libctx, + int scheme_id, + const char *properties) +{ + struct loader_data_st methdata; + void *method; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + method = inner_loader_fetch(&methdata, scheme_id, NULL, properties); + dealloc_tmp_loader_store(methdata.tmp_store); + return method; +} + +int ossl_store_loader_store_cache_flush(OSSL_LIB_CTX *libctx) +{ + OSSL_METHOD_STORE *store = get_loader_store(libctx); + + if (store != NULL) + return ossl_method_store_cache_flush_all(store); + return 1; +} + +int ossl_store_loader_store_remove_all_provided(const OSSL_PROVIDER *prov) +{ + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_METHOD_STORE *store = get_loader_store(libctx); + + if (store != NULL) + return ossl_method_store_remove_all_provided(store, prov); + return 1; +} + +/* + * Library of basic method functions + */ + +const OSSL_PROVIDER *OSSL_STORE_LOADER_get0_provider(const OSSL_STORE_LOADER *loader) +{ + if (!ossl_assert(loader != NULL)) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return loader->prov; +} + +const char *OSSL_STORE_LOADER_get0_properties(const OSSL_STORE_LOADER *loader) +{ + if (!ossl_assert(loader != NULL)) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return loader->propdef; +} + +int ossl_store_loader_get_number(const OSSL_STORE_LOADER *loader) +{ + if (!ossl_assert(loader != NULL)) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return loader->scheme_id; +} + +const char *OSSL_STORE_LOADER_get0_description(const OSSL_STORE_LOADER *loader) +{ + return loader->description; +} + +int OSSL_STORE_LOADER_is_a(const OSSL_STORE_LOADER *loader, const char *name) +{ + if (loader->prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(loader->prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_name2num(namemap, name) == loader->scheme_id; + } + return 0; +} + +struct do_one_data_st { + void (*user_fn)(OSSL_STORE_LOADER *loader, void *arg); + void *user_arg; +}; + +static void do_one(ossl_unused int id, void *method, void *arg) +{ + struct do_one_data_st *data = arg; + + data->user_fn(method, data->user_arg); +} + +void OSSL_STORE_LOADER_do_all_provided(OSSL_LIB_CTX *libctx, + void (*user_fn)(OSSL_STORE_LOADER *loader, + void *arg), + void *user_arg) +{ + struct loader_data_st methdata; + struct do_one_data_st data; + + methdata.libctx = libctx; + methdata.tmp_store = NULL; + (void)inner_loader_fetch(&methdata, 0, NULL, NULL /* properties */); + + data.user_fn = user_fn; + data.user_arg = user_arg; + if (methdata.tmp_store != NULL) + ossl_method_store_do_all(methdata.tmp_store, &do_one, &data); + ossl_method_store_do_all(get_loader_store(libctx), &do_one, &data); + dealloc_tmp_loader_store(methdata.tmp_store); +} + +int OSSL_STORE_LOADER_names_do_all(const OSSL_STORE_LOADER *loader, + void (*fn)(const char *name, void *data), + void *data) +{ + if (loader == NULL) + return 0; + + if (loader->prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(loader->prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_doall_names(namemap, loader->scheme_id, fn, data); + } + + return 1; +} diff --git a/crypto/openssl/crypto/store/store_register.c b/crypto/openssl/crypto/store/store_register.c index 3631d9b50634..6fa7352ccdc1 100644 --- a/crypto/openssl/crypto/store/store_register.c +++ b/crypto/openssl/crypto/store/store_register.c @@ -1,7 +1,7 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -39,13 +39,12 @@ OSSL_STORE_LOADER *OSSL_STORE_LOADER_new(ENGINE *e, const char *scheme) * later on. */ if (scheme == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_LOADER_NEW, - OSSL_STORE_R_INVALID_SCHEME); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_INVALID_SCHEME); return NULL; } if ((res = OPENSSL_zalloc(sizeof(*res))) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_LOADER_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -71,6 +70,21 @@ int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *loader, return 1; } +int OSSL_STORE_LOADER_set_open_ex + (OSSL_STORE_LOADER *loader, + OSSL_STORE_open_ex_fn open_ex_function) +{ + loader->open_ex = open_ex_function; + return 1; +} + +int OSSL_STORE_LOADER_set_attach(OSSL_STORE_LOADER *loader, + OSSL_STORE_attach_fn attach_function) +{ + loader->attach = attach_function; + return 1; +} + int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *loader, OSSL_STORE_ctrl_fn ctrl_function) { @@ -116,15 +130,10 @@ int OSSL_STORE_LOADER_set_error(OSSL_STORE_LOADER *loader, int OSSL_STORE_LOADER_set_close(OSSL_STORE_LOADER *loader, OSSL_STORE_close_fn close_function) { - loader->close = close_function; + loader->closefn = close_function; return 1; } -void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader) -{ - OPENSSL_free(loader); -} - /* * Functions for registering OSSL_STORE_LOADERs */ @@ -142,6 +151,14 @@ static int store_loader_cmp(const OSSL_STORE_LOADER *a, } static LHASH_OF(OSSL_STORE_LOADER) *loader_register = NULL; +static int ossl_store_register_init(void) +{ + if (loader_register == NULL) { + loader_register = lh_OSSL_STORE_LOADER_new(store_loader_hash, + store_loader_cmp); + } + return loader_register != NULL; +} int ossl_store_register_loader_int(OSSL_STORE_LOADER *loader) { @@ -161,33 +178,26 @@ int ossl_store_register_loader_int(OSSL_STORE_LOADER *loader) || strchr("+-.", *scheme) != NULL)) scheme++; if (*scheme != '\0') { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT, - OSSL_STORE_R_INVALID_SCHEME); - ERR_add_error_data(2, "scheme=", loader->scheme); + ERR_raise_data(ERR_LIB_OSSL_STORE, OSSL_STORE_R_INVALID_SCHEME, + "scheme=%s", loader->scheme); return 0; } /* Check that functions we absolutely require are present */ if (loader->open == NULL || loader->load == NULL || loader->eof == NULL - || loader->error == NULL || loader->close == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT, - OSSL_STORE_R_LOADER_INCOMPLETE); + || loader->error == NULL || loader->closefn == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADER_INCOMPLETE); return 0; } if (!RUN_ONCE(®istry_init, do_registry_init)) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return 0; } - CRYPTO_THREAD_write_lock(registry_lock); - - if (loader_register == NULL) { - loader_register = lh_OSSL_STORE_LOADER_new(store_loader_hash, - store_loader_cmp); - } + if (!CRYPTO_THREAD_write_lock(registry_lock)) + return 0; - if (loader_register != NULL + if (ossl_store_register_init() && (lh_OSSL_STORE_LOADER_insert(loader_register, loader) != NULL || lh_OSSL_STORE_LOADER_error(loader_register) == 0)) ok = 1; @@ -198,8 +208,6 @@ int ossl_store_register_loader_int(OSSL_STORE_LOADER *loader) } int OSSL_STORE_register_loader(OSSL_STORE_LOADER *loader) { - if (!ossl_store_init_once()) - return 0; return ossl_store_register_loader_int(loader); } @@ -212,25 +220,22 @@ const OSSL_STORE_LOADER *ossl_store_get0_loader_int(const char *scheme) template.open = NULL; template.load = NULL; template.eof = NULL; - template.close = NULL; - - if (!ossl_store_init_once()) - return NULL; + template.closefn = NULL; + template.open_ex = NULL; if (!RUN_ONCE(®istry_init, do_registry_init)) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } - CRYPTO_THREAD_write_lock(registry_lock); - - loader = lh_OSSL_STORE_LOADER_retrieve(loader_register, &template); + if (!CRYPTO_THREAD_write_lock(registry_lock)) + return NULL; - if (loader == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT, - OSSL_STORE_R_UNREGISTERED_SCHEME); - ERR_add_error_data(2, "scheme=", scheme); - } + if (!ossl_store_register_init()) + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_INTERNAL_ERROR); + else if ((loader = lh_OSSL_STORE_LOADER_retrieve(loader_register, + &template)) == NULL) + ERR_raise_data(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNREGISTERED_SCHEME, + "scheme=%s", scheme); CRYPTO_THREAD_unlock(registry_lock); @@ -246,22 +251,21 @@ OSSL_STORE_LOADER *ossl_store_unregister_loader_int(const char *scheme) template.open = NULL; template.load = NULL; template.eof = NULL; - template.close = NULL; + template.closefn = NULL; if (!RUN_ONCE(®istry_init, do_registry_init)) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } - CRYPTO_THREAD_write_lock(registry_lock); - - loader = lh_OSSL_STORE_LOADER_delete(loader_register, &template); + if (!CRYPTO_THREAD_write_lock(registry_lock)) + return NULL; - if (loader == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT, - OSSL_STORE_R_UNREGISTERED_SCHEME); - ERR_add_error_data(2, "scheme=", scheme); - } + if (!ossl_store_register_init()) + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_INTERNAL_ERROR); + else if ((loader = lh_OSSL_STORE_LOADER_delete(loader_register, + &template)) == NULL) + ERR_raise_data(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNREGISTERED_SCHEME, + "scheme=%s", scheme); CRYPTO_THREAD_unlock(registry_lock); @@ -269,14 +273,11 @@ OSSL_STORE_LOADER *ossl_store_unregister_loader_int(const char *scheme) } OSSL_STORE_LOADER *OSSL_STORE_unregister_loader(const char *scheme) { - if (!ossl_store_init_once()) - return 0; return ossl_store_unregister_loader_int(scheme); } void ossl_store_destroy_loaders_int(void) { - assert(lh_OSSL_STORE_LOADER_num_items(loader_register) == 0); lh_OSSL_STORE_LOADER_free(loader_register); loader_register = NULL; CRYPTO_THREAD_lock_free(registry_lock); @@ -292,6 +293,7 @@ int OSSL_STORE_do_all_loaders(void (*do_function) (const OSSL_STORE_LOADER *loader, void *do_arg), void *do_arg) { - lh_OSSL_STORE_LOADER_doall_void(loader_register, do_function, do_arg); + if (ossl_store_register_init()) + lh_OSSL_STORE_LOADER_doall_void(loader_register, do_function, do_arg); return 1; } diff --git a/crypto/openssl/crypto/store/store_result.c b/crypto/openssl/crypto/store/store_result.c new file mode 100644 index 000000000000..96d31199074d --- /dev/null +++ b/crypto/openssl/crypto/store/store_result.c @@ -0,0 +1,648 @@ +/* + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "e_os.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/provider.h" +#include "internal/passphrase.h" +#include "crypto/evp.h" +#include "crypto/x509.h" +#include "store_local.h" + +#ifndef OSSL_OBJECT_PKCS12 +/* + * The object abstraction doesn't know PKCS#12, but we want to indicate + * it anyway, so we create our own. Since the public macros use positive + * numbers, negative ones should be fine. They must never slip out from + * this translation unit anyway. + */ +# define OSSL_OBJECT_PKCS12 -1 +#endif + +/* + * ossl_store_handle_load_result() is initially written to be a companion + * to our 'file:' scheme provider implementation, but has been made generic + * to serve others as well. + * + * This result handler takes any object abstraction (see provider-object(7)) + * and does the best it can with it. If the object is passed by value (not + * by reference), the contents are currently expected to be DER encoded. + * If an object type is specified, that will be respected; otherwise, this + * handler will guess the contents, by trying the following in order: + * + * 1. Decode it into an EVP_PKEY, using OSSL_DECODER. + * 2. Decode it into an X.509 certificate, using d2i_X509 / d2i_X509_AUX. + * 3. Decode it into an X.509 CRL, using d2i_X509_CRL. + * 4. Decode it into a PKCS#12 structure, using d2i_PKCS12 (*). + * + * For the 'file:' scheme implementation, this is division of labor. Since + * the libcrypto <-> provider interface currently doesn't support certain + * structures as first class objects, they must be unpacked from DER here + * rather than in the provider. The current exception is asymmetric keys, + * which can reside within the provider boundary, most of all thanks to + * OSSL_FUNC_keymgmt_load(), which allows loading the key material by + * reference. + */ + +struct extracted_param_data_st { + int object_type; + const char *data_type; + const char *data_structure; + const char *utf8_data; + const void *octet_data; + size_t octet_data_size; + const void *ref; + size_t ref_size; + const char *desc; +}; + +static int try_name(struct extracted_param_data_st *, OSSL_STORE_INFO **); +static int try_key(struct extracted_param_data_st *, OSSL_STORE_INFO **, + OSSL_STORE_CTX *, const OSSL_PROVIDER *, + OSSL_LIB_CTX *, const char *); +static int try_cert(struct extracted_param_data_st *, OSSL_STORE_INFO **, + OSSL_LIB_CTX *, const char *); +static int try_crl(struct extracted_param_data_st *, OSSL_STORE_INFO **, + OSSL_LIB_CTX *, const char *); +static int try_pkcs12(struct extracted_param_data_st *, OSSL_STORE_INFO **, + OSSL_STORE_CTX *, OSSL_LIB_CTX *, const char *); + +int ossl_store_handle_load_result(const OSSL_PARAM params[], void *arg) +{ + struct ossl_load_result_data_st *cbdata = arg; + OSSL_STORE_INFO **v = &cbdata->v; + OSSL_STORE_CTX *ctx = cbdata->ctx; + const OSSL_PROVIDER *provider = + OSSL_STORE_LOADER_get0_provider(ctx->fetched_loader); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(provider); + const char *propq = ctx->properties; + const OSSL_PARAM *p; + struct extracted_param_data_st helper_data; + + memset(&helper_data, 0, sizeof(helper_data)); + helper_data.object_type = OSSL_OBJECT_UNKNOWN; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_TYPE)) != NULL + && !OSSL_PARAM_get_int(p, &helper_data.object_type)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_TYPE); + if (p != NULL + && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.data_type)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA); + if (p != NULL + && !OSSL_PARAM_get_octet_string_ptr(p, &helper_data.octet_data, + &helper_data.octet_data_size) + && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.utf8_data)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_STRUCTURE); + if (p != NULL + && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.data_structure)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_REFERENCE); + if (p != NULL && !OSSL_PARAM_get_octet_string_ptr(p, &helper_data.ref, + &helper_data.ref_size)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DESC); + if (p != NULL && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.desc)) + return 0; + + /* + * The helper functions return 0 on actual errors, otherwise 1, even if + * they didn't fill out |*v|. + */ + ERR_set_mark(); + if (*v == NULL && !try_name(&helper_data, v)) + goto err; + ERR_pop_to_mark(); + ERR_set_mark(); + if (*v == NULL && !try_key(&helper_data, v, ctx, provider, libctx, propq)) + goto err; + ERR_pop_to_mark(); + ERR_set_mark(); + if (*v == NULL && !try_cert(&helper_data, v, libctx, propq)) + goto err; + ERR_pop_to_mark(); + ERR_set_mark(); + if (*v == NULL && !try_crl(&helper_data, v, libctx, propq)) + goto err; + ERR_pop_to_mark(); + ERR_set_mark(); + if (*v == NULL && !try_pkcs12(&helper_data, v, ctx, libctx, propq)) + goto err; + ERR_pop_to_mark(); + + if (*v == NULL) + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_UNSUPPORTED); + + return (*v != NULL); + err: + ERR_clear_last_mark(); + return 0; +} + +static int try_name(struct extracted_param_data_st *data, OSSL_STORE_INFO **v) +{ + if (data->object_type == OSSL_OBJECT_NAME) { + char *newname = NULL, *newdesc = NULL; + + if (data->utf8_data == NULL) + return 0; + if ((newname = OPENSSL_strdup(data->utf8_data)) == NULL + || (data->desc != NULL + && (newdesc = OPENSSL_strdup(data->desc)) == NULL) + || (*v = OSSL_STORE_INFO_new_NAME(newname)) == NULL) { + OPENSSL_free(newname); + OPENSSL_free(newdesc); + return 0; + } + OSSL_STORE_INFO_set0_NAME_description(*v, newdesc); + } + return 1; +} + +/* + * For the rest of the object types, the provider code may not know what + * type of data it gave us, so we may need to figure that out on our own. + * Therefore, we do check for OSSL_OBJECT_UNKNOWN everywhere below, and + * only return 0 on error if the object type is known. + */ + +static EVP_PKEY *try_key_ref(struct extracted_param_data_st *data, + OSSL_STORE_CTX *ctx, + const OSSL_PROVIDER *provider, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_PKEY *pk = NULL; + EVP_KEYMGMT *keymgmt = NULL; + void *keydata = NULL; + int try_fallback = 2; + + /* If we have an object reference, we must have a data type */ + if (data->data_type == NULL) + return 0; + + keymgmt = EVP_KEYMGMT_fetch(libctx, data->data_type, propq); + ERR_set_mark(); + while (keymgmt != NULL && keydata == NULL && try_fallback-- > 0) { + /* + * There are two possible cases + * + * 1. The keymgmt is from the same provider as the loader, + * so we can use evp_keymgmt_load() + * 2. The keymgmt is from another provider, then we must + * do the export/import dance. + */ + if (EVP_KEYMGMT_get0_provider(keymgmt) == provider) { + /* no point trying fallback here */ + try_fallback = 0; + keydata = evp_keymgmt_load(keymgmt, data->ref, data->ref_size); + } else { + struct evp_keymgmt_util_try_import_data_st import_data; + OSSL_FUNC_store_export_object_fn *export_object = + ctx->fetched_loader->p_export_object; + + import_data.keymgmt = keymgmt; + import_data.keydata = NULL; + import_data.selection = OSSL_KEYMGMT_SELECT_ALL; + + if (export_object != NULL) { + /* + * No need to check for errors here, the value of + * |import_data.keydata| is as much an indicator. + */ + (void)export_object(ctx->loader_ctx, + data->ref, data->ref_size, + &evp_keymgmt_util_try_import, + &import_data); + } + + keydata = import_data.keydata; + } + + if (keydata == NULL && try_fallback > 0) { + EVP_KEYMGMT_free(keymgmt); + keymgmt = evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)provider, + data->data_type, propq); + if (keymgmt != NULL) { + ERR_pop_to_mark(); + ERR_set_mark(); + } + } + } + if (keydata != NULL) { + ERR_pop_to_mark(); + pk = evp_keymgmt_util_make_pkey(keymgmt, keydata); + } else { + ERR_clear_last_mark(); + } + EVP_KEYMGMT_free(keymgmt); + + return pk; +} + +static EVP_PKEY *try_key_value(struct extracted_param_data_st *data, + OSSL_STORE_CTX *ctx, + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_PKEY *pk = NULL; + OSSL_DECODER_CTX *decoderctx = NULL; + const unsigned char *pdata = data->octet_data; + size_t pdatalen = data->octet_data_size; + int selection = 0; + + switch (ctx->expected_type) { + case 0: + break; + case OSSL_STORE_INFO_PARAMS: + selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS; + break; + case OSSL_STORE_INFO_PUBKEY: + selection = + OSSL_KEYMGMT_SELECT_PUBLIC_KEY + | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS; + break; + case OSSL_STORE_INFO_PKEY: + selection = OSSL_KEYMGMT_SELECT_ALL; + break; + default: + return NULL; + } + + decoderctx = + OSSL_DECODER_CTX_new_for_pkey(&pk, NULL, data->data_structure, + data->data_type, selection, libctx, + propq); + (void)OSSL_DECODER_CTX_set_passphrase_cb(decoderctx, cb, cbarg); + + /* No error if this couldn't be decoded */ + (void)OSSL_DECODER_from_data(decoderctx, &pdata, &pdatalen); + + OSSL_DECODER_CTX_free(decoderctx); + + return pk; +} + +typedef OSSL_STORE_INFO *store_info_new_fn(EVP_PKEY *); + +static EVP_PKEY *try_key_value_legacy(struct extracted_param_data_st *data, + store_info_new_fn **store_info_new, + OSSL_STORE_CTX *ctx, + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_PKEY *pk = NULL; + const unsigned char *der = data->octet_data, *derp; + long der_len = (long)data->octet_data_size; + + /* Try PUBKEY first, that's a real easy target */ + if (ctx->expected_type == 0 + || ctx->expected_type == OSSL_STORE_INFO_PUBKEY) { + derp = der; + pk = d2i_PUBKEY_ex(NULL, &derp, der_len, libctx, propq); + + if (pk != NULL) + *store_info_new = OSSL_STORE_INFO_new_PUBKEY; + } + + /* Try private keys next */ + if (pk == NULL + && (ctx->expected_type == 0 + || ctx->expected_type == OSSL_STORE_INFO_PKEY)) { + unsigned char *new_der = NULL; + X509_SIG *p8 = NULL; + PKCS8_PRIV_KEY_INFO *p8info = NULL; + + /* See if it's an encrypted PKCS#8 and decrypt it. */ + derp = der; + p8 = d2i_X509_SIG(NULL, &derp, der_len); + + if (p8 != NULL) { + char pbuf[PEM_BUFSIZE]; + size_t plen = 0; + + if (!cb(pbuf, sizeof(pbuf), &plen, NULL, cbarg)) { + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_BAD_PASSWORD_READ); + } else { + const X509_ALGOR *alg = NULL; + const ASN1_OCTET_STRING *oct = NULL; + int len = 0; + + X509_SIG_get0(p8, &alg, &oct); + + /* + * No need to check the returned value, |new_der| + * will be NULL on error anyway. + */ + PKCS12_pbe_crypt(alg, pbuf, plen, + oct->data, oct->length, + &new_der, &len, 0); + der_len = len; + der = new_der; + } + X509_SIG_free(p8); + } + + /* + * If the encrypted PKCS#8 couldn't be decrypted, + * |der| is NULL + */ + if (der != NULL) { + /* Try to unpack an unencrypted PKCS#8, that's easy */ + derp = der; + p8info = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, der_len); + + if (p8info != NULL) { + pk = EVP_PKCS82PKEY_ex(p8info, libctx, propq); + PKCS8_PRIV_KEY_INFO_free(p8info); + } + } + + if (pk != NULL) + *store_info_new = OSSL_STORE_INFO_new_PKEY; + + OPENSSL_free(new_der); + } + + return pk; +} + +static int try_key(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, + OSSL_STORE_CTX *ctx, const OSSL_PROVIDER *provider, + OSSL_LIB_CTX *libctx, const char *propq) +{ + store_info_new_fn *store_info_new = NULL; + + if (data->object_type == OSSL_OBJECT_UNKNOWN + || data->object_type == OSSL_OBJECT_PKEY) { + EVP_PKEY *pk = NULL; + + /* Prefer key by reference than key by value */ + if (data->object_type == OSSL_OBJECT_PKEY && data->ref != NULL) { + pk = try_key_ref(data, ctx, provider, libctx, propq); + + /* + * If for some reason we couldn't get a key, it's an error. + * It indicates that while decoders could make a key reference, + * the keymgmt somehow couldn't handle it, or doesn't have a + * OSSL_FUNC_keymgmt_load function. + */ + if (pk == NULL) + return 0; + } else if (data->octet_data != NULL) { + OSSL_PASSPHRASE_CALLBACK *cb = ossl_pw_passphrase_callback_dec; + void *cbarg = &ctx->pwdata; + + pk = try_key_value(data, ctx, cb, cbarg, libctx, propq); + + /* + * Desperate last maneuver, in case the decoders don't support + * the data we have, then we try on our own to at least get an + * engine provided legacy key. + * This is the same as der2key_decode() does, but in a limited + * way and within the walls of libcrypto. + */ + if (pk == NULL) + pk = try_key_value_legacy(data, &store_info_new, ctx, + cb, cbarg, libctx, propq); + } + + if (pk != NULL) { + data->object_type = OSSL_OBJECT_PKEY; + + if (store_info_new == NULL) { + /* + * We determined the object type for OSSL_STORE_INFO, which + * makes an explicit difference between an EVP_PKEY with just + * (domain) parameters and an EVP_PKEY with actual key + * material. + * The logic is that an EVP_PKEY with actual key material + * always has the public half. + */ + if (evp_keymgmt_util_has(pk, OSSL_KEYMGMT_SELECT_PRIVATE_KEY)) + store_info_new = OSSL_STORE_INFO_new_PKEY; + else if (evp_keymgmt_util_has(pk, + OSSL_KEYMGMT_SELECT_PUBLIC_KEY)) + store_info_new = OSSL_STORE_INFO_new_PUBKEY; + else + store_info_new = OSSL_STORE_INFO_new_PARAMS; + } + *v = store_info_new(pk); + } + + if (*v == NULL) + EVP_PKEY_free(pk); + } + + return 1; +} + +static int try_cert(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, + OSSL_LIB_CTX *libctx, const char *propq) +{ + if (data->object_type == OSSL_OBJECT_UNKNOWN + || data->object_type == OSSL_OBJECT_CERT) { + /* + * In most cases, we can try to interpret the serialized + * data as a trusted cert (X509 + X509_AUX) and fall back + * to reading it as a normal cert (just X509), but if + * |data_type| (the PEM name) specifically declares it as a + * trusted cert, then no fallback should be engaged. + * |ignore_trusted| tells if the fallback can be used (1) + * or not (0). + */ + int ignore_trusted = 1; + X509 *cert = X509_new_ex(libctx, propq); + + if (cert == NULL) + return 0; + + /* If we have a data type, it should be a PEM name */ + if (data->data_type != NULL + && (OPENSSL_strcasecmp(data->data_type, PEM_STRING_X509_TRUSTED) == 0)) + ignore_trusted = 0; + + if (d2i_X509_AUX(&cert, (const unsigned char **)&data->octet_data, + data->octet_data_size) == NULL + && (!ignore_trusted + || d2i_X509(&cert, (const unsigned char **)&data->octet_data, + data->octet_data_size) == NULL)) { + X509_free(cert); + cert = NULL; + } + + if (cert != NULL) { + /* We determined the object type */ + data->object_type = OSSL_OBJECT_CERT; + *v = OSSL_STORE_INFO_new_CERT(cert); + if (*v == NULL) + X509_free(cert); + } + } + + return 1; +} + +static int try_crl(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, + OSSL_LIB_CTX *libctx, const char *propq) +{ + if (data->object_type == OSSL_OBJECT_UNKNOWN + || data->object_type == OSSL_OBJECT_CRL) { + X509_CRL *crl; + + crl = d2i_X509_CRL(NULL, (const unsigned char **)&data->octet_data, + data->octet_data_size); + + if (crl != NULL) + /* We determined the object type */ + data->object_type = OSSL_OBJECT_CRL; + + if (crl != NULL && !ossl_x509_crl_set0_libctx(crl, libctx, propq)) { + X509_CRL_free(crl); + crl = NULL; + } + + if (crl != NULL) + *v = OSSL_STORE_INFO_new_CRL(crl); + if (*v == NULL) + X509_CRL_free(crl); + } + + return 1; +} + +static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, + OSSL_STORE_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int ok = 1; + + /* There is no specific object type for PKCS12 */ + if (data->object_type == OSSL_OBJECT_UNKNOWN) { + /* Initial parsing */ + PKCS12 *p12; + + p12 = d2i_PKCS12(NULL, (const unsigned char **)&data->octet_data, + data->octet_data_size); + + if (p12 != NULL) { + char *pass = NULL; + char tpass[PEM_BUFSIZE + 1]; + size_t tpass_len; + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; + STACK_OF(X509) *chain = NULL; + + data->object_type = OSSL_OBJECT_PKCS12; + + ok = 0; /* Assume decryption or parse error */ + + if (PKCS12_verify_mac(p12, "", 0) + || PKCS12_verify_mac(p12, NULL, 0)) { + pass = ""; + } else { + static char prompt_info[] = "PKCS12 import pass phrase"; + OSSL_PARAM pw_params[] = { + OSSL_PARAM_utf8_string(OSSL_PASSPHRASE_PARAM_INFO, + prompt_info, + sizeof(prompt_info) - 1), + OSSL_PARAM_END + }; + + if (!ossl_pw_get_passphrase(tpass, sizeof(tpass) - 1, + &tpass_len, + pw_params, 0, &ctx->pwdata)) { + ERR_raise(ERR_LIB_OSSL_STORE, + OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR); + goto p12_end; + } + pass = tpass; + /* + * ossl_pw_get_passphrase() does not NUL terminate but + * we must do it for PKCS12_parse() + */ + pass[tpass_len] = '\0'; + if (!PKCS12_verify_mac(p12, pass, tpass_len)) { + ERR_raise_data(ERR_LIB_OSSL_STORE, + OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC, + tpass_len == 0 ? "empty password" : + "maybe wrong password"); + goto p12_end; + } + } + + if (PKCS12_parse(p12, pass, &pkey, &cert, &chain)) { + STACK_OF(OSSL_STORE_INFO) *infos = NULL; + OSSL_STORE_INFO *osi_pkey = NULL; + OSSL_STORE_INFO *osi_cert = NULL; + OSSL_STORE_INFO *osi_ca = NULL; + + ok = 1; /* Parsing went through correctly! */ + + if ((infos = sk_OSSL_STORE_INFO_new_null()) != NULL) { + if (pkey != NULL) { + if ((osi_pkey = OSSL_STORE_INFO_new_PKEY(pkey)) != NULL + /* clearing pkey here avoids case distinctions */ + && (pkey = NULL) == NULL + && sk_OSSL_STORE_INFO_push(infos, osi_pkey) != 0) + osi_pkey = NULL; + else + ok = 0; + } + if (ok && cert != NULL) { + if ((osi_cert = OSSL_STORE_INFO_new_CERT(cert)) != NULL + /* clearing cert here avoids case distinctions */ + && (cert = NULL) == NULL + && sk_OSSL_STORE_INFO_push(infos, osi_cert) != 0) + osi_cert = NULL; + else + ok = 0; + } + while (ok && sk_X509_num(chain) > 0) { + X509 *ca = sk_X509_value(chain, 0); + + if ((osi_ca = OSSL_STORE_INFO_new_CERT(ca)) != NULL + && sk_X509_shift(chain) != NULL + && sk_OSSL_STORE_INFO_push(infos, osi_ca) != 0) + osi_ca = NULL; + else + ok = 0; + } + } + EVP_PKEY_free(pkey); + X509_free(cert); + sk_X509_pop_free(chain, X509_free); + OSSL_STORE_INFO_free(osi_pkey); + OSSL_STORE_INFO_free(osi_cert); + OSSL_STORE_INFO_free(osi_ca); + if (!ok) { + sk_OSSL_STORE_INFO_pop_free(infos, OSSL_STORE_INFO_free); + infos = NULL; + } + ctx->cached_info = infos; + } + p12_end: + OPENSSL_cleanse(tpass, sizeof(tpass)); + PKCS12_free(p12); + } + *v = sk_OSSL_STORE_INFO_shift(ctx->cached_info); + } + + return ok; +} diff --git a/crypto/openssl/crypto/store/store_strings.c b/crypto/openssl/crypto/store/store_strings.c index 76cf3164837c..3d4a8ea73079 100644 --- a/crypto/openssl/crypto/store/store_strings.c +++ b/crypto/openssl/crypto/store/store_strings.c @@ -1,7 +1,7 @@ /* - * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,6 +12,7 @@ static char *type_strings[] = { "Name", /* OSSL_STORE_INFO_NAME */ "Parameters", /* OSSL_STORE_INFO_PARAMS */ + "Public key", /* OSSL_STORE_INFO_PUBKEY */ "Pkey", /* OSSL_STORE_INFO_PKEY */ "Certificate", /* OSSL_STORE_INFO_CERT */ "CRL" /* OSSL_STORE_INFO_CRL */ diff --git a/crypto/openssl/crypto/threads_lib.c b/crypto/openssl/crypto/threads_lib.c new file mode 100644 index 000000000000..0c7162392df8 --- /dev/null +++ b/crypto/openssl/crypto/threads_lib.c @@ -0,0 +1,25 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#include + +#ifndef OPENSSL_NO_DEPRECATED_3_0 + +void OPENSSL_fork_prepare(void) +{ +} + +void OPENSSL_fork_parent(void) +{ +} + +void OPENSSL_fork_child(void) +{ +} + +#endif diff --git a/crypto/openssl/crypto/threads_none.c b/crypto/openssl/crypto/threads_none.c index aaaaae872a9b..2570efde2378 100644 --- a/crypto/openssl/crypto/threads_none.c +++ b/crypto/openssl/crypto/threads_none.c @@ -1,7 +1,7 @@ /* - * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -31,14 +31,14 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) return lock; } -int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock) +__owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock) { if (!ossl_assert(*(unsigned int *)lock == 1)) return 0; return 1; } -int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock) +__owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock) { if (!ossl_assert(*(unsigned int *)lock == 1)) return 0; @@ -133,6 +133,22 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) return 1; } +int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret, + CRYPTO_RWLOCK *lock) +{ + *val |= op; + *ret = *val; + + return 1; +} + +int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock) +{ + *ret = *val; + + return 1; +} + int openssl_init_fork_handlers(void) { return 0; diff --git a/crypto/openssl/crypto/threads_pthread.c b/crypto/openssl/crypto/threads_pthread.c index 360a3136894f..bfc05a4e878c 100644 --- a/crypto/openssl/crypto/threads_pthread.c +++ b/crypto/openssl/crypto/threads_pthread.c @@ -1,15 +1,34 @@ /* - * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use the OPENSSL_fork_*() deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include "internal/cryptlib.h" +#if defined(__sun) +# include +#endif + +#if defined(__apple_build_version__) && __apple_build_version__ < 6000000 +/* + * OS/X 10.7 and 10.8 had a weird version of clang which has __ATOMIC_ACQUIRE and + * __ATOMIC_ACQ_REL but which expects only one parameter for __atomic_is_lock_free() + * rather than two which has signature __atomic_is_lock_free(sizeof(_Atomic(T))). + * All of this makes impossible to use __atomic_is_lock_free here. + * + * See: https://github.com/llvm/llvm-project/commit/a4c2602b714e6c6edb98164550a5ae829b2de760 + */ +#define BROKEN_CLANG_ATOMICS +#endif + #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS) # if defined(OPENSSL_SYS_UNIX) @@ -17,6 +36,8 @@ # include #endif +# include + # ifdef PTHREAD_RWLOCK_INITIALIZER # define USE_RWLOCK # endif @@ -44,8 +65,19 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) return NULL; } + /* + * We don't use recursive mutexes, but try to catch errors if we do. + */ pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); +# if !defined (__TANDEM) && !defined (_SPT_MODEL_) +# if !defined(NDEBUG) && !defined(OPENSSL_NO_MUTEX_ERRORCHECK) + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); +# else + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); +# endif +# else + /* The SPT Thread Library does not define MUTEX attributes. */ +# endif if (pthread_mutex_init(lock, &attr) != 0) { pthread_mutexattr_destroy(&attr); @@ -59,27 +91,31 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) return lock; } -int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock) +__owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock) { # ifdef USE_RWLOCK if (pthread_rwlock_rdlock(lock) != 0) return 0; # else - if (pthread_mutex_lock(lock) != 0) + if (pthread_mutex_lock(lock) != 0) { + assert(errno != EDEADLK && errno != EBUSY); return 0; + } # endif return 1; } -int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock) +__owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock) { # ifdef USE_RWLOCK if (pthread_rwlock_wrlock(lock) != 0) return 0; # else - if (pthread_mutex_lock(lock) != 0) + if (pthread_mutex_lock(lock) != 0) { + assert(errno != EDEADLK && errno != EBUSY); return 0; + } # endif return 1; @@ -91,8 +127,10 @@ int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock) if (pthread_rwlock_unlock(lock) != 0) return 0; # else - if (pthread_mutex_unlock(lock) != 0) + if (pthread_mutex_unlock(lock) != 0) { + assert(errno != EPERM); return 0; + } # endif return 1; @@ -162,14 +200,19 @@ int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b) int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) { -# if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL) && \ - !(defined(__arm__) && __ARM_ARCH < 6) +# if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL) && !defined(BROKEN_CLANG_ATOMICS) if (__atomic_is_lock_free(sizeof(*val), val)) { *ret = __atomic_add_fetch(val, amount, __ATOMIC_ACQ_REL); return 1; } +# elif defined(__sun) && (defined(__SunOS_5_10) || defined(__SunOS_5_11)) + /* This will work for all future Solaris versions. */ + if (ret != NULL) { + *ret = atomic_add_int_nv((volatile unsigned int *)val, amount); + return 1; + } # endif - if (!CRYPTO_THREAD_write_lock(lock)) + if (lock == NULL || !CRYPTO_THREAD_write_lock(lock)) return 0; *val += amount; @@ -181,24 +224,60 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) return 1; } -# ifdef OPENSSL_SYS_UNIX -static pthread_once_t fork_once_control = PTHREAD_ONCE_INIT; - -static void fork_once_func(void) +int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret, + CRYPTO_RWLOCK *lock) { - pthread_atfork(OPENSSL_fork_prepare, - OPENSSL_fork_parent, OPENSSL_fork_child); -} +# if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL) && !defined(BROKEN_CLANG_ATOMICS) + if (__atomic_is_lock_free(sizeof(*val), val)) { + *ret = __atomic_or_fetch(val, op, __ATOMIC_ACQ_REL); + return 1; + } +# elif defined(__sun) && (defined(__SunOS_5_10) || defined(__SunOS_5_11)) + /* This will work for all future Solaris versions. */ + if (ret != NULL) { + *ret = atomic_or_64_nv(val, op); + return 1; + } # endif + if (lock == NULL || !CRYPTO_THREAD_write_lock(lock)) + return 0; + *val |= op; + *ret = *val; -int openssl_init_fork_handlers(void) + if (!CRYPTO_THREAD_unlock(lock)) + return 0; + + return 1; +} + +int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock) { -# ifdef OPENSSL_SYS_UNIX - if (pthread_once(&fork_once_control, fork_once_func) == 0) +# if defined(__GNUC__) && defined(__ATOMIC_ACQUIRE) && !defined(BROKEN_CLANG_ATOMICS) + if (__atomic_is_lock_free(sizeof(*val), val)) { + __atomic_load(val, ret, __ATOMIC_ACQUIRE); + return 1; + } +# elif defined(__sun) && (defined(__SunOS_5_10) || defined(__SunOS_5_11)) + /* This will work for all future Solaris versions. */ + if (ret != NULL) { + *ret = atomic_or_64_nv(val, 0); return 1; + } # endif - return 0; + if (lock == NULL || !CRYPTO_THREAD_read_lock(lock)) + return 0; + *ret = *val; + if (!CRYPTO_THREAD_unlock(lock)) + return 0; + + return 1; +} +# ifndef FIPS_MODULE +int openssl_init_fork_handlers(void) +{ + return 1; } +# endif /* FIPS_MODULE */ int openssl_get_fork_id(void) { diff --git a/crypto/openssl/crypto/trace.c b/crypto/openssl/crypto/trace.c new file mode 100644 index 000000000000..3df9b5a51e99 --- /dev/null +++ b/crypto/openssl/crypto/trace.c @@ -0,0 +1,531 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +#include "internal/thread_once.h" +#include +#include +#include +#include "internal/bio.h" +#include "internal/nelem.h" +#include "internal/refcount.h" +#include "crypto/cryptlib.h" + +#ifndef OPENSSL_NO_TRACE + +static CRYPTO_RWLOCK *trace_lock = NULL; + +static const BIO *current_channel = NULL; + +/*- + * INTERNAL TRACE CHANNEL IMPLEMENTATION + * + * For our own flexibility, all trace categories are associated with a + * BIO sink object, also called the trace channel. Instead of a BIO object, + * the application can also provide a callback function, in which case an + * internal trace channel is attached, which simply calls the registered + * callback function. + */ +static int trace_write(BIO *b, const char *buf, + size_t num, size_t *written); +static int trace_puts(BIO *b, const char *str); +static long trace_ctrl(BIO *channel, int cmd, long argl, void *argp); +static int trace_free(BIO *b); + +static const BIO_METHOD trace_method = { + BIO_TYPE_SOURCE_SINK, + "trace", + trace_write, + NULL, /* old write */ + NULL, /* read_ex */ + NULL, /* read */ + trace_puts, + NULL, /* gets */ + trace_ctrl, /* ctrl */ + NULL, /* create */ + trace_free, /* free */ + NULL, /* callback_ctrl */ +}; + +struct trace_data_st { + OSSL_trace_cb callback; + int category; + void *data; +}; + +static int trace_write(BIO *channel, + const char *buf, size_t num, size_t *written) +{ + struct trace_data_st *ctx = BIO_get_data(channel); + size_t cnt = ctx->callback(buf, num, ctx->category, OSSL_TRACE_CTRL_WRITE, + ctx->data); + + *written = cnt; + return cnt != 0; +} + +static int trace_puts(BIO *channel, const char *str) +{ + size_t written; + + if (trace_write(channel, str, strlen(str), &written)) + return (int)written; + + return EOF; +} + +static long trace_ctrl(BIO *channel, int cmd, long argl, void *argp) +{ + struct trace_data_st *ctx = BIO_get_data(channel); + + switch (cmd) { + case OSSL_TRACE_CTRL_BEGIN: + case OSSL_TRACE_CTRL_END: + /* We know that the callback is likely to return 0 here */ + ctx->callback("", 0, ctx->category, cmd, ctx->data); + return 1; + default: + break; + } + return -2; /* Unsupported */ +} + +static int trace_free(BIO *channel) +{ + if (channel == NULL) + return 0; + OPENSSL_free(BIO_get_data(channel)); + return 1; +} +#endif + +/*- + * TRACE + */ + +/* Helper struct and macro to get name string to number mapping */ +struct trace_category_st { + const char * const name; + const int num; +}; +#define TRACE_CATEGORY_(name) { #name, OSSL_TRACE_CATEGORY_##name } + +static const struct trace_category_st + trace_categories[OSSL_TRACE_CATEGORY_NUM] = { + TRACE_CATEGORY_(ALL), + TRACE_CATEGORY_(TRACE), + TRACE_CATEGORY_(INIT), + TRACE_CATEGORY_(TLS), + TRACE_CATEGORY_(TLS_CIPHER), + TRACE_CATEGORY_(CONF), + TRACE_CATEGORY_(ENGINE_TABLE), + TRACE_CATEGORY_(ENGINE_REF_COUNT), + TRACE_CATEGORY_(PKCS5V2), + TRACE_CATEGORY_(PKCS12_KEYGEN), + TRACE_CATEGORY_(PKCS12_DECRYPT), + TRACE_CATEGORY_(X509V3_POLICY), + TRACE_CATEGORY_(BN_CTX), + TRACE_CATEGORY_(CMP), + TRACE_CATEGORY_(STORE), + TRACE_CATEGORY_(DECODER), + TRACE_CATEGORY_(ENCODER), + TRACE_CATEGORY_(REF_COUNT) +}; + +const char *OSSL_trace_get_category_name(int num) +{ + if (num < 0 || (size_t)num >= OSSL_NELEM(trace_categories)) + return NULL; + /* + * Partial check that OSSL_TRACE_CATEGORY_... macros + * are synced with trace_categories array + */ + if (!ossl_assert(trace_categories[num].name != NULL) + || !ossl_assert(trace_categories[num].num == num)) + return NULL; + return trace_categories[num].name; +} + +int OSSL_trace_get_category_num(const char *name) +{ + size_t i; + + if (name == NULL) + return -1; + + for (i = 0; i < OSSL_NELEM(trace_categories); i++) + if (OPENSSL_strcasecmp(name, trace_categories[i].name) == 0) + return trace_categories[i].num; + + return -1; /* not found */ +} + +#ifndef OPENSSL_NO_TRACE + +/* We use one trace channel for each trace category */ +static struct { + enum { SIMPLE_CHANNEL, CALLBACK_CHANNEL } type; + BIO *bio; + char *prefix; + char *suffix; +} trace_channels[OSSL_TRACE_CATEGORY_NUM] = { + { 0, NULL, NULL, NULL }, +}; + +#endif + +#ifndef OPENSSL_NO_TRACE + +enum { + CHANNEL, + PREFIX, + SUFFIX +}; + +static int trace_attach_cb(int category, int type, const void *data) +{ + switch (type) { + case CHANNEL: + OSSL_TRACE2(TRACE, "Attach channel %p to category '%s'\n", + data, trace_categories[category].name); + break; + case PREFIX: + OSSL_TRACE2(TRACE, "Attach prefix \"%s\" to category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + case SUFFIX: + OSSL_TRACE2(TRACE, "Attach suffix \"%s\" to category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + default: /* No clue */ + break; + } + return 1; +} + +static int trace_detach_cb(int category, int type, const void *data) +{ + switch (type) { + case CHANNEL: + OSSL_TRACE2(TRACE, "Detach channel %p from category '%s'\n", + data, trace_categories[category].name); + break; + case PREFIX: + OSSL_TRACE2(TRACE, "Detach prefix \"%s\" from category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + case SUFFIX: + OSSL_TRACE2(TRACE, "Detach suffix \"%s\" from category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + default: /* No clue */ + break; + } + return 1; +} + +static int do_ossl_trace_init(void); +static CRYPTO_ONCE trace_inited = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(ossl_trace_init) +{ + return do_ossl_trace_init(); +} + +static int set_trace_data(int category, int type, BIO **channel, + const char **prefix, const char **suffix, + int (*attach_cb)(int, int, const void *), + int (*detach_cb)(int, int, const void *)) +{ + BIO *curr_channel = NULL; + char *curr_prefix = NULL; + char *curr_suffix = NULL; + + /* Ensure do_ossl_trace_init() is called once */ + if (!RUN_ONCE(&trace_inited, ossl_trace_init)) + return 0; + + curr_channel = trace_channels[category].bio; + curr_prefix = trace_channels[category].prefix; + curr_suffix = trace_channels[category].suffix; + + /* Make sure to run the detach callback first on all data */ + if (prefix != NULL && curr_prefix != NULL) { + detach_cb(category, PREFIX, curr_prefix); + } + + if (suffix != NULL && curr_suffix != NULL) { + detach_cb(category, SUFFIX, curr_suffix); + } + + if (channel != NULL && curr_channel != NULL) { + detach_cb(category, CHANNEL, curr_channel); + } + + /* After detach callbacks are done, clear data where appropriate */ + if (prefix != NULL && curr_prefix != NULL) { + OPENSSL_free(curr_prefix); + trace_channels[category].prefix = NULL; + } + + if (suffix != NULL && curr_suffix != NULL) { + OPENSSL_free(curr_suffix); + trace_channels[category].suffix = NULL; + } + + if (channel != NULL && curr_channel != NULL) { + BIO_free(curr_channel); + trace_channels[category].type = 0; + trace_channels[category].bio = NULL; + } + + /* Before running callbacks are done, set new data where appropriate */ + if (prefix != NULL && *prefix != NULL) { + if ((curr_prefix = OPENSSL_strdup(*prefix)) == NULL) + return 0; + trace_channels[category].prefix = curr_prefix; + } + + if (suffix != NULL && *suffix != NULL) { + if ((curr_suffix = OPENSSL_strdup(*suffix)) == NULL) + return 0; + trace_channels[category].suffix = curr_suffix; + } + + if (channel != NULL && *channel != NULL) { + trace_channels[category].type = type; + trace_channels[category].bio = *channel; + /* + * This must not be done before setting prefix/suffix, + * as those may fail, and then the caller is mislead to free *channel. + */ + } + + /* Finally, run the attach callback on the new data */ + if (channel != NULL && *channel != NULL) { + attach_cb(category, CHANNEL, *channel); + } + + if (prefix != NULL && *prefix != NULL) { + attach_cb(category, PREFIX, *prefix); + } + + if (suffix != NULL && *suffix != NULL) { + attach_cb(category, SUFFIX, *suffix); + } + + return 1; +} + +static int do_ossl_trace_init(void) +{ + trace_lock = CRYPTO_THREAD_lock_new(); + return trace_lock != NULL; +} + +#endif + +void ossl_trace_cleanup(void) +{ +#ifndef OPENSSL_NO_TRACE + int category; + BIO *channel = NULL; + const char *prefix = NULL; + const char *suffix = NULL; + + for (category = 0; category < OSSL_TRACE_CATEGORY_NUM; category++) { + /* We force the TRACE category to be treated last */ + if (category == OSSL_TRACE_CATEGORY_TRACE) + continue; + set_trace_data(category, 0, &channel, &prefix, &suffix, + trace_attach_cb, trace_detach_cb); + } + set_trace_data(OSSL_TRACE_CATEGORY_TRACE, 0, &channel, + &prefix, &suffix, + trace_attach_cb, trace_detach_cb); + CRYPTO_THREAD_lock_free(trace_lock); +#endif +} + +int OSSL_trace_set_channel(int category, BIO *channel) +{ +#ifndef OPENSSL_NO_TRACE + if (category >= 0 && category < OSSL_TRACE_CATEGORY_NUM) + return set_trace_data(category, SIMPLE_CHANNEL, &channel, NULL, NULL, + trace_attach_cb, trace_detach_cb); +#endif + return 0; +} + +#ifndef OPENSSL_NO_TRACE +static int trace_attach_w_callback_cb(int category, int type, const void *data) +{ + switch (type) { + case CHANNEL: + OSSL_TRACE2(TRACE, + "Attach channel %p to category '%s' (with callback)\n", + data, trace_categories[category].name); + break; + case PREFIX: + OSSL_TRACE2(TRACE, "Attach prefix \"%s\" to category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + case SUFFIX: + OSSL_TRACE2(TRACE, "Attach suffix \"%s\" to category '%s'\n", + (const char *)data, trace_categories[category].name); + break; + default: /* No clue */ + break; + } + return 1; +} +#endif + +int OSSL_trace_set_callback(int category, OSSL_trace_cb callback, void *data) +{ +#ifndef OPENSSL_NO_TRACE + BIO *channel = NULL; + struct trace_data_st *trace_data = NULL; + + if (category < 0 || category >= OSSL_TRACE_CATEGORY_NUM) + return 0; + + if (callback != NULL) { + if ((channel = BIO_new(&trace_method)) == NULL + || (trace_data = + OPENSSL_zalloc(sizeof(struct trace_data_st))) == NULL) + goto err; + + trace_data->callback = callback; + trace_data->category = category; + trace_data->data = data; + + BIO_set_data(channel, trace_data); + } + + if (!set_trace_data(category, CALLBACK_CHANNEL, &channel, NULL, NULL, + trace_attach_w_callback_cb, trace_detach_cb)) + goto err; + + return 1; + + err: + BIO_free(channel); + OPENSSL_free(trace_data); +#endif + + return 0; +} + +int OSSL_trace_set_prefix(int category, const char *prefix) +{ +#ifndef OPENSSL_NO_TRACE + if (category >= 0 && category < OSSL_TRACE_CATEGORY_NUM) + return set_trace_data(category, 0, NULL, &prefix, NULL, + trace_attach_cb, trace_detach_cb); +#endif + return 0; +} + +int OSSL_trace_set_suffix(int category, const char *suffix) +{ +#ifndef OPENSSL_NO_TRACE + if (category >= 0 && category < OSSL_TRACE_CATEGORY_NUM) + return set_trace_data(category, 0, NULL, NULL, &suffix, + trace_attach_cb, trace_detach_cb); +#endif + return 0; +} + +#ifndef OPENSSL_NO_TRACE +static int ossl_trace_get_category(int category) +{ + if (category < 0 || category >= OSSL_TRACE_CATEGORY_NUM) + return -1; + if (trace_channels[category].bio != NULL) + return category; + return OSSL_TRACE_CATEGORY_ALL; +} +#endif + +int OSSL_trace_enabled(int category) +{ + int ret = 0; +#ifndef OPENSSL_NO_TRACE + category = ossl_trace_get_category(category); + if (category >= 0) + ret = trace_channels[category].bio != NULL; +#endif + return ret; +} + +BIO *OSSL_trace_begin(int category) +{ + BIO *channel = NULL; +#ifndef OPENSSL_NO_TRACE + char *prefix = NULL; + + category = ossl_trace_get_category(category); + if (category < 0) + return NULL; + + channel = trace_channels[category].bio; + prefix = trace_channels[category].prefix; + + if (channel != NULL) { + if (!CRYPTO_THREAD_write_lock(trace_lock)) + return NULL; + current_channel = channel; + switch (trace_channels[category].type) { + case SIMPLE_CHANNEL: + if (prefix != NULL) { + (void)BIO_puts(channel, prefix); + (void)BIO_puts(channel, "\n"); + } + break; + case CALLBACK_CHANNEL: + (void)BIO_ctrl(channel, OSSL_TRACE_CTRL_BEGIN, + prefix == NULL ? 0 : strlen(prefix), prefix); + break; + } + } +#endif + return channel; +} + +void OSSL_trace_end(int category, BIO * channel) +{ +#ifndef OPENSSL_NO_TRACE + char *suffix = NULL; + + category = ossl_trace_get_category(category); + if (category < 0) + return; + suffix = trace_channels[category].suffix; + if (channel != NULL + && ossl_assert(channel == current_channel)) { + (void)BIO_flush(channel); + switch (trace_channels[category].type) { + case SIMPLE_CHANNEL: + if (suffix != NULL) { + (void)BIO_puts(channel, suffix); + (void)BIO_puts(channel, "\n"); + } + break; + case CALLBACK_CHANNEL: + (void)BIO_ctrl(channel, OSSL_TRACE_CTRL_END, + suffix == NULL ? 0 : strlen(suffix), suffix); + break; + } + current_channel = NULL; + CRYPTO_THREAD_unlock(trace_lock); + } +#endif +} diff --git a/crypto/openssl/crypto/ts/ts_asn1.c b/crypto/openssl/crypto/ts/ts_asn1.c index 2840f5858acb..ba3195eab8b3 100644 --- a/crypto/openssl/crypto/ts/ts_asn1.c +++ b/crypto/openssl/crypto/ts/ts_asn1.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -17,7 +17,7 @@ ASN1_SEQUENCE(TS_MSG_IMPRINT) = { ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING) } static_ASN1_SEQUENCE_END(TS_MSG_IMPRINT) -IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT) +IMPLEMENT_ASN1_FUNCTIONS(TS_MSG_IMPRINT) IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT) TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a) { @@ -25,9 +25,9 @@ TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a) d2i_TS_MSG_IMPRINT, bp, a); } -int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a) +int i2d_TS_MSG_IMPRINT_bio(BIO *bp, const TS_MSG_IMPRINT *a) { - return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a); + return ASN1_i2d_bio_of(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a); } #ifndef OPENSSL_NO_STDIO TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a) @@ -36,9 +36,9 @@ TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a) d2i_TS_MSG_IMPRINT, fp, a); } -int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a) +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, const TS_MSG_IMPRINT *a) { - return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a); + return ASN1_i2d_fp_of(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a); } #endif @@ -51,16 +51,16 @@ ASN1_SEQUENCE(TS_REQ) = { ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0) } static_ASN1_SEQUENCE_END(TS_REQ) -IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ) +IMPLEMENT_ASN1_FUNCTIONS(TS_REQ) IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ) TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a) { return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a); } -int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a) +int i2d_TS_REQ_bio(BIO *bp, const TS_REQ *a) { - return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a); + return ASN1_i2d_bio_of(TS_REQ, i2d_TS_REQ, bp, a); } #ifndef OPENSSL_NO_STDIO TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a) @@ -68,9 +68,9 @@ TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a) return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a); } -int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a) +int i2d_TS_REQ_fp(FILE *fp, const TS_REQ *a) { - return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a); + return ASN1_i2d_fp_of(TS_REQ, i2d_TS_REQ, fp, a); } #endif @@ -80,7 +80,7 @@ ASN1_SEQUENCE(TS_ACCURACY) = { ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1) } static_ASN1_SEQUENCE_END(TS_ACCURACY) -IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY) +IMPLEMENT_ASN1_FUNCTIONS(TS_ACCURACY) IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY) ASN1_SEQUENCE(TS_TST_INFO) = { @@ -96,7 +96,7 @@ ASN1_SEQUENCE(TS_TST_INFO) = { ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1) } static_ASN1_SEQUENCE_END(TS_TST_INFO) -IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO) +IMPLEMENT_ASN1_FUNCTIONS(TS_TST_INFO) IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO) TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a) { @@ -104,9 +104,9 @@ TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a) a); } -int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a) +int i2d_TS_TST_INFO_bio(BIO *bp, const TS_TST_INFO *a) { - return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a); + return ASN1_i2d_bio_of(TS_TST_INFO, i2d_TS_TST_INFO, bp, a); } #ifndef OPENSSL_NO_STDIO TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a) @@ -115,9 +115,9 @@ TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a) a); } -int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a) +int i2d_TS_TST_INFO_fp(FILE *fp, const TS_TST_INFO *a) { - return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a); + return ASN1_i2d_fp_of(TS_TST_INFO, i2d_TS_TST_INFO, fp, a); } #endif @@ -127,7 +127,7 @@ ASN1_SEQUENCE(TS_STATUS_INFO) = { ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING) } static_ASN1_SEQUENCE_END(TS_STATUS_INFO) -IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO) +IMPLEMENT_ASN1_FUNCTIONS(TS_STATUS_INFO) IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO) static int ts_resp_set_tst_info(TS_RESP *a) @@ -138,18 +138,17 @@ static int ts_resp_set_tst_info(TS_RESP *a) if (a->token) { if (status != 0 && status != 1) { - TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT); + ERR_raise(ERR_LIB_TS, TS_R_TOKEN_PRESENT); return 0; } TS_TST_INFO_free(a->tst_info); a->tst_info = PKCS7_to_TS_TST_INFO(a->token); if (!a->tst_info) { - TSerr(TS_F_TS_RESP_SET_TST_INFO, - TS_R_PKCS7_TO_TS_TST_INFO_FAILED); + ERR_raise(ERR_LIB_TS, TS_R_PKCS7_TO_TS_TST_INFO_FAILED); return 0; } } else if (status == 0 || status == 1) { - TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT); + ERR_raise(ERR_LIB_TS, TS_R_TOKEN_NOT_PRESENT); return 0; } @@ -176,7 +175,7 @@ ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = { ASN1_OPT(TS_RESP, token, PKCS7), } static_ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP) -IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP) +IMPLEMENT_ASN1_FUNCTIONS(TS_RESP) IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP) @@ -185,9 +184,9 @@ TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a) return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a); } -int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a) +int i2d_TS_RESP_bio(BIO *bp, const TS_RESP *a) { - return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a); + return ASN1_i2d_bio_of(TS_RESP, i2d_TS_RESP, bp, a); } #ifndef OPENSSL_NO_STDIO TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a) @@ -195,53 +194,12 @@ TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a) return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a); } -int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a) +int i2d_TS_RESP_fp(FILE *fp, const TS_RESP *a) { - return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a); + return ASN1_i2d_fp_of(TS_RESP, i2d_TS_RESP, fp, a); } #endif -ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = { - ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME), - ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER) -} static_ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL) - -IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL) -IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL) - -ASN1_SEQUENCE(ESS_CERT_ID) = { - ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING), - ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL) -} static_ASN1_SEQUENCE_END(ESS_CERT_ID) - -IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID) -IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID) - -ASN1_SEQUENCE(ESS_SIGNING_CERT) = { - ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID), - ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO) -} static_ASN1_SEQUENCE_END(ESS_SIGNING_CERT) - -IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT) -IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT) - -ASN1_SEQUENCE(ESS_CERT_ID_V2) = { - ASN1_OPT(ESS_CERT_ID_V2, hash_alg, X509_ALGOR), - ASN1_SIMPLE(ESS_CERT_ID_V2, hash, ASN1_OCTET_STRING), - ASN1_OPT(ESS_CERT_ID_V2, issuer_serial, ESS_ISSUER_SERIAL) -} static_ASN1_SEQUENCE_END(ESS_CERT_ID_V2) - -IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID_V2) -IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID_V2) - -ASN1_SEQUENCE(ESS_SIGNING_CERT_V2) = { - ASN1_SEQUENCE_OF(ESS_SIGNING_CERT_V2, cert_ids, ESS_CERT_ID_V2), - ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT_V2, policy_info, POLICYINFO) -} static_ASN1_SEQUENCE_END(ESS_SIGNING_CERT_V2) - -IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT_V2) -IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT_V2) - /* Getting encapsulated TS_TST_INFO object from PKCS7. */ TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token) { @@ -252,22 +210,22 @@ TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token) const unsigned char *p; if (!PKCS7_type_is_signed(token)) { - TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); + ERR_raise(ERR_LIB_TS, TS_R_BAD_PKCS7_TYPE); return NULL; } if (PKCS7_get_detached(token)) { - TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT); + ERR_raise(ERR_LIB_TS, TS_R_DETACHED_CONTENT); return NULL; } pkcs7_signed = token->d.sign; enveloped = pkcs7_signed->contents; if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo) { - TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); + ERR_raise(ERR_LIB_TS, TS_R_BAD_PKCS7_TYPE); return NULL; } tst_info_wrapper = enveloped->d.other; if (tst_info_wrapper->type != V_ASN1_OCTET_STRING) { - TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE); + ERR_raise(ERR_LIB_TS, TS_R_BAD_TYPE); return NULL; } tst_info_der = tst_info_wrapper->value.octet_string; diff --git a/crypto/openssl/crypto/ts/ts_conf.c b/crypto/openssl/crypto/ts/ts_conf.c index 625089a59bf9..fd2ad90754b0 100644 --- a/crypto/openssl/crypto/ts/ts_conf.c +++ b/crypto/openssl/crypto/ts/ts_conf.c @@ -1,12 +1,15 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include @@ -14,6 +17,7 @@ #include #include #include +#include /* Macro definitions for the configuration file. */ #define BASE_SECTION "tsa" @@ -51,7 +55,7 @@ X509 *TS_CONF_load_cert(const char *file) x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL); end: if (x == NULL) - TSerr(TS_F_TS_CONF_LOAD_CERT, TS_R_CANNOT_LOAD_CERT); + ERR_raise(ERR_LIB_TS, TS_R_CANNOT_LOAD_CERT); BIO_free(cert); return x; } @@ -71,14 +75,19 @@ STACK_OF(X509) *TS_CONF_load_certs(const char *file) allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL); for (i = 0; i < sk_X509_INFO_num(allcerts); i++) { X509_INFO *xi = sk_X509_INFO_value(allcerts, i); - if (xi->x509) { - sk_X509_push(othercerts, xi->x509); + + if (xi->x509 != NULL) { + if (!X509_add_cert(othercerts, xi->x509, X509_ADD_FLAG_DEFAULT)) { + sk_X509_pop_free(othercerts, X509_free); + othercerts = NULL; + goto end; + } xi->x509 = NULL; } } end: if (othercerts == NULL) - TSerr(TS_F_TS_CONF_LOAD_CERTS, TS_R_CANNOT_LOAD_CERT); + ERR_raise(ERR_LIB_TS, TS_R_CANNOT_LOAD_CERT); sk_X509_INFO_pop_free(allcerts, X509_INFO_free); BIO_free(certs); return othercerts; @@ -94,7 +103,7 @@ EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass) pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *)pass); end: if (pkey == NULL) - TSerr(TS_F_TS_CONF_LOAD_KEY, TS_R_CANNOT_LOAD_KEY); + ERR_raise(ERR_LIB_TS, TS_R_CANNOT_LOAD_KEY); BIO_free(key); return pkey; } @@ -103,14 +112,12 @@ EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass) static void ts_CONF_lookup_fail(const char *name, const char *tag) { - TSerr(TS_F_TS_CONF_LOOKUP_FAIL, TS_R_VAR_LOOKUP_FAILURE); - ERR_add_error_data(3, name, "::", tag); + ERR_raise_data(ERR_LIB_TS, TS_R_VAR_LOOKUP_FAILURE, "%s::%s", name, tag); } static void ts_CONF_invalid(const char *name, const char *tag) { - TSerr(TS_F_TS_CONF_INVALID, TS_R_VAR_BAD_VALUE); - ERR_add_error_data(3, name, "::", tag); + ERR_raise_data(ERR_LIB_TS, TS_R_VAR_BAD_VALUE, "%s::%s", name, tag); } const char *TS_CONF_get_tsa_section(CONF *conf, const char *section) @@ -175,10 +182,9 @@ int TS_CONF_set_default_engine(const char *name) ret = 1; err: - if (!ret) { - TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE, TS_R_COULD_NOT_SET_ENGINE); - ERR_add_error_data(2, "engine:", name); - } + if (!ret) + ERR_raise_data(ERR_LIB_TS, TS_R_COULD_NOT_SET_ENGINE, + "engine:%s", name); ENGINE_free(e); return ret; } @@ -283,9 +289,10 @@ int TS_CONF_set_def_policy(CONF *conf, const char *section, { int ret = 0; ASN1_OBJECT *policy_obj = NULL; - if (!policy) + + if (policy == NULL) policy = NCONF_get_string(conf, section, ENV_DEFAULT_POLICY); - if (!policy) { + if (policy == NULL) { ts_CONF_lookup_fail(section, ENV_DEFAULT_POLICY); goto err; } @@ -409,7 +416,7 @@ int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx) return ret; } -int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, +int TS_CONF_set_clock_precision_digits(const CONF *conf, const char *section, TS_RESP_CTX *ctx) { int ret = 0; @@ -418,9 +425,7 @@ int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, /* * If not specified, set the default value to 0, i.e. sec precision */ - if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS, - &digits)) - digits = 0; + digits = _CONF_get_number(conf, section, ENV_CLOCK_PRECISION_DIGITS); if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS) { ts_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS); goto err; diff --git a/crypto/openssl/crypto/ts/ts_err.c b/crypto/openssl/crypto/ts/ts_err.c index 1f3854d8491e..46e89beee8a2 100644 --- a/crypto/openssl/crypto/ts/ts_err.c +++ b/crypto/openssl/crypto/ts/ts_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,105 +10,11 @@ #include #include +#include "crypto/tserr.h" -#ifndef OPENSSL_NO_ERR +#ifndef OPENSSL_NO_TS -static const ERR_STRING_DATA TS_str_functs[] = { - {ERR_PACK(ERR_LIB_TS, TS_F_DEF_SERIAL_CB, 0), "def_serial_cb"}, - {ERR_PACK(ERR_LIB_TS, TS_F_DEF_TIME_CB, 0), "def_time_cb"}, - {ERR_PACK(ERR_LIB_TS, TS_F_ESS_ADD_SIGNING_CERT, 0), - "ess_add_signing_cert"}, - {ERR_PACK(ERR_LIB_TS, TS_F_ESS_ADD_SIGNING_CERT_V2, 0), - "ess_add_signing_cert_v2"}, - {ERR_PACK(ERR_LIB_TS, TS_F_ESS_CERT_ID_NEW_INIT, 0), - "ess_CERT_ID_new_init"}, - {ERR_PACK(ERR_LIB_TS, TS_F_ESS_CERT_ID_V2_NEW_INIT, 0), - "ess_cert_id_v2_new_init"}, - {ERR_PACK(ERR_LIB_TS, TS_F_ESS_SIGNING_CERT_NEW_INIT, 0), - "ess_SIGNING_CERT_new_init"}, - {ERR_PACK(ERR_LIB_TS, TS_F_ESS_SIGNING_CERT_V2_NEW_INIT, 0), - "ess_signing_cert_v2_new_init"}, - {ERR_PACK(ERR_LIB_TS, TS_F_INT_TS_RESP_VERIFY_TOKEN, 0), - "int_ts_RESP_verify_token"}, - {ERR_PACK(ERR_LIB_TS, TS_F_PKCS7_TO_TS_TST_INFO, 0), - "PKCS7_to_TS_TST_INFO"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_ACCURACY_SET_MICROS, 0), - "TS_ACCURACY_set_micros"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_ACCURACY_SET_MILLIS, 0), - "TS_ACCURACY_set_millis"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_ACCURACY_SET_SECONDS, 0), - "TS_ACCURACY_set_seconds"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CHECK_IMPRINTS, 0), "ts_check_imprints"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CHECK_NONCES, 0), "ts_check_nonces"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CHECK_POLICY, 0), "ts_check_policy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CHECK_SIGNING_CERTS, 0), - "ts_check_signing_certs"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CHECK_STATUS_INFO, 0), - "ts_check_status_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_COMPUTE_IMPRINT, 0), "ts_compute_imprint"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_INVALID, 0), "ts_CONF_invalid"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_LOAD_CERT, 0), "TS_CONF_load_cert"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_LOAD_CERTS, 0), "TS_CONF_load_certs"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_LOAD_KEY, 0), "TS_CONF_load_key"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_LOOKUP_FAIL, 0), "ts_CONF_lookup_fail"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_CONF_SET_DEFAULT_ENGINE, 0), - "TS_CONF_set_default_engine"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_GET_STATUS_TEXT, 0), "ts_get_status_text"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_MSG_IMPRINT_SET_ALGO, 0), - "TS_MSG_IMPRINT_set_algo"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_REQ_SET_MSG_IMPRINT, 0), - "TS_REQ_set_msg_imprint"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_REQ_SET_NONCE, 0), "TS_REQ_set_nonce"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_REQ_SET_POLICY_ID, 0), - "TS_REQ_set_policy_id"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CREATE_RESPONSE, 0), - "TS_RESP_create_response"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CREATE_TST_INFO, 0), - "ts_RESP_create_tst_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, 0), - "TS_RESP_CTX_add_failure_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_ADD_MD, 0), "TS_RESP_CTX_add_md"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_ADD_POLICY, 0), - "TS_RESP_CTX_add_policy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_NEW, 0), "TS_RESP_CTX_new"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_SET_ACCURACY, 0), - "TS_RESP_CTX_set_accuracy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_SET_CERTS, 0), - "TS_RESP_CTX_set_certs"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_SET_DEF_POLICY, 0), - "TS_RESP_CTX_set_def_policy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_SET_SIGNER_CERT, 0), - "TS_RESP_CTX_set_signer_cert"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_CTX_SET_STATUS_INFO, 0), - "TS_RESP_CTX_set_status_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_GET_POLICY, 0), "ts_RESP_get_policy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, 0), - "TS_RESP_set_genTime_with_precision"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_SET_STATUS_INFO, 0), - "TS_RESP_set_status_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_SET_TST_INFO, 0), - "TS_RESP_set_tst_info"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_SIGN, 0), "ts_RESP_sign"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_RESP_VERIFY_SIGNATURE, 0), - "TS_RESP_verify_signature"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_ACCURACY, 0), - "TS_TST_INFO_set_accuracy"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_MSG_IMPRINT, 0), - "TS_TST_INFO_set_msg_imprint"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_NONCE, 0), - "TS_TST_INFO_set_nonce"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_POLICY_ID, 0), - "TS_TST_INFO_set_policy_id"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_SERIAL, 0), - "TS_TST_INFO_set_serial"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_TIME, 0), - "TS_TST_INFO_set_time"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_TST_INFO_SET_TSA, 0), "TS_TST_INFO_set_tsa"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_VERIFY, 0), ""}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_VERIFY_CERT, 0), "ts_verify_cert"}, - {ERR_PACK(ERR_LIB_TS, TS_F_TS_VERIFY_CTX_NEW, 0), "TS_VERIFY_CTX_new"}, - {0, NULL} -}; +# ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA TS_str_reasons[] = { {ERR_PACK(ERR_LIB_TS, 0, TS_R_BAD_PKCS7_TYPE), "bad pkcs7 type"}, @@ -170,15 +76,16 @@ static const ERR_STRING_DATA TS_str_reasons[] = { {0, NULL} }; -#endif +# endif -int ERR_load_TS_strings(void) +int ossl_err_load_TS_strings(void) { -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(TS_str_functs[0].error) == NULL) { - ERR_load_strings_const(TS_str_functs); +# ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(TS_str_reasons[0].error) == NULL) ERR_load_strings_const(TS_str_reasons); - } -#endif +# endif return 1; } +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/crypto/openssl/crypto/ts/ts_lib.c b/crypto/openssl/crypto/ts/ts_lib.c index bfe981364b03..5a99c9df1759 100644 --- a/crypto/openssl/crypto/ts/ts_lib.c +++ b/crypto/openssl/crypto/ts/ts_lib.c @@ -1,7 +1,7 @@ /* * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ts/ts_local.h b/crypto/openssl/crypto/ts/ts_local.h index 771784fef7c8..4dcb7af960b2 100644 --- a/crypto/openssl/crypto/ts/ts_local.h +++ b/crypto/openssl/crypto/ts/ts_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -98,67 +98,6 @@ struct TS_status_info_st { ASN1_BIT_STRING *failure_info; }; -/*- - * IssuerSerial ::= SEQUENCE { - * issuer GeneralNames, - * serialNumber CertificateSerialNumber - * } - */ -struct ESS_issuer_serial { - STACK_OF(GENERAL_NAME) *issuer; - ASN1_INTEGER *serial; -}; - -/*- - * ESSCertID ::= SEQUENCE { - * certHash Hash, - * issuerSerial IssuerSerial OPTIONAL - * } - */ -struct ESS_cert_id { - ASN1_OCTET_STRING *hash; /* Always SHA-1 digest. */ - ESS_ISSUER_SERIAL *issuer_serial; -}; - -/*- - * SigningCertificate ::= SEQUENCE { - * certs SEQUENCE OF ESSCertID, - * policies SEQUENCE OF PolicyInformation OPTIONAL - * } - */ -struct ESS_signing_cert { - STACK_OF(ESS_CERT_ID) *cert_ids; - STACK_OF(POLICYINFO) *policy_info; -}; - -/*- - * ESSCertIDv2 ::= SEQUENCE { - * hashAlgorithm AlgorithmIdentifier - * DEFAULT {algorithm id-sha256}, - * certHash Hash, - * issuerSerial IssuerSerial OPTIONAL - * } - */ - -struct ESS_cert_id_v2_st { - X509_ALGOR *hash_alg; /* Default: SHA-256 */ - ASN1_OCTET_STRING *hash; - ESS_ISSUER_SERIAL *issuer_serial; -}; - -/*- - * SigningCertificateV2 ::= SEQUENCE { - * certs SEQUENCE OF ESSCertIDv2, - * policies SEQUENCE OF PolicyInformation OPTIONAL - * } - */ - -struct ESS_signing_cert_v2_st { - STACK_OF(ESS_CERT_ID_V2) *cert_ids; - STACK_OF(POLICYINFO) *policy_info; -}; - - struct TS_resp_ctx { X509 *signer_cert; EVP_PKEY *signer_key; @@ -185,6 +124,8 @@ struct TS_resp_ctx { TS_REQ *request; TS_RESP *response; TS_TST_INFO *tst_info; + OSSL_LIB_CTX *libctx; + char *propq; }; struct TS_verify_ctx { diff --git a/crypto/openssl/crypto/ts/ts_req_print.c b/crypto/openssl/crypto/ts/ts_req_print.c index 4eba5cf0181c..968816ae2858 100644 --- a/crypto/openssl/crypto/ts/ts_req_print.c +++ b/crypto/openssl/crypto/ts/ts_req_print.c @@ -1,7 +1,7 @@ /* * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ts/ts_req_utils.c b/crypto/openssl/crypto/ts/ts_req_utils.c index a4568e3b779d..b560fc7b38a9 100644 --- a/crypto/openssl/crypto/ts/ts_req_utils.c +++ b/crypto/openssl/crypto/ts/ts_req_utils.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -32,7 +32,7 @@ int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint) return 1; new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); if (new_msg_imprint == NULL) { - TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } TS_MSG_IMPRINT_free(a->msg_imprint); @@ -53,7 +53,7 @@ int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg) return 1; new_alg = X509_ALGOR_dup(alg); if (new_alg == NULL) { - TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } X509_ALGOR_free(a->hash_algo); @@ -84,7 +84,7 @@ int TS_REQ_set_policy_id(TS_REQ *a, const ASN1_OBJECT *policy) return 1; new_policy = OBJ_dup(policy); if (new_policy == NULL) { - TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } ASN1_OBJECT_free(a->policy_id); @@ -105,7 +105,7 @@ int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce) return 1; new_nonce = ASN1_INTEGER_dup(nonce); if (new_nonce == NULL) { - TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } ASN1_INTEGER_free(a->nonce); diff --git a/crypto/openssl/crypto/ts/ts_rsp_print.c b/crypto/openssl/crypto/ts/ts_rsp_print.c index a2451aaa8d81..ca2d8a6dc154 100644 --- a/crypto/openssl/crypto/ts/ts_rsp_print.c +++ b/crypto/openssl/crypto/ts/ts_rsp_print.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ts/ts_rsp_sign.c b/crypto/openssl/crypto/ts/ts_rsp_sign.c index 342582f024b2..8937bb2d6671 100644 --- a/crypto/openssl/crypto/ts/ts_rsp_sign.c +++ b/crypto/openssl/crypto/ts/ts_rsp_sign.c @@ -1,21 +1,25 @@ /* - * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include "e_os.h" -#include "internal/cryptlib.h" #include #include #include #include +#include "internal/cryptlib.h" +#include "internal/sizes.h" +#include "crypto/ess.h" #include "ts_local.h" +DEFINE_STACK_OF_CONST(EVP_MD) + static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *); static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec); static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *); @@ -29,20 +33,7 @@ static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx, static int ts_RESP_process_extensions(TS_RESP_CTX *ctx); static int ts_RESP_sign(TS_RESP_CTX *ctx); -static ESS_SIGNING_CERT *ess_SIGNING_CERT_new_init(X509 *signcert, - STACK_OF(X509) *certs); -static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed); static int ts_TST_INFO_content_new(PKCS7 *p7); -static int ess_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc); - -static ESS_SIGNING_CERT_V2 *ess_signing_cert_v2_new_init(const EVP_MD *hash_alg, - X509 *signcert, - STACK_OF(X509) - *certs); -static ESS_CERT_ID_V2 *ess_cert_id_v2_new_init(const EVP_MD *hash_alg, - X509 *cert, int issuer_needed); -static int ess_add_signing_cert_v2(PKCS7_SIGNER_INFO *si, - ESS_SIGNING_CERT_V2 *sc); static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long, @@ -57,11 +48,10 @@ static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data) goto err; if (!ASN1_INTEGER_set(serial, 1)) goto err; - return serial; err: - TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, "Error during serial number generation."); ASN1_INTEGER_free(serial); @@ -75,7 +65,7 @@ static int def_time_cb(struct TS_resp_ctx *ctx, void *data, { struct timeval tv; if (gettimeofday(&tv, NULL) != 0) { - TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); + ERR_raise(ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR); TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, "Time is not available."); TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); @@ -94,7 +84,7 @@ static int def_time_cb(struct TS_resp_ctx *ctx, void *data, { time_t t; if (time(&t) == (time_t)-1) { - TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); + ERR_raise(ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR); TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, "Time is not available."); TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); @@ -119,17 +109,24 @@ static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, /* TS_RESP_CTX management functions. */ -TS_RESP_CTX *TS_RESP_CTX_new(void) +TS_RESP_CTX *TS_RESP_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { TS_RESP_CTX *ctx; if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return NULL; } - ctx->signer_md = EVP_sha256(); - + if (propq != NULL) { + ctx->propq = OPENSSL_strdup(propq); + if (ctx->propq == NULL) { + OPENSSL_free(ctx); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); + return NULL; + } + } + ctx->libctx = libctx; ctx->serial_cb = def_serial_cb; ctx->time_cb = def_time_cb; ctx->extension_cb = def_extension_cb; @@ -137,11 +134,17 @@ TS_RESP_CTX *TS_RESP_CTX_new(void) return ctx; } +TS_RESP_CTX *TS_RESP_CTX_new(void) +{ + return TS_RESP_CTX_new_ex(NULL, NULL); +} + void TS_RESP_CTX_free(TS_RESP_CTX *ctx) { if (!ctx) return; + OPENSSL_free(ctx->propq); X509_free(ctx->signer_cert); EVP_PKEY_free(ctx->signer_key); sk_X509_pop_free(ctx->certs, X509_free); @@ -157,8 +160,7 @@ void TS_RESP_CTX_free(TS_RESP_CTX *ctx) int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer) { if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) { - TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, - TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE); + ERR_raise(ERR_LIB_TS, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE); return 0; } X509_free(ctx->signer_cert); @@ -189,23 +191,16 @@ int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy) goto err; return 1; err: - TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs) { - sk_X509_pop_free(ctx->certs, X509_free); ctx->certs = NULL; - if (!certs) - return 1; - if ((ctx->certs = X509_chain_up_ref(certs)) == NULL) { - TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE); - return 0; - } - return 1; + return certs == NULL || (ctx->certs = X509_chain_up_ref(certs)) != NULL; } int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy) @@ -222,7 +217,7 @@ int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy) return 1; err: - TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); ASN1_OBJECT_free(copy); return 0; } @@ -237,7 +232,7 @@ int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md) return 1; err: - TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } @@ -270,7 +265,7 @@ int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, return 1; err: TS_RESP_CTX_accuracy_free(ctx); - TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } @@ -325,7 +320,7 @@ int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, ret = 1; err: if (!ret) - TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); TS_STATUS_INFO_free(si); ASN1_UTF8STRING_free(utf8_text); return ret; @@ -353,7 +348,7 @@ int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure) goto err; return 1; err: - TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } @@ -386,7 +381,7 @@ TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) ts_RESP_CTX_init(ctx); if ((ctx->response = TS_RESP_new()) == NULL) { - TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); goto end; } if ((ctx->request = d2i_TS_REQ_bio(req_bio, NULL)) == NULL) { @@ -411,7 +406,7 @@ TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) end: if (!result) { - TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR); + ERR_raise(ERR_LIB_TS, TS_R_RESPONSE_SETUP_ERROR); if (ctx->response != NULL) { if (TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, @@ -453,7 +448,7 @@ static int ts_RESP_check_request(TS_RESP_CTX *ctx) TS_REQ *request = ctx->request; TS_MSG_IMPRINT *msg_imprint; X509_ALGOR *md_alg; - int md_alg_id; + char md_alg_name[OSSL_MAX_NAME_SIZE]; const ASN1_OCTET_STRING *digest; const EVP_MD *md = NULL; int i; @@ -467,10 +462,10 @@ static int ts_RESP_check_request(TS_RESP_CTX *ctx) msg_imprint = request->msg_imprint; md_alg = msg_imprint->hash_algo; - md_alg_id = OBJ_obj2nid(md_alg->algorithm); + OBJ_obj2txt(md_alg_name, sizeof(md_alg_name), md_alg->algorithm, 0); for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) { const EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i); - if (md_alg_id == EVP_MD_type(current_md)) + if (EVP_MD_is_a(current_md, md_alg_name)) md = current_md; } if (!md) { @@ -489,7 +484,7 @@ static int ts_RESP_check_request(TS_RESP_CTX *ctx) return 0; } digest = msg_imprint->hashed_msg; - if (digest->length != EVP_MD_size(md)) { + if (digest->length != EVP_MD_get_size(md)) { TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, "Bad message digest."); TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); @@ -507,7 +502,7 @@ static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx) int i; if (ctx->default_policy == NULL) { - TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER); + ERR_raise(ERR_LIB_TS, TS_R_INVALID_NULL_POINTER); return NULL; } if (!requested || !OBJ_cmp(requested, ctx->default_policy)) @@ -519,8 +514,8 @@ static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx) if (!OBJ_cmp(requested, current)) policy = current; } - if (!policy) { - TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY); + if (policy == NULL) { + ERR_raise(ERR_LIB_TS, TS_R_UNACCEPTABLE_POLICY); TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, "Requested policy is not " "supported."); TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY); @@ -596,7 +591,7 @@ static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx, if (!result) { TS_TST_INFO_free(tst_info); tst_info = NULL; - TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR); + ERR_raise(ERR_LIB_TS, TS_R_TST_INFO_SETUP_ERROR); TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, "Error during TSTInfo " "generation."); @@ -631,6 +626,52 @@ static int ts_RESP_process_extensions(TS_RESP_CTX *ctx) } /* Functions for signing the TS_TST_INFO structure of the context. */ +static int ossl_ess_add1_signing_cert(PKCS7_SIGNER_INFO *si, + const ESS_SIGNING_CERT *sc) +{ + ASN1_STRING *seq = NULL; + int len = i2d_ESS_SIGNING_CERT(sc, NULL); + unsigned char *p, *pp = OPENSSL_malloc(len); + + if (pp == NULL) + return 0; + + p = pp; + i2d_ESS_SIGNING_CERT(sc, &p); + if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) { + ASN1_STRING_free(seq); + OPENSSL_free(pp); + return 0; + } + + OPENSSL_free(pp); + return PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificate, + V_ASN1_SEQUENCE, seq); +} + +static int ossl_ess_add1_signing_cert_v2(PKCS7_SIGNER_INFO *si, + const ESS_SIGNING_CERT_V2 *sc) +{ + ASN1_STRING *seq = NULL; + int len = i2d_ESS_SIGNING_CERT_V2(sc, NULL); + unsigned char *p, *pp = OPENSSL_malloc(len); + + if (pp == NULL) + return 0; + + p = pp; + i2d_ESS_SIGNING_CERT_V2(sc, &p); + if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) { + ASN1_STRING_free(seq); + OPENSSL_free(pp); + return 0; + } + + OPENSSL_free(pp); + return PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificateV2, + V_ASN1_SEQUENCE, seq); +} + static int ts_RESP_sign(TS_RESP_CTX *ctx) { int ret = 0; @@ -642,14 +683,15 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx) ASN1_OBJECT *oid; BIO *p7bio = NULL; int i; + EVP_MD *signer_md = NULL; if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + ERR_raise(ERR_LIB_TS, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); goto err; } - if ((p7 = PKCS7_new()) == NULL) { - TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); + if ((p7 = PKCS7_new_ex(ctx->libctx, ctx->propq)) == NULL) { + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); goto err; } if (!PKCS7_set_type(p7, NID_pkcs7_signed)) @@ -667,37 +709,46 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx) } } + if (ctx->signer_md == NULL) + signer_md = EVP_MD_fetch(ctx->libctx, "SHA256", ctx->propq); + else if (EVP_MD_get0_provider(ctx->signer_md) == NULL) + signer_md = EVP_MD_fetch(ctx->libctx, EVP_MD_get0_name(ctx->signer_md), + ctx->propq); + else + signer_md = (EVP_MD *)ctx->signer_md; + if ((si = PKCS7_add_signature(p7, ctx->signer_cert, - ctx->signer_key, ctx->signer_md)) == NULL) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR); + ctx->signer_key, signer_md)) == NULL) { + ERR_raise(ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNATURE_ERROR); goto err; } oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, oid)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR); + ERR_raise(ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR); goto err; } certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL; if (ctx->ess_cert_id_digest == NULL - || ctx->ess_cert_id_digest == EVP_sha1()) { - if ((sc = ess_SIGNING_CERT_new_init(ctx->signer_cert, certs)) == NULL) + || EVP_MD_is_a(ctx->ess_cert_id_digest, SN_sha1)) { + if ((sc = OSSL_ESS_signing_cert_new_init(ctx->signer_cert, + certs, 0)) == NULL) goto err; - if (!ess_add_signing_cert(si, sc)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR); + if (!ossl_ess_add1_signing_cert(si, sc)) { + ERR_raise(ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_ERROR); goto err; } } else { - sc2 = ess_signing_cert_v2_new_init(ctx->ess_cert_id_digest, - ctx->signer_cert, certs); + sc2 = OSSL_ESS_signing_cert_v2_new_init(ctx->ess_cert_id_digest, + ctx->signer_cert, certs, 0); if (sc2 == NULL) goto err; - if (!ess_add_signing_cert_v2(si, sc2)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR); + if (!ossl_ess_add1_signing_cert_v2(si, sc2)) { + ERR_raise(ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR); goto err; } } @@ -705,15 +756,15 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx) if (!ts_TST_INFO_content_new(p7)) goto err; if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) { - TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); goto err; } if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); + ERR_raise(ERR_LIB_TS, TS_R_TS_DATASIGN); goto err; } if (!PKCS7_dataFinal(p7, p7bio)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); + ERR_raise(ERR_LIB_TS, TS_R_TS_DATASIGN); goto err; } TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info); @@ -722,6 +773,9 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx) ret = 1; err: + if (signer_md != ctx->signer_md) + EVP_MD_free(signer_md); + if (!ret) TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, "Error during signature " @@ -733,78 +787,6 @@ static int ts_RESP_sign(TS_RESP_CTX *ctx) return ret; } -static ESS_SIGNING_CERT *ess_SIGNING_CERT_new_init(X509 *signcert, - STACK_OF(X509) *certs) -{ - ESS_CERT_ID *cid; - ESS_SIGNING_CERT *sc = NULL; - int i; - - if ((sc = ESS_SIGNING_CERT_new()) == NULL) - goto err; - if (sc->cert_ids == NULL - && (sc->cert_ids = sk_ESS_CERT_ID_new_null()) == NULL) - goto err; - - if ((cid = ess_CERT_ID_new_init(signcert, 0)) == NULL - || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) - goto err; - for (i = 0; i < sk_X509_num(certs); ++i) { - X509 *cert = sk_X509_value(certs, i); - if ((cid = ess_CERT_ID_new_init(cert, 1)) == NULL - || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) - goto err; - } - - return sc; - err: - ESS_SIGNING_CERT_free(sc); - TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE); - return NULL; -} - -static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed) -{ - ESS_CERT_ID *cid = NULL; - GENERAL_NAME *name = NULL; - unsigned char cert_sha1[SHA_DIGEST_LENGTH]; - - /* Call for side-effect of computing hash and caching extensions */ - X509_check_purpose(cert, -1, 0); - if ((cid = ESS_CERT_ID_new()) == NULL) - goto err; - if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL)) - goto err; - if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH)) - goto err; - - /* Setting the issuer/serial if requested. */ - if (issuer_needed) { - if (cid->issuer_serial == NULL - && (cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL) - goto err; - if ((name = GENERAL_NAME_new()) == NULL) - goto err; - name->type = GEN_DIRNAME; - if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL) - goto err; - if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) - goto err; - name = NULL; /* Ownership is lost. */ - ASN1_INTEGER_free(cid->issuer_serial->serial); - if (!(cid->issuer_serial->serial = - ASN1_INTEGER_dup(X509_get_serialNumber(cert)))) - goto err; - } - - return cid; - err: - GENERAL_NAME_free(name); - ESS_CERT_ID_free(cid); - TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE); - return NULL; -} - static int ts_TST_INFO_content_new(PKCS7 *p7) { PKCS7 *ret = NULL; @@ -832,159 +814,6 @@ static int ts_TST_INFO_content_new(PKCS7 *p7) return 0; } -static int ess_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc) -{ - ASN1_STRING *seq = NULL; - unsigned char *p, *pp = NULL; - int len; - - len = i2d_ESS_SIGNING_CERT(sc, NULL); - if ((pp = OPENSSL_malloc(len)) == NULL) { - TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); - goto err; - } - p = pp; - i2d_ESS_SIGNING_CERT(sc, &p); - if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) { - TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); - goto err; - } - OPENSSL_free(pp); - pp = NULL; - return PKCS7_add_signed_attribute(si, - NID_id_smime_aa_signingCertificate, - V_ASN1_SEQUENCE, seq); - err: - ASN1_STRING_free(seq); - OPENSSL_free(pp); - - return 0; -} - -static ESS_SIGNING_CERT_V2 *ess_signing_cert_v2_new_init(const EVP_MD *hash_alg, - X509 *signcert, - STACK_OF(X509) *certs) -{ - ESS_CERT_ID_V2 *cid = NULL; - ESS_SIGNING_CERT_V2 *sc = NULL; - int i; - - if ((sc = ESS_SIGNING_CERT_V2_new()) == NULL) - goto err; - if ((cid = ess_cert_id_v2_new_init(hash_alg, signcert, 0)) == NULL) - goto err; - if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid)) - goto err; - cid = NULL; - - for (i = 0; i < sk_X509_num(certs); ++i) { - X509 *cert = sk_X509_value(certs, i); - - if ((cid = ess_cert_id_v2_new_init(hash_alg, cert, 1)) == NULL) - goto err; - if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid)) - goto err; - cid = NULL; - } - - return sc; - err: - ESS_SIGNING_CERT_V2_free(sc); - ESS_CERT_ID_V2_free(cid); - TSerr(TS_F_ESS_SIGNING_CERT_V2_NEW_INIT, ERR_R_MALLOC_FAILURE); - return NULL; -} - -static ESS_CERT_ID_V2 *ess_cert_id_v2_new_init(const EVP_MD *hash_alg, - X509 *cert, int issuer_needed) -{ - ESS_CERT_ID_V2 *cid = NULL; - GENERAL_NAME *name = NULL; - unsigned char hash[EVP_MAX_MD_SIZE]; - unsigned int hash_len = sizeof(hash); - X509_ALGOR *alg = NULL; - - memset(hash, 0, sizeof(hash)); - - if ((cid = ESS_CERT_ID_V2_new()) == NULL) - goto err; - - if (hash_alg != EVP_sha256()) { - alg = X509_ALGOR_new(); - if (alg == NULL) - goto err; - X509_ALGOR_set_md(alg, hash_alg); - if (alg->algorithm == NULL) - goto err; - cid->hash_alg = alg; - alg = NULL; - } else { - cid->hash_alg = NULL; - } - - if (!X509_digest(cert, hash_alg, hash, &hash_len)) - goto err; - - if (!ASN1_OCTET_STRING_set(cid->hash, hash, hash_len)) - goto err; - - if (issuer_needed) { - if ((cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL) - goto err; - if ((name = GENERAL_NAME_new()) == NULL) - goto err; - name->type = GEN_DIRNAME; - if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL) - goto err; - if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) - goto err; - name = NULL; /* Ownership is lost. */ - ASN1_INTEGER_free(cid->issuer_serial->serial); - cid->issuer_serial->serial = - ASN1_INTEGER_dup(X509_get_serialNumber(cert)); - if (cid->issuer_serial->serial == NULL) - goto err; - } - - return cid; - err: - X509_ALGOR_free(alg); - GENERAL_NAME_free(name); - ESS_CERT_ID_V2_free(cid); - TSerr(TS_F_ESS_CERT_ID_V2_NEW_INIT, ERR_R_MALLOC_FAILURE); - return NULL; -} - -static int ess_add_signing_cert_v2(PKCS7_SIGNER_INFO *si, - ESS_SIGNING_CERT_V2 *sc) -{ - ASN1_STRING *seq = NULL; - unsigned char *p, *pp = NULL; - int len = i2d_ESS_SIGNING_CERT_V2(sc, NULL); - - if ((pp = OPENSSL_malloc(len)) == NULL) { - TSerr(TS_F_ESS_ADD_SIGNING_CERT_V2, ERR_R_MALLOC_FAILURE); - goto err; - } - - p = pp; - i2d_ESS_SIGNING_CERT_V2(sc, &p); - if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) { - TSerr(TS_F_ESS_ADD_SIGNING_CERT_V2, ERR_R_MALLOC_FAILURE); - goto err; - } - - OPENSSL_free(pp); - pp = NULL; - return PKCS7_add_signed_attribute(si, - NID_id_smime_aa_signingCertificateV2, - V_ASN1_SEQUENCE, seq); - err: - ASN1_STRING_free(seq); - OPENSSL_free(pp); - return 0; -} - static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision( ASN1_GENERALIZEDTIME *asn1_time, long sec, long usec, unsigned precision) @@ -1049,7 +878,7 @@ static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision( return asn1_time; err: - TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME); + ERR_raise(ERR_LIB_TS, TS_R_COULD_NOT_SET_TIME); return NULL; } diff --git a/crypto/openssl/crypto/ts/ts_rsp_utils.c b/crypto/openssl/crypto/ts/ts_rsp_utils.c index 3fa0dbd0f09e..cae076f21a6a 100644 --- a/crypto/openssl/crypto/ts/ts_rsp_utils.c +++ b/crypto/openssl/crypto/ts/ts_rsp_utils.c @@ -1,7 +1,7 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -22,7 +22,7 @@ int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info) return 1; new_status_info = TS_STATUS_INFO_dup(status_info); if (new_status_info == NULL) { - TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } TS_STATUS_INFO_free(a->status_info); @@ -73,7 +73,7 @@ int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy) return 1; new_policy = OBJ_dup(policy); if (new_policy == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } ASN1_OBJECT_free(a->policy_id); @@ -94,7 +94,7 @@ int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint) return 1; new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); if (new_msg_imprint == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } TS_MSG_IMPRINT_free(a->msg_imprint); @@ -115,7 +115,7 @@ int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial) return 1; new_serial = ASN1_INTEGER_dup(serial); if (new_serial == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } ASN1_INTEGER_free(a->serial); @@ -136,7 +136,7 @@ int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime) return 1; new_time = ASN1_STRING_dup(gtime); if (new_time == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } ASN1_GENERALIZEDTIME_free(a->time); @@ -157,7 +157,7 @@ int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy) return 1; new_accuracy = TS_ACCURACY_dup(accuracy); if (new_accuracy == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } TS_ACCURACY_free(a->accuracy); @@ -178,7 +178,7 @@ int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds) return 1; new_seconds = ASN1_INTEGER_dup(seconds); if (new_seconds == NULL) { - TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } ASN1_INTEGER_free(a->seconds); @@ -200,7 +200,7 @@ int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis) if (millis != NULL) { new_millis = ASN1_INTEGER_dup(millis); if (new_millis == NULL) { - TSerr(TS_F_TS_ACCURACY_SET_MILLIS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } } @@ -223,7 +223,7 @@ int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros) if (micros != NULL) { new_micros = ASN1_INTEGER_dup(micros); if (new_micros == NULL) { - TSerr(TS_F_TS_ACCURACY_SET_MICROS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } } @@ -256,7 +256,7 @@ int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce) return 1; new_nonce = ASN1_INTEGER_dup(nonce); if (new_nonce == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } ASN1_INTEGER_free(a->nonce); @@ -277,7 +277,7 @@ int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa) return 1; new_tsa = GENERAL_NAME_dup(tsa); if (new_tsa == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return 0; } GENERAL_NAME_free(a->tsa); diff --git a/crypto/openssl/crypto/ts/ts_rsp_verify.c b/crypto/openssl/crypto/ts/ts_rsp_verify.c index 7fe3d27e74a2..792a27ce572b 100644 --- a/crypto/openssl/crypto/ts/ts_rsp_verify.c +++ b/crypto/openssl/crypto/ts/ts_rsp_verify.c @@ -1,26 +1,26 @@ /* * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include -#include "internal/cryptlib.h" #include #include #include +#include "internal/cryptlib.h" +#include "internal/sizes.h" +#include "crypto/ess.h" #include "ts_local.h" static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, X509 *signer, STACK_OF(X509) **chain); -static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si, - STACK_OF(X509) *chain); -static ESS_SIGNING_CERT *ess_get_signing_cert(PKCS7_SIGNER_INFO *si); -static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); -static int ts_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert); +static int ts_check_signing_certs(const PKCS7_SIGNER_INFO *si, + const STACK_OF(X509) *chain); + static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token, TS_TST_INFO *tst_info); static int ts_check_status_info(TS_RESP *response); @@ -37,8 +37,6 @@ static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info); static int ts_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer); static int ts_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name); -static int ts_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert); -static ESS_SIGNING_CERT_V2 *ess_get_signing_cert_v2(PKCS7_SIGNER_INFO *si); /* * This must be large enough to hold all values in ts_status_text (with @@ -92,6 +90,7 @@ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, { STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; PKCS7_SIGNER_INFO *si; + STACK_OF(X509) *untrusted = NULL; STACK_OF(X509) *signers = NULL; X509 *signer; STACK_OF(X509) *chain = NULL; @@ -101,21 +100,21 @@ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, /* Some sanity checks first. */ if (!token) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER); + ERR_raise(ERR_LIB_TS, TS_R_INVALID_NULL_POINTER); goto err; } if (!PKCS7_type_is_signed(token)) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE); + ERR_raise(ERR_LIB_TS, TS_R_WRONG_CONTENT_TYPE); goto err; } sinfos = PKCS7_get_signer_info(token); if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_THERE_MUST_BE_ONE_SIGNER); + ERR_raise(ERR_LIB_TS, TS_R_THERE_MUST_BE_ONE_SIGNER); goto err; } si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0); if (PKCS7_get_detached(token)) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT); + ERR_raise(ERR_LIB_TS, TS_R_NO_CONTENT); goto err; } @@ -128,7 +127,13 @@ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, goto err; signer = sk_X509_value(signers, 0); - if (!ts_verify_cert(store, certs, signer, &chain)) + untrusted = sk_X509_new_reserve(NULL, sk_X509_num(certs) + + sk_X509_num(token->d.sign->cert)); + if (untrusted == NULL + || !X509_add_certs(untrusted, certs, 0) + || !X509_add_certs(untrusted, token->d.sign->cert, 0)) + goto err; + if (!ts_verify_cert(store, untrusted, signer, &chain)) goto err; if (!ts_check_signing_certs(si, chain)) goto err; @@ -140,7 +145,7 @@ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, j = PKCS7_signatureVerify(p7bio, token, si, signer); if (j <= 0) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE); + ERR_raise(ERR_LIB_TS, TS_R_SIGNATURE_FAILURE); goto err; } @@ -152,6 +157,7 @@ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, err: BIO_free_all(p7bio); + sk_X509_free(untrusted); sk_X509_pop_free(chain, X509_free); sk_X509_free(signers); @@ -172,7 +178,7 @@ static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, *chain = NULL; cert_ctx = X509_STORE_CTX_new(); if (cert_ctx == NULL) { - TSerr(TS_F_TS_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); goto err; } if (!X509_STORE_CTX_init(cert_ctx, store, signer, untrusted)) @@ -181,9 +187,8 @@ static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, i = X509_verify_cert(cert_ctx); if (i <= 0) { int j = X509_STORE_CTX_get_error(cert_ctx); - TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(j)); + ERR_raise_data(ERR_LIB_TS, TS_R_CERTIFICATE_VERIFY_ERROR, + "Verify error:%s", X509_verify_cert_error_string(j)); goto err; } *chain = X509_STORE_CTX_get1_chain(cert_ctx); @@ -198,77 +203,20 @@ static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, return ret; } -static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si, - STACK_OF(X509) *chain) -{ - ESS_SIGNING_CERT *ss = ess_get_signing_cert(si); - STACK_OF(ESS_CERT_ID) *cert_ids = NULL; - ESS_SIGNING_CERT_V2 *ssv2 = ess_get_signing_cert_v2(si); - STACK_OF(ESS_CERT_ID_V2) *cert_ids_v2 = NULL; - X509 *cert; - int i = 0; - int ret = 0; - - if (ss != NULL) { - cert_ids = ss->cert_ids; - cert = sk_X509_value(chain, 0); - if (ts_find_cert(cert_ids, cert) != 0) - goto err; - - /* - * Check the other certificates of the chain if there are more than one - * certificate ids in cert_ids. - */ - if (sk_ESS_CERT_ID_num(cert_ids) > 1) { - for (i = 1; i < sk_X509_num(chain); ++i) { - cert = sk_X509_value(chain, i); - if (ts_find_cert(cert_ids, cert) < 0) - goto err; - } - } - } else if (ssv2 != NULL) { - cert_ids_v2 = ssv2->cert_ids; - cert = sk_X509_value(chain, 0); - if (ts_find_cert_v2(cert_ids_v2, cert) != 0) - goto err; - - /* - * Check the other certificates of the chain if there are more than one - * certificate ids in cert_ids. - */ - if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) { - for (i = 1; i < sk_X509_num(chain); ++i) { - cert = sk_X509_value(chain, i); - if (ts_find_cert_v2(cert_ids_v2, cert) < 0) - goto err; - } - } - } else { - goto err; - } - - ret = 1; - err: - if (!ret) - TSerr(TS_F_TS_CHECK_SIGNING_CERTS, - TS_R_ESS_SIGNING_CERTIFICATE_ERROR); - ESS_SIGNING_CERT_free(ss); - ESS_SIGNING_CERT_V2_free(ssv2); - return ret; -} - -static ESS_SIGNING_CERT *ess_get_signing_cert(PKCS7_SIGNER_INFO *si) +static ESS_SIGNING_CERT *ossl_ess_get_signing_cert(const PKCS7_SIGNER_INFO *si) { ASN1_TYPE *attr; const unsigned char *p; + attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate); - if (!attr) + if (attr == NULL) return NULL; p = attr->value.sequence->data; return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); } -static ESS_SIGNING_CERT_V2 *ess_get_signing_cert_v2(PKCS7_SIGNER_INFO *si) +static +ESS_SIGNING_CERT_V2 *ossl_ess_get_signing_cert_v2(const PKCS7_SIGNER_INFO *si) { ASN1_TYPE *attr; const unsigned char *p; @@ -280,85 +228,16 @@ static ESS_SIGNING_CERT_V2 *ess_get_signing_cert_v2(PKCS7_SIGNER_INFO *si) return d2i_ESS_SIGNING_CERT_V2(NULL, &p, attr->value.sequence->length); } -/* Returns < 0 if certificate is not found, certificate index otherwise. */ -static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) +static int ts_check_signing_certs(const PKCS7_SIGNER_INFO *si, + const STACK_OF(X509) *chain) { - int i; - unsigned char cert_sha1[SHA_DIGEST_LENGTH]; - - if (!cert_ids || !cert) - return -1; + ESS_SIGNING_CERT *ss = ossl_ess_get_signing_cert(si); + ESS_SIGNING_CERT_V2 *ssv2 = ossl_ess_get_signing_cert_v2(si); + int ret = OSSL_ESS_check_signing_certs(ss, ssv2, chain, 1) > 0; - /* Recompute SHA1 hash of certificate if necessary (side effect). */ - X509_check_purpose(cert, -1, 0); - - if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL)) - return -1; - - /* Look for cert in the cert_ids vector. */ - for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) { - ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); - - if (cid->hash->length == SHA_DIGEST_LENGTH - && memcmp(cid->hash->data, cert_sha1, SHA_DIGEST_LENGTH) == 0) { - ESS_ISSUER_SERIAL *is = cid->issuer_serial; - if (!is || !ts_issuer_serial_cmp(is, cert)) - return i; - } - } - - return -1; -} - -/* Returns < 0 if certificate is not found, certificate index otherwise. */ -static int ts_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert) -{ - int i; - unsigned char cert_digest[EVP_MAX_MD_SIZE]; - unsigned int len; - - /* Look for cert in the cert_ids vector. */ - for (i = 0; i < sk_ESS_CERT_ID_V2_num(cert_ids); ++i) { - ESS_CERT_ID_V2 *cid = sk_ESS_CERT_ID_V2_value(cert_ids, i); - const EVP_MD *md; - - if (cid->hash_alg != NULL) - md = EVP_get_digestbyobj(cid->hash_alg->algorithm); - else - md = EVP_sha256(); - - if (!X509_digest(cert, md, cert_digest, &len)) - return -1; - if (cid->hash->length != (int)len) - return -1; - - if (memcmp(cid->hash->data, cert_digest, cid->hash->length) == 0) { - ESS_ISSUER_SERIAL *is = cid->issuer_serial; - - if (is == NULL || !ts_issuer_serial_cmp(is, cert)) - return i; - } - } - - return -1; -} - -static int ts_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert) -{ - GENERAL_NAME *issuer; - - if (!is || !cert || sk_GENERAL_NAME_num(is->issuer) != 1) - return -1; - - issuer = sk_GENERAL_NAME_value(is->issuer, 0); - if (issuer->type != GEN_DIRNAME - || X509_NAME_cmp(issuer->d.dirn, X509_get_issuer_name(cert))) - return -1; - - if (ASN1_INTEGER_cmp(is->serial, X509_get_serialNumber(cert))) - return -1; - - return 0; + ESS_SIGNING_CERT_free(ss); + ESS_SIGNING_CERT_V2_free(ssv2); + return ret; } /*- @@ -432,7 +311,7 @@ static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx, goto err; if ((flags & TS_VFY_VERSION) && TS_TST_INFO_get_version(tst_info) != 1) { - TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION); + ERR_raise(ERR_LIB_TS, TS_R_UNSUPPORTED_VERSION); goto err; } if ((flags & TS_VFY_POLICY) @@ -452,12 +331,12 @@ static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx, goto err; if ((flags & TS_VFY_SIGNER) && tsa_name && !ts_check_signer_name(tsa_name, signer)) { - TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH); + ERR_raise(ERR_LIB_TS, TS_R_TSA_NAME_MISMATCH); goto err; } if ((flags & TS_VFY_TSA_NAME) && !ts_check_signer_name(ctx->tsa_name, signer)) { - TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED); + ERR_raise(ERR_LIB_TS, TS_R_TSA_UNTRUSTED); goto err; } ret = 1; @@ -508,12 +387,11 @@ static int ts_check_status_info(TS_RESP *response) if (failure_text[0] == '\0') strcpy(failure_text, "unspecified"); - TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN); - ERR_add_error_data(6, - "status code: ", status_text, - ", status text: ", embedded_status_text ? - embedded_status_text : "unspecified", - ", failure codes: ", failure_text); + ERR_raise_data(ERR_LIB_TS, TS_R_NO_TIME_STAMP_TOKEN, + "status code: %s, status text: %s, failure codes: %s", + status_text, + embedded_status_text ? embedded_status_text : "unspecified", + failure_text); OPENSSL_free(embedded_status_text); return 0; @@ -521,34 +399,7 @@ static int ts_check_status_info(TS_RESP *response) static char *ts_get_status_text(STACK_OF(ASN1_UTF8STRING) *text) { - int i; - int length = 0; - char *result = NULL; - char *p; - - for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) { - ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); - if (ASN1_STRING_length(current) > TS_MAX_STATUS_LENGTH - length - 1) - return NULL; - length += ASN1_STRING_length(current); - length += 1; /* separator character */ - } - if ((result = OPENSSL_malloc(length)) == NULL) { - TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE); - return NULL; - } - - for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) { - ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); - length = ASN1_STRING_length(current); - if (i > 0) - *p++ = '/'; - strncpy(p, (const char *)ASN1_STRING_get0_data(current), length); - p += length; - } - *p = '\0'; - - return result; + return ossl_sk_ASN1_UTF8STRING2text(text, "/", TS_MAX_STATUS_LENGTH); } static int ts_check_policy(const ASN1_OBJECT *req_oid, @@ -557,7 +408,7 @@ static int ts_check_policy(const ASN1_OBJECT *req_oid, const ASN1_OBJECT *resp_oid = tst_info->policy_id; if (OBJ_cmp(req_oid, resp_oid) != 0) { - TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH); + ERR_raise(ERR_LIB_TS, TS_R_POLICY_MISMATCH); return 0; } @@ -570,9 +421,10 @@ static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info, { TS_MSG_IMPRINT *msg_imprint = tst_info->msg_imprint; X509_ALGOR *md_alg_resp = msg_imprint->hash_algo; - const EVP_MD *md; + EVP_MD *md = NULL; EVP_MD_CTX *md_ctx = NULL; unsigned char buffer[4096]; + char name[OSSL_MAX_NAME_SIZE]; int length; *md_alg = NULL; @@ -580,26 +432,39 @@ static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info, if ((*md_alg = X509_ALGOR_dup(md_alg_resp)) == NULL) goto err; - if ((md = EVP_get_digestbyobj((*md_alg)->algorithm)) == NULL) { - TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM); + + OBJ_obj2txt(name, sizeof(name), md_alg_resp->algorithm, 0); + + (void)ERR_set_mark(); + md = EVP_MD_fetch(NULL, name, NULL); + + if (md == NULL) + md = (EVP_MD *)EVP_get_digestbyname(name); + + if (md == NULL) { + (void)ERR_clear_last_mark(); goto err; } - length = EVP_MD_size(md); + (void)ERR_pop_to_mark(); + + length = EVP_MD_get_size(md); if (length < 0) goto err; *imprint_len = length; if ((*imprint = OPENSSL_malloc(*imprint_len)) == NULL) { - TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); goto err; } md_ctx = EVP_MD_CTX_new(); if (md_ctx == NULL) { - TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_DigestInit(md_ctx, md)) goto err; + EVP_MD_free(md); + md = NULL; while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) { if (!EVP_DigestUpdate(md_ctx, buffer, length)) goto err; @@ -611,6 +476,7 @@ static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info, return 1; err: EVP_MD_CTX_free(md_ctx); + EVP_MD_free(md); X509_ALGOR_free(*md_alg); *md_alg = NULL; OPENSSL_free(*imprint); @@ -643,7 +509,7 @@ static int ts_check_imprints(X509_ALGOR *algor_a, memcmp(imprint_a, ASN1_STRING_get0_data(b->hashed_msg), len_a) == 0; err: if (!ret) - TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH); + ERR_raise(ERR_LIB_TS, TS_R_MESSAGE_IMPRINT_MISMATCH); return ret; } @@ -652,13 +518,13 @@ static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info) const ASN1_INTEGER *b = tst_info->nonce; if (!b) { - TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED); + ERR_raise(ERR_LIB_TS, TS_R_NONCE_NOT_RETURNED); return 0; } /* No error if a nonce is returned without being requested. */ if (ASN1_INTEGER_cmp(a, b) != 0) { - TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH); + ERR_raise(ERR_LIB_TS, TS_R_NONCE_MISMATCH); return 0; } diff --git a/crypto/openssl/crypto/ts/ts_verify_ctx.c b/crypto/openssl/crypto/ts/ts_verify_ctx.c index b504649a415f..2f6f00c0ccd6 100644 --- a/crypto/openssl/crypto/ts/ts_verify_ctx.c +++ b/crypto/openssl/crypto/ts/ts_verify_ctx.c @@ -1,7 +1,7 @@ /* * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -17,7 +17,7 @@ TS_VERIFY_CTX *TS_VERIFY_CTX_new(void) TS_VERIFY_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx == NULL) - TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE); return ctx; } @@ -60,7 +60,7 @@ X509_STORE *TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *s) return ctx->store; } -STACK_OF(X509) *TS_VERIFY_CTS_set_certs(TS_VERIFY_CTX *ctx, +STACK_OF(X509) *TS_VERIFY_CTX_set_certs(TS_VERIFY_CTX *ctx, STACK_OF(X509) *certs) { ctx->certs = certs; diff --git a/crypto/openssl/crypto/txt_db/txt_db.c b/crypto/openssl/crypto/txt_db/txt_db.c index cbb81905ac81..2c1cbfb4f129 100644 --- a/crypto/openssl/crypto/txt_db/txt_db.c +++ b/crypto/openssl/crypto/txt_db/txt_db.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ui/ui_err.c b/crypto/openssl/crypto/ui/ui_err.c index b806872c30bd..9b9c12133270 100644 --- a/crypto/openssl/crypto/ui/ui_err.c +++ b/crypto/openssl/crypto/ui/ui_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,39 +10,10 @@ #include #include +#include "crypto/uierr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA UI_str_functs[] = { - {ERR_PACK(ERR_LIB_UI, UI_F_CLOSE_CONSOLE, 0), "close_console"}, - {ERR_PACK(ERR_LIB_UI, UI_F_ECHO_CONSOLE, 0), "echo_console"}, - {ERR_PACK(ERR_LIB_UI, UI_F_GENERAL_ALLOCATE_BOOLEAN, 0), - "general_allocate_boolean"}, - {ERR_PACK(ERR_LIB_UI, UI_F_GENERAL_ALLOCATE_PROMPT, 0), - "general_allocate_prompt"}, - {ERR_PACK(ERR_LIB_UI, UI_F_NOECHO_CONSOLE, 0), "noecho_console"}, - {ERR_PACK(ERR_LIB_UI, UI_F_OPEN_CONSOLE, 0), "open_console"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_CONSTRUCT_PROMPT, 0), "UI_construct_prompt"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_CREATE_METHOD, 0), "UI_create_method"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_CTRL, 0), "UI_ctrl"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_ERROR_STRING, 0), "UI_dup_error_string"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_INFO_STRING, 0), "UI_dup_info_string"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_INPUT_BOOLEAN, 0), - "UI_dup_input_boolean"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_INPUT_STRING, 0), "UI_dup_input_string"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_USER_DATA, 0), "UI_dup_user_data"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_DUP_VERIFY_STRING, 0), - "UI_dup_verify_string"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_GET0_RESULT, 0), "UI_get0_result"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_GET_RESULT_LENGTH, 0), - "UI_get_result_length"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_NEW_METHOD, 0), "UI_new_method"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_PROCESS, 0), "UI_process"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_SET_RESULT, 0), "UI_set_result"}, - {ERR_PACK(ERR_LIB_UI, UI_F_UI_SET_RESULT_EX, 0), "UI_set_result_ex"}, - {0, NULL} -}; - static const ERR_STRING_DATA UI_str_reasons[] = { {ERR_PACK(ERR_LIB_UI, 0, UI_R_COMMON_OK_AND_CANCEL_CHARACTERS), "common ok and cancel characters"}, @@ -66,13 +37,11 @@ static const ERR_STRING_DATA UI_str_reasons[] = { #endif -int ERR_load_UI_strings(void) +int ossl_err_load_UI_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(UI_str_functs[0].error) == NULL) { - ERR_load_strings_const(UI_str_functs); + if (ERR_reason_error_string(UI_str_reasons[0].error) == NULL) ERR_load_strings_const(UI_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/ui/ui_lib.c b/crypto/openssl/crypto/ui/ui_lib.c index 49cc45057c4c..1ff8c6fa35f3 100644 --- a/crypto/openssl/crypto/ui/ui_lib.c +++ b/crypto/openssl/crypto/ui/ui_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -25,13 +25,13 @@ UI *UI_new_method(const UI_METHOD *method) UI *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); return NULL; } ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } @@ -43,7 +43,7 @@ UI *UI_new_method(const UI_METHOD *method) ret->meth = method; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data)) { - OPENSSL_free(ret); + UI_free(ret); return NULL; } return ret; @@ -102,11 +102,11 @@ static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt, UI_STRING *ret = NULL; if (prompt == NULL) { - UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_UI, ERR_R_PASSED_NULL_PARAMETER); } else if ((type == UIT_PROMPT || type == UIT_VERIFY || type == UIT_BOOLEAN) && result_buf == NULL) { - UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, UI_R_NO_RESULT_BUFFER); - } else if ((ret = OPENSSL_malloc(sizeof(*ret))) != NULL) { + ERR_raise(ERR_LIB_UI, UI_R_NO_RESULT_BUFFER); + } else if ((ret = OPENSSL_zalloc(sizeof(*ret))) != NULL) { ret->out_string = prompt; ret->flags = prompt_freeable ? OUT_STRING_FREEABLE : 0; ret->input_flags = input_flags; @@ -157,14 +157,13 @@ static int general_allocate_boolean(UI *ui, const char *p; if (ok_chars == NULL) { - UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_UI, ERR_R_PASSED_NULL_PARAMETER); } else if (cancel_chars == NULL) { - UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_UI, ERR_R_PASSED_NULL_PARAMETER); } else { for (p = ok_chars; *p != '\0'; p++) { if (strchr(cancel_chars, *p) != NULL) { - UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, - UI_R_COMMON_OK_AND_CANCEL_CHARACTERS); + ERR_raise(ERR_LIB_UI, UI_R_COMMON_OK_AND_CANCEL_CHARACTERS); } } @@ -212,7 +211,7 @@ int UI_dup_input_string(UI *ui, const char *prompt, int flags, if (prompt != NULL) { prompt_copy = OPENSSL_strdup(prompt); if (prompt_copy == NULL) { - UIerr(UI_F_UI_DUP_INPUT_STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); return 0; } } @@ -240,7 +239,7 @@ int UI_dup_verify_string(UI *ui, const char *prompt, int flags, if (prompt != NULL) { prompt_copy = OPENSSL_strdup(prompt); if (prompt_copy == NULL) { - UIerr(UI_F_UI_DUP_VERIFY_STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); return -1; } } @@ -271,7 +270,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, if (prompt != NULL) { prompt_copy = OPENSSL_strdup(prompt); if (prompt_copy == NULL) { - UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); goto err; } } @@ -279,7 +278,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, if (action_desc != NULL) { action_desc_copy = OPENSSL_strdup(action_desc); if (action_desc_copy == NULL) { - UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); goto err; } } @@ -287,7 +286,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, if (ok_chars != NULL) { ok_chars_copy = OPENSSL_strdup(ok_chars); if (ok_chars_copy == NULL) { - UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); goto err; } } @@ -295,7 +294,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, if (cancel_chars != NULL) { cancel_chars_copy = OPENSSL_strdup(cancel_chars); if (cancel_chars_copy == NULL) { - UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); goto err; } } @@ -324,7 +323,7 @@ int UI_dup_info_string(UI *ui, const char *text) if (text != NULL) { text_copy = OPENSSL_strdup(text); if (text_copy == NULL) { - UIerr(UI_F_UI_DUP_INFO_STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); return -1; } } @@ -346,7 +345,7 @@ int UI_dup_error_string(UI *ui, const char *text) if (text != NULL) { text_copy = OPENSSL_strdup(text); if (text_copy == NULL) { - UIerr(UI_F_UI_DUP_ERROR_STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); return -1; } } @@ -354,32 +353,32 @@ int UI_dup_error_string(UI *ui, const char *text) 0, 0, NULL); } -char *UI_construct_prompt(UI *ui, const char *object_desc, +char *UI_construct_prompt(UI *ui, const char *phrase_desc, const char *object_name) { char *prompt = NULL; - if (ui->meth->ui_construct_prompt != NULL) - prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name); + if (ui != NULL && ui->meth != NULL && ui->meth->ui_construct_prompt != NULL) + prompt = ui->meth->ui_construct_prompt(ui, phrase_desc, object_name); else { char prompt1[] = "Enter "; char prompt2[] = " for "; char prompt3[] = ":"; int len = 0; - if (object_desc == NULL) + if (phrase_desc == NULL) return NULL; - len = sizeof(prompt1) - 1 + strlen(object_desc); + len = sizeof(prompt1) - 1 + strlen(phrase_desc); if (object_name != NULL) len += sizeof(prompt2) - 1 + strlen(object_name); len += sizeof(prompt3) - 1; if ((prompt = OPENSSL_malloc(len + 1)) == NULL) { - UIerr(UI_F_UI_CONSTRUCT_PROMPT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_strlcpy(prompt, prompt1, len + 1); - OPENSSL_strlcat(prompt, object_desc, len + 1); + OPENSSL_strlcat(prompt, phrase_desc, len + 1); if (object_name != NULL) { OPENSSL_strlcat(prompt, prompt2, len + 1); OPENSSL_strlcat(prompt, object_name, len + 1); @@ -408,13 +407,13 @@ int UI_dup_user_data(UI *ui, void *user_data) if (ui->meth->ui_duplicate_data == NULL || ui->meth->ui_destroy_data == NULL) { - UIerr(UI_F_UI_DUP_USER_DATA, UI_R_USER_DATA_DUPLICATION_UNSUPPORTED); + ERR_raise(ERR_LIB_UI, UI_R_USER_DATA_DUPLICATION_UNSUPPORTED); return -1; } duplicate = ui->meth->ui_duplicate_data(ui, user_data); if (duplicate == NULL) { - UIerr(UI_F_UI_DUP_USER_DATA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); return -1; } @@ -432,11 +431,11 @@ void *UI_get0_user_data(UI *ui) const char *UI_get0_result(UI *ui, int i) { if (i < 0) { - UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_SMALL); + ERR_raise(ERR_LIB_UI, UI_R_INDEX_TOO_SMALL); return NULL; } if (i >= sk_UI_STRING_num(ui->strings)) { - UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_LARGE); + ERR_raise(ERR_LIB_UI, UI_R_INDEX_TOO_LARGE); return NULL; } return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i)); @@ -445,11 +444,11 @@ const char *UI_get0_result(UI *ui, int i) int UI_get_result_length(UI *ui, int i) { if (i < 0) { - UIerr(UI_F_UI_GET_RESULT_LENGTH, UI_R_INDEX_TOO_SMALL); + ERR_raise(ERR_LIB_UI, UI_R_INDEX_TOO_SMALL); return -1; } if (i >= sk_UI_STRING_num(ui->strings)) { - UIerr(UI_F_UI_GET_RESULT_LENGTH, UI_R_INDEX_TOO_LARGE); + ERR_raise(ERR_LIB_UI, UI_R_INDEX_TOO_LARGE); return -1; } return UI_get_result_string_length(sk_UI_STRING_value(ui->strings, i)); @@ -541,17 +540,15 @@ int UI_process(UI *ui) ok = -1; } - if (ok == -1) { - UIerr(UI_F_UI_PROCESS, UI_R_PROCESSING_ERROR); - ERR_add_error_data(2, "while ", state); - } + if (ok == -1) + ERR_raise_data(ERR_LIB_UI, UI_R_PROCESSING_ERROR, "while %s", state); return ok; } int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)) { if (ui == NULL) { - UIerr(UI_F_UI_CTRL, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_UI, ERR_R_PASSED_NULL_PARAMETER); return -1; } switch (cmd) { @@ -569,7 +566,7 @@ int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)) default: break; } - UIerr(UI_F_UI_CTRL, UI_R_UNKNOWN_CONTROL_COMMAND); + ERR_raise(ERR_LIB_UI, UI_R_UNKNOWN_CONTROL_COMMAND); return -1; } @@ -578,7 +575,7 @@ int UI_set_ex_data(UI *r, int idx, void *arg) return CRYPTO_set_ex_data(&r->ex_data, idx, arg); } -void *UI_get_ex_data(UI *r, int idx) +void *UI_get_ex_data(const UI *r, int idx) { return CRYPTO_get_ex_data(&r->ex_data, idx); } @@ -605,7 +602,7 @@ UI_METHOD *UI_create_method(const char *name) if (ui_method) OPENSSL_free(ui_method->name); OPENSSL_free(ui_method); - UIerr(UI_F_UI_CREATE_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); return NULL; } return ui_method; @@ -688,10 +685,8 @@ int UI_method_set_data_duplicator(UI_METHOD *method, int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor) (UI *ui, - const char - *object_desc, - const char - *object_name)) + const char *, + const char *)) { if (method != NULL) { method->ui_construct_prompt = prompt_constructor; @@ -874,13 +869,6 @@ int UI_get_result_maxsize(UI_STRING *uis) int UI_set_result(UI *ui, UI_STRING *uis, const char *result) { -#if 0 - /* - * This is placed here solely to preserve UI_F_UI_SET_RESULT - * To be removed for OpenSSL 1.2.0 - */ - UIerr(UI_F_UI_SET_RESULT, ERR_R_DISABLED); -#endif return UI_set_result_ex(ui, uis, result, strlen(result)); } @@ -891,33 +879,25 @@ int UI_set_result_ex(UI *ui, UI_STRING *uis, const char *result, int len) switch (uis->type) { case UIT_PROMPT: case UIT_VERIFY: - { - char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize) + 1]; - char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize) + 1]; - - BIO_snprintf(number1, sizeof(number1), "%d", - uis->_.string_data.result_minsize); - BIO_snprintf(number2, sizeof(number2), "%d", - uis->_.string_data.result_maxsize); - - if (len < uis->_.string_data.result_minsize) { - ui->flags |= UI_FLAG_REDOABLE; - UIerr(UI_F_UI_SET_RESULT_EX, UI_R_RESULT_TOO_SMALL); - ERR_add_error_data(5, "You must type in ", - number1, " to ", number2, " characters"); - return -1; - } - if (len > uis->_.string_data.result_maxsize) { - ui->flags |= UI_FLAG_REDOABLE; - UIerr(UI_F_UI_SET_RESULT_EX, UI_R_RESULT_TOO_LARGE); - ERR_add_error_data(5, "You must type in ", - number1, " to ", number2, " characters"); - return -1; - } + if (len < uis->_.string_data.result_minsize) { + ui->flags |= UI_FLAG_REDOABLE; + ERR_raise_data(ERR_LIB_UI, UI_R_RESULT_TOO_SMALL, + "You must type in %d to %d characters", + uis->_.string_data.result_minsize, + uis->_.string_data.result_maxsize); + return -1; + } + if (len > uis->_.string_data.result_maxsize) { + ui->flags |= UI_FLAG_REDOABLE; + ERR_raise_data(ERR_LIB_UI, UI_R_RESULT_TOO_LARGE, + "You must type in %d to %d characters", + uis->_.string_data.result_minsize, + uis->_.string_data.result_maxsize); + return -1; } if (uis->result_buf == NULL) { - UIerr(UI_F_UI_SET_RESULT_EX, UI_R_NO_RESULT_BUFFER); + ERR_raise(ERR_LIB_UI, UI_R_NO_RESULT_BUFFER); return -1; } @@ -931,7 +911,7 @@ int UI_set_result_ex(UI *ui, UI_STRING *uis, const char *result, int len) const char *p; if (uis->result_buf == NULL) { - UIerr(UI_F_UI_SET_RESULT_EX, UI_R_NO_RESULT_BUFFER); + ERR_raise(ERR_LIB_UI, UI_R_NO_RESULT_BUFFER); return -1; } diff --git a/crypto/openssl/crypto/ui/ui_local.h b/crypto/openssl/crypto/ui/ui_local.h index 8a7dbda14721..36b3e6194b0a 100644 --- a/crypto/openssl/crypto/ui/ui_local.h +++ b/crypto/openssl/crypto/ui/ui_local.h @@ -1,7 +1,7 @@ /* * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ui/ui_null.c b/crypto/openssl/crypto/ui/ui_null.c index 9ab00e0a7cb8..f002448d2cd4 100644 --- a/crypto/openssl/crypto/ui/ui_null.c +++ b/crypto/openssl/crypto/ui/ui_null.c @@ -1,7 +1,7 @@ /* * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/ui/ui_openssl.c b/crypto/openssl/crypto/ui/ui_openssl.c index 0f630a5bd963..8007f2f70c87 100644 --- a/crypto/openssl/crypto/ui/ui_openssl.c +++ b/crypto/openssl/crypto/ui/ui_openssl.c @@ -1,7 +1,7 @@ /* * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -34,11 +34,7 @@ # include # if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) -# ifdef OPENSSL_UNISTD -# include OPENSSL_UNISTD -# else -# include -# endif +# include /* * If unistd.h defines _POSIX_VERSION, we conclude that we are on a POSIX * system and have sigaction and termios. @@ -92,8 +88,8 @@ * We know that VMS, MSDOS, VXWORKS, use entirely other mechanisms. */ # elif !defined(OPENSSL_SYS_VMS) \ - && !defined(OPENSSL_SYS_MSDOS) \ - && !defined(OPENSSL_SYS_VXWORKS) + && !defined(OPENSSL_SYS_MSDOS) \ + && !defined(OPENSSL_SYS_VXWORKS) # define TERMIOS # undef TERMIO # undef SGTTY @@ -131,7 +127,7 @@ # define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) # endif -# if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) +# if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && ! (defined(OPENSSL_SYS_TANDEM) && defined(_SPT_MODEL_)) # include # endif @@ -376,7 +372,8 @@ static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) /* Internal functions to open, handle and close a channel to the console. */ static int open_console(UI *ui) { - CRYPTO_THREAD_write_lock(ui->lock); + if (!CRYPTO_THREAD_write_lock(ui->lock)) + return 0; is_a_tty = 1; # if defined(OPENSSL_SYS_VXWORKS) @@ -455,15 +452,12 @@ static int open_console(UI *ui) * which seems appropriate. */ if (errno == ENODEV) - is_a_tty = 0; + is_a_tty = 0; else # endif { - char tmp_num[10]; - BIO_snprintf(tmp_num, sizeof(tmp_num) - 1, "%d", errno); - UIerr(UI_F_OPEN_CONSOLE, UI_R_UNKNOWN_TTYGET_ERRNO_VALUE); - ERR_add_error_data(2, "errno=", tmp_num); - + ERR_raise_data(ERR_LIB_UI, UI_R_UNKNOWN_TTYGET_ERRNO_VALUE, + "errno=%d", errno); return 0; } } @@ -473,11 +467,8 @@ static int open_console(UI *ui) /* if there isn't a TT device, something is very wrong */ if (status != SS$_NORMAL) { - char tmp_num[12]; - - BIO_snprintf(tmp_num, sizeof(tmp_num) - 1, "%%X%08X", status); - UIerr(UI_F_OPEN_CONSOLE, UI_R_SYSASSIGN_ERROR); - ERR_add_error_data(2, "status=", tmp_num); + ERR_raise_data(ERR_LIB_UI, UI_R_SYSASSIGN_ERROR, + "status=%%X%08X", status); return 0; } @@ -510,15 +501,9 @@ static int noecho_console(UI *ui) status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0, 0); if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) { - char tmp_num[2][12]; - - BIO_snprintf(tmp_num[0], sizeof(tmp_num[0]) - 1, "%%X%08X", - status); - BIO_snprintf(tmp_num[1], sizeof(tmp_num[1]) - 1, "%%X%08X", - iosb.iosb$w_value); - UIerr(UI_F_NOECHO_CONSOLE, UI_R_SYSQIOW_ERROR); - ERR_add_error_data(5, "status=", tmp_num[0], - ",", "iosb.iosb$w_value=", tmp_num[1]); + ERR_raise_data(ERR_LIB_UI, UI_R_SYSQIOW_ERROR, + "status=%%X%08X, iosb.iosb$w_value=%%X%08X", + status, iosb.iosb$w_value); return 0; } } @@ -548,15 +533,9 @@ static int echo_console(UI *ui) status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0, 0); if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) { - char tmp_num[2][12]; - - BIO_snprintf(tmp_num[0], sizeof(tmp_num[0]) - 1, "%%X%08X", - status); - BIO_snprintf(tmp_num[1], sizeof(tmp_num[1]) - 1, "%%X%08X", - iosb.iosb$w_value); - UIerr(UI_F_ECHO_CONSOLE, UI_R_SYSQIOW_ERROR); - ERR_add_error_data(5, "status=", tmp_num[0], - ",", "iosb.iosb$w_value=", tmp_num[1]); + ERR_raise_data(ERR_LIB_UI, UI_R_SYSQIOW_ERROR, + "status=%%X%08X, iosb.iosb$w_value=%%X%08X", + status, iosb.iosb$w_value); return 0; } } @@ -581,11 +560,8 @@ static int close_console(UI *ui) # ifdef OPENSSL_SYS_VMS status = sys$dassgn(channel); if (status != SS$_NORMAL) { - char tmp_num[12]; - - BIO_snprintf(tmp_num, sizeof(tmp_num) - 1, "%%X%08X", status); - UIerr(UI_F_CLOSE_CONSOLE, UI_R_SYSDASSGN_ERROR); - ERR_add_error_data(2, "status=", tmp_num); + ERR_raise_data(ERR_LIB_UI, UI_R_SYSDASSGN_ERROR, + "status=%%X%08X", status); ret = 0; } # endif diff --git a/crypto/openssl/crypto/ui/ui_util.c b/crypto/openssl/crypto/ui/ui_util.c index 32a3c4e38de2..80297969ab1d 100644 --- a/crypto/openssl/crypto/ui/ui_util.c +++ b/crypto/openssl/crypto/ui/ui_util.c @@ -1,7 +1,7 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -71,12 +71,14 @@ static void ui_new_method_data(void *parent, void *ptr, CRYPTO_EX_DATA *ad, } static int ui_dup_method_data(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, - void *from_d, int idx, long argl, void *argp) + void **pptr, int idx, long argl, void *argp) { - void **pptr = (void **)from_d; - if (*pptr != NULL) + if (*pptr != NULL) { *pptr = OPENSSL_memdup(*pptr, sizeof(struct pem_password_cb_data)); - return 1; + if (*pptr != NULL) + return 1; + } + return 0; } static void ui_free_method_data(void *parent, void *ptr, CRYPTO_EX_DATA *ad, @@ -115,7 +117,7 @@ static int ui_read(UI *ui, UI_STRING *uis) if (len >= 0) result[len] = '\0'; - if (len <= 0) + if (len < 0) return len; if (UI_set_result_ex(ui, uis, result, len) >= 0) return 1; @@ -151,7 +153,7 @@ UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag) || UI_method_set_writer(ui_method, ui_write) < 0 || UI_method_set_closer(ui_method, ui_close) < 0 || !RUN_ONCE(&get_index_once, ui_method_data_index_init) - || UI_method_set_ex_data(ui_method, ui_method_data_index, data) < 0) { + || !UI_method_set_ex_data(ui_method, ui_method_data_index, data)) { UI_destroy_method(ui_method); OPENSSL_free(data); return NULL; diff --git a/crypto/openssl/crypto/uid.c b/crypto/openssl/crypto/uid.c index a9eae36818ca..698127779f54 100644 --- a/crypto/openssl/crypto/uid.c +++ b/crypto/openssl/crypto/uid.c @@ -1,7 +1,7 @@ /* * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,7 +19,7 @@ int OPENSSL_issetugid(void) #elif defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ > 2) || defined(__DragonFly__) || (defined(__GLIBC__) && defined(__FreeBSD_kernel__)) -# include OPENSSL_UNISTD +# include int OPENSSL_issetugid(void) { @@ -28,7 +28,7 @@ int OPENSSL_issetugid(void) #else -# include OPENSSL_UNISTD +# include # include # if defined(__GLIBC__) && defined(__GLIBC_PREREQ) diff --git a/crypto/openssl/crypto/vms_rms.h b/crypto/openssl/crypto/vms_rms.h index 3b994a0aba2c..ae74ba68294e 100644 --- a/crypto/openssl/crypto/vms_rms.h +++ b/crypto/openssl/crypto/vms_rms.h @@ -1,7 +1,7 @@ /* * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/whrlpool/asm/wp-mmx.pl b/crypto/openssl/crypto/whrlpool/asm/wp-mmx.pl index 176be50a67f2..ad2528a9e28a 100755 --- a/crypto/openssl/crypto/whrlpool/asm/wp-mmx.pl +++ b/crypto/openssl/crypto/whrlpool/asm/wp-mmx.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -10,7 +10,7 @@ # ==================================================================== # Written by Andy Polyakov for the OpenSSL # project. Rights for redistribution and usage in source and binary -# forms are granted according to the OpenSSL license. +# forms are granted according to the License. # ==================================================================== # # whirlpool_block_mmx implementation. @@ -56,8 +56,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC,"${dir}","${dir}../../perlasm"); require "x86asm.pl"; -$output=pop; -open STDOUT,">$output"; +$output=pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/openssl/crypto/whrlpool/asm/wp-x86_64.pl b/crypto/openssl/crypto/whrlpool/asm/wp-x86_64.pl index b4fcd8be3c75..f94152af9769 100755 --- a/crypto/openssl/crypto/whrlpool/asm/wp-x86_64.pl +++ b/crypto/openssl/crypto/whrlpool/asm/wp-x86_64.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -10,7 +10,7 @@ # ==================================================================== # Written by Andy Polyakov for the OpenSSL # project. Rights for redistribution and usage in source and binary -# forms are granted according to the OpenSSL license. +# forms are granted according to the License. # ==================================================================== # # whirlpool_block for x86_64. @@ -37,9 +37,10 @@ # 3 on Opteron] and which is *unacceptably* slow with 64-bit # operand. -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -48,7 +49,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate; ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; sub L() { $code.=".byte ".join(',',@_)."\n"; } diff --git a/crypto/openssl/crypto/whrlpool/build.info b/crypto/openssl/crypto/whrlpool/build.info index 4b167b504ec3..c7dbecb4fd79 100644 --- a/crypto/openssl/crypto/whrlpool/build.info +++ b/crypto/openssl/crypto/whrlpool/build.info @@ -1,8 +1,33 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=wp_dgst.c {- $target{wp_asm_src} -} -GENERATE[wp-mmx.s]=asm/wp-mmx.pl \ - $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR) -DEPEND[wp-mmx.s]=../perlasm/x86asm.pl +$WPASM=wp_block.c +IF[{- !$disabled{asm} -}] + IF[{- $config{processor} ne "386" -}] + $WPASM_x86=wp_block.c wp-mmx.S + $WPDEF_x86=WHIRLPOOL_ASM + ENDIF + $WPASM_x86_64=wp-x86_64.s + $WPDEF_x86_64=WHIRLPOOL_ASM -GENERATE[wp-x86_64.s]=asm/wp-x86_64.pl $(PERLASM_SCHEME) + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$WPASM_{- $target{asm_arch} -}] + $WPASM=$WPASM_{- $target{asm_arch} -} + $WPDEF=$WPDEF_{- $target{asm_arch} -} + ENDIF +ENDIF + +SOURCE[../../libcrypto]=wp_dgst.c $WPASM +DEFINE[../../libcrypto]=$WPDEF + +# When all deprecated symbols are removed, libcrypto doesn't export the +# WHIRLPOOL functions, so we must include them directly in liblegacy.a +IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}] + SOURCE[../../providers/liblegacy.a]=wp_dgst.c $WPASM + DEFINE[../../providers/liblegacy.a]=$WPDEF +ENDIF + +GENERATE[wp-mmx.S]=asm/wp-mmx.pl +DEPEND[wp-mmx.S]=../perlasm/x86asm.pl + +GENERATE[wp-x86_64.s]=asm/wp-x86_64.pl diff --git a/crypto/openssl/crypto/whrlpool/wp-mmx.S b/crypto/openssl/crypto/whrlpool/wp-mmx.S new file mode 100644 index 000000000000..ee571f645947 --- /dev/null +++ b/crypto/openssl/crypto/whrlpool/wp-mmx.S @@ -0,0 +1,1128 @@ +.text +.globl whirlpool_block_mmx +.type whirlpool_block_mmx,@function +.align 16 +whirlpool_block_mmx: +.L_whirlpool_block_mmx_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl 20(%esp),%esi + movl 24(%esp),%edi + movl 28(%esp),%ebp + movl %esp,%eax + subl $148,%esp + andl $-64,%esp + leal 128(%esp),%ebx + movl %esi,(%ebx) + movl %edi,4(%ebx) + movl %ebp,8(%ebx) + movl %eax,16(%ebx) + call .L000pic_point +.L000pic_point: + popl %ebp + leal .L001table-.L000pic_point(%ebp),%ebp + xorl %ecx,%ecx + xorl %edx,%edx + movq (%esi),%mm0 + movq 8(%esi),%mm1 + movq 16(%esi),%mm2 + movq 24(%esi),%mm3 + movq 32(%esi),%mm4 + movq 40(%esi),%mm5 + movq 48(%esi),%mm6 + movq 56(%esi),%mm7 +.L002outerloop: + movq %mm0,(%esp) + movq %mm1,8(%esp) + movq %mm2,16(%esp) + movq %mm3,24(%esp) + movq %mm4,32(%esp) + movq %mm5,40(%esp) + movq %mm6,48(%esp) + movq %mm7,56(%esp) + pxor (%edi),%mm0 + pxor 8(%edi),%mm1 + pxor 16(%edi),%mm2 + pxor 24(%edi),%mm3 + pxor 32(%edi),%mm4 + pxor 40(%edi),%mm5 + pxor 48(%edi),%mm6 + pxor 56(%edi),%mm7 + movq %mm0,64(%esp) + movq %mm1,72(%esp) + movq %mm2,80(%esp) + movq %mm3,88(%esp) + movq %mm4,96(%esp) + movq %mm5,104(%esp) + movq %mm6,112(%esp) + movq %mm7,120(%esp) + xorl %esi,%esi + movl %esi,12(%ebx) +.align 16 +.L003round: + movq 4096(%ebp,%esi,8),%mm0 + movl (%esp),%eax + movl 4(%esp),%ebx + movzbl %al,%ecx + movzbl %ah,%edx + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm0 + movq 7(%ebp,%edi,8),%mm1 + movl 8(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + movq 6(%ebp,%esi,8),%mm2 + movq 5(%ebp,%edi,8),%mm3 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + movq 4(%ebp,%esi,8),%mm4 + movq 3(%ebp,%edi,8),%mm5 + movl 12(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + movq 2(%ebp,%esi,8),%mm6 + movq 1(%ebp,%edi,8),%mm7 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm1 + pxor 7(%ebp,%edi,8),%mm2 + movl 16(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm3 + pxor 5(%ebp,%edi,8),%mm4 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm5 + pxor 3(%ebp,%edi,8),%mm6 + movl 20(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm7 + pxor 1(%ebp,%edi,8),%mm0 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm2 + pxor 7(%ebp,%edi,8),%mm3 + movl 24(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm4 + pxor 5(%ebp,%edi,8),%mm5 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm6 + pxor 3(%ebp,%edi,8),%mm7 + movl 28(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm0 + pxor 1(%ebp,%edi,8),%mm1 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm3 + pxor 7(%ebp,%edi,8),%mm4 + movl 32(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm5 + pxor 5(%ebp,%edi,8),%mm6 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm7 + pxor 3(%ebp,%edi,8),%mm0 + movl 36(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm1 + pxor 1(%ebp,%edi,8),%mm2 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm4 + pxor 7(%ebp,%edi,8),%mm5 + movl 40(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm6 + pxor 5(%ebp,%edi,8),%mm7 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm0 + pxor 3(%ebp,%edi,8),%mm1 + movl 44(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm2 + pxor 1(%ebp,%edi,8),%mm3 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm5 + pxor 7(%ebp,%edi,8),%mm6 + movl 48(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm7 + pxor 5(%ebp,%edi,8),%mm0 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm1 + pxor 3(%ebp,%edi,8),%mm2 + movl 52(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm3 + pxor 1(%ebp,%edi,8),%mm4 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm6 + pxor 7(%ebp,%edi,8),%mm7 + movl 56(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm0 + pxor 5(%ebp,%edi,8),%mm1 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm2 + pxor 3(%ebp,%edi,8),%mm3 + movl 60(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm4 + pxor 1(%ebp,%edi,8),%mm5 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm7 + pxor 7(%ebp,%edi,8),%mm0 + movl 64(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm1 + pxor 5(%ebp,%edi,8),%mm2 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm3 + pxor 3(%ebp,%edi,8),%mm4 + movl 68(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm5 + pxor 1(%ebp,%edi,8),%mm6 + movq %mm0,(%esp) + movq %mm1,8(%esp) + movq %mm2,16(%esp) + movq %mm3,24(%esp) + movq %mm4,32(%esp) + movq %mm5,40(%esp) + movq %mm6,48(%esp) + movq %mm7,56(%esp) + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm0 + pxor 7(%ebp,%edi,8),%mm1 + movl 72(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm2 + pxor 5(%ebp,%edi,8),%mm3 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm4 + pxor 3(%ebp,%edi,8),%mm5 + movl 76(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm6 + pxor 1(%ebp,%edi,8),%mm7 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm1 + pxor 7(%ebp,%edi,8),%mm2 + movl 80(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm3 + pxor 5(%ebp,%edi,8),%mm4 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm5 + pxor 3(%ebp,%edi,8),%mm6 + movl 84(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm7 + pxor 1(%ebp,%edi,8),%mm0 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm2 + pxor 7(%ebp,%edi,8),%mm3 + movl 88(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm4 + pxor 5(%ebp,%edi,8),%mm5 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm6 + pxor 3(%ebp,%edi,8),%mm7 + movl 92(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm0 + pxor 1(%ebp,%edi,8),%mm1 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm3 + pxor 7(%ebp,%edi,8),%mm4 + movl 96(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm5 + pxor 5(%ebp,%edi,8),%mm6 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm7 + pxor 3(%ebp,%edi,8),%mm0 + movl 100(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm1 + pxor 1(%ebp,%edi,8),%mm2 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm4 + pxor 7(%ebp,%edi,8),%mm5 + movl 104(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm6 + pxor 5(%ebp,%edi,8),%mm7 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm0 + pxor 3(%ebp,%edi,8),%mm1 + movl 108(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm2 + pxor 1(%ebp,%edi,8),%mm3 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm5 + pxor 7(%ebp,%edi,8),%mm6 + movl 112(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm7 + pxor 5(%ebp,%edi,8),%mm0 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm1 + pxor 3(%ebp,%edi,8),%mm2 + movl 116(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm3 + pxor 1(%ebp,%edi,8),%mm4 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm6 + pxor 7(%ebp,%edi,8),%mm7 + movl 120(%esp),%eax + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm0 + pxor 5(%ebp,%edi,8),%mm1 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm2 + pxor 3(%ebp,%edi,8),%mm3 + movl 124(%esp),%ebx + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm4 + pxor 1(%ebp,%edi,8),%mm5 + shrl $16,%eax + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor (%ebp,%esi,8),%mm7 + pxor 7(%ebp,%edi,8),%mm0 + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 6(%ebp,%esi,8),%mm1 + pxor 5(%ebp,%edi,8),%mm2 + shrl $16,%ebx + leal (%ecx,%ecx,1),%esi + movzbl %bl,%ecx + leal (%edx,%edx,1),%edi + movzbl %bh,%edx + pxor 4(%ebp,%esi,8),%mm3 + pxor 3(%ebp,%edi,8),%mm4 + leal (%ecx,%ecx,1),%esi + movzbl %al,%ecx + leal (%edx,%edx,1),%edi + movzbl %ah,%edx + pxor 2(%ebp,%esi,8),%mm5 + pxor 1(%ebp,%edi,8),%mm6 + leal 128(%esp),%ebx + movl 12(%ebx),%esi + addl $1,%esi + cmpl $10,%esi + je .L004roundsdone + movl %esi,12(%ebx) + movq %mm0,64(%esp) + movq %mm1,72(%esp) + movq %mm2,80(%esp) + movq %mm3,88(%esp) + movq %mm4,96(%esp) + movq %mm5,104(%esp) + movq %mm6,112(%esp) + movq %mm7,120(%esp) + jmp .L003round +.align 16 +.L004roundsdone: + movl (%ebx),%esi + movl 4(%ebx),%edi + movl 8(%ebx),%eax + pxor (%edi),%mm0 + pxor 8(%edi),%mm1 + pxor 16(%edi),%mm2 + pxor 24(%edi),%mm3 + pxor 32(%edi),%mm4 + pxor 40(%edi),%mm5 + pxor 48(%edi),%mm6 + pxor 56(%edi),%mm7 + pxor (%esi),%mm0 + pxor 8(%esi),%mm1 + pxor 16(%esi),%mm2 + pxor 24(%esi),%mm3 + pxor 32(%esi),%mm4 + pxor 40(%esi),%mm5 + pxor 48(%esi),%mm6 + pxor 56(%esi),%mm7 + movq %mm0,(%esi) + movq %mm1,8(%esi) + movq %mm2,16(%esi) + movq %mm3,24(%esi) + movq %mm4,32(%esi) + movq %mm5,40(%esi) + movq %mm6,48(%esi) + movq %mm7,56(%esi) + leal 64(%edi),%edi + subl $1,%eax + jz .L005alldone + movl %edi,4(%ebx) + movl %eax,8(%ebx) + jmp .L002outerloop +.L005alldone: + emms + movl 16(%ebx),%esp + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.align 64 +.L001table: +.byte 24,24,96,24,192,120,48,216 +.byte 24,24,96,24,192,120,48,216 +.byte 35,35,140,35,5,175,70,38 +.byte 35,35,140,35,5,175,70,38 +.byte 198,198,63,198,126,249,145,184 +.byte 198,198,63,198,126,249,145,184 +.byte 232,232,135,232,19,111,205,251 +.byte 232,232,135,232,19,111,205,251 +.byte 135,135,38,135,76,161,19,203 +.byte 135,135,38,135,76,161,19,203 +.byte 184,184,218,184,169,98,109,17 +.byte 184,184,218,184,169,98,109,17 +.byte 1,1,4,1,8,5,2,9 +.byte 1,1,4,1,8,5,2,9 +.byte 79,79,33,79,66,110,158,13 +.byte 79,79,33,79,66,110,158,13 +.byte 54,54,216,54,173,238,108,155 +.byte 54,54,216,54,173,238,108,155 +.byte 166,166,162,166,89,4,81,255 +.byte 166,166,162,166,89,4,81,255 +.byte 210,210,111,210,222,189,185,12 +.byte 210,210,111,210,222,189,185,12 +.byte 245,245,243,245,251,6,247,14 +.byte 245,245,243,245,251,6,247,14 +.byte 121,121,249,121,239,128,242,150 +.byte 121,121,249,121,239,128,242,150 +.byte 111,111,161,111,95,206,222,48 +.byte 111,111,161,111,95,206,222,48 +.byte 145,145,126,145,252,239,63,109 +.byte 145,145,126,145,252,239,63,109 +.byte 82,82,85,82,170,7,164,248 +.byte 82,82,85,82,170,7,164,248 +.byte 96,96,157,96,39,253,192,71 +.byte 96,96,157,96,39,253,192,71 +.byte 188,188,202,188,137,118,101,53 +.byte 188,188,202,188,137,118,101,53 +.byte 155,155,86,155,172,205,43,55 +.byte 155,155,86,155,172,205,43,55 +.byte 142,142,2,142,4,140,1,138 +.byte 142,142,2,142,4,140,1,138 +.byte 163,163,182,163,113,21,91,210 +.byte 163,163,182,163,113,21,91,210 +.byte 12,12,48,12,96,60,24,108 +.byte 12,12,48,12,96,60,24,108 +.byte 123,123,241,123,255,138,246,132 +.byte 123,123,241,123,255,138,246,132 +.byte 53,53,212,53,181,225,106,128 +.byte 53,53,212,53,181,225,106,128 +.byte 29,29,116,29,232,105,58,245 +.byte 29,29,116,29,232,105,58,245 +.byte 224,224,167,224,83,71,221,179 +.byte 224,224,167,224,83,71,221,179 +.byte 215,215,123,215,246,172,179,33 +.byte 215,215,123,215,246,172,179,33 +.byte 194,194,47,194,94,237,153,156 +.byte 194,194,47,194,94,237,153,156 +.byte 46,46,184,46,109,150,92,67 +.byte 46,46,184,46,109,150,92,67 +.byte 75,75,49,75,98,122,150,41 +.byte 75,75,49,75,98,122,150,41 +.byte 254,254,223,254,163,33,225,93 +.byte 254,254,223,254,163,33,225,93 +.byte 87,87,65,87,130,22,174,213 +.byte 87,87,65,87,130,22,174,213 +.byte 21,21,84,21,168,65,42,189 +.byte 21,21,84,21,168,65,42,189 +.byte 119,119,193,119,159,182,238,232 +.byte 119,119,193,119,159,182,238,232 +.byte 55,55,220,55,165,235,110,146 +.byte 55,55,220,55,165,235,110,146 +.byte 229,229,179,229,123,86,215,158 +.byte 229,229,179,229,123,86,215,158 +.byte 159,159,70,159,140,217,35,19 +.byte 159,159,70,159,140,217,35,19 +.byte 240,240,231,240,211,23,253,35 +.byte 240,240,231,240,211,23,253,35 +.byte 74,74,53,74,106,127,148,32 +.byte 74,74,53,74,106,127,148,32 +.byte 218,218,79,218,158,149,169,68 +.byte 218,218,79,218,158,149,169,68 +.byte 88,88,125,88,250,37,176,162 +.byte 88,88,125,88,250,37,176,162 +.byte 201,201,3,201,6,202,143,207 +.byte 201,201,3,201,6,202,143,207 +.byte 41,41,164,41,85,141,82,124 +.byte 41,41,164,41,85,141,82,124 +.byte 10,10,40,10,80,34,20,90 +.byte 10,10,40,10,80,34,20,90 +.byte 177,177,254,177,225,79,127,80 +.byte 177,177,254,177,225,79,127,80 +.byte 160,160,186,160,105,26,93,201 +.byte 160,160,186,160,105,26,93,201 +.byte 107,107,177,107,127,218,214,20 +.byte 107,107,177,107,127,218,214,20 +.byte 133,133,46,133,92,171,23,217 +.byte 133,133,46,133,92,171,23,217 +.byte 189,189,206,189,129,115,103,60 +.byte 189,189,206,189,129,115,103,60 +.byte 93,93,105,93,210,52,186,143 +.byte 93,93,105,93,210,52,186,143 +.byte 16,16,64,16,128,80,32,144 +.byte 16,16,64,16,128,80,32,144 +.byte 244,244,247,244,243,3,245,7 +.byte 244,244,247,244,243,3,245,7 +.byte 203,203,11,203,22,192,139,221 +.byte 203,203,11,203,22,192,139,221 +.byte 62,62,248,62,237,198,124,211 +.byte 62,62,248,62,237,198,124,211 +.byte 5,5,20,5,40,17,10,45 +.byte 5,5,20,5,40,17,10,45 +.byte 103,103,129,103,31,230,206,120 +.byte 103,103,129,103,31,230,206,120 +.byte 228,228,183,228,115,83,213,151 +.byte 228,228,183,228,115,83,213,151 +.byte 39,39,156,39,37,187,78,2 +.byte 39,39,156,39,37,187,78,2 +.byte 65,65,25,65,50,88,130,115 +.byte 65,65,25,65,50,88,130,115 +.byte 139,139,22,139,44,157,11,167 +.byte 139,139,22,139,44,157,11,167 +.byte 167,167,166,167,81,1,83,246 +.byte 167,167,166,167,81,1,83,246 +.byte 125,125,233,125,207,148,250,178 +.byte 125,125,233,125,207,148,250,178 +.byte 149,149,110,149,220,251,55,73 +.byte 149,149,110,149,220,251,55,73 +.byte 216,216,71,216,142,159,173,86 +.byte 216,216,71,216,142,159,173,86 +.byte 251,251,203,251,139,48,235,112 +.byte 251,251,203,251,139,48,235,112 +.byte 238,238,159,238,35,113,193,205 +.byte 238,238,159,238,35,113,193,205 +.byte 124,124,237,124,199,145,248,187 +.byte 124,124,237,124,199,145,248,187 +.byte 102,102,133,102,23,227,204,113 +.byte 102,102,133,102,23,227,204,113 +.byte 221,221,83,221,166,142,167,123 +.byte 221,221,83,221,166,142,167,123 +.byte 23,23,92,23,184,75,46,175 +.byte 23,23,92,23,184,75,46,175 +.byte 71,71,1,71,2,70,142,69 +.byte 71,71,1,71,2,70,142,69 +.byte 158,158,66,158,132,220,33,26 +.byte 158,158,66,158,132,220,33,26 +.byte 202,202,15,202,30,197,137,212 +.byte 202,202,15,202,30,197,137,212 +.byte 45,45,180,45,117,153,90,88 +.byte 45,45,180,45,117,153,90,88 +.byte 191,191,198,191,145,121,99,46 +.byte 191,191,198,191,145,121,99,46 +.byte 7,7,28,7,56,27,14,63 +.byte 7,7,28,7,56,27,14,63 +.byte 173,173,142,173,1,35,71,172 +.byte 173,173,142,173,1,35,71,172 +.byte 90,90,117,90,234,47,180,176 +.byte 90,90,117,90,234,47,180,176 +.byte 131,131,54,131,108,181,27,239 +.byte 131,131,54,131,108,181,27,239 +.byte 51,51,204,51,133,255,102,182 +.byte 51,51,204,51,133,255,102,182 +.byte 99,99,145,99,63,242,198,92 +.byte 99,99,145,99,63,242,198,92 +.byte 2,2,8,2,16,10,4,18 +.byte 2,2,8,2,16,10,4,18 +.byte 170,170,146,170,57,56,73,147 +.byte 170,170,146,170,57,56,73,147 +.byte 113,113,217,113,175,168,226,222 +.byte 113,113,217,113,175,168,226,222 +.byte 200,200,7,200,14,207,141,198 +.byte 200,200,7,200,14,207,141,198 +.byte 25,25,100,25,200,125,50,209 +.byte 25,25,100,25,200,125,50,209 +.byte 73,73,57,73,114,112,146,59 +.byte 73,73,57,73,114,112,146,59 +.byte 217,217,67,217,134,154,175,95 +.byte 217,217,67,217,134,154,175,95 +.byte 242,242,239,242,195,29,249,49 +.byte 242,242,239,242,195,29,249,49 +.byte 227,227,171,227,75,72,219,168 +.byte 227,227,171,227,75,72,219,168 +.byte 91,91,113,91,226,42,182,185 +.byte 91,91,113,91,226,42,182,185 +.byte 136,136,26,136,52,146,13,188 +.byte 136,136,26,136,52,146,13,188 +.byte 154,154,82,154,164,200,41,62 +.byte 154,154,82,154,164,200,41,62 +.byte 38,38,152,38,45,190,76,11 +.byte 38,38,152,38,45,190,76,11 +.byte 50,50,200,50,141,250,100,191 +.byte 50,50,200,50,141,250,100,191 +.byte 176,176,250,176,233,74,125,89 +.byte 176,176,250,176,233,74,125,89 +.byte 233,233,131,233,27,106,207,242 +.byte 233,233,131,233,27,106,207,242 +.byte 15,15,60,15,120,51,30,119 +.byte 15,15,60,15,120,51,30,119 +.byte 213,213,115,213,230,166,183,51 +.byte 213,213,115,213,230,166,183,51 +.byte 128,128,58,128,116,186,29,244 +.byte 128,128,58,128,116,186,29,244 +.byte 190,190,194,190,153,124,97,39 +.byte 190,190,194,190,153,124,97,39 +.byte 205,205,19,205,38,222,135,235 +.byte 205,205,19,205,38,222,135,235 +.byte 52,52,208,52,189,228,104,137 +.byte 52,52,208,52,189,228,104,137 +.byte 72,72,61,72,122,117,144,50 +.byte 72,72,61,72,122,117,144,50 +.byte 255,255,219,255,171,36,227,84 +.byte 255,255,219,255,171,36,227,84 +.byte 122,122,245,122,247,143,244,141 +.byte 122,122,245,122,247,143,244,141 +.byte 144,144,122,144,244,234,61,100 +.byte 144,144,122,144,244,234,61,100 +.byte 95,95,97,95,194,62,190,157 +.byte 95,95,97,95,194,62,190,157 +.byte 32,32,128,32,29,160,64,61 +.byte 32,32,128,32,29,160,64,61 +.byte 104,104,189,104,103,213,208,15 +.byte 104,104,189,104,103,213,208,15 +.byte 26,26,104,26,208,114,52,202 +.byte 26,26,104,26,208,114,52,202 +.byte 174,174,130,174,25,44,65,183 +.byte 174,174,130,174,25,44,65,183 +.byte 180,180,234,180,201,94,117,125 +.byte 180,180,234,180,201,94,117,125 +.byte 84,84,77,84,154,25,168,206 +.byte 84,84,77,84,154,25,168,206 +.byte 147,147,118,147,236,229,59,127 +.byte 147,147,118,147,236,229,59,127 +.byte 34,34,136,34,13,170,68,47 +.byte 34,34,136,34,13,170,68,47 +.byte 100,100,141,100,7,233,200,99 +.byte 100,100,141,100,7,233,200,99 +.byte 241,241,227,241,219,18,255,42 +.byte 241,241,227,241,219,18,255,42 +.byte 115,115,209,115,191,162,230,204 +.byte 115,115,209,115,191,162,230,204 +.byte 18,18,72,18,144,90,36,130 +.byte 18,18,72,18,144,90,36,130 +.byte 64,64,29,64,58,93,128,122 +.byte 64,64,29,64,58,93,128,122 +.byte 8,8,32,8,64,40,16,72 +.byte 8,8,32,8,64,40,16,72 +.byte 195,195,43,195,86,232,155,149 +.byte 195,195,43,195,86,232,155,149 +.byte 236,236,151,236,51,123,197,223 +.byte 236,236,151,236,51,123,197,223 +.byte 219,219,75,219,150,144,171,77 +.byte 219,219,75,219,150,144,171,77 +.byte 161,161,190,161,97,31,95,192 +.byte 161,161,190,161,97,31,95,192 +.byte 141,141,14,141,28,131,7,145 +.byte 141,141,14,141,28,131,7,145 +.byte 61,61,244,61,245,201,122,200 +.byte 61,61,244,61,245,201,122,200 +.byte 151,151,102,151,204,241,51,91 +.byte 151,151,102,151,204,241,51,91 +.byte 0,0,0,0,0,0,0,0 +.byte 0,0,0,0,0,0,0,0 +.byte 207,207,27,207,54,212,131,249 +.byte 207,207,27,207,54,212,131,249 +.byte 43,43,172,43,69,135,86,110 +.byte 43,43,172,43,69,135,86,110 +.byte 118,118,197,118,151,179,236,225 +.byte 118,118,197,118,151,179,236,225 +.byte 130,130,50,130,100,176,25,230 +.byte 130,130,50,130,100,176,25,230 +.byte 214,214,127,214,254,169,177,40 +.byte 214,214,127,214,254,169,177,40 +.byte 27,27,108,27,216,119,54,195 +.byte 27,27,108,27,216,119,54,195 +.byte 181,181,238,181,193,91,119,116 +.byte 181,181,238,181,193,91,119,116 +.byte 175,175,134,175,17,41,67,190 +.byte 175,175,134,175,17,41,67,190 +.byte 106,106,181,106,119,223,212,29 +.byte 106,106,181,106,119,223,212,29 +.byte 80,80,93,80,186,13,160,234 +.byte 80,80,93,80,186,13,160,234 +.byte 69,69,9,69,18,76,138,87 +.byte 69,69,9,69,18,76,138,87 +.byte 243,243,235,243,203,24,251,56 +.byte 243,243,235,243,203,24,251,56 +.byte 48,48,192,48,157,240,96,173 +.byte 48,48,192,48,157,240,96,173 +.byte 239,239,155,239,43,116,195,196 +.byte 239,239,155,239,43,116,195,196 +.byte 63,63,252,63,229,195,126,218 +.byte 63,63,252,63,229,195,126,218 +.byte 85,85,73,85,146,28,170,199 +.byte 85,85,73,85,146,28,170,199 +.byte 162,162,178,162,121,16,89,219 +.byte 162,162,178,162,121,16,89,219 +.byte 234,234,143,234,3,101,201,233 +.byte 234,234,143,234,3,101,201,233 +.byte 101,101,137,101,15,236,202,106 +.byte 101,101,137,101,15,236,202,106 +.byte 186,186,210,186,185,104,105,3 +.byte 186,186,210,186,185,104,105,3 +.byte 47,47,188,47,101,147,94,74 +.byte 47,47,188,47,101,147,94,74 +.byte 192,192,39,192,78,231,157,142 +.byte 192,192,39,192,78,231,157,142 +.byte 222,222,95,222,190,129,161,96 +.byte 222,222,95,222,190,129,161,96 +.byte 28,28,112,28,224,108,56,252 +.byte 28,28,112,28,224,108,56,252 +.byte 253,253,211,253,187,46,231,70 +.byte 253,253,211,253,187,46,231,70 +.byte 77,77,41,77,82,100,154,31 +.byte 77,77,41,77,82,100,154,31 +.byte 146,146,114,146,228,224,57,118 +.byte 146,146,114,146,228,224,57,118 +.byte 117,117,201,117,143,188,234,250 +.byte 117,117,201,117,143,188,234,250 +.byte 6,6,24,6,48,30,12,54 +.byte 6,6,24,6,48,30,12,54 +.byte 138,138,18,138,36,152,9,174 +.byte 138,138,18,138,36,152,9,174 +.byte 178,178,242,178,249,64,121,75 +.byte 178,178,242,178,249,64,121,75 +.byte 230,230,191,230,99,89,209,133 +.byte 230,230,191,230,99,89,209,133 +.byte 14,14,56,14,112,54,28,126 +.byte 14,14,56,14,112,54,28,126 +.byte 31,31,124,31,248,99,62,231 +.byte 31,31,124,31,248,99,62,231 +.byte 98,98,149,98,55,247,196,85 +.byte 98,98,149,98,55,247,196,85 +.byte 212,212,119,212,238,163,181,58 +.byte 212,212,119,212,238,163,181,58 +.byte 168,168,154,168,41,50,77,129 +.byte 168,168,154,168,41,50,77,129 +.byte 150,150,98,150,196,244,49,82 +.byte 150,150,98,150,196,244,49,82 +.byte 249,249,195,249,155,58,239,98 +.byte 249,249,195,249,155,58,239,98 +.byte 197,197,51,197,102,246,151,163 +.byte 197,197,51,197,102,246,151,163 +.byte 37,37,148,37,53,177,74,16 +.byte 37,37,148,37,53,177,74,16 +.byte 89,89,121,89,242,32,178,171 +.byte 89,89,121,89,242,32,178,171 +.byte 132,132,42,132,84,174,21,208 +.byte 132,132,42,132,84,174,21,208 +.byte 114,114,213,114,183,167,228,197 +.byte 114,114,213,114,183,167,228,197 +.byte 57,57,228,57,213,221,114,236 +.byte 57,57,228,57,213,221,114,236 +.byte 76,76,45,76,90,97,152,22 +.byte 76,76,45,76,90,97,152,22 +.byte 94,94,101,94,202,59,188,148 +.byte 94,94,101,94,202,59,188,148 +.byte 120,120,253,120,231,133,240,159 +.byte 120,120,253,120,231,133,240,159 +.byte 56,56,224,56,221,216,112,229 +.byte 56,56,224,56,221,216,112,229 +.byte 140,140,10,140,20,134,5,152 +.byte 140,140,10,140,20,134,5,152 +.byte 209,209,99,209,198,178,191,23 +.byte 209,209,99,209,198,178,191,23 +.byte 165,165,174,165,65,11,87,228 +.byte 165,165,174,165,65,11,87,228 +.byte 226,226,175,226,67,77,217,161 +.byte 226,226,175,226,67,77,217,161 +.byte 97,97,153,97,47,248,194,78 +.byte 97,97,153,97,47,248,194,78 +.byte 179,179,246,179,241,69,123,66 +.byte 179,179,246,179,241,69,123,66 +.byte 33,33,132,33,21,165,66,52 +.byte 33,33,132,33,21,165,66,52 +.byte 156,156,74,156,148,214,37,8 +.byte 156,156,74,156,148,214,37,8 +.byte 30,30,120,30,240,102,60,238 +.byte 30,30,120,30,240,102,60,238 +.byte 67,67,17,67,34,82,134,97 +.byte 67,67,17,67,34,82,134,97 +.byte 199,199,59,199,118,252,147,177 +.byte 199,199,59,199,118,252,147,177 +.byte 252,252,215,252,179,43,229,79 +.byte 252,252,215,252,179,43,229,79 +.byte 4,4,16,4,32,20,8,36 +.byte 4,4,16,4,32,20,8,36 +.byte 81,81,89,81,178,8,162,227 +.byte 81,81,89,81,178,8,162,227 +.byte 153,153,94,153,188,199,47,37 +.byte 153,153,94,153,188,199,47,37 +.byte 109,109,169,109,79,196,218,34 +.byte 109,109,169,109,79,196,218,34 +.byte 13,13,52,13,104,57,26,101 +.byte 13,13,52,13,104,57,26,101 +.byte 250,250,207,250,131,53,233,121 +.byte 250,250,207,250,131,53,233,121 +.byte 223,223,91,223,182,132,163,105 +.byte 223,223,91,223,182,132,163,105 +.byte 126,126,229,126,215,155,252,169 +.byte 126,126,229,126,215,155,252,169 +.byte 36,36,144,36,61,180,72,25 +.byte 36,36,144,36,61,180,72,25 +.byte 59,59,236,59,197,215,118,254 +.byte 59,59,236,59,197,215,118,254 +.byte 171,171,150,171,49,61,75,154 +.byte 171,171,150,171,49,61,75,154 +.byte 206,206,31,206,62,209,129,240 +.byte 206,206,31,206,62,209,129,240 +.byte 17,17,68,17,136,85,34,153 +.byte 17,17,68,17,136,85,34,153 +.byte 143,143,6,143,12,137,3,131 +.byte 143,143,6,143,12,137,3,131 +.byte 78,78,37,78,74,107,156,4 +.byte 78,78,37,78,74,107,156,4 +.byte 183,183,230,183,209,81,115,102 +.byte 183,183,230,183,209,81,115,102 +.byte 235,235,139,235,11,96,203,224 +.byte 235,235,139,235,11,96,203,224 +.byte 60,60,240,60,253,204,120,193 +.byte 60,60,240,60,253,204,120,193 +.byte 129,129,62,129,124,191,31,253 +.byte 129,129,62,129,124,191,31,253 +.byte 148,148,106,148,212,254,53,64 +.byte 148,148,106,148,212,254,53,64 +.byte 247,247,251,247,235,12,243,28 +.byte 247,247,251,247,235,12,243,28 +.byte 185,185,222,185,161,103,111,24 +.byte 185,185,222,185,161,103,111,24 +.byte 19,19,76,19,152,95,38,139 +.byte 19,19,76,19,152,95,38,139 +.byte 44,44,176,44,125,156,88,81 +.byte 44,44,176,44,125,156,88,81 +.byte 211,211,107,211,214,184,187,5 +.byte 211,211,107,211,214,184,187,5 +.byte 231,231,187,231,107,92,211,140 +.byte 231,231,187,231,107,92,211,140 +.byte 110,110,165,110,87,203,220,57 +.byte 110,110,165,110,87,203,220,57 +.byte 196,196,55,196,110,243,149,170 +.byte 196,196,55,196,110,243,149,170 +.byte 3,3,12,3,24,15,6,27 +.byte 3,3,12,3,24,15,6,27 +.byte 86,86,69,86,138,19,172,220 +.byte 86,86,69,86,138,19,172,220 +.byte 68,68,13,68,26,73,136,94 +.byte 68,68,13,68,26,73,136,94 +.byte 127,127,225,127,223,158,254,160 +.byte 127,127,225,127,223,158,254,160 +.byte 169,169,158,169,33,55,79,136 +.byte 169,169,158,169,33,55,79,136 +.byte 42,42,168,42,77,130,84,103 +.byte 42,42,168,42,77,130,84,103 +.byte 187,187,214,187,177,109,107,10 +.byte 187,187,214,187,177,109,107,10 +.byte 193,193,35,193,70,226,159,135 +.byte 193,193,35,193,70,226,159,135 +.byte 83,83,81,83,162,2,166,241 +.byte 83,83,81,83,162,2,166,241 +.byte 220,220,87,220,174,139,165,114 +.byte 220,220,87,220,174,139,165,114 +.byte 11,11,44,11,88,39,22,83 +.byte 11,11,44,11,88,39,22,83 +.byte 157,157,78,157,156,211,39,1 +.byte 157,157,78,157,156,211,39,1 +.byte 108,108,173,108,71,193,216,43 +.byte 108,108,173,108,71,193,216,43 +.byte 49,49,196,49,149,245,98,164 +.byte 49,49,196,49,149,245,98,164 +.byte 116,116,205,116,135,185,232,243 +.byte 116,116,205,116,135,185,232,243 +.byte 246,246,255,246,227,9,241,21 +.byte 246,246,255,246,227,9,241,21 +.byte 70,70,5,70,10,67,140,76 +.byte 70,70,5,70,10,67,140,76 +.byte 172,172,138,172,9,38,69,165 +.byte 172,172,138,172,9,38,69,165 +.byte 137,137,30,137,60,151,15,181 +.byte 137,137,30,137,60,151,15,181 +.byte 20,20,80,20,160,68,40,180 +.byte 20,20,80,20,160,68,40,180 +.byte 225,225,163,225,91,66,223,186 +.byte 225,225,163,225,91,66,223,186 +.byte 22,22,88,22,176,78,44,166 +.byte 22,22,88,22,176,78,44,166 +.byte 58,58,232,58,205,210,116,247 +.byte 58,58,232,58,205,210,116,247 +.byte 105,105,185,105,111,208,210,6 +.byte 105,105,185,105,111,208,210,6 +.byte 9,9,36,9,72,45,18,65 +.byte 9,9,36,9,72,45,18,65 +.byte 112,112,221,112,167,173,224,215 +.byte 112,112,221,112,167,173,224,215 +.byte 182,182,226,182,217,84,113,111 +.byte 182,182,226,182,217,84,113,111 +.byte 208,208,103,208,206,183,189,30 +.byte 208,208,103,208,206,183,189,30 +.byte 237,237,147,237,59,126,199,214 +.byte 237,237,147,237,59,126,199,214 +.byte 204,204,23,204,46,219,133,226 +.byte 204,204,23,204,46,219,133,226 +.byte 66,66,21,66,42,87,132,104 +.byte 66,66,21,66,42,87,132,104 +.byte 152,152,90,152,180,194,45,44 +.byte 152,152,90,152,180,194,45,44 +.byte 164,164,170,164,73,14,85,237 +.byte 164,164,170,164,73,14,85,237 +.byte 40,40,160,40,93,136,80,117 +.byte 40,40,160,40,93,136,80,117 +.byte 92,92,109,92,218,49,184,134 +.byte 92,92,109,92,218,49,184,134 +.byte 248,248,199,248,147,63,237,107 +.byte 248,248,199,248,147,63,237,107 +.byte 134,134,34,134,68,164,17,194 +.byte 134,134,34,134,68,164,17,194 +.byte 24,35,198,232,135,184,1,79 +.byte 54,166,210,245,121,111,145,82 +.byte 96,188,155,142,163,12,123,53 +.byte 29,224,215,194,46,75,254,87 +.byte 21,119,55,229,159,240,74,218 +.byte 88,201,41,10,177,160,107,133 +.byte 189,93,16,244,203,62,5,103 +.byte 228,39,65,139,167,125,149,216 +.byte 251,238,124,102,221,23,71,158 +.byte 202,45,191,7,173,90,131,51 +.size whirlpool_block_mmx,.-.L_whirlpool_block_mmx_begin + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/whrlpool/wp-x86_64.S b/crypto/openssl/crypto/whrlpool/wp-x86_64.S new file mode 100644 index 000000000000..5e236f948185 --- /dev/null +++ b/crypto/openssl/crypto/whrlpool/wp-x86_64.S @@ -0,0 +1,900 @@ +.text + +.globl whirlpool_block +.type whirlpool_block,@function +.align 16 +whirlpool_block: +.cfi_startproc + movq %rsp,%rax +.cfi_def_cfa_register %rax + pushq %rbx +.cfi_offset %rbx,-16 + pushq %rbp +.cfi_offset %rbp,-24 + pushq %r12 +.cfi_offset %r12,-32 + pushq %r13 +.cfi_offset %r13,-40 + pushq %r14 +.cfi_offset %r14,-48 + pushq %r15 +.cfi_offset %r15,-56 + + subq $128+40,%rsp + andq $-64,%rsp + + leaq 128(%rsp),%r10 + movq %rdi,0(%r10) + movq %rsi,8(%r10) + movq %rdx,16(%r10) + movq %rax,32(%r10) +.cfi_escape 0x0f,0x06,0x77,0xa0,0x01,0x06,0x23,0x08 +.Lprologue: + + movq %r10,%rbx + leaq .Ltable(%rip),%rbp + + xorq %rcx,%rcx + xorq %rdx,%rdx + movq 0(%rdi),%r8 + movq 8(%rdi),%r9 + movq 16(%rdi),%r10 + movq 24(%rdi),%r11 + movq 32(%rdi),%r12 + movq 40(%rdi),%r13 + movq 48(%rdi),%r14 + movq 56(%rdi),%r15 +.Louterloop: + movq %r8,0(%rsp) + movq %r9,8(%rsp) + movq %r10,16(%rsp) + movq %r11,24(%rsp) + movq %r12,32(%rsp) + movq %r13,40(%rsp) + movq %r14,48(%rsp) + movq %r15,56(%rsp) + xorq 0(%rsi),%r8 + xorq 8(%rsi),%r9 + xorq 16(%rsi),%r10 + xorq 24(%rsi),%r11 + xorq 32(%rsi),%r12 + xorq 40(%rsi),%r13 + xorq 48(%rsi),%r14 + xorq 56(%rsi),%r15 + movq %r8,64+0(%rsp) + movq %r9,64+8(%rsp) + movq %r10,64+16(%rsp) + movq %r11,64+24(%rsp) + movq %r12,64+32(%rsp) + movq %r13,64+40(%rsp) + movq %r14,64+48(%rsp) + movq %r15,64+56(%rsp) + xorq %rsi,%rsi + movq %rsi,24(%rbx) + jmp .Lround +.align 16 +.Lround: + movq 4096(%rbp,%rsi,8),%r8 + movl 0(%rsp),%eax + movl 4(%rsp),%ebx + movzbl %al,%ecx + movzbl %ah,%edx + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r8 + movq 7(%rbp,%rdi,8),%r9 + movl 0+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + movq 6(%rbp,%rsi,8),%r10 + movq 5(%rbp,%rdi,8),%r11 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + movq 4(%rbp,%rsi,8),%r12 + movq 3(%rbp,%rdi,8),%r13 + movl 0+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + movq 2(%rbp,%rsi,8),%r14 + movq 1(%rbp,%rdi,8),%r15 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r9 + xorq 7(%rbp,%rdi,8),%r10 + movl 8+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r11 + xorq 5(%rbp,%rdi,8),%r12 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r13 + xorq 3(%rbp,%rdi,8),%r14 + movl 8+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r15 + xorq 1(%rbp,%rdi,8),%r8 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r10 + xorq 7(%rbp,%rdi,8),%r11 + movl 16+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r12 + xorq 5(%rbp,%rdi,8),%r13 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r14 + xorq 3(%rbp,%rdi,8),%r15 + movl 16+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r8 + xorq 1(%rbp,%rdi,8),%r9 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r11 + xorq 7(%rbp,%rdi,8),%r12 + movl 24+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r13 + xorq 5(%rbp,%rdi,8),%r14 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r15 + xorq 3(%rbp,%rdi,8),%r8 + movl 24+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r9 + xorq 1(%rbp,%rdi,8),%r10 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r12 + xorq 7(%rbp,%rdi,8),%r13 + movl 32+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r14 + xorq 5(%rbp,%rdi,8),%r15 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r8 + xorq 3(%rbp,%rdi,8),%r9 + movl 32+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r10 + xorq 1(%rbp,%rdi,8),%r11 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r13 + xorq 7(%rbp,%rdi,8),%r14 + movl 40+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r15 + xorq 5(%rbp,%rdi,8),%r8 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r9 + xorq 3(%rbp,%rdi,8),%r10 + movl 40+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r11 + xorq 1(%rbp,%rdi,8),%r12 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r14 + xorq 7(%rbp,%rdi,8),%r15 + movl 48+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r8 + xorq 5(%rbp,%rdi,8),%r9 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r10 + xorq 3(%rbp,%rdi,8),%r11 + movl 48+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r12 + xorq 1(%rbp,%rdi,8),%r13 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r15 + xorq 7(%rbp,%rdi,8),%r8 + movl 56+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r9 + xorq 5(%rbp,%rdi,8),%r10 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r11 + xorq 3(%rbp,%rdi,8),%r12 + movl 56+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r13 + xorq 1(%rbp,%rdi,8),%r14 + movq %r8,0(%rsp) + movq %r9,8(%rsp) + movq %r10,16(%rsp) + movq %r11,24(%rsp) + movq %r12,32(%rsp) + movq %r13,40(%rsp) + movq %r14,48(%rsp) + movq %r15,56(%rsp) + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r8 + xorq 7(%rbp,%rdi,8),%r9 + movl 64+0+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r10 + xorq 5(%rbp,%rdi,8),%r11 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r12 + xorq 3(%rbp,%rdi,8),%r13 + movl 64+0+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r14 + xorq 1(%rbp,%rdi,8),%r15 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r9 + xorq 7(%rbp,%rdi,8),%r10 + movl 64+8+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r11 + xorq 5(%rbp,%rdi,8),%r12 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r13 + xorq 3(%rbp,%rdi,8),%r14 + movl 64+8+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r15 + xorq 1(%rbp,%rdi,8),%r8 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r10 + xorq 7(%rbp,%rdi,8),%r11 + movl 64+16+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r12 + xorq 5(%rbp,%rdi,8),%r13 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r14 + xorq 3(%rbp,%rdi,8),%r15 + movl 64+16+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r8 + xorq 1(%rbp,%rdi,8),%r9 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r11 + xorq 7(%rbp,%rdi,8),%r12 + movl 64+24+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r13 + xorq 5(%rbp,%rdi,8),%r14 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r15 + xorq 3(%rbp,%rdi,8),%r8 + movl 64+24+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r9 + xorq 1(%rbp,%rdi,8),%r10 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r12 + xorq 7(%rbp,%rdi,8),%r13 + movl 64+32+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r14 + xorq 5(%rbp,%rdi,8),%r15 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r8 + xorq 3(%rbp,%rdi,8),%r9 + movl 64+32+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r10 + xorq 1(%rbp,%rdi,8),%r11 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r13 + xorq 7(%rbp,%rdi,8),%r14 + movl 64+40+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r15 + xorq 5(%rbp,%rdi,8),%r8 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r9 + xorq 3(%rbp,%rdi,8),%r10 + movl 64+40+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r11 + xorq 1(%rbp,%rdi,8),%r12 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r14 + xorq 7(%rbp,%rdi,8),%r15 + movl 64+48+8(%rsp),%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r8 + xorq 5(%rbp,%rdi,8),%r9 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r10 + xorq 3(%rbp,%rdi,8),%r11 + movl 64+48+8+4(%rsp),%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r12 + xorq 1(%rbp,%rdi,8),%r13 + shrl $16,%eax + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 0(%rbp,%rsi,8),%r15 + xorq 7(%rbp,%rdi,8),%r8 + + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 6(%rbp,%rsi,8),%r9 + xorq 5(%rbp,%rdi,8),%r10 + shrl $16,%ebx + leaq (%rcx,%rcx,1),%rsi + movzbl %bl,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %bh,%edx + xorq 4(%rbp,%rsi,8),%r11 + xorq 3(%rbp,%rdi,8),%r12 + + leaq (%rcx,%rcx,1),%rsi + movzbl %al,%ecx + leaq (%rdx,%rdx,1),%rdi + movzbl %ah,%edx + xorq 2(%rbp,%rsi,8),%r13 + xorq 1(%rbp,%rdi,8),%r14 + leaq 128(%rsp),%rbx + movq 24(%rbx),%rsi + addq $1,%rsi + cmpq $10,%rsi + je .Lroundsdone + + movq %rsi,24(%rbx) + movq %r8,64+0(%rsp) + movq %r9,64+8(%rsp) + movq %r10,64+16(%rsp) + movq %r11,64+24(%rsp) + movq %r12,64+32(%rsp) + movq %r13,64+40(%rsp) + movq %r14,64+48(%rsp) + movq %r15,64+56(%rsp) + jmp .Lround +.align 16 +.Lroundsdone: + movq 0(%rbx),%rdi + movq 8(%rbx),%rsi + movq 16(%rbx),%rax + xorq 0(%rsi),%r8 + xorq 8(%rsi),%r9 + xorq 16(%rsi),%r10 + xorq 24(%rsi),%r11 + xorq 32(%rsi),%r12 + xorq 40(%rsi),%r13 + xorq 48(%rsi),%r14 + xorq 56(%rsi),%r15 + xorq 0(%rdi),%r8 + xorq 8(%rdi),%r9 + xorq 16(%rdi),%r10 + xorq 24(%rdi),%r11 + xorq 32(%rdi),%r12 + xorq 40(%rdi),%r13 + xorq 48(%rdi),%r14 + xorq 56(%rdi),%r15 + movq %r8,0(%rdi) + movq %r9,8(%rdi) + movq %r10,16(%rdi) + movq %r11,24(%rdi) + movq %r12,32(%rdi) + movq %r13,40(%rdi) + movq %r14,48(%rdi) + movq %r15,56(%rdi) + leaq 64(%rsi),%rsi + subq $1,%rax + jz .Lalldone + movq %rsi,8(%rbx) + movq %rax,16(%rbx) + jmp .Louterloop +.Lalldone: + movq 32(%rbx),%rsi +.cfi_def_cfa %rsi,8 + movq -48(%rsi),%r15 +.cfi_restore %r15 + movq -40(%rsi),%r14 +.cfi_restore %r14 + movq -32(%rsi),%r13 +.cfi_restore %r13 + movq -24(%rsi),%r12 +.cfi_restore %r12 + movq -16(%rsi),%rbp +.cfi_restore %rbp + movq -8(%rsi),%rbx +.cfi_restore %rbx + leaq (%rsi),%rsp +.cfi_def_cfa_register %rsp +.Lepilogue: + .byte 0xf3,0xc3 +.cfi_endproc +.size whirlpool_block,.-whirlpool_block + +.align 64 +.type .Ltable,@object +.Ltable: +.byte 24,24,96,24,192,120,48,216,24,24,96,24,192,120,48,216 +.byte 35,35,140,35,5,175,70,38,35,35,140,35,5,175,70,38 +.byte 198,198,63,198,126,249,145,184,198,198,63,198,126,249,145,184 +.byte 232,232,135,232,19,111,205,251,232,232,135,232,19,111,205,251 +.byte 135,135,38,135,76,161,19,203,135,135,38,135,76,161,19,203 +.byte 184,184,218,184,169,98,109,17,184,184,218,184,169,98,109,17 +.byte 1,1,4,1,8,5,2,9,1,1,4,1,8,5,2,9 +.byte 79,79,33,79,66,110,158,13,79,79,33,79,66,110,158,13 +.byte 54,54,216,54,173,238,108,155,54,54,216,54,173,238,108,155 +.byte 166,166,162,166,89,4,81,255,166,166,162,166,89,4,81,255 +.byte 210,210,111,210,222,189,185,12,210,210,111,210,222,189,185,12 +.byte 245,245,243,245,251,6,247,14,245,245,243,245,251,6,247,14 +.byte 121,121,249,121,239,128,242,150,121,121,249,121,239,128,242,150 +.byte 111,111,161,111,95,206,222,48,111,111,161,111,95,206,222,48 +.byte 145,145,126,145,252,239,63,109,145,145,126,145,252,239,63,109 +.byte 82,82,85,82,170,7,164,248,82,82,85,82,170,7,164,248 +.byte 96,96,157,96,39,253,192,71,96,96,157,96,39,253,192,71 +.byte 188,188,202,188,137,118,101,53,188,188,202,188,137,118,101,53 +.byte 155,155,86,155,172,205,43,55,155,155,86,155,172,205,43,55 +.byte 142,142,2,142,4,140,1,138,142,142,2,142,4,140,1,138 +.byte 163,163,182,163,113,21,91,210,163,163,182,163,113,21,91,210 +.byte 12,12,48,12,96,60,24,108,12,12,48,12,96,60,24,108 +.byte 123,123,241,123,255,138,246,132,123,123,241,123,255,138,246,132 +.byte 53,53,212,53,181,225,106,128,53,53,212,53,181,225,106,128 +.byte 29,29,116,29,232,105,58,245,29,29,116,29,232,105,58,245 +.byte 224,224,167,224,83,71,221,179,224,224,167,224,83,71,221,179 +.byte 215,215,123,215,246,172,179,33,215,215,123,215,246,172,179,33 +.byte 194,194,47,194,94,237,153,156,194,194,47,194,94,237,153,156 +.byte 46,46,184,46,109,150,92,67,46,46,184,46,109,150,92,67 +.byte 75,75,49,75,98,122,150,41,75,75,49,75,98,122,150,41 +.byte 254,254,223,254,163,33,225,93,254,254,223,254,163,33,225,93 +.byte 87,87,65,87,130,22,174,213,87,87,65,87,130,22,174,213 +.byte 21,21,84,21,168,65,42,189,21,21,84,21,168,65,42,189 +.byte 119,119,193,119,159,182,238,232,119,119,193,119,159,182,238,232 +.byte 55,55,220,55,165,235,110,146,55,55,220,55,165,235,110,146 +.byte 229,229,179,229,123,86,215,158,229,229,179,229,123,86,215,158 +.byte 159,159,70,159,140,217,35,19,159,159,70,159,140,217,35,19 +.byte 240,240,231,240,211,23,253,35,240,240,231,240,211,23,253,35 +.byte 74,74,53,74,106,127,148,32,74,74,53,74,106,127,148,32 +.byte 218,218,79,218,158,149,169,68,218,218,79,218,158,149,169,68 +.byte 88,88,125,88,250,37,176,162,88,88,125,88,250,37,176,162 +.byte 201,201,3,201,6,202,143,207,201,201,3,201,6,202,143,207 +.byte 41,41,164,41,85,141,82,124,41,41,164,41,85,141,82,124 +.byte 10,10,40,10,80,34,20,90,10,10,40,10,80,34,20,90 +.byte 177,177,254,177,225,79,127,80,177,177,254,177,225,79,127,80 +.byte 160,160,186,160,105,26,93,201,160,160,186,160,105,26,93,201 +.byte 107,107,177,107,127,218,214,20,107,107,177,107,127,218,214,20 +.byte 133,133,46,133,92,171,23,217,133,133,46,133,92,171,23,217 +.byte 189,189,206,189,129,115,103,60,189,189,206,189,129,115,103,60 +.byte 93,93,105,93,210,52,186,143,93,93,105,93,210,52,186,143 +.byte 16,16,64,16,128,80,32,144,16,16,64,16,128,80,32,144 +.byte 244,244,247,244,243,3,245,7,244,244,247,244,243,3,245,7 +.byte 203,203,11,203,22,192,139,221,203,203,11,203,22,192,139,221 +.byte 62,62,248,62,237,198,124,211,62,62,248,62,237,198,124,211 +.byte 5,5,20,5,40,17,10,45,5,5,20,5,40,17,10,45 +.byte 103,103,129,103,31,230,206,120,103,103,129,103,31,230,206,120 +.byte 228,228,183,228,115,83,213,151,228,228,183,228,115,83,213,151 +.byte 39,39,156,39,37,187,78,2,39,39,156,39,37,187,78,2 +.byte 65,65,25,65,50,88,130,115,65,65,25,65,50,88,130,115 +.byte 139,139,22,139,44,157,11,167,139,139,22,139,44,157,11,167 +.byte 167,167,166,167,81,1,83,246,167,167,166,167,81,1,83,246 +.byte 125,125,233,125,207,148,250,178,125,125,233,125,207,148,250,178 +.byte 149,149,110,149,220,251,55,73,149,149,110,149,220,251,55,73 +.byte 216,216,71,216,142,159,173,86,216,216,71,216,142,159,173,86 +.byte 251,251,203,251,139,48,235,112,251,251,203,251,139,48,235,112 +.byte 238,238,159,238,35,113,193,205,238,238,159,238,35,113,193,205 +.byte 124,124,237,124,199,145,248,187,124,124,237,124,199,145,248,187 +.byte 102,102,133,102,23,227,204,113,102,102,133,102,23,227,204,113 +.byte 221,221,83,221,166,142,167,123,221,221,83,221,166,142,167,123 +.byte 23,23,92,23,184,75,46,175,23,23,92,23,184,75,46,175 +.byte 71,71,1,71,2,70,142,69,71,71,1,71,2,70,142,69 +.byte 158,158,66,158,132,220,33,26,158,158,66,158,132,220,33,26 +.byte 202,202,15,202,30,197,137,212,202,202,15,202,30,197,137,212 +.byte 45,45,180,45,117,153,90,88,45,45,180,45,117,153,90,88 +.byte 191,191,198,191,145,121,99,46,191,191,198,191,145,121,99,46 +.byte 7,7,28,7,56,27,14,63,7,7,28,7,56,27,14,63 +.byte 173,173,142,173,1,35,71,172,173,173,142,173,1,35,71,172 +.byte 90,90,117,90,234,47,180,176,90,90,117,90,234,47,180,176 +.byte 131,131,54,131,108,181,27,239,131,131,54,131,108,181,27,239 +.byte 51,51,204,51,133,255,102,182,51,51,204,51,133,255,102,182 +.byte 99,99,145,99,63,242,198,92,99,99,145,99,63,242,198,92 +.byte 2,2,8,2,16,10,4,18,2,2,8,2,16,10,4,18 +.byte 170,170,146,170,57,56,73,147,170,170,146,170,57,56,73,147 +.byte 113,113,217,113,175,168,226,222,113,113,217,113,175,168,226,222 +.byte 200,200,7,200,14,207,141,198,200,200,7,200,14,207,141,198 +.byte 25,25,100,25,200,125,50,209,25,25,100,25,200,125,50,209 +.byte 73,73,57,73,114,112,146,59,73,73,57,73,114,112,146,59 +.byte 217,217,67,217,134,154,175,95,217,217,67,217,134,154,175,95 +.byte 242,242,239,242,195,29,249,49,242,242,239,242,195,29,249,49 +.byte 227,227,171,227,75,72,219,168,227,227,171,227,75,72,219,168 +.byte 91,91,113,91,226,42,182,185,91,91,113,91,226,42,182,185 +.byte 136,136,26,136,52,146,13,188,136,136,26,136,52,146,13,188 +.byte 154,154,82,154,164,200,41,62,154,154,82,154,164,200,41,62 +.byte 38,38,152,38,45,190,76,11,38,38,152,38,45,190,76,11 +.byte 50,50,200,50,141,250,100,191,50,50,200,50,141,250,100,191 +.byte 176,176,250,176,233,74,125,89,176,176,250,176,233,74,125,89 +.byte 233,233,131,233,27,106,207,242,233,233,131,233,27,106,207,242 +.byte 15,15,60,15,120,51,30,119,15,15,60,15,120,51,30,119 +.byte 213,213,115,213,230,166,183,51,213,213,115,213,230,166,183,51 +.byte 128,128,58,128,116,186,29,244,128,128,58,128,116,186,29,244 +.byte 190,190,194,190,153,124,97,39,190,190,194,190,153,124,97,39 +.byte 205,205,19,205,38,222,135,235,205,205,19,205,38,222,135,235 +.byte 52,52,208,52,189,228,104,137,52,52,208,52,189,228,104,137 +.byte 72,72,61,72,122,117,144,50,72,72,61,72,122,117,144,50 +.byte 255,255,219,255,171,36,227,84,255,255,219,255,171,36,227,84 +.byte 122,122,245,122,247,143,244,141,122,122,245,122,247,143,244,141 +.byte 144,144,122,144,244,234,61,100,144,144,122,144,244,234,61,100 +.byte 95,95,97,95,194,62,190,157,95,95,97,95,194,62,190,157 +.byte 32,32,128,32,29,160,64,61,32,32,128,32,29,160,64,61 +.byte 104,104,189,104,103,213,208,15,104,104,189,104,103,213,208,15 +.byte 26,26,104,26,208,114,52,202,26,26,104,26,208,114,52,202 +.byte 174,174,130,174,25,44,65,183,174,174,130,174,25,44,65,183 +.byte 180,180,234,180,201,94,117,125,180,180,234,180,201,94,117,125 +.byte 84,84,77,84,154,25,168,206,84,84,77,84,154,25,168,206 +.byte 147,147,118,147,236,229,59,127,147,147,118,147,236,229,59,127 +.byte 34,34,136,34,13,170,68,47,34,34,136,34,13,170,68,47 +.byte 100,100,141,100,7,233,200,99,100,100,141,100,7,233,200,99 +.byte 241,241,227,241,219,18,255,42,241,241,227,241,219,18,255,42 +.byte 115,115,209,115,191,162,230,204,115,115,209,115,191,162,230,204 +.byte 18,18,72,18,144,90,36,130,18,18,72,18,144,90,36,130 +.byte 64,64,29,64,58,93,128,122,64,64,29,64,58,93,128,122 +.byte 8,8,32,8,64,40,16,72,8,8,32,8,64,40,16,72 +.byte 195,195,43,195,86,232,155,149,195,195,43,195,86,232,155,149 +.byte 236,236,151,236,51,123,197,223,236,236,151,236,51,123,197,223 +.byte 219,219,75,219,150,144,171,77,219,219,75,219,150,144,171,77 +.byte 161,161,190,161,97,31,95,192,161,161,190,161,97,31,95,192 +.byte 141,141,14,141,28,131,7,145,141,141,14,141,28,131,7,145 +.byte 61,61,244,61,245,201,122,200,61,61,244,61,245,201,122,200 +.byte 151,151,102,151,204,241,51,91,151,151,102,151,204,241,51,91 +.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.byte 207,207,27,207,54,212,131,249,207,207,27,207,54,212,131,249 +.byte 43,43,172,43,69,135,86,110,43,43,172,43,69,135,86,110 +.byte 118,118,197,118,151,179,236,225,118,118,197,118,151,179,236,225 +.byte 130,130,50,130,100,176,25,230,130,130,50,130,100,176,25,230 +.byte 214,214,127,214,254,169,177,40,214,214,127,214,254,169,177,40 +.byte 27,27,108,27,216,119,54,195,27,27,108,27,216,119,54,195 +.byte 181,181,238,181,193,91,119,116,181,181,238,181,193,91,119,116 +.byte 175,175,134,175,17,41,67,190,175,175,134,175,17,41,67,190 +.byte 106,106,181,106,119,223,212,29,106,106,181,106,119,223,212,29 +.byte 80,80,93,80,186,13,160,234,80,80,93,80,186,13,160,234 +.byte 69,69,9,69,18,76,138,87,69,69,9,69,18,76,138,87 +.byte 243,243,235,243,203,24,251,56,243,243,235,243,203,24,251,56 +.byte 48,48,192,48,157,240,96,173,48,48,192,48,157,240,96,173 +.byte 239,239,155,239,43,116,195,196,239,239,155,239,43,116,195,196 +.byte 63,63,252,63,229,195,126,218,63,63,252,63,229,195,126,218 +.byte 85,85,73,85,146,28,170,199,85,85,73,85,146,28,170,199 +.byte 162,162,178,162,121,16,89,219,162,162,178,162,121,16,89,219 +.byte 234,234,143,234,3,101,201,233,234,234,143,234,3,101,201,233 +.byte 101,101,137,101,15,236,202,106,101,101,137,101,15,236,202,106 +.byte 186,186,210,186,185,104,105,3,186,186,210,186,185,104,105,3 +.byte 47,47,188,47,101,147,94,74,47,47,188,47,101,147,94,74 +.byte 192,192,39,192,78,231,157,142,192,192,39,192,78,231,157,142 +.byte 222,222,95,222,190,129,161,96,222,222,95,222,190,129,161,96 +.byte 28,28,112,28,224,108,56,252,28,28,112,28,224,108,56,252 +.byte 253,253,211,253,187,46,231,70,253,253,211,253,187,46,231,70 +.byte 77,77,41,77,82,100,154,31,77,77,41,77,82,100,154,31 +.byte 146,146,114,146,228,224,57,118,146,146,114,146,228,224,57,118 +.byte 117,117,201,117,143,188,234,250,117,117,201,117,143,188,234,250 +.byte 6,6,24,6,48,30,12,54,6,6,24,6,48,30,12,54 +.byte 138,138,18,138,36,152,9,174,138,138,18,138,36,152,9,174 +.byte 178,178,242,178,249,64,121,75,178,178,242,178,249,64,121,75 +.byte 230,230,191,230,99,89,209,133,230,230,191,230,99,89,209,133 +.byte 14,14,56,14,112,54,28,126,14,14,56,14,112,54,28,126 +.byte 31,31,124,31,248,99,62,231,31,31,124,31,248,99,62,231 +.byte 98,98,149,98,55,247,196,85,98,98,149,98,55,247,196,85 +.byte 212,212,119,212,238,163,181,58,212,212,119,212,238,163,181,58 +.byte 168,168,154,168,41,50,77,129,168,168,154,168,41,50,77,129 +.byte 150,150,98,150,196,244,49,82,150,150,98,150,196,244,49,82 +.byte 249,249,195,249,155,58,239,98,249,249,195,249,155,58,239,98 +.byte 197,197,51,197,102,246,151,163,197,197,51,197,102,246,151,163 +.byte 37,37,148,37,53,177,74,16,37,37,148,37,53,177,74,16 +.byte 89,89,121,89,242,32,178,171,89,89,121,89,242,32,178,171 +.byte 132,132,42,132,84,174,21,208,132,132,42,132,84,174,21,208 +.byte 114,114,213,114,183,167,228,197,114,114,213,114,183,167,228,197 +.byte 57,57,228,57,213,221,114,236,57,57,228,57,213,221,114,236 +.byte 76,76,45,76,90,97,152,22,76,76,45,76,90,97,152,22 +.byte 94,94,101,94,202,59,188,148,94,94,101,94,202,59,188,148 +.byte 120,120,253,120,231,133,240,159,120,120,253,120,231,133,240,159 +.byte 56,56,224,56,221,216,112,229,56,56,224,56,221,216,112,229 +.byte 140,140,10,140,20,134,5,152,140,140,10,140,20,134,5,152 +.byte 209,209,99,209,198,178,191,23,209,209,99,209,198,178,191,23 +.byte 165,165,174,165,65,11,87,228,165,165,174,165,65,11,87,228 +.byte 226,226,175,226,67,77,217,161,226,226,175,226,67,77,217,161 +.byte 97,97,153,97,47,248,194,78,97,97,153,97,47,248,194,78 +.byte 179,179,246,179,241,69,123,66,179,179,246,179,241,69,123,66 +.byte 33,33,132,33,21,165,66,52,33,33,132,33,21,165,66,52 +.byte 156,156,74,156,148,214,37,8,156,156,74,156,148,214,37,8 +.byte 30,30,120,30,240,102,60,238,30,30,120,30,240,102,60,238 +.byte 67,67,17,67,34,82,134,97,67,67,17,67,34,82,134,97 +.byte 199,199,59,199,118,252,147,177,199,199,59,199,118,252,147,177 +.byte 252,252,215,252,179,43,229,79,252,252,215,252,179,43,229,79 +.byte 4,4,16,4,32,20,8,36,4,4,16,4,32,20,8,36 +.byte 81,81,89,81,178,8,162,227,81,81,89,81,178,8,162,227 +.byte 153,153,94,153,188,199,47,37,153,153,94,153,188,199,47,37 +.byte 109,109,169,109,79,196,218,34,109,109,169,109,79,196,218,34 +.byte 13,13,52,13,104,57,26,101,13,13,52,13,104,57,26,101 +.byte 250,250,207,250,131,53,233,121,250,250,207,250,131,53,233,121 +.byte 223,223,91,223,182,132,163,105,223,223,91,223,182,132,163,105 +.byte 126,126,229,126,215,155,252,169,126,126,229,126,215,155,252,169 +.byte 36,36,144,36,61,180,72,25,36,36,144,36,61,180,72,25 +.byte 59,59,236,59,197,215,118,254,59,59,236,59,197,215,118,254 +.byte 171,171,150,171,49,61,75,154,171,171,150,171,49,61,75,154 +.byte 206,206,31,206,62,209,129,240,206,206,31,206,62,209,129,240 +.byte 17,17,68,17,136,85,34,153,17,17,68,17,136,85,34,153 +.byte 143,143,6,143,12,137,3,131,143,143,6,143,12,137,3,131 +.byte 78,78,37,78,74,107,156,4,78,78,37,78,74,107,156,4 +.byte 183,183,230,183,209,81,115,102,183,183,230,183,209,81,115,102 +.byte 235,235,139,235,11,96,203,224,235,235,139,235,11,96,203,224 +.byte 60,60,240,60,253,204,120,193,60,60,240,60,253,204,120,193 +.byte 129,129,62,129,124,191,31,253,129,129,62,129,124,191,31,253 +.byte 148,148,106,148,212,254,53,64,148,148,106,148,212,254,53,64 +.byte 247,247,251,247,235,12,243,28,247,247,251,247,235,12,243,28 +.byte 185,185,222,185,161,103,111,24,185,185,222,185,161,103,111,24 +.byte 19,19,76,19,152,95,38,139,19,19,76,19,152,95,38,139 +.byte 44,44,176,44,125,156,88,81,44,44,176,44,125,156,88,81 +.byte 211,211,107,211,214,184,187,5,211,211,107,211,214,184,187,5 +.byte 231,231,187,231,107,92,211,140,231,231,187,231,107,92,211,140 +.byte 110,110,165,110,87,203,220,57,110,110,165,110,87,203,220,57 +.byte 196,196,55,196,110,243,149,170,196,196,55,196,110,243,149,170 +.byte 3,3,12,3,24,15,6,27,3,3,12,3,24,15,6,27 +.byte 86,86,69,86,138,19,172,220,86,86,69,86,138,19,172,220 +.byte 68,68,13,68,26,73,136,94,68,68,13,68,26,73,136,94 +.byte 127,127,225,127,223,158,254,160,127,127,225,127,223,158,254,160 +.byte 169,169,158,169,33,55,79,136,169,169,158,169,33,55,79,136 +.byte 42,42,168,42,77,130,84,103,42,42,168,42,77,130,84,103 +.byte 187,187,214,187,177,109,107,10,187,187,214,187,177,109,107,10 +.byte 193,193,35,193,70,226,159,135,193,193,35,193,70,226,159,135 +.byte 83,83,81,83,162,2,166,241,83,83,81,83,162,2,166,241 +.byte 220,220,87,220,174,139,165,114,220,220,87,220,174,139,165,114 +.byte 11,11,44,11,88,39,22,83,11,11,44,11,88,39,22,83 +.byte 157,157,78,157,156,211,39,1,157,157,78,157,156,211,39,1 +.byte 108,108,173,108,71,193,216,43,108,108,173,108,71,193,216,43 +.byte 49,49,196,49,149,245,98,164,49,49,196,49,149,245,98,164 +.byte 116,116,205,116,135,185,232,243,116,116,205,116,135,185,232,243 +.byte 246,246,255,246,227,9,241,21,246,246,255,246,227,9,241,21 +.byte 70,70,5,70,10,67,140,76,70,70,5,70,10,67,140,76 +.byte 172,172,138,172,9,38,69,165,172,172,138,172,9,38,69,165 +.byte 137,137,30,137,60,151,15,181,137,137,30,137,60,151,15,181 +.byte 20,20,80,20,160,68,40,180,20,20,80,20,160,68,40,180 +.byte 225,225,163,225,91,66,223,186,225,225,163,225,91,66,223,186 +.byte 22,22,88,22,176,78,44,166,22,22,88,22,176,78,44,166 +.byte 58,58,232,58,205,210,116,247,58,58,232,58,205,210,116,247 +.byte 105,105,185,105,111,208,210,6,105,105,185,105,111,208,210,6 +.byte 9,9,36,9,72,45,18,65,9,9,36,9,72,45,18,65 +.byte 112,112,221,112,167,173,224,215,112,112,221,112,167,173,224,215 +.byte 182,182,226,182,217,84,113,111,182,182,226,182,217,84,113,111 +.byte 208,208,103,208,206,183,189,30,208,208,103,208,206,183,189,30 +.byte 237,237,147,237,59,126,199,214,237,237,147,237,59,126,199,214 +.byte 204,204,23,204,46,219,133,226,204,204,23,204,46,219,133,226 +.byte 66,66,21,66,42,87,132,104,66,66,21,66,42,87,132,104 +.byte 152,152,90,152,180,194,45,44,152,152,90,152,180,194,45,44 +.byte 164,164,170,164,73,14,85,237,164,164,170,164,73,14,85,237 +.byte 40,40,160,40,93,136,80,117,40,40,160,40,93,136,80,117 +.byte 92,92,109,92,218,49,184,134,92,92,109,92,218,49,184,134 +.byte 248,248,199,248,147,63,237,107,248,248,199,248,147,63,237,107 +.byte 134,134,34,134,68,164,17,194,134,134,34,134,68,164,17,194 +.byte 24,35,198,232,135,184,1,79 +.byte 54,166,210,245,121,111,145,82 +.byte 96,188,155,142,163,12,123,53 +.byte 29,224,215,194,46,75,254,87 +.byte 21,119,55,229,159,240,74,218 +.byte 88,201,41,10,177,160,107,133 +.byte 189,93,16,244,203,62,5,103 +.byte 228,39,65,139,167,125,149,216 +.byte 251,238,124,102,221,23,71,158 +.byte 202,45,191,7,173,90,131,51 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/whrlpool/wp_block.c b/crypto/openssl/crypto/whrlpool/wp_block.c index 39ad009c01bf..bcf7a199ed0e 100644 --- a/crypto/openssl/crypto/whrlpool/wp_block.c +++ b/crypto/openssl/crypto/whrlpool/wp_block.c @@ -1,7 +1,7 @@ /* - * Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -36,6 +36,13 @@ * */ +/* + * Whirlpool low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include "internal/cryptlib.h" #include "wp_local.h" #include @@ -89,7 +96,6 @@ typedef u64 u64_aX; # define OPENSSL_SMALL_FOOTPRINT # endif # define GO_FOR_MMX(ctx,inp,num) do { \ - extern unsigned long OPENSSL_ia32cap_P[]; \ void whirlpool_block_mmx(void *,const void *,size_t); \ if (!(OPENSSL_ia32cap_P[0] & (1<<23))) break; \ whirlpool_block_mmx(ctx->H.c,inp,num); return; \ @@ -159,7 +165,7 @@ typedef u64 u64_aX; */ /* * Note that every Cn macro expands as two loads: one byte load and - * one quadword load. One can argue that that many single-byte loads + * one quadword load. One can argue that many single-byte loads * is too excessive, as one could load a quadword and "milk" it for * eight 8-bit values instead. Well, yes, but in order to do so *and* * avoid excessive loads you have to accommodate a handful of 64-bit diff --git a/crypto/openssl/crypto/whrlpool/wp_dgst.c b/crypto/openssl/crypto/whrlpool/wp_dgst.c index e8a3392268aa..4a1d912d6290 100644 --- a/crypto/openssl/crypto/whrlpool/wp_dgst.c +++ b/crypto/openssl/crypto/whrlpool/wp_dgst.c @@ -1,7 +1,7 @@ /* - * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -52,6 +52,12 @@ * input. This is done for performance. */ +/* + * Whirlpool low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "wp_local.h" #include diff --git a/crypto/openssl/crypto/whrlpool/wp_local.h b/crypto/openssl/crypto/whrlpool/wp_local.h index 3a81cfd58c1a..73dc2a003da3 100644 --- a/crypto/openssl/crypto/whrlpool/wp_local.h +++ b/crypto/openssl/crypto/whrlpool/wp_local.h @@ -1,7 +1,7 @@ /* * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/x509/build.info b/crypto/openssl/crypto/x509/build.info index afd0b6134e52..8820f983bb3d 100644 --- a/crypto/openssl/crypto/x509/build.info +++ b/crypto/openssl/crypto/x509/build.info @@ -4,7 +4,18 @@ SOURCE[../../libcrypto]=\ x509_obj.c x509_req.c x509spki.c x509_vfy.c \ x509_set.c x509cset.c x509rset.c x509_err.c \ x509name.c x509_v3.c x509_ext.c x509_att.c \ - x509type.c x509_meth.c x509_lu.c x_all.c x509_txt.c \ - x509_trs.c by_file.c by_dir.c x509_vpm.c \ + x509_meth.c x509_lu.c x_all.c x509_txt.c \ + x509_trust.c by_file.c by_dir.c by_store.c x509_vpm.c \ x_crl.c t_crl.c x_req.c t_req.c x_x509.c t_x509.c \ - x_pubkey.c x_x509a.c x_attrib.c x_exten.c x_name.c + x_pubkey.c x_x509a.c x_attrib.c x_exten.c x_name.c \ + v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_utf8.c v3_lib.c \ + v3_prn.c v3_utl.c v3err.c v3_genn.c v3_san.c v3_skid.c v3_akid.c \ + v3_pku.c v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c \ + v3_info.c v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c \ + v3_pcia.c v3_pci.c v3_ist.c \ + pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \ + v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c + +IF[{- !$disabled{'deprecated-3.0'} -}] + SOURCE[../../libcrypto]=x509type.c +ENDIF diff --git a/crypto/openssl/crypto/x509/by_dir.c b/crypto/openssl/crypto/x509/by_dir.c index 46a861e90de0..cb40c7737f72 100644 --- a/crypto/openssl/crypto/x509/by_dir.c +++ b/crypto/openssl/crypto/x509/by_dir.c @@ -1,12 +1,21 @@ /* * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +#if defined (__TANDEM) && defined (_SPT_MODEL_) + /* + * These definitions have to come first in SPT due to scoping of the + * declarations in c99 associated with SPT use of stat. + */ +# include +# include +#endif + #include "e_os.h" #include "internal/cryptlib.h" #include @@ -40,23 +49,29 @@ typedef struct lookup_dir_st { } BY_DIR; static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, - char **ret); + char **retp); + static int new_dir(X509_LOOKUP *lu); static void free_dir(X509_LOOKUP *lu); static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, - X509_NAME *name, X509_OBJECT *ret); + const X509_NAME *name, X509_OBJECT *ret); +static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq); static X509_LOOKUP_METHOD x509_dir_lookup = { "Load certs from files in a directory", - new_dir, /* new_item */ - free_dir, /* free */ - NULL, /* init */ - NULL, /* shutdown */ - dir_ctrl, /* ctrl */ - get_cert_by_subject, /* get_by_subject */ - NULL, /* get_by_issuer_serial */ - NULL, /* get_by_fingerprint */ - NULL, /* get_by_alias */ + new_dir, /* new_item */ + free_dir, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + dir_ctrl, /* ctrl */ + get_cert_by_subject, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ + get_cert_by_subject_ex, /* get_by_subject_ex */ + NULL, /* ctrl_ex */ }; X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) @@ -81,7 +96,7 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, ret = add_cert_dir(ld, X509_get_default_cert_dir(), X509_FILETYPE_PEM); if (!ret) { - X509err(X509_F_DIR_CTRL, X509_R_LOADING_CERT_DIR); + ERR_raise(ERR_LIB_X509, X509_R_LOADING_CERT_DIR); } } else ret = add_cert_dir(ld, argp, (int)argl); @@ -95,19 +110,19 @@ static int new_dir(X509_LOOKUP *lu) BY_DIR *a = OPENSSL_malloc(sizeof(*a)); if (a == NULL) { - X509err(X509_F_NEW_DIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return 0; } if ((a->buffer = BUF_MEM_new()) == NULL) { - X509err(X509_F_NEW_DIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } a->dirs = NULL; a->lock = CRYPTO_THREAD_lock_new(); if (a->lock == NULL) { BUF_MEM_free(a->buffer); - X509err(X509_F_NEW_DIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } lu->method_data = a; @@ -156,8 +171,8 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) size_t len; const char *s, *ss, *p; - if (dir == NULL || !*dir) { - X509err(X509_F_ADD_CERT_DIR, X509_R_INVALID_DIRECTORY); + if (dir == NULL || *dir == '\0') { + ERR_raise(ERR_LIB_X509, X509_R_INVALID_DIRECTORY); return 0; } @@ -182,13 +197,13 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) if (ctx->dirs == NULL) { ctx->dirs = sk_BY_DIR_ENTRY_new_null(); if (!ctx->dirs) { - X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return 0; } } ent = OPENSSL_malloc(sizeof(*ent)); if (ent == NULL) { - X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return 0; } ent->dir_type = type; @@ -200,7 +215,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) } if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { by_dir_entry_free(ent); - X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return 0; } } @@ -208,8 +223,9 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) return 1; } -static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, - X509_NAME *name, X509_OBJECT *ret) +static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq) { BY_DIR *ctx; union { @@ -228,26 +244,26 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, stmp.type = type; if (type == X509_LU_X509) { - data.st_x509.cert_info.subject = name; + data.st_x509.cert_info.subject = (X509_NAME *)name; /* won't modify it */ stmp.data.x509 = &data.st_x509; - postfix = ""; } else if (type == X509_LU_CRL) { - data.crl.crl.issuer = name; + data.crl.crl.issuer = (X509_NAME *)name; /* won't modify it */ stmp.data.crl = &data.crl; postfix = "r"; } else { - X509err(X509_F_GET_CERT_BY_SUBJECT, X509_R_WRONG_LOOKUP_TYPE); + ERR_raise(ERR_LIB_X509, X509_R_WRONG_LOOKUP_TYPE); goto finish; } if ((b = BUF_MEM_new()) == NULL) { - X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); goto finish; } ctx = (BY_DIR *)xl->method_data; - - h = X509_NAME_hash(name); + h = X509_NAME_hash_ex(name, libctx, propq, &i); + if (i == 0) + goto finish; for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { BY_DIR_ENTRY *ent; int idx; @@ -256,12 +272,13 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; if (!BUF_MEM_grow(b, j)) { - X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto finish; } if (type == X509_LU_CRL && ent->hashes) { htmp.hash = h; - CRYPTO_THREAD_read_lock(ctx->lock); + if (!CRYPTO_THREAD_read_lock(ctx->lock)) + goto finish; idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); if (idx >= 0) { hent = sk_BY_DIR_HASH_value(ent->hashes, idx); @@ -277,6 +294,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, } for (;;) { char c = '/'; + #ifdef OPENSSL_SYS_VMS c = ent->dir[strlen(ent->dir) - 1]; if (c != ':' && c != '>' && c != ']') { @@ -290,7 +308,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, } else { c = '\0'; } -#endif + if (c == '\0') { /* * This is special. When c == '\0', no directory separator @@ -298,7 +316,9 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, */ BIO_snprintf(b->data, b->max, "%s%08lx.%s%d", ent->dir, h, postfix, k); - } else { + } else +#endif + { BIO_snprintf(b->data, b->max, "%s%c%08lx.%s%d", ent->dir, c, h, postfix, k); } @@ -314,7 +334,8 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, #endif /* found one. */ if (type == X509_LU_X509) { - if ((X509_load_cert_file(xl, b->data, ent->dir_type)) == 0) + if ((X509_load_cert_file_ex(xl, b->data, ent->dir_type, libctx, + propq)) == 0) break; } else if (type == X509_LU_CRL) { if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) @@ -339,7 +360,8 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, * simple case where no CRL is present for a hash. */ if (type == X509_LU_CRL && k > 0) { - CRYPTO_THREAD_write_lock(ctx->lock); + if (!CRYPTO_THREAD_write_lock(ctx->lock)) + goto finish; /* * Look for entry again in case another thread added an entry * first. @@ -353,7 +375,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, hent = OPENSSL_malloc(sizeof(*hent)); if (hent == NULL) { CRYPTO_THREAD_unlock(ctx->lock); - X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); ok = 0; goto finish; } @@ -362,7 +384,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { CRYPTO_THREAD_unlock(ctx->lock); OPENSSL_free(hent); - X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); ok = 0; goto finish; } @@ -398,3 +420,9 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, BUF_MEM_free(b); return ok; } + +static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret) +{ + return get_cert_by_subject_ex(xl, type, name, ret, NULL, NULL); +} diff --git a/crypto/openssl/crypto/x509/by_file.c b/crypto/openssl/crypto/x509/by_file.c index 237b362e2746..37d73ca84c54 100644 --- a/crypto/openssl/crypto/x509/by_file.c +++ b/crypto/openssl/crypto/x509/by_file.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,6 +19,11 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); +static int by_file_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret, OSSL_LIB_CTX *libctx, + const char *propq); + + static X509_LOOKUP_METHOD x509_file_lookup = { "Load file into cache", NULL, /* new_item */ @@ -30,6 +35,8 @@ static X509_LOOKUP_METHOD x509_file_lookup = { NULL, /* get_by_issuer_serial */ NULL, /* get_by_fingerprint */ NULL, /* get_by_alias */ + NULL, /* get_by_subject_ex */ + by_file_ctrl_ex, /* ctrl_ex */ }; X509_LOOKUP_METHOD *X509_LOOKUP_file(void) @@ -37,8 +44,9 @@ X509_LOOKUP_METHOD *X509_LOOKUP_file(void) return &x509_file_lookup; } -static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, - long argl, char **ret) +static int by_file_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp, + long argl, char **ret, OSSL_LIB_CTX *libctx, + const char *propq) { int ok = 0; const char *file; @@ -48,30 +56,38 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, if (argl == X509_FILETYPE_DEFAULT) { file = ossl_safe_getenv(X509_get_default_cert_file_env()); if (file) - ok = (X509_load_cert_crl_file(ctx, file, - X509_FILETYPE_PEM) != 0); + ok = (X509_load_cert_crl_file_ex(ctx, file, X509_FILETYPE_PEM, + libctx, propq) != 0); else - ok = (X509_load_cert_crl_file - (ctx, X509_get_default_cert_file(), - X509_FILETYPE_PEM) != 0); + ok = (X509_load_cert_crl_file_ex( + ctx, X509_get_default_cert_file(), + X509_FILETYPE_PEM, libctx, propq) != 0); if (!ok) { - X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS); + ERR_raise(ERR_LIB_X509, X509_R_LOADING_DEFAULTS); } } else { if (argl == X509_FILETYPE_PEM) - ok = (X509_load_cert_crl_file(ctx, argp, - X509_FILETYPE_PEM) != 0); + ok = (X509_load_cert_crl_file_ex(ctx, argp, X509_FILETYPE_PEM, + libctx, propq) != 0); else - ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); + ok = (X509_load_cert_file_ex(ctx, argp, (int)argl, libctx, + propq) != 0); } break; } return ok; } -int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, + const char *argp, long argl, char **ret) +{ + return by_file_ctrl_ex(ctx, cmd, argp, argl, ret, NULL, NULL); +} + +int X509_load_cert_file_ex(X509_LOOKUP *ctx, const char *file, int type, + OSSL_LIB_CTX *libctx, const char *propq) { int ret = 0; BIO *in = NULL; @@ -81,23 +97,34 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) in = BIO_new(BIO_s_file()); if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { - X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB); + goto err; + } + + if (type != X509_FILETYPE_PEM && type != X509_FILETYPE_ASN1) { + ERR_raise(ERR_LIB_X509, X509_R_BAD_X509_FILETYPE); + goto err; + } + x = X509_new_ex(libctx, propq); + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } if (type == X509_FILETYPE_PEM) { for (;;) { - x = PEM_read_bio_X509_AUX(in, NULL, NULL, ""); - if (x == NULL) { + ERR_set_mark(); + if (PEM_read_bio_X509_AUX(in, &x, NULL, "") == NULL) { if ((ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) && (count > 0)) { - ERR_clear_error(); + ERR_pop_to_mark(); break; } else { - X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB); + ERR_clear_last_mark(); goto err; } } + ERR_clear_last_mark(); i = X509_STORE_add_cert(ctx->store_ctx, x); if (!i) goto err; @@ -107,27 +134,28 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) } ret = count; } else if (type == X509_FILETYPE_ASN1) { - x = d2i_X509_bio(in, NULL); - if (x == NULL) { - X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB); + if (d2i_X509_bio(in, &x) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; } i = X509_STORE_add_cert(ctx->store_ctx, x); if (!i) goto err; ret = i; - } else { - X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); - goto err; } if (ret == 0) - X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_NO_CERTIFICATE_FOUND); + ERR_raise(ERR_LIB_X509, X509_R_NO_CERTIFICATE_FOUND); err: X509_free(x); BIO_free(in); return ret; } +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) +{ + return X509_load_cert_file_ex(ctx, file, type, NULL, NULL); +} + int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) { int ret = 0; @@ -138,7 +166,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) in = BIO_new(BIO_s_file()); if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { - X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB); goto err; } @@ -151,7 +179,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) ERR_clear_error(); break; } else { - X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_PEM_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_PEM_LIB); goto err; } } @@ -166,7 +194,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) } else if (type == X509_FILETYPE_ASN1) { x = d2i_X509_CRL_bio(in, NULL); if (x == NULL) { - X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; } i = X509_STORE_add_crl(ctx->store_ctx, x); @@ -174,18 +202,19 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) goto err; ret = i; } else { - X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE); + ERR_raise(ERR_LIB_X509, X509_R_BAD_X509_FILETYPE); goto err; } if (ret == 0) - X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_NO_CRL_FOUND); + ERR_raise(ERR_LIB_X509, X509_R_NO_CRL_FOUND); err: X509_CRL_free(x); BIO_free(in); return ret; } -int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) +int X509_load_cert_crl_file_ex(X509_LOOKUP *ctx, const char *file, int type, + OSSL_LIB_CTX *libctx, const char *propq) { STACK_OF(X509_INFO) *inf; X509_INFO *itmp; @@ -193,16 +222,16 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) int i, count = 0; if (type != X509_FILETYPE_PEM) - return X509_load_cert_file(ctx, file, type); + return X509_load_cert_file_ex(ctx, file, type, libctx, propq); in = BIO_new_file(file, "r"); if (!in) { - X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB); return 0; } - inf = PEM_X509_INFO_read_bio(in, NULL, NULL, ""); + inf = PEM_X509_INFO_read_bio_ex(in, NULL, NULL, "", libctx, propq); BIO_free(in); if (!inf) { - X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_PEM_LIB); return 0; } for (i = 0; i < sk_X509_INFO_num(inf); i++) { @@ -219,9 +248,14 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) } } if (count == 0) - X509err(X509_F_X509_LOAD_CERT_CRL_FILE, - X509_R_NO_CERTIFICATE_OR_CRL_FOUND); + ERR_raise(ERR_LIB_X509, X509_R_NO_CERTIFICATE_OR_CRL_FOUND); err: sk_X509_INFO_pop_free(inf, X509_INFO_free); return count; } + +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + return X509_load_cert_crl_file_ex(ctx, file, type, NULL, NULL); +} + diff --git a/crypto/openssl/crypto/x509/by_store.c b/crypto/openssl/crypto/x509/by_store.c new file mode 100644 index 000000000000..050735ce3247 --- /dev/null +++ b/crypto/openssl/crypto/x509/by_store.c @@ -0,0 +1,249 @@ +/* + * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include "crypto/x509.h" +#include "x509_local.h" + +/* Generic object loader, given expected type and criterion */ +static int cache_objects(X509_LOOKUP *lctx, const char *uri, + const OSSL_STORE_SEARCH *criterion, + int depth, OSSL_LIB_CTX *libctx, const char *propq) +{ + int ok = 0; + OSSL_STORE_CTX *ctx = NULL; + X509_STORE *xstore = X509_LOOKUP_get_store(lctx); + + if ((ctx = OSSL_STORE_open_ex(uri, libctx, propq, NULL, NULL, NULL, + NULL, NULL)) == NULL) + return 0; + + /* + * We try to set the criterion, but don't care if it was valid or not. + * For a OSSL_STORE, it merely serves as an optimization, the expectation + * being that if the criterion couldn't be used, we will get *everything* + * from the container that the URI represents rather than the subset that + * the criterion indicates, so the biggest harm is that we cache more + * objects certs and CRLs than we may expect, but that's ok. + * + * Specifically for OpenSSL's own file: scheme, the only workable + * criterion is the BY_NAME one, which it can only apply on directories, + * but it's possible that the URI is a single file rather than a directory, + * and in that case, the BY_NAME criterion is pointless. + * + * We could very simply not apply any criterion at all here, and just let + * the code that selects certs and CRLs from the cached objects do its job, + * but it's a nice optimization when it can be applied (such as on an + * actual directory with a thousand CA certs). + */ + if (criterion != NULL) + OSSL_STORE_find(ctx, criterion); + + for (;;) { + OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); + int infotype; + + /* NULL means error or "end of file". Either way, we break. */ + if (info == NULL) + break; + + infotype = OSSL_STORE_INFO_get_type(info); + ok = 0; + + if (infotype == OSSL_STORE_INFO_NAME) { + /* + * This is an entry in the "directory" represented by the current + * uri. if |depth| allows, dive into it. + */ + if (depth > 0) + ok = cache_objects(lctx, OSSL_STORE_INFO_get0_NAME(info), + criterion, depth - 1, libctx, propq); + } else { + /* + * We know that X509_STORE_add_{cert|crl} increments the object's + * refcount, so we can safely use OSSL_STORE_INFO_get0_{cert,crl} + * to get them. + */ + switch (infotype) { + case OSSL_STORE_INFO_CERT: + ok = X509_STORE_add_cert(xstore, + OSSL_STORE_INFO_get0_CERT(info)); + break; + case OSSL_STORE_INFO_CRL: + ok = X509_STORE_add_crl(xstore, + OSSL_STORE_INFO_get0_CRL(info)); + break; + } + } + + OSSL_STORE_INFO_free(info); + if (!ok) + break; + } + OSSL_STORE_close(ctx); + + return ok; +} + + +/* Because OPENSSL_free is a macro and for C type match */ +static void free_uri(OPENSSL_STRING data) +{ + OPENSSL_free(data); +} + +static void by_store_free(X509_LOOKUP *ctx) +{ + STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); + sk_OPENSSL_STRING_pop_free(uris, free_uri); +} + +static int by_store_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp, + long argl, char **retp, OSSL_LIB_CTX *libctx, + const char *propq) +{ + switch (cmd) { + case X509_L_ADD_STORE: + /* If no URI is given, use the default cert dir as default URI */ + if (argp == NULL) + argp = ossl_safe_getenv(X509_get_default_cert_dir_env()); + if (argp == NULL) + argp = X509_get_default_cert_dir(); + + { + STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); + char *data = OPENSSL_strdup(argp); + + if (data == NULL) { + return 0; + } + if (uris == NULL) { + uris = sk_OPENSSL_STRING_new_null(); + X509_LOOKUP_set_method_data(ctx, uris); + } + return sk_OPENSSL_STRING_push(uris, data) > 0; + } + case X509_L_LOAD_STORE: + /* This is a shortcut for quick loading of specific containers */ + return cache_objects(ctx, argp, NULL, 0, libctx, propq); + } + + return 0; +} + +static int by_store_ctrl(X509_LOOKUP *ctx, int cmd, + const char *argp, long argl, char **retp) +{ + return by_store_ctrl_ex(ctx, cmd, argp, argl, retp, NULL, NULL); +} + +static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const OSSL_STORE_SEARCH *criterion, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq) +{ + STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); + int i; + int ok = 0; + + for (i = 0; i < sk_OPENSSL_STRING_num(uris); i++) { + ok = cache_objects(ctx, sk_OPENSSL_STRING_value(uris, i), criterion, + 1 /* depth */, libctx, propq); + + if (ok) + break; + } + return ok; +} + +static int by_store_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq) +{ + OSSL_STORE_SEARCH *criterion = + OSSL_STORE_SEARCH_by_name((X509_NAME *)name); /* won't modify it */ + int ok = by_store(ctx, type, criterion, ret, libctx, propq); + STACK_OF(X509_OBJECT) *store_objects = + X509_STORE_get0_objects(X509_LOOKUP_get_store(ctx)); + X509_OBJECT *tmp = NULL; + + OSSL_STORE_SEARCH_free(criterion); + + if (ok) + tmp = X509_OBJECT_retrieve_by_subject(store_objects, type, name); + + ok = 0; + if (tmp != NULL) { + /* + * This could also be done like this: + * + * if (tmp != NULL) { + * *ret = *tmp; + * ok = 1; + * } + * + * However, we want to exercise the documented API to the max, so + * we do it the hard way. + * + * To be noted is that X509_OBJECT_set1_* increment the refcount, + * but so does X509_STORE_CTX_get_by_subject upon return of this + * function, so we must ensure the refcount is decremented + * before we return, or we will get a refcount leak. We cannot do + * this with X509_OBJECT_free(), though, as that will free a bit + * too much. + */ + switch (type) { + case X509_LU_X509: + ok = X509_OBJECT_set1_X509(ret, tmp->data.x509); + if (ok) + X509_free(tmp->data.x509); + break; + case X509_LU_CRL: + ok = X509_OBJECT_set1_X509_CRL(ret, tmp->data.crl); + if (ok) + X509_CRL_free(tmp->data.crl); + break; + case X509_LU_NONE: + break; + } + } + return ok; +} + +static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret) +{ + return by_store_subject_ex(ctx, type, name, ret, NULL, NULL); +} + +/* + * We lack the implementations for get_by_issuer_serial, get_by_fingerprint + * and get_by_alias. There's simply not enough support in the X509_LOOKUP + * or X509_STORE APIs. + */ + +static X509_LOOKUP_METHOD x509_store_lookup = { + "Load certs from STORE URIs", + NULL, /* new_item */ + by_store_free, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + by_store_ctrl, /* ctrl */ + by_store_subject, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ + by_store_subject_ex, + by_store_ctrl_ex +}; + +X509_LOOKUP_METHOD *X509_LOOKUP_store(void) +{ + return &x509_store_lookup; +} diff --git a/crypto/openssl/crypto/x509/ext_dat.h b/crypto/openssl/crypto/x509/ext_dat.h new file mode 100644 index 000000000000..a0a7f88ccd8a --- /dev/null +++ b/crypto/openssl/crypto/x509/ext_dat.h @@ -0,0 +1,27 @@ +/* + * Copyright 1999-2021 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 + */ + +int ossl_v3_name_cmp(const char *name, const char *cmp); + +extern const X509V3_EXT_METHOD ossl_v3_bcons, ossl_v3_nscert, ossl_v3_key_usage, ossl_v3_ext_ku; +extern const X509V3_EXT_METHOD ossl_v3_pkey_usage_period, ossl_v3_sxnet, ossl_v3_info, ossl_v3_sinfo; +extern const X509V3_EXT_METHOD ossl_v3_ns_ia5_list[8], ossl_v3_alt[3], ossl_v3_skey_id, ossl_v3_akey_id; +extern const X509V3_EXT_METHOD ossl_v3_crl_num, ossl_v3_crl_reason, ossl_v3_crl_invdate; +extern const X509V3_EXT_METHOD ossl_v3_delta_crl, ossl_v3_cpols, ossl_v3_crld, ossl_v3_freshest_crl; +extern const X509V3_EXT_METHOD ossl_v3_ocsp_nonce, ossl_v3_ocsp_accresp, ossl_v3_ocsp_acutoff; +extern const X509V3_EXT_METHOD ossl_v3_ocsp_crlid, ossl_v3_ocsp_nocheck, ossl_v3_ocsp_serviceloc; +extern const X509V3_EXT_METHOD ossl_v3_crl_hold, ossl_v3_pci; +extern const X509V3_EXT_METHOD ossl_v3_policy_mappings, ossl_v3_policy_constraints; +extern const X509V3_EXT_METHOD ossl_v3_name_constraints, ossl_v3_inhibit_anyp, ossl_v3_idp; +extern const X509V3_EXT_METHOD ossl_v3_addr, ossl_v3_asid; +extern const X509V3_EXT_METHOD ossl_v3_ct_scts[3]; +extern const X509V3_EXT_METHOD ossl_v3_tls_feature; +extern const X509V3_EXT_METHOD ossl_v3_ext_admission; +extern const X509V3_EXT_METHOD ossl_v3_utf8_list[1]; +extern const X509V3_EXT_METHOD ossl_v3_issuer_sign_tool; diff --git a/crypto/openssl/crypto/x509v3/pcy_cache.c b/crypto/openssl/crypto/x509/pcy_cache.c similarity index 83% rename from crypto/openssl/crypto/x509v3/pcy_cache.c rename to crypto/openssl/crypto/x509/pcy_cache.c index 04401bace8c5..1339f994aee1 100644 --- a/crypto/openssl/crypto/x509v3/pcy_cache.c +++ b/crypto/openssl/crypto/x509/pcy_cache.c @@ -1,7 +1,7 @@ /* - * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -35,14 +35,14 @@ static int policy_cache_create(X509 *x, goto bad_policy; cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp); if (cache->data == NULL) { - X509V3err(X509V3_F_POLICY_CACHE_CREATE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto just_cleanup; } for (i = 0; i < num; i++) { policy = sk_POLICYINFO_value(policies, i); - data = policy_data_new(policy, NULL, crit); + data = ossl_policy_data_new(policy, NULL, crit); if (data == NULL) { - X509V3err(X509V3_F_POLICY_CACHE_CREATE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto just_cleanup; } /* @@ -58,7 +58,7 @@ static int policy_cache_create(X509 *x, ret = -1; goto bad_policy; } else if (!sk_X509_POLICY_DATA_push(cache->data, data)) { - X509V3err(X509V3_F_POLICY_CACHE_CREATE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto bad_policy; } data = NULL; @@ -68,11 +68,11 @@ static int policy_cache_create(X509 *x, bad_policy: if (ret == -1) x->ex_flags |= EXFLAG_INVALID_POLICY; - policy_data_free(data); + ossl_policy_data_free(data); just_cleanup: sk_POLICYINFO_pop_free(policies, POLICYINFO_free); if (ret <= 0) { - sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); + sk_X509_POLICY_DATA_pop_free(cache->data, ossl_policy_data_free); cache->data = NULL; } return ret; @@ -91,7 +91,7 @@ static int policy_cache_new(X509 *x) return 1; cache = OPENSSL_malloc(sizeof(*cache)); if (cache == NULL) { - X509V3err(X509V3_F_POLICY_CACHE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return 0; } cache->anyPolicy = NULL; @@ -151,7 +151,7 @@ static int policy_cache_new(X509 *x) if (i != -1) goto bad_cache; } else { - i = policy_cache_set_mapping(x, ext_pmaps); + i = ossl_policy_cache_set_mapping(x, ext_pmaps); if (i <= 0) goto bad_cache; } @@ -175,20 +175,21 @@ static int policy_cache_new(X509 *x) } -void policy_cache_free(X509_POLICY_CACHE *cache) +void ossl_policy_cache_free(X509_POLICY_CACHE *cache) { if (!cache) return; - policy_data_free(cache->anyPolicy); - sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); + ossl_policy_data_free(cache->anyPolicy); + sk_X509_POLICY_DATA_pop_free(cache->data, ossl_policy_data_free); OPENSSL_free(cache); } -const X509_POLICY_CACHE *policy_cache_set(X509 *x) +const X509_POLICY_CACHE *ossl_policy_cache_set(X509 *x) { if (x->policy_cache == NULL) { - CRYPTO_THREAD_write_lock(x->lock); + if (!CRYPTO_THREAD_write_lock(x->lock)) + return NULL; policy_cache_new(x); CRYPTO_THREAD_unlock(x->lock); } @@ -197,8 +198,8 @@ const X509_POLICY_CACHE *policy_cache_set(X509 *x) } -X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, - const ASN1_OBJECT *id) +X509_POLICY_DATA *ossl_policy_cache_find_data(const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id) { int idx; X509_POLICY_DATA tmp; diff --git a/crypto/openssl/crypto/x509v3/pcy_data.c b/crypto/openssl/crypto/x509/pcy_data.c similarity index 81% rename from crypto/openssl/crypto/x509v3/pcy_data.c rename to crypto/openssl/crypto/x509/pcy_data.c index 8c7bc69576a4..6fb8f14ba8e8 100644 --- a/crypto/openssl/crypto/x509v3/pcy_data.c +++ b/crypto/openssl/crypto/x509/pcy_data.c @@ -1,7 +1,7 @@ /* - * Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,7 +15,7 @@ /* Policy Node routines */ -void policy_data_free(X509_POLICY_DATA *data) +void ossl_policy_data_free(X509_POLICY_DATA *data) { if (data == NULL) return; @@ -35,8 +35,8 @@ void policy_data_free(X509_POLICY_DATA *data) * source. */ -X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, - const ASN1_OBJECT *cid, int crit) +X509_POLICY_DATA *ossl_policy_data_new(POLICYINFO *policy, + const ASN1_OBJECT *cid, int crit) { X509_POLICY_DATA *ret; ASN1_OBJECT *id; @@ -51,15 +51,15 @@ X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, id = NULL; ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - X509V3err(X509V3_F_POLICY_DATA_NEW, ERR_R_MALLOC_FAILURE); ASN1_OBJECT_free(id); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } ret->expected_policy_set = sk_ASN1_OBJECT_new_null(); if (ret->expected_policy_set == NULL) { OPENSSL_free(ret); ASN1_OBJECT_free(id); - X509V3err(X509V3_F_POLICY_DATA_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/openssl/crypto/x509v3/pcy_lib.c b/crypto/openssl/crypto/x509/pcy_lib.c similarity index 91% rename from crypto/openssl/crypto/x509v3/pcy_lib.c rename to crypto/openssl/crypto/x509/pcy_lib.c index 2e196b838ca2..c4740a0a30c5 100644 --- a/crypto/openssl/crypto/x509v3/pcy_lib.c +++ b/crypto/openssl/crypto/x509/pcy_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -69,7 +69,7 @@ int X509_policy_level_node_count(X509_POLICY_LEVEL *level) return n; } -X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i) +X509_POLICY_NODE *X509_policy_level_get0_node(const X509_POLICY_LEVEL *level, int i) { if (!level) return NULL; diff --git a/crypto/openssl/crypto/x509v3/pcy_local.h b/crypto/openssl/crypto/x509/pcy_local.h similarity index 70% rename from crypto/openssl/crypto/x509v3/pcy_local.h rename to crypto/openssl/crypto/x509/pcy_local.h index 5daf78de4585..18b53cc09ebf 100644 --- a/crypto/openssl/crypto/x509v3/pcy_local.h +++ b/crypto/openssl/crypto/x509/pcy_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -135,33 +135,31 @@ struct X509_POLICY_TREE_st { /* Internal functions */ -X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, - int crit); -void policy_data_free(X509_POLICY_DATA *data); +X509_POLICY_DATA *ossl_policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, + int crit); +void ossl_policy_data_free(X509_POLICY_DATA *data); -X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, - const ASN1_OBJECT *id); -int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps); +X509_POLICY_DATA *ossl_policy_cache_find_data(const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id); +int ossl_policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps); -STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void); +STACK_OF(X509_POLICY_NODE) *ossl_policy_node_cmp_new(void); -void policy_cache_init(void); +void ossl_policy_cache_free(X509_POLICY_CACHE *cache); -void policy_cache_free(X509_POLICY_CACHE *cache); +X509_POLICY_NODE *ossl_policy_level_find_node(const X509_POLICY_LEVEL *level, + const X509_POLICY_NODE *parent, + const ASN1_OBJECT *id); -X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, - const X509_POLICY_NODE *parent, - const ASN1_OBJECT *id); +X509_POLICY_NODE *ossl_policy_tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, + const ASN1_OBJECT *id); -X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, - const ASN1_OBJECT *id); +X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, + X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, + X509_POLICY_TREE *tree); +void ossl_policy_node_free(X509_POLICY_NODE *node); +int ossl_policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); -X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, - X509_POLICY_DATA *data, - X509_POLICY_NODE *parent, - X509_POLICY_TREE *tree); -void policy_node_free(X509_POLICY_NODE *node); -int policy_node_match(const X509_POLICY_LEVEL *lvl, - const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); - -const X509_POLICY_CACHE *policy_cache_set(X509 *x); +const X509_POLICY_CACHE *ossl_policy_cache_set(X509 *x); diff --git a/crypto/openssl/crypto/x509v3/pcy_map.c b/crypto/openssl/crypto/x509/pcy_map.c similarity index 78% rename from crypto/openssl/crypto/x509v3/pcy_map.c rename to crypto/openssl/crypto/x509/pcy_map.c index ae2a62c97787..60dfd1e3203b 100644 --- a/crypto/openssl/crypto/x509v3/pcy_map.c +++ b/crypto/openssl/crypto/x509/pcy_map.c @@ -1,7 +1,7 @@ /* - * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,7 +19,7 @@ * POLICY_MAPPINGS structure */ -int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) +int ossl_policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) { POLICY_MAPPING *map; X509_POLICY_DATA *data; @@ -40,16 +40,16 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) } /* Attempt to find matching policy data */ - data = policy_cache_find_data(cache, map->issuerDomainPolicy); + data = ossl_policy_cache_find_data(cache, map->issuerDomainPolicy); /* If we don't have anyPolicy can't map */ if (data == NULL && !cache->anyPolicy) continue; /* Create a NODE from anyPolicy */ if (data == NULL) { - data = policy_data_new(NULL, map->issuerDomainPolicy, - cache->anyPolicy->flags - & POLICY_DATA_FLAG_CRITICAL); + data = ossl_policy_data_new(NULL, map->issuerDomainPolicy, + cache->anyPolicy->flags + & POLICY_DATA_FLAG_CRITICAL); if (data == NULL) goto bad_mapping; data->qualifier_set = cache->anyPolicy->qualifier_set; @@ -59,7 +59,7 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; if (!sk_X509_POLICY_DATA_push(cache->data, data)) { - policy_data_free(data); + ossl_policy_data_free(data); goto bad_mapping; } } else @@ -73,8 +73,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) ret = 1; bad_mapping: - if (ret == -1) - x->ex_flags |= EXFLAG_INVALID_POLICY; sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); return ret; diff --git a/crypto/openssl/crypto/x509v3/pcy_node.c b/crypto/openssl/crypto/x509/pcy_node.c similarity index 66% rename from crypto/openssl/crypto/x509v3/pcy_node.c rename to crypto/openssl/crypto/x509/pcy_node.c index e2d7b1532236..9d9a7ea1799c 100644 --- a/crypto/openssl/crypto/x509v3/pcy_node.c +++ b/crypto/openssl/crypto/x509/pcy_node.c @@ -1,7 +1,7 @@ /* - * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,13 +20,13 @@ static int node_cmp(const X509_POLICY_NODE *const *a, return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy); } -STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void) +STACK_OF(X509_POLICY_NODE) *ossl_policy_node_cmp_new(void) { return sk_X509_POLICY_NODE_new(node_cmp); } -X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, - const ASN1_OBJECT *id) +X509_POLICY_NODE *ossl_policy_tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, + const ASN1_OBJECT *id) { X509_POLICY_DATA n; X509_POLICY_NODE l; @@ -40,9 +40,9 @@ X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, } -X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, - const X509_POLICY_NODE *parent, - const ASN1_OBJECT *id) +X509_POLICY_NODE *ossl_policy_level_find_node(const X509_POLICY_LEVEL *level, + const X509_POLICY_NODE *parent, + const ASN1_OBJECT *id) { X509_POLICY_NODE *node; int i; @@ -56,16 +56,16 @@ X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, return NULL; } -X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, - X509_POLICY_DATA *data, - X509_POLICY_NODE *parent, - X509_POLICY_TREE *tree) +X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, + X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, + X509_POLICY_TREE *tree) { X509_POLICY_NODE *node; node = OPENSSL_zalloc(sizeof(*node)); if (node == NULL) { - X509V3err(X509V3_F_LEVEL_ADD_NODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } node->data = data; @@ -78,13 +78,13 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, } else { if (level->nodes == NULL) - level->nodes = policy_node_cmp_new(); + level->nodes = ossl_policy_node_cmp_new(); if (level->nodes == NULL) { - X509V3err(X509V3_F_LEVEL_ADD_NODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto node_error; } if (!sk_X509_POLICY_NODE_push(level->nodes, node)) { - X509V3err(X509V3_F_LEVEL_ADD_NODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto node_error; } } @@ -94,11 +94,11 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, if (tree->extra_data == NULL) tree->extra_data = sk_X509_POLICY_DATA_new_null(); if (tree->extra_data == NULL){ - X509V3err(X509V3_F_LEVEL_ADD_NODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto node_error; } if (!sk_X509_POLICY_DATA_push(tree->extra_data, data)) { - X509V3err(X509V3_F_LEVEL_ADD_NODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto node_error; } } @@ -109,11 +109,11 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, return node; node_error: - policy_node_free(node); + ossl_policy_node_free(node); return NULL; } -void policy_node_free(X509_POLICY_NODE *node) +void ossl_policy_node_free(X509_POLICY_NODE *node) { OPENSSL_free(node); } @@ -123,8 +123,8 @@ void policy_node_free(X509_POLICY_NODE *node) * expected policy set otherwise just valid policy. */ -int policy_node_match(const X509_POLICY_LEVEL *lvl, - const X509_POLICY_NODE *node, const ASN1_OBJECT *oid) +int ossl_policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid) { int i; ASN1_OBJECT *policy_oid; diff --git a/crypto/openssl/crypto/x509v3/pcy_tree.c b/crypto/openssl/crypto/x509/pcy_tree.c similarity index 86% rename from crypto/openssl/crypto/x509v3/pcy_tree.c rename to crypto/openssl/crypto/x509/pcy_tree.c index 6e8322cbc5e3..fa45da5117a1 100644 --- a/crypto/openssl/crypto/x509v3/pcy_tree.c +++ b/crypto/openssl/crypto/x509/pcy_tree.c @@ -1,83 +1,78 @@ /* - * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include "internal/cryptlib.h" +#include #include #include #include "pcy_local.h" -/* - * Enable this to print out the complete policy tree at various point during - * evaluation. - */ - -/* - * #define OPENSSL_POLICY_DEBUG - */ - -#ifdef OPENSSL_POLICY_DEBUG - -static void expected_print(BIO *err, X509_POLICY_LEVEL *lev, - X509_POLICY_NODE *node, int indent) +static void expected_print(BIO *channel, + X509_POLICY_LEVEL *lev, X509_POLICY_NODE *node, + int indent) { if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) - BIO_puts(err, " Not Mapped\n"); + BIO_puts(channel, " Not Mapped\n"); else { int i; + STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; ASN1_OBJECT *oid; - BIO_puts(err, " Expected: "); + BIO_puts(channel, " Expected: "); for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) { oid = sk_ASN1_OBJECT_value(pset, i); if (i) - BIO_puts(err, ", "); - i2a_ASN1_OBJECT(err, oid); + BIO_puts(channel, ", "); + i2a_ASN1_OBJECT(channel, oid); } - BIO_puts(err, "\n"); + BIO_puts(channel, "\n"); } } -static void tree_print(char *str, X509_POLICY_TREE *tree, +static void tree_print(BIO *channel, + char *str, X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) { - BIO *err = BIO_new_fp(stderr, BIO_NOCLOSE); X509_POLICY_LEVEL *plev; - if (err == NULL) - return; if (!curr) curr = tree->levels + tree->nlevel; else curr++; - BIO_printf(err, "Level print after %s\n", str); - BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); + BIO_printf(channel, "Level print after %s\n", str); + BIO_printf(channel, "Printing Up to Level %ld\n", + (long)(curr - tree->levels)); for (plev = tree->levels; plev != curr; plev++) { int i; - BIO_printf(err, "Level %ld, flags = %x\n", + BIO_printf(channel, "Level %ld, flags = %x\n", (long)(plev - tree->levels), plev->flags); for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) { - X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(plev->nodes, i); + X509_POLICY_NODE *node = + sk_X509_POLICY_NODE_value(plev->nodes, i); - X509_POLICY_NODE_print(err, node, 2); - expected_print(err, plev, node, 2); - BIO_printf(err, " Flags: %x\n", node->data->flags); + X509_POLICY_NODE_print(channel, node, 2); + expected_print(channel, plev, node, 2); + BIO_printf(channel, " Flags: %x\n", node->data->flags); } if (plev->anyPolicy) - X509_POLICY_NODE_print(err, plev->anyPolicy, 2); + X509_POLICY_NODE_print(channel, plev->anyPolicy, 2); } - BIO_free(err); } -#endif + +#define TREE_PRINT(str, tree, curr) \ + OSSL_TRACE_BEGIN(X509V3_POLICY) { \ + tree_print(trc_out, "before tree_prune()", tree, curr); \ + } OSSL_TRACE_END(X509V3_POLICY) /*- * Return value: <= 0 on error, or positive bit mask: @@ -118,7 +113,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, X509_check_purpose(x, -1, 0); /* If cache is NULL, likely ENOMEM: return immediately */ - if (policy_cache_set(x) == NULL) + if (ossl_policy_cache_set(x) == NULL) return X509_PCY_TREE_INTERNAL; } @@ -144,7 +139,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, return X509_PCY_TREE_INVALID; /* Access the cache which we now know exists */ - cache = policy_cache_set(x); + cache = ossl_policy_cache_set(x); if ((ret & X509_PCY_TREE_VALID) && cache->data == NULL) ret = X509_PCY_TREE_EMPTY; @@ -164,7 +159,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, /* If we get this far initialize the tree */ if ((tree = OPENSSL_zalloc(sizeof(*tree))) == NULL) { - X509V3err(X509V3_F_TREE_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return X509_PCY_TREE_INTERNAL; } @@ -177,15 +172,16 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, */ if ((tree->levels = OPENSSL_zalloc(sizeof(*tree->levels)*(n+1))) == NULL) { OPENSSL_free(tree); - X509V3err(X509V3_F_TREE_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return X509_PCY_TREE_INTERNAL; } tree->nlevel = n+1; level = tree->levels; - if ((data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0)) == NULL) + if ((data = ossl_policy_data_new(NULL, + OBJ_nid2obj(NID_any_policy), 0)) == NULL) goto bad_tree; - if (level_add_node(level, data, NULL, tree) == NULL) { - policy_data_free(data); + if (ossl_policy_level_add_node(level, data, NULL, tree) == NULL) { + ossl_policy_data_free(data); goto bad_tree; } @@ -198,7 +194,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, uint32_t ex_flags = X509_get_extension_flags(x); /* Access the cache which we now know exists */ - cache = policy_cache_set(x); + cache = ossl_policy_cache_set(x); X509_up_ref(x); (++level)->cert = x; @@ -252,14 +248,14 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i); - if (policy_node_match(last, node, data->valid_policy)) { - if (level_add_node(curr, data, node, NULL) == NULL) + if (ossl_policy_node_match(last, node, data->valid_policy)) { + if (ossl_policy_level_add_node(curr, data, node, NULL) == NULL) return 0; matched = 1; } } if (!matched && last->anyPolicy) { - if (level_add_node(curr, data, last->anyPolicy, NULL) == NULL) + if (ossl_policy_level_add_node(curr, data, last->anyPolicy, NULL) == NULL) return 0; } return 1; @@ -305,14 +301,14 @@ static int tree_add_unmatched(X509_POLICY_LEVEL *curr, * Create a new node with qualifiers from anyPolicy and id from unmatched * node. */ - if ((data = policy_data_new(NULL, id, node_critical(node))) == NULL) + if ((data = ossl_policy_data_new(NULL, id, node_critical(node))) == NULL) return 0; /* Curr may not have anyPolicy */ data->qualifier_set = cache->anyPolicy->qualifier_set; data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; - if (level_add_node(curr, data, node, tree) == NULL) { - policy_data_free(data); + if (ossl_policy_level_add_node(curr, data, node, tree) == NULL) { + ossl_policy_data_free(data); return 0; } return 1; @@ -344,7 +340,7 @@ static int tree_link_unmatched(X509_POLICY_LEVEL *curr, /* Locate unmatched nodes */ for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) { ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); - if (level_find_node(curr, node, oid)) + if (ossl_policy_level_find_node(curr, node, oid)) continue; if (!tree_add_unmatched(curr, cache, oid, node, tree)) return 0; @@ -373,7 +369,8 @@ static int tree_link_any(X509_POLICY_LEVEL *curr, } /* Finally add link to anyPolicy */ if (last->anyPolicy && - level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL) == NULL) + ossl_policy_level_add_node(curr, cache->anyPolicy, + last->anyPolicy, NULL) == NULL) return 0; return 1; } @@ -440,7 +437,7 @@ static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, X509_POLICY_NODE *pcy) { if (*pnodes == NULL && - (*pnodes = policy_node_cmp_new()) == NULL) + (*pnodes = ossl_policy_node_cmp_new()) == NULL) return 0; if (sk_X509_POLICY_NODE_find(*pnodes, pcy) >= 0) return 1; @@ -484,7 +481,7 @@ static int tree_calculate_authority_set(X509_POLICY_TREE *tree, curr = tree->levels; for (i = 1; i < tree->nlevel; i++) { /* - * If no anyPolicy node on this this level it can't appear on lower + * If no anyPolicy node on this level it can't appear on lower * levels so end search. */ if ((anyptr = curr->anyPolicy) == NULL) @@ -541,7 +538,7 @@ static int tree_calculate_user_set(X509_POLICY_TREE *tree, for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { oid = sk_ASN1_OBJECT_value(policy_oids, i); - node = tree_find_sk(auth_nodes, oid); + node = ossl_policy_tree_find_sk(auth_nodes, oid); if (!node) { if (!anyPolicy) continue; @@ -549,13 +546,14 @@ static int tree_calculate_user_set(X509_POLICY_TREE *tree, * Create a new node with policy ID from user set and qualifiers * from anyPolicy. */ - extra = policy_data_new(NULL, oid, node_critical(anyPolicy)); + extra = ossl_policy_data_new(NULL, oid, node_critical(anyPolicy)); if (extra == NULL) return 0; extra->qualifier_set = anyPolicy->data->qualifier_set; extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS | POLICY_DATA_FLAG_EXTRA_NODE; - node = level_add_node(NULL, extra, anyPolicy->parent, tree); + node = ossl_policy_level_add_node(NULL, extra, anyPolicy->parent, + tree); } if (!tree->user_policies) { tree->user_policies = sk_X509_POLICY_NODE_new_null(); @@ -581,16 +579,14 @@ static int tree_evaluate(X509_POLICY_TREE *tree) const X509_POLICY_CACHE *cache; for (i = 1; i < tree->nlevel; i++, curr++) { - cache = policy_cache_set(curr->cert); + cache = ossl_policy_cache_set(curr->cert); if (!tree_link_nodes(curr, cache)) return X509_PCY_TREE_INTERNAL; if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) && !tree_link_any(curr, cache, tree)) return X509_PCY_TREE_INTERNAL; -#ifdef OPENSSL_POLICY_DEBUG - tree_print("before tree_prune()", tree, curr); -#endif + TREE_PRINT("before tree_prune()", tree, curr); ret = tree_prune(tree, curr); if (ret != X509_PCY_TREE_VALID) return ret; @@ -617,11 +613,11 @@ void X509_policy_tree_free(X509_POLICY_TREE *tree) for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) { X509_free(curr->cert); - sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free); - policy_node_free(curr->anyPolicy); + sk_X509_POLICY_NODE_pop_free(curr->nodes, ossl_policy_node_free); + ossl_policy_node_free(curr->anyPolicy); } - sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free); + sk_X509_POLICY_DATA_pop_free(tree->extra_data, ossl_policy_data_free); OPENSSL_free(tree->levels); OPENSSL_free(tree); @@ -665,9 +661,7 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, } ret = tree_evaluate(tree); -#ifdef OPENSSL_POLICY_DEBUG - tree_print("tree_evaluate()", tree, NULL); -#endif + TREE_PRINT("tree_evaluate()", tree, NULL); if (ret <= 0) goto error; diff --git a/crypto/openssl/crypto/x509/standard_exts.h b/crypto/openssl/crypto/x509/standard_exts.h new file mode 100644 index 000000000000..27a99a4b13ed --- /dev/null +++ b/crypto/openssl/crypto/x509/standard_exts.h @@ -0,0 +1,80 @@ +/* + * Copyright 1999-2021 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 + */ + +/* + * This table will be searched using OBJ_bsearch so it *must* kept in order + * of the ext_nid values. + */ + +static const X509V3_EXT_METHOD *standard_exts[] = { + &ossl_v3_nscert, + &ossl_v3_ns_ia5_list[0], + &ossl_v3_ns_ia5_list[1], + &ossl_v3_ns_ia5_list[2], + &ossl_v3_ns_ia5_list[3], + &ossl_v3_ns_ia5_list[4], + &ossl_v3_ns_ia5_list[5], + &ossl_v3_ns_ia5_list[6], + &ossl_v3_skey_id, + &ossl_v3_key_usage, + &ossl_v3_pkey_usage_period, + &ossl_v3_alt[0], + &ossl_v3_alt[1], + &ossl_v3_bcons, + &ossl_v3_crl_num, + &ossl_v3_cpols, + &ossl_v3_akey_id, + &ossl_v3_crld, + &ossl_v3_ext_ku, + &ossl_v3_delta_crl, + &ossl_v3_crl_reason, +#ifndef OPENSSL_NO_OCSP + &ossl_v3_crl_invdate, +#endif + &ossl_v3_sxnet, + &ossl_v3_info, +#ifndef OPENSSL_NO_RFC3779 + &ossl_v3_addr, + &ossl_v3_asid, +#endif +#ifndef OPENSSL_NO_OCSP + &ossl_v3_ocsp_nonce, + &ossl_v3_ocsp_crlid, + &ossl_v3_ocsp_accresp, + &ossl_v3_ocsp_nocheck, + &ossl_v3_ocsp_acutoff, + &ossl_v3_ocsp_serviceloc, +#endif + &ossl_v3_sinfo, + &ossl_v3_policy_constraints, +#ifndef OPENSSL_NO_OCSP + &ossl_v3_crl_hold, +#endif + &ossl_v3_pci, + &ossl_v3_name_constraints, + &ossl_v3_policy_mappings, + &ossl_v3_inhibit_anyp, + &ossl_v3_idp, + &ossl_v3_alt[2], + &ossl_v3_freshest_crl, +#ifndef OPENSSL_NO_CT + &ossl_v3_ct_scts[0], + &ossl_v3_ct_scts[1], + &ossl_v3_ct_scts[2], +#endif + &ossl_v3_utf8_list[0], + &ossl_v3_issuer_sign_tool, + &ossl_v3_tls_feature, + &ossl_v3_ext_admission +}; + +/* Number of standard extensions */ + +#define STANDARD_EXTENSION_COUNT OSSL_NELEM(standard_exts) + diff --git a/crypto/openssl/crypto/x509/t_crl.c b/crypto/openssl/crypto/x509/t_crl.c index 8e262912ffaa..e77a77978a83 100644 --- a/crypto/openssl/crypto/x509/t_crl.c +++ b/crypto/openssl/crypto/x509/t_crl.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -22,7 +22,7 @@ int X509_CRL_print_fp(FILE *fp, X509_CRL *x) int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - X509err(X509_F_X509_CRL_PRINT_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -48,7 +48,7 @@ int X509_CRL_print_ex(BIO *out, X509_CRL *x, unsigned long nmflag) BIO_printf(out, "Certificate Revocation List (CRL):\n"); l = X509_CRL_get_version(x); - if (l >= 0 && l <= 1) + if (l >= X509_CRL_VERSION_1 && l <= X509_CRL_VERSION_2) BIO_printf(out, "%8sVersion %ld (0x%lx)\n", "", l + 1, (unsigned long)l); else BIO_printf(out, "%8sVersion unknown (%ld)\n", "", l); diff --git a/crypto/openssl/crypto/x509/t_req.c b/crypto/openssl/crypto/x509/t_req.c index dc3b4f262de9..095c16510099 100644 --- a/crypto/openssl/crypto/x509/t_req.c +++ b/crypto/openssl/crypto/x509/t_req.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -24,7 +24,7 @@ int X509_REQ_print_fp(FILE *fp, X509_REQ *x) int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -60,7 +60,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, } if (!(cflag & X509_FLAG_NO_VERSION)) { l = X509_REQ_get_version(x); - if (l >= 0 && l <= 2) { + if (l == X509_REQ_VERSION_1) { if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0) goto err; } else { @@ -108,7 +108,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, goto err; if (X509_REQ_get_attr_count(x) == 0) { - if (BIO_printf(bp, "%12sa0:00\n", "") <= 0) + if (BIO_printf(bp, "%12s(none)\n", "") <= 0) goto err; } else { for (i = 0; i < X509_REQ_get_attr_count(x); i++) { @@ -128,7 +128,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, ii = 0; count = X509_ATTRIBUTE_count(a); if (count == 0) { - X509err(X509_F_X509_REQ_PRINT_EX, X509_R_INVALID_ATTRIBUTES); + ERR_raise(ERR_LIB_X509, X509_R_INVALID_ATTRIBUTES); return 0; } get_next: @@ -166,14 +166,14 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { exts = X509_REQ_get_extensions(x); if (exts) { - if (BIO_printf(bp, "%8sRequested Extensions:\n", "") <= 0) + if (BIO_printf(bp, "%12sRequested Extensions:\n", "") <= 0) goto err; for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { ASN1_OBJECT *obj; X509_EXTENSION *ex; int critical; ex = sk_X509_EXTENSION_value(exts, i); - if (BIO_printf(bp, "%12s", "") <= 0) + if (BIO_printf(bp, "%16s", "") <= 0) goto err; obj = X509_EXTENSION_get_object(ex); if (i2a_ASN1_OBJECT(bp, obj) <= 0) @@ -181,8 +181,8 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, critical = X509_EXTENSION_get_critical(ex); if (BIO_printf(bp, ": %s\n", critical ? "critical" : "") <= 0) goto err; - if (!X509V3_EXT_print(bp, ex, cflag, 16)) { - if (BIO_printf(bp, "%16s", "") <= 0 + if (!X509V3_EXT_print(bp, ex, cflag, 20)) { + if (BIO_printf(bp, "%20s", "") <= 0 || ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex)) <= 0) goto err; @@ -204,7 +204,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, return 1; err: - X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); return 0; } diff --git a/crypto/openssl/crypto/x509/t_x509.c b/crypto/openssl/crypto/x509/t_x509.c index ece987a6bdbe..95ee5f519fdd 100644 --- a/crypto/openssl/crypto/x509/t_x509.c +++ b/crypto/openssl/crypto/x509/t_x509.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,6 +15,7 @@ #include #include #include "crypto/asn1.h" +#include "crypto/x509.h" #ifndef OPENSSL_NO_STDIO int X509_print_fp(FILE *fp, X509 *x) @@ -29,7 +30,7 @@ int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -50,8 +51,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, long l; int ret = 0, i; char *m = NULL, mlch = ' '; - int nmindent = 0; - ASN1_INTEGER *bs; + int nmindent = 0, printok = 0; EVP_PKEY *pkey = NULL; const char *neg; @@ -60,8 +60,10 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, nmindent = 12; } - if (nmflags == X509_FLAG_COMPAT) + if (nmflags == X509_FLAG_COMPAT) { nmindent = 16; + printok = 1; + } if (!(cflag & X509_FLAG_NO_HEADER)) { if (BIO_write(bp, "Certificate:\n", 13) <= 0) @@ -71,7 +73,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, } if (!(cflag & X509_FLAG_NO_VERSION)) { l = X509_get_version(x); - if (l >= 0 && l <= 2) { + if (l >= X509_VERSION_1 && l <= X509_VERSION_3) { if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0) goto err; } else { @@ -80,11 +82,11 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, } } if (!(cflag & X509_FLAG_NO_SERIAL)) { + const ASN1_INTEGER *bs = X509_get0_serialNumber(x); if (BIO_write(bp, " Serial Number:", 22) <= 0) goto err; - bs = X509_get_serialNumber(x); if (bs->length <= (int)sizeof(long)) { ERR_set_mark(); l = ASN1_INTEGER_get(bs); @@ -130,7 +132,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, if (BIO_printf(bp, " Issuer:%c", mlch) <= 0) goto err; if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags) - < 0) + < printok) goto err; if (BIO_write(bp, "\n", 1) <= 0) goto err; @@ -140,11 +142,11 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, goto err; if (BIO_write(bp, " Not Before: ", 24) <= 0) goto err; - if (!ASN1_TIME_print(bp, X509_get0_notBefore(x))) + if (ossl_asn1_time_print_ex(bp, X509_get0_notBefore(x), ASN1_DTFLGS_RFC822) == 0) goto err; if (BIO_write(bp, "\n Not After : ", 25) <= 0) goto err; - if (!ASN1_TIME_print(bp, X509_get0_notAfter(x))) + if (ossl_asn1_time_print_ex(bp, X509_get0_notAfter(x), ASN1_DTFLGS_RFC822) == 0) goto err; if (BIO_write(bp, "\n", 1) <= 0) goto err; @@ -153,7 +155,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, if (BIO_printf(bp, " Subject:%c", mlch) <= 0) goto err; if (X509_NAME_print_ex - (bp, X509_get_subject_name(x), nmindent, nmflags) < 0) + (bp, X509_get_subject_name(x), nmindent, nmflags) < printok) goto err; if (BIO_write(bp, "\n", 1) <= 0) goto err; @@ -197,9 +199,10 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, } } - if (!(cflag & X509_FLAG_NO_EXTENSIONS)) - X509V3_extensions_print(bp, "X509v3 extensions", - X509_get0_extensions(x), cflag, 8); + if (!(cflag & X509_FLAG_NO_EXTENSIONS) + && !X509V3_extensions_print(bp, "X509v3 extensions", + X509_get0_extensions(x), cflag, 8)) + goto err; if (!(cflag & X509_FLAG_NO_SIGDUMP)) { const X509_ALGOR *sig_alg; @@ -226,8 +229,11 @@ int X509_ocspid_print(BIO *bp, X509 *x) int i; unsigned char SHA1md[SHA_DIGEST_LENGTH]; ASN1_BIT_STRING *keybstr; - X509_NAME *subj; + const X509_NAME *subj; + EVP_MD *md = NULL; + if (x == NULL || bp == NULL) + return 0; /* * display the hash of the subject as it would appear in OCSP requests */ @@ -235,11 +241,16 @@ int X509_ocspid_print(BIO *bp, X509 *x) goto err; subj = X509_get_subject_name(x); derlen = i2d_X509_NAME(subj, NULL); + if (derlen <= 0) + goto err; if ((der = dertmp = OPENSSL_malloc(derlen)) == NULL) goto err; i2d_X509_NAME(subj, &dertmp); - if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL)) + md = EVP_MD_fetch(x->libctx, SN_sha1, x->propq); + if (md == NULL) + goto err; + if (!EVP_Digest(der, derlen, SHA1md, NULL, md, NULL)) goto err; for (i = 0; i < SHA_DIGEST_LENGTH; i++) { if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) @@ -260,18 +271,19 @@ int X509_ocspid_print(BIO *bp, X509 *x) goto err; if (!EVP_Digest(ASN1_STRING_get0_data(keybstr), - ASN1_STRING_length(keybstr), SHA1md, NULL, EVP_sha1(), - NULL)) + ASN1_STRING_length(keybstr), SHA1md, NULL, md, NULL)) goto err; for (i = 0; i < SHA_DIGEST_LENGTH; i++) { if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) goto err; } BIO_printf(bp, "\n"); + EVP_MD_free(md); return 1; err: OPENSSL_free(der); + EVP_MD_free(md); return 0; } @@ -284,7 +296,7 @@ int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) s = sig->data; for (i = 0; i < n; i++) { if ((i % 18) == 0) { - if (BIO_write(bp, "\n", 1) <= 0) + if (i > 0 && BIO_write(bp, "\n", 1) <= 0) return 0; if (BIO_indent(bp, indent, indent) <= 0) return 0; @@ -302,11 +314,14 @@ int X509_signature_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig) { int sig_nid; - if (BIO_puts(bp, " Signature Algorithm: ") <= 0) + int indent = 4; + if (BIO_printf(bp, "%*sSignature Algorithm: ", indent, "") <= 0) return 0; if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0; + if (sig && BIO_printf(bp, "\n%*sSignature Value:", indent, "") <= 0) + return 0; sig_nid = OBJ_obj2nid(sigalg->algorithm); if (sig_nid != NID_undef) { int pkey_nid, dig_nid; @@ -314,13 +329,13 @@ int X509_signature_print(BIO *bp, const X509_ALGOR *sigalg, if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) { ameth = EVP_PKEY_asn1_find(NULL, pkey_nid); if (ameth && ameth->sig_print) - return ameth->sig_print(bp, sigalg, sig, 9, 0); + return ameth->sig_print(bp, sigalg, sig, indent + 4, 0); } } - if (sig) - return X509_signature_dump(bp, sig, 9); - else if (BIO_puts(bp, "\n") <= 0) + if (BIO_write(bp, "\n", 1) != 1) return 0; + if (sig) + return X509_signature_dump(bp, sig, indent + 4); return 1; } @@ -377,3 +392,138 @@ int X509_aux_print(BIO *out, X509 *x, int indent) } return 1; } + +/* + * Helper functions for improving certificate verification error diagnostics + */ + +int ossl_x509_print_ex_brief(BIO *bio, X509 *cert, unsigned long neg_cflags) +{ + unsigned long flags = ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | + XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN; + + if (cert == NULL) + return BIO_printf(bio, " (no certificate)\n") > 0; + if (BIO_printf(bio, " certificate\n") <= 0 + || !X509_print_ex(bio, cert, flags, ~X509_FLAG_NO_SUBJECT)) + return 0; + if (X509_check_issued((X509 *)cert, cert) == X509_V_OK) { + if (BIO_printf(bio, " self-issued\n") <= 0) + return 0; + } else { + if (BIO_printf(bio, " ") <= 0 + || !X509_print_ex(bio, cert, flags, ~X509_FLAG_NO_ISSUER)) + return 0; + } + if (!X509_print_ex(bio, cert, flags, + ~(X509_FLAG_NO_SERIAL | X509_FLAG_NO_VALIDITY))) + return 0; + if (X509_cmp_current_time(X509_get0_notBefore(cert)) > 0) + if (BIO_printf(bio, " not yet valid\n") <= 0) + return 0; + if (X509_cmp_current_time(X509_get0_notAfter(cert)) < 0) + if (BIO_printf(bio, " no more valid\n") <= 0) + return 0; + return X509_print_ex(bio, cert, flags, + ~neg_cflags & ~X509_FLAG_EXTENSIONS_ONLY_KID); +} + +static int print_certs(BIO *bio, const STACK_OF(X509) *certs) +{ + int i; + + if (certs == NULL || sk_X509_num(certs) <= 0) + return BIO_printf(bio, " (no certificates)\n") >= 0; + + for (i = 0; i < sk_X509_num(certs); i++) { + X509 *cert = sk_X509_value(certs, i); + + if (cert != NULL) { + if (!ossl_x509_print_ex_brief(bio, cert, 0)) + return 0; + if (!X509V3_extensions_print(bio, NULL, + X509_get0_extensions(cert), + X509_FLAG_EXTENSIONS_ONLY_KID, 8)) + return 0; + } + } + return 1; +} + +static int print_store_certs(BIO *bio, X509_STORE *store) +{ + if (store != NULL) { + STACK_OF(X509) *certs = X509_STORE_get1_all_certs(store); + int ret = print_certs(bio, certs); + + sk_X509_pop_free(certs, X509_free); + return ret; + } else { + return BIO_printf(bio, " (no trusted store)\n") >= 0; + } +} + +/* Extend the error queue with details on a failed cert verification */ +int X509_STORE_CTX_print_verify_cb(int ok, X509_STORE_CTX *ctx) +{ + if (ok == 0 && ctx != NULL) { + int cert_error = X509_STORE_CTX_get_error(ctx); + BIO *bio = BIO_new(BIO_s_mem()); /* may be NULL */ + + BIO_printf(bio, "%s at depth = %d error = %d (%s)\n", + X509_STORE_CTX_get0_parent_ctx(ctx) != NULL + ? "CRL path validation" + : "Certificate verification", + X509_STORE_CTX_get_error_depth(ctx), + cert_error, X509_verify_cert_error_string(cert_error)); + { + X509_STORE *ts = X509_STORE_CTX_get0_store(ctx); + X509_VERIFY_PARAM *vpm = X509_STORE_get0_param(ts); + char *str; + int idx = 0; + + switch (cert_error) { + case X509_V_ERR_HOSTNAME_MISMATCH: + BIO_printf(bio, "Expected hostname(s) = "); + while ((str = X509_VERIFY_PARAM_get0_host(vpm, idx++)) != NULL) + BIO_printf(bio, "%s%s", idx == 1 ? "" : ", ", str); + BIO_printf(bio, "\n"); + break; + case X509_V_ERR_EMAIL_MISMATCH: + str = X509_VERIFY_PARAM_get0_email(vpm); + if (str != NULL) + BIO_printf(bio, "Expected email address = %s\n", str); + break; + case X509_V_ERR_IP_ADDRESS_MISMATCH: + str = X509_VERIFY_PARAM_get1_ip_asc(vpm); + if (str != NULL) + BIO_printf(bio, "Expected IP address = %s\n", str); + OPENSSL_free(str); + break; + default: + break; + } + } + + BIO_printf(bio, "Failure for:\n"); + ossl_x509_print_ex_brief(bio, X509_STORE_CTX_get_current_cert(ctx), + X509_FLAG_NO_EXTENSIONS); + if (cert_error == X509_V_ERR_CERT_UNTRUSTED + || cert_error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT + || cert_error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN + || cert_error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT + || cert_error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY + || cert_error == X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER + || cert_error == X509_V_ERR_STORE_LOOKUP) { + BIO_printf(bio, "Non-trusted certs:\n"); + print_certs(bio, X509_STORE_CTX_get0_untrusted(ctx)); + BIO_printf(bio, "Certs in trust store:\n"); + print_store_certs(bio, X509_STORE_CTX_get0_store(ctx)); + } + ERR_raise(ERR_LIB_X509, X509_R_CERTIFICATE_VERIFICATION_FAILED); + ERR_add_error_mem_bio("\n", bio); + BIO_free(bio); + } + + return ok; +} diff --git a/crypto/openssl/crypto/x509v3/v3_addr.c b/crypto/openssl/crypto/x509/v3_addr.c similarity index 91% rename from crypto/openssl/crypto/x509v3/v3_addr.c rename to crypto/openssl/crypto/x509/v3_addr.c index f9c368bea405..db010720741c 100644 --- a/crypto/openssl/crypto/x509v3/v3_addr.c +++ b/crypto/openssl/crypto/x509/v3_addr.c @@ -1,7 +1,7 @@ /* * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -24,6 +24,7 @@ #include #include "crypto/x509.h" #include "ext_dat.h" +#include "x509_local.h" #ifndef OPENSSL_NO_RFC3779 @@ -690,6 +691,14 @@ static int IPAddressFamily_cmp(const IPAddressFamily *const *a_, return cmp ? cmp : a->length - b->length; } +static int IPAddressFamily_check_len(const IPAddressFamily *f) +{ + if (f->addressFamily->length < 2 || f->addressFamily->length > 3) + return 0; + else + return 1; +} + /* * Check whether an IPAddrBLocks is in canonical form. */ @@ -712,6 +721,10 @@ int X509v3_addr_is_canonical(IPAddrBlocks *addr) for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); + + if (!IPAddressFamily_check_len(a) || !IPAddressFamily_check_len(b)) + return 0; + if (IPAddressFamily_cmp(&a, &b) >= 0) return 0; } @@ -738,6 +751,9 @@ int X509v3_addr_is_canonical(IPAddrBlocks *addr) return 0; } + if (!IPAddressFamily_check_len(f)) + return 0; + /* * It's an IPAddressOrRanges sequence, check it. */ @@ -882,6 +898,10 @@ int X509v3_addr_canonize(IPAddrBlocks *addr) int i; for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); + + if (!IPAddressFamily_check_len(f)) + return 0; + if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && !IPAddressOrRanges_canonize(f->ipAddressChoice-> u.addressesOrRanges, @@ -909,7 +929,7 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, int i; if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } @@ -920,20 +940,19 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, const char *addr_chars = NULL; int prefixlen, i1, i2, delim, length; - if (!name_cmp(val->name, "IPv4")) { + if (!ossl_v3_name_cmp(val->name, "IPv4")) { afi = IANA_AFI_IPV4; - } else if (!name_cmp(val->name, "IPv6")) { + } else if (!ossl_v3_name_cmp(val->name, "IPv6")) { afi = IANA_AFI_IPV6; - } else if (!name_cmp(val->name, "IPv4-SAFI")) { + } else if (!ossl_v3_name_cmp(val->name, "IPv4-SAFI")) { afi = IANA_AFI_IPV4; safi = &safi_; - } else if (!name_cmp(val->name, "IPv6-SAFI")) { + } else if (!ossl_v3_name_cmp(val->name, "IPv6-SAFI")) { afi = IANA_AFI_IPV6; safi = &safi_; } else { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_EXTENSION_NAME_ERROR); - X509V3_conf_err(val); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_EXTENSION_NAME_ERROR, + "%s", val->name); goto err; } @@ -956,8 +975,8 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, *safi = strtoul(val->value, &t, 0); t += strspn(t, " \t"); if (*safi > 0xFF || *t++ != ':') { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_SAFI); + X509V3_conf_add_error_name_value(val); goto err; } t += strspn(t, " \t"); @@ -966,7 +985,7 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, s = OPENSSL_strdup(val->value); } if (s == NULL) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } @@ -976,9 +995,8 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, */ if (strcmp(s, "inherit") == 0) { if (!X509v3_addr_add_inherit(addr, afi, safi)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_INVALID_INHERITANCE); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_INHERITANCE); + X509V3_conf_add_error_name_value(val); goto err; } OPENSSL_free(s); @@ -991,9 +1009,9 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, delim = s[i2++]; s[i1] = '\0'; - if (a2i_ipadd(min, s) != length) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); - X509V3_conf_err(val); + if (ossl_a2i_ipadd(min, s) != length) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_IPADDRESS); + X509V3_conf_add_error_name_value(val); goto err; } @@ -1004,13 +1022,12 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, || *t != '\0' || prefixlen > (length * 8) || prefixlen < 0) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_add_error_name_value(val); goto err; } if (!X509v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } break; @@ -1018,38 +1035,34 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, i1 = i2 + strspn(s + i2, " \t"); i2 = i1 + strspn(s + i1, addr_chars); if (i1 == i2 || s[i2] != '\0') { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_add_error_name_value(val); goto err; } - if (a2i_ipadd(max, s + i1) != length) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_INVALID_IPADDRESS); - X509V3_conf_err(val); + if (ossl_a2i_ipadd(max, s + i1) != length) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_IPADDRESS); + X509V3_conf_add_error_name_value(val); goto err; } if (memcmp(min, max, length_from_afi(afi)) > 0) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_add_error_name_value(val); goto err; } if (!X509v3_addr_add_range(addr, afi, safi, min, max)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } break; case '\0': if (!X509v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } break; default: - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_add_error_name_value(val); goto err; } @@ -1073,7 +1086,7 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, /* * OpenSSL dispatch */ -const X509V3_EXT_METHOD v3_addr = { +const X509V3_EXT_METHOD ossl_v3_addr = { NID_sbgp_ipAddrBlock, /* nid */ 0, /* flags */ ASN1_ITEM_ref(IPAddrBlocks), /* template */ @@ -1122,7 +1135,7 @@ static int addr_contains(IPAddressOrRanges *parent, for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { if (!extract_min_max(sk_IPAddressOrRange_value(child, c), c_min, c_max, length)) - return -1; + return 0; for (;; p++) { if (p >= sk_IPAddressOrRange_num(parent)) return 0; @@ -1154,10 +1167,12 @@ int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) for (i = 0; i < sk_IPAddressFamily_num(a); i++) { IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); int j = sk_IPAddressFamily_find(b, fa); - IPAddressFamily *fb; - fb = sk_IPAddressFamily_value(b, j); + IPAddressFamily *fb = sk_IPAddressFamily_value(b, j); + if (fb == NULL) return 0; + if (!IPAddressFamily_check_len(fa) || !IPAddressFamily_check_len(fb)) + return 0; if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, fa->ipAddressChoice->u.addressesOrRanges, length_from_afi(X509v3_addr_get_afi(fb)))) @@ -1169,19 +1184,19 @@ int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) /* * Validation error handling via callback. */ -#define validation_err(_err_) \ - do { \ - if (ctx != NULL) { \ - ctx->error = _err_; \ - ctx->error_depth = i; \ - ctx->current_cert = x; \ - ret = ctx->verify_cb(0, ctx); \ - } else { \ - ret = 0; \ - } \ - if (!ret) \ - goto done; \ - } while (0) +# define validation_err(_err_) \ + do { \ + if (ctx != NULL) { \ + ctx->error = _err_; \ + ctx->error_depth = i; \ + ctx->current_cert = x; \ + rv = ctx->verify_cb(0, ctx); \ + } else { \ + rv = 0; \ + } \ + if (rv == 0) \ + goto done; \ + } while (0) /* * Core code for RFC 3779 2.3 path validation. @@ -1196,7 +1211,7 @@ static int addr_validate_path_internal(X509_STORE_CTX *ctx, IPAddrBlocks *ext) { IPAddrBlocks *child = NULL; - int i, j, ret = 1; + int i, j, ret = 0, rv; X509 *x; if (!ossl_assert(chain != NULL && sk_X509_num(chain) > 0) @@ -1219,17 +1234,15 @@ static int addr_validate_path_internal(X509_STORE_CTX *ctx, i = 0; x = sk_X509_value(chain, i); if ((ext = x->rfc3779_addr) == NULL) - goto done; + return 1; /* Return success */ } if (!X509v3_addr_is_canonical(ext)) validation_err(X509_V_ERR_INVALID_EXTENSION); (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { - X509V3err(X509V3_F_ADDR_VALIDATE_PATH_INTERNAL, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); if (ctx != NULL) ctx->error = X509_V_ERR_OUT_OF_MEM; - ret = 0; goto done; } @@ -1244,6 +1257,10 @@ static int addr_validate_path_internal(X509_STORE_CTX *ctx, if (x->rfc3779_addr == NULL) { for (j = 0; j < sk_IPAddressFamily_num(child); j++) { IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); + + if (!IPAddressFamily_check_len(fc)) + goto done; + if (fc->ipAddressChoice->type != IPAddressChoice_inherit) { validation_err(X509_V_ERR_UNNESTED_RESOURCE); break; @@ -1258,6 +1275,7 @@ static int addr_validate_path_internal(X509_STORE_CTX *ctx, int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k); + if (fp == NULL) { if (fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) { @@ -1266,13 +1284,17 @@ static int addr_validate_path_internal(X509_STORE_CTX *ctx, } continue; } + + if (!IPAddressFamily_check_len(fc) || !IPAddressFamily_check_len(fp)) + goto done; + if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) { if (fc->ipAddressChoice->type == IPAddressChoice_inherit || addr_contains(fp->ipAddressChoice->u.addressesOrRanges, fc->ipAddressChoice->u.addressesOrRanges, length_from_afi(X509v3_addr_get_afi(fc)))) - sk_IPAddressFamily_set(child, j, fp); + (void)sk_IPAddressFamily_set(child, j, fp); else validation_err(X509_V_ERR_UNNESTED_RESOURCE); } @@ -1284,14 +1306,17 @@ static int addr_validate_path_internal(X509_STORE_CTX *ctx, */ if (x->rfc3779_addr != NULL) { for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { - IPAddressFamily *fp = - sk_IPAddressFamily_value(x->rfc3779_addr, j); + IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j); + + if (!IPAddressFamily_check_len(fp)) + goto done; + if (fp->ipAddressChoice->type == IPAddressChoice_inherit && sk_IPAddressFamily_find(child, fp) >= 0) validation_err(X509_V_ERR_UNNESTED_RESOURCE); } } - + ret = 1; done: sk_IPAddressFamily_free(child); return ret; diff --git a/crypto/openssl/crypto/x509v3/v3_admis.c b/crypto/openssl/crypto/x509/v3_admis.c similarity index 98% rename from crypto/openssl/crypto/x509v3/v3_admis.c rename to crypto/openssl/crypto/x509/v3_admis.c index c8e75191bb3b..3bce232ed2fe 100644 --- a/crypto/openssl/crypto/x509v3/v3_admis.c +++ b/crypto/openssl/crypto/x509/v3_admis.c @@ -1,7 +1,7 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,7 +9,7 @@ #include #include "internal/cryptlib.h" #include -#include +#include #include #include @@ -20,7 +20,6 @@ #include "v3_admis.h" #include "ext_dat.h" - ASN1_SEQUENCE(NAMING_AUTHORITY) = { ASN1_OPT(NAMING_AUTHORITY, namingAuthorityId, ASN1_OBJECT), ASN1_OPT(NAMING_AUTHORITY, namingAuthorityUrl, ASN1_IA5STRING), @@ -54,7 +53,7 @@ IMPLEMENT_ASN1_FUNCTIONS(ADMISSION_SYNTAX) static int i2r_ADMISSION_SYNTAX(const struct v3_ext_method *method, void *in, BIO *bp, int ind); -const X509V3_EXT_METHOD v3_ext_admission = { +const X509V3_EXT_METHOD ossl_v3_ext_admission = { NID_x509ExtAdmission, /* .ext_nid = */ 0, /* .ext_flags = */ ASN1_ITEM_ref(ADMISSION_SYNTAX), /* .it = */ @@ -200,7 +199,7 @@ static int i2r_ADMISSION_SYNTAX(const struct v3_ext_method *method, void *in, return 1; err: - return -1; + return 0; } const ASN1_OBJECT *NAMING_AUTHORITY_get0_authorityId(const NAMING_AUTHORITY *n) diff --git a/crypto/openssl/crypto/x509v3/v3_admis.h b/crypto/openssl/crypto/x509/v3_admis.h similarity index 86% rename from crypto/openssl/crypto/x509v3/v3_admis.h rename to crypto/openssl/crypto/x509/v3_admis.h index ea7632b3708d..1e82c0f4a33f 100644 --- a/crypto/openssl/crypto/x509v3/v3_admis.h +++ b/crypto/openssl/crypto/x509/v3_admis.h @@ -1,14 +1,14 @@ /* * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -#ifndef OSSL_CRYPTO_X509V3_V3_ADMIS_H -# define OSSL_CRYPTO_X509V3_V3_ADMIS_H +#ifndef OSSL_CRYPTO_X509_V3_ADMIS_H +# define OSSL_CRYPTO_X509_V3_ADMIS_H struct NamingAuthority_st { ASN1_OBJECT* namingAuthorityId; diff --git a/crypto/openssl/crypto/x509v3/v3_akeya.c b/crypto/openssl/crypto/x509/v3_akeya.c similarity index 90% rename from crypto/openssl/crypto/x509v3/v3_akeya.c rename to crypto/openssl/crypto/x509/v3_akeya.c index d6dd6bcb9b96..aae8c21e73c2 100644 --- a/crypto/openssl/crypto/x509v3/v3_akeya.c +++ b/crypto/openssl/crypto/x509/v3_akeya.c @@ -1,7 +1,7 @@ /* * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/x509v3/v3_akey.c b/crypto/openssl/crypto/x509/v3_akid.c similarity index 58% rename from crypto/openssl/crypto/x509v3/v3_akey.c rename to crypto/openssl/crypto/x509/v3_akid.c index 33b1933d7228..43b515f50c49 100644 --- a/crypto/openssl/crypto/x509v3/v3_akey.c +++ b/crypto/openssl/crypto/x509/v3_akid.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,6 +13,7 @@ #include #include #include +#include "crypto/x509.h" #include "ext_dat.h" static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, @@ -23,7 +24,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); -const X509V3_EXT_METHOD v3_akey_id = { +const X509V3_EXT_METHOD ossl_v3_akey_id = { NID_authority_key_identifier, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID), 0, 0, 0, 0, @@ -45,12 +46,13 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, if (akeyid->keyid) { tmp = OPENSSL_buf2hexstr(akeyid->keyid->data, akeyid->keyid->length); if (tmp == NULL) { - X509V3err(X509V3_F_I2V_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } - if (!X509V3_add_value("keyid", tmp, &extlist)) { + if (!X509V3_add_value((akeyid->issuer || akeyid->serial) ? "keyid" : NULL, + tmp, &extlist)) { OPENSSL_free(tmp); - X509V3err(X509V3_F_I2V_AUTHORITY_KEYID, ERR_R_X509_LIB); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509_LIB); goto err; } OPENSSL_free(tmp); @@ -58,7 +60,7 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, if (akeyid->issuer) { tmpextlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); if (tmpextlist == NULL) { - X509V3err(X509V3_F_I2V_AUTHORITY_KEYID, ERR_R_X509_LIB); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509_LIB); goto err; } extlist = tmpextlist; @@ -66,12 +68,11 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, if (akeyid->serial) { tmp = OPENSSL_buf2hexstr(akeyid->serial->data, akeyid->serial->length); if (tmp == NULL) { - X509V3err(X509V3_F_I2V_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } if (!X509V3_add_value("serial", tmp, &extlist)) { OPENSSL_free(tmp); - X509V3err(X509V3_F_I2V_AUTHORITY_KEYID, ERR_R_X509_LIB); goto err; } OPENSSL_free(tmp); @@ -97,7 +98,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, STACK_OF(CONF_VALUE) *values) { char keyid = 0, issuer = 0; - int i; + int i, n = sk_CONF_VALUE_num(values); CONF_VALUE *cnf; ASN1_OCTET_STRING *ikeyid = NULL; X509_NAME *isname = NULL; @@ -105,10 +106,18 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, GENERAL_NAME *gen = NULL; ASN1_INTEGER *serial = NULL; X509_EXTENSION *ext; - X509 *cert; - AUTHORITY_KEYID *akeyid; + X509 *issuer_cert; + int same_issuer, ss; + AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new(); - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + if (akeyid == NULL) + goto err; + + if (n == 1 && strcmp(sk_CONF_VALUE_value(values, 0)->name, "none") == 0) { + return akeyid; + } + + for (i = 0; i < n; i++) { cnf = sk_CONF_VALUE_value(values, i); if (strcmp(cnf->name, "keyid") == 0) { keyid = 1; @@ -119,51 +128,71 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, if (cnf->value && strcmp(cnf->value, "always") == 0) issuer = 2; } else { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, X509V3_R_UNKNOWN_OPTION); - ERR_add_error_data(2, "name=", cnf->name); - return NULL; + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNKNOWN_OPTION, + "name=%s", cnf->name); + goto err; } } - if (!ctx || !ctx->issuer_cert) { - if (ctx && (ctx->flags == CTX_TEST)) - return AUTHORITY_KEYID_new(); - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, - X509V3_R_NO_ISSUER_CERTIFICATE); - return NULL; - } - - cert = ctx->issuer_cert; + if (ctx != NULL && (ctx->flags & X509V3_CTX_TEST) != 0) + return akeyid; - if (keyid) { - i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); - if ((i >= 0) && (ext = X509_get_ext(cert, i))) + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + if ((issuer_cert = ctx->issuer_cert) == NULL) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE); + goto err; + } + same_issuer = ctx->subject_cert == ctx->issuer_cert; + ERR_set_mark(); + if (ctx->issuer_pkey != NULL) + ss = X509_check_private_key(ctx->subject_cert, ctx->issuer_pkey); + else + ss = same_issuer; + ERR_pop_to_mark(); + + /* unless forced with "always", AKID is suppressed for self-signed certs */ + if (keyid == 2 || (keyid == 1 && !ss)) { + /* + * prefer any pre-existing subject key identifier of the issuer cert + * except issuer cert is same as subject cert and is not self-signed + */ + i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1); + if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL + && !(same_issuer && !ss)) ikeyid = X509V3_EXT_d2i(ext); - if (keyid == 2 && !ikeyid) { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, - X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); - return NULL; + if (ikeyid == NULL && same_issuer && ctx->issuer_pkey != NULL) { + /* generate fallback AKID, emulating s2i_skey_id(..., "hash") */ + X509_PUBKEY *pubkey = NULL; + + if (X509_PUBKEY_set(&pubkey, ctx->issuer_pkey)) + ikeyid = ossl_x509_pubkey_hash(pubkey); + X509_PUBKEY_free(pubkey); + } + if ((keyid == 2 || issuer == 0) + && (ikeyid == NULL + || ASN1_STRING_length(ikeyid) <= 2) /* indicating "none" */) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); + goto err; } } - if ((issuer && !ikeyid) || (issuer == 2)) { - isname = X509_NAME_dup(X509_get_issuer_name(cert)); - serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); - if (!isname || !serial) { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, - X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); + if (issuer == 2 || (issuer == 1 && ikeyid == NULL)) { + isname = X509_NAME_dup(X509_get_issuer_name(issuer_cert)); + serial = ASN1_INTEGER_dup(X509_get0_serialNumber(issuer_cert)); + if (isname == NULL || serial == NULL) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); goto err; } } - if ((akeyid = AUTHORITY_KEYID_new()) == NULL) - goto err; - - if (isname) { + if (isname != NULL) { if ((gens = sk_GENERAL_NAME_new_null()) == NULL || (gen = GENERAL_NAME_new()) == NULL || !sk_GENERAL_NAME_push(gens, gen)) { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } gen->type = GEN_DIRNAME; @@ -184,5 +213,6 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, X509_NAME_free(isname); ASN1_INTEGER_free(serial); ASN1_OCTET_STRING_free(ikeyid); + AUTHORITY_KEYID_free(akeyid); return NULL; } diff --git a/crypto/openssl/crypto/x509v3/v3_asid.c b/crypto/openssl/crypto/x509/v3_asid.c similarity index 92% rename from crypto/openssl/crypto/x509v3/v3_asid.c rename to crypto/openssl/crypto/x509/v3_asid.c index 8e9e919804d0..86577d6ca48c 100644 --- a/crypto/openssl/crypto/x509v3/v3_asid.c +++ b/crypto/openssl/crypto/x509/v3_asid.c @@ -1,7 +1,7 @@ /* * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -23,6 +23,7 @@ #include "crypto/x509.h" #include #include "ext_dat.h" +#include "x509_local.h" #ifndef OPENSSL_NO_RFC3779 @@ -300,16 +301,14 @@ static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) if ((bn == NULL && (bn = BN_new()) == NULL) || ASN1_INTEGER_to_BN(a_max, bn) == NULL || !BN_add_word(bn, 1)) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto done; } if ((a_max_plus_one = BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { a_max_plus_one = orig; - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto done; } @@ -373,8 +372,7 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) */ if (choice->type != ASIdentifierChoice_asIdsOrRanges || sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, - X509V3_R_EXTENSION_VALUE_ERROR); + ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR); return 0; } @@ -414,8 +412,7 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) * Check for overlaps. */ if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, - X509V3_R_EXTENSION_VALUE_ERROR); + ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR); goto done; } @@ -425,16 +422,14 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) if ((bn == NULL && (bn = BN_new()) == NULL) || ASN1_INTEGER_to_BN(a_max, bn) == NULL || !BN_add_word(bn, 1)) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto done; } if ((a_max_plus_one = BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { a_max_plus_one = orig; - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto done; } @@ -446,8 +441,7 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) switch (a->type) { case ASIdOrRange_id: if ((r = OPENSSL_malloc(sizeof(*r))) == NULL) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto done; } r->min = a_min; @@ -523,7 +517,7 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method, int i; if ((asid = ASIdentifiers_new()) == NULL) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } @@ -534,14 +528,13 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method, /* * Figure out whether this is an AS or an RDI. */ - if (!name_cmp(val->name, "AS")) { + if (!ossl_v3_name_cmp(val->name, "AS")) { which = V3_ASID_ASNUM; - } else if (!name_cmp(val->name, "RDI")) { + } else if (!ossl_v3_name_cmp(val->name, "RDI")) { which = V3_ASID_RDI; } else { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, - X509V3_R_EXTENSION_NAME_ERROR); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_NAME_ERROR); + X509V3_conf_add_error_name_value(val); goto err; } @@ -551,9 +544,8 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method, if (strcmp(val->value, "inherit") == 0) { if (X509v3_asid_add_inherit(asid, which)) continue; - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, - X509V3_R_INVALID_INHERITANCE); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_INHERITANCE); + X509V3_conf_add_error_name_value(val); goto err; } @@ -567,18 +559,16 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method, is_range = 1; i2 = i1 + strspn(val->value + i1, " \t"); if (val->value[i2] != '-') { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, - X509V3_R_INVALID_ASNUMBER); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_ASNUMBER); + X509V3_conf_add_error_name_value(val); goto err; } i2++; i2 = i2 + strspn(val->value + i2, " \t"); i3 = i2 + strspn(val->value + i2, "0123456789"); if (val->value[i3] != '\0') { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, - X509V3_R_INVALID_ASRANGE); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_ASRANGE); + X509V3_conf_add_error_name_value(val); goto err; } } @@ -588,13 +578,13 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method, */ if (!is_range) { if (!X509V3_get_value_int(val, &min)) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } } else { char *s = OPENSSL_strdup(val->value); if (s == NULL) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } s[i1] = '\0'; @@ -602,17 +592,16 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method, max = s2i_ASN1_INTEGER(NULL, s + i2); OPENSSL_free(s); if (min == NULL || max == NULL) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } if (ASN1_INTEGER_cmp(min, max) > 0) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, - X509V3_R_EXTENSION_VALUE_ERROR); + ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR); goto err; } } if (!X509v3_asid_add_id_or_range(asid, which, min, max)) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } min = max = NULL; @@ -635,7 +624,7 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method, /* * OpenSSL dispatch. */ -const X509V3_EXT_METHOD v3_asid = { +const X509V3_EXT_METHOD ossl_v3_asid = { NID_sbgp_autonomousSysNum, /* nid */ 0, /* flags */ ASN1_ITEM_ref(ASIdentifiers), /* template */ diff --git a/crypto/openssl/crypto/x509v3/v3_bcons.c b/crypto/openssl/crypto/x509/v3_bcons.c similarity index 87% rename from crypto/openssl/crypto/x509v3/v3_bcons.c rename to crypto/openssl/crypto/x509/v3_bcons.c index 3bbf15550d32..6e7a165f26e8 100644 --- a/crypto/openssl/crypto/x509v3/v3_bcons.c +++ b/crypto/openssl/crypto/x509/v3_bcons.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,6 +14,7 @@ #include #include #include "ext_dat.h" +#include "x509_local.h" static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, @@ -23,7 +24,7 @@ static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); -const X509V3_EXT_METHOD v3_bcons = { +const X509V3_EXT_METHOD ossl_v3_bcons = { NID_basic_constraints, 0, ASN1_ITEM_ref(BASIC_CONSTRAINTS), 0, 0, 0, 0, @@ -60,7 +61,7 @@ static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, int i; if ((bcons = BASIC_CONSTRAINTS_new()) == NULL) { - X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } for (i = 0; i < sk_CONF_VALUE_num(values); i++) { @@ -72,8 +73,8 @@ static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, if (!X509V3_get_value_int(val, &bcons->pathlen)) goto err; } else { - X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_add_error_name_value(val); goto err; } } diff --git a/crypto/openssl/crypto/x509v3/v3_bitst.c b/crypto/openssl/crypto/x509/v3_bitst.c similarity index 82% rename from crypto/openssl/crypto/x509v3/v3_bitst.c rename to crypto/openssl/crypto/x509/v3_bitst.c index 4802116ba0d4..b53c5ba3ecd3 100644 --- a/crypto/openssl/crypto/x509v3/v3_bitst.c +++ b/crypto/openssl/crypto/x509/v3_bitst.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -38,9 +38,9 @@ static BIT_STRING_BITNAME key_usage_type_table[] = { {-1, NULL, NULL} }; -const X509V3_EXT_METHOD v3_nscert = +const X509V3_EXT_METHOD ossl_v3_nscert = EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table); -const X509V3_EXT_METHOD v3_key_usage = +const X509V3_EXT_METHOD ossl_v3_key_usage = EXT_BITSTRING(NID_key_usage, key_usage_type_table); STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, @@ -64,7 +64,7 @@ ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, int i; BIT_STRING_BITNAME *bnam; if ((bs = ASN1_BIT_STRING_new()) == NULL) { - X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { @@ -73,8 +73,7 @@ ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, if (strcmp(bnam->sname, val->name) == 0 || strcmp(bnam->lname, val->name) == 0) { if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) { - X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); ASN1_BIT_STRING_free(bs); return NULL; } @@ -82,9 +81,8 @@ ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, } } if (!bnam->lname) { - X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, - X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); - X509V3_conf_err(val); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT, + "%s", val->name); ASN1_BIT_STRING_free(bs); return NULL; } diff --git a/crypto/openssl/crypto/x509v3/v3_conf.c b/crypto/openssl/crypto/x509/v3_conf.c similarity index 69% rename from crypto/openssl/crypto/x509v3/v3_conf.c rename to crypto/openssl/crypto/x509/v3_conf.c index e93de3454604..1c11d671b2ed 100644 --- a/crypto/openssl/crypto/x509v3/v3_conf.c +++ b/crypto/openssl/crypto/x509/v3_conf.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -30,33 +30,43 @@ static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit, void *ext_struc); static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, long *ext_len); -/* CONF *conf: Config file */ -/* char *name: Name */ -/* char *value: Value */ -X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, - const char *value) + +static X509_EXTENSION *X509V3_EXT_nconf_int(CONF *conf, X509V3_CTX *ctx, + const char *section, + const char *name, const char *value) { int crit; int ext_type; X509_EXTENSION *ret; + crit = v3_check_critical(&value); if ((ext_type = v3_check_generic(&value))) return v3_generic_extension(name, value, crit, ext_type, ctx); ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); if (!ret) { - X509V3err(X509V3_F_X509V3_EXT_NCONF, X509V3_R_ERROR_IN_EXTENSION); - ERR_add_error_data(4, "name=", name, ", value=", value); + if (section != NULL) + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_ERROR_IN_EXTENSION, + "section=%s, name=%s, value=%s", + section, name, value); + else + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_ERROR_IN_EXTENSION, + "name=%s, value=%s", name, value); } return ret; } -/* CONF *conf: Config file */ -/* char *value: Value */ +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, + const char *value) +{ + return X509V3_EXT_nconf_int(conf, ctx, NULL, name, value); +} + X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, const char *value) { int crit; int ext_type; + crit = v3_check_critical(&value); if ((ext_type = v3_check_generic(&value))) return v3_generic_extension(OBJ_nid2sn(ext_nid), @@ -75,11 +85,11 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, void *ext_struc; if (ext_nid == NID_undef) { - X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION_NAME); + ERR_raise(ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME); return NULL; } if ((method = X509V3_EXT_get_nid(ext_nid)) == NULL) { - X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION); + ERR_raise(ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION); return NULL; } /* Now get internal extension representation based on type */ @@ -89,10 +99,8 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, else nval = X509V3_parse_list(value); if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) { - X509V3err(X509V3_F_DO_EXT_NCONF, - X509V3_R_INVALID_EXTENSION_STRING); - ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", - value); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_INVALID_EXTENSION_STRING, + "name=%s,section=%s", OBJ_nid2sn(ext_nid), value); if (*value != '@') sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); return NULL; @@ -107,15 +115,14 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, return NULL; } else if (method->r2i) { if (!ctx->db || !ctx->db_meth) { - X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_NO_CONFIG_DATABASE); + ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_CONFIG_DATABASE); return NULL; } if ((ext_struc = method->r2i(method, ctx, value)) == NULL) return NULL; } else { - X509V3err(X509V3_F_DO_EXT_NCONF, - X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); - ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid)); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED, + "name=%s", OBJ_nid2sn(ext_nid)); return NULL; } @@ -135,6 +142,7 @@ static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_len; ASN1_OCTET_STRING *ext_oct = NULL; X509_EXTENSION *ext; + /* Convert internal representation to DER */ if (method->it) { ext_der = NULL; @@ -146,6 +154,8 @@ static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, unsigned char *p; ext_len = method->i2d(ext_struc, NULL); + if (ext_len <= 0) + goto merr; if ((ext_der = OPENSSL_malloc(ext_len)) == NULL) goto merr; p = ext_der; @@ -165,7 +175,7 @@ static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, return ext; merr: - X509V3err(X509V3_F_DO_EXT_I2D, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); OPENSSL_free(ext_der); ASN1_OCTET_STRING_free(ext_oct); return NULL; @@ -179,7 +189,7 @@ X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) const X509V3_EXT_METHOD *method; if ((method = X509V3_EXT_get_nid(ext_nid)) == NULL) { - X509V3err(X509V3_F_X509V3_EXT_I2D, X509V3_R_UNKNOWN_EXTENSION); + ERR_raise(ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION); return NULL; } return do_ext_i2d(method, ext_nid, crit, ext_struc); @@ -189,6 +199,7 @@ X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) static int v3_check_critical(const char **value) { const char *p = *value; + if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) return 0; p += 9; @@ -203,6 +214,7 @@ static int v3_check_generic(const char **value) { int gen_type = 0; const char *p = *value; + if ((strlen(p) >= 4) && strncmp(p, "DER:", 4) == 0) { p += 4; gen_type = 1; @@ -230,9 +242,8 @@ static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, X509_EXTENSION *extension = NULL; if ((obj = OBJ_txt2obj(ext, 0)) == NULL) { - X509V3err(X509V3_F_V3_GENERIC_EXTENSION, - X509V3_R_EXTENSION_NAME_ERROR); - ERR_add_error_data(2, "name=", ext); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_EXTENSION_NAME_ERROR, + "name=%s", ext); goto err; } @@ -242,14 +253,13 @@ static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, ext_der = generic_asn1(value, ctx, &ext_len); if (ext_der == NULL) { - X509V3err(X509V3_F_V3_GENERIC_EXTENSION, - X509V3_R_EXTENSION_VALUE_ERROR); - ERR_add_error_data(2, "value=", value); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR, + "value=%s", value); goto err; } if ((oct = ASN1_OCTET_STRING_new()) == NULL) { - X509V3err(X509V3_F_V3_GENERIC_EXTENSION, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } @@ -272,6 +282,7 @@ static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, { ASN1_TYPE *typ; unsigned char *ext_der = NULL; + typ = ASN1_generate_v3(value, ctx); if (typ == NULL) return NULL; @@ -284,19 +295,17 @@ static void delete_ext(STACK_OF(X509_EXTENSION) *sk, X509_EXTENSION *dext) { int idx; ASN1_OBJECT *obj; + obj = X509_EXTENSION_get_object(dext); - while ((idx = X509v3_get_ext_by_OBJ(sk, obj, -1)) >= 0) { - X509_EXTENSION *tmpext = X509v3_get_ext(sk, idx); - X509v3_delete_ext(sk, idx); - X509_EXTENSION_free(tmpext); - } + while ((idx = X509v3_get_ext_by_OBJ(sk, obj, -1)) >= 0) + X509_EXTENSION_free(X509v3_delete_ext(sk, idx)); } /* * This is the main function: add a bunch of extensions based on a config - * file section to an extension STACK. + * file section to an extension STACK. Just check in case sk == NULL. + * Note that on error new elements may have been added to *sk if sk != NULL. */ - int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, STACK_OF(X509_EXTENSION) **sk) { @@ -309,11 +318,12 @@ int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, return 0; for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { val = sk_CONF_VALUE_value(nval, i); - if ((ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)) == NULL) + if ((ext = X509V3_EXT_nconf_int(conf, ctx, val->section, + val->name, val->value)) == NULL) return 0; - if (ctx->flags == X509V3_CTX_REPLACE) - delete_ext(*sk, ext); if (sk != NULL) { + if (ctx->flags == X509V3_CTX_REPLACE) + delete_ext(*sk, ext); if (X509v3_add_ext(sk, ext, -1) == NULL) { X509_EXTENSION_free(ext); return 0; @@ -325,44 +335,45 @@ int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, } /* - * Convenience functions to add extensions to a certificate, CRL and request + * Add extensions to a certificate. Just check in case cert == NULL. + * Note that on error new elements may remain added to cert if cert != NULL. */ - int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, X509 *cert) { STACK_OF(X509_EXTENSION) **sk = NULL; - if (cert) + if (cert != NULL) sk = &cert->cert_info.extensions; return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); } -/* Same as above but for a CRL */ - +/* + * Add extensions to a CRL. Just check in case crl == NULL. + * Note that on error new elements may remain added to crl if crl != NULL. + */ int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, X509_CRL *crl) { STACK_OF(X509_EXTENSION) **sk = NULL; - if (crl) + if (crl != NULL) sk = &crl->crl.extensions; return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); } -/* Add extensions to certificate request */ - +/* + * Add extensions to certificate request. Just check in case req is NULL. + * Note that on error new elements may remain added to req if req != NULL. + */ int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, X509_REQ *req) { - STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; - int i; - if (req) - sk = &extlist; - i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); - if (!i || !sk) - return i; - i = X509_REQ_add_extensions(req, extlist); - sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); - return i; + STACK_OF(X509_EXTENSION) *exts = NULL; + int ret = X509V3_EXT_add_nconf_sk(conf, ctx, section, &exts); + + if (ret && req != NULL && exts != NULL) + ret = X509_REQ_add_extensions(req, exts); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + return ret; } /* Config database functions */ @@ -370,7 +381,7 @@ int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section) { if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) { - X509V3err(X509V3_F_X509V3_GET_STRING, X509V3_R_OPERATION_NOT_DEFINED); + ERR_raise(ERR_LIB_X509V3, X509V3_R_OPERATION_NOT_DEFINED); return NULL; } if (ctx->db_meth->get_string) @@ -381,8 +392,7 @@ char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section) STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section) { if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) { - X509V3err(X509V3_F_X509V3_GET_SECTION, - X509V3_R_OPERATION_NOT_DEFINED); + ERR_raise(ERR_LIB_X509V3, X509V3_R_OPERATION_NOT_DEFINED); return NULL; } if (ctx->db_meth->get_section) @@ -425,6 +435,10 @@ static X509V3_CONF_METHOD nconf_method = { void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) { + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); + return; + } ctx->db_meth = &nconf_method; ctx->db = conf; } @@ -432,11 +446,33 @@ void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, X509_CRL *crl, int flags) { + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); + return; + } + ctx->flags = flags; ctx->issuer_cert = issuer; ctx->subject_cert = subj; - ctx->crl = crl; ctx->subject_req = req; - ctx->flags = flags; + ctx->crl = crl; + ctx->db_meth = NULL; + ctx->db = NULL; + ctx->issuer_pkey = NULL; +} + +/* For API backward compatibility, this is separate from X509V3_set_ctx() */ +int X509V3_set_issuer_pkey(X509V3_CTX *ctx, EVP_PKEY *pkey) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ctx->subject_cert == NULL && pkey != NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + ctx->issuer_pkey = pkey; + return 1; } /* Old conf compatibility functions */ @@ -444,19 +480,31 @@ void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, const char *name, const char *value) { - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_nconf(&ctmp, ctx, name, value); + CONF *ctmp; + X509_EXTENSION *ret; + + if ((ctmp = NCONF_new(NULL)) == NULL) + return NULL; + CONF_set_nconf(ctmp, conf); + ret = X509V3_EXT_nconf(ctmp, ctx, name, value); + CONF_set_nconf(ctmp, NULL); + NCONF_free(ctmp); + return ret; } -/* LHASH *conf: Config file */ -/* char *value: Value */ X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int ext_nid, const char *value) { - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value); + CONF *ctmp; + X509_EXTENSION *ret; + + if ((ctmp = NCONF_new(NULL)) == NULL) + return NULL; + CONF_set_nconf(ctmp, conf); + ret = X509V3_EXT_nconf_nid(ctmp, ctx, ext_nid, value); + CONF_set_nconf(ctmp, NULL); + NCONF_free(ctmp); + return ret; } static char *conf_lhash_get_string(void *db, const char *section, const char *value) @@ -478,6 +526,10 @@ static X509V3_CONF_METHOD conf_lhash_method = { void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash) { + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); + return; + } ctx->db_meth = &conf_lhash_method; ctx->db = lhash; } @@ -485,9 +537,16 @@ void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash) int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, const char *section, X509 *cert) { - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert); + CONF *ctmp; + int ret; + + if ((ctmp = NCONF_new(NULL)) == NULL) + return 0; + CONF_set_nconf(ctmp, conf); + ret = X509V3_EXT_add_nconf(ctmp, ctx, section, cert); + CONF_set_nconf(ctmp, NULL); + NCONF_free(ctmp); + return ret; } /* Same as above but for a CRL */ @@ -495,9 +554,16 @@ int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, const char *section, X509_CRL *crl) { - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl); + CONF *ctmp; + int ret; + + if ((ctmp = NCONF_new(NULL)) == NULL) + return 0; + CONF_set_nconf(ctmp, conf); + ret = X509V3_EXT_CRL_add_nconf(ctmp, ctx, section, crl); + CONF_set_nconf(ctmp, NULL); + NCONF_free(ctmp); + return ret; } /* Add extensions to certificate request */ @@ -505,7 +571,14 @@ int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, const char *section, X509_REQ *req) { - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req); + CONF *ctmp; + int ret; + + if ((ctmp = NCONF_new(NULL)) == NULL) + return 0; + CONF_set_nconf(ctmp, conf); + ret = X509V3_EXT_REQ_add_nconf(ctmp, ctx, section, req); + CONF_set_nconf(ctmp, NULL); + NCONF_free(ctmp); + return ret; } diff --git a/crypto/openssl/crypto/x509v3/v3_cpols.c b/crypto/openssl/crypto/x509/v3_cpols.c similarity index 85% rename from crypto/openssl/crypto/x509v3/v3_cpols.c rename to crypto/openssl/crypto/x509/v3_cpols.c index 09804b58482c..5353a6916761 100644 --- a/crypto/openssl/crypto/x509v3/v3_cpols.c +++ b/crypto/openssl/crypto/x509/v3_cpols.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,6 +14,7 @@ #include #include +#include "x509_local.h" #include "pcy_local.h" #include "ext_dat.h" @@ -34,7 +35,7 @@ static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); static int displaytext_str2tag(const char *tagstr, unsigned int *tag_len); static int displaytext_get_tag_len(const char *tagstr); -const X509V3_EXT_METHOD v3_cpols = { +const X509V3_EXT_METHOD ossl_v3_cpols = { NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES), 0, 0, 0, 0, 0, 0, @@ -98,24 +99,22 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, int i, ia5org; if (vals == NULL) { - X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); return NULL; } pols = sk_POLICYINFO_new_reserve(NULL, num); if (pols == NULL) { - X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } ia5org = 0; for (i = 0; i < num; i++) { cnf = sk_CONF_VALUE_value(vals, i); - - if (cnf->value || !cnf->name) { - X509V3err(X509V3_F_R2I_CERTPOL, - X509V3_R_INVALID_POLICY_IDENTIFIER); - X509V3_conf_err(cnf); + if (cnf->value != NULL || cnf->name == NULL) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER); + X509V3_conf_add_error_name_value(cnf); goto err; } pstr = cnf->name; @@ -124,11 +123,11 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, continue; } else if (*pstr == '@') { STACK_OF(CONF_VALUE) *polsect; - polsect = X509V3_get_section(ctx, pstr + 1); - if (!polsect) { - X509V3err(X509V3_F_R2I_CERTPOL, X509V3_R_INVALID_SECTION); - X509V3_conf_err(cnf); + polsect = X509V3_get_section(ctx, pstr + 1); + if (polsect == NULL) { + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_INVALID_SECTION, + "%s", cnf->name); goto err; } pol = policy_section(ctx, polsect, ia5org); @@ -137,22 +136,22 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, goto err; } else { if ((pobj = OBJ_txt2obj(cnf->name, 0)) == NULL) { - X509V3err(X509V3_F_R2I_CERTPOL, - X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(cnf); + ERR_raise_data(ERR_LIB_X509V3, + X509V3_R_INVALID_OBJECT_IDENTIFIER, + "%s", cnf->name); goto err; } pol = POLICYINFO_new(); if (pol == NULL) { ASN1_OBJECT_free(pobj); - X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } pol->policyid = pobj; } if (!sk_POLICYINFO_push(pols, pol)) { POLICYINFO_free(pol); - X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } } @@ -178,15 +177,15 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, cnf = sk_CONF_VALUE_value(polstrs, i); if (strcmp(cnf->name, "policyIdentifier") == 0) { ASN1_OBJECT *pobj; + if ((pobj = OBJ_txt2obj(cnf->value, 0)) == NULL) { - X509V3err(X509V3_F_POLICY_SECTION, - X509V3_R_INVALID_OBJECT_IDENTIFIER); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); X509V3_conf_err(cnf); goto err; } pol->policyid = pobj; - } else if (!name_cmp(cnf->name, "CPS")) { + } else if (!ossl_v3_name_cmp(cnf->name, "CPS")) { if (pol->qualifiers == NULL) pol->qualifiers = sk_POLICYQUALINFO_new_null(); if ((qual = POLICYQUALINFO_new()) == NULL) @@ -194,7 +193,7 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) goto merr; if ((qual->pqualid = OBJ_nid2obj(NID_id_qt_cps)) == NULL) { - X509V3err(X509V3_F_POLICY_SECTION, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_X509V3, ERR_R_INTERNAL_ERROR); goto err; } if ((qual->d.cpsuri = ASN1_IA5STRING_new()) == NULL) @@ -202,17 +201,16 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, strlen(cnf->value))) goto merr; - } else if (!name_cmp(cnf->name, "userNotice")) { + } else if (!ossl_v3_name_cmp(cnf->name, "userNotice")) { STACK_OF(CONF_VALUE) *unot; if (*cnf->value != '@') { - X509V3err(X509V3_F_POLICY_SECTION, - X509V3_R_EXPECTED_A_SECTION_NAME); + ERR_raise(ERR_LIB_X509V3, X509V3_R_EXPECTED_A_SECTION_NAME); X509V3_conf_err(cnf); goto err; } unot = X509V3_get_section(ctx, cnf->value + 1); if (!unot) { - X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_SECTION); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_SECTION); X509V3_conf_err(cnf); goto err; @@ -221,26 +219,25 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, X509V3_section_free(ctx, unot); if (!qual) goto err; - if (!pol->qualifiers) + if (pol->qualifiers == NULL) pol->qualifiers = sk_POLICYQUALINFO_new_null(); if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) goto merr; } else { - X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_OPTION); - + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_OPTION); X509V3_conf_err(cnf); goto err; } } - if (!pol->policyid) { - X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_NO_POLICY_IDENTIFIER); + if (pol->policyid == NULL) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_POLICY_IDENTIFIER); goto err; } return pol; merr: - X509V3err(X509V3_F_POLICY_SECTION, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); err: POLICYINFO_free(pol); @@ -293,7 +290,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, if ((qual = POLICYQUALINFO_new()) == NULL) goto merr; if ((qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice)) == NULL) { - X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_X509V3, ERR_R_INTERNAL_ERROR); goto err; } if ((not = USERNOTICE_new()) == NULL) @@ -301,6 +298,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, qual->d.usernotice = not; for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { cnf = sk_CONF_VALUE_value(unot, i); + value = cnf->value; if (strcmp(cnf->name, "explicitText") == 0) { tag = displaytext_str2tag(value, &tag_len); @@ -313,6 +311,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, goto merr; } else if (strcmp(cnf->name, "organization") == 0) { NOTICEREF *nref; + if (!not->noticeref) { if ((nref = NOTICEREF_new()) == NULL) goto merr; @@ -328,6 +327,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, goto merr; } else if (strcmp(cnf->name, "noticeNumbers") == 0) { NOTICEREF *nref; + STACK_OF(CONF_VALUE) *nos; if (!not->noticeref) { if ((nref = NOTICEREF_new()) == NULL) @@ -337,8 +337,8 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, nref = not->noticeref; nos = X509V3_parse_list(cnf->value); if (!nos || !sk_CONF_VALUE_num(nos)) { - X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_NUMBERS); - X509V3_conf_err(cnf); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NUMBERS); + X509V3_conf_add_error_name_value(cnf); sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); goto err; } @@ -347,23 +347,22 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, if (!ret) goto err; } else { - X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_OPTION); - X509V3_conf_err(cnf); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_OPTION); + X509V3_conf_add_error_name_value(cnf); goto err; } } if (not->noticeref && (!not->noticeref->noticenos || !not->noticeref->organization)) { - X509V3err(X509V3_F_NOTICE_SECTION, - X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); + ERR_raise(ERR_LIB_X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); goto err; } return qual; merr: - X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); err: POLICYQUALINFO_free(qual); @@ -380,7 +379,7 @@ static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) for (i = 0; i < sk_CONF_VALUE_num(nos); i++) { cnf = sk_CONF_VALUE_value(nos, i); if ((aint = s2i_ASN1_INTEGER(NULL, cnf->name)) == NULL) { - X509V3err(X509V3_F_NREF_NOS, X509V3_R_INVALID_NUMBER); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NUMBER); goto err; } if (!sk_ASN1_INTEGER_push(nnums, aint)) @@ -390,7 +389,7 @@ static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) merr: ASN1_INTEGER_free(aint); - X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); err: return 0; @@ -403,12 +402,15 @@ static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, POLICYINFO *pinfo; /* First print out the policy OIDs */ for (i = 0; i < sk_POLICYINFO_num(pol); i++) { + if (i > 0) + BIO_puts(out, "\n"); pinfo = sk_POLICYINFO_value(pol, i); BIO_printf(out, "%*sPolicy: ", indent, ""); i2a_ASN1_OBJECT(out, pinfo->policyid); - BIO_puts(out, "\n"); - if (pinfo->qualifiers) + if (pinfo->qualifiers) { + BIO_puts(out, "\n"); print_qualifiers(out, pinfo->qualifiers, indent + 2); + } } return 1; } @@ -419,10 +421,12 @@ static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, POLICYQUALINFO *qualinfo; int i; for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { + if (i > 0) + BIO_puts(out, "\n"); qualinfo = sk_POLICYQUALINFO_value(quals, i); switch (OBJ_obj2nid(qualinfo->pqualid)) { case NID_id_qt_cps: - BIO_printf(out, "%*sCPS: %.*s\n", indent, "", + BIO_printf(out, "%*sCPS: %.*s", indent, "", qualinfo->d.cpsuri->length, qualinfo->d.cpsuri->data); break; @@ -436,7 +440,6 @@ static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, ""); i2a_ASN1_OBJECT(out, qualinfo->pqualid); - BIO_puts(out, "\n"); break; } } @@ -469,10 +472,11 @@ static void print_notice(BIO *out, USERNOTICE *notice, int indent) OPENSSL_free(tmp); } } - BIO_puts(out, "\n"); + if (notice->exptext) + BIO_puts(out, "\n"); } if (notice->exptext) - BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "", + BIO_printf(out, "%*sExplicit Text: %.*s", indent, "", notice->exptext->length, notice->exptext->data); } @@ -487,8 +491,10 @@ void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) BIO_puts(out, "\n"); BIO_printf(out, "%*s%s\n", indent + 2, "", node_data_critical(dat) ? "Critical" : "Non Critical"); - if (dat->qualifier_set) + if (dat->qualifier_set) { print_qualifiers(out, dat->qualifier_set, indent + 2); + BIO_puts(out, "\n"); + } else BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, ""); } diff --git a/crypto/openssl/crypto/x509v3/v3_crld.c b/crypto/openssl/crypto/x509/v3_crld.c similarity index 90% rename from crypto/openssl/crypto/x509v3/v3_crld.c rename to crypto/openssl/crypto/x509/v3_crld.c index 4854748ffb51..0289df4de789 100644 --- a/crypto/openssl/crypto/x509v3/v3_crld.c +++ b/crypto/openssl/crypto/x509/v3_crld.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -16,13 +16,14 @@ #include "crypto/x509.h" #include "ext_dat.h" +#include "x509_local.h" static void *v2i_crld(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, int indent); -const X509V3_EXT_METHOD v3_crld = { +const X509V3_EXT_METHOD ossl_v3_crld = { NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), 0, 0, 0, 0, 0, 0, @@ -32,7 +33,7 @@ const X509V3_EXT_METHOD v3_crld = { NULL }; -const X509V3_EXT_METHOD v3_freshest_crl = { +const X509V3_EXT_METHOD ossl_v3_freshest_crl = { NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), 0, 0, 0, 0, 0, 0, @@ -52,7 +53,7 @@ static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, else gnsect = X509V3_parse_list(sect); if (!gnsect) { - X509V3err(X509V3_F_GNAMES_FROM_SECTNAME, X509V3_R_SECTION_NOT_FOUND); + ERR_raise(ERR_LIB_X509V3, X509V3_R_SECTION_NOT_FOUND); return NULL; } gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); @@ -82,8 +83,8 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, return -1; dnsect = X509V3_get_section(ctx, cnf->value); if (!dnsect) { - X509V3err(X509V3_F_SET_DIST_POINT_NAME, - X509V3_R_SECTION_NOT_FOUND); + X509_NAME_free(nm); + ERR_raise(ERR_LIB_X509V3, X509V3_R_SECTION_NOT_FOUND); return -1; } ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); @@ -98,16 +99,14 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, */ if (sk_X509_NAME_ENTRY_value(rnm, sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { - X509V3err(X509V3_F_SET_DIST_POINT_NAME, - X509V3_R_INVALID_MULTIPLE_RDNS); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_MULTIPLE_RDNS); goto err; } } else return 0; if (*pdp) { - X509V3err(X509V3_F_SET_DIST_POINT_NAME, - X509V3_R_DISTPOINT_ALREADY_SET); + ERR_raise(ERR_LIB_X509V3, X509V3_R_DISTPOINT_ALREADY_SET); goto err; } @@ -168,7 +167,7 @@ static int set_reasons(ASN1_BIT_STRING **preas, char *value) break; } } - if (!pbn->lname) + if (pbn->lname == NULL) goto err; } ret = 1; @@ -222,7 +221,7 @@ static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, goto err; } else if (strcmp(cnf->name, "CRLissuer") == 0) { point->CRLissuer = gnames_from_sectname(ctx, cnf->value); - if (!point->CRLissuer) + if (point->CRLissuer == NULL) goto err; } } @@ -251,14 +250,14 @@ static void *v2i_crld(const X509V3_EXT_METHOD *method, DIST_POINT *point; cnf = sk_CONF_VALUE_value(nval, i); - if (!cnf->value) { + if (cnf->value == NULL) { STACK_OF(CONF_VALUE) *dpsect; dpsect = X509V3_get_section(ctx, cnf->name); if (!dpsect) goto err; point = crldp_from_section(ctx, dpsect); X509V3_section_free(ctx, dpsect); - if (!point) + if (point == NULL) goto err; sk_DIST_POINT_push(crld, point); /* no failure as it was reserved */ } else { @@ -282,7 +281,7 @@ static void *v2i_crld(const X509V3_EXT_METHOD *method, return crld; merr: - X509V3err(X509V3_F_V2I_CRLD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); err: GENERAL_NAME_free(gen); GENERAL_NAMES_free(gens); @@ -346,7 +345,7 @@ static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -const X509V3_EXT_METHOD v3_idp = { +const X509V3_EXT_METHOD ossl_v3_idp = { NID_issuing_distribution_point, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(ISSUING_DIST_POINT), 0, 0, 0, 0, @@ -392,15 +391,15 @@ static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, if (!set_reasons(&idp->onlysomereasons, val)) goto err; } else { - X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME); - X509V3_conf_err(cnf); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_add_error_name_value(cnf); goto err; } } return idp; merr: - X509V3err(X509V3_F_V2I_IDP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); err: ISSUING_DIST_POINT_free(idp); return NULL; @@ -410,9 +409,10 @@ static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) { int i; for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + if (i > 0) + BIO_puts(out, "\n"); BIO_printf(out, "%*s", indent + 2, ""); GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); - BIO_puts(out, "\n"); } return 1; } @@ -463,7 +463,8 @@ static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, DIST_POINT *point; int i; for (i = 0; i < sk_DIST_POINT_num(crld); i++) { - BIO_puts(out, "\n"); + if (i > 0) + BIO_puts(out, "\n"); point = sk_DIST_POINT_value(crld, i); if (point->distpoint) print_distpoint(out, point->distpoint, indent); @@ -477,30 +478,31 @@ static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, return 1; } -int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) +/* Append any nameRelativeToCRLIssuer in dpn to iname, set in dpn->dpname */ +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, const X509_NAME *iname) { int i; STACK_OF(X509_NAME_ENTRY) *frag; X509_NAME_ENTRY *ne; - if (!dpn || (dpn->type != 1)) + + if (dpn == NULL || dpn->type != 1) return 1; frag = dpn->name.relativename; + X509_NAME_free(dpn->dpname); /* just in case it was already set */ dpn->dpname = X509_NAME_dup(iname); - if (!dpn->dpname) + if (dpn->dpname == NULL) return 0; for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { ne = sk_X509_NAME_ENTRY_value(frag, i); - if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { - X509_NAME_free(dpn->dpname); - dpn->dpname = NULL; - return 0; - } + if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) + goto err; } /* generate cached encoding of name */ - if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { - X509_NAME_free(dpn->dpname); - dpn->dpname = NULL; - return 0; - } - return 1; + if (i2d_X509_NAME(dpn->dpname, NULL) >= 0) + return 1; + + err: + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; } diff --git a/crypto/openssl/crypto/x509v3/v3_enum.c b/crypto/openssl/crypto/x509/v3_enum.c similarity index 89% rename from crypto/openssl/crypto/x509v3/v3_enum.c rename to crypto/openssl/crypto/x509/v3_enum.c index 3b0f197444af..b73a6d55162b 100644 --- a/crypto/openssl/crypto/x509v3/v3_enum.c +++ b/crypto/openssl/crypto/x509/v3_enum.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -29,7 +29,7 @@ static ENUMERATED_NAMES crl_reasons[] = { {-1, NULL, NULL} }; -const X509V3_EXT_METHOD v3_crl_reason = { +const X509V3_EXT_METHOD ossl_v3_crl_reason = { NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED), 0, 0, 0, 0, (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE, diff --git a/crypto/openssl/crypto/x509v3/v3_extku.c b/crypto/openssl/crypto/x509/v3_extku.c similarity index 86% rename from crypto/openssl/crypto/x509v3/v3_extku.c rename to crypto/openssl/crypto/x509/v3_extku.c index 91b24376ed8a..4f2a86bdcb2b 100644 --- a/crypto/openssl/crypto/x509v3/v3_extku.c +++ b/crypto/openssl/crypto/x509/v3_extku.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -21,7 +21,7 @@ static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *eku, STACK_OF(CONF_VALUE) *extlist); -const X509V3_EXT_METHOD v3_ext_ku = { +const X509V3_EXT_METHOD ossl_v3_ext_ku = { NID_ext_key_usage, 0, ASN1_ITEM_ref(EXTENDED_KEY_USAGE), 0, 0, 0, 0, @@ -33,7 +33,7 @@ const X509V3_EXT_METHOD v3_ext_ku = { }; /* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */ -const X509V3_EXT_METHOD v3_ocsp_accresp = { +const X509V3_EXT_METHOD ossl_v3_ocsp_accresp = { NID_id_pkix_OCSP_acceptableResponses, 0, ASN1_ITEM_ref(EXTENDED_KEY_USAGE), 0, 0, 0, 0, @@ -79,7 +79,7 @@ static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, extku = sk_ASN1_OBJECT_new_reserve(NULL, num); if (extku == NULL) { - X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); sk_ASN1_OBJECT_free(extku); return NULL; } @@ -92,9 +92,8 @@ static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, extval = val->name; if ((objtmp = OBJ_txt2obj(extval, 0)) == NULL) { sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); - X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, - X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER, + "%s", extval); return NULL; } sk_ASN1_OBJECT_push(extku, objtmp); /* no failure as it was reserved */ diff --git a/crypto/openssl/crypto/x509v3/v3_genn.c b/crypto/openssl/crypto/x509/v3_genn.c similarity index 98% rename from crypto/openssl/crypto/x509v3/v3_genn.c rename to crypto/openssl/crypto/x509/v3_genn.c index fd307c43cf20..1f67bf2f63ab 100644 --- a/crypto/openssl/crypto/x509v3/v3_genn.c +++ b/crypto/openssl/crypto/x509/v3_genn.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -51,7 +51,7 @@ ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES) IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) -GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a) +GENERAL_NAME *GENERAL_NAME_dup(const GENERAL_NAME *a) { return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME, (d2i_of_void *)d2i_GENERAL_NAME, diff --git a/crypto/openssl/crypto/x509v3/v3_ia5.c b/crypto/openssl/crypto/x509/v3_ia5.c similarity index 76% rename from crypto/openssl/crypto/x509v3/v3_ia5.c rename to crypto/openssl/crypto/x509/v3_ia5.c index c1170d46161e..6722b6c01f05 100644 --- a/crypto/openssl/crypto/x509v3/v3_ia5.c +++ b/crypto/openssl/crypto/x509/v3_ia5.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,7 +14,7 @@ #include #include "ext_dat.h" -const X509V3_EXT_METHOD v3_ns_ia5_list[8] = { +const X509V3_EXT_METHOD ossl_v3_ns_ia5_list[8] = { EXT_IA5STRING(NID_netscape_base_url), EXT_IA5STRING(NID_netscape_revocation_url), EXT_IA5STRING(NID_netscape_ca_revocation_url), @@ -29,10 +29,10 @@ char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5) { char *tmp; - if (!ia5 || !ia5->length) + if (ia5 == NULL || ia5->length <= 0) return NULL; if ((tmp = OPENSSL_malloc(ia5->length + 1)) == NULL) { - X509V3err(X509V3_F_I2S_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } memcpy(tmp, ia5->data, ia5->length); @@ -44,9 +44,8 @@ ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) { ASN1_IA5STRING *ia5; - if (!str) { - X509V3err(X509V3_F_S2I_ASN1_IA5STRING, - X509V3_R_INVALID_NULL_ARGUMENT); + if (str == NULL) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NULL_ARGUMENT); return NULL; } if ((ia5 = ASN1_IA5STRING_new()) == NULL) @@ -60,6 +59,6 @@ ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, #endif /* CHARSET_EBCDIC */ return ia5; err: - X509V3err(X509V3_F_S2I_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/openssl/crypto/x509v3/v3_info.c b/crypto/openssl/crypto/x509/v3_info.c similarity index 81% rename from crypto/openssl/crypto/x509v3/v3_info.c rename to crypto/openssl/crypto/x509/v3_info.c index 7af9e23ae8c9..5f21ce11e7d5 100644 --- a/crypto/openssl/crypto/x509v3/v3_info.c +++ b/crypto/openssl/crypto/x509/v3_info.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -25,7 +25,7 @@ static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD STACK_OF(CONF_VALUE) *nval); -const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE, +const X509V3_EXT_METHOD ossl_v3_info = { NID_info_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), 0, 0, 0, 0, 0, 0, @@ -35,7 +35,7 @@ const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE, NULL }; -const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE, +const X509V3_EXT_METHOD ossl_v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), 0, 0, 0, 0, 0, 0, @@ -91,7 +91,7 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( return tret; err: - X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); if (ret == NULL && tret != NULL) sk_CONF_VALUE_pop_free(tret, X509V3_conf_free); return NULL; @@ -106,48 +106,42 @@ static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD AUTHORITY_INFO_ACCESS *ainfo = NULL; CONF_VALUE *cnf, ctmp; ACCESS_DESCRIPTION *acc; - int i, objlen; + int i; const int num = sk_CONF_VALUE_num(nval); char *objtmp, *ptmp; if ((ainfo = sk_ACCESS_DESCRIPTION_new_reserve(NULL, num)) == NULL) { - X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } for (i = 0; i < num; i++) { cnf = sk_CONF_VALUE_value(nval, i); if ((acc = ACCESS_DESCRIPTION_new()) == NULL) { - X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } sk_ACCESS_DESCRIPTION_push(ainfo, acc); /* Cannot fail due to reserve */ ptmp = strchr(cnf->name, ';'); - if (!ptmp) { - X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, - X509V3_R_INVALID_SYNTAX); + if (ptmp == NULL) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_SYNTAX); goto err; } - objlen = ptmp - cnf->name; ctmp.name = ptmp + 1; ctmp.value = cnf->value; if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) goto err; - if ((objtmp = OPENSSL_strndup(cnf->name, objlen)) == NULL) { - X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, - ERR_R_MALLOC_FAILURE); + if ((objtmp = OPENSSL_strndup(cnf->name, ptmp - cnf->name)) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } acc->method = OBJ_txt2obj(objtmp, 0); if (!acc->method) { - X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, - X509V3_R_BAD_OBJECT); - ERR_add_error_data(2, "value=", objtmp); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_BAD_OBJECT, + "value=%s", objtmp); OPENSSL_free(objtmp); goto err; } OPENSSL_free(objtmp); - } return ainfo; err: diff --git a/crypto/openssl/crypto/x509v3/v3_int.c b/crypto/openssl/crypto/x509/v3_int.c similarity index 76% rename from crypto/openssl/crypto/x509v3/v3_int.c rename to crypto/openssl/crypto/x509/v3_int.c index 690c90e8f96e..dae26a5ba9d7 100644 --- a/crypto/openssl/crypto/x509v3/v3_int.c +++ b/crypto/openssl/crypto/x509/v3_int.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,7 +12,7 @@ #include #include "ext_dat.h" -const X509V3_EXT_METHOD v3_crl_num = { +const X509V3_EXT_METHOD ossl_v3_crl_num = { NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER), 0, 0, 0, 0, (X509V3_EXT_I2S)i2s_ASN1_INTEGER, @@ -20,7 +20,7 @@ const X509V3_EXT_METHOD v3_crl_num = { 0, 0, 0, 0, NULL }; -const X509V3_EXT_METHOD v3_delta_crl = { +const X509V3_EXT_METHOD ossl_v3_delta_crl = { NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER), 0, 0, 0, 0, (X509V3_EXT_I2S)i2s_ASN1_INTEGER, @@ -34,7 +34,7 @@ static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, return s2i_ASN1_INTEGER(meth, value); } -const X509V3_EXT_METHOD v3_inhibit_anyp = { +const X509V3_EXT_METHOD ossl_v3_inhibit_anyp = { NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER), 0, 0, 0, 0, (X509V3_EXT_I2S)i2s_ASN1_INTEGER, diff --git a/crypto/openssl/crypto/x509/v3_ist.c b/crypto/openssl/crypto/x509/v3_ist.c new file mode 100644 index 000000000000..0de281f66871 --- /dev/null +++ b/crypto/openssl/crypto/x509/v3_ist.c @@ -0,0 +1,149 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include +#include "ext_dat.h" + +/* + * Issuer Sign Tool (1.2.643.100.112) The name of the tool used to signs the subject (ASN1_SEQUENCE) + * This extention is required to obtain the status of a qualified certificate at Russian Federation. + * RFC-style description is available here: https://tools.ietf.org/html/draft-deremin-rfc4491-bis-04#section-5 + * Russian Federal Law 63 "Digital Sign" is available here: http://www.consultant.ru/document/cons_doc_LAW_112701/ + */ + +ASN1_SEQUENCE(ISSUER_SIGN_TOOL) = { + ASN1_SIMPLE(ISSUER_SIGN_TOOL, signTool, ASN1_UTF8STRING), + ASN1_SIMPLE(ISSUER_SIGN_TOOL, cATool, ASN1_UTF8STRING), + ASN1_SIMPLE(ISSUER_SIGN_TOOL, signToolCert, ASN1_UTF8STRING), + ASN1_SIMPLE(ISSUER_SIGN_TOOL, cAToolCert, ASN1_UTF8STRING) +} ASN1_SEQUENCE_END(ISSUER_SIGN_TOOL) + +IMPLEMENT_ASN1_FUNCTIONS(ISSUER_SIGN_TOOL) + + +static ISSUER_SIGN_TOOL *v2i_issuer_sign_tool(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + ISSUER_SIGN_TOOL *ist = ISSUER_SIGN_TOOL_new(); + int i; + + if (ist == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); ++i) { + CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + + if (cnf == NULL) { + continue; + } + if (strcmp(cnf->name, "signTool") == 0) { + ist->signTool = ASN1_UTF8STRING_new(); + if (ist->signTool == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ISSUER_SIGN_TOOL_free(ist); + return NULL; + } + ASN1_STRING_set(ist->signTool, cnf->value, strlen(cnf->value)); + } else if (strcmp(cnf->name, "cATool") == 0) { + ist->cATool = ASN1_UTF8STRING_new(); + if (ist->cATool == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ISSUER_SIGN_TOOL_free(ist); + return NULL; + } + ASN1_STRING_set(ist->cATool, cnf->value, strlen(cnf->value)); + } else if (strcmp(cnf->name, "signToolCert") == 0) { + ist->signToolCert = ASN1_UTF8STRING_new(); + if (ist->signToolCert == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ISSUER_SIGN_TOOL_free(ist); + return NULL; + } + ASN1_STRING_set(ist->signToolCert, cnf->value, strlen(cnf->value)); + } else if (strcmp(cnf->name, "cAToolCert") == 0) { + ist->cAToolCert = ASN1_UTF8STRING_new(); + if (ist->cAToolCert == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ISSUER_SIGN_TOOL_free(ist); + return NULL; + } + ASN1_STRING_set(ist->cAToolCert, cnf->value, strlen(cnf->value)); + } else { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_INVALID_ARGUMENT); + ISSUER_SIGN_TOOL_free(ist); + return NULL; + } + } + return ist; +} + +static int i2r_issuer_sign_tool(X509V3_EXT_METHOD *method, + ISSUER_SIGN_TOOL *ist, BIO *out, + int indent) +{ + int new_line = 0; + + if (ist == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ist->signTool != NULL) { + if (new_line == 1) { + BIO_write(out, "\n", 1); + } + BIO_printf(out, "%*ssignTool : ", indent, ""); + BIO_write(out, ist->signTool->data, ist->signTool->length); + new_line = 1; + } + if (ist->cATool != NULL) { + if (new_line == 1) { + BIO_write(out, "\n", 1); + } + BIO_printf(out, "%*scATool : ", indent, ""); + BIO_write(out, ist->cATool->data, ist->cATool->length); + new_line = 1; + } + if (ist->signToolCert != NULL) { + if (new_line == 1) { + BIO_write(out, "\n", 1); + } + BIO_printf(out, "%*ssignToolCert: ", indent, ""); + BIO_write(out, ist->signToolCert->data, ist->signToolCert->length); + new_line = 1; + } + if (ist->cAToolCert != NULL) { + if (new_line == 1) { + BIO_write(out, "\n", 1); + } + BIO_printf(out, "%*scAToolCert : ", indent, ""); + BIO_write(out, ist->cAToolCert->data, ist->cAToolCert->length); + new_line = 1; + } + return 1; +} + +const X509V3_EXT_METHOD ossl_v3_issuer_sign_tool = { + NID_issuerSignTool, /* nid */ + X509V3_EXT_MULTILINE, /* flags */ + ASN1_ITEM_ref(ISSUER_SIGN_TOOL), /* template */ + 0, 0, 0, 0, /* old functions, ignored */ + 0, /* i2s */ + 0, /* s2i */ + 0, /* i2v */ + (X509V3_EXT_V2I)v2i_issuer_sign_tool, /* v2i */ + (X509V3_EXT_I2R)i2r_issuer_sign_tool, /* i2r */ + 0, /* r2i */ + NULL /* extension-specific data */ +}; diff --git a/crypto/openssl/crypto/x509v3/v3_lib.c b/crypto/openssl/crypto/x509/v3_lib.c similarity index 93% rename from crypto/openssl/crypto/x509v3/v3_lib.c rename to crypto/openssl/crypto/x509/v3_lib.c index ea88ff2acd22..5ffeb75d9f5b 100644 --- a/crypto/openssl/crypto/x509v3/v3_lib.c +++ b/crypto/openssl/crypto/x509/v3_lib.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -26,11 +26,11 @@ int X509V3_EXT_add(X509V3_EXT_METHOD *ext) { if (ext_list == NULL && (ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp)) == NULL) { - X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return 0; } if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { - X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -89,11 +89,11 @@ int X509V3_EXT_add_alias(int nid_to, int nid_from) X509V3_EXT_METHOD *tmpext; if ((ext = X509V3_EXT_get_nid(nid_from)) == NULL) { - X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, X509V3_R_EXTENSION_NOT_FOUND); + ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_NOT_FOUND); return 0; } if ((tmpext = OPENSSL_malloc(sizeof(*tmpext))) == NULL) { - X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return 0; } *tmpext = *ext; @@ -267,8 +267,7 @@ int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, ext = X509V3_EXT_i2d(nid, crit, value); if (!ext) { - X509V3err(X509V3_F_X509V3_ADD1_I2D, - X509V3_R_ERROR_CREATING_EXTENSION); + ERR_raise(ERR_LIB_X509V3, X509V3_R_ERROR_CREATING_EXTENSION); return 0; } @@ -292,7 +291,7 @@ int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, return 1; m_fail: - /* X509V3err(X509V3_F_X509V3_ADD1_I2D, ERR_R_MALLOC_FAILURE); */ + /* ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); */ if (ret != *x) sk_X509_EXTENSION_free(ret); X509_EXTENSION_free(ext); @@ -300,6 +299,6 @@ int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, err: if (!(flags & X509V3_ADD_SILENT)) - X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode); + ERR_raise(ERR_LIB_X509V3, errcode); return 0; } diff --git a/crypto/openssl/crypto/x509v3/v3_ncons.c b/crypto/openssl/crypto/x509/v3_ncons.c similarity index 78% rename from crypto/openssl/crypto/x509v3/v3_ncons.c rename to crypto/openssl/crypto/x509/v3_ncons.c index 60cb4ceaa8f8..a51354e7fc4c 100644 --- a/crypto/openssl/crypto/x509v3/v3_ncons.c +++ b/crypto/openssl/crypto/x509/v3_ncons.c @@ -1,7 +1,7 @@ /* - * Copyright 2003-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2003-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,8 +14,10 @@ #include #include #include +#include #include "crypto/x509.h" +#include "crypto/punycode.h" #include "ext_dat.h" static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, @@ -29,14 +31,16 @@ static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); -static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); -static int nc_dn(X509_NAME *sub, X509_NAME *nm); +static int nc_match_single(int effective_type, GENERAL_NAME *sub, + GENERAL_NAME *gen); +static int nc_dn(const X509_NAME *sub, const X509_NAME *nm); static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); +static int nc_email_eai(ASN1_TYPE *emltype, ASN1_IA5STRING *base); static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base); -const X509V3_EXT_METHOD v3_name_constraints = { +const X509V3_EXT_METHOD ossl_v3_name_constraints = { NID_name_constraints, 0, ASN1_ITEM_ref(NAME_CONSTRAINTS), 0, 0, 0, 0, @@ -139,7 +143,7 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, ptree = &ncons->excludedSubtrees; tval.name = val->name + 9; } else { - X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_SYNTAX); goto err; } tval.value = val->value; @@ -158,7 +162,7 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, return ncons; memerr: - X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); err: NAME_CONSTRAINTS_free(ncons); GENERAL_SUBTREE_free(sub); @@ -172,6 +176,8 @@ static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, NAME_CONSTRAINTS *ncons = a; do_i2r_name_constraints(method, ncons->permittedSubtrees, bp, ind, "Permitted"); + if (ncons->permittedSubtrees && ncons->excludedSubtrees) + BIO_puts(bp, "\n"); do_i2r_name_constraints(method, ncons->excludedSubtrees, bp, ind, "Excluded"); return 1; @@ -186,39 +192,31 @@ static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, if (sk_GENERAL_SUBTREE_num(trees) > 0) BIO_printf(bp, "%*s%s:\n", ind, "", name); for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { + if (i > 0) + BIO_puts(bp, "\n"); tree = sk_GENERAL_SUBTREE_value(trees, i); BIO_printf(bp, "%*s", ind + 2, ""); if (tree->base->type == GEN_IPADD) print_nc_ipadd(bp, tree->base->d.ip); else GENERAL_NAME_print(bp, tree->base); - BIO_puts(bp, "\n"); } return 1; } static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) { - int i, len; - unsigned char *p; - p = ip->data; - len = ip->length; - BIO_puts(bp, "IP:"); - if (len == 8) { - BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - } else if (len == 32) { - for (i = 0; i < 16; i++) { - BIO_printf(bp, "%X", p[0] << 8 | p[1]); - p += 2; - if (i == 7) - BIO_puts(bp, "/"); - else if (i != 15) - BIO_puts(bp, ":"); - } - } else - BIO_printf(bp, "IP Address:"); - return 1; + /* ip->length should be 8 or 32 and len1 == len2 == 4 or len1 == len2 == 16 */ + int len1 = ip->length >= 16 ? 16 : ip->length >= 4 ? 4 : ip->length; + int len2 = ip->length - len1; + char *ip1 = ossl_ipaddr_to_asc(ip->data, len1); + char *ip2 = ossl_ipaddr_to_asc(ip->data + len1, len2); + int ret = ip1 != NULL && ip2 != NULL + && BIO_printf(bp, "IP:%s/%s", ip1, ip2) > 0; + + OPENSSL_free(ip1); + OPENSSL_free(ip2); + return ret; } #define NAME_CHECK_MAX (1 << 20) @@ -411,7 +409,7 @@ static int cn2dnsid(ASN1_STRING *cn, unsigned char **dnsid, size_t *idlen) int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc) { int r, i; - X509_NAME *nm = X509_get_subject_name(x); + const X509_NAME *nm = X509_get_subject_name(x); ASN1_STRING stmp; GENERAL_NAME gntmp; @@ -450,10 +448,42 @@ int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc) return X509_V_OK; } +/* + * Return nonzero if the GeneralSubtree has valid 'minimum' field + * (must be absent or 0) and valid 'maximum' field (must be absent). + */ +static int nc_minmax_valid(GENERAL_SUBTREE *sub) { + BIGNUM *bn = NULL; + int ok = 1; + + if (sub->maximum) + ok = 0; + + if (sub->minimum) { + bn = ASN1_INTEGER_to_BN(sub->minimum, NULL); + if (bn == NULL || !BN_is_zero(bn)) + ok = 0; + BN_free(bn); + } + + return ok; +} + static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) { GENERAL_SUBTREE *sub; int i, r, match = 0; + int effective_type = gen->type; + + /* + * We need to compare not gen->type field but an "effective" type because + * the otherName field may contain EAI email address treated specially + * according to RFC 8398, section 6 + */ + if (effective_type == GEN_OTHERNAME && + (OBJ_obj2nid(gen->d.otherName->type_id) == NID_id_on_SmtpUTF8Mailbox)) { + effective_type = GEN_EMAIL; + } /* * Permitted subtrees: if any subtrees exist of matching the type at @@ -462,16 +492,19 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); - if (gen->type != sub->base->type) + if (effective_type != sub->base->type + || (effective_type == GEN_OTHERNAME && + OBJ_cmp(gen->d.otherName->type_id, + sub->base->d.otherName->type_id) != 0)) continue; - if (sub->minimum || sub->maximum) + if (!nc_minmax_valid(sub)) return X509_V_ERR_SUBTREE_MINMAX; /* If we already have a match don't bother trying any more */ if (match == 2) continue; if (match == 0) match = 1; - r = nc_match_single(gen, sub->base); + r = nc_match_single(effective_type, gen, sub->base); if (r == X509_V_OK) match = 2; else if (r != X509_V_ERR_PERMITTED_VIOLATION) @@ -485,12 +518,15 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); - if (gen->type != sub->base->type) + if (effective_type != sub->base->type + || (effective_type == GEN_OTHERNAME && + OBJ_cmp(gen->d.otherName->type_id, + sub->base->d.otherName->type_id) != 0)) continue; - if (sub->minimum || sub->maximum) + if (!nc_minmax_valid(sub)) return X509_V_ERR_SUBTREE_MINMAX; - r = nc_match_single(gen, sub->base); + r = nc_match_single(effective_type, gen, sub->base); if (r == X509_V_OK) return X509_V_ERR_EXCLUDED_VIOLATION; else if (r != X509_V_ERR_PERMITTED_VIOLATION) @@ -502,9 +538,23 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) } -static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) +static int nc_match_single(int effective_type, GENERAL_NAME *gen, + GENERAL_NAME *base) { - switch (base->type) { + switch (gen->type) { + case GEN_OTHERNAME: + switch (effective_type) { + case GEN_EMAIL: + /* + * We are here only when we have SmtpUTF8 name, + * so we match the value of othername with base->d.rfc822Name + */ + return nc_email_eai(gen->d.otherName->value, base->d.rfc822Name); + + default: + return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; + } + case GEN_DIRNAME: return nc_dn(gen->d.directoryName, base->d.directoryName); @@ -533,7 +583,7 @@ static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) * subset of the name. */ -static int nc_dn(X509_NAME *nm, X509_NAME *base) +static int nc_dn(const X509_NAME *nm, const X509_NAME *base) { /* Ensure canonical encodings are up to date. */ if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) @@ -576,6 +626,85 @@ static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) } +/* + * This function implements comparison between ASCII/U-label in emltype + * and A-label in base according to RFC 8398, section 6. + * Convert base to U-label and ASCII-parts of domain names, for base + * Octet-to-octet comparison of `emltype` and `base` hostname parts + * (ASCII-parts should be compared in case-insensitive manner) + */ +static int nc_email_eai(ASN1_TYPE *emltype, ASN1_IA5STRING *base) +{ + ASN1_UTF8STRING *eml; + char *baseptr = NULL; + const char *emlptr; + const char *emlat; + char ulabel[256]; + size_t size = sizeof(ulabel) - 1; + int ret = X509_V_OK; + size_t emlhostlen; + + /* We do not accept embedded NUL characters */ + if (base->length > 0 && memchr(base->data, 0, base->length) != NULL) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + /* 'base' may not be NUL terminated. Create a copy that is */ + baseptr = OPENSSL_strndup((char *)base->data, base->length); + if (baseptr == NULL) + return X509_V_ERR_OUT_OF_MEM; + + if (emltype->type != V_ASN1_UTF8STRING) { + ret = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + goto end; + } + + eml = emltype->value.utf8string; + emlptr = (char *)eml->data; + emlat = ia5memrchr(eml, '@'); + + if (emlat == NULL) { + ret = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + goto end; + } + + memset(ulabel, 0, sizeof(ulabel)); + /* Special case: initial '.' is RHS match */ + if (*baseptr == '.') { + ulabel[0] = '.'; + size -= 1; + if (ossl_a2ulabel(baseptr, ulabel + 1, &size) <= 0) { + ret = X509_V_ERR_UNSPECIFIED; + goto end; + } + + if ((size_t)eml->length > strlen(ulabel)) { + emlptr += eml->length - (strlen(ulabel)); + /* X509_V_OK */ + if (ia5ncasecmp(ulabel, emlptr, strlen(ulabel)) == 0) + goto end; + } + ret = X509_V_ERR_PERMITTED_VIOLATION; + goto end; + } + + if (ossl_a2ulabel(baseptr, ulabel, &size) <= 0) { + ret = X509_V_ERR_UNSPECIFIED; + goto end; + } + /* Just have hostname left to match: case insensitive */ + emlptr = emlat + 1; + emlhostlen = IA5_OFFSET_LEN(eml, emlptr); + if (emlhostlen != strlen(ulabel) + || ia5ncasecmp(ulabel, emlptr, emlhostlen) != 0) { + ret = X509_V_ERR_PERMITTED_VIOLATION; + goto end; + } + + end: + OPENSSL_free(baseptr); + return ret; +} + static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) { const char *baseptr = (char *)base->data; diff --git a/crypto/openssl/crypto/x509v3/v3_pci.c b/crypto/openssl/crypto/x509/v3_pci.c similarity index 86% rename from crypto/openssl/crypto/x509v3/v3_pci.c rename to crypto/openssl/crypto/x509/v3_pci.c index 532d4e192fec..a931e01a9c92 100644 --- a/crypto/openssl/crypto/x509v3/v3_pci.c +++ b/crypto/openssl/crypto/x509/v3_pci.c @@ -1,7 +1,7 @@ /* * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -54,7 +54,7 @@ static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str); -const X509V3_EXT_METHOD v3_pci = +const X509V3_EXT_METHOD ossl_v3_pci = { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), 0, 0, 0, 0, 0, 0, @@ -75,9 +75,8 @@ static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, BIO_puts(out, "\n"); BIO_printf(out, "%*sPolicy Language: ", indent, ""); i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); - BIO_puts(out, "\n"); if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) - BIO_printf(out, "%*sPolicy Text: %.*s\n", indent, "", + BIO_printf(out, "\n%*sPolicy Text: %.*s", indent, "", pci->proxyPolicy->policy->length, pci->proxyPolicy->policy->data); return 1; @@ -91,37 +90,35 @@ static int process_pci_value(CONF_VALUE *val, if (strcmp(val->name, "language") == 0) { if (*language) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); + ERR_raise(ERR_LIB_X509V3, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); X509V3_conf_err(val); return 0; } if ((*language = OBJ_txt2obj(val->value, 0)) == NULL) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - X509V3_R_INVALID_OBJECT_IDENTIFIER); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); X509V3_conf_err(val); return 0; } } else if (strcmp(val->name, "pathlen") == 0) { if (*pathlen) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, + ERR_raise(ERR_LIB_X509V3, X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); X509V3_conf_err(val); return 0; } if (!X509V3_get_value_int(val, pathlen)) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - X509V3_R_POLICY_PATH_LENGTH); + ERR_raise(ERR_LIB_X509V3, X509V3_R_POLICY_PATH_LENGTH); X509V3_conf_err(val); return 0; } } else if (strcmp(val->name, "policy") == 0) { unsigned char *tmp_data = NULL; long val_len; - if (!*policy) { + + if (*policy == NULL) { *policy = ASN1_OCTET_STRING_new(); if (*policy == NULL) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); X509V3_conf_err(val); return 0; } @@ -153,7 +150,7 @@ static int process_pci_value(CONF_VALUE *val, OPENSSL_free((*policy)->data); (*policy)->data = NULL; (*policy)->length = 0; - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); X509V3_conf_err(val); goto err; } @@ -163,7 +160,7 @@ static int process_pci_value(CONF_VALUE *val, int n; BIO *b = BIO_new_file(val->value + 5, "r"); if (!b) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_X509V3, ERR_R_BIO_LIB); X509V3_conf_err(val); goto err; } @@ -179,8 +176,7 @@ static int process_pci_value(CONF_VALUE *val, OPENSSL_free((*policy)->data); (*policy)->data = NULL; (*policy)->length = 0; - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); X509V3_conf_err(val); BIO_free_all(b); goto err; @@ -194,7 +190,7 @@ static int process_pci_value(CONF_VALUE *val, BIO_free_all(b); if (n < 0) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB); + ERR_raise(ERR_LIB_X509V3, ERR_R_BIO_LIB); X509V3_conf_err(val); goto err; } @@ -216,18 +212,17 @@ static int process_pci_value(CONF_VALUE *val, OPENSSL_free((*policy)->data); (*policy)->data = NULL; (*policy)->length = 0; - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); X509V3_conf_err(val); goto err; } } else { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); X509V3_conf_err(val); goto err; } if (!tmp_data) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); X509V3_conf_err(val); goto err; } @@ -254,9 +249,9 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, vals = X509V3_parse_list(value); for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); + if (!cnf->name || (*cnf->name != '@' && !cnf->value)) { - X509V3err(X509V3_F_R2I_PCI, - X509V3_R_INVALID_PROXY_POLICY_SETTING); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING); X509V3_conf_err(cnf); goto err; } @@ -266,7 +261,7 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, sect = X509V3_get_section(ctx, cnf->name + 1); if (!sect) { - X509V3err(X509V3_F_R2I_PCI, X509V3_R_INVALID_SECTION); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_SECTION); X509V3_conf_err(cnf); goto err; } @@ -288,20 +283,20 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, /* Language is mandatory */ if (!language) { - X509V3err(X509V3_F_R2I_PCI, + ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); goto err; } i = OBJ_obj2nid(language); if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) { - X509V3err(X509V3_F_R2I_PCI, + ERR_raise(ERR_LIB_X509V3, X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); goto err; } pci = PROXY_CERT_INFO_EXTENSION_new(); if (pci == NULL) { - X509V3err(X509V3_F_R2I_PCI, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } diff --git a/crypto/openssl/crypto/x509v3/v3_pcia.c b/crypto/openssl/crypto/x509/v3_pcia.c similarity index 97% rename from crypto/openssl/crypto/x509v3/v3_pcia.c rename to crypto/openssl/crypto/x509/v3_pcia.c index 8d6af60e5da6..7f5985f5e859 100644 --- a/crypto/openssl/crypto/x509v3/v3_pcia.c +++ b/crypto/openssl/crypto/x509/v3_pcia.c @@ -1,7 +1,7 @@ /* * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/x509v3/v3_pcons.c b/crypto/openssl/crypto/x509/v3_pcons.c similarity index 83% rename from crypto/openssl/crypto/x509v3/v3_pcons.c rename to crypto/openssl/crypto/x509/v3_pcons.c index 24f7ff49e57c..128365f572e2 100644 --- a/crypto/openssl/crypto/x509v3/v3_pcons.c +++ b/crypto/openssl/crypto/x509/v3_pcons.c @@ -1,7 +1,7 @@ /* - * Copyright 2003-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2003-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -22,7 +22,7 @@ static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); -const X509V3_EXT_METHOD v3_policy_constraints = { +const X509V3_EXT_METHOD ossl_v3_policy_constraints = { NID_policy_constraints, 0, ASN1_ITEM_ref(POLICY_CONSTRAINTS), 0, 0, 0, 0, @@ -61,7 +61,7 @@ static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, int i; if ((pcons = POLICY_CONSTRAINTS_new()) == NULL) { - X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } for (i = 0; i < sk_CONF_VALUE_num(values); i++) { @@ -73,14 +73,14 @@ static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping)) goto err; } else { - X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME); - X509V3_conf_err(val); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_INVALID_NAME, + "%s", val->name); goto err; } } - if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { - X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, - X509V3_R_ILLEGAL_EMPTY_EXTENSION); + if (pcons->inhibitPolicyMapping == NULL + && pcons->requireExplicitPolicy == NULL) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION); goto err; } diff --git a/crypto/openssl/crypto/x509v3/v3_pku.c b/crypto/openssl/crypto/x509/v3_pku.c similarity index 88% rename from crypto/openssl/crypto/x509v3/v3_pku.c rename to crypto/openssl/crypto/x509/v3_pku.c index 5a7e7d972516..8f7e7d681300 100644 --- a/crypto/openssl/crypto/x509v3/v3_pku.c +++ b/crypto/openssl/crypto/x509/v3_pku.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -18,7 +18,7 @@ static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage, BIO *out, int indent); -const X509V3_EXT_METHOD v3_pkey_usage_period = { +const X509V3_EXT_METHOD ossl_v3_pkey_usage_period = { NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD), 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/crypto/openssl/crypto/x509v3/v3_pmaps.c b/crypto/openssl/crypto/x509/v3_pmaps.c similarity index 83% rename from crypto/openssl/crypto/x509v3/v3_pmaps.c rename to crypto/openssl/crypto/x509/v3_pmaps.c index 5b6a2af0fbf6..2094e9671141 100644 --- a/crypto/openssl/crypto/x509v3/v3_pmaps.c +++ b/crypto/openssl/crypto/x509/v3_pmaps.c @@ -1,7 +1,7 @@ /* - * Copyright 2003-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2003-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,7 +20,7 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *pmps, STACK_OF(CONF_VALUE) *extlist); -const X509V3_EXT_METHOD v3_policy_mappings = { +const X509V3_EXT_METHOD ossl_v3_policy_mappings = { NID_policy_mappings, 0, ASN1_ITEM_ref(POLICY_MAPPINGS), 0, 0, 0, 0, @@ -73,29 +73,27 @@ static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, int i; if ((pmaps = sk_POLICY_MAPPING_new_reserve(NULL, num)) == NULL) { - X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } for (i = 0; i < num; i++) { val = sk_CONF_VALUE_value(nval, i); if (!val->value || !val->name) { - X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, - X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER, + "%s", val->name); goto err; } obj1 = OBJ_txt2obj(val->name, 0); obj2 = OBJ_txt2obj(val->value, 0); if (!obj1 || !obj2) { - X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, - X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER, + "%s", val->name); goto err; } pmap = POLICY_MAPPING_new(); if (pmap == NULL) { - X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } pmap->issuerDomainPolicy = obj1; diff --git a/crypto/openssl/crypto/x509v3/v3_prn.c b/crypto/openssl/crypto/x509/v3_prn.c similarity index 92% rename from crypto/openssl/crypto/x509v3/v3_prn.c rename to crypto/openssl/crypto/x509/v3_prn.c index f384c342acc0..1e4516a713c2 100644 --- a/crypto/openssl/crypto/x509v3/v3_prn.c +++ b/crypto/openssl/crypto/x509/v3_prn.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -34,8 +34,11 @@ void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, BIO_puts(out, "\n"); } for (i = 0; i < sk_CONF_VALUE_num(val); i++) { - if (ml) + if (ml) { + if (i > 0) + BIO_printf(out, "\n"); BIO_printf(out, "%*s", indent, ""); + } else if (i > 0) BIO_printf(out, ", "); nval = sk_CONF_VALUE_value(val, i); @@ -59,8 +62,6 @@ void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, } } #endif - if (ml) - BIO_puts(out, "\n"); } } @@ -152,10 +153,15 @@ int X509V3_extensions_print(BIO *bp, const char *title, for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { ASN1_OBJECT *obj; X509_EXTENSION *ex; + ex = sk_X509_EXTENSION_value(exts, i); + obj = X509_EXTENSION_get_object(ex); + if ((flag & X509_FLAG_EXTENSIONS_ONLY_KID) != 0 + && OBJ_obj2nid(obj) != NID_subject_key_identifier + && OBJ_obj2nid(obj) != NID_authority_key_identifier) + continue; if (indent && BIO_printf(bp, "%*s", indent, "") <= 0) return 0; - obj = X509_EXTENSION_get_object(ex); i2a_ASN1_OBJECT(bp, obj); j = X509_EXTENSION_get_critical(ex); if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) diff --git a/crypto/openssl/crypto/x509v3/v3_purp.c b/crypto/openssl/crypto/x509/v3_purp.c similarity index 67% rename from crypto/openssl/crypto/x509v3/v3_purp.c rename to crypto/openssl/crypto/x509/v3_purp.c index a1aeb4e4c60b..a6ebbd5f94f6 100644 --- a/crypto/openssl/crypto/x509v3/v3_purp.c +++ b/crypto/openssl/crypto/x509/v3_purp.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,29 +13,29 @@ #include #include #include "crypto/x509.h" -#include "../x509/x509_local.h" /* for x509_signing_allowed() */ #include "internal/tsan_assist.h" - -static void x509v3_cache_extensions(X509 *x); +#include "x509_local.h" static int check_ssl_ca(const X509 *x); static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, - int ca); + int require_ca); static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca); + int require_ca); static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int purpose_smime(const X509 *x, int ca); + int require_ca); +static int purpose_smime(const X509 *x, int require_ca); static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, - int ca); + int require_ca); static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, - int ca); + int require_ca); static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, - int ca); + int require_ca); static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); -static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); + int require_ca); +static int no_check_purpose(const X509_PURPOSE *xp, const X509 *x, + int require_ca); +static int check_purpose_ocsp_helper(const X509_PURPOSE *xp, const X509 *x, + int require_ca); static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b); static void xptable_free(X509_PURPOSE *p); @@ -53,9 +53,10 @@ static X509_PURPOSE xstandard[] = { check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL}, {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL}, - {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", + {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check_purpose, + "Any Purpose", "any", NULL}, - {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, + {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, check_purpose_ocsp_helper, "OCSP helper", "ocsphelper", NULL}, {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", @@ -72,33 +73,32 @@ static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b) } /* - * As much as I'd like to make X509_check_purpose use a "const" X509* I - * really can't because it does recalculate hashes and do other non-const - * things. + * As much as I'd like to make X509_check_purpose use a "const" X509* I really + * can't because it does recalculate hashes and do other non-const things. + * If id == -1 it just calls x509v3_cache_extensions() for its side-effect. + * Returns 1 on success, 0 if x does not allow purpose, -1 on (internal) error. */ -int X509_check_purpose(X509 *x, int id, int ca) +int X509_check_purpose(X509 *x, int id, int require_ca) { int idx; const X509_PURPOSE *pt; - x509v3_cache_extensions(x); - if (x->ex_flags & EXFLAG_INVALID) + if (!ossl_x509v3_cache_extensions(x)) return -1; - - /* Return if side-effect only call */ if (id == -1) return 1; + idx = X509_PURPOSE_get_by_id(id); if (idx == -1) return -1; pt = X509_PURPOSE_get0(idx); - return pt->check_purpose(pt, x, ca); + return pt->check_purpose(pt, x, require_ca); } int X509_PURPOSE_set(int *p, int purpose) { if (X509_PURPOSE_get_by_id(purpose) == -1) { - X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_PURPOSE); return 0; } *p = purpose; @@ -133,12 +133,13 @@ int X509_PURPOSE_get_by_sname(const char *sname) return -1; } +/* Returns -1 on error, else an index => 0 in standard/extended purpose table */ int X509_PURPOSE_get_by_id(int purpose) { X509_PURPOSE tmp; int idx; - if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) + if (purpose >= X509_PURPOSE_MIN && purpose <= X509_PURPOSE_MAX) return purpose - X509_PURPOSE_MIN; if (xptable == NULL) return -1; @@ -155,9 +156,8 @@ int X509_PURPOSE_add(int id, int trust, int flags, { int idx; X509_PURPOSE *ptmp; - /* - * This is set according to what we change: application can't set it - */ + + /* This is set according to what we change: application can't set it */ flags &= ~X509_PURPOSE_DYNAMIC; /* This will always be set for application modified trust entries */ flags |= X509_PURPOSE_DYNAMIC_NAME; @@ -166,7 +166,7 @@ int X509_PURPOSE_add(int id, int trust, int flags, /* Need a new entry */ if (idx == -1) { if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) { - X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return 0; } ptmp->flags = X509_PURPOSE_DYNAMIC; @@ -178,11 +178,11 @@ int X509_PURPOSE_add(int id, int trust, int flags, OPENSSL_free(ptmp->name); OPENSSL_free(ptmp->sname); } - /* dup supplied name */ + /* Dup supplied name */ ptmp->name = OPENSSL_strdup(name); ptmp->sname = OPENSSL_strdup(sname); - if (!ptmp->name || !ptmp->sname) { - X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + if (ptmp->name == NULL|| ptmp->sname == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } /* Keep the dynamic flag of existing entry */ @@ -199,11 +199,11 @@ int X509_PURPOSE_add(int id, int trust, int flags, if (idx == -1) { if (xptable == NULL && (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) { - X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } if (!sk_X509_PURPOSE_push(xptable, ptmp)) { - X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } } @@ -219,7 +219,7 @@ int X509_PURPOSE_add(int id, int trust, int flags, static void xptable_free(X509_PURPOSE *p) { - if (!p) + if (p == NULL) return; if (p->flags & X509_PURPOSE_DYNAMIC) { if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { @@ -273,7 +273,6 @@ int X509_supported_extension(X509_EXTENSION *ex) * normally reject the certificate. The list must be kept in numerical * order because it will be searched using bsearch. */ - static const int supported_nids[] = { NID_netscape_cert_type, /* 71 */ NID_key_usage, /* 83 */ @@ -286,6 +285,7 @@ int X509_supported_extension(X509_EXTENSION *ex) NID_sbgp_ipAddrBlock, /* 290 */ NID_sbgp_autonomousSysNum, /* 291 */ #endif + NID_id_pkix_OCSP_noCheck, /* 369 */ NID_policy_constraints, /* 401 */ NID_proxyCertInfo, /* 663 */ NID_name_constraints, /* 666 */ @@ -303,34 +303,49 @@ int X509_supported_extension(X509_EXTENSION *ex) return 0; } -static int setup_dp(X509 *x, DIST_POINT *dp) +/* Returns 1 on success, 0 if x is invalid, -1 on (internal) error. */ +static int setup_dp(const X509 *x, DIST_POINT *dp) { - X509_NAME *iname = NULL; + const X509_NAME *iname = NULL; int i; - if (dp->reasons) { + if (dp->distpoint == NULL && sk_GENERAL_NAME_num(dp->CRLissuer) <= 0) { + ERR_raise(ERR_LIB_X509, X509_R_INVALID_DISTPOINT); + return 0; + } + if (dp->reasons != NULL) { if (dp->reasons->length > 0) dp->dp_reasons = dp->reasons->data[0]; if (dp->reasons->length > 1) dp->dp_reasons |= (dp->reasons->data[1] << 8); dp->dp_reasons &= CRLDP_ALL_REASONS; - } else + } else { dp->dp_reasons = CRLDP_ALL_REASONS; - if (!dp->distpoint || (dp->distpoint->type != 1)) + } + if (dp->distpoint == NULL || dp->distpoint->type != 1) return 1; + + /* Handle name fragment given by nameRelativeToCRLIssuer */ + /* + * Note that the below way of determining iname is not really compliant + * with https://tools.ietf.org/html/rfc5280#section-4.2.1.13 + * According to it, sk_GENERAL_NAME_num(dp->CRLissuer) MUST be <= 1 + * and any CRLissuer could be of type different to GEN_DIRNAME. + */ for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type == GEN_DIRNAME) { iname = gen->d.directoryName; break; } } - if (!iname) + if (iname == NULL) iname = X509_get_issuer_name(x); - - return DIST_POINT_set_dpname(dp->distpoint, iname); + return DIST_POINT_set_dpname(dp->distpoint, iname) ? 1 : -1; } +/* Return 1 on success, 0 if x is invalid, -1 on (internal) error. */ static int setup_crldp(X509 *x) { int i; @@ -338,159 +353,176 @@ static int setup_crldp(X509 *x) x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &i, NULL); if (x->crldp == NULL && i != -1) return 0; + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { - if (!setup_dp(x, sk_DIST_POINT_value(x->crldp, i))) - return 0; + int res = setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); + + if (res < 1) + return res; } return 1; } /* Check that issuer public key algorithm matches subject signature algorithm */ -static int check_sig_alg_match(const EVP_PKEY *pkey, const X509 *subject) +static int check_sig_alg_match(const EVP_PKEY *issuer_key, const X509 *subject) { - int pkey_sig_nid, subj_sig_nid; + int subj_sig_nid; - if (pkey == NULL) + if (issuer_key == NULL) return X509_V_ERR_NO_ISSUER_PUBLIC_KEY; - if (OBJ_find_sigid_algs(EVP_PKEY_base_id(pkey), - NULL, &pkey_sig_nid) == 0) - pkey_sig_nid = EVP_PKEY_base_id(pkey); if (OBJ_find_sigid_algs(OBJ_obj2nid(subject->cert_info.signature.algorithm), NULL, &subj_sig_nid) == 0) - return X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM; - if (pkey_sig_nid != EVP_PKEY_type(subj_sig_nid)) - return X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH; - return X509_V_OK; + return X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM; + if (EVP_PKEY_is_a(issuer_key, OBJ_nid2sn(subj_sig_nid)) + || (EVP_PKEY_is_a(issuer_key, "RSA") && subj_sig_nid == NID_rsassaPss)) + return X509_V_OK; + return X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH; } #define V1_ROOT (EXFLAG_V1|EXFLAG_SS) #define ku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) + (((x)->ex_flags & EXFLAG_KUSAGE) != 0 && ((x)->ex_kusage & (usage)) == 0) #define xku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) + (((x)->ex_flags & EXFLAG_XKUSAGE) != 0 && ((x)->ex_xkusage & (usage)) == 0) #define ns_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) + (((x)->ex_flags & EXFLAG_NSCERT) != 0 && ((x)->ex_nscert & (usage)) == 0) -static void x509v3_cache_extensions(X509 *x) +/* + * Cache info on various X.509v3 extensions and further derived information, + * e.g., if cert 'x' is self-issued, in x->ex_flags and other internal fields. + * x->sha1_hash is filled in, or else EXFLAG_NO_FINGERPRINT is set in x->flags. + * X509_SIG_INFO_VALID is set in x->flags if x->siginf was filled successfully. + * Set EXFLAG_INVALID and return 0 in case the certificate is invalid. + */ +int ossl_x509v3_cache_extensions(X509 *x) { BASIC_CONSTRAINTS *bs; PROXY_CERT_INFO_EXTENSION *pci; ASN1_BIT_STRING *usage; ASN1_BIT_STRING *ns; EXTENDED_KEY_USAGE *extusage; - X509_EXTENSION *ex; int i; + int res; #ifdef tsan_ld_acq - /* fast lock-free check, see end of the function for details. */ + /* Fast lock-free check, see end of the function for details. */ if (tsan_ld_acq((TSAN_QUALIFIER int *)&x->ex_cached)) - return; + return (x->ex_flags & EXFLAG_INVALID) == 0; #endif - CRYPTO_THREAD_write_lock(x->lock); - if (x->ex_flags & EXFLAG_SET) { + if (!CRYPTO_THREAD_write_lock(x->lock)) + return 0; + if (x->ex_flags & EXFLAG_SET) { /* Cert has already been processed */ CRYPTO_THREAD_unlock(x->lock); - return; + return (x->ex_flags & EXFLAG_INVALID) == 0; } + /* Cache the SHA1 digest of the cert */ if (!X509_digest(x, EVP_sha1(), x->sha1_hash, NULL)) - x->ex_flags |= (EXFLAG_NO_FINGERPRINT | EXFLAG_INVALID); + x->ex_flags |= EXFLAG_NO_FINGERPRINT; + + ERR_set_mark(); /* V1 should mean no extensions ... */ - if (!X509_get_version(x)) + if (X509_get_version(x) == X509_VERSION_1) x->ex_flags |= EXFLAG_V1; + /* Handle basic constraints */ - if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL))) { + x->ex_pathlen = -1; + if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL)) != NULL) { if (bs->ca) x->ex_flags |= EXFLAG_CA; - if (bs->pathlen) { + if (bs->pathlen != NULL) { + /* + * The error case !bs->ca is checked by check_chain() + * in case ctx->param->flags & X509_V_FLAG_X509_STRICT + */ if (bs->pathlen->type == V_ASN1_NEG_INTEGER) { + ERR_raise(ERR_LIB_X509, X509V3_R_NEGATIVE_PATHLEN); x->ex_flags |= EXFLAG_INVALID; - x->ex_pathlen = 0; } else { x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); - if (!bs->ca && x->ex_pathlen != 0) { - x->ex_flags |= EXFLAG_INVALID; - x->ex_pathlen = 0; - } } - } else - x->ex_pathlen = -1; + } BASIC_CONSTRAINTS_free(bs); x->ex_flags |= EXFLAG_BCONS; } else if (i != -1) { x->ex_flags |= EXFLAG_INVALID; } + /* Handle proxy certificates */ - if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, &i, NULL))) { + if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, &i, NULL)) != NULL) { if (x->ex_flags & EXFLAG_CA || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) { x->ex_flags |= EXFLAG_INVALID; } - if (pci->pcPathLengthConstraint) { + if (pci->pcPathLengthConstraint != NULL) x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint); - } else + else x->ex_pcpathlen = -1; PROXY_CERT_INFO_EXTENSION_free(pci); x->ex_flags |= EXFLAG_PROXY; } else if (i != -1) { x->ex_flags |= EXFLAG_INVALID; } - /* Handle key usage */ - if ((usage = X509_get_ext_d2i(x, NID_key_usage, &i, NULL))) { + + /* Handle (basic) key usage */ + if ((usage = X509_get_ext_d2i(x, NID_key_usage, &i, NULL)) != NULL) { + x->ex_kusage = 0; if (usage->length > 0) { x->ex_kusage = usage->data[0]; if (usage->length > 1) x->ex_kusage |= usage->data[1] << 8; - } else - x->ex_kusage = 0; + } x->ex_flags |= EXFLAG_KUSAGE; ASN1_BIT_STRING_free(usage); + /* Check for empty key usage according to RFC 5280 section 4.2.1.3 */ + if (x->ex_kusage == 0) { + ERR_raise(ERR_LIB_X509, X509V3_R_EMPTY_KEY_USAGE); + x->ex_flags |= EXFLAG_INVALID; + } } else if (i != -1) { x->ex_flags |= EXFLAG_INVALID; } + + /* Handle extended key usage */ x->ex_xkusage = 0; - if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &i, NULL))) { + if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &i, NULL)) != NULL) { x->ex_flags |= EXFLAG_XKUSAGE; for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { case NID_server_auth: x->ex_xkusage |= XKU_SSL_SERVER; break; - case NID_client_auth: x->ex_xkusage |= XKU_SSL_CLIENT; break; - case NID_email_protect: x->ex_xkusage |= XKU_SMIME; break; - case NID_code_sign: x->ex_xkusage |= XKU_CODE_SIGN; break; - case NID_ms_sgc: case NID_ns_sgc: x->ex_xkusage |= XKU_SGC; break; - case NID_OCSP_sign: x->ex_xkusage |= XKU_OCSP_SIGN; break; - case NID_time_stamp: x->ex_xkusage |= XKU_TIMESTAMP; break; - case NID_dvcs: x->ex_xkusage |= XKU_DVCS; break; - case NID_anyExtendedKeyUsage: x->ex_xkusage |= XKU_ANYEKU; break; + default: + /* Ignore unknown extended key usage */ + break; } } sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); @@ -498,7 +530,8 @@ static void x509v3_cache_extensions(X509 *x) x->ex_flags |= EXFLAG_INVALID; } - if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, &i, NULL))) { + /* Handle legacy Netscape extension */ + if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, &i, NULL)) != NULL) { if (ns->length > 0) x->ex_nscert = ns->data[0]; else @@ -508,28 +541,40 @@ static void x509v3_cache_extensions(X509 *x) } else if (i != -1) { x->ex_flags |= EXFLAG_INVALID; } + + /* Handle subject key identifier and issuer/authority key identifier */ x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &i, NULL); if (x->skid == NULL && i != -1) x->ex_flags |= EXFLAG_INVALID; + x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &i, NULL); if (x->akid == NULL && i != -1) x->ex_flags |= EXFLAG_INVALID; - /* Does subject name match issuer ? */ - if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) { - x->ex_flags |= EXFLAG_SI; /* cert is self-issued */ + + /* Check if subject name matches issuer */ + if (X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)) == 0) { + x->ex_flags |= EXFLAG_SI; /* Cert is self-issued */ if (X509_check_akid(x, x->akid) == X509_V_OK /* SKID matches AKID */ /* .. and the signature alg matches the PUBKEY alg: */ && check_sig_alg_match(X509_get0_pubkey(x), x) == X509_V_OK) x->ex_flags |= EXFLAG_SS; /* indicate self-signed */ + /* This is very related to ossl_x509_likely_issued(x, x) == X509_V_OK */ } + + /* Handle subject alternative names and various other extensions */ x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, &i, NULL); if (x->altname == NULL && i != -1) x->ex_flags |= EXFLAG_INVALID; x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL); if (x->nc == NULL && i != -1) x->ex_flags |= EXFLAG_INVALID; - if (!setup_crldp(x)) + + /* Handle CRL distribution point entries */ + res = setup_crldp(x); + if (res == 0) x->ex_flags |= EXFLAG_INVALID; + else if (res < 0) + goto err; #ifndef OPENSSL_NO_RFC3779 x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL); @@ -540,9 +585,10 @@ static void x509v3_cache_extensions(X509 *x) x->ex_flags |= EXFLAG_INVALID; #endif for (i = 0; i < X509_get_ext_count(x); i++) { - ex = X509_get_ext(x, i); - if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) - == NID_freshest_crl) + X509_EXTENSION *ex = X509_get_ext(x, i); + int nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); + + if (nid == NID_freshest_crl) x->ex_flags |= EXFLAG_FRESHEST; if (!X509_EXTENSION_get_critical(ex)) continue; @@ -550,9 +596,28 @@ static void x509v3_cache_extensions(X509 *x) x->ex_flags |= EXFLAG_CRITICAL; break; } + switch (nid) { + case NID_basic_constraints: + x->ex_flags |= EXFLAG_BCONS_CRITICAL; + break; + case NID_authority_key_identifier: + x->ex_flags |= EXFLAG_AKID_CRITICAL; + break; + case NID_subject_key_identifier: + x->ex_flags |= EXFLAG_SKID_CRITICAL; + break; + case NID_subject_alt_name: + x->ex_flags |= EXFLAG_SAN_CRITICAL; + break; + default: + break; + } } - x509_init_sig_info(x); - x->ex_flags |= EXFLAG_SET; + + /* Set x->siginf, ignoring errors due to unsupported algos */ + (void)ossl_x509_init_sig_info(x); + + x->ex_flags |= EXFLAG_SET; /* Indicate that cert has been processed */ #ifdef tsan_st_rel tsan_st_rel((TSAN_QUALIFIER int *)&x->ex_cached, 1); /* @@ -561,7 +626,19 @@ static void x509v3_cache_extensions(X509 *x) * all stores are visible on all processors. Hence the release fence. */ #endif + ERR_pop_to_mark(); + if ((x->ex_flags & (EXFLAG_INVALID | EXFLAG_NO_FINGERPRINT)) == 0) { + CRYPTO_THREAD_unlock(x->lock); + return 1; + } + if ((x->ex_flags & EXFLAG_INVALID) != 0) + ERR_raise(ERR_LIB_X509, X509V3_R_INVALID_CERTIFICATE); + /* If computing sha1_hash failed the error queue already reflects this. */ + + err: + x->ex_flags |= EXFLAG_SET; /* indicate that cert has been processed */ CRYPTO_THREAD_unlock(x->lock); + return 0; } /*- @@ -571,7 +648,7 @@ static void x509v3_cache_extensions(X509 *x) * 1 is a CA * 2 Only possible in older versions of openSSL when basicConstraints are absent * new versions will not return this value. May be a CA - * 3 basicConstraints absent but self signed V1. + * 3 basicConstraints absent but self-signed V1. * 4 basicConstraints absent but keyUsage present and keyCertSign asserted. * 5 Netscape specific CA Flags present */ @@ -581,14 +658,11 @@ static int check_ca(const X509 *x) /* keyUsage if present should allow cert signing */ if (ku_reject(x, KU_KEY_CERT_SIGN)) return 0; - if (x->ex_flags & EXFLAG_BCONS) { - if (x->ex_flags & EXFLAG_CA) - return 1; + if ((x->ex_flags & EXFLAG_BCONS) != 0) { /* If basicConstraints says not a CA then say so */ - else - return 0; + return (x->ex_flags & EXFLAG_CA) != 0; } else { - /* we support V1 roots for... uh, I don't really know why. */ + /* We support V1 roots for... uh, I don't really know why. */ if ((x->ex_flags & V1_ROOT) == V1_ROOT) return 3; /* @@ -599,14 +673,17 @@ static int check_ca(const X509 *x) /* Older certificates could have Netscape-specific CA types */ else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA) return 5; - /* can this still be regarded a CA certificate? I doubt it */ + /* Can this still be regarded a CA certificate? I doubt it. */ return 0; } } void X509_set_proxy_flag(X509 *x) { - x->ex_flags |= EXFLAG_PROXY; + if (CRYPTO_THREAD_write_lock(x->lock)) { + x->ex_flags |= EXFLAG_PROXY; + CRYPTO_THREAD_unlock(x->lock); + } } void X509_set_proxy_pathlen(X509 *x, long l) @@ -616,31 +693,30 @@ void X509_set_proxy_pathlen(X509 *x, long l) int X509_check_ca(X509 *x) { - x509v3_cache_extensions(x); + /* Note 0 normally means "not a CA" - but in this case means error. */ + if (!ossl_x509v3_cache_extensions(x)) + return 0; return check_ca(x); } -/* Check SSL CA: common checks for SSL client and server */ +/* Check SSL CA: common checks for SSL client and server. */ static int check_ssl_ca(const X509 *x) { - int ca_ret; - ca_ret = check_ca(x); - if (!ca_ret) - return 0; - /* check nsCertType if present */ - if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA) - return ca_ret; - else + int ca_ret = check_ca(x); + + if (ca_ret == 0) return 0; + /* Check nsCertType if present */ + return ca_ret != 5 || (x->ex_nscert & NS_SSL_CA) != 0; } static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, - int ca) + int require_ca) { if (xku_reject(x, XKU_SSL_CLIENT)) return 0; - if (ca) + if (require_ca) return check_ssl_ca(x); /* We need to do digital signatures or key agreement */ if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)) @@ -660,11 +736,11 @@ static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca) + int require_ca) { if (xku_reject(x, XKU_SSL_SERVER | XKU_SGC)) return 0; - if (ca) + if (require_ca) return check_ssl_ca(x); if (ns_reject(x, NS_SSL_SERVER)) @@ -677,11 +753,11 @@ static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, } static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca) + int require_ca) { int ret; - ret = check_purpose_ssl_server(xp, x, ca); - if (!ret || ca) + ret = check_purpose_ssl_server(xp, x, require_ca); + if (!ret || require_ca) return ret; /* We need to encipher or Netscape complains */ if (ku_reject(x, KU_KEY_ENCIPHERMENT)) @@ -690,16 +766,16 @@ static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, } /* common S/MIME checks */ -static int purpose_smime(const X509 *x, int ca) +static int purpose_smime(const X509 *x, int require_ca) { if (xku_reject(x, XKU_SMIME)) return 0; - if (ca) { + if (require_ca) { int ca_ret; ca_ret = check_ca(x); - if (!ca_ret) + if (ca_ret == 0) return 0; - /* check nsCertType if present */ + /* Check nsCertType if present */ if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) return ca_ret; else @@ -717,11 +793,11 @@ static int purpose_smime(const X509 *x, int ca) } static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, - int ca) + int require_ca) { int ret; - ret = purpose_smime(x, ca); - if (!ret || ca) + ret = purpose_smime(x, require_ca); + if (!ret || require_ca) return ret; if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)) return 0; @@ -729,11 +805,11 @@ static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, } static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, - int ca) + int require_ca) { int ret; - ret = purpose_smime(x, ca); - if (!ret || ca) + ret = purpose_smime(x, require_ca); + if (!ret || require_ca) return ret; if (ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0; @@ -741,9 +817,9 @@ static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, } static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, - int ca) + int require_ca) { - if (ca) { + if (require_ca) { int ca_ret; if ((ca_ret = check_ca(x)) != 2) return ca_ret; @@ -759,26 +835,26 @@ static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, * OCSP helper: this is *not* a full OCSP check. It just checks that each CA * is valid. Additional checks must be made on the chain. */ - -static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) +static int check_purpose_ocsp_helper(const X509_PURPOSE *xp, const X509 *x, + int require_ca) { /* * Must be a valid CA. Should we really support the "I don't know" value * (2)? */ - if (ca) + if (require_ca) return check_ca(x); - /* leaf certificate is checked in OCSP_verify() */ + /* Leaf certificate is checked in OCSP_verify() */ return 1; } static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, - int ca) + int require_ca) { int i_ext; /* If ca is true we must return if this is a valid CA certificate. */ - if (ca) + if (require_ca) return check_ca(x); /* @@ -807,79 +883,76 @@ static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, return 1; } -static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) +static int no_check_purpose(const X509_PURPOSE *xp, const X509 *x, + int require_ca) { return 1; } /*- - * Check if certificate I is allowed to issue certificate I - * according to the B field of I if present - * depending on any proxyCertInfo extension of I. - * Returns 0 for OK, or positive for reason for rejection - * where reason codes match those for X509_verify_cert(). - */ -int x509_signing_allowed(const X509 *issuer, const X509 *subject) -{ - if (subject->ex_flags & EXFLAG_PROXY) { - if (ku_reject(issuer, KU_DIGITAL_SIGNATURE)) - return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; - } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) - return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; - return X509_V_OK; -} - -/*- - * Various checks to see if one certificate issued the second. - * This can be used to prune a set of possible issuer certificates - * which have been looked up using some simple method such as by - * subject name. + * Various checks to see if one certificate potentially issued the second. + * This can be used to prune a set of possible issuer certificates which + * have been looked up using some simple method such as by subject name. * These are: - * 1. Check issuer_name(subject) == subject_name(issuer) - * 2. If akid(subject) exists check it matches issuer - * 3. Check that issuer public key algorithm matches subject signature algorithm - * 4. If key_usage(issuer) exists check it supports certificate signing - * returns 0 for OK, positive for reason for mismatch, reasons match - * codes for X509_verify_cert() + * 1. issuer_name(subject) == subject_name(issuer) + * 2. If akid(subject) exists, it matches the respective issuer fields. + * 3. subject signature algorithm == issuer public key algorithm + * 4. If key_usage(issuer) exists, it allows for signing subject. + * Note that this does not include actually checking the signature. + * Returns 0 for OK, or positive for reason for mismatch + * where reason codes match those for X509_verify_cert(). */ - int X509_check_issued(X509 *issuer, X509 *subject) { int ret; - if ((ret = x509_likely_issued(issuer, subject)) != X509_V_OK) + if ((ret = ossl_x509_likely_issued(issuer, subject)) != X509_V_OK) return ret; - return x509_signing_allowed(issuer, subject); + return ossl_x509_signing_allowed(issuer, subject); } /* do the checks 1., 2., and 3. as described above for X509_check_issued() */ -int x509_likely_issued(X509 *issuer, X509 *subject) +int ossl_x509_likely_issued(X509 *issuer, X509 *subject) { + int ret; + if (X509_NAME_cmp(X509_get_subject_name(issuer), - X509_get_issuer_name(subject))) + X509_get_issuer_name(subject)) != 0) return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; - x509v3_cache_extensions(issuer); - if (issuer->ex_flags & EXFLAG_INVALID) - return X509_V_ERR_UNSPECIFIED; - x509v3_cache_extensions(subject); - if (subject->ex_flags & EXFLAG_INVALID) + /* set issuer->skid and subject->akid */ + if (!ossl_x509v3_cache_extensions(issuer) + || !ossl_x509v3_cache_extensions(subject)) return X509_V_ERR_UNSPECIFIED; - if (subject->akid) { - int ret = X509_check_akid(issuer, subject->akid); - if (ret != X509_V_OK) - return ret; - } + ret = X509_check_akid(issuer, subject->akid); + if (ret != X509_V_OK) + return ret; - /* check if the subject signature alg matches the issuer's PUBKEY alg */ + /* Check if the subject signature alg matches the issuer's PUBKEY alg */ return check_sig_alg_match(X509_get0_pubkey(issuer), subject); } -int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) +/*- + * Check if certificate I is allowed to issue certificate I + * according to the B field of I if present + * depending on any proxyCertInfo extension of I. + * Returns 0 for OK, or positive for reason for rejection + * where reason codes match those for X509_verify_cert(). + */ +int ossl_x509_signing_allowed(const X509 *issuer, const X509 *subject) { + if (subject->ex_flags & EXFLAG_PROXY) { + if (ku_reject(issuer, KU_DIGITAL_SIGNATURE)) + return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; + } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) + return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; + return X509_V_OK; +} - if (!akid) +int X509_check_akid(const X509 *issuer, const AUTHORITY_KEYID *akid) +{ + if (akid == NULL) return X509_V_OK; /* Check key ids (if present) */ @@ -888,7 +961,7 @@ int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) return X509_V_ERR_AKID_SKID_MISMATCH; /* Check serial number */ if (akid->serial && - ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) + ASN1_INTEGER_cmp(X509_get0_serialNumber(issuer), akid->serial)) return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; /* Check issuer name */ if (akid->issuer) { @@ -909,7 +982,7 @@ int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) break; } } - if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) + if (nm != NULL && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)) != 0) return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; } return X509_V_OK; @@ -918,14 +991,14 @@ int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) uint32_t X509_get_extension_flags(X509 *x) { /* Call for side-effect of computing hash and caching extensions */ - X509_check_purpose(x, -1, -1); + X509_check_purpose(x, -1, 0); return x->ex_flags; } uint32_t X509_get_key_usage(X509 *x) { /* Call for side-effect of computing hash and caching extensions */ - if (X509_check_purpose(x, -1, -1) != 1) + if (X509_check_purpose(x, -1, 0) != 1) return 0; if (x->ex_flags & EXFLAG_KUSAGE) return x->ex_kusage; @@ -935,7 +1008,7 @@ uint32_t X509_get_key_usage(X509 *x) uint32_t X509_get_extended_key_usage(X509 *x) { /* Call for side-effect of computing hash and caching extensions */ - if (X509_check_purpose(x, -1, -1) != 1) + if (X509_check_purpose(x, -1, 0) != 1) return 0; if (x->ex_flags & EXFLAG_XKUSAGE) return x->ex_xkusage; @@ -945,7 +1018,7 @@ uint32_t X509_get_extended_key_usage(X509 *x) const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x) { /* Call for side-effect of computing hash and caching extensions */ - if (X509_check_purpose(x, -1, -1) != 1) + if (X509_check_purpose(x, -1, 0) != 1) return NULL; return x->skid; } @@ -953,7 +1026,7 @@ const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x) const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x) { /* Call for side-effect of computing hash and caching extensions */ - if (X509_check_purpose(x, -1, -1) != 1) + if (X509_check_purpose(x, -1, 0) != 1) return NULL; return (x->akid != NULL ? x->akid->keyid : NULL); } @@ -961,7 +1034,7 @@ const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x) const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x) { /* Call for side-effect of computing hash and caching extensions */ - if (X509_check_purpose(x, -1, -1) != 1) + if (X509_check_purpose(x, -1, 0) != 1) return NULL; return (x->akid != NULL ? x->akid->issuer : NULL); } @@ -969,7 +1042,7 @@ const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x) const ASN1_INTEGER *X509_get0_authority_serial(X509 *x) { /* Call for side-effect of computing hash and caching extensions */ - if (X509_check_purpose(x, -1, -1) != 1) + if (X509_check_purpose(x, -1, 0) != 1) return NULL; return (x->akid != NULL ? x->akid->serial : NULL); } @@ -977,7 +1050,7 @@ const ASN1_INTEGER *X509_get0_authority_serial(X509 *x) long X509_get_pathlen(X509 *x) { /* Called for side effect of caching extensions */ - if (X509_check_purpose(x, -1, -1) != 1 + if (X509_check_purpose(x, -1, 0) != 1 || (x->ex_flags & EXFLAG_BCONS) == 0) return -1; return x->ex_pathlen; @@ -986,7 +1059,7 @@ long X509_get_pathlen(X509 *x) long X509_get_proxy_pathlen(X509 *x) { /* Called for side effect of caching extensions */ - if (X509_check_purpose(x, -1, -1) != 1 + if (X509_check_purpose(x, -1, 0) != 1 || (x->ex_flags & EXFLAG_PROXY) == 0) return -1; return x->ex_pcpathlen; diff --git a/crypto/openssl/crypto/x509v3/v3_alt.c b/crypto/openssl/crypto/x509/v3_san.c similarity index 64% rename from crypto/openssl/crypto/x509v3/v3_alt.c rename to crypto/openssl/crypto/x509/v3_san.c index 7c32d4031d11..c081f02e19e4 100644 --- a/crypto/openssl/crypto/x509v3/v3_alt.c +++ b/crypto/openssl/crypto/x509/v3_san.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,6 +12,7 @@ #include "crypto/x509.h" #include #include +#include #include "ext_dat.h" static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, @@ -25,7 +26,7 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); -const X509V3_EXT_METHOD v3_alt[3] = { +const X509V3_EXT_METHOD ossl_v3_alt[3] = { {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 0, 0, 0, 0, 0, 0, @@ -79,14 +80,78 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret) { - unsigned char *p; - char oline[256], htmp[5]; - int i; + char othername[300]; + char oline[256], *tmp; switch (gen->type) { case GEN_OTHERNAME: - if (!X509V3_add_value("othername", "", &ret)) - return NULL; + switch (OBJ_obj2nid(gen->d.otherName->type_id)) { + case NID_id_on_SmtpUTF8Mailbox: + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !x509v3_add_len_value_uchar("othername: SmtpUTF8Mailbox:", + gen->d.otherName->value->value.utf8string->data, + gen->d.otherName->value->value.utf8string->length, + &ret)) + return NULL; + break; + case NID_XmppAddr: + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !x509v3_add_len_value_uchar("othername: XmppAddr:", + gen->d.otherName->value->value.utf8string->data, + gen->d.otherName->value->value.utf8string->length, + &ret)) + return NULL; + break; + case NID_SRVName: + if (gen->d.otherName->value->type != V_ASN1_IA5STRING + || !x509v3_add_len_value_uchar("othername: SRVName:", + gen->d.otherName->value->value.ia5string->data, + gen->d.otherName->value->value.ia5string->length, + &ret)) + return NULL; + break; + case NID_ms_upn: + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !x509v3_add_len_value_uchar("othername: UPN:", + gen->d.otherName->value->value.utf8string->data, + gen->d.otherName->value->value.utf8string->length, + &ret)) + return NULL; + break; + case NID_NAIRealm: + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !x509v3_add_len_value_uchar("othername: NAIRealm:", + gen->d.otherName->value->value.utf8string->data, + gen->d.otherName->value->value.utf8string->length, + &ret)) + return NULL; + break; + default: + if (OBJ_obj2txt(oline, sizeof(oline), gen->d.otherName->type_id, 0) > 0) + BIO_snprintf(othername, sizeof(othername), "othername: %s:", + oline); + else + OPENSSL_strlcpy(othername, "othername:", sizeof(othername)); + + /* check if the value is something printable */ + if (gen->d.otherName->value->type == V_ASN1_IA5STRING) { + if (x509v3_add_len_value_uchar(othername, + gen->d.otherName->value->value.ia5string->data, + gen->d.otherName->value->value.ia5string->length, + &ret)) + return ret; + } + if (gen->d.otherName->value->type == V_ASN1_UTF8STRING) { + if (x509v3_add_len_value_uchar(othername, + gen->d.otherName->value->value.utf8string->data, + gen->d.otherName->value->value.utf8string->length, + &ret)) + return ret; + } + if (!X509V3_add_value(othername, "", &ret)) + return NULL; + break; + } break; case GEN_X400: @@ -124,26 +189,10 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, break; case GEN_IPADD: - p = gen->d.ip->data; - if (gen->d.ip->length == 4) - BIO_snprintf(oline, sizeof(oline), "%d.%d.%d.%d", - p[0], p[1], p[2], p[3]); - else if (gen->d.ip->length == 16) { - oline[0] = 0; - for (i = 0; i < 8; i++) { - BIO_snprintf(htmp, sizeof(htmp), "%X", p[0] << 8 | p[1]); - p += 2; - strcat(oline, htmp); - if (i != 7) - strcat(oline, ":"); - } - } else { - if (!X509V3_add_value("IP Address", "", &ret)) - return NULL; - break; - } - if (!X509V3_add_value("IP Address", oline, &ret)) - return NULL; + tmp = ossl_ipaddr_to_asc(gen->d.ip->data, gen->d.ip->length); + if (tmp == NULL || !X509V3_add_value("IP Address", tmp, &ret)) + ret = NULL; + OPENSSL_free(tmp); break; case GEN_RID: @@ -157,11 +206,51 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) { - unsigned char *p; - int i; + char *tmp; + int nid; + switch (gen->type) { case GEN_OTHERNAME: - BIO_printf(out, "othername:"); + nid = OBJ_obj2nid(gen->d.otherName->type_id); + /* Validate the types are as we expect before we use them */ + if ((nid == NID_SRVName + && gen->d.otherName->value->type != V_ASN1_IA5STRING) + || (nid != NID_SRVName + && gen->d.otherName->value->type != V_ASN1_UTF8STRING)) { + BIO_printf(out, "othername:"); + break; + } + + switch (nid) { + case NID_id_on_SmtpUTF8Mailbox: + BIO_printf(out, "othername:SmtpUTF8Mailbox:%.*s", + gen->d.otherName->value->value.utf8string->length, + gen->d.otherName->value->value.utf8string->data); + break; + case NID_XmppAddr: + BIO_printf(out, "othername:XmppAddr:%.*s", + gen->d.otherName->value->value.utf8string->length, + gen->d.otherName->value->value.utf8string->data); + break; + case NID_SRVName: + BIO_printf(out, "othername:SRVName:%.*s", + gen->d.otherName->value->value.ia5string->length, + gen->d.otherName->value->value.ia5string->data); + break; + case NID_ms_upn: + BIO_printf(out, "othername:UPN:%.*s", + gen->d.otherName->value->value.utf8string->length, + gen->d.otherName->value->value.utf8string->data); + break; + case NID_NAIRealm: + BIO_printf(out, "othername:NAIRealm:%.*s", + gen->d.otherName->value->value.utf8string->length, + gen->d.otherName->value->value.utf8string->data); + break; + default: + BIO_printf(out, "othername:"); + break; + } break; case GEN_X400: @@ -194,20 +283,11 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) break; case GEN_IPADD: - p = gen->d.ip->data; - if (gen->d.ip->length == 4) - BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); - else if (gen->d.ip->length == 16) { - BIO_printf(out, "IP Address"); - for (i = 0; i < 8; i++) { - BIO_printf(out, ":%X", p[0] << 8 | p[1]); - p += 2; - } - BIO_puts(out, "\n"); - } else { - BIO_printf(out, "IP Address:"); - break; - } + tmp = ossl_ipaddr_to_asc(gen->d.ip->data, gen->d.ip->length); + if (tmp == NULL) + return 0; + BIO_printf(out, "IP Address:%s", tmp); + OPENSSL_free(tmp); break; case GEN_RID: @@ -227,14 +307,14 @@ static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, int i; if (gens == NULL) { - X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); sk_GENERAL_NAME_free(gens); return NULL; } for (i = 0; i < num; i++) { CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); - if (!name_cmp(cnf->name, "issuer") + if (!ossl_v3_name_cmp(cnf->name, "issuer") && cnf->value && strcmp(cnf->value, "copy") == 0) { if (!copy_issuer(ctx, gens)) goto err; @@ -261,10 +341,10 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) X509_EXTENSION *ext; int i, num; - if (ctx && (ctx->flags == CTX_TEST)) + if (ctx != NULL && (ctx->flags & X509V3_CTX_TEST) != 0) return 1; if (!ctx || !ctx->issuer_cert) { - X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS); + ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_ISSUER_DETAILS); goto err; } i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); @@ -272,14 +352,13 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) return 1; if ((ext = X509_get_ext(ctx->issuer_cert, i)) == NULL || (ialt = X509V3_EXT_d2i(ext)) == NULL) { - X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); + ERR_raise(ERR_LIB_X509V3, X509V3_R_ISSUER_DECODE_ERROR); goto err; } num = sk_GENERAL_NAME_num(ialt); if (!sk_GENERAL_NAME_reserve(gens, num)) { - X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); - sk_GENERAL_NAME_free(ialt); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } @@ -307,18 +386,18 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, gens = sk_GENERAL_NAME_new_reserve(NULL, num); if (gens == NULL) { - X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); sk_GENERAL_NAME_free(gens); return NULL; } for (i = 0; i < num; i++) { cnf = sk_CONF_VALUE_value(nval, i); - if (!name_cmp(cnf->name, "email") + if (ossl_v3_name_cmp(cnf->name, "email") == 0 && cnf->value && strcmp(cnf->value, "copy") == 0) { if (!copy_email(ctx, gens, 0)) goto err; - } else if (!name_cmp(cnf->name, "email") + } else if (ossl_v3_name_cmp(cnf->name, "email") == 0 && cnf->value && strcmp(cnf->value, "move") == 0) { if (!copy_email(ctx, gens, 1)) goto err; @@ -347,18 +426,17 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) GENERAL_NAME *gen = NULL; int i = -1; - if (ctx != NULL && ctx->flags == CTX_TEST) + if (ctx != NULL && (ctx->flags & X509V3_CTX_TEST) != 0) return 1; if (ctx == NULL || (ctx->subject_cert == NULL && ctx->subject_req == NULL)) { - X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); - goto err; + ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_SUBJECT_DETAILS); + return 0; } /* Find the subject name */ - if (ctx->subject_cert) - nm = X509_get_subject_name(ctx->subject_cert); - else - nm = X509_REQ_get_subject_name(ctx->subject_req); + nm = ctx->subject_cert != NULL ? + X509_get_subject_name(ctx->subject_cert) : + X509_REQ_get_subject_name(ctx->subject_req); /* Now add any email address(es) to STACK */ while ((i = X509_NAME_get_index_by_NID(nm, @@ -371,14 +449,14 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) i--; } if (email == NULL || (gen = GENERAL_NAME_new()) == NULL) { - X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } gen->d.ia5 = email; email = NULL; gen->type = GEN_EMAIL; if (!sk_GENERAL_NAME_push(gens, gen)) { - X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } gen = NULL; @@ -404,7 +482,7 @@ GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, gens = sk_GENERAL_NAME_new_reserve(NULL, num); if (gens == NULL) { - X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); sk_GENERAL_NAME_free(gens); return NULL; } @@ -436,7 +514,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, GENERAL_NAME *gen = NULL; if (!value) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE); + ERR_raise(ERR_LIB_X509V3, X509V3_R_MISSING_VALUE); return NULL; } @@ -445,7 +523,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, else { gen = GENERAL_NAME_new(); if (gen == NULL) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } } @@ -461,8 +539,8 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, { ASN1_OBJECT *obj; if ((obj = OBJ_txt2obj(value, 0)) == NULL) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT); - ERR_add_error_data(2, "value=", value); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_BAD_OBJECT, + "value=%s", value); goto err; } gen->d.rid = obj; @@ -475,27 +553,27 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, else gen->d.ip = a2i_IPADDRESS(value); if (gen->d.ip == NULL) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS); - ERR_add_error_data(2, "value=", value); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_BAD_IP_ADDRESS, + "value=%s", value); goto err; } break; case GEN_DIRNAME: if (!do_dirname(gen, value, ctx)) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR); + ERR_raise(ERR_LIB_X509V3, X509V3_R_DIRNAME_ERROR); goto err; } break; case GEN_OTHERNAME: if (!do_othername(gen, value, ctx)) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR); + ERR_raise(ERR_LIB_X509V3, X509V3_R_OTHERNAME_ERROR); goto err; } break; default: - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE); + ERR_raise(ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_TYPE); goto err; } @@ -503,7 +581,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL || !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, strlen(value))) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } } @@ -530,27 +608,27 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, value = cnf->value; if (!value) { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE); + ERR_raise(ERR_LIB_X509V3, X509V3_R_MISSING_VALUE); return NULL; } - if (!name_cmp(name, "email")) + if (!ossl_v3_name_cmp(name, "email")) type = GEN_EMAIL; - else if (!name_cmp(name, "URI")) + else if (!ossl_v3_name_cmp(name, "URI")) type = GEN_URI; - else if (!name_cmp(name, "DNS")) + else if (!ossl_v3_name_cmp(name, "DNS")) type = GEN_DNS; - else if (!name_cmp(name, "RID")) + else if (!ossl_v3_name_cmp(name, "RID")) type = GEN_RID; - else if (!name_cmp(name, "IP")) + else if (!ossl_v3_name_cmp(name, "IP")) type = GEN_IPADD; - else if (!name_cmp(name, "dirName")) + else if (!ossl_v3_name_cmp(name, "dirName")) type = GEN_DIRNAME; - else if (!name_cmp(name, "otherName")) + else if (!ossl_v3_name_cmp(name, "otherName")) type = GEN_OTHERNAME; else { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION); - ERR_add_error_data(2, "name=", name); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_OPTION, + "name=%s", name); return NULL; } @@ -595,8 +673,8 @@ static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) goto err; sk = X509V3_get_section(ctx, value); if (!sk) { - X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND); - ERR_add_error_data(2, "section=", value); + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_SECTION_NOT_FOUND, + "section=%s", value); goto err; } /* FIXME: should allow other character types... */ diff --git a/crypto/openssl/crypto/x509v3/v3_skey.c b/crypto/openssl/crypto/x509/v3_skid.c similarity index 55% rename from crypto/openssl/crypto/x509v3/v3_skey.c rename to crypto/openssl/crypto/x509/v3_skid.c index c2e82045682a..18223f2ef496 100644 --- a/crypto/openssl/crypto/x509v3/v3_skey.c +++ b/crypto/openssl/crypto/x509/v3_skid.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,7 +15,7 @@ static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str); -const X509V3_EXT_METHOD v3_skey_id = { +const X509V3_EXT_METHOD ossl_v3_skey_id = { NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING), 0, 0, 0, 0, (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, @@ -37,7 +37,7 @@ ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, long length; if ((oct = ASN1_OCTET_STRING_new()) == NULL) { - X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } @@ -52,55 +52,60 @@ ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, } -static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str) +ASN1_OCTET_STRING *ossl_x509_pubkey_hash(X509_PUBKEY *pubkey) { ASN1_OCTET_STRING *oct; - X509_PUBKEY *pubkey; const unsigned char *pk; int pklen; unsigned char pkey_dig[EVP_MAX_MD_SIZE]; unsigned int diglen; + const char *propq; + OSSL_LIB_CTX *libctx; + EVP_MD *md; - if (strcmp(str, "hash")) - return s2i_ASN1_OCTET_STRING(method, ctx, str); - + if (pubkey == NULL) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_PUBLIC_KEY); + return NULL; + } + if (!ossl_x509_PUBKEY_get0_libctx(&libctx, &propq, pubkey)) + return NULL; + if ((md = EVP_MD_fetch(libctx, SN_sha1, propq)) == NULL) + return NULL; if ((oct = ASN1_OCTET_STRING_new()) == NULL) { - X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); + EVP_MD_free(md); return NULL; } - if (ctx && (ctx->flags == CTX_TEST)) + X509_PUBKEY_get0_param(NULL, &pk, &pklen, NULL, pubkey); + if (EVP_Digest(pk, pklen, pkey_dig, &diglen, md, NULL) + && ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { + EVP_MD_free(md); return oct; - - if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { - X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); - goto err; } - if (ctx->subject_req) - pubkey = ctx->subject_req->req_info.pubkey; - else - pubkey = ctx->subject_cert->cert_info.key; - - if (pubkey == NULL) { - X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); - goto err; - } + EVP_MD_free(md); + ASN1_OCTET_STRING_free(oct); + return NULL; +} - X509_PUBKEY_get0_param(NULL, &pk, &pklen, NULL, pubkey); +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str) +{ + if (strcmp(str, "none") == 0) + return ASN1_OCTET_STRING_new(); /* dummy */ - if (!EVP_Digest(pk, pklen, pkey_dig, &diglen, EVP_sha1(), NULL)) - goto err; + if (strcmp(str, "hash") != 0) + return s2i_ASN1_OCTET_STRING(method, ctx /* not used */, str); - if (!ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { - X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); - goto err; + if (ctx != NULL && (ctx->flags & X509V3_CTX_TEST) != 0) + return ASN1_OCTET_STRING_new(); + if (ctx == NULL + || (ctx->subject_cert == NULL && ctx->subject_req == NULL)) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_SUBJECT_DETAILS); + return NULL; } - return oct; - - err: - ASN1_OCTET_STRING_free(oct); - return NULL; + return ossl_x509_pubkey_hash(ctx->subject_cert != NULL ? + ctx->subject_cert->cert_info.key : + ctx->subject_req->req_info.pubkey); } diff --git a/crypto/openssl/crypto/x509v3/v3_sxnet.c b/crypto/openssl/crypto/x509/v3_sxnet.c similarity index 87% rename from crypto/openssl/crypto/x509v3/v3_sxnet.c rename to crypto/openssl/crypto/x509/v3_sxnet.c index 3c5508f9416c..ca46dc1a5c32 100644 --- a/crypto/openssl/crypto/x509v3/v3_sxnet.c +++ b/crypto/openssl/crypto/x509/v3_sxnet.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -25,7 +25,7 @@ static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); #endif -const X509V3_EXT_METHOD v3_sxnet = { +const X509V3_EXT_METHOD ossl_v3_sxnet = { NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET), 0, 0, 0, 0, 0, 0, @@ -120,7 +120,7 @@ int SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userle ASN1_INTEGER *izone; if ((izone = s2i_ASN1_INTEGER(NULL, zone)) == NULL) { - X509V3err(X509V3_F_SXNET_ADD_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE); + ERR_raise(ERR_LIB_X509V3, X509V3_R_ERROR_CONVERTING_ZONE); return 0; } return SXNET_add_id_INTEGER(psx, izone, user, userlen); @@ -135,7 +135,7 @@ int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user, if ((izone = ASN1_INTEGER_new()) == NULL || !ASN1_INTEGER_set(izone, lzone)) { - X509V3err(X509V3_F_SXNET_ADD_ID_ULONG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); ASN1_INTEGER_free(izone); return 0; } @@ -153,15 +153,15 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, const char *user, { SXNET *sx = NULL; SXNETID *id = NULL; - if (!psx || !zone || !user) { - X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, - X509V3_R_INVALID_NULL_ARGUMENT); + + if (psx == NULL || zone == NULL || user == NULL) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NULL_ARGUMENT); return 0; } if (userlen == -1) userlen = strlen(user); if (userlen > 64) { - X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_USER_TOO_LONG); + ERR_raise(ERR_LIB_X509V3, X509V3_R_USER_TOO_LONG); return 0; } if (*psx == NULL) { @@ -169,11 +169,12 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, const char *user, goto err; if (!ASN1_INTEGER_set(sx->version, 0)) goto err; - *psx = sx; } else sx = *psx; if (SXNET_get_id_INTEGER(sx, zone)) { - X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_DUPLICATE_ZONE_ID); + ERR_raise(ERR_LIB_X509V3, X509V3_R_DUPLICATE_ZONE_ID); + if (*psx == NULL) + SXNET_free(sx); return 0; } @@ -187,13 +188,14 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, const char *user, if (!sk_SXNETID_push(sx->ids, id)) goto err; id->zone = zone; + *psx = sx; return 1; err: - X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); SXNETID_free(id); - SXNET_free(sx); - *psx = NULL; + if (*psx == NULL) + SXNET_free(sx); return 0; } @@ -203,7 +205,7 @@ ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, const char *zone) ASN1_OCTET_STRING *oct; if ((izone = s2i_ASN1_INTEGER(NULL, zone)) == NULL) { - X509V3err(X509V3_F_SXNET_GET_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE); + ERR_raise(ERR_LIB_X509V3, X509V3_R_ERROR_CONVERTING_ZONE); return NULL; } oct = SXNET_get_id_INTEGER(sx, izone); @@ -218,7 +220,7 @@ ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone) if ((izone = ASN1_INTEGER_new()) == NULL || !ASN1_INTEGER_set(izone, lzone)) { - X509V3err(X509V3_F_SXNET_GET_ID_ULONG, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); ASN1_INTEGER_free(izone); return NULL; } diff --git a/crypto/openssl/crypto/x509v3/v3_tlsf.c b/crypto/openssl/crypto/x509/v3_tlsf.c similarity index 85% rename from crypto/openssl/crypto/x509v3/v3_tlsf.c rename to crypto/openssl/crypto/x509/v3_tlsf.c index 7fd6ef17dbee..3a457fa57bee 100644 --- a/crypto/openssl/crypto/x509v3/v3_tlsf.c +++ b/crypto/openssl/crypto/x509/v3_tlsf.c @@ -1,7 +1,7 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,11 +10,11 @@ #include "e_os.h" #include "internal/cryptlib.h" #include -#include "internal/o_str.h" #include #include #include #include "ext_dat.h" +#include "x509_local.h" static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method, TLS_FEATURE *tls_feature, @@ -29,7 +29,7 @@ static_ASN1_ITEM_TEMPLATE_END(TLS_FEATURE) IMPLEMENT_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE) -const X509V3_EXT_METHOD v3_tls_feature = { +const X509V3_EXT_METHOD ossl_v3_tls_feature = { NID_tlsfeature, 0, ASN1_ITEM_ref(TLS_FEATURE), 0, 0, 0, 0, @@ -89,14 +89,14 @@ static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, { TLS_FEATURE *tlsf; char *extval, *endptr; - ASN1_INTEGER *ai; + ASN1_INTEGER *ai = NULL; CONF_VALUE *val; int i; size_t j; long tlsextid; if ((tlsf = sk_ASN1_INTEGER_new_null()) == NULL) { - X509V3err(X509V3_F_V2I_TLS_FEATURE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } @@ -108,7 +108,7 @@ static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, extval = val->name; for (j = 0; j < OSSL_NELEM(tls_feature_tbl); j++) - if (strcasecmp(extval, tls_feature_tbl[j].name) == 0) + if (OPENSSL_strcasecmp(extval, tls_feature_tbl[j].name) == 0) break; if (j < OSSL_NELEM(tls_feature_tbl)) tlsextid = tls_feature_tbl[j].num; @@ -116,8 +116,8 @@ static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, tlsextid = strtol(extval, &endptr, 10); if (((*endptr) != '\0') || (extval == endptr) || (tlsextid < 0) || (tlsextid > 65535)) { - X509V3err(X509V3_F_V2I_TLS_FEATURE, X509V3_R_INVALID_SYNTAX); - X509V3_conf_err(val); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_SYNTAX); + X509V3_conf_add_error_name_value(val); goto err; } } @@ -125,13 +125,16 @@ static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, if ((ai = ASN1_INTEGER_new()) == NULL || !ASN1_INTEGER_set(ai, tlsextid) || sk_ASN1_INTEGER_push(tlsf, ai) <= 0) { - X509V3err(X509V3_F_V2I_TLS_FEATURE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } + /* So it doesn't get purged if an error occurs next time around */ + ai = NULL; } return tlsf; err: sk_ASN1_INTEGER_pop_free(tlsf, ASN1_INTEGER_free); + ASN1_INTEGER_free(ai); return NULL; } diff --git a/crypto/openssl/crypto/x509/v3_utf8.c b/crypto/openssl/crypto/x509/v3_utf8.c new file mode 100644 index 000000000000..1c4f79c4cd9b --- /dev/null +++ b/crypto/openssl/crypto/x509/v3_utf8.c @@ -0,0 +1,68 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +/* + * Subject Sign Tool (1.2.643.100.111) The name of the tool used to signs the subject (UTF8String) + * This extention is required to obtain the status of a qualified certificate at Russian Federation. + * RFC-style description is available here: https://tools.ietf.org/html/draft-deremin-rfc4491-bis-04#section-5 + * Russian Federal Law 63 "Digital Sign" is available here: http://www.consultant.ru/document/cons_doc_LAW_112701/ + */ + + +const X509V3_EXT_METHOD ossl_v3_utf8_list[1] = { + EXT_UTF8STRING(NID_subjectSignTool), +}; + +char *i2s_ASN1_UTF8STRING(X509V3_EXT_METHOD *method, + ASN1_UTF8STRING *utf8) +{ + char *tmp; + + if (utf8 == NULL || utf8->length == 0) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if ((tmp = OPENSSL_malloc(utf8->length + 1)) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + memcpy(tmp, utf8->data, utf8->length); + tmp[utf8->length] = 0; + return tmp; +} + +ASN1_UTF8STRING *s2i_ASN1_UTF8STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str) +{ + ASN1_UTF8STRING *utf8; + if (str == NULL) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if ((utf8 = ASN1_UTF8STRING_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!ASN1_STRING_set((ASN1_STRING *)utf8, str, strlen(str))) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ASN1_UTF8STRING_free(utf8); + return NULL; + } +#ifdef CHARSET_EBCDIC + ebcdic2ascii(utf8->data, utf8->data, utf8->length); +#endif /* CHARSET_EBCDIC */ + return utf8; +} diff --git a/crypto/openssl/crypto/x509v3/v3_utl.c b/crypto/openssl/crypto/x509/v3_utl.c similarity index 87% rename from crypto/openssl/crypto/x509v3/v3_utl.c rename to crypto/openssl/crypto/x509/v3_utl.c index eac78259fc82..6e4ef26ed608 100644 --- a/crypto/openssl/crypto/x509v3/v3_utl.c +++ b/crypto/openssl/crypto/x509/v3_utl.c @@ -1,7 +1,7 @@ /* * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,13 +20,15 @@ #include "crypto/x509.h" #include #include "ext_dat.h" +#include "x509_local.h" static char *strip_spaces(char *name); static int sk_strcmp(const char *const *a, const char *const *b); -static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, +static STACK_OF(OPENSSL_STRING) *get_email(const X509_NAME *name, GENERAL_NAMES *gens); static void str_free(OPENSSL_STRING str); -static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email); +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, + const ASN1_IA5STRING *email); static int ipv4_from_asc(unsigned char *v4, const char *in); static int ipv6_from_asc(unsigned char *v6, const char *in); @@ -44,12 +46,9 @@ static int x509v3_add_len_value(const char *name, const char *value, if (name != NULL && (tname = OPENSSL_strdup(name)) == NULL) goto err; - if (value != NULL && vallen > 0) { - /* - * We tolerate a single trailing NUL character, but otherwise no - * embedded NULs - */ - if (memchr(value, 0, vallen - 1) != NULL) + if (value != NULL) { + /* We don't allow embeded NUL characters */ + if (memchr(value, 0, vallen) != NULL) goto err; tvalue = OPENSSL_strndup(value, vallen); if (tvalue == NULL) @@ -66,7 +65,7 @@ static int x509v3_add_len_value(const char *name, const char *value, goto err; return 1; err: - X509V3err(X509V3_F_X509V3_ADD_LEN_VALUE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); if (sk_allocated) { sk_CONF_VALUE_free(*extlist); *extlist = NULL; @@ -147,7 +146,7 @@ static char *bignum_to_string(const BIGNUM *bn) len = strlen(tmp) + 3; ret = OPENSSL_malloc(len); if (ret == NULL) { - X509V3err(X509V3_F_BIGNUM_TO_STRING, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); OPENSSL_free(tmp); return NULL; } @@ -173,7 +172,7 @@ char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a) return NULL; if ((bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) == NULL || (strtmp = bignum_to_string(bntmp)) == NULL) - X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); BN_free(bntmp); return strtmp; } @@ -187,7 +186,7 @@ char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a) return NULL; if ((bntmp = ASN1_INTEGER_to_BN(a, NULL)) == NULL || (strtmp = bignum_to_string(bntmp)) == NULL) - X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); BN_free(bntmp); return strtmp; } @@ -198,26 +197,29 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value) ASN1_INTEGER *aint; int isneg, ishex; int ret; + if (value == NULL) { - X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NULL_VALUE); return NULL; } bn = BN_new(); if (bn == NULL) { - X509V3err(X509V3_F_S2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } if (value[0] == '-') { value++; isneg = 1; - } else + } else { isneg = 0; + } if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) { value += 2; ishex = 1; - } else + } else { ishex = 0; + } if (ishex) ret = BN_hex2bn(&bn, value); @@ -226,7 +228,7 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value) if (!ret || value[ret]) { BN_free(bn); - X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR); + ERR_raise(ERR_LIB_X509V3, X509V3_R_BN_DEC2BN_ERROR); return NULL; } @@ -236,8 +238,7 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value) aint = BN_to_ASN1_INTEGER(bn, NULL); BN_free(bn); if (!aint) { - X509V3err(X509V3_F_S2I_ASN1_INTEGER, - X509V3_R_BN_TO_ASN1_INTEGER_ERROR); + ERR_raise(ERR_LIB_X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR); return NULL; } if (isneg) @@ -285,9 +286,8 @@ int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool) return 1; } err: - X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL, - X509V3_R_INVALID_BOOLEAN_STRING); - X509V3_conf_err(value); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_BOOLEAN_STRING); + X509V3_conf_add_error_name_value(value); return 0; } @@ -296,7 +296,7 @@ int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint) ASN1_INTEGER *itmp; if ((itmp = s2i_ASN1_INTEGER(NULL, value->value)) == NULL) { - X509V3_conf_err(value); + X509V3_conf_add_error_name_value(value); return 0; } *aint = itmp; @@ -317,10 +317,11 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) STACK_OF(CONF_VALUE) *values = NULL; char *linebuf; int state; + /* We are going to modify the line so copy it first */ linebuf = OPENSSL_strdup(line); if (linebuf == NULL) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); goto err; } state = HDR_NAME; @@ -336,8 +337,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) *p = 0; ntmp = strip_spaces(q); if (!ntmp) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, - X509V3_R_INVALID_NULL_NAME); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_EMPTY_NAME); goto err; } q = p + 1; @@ -346,11 +346,12 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) ntmp = strip_spaces(q); q = p + 1; if (!ntmp) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, - X509V3_R_INVALID_NULL_NAME); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_EMPTY_NAME); + goto err; + } + if (!X509V3_add_value(ntmp, NULL, &values)) { goto err; } - X509V3_add_value(ntmp, NULL, &values); } break; @@ -360,11 +361,12 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) *p = 0; vtmp = strip_spaces(q); if (!vtmp) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, - X509V3_R_INVALID_NULL_VALUE); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NULL_VALUE); + goto err; + } + if (!X509V3_add_value(ntmp, vtmp, &values)) { goto err; } - X509V3_add_value(ntmp, vtmp, &values); ntmp = NULL; q = p + 1; } @@ -375,18 +377,21 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) if (state == HDR_VALUE) { vtmp = strip_spaces(q); if (!vtmp) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, - X509V3_R_INVALID_NULL_VALUE); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NULL_VALUE); + goto err; + } + if (!X509V3_add_value(ntmp, vtmp, &values)) { goto err; } - X509V3_add_value(ntmp, vtmp, &values); } else { ntmp = strip_spaces(q); if (!ntmp) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_EMPTY_NAME); + goto err; + } + if (!X509V3_add_value(ntmp, NULL, &values)) { goto err; } - X509V3_add_value(ntmp, NULL, &values); } OPENSSL_free(linebuf); return values; @@ -402,18 +407,19 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) static char *strip_spaces(char *name) { char *p, *q; + /* Skip over leading spaces */ p = name; while (*p && ossl_isspace(*p)) p++; - if (!*p) + if (*p == '\0') return NULL; q = p + strlen(p) - 1; while ((q != p) && ossl_isspace(*q)) q--; if (p != q) q[1] = 0; - if (!*p) + if (*p == '\0') return NULL; return p; } @@ -423,10 +429,11 @@ static char *strip_spaces(char *name) * V2I name comparison function: returns zero if 'name' matches cmp or cmp.* */ -int name_cmp(const char *name, const char *cmp) +int ossl_v3_name_cmp(const char *name, const char *cmp) { int len, ret; char c; + len = strlen(cmp); if ((ret = strncmp(name, cmp, len))) return ret; @@ -489,7 +496,7 @@ STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x) return ret; } -static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, +static STACK_OF(OPENSSL_STRING) *get_email(const X509_NAME *name, GENERAL_NAMES *gens) { STACK_OF(OPENSSL_STRING) *ret = NULL; @@ -522,9 +529,11 @@ static void str_free(OPENSSL_STRING str) OPENSSL_free(str); } -static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email) +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, + const ASN1_IA5STRING *email) { char *emtmp; + /* First some sanity checks */ if (email->type != V_ASN1_IA5STRING) return 1; @@ -607,9 +616,10 @@ static int equal_nocase(const unsigned char *pattern, size_t pattern_len, skip_prefix(&pattern, &pattern_len, subject_len, flags); if (pattern_len != subject_len) return 0; - while (pattern_len) { + while (pattern_len != 0) { unsigned char l = *pattern; unsigned char r = *subject; + /* The pattern must not contain NUL characters. */ if (l == 0) return 0; @@ -648,6 +658,7 @@ static int equal_email(const unsigned char *a, size_t a_len, unsigned int unused_flags) { size_t i = a_len; + if (a_len != b_len) return 0; /* @@ -704,7 +715,7 @@ static int wildcard_match(const unsigned char *prefix, size_t prefix_len, } /* IDNA labels cannot match partial wildcards */ if (!allow_idna && - subject_len >= 4 && strncasecmp((char *)subject, "xn--", 4) == 0) + subject_len >= 4 && OPENSSL_strncasecmp((char *)subject, "xn--", 4) == 0) return 0; /* The wildcard may match a literal '*' */ if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*') @@ -735,6 +746,7 @@ static const unsigned char *valid_star(const unsigned char *p, size_t len, size_t i; int state = LABEL_START; int dots = 0; + for (i = 0; i < len; ++i) { /* * Locate first and only legal wildcard, either at the start @@ -763,7 +775,7 @@ static const unsigned char *valid_star(const unsigned char *p, size_t len, || ('A' <= p[i] && p[i] <= 'Z') || ('0' <= p[i] && p[i] <= '9')) { if ((state & LABEL_START) != 0 - && len - i >= 4 && strncasecmp((char *)&p[i], "xn--", 4) == 0) + && len - i >= 4 && OPENSSL_strncasecmp((char *)&p[i], "xn--", 4) == 0) state |= LABEL_IDNA; state &= ~(LABEL_HYPHEN | LABEL_START); } else if (p[i] == '.') { @@ -776,8 +788,9 @@ static const unsigned char *valid_star(const unsigned char *p, size_t len, if ((state & LABEL_START) != 0) return NULL; state |= LABEL_HYPHEN; - } else + } else { return NULL; + } } /* @@ -864,7 +877,7 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen, unsigned int flags, int check_type, char **peername) { GENERAL_NAMES *gens = NULL; - X509_NAME *name = NULL; + const X509_NAME *name = NULL; int i; int cnid = NID_undef; int alt_type; @@ -901,9 +914,31 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen, for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { GENERAL_NAME *gen; ASN1_STRING *cstr; + gen = sk_GENERAL_NAME_value(gens, i); - if (gen->type != check_type) - continue; + if ((gen->type == GEN_OTHERNAME) && (check_type == GEN_EMAIL)) { + if (OBJ_obj2nid(gen->d.otherName->type_id) == + NID_id_on_SmtpUTF8Mailbox) { + san_present = 1; + + /* + * If it is not a UTF8String then that is unexpected and we + * treat it as no match + */ + if (gen->d.otherName->value->type == V_ASN1_UTF8STRING) { + cstr = gen->d.otherName->value->value.utf8string; + + /* Positive on success, negative on error! */ + if ((rv = do_check_string(cstr, 0, equal, flags, + chk, chklen, peername)) != 0) + break; + } + } else + continue; + } else { + if ((gen->type != check_type) && (gen->type != GEN_OTHERNAME)) + continue; + } san_present = 1; if (check_type == GEN_EMAIL) cstr = gen->d.rfc822Name; @@ -994,12 +1029,42 @@ int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags) if (ipasc == NULL) return -2; - iplen = (size_t)a2i_ipadd(ipout, ipasc); + iplen = (size_t)ossl_a2i_ipadd(ipout, ipasc); if (iplen == 0) return -2; return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL); } +char *ossl_ipaddr_to_asc(unsigned char *p, int len) +{ + /* + * 40 is enough space for the longest IPv6 address + nul terminator byte + * XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX\0 + */ + char buf[40], *out; + int i = 0, remain = 0, bytes = 0; + + switch (len) { + case 4: /* IPv4 */ + BIO_snprintf(buf, sizeof(buf), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + break; + case 16: /* IPv6 */ + for (out = buf, i = 8, remain = sizeof(buf); + i-- > 0 && bytes >= 0; + remain -= bytes, out += bytes) { + const char *template = (i > 0 ? "%X:" : "%X"); + + bytes = BIO_snprintf(out, remain, template, p[0] << 8 | p[1]); + p += 2; + } + break; + default: + BIO_snprintf(buf, sizeof(buf), "", len); + break; + } + return OPENSSL_strdup(buf); +} + /* * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible * with RFC3280. @@ -1013,7 +1078,7 @@ ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc) /* If string contains a ':' assume IPv6 */ - iplen = a2i_ipadd(ipout, ipasc); + iplen = ossl_a2i_ipadd(ipout, ipasc); if (!iplen) return NULL; @@ -1034,21 +1099,22 @@ ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc) unsigned char ipout[32]; char *iptmp = NULL, *p; int iplen1, iplen2; + p = strchr(ipasc, '/'); - if (!p) + if (p == NULL) return NULL; iptmp = OPENSSL_strdup(ipasc); - if (!iptmp) + if (iptmp == NULL) return NULL; p = iptmp + (p - ipasc); *p++ = 0; - iplen1 = a2i_ipadd(ipout, iptmp); + iplen1 = ossl_a2i_ipadd(ipout, iptmp); if (!iplen1) goto err; - iplen2 = a2i_ipadd(ipout + iplen1, p); + iplen2 = ossl_a2i_ipadd(ipout + iplen1, p); OPENSSL_free(iptmp); iptmp = NULL; @@ -1070,7 +1136,7 @@ ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc) return NULL; } -int a2i_ipadd(unsigned char *ipout, const char *ipasc) +int ossl_a2i_ipadd(unsigned char *ipout, const char *ipasc) { /* If string contains a ':' assume IPv6 */ @@ -1119,6 +1185,7 @@ typedef struct { static int ipv6_from_asc(unsigned char *v6, const char *in) { IPV6_STAT v6stat; + v6stat.total = 0; v6stat.zero_pos = -1; v6stat.zero_cnt = 0; @@ -1141,21 +1208,19 @@ static int ipv6_from_asc(unsigned char *v6, const char *in) if (v6stat.total == 16) return 0; /* More than three zeroes is an error */ - if (v6stat.zero_cnt > 3) + if (v6stat.zero_cnt > 3) { return 0; /* Can only have three zeroes if nothing else present */ - else if (v6stat.zero_cnt == 3) { + } else if (v6stat.zero_cnt == 3) { if (v6stat.total > 0) return 0; - } - /* Can only have two zeroes if at start or end */ - else if (v6stat.zero_cnt == 2) { + } else if (v6stat.zero_cnt == 2) { + /* Can only have two zeroes if at start or end */ if ((v6stat.zero_pos != 0) && (v6stat.zero_pos != v6stat.total)) return 0; - } else + } else { /* Can only have one zero if *not* start or end */ - { if ((v6stat.zero_pos == 0) || (v6stat.zero_pos == v6stat.total)) return 0; @@ -1174,8 +1239,9 @@ static int ipv6_from_asc(unsigned char *v6, const char *in) memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, v6stat.tmp + v6stat.zero_pos, v6stat.total - v6stat.zero_pos); - } else + } else { memcpy(v6, v6stat.tmp, 16); + } return 1; } @@ -1183,6 +1249,7 @@ static int ipv6_from_asc(unsigned char *v6, const char *in) static int ipv6_cb(const char *elem, int len, void *usr) { IPV6_STAT *s = usr; + /* Error if 16 bytes written */ if (s->total == 16) return 0; @@ -1246,6 +1313,7 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, CONF_VALUE *v; int i, mval, spec_char, plus_char; char *p, *type; + if (!nm) return 0; @@ -1260,7 +1328,7 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, spec_char = ((*p == ':') || (*p == ',') || (*p == '.')); #else spec_char = ((*p == os_toascii[':']) || (*p == os_toascii[',']) - || (*p == os_toascii['.'])); + || (*p == os_toascii['.'])); #endif if (spec_char) { p++; @@ -1277,8 +1345,9 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, if (plus_char) { mval = -1; type++; - } else + } else { mval = 0; + } if (!X509_NAME_add_entry_by_txt(nm, type, chtype, (unsigned char *)v->value, -1, -1, mval)) diff --git a/crypto/openssl/crypto/x509v3/v3err.c b/crypto/openssl/crypto/x509/v3err.c similarity index 50% rename from crypto/openssl/crypto/x509v3/v3err.c rename to crypto/openssl/crypto/x509/v3err.c index 8b2918a64fff..6f38034c1afe 100644 --- a/crypto/openssl/crypto/x509v3/v3err.c +++ b/crypto/openssl/crypto/x509/v3err.c @@ -2,7 +2,7 @@ * Generated by util/mkerr.pl DO NOT EDIT * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,127 +10,10 @@ #include #include +#include "crypto/x509v3err.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA X509V3_str_functs[] = { - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_A2I_GENERAL_NAME, 0), - "a2i_GENERAL_NAME"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_ADDR_VALIDATE_PATH_INTERNAL, 0), - "addr_validate_path_internal"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, 0), - "ASIdentifierChoice_canonize"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, 0), - "ASIdentifierChoice_is_canonical"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_BIGNUM_TO_STRING, 0), - "bignum_to_string"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_COPY_EMAIL, 0), "copy_email"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_COPY_ISSUER, 0), "copy_issuer"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_DO_DIRNAME, 0), "do_dirname"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_DO_EXT_I2D, 0), "do_ext_i2d"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_DO_EXT_NCONF, 0), "do_ext_nconf"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_GNAMES_FROM_SECTNAME, 0), - "gnames_from_sectname"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2S_ASN1_ENUMERATED, 0), - "i2s_ASN1_ENUMERATED"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2S_ASN1_IA5STRING, 0), - "i2s_ASN1_IA5STRING"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2S_ASN1_INTEGER, 0), - "i2s_ASN1_INTEGER"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2V_AUTHORITY_INFO_ACCESS, 0), - "i2v_AUTHORITY_INFO_ACCESS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2V_AUTHORITY_KEYID, 0), - "i2v_AUTHORITY_KEYID"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_LEVEL_ADD_NODE, 0), "level_add_node"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_NOTICE_SECTION, 0), "notice_section"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_NREF_NOS, 0), "nref_nos"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_POLICY_CACHE_CREATE, 0), - "policy_cache_create"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_POLICY_CACHE_NEW, 0), - "policy_cache_new"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_POLICY_DATA_NEW, 0), "policy_data_new"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_POLICY_SECTION, 0), "policy_section"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_PROCESS_PCI_VALUE, 0), - "process_pci_value"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_R2I_CERTPOL, 0), "r2i_certpol"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_R2I_PCI, 0), "r2i_pci"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_ASN1_IA5STRING, 0), - "s2i_ASN1_IA5STRING"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_ASN1_INTEGER, 0), - "s2i_ASN1_INTEGER"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_ASN1_OCTET_STRING, 0), - "s2i_ASN1_OCTET_STRING"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_SKEY_ID, 0), "s2i_skey_id"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SET_DIST_POINT_NAME, 0), - "set_dist_point_name"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SXNET_ADD_ID_ASC, 0), - "SXNET_add_id_asc"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SXNET_ADD_ID_INTEGER, 0), - "SXNET_add_id_INTEGER"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SXNET_ADD_ID_ULONG, 0), - "SXNET_add_id_ulong"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SXNET_GET_ID_ASC, 0), - "SXNET_get_id_asc"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SXNET_GET_ID_ULONG, 0), - "SXNET_get_id_ulong"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_TREE_INIT, 0), "tree_init"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_ASIDENTIFIERS, 0), - "v2i_ASIdentifiers"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_ASN1_BIT_STRING, 0), - "v2i_ASN1_BIT_STRING"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_AUTHORITY_INFO_ACCESS, 0), - "v2i_AUTHORITY_INFO_ACCESS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_AUTHORITY_KEYID, 0), - "v2i_AUTHORITY_KEYID"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_BASIC_CONSTRAINTS, 0), - "v2i_BASIC_CONSTRAINTS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_CRLD, 0), "v2i_crld"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_EXTENDED_KEY_USAGE, 0), - "v2i_EXTENDED_KEY_USAGE"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_GENERAL_NAMES, 0), - "v2i_GENERAL_NAMES"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_GENERAL_NAME_EX, 0), - "v2i_GENERAL_NAME_ex"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_IDP, 0), "v2i_idp"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_IPADDRBLOCKS, 0), - "v2i_IPAddrBlocks"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_ISSUER_ALT, 0), "v2i_issuer_alt"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_NAME_CONSTRAINTS, 0), - "v2i_NAME_CONSTRAINTS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_POLICY_CONSTRAINTS, 0), - "v2i_POLICY_CONSTRAINTS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_POLICY_MAPPINGS, 0), - "v2i_POLICY_MAPPINGS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_SUBJECT_ALT, 0), "v2i_subject_alt"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V2I_TLS_FEATURE, 0), "v2i_TLS_FEATURE"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_V3_GENERIC_EXTENSION, 0), - "v3_generic_extension"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_ADD1_I2D, 0), "X509V3_add1_i2d"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_ADD_LEN_VALUE, 0), - "x509v3_add_len_value"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_ADD_VALUE, 0), - "X509V3_add_value"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_EXT_ADD, 0), "X509V3_EXT_add"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_EXT_ADD_ALIAS, 0), - "X509V3_EXT_add_alias"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_EXT_I2D, 0), "X509V3_EXT_i2d"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_EXT_NCONF, 0), - "X509V3_EXT_nconf"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_GET_SECTION, 0), - "X509V3_get_section"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_GET_STRING, 0), - "X509V3_get_string"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_GET_VALUE_BOOL, 0), - "X509V3_get_value_bool"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509V3_PARSE_LIST, 0), - "X509V3_parse_list"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509_PURPOSE_ADD, 0), - "X509_PURPOSE_add"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_X509_PURPOSE_SET, 0), - "X509_PURPOSE_set"}, - {0, NULL} -}; - static const ERR_STRING_DATA X509V3_str_reasons[] = { {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_IP_ADDRESS), "bad ip address"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_OBJECT), "bad object"}, @@ -142,6 +25,7 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = { "distpoint already set"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_DUPLICATE_ZONE_ID), "duplicate zone id"}, + {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_EMPTY_KEY_USAGE), "empty key usage"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ERROR_CREATING_EXTENSION), @@ -169,6 +53,10 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = { {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_ASRANGE), "invalid asrange"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"}, + {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_CERTIFICATE), + "invalid certificate"}, + {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_EMPTY_NAME), + "invalid empty name"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_EXTENSION_STRING), "invalid extension string"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_INHERITANCE), @@ -180,8 +68,6 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = { {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_NAME), "invalid name"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, - {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_NULL_NAME), - "invalid null name"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_NULL_VALUE), "invalid null value"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_NUMBER), "invalid number"}, @@ -202,6 +88,8 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = { {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_MISSING_VALUE), "missing value"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS), "need organization and numbers"}, + {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NEGATIVE_PATHLEN), + "negative pathlen"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_CONFIG_DATABASE), "no config database"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_ISSUER_CERTIFICATE), @@ -249,13 +137,11 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = { #endif -int ERR_load_X509V3_strings(void) +int ossl_err_load_X509V3_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) { - ERR_load_strings_const(X509V3_str_functs); + if (ERR_reason_error_string(X509V3_str_reasons[0].error) == NULL) ERR_load_strings_const(X509V3_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/x509/x509_att.c b/crypto/openssl/crypto/x509/x509_att.c index cc9f9d19099d..73ac59454d1f 100644 --- a/crypto/openssl/crypto/x509/x509_att.c +++ b/crypto/openssl/crypto/x509/x509_att.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -15,6 +15,7 @@ #include #include #include +#include "crypto/x509.h" #include "x509_local.h" int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) @@ -77,15 +78,16 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, STACK_OF(X509_ATTRIBUTE) *sk = NULL; if (x == NULL) { - X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER); - goto err2; + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return NULL; } if (*x == NULL) { if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) goto err; - } else + } else { sk = *x; + } if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) goto err2; @@ -95,10 +97,11 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, *x = sk; return sk; err: - X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); err2: X509_ATTRIBUTE_free(new_attr); - sk_X509_ATTRIBUTE_free(sk); + if (*x == NULL) + sk_X509_ATTRIBUTE_free(sk); return NULL; } @@ -165,6 +168,23 @@ void *X509at_get0_data_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *x, return X509_ATTRIBUTE_get0_data(at, 0, type, NULL); } +STACK_OF(X509_ATTRIBUTE) *ossl_x509at_dup(const STACK_OF(X509_ATTRIBUTE) *x) +{ + int i, n; + STACK_OF(X509_ATTRIBUTE) *sk = NULL; + + n = sk_X509_ATTRIBUTE_num(x); + for (i = 0; i < n; ++i) { + X509_ATTRIBUTE *attr = sk_X509_ATTRIBUTE_value(x, i); + + if (X509at_add1_attr(&sk, attr) == NULL) { + sk_X509_ATTRIBUTE_pop_free(sk, X509_ATTRIBUTE_free); + return NULL; + } + } + return sk; +} + X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, int atrtype, const void *data, int len) @@ -174,7 +194,7 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, obj = OBJ_nid2obj(nid); if (obj == NULL) { - X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID, X509_R_UNKNOWN_NID); + ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_NID); return NULL; } ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len); @@ -192,8 +212,7 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, if ((attr == NULL) || (*attr == NULL)) { if ((ret = X509_ATTRIBUTE_new()) == NULL) { - X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } } else @@ -223,9 +242,8 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, obj = OBJ_txt2obj(atrname, 0); if (obj == NULL) { - X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT, - X509_R_INVALID_FIELD_NAME); - ERR_add_error_data(2, "name=", atrname); + ERR_raise_data(ERR_LIB_X509, X509_R_INVALID_FIELD_NAME, + "name=%s", atrname); return NULL; } nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len); @@ -254,7 +272,7 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, OBJ_obj2nid(attr->object)); if (!stmp) { - X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); return 0; } atype = stmp->type; @@ -287,7 +305,7 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, goto err; return 1; err: - X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); ASN1_TYPE_free(ttmp); ASN1_STRING_free(stmp); return 0; @@ -317,7 +335,7 @@ void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, 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); + ERR_raise(ERR_LIB_X509, X509_R_WRONG_TYPE); return NULL; } return ttmp->value.ptr; diff --git a/crypto/openssl/crypto/x509/x509_cmp.c b/crypto/openssl/crypto/x509/x509_cmp.c index 3724a118f343..5c9d91f4073d 100644 --- a/crypto/openssl/crypto/x509/x509_cmp.c +++ b/crypto/openssl/crypto/x509/x509_cmp.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,6 +13,7 @@ #include #include #include +#include #include "crypto/x509.h" int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) @@ -20,11 +21,15 @@ int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) int i; const X509_CINF *ai, *bi; + if (b == NULL) + return a != NULL; + if (a == NULL) + return -1; ai = &a->cert_info; bi = &b->cert_info; i = ASN1_INTEGER_cmp(&ai->serialNumber, &bi->serialNumber); - if (i) - return i; + if (i != 0) + return i < 0 ? -1 : 1; return X509_NAME_cmp(ai->issuer, bi->issuer); } @@ -35,13 +40,18 @@ unsigned long X509_issuer_and_serial_hash(X509 *a) EVP_MD_CTX *ctx = EVP_MD_CTX_new(); unsigned char md[16]; char *f = NULL; + EVP_MD *digest = NULL; if (ctx == NULL) goto err; f = X509_NAME_oneline(a->cert_info.issuer, NULL, 0); if (f == NULL) goto err; - if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL)) + digest = EVP_MD_fetch(a->libctx, SN_md5, a->propq); + if (digest == NULL) + goto err; + + if (!EVP_DigestInit_ex(ctx, digest, NULL)) goto err; if (!EVP_DigestUpdate(ctx, (unsigned char *)f, strlen(f))) goto err; @@ -56,6 +66,7 @@ unsigned long X509_issuer_and_serial_hash(X509 *a) ) & 0xffffffffL; err: OPENSSL_free(f); + EVP_MD_free(digest); EVP_MD_CTX_free(ctx); return ret; } @@ -78,7 +89,15 @@ int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) { - return memcmp(a->sha1_hash, b->sha1_hash, 20); + int rv; + + if ((a->flags & EXFLAG_NO_FINGERPRINT) == 0 + && (b->flags & EXFLAG_NO_FINGERPRINT) == 0) + rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); + else + return -2; + + return rv < 0 ? -1 : rv > 0; } X509_NAME *X509_get_issuer_name(const X509 *a) @@ -88,7 +107,7 @@ X509_NAME *X509_get_issuer_name(const X509 *a) unsigned long X509_issuer_name_hash(X509 *x) { - return X509_NAME_hash(x->cert_info.issuer); + return X509_NAME_hash_ex(x->cert_info.issuer, NULL, NULL, NULL); } #ifndef OPENSSL_NO_MD5 @@ -115,7 +134,7 @@ const ASN1_INTEGER *X509_get0_serialNumber(const X509 *a) unsigned long X509_subject_name_hash(X509 *x) { - return X509_NAME_hash(x->cert_info.subject); + return X509_NAME_hash_ex(x->cert_info.subject, NULL, NULL, NULL); } #ifndef OPENSSL_NO_MD5 @@ -140,7 +159,7 @@ int X509_cmp(const X509 *a, const X509 *b) if (a == b) /* for efficiency */ return 0; - /* try to make sure hash is valid */ + /* attempt to compute cert hash */ (void)X509_check_purpose((X509 *)a, -1, 0); (void)X509_check_purpose((X509 *)b, -1, 0); @@ -148,7 +167,7 @@ int X509_cmp(const X509 *a, const X509 *b) && (b->ex_flags & EXFLAG_NO_FINGERPRINT) == 0) rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); if (rv != 0) - return rv; + return rv < 0 ? -1 : 1; /* Check for match against stored encoding too */ if (!a->cert_info.enc.modified && !b->cert_info.enc.modified) { @@ -156,53 +175,137 @@ int X509_cmp(const X509 *a, const X509 *b) return -1; if (a->cert_info.enc.len > b->cert_info.enc.len) return 1; - return memcmp(a->cert_info.enc.enc, b->cert_info.enc.enc, - a->cert_info.enc.len); + rv = memcmp(a->cert_info.enc.enc, + b->cert_info.enc.enc, a->cert_info.enc.len); } - return rv; + return rv < 0 ? -1 : rv > 0; +} + +int ossl_x509_add_cert_new(STACK_OF(X509) **p_sk, X509 *cert, int flags) +{ + if (*p_sk == NULL && (*p_sk = sk_X509_new_null()) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + return 0; + } + return X509_add_cert(*p_sk, cert, flags); +} + +int X509_add_cert(STACK_OF(X509) *sk, X509 *cert, int flags) +{ + if (sk == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if ((flags & X509_ADD_FLAG_NO_DUP) != 0) { + /* + * not using sk_X509_set_cmp_func() and sk_X509_find() + * because this re-orders the certs on the stack + */ + int i; + + for (i = 0; i < sk_X509_num(sk); i++) { + if (X509_cmp(sk_X509_value(sk, i), cert) == 0) + return 1; + } + } + if ((flags & X509_ADD_FLAG_NO_SS) != 0) { + int ret = X509_self_signed(cert, 0); + + if (ret != 0) + return ret > 0 ? 1 : 0; + } + if (!sk_X509_insert(sk, cert, + (flags & X509_ADD_FLAG_PREPEND) != 0 ? 0 : -1)) { + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + return 0; + } + if ((flags & X509_ADD_FLAG_UP_REF) != 0) + (void)X509_up_ref(cert); + return 1; +} + +int X509_add_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, int flags) +/* compiler would allow 'const' for the certs, yet they may get up-ref'ed */ +{ + if (sk == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return ossl_x509_add_certs_new(&sk, certs, flags); +} + +int ossl_x509_add_certs_new(STACK_OF(X509) **p_sk, STACK_OF(X509) *certs, + int flags) +/* compiler would allow 'const' for the certs, yet they may get up-ref'ed */ +{ + int n = sk_X509_num(certs /* may be NULL */); + int i; + + for (i = 0; i < n; i++) { + int j = (flags & X509_ADD_FLAG_PREPEND) == 0 ? i : n - 1 - i; + /* if prepend, add certs in reverse order to keep original order */ + + if (!ossl_x509_add_cert_new(p_sk, sk_X509_value(certs, j), flags)) + return 0; + } + return 1; } int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) { int ret; - /* Ensure canonical encoding is present and up to date */ + if (b == NULL) + return a != NULL; + if (a == NULL) + return -1; - if (!a->canon_enc || a->modified) { + /* Ensure canonical encoding is present and up to date */ + if (a->canon_enc == NULL || a->modified) { ret = i2d_X509_NAME((X509_NAME *)a, NULL); if (ret < 0) return -2; } - if (!b->canon_enc || b->modified) { + if (b->canon_enc == NULL || b->modified) { ret = i2d_X509_NAME((X509_NAME *)b, NULL); if (ret < 0) return -2; } ret = a->canon_enclen - b->canon_enclen; + if (ret == 0 && a->canon_enclen == 0) + return 0; - if (ret != 0 || a->canon_enclen == 0) - return ret; + if (a->canon_enc == NULL || b->canon_enc == NULL) + return -2; - return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); + if (ret == 0) + ret = memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); + return ret < 0 ? -1 : ret > 0; } -unsigned long X509_NAME_hash(X509_NAME *x) +unsigned long X509_NAME_hash_ex(const X509_NAME *x, OSSL_LIB_CTX *libctx, + const char *propq, int *ok) { unsigned long ret = 0; unsigned char md[SHA_DIGEST_LENGTH]; + EVP_MD *sha1 = EVP_MD_fetch(libctx, "SHA1", propq); /* Make sure X509_NAME structure contains valid cached encoding */ i2d_X509_NAME(x, NULL); - if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), - NULL)) - return 0; - - ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | - ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) - ) & 0xffffffffL; + if (ok != NULL) + *ok = 0; + if (sha1 != NULL + && EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, sha1, NULL)) { + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) + ) & 0xffffffffL; + if (ok != NULL) + *ok = 1; + } + EVP_MD_free(sha1); return ret; } @@ -211,34 +314,36 @@ unsigned long X509_NAME_hash(X509_NAME *x) * I now DER encode the name and hash it. Since I cache the DER encoding, * this is reasonably efficient. */ - -unsigned long X509_NAME_hash_old(X509_NAME *x) +unsigned long X509_NAME_hash_old(const X509_NAME *x) { + EVP_MD *md5 = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_MD5, "-fips"); EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); unsigned long ret = 0; unsigned char md[16]; - if (md_ctx == NULL) - return ret; + if (md5 == NULL || md_ctx == NULL) + goto end; /* Make sure X509_NAME structure contains valid cached encoding */ i2d_X509_NAME(x, NULL); - EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - if (EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL) + if (EVP_DigestInit_ex(md_ctx, md5, NULL) && EVP_DigestUpdate(md_ctx, x->bytes->data, x->bytes->length) && EVP_DigestFinal_ex(md_ctx, md, NULL)) ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) ) & 0xffffffffL; + + end: EVP_MD_CTX_free(md_ctx); + EVP_MD_free(md5); return ret; } #endif /* Search a stack of X509 for a match */ -X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, - ASN1_INTEGER *serial) +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, const X509_NAME *name, + const ASN1_INTEGER *serial) { int i; X509 x, *x509 = NULL; @@ -247,7 +352,7 @@ X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, return NULL; x.cert_info.serialNumber = *serial; - x.cert_info.issuer = name; + x.cert_info.issuer = (X509_NAME *)name; /* won't modify it */ for (i = 0; i < sk_X509_num(sk); i++) { x509 = sk_X509_value(sk, i); @@ -257,7 +362,7 @@ X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, return NULL; } -X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) +X509 *X509_find_by_subject(STACK_OF(X509) *sk, const X509_NAME *name) { X509 *x509; int i; @@ -290,27 +395,24 @@ int X509_check_private_key(const X509 *x, const EVP_PKEY *k) int ret; xk = X509_get0_pubkey(x); + if (xk == NULL) { + ERR_raise(ERR_LIB_X509, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); + return 0; + } - if (xk) - ret = EVP_PKEY_cmp(xk, k); - else - ret = -2; - - switch (ret) { - case 1: - break; + switch (ret = EVP_PKEY_eq(xk, k)) { case 0: - X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH); + ERR_raise(ERR_LIB_X509, X509_R_KEY_VALUES_MISMATCH); break; case -1: - X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); + ERR_raise(ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH); break; case -2: - X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); + ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_KEY_TYPE); + break; } - if (ret > 0) - return 1; - return 0; + + return ret > 0; } /* @@ -323,13 +425,18 @@ int X509_check_private_key(const X509 *x, const EVP_PKEY *k) static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags) { - const EC_GROUP *grp = NULL; + char curve_name[80]; + size_t curve_name_len; int curve_nid; - if (pkey && EVP_PKEY_id(pkey) == EVP_PKEY_EC) - grp = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey)); - if (!grp) + + if (pkey == NULL || !EVP_PKEY_is_a(pkey, "EC")) return X509_V_ERR_SUITE_B_INVALID_ALGORITHM; - curve_nid = EC_GROUP_get_curve_name(grp); + + if (!EVP_PKEY_get_group_name(pkey, curve_name, sizeof(curve_name), + &curve_name_len)) + return X509_V_ERR_SUITE_B_INVALID_CURVE; + + curve_nid = OBJ_txt2nid(curve_name); /* Check curve is consistent with LOS */ if (curve_nid == NID_secp384r1) { /* P-384 */ /* @@ -346,9 +453,9 @@ static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags) return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY)) return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; - } else + } else { return X509_V_ERR_SUITE_B_INVALID_CURVE; - + } return X509_V_OK; } @@ -366,9 +473,9 @@ int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, if (x == NULL) { x = sk_X509_value(chain, 0); i = 1; - } else + } else { i = 0; - + } pk = X509_get0_pubkey(x); /* @@ -380,7 +487,7 @@ int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, if (chain == NULL) return check_suite_b(pk, -1, &tflags); - if (X509_get_version(x) != 2) { + if (X509_get_version(x) != X509_VERSION_3) { rv = X509_V_ERR_SUITE_B_INVALID_VERSION; /* Correct error depth */ i = 0; @@ -397,7 +504,7 @@ int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, for (; i < sk_X509_num(chain); i++) { sign_nid = X509_get_signature_nid(x); x = sk_X509_value(chain, i); - if (X509_get_version(x) != 2) { + if (X509_get_version(x) != X509_VERSION_3) { rv = X509_V_ERR_SUITE_B_INVALID_VERSION; goto end; } @@ -449,6 +556,7 @@ int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) } #endif + /* * Not strictly speaking an "up_ref" as a STACK doesn't have a reference * count but it has the same effect by duping the STACK and upping the ref of @@ -456,20 +564,22 @@ int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) */ STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain) { - STACK_OF(X509) *ret; + STACK_OF(X509) *ret = sk_X509_dup(chain); 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); + if (!X509_up_ref(x)) goto err; } return ret; + err: while (i-- > 0) - X509_free (sk_X509_value(ret, i)); + X509_free(sk_X509_value(ret, i)); sk_X509_free(ret); return NULL; } diff --git a/crypto/openssl/crypto/x509/x509_d2.c b/crypto/openssl/crypto/x509/x509_d2.c index 099ffda1e15c..62aceb7acade 100644 --- a/crypto/openssl/crypto/x509/x509_d2.c +++ b/crypto/openssl/crypto/x509/x509_d2.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -12,46 +12,100 @@ #include #include -int X509_STORE_set_default_paths(X509_STORE *ctx) +int X509_STORE_set_default_paths_ex(X509_STORE *ctx, OSSL_LIB_CTX *libctx, + const char *propq) { X509_LOOKUP *lookup; lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); if (lookup == NULL) return 0; - X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT, libctx, propq); lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); if (lookup == NULL) return 0; X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_store()); + if (lookup == NULL) + return 0; + X509_LOOKUP_add_store_ex(lookup, NULL, libctx, propq); + /* clear any errors */ ERR_clear_error(); return 1; } +int X509_STORE_set_default_paths(X509_STORE *ctx) +{ + return X509_STORE_set_default_paths_ex(ctx, NULL, NULL); +} -int X509_STORE_load_locations(X509_STORE *ctx, const char *file, - const char *path) +int X509_STORE_load_file_ex(X509_STORE *ctx, const char *file, + OSSL_LIB_CTX *libctx, const char *propq) +{ + X509_LOOKUP *lookup; + + if (file == NULL + || (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file())) == NULL + || X509_LOOKUP_load_file_ex(lookup, file, X509_FILETYPE_PEM, libctx, + propq) <= 0) + return 0; + + return 1; +} + +int X509_STORE_load_file(X509_STORE *ctx, const char *file) +{ + return X509_STORE_load_file_ex(ctx, file, NULL, NULL); +} + +int X509_STORE_load_path(X509_STORE *ctx, const char *path) +{ + X509_LOOKUP *lookup; + + if (path == NULL + || (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir())) == NULL + || X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) <= 0) + return 0; + + return 1; +} + +int X509_STORE_load_store_ex(X509_STORE *ctx, const char *uri, + OSSL_LIB_CTX *libctx, const char *propq) { X509_LOOKUP *lookup; - if (file != NULL) { - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); - if (lookup == NULL) - return 0; - if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) - return 0; - } - if (path != NULL) { - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); - if (lookup == NULL) - return 0; - if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) - return 0; - } - if ((path == NULL) && (file == NULL)) + if (uri == NULL + || (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_store())) == NULL + || X509_LOOKUP_add_store_ex(lookup, uri, libctx, propq) == 0) + return 0; + + return 1; +} + +int X509_STORE_load_store(X509_STORE *ctx, const char *uri) +{ + return X509_STORE_load_store_ex(ctx, uri, NULL, NULL); +} + +int X509_STORE_load_locations_ex(X509_STORE *ctx, const char *file, + const char *path, OSSL_LIB_CTX *libctx, + const char *propq) +{ + if (file == NULL && path == NULL) + return 0; + if (file != NULL && !X509_STORE_load_file_ex(ctx, file, libctx, propq)) + return 0; + if (path != NULL && !X509_STORE_load_path(ctx, path)) return 0; return 1; } + +int X509_STORE_load_locations(X509_STORE *ctx, const char *file, + const char *path) +{ + return X509_STORE_load_locations_ex(ctx, file, path, NULL, NULL); +} diff --git a/crypto/openssl/crypto/x509/x509_def.c b/crypto/openssl/crypto/x509/x509_def.c index bfa8d7d8522a..b8bdcb484195 100644 --- a/crypto/openssl/crypto/x509/x509_def.c +++ b/crypto/openssl/crypto/x509/x509_def.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/x509/x509_err.c b/crypto/openssl/crypto/x509/x509_err.c index bdd1e67cd3fd..a933aeef351f 100644 --- a/crypto/openssl/crypto/x509/x509_err.c +++ b/crypto/openssl/crypto/x509/x509_err.c @@ -1,8 +1,8 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -10,107 +10,10 @@ #include #include +#include "crypto/x509err.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA X509_str_functs[] = { - {ERR_PACK(ERR_LIB_X509, X509_F_ADD_CERT_DIR, 0), "add_cert_dir"}, - {ERR_PACK(ERR_LIB_X509, X509_F_BUILD_CHAIN, 0), "build_chain"}, - {ERR_PACK(ERR_LIB_X509, X509_F_BY_FILE_CTRL, 0), "by_file_ctrl"}, - {ERR_PACK(ERR_LIB_X509, X509_F_CHECK_NAME_CONSTRAINTS, 0), - "check_name_constraints"}, - {ERR_PACK(ERR_LIB_X509, X509_F_CHECK_POLICY, 0), "check_policy"}, - {ERR_PACK(ERR_LIB_X509, X509_F_DANE_I2D, 0), "dane_i2d"}, - {ERR_PACK(ERR_LIB_X509, X509_F_DIR_CTRL, 0), "dir_ctrl"}, - {ERR_PACK(ERR_LIB_X509, X509_F_GET_CERT_BY_SUBJECT, 0), - "get_cert_by_subject"}, - {ERR_PACK(ERR_LIB_X509, X509_F_I2D_X509_AUX, 0), "i2d_X509_AUX"}, - {ERR_PACK(ERR_LIB_X509, X509_F_LOOKUP_CERTS_SK, 0), "lookup_certs_sk"}, - {ERR_PACK(ERR_LIB_X509, X509_F_NETSCAPE_SPKI_B64_DECODE, 0), - "NETSCAPE_SPKI_b64_decode"}, - {ERR_PACK(ERR_LIB_X509, X509_F_NETSCAPE_SPKI_B64_ENCODE, 0), - "NETSCAPE_SPKI_b64_encode"}, - {ERR_PACK(ERR_LIB_X509, X509_F_NEW_DIR, 0), "new_dir"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509AT_ADD1_ATTR, 0), "X509at_add1_attr"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509V3_ADD_EXT, 0), "X509v3_add_ext"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_CREATE_BY_NID, 0), - "X509_ATTRIBUTE_create_by_NID"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ, 0), - "X509_ATTRIBUTE_create_by_OBJ"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_CREATE_BY_TXT, 0), - "X509_ATTRIBUTE_create_by_txt"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_GET0_DATA, 0), - "X509_ATTRIBUTE_get0_data"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_SET1_DATA, 0), - "X509_ATTRIBUTE_set1_data"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_CHECK_PRIVATE_KEY, 0), - "X509_check_private_key"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_CRL_DIFF, 0), "X509_CRL_diff"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_CRL_METHOD_NEW, 0), - "X509_CRL_METHOD_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_CRL_PRINT_FP, 0), "X509_CRL_print_fp"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_EXTENSION_CREATE_BY_NID, 0), - "X509_EXTENSION_create_by_NID"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_EXTENSION_CREATE_BY_OBJ, 0), - "X509_EXTENSION_create_by_OBJ"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_GET_PUBKEY_PARAMETERS, 0), - "X509_get_pubkey_parameters"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOAD_CERT_CRL_FILE, 0), - "X509_load_cert_crl_file"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOAD_CERT_FILE, 0), - "X509_load_cert_file"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOAD_CRL_FILE, 0), - "X509_load_crl_file"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOOKUP_METH_NEW, 0), - "X509_LOOKUP_meth_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOOKUP_NEW, 0), "X509_LOOKUP_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ADD_ENTRY, 0), - "X509_NAME_add_entry"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_CANON, 0), "x509_name_canon"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ENTRY_CREATE_BY_NID, 0), - "X509_NAME_ENTRY_create_by_NID"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ENTRY_CREATE_BY_TXT, 0), - "X509_NAME_ENTRY_create_by_txt"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ENTRY_SET_OBJECT, 0), - "X509_NAME_ENTRY_set_object"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ONELINE, 0), "X509_NAME_oneline"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_PRINT, 0), "X509_NAME_print"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_OBJECT_NEW, 0), "X509_OBJECT_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_PRINT_EX_FP, 0), "X509_print_ex_fp"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_PUBKEY_DECODE, 0), - "x509_pubkey_decode"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_PUBKEY_GET, 0), "X509_PUBKEY_get"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_PUBKEY_GET0, 0), "X509_PUBKEY_get0"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_PUBKEY_SET, 0), "X509_PUBKEY_set"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_CHECK_PRIVATE_KEY, 0), - "X509_REQ_check_private_key"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_EX, 0), "X509_REQ_print_ex"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_FP, 0), "X509_REQ_print_fp"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_TO_X509, 0), "X509_REQ_to_X509"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CERT, 0), - "X509_STORE_add_cert"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CRL, 0), - "X509_STORE_add_crl"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_LOOKUP, 0), - "X509_STORE_add_lookup"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_GET1_ISSUER, 0), - "X509_STORE_CTX_get1_issuer"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_INIT, 0), - "X509_STORE_CTX_init"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_NEW, 0), - "X509_STORE_CTX_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_PURPOSE_INHERIT, 0), - "X509_STORE_CTX_purpose_inherit"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_NEW, 0), "X509_STORE_new"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_TO_X509_REQ, 0), "X509_to_X509_REQ"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_TRUST_ADD, 0), "X509_TRUST_add"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_TRUST_SET, 0), "X509_TRUST_set"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, 0), "X509_verify_cert"}, - {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_PARAM_NEW, 0), - "X509_VERIFY_PARAM_new"}, - {0, NULL} -}; - static const ERR_STRING_DATA X509_str_reasons[] = { {ERR_PACK(ERR_LIB_X509, 0, X509_R_AKID_MISMATCH), "akid mismatch"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_BAD_SELECTOR), "bad selector"}, @@ -118,15 +21,22 @@ static const ERR_STRING_DATA X509_str_reasons[] = { {ERR_PACK(ERR_LIB_X509, 0, X509_R_BASE64_DECODE_ERROR), "base64 decode error"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_CANT_CHECK_DH_KEY), "cant check dh key"}, + {ERR_PACK(ERR_LIB_X509, 0, X509_R_CERTIFICATE_VERIFICATION_FAILED), + "certificate verification failed"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_CERT_ALREADY_IN_HASH_TABLE), "cert already in hash table"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_ALREADY_DELTA), "crl already delta"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE), "crl verify failure"}, + {ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_GETTING_MD_BY_NID), + "error getting md by nid"}, + {ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_USING_SIGINF_SET), + "error using siginf set"}, {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_DISTPOINT), "invalid distpoint"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_FIELD_NAME), "invalid field name"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_TRUST), "invalid trust"}, @@ -162,6 +72,8 @@ static const ERR_STRING_DATA X509_str_reasons[] = { {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_NID), "unknown nid"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_PURPOSE_ID), "unknown purpose id"}, + {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_SIGID_ALGS), + "unknown sigid algs"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_TRUST_ID), "unknown trust id"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, @@ -172,13 +84,11 @@ static const ERR_STRING_DATA X509_str_reasons[] = { #endif -int ERR_load_X509_strings(void) +int ossl_err_load_X509_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(X509_str_functs[0].error) == NULL) { - ERR_load_strings_const(X509_str_functs); + if (ERR_reason_error_string(X509_str_reasons[0].error) == NULL) ERR_load_strings_const(X509_str_reasons); - } #endif return 1; } diff --git a/crypto/openssl/crypto/x509/x509_ext.c b/crypto/openssl/crypto/x509/x509_ext.c index 4cdab724eadf..a7b85857bdad 100644 --- a/crypto/openssl/crypto/x509/x509_ext.c +++ b/crypto/openssl/crypto/x509/x509_ext.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/x509/x509_local.h b/crypto/openssl/crypto/x509/x509_local.h index 10807e1def04..6d602e1d8ef5 100644 --- a/crypto/openssl/crypto/x509/x509_local.h +++ b/crypto/openssl/crypto/x509/x509_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -9,6 +9,9 @@ #include "internal/refcount.h" +#define X509V3_conf_add_error_name_value(val) \ + ERR_add_error_data(4, "name=", (val)->name, ", value=", (val)->value) + /* * This structure holds all parameters associated with a verify operation by * including an X509_VERIFY_PARAM structure in related structures the @@ -36,7 +39,7 @@ struct X509_VERIFY_PARAM_st { }; /* No error callback if depth < 0 */ -int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth); +int ossl_x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth); /* a sequence of these are used */ struct x509_attributes_st { @@ -64,7 +67,7 @@ struct x509_crl_method_st { int (*crl_init) (X509_CRL *crl); int (*crl_free) (X509_CRL *crl); int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret, - ASN1_INTEGER *ser, X509_NAME *issuer); + const ASN1_INTEGER *ser, const X509_NAME *issuer); int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk); }; @@ -77,15 +80,21 @@ struct x509_lookup_method_st { int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); int (*get_by_subject) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, - X509_NAME *name, X509_OBJECT *ret); + const X509_NAME *name, X509_OBJECT *ret); int (*get_by_issuer_serial) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, - X509_NAME *name, ASN1_INTEGER *serial, + const X509_NAME *name, + const ASN1_INTEGER *serial, X509_OBJECT *ret); int (*get_by_fingerprint) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const unsigned char *bytes, int len, X509_OBJECT *ret); int (*get_by_alias) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const char *str, int len, X509_OBJECT *ret); + int (*get_by_subject_ex) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq); + int (*ctrl_ex) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret, OSSL_LIB_CTX *libctx, const char *propq); }; /* This is the functions plus an instance of the local variables. */ @@ -128,8 +137,11 @@ struct x509_store_st { int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check policy status of the chain */ int (*check_policy) (X509_STORE_CTX *ctx); - STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); - STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, + const X509_NAME *nm); + /* cannot constify 'ctx' param due to lookup_certs_sk() in x509_vfy.c */ + STACK_OF(X509_CRL) *(*lookup_crls) (const X509_STORE_CTX *ctx, + const X509_NAME *nm); int (*cleanup) (X509_STORE_CTX *ctx); CRYPTO_EX_DATA ex_data; CRYPTO_REF_COUNT references; @@ -143,7 +155,5 @@ DEFINE_STACK_OF(BY_DIR_ENTRY) typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY) -void x509_set_signature_info(X509_SIG_INFO *siginf, const X509_ALGOR *alg, - const ASN1_STRING *sig); -int x509_likely_issued(X509 *issuer, X509 *subject); -int x509_signing_allowed(const X509 *issuer, const X509 *subject); +int ossl_x509_likely_issued(X509 *issuer, X509 *subject); +int ossl_x509_signing_allowed(const X509 *issuer, const X509 *subject); diff --git a/crypto/openssl/crypto/x509/x509_lu.c b/crypto/openssl/crypto/x509/x509_lu.c index 641a41c35c78..d8927bda0706 100644 --- a/crypto/openssl/crypto/x509/x509_lu.c +++ b/crypto/openssl/crypto/x509/x509_lu.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -20,7 +20,7 @@ X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) X509_LOOKUP *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - X509err(X509_F_X509_LOOKUP_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } @@ -71,29 +71,49 @@ int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) return 1; } -int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, - char **ret) +int X509_LOOKUP_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret, OSSL_LIB_CTX *libctx, const char *propq) { if (ctx->method == NULL) return -1; + if (ctx->method->ctrl_ex != NULL) + return ctx->method->ctrl_ex(ctx, cmd, argc, argl, ret, libctx, propq); if (ctx->method->ctrl != NULL) return ctx->method->ctrl(ctx, cmd, argc, argl, ret); + return 1; +} + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret) +{ + return X509_LOOKUP_ctrl_ex(ctx, cmd, argc, argl, ret, NULL, NULL); +} + +int X509_LOOKUP_by_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq) +{ + if (ctx->skip + || ctx->method == NULL + || (ctx->method->get_by_subject == NULL + && ctx->method->get_by_subject_ex == NULL)) + return 0; + if (ctx->method->get_by_subject_ex != NULL) + return ctx->method->get_by_subject_ex(ctx, type, name, ret, libctx, + propq); else - return 1; + return ctx->method->get_by_subject(ctx, type, name, ret); } int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, - X509_NAME *name, X509_OBJECT *ret) + const X509_NAME *name, X509_OBJECT *ret) { - if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) - return 0; - if (ctx->skip) - return 0; - return ctx->method->get_by_subject(ctx, type, name, ret); + return X509_LOOKUP_by_subject_ex(ctx, type, name, ret, NULL, NULL); } int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, - X509_NAME *name, ASN1_INTEGER *serial, + const X509_NAME *name, + const ASN1_INTEGER *serial, X509_OBJECT *ret) { if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL)) @@ -162,34 +182,33 @@ X509_STORE *X509_STORE_new(void) X509_STORE *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } ret->cache = 1; if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } - ret->references = 1; return ret; @@ -237,7 +256,7 @@ int X509_STORE_up_ref(X509_STORE *vfy) if (CRYPTO_UP_REF(&vfy->references, &i, vfy->lock) <= 0) return 0; - REF_PRINT_COUNT("X509_STORE", a); + REF_PRINT_COUNT("X509_STORE", vfy); REF_ASSERT_ISNT(i < 2); return ((i > 1) ? 1 : 0); } @@ -258,7 +277,7 @@ X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) /* a new one */ lu = X509_LOOKUP_new(m); if (lu == NULL) { - X509err(X509_F_X509_STORE_ADD_LOOKUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } @@ -266,14 +285,14 @@ X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) return lu; /* malloc failed */ - X509err(X509_F_X509_STORE_ADD_LOOKUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); X509_LOOKUP_free(lu); return NULL; } X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, - X509_NAME *name) + const X509_NAME *name) { X509_OBJECT *ret = X509_OBJECT_new(); @@ -286,10 +305,12 @@ X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, return ret; } -int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, - X509_NAME *name, X509_OBJECT *ret) +/* Also fill the cache with all matching certificates */ +int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs, + X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret) { - X509_STORE *store = vs->ctx; + X509_STORE *store = vs->store; X509_LOOKUP *lu; X509_OBJECT stmp, *tmp; int i, j; @@ -300,15 +321,17 @@ int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, stmp.type = X509_LU_NONE; stmp.data.ptr = NULL; + if (!X509_STORE_lock(store)) + return 0; - 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(store->get_cert_methods); i++) { lu = sk_X509_LOOKUP_value(store->get_cert_methods, i); - j = X509_LOOKUP_by_subject(lu, type, name, &stmp); + j = X509_LOOKUP_by_subject_ex(lu, type, name, &stmp, vs->libctx, + vs->propq); if (j) { tmp = &stmp; break; @@ -350,7 +373,12 @@ static int x509_store_add(X509_STORE *store, void *x, int crl) { return 0; } - X509_STORE_lock(store); + if (!X509_STORE_lock(store)) { + obj->type = X509_LU_NONE; + X509_OBJECT_free(obj); + return 0; + } + if (X509_OBJECT_retrieve_match(store->objs, obj)) { ret = 1; } else { @@ -368,7 +396,7 @@ static int x509_store_add(X509_STORE *store, void *x, int crl) { int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) { if (!x509_store_add(ctx, x, 0)) { - X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -377,7 +405,7 @@ int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) { if (!x509_store_add(ctx, x, 1)) { - X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -403,7 +431,7 @@ X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a) return a->data.x509; } -X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *a) +X509_CRL *X509_OBJECT_get0_X509_CRL(const X509_OBJECT *a) { if (a == NULL || a->type != X509_LU_CRL) return NULL; @@ -420,7 +448,7 @@ X509_OBJECT *X509_OBJECT_new(void) X509_OBJECT *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - X509err(X509_F_X509_OBJECT_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } ret->type = X509_LU_NONE; @@ -472,7 +500,7 @@ void X509_OBJECT_free(X509_OBJECT *a) } static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, - X509_NAME *name, int *pnmatch) + const X509_NAME *name, int *pnmatch) { X509_OBJECT stmp; X509 x509_s; @@ -483,42 +511,30 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, switch (type) { case X509_LU_X509: stmp.data.x509 = &x509_s; - x509_s.cert_info.subject = name; + x509_s.cert_info.subject = (X509_NAME *)name; /* won't modify it */ break; case X509_LU_CRL: stmp.data.crl = &crl_s; - crl_s.crl.issuer = name; + crl_s.crl.issuer = (X509_NAME *)name; /* won't modify it */ break; case X509_LU_NONE: /* abort(); */ return -1; } - idx = sk_X509_OBJECT_find(h, &stmp); - if (idx >= 0 && pnmatch) { - int tidx; - const X509_OBJECT *tobj, *pstmp; - *pnmatch = 1; - pstmp = &stmp; - for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) { - tobj = sk_X509_OBJECT_value(h, tidx); - if (x509_object_cmp(&tobj, &pstmp)) - break; - (*pnmatch)++; - } - } + idx = sk_X509_OBJECT_find_all(h, &stmp, pnmatch); return idx; } int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, - X509_NAME *name) + const X509_NAME *name) { return x509_object_idx_cnt(h, type, name, NULL); } X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, - X509_NAME *name) + const X509_NAME *name) { int idx; idx = X509_OBJECT_idx_by_subject(h, type, name); @@ -527,23 +543,59 @@ X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, return sk_X509_OBJECT_value(h, idx); } -STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v) +STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *v) { return v->objs; } -STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) +STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *store) +{ + STACK_OF(X509) *sk; + STACK_OF(X509_OBJECT) *objs; + int i; + + if (store == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if ((sk = sk_X509_new_null()) == NULL) + return NULL; + if (!X509_STORE_lock(store)) + goto out_free; + + objs = X509_STORE_get0_objects(store); + for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { + X509 *cert = X509_OBJECT_get0_X509(sk_X509_OBJECT_value(objs, i)); + + if (cert != NULL + && !X509_add_cert(sk, cert, X509_ADD_FLAG_UP_REF)) + goto err; + } + X509_STORE_unlock(store); + return sk; + + err: + X509_STORE_unlock(store); + out_free: + sk_X509_pop_free(sk, X509_free); + return NULL; +} + +STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, + const X509_NAME *nm) { int i, idx, cnt; STACK_OF(X509) *sk = NULL; X509 *x; X509_OBJECT *obj; - X509_STORE *store = ctx->ctx; + X509_STORE *store = ctx->store; if (store == NULL) return NULL; - X509_STORE_lock(store); + if (!X509_STORE_lock(store)) + return NULL; + idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt); if (idx < 0) { /* @@ -561,7 +613,8 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) return NULL; } X509_OBJECT_free(xobj); - X509_STORE_lock(store); + if (!X509_STORE_lock(store)) + return NULL; idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt); if (idx < 0) { X509_STORE_unlock(store); @@ -573,29 +626,24 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) for (i = 0; i < cnt; i++, idx++) { obj = sk_X509_OBJECT_value(store->objs, idx); x = obj->data.x509; - if (!X509_up_ref(x)) { + if (!X509_add_cert(sk, x, X509_ADD_FLAG_UP_REF)) { X509_STORE_unlock(store); sk_X509_pop_free(sk, X509_free); return NULL; } - if (!sk_X509_push(sk, x)) { - X509_STORE_unlock(store); - X509_free(x); - sk_X509_pop_free(sk, X509_free); - return NULL; - } } X509_STORE_unlock(store); return sk; } -STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) +STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(const X509_STORE_CTX *ctx, + const X509_NAME *nm) { int i, idx, cnt; 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; + X509_STORE *store = ctx->store; /* Always do lookup to possibly add new CRLs to cache */ if (sk == NULL @@ -607,7 +655,10 @@ STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) return NULL; } X509_OBJECT_free(xobj); - X509_STORE_lock(store); + if (!X509_STORE_lock(store)) { + sk_X509_CRL_free(sk); + return NULL; + } idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, nm, &cnt); if (idx < 0) { X509_STORE_unlock(store); @@ -654,7 +705,7 @@ X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, if (!X509_cmp(obj->data.x509, x->data.x509)) return obj; } else if (x->type == X509_LU_CRL) { - if (!X509_CRL_match(obj->data.crl, x->data.crl)) + if (X509_CRL_match(obj->data.crl, x->data.crl) == 0) return obj; } else return obj; @@ -663,11 +714,8 @@ X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, } /*- - * Try to get issuer certificate from store. Due to limitations - * of the API this can only retrieve a single certificate matching - * a given subject name. However it will fill the cache with all - * matching certificates, so we can examine the cache for all - * matches. + * Try to get issuer cert from |ctx->store| matching the subject name of |x|. + * Prefer the first non-expired one, else take the most recently expired one. * * Return values are: * 1 lookup successful. @@ -676,10 +724,10 @@ X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, */ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { - X509_NAME *xn; + const X509_NAME *xn; X509_OBJECT *obj = X509_OBJECT_new(), *pobj = NULL; - X509_STORE *store = ctx->ctx; - int i, ok, idx, ret; + X509_STORE *store = ctx->store; + int i, ok, idx, ret, nmatch = 0; if (obj == NULL) return -1; @@ -690,53 +738,58 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) X509_OBJECT_free(obj); return 0; } - /* If certificate matches all OK */ + /* If certificate matches and is currently valid all OK */ if (ctx->check_issued(ctx, x, obj->data.x509)) { - if (x509_check_cert_time(ctx, obj->data.x509, -1)) { + if (ossl_x509_check_cert_time(ctx, obj->data.x509, -1)) { *issuer = obj->data.x509; - if (!X509_up_ref(*issuer)) { - *issuer = NULL; - ok = -1; - } + /* |*issuer| has taken over the cert reference from |obj| */ + obj->type = X509_LU_NONE; X509_OBJECT_free(obj); - return ok; + return 1; } } X509_OBJECT_free(obj); + /* + * Due to limitations of the API this can only retrieve a single cert. + * However it will fill the cache with all matching certificates, + * so we can examine the cache for all matches. + */ if (store == NULL) return 0; - /* Else find index of first cert accepted by 'check_issued' */ + /* Find index of first currently valid cert accepted by 'check_issued' */ ret = 0; - 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 */ + if (!X509_STORE_lock(store)) + return 0; + + idx = x509_object_idx_cnt(store->objs, X509_LU_X509, xn, &nmatch); + 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(store->objs); i++) { + for (i = idx; i < idx + nmatch; i++) { pobj = sk_X509_OBJECT_value(store->objs, i); /* See if we've run past the matches */ if (pobj->type != X509_LU_X509) break; - if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) - break; if (ctx->check_issued(ctx, x, pobj->data.x509)) { - *issuer = pobj->data.x509; ret = 1; + /* If times check fine, exit with match, else keep looking. */ + if (ossl_x509_check_cert_time(ctx, pobj->data.x509, -1)) { + *issuer = pobj->data.x509; + break; + } /* - * If times check, exit with match, - * otherwise keep looking. Leave last - * match in issuer so we return nearest - * match if no certificate time is OK. + * Leave the so far most recently expired match in *issuer + * so we return nearest match if no certificate time is OK. */ - - if (x509_check_cert_time(ctx, *issuer, -1)) - break; + if (*issuer == NULL + || ASN1_TIME_compare(X509_get0_notAfter(pobj->data.x509), + X509_get0_notAfter(*issuer)) > 0) + *issuer = pobj->data.x509; } } } - if (*issuer && !X509_up_ref(*issuer)) { + if (*issuer != NULL && !X509_up_ref(*issuer)) { *issuer = NULL; ret = -1; } @@ -765,12 +818,12 @@ int X509_STORE_set_trust(X509_STORE *ctx, int trust) return X509_VERIFY_PARAM_set_trust(ctx->param, trust); } -int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) +int X509_STORE_set1_param(X509_STORE *ctx, const X509_VERIFY_PARAM *param) { return X509_VERIFY_PARAM_set1(ctx->param, param); } -X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) +X509_VERIFY_PARAM *X509_STORE_get0_param(const X509_STORE *ctx) { return ctx->param; } @@ -780,7 +833,7 @@ void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify) ctx->verify = verify; } -X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx) +X509_STORE_CTX_verify_fn X509_STORE_get_verify(const X509_STORE *ctx) { return ctx->verify; } @@ -791,7 +844,7 @@ void X509_STORE_set_verify_cb(X509_STORE *ctx, ctx->verify_cb = verify_cb; } -X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx) +X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(const X509_STORE *ctx) { return ctx->verify_cb; } @@ -802,7 +855,7 @@ void X509_STORE_set_get_issuer(X509_STORE *ctx, ctx->get_issuer = get_issuer; } -X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx) +X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(const X509_STORE *ctx) { return ctx->get_issuer; } @@ -813,7 +866,7 @@ void X509_STORE_set_check_issued(X509_STORE *ctx, ctx->check_issued = check_issued; } -X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx) +X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(const X509_STORE *ctx) { return ctx->check_issued; } @@ -824,7 +877,7 @@ void X509_STORE_set_check_revocation(X509_STORE *ctx, ctx->check_revocation = check_revocation; } -X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx) +X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(const X509_STORE *ctx) { return ctx->check_revocation; } @@ -835,7 +888,7 @@ void X509_STORE_set_get_crl(X509_STORE *ctx, ctx->get_crl = get_crl; } -X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx) +X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(const X509_STORE *ctx) { return ctx->get_crl; } @@ -846,7 +899,7 @@ void X509_STORE_set_check_crl(X509_STORE *ctx, ctx->check_crl = check_crl; } -X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx) +X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(const X509_STORE *ctx) { return ctx->check_crl; } @@ -857,7 +910,7 @@ void X509_STORE_set_cert_crl(X509_STORE *ctx, ctx->cert_crl = cert_crl; } -X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx) +X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(const X509_STORE *ctx) { return ctx->cert_crl; } @@ -868,7 +921,7 @@ void X509_STORE_set_check_policy(X509_STORE *ctx, ctx->check_policy = check_policy; } -X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(X509_STORE *ctx) +X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(const X509_STORE *ctx) { return ctx->check_policy; } @@ -879,7 +932,7 @@ void X509_STORE_set_lookup_certs(X509_STORE *ctx, ctx->lookup_certs = lookup_certs; } -X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx) +X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(const X509_STORE *ctx) { return ctx->lookup_certs; } @@ -890,7 +943,7 @@ void X509_STORE_set_lookup_crls(X509_STORE *ctx, ctx->lookup_crls = lookup_crls; } -X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx) +X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(const X509_STORE *ctx) { return ctx->lookup_crls; } @@ -901,7 +954,7 @@ void X509_STORE_set_cleanup(X509_STORE *ctx, ctx->cleanup = ctx_cleanup; } -X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx) +X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *ctx) { return ctx->cleanup; } @@ -911,12 +964,12 @@ int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data) return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); } -void *X509_STORE_get_ex_data(X509_STORE *ctx, int idx) +void *X509_STORE_get_ex_data(const X509_STORE *ctx, int idx) { return CRYPTO_get_ex_data(&ctx->ex_data, idx); } -X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) +X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx) { - return ctx->ctx; + return ctx->store; } diff --git a/crypto/openssl/crypto/x509/x509_meth.c b/crypto/openssl/crypto/x509/x509_meth.c index 9348cc8eb788..a8eedd9b59af 100644 --- a/crypto/openssl/crypto/x509/x509_meth.c +++ b/crypto/openssl/crypto/x509/x509_meth.c @@ -1,7 +1,7 @@ /* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -14,7 +14,7 @@ #include "internal/cryptlib.h" #include #include -#include +#include #include "x509_local.h" X509_LOOKUP_METHOD *X509_LOOKUP_meth_new(const char *name) @@ -24,7 +24,7 @@ X509_LOOKUP_METHOD *X509_LOOKUP_meth_new(const char *name) if (method != NULL) { method->name = OPENSSL_strdup(name); if (method->name == NULL) { - X509err(X509_F_X509_LOOKUP_METH_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } } diff --git a/crypto/openssl/crypto/x509/x509_obj.c b/crypto/openssl/crypto/x509/x509_obj.c index f54d483cc4dd..12c6d6f78b6e 100644 --- a/crypto/openssl/crypto/x509/x509_obj.c +++ b/crypto/openssl/crypto/x509/x509_obj.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -13,6 +13,7 @@ #include #include #include "crypto/x509.h" +#include "crypto/ctype.h" /* * Limit to ensure we don't overflow: much greater than @@ -26,6 +27,7 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) const X509_NAME_ENTRY *ne; int i; int n, lold, l, l1, l2, num, j, type; + int prev_set = -1; const char *s; char *p; unsigned char *q; @@ -71,7 +73,7 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) type = ne->value->type; num = ne->value->length; if (num > NAME_ONELINE_MAX) { - X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); + ERR_raise(ERR_LIB_X509, X509_R_NAME_TOO_LONG); goto end; } q = ne->value->data; @@ -107,20 +109,17 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) if (!gs_doit[j & 3]) continue; l2++; -#ifndef CHARSET_EBCDIC - if ((q[j] < ' ') || (q[j] > '~')) - l2 += 3; -#else - if ((os_toascii[q[j]] < os_toascii[' ']) || - (os_toascii[q[j]] > os_toascii['~'])) + if (q[j] == '/' || q[j] == '+') + l2++; /* char needs to be escaped */ + else if ((ossl_toascii(q[j]) < ossl_toascii(' ')) || + (ossl_toascii(q[j]) > ossl_toascii('~'))) l2 += 3; -#endif } lold = l; l += 1 + l1 + 1 + l2; if (l > NAME_ONELINE_MAX) { - X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); + ERR_raise(ERR_LIB_X509, X509_R_NAME_TOO_LONG); goto end; } if (b != NULL) { @@ -131,7 +130,7 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) break; } else p = &(buf[lold]); - *(p++) = '/'; + *(p++) = prev_set == ne->set ? '+' : '/'; memcpy(p, s, (unsigned int)l1); p += l1; *(p++) = '='; @@ -150,8 +149,11 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) *(p++) = 'x'; *(p++) = hex[(n >> 4) & 0x0f]; *(p++) = hex[n & 0x0f]; - } else + } else { + if (n == '/' || n == '+') + *(p++) = '\\'; *(p++) = n; + } #else n = os_toascii[q[j]]; if ((n < os_toascii[' ']) || (n > os_toascii['~'])) { @@ -159,11 +161,15 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) *(p++) = 'x'; *(p++) = hex[(n >> 4) & 0x0f]; *(p++) = hex[n & 0x0f]; - } else + } else { + if (n == os_toascii['/'] || n == os_toascii['+']) + *(p++) = '\\'; *(p++) = q[j]; + } #endif } *p = '\0'; + prev_set = ne->set; } if (b != NULL) { p = b->data; @@ -174,7 +180,7 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) *p = '\0'; return p; err: - X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); end: BUF_MEM_free(b); return NULL; diff --git a/crypto/openssl/crypto/x509/x509_r2x.c b/crypto/openssl/crypto/x509/x509_r2x.c index 6b1623feacb7..c7f6181c4465 100644 --- a/crypto/openssl/crypto/x509/x509_r2x.c +++ b/crypto/openssl/crypto/x509/x509_r2x.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -21,11 +21,11 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) { X509 *ret = NULL; X509_CINF *xi = NULL; - X509_NAME *xn; + const X509_NAME *xn; EVP_PKEY *pubkey = NULL; if ((ret = X509_new()) == NULL) { - X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/openssl/crypto/x509/x509_req.c b/crypto/openssl/crypto/x509/x509_req.c index c2b8cb9f3e2d..5428bdaf4ca6 100644 --- a/crypto/openssl/crypto/x509/x509_req.c +++ b/crypto/openssl/crypto/x509/x509_req.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -26,9 +26,9 @@ X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) int i; EVP_PKEY *pktmp; - ret = X509_REQ_new(); + ret = X509_REQ_new_ex(x->libctx, x->propq); if (ret == NULL) { - X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } @@ -85,33 +85,18 @@ int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) int ok = 0; xk = X509_REQ_get_pubkey(x); - switch (EVP_PKEY_cmp(xk, k)) { + switch (EVP_PKEY_eq(xk, k)) { case 1: ok = 1; break; case 0: - X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, - X509_R_KEY_VALUES_MISMATCH); + ERR_raise(ERR_LIB_X509, X509_R_KEY_VALUES_MISMATCH); break; case -1: - X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); + ERR_raise(ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH); break; case -2: -#ifndef OPENSSL_NO_EC - if (EVP_PKEY_id(k) == EVP_PKEY_EC) { - X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB); - break; - } -#endif -#ifndef OPENSSL_NO_DH - if (EVP_PKEY_id(k) == EVP_PKEY_DH) { - /* No idea */ - X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, - X509_R_CANT_CHECK_DH_KEY); - break; - } -#endif - X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); + ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_KEY_TYPE); } EVP_PKEY_free(xk); @@ -131,6 +116,7 @@ static int *ext_nids = ext_nid_list; int X509_REQ_extension_nid(int req_nid) { int i, nid; + for (i = 0;; i++) { nid = ext_nids[i]; if (nid == NID_undef) @@ -157,7 +143,7 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) int idx, *pnid; const unsigned char *p; - if ((req == NULL) || !ext_nids) + if (req == NULL || !ext_nids) return NULL; for (pnid = ext_nids; *pnid != NID_undef; pnid++) { idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); @@ -181,15 +167,15 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) * Add a STACK_OF extensions to a certificate request: allow alternative OIDs * in case we want to create a non standard one. */ - -int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, - int nid) +int X509_REQ_add_extensions_nid(X509_REQ *req, + const STACK_OF(X509_EXTENSION) *exts, int nid) { int extlen; int rv = 0; unsigned char *ext = NULL; + /* Generate encoding of extensions */ - extlen = ASN1_item_i2d((ASN1_VALUE *)exts, &ext, + extlen = ASN1_item_i2d((const ASN1_VALUE *)exts, &ext, ASN1_ITEM_rptr(X509_EXTENSIONS)); if (extlen <= 0) return 0; @@ -199,7 +185,7 @@ int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, } /* This is the normal usage: use the "official" OID */ -int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) +int X509_REQ_add_extensions(X509_REQ *req, const STACK_OF(X509_EXTENSION) *exts) { return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); } @@ -229,8 +215,13 @@ X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) { - X509_ATTRIBUTE *attr = X509at_delete_attr(req->req_info.attributes, loc); + X509_ATTRIBUTE *attr; + if (req == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + attr = X509at_delete_attr(req->req_info.attributes, loc); if (attr != NULL) req->req_info.enc.modified = 1; return attr; @@ -238,6 +229,10 @@ X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) { + if (req == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } if (!X509at_add1_attr(&req->req_info.attributes, attr)) return 0; req->req_info.enc.modified = 1; @@ -248,6 +243,10 @@ int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, const ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len) { + if (req == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } if (!X509at_add1_attr_by_OBJ(&req->req_info.attributes, obj, type, bytes, len)) return 0; @@ -259,6 +258,10 @@ int X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, int type, const unsigned char *bytes, int len) { + if (req == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } if (!X509at_add1_attr_by_NID(&req->req_info.attributes, nid, type, bytes, len)) return 0; @@ -270,6 +273,10 @@ int X509_REQ_add1_attr_by_txt(X509_REQ *req, const char *attrname, int type, const unsigned char *bytes, int len) { + if (req == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } if (!X509at_add1_attr_by_txt(&req->req_info.attributes, attrname, type, bytes, len)) return 0; @@ -299,7 +306,7 @@ void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, void X509_REQ_set0_signature(X509_REQ *req, ASN1_BIT_STRING *psig) { if (req->signature) - ASN1_BIT_STRING_free(req->signature); + ASN1_BIT_STRING_free(req->signature); req->signature = psig; } @@ -315,6 +322,10 @@ int X509_REQ_get_signature_nid(const X509_REQ *req) int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) { + if (req == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } req->req_info.enc.modified = 1; return i2d_X509_REQ_INFO(&req->req_info, pp); } diff --git a/crypto/openssl/crypto/x509/x509_set.c b/crypto/openssl/crypto/x509/x509_set.c index 164b4e2be136..d8ddde8aaa51 100644 --- a/crypto/openssl/crypto/x509/x509_set.c +++ b/crypto/openssl/crypto/x509/x509_set.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -47,21 +47,21 @@ int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) return 1; } -int X509_set_issuer_name(X509 *x, X509_NAME *name) +int X509_set_issuer_name(X509 *x, const X509_NAME *name) { if (x == NULL) return 0; return X509_NAME_set(&x->cert_info.issuer, name); } -int X509_set_subject_name(X509 *x, X509_NAME *name) +int X509_set_subject_name(X509 *x, const X509_NAME *name) { if (x == NULL) return 0; return X509_NAME_set(&x->cert_info.subject, name); } -int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm) +int ossl_x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm) { ASN1_TIME *in; in = *ptm; @@ -79,14 +79,14 @@ int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm) { if (x == NULL) return 0; - return x509_set1_time(&x->cert_info.validity.notBefore, tm); + return ossl_x509_set1_time(&x->cert_info.validity.notBefore, tm); } int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm) { if (x == NULL) return 0; - return x509_set1_time(&x->cert_info.validity.notAfter, tm); + return ossl_x509_set1_time(&x->cert_info.validity.notAfter, tm); } int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) @@ -192,46 +192,85 @@ int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits, return X509_SIG_INFO_get(&x->siginf, mdnid, pknid, secbits, flags); } -static void x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg, - const ASN1_STRING *sig) +/* Modify *siginf according to alg and sig. Return 1 on success, else 0. */ +static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg, + const ASN1_STRING *sig) { int pknid, mdnid; const EVP_MD *md; + const EVP_PKEY_ASN1_METHOD *ameth; siginf->mdnid = NID_undef; siginf->pknid = NID_undef; siginf->secbits = -1; siginf->flags = 0; if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &mdnid, &pknid) - || pknid == NID_undef) - return; + || pknid == NID_undef) { + ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_SIGID_ALGS); + return 0; + } + siginf->mdnid = mdnid; siginf->pknid = pknid; - if (mdnid == NID_undef) { + + switch (mdnid) { + case NID_undef: /* If we have one, use a custom handler for this algorithm */ - const EVP_PKEY_ASN1_METHOD *ameth = EVP_PKEY_asn1_find(NULL, pknid); + ameth = EVP_PKEY_asn1_find(NULL, pknid); if (ameth == NULL || ameth->siginf_set == NULL - || ameth->siginf_set(siginf, alg, sig) == 0) - return; - siginf->flags |= X509_SIG_INFO_VALID; - return; + || !ameth->siginf_set(siginf, alg, sig)) { + ERR_raise(ERR_LIB_X509, X509_R_ERROR_USING_SIGINF_SET); + return 0; + } + break; + /* + * SHA1 and MD5 are known to be broken. Reduce security bits so that + * they're no longer accepted at security level 1. + * The real values don't really matter as long as they're lower than 80, + * which is our security level 1. + */ + case NID_sha1: + /* + * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack + * for SHA1 at2^63.4 + */ + siginf->secbits = 63; + break; + case NID_md5: + /* + * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf + * puts a chosen-prefix attack for MD5 at 2^39. + */ + siginf->secbits = 39; + break; + case NID_id_GostR3411_94: + /* + * There is a collision attack on GOST R 34.11-94 at 2^105, see + * https://link.springer.com/chapter/10.1007%2F978-3-540-85174-5_10 + */ + siginf->secbits = 105; + break; + default: + /* Security bits: half number of bits in digest */ + if ((md = EVP_get_digestbynid(mdnid)) == NULL) { + ERR_raise(ERR_LIB_X509, X509_R_ERROR_GETTING_MD_BY_NID); + return 0; + } + siginf->secbits = EVP_MD_get_size(md) * 4; + break; } - siginf->flags |= X509_SIG_INFO_VALID; - siginf->mdnid = mdnid; - md = EVP_get_digestbynid(mdnid); - if (md == NULL) - return; - /* Security bits: half number of bits in digest */ - siginf->secbits = EVP_MD_size(md) * 4; switch (mdnid) { - case NID_sha1: - case NID_sha256: - case NID_sha384: - case NID_sha512: + case NID_sha1: + case NID_sha256: + case NID_sha384: + case NID_sha512: siginf->flags |= X509_SIG_INFO_TLS; } + siginf->flags |= X509_SIG_INFO_VALID; + return 1; } -void x509_init_sig_info(X509 *x) +/* Returns 1 on success, 0 on failure */ +int ossl_x509_init_sig_info(X509 *x) { - x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature); + return x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature); } diff --git a/crypto/openssl/crypto/x509/x509_trs.c b/crypto/openssl/crypto/x509/x509_trust.c similarity index 92% rename from crypto/openssl/crypto/x509/x509_trs.c rename to crypto/openssl/crypto/x509/x509_trust.c index a10d437735b8..fd77b0c6fe61 100644 --- a/crypto/openssl/crypto/x509/x509_trs.c +++ b/crypto/openssl/crypto/x509/x509_trust.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -72,7 +72,7 @@ int X509_check_trust(X509 *x, int id, int flags) return obj_trust(NID_anyExtendedKeyUsage, x, flags | X509_TRUST_DO_SS_COMPAT); idx = X509_TRUST_get_by_id(id); - if (idx == -1) + if (idx < 0) return default_trust(id, x, flags); pt = X509_TRUST_get0(idx); return pt->check_trust(pt, x, flags); @@ -112,8 +112,8 @@ int X509_TRUST_get_by_id(int id) int X509_TRUST_set(int *t, int trust) { - if (X509_TRUST_get_by_id(trust) == -1) { - X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST); + if (X509_TRUST_get_by_id(trust) < 0) { + ERR_raise(ERR_LIB_X509, X509_R_INVALID_TRUST); return 0; } *t = trust; @@ -134,9 +134,9 @@ int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), /* Get existing entry if any */ idx = X509_TRUST_get_by_id(id); /* Need a new entry */ - if (idx == -1) { + if (idx < 0) { if ((trtmp = OPENSSL_malloc(sizeof(*trtmp))) == NULL) { - X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return 0; } trtmp->flags = X509_TRUST_DYNAMIC; @@ -148,7 +148,7 @@ int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), OPENSSL_free(trtmp->name); /* dup supplied name */ if ((trtmp->name = OPENSSL_strdup(name)) == NULL) { - X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } /* Keep the dynamic flag of existing entry */ @@ -162,20 +162,20 @@ int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), trtmp->arg2 = arg2; /* If its a new entry manage the dynamic table */ - if (idx == -1) { + if (idx < 0) { if (trtable == NULL && (trtable = sk_X509_TRUST_new(tr_cmp)) == NULL) { - X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err;; } if (!sk_X509_TRUST_push(trtable, trtmp)) { - X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } } return 1; err: - if (idx == -1) { + if (idx < 0) { OPENSSL_free(trtmp->name); OPENSSL_free(trtmp); } @@ -184,7 +184,7 @@ int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), static void trtable_free(X509_TRUST *p) { - if (!p) + if (p == NULL) return; if (p->flags & X509_TRUST_DYNAMIC) { if (p->flags & X509_TRUST_DYNAMIC_NAME) @@ -220,7 +220,7 @@ static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) * Declare the chain verified if the desired trust OID is not rejected in * any auxiliary trust info for this certificate, and the OID is either * expressly trusted, or else either "anyEKU" is trusted, or the - * certificate is self-signed. + * certificate is self-signed and X509_TRUST_NO_SS_COMPAT is not set. */ flags |= X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU; return obj_trust(trust->arg1, x, flags); @@ -239,7 +239,7 @@ static int trust_1oid(X509_TRUST *trust, X509 *x, int flags) static int trust_compat(X509_TRUST *trust, X509 *x, int flags) { - /* Call for side-effect of computing hash and caching extensions */ + /* Call for side-effect of setting EXFLAG_SS for self-signed-certs */ if (X509_check_purpose(x, -1, 0) != 1) return X509_TRUST_UNTRUSTED; if ((flags & X509_TRUST_NO_SS_COMPAT) == 0 && (x->ex_flags & EXFLAG_SS)) diff --git a/crypto/openssl/crypto/x509/x509_txt.c b/crypto/openssl/crypto/x509/x509_txt.c index 02bde640d8e8..f25bb41acb52 100644 --- a/crypto/openssl/crypto/x509/x509_txt.c +++ b/crypto/openssl/crypto/x509/x509_txt.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -58,9 +58,9 @@ const char *X509_verify_cert_error_string(long n) case X509_V_ERR_OUT_OF_MEM: return "out of memory"; case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - return "self signed certificate"; + return "self-signed certificate"; case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - return "self signed certificate in certificate chain"; + return "self-signed certificate in certificate chain"; case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: return "unable to get local issuer certificate"; case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: @@ -69,12 +69,12 @@ const char *X509_verify_cert_error_string(long n) return "certificate chain too long"; case X509_V_ERR_CERT_REVOKED: return "certificate revoked"; - case X509_V_ERR_INVALID_CA: - return "invalid CA certificate"; + case X509_V_ERR_NO_ISSUER_PUBLIC_KEY: + return "issuer certificate doesn't have a public key"; case X509_V_ERR_PATH_LENGTH_EXCEEDED: return "path length constraint exceeded"; case X509_V_ERR_INVALID_PURPOSE: - return "unsupported certificate purpose"; + return "unsuitable certificate purpose"; case X509_V_ERR_CERT_UNTRUSTED: return "certificate not trusted"; case X509_V_ERR_CERT_REJECTED: @@ -111,9 +111,9 @@ const char *X509_verify_cert_error_string(long n) case X509_V_ERR_NO_EXPLICIT_POLICY: return "no explicit policy"; case X509_V_ERR_DIFFERENT_CRL_SCOPE: - return "Different CRL scope"; + return "different CRL scope"; case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: - return "Unsupported extension feature"; + return "unsupported extension feature"; case X509_V_ERR_UNNESTED_RESOURCE: return "RFC 3779 resource not subset of parent's resources"; case X509_V_ERR_PERMITTED_VIOLATION: @@ -133,7 +133,7 @@ const char *X509_verify_cert_error_string(long n) case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: return "CRL path validation error"; case X509_V_ERR_PATH_LOOP: - return "Path Loop"; + return "path loop"; case X509_V_ERR_SUITE_B_INVALID_VERSION: return "Suite B: certificate version invalid"; case X509_V_ERR_SUITE_B_INVALID_ALGORITHM: @@ -147,13 +147,13 @@ const char *X509_verify_cert_error_string(long n) case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: return "Suite B: cannot sign P-384 with P-256"; case X509_V_ERR_HOSTNAME_MISMATCH: - return "Hostname mismatch"; + return "hostname mismatch"; case X509_V_ERR_EMAIL_MISMATCH: - return "Email address mismatch"; + return "email address mismatch"; case X509_V_ERR_IP_ADDRESS_MISMATCH: return "IP address mismatch"; case X509_V_ERR_DANE_NO_MATCH: - return "No matching DANE TLSA records"; + return "no matching DANE TLSA records"; case X509_V_ERR_EE_KEY_TOO_SMALL: return "EE certificate key too weak"; case X509_V_ERR_CA_KEY_TOO_SMALL: @@ -161,9 +161,9 @@ const char *X509_verify_cert_error_string(long n) case X509_V_ERR_CA_MD_TOO_WEAK: return "CA signature digest algorithm too weak"; case X509_V_ERR_INVALID_CALL: - return "Invalid certificate verification context"; + return "invalid certificate verification context"; case X509_V_ERR_STORE_LOOKUP: - return "Issuer certificate lookup error"; + return "issuer certificate lookup error"; case X509_V_ERR_NO_VALID_SCTS: return "Certificate Transparency required, but no valid SCTs found"; case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION: @@ -174,6 +174,42 @@ const char *X509_verify_cert_error_string(long n) return "OCSP verification failed"; case X509_V_ERR_OCSP_CERT_UNKNOWN: return "OCSP unknown cert"; + case X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM: + return "Cannot find certificate signature algorithm"; + case X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH: + return "subject signature algorithm and issuer public key algorithm mismatch"; + case X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY: + return "cert info siganature and signature algorithm mismatch"; + case X509_V_ERR_INVALID_CA: + return "invalid CA certificate"; + case X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA: + return "Path length invalid for non-CA cert"; + case X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN: + return "Path length given without key usage keyCertSign"; + case X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA: + return "Key usage keyCertSign invalid for non-CA cert"; + case X509_V_ERR_ISSUER_NAME_EMPTY: + return "Issuer name empty"; + case X509_V_ERR_SUBJECT_NAME_EMPTY: + return "Subject name empty"; + case X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER: + return "Missing Authority Key Identifier"; + case X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER: + return "Missing Subject Key Identifier"; + case X509_V_ERR_EMPTY_SUBJECT_ALT_NAME: + return "Empty Subject Alternative Name extension"; + case X509_V_ERR_CA_BCONS_NOT_CRITICAL: + return "Basic Constraints of CA cert not marked critical"; + case X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL: + return "Subject empty and Subject Alt Name extension not critical"; + case X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL: + return "Authority Key Identifier marked critical"; + case X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL: + return "Subject Key Identifier marked critical"; + case X509_V_ERR_CA_CERT_MISSING_KEY_USAGE: + return "CA cert does not include key usage extension"; + case X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3: + return "Using cert extension requires at least X509v3"; case X509_V_ERR_EC_KEY_EXPLICIT_PARAMS: return "Certificate public key has explicit ECC parameters"; diff --git a/crypto/openssl/crypto/x509/x509_v3.c b/crypto/openssl/crypto/x509/x509_v3.c index c7876023304c..62ae7d6b8d62 100644 --- a/crypto/openssl/crypto/x509/x509_v3.c +++ b/crypto/openssl/crypto/x509/x509_v3.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -19,9 +19,12 @@ int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) { + int ret; + if (x == NULL) return 0; - return sk_X509_EXTENSION_num(x); + ret = sk_X509_EXTENSION_num(x); + return ret > 0 ? ret : 0; } int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, @@ -101,7 +104,7 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, STACK_OF(X509_EXTENSION) *sk = NULL; if (x == NULL) { - X509err(X509_F_X509V3_ADD_EXT, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); goto err2; } @@ -125,7 +128,7 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, *x = sk; return sk; err: - X509err(X509_F_X509V3_ADD_EXT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); err2: X509_EXTENSION_free(new_ex); if (x != NULL && *x == NULL) @@ -142,7 +145,7 @@ X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, obj = OBJ_nid2obj(nid); if (obj == NULL) { - X509err(X509_F_X509_EXTENSION_CREATE_BY_NID, X509_R_UNKNOWN_NID); + ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_NID); return NULL; } ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); @@ -159,8 +162,7 @@ X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, if ((ex == NULL) || (*ex == NULL)) { if ((ret = X509_EXTENSION_new()) == NULL) { - X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } } else diff --git a/crypto/openssl/crypto/x509/x509_vfy.c b/crypto/openssl/crypto/x509/x509_vfy.c index 925fbb541258..9384f1da9bad 100644 --- a/crypto/openssl/crypto/x509/x509_vfy.c +++ b/crypto/openssl/crypto/x509/x509_vfy.c @@ -1,12 +1,14 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#include "internal/deprecated.h" + #include #include #include @@ -21,47 +23,23 @@ #include #include #include +#include #include "internal/dane.h" #include "crypto/x509.h" #include "x509_local.h" /* CRL score values */ -/* No unhandled critical extensions */ - -#define CRL_SCORE_NOCRITICAL 0x100 - -/* certificate is within CRL scope */ - -#define CRL_SCORE_SCOPE 0x080 - -/* CRL times valid */ - -#define CRL_SCORE_TIME 0x040 - -/* Issuer name matches certificate */ - -#define CRL_SCORE_ISSUER_NAME 0x020 - -/* If this score or above CRL is probably valid */ - -#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) - -/* CRL issuer is certificate issuer */ - -#define CRL_SCORE_ISSUER_CERT 0x018 - -/* CRL issuer is on certificate path */ - -#define CRL_SCORE_SAME_PATH 0x008 - -/* CRL issuer matches CRL AKID */ - -#define CRL_SCORE_AKID 0x004 - -/* Have a delta CRL with valid times */ - -#define CRL_SCORE_TIME_DELTA 0x002 +#define CRL_SCORE_NOCRITICAL 0x100 /* No unhandled critical extensions */ +#define CRL_SCORE_SCOPE 0x080 /* certificate is within CRL scope */ +#define CRL_SCORE_TIME 0x040 /* CRL times valid */ +#define CRL_SCORE_ISSUER_NAME 0x020 /* Issuer name matches certificate */ +#define CRL_SCORE_VALID /* If this score or above CRL is probably valid */ \ + (CRL_SCORE_NOCRITICAL | CRL_SCORE_TIME | CRL_SCORE_SCOPE) +#define CRL_SCORE_ISSUER_CERT 0x018 /* CRL issuer is certificate issuer */ +#define CRL_SCORE_SAME_PATH 0x008 /* CRL issuer is on certificate path */ +#define CRL_SCORE_AKID 0x004 /* CRL issuer matches CRL AKID */ +#define CRL_SCORE_TIME_DELTA 0x002 /* Have a delta CRL with valid times */ static int build_chain(X509_STORE_CTX *ctx); static int verify_chain(X509_STORE_CTX *ctx); @@ -69,7 +47,7 @@ static int dane_verify(X509_STORE_CTX *ctx); static int null_callback(int ok, X509_STORE_CTX *e); static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); -static int check_chain_extensions(X509_STORE_CTX *ctx); +static int check_extensions(X509_STORE_CTX *ctx); static int check_name_constraints(X509_STORE_CTX *ctx); static int check_id(X509_STORE_CTX *ctx); static int check_trust(X509_STORE_CTX *ctx, int num_untrusted); @@ -105,64 +83,90 @@ static int null_callback(int ok, X509_STORE_CTX *e) return ok; } -/* - * Return 1 if given cert is considered self-signed, 0 if not or on error. - * This does not verify self-signedness but relies on x509v3_cache_extensions() - * matching issuer and subject names (i.e., the cert being self-issued) and any - * present authority key identifier matching the subject key identifier, etc. +/*- + * Return 1 if given cert is considered self-signed, 0 if not, or -1 on error. + * This actually verifies self-signedness only if requested. + * It calls ossl_x509v3_cache_extensions() + * to match issuer and subject names (i.e., the cert being self-issued) and any + * present authority key identifier to match the subject key identifier, etc. */ -static int cert_self_signed(X509 *x) +int X509_self_signed(X509 *cert, int verify_signature) { - if (X509_check_purpose(x, -1, 0) != 1) + EVP_PKEY *pkey; + + if ((pkey = X509_get0_pubkey(cert)) == NULL) { /* handles cert == NULL */ + ERR_raise(ERR_LIB_X509, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); + return -1; + } + if (!ossl_x509v3_cache_extensions(cert)) + return -1; + if ((cert->ex_flags & EXFLAG_SS) == 0) return 0; - if (x->ex_flags & EXFLAG_SS) + if (!verify_signature) return 1; - else - return 0; + return X509_verify(cert, pkey); } -/* Given a certificate try and find an exact match in the store */ - -static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) +/* + * Given a certificate, try and find an exact match in the store. + * Returns 1 on success, 0 on not found, -1 on internal error. + */ +static int lookup_cert_match(X509 **result, X509_STORE_CTX *ctx, X509 *x) { STACK_OF(X509) *certs; X509 *xtmp = NULL; - int i; + int i, ret; + + *result = NULL; /* Lookup all certs with matching subject name */ + ERR_set_mark(); certs = ctx->lookup_certs(ctx, X509_get_subject_name(x)); + ERR_pop_to_mark(); if (certs == NULL) - return NULL; + return -1; /* Look for exact match */ for (i = 0; i < sk_X509_num(certs); i++) { xtmp = sk_X509_value(certs, i); - if (!X509_cmp(xtmp, x)) + if (X509_cmp(xtmp, x) == 0) break; xtmp = NULL; } - if (xtmp != NULL && !X509_up_ref(xtmp)) - xtmp = NULL; + ret = xtmp != NULL; + if (ret) { + if (!X509_up_ref(xtmp)) + ret = -1; + else + *result = xtmp; + } sk_X509_pop_free(certs, X509_free); - return xtmp; + return ret; } /*- * Inform the verify callback of an error. - * If B is not NULL it is the error cert, otherwise use the chain cert at - * B. - * If B is not X509_V_OK, that's the error value, otherwise leave - * unchanged (presumably set by the caller). + * The error code is set to |err| if |err| is not X509_V_OK, else + * |ctx->error| is left unchanged (under the assumption it is set elsewhere). + * The error depth is |depth| if >= 0, else it defaults to |ctx->error_depth|. + * The error cert is |x| if not NULL, else defaults to the chain cert at depth. * * Returns 0 to abort verification with an error, non-zero to continue. */ static int verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err) { - ctx->error_depth = depth; + if (depth < 0) + depth = ctx->error_depth; + else + ctx->error_depth = depth; ctx->current_cert = (x != NULL) ? x : sk_X509_value(ctx->chain, depth); if (err != X509_V_OK) ctx->error = err; return ctx->verify_cb(0, ctx); } +#define CB_FAIL_IF(cond, ctx, cert, depth, err) \ + if ((cond) && verify_cb_cert(ctx, cert, depth, err) == 0) \ + return 0 + /*- * Inform the verify callback of an error, CRL-specific variant. Here, the * error depth and certificate are already set, we just specify the error @@ -191,73 +195,79 @@ static int check_auth_level(X509_STORE_CTX *ctx) * We've already checked the security of the leaf key, so here we only * check the security of issuer keys. */ - if (i > 0 && !check_key_level(ctx, cert) && - verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_KEY_TOO_SMALL) == 0) - return 0; + CB_FAIL_IF(i > 0 && !check_key_level(ctx, cert), + ctx, cert, i, X509_V_ERR_CA_KEY_TOO_SMALL); /* * We also check the signature algorithm security of all certificates * except those of the trust anchor at index num-1. */ - if (i < num - 1 && !check_sig_level(ctx, cert) && - verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_MD_TOO_WEAK) == 0) - return 0; + CB_FAIL_IF(i < num - 1 && !check_sig_level(ctx, cert), + ctx, cert, i, X509_V_ERR_CA_MD_TOO_WEAK); } return 1; } +/* Returns -1 on internal error */ static int verify_chain(X509_STORE_CTX *ctx) { int err; int ok; - /* - * Before either returning with an error, or continuing with CRL checks, - * instantiate chain public key parameters. - */ - if ((ok = build_chain(ctx)) == 0 || - (ok = check_chain_extensions(ctx)) == 0 || - (ok = check_auth_level(ctx)) == 0 || - (ok = check_id(ctx)) == 0 || 1) - X509_get_pubkey_parameters(NULL, ctx->chain); - if (ok == 0 || (ok = ctx->check_revocation(ctx)) == 0) + if ((ok = build_chain(ctx)) <= 0 + || (ok = check_extensions(ctx)) <= 0 + || (ok = check_auth_level(ctx)) <= 0 + || (ok = check_id(ctx)) <= 0 + || (ok = X509_get_pubkey_parameters(NULL, ctx->chain) ? 1 : -1) <= 0 + || (ok = ctx->check_revocation(ctx)) <= 0) return ok; err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain, ctx->param->flags); - if (err != X509_V_OK) { - if ((ok = verify_cb_cert(ctx, NULL, ctx->error_depth, err)) == 0) - return ok; - } + CB_FAIL_IF(err != X509_V_OK, ctx, NULL, ctx->error_depth, err); /* Verify chain signatures and expiration times */ - ok = (ctx->verify != NULL) ? ctx->verify(ctx) : internal_verify(ctx); - if (!ok) + ok = ctx->verify != NULL ? ctx->verify(ctx) : internal_verify(ctx); + if (ok <= 0) return ok; - if ((ok = check_name_constraints(ctx)) == 0) + if ((ok = check_name_constraints(ctx)) <= 0) return ok; #ifndef OPENSSL_NO_RFC3779 /* RFC 3779 path validation, now that CRL check has been done */ - if ((ok = X509v3_asid_validate_path(ctx)) == 0) + if ((ok = X509v3_asid_validate_path(ctx)) <= 0) return ok; - if ((ok = X509v3_addr_validate_path(ctx)) == 0) + if ((ok = X509v3_addr_validate_path(ctx)) <= 0) return ok; #endif /* If we get this far evaluate policies */ - if (ctx->param->flags & X509_V_FLAG_POLICY_CHECK) + if ((ctx->param->flags & X509_V_FLAG_POLICY_CHECK) != 0) ok = ctx->check_policy(ctx); return ok; } +int X509_STORE_CTX_verify(X509_STORE_CTX *ctx) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + if (ctx->cert == NULL && sk_X509_num(ctx->untrusted) >= 1) + ctx->cert = sk_X509_value(ctx->untrusted, 0); + return X509_verify_cert(ctx); +} + int X509_verify_cert(X509_STORE_CTX *ctx) { - SSL_DANE *dane = ctx->dane; int ret; + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } if (ctx->cert == NULL) { - X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); + ERR_raise(ERR_LIB_X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); ctx->error = X509_V_ERR_INVALID_CALL; return -1; } @@ -267,40 +277,22 @@ int X509_verify_cert(X509_STORE_CTX *ctx) * This X509_STORE_CTX has already been used to verify a cert. We * cannot do another one. */ - X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ctx->error = X509_V_ERR_INVALID_CALL; return -1; } - if (!X509_up_ref(ctx->cert)) { - X509err(X509_F_X509_VERIFY_CERT, ERR_R_INTERNAL_ERROR); - ctx->error = X509_V_ERR_UNSPECIFIED; - return -1; - } - - /* - * first we make sure the chain we are going to build is present and that - * the first entry is in place - */ - if ((ctx->chain = sk_X509_new_null()) == NULL - || !sk_X509_push(ctx->chain, ctx->cert)) { - X509_free(ctx->cert); - X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + if (!ossl_x509_add_cert_new(&ctx->chain, ctx->cert, X509_ADD_FLAG_UP_REF)) { ctx->error = X509_V_ERR_OUT_OF_MEM; return -1; } - ctx->num_untrusted = 1; /* If the peer's public key is too weak, we can stop early. */ - if (!check_key_level(ctx, ctx->cert) && - !verify_cb_cert(ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL)) - return 0; + CB_FAIL_IF(!check_key_level(ctx, ctx->cert), + ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL); - if (DANETLS_ENABLED(dane)) - ret = dane_verify(ctx); - else - ret = verify_chain(ctx); + ret = DANETLS_ENABLED(ctx->dane) ? dane_verify(ctx) : verify_chain(ctx); /* * Safety-net. If we are returning an error, we must also set ctx->error, @@ -323,10 +315,10 @@ static int sk_X509_contains(STACK_OF(X509) *sk, X509 *cert) } /* - * Find in given STACK_OF(X509) sk an issuer cert of given cert x. - * The issuer must not yet be in ctx->chain, where the exceptional case - * that x is self-issued and ctx->chain has just one element is allowed. - * Prefer the first one that is not expired, else take the last expired one. + * Find in given STACK_OF(X509) |sk| an issuer cert (if any) of given cert |x|. + * The issuer must not yet be in |ctx->chain|, yet allowing the exception that + * |x| is self-issued and |ctx->chain| has just one element. + * Prefer the first non-expired one, else take the most recently expired one. */ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) { @@ -338,56 +330,60 @@ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) if (ctx->check_issued(ctx, x, issuer) && (((x->ex_flags & EXFLAG_SI) != 0 && sk_X509_num(ctx->chain) == 1) || !sk_X509_contains(ctx->chain, issuer))) { - rv = issuer; - if (x509_check_cert_time(ctx, rv, -1)) - break; + if (ossl_x509_check_cert_time(ctx, issuer, -1)) + return issuer; + if (rv == NULL || ASN1_TIME_compare(X509_get0_notAfter(issuer), + X509_get0_notAfter(rv)) > 0) + rv = issuer; } } return rv; } /* Check that the given certificate 'x' is issued by the certificate 'issuer' */ -static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) +static int check_issued(ossl_unused X509_STORE_CTX *ctx, X509 *x, X509 *issuer) { - return x509_likely_issued(issuer, x) == X509_V_OK; + int err = ossl_x509_likely_issued(issuer, x); + + if (err == X509_V_OK) + return 1; + /* + * SUBJECT_ISSUER_MISMATCH just means 'x' is clearly not issued by 'issuer'. + * Every other error code likely indicates a real error. + */ + return 0; } -/* Alternative lookup method: look from a STACK stored in other_ctx */ +/*- + * Alternative get_issuer method: look up from a STACK_OF(X509) in other_ctx. + * Returns -1 on internal error. + */ static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { *issuer = find_issuer(ctx, ctx->other_ctx, x); - - if (*issuer == NULL || !X509_up_ref(*issuer)) - goto err; - - return 1; - - err: - *issuer = NULL; + if (*issuer != NULL) + return X509_up_ref(*issuer) ? 1 : -1; return 0; } -static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, X509_NAME *nm) +/*- + * Alternative lookup method: look from a STACK stored in other_ctx. + * Returns NULL on internal error (such as out of memory). + */ +static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, + const X509_NAME *nm) { - STACK_OF(X509) *sk = NULL; + STACK_OF(X509) *sk = sk_X509_new_null(); X509 *x; int i; + if (sk == NULL) + return NULL; for (i = 0; i < sk_X509_num(ctx->other_ctx); i++) { x = sk_X509_value(ctx->other_ctx, i); if (X509_NAME_cmp(nm, X509_get_subject_name(x)) == 0) { - if (!X509_up_ref(x)) { + if (!X509_add_cert(sk, x, X509_ADD_FLAG_UP_REF)) { sk_X509_pop_free(sk, X509_free); - X509err(X509_F_LOOKUP_CERTS_SK, ERR_R_INTERNAL_ERROR); - ctx->error = X509_V_ERR_UNSPECIFIED; - return NULL; - } - if (sk == NULL) - sk = sk_X509_new_null(); - if (sk == NULL || !sk_X509_push(sk, x)) { - X509_free(x); - sk_X509_pop_free(sk, X509_free); - X509err(X509_F_LOOKUP_CERTS_SK, ERR_R_MALLOC_FAILURE); ctx->error = X509_V_ERR_OUT_OF_MEM; return NULL; } @@ -399,6 +395,7 @@ static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, X509_NAME *nm) /* * Check EE or CA certificate purpose. For trusted certificates explicit local * auxiliary trust can be used to override EKU-restrictions. + * Sadly, returns 0 also on internal error. */ static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth, int must_be_ca) @@ -448,18 +445,15 @@ static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth, } /* - * Check a certificate chains extensions for consistency with the supplied - * purpose + * Check extensions of a cert chain for consistency with the supplied purpose. + * Sadly, returns 0 also on internal error. */ - -static int check_chain_extensions(X509_STORE_CTX *ctx) +static int check_extensions(X509_STORE_CTX *ctx) { int i, must_be_ca, plen = 0; X509 *x; - int proxy_path_length = 0; - int purpose; - int allow_proxy_certs; - int num = sk_X509_num(ctx->chain); + int ret, proxy_path_length = 0; + int purpose, allow_proxy_certs, num = sk_X509_num(ctx->chain); /*- * must_be_ca can have 1 of 3 values: @@ -473,87 +467,127 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) must_be_ca = -1; /* CRL path validation */ - if (ctx->parent) { + if (ctx->parent != NULL) { allow_proxy_certs = 0; purpose = X509_PURPOSE_CRL_SIGN; } else { allow_proxy_certs = - ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); + (ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS) != 0; purpose = ctx->param->purpose; } for (i = 0; i < num; i++) { - int ret; x = sk_X509_value(ctx->chain, i); - if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) - && (x->ex_flags & EXFLAG_CRITICAL)) { - if (!verify_cb_cert(ctx, x, i, - X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION)) - return 0; - } - if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) { - if (!verify_cb_cert(ctx, x, i, - X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED)) - return 0; - } + CB_FAIL_IF((ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) == 0 + && (x->ex_flags & EXFLAG_CRITICAL) != 0, + ctx, x, i, X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION); + CB_FAIL_IF(!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY) != 0, + ctx, x, i, X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED); ret = X509_check_ca(x); switch (must_be_ca) { case -1: - if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) - && (ret != 1) && (ret != 0)) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_CA; - } else - ret = 1; + CB_FAIL_IF((ctx->param->flags & X509_V_FLAG_X509_STRICT) != 0 + && ret != 1 && ret != 0, + ctx, x, i, X509_V_ERR_INVALID_CA); break; case 0: - if (ret != 0) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_NON_CA; - } else - ret = 1; + CB_FAIL_IF(ret != 0, ctx, x, i, X509_V_ERR_INVALID_NON_CA); break; default: /* X509_V_FLAG_X509_STRICT is implicit for intermediate CAs */ - if ((ret == 0) - || ((i + 1 < num || ctx->param->flags & X509_V_FLAG_X509_STRICT) - && (ret != 1))) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_CA; - } else - ret = 1; + CB_FAIL_IF(ret == 0 + || ((i + 1 < num + || (ctx->param->flags & X509_V_FLAG_X509_STRICT) != 0) + && ret != 1), ctx, x, i, X509_V_ERR_INVALID_CA); break; } - if (ret > 0 - && (ctx->param->flags & X509_V_FLAG_X509_STRICT) && num > 1) { + if (num > 1) { /* Check for presence of explicit elliptic curve parameters */ ret = check_curve(x); - if (ret < 0) { - ctx->error = X509_V_ERR_UNSPECIFIED; - ret = 0; - } else if (ret == 0) { - ctx->error = X509_V_ERR_EC_KEY_EXPLICIT_PARAMS; - } + CB_FAIL_IF(ret < 0, ctx, x, i, X509_V_ERR_UNSPECIFIED); + CB_FAIL_IF(ret == 0, ctx, x, i, X509_V_ERR_EC_KEY_EXPLICIT_PARAMS); } - if (ret > 0 - && (x->ex_flags & EXFLAG_CA) == 0 - && x->ex_pathlen != -1 - && (ctx->param->flags & X509_V_FLAG_X509_STRICT)) { - ctx->error = X509_V_ERR_INVALID_EXTENSION; - ret = 0; + /* + * Do the following set of checks only if strict checking is requested + * and not for self-issued (including self-signed) EE (non-CA) certs + * because RFC 5280 does not apply to them according RFC 6818 section 2. + */ + if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) != 0 + && num > 1) { /* + * this should imply + * !(i == 0 && (x->ex_flags & EXFLAG_CA) == 0 + * && (x->ex_flags & EXFLAG_SI) != 0) + */ + /* Check Basic Constraints according to RFC 5280 section 4.2.1.9 */ + if (x->ex_pathlen != -1) { + CB_FAIL_IF((x->ex_flags & EXFLAG_CA) == 0, + ctx, x, i, X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA); + CB_FAIL_IF((x->ex_kusage & KU_KEY_CERT_SIGN) == 0, ctx, + x, i, X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN); + } + CB_FAIL_IF((x->ex_flags & EXFLAG_CA) != 0 + && (x->ex_flags & EXFLAG_BCONS) != 0 + && (x->ex_flags & EXFLAG_BCONS_CRITICAL) == 0, + ctx, x, i, X509_V_ERR_CA_BCONS_NOT_CRITICAL); + /* Check Key Usage according to RFC 5280 section 4.2.1.3 */ + if ((x->ex_flags & EXFLAG_CA) != 0) { + CB_FAIL_IF((x->ex_flags & EXFLAG_KUSAGE) == 0, + ctx, x, i, X509_V_ERR_CA_CERT_MISSING_KEY_USAGE); + } else { + CB_FAIL_IF((x->ex_kusage & KU_KEY_CERT_SIGN) != 0, ctx, x, i, + X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA); + } + /* Check issuer is non-empty acc. to RFC 5280 section 4.1.2.4 */ + CB_FAIL_IF(X509_NAME_entry_count(X509_get_issuer_name(x)) == 0, + ctx, x, i, X509_V_ERR_ISSUER_NAME_EMPTY); + /* Check subject is non-empty acc. to RFC 5280 section 4.1.2.6 */ + CB_FAIL_IF(((x->ex_flags & EXFLAG_CA) != 0 + || (x->ex_kusage & KU_CRL_SIGN) != 0 + || x->altname == NULL) + && X509_NAME_entry_count(X509_get_subject_name(x)) == 0, + ctx, x, i, X509_V_ERR_SUBJECT_NAME_EMPTY); + CB_FAIL_IF(X509_NAME_entry_count(X509_get_subject_name(x)) == 0 + && x->altname != NULL + && (x->ex_flags & EXFLAG_SAN_CRITICAL) == 0, + ctx, x, i, X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL); + /* Check SAN is non-empty according to RFC 5280 section 4.2.1.6 */ + CB_FAIL_IF(x->altname != NULL + && sk_GENERAL_NAME_num(x->altname) <= 0, + ctx, x, i, X509_V_ERR_EMPTY_SUBJECT_ALT_NAME); + /* Check sig alg consistency acc. to RFC 5280 section 4.1.1.2 */ + CB_FAIL_IF(X509_ALGOR_cmp(&x->sig_alg, &x->cert_info.signature) != 0, + ctx, x, i, X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY); + CB_FAIL_IF(x->akid != NULL + && (x->ex_flags & EXFLAG_AKID_CRITICAL) != 0, + ctx, x, i, X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL); + CB_FAIL_IF(x->skid != NULL + && (x->ex_flags & EXFLAG_SKID_CRITICAL) != 0, + ctx, x, i, X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL); + if (X509_get_version(x) >= X509_VERSION_3) { + /* Check AKID presence acc. to RFC 5280 section 4.2.1.1 */ + CB_FAIL_IF(i + 1 < num /* + * this means not last cert in chain, + * taken as "generated by conforming CAs" + */ + && (x->akid == NULL || x->akid->keyid == NULL), ctx, + x, i, X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER); + /* Check SKID presence acc. to RFC 5280 section 4.2.1.2 */ + CB_FAIL_IF((x->ex_flags & EXFLAG_CA) != 0 && x->skid == NULL, + ctx, x, i, X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER); + } else { + CB_FAIL_IF(sk_X509_EXTENSION_num(X509_get0_extensions(x)) > 0, + ctx, x, i, X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3); + } } - if (ret == 0 && !verify_cb_cert(ctx, x, i, X509_V_OK)) - return 0; + /* check_purpose() makes the callback as needed */ if (purpose > 0 && !check_purpose(ctx, x, purpose, i, must_be_ca)) return 0; - /* Check pathlen */ - if ((i > 1) && (x->ex_pathlen != -1) - && (plen > (x->ex_pathlen + proxy_path_length))) { - if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED)) - return 0; - } - /* Increment path length if not a self issued intermediate CA */ + /* Check path length */ + CB_FAIL_IF(i > 1 && x->ex_pathlen != -1 + && plen > x->ex_pathlen + proxy_path_length, + ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED); + /* Increment path length if not a self-issued intermediate CA */ if (i > 0 && (x->ex_flags & EXFLAG_SI) == 0) plen++; /* @@ -574,17 +608,15 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) * increment proxy_path_length. */ if (x->ex_pcpathlen != -1) { - if (proxy_path_length > x->ex_pcpathlen) { - if (!verify_cb_cert(ctx, x, i, - X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED)) - return 0; - } + CB_FAIL_IF(proxy_path_length > x->ex_pcpathlen, + ctx, x, i, X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED); proxy_path_length = x->ex_pcpathlen; } proxy_path_length++; must_be_ca = 0; - } else + } else { must_be_ca = 1; + } } return 1; } @@ -610,6 +642,7 @@ static int has_san_id(X509 *x, int gtype) return ret; } +/* Returns -1 on internal error */ static int check_name_constraints(X509_STORE_CTX *ctx) { int i; @@ -619,8 +652,8 @@ static int check_name_constraints(X509_STORE_CTX *ctx) X509 *x = sk_X509_value(ctx->chain, i); int j; - /* Ignore self issued certs unless last in chain */ - if (i && (x->ex_flags & EXFLAG_SI)) + /* Ignore self-issued certs unless last in chain */ + if (i != 0 && (x->ex_flags & EXFLAG_SI) != 0) continue; /* @@ -629,16 +662,16 @@ static int check_name_constraints(X509_STORE_CTX *ctx) * added. * (RFC 3820: 3.4, 4.1.3 (a)(4)) */ - if (x->ex_flags & EXFLAG_PROXY) { + if ((x->ex_flags & EXFLAG_PROXY) != 0) { X509_NAME *tmpsubject = X509_get_subject_name(x); X509_NAME *tmpissuer = X509_get_issuer_name(x); X509_NAME_ENTRY *tmpentry = NULL; - int last_object_nid = 0; + int last_nid = 0; int err = X509_V_OK; - int last_object_loc = X509_NAME_entry_count(tmpsubject) - 1; + int last_loc = X509_NAME_entry_count(tmpsubject) - 1; /* Check that there are at least two RDNs */ - if (last_object_loc < 1) { + if (last_loc < 1) { err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; goto proxy_name_done; } @@ -655,12 +688,11 @@ static int check_name_constraints(X509_STORE_CTX *ctx) /* * Check that the last subject component isn't part of a - * multivalued RDN + * multi-valued RDN */ - if (X509_NAME_ENTRY_set(X509_NAME_get_entry(tmpsubject, - last_object_loc)) + if (X509_NAME_ENTRY_set(X509_NAME_get_entry(tmpsubject, last_loc)) == X509_NAME_ENTRY_set(X509_NAME_get_entry(tmpsubject, - last_object_loc - 1))) { + last_loc - 1))) { err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; goto proxy_name_done; } @@ -671,17 +703,15 @@ static int check_name_constraints(X509_STORE_CTX *ctx) */ tmpsubject = X509_NAME_dup(tmpsubject); if (tmpsubject == NULL) { - X509err(X509_F_CHECK_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); ctx->error = X509_V_ERR_OUT_OF_MEM; - return 0; + return -1; } - tmpentry = - X509_NAME_delete_entry(tmpsubject, last_object_loc); - last_object_nid = - OBJ_obj2nid(X509_NAME_ENTRY_get_object(tmpentry)); + tmpentry = X509_NAME_delete_entry(tmpsubject, last_loc); + last_nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(tmpentry)); - if (last_object_nid != NID_commonName + if (last_nid != NID_commonName || X509_NAME_cmp(tmpsubject, tmpissuer) != 0) { err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; } @@ -689,10 +719,8 @@ static int check_name_constraints(X509_STORE_CTX *ctx) X509_NAME_ENTRY_free(tmpentry); X509_NAME_free(tmpsubject); - proxy_name_done: - if (err != X509_V_OK - && !verify_cb_cert(ctx, x, i, err)) - return 0; + proxy_name_done: + CB_FAIL_IF(err != X509_V_OK, ctx, x, i, err); } /* @@ -706,6 +734,7 @@ static int check_name_constraints(X509_STORE_CTX *ctx) if (nc) { int rv = NAME_CONSTRAINTS_check(x, nc); + int ret = 1; /* If EE certificate check commonName too */ if (rv == X509_V_OK && i == 0 @@ -713,17 +742,18 @@ static int check_name_constraints(X509_STORE_CTX *ctx) & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT) == 0 && ((ctx->param->hostflags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT) != 0 - || !has_san_id(x, GEN_DNS))) + || (ret = has_san_id(x, GEN_DNS)) == 0)) rv = NAME_CONSTRAINTS_check_CN(x, nc); + if (ret < 0) + return ret; switch (rv) { case X509_V_OK: break; case X509_V_ERR_OUT_OF_MEM: - return 0; + return -1; default: - if (!verify_cb_cert(ctx, x, i, rv)) - return 0; + CB_FAIL_IF(1, ctx, x, i, rv); break; } } @@ -759,24 +789,27 @@ static int check_id(X509_STORE_CTX *ctx) { X509_VERIFY_PARAM *vpm = ctx->param; X509 *x = ctx->cert; - if (vpm->hosts && check_hosts(x, vpm) <= 0) { + + if (vpm->hosts != NULL && check_hosts(x, vpm) <= 0) { if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) return 0; } - if (vpm->email && X509_check_email(x, vpm->email, vpm->emaillen, 0) <= 0) { + if (vpm->email != NULL + && X509_check_email(x, vpm->email, vpm->emaillen, 0) <= 0) { if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH)) return 0; } - if (vpm->ip && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) { + if (vpm->ip != NULL && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) { if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH)) return 0; } return 1; } +/* Returns -1 on internal error */ static int check_trust(X509_STORE_CTX *ctx, int num_untrusted) { - int i; + int i, res; X509 *x = NULL; X509 *mx; SSL_DANE *dane = ctx->dane; @@ -788,11 +821,9 @@ static int check_trust(X509_STORE_CTX *ctx, int num_untrusted) * match, we're done, otherwise we'll merely record the match depth. */ if (DANETLS_HAS_TA(dane) && num_untrusted > 0 && num_untrusted < num) { - switch (trust = check_dane_issuer(ctx, num_untrusted)) { - case X509_TRUST_TRUSTED: - case X509_TRUST_REJECTED: + trust = check_dane_issuer(ctx, num_untrusted); + if (trust != X509_TRUST_UNTRUSTED) return trust; - } } /* @@ -804,7 +835,7 @@ static int check_trust(X509_STORE_CTX *ctx, int num_untrusted) for (i = num_untrusted; i < num; i++) { x = sk_X509_value(ctx->chain, i); trust = X509_check_trust(x, ctx->param->trust, 0); - /* If explicitly trusted return trusted */ + /* If explicitly trusted (so not neutral nor rejected) return trusted */ if (trust == X509_TRUST_TRUSTED) goto trusted; if (trust == X509_TRUST_REJECTED) @@ -816,20 +847,23 @@ static int check_trust(X509_STORE_CTX *ctx, int num_untrusted) * the chain is PKIX trusted. */ if (num_untrusted < num) { - if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) + if ((ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) != 0) goto trusted; return X509_TRUST_UNTRUSTED; } - if (num_untrusted == num && ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { + if (num_untrusted == num + && (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) != 0) { /* * Last-resort call with no new trusted certificates, check the leaf * for a direct trust store match. */ i = 0; x = sk_X509_value(ctx->chain, i); - mx = lookup_cert_match(ctx, x); - if (!mx) + res = lookup_cert_match(&mx, ctx, x); + if (res < 0) + return res; + if (mx == NULL) return X509_TRUST_UNTRUSTED; /* @@ -843,7 +877,7 @@ static int check_trust(X509_STORE_CTX *ctx, int num_untrusted) } /* Replace leaf with trusted match */ - (void) sk_X509_set(ctx->chain, 0, mx); + (void)sk_X509_set(ctx->chain, 0, mx); X509_free(x); ctx->num_untrusted = 0; goto trusted; @@ -856,9 +890,8 @@ static int check_trust(X509_STORE_CTX *ctx, int num_untrusted) return X509_TRUST_UNTRUSTED; rejected: - if (!verify_cb_cert(ctx, x, i, X509_V_ERR_CERT_REJECTED)) - return X509_TRUST_REJECTED; - return X509_TRUST_UNTRUSTED; + return verify_cb_cert(ctx, x, i, X509_V_ERR_CERT_REJECTED) == 0 + ? X509_TRUST_REJECTED : X509_TRUST_UNTRUSTED; trusted: if (!DANETLS_ENABLED(dane)) @@ -871,14 +904,16 @@ static int check_trust(X509_STORE_CTX *ctx, int num_untrusted) return X509_TRUST_UNTRUSTED; } +/* Sadly, returns 0 also on internal error. */ static int check_revocation(X509_STORE_CTX *ctx) { int i = 0, last = 0, ok = 0; - if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) + + if ((ctx->param->flags & X509_V_FLAG_CRL_CHECK) == 0) return 1; - if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) + if ((ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) != 0) { last = sk_X509_num(ctx->chain) - 1; - else { + } else { /* If checking CRL paths this isn't the EE certificate */ if (ctx->parent) return 1; @@ -893,6 +928,7 @@ static int check_revocation(X509_STORE_CTX *ctx) return 1; } +/* Sadly, returns 0 also on internal error. */ static int check_cert(X509_STORE_CTX *ctx) { X509_CRL *crl = NULL, *dcrl = NULL; @@ -905,20 +941,18 @@ static int check_cert(X509_STORE_CTX *ctx) ctx->current_crl_score = 0; ctx->current_reasons = 0; - if (x->ex_flags & EXFLAG_PROXY) + if ((x->ex_flags & EXFLAG_PROXY) != 0) return 1; while (ctx->current_reasons != CRLDP_ALL_REASONS) { unsigned int last_reasons = ctx->current_reasons; /* Try to retrieve relevant CRL */ - if (ctx->get_crl) + if (ctx->get_crl != NULL) ok = ctx->get_crl(ctx, &crl, x); else ok = get_crl_delta(ctx, &crl, &dcrl, x); - /* - * If error looking up CRL, nothing we can do except notify callback - */ + /* If error looking up CRL, nothing we can do except notify callback */ if (!ok) { ok = verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL); goto done; @@ -928,15 +962,16 @@ static int check_cert(X509_STORE_CTX *ctx) if (!ok) goto done; - if (dcrl) { + if (dcrl != NULL) { ok = ctx->check_crl(ctx, dcrl); if (!ok) goto done; ok = ctx->cert_crl(ctx, dcrl, x); if (!ok) goto done; - } else + } else { ok = 1; + } /* Don't look in full CRL if delta reason is removefromCRL */ if (ok != 2) { @@ -967,15 +1002,14 @@ static int check_cert(X509_STORE_CTX *ctx) } /* Check CRL times against values in X509_STORE_CTX */ - static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) { time_t *ptime; int i; - if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + if ((ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) != 0) ptime = &ctx->param->check_time; - else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) + else if ((ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) != 0) return 1; else ptime = NULL; @@ -1006,11 +1040,9 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) if (!verify_cb_crl(ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD)) return 0; } - /* Ignore expiry of base CRL is delta is valid */ - if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { - if (!notify) - return 0; - if (!verify_cb_crl(ctx, X509_V_ERR_CRL_HAS_EXPIRED)) + /* Ignore expiration of base CRL is delta is valid */ + if (i < 0 && (ctx->current_crl_score & CRL_SCORE_TIME_DELTA) == 0) { + if (!notify || !verify_cb_crl(ctx, X509_V_ERR_CRL_HAS_EXPIRED)) return 0; } } @@ -1040,6 +1072,7 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, /* If current CRL is equivalent use it if it is newer */ if (crl_score == best_score && best_crl != NULL) { int day, sec; + if (ASN1_TIME_diff(&day, &sec, X509_CRL_get0_lastUpdate(best_crl), X509_CRL_get0_lastUpdate(crl)) == 0) continue; @@ -1056,7 +1089,7 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, best_reasons = reasons; } - if (best_crl) { + if (best_crl != NULL) { X509_CRL_free(*pcrl); *pcrl = best_crl; *pissuer = best_crl_issuer; @@ -1078,54 +1111,46 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, * Compare two CRL extensions for delta checking purposes. They should be * both present or both absent. If both present all fields must be identical. */ - static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) { - ASN1_OCTET_STRING *exta, *extb; - int i; - i = X509_CRL_get_ext_by_NID(a, nid, -1); + ASN1_OCTET_STRING *exta = NULL, *extb = NULL; + int i = X509_CRL_get_ext_by_NID(a, nid, -1); + if (i >= 0) { /* Can't have multiple occurrences */ if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) return 0; exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); - } else - exta = NULL; + } i = X509_CRL_get_ext_by_NID(b, nid, -1); - if (i >= 0) { - if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) return 0; extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); - } else - extb = NULL; + } - if (!exta && !extb) + if (exta == NULL && extb == NULL) return 1; - if (!exta || !extb) + if (exta == NULL || extb == NULL) return 0; - if (ASN1_OCTET_STRING_cmp(exta, extb)) - return 0; - - return 1; + return ASN1_OCTET_STRING_cmp(exta, extb) == 0; } /* See if a base and delta are compatible */ - static int check_delta_base(X509_CRL *delta, X509_CRL *base) { /* Delta CRL must be a delta */ - if (!delta->base_crl_number) + if (delta->base_crl_number == NULL) return 0; /* Base must have a CRL number */ - if (!base->crl_number) + if (base->crl_number == NULL) return 0; /* Issuer names must match */ - if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta))) + if (X509_NAME_cmp(X509_CRL_get_issuer(base), + X509_CRL_get_issuer(delta)) != 0) return 0; /* AKID and IDP must match */ if (!crl_extension_match(delta, base, NID_authority_key_identifier)) @@ -1136,24 +1161,22 @@ static int check_delta_base(X509_CRL *delta, X509_CRL *base) if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) return 0; /* Delta CRL number must exceed full CRL number */ - if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) - return 1; - return 0; + return ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0; } /* * For a given base CRL find a delta... maybe extend to delta scoring or * retrieve a chain of deltas... */ - static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, X509_CRL *base, STACK_OF(X509_CRL) *crls) { X509_CRL *delta; int i; - if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) + + if ((ctx->param->flags & X509_V_FLAG_USE_DELTAS) == 0) return; - if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) + if (((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST) == 0) return; for (i = 0; i < sk_X509_CRL_num(crls); i++) { delta = sk_X509_CRL_value(crls, i); @@ -1175,42 +1198,41 @@ static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, * also used to determine if the CRL is suitable: if no new reasons the CRL * is rejected, otherwise reasons is updated. */ - static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, unsigned int *preasons, X509_CRL *crl, X509 *x) { - int crl_score = 0; unsigned int tmp_reasons = *preasons, crl_reasons; /* First see if we can reject CRL straight away */ /* Invalid IDP cannot be processed */ - if (crl->idp_flags & IDP_INVALID) + if ((crl->idp_flags & IDP_INVALID) != 0) return 0; /* Reason codes or indirect CRLs need extended CRL support */ - if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { + if ((ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT) == 0) { if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) return 0; - } else if (crl->idp_flags & IDP_REASONS) { + } else if ((crl->idp_flags & IDP_REASONS) != 0) { /* If no new reasons reject */ - if (!(crl->idp_reasons & ~tmp_reasons)) + if ((crl->idp_reasons & ~tmp_reasons) == 0) return 0; } /* Don't process deltas at this stage */ - else if (crl->base_crl_number) + else if (crl->base_crl_number != NULL) return 0; /* If issuer name doesn't match certificate need indirect CRL */ - if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { - if (!(crl->idp_flags & IDP_INDIRECT)) + if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl)) != 0) { + if ((crl->idp_flags & IDP_INDIRECT) == 0) return 0; - } else + } else { crl_score |= CRL_SCORE_ISSUER_NAME; + } - if (!(crl->flags & EXFLAG_CRITICAL)) + if ((crl->flags & EXFLAG_CRITICAL) == 0) crl_score |= CRL_SCORE_NOCRITICAL; - /* Check expiry */ + /* Check expiration */ if (check_crl_time(ctx, crl, 0)) crl_score |= CRL_SCORE_TIME; @@ -1218,15 +1240,13 @@ static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, crl_akid_check(ctx, crl, pissuer, &crl_score); /* If we can't locate certificate issuer at this point forget it */ - - if (!(crl_score & CRL_SCORE_AKID)) + if ((crl_score & CRL_SCORE_AKID) == 0) return 0; /* Check cert for matching CRL distribution points */ - if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) { /* If no new reasons reject */ - if (!(crl_reasons & ~tmp_reasons)) + if ((crl_reasons & ~tmp_reasons) == 0) return 0; tmp_reasons |= crl_reasons; crl_score |= CRL_SCORE_SCOPE; @@ -1242,7 +1262,7 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, int *pcrl_score) { X509 *crl_issuer = NULL; - X509_NAME *cnm = X509_CRL_get_issuer(crl); + const X509_NAME *cnm = X509_CRL_get_issuer(crl); int cidx = ctx->error_depth; int i; @@ -1271,8 +1291,7 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, } /* Anything else needs extended CRL support */ - - if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) + if ((ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT) == 0) return; /* @@ -1281,7 +1300,7 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, */ for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { crl_issuer = sk_X509_value(ctx->untrusted, i); - if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm) != 0) continue; if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { *pissuer = crl_issuer; @@ -1297,16 +1316,15 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, * parent. This could be optimised somewhat since a lot of path checking will * be duplicated by the parent, but this will rarely be used in practice. */ - static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) { - X509_STORE_CTX crl_ctx; + X509_STORE_CTX crl_ctx = {0}; int ret; /* Don't allow recursive CRL path validation */ - if (ctx->parent) + if (ctx->parent != NULL) return 0; - if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) + if (!X509_STORE_CTX_init(&crl_ctx, ctx->store, x, ctx->untrusted)) return -1; crl_ctx.crls = ctx->crls; @@ -1331,22 +1349,19 @@ static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) /* * RFC3280 says nothing about the relationship between CRL path and * certificate path, which could lead to situations where a certificate could - * be revoked or validated by a CA not authorised to do so. RFC5280 is more + * be revoked or validated by a CA not authorized to do so. RFC5280 is more * strict and states that the two paths must end in the same trust anchor, * though some discussions remain... until this is resolved we use the * RFC5280 version */ - static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, STACK_OF(X509) *crl_path) { - X509 *cert_ta, *crl_ta; - cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); - crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); - if (!X509_cmp(cert_ta, crl_ta)) - return 1; - return 0; + X509 *cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); + X509 *crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); + + return X509_cmp(cert_ta, crl_ta) == 0; } /*- @@ -1356,32 +1371,29 @@ static int check_crl_chain(X509_STORE_CTX *ctx, * 3. Both are full names and compare two GENERAL_NAMES. * 4. One is NULL: automatic match. */ - static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) { X509_NAME *nm = NULL; GENERAL_NAMES *gens = NULL; GENERAL_NAME *gena, *genb; int i, j; - if (!a || !b) + + if (a == NULL || b == NULL) return 1; if (a->type == 1) { - if (!a->dpname) + if (a->dpname == NULL) return 0; /* Case 1: two X509_NAME */ if (b->type == 1) { - if (!b->dpname) - return 0; - if (!X509_NAME_cmp(a->dpname, b->dpname)) - return 1; - else + if (b->dpname == NULL) return 0; + return X509_NAME_cmp(a->dpname, b->dpname) == 0; } /* Case 2: set name and GENERAL_NAMES appropriately */ nm = a->dpname; gens = b->name.fullname; } else if (b->type == 1) { - if (!b->dpname) + if (b->dpname == NULL) return 0; /* Case 2: set name and GENERAL_NAMES appropriately */ gens = a->name.fullname; @@ -1389,12 +1401,12 @@ static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) } /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ - if (nm) { + if (nm != NULL) { for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { gena = sk_GENERAL_NAME_value(gens, i); if (gena->type != GEN_DIRNAME) continue; - if (!X509_NAME_cmp(nm, gena->d.directoryName)) + if (X509_NAME_cmp(nm, gena->d.directoryName) == 0) return 1; } return 0; @@ -1406,7 +1418,7 @@ static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) gena = sk_GENERAL_NAME_value(a->name.fullname, i); for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) { genb = sk_GENERAL_NAME_value(b->name.fullname, j); - if (!GENERAL_NAME_cmp(gena, genb)) + if (GENERAL_NAME_cmp(gena, genb) == 0) return 1; } } @@ -1418,56 +1430,57 @@ static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) { int i; - X509_NAME *nm = X509_CRL_get_issuer(crl); + const X509_NAME *nm = X509_CRL_get_issuer(crl); + /* If no CRLissuer return is successful iff don't need a match */ - if (!dp->CRLissuer) - return ! !(crl_score & CRL_SCORE_ISSUER_NAME); + if (dp->CRLissuer == NULL) + return (crl_score & CRL_SCORE_ISSUER_NAME) != 0; for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type != GEN_DIRNAME) continue; - if (!X509_NAME_cmp(gen->d.directoryName, nm)) + if (X509_NAME_cmp(gen->d.directoryName, nm) == 0) return 1; } return 0; } /* Check CRLDP and IDP */ - static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, unsigned int *preasons) { int i; - if (crl->idp_flags & IDP_ONLYATTR) + + if ((crl->idp_flags & IDP_ONLYATTR) != 0) return 0; - if (x->ex_flags & EXFLAG_CA) { - if (crl->idp_flags & IDP_ONLYUSER) + if ((x->ex_flags & EXFLAG_CA) != 0) { + if ((crl->idp_flags & IDP_ONLYUSER) != 0) return 0; } else { - if (crl->idp_flags & IDP_ONLYCA) + if ((crl->idp_flags & IDP_ONLYCA) != 0) return 0; } *preasons = crl->idp_reasons; for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); + if (crldp_check_crlissuer(dp, crl, crl_score)) { - if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) { + if (crl->idp == NULL + || idp_check_dp(dp->distpoint, crl->idp->distpoint)) { *preasons &= dp->dp_reasons; return 1; } } } - if ((!crl->idp || !crl->idp->distpoint) - && (crl_score & CRL_SCORE_ISSUER_NAME)) - return 1; - return 0; + return (crl->idp == NULL || crl->idp->distpoint == NULL) + && (crl_score & CRL_SCORE_ISSUER_NAME) != 0; } /* * Retrieve CRL corresponding to current certificate. If deltas enabled try * to find a delta CRL too */ - static int get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) { @@ -1477,7 +1490,7 @@ static int get_crl_delta(X509_STORE_CTX *ctx, unsigned int reasons; X509_CRL *crl = NULL, *dcrl = NULL; STACK_OF(X509_CRL) *skcrl; - X509_NAME *nm = X509_get_issuer_name(x); + const X509_NAME *nm = X509_get_issuer_name(x); reasons = ctx->current_reasons; ok = get_crl_sk(ctx, &crl, &dcrl, @@ -1486,11 +1499,10 @@ static int get_crl_delta(X509_STORE_CTX *ctx, goto done; /* Lookup CRLs from store */ - skcrl = ctx->lookup_crls(ctx, nm); /* If no CRLs found and a near match from get_crl_sk use that */ - if (!skcrl && crl) + if (skcrl == NULL && crl != NULL) goto done; get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); @@ -1499,7 +1511,7 @@ static int get_crl_delta(X509_STORE_CTX *ctx, done: /* If we got any kind of CRL use it and return success */ - if (crl) { + if (crl != NULL) { ctx->current_issuer = issuer; ctx->current_crl_score = crl_score; ctx->current_reasons = reasons; @@ -1518,18 +1530,18 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) int cnum = ctx->error_depth; int chnum = sk_X509_num(ctx->chain) - 1; - /* if we have an alternative CRL issuer cert use that */ - if (ctx->current_issuer) + /* If we have an alternative CRL issuer cert use that */ + if (ctx->current_issuer != NULL) { issuer = ctx->current_issuer; /* * Else find CRL issuer: if not last certificate then issuer is next * certificate in chain. */ - else if (cnum < chnum) + } else if (cnum < chnum) { issuer = sk_X509_value(ctx->chain, cnum + 1); - else { + } else { issuer = sk_X509_value(ctx->chain, chnum); - /* If not self signed, can't check signature */ + /* If not self-issued, can't check signature */ if (!ctx->check_issued(ctx, issuer, issuer) && !verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER)) return 0; @@ -1541,39 +1553,38 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) /* * Skip most tests for deltas because they have already been done */ - if (!crl->base_crl_number) { + if (crl->base_crl_number == NULL) { /* Check for cRLSign bit if keyUsage present */ - if ((issuer->ex_flags & EXFLAG_KUSAGE) && - !(issuer->ex_kusage & KU_CRL_SIGN) && + if ((issuer->ex_flags & EXFLAG_KUSAGE) != 0 && + (issuer->ex_kusage & KU_CRL_SIGN) == 0 && !verify_cb_crl(ctx, X509_V_ERR_KEYUSAGE_NO_CRL_SIGN)) return 0; - if (!(ctx->current_crl_score & CRL_SCORE_SCOPE) && + if ((ctx->current_crl_score & CRL_SCORE_SCOPE) == 0 && !verify_cb_crl(ctx, X509_V_ERR_DIFFERENT_CRL_SCOPE)) return 0; - if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH) && + if ((ctx->current_crl_score & CRL_SCORE_SAME_PATH) == 0 && check_crl_path(ctx, ctx->current_issuer) <= 0 && !verify_cb_crl(ctx, X509_V_ERR_CRL_PATH_VALIDATION_ERROR)) return 0; - if ((crl->idp_flags & IDP_INVALID) && + if ((crl->idp_flags & IDP_INVALID) != 0 && !verify_cb_crl(ctx, X509_V_ERR_INVALID_EXTENSION)) return 0; } - if (!(ctx->current_crl_score & CRL_SCORE_TIME) && + if ((ctx->current_crl_score & CRL_SCORE_TIME) == 0 && !check_crl_time(ctx, crl, 1)) return 0; /* Attempt to get issuer certificate public key */ ikey = X509_get0_pubkey(issuer); - - if (!ikey && + if (ikey == NULL && !verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)) return 0; - if (ikey) { + if (ikey != NULL) { int rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags); if (rv != X509_V_OK && !verify_cb_crl(ctx, rv)) @@ -1597,8 +1608,8 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) * was revoked. This has since been changed since critical extensions can * change the meaning of CRL entries. */ - if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) - && (crl->flags & EXFLAG_CRITICAL) && + if ((ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) == 0 + && (crl->flags & EXFLAG_CRITICAL) != 0 && !verify_cb_crl(ctx, X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION)) return 0; /* @@ -1632,21 +1643,15 @@ static int check_policy(X509_STORE_CTX *ctx) * was verified via a bare public key, and pop it off right after the * X509_policy_check() call. */ - if (ctx->bare_ta_signed && !sk_X509_push(ctx->chain, NULL)) { - X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - return 0; - } + if (ctx->bare_ta_signed && !sk_X509_push(ctx->chain, NULL)) + goto memerr; ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, ctx->param->policies, ctx->param->flags); if (ctx->bare_ta_signed) - sk_X509_pop(ctx->chain); + (void)sk_X509_pop(ctx->chain); - if (ret == X509_PCY_TREE_INTERNAL) { - X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - return 0; - } + if (ret == X509_PCY_TREE_INTERNAL) + goto memerr; /* Invalid or inconsistent extensions */ if (ret == X509_PCY_TREE_INVALID) { int i; @@ -1655,11 +1660,8 @@ static int check_policy(X509_STORE_CTX *ctx) for (i = 1; i < sk_X509_num(ctx->chain); i++) { X509 *x = sk_X509_value(ctx->chain, i); - if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) - continue; - if (!verify_cb_cert(ctx, x, i, - X509_V_ERR_INVALID_POLICY_EXTENSION)) - return 0; + CB_FAIL_IF((x->ex_flags & EXFLAG_INVALID_POLICY) != 0, + ctx, x, i, X509_V_ERR_INVALID_POLICY_EXTENSION); } return 1; } @@ -1669,11 +1671,11 @@ static int check_policy(X509_STORE_CTX *ctx) return ctx->verify_cb(0, ctx); } if (ret != X509_PCY_TREE_VALID) { - X509err(X509_F_CHECK_POLICY, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR); return 0; } - if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { + if ((ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) != 0) { ctx->current_cert = NULL; /* * Verification errors need to be "sticky", a callback may have allowed @@ -1686,6 +1688,11 @@ static int check_policy(X509_STORE_CTX *ctx) } return 1; + + memerr: + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + return -1; } /*- @@ -1695,14 +1702,14 @@ static int check_policy(X509_STORE_CTX *ctx) * * Return 1 on success, 0 otherwise. */ -int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) +int ossl_x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) { time_t *ptime; int i; - if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + if ((ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) != 0) ptime = &ctx->param->check_time; - else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) + else if ((ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) != 0) return 1; else ptime = NULL; @@ -1710,79 +1717,73 @@ int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) i = X509_cmp_time(X509_get0_notBefore(x), ptime); if (i >= 0 && depth < 0) return 0; - if (i == 0 && !verify_cb_cert(ctx, x, depth, - X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD)) - return 0; - if (i > 0 && !verify_cb_cert(ctx, x, depth, X509_V_ERR_CERT_NOT_YET_VALID)) - return 0; + CB_FAIL_IF(i == 0, ctx, x, depth, X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD); + CB_FAIL_IF(i > 0, ctx, x, depth, X509_V_ERR_CERT_NOT_YET_VALID); i = X509_cmp_time(X509_get0_notAfter(x), ptime); if (i <= 0 && depth < 0) return 0; - if (i == 0 && !verify_cb_cert(ctx, x, depth, - X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD)) - return 0; - if (i < 0 && !verify_cb_cert(ctx, x, depth, X509_V_ERR_CERT_HAS_EXPIRED)) - return 0; + CB_FAIL_IF(i == 0, ctx, x, depth, X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD); + CB_FAIL_IF(i < 0, ctx, x, depth, X509_V_ERR_CERT_HAS_EXPIRED); return 1; } -/* verify the issuer signatures and cert times of ctx->chain */ +/* + * Verify the issuer signatures and cert times of ctx->chain. + * Sadly, returns 0 also on internal error. + */ static int internal_verify(X509_STORE_CTX *ctx) { int n = sk_X509_num(ctx->chain) - 1; X509 *xi = sk_X509_value(ctx->chain, n); - X509 *xs; + X509 *xs = xi; - /* - * With DANE-verified bare public key TA signatures, it remains only to - * check the timestamps of the top certificate. We report the issuer as - * NULL, since all we have is a bare key. - */ + ctx->error_depth = n; if (ctx->bare_ta_signed) { - xs = xi; + /* + * With DANE-verified bare public key TA signatures, + * on the top certificate we check only the timestamps. + * We report the issuer as NULL because all we have is a bare key. + */ xi = NULL; - goto check_cert_time; - } - - if (ctx->check_issued(ctx, xi, xi)) - xs = xi; /* the typical case: last cert in the chain is self-issued */ - else { - if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { - xs = xi; - goto check_cert_time; - } - if (n <= 0) { - if (!verify_cb_cert(ctx, xi, 0, - X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)) - return 0; - - xs = xi; - goto check_cert_time; + } else if (ossl_x509_likely_issued(xi, xi) != X509_V_OK + /* exceptional case: last cert in the chain is not self-issued */ + && ((ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) == 0)) { + if (n > 0) { + n--; + ctx->error_depth = n; + xs = sk_X509_value(ctx->chain, n); + } else { + CB_FAIL_IF(1, ctx, xi, 0, + X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE); } - - n--; - ctx->error_depth = n; - xs = sk_X509_value(ctx->chain, n); + /* + * The below code will certainly not do a + * self-signature check on xi because it is not self-issued. + */ } /* - * Do not clear ctx->error=0, it must be "sticky", only the user's callback - * is allowed to reset errors (at its own peril). + * Do not clear error (by ctx->error = X509_V_OK), it must be "sticky", + * only the user's callback is allowed to reset errors (at its own peril). */ while (n >= 0) { - /* + /*- * For each iteration of this loop: * n is the subject depth * xs is the subject cert, for which the signature is to be checked - * xi is the supposed issuer cert containing the public key to use + * xi is NULL for DANE-verified bare public key TA signatures + * else the supposed issuer cert containing the public key to use * Initially xs == xi if the last cert in the chain is self-issued. - * - * Skip signature check for self-signed certificates unless explicitly + */ + /* + * Do signature check for self-signed certificates only if explicitly * asked for because it does not add any security and just wastes time. */ - if (xs != xi || ((ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE) - && (xi->ex_flags & EXFLAG_SS) != 0)) { + if (xi != NULL + && (xs != xi + || ((ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE) != 0 + && (xi->ex_flags & EXFLAG_SS) != 0))) { EVP_PKEY *pkey; /* * If the issuer's public key is not available or its key usage @@ -1795,8 +1796,8 @@ static int internal_verify(X509_STORE_CTX *ctx) * step (n) we must check any given key usage extension in a CA cert * when preparing the verification of a certificate issued by it. * According to https://tools.ietf.org/html/rfc5280#section-4.2.1.3 - * we must not verify a certifiate signature if the key usage of the - * CA certificate that issued the certificate prohibits signing. + * we must not verify a certificate signature if the key usage of + * the CA certificate that issued the certificate prohibits signing. * In case the 'issuing' certificate is the last in the chain and is * not a CA certificate but a 'self-issued' end-entity cert (i.e., * xs == xi && !(xi->ex_flags & EXFLAG_CA)) RFC 5280 does not apply @@ -1804,24 +1805,21 @@ static int internal_verify(X509_STORE_CTX *ctx) * we are free to ignore any key usage restrictions on such certs. */ int ret = xs == xi && (xi->ex_flags & EXFLAG_CA) == 0 - ? X509_V_OK : x509_signing_allowed(xi, xs); + ? X509_V_OK : ossl_x509_signing_allowed(xi, xs); - if (ret != X509_V_OK && !verify_cb_cert(ctx, xi, issuer_depth, ret)) - return 0; + CB_FAIL_IF(ret != X509_V_OK, ctx, xi, issuer_depth, ret); if ((pkey = X509_get0_pubkey(xi)) == NULL) { - ret = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; - if (!verify_cb_cert(ctx, xi, issuer_depth, ret)) - return 0; - } else if (X509_verify(xs, pkey) <= 0) { - ret = X509_V_ERR_CERT_SIGNATURE_FAILURE; - if (!verify_cb_cert(ctx, xs, n, ret)) - return 0; + CB_FAIL_IF(1, ctx, xi, issuer_depth, + X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY); + } else { + CB_FAIL_IF(X509_verify(xs, pkey) <= 0, + ctx, xs, n, X509_V_ERR_CERT_SIGNATURE_FAILURE); } } - check_cert_time: /* in addition to RFC 5280, do also for trusted (root) cert */ + /* In addition to RFC 5280 requirements do also for trust anchor cert */ /* Calls verify callback as needed */ - if (!x509_check_cert_time(ctx, xs, n)) + if (!ossl_x509_check_cert_time(ctx, xs, n)) return 0; /* @@ -1858,7 +1856,8 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) #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: * UTCTime: YYMMDDHHMMSSZ @@ -1888,7 +1887,7 @@ 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 (!ascii_isdigit(ctm->data[i])) + if (!ossl_ascii_isdigit(ctm->data[i])) return 0; } if (ctm->data[ctm->length - 1] != upper_z) @@ -1902,7 +1901,7 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) asn1_cmp_time = X509_time_adj(NULL, 0, cmp_time); if (asn1_cmp_time == NULL) goto err; - if (!ASN1_TIME_diff(&day, &sec, ctm, asn1_cmp_time)) + if (ASN1_TIME_diff(&day, &sec, ctm, asn1_cmp_time) == 0) goto err; /* @@ -1916,6 +1915,31 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) return ret; } +/* + * Return 0 if time should not be checked or reference time is in range, + * or else 1 if it is past the end, or -1 if it is before the start + */ +int X509_cmp_timeframe(const X509_VERIFY_PARAM *vpm, + const ASN1_TIME *start, const ASN1_TIME *end) +{ + time_t ref_time; + time_t *time = NULL; + unsigned long flags = vpm == NULL ? 0 : X509_VERIFY_PARAM_get_flags(vpm); + + if ((flags & X509_V_FLAG_USE_CHECK_TIME) != 0) { + ref_time = X509_VERIFY_PARAM_get_time(vpm); + time = &ref_time; + } else if ((flags & X509_V_FLAG_NO_CHECK_TIME) != 0) { + return 0; /* this means ok */ + } /* else reference time is the current time */ + + if (end != NULL && X509_cmp_time(end, time) < 0) + return 1; + if (start != NULL && X509_cmp_time(start, time) > 0) + return -1; + return 0; +} + ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) { return X509_time_adj(s, adj, NULL); @@ -1936,7 +1960,7 @@ ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, else time(&t); - if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) { + if (s != NULL && (s->flags & ASN1_STRING_FLAG_MSTRING) == 0) { if (s->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); if (s->type == V_ASN1_GENERALIZEDTIME) @@ -1945,87 +1969,92 @@ ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, return ASN1_TIME_adj(s, t, offset_day, offset_sec); } +/* Copy any missing public key parameters up the chain towards pkey */ int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) { EVP_PKEY *ktmp = NULL, *ktmp2; int i, j; - if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) + if (pkey != NULL && !EVP_PKEY_missing_parameters(pkey)) return 1; for (i = 0; i < sk_X509_num(chain); i++) { ktmp = X509_get0_pubkey(sk_X509_value(chain, i)); if (ktmp == NULL) { - X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, - X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); + ERR_raise(ERR_LIB_X509, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); return 0; } if (!EVP_PKEY_missing_parameters(ktmp)) break; + ktmp = NULL; } if (ktmp == NULL) { - X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, - X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); + ERR_raise(ERR_LIB_X509, X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); return 0; } /* first, populate the other certs */ for (j = i - 1; j >= 0; j--) { ktmp2 = X509_get0_pubkey(sk_X509_value(chain, j)); - EVP_PKEY_copy_parameters(ktmp2, ktmp); + if (!EVP_PKEY_copy_parameters(ktmp2, ktmp)) + return 0; } if (pkey != NULL) - EVP_PKEY_copy_parameters(pkey, ktmp); + return EVP_PKEY_copy_parameters(pkey, ktmp); return 1; } -/* Make a delta CRL as the diff between two full CRLs */ - +/* + * Make a delta CRL as the difference between two full CRLs. + * Sadly, returns NULL also on internal error. + */ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, EVP_PKEY *skey, const EVP_MD *md, unsigned int flags) { X509_CRL *crl = NULL; int i; + STACK_OF(X509_REVOKED) *revs = NULL; /* CRLs can't be delta already */ - if (base->base_crl_number || newer->base_crl_number) { - X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_ALREADY_DELTA); + if (base->base_crl_number != NULL || newer->base_crl_number != NULL) { + ERR_raise(ERR_LIB_X509, X509_R_CRL_ALREADY_DELTA); return NULL; } /* Base and new CRL must have a CRL number */ - if (!base->crl_number || !newer->crl_number) { - X509err(X509_F_X509_CRL_DIFF, X509_R_NO_CRL_NUMBER); + if (base->crl_number == NULL || newer->crl_number == NULL) { + ERR_raise(ERR_LIB_X509, X509_R_NO_CRL_NUMBER); return NULL; } /* Issuer names must match */ - if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) { - X509err(X509_F_X509_CRL_DIFF, X509_R_ISSUER_MISMATCH); + if (X509_NAME_cmp(X509_CRL_get_issuer(base), + X509_CRL_get_issuer(newer)) != 0) { + ERR_raise(ERR_LIB_X509, X509_R_ISSUER_MISMATCH); return NULL; } /* AKID and IDP must match */ if (!crl_extension_match(base, newer, NID_authority_key_identifier)) { - X509err(X509_F_X509_CRL_DIFF, X509_R_AKID_MISMATCH); + ERR_raise(ERR_LIB_X509, X509_R_AKID_MISMATCH); return NULL; } if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) { - X509err(X509_F_X509_CRL_DIFF, X509_R_IDP_MISMATCH); + ERR_raise(ERR_LIB_X509, X509_R_IDP_MISMATCH); return NULL; } /* Newer CRL number must exceed full CRL number */ if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) { - X509err(X509_F_X509_CRL_DIFF, X509_R_NEWER_CRL_NOT_NEWER); + ERR_raise(ERR_LIB_X509, X509_R_NEWER_CRL_NOT_NEWER); return NULL; } /* CRLs must verify */ - if (skey && (X509_CRL_verify(base, skey) <= 0 || - X509_CRL_verify(newer, skey) <= 0)) { - X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_VERIFY_FAILURE); + if (skey != NULL && (X509_CRL_verify(base, skey) <= 0 || + X509_CRL_verify(newer, skey) <= 0)) { + ERR_raise(ERR_LIB_X509, X509_R_CRL_VERIFY_FAILURE); return NULL; } /* Create new CRL */ - crl = X509_CRL_new(); - if (crl == NULL || !X509_CRL_set_version(crl, 1)) + crl = X509_CRL_new_ex(base->libctx, base->propq); + if (crl == NULL || !X509_CRL_set_version(crl, X509_CRL_VERSION_2)) goto memerr; /* Set issuer name */ if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer))) @@ -2037,7 +2066,6 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, goto memerr; /* Set base CRL number: must be critical */ - if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0)) goto memerr; @@ -2045,28 +2073,28 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, * Copy extensions across from newest CRL to delta: this will set CRL * number to correct value too. */ - for (i = 0; i < X509_CRL_get_ext_count(newer); i++) { - X509_EXTENSION *ext; - ext = X509_CRL_get_ext(newer, i); + X509_EXTENSION *ext = X509_CRL_get_ext(newer, i); + if (!X509_CRL_add_ext(crl, ext, -1)) goto memerr; } /* Go through revoked entries, copying as needed */ - revs = X509_CRL_get_REVOKED(newer); for (i = 0; i < sk_X509_REVOKED_num(revs); i++) { X509_REVOKED *rvn, *rvtmp; + rvn = sk_X509_REVOKED_value(revs, i); /* - * Add only if not also in base. TODO: need something cleverer here - * for some more complex CRLs covering multiple CAs. + * Add only if not also in base. + * Need something cleverer here for some more complex CRLs covering + * multiple CAs. */ if (!X509_CRL_get0_by_serial(base, &rvtmp, &rvn->serialNumber)) { rvtmp = X509_REVOKED_dup(rvn); - if (!rvtmp) + if (rvtmp == NULL) goto memerr; if (!X509_CRL_add0_revoked(crl, rvtmp)) { X509_REVOKED_free(rvtmp); @@ -2074,15 +2102,14 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, } } } - /* TODO: optionally prune deleted entries */ - if (skey && md && !X509_CRL_sign(crl, skey, md)) + if (skey != NULL && md != NULL && !X509_CRL_sign(crl, skey, md)) goto memerr; return crl; memerr: - X509err(X509_F_X509_CRL_DIFF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); X509_CRL_free(crl); return NULL; } @@ -2092,12 +2119,12 @@ int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); } -void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) +void *X509_STORE_CTX_get_ex_data(const X509_STORE_CTX *ctx, int idx) { return CRYPTO_get_ex_data(&ctx->ex_data, idx); } -int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) +int X509_STORE_CTX_get_error(const X509_STORE_CTX *ctx) { return ctx->error; } @@ -2107,7 +2134,7 @@ void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) ctx->error = err; } -int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) +int X509_STORE_CTX_get_error_depth(const X509_STORE_CTX *ctx) { return ctx->error_depth; } @@ -2117,7 +2144,7 @@ void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth) ctx->error_depth = depth; } -X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) +X509 *X509_STORE_CTX_get_current_cert(const X509_STORE_CTX *ctx) { return ctx->current_cert; } @@ -2127,29 +2154,29 @@ void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x) ctx->current_cert = x; } -STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx) +STACK_OF(X509) *X509_STORE_CTX_get0_chain(const X509_STORE_CTX *ctx) { return ctx->chain; } -STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) +STACK_OF(X509) *X509_STORE_CTX_get1_chain(const X509_STORE_CTX *ctx) { - if (!ctx->chain) + if (ctx->chain == NULL) return NULL; return X509_chain_up_ref(ctx->chain); } -X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) +X509 *X509_STORE_CTX_get0_current_issuer(const X509_STORE_CTX *ctx) { return ctx->current_issuer; } -X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) +X509_CRL *X509_STORE_CTX_get0_current_crl(const X509_STORE_CTX *ctx) { return ctx->current_crl; } -X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(const X509_STORE_CTX *ctx) { return ctx->parent; } @@ -2193,13 +2220,13 @@ int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) * application can set: if they aren't set then we use the default of SSL * client/server. */ - int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, int purpose, int trust) { int idx; + /* If purpose not set use default */ - if (!purpose) + if (purpose == 0) purpose = def_purpose; /* * If purpose is set but we don't have a default then set the default to @@ -2208,70 +2235,91 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, else if (def_purpose == 0) def_purpose = purpose; /* If we have a purpose then check it is valid */ - if (purpose) { + if (purpose != 0) { X509_PURPOSE *ptmp; + idx = X509_PURPOSE_get_by_id(purpose); if (idx == -1) { - X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, - X509_R_UNKNOWN_PURPOSE_ID); + ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_PURPOSE_ID); return 0; } ptmp = X509_PURPOSE_get0(idx); if (ptmp->trust == X509_TRUST_DEFAULT) { idx = X509_PURPOSE_get_by_id(def_purpose); if (idx == -1) { - X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, - X509_R_UNKNOWN_PURPOSE_ID); + ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_PURPOSE_ID); return 0; } ptmp = X509_PURPOSE_get0(idx); } /* If trust not set then get from purpose default */ - if (!trust) + if (trust == 0) trust = ptmp->trust; } - if (trust) { + if (trust != 0) { idx = X509_TRUST_get_by_id(trust); if (idx == -1) { - X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, - X509_R_UNKNOWN_TRUST_ID); + ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_TRUST_ID); return 0; } } - if (purpose && !ctx->param->purpose) + if (ctx->param->purpose == 0 && purpose != 0) ctx->param->purpose = purpose; - if (trust && !ctx->param->trust) + if (ctx->param->trust == 0 && trust != 0) ctx->param->trust = trust; return 1; } -X509_STORE_CTX *X509_STORE_CTX_new(void) +X509_STORE_CTX *X509_STORE_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { X509_STORE_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx == NULL) { - X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } + + ctx->libctx = libctx; + if (propq != NULL) { + ctx->propq = OPENSSL_strdup(propq); + if (ctx->propq == NULL) { + OPENSSL_free(ctx); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + } + return ctx; } +X509_STORE_CTX *X509_STORE_CTX_new(void) +{ + return X509_STORE_CTX_new_ex(NULL, NULL); +} + void X509_STORE_CTX_free(X509_STORE_CTX *ctx) { if (ctx == NULL) return; X509_STORE_CTX_cleanup(ctx); + + /* libctx and propq survive X509_STORE_CTX_cleanup() */ + OPENSSL_free(ctx->propq); OPENSSL_free(ctx); } int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain) { - int ret = 1; + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + X509_STORE_CTX_cleanup(ctx); - ctx->ctx = store; + ctx->store = store; ctx->cert = x509; ctx->untrusted = chain; ctx->crls = NULL; @@ -2279,7 +2327,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, ctx->other_ctx = NULL; ctx->valid = 0; ctx->chain = NULL; - ctx->error = 0; + ctx->error = X509_V_OK; ctx->explicit_policy = 0; ctx->error_depth = 0; ctx->current_cert = NULL; @@ -2295,88 +2343,80 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, memset(&ctx->ex_data, 0, sizeof(ctx->ex_data)); /* store->cleanup is always 0 in OpenSSL, if set must be idempotent */ - if (store) + if (store != NULL) ctx->cleanup = store->cleanup; else - ctx->cleanup = 0; + ctx->cleanup = NULL; - if (store && store->check_issued) + if (store != NULL && store->check_issued != NULL) ctx->check_issued = store->check_issued; else ctx->check_issued = check_issued; - if (store && store->get_issuer) + if (store != NULL && store->get_issuer != NULL) ctx->get_issuer = store->get_issuer; else ctx->get_issuer = X509_STORE_CTX_get1_issuer; - if (store && store->verify_cb) + if (store != NULL && store->verify_cb != NULL) ctx->verify_cb = store->verify_cb; else ctx->verify_cb = null_callback; - if (store && store->verify) + if (store != NULL && store->verify != NULL) ctx->verify = store->verify; else ctx->verify = internal_verify; - if (store && store->check_revocation) + if (store != NULL && store->check_revocation != NULL) ctx->check_revocation = store->check_revocation; else ctx->check_revocation = check_revocation; - if (store && store->get_crl) + if (store != NULL && store->get_crl != NULL) ctx->get_crl = store->get_crl; else ctx->get_crl = NULL; - if (store && store->check_crl) + if (store != NULL && store->check_crl != NULL) ctx->check_crl = store->check_crl; else ctx->check_crl = check_crl; - if (store && store->cert_crl) + if (store != NULL && store->cert_crl != NULL) ctx->cert_crl = store->cert_crl; else ctx->cert_crl = cert_crl; - if (store && store->check_policy) + if (store != NULL && store->check_policy != NULL) ctx->check_policy = store->check_policy; else ctx->check_policy = check_policy; - if (store && store->lookup_certs) + if (store != NULL && store->lookup_certs != NULL) ctx->lookup_certs = store->lookup_certs; else ctx->lookup_certs = X509_STORE_CTX_get1_certs; - if (store && store->lookup_crls) + if (store != NULL && store->lookup_crls != NULL) ctx->lookup_crls = store->lookup_crls; else ctx->lookup_crls = X509_STORE_CTX_get1_crls; ctx->param = X509_VERIFY_PARAM_new(); if (ctx->param == NULL) { - X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } - /* - * Inherit callbacks and flags from X509_STORE if not set use defaults. - */ - if (store) - ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param); - else + /* Inherit callbacks and flags from X509_STORE if not set use defaults. */ + if (store == NULL) ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE; + else if (X509_VERIFY_PARAM_inherit(ctx->param, store->param) == 0) + goto err; - if (ret) - ret = X509_VERIFY_PARAM_inherit(ctx->param, - X509_VERIFY_PARAM_lookup("default")); - - if (ret == 0) { - X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + if (!X509_STORE_CTX_set_default(ctx, "default")) goto err; - } /* * XXX: For now, continue to inherit trust from VPM, but infer from the @@ -2393,7 +2433,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &ctx->ex_data)) return 1; - X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); err: /* @@ -2405,8 +2445,8 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, } /* - * Set alternative lookup method: just a STACK of trusted certificates. This - * avoids X509_STORE nastiness where it isn't needed. + * Set alternative get_issuer method: just from a STACK of trusted certificates. + * This avoids the complexity of X509_STORE where it is not needed. */ void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) { @@ -2423,7 +2463,7 @@ void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) * calls cleanup() for the same object twice! Thus we must zero the * pointers below after they're freed! */ - /* Seems to always be 0 in OpenSSL, do this at most once. */ + /* Seems to always be NULL in OpenSSL, do this at most once. */ if (ctx->cleanup != NULL) { ctx->cleanup(ctx); ctx->cleanup = NULL; @@ -2457,12 +2497,12 @@ void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, X509_VERIFY_PARAM_set_time(ctx->param, t); } -X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) +X509 *X509_STORE_CTX_get0_cert(const X509_STORE_CTX *ctx) { return ctx->cert; } -STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) +STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(const X509_STORE_CTX *ctx) { return ctx->untrusted; } @@ -2484,7 +2524,7 @@ void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, ctx->verify_cb = verify_cb; } -X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx) +X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(const X509_STORE_CTX *ctx) { return ctx->verify_cb; } @@ -2495,72 +2535,80 @@ void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, ctx->verify = verify; } -X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx) +X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(const X509_STORE_CTX *ctx) { return ctx->verify; } -X509_STORE_CTX_get_issuer_fn X509_STORE_CTX_get_get_issuer(X509_STORE_CTX *ctx) +X509_STORE_CTX_get_issuer_fn +X509_STORE_CTX_get_get_issuer(const X509_STORE_CTX *ctx) { return ctx->get_issuer; } -X509_STORE_CTX_check_issued_fn X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx) +X509_STORE_CTX_check_issued_fn +X509_STORE_CTX_get_check_issued(const X509_STORE_CTX *ctx) { return ctx->check_issued; } -X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(X509_STORE_CTX *ctx) +X509_STORE_CTX_check_revocation_fn +X509_STORE_CTX_get_check_revocation(const X509_STORE_CTX *ctx) { return ctx->check_revocation; } -X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(X509_STORE_CTX *ctx) +X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(const X509_STORE_CTX *ctx) { return ctx->get_crl; } -X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(X509_STORE_CTX *ctx) +X509_STORE_CTX_check_crl_fn +X509_STORE_CTX_get_check_crl(const X509_STORE_CTX *ctx) { return ctx->check_crl; } -X509_STORE_CTX_cert_crl_fn X509_STORE_CTX_get_cert_crl(X509_STORE_CTX *ctx) +X509_STORE_CTX_cert_crl_fn +X509_STORE_CTX_get_cert_crl(const X509_STORE_CTX *ctx) { return ctx->cert_crl; } -X509_STORE_CTX_check_policy_fn X509_STORE_CTX_get_check_policy(X509_STORE_CTX *ctx) +X509_STORE_CTX_check_policy_fn +X509_STORE_CTX_get_check_policy(const X509_STORE_CTX *ctx) { return ctx->check_policy; } -X509_STORE_CTX_lookup_certs_fn X509_STORE_CTX_get_lookup_certs(X509_STORE_CTX *ctx) +X509_STORE_CTX_lookup_certs_fn +X509_STORE_CTX_get_lookup_certs(const X509_STORE_CTX *ctx) { return ctx->lookup_certs; } -X509_STORE_CTX_lookup_crls_fn X509_STORE_CTX_get_lookup_crls(X509_STORE_CTX *ctx) +X509_STORE_CTX_lookup_crls_fn +X509_STORE_CTX_get_lookup_crls(const X509_STORE_CTX *ctx) { return ctx->lookup_crls; } -X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(X509_STORE_CTX *ctx) +X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(const X509_STORE_CTX *ctx) { return ctx->cleanup; } -X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(const X509_STORE_CTX *ctx) { return ctx->tree; } -int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) +int X509_STORE_CTX_get_explicit_policy(const X509_STORE_CTX *ctx) { return ctx->explicit_policy; } -int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx) +int X509_STORE_CTX_get_num_untrusted(const X509_STORE_CTX *ctx) { return ctx->num_untrusted; } @@ -2568,13 +2616,16 @@ int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx) int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) { const X509_VERIFY_PARAM *param; + param = X509_VERIFY_PARAM_lookup(name); - if (!param) + if (param == NULL) { + ERR_raise_data(ERR_LIB_X509, X509_R_UNKNOWN_PURPOSE_ID, "name=%s", name); return 0; + } return X509_VERIFY_PARAM_inherit(ctx->param, param); } -X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(const X509_STORE_CTX *ctx) { return ctx->param; } @@ -2590,10 +2641,8 @@ void X509_STORE_CTX_set0_dane(X509_STORE_CTX *ctx, SSL_DANE *dane) ctx->dane = dane; } -static unsigned char *dane_i2d( - X509 *cert, - uint8_t selector, - unsigned int *i2dlen) +static unsigned char *dane_i2d(X509 *cert, uint8_t selector, + unsigned int *i2dlen) { unsigned char *buf = NULL; int len; @@ -2609,12 +2658,12 @@ static unsigned char *dane_i2d( len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &buf); break; default: - X509err(X509_F_DANE_I2D, X509_R_BAD_SELECTOR); + ERR_raise(ERR_LIB_X509, X509_R_BAD_SELECTOR); return NULL; } if (len < 0 || buf == NULL) { - X509err(X509_F_DANE_I2D, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } @@ -2622,8 +2671,9 @@ static unsigned char *dane_i2d( return buf; } -#define DANETLS_NONE 256 /* impossible uint8_t */ +#define DANETLS_NONE 256 /* impossible uint8_t */ +/* Returns -1 on internal error */ static int dane_match(X509_STORE_CTX *ctx, X509 *cert, int depth) { SSL_DANE *dane = ctx->dane; @@ -2644,9 +2694,7 @@ static int dane_match(X509_STORE_CTX *ctx, X509 *cert, int depth) mask = (depth == 0) ? DANETLS_EE_MASK : DANETLS_TA_MASK; - /* - * The trust store is not applicable with DANE-TA(2) - */ + /* The trust store is not applicable with DANE-TA(2) */ if (depth >= ctx->num_untrusted) mask &= DANETLS_PKIX_MASK; @@ -2686,7 +2734,7 @@ static int dane_match(X509_STORE_CTX *ctx, X509 *cert, int depth) * exhausting all DANE-?? records, we've matched a PKIX-?? record, which is * sufficient for DANE, and what remains to do is ordinary PKIX validation. */ - recnum = (dane->umask & mask) ? sk_danetls_record_num(dane->trecs) : 0; + recnum = (dane->umask & mask) != 0 ? sk_danetls_record_num(dane->trecs) : 0; for (i = 0; matched == 0 && i < recnum; ++i) { t = sk_danetls_record_value(dane->trecs, i); if ((DANETLS_USAGE_BIT(t->usage) & mask) == 0) @@ -2730,6 +2778,7 @@ static int dane_match(X509_STORE_CTX *ctx, X509 *cert, int depth) */ if (t->mtype != mtype) { const EVP_MD *md = dane->dctx->mdevp[mtype = t->mtype]; + cmpbuf = i2dbuf; cmplen = i2dlen; @@ -2767,6 +2816,7 @@ static int dane_match(X509_STORE_CTX *ctx, X509 *cert, int depth) return matched; } +/* Returns -1 on internal error */ static int check_dane_issuer(X509_STORE_CTX *ctx, int depth) { SSL_DANE *dane = ctx->dane; @@ -2774,22 +2824,22 @@ static int check_dane_issuer(X509_STORE_CTX *ctx, int depth) X509 *cert; if (!DANETLS_HAS_TA(dane) || depth == 0) - return X509_TRUST_UNTRUSTED; + return X509_TRUST_UNTRUSTED; /* - * Record any DANE trust-anchor matches, for the first depth to test, if + * Record any DANE trust anchor matches, for the first depth to test, if * there's one at that depth. (This'll be false for length 1 chains looking * for an exact match for the leaf certificate). */ cert = sk_X509_value(ctx->chain, depth); if (cert != NULL && (matched = dane_match(ctx, cert, depth)) < 0) - return X509_TRUST_REJECTED; + return matched; if (matched > 0) { ctx->num_untrusted = depth - 1; - return X509_TRUST_TRUSTED; + return X509_TRUST_TRUSTED; } - return X509_TRUST_UNTRUSTED; + return X509_TRUST_UNTRUSTED; } static int check_dane_pkeys(X509_STORE_CTX *ctx) @@ -2831,9 +2881,7 @@ static int check_dane_pkeys(X509_STORE_CTX *ctx) static void dane_reset(SSL_DANE *dane) { - /* - * Reset state to verify another chain, or clear after failure. - */ + /* Reset state to verify another chain, or clear after failure. */ X509_free(dane->mcert); dane->mcert = NULL; dane->mtlsa = NULL; @@ -2845,11 +2893,11 @@ static int check_leaf_suiteb(X509_STORE_CTX *ctx, X509 *cert) { int err = X509_chain_check_suiteb(NULL, cert, NULL, ctx->param->flags); - if (err == X509_V_OK) - return 1; - return verify_cb_cert(ctx, cert, 0, err); + CB_FAIL_IF(err != X509_V_OK, ctx, cert, 0, err); + return 1; } +/* Returns -1 on internal error */ static int dane_verify(X509_STORE_CTX *ctx) { X509 *cert = ctx->cert; @@ -2863,7 +2911,7 @@ static int dane_verify(X509_STORE_CTX *ctx) * When testing the leaf certificate, if we match a DANE-EE(3) record, * dane_match() returns 1 and we're done. If however we match a PKIX-EE(1) * record, the match depth and matching TLSA record are recorded, but the - * return value is 0, because we still need to find a PKIX trust-anchor. + * return value is 0, because we still need to find a PKIX trust anchor. * Therefore, when DANE authentication is enabled (required), we're done * if: * + matched < 0, internal error. @@ -2874,8 +2922,8 @@ static int dane_verify(X509_STORE_CTX *ctx) matched = dane_match(ctx, ctx->cert, 0); done = matched != 0 || (!DANETLS_HAS_TA(dane) && dane->mdpth < 0); - if (done) - X509_get_pubkey_parameters(NULL, ctx->chain); + if (done && !X509_get_pubkey_parameters(NULL, ctx->chain)) + return -1; if (matched > 0) { /* Callback invoked as needed */ @@ -2912,8 +2960,11 @@ static int dane_verify(X509_STORE_CTX *ctx) return verify_chain(ctx); } -/* Get issuer, without duplicate suppression */ -static int get_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *cert) +/* + * Get trusted issuer, without duplicate suppression + * Returns -1 on internal error. + */ +static int get1_trusted_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *cert) { STACK_OF(X509) *saved_chain = ctx->chain; int ok; @@ -2925,118 +2976,89 @@ static int get_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *cert) return ok; } -static int augment_stack(STACK_OF(X509) *src, STACK_OF(X509) **dstPtr) -{ - if (src) { - STACK_OF(X509) *dst; - int i; - - if (*dstPtr == NULL) - return ((*dstPtr = sk_X509_dup(src)) != NULL); - - for (dst = *dstPtr, i = 0; i < sk_X509_num(src); ++i) { - if (!sk_X509_push(dst, sk_X509_value(src, i))) { - sk_X509_free(dst); - *dstPtr = NULL; - return 0; - } - } - } - return 1; -} - +/* Returns -1 on internal error */ static int build_chain(X509_STORE_CTX *ctx) { SSL_DANE *dane = ctx->dane; int num = sk_X509_num(ctx->chain); - X509 *cert = sk_X509_value(ctx->chain, num - 1); - int ss = cert_self_signed(cert); - STACK_OF(X509) *sktmp = NULL; + STACK_OF(X509) *sk_untrusted = NULL; unsigned int search; int may_trusted = 0; int may_alternate = 0; int trust = X509_TRUST_UNTRUSTED; int alt_untrusted = 0; - int depth; + int max_depth; int ok = 0; int i; /* Our chain starts with a single untrusted element. */ - if (!ossl_assert(num == 1 && ctx->num_untrusted == num)) { - X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR); - ctx->error = X509_V_ERR_UNSPECIFIED; - return 0; - } + if (!ossl_assert(num == 1 && ctx->num_untrusted == num)) + goto int_err; -#define S_DOUNTRUSTED (1 << 0) /* Search untrusted chain */ -#define S_DOTRUSTED (1 << 1) /* Search trusted store */ -#define S_DOALTERNATE (1 << 2) /* Retry with pruned alternate chain */ +#define S_DOUNTRUSTED (1 << 0) /* Search untrusted chain */ +#define S_DOTRUSTED (1 << 1) /* Search trusted store */ +#define S_DOALTERNATE (1 << 2) /* Retry with pruned alternate chain */ /* - * Set up search policy, untrusted if possible, trusted-first if enabled. + * Set up search policy, untrusted if possible, trusted-first if enabled, + * which is the default. * If we're doing DANE and not doing PKIX-TA/PKIX-EE, we never look in the * trust_store, otherwise we might look there first. If not trusted-first, * and alternate chains are not disabled, try building an alternate chain * if no luck with untrusted first. */ - search = (ctx->untrusted != NULL) ? S_DOUNTRUSTED : 0; + search = ctx->untrusted != NULL ? S_DOUNTRUSTED : 0; if (DANETLS_HAS_PKIX(dane) || !DANETLS_HAS_DANE(dane)) { - if (search == 0 || ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) + if (search == 0 || (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) != 0) search |= S_DOTRUSTED; else if (!(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) may_alternate = 1; may_trusted = 1; } + /* Initialize empty untrusted stack. */ + if ((sk_untrusted = sk_X509_new_null()) == NULL) + goto memerr; + /* - * If we got any "Cert(0) Full(0)" issuer certificates from DNS, *prepend* - * them to our working copy of the untrusted certificate stack. Since the - * caller of X509_STORE_CTX_init() may have provided only a leaf cert with - * no corresponding stack of untrusted certificates, we may need to create - * an empty stack first. [ At present only the ssl library provides DANE - * support, and ssl_verify_cert_chain() always provides a non-null stack - * containing at least the leaf certificate, but we must be prepared for - * this to change. ] + * If we got any "Cert(0) Full(0)" trust anchors from DNS, *prepend* them + * to our working copy of the untrusted certificate stack. */ - if (DANETLS_ENABLED(dane) && !augment_stack(dane->certs, &sktmp)) { - X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - return 0; - } + if (DANETLS_ENABLED(dane) && dane->certs != NULL + && !X509_add_certs(sk_untrusted, dane->certs, X509_ADD_FLAG_DEFAULT)) + goto memerr; /* * Shallow-copy the stack of untrusted certificates (with TLS, this is - * typically the content of the peer's certificate message) so can make + * typically the content of the peer's certificate message) so we can make * multiple passes over it, while free to remove elements as we go. */ - if (!augment_stack(ctx->untrusted, &sktmp)) { - X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - return 0; - } + if (!X509_add_certs(sk_untrusted, ctx->untrusted, X509_ADD_FLAG_DEFAULT)) + goto memerr; /* * Still absurdly large, but arithmetically safe, a lower hard upper bound * might be reasonable. */ - if (ctx->param->depth > INT_MAX/2) - ctx->param->depth = INT_MAX/2; + if (ctx->param->depth > INT_MAX / 2) + ctx->param->depth = INT_MAX / 2; /* - * Try to Extend the chain until we reach an ultimately trusted issuer. + * Try to extend the chain until we reach an ultimately trusted issuer. * Build chains up to one longer the limit, later fail if we hit the limit, * with an X509_V_ERR_CERT_CHAIN_TOO_LONG error code. */ - depth = ctx->param->depth + 1; + max_depth = ctx->param->depth + 1; while (search != 0) { - X509 *x; - X509 *xtmp = NULL; + X509 *curr, *issuer = NULL; + num = sk_X509_num(ctx->chain); + ctx->error_depth = num - 1; /* * Look in the trust store if enabled for first lookup, or we've run * out of untrusted issuers and search here is not disabled. When we * reach the depth limit, we stop extending the chain, if by that point - * we've not found a trust-anchor, any trusted chain would be too long. + * we've not found a trust anchor, any trusted chain would be too long. * * The error reported to the application verify callback is at the * maximal valid depth with the current certificate equal to the last @@ -3047,7 +3069,7 @@ static int build_chain(X509_STORE_CTX *ctx) * would be a-priori too long. */ if ((search & S_DOTRUSTED) != 0) { - i = num = sk_X509_num(ctx->chain); + i = num; if ((search & S_DOALTERNATE) != 0) { /* * As high up the chain as we can, look for an alternative @@ -3066,24 +3088,30 @@ static int build_chain(X509_STORE_CTX *ctx) */ i = alt_untrusted; } - x = sk_X509_value(ctx->chain, i-1); + curr = sk_X509_value(ctx->chain, i - 1); - ok = (depth < num) ? 0 : get_issuer(&xtmp, ctx, x); + /* Note: get1_trusted_issuer() must be used even if self-signed. */ + ok = num > max_depth ? 0 : get1_trusted_issuer(&issuer, ctx, curr); if (ok < 0) { - trust = X509_TRUST_REJECTED; + trust = -1; ctx->error = X509_V_ERR_STORE_LOOKUP; - search = 0; - continue; + break; } if (ok > 0) { + int self_signed = X509_self_signed(curr, 0); + + if (self_signed < 0) { + X509_free(issuer); + goto int_err; + } /* * Alternative trusted issuer for a mid-chain untrusted cert? * Pop the untrusted cert's successors and retry. We might now * be able to complete a valid chain via the trust store. Note - * that despite the current trust-store match we might still - * fail complete the chain to a suitable trust-anchor, in which + * that despite the current trust store match we might still + * fail complete the chain to a suitable trust anchor, in which * case we may prune some more untrusted certificates and try * again. Thus the S_DOALTERNATE bit may yet be turned on * again with an even shorter untrusted chain! @@ -3093,13 +3121,9 @@ static int build_chain(X509_STORE_CTX *ctx) * certificate among the ones from the trust store. */ if ((search & S_DOALTERNATE) != 0) { - if (!ossl_assert(num > i && i > 0 && ss == 0)) { - X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR); - X509_free(xtmp); - trust = X509_TRUST_REJECTED; - ctx->error = X509_V_ERR_UNSPECIFIED; - search = 0; - continue; + if (!ossl_assert(num > i && i > 0 && !self_signed)) { + X509_free(issuer); + goto int_err; } search &= ~S_DOALTERNATE; for (; num > i; --num) @@ -3121,36 +3145,33 @@ static int build_chain(X509_STORE_CTX *ctx) * Self-signed untrusted certificates get replaced by their * trusted matching issuer. Otherwise, grow the chain. */ - if (ss == 0) { - if (!sk_X509_push(ctx->chain, x = xtmp)) { - X509_free(xtmp); - X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); - trust = X509_TRUST_REJECTED; - ctx->error = X509_V_ERR_OUT_OF_MEM; - search = 0; - continue; + if (!self_signed) { + if (!sk_X509_push(ctx->chain, issuer)) { + X509_free(issuer); + goto memerr; } - ss = cert_self_signed(x); - } else if (num == ctx->num_untrusted) { + if ((self_signed = X509_self_signed(issuer, 0)) < 0) + goto int_err; + } else { /* * We have a self-signed certificate that has the same * subject name (and perhaps keyid and/or serial number) as - * a trust-anchor. We must have an exact match to avoid + * a trust anchor. We must have an exact match to avoid * possible impersonation via key substitution etc. */ - if (X509_cmp(x, xtmp) != 0) { + if (X509_cmp(curr, issuer) != 0) { /* Self-signed untrusted mimic. */ - X509_free(xtmp); + X509_free(issuer); ok = 0; - } else { - X509_free(x); + } else { /* curr "==" issuer */ + X509_free(curr); ctx->num_untrusted = --num; - (void) sk_X509_set(ctx->chain, num, x = xtmp); + (void)sk_X509_set(ctx->chain, num, issuer); } } /* - * We've added a new trusted certificate to the chain, recheck + * We've added a new trusted certificate to the chain, re-check * trust. If not done, and not self-signed look deeper. * Whether or not we're doing "trusted first", we no longer * look for untrusted certificates from the peer's chain. @@ -3163,21 +3184,13 @@ static int build_chain(X509_STORE_CTX *ctx) * certificate with ctx->num_untrusted <= num. */ if (ok) { - if (!ossl_assert(ctx->num_untrusted <= num)) { - X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR); - trust = X509_TRUST_REJECTED; - ctx->error = X509_V_ERR_UNSPECIFIED; - search = 0; - continue; - } + if (!ossl_assert(ctx->num_untrusted <= num)) + goto int_err; search &= ~S_DOUNTRUSTED; - switch (trust = check_trust(ctx, num)) { - case X509_TRUST_TRUSTED: - case X509_TRUST_REJECTED: - search = 0; - continue; - } - if (ss == 0) + trust = check_trust(ctx, num); + if (trust != X509_TRUST_UNTRUSTED) + break; + if (!self_signed) continue; } } @@ -3199,30 +3212,25 @@ static int build_chain(X509_STORE_CTX *ctx) /* Search for a trusted issuer of a shorter chain */ search |= S_DOALTERNATE; alt_untrusted = ctx->num_untrusted - 1; - ss = 0; } } /* - * Extend chain with peer-provided certificates + * Extend chain with peer-provided untrusted certificates */ if ((search & S_DOUNTRUSTED) != 0) { num = sk_X509_num(ctx->chain); - if (!ossl_assert(num == ctx->num_untrusted)) { - X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR); - trust = X509_TRUST_REJECTED; - ctx->error = X509_V_ERR_UNSPECIFIED; - search = 0; - continue; - } - x = sk_X509_value(ctx->chain, num-1); - - /* - * Once we run out of untrusted issuers, we stop looking for more - * and start looking only in the trust store if enabled. - */ - xtmp = (ss || depth < num) ? NULL : find_issuer(ctx, sktmp, x); - if (xtmp == NULL) { + if (!ossl_assert(num == ctx->num_untrusted)) + goto int_err; + curr = sk_X509_value(ctx->chain, num - 1); + issuer = (X509_self_signed(curr, 0) > 0 || num > max_depth) ? + NULL : find_issuer(ctx, sk_untrusted, curr); + if (issuer == NULL) { + /* + * Once we have reached a self-signed cert or num > max_depth + * or can't find an issuer in the untrusted list we stop looking + * there and start looking only in the trust store if enabled. + */ search &= ~S_DOUNTRUSTED; if (may_trusted) search |= S_DOTRUSTED; @@ -3230,48 +3238,30 @@ static int build_chain(X509_STORE_CTX *ctx) } /* Drop this issuer from future consideration */ - (void) sk_X509_delete_ptr(sktmp, xtmp); - - if (!X509_up_ref(xtmp)) { - X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR); - trust = X509_TRUST_REJECTED; - ctx->error = X509_V_ERR_UNSPECIFIED; - search = 0; - continue; - } + (void)sk_X509_delete_ptr(sk_untrusted, issuer); - if (!sk_X509_push(ctx->chain, xtmp)) { - X509_free(xtmp); - X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); - trust = X509_TRUST_REJECTED; - ctx->error = X509_V_ERR_OUT_OF_MEM; - search = 0; - continue; - } + if (!X509_add_cert(ctx->chain, issuer, X509_ADD_FLAG_UP_REF)) + goto int_err; - x = xtmp; ++ctx->num_untrusted; - ss = cert_self_signed(xtmp); - /* - * Check for DANE-TA trust of the topmost untrusted certificate. - */ - switch (trust = check_dane_issuer(ctx, ctx->num_untrusted - 1)) { - case X509_TRUST_TRUSTED: - case X509_TRUST_REJECTED: - search = 0; - continue; - } + /* Check for DANE-TA trust of the topmost untrusted certificate. */ + trust = check_dane_issuer(ctx, ctx->num_untrusted - 1); + if (trust == X509_TRUST_TRUSTED || trust == X509_TRUST_REJECTED) + break; } } - sk_X509_free(sktmp); + sk_X509_free(sk_untrusted); + + if (trust < 0) /* internal error */ + return trust; /* * Last chance to make a trusted chain, either bare DANE-TA public-key * signers, or else direct leaf PKIX trust. */ num = sk_X509_num(ctx->chain); - if (num <= depth) { + if (num <= max_depth) { if (trust == X509_TRUST_UNTRUSTED && DANETLS_HAS_DANE_TA(dane)) trust = check_dane_pkeys(ctx); if (trust == X509_TRUST_UNTRUSTED && num == ctx->num_untrusted) @@ -3286,34 +3276,97 @@ static int build_chain(X509_STORE_CTX *ctx) return 0; case X509_TRUST_UNTRUSTED: default: - num = sk_X509_num(ctx->chain); - if (num > depth) - return verify_cb_cert(ctx, NULL, num-1, - X509_V_ERR_CERT_CHAIN_TOO_LONG); - if (DANETLS_ENABLED(dane) && - (!DANETLS_HAS_PKIX(dane) || dane->pdpth >= 0)) - return verify_cb_cert(ctx, NULL, num-1, X509_V_ERR_DANE_NO_MATCH); - if (ss && sk_X509_num(ctx->chain) == 1) - return verify_cb_cert(ctx, NULL, num-1, - X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT); - if (ss) - return verify_cb_cert(ctx, NULL, num-1, - X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN); - if (ctx->num_untrusted < num) - return verify_cb_cert(ctx, NULL, num-1, - X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT); - return verify_cb_cert(ctx, NULL, num-1, - X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY); + switch(ctx->error) { + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + case X509_V_ERR_CERT_HAS_EXPIRED: + return 0; /* Callback already issued by ossl_x509_check_cert_time() */ + default: /* A preliminary error has become final */ + return verify_cb_cert(ctx, NULL, num - 1, ctx->error); + case X509_V_OK: + break; + } + CB_FAIL_IF(num > max_depth, + ctx, NULL, num - 1, X509_V_ERR_CERT_CHAIN_TOO_LONG); + CB_FAIL_IF(DANETLS_ENABLED(dane) + && (!DANETLS_HAS_PKIX(dane) || dane->pdpth >= 0), + ctx, NULL, num - 1, X509_V_ERR_DANE_NO_MATCH); + if (X509_self_signed(sk_X509_value(ctx->chain, num - 1), 0) > 0) + return verify_cb_cert(ctx, NULL, num - 1, + num == 1 + ? X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT + : X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN); + return verify_cb_cert(ctx, NULL, num - 1, + ctx->num_untrusted < num + ? X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT + : X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY); + } + + int_err: + ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR); + ctx->error = X509_V_ERR_UNSPECIFIED; + sk_X509_free(sk_untrusted); + return -1; + + memerr: + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + sk_X509_free(sk_untrusted); + return -1; +} + +STACK_OF(X509) *X509_build_chain(X509 *target, STACK_OF(X509) *certs, + X509_STORE *store, int with_self_signed, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int finish_chain = store != NULL; + X509_STORE_CTX *ctx; + int flags = X509_ADD_FLAG_UP_REF; + STACK_OF(X509) *result = NULL; + + if (target == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if ((ctx = X509_STORE_CTX_new_ex(libctx, propq)) == NULL) + return NULL; + if (!X509_STORE_CTX_init(ctx, store, target, finish_chain ? certs : NULL)) + goto err; + if (!finish_chain) + X509_STORE_CTX_set0_trusted_stack(ctx, certs); + if (!ossl_x509_add_cert_new(&ctx->chain, target, X509_ADD_FLAG_UP_REF)) { + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto err; } + ctx->num_untrusted = 1; + + if (!build_chain(ctx) && finish_chain) + goto err; + + /* result list to store the up_ref'ed certificates */ + if (sk_X509_num(ctx->chain) > 1 && !with_self_signed) + flags |= X509_ADD_FLAG_NO_SS; + if (!ossl_x509_add_certs_new(&result, ctx->chain, flags)) { + sk_X509_free(result); + result = NULL; + } + + err: + X509_STORE_CTX_free(ctx); + return result; } +/* + * note that there's a corresponding minbits_table in ssl/ssl_cert.c + * in ssl_get_security_level_bits that's used for selection of DH parameters + */ static const int minbits_table[] = { 80, 112, 128, 192, 256 }; static const int NUM_AUTH_LEVELS = OSSL_NELEM(minbits_table); -/* - * Check whether the public key of ``cert`` meets the security level of - * ``ctx``. - * +/*- + * Check whether the public key of `cert` meets the security level of `ctx`. * Returns 1 on success, 0 otherwise. */ static int check_key_level(X509_STORE_CTX *ctx, X509 *cert) @@ -3337,10 +3390,10 @@ static int check_key_level(X509_STORE_CTX *ctx, X509 *cert) if (level > NUM_AUTH_LEVELS) level = NUM_AUTH_LEVELS; - return EVP_PKEY_security_bits(pkey) >= minbits_table[level - 1]; + return EVP_PKEY_get_security_bits(pkey) >= minbits_table[level - 1]; } -/* +/*- * Check whether the public key of ``cert`` does not use explicit params * for an elliptic curve. * @@ -3348,25 +3401,25 @@ static int check_key_level(X509_STORE_CTX *ctx, X509 *cert) */ static int check_curve(X509 *cert) { -#ifndef OPENSSL_NO_EC EVP_PKEY *pkey = X509_get0_pubkey(cert); /* Unsupported or malformed key */ if (pkey == NULL) return -1; - if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { - int ret; + if (EVP_PKEY_get_id(pkey) == EVP_PKEY_EC) { + int ret, val; - ret = EC_KEY_decoded_from_explicit_params(EVP_PKEY_get0_EC_KEY(pkey)); - return ret < 0 ? ret : !ret; + ret = EVP_PKEY_get_int_param(pkey, + OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, + &val); + return ret < 0 ? ret : !val; } -#endif return 1; } -/* +/*- * Check whether the signature digest algorithm of ``cert`` meets the security * level of ``ctx``. Should not be checked for trust anchors (whether * self-signed or otherwise). diff --git a/crypto/openssl/crypto/x509/x509_vpm.c b/crypto/openssl/crypto/x509/x509_vpm.c index 535f169a29e7..b4f4c45998be 100644 --- a/crypto/openssl/crypto/x509/x509_vpm.c +++ b/crypto/openssl/crypto/x509/x509_vpm.c @@ -1,7 +1,7 @@ /* - * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -44,7 +44,8 @@ static int int_x509_param_set_hosts(X509_VERIFY_PARAM *vpm, int mode, */ if (namelen == 0 || name == NULL) namelen = name ? strlen(name) : 0; - else if (name && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen)) + else if (name != NULL + && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen) != NULL) return 0; if (namelen > 0 && name[namelen - 1] == '\0') --namelen; @@ -78,14 +79,13 @@ static int int_x509_param_set_hosts(X509_VERIFY_PARAM *vpm, int mode, return 1; } - X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) { X509_VERIFY_PARAM *param; param = OPENSSL_zalloc(sizeof(*param)); if (param == NULL) { - X509err(X509_F_X509_VERIFY_PARAM_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } param->trust = X509_TRUST_DEFAULT; @@ -142,39 +142,32 @@ void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) /* Macro to test if a field should be copied from src to dest */ #define test_x509_verify_param_copy(field, def) \ - (to_overwrite || \ - ((src->field != def) && (to_default || (dest->field == def)))) + (to_overwrite || (src->field != def && (to_default || dest->field == def))) /* Macro to test and copy a field if necessary */ #define x509_verify_param_copy(field, def) \ - if (test_x509_verify_param_copy(field, def)) \ - dest->field = src->field + if (test_x509_verify_param_copy(field, def)) \ + dest->field = src->field; int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src) { unsigned long inh_flags; int to_default, to_overwrite; - if (!src) + + if (src == NULL) return 1; inh_flags = dest->inh_flags | src->inh_flags; - if (inh_flags & X509_VP_FLAG_ONCE) + if ((inh_flags & X509_VP_FLAG_ONCE) != 0) dest->inh_flags = 0; - if (inh_flags & X509_VP_FLAG_LOCKED) + if ((inh_flags & X509_VP_FLAG_LOCKED) != 0) return 1; - if (inh_flags & X509_VP_FLAG_DEFAULT) - to_default = 1; - else - to_default = 0; - - if (inh_flags & X509_VP_FLAG_OVERWRITE) - to_overwrite = 1; - else - to_overwrite = 0; + to_default = (inh_flags & X509_VP_FLAG_DEFAULT) != 0; + to_overwrite = (inh_flags & X509_VP_FLAG_OVERWRITE) != 0; x509_verify_param_copy(purpose, 0); x509_verify_param_copy(trust, X509_TRUST_DEFAULT); @@ -183,13 +176,13 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, /* If overwrite or check time not set, copy across */ - if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { + if (to_overwrite || (dest->flags & X509_V_FLAG_USE_CHECK_TIME) == 0) { dest->check_time = src->check_time; dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; /* Don't need to copy flag: that is done below */ } - if (inh_flags & X509_VP_FLAG_RESET_FLAGS) + if ((inh_flags & X509_VP_FLAG_RESET_FLAGS) != 0) dest->flags = 0; dest->flags |= src->flags; @@ -204,7 +197,7 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, if (test_x509_verify_param_copy(hosts, NULL)) { sk_OPENSSL_STRING_pop_free(dest->hosts, str_free); dest->hosts = NULL; - if (src->hosts) { + if (src->hosts != NULL) { dest->hosts = sk_OPENSSL_STRING_deep_copy(src->hosts, str_copy, str_free); if (dest->hosts == NULL) @@ -228,8 +221,14 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from) { - unsigned long save_flags = to->inh_flags; + unsigned long save_flags; int ret; + + if (to == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + save_flags = to->inh_flags; to->inh_flags |= X509_VP_FLAG_DEFAULT; ret = X509_VERIFY_PARAM_inherit(to, from); to->inh_flags = save_flags; @@ -239,14 +238,17 @@ int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, static int int_x509_param_set1(char **pdest, size_t *pdestlen, const char *src, size_t srclen) { - void *tmp; - if (src) { + char *tmp; + + if (src != NULL) { if (srclen == 0) srclen = strlen(src); - tmp = OPENSSL_memdup(src, srclen); + tmp = OPENSSL_malloc(srclen + 1); if (tmp == NULL) return 0; + memcpy(tmp, src, srclen); + tmp[srclen] = '\0'; /* enforce NUL termination */ } else { tmp = NULL; srclen = 0; @@ -262,15 +264,13 @@ int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) { OPENSSL_free(param->name); param->name = OPENSSL_strdup(name); - if (param->name) - return 1; - return 0; + return param->name != NULL; } int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) { param->flags |= flags; - if (flags & X509_V_FLAG_POLICY_MASK) + if ((flags & X509_V_FLAG_POLICY_MASK) != 0) param->flags |= X509_V_FLAG_POLICY_CHECK; return 1; } @@ -282,7 +282,7 @@ int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, return 1; } -unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) +unsigned long X509_VERIFY_PARAM_get_flags(const X509_VERIFY_PARAM *param) { return param->flags; } @@ -332,14 +332,12 @@ void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy) { - if (!param->policies) { + if (param->policies == NULL) { param->policies = sk_ASN1_OBJECT_new_null(); - if (!param->policies) + if (param->policies == NULL) return 0; } - if (!sk_ASN1_OBJECT_push(param->policies, policy)) - return 0; - return 1; + return sk_ASN1_OBJECT_push(param->policies, policy); } int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, @@ -348,23 +346,25 @@ int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, int i; ASN1_OBJECT *oid, *doid; - if (!param) + if (param == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return 0; + } sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); - if (!policies) { + if (policies == NULL) { param->policies = NULL; return 1; } param->policies = sk_ASN1_OBJECT_new_null(); - if (!param->policies) + if (param->policies == NULL) return 0; for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { oid = sk_ASN1_OBJECT_value(policies, i); doid = OBJ_dup(oid); - if (!doid) + if (doid == NULL) return 0; if (!sk_ASN1_OBJECT_push(param->policies, doid)) { ASN1_OBJECT_free(doid); @@ -375,6 +375,11 @@ int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, return 1; } +char *X509_VERIFY_PARAM_get0_host(X509_VERIFY_PARAM *param, int idx) +{ + return sk_OPENSSL_STRING_value(param->hosts, idx); +} + int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, const char *name, size_t namelen) { @@ -398,7 +403,7 @@ unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param) return param->hostflags; } -char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) +char *X509_VERIFY_PARAM_get0_peername(const X509_VERIFY_PARAM *param) { return param->peername; } @@ -417,10 +422,15 @@ void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *to, OPENSSL_free(to->peername); to->peername = peername; } - if (from) + if (from != NULL) from->peername = NULL; } +char *X509_VERIFY_PARAM_get0_email(X509_VERIFY_PARAM *param) +{ + return param->email; +} + int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, size_t emaillen) { @@ -428,11 +438,33 @@ int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, email, emaillen); } +static unsigned char +*int_X509_VERIFY_PARAM_get0_ip(X509_VERIFY_PARAM *param, size_t *plen) +{ + if (param == NULL || param->ip == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (plen != NULL) + *plen = param->iplen; + return param->ip; +} + +char *X509_VERIFY_PARAM_get1_ip_asc(X509_VERIFY_PARAM *param) +{ + size_t iplen; + unsigned char *ip = int_X509_VERIFY_PARAM_get0_ip(param, &iplen); + + return ip == NULL ? NULL : ossl_ipaddr_to_asc(ip, iplen); +} + int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, size_t iplen) { - if (iplen != 0 && iplen != 4 && iplen != 16) + if (iplen != 0 && iplen != 4 && iplen != 16) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT); return 0; + } return int_x509_param_set1((char **)¶m->ip, ¶m->iplen, (char *)ip, iplen); } @@ -440,9 +472,8 @@ int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) { unsigned char ipout[16]; - size_t iplen; + size_t iplen = (size_t)ossl_a2i_ipadd(ipout, ipasc); - iplen = (size_t)a2i_ipadd(ipout, ipasc); if (iplen == 0) return 0; return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); @@ -474,8 +505,8 @@ const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) static const X509_VERIFY_PARAM default_table[] = { { "default", /* X509 default parameters */ - 0, /* Check time */ - 0, /* internal flags */ + 0, /* check time to use */ + 0, /* inheritance flags */ X509_V_FLAG_TRUSTED_FIRST, /* flags */ 0, /* purpose */ 0, /* trust */ @@ -485,8 +516,8 @@ static const X509_VERIFY_PARAM default_table[] = { vpm_empty_id}, { "pkcs7", /* S/MIME sign parameters */ - 0, /* Check time */ - 0, /* internal flags */ + 0, /* check time to use */ + 0, /* inheritance flags */ 0, /* flags */ X509_PURPOSE_SMIME_SIGN, /* purpose */ X509_TRUST_EMAIL, /* trust */ @@ -496,8 +527,8 @@ static const X509_VERIFY_PARAM default_table[] = { vpm_empty_id}, { "smime_sign", /* S/MIME sign parameters */ - 0, /* Check time */ - 0, /* internal flags */ + 0, /* check time to use */ + 0, /* inheritance flags */ 0, /* flags */ X509_PURPOSE_SMIME_SIGN, /* purpose */ X509_TRUST_EMAIL, /* trust */ @@ -507,8 +538,8 @@ static const X509_VERIFY_PARAM default_table[] = { vpm_empty_id}, { "ssl_client", /* SSL/TLS client parameters */ - 0, /* Check time */ - 0, /* internal flags */ + 0, /* check time to use */ + 0, /* inheritance flags */ 0, /* flags */ X509_PURPOSE_SSL_CLIENT, /* purpose */ X509_TRUST_SSL_CLIENT, /* trust */ @@ -518,8 +549,8 @@ static const X509_VERIFY_PARAM default_table[] = { vpm_empty_id}, { "ssl_server", /* SSL/TLS server parameters */ - 0, /* Check time */ - 0, /* internal flags */ + 0, /* check time to use */ + 0, /* inheritance flags */ 0, /* flags */ X509_PURPOSE_SSL_SERVER, /* purpose */ X509_TRUST_SSL_SERVER, /* trust */ @@ -549,6 +580,7 @@ int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) { int idx; X509_VERIFY_PARAM *ptmp; + if (param_table == NULL) { param_table = sk_X509_VERIFY_PARAM_new(param_cmp); if (param_table == NULL) @@ -560,15 +592,14 @@ int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) X509_VERIFY_PARAM_free(ptmp); } } - if (!sk_X509_VERIFY_PARAM_push(param_table, param)) - return 0; - return 1; + return sk_X509_VERIFY_PARAM_push(param_table, param); } int X509_VERIFY_PARAM_get_count(void) { int num = OSSL_NELEM(default_table); - if (param_table) + + if (param_table != NULL) num += sk_X509_VERIFY_PARAM_num(param_table); return num; } @@ -576,6 +607,7 @@ int X509_VERIFY_PARAM_get_count(void) const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id) { int num = OSSL_NELEM(default_table); + if (id < num) return default_table + id; return sk_X509_VERIFY_PARAM_value(param_table, id - num); diff --git a/crypto/openssl/crypto/x509/x509cset.c b/crypto/openssl/crypto/x509/x509cset.c index 6c08509138d5..2746b9892506 100644 --- a/crypto/openssl/crypto/x509/x509cset.c +++ b/crypto/openssl/crypto/x509/x509cset.c @@ -1,7 +1,7 @@ /* - * Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -27,7 +27,7 @@ int X509_CRL_set_version(X509_CRL *x, long version) return ASN1_INTEGER_set(x->crl.version, version); } -int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) +int X509_CRL_set_issuer_name(X509_CRL *x, const X509_NAME *name) { if (x == NULL) return 0; @@ -38,14 +38,14 @@ int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) { if (x == NULL) return 0; - return x509_set1_time(&x->crl.lastUpdate, tm); + return ossl_x509_set1_time(&x->crl.lastUpdate, tm); } int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) { if (x == NULL) return 0; - return x509_set1_time(&x->crl.nextUpdate, tm); + return ossl_x509_set1_time(&x->crl.nextUpdate, tm); } int X509_CRL_sort(X509_CRL *c) @@ -91,7 +91,7 @@ const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl) return crl->crl.nextUpdate; } -#if OPENSSL_API_COMPAT < 0x10100000L +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl) { return crl->crl.lastUpdate; diff --git a/crypto/openssl/crypto/x509/x509name.c b/crypto/openssl/crypto/x509/x509name.c index c86d8e7914f1..9ae0dc5de48f 100644 --- a/crypto/openssl/crypto/x509/x509name.c +++ b/crypto/openssl/crypto/x509/x509name.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -16,7 +16,8 @@ #include #include "crypto/x509.h" -int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) +int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, + char *buf, int len) { ASN1_OBJECT *obj; @@ -26,7 +27,7 @@ int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) return X509_NAME_get_text_by_OBJ(name, obj, buf, len); } -int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, +int X509_NAME_get_text_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, char *buf, int len) { int i; @@ -48,12 +49,15 @@ int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int X509_NAME_entry_count(const X509_NAME *name) { + int ret; + if (name == NULL) return 0; - return sk_X509_NAME_ENTRY_num(name->entries); + ret = sk_X509_NAME_ENTRY_num(name->entries); + return ret > 0 ? ret : 0; } -int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos) +int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos) { ASN1_OBJECT *obj; @@ -64,7 +68,8 @@ int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos) } /* NOTE: you should be passing -1, not 0 as lastpos */ -int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int lastpos) +int X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, + int lastpos) { int n; X509_NAME_ENTRY *ne; @@ -216,15 +221,11 @@ int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc, set = sk_X509_NAME_ENTRY_value(sk, loc)->set; } - /* - * X509_NAME_ENTRY_dup is ASN1 generated code, that can't be easily - * const'ified; harmless cast since dup() don't modify its input. - */ - if ((new_name = X509_NAME_ENTRY_dup((X509_NAME_ENTRY *)ne)) == NULL) + if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL) goto err; new_name->set = set; if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { - X509err(X509_F_X509_NAME_ADD_ENTRY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } if (inc) { @@ -248,9 +249,8 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, obj = OBJ_txt2obj(field, 0); if (obj == NULL) { - X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT, - X509_R_INVALID_FIELD_NAME); - ERR_add_error_data(2, "name=", field); + ERR_raise_data(ERR_LIB_X509, X509_R_INVALID_FIELD_NAME, + "name=%s", field); return NULL; } nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); @@ -268,7 +268,7 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, obj = OBJ_nid2obj(nid); if (obj == NULL) { - X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, X509_R_UNKNOWN_NID); + ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_NID); return NULL; } nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); @@ -306,8 +306,7 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj) { if ((ne == NULL) || (obj == NULL)) { - X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT, - ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return 0; } ASN1_OBJECT_free(ne->object); diff --git a/crypto/openssl/crypto/x509/x509rset.c b/crypto/openssl/crypto/x509/x509rset.c index 9da3f2ee27df..344993d4c78c 100644 --- a/crypto/openssl/crypto/x509/x509rset.c +++ b/crypto/openssl/crypto/x509/x509rset.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -23,7 +23,7 @@ int X509_REQ_set_version(X509_REQ *x, long version) return ASN1_INTEGER_set(x->req_info.version, version); } -int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) +int X509_REQ_set_subject_name(X509_REQ *x, const X509_NAME *name) { if (x == NULL) return 0; diff --git a/crypto/openssl/crypto/x509/x509spki.c b/crypto/openssl/crypto/x509/x509spki.c index fd8162af6df2..1d66697db00d 100644 --- a/crypto/openssl/crypto/x509/x509spki.c +++ b/crypto/openssl/crypto/x509/x509spki.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -36,12 +36,12 @@ NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len) if (len <= 0) len = strlen(str); if ((spki_der = OPENSSL_malloc(len + 1)) == NULL) { - X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len); if (spki_len < 0) { - X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, X509_R_BASE64_DECODE_ERROR); + ERR_raise(ERR_LIB_X509, X509_R_BASE64_DECODE_ERROR); OPENSSL_free(spki_der); return NULL; } @@ -58,11 +58,14 @@ char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) unsigned char *der_spki, *p; char *b64_str; int der_len; + der_len = i2d_NETSCAPE_SPKI(spki, NULL); + if (der_len <= 0) + return NULL; der_spki = OPENSSL_malloc(der_len); b64_str = OPENSSL_malloc(der_len * 2); if (der_spki == NULL || b64_str == NULL) { - X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); OPENSSL_free(der_spki); OPENSSL_free(b64_str); return NULL; diff --git a/crypto/openssl/crypto/x509/x509type.c b/crypto/openssl/crypto/x509/x509type.c index 0e33b424be51..79fd5e7db609 100644 --- a/crypto/openssl/crypto/x509/x509type.c +++ b/crypto/openssl/crypto/x509/x509type.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -29,7 +29,7 @@ int X509_certificate_type(const X509 *x, const EVP_PKEY *pkey) if (pk == NULL) return 0; - switch (EVP_PKEY_id(pk)) { + switch (EVP_PKEY_get_id(pk)) { case EVP_PKEY_RSA: ret = EVP_PK_RSA | EVP_PKT_SIGN; /* if (!sign only extension) */ diff --git a/crypto/openssl/crypto/x509/x_all.c b/crypto/openssl/crypto/x509/x_all.c index fcf6b5ba3780..e58c9ab1c117 100644 --- a/crypto/openssl/crypto/x509/x_all.c +++ b/crypto/openssl/crypto/x509/x_all.c @@ -1,46 +1,69 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * Low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include #include #include #include -#include "crypto/x509.h" -#include +#include #include #include #include +#include "internal/asn1.h" +#include "crypto/pkcs7.h" +#include "crypto/x509.h" +#include "crypto/rsa.h" int X509_verify(X509 *a, EVP_PKEY *r) { - if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature)) + if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature) != 0) return 0; - return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg, - &a->signature, &a->cert_info, r)); + + return ASN1_item_verify_ex(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg, + &a->signature, &a->cert_info, + a->distinguishing_id, r, a->libctx, a->propq); +} + +int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *r, OSSL_LIB_CTX *libctx, + const char *propq) +{ + return ASN1_item_verify_ex(ASN1_ITEM_rptr(X509_REQ_INFO), &a->sig_alg, + a->signature, &a->req_info, a->distinguishing_id, + r, libctx, propq); } int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) { - return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), - &a->sig_alg, a->signature, &a->req_info, r)); + return X509_REQ_verify_ex(a, r, NULL, NULL); } int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) { - return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), - &a->sig_algor, a->signature, a->spkac, r)); + return ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), + &a->sig_algor, a->signature, a->spkac, r); } int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) { + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + /* * Setting the modified flag before signing it. This makes the cached * encoding to be ignored, so even if the certificate fields have changed, @@ -49,36 +72,61 @@ int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) * which exist below are the same. */ x->cert_info.enc.modified = 1; - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), &x->cert_info.signature, - &x->sig_alg, &x->signature, &x->cert_info, pkey, - md)); + return ASN1_item_sign_ex(ASN1_ITEM_rptr(X509_CINF), &x->cert_info.signature, + &x->sig_alg, &x->signature, &x->cert_info, NULL, + pkey, md, x->libctx, x->propq); } int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) { + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } x->cert_info.enc.modified = 1; return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), &x->cert_info.signature, &x->sig_alg, &x->signature, &x->cert_info, ctx); } -#ifndef OPENSSL_NO_OCSP -int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert) +static ASN1_VALUE *simple_get_asn1(const char *url, BIO *bio, BIO *rbio, + int timeout, const ASN1_ITEM *it) { - return OCSP_REQ_CTX_nbio_d2i(rctx, - (ASN1_VALUE **)pcert, ASN1_ITEM_rptr(X509)); + BIO *mem = OSSL_HTTP_get(url, NULL /* proxy */, NULL /* no_proxy */, + bio, rbio, NULL /* cb */, NULL /* arg */, + 1024 /* buf_size */, NULL /* headers */, + NULL /* expected_ct */, 1 /* expect_asn1 */, + OSSL_HTTP_DEFAULT_MAX_RESP_LEN, timeout); + ASN1_VALUE *res = ASN1_item_d2i_bio(it, mem, NULL); + + BIO_free(mem); + return res; +} + +X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout) +{ + return (X509 *)simple_get_asn1(url, bio, rbio, timeout, + ASN1_ITEM_rptr(X509)); } -#endif int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) { + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } x->req_info.enc.modified = 1; - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), &x->sig_alg, NULL, - x->signature, &x->req_info, pkey, md)); + return ASN1_item_sign_ex(ASN1_ITEM_rptr(X509_REQ_INFO), &x->sig_alg, NULL, + x->signature, &x->req_info, NULL, + pkey, md, x->libctx, x->propq); } int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) { + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } x->req_info.enc.modified = 1; return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), &x->sig_alg, NULL, x->signature, &x->req_info, @@ -87,32 +135,39 @@ int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) { + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } x->crl.enc.modified = 1; - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), &x->crl.sig_alg, - &x->sig_alg, &x->signature, &x->crl, pkey, md)); + return ASN1_item_sign_ex(ASN1_ITEM_rptr(X509_CRL_INFO), &x->crl.sig_alg, + &x->sig_alg, &x->signature, &x->crl, NULL, + pkey, md, x->libctx, x->propq); } int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) { + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } x->crl.enc.modified = 1; return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), &x->crl.sig_alg, &x->sig_alg, &x->signature, &x->crl, ctx); } -#ifndef OPENSSL_NO_OCSP -int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl) +X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout) { - return OCSP_REQ_CTX_nbio_d2i(rctx, - (ASN1_VALUE **)pcrl, - ASN1_ITEM_rptr(X509_CRL)); + return (X509_CRL *)simple_get_asn1(url, bio, rbio, timeout, + ASN1_ITEM_rptr(X509_CRL)); } -#endif int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) { - return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), &x->sig_algor, NULL, - x->signature, x->spkac, pkey, md)); + return + ASN1_item_sign_ex(ASN1_ITEM_rptr(NETSCAPE_SPKAC), &x->sig_algor, NULL, + x->signature, x->spkac, NULL, pkey, md, NULL, NULL); } #ifndef OPENSSL_NO_STDIO @@ -121,7 +176,7 @@ X509 *d2i_X509_fp(FILE *fp, X509 **x509) return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509); } -int i2d_X509_fp(FILE *fp, X509 *x509) +int i2d_X509_fp(FILE *fp, const X509 *x509) { return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509); } @@ -132,7 +187,7 @@ X509 *d2i_X509_bio(BIO *bp, X509 **x509) return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509); } -int i2d_X509_bio(BIO *bp, X509 *x509) +int i2d_X509_bio(BIO *bp, const X509 *x509) { return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509); } @@ -143,7 +198,7 @@ X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); } -int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) +int i2d_X509_CRL_fp(FILE *fp, const X509_CRL *crl) { return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); } @@ -154,7 +209,7 @@ X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); } -int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) +int i2d_X509_CRL_bio(BIO *bp, const X509_CRL *crl) { return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); } @@ -162,10 +217,22 @@ int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) #ifndef OPENSSL_NO_STDIO PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) { - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); + PKCS7 *ret; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + + if (p7 != NULL && *p7 != NULL) { + libctx = (*p7)->ctx.libctx; + propq = (*p7)->ctx.propq; + } + + ret = ASN1_item_d2i_fp_ex(ASN1_ITEM_rptr(PKCS7), fp, p7, libctx, propq); + if (ret != NULL) + ossl_pkcs7_resolve_libctx(ret); + return ret; } -int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7) +int i2d_PKCS7_fp(FILE *fp, const PKCS7 *p7) { return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); } @@ -173,10 +240,22 @@ int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7) PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7) { - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); + PKCS7 *ret; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + + if (p7 != NULL && *p7 != NULL) { + libctx = (*p7)->ctx.libctx; + propq = (*p7)->ctx.propq; + } + + ret = ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(PKCS7), bp, p7, libctx, propq); + if (ret != NULL) + ossl_pkcs7_resolve_libctx(ret); + return ret; } -int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7) +int i2d_PKCS7_bio(BIO *bp, const PKCS7 *p7) { return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); } @@ -187,7 +266,7 @@ X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); } -int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) +int i2d_X509_REQ_fp(FILE *fp, const X509_REQ *req) { return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); } @@ -195,23 +274,29 @@ int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) { - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + + if (req != NULL && *req != NULL) { + libctx = (*req)->libctx; + propq = (*req)->propq; + } + + return ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(X509_REQ), bp, req, libctx, propq); } -int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) +int i2d_X509_REQ_bio(BIO *bp, const X509_REQ *req) { return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); } -#ifndef OPENSSL_NO_RSA - -# ifndef OPENSSL_NO_STDIO +#ifndef OPENSSL_NO_STDIO RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) { return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); } -int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) +int i2d_RSAPrivateKey_fp(FILE *fp, const RSA *rsa) { return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); } @@ -228,23 +313,23 @@ RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa) (void **)rsa); } -int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa) +int i2d_RSAPublicKey_fp(FILE *fp, const RSA *rsa) { return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); } -int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa) +int i2d_RSA_PUBKEY_fp(FILE *fp, const RSA *rsa) { return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa); } -# endif +#endif RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) { return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); } -int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) +int i2d_RSAPrivateKey_bio(BIO *bp, const RSA *rsa) { return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); } @@ -259,16 +344,15 @@ RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa) return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa); } -int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa) +int i2d_RSAPublicKey_bio(BIO *bp, const RSA *rsa) { return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); } -int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa) +int i2d_RSA_PUBKEY_bio(BIO *bp, const RSA *rsa) { return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa); } -#endif #ifndef OPENSSL_NO_DSA # ifndef OPENSSL_NO_STDIO @@ -277,9 +361,9 @@ DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa) return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa); } -int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa) +int i2d_DSAPrivateKey_fp(FILE *fp, const DSA *dsa) { - return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa); + return ASN1_i2d_fp_of(DSA, i2d_DSAPrivateKey, fp, dsa); } DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa) @@ -287,7 +371,7 @@ DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa) return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa); } -int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa) +int i2d_DSA_PUBKEY_fp(FILE *fp, const DSA *dsa) { return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa); } @@ -298,9 +382,9 @@ DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa) return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa); } -int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa) +int i2d_DSAPrivateKey_bio(BIO *bp, const DSA *dsa) { - return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa); + return ASN1_i2d_bio_of(DSA, i2d_DSAPrivateKey, bp, dsa); } DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa) @@ -308,7 +392,7 @@ DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa) return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa); } -int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa) +int i2d_DSA_PUBKEY_bio(BIO *bp, const DSA *dsa) { return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa); } @@ -322,7 +406,7 @@ EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey) return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey); } -int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey) +int i2d_EC_PUBKEY_fp(FILE *fp, const EC_KEY *eckey) { return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey); } @@ -332,7 +416,7 @@ EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey) return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey); } -int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey) +int i2d_ECPrivateKey_fp(FILE *fp, const EC_KEY *eckey) { return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey); } @@ -342,7 +426,7 @@ EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey) return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey); } -int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa) +int i2d_EC_PUBKEY_bio(BIO *bp, const EC_KEY *ecdsa) { return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa); } @@ -352,7 +436,7 @@ EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey) return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey); } -int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey) +int i2d_ECPrivateKey_bio(BIO *bp, const EC_KEY *eckey) { return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey); } @@ -361,63 +445,160 @@ int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey) int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md, unsigned int *len) { - ASN1_BIT_STRING *key; - key = X509_get0_pubkey_bitstr(data); - if (!key) + ASN1_BIT_STRING *key = X509_get0_pubkey_bitstr(data); + + if (key == NULL) return 0; return EVP_Digest(key->data, key->length, md, len, type, NULL); } -int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, +int X509_digest(const X509 *cert, const EVP_MD *md, unsigned char *data, unsigned int *len) { - if (type == EVP_sha1() && (data->ex_flags & EXFLAG_SET) != 0 - && (data->ex_flags & EXFLAG_NO_FINGERPRINT) == 0) { + if (EVP_MD_is_a(md, SN_sha1) && (cert->ex_flags & EXFLAG_SET) != 0 + && (cert->ex_flags & EXFLAG_NO_FINGERPRINT) == 0) { /* Asking for SHA1 and we already computed it. */ if (len != NULL) - *len = sizeof(data->sha1_hash); - memcpy(md, data->sha1_hash, sizeof(data->sha1_hash)); + *len = sizeof(cert->sha1_hash); + memcpy(data, cert->sha1_hash, sizeof(cert->sha1_hash)); return 1; } - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509), type, (char *)data, md, len)); + return ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(X509), md, (char *)cert, + data, len, cert->libctx, cert->propq); +} + +/* calculate cert digest using the same hash algorithm as in its signature */ +ASN1_OCTET_STRING *X509_digest_sig(const X509 *cert, + EVP_MD **md_used, int *md_is_fallback) +{ + unsigned int len; + unsigned char hash[EVP_MAX_MD_SIZE]; + int mdnid, pknid; + EVP_MD *md = NULL; + const char *md_name; + ASN1_OCTET_STRING *new; + + if (md_used != NULL) + *md_used = NULL; + if (md_is_fallback != NULL) + *md_is_fallback = 0; + + if (cert == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if (!OBJ_find_sigid_algs(X509_get_signature_nid(cert), &mdnid, &pknid)) { + ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_SIGID_ALGS); + return NULL; + } + + if (mdnid == NID_undef) { + if (pknid == EVP_PKEY_RSA_PSS) { + RSA_PSS_PARAMS *pss = ossl_rsa_pss_decode(&cert->sig_alg); + const EVP_MD *mgf1md, *mmd = NULL; + int saltlen, trailerfield; + + if (pss == NULL + || !ossl_rsa_pss_get_param_unverified(pss, &mmd, &mgf1md, + &saltlen, + &trailerfield) + || mmd == NULL) { + RSA_PSS_PARAMS_free(pss); + ERR_raise(ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM); + return NULL; + } + RSA_PSS_PARAMS_free(pss); + /* Fetch explicitly and do not fallback */ + if ((md = EVP_MD_fetch(cert->libctx, EVP_MD_get0_name(mmd), + cert->propq)) == NULL) + /* Error code from fetch is sufficient */ + return NULL; + } else if (pknid != NID_undef) { + /* A known algorithm, but without a digest */ + switch (pknid) { + case NID_ED25519: /* Follow CMS default given in RFC8419 */ + md_name = "SHA512"; + break; + case NID_ED448: /* Follow CMS default given in RFC8419 */ + md_name = "SHAKE256"; + break; + default: /* Fall back to SHA-256 */ + md_name = "SHA256"; + break; + } + if ((md = EVP_MD_fetch(cert->libctx, md_name, + cert->propq)) == NULL) + return NULL; + if (md_is_fallback != NULL) + *md_is_fallback = 1; + } else { + /* A completely unknown algorithm */ + ERR_raise(ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM); + return NULL; + } + } else if ((md = EVP_MD_fetch(cert->libctx, OBJ_nid2sn(mdnid), + cert->propq)) == NULL + && (md = (EVP_MD *)EVP_get_digestbynid(mdnid)) == NULL) { + ERR_raise(ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM); + return NULL; + } + if (!X509_digest(cert, md, hash, &len) + || (new = ASN1_OCTET_STRING_new()) == NULL) + goto err; + if (ASN1_OCTET_STRING_set(new, hash, len)) { + if (md_used != NULL) + *md_used = md; + else + EVP_MD_free(md); + return new; + } + ASN1_OCTET_STRING_free(new); + err: + EVP_MD_free(md); + return NULL; } int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md, unsigned int *len) { - if (type == EVP_sha1() && (data->flags & EXFLAG_SET) != 0 - && (data->flags & EXFLAG_INVALID) == 0) { + if (type == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (EVP_MD_is_a(type, SN_sha1) + && (data->flags & EXFLAG_SET) != 0 + && (data->flags & EXFLAG_NO_FINGERPRINT) == 0) { /* Asking for SHA1; always computed in CRL d2i. */ if (len != NULL) *len = sizeof(data->sha1_hash); memcpy(md, data->sha1_hash, sizeof(data->sha1_hash)); return 1; } - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len)); + return ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(X509_CRL), type, (char *)data, + md, len, data->libctx, data->propq); } int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md, unsigned int *len) { - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len)); + return ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(X509_REQ), type, (char *)data, + md, len, data->libctx, data->propq); } int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md, unsigned int *len) { - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len)); + return ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME), type, (char *)data, + md, len); } int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, const EVP_MD *type, unsigned char *md, unsigned int *len) { - return (ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL), type, - (char *)data, md, len)); + return ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL), type, + (char *)data, md, len); } #ifndef OPENSSL_NO_STDIO @@ -426,7 +607,7 @@ X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8) return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8); } -int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8) +int i2d_PKCS8_fp(FILE *fp, const X509_SIG *p8) { return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8); } @@ -437,11 +618,35 @@ X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8) return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8); } -int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8) +int i2d_PKCS8_bio(BIO *bp, const X509_SIG *p8) { return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8); } +#ifndef OPENSSL_NO_STDIO +X509_PUBKEY *d2i_X509_PUBKEY_fp(FILE *fp, X509_PUBKEY **xpk) +{ + return ASN1_d2i_fp_of(X509_PUBKEY, X509_PUBKEY_new, d2i_X509_PUBKEY, + fp, xpk); +} + +int i2d_X509_PUBKEY_fp(FILE *fp, const X509_PUBKEY *xpk) +{ + return ASN1_i2d_fp_of(X509_PUBKEY, i2d_X509_PUBKEY, fp, xpk); +} +#endif + +X509_PUBKEY *d2i_X509_PUBKEY_bio(BIO *bp, X509_PUBKEY **xpk) +{ + return ASN1_d2i_bio_of(X509_PUBKEY, X509_PUBKEY_new, d2i_X509_PUBKEY, + bp, xpk); +} + +int i2d_X509_PUBKEY_bio(BIO *bp, const X509_PUBKEY *xpk) +{ + return ASN1_i2d_bio_of(X509_PUBKEY, i2d_X509_PUBKEY, bp, xpk); +} + #ifndef OPENSSL_NO_STDIO PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf) @@ -450,25 +655,26 @@ PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf); } -int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf) +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, const PKCS8_PRIV_KEY_INFO *p8inf) { return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp, p8inf); } -int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, const EVP_PKEY *key) { PKCS8_PRIV_KEY_INFO *p8inf; int ret; + p8inf = EVP_PKEY2PKCS8(key); - if (!p8inf) + if (p8inf == NULL) return 0; ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); PKCS8_PRIV_KEY_INFO_free(p8inf); return ret; } -int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey) +int i2d_PrivateKey_fp(FILE *fp, const EVP_PKEY *pkey) { return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey); } @@ -478,7 +684,23 @@ EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a); } -int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey) +EVP_PKEY *d2i_PrivateKey_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, + const char *propq) +{ + BIO *b; + void *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); + return NULL; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = d2i_PrivateKey_ex_bio(b, a, libctx, propq); + BIO_free(b); + return ret; +} + +int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey) { return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey); } @@ -497,25 +719,26 @@ PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf); } -int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf) +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, const PKCS8_PRIV_KEY_INFO *p8inf) { return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp, p8inf); } -int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, const EVP_PKEY *key) { PKCS8_PRIV_KEY_INFO *p8inf; int ret; + p8inf = EVP_PKEY2PKCS8(key); - if (!p8inf) + if (p8inf == NULL) return 0; ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); PKCS8_PRIV_KEY_INFO_free(p8inf); return ret; } -int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) +int i2d_PrivateKey_bio(BIO *bp, const EVP_PKEY *pkey) { return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey); } @@ -525,7 +748,26 @@ EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a); } -int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey) +EVP_PKEY *d2i_PrivateKey_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, + const char *propq) +{ + BUF_MEM *b = NULL; + const unsigned char *p; + void *ret = NULL; + int len; + + len = asn1_d2i_read_bio(bp, &b); + if (len < 0) + goto err; + + p = (unsigned char *)b->data; + ret = d2i_AutoPrivateKey_ex(a, &p, len, libctx, propq); + err: + BUF_MEM_free(b); + return ret; +} + +int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey) { return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey); } diff --git a/crypto/openssl/crypto/x509/x_attrib.c b/crypto/openssl/crypto/x509/x_attrib.c index 7342c4f6bcb5..5c7e622d1a0b 100644 --- a/crypto/openssl/crypto/x509/x_attrib.c +++ b/crypto/openssl/crypto/x509/x_attrib.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/x509/x_crl.c b/crypto/openssl/crypto/x509/x_crl.c index df0041c0108c..fd98ad6926cf 100644 --- a/crypto/openssl/crypto/x509/x_crl.c +++ b/crypto/openssl/crypto/x509/x_crl.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -27,8 +27,8 @@ ASN1_SEQUENCE(X509_REVOKED) = { static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); static int def_crl_lookup(X509_CRL *crl, - X509_REVOKED **ret, ASN1_INTEGER *serial, - X509_NAME *issuer); + X509_REVOKED **ret, const ASN1_INTEGER *serial, + const X509_NAME *issuer); static X509_CRL_METHOD int_crl_meth = { 0, @@ -151,7 +151,7 @@ static int crl_set_issuers(X509_CRL *crl) /* * The X509_CRL structure needs a bit of customisation. Cache some extensions - * and hash of the whole CRL. + * and hash of the whole CRL or set EXFLAG_NO_FINGERPRINT if this fails. */ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) @@ -189,7 +189,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, case ASN1_OP_D2I_POST: if (!X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL)) - crl->flags |= EXFLAG_INVALID; + crl->flags |= EXFLAG_NO_FINGERPRINT; crl->idp = X509_CRL_get_ext_d2i(crl, NID_issuing_distribution_point, &i, NULL); @@ -268,6 +268,15 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ASN1_INTEGER_free(crl->crl_number); ASN1_INTEGER_free(crl->base_crl_number); sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); + OPENSSL_free(crl->propq); + break; + case ASN1_OP_DUP_POST: + { + X509_CRL *old = exarg; + + if (!ossl_x509_crl_set0_libctx(crl, old->libctx, old->propq)) + return 0; + } break; } return 1; @@ -335,6 +344,18 @@ static int X509_REVOKED_cmp(const X509_REVOKED *const *a, (ASN1_STRING *)&(*b)->serialNumber)); } +X509_CRL *X509_CRL_new_ex(OSSL_LIB_CTX *libctx, const char *propq) +{ + X509_CRL *crl = NULL; + + crl = (X509_CRL *)ASN1_item_new((X509_CRL_it())); + if (!ossl_x509_crl_set0_libctx(crl, libctx, propq)) { + X509_CRL_free(crl); + crl = NULL; + } + return crl; +} + int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) { X509_CRL_INFO *inf; @@ -343,7 +364,7 @@ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) if (inf->revoked == NULL) inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp); if (inf->revoked == NULL || !sk_X509_REVOKED_push(inf->revoked, rev)) { - ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return 0; } inf->enc.modified = 1; @@ -358,7 +379,7 @@ int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r) } int X509_CRL_get0_by_serial(X509_CRL *crl, - X509_REVOKED **ret, ASN1_INTEGER *serial) + X509_REVOKED **ret, const ASN1_INTEGER *serial) { if (crl->meth->crl_lookup) return crl->meth->crl_lookup(crl, ret, serial, NULL); @@ -369,18 +390,19 @@ int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) { if (crl->meth->crl_lookup) return crl->meth->crl_lookup(crl, ret, - X509_get_serialNumber(x), + X509_get0_serialNumber(x), X509_get_issuer_name(x)); return 0; } static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r) { - return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), - &crl->sig_alg, &crl->signature, &crl->crl, r)); + return ASN1_item_verify_ex(ASN1_ITEM_rptr(X509_CRL_INFO), + &crl->sig_alg, &crl->signature, &crl->crl, NULL, + r, crl->libctx, crl->propq); } -static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, +static int crl_revoked_issuer_match(X509_CRL *crl, const X509_NAME *nm, X509_REVOKED *rev) { int i; @@ -408,8 +430,8 @@ static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, } static int def_crl_lookup(X509_CRL *crl, - X509_REVOKED **ret, ASN1_INTEGER *serial, - X509_NAME *issuer) + X509_REVOKED **ret, const ASN1_INTEGER *serial, + const X509_NAME *issuer) { X509_REVOKED rtmp, *rev; int idx, num; @@ -422,7 +444,8 @@ static int def_crl_lookup(X509_CRL *crl, * under a lock to avoid race condition. */ if (!sk_X509_REVOKED_is_sorted(crl->crl.revoked)) { - CRYPTO_THREAD_write_lock(crl->lock); + if (!CRYPTO_THREAD_write_lock(crl->lock)) + return 0; sk_X509_REVOKED_sort(crl->crl.revoked); CRYPTO_THREAD_unlock(crl->lock); } @@ -458,15 +481,15 @@ X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), int (*crl_free) (X509_CRL *crl), int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret, - ASN1_INTEGER *ser, - X509_NAME *issuer), + const ASN1_INTEGER *ser, + const X509_NAME *issuer), int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk)) { X509_CRL_METHOD *m = OPENSSL_malloc(sizeof(*m)); if (m == NULL) { - X509err(X509_F_X509_CRL_METHOD_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } m->crl_init = crl_init; @@ -493,3 +516,19 @@ void *X509_CRL_get_meth_data(X509_CRL *crl) { return crl->meth_data; } + +int ossl_x509_crl_set0_libctx(X509_CRL *x, OSSL_LIB_CTX *libctx, + const char *propq) +{ + if (x != NULL) { + x->libctx = libctx; + OPENSSL_free(x->propq); + x->propq = NULL; + if (propq != NULL) { + x->propq = OPENSSL_strdup(propq); + if (x->propq == NULL) + return 0; + } + } + return 1; +} diff --git a/crypto/openssl/crypto/x509/x_exten.c b/crypto/openssl/crypto/x509/x_exten.c index bd7518ef12bf..4e63b50caa62 100644 --- a/crypto/openssl/crypto/x509/x_exten.c +++ b/crypto/openssl/crypto/x509/x_exten.c @@ -1,7 +1,7 @@ /* * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 diff --git a/crypto/openssl/crypto/x509/x_name.c b/crypto/openssl/crypto/x509/x_name.c index dc4a494fb543..944eb9992486 100644 --- a/crypto/openssl/crypto/x509/x_name.c +++ b/crypto/openssl/crypto/x509/x_name.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -28,7 +28,7 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx); -static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, +static int x509_name_ex_i2d(const ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); @@ -36,10 +36,10 @@ static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); static int x509_name_encode(X509_NAME *a); static int x509_name_canon(X509_NAME *a); static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in); -static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname, +static int i2d_name_canon(const STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname, unsigned char **in); -static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, +static int x509_name_ex_print(BIO *out, const ASN1_VALUE **pval, int indent, const char *fname, const ASN1_PCTX *pctx); @@ -102,7 +102,7 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) return 1; memerr: - ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); if (ret) { sk_X509_NAME_ENTRY_free(ret->entries); OPENSSL_free(ret); @@ -114,7 +114,7 @@ static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { X509_NAME *a; - if (!pval || !*pval) + if (pval == NULL || *pval == NULL) return; a = (X509_NAME *)*pval; @@ -156,6 +156,7 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, int i, j, ret; STACK_OF(X509_NAME_ENTRY) *entries; X509_NAME_ENTRY *entry; + if (len > X509_NAME_MAX) len = X509_NAME_MAX; q = p; @@ -185,7 +186,7 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, entry->set = i; if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) goto err; - sk_X509_NAME_ENTRY_set(entries, j, NULL); + (void)sk_X509_NAME_ENTRY_set(entries, j, NULL); } } ret = x509_name_canon(nm.x); @@ -203,15 +204,16 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, X509_NAME_free(nm.x); sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, local_sk_X509_NAME_ENTRY_pop_free); - ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); return 0; } -static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, +static int x509_name_ex_i2d(const ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) { int ret; X509_NAME *a = (X509_NAME *)*val; + if (a->modified) { ret = x509_name_encode(a); if (ret < 0) @@ -232,7 +234,7 @@ static int x509_name_encode(X509_NAME *a) { union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; - ASN1_VALUE *a; + const ASN1_VALUE *a; } intname = { NULL }; @@ -241,6 +243,7 @@ static int x509_name_encode(X509_NAME *a) STACK_OF(X509_NAME_ENTRY) *entries = NULL; X509_NAME_ENTRY *entry; int i, set = -1; + intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); if (!intname.s) goto memerr; @@ -273,11 +276,11 @@ static int x509_name_encode(X509_NAME *a) memerr: sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, local_sk_X509_NAME_ENTRY_free); - ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } -static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, +static int x509_name_ex_print(BIO *out, const ASN1_VALUE **pval, int indent, const char *fname, const ASN1_PCTX *pctx) { @@ -295,6 +298,7 @@ static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, * comparison of Name structures can be rapidly performed by just using * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name * constraints of type dirName can also be checked with a simple memcmp(). + * NOTE: For empty X509_NAME (NULL-DN), canon_enclen == 0 && canon_enc == NULL */ static int x509_name_canon(X509_NAME *a) @@ -314,7 +318,7 @@ static int x509_name_canon(X509_NAME *a) } intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); if (intname == NULL) { - X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { @@ -325,25 +329,25 @@ static int x509_name_canon(X509_NAME *a) goto err; if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { sk_X509_NAME_ENTRY_free(entries); - X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } set = entry->set; } tmpentry = X509_NAME_ENTRY_new(); if (tmpentry == NULL) { - X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } tmpentry->object = OBJ_dup(entry->object); if (tmpentry->object == NULL) { - X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } if (!asn1_string_canon(tmpentry->value, entry->value)) goto err; if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) { - X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } tmpentry = NULL; @@ -357,7 +361,7 @@ static int x509_name_canon(X509_NAME *a) p = OPENSSL_malloc(a->canon_enclen); if (p == NULL) { - X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); goto err; } @@ -460,11 +464,11 @@ static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in) } -static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, +static int i2d_name_canon(const STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, unsigned char **in) { int i, len, ltmp; - ASN1_VALUE *v; + const ASN1_VALUE *v; STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; len = 0; @@ -479,14 +483,16 @@ static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, return len; } -int X509_NAME_set(X509_NAME **xn, X509_NAME *name) +int X509_NAME_set(X509_NAME **xn, const X509_NAME *name) { + X509_NAME *name_copy; + if (*xn == name) return *xn != NULL; - if ((name = X509_NAME_dup(name)) == NULL) + if ((name_copy = X509_NAME_dup(name)) == NULL) return 0; X509_NAME_free(*xn); - *xn = name; + *xn = name_copy; return 1; } @@ -496,9 +502,9 @@ int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase) int i; b = X509_NAME_oneline(name, NULL, 0); - if (!b) + if (b == NULL) return 0; - if (!*b) { + if (*b == '\0') { OPENSSL_free(b); return 1; } @@ -528,12 +534,12 @@ int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase) OPENSSL_free(b); return 1; err: - X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); OPENSSL_free(b); return 0; } -int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, +int X509_NAME_get0_der(const X509_NAME *nm, const unsigned char **pder, size_t *pderlen) { /* Make sure encoding is valid */ diff --git a/crypto/openssl/crypto/x509/x_pubkey.c b/crypto/openssl/crypto/x509/x_pubkey.c index 9be7e9286571..b290075c8589 100644 --- a/crypto/openssl/crypto/x509/x_pubkey.c +++ b/crypto/openssl/crypto/x509/x_pubkey.c @@ -1,92 +1,386 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include "internal/cryptlib.h" #include #include +#include #include "crypto/asn1.h" #include "crypto/evp.h" #include "crypto/x509.h" #include #include +#include +#include +#include "internal/provider.h" +#include "internal/sizes.h" struct X509_pubkey_st { X509_ALGOR *algor; ASN1_BIT_STRING *public_key; + EVP_PKEY *pkey; + + /* extra data for the callback, used by d2i_PUBKEY_ex */ + OSSL_LIB_CTX *libctx; + char *propq; + + /* Flag to force legacy keys */ + unsigned int flag_force_legacy : 1; }; -static int x509_pubkey_decode(EVP_PKEY **pk, X509_PUBKEY *key); +static int x509_pubkey_decode(EVP_PKEY **pk, const X509_PUBKEY *key); -/* Minor tweak to operation: free up EVP_PKEY */ -static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) +static int x509_pubkey_set0_libctx(X509_PUBKEY *x, OSSL_LIB_CTX *libctx, + const char *propq) { - if (operation == ASN1_OP_FREE_POST) { - X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; - EVP_PKEY_free(pubkey->pkey); - } else if (operation == ASN1_OP_D2I_POST) { - /* Attempt to decode public key and cache in pubkey structure. */ - X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; - EVP_PKEY_free(pubkey->pkey); - pubkey->pkey = NULL; - /* - * Opportunistically decode the key but remove any non fatal errors - * from the queue. Subsequent explicit attempts to decode/use the key - * will return an appropriate error. - */ - ERR_set_mark(); - if (x509_pubkey_decode(&pubkey->pkey, pubkey) == -1) - return 0; - ERR_pop_to_mark(); + if (x != NULL) { + x->libctx = libctx; + OPENSSL_free(x->propq); + x->propq = NULL; + if (propq != NULL) { + x->propq = OPENSSL_strdup(propq); + if (x->propq == NULL) + return 0; + } } return 1; } -ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { +ASN1_SEQUENCE(X509_PUBKEY_INTERNAL) = { ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) +} static_ASN1_SEQUENCE_END_name(X509_PUBKEY, X509_PUBKEY_INTERNAL) + +X509_PUBKEY *ossl_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp, + long len, OSSL_LIB_CTX *libctx) +{ + X509_PUBKEY *xpub = OPENSSL_zalloc(sizeof(*xpub)); + + if (xpub == NULL) + return NULL; + return (X509_PUBKEY *)ASN1_item_d2i_ex((ASN1_VALUE **)&xpub, pp, len, + ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), + libctx, NULL); +} + +void ossl_X509_PUBKEY_INTERNAL_free(X509_PUBKEY *xpub) +{ + ASN1_item_free((ASN1_VALUE *)xpub, ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL)); +} + +static void x509_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + X509_PUBKEY *pubkey; + + if (pval != NULL && (pubkey = (X509_PUBKEY *)*pval) != NULL) { + X509_ALGOR_free(pubkey->algor); + ASN1_BIT_STRING_free(pubkey->public_key); + EVP_PKEY_free(pubkey->pkey); + OPENSSL_free(pubkey->propq); + OPENSSL_free(pubkey); + *pval = NULL; + } +} + +static int x509_pubkey_ex_populate(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; + + return (pubkey->algor != NULL + || (pubkey->algor = X509_ALGOR_new()) != NULL) + && (pubkey->public_key != NULL + || (pubkey->public_key = ASN1_BIT_STRING_new()) != NULL); +} + + +static int x509_pubkey_ex_new_ex(ASN1_VALUE **pval, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq) +{ + X509_PUBKEY *ret; + + if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL + || !x509_pubkey_ex_populate((ASN1_VALUE **)&ret, NULL) + || !x509_pubkey_set0_libctx(ret, libctx, propq)) { + x509_pubkey_ex_free((ASN1_VALUE **)&ret, NULL); + ret = NULL; + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + } else { + *pval = (ASN1_VALUE *)ret; + } + + return ret != NULL; +} + +static int x509_pubkey_ex_d2i_ex(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, + char opt, ASN1_TLC *ctx, OSSL_LIB_CTX *libctx, + const char *propq) +{ + const unsigned char *in_saved = *in; + size_t publen; + X509_PUBKEY *pubkey; + int ret; + OSSL_DECODER_CTX *dctx = NULL; + unsigned char *tmpbuf = NULL; + + if (*pval == NULL && !x509_pubkey_ex_new_ex(pval, it, libctx, propq)) + return 0; + if (!x509_pubkey_ex_populate(pval, NULL)) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* This ensures that |*in| advances properly no matter what */ + if ((ret = ASN1_item_ex_d2i(pval, in, len, + ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), + tag, aclass, opt, ctx)) <= 0) + return ret; + + publen = *in - in_saved; + if (!ossl_assert(publen > 0)) { + ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR); + return 0; + } + + pubkey = (X509_PUBKEY *)*pval; + EVP_PKEY_free(pubkey->pkey); + pubkey->pkey = NULL; + + /* + * Opportunistically decode the key but remove any non fatal errors + * from the queue. Subsequent explicit attempts to decode/use the key + * will return an appropriate error. + */ + ERR_set_mark(); + /* + * Try to decode with legacy method first. This ensures that engines + * aren't overriden by providers. + */ + if ((ret = x509_pubkey_decode(&pubkey->pkey, pubkey)) == -1) { + /* -1 indicates a fatal error, like malloc failure */ + ERR_clear_last_mark(); + goto end; + } + + /* Try to decode it into an EVP_PKEY with OSSL_DECODER */ + if (ret <= 0 && !pubkey->flag_force_legacy) { + const unsigned char *p; + char txtoidname[OSSL_MAX_NAME_SIZE]; + size_t slen = publen; + + /* + * The decoders don't know how to handle anything other than Universal + * class so we modify the data accordingly. + */ + if (aclass != V_ASN1_UNIVERSAL) { + tmpbuf = OPENSSL_memdup(in_saved, publen); + if (tmpbuf == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + in_saved = tmpbuf; + *tmpbuf = V_ASN1_CONSTRUCTED | V_ASN1_SEQUENCE; + } + p = in_saved; + + if (OBJ_obj2txt(txtoidname, sizeof(txtoidname), + pubkey->algor->algorithm, 0) <= 0) { + ERR_clear_last_mark(); + goto end; + } + if ((dctx = + OSSL_DECODER_CTX_new_for_pkey(&pubkey->pkey, + "DER", "SubjectPublicKeyInfo", + txtoidname, EVP_PKEY_PUBLIC_KEY, + pubkey->libctx, + pubkey->propq)) != NULL) + /* + * As said higher up, we're being opportunistic. In other words, + * we don't care if we fail. + */ + if (OSSL_DECODER_from_data(dctx, &p, &slen)) { + if (slen != 0) { + /* + * If we successfully decoded then we *must* consume all the + * bytes. + */ + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_ASN1, EVP_R_DECODE_ERROR); + goto end; + } + } + } + + ERR_pop_to_mark(); + ret = 1; + end: + OSSL_DECODER_CTX_free(dctx); + OPENSSL_free(tmpbuf); + return ret; +} + +static int x509_pubkey_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) +{ + return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), + tag, aclass); +} + +static int x509_pubkey_ex_print(BIO *out, const ASN1_VALUE **pval, int indent, + const char *fname, const ASN1_PCTX *pctx) +{ + return ASN1_item_print(out, *pval, indent, + ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), pctx); +} + +static const ASN1_EXTERN_FUNCS x509_pubkey_ff = { + NULL, + NULL, + x509_pubkey_ex_free, + 0, /* Default clear behaviour is OK */ + NULL, + x509_pubkey_ex_i2d, + x509_pubkey_ex_print, + x509_pubkey_ex_new_ex, + x509_pubkey_ex_d2i_ex, +}; + +IMPLEMENT_EXTERN_ASN1(X509_PUBKEY, V_ASN1_SEQUENCE, x509_pubkey_ff) IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) +X509_PUBKEY *X509_PUBKEY_new_ex(OSSL_LIB_CTX *libctx, const char *propq) +{ + X509_PUBKEY *pubkey = NULL; + + pubkey = (X509_PUBKEY *)ASN1_item_new_ex(X509_PUBKEY_it(), libctx, propq); + if (!x509_pubkey_set0_libctx(pubkey, libctx, propq)) { + X509_PUBKEY_free(pubkey); + pubkey = NULL; + } + return pubkey; +} + +/* + * X509_PUBKEY_dup() must be implemented manually, because there is no + * support for it in ASN1_EXTERN_FUNCS. + */ +X509_PUBKEY *X509_PUBKEY_dup(const X509_PUBKEY *a) +{ + X509_PUBKEY *pubkey = OPENSSL_zalloc(sizeof(*pubkey)); + + if (pubkey == NULL + || !x509_pubkey_set0_libctx(pubkey, a->libctx, a->propq) + || (pubkey->algor = X509_ALGOR_dup(a->algor)) == NULL + || (pubkey->public_key = ASN1_BIT_STRING_new()) == NULL + || !ASN1_BIT_STRING_set(pubkey->public_key, + a->public_key->data, + a->public_key->length)) { + x509_pubkey_ex_free((ASN1_VALUE **)&pubkey, + ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL)); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (a->pkey != NULL) { + ERR_set_mark(); + pubkey->pkey = EVP_PKEY_dup(a->pkey); + if (pubkey->pkey == NULL) { + pubkey->flag_force_legacy = 1; + if (x509_pubkey_decode(&pubkey->pkey, pubkey) <= 0) { + x509_pubkey_ex_free((ASN1_VALUE **)&pubkey, + ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL)); + ERR_clear_last_mark(); + return NULL; + } + } + ERR_pop_to_mark(); + } + return pubkey; +} + int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) { X509_PUBKEY *pk = NULL; - if (x == NULL) + if (x == NULL || pkey == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return 0; + } - if ((pk = X509_PUBKEY_new()) == NULL) - goto error; - - if (pkey->ameth) { - if (pkey->ameth->pub_encode) { + if (pkey->ameth != NULL) { + if ((pk = X509_PUBKEY_new()) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + goto error; + } + if (pkey->ameth->pub_encode != NULL) { if (!pkey->ameth->pub_encode(pk, pkey)) { - X509err(X509_F_X509_PUBKEY_SET, - X509_R_PUBLIC_KEY_ENCODE_ERROR); + ERR_raise(ERR_LIB_X509, X509_R_PUBLIC_KEY_ENCODE_ERROR); goto error; } } else { - X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED); + ERR_raise(ERR_LIB_X509, X509_R_METHOD_NOT_SUPPORTED); goto error; } - } else { - X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM); + } else if (evp_pkey_is_provided(pkey)) { + unsigned char *der = NULL; + size_t derlen = 0; + OSSL_ENCODER_CTX *ectx = + OSSL_ENCODER_CTX_new_for_pkey(pkey, EVP_PKEY_PUBLIC_KEY, + "DER", "SubjectPublicKeyInfo", + NULL); + + if (OSSL_ENCODER_to_data(ectx, &der, &derlen)) { + const unsigned char *pder = der; + + pk = d2i_X509_PUBKEY(NULL, &pder, (long)derlen); + } + + OSSL_ENCODER_CTX_free(ectx); + OPENSSL_free(der); + } + + if (pk == NULL) { + ERR_raise(ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM); goto error; } X509_PUBKEY_free(*x); + if (!EVP_PKEY_up_ref(pkey)) { + ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR); + goto error; + } *x = pk; + + /* + * pk->pkey is NULL when using the legacy routine, but is non-NULL when + * going through the encoder, and for all intents and purposes, it's + * a perfect copy of the public key portions of |pkey|, just not the same + * instance. If that's all there was to pkey then we could simply return + * early, right here. However, some application might very well depend on + * the passed |pkey| being used and none other, so we spend a few more + * cycles throwing away the newly created |pk->pkey| and replace it with + * |pkey|. + */ + if (pk->pkey != NULL) + EVP_PKEY_free(pk->pkey); + pk->pkey = pkey; - EVP_PKEY_up_ref(pkey); return 1; error: @@ -98,20 +392,36 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) * Attempt to decode a public key. * Returns 1 on success, 0 for a decode failure and -1 for a fatal * error e.g. malloc failure. + * + * This function is #legacy. */ +static int x509_pubkey_decode(EVP_PKEY **ppkey, const X509_PUBKEY *key) +{ + EVP_PKEY *pkey; + int nid; + nid = OBJ_obj2nid(key->algor->algorithm); + if (!key->flag_force_legacy) { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e = NULL; -static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key) -{ - EVP_PKEY *pkey = EVP_PKEY_new(); + e = ENGINE_get_pkey_meth_engine(nid); + if (e == NULL) + return 0; + ENGINE_finish(e); +#else + return 0; +#endif + } + pkey = EVP_PKEY_new(); if (pkey == NULL) { - X509err(X509_F_X509_PUBKEY_DECODE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return -1; } - if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(key->algor->algorithm))) { - X509err(X509_F_X509_PUBKEY_DECODE, X509_R_UNSUPPORTED_ALGORITHM); + if (!EVP_PKEY_set_type(pkey, nid)) { + ERR_raise(ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM); goto error; } @@ -121,12 +431,10 @@ static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key) * future we could have different return codes for decode * errors and fatal errors such as malloc failure. */ - if (!pkey->ameth->pub_decode(pkey, key)) { - X509err(X509_F_X509_PUBKEY_DECODE, X509_R_PUBLIC_KEY_DECODE_ERROR); + if (!pkey->ameth->pub_decode(pkey, key)) goto error; - } } else { - X509err(X509_F_X509_PUBKEY_DECODE, X509_R_METHOD_NOT_SUPPORTED); + ERR_raise(ERR_LIB_X509, X509_R_METHOD_NOT_SUPPORTED); goto error; } @@ -138,110 +446,181 @@ static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key) return 0; } -EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key) +EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key) { - EVP_PKEY *ret = NULL; - - if (key == NULL || key->public_key == NULL) + if (key == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return NULL; + } - if (key->pkey != NULL) - return key->pkey; - - /* - * When the key ASN.1 is initially parsed an attempt is made to - * decode the public key and cache the EVP_PKEY structure. If this - * operation fails the cached value will be NULL. Parsing continues - * to allow parsing of unknown key types or unsupported forms. - * We repeat the decode operation so the appropriate errors are left - * in the queue. - */ - x509_pubkey_decode(&ret, key); - /* If decode doesn't fail something bad happened */ - if (ret != NULL) { - X509err(X509_F_X509_PUBKEY_GET0, ERR_R_INTERNAL_ERROR); - EVP_PKEY_free(ret); + if (key->pkey == NULL) { + /* We failed to decode the key when we loaded it, or it was never set */ + ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); + return NULL; } - return NULL; + return key->pkey; } -EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) +EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key) { EVP_PKEY *ret = X509_PUBKEY_get0(key); if (ret != NULL && !EVP_PKEY_up_ref(ret)) { - X509err(X509_F_X509_PUBKEY_GET, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR); ret = NULL; } return ret; } /* - * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or - * decode as X509_PUBKEY + * Now three pseudo ASN1 routines that take an EVP_PKEY structure and encode + * or decode as X509_PUBKEY */ - -EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) +static EVP_PKEY *d2i_PUBKEY_int(EVP_PKEY **a, + const unsigned char **pp, long length, + OSSL_LIB_CTX *libctx, const char *propq, + unsigned int force_legacy, + X509_PUBKEY * + (*d2i_x509_pubkey)(X509_PUBKEY **a, + const unsigned char **in, + long len)) { - X509_PUBKEY *xpk; - EVP_PKEY *pktmp; + X509_PUBKEY *xpk, *xpk2 = NULL, **pxpk = NULL; + EVP_PKEY *pktmp = NULL; const unsigned char *q; + q = *pp; - xpk = d2i_X509_PUBKEY(NULL, &q, length); - if (!xpk) - return NULL; + + /* + * If libctx or propq are non-NULL, we take advantage of the reuse + * feature. It's not generally recommended, but is safe enough for + * newly created structures. + */ + if (libctx != NULL || propq != NULL || force_legacy) { + xpk2 = OPENSSL_zalloc(sizeof(*xpk2)); + if (xpk2 == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!x509_pubkey_set0_libctx(xpk2, libctx, propq)) + goto end; + xpk2->flag_force_legacy = !!force_legacy; + pxpk = &xpk2; + } + xpk = d2i_x509_pubkey(pxpk, &q, length); + if (xpk == NULL) + goto end; pktmp = X509_PUBKEY_get(xpk); X509_PUBKEY_free(xpk); - if (!pktmp) - return NULL; + xpk2 = NULL; /* We know that xpk == xpk2 */ + if (pktmp == NULL) + goto end; *pp = q; - if (a) { + if (a != NULL) { EVP_PKEY_free(*a); *a = pktmp; } + end: + X509_PUBKEY_free(xpk2); return pktmp; } -int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp) +/* For the algorithm specific d2i functions further down */ +EVP_PKEY *ossl_d2i_PUBKEY_legacy(EVP_PKEY **a, const unsigned char **pp, + long length) { - X509_PUBKEY *xpk = NULL; - int ret; - if (!a) + return d2i_PUBKEY_int(a, pp, length, NULL, NULL, 1, d2i_X509_PUBKEY); +} + +EVP_PKEY *d2i_PUBKEY_ex(EVP_PKEY **a, const unsigned char **pp, long length, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return d2i_PUBKEY_int(a, pp, length, libctx, propq, 0, d2i_X509_PUBKEY); +} + +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) +{ + return d2i_PUBKEY_ex(a, pp, length, NULL, NULL); +} + +int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp) +{ + int ret = -1; + + if (a == NULL) return 0; - if (!X509_PUBKEY_set(&xpk, a)) - return -1; - ret = i2d_X509_PUBKEY(xpk, pp); - X509_PUBKEY_free(xpk); + if (a->ameth != NULL) { + X509_PUBKEY *xpk = NULL; + + if ((xpk = X509_PUBKEY_new()) == NULL) + return -1; + + /* pub_encode() only encode parameters, not the key itself */ + if (a->ameth->pub_encode != NULL && a->ameth->pub_encode(xpk, a)) { + xpk->pkey = (EVP_PKEY *)a; + ret = i2d_X509_PUBKEY(xpk, pp); + xpk->pkey = NULL; + } + X509_PUBKEY_free(xpk); + } else if (a->keymgmt != NULL) { + OSSL_ENCODER_CTX *ctx = + OSSL_ENCODER_CTX_new_for_pkey(a, EVP_PKEY_PUBLIC_KEY, + "DER", "SubjectPublicKeyInfo", + NULL); + BIO *out = BIO_new(BIO_s_mem()); + BUF_MEM *buf = NULL; + + if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0 + && out != NULL + && OSSL_ENCODER_to_bio(ctx, out) + && BIO_get_mem_ptr(out, &buf) > 0) { + ret = buf->length; + + if (pp != NULL) { + if (*pp == NULL) { + *pp = (unsigned char *)buf->data; + buf->length = 0; + buf->data = NULL; + } else { + memcpy(*pp, buf->data, ret); + *pp += ret; + } + } + } + BIO_free(out); + OSSL_ENCODER_CTX_free(ctx); + } + return ret; } /* * The following are equivalents but which return RSA and DSA keys */ -#ifndef OPENSSL_NO_RSA RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length) { EVP_PKEY *pkey; - RSA *key; + RSA *key = NULL; const unsigned char *q; + q = *pp; - pkey = d2i_PUBKEY(NULL, &q, length); - if (!pkey) + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) return NULL; key = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); - if (!key) + if (key == NULL) return NULL; *pp = q; - if (a) { + if (a != NULL) { RSA_free(*a); *a = key; } return key; } -int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp) +int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp) { EVP_PKEY *pktmp; int ret; @@ -249,11 +628,95 @@ int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp) return 0; pktmp = EVP_PKEY_new(); if (pktmp == NULL) { - ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } - EVP_PKEY_set1_RSA(pktmp, a); + (void)EVP_PKEY_assign_RSA(pktmp, (RSA *)a); ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} + +#ifndef OPENSSL_NO_DH +DH *ossl_d2i_DH_PUBKEY(DH **a, const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + DH *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + if (EVP_PKEY_get_id(pkey) == EVP_PKEY_DH) + key = EVP_PKEY_get1_DH(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + DH_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_DH_PUBKEY(const DH *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (pktmp == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign_DH(pktmp, (DH *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} + +DH *ossl_d2i_DHx_PUBKEY(DH **a, const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + DH *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + if (EVP_PKEY_get_id(pkey) == EVP_PKEY_DHX) + key = EVP_PKEY_get1_DH(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + DH_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_DHx_PUBKEY(const DH *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (pktmp == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign(pktmp, EVP_PKEY_DHX, (DH *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; EVP_PKEY_free(pktmp); return ret; } @@ -263,25 +726,50 @@ int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp) DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length) { EVP_PKEY *pkey; - DSA *key; + DSA *key = NULL; const unsigned char *q; + q = *pp; - pkey = d2i_PUBKEY(NULL, &q, length); - if (!pkey) + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) return NULL; key = EVP_PKEY_get1_DSA(pkey); EVP_PKEY_free(pkey); - if (!key) + if (key == NULL) return NULL; *pp = q; - if (a) { + if (a != NULL) { + DSA_free(*a); + *a = key; + } + return key; +} + +/* Called from decoders; disallows provided DSA keys without parameters. */ +DSA *ossl_d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length) +{ + DSA *key = NULL; + const unsigned char *data; + const BIGNUM *p, *q, *g; + + data = *pp; + key = d2i_DSA_PUBKEY(NULL, &data, length); + if (key == NULL) + return NULL; + DSA_get0_pqg(key, &p, &q, &g); + if (p == NULL || q == NULL || g == NULL) { + DSA_free(key); + return NULL; + } + *pp = data; + if (a != NULL) { DSA_free(*a); *a = key; } return key; } -int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp) +int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp) { EVP_PKEY *pktmp; int ret; @@ -289,11 +777,12 @@ int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp) return 0; pktmp = EVP_PKEY_new(); if (pktmp == NULL) { - ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } - EVP_PKEY_set1_DSA(pktmp, a); + (void)EVP_PKEY_assign_DSA(pktmp, (DSA *)a); ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; EVP_PKEY_free(pktmp); return ret; } @@ -303,39 +792,213 @@ int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp) EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length) { EVP_PKEY *pkey; - EC_KEY *key; + EC_KEY *key = NULL; const unsigned char *q; + int type; + q = *pp; - pkey = d2i_PUBKEY(NULL, &q, length); - if (!pkey) + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) return NULL; - key = EVP_PKEY_get1_EC_KEY(pkey); + type = EVP_PKEY_get_id(pkey); + if (type == EVP_PKEY_EC || type == EVP_PKEY_SM2) + key = EVP_PKEY_get1_EC_KEY(pkey); EVP_PKEY_free(pkey); - if (!key) + if (key == NULL) return NULL; *pp = q; - if (a) { + if (a != NULL) { EC_KEY_free(*a); *a = key; } return key; } -int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp) +int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp) { EVP_PKEY *pktmp; int ret; - if (!a) + + if (a == NULL) return 0; if ((pktmp = EVP_PKEY_new()) == NULL) { - ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } - EVP_PKEY_set1_EC_KEY(pktmp, a); + (void)EVP_PKEY_assign_EC_KEY(pktmp, (EC_KEY *)a); ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; EVP_PKEY_free(pktmp); return ret; } + +ECX_KEY *ossl_d2i_ED25519_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + ECX_KEY *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + key = ossl_evp_pkey_get1_ED25519(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + ossl_ecx_key_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_ED25519_PUBKEY(const ECX_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + + if (a == NULL) + return 0; + if ((pktmp = EVP_PKEY_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED25519, (ECX_KEY *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} + +ECX_KEY *ossl_d2i_ED448_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + ECX_KEY *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + if (EVP_PKEY_get_id(pkey) == EVP_PKEY_ED448) + key = ossl_evp_pkey_get1_ED448(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + ossl_ecx_key_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_ED448_PUBKEY(const ECX_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + + if (a == NULL) + return 0; + if ((pktmp = EVP_PKEY_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED448, (ECX_KEY *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} + +ECX_KEY *ossl_d2i_X25519_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + ECX_KEY *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + if (EVP_PKEY_get_id(pkey) == EVP_PKEY_X25519) + key = ossl_evp_pkey_get1_X25519(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + ossl_ecx_key_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_X25519_PUBKEY(const ECX_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + + if (a == NULL) + return 0; + if ((pktmp = EVP_PKEY_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X25519, (ECX_KEY *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} + +ECX_KEY *ossl_d2i_X448_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + ECX_KEY *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + if (EVP_PKEY_get_id(pkey) == EVP_PKEY_X448) + key = ossl_evp_pkey_get1_X448(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + ossl_ecx_key_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_X448_PUBKEY(const ECX_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + + if (a == NULL) + return 0; + if ((pktmp = EVP_PKEY_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X448, (ECX_KEY *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} + #endif int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, @@ -357,7 +1020,7 @@ int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, - X509_ALGOR **pa, X509_PUBKEY *pub) + X509_ALGOR **pa, const X509_PUBKEY *pub) { if (ppkalg) *ppkalg = pub->algor->algorithm; @@ -376,3 +1039,34 @@ ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) return NULL; return x->cert_info.key->public_key; } + +/* Returns 1 for equal, 0, for non-equal, < 0 on error */ +int X509_PUBKEY_eq(const X509_PUBKEY *a, const X509_PUBKEY *b) +{ + X509_ALGOR *algA, *algB; + EVP_PKEY *pA, *pB; + + if (a == b) + return 1; + if (a == NULL || b == NULL) + return 0; + if (!X509_PUBKEY_get0_param(NULL, NULL, NULL, &algA, a) || algA == NULL + || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algB, b) || algB == NULL) + return -2; + if (X509_ALGOR_cmp(algA, algB) != 0) + return 0; + if ((pA = X509_PUBKEY_get0(a)) == NULL + || (pB = X509_PUBKEY_get0(b)) == NULL) + return -2; + return EVP_PKEY_eq(pA, pB); +} + +int ossl_x509_PUBKEY_get0_libctx(OSSL_LIB_CTX **plibctx, const char **ppropq, + const X509_PUBKEY *key) +{ + if (plibctx) + *plibctx = key->libctx; + if (ppropq) + *ppropq = key->propq; + return 1; +} diff --git a/crypto/openssl/crypto/x509/x_req.c b/crypto/openssl/crypto/x509/x_req.c index d2b02f6dae86..293d4be71335 100644 --- a/crypto/openssl/crypto/x509/x_req.c +++ b/crypto/openssl/crypto/x509/x_req.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -45,6 +45,67 @@ static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, return 1; } +static int req_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509_REQ *ret = (X509_REQ *)*pval; + + switch (operation) { + case ASN1_OP_D2I_PRE: + ASN1_OCTET_STRING_free(ret->distinguishing_id); + /* fall thru */ + case ASN1_OP_NEW_POST: + ret->distinguishing_id = NULL; + break; + + case ASN1_OP_FREE_POST: + ASN1_OCTET_STRING_free(ret->distinguishing_id); + OPENSSL_free(ret->propq); + break; + case ASN1_OP_DUP_POST: + { + X509_REQ *old = exarg; + + if (!ossl_x509_req_set0_libctx(ret, old->libctx, old->propq)) + return 0; + if (old->req_info.pubkey != NULL) { + EVP_PKEY *pkey = X509_PUBKEY_get0(old->req_info.pubkey); + + if (pkey != NULL) { + pkey = EVP_PKEY_dup(pkey); + if (pkey == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!X509_PUBKEY_set(&ret->req_info.pubkey, pkey)) { + EVP_PKEY_free(pkey); + ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR); + return 0; + } + EVP_PKEY_free(pkey); + } + } + } + break; + case ASN1_OP_GET0_LIBCTX: + { + OSSL_LIB_CTX **libctx = exarg; + + *libctx = ret->libctx; + } + break; + case ASN1_OP_GET0_PROPQ: + { + const char **propq = exarg; + + *propq = ret->propq; + } + break; + } + + return 1; +} + ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER), ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME), @@ -57,7 +118,7 @@ ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO) -ASN1_SEQUENCE_ref(X509_REQ, 0) = { +ASN1_SEQUENCE_ref(X509_REQ, req_cb) = { ASN1_EMBED(X509_REQ, req_info, X509_REQ_INFO), ASN1_EMBED(X509_REQ, sig_alg, X509_ALGOR), ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING) @@ -66,3 +127,47 @@ ASN1_SEQUENCE_ref(X509_REQ, 0) = { IMPLEMENT_ASN1_FUNCTIONS(X509_REQ) IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ) + +void X509_REQ_set0_distinguishing_id(X509_REQ *x, ASN1_OCTET_STRING *d_id) +{ + ASN1_OCTET_STRING_free(x->distinguishing_id); + x->distinguishing_id = d_id; +} + +ASN1_OCTET_STRING *X509_REQ_get0_distinguishing_id(X509_REQ *x) +{ + return x->distinguishing_id; +} + +/* + * This should only be used if the X509_REQ object was embedded inside another + * asn1 object and it needs a libctx to operate. + * Use X509_REQ_new_ex() instead if possible. + */ +int ossl_x509_req_set0_libctx(X509_REQ *x, OSSL_LIB_CTX *libctx, + const char *propq) +{ + if (x != NULL) { + x->libctx = libctx; + OPENSSL_free(x->propq); + x->propq = NULL; + if (propq != NULL) { + x->propq = OPENSSL_strdup(propq); + if (x->propq == NULL) + return 0; + } + } + return 1; +} + +X509_REQ *X509_REQ_new_ex(OSSL_LIB_CTX *libctx, const char *propq) +{ + X509_REQ *req = NULL; + + req = (X509_REQ *)ASN1_item_new((X509_REQ_it())); + if (!ossl_x509_req_set0_libctx(req, libctx, propq)) { + X509_REQ_free(req); + req = NULL; + } + return req; +} diff --git a/crypto/openssl/crypto/x509/x_x509.c b/crypto/openssl/crypto/x509/x_x509.c index 7aa8b77ae73a..010578b19a31 100644 --- a/crypto/openssl/crypto/x509/x_x509.c +++ b/crypto/openssl/crypto/x509/x_x509.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -31,7 +31,7 @@ ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) /* X509 top level structure needs a bit of customisation */ -extern void policy_cache_free(X509_POLICY_CACHE *cache); +extern void ossl_policy_cache_free(X509_POLICY_CACHE *cache); static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) @@ -46,13 +46,14 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ASN1_OCTET_STRING_free(ret->skid); AUTHORITY_KEYID_free(ret->akid); CRL_DIST_POINTS_free(ret->crldp); - policy_cache_free(ret->policy_cache); + ossl_policy_cache_free(ret->policy_cache); GENERAL_NAMES_free(ret->altname); NAME_CONSTRAINTS_free(ret->nc); #ifndef OPENSSL_NO_RFC3779 sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); ASIdentifiers_free(ret->rfc3779_asid); #endif + ASN1_OCTET_STRING_free(ret->distinguishing_id); /* fall thru */ @@ -73,6 +74,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ret->rfc3779_addr = NULL; ret->rfc3779_asid = NULL; #endif + ret->distinguishing_id = NULL; ret->aux = NULL; ret->crldp = NULL; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data)) @@ -85,19 +87,46 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ASN1_OCTET_STRING_free(ret->skid); AUTHORITY_KEYID_free(ret->akid); CRL_DIST_POINTS_free(ret->crldp); - policy_cache_free(ret->policy_cache); + ossl_policy_cache_free(ret->policy_cache); GENERAL_NAMES_free(ret->altname); NAME_CONSTRAINTS_free(ret->nc); #ifndef OPENSSL_NO_RFC3779 sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); ASIdentifiers_free(ret->rfc3779_asid); #endif + ASN1_OCTET_STRING_free(ret->distinguishing_id); + OPENSSL_free(ret->propq); break; + case ASN1_OP_DUP_POST: + { + X509 *old = exarg; + + if (!ossl_x509_set0_libctx(ret, old->libctx, old->propq)) + return 0; + } + break; + case ASN1_OP_GET0_LIBCTX: + { + OSSL_LIB_CTX **libctx = exarg; + + *libctx = ret->libctx; + } + break; + + case ASN1_OP_GET0_PROPQ: + { + const char **propq = exarg; + + *propq = ret->propq; + } + break; + + default: + break; } return 1; - } ASN1_SEQUENCE_ref(X509, x509_cb) = { @@ -107,15 +136,46 @@ ASN1_SEQUENCE_ref(X509, x509_cb) = { } ASN1_SEQUENCE_END_ref(X509, X509) IMPLEMENT_ASN1_FUNCTIONS(X509) - IMPLEMENT_ASN1_DUP_FUNCTION(X509) +/* + * This should only be used if the X509 object was embedded inside another + * asn1 object and it needs a libctx to operate. + * Use X509_new_ex() instead if possible. + */ +int ossl_x509_set0_libctx(X509 *x, OSSL_LIB_CTX *libctx, const char *propq) +{ + if (x != NULL) { + x->libctx = libctx; + OPENSSL_free(x->propq); + x->propq = NULL; + if (propq != NULL) { + x->propq = OPENSSL_strdup(propq); + if (x->propq == NULL) + return 0; + } + } + return 1; +} + +X509 *X509_new_ex(OSSL_LIB_CTX *libctx, const char *propq) +{ + X509 *cert = NULL; + + cert = (X509 *)ASN1_item_new_ex(X509_it(), libctx, propq); + if (!ossl_x509_set0_libctx(cert, libctx, propq)) { + X509_free(cert); + cert = NULL; + } + return cert; +} + int X509_set_ex_data(X509 *r, int idx, void *arg) { return CRYPTO_set_ex_data(&r->ex_data, idx, arg); } -void *X509_get_ex_data(X509 *r, int idx) +void *X509_get_ex_data(const X509 *r, int idx) { return CRYPTO_get_ex_data(&r->ex_data, idx); } @@ -163,7 +223,7 @@ X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) * error path, but that depends on similar hygiene in lower-level functions. * Here we avoid compounding the problem. */ -static int i2d_x509_aux_internal(X509 *a, unsigned char **pp) +static int i2d_x509_aux_internal(const X509 *a, unsigned char **pp) { int length, tmplen; unsigned char *start = pp != NULL ? *pp : NULL; @@ -197,7 +257,7 @@ static int i2d_x509_aux_internal(X509 *a, unsigned char **pp) * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the * allocated buffer. */ -int i2d_X509_AUX(X509 *a, unsigned char **pp) +int i2d_X509_AUX(const X509 *a, unsigned char **pp) { int length; unsigned char *tmp; @@ -213,7 +273,7 @@ int i2d_X509_AUX(X509 *a, unsigned char **pp) /* Allocate requisite combined storage */ *pp = tmp = OPENSSL_malloc(length); if (tmp == NULL) { - X509err(X509_F_I2D_X509_AUX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return -1; } @@ -245,3 +305,14 @@ int X509_get_signature_nid(const X509 *x) { return OBJ_obj2nid(x->sig_alg.algorithm); } + +void X509_set0_distinguishing_id(X509 *x, ASN1_OCTET_STRING *d_id) +{ + ASN1_OCTET_STRING_free(x->distinguishing_id); + x->distinguishing_id = d_id; +} + +ASN1_OCTET_STRING *X509_get0_distinguishing_id(X509 *x) +{ + return x->distinguishing_id; +} diff --git a/crypto/openssl/crypto/x509/x_x509a.c b/crypto/openssl/crypto/x509/x_x509a.c index c5175faef7af..f7953c269e7c 100644 --- a/crypto/openssl/crypto/x509/x_x509a.c +++ b/crypto/openssl/crypto/x509/x_x509a.c @@ -1,7 +1,7 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -125,6 +125,8 @@ int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj) { X509_CERT_AUX *aux; ASN1_OBJECT *objtmp; + int res = 0; + if ((objtmp = OBJ_dup(obj)) == NULL) return 0; if ((aux = aux_get(x)) == NULL) @@ -132,10 +134,13 @@ int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj) if (aux->reject == NULL && (aux->reject = sk_ASN1_OBJECT_new_null()) == NULL) goto err; - return sk_ASN1_OBJECT_push(aux->reject, objtmp); + if (sk_ASN1_OBJECT_push(aux->reject, objtmp) > 0) + res = 1; + err: - ASN1_OBJECT_free(objtmp); - return 0; + if (!res) + ASN1_OBJECT_free(objtmp); + return res; } void X509_trust_clear(X509 *x) diff --git a/crypto/openssl/crypto/x509v3/build.info b/crypto/openssl/crypto/x509v3/build.info deleted file mode 100644 index 4ab648849367..000000000000 --- a/crypto/openssl/crypto/x509v3/build.info +++ /dev/null @@ -1,8 +0,0 @@ -LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_lib.c \ - v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c v3_skey.c v3_akey.c v3_pku.c \ - v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c v3_info.c \ - v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c v3_pcia.c v3_pci.c \ - pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \ - v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c diff --git a/crypto/openssl/crypto/x509v3/ext_dat.h b/crypto/openssl/crypto/x509v3/ext_dat.h deleted file mode 100644 index 762e264bb22d..000000000000 --- a/crypto/openssl/crypto/x509v3/ext_dat.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 1999-2017 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 - */ - -int name_cmp(const char *name, const char *cmp); - -extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; -extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo; -extern const X509V3_EXT_METHOD v3_ns_ia5_list[8], v3_alt[3], v3_skey_id, v3_akey_id; -extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; -extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl; -extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; -extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; -extern const X509V3_EXT_METHOD v3_crl_hold, v3_pci; -extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; -extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; -extern const X509V3_EXT_METHOD v3_addr, v3_asid; -extern const X509V3_EXT_METHOD v3_ct_scts[3]; -extern const X509V3_EXT_METHOD v3_tls_feature; -extern const X509V3_EXT_METHOD v3_ext_admission; diff --git a/crypto/openssl/crypto/x509v3/standard_exts.h b/crypto/openssl/crypto/x509v3/standard_exts.h deleted file mode 100644 index 944f4de02eb5..000000000000 --- a/crypto/openssl/crypto/x509v3/standard_exts.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 1999-2017 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 - */ - -/* - * This table will be searched using OBJ_bsearch so it *must* kept in order - * of the ext_nid values. - */ - -static const X509V3_EXT_METHOD *standard_exts[] = { - &v3_nscert, - &v3_ns_ia5_list[0], - &v3_ns_ia5_list[1], - &v3_ns_ia5_list[2], - &v3_ns_ia5_list[3], - &v3_ns_ia5_list[4], - &v3_ns_ia5_list[5], - &v3_ns_ia5_list[6], - &v3_skey_id, - &v3_key_usage, - &v3_pkey_usage_period, - &v3_alt[0], - &v3_alt[1], - &v3_bcons, - &v3_crl_num, - &v3_cpols, - &v3_akey_id, - &v3_crld, - &v3_ext_ku, - &v3_delta_crl, - &v3_crl_reason, -#ifndef OPENSSL_NO_OCSP - &v3_crl_invdate, -#endif - &v3_sxnet, - &v3_info, -#ifndef OPENSSL_NO_RFC3779 - &v3_addr, - &v3_asid, -#endif -#ifndef OPENSSL_NO_OCSP - &v3_ocsp_nonce, - &v3_ocsp_crlid, - &v3_ocsp_accresp, - &v3_ocsp_nocheck, - &v3_ocsp_acutoff, - &v3_ocsp_serviceloc, -#endif - &v3_sinfo, - &v3_policy_constraints, -#ifndef OPENSSL_NO_OCSP - &v3_crl_hold, -#endif - &v3_pci, - &v3_name_constraints, - &v3_policy_mappings, - &v3_inhibit_anyp, - &v3_idp, - &v3_alt[2], - &v3_freshest_crl, -#ifndef OPENSSL_NO_CT - &v3_ct_scts[0], - &v3_ct_scts[1], - &v3_ct_scts[2], -#endif - &v3_tls_feature, - &v3_ext_admission -}; - -/* Number of standard extensions */ - -#define STANDARD_EXTENSION_COUNT OSSL_NELEM(standard_exts) - diff --git a/crypto/openssl/crypto/x86_64cpuid.S b/crypto/openssl/crypto/x86_64cpuid.S new file mode 100644 index 000000000000..6a5180311ccc --- /dev/null +++ b/crypto/openssl/crypto/x86_64cpuid.S @@ -0,0 +1,512 @@ + +.hidden OPENSSL_cpuid_setup +.section .init + call OPENSSL_cpuid_setup + +.hidden OPENSSL_ia32cap_P +.comm OPENSSL_ia32cap_P,16,4 + +.text + +.globl OPENSSL_atomic_add +.type OPENSSL_atomic_add,@function +.align 16 +OPENSSL_atomic_add: +.cfi_startproc +.byte 243,15,30,250 + movl (%rdi),%eax +.Lspin: leaq (%rsi,%rax,1),%r8 +.byte 0xf0 + cmpxchgl %r8d,(%rdi) + jne .Lspin + movl %r8d,%eax +.byte 0x48,0x98 + .byte 0xf3,0xc3 +.cfi_endproc +.size OPENSSL_atomic_add,.-OPENSSL_atomic_add + +.globl OPENSSL_rdtsc +.type OPENSSL_rdtsc,@function +.align 16 +OPENSSL_rdtsc: +.cfi_startproc +.byte 243,15,30,250 + rdtsc + shlq $32,%rdx + orq %rdx,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size OPENSSL_rdtsc,.-OPENSSL_rdtsc + +.globl OPENSSL_ia32_cpuid +.type OPENSSL_ia32_cpuid,@function +.align 16 +OPENSSL_ia32_cpuid: +.cfi_startproc +.byte 243,15,30,250 + movq %rbx,%r8 +.cfi_register %rbx,%r8 + + xorl %eax,%eax + movq %rax,8(%rdi) + cpuid + movl %eax,%r11d + + xorl %eax,%eax + cmpl $0x756e6547,%ebx + setne %al + movl %eax,%r9d + cmpl $0x49656e69,%edx + setne %al + orl %eax,%r9d + cmpl $0x6c65746e,%ecx + setne %al + orl %eax,%r9d + jz .Lintel + + cmpl $0x68747541,%ebx + setne %al + movl %eax,%r10d + cmpl $0x69746E65,%edx + setne %al + orl %eax,%r10d + cmpl $0x444D4163,%ecx + setne %al + orl %eax,%r10d + jnz .Lintel + + + movl $0x80000000,%eax + cpuid + cmpl $0x80000001,%eax + jb .Lintel + movl %eax,%r10d + movl $0x80000001,%eax + cpuid + orl %ecx,%r9d + andl $0x00000801,%r9d + + cmpl $0x80000008,%r10d + jb .Lintel + + movl $0x80000008,%eax + cpuid + movzbq %cl,%r10 + incq %r10 + + movl $1,%eax + cpuid + btl $28,%edx + jnc .Lgeneric + shrl $16,%ebx + cmpb %r10b,%bl + ja .Lgeneric + andl $0xefffffff,%edx + jmp .Lgeneric + +.Lintel: + cmpl $4,%r11d + movl $-1,%r10d + jb .Lnocacheinfo + + movl $4,%eax + movl $0,%ecx + cpuid + movl %eax,%r10d + shrl $14,%r10d + andl $0xfff,%r10d + +.Lnocacheinfo: + movl $1,%eax + cpuid + movd %eax,%xmm0 + andl $0xbfefffff,%edx + cmpl $0,%r9d + jne .Lnotintel + orl $0x40000000,%edx + andb $15,%ah + cmpb $15,%ah + jne .LnotP4 + orl $0x00100000,%edx +.LnotP4: + cmpb $6,%ah + jne .Lnotintel + andl $0x0fff0ff0,%eax + cmpl $0x00050670,%eax + je .Lknights + cmpl $0x00080650,%eax + jne .Lnotintel +.Lknights: + andl $0xfbffffff,%ecx + +.Lnotintel: + btl $28,%edx + jnc .Lgeneric + andl $0xefffffff,%edx + cmpl $0,%r10d + je .Lgeneric + + orl $0x10000000,%edx + shrl $16,%ebx + cmpb $1,%bl + ja .Lgeneric + andl $0xefffffff,%edx +.Lgeneric: + andl $0x00000800,%r9d + andl $0xfffff7ff,%ecx + orl %ecx,%r9d + + movl %edx,%r10d + + cmpl $7,%r11d + jb .Lno_extended_info + movl $7,%eax + xorl %ecx,%ecx + cpuid + btl $26,%r9d + jc .Lnotknights + andl $0xfff7ffff,%ebx +.Lnotknights: + movd %xmm0,%eax + andl $0x0fff0ff0,%eax + cmpl $0x00050650,%eax + jne .Lnotskylakex + andl $0xfffeffff,%ebx + +.Lnotskylakex: + movl %ebx,8(%rdi) + movl %ecx,12(%rdi) +.Lno_extended_info: + + btl $27,%r9d + jnc .Lclear_avx + xorl %ecx,%ecx +.byte 0x0f,0x01,0xd0 + andl $0xe6,%eax + cmpl $0xe6,%eax + je .Ldone + andl $0x3fdeffff,8(%rdi) + + + + + andl $6,%eax + cmpl $6,%eax + je .Ldone +.Lclear_avx: + movl $0xefffe7ff,%eax + andl %eax,%r9d + movl $0x3fdeffdf,%eax + andl %eax,8(%rdi) +.Ldone: + shlq $32,%r9 + movl %r10d,%eax + movq %r8,%rbx +.cfi_restore %rbx + orq %r9,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid + +.globl OPENSSL_cleanse +.type OPENSSL_cleanse,@function +.align 16 +OPENSSL_cleanse: +.cfi_startproc +.byte 243,15,30,250 + xorq %rax,%rax + cmpq $15,%rsi + jae .Lot + cmpq $0,%rsi + je .Lret +.Little: + movb %al,(%rdi) + subq $1,%rsi + leaq 1(%rdi),%rdi + jnz .Little +.Lret: + .byte 0xf3,0xc3 +.align 16 +.Lot: + testq $7,%rdi + jz .Laligned + movb %al,(%rdi) + leaq -1(%rsi),%rsi + leaq 1(%rdi),%rdi + jmp .Lot +.Laligned: + movq %rax,(%rdi) + leaq -8(%rsi),%rsi + testq $-8,%rsi + leaq 8(%rdi),%rdi + jnz .Laligned + cmpq $0,%rsi + jne .Little + .byte 0xf3,0xc3 +.cfi_endproc +.size OPENSSL_cleanse,.-OPENSSL_cleanse + +.globl CRYPTO_memcmp +.type CRYPTO_memcmp,@function +.align 16 +CRYPTO_memcmp: +.cfi_startproc +.byte 243,15,30,250 + xorq %rax,%rax + xorq %r10,%r10 + cmpq $0,%rdx + je .Lno_data + cmpq $16,%rdx + jne .Loop_cmp + movq (%rdi),%r10 + movq 8(%rdi),%r11 + movq $1,%rdx + xorq (%rsi),%r10 + xorq 8(%rsi),%r11 + orq %r11,%r10 + cmovnzq %rdx,%rax + .byte 0xf3,0xc3 + +.align 16 +.Loop_cmp: + movb (%rdi),%r10b + leaq 1(%rdi),%rdi + xorb (%rsi),%r10b + leaq 1(%rsi),%rsi + orb %r10b,%al + decq %rdx + jnz .Loop_cmp + negq %rax + shrq $63,%rax +.Lno_data: + .byte 0xf3,0xc3 +.cfi_endproc +.size CRYPTO_memcmp,.-CRYPTO_memcmp +.globl OPENSSL_wipe_cpu +.type OPENSSL_wipe_cpu,@function +.align 16 +OPENSSL_wipe_cpu: +.cfi_startproc +.byte 243,15,30,250 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 + pxor %xmm10,%xmm10 + pxor %xmm11,%xmm11 + pxor %xmm12,%xmm12 + pxor %xmm13,%xmm13 + pxor %xmm14,%xmm14 + pxor %xmm15,%xmm15 + xorq %rcx,%rcx + xorq %rdx,%rdx + xorq %rsi,%rsi + xorq %rdi,%rdi + xorq %r8,%r8 + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + leaq 8(%rsp),%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu +.globl OPENSSL_instrument_bus +.type OPENSSL_instrument_bus,@function +.align 16 +OPENSSL_instrument_bus: +.cfi_startproc +.byte 243,15,30,250 + movq %rdi,%r10 + movq %rsi,%rcx + movq %rsi,%r11 + + rdtsc + movl %eax,%r8d + movl $0,%r9d + clflush (%r10) +.byte 0xf0 + addl %r9d,(%r10) + jmp .Loop +.align 16 +.Loop: rdtsc + movl %eax,%edx + subl %r8d,%eax + movl %edx,%r8d + movl %eax,%r9d + clflush (%r10) +.byte 0xf0 + addl %eax,(%r10) + leaq 4(%r10),%r10 + subq $1,%rcx + jnz .Loop + + movq %r11,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size OPENSSL_instrument_bus,.-OPENSSL_instrument_bus + +.globl OPENSSL_instrument_bus2 +.type OPENSSL_instrument_bus2,@function +.align 16 +OPENSSL_instrument_bus2: +.cfi_startproc +.byte 243,15,30,250 + movq %rdi,%r10 + movq %rsi,%rcx + movq %rdx,%r11 + movq %rcx,8(%rsp) + + rdtsc + movl %eax,%r8d + movl $0,%r9d + + clflush (%r10) +.byte 0xf0 + addl %r9d,(%r10) + + rdtsc + movl %eax,%edx + subl %r8d,%eax + movl %edx,%r8d + movl %eax,%r9d +.Loop2: + clflush (%r10) +.byte 0xf0 + addl %eax,(%r10) + + subq $1,%r11 + jz .Ldone2 + + rdtsc + movl %eax,%edx + subl %r8d,%eax + movl %edx,%r8d + cmpl %r9d,%eax + movl %eax,%r9d + movl $0,%edx + setne %dl + subq %rdx,%rcx + leaq (%r10,%rdx,4),%r10 + jnz .Loop2 + +.Ldone2: + movq 8(%rsp),%rax + subq %rcx,%rax + .byte 0xf3,0xc3 +.cfi_endproc +.size OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2 +.globl OPENSSL_ia32_rdrand_bytes +.type OPENSSL_ia32_rdrand_bytes,@function +.align 16 +OPENSSL_ia32_rdrand_bytes: +.cfi_startproc +.byte 243,15,30,250 + xorq %rax,%rax + cmpq $0,%rsi + je .Ldone_rdrand_bytes + + movq $8,%r11 +.Loop_rdrand_bytes: +.byte 73,15,199,242 + jc .Lbreak_rdrand_bytes + decq %r11 + jnz .Loop_rdrand_bytes + jmp .Ldone_rdrand_bytes + +.align 16 +.Lbreak_rdrand_bytes: + cmpq $8,%rsi + jb .Ltail_rdrand_bytes + movq %r10,(%rdi) + leaq 8(%rdi),%rdi + addq $8,%rax + subq $8,%rsi + jz .Ldone_rdrand_bytes + movq $8,%r11 + jmp .Loop_rdrand_bytes + +.align 16 +.Ltail_rdrand_bytes: + movb %r10b,(%rdi) + leaq 1(%rdi),%rdi + incq %rax + shrq $8,%r10 + decq %rsi + jnz .Ltail_rdrand_bytes + +.Ldone_rdrand_bytes: + xorq %r10,%r10 + .byte 0xf3,0xc3 +.cfi_endproc +.size OPENSSL_ia32_rdrand_bytes,.-OPENSSL_ia32_rdrand_bytes +.globl OPENSSL_ia32_rdseed_bytes +.type OPENSSL_ia32_rdseed_bytes,@function +.align 16 +OPENSSL_ia32_rdseed_bytes: +.cfi_startproc +.byte 243,15,30,250 + xorq %rax,%rax + cmpq $0,%rsi + je .Ldone_rdseed_bytes + + movq $8,%r11 +.Loop_rdseed_bytes: +.byte 73,15,199,250 + jc .Lbreak_rdseed_bytes + decq %r11 + jnz .Loop_rdseed_bytes + jmp .Ldone_rdseed_bytes + +.align 16 +.Lbreak_rdseed_bytes: + cmpq $8,%rsi + jb .Ltail_rdseed_bytes + movq %r10,(%rdi) + leaq 8(%rdi),%rdi + addq $8,%rax + subq $8,%rsi + jz .Ldone_rdseed_bytes + movq $8,%r11 + jmp .Loop_rdseed_bytes + +.align 16 +.Ltail_rdseed_bytes: + movb %r10b,(%rdi) + leaq 1(%rdi),%rdi + incq %rax + shrq $8,%r10 + decq %rsi + jnz .Ltail_rdseed_bytes + +.Ldone_rdseed_bytes: + xorq %r10,%r10 + .byte 0xf3,0xc3 +.cfi_endproc +.size OPENSSL_ia32_rdseed_bytes,.-OPENSSL_ia32_rdseed_bytes + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + # "GNU" encoded with .byte, since .asciz isn't supported + # on Solaris. + .byte 0x47 + .byte 0x4e + .byte 0x55 + .byte 0 +1: + .p2align 3 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 3 +4: diff --git a/crypto/openssl/crypto/x86_64cpuid.pl b/crypto/openssl/crypto/x86_64cpuid.pl index d9536d65768f..53685ec26390 100755 --- a/crypto/openssl/crypto/x86_64cpuid.pl +++ b/crypto/openssl/crypto/x86_64cpuid.pl @@ -1,15 +1,16 @@ #! /usr/bin/env perl -# Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); @@ -18,7 +19,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}perlasm/x86_64-xlate.pl" and -f $xlate) or die "can't locate x86_64-xlate.pl"; -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; *STDOUT=*OUT; ($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order @@ -40,6 +42,7 @@ print<<___; .align 16 OPENSSL_atomic_add: .cfi_startproc + endbranch movl ($arg1),%eax .Lspin: leaq ($arg2,%rax),%r8 .byte 0xf0 # lock @@ -56,6 +59,7 @@ OPENSSL_atomic_add: .align 16 OPENSSL_rdtsc: .cfi_startproc + endbranch rdtsc shl \$32,%rdx or %rdx,%rax @@ -68,6 +72,7 @@ OPENSSL_rdtsc: .align 16 OPENSSL_ia32_cpuid: .cfi_startproc + endbranch mov %rbx,%r8 # save %rbx .cfi_register %rbx,%r8 @@ -210,7 +215,7 @@ OPENSSL_ia32_cpuid: cmp \$0xe6,%eax je .Ldone andl \$0x3fdeffff,8(%rdi) # ~(1<<31|1<<30|1<<21|1<<16) - # clear AVX512F+BW+VL+FIMA, all of + # clear AVX512F+BW+VL+IFMA, all of # them are EVEX-encoded, which requires # ZMM state support even if one uses # only XMM and YMM :-( @@ -237,6 +242,7 @@ OPENSSL_ia32_cpuid: .align 16 OPENSSL_cleanse: .cfi_startproc + endbranch xor %rax,%rax cmp \$15,$arg2 jae .Lot @@ -274,6 +280,7 @@ OPENSSL_cleanse: .align 16 CRYPTO_memcmp: .cfi_startproc + endbranch xor %rax,%rax xor %r10,%r10 cmp \$0,$arg3 @@ -312,6 +319,7 @@ print<<___ if (!$win64); .align 16 OPENSSL_wipe_cpu: .cfi_startproc + endbranch pxor %xmm0,%xmm0 pxor %xmm1,%xmm1 pxor %xmm2,%xmm2 @@ -376,6 +384,7 @@ print<<___; .align 16 OPENSSL_instrument_bus: .cfi_startproc + endbranch mov $arg1,$out # tribute to Win64 mov $arg2,$cnt mov $arg2,$max @@ -410,6 +419,7 @@ OPENSSL_instrument_bus: .align 16 OPENSSL_instrument_bus2: .cfi_startproc + endbranch mov $arg1,$out # tribute to Win64 mov $arg2,$cnt mov $arg3,$max @@ -465,6 +475,7 @@ print<<___; .align 16 OPENSSL_ia32_${rdop}_bytes: .cfi_startproc + endbranch xor %rax, %rax # return value cmp \$0,$arg2 je .Ldone_${rdop}_bytes diff --git a/crypto/openssl/crypto/x86cpuid.S b/crypto/openssl/crypto/x86cpuid.S new file mode 100644 index 000000000000..d4f2ec09e4e6 --- /dev/null +++ b/crypto/openssl/crypto/x86cpuid.S @@ -0,0 +1,614 @@ +.text +.globl OPENSSL_ia32_cpuid +.type OPENSSL_ia32_cpuid,@function +.align 16 +OPENSSL_ia32_cpuid: +.L_OPENSSL_ia32_cpuid_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + xorl %edx,%edx + pushfl + popl %eax + movl %eax,%ecx + xorl $2097152,%eax + pushl %eax + popfl + pushfl + popl %eax + xorl %eax,%ecx + xorl %eax,%eax + movl 20(%esp),%esi + movl %eax,8(%esi) + btl $21,%ecx + jnc .L000nocpuid + .byte 0x0f,0xa2 + movl %eax,%edi + xorl %eax,%eax + cmpl $1970169159,%ebx + setne %al + movl %eax,%ebp + cmpl $1231384169,%edx + setne %al + orl %eax,%ebp + cmpl $1818588270,%ecx + setne %al + orl %eax,%ebp + jz .L001intel + cmpl $1752462657,%ebx + setne %al + movl %eax,%esi + cmpl $1769238117,%edx + setne %al + orl %eax,%esi + cmpl $1145913699,%ecx + setne %al + orl %eax,%esi + jnz .L001intel + movl $2147483648,%eax + .byte 0x0f,0xa2 + cmpl $2147483649,%eax + jb .L001intel + movl %eax,%esi + movl $2147483649,%eax + .byte 0x0f,0xa2 + orl %ecx,%ebp + andl $2049,%ebp + cmpl $2147483656,%esi + jb .L001intel + movl $2147483656,%eax + .byte 0x0f,0xa2 + movzbl %cl,%esi + incl %esi + movl $1,%eax + xorl %ecx,%ecx + .byte 0x0f,0xa2 + btl $28,%edx + jnc .L002generic + shrl $16,%ebx + andl $255,%ebx + cmpl %esi,%ebx + ja .L002generic + andl $4026531839,%edx + jmp .L002generic +.L001intel: + cmpl $4,%edi + movl $-1,%esi + jb .L003nocacheinfo + movl $4,%eax + movl $0,%ecx + .byte 0x0f,0xa2 + movl %eax,%esi + shrl $14,%esi + andl $4095,%esi +.L003nocacheinfo: + movl $1,%eax + xorl %ecx,%ecx + .byte 0x0f,0xa2 + andl $3220176895,%edx + cmpl $0,%ebp + jne .L004notintel + orl $1073741824,%edx + andb $15,%ah + cmpb $15,%ah + jne .L004notintel + orl $1048576,%edx +.L004notintel: + btl $28,%edx + jnc .L002generic + andl $4026531839,%edx + cmpl $0,%esi + je .L002generic + orl $268435456,%edx + shrl $16,%ebx + cmpb $1,%bl + ja .L002generic + andl $4026531839,%edx +.L002generic: + andl $2048,%ebp + andl $4294965247,%ecx + movl %edx,%esi + orl %ecx,%ebp + cmpl $7,%edi + movl 20(%esp),%edi + jb .L005no_extended_info + movl $7,%eax + xorl %ecx,%ecx + .byte 0x0f,0xa2 + movl %ebx,8(%edi) +.L005no_extended_info: + btl $27,%ebp + jnc .L006clear_avx + xorl %ecx,%ecx +.byte 15,1,208 + andl $6,%eax + cmpl $6,%eax + je .L007done + cmpl $2,%eax + je .L006clear_avx +.L008clear_xmm: + andl $4261412861,%ebp + andl $4278190079,%esi +.L006clear_avx: + andl $4026525695,%ebp + andl $4294967263,8(%edi) +.L007done: + movl %esi,%eax + movl %ebp,%edx +.L000nocpuid: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size OPENSSL_ia32_cpuid,.-.L_OPENSSL_ia32_cpuid_begin +.globl OPENSSL_rdtsc +.type OPENSSL_rdtsc,@function +.align 16 +OPENSSL_rdtsc: +.L_OPENSSL_rdtsc_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + xorl %eax,%eax + xorl %edx,%edx + call .L009PIC_me_up +.L009PIC_me_up: + popl %ecx + leal OPENSSL_ia32cap_P-.L009PIC_me_up(%ecx),%ecx + btl $4,(%ecx) + jnc .L010notsc + .byte 0x0f,0x31 +.L010notsc: + ret +.size OPENSSL_rdtsc,.-.L_OPENSSL_rdtsc_begin +.globl OPENSSL_instrument_halt +.type OPENSSL_instrument_halt,@function +.align 16 +OPENSSL_instrument_halt: +.L_OPENSSL_instrument_halt_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + call .L011PIC_me_up +.L011PIC_me_up: + popl %ecx + leal OPENSSL_ia32cap_P-.L011PIC_me_up(%ecx),%ecx + btl $4,(%ecx) + jnc .L012nohalt +.long 2421723150 + andl $3,%eax + jnz .L012nohalt + pushfl + popl %eax + btl $9,%eax + jnc .L012nohalt + .byte 0x0f,0x31 + pushl %edx + pushl %eax + hlt + .byte 0x0f,0x31 + subl (%esp),%eax + sbbl 4(%esp),%edx + addl $8,%esp + ret +.L012nohalt: + xorl %eax,%eax + xorl %edx,%edx + ret +.size OPENSSL_instrument_halt,.-.L_OPENSSL_instrument_halt_begin +.globl OPENSSL_far_spin +.type OPENSSL_far_spin,@function +.align 16 +OPENSSL_far_spin: +.L_OPENSSL_far_spin_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushfl + popl %eax + btl $9,%eax + jnc .L013nospin + movl 4(%esp),%eax + movl 8(%esp),%ecx +.long 2430111262 + xorl %eax,%eax + movl (%ecx),%edx + jmp .L014spin +.align 16 +.L014spin: + incl %eax + cmpl (%ecx),%edx + je .L014spin +.long 529567888 + ret +.L013nospin: + xorl %eax,%eax + xorl %edx,%edx + ret +.size OPENSSL_far_spin,.-.L_OPENSSL_far_spin_begin +.globl OPENSSL_wipe_cpu +.type OPENSSL_wipe_cpu,@function +.align 16 +OPENSSL_wipe_cpu: +.L_OPENSSL_wipe_cpu_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + xorl %eax,%eax + xorl %edx,%edx + call .L015PIC_me_up +.L015PIC_me_up: + popl %ecx + leal OPENSSL_ia32cap_P-.L015PIC_me_up(%ecx),%ecx + movl (%ecx),%ecx + btl $1,(%ecx) + jnc .L016no_x87 + andl $83886080,%ecx + cmpl $83886080,%ecx + jne .L017no_sse2 + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 +.L017no_sse2: +.long 4007259865,4007259865,4007259865,4007259865,2430851995 +.L016no_x87: + leal 4(%esp),%eax + ret +.size OPENSSL_wipe_cpu,.-.L_OPENSSL_wipe_cpu_begin +.globl OPENSSL_atomic_add +.type OPENSSL_atomic_add,@function +.align 16 +OPENSSL_atomic_add: +.L_OPENSSL_atomic_add_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl 4(%esp),%edx + movl 8(%esp),%ecx + pushl %ebx + nop + movl (%edx),%eax +.L018spin: + leal (%eax,%ecx,1),%ebx + nop +.long 447811568 + jne .L018spin + movl %ebx,%eax + popl %ebx + ret +.size OPENSSL_atomic_add,.-.L_OPENSSL_atomic_add_begin +.globl OPENSSL_cleanse +.type OPENSSL_cleanse,@function +.align 16 +OPENSSL_cleanse: +.L_OPENSSL_cleanse_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + movl 4(%esp),%edx + movl 8(%esp),%ecx + xorl %eax,%eax + cmpl $7,%ecx + jae .L019lot + cmpl $0,%ecx + je .L020ret +.L021little: + movb %al,(%edx) + subl $1,%ecx + leal 1(%edx),%edx + jnz .L021little +.L020ret: + ret +.align 16 +.L019lot: + testl $3,%edx + jz .L022aligned + movb %al,(%edx) + leal -1(%ecx),%ecx + leal 1(%edx),%edx + jmp .L019lot +.L022aligned: + movl %eax,(%edx) + leal -4(%ecx),%ecx + testl $-4,%ecx + leal 4(%edx),%edx + jnz .L022aligned + cmpl $0,%ecx + jne .L021little + ret +.size OPENSSL_cleanse,.-.L_OPENSSL_cleanse_begin +.globl CRYPTO_memcmp +.type CRYPTO_memcmp,@function +.align 16 +CRYPTO_memcmp: +.L_CRYPTO_memcmp_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %esi + pushl %edi + movl 12(%esp),%esi + movl 16(%esp),%edi + movl 20(%esp),%ecx + xorl %eax,%eax + xorl %edx,%edx + cmpl $0,%ecx + je .L023no_data +.L024loop: + movb (%esi),%dl + leal 1(%esi),%esi + xorb (%edi),%dl + leal 1(%edi),%edi + orb %dl,%al + decl %ecx + jnz .L024loop + negl %eax + shrl $31,%eax +.L023no_data: + popl %edi + popl %esi + ret +.size CRYPTO_memcmp,.-.L_CRYPTO_memcmp_begin +.globl OPENSSL_instrument_bus +.type OPENSSL_instrument_bus,@function +.align 16 +OPENSSL_instrument_bus: +.L_OPENSSL_instrument_bus_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl $0,%eax + call .L025PIC_me_up +.L025PIC_me_up: + popl %edx + leal OPENSSL_ia32cap_P-.L025PIC_me_up(%edx),%edx + btl $4,(%edx) + jnc .L026nogo + btl $19,(%edx) + jnc .L026nogo + movl 20(%esp),%edi + movl 24(%esp),%ecx + .byte 0x0f,0x31 + movl %eax,%esi + movl $0,%ebx + clflush (%edi) +.byte 240 + addl %ebx,(%edi) + jmp .L027loop +.align 16 +.L027loop: + .byte 0x0f,0x31 + movl %eax,%edx + subl %esi,%eax + movl %edx,%esi + movl %eax,%ebx + clflush (%edi) +.byte 240 + addl %eax,(%edi) + leal 4(%edi),%edi + subl $1,%ecx + jnz .L027loop + movl 24(%esp),%eax +.L026nogo: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size OPENSSL_instrument_bus,.-.L_OPENSSL_instrument_bus_begin +.globl OPENSSL_instrument_bus2 +.type OPENSSL_instrument_bus2,@function +.align 16 +OPENSSL_instrument_bus2: +.L_OPENSSL_instrument_bus2_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + movl $0,%eax + call .L028PIC_me_up +.L028PIC_me_up: + popl %edx + leal OPENSSL_ia32cap_P-.L028PIC_me_up(%edx),%edx + btl $4,(%edx) + jnc .L029nogo + btl $19,(%edx) + jnc .L029nogo + movl 20(%esp),%edi + movl 24(%esp),%ecx + movl 28(%esp),%ebp + .byte 0x0f,0x31 + movl %eax,%esi + movl $0,%ebx + clflush (%edi) +.byte 240 + addl %ebx,(%edi) + .byte 0x0f,0x31 + movl %eax,%edx + subl %esi,%eax + movl %edx,%esi + movl %eax,%ebx + jmp .L030loop2 +.align 16 +.L030loop2: + clflush (%edi) +.byte 240 + addl %eax,(%edi) + subl $1,%ebp + jz .L031done2 + .byte 0x0f,0x31 + movl %eax,%edx + subl %esi,%eax + movl %edx,%esi + cmpl %ebx,%eax + movl %eax,%ebx + movl $0,%edx + setne %dl + subl %edx,%ecx + leal (%edi,%edx,4),%edi + jnz .L030loop2 +.L031done2: + movl 24(%esp),%eax + subl %ecx,%eax +.L029nogo: + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.size OPENSSL_instrument_bus2,.-.L_OPENSSL_instrument_bus2_begin +.globl OPENSSL_ia32_rdrand_bytes +.type OPENSSL_ia32_rdrand_bytes,@function +.align 16 +OPENSSL_ia32_rdrand_bytes: +.L_OPENSSL_ia32_rdrand_bytes_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %edi + pushl %ebx + xorl %eax,%eax + movl 12(%esp),%edi + movl 16(%esp),%ebx + cmpl $0,%ebx + je .L032done + movl $8,%ecx +.L033loop: +.byte 15,199,242 + jc .L034break + loop .L033loop + jmp .L032done +.align 16 +.L034break: + cmpl $4,%ebx + jb .L035tail + movl %edx,(%edi) + leal 4(%edi),%edi + addl $4,%eax + subl $4,%ebx + jz .L032done + movl $8,%ecx + jmp .L033loop +.align 16 +.L035tail: + movb %dl,(%edi) + leal 1(%edi),%edi + incl %eax + shrl $8,%edx + decl %ebx + jnz .L035tail +.L032done: + xorl %edx,%edx + popl %ebx + popl %edi + ret +.size OPENSSL_ia32_rdrand_bytes,.-.L_OPENSSL_ia32_rdrand_bytes_begin +.globl OPENSSL_ia32_rdseed_bytes +.type OPENSSL_ia32_rdseed_bytes,@function +.align 16 +OPENSSL_ia32_rdseed_bytes: +.L_OPENSSL_ia32_rdseed_bytes_begin: + #ifdef __CET__ + +.byte 243,15,30,251 + #endif + + pushl %edi + pushl %ebx + xorl %eax,%eax + movl 12(%esp),%edi + movl 16(%esp),%ebx + cmpl $0,%ebx + je .L036done + movl $8,%ecx +.L037loop: +.byte 15,199,250 + jc .L038break + loop .L037loop + jmp .L036done +.align 16 +.L038break: + cmpl $4,%ebx + jb .L039tail + movl %edx,(%edi) + leal 4(%edi),%edi + addl $4,%eax + subl $4,%ebx + jz .L036done + movl $8,%ecx + jmp .L037loop +.align 16 +.L039tail: + movb %dl,(%edi) + leal 1(%edi),%edi + incl %eax + shrl $8,%edx + decl %ebx + jnz .L039tail +.L036done: + xorl %edx,%edx + popl %ebx + popl %edi + ret +.size OPENSSL_ia32_rdseed_bytes,.-.L_OPENSSL_ia32_rdseed_bytes_begin +.hidden OPENSSL_cpuid_setup +.hidden OPENSSL_ia32cap_P +.comm OPENSSL_ia32cap_P,16,4 +.section .init + call OPENSSL_cpuid_setup + + .section ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .asciz "GNU" +1: + .p2align 2 + .long 0xc0000002 + .long 3f - 2f +2: + .long 3 +3: + .p2align 2 +4: diff --git a/crypto/openssl/crypto/x86cpuid.pl b/crypto/openssl/crypto/x86cpuid.pl index ba4fd80fb32e..a7bcb27e262d 100755 --- a/crypto/openssl/crypto/x86cpuid.pl +++ b/crypto/openssl/crypto/x86cpuid.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl # Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# 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 @@ -10,9 +10,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC, "${dir}perlasm", "perlasm"); require "x86asm.pl"; -$output = pop; -open OUT,">$output"; -*STDOUT=*OUT; +$output = pop and open STDOUT,">$output"; &asm_init($ARGV[0]); diff --git a/crypto/openssl/doc/HOWTO/certificates.txt b/crypto/openssl/doc/HOWTO/certificates.txt index cfd2bdabb130..78ab97b41928 100644 --- a/crypto/openssl/doc/HOWTO/certificates.txt +++ b/crypto/openssl/doc/HOWTO/certificates.txt @@ -30,7 +30,7 @@ keys, so before you create a certificate or a certificate request, you need to create a private key. Private keys are generated with 'openssl genrsa -out privkey.pem' if -you want a RSA private key, or if you want a DSA private key: +you want an RSA private key, or if you want a DSA private key: 'openssl dsaparam -out dsaparam.pem 2048; openssl gendsa -out privkey.pem dsaparam.pem'. The private keys created by these commands are not passphrase protected; diff --git a/crypto/openssl/doc/HOWTO/keys.txt b/crypto/openssl/doc/HOWTO/keys.txt index 9f0967cf5577..c4a74c54fcb8 100644 --- a/crypto/openssl/doc/HOWTO/keys.txt +++ b/crypto/openssl/doc/HOWTO/keys.txt @@ -14,9 +14,9 @@ algorithms. The most popular ones associated with certificates are RSA and DSA, and this HOWTO will show how to generate each of them. -2. To generate a RSA key +2. To generate an RSA key -A RSA key can be used both for encryption and for signing. +An RSA key can be used both for encryption and for signing. Generating a key for the RSA algorithm is quite easy, all you have to do is the following: diff --git a/crypto/openssl/doc/README b/crypto/openssl/doc/README.md similarity index 58% rename from crypto/openssl/doc/README rename to crypto/openssl/doc/README.md index 964d8798100b..12bb37ddb8fc 100644 --- a/crypto/openssl/doc/README +++ b/crypto/openssl/doc/README.md @@ -1,27 +1,30 @@ +OpenSSL Documentation +===================== -README This file +README.md This file -fingerprints.txt +[fingerprints.txt](fingerprints.txt) PGP fingerprints of authorised release signers standards.txt - Moved to the web, https://www.openssl.org/docs/standards.html +standards.txt + Moved to the web, -HOWTO/ +[HOWTO/](HOWTO/) A few how-to documents; not necessarily up-to-date -man1/ +[man1/](man1/) The openssl command-line tools; start with openssl.pod -man3/ +[man3/](man3/) The SSL library and the crypto library -man5/ +[man5/](man5/) File formats -man7/ +[man7/](man7/) Overviews; start with crypto.pod and ssl.pod, for example Algorithm specific EVP_PKEY documentation. Formatted versions of the manpages (apps,ssl,crypto) can be found at - https://www.openssl.org/docs/manpages.html + diff --git a/crypto/openssl/doc/build.info b/crypto/openssl/doc/build.info new file mode 100644 index 000000000000..ec8778f2ac69 --- /dev/null +++ b/crypto/openssl/doc/build.info @@ -0,0 +1,4860 @@ +SUBDIRS = man1 + +DEPEND[html/man1/CA.pl.html]=man1/CA.pl.pod +GENERATE[html/man1/CA.pl.html]=man1/CA.pl.pod +DEPEND[man/man1/CA.pl.1]=man1/CA.pl.pod +GENERATE[man/man1/CA.pl.1]=man1/CA.pl.pod +DEPEND[html/man1/openssl-asn1parse.html]=man1/openssl-asn1parse.pod +GENERATE[html/man1/openssl-asn1parse.html]=man1/openssl-asn1parse.pod +DEPEND[man/man1/openssl-asn1parse.1]=man1/openssl-asn1parse.pod +GENERATE[man/man1/openssl-asn1parse.1]=man1/openssl-asn1parse.pod +DEPEND[man1/openssl-asn1parse.pod]{pod}=man1/openssl-asn1parse.pod.in +GENERATE[man1/openssl-asn1parse.pod]=man1/openssl-asn1parse.pod.in +DEPEND[html/man1/openssl-ca.html]=man1/openssl-ca.pod +GENERATE[html/man1/openssl-ca.html]=man1/openssl-ca.pod +DEPEND[man/man1/openssl-ca.1]=man1/openssl-ca.pod +GENERATE[man/man1/openssl-ca.1]=man1/openssl-ca.pod +DEPEND[man1/openssl-ca.pod]{pod}=man1/openssl-ca.pod.in +GENERATE[man1/openssl-ca.pod]=man1/openssl-ca.pod.in +DEPEND[html/man1/openssl-ciphers.html]=man1/openssl-ciphers.pod +GENERATE[html/man1/openssl-ciphers.html]=man1/openssl-ciphers.pod +DEPEND[man/man1/openssl-ciphers.1]=man1/openssl-ciphers.pod +GENERATE[man/man1/openssl-ciphers.1]=man1/openssl-ciphers.pod +DEPEND[man1/openssl-ciphers.pod]{pod}=man1/openssl-ciphers.pod.in +GENERATE[man1/openssl-ciphers.pod]=man1/openssl-ciphers.pod.in +DEPEND[html/man1/openssl-cmds.html]=man1/openssl-cmds.pod +GENERATE[html/man1/openssl-cmds.html]=man1/openssl-cmds.pod +DEPEND[man/man1/openssl-cmds.1]=man1/openssl-cmds.pod +GENERATE[man/man1/openssl-cmds.1]=man1/openssl-cmds.pod +DEPEND[man1/openssl-cmds.pod]{pod}=man1/openssl-cmds.pod.in +GENERATE[man1/openssl-cmds.pod]=man1/openssl-cmds.pod.in +DEPEND[html/man1/openssl-cmp.html]=man1/openssl-cmp.pod +GENERATE[html/man1/openssl-cmp.html]=man1/openssl-cmp.pod +DEPEND[man/man1/openssl-cmp.1]=man1/openssl-cmp.pod +GENERATE[man/man1/openssl-cmp.1]=man1/openssl-cmp.pod +DEPEND[man1/openssl-cmp.pod]{pod}=man1/openssl-cmp.pod.in +GENERATE[man1/openssl-cmp.pod]=man1/openssl-cmp.pod.in +DEPEND[html/man1/openssl-cms.html]=man1/openssl-cms.pod +GENERATE[html/man1/openssl-cms.html]=man1/openssl-cms.pod +DEPEND[man/man1/openssl-cms.1]=man1/openssl-cms.pod +GENERATE[man/man1/openssl-cms.1]=man1/openssl-cms.pod +DEPEND[man1/openssl-cms.pod]{pod}=man1/openssl-cms.pod.in +GENERATE[man1/openssl-cms.pod]=man1/openssl-cms.pod.in +DEPEND[html/man1/openssl-crl.html]=man1/openssl-crl.pod +GENERATE[html/man1/openssl-crl.html]=man1/openssl-crl.pod +DEPEND[man/man1/openssl-crl.1]=man1/openssl-crl.pod +GENERATE[man/man1/openssl-crl.1]=man1/openssl-crl.pod +DEPEND[man1/openssl-crl.pod]{pod}=man1/openssl-crl.pod.in +GENERATE[man1/openssl-crl.pod]=man1/openssl-crl.pod.in +DEPEND[html/man1/openssl-crl2pkcs7.html]=man1/openssl-crl2pkcs7.pod +GENERATE[html/man1/openssl-crl2pkcs7.html]=man1/openssl-crl2pkcs7.pod +DEPEND[man/man1/openssl-crl2pkcs7.1]=man1/openssl-crl2pkcs7.pod +GENERATE[man/man1/openssl-crl2pkcs7.1]=man1/openssl-crl2pkcs7.pod +DEPEND[man1/openssl-crl2pkcs7.pod]{pod}=man1/openssl-crl2pkcs7.pod.in +GENERATE[man1/openssl-crl2pkcs7.pod]=man1/openssl-crl2pkcs7.pod.in +DEPEND[html/man1/openssl-dgst.html]=man1/openssl-dgst.pod +GENERATE[html/man1/openssl-dgst.html]=man1/openssl-dgst.pod +DEPEND[man/man1/openssl-dgst.1]=man1/openssl-dgst.pod +GENERATE[man/man1/openssl-dgst.1]=man1/openssl-dgst.pod +DEPEND[man1/openssl-dgst.pod]{pod}=man1/openssl-dgst.pod.in +GENERATE[man1/openssl-dgst.pod]=man1/openssl-dgst.pod.in +DEPEND[html/man1/openssl-dhparam.html]=man1/openssl-dhparam.pod +GENERATE[html/man1/openssl-dhparam.html]=man1/openssl-dhparam.pod +DEPEND[man/man1/openssl-dhparam.1]=man1/openssl-dhparam.pod +GENERATE[man/man1/openssl-dhparam.1]=man1/openssl-dhparam.pod +DEPEND[man1/openssl-dhparam.pod]{pod}=man1/openssl-dhparam.pod.in +GENERATE[man1/openssl-dhparam.pod]=man1/openssl-dhparam.pod.in +DEPEND[html/man1/openssl-dsa.html]=man1/openssl-dsa.pod +GENERATE[html/man1/openssl-dsa.html]=man1/openssl-dsa.pod +DEPEND[man/man1/openssl-dsa.1]=man1/openssl-dsa.pod +GENERATE[man/man1/openssl-dsa.1]=man1/openssl-dsa.pod +DEPEND[man1/openssl-dsa.pod]{pod}=man1/openssl-dsa.pod.in +GENERATE[man1/openssl-dsa.pod]=man1/openssl-dsa.pod.in +DEPEND[html/man1/openssl-dsaparam.html]=man1/openssl-dsaparam.pod +GENERATE[html/man1/openssl-dsaparam.html]=man1/openssl-dsaparam.pod +DEPEND[man/man1/openssl-dsaparam.1]=man1/openssl-dsaparam.pod +GENERATE[man/man1/openssl-dsaparam.1]=man1/openssl-dsaparam.pod +DEPEND[man1/openssl-dsaparam.pod]{pod}=man1/openssl-dsaparam.pod.in +GENERATE[man1/openssl-dsaparam.pod]=man1/openssl-dsaparam.pod.in +DEPEND[html/man1/openssl-ec.html]=man1/openssl-ec.pod +GENERATE[html/man1/openssl-ec.html]=man1/openssl-ec.pod +DEPEND[man/man1/openssl-ec.1]=man1/openssl-ec.pod +GENERATE[man/man1/openssl-ec.1]=man1/openssl-ec.pod +DEPEND[man1/openssl-ec.pod]{pod}=man1/openssl-ec.pod.in +GENERATE[man1/openssl-ec.pod]=man1/openssl-ec.pod.in +DEPEND[html/man1/openssl-ecparam.html]=man1/openssl-ecparam.pod +GENERATE[html/man1/openssl-ecparam.html]=man1/openssl-ecparam.pod +DEPEND[man/man1/openssl-ecparam.1]=man1/openssl-ecparam.pod +GENERATE[man/man1/openssl-ecparam.1]=man1/openssl-ecparam.pod +DEPEND[man1/openssl-ecparam.pod]{pod}=man1/openssl-ecparam.pod.in +GENERATE[man1/openssl-ecparam.pod]=man1/openssl-ecparam.pod.in +DEPEND[html/man1/openssl-enc.html]=man1/openssl-enc.pod +GENERATE[html/man1/openssl-enc.html]=man1/openssl-enc.pod +DEPEND[man/man1/openssl-enc.1]=man1/openssl-enc.pod +GENERATE[man/man1/openssl-enc.1]=man1/openssl-enc.pod +DEPEND[man1/openssl-enc.pod]{pod}=man1/openssl-enc.pod.in +GENERATE[man1/openssl-enc.pod]=man1/openssl-enc.pod.in +DEPEND[html/man1/openssl-engine.html]=man1/openssl-engine.pod +GENERATE[html/man1/openssl-engine.html]=man1/openssl-engine.pod +DEPEND[man/man1/openssl-engine.1]=man1/openssl-engine.pod +GENERATE[man/man1/openssl-engine.1]=man1/openssl-engine.pod +DEPEND[man1/openssl-engine.pod]{pod}=man1/openssl-engine.pod.in +GENERATE[man1/openssl-engine.pod]=man1/openssl-engine.pod.in +DEPEND[html/man1/openssl-errstr.html]=man1/openssl-errstr.pod +GENERATE[html/man1/openssl-errstr.html]=man1/openssl-errstr.pod +DEPEND[man/man1/openssl-errstr.1]=man1/openssl-errstr.pod +GENERATE[man/man1/openssl-errstr.1]=man1/openssl-errstr.pod +DEPEND[man1/openssl-errstr.pod]{pod}=man1/openssl-errstr.pod.in +GENERATE[man1/openssl-errstr.pod]=man1/openssl-errstr.pod.in +DEPEND[html/man1/openssl-fipsinstall.html]=man1/openssl-fipsinstall.pod +GENERATE[html/man1/openssl-fipsinstall.html]=man1/openssl-fipsinstall.pod +DEPEND[man/man1/openssl-fipsinstall.1]=man1/openssl-fipsinstall.pod +GENERATE[man/man1/openssl-fipsinstall.1]=man1/openssl-fipsinstall.pod +DEPEND[man1/openssl-fipsinstall.pod]{pod}=man1/openssl-fipsinstall.pod.in +GENERATE[man1/openssl-fipsinstall.pod]=man1/openssl-fipsinstall.pod.in +DEPEND[html/man1/openssl-format-options.html]=man1/openssl-format-options.pod +GENERATE[html/man1/openssl-format-options.html]=man1/openssl-format-options.pod +DEPEND[man/man1/openssl-format-options.1]=man1/openssl-format-options.pod +GENERATE[man/man1/openssl-format-options.1]=man1/openssl-format-options.pod +DEPEND[html/man1/openssl-gendsa.html]=man1/openssl-gendsa.pod +GENERATE[html/man1/openssl-gendsa.html]=man1/openssl-gendsa.pod +DEPEND[man/man1/openssl-gendsa.1]=man1/openssl-gendsa.pod +GENERATE[man/man1/openssl-gendsa.1]=man1/openssl-gendsa.pod +DEPEND[man1/openssl-gendsa.pod]{pod}=man1/openssl-gendsa.pod.in +GENERATE[man1/openssl-gendsa.pod]=man1/openssl-gendsa.pod.in +DEPEND[html/man1/openssl-genpkey.html]=man1/openssl-genpkey.pod +GENERATE[html/man1/openssl-genpkey.html]=man1/openssl-genpkey.pod +DEPEND[man/man1/openssl-genpkey.1]=man1/openssl-genpkey.pod +GENERATE[man/man1/openssl-genpkey.1]=man1/openssl-genpkey.pod +DEPEND[man1/openssl-genpkey.pod]{pod}=man1/openssl-genpkey.pod.in +GENERATE[man1/openssl-genpkey.pod]=man1/openssl-genpkey.pod.in +DEPEND[html/man1/openssl-genrsa.html]=man1/openssl-genrsa.pod +GENERATE[html/man1/openssl-genrsa.html]=man1/openssl-genrsa.pod +DEPEND[man/man1/openssl-genrsa.1]=man1/openssl-genrsa.pod +GENERATE[man/man1/openssl-genrsa.1]=man1/openssl-genrsa.pod +DEPEND[man1/openssl-genrsa.pod]{pod}=man1/openssl-genrsa.pod.in +GENERATE[man1/openssl-genrsa.pod]=man1/openssl-genrsa.pod.in +DEPEND[html/man1/openssl-info.html]=man1/openssl-info.pod +GENERATE[html/man1/openssl-info.html]=man1/openssl-info.pod +DEPEND[man/man1/openssl-info.1]=man1/openssl-info.pod +GENERATE[man/man1/openssl-info.1]=man1/openssl-info.pod +DEPEND[man1/openssl-info.pod]{pod}=man1/openssl-info.pod.in +GENERATE[man1/openssl-info.pod]=man1/openssl-info.pod.in +DEPEND[html/man1/openssl-kdf.html]=man1/openssl-kdf.pod +GENERATE[html/man1/openssl-kdf.html]=man1/openssl-kdf.pod +DEPEND[man/man1/openssl-kdf.1]=man1/openssl-kdf.pod +GENERATE[man/man1/openssl-kdf.1]=man1/openssl-kdf.pod +DEPEND[man1/openssl-kdf.pod]{pod}=man1/openssl-kdf.pod.in +GENERATE[man1/openssl-kdf.pod]=man1/openssl-kdf.pod.in +DEPEND[html/man1/openssl-list.html]=man1/openssl-list.pod +GENERATE[html/man1/openssl-list.html]=man1/openssl-list.pod +DEPEND[man/man1/openssl-list.1]=man1/openssl-list.pod +GENERATE[man/man1/openssl-list.1]=man1/openssl-list.pod +DEPEND[man1/openssl-list.pod]{pod}=man1/openssl-list.pod.in +GENERATE[man1/openssl-list.pod]=man1/openssl-list.pod.in +DEPEND[html/man1/openssl-mac.html]=man1/openssl-mac.pod +GENERATE[html/man1/openssl-mac.html]=man1/openssl-mac.pod +DEPEND[man/man1/openssl-mac.1]=man1/openssl-mac.pod +GENERATE[man/man1/openssl-mac.1]=man1/openssl-mac.pod +DEPEND[man1/openssl-mac.pod]{pod}=man1/openssl-mac.pod.in +GENERATE[man1/openssl-mac.pod]=man1/openssl-mac.pod.in +DEPEND[html/man1/openssl-namedisplay-options.html]=man1/openssl-namedisplay-options.pod +GENERATE[html/man1/openssl-namedisplay-options.html]=man1/openssl-namedisplay-options.pod +DEPEND[man/man1/openssl-namedisplay-options.1]=man1/openssl-namedisplay-options.pod +GENERATE[man/man1/openssl-namedisplay-options.1]=man1/openssl-namedisplay-options.pod +DEPEND[html/man1/openssl-nseq.html]=man1/openssl-nseq.pod +GENERATE[html/man1/openssl-nseq.html]=man1/openssl-nseq.pod +DEPEND[man/man1/openssl-nseq.1]=man1/openssl-nseq.pod +GENERATE[man/man1/openssl-nseq.1]=man1/openssl-nseq.pod +DEPEND[man1/openssl-nseq.pod]{pod}=man1/openssl-nseq.pod.in +GENERATE[man1/openssl-nseq.pod]=man1/openssl-nseq.pod.in +DEPEND[html/man1/openssl-ocsp.html]=man1/openssl-ocsp.pod +GENERATE[html/man1/openssl-ocsp.html]=man1/openssl-ocsp.pod +DEPEND[man/man1/openssl-ocsp.1]=man1/openssl-ocsp.pod +GENERATE[man/man1/openssl-ocsp.1]=man1/openssl-ocsp.pod +DEPEND[man1/openssl-ocsp.pod]{pod}=man1/openssl-ocsp.pod.in +GENERATE[man1/openssl-ocsp.pod]=man1/openssl-ocsp.pod.in +DEPEND[html/man1/openssl-passphrase-options.html]=man1/openssl-passphrase-options.pod +GENERATE[html/man1/openssl-passphrase-options.html]=man1/openssl-passphrase-options.pod +DEPEND[man/man1/openssl-passphrase-options.1]=man1/openssl-passphrase-options.pod +GENERATE[man/man1/openssl-passphrase-options.1]=man1/openssl-passphrase-options.pod +DEPEND[html/man1/openssl-passwd.html]=man1/openssl-passwd.pod +GENERATE[html/man1/openssl-passwd.html]=man1/openssl-passwd.pod +DEPEND[man/man1/openssl-passwd.1]=man1/openssl-passwd.pod +GENERATE[man/man1/openssl-passwd.1]=man1/openssl-passwd.pod +DEPEND[man1/openssl-passwd.pod]{pod}=man1/openssl-passwd.pod.in +GENERATE[man1/openssl-passwd.pod]=man1/openssl-passwd.pod.in +DEPEND[html/man1/openssl-pkcs12.html]=man1/openssl-pkcs12.pod +GENERATE[html/man1/openssl-pkcs12.html]=man1/openssl-pkcs12.pod +DEPEND[man/man1/openssl-pkcs12.1]=man1/openssl-pkcs12.pod +GENERATE[man/man1/openssl-pkcs12.1]=man1/openssl-pkcs12.pod +DEPEND[man1/openssl-pkcs12.pod]{pod}=man1/openssl-pkcs12.pod.in +GENERATE[man1/openssl-pkcs12.pod]=man1/openssl-pkcs12.pod.in +DEPEND[html/man1/openssl-pkcs7.html]=man1/openssl-pkcs7.pod +GENERATE[html/man1/openssl-pkcs7.html]=man1/openssl-pkcs7.pod +DEPEND[man/man1/openssl-pkcs7.1]=man1/openssl-pkcs7.pod +GENERATE[man/man1/openssl-pkcs7.1]=man1/openssl-pkcs7.pod +DEPEND[man1/openssl-pkcs7.pod]{pod}=man1/openssl-pkcs7.pod.in +GENERATE[man1/openssl-pkcs7.pod]=man1/openssl-pkcs7.pod.in +DEPEND[html/man1/openssl-pkcs8.html]=man1/openssl-pkcs8.pod +GENERATE[html/man1/openssl-pkcs8.html]=man1/openssl-pkcs8.pod +DEPEND[man/man1/openssl-pkcs8.1]=man1/openssl-pkcs8.pod +GENERATE[man/man1/openssl-pkcs8.1]=man1/openssl-pkcs8.pod +DEPEND[man1/openssl-pkcs8.pod]{pod}=man1/openssl-pkcs8.pod.in +GENERATE[man1/openssl-pkcs8.pod]=man1/openssl-pkcs8.pod.in +DEPEND[html/man1/openssl-pkey.html]=man1/openssl-pkey.pod +GENERATE[html/man1/openssl-pkey.html]=man1/openssl-pkey.pod +DEPEND[man/man1/openssl-pkey.1]=man1/openssl-pkey.pod +GENERATE[man/man1/openssl-pkey.1]=man1/openssl-pkey.pod +DEPEND[man1/openssl-pkey.pod]{pod}=man1/openssl-pkey.pod.in +GENERATE[man1/openssl-pkey.pod]=man1/openssl-pkey.pod.in +DEPEND[html/man1/openssl-pkeyparam.html]=man1/openssl-pkeyparam.pod +GENERATE[html/man1/openssl-pkeyparam.html]=man1/openssl-pkeyparam.pod +DEPEND[man/man1/openssl-pkeyparam.1]=man1/openssl-pkeyparam.pod +GENERATE[man/man1/openssl-pkeyparam.1]=man1/openssl-pkeyparam.pod +DEPEND[man1/openssl-pkeyparam.pod]{pod}=man1/openssl-pkeyparam.pod.in +GENERATE[man1/openssl-pkeyparam.pod]=man1/openssl-pkeyparam.pod.in +DEPEND[html/man1/openssl-pkeyutl.html]=man1/openssl-pkeyutl.pod +GENERATE[html/man1/openssl-pkeyutl.html]=man1/openssl-pkeyutl.pod +DEPEND[man/man1/openssl-pkeyutl.1]=man1/openssl-pkeyutl.pod +GENERATE[man/man1/openssl-pkeyutl.1]=man1/openssl-pkeyutl.pod +DEPEND[man1/openssl-pkeyutl.pod]{pod}=man1/openssl-pkeyutl.pod.in +GENERATE[man1/openssl-pkeyutl.pod]=man1/openssl-pkeyutl.pod.in +DEPEND[html/man1/openssl-prime.html]=man1/openssl-prime.pod +GENERATE[html/man1/openssl-prime.html]=man1/openssl-prime.pod +DEPEND[man/man1/openssl-prime.1]=man1/openssl-prime.pod +GENERATE[man/man1/openssl-prime.1]=man1/openssl-prime.pod +DEPEND[man1/openssl-prime.pod]{pod}=man1/openssl-prime.pod.in +GENERATE[man1/openssl-prime.pod]=man1/openssl-prime.pod.in +DEPEND[html/man1/openssl-rand.html]=man1/openssl-rand.pod +GENERATE[html/man1/openssl-rand.html]=man1/openssl-rand.pod +DEPEND[man/man1/openssl-rand.1]=man1/openssl-rand.pod +GENERATE[man/man1/openssl-rand.1]=man1/openssl-rand.pod +DEPEND[man1/openssl-rand.pod]{pod}=man1/openssl-rand.pod.in +GENERATE[man1/openssl-rand.pod]=man1/openssl-rand.pod.in +DEPEND[html/man1/openssl-rehash.html]=man1/openssl-rehash.pod +GENERATE[html/man1/openssl-rehash.html]=man1/openssl-rehash.pod +DEPEND[man/man1/openssl-rehash.1]=man1/openssl-rehash.pod +GENERATE[man/man1/openssl-rehash.1]=man1/openssl-rehash.pod +DEPEND[man1/openssl-rehash.pod]{pod}=man1/openssl-rehash.pod.in +GENERATE[man1/openssl-rehash.pod]=man1/openssl-rehash.pod.in +DEPEND[html/man1/openssl-req.html]=man1/openssl-req.pod +GENERATE[html/man1/openssl-req.html]=man1/openssl-req.pod +DEPEND[man/man1/openssl-req.1]=man1/openssl-req.pod +GENERATE[man/man1/openssl-req.1]=man1/openssl-req.pod +DEPEND[man1/openssl-req.pod]{pod}=man1/openssl-req.pod.in +GENERATE[man1/openssl-req.pod]=man1/openssl-req.pod.in +DEPEND[html/man1/openssl-rsa.html]=man1/openssl-rsa.pod +GENERATE[html/man1/openssl-rsa.html]=man1/openssl-rsa.pod +DEPEND[man/man1/openssl-rsa.1]=man1/openssl-rsa.pod +GENERATE[man/man1/openssl-rsa.1]=man1/openssl-rsa.pod +DEPEND[man1/openssl-rsa.pod]{pod}=man1/openssl-rsa.pod.in +GENERATE[man1/openssl-rsa.pod]=man1/openssl-rsa.pod.in +DEPEND[html/man1/openssl-rsautl.html]=man1/openssl-rsautl.pod +GENERATE[html/man1/openssl-rsautl.html]=man1/openssl-rsautl.pod +DEPEND[man/man1/openssl-rsautl.1]=man1/openssl-rsautl.pod +GENERATE[man/man1/openssl-rsautl.1]=man1/openssl-rsautl.pod +DEPEND[man1/openssl-rsautl.pod]{pod}=man1/openssl-rsautl.pod.in +GENERATE[man1/openssl-rsautl.pod]=man1/openssl-rsautl.pod.in +DEPEND[html/man1/openssl-s_client.html]=man1/openssl-s_client.pod +GENERATE[html/man1/openssl-s_client.html]=man1/openssl-s_client.pod +DEPEND[man/man1/openssl-s_client.1]=man1/openssl-s_client.pod +GENERATE[man/man1/openssl-s_client.1]=man1/openssl-s_client.pod +DEPEND[man1/openssl-s_client.pod]{pod}=man1/openssl-s_client.pod.in +GENERATE[man1/openssl-s_client.pod]=man1/openssl-s_client.pod.in +DEPEND[html/man1/openssl-s_server.html]=man1/openssl-s_server.pod +GENERATE[html/man1/openssl-s_server.html]=man1/openssl-s_server.pod +DEPEND[man/man1/openssl-s_server.1]=man1/openssl-s_server.pod +GENERATE[man/man1/openssl-s_server.1]=man1/openssl-s_server.pod +DEPEND[man1/openssl-s_server.pod]{pod}=man1/openssl-s_server.pod.in +GENERATE[man1/openssl-s_server.pod]=man1/openssl-s_server.pod.in +DEPEND[html/man1/openssl-s_time.html]=man1/openssl-s_time.pod +GENERATE[html/man1/openssl-s_time.html]=man1/openssl-s_time.pod +DEPEND[man/man1/openssl-s_time.1]=man1/openssl-s_time.pod +GENERATE[man/man1/openssl-s_time.1]=man1/openssl-s_time.pod +DEPEND[man1/openssl-s_time.pod]{pod}=man1/openssl-s_time.pod.in +GENERATE[man1/openssl-s_time.pod]=man1/openssl-s_time.pod.in +DEPEND[html/man1/openssl-sess_id.html]=man1/openssl-sess_id.pod +GENERATE[html/man1/openssl-sess_id.html]=man1/openssl-sess_id.pod +DEPEND[man/man1/openssl-sess_id.1]=man1/openssl-sess_id.pod +GENERATE[man/man1/openssl-sess_id.1]=man1/openssl-sess_id.pod +DEPEND[man1/openssl-sess_id.pod]{pod}=man1/openssl-sess_id.pod.in +GENERATE[man1/openssl-sess_id.pod]=man1/openssl-sess_id.pod.in +DEPEND[html/man1/openssl-smime.html]=man1/openssl-smime.pod +GENERATE[html/man1/openssl-smime.html]=man1/openssl-smime.pod +DEPEND[man/man1/openssl-smime.1]=man1/openssl-smime.pod +GENERATE[man/man1/openssl-smime.1]=man1/openssl-smime.pod +DEPEND[man1/openssl-smime.pod]{pod}=man1/openssl-smime.pod.in +GENERATE[man1/openssl-smime.pod]=man1/openssl-smime.pod.in +DEPEND[html/man1/openssl-speed.html]=man1/openssl-speed.pod +GENERATE[html/man1/openssl-speed.html]=man1/openssl-speed.pod +DEPEND[man/man1/openssl-speed.1]=man1/openssl-speed.pod +GENERATE[man/man1/openssl-speed.1]=man1/openssl-speed.pod +DEPEND[man1/openssl-speed.pod]{pod}=man1/openssl-speed.pod.in +GENERATE[man1/openssl-speed.pod]=man1/openssl-speed.pod.in +DEPEND[html/man1/openssl-spkac.html]=man1/openssl-spkac.pod +GENERATE[html/man1/openssl-spkac.html]=man1/openssl-spkac.pod +DEPEND[man/man1/openssl-spkac.1]=man1/openssl-spkac.pod +GENERATE[man/man1/openssl-spkac.1]=man1/openssl-spkac.pod +DEPEND[man1/openssl-spkac.pod]{pod}=man1/openssl-spkac.pod.in +GENERATE[man1/openssl-spkac.pod]=man1/openssl-spkac.pod.in +DEPEND[html/man1/openssl-srp.html]=man1/openssl-srp.pod +GENERATE[html/man1/openssl-srp.html]=man1/openssl-srp.pod +DEPEND[man/man1/openssl-srp.1]=man1/openssl-srp.pod +GENERATE[man/man1/openssl-srp.1]=man1/openssl-srp.pod +DEPEND[man1/openssl-srp.pod]{pod}=man1/openssl-srp.pod.in +GENERATE[man1/openssl-srp.pod]=man1/openssl-srp.pod.in +DEPEND[html/man1/openssl-storeutl.html]=man1/openssl-storeutl.pod +GENERATE[html/man1/openssl-storeutl.html]=man1/openssl-storeutl.pod +DEPEND[man/man1/openssl-storeutl.1]=man1/openssl-storeutl.pod +GENERATE[man/man1/openssl-storeutl.1]=man1/openssl-storeutl.pod +DEPEND[man1/openssl-storeutl.pod]{pod}=man1/openssl-storeutl.pod.in +GENERATE[man1/openssl-storeutl.pod]=man1/openssl-storeutl.pod.in +DEPEND[html/man1/openssl-ts.html]=man1/openssl-ts.pod +GENERATE[html/man1/openssl-ts.html]=man1/openssl-ts.pod +DEPEND[man/man1/openssl-ts.1]=man1/openssl-ts.pod +GENERATE[man/man1/openssl-ts.1]=man1/openssl-ts.pod +DEPEND[man1/openssl-ts.pod]{pod}=man1/openssl-ts.pod.in +GENERATE[man1/openssl-ts.pod]=man1/openssl-ts.pod.in +DEPEND[html/man1/openssl-verification-options.html]=man1/openssl-verification-options.pod +GENERATE[html/man1/openssl-verification-options.html]=man1/openssl-verification-options.pod +DEPEND[man/man1/openssl-verification-options.1]=man1/openssl-verification-options.pod +GENERATE[man/man1/openssl-verification-options.1]=man1/openssl-verification-options.pod +DEPEND[html/man1/openssl-verify.html]=man1/openssl-verify.pod +GENERATE[html/man1/openssl-verify.html]=man1/openssl-verify.pod +DEPEND[man/man1/openssl-verify.1]=man1/openssl-verify.pod +GENERATE[man/man1/openssl-verify.1]=man1/openssl-verify.pod +DEPEND[man1/openssl-verify.pod]{pod}=man1/openssl-verify.pod.in +GENERATE[man1/openssl-verify.pod]=man1/openssl-verify.pod.in +DEPEND[html/man1/openssl-version.html]=man1/openssl-version.pod +GENERATE[html/man1/openssl-version.html]=man1/openssl-version.pod +DEPEND[man/man1/openssl-version.1]=man1/openssl-version.pod +GENERATE[man/man1/openssl-version.1]=man1/openssl-version.pod +DEPEND[man1/openssl-version.pod]{pod}=man1/openssl-version.pod.in +GENERATE[man1/openssl-version.pod]=man1/openssl-version.pod.in +DEPEND[html/man1/openssl-x509.html]=man1/openssl-x509.pod +GENERATE[html/man1/openssl-x509.html]=man1/openssl-x509.pod +DEPEND[man/man1/openssl-x509.1]=man1/openssl-x509.pod +GENERATE[man/man1/openssl-x509.1]=man1/openssl-x509.pod +DEPEND[man1/openssl-x509.pod]{pod}=man1/openssl-x509.pod.in +GENERATE[man1/openssl-x509.pod]=man1/openssl-x509.pod.in +DEPEND[html/man1/openssl.html]=man1/openssl.pod +GENERATE[html/man1/openssl.html]=man1/openssl.pod +DEPEND[man/man1/openssl.1]=man1/openssl.pod +GENERATE[man/man1/openssl.1]=man1/openssl.pod +DEPEND[html/man1/tsget.html]=man1/tsget.pod +GENERATE[html/man1/tsget.html]=man1/tsget.pod +DEPEND[man/man1/tsget.1]=man1/tsget.pod +GENERATE[man/man1/tsget.1]=man1/tsget.pod +IMAGEDOCS[man1]= +HTMLDOCS[man1]=html/man1/CA.pl.html \ +html/man1/openssl-asn1parse.html \ +html/man1/openssl-ca.html \ +html/man1/openssl-ciphers.html \ +html/man1/openssl-cmds.html \ +html/man1/openssl-cmp.html \ +html/man1/openssl-cms.html \ +html/man1/openssl-crl.html \ +html/man1/openssl-crl2pkcs7.html \ +html/man1/openssl-dgst.html \ +html/man1/openssl-dhparam.html \ +html/man1/openssl-dsa.html \ +html/man1/openssl-dsaparam.html \ +html/man1/openssl-ec.html \ +html/man1/openssl-ecparam.html \ +html/man1/openssl-enc.html \ +html/man1/openssl-engine.html \ +html/man1/openssl-errstr.html \ +html/man1/openssl-fipsinstall.html \ +html/man1/openssl-format-options.html \ +html/man1/openssl-gendsa.html \ +html/man1/openssl-genpkey.html \ +html/man1/openssl-genrsa.html \ +html/man1/openssl-info.html \ +html/man1/openssl-kdf.html \ +html/man1/openssl-list.html \ +html/man1/openssl-mac.html \ +html/man1/openssl-namedisplay-options.html \ +html/man1/openssl-nseq.html \ +html/man1/openssl-ocsp.html \ +html/man1/openssl-passphrase-options.html \ +html/man1/openssl-passwd.html \ +html/man1/openssl-pkcs12.html \ +html/man1/openssl-pkcs7.html \ +html/man1/openssl-pkcs8.html \ +html/man1/openssl-pkey.html \ +html/man1/openssl-pkeyparam.html \ +html/man1/openssl-pkeyutl.html \ +html/man1/openssl-prime.html \ +html/man1/openssl-rand.html \ +html/man1/openssl-rehash.html \ +html/man1/openssl-req.html \ +html/man1/openssl-rsa.html \ +html/man1/openssl-rsautl.html \ +html/man1/openssl-s_client.html \ +html/man1/openssl-s_server.html \ +html/man1/openssl-s_time.html \ +html/man1/openssl-sess_id.html \ +html/man1/openssl-smime.html \ +html/man1/openssl-speed.html \ +html/man1/openssl-spkac.html \ +html/man1/openssl-srp.html \ +html/man1/openssl-storeutl.html \ +html/man1/openssl-ts.html \ +html/man1/openssl-verification-options.html \ +html/man1/openssl-verify.html \ +html/man1/openssl-version.html \ +html/man1/openssl-x509.html \ +html/man1/openssl.html \ +html/man1/tsget.html +MANDOCS[man1]=man/man1/CA.pl.1 \ +man/man1/openssl-asn1parse.1 \ +man/man1/openssl-ca.1 \ +man/man1/openssl-ciphers.1 \ +man/man1/openssl-cmds.1 \ +man/man1/openssl-cmp.1 \ +man/man1/openssl-cms.1 \ +man/man1/openssl-crl.1 \ +man/man1/openssl-crl2pkcs7.1 \ +man/man1/openssl-dgst.1 \ +man/man1/openssl-dhparam.1 \ +man/man1/openssl-dsa.1 \ +man/man1/openssl-dsaparam.1 \ +man/man1/openssl-ec.1 \ +man/man1/openssl-ecparam.1 \ +man/man1/openssl-enc.1 \ +man/man1/openssl-engine.1 \ +man/man1/openssl-errstr.1 \ +man/man1/openssl-fipsinstall.1 \ +man/man1/openssl-format-options.1 \ +man/man1/openssl-gendsa.1 \ +man/man1/openssl-genpkey.1 \ +man/man1/openssl-genrsa.1 \ +man/man1/openssl-info.1 \ +man/man1/openssl-kdf.1 \ +man/man1/openssl-list.1 \ +man/man1/openssl-mac.1 \ +man/man1/openssl-namedisplay-options.1 \ +man/man1/openssl-nseq.1 \ +man/man1/openssl-ocsp.1 \ +man/man1/openssl-passphrase-options.1 \ +man/man1/openssl-passwd.1 \ +man/man1/openssl-pkcs12.1 \ +man/man1/openssl-pkcs7.1 \ +man/man1/openssl-pkcs8.1 \ +man/man1/openssl-pkey.1 \ +man/man1/openssl-pkeyparam.1 \ +man/man1/openssl-pkeyutl.1 \ +man/man1/openssl-prime.1 \ +man/man1/openssl-rand.1 \ +man/man1/openssl-rehash.1 \ +man/man1/openssl-req.1 \ +man/man1/openssl-rsa.1 \ +man/man1/openssl-rsautl.1 \ +man/man1/openssl-s_client.1 \ +man/man1/openssl-s_server.1 \ +man/man1/openssl-s_time.1 \ +man/man1/openssl-sess_id.1 \ +man/man1/openssl-smime.1 \ +man/man1/openssl-speed.1 \ +man/man1/openssl-spkac.1 \ +man/man1/openssl-srp.1 \ +man/man1/openssl-storeutl.1 \ +man/man1/openssl-ts.1 \ +man/man1/openssl-verification-options.1 \ +man/man1/openssl-verify.1 \ +man/man1/openssl-version.1 \ +man/man1/openssl-x509.1 \ +man/man1/openssl.1 \ +man/man1/tsget.1 +DEPEND[html/man3/ADMISSIONS.html]=man3/ADMISSIONS.pod +GENERATE[html/man3/ADMISSIONS.html]=man3/ADMISSIONS.pod +DEPEND[man/man3/ADMISSIONS.3]=man3/ADMISSIONS.pod +GENERATE[man/man3/ADMISSIONS.3]=man3/ADMISSIONS.pod +DEPEND[html/man3/ASN1_EXTERN_FUNCS.html]=man3/ASN1_EXTERN_FUNCS.pod +GENERATE[html/man3/ASN1_EXTERN_FUNCS.html]=man3/ASN1_EXTERN_FUNCS.pod +DEPEND[man/man3/ASN1_EXTERN_FUNCS.3]=man3/ASN1_EXTERN_FUNCS.pod +GENERATE[man/man3/ASN1_EXTERN_FUNCS.3]=man3/ASN1_EXTERN_FUNCS.pod +DEPEND[html/man3/ASN1_INTEGER_get_int64.html]=man3/ASN1_INTEGER_get_int64.pod +GENERATE[html/man3/ASN1_INTEGER_get_int64.html]=man3/ASN1_INTEGER_get_int64.pod +DEPEND[man/man3/ASN1_INTEGER_get_int64.3]=man3/ASN1_INTEGER_get_int64.pod +GENERATE[man/man3/ASN1_INTEGER_get_int64.3]=man3/ASN1_INTEGER_get_int64.pod +DEPEND[html/man3/ASN1_INTEGER_new.html]=man3/ASN1_INTEGER_new.pod +GENERATE[html/man3/ASN1_INTEGER_new.html]=man3/ASN1_INTEGER_new.pod +DEPEND[man/man3/ASN1_INTEGER_new.3]=man3/ASN1_INTEGER_new.pod +GENERATE[man/man3/ASN1_INTEGER_new.3]=man3/ASN1_INTEGER_new.pod +DEPEND[html/man3/ASN1_ITEM_lookup.html]=man3/ASN1_ITEM_lookup.pod +GENERATE[html/man3/ASN1_ITEM_lookup.html]=man3/ASN1_ITEM_lookup.pod +DEPEND[man/man3/ASN1_ITEM_lookup.3]=man3/ASN1_ITEM_lookup.pod +GENERATE[man/man3/ASN1_ITEM_lookup.3]=man3/ASN1_ITEM_lookup.pod +DEPEND[html/man3/ASN1_OBJECT_new.html]=man3/ASN1_OBJECT_new.pod +GENERATE[html/man3/ASN1_OBJECT_new.html]=man3/ASN1_OBJECT_new.pod +DEPEND[man/man3/ASN1_OBJECT_new.3]=man3/ASN1_OBJECT_new.pod +GENERATE[man/man3/ASN1_OBJECT_new.3]=man3/ASN1_OBJECT_new.pod +DEPEND[html/man3/ASN1_STRING_TABLE_add.html]=man3/ASN1_STRING_TABLE_add.pod +GENERATE[html/man3/ASN1_STRING_TABLE_add.html]=man3/ASN1_STRING_TABLE_add.pod +DEPEND[man/man3/ASN1_STRING_TABLE_add.3]=man3/ASN1_STRING_TABLE_add.pod +GENERATE[man/man3/ASN1_STRING_TABLE_add.3]=man3/ASN1_STRING_TABLE_add.pod +DEPEND[html/man3/ASN1_STRING_length.html]=man3/ASN1_STRING_length.pod +GENERATE[html/man3/ASN1_STRING_length.html]=man3/ASN1_STRING_length.pod +DEPEND[man/man3/ASN1_STRING_length.3]=man3/ASN1_STRING_length.pod +GENERATE[man/man3/ASN1_STRING_length.3]=man3/ASN1_STRING_length.pod +DEPEND[html/man3/ASN1_STRING_new.html]=man3/ASN1_STRING_new.pod +GENERATE[html/man3/ASN1_STRING_new.html]=man3/ASN1_STRING_new.pod +DEPEND[man/man3/ASN1_STRING_new.3]=man3/ASN1_STRING_new.pod +GENERATE[man/man3/ASN1_STRING_new.3]=man3/ASN1_STRING_new.pod +DEPEND[html/man3/ASN1_STRING_print_ex.html]=man3/ASN1_STRING_print_ex.pod +GENERATE[html/man3/ASN1_STRING_print_ex.html]=man3/ASN1_STRING_print_ex.pod +DEPEND[man/man3/ASN1_STRING_print_ex.3]=man3/ASN1_STRING_print_ex.pod +GENERATE[man/man3/ASN1_STRING_print_ex.3]=man3/ASN1_STRING_print_ex.pod +DEPEND[html/man3/ASN1_TIME_set.html]=man3/ASN1_TIME_set.pod +GENERATE[html/man3/ASN1_TIME_set.html]=man3/ASN1_TIME_set.pod +DEPEND[man/man3/ASN1_TIME_set.3]=man3/ASN1_TIME_set.pod +GENERATE[man/man3/ASN1_TIME_set.3]=man3/ASN1_TIME_set.pod +DEPEND[html/man3/ASN1_TYPE_get.html]=man3/ASN1_TYPE_get.pod +GENERATE[html/man3/ASN1_TYPE_get.html]=man3/ASN1_TYPE_get.pod +DEPEND[man/man3/ASN1_TYPE_get.3]=man3/ASN1_TYPE_get.pod +GENERATE[man/man3/ASN1_TYPE_get.3]=man3/ASN1_TYPE_get.pod +DEPEND[html/man3/ASN1_aux_cb.html]=man3/ASN1_aux_cb.pod +GENERATE[html/man3/ASN1_aux_cb.html]=man3/ASN1_aux_cb.pod +DEPEND[man/man3/ASN1_aux_cb.3]=man3/ASN1_aux_cb.pod +GENERATE[man/man3/ASN1_aux_cb.3]=man3/ASN1_aux_cb.pod +DEPEND[html/man3/ASN1_generate_nconf.html]=man3/ASN1_generate_nconf.pod +GENERATE[html/man3/ASN1_generate_nconf.html]=man3/ASN1_generate_nconf.pod +DEPEND[man/man3/ASN1_generate_nconf.3]=man3/ASN1_generate_nconf.pod +GENERATE[man/man3/ASN1_generate_nconf.3]=man3/ASN1_generate_nconf.pod +DEPEND[html/man3/ASN1_item_d2i_bio.html]=man3/ASN1_item_d2i_bio.pod +GENERATE[html/man3/ASN1_item_d2i_bio.html]=man3/ASN1_item_d2i_bio.pod +DEPEND[man/man3/ASN1_item_d2i_bio.3]=man3/ASN1_item_d2i_bio.pod +GENERATE[man/man3/ASN1_item_d2i_bio.3]=man3/ASN1_item_d2i_bio.pod +DEPEND[html/man3/ASN1_item_new.html]=man3/ASN1_item_new.pod +GENERATE[html/man3/ASN1_item_new.html]=man3/ASN1_item_new.pod +DEPEND[man/man3/ASN1_item_new.3]=man3/ASN1_item_new.pod +GENERATE[man/man3/ASN1_item_new.3]=man3/ASN1_item_new.pod +DEPEND[html/man3/ASN1_item_sign.html]=man3/ASN1_item_sign.pod +GENERATE[html/man3/ASN1_item_sign.html]=man3/ASN1_item_sign.pod +DEPEND[man/man3/ASN1_item_sign.3]=man3/ASN1_item_sign.pod +GENERATE[man/man3/ASN1_item_sign.3]=man3/ASN1_item_sign.pod +DEPEND[html/man3/ASYNC_WAIT_CTX_new.html]=man3/ASYNC_WAIT_CTX_new.pod +GENERATE[html/man3/ASYNC_WAIT_CTX_new.html]=man3/ASYNC_WAIT_CTX_new.pod +DEPEND[man/man3/ASYNC_WAIT_CTX_new.3]=man3/ASYNC_WAIT_CTX_new.pod +GENERATE[man/man3/ASYNC_WAIT_CTX_new.3]=man3/ASYNC_WAIT_CTX_new.pod +DEPEND[html/man3/ASYNC_start_job.html]=man3/ASYNC_start_job.pod +GENERATE[html/man3/ASYNC_start_job.html]=man3/ASYNC_start_job.pod +DEPEND[man/man3/ASYNC_start_job.3]=man3/ASYNC_start_job.pod +GENERATE[man/man3/ASYNC_start_job.3]=man3/ASYNC_start_job.pod +DEPEND[html/man3/BF_encrypt.html]=man3/BF_encrypt.pod +GENERATE[html/man3/BF_encrypt.html]=man3/BF_encrypt.pod +DEPEND[man/man3/BF_encrypt.3]=man3/BF_encrypt.pod +GENERATE[man/man3/BF_encrypt.3]=man3/BF_encrypt.pod +DEPEND[html/man3/BIO_ADDR.html]=man3/BIO_ADDR.pod +GENERATE[html/man3/BIO_ADDR.html]=man3/BIO_ADDR.pod +DEPEND[man/man3/BIO_ADDR.3]=man3/BIO_ADDR.pod +GENERATE[man/man3/BIO_ADDR.3]=man3/BIO_ADDR.pod +DEPEND[html/man3/BIO_ADDRINFO.html]=man3/BIO_ADDRINFO.pod +GENERATE[html/man3/BIO_ADDRINFO.html]=man3/BIO_ADDRINFO.pod +DEPEND[man/man3/BIO_ADDRINFO.3]=man3/BIO_ADDRINFO.pod +GENERATE[man/man3/BIO_ADDRINFO.3]=man3/BIO_ADDRINFO.pod +DEPEND[html/man3/BIO_connect.html]=man3/BIO_connect.pod +GENERATE[html/man3/BIO_connect.html]=man3/BIO_connect.pod +DEPEND[man/man3/BIO_connect.3]=man3/BIO_connect.pod +GENERATE[man/man3/BIO_connect.3]=man3/BIO_connect.pod +DEPEND[html/man3/BIO_ctrl.html]=man3/BIO_ctrl.pod +GENERATE[html/man3/BIO_ctrl.html]=man3/BIO_ctrl.pod +DEPEND[man/man3/BIO_ctrl.3]=man3/BIO_ctrl.pod +GENERATE[man/man3/BIO_ctrl.3]=man3/BIO_ctrl.pod +DEPEND[html/man3/BIO_f_base64.html]=man3/BIO_f_base64.pod +GENERATE[html/man3/BIO_f_base64.html]=man3/BIO_f_base64.pod +DEPEND[man/man3/BIO_f_base64.3]=man3/BIO_f_base64.pod +GENERATE[man/man3/BIO_f_base64.3]=man3/BIO_f_base64.pod +DEPEND[html/man3/BIO_f_buffer.html]=man3/BIO_f_buffer.pod +GENERATE[html/man3/BIO_f_buffer.html]=man3/BIO_f_buffer.pod +DEPEND[man/man3/BIO_f_buffer.3]=man3/BIO_f_buffer.pod +GENERATE[man/man3/BIO_f_buffer.3]=man3/BIO_f_buffer.pod +DEPEND[html/man3/BIO_f_cipher.html]=man3/BIO_f_cipher.pod +GENERATE[html/man3/BIO_f_cipher.html]=man3/BIO_f_cipher.pod +DEPEND[man/man3/BIO_f_cipher.3]=man3/BIO_f_cipher.pod +GENERATE[man/man3/BIO_f_cipher.3]=man3/BIO_f_cipher.pod +DEPEND[html/man3/BIO_f_md.html]=man3/BIO_f_md.pod +GENERATE[html/man3/BIO_f_md.html]=man3/BIO_f_md.pod +DEPEND[man/man3/BIO_f_md.3]=man3/BIO_f_md.pod +GENERATE[man/man3/BIO_f_md.3]=man3/BIO_f_md.pod +DEPEND[html/man3/BIO_f_null.html]=man3/BIO_f_null.pod +GENERATE[html/man3/BIO_f_null.html]=man3/BIO_f_null.pod +DEPEND[man/man3/BIO_f_null.3]=man3/BIO_f_null.pod +GENERATE[man/man3/BIO_f_null.3]=man3/BIO_f_null.pod +DEPEND[html/man3/BIO_f_prefix.html]=man3/BIO_f_prefix.pod +GENERATE[html/man3/BIO_f_prefix.html]=man3/BIO_f_prefix.pod +DEPEND[man/man3/BIO_f_prefix.3]=man3/BIO_f_prefix.pod +GENERATE[man/man3/BIO_f_prefix.3]=man3/BIO_f_prefix.pod +DEPEND[html/man3/BIO_f_readbuffer.html]=man3/BIO_f_readbuffer.pod +GENERATE[html/man3/BIO_f_readbuffer.html]=man3/BIO_f_readbuffer.pod +DEPEND[man/man3/BIO_f_readbuffer.3]=man3/BIO_f_readbuffer.pod +GENERATE[man/man3/BIO_f_readbuffer.3]=man3/BIO_f_readbuffer.pod +DEPEND[html/man3/BIO_f_ssl.html]=man3/BIO_f_ssl.pod +GENERATE[html/man3/BIO_f_ssl.html]=man3/BIO_f_ssl.pod +DEPEND[man/man3/BIO_f_ssl.3]=man3/BIO_f_ssl.pod +GENERATE[man/man3/BIO_f_ssl.3]=man3/BIO_f_ssl.pod +DEPEND[html/man3/BIO_find_type.html]=man3/BIO_find_type.pod +GENERATE[html/man3/BIO_find_type.html]=man3/BIO_find_type.pod +DEPEND[man/man3/BIO_find_type.3]=man3/BIO_find_type.pod +GENERATE[man/man3/BIO_find_type.3]=man3/BIO_find_type.pod +DEPEND[html/man3/BIO_get_data.html]=man3/BIO_get_data.pod +GENERATE[html/man3/BIO_get_data.html]=man3/BIO_get_data.pod +DEPEND[man/man3/BIO_get_data.3]=man3/BIO_get_data.pod +GENERATE[man/man3/BIO_get_data.3]=man3/BIO_get_data.pod +DEPEND[html/man3/BIO_get_ex_new_index.html]=man3/BIO_get_ex_new_index.pod +GENERATE[html/man3/BIO_get_ex_new_index.html]=man3/BIO_get_ex_new_index.pod +DEPEND[man/man3/BIO_get_ex_new_index.3]=man3/BIO_get_ex_new_index.pod +GENERATE[man/man3/BIO_get_ex_new_index.3]=man3/BIO_get_ex_new_index.pod +DEPEND[html/man3/BIO_meth_new.html]=man3/BIO_meth_new.pod +GENERATE[html/man3/BIO_meth_new.html]=man3/BIO_meth_new.pod +DEPEND[man/man3/BIO_meth_new.3]=man3/BIO_meth_new.pod +GENERATE[man/man3/BIO_meth_new.3]=man3/BIO_meth_new.pod +DEPEND[html/man3/BIO_new.html]=man3/BIO_new.pod +GENERATE[html/man3/BIO_new.html]=man3/BIO_new.pod +DEPEND[man/man3/BIO_new.3]=man3/BIO_new.pod +GENERATE[man/man3/BIO_new.3]=man3/BIO_new.pod +DEPEND[html/man3/BIO_new_CMS.html]=man3/BIO_new_CMS.pod +GENERATE[html/man3/BIO_new_CMS.html]=man3/BIO_new_CMS.pod +DEPEND[man/man3/BIO_new_CMS.3]=man3/BIO_new_CMS.pod +GENERATE[man/man3/BIO_new_CMS.3]=man3/BIO_new_CMS.pod +DEPEND[html/man3/BIO_parse_hostserv.html]=man3/BIO_parse_hostserv.pod +GENERATE[html/man3/BIO_parse_hostserv.html]=man3/BIO_parse_hostserv.pod +DEPEND[man/man3/BIO_parse_hostserv.3]=man3/BIO_parse_hostserv.pod +GENERATE[man/man3/BIO_parse_hostserv.3]=man3/BIO_parse_hostserv.pod +DEPEND[html/man3/BIO_printf.html]=man3/BIO_printf.pod +GENERATE[html/man3/BIO_printf.html]=man3/BIO_printf.pod +DEPEND[man/man3/BIO_printf.3]=man3/BIO_printf.pod +GENERATE[man/man3/BIO_printf.3]=man3/BIO_printf.pod +DEPEND[html/man3/BIO_push.html]=man3/BIO_push.pod +GENERATE[html/man3/BIO_push.html]=man3/BIO_push.pod +DEPEND[man/man3/BIO_push.3]=man3/BIO_push.pod +GENERATE[man/man3/BIO_push.3]=man3/BIO_push.pod +DEPEND[html/man3/BIO_read.html]=man3/BIO_read.pod +GENERATE[html/man3/BIO_read.html]=man3/BIO_read.pod +DEPEND[man/man3/BIO_read.3]=man3/BIO_read.pod +GENERATE[man/man3/BIO_read.3]=man3/BIO_read.pod +DEPEND[html/man3/BIO_s_accept.html]=man3/BIO_s_accept.pod +GENERATE[html/man3/BIO_s_accept.html]=man3/BIO_s_accept.pod +DEPEND[man/man3/BIO_s_accept.3]=man3/BIO_s_accept.pod +GENERATE[man/man3/BIO_s_accept.3]=man3/BIO_s_accept.pod +DEPEND[html/man3/BIO_s_bio.html]=man3/BIO_s_bio.pod +GENERATE[html/man3/BIO_s_bio.html]=man3/BIO_s_bio.pod +DEPEND[man/man3/BIO_s_bio.3]=man3/BIO_s_bio.pod +GENERATE[man/man3/BIO_s_bio.3]=man3/BIO_s_bio.pod +DEPEND[html/man3/BIO_s_connect.html]=man3/BIO_s_connect.pod +GENERATE[html/man3/BIO_s_connect.html]=man3/BIO_s_connect.pod +DEPEND[man/man3/BIO_s_connect.3]=man3/BIO_s_connect.pod +GENERATE[man/man3/BIO_s_connect.3]=man3/BIO_s_connect.pod +DEPEND[html/man3/BIO_s_core.html]=man3/BIO_s_core.pod +GENERATE[html/man3/BIO_s_core.html]=man3/BIO_s_core.pod +DEPEND[man/man3/BIO_s_core.3]=man3/BIO_s_core.pod +GENERATE[man/man3/BIO_s_core.3]=man3/BIO_s_core.pod +DEPEND[html/man3/BIO_s_datagram.html]=man3/BIO_s_datagram.pod +GENERATE[html/man3/BIO_s_datagram.html]=man3/BIO_s_datagram.pod +DEPEND[man/man3/BIO_s_datagram.3]=man3/BIO_s_datagram.pod +GENERATE[man/man3/BIO_s_datagram.3]=man3/BIO_s_datagram.pod +DEPEND[html/man3/BIO_s_fd.html]=man3/BIO_s_fd.pod +GENERATE[html/man3/BIO_s_fd.html]=man3/BIO_s_fd.pod +DEPEND[man/man3/BIO_s_fd.3]=man3/BIO_s_fd.pod +GENERATE[man/man3/BIO_s_fd.3]=man3/BIO_s_fd.pod +DEPEND[html/man3/BIO_s_file.html]=man3/BIO_s_file.pod +GENERATE[html/man3/BIO_s_file.html]=man3/BIO_s_file.pod +DEPEND[man/man3/BIO_s_file.3]=man3/BIO_s_file.pod +GENERATE[man/man3/BIO_s_file.3]=man3/BIO_s_file.pod +DEPEND[html/man3/BIO_s_mem.html]=man3/BIO_s_mem.pod +GENERATE[html/man3/BIO_s_mem.html]=man3/BIO_s_mem.pod +DEPEND[man/man3/BIO_s_mem.3]=man3/BIO_s_mem.pod +GENERATE[man/man3/BIO_s_mem.3]=man3/BIO_s_mem.pod +DEPEND[html/man3/BIO_s_null.html]=man3/BIO_s_null.pod +GENERATE[html/man3/BIO_s_null.html]=man3/BIO_s_null.pod +DEPEND[man/man3/BIO_s_null.3]=man3/BIO_s_null.pod +GENERATE[man/man3/BIO_s_null.3]=man3/BIO_s_null.pod +DEPEND[html/man3/BIO_s_socket.html]=man3/BIO_s_socket.pod +GENERATE[html/man3/BIO_s_socket.html]=man3/BIO_s_socket.pod +DEPEND[man/man3/BIO_s_socket.3]=man3/BIO_s_socket.pod +GENERATE[man/man3/BIO_s_socket.3]=man3/BIO_s_socket.pod +DEPEND[html/man3/BIO_set_callback.html]=man3/BIO_set_callback.pod +GENERATE[html/man3/BIO_set_callback.html]=man3/BIO_set_callback.pod +DEPEND[man/man3/BIO_set_callback.3]=man3/BIO_set_callback.pod +GENERATE[man/man3/BIO_set_callback.3]=man3/BIO_set_callback.pod +DEPEND[html/man3/BIO_should_retry.html]=man3/BIO_should_retry.pod +GENERATE[html/man3/BIO_should_retry.html]=man3/BIO_should_retry.pod +DEPEND[man/man3/BIO_should_retry.3]=man3/BIO_should_retry.pod +GENERATE[man/man3/BIO_should_retry.3]=man3/BIO_should_retry.pod +DEPEND[html/man3/BIO_socket_wait.html]=man3/BIO_socket_wait.pod +GENERATE[html/man3/BIO_socket_wait.html]=man3/BIO_socket_wait.pod +DEPEND[man/man3/BIO_socket_wait.3]=man3/BIO_socket_wait.pod +GENERATE[man/man3/BIO_socket_wait.3]=man3/BIO_socket_wait.pod +DEPEND[html/man3/BN_BLINDING_new.html]=man3/BN_BLINDING_new.pod +GENERATE[html/man3/BN_BLINDING_new.html]=man3/BN_BLINDING_new.pod +DEPEND[man/man3/BN_BLINDING_new.3]=man3/BN_BLINDING_new.pod +GENERATE[man/man3/BN_BLINDING_new.3]=man3/BN_BLINDING_new.pod +DEPEND[html/man3/BN_CTX_new.html]=man3/BN_CTX_new.pod +GENERATE[html/man3/BN_CTX_new.html]=man3/BN_CTX_new.pod +DEPEND[man/man3/BN_CTX_new.3]=man3/BN_CTX_new.pod +GENERATE[man/man3/BN_CTX_new.3]=man3/BN_CTX_new.pod +DEPEND[html/man3/BN_CTX_start.html]=man3/BN_CTX_start.pod +GENERATE[html/man3/BN_CTX_start.html]=man3/BN_CTX_start.pod +DEPEND[man/man3/BN_CTX_start.3]=man3/BN_CTX_start.pod +GENERATE[man/man3/BN_CTX_start.3]=man3/BN_CTX_start.pod +DEPEND[html/man3/BN_add.html]=man3/BN_add.pod +GENERATE[html/man3/BN_add.html]=man3/BN_add.pod +DEPEND[man/man3/BN_add.3]=man3/BN_add.pod +GENERATE[man/man3/BN_add.3]=man3/BN_add.pod +DEPEND[html/man3/BN_add_word.html]=man3/BN_add_word.pod +GENERATE[html/man3/BN_add_word.html]=man3/BN_add_word.pod +DEPEND[man/man3/BN_add_word.3]=man3/BN_add_word.pod +GENERATE[man/man3/BN_add_word.3]=man3/BN_add_word.pod +DEPEND[html/man3/BN_bn2bin.html]=man3/BN_bn2bin.pod +GENERATE[html/man3/BN_bn2bin.html]=man3/BN_bn2bin.pod +DEPEND[man/man3/BN_bn2bin.3]=man3/BN_bn2bin.pod +GENERATE[man/man3/BN_bn2bin.3]=man3/BN_bn2bin.pod +DEPEND[html/man3/BN_cmp.html]=man3/BN_cmp.pod +GENERATE[html/man3/BN_cmp.html]=man3/BN_cmp.pod +DEPEND[man/man3/BN_cmp.3]=man3/BN_cmp.pod +GENERATE[man/man3/BN_cmp.3]=man3/BN_cmp.pod +DEPEND[html/man3/BN_copy.html]=man3/BN_copy.pod +GENERATE[html/man3/BN_copy.html]=man3/BN_copy.pod +DEPEND[man/man3/BN_copy.3]=man3/BN_copy.pod +GENERATE[man/man3/BN_copy.3]=man3/BN_copy.pod +DEPEND[html/man3/BN_generate_prime.html]=man3/BN_generate_prime.pod +GENERATE[html/man3/BN_generate_prime.html]=man3/BN_generate_prime.pod +DEPEND[man/man3/BN_generate_prime.3]=man3/BN_generate_prime.pod +GENERATE[man/man3/BN_generate_prime.3]=man3/BN_generate_prime.pod +DEPEND[html/man3/BN_mod_exp_mont.html]=man3/BN_mod_exp_mont.pod +GENERATE[html/man3/BN_mod_exp_mont.html]=man3/BN_mod_exp_mont.pod +DEPEND[man/man3/BN_mod_exp_mont.3]=man3/BN_mod_exp_mont.pod +GENERATE[man/man3/BN_mod_exp_mont.3]=man3/BN_mod_exp_mont.pod +DEPEND[html/man3/BN_mod_inverse.html]=man3/BN_mod_inverse.pod +GENERATE[html/man3/BN_mod_inverse.html]=man3/BN_mod_inverse.pod +DEPEND[man/man3/BN_mod_inverse.3]=man3/BN_mod_inverse.pod +GENERATE[man/man3/BN_mod_inverse.3]=man3/BN_mod_inverse.pod +DEPEND[html/man3/BN_mod_mul_montgomery.html]=man3/BN_mod_mul_montgomery.pod +GENERATE[html/man3/BN_mod_mul_montgomery.html]=man3/BN_mod_mul_montgomery.pod +DEPEND[man/man3/BN_mod_mul_montgomery.3]=man3/BN_mod_mul_montgomery.pod +GENERATE[man/man3/BN_mod_mul_montgomery.3]=man3/BN_mod_mul_montgomery.pod +DEPEND[html/man3/BN_mod_mul_reciprocal.html]=man3/BN_mod_mul_reciprocal.pod +GENERATE[html/man3/BN_mod_mul_reciprocal.html]=man3/BN_mod_mul_reciprocal.pod +DEPEND[man/man3/BN_mod_mul_reciprocal.3]=man3/BN_mod_mul_reciprocal.pod +GENERATE[man/man3/BN_mod_mul_reciprocal.3]=man3/BN_mod_mul_reciprocal.pod +DEPEND[html/man3/BN_new.html]=man3/BN_new.pod +GENERATE[html/man3/BN_new.html]=man3/BN_new.pod +DEPEND[man/man3/BN_new.3]=man3/BN_new.pod +GENERATE[man/man3/BN_new.3]=man3/BN_new.pod +DEPEND[html/man3/BN_num_bytes.html]=man3/BN_num_bytes.pod +GENERATE[html/man3/BN_num_bytes.html]=man3/BN_num_bytes.pod +DEPEND[man/man3/BN_num_bytes.3]=man3/BN_num_bytes.pod +GENERATE[man/man3/BN_num_bytes.3]=man3/BN_num_bytes.pod +DEPEND[html/man3/BN_rand.html]=man3/BN_rand.pod +GENERATE[html/man3/BN_rand.html]=man3/BN_rand.pod +DEPEND[man/man3/BN_rand.3]=man3/BN_rand.pod +GENERATE[man/man3/BN_rand.3]=man3/BN_rand.pod +DEPEND[html/man3/BN_security_bits.html]=man3/BN_security_bits.pod +GENERATE[html/man3/BN_security_bits.html]=man3/BN_security_bits.pod +DEPEND[man/man3/BN_security_bits.3]=man3/BN_security_bits.pod +GENERATE[man/man3/BN_security_bits.3]=man3/BN_security_bits.pod +DEPEND[html/man3/BN_set_bit.html]=man3/BN_set_bit.pod +GENERATE[html/man3/BN_set_bit.html]=man3/BN_set_bit.pod +DEPEND[man/man3/BN_set_bit.3]=man3/BN_set_bit.pod +GENERATE[man/man3/BN_set_bit.3]=man3/BN_set_bit.pod +DEPEND[html/man3/BN_swap.html]=man3/BN_swap.pod +GENERATE[html/man3/BN_swap.html]=man3/BN_swap.pod +DEPEND[man/man3/BN_swap.3]=man3/BN_swap.pod +GENERATE[man/man3/BN_swap.3]=man3/BN_swap.pod +DEPEND[html/man3/BN_zero.html]=man3/BN_zero.pod +GENERATE[html/man3/BN_zero.html]=man3/BN_zero.pod +DEPEND[man/man3/BN_zero.3]=man3/BN_zero.pod +GENERATE[man/man3/BN_zero.3]=man3/BN_zero.pod +DEPEND[html/man3/BUF_MEM_new.html]=man3/BUF_MEM_new.pod +GENERATE[html/man3/BUF_MEM_new.html]=man3/BUF_MEM_new.pod +DEPEND[man/man3/BUF_MEM_new.3]=man3/BUF_MEM_new.pod +GENERATE[man/man3/BUF_MEM_new.3]=man3/BUF_MEM_new.pod +DEPEND[html/man3/CMS_EncryptedData_decrypt.html]=man3/CMS_EncryptedData_decrypt.pod +GENERATE[html/man3/CMS_EncryptedData_decrypt.html]=man3/CMS_EncryptedData_decrypt.pod +DEPEND[man/man3/CMS_EncryptedData_decrypt.3]=man3/CMS_EncryptedData_decrypt.pod +GENERATE[man/man3/CMS_EncryptedData_decrypt.3]=man3/CMS_EncryptedData_decrypt.pod +DEPEND[html/man3/CMS_EncryptedData_encrypt.html]=man3/CMS_EncryptedData_encrypt.pod +GENERATE[html/man3/CMS_EncryptedData_encrypt.html]=man3/CMS_EncryptedData_encrypt.pod +DEPEND[man/man3/CMS_EncryptedData_encrypt.3]=man3/CMS_EncryptedData_encrypt.pod +GENERATE[man/man3/CMS_EncryptedData_encrypt.3]=man3/CMS_EncryptedData_encrypt.pod +DEPEND[html/man3/CMS_EnvelopedData_create.html]=man3/CMS_EnvelopedData_create.pod +GENERATE[html/man3/CMS_EnvelopedData_create.html]=man3/CMS_EnvelopedData_create.pod +DEPEND[man/man3/CMS_EnvelopedData_create.3]=man3/CMS_EnvelopedData_create.pod +GENERATE[man/man3/CMS_EnvelopedData_create.3]=man3/CMS_EnvelopedData_create.pod +DEPEND[html/man3/CMS_add0_cert.html]=man3/CMS_add0_cert.pod +GENERATE[html/man3/CMS_add0_cert.html]=man3/CMS_add0_cert.pod +DEPEND[man/man3/CMS_add0_cert.3]=man3/CMS_add0_cert.pod +GENERATE[man/man3/CMS_add0_cert.3]=man3/CMS_add0_cert.pod +DEPEND[html/man3/CMS_add1_recipient_cert.html]=man3/CMS_add1_recipient_cert.pod +GENERATE[html/man3/CMS_add1_recipient_cert.html]=man3/CMS_add1_recipient_cert.pod +DEPEND[man/man3/CMS_add1_recipient_cert.3]=man3/CMS_add1_recipient_cert.pod +GENERATE[man/man3/CMS_add1_recipient_cert.3]=man3/CMS_add1_recipient_cert.pod +DEPEND[html/man3/CMS_add1_signer.html]=man3/CMS_add1_signer.pod +GENERATE[html/man3/CMS_add1_signer.html]=man3/CMS_add1_signer.pod +DEPEND[man/man3/CMS_add1_signer.3]=man3/CMS_add1_signer.pod +GENERATE[man/man3/CMS_add1_signer.3]=man3/CMS_add1_signer.pod +DEPEND[html/man3/CMS_compress.html]=man3/CMS_compress.pod +GENERATE[html/man3/CMS_compress.html]=man3/CMS_compress.pod +DEPEND[man/man3/CMS_compress.3]=man3/CMS_compress.pod +GENERATE[man/man3/CMS_compress.3]=man3/CMS_compress.pod +DEPEND[html/man3/CMS_data_create.html]=man3/CMS_data_create.pod +GENERATE[html/man3/CMS_data_create.html]=man3/CMS_data_create.pod +DEPEND[man/man3/CMS_data_create.3]=man3/CMS_data_create.pod +GENERATE[man/man3/CMS_data_create.3]=man3/CMS_data_create.pod +DEPEND[html/man3/CMS_decrypt.html]=man3/CMS_decrypt.pod +GENERATE[html/man3/CMS_decrypt.html]=man3/CMS_decrypt.pod +DEPEND[man/man3/CMS_decrypt.3]=man3/CMS_decrypt.pod +GENERATE[man/man3/CMS_decrypt.3]=man3/CMS_decrypt.pod +DEPEND[html/man3/CMS_digest_create.html]=man3/CMS_digest_create.pod +GENERATE[html/man3/CMS_digest_create.html]=man3/CMS_digest_create.pod +DEPEND[man/man3/CMS_digest_create.3]=man3/CMS_digest_create.pod +GENERATE[man/man3/CMS_digest_create.3]=man3/CMS_digest_create.pod +DEPEND[html/man3/CMS_encrypt.html]=man3/CMS_encrypt.pod +GENERATE[html/man3/CMS_encrypt.html]=man3/CMS_encrypt.pod +DEPEND[man/man3/CMS_encrypt.3]=man3/CMS_encrypt.pod +GENERATE[man/man3/CMS_encrypt.3]=man3/CMS_encrypt.pod +DEPEND[html/man3/CMS_final.html]=man3/CMS_final.pod +GENERATE[html/man3/CMS_final.html]=man3/CMS_final.pod +DEPEND[man/man3/CMS_final.3]=man3/CMS_final.pod +GENERATE[man/man3/CMS_final.3]=man3/CMS_final.pod +DEPEND[html/man3/CMS_get0_RecipientInfos.html]=man3/CMS_get0_RecipientInfos.pod +GENERATE[html/man3/CMS_get0_RecipientInfos.html]=man3/CMS_get0_RecipientInfos.pod +DEPEND[man/man3/CMS_get0_RecipientInfos.3]=man3/CMS_get0_RecipientInfos.pod +GENERATE[man/man3/CMS_get0_RecipientInfos.3]=man3/CMS_get0_RecipientInfos.pod +DEPEND[html/man3/CMS_get0_SignerInfos.html]=man3/CMS_get0_SignerInfos.pod +GENERATE[html/man3/CMS_get0_SignerInfos.html]=man3/CMS_get0_SignerInfos.pod +DEPEND[man/man3/CMS_get0_SignerInfos.3]=man3/CMS_get0_SignerInfos.pod +GENERATE[man/man3/CMS_get0_SignerInfos.3]=man3/CMS_get0_SignerInfos.pod +DEPEND[html/man3/CMS_get0_type.html]=man3/CMS_get0_type.pod +GENERATE[html/man3/CMS_get0_type.html]=man3/CMS_get0_type.pod +DEPEND[man/man3/CMS_get0_type.3]=man3/CMS_get0_type.pod +GENERATE[man/man3/CMS_get0_type.3]=man3/CMS_get0_type.pod +DEPEND[html/man3/CMS_get1_ReceiptRequest.html]=man3/CMS_get1_ReceiptRequest.pod +GENERATE[html/man3/CMS_get1_ReceiptRequest.html]=man3/CMS_get1_ReceiptRequest.pod +DEPEND[man/man3/CMS_get1_ReceiptRequest.3]=man3/CMS_get1_ReceiptRequest.pod +GENERATE[man/man3/CMS_get1_ReceiptRequest.3]=man3/CMS_get1_ReceiptRequest.pod +DEPEND[html/man3/CMS_sign.html]=man3/CMS_sign.pod +GENERATE[html/man3/CMS_sign.html]=man3/CMS_sign.pod +DEPEND[man/man3/CMS_sign.3]=man3/CMS_sign.pod +GENERATE[man/man3/CMS_sign.3]=man3/CMS_sign.pod +DEPEND[html/man3/CMS_sign_receipt.html]=man3/CMS_sign_receipt.pod +GENERATE[html/man3/CMS_sign_receipt.html]=man3/CMS_sign_receipt.pod +DEPEND[man/man3/CMS_sign_receipt.3]=man3/CMS_sign_receipt.pod +GENERATE[man/man3/CMS_sign_receipt.3]=man3/CMS_sign_receipt.pod +DEPEND[html/man3/CMS_uncompress.html]=man3/CMS_uncompress.pod +GENERATE[html/man3/CMS_uncompress.html]=man3/CMS_uncompress.pod +DEPEND[man/man3/CMS_uncompress.3]=man3/CMS_uncompress.pod +GENERATE[man/man3/CMS_uncompress.3]=man3/CMS_uncompress.pod +DEPEND[html/man3/CMS_verify.html]=man3/CMS_verify.pod +GENERATE[html/man3/CMS_verify.html]=man3/CMS_verify.pod +DEPEND[man/man3/CMS_verify.3]=man3/CMS_verify.pod +GENERATE[man/man3/CMS_verify.3]=man3/CMS_verify.pod +DEPEND[html/man3/CMS_verify_receipt.html]=man3/CMS_verify_receipt.pod +GENERATE[html/man3/CMS_verify_receipt.html]=man3/CMS_verify_receipt.pod +DEPEND[man/man3/CMS_verify_receipt.3]=man3/CMS_verify_receipt.pod +GENERATE[man/man3/CMS_verify_receipt.3]=man3/CMS_verify_receipt.pod +DEPEND[html/man3/CONF_modules_free.html]=man3/CONF_modules_free.pod +GENERATE[html/man3/CONF_modules_free.html]=man3/CONF_modules_free.pod +DEPEND[man/man3/CONF_modules_free.3]=man3/CONF_modules_free.pod +GENERATE[man/man3/CONF_modules_free.3]=man3/CONF_modules_free.pod +DEPEND[html/man3/CONF_modules_load_file.html]=man3/CONF_modules_load_file.pod +GENERATE[html/man3/CONF_modules_load_file.html]=man3/CONF_modules_load_file.pod +DEPEND[man/man3/CONF_modules_load_file.3]=man3/CONF_modules_load_file.pod +GENERATE[man/man3/CONF_modules_load_file.3]=man3/CONF_modules_load_file.pod +DEPEND[html/man3/CRYPTO_THREAD_run_once.html]=man3/CRYPTO_THREAD_run_once.pod +GENERATE[html/man3/CRYPTO_THREAD_run_once.html]=man3/CRYPTO_THREAD_run_once.pod +DEPEND[man/man3/CRYPTO_THREAD_run_once.3]=man3/CRYPTO_THREAD_run_once.pod +GENERATE[man/man3/CRYPTO_THREAD_run_once.3]=man3/CRYPTO_THREAD_run_once.pod +DEPEND[html/man3/CRYPTO_get_ex_new_index.html]=man3/CRYPTO_get_ex_new_index.pod +GENERATE[html/man3/CRYPTO_get_ex_new_index.html]=man3/CRYPTO_get_ex_new_index.pod +DEPEND[man/man3/CRYPTO_get_ex_new_index.3]=man3/CRYPTO_get_ex_new_index.pod +GENERATE[man/man3/CRYPTO_get_ex_new_index.3]=man3/CRYPTO_get_ex_new_index.pod +DEPEND[html/man3/CRYPTO_memcmp.html]=man3/CRYPTO_memcmp.pod +GENERATE[html/man3/CRYPTO_memcmp.html]=man3/CRYPTO_memcmp.pod +DEPEND[man/man3/CRYPTO_memcmp.3]=man3/CRYPTO_memcmp.pod +GENERATE[man/man3/CRYPTO_memcmp.3]=man3/CRYPTO_memcmp.pod +DEPEND[html/man3/CTLOG_STORE_get0_log_by_id.html]=man3/CTLOG_STORE_get0_log_by_id.pod +GENERATE[html/man3/CTLOG_STORE_get0_log_by_id.html]=man3/CTLOG_STORE_get0_log_by_id.pod +DEPEND[man/man3/CTLOG_STORE_get0_log_by_id.3]=man3/CTLOG_STORE_get0_log_by_id.pod +GENERATE[man/man3/CTLOG_STORE_get0_log_by_id.3]=man3/CTLOG_STORE_get0_log_by_id.pod +DEPEND[html/man3/CTLOG_STORE_new.html]=man3/CTLOG_STORE_new.pod +GENERATE[html/man3/CTLOG_STORE_new.html]=man3/CTLOG_STORE_new.pod +DEPEND[man/man3/CTLOG_STORE_new.3]=man3/CTLOG_STORE_new.pod +GENERATE[man/man3/CTLOG_STORE_new.3]=man3/CTLOG_STORE_new.pod +DEPEND[html/man3/CTLOG_new.html]=man3/CTLOG_new.pod +GENERATE[html/man3/CTLOG_new.html]=man3/CTLOG_new.pod +DEPEND[man/man3/CTLOG_new.3]=man3/CTLOG_new.pod +GENERATE[man/man3/CTLOG_new.3]=man3/CTLOG_new.pod +DEPEND[html/man3/CT_POLICY_EVAL_CTX_new.html]=man3/CT_POLICY_EVAL_CTX_new.pod +GENERATE[html/man3/CT_POLICY_EVAL_CTX_new.html]=man3/CT_POLICY_EVAL_CTX_new.pod +DEPEND[man/man3/CT_POLICY_EVAL_CTX_new.3]=man3/CT_POLICY_EVAL_CTX_new.pod +GENERATE[man/man3/CT_POLICY_EVAL_CTX_new.3]=man3/CT_POLICY_EVAL_CTX_new.pod +DEPEND[html/man3/DEFINE_STACK_OF.html]=man3/DEFINE_STACK_OF.pod +GENERATE[html/man3/DEFINE_STACK_OF.html]=man3/DEFINE_STACK_OF.pod +DEPEND[man/man3/DEFINE_STACK_OF.3]=man3/DEFINE_STACK_OF.pod +GENERATE[man/man3/DEFINE_STACK_OF.3]=man3/DEFINE_STACK_OF.pod +DEPEND[html/man3/DES_random_key.html]=man3/DES_random_key.pod +GENERATE[html/man3/DES_random_key.html]=man3/DES_random_key.pod +DEPEND[man/man3/DES_random_key.3]=man3/DES_random_key.pod +GENERATE[man/man3/DES_random_key.3]=man3/DES_random_key.pod +DEPEND[html/man3/DH_generate_key.html]=man3/DH_generate_key.pod +GENERATE[html/man3/DH_generate_key.html]=man3/DH_generate_key.pod +DEPEND[man/man3/DH_generate_key.3]=man3/DH_generate_key.pod +GENERATE[man/man3/DH_generate_key.3]=man3/DH_generate_key.pod +DEPEND[html/man3/DH_generate_parameters.html]=man3/DH_generate_parameters.pod +GENERATE[html/man3/DH_generate_parameters.html]=man3/DH_generate_parameters.pod +DEPEND[man/man3/DH_generate_parameters.3]=man3/DH_generate_parameters.pod +GENERATE[man/man3/DH_generate_parameters.3]=man3/DH_generate_parameters.pod +DEPEND[html/man3/DH_get0_pqg.html]=man3/DH_get0_pqg.pod +GENERATE[html/man3/DH_get0_pqg.html]=man3/DH_get0_pqg.pod +DEPEND[man/man3/DH_get0_pqg.3]=man3/DH_get0_pqg.pod +GENERATE[man/man3/DH_get0_pqg.3]=man3/DH_get0_pqg.pod +DEPEND[html/man3/DH_get_1024_160.html]=man3/DH_get_1024_160.pod +GENERATE[html/man3/DH_get_1024_160.html]=man3/DH_get_1024_160.pod +DEPEND[man/man3/DH_get_1024_160.3]=man3/DH_get_1024_160.pod +GENERATE[man/man3/DH_get_1024_160.3]=man3/DH_get_1024_160.pod +DEPEND[html/man3/DH_meth_new.html]=man3/DH_meth_new.pod +GENERATE[html/man3/DH_meth_new.html]=man3/DH_meth_new.pod +DEPEND[man/man3/DH_meth_new.3]=man3/DH_meth_new.pod +GENERATE[man/man3/DH_meth_new.3]=man3/DH_meth_new.pod +DEPEND[html/man3/DH_new.html]=man3/DH_new.pod +GENERATE[html/man3/DH_new.html]=man3/DH_new.pod +DEPEND[man/man3/DH_new.3]=man3/DH_new.pod +GENERATE[man/man3/DH_new.3]=man3/DH_new.pod +DEPEND[html/man3/DH_new_by_nid.html]=man3/DH_new_by_nid.pod +GENERATE[html/man3/DH_new_by_nid.html]=man3/DH_new_by_nid.pod +DEPEND[man/man3/DH_new_by_nid.3]=man3/DH_new_by_nid.pod +GENERATE[man/man3/DH_new_by_nid.3]=man3/DH_new_by_nid.pod +DEPEND[html/man3/DH_set_method.html]=man3/DH_set_method.pod +GENERATE[html/man3/DH_set_method.html]=man3/DH_set_method.pod +DEPEND[man/man3/DH_set_method.3]=man3/DH_set_method.pod +GENERATE[man/man3/DH_set_method.3]=man3/DH_set_method.pod +DEPEND[html/man3/DH_size.html]=man3/DH_size.pod +GENERATE[html/man3/DH_size.html]=man3/DH_size.pod +DEPEND[man/man3/DH_size.3]=man3/DH_size.pod +GENERATE[man/man3/DH_size.3]=man3/DH_size.pod +DEPEND[html/man3/DSA_SIG_new.html]=man3/DSA_SIG_new.pod +GENERATE[html/man3/DSA_SIG_new.html]=man3/DSA_SIG_new.pod +DEPEND[man/man3/DSA_SIG_new.3]=man3/DSA_SIG_new.pod +GENERATE[man/man3/DSA_SIG_new.3]=man3/DSA_SIG_new.pod +DEPEND[html/man3/DSA_do_sign.html]=man3/DSA_do_sign.pod +GENERATE[html/man3/DSA_do_sign.html]=man3/DSA_do_sign.pod +DEPEND[man/man3/DSA_do_sign.3]=man3/DSA_do_sign.pod +GENERATE[man/man3/DSA_do_sign.3]=man3/DSA_do_sign.pod +DEPEND[html/man3/DSA_dup_DH.html]=man3/DSA_dup_DH.pod +GENERATE[html/man3/DSA_dup_DH.html]=man3/DSA_dup_DH.pod +DEPEND[man/man3/DSA_dup_DH.3]=man3/DSA_dup_DH.pod +GENERATE[man/man3/DSA_dup_DH.3]=man3/DSA_dup_DH.pod +DEPEND[html/man3/DSA_generate_key.html]=man3/DSA_generate_key.pod +GENERATE[html/man3/DSA_generate_key.html]=man3/DSA_generate_key.pod +DEPEND[man/man3/DSA_generate_key.3]=man3/DSA_generate_key.pod +GENERATE[man/man3/DSA_generate_key.3]=man3/DSA_generate_key.pod +DEPEND[html/man3/DSA_generate_parameters.html]=man3/DSA_generate_parameters.pod +GENERATE[html/man3/DSA_generate_parameters.html]=man3/DSA_generate_parameters.pod +DEPEND[man/man3/DSA_generate_parameters.3]=man3/DSA_generate_parameters.pod +GENERATE[man/man3/DSA_generate_parameters.3]=man3/DSA_generate_parameters.pod +DEPEND[html/man3/DSA_get0_pqg.html]=man3/DSA_get0_pqg.pod +GENERATE[html/man3/DSA_get0_pqg.html]=man3/DSA_get0_pqg.pod +DEPEND[man/man3/DSA_get0_pqg.3]=man3/DSA_get0_pqg.pod +GENERATE[man/man3/DSA_get0_pqg.3]=man3/DSA_get0_pqg.pod +DEPEND[html/man3/DSA_meth_new.html]=man3/DSA_meth_new.pod +GENERATE[html/man3/DSA_meth_new.html]=man3/DSA_meth_new.pod +DEPEND[man/man3/DSA_meth_new.3]=man3/DSA_meth_new.pod +GENERATE[man/man3/DSA_meth_new.3]=man3/DSA_meth_new.pod +DEPEND[html/man3/DSA_new.html]=man3/DSA_new.pod +GENERATE[html/man3/DSA_new.html]=man3/DSA_new.pod +DEPEND[man/man3/DSA_new.3]=man3/DSA_new.pod +GENERATE[man/man3/DSA_new.3]=man3/DSA_new.pod +DEPEND[html/man3/DSA_set_method.html]=man3/DSA_set_method.pod +GENERATE[html/man3/DSA_set_method.html]=man3/DSA_set_method.pod +DEPEND[man/man3/DSA_set_method.3]=man3/DSA_set_method.pod +GENERATE[man/man3/DSA_set_method.3]=man3/DSA_set_method.pod +DEPEND[html/man3/DSA_sign.html]=man3/DSA_sign.pod +GENERATE[html/man3/DSA_sign.html]=man3/DSA_sign.pod +DEPEND[man/man3/DSA_sign.3]=man3/DSA_sign.pod +GENERATE[man/man3/DSA_sign.3]=man3/DSA_sign.pod +DEPEND[html/man3/DSA_size.html]=man3/DSA_size.pod +GENERATE[html/man3/DSA_size.html]=man3/DSA_size.pod +DEPEND[man/man3/DSA_size.3]=man3/DSA_size.pod +GENERATE[man/man3/DSA_size.3]=man3/DSA_size.pod +DEPEND[html/man3/DTLS_get_data_mtu.html]=man3/DTLS_get_data_mtu.pod +GENERATE[html/man3/DTLS_get_data_mtu.html]=man3/DTLS_get_data_mtu.pod +DEPEND[man/man3/DTLS_get_data_mtu.3]=man3/DTLS_get_data_mtu.pod +GENERATE[man/man3/DTLS_get_data_mtu.3]=man3/DTLS_get_data_mtu.pod +DEPEND[html/man3/DTLS_set_timer_cb.html]=man3/DTLS_set_timer_cb.pod +GENERATE[html/man3/DTLS_set_timer_cb.html]=man3/DTLS_set_timer_cb.pod +DEPEND[man/man3/DTLS_set_timer_cb.3]=man3/DTLS_set_timer_cb.pod +GENERATE[man/man3/DTLS_set_timer_cb.3]=man3/DTLS_set_timer_cb.pod +DEPEND[html/man3/DTLSv1_listen.html]=man3/DTLSv1_listen.pod +GENERATE[html/man3/DTLSv1_listen.html]=man3/DTLSv1_listen.pod +DEPEND[man/man3/DTLSv1_listen.3]=man3/DTLSv1_listen.pod +GENERATE[man/man3/DTLSv1_listen.3]=man3/DTLSv1_listen.pod +DEPEND[html/man3/ECDSA_SIG_new.html]=man3/ECDSA_SIG_new.pod +GENERATE[html/man3/ECDSA_SIG_new.html]=man3/ECDSA_SIG_new.pod +DEPEND[man/man3/ECDSA_SIG_new.3]=man3/ECDSA_SIG_new.pod +GENERATE[man/man3/ECDSA_SIG_new.3]=man3/ECDSA_SIG_new.pod +DEPEND[html/man3/ECDSA_sign.html]=man3/ECDSA_sign.pod +GENERATE[html/man3/ECDSA_sign.html]=man3/ECDSA_sign.pod +DEPEND[man/man3/ECDSA_sign.3]=man3/ECDSA_sign.pod +GENERATE[man/man3/ECDSA_sign.3]=man3/ECDSA_sign.pod +DEPEND[html/man3/ECPKParameters_print.html]=man3/ECPKParameters_print.pod +GENERATE[html/man3/ECPKParameters_print.html]=man3/ECPKParameters_print.pod +DEPEND[man/man3/ECPKParameters_print.3]=man3/ECPKParameters_print.pod +GENERATE[man/man3/ECPKParameters_print.3]=man3/ECPKParameters_print.pod +DEPEND[html/man3/EC_GFp_simple_method.html]=man3/EC_GFp_simple_method.pod +GENERATE[html/man3/EC_GFp_simple_method.html]=man3/EC_GFp_simple_method.pod +DEPEND[man/man3/EC_GFp_simple_method.3]=man3/EC_GFp_simple_method.pod +GENERATE[man/man3/EC_GFp_simple_method.3]=man3/EC_GFp_simple_method.pod +DEPEND[html/man3/EC_GROUP_copy.html]=man3/EC_GROUP_copy.pod +GENERATE[html/man3/EC_GROUP_copy.html]=man3/EC_GROUP_copy.pod +DEPEND[man/man3/EC_GROUP_copy.3]=man3/EC_GROUP_copy.pod +GENERATE[man/man3/EC_GROUP_copy.3]=man3/EC_GROUP_copy.pod +DEPEND[html/man3/EC_GROUP_new.html]=man3/EC_GROUP_new.pod +GENERATE[html/man3/EC_GROUP_new.html]=man3/EC_GROUP_new.pod +DEPEND[man/man3/EC_GROUP_new.3]=man3/EC_GROUP_new.pod +GENERATE[man/man3/EC_GROUP_new.3]=man3/EC_GROUP_new.pod +DEPEND[html/man3/EC_KEY_get_enc_flags.html]=man3/EC_KEY_get_enc_flags.pod +GENERATE[html/man3/EC_KEY_get_enc_flags.html]=man3/EC_KEY_get_enc_flags.pod +DEPEND[man/man3/EC_KEY_get_enc_flags.3]=man3/EC_KEY_get_enc_flags.pod +GENERATE[man/man3/EC_KEY_get_enc_flags.3]=man3/EC_KEY_get_enc_flags.pod +DEPEND[html/man3/EC_KEY_new.html]=man3/EC_KEY_new.pod +GENERATE[html/man3/EC_KEY_new.html]=man3/EC_KEY_new.pod +DEPEND[man/man3/EC_KEY_new.3]=man3/EC_KEY_new.pod +GENERATE[man/man3/EC_KEY_new.3]=man3/EC_KEY_new.pod +DEPEND[html/man3/EC_POINT_add.html]=man3/EC_POINT_add.pod +GENERATE[html/man3/EC_POINT_add.html]=man3/EC_POINT_add.pod +DEPEND[man/man3/EC_POINT_add.3]=man3/EC_POINT_add.pod +GENERATE[man/man3/EC_POINT_add.3]=man3/EC_POINT_add.pod +DEPEND[html/man3/EC_POINT_new.html]=man3/EC_POINT_new.pod +GENERATE[html/man3/EC_POINT_new.html]=man3/EC_POINT_new.pod +DEPEND[man/man3/EC_POINT_new.3]=man3/EC_POINT_new.pod +GENERATE[man/man3/EC_POINT_new.3]=man3/EC_POINT_new.pod +DEPEND[html/man3/ENGINE_add.html]=man3/ENGINE_add.pod +GENERATE[html/man3/ENGINE_add.html]=man3/ENGINE_add.pod +DEPEND[man/man3/ENGINE_add.3]=man3/ENGINE_add.pod +GENERATE[man/man3/ENGINE_add.3]=man3/ENGINE_add.pod +DEPEND[html/man3/ERR_GET_LIB.html]=man3/ERR_GET_LIB.pod +GENERATE[html/man3/ERR_GET_LIB.html]=man3/ERR_GET_LIB.pod +DEPEND[man/man3/ERR_GET_LIB.3]=man3/ERR_GET_LIB.pod +GENERATE[man/man3/ERR_GET_LIB.3]=man3/ERR_GET_LIB.pod +DEPEND[html/man3/ERR_clear_error.html]=man3/ERR_clear_error.pod +GENERATE[html/man3/ERR_clear_error.html]=man3/ERR_clear_error.pod +DEPEND[man/man3/ERR_clear_error.3]=man3/ERR_clear_error.pod +GENERATE[man/man3/ERR_clear_error.3]=man3/ERR_clear_error.pod +DEPEND[html/man3/ERR_error_string.html]=man3/ERR_error_string.pod +GENERATE[html/man3/ERR_error_string.html]=man3/ERR_error_string.pod +DEPEND[man/man3/ERR_error_string.3]=man3/ERR_error_string.pod +GENERATE[man/man3/ERR_error_string.3]=man3/ERR_error_string.pod +DEPEND[html/man3/ERR_get_error.html]=man3/ERR_get_error.pod +GENERATE[html/man3/ERR_get_error.html]=man3/ERR_get_error.pod +DEPEND[man/man3/ERR_get_error.3]=man3/ERR_get_error.pod +GENERATE[man/man3/ERR_get_error.3]=man3/ERR_get_error.pod +DEPEND[html/man3/ERR_load_crypto_strings.html]=man3/ERR_load_crypto_strings.pod +GENERATE[html/man3/ERR_load_crypto_strings.html]=man3/ERR_load_crypto_strings.pod +DEPEND[man/man3/ERR_load_crypto_strings.3]=man3/ERR_load_crypto_strings.pod +GENERATE[man/man3/ERR_load_crypto_strings.3]=man3/ERR_load_crypto_strings.pod +DEPEND[html/man3/ERR_load_strings.html]=man3/ERR_load_strings.pod +GENERATE[html/man3/ERR_load_strings.html]=man3/ERR_load_strings.pod +DEPEND[man/man3/ERR_load_strings.3]=man3/ERR_load_strings.pod +GENERATE[man/man3/ERR_load_strings.3]=man3/ERR_load_strings.pod +DEPEND[html/man3/ERR_new.html]=man3/ERR_new.pod +GENERATE[html/man3/ERR_new.html]=man3/ERR_new.pod +DEPEND[man/man3/ERR_new.3]=man3/ERR_new.pod +GENERATE[man/man3/ERR_new.3]=man3/ERR_new.pod +DEPEND[html/man3/ERR_print_errors.html]=man3/ERR_print_errors.pod +GENERATE[html/man3/ERR_print_errors.html]=man3/ERR_print_errors.pod +DEPEND[man/man3/ERR_print_errors.3]=man3/ERR_print_errors.pod +GENERATE[man/man3/ERR_print_errors.3]=man3/ERR_print_errors.pod +DEPEND[html/man3/ERR_put_error.html]=man3/ERR_put_error.pod +GENERATE[html/man3/ERR_put_error.html]=man3/ERR_put_error.pod +DEPEND[man/man3/ERR_put_error.3]=man3/ERR_put_error.pod +GENERATE[man/man3/ERR_put_error.3]=man3/ERR_put_error.pod +DEPEND[html/man3/ERR_remove_state.html]=man3/ERR_remove_state.pod +GENERATE[html/man3/ERR_remove_state.html]=man3/ERR_remove_state.pod +DEPEND[man/man3/ERR_remove_state.3]=man3/ERR_remove_state.pod +GENERATE[man/man3/ERR_remove_state.3]=man3/ERR_remove_state.pod +DEPEND[html/man3/ERR_set_mark.html]=man3/ERR_set_mark.pod +GENERATE[html/man3/ERR_set_mark.html]=man3/ERR_set_mark.pod +DEPEND[man/man3/ERR_set_mark.3]=man3/ERR_set_mark.pod +GENERATE[man/man3/ERR_set_mark.3]=man3/ERR_set_mark.pod +DEPEND[html/man3/EVP_ASYM_CIPHER_free.html]=man3/EVP_ASYM_CIPHER_free.pod +GENERATE[html/man3/EVP_ASYM_CIPHER_free.html]=man3/EVP_ASYM_CIPHER_free.pod +DEPEND[man/man3/EVP_ASYM_CIPHER_free.3]=man3/EVP_ASYM_CIPHER_free.pod +GENERATE[man/man3/EVP_ASYM_CIPHER_free.3]=man3/EVP_ASYM_CIPHER_free.pod +DEPEND[html/man3/EVP_BytesToKey.html]=man3/EVP_BytesToKey.pod +GENERATE[html/man3/EVP_BytesToKey.html]=man3/EVP_BytesToKey.pod +DEPEND[man/man3/EVP_BytesToKey.3]=man3/EVP_BytesToKey.pod +GENERATE[man/man3/EVP_BytesToKey.3]=man3/EVP_BytesToKey.pod +DEPEND[html/man3/EVP_CIPHER_CTX_get_cipher_data.html]=man3/EVP_CIPHER_CTX_get_cipher_data.pod +GENERATE[html/man3/EVP_CIPHER_CTX_get_cipher_data.html]=man3/EVP_CIPHER_CTX_get_cipher_data.pod +DEPEND[man/man3/EVP_CIPHER_CTX_get_cipher_data.3]=man3/EVP_CIPHER_CTX_get_cipher_data.pod +GENERATE[man/man3/EVP_CIPHER_CTX_get_cipher_data.3]=man3/EVP_CIPHER_CTX_get_cipher_data.pod +DEPEND[html/man3/EVP_CIPHER_CTX_get_original_iv.html]=man3/EVP_CIPHER_CTX_get_original_iv.pod +GENERATE[html/man3/EVP_CIPHER_CTX_get_original_iv.html]=man3/EVP_CIPHER_CTX_get_original_iv.pod +DEPEND[man/man3/EVP_CIPHER_CTX_get_original_iv.3]=man3/EVP_CIPHER_CTX_get_original_iv.pod +GENERATE[man/man3/EVP_CIPHER_CTX_get_original_iv.3]=man3/EVP_CIPHER_CTX_get_original_iv.pod +DEPEND[html/man3/EVP_CIPHER_meth_new.html]=man3/EVP_CIPHER_meth_new.pod +GENERATE[html/man3/EVP_CIPHER_meth_new.html]=man3/EVP_CIPHER_meth_new.pod +DEPEND[man/man3/EVP_CIPHER_meth_new.3]=man3/EVP_CIPHER_meth_new.pod +GENERATE[man/man3/EVP_CIPHER_meth_new.3]=man3/EVP_CIPHER_meth_new.pod +DEPEND[html/man3/EVP_DigestInit.html]=man3/EVP_DigestInit.pod +GENERATE[html/man3/EVP_DigestInit.html]=man3/EVP_DigestInit.pod +DEPEND[man/man3/EVP_DigestInit.3]=man3/EVP_DigestInit.pod +GENERATE[man/man3/EVP_DigestInit.3]=man3/EVP_DigestInit.pod +DEPEND[html/man3/EVP_DigestSignInit.html]=man3/EVP_DigestSignInit.pod +GENERATE[html/man3/EVP_DigestSignInit.html]=man3/EVP_DigestSignInit.pod +DEPEND[man/man3/EVP_DigestSignInit.3]=man3/EVP_DigestSignInit.pod +GENERATE[man/man3/EVP_DigestSignInit.3]=man3/EVP_DigestSignInit.pod +DEPEND[html/man3/EVP_DigestVerifyInit.html]=man3/EVP_DigestVerifyInit.pod +GENERATE[html/man3/EVP_DigestVerifyInit.html]=man3/EVP_DigestVerifyInit.pod +DEPEND[man/man3/EVP_DigestVerifyInit.3]=man3/EVP_DigestVerifyInit.pod +GENERATE[man/man3/EVP_DigestVerifyInit.3]=man3/EVP_DigestVerifyInit.pod +DEPEND[html/man3/EVP_EncodeInit.html]=man3/EVP_EncodeInit.pod +GENERATE[html/man3/EVP_EncodeInit.html]=man3/EVP_EncodeInit.pod +DEPEND[man/man3/EVP_EncodeInit.3]=man3/EVP_EncodeInit.pod +GENERATE[man/man3/EVP_EncodeInit.3]=man3/EVP_EncodeInit.pod +DEPEND[html/man3/EVP_EncryptInit.html]=man3/EVP_EncryptInit.pod +GENERATE[html/man3/EVP_EncryptInit.html]=man3/EVP_EncryptInit.pod +DEPEND[man/man3/EVP_EncryptInit.3]=man3/EVP_EncryptInit.pod +GENERATE[man/man3/EVP_EncryptInit.3]=man3/EVP_EncryptInit.pod +DEPEND[html/man3/EVP_KDF.html]=man3/EVP_KDF.pod +GENERATE[html/man3/EVP_KDF.html]=man3/EVP_KDF.pod +DEPEND[man/man3/EVP_KDF.3]=man3/EVP_KDF.pod +GENERATE[man/man3/EVP_KDF.3]=man3/EVP_KDF.pod +DEPEND[html/man3/EVP_KEM_free.html]=man3/EVP_KEM_free.pod +GENERATE[html/man3/EVP_KEM_free.html]=man3/EVP_KEM_free.pod +DEPEND[man/man3/EVP_KEM_free.3]=man3/EVP_KEM_free.pod +GENERATE[man/man3/EVP_KEM_free.3]=man3/EVP_KEM_free.pod +DEPEND[html/man3/EVP_KEYEXCH_free.html]=man3/EVP_KEYEXCH_free.pod +GENERATE[html/man3/EVP_KEYEXCH_free.html]=man3/EVP_KEYEXCH_free.pod +DEPEND[man/man3/EVP_KEYEXCH_free.3]=man3/EVP_KEYEXCH_free.pod +GENERATE[man/man3/EVP_KEYEXCH_free.3]=man3/EVP_KEYEXCH_free.pod +DEPEND[html/man3/EVP_KEYMGMT.html]=man3/EVP_KEYMGMT.pod +GENERATE[html/man3/EVP_KEYMGMT.html]=man3/EVP_KEYMGMT.pod +DEPEND[man/man3/EVP_KEYMGMT.3]=man3/EVP_KEYMGMT.pod +GENERATE[man/man3/EVP_KEYMGMT.3]=man3/EVP_KEYMGMT.pod +DEPEND[html/man3/EVP_MAC.html]=man3/EVP_MAC.pod +GENERATE[html/man3/EVP_MAC.html]=man3/EVP_MAC.pod +DEPEND[man/man3/EVP_MAC.3]=man3/EVP_MAC.pod +GENERATE[man/man3/EVP_MAC.3]=man3/EVP_MAC.pod +DEPEND[html/man3/EVP_MD_meth_new.html]=man3/EVP_MD_meth_new.pod +GENERATE[html/man3/EVP_MD_meth_new.html]=man3/EVP_MD_meth_new.pod +DEPEND[man/man3/EVP_MD_meth_new.3]=man3/EVP_MD_meth_new.pod +GENERATE[man/man3/EVP_MD_meth_new.3]=man3/EVP_MD_meth_new.pod +DEPEND[html/man3/EVP_OpenInit.html]=man3/EVP_OpenInit.pod +GENERATE[html/man3/EVP_OpenInit.html]=man3/EVP_OpenInit.pod +DEPEND[man/man3/EVP_OpenInit.3]=man3/EVP_OpenInit.pod +GENERATE[man/man3/EVP_OpenInit.3]=man3/EVP_OpenInit.pod +DEPEND[html/man3/EVP_PBE_CipherInit.html]=man3/EVP_PBE_CipherInit.pod +GENERATE[html/man3/EVP_PBE_CipherInit.html]=man3/EVP_PBE_CipherInit.pod +DEPEND[man/man3/EVP_PBE_CipherInit.3]=man3/EVP_PBE_CipherInit.pod +GENERATE[man/man3/EVP_PBE_CipherInit.3]=man3/EVP_PBE_CipherInit.pod +DEPEND[html/man3/EVP_PKEY2PKCS8.html]=man3/EVP_PKEY2PKCS8.pod +GENERATE[html/man3/EVP_PKEY2PKCS8.html]=man3/EVP_PKEY2PKCS8.pod +DEPEND[man/man3/EVP_PKEY2PKCS8.3]=man3/EVP_PKEY2PKCS8.pod +GENERATE[man/man3/EVP_PKEY2PKCS8.3]=man3/EVP_PKEY2PKCS8.pod +DEPEND[html/man3/EVP_PKEY_ASN1_METHOD.html]=man3/EVP_PKEY_ASN1_METHOD.pod +GENERATE[html/man3/EVP_PKEY_ASN1_METHOD.html]=man3/EVP_PKEY_ASN1_METHOD.pod +DEPEND[man/man3/EVP_PKEY_ASN1_METHOD.3]=man3/EVP_PKEY_ASN1_METHOD.pod +GENERATE[man/man3/EVP_PKEY_ASN1_METHOD.3]=man3/EVP_PKEY_ASN1_METHOD.pod +DEPEND[html/man3/EVP_PKEY_CTX_ctrl.html]=man3/EVP_PKEY_CTX_ctrl.pod +GENERATE[html/man3/EVP_PKEY_CTX_ctrl.html]=man3/EVP_PKEY_CTX_ctrl.pod +DEPEND[man/man3/EVP_PKEY_CTX_ctrl.3]=man3/EVP_PKEY_CTX_ctrl.pod +GENERATE[man/man3/EVP_PKEY_CTX_ctrl.3]=man3/EVP_PKEY_CTX_ctrl.pod +DEPEND[html/man3/EVP_PKEY_CTX_get0_libctx.html]=man3/EVP_PKEY_CTX_get0_libctx.pod +GENERATE[html/man3/EVP_PKEY_CTX_get0_libctx.html]=man3/EVP_PKEY_CTX_get0_libctx.pod +DEPEND[man/man3/EVP_PKEY_CTX_get0_libctx.3]=man3/EVP_PKEY_CTX_get0_libctx.pod +GENERATE[man/man3/EVP_PKEY_CTX_get0_libctx.3]=man3/EVP_PKEY_CTX_get0_libctx.pod +DEPEND[html/man3/EVP_PKEY_CTX_get0_pkey.html]=man3/EVP_PKEY_CTX_get0_pkey.pod +GENERATE[html/man3/EVP_PKEY_CTX_get0_pkey.html]=man3/EVP_PKEY_CTX_get0_pkey.pod +DEPEND[man/man3/EVP_PKEY_CTX_get0_pkey.3]=man3/EVP_PKEY_CTX_get0_pkey.pod +GENERATE[man/man3/EVP_PKEY_CTX_get0_pkey.3]=man3/EVP_PKEY_CTX_get0_pkey.pod +DEPEND[html/man3/EVP_PKEY_CTX_new.html]=man3/EVP_PKEY_CTX_new.pod +GENERATE[html/man3/EVP_PKEY_CTX_new.html]=man3/EVP_PKEY_CTX_new.pod +DEPEND[man/man3/EVP_PKEY_CTX_new.3]=man3/EVP_PKEY_CTX_new.pod +GENERATE[man/man3/EVP_PKEY_CTX_new.3]=man3/EVP_PKEY_CTX_new.pod +DEPEND[html/man3/EVP_PKEY_CTX_set1_pbe_pass.html]=man3/EVP_PKEY_CTX_set1_pbe_pass.pod +GENERATE[html/man3/EVP_PKEY_CTX_set1_pbe_pass.html]=man3/EVP_PKEY_CTX_set1_pbe_pass.pod +DEPEND[man/man3/EVP_PKEY_CTX_set1_pbe_pass.3]=man3/EVP_PKEY_CTX_set1_pbe_pass.pod +GENERATE[man/man3/EVP_PKEY_CTX_set1_pbe_pass.3]=man3/EVP_PKEY_CTX_set1_pbe_pass.pod +DEPEND[html/man3/EVP_PKEY_CTX_set_hkdf_md.html]=man3/EVP_PKEY_CTX_set_hkdf_md.pod +GENERATE[html/man3/EVP_PKEY_CTX_set_hkdf_md.html]=man3/EVP_PKEY_CTX_set_hkdf_md.pod +DEPEND[man/man3/EVP_PKEY_CTX_set_hkdf_md.3]=man3/EVP_PKEY_CTX_set_hkdf_md.pod +GENERATE[man/man3/EVP_PKEY_CTX_set_hkdf_md.3]=man3/EVP_PKEY_CTX_set_hkdf_md.pod +DEPEND[html/man3/EVP_PKEY_CTX_set_params.html]=man3/EVP_PKEY_CTX_set_params.pod +GENERATE[html/man3/EVP_PKEY_CTX_set_params.html]=man3/EVP_PKEY_CTX_set_params.pod +DEPEND[man/man3/EVP_PKEY_CTX_set_params.3]=man3/EVP_PKEY_CTX_set_params.pod +GENERATE[man/man3/EVP_PKEY_CTX_set_params.3]=man3/EVP_PKEY_CTX_set_params.pod +DEPEND[html/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.html]=man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.pod +GENERATE[html/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.html]=man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.pod +DEPEND[man/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.3]=man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.pod +GENERATE[man/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.3]=man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.pod +DEPEND[html/man3/EVP_PKEY_CTX_set_scrypt_N.html]=man3/EVP_PKEY_CTX_set_scrypt_N.pod +GENERATE[html/man3/EVP_PKEY_CTX_set_scrypt_N.html]=man3/EVP_PKEY_CTX_set_scrypt_N.pod +DEPEND[man/man3/EVP_PKEY_CTX_set_scrypt_N.3]=man3/EVP_PKEY_CTX_set_scrypt_N.pod +GENERATE[man/man3/EVP_PKEY_CTX_set_scrypt_N.3]=man3/EVP_PKEY_CTX_set_scrypt_N.pod +DEPEND[html/man3/EVP_PKEY_CTX_set_tls1_prf_md.html]=man3/EVP_PKEY_CTX_set_tls1_prf_md.pod +GENERATE[html/man3/EVP_PKEY_CTX_set_tls1_prf_md.html]=man3/EVP_PKEY_CTX_set_tls1_prf_md.pod +DEPEND[man/man3/EVP_PKEY_CTX_set_tls1_prf_md.3]=man3/EVP_PKEY_CTX_set_tls1_prf_md.pod +GENERATE[man/man3/EVP_PKEY_CTX_set_tls1_prf_md.3]=man3/EVP_PKEY_CTX_set_tls1_prf_md.pod +DEPEND[html/man3/EVP_PKEY_asn1_get_count.html]=man3/EVP_PKEY_asn1_get_count.pod +GENERATE[html/man3/EVP_PKEY_asn1_get_count.html]=man3/EVP_PKEY_asn1_get_count.pod +DEPEND[man/man3/EVP_PKEY_asn1_get_count.3]=man3/EVP_PKEY_asn1_get_count.pod +GENERATE[man/man3/EVP_PKEY_asn1_get_count.3]=man3/EVP_PKEY_asn1_get_count.pod +DEPEND[html/man3/EVP_PKEY_check.html]=man3/EVP_PKEY_check.pod +GENERATE[html/man3/EVP_PKEY_check.html]=man3/EVP_PKEY_check.pod +DEPEND[man/man3/EVP_PKEY_check.3]=man3/EVP_PKEY_check.pod +GENERATE[man/man3/EVP_PKEY_check.3]=man3/EVP_PKEY_check.pod +DEPEND[html/man3/EVP_PKEY_copy_parameters.html]=man3/EVP_PKEY_copy_parameters.pod +GENERATE[html/man3/EVP_PKEY_copy_parameters.html]=man3/EVP_PKEY_copy_parameters.pod +DEPEND[man/man3/EVP_PKEY_copy_parameters.3]=man3/EVP_PKEY_copy_parameters.pod +GENERATE[man/man3/EVP_PKEY_copy_parameters.3]=man3/EVP_PKEY_copy_parameters.pod +DEPEND[html/man3/EVP_PKEY_decapsulate.html]=man3/EVP_PKEY_decapsulate.pod +GENERATE[html/man3/EVP_PKEY_decapsulate.html]=man3/EVP_PKEY_decapsulate.pod +DEPEND[man/man3/EVP_PKEY_decapsulate.3]=man3/EVP_PKEY_decapsulate.pod +GENERATE[man/man3/EVP_PKEY_decapsulate.3]=man3/EVP_PKEY_decapsulate.pod +DEPEND[html/man3/EVP_PKEY_decrypt.html]=man3/EVP_PKEY_decrypt.pod +GENERATE[html/man3/EVP_PKEY_decrypt.html]=man3/EVP_PKEY_decrypt.pod +DEPEND[man/man3/EVP_PKEY_decrypt.3]=man3/EVP_PKEY_decrypt.pod +GENERATE[man/man3/EVP_PKEY_decrypt.3]=man3/EVP_PKEY_decrypt.pod +DEPEND[html/man3/EVP_PKEY_derive.html]=man3/EVP_PKEY_derive.pod +GENERATE[html/man3/EVP_PKEY_derive.html]=man3/EVP_PKEY_derive.pod +DEPEND[man/man3/EVP_PKEY_derive.3]=man3/EVP_PKEY_derive.pod +GENERATE[man/man3/EVP_PKEY_derive.3]=man3/EVP_PKEY_derive.pod +DEPEND[html/man3/EVP_PKEY_digestsign_supports_digest.html]=man3/EVP_PKEY_digestsign_supports_digest.pod +GENERATE[html/man3/EVP_PKEY_digestsign_supports_digest.html]=man3/EVP_PKEY_digestsign_supports_digest.pod +DEPEND[man/man3/EVP_PKEY_digestsign_supports_digest.3]=man3/EVP_PKEY_digestsign_supports_digest.pod +GENERATE[man/man3/EVP_PKEY_digestsign_supports_digest.3]=man3/EVP_PKEY_digestsign_supports_digest.pod +DEPEND[html/man3/EVP_PKEY_encapsulate.html]=man3/EVP_PKEY_encapsulate.pod +GENERATE[html/man3/EVP_PKEY_encapsulate.html]=man3/EVP_PKEY_encapsulate.pod +DEPEND[man/man3/EVP_PKEY_encapsulate.3]=man3/EVP_PKEY_encapsulate.pod +GENERATE[man/man3/EVP_PKEY_encapsulate.3]=man3/EVP_PKEY_encapsulate.pod +DEPEND[html/man3/EVP_PKEY_encrypt.html]=man3/EVP_PKEY_encrypt.pod +GENERATE[html/man3/EVP_PKEY_encrypt.html]=man3/EVP_PKEY_encrypt.pod +DEPEND[man/man3/EVP_PKEY_encrypt.3]=man3/EVP_PKEY_encrypt.pod +GENERATE[man/man3/EVP_PKEY_encrypt.3]=man3/EVP_PKEY_encrypt.pod +DEPEND[html/man3/EVP_PKEY_fromdata.html]=man3/EVP_PKEY_fromdata.pod +GENERATE[html/man3/EVP_PKEY_fromdata.html]=man3/EVP_PKEY_fromdata.pod +DEPEND[man/man3/EVP_PKEY_fromdata.3]=man3/EVP_PKEY_fromdata.pod +GENERATE[man/man3/EVP_PKEY_fromdata.3]=man3/EVP_PKEY_fromdata.pod +DEPEND[html/man3/EVP_PKEY_get_default_digest_nid.html]=man3/EVP_PKEY_get_default_digest_nid.pod +GENERATE[html/man3/EVP_PKEY_get_default_digest_nid.html]=man3/EVP_PKEY_get_default_digest_nid.pod +DEPEND[man/man3/EVP_PKEY_get_default_digest_nid.3]=man3/EVP_PKEY_get_default_digest_nid.pod +GENERATE[man/man3/EVP_PKEY_get_default_digest_nid.3]=man3/EVP_PKEY_get_default_digest_nid.pod +DEPEND[html/man3/EVP_PKEY_get_field_type.html]=man3/EVP_PKEY_get_field_type.pod +GENERATE[html/man3/EVP_PKEY_get_field_type.html]=man3/EVP_PKEY_get_field_type.pod +DEPEND[man/man3/EVP_PKEY_get_field_type.3]=man3/EVP_PKEY_get_field_type.pod +GENERATE[man/man3/EVP_PKEY_get_field_type.3]=man3/EVP_PKEY_get_field_type.pod +DEPEND[html/man3/EVP_PKEY_get_group_name.html]=man3/EVP_PKEY_get_group_name.pod +GENERATE[html/man3/EVP_PKEY_get_group_name.html]=man3/EVP_PKEY_get_group_name.pod +DEPEND[man/man3/EVP_PKEY_get_group_name.3]=man3/EVP_PKEY_get_group_name.pod +GENERATE[man/man3/EVP_PKEY_get_group_name.3]=man3/EVP_PKEY_get_group_name.pod +DEPEND[html/man3/EVP_PKEY_get_size.html]=man3/EVP_PKEY_get_size.pod +GENERATE[html/man3/EVP_PKEY_get_size.html]=man3/EVP_PKEY_get_size.pod +DEPEND[man/man3/EVP_PKEY_get_size.3]=man3/EVP_PKEY_get_size.pod +GENERATE[man/man3/EVP_PKEY_get_size.3]=man3/EVP_PKEY_get_size.pod +DEPEND[html/man3/EVP_PKEY_gettable_params.html]=man3/EVP_PKEY_gettable_params.pod +GENERATE[html/man3/EVP_PKEY_gettable_params.html]=man3/EVP_PKEY_gettable_params.pod +DEPEND[man/man3/EVP_PKEY_gettable_params.3]=man3/EVP_PKEY_gettable_params.pod +GENERATE[man/man3/EVP_PKEY_gettable_params.3]=man3/EVP_PKEY_gettable_params.pod +DEPEND[html/man3/EVP_PKEY_is_a.html]=man3/EVP_PKEY_is_a.pod +GENERATE[html/man3/EVP_PKEY_is_a.html]=man3/EVP_PKEY_is_a.pod +DEPEND[man/man3/EVP_PKEY_is_a.3]=man3/EVP_PKEY_is_a.pod +GENERATE[man/man3/EVP_PKEY_is_a.3]=man3/EVP_PKEY_is_a.pod +DEPEND[html/man3/EVP_PKEY_keygen.html]=man3/EVP_PKEY_keygen.pod +GENERATE[html/man3/EVP_PKEY_keygen.html]=man3/EVP_PKEY_keygen.pod +DEPEND[man/man3/EVP_PKEY_keygen.3]=man3/EVP_PKEY_keygen.pod +GENERATE[man/man3/EVP_PKEY_keygen.3]=man3/EVP_PKEY_keygen.pod +DEPEND[html/man3/EVP_PKEY_meth_get_count.html]=man3/EVP_PKEY_meth_get_count.pod +GENERATE[html/man3/EVP_PKEY_meth_get_count.html]=man3/EVP_PKEY_meth_get_count.pod +DEPEND[man/man3/EVP_PKEY_meth_get_count.3]=man3/EVP_PKEY_meth_get_count.pod +GENERATE[man/man3/EVP_PKEY_meth_get_count.3]=man3/EVP_PKEY_meth_get_count.pod +DEPEND[html/man3/EVP_PKEY_meth_new.html]=man3/EVP_PKEY_meth_new.pod +GENERATE[html/man3/EVP_PKEY_meth_new.html]=man3/EVP_PKEY_meth_new.pod +DEPEND[man/man3/EVP_PKEY_meth_new.3]=man3/EVP_PKEY_meth_new.pod +GENERATE[man/man3/EVP_PKEY_meth_new.3]=man3/EVP_PKEY_meth_new.pod +DEPEND[html/man3/EVP_PKEY_new.html]=man3/EVP_PKEY_new.pod +GENERATE[html/man3/EVP_PKEY_new.html]=man3/EVP_PKEY_new.pod +DEPEND[man/man3/EVP_PKEY_new.3]=man3/EVP_PKEY_new.pod +GENERATE[man/man3/EVP_PKEY_new.3]=man3/EVP_PKEY_new.pod +DEPEND[html/man3/EVP_PKEY_print_private.html]=man3/EVP_PKEY_print_private.pod +GENERATE[html/man3/EVP_PKEY_print_private.html]=man3/EVP_PKEY_print_private.pod +DEPEND[man/man3/EVP_PKEY_print_private.3]=man3/EVP_PKEY_print_private.pod +GENERATE[man/man3/EVP_PKEY_print_private.3]=man3/EVP_PKEY_print_private.pod +DEPEND[html/man3/EVP_PKEY_set1_RSA.html]=man3/EVP_PKEY_set1_RSA.pod +GENERATE[html/man3/EVP_PKEY_set1_RSA.html]=man3/EVP_PKEY_set1_RSA.pod +DEPEND[man/man3/EVP_PKEY_set1_RSA.3]=man3/EVP_PKEY_set1_RSA.pod +GENERATE[man/man3/EVP_PKEY_set1_RSA.3]=man3/EVP_PKEY_set1_RSA.pod +DEPEND[html/man3/EVP_PKEY_set1_encoded_public_key.html]=man3/EVP_PKEY_set1_encoded_public_key.pod +GENERATE[html/man3/EVP_PKEY_set1_encoded_public_key.html]=man3/EVP_PKEY_set1_encoded_public_key.pod +DEPEND[man/man3/EVP_PKEY_set1_encoded_public_key.3]=man3/EVP_PKEY_set1_encoded_public_key.pod +GENERATE[man/man3/EVP_PKEY_set1_encoded_public_key.3]=man3/EVP_PKEY_set1_encoded_public_key.pod +DEPEND[html/man3/EVP_PKEY_set_type.html]=man3/EVP_PKEY_set_type.pod +GENERATE[html/man3/EVP_PKEY_set_type.html]=man3/EVP_PKEY_set_type.pod +DEPEND[man/man3/EVP_PKEY_set_type.3]=man3/EVP_PKEY_set_type.pod +GENERATE[man/man3/EVP_PKEY_set_type.3]=man3/EVP_PKEY_set_type.pod +DEPEND[html/man3/EVP_PKEY_settable_params.html]=man3/EVP_PKEY_settable_params.pod +GENERATE[html/man3/EVP_PKEY_settable_params.html]=man3/EVP_PKEY_settable_params.pod +DEPEND[man/man3/EVP_PKEY_settable_params.3]=man3/EVP_PKEY_settable_params.pod +GENERATE[man/man3/EVP_PKEY_settable_params.3]=man3/EVP_PKEY_settable_params.pod +DEPEND[html/man3/EVP_PKEY_sign.html]=man3/EVP_PKEY_sign.pod +GENERATE[html/man3/EVP_PKEY_sign.html]=man3/EVP_PKEY_sign.pod +DEPEND[man/man3/EVP_PKEY_sign.3]=man3/EVP_PKEY_sign.pod +GENERATE[man/man3/EVP_PKEY_sign.3]=man3/EVP_PKEY_sign.pod +DEPEND[html/man3/EVP_PKEY_todata.html]=man3/EVP_PKEY_todata.pod +GENERATE[html/man3/EVP_PKEY_todata.html]=man3/EVP_PKEY_todata.pod +DEPEND[man/man3/EVP_PKEY_todata.3]=man3/EVP_PKEY_todata.pod +GENERATE[man/man3/EVP_PKEY_todata.3]=man3/EVP_PKEY_todata.pod +DEPEND[html/man3/EVP_PKEY_verify.html]=man3/EVP_PKEY_verify.pod +GENERATE[html/man3/EVP_PKEY_verify.html]=man3/EVP_PKEY_verify.pod +DEPEND[man/man3/EVP_PKEY_verify.3]=man3/EVP_PKEY_verify.pod +GENERATE[man/man3/EVP_PKEY_verify.3]=man3/EVP_PKEY_verify.pod +DEPEND[html/man3/EVP_PKEY_verify_recover.html]=man3/EVP_PKEY_verify_recover.pod +GENERATE[html/man3/EVP_PKEY_verify_recover.html]=man3/EVP_PKEY_verify_recover.pod +DEPEND[man/man3/EVP_PKEY_verify_recover.3]=man3/EVP_PKEY_verify_recover.pod +GENERATE[man/man3/EVP_PKEY_verify_recover.3]=man3/EVP_PKEY_verify_recover.pod +DEPEND[html/man3/EVP_RAND.html]=man3/EVP_RAND.pod +GENERATE[html/man3/EVP_RAND.html]=man3/EVP_RAND.pod +DEPEND[man/man3/EVP_RAND.3]=man3/EVP_RAND.pod +GENERATE[man/man3/EVP_RAND.3]=man3/EVP_RAND.pod +DEPEND[html/man3/EVP_SIGNATURE.html]=man3/EVP_SIGNATURE.pod +GENERATE[html/man3/EVP_SIGNATURE.html]=man3/EVP_SIGNATURE.pod +DEPEND[man/man3/EVP_SIGNATURE.3]=man3/EVP_SIGNATURE.pod +GENERATE[man/man3/EVP_SIGNATURE.3]=man3/EVP_SIGNATURE.pod +DEPEND[html/man3/EVP_SealInit.html]=man3/EVP_SealInit.pod +GENERATE[html/man3/EVP_SealInit.html]=man3/EVP_SealInit.pod +DEPEND[man/man3/EVP_SealInit.3]=man3/EVP_SealInit.pod +GENERATE[man/man3/EVP_SealInit.3]=man3/EVP_SealInit.pod +DEPEND[html/man3/EVP_SignInit.html]=man3/EVP_SignInit.pod +GENERATE[html/man3/EVP_SignInit.html]=man3/EVP_SignInit.pod +DEPEND[man/man3/EVP_SignInit.3]=man3/EVP_SignInit.pod +GENERATE[man/man3/EVP_SignInit.3]=man3/EVP_SignInit.pod +DEPEND[html/man3/EVP_VerifyInit.html]=man3/EVP_VerifyInit.pod +GENERATE[html/man3/EVP_VerifyInit.html]=man3/EVP_VerifyInit.pod +DEPEND[man/man3/EVP_VerifyInit.3]=man3/EVP_VerifyInit.pod +GENERATE[man/man3/EVP_VerifyInit.3]=man3/EVP_VerifyInit.pod +DEPEND[html/man3/EVP_aes_128_gcm.html]=man3/EVP_aes_128_gcm.pod +GENERATE[html/man3/EVP_aes_128_gcm.html]=man3/EVP_aes_128_gcm.pod +DEPEND[man/man3/EVP_aes_128_gcm.3]=man3/EVP_aes_128_gcm.pod +GENERATE[man/man3/EVP_aes_128_gcm.3]=man3/EVP_aes_128_gcm.pod +DEPEND[html/man3/EVP_aria_128_gcm.html]=man3/EVP_aria_128_gcm.pod +GENERATE[html/man3/EVP_aria_128_gcm.html]=man3/EVP_aria_128_gcm.pod +DEPEND[man/man3/EVP_aria_128_gcm.3]=man3/EVP_aria_128_gcm.pod +GENERATE[man/man3/EVP_aria_128_gcm.3]=man3/EVP_aria_128_gcm.pod +DEPEND[html/man3/EVP_bf_cbc.html]=man3/EVP_bf_cbc.pod +GENERATE[html/man3/EVP_bf_cbc.html]=man3/EVP_bf_cbc.pod +DEPEND[man/man3/EVP_bf_cbc.3]=man3/EVP_bf_cbc.pod +GENERATE[man/man3/EVP_bf_cbc.3]=man3/EVP_bf_cbc.pod +DEPEND[html/man3/EVP_blake2b512.html]=man3/EVP_blake2b512.pod +GENERATE[html/man3/EVP_blake2b512.html]=man3/EVP_blake2b512.pod +DEPEND[man/man3/EVP_blake2b512.3]=man3/EVP_blake2b512.pod +GENERATE[man/man3/EVP_blake2b512.3]=man3/EVP_blake2b512.pod +DEPEND[html/man3/EVP_camellia_128_ecb.html]=man3/EVP_camellia_128_ecb.pod +GENERATE[html/man3/EVP_camellia_128_ecb.html]=man3/EVP_camellia_128_ecb.pod +DEPEND[man/man3/EVP_camellia_128_ecb.3]=man3/EVP_camellia_128_ecb.pod +GENERATE[man/man3/EVP_camellia_128_ecb.3]=man3/EVP_camellia_128_ecb.pod +DEPEND[html/man3/EVP_cast5_cbc.html]=man3/EVP_cast5_cbc.pod +GENERATE[html/man3/EVP_cast5_cbc.html]=man3/EVP_cast5_cbc.pod +DEPEND[man/man3/EVP_cast5_cbc.3]=man3/EVP_cast5_cbc.pod +GENERATE[man/man3/EVP_cast5_cbc.3]=man3/EVP_cast5_cbc.pod +DEPEND[html/man3/EVP_chacha20.html]=man3/EVP_chacha20.pod +GENERATE[html/man3/EVP_chacha20.html]=man3/EVP_chacha20.pod +DEPEND[man/man3/EVP_chacha20.3]=man3/EVP_chacha20.pod +GENERATE[man/man3/EVP_chacha20.3]=man3/EVP_chacha20.pod +DEPEND[html/man3/EVP_des_cbc.html]=man3/EVP_des_cbc.pod +GENERATE[html/man3/EVP_des_cbc.html]=man3/EVP_des_cbc.pod +DEPEND[man/man3/EVP_des_cbc.3]=man3/EVP_des_cbc.pod +GENERATE[man/man3/EVP_des_cbc.3]=man3/EVP_des_cbc.pod +DEPEND[html/man3/EVP_desx_cbc.html]=man3/EVP_desx_cbc.pod +GENERATE[html/man3/EVP_desx_cbc.html]=man3/EVP_desx_cbc.pod +DEPEND[man/man3/EVP_desx_cbc.3]=man3/EVP_desx_cbc.pod +GENERATE[man/man3/EVP_desx_cbc.3]=man3/EVP_desx_cbc.pod +DEPEND[html/man3/EVP_idea_cbc.html]=man3/EVP_idea_cbc.pod +GENERATE[html/man3/EVP_idea_cbc.html]=man3/EVP_idea_cbc.pod +DEPEND[man/man3/EVP_idea_cbc.3]=man3/EVP_idea_cbc.pod +GENERATE[man/man3/EVP_idea_cbc.3]=man3/EVP_idea_cbc.pod +DEPEND[html/man3/EVP_md2.html]=man3/EVP_md2.pod +GENERATE[html/man3/EVP_md2.html]=man3/EVP_md2.pod +DEPEND[man/man3/EVP_md2.3]=man3/EVP_md2.pod +GENERATE[man/man3/EVP_md2.3]=man3/EVP_md2.pod +DEPEND[html/man3/EVP_md4.html]=man3/EVP_md4.pod +GENERATE[html/man3/EVP_md4.html]=man3/EVP_md4.pod +DEPEND[man/man3/EVP_md4.3]=man3/EVP_md4.pod +GENERATE[man/man3/EVP_md4.3]=man3/EVP_md4.pod +DEPEND[html/man3/EVP_md5.html]=man3/EVP_md5.pod +GENERATE[html/man3/EVP_md5.html]=man3/EVP_md5.pod +DEPEND[man/man3/EVP_md5.3]=man3/EVP_md5.pod +GENERATE[man/man3/EVP_md5.3]=man3/EVP_md5.pod +DEPEND[html/man3/EVP_mdc2.html]=man3/EVP_mdc2.pod +GENERATE[html/man3/EVP_mdc2.html]=man3/EVP_mdc2.pod +DEPEND[man/man3/EVP_mdc2.3]=man3/EVP_mdc2.pod +GENERATE[man/man3/EVP_mdc2.3]=man3/EVP_mdc2.pod +DEPEND[html/man3/EVP_rc2_cbc.html]=man3/EVP_rc2_cbc.pod +GENERATE[html/man3/EVP_rc2_cbc.html]=man3/EVP_rc2_cbc.pod +DEPEND[man/man3/EVP_rc2_cbc.3]=man3/EVP_rc2_cbc.pod +GENERATE[man/man3/EVP_rc2_cbc.3]=man3/EVP_rc2_cbc.pod +DEPEND[html/man3/EVP_rc4.html]=man3/EVP_rc4.pod +GENERATE[html/man3/EVP_rc4.html]=man3/EVP_rc4.pod +DEPEND[man/man3/EVP_rc4.3]=man3/EVP_rc4.pod +GENERATE[man/man3/EVP_rc4.3]=man3/EVP_rc4.pod +DEPEND[html/man3/EVP_rc5_32_12_16_cbc.html]=man3/EVP_rc5_32_12_16_cbc.pod +GENERATE[html/man3/EVP_rc5_32_12_16_cbc.html]=man3/EVP_rc5_32_12_16_cbc.pod +DEPEND[man/man3/EVP_rc5_32_12_16_cbc.3]=man3/EVP_rc5_32_12_16_cbc.pod +GENERATE[man/man3/EVP_rc5_32_12_16_cbc.3]=man3/EVP_rc5_32_12_16_cbc.pod +DEPEND[html/man3/EVP_ripemd160.html]=man3/EVP_ripemd160.pod +GENERATE[html/man3/EVP_ripemd160.html]=man3/EVP_ripemd160.pod +DEPEND[man/man3/EVP_ripemd160.3]=man3/EVP_ripemd160.pod +GENERATE[man/man3/EVP_ripemd160.3]=man3/EVP_ripemd160.pod +DEPEND[html/man3/EVP_seed_cbc.html]=man3/EVP_seed_cbc.pod +GENERATE[html/man3/EVP_seed_cbc.html]=man3/EVP_seed_cbc.pod +DEPEND[man/man3/EVP_seed_cbc.3]=man3/EVP_seed_cbc.pod +GENERATE[man/man3/EVP_seed_cbc.3]=man3/EVP_seed_cbc.pod +DEPEND[html/man3/EVP_set_default_properties.html]=man3/EVP_set_default_properties.pod +GENERATE[html/man3/EVP_set_default_properties.html]=man3/EVP_set_default_properties.pod +DEPEND[man/man3/EVP_set_default_properties.3]=man3/EVP_set_default_properties.pod +GENERATE[man/man3/EVP_set_default_properties.3]=man3/EVP_set_default_properties.pod +DEPEND[html/man3/EVP_sha1.html]=man3/EVP_sha1.pod +GENERATE[html/man3/EVP_sha1.html]=man3/EVP_sha1.pod +DEPEND[man/man3/EVP_sha1.3]=man3/EVP_sha1.pod +GENERATE[man/man3/EVP_sha1.3]=man3/EVP_sha1.pod +DEPEND[html/man3/EVP_sha224.html]=man3/EVP_sha224.pod +GENERATE[html/man3/EVP_sha224.html]=man3/EVP_sha224.pod +DEPEND[man/man3/EVP_sha224.3]=man3/EVP_sha224.pod +GENERATE[man/man3/EVP_sha224.3]=man3/EVP_sha224.pod +DEPEND[html/man3/EVP_sha3_224.html]=man3/EVP_sha3_224.pod +GENERATE[html/man3/EVP_sha3_224.html]=man3/EVP_sha3_224.pod +DEPEND[man/man3/EVP_sha3_224.3]=man3/EVP_sha3_224.pod +GENERATE[man/man3/EVP_sha3_224.3]=man3/EVP_sha3_224.pod +DEPEND[html/man3/EVP_sm3.html]=man3/EVP_sm3.pod +GENERATE[html/man3/EVP_sm3.html]=man3/EVP_sm3.pod +DEPEND[man/man3/EVP_sm3.3]=man3/EVP_sm3.pod +GENERATE[man/man3/EVP_sm3.3]=man3/EVP_sm3.pod +DEPEND[html/man3/EVP_sm4_cbc.html]=man3/EVP_sm4_cbc.pod +GENERATE[html/man3/EVP_sm4_cbc.html]=man3/EVP_sm4_cbc.pod +DEPEND[man/man3/EVP_sm4_cbc.3]=man3/EVP_sm4_cbc.pod +GENERATE[man/man3/EVP_sm4_cbc.3]=man3/EVP_sm4_cbc.pod +DEPEND[html/man3/EVP_whirlpool.html]=man3/EVP_whirlpool.pod +GENERATE[html/man3/EVP_whirlpool.html]=man3/EVP_whirlpool.pod +DEPEND[man/man3/EVP_whirlpool.3]=man3/EVP_whirlpool.pod +GENERATE[man/man3/EVP_whirlpool.3]=man3/EVP_whirlpool.pod +DEPEND[html/man3/HMAC.html]=man3/HMAC.pod +GENERATE[html/man3/HMAC.html]=man3/HMAC.pod +DEPEND[man/man3/HMAC.3]=man3/HMAC.pod +GENERATE[man/man3/HMAC.3]=man3/HMAC.pod +DEPEND[html/man3/MD5.html]=man3/MD5.pod +GENERATE[html/man3/MD5.html]=man3/MD5.pod +DEPEND[man/man3/MD5.3]=man3/MD5.pod +GENERATE[man/man3/MD5.3]=man3/MD5.pod +DEPEND[html/man3/MDC2_Init.html]=man3/MDC2_Init.pod +GENERATE[html/man3/MDC2_Init.html]=man3/MDC2_Init.pod +DEPEND[man/man3/MDC2_Init.3]=man3/MDC2_Init.pod +GENERATE[man/man3/MDC2_Init.3]=man3/MDC2_Init.pod +DEPEND[html/man3/NCONF_new_ex.html]=man3/NCONF_new_ex.pod +GENERATE[html/man3/NCONF_new_ex.html]=man3/NCONF_new_ex.pod +DEPEND[man/man3/NCONF_new_ex.3]=man3/NCONF_new_ex.pod +GENERATE[man/man3/NCONF_new_ex.3]=man3/NCONF_new_ex.pod +DEPEND[html/man3/OBJ_nid2obj.html]=man3/OBJ_nid2obj.pod +GENERATE[html/man3/OBJ_nid2obj.html]=man3/OBJ_nid2obj.pod +DEPEND[man/man3/OBJ_nid2obj.3]=man3/OBJ_nid2obj.pod +GENERATE[man/man3/OBJ_nid2obj.3]=man3/OBJ_nid2obj.pod +DEPEND[html/man3/OCSP_REQUEST_new.html]=man3/OCSP_REQUEST_new.pod +GENERATE[html/man3/OCSP_REQUEST_new.html]=man3/OCSP_REQUEST_new.pod +DEPEND[man/man3/OCSP_REQUEST_new.3]=man3/OCSP_REQUEST_new.pod +GENERATE[man/man3/OCSP_REQUEST_new.3]=man3/OCSP_REQUEST_new.pod +DEPEND[html/man3/OCSP_cert_to_id.html]=man3/OCSP_cert_to_id.pod +GENERATE[html/man3/OCSP_cert_to_id.html]=man3/OCSP_cert_to_id.pod +DEPEND[man/man3/OCSP_cert_to_id.3]=man3/OCSP_cert_to_id.pod +GENERATE[man/man3/OCSP_cert_to_id.3]=man3/OCSP_cert_to_id.pod +DEPEND[html/man3/OCSP_request_add1_nonce.html]=man3/OCSP_request_add1_nonce.pod +GENERATE[html/man3/OCSP_request_add1_nonce.html]=man3/OCSP_request_add1_nonce.pod +DEPEND[man/man3/OCSP_request_add1_nonce.3]=man3/OCSP_request_add1_nonce.pod +GENERATE[man/man3/OCSP_request_add1_nonce.3]=man3/OCSP_request_add1_nonce.pod +DEPEND[html/man3/OCSP_resp_find_status.html]=man3/OCSP_resp_find_status.pod +GENERATE[html/man3/OCSP_resp_find_status.html]=man3/OCSP_resp_find_status.pod +DEPEND[man/man3/OCSP_resp_find_status.3]=man3/OCSP_resp_find_status.pod +GENERATE[man/man3/OCSP_resp_find_status.3]=man3/OCSP_resp_find_status.pod +DEPEND[html/man3/OCSP_response_status.html]=man3/OCSP_response_status.pod +GENERATE[html/man3/OCSP_response_status.html]=man3/OCSP_response_status.pod +DEPEND[man/man3/OCSP_response_status.3]=man3/OCSP_response_status.pod +GENERATE[man/man3/OCSP_response_status.3]=man3/OCSP_response_status.pod +DEPEND[html/man3/OCSP_sendreq_new.html]=man3/OCSP_sendreq_new.pod +GENERATE[html/man3/OCSP_sendreq_new.html]=man3/OCSP_sendreq_new.pod +DEPEND[man/man3/OCSP_sendreq_new.3]=man3/OCSP_sendreq_new.pod +GENERATE[man/man3/OCSP_sendreq_new.3]=man3/OCSP_sendreq_new.pod +DEPEND[html/man3/OPENSSL_Applink.html]=man3/OPENSSL_Applink.pod +GENERATE[html/man3/OPENSSL_Applink.html]=man3/OPENSSL_Applink.pod +DEPEND[man/man3/OPENSSL_Applink.3]=man3/OPENSSL_Applink.pod +GENERATE[man/man3/OPENSSL_Applink.3]=man3/OPENSSL_Applink.pod +DEPEND[html/man3/OPENSSL_FILE.html]=man3/OPENSSL_FILE.pod +GENERATE[html/man3/OPENSSL_FILE.html]=man3/OPENSSL_FILE.pod +DEPEND[man/man3/OPENSSL_FILE.3]=man3/OPENSSL_FILE.pod +GENERATE[man/man3/OPENSSL_FILE.3]=man3/OPENSSL_FILE.pod +DEPEND[html/man3/OPENSSL_LH_COMPFUNC.html]=man3/OPENSSL_LH_COMPFUNC.pod +GENERATE[html/man3/OPENSSL_LH_COMPFUNC.html]=man3/OPENSSL_LH_COMPFUNC.pod +DEPEND[man/man3/OPENSSL_LH_COMPFUNC.3]=man3/OPENSSL_LH_COMPFUNC.pod +GENERATE[man/man3/OPENSSL_LH_COMPFUNC.3]=man3/OPENSSL_LH_COMPFUNC.pod +DEPEND[html/man3/OPENSSL_LH_stats.html]=man3/OPENSSL_LH_stats.pod +GENERATE[html/man3/OPENSSL_LH_stats.html]=man3/OPENSSL_LH_stats.pod +DEPEND[man/man3/OPENSSL_LH_stats.3]=man3/OPENSSL_LH_stats.pod +GENERATE[man/man3/OPENSSL_LH_stats.3]=man3/OPENSSL_LH_stats.pod +DEPEND[html/man3/OPENSSL_config.html]=man3/OPENSSL_config.pod +GENERATE[html/man3/OPENSSL_config.html]=man3/OPENSSL_config.pod +DEPEND[man/man3/OPENSSL_config.3]=man3/OPENSSL_config.pod +GENERATE[man/man3/OPENSSL_config.3]=man3/OPENSSL_config.pod +DEPEND[html/man3/OPENSSL_fork_prepare.html]=man3/OPENSSL_fork_prepare.pod +GENERATE[html/man3/OPENSSL_fork_prepare.html]=man3/OPENSSL_fork_prepare.pod +DEPEND[man/man3/OPENSSL_fork_prepare.3]=man3/OPENSSL_fork_prepare.pod +GENERATE[man/man3/OPENSSL_fork_prepare.3]=man3/OPENSSL_fork_prepare.pod +DEPEND[html/man3/OPENSSL_gmtime.html]=man3/OPENSSL_gmtime.pod +GENERATE[html/man3/OPENSSL_gmtime.html]=man3/OPENSSL_gmtime.pod +DEPEND[man/man3/OPENSSL_gmtime.3]=man3/OPENSSL_gmtime.pod +GENERATE[man/man3/OPENSSL_gmtime.3]=man3/OPENSSL_gmtime.pod +DEPEND[html/man3/OPENSSL_hexchar2int.html]=man3/OPENSSL_hexchar2int.pod +GENERATE[html/man3/OPENSSL_hexchar2int.html]=man3/OPENSSL_hexchar2int.pod +DEPEND[man/man3/OPENSSL_hexchar2int.3]=man3/OPENSSL_hexchar2int.pod +GENERATE[man/man3/OPENSSL_hexchar2int.3]=man3/OPENSSL_hexchar2int.pod +DEPEND[html/man3/OPENSSL_ia32cap.html]=man3/OPENSSL_ia32cap.pod +GENERATE[html/man3/OPENSSL_ia32cap.html]=man3/OPENSSL_ia32cap.pod +DEPEND[man/man3/OPENSSL_ia32cap.3]=man3/OPENSSL_ia32cap.pod +GENERATE[man/man3/OPENSSL_ia32cap.3]=man3/OPENSSL_ia32cap.pod +DEPEND[html/man3/OPENSSL_init_crypto.html]=man3/OPENSSL_init_crypto.pod +GENERATE[html/man3/OPENSSL_init_crypto.html]=man3/OPENSSL_init_crypto.pod +DEPEND[man/man3/OPENSSL_init_crypto.3]=man3/OPENSSL_init_crypto.pod +GENERATE[man/man3/OPENSSL_init_crypto.3]=man3/OPENSSL_init_crypto.pod +DEPEND[html/man3/OPENSSL_init_ssl.html]=man3/OPENSSL_init_ssl.pod +GENERATE[html/man3/OPENSSL_init_ssl.html]=man3/OPENSSL_init_ssl.pod +DEPEND[man/man3/OPENSSL_init_ssl.3]=man3/OPENSSL_init_ssl.pod +GENERATE[man/man3/OPENSSL_init_ssl.3]=man3/OPENSSL_init_ssl.pod +DEPEND[html/man3/OPENSSL_instrument_bus.html]=man3/OPENSSL_instrument_bus.pod +GENERATE[html/man3/OPENSSL_instrument_bus.html]=man3/OPENSSL_instrument_bus.pod +DEPEND[man/man3/OPENSSL_instrument_bus.3]=man3/OPENSSL_instrument_bus.pod +GENERATE[man/man3/OPENSSL_instrument_bus.3]=man3/OPENSSL_instrument_bus.pod +DEPEND[html/man3/OPENSSL_load_builtin_modules.html]=man3/OPENSSL_load_builtin_modules.pod +GENERATE[html/man3/OPENSSL_load_builtin_modules.html]=man3/OPENSSL_load_builtin_modules.pod +DEPEND[man/man3/OPENSSL_load_builtin_modules.3]=man3/OPENSSL_load_builtin_modules.pod +GENERATE[man/man3/OPENSSL_load_builtin_modules.3]=man3/OPENSSL_load_builtin_modules.pod +DEPEND[html/man3/OPENSSL_malloc.html]=man3/OPENSSL_malloc.pod +GENERATE[html/man3/OPENSSL_malloc.html]=man3/OPENSSL_malloc.pod +DEPEND[man/man3/OPENSSL_malloc.3]=man3/OPENSSL_malloc.pod +GENERATE[man/man3/OPENSSL_malloc.3]=man3/OPENSSL_malloc.pod +DEPEND[html/man3/OPENSSL_s390xcap.html]=man3/OPENSSL_s390xcap.pod +GENERATE[html/man3/OPENSSL_s390xcap.html]=man3/OPENSSL_s390xcap.pod +DEPEND[man/man3/OPENSSL_s390xcap.3]=man3/OPENSSL_s390xcap.pod +GENERATE[man/man3/OPENSSL_s390xcap.3]=man3/OPENSSL_s390xcap.pod +DEPEND[html/man3/OPENSSL_secure_malloc.html]=man3/OPENSSL_secure_malloc.pod +GENERATE[html/man3/OPENSSL_secure_malloc.html]=man3/OPENSSL_secure_malloc.pod +DEPEND[man/man3/OPENSSL_secure_malloc.3]=man3/OPENSSL_secure_malloc.pod +GENERATE[man/man3/OPENSSL_secure_malloc.3]=man3/OPENSSL_secure_malloc.pod +DEPEND[html/man3/OPENSSL_strcasecmp.html]=man3/OPENSSL_strcasecmp.pod +GENERATE[html/man3/OPENSSL_strcasecmp.html]=man3/OPENSSL_strcasecmp.pod +DEPEND[man/man3/OPENSSL_strcasecmp.3]=man3/OPENSSL_strcasecmp.pod +GENERATE[man/man3/OPENSSL_strcasecmp.3]=man3/OPENSSL_strcasecmp.pod +DEPEND[html/man3/OSSL_ALGORITHM.html]=man3/OSSL_ALGORITHM.pod +GENERATE[html/man3/OSSL_ALGORITHM.html]=man3/OSSL_ALGORITHM.pod +DEPEND[man/man3/OSSL_ALGORITHM.3]=man3/OSSL_ALGORITHM.pod +GENERATE[man/man3/OSSL_ALGORITHM.3]=man3/OSSL_ALGORITHM.pod +DEPEND[html/man3/OSSL_CALLBACK.html]=man3/OSSL_CALLBACK.pod +GENERATE[html/man3/OSSL_CALLBACK.html]=man3/OSSL_CALLBACK.pod +DEPEND[man/man3/OSSL_CALLBACK.3]=man3/OSSL_CALLBACK.pod +GENERATE[man/man3/OSSL_CALLBACK.3]=man3/OSSL_CALLBACK.pod +DEPEND[html/man3/OSSL_CMP_CTX_new.html]=man3/OSSL_CMP_CTX_new.pod +GENERATE[html/man3/OSSL_CMP_CTX_new.html]=man3/OSSL_CMP_CTX_new.pod +DEPEND[man/man3/OSSL_CMP_CTX_new.3]=man3/OSSL_CMP_CTX_new.pod +GENERATE[man/man3/OSSL_CMP_CTX_new.3]=man3/OSSL_CMP_CTX_new.pod +DEPEND[html/man3/OSSL_CMP_HDR_get0_transactionID.html]=man3/OSSL_CMP_HDR_get0_transactionID.pod +GENERATE[html/man3/OSSL_CMP_HDR_get0_transactionID.html]=man3/OSSL_CMP_HDR_get0_transactionID.pod +DEPEND[man/man3/OSSL_CMP_HDR_get0_transactionID.3]=man3/OSSL_CMP_HDR_get0_transactionID.pod +GENERATE[man/man3/OSSL_CMP_HDR_get0_transactionID.3]=man3/OSSL_CMP_HDR_get0_transactionID.pod +DEPEND[html/man3/OSSL_CMP_ITAV_set0.html]=man3/OSSL_CMP_ITAV_set0.pod +GENERATE[html/man3/OSSL_CMP_ITAV_set0.html]=man3/OSSL_CMP_ITAV_set0.pod +DEPEND[man/man3/OSSL_CMP_ITAV_set0.3]=man3/OSSL_CMP_ITAV_set0.pod +GENERATE[man/man3/OSSL_CMP_ITAV_set0.3]=man3/OSSL_CMP_ITAV_set0.pod +DEPEND[html/man3/OSSL_CMP_MSG_get0_header.html]=man3/OSSL_CMP_MSG_get0_header.pod +GENERATE[html/man3/OSSL_CMP_MSG_get0_header.html]=man3/OSSL_CMP_MSG_get0_header.pod +DEPEND[man/man3/OSSL_CMP_MSG_get0_header.3]=man3/OSSL_CMP_MSG_get0_header.pod +GENERATE[man/man3/OSSL_CMP_MSG_get0_header.3]=man3/OSSL_CMP_MSG_get0_header.pod +DEPEND[html/man3/OSSL_CMP_MSG_http_perform.html]=man3/OSSL_CMP_MSG_http_perform.pod +GENERATE[html/man3/OSSL_CMP_MSG_http_perform.html]=man3/OSSL_CMP_MSG_http_perform.pod +DEPEND[man/man3/OSSL_CMP_MSG_http_perform.3]=man3/OSSL_CMP_MSG_http_perform.pod +GENERATE[man/man3/OSSL_CMP_MSG_http_perform.3]=man3/OSSL_CMP_MSG_http_perform.pod +DEPEND[html/man3/OSSL_CMP_SRV_CTX_new.html]=man3/OSSL_CMP_SRV_CTX_new.pod +GENERATE[html/man3/OSSL_CMP_SRV_CTX_new.html]=man3/OSSL_CMP_SRV_CTX_new.pod +DEPEND[man/man3/OSSL_CMP_SRV_CTX_new.3]=man3/OSSL_CMP_SRV_CTX_new.pod +GENERATE[man/man3/OSSL_CMP_SRV_CTX_new.3]=man3/OSSL_CMP_SRV_CTX_new.pod +DEPEND[html/man3/OSSL_CMP_STATUSINFO_new.html]=man3/OSSL_CMP_STATUSINFO_new.pod +GENERATE[html/man3/OSSL_CMP_STATUSINFO_new.html]=man3/OSSL_CMP_STATUSINFO_new.pod +DEPEND[man/man3/OSSL_CMP_STATUSINFO_new.3]=man3/OSSL_CMP_STATUSINFO_new.pod +GENERATE[man/man3/OSSL_CMP_STATUSINFO_new.3]=man3/OSSL_CMP_STATUSINFO_new.pod +DEPEND[html/man3/OSSL_CMP_exec_certreq.html]=man3/OSSL_CMP_exec_certreq.pod +GENERATE[html/man3/OSSL_CMP_exec_certreq.html]=man3/OSSL_CMP_exec_certreq.pod +DEPEND[man/man3/OSSL_CMP_exec_certreq.3]=man3/OSSL_CMP_exec_certreq.pod +GENERATE[man/man3/OSSL_CMP_exec_certreq.3]=man3/OSSL_CMP_exec_certreq.pod +DEPEND[html/man3/OSSL_CMP_log_open.html]=man3/OSSL_CMP_log_open.pod +GENERATE[html/man3/OSSL_CMP_log_open.html]=man3/OSSL_CMP_log_open.pod +DEPEND[man/man3/OSSL_CMP_log_open.3]=man3/OSSL_CMP_log_open.pod +GENERATE[man/man3/OSSL_CMP_log_open.3]=man3/OSSL_CMP_log_open.pod +DEPEND[html/man3/OSSL_CMP_validate_msg.html]=man3/OSSL_CMP_validate_msg.pod +GENERATE[html/man3/OSSL_CMP_validate_msg.html]=man3/OSSL_CMP_validate_msg.pod +DEPEND[man/man3/OSSL_CMP_validate_msg.3]=man3/OSSL_CMP_validate_msg.pod +GENERATE[man/man3/OSSL_CMP_validate_msg.3]=man3/OSSL_CMP_validate_msg.pod +DEPEND[html/man3/OSSL_CORE_MAKE_FUNC.html]=man3/OSSL_CORE_MAKE_FUNC.pod +GENERATE[html/man3/OSSL_CORE_MAKE_FUNC.html]=man3/OSSL_CORE_MAKE_FUNC.pod +DEPEND[man/man3/OSSL_CORE_MAKE_FUNC.3]=man3/OSSL_CORE_MAKE_FUNC.pod +GENERATE[man/man3/OSSL_CORE_MAKE_FUNC.3]=man3/OSSL_CORE_MAKE_FUNC.pod +DEPEND[html/man3/OSSL_CRMF_MSG_get0_tmpl.html]=man3/OSSL_CRMF_MSG_get0_tmpl.pod +GENERATE[html/man3/OSSL_CRMF_MSG_get0_tmpl.html]=man3/OSSL_CRMF_MSG_get0_tmpl.pod +DEPEND[man/man3/OSSL_CRMF_MSG_get0_tmpl.3]=man3/OSSL_CRMF_MSG_get0_tmpl.pod +GENERATE[man/man3/OSSL_CRMF_MSG_get0_tmpl.3]=man3/OSSL_CRMF_MSG_get0_tmpl.pod +DEPEND[html/man3/OSSL_CRMF_MSG_set0_validity.html]=man3/OSSL_CRMF_MSG_set0_validity.pod +GENERATE[html/man3/OSSL_CRMF_MSG_set0_validity.html]=man3/OSSL_CRMF_MSG_set0_validity.pod +DEPEND[man/man3/OSSL_CRMF_MSG_set0_validity.3]=man3/OSSL_CRMF_MSG_set0_validity.pod +GENERATE[man/man3/OSSL_CRMF_MSG_set0_validity.3]=man3/OSSL_CRMF_MSG_set0_validity.pod +DEPEND[html/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.html]=man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod +GENERATE[html/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.html]=man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod +DEPEND[man/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.3]=man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod +GENERATE[man/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.3]=man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod +DEPEND[html/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.html]=man3/OSSL_CRMF_MSG_set1_regInfo_certReq.pod +GENERATE[html/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.html]=man3/OSSL_CRMF_MSG_set1_regInfo_certReq.pod +DEPEND[man/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.3]=man3/OSSL_CRMF_MSG_set1_regInfo_certReq.pod +GENERATE[man/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.3]=man3/OSSL_CRMF_MSG_set1_regInfo_certReq.pod +DEPEND[html/man3/OSSL_CRMF_pbmp_new.html]=man3/OSSL_CRMF_pbmp_new.pod +GENERATE[html/man3/OSSL_CRMF_pbmp_new.html]=man3/OSSL_CRMF_pbmp_new.pod +DEPEND[man/man3/OSSL_CRMF_pbmp_new.3]=man3/OSSL_CRMF_pbmp_new.pod +GENERATE[man/man3/OSSL_CRMF_pbmp_new.3]=man3/OSSL_CRMF_pbmp_new.pod +DEPEND[html/man3/OSSL_DECODER.html]=man3/OSSL_DECODER.pod +GENERATE[html/man3/OSSL_DECODER.html]=man3/OSSL_DECODER.pod +DEPEND[man/man3/OSSL_DECODER.3]=man3/OSSL_DECODER.pod +GENERATE[man/man3/OSSL_DECODER.3]=man3/OSSL_DECODER.pod +DEPEND[html/man3/OSSL_DECODER_CTX.html]=man3/OSSL_DECODER_CTX.pod +GENERATE[html/man3/OSSL_DECODER_CTX.html]=man3/OSSL_DECODER_CTX.pod +DEPEND[man/man3/OSSL_DECODER_CTX.3]=man3/OSSL_DECODER_CTX.pod +GENERATE[man/man3/OSSL_DECODER_CTX.3]=man3/OSSL_DECODER_CTX.pod +DEPEND[html/man3/OSSL_DECODER_CTX_new_for_pkey.html]=man3/OSSL_DECODER_CTX_new_for_pkey.pod +GENERATE[html/man3/OSSL_DECODER_CTX_new_for_pkey.html]=man3/OSSL_DECODER_CTX_new_for_pkey.pod +DEPEND[man/man3/OSSL_DECODER_CTX_new_for_pkey.3]=man3/OSSL_DECODER_CTX_new_for_pkey.pod +GENERATE[man/man3/OSSL_DECODER_CTX_new_for_pkey.3]=man3/OSSL_DECODER_CTX_new_for_pkey.pod +DEPEND[html/man3/OSSL_DECODER_from_bio.html]=man3/OSSL_DECODER_from_bio.pod +GENERATE[html/man3/OSSL_DECODER_from_bio.html]=man3/OSSL_DECODER_from_bio.pod +DEPEND[man/man3/OSSL_DECODER_from_bio.3]=man3/OSSL_DECODER_from_bio.pod +GENERATE[man/man3/OSSL_DECODER_from_bio.3]=man3/OSSL_DECODER_from_bio.pod +DEPEND[html/man3/OSSL_DISPATCH.html]=man3/OSSL_DISPATCH.pod +GENERATE[html/man3/OSSL_DISPATCH.html]=man3/OSSL_DISPATCH.pod +DEPEND[man/man3/OSSL_DISPATCH.3]=man3/OSSL_DISPATCH.pod +GENERATE[man/man3/OSSL_DISPATCH.3]=man3/OSSL_DISPATCH.pod +DEPEND[html/man3/OSSL_ENCODER.html]=man3/OSSL_ENCODER.pod +GENERATE[html/man3/OSSL_ENCODER.html]=man3/OSSL_ENCODER.pod +DEPEND[man/man3/OSSL_ENCODER.3]=man3/OSSL_ENCODER.pod +GENERATE[man/man3/OSSL_ENCODER.3]=man3/OSSL_ENCODER.pod +DEPEND[html/man3/OSSL_ENCODER_CTX.html]=man3/OSSL_ENCODER_CTX.pod +GENERATE[html/man3/OSSL_ENCODER_CTX.html]=man3/OSSL_ENCODER_CTX.pod +DEPEND[man/man3/OSSL_ENCODER_CTX.3]=man3/OSSL_ENCODER_CTX.pod +GENERATE[man/man3/OSSL_ENCODER_CTX.3]=man3/OSSL_ENCODER_CTX.pod +DEPEND[html/man3/OSSL_ENCODER_CTX_new_for_pkey.html]=man3/OSSL_ENCODER_CTX_new_for_pkey.pod +GENERATE[html/man3/OSSL_ENCODER_CTX_new_for_pkey.html]=man3/OSSL_ENCODER_CTX_new_for_pkey.pod +DEPEND[man/man3/OSSL_ENCODER_CTX_new_for_pkey.3]=man3/OSSL_ENCODER_CTX_new_for_pkey.pod +GENERATE[man/man3/OSSL_ENCODER_CTX_new_for_pkey.3]=man3/OSSL_ENCODER_CTX_new_for_pkey.pod +DEPEND[html/man3/OSSL_ENCODER_to_bio.html]=man3/OSSL_ENCODER_to_bio.pod +GENERATE[html/man3/OSSL_ENCODER_to_bio.html]=man3/OSSL_ENCODER_to_bio.pod +DEPEND[man/man3/OSSL_ENCODER_to_bio.3]=man3/OSSL_ENCODER_to_bio.pod +GENERATE[man/man3/OSSL_ENCODER_to_bio.3]=man3/OSSL_ENCODER_to_bio.pod +DEPEND[html/man3/OSSL_ESS_check_signing_certs.html]=man3/OSSL_ESS_check_signing_certs.pod +GENERATE[html/man3/OSSL_ESS_check_signing_certs.html]=man3/OSSL_ESS_check_signing_certs.pod +DEPEND[man/man3/OSSL_ESS_check_signing_certs.3]=man3/OSSL_ESS_check_signing_certs.pod +GENERATE[man/man3/OSSL_ESS_check_signing_certs.3]=man3/OSSL_ESS_check_signing_certs.pod +DEPEND[html/man3/OSSL_HTTP_REQ_CTX.html]=man3/OSSL_HTTP_REQ_CTX.pod +GENERATE[html/man3/OSSL_HTTP_REQ_CTX.html]=man3/OSSL_HTTP_REQ_CTX.pod +DEPEND[man/man3/OSSL_HTTP_REQ_CTX.3]=man3/OSSL_HTTP_REQ_CTX.pod +GENERATE[man/man3/OSSL_HTTP_REQ_CTX.3]=man3/OSSL_HTTP_REQ_CTX.pod +DEPEND[html/man3/OSSL_HTTP_parse_url.html]=man3/OSSL_HTTP_parse_url.pod +GENERATE[html/man3/OSSL_HTTP_parse_url.html]=man3/OSSL_HTTP_parse_url.pod +DEPEND[man/man3/OSSL_HTTP_parse_url.3]=man3/OSSL_HTTP_parse_url.pod +GENERATE[man/man3/OSSL_HTTP_parse_url.3]=man3/OSSL_HTTP_parse_url.pod +DEPEND[html/man3/OSSL_HTTP_transfer.html]=man3/OSSL_HTTP_transfer.pod +GENERATE[html/man3/OSSL_HTTP_transfer.html]=man3/OSSL_HTTP_transfer.pod +DEPEND[man/man3/OSSL_HTTP_transfer.3]=man3/OSSL_HTTP_transfer.pod +GENERATE[man/man3/OSSL_HTTP_transfer.3]=man3/OSSL_HTTP_transfer.pod +DEPEND[html/man3/OSSL_ITEM.html]=man3/OSSL_ITEM.pod +GENERATE[html/man3/OSSL_ITEM.html]=man3/OSSL_ITEM.pod +DEPEND[man/man3/OSSL_ITEM.3]=man3/OSSL_ITEM.pod +GENERATE[man/man3/OSSL_ITEM.3]=man3/OSSL_ITEM.pod +DEPEND[html/man3/OSSL_LIB_CTX.html]=man3/OSSL_LIB_CTX.pod +GENERATE[html/man3/OSSL_LIB_CTX.html]=man3/OSSL_LIB_CTX.pod +DEPEND[man/man3/OSSL_LIB_CTX.3]=man3/OSSL_LIB_CTX.pod +GENERATE[man/man3/OSSL_LIB_CTX.3]=man3/OSSL_LIB_CTX.pod +DEPEND[html/man3/OSSL_PARAM.html]=man3/OSSL_PARAM.pod +GENERATE[html/man3/OSSL_PARAM.html]=man3/OSSL_PARAM.pod +DEPEND[man/man3/OSSL_PARAM.3]=man3/OSSL_PARAM.pod +GENERATE[man/man3/OSSL_PARAM.3]=man3/OSSL_PARAM.pod +DEPEND[html/man3/OSSL_PARAM_BLD.html]=man3/OSSL_PARAM_BLD.pod +GENERATE[html/man3/OSSL_PARAM_BLD.html]=man3/OSSL_PARAM_BLD.pod +DEPEND[man/man3/OSSL_PARAM_BLD.3]=man3/OSSL_PARAM_BLD.pod +GENERATE[man/man3/OSSL_PARAM_BLD.3]=man3/OSSL_PARAM_BLD.pod +DEPEND[html/man3/OSSL_PARAM_allocate_from_text.html]=man3/OSSL_PARAM_allocate_from_text.pod +GENERATE[html/man3/OSSL_PARAM_allocate_from_text.html]=man3/OSSL_PARAM_allocate_from_text.pod +DEPEND[man/man3/OSSL_PARAM_allocate_from_text.3]=man3/OSSL_PARAM_allocate_from_text.pod +GENERATE[man/man3/OSSL_PARAM_allocate_from_text.3]=man3/OSSL_PARAM_allocate_from_text.pod +DEPEND[html/man3/OSSL_PARAM_dup.html]=man3/OSSL_PARAM_dup.pod +GENERATE[html/man3/OSSL_PARAM_dup.html]=man3/OSSL_PARAM_dup.pod +DEPEND[man/man3/OSSL_PARAM_dup.3]=man3/OSSL_PARAM_dup.pod +GENERATE[man/man3/OSSL_PARAM_dup.3]=man3/OSSL_PARAM_dup.pod +DEPEND[html/man3/OSSL_PARAM_int.html]=man3/OSSL_PARAM_int.pod +GENERATE[html/man3/OSSL_PARAM_int.html]=man3/OSSL_PARAM_int.pod +DEPEND[man/man3/OSSL_PARAM_int.3]=man3/OSSL_PARAM_int.pod +GENERATE[man/man3/OSSL_PARAM_int.3]=man3/OSSL_PARAM_int.pod +DEPEND[html/man3/OSSL_PROVIDER.html]=man3/OSSL_PROVIDER.pod +GENERATE[html/man3/OSSL_PROVIDER.html]=man3/OSSL_PROVIDER.pod +DEPEND[man/man3/OSSL_PROVIDER.3]=man3/OSSL_PROVIDER.pod +GENERATE[man/man3/OSSL_PROVIDER.3]=man3/OSSL_PROVIDER.pod +DEPEND[html/man3/OSSL_SELF_TEST_new.html]=man3/OSSL_SELF_TEST_new.pod +GENERATE[html/man3/OSSL_SELF_TEST_new.html]=man3/OSSL_SELF_TEST_new.pod +DEPEND[man/man3/OSSL_SELF_TEST_new.3]=man3/OSSL_SELF_TEST_new.pod +GENERATE[man/man3/OSSL_SELF_TEST_new.3]=man3/OSSL_SELF_TEST_new.pod +DEPEND[html/man3/OSSL_SELF_TEST_set_callback.html]=man3/OSSL_SELF_TEST_set_callback.pod +GENERATE[html/man3/OSSL_SELF_TEST_set_callback.html]=man3/OSSL_SELF_TEST_set_callback.pod +DEPEND[man/man3/OSSL_SELF_TEST_set_callback.3]=man3/OSSL_SELF_TEST_set_callback.pod +GENERATE[man/man3/OSSL_SELF_TEST_set_callback.3]=man3/OSSL_SELF_TEST_set_callback.pod +DEPEND[html/man3/OSSL_STORE_INFO.html]=man3/OSSL_STORE_INFO.pod +GENERATE[html/man3/OSSL_STORE_INFO.html]=man3/OSSL_STORE_INFO.pod +DEPEND[man/man3/OSSL_STORE_INFO.3]=man3/OSSL_STORE_INFO.pod +GENERATE[man/man3/OSSL_STORE_INFO.3]=man3/OSSL_STORE_INFO.pod +DEPEND[html/man3/OSSL_STORE_LOADER.html]=man3/OSSL_STORE_LOADER.pod +GENERATE[html/man3/OSSL_STORE_LOADER.html]=man3/OSSL_STORE_LOADER.pod +DEPEND[man/man3/OSSL_STORE_LOADER.3]=man3/OSSL_STORE_LOADER.pod +GENERATE[man/man3/OSSL_STORE_LOADER.3]=man3/OSSL_STORE_LOADER.pod +DEPEND[html/man3/OSSL_STORE_SEARCH.html]=man3/OSSL_STORE_SEARCH.pod +GENERATE[html/man3/OSSL_STORE_SEARCH.html]=man3/OSSL_STORE_SEARCH.pod +DEPEND[man/man3/OSSL_STORE_SEARCH.3]=man3/OSSL_STORE_SEARCH.pod +GENERATE[man/man3/OSSL_STORE_SEARCH.3]=man3/OSSL_STORE_SEARCH.pod +DEPEND[html/man3/OSSL_STORE_attach.html]=man3/OSSL_STORE_attach.pod +GENERATE[html/man3/OSSL_STORE_attach.html]=man3/OSSL_STORE_attach.pod +DEPEND[man/man3/OSSL_STORE_attach.3]=man3/OSSL_STORE_attach.pod +GENERATE[man/man3/OSSL_STORE_attach.3]=man3/OSSL_STORE_attach.pod +DEPEND[html/man3/OSSL_STORE_expect.html]=man3/OSSL_STORE_expect.pod +GENERATE[html/man3/OSSL_STORE_expect.html]=man3/OSSL_STORE_expect.pod +DEPEND[man/man3/OSSL_STORE_expect.3]=man3/OSSL_STORE_expect.pod +GENERATE[man/man3/OSSL_STORE_expect.3]=man3/OSSL_STORE_expect.pod +DEPEND[html/man3/OSSL_STORE_open.html]=man3/OSSL_STORE_open.pod +GENERATE[html/man3/OSSL_STORE_open.html]=man3/OSSL_STORE_open.pod +DEPEND[man/man3/OSSL_STORE_open.3]=man3/OSSL_STORE_open.pod +GENERATE[man/man3/OSSL_STORE_open.3]=man3/OSSL_STORE_open.pod +DEPEND[html/man3/OSSL_trace_enabled.html]=man3/OSSL_trace_enabled.pod +GENERATE[html/man3/OSSL_trace_enabled.html]=man3/OSSL_trace_enabled.pod +DEPEND[man/man3/OSSL_trace_enabled.3]=man3/OSSL_trace_enabled.pod +GENERATE[man/man3/OSSL_trace_enabled.3]=man3/OSSL_trace_enabled.pod +DEPEND[html/man3/OSSL_trace_get_category_num.html]=man3/OSSL_trace_get_category_num.pod +GENERATE[html/man3/OSSL_trace_get_category_num.html]=man3/OSSL_trace_get_category_num.pod +DEPEND[man/man3/OSSL_trace_get_category_num.3]=man3/OSSL_trace_get_category_num.pod +GENERATE[man/man3/OSSL_trace_get_category_num.3]=man3/OSSL_trace_get_category_num.pod +DEPEND[html/man3/OSSL_trace_set_channel.html]=man3/OSSL_trace_set_channel.pod +GENERATE[html/man3/OSSL_trace_set_channel.html]=man3/OSSL_trace_set_channel.pod +DEPEND[man/man3/OSSL_trace_set_channel.3]=man3/OSSL_trace_set_channel.pod +GENERATE[man/man3/OSSL_trace_set_channel.3]=man3/OSSL_trace_set_channel.pod +DEPEND[html/man3/OpenSSL_add_all_algorithms.html]=man3/OpenSSL_add_all_algorithms.pod +GENERATE[html/man3/OpenSSL_add_all_algorithms.html]=man3/OpenSSL_add_all_algorithms.pod +DEPEND[man/man3/OpenSSL_add_all_algorithms.3]=man3/OpenSSL_add_all_algorithms.pod +GENERATE[man/man3/OpenSSL_add_all_algorithms.3]=man3/OpenSSL_add_all_algorithms.pod +DEPEND[html/man3/OpenSSL_version.html]=man3/OpenSSL_version.pod +GENERATE[html/man3/OpenSSL_version.html]=man3/OpenSSL_version.pod +DEPEND[man/man3/OpenSSL_version.3]=man3/OpenSSL_version.pod +GENERATE[man/man3/OpenSSL_version.3]=man3/OpenSSL_version.pod +DEPEND[html/man3/PEM_X509_INFO_read_bio_ex.html]=man3/PEM_X509_INFO_read_bio_ex.pod +GENERATE[html/man3/PEM_X509_INFO_read_bio_ex.html]=man3/PEM_X509_INFO_read_bio_ex.pod +DEPEND[man/man3/PEM_X509_INFO_read_bio_ex.3]=man3/PEM_X509_INFO_read_bio_ex.pod +GENERATE[man/man3/PEM_X509_INFO_read_bio_ex.3]=man3/PEM_X509_INFO_read_bio_ex.pod +DEPEND[html/man3/PEM_bytes_read_bio.html]=man3/PEM_bytes_read_bio.pod +GENERATE[html/man3/PEM_bytes_read_bio.html]=man3/PEM_bytes_read_bio.pod +DEPEND[man/man3/PEM_bytes_read_bio.3]=man3/PEM_bytes_read_bio.pod +GENERATE[man/man3/PEM_bytes_read_bio.3]=man3/PEM_bytes_read_bio.pod +DEPEND[html/man3/PEM_read.html]=man3/PEM_read.pod +GENERATE[html/man3/PEM_read.html]=man3/PEM_read.pod +DEPEND[man/man3/PEM_read.3]=man3/PEM_read.pod +GENERATE[man/man3/PEM_read.3]=man3/PEM_read.pod +DEPEND[html/man3/PEM_read_CMS.html]=man3/PEM_read_CMS.pod +GENERATE[html/man3/PEM_read_CMS.html]=man3/PEM_read_CMS.pod +DEPEND[man/man3/PEM_read_CMS.3]=man3/PEM_read_CMS.pod +GENERATE[man/man3/PEM_read_CMS.3]=man3/PEM_read_CMS.pod +DEPEND[html/man3/PEM_read_bio_PrivateKey.html]=man3/PEM_read_bio_PrivateKey.pod +GENERATE[html/man3/PEM_read_bio_PrivateKey.html]=man3/PEM_read_bio_PrivateKey.pod +DEPEND[man/man3/PEM_read_bio_PrivateKey.3]=man3/PEM_read_bio_PrivateKey.pod +GENERATE[man/man3/PEM_read_bio_PrivateKey.3]=man3/PEM_read_bio_PrivateKey.pod +DEPEND[html/man3/PEM_read_bio_ex.html]=man3/PEM_read_bio_ex.pod +GENERATE[html/man3/PEM_read_bio_ex.html]=man3/PEM_read_bio_ex.pod +DEPEND[man/man3/PEM_read_bio_ex.3]=man3/PEM_read_bio_ex.pod +GENERATE[man/man3/PEM_read_bio_ex.3]=man3/PEM_read_bio_ex.pod +DEPEND[html/man3/PEM_write_bio_CMS_stream.html]=man3/PEM_write_bio_CMS_stream.pod +GENERATE[html/man3/PEM_write_bio_CMS_stream.html]=man3/PEM_write_bio_CMS_stream.pod +DEPEND[man/man3/PEM_write_bio_CMS_stream.3]=man3/PEM_write_bio_CMS_stream.pod +GENERATE[man/man3/PEM_write_bio_CMS_stream.3]=man3/PEM_write_bio_CMS_stream.pod +DEPEND[html/man3/PEM_write_bio_PKCS7_stream.html]=man3/PEM_write_bio_PKCS7_stream.pod +GENERATE[html/man3/PEM_write_bio_PKCS7_stream.html]=man3/PEM_write_bio_PKCS7_stream.pod +DEPEND[man/man3/PEM_write_bio_PKCS7_stream.3]=man3/PEM_write_bio_PKCS7_stream.pod +GENERATE[man/man3/PEM_write_bio_PKCS7_stream.3]=man3/PEM_write_bio_PKCS7_stream.pod +DEPEND[html/man3/PKCS12_PBE_keyivgen.html]=man3/PKCS12_PBE_keyivgen.pod +GENERATE[html/man3/PKCS12_PBE_keyivgen.html]=man3/PKCS12_PBE_keyivgen.pod +DEPEND[man/man3/PKCS12_PBE_keyivgen.3]=man3/PKCS12_PBE_keyivgen.pod +GENERATE[man/man3/PKCS12_PBE_keyivgen.3]=man3/PKCS12_PBE_keyivgen.pod +DEPEND[html/man3/PKCS12_SAFEBAG_create_cert.html]=man3/PKCS12_SAFEBAG_create_cert.pod +GENERATE[html/man3/PKCS12_SAFEBAG_create_cert.html]=man3/PKCS12_SAFEBAG_create_cert.pod +DEPEND[man/man3/PKCS12_SAFEBAG_create_cert.3]=man3/PKCS12_SAFEBAG_create_cert.pod +GENERATE[man/man3/PKCS12_SAFEBAG_create_cert.3]=man3/PKCS12_SAFEBAG_create_cert.pod +DEPEND[html/man3/PKCS12_SAFEBAG_get0_attrs.html]=man3/PKCS12_SAFEBAG_get0_attrs.pod +GENERATE[html/man3/PKCS12_SAFEBAG_get0_attrs.html]=man3/PKCS12_SAFEBAG_get0_attrs.pod +DEPEND[man/man3/PKCS12_SAFEBAG_get0_attrs.3]=man3/PKCS12_SAFEBAG_get0_attrs.pod +GENERATE[man/man3/PKCS12_SAFEBAG_get0_attrs.3]=man3/PKCS12_SAFEBAG_get0_attrs.pod +DEPEND[html/man3/PKCS12_SAFEBAG_get1_cert.html]=man3/PKCS12_SAFEBAG_get1_cert.pod +GENERATE[html/man3/PKCS12_SAFEBAG_get1_cert.html]=man3/PKCS12_SAFEBAG_get1_cert.pod +DEPEND[man/man3/PKCS12_SAFEBAG_get1_cert.3]=man3/PKCS12_SAFEBAG_get1_cert.pod +GENERATE[man/man3/PKCS12_SAFEBAG_get1_cert.3]=man3/PKCS12_SAFEBAG_get1_cert.pod +DEPEND[html/man3/PKCS12_add1_attr_by_NID.html]=man3/PKCS12_add1_attr_by_NID.pod +GENERATE[html/man3/PKCS12_add1_attr_by_NID.html]=man3/PKCS12_add1_attr_by_NID.pod +DEPEND[man/man3/PKCS12_add1_attr_by_NID.3]=man3/PKCS12_add1_attr_by_NID.pod +GENERATE[man/man3/PKCS12_add1_attr_by_NID.3]=man3/PKCS12_add1_attr_by_NID.pod +DEPEND[html/man3/PKCS12_add_CSPName_asc.html]=man3/PKCS12_add_CSPName_asc.pod +GENERATE[html/man3/PKCS12_add_CSPName_asc.html]=man3/PKCS12_add_CSPName_asc.pod +DEPEND[man/man3/PKCS12_add_CSPName_asc.3]=man3/PKCS12_add_CSPName_asc.pod +GENERATE[man/man3/PKCS12_add_CSPName_asc.3]=man3/PKCS12_add_CSPName_asc.pod +DEPEND[html/man3/PKCS12_add_cert.html]=man3/PKCS12_add_cert.pod +GENERATE[html/man3/PKCS12_add_cert.html]=man3/PKCS12_add_cert.pod +DEPEND[man/man3/PKCS12_add_cert.3]=man3/PKCS12_add_cert.pod +GENERATE[man/man3/PKCS12_add_cert.3]=man3/PKCS12_add_cert.pod +DEPEND[html/man3/PKCS12_add_friendlyname_asc.html]=man3/PKCS12_add_friendlyname_asc.pod +GENERATE[html/man3/PKCS12_add_friendlyname_asc.html]=man3/PKCS12_add_friendlyname_asc.pod +DEPEND[man/man3/PKCS12_add_friendlyname_asc.3]=man3/PKCS12_add_friendlyname_asc.pod +GENERATE[man/man3/PKCS12_add_friendlyname_asc.3]=man3/PKCS12_add_friendlyname_asc.pod +DEPEND[html/man3/PKCS12_add_localkeyid.html]=man3/PKCS12_add_localkeyid.pod +GENERATE[html/man3/PKCS12_add_localkeyid.html]=man3/PKCS12_add_localkeyid.pod +DEPEND[man/man3/PKCS12_add_localkeyid.3]=man3/PKCS12_add_localkeyid.pod +GENERATE[man/man3/PKCS12_add_localkeyid.3]=man3/PKCS12_add_localkeyid.pod +DEPEND[html/man3/PKCS12_add_safe.html]=man3/PKCS12_add_safe.pod +GENERATE[html/man3/PKCS12_add_safe.html]=man3/PKCS12_add_safe.pod +DEPEND[man/man3/PKCS12_add_safe.3]=man3/PKCS12_add_safe.pod +GENERATE[man/man3/PKCS12_add_safe.3]=man3/PKCS12_add_safe.pod +DEPEND[html/man3/PKCS12_create.html]=man3/PKCS12_create.pod +GENERATE[html/man3/PKCS12_create.html]=man3/PKCS12_create.pod +DEPEND[man/man3/PKCS12_create.3]=man3/PKCS12_create.pod +GENERATE[man/man3/PKCS12_create.3]=man3/PKCS12_create.pod +DEPEND[html/man3/PKCS12_decrypt_skey.html]=man3/PKCS12_decrypt_skey.pod +GENERATE[html/man3/PKCS12_decrypt_skey.html]=man3/PKCS12_decrypt_skey.pod +DEPEND[man/man3/PKCS12_decrypt_skey.3]=man3/PKCS12_decrypt_skey.pod +GENERATE[man/man3/PKCS12_decrypt_skey.3]=man3/PKCS12_decrypt_skey.pod +DEPEND[html/man3/PKCS12_gen_mac.html]=man3/PKCS12_gen_mac.pod +GENERATE[html/man3/PKCS12_gen_mac.html]=man3/PKCS12_gen_mac.pod +DEPEND[man/man3/PKCS12_gen_mac.3]=man3/PKCS12_gen_mac.pod +GENERATE[man/man3/PKCS12_gen_mac.3]=man3/PKCS12_gen_mac.pod +DEPEND[html/man3/PKCS12_get_friendlyname.html]=man3/PKCS12_get_friendlyname.pod +GENERATE[html/man3/PKCS12_get_friendlyname.html]=man3/PKCS12_get_friendlyname.pod +DEPEND[man/man3/PKCS12_get_friendlyname.3]=man3/PKCS12_get_friendlyname.pod +GENERATE[man/man3/PKCS12_get_friendlyname.3]=man3/PKCS12_get_friendlyname.pod +DEPEND[html/man3/PKCS12_init.html]=man3/PKCS12_init.pod +GENERATE[html/man3/PKCS12_init.html]=man3/PKCS12_init.pod +DEPEND[man/man3/PKCS12_init.3]=man3/PKCS12_init.pod +GENERATE[man/man3/PKCS12_init.3]=man3/PKCS12_init.pod +DEPEND[html/man3/PKCS12_item_decrypt_d2i.html]=man3/PKCS12_item_decrypt_d2i.pod +GENERATE[html/man3/PKCS12_item_decrypt_d2i.html]=man3/PKCS12_item_decrypt_d2i.pod +DEPEND[man/man3/PKCS12_item_decrypt_d2i.3]=man3/PKCS12_item_decrypt_d2i.pod +GENERATE[man/man3/PKCS12_item_decrypt_d2i.3]=man3/PKCS12_item_decrypt_d2i.pod +DEPEND[html/man3/PKCS12_key_gen_utf8_ex.html]=man3/PKCS12_key_gen_utf8_ex.pod +GENERATE[html/man3/PKCS12_key_gen_utf8_ex.html]=man3/PKCS12_key_gen_utf8_ex.pod +DEPEND[man/man3/PKCS12_key_gen_utf8_ex.3]=man3/PKCS12_key_gen_utf8_ex.pod +GENERATE[man/man3/PKCS12_key_gen_utf8_ex.3]=man3/PKCS12_key_gen_utf8_ex.pod +DEPEND[html/man3/PKCS12_newpass.html]=man3/PKCS12_newpass.pod +GENERATE[html/man3/PKCS12_newpass.html]=man3/PKCS12_newpass.pod +DEPEND[man/man3/PKCS12_newpass.3]=man3/PKCS12_newpass.pod +GENERATE[man/man3/PKCS12_newpass.3]=man3/PKCS12_newpass.pod +DEPEND[html/man3/PKCS12_pack_p7encdata.html]=man3/PKCS12_pack_p7encdata.pod +GENERATE[html/man3/PKCS12_pack_p7encdata.html]=man3/PKCS12_pack_p7encdata.pod +DEPEND[man/man3/PKCS12_pack_p7encdata.3]=man3/PKCS12_pack_p7encdata.pod +GENERATE[man/man3/PKCS12_pack_p7encdata.3]=man3/PKCS12_pack_p7encdata.pod +DEPEND[html/man3/PKCS12_parse.html]=man3/PKCS12_parse.pod +GENERATE[html/man3/PKCS12_parse.html]=man3/PKCS12_parse.pod +DEPEND[man/man3/PKCS12_parse.3]=man3/PKCS12_parse.pod +GENERATE[man/man3/PKCS12_parse.3]=man3/PKCS12_parse.pod +DEPEND[html/man3/PKCS5_PBE_keyivgen.html]=man3/PKCS5_PBE_keyivgen.pod +GENERATE[html/man3/PKCS5_PBE_keyivgen.html]=man3/PKCS5_PBE_keyivgen.pod +DEPEND[man/man3/PKCS5_PBE_keyivgen.3]=man3/PKCS5_PBE_keyivgen.pod +GENERATE[man/man3/PKCS5_PBE_keyivgen.3]=man3/PKCS5_PBE_keyivgen.pod +DEPEND[html/man3/PKCS5_PBKDF2_HMAC.html]=man3/PKCS5_PBKDF2_HMAC.pod +GENERATE[html/man3/PKCS5_PBKDF2_HMAC.html]=man3/PKCS5_PBKDF2_HMAC.pod +DEPEND[man/man3/PKCS5_PBKDF2_HMAC.3]=man3/PKCS5_PBKDF2_HMAC.pod +GENERATE[man/man3/PKCS5_PBKDF2_HMAC.3]=man3/PKCS5_PBKDF2_HMAC.pod +DEPEND[html/man3/PKCS7_decrypt.html]=man3/PKCS7_decrypt.pod +GENERATE[html/man3/PKCS7_decrypt.html]=man3/PKCS7_decrypt.pod +DEPEND[man/man3/PKCS7_decrypt.3]=man3/PKCS7_decrypt.pod +GENERATE[man/man3/PKCS7_decrypt.3]=man3/PKCS7_decrypt.pod +DEPEND[html/man3/PKCS7_encrypt.html]=man3/PKCS7_encrypt.pod +GENERATE[html/man3/PKCS7_encrypt.html]=man3/PKCS7_encrypt.pod +DEPEND[man/man3/PKCS7_encrypt.3]=man3/PKCS7_encrypt.pod +GENERATE[man/man3/PKCS7_encrypt.3]=man3/PKCS7_encrypt.pod +DEPEND[html/man3/PKCS7_get_octet_string.html]=man3/PKCS7_get_octet_string.pod +GENERATE[html/man3/PKCS7_get_octet_string.html]=man3/PKCS7_get_octet_string.pod +DEPEND[man/man3/PKCS7_get_octet_string.3]=man3/PKCS7_get_octet_string.pod +GENERATE[man/man3/PKCS7_get_octet_string.3]=man3/PKCS7_get_octet_string.pod +DEPEND[html/man3/PKCS7_sign.html]=man3/PKCS7_sign.pod +GENERATE[html/man3/PKCS7_sign.html]=man3/PKCS7_sign.pod +DEPEND[man/man3/PKCS7_sign.3]=man3/PKCS7_sign.pod +GENERATE[man/man3/PKCS7_sign.3]=man3/PKCS7_sign.pod +DEPEND[html/man3/PKCS7_sign_add_signer.html]=man3/PKCS7_sign_add_signer.pod +GENERATE[html/man3/PKCS7_sign_add_signer.html]=man3/PKCS7_sign_add_signer.pod +DEPEND[man/man3/PKCS7_sign_add_signer.3]=man3/PKCS7_sign_add_signer.pod +GENERATE[man/man3/PKCS7_sign_add_signer.3]=man3/PKCS7_sign_add_signer.pod +DEPEND[html/man3/PKCS7_type_is_other.html]=man3/PKCS7_type_is_other.pod +GENERATE[html/man3/PKCS7_type_is_other.html]=man3/PKCS7_type_is_other.pod +DEPEND[man/man3/PKCS7_type_is_other.3]=man3/PKCS7_type_is_other.pod +GENERATE[man/man3/PKCS7_type_is_other.3]=man3/PKCS7_type_is_other.pod +DEPEND[html/man3/PKCS7_verify.html]=man3/PKCS7_verify.pod +GENERATE[html/man3/PKCS7_verify.html]=man3/PKCS7_verify.pod +DEPEND[man/man3/PKCS7_verify.3]=man3/PKCS7_verify.pod +GENERATE[man/man3/PKCS7_verify.3]=man3/PKCS7_verify.pod +DEPEND[html/man3/PKCS8_encrypt.html]=man3/PKCS8_encrypt.pod +GENERATE[html/man3/PKCS8_encrypt.html]=man3/PKCS8_encrypt.pod +DEPEND[man/man3/PKCS8_encrypt.3]=man3/PKCS8_encrypt.pod +GENERATE[man/man3/PKCS8_encrypt.3]=man3/PKCS8_encrypt.pod +DEPEND[html/man3/PKCS8_pkey_add1_attr.html]=man3/PKCS8_pkey_add1_attr.pod +GENERATE[html/man3/PKCS8_pkey_add1_attr.html]=man3/PKCS8_pkey_add1_attr.pod +DEPEND[man/man3/PKCS8_pkey_add1_attr.3]=man3/PKCS8_pkey_add1_attr.pod +GENERATE[man/man3/PKCS8_pkey_add1_attr.3]=man3/PKCS8_pkey_add1_attr.pod +DEPEND[html/man3/RAND_add.html]=man3/RAND_add.pod +GENERATE[html/man3/RAND_add.html]=man3/RAND_add.pod +DEPEND[man/man3/RAND_add.3]=man3/RAND_add.pod +GENERATE[man/man3/RAND_add.3]=man3/RAND_add.pod +DEPEND[html/man3/RAND_bytes.html]=man3/RAND_bytes.pod +GENERATE[html/man3/RAND_bytes.html]=man3/RAND_bytes.pod +DEPEND[man/man3/RAND_bytes.3]=man3/RAND_bytes.pod +GENERATE[man/man3/RAND_bytes.3]=man3/RAND_bytes.pod +DEPEND[html/man3/RAND_cleanup.html]=man3/RAND_cleanup.pod +GENERATE[html/man3/RAND_cleanup.html]=man3/RAND_cleanup.pod +DEPEND[man/man3/RAND_cleanup.3]=man3/RAND_cleanup.pod +GENERATE[man/man3/RAND_cleanup.3]=man3/RAND_cleanup.pod +DEPEND[html/man3/RAND_egd.html]=man3/RAND_egd.pod +GENERATE[html/man3/RAND_egd.html]=man3/RAND_egd.pod +DEPEND[man/man3/RAND_egd.3]=man3/RAND_egd.pod +GENERATE[man/man3/RAND_egd.3]=man3/RAND_egd.pod +DEPEND[html/man3/RAND_get0_primary.html]=man3/RAND_get0_primary.pod +GENERATE[html/man3/RAND_get0_primary.html]=man3/RAND_get0_primary.pod +DEPEND[man/man3/RAND_get0_primary.3]=man3/RAND_get0_primary.pod +GENERATE[man/man3/RAND_get0_primary.3]=man3/RAND_get0_primary.pod +DEPEND[html/man3/RAND_load_file.html]=man3/RAND_load_file.pod +GENERATE[html/man3/RAND_load_file.html]=man3/RAND_load_file.pod +DEPEND[man/man3/RAND_load_file.3]=man3/RAND_load_file.pod +GENERATE[man/man3/RAND_load_file.3]=man3/RAND_load_file.pod +DEPEND[html/man3/RAND_set_DRBG_type.html]=man3/RAND_set_DRBG_type.pod +GENERATE[html/man3/RAND_set_DRBG_type.html]=man3/RAND_set_DRBG_type.pod +DEPEND[man/man3/RAND_set_DRBG_type.3]=man3/RAND_set_DRBG_type.pod +GENERATE[man/man3/RAND_set_DRBG_type.3]=man3/RAND_set_DRBG_type.pod +DEPEND[html/man3/RAND_set_rand_method.html]=man3/RAND_set_rand_method.pod +GENERATE[html/man3/RAND_set_rand_method.html]=man3/RAND_set_rand_method.pod +DEPEND[man/man3/RAND_set_rand_method.3]=man3/RAND_set_rand_method.pod +GENERATE[man/man3/RAND_set_rand_method.3]=man3/RAND_set_rand_method.pod +DEPEND[html/man3/RC4_set_key.html]=man3/RC4_set_key.pod +GENERATE[html/man3/RC4_set_key.html]=man3/RC4_set_key.pod +DEPEND[man/man3/RC4_set_key.3]=man3/RC4_set_key.pod +GENERATE[man/man3/RC4_set_key.3]=man3/RC4_set_key.pod +DEPEND[html/man3/RIPEMD160_Init.html]=man3/RIPEMD160_Init.pod +GENERATE[html/man3/RIPEMD160_Init.html]=man3/RIPEMD160_Init.pod +DEPEND[man/man3/RIPEMD160_Init.3]=man3/RIPEMD160_Init.pod +GENERATE[man/man3/RIPEMD160_Init.3]=man3/RIPEMD160_Init.pod +DEPEND[html/man3/RSA_blinding_on.html]=man3/RSA_blinding_on.pod +GENERATE[html/man3/RSA_blinding_on.html]=man3/RSA_blinding_on.pod +DEPEND[man/man3/RSA_blinding_on.3]=man3/RSA_blinding_on.pod +GENERATE[man/man3/RSA_blinding_on.3]=man3/RSA_blinding_on.pod +DEPEND[html/man3/RSA_check_key.html]=man3/RSA_check_key.pod +GENERATE[html/man3/RSA_check_key.html]=man3/RSA_check_key.pod +DEPEND[man/man3/RSA_check_key.3]=man3/RSA_check_key.pod +GENERATE[man/man3/RSA_check_key.3]=man3/RSA_check_key.pod +DEPEND[html/man3/RSA_generate_key.html]=man3/RSA_generate_key.pod +GENERATE[html/man3/RSA_generate_key.html]=man3/RSA_generate_key.pod +DEPEND[man/man3/RSA_generate_key.3]=man3/RSA_generate_key.pod +GENERATE[man/man3/RSA_generate_key.3]=man3/RSA_generate_key.pod +DEPEND[html/man3/RSA_get0_key.html]=man3/RSA_get0_key.pod +GENERATE[html/man3/RSA_get0_key.html]=man3/RSA_get0_key.pod +DEPEND[man/man3/RSA_get0_key.3]=man3/RSA_get0_key.pod +GENERATE[man/man3/RSA_get0_key.3]=man3/RSA_get0_key.pod +DEPEND[html/man3/RSA_meth_new.html]=man3/RSA_meth_new.pod +GENERATE[html/man3/RSA_meth_new.html]=man3/RSA_meth_new.pod +DEPEND[man/man3/RSA_meth_new.3]=man3/RSA_meth_new.pod +GENERATE[man/man3/RSA_meth_new.3]=man3/RSA_meth_new.pod +DEPEND[html/man3/RSA_new.html]=man3/RSA_new.pod +GENERATE[html/man3/RSA_new.html]=man3/RSA_new.pod +DEPEND[man/man3/RSA_new.3]=man3/RSA_new.pod +GENERATE[man/man3/RSA_new.3]=man3/RSA_new.pod +DEPEND[html/man3/RSA_padding_add_PKCS1_type_1.html]=man3/RSA_padding_add_PKCS1_type_1.pod +GENERATE[html/man3/RSA_padding_add_PKCS1_type_1.html]=man3/RSA_padding_add_PKCS1_type_1.pod +DEPEND[man/man3/RSA_padding_add_PKCS1_type_1.3]=man3/RSA_padding_add_PKCS1_type_1.pod +GENERATE[man/man3/RSA_padding_add_PKCS1_type_1.3]=man3/RSA_padding_add_PKCS1_type_1.pod +DEPEND[html/man3/RSA_print.html]=man3/RSA_print.pod +GENERATE[html/man3/RSA_print.html]=man3/RSA_print.pod +DEPEND[man/man3/RSA_print.3]=man3/RSA_print.pod +GENERATE[man/man3/RSA_print.3]=man3/RSA_print.pod +DEPEND[html/man3/RSA_private_encrypt.html]=man3/RSA_private_encrypt.pod +GENERATE[html/man3/RSA_private_encrypt.html]=man3/RSA_private_encrypt.pod +DEPEND[man/man3/RSA_private_encrypt.3]=man3/RSA_private_encrypt.pod +GENERATE[man/man3/RSA_private_encrypt.3]=man3/RSA_private_encrypt.pod +DEPEND[html/man3/RSA_public_encrypt.html]=man3/RSA_public_encrypt.pod +GENERATE[html/man3/RSA_public_encrypt.html]=man3/RSA_public_encrypt.pod +DEPEND[man/man3/RSA_public_encrypt.3]=man3/RSA_public_encrypt.pod +GENERATE[man/man3/RSA_public_encrypt.3]=man3/RSA_public_encrypt.pod +DEPEND[html/man3/RSA_set_method.html]=man3/RSA_set_method.pod +GENERATE[html/man3/RSA_set_method.html]=man3/RSA_set_method.pod +DEPEND[man/man3/RSA_set_method.3]=man3/RSA_set_method.pod +GENERATE[man/man3/RSA_set_method.3]=man3/RSA_set_method.pod +DEPEND[html/man3/RSA_sign.html]=man3/RSA_sign.pod +GENERATE[html/man3/RSA_sign.html]=man3/RSA_sign.pod +DEPEND[man/man3/RSA_sign.3]=man3/RSA_sign.pod +GENERATE[man/man3/RSA_sign.3]=man3/RSA_sign.pod +DEPEND[html/man3/RSA_sign_ASN1_OCTET_STRING.html]=man3/RSA_sign_ASN1_OCTET_STRING.pod +GENERATE[html/man3/RSA_sign_ASN1_OCTET_STRING.html]=man3/RSA_sign_ASN1_OCTET_STRING.pod +DEPEND[man/man3/RSA_sign_ASN1_OCTET_STRING.3]=man3/RSA_sign_ASN1_OCTET_STRING.pod +GENERATE[man/man3/RSA_sign_ASN1_OCTET_STRING.3]=man3/RSA_sign_ASN1_OCTET_STRING.pod +DEPEND[html/man3/RSA_size.html]=man3/RSA_size.pod +GENERATE[html/man3/RSA_size.html]=man3/RSA_size.pod +DEPEND[man/man3/RSA_size.3]=man3/RSA_size.pod +GENERATE[man/man3/RSA_size.3]=man3/RSA_size.pod +DEPEND[html/man3/SCT_new.html]=man3/SCT_new.pod +GENERATE[html/man3/SCT_new.html]=man3/SCT_new.pod +DEPEND[man/man3/SCT_new.3]=man3/SCT_new.pod +GENERATE[man/man3/SCT_new.3]=man3/SCT_new.pod +DEPEND[html/man3/SCT_print.html]=man3/SCT_print.pod +GENERATE[html/man3/SCT_print.html]=man3/SCT_print.pod +DEPEND[man/man3/SCT_print.3]=man3/SCT_print.pod +GENERATE[man/man3/SCT_print.3]=man3/SCT_print.pod +DEPEND[html/man3/SCT_validate.html]=man3/SCT_validate.pod +GENERATE[html/man3/SCT_validate.html]=man3/SCT_validate.pod +DEPEND[man/man3/SCT_validate.3]=man3/SCT_validate.pod +GENERATE[man/man3/SCT_validate.3]=man3/SCT_validate.pod +DEPEND[html/man3/SHA256_Init.html]=man3/SHA256_Init.pod +GENERATE[html/man3/SHA256_Init.html]=man3/SHA256_Init.pod +DEPEND[man/man3/SHA256_Init.3]=man3/SHA256_Init.pod +GENERATE[man/man3/SHA256_Init.3]=man3/SHA256_Init.pod +DEPEND[html/man3/SMIME_read_ASN1.html]=man3/SMIME_read_ASN1.pod +GENERATE[html/man3/SMIME_read_ASN1.html]=man3/SMIME_read_ASN1.pod +DEPEND[man/man3/SMIME_read_ASN1.3]=man3/SMIME_read_ASN1.pod +GENERATE[man/man3/SMIME_read_ASN1.3]=man3/SMIME_read_ASN1.pod +DEPEND[html/man3/SMIME_read_CMS.html]=man3/SMIME_read_CMS.pod +GENERATE[html/man3/SMIME_read_CMS.html]=man3/SMIME_read_CMS.pod +DEPEND[man/man3/SMIME_read_CMS.3]=man3/SMIME_read_CMS.pod +GENERATE[man/man3/SMIME_read_CMS.3]=man3/SMIME_read_CMS.pod +DEPEND[html/man3/SMIME_read_PKCS7.html]=man3/SMIME_read_PKCS7.pod +GENERATE[html/man3/SMIME_read_PKCS7.html]=man3/SMIME_read_PKCS7.pod +DEPEND[man/man3/SMIME_read_PKCS7.3]=man3/SMIME_read_PKCS7.pod +GENERATE[man/man3/SMIME_read_PKCS7.3]=man3/SMIME_read_PKCS7.pod +DEPEND[html/man3/SMIME_write_ASN1.html]=man3/SMIME_write_ASN1.pod +GENERATE[html/man3/SMIME_write_ASN1.html]=man3/SMIME_write_ASN1.pod +DEPEND[man/man3/SMIME_write_ASN1.3]=man3/SMIME_write_ASN1.pod +GENERATE[man/man3/SMIME_write_ASN1.3]=man3/SMIME_write_ASN1.pod +DEPEND[html/man3/SMIME_write_CMS.html]=man3/SMIME_write_CMS.pod +GENERATE[html/man3/SMIME_write_CMS.html]=man3/SMIME_write_CMS.pod +DEPEND[man/man3/SMIME_write_CMS.3]=man3/SMIME_write_CMS.pod +GENERATE[man/man3/SMIME_write_CMS.3]=man3/SMIME_write_CMS.pod +DEPEND[html/man3/SMIME_write_PKCS7.html]=man3/SMIME_write_PKCS7.pod +GENERATE[html/man3/SMIME_write_PKCS7.html]=man3/SMIME_write_PKCS7.pod +DEPEND[man/man3/SMIME_write_PKCS7.3]=man3/SMIME_write_PKCS7.pod +GENERATE[man/man3/SMIME_write_PKCS7.3]=man3/SMIME_write_PKCS7.pod +DEPEND[html/man3/SRP_Calc_B.html]=man3/SRP_Calc_B.pod +GENERATE[html/man3/SRP_Calc_B.html]=man3/SRP_Calc_B.pod +DEPEND[man/man3/SRP_Calc_B.3]=man3/SRP_Calc_B.pod +GENERATE[man/man3/SRP_Calc_B.3]=man3/SRP_Calc_B.pod +DEPEND[html/man3/SRP_VBASE_new.html]=man3/SRP_VBASE_new.pod +GENERATE[html/man3/SRP_VBASE_new.html]=man3/SRP_VBASE_new.pod +DEPEND[man/man3/SRP_VBASE_new.3]=man3/SRP_VBASE_new.pod +GENERATE[man/man3/SRP_VBASE_new.3]=man3/SRP_VBASE_new.pod +DEPEND[html/man3/SRP_create_verifier.html]=man3/SRP_create_verifier.pod +GENERATE[html/man3/SRP_create_verifier.html]=man3/SRP_create_verifier.pod +DEPEND[man/man3/SRP_create_verifier.3]=man3/SRP_create_verifier.pod +GENERATE[man/man3/SRP_create_verifier.3]=man3/SRP_create_verifier.pod +DEPEND[html/man3/SRP_user_pwd_new.html]=man3/SRP_user_pwd_new.pod +GENERATE[html/man3/SRP_user_pwd_new.html]=man3/SRP_user_pwd_new.pod +DEPEND[man/man3/SRP_user_pwd_new.3]=man3/SRP_user_pwd_new.pod +GENERATE[man/man3/SRP_user_pwd_new.3]=man3/SRP_user_pwd_new.pod +DEPEND[html/man3/SSL_CIPHER_get_name.html]=man3/SSL_CIPHER_get_name.pod +GENERATE[html/man3/SSL_CIPHER_get_name.html]=man3/SSL_CIPHER_get_name.pod +DEPEND[man/man3/SSL_CIPHER_get_name.3]=man3/SSL_CIPHER_get_name.pod +GENERATE[man/man3/SSL_CIPHER_get_name.3]=man3/SSL_CIPHER_get_name.pod +DEPEND[html/man3/SSL_COMP_add_compression_method.html]=man3/SSL_COMP_add_compression_method.pod +GENERATE[html/man3/SSL_COMP_add_compression_method.html]=man3/SSL_COMP_add_compression_method.pod +DEPEND[man/man3/SSL_COMP_add_compression_method.3]=man3/SSL_COMP_add_compression_method.pod +GENERATE[man/man3/SSL_COMP_add_compression_method.3]=man3/SSL_COMP_add_compression_method.pod +DEPEND[html/man3/SSL_CONF_CTX_new.html]=man3/SSL_CONF_CTX_new.pod +GENERATE[html/man3/SSL_CONF_CTX_new.html]=man3/SSL_CONF_CTX_new.pod +DEPEND[man/man3/SSL_CONF_CTX_new.3]=man3/SSL_CONF_CTX_new.pod +GENERATE[man/man3/SSL_CONF_CTX_new.3]=man3/SSL_CONF_CTX_new.pod +DEPEND[html/man3/SSL_CONF_CTX_set1_prefix.html]=man3/SSL_CONF_CTX_set1_prefix.pod +GENERATE[html/man3/SSL_CONF_CTX_set1_prefix.html]=man3/SSL_CONF_CTX_set1_prefix.pod +DEPEND[man/man3/SSL_CONF_CTX_set1_prefix.3]=man3/SSL_CONF_CTX_set1_prefix.pod +GENERATE[man/man3/SSL_CONF_CTX_set1_prefix.3]=man3/SSL_CONF_CTX_set1_prefix.pod +DEPEND[html/man3/SSL_CONF_CTX_set_flags.html]=man3/SSL_CONF_CTX_set_flags.pod +GENERATE[html/man3/SSL_CONF_CTX_set_flags.html]=man3/SSL_CONF_CTX_set_flags.pod +DEPEND[man/man3/SSL_CONF_CTX_set_flags.3]=man3/SSL_CONF_CTX_set_flags.pod +GENERATE[man/man3/SSL_CONF_CTX_set_flags.3]=man3/SSL_CONF_CTX_set_flags.pod +DEPEND[html/man3/SSL_CONF_CTX_set_ssl_ctx.html]=man3/SSL_CONF_CTX_set_ssl_ctx.pod +GENERATE[html/man3/SSL_CONF_CTX_set_ssl_ctx.html]=man3/SSL_CONF_CTX_set_ssl_ctx.pod +DEPEND[man/man3/SSL_CONF_CTX_set_ssl_ctx.3]=man3/SSL_CONF_CTX_set_ssl_ctx.pod +GENERATE[man/man3/SSL_CONF_CTX_set_ssl_ctx.3]=man3/SSL_CONF_CTX_set_ssl_ctx.pod +DEPEND[html/man3/SSL_CONF_cmd.html]=man3/SSL_CONF_cmd.pod +GENERATE[html/man3/SSL_CONF_cmd.html]=man3/SSL_CONF_cmd.pod +DEPEND[man/man3/SSL_CONF_cmd.3]=man3/SSL_CONF_cmd.pod +GENERATE[man/man3/SSL_CONF_cmd.3]=man3/SSL_CONF_cmd.pod +DEPEND[html/man3/SSL_CONF_cmd_argv.html]=man3/SSL_CONF_cmd_argv.pod +GENERATE[html/man3/SSL_CONF_cmd_argv.html]=man3/SSL_CONF_cmd_argv.pod +DEPEND[man/man3/SSL_CONF_cmd_argv.3]=man3/SSL_CONF_cmd_argv.pod +GENERATE[man/man3/SSL_CONF_cmd_argv.3]=man3/SSL_CONF_cmd_argv.pod +DEPEND[html/man3/SSL_CTX_add1_chain_cert.html]=man3/SSL_CTX_add1_chain_cert.pod +GENERATE[html/man3/SSL_CTX_add1_chain_cert.html]=man3/SSL_CTX_add1_chain_cert.pod +DEPEND[man/man3/SSL_CTX_add1_chain_cert.3]=man3/SSL_CTX_add1_chain_cert.pod +GENERATE[man/man3/SSL_CTX_add1_chain_cert.3]=man3/SSL_CTX_add1_chain_cert.pod +DEPEND[html/man3/SSL_CTX_add_extra_chain_cert.html]=man3/SSL_CTX_add_extra_chain_cert.pod +GENERATE[html/man3/SSL_CTX_add_extra_chain_cert.html]=man3/SSL_CTX_add_extra_chain_cert.pod +DEPEND[man/man3/SSL_CTX_add_extra_chain_cert.3]=man3/SSL_CTX_add_extra_chain_cert.pod +GENERATE[man/man3/SSL_CTX_add_extra_chain_cert.3]=man3/SSL_CTX_add_extra_chain_cert.pod +DEPEND[html/man3/SSL_CTX_add_session.html]=man3/SSL_CTX_add_session.pod +GENERATE[html/man3/SSL_CTX_add_session.html]=man3/SSL_CTX_add_session.pod +DEPEND[man/man3/SSL_CTX_add_session.3]=man3/SSL_CTX_add_session.pod +GENERATE[man/man3/SSL_CTX_add_session.3]=man3/SSL_CTX_add_session.pod +DEPEND[html/man3/SSL_CTX_config.html]=man3/SSL_CTX_config.pod +GENERATE[html/man3/SSL_CTX_config.html]=man3/SSL_CTX_config.pod +DEPEND[man/man3/SSL_CTX_config.3]=man3/SSL_CTX_config.pod +GENERATE[man/man3/SSL_CTX_config.3]=man3/SSL_CTX_config.pod +DEPEND[html/man3/SSL_CTX_ctrl.html]=man3/SSL_CTX_ctrl.pod +GENERATE[html/man3/SSL_CTX_ctrl.html]=man3/SSL_CTX_ctrl.pod +DEPEND[man/man3/SSL_CTX_ctrl.3]=man3/SSL_CTX_ctrl.pod +GENERATE[man/man3/SSL_CTX_ctrl.3]=man3/SSL_CTX_ctrl.pod +DEPEND[html/man3/SSL_CTX_dane_enable.html]=man3/SSL_CTX_dane_enable.pod +GENERATE[html/man3/SSL_CTX_dane_enable.html]=man3/SSL_CTX_dane_enable.pod +DEPEND[man/man3/SSL_CTX_dane_enable.3]=man3/SSL_CTX_dane_enable.pod +GENERATE[man/man3/SSL_CTX_dane_enable.3]=man3/SSL_CTX_dane_enable.pod +DEPEND[html/man3/SSL_CTX_flush_sessions.html]=man3/SSL_CTX_flush_sessions.pod +GENERATE[html/man3/SSL_CTX_flush_sessions.html]=man3/SSL_CTX_flush_sessions.pod +DEPEND[man/man3/SSL_CTX_flush_sessions.3]=man3/SSL_CTX_flush_sessions.pod +GENERATE[man/man3/SSL_CTX_flush_sessions.3]=man3/SSL_CTX_flush_sessions.pod +DEPEND[html/man3/SSL_CTX_free.html]=man3/SSL_CTX_free.pod +GENERATE[html/man3/SSL_CTX_free.html]=man3/SSL_CTX_free.pod +DEPEND[man/man3/SSL_CTX_free.3]=man3/SSL_CTX_free.pod +GENERATE[man/man3/SSL_CTX_free.3]=man3/SSL_CTX_free.pod +DEPEND[html/man3/SSL_CTX_get0_param.html]=man3/SSL_CTX_get0_param.pod +GENERATE[html/man3/SSL_CTX_get0_param.html]=man3/SSL_CTX_get0_param.pod +DEPEND[man/man3/SSL_CTX_get0_param.3]=man3/SSL_CTX_get0_param.pod +GENERATE[man/man3/SSL_CTX_get0_param.3]=man3/SSL_CTX_get0_param.pod +DEPEND[html/man3/SSL_CTX_get_verify_mode.html]=man3/SSL_CTX_get_verify_mode.pod +GENERATE[html/man3/SSL_CTX_get_verify_mode.html]=man3/SSL_CTX_get_verify_mode.pod +DEPEND[man/man3/SSL_CTX_get_verify_mode.3]=man3/SSL_CTX_get_verify_mode.pod +GENERATE[man/man3/SSL_CTX_get_verify_mode.3]=man3/SSL_CTX_get_verify_mode.pod +DEPEND[html/man3/SSL_CTX_has_client_custom_ext.html]=man3/SSL_CTX_has_client_custom_ext.pod +GENERATE[html/man3/SSL_CTX_has_client_custom_ext.html]=man3/SSL_CTX_has_client_custom_ext.pod +DEPEND[man/man3/SSL_CTX_has_client_custom_ext.3]=man3/SSL_CTX_has_client_custom_ext.pod +GENERATE[man/man3/SSL_CTX_has_client_custom_ext.3]=man3/SSL_CTX_has_client_custom_ext.pod +DEPEND[html/man3/SSL_CTX_load_verify_locations.html]=man3/SSL_CTX_load_verify_locations.pod +GENERATE[html/man3/SSL_CTX_load_verify_locations.html]=man3/SSL_CTX_load_verify_locations.pod +DEPEND[man/man3/SSL_CTX_load_verify_locations.3]=man3/SSL_CTX_load_verify_locations.pod +GENERATE[man/man3/SSL_CTX_load_verify_locations.3]=man3/SSL_CTX_load_verify_locations.pod +DEPEND[html/man3/SSL_CTX_new.html]=man3/SSL_CTX_new.pod +GENERATE[html/man3/SSL_CTX_new.html]=man3/SSL_CTX_new.pod +DEPEND[man/man3/SSL_CTX_new.3]=man3/SSL_CTX_new.pod +GENERATE[man/man3/SSL_CTX_new.3]=man3/SSL_CTX_new.pod +DEPEND[html/man3/SSL_CTX_sess_number.html]=man3/SSL_CTX_sess_number.pod +GENERATE[html/man3/SSL_CTX_sess_number.html]=man3/SSL_CTX_sess_number.pod +DEPEND[man/man3/SSL_CTX_sess_number.3]=man3/SSL_CTX_sess_number.pod +GENERATE[man/man3/SSL_CTX_sess_number.3]=man3/SSL_CTX_sess_number.pod +DEPEND[html/man3/SSL_CTX_sess_set_cache_size.html]=man3/SSL_CTX_sess_set_cache_size.pod +GENERATE[html/man3/SSL_CTX_sess_set_cache_size.html]=man3/SSL_CTX_sess_set_cache_size.pod +DEPEND[man/man3/SSL_CTX_sess_set_cache_size.3]=man3/SSL_CTX_sess_set_cache_size.pod +GENERATE[man/man3/SSL_CTX_sess_set_cache_size.3]=man3/SSL_CTX_sess_set_cache_size.pod +DEPEND[html/man3/SSL_CTX_sess_set_get_cb.html]=man3/SSL_CTX_sess_set_get_cb.pod +GENERATE[html/man3/SSL_CTX_sess_set_get_cb.html]=man3/SSL_CTX_sess_set_get_cb.pod +DEPEND[man/man3/SSL_CTX_sess_set_get_cb.3]=man3/SSL_CTX_sess_set_get_cb.pod +GENERATE[man/man3/SSL_CTX_sess_set_get_cb.3]=man3/SSL_CTX_sess_set_get_cb.pod +DEPEND[html/man3/SSL_CTX_sessions.html]=man3/SSL_CTX_sessions.pod +GENERATE[html/man3/SSL_CTX_sessions.html]=man3/SSL_CTX_sessions.pod +DEPEND[man/man3/SSL_CTX_sessions.3]=man3/SSL_CTX_sessions.pod +GENERATE[man/man3/SSL_CTX_sessions.3]=man3/SSL_CTX_sessions.pod +DEPEND[html/man3/SSL_CTX_set0_CA_list.html]=man3/SSL_CTX_set0_CA_list.pod +GENERATE[html/man3/SSL_CTX_set0_CA_list.html]=man3/SSL_CTX_set0_CA_list.pod +DEPEND[man/man3/SSL_CTX_set0_CA_list.3]=man3/SSL_CTX_set0_CA_list.pod +GENERATE[man/man3/SSL_CTX_set0_CA_list.3]=man3/SSL_CTX_set0_CA_list.pod +DEPEND[html/man3/SSL_CTX_set1_curves.html]=man3/SSL_CTX_set1_curves.pod +GENERATE[html/man3/SSL_CTX_set1_curves.html]=man3/SSL_CTX_set1_curves.pod +DEPEND[man/man3/SSL_CTX_set1_curves.3]=man3/SSL_CTX_set1_curves.pod +GENERATE[man/man3/SSL_CTX_set1_curves.3]=man3/SSL_CTX_set1_curves.pod +DEPEND[html/man3/SSL_CTX_set1_sigalgs.html]=man3/SSL_CTX_set1_sigalgs.pod +GENERATE[html/man3/SSL_CTX_set1_sigalgs.html]=man3/SSL_CTX_set1_sigalgs.pod +DEPEND[man/man3/SSL_CTX_set1_sigalgs.3]=man3/SSL_CTX_set1_sigalgs.pod +GENERATE[man/man3/SSL_CTX_set1_sigalgs.3]=man3/SSL_CTX_set1_sigalgs.pod +DEPEND[html/man3/SSL_CTX_set1_verify_cert_store.html]=man3/SSL_CTX_set1_verify_cert_store.pod +GENERATE[html/man3/SSL_CTX_set1_verify_cert_store.html]=man3/SSL_CTX_set1_verify_cert_store.pod +DEPEND[man/man3/SSL_CTX_set1_verify_cert_store.3]=man3/SSL_CTX_set1_verify_cert_store.pod +GENERATE[man/man3/SSL_CTX_set1_verify_cert_store.3]=man3/SSL_CTX_set1_verify_cert_store.pod +DEPEND[html/man3/SSL_CTX_set_alpn_select_cb.html]=man3/SSL_CTX_set_alpn_select_cb.pod +GENERATE[html/man3/SSL_CTX_set_alpn_select_cb.html]=man3/SSL_CTX_set_alpn_select_cb.pod +DEPEND[man/man3/SSL_CTX_set_alpn_select_cb.3]=man3/SSL_CTX_set_alpn_select_cb.pod +GENERATE[man/man3/SSL_CTX_set_alpn_select_cb.3]=man3/SSL_CTX_set_alpn_select_cb.pod +DEPEND[html/man3/SSL_CTX_set_cert_cb.html]=man3/SSL_CTX_set_cert_cb.pod +GENERATE[html/man3/SSL_CTX_set_cert_cb.html]=man3/SSL_CTX_set_cert_cb.pod +DEPEND[man/man3/SSL_CTX_set_cert_cb.3]=man3/SSL_CTX_set_cert_cb.pod +GENERATE[man/man3/SSL_CTX_set_cert_cb.3]=man3/SSL_CTX_set_cert_cb.pod +DEPEND[html/man3/SSL_CTX_set_cert_store.html]=man3/SSL_CTX_set_cert_store.pod +GENERATE[html/man3/SSL_CTX_set_cert_store.html]=man3/SSL_CTX_set_cert_store.pod +DEPEND[man/man3/SSL_CTX_set_cert_store.3]=man3/SSL_CTX_set_cert_store.pod +GENERATE[man/man3/SSL_CTX_set_cert_store.3]=man3/SSL_CTX_set_cert_store.pod +DEPEND[html/man3/SSL_CTX_set_cert_verify_callback.html]=man3/SSL_CTX_set_cert_verify_callback.pod +GENERATE[html/man3/SSL_CTX_set_cert_verify_callback.html]=man3/SSL_CTX_set_cert_verify_callback.pod +DEPEND[man/man3/SSL_CTX_set_cert_verify_callback.3]=man3/SSL_CTX_set_cert_verify_callback.pod +GENERATE[man/man3/SSL_CTX_set_cert_verify_callback.3]=man3/SSL_CTX_set_cert_verify_callback.pod +DEPEND[html/man3/SSL_CTX_set_cipher_list.html]=man3/SSL_CTX_set_cipher_list.pod +GENERATE[html/man3/SSL_CTX_set_cipher_list.html]=man3/SSL_CTX_set_cipher_list.pod +DEPEND[man/man3/SSL_CTX_set_cipher_list.3]=man3/SSL_CTX_set_cipher_list.pod +GENERATE[man/man3/SSL_CTX_set_cipher_list.3]=man3/SSL_CTX_set_cipher_list.pod +DEPEND[html/man3/SSL_CTX_set_client_cert_cb.html]=man3/SSL_CTX_set_client_cert_cb.pod +GENERATE[html/man3/SSL_CTX_set_client_cert_cb.html]=man3/SSL_CTX_set_client_cert_cb.pod +DEPEND[man/man3/SSL_CTX_set_client_cert_cb.3]=man3/SSL_CTX_set_client_cert_cb.pod +GENERATE[man/man3/SSL_CTX_set_client_cert_cb.3]=man3/SSL_CTX_set_client_cert_cb.pod +DEPEND[html/man3/SSL_CTX_set_client_hello_cb.html]=man3/SSL_CTX_set_client_hello_cb.pod +GENERATE[html/man3/SSL_CTX_set_client_hello_cb.html]=man3/SSL_CTX_set_client_hello_cb.pod +DEPEND[man/man3/SSL_CTX_set_client_hello_cb.3]=man3/SSL_CTX_set_client_hello_cb.pod +GENERATE[man/man3/SSL_CTX_set_client_hello_cb.3]=man3/SSL_CTX_set_client_hello_cb.pod +DEPEND[html/man3/SSL_CTX_set_ct_validation_callback.html]=man3/SSL_CTX_set_ct_validation_callback.pod +GENERATE[html/man3/SSL_CTX_set_ct_validation_callback.html]=man3/SSL_CTX_set_ct_validation_callback.pod +DEPEND[man/man3/SSL_CTX_set_ct_validation_callback.3]=man3/SSL_CTX_set_ct_validation_callback.pod +GENERATE[man/man3/SSL_CTX_set_ct_validation_callback.3]=man3/SSL_CTX_set_ct_validation_callback.pod +DEPEND[html/man3/SSL_CTX_set_ctlog_list_file.html]=man3/SSL_CTX_set_ctlog_list_file.pod +GENERATE[html/man3/SSL_CTX_set_ctlog_list_file.html]=man3/SSL_CTX_set_ctlog_list_file.pod +DEPEND[man/man3/SSL_CTX_set_ctlog_list_file.3]=man3/SSL_CTX_set_ctlog_list_file.pod +GENERATE[man/man3/SSL_CTX_set_ctlog_list_file.3]=man3/SSL_CTX_set_ctlog_list_file.pod +DEPEND[html/man3/SSL_CTX_set_default_passwd_cb.html]=man3/SSL_CTX_set_default_passwd_cb.pod +GENERATE[html/man3/SSL_CTX_set_default_passwd_cb.html]=man3/SSL_CTX_set_default_passwd_cb.pod +DEPEND[man/man3/SSL_CTX_set_default_passwd_cb.3]=man3/SSL_CTX_set_default_passwd_cb.pod +GENERATE[man/man3/SSL_CTX_set_default_passwd_cb.3]=man3/SSL_CTX_set_default_passwd_cb.pod +DEPEND[html/man3/SSL_CTX_set_generate_session_id.html]=man3/SSL_CTX_set_generate_session_id.pod +GENERATE[html/man3/SSL_CTX_set_generate_session_id.html]=man3/SSL_CTX_set_generate_session_id.pod +DEPEND[man/man3/SSL_CTX_set_generate_session_id.3]=man3/SSL_CTX_set_generate_session_id.pod +GENERATE[man/man3/SSL_CTX_set_generate_session_id.3]=man3/SSL_CTX_set_generate_session_id.pod +DEPEND[html/man3/SSL_CTX_set_info_callback.html]=man3/SSL_CTX_set_info_callback.pod +GENERATE[html/man3/SSL_CTX_set_info_callback.html]=man3/SSL_CTX_set_info_callback.pod +DEPEND[man/man3/SSL_CTX_set_info_callback.3]=man3/SSL_CTX_set_info_callback.pod +GENERATE[man/man3/SSL_CTX_set_info_callback.3]=man3/SSL_CTX_set_info_callback.pod +DEPEND[html/man3/SSL_CTX_set_keylog_callback.html]=man3/SSL_CTX_set_keylog_callback.pod +GENERATE[html/man3/SSL_CTX_set_keylog_callback.html]=man3/SSL_CTX_set_keylog_callback.pod +DEPEND[man/man3/SSL_CTX_set_keylog_callback.3]=man3/SSL_CTX_set_keylog_callback.pod +GENERATE[man/man3/SSL_CTX_set_keylog_callback.3]=man3/SSL_CTX_set_keylog_callback.pod +DEPEND[html/man3/SSL_CTX_set_max_cert_list.html]=man3/SSL_CTX_set_max_cert_list.pod +GENERATE[html/man3/SSL_CTX_set_max_cert_list.html]=man3/SSL_CTX_set_max_cert_list.pod +DEPEND[man/man3/SSL_CTX_set_max_cert_list.3]=man3/SSL_CTX_set_max_cert_list.pod +GENERATE[man/man3/SSL_CTX_set_max_cert_list.3]=man3/SSL_CTX_set_max_cert_list.pod +DEPEND[html/man3/SSL_CTX_set_min_proto_version.html]=man3/SSL_CTX_set_min_proto_version.pod +GENERATE[html/man3/SSL_CTX_set_min_proto_version.html]=man3/SSL_CTX_set_min_proto_version.pod +DEPEND[man/man3/SSL_CTX_set_min_proto_version.3]=man3/SSL_CTX_set_min_proto_version.pod +GENERATE[man/man3/SSL_CTX_set_min_proto_version.3]=man3/SSL_CTX_set_min_proto_version.pod +DEPEND[html/man3/SSL_CTX_set_mode.html]=man3/SSL_CTX_set_mode.pod +GENERATE[html/man3/SSL_CTX_set_mode.html]=man3/SSL_CTX_set_mode.pod +DEPEND[man/man3/SSL_CTX_set_mode.3]=man3/SSL_CTX_set_mode.pod +GENERATE[man/man3/SSL_CTX_set_mode.3]=man3/SSL_CTX_set_mode.pod +DEPEND[html/man3/SSL_CTX_set_msg_callback.html]=man3/SSL_CTX_set_msg_callback.pod +GENERATE[html/man3/SSL_CTX_set_msg_callback.html]=man3/SSL_CTX_set_msg_callback.pod +DEPEND[man/man3/SSL_CTX_set_msg_callback.3]=man3/SSL_CTX_set_msg_callback.pod +GENERATE[man/man3/SSL_CTX_set_msg_callback.3]=man3/SSL_CTX_set_msg_callback.pod +DEPEND[html/man3/SSL_CTX_set_num_tickets.html]=man3/SSL_CTX_set_num_tickets.pod +GENERATE[html/man3/SSL_CTX_set_num_tickets.html]=man3/SSL_CTX_set_num_tickets.pod +DEPEND[man/man3/SSL_CTX_set_num_tickets.3]=man3/SSL_CTX_set_num_tickets.pod +GENERATE[man/man3/SSL_CTX_set_num_tickets.3]=man3/SSL_CTX_set_num_tickets.pod +DEPEND[html/man3/SSL_CTX_set_options.html]=man3/SSL_CTX_set_options.pod +GENERATE[html/man3/SSL_CTX_set_options.html]=man3/SSL_CTX_set_options.pod +DEPEND[man/man3/SSL_CTX_set_options.3]=man3/SSL_CTX_set_options.pod +GENERATE[man/man3/SSL_CTX_set_options.3]=man3/SSL_CTX_set_options.pod +DEPEND[html/man3/SSL_CTX_set_psk_client_callback.html]=man3/SSL_CTX_set_psk_client_callback.pod +GENERATE[html/man3/SSL_CTX_set_psk_client_callback.html]=man3/SSL_CTX_set_psk_client_callback.pod +DEPEND[man/man3/SSL_CTX_set_psk_client_callback.3]=man3/SSL_CTX_set_psk_client_callback.pod +GENERATE[man/man3/SSL_CTX_set_psk_client_callback.3]=man3/SSL_CTX_set_psk_client_callback.pod +DEPEND[html/man3/SSL_CTX_set_quiet_shutdown.html]=man3/SSL_CTX_set_quiet_shutdown.pod +GENERATE[html/man3/SSL_CTX_set_quiet_shutdown.html]=man3/SSL_CTX_set_quiet_shutdown.pod +DEPEND[man/man3/SSL_CTX_set_quiet_shutdown.3]=man3/SSL_CTX_set_quiet_shutdown.pod +GENERATE[man/man3/SSL_CTX_set_quiet_shutdown.3]=man3/SSL_CTX_set_quiet_shutdown.pod +DEPEND[html/man3/SSL_CTX_set_read_ahead.html]=man3/SSL_CTX_set_read_ahead.pod +GENERATE[html/man3/SSL_CTX_set_read_ahead.html]=man3/SSL_CTX_set_read_ahead.pod +DEPEND[man/man3/SSL_CTX_set_read_ahead.3]=man3/SSL_CTX_set_read_ahead.pod +GENERATE[man/man3/SSL_CTX_set_read_ahead.3]=man3/SSL_CTX_set_read_ahead.pod +DEPEND[html/man3/SSL_CTX_set_record_padding_callback.html]=man3/SSL_CTX_set_record_padding_callback.pod +GENERATE[html/man3/SSL_CTX_set_record_padding_callback.html]=man3/SSL_CTX_set_record_padding_callback.pod +DEPEND[man/man3/SSL_CTX_set_record_padding_callback.3]=man3/SSL_CTX_set_record_padding_callback.pod +GENERATE[man/man3/SSL_CTX_set_record_padding_callback.3]=man3/SSL_CTX_set_record_padding_callback.pod +DEPEND[html/man3/SSL_CTX_set_security_level.html]=man3/SSL_CTX_set_security_level.pod +GENERATE[html/man3/SSL_CTX_set_security_level.html]=man3/SSL_CTX_set_security_level.pod +DEPEND[man/man3/SSL_CTX_set_security_level.3]=man3/SSL_CTX_set_security_level.pod +GENERATE[man/man3/SSL_CTX_set_security_level.3]=man3/SSL_CTX_set_security_level.pod +DEPEND[html/man3/SSL_CTX_set_session_cache_mode.html]=man3/SSL_CTX_set_session_cache_mode.pod +GENERATE[html/man3/SSL_CTX_set_session_cache_mode.html]=man3/SSL_CTX_set_session_cache_mode.pod +DEPEND[man/man3/SSL_CTX_set_session_cache_mode.3]=man3/SSL_CTX_set_session_cache_mode.pod +GENERATE[man/man3/SSL_CTX_set_session_cache_mode.3]=man3/SSL_CTX_set_session_cache_mode.pod +DEPEND[html/man3/SSL_CTX_set_session_id_context.html]=man3/SSL_CTX_set_session_id_context.pod +GENERATE[html/man3/SSL_CTX_set_session_id_context.html]=man3/SSL_CTX_set_session_id_context.pod +DEPEND[man/man3/SSL_CTX_set_session_id_context.3]=man3/SSL_CTX_set_session_id_context.pod +GENERATE[man/man3/SSL_CTX_set_session_id_context.3]=man3/SSL_CTX_set_session_id_context.pod +DEPEND[html/man3/SSL_CTX_set_session_ticket_cb.html]=man3/SSL_CTX_set_session_ticket_cb.pod +GENERATE[html/man3/SSL_CTX_set_session_ticket_cb.html]=man3/SSL_CTX_set_session_ticket_cb.pod +DEPEND[man/man3/SSL_CTX_set_session_ticket_cb.3]=man3/SSL_CTX_set_session_ticket_cb.pod +GENERATE[man/man3/SSL_CTX_set_session_ticket_cb.3]=man3/SSL_CTX_set_session_ticket_cb.pod +DEPEND[html/man3/SSL_CTX_set_split_send_fragment.html]=man3/SSL_CTX_set_split_send_fragment.pod +GENERATE[html/man3/SSL_CTX_set_split_send_fragment.html]=man3/SSL_CTX_set_split_send_fragment.pod +DEPEND[man/man3/SSL_CTX_set_split_send_fragment.3]=man3/SSL_CTX_set_split_send_fragment.pod +GENERATE[man/man3/SSL_CTX_set_split_send_fragment.3]=man3/SSL_CTX_set_split_send_fragment.pod +DEPEND[html/man3/SSL_CTX_set_srp_password.html]=man3/SSL_CTX_set_srp_password.pod +GENERATE[html/man3/SSL_CTX_set_srp_password.html]=man3/SSL_CTX_set_srp_password.pod +DEPEND[man/man3/SSL_CTX_set_srp_password.3]=man3/SSL_CTX_set_srp_password.pod +GENERATE[man/man3/SSL_CTX_set_srp_password.3]=man3/SSL_CTX_set_srp_password.pod +DEPEND[html/man3/SSL_CTX_set_ssl_version.html]=man3/SSL_CTX_set_ssl_version.pod +GENERATE[html/man3/SSL_CTX_set_ssl_version.html]=man3/SSL_CTX_set_ssl_version.pod +DEPEND[man/man3/SSL_CTX_set_ssl_version.3]=man3/SSL_CTX_set_ssl_version.pod +GENERATE[man/man3/SSL_CTX_set_ssl_version.3]=man3/SSL_CTX_set_ssl_version.pod +DEPEND[html/man3/SSL_CTX_set_stateless_cookie_generate_cb.html]=man3/SSL_CTX_set_stateless_cookie_generate_cb.pod +GENERATE[html/man3/SSL_CTX_set_stateless_cookie_generate_cb.html]=man3/SSL_CTX_set_stateless_cookie_generate_cb.pod +DEPEND[man/man3/SSL_CTX_set_stateless_cookie_generate_cb.3]=man3/SSL_CTX_set_stateless_cookie_generate_cb.pod +GENERATE[man/man3/SSL_CTX_set_stateless_cookie_generate_cb.3]=man3/SSL_CTX_set_stateless_cookie_generate_cb.pod +DEPEND[html/man3/SSL_CTX_set_timeout.html]=man3/SSL_CTX_set_timeout.pod +GENERATE[html/man3/SSL_CTX_set_timeout.html]=man3/SSL_CTX_set_timeout.pod +DEPEND[man/man3/SSL_CTX_set_timeout.3]=man3/SSL_CTX_set_timeout.pod +GENERATE[man/man3/SSL_CTX_set_timeout.3]=man3/SSL_CTX_set_timeout.pod +DEPEND[html/man3/SSL_CTX_set_tlsext_servername_callback.html]=man3/SSL_CTX_set_tlsext_servername_callback.pod +GENERATE[html/man3/SSL_CTX_set_tlsext_servername_callback.html]=man3/SSL_CTX_set_tlsext_servername_callback.pod +DEPEND[man/man3/SSL_CTX_set_tlsext_servername_callback.3]=man3/SSL_CTX_set_tlsext_servername_callback.pod +GENERATE[man/man3/SSL_CTX_set_tlsext_servername_callback.3]=man3/SSL_CTX_set_tlsext_servername_callback.pod +DEPEND[html/man3/SSL_CTX_set_tlsext_status_cb.html]=man3/SSL_CTX_set_tlsext_status_cb.pod +GENERATE[html/man3/SSL_CTX_set_tlsext_status_cb.html]=man3/SSL_CTX_set_tlsext_status_cb.pod +DEPEND[man/man3/SSL_CTX_set_tlsext_status_cb.3]=man3/SSL_CTX_set_tlsext_status_cb.pod +GENERATE[man/man3/SSL_CTX_set_tlsext_status_cb.3]=man3/SSL_CTX_set_tlsext_status_cb.pod +DEPEND[html/man3/SSL_CTX_set_tlsext_ticket_key_cb.html]=man3/SSL_CTX_set_tlsext_ticket_key_cb.pod +GENERATE[html/man3/SSL_CTX_set_tlsext_ticket_key_cb.html]=man3/SSL_CTX_set_tlsext_ticket_key_cb.pod +DEPEND[man/man3/SSL_CTX_set_tlsext_ticket_key_cb.3]=man3/SSL_CTX_set_tlsext_ticket_key_cb.pod +GENERATE[man/man3/SSL_CTX_set_tlsext_ticket_key_cb.3]=man3/SSL_CTX_set_tlsext_ticket_key_cb.pod +DEPEND[html/man3/SSL_CTX_set_tlsext_use_srtp.html]=man3/SSL_CTX_set_tlsext_use_srtp.pod +GENERATE[html/man3/SSL_CTX_set_tlsext_use_srtp.html]=man3/SSL_CTX_set_tlsext_use_srtp.pod +DEPEND[man/man3/SSL_CTX_set_tlsext_use_srtp.3]=man3/SSL_CTX_set_tlsext_use_srtp.pod +GENERATE[man/man3/SSL_CTX_set_tlsext_use_srtp.3]=man3/SSL_CTX_set_tlsext_use_srtp.pod +DEPEND[html/man3/SSL_CTX_set_tmp_dh_callback.html]=man3/SSL_CTX_set_tmp_dh_callback.pod +GENERATE[html/man3/SSL_CTX_set_tmp_dh_callback.html]=man3/SSL_CTX_set_tmp_dh_callback.pod +DEPEND[man/man3/SSL_CTX_set_tmp_dh_callback.3]=man3/SSL_CTX_set_tmp_dh_callback.pod +GENERATE[man/man3/SSL_CTX_set_tmp_dh_callback.3]=man3/SSL_CTX_set_tmp_dh_callback.pod +DEPEND[html/man3/SSL_CTX_set_tmp_ecdh.html]=man3/SSL_CTX_set_tmp_ecdh.pod +GENERATE[html/man3/SSL_CTX_set_tmp_ecdh.html]=man3/SSL_CTX_set_tmp_ecdh.pod +DEPEND[man/man3/SSL_CTX_set_tmp_ecdh.3]=man3/SSL_CTX_set_tmp_ecdh.pod +GENERATE[man/man3/SSL_CTX_set_tmp_ecdh.3]=man3/SSL_CTX_set_tmp_ecdh.pod +DEPEND[html/man3/SSL_CTX_set_verify.html]=man3/SSL_CTX_set_verify.pod +GENERATE[html/man3/SSL_CTX_set_verify.html]=man3/SSL_CTX_set_verify.pod +DEPEND[man/man3/SSL_CTX_set_verify.3]=man3/SSL_CTX_set_verify.pod +GENERATE[man/man3/SSL_CTX_set_verify.3]=man3/SSL_CTX_set_verify.pod +DEPEND[html/man3/SSL_CTX_use_certificate.html]=man3/SSL_CTX_use_certificate.pod +GENERATE[html/man3/SSL_CTX_use_certificate.html]=man3/SSL_CTX_use_certificate.pod +DEPEND[man/man3/SSL_CTX_use_certificate.3]=man3/SSL_CTX_use_certificate.pod +GENERATE[man/man3/SSL_CTX_use_certificate.3]=man3/SSL_CTX_use_certificate.pod +DEPEND[html/man3/SSL_CTX_use_psk_identity_hint.html]=man3/SSL_CTX_use_psk_identity_hint.pod +GENERATE[html/man3/SSL_CTX_use_psk_identity_hint.html]=man3/SSL_CTX_use_psk_identity_hint.pod +DEPEND[man/man3/SSL_CTX_use_psk_identity_hint.3]=man3/SSL_CTX_use_psk_identity_hint.pod +GENERATE[man/man3/SSL_CTX_use_psk_identity_hint.3]=man3/SSL_CTX_use_psk_identity_hint.pod +DEPEND[html/man3/SSL_CTX_use_serverinfo.html]=man3/SSL_CTX_use_serverinfo.pod +GENERATE[html/man3/SSL_CTX_use_serverinfo.html]=man3/SSL_CTX_use_serverinfo.pod +DEPEND[man/man3/SSL_CTX_use_serverinfo.3]=man3/SSL_CTX_use_serverinfo.pod +GENERATE[man/man3/SSL_CTX_use_serverinfo.3]=man3/SSL_CTX_use_serverinfo.pod +DEPEND[html/man3/SSL_SESSION_free.html]=man3/SSL_SESSION_free.pod +GENERATE[html/man3/SSL_SESSION_free.html]=man3/SSL_SESSION_free.pod +DEPEND[man/man3/SSL_SESSION_free.3]=man3/SSL_SESSION_free.pod +GENERATE[man/man3/SSL_SESSION_free.3]=man3/SSL_SESSION_free.pod +DEPEND[html/man3/SSL_SESSION_get0_cipher.html]=man3/SSL_SESSION_get0_cipher.pod +GENERATE[html/man3/SSL_SESSION_get0_cipher.html]=man3/SSL_SESSION_get0_cipher.pod +DEPEND[man/man3/SSL_SESSION_get0_cipher.3]=man3/SSL_SESSION_get0_cipher.pod +GENERATE[man/man3/SSL_SESSION_get0_cipher.3]=man3/SSL_SESSION_get0_cipher.pod +DEPEND[html/man3/SSL_SESSION_get0_hostname.html]=man3/SSL_SESSION_get0_hostname.pod +GENERATE[html/man3/SSL_SESSION_get0_hostname.html]=man3/SSL_SESSION_get0_hostname.pod +DEPEND[man/man3/SSL_SESSION_get0_hostname.3]=man3/SSL_SESSION_get0_hostname.pod +GENERATE[man/man3/SSL_SESSION_get0_hostname.3]=man3/SSL_SESSION_get0_hostname.pod +DEPEND[html/man3/SSL_SESSION_get0_id_context.html]=man3/SSL_SESSION_get0_id_context.pod +GENERATE[html/man3/SSL_SESSION_get0_id_context.html]=man3/SSL_SESSION_get0_id_context.pod +DEPEND[man/man3/SSL_SESSION_get0_id_context.3]=man3/SSL_SESSION_get0_id_context.pod +GENERATE[man/man3/SSL_SESSION_get0_id_context.3]=man3/SSL_SESSION_get0_id_context.pod +DEPEND[html/man3/SSL_SESSION_get0_peer.html]=man3/SSL_SESSION_get0_peer.pod +GENERATE[html/man3/SSL_SESSION_get0_peer.html]=man3/SSL_SESSION_get0_peer.pod +DEPEND[man/man3/SSL_SESSION_get0_peer.3]=man3/SSL_SESSION_get0_peer.pod +GENERATE[man/man3/SSL_SESSION_get0_peer.3]=man3/SSL_SESSION_get0_peer.pod +DEPEND[html/man3/SSL_SESSION_get_compress_id.html]=man3/SSL_SESSION_get_compress_id.pod +GENERATE[html/man3/SSL_SESSION_get_compress_id.html]=man3/SSL_SESSION_get_compress_id.pod +DEPEND[man/man3/SSL_SESSION_get_compress_id.3]=man3/SSL_SESSION_get_compress_id.pod +GENERATE[man/man3/SSL_SESSION_get_compress_id.3]=man3/SSL_SESSION_get_compress_id.pod +DEPEND[html/man3/SSL_SESSION_get_protocol_version.html]=man3/SSL_SESSION_get_protocol_version.pod +GENERATE[html/man3/SSL_SESSION_get_protocol_version.html]=man3/SSL_SESSION_get_protocol_version.pod +DEPEND[man/man3/SSL_SESSION_get_protocol_version.3]=man3/SSL_SESSION_get_protocol_version.pod +GENERATE[man/man3/SSL_SESSION_get_protocol_version.3]=man3/SSL_SESSION_get_protocol_version.pod +DEPEND[html/man3/SSL_SESSION_get_time.html]=man3/SSL_SESSION_get_time.pod +GENERATE[html/man3/SSL_SESSION_get_time.html]=man3/SSL_SESSION_get_time.pod +DEPEND[man/man3/SSL_SESSION_get_time.3]=man3/SSL_SESSION_get_time.pod +GENERATE[man/man3/SSL_SESSION_get_time.3]=man3/SSL_SESSION_get_time.pod +DEPEND[html/man3/SSL_SESSION_has_ticket.html]=man3/SSL_SESSION_has_ticket.pod +GENERATE[html/man3/SSL_SESSION_has_ticket.html]=man3/SSL_SESSION_has_ticket.pod +DEPEND[man/man3/SSL_SESSION_has_ticket.3]=man3/SSL_SESSION_has_ticket.pod +GENERATE[man/man3/SSL_SESSION_has_ticket.3]=man3/SSL_SESSION_has_ticket.pod +DEPEND[html/man3/SSL_SESSION_is_resumable.html]=man3/SSL_SESSION_is_resumable.pod +GENERATE[html/man3/SSL_SESSION_is_resumable.html]=man3/SSL_SESSION_is_resumable.pod +DEPEND[man/man3/SSL_SESSION_is_resumable.3]=man3/SSL_SESSION_is_resumable.pod +GENERATE[man/man3/SSL_SESSION_is_resumable.3]=man3/SSL_SESSION_is_resumable.pod +DEPEND[html/man3/SSL_SESSION_print.html]=man3/SSL_SESSION_print.pod +GENERATE[html/man3/SSL_SESSION_print.html]=man3/SSL_SESSION_print.pod +DEPEND[man/man3/SSL_SESSION_print.3]=man3/SSL_SESSION_print.pod +GENERATE[man/man3/SSL_SESSION_print.3]=man3/SSL_SESSION_print.pod +DEPEND[html/man3/SSL_SESSION_set1_id.html]=man3/SSL_SESSION_set1_id.pod +GENERATE[html/man3/SSL_SESSION_set1_id.html]=man3/SSL_SESSION_set1_id.pod +DEPEND[man/man3/SSL_SESSION_set1_id.3]=man3/SSL_SESSION_set1_id.pod +GENERATE[man/man3/SSL_SESSION_set1_id.3]=man3/SSL_SESSION_set1_id.pod +DEPEND[html/man3/SSL_accept.html]=man3/SSL_accept.pod +GENERATE[html/man3/SSL_accept.html]=man3/SSL_accept.pod +DEPEND[man/man3/SSL_accept.3]=man3/SSL_accept.pod +GENERATE[man/man3/SSL_accept.3]=man3/SSL_accept.pod +DEPEND[html/man3/SSL_alert_type_string.html]=man3/SSL_alert_type_string.pod +GENERATE[html/man3/SSL_alert_type_string.html]=man3/SSL_alert_type_string.pod +DEPEND[man/man3/SSL_alert_type_string.3]=man3/SSL_alert_type_string.pod +GENERATE[man/man3/SSL_alert_type_string.3]=man3/SSL_alert_type_string.pod +DEPEND[html/man3/SSL_alloc_buffers.html]=man3/SSL_alloc_buffers.pod +GENERATE[html/man3/SSL_alloc_buffers.html]=man3/SSL_alloc_buffers.pod +DEPEND[man/man3/SSL_alloc_buffers.3]=man3/SSL_alloc_buffers.pod +GENERATE[man/man3/SSL_alloc_buffers.3]=man3/SSL_alloc_buffers.pod +DEPEND[html/man3/SSL_check_chain.html]=man3/SSL_check_chain.pod +GENERATE[html/man3/SSL_check_chain.html]=man3/SSL_check_chain.pod +DEPEND[man/man3/SSL_check_chain.3]=man3/SSL_check_chain.pod +GENERATE[man/man3/SSL_check_chain.3]=man3/SSL_check_chain.pod +DEPEND[html/man3/SSL_clear.html]=man3/SSL_clear.pod +GENERATE[html/man3/SSL_clear.html]=man3/SSL_clear.pod +DEPEND[man/man3/SSL_clear.3]=man3/SSL_clear.pod +GENERATE[man/man3/SSL_clear.3]=man3/SSL_clear.pod +DEPEND[html/man3/SSL_connect.html]=man3/SSL_connect.pod +GENERATE[html/man3/SSL_connect.html]=man3/SSL_connect.pod +DEPEND[man/man3/SSL_connect.3]=man3/SSL_connect.pod +GENERATE[man/man3/SSL_connect.3]=man3/SSL_connect.pod +DEPEND[html/man3/SSL_do_handshake.html]=man3/SSL_do_handshake.pod +GENERATE[html/man3/SSL_do_handshake.html]=man3/SSL_do_handshake.pod +DEPEND[man/man3/SSL_do_handshake.3]=man3/SSL_do_handshake.pod +GENERATE[man/man3/SSL_do_handshake.3]=man3/SSL_do_handshake.pod +DEPEND[html/man3/SSL_export_keying_material.html]=man3/SSL_export_keying_material.pod +GENERATE[html/man3/SSL_export_keying_material.html]=man3/SSL_export_keying_material.pod +DEPEND[man/man3/SSL_export_keying_material.3]=man3/SSL_export_keying_material.pod +GENERATE[man/man3/SSL_export_keying_material.3]=man3/SSL_export_keying_material.pod +DEPEND[html/man3/SSL_extension_supported.html]=man3/SSL_extension_supported.pod +GENERATE[html/man3/SSL_extension_supported.html]=man3/SSL_extension_supported.pod +DEPEND[man/man3/SSL_extension_supported.3]=man3/SSL_extension_supported.pod +GENERATE[man/man3/SSL_extension_supported.3]=man3/SSL_extension_supported.pod +DEPEND[html/man3/SSL_free.html]=man3/SSL_free.pod +GENERATE[html/man3/SSL_free.html]=man3/SSL_free.pod +DEPEND[man/man3/SSL_free.3]=man3/SSL_free.pod +GENERATE[man/man3/SSL_free.3]=man3/SSL_free.pod +DEPEND[html/man3/SSL_get0_peer_scts.html]=man3/SSL_get0_peer_scts.pod +GENERATE[html/man3/SSL_get0_peer_scts.html]=man3/SSL_get0_peer_scts.pod +DEPEND[man/man3/SSL_get0_peer_scts.3]=man3/SSL_get0_peer_scts.pod +GENERATE[man/man3/SSL_get0_peer_scts.3]=man3/SSL_get0_peer_scts.pod +DEPEND[html/man3/SSL_get_SSL_CTX.html]=man3/SSL_get_SSL_CTX.pod +GENERATE[html/man3/SSL_get_SSL_CTX.html]=man3/SSL_get_SSL_CTX.pod +DEPEND[man/man3/SSL_get_SSL_CTX.3]=man3/SSL_get_SSL_CTX.pod +GENERATE[man/man3/SSL_get_SSL_CTX.3]=man3/SSL_get_SSL_CTX.pod +DEPEND[html/man3/SSL_get_all_async_fds.html]=man3/SSL_get_all_async_fds.pod +GENERATE[html/man3/SSL_get_all_async_fds.html]=man3/SSL_get_all_async_fds.pod +DEPEND[man/man3/SSL_get_all_async_fds.3]=man3/SSL_get_all_async_fds.pod +GENERATE[man/man3/SSL_get_all_async_fds.3]=man3/SSL_get_all_async_fds.pod +DEPEND[html/man3/SSL_get_certificate.html]=man3/SSL_get_certificate.pod +GENERATE[html/man3/SSL_get_certificate.html]=man3/SSL_get_certificate.pod +DEPEND[man/man3/SSL_get_certificate.3]=man3/SSL_get_certificate.pod +GENERATE[man/man3/SSL_get_certificate.3]=man3/SSL_get_certificate.pod +DEPEND[html/man3/SSL_get_ciphers.html]=man3/SSL_get_ciphers.pod +GENERATE[html/man3/SSL_get_ciphers.html]=man3/SSL_get_ciphers.pod +DEPEND[man/man3/SSL_get_ciphers.3]=man3/SSL_get_ciphers.pod +GENERATE[man/man3/SSL_get_ciphers.3]=man3/SSL_get_ciphers.pod +DEPEND[html/man3/SSL_get_client_random.html]=man3/SSL_get_client_random.pod +GENERATE[html/man3/SSL_get_client_random.html]=man3/SSL_get_client_random.pod +DEPEND[man/man3/SSL_get_client_random.3]=man3/SSL_get_client_random.pod +GENERATE[man/man3/SSL_get_client_random.3]=man3/SSL_get_client_random.pod +DEPEND[html/man3/SSL_get_current_cipher.html]=man3/SSL_get_current_cipher.pod +GENERATE[html/man3/SSL_get_current_cipher.html]=man3/SSL_get_current_cipher.pod +DEPEND[man/man3/SSL_get_current_cipher.3]=man3/SSL_get_current_cipher.pod +GENERATE[man/man3/SSL_get_current_cipher.3]=man3/SSL_get_current_cipher.pod +DEPEND[html/man3/SSL_get_default_timeout.html]=man3/SSL_get_default_timeout.pod +GENERATE[html/man3/SSL_get_default_timeout.html]=man3/SSL_get_default_timeout.pod +DEPEND[man/man3/SSL_get_default_timeout.3]=man3/SSL_get_default_timeout.pod +GENERATE[man/man3/SSL_get_default_timeout.3]=man3/SSL_get_default_timeout.pod +DEPEND[html/man3/SSL_get_error.html]=man3/SSL_get_error.pod +GENERATE[html/man3/SSL_get_error.html]=man3/SSL_get_error.pod +DEPEND[man/man3/SSL_get_error.3]=man3/SSL_get_error.pod +GENERATE[man/man3/SSL_get_error.3]=man3/SSL_get_error.pod +DEPEND[html/man3/SSL_get_extms_support.html]=man3/SSL_get_extms_support.pod +GENERATE[html/man3/SSL_get_extms_support.html]=man3/SSL_get_extms_support.pod +DEPEND[man/man3/SSL_get_extms_support.3]=man3/SSL_get_extms_support.pod +GENERATE[man/man3/SSL_get_extms_support.3]=man3/SSL_get_extms_support.pod +DEPEND[html/man3/SSL_get_fd.html]=man3/SSL_get_fd.pod +GENERATE[html/man3/SSL_get_fd.html]=man3/SSL_get_fd.pod +DEPEND[man/man3/SSL_get_fd.3]=man3/SSL_get_fd.pod +GENERATE[man/man3/SSL_get_fd.3]=man3/SSL_get_fd.pod +DEPEND[html/man3/SSL_get_peer_cert_chain.html]=man3/SSL_get_peer_cert_chain.pod +GENERATE[html/man3/SSL_get_peer_cert_chain.html]=man3/SSL_get_peer_cert_chain.pod +DEPEND[man/man3/SSL_get_peer_cert_chain.3]=man3/SSL_get_peer_cert_chain.pod +GENERATE[man/man3/SSL_get_peer_cert_chain.3]=man3/SSL_get_peer_cert_chain.pod +DEPEND[html/man3/SSL_get_peer_certificate.html]=man3/SSL_get_peer_certificate.pod +GENERATE[html/man3/SSL_get_peer_certificate.html]=man3/SSL_get_peer_certificate.pod +DEPEND[man/man3/SSL_get_peer_certificate.3]=man3/SSL_get_peer_certificate.pod +GENERATE[man/man3/SSL_get_peer_certificate.3]=man3/SSL_get_peer_certificate.pod +DEPEND[html/man3/SSL_get_peer_signature_nid.html]=man3/SSL_get_peer_signature_nid.pod +GENERATE[html/man3/SSL_get_peer_signature_nid.html]=man3/SSL_get_peer_signature_nid.pod +DEPEND[man/man3/SSL_get_peer_signature_nid.3]=man3/SSL_get_peer_signature_nid.pod +GENERATE[man/man3/SSL_get_peer_signature_nid.3]=man3/SSL_get_peer_signature_nid.pod +DEPEND[html/man3/SSL_get_peer_tmp_key.html]=man3/SSL_get_peer_tmp_key.pod +GENERATE[html/man3/SSL_get_peer_tmp_key.html]=man3/SSL_get_peer_tmp_key.pod +DEPEND[man/man3/SSL_get_peer_tmp_key.3]=man3/SSL_get_peer_tmp_key.pod +GENERATE[man/man3/SSL_get_peer_tmp_key.3]=man3/SSL_get_peer_tmp_key.pod +DEPEND[html/man3/SSL_get_psk_identity.html]=man3/SSL_get_psk_identity.pod +GENERATE[html/man3/SSL_get_psk_identity.html]=man3/SSL_get_psk_identity.pod +DEPEND[man/man3/SSL_get_psk_identity.3]=man3/SSL_get_psk_identity.pod +GENERATE[man/man3/SSL_get_psk_identity.3]=man3/SSL_get_psk_identity.pod +DEPEND[html/man3/SSL_get_rbio.html]=man3/SSL_get_rbio.pod +GENERATE[html/man3/SSL_get_rbio.html]=man3/SSL_get_rbio.pod +DEPEND[man/man3/SSL_get_rbio.3]=man3/SSL_get_rbio.pod +GENERATE[man/man3/SSL_get_rbio.3]=man3/SSL_get_rbio.pod +DEPEND[html/man3/SSL_get_session.html]=man3/SSL_get_session.pod +GENERATE[html/man3/SSL_get_session.html]=man3/SSL_get_session.pod +DEPEND[man/man3/SSL_get_session.3]=man3/SSL_get_session.pod +GENERATE[man/man3/SSL_get_session.3]=man3/SSL_get_session.pod +DEPEND[html/man3/SSL_get_shared_sigalgs.html]=man3/SSL_get_shared_sigalgs.pod +GENERATE[html/man3/SSL_get_shared_sigalgs.html]=man3/SSL_get_shared_sigalgs.pod +DEPEND[man/man3/SSL_get_shared_sigalgs.3]=man3/SSL_get_shared_sigalgs.pod +GENERATE[man/man3/SSL_get_shared_sigalgs.3]=man3/SSL_get_shared_sigalgs.pod +DEPEND[html/man3/SSL_get_verify_result.html]=man3/SSL_get_verify_result.pod +GENERATE[html/man3/SSL_get_verify_result.html]=man3/SSL_get_verify_result.pod +DEPEND[man/man3/SSL_get_verify_result.3]=man3/SSL_get_verify_result.pod +GENERATE[man/man3/SSL_get_verify_result.3]=man3/SSL_get_verify_result.pod +DEPEND[html/man3/SSL_get_version.html]=man3/SSL_get_version.pod +GENERATE[html/man3/SSL_get_version.html]=man3/SSL_get_version.pod +DEPEND[man/man3/SSL_get_version.3]=man3/SSL_get_version.pod +GENERATE[man/man3/SSL_get_version.3]=man3/SSL_get_version.pod +DEPEND[html/man3/SSL_group_to_name.html]=man3/SSL_group_to_name.pod +GENERATE[html/man3/SSL_group_to_name.html]=man3/SSL_group_to_name.pod +DEPEND[man/man3/SSL_group_to_name.3]=man3/SSL_group_to_name.pod +GENERATE[man/man3/SSL_group_to_name.3]=man3/SSL_group_to_name.pod +DEPEND[html/man3/SSL_in_init.html]=man3/SSL_in_init.pod +GENERATE[html/man3/SSL_in_init.html]=man3/SSL_in_init.pod +DEPEND[man/man3/SSL_in_init.3]=man3/SSL_in_init.pod +GENERATE[man/man3/SSL_in_init.3]=man3/SSL_in_init.pod +DEPEND[html/man3/SSL_key_update.html]=man3/SSL_key_update.pod +GENERATE[html/man3/SSL_key_update.html]=man3/SSL_key_update.pod +DEPEND[man/man3/SSL_key_update.3]=man3/SSL_key_update.pod +GENERATE[man/man3/SSL_key_update.3]=man3/SSL_key_update.pod +DEPEND[html/man3/SSL_library_init.html]=man3/SSL_library_init.pod +GENERATE[html/man3/SSL_library_init.html]=man3/SSL_library_init.pod +DEPEND[man/man3/SSL_library_init.3]=man3/SSL_library_init.pod +GENERATE[man/man3/SSL_library_init.3]=man3/SSL_library_init.pod +DEPEND[html/man3/SSL_load_client_CA_file.html]=man3/SSL_load_client_CA_file.pod +GENERATE[html/man3/SSL_load_client_CA_file.html]=man3/SSL_load_client_CA_file.pod +DEPEND[man/man3/SSL_load_client_CA_file.3]=man3/SSL_load_client_CA_file.pod +GENERATE[man/man3/SSL_load_client_CA_file.3]=man3/SSL_load_client_CA_file.pod +DEPEND[html/man3/SSL_new.html]=man3/SSL_new.pod +GENERATE[html/man3/SSL_new.html]=man3/SSL_new.pod +DEPEND[man/man3/SSL_new.3]=man3/SSL_new.pod +GENERATE[man/man3/SSL_new.3]=man3/SSL_new.pod +DEPEND[html/man3/SSL_pending.html]=man3/SSL_pending.pod +GENERATE[html/man3/SSL_pending.html]=man3/SSL_pending.pod +DEPEND[man/man3/SSL_pending.3]=man3/SSL_pending.pod +GENERATE[man/man3/SSL_pending.3]=man3/SSL_pending.pod +DEPEND[html/man3/SSL_read.html]=man3/SSL_read.pod +GENERATE[html/man3/SSL_read.html]=man3/SSL_read.pod +DEPEND[man/man3/SSL_read.3]=man3/SSL_read.pod +GENERATE[man/man3/SSL_read.3]=man3/SSL_read.pod +DEPEND[html/man3/SSL_read_early_data.html]=man3/SSL_read_early_data.pod +GENERATE[html/man3/SSL_read_early_data.html]=man3/SSL_read_early_data.pod +DEPEND[man/man3/SSL_read_early_data.3]=man3/SSL_read_early_data.pod +GENERATE[man/man3/SSL_read_early_data.3]=man3/SSL_read_early_data.pod +DEPEND[html/man3/SSL_rstate_string.html]=man3/SSL_rstate_string.pod +GENERATE[html/man3/SSL_rstate_string.html]=man3/SSL_rstate_string.pod +DEPEND[man/man3/SSL_rstate_string.3]=man3/SSL_rstate_string.pod +GENERATE[man/man3/SSL_rstate_string.3]=man3/SSL_rstate_string.pod +DEPEND[html/man3/SSL_session_reused.html]=man3/SSL_session_reused.pod +GENERATE[html/man3/SSL_session_reused.html]=man3/SSL_session_reused.pod +DEPEND[man/man3/SSL_session_reused.3]=man3/SSL_session_reused.pod +GENERATE[man/man3/SSL_session_reused.3]=man3/SSL_session_reused.pod +DEPEND[html/man3/SSL_set1_host.html]=man3/SSL_set1_host.pod +GENERATE[html/man3/SSL_set1_host.html]=man3/SSL_set1_host.pod +DEPEND[man/man3/SSL_set1_host.3]=man3/SSL_set1_host.pod +GENERATE[man/man3/SSL_set1_host.3]=man3/SSL_set1_host.pod +DEPEND[html/man3/SSL_set_async_callback.html]=man3/SSL_set_async_callback.pod +GENERATE[html/man3/SSL_set_async_callback.html]=man3/SSL_set_async_callback.pod +DEPEND[man/man3/SSL_set_async_callback.3]=man3/SSL_set_async_callback.pod +GENERATE[man/man3/SSL_set_async_callback.3]=man3/SSL_set_async_callback.pod +DEPEND[html/man3/SSL_set_bio.html]=man3/SSL_set_bio.pod +GENERATE[html/man3/SSL_set_bio.html]=man3/SSL_set_bio.pod +DEPEND[man/man3/SSL_set_bio.3]=man3/SSL_set_bio.pod +GENERATE[man/man3/SSL_set_bio.3]=man3/SSL_set_bio.pod +DEPEND[html/man3/SSL_set_connect_state.html]=man3/SSL_set_connect_state.pod +GENERATE[html/man3/SSL_set_connect_state.html]=man3/SSL_set_connect_state.pod +DEPEND[man/man3/SSL_set_connect_state.3]=man3/SSL_set_connect_state.pod +GENERATE[man/man3/SSL_set_connect_state.3]=man3/SSL_set_connect_state.pod +DEPEND[html/man3/SSL_set_fd.html]=man3/SSL_set_fd.pod +GENERATE[html/man3/SSL_set_fd.html]=man3/SSL_set_fd.pod +DEPEND[man/man3/SSL_set_fd.3]=man3/SSL_set_fd.pod +GENERATE[man/man3/SSL_set_fd.3]=man3/SSL_set_fd.pod +DEPEND[html/man3/SSL_set_retry_verify.html]=man3/SSL_set_retry_verify.pod +GENERATE[html/man3/SSL_set_retry_verify.html]=man3/SSL_set_retry_verify.pod +DEPEND[man/man3/SSL_set_retry_verify.3]=man3/SSL_set_retry_verify.pod +GENERATE[man/man3/SSL_set_retry_verify.3]=man3/SSL_set_retry_verify.pod +DEPEND[html/man3/SSL_set_session.html]=man3/SSL_set_session.pod +GENERATE[html/man3/SSL_set_session.html]=man3/SSL_set_session.pod +DEPEND[man/man3/SSL_set_session.3]=man3/SSL_set_session.pod +GENERATE[man/man3/SSL_set_session.3]=man3/SSL_set_session.pod +DEPEND[html/man3/SSL_set_shutdown.html]=man3/SSL_set_shutdown.pod +GENERATE[html/man3/SSL_set_shutdown.html]=man3/SSL_set_shutdown.pod +DEPEND[man/man3/SSL_set_shutdown.3]=man3/SSL_set_shutdown.pod +GENERATE[man/man3/SSL_set_shutdown.3]=man3/SSL_set_shutdown.pod +DEPEND[html/man3/SSL_set_verify_result.html]=man3/SSL_set_verify_result.pod +GENERATE[html/man3/SSL_set_verify_result.html]=man3/SSL_set_verify_result.pod +DEPEND[man/man3/SSL_set_verify_result.3]=man3/SSL_set_verify_result.pod +GENERATE[man/man3/SSL_set_verify_result.3]=man3/SSL_set_verify_result.pod +DEPEND[html/man3/SSL_shutdown.html]=man3/SSL_shutdown.pod +GENERATE[html/man3/SSL_shutdown.html]=man3/SSL_shutdown.pod +DEPEND[man/man3/SSL_shutdown.3]=man3/SSL_shutdown.pod +GENERATE[man/man3/SSL_shutdown.3]=man3/SSL_shutdown.pod +DEPEND[html/man3/SSL_state_string.html]=man3/SSL_state_string.pod +GENERATE[html/man3/SSL_state_string.html]=man3/SSL_state_string.pod +DEPEND[man/man3/SSL_state_string.3]=man3/SSL_state_string.pod +GENERATE[man/man3/SSL_state_string.3]=man3/SSL_state_string.pod +DEPEND[html/man3/SSL_want.html]=man3/SSL_want.pod +GENERATE[html/man3/SSL_want.html]=man3/SSL_want.pod +DEPEND[man/man3/SSL_want.3]=man3/SSL_want.pod +GENERATE[man/man3/SSL_want.3]=man3/SSL_want.pod +DEPEND[html/man3/SSL_write.html]=man3/SSL_write.pod +GENERATE[html/man3/SSL_write.html]=man3/SSL_write.pod +DEPEND[man/man3/SSL_write.3]=man3/SSL_write.pod +GENERATE[man/man3/SSL_write.3]=man3/SSL_write.pod +DEPEND[html/man3/TS_RESP_CTX_new.html]=man3/TS_RESP_CTX_new.pod +GENERATE[html/man3/TS_RESP_CTX_new.html]=man3/TS_RESP_CTX_new.pod +DEPEND[man/man3/TS_RESP_CTX_new.3]=man3/TS_RESP_CTX_new.pod +GENERATE[man/man3/TS_RESP_CTX_new.3]=man3/TS_RESP_CTX_new.pod +DEPEND[html/man3/TS_VERIFY_CTX_set_certs.html]=man3/TS_VERIFY_CTX_set_certs.pod +GENERATE[html/man3/TS_VERIFY_CTX_set_certs.html]=man3/TS_VERIFY_CTX_set_certs.pod +DEPEND[man/man3/TS_VERIFY_CTX_set_certs.3]=man3/TS_VERIFY_CTX_set_certs.pod +GENERATE[man/man3/TS_VERIFY_CTX_set_certs.3]=man3/TS_VERIFY_CTX_set_certs.pod +DEPEND[html/man3/UI_STRING.html]=man3/UI_STRING.pod +GENERATE[html/man3/UI_STRING.html]=man3/UI_STRING.pod +DEPEND[man/man3/UI_STRING.3]=man3/UI_STRING.pod +GENERATE[man/man3/UI_STRING.3]=man3/UI_STRING.pod +DEPEND[html/man3/UI_UTIL_read_pw.html]=man3/UI_UTIL_read_pw.pod +GENERATE[html/man3/UI_UTIL_read_pw.html]=man3/UI_UTIL_read_pw.pod +DEPEND[man/man3/UI_UTIL_read_pw.3]=man3/UI_UTIL_read_pw.pod +GENERATE[man/man3/UI_UTIL_read_pw.3]=man3/UI_UTIL_read_pw.pod +DEPEND[html/man3/UI_create_method.html]=man3/UI_create_method.pod +GENERATE[html/man3/UI_create_method.html]=man3/UI_create_method.pod +DEPEND[man/man3/UI_create_method.3]=man3/UI_create_method.pod +GENERATE[man/man3/UI_create_method.3]=man3/UI_create_method.pod +DEPEND[html/man3/UI_new.html]=man3/UI_new.pod +GENERATE[html/man3/UI_new.html]=man3/UI_new.pod +DEPEND[man/man3/UI_new.3]=man3/UI_new.pod +GENERATE[man/man3/UI_new.3]=man3/UI_new.pod +DEPEND[html/man3/X509V3_get_d2i.html]=man3/X509V3_get_d2i.pod +GENERATE[html/man3/X509V3_get_d2i.html]=man3/X509V3_get_d2i.pod +DEPEND[man/man3/X509V3_get_d2i.3]=man3/X509V3_get_d2i.pod +GENERATE[man/man3/X509V3_get_d2i.3]=man3/X509V3_get_d2i.pod +DEPEND[html/man3/X509V3_set_ctx.html]=man3/X509V3_set_ctx.pod +GENERATE[html/man3/X509V3_set_ctx.html]=man3/X509V3_set_ctx.pod +DEPEND[man/man3/X509V3_set_ctx.3]=man3/X509V3_set_ctx.pod +GENERATE[man/man3/X509V3_set_ctx.3]=man3/X509V3_set_ctx.pod +DEPEND[html/man3/X509_ALGOR_dup.html]=man3/X509_ALGOR_dup.pod +GENERATE[html/man3/X509_ALGOR_dup.html]=man3/X509_ALGOR_dup.pod +DEPEND[man/man3/X509_ALGOR_dup.3]=man3/X509_ALGOR_dup.pod +GENERATE[man/man3/X509_ALGOR_dup.3]=man3/X509_ALGOR_dup.pod +DEPEND[html/man3/X509_CRL_get0_by_serial.html]=man3/X509_CRL_get0_by_serial.pod +GENERATE[html/man3/X509_CRL_get0_by_serial.html]=man3/X509_CRL_get0_by_serial.pod +DEPEND[man/man3/X509_CRL_get0_by_serial.3]=man3/X509_CRL_get0_by_serial.pod +GENERATE[man/man3/X509_CRL_get0_by_serial.3]=man3/X509_CRL_get0_by_serial.pod +DEPEND[html/man3/X509_EXTENSION_set_object.html]=man3/X509_EXTENSION_set_object.pod +GENERATE[html/man3/X509_EXTENSION_set_object.html]=man3/X509_EXTENSION_set_object.pod +DEPEND[man/man3/X509_EXTENSION_set_object.3]=man3/X509_EXTENSION_set_object.pod +GENERATE[man/man3/X509_EXTENSION_set_object.3]=man3/X509_EXTENSION_set_object.pod +DEPEND[html/man3/X509_LOOKUP.html]=man3/X509_LOOKUP.pod +GENERATE[html/man3/X509_LOOKUP.html]=man3/X509_LOOKUP.pod +DEPEND[man/man3/X509_LOOKUP.3]=man3/X509_LOOKUP.pod +GENERATE[man/man3/X509_LOOKUP.3]=man3/X509_LOOKUP.pod +DEPEND[html/man3/X509_LOOKUP_hash_dir.html]=man3/X509_LOOKUP_hash_dir.pod +GENERATE[html/man3/X509_LOOKUP_hash_dir.html]=man3/X509_LOOKUP_hash_dir.pod +DEPEND[man/man3/X509_LOOKUP_hash_dir.3]=man3/X509_LOOKUP_hash_dir.pod +GENERATE[man/man3/X509_LOOKUP_hash_dir.3]=man3/X509_LOOKUP_hash_dir.pod +DEPEND[html/man3/X509_LOOKUP_meth_new.html]=man3/X509_LOOKUP_meth_new.pod +GENERATE[html/man3/X509_LOOKUP_meth_new.html]=man3/X509_LOOKUP_meth_new.pod +DEPEND[man/man3/X509_LOOKUP_meth_new.3]=man3/X509_LOOKUP_meth_new.pod +GENERATE[man/man3/X509_LOOKUP_meth_new.3]=man3/X509_LOOKUP_meth_new.pod +DEPEND[html/man3/X509_NAME_ENTRY_get_object.html]=man3/X509_NAME_ENTRY_get_object.pod +GENERATE[html/man3/X509_NAME_ENTRY_get_object.html]=man3/X509_NAME_ENTRY_get_object.pod +DEPEND[man/man3/X509_NAME_ENTRY_get_object.3]=man3/X509_NAME_ENTRY_get_object.pod +GENERATE[man/man3/X509_NAME_ENTRY_get_object.3]=man3/X509_NAME_ENTRY_get_object.pod +DEPEND[html/man3/X509_NAME_add_entry_by_txt.html]=man3/X509_NAME_add_entry_by_txt.pod +GENERATE[html/man3/X509_NAME_add_entry_by_txt.html]=man3/X509_NAME_add_entry_by_txt.pod +DEPEND[man/man3/X509_NAME_add_entry_by_txt.3]=man3/X509_NAME_add_entry_by_txt.pod +GENERATE[man/man3/X509_NAME_add_entry_by_txt.3]=man3/X509_NAME_add_entry_by_txt.pod +DEPEND[html/man3/X509_NAME_get0_der.html]=man3/X509_NAME_get0_der.pod +GENERATE[html/man3/X509_NAME_get0_der.html]=man3/X509_NAME_get0_der.pod +DEPEND[man/man3/X509_NAME_get0_der.3]=man3/X509_NAME_get0_der.pod +GENERATE[man/man3/X509_NAME_get0_der.3]=man3/X509_NAME_get0_der.pod +DEPEND[html/man3/X509_NAME_get_index_by_NID.html]=man3/X509_NAME_get_index_by_NID.pod +GENERATE[html/man3/X509_NAME_get_index_by_NID.html]=man3/X509_NAME_get_index_by_NID.pod +DEPEND[man/man3/X509_NAME_get_index_by_NID.3]=man3/X509_NAME_get_index_by_NID.pod +GENERATE[man/man3/X509_NAME_get_index_by_NID.3]=man3/X509_NAME_get_index_by_NID.pod +DEPEND[html/man3/X509_NAME_print_ex.html]=man3/X509_NAME_print_ex.pod +GENERATE[html/man3/X509_NAME_print_ex.html]=man3/X509_NAME_print_ex.pod +DEPEND[man/man3/X509_NAME_print_ex.3]=man3/X509_NAME_print_ex.pod +GENERATE[man/man3/X509_NAME_print_ex.3]=man3/X509_NAME_print_ex.pod +DEPEND[html/man3/X509_PUBKEY_new.html]=man3/X509_PUBKEY_new.pod +GENERATE[html/man3/X509_PUBKEY_new.html]=man3/X509_PUBKEY_new.pod +DEPEND[man/man3/X509_PUBKEY_new.3]=man3/X509_PUBKEY_new.pod +GENERATE[man/man3/X509_PUBKEY_new.3]=man3/X509_PUBKEY_new.pod +DEPEND[html/man3/X509_SIG_get0.html]=man3/X509_SIG_get0.pod +GENERATE[html/man3/X509_SIG_get0.html]=man3/X509_SIG_get0.pod +DEPEND[man/man3/X509_SIG_get0.3]=man3/X509_SIG_get0.pod +GENERATE[man/man3/X509_SIG_get0.3]=man3/X509_SIG_get0.pod +DEPEND[html/man3/X509_STORE_CTX_get_error.html]=man3/X509_STORE_CTX_get_error.pod +GENERATE[html/man3/X509_STORE_CTX_get_error.html]=man3/X509_STORE_CTX_get_error.pod +DEPEND[man/man3/X509_STORE_CTX_get_error.3]=man3/X509_STORE_CTX_get_error.pod +GENERATE[man/man3/X509_STORE_CTX_get_error.3]=man3/X509_STORE_CTX_get_error.pod +DEPEND[html/man3/X509_STORE_CTX_new.html]=man3/X509_STORE_CTX_new.pod +GENERATE[html/man3/X509_STORE_CTX_new.html]=man3/X509_STORE_CTX_new.pod +DEPEND[man/man3/X509_STORE_CTX_new.3]=man3/X509_STORE_CTX_new.pod +GENERATE[man/man3/X509_STORE_CTX_new.3]=man3/X509_STORE_CTX_new.pod +DEPEND[html/man3/X509_STORE_CTX_set_verify_cb.html]=man3/X509_STORE_CTX_set_verify_cb.pod +GENERATE[html/man3/X509_STORE_CTX_set_verify_cb.html]=man3/X509_STORE_CTX_set_verify_cb.pod +DEPEND[man/man3/X509_STORE_CTX_set_verify_cb.3]=man3/X509_STORE_CTX_set_verify_cb.pod +GENERATE[man/man3/X509_STORE_CTX_set_verify_cb.3]=man3/X509_STORE_CTX_set_verify_cb.pod +DEPEND[html/man3/X509_STORE_add_cert.html]=man3/X509_STORE_add_cert.pod +GENERATE[html/man3/X509_STORE_add_cert.html]=man3/X509_STORE_add_cert.pod +DEPEND[man/man3/X509_STORE_add_cert.3]=man3/X509_STORE_add_cert.pod +GENERATE[man/man3/X509_STORE_add_cert.3]=man3/X509_STORE_add_cert.pod +DEPEND[html/man3/X509_STORE_get0_param.html]=man3/X509_STORE_get0_param.pod +GENERATE[html/man3/X509_STORE_get0_param.html]=man3/X509_STORE_get0_param.pod +DEPEND[man/man3/X509_STORE_get0_param.3]=man3/X509_STORE_get0_param.pod +GENERATE[man/man3/X509_STORE_get0_param.3]=man3/X509_STORE_get0_param.pod +DEPEND[html/man3/X509_STORE_new.html]=man3/X509_STORE_new.pod +GENERATE[html/man3/X509_STORE_new.html]=man3/X509_STORE_new.pod +DEPEND[man/man3/X509_STORE_new.3]=man3/X509_STORE_new.pod +GENERATE[man/man3/X509_STORE_new.3]=man3/X509_STORE_new.pod +DEPEND[html/man3/X509_STORE_set_verify_cb_func.html]=man3/X509_STORE_set_verify_cb_func.pod +GENERATE[html/man3/X509_STORE_set_verify_cb_func.html]=man3/X509_STORE_set_verify_cb_func.pod +DEPEND[man/man3/X509_STORE_set_verify_cb_func.3]=man3/X509_STORE_set_verify_cb_func.pod +GENERATE[man/man3/X509_STORE_set_verify_cb_func.3]=man3/X509_STORE_set_verify_cb_func.pod +DEPEND[html/man3/X509_VERIFY_PARAM_set_flags.html]=man3/X509_VERIFY_PARAM_set_flags.pod +GENERATE[html/man3/X509_VERIFY_PARAM_set_flags.html]=man3/X509_VERIFY_PARAM_set_flags.pod +DEPEND[man/man3/X509_VERIFY_PARAM_set_flags.3]=man3/X509_VERIFY_PARAM_set_flags.pod +GENERATE[man/man3/X509_VERIFY_PARAM_set_flags.3]=man3/X509_VERIFY_PARAM_set_flags.pod +DEPEND[html/man3/X509_add_cert.html]=man3/X509_add_cert.pod +GENERATE[html/man3/X509_add_cert.html]=man3/X509_add_cert.pod +DEPEND[man/man3/X509_add_cert.3]=man3/X509_add_cert.pod +GENERATE[man/man3/X509_add_cert.3]=man3/X509_add_cert.pod +DEPEND[html/man3/X509_check_ca.html]=man3/X509_check_ca.pod +GENERATE[html/man3/X509_check_ca.html]=man3/X509_check_ca.pod +DEPEND[man/man3/X509_check_ca.3]=man3/X509_check_ca.pod +GENERATE[man/man3/X509_check_ca.3]=man3/X509_check_ca.pod +DEPEND[html/man3/X509_check_host.html]=man3/X509_check_host.pod +GENERATE[html/man3/X509_check_host.html]=man3/X509_check_host.pod +DEPEND[man/man3/X509_check_host.3]=man3/X509_check_host.pod +GENERATE[man/man3/X509_check_host.3]=man3/X509_check_host.pod +DEPEND[html/man3/X509_check_issued.html]=man3/X509_check_issued.pod +GENERATE[html/man3/X509_check_issued.html]=man3/X509_check_issued.pod +DEPEND[man/man3/X509_check_issued.3]=man3/X509_check_issued.pod +GENERATE[man/man3/X509_check_issued.3]=man3/X509_check_issued.pod +DEPEND[html/man3/X509_check_private_key.html]=man3/X509_check_private_key.pod +GENERATE[html/man3/X509_check_private_key.html]=man3/X509_check_private_key.pod +DEPEND[man/man3/X509_check_private_key.3]=man3/X509_check_private_key.pod +GENERATE[man/man3/X509_check_private_key.3]=man3/X509_check_private_key.pod +DEPEND[html/man3/X509_check_purpose.html]=man3/X509_check_purpose.pod +GENERATE[html/man3/X509_check_purpose.html]=man3/X509_check_purpose.pod +DEPEND[man/man3/X509_check_purpose.3]=man3/X509_check_purpose.pod +GENERATE[man/man3/X509_check_purpose.3]=man3/X509_check_purpose.pod +DEPEND[html/man3/X509_cmp.html]=man3/X509_cmp.pod +GENERATE[html/man3/X509_cmp.html]=man3/X509_cmp.pod +DEPEND[man/man3/X509_cmp.3]=man3/X509_cmp.pod +GENERATE[man/man3/X509_cmp.3]=man3/X509_cmp.pod +DEPEND[html/man3/X509_cmp_time.html]=man3/X509_cmp_time.pod +GENERATE[html/man3/X509_cmp_time.html]=man3/X509_cmp_time.pod +DEPEND[man/man3/X509_cmp_time.3]=man3/X509_cmp_time.pod +GENERATE[man/man3/X509_cmp_time.3]=man3/X509_cmp_time.pod +DEPEND[html/man3/X509_digest.html]=man3/X509_digest.pod +GENERATE[html/man3/X509_digest.html]=man3/X509_digest.pod +DEPEND[man/man3/X509_digest.3]=man3/X509_digest.pod +GENERATE[man/man3/X509_digest.3]=man3/X509_digest.pod +DEPEND[html/man3/X509_dup.html]=man3/X509_dup.pod +GENERATE[html/man3/X509_dup.html]=man3/X509_dup.pod +DEPEND[man/man3/X509_dup.3]=man3/X509_dup.pod +GENERATE[man/man3/X509_dup.3]=man3/X509_dup.pod +DEPEND[html/man3/X509_get0_distinguishing_id.html]=man3/X509_get0_distinguishing_id.pod +GENERATE[html/man3/X509_get0_distinguishing_id.html]=man3/X509_get0_distinguishing_id.pod +DEPEND[man/man3/X509_get0_distinguishing_id.3]=man3/X509_get0_distinguishing_id.pod +GENERATE[man/man3/X509_get0_distinguishing_id.3]=man3/X509_get0_distinguishing_id.pod +DEPEND[html/man3/X509_get0_notBefore.html]=man3/X509_get0_notBefore.pod +GENERATE[html/man3/X509_get0_notBefore.html]=man3/X509_get0_notBefore.pod +DEPEND[man/man3/X509_get0_notBefore.3]=man3/X509_get0_notBefore.pod +GENERATE[man/man3/X509_get0_notBefore.3]=man3/X509_get0_notBefore.pod +DEPEND[html/man3/X509_get0_signature.html]=man3/X509_get0_signature.pod +GENERATE[html/man3/X509_get0_signature.html]=man3/X509_get0_signature.pod +DEPEND[man/man3/X509_get0_signature.3]=man3/X509_get0_signature.pod +GENERATE[man/man3/X509_get0_signature.3]=man3/X509_get0_signature.pod +DEPEND[html/man3/X509_get0_uids.html]=man3/X509_get0_uids.pod +GENERATE[html/man3/X509_get0_uids.html]=man3/X509_get0_uids.pod +DEPEND[man/man3/X509_get0_uids.3]=man3/X509_get0_uids.pod +GENERATE[man/man3/X509_get0_uids.3]=man3/X509_get0_uids.pod +DEPEND[html/man3/X509_get_extension_flags.html]=man3/X509_get_extension_flags.pod +GENERATE[html/man3/X509_get_extension_flags.html]=man3/X509_get_extension_flags.pod +DEPEND[man/man3/X509_get_extension_flags.3]=man3/X509_get_extension_flags.pod +GENERATE[man/man3/X509_get_extension_flags.3]=man3/X509_get_extension_flags.pod +DEPEND[html/man3/X509_get_pubkey.html]=man3/X509_get_pubkey.pod +GENERATE[html/man3/X509_get_pubkey.html]=man3/X509_get_pubkey.pod +DEPEND[man/man3/X509_get_pubkey.3]=man3/X509_get_pubkey.pod +GENERATE[man/man3/X509_get_pubkey.3]=man3/X509_get_pubkey.pod +DEPEND[html/man3/X509_get_serialNumber.html]=man3/X509_get_serialNumber.pod +GENERATE[html/man3/X509_get_serialNumber.html]=man3/X509_get_serialNumber.pod +DEPEND[man/man3/X509_get_serialNumber.3]=man3/X509_get_serialNumber.pod +GENERATE[man/man3/X509_get_serialNumber.3]=man3/X509_get_serialNumber.pod +DEPEND[html/man3/X509_get_subject_name.html]=man3/X509_get_subject_name.pod +GENERATE[html/man3/X509_get_subject_name.html]=man3/X509_get_subject_name.pod +DEPEND[man/man3/X509_get_subject_name.3]=man3/X509_get_subject_name.pod +GENERATE[man/man3/X509_get_subject_name.3]=man3/X509_get_subject_name.pod +DEPEND[html/man3/X509_get_version.html]=man3/X509_get_version.pod +GENERATE[html/man3/X509_get_version.html]=man3/X509_get_version.pod +DEPEND[man/man3/X509_get_version.3]=man3/X509_get_version.pod +GENERATE[man/man3/X509_get_version.3]=man3/X509_get_version.pod +DEPEND[html/man3/X509_load_http.html]=man3/X509_load_http.pod +GENERATE[html/man3/X509_load_http.html]=man3/X509_load_http.pod +DEPEND[man/man3/X509_load_http.3]=man3/X509_load_http.pod +GENERATE[man/man3/X509_load_http.3]=man3/X509_load_http.pod +DEPEND[html/man3/X509_new.html]=man3/X509_new.pod +GENERATE[html/man3/X509_new.html]=man3/X509_new.pod +DEPEND[man/man3/X509_new.3]=man3/X509_new.pod +GENERATE[man/man3/X509_new.3]=man3/X509_new.pod +DEPEND[html/man3/X509_sign.html]=man3/X509_sign.pod +GENERATE[html/man3/X509_sign.html]=man3/X509_sign.pod +DEPEND[man/man3/X509_sign.3]=man3/X509_sign.pod +GENERATE[man/man3/X509_sign.3]=man3/X509_sign.pod +DEPEND[html/man3/X509_verify.html]=man3/X509_verify.pod +GENERATE[html/man3/X509_verify.html]=man3/X509_verify.pod +DEPEND[man/man3/X509_verify.3]=man3/X509_verify.pod +GENERATE[man/man3/X509_verify.3]=man3/X509_verify.pod +DEPEND[html/man3/X509_verify_cert.html]=man3/X509_verify_cert.pod +GENERATE[html/man3/X509_verify_cert.html]=man3/X509_verify_cert.pod +DEPEND[man/man3/X509_verify_cert.3]=man3/X509_verify_cert.pod +GENERATE[man/man3/X509_verify_cert.3]=man3/X509_verify_cert.pod +DEPEND[html/man3/X509v3_get_ext_by_NID.html]=man3/X509v3_get_ext_by_NID.pod +GENERATE[html/man3/X509v3_get_ext_by_NID.html]=man3/X509v3_get_ext_by_NID.pod +DEPEND[man/man3/X509v3_get_ext_by_NID.3]=man3/X509v3_get_ext_by_NID.pod +GENERATE[man/man3/X509v3_get_ext_by_NID.3]=man3/X509v3_get_ext_by_NID.pod +DEPEND[html/man3/b2i_PVK_bio_ex.html]=man3/b2i_PVK_bio_ex.pod +GENERATE[html/man3/b2i_PVK_bio_ex.html]=man3/b2i_PVK_bio_ex.pod +DEPEND[man/man3/b2i_PVK_bio_ex.3]=man3/b2i_PVK_bio_ex.pod +GENERATE[man/man3/b2i_PVK_bio_ex.3]=man3/b2i_PVK_bio_ex.pod +DEPEND[html/man3/d2i_PKCS8PrivateKey_bio.html]=man3/d2i_PKCS8PrivateKey_bio.pod +GENERATE[html/man3/d2i_PKCS8PrivateKey_bio.html]=man3/d2i_PKCS8PrivateKey_bio.pod +DEPEND[man/man3/d2i_PKCS8PrivateKey_bio.3]=man3/d2i_PKCS8PrivateKey_bio.pod +GENERATE[man/man3/d2i_PKCS8PrivateKey_bio.3]=man3/d2i_PKCS8PrivateKey_bio.pod +DEPEND[html/man3/d2i_PrivateKey.html]=man3/d2i_PrivateKey.pod +GENERATE[html/man3/d2i_PrivateKey.html]=man3/d2i_PrivateKey.pod +DEPEND[man/man3/d2i_PrivateKey.3]=man3/d2i_PrivateKey.pod +GENERATE[man/man3/d2i_PrivateKey.3]=man3/d2i_PrivateKey.pod +DEPEND[html/man3/d2i_RSAPrivateKey.html]=man3/d2i_RSAPrivateKey.pod +GENERATE[html/man3/d2i_RSAPrivateKey.html]=man3/d2i_RSAPrivateKey.pod +DEPEND[man/man3/d2i_RSAPrivateKey.3]=man3/d2i_RSAPrivateKey.pod +GENERATE[man/man3/d2i_RSAPrivateKey.3]=man3/d2i_RSAPrivateKey.pod +DEPEND[html/man3/d2i_SSL_SESSION.html]=man3/d2i_SSL_SESSION.pod +GENERATE[html/man3/d2i_SSL_SESSION.html]=man3/d2i_SSL_SESSION.pod +DEPEND[man/man3/d2i_SSL_SESSION.3]=man3/d2i_SSL_SESSION.pod +GENERATE[man/man3/d2i_SSL_SESSION.3]=man3/d2i_SSL_SESSION.pod +DEPEND[html/man3/d2i_X509.html]=man3/d2i_X509.pod +GENERATE[html/man3/d2i_X509.html]=man3/d2i_X509.pod +DEPEND[man/man3/d2i_X509.3]=man3/d2i_X509.pod +GENERATE[man/man3/d2i_X509.3]=man3/d2i_X509.pod +DEPEND[html/man3/i2d_CMS_bio_stream.html]=man3/i2d_CMS_bio_stream.pod +GENERATE[html/man3/i2d_CMS_bio_stream.html]=man3/i2d_CMS_bio_stream.pod +DEPEND[man/man3/i2d_CMS_bio_stream.3]=man3/i2d_CMS_bio_stream.pod +GENERATE[man/man3/i2d_CMS_bio_stream.3]=man3/i2d_CMS_bio_stream.pod +DEPEND[html/man3/i2d_PKCS7_bio_stream.html]=man3/i2d_PKCS7_bio_stream.pod +GENERATE[html/man3/i2d_PKCS7_bio_stream.html]=man3/i2d_PKCS7_bio_stream.pod +DEPEND[man/man3/i2d_PKCS7_bio_stream.3]=man3/i2d_PKCS7_bio_stream.pod +GENERATE[man/man3/i2d_PKCS7_bio_stream.3]=man3/i2d_PKCS7_bio_stream.pod +DEPEND[html/man3/i2d_re_X509_tbs.html]=man3/i2d_re_X509_tbs.pod +GENERATE[html/man3/i2d_re_X509_tbs.html]=man3/i2d_re_X509_tbs.pod +DEPEND[man/man3/i2d_re_X509_tbs.3]=man3/i2d_re_X509_tbs.pod +GENERATE[man/man3/i2d_re_X509_tbs.3]=man3/i2d_re_X509_tbs.pod +DEPEND[html/man3/o2i_SCT_LIST.html]=man3/o2i_SCT_LIST.pod +GENERATE[html/man3/o2i_SCT_LIST.html]=man3/o2i_SCT_LIST.pod +DEPEND[man/man3/o2i_SCT_LIST.3]=man3/o2i_SCT_LIST.pod +GENERATE[man/man3/o2i_SCT_LIST.3]=man3/o2i_SCT_LIST.pod +DEPEND[html/man3/s2i_ASN1_IA5STRING.html]=man3/s2i_ASN1_IA5STRING.pod +GENERATE[html/man3/s2i_ASN1_IA5STRING.html]=man3/s2i_ASN1_IA5STRING.pod +DEPEND[man/man3/s2i_ASN1_IA5STRING.3]=man3/s2i_ASN1_IA5STRING.pod +GENERATE[man/man3/s2i_ASN1_IA5STRING.3]=man3/s2i_ASN1_IA5STRING.pod +IMAGEDOCS[man3]= +HTMLDOCS[man3]=html/man3/ADMISSIONS.html \ +html/man3/ASN1_EXTERN_FUNCS.html \ +html/man3/ASN1_INTEGER_get_int64.html \ +html/man3/ASN1_INTEGER_new.html \ +html/man3/ASN1_ITEM_lookup.html \ +html/man3/ASN1_OBJECT_new.html \ +html/man3/ASN1_STRING_TABLE_add.html \ +html/man3/ASN1_STRING_length.html \ +html/man3/ASN1_STRING_new.html \ +html/man3/ASN1_STRING_print_ex.html \ +html/man3/ASN1_TIME_set.html \ +html/man3/ASN1_TYPE_get.html \ +html/man3/ASN1_aux_cb.html \ +html/man3/ASN1_generate_nconf.html \ +html/man3/ASN1_item_d2i_bio.html \ +html/man3/ASN1_item_new.html \ +html/man3/ASN1_item_sign.html \ +html/man3/ASYNC_WAIT_CTX_new.html \ +html/man3/ASYNC_start_job.html \ +html/man3/BF_encrypt.html \ +html/man3/BIO_ADDR.html \ +html/man3/BIO_ADDRINFO.html \ +html/man3/BIO_connect.html \ +html/man3/BIO_ctrl.html \ +html/man3/BIO_f_base64.html \ +html/man3/BIO_f_buffer.html \ +html/man3/BIO_f_cipher.html \ +html/man3/BIO_f_md.html \ +html/man3/BIO_f_null.html \ +html/man3/BIO_f_prefix.html \ +html/man3/BIO_f_readbuffer.html \ +html/man3/BIO_f_ssl.html \ +html/man3/BIO_find_type.html \ +html/man3/BIO_get_data.html \ +html/man3/BIO_get_ex_new_index.html \ +html/man3/BIO_meth_new.html \ +html/man3/BIO_new.html \ +html/man3/BIO_new_CMS.html \ +html/man3/BIO_parse_hostserv.html \ +html/man3/BIO_printf.html \ +html/man3/BIO_push.html \ +html/man3/BIO_read.html \ +html/man3/BIO_s_accept.html \ +html/man3/BIO_s_bio.html \ +html/man3/BIO_s_connect.html \ +html/man3/BIO_s_core.html \ +html/man3/BIO_s_datagram.html \ +html/man3/BIO_s_fd.html \ +html/man3/BIO_s_file.html \ +html/man3/BIO_s_mem.html \ +html/man3/BIO_s_null.html \ +html/man3/BIO_s_socket.html \ +html/man3/BIO_set_callback.html \ +html/man3/BIO_should_retry.html \ +html/man3/BIO_socket_wait.html \ +html/man3/BN_BLINDING_new.html \ +html/man3/BN_CTX_new.html \ +html/man3/BN_CTX_start.html \ +html/man3/BN_add.html \ +html/man3/BN_add_word.html \ +html/man3/BN_bn2bin.html \ +html/man3/BN_cmp.html \ +html/man3/BN_copy.html \ +html/man3/BN_generate_prime.html \ +html/man3/BN_mod_exp_mont.html \ +html/man3/BN_mod_inverse.html \ +html/man3/BN_mod_mul_montgomery.html \ +html/man3/BN_mod_mul_reciprocal.html \ +html/man3/BN_new.html \ +html/man3/BN_num_bytes.html \ +html/man3/BN_rand.html \ +html/man3/BN_security_bits.html \ +html/man3/BN_set_bit.html \ +html/man3/BN_swap.html \ +html/man3/BN_zero.html \ +html/man3/BUF_MEM_new.html \ +html/man3/CMS_EncryptedData_decrypt.html \ +html/man3/CMS_EncryptedData_encrypt.html \ +html/man3/CMS_EnvelopedData_create.html \ +html/man3/CMS_add0_cert.html \ +html/man3/CMS_add1_recipient_cert.html \ +html/man3/CMS_add1_signer.html \ +html/man3/CMS_compress.html \ +html/man3/CMS_data_create.html \ +html/man3/CMS_decrypt.html \ +html/man3/CMS_digest_create.html \ +html/man3/CMS_encrypt.html \ +html/man3/CMS_final.html \ +html/man3/CMS_get0_RecipientInfos.html \ +html/man3/CMS_get0_SignerInfos.html \ +html/man3/CMS_get0_type.html \ +html/man3/CMS_get1_ReceiptRequest.html \ +html/man3/CMS_sign.html \ +html/man3/CMS_sign_receipt.html \ +html/man3/CMS_uncompress.html \ +html/man3/CMS_verify.html \ +html/man3/CMS_verify_receipt.html \ +html/man3/CONF_modules_free.html \ +html/man3/CONF_modules_load_file.html \ +html/man3/CRYPTO_THREAD_run_once.html \ +html/man3/CRYPTO_get_ex_new_index.html \ +html/man3/CRYPTO_memcmp.html \ +html/man3/CTLOG_STORE_get0_log_by_id.html \ +html/man3/CTLOG_STORE_new.html \ +html/man3/CTLOG_new.html \ +html/man3/CT_POLICY_EVAL_CTX_new.html \ +html/man3/DEFINE_STACK_OF.html \ +html/man3/DES_random_key.html \ +html/man3/DH_generate_key.html \ +html/man3/DH_generate_parameters.html \ +html/man3/DH_get0_pqg.html \ +html/man3/DH_get_1024_160.html \ +html/man3/DH_meth_new.html \ +html/man3/DH_new.html \ +html/man3/DH_new_by_nid.html \ +html/man3/DH_set_method.html \ +html/man3/DH_size.html \ +html/man3/DSA_SIG_new.html \ +html/man3/DSA_do_sign.html \ +html/man3/DSA_dup_DH.html \ +html/man3/DSA_generate_key.html \ +html/man3/DSA_generate_parameters.html \ +html/man3/DSA_get0_pqg.html \ +html/man3/DSA_meth_new.html \ +html/man3/DSA_new.html \ +html/man3/DSA_set_method.html \ +html/man3/DSA_sign.html \ +html/man3/DSA_size.html \ +html/man3/DTLS_get_data_mtu.html \ +html/man3/DTLS_set_timer_cb.html \ +html/man3/DTLSv1_listen.html \ +html/man3/ECDSA_SIG_new.html \ +html/man3/ECDSA_sign.html \ +html/man3/ECPKParameters_print.html \ +html/man3/EC_GFp_simple_method.html \ +html/man3/EC_GROUP_copy.html \ +html/man3/EC_GROUP_new.html \ +html/man3/EC_KEY_get_enc_flags.html \ +html/man3/EC_KEY_new.html \ +html/man3/EC_POINT_add.html \ +html/man3/EC_POINT_new.html \ +html/man3/ENGINE_add.html \ +html/man3/ERR_GET_LIB.html \ +html/man3/ERR_clear_error.html \ +html/man3/ERR_error_string.html \ +html/man3/ERR_get_error.html \ +html/man3/ERR_load_crypto_strings.html \ +html/man3/ERR_load_strings.html \ +html/man3/ERR_new.html \ +html/man3/ERR_print_errors.html \ +html/man3/ERR_put_error.html \ +html/man3/ERR_remove_state.html \ +html/man3/ERR_set_mark.html \ +html/man3/EVP_ASYM_CIPHER_free.html \ +html/man3/EVP_BytesToKey.html \ +html/man3/EVP_CIPHER_CTX_get_cipher_data.html \ +html/man3/EVP_CIPHER_CTX_get_original_iv.html \ +html/man3/EVP_CIPHER_meth_new.html \ +html/man3/EVP_DigestInit.html \ +html/man3/EVP_DigestSignInit.html \ +html/man3/EVP_DigestVerifyInit.html \ +html/man3/EVP_EncodeInit.html \ +html/man3/EVP_EncryptInit.html \ +html/man3/EVP_KDF.html \ +html/man3/EVP_KEM_free.html \ +html/man3/EVP_KEYEXCH_free.html \ +html/man3/EVP_KEYMGMT.html \ +html/man3/EVP_MAC.html \ +html/man3/EVP_MD_meth_new.html \ +html/man3/EVP_OpenInit.html \ +html/man3/EVP_PBE_CipherInit.html \ +html/man3/EVP_PKEY2PKCS8.html \ +html/man3/EVP_PKEY_ASN1_METHOD.html \ +html/man3/EVP_PKEY_CTX_ctrl.html \ +html/man3/EVP_PKEY_CTX_get0_libctx.html \ +html/man3/EVP_PKEY_CTX_get0_pkey.html \ +html/man3/EVP_PKEY_CTX_new.html \ +html/man3/EVP_PKEY_CTX_set1_pbe_pass.html \ +html/man3/EVP_PKEY_CTX_set_hkdf_md.html \ +html/man3/EVP_PKEY_CTX_set_params.html \ +html/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.html \ +html/man3/EVP_PKEY_CTX_set_scrypt_N.html \ +html/man3/EVP_PKEY_CTX_set_tls1_prf_md.html \ +html/man3/EVP_PKEY_asn1_get_count.html \ +html/man3/EVP_PKEY_check.html \ +html/man3/EVP_PKEY_copy_parameters.html \ +html/man3/EVP_PKEY_decapsulate.html \ +html/man3/EVP_PKEY_decrypt.html \ +html/man3/EVP_PKEY_derive.html \ +html/man3/EVP_PKEY_digestsign_supports_digest.html \ +html/man3/EVP_PKEY_encapsulate.html \ +html/man3/EVP_PKEY_encrypt.html \ +html/man3/EVP_PKEY_fromdata.html \ +html/man3/EVP_PKEY_get_default_digest_nid.html \ +html/man3/EVP_PKEY_get_field_type.html \ +html/man3/EVP_PKEY_get_group_name.html \ +html/man3/EVP_PKEY_get_size.html \ +html/man3/EVP_PKEY_gettable_params.html \ +html/man3/EVP_PKEY_is_a.html \ +html/man3/EVP_PKEY_keygen.html \ +html/man3/EVP_PKEY_meth_get_count.html \ +html/man3/EVP_PKEY_meth_new.html \ +html/man3/EVP_PKEY_new.html \ +html/man3/EVP_PKEY_print_private.html \ +html/man3/EVP_PKEY_set1_RSA.html \ +html/man3/EVP_PKEY_set1_encoded_public_key.html \ +html/man3/EVP_PKEY_set_type.html \ +html/man3/EVP_PKEY_settable_params.html \ +html/man3/EVP_PKEY_sign.html \ +html/man3/EVP_PKEY_todata.html \ +html/man3/EVP_PKEY_verify.html \ +html/man3/EVP_PKEY_verify_recover.html \ +html/man3/EVP_RAND.html \ +html/man3/EVP_SIGNATURE.html \ +html/man3/EVP_SealInit.html \ +html/man3/EVP_SignInit.html \ +html/man3/EVP_VerifyInit.html \ +html/man3/EVP_aes_128_gcm.html \ +html/man3/EVP_aria_128_gcm.html \ +html/man3/EVP_bf_cbc.html \ +html/man3/EVP_blake2b512.html \ +html/man3/EVP_camellia_128_ecb.html \ +html/man3/EVP_cast5_cbc.html \ +html/man3/EVP_chacha20.html \ +html/man3/EVP_des_cbc.html \ +html/man3/EVP_desx_cbc.html \ +html/man3/EVP_idea_cbc.html \ +html/man3/EVP_md2.html \ +html/man3/EVP_md4.html \ +html/man3/EVP_md5.html \ +html/man3/EVP_mdc2.html \ +html/man3/EVP_rc2_cbc.html \ +html/man3/EVP_rc4.html \ +html/man3/EVP_rc5_32_12_16_cbc.html \ +html/man3/EVP_ripemd160.html \ +html/man3/EVP_seed_cbc.html \ +html/man3/EVP_set_default_properties.html \ +html/man3/EVP_sha1.html \ +html/man3/EVP_sha224.html \ +html/man3/EVP_sha3_224.html \ +html/man3/EVP_sm3.html \ +html/man3/EVP_sm4_cbc.html \ +html/man3/EVP_whirlpool.html \ +html/man3/HMAC.html \ +html/man3/MD5.html \ +html/man3/MDC2_Init.html \ +html/man3/NCONF_new_ex.html \ +html/man3/OBJ_nid2obj.html \ +html/man3/OCSP_REQUEST_new.html \ +html/man3/OCSP_cert_to_id.html \ +html/man3/OCSP_request_add1_nonce.html \ +html/man3/OCSP_resp_find_status.html \ +html/man3/OCSP_response_status.html \ +html/man3/OCSP_sendreq_new.html \ +html/man3/OPENSSL_Applink.html \ +html/man3/OPENSSL_FILE.html \ +html/man3/OPENSSL_LH_COMPFUNC.html \ +html/man3/OPENSSL_LH_stats.html \ +html/man3/OPENSSL_config.html \ +html/man3/OPENSSL_fork_prepare.html \ +html/man3/OPENSSL_gmtime.html \ +html/man3/OPENSSL_hexchar2int.html \ +html/man3/OPENSSL_ia32cap.html \ +html/man3/OPENSSL_init_crypto.html \ +html/man3/OPENSSL_init_ssl.html \ +html/man3/OPENSSL_instrument_bus.html \ +html/man3/OPENSSL_load_builtin_modules.html \ +html/man3/OPENSSL_malloc.html \ +html/man3/OPENSSL_s390xcap.html \ +html/man3/OPENSSL_secure_malloc.html \ +html/man3/OPENSSL_strcasecmp.html \ +html/man3/OSSL_ALGORITHM.html \ +html/man3/OSSL_CALLBACK.html \ +html/man3/OSSL_CMP_CTX_new.html \ +html/man3/OSSL_CMP_HDR_get0_transactionID.html \ +html/man3/OSSL_CMP_ITAV_set0.html \ +html/man3/OSSL_CMP_MSG_get0_header.html \ +html/man3/OSSL_CMP_MSG_http_perform.html \ +html/man3/OSSL_CMP_SRV_CTX_new.html \ +html/man3/OSSL_CMP_STATUSINFO_new.html \ +html/man3/OSSL_CMP_exec_certreq.html \ +html/man3/OSSL_CMP_log_open.html \ +html/man3/OSSL_CMP_validate_msg.html \ +html/man3/OSSL_CORE_MAKE_FUNC.html \ +html/man3/OSSL_CRMF_MSG_get0_tmpl.html \ +html/man3/OSSL_CRMF_MSG_set0_validity.html \ +html/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.html \ +html/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.html \ +html/man3/OSSL_CRMF_pbmp_new.html \ +html/man3/OSSL_DECODER.html \ +html/man3/OSSL_DECODER_CTX.html \ +html/man3/OSSL_DECODER_CTX_new_for_pkey.html \ +html/man3/OSSL_DECODER_from_bio.html \ +html/man3/OSSL_DISPATCH.html \ +html/man3/OSSL_ENCODER.html \ +html/man3/OSSL_ENCODER_CTX.html \ +html/man3/OSSL_ENCODER_CTX_new_for_pkey.html \ +html/man3/OSSL_ENCODER_to_bio.html \ +html/man3/OSSL_ESS_check_signing_certs.html \ +html/man3/OSSL_HTTP_REQ_CTX.html \ +html/man3/OSSL_HTTP_parse_url.html \ +html/man3/OSSL_HTTP_transfer.html \ +html/man3/OSSL_ITEM.html \ +html/man3/OSSL_LIB_CTX.html \ +html/man3/OSSL_PARAM.html \ +html/man3/OSSL_PARAM_BLD.html \ +html/man3/OSSL_PARAM_allocate_from_text.html \ +html/man3/OSSL_PARAM_dup.html \ +html/man3/OSSL_PARAM_int.html \ +html/man3/OSSL_PROVIDER.html \ +html/man3/OSSL_SELF_TEST_new.html \ +html/man3/OSSL_SELF_TEST_set_callback.html \ +html/man3/OSSL_STORE_INFO.html \ +html/man3/OSSL_STORE_LOADER.html \ +html/man3/OSSL_STORE_SEARCH.html \ +html/man3/OSSL_STORE_attach.html \ +html/man3/OSSL_STORE_expect.html \ +html/man3/OSSL_STORE_open.html \ +html/man3/OSSL_trace_enabled.html \ +html/man3/OSSL_trace_get_category_num.html \ +html/man3/OSSL_trace_set_channel.html \ +html/man3/OpenSSL_add_all_algorithms.html \ +html/man3/OpenSSL_version.html \ +html/man3/PEM_X509_INFO_read_bio_ex.html \ +html/man3/PEM_bytes_read_bio.html \ +html/man3/PEM_read.html \ +html/man3/PEM_read_CMS.html \ +html/man3/PEM_read_bio_PrivateKey.html \ +html/man3/PEM_read_bio_ex.html \ +html/man3/PEM_write_bio_CMS_stream.html \ +html/man3/PEM_write_bio_PKCS7_stream.html \ +html/man3/PKCS12_PBE_keyivgen.html \ +html/man3/PKCS12_SAFEBAG_create_cert.html \ +html/man3/PKCS12_SAFEBAG_get0_attrs.html \ +html/man3/PKCS12_SAFEBAG_get1_cert.html \ +html/man3/PKCS12_add1_attr_by_NID.html \ +html/man3/PKCS12_add_CSPName_asc.html \ +html/man3/PKCS12_add_cert.html \ +html/man3/PKCS12_add_friendlyname_asc.html \ +html/man3/PKCS12_add_localkeyid.html \ +html/man3/PKCS12_add_safe.html \ +html/man3/PKCS12_create.html \ +html/man3/PKCS12_decrypt_skey.html \ +html/man3/PKCS12_gen_mac.html \ +html/man3/PKCS12_get_friendlyname.html \ +html/man3/PKCS12_init.html \ +html/man3/PKCS12_item_decrypt_d2i.html \ +html/man3/PKCS12_key_gen_utf8_ex.html \ +html/man3/PKCS12_newpass.html \ +html/man3/PKCS12_pack_p7encdata.html \ +html/man3/PKCS12_parse.html \ +html/man3/PKCS5_PBE_keyivgen.html \ +html/man3/PKCS5_PBKDF2_HMAC.html \ +html/man3/PKCS7_decrypt.html \ +html/man3/PKCS7_encrypt.html \ +html/man3/PKCS7_get_octet_string.html \ +html/man3/PKCS7_sign.html \ +html/man3/PKCS7_sign_add_signer.html \ +html/man3/PKCS7_type_is_other.html \ +html/man3/PKCS7_verify.html \ +html/man3/PKCS8_encrypt.html \ +html/man3/PKCS8_pkey_add1_attr.html \ +html/man3/RAND_add.html \ +html/man3/RAND_bytes.html \ +html/man3/RAND_cleanup.html \ +html/man3/RAND_egd.html \ +html/man3/RAND_get0_primary.html \ +html/man3/RAND_load_file.html \ +html/man3/RAND_set_DRBG_type.html \ +html/man3/RAND_set_rand_method.html \ +html/man3/RC4_set_key.html \ +html/man3/RIPEMD160_Init.html \ +html/man3/RSA_blinding_on.html \ +html/man3/RSA_check_key.html \ +html/man3/RSA_generate_key.html \ +html/man3/RSA_get0_key.html \ +html/man3/RSA_meth_new.html \ +html/man3/RSA_new.html \ +html/man3/RSA_padding_add_PKCS1_type_1.html \ +html/man3/RSA_print.html \ +html/man3/RSA_private_encrypt.html \ +html/man3/RSA_public_encrypt.html \ +html/man3/RSA_set_method.html \ +html/man3/RSA_sign.html \ +html/man3/RSA_sign_ASN1_OCTET_STRING.html \ +html/man3/RSA_size.html \ +html/man3/SCT_new.html \ +html/man3/SCT_print.html \ +html/man3/SCT_validate.html \ +html/man3/SHA256_Init.html \ +html/man3/SMIME_read_ASN1.html \ +html/man3/SMIME_read_CMS.html \ +html/man3/SMIME_read_PKCS7.html \ +html/man3/SMIME_write_ASN1.html \ +html/man3/SMIME_write_CMS.html \ +html/man3/SMIME_write_PKCS7.html \ +html/man3/SRP_Calc_B.html \ +html/man3/SRP_VBASE_new.html \ +html/man3/SRP_create_verifier.html \ +html/man3/SRP_user_pwd_new.html \ +html/man3/SSL_CIPHER_get_name.html \ +html/man3/SSL_COMP_add_compression_method.html \ +html/man3/SSL_CONF_CTX_new.html \ +html/man3/SSL_CONF_CTX_set1_prefix.html \ +html/man3/SSL_CONF_CTX_set_flags.html \ +html/man3/SSL_CONF_CTX_set_ssl_ctx.html \ +html/man3/SSL_CONF_cmd.html \ +html/man3/SSL_CONF_cmd_argv.html \ +html/man3/SSL_CTX_add1_chain_cert.html \ +html/man3/SSL_CTX_add_extra_chain_cert.html \ +html/man3/SSL_CTX_add_session.html \ +html/man3/SSL_CTX_config.html \ +html/man3/SSL_CTX_ctrl.html \ +html/man3/SSL_CTX_dane_enable.html \ +html/man3/SSL_CTX_flush_sessions.html \ +html/man3/SSL_CTX_free.html \ +html/man3/SSL_CTX_get0_param.html \ +html/man3/SSL_CTX_get_verify_mode.html \ +html/man3/SSL_CTX_has_client_custom_ext.html \ +html/man3/SSL_CTX_load_verify_locations.html \ +html/man3/SSL_CTX_new.html \ +html/man3/SSL_CTX_sess_number.html \ +html/man3/SSL_CTX_sess_set_cache_size.html \ +html/man3/SSL_CTX_sess_set_get_cb.html \ +html/man3/SSL_CTX_sessions.html \ +html/man3/SSL_CTX_set0_CA_list.html \ +html/man3/SSL_CTX_set1_curves.html \ +html/man3/SSL_CTX_set1_sigalgs.html \ +html/man3/SSL_CTX_set1_verify_cert_store.html \ +html/man3/SSL_CTX_set_alpn_select_cb.html \ +html/man3/SSL_CTX_set_cert_cb.html \ +html/man3/SSL_CTX_set_cert_store.html \ +html/man3/SSL_CTX_set_cert_verify_callback.html \ +html/man3/SSL_CTX_set_cipher_list.html \ +html/man3/SSL_CTX_set_client_cert_cb.html \ +html/man3/SSL_CTX_set_client_hello_cb.html \ +html/man3/SSL_CTX_set_ct_validation_callback.html \ +html/man3/SSL_CTX_set_ctlog_list_file.html \ +html/man3/SSL_CTX_set_default_passwd_cb.html \ +html/man3/SSL_CTX_set_generate_session_id.html \ +html/man3/SSL_CTX_set_info_callback.html \ +html/man3/SSL_CTX_set_keylog_callback.html \ +html/man3/SSL_CTX_set_max_cert_list.html \ +html/man3/SSL_CTX_set_min_proto_version.html \ +html/man3/SSL_CTX_set_mode.html \ +html/man3/SSL_CTX_set_msg_callback.html \ +html/man3/SSL_CTX_set_num_tickets.html \ +html/man3/SSL_CTX_set_options.html \ +html/man3/SSL_CTX_set_psk_client_callback.html \ +html/man3/SSL_CTX_set_quiet_shutdown.html \ +html/man3/SSL_CTX_set_read_ahead.html \ +html/man3/SSL_CTX_set_record_padding_callback.html \ +html/man3/SSL_CTX_set_security_level.html \ +html/man3/SSL_CTX_set_session_cache_mode.html \ +html/man3/SSL_CTX_set_session_id_context.html \ +html/man3/SSL_CTX_set_session_ticket_cb.html \ +html/man3/SSL_CTX_set_split_send_fragment.html \ +html/man3/SSL_CTX_set_srp_password.html \ +html/man3/SSL_CTX_set_ssl_version.html \ +html/man3/SSL_CTX_set_stateless_cookie_generate_cb.html \ +html/man3/SSL_CTX_set_timeout.html \ +html/man3/SSL_CTX_set_tlsext_servername_callback.html \ +html/man3/SSL_CTX_set_tlsext_status_cb.html \ +html/man3/SSL_CTX_set_tlsext_ticket_key_cb.html \ +html/man3/SSL_CTX_set_tlsext_use_srtp.html \ +html/man3/SSL_CTX_set_tmp_dh_callback.html \ +html/man3/SSL_CTX_set_tmp_ecdh.html \ +html/man3/SSL_CTX_set_verify.html \ +html/man3/SSL_CTX_use_certificate.html \ +html/man3/SSL_CTX_use_psk_identity_hint.html \ +html/man3/SSL_CTX_use_serverinfo.html \ +html/man3/SSL_SESSION_free.html \ +html/man3/SSL_SESSION_get0_cipher.html \ +html/man3/SSL_SESSION_get0_hostname.html \ +html/man3/SSL_SESSION_get0_id_context.html \ +html/man3/SSL_SESSION_get0_peer.html \ +html/man3/SSL_SESSION_get_compress_id.html \ +html/man3/SSL_SESSION_get_protocol_version.html \ +html/man3/SSL_SESSION_get_time.html \ +html/man3/SSL_SESSION_has_ticket.html \ +html/man3/SSL_SESSION_is_resumable.html \ +html/man3/SSL_SESSION_print.html \ +html/man3/SSL_SESSION_set1_id.html \ +html/man3/SSL_accept.html \ +html/man3/SSL_alert_type_string.html \ +html/man3/SSL_alloc_buffers.html \ +html/man3/SSL_check_chain.html \ +html/man3/SSL_clear.html \ +html/man3/SSL_connect.html \ +html/man3/SSL_do_handshake.html \ +html/man3/SSL_export_keying_material.html \ +html/man3/SSL_extension_supported.html \ +html/man3/SSL_free.html \ +html/man3/SSL_get0_peer_scts.html \ +html/man3/SSL_get_SSL_CTX.html \ +html/man3/SSL_get_all_async_fds.html \ +html/man3/SSL_get_certificate.html \ +html/man3/SSL_get_ciphers.html \ +html/man3/SSL_get_client_random.html \ +html/man3/SSL_get_current_cipher.html \ +html/man3/SSL_get_default_timeout.html \ +html/man3/SSL_get_error.html \ +html/man3/SSL_get_extms_support.html \ +html/man3/SSL_get_fd.html \ +html/man3/SSL_get_peer_cert_chain.html \ +html/man3/SSL_get_peer_certificate.html \ +html/man3/SSL_get_peer_signature_nid.html \ +html/man3/SSL_get_peer_tmp_key.html \ +html/man3/SSL_get_psk_identity.html \ +html/man3/SSL_get_rbio.html \ +html/man3/SSL_get_session.html \ +html/man3/SSL_get_shared_sigalgs.html \ +html/man3/SSL_get_verify_result.html \ +html/man3/SSL_get_version.html \ +html/man3/SSL_group_to_name.html \ +html/man3/SSL_in_init.html \ +html/man3/SSL_key_update.html \ +html/man3/SSL_library_init.html \ +html/man3/SSL_load_client_CA_file.html \ +html/man3/SSL_new.html \ +html/man3/SSL_pending.html \ +html/man3/SSL_read.html \ +html/man3/SSL_read_early_data.html \ +html/man3/SSL_rstate_string.html \ +html/man3/SSL_session_reused.html \ +html/man3/SSL_set1_host.html \ +html/man3/SSL_set_async_callback.html \ +html/man3/SSL_set_bio.html \ +html/man3/SSL_set_connect_state.html \ +html/man3/SSL_set_fd.html \ +html/man3/SSL_set_retry_verify.html \ +html/man3/SSL_set_session.html \ +html/man3/SSL_set_shutdown.html \ +html/man3/SSL_set_verify_result.html \ +html/man3/SSL_shutdown.html \ +html/man3/SSL_state_string.html \ +html/man3/SSL_want.html \ +html/man3/SSL_write.html \ +html/man3/TS_RESP_CTX_new.html \ +html/man3/TS_VERIFY_CTX_set_certs.html \ +html/man3/UI_STRING.html \ +html/man3/UI_UTIL_read_pw.html \ +html/man3/UI_create_method.html \ +html/man3/UI_new.html \ +html/man3/X509V3_get_d2i.html \ +html/man3/X509V3_set_ctx.html \ +html/man3/X509_ALGOR_dup.html \ +html/man3/X509_CRL_get0_by_serial.html \ +html/man3/X509_EXTENSION_set_object.html \ +html/man3/X509_LOOKUP.html \ +html/man3/X509_LOOKUP_hash_dir.html \ +html/man3/X509_LOOKUP_meth_new.html \ +html/man3/X509_NAME_ENTRY_get_object.html \ +html/man3/X509_NAME_add_entry_by_txt.html \ +html/man3/X509_NAME_get0_der.html \ +html/man3/X509_NAME_get_index_by_NID.html \ +html/man3/X509_NAME_print_ex.html \ +html/man3/X509_PUBKEY_new.html \ +html/man3/X509_SIG_get0.html \ +html/man3/X509_STORE_CTX_get_error.html \ +html/man3/X509_STORE_CTX_new.html \ +html/man3/X509_STORE_CTX_set_verify_cb.html \ +html/man3/X509_STORE_add_cert.html \ +html/man3/X509_STORE_get0_param.html \ +html/man3/X509_STORE_new.html \ +html/man3/X509_STORE_set_verify_cb_func.html \ +html/man3/X509_VERIFY_PARAM_set_flags.html \ +html/man3/X509_add_cert.html \ +html/man3/X509_check_ca.html \ +html/man3/X509_check_host.html \ +html/man3/X509_check_issued.html \ +html/man3/X509_check_private_key.html \ +html/man3/X509_check_purpose.html \ +html/man3/X509_cmp.html \ +html/man3/X509_cmp_time.html \ +html/man3/X509_digest.html \ +html/man3/X509_dup.html \ +html/man3/X509_get0_distinguishing_id.html \ +html/man3/X509_get0_notBefore.html \ +html/man3/X509_get0_signature.html \ +html/man3/X509_get0_uids.html \ +html/man3/X509_get_extension_flags.html \ +html/man3/X509_get_pubkey.html \ +html/man3/X509_get_serialNumber.html \ +html/man3/X509_get_subject_name.html \ +html/man3/X509_get_version.html \ +html/man3/X509_load_http.html \ +html/man3/X509_new.html \ +html/man3/X509_sign.html \ +html/man3/X509_verify.html \ +html/man3/X509_verify_cert.html \ +html/man3/X509v3_get_ext_by_NID.html \ +html/man3/b2i_PVK_bio_ex.html \ +html/man3/d2i_PKCS8PrivateKey_bio.html \ +html/man3/d2i_PrivateKey.html \ +html/man3/d2i_RSAPrivateKey.html \ +html/man3/d2i_SSL_SESSION.html \ +html/man3/d2i_X509.html \ +html/man3/i2d_CMS_bio_stream.html \ +html/man3/i2d_PKCS7_bio_stream.html \ +html/man3/i2d_re_X509_tbs.html \ +html/man3/o2i_SCT_LIST.html \ +html/man3/s2i_ASN1_IA5STRING.html +MANDOCS[man3]=man/man3/ADMISSIONS.3 \ +man/man3/ASN1_EXTERN_FUNCS.3 \ +man/man3/ASN1_INTEGER_get_int64.3 \ +man/man3/ASN1_INTEGER_new.3 \ +man/man3/ASN1_ITEM_lookup.3 \ +man/man3/ASN1_OBJECT_new.3 \ +man/man3/ASN1_STRING_TABLE_add.3 \ +man/man3/ASN1_STRING_length.3 \ +man/man3/ASN1_STRING_new.3 \ +man/man3/ASN1_STRING_print_ex.3 \ +man/man3/ASN1_TIME_set.3 \ +man/man3/ASN1_TYPE_get.3 \ +man/man3/ASN1_aux_cb.3 \ +man/man3/ASN1_generate_nconf.3 \ +man/man3/ASN1_item_d2i_bio.3 \ +man/man3/ASN1_item_new.3 \ +man/man3/ASN1_item_sign.3 \ +man/man3/ASYNC_WAIT_CTX_new.3 \ +man/man3/ASYNC_start_job.3 \ +man/man3/BF_encrypt.3 \ +man/man3/BIO_ADDR.3 \ +man/man3/BIO_ADDRINFO.3 \ +man/man3/BIO_connect.3 \ +man/man3/BIO_ctrl.3 \ +man/man3/BIO_f_base64.3 \ +man/man3/BIO_f_buffer.3 \ +man/man3/BIO_f_cipher.3 \ +man/man3/BIO_f_md.3 \ +man/man3/BIO_f_null.3 \ +man/man3/BIO_f_prefix.3 \ +man/man3/BIO_f_readbuffer.3 \ +man/man3/BIO_f_ssl.3 \ +man/man3/BIO_find_type.3 \ +man/man3/BIO_get_data.3 \ +man/man3/BIO_get_ex_new_index.3 \ +man/man3/BIO_meth_new.3 \ +man/man3/BIO_new.3 \ +man/man3/BIO_new_CMS.3 \ +man/man3/BIO_parse_hostserv.3 \ +man/man3/BIO_printf.3 \ +man/man3/BIO_push.3 \ +man/man3/BIO_read.3 \ +man/man3/BIO_s_accept.3 \ +man/man3/BIO_s_bio.3 \ +man/man3/BIO_s_connect.3 \ +man/man3/BIO_s_core.3 \ +man/man3/BIO_s_datagram.3 \ +man/man3/BIO_s_fd.3 \ +man/man3/BIO_s_file.3 \ +man/man3/BIO_s_mem.3 \ +man/man3/BIO_s_null.3 \ +man/man3/BIO_s_socket.3 \ +man/man3/BIO_set_callback.3 \ +man/man3/BIO_should_retry.3 \ +man/man3/BIO_socket_wait.3 \ +man/man3/BN_BLINDING_new.3 \ +man/man3/BN_CTX_new.3 \ +man/man3/BN_CTX_start.3 \ +man/man3/BN_add.3 \ +man/man3/BN_add_word.3 \ +man/man3/BN_bn2bin.3 \ +man/man3/BN_cmp.3 \ +man/man3/BN_copy.3 \ +man/man3/BN_generate_prime.3 \ +man/man3/BN_mod_exp_mont.3 \ +man/man3/BN_mod_inverse.3 \ +man/man3/BN_mod_mul_montgomery.3 \ +man/man3/BN_mod_mul_reciprocal.3 \ +man/man3/BN_new.3 \ +man/man3/BN_num_bytes.3 \ +man/man3/BN_rand.3 \ +man/man3/BN_security_bits.3 \ +man/man3/BN_set_bit.3 \ +man/man3/BN_swap.3 \ +man/man3/BN_zero.3 \ +man/man3/BUF_MEM_new.3 \ +man/man3/CMS_EncryptedData_decrypt.3 \ +man/man3/CMS_EncryptedData_encrypt.3 \ +man/man3/CMS_EnvelopedData_create.3 \ +man/man3/CMS_add0_cert.3 \ +man/man3/CMS_add1_recipient_cert.3 \ +man/man3/CMS_add1_signer.3 \ +man/man3/CMS_compress.3 \ +man/man3/CMS_data_create.3 \ +man/man3/CMS_decrypt.3 \ +man/man3/CMS_digest_create.3 \ +man/man3/CMS_encrypt.3 \ +man/man3/CMS_final.3 \ +man/man3/CMS_get0_RecipientInfos.3 \ +man/man3/CMS_get0_SignerInfos.3 \ +man/man3/CMS_get0_type.3 \ +man/man3/CMS_get1_ReceiptRequest.3 \ +man/man3/CMS_sign.3 \ +man/man3/CMS_sign_receipt.3 \ +man/man3/CMS_uncompress.3 \ +man/man3/CMS_verify.3 \ +man/man3/CMS_verify_receipt.3 \ +man/man3/CONF_modules_free.3 \ +man/man3/CONF_modules_load_file.3 \ +man/man3/CRYPTO_THREAD_run_once.3 \ +man/man3/CRYPTO_get_ex_new_index.3 \ +man/man3/CRYPTO_memcmp.3 \ +man/man3/CTLOG_STORE_get0_log_by_id.3 \ +man/man3/CTLOG_STORE_new.3 \ +man/man3/CTLOG_new.3 \ +man/man3/CT_POLICY_EVAL_CTX_new.3 \ +man/man3/DEFINE_STACK_OF.3 \ +man/man3/DES_random_key.3 \ +man/man3/DH_generate_key.3 \ +man/man3/DH_generate_parameters.3 \ +man/man3/DH_get0_pqg.3 \ +man/man3/DH_get_1024_160.3 \ +man/man3/DH_meth_new.3 \ +man/man3/DH_new.3 \ +man/man3/DH_new_by_nid.3 \ +man/man3/DH_set_method.3 \ +man/man3/DH_size.3 \ +man/man3/DSA_SIG_new.3 \ +man/man3/DSA_do_sign.3 \ +man/man3/DSA_dup_DH.3 \ +man/man3/DSA_generate_key.3 \ +man/man3/DSA_generate_parameters.3 \ +man/man3/DSA_get0_pqg.3 \ +man/man3/DSA_meth_new.3 \ +man/man3/DSA_new.3 \ +man/man3/DSA_set_method.3 \ +man/man3/DSA_sign.3 \ +man/man3/DSA_size.3 \ +man/man3/DTLS_get_data_mtu.3 \ +man/man3/DTLS_set_timer_cb.3 \ +man/man3/DTLSv1_listen.3 \ +man/man3/ECDSA_SIG_new.3 \ +man/man3/ECDSA_sign.3 \ +man/man3/ECPKParameters_print.3 \ +man/man3/EC_GFp_simple_method.3 \ +man/man3/EC_GROUP_copy.3 \ +man/man3/EC_GROUP_new.3 \ +man/man3/EC_KEY_get_enc_flags.3 \ +man/man3/EC_KEY_new.3 \ +man/man3/EC_POINT_add.3 \ +man/man3/EC_POINT_new.3 \ +man/man3/ENGINE_add.3 \ +man/man3/ERR_GET_LIB.3 \ +man/man3/ERR_clear_error.3 \ +man/man3/ERR_error_string.3 \ +man/man3/ERR_get_error.3 \ +man/man3/ERR_load_crypto_strings.3 \ +man/man3/ERR_load_strings.3 \ +man/man3/ERR_new.3 \ +man/man3/ERR_print_errors.3 \ +man/man3/ERR_put_error.3 \ +man/man3/ERR_remove_state.3 \ +man/man3/ERR_set_mark.3 \ +man/man3/EVP_ASYM_CIPHER_free.3 \ +man/man3/EVP_BytesToKey.3 \ +man/man3/EVP_CIPHER_CTX_get_cipher_data.3 \ +man/man3/EVP_CIPHER_CTX_get_original_iv.3 \ +man/man3/EVP_CIPHER_meth_new.3 \ +man/man3/EVP_DigestInit.3 \ +man/man3/EVP_DigestSignInit.3 \ +man/man3/EVP_DigestVerifyInit.3 \ +man/man3/EVP_EncodeInit.3 \ +man/man3/EVP_EncryptInit.3 \ +man/man3/EVP_KDF.3 \ +man/man3/EVP_KEM_free.3 \ +man/man3/EVP_KEYEXCH_free.3 \ +man/man3/EVP_KEYMGMT.3 \ +man/man3/EVP_MAC.3 \ +man/man3/EVP_MD_meth_new.3 \ +man/man3/EVP_OpenInit.3 \ +man/man3/EVP_PBE_CipherInit.3 \ +man/man3/EVP_PKEY2PKCS8.3 \ +man/man3/EVP_PKEY_ASN1_METHOD.3 \ +man/man3/EVP_PKEY_CTX_ctrl.3 \ +man/man3/EVP_PKEY_CTX_get0_libctx.3 \ +man/man3/EVP_PKEY_CTX_get0_pkey.3 \ +man/man3/EVP_PKEY_CTX_new.3 \ +man/man3/EVP_PKEY_CTX_set1_pbe_pass.3 \ +man/man3/EVP_PKEY_CTX_set_hkdf_md.3 \ +man/man3/EVP_PKEY_CTX_set_params.3 \ +man/man3/EVP_PKEY_CTX_set_rsa_pss_keygen_md.3 \ +man/man3/EVP_PKEY_CTX_set_scrypt_N.3 \ +man/man3/EVP_PKEY_CTX_set_tls1_prf_md.3 \ +man/man3/EVP_PKEY_asn1_get_count.3 \ +man/man3/EVP_PKEY_check.3 \ +man/man3/EVP_PKEY_copy_parameters.3 \ +man/man3/EVP_PKEY_decapsulate.3 \ +man/man3/EVP_PKEY_decrypt.3 \ +man/man3/EVP_PKEY_derive.3 \ +man/man3/EVP_PKEY_digestsign_supports_digest.3 \ +man/man3/EVP_PKEY_encapsulate.3 \ +man/man3/EVP_PKEY_encrypt.3 \ +man/man3/EVP_PKEY_fromdata.3 \ +man/man3/EVP_PKEY_get_default_digest_nid.3 \ +man/man3/EVP_PKEY_get_field_type.3 \ +man/man3/EVP_PKEY_get_group_name.3 \ +man/man3/EVP_PKEY_get_size.3 \ +man/man3/EVP_PKEY_gettable_params.3 \ +man/man3/EVP_PKEY_is_a.3 \ +man/man3/EVP_PKEY_keygen.3 \ +man/man3/EVP_PKEY_meth_get_count.3 \ +man/man3/EVP_PKEY_meth_new.3 \ +man/man3/EVP_PKEY_new.3 \ +man/man3/EVP_PKEY_print_private.3 \ +man/man3/EVP_PKEY_set1_RSA.3 \ +man/man3/EVP_PKEY_set1_encoded_public_key.3 \ +man/man3/EVP_PKEY_set_type.3 \ +man/man3/EVP_PKEY_settable_params.3 \ +man/man3/EVP_PKEY_sign.3 \ +man/man3/EVP_PKEY_todata.3 \ +man/man3/EVP_PKEY_verify.3 \ +man/man3/EVP_PKEY_verify_recover.3 \ +man/man3/EVP_RAND.3 \ +man/man3/EVP_SIGNATURE.3 \ +man/man3/EVP_SealInit.3 \ +man/man3/EVP_SignInit.3 \ +man/man3/EVP_VerifyInit.3 \ +man/man3/EVP_aes_128_gcm.3 \ +man/man3/EVP_aria_128_gcm.3 \ +man/man3/EVP_bf_cbc.3 \ +man/man3/EVP_blake2b512.3 \ +man/man3/EVP_camellia_128_ecb.3 \ +man/man3/EVP_cast5_cbc.3 \ +man/man3/EVP_chacha20.3 \ +man/man3/EVP_des_cbc.3 \ +man/man3/EVP_desx_cbc.3 \ +man/man3/EVP_idea_cbc.3 \ +man/man3/EVP_md2.3 \ +man/man3/EVP_md4.3 \ +man/man3/EVP_md5.3 \ +man/man3/EVP_mdc2.3 \ +man/man3/EVP_rc2_cbc.3 \ +man/man3/EVP_rc4.3 \ +man/man3/EVP_rc5_32_12_16_cbc.3 \ +man/man3/EVP_ripemd160.3 \ +man/man3/EVP_seed_cbc.3 \ +man/man3/EVP_set_default_properties.3 \ +man/man3/EVP_sha1.3 \ +man/man3/EVP_sha224.3 \ +man/man3/EVP_sha3_224.3 \ +man/man3/EVP_sm3.3 \ +man/man3/EVP_sm4_cbc.3 \ +man/man3/EVP_whirlpool.3 \ +man/man3/HMAC.3 \ +man/man3/MD5.3 \ +man/man3/MDC2_Init.3 \ +man/man3/NCONF_new_ex.3 \ +man/man3/OBJ_nid2obj.3 \ +man/man3/OCSP_REQUEST_new.3 \ +man/man3/OCSP_cert_to_id.3 \ +man/man3/OCSP_request_add1_nonce.3 \ +man/man3/OCSP_resp_find_status.3 \ +man/man3/OCSP_response_status.3 \ +man/man3/OCSP_sendreq_new.3 \ +man/man3/OPENSSL_Applink.3 \ +man/man3/OPENSSL_FILE.3 \ +man/man3/OPENSSL_LH_COMPFUNC.3 \ +man/man3/OPENSSL_LH_stats.3 \ +man/man3/OPENSSL_config.3 \ +man/man3/OPENSSL_fork_prepare.3 \ +man/man3/OPENSSL_gmtime.3 \ +man/man3/OPENSSL_hexchar2int.3 \ +man/man3/OPENSSL_ia32cap.3 \ +man/man3/OPENSSL_init_crypto.3 \ +man/man3/OPENSSL_init_ssl.3 \ +man/man3/OPENSSL_instrument_bus.3 \ +man/man3/OPENSSL_load_builtin_modules.3 \ +man/man3/OPENSSL_malloc.3 \ +man/man3/OPENSSL_s390xcap.3 \ +man/man3/OPENSSL_secure_malloc.3 \ +man/man3/OPENSSL_strcasecmp.3 \ +man/man3/OSSL_ALGORITHM.3 \ +man/man3/OSSL_CALLBACK.3 \ +man/man3/OSSL_CMP_CTX_new.3 \ +man/man3/OSSL_CMP_HDR_get0_transactionID.3 \ +man/man3/OSSL_CMP_ITAV_set0.3 \ +man/man3/OSSL_CMP_MSG_get0_header.3 \ +man/man3/OSSL_CMP_MSG_http_perform.3 \ +man/man3/OSSL_CMP_SRV_CTX_new.3 \ +man/man3/OSSL_CMP_STATUSINFO_new.3 \ +man/man3/OSSL_CMP_exec_certreq.3 \ +man/man3/OSSL_CMP_log_open.3 \ +man/man3/OSSL_CMP_validate_msg.3 \ +man/man3/OSSL_CORE_MAKE_FUNC.3 \ +man/man3/OSSL_CRMF_MSG_get0_tmpl.3 \ +man/man3/OSSL_CRMF_MSG_set0_validity.3 \ +man/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.3 \ +man/man3/OSSL_CRMF_MSG_set1_regInfo_certReq.3 \ +man/man3/OSSL_CRMF_pbmp_new.3 \ +man/man3/OSSL_DECODER.3 \ +man/man3/OSSL_DECODER_CTX.3 \ +man/man3/OSSL_DECODER_CTX_new_for_pkey.3 \ +man/man3/OSSL_DECODER_from_bio.3 \ +man/man3/OSSL_DISPATCH.3 \ +man/man3/OSSL_ENCODER.3 \ +man/man3/OSSL_ENCODER_CTX.3 \ +man/man3/OSSL_ENCODER_CTX_new_for_pkey.3 \ +man/man3/OSSL_ENCODER_to_bio.3 \ +man/man3/OSSL_ESS_check_signing_certs.3 \ +man/man3/OSSL_HTTP_REQ_CTX.3 \ +man/man3/OSSL_HTTP_parse_url.3 \ +man/man3/OSSL_HTTP_transfer.3 \ +man/man3/OSSL_ITEM.3 \ +man/man3/OSSL_LIB_CTX.3 \ +man/man3/OSSL_PARAM.3 \ +man/man3/OSSL_PARAM_BLD.3 \ +man/man3/OSSL_PARAM_allocate_from_text.3 \ +man/man3/OSSL_PARAM_dup.3 \ +man/man3/OSSL_PARAM_int.3 \ +man/man3/OSSL_PROVIDER.3 \ +man/man3/OSSL_SELF_TEST_new.3 \ +man/man3/OSSL_SELF_TEST_set_callback.3 \ +man/man3/OSSL_STORE_INFO.3 \ +man/man3/OSSL_STORE_LOADER.3 \ +man/man3/OSSL_STORE_SEARCH.3 \ +man/man3/OSSL_STORE_attach.3 \ +man/man3/OSSL_STORE_expect.3 \ +man/man3/OSSL_STORE_open.3 \ +man/man3/OSSL_trace_enabled.3 \ +man/man3/OSSL_trace_get_category_num.3 \ +man/man3/OSSL_trace_set_channel.3 \ +man/man3/OpenSSL_add_all_algorithms.3 \ +man/man3/OpenSSL_version.3 \ +man/man3/PEM_X509_INFO_read_bio_ex.3 \ +man/man3/PEM_bytes_read_bio.3 \ +man/man3/PEM_read.3 \ +man/man3/PEM_read_CMS.3 \ +man/man3/PEM_read_bio_PrivateKey.3 \ +man/man3/PEM_read_bio_ex.3 \ +man/man3/PEM_write_bio_CMS_stream.3 \ +man/man3/PEM_write_bio_PKCS7_stream.3 \ +man/man3/PKCS12_PBE_keyivgen.3 \ +man/man3/PKCS12_SAFEBAG_create_cert.3 \ +man/man3/PKCS12_SAFEBAG_get0_attrs.3 \ +man/man3/PKCS12_SAFEBAG_get1_cert.3 \ +man/man3/PKCS12_add1_attr_by_NID.3 \ +man/man3/PKCS12_add_CSPName_asc.3 \ +man/man3/PKCS12_add_cert.3 \ +man/man3/PKCS12_add_friendlyname_asc.3 \ +man/man3/PKCS12_add_localkeyid.3 \ +man/man3/PKCS12_add_safe.3 \ +man/man3/PKCS12_create.3 \ +man/man3/PKCS12_decrypt_skey.3 \ +man/man3/PKCS12_gen_mac.3 \ +man/man3/PKCS12_get_friendlyname.3 \ +man/man3/PKCS12_init.3 \ +man/man3/PKCS12_item_decrypt_d2i.3 \ +man/man3/PKCS12_key_gen_utf8_ex.3 \ +man/man3/PKCS12_newpass.3 \ +man/man3/PKCS12_pack_p7encdata.3 \ +man/man3/PKCS12_parse.3 \ +man/man3/PKCS5_PBE_keyivgen.3 \ +man/man3/PKCS5_PBKDF2_HMAC.3 \ +man/man3/PKCS7_decrypt.3 \ +man/man3/PKCS7_encrypt.3 \ +man/man3/PKCS7_get_octet_string.3 \ +man/man3/PKCS7_sign.3 \ +man/man3/PKCS7_sign_add_signer.3 \ +man/man3/PKCS7_type_is_other.3 \ +man/man3/PKCS7_verify.3 \ +man/man3/PKCS8_encrypt.3 \ +man/man3/PKCS8_pkey_add1_attr.3 \ +man/man3/RAND_add.3 \ +man/man3/RAND_bytes.3 \ +man/man3/RAND_cleanup.3 \ +man/man3/RAND_egd.3 \ +man/man3/RAND_get0_primary.3 \ +man/man3/RAND_load_file.3 \ +man/man3/RAND_set_DRBG_type.3 \ +man/man3/RAND_set_rand_method.3 \ +man/man3/RC4_set_key.3 \ +man/man3/RIPEMD160_Init.3 \ +man/man3/RSA_blinding_on.3 \ +man/man3/RSA_check_key.3 \ +man/man3/RSA_generate_key.3 \ +man/man3/RSA_get0_key.3 \ +man/man3/RSA_meth_new.3 \ +man/man3/RSA_new.3 \ +man/man3/RSA_padding_add_PKCS1_type_1.3 \ +man/man3/RSA_print.3 \ +man/man3/RSA_private_encrypt.3 \ +man/man3/RSA_public_encrypt.3 \ +man/man3/RSA_set_method.3 \ +man/man3/RSA_sign.3 \ +man/man3/RSA_sign_ASN1_OCTET_STRING.3 \ +man/man3/RSA_size.3 \ +man/man3/SCT_new.3 \ +man/man3/SCT_print.3 \ +man/man3/SCT_validate.3 \ +man/man3/SHA256_Init.3 \ +man/man3/SMIME_read_ASN1.3 \ +man/man3/SMIME_read_CMS.3 \ +man/man3/SMIME_read_PKCS7.3 \ +man/man3/SMIME_write_ASN1.3 \ +man/man3/SMIME_write_CMS.3 \ +man/man3/SMIME_write_PKCS7.3 \ +man/man3/SRP_Calc_B.3 \ +man/man3/SRP_VBASE_new.3 \ +man/man3/SRP_create_verifier.3 \ +man/man3/SRP_user_pwd_new.3 \ +man/man3/SSL_CIPHER_get_name.3 \ +man/man3/SSL_COMP_add_compression_method.3 \ +man/man3/SSL_CONF_CTX_new.3 \ +man/man3/SSL_CONF_CTX_set1_prefix.3 \ +man/man3/SSL_CONF_CTX_set_flags.3 \ +man/man3/SSL_CONF_CTX_set_ssl_ctx.3 \ +man/man3/SSL_CONF_cmd.3 \ +man/man3/SSL_CONF_cmd_argv.3 \ +man/man3/SSL_CTX_add1_chain_cert.3 \ +man/man3/SSL_CTX_add_extra_chain_cert.3 \ +man/man3/SSL_CTX_add_session.3 \ +man/man3/SSL_CTX_config.3 \ +man/man3/SSL_CTX_ctrl.3 \ +man/man3/SSL_CTX_dane_enable.3 \ +man/man3/SSL_CTX_flush_sessions.3 \ +man/man3/SSL_CTX_free.3 \ +man/man3/SSL_CTX_get0_param.3 \ +man/man3/SSL_CTX_get_verify_mode.3 \ +man/man3/SSL_CTX_has_client_custom_ext.3 \ +man/man3/SSL_CTX_load_verify_locations.3 \ +man/man3/SSL_CTX_new.3 \ +man/man3/SSL_CTX_sess_number.3 \ +man/man3/SSL_CTX_sess_set_cache_size.3 \ +man/man3/SSL_CTX_sess_set_get_cb.3 \ +man/man3/SSL_CTX_sessions.3 \ +man/man3/SSL_CTX_set0_CA_list.3 \ +man/man3/SSL_CTX_set1_curves.3 \ +man/man3/SSL_CTX_set1_sigalgs.3 \ +man/man3/SSL_CTX_set1_verify_cert_store.3 \ +man/man3/SSL_CTX_set_alpn_select_cb.3 \ +man/man3/SSL_CTX_set_cert_cb.3 \ +man/man3/SSL_CTX_set_cert_store.3 \ +man/man3/SSL_CTX_set_cert_verify_callback.3 \ +man/man3/SSL_CTX_set_cipher_list.3 \ +man/man3/SSL_CTX_set_client_cert_cb.3 \ +man/man3/SSL_CTX_set_client_hello_cb.3 \ +man/man3/SSL_CTX_set_ct_validation_callback.3 \ +man/man3/SSL_CTX_set_ctlog_list_file.3 \ +man/man3/SSL_CTX_set_default_passwd_cb.3 \ +man/man3/SSL_CTX_set_generate_session_id.3 \ +man/man3/SSL_CTX_set_info_callback.3 \ +man/man3/SSL_CTX_set_keylog_callback.3 \ +man/man3/SSL_CTX_set_max_cert_list.3 \ +man/man3/SSL_CTX_set_min_proto_version.3 \ +man/man3/SSL_CTX_set_mode.3 \ +man/man3/SSL_CTX_set_msg_callback.3 \ +man/man3/SSL_CTX_set_num_tickets.3 \ +man/man3/SSL_CTX_set_options.3 \ +man/man3/SSL_CTX_set_psk_client_callback.3 \ +man/man3/SSL_CTX_set_quiet_shutdown.3 \ +man/man3/SSL_CTX_set_read_ahead.3 \ +man/man3/SSL_CTX_set_record_padding_callback.3 \ +man/man3/SSL_CTX_set_security_level.3 \ +man/man3/SSL_CTX_set_session_cache_mode.3 \ +man/man3/SSL_CTX_set_session_id_context.3 \ +man/man3/SSL_CTX_set_session_ticket_cb.3 \ +man/man3/SSL_CTX_set_split_send_fragment.3 \ +man/man3/SSL_CTX_set_srp_password.3 \ +man/man3/SSL_CTX_set_ssl_version.3 \ +man/man3/SSL_CTX_set_stateless_cookie_generate_cb.3 \ +man/man3/SSL_CTX_set_timeout.3 \ +man/man3/SSL_CTX_set_tlsext_servername_callback.3 \ +man/man3/SSL_CTX_set_tlsext_status_cb.3 \ +man/man3/SSL_CTX_set_tlsext_ticket_key_cb.3 \ +man/man3/SSL_CTX_set_tlsext_use_srtp.3 \ +man/man3/SSL_CTX_set_tmp_dh_callback.3 \ +man/man3/SSL_CTX_set_tmp_ecdh.3 \ +man/man3/SSL_CTX_set_verify.3 \ +man/man3/SSL_CTX_use_certificate.3 \ +man/man3/SSL_CTX_use_psk_identity_hint.3 \ +man/man3/SSL_CTX_use_serverinfo.3 \ +man/man3/SSL_SESSION_free.3 \ +man/man3/SSL_SESSION_get0_cipher.3 \ +man/man3/SSL_SESSION_get0_hostname.3 \ +man/man3/SSL_SESSION_get0_id_context.3 \ +man/man3/SSL_SESSION_get0_peer.3 \ +man/man3/SSL_SESSION_get_compress_id.3 \ +man/man3/SSL_SESSION_get_protocol_version.3 \ +man/man3/SSL_SESSION_get_time.3 \ +man/man3/SSL_SESSION_has_ticket.3 \ +man/man3/SSL_SESSION_is_resumable.3 \ +man/man3/SSL_SESSION_print.3 \ +man/man3/SSL_SESSION_set1_id.3 \ +man/man3/SSL_accept.3 \ +man/man3/SSL_alert_type_string.3 \ +man/man3/SSL_alloc_buffers.3 \ +man/man3/SSL_check_chain.3 \ +man/man3/SSL_clear.3 \ +man/man3/SSL_connect.3 \ +man/man3/SSL_do_handshake.3 \ +man/man3/SSL_export_keying_material.3 \ +man/man3/SSL_extension_supported.3 \ +man/man3/SSL_free.3 \ +man/man3/SSL_get0_peer_scts.3 \ +man/man3/SSL_get_SSL_CTX.3 \ +man/man3/SSL_get_all_async_fds.3 \ +man/man3/SSL_get_certificate.3 \ +man/man3/SSL_get_ciphers.3 \ +man/man3/SSL_get_client_random.3 \ +man/man3/SSL_get_current_cipher.3 \ +man/man3/SSL_get_default_timeout.3 \ +man/man3/SSL_get_error.3 \ +man/man3/SSL_get_extms_support.3 \ +man/man3/SSL_get_fd.3 \ +man/man3/SSL_get_peer_cert_chain.3 \ +man/man3/SSL_get_peer_certificate.3 \ +man/man3/SSL_get_peer_signature_nid.3 \ +man/man3/SSL_get_peer_tmp_key.3 \ +man/man3/SSL_get_psk_identity.3 \ +man/man3/SSL_get_rbio.3 \ +man/man3/SSL_get_session.3 \ +man/man3/SSL_get_shared_sigalgs.3 \ +man/man3/SSL_get_verify_result.3 \ +man/man3/SSL_get_version.3 \ +man/man3/SSL_group_to_name.3 \ +man/man3/SSL_in_init.3 \ +man/man3/SSL_key_update.3 \ +man/man3/SSL_library_init.3 \ +man/man3/SSL_load_client_CA_file.3 \ +man/man3/SSL_new.3 \ +man/man3/SSL_pending.3 \ +man/man3/SSL_read.3 \ +man/man3/SSL_read_early_data.3 \ +man/man3/SSL_rstate_string.3 \ +man/man3/SSL_session_reused.3 \ +man/man3/SSL_set1_host.3 \ +man/man3/SSL_set_async_callback.3 \ +man/man3/SSL_set_bio.3 \ +man/man3/SSL_set_connect_state.3 \ +man/man3/SSL_set_fd.3 \ +man/man3/SSL_set_retry_verify.3 \ +man/man3/SSL_set_session.3 \ +man/man3/SSL_set_shutdown.3 \ +man/man3/SSL_set_verify_result.3 \ +man/man3/SSL_shutdown.3 \ +man/man3/SSL_state_string.3 \ +man/man3/SSL_want.3 \ +man/man3/SSL_write.3 \ +man/man3/TS_RESP_CTX_new.3 \ +man/man3/TS_VERIFY_CTX_set_certs.3 \ +man/man3/UI_STRING.3 \ +man/man3/UI_UTIL_read_pw.3 \ +man/man3/UI_create_method.3 \ +man/man3/UI_new.3 \ +man/man3/X509V3_get_d2i.3 \ +man/man3/X509V3_set_ctx.3 \ +man/man3/X509_ALGOR_dup.3 \ +man/man3/X509_CRL_get0_by_serial.3 \ +man/man3/X509_EXTENSION_set_object.3 \ +man/man3/X509_LOOKUP.3 \ +man/man3/X509_LOOKUP_hash_dir.3 \ +man/man3/X509_LOOKUP_meth_new.3 \ +man/man3/X509_NAME_ENTRY_get_object.3 \ +man/man3/X509_NAME_add_entry_by_txt.3 \ +man/man3/X509_NAME_get0_der.3 \ +man/man3/X509_NAME_get_index_by_NID.3 \ +man/man3/X509_NAME_print_ex.3 \ +man/man3/X509_PUBKEY_new.3 \ +man/man3/X509_SIG_get0.3 \ +man/man3/X509_STORE_CTX_get_error.3 \ +man/man3/X509_STORE_CTX_new.3 \ +man/man3/X509_STORE_CTX_set_verify_cb.3 \ +man/man3/X509_STORE_add_cert.3 \ +man/man3/X509_STORE_get0_param.3 \ +man/man3/X509_STORE_new.3 \ +man/man3/X509_STORE_set_verify_cb_func.3 \ +man/man3/X509_VERIFY_PARAM_set_flags.3 \ +man/man3/X509_add_cert.3 \ +man/man3/X509_check_ca.3 \ +man/man3/X509_check_host.3 \ +man/man3/X509_check_issued.3 \ +man/man3/X509_check_private_key.3 \ +man/man3/X509_check_purpose.3 \ +man/man3/X509_cmp.3 \ +man/man3/X509_cmp_time.3 \ +man/man3/X509_digest.3 \ +man/man3/X509_dup.3 \ +man/man3/X509_get0_distinguishing_id.3 \ +man/man3/X509_get0_notBefore.3 \ +man/man3/X509_get0_signature.3 \ +man/man3/X509_get0_uids.3 \ +man/man3/X509_get_extension_flags.3 \ +man/man3/X509_get_pubkey.3 \ +man/man3/X509_get_serialNumber.3 \ +man/man3/X509_get_subject_name.3 \ +man/man3/X509_get_version.3 \ +man/man3/X509_load_http.3 \ +man/man3/X509_new.3 \ +man/man3/X509_sign.3 \ +man/man3/X509_verify.3 \ +man/man3/X509_verify_cert.3 \ +man/man3/X509v3_get_ext_by_NID.3 \ +man/man3/b2i_PVK_bio_ex.3 \ +man/man3/d2i_PKCS8PrivateKey_bio.3 \ +man/man3/d2i_PrivateKey.3 \ +man/man3/d2i_RSAPrivateKey.3 \ +man/man3/d2i_SSL_SESSION.3 \ +man/man3/d2i_X509.3 \ +man/man3/i2d_CMS_bio_stream.3 \ +man/man3/i2d_PKCS7_bio_stream.3 \ +man/man3/i2d_re_X509_tbs.3 \ +man/man3/o2i_SCT_LIST.3 \ +man/man3/s2i_ASN1_IA5STRING.3 +DEPEND[html/man5/config.html]=man5/config.pod +GENERATE[html/man5/config.html]=man5/config.pod +DEPEND[man/man5/config.5]=man5/config.pod +GENERATE[man/man5/config.5]=man5/config.pod +DEPEND[html/man5/fips_config.html]=man5/fips_config.pod +GENERATE[html/man5/fips_config.html]=man5/fips_config.pod +DEPEND[man/man5/fips_config.5]=man5/fips_config.pod +GENERATE[man/man5/fips_config.5]=man5/fips_config.pod +DEPEND[html/man5/x509v3_config.html]=man5/x509v3_config.pod +GENERATE[html/man5/x509v3_config.html]=man5/x509v3_config.pod +DEPEND[man/man5/x509v3_config.5]=man5/x509v3_config.pod +GENERATE[man/man5/x509v3_config.5]=man5/x509v3_config.pod +IMAGEDOCS[man5]= +HTMLDOCS[man5]=html/man5/config.html \ +html/man5/fips_config.html \ +html/man5/x509v3_config.html +MANDOCS[man5]=man/man5/config.5 \ +man/man5/fips_config.5 \ +man/man5/x509v3_config.5 +DEPEND[html/man7/EVP_ASYM_CIPHER-RSA.html]=man7/EVP_ASYM_CIPHER-RSA.pod +GENERATE[html/man7/EVP_ASYM_CIPHER-RSA.html]=man7/EVP_ASYM_CIPHER-RSA.pod +DEPEND[man/man7/EVP_ASYM_CIPHER-RSA.7]=man7/EVP_ASYM_CIPHER-RSA.pod +GENERATE[man/man7/EVP_ASYM_CIPHER-RSA.7]=man7/EVP_ASYM_CIPHER-RSA.pod +DEPEND[html/man7/EVP_ASYM_CIPHER-SM2.html]=man7/EVP_ASYM_CIPHER-SM2.pod +GENERATE[html/man7/EVP_ASYM_CIPHER-SM2.html]=man7/EVP_ASYM_CIPHER-SM2.pod +DEPEND[man/man7/EVP_ASYM_CIPHER-SM2.7]=man7/EVP_ASYM_CIPHER-SM2.pod +GENERATE[man/man7/EVP_ASYM_CIPHER-SM2.7]=man7/EVP_ASYM_CIPHER-SM2.pod +DEPEND[html/man7/EVP_CIPHER-AES.html]=man7/EVP_CIPHER-AES.pod +GENERATE[html/man7/EVP_CIPHER-AES.html]=man7/EVP_CIPHER-AES.pod +DEPEND[man/man7/EVP_CIPHER-AES.7]=man7/EVP_CIPHER-AES.pod +GENERATE[man/man7/EVP_CIPHER-AES.7]=man7/EVP_CIPHER-AES.pod +DEPEND[html/man7/EVP_CIPHER-ARIA.html]=man7/EVP_CIPHER-ARIA.pod +GENERATE[html/man7/EVP_CIPHER-ARIA.html]=man7/EVP_CIPHER-ARIA.pod +DEPEND[man/man7/EVP_CIPHER-ARIA.7]=man7/EVP_CIPHER-ARIA.pod +GENERATE[man/man7/EVP_CIPHER-ARIA.7]=man7/EVP_CIPHER-ARIA.pod +DEPEND[html/man7/EVP_CIPHER-BLOWFISH.html]=man7/EVP_CIPHER-BLOWFISH.pod +GENERATE[html/man7/EVP_CIPHER-BLOWFISH.html]=man7/EVP_CIPHER-BLOWFISH.pod +DEPEND[man/man7/EVP_CIPHER-BLOWFISH.7]=man7/EVP_CIPHER-BLOWFISH.pod +GENERATE[man/man7/EVP_CIPHER-BLOWFISH.7]=man7/EVP_CIPHER-BLOWFISH.pod +DEPEND[html/man7/EVP_CIPHER-CAMELLIA.html]=man7/EVP_CIPHER-CAMELLIA.pod +GENERATE[html/man7/EVP_CIPHER-CAMELLIA.html]=man7/EVP_CIPHER-CAMELLIA.pod +DEPEND[man/man7/EVP_CIPHER-CAMELLIA.7]=man7/EVP_CIPHER-CAMELLIA.pod +GENERATE[man/man7/EVP_CIPHER-CAMELLIA.7]=man7/EVP_CIPHER-CAMELLIA.pod +DEPEND[html/man7/EVP_CIPHER-CAST.html]=man7/EVP_CIPHER-CAST.pod +GENERATE[html/man7/EVP_CIPHER-CAST.html]=man7/EVP_CIPHER-CAST.pod +DEPEND[man/man7/EVP_CIPHER-CAST.7]=man7/EVP_CIPHER-CAST.pod +GENERATE[man/man7/EVP_CIPHER-CAST.7]=man7/EVP_CIPHER-CAST.pod +DEPEND[html/man7/EVP_CIPHER-CHACHA.html]=man7/EVP_CIPHER-CHACHA.pod +GENERATE[html/man7/EVP_CIPHER-CHACHA.html]=man7/EVP_CIPHER-CHACHA.pod +DEPEND[man/man7/EVP_CIPHER-CHACHA.7]=man7/EVP_CIPHER-CHACHA.pod +GENERATE[man/man7/EVP_CIPHER-CHACHA.7]=man7/EVP_CIPHER-CHACHA.pod +DEPEND[html/man7/EVP_CIPHER-DES.html]=man7/EVP_CIPHER-DES.pod +GENERATE[html/man7/EVP_CIPHER-DES.html]=man7/EVP_CIPHER-DES.pod +DEPEND[man/man7/EVP_CIPHER-DES.7]=man7/EVP_CIPHER-DES.pod +GENERATE[man/man7/EVP_CIPHER-DES.7]=man7/EVP_CIPHER-DES.pod +DEPEND[html/man7/EVP_CIPHER-IDEA.html]=man7/EVP_CIPHER-IDEA.pod +GENERATE[html/man7/EVP_CIPHER-IDEA.html]=man7/EVP_CIPHER-IDEA.pod +DEPEND[man/man7/EVP_CIPHER-IDEA.7]=man7/EVP_CIPHER-IDEA.pod +GENERATE[man/man7/EVP_CIPHER-IDEA.7]=man7/EVP_CIPHER-IDEA.pod +DEPEND[html/man7/EVP_CIPHER-RC2.html]=man7/EVP_CIPHER-RC2.pod +GENERATE[html/man7/EVP_CIPHER-RC2.html]=man7/EVP_CIPHER-RC2.pod +DEPEND[man/man7/EVP_CIPHER-RC2.7]=man7/EVP_CIPHER-RC2.pod +GENERATE[man/man7/EVP_CIPHER-RC2.7]=man7/EVP_CIPHER-RC2.pod +DEPEND[html/man7/EVP_CIPHER-RC4.html]=man7/EVP_CIPHER-RC4.pod +GENERATE[html/man7/EVP_CIPHER-RC4.html]=man7/EVP_CIPHER-RC4.pod +DEPEND[man/man7/EVP_CIPHER-RC4.7]=man7/EVP_CIPHER-RC4.pod +GENERATE[man/man7/EVP_CIPHER-RC4.7]=man7/EVP_CIPHER-RC4.pod +DEPEND[html/man7/EVP_CIPHER-RC5.html]=man7/EVP_CIPHER-RC5.pod +GENERATE[html/man7/EVP_CIPHER-RC5.html]=man7/EVP_CIPHER-RC5.pod +DEPEND[man/man7/EVP_CIPHER-RC5.7]=man7/EVP_CIPHER-RC5.pod +GENERATE[man/man7/EVP_CIPHER-RC5.7]=man7/EVP_CIPHER-RC5.pod +DEPEND[html/man7/EVP_CIPHER-SEED.html]=man7/EVP_CIPHER-SEED.pod +GENERATE[html/man7/EVP_CIPHER-SEED.html]=man7/EVP_CIPHER-SEED.pod +DEPEND[man/man7/EVP_CIPHER-SEED.7]=man7/EVP_CIPHER-SEED.pod +GENERATE[man/man7/EVP_CIPHER-SEED.7]=man7/EVP_CIPHER-SEED.pod +DEPEND[html/man7/EVP_CIPHER-SM4.html]=man7/EVP_CIPHER-SM4.pod +GENERATE[html/man7/EVP_CIPHER-SM4.html]=man7/EVP_CIPHER-SM4.pod +DEPEND[man/man7/EVP_CIPHER-SM4.7]=man7/EVP_CIPHER-SM4.pod +GENERATE[man/man7/EVP_CIPHER-SM4.7]=man7/EVP_CIPHER-SM4.pod +DEPEND[html/man7/EVP_KDF-HKDF.html]=man7/EVP_KDF-HKDF.pod +GENERATE[html/man7/EVP_KDF-HKDF.html]=man7/EVP_KDF-HKDF.pod +DEPEND[man/man7/EVP_KDF-HKDF.7]=man7/EVP_KDF-HKDF.pod +GENERATE[man/man7/EVP_KDF-HKDF.7]=man7/EVP_KDF-HKDF.pod +DEPEND[html/man7/EVP_KDF-KB.html]=man7/EVP_KDF-KB.pod +GENERATE[html/man7/EVP_KDF-KB.html]=man7/EVP_KDF-KB.pod +DEPEND[man/man7/EVP_KDF-KB.7]=man7/EVP_KDF-KB.pod +GENERATE[man/man7/EVP_KDF-KB.7]=man7/EVP_KDF-KB.pod +DEPEND[html/man7/EVP_KDF-KRB5KDF.html]=man7/EVP_KDF-KRB5KDF.pod +GENERATE[html/man7/EVP_KDF-KRB5KDF.html]=man7/EVP_KDF-KRB5KDF.pod +DEPEND[man/man7/EVP_KDF-KRB5KDF.7]=man7/EVP_KDF-KRB5KDF.pod +GENERATE[man/man7/EVP_KDF-KRB5KDF.7]=man7/EVP_KDF-KRB5KDF.pod +DEPEND[html/man7/EVP_KDF-PBKDF1.html]=man7/EVP_KDF-PBKDF1.pod +GENERATE[html/man7/EVP_KDF-PBKDF1.html]=man7/EVP_KDF-PBKDF1.pod +DEPEND[man/man7/EVP_KDF-PBKDF1.7]=man7/EVP_KDF-PBKDF1.pod +GENERATE[man/man7/EVP_KDF-PBKDF1.7]=man7/EVP_KDF-PBKDF1.pod +DEPEND[html/man7/EVP_KDF-PBKDF2.html]=man7/EVP_KDF-PBKDF2.pod +GENERATE[html/man7/EVP_KDF-PBKDF2.html]=man7/EVP_KDF-PBKDF2.pod +DEPEND[man/man7/EVP_KDF-PBKDF2.7]=man7/EVP_KDF-PBKDF2.pod +GENERATE[man/man7/EVP_KDF-PBKDF2.7]=man7/EVP_KDF-PBKDF2.pod +DEPEND[html/man7/EVP_KDF-PKCS12KDF.html]=man7/EVP_KDF-PKCS12KDF.pod +GENERATE[html/man7/EVP_KDF-PKCS12KDF.html]=man7/EVP_KDF-PKCS12KDF.pod +DEPEND[man/man7/EVP_KDF-PKCS12KDF.7]=man7/EVP_KDF-PKCS12KDF.pod +GENERATE[man/man7/EVP_KDF-PKCS12KDF.7]=man7/EVP_KDF-PKCS12KDF.pod +DEPEND[html/man7/EVP_KDF-SCRYPT.html]=man7/EVP_KDF-SCRYPT.pod +GENERATE[html/man7/EVP_KDF-SCRYPT.html]=man7/EVP_KDF-SCRYPT.pod +DEPEND[man/man7/EVP_KDF-SCRYPT.7]=man7/EVP_KDF-SCRYPT.pod +GENERATE[man/man7/EVP_KDF-SCRYPT.7]=man7/EVP_KDF-SCRYPT.pod +DEPEND[html/man7/EVP_KDF-SS.html]=man7/EVP_KDF-SS.pod +GENERATE[html/man7/EVP_KDF-SS.html]=man7/EVP_KDF-SS.pod +DEPEND[man/man7/EVP_KDF-SS.7]=man7/EVP_KDF-SS.pod +GENERATE[man/man7/EVP_KDF-SS.7]=man7/EVP_KDF-SS.pod +DEPEND[html/man7/EVP_KDF-SSHKDF.html]=man7/EVP_KDF-SSHKDF.pod +GENERATE[html/man7/EVP_KDF-SSHKDF.html]=man7/EVP_KDF-SSHKDF.pod +DEPEND[man/man7/EVP_KDF-SSHKDF.7]=man7/EVP_KDF-SSHKDF.pod +GENERATE[man/man7/EVP_KDF-SSHKDF.7]=man7/EVP_KDF-SSHKDF.pod +DEPEND[html/man7/EVP_KDF-TLS13_KDF.html]=man7/EVP_KDF-TLS13_KDF.pod +GENERATE[html/man7/EVP_KDF-TLS13_KDF.html]=man7/EVP_KDF-TLS13_KDF.pod +DEPEND[man/man7/EVP_KDF-TLS13_KDF.7]=man7/EVP_KDF-TLS13_KDF.pod +GENERATE[man/man7/EVP_KDF-TLS13_KDF.7]=man7/EVP_KDF-TLS13_KDF.pod +DEPEND[html/man7/EVP_KDF-TLS1_PRF.html]=man7/EVP_KDF-TLS1_PRF.pod +GENERATE[html/man7/EVP_KDF-TLS1_PRF.html]=man7/EVP_KDF-TLS1_PRF.pod +DEPEND[man/man7/EVP_KDF-TLS1_PRF.7]=man7/EVP_KDF-TLS1_PRF.pod +GENERATE[man/man7/EVP_KDF-TLS1_PRF.7]=man7/EVP_KDF-TLS1_PRF.pod +DEPEND[html/man7/EVP_KDF-X942-ASN1.html]=man7/EVP_KDF-X942-ASN1.pod +GENERATE[html/man7/EVP_KDF-X942-ASN1.html]=man7/EVP_KDF-X942-ASN1.pod +DEPEND[man/man7/EVP_KDF-X942-ASN1.7]=man7/EVP_KDF-X942-ASN1.pod +GENERATE[man/man7/EVP_KDF-X942-ASN1.7]=man7/EVP_KDF-X942-ASN1.pod +DEPEND[html/man7/EVP_KDF-X942-CONCAT.html]=man7/EVP_KDF-X942-CONCAT.pod +GENERATE[html/man7/EVP_KDF-X942-CONCAT.html]=man7/EVP_KDF-X942-CONCAT.pod +DEPEND[man/man7/EVP_KDF-X942-CONCAT.7]=man7/EVP_KDF-X942-CONCAT.pod +GENERATE[man/man7/EVP_KDF-X942-CONCAT.7]=man7/EVP_KDF-X942-CONCAT.pod +DEPEND[html/man7/EVP_KDF-X963.html]=man7/EVP_KDF-X963.pod +GENERATE[html/man7/EVP_KDF-X963.html]=man7/EVP_KDF-X963.pod +DEPEND[man/man7/EVP_KDF-X963.7]=man7/EVP_KDF-X963.pod +GENERATE[man/man7/EVP_KDF-X963.7]=man7/EVP_KDF-X963.pod +DEPEND[html/man7/EVP_KEM-RSA.html]=man7/EVP_KEM-RSA.pod +GENERATE[html/man7/EVP_KEM-RSA.html]=man7/EVP_KEM-RSA.pod +DEPEND[man/man7/EVP_KEM-RSA.7]=man7/EVP_KEM-RSA.pod +GENERATE[man/man7/EVP_KEM-RSA.7]=man7/EVP_KEM-RSA.pod +DEPEND[html/man7/EVP_KEYEXCH-DH.html]=man7/EVP_KEYEXCH-DH.pod +GENERATE[html/man7/EVP_KEYEXCH-DH.html]=man7/EVP_KEYEXCH-DH.pod +DEPEND[man/man7/EVP_KEYEXCH-DH.7]=man7/EVP_KEYEXCH-DH.pod +GENERATE[man/man7/EVP_KEYEXCH-DH.7]=man7/EVP_KEYEXCH-DH.pod +DEPEND[html/man7/EVP_KEYEXCH-ECDH.html]=man7/EVP_KEYEXCH-ECDH.pod +GENERATE[html/man7/EVP_KEYEXCH-ECDH.html]=man7/EVP_KEYEXCH-ECDH.pod +DEPEND[man/man7/EVP_KEYEXCH-ECDH.7]=man7/EVP_KEYEXCH-ECDH.pod +GENERATE[man/man7/EVP_KEYEXCH-ECDH.7]=man7/EVP_KEYEXCH-ECDH.pod +DEPEND[html/man7/EVP_KEYEXCH-X25519.html]=man7/EVP_KEYEXCH-X25519.pod +GENERATE[html/man7/EVP_KEYEXCH-X25519.html]=man7/EVP_KEYEXCH-X25519.pod +DEPEND[man/man7/EVP_KEYEXCH-X25519.7]=man7/EVP_KEYEXCH-X25519.pod +GENERATE[man/man7/EVP_KEYEXCH-X25519.7]=man7/EVP_KEYEXCH-X25519.pod +DEPEND[html/man7/EVP_MAC-BLAKE2.html]=man7/EVP_MAC-BLAKE2.pod +GENERATE[html/man7/EVP_MAC-BLAKE2.html]=man7/EVP_MAC-BLAKE2.pod +DEPEND[man/man7/EVP_MAC-BLAKE2.7]=man7/EVP_MAC-BLAKE2.pod +GENERATE[man/man7/EVP_MAC-BLAKE2.7]=man7/EVP_MAC-BLAKE2.pod +DEPEND[html/man7/EVP_MAC-CMAC.html]=man7/EVP_MAC-CMAC.pod +GENERATE[html/man7/EVP_MAC-CMAC.html]=man7/EVP_MAC-CMAC.pod +DEPEND[man/man7/EVP_MAC-CMAC.7]=man7/EVP_MAC-CMAC.pod +GENERATE[man/man7/EVP_MAC-CMAC.7]=man7/EVP_MAC-CMAC.pod +DEPEND[html/man7/EVP_MAC-GMAC.html]=man7/EVP_MAC-GMAC.pod +GENERATE[html/man7/EVP_MAC-GMAC.html]=man7/EVP_MAC-GMAC.pod +DEPEND[man/man7/EVP_MAC-GMAC.7]=man7/EVP_MAC-GMAC.pod +GENERATE[man/man7/EVP_MAC-GMAC.7]=man7/EVP_MAC-GMAC.pod +DEPEND[html/man7/EVP_MAC-HMAC.html]=man7/EVP_MAC-HMAC.pod +GENERATE[html/man7/EVP_MAC-HMAC.html]=man7/EVP_MAC-HMAC.pod +DEPEND[man/man7/EVP_MAC-HMAC.7]=man7/EVP_MAC-HMAC.pod +GENERATE[man/man7/EVP_MAC-HMAC.7]=man7/EVP_MAC-HMAC.pod +DEPEND[html/man7/EVP_MAC-KMAC.html]=man7/EVP_MAC-KMAC.pod +GENERATE[html/man7/EVP_MAC-KMAC.html]=man7/EVP_MAC-KMAC.pod +DEPEND[man/man7/EVP_MAC-KMAC.7]=man7/EVP_MAC-KMAC.pod +GENERATE[man/man7/EVP_MAC-KMAC.7]=man7/EVP_MAC-KMAC.pod +DEPEND[html/man7/EVP_MAC-Poly1305.html]=man7/EVP_MAC-Poly1305.pod +GENERATE[html/man7/EVP_MAC-Poly1305.html]=man7/EVP_MAC-Poly1305.pod +DEPEND[man/man7/EVP_MAC-Poly1305.7]=man7/EVP_MAC-Poly1305.pod +GENERATE[man/man7/EVP_MAC-Poly1305.7]=man7/EVP_MAC-Poly1305.pod +DEPEND[html/man7/EVP_MAC-Siphash.html]=man7/EVP_MAC-Siphash.pod +GENERATE[html/man7/EVP_MAC-Siphash.html]=man7/EVP_MAC-Siphash.pod +DEPEND[man/man7/EVP_MAC-Siphash.7]=man7/EVP_MAC-Siphash.pod +GENERATE[man/man7/EVP_MAC-Siphash.7]=man7/EVP_MAC-Siphash.pod +DEPEND[html/man7/EVP_MD-BLAKE2.html]=man7/EVP_MD-BLAKE2.pod +GENERATE[html/man7/EVP_MD-BLAKE2.html]=man7/EVP_MD-BLAKE2.pod +DEPEND[man/man7/EVP_MD-BLAKE2.7]=man7/EVP_MD-BLAKE2.pod +GENERATE[man/man7/EVP_MD-BLAKE2.7]=man7/EVP_MD-BLAKE2.pod +DEPEND[html/man7/EVP_MD-MD2.html]=man7/EVP_MD-MD2.pod +GENERATE[html/man7/EVP_MD-MD2.html]=man7/EVP_MD-MD2.pod +DEPEND[man/man7/EVP_MD-MD2.7]=man7/EVP_MD-MD2.pod +GENERATE[man/man7/EVP_MD-MD2.7]=man7/EVP_MD-MD2.pod +DEPEND[html/man7/EVP_MD-MD4.html]=man7/EVP_MD-MD4.pod +GENERATE[html/man7/EVP_MD-MD4.html]=man7/EVP_MD-MD4.pod +DEPEND[man/man7/EVP_MD-MD4.7]=man7/EVP_MD-MD4.pod +GENERATE[man/man7/EVP_MD-MD4.7]=man7/EVP_MD-MD4.pod +DEPEND[html/man7/EVP_MD-MD5-SHA1.html]=man7/EVP_MD-MD5-SHA1.pod +GENERATE[html/man7/EVP_MD-MD5-SHA1.html]=man7/EVP_MD-MD5-SHA1.pod +DEPEND[man/man7/EVP_MD-MD5-SHA1.7]=man7/EVP_MD-MD5-SHA1.pod +GENERATE[man/man7/EVP_MD-MD5-SHA1.7]=man7/EVP_MD-MD5-SHA1.pod +DEPEND[html/man7/EVP_MD-MD5.html]=man7/EVP_MD-MD5.pod +GENERATE[html/man7/EVP_MD-MD5.html]=man7/EVP_MD-MD5.pod +DEPEND[man/man7/EVP_MD-MD5.7]=man7/EVP_MD-MD5.pod +GENERATE[man/man7/EVP_MD-MD5.7]=man7/EVP_MD-MD5.pod +DEPEND[html/man7/EVP_MD-MDC2.html]=man7/EVP_MD-MDC2.pod +GENERATE[html/man7/EVP_MD-MDC2.html]=man7/EVP_MD-MDC2.pod +DEPEND[man/man7/EVP_MD-MDC2.7]=man7/EVP_MD-MDC2.pod +GENERATE[man/man7/EVP_MD-MDC2.7]=man7/EVP_MD-MDC2.pod +DEPEND[html/man7/EVP_MD-RIPEMD160.html]=man7/EVP_MD-RIPEMD160.pod +GENERATE[html/man7/EVP_MD-RIPEMD160.html]=man7/EVP_MD-RIPEMD160.pod +DEPEND[man/man7/EVP_MD-RIPEMD160.7]=man7/EVP_MD-RIPEMD160.pod +GENERATE[man/man7/EVP_MD-RIPEMD160.7]=man7/EVP_MD-RIPEMD160.pod +DEPEND[html/man7/EVP_MD-SHA1.html]=man7/EVP_MD-SHA1.pod +GENERATE[html/man7/EVP_MD-SHA1.html]=man7/EVP_MD-SHA1.pod +DEPEND[man/man7/EVP_MD-SHA1.7]=man7/EVP_MD-SHA1.pod +GENERATE[man/man7/EVP_MD-SHA1.7]=man7/EVP_MD-SHA1.pod +DEPEND[html/man7/EVP_MD-SHA2.html]=man7/EVP_MD-SHA2.pod +GENERATE[html/man7/EVP_MD-SHA2.html]=man7/EVP_MD-SHA2.pod +DEPEND[man/man7/EVP_MD-SHA2.7]=man7/EVP_MD-SHA2.pod +GENERATE[man/man7/EVP_MD-SHA2.7]=man7/EVP_MD-SHA2.pod +DEPEND[html/man7/EVP_MD-SHA3.html]=man7/EVP_MD-SHA3.pod +GENERATE[html/man7/EVP_MD-SHA3.html]=man7/EVP_MD-SHA3.pod +DEPEND[man/man7/EVP_MD-SHA3.7]=man7/EVP_MD-SHA3.pod +GENERATE[man/man7/EVP_MD-SHA3.7]=man7/EVP_MD-SHA3.pod +DEPEND[html/man7/EVP_MD-SHAKE.html]=man7/EVP_MD-SHAKE.pod +GENERATE[html/man7/EVP_MD-SHAKE.html]=man7/EVP_MD-SHAKE.pod +DEPEND[man/man7/EVP_MD-SHAKE.7]=man7/EVP_MD-SHAKE.pod +GENERATE[man/man7/EVP_MD-SHAKE.7]=man7/EVP_MD-SHAKE.pod +DEPEND[html/man7/EVP_MD-SM3.html]=man7/EVP_MD-SM3.pod +GENERATE[html/man7/EVP_MD-SM3.html]=man7/EVP_MD-SM3.pod +DEPEND[man/man7/EVP_MD-SM3.7]=man7/EVP_MD-SM3.pod +GENERATE[man/man7/EVP_MD-SM3.7]=man7/EVP_MD-SM3.pod +DEPEND[html/man7/EVP_MD-WHIRLPOOL.html]=man7/EVP_MD-WHIRLPOOL.pod +GENERATE[html/man7/EVP_MD-WHIRLPOOL.html]=man7/EVP_MD-WHIRLPOOL.pod +DEPEND[man/man7/EVP_MD-WHIRLPOOL.7]=man7/EVP_MD-WHIRLPOOL.pod +GENERATE[man/man7/EVP_MD-WHIRLPOOL.7]=man7/EVP_MD-WHIRLPOOL.pod +DEPEND[html/man7/EVP_MD-common.html]=man7/EVP_MD-common.pod +GENERATE[html/man7/EVP_MD-common.html]=man7/EVP_MD-common.pod +DEPEND[man/man7/EVP_MD-common.7]=man7/EVP_MD-common.pod +GENERATE[man/man7/EVP_MD-common.7]=man7/EVP_MD-common.pod +DEPEND[html/man7/EVP_PKEY-DH.html]=man7/EVP_PKEY-DH.pod +GENERATE[html/man7/EVP_PKEY-DH.html]=man7/EVP_PKEY-DH.pod +DEPEND[man/man7/EVP_PKEY-DH.7]=man7/EVP_PKEY-DH.pod +GENERATE[man/man7/EVP_PKEY-DH.7]=man7/EVP_PKEY-DH.pod +DEPEND[html/man7/EVP_PKEY-DSA.html]=man7/EVP_PKEY-DSA.pod +GENERATE[html/man7/EVP_PKEY-DSA.html]=man7/EVP_PKEY-DSA.pod +DEPEND[man/man7/EVP_PKEY-DSA.7]=man7/EVP_PKEY-DSA.pod +GENERATE[man/man7/EVP_PKEY-DSA.7]=man7/EVP_PKEY-DSA.pod +DEPEND[html/man7/EVP_PKEY-EC.html]=man7/EVP_PKEY-EC.pod +GENERATE[html/man7/EVP_PKEY-EC.html]=man7/EVP_PKEY-EC.pod +DEPEND[man/man7/EVP_PKEY-EC.7]=man7/EVP_PKEY-EC.pod +GENERATE[man/man7/EVP_PKEY-EC.7]=man7/EVP_PKEY-EC.pod +DEPEND[html/man7/EVP_PKEY-FFC.html]=man7/EVP_PKEY-FFC.pod +GENERATE[html/man7/EVP_PKEY-FFC.html]=man7/EVP_PKEY-FFC.pod +DEPEND[man/man7/EVP_PKEY-FFC.7]=man7/EVP_PKEY-FFC.pod +GENERATE[man/man7/EVP_PKEY-FFC.7]=man7/EVP_PKEY-FFC.pod +DEPEND[html/man7/EVP_PKEY-HMAC.html]=man7/EVP_PKEY-HMAC.pod +GENERATE[html/man7/EVP_PKEY-HMAC.html]=man7/EVP_PKEY-HMAC.pod +DEPEND[man/man7/EVP_PKEY-HMAC.7]=man7/EVP_PKEY-HMAC.pod +GENERATE[man/man7/EVP_PKEY-HMAC.7]=man7/EVP_PKEY-HMAC.pod +DEPEND[html/man7/EVP_PKEY-RSA.html]=man7/EVP_PKEY-RSA.pod +GENERATE[html/man7/EVP_PKEY-RSA.html]=man7/EVP_PKEY-RSA.pod +DEPEND[man/man7/EVP_PKEY-RSA.7]=man7/EVP_PKEY-RSA.pod +GENERATE[man/man7/EVP_PKEY-RSA.7]=man7/EVP_PKEY-RSA.pod +DEPEND[html/man7/EVP_PKEY-SM2.html]=man7/EVP_PKEY-SM2.pod +GENERATE[html/man7/EVP_PKEY-SM2.html]=man7/EVP_PKEY-SM2.pod +DEPEND[man/man7/EVP_PKEY-SM2.7]=man7/EVP_PKEY-SM2.pod +GENERATE[man/man7/EVP_PKEY-SM2.7]=man7/EVP_PKEY-SM2.pod +DEPEND[html/man7/EVP_PKEY-X25519.html]=man7/EVP_PKEY-X25519.pod +GENERATE[html/man7/EVP_PKEY-X25519.html]=man7/EVP_PKEY-X25519.pod +DEPEND[man/man7/EVP_PKEY-X25519.7]=man7/EVP_PKEY-X25519.pod +GENERATE[man/man7/EVP_PKEY-X25519.7]=man7/EVP_PKEY-X25519.pod +DEPEND[html/man7/EVP_RAND-CTR-DRBG.html]=man7/EVP_RAND-CTR-DRBG.pod +GENERATE[html/man7/EVP_RAND-CTR-DRBG.html]=man7/EVP_RAND-CTR-DRBG.pod +DEPEND[man/man7/EVP_RAND-CTR-DRBG.7]=man7/EVP_RAND-CTR-DRBG.pod +GENERATE[man/man7/EVP_RAND-CTR-DRBG.7]=man7/EVP_RAND-CTR-DRBG.pod +DEPEND[html/man7/EVP_RAND-HASH-DRBG.html]=man7/EVP_RAND-HASH-DRBG.pod +GENERATE[html/man7/EVP_RAND-HASH-DRBG.html]=man7/EVP_RAND-HASH-DRBG.pod +DEPEND[man/man7/EVP_RAND-HASH-DRBG.7]=man7/EVP_RAND-HASH-DRBG.pod +GENERATE[man/man7/EVP_RAND-HASH-DRBG.7]=man7/EVP_RAND-HASH-DRBG.pod +DEPEND[html/man7/EVP_RAND-HMAC-DRBG.html]=man7/EVP_RAND-HMAC-DRBG.pod +GENERATE[html/man7/EVP_RAND-HMAC-DRBG.html]=man7/EVP_RAND-HMAC-DRBG.pod +DEPEND[man/man7/EVP_RAND-HMAC-DRBG.7]=man7/EVP_RAND-HMAC-DRBG.pod +GENERATE[man/man7/EVP_RAND-HMAC-DRBG.7]=man7/EVP_RAND-HMAC-DRBG.pod +DEPEND[html/man7/EVP_RAND-SEED-SRC.html]=man7/EVP_RAND-SEED-SRC.pod +GENERATE[html/man7/EVP_RAND-SEED-SRC.html]=man7/EVP_RAND-SEED-SRC.pod +DEPEND[man/man7/EVP_RAND-SEED-SRC.7]=man7/EVP_RAND-SEED-SRC.pod +GENERATE[man/man7/EVP_RAND-SEED-SRC.7]=man7/EVP_RAND-SEED-SRC.pod +DEPEND[html/man7/EVP_RAND-TEST-RAND.html]=man7/EVP_RAND-TEST-RAND.pod +GENERATE[html/man7/EVP_RAND-TEST-RAND.html]=man7/EVP_RAND-TEST-RAND.pod +DEPEND[man/man7/EVP_RAND-TEST-RAND.7]=man7/EVP_RAND-TEST-RAND.pod +GENERATE[man/man7/EVP_RAND-TEST-RAND.7]=man7/EVP_RAND-TEST-RAND.pod +DEPEND[html/man7/EVP_RAND.html]=man7/EVP_RAND.pod +GENERATE[html/man7/EVP_RAND.html]=man7/EVP_RAND.pod +DEPEND[man/man7/EVP_RAND.7]=man7/EVP_RAND.pod +GENERATE[man/man7/EVP_RAND.7]=man7/EVP_RAND.pod +DEPEND[html/man7/EVP_SIGNATURE-DSA.html]=man7/EVP_SIGNATURE-DSA.pod +GENERATE[html/man7/EVP_SIGNATURE-DSA.html]=man7/EVP_SIGNATURE-DSA.pod +DEPEND[man/man7/EVP_SIGNATURE-DSA.7]=man7/EVP_SIGNATURE-DSA.pod +GENERATE[man/man7/EVP_SIGNATURE-DSA.7]=man7/EVP_SIGNATURE-DSA.pod +DEPEND[html/man7/EVP_SIGNATURE-ECDSA.html]=man7/EVP_SIGNATURE-ECDSA.pod +GENERATE[html/man7/EVP_SIGNATURE-ECDSA.html]=man7/EVP_SIGNATURE-ECDSA.pod +DEPEND[man/man7/EVP_SIGNATURE-ECDSA.7]=man7/EVP_SIGNATURE-ECDSA.pod +GENERATE[man/man7/EVP_SIGNATURE-ECDSA.7]=man7/EVP_SIGNATURE-ECDSA.pod +DEPEND[html/man7/EVP_SIGNATURE-ED25519.html]=man7/EVP_SIGNATURE-ED25519.pod +GENERATE[html/man7/EVP_SIGNATURE-ED25519.html]=man7/EVP_SIGNATURE-ED25519.pod +DEPEND[man/man7/EVP_SIGNATURE-ED25519.7]=man7/EVP_SIGNATURE-ED25519.pod +GENERATE[man/man7/EVP_SIGNATURE-ED25519.7]=man7/EVP_SIGNATURE-ED25519.pod +DEPEND[html/man7/EVP_SIGNATURE-HMAC.html]=man7/EVP_SIGNATURE-HMAC.pod +GENERATE[html/man7/EVP_SIGNATURE-HMAC.html]=man7/EVP_SIGNATURE-HMAC.pod +DEPEND[man/man7/EVP_SIGNATURE-HMAC.7]=man7/EVP_SIGNATURE-HMAC.pod +GENERATE[man/man7/EVP_SIGNATURE-HMAC.7]=man7/EVP_SIGNATURE-HMAC.pod +DEPEND[html/man7/EVP_SIGNATURE-RSA.html]=man7/EVP_SIGNATURE-RSA.pod +GENERATE[html/man7/EVP_SIGNATURE-RSA.html]=man7/EVP_SIGNATURE-RSA.pod +DEPEND[man/man7/EVP_SIGNATURE-RSA.7]=man7/EVP_SIGNATURE-RSA.pod +GENERATE[man/man7/EVP_SIGNATURE-RSA.7]=man7/EVP_SIGNATURE-RSA.pod +DEPEND[html/man7/OSSL_PROVIDER-FIPS.html]=man7/OSSL_PROVIDER-FIPS.pod +GENERATE[html/man7/OSSL_PROVIDER-FIPS.html]=man7/OSSL_PROVIDER-FIPS.pod +DEPEND[man/man7/OSSL_PROVIDER-FIPS.7]=man7/OSSL_PROVIDER-FIPS.pod +GENERATE[man/man7/OSSL_PROVIDER-FIPS.7]=man7/OSSL_PROVIDER-FIPS.pod +DEPEND[html/man7/OSSL_PROVIDER-base.html]=man7/OSSL_PROVIDER-base.pod +GENERATE[html/man7/OSSL_PROVIDER-base.html]=man7/OSSL_PROVIDER-base.pod +DEPEND[man/man7/OSSL_PROVIDER-base.7]=man7/OSSL_PROVIDER-base.pod +GENERATE[man/man7/OSSL_PROVIDER-base.7]=man7/OSSL_PROVIDER-base.pod +DEPEND[html/man7/OSSL_PROVIDER-default.html]=man7/OSSL_PROVIDER-default.pod +GENERATE[html/man7/OSSL_PROVIDER-default.html]=man7/OSSL_PROVIDER-default.pod +DEPEND[man/man7/OSSL_PROVIDER-default.7]=man7/OSSL_PROVIDER-default.pod +GENERATE[man/man7/OSSL_PROVIDER-default.7]=man7/OSSL_PROVIDER-default.pod +DEPEND[html/man7/OSSL_PROVIDER-legacy.html]=man7/OSSL_PROVIDER-legacy.pod +GENERATE[html/man7/OSSL_PROVIDER-legacy.html]=man7/OSSL_PROVIDER-legacy.pod +DEPEND[man/man7/OSSL_PROVIDER-legacy.7]=man7/OSSL_PROVIDER-legacy.pod +GENERATE[man/man7/OSSL_PROVIDER-legacy.7]=man7/OSSL_PROVIDER-legacy.pod +DEPEND[html/man7/OSSL_PROVIDER-null.html]=man7/OSSL_PROVIDER-null.pod +GENERATE[html/man7/OSSL_PROVIDER-null.html]=man7/OSSL_PROVIDER-null.pod +DEPEND[man/man7/OSSL_PROVIDER-null.7]=man7/OSSL_PROVIDER-null.pod +GENERATE[man/man7/OSSL_PROVIDER-null.7]=man7/OSSL_PROVIDER-null.pod +DEPEND[html/man7/RAND.html]=man7/RAND.pod +GENERATE[html/man7/RAND.html]=man7/RAND.pod +DEPEND[man/man7/RAND.7]=man7/RAND.pod +GENERATE[man/man7/RAND.7]=man7/RAND.pod +DEPEND[html/man7/RSA-PSS.html]=man7/RSA-PSS.pod +GENERATE[html/man7/RSA-PSS.html]=man7/RSA-PSS.pod +DEPEND[man/man7/RSA-PSS.7]=man7/RSA-PSS.pod +GENERATE[man/man7/RSA-PSS.7]=man7/RSA-PSS.pod +DEPEND[html/man7/X25519.html]=man7/X25519.pod +GENERATE[html/man7/X25519.html]=man7/X25519.pod +DEPEND[man/man7/X25519.7]=man7/X25519.pod +GENERATE[man/man7/X25519.7]=man7/X25519.pod +DEPEND[html/man7/bio.html]=man7/bio.pod +GENERATE[html/man7/bio.html]=man7/bio.pod +DEPEND[man/man7/bio.7]=man7/bio.pod +GENERATE[man/man7/bio.7]=man7/bio.pod +DEPEND[html/man7/crypto.html]=man7/crypto.pod +GENERATE[html/man7/crypto.html]=man7/crypto.pod +DEPEND[man/man7/crypto.7]=man7/crypto.pod +GENERATE[man/man7/crypto.7]=man7/crypto.pod +DEPEND[html/man7/ct.html]=man7/ct.pod +GENERATE[html/man7/ct.html]=man7/ct.pod +DEPEND[man/man7/ct.7]=man7/ct.pod +GENERATE[man/man7/ct.7]=man7/ct.pod +DEPEND[html/man7/des_modes.html]=man7/des_modes.pod +GENERATE[html/man7/des_modes.html]=man7/des_modes.pod +DEPEND[man/man7/des_modes.7]=man7/des_modes.pod +GENERATE[man/man7/des_modes.7]=man7/des_modes.pod +DEPEND[html/man7/evp.html]=man7/evp.pod +GENERATE[html/man7/evp.html]=man7/evp.pod +DEPEND[man/man7/evp.7]=man7/evp.pod +GENERATE[man/man7/evp.7]=man7/evp.pod +DEPEND[html/man7/fips_module.html]=man7/fips_module.pod +GENERATE[html/man7/fips_module.html]=man7/fips_module.pod +DEPEND[man/man7/fips_module.7]=man7/fips_module.pod +GENERATE[man/man7/fips_module.7]=man7/fips_module.pod +DEPEND[html/man7/life_cycle-cipher.html]=man7/life_cycle-cipher.pod +GENERATE[html/man7/life_cycle-cipher.html]=man7/life_cycle-cipher.pod +DEPEND[man/man7/life_cycle-cipher.7]=man7/life_cycle-cipher.pod +GENERATE[man/man7/life_cycle-cipher.7]=man7/life_cycle-cipher.pod +DEPEND[html/man7/life_cycle-digest.html]=man7/life_cycle-digest.pod +GENERATE[html/man7/life_cycle-digest.html]=man7/life_cycle-digest.pod +DEPEND[man/man7/life_cycle-digest.7]=man7/life_cycle-digest.pod +GENERATE[man/man7/life_cycle-digest.7]=man7/life_cycle-digest.pod +DEPEND[html/man7/life_cycle-kdf.html]=man7/life_cycle-kdf.pod +GENERATE[html/man7/life_cycle-kdf.html]=man7/life_cycle-kdf.pod +DEPEND[man/man7/life_cycle-kdf.7]=man7/life_cycle-kdf.pod +GENERATE[man/man7/life_cycle-kdf.7]=man7/life_cycle-kdf.pod +DEPEND[html/man7/life_cycle-mac.html]=man7/life_cycle-mac.pod +GENERATE[html/man7/life_cycle-mac.html]=man7/life_cycle-mac.pod +DEPEND[man/man7/life_cycle-mac.7]=man7/life_cycle-mac.pod +GENERATE[man/man7/life_cycle-mac.7]=man7/life_cycle-mac.pod +DEPEND[html/man7/life_cycle-pkey.html]=man7/life_cycle-pkey.pod +GENERATE[html/man7/life_cycle-pkey.html]=man7/life_cycle-pkey.pod +DEPEND[man/man7/life_cycle-pkey.7]=man7/life_cycle-pkey.pod +GENERATE[man/man7/life_cycle-pkey.7]=man7/life_cycle-pkey.pod +DEPEND[html/man7/life_cycle-rand.html]=man7/life_cycle-rand.pod +GENERATE[html/man7/life_cycle-rand.html]=man7/life_cycle-rand.pod +DEPEND[man/man7/life_cycle-rand.7]=man7/life_cycle-rand.pod +GENERATE[man/man7/life_cycle-rand.7]=man7/life_cycle-rand.pod +DEPEND[html/man7/migration_guide.html]=man7/migration_guide.pod +GENERATE[html/man7/migration_guide.html]=man7/migration_guide.pod +DEPEND[man/man7/migration_guide.7]=man7/migration_guide.pod +GENERATE[man/man7/migration_guide.7]=man7/migration_guide.pod +DEPEND[html/man7/openssl-core.h.html]=man7/openssl-core.h.pod +GENERATE[html/man7/openssl-core.h.html]=man7/openssl-core.h.pod +DEPEND[man/man7/openssl-core.h.7]=man7/openssl-core.h.pod +GENERATE[man/man7/openssl-core.h.7]=man7/openssl-core.h.pod +DEPEND[html/man7/openssl-core_dispatch.h.html]=man7/openssl-core_dispatch.h.pod +GENERATE[html/man7/openssl-core_dispatch.h.html]=man7/openssl-core_dispatch.h.pod +DEPEND[man/man7/openssl-core_dispatch.h.7]=man7/openssl-core_dispatch.h.pod +GENERATE[man/man7/openssl-core_dispatch.h.7]=man7/openssl-core_dispatch.h.pod +DEPEND[html/man7/openssl-core_names.h.html]=man7/openssl-core_names.h.pod +GENERATE[html/man7/openssl-core_names.h.html]=man7/openssl-core_names.h.pod +DEPEND[man/man7/openssl-core_names.h.7]=man7/openssl-core_names.h.pod +GENERATE[man/man7/openssl-core_names.h.7]=man7/openssl-core_names.h.pod +DEPEND[html/man7/openssl-env.html]=man7/openssl-env.pod +GENERATE[html/man7/openssl-env.html]=man7/openssl-env.pod +DEPEND[man/man7/openssl-env.7]=man7/openssl-env.pod +GENERATE[man/man7/openssl-env.7]=man7/openssl-env.pod +DEPEND[html/man7/openssl-glossary.html]=man7/openssl-glossary.pod +GENERATE[html/man7/openssl-glossary.html]=man7/openssl-glossary.pod +DEPEND[man/man7/openssl-glossary.7]=man7/openssl-glossary.pod +GENERATE[man/man7/openssl-glossary.7]=man7/openssl-glossary.pod +DEPEND[html/man7/openssl-threads.html]=man7/openssl-threads.pod +GENERATE[html/man7/openssl-threads.html]=man7/openssl-threads.pod +DEPEND[man/man7/openssl-threads.7]=man7/openssl-threads.pod +GENERATE[man/man7/openssl-threads.7]=man7/openssl-threads.pod +DEPEND[html/man7/openssl_user_macros.html]=man7/openssl_user_macros.pod +GENERATE[html/man7/openssl_user_macros.html]=man7/openssl_user_macros.pod +DEPEND[man/man7/openssl_user_macros.7]=man7/openssl_user_macros.pod +GENERATE[man/man7/openssl_user_macros.7]=man7/openssl_user_macros.pod +DEPEND[man7/openssl_user_macros.pod]{pod}=man7/openssl_user_macros.pod.in +GENERATE[man7/openssl_user_macros.pod]=man7/openssl_user_macros.pod.in +DEPEND[html/man7/ossl_store-file.html]=man7/ossl_store-file.pod +GENERATE[html/man7/ossl_store-file.html]=man7/ossl_store-file.pod +DEPEND[man/man7/ossl_store-file.7]=man7/ossl_store-file.pod +GENERATE[man/man7/ossl_store-file.7]=man7/ossl_store-file.pod +DEPEND[html/man7/ossl_store.html]=man7/ossl_store.pod +GENERATE[html/man7/ossl_store.html]=man7/ossl_store.pod +DEPEND[man/man7/ossl_store.7]=man7/ossl_store.pod +GENERATE[man/man7/ossl_store.7]=man7/ossl_store.pod +DEPEND[html/man7/passphrase-encoding.html]=man7/passphrase-encoding.pod +GENERATE[html/man7/passphrase-encoding.html]=man7/passphrase-encoding.pod +DEPEND[man/man7/passphrase-encoding.7]=man7/passphrase-encoding.pod +GENERATE[man/man7/passphrase-encoding.7]=man7/passphrase-encoding.pod +DEPEND[html/man7/property.html]=man7/property.pod +GENERATE[html/man7/property.html]=man7/property.pod +DEPEND[man/man7/property.7]=man7/property.pod +GENERATE[man/man7/property.7]=man7/property.pod +DEPEND[html/man7/provider-asym_cipher.html]=man7/provider-asym_cipher.pod +GENERATE[html/man7/provider-asym_cipher.html]=man7/provider-asym_cipher.pod +DEPEND[man/man7/provider-asym_cipher.7]=man7/provider-asym_cipher.pod +GENERATE[man/man7/provider-asym_cipher.7]=man7/provider-asym_cipher.pod +DEPEND[html/man7/provider-base.html]=man7/provider-base.pod +GENERATE[html/man7/provider-base.html]=man7/provider-base.pod +DEPEND[man/man7/provider-base.7]=man7/provider-base.pod +GENERATE[man/man7/provider-base.7]=man7/provider-base.pod +DEPEND[html/man7/provider-cipher.html]=man7/provider-cipher.pod +GENERATE[html/man7/provider-cipher.html]=man7/provider-cipher.pod +DEPEND[man/man7/provider-cipher.7]=man7/provider-cipher.pod +GENERATE[man/man7/provider-cipher.7]=man7/provider-cipher.pod +DEPEND[html/man7/provider-decoder.html]=man7/provider-decoder.pod +GENERATE[html/man7/provider-decoder.html]=man7/provider-decoder.pod +DEPEND[man/man7/provider-decoder.7]=man7/provider-decoder.pod +GENERATE[man/man7/provider-decoder.7]=man7/provider-decoder.pod +DEPEND[html/man7/provider-digest.html]=man7/provider-digest.pod +GENERATE[html/man7/provider-digest.html]=man7/provider-digest.pod +DEPEND[man/man7/provider-digest.7]=man7/provider-digest.pod +GENERATE[man/man7/provider-digest.7]=man7/provider-digest.pod +DEPEND[html/man7/provider-encoder.html]=man7/provider-encoder.pod +GENERATE[html/man7/provider-encoder.html]=man7/provider-encoder.pod +DEPEND[man/man7/provider-encoder.7]=man7/provider-encoder.pod +GENERATE[man/man7/provider-encoder.7]=man7/provider-encoder.pod +DEPEND[html/man7/provider-kdf.html]=man7/provider-kdf.pod +GENERATE[html/man7/provider-kdf.html]=man7/provider-kdf.pod +DEPEND[man/man7/provider-kdf.7]=man7/provider-kdf.pod +GENERATE[man/man7/provider-kdf.7]=man7/provider-kdf.pod +DEPEND[html/man7/provider-kem.html]=man7/provider-kem.pod +GENERATE[html/man7/provider-kem.html]=man7/provider-kem.pod +DEPEND[man/man7/provider-kem.7]=man7/provider-kem.pod +GENERATE[man/man7/provider-kem.7]=man7/provider-kem.pod +DEPEND[html/man7/provider-keyexch.html]=man7/provider-keyexch.pod +GENERATE[html/man7/provider-keyexch.html]=man7/provider-keyexch.pod +DEPEND[man/man7/provider-keyexch.7]=man7/provider-keyexch.pod +GENERATE[man/man7/provider-keyexch.7]=man7/provider-keyexch.pod +DEPEND[html/man7/provider-keymgmt.html]=man7/provider-keymgmt.pod +GENERATE[html/man7/provider-keymgmt.html]=man7/provider-keymgmt.pod +DEPEND[man/man7/provider-keymgmt.7]=man7/provider-keymgmt.pod +GENERATE[man/man7/provider-keymgmt.7]=man7/provider-keymgmt.pod +DEPEND[html/man7/provider-mac.html]=man7/provider-mac.pod +GENERATE[html/man7/provider-mac.html]=man7/provider-mac.pod +DEPEND[man/man7/provider-mac.7]=man7/provider-mac.pod +GENERATE[man/man7/provider-mac.7]=man7/provider-mac.pod +DEPEND[html/man7/provider-object.html]=man7/provider-object.pod +GENERATE[html/man7/provider-object.html]=man7/provider-object.pod +DEPEND[man/man7/provider-object.7]=man7/provider-object.pod +GENERATE[man/man7/provider-object.7]=man7/provider-object.pod +DEPEND[html/man7/provider-rand.html]=man7/provider-rand.pod +GENERATE[html/man7/provider-rand.html]=man7/provider-rand.pod +DEPEND[man/man7/provider-rand.7]=man7/provider-rand.pod +GENERATE[man/man7/provider-rand.7]=man7/provider-rand.pod +DEPEND[html/man7/provider-signature.html]=man7/provider-signature.pod +GENERATE[html/man7/provider-signature.html]=man7/provider-signature.pod +DEPEND[man/man7/provider-signature.7]=man7/provider-signature.pod +GENERATE[man/man7/provider-signature.7]=man7/provider-signature.pod +DEPEND[html/man7/provider-storemgmt.html]=man7/provider-storemgmt.pod +GENERATE[html/man7/provider-storemgmt.html]=man7/provider-storemgmt.pod +DEPEND[man/man7/provider-storemgmt.7]=man7/provider-storemgmt.pod +GENERATE[man/man7/provider-storemgmt.7]=man7/provider-storemgmt.pod +DEPEND[html/man7/provider.html]=man7/provider.pod +GENERATE[html/man7/provider.html]=man7/provider.pod +DEPEND[man/man7/provider.7]=man7/provider.pod +GENERATE[man/man7/provider.7]=man7/provider.pod +DEPEND[html/man7/proxy-certificates.html]=man7/proxy-certificates.pod +GENERATE[html/man7/proxy-certificates.html]=man7/proxy-certificates.pod +DEPEND[man/man7/proxy-certificates.7]=man7/proxy-certificates.pod +GENERATE[man/man7/proxy-certificates.7]=man7/proxy-certificates.pod +DEPEND[html/man7/ssl.html]=man7/ssl.pod +GENERATE[html/man7/ssl.html]=man7/ssl.pod +DEPEND[man/man7/ssl.7]=man7/ssl.pod +GENERATE[man/man7/ssl.7]=man7/ssl.pod +DEPEND[html/man7/x509.html]=man7/x509.pod +GENERATE[html/man7/x509.html]=man7/x509.pod +DEPEND[man/man7/x509.7]=man7/x509.pod +GENERATE[man/man7/x509.7]=man7/x509.pod +IMAGEDOCS[man7]=man7/img/cipher.png \ +man7/img/digest.png \ +man7/img/kdf.png \ +man7/img/mac.png \ +man7/img/pkey.png \ +man7/img/rand.png +HTMLDOCS[man7]=html/man7/EVP_ASYM_CIPHER-RSA.html \ +html/man7/EVP_ASYM_CIPHER-SM2.html \ +html/man7/EVP_CIPHER-AES.html \ +html/man7/EVP_CIPHER-ARIA.html \ +html/man7/EVP_CIPHER-BLOWFISH.html \ +html/man7/EVP_CIPHER-CAMELLIA.html \ +html/man7/EVP_CIPHER-CAST.html \ +html/man7/EVP_CIPHER-CHACHA.html \ +html/man7/EVP_CIPHER-DES.html \ +html/man7/EVP_CIPHER-IDEA.html \ +html/man7/EVP_CIPHER-RC2.html \ +html/man7/EVP_CIPHER-RC4.html \ +html/man7/EVP_CIPHER-RC5.html \ +html/man7/EVP_CIPHER-SEED.html \ +html/man7/EVP_CIPHER-SM4.html \ +html/man7/EVP_KDF-HKDF.html \ +html/man7/EVP_KDF-KB.html \ +html/man7/EVP_KDF-KRB5KDF.html \ +html/man7/EVP_KDF-PBKDF1.html \ +html/man7/EVP_KDF-PBKDF2.html \ +html/man7/EVP_KDF-PKCS12KDF.html \ +html/man7/EVP_KDF-SCRYPT.html \ +html/man7/EVP_KDF-SS.html \ +html/man7/EVP_KDF-SSHKDF.html \ +html/man7/EVP_KDF-TLS13_KDF.html \ +html/man7/EVP_KDF-TLS1_PRF.html \ +html/man7/EVP_KDF-X942-ASN1.html \ +html/man7/EVP_KDF-X942-CONCAT.html \ +html/man7/EVP_KDF-X963.html \ +html/man7/EVP_KEM-RSA.html \ +html/man7/EVP_KEYEXCH-DH.html \ +html/man7/EVP_KEYEXCH-ECDH.html \ +html/man7/EVP_KEYEXCH-X25519.html \ +html/man7/EVP_MAC-BLAKE2.html \ +html/man7/EVP_MAC-CMAC.html \ +html/man7/EVP_MAC-GMAC.html \ +html/man7/EVP_MAC-HMAC.html \ +html/man7/EVP_MAC-KMAC.html \ +html/man7/EVP_MAC-Poly1305.html \ +html/man7/EVP_MAC-Siphash.html \ +html/man7/EVP_MD-BLAKE2.html \ +html/man7/EVP_MD-MD2.html \ +html/man7/EVP_MD-MD4.html \ +html/man7/EVP_MD-MD5-SHA1.html \ +html/man7/EVP_MD-MD5.html \ +html/man7/EVP_MD-MDC2.html \ +html/man7/EVP_MD-RIPEMD160.html \ +html/man7/EVP_MD-SHA1.html \ +html/man7/EVP_MD-SHA2.html \ +html/man7/EVP_MD-SHA3.html \ +html/man7/EVP_MD-SHAKE.html \ +html/man7/EVP_MD-SM3.html \ +html/man7/EVP_MD-WHIRLPOOL.html \ +html/man7/EVP_MD-common.html \ +html/man7/EVP_PKEY-DH.html \ +html/man7/EVP_PKEY-DSA.html \ +html/man7/EVP_PKEY-EC.html \ +html/man7/EVP_PKEY-FFC.html \ +html/man7/EVP_PKEY-HMAC.html \ +html/man7/EVP_PKEY-RSA.html \ +html/man7/EVP_PKEY-SM2.html \ +html/man7/EVP_PKEY-X25519.html \ +html/man7/EVP_RAND-CTR-DRBG.html \ +html/man7/EVP_RAND-HASH-DRBG.html \ +html/man7/EVP_RAND-HMAC-DRBG.html \ +html/man7/EVP_RAND-SEED-SRC.html \ +html/man7/EVP_RAND-TEST-RAND.html \ +html/man7/EVP_RAND.html \ +html/man7/EVP_SIGNATURE-DSA.html \ +html/man7/EVP_SIGNATURE-ECDSA.html \ +html/man7/EVP_SIGNATURE-ED25519.html \ +html/man7/EVP_SIGNATURE-HMAC.html \ +html/man7/EVP_SIGNATURE-RSA.html \ +html/man7/OSSL_PROVIDER-FIPS.html \ +html/man7/OSSL_PROVIDER-base.html \ +html/man7/OSSL_PROVIDER-default.html \ +html/man7/OSSL_PROVIDER-legacy.html \ +html/man7/OSSL_PROVIDER-null.html \ +html/man7/RAND.html \ +html/man7/RSA-PSS.html \ +html/man7/X25519.html \ +html/man7/bio.html \ +html/man7/crypto.html \ +html/man7/ct.html \ +html/man7/des_modes.html \ +html/man7/evp.html \ +html/man7/fips_module.html \ +html/man7/life_cycle-cipher.html \ +html/man7/life_cycle-digest.html \ +html/man7/life_cycle-kdf.html \ +html/man7/life_cycle-mac.html \ +html/man7/life_cycle-pkey.html \ +html/man7/life_cycle-rand.html \ +html/man7/migration_guide.html \ +html/man7/openssl-core.h.html \ +html/man7/openssl-core_dispatch.h.html \ +html/man7/openssl-core_names.h.html \ +html/man7/openssl-env.html \ +html/man7/openssl-glossary.html \ +html/man7/openssl-threads.html \ +html/man7/openssl_user_macros.html \ +html/man7/ossl_store-file.html \ +html/man7/ossl_store.html \ +html/man7/passphrase-encoding.html \ +html/man7/property.html \ +html/man7/provider-asym_cipher.html \ +html/man7/provider-base.html \ +html/man7/provider-cipher.html \ +html/man7/provider-decoder.html \ +html/man7/provider-digest.html \ +html/man7/provider-encoder.html \ +html/man7/provider-kdf.html \ +html/man7/provider-kem.html \ +html/man7/provider-keyexch.html \ +html/man7/provider-keymgmt.html \ +html/man7/provider-mac.html \ +html/man7/provider-object.html \ +html/man7/provider-rand.html \ +html/man7/provider-signature.html \ +html/man7/provider-storemgmt.html \ +html/man7/provider.html \ +html/man7/proxy-certificates.html \ +html/man7/ssl.html \ +html/man7/x509.html +MANDOCS[man7]=man/man7/EVP_ASYM_CIPHER-RSA.7 \ +man/man7/EVP_ASYM_CIPHER-SM2.7 \ +man/man7/EVP_CIPHER-AES.7 \ +man/man7/EVP_CIPHER-ARIA.7 \ +man/man7/EVP_CIPHER-BLOWFISH.7 \ +man/man7/EVP_CIPHER-CAMELLIA.7 \ +man/man7/EVP_CIPHER-CAST.7 \ +man/man7/EVP_CIPHER-CHACHA.7 \ +man/man7/EVP_CIPHER-DES.7 \ +man/man7/EVP_CIPHER-IDEA.7 \ +man/man7/EVP_CIPHER-RC2.7 \ +man/man7/EVP_CIPHER-RC4.7 \ +man/man7/EVP_CIPHER-RC5.7 \ +man/man7/EVP_CIPHER-SEED.7 \ +man/man7/EVP_CIPHER-SM4.7 \ +man/man7/EVP_KDF-HKDF.7 \ +man/man7/EVP_KDF-KB.7 \ +man/man7/EVP_KDF-KRB5KDF.7 \ +man/man7/EVP_KDF-PBKDF1.7 \ +man/man7/EVP_KDF-PBKDF2.7 \ +man/man7/EVP_KDF-PKCS12KDF.7 \ +man/man7/EVP_KDF-SCRYPT.7 \ +man/man7/EVP_KDF-SS.7 \ +man/man7/EVP_KDF-SSHKDF.7 \ +man/man7/EVP_KDF-TLS13_KDF.7 \ +man/man7/EVP_KDF-TLS1_PRF.7 \ +man/man7/EVP_KDF-X942-ASN1.7 \ +man/man7/EVP_KDF-X942-CONCAT.7 \ +man/man7/EVP_KDF-X963.7 \ +man/man7/EVP_KEM-RSA.7 \ +man/man7/EVP_KEYEXCH-DH.7 \ +man/man7/EVP_KEYEXCH-ECDH.7 \ +man/man7/EVP_KEYEXCH-X25519.7 \ +man/man7/EVP_MAC-BLAKE2.7 \ +man/man7/EVP_MAC-CMAC.7 \ +man/man7/EVP_MAC-GMAC.7 \ +man/man7/EVP_MAC-HMAC.7 \ +man/man7/EVP_MAC-KMAC.7 \ +man/man7/EVP_MAC-Poly1305.7 \ +man/man7/EVP_MAC-Siphash.7 \ +man/man7/EVP_MD-BLAKE2.7 \ +man/man7/EVP_MD-MD2.7 \ +man/man7/EVP_MD-MD4.7 \ +man/man7/EVP_MD-MD5-SHA1.7 \ +man/man7/EVP_MD-MD5.7 \ +man/man7/EVP_MD-MDC2.7 \ +man/man7/EVP_MD-RIPEMD160.7 \ +man/man7/EVP_MD-SHA1.7 \ +man/man7/EVP_MD-SHA2.7 \ +man/man7/EVP_MD-SHA3.7 \ +man/man7/EVP_MD-SHAKE.7 \ +man/man7/EVP_MD-SM3.7 \ +man/man7/EVP_MD-WHIRLPOOL.7 \ +man/man7/EVP_MD-common.7 \ +man/man7/EVP_PKEY-DH.7 \ +man/man7/EVP_PKEY-DSA.7 \ +man/man7/EVP_PKEY-EC.7 \ +man/man7/EVP_PKEY-FFC.7 \ +man/man7/EVP_PKEY-HMAC.7 \ +man/man7/EVP_PKEY-RSA.7 \ +man/man7/EVP_PKEY-SM2.7 \ +man/man7/EVP_PKEY-X25519.7 \ +man/man7/EVP_RAND-CTR-DRBG.7 \ +man/man7/EVP_RAND-HASH-DRBG.7 \ +man/man7/EVP_RAND-HMAC-DRBG.7 \ +man/man7/EVP_RAND-SEED-SRC.7 \ +man/man7/EVP_RAND-TEST-RAND.7 \ +man/man7/EVP_RAND.7 \ +man/man7/EVP_SIGNATURE-DSA.7 \ +man/man7/EVP_SIGNATURE-ECDSA.7 \ +man/man7/EVP_SIGNATURE-ED25519.7 \ +man/man7/EVP_SIGNATURE-HMAC.7 \ +man/man7/EVP_SIGNATURE-RSA.7 \ +man/man7/OSSL_PROVIDER-FIPS.7 \ +man/man7/OSSL_PROVIDER-base.7 \ +man/man7/OSSL_PROVIDER-default.7 \ +man/man7/OSSL_PROVIDER-legacy.7 \ +man/man7/OSSL_PROVIDER-null.7 \ +man/man7/RAND.7 \ +man/man7/RSA-PSS.7 \ +man/man7/X25519.7 \ +man/man7/bio.7 \ +man/man7/crypto.7 \ +man/man7/ct.7 \ +man/man7/des_modes.7 \ +man/man7/evp.7 \ +man/man7/fips_module.7 \ +man/man7/life_cycle-cipher.7 \ +man/man7/life_cycle-digest.7 \ +man/man7/life_cycle-kdf.7 \ +man/man7/life_cycle-mac.7 \ +man/man7/life_cycle-pkey.7 \ +man/man7/life_cycle-rand.7 \ +man/man7/migration_guide.7 \ +man/man7/openssl-core.h.7 \ +man/man7/openssl-core_dispatch.h.7 \ +man/man7/openssl-core_names.h.7 \ +man/man7/openssl-env.7 \ +man/man7/openssl-glossary.7 \ +man/man7/openssl-threads.7 \ +man/man7/openssl_user_macros.7 \ +man/man7/ossl_store-file.7 \ +man/man7/ossl_store.7 \ +man/man7/passphrase-encoding.7 \ +man/man7/property.7 \ +man/man7/provider-asym_cipher.7 \ +man/man7/provider-base.7 \ +man/man7/provider-cipher.7 \ +man/man7/provider-decoder.7 \ +man/man7/provider-digest.7 \ +man/man7/provider-encoder.7 \ +man/man7/provider-kdf.7 \ +man/man7/provider-kem.7 \ +man/man7/provider-keyexch.7 \ +man/man7/provider-keymgmt.7 \ +man/man7/provider-mac.7 \ +man/man7/provider-object.7 \ +man/man7/provider-rand.7 \ +man/man7/provider-signature.7 \ +man/man7/provider-storemgmt.7 \ +man/man7/provider.7 \ +man/man7/proxy-certificates.7 \ +man/man7/ssl.7 \ +man/man7/x509.7 + diff --git a/crypto/openssl/doc/build.info.in b/crypto/openssl/doc/build.info.in new file mode 100644 index 000000000000..e8dae7058a6e --- /dev/null +++ b/crypto/openssl/doc/build.info.in @@ -0,0 +1,80 @@ +SUBDIRS = man1 + +{- + use File::Spec::Functions qw(:DEFAULT abs2rel rel2abs); + use File::Basename; + + my $sourcedir = catdir($config{sourcedir}, 'doc'); + + foreach my $section ((1, 3, 5, 7)) { + my @imagefiles = (); + my @htmlfiles = (); + my @manfiles = (); + my %pngfiles = + map { $_ => 1 } glob catfile($sourcedir, "man$section", "img", "*.png"); + my %podfiles = + map { $_ => 1 } glob catfile($sourcedir, "man$section", "*.pod"); + my %podinfiles = + map { $_ => 1 } glob catfile($sourcedir, "man$section", "*.pod.in"); + + foreach (keys %podinfiles) { + (my $p = $_) =~ s|\.in$||i; + $podfiles{$p} = 1; + } + + foreach my $p (sort keys %podfiles) { + my $podfile = abs2rel($p, $sourcedir); + my $podname = basename($podfile, '.pod'); + my $podinfile = $podinfiles{"$p.in"} ? "$podfile.in" : undef; + + my $podname = basename($podfile, ".pod"); + + my $htmlfile = abs2rel(catfile($buildtop, "doc", "html", "man$section", + "$podname.html"), + catdir($buildtop, "doc")); + my $manfile = abs2rel(catfile($buildtop, "doc", "man", "man$section", + "$podname.$section"), + catdir($buildtop, "doc")); + + # The build.info format requires file specs to be in Unix format. + # Especially, since VMS file specs use [ and ], the build.info parser + # will otherwise get terribly confused. + if ($^O eq 'VMS') { + $htmlfile = VMS::Filespec::unixify($htmlfile); + $manfile = VMS::Filespec::unixify($manfile); + $podfile = VMS::Filespec::unixify($podfile); + $podinfile = VMS::Filespec::unixify($podinfile) + if defined $podinfile; + } elsif ($^O eq 'MSWin32') { + $htmlfile =~ s|\\|/|g; + $manfile =~ s|\\|/|g; + $podfile =~ s|\\|/|g; + $podinfile =~ s|\\|/|g + if defined $podinfile; + } + push @htmlfiles, $htmlfile; + push @manfiles, $manfile; + $OUT .= << "_____"; +DEPEND[$htmlfile]=$podfile +GENERATE[$htmlfile]=$podfile +DEPEND[$manfile]=$podfile +GENERATE[$manfile]=$podfile +_____ + $OUT .= << "_____" if $podinfile; +DEPEND[$podfile]{pod}=$podinfile +GENERATE[$podfile]=$podinfile +_____ + } + + foreach my $p (sort keys %pngfiles) { + my $relpath = abs2rel($p, $sourcedir); + my $imagefile = abs2rel(catfile($buildtop, "doc", "$relpath"), + catdir($buildtop, "doc")); + push @imagefiles, $imagefile; + } + + $OUT .= "IMAGEDOCS[man$section]=" . join(" \\\n", @imagefiles) . "\n"; + $OUT .= "HTMLDOCS[man$section]=" . join(" \\\n", @htmlfiles) . "\n"; + $OUT .= "MANDOCS[man$section]=" . join(" \\\n", @manfiles) . "\n"; + } + -} diff --git a/crypto/openssl/doc/fingerprints.txt b/crypto/openssl/doc/fingerprints.txt index 3604fbdc658c..4f95f2beaec8 100644 --- a/crypto/openssl/doc/fingerprints.txt +++ b/crypto/openssl/doc/fingerprints.txt @@ -12,23 +12,14 @@ in the file named openssl-1.0.1h.tar.gz.asc. The following is the list of fingerprints for the keys that are currently in use to sign OpenSSL distributions: -pub 4096R/7DF9EE8C 2014-10-04 - Key fingerprint = 7953 AC1F BC3D C8B3 B292 393E D5E9 E43F 7DF9 EE8C -uid Richard Levitte -uid Richard Levitte -uid Richard Levitte +Richard Levitte: +7953 AC1F BC3D C8B3 B292 393E D5E9 E43F 7DF9 EE8C -pub 2048R/0E604491 2013-04-30 - Key fingerprint = 8657 ABB2 60F0 56B1 E519 0839 D9C4 D26D 0E60 4491 -uid Matt Caswell -uid Matt Caswell +Matt Caswell: +8657 ABB2 60F0 56B1 E519 0839 D9C4 D26D 0E60 4491 -pub rsa4096 2021-02-14 - B7C1 C143 60F3 53A3 6862 E4D5 231C 84CD DCC6 9C45 -uid Paul Dale +Paul Dale: +B7C1 C143 60F3 53A3 6862 E4D5 231C 84CD DCC6 9C45 -pub rsa4096 2021-07-16 - A21F AB74 B008 8AA3 6115 2586 B8EF 1A6B A9DA 2D5C -uid Tomáš Mráz -uid Tomáš Mráz -uid Tomáš Mráz +Tomáš Mráz: +A21F AB74 B008 8AA3 6115 2586 B8EF 1A6B A9DA 2D5C diff --git a/crypto/openssl/doc/images/openssl.svg b/crypto/openssl/doc/images/openssl.svg new file mode 100644 index 000000000000..9cd6794fbdcf --- /dev/null +++ b/crypto/openssl/doc/images/openssl.svg @@ -0,0 +1,41 @@ + + + + + OpenSSL + Cryptography and SSL/TLS Toolkit + + diff --git a/crypto/openssl/doc/internal/man3/OPENSSL_SA.pod b/crypto/openssl/doc/internal/man3/OPENSSL_SA.pod new file mode 100644 index 000000000000..8124003d77a6 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/OPENSSL_SA.pod @@ -0,0 +1,131 @@ +=pod + +=head1 NAME + +OPENSSL_SA, ossl_sa_TYPE_new, ossl_sa_TYPE_free, +ossl_sa_TYPE_free_leaves, ossl_sa_TYPE_num, ossl_sa_TYPE_doall, +ossl_sa_TYPE_doall_arg, ossl_sa_TYPE_get, ossl_sa_TYPE_set +- sparse array container + +=head1 SYNOPSIS + + #include "crypto/sparse_array.h" + + typedef struct sparse_array_st OPENSSL_SA; + + SPARSE_ARRAY_OF(TYPE) + DEFINE_SPARSE_ARRAY_OF(TYPE) + + SPARSE_ARRAY_OF(TYPE) *ossl_sa_TYPE_new(void); + void ossl_sa_TYPE_free(const SPARSE_ARRAY_OF(TYPE) *sa); + void ossl_sa_TYPE_free_leaves(const SPARSE_ARRAY_OF(TYPE) *sa); + size_t ossl_sa_TYPE_num(const SPARSE_ARRAY_OF(TYPE) *sa); + void ossl_sa_TYPE_doall(const OPENSSL_SA *sa, void (*leaf)(ossl_uintmax_t, + void *)); + void ossl_sa_TYPE_doall_arg(const OPENSSL_SA *sa, + void (*leaf)(ossl_uintmax_t, void *, void *), + void *arg); + TYPE *ossl_sa_TYPE_get(const SPARSE_ARRAY_OF(TYPE) *sa, ossl_uintmax_t idx); + int ossl_sa_TYPE_set(SPARSE_ARRAY_OF(TYPE) *sa, ossl_uintmax_t idx, + TYPE *value); + +=head1 DESCRIPTION + +=begin comment + +POD is pretty good at recognising function names and making them appropriately +bold... however, when part of the function name is variable, we have to help +the processor along + +=end comment + +SPARSE_ARRAY_OF() returns the name for a sparse array of the specified +B>. DEFINE_SPARSE_ARRAY_OF() creates set of functions for a sparse +array of B>. This will mean that a pointer to type B> +is stored in each element of a sparse array, the type is referenced by +B(B>) and each function name begins with +B_>. For example: + + TYPE *ossl_sa_TYPE_get(SPARSE_ARRAY_OF(TYPE) *sa, ossl_uintmax_t idx); + +B_num>() returns the number of elements in I or 0 if I +is NULL. + +B_get>() returns element I in I, where I starts +at zero. If I refers to a value that has not been set then NULL is +returned. + +B_set>() sets element I in I to I, where I +starts at zero. The sparse array will be resized as required. + +B_new>() allocates a new empty sparse array. + +B_free>() frees up the I structure. It does I free up any +elements of I. After this call I is no longer valid. + +B_free_leaves>() frees up the I structure and all of its +elements. After this call I is no longer valid. + +B_doall>() calls the function I for each element in I +in ascending index order. The index position, within the sparse array, +of each item is passed as the first argument to the leaf function and a +pointer to the associated value is passed as the second argument. + +B_doall_arg>() calls the function I for each element in +I in ascending index order. The index position, within the sparse +array, of each item is passed as the first argument to the leaf function, +a pointer to the associated value is passed as the second argument and +the third argument is the user supplied I. + + +=head1 NOTES + +Sparse arrays are an internal data structure and should B be used by user +applications. + +Care should be taken when accessing sparse arrays in multi-threaded +environments. The B_set>() operation can cause the internal +structure of the sparse array to change which causes race conditions if the +sparse array is accessed in a different thread. + +SPARSE_ARRAY_OF() and DEFINE_SPARSE_ARRAY_OF() are implemented as macros. + +The underlying utility B API should not be used directly. It +defines these functions: OPENSSL_SA_doall, OPENSSL_SA_doall_arg, +OPENSSL_SA_free, OPENSSL_SA_free_leaves, OPENSSL_SA_get, OPENSSL_SA_new, +OPENSSL_SA_num and OPENSSL_SA_set. + +=head1 RETURN VALUES + +B_num>() returns the number of elements in the sparse array or +B<0> if the passed sparse array is NULL. + +B_get>() returns a pointer to a sparse array element or NULL if +the element has not be set. + +B_set>() return B<1> on success and B<0> on error. In the latter +case, the elements of the sparse array remain unchanged, although the internal +structures might have. + +B_new>() returns an empty sparse array or NULL if an error +occurs. + +B_doall>(), B_doall_arg>(), +B_free>() and B_free_leaves>() +do not return values. + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. Copyright +(c) 2019, Oracle and/or its affiliates. All rights reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use this +file except in compliance with the License. You can obtain a copy in the file +LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/OPTIONS.pod b/crypto/openssl/doc/internal/man3/OPTIONS.pod new file mode 100644 index 000000000000..90593ca46f6f --- /dev/null +++ b/crypto/openssl/doc/internal/man3/OPTIONS.pod @@ -0,0 +1,343 @@ +=pod + +=head1 NAME + +OPTIONS, OPT_PAIR, OPT_COMMON, OPT_ERR, OPT_EOF, OPT_HELP, +opt_init, opt_progname, opt_appname, opt_getprog, opt_help, +opt_begin, opt_next, opt_flag, opt_arg, opt_unknown, opt_cipher, +opt_cipher_any, opt_cipher_silent, opt_md, +opt_int, opt_int_arg, opt_long, opt_ulong, opt_intmax, opt_uintmax, +opt_format, opt_isdir, opt_string, opt_pair, +opt_num_rest, opt_rest, opt_legacy_okay +- Option parsing for commands and tests + +=head1 SYNOPSIS + + #include "opt.h" + + typedef struct { ... } OPTIONS; + typedef struct { ... } OPT_PAIR; + #define OPT_COMMON + #define OPT_ERR + #define OPT_EOF + #define OPT_HELP + + char *opt_init(int argc, char **argv, const OPTIONS *o); + char *opt_progname(const char *argv0); + char *opt_appname(const char *argv0); + char *opt_getprog(void); + void opt_help(const OPTIONS *list); + + void opt_begin(void); + int opt_next(void); + char *opt_flag(void); + char *opt_arg(void); + char *opt_unknown(void); + int opt_cipher(const char *name, EVP_CIPHER **cipherp); + int opt_cipher_any(const char *name, EVP_CIPHER **cipherp); + int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp); + int opt_md(const char *name, EVP_MD **mdp); + + int opt_int(const char *value, int *result); + int opt_int_arg(void); + int opt_long(const char *value, long *result); + int opt_ulong(const char *value, unsigned long *result); + int opt_intmax(const char *value, intmax_t *result); + int opt_uintmax(const char *value, uintmax_t *result); + + int opt_format(const char *s, unsigned long flags, int *result); + int opt_isdir(const char *name); + int opt_string(const char *name, const char **options); + int opt_pair(const char *name, const OPT_PAIR* pairs, int *result); + + int opt_num_rest(void); + char **opt_rest(void); + + int opt_legacy_okay(void); + +=head1 DESCRIPTION + +The functions on this page provide a common set of option-parsing for +the OpenSSL command and the internal test programs. +It is intended to be used like the standard getopt(3) routine, except +that multi-character flag names are supported, and a variety of parsing +and other utility functions are also provided. + +Programs that use this should make sure to set the appropriate C<-I> +flag. + +These routines expect a global B named B to point to +the equivalent of B. This is already done in the OpenSSL +application. + +=head2 Data Types + +Each program should define, near the main() routine, an enumeration +that is the set of options the program accepts. For example: + + typedef enum OPTION_choice { + OPT_COMMON, + OPT_YES, OPT_NAME, OPT_COUNT, OPT_OFILE, + ... + } OPTION_CHOICE; + +The first two lines must appear exactly as shown. +OPT_COMMON is a macro that expands to C. +In addition to defining symbolic names for the constants that opt_next() +returns, it also helps guarantee that every command has a C<-help> option. +The third line is a sample +set of flags, and the closing C name is used for error-checking +as discussed below. +By declaring the variable as an C, with the right warning +flags, the compiler could check that all specified options are handled. + +The B C specifies an option: what type of argument +it takes (if any), and an optional "help" string. It is a C +containing these fields: + + const char *name; + int retval; + int valtype; + const char *helpstr; + +The B is the name of the option that the user would type. Options +are words prefaced with a minus sign. If the user uses two minus signs, +this is also accepted for compatibility with other GNU software. Some +names are special, and are described below. + +The B is the value to return if the option is found. It should be +one of the choices in the enumeration above. + +The B defines what the option's parameter must be. It should +be chosen from the following set: + + \0 No value + '-' No value + 's' A text string + '/' A directory + '<' Name of file to open for input + '>' Name of file to open for output + 'n' A signed number that fits in the C type + 'p' A positive number that fits in the C type + 'N' A nonnegative number that fits in the C type + 'M' A signed number that fits in the C type + 'U' An unsigned number that fits in the C type + 'l' A signed number that fits in the C type + 'u' An unsigned number that fits in the C type + 'c' File in PEM, DER, or S/MIME format + 'F' A file in PEM or DER format + 'E' Like 'F' but also allows ENGINE + 'f' Any file format + +The B is what to display when the user uses the help option, +which should be C<"help">. + +A program should declare its options right after the enumeration, +and should follow the ordering of the enumeration as this helps +readability and maintainability: + + static OPTIONS my_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"yes", OPT_YES, '-', "Print an affirmative reply"}, + {"count", OPT_COUNT, 'p', "Repeat count"}, + {"output" OPT_OFILE, '>', "Output file; default is stdout"}, + {NULL} + }; + +Note that the B option is explicitly listed, and the list ends with +an entry of all-null's. The other two special options, B and B +should not appear in the array. + +If the help string is too long to fit into one line, it may be continued +on multiple lines; each entry should use B, like this: + + {"output" OPT_OFILE, '>', "Output file; default is stdout"}, + {OPT_MORE_STR, 0, 0, + "This flag is not really needed on Unix systems"}, + {OPT_MORE_STR, 0, 0, + "(Unix and descendents for ths win!)"} + +Each subsequent line will be indented the correct amount. + +By default, the help display will include a standard prolog: + + Usage: PROGRAM [options] + Valid options are: + ...detailed list of options... + +Sometimes there are parameters that should appear in the synopsis. +Use B as the first entry in your array: + + {OPT_HELP_STR, 1, '-', Usage: %s [options] [text...]\n"} + +The B and B are ignored, and the B should +follow the general construction as shown. The C<%s> will get the program +name. + +If a command has a large set of options, it can be useful to break them +into sections. Use the macro B or B +to indicate this. The two lines below are equivalent: + + OPT_SECTION("Validation"), + {OPT_SECTION_STR, 1, '-', "Validation options:\n"}, + +In addition to providing help about options, you can provide a description +of the parameters a command takes. These should appear at the end of +the options and are indicated by using B or the +B macro: + + OPT_PARAMETERS() + {OPT_PARAM_STR, 1, '-', "Parameters:\n"} + +Every "option" after after this should contain the parameter and +the help string: + + {"text", 0, 0, "Words to display (optional)"}, + +=head2 Functions + +The opt_init() function takes the I and I arguments given to main() +and a pointer I to the list of options. It returns the simple program +name, as defined by opt_progname(). + +The opt_progname() function takes the full pathname C in its I +parameter and returns +the simple short name of the executable, to be used for error messages and +the like. + +The opt_appname() function takes in its I parameter +the "application" name (such +as the specific command from L and appends it to the program +name. This function should only be called once. + +The opt_getprog() function returns the value set by opt_appname(). + +The opt_help() function takes a list of option definitions and prints a +nicely-formatted output. + +The opt_begin() function, which is called automatically by opt_init(), +can be used to reset the option parsing loop. + +The opt_next() function is called, once opt_init() has been called, +in a loop to fetch each option in turn. It returns -1, or B when the +end of arguments has been reached. This is typically done like this: + + prog = opt_init(argc, argv, my_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + fprintf(stderr, "%s: Use -help for summary\n", prog); + exit(1); + case OPT_HELP: + opt_help(my_options); + exit(0); + ...other options... + } + } + +Within the option parsing loop, the following functions may be called. + +The opt_flag() function returns the most recent option name +including the preceding C<->. + +The opt_arg() function returns the option's argument value, if there is one. + +The opt_unknown() function returns the unknown option. +In an option list, there can be at most one option with the empty string. +This is a "wildcard" or "unknown" option. For example, it allows an +option to be be taken as digest algorithm, like C<-sha1>. The function +opt_md() takes the specified I and fills in the digest into I. +The functions opt_cipher(), opt_cipher_any() and opt_cipher_silent() +each takes the specified I and fills in the cipher into I. +The function opt_cipher() only accepts ciphers which are not +AEAD and are not using XTS mode. The functions opt_cipher_any() and +opt_cipher_silent() accept any cipher, the latter not emitting an error +if the cipher is not located. + +There are a several useful functions for parsing numbers. These are +opt_int(), opt_long(), opt_ulong(), opt_intmax(), and opt_uintmax(). They all +take C<0x> to mean hexadecimal and C<0> to mean octal, and will do the +necessary range-checking. They return 1 if successful and fill in the +C pointer with the value, or 0 on error. Note that opt_next() +will also do range-check on the argument if the appropriate B +field is specified for the option. This means that error-checking inside +the C C can often be elided. + +The opt_int_arg() function is a convenience abbreviation to opt_int(). +It parses and returns an integer, assuming its range has been checked before. + +The opt_format() function takes a string value, +such as used with the B<-informat> or similar option, and fills +the value from the constants in F file. + +The opt_isdir() function returns 1 if the specified I is +a directory, or 0 if not. + +The opt_string() function checks that I appears in the +NULL-terminated array of strings. It returns 1 if found, +or prints a diagnostic and returns 0 if not. + +The opt_pair() function takes a list of I, each of which +has a text name and an integer. The specified I is +found on the list, it puts the index in I<*result>, and returns +1. If not found, it returns 0. + +The following functions can be used after processing all the options. + +The opt_num_rest() function returns what is left. + +The opt_rest() function returns a pointer to the first non-option. +If there were no parameters, it will point to the NULL that is +at the end of the standard I array. + +The opt_legacy_okay() function returns true if no options have been +specified that would preclude using legacy code paths. Currently, +the various provider options preclude legacy operation. This means, +for example, that specifying both B<-provider> and B<-engine> in the +same command line will not work as expected. + +=head2 Common Options + +There are a few groups of options that are common to many OpenSSL programs. +These are handled with sets of macros that define common option names +and common code to handle them. The categories are identified by a +letter: + + V Validation + X Extended certificate + S TLS/SSL + R Random state + +The B macro is used to define the numeration values, where B +is one of the letters above. The B macro is used to +list the set of common options, and the B is used in +the C statement. + +The common options are used throughout the sources for the OpenSSL commands. +They are also used with common descriptions when generating the +manpages, in the file F, which follow a similar naming +convention. + +=head1 RETURN VALUES + +Detailed above. + +=head1 EXAMPLES + +The best examples can be found in sources for the commands in the F +directory of the source tree. +A notable exception is F which uses this API, but does +things very differently. + +=head1 COPYRIGHT + +Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use this +file except in compliance with the License. You can obtain a copy in the file +LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/OSSL_DEPRECATED.pod b/crypto/openssl/doc/internal/man3/OSSL_DEPRECATED.pod new file mode 100644 index 000000000000..8370d60f18fb --- /dev/null +++ b/crypto/openssl/doc/internal/man3/OSSL_DEPRECATED.pod @@ -0,0 +1,54 @@ +=pod + +=head1 NAME + +OSSL_DEPRECATED, OSSL_DEPRECATED_FOR - General deprecation macros + +=head1 SYNOPSIS + + #include + + #define OSSL_DEPRECATED(since) + #define OSSL_DEPRECATED_FOR(since, msg) + +=head1 DESCRIPTION + +OSSL_DEPRECATED() implements the deprecated attribute if the compiler +supports it, otherwise it expands to nothing. It takes one argument +I that should be set to the OpenSSL version where the symbol was +deprecated, and will be displayed with the deprecation warning message, +for compilers that support user specified deprecation messages. + +OSSL_DEPRECATED_FOR() does the same as OSSL_DEPRECATED(), but also takes a +second argument I, which is an additional text messages to be displayed +with the deprecation warning along with the OpenSSL version number, for +compilers that support user specified deprecation messages. + +These macros are used to define the version specific deprecation macros +described in L. + +=begin comment + +[RETURN VALUES isn't relevant for these macros, but find-doc-nits demands +the presence of this section] + +=head1 RETURN VALUES + +[podchecker doesn't like empty sections] + +=end comment + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/OSSL_METHOD_STORE.pod b/crypto/openssl/doc/internal/man3/OSSL_METHOD_STORE.pod new file mode 100644 index 000000000000..70f6eb520ff3 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/OSSL_METHOD_STORE.pod @@ -0,0 +1,144 @@ +=pod + +=head1 NAME + +OSSL_METHOD_STORE, ossl_method_store_new, ossl_method_store_free, +ossl_method_store_init, ossl_method_store_cleanup, +ossl_method_store_add, ossl_method_store_fetch, +ossl_method_store_remove, ossl_method_store_remove_all_provided, +ossl_method_store_cache_get, ossl_method_store_cache_set, +ossl_method_store_cache_flush_all +- implementation method store and query + +=head1 SYNOPSIS + + #include "internal/property.h" + + typedef struct ossl_method_store_st OSSL_METHOD_STORE; + + OSSL_METHOD_STORE *ossl_method_store_new(OSSL_LIB_CTX *ctx); + void ossl_method_store_free(OSSL_METHOD_STORE *store); + int ossl_method_store_init(OSSL_LIB_CTX *ctx); + void ossl_method_store_cleanup(OSSL_LIB_CTX *ctx); + int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov, + int nid, const char *properties, void *method, + int (*method_up_ref)(void *), + void (*method_destruct)(void *)); + int ossl_method_store_remove(OSSL_METHOD_STORE *store, + int nid, const void *method); + int ossl_method_store_fetch(OSSL_METHOD_STORE *store, + int nid, const char *properties, + void **method, const OSSL_PROVIDER **prov_rw); + int ossl_method_store_remove_all_provided(OSSL_METHOD_STORE *store, + const OSSL_PROVIDER *prov); + + int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov, + int nid, const char *prop_query, void **method); + int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov, + int nid, const char *prop_query, void *method, + int (*method_up_ref)(void *), + void (*method_destruct)(void *)); + void ossl_method_store_cache_flush_all(OSSL_METHOD_STORE *store); + +=head1 DESCRIPTION + +OSSL_METHOD_STORE stores methods that can be queried using properties and a +numeric identity (nid). + +Methods are expected to be library internal structures. +It's left to the caller to define the exact contents. + +Numeric identities are expected to be an algorithm identity for the methods. +It's left to the caller to define exactly what an algorithm is, and to allocate +these numeric identities accordingly. + +The B also holds an internal query cache, which is accessed +separately (see L below). + +=head2 Store Functions + +ossl_method_store_init() initialises the method store subsystem in the scope of +the library context I. + +ossl_method_store_cleanup() cleans up and shuts down the implementation method +store subsystem in the scope of the library context I. + +ossl_method_store_new() create a new empty method store using the supplied +I to allow access to the required underlying property data. + +ossl_method_store_free() frees resources allocated to I. + +ossl_method_store_add() adds the I constructed from an implementation in +the provider I to the I as an instance of an algorithm indicated by +I and the property definition I, unless the I already +has a method from the same provider with the same I and I. +If the I function is given, it's called to increment the +reference count of the method. +If the I function is given, it's called when this function +fails to add the method to the store, or later on when it is being released from +the I. + +ossl_method_store_remove() removes the I identified by I from the +I. + +ossl_method_store_fetch() queries I for a method identified by I +that matches the property query I. +I<*prop> may be a pointer to a provider, which will narrow the search +to methods from that provider. +The result, if any, is returned in I<*method>, and its provider in I<*prov>. + +ossl_method_store_remove_all_provided() removes all methods from I +that are provided by I. +When doing so, it also flushes the corresponding cache entries. + +=head2 Cache Functions + +ossl_method_store_cache_get() queries the cache associated with the I +for a method identified by I that matches the property query +I. +Additionally, if I isn't NULL, it will be used to narrow the search +to only include methods from that provider. +The result, if any, is returned in I. + +ossl_method_store_cache_set() sets a cache entry identified by I from the +provider I, with the property query I in the I. +Future calls to ossl_method_store_cache_get() will return the specified I. +The I function is called to increment the +reference count of the method and the I function is called +to decrement it. + +ossl_method_store_cache_flush_all() flushes all cached entries associated with +I. + +=head1 NOTES + +The I argument to ossl_method_store_cache_get() and +ossl_method_store_cache_set() is not allowed to be NULL. Use "" for an +empty property definition or query. + +=head1 RETURN VALUES + +ossl_method_store_new() returns a new method store object or NULL on failure. + +ossl_method_store_free(), ossl_method_store_add(), +ossl_method_store_remove(), ossl_method_store_fetch(), +ossl_method_store_cache_get(), ossl_method_store_cache_set() and +ossl_method_store_flush_cache() return B<1> on success and B<0> on error. + +ossl_method_store_free() and ossl_method_store_cleanup() do not return any value. + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use this +file except in compliance with the License. You can obtain a copy in the file +LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/cms_add1_signing_cert.pod b/crypto/openssl/doc/internal/man3/cms_add1_signing_cert.pod new file mode 100644 index 000000000000..cc2747dcde6e --- /dev/null +++ b/crypto/openssl/doc/internal/man3/cms_add1_signing_cert.pod @@ -0,0 +1,46 @@ +=pod + +=head1 NAME + +cms_add1_signing_cert, cms_add1_signing_cert_v2 +- add ESS signing-certificate signed attribute to a +CMS_SignerInfo data structure + +=head1 SYNOPSIS + + #include + + int cms_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc); + + int cms_add1_signing_cert_v2(CMS_SignerInfo *si, ESS_SIGNING_CERT_V2 *sc2); + +=head1 DESCRIPTION + +cms_add1_signing_cert() adds an ESS Signing Certificate I (version 1) signed +attribute to the CMS_SignerInfo I. +cms_add1_signing_cert_v2() adds an ESS Signing Certificate I (version 2) signed +attribute to the CMS_SignerInfo I. +The ESS Signing Certificate attributes version 1 and 2 are defined in RFC 5035 +which updates Section 5.4 of RFC 2634. + +=head1 NOTES + +This attribute is mandatory to make a CMS compliant with CAdES-BES +(European Standard ETSI EN 319 122-1 V1.1.1). +For a fuller description see L). + +=head1 RETURN VALUES + +cms_add1_signing_cert() and cms_add1_signing_cert_v2() return 1 if attribute +is added or 0 if an error occurred. + +=head1 COPYRIGHT + +Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/evp_generic_fetch.pod b/crypto/openssl/doc/internal/man3/evp_generic_fetch.pod new file mode 100644 index 000000000000..b23d2ec0eaa2 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/evp_generic_fetch.pod @@ -0,0 +1,285 @@ +=pod + +=head1 NAME + +evp_generic_fetch, evp_generic_fetch_by_number, evp_generic_fetch_from_prov +- generic algorithm fetchers and method creators for EVP + +=head1 SYNOPSIS + + /* Only for EVP source */ + #include "evp_local.h" + + void *evp_generic_fetch(OSSL_LIB_CTX *libctx, int operation_id, + const char *name, const char *properties, + void *(*new_method)(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *method_data), + void *method_data, + int (*up_ref_method)(void *), + void (*free_method)(void *)); + + void *evp_generic_fetch_by_number(OSSL_LIB_CTX *ctx, int operation_id, + int name_id, const char *properties, + void *(*new_method)(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *method_data), + void *method_data, + int (*up_ref_method)(void *), + void (*free_method)(void *)); + void *evp_generic_fetch_from_prov(OSSL_PROVIDER *prov, int operation_id, + int name_id, const char *properties, + void *(*new_method)(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *method_data), + void *method_data, + int (*up_ref_method)(void *), + void (*free_method)(void *)); + +=head1 DESCRIPTION + +evp_generic_fetch() calls ossl_method_construct() with the given +I, I, I, and I and uses +it to create an EVP method with the help of the functions +I, I, and I. + +evp_generic_fetch_by_number() does the same thing as evp_generic_fetch(), +but takes a numeric I instead of a name. +I must always be nonzero; as a matter of fact, it being zero +is considered a programming error. +This is meant to be used when one method needs to fetch an associated +method, and is typically called from inside the given function +I. + +evp_generic_fetch_from_prov() does the same thing as evp_generic_fetch(), +but limits the search of methods to the provider given with I. +This is meant to be used when one method needs to fetch an associated +method in the same provider. + +The three functions I, I, and +I are supposed to: + +=over 4 + +=item new_method() + +creates an internal method from function pointers found in the +dispatch table I, with name identity I. +The provider I and I are also passed to be used as +new_method() sees fit. + +=item up_ref_method() + +increments the reference counter for the given method, if there is +one. + +=item free_method() + +frees the given method. + +=back + +=head1 RETURN VALUES + +evp_generic_fetch() returns a method on success, or NULL on error. + +=head1 EXAMPLES + +This is a short example of the fictitious EVP API and operation called +B. + +To begin with, let's assume something like this in +F: + + #define OSSL_OP_FOO 100 + + #define OSSL_FUNC_FOO_NEWCTX_FUNC 2001 + #define OSSL_FUNC_FOO_INIT 2002 + #define OSSL_FUNC_FOO_OPERATE 2003 + #define OSSL_FUNC_FOO_CLEANCTX_FUNC 2004 + #define OSSL_FUNC_FOO_FREECTX_FUNC 2005 + + OSSL_CORE_MAKE_FUNC(void *, foo_newctx, (void)) + OSSL_CORE_MAKE_FUNC(int, foo_init, (void *vctx)) + OSSL_CORE_MAKE_FUNC(int, foo_operate, (void *vctx, + unsigned char *out, size_t *out_l, + unsigned char *in, size_t in_l)) + OSSL_CORE_MAKE_FUNC(void, foo_cleanctx, (void *vctx)) + OSSL_CORE_MAKE_FUNC(void, foo_freectx, (void *vctx)) + +And here's the implementation of the FOO method fetcher: + + /* typedef struct evp_foo_st EVP_FOO */ + struct evp_foo_st { + OSSL_PROVIDER *prov; + int name_id; + CRYPTO_REF_COUNT refcnt; + OSSL_FUNC_foo_newctx_fn *newctx; + OSSL_FUNC_foo_init_fn *init; + OSSL_FUNC_foo_operate_fn *operate; + OSSL_FUNC_foo_cleanctx_fn *cleanctx; + OSSL_FUNC_foo_freectx_fn *freectx; + }; + + /* + * In this example, we have a public method creator and destructor. + * It's not absolutely necessary, but is in the spirit of OpenSSL. + */ + EVP_FOO *EVP_FOO_meth_from_algorithm(int name_id, + const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, + void *data) + { + EVP_FOO *foo = NULL; + + if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL) + return NULL; + + foo->name_id = name_id; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_FOO_NEWCTX: + foo->newctx = OSSL_FUNC_foo_newctx(fns); + break; + case OSSL_FUNC_FOO_INIT: + foo->init = OSSL_FUNC_foo_init(fns); + break; + case OSSL_FUNC_FOO_OPERATE: + foo->operate = OSSL_FUNC_foo_operate(fns); + break; + case OSSL_FUNC_FOO_CLEANCTX: + foo->cleanctx = OSSL_FUNC_foo_cleanctx(fns); + break; + case OSSL_FUNC_FOO_FREECTX: + foo->freectx = OSSL_FUNC_foo_freectx(fns); + break; + } + } + foo->prov = prov; + if (prov) + ossl_provider_up_ref(prov); + + return foo; + } + + EVP_FOO_meth_free(EVP_FOO *foo) + { + if (foo != NULL) { + OSSL_PROVIDER *prov = foo->prov; + + OPENSSL_free(foo); + ossl_provider_free(prov); + } + } + + static void *foo_from_algorithm(const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov) + { + return EVP_FOO_meth_from_algorithm(fns, prov); + } + + static int foo_up_ref(void *vfoo) + { + EVP_FOO *foo = vfoo; + int ref = 0; + + CRYPTO_UP_REF(&foo->refcnt, &ref, foo_lock); + return 1; + } + + static void foo_free(void *vfoo) + { + EVP_FOO_meth_free(vfoo); + } + + EVP_FOO *EVP_FOO_fetch(OSSL_LIB_CTX *ctx, + const char *name, + const char *properties) + { + EVP_FOO *foo = + evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties, + foo_from_algorithm, foo_up_ref, foo_free); + + /* + * If this method exists in legacy form, with a constant NID for the + * given |name|, this is the spot to find that NID and set it in + * the newly constructed EVP_FOO instance. + */ + + return foo; + + } + +And finally, the library functions: + + /* typedef struct evp_foo_st EVP_FOO_CTX */ + struct evp_foo_ctx_st { + const EVP_FOO *foo; + void *provctx; /* corresponding provider context */ + }; + + int EVP_FOO_CTX_reset(EVP_FOO_CTX *c) + { + if (c == NULL) + return 1; + if (c->foo != NULL && c->foo->cleanctx != NULL) + c->foo->cleanctx(c->provctx); + return 1; + } + + EVP_FOO_CTX *EVP_FOO_CTX_new(void) + { + return OPENSSL_zalloc(sizeof(EVP_FOO_CTX)); + } + + void EVP_FOO_CTX_free(EVP_FOO_CTX *c) + { + EVP_FOO_CTX_reset(c); + c->foo->freectx(c->provctx); + OPENSSL_free(c); + } + + int EVP_FooInit(EVP_FOO_CTX *c, const EVP_FOO *foo) + { + int ok = 1; + + c->foo = foo; + if (c->provctx == NULL) + c->provctx = c->foo->newctx(); + + ok = c->foo->init(c->provctx); + + return ok; + } + + int EVP_FooOperate(EVP_FOO_CTX *c, unsigned char *out, size_t *outl, + const unsigned char *in, size_t inl) + { + int ok = 1; + + ok = c->foo->update(c->provctx, out, inl, &outl, in, inl); + return ok; + } + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/evp_keymgmt_newdata.pod b/crypto/openssl/doc/internal/man3/evp_keymgmt_newdata.pod new file mode 100644 index 000000000000..9b3f2c55f160 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/evp_keymgmt_newdata.pod @@ -0,0 +1,88 @@ +=pod + +=head1 NAME + +evp_keymgmt_newdata, evp_keymgmt_freedata, +evp_keymgmt_get_params, +evp_keymgmt_has, evp_keymgmt_validate, +evp_keymgmt_import, evp_keymgmt_import_types, +evp_keymgmt_export, evp_keymgmt_export_types +- internal KEYMGMT interface functions + +=head1 SYNOPSIS + + #include "crypto/evp.h" + + void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt); + void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keyddata); + int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, + void *keydata, OSSL_PARAM params[]); + + int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keyddata, int selection); + int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata, + int selection); + + int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata, + int selection, const OSSL_PARAM params[]); + const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt, + int selection); + int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata, + int selection, OSSL_CALLBACK *param_cb, void *cbarg); + const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt, + int selection); + +=head1 DESCRIPTION + +All these functions are helpers to call the provider's corresponding +function. They all have in common that they take a B as +first argument, which they also retrieve a provider context from when +needed. The rest of the arguments are simply passed on to the +function they wrap around. + +evp_keymgmt_newdata() calls the method's new() function. + +evp_keymgmt_freedata() calls the method's free() function. + +(the name evp_keymgmt_freedata() was chosen to avoid a clash with +EVP_KEYMGMT_free() on case insensitive systems, the name +evp_keymgmt_newdata() was chosen for consistency) + +evp_keymgmt_get_params() calls the method's get_params() function. + +evp_keymgmt_has() calls the method's has() function. + +evp_keymgmt_validate() calls the method's validate() function. + +evp_keymgmt_import() calls the method's import() function. + +evp_keymgmt_import_types() calls the method's import_types() function. + +evp_keymgmt_export() calls the method's export() function. + +evp_keymgmt_export_types() calls the method's export_types() function. + +=head1 RETURN VALUES + +evp_keymgmt_newdata() returns a pointer to a provider side key object, +or NULL on error. + +evp_keymgmt_import_types(), and evp_keymgmt_export_types() return a parameter +descriptor for importing and exporting key data, or NULL if there are no such +descriptors. + +All other functions return 1 on success and 0 on error. + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod b/crypto/openssl/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod new file mode 100644 index 000000000000..7099e4496473 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod @@ -0,0 +1,106 @@ +=pod + +=head1 NAME + +evp_keymgmt_util_export, +evp_keymgmt_util_export_to_provider, +evp_keymgmt_util_find_operation_cache, +evp_keymgmt_util_clear_operation_cache, +evp_keymgmt_util_cache_keydata, +evp_keymgmt_util_cache_keyinfo, +evp_keymgmt_util_fromdata, +OP_CACHE_ELEM +- internal KEYMGMT utility functions + +=head1 SYNOPSIS + + #include "crypto/evp.h" + + typedef struct OP_CACHE_ELEM; + + int evp_keymgmt_util_export(const EVP_PKEY *pk, int selection, + OSSL_CALLBACK *export_cb, void *export_cbarg); + void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, + int selection); + OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk, + EVP_KEYMGMT *keymgmt, + int selection); + int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk, int locking); + int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, + void *keydata, int selection); + void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk); + void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, + int selection, const OSSL_PARAM params[]); + +=head1 DESCRIPTION + +evp_keymgmt_util_export() calls L with the +I and I from I. This is used as a +helper for L. + +evp_keymgmt_util_export_to_provider() exports cached key material +(provider side key material) from the given key I to a provider +via a B interface, if this hasn't already been done. +It maintains a cache of provider key references in I to keep track +of all provider side keys. + +To export a legacy key, use L instead, +as this function ignores any legacy key data. + +evp_keymgmt_util_find_operation_cache() finds +I in I's cache of provided keys for operations. +It should only be called while holding I's lock (read or write). + +evp_keymgmt_util_clear_operation_cache() can be used to explicitly +clear the cache of operation key references. If I is set to 1 then +then I's lock will be obtained while doing the clear. Otherwise it will be +assumed that the lock has already been obtained or is not required. + +evp_keymgmt_util_cache_keydata() can be used to add a provider key +object to a B. + +evp_keymgmt_util_cache_keyinfo() can be used to get all kinds of +information from the provvider "origin" and save it in I's +information cache. + +evp_keymgmt_util_fromdata() can be used to add key object data to a +given key I via a B interface. This is used as a +helper for L. + +In all functions that take a I argument, the selection is used to +constraint the information requested on export. It is also used in the cache +so that key data is guaranteed to contain all the information requested in +the selection. + +=head1 RETURN VALUES + +evp_keymgmt_export_to_provider() and evp_keymgmt_util_fromdata() +return a pointer to the appropriate provider side key (created or +found again), or NULL on error. + +evp_keymgmt_util_find_operation_cache() returns a pointer to the +operation cache slot. If I is NULL, or if there is no slot +with a match for I, NULL is returned. + +evp_keymgmt_util_cache_keydata() and evp_keymgmt_util_clear_operation_cache() +return 1 on success or 0 otherwise. + +=head1 NOTES + +"Legacy key" is the term used for any key that has been assigned to an +B with EVP_PKEY_assign_RSA() and similar functions. + +=head1 SEE ALSO + +L, L + +=head1 COPYRIGHT + +Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/evp_md_get_number.pod b/crypto/openssl/doc/internal/man3/evp_md_get_number.pod new file mode 100644 index 000000000000..1f913551aad6 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/evp_md_get_number.pod @@ -0,0 +1,112 @@ +=pod + +=head1 NAME + +ossl_decoder_get_number, evp_md_get_number, evp_cipher_get_number, +evp_mac_get_number, evp_rand_get_number, evp_keymgmt_get_number, +evp_signature_get_number, evp_asym_cipher_get_number, evp_kem_get_number, +evp_keyexch_get_number, evp_kdf_get_number, ossl_encoder_get_number, +ossl_store_loader_get_number - EVP get internal identification numbers + +=head1 SYNOPSIS + + #include "crypto/evp.h" + + int evp_asym_cipher_get_number(const EVP_ASYM_CIPHER *cipher); + int evp_cipher_get_number(const EVP_CIPHER *e); + int evp_kdf_get_number(const EVP_KDF *kdf); + int evp_kem_get_number(const EVP_KEM *kem); + int evp_keyexch_get_number(const EVP_KEYEXCH *exchange); + int evp_keymgmt_get_number(const EVP_KEYMGMT *keymgmt); + int evp_mac_get_number(const EVP_MAC *mac); + int evp_md_get_number(const EVP_MD *md); + int evp_rand_get_number(const EVP_RAND *rand); + int evp_signature_get_number(const EVP_SIGNATURE *signature); + int ossl_decoder_get_number(const OSSL_DECODER *decoder); + int ossl_encoder_get_number(const OSSL_ENCODER *encoder); + int ossl_store_loader_get_number(const OSSL_STORE_LOADER *loader); + +=head1 DESCRIPTION + +All provided algorithms get an associated integer identification number. +This number is dynamic and should be expected to vary from run to run. +These numbers should only be considered to be unique per provider per +library context. + +=over 4 + +=item evp_asym_cipher_get_number() + +Returns the internal dynamic number assigned to I. + +=item evp_cipher_get_number() + +Returns the internal dynamic number assigned to the I. This is only +useful with fetched Bs. + +=item evp_kdf_get_number() + +Keturns the internal dynamic number assigned to I. + +=item evp_kem_get_number() + +Returns the internal dynamic number assigned to I. + +=item evp_keyexch_get_number() + +Returns the internal dynamic number assigned to the I. + +=item evp_keymgmt_get_number() + +Returns the internal dynamic number assigned to the I. + +=item evp_mac_get_number() + +Returns the internal dynamic number assigned to I. + +=item evp_md_get_number() + +Returns the internal dynamic number assigned to the I. This is +only useful with fetched Bs. + +=item evp_rand_get_number() + +Returns the internal dynamic number assigned to I. + +=item evp_signature_get_number() + +Returns the internal dynamic number assigned to I. + +=item ossl_decoder_get_number() + +Returns the internal dynamic number assigned to the given I. + +=item ossl_encoder_get_number() + +Returns the internal dynamic number assigned to the given I. + +=item ossl_store_loader_get_number() + +Returns the internal dynamic number assigned to the given I. + +=back + +=head1 RETURN VALUES + +All of these functions return the provider specific identification number +for the specified algorithm. + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/evp_pkey_export_to_provider.pod b/crypto/openssl/doc/internal/man3/evp_pkey_export_to_provider.pod new file mode 100644 index 000000000000..44efbbe2668f --- /dev/null +++ b/crypto/openssl/doc/internal/man3/evp_pkey_export_to_provider.pod @@ -0,0 +1,80 @@ +=pod + +=head1 NAME + +evp_pkey_export_to_provider, evp_pkey_copy_downgraded, evp_pkey_get_legacy +- internal EVP_PKEY support functions for providers + +=head1 SYNOPSIS + + /* Only for EVP source */ + #include "evp_local.h" + + void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx, + EVP_KEYMGMT **keymgmt, + const char *propquery); + int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src); + void *evp_pkey_get_legacy(EVP_PKEY *pk); + +=head1 DESCRIPTION + +This manual uses the term "origin", which is explained in internal +L. + +evp_pkey_export_to_provider() exports the "origin" key contained in I +to its operation cache to make it suitable for an B given either +with I<*keymgmt> or with an implicit fetch using I (NULL means the +default context), the name of the legacy type of I, and the I +(NULL means the default property query settings). + +If I isn't NULL but I<*keymgmt> is, and the "origin" was successfully +exported, then I<*keymgmt> is assigned the implicitly fetched B. + +evp_pkey_copy_downgraded() makes a copy of I in legacy form into I<*dest>, +if there's a corresponding legacy implementation. This should be used if the +use of a downgraded key is temporary. +For example, L uses this to try its +best to get "traditional" PEM output even if the input B has a +provider-native internal key. + +evp_pkey_get_legacy() obtains and returns a legacy key structure. If the +EVP_PKEY already contains a legacy key then it is simply returned. If it is a +provider based key, then a new legacy key is constructed based on the provider +key. The legacy key is cached inside the EVP_PKEY and its value returned from +this function. Subsequent calls to evp_pkey_get_legacy() will return the cached +key. Subsequent changes to the provider key are not reflected back in the +legacy key. Similarly changes to the legacy key are not reflected back in the +provider key. + +=head1 RETURN VALUES + +evp_pkey_export_to_provider() returns the provider key data if there was any +allocated. It also either sets I<*keymgmt> to the B associated +with the returned key data, or NULL on error. + +evp_pkey_get_legacy() returns the legacy key or NULL on error. + +=head1 NOTES + +Some functions calling evp_pkey_export_to_provider() may have received a const +key, and may therefore have to cast the key to non-const form to call this +function. Since B is always dynamically allocated, this is OK. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/evp_pkey_get1_ED25519.pod b/crypto/openssl/doc/internal/man3/evp_pkey_get1_ED25519.pod new file mode 100644 index 000000000000..37b41e459166 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/evp_pkey_get1_ED25519.pod @@ -0,0 +1,43 @@ +=pod + +=head1 NAME + +evp_pkey_get1_ED25519, evp_pkey_get1_ED448, +evp_pkey_get1_X25519, evp_pkey_get1_X448 +- internal ECX from EVP_PKEY getter functions + +=head1 SYNOPSIS + + #include "internal/evp.h" + + ECX_KEY *evp_pkey_get1_ED25519(EVP_PKEY *pkey); + ECX_KEY *evp_pkey_get1_ED448(EVP_PKEY *pkey); + ECX_KEY *evp_pkey_get1_X25519(EVP_PKEY *pkey); + ECX_KEY *evp_pkey_get1_X448(EVP_PKEY *pkey); + +=head1 DESCRIPTION + +evp_pkey_get1_ED25519(), evp_pkey_get1_ED448(), evp_pkey_get1_X25519() and +evp_pkey_get1_X448() return the referenced key in I or NULL if the key +is not of the correct type. The returned key must be freed after use. + +=head1 RETURN VALUES + +evp_pkey_get1_ED25519(), evp_pkey_get1_ED448(), evp_pkey_get1_X25519() and +evp_pkey_get1_X448() return the referenced key or NULL if an error +occurred. + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use this +file except in compliance with the License. You can obtain a copy in the file +LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_DER_w_begin_sequence.pod b/crypto/openssl/doc/internal/man3/ossl_DER_w_begin_sequence.pod new file mode 100644 index 000000000000..b78056f6e121 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_DER_w_begin_sequence.pod @@ -0,0 +1,48 @@ +=pod + +=head1 NAME + +ossl_DER_w_begin_sequence, ossl_DER_w_end_sequence +- internal DER writers for DER constructed elements + +=head1 SYNOPSIS + + #include "internal/der.h" + + int ossl_DER_w_begin_sequence(WPACKET *pkt, int tag); + int ossl_DER_w_end_sequence(WPACKET *pkt, int tag); + +=head1 DESCRIPTION + +All functions described here are wrappers for constructed structures, +i.e. the ASN.1 SEQUENCE, SET and CHOICE specifications. They all come +in pairs, as noted by the function names containing the words C +and B. + +When using these, special care must be taken to ensure that the ASN.1 tag +value I is the same in the matching C and C function calls. + +ossl_DER_w_begin_sequence() and ossl_DER_w_end_sequence() begins and ends a +SEQUENCE. + +=head1 RETURN VALUES + +All the functions return 1 on success and 0 on failure. Failure may +mean that the buffer held by the I is too small, but may also +mean that the values given to the functions are invalid, such as the provided +I value being too large for the implementation. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_DER_w_bn.pod b/crypto/openssl/doc/internal/man3/ossl_DER_w_bn.pod new file mode 100644 index 000000000000..49644ffd058f --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_DER_w_bn.pod @@ -0,0 +1,66 @@ +=pod + +=head1 NAME + +ossl_DER_w_boolean, ossl_DER_w_uint32, ossl_DER_w_bn, ossl_DER_w_null, +ossl_DER_w_octet_string, ossl_DER_w_octet_string_uint32 +- internal DER writers for DER primitives + +=head1 SYNOPSIS + + #include "internal/der.h" + + int ossl_DER_w_boolean(WPACKET *pkt, int tag, int b); + int ossl_DER_w_uint32(WPACKET *pkt, int tag, uint32_t v); + int ossl_DER_w_bn(WPACKET *pkt, int tag, const BIGNUM *v); + int ossl_DER_w_null(WPACKET *pkt, int tag); + int ossl_DER_w_octet_string(WPACKET *pkt, int tag, + const unsigned char *data, size_t data_n); + int ossl_DER_w_octet_string_uint32(WPACKET *pkt, int tag, uint32_t value); + +=head1 DESCRIPTION + +All functions described here behave the same way, they prepend +(remember that DER writers are used backwards) the DER encoding of +their respective value to the already written output buffer held by +I. + +ossl_DER_w_boolean() writes the primitive BOOLEAN using the value I. +Any value that evaluates as true will render a B BOOLEAN, +otherwise a B BOOLEAN. + +ossl_DER_w_uint32() and ossl_DER_w_bn() both write the primitive INTEGER using +the value I. + +=for comment Other similar functions for diverse C integers should be +added. + +ossl_DER_w_null() writes the primitive NULL. + +ossl_DER_w_octet_string() writes the primitive OCTET STRING using the bytes +from I with a length of I. + +ossl_DER_w_octet_string_uint32() writes the primitive OCTET STRING using a +32 bit value in I. + +=head1 RETURN VALUES + +All the functions return 1 on success and 0 on failure. Failure may +mean that the buffer held by the I is too small, but may also +mean that the values given to the functions are invalid, such as the provided +I value being too large for the implementation. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_DER_w_precompiled.pod b/crypto/openssl/doc/internal/man3/ossl_DER_w_precompiled.pod new file mode 100644 index 000000000000..aa7fa3930f89 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_DER_w_precompiled.pod @@ -0,0 +1,48 @@ +=pod + +=head1 NAME + +ossl_DER_w_precompiled +- internal DER writers for precompiled DER blobs + +=head1 SYNOPSIS + + #include "internal/der.h" + + int ossl_DER_w_precompiled(WPACKET *pkt, int tag, + const unsigned char *precompiled, + size_t precompiled_n); + +=head1 DESCRIPTION + +There may be already existing DER blobs that can simply be copied to +the buffer held by I. For example, precompiled values, such as +OIDs (for example, C) or complete AlgorithmIdentifiers +(for example, C). To add those as an element in a +structure being DER encoded, use ossl_DER_w_precompiled(). + +ossl_DER_w_precompiled() will simply take the DER encoded blob given as +I with length I and add it to the buffer +held by I. + +=head1 RETURN VALUES + +ossl_DER_w_precompiled() returns 1 on success and 0 on failure. Failure +may mean that the buffer held by the I is too small, but may also +mean that the values given to the functions are invalid, such as the provided +I value being too large for the implementation. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_algorithm_do_all.pod b/crypto/openssl/doc/internal/man3/ossl_algorithm_do_all.pod new file mode 100644 index 000000000000..7a321d492a04 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_algorithm_do_all.pod @@ -0,0 +1,63 @@ +=pod + +=head1 NAME + +ossl_algorithm_do_all - generic algorithm implementation iterator + +=head1 SYNOPSIS + + void ossl_algorithm_do_all(OSSL_LIB_CTX *libctx, int operation_id, + OSSL_PROVIDER *provider, + void (*fn)(OSSL_PROVIDER *provider, + const OSSL_ALGORITHM *algo, + int no_store, void *data), + void *data); + +=head1 DESCRIPTION + +ossl_algorithm_do_all() looks up every algorithm it can find, given a +library context I, an operation identity I and a +provider I. +I may be NULL to signify that the default library context should +be used. +I may be zero to signify that all kinds of operations +will be looked up. +I may be NULL to signify that all loaded providers will be +queried. + +For each implementation found, the function I is called with the +I for the implementation, the algorithm descriptor I, +the flag I indicating whether the algorithm descriptor may +be remembered or not, and the caller I that was passed to +ossl_algorithm_do_all(). + +=head1 RETURN VALUES + +ossl_algorithm_do_all() doesn't return any value. + +=head1 NOTES + +The function described here are mainly useful for discovery, and +possibly display of what has been discovered, for example an +application that wants to display the loaded providers and what they +may offer, but also for constructors, such as +L. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use this +file except in compliance with the License. You can obtain a copy in the file +LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_cmp_X509_STORE_add1_certs.pod b/crypto/openssl/doc/internal/man3/ossl_cmp_X509_STORE_add1_certs.pod new file mode 100644 index 000000000000..97304ee40d92 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_cmp_X509_STORE_add1_certs.pod @@ -0,0 +1,44 @@ +=pod + +=head1 NAME + +ossl_cmp_X509_STORE_add1_certs, +ossl_cmp_X509_STORE_get1_certs +- functions manipulating stores of certificates + +=head1 SYNOPSIS + + #include + + int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs, + int only_self_signed); + STACK_OF(X509) *ossl_cmp_X509_STORE_get1_certs(X509_STORE *store); + +=head1 DESCRIPTION + +ossl_cmp_X509_STORE_add1_certs() adds all or only self-signed certificates from +the given stack to given store. The I parameter may be NULL. + +ossl_cmp_X509_STORE_get1_certs() retrieves a copy of all certificates in the +given store. + +=head1 RETURN VALUES + +ossl_cmp_X509_STORE_add1_certs() returns 1 on success, 0 on error. + +ossl_cmp_X509_STORE_get1_certs() returns a list of certificates, NULL on error. + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod b/crypto/openssl/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod new file mode 100644 index 000000000000..a154cda1c989 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_cmp_asn1_octet_string_set1.pod @@ -0,0 +1,45 @@ +=pod + +=head1 NAME + +ossl_cmp_asn1_octet_string_set1, +ossl_cmp_asn1_octet_string_set1_bytes +- ASN.1 octet string utility functions + +=head1 SYNOPSIS + + #include "cmp_local.h" + + int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt, + const ASN1_OCTET_STRING *src); + int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt, + const unsigned char *bytes, int len); + +=head1 DESCRIPTION + +ossl_cmp_asn1_octet_string_set1() frees any previous value of the variable +referenced via the I argument and assigns either a copy of +the ASN1_OCTET_STRING given as the I argument or NULL. + +ossl_cmp_asn1_octet_string_set1_bytes() frees any previous value of the variable +referenced via the I argument and assigns either a copy of the given byte +string (with the given length) or NULL. + +=head1 RETURN VALUES + +All functions return 1 on success, 0 on error. + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_cmp_certreq_new.pod b/crypto/openssl/doc/internal/man3/ossl_cmp_certreq_new.pod new file mode 100644 index 000000000000..068e1b29b977 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_cmp_certreq_new.pod @@ -0,0 +1,177 @@ +=pod + +=head1 NAME + +ossl_cmp_certreq_new, +ossl_cmp_certrep_new, +ossl_cmp_rr_new, +ossl_cmp_rp_new, +ossl_cmp_certConf_new, +ossl_cmp_pkiconf_new, +ossl_cmp_pollReq_new, +ossl_cmp_pollRep_new, +ossl_cmp_genm_new, +ossl_cmp_genp_new, +ossl_cmp_error_new +- functions for generating CMP messages + +=head1 SYNOPSIS + + #include "cmp_local.h" + + OSSL_ossl_cmp_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int bodytype, + const OSSL_CRMF_MSG *crm); + OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype, + int certReqId, const OSSL_CMP_PKISI *si, + X509 *cert, const X509 *encryption_recip, + STACK_OF(X509) *chain, STACK_OF(X509) *caPubs, + int unprotectedErrors); + OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx); + OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si, + const OSSL_CRMF_CERTID *cid, + int unprotectedErrors); + OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info, + const char *text); + OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx); + OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid); + OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid, int poll_after); + OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx); + OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx); + OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si, + int64_t errorCode, const char *details, + int unprotected); + +=head1 DESCRIPTION + +This is the internal API for creating various CMP PKIMESSAGES. +All functions are based on L. +The allocate a new message, fill it with the relevant data derived from +the given B, and create the applicable protection. + +ossl_cmp_certreq_new() creates a PKIMessage for requesting a certificate, +which can be either of IR/CR/KUR/P10CR, depending on the given I. +The CRMF message to use may be given explicitly via a non-NULL I argument, +otherwise it is created from the information in the I. + +Available CMP certificate request PKIMessage Is are: + +=over 4 + +=item * B - Initialization Request + +=item * B - Certification Request + +=item * B - PKCS#10 Certification Request + +=item * B - Key Update Request + +=back + +ossl_cmp_certrep_new() creates a PKIMessage for certificate response, +which can be either of IP/CP/KUP, depending on the given I, +with the given I and I values and optionally with I, +I, and I. The I, I, and I arguments +are not consumed if present but their internal reference counter is increased. +The I is currently unsupported. +The function does not protect the message if the B value in I +is B and I is nonzero. + +Available CMP certificate response PKIMessage Is are: + +=over 4 + +=item * B - Initialization Response + +=item * B - Certification Response + +=item * B - Key Update Response + +=back + +The list of all CMP PKIMessage Is is: + + #define OSSL_CMP_PKIBODY_IR 0 + #define OSSL_CMP_PKIBODY_IP 1 + #define OSSL_CMP_PKIBODY_CR 2 + #define OSSL_CMP_PKIBODY_CP 3 + #define OSSL_CMP_PKIBODY_P10CR 4 + #define OSSL_CMP_PKIBODY_POPDECC 5 + #define OSSL_CMP_PKIBODY_POPDECR 6 + #define OSSL_CMP_PKIBODY_KRR 9 + #define OSSL_CMP_PKIBODY_KRP 10 + #define OSSL_CMP_PKIBODY_RR 11 + #define OSSL_CMP_PKIBODY_RP 12 + #define OSSL_CMP_PKIBODY_CCR 13 + #define OSSL_CMP_PKIBODY_CCP 14 + #define OSSL_CMP_PKIBODY_CKUANN 15 + #define OSSL_CMP_PKIBODY_CANN 16 + #define OSSL_CMP_PKIBODY_RANN 17 + #define OSSL_CMP_PKIBODY_CRLANN 18 + #define OSSL_CMP_PKIBODY_PKICONF 19 + #define OSSL_CMP_PKIBODY_NESTED 20 + #define OSSL_CMP_PKIBODY_GENM 21 + #define OSSL_CMP_PKIBODY_GENP 22 + #define OSSL_CMP_PKIBODY_ERROR 23 + #define OSSL_CMP_PKIBODY_CERTCONF 24 + #define OSSL_CMP_PKIBODY_POLLREQ 25 + #define OSSL_CMP_PKIBODY_POLLREP 26 + +ossl_cmp_rr_new() creates a Revocation Request message from the +information set via OSSL_CMP_CTX_set1_oldClCert(). + +ossl_cmp_rp_new() creates a Revocation Response message with I and I. +It does not protect the message if the B value in I is B +and I is nonzero. + +ossl_cmp_certConf_new() creates a Certificate Confirmation message for the last +received certificate. PKIStatus defaults to B if the I bit +field is 0. Else it is taken as the failInfo of the PKIStatusInfo, PKIStatus is +set to B, and I is copied to statusString unless it is NULL. + +ossl_cmp_pkiconf_new() creates a PKI Confirmation message. + +ossl_cmp_pollReq_new() creates a Polling Request message with certReqId set to +I. + +ossl_cmp_pollRep_new() creates a Polling Response message with certReqId set to +I and pollAfter to I. + +ossl_cmp_genm_new() creates a new General Message with an empty ITAV stack. + +ossl_cmp_genp_new() creates a new General Response with an empty ITAV stack. + +ossl_cmp_error_new() creates a new Error Message with the given contents +I, I, and optional I
. +If I is positive and in the range of an OpenSSL error code, +the library and reason strings are included in the B field. +If given, the I
are added to the contents of the B field. +The function does not protect the message if I is nonzero. + +=head1 NOTES + +CMP is specified in RFC 4210 (and CRMF in RFC 4211). + +=head1 RETURN VALUES + +All of the functions return a new OSSL_CMP_MSG structure containing +the generated message on success, or NULL on error. + +=head1 SEE ALSO + +L, +L, L + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_cmp_ctx_set1_caPubs.pod b/crypto/openssl/doc/internal/man3/ossl_cmp_ctx_set1_caPubs.pod new file mode 100644 index 000000000000..f3c45ed56c65 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_cmp_ctx_set1_caPubs.pod @@ -0,0 +1,76 @@ +=pod + +=head1 NAME + +ossl_cmp_ctx_set1_caPubs, +ossl_cmp_ctx_set0_validatedSrvCert, +ossl_cmp_ctx_set_status, +ossl_cmp_ctx_set0_statusString, +ossl_cmp_ctx_set_failInfoCode, +ossl_cmp_ctx_set0_newCert, +ossl_cmp_ctx_set1_extraCertsIn, +ossl_cmp_ctx_set1_recipNonce +- internal functions for managing the CMP client context datastructure + +=head1 SYNOPSIS + + #include + + int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs); + int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert); + int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status); + int ossl_cmp_ctx_set0_statusString(OSSL_CMP_CTX *ctx, + OSSL_CMP_PKIFREETEXT *text); + int ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info); + int ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert); + int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx, + STACK_OF(X509) *extraCertsIn); + int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx, + const ASN1_OCTET_STRING *nonce); + +=head1 DESCRIPTION + +ossl_cmp_ctx_set1_caPubs() copies the given stack of CA certificates +to the caPubs field of the context. +The reference counts of those certificates handled successfully are increased. + +ossl_cmp_ctx_set0_validatedSrvCert() sets the validatedSrvCert of the context, +which caches any already validated server cert, or NULL if not available. + +ossl_cmp_ctx_set_status() sets the status field of the context. + +ossl_cmp_ctx_set0_statusString() sets the statusString field of the context. + +ossl_cmp_ctx_set_failInfoCode() sets the error code bits in the failInfoCode +field of the context based on the given OSSL_CMP_PKIFAILUREINFO structure. + +ossl_cmp_ctx_set0_newCert() sets the given (newly enrolled) certificate +in the context. + +ossl_cmp_ctx_set1_extraCertsIn() sets the extraCertsIn field of the context. +The reference counts of those certificates handled successfully are increased. + +ossl_cmp_ctx_set1_recipNonce() sets the given recipient nonce in the context. + +=head1 NOTES + +CMP is defined in RFC 4210 (and CRMF in RFC 4211). + +=head1 RETURN VALUES + +All functions return 1 on success, 0 on error. + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_cmp_hdr_init.pod b/crypto/openssl/doc/internal/man3/ossl_cmp_hdr_init.pod new file mode 100644 index 000000000000..a0804aa4cf2a --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_cmp_hdr_init.pod @@ -0,0 +1,151 @@ +=pod + +=head1 NAME + +ossl_cmp_hdr_set_pvno, +ossl_cmp_hdr_get_pvno, +ossl_cmp_hdr_get_protection_nid, +ossl_cmp_hdr_get0_sendernonce, +ossl_cmp_general_name_is_NULL_DN, +ossl_cmp_hdr_set1_sender, +ossl_cmp_hdr_set1_recipient, +ossl_cmp_hdr_update_messagetime, +ossl_cmp_hdr_set1_senderKID, +ossl_cmp_hdr_push0_freeText, +ossl_cmp_hdr_push1_freeText, +ossl_cmp_hdr_generalinfo_item_push0, +ossl_cmp_hdr_generalinfo_items_push1, +ossl_cmp_hdr_set_implicitConfirm, +ossl_cmp_hdr_has_implicitConfirm, +ossl_cmp_hdr_set_transactionID, +ossl_cmp_hdr_init +- functions handling CMP message headers + +=head1 SYNOPSIS + + #include "cmp_local.h" + + int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno); + int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr); + int ossl_cmp_hdr_get_protection_nid(const OSSL_CMP_PKIHEADER *hdr); + ASN1_OCTET_STRING + *ossl_cmp_hdr_get0_sendernonce(const OSSL_CMP_PKIHEADER *hdr); + int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name); + + int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm); + int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm); + int ossl_cmp_hdr_update_messagetime(OSSL_CMP_PKIHEADER *hdr); + int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr, + const ASN1_OCTET_STRING *senderKID); + int ossl_cmp_hdr_generalinfo_item_push0(OSSL_CMP_PKIHEADER *hdr, + OSSL_CMP_ITAV *itav); + int ossl_cmp_hdr_generalinfo_items_push1(OSSL_CMP_PKIHEADER *hdr, + STACK_OF(OSSL_CMP_ITAV) *itavs); + int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, + ASN1_UTF8STRING *text); + int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, + ASN1_UTF8STRING *text); + int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr); + int ossl_cmp_hdr_has_implicitConfirm(OSSL_CMP_PKIHEADER *hdr); + int ossl_cmp_hdr_set_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr); + int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr); + +=head1 DESCRIPTION + +ossl_cmp_hdr_set_pvno() sets hdr->pvno to the given B. + +ossl_cmp_hdr_get_pvno() returns the pvno of the given B or -1 on error. + +ossl_cmp_hdr_get_protection_nid returns the NID of the protection algorithm +in B or NID_undef on error. + +ossl_cmp_hdr_get0_sendernonce() returns the sender nonce of the given PKIHeader. + +ossl_cmp_general_name_is_NULL_DN() determines if the given GENERAL_NAME +is the NULL-DN. + +ossl_cmp_hdr_set1_sender() sets the sender field in the given PKIHeader +to the given X509 Name value, without consuming the pointer. + +ossl_cmp_hdr_set1_recipient() sets the recipient field in the given +PKIHeader to the given X509 Name value, without consuming the pointer. +If B is NULL, recipient is set to the NULL DN (the empty list of strings). + +ossl_cmp_hdr_update_messagetime() (re-)sets the messageTime to the current +system time. As written in RFC 4210, section 5.1.1: +The messageTime field contains the time at which the sender created the message. +This may be useful to allow end entities to correct/check their local time for +consistency with the time on a central system. + +ossl_cmp_hdr_set1_senderKID() Sets hdr->senderKID to the given string. +In an PBMAC-protected IR this usually is a reference number issued by the CA, +else the subject key ID of the sender's protecting certificate. + +ossl_cmp_hdr_push0_freeText() pushes an ASN1_UTF8STRING to +hdr->freeText and consumes the given pointer. + +ossl_cmp_hdr_push1_freeText() pushes an ASN1_UTF8STRING to +hdr->freeText and does not consume the pointer. + +ossl_cmp_hdr_generalinfo_item_push0() adds the given InfoTypeAndValue +item to the hdr->generalInfo stack. Consumes the B pointer. + +ossl_cmp_hdr_generalinfo_items_push1() adds a copy of the B stack to +the generalInfo field of PKIheader of the B. Does not consume the B +pointer. + +ossl_cmp_hdr_set_implicitConfirm() sets implicitConfirm in the generalInfo field +of the PKIMessage header. + +ossl_cmp_hdr_has_implicitConfirm() returns 1 if implicitConfirm is +set int generalInfo field of the given PKIMessage header, 0 if not. + +ossl_cmp_hdr_set_transactionID() sets the B field in C. +In case ctx->transactionID is NULL, it starts a new transaction +by creating and storing a new random valuee with 128 bits length. + +ossl_cmp_hdr_init() initializes a PKIHeader structure based on the +values in the given OSSL_CMP_CTX structure. +This starts a new transaction in case ctx->transactionID is NULL. +The sender name is copied from the subject of the client cert, if any, +or else from the subject name provided for certification requests. +As required by RFC 4210 section 5.1.1., if the sender name is not known +to the client it set to the NULL-DN. In this case for identification at least +the senderKID must be set, which we take from any referenceValue provided. + +=head1 NOTES + +CMP is defined in RFC 4210 (and CRMF in RFC 4211). + +=head1 RETURN VALUES + +ossl_cmp_hdr_get_pvno() returns the pvno of the given B or -1 on error. + +ossl_cmp_hdr_get_protection_nid returns the respective NID, NID_undef on error. + +ossl_cmp_hdr_get0_sendernonce() returns the respective nonce, or NULL. + +ossl_cmp_general_name_is_NULL_DN() returns 1 given a NULL-DN, else 0. + +All other functions return 1 on success, 0 on error. + +See the individual functions above. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_cmp_mock_srv_new.pod b/crypto/openssl/doc/internal/man3/ossl_cmp_mock_srv_new.pod new file mode 100644 index 000000000000..837ca06bb34c --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_cmp_mock_srv_new.pod @@ -0,0 +1,87 @@ +=pod + +=head1 NAME + +ossl_cmp_mock_srv_new, +ossl_cmp_mock_srv_free, +ossl_cmp_mock_srv_set1_certOut, +ossl_cmp_mock_srv_set1_chainOut, +ossl_cmp_mock_srv_set1_caPubsOut, +ossl_cmp_mock_srv_set_statusInfo, +ossl_cmp_mock_srv_set_send_error, +ossl_cmp_mock_srv_set_pollCount, +ossl_cmp_mock_srv_set_checkAfterTime +- functions used for testing with CMP mock server + +=head1 SYNOPSIS + + #include "apps/cmp_mock_srv.h" + + OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq); + void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx); + + int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); + int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx, + STACK_OF(X509) *chain); + int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx, + STACK_OF(X509) *caPubs); + int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status, + int fail_info, const char *text); + int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val); + int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count); + int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec); + +=head1 DESCRIPTION + +ossl_cmp_mock_srv_new() allocates the contexts for the CMP mock server +associated with the library context I and property query string +I, both of which may be NULL to select the defaults. + +ossl_cmp_mock_srv_free() deallocates the contexts for the CMP mock server. + +OSSL_CMP_SRV_CTX_set1_certOut() sets the certificate to be returned in +cp/ip/kup. + +OSSL_CMP_SRV_CTX_set1_chainOut() sets the certificate chain to be added to +the extraCerts in a cp/ip/kup. +It should to useful to validate B. + +OSSL_CMP_SRV_CTX_set1_caPubsOut() sets the caPubs to be returned in an ip. + +OSSL_CMP_SRV_CTX_set_statusInfo() sets the status info to be returned. + +OSSL_CMP_SRV_CTX_set_send_error() enables enforcement of error responses. + +OSSL_CMP_SRV_CTX_set_pollCount() sets the number of polls before cert response. + +OSSL_CMP_SRV_CTX_set_checkAfterTime() sets the number of seconds +the client should wait for the next poll. + + +=head1 NOTES + +CMP is defined in RFC 4210 (and CRMF in RFC 4211). + +=head1 RETURN VALUES + +ossl_cmp_mock_srv() returns a B structure on success, +NULL on error. + +ossl_cmp_mock_srv_free() does not return a value. + +All other functions return 1 on success, 0 on error. + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_cmp_msg_check_update.pod b/crypto/openssl/doc/internal/man3/ossl_cmp_msg_check_update.pod new file mode 100644 index 000000000000..4e7a9224afdd --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_cmp_msg_check_update.pod @@ -0,0 +1,95 @@ +=pod + +=head1 NAME + +ossl_cmp_allow_unprotected_cb_t, +ossl_cmp_msg_check_update +- generic checks on a received CMP message, updating the context + +=head1 SYNOPSIS + + #include "cmp_local.h" + + typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg, + int invalid_protection, int arg); + + int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, + ossl_cmp_allow_unprotected_cb_t cb, int cb_arg); + +=head1 DESCRIPTION + +ossl_cmp_msg_check_update() does all generic checks on the given message B, +which may be a server response or a request by some client, +and updates the B accordingly. + +The B is checked for the following: + +=over 4 + +=item its sender is of appropriate type (currently only B) + and matches any expected sender or srvCert subject given in B, + +=item its protection is present and valid (or a callback function B +is present and indicates that a missing or invalid protection is acceptable), + +=item its CMP protocol version is acceptable, namely B, + +=item its body type is valid, + +=item its transaction ID matches any transaction ID given in B, and + +=item its recipNonce matches any senderNonce given in B. + +=back + +In case no protection is present and B is not NULL then this callback +function is called with its B parameter being 0, while in +case an invalid protection is present the B parameter is 1. +The callback is passed also the arguments B, B, and +(which typically contains the expected message type). +The callback should return 1 on acceptance, 0 on rejection, or -1 on error. +It should not put an error on the error stack since this could be misleading. + +ossl_cmp_msg_check_update() adds all extraCerts contained in the to +the list of untrusted certificates in B such that they are already usable +for OSSL_CMP_validate_msg(), which is called internally, and for future use. +Thus they are available also to the certificate confirmation callback, and the +peer does not need to send them again (at least not in the same transaction). +Note that it does not help validating the message before storing the extraCerts +because they are not part of the protected portion of the message anyway. +For efficiency, the extraCerts are prepended to the list so they get used first. + +If all checks pass then ossl_cmp_msg_check_update() +records in B the senderNonce of the received message as the new recipNonce +and learns the transaction ID if none is currently present in B. + +Moreover, according to RFC 4210 section 5.3.2, if the message protection is +PBM-based then any certificates in the caPubs field are added to the list of +trusted certificates (if set via L). +This way these certs are available for validating subsequent messages in the +same context and could apply to any Polling Response (pollRep), error, or PKI +Confirmation (PKIConf) messages following in the same or future transactions. + +=head1 RETURN VALUES + +ossl_cmp_msg_check_update() returns 1 on success, -1 on error. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_cmp_msg_create.pod b/crypto/openssl/doc/internal/man3/ossl_cmp_msg_create.pod new file mode 100644 index 000000000000..d4294d3e9fa6 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_cmp_msg_create.pod @@ -0,0 +1,134 @@ +=pod + +=head1 NAME + +OSSL_CMP_PKIBODY_IR, +OSSL_CMP_PKIBODY_IP, +OSSL_CMP_PKIBODY_CR, +OSSL_CMP_PKIBODY_CP, +OSSL_CMP_PKIBODY_P10CR, +OSSL_CMP_PKIBODY_POPDECC, +OSSL_CMP_PKIBODY_POPDECR, +OSSL_CMP_PKIBODY_KUR, +OSSL_CMP_PKIBODY_KUP, +OSSL_CMP_PKIBODY_KRR, +OSSL_CMP_PKIBODY_KRP, +OSSL_CMP_PKIBODY_RR, +OSSL_CMP_PKIBODY_RP, +OSSL_CMP_PKIBODY_CCR, +OSSL_CMP_PKIBODY_CCP, +OSSL_CMP_PKIBODY_CKUANN, +OSSL_CMP_PKIBODY_CANN, +OSSL_CMP_PKIBODY_RANN, +OSSL_CMP_PKIBODY_CRLANN, +OSSL_CMP_PKIBODY_PKICONF, +OSSL_CMP_PKIBODY_NESTED, +OSSL_CMP_PKIBODY_GENM, +OSSL_CMP_PKIBODY_GENP, +OSSL_CMP_PKIBODY_ERROR, +OSSL_CMP_PKIBODY_CERTCONF, +OSSL_CMP_PKIBODY_POLLREQ, +OSSL_CMP_PKIBODY_POLLREP, +ossl_cmp_bodytype_to_string, +ossl_cmp_msg_get_bodytype, +ossl_cmp_msg_set_bodytype, +ossl_cmp_msg_create, +ossl_cmp_msg_gen_ITAV_push0, +ossl_cmp_msg_gen_ITAVs_push1 +- functions handling CMP messages + +=head1 SYNOPSIS + + #include "cmp_local.h" + + #define OSSL_CMP_PKIBODY_IR 0 + #define OSSL_CMP_PKIBODY_IP 1 + #define OSSL_CMP_PKIBODY_CR 2 + #define OSSL_CMP_PKIBODY_CP 3 + #define OSSL_CMP_PKIBODY_P10CR 4 + #define OSSL_CMP_PKIBODY_POPDECC 5 + #define OSSL_CMP_PKIBODY_POPDECR 6 + #define OSSL_CMP_PKIBODY_KUR 7 + #define OSSL_CMP_PKIBODY_KUP 8 + #define OSSL_CMP_PKIBODY_KRR 9 + #define OSSL_CMP_PKIBODY_KRP 10 + #define OSSL_CMP_PKIBODY_RR 11 + #define OSSL_CMP_PKIBODY_RP 12 + #define OSSL_CMP_PKIBODY_CCR 13 + #define OSSL_CMP_PKIBODY_CCP 14 + #define OSSL_CMP_PKIBODY_CKUANN 15 + #define OSSL_CMP_PKIBODY_CANN 16 + #define OSSL_CMP_PKIBODY_RANN 17 + #define OSSL_CMP_PKIBODY_CRLANN 18 + #define OSSL_CMP_PKIBODY_PKICONF 19 + #define OSSL_CMP_PKIBODY_NESTED 20 + #define OSSL_CMP_PKIBODY_GENM 21 + #define OSSL_CMP_PKIBODY_GENP 22 + #define OSSL_CMP_PKIBODY_ERROR 23 + #define OSSL_CMP_PKIBODY_CERTCONF 24 + #define OSSL_CMP_PKIBODY_POLLREQ 25 + #define OSSL_CMP_PKIBODY_POLLREP 26 + + const char *ossl_cmp_bodytype_to_string(int type); + int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG *msg); + int ossl_cmp_msg_set_bodytype( OSSL_CMP_MSG *msg, int type); + OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype); + int ossl_cmp_msg_gen_ITAV_push0(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav); + int ossl_cmp_msg_gen_ITAVs_push1(OSSL_CMP_MSG *msg, + STACK_OF(OSSL_CMP_ITAV) *itavs); + +=head1 DESCRIPTION + +ossl_cmp_bodytype_to_string() returns the name of the given body type as string, +or "illegal body type" on error. + +ossl_cmp_msg_get_bodytype() returns the body type of the given PKIMessage, +or -1 on error. + +ossl_cmp_msg_set_bodytype() sets the type of the message contained in +the PKIMessage body field. +Returns 1 on success, 0 on error. + +ossl_cmp_msg_create() creates and initializes an B structure, +using fields of B for the header and B for the body. +If the current B field in I indicates that there is no +current transaction, it creates and stores a random one with 128 bits length. +Thus, the I may be modified by this and related ossl_cmp_*_new() functions. +Returns pointer to created B on success, NULL on error. + +ossl_cmp_msg_gen_ITAV_push0() pushes the B to the body of the +PKIMessage B of GenMsg or GenRep type. Consumes the B pointer. +Returns 1 on success, 0 on error. + +ossl_cmp_msg_gen_ITAVs_push1() adds a copy of the B stack to the body +of the PKIMessage B of GenMsg or GenRep type. +Does not consume the B pointer nor its elements. +Returns 1 on success, 0 on error. + +=head1 NOTES + +CMP is defined in RFC 4210 (and CRMF in RFC 4211). + +=head1 RETURN VALUES + +See the individual functions above. + +=head1 SEE ALSO + +L, +L, L + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_cmp_msg_protect.pod b/crypto/openssl/doc/internal/man3/ossl_cmp_msg_protect.pod new file mode 100644 index 000000000000..ae7771280763 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_cmp_msg_protect.pod @@ -0,0 +1,62 @@ +=pod + +=head1 NAME + +ossl_cmp_calc_protection, +ossl_cmp_msg_protect, +ossl_cmp_msg_add_extraCerts +- functions for producing CMP message protection + +=head1 SYNOPSIS + + #include "cmp_local.h" + + ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg); + int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); + int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); + +=head1 DESCRIPTION + +ossl_cmp_calc_protection() calculates the protection for the given I +according to the algorithm and parameters in the message header's protectionAlg +using the credentials, library context, and property criteria in the I. + +ossl_cmp_msg_protect() (re-)protects the given message I using an algorithm +depending on the available context information given in the I. +If there is a secretValue it selects PBMAC, else if there is a protection cert +it selects Signature and uses L. +It also sets the protectionAlg field in the message header accordingly. + +ossl_cmp_msg_add_extraCerts() adds elements to the extraCerts field in I. +If signature-based message protection is used it adds first the CMP signer cert +ctx->cert and then its chain ctx->chain. If this chain is not present in I +tries to build it using ctx->untrusted and caches the result in ctx->chain. +In any case all the certificates explicitly specified to be sent out (i.e., +IextraCertsOut>) are added. Note that it will NOT add the root certificate +of the chain, i.e, the trust anchor (unless it is part of extraCertsOut). + +=head1 NOTES + +CMP is defined in RFC 4210 (and CRMF in RFC 4211). + +=head1 RETURN VALUES + +ossl_cmp_calc_protection() returns the protection on success, else NULL. + +All other functions return 1 on success, 0 on error. + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_cmp_pkisi_get_status.pod b/crypto/openssl/doc/internal/man3/ossl_cmp_pkisi_get_status.pod new file mode 100644 index 000000000000..21f6f90b39d3 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_cmp_pkisi_get_status.pod @@ -0,0 +1,99 @@ +=pod + +=head1 NAME + +ossl_cmp_certresponse_get1_cert, +ossl_cmp_pkisi_get_status, +ossl_cmp_PKIStatus_to_string, +ossl_cmp_pkisi_get0_statusString, +ossl_cmp_pkisi_get_pkifailureinfo, +ossl_cmp_pkisi_check_pkifailureinfo +- functions for managing PKI status information + +=head1 SYNOPSIS + + #include "cmp.h" + +# define OSSL_CMP_PKIFAILUREINFO_badAlg 0 +# define OSSL_CMP_PKIFAILUREINFO_badMessageCheck 1 +# define OSSL_CMP_PKIFAILUREINFO_badRequest 2 +# define OSSL_CMP_PKIFAILUREINFO_badTime 3 +# define OSSL_CMP_PKIFAILUREINFO_badCertId 4 +# define OSSL_CMP_PKIFAILUREINFO_badDataFormat 5 +# define OSSL_CMP_PKIFAILUREINFO_wrongAuthority 6 +# define OSSL_CMP_PKIFAILUREINFO_incorrectData 7 +# define OSSL_CMP_PKIFAILUREINFO_missingTimeStamp 8 +# define OSSL_CMP_PKIFAILUREINFO_badPOP 9 +# define OSSL_CMP_PKIFAILUREINFO_certRevoked 10 +# define OSSL_CMP_PKIFAILUREINFO_certConfirmed 11 +# define OSSL_CMP_PKIFAILUREINFO_wrongIntegrity 12 +# define OSSL_CMP_PKIFAILUREINFO_badRecipientNonce 13 +# define OSSL_CMP_PKIFAILUREINFO_timeNotAvailable 14 +# define OSSL_CMP_PKIFAILUREINFO_unacceptedPolicy 15 +# define OSSL_CMP_PKIFAILUREINFO_unacceptedExtension 16 +# define OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable 17 +# define OSSL_CMP_PKIFAILUREINFO_badSenderNonce 18 +# define OSSL_CMP_PKIFAILUREINFO_badCertTemplate 19 +# define OSSL_CMP_PKIFAILUREINFO_signerNotTrusted 20 +# define OSSL_CMP_PKIFAILUREINFO_transactionIdInUse 21 +# define OSSL_CMP_PKIFAILUREINFO_unsupportedVersion 22 +# define OSSL_CMP_PKIFAILUREINFO_notAuthorized 23 +# define OSSL_CMP_PKIFAILUREINFO_systemUnavail 24 +# define OSSL_CMP_PKIFAILUREINFO_systemFailure 25 +# define OSSL_CMP_PKIFAILUREINFO_duplicateCertReq 26 +# define OSSL_CMP_PKIFAILUREINFO_MAX 26 + + X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep, + const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey); + int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si); + const char *ossl_cmp_PKIStatus_to_string(int status); + OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si); + int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si); + int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index); + +=head1 DESCRIPTION + +ossl_cmp_certresponse_get1_cert() returns a pointer to a copy of the newly +enrolled certificate from the given certResponse I, or NULL on error. +In case of indirect POPO uses data from the I and the private key I. + +ossl_cmp_pkisi_get_status() returns the PKIStatus of I, or -1 on error. + +ossl_cmp_PKIStatus_to_string() returns a human-readable string representing +the PKIStatus values as specified in RFC 4210, Appendix F. + +ossl_cmp_pkisi_get0_statusString() returns a direct pointer to the statusString +field contained in I. + +ossl_cmp_pkisi_get_pkifailureinfo() returns the PKIFailureInfo bits +of I, encoded as integer, or -1 on error. + +ossl_cmp_pkisi_check_pkifailureinfo() returns the state of the bit (0 or 1) +with index I in the PKIFailureInfo of the I, or -1 on error. + +=head1 NOTES + +CMP is defined in RFC 4210 (and CRMF in RFC 4211). + +=head1 RETURN VALUES + +See the individual functions above. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_cmp_print_log.pod b/crypto/openssl/doc/internal/man3/ossl_cmp_print_log.pod new file mode 100644 index 000000000000..f4384402e584 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_cmp_print_log.pod @@ -0,0 +1,108 @@ +=pod + +=head1 NAME + +ossl_cmp_print_log, +ossl_cmp_alert, +ossl_cmp_err, +ossl_cmp_warn, +ossl_cmp_info, +ossl_cmp_debug, +ossl_cmp_log, +ossl_cmp_log1, +ossl_cmp_log2, +ossl_cmp_log3, +ossl_cmp_log4, +ossl_cmp_log_parse_metadata, +ossl_cmp_add_error_data, +ossl_cmp_add_error_line +- logging and error reporting support for CMP + +=head1 SYNOPSIS + + #include "cmp_local.h" + + int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, + const char *func, const char *file, int line, + const char *level_str, const char *format, ...); + #define ossl_cmp_alert(ctx, msg) + #define ossl_cmp_err(ctx, msg) + #define ossl_cmp_warn(ctx, msg) + #define ossl_cmp_info(ctx, msg) + #define ossl_cmp_debug(ctx, (msg) + #define ossl_cmp_log(level, ctx, msg) + #define ossl_cmp_log1(level, ctx, fmt, arg1) + #define ossl_cmp_log2(level, ctx, fmt, arg1, arg2) + #define ossl_cmp_log3(level, ctx, fmt, arg1, arg2, arg3) + #define ossl_cmp_log4(level, ctx, fmt, arg1, arg2, arg3, arg4) + const char *ossl_cmp_log_parse_metadata(const char *buf, + OSSL_CMP_severity *level, char **func, + char **file, int *line); + + #define ossl_cmp_add_error_data(txt) + #define ossl_cmp_add_error_line(txt) + +=head1 DESCRIPTION + +ossl_cmp_print_log() prints CMP log messages (i.e., diagnostic info) via the +log callback of the B if present and the severity level is sufficient. +If the trace API if enabled the function uses it, prepending the function name, +filename, line number, and severity information to the message being output. +In any case the B, B, B, and B parameters +and the message constructed using the given B and variable further +argument list are passed to the log callback function (unless it is NULL). +The B, B, B, and B arguments may be NULL. + +ossl_cmp_alert(), ossl_cmp_err(), ossl_cmp_warn(), ossl_cmp_info(), and +ossl_cmp_debug() output a simple alert/error/warning/info/debug message +via ossl_cmp_print_log(). + +ossl_cmp_log(), ossl_cmp_log1(), ossl_cmp_log2(), ossl_cmp_log3(), and +ossl_cmp_log4() output a log message with the given severity, +constructing the message text from the given format and arguments. + +ossl_cmp_log_parse_metadata() parses the given message buffer I populated +by ossl_cmp_log() etc. +according to the pattern OSSL_CMP_LOG_START#level ": %s\n", filling in +the variable pointed to by I with the severity level or -1, +the variable pointed to by I with the function name string or NULL, +the variable pointed to by I with the filename string or NULL, and +the variable pointed to by I with the line number or -1. +Any string returned via I<*func> and I<*file> must be freed by the caller. + +ossl_cmp_add_error_data() is a macro calling +L with the separator being ":". + +ossl_cmp_add_error_line() is a macro calling +L with the separator being "\n". + +=head1 RETURN VALUES + +ossl_cmp_log_parse_metadata() returns the pointer to the actual message text +after the OSSL_CMP_LOG_PREFIX and level and ':' if found in the buffer, +else the beginning of the buffer. + +ossl_cmp_add_error_data() and +ossl_cmp_add_error_line() +do not return anything. + +All other functions return 1 on success, 0 on error. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_ends_with_dirsep.pod b/crypto/openssl/doc/internal/man3/ossl_ends_with_dirsep.pod new file mode 100644 index 000000000000..d19ce7a3b97c --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_ends_with_dirsep.pod @@ -0,0 +1,45 @@ +=pod + +=head1 NAME + +ossl_ends_with_dirsep, ossl_is_absolute_path +- internal functions to work with paths + +=head1 SYNOPSIS + + #include "internal/cryptlib.h" + + int ossl_ends_with_dirsep(const char *path); + + int ossl_is_absolute_path(const char *path); + +=head1 DESCRIPTION + +ossl_ends_with_dirsep() detects whether the I ends with a directory +separator in a platform agnostic way. + +ossl_is_absolute_path() detects whether the I is absolute path in +a platform agnostic way. + +=head1 RETURN VALUES + +ossl_ends_with_dirsep() returns 1 if the I ends with a directory +separator, 0 otherwise. + +ossl_is_absolute_path() returns 1 if the I is absolute, 0 otherwise. + +=head1 HISTORY + +The functions described here were added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut + diff --git a/crypto/openssl/doc/internal/man3/ossl_global_properties_no_mirrored.pod b/crypto/openssl/doc/internal/man3/ossl_global_properties_no_mirrored.pod new file mode 100644 index 000000000000..6c39ccbc0ffe --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_global_properties_no_mirrored.pod @@ -0,0 +1,56 @@ +=pod + +=head1 NAME + +ossl_property_list_to_string, ossl_global_properties_no_mirrored +- internal property routines + +=head1 SYNOPSIS + + #include "internal/property.h" + + size_t ossl_property_list_to_string(OSSL_LIB_CTX *ctx, + const OSSL_PROPERTY_LIST *list, char *buf, + size_t bufsize); + + int ossl_global_properties_no_mirrored(OSSL_LIB_CTX *libctx); + void ossl_global_properties_no_mirrored(OSSL_LIB_CTX *libctx); + + +=head1 DESCRIPTION + +ossl_property_list_to_string() takes a given OSSL_PROPERTY_LIST in I and +converts it to a string. If I is non NULL then the string will be stored +in I. The size of the buffer is provided in I. If I is +too short then the string will be truncated. If I is NULL then the length +of the string is still calculated and returned. If the property list has no +properties in it then the empty string will be stored in I. + +ossl_global_properties_no_mirrored() checks whether mirroring of global +properties from a parent library context is allowed for the current library +context. + +ossl_global_properties_no_mirrored() prevents future mirroring of global +properties from a parent library context for the current library context. + +=head1 RETURN VALUES + +ossl_property_list_to_string() returns the length of the string, or 0 on error. + +ossl_global_properties_no_mirrored() returns 1 if mirroring of global properties +is not allowed, or 0 otherwise. + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_init_thread_deregister.pod b/crypto/openssl/doc/internal/man3/ossl_init_thread_deregister.pod new file mode 100644 index 000000000000..6c9e0b5b8998 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_init_thread_deregister.pod @@ -0,0 +1,66 @@ +=pod + +=head1 NAME + +OSSL_thread_stop_handler_fn, +ossl_init_thread_start, +ossl_init_thread_deregister +- internal thread routines + +=head1 SYNOPSIS + + #include "crypto/cryptlib.h" + #include + + typedef void (*OSSL_thread_stop_handler_fn)(void *arg); + + int ossl_init_thread_start(const void *index, void *arg, + OSSL_thread_stop_handler_fn handfn); + int ossl_init_thread_deregister(void *index); + +=head1 DESCRIPTION + +Thread aware code may be informed about when a thread is stopping, typically to +perform some cleanup operation. +Thread stop events may be detected by OpenSSL either automatically (using the +capabilities of the underlying threading library) where possible or explicitly +by the application calling OPENSSL_thread_stop() or OPENSSL_thread_stop_ex(). + +Thread aware code registers a "stop handler" for each new thread that it uses. +Typically, when a new thread is being used, code will add a new value to some +thread local variable and then register a stop handler. When the thread is +stopping the stop handler is called (while on that thread) and the code can +clean up the value stored in the thread local variable. + +A new stop handler is registered using the function ossl_init_thread_start(). +The I parameter should be a unique value that can be used to identify a +set of common stop handlers and is passed in a later call to +ossl_init_thread_deregister. If no later call to ossl_init_thread_deregister is +made then NULL can be passed for this parameter. The I parameter is passed +back as an argument to the stop handler when it is later invoked. Finally the +I is a function pointer to the stop handler itself. + +In the event that previously registered stop handlers need to be deregistered +then this can be done using the function ossl_init_thread_deregister(). +This will deregister all stop handlers (no matter which thread they were +registered for) which the same I value. + +=head1 RETURN VALUES + +ossl_init_thread_start() and ossl_init_thread_deregister() return 1 for success +or 0 on error. + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_lib_ctx_get_data.pod b/crypto/openssl/doc/internal/man3/ossl_lib_ctx_get_data.pod new file mode 100644 index 000000000000..faedf7275f08 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_lib_ctx_get_data.pod @@ -0,0 +1,154 @@ +=pod + +=head1 NAME + +ossl_lib_ctx_get_data, ossl_lib_ctx_run_once, ossl_lib_ctx_onfree, +ossl_lib_ctx_is_child +- internal OSSL_LIB_CTX routines + +=head1 SYNOPSIS + + #include + #include "internal/cryptlib.h" + + typedef struct ossl_lib_ctx_method { + int priority; + void *(*new_func)(OSSL_LIB_CTX *ctx); + void (*free_func)(void *); + } OSSL_LIB_CTX_METHOD; + + void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index, + const OSSL_LIB_CTX_METHOD *meth); + + int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx, + ossl_lib_ctx_run_once_fn run_once_fn); + int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn); + + int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx); + +=head1 DESCRIPTION + +Internally, the OpenSSL library context B is implemented +as a B, which allows data from diverse parts of the +library to be added and removed dynamically. +Each such data item must have a corresponding CRYPTO_EX_DATA index +associated with it. Unlike normal CRYPTO_EX_DATA objects we use static indexes +to identify data items. These are mapped transparently to CRYPTO_EX_DATA dynamic +indexes internally to the implementation. +See the example further down to see how that's done. + +ossl_lib_ctx_get_data() is used to retrieve a pointer to the data in +the library context I associated with the given I. An +OSSL_LIB_CTX_METHOD must be defined and given in the I parameter. The index +for it should be defined in cryptlib.h. The functions through the method are +used to create or free items that are stored at that index whenever a library +context is created or freed, meaning that the code that use a data item of that +index doesn't have to worry about that, just use the data available. + +Deallocation of an index happens automatically when the library +context is freed. + +ossl_lib_ctx_run_once is used to run some initialisation routine I +exactly once per library context I object. Each initialisation routine +should be allocate a unique run once index in cryptlib.h. + +Any resources allocated via a run once initialisation routine can be cleaned up +using ossl_lib_ctx_onfree. This associates an "on free" routine I with +the library context I. When I is freed all associated "on free" +routines are called. + +ossl_lib_ctx_is_child() returns 1 if this library context is a child and 0 +otherwise. + +=head1 RETURN VALUES + +ossl_lib_ctx_get_data() returns a pointer on success, or NULL on +failure. + +=head1 EXAMPLES + +=head2 Initialization + +For a type C that should end up in the OpenSSL library context, a +small bit of initialization is needed, i.e. to associate a constructor +and a destructor to an index. + + typedef struct foo_st { + int i; + void *data; + } FOO; + + static void *foo_new(OSSL_LIB_CTX *ctx) + { + FOO *ptr = OPENSSL_zalloc(sizeof(*foo)); + if (ptr != NULL) + ptr->i = 42; + return ptr; + } + static void foo_free(void *ptr) + { + OPENSSL_free(ptr); + } + + /* + * Include a reference to this in the methods table in context.c + * OSSL_LIB_CTX_FOO_INDEX should be added to internal/cryptlib.h + * Priorities can be OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, + * OSSL_LIB_CTX_METHOD_PRIORITY_1, OSSL_LIB_CTX_METHOD_PRIORITY_2, etc. + * Default priority is low (0). The higher the priority the earlier the + * method's destructor will be called when the library context is cleaned up. + */ + const OSSL_LIB_CTX_METHOD foo_method = { + OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, + foo_new, + foo_free + }; + +=head2 Usage + +To get and use the data stored in the library context, simply do this: + + /* + * ctx is received from a caller, + */ + FOO *data = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_FOO_INDEX, &foo_method); + +=head2 Run Once + + void foo_cleanup(OSSL_LIB_CTX *ctx) + { + /* Free foo resources associated with ctx */ + } + + static ossl_lib_ctx_run_once_fn do_foo_init; + static int do_foo_init(OSSL_LIB_CTX *ctx) + { + /* Allocate and initialise some foo resources and associated with ctx */ + return ossl_lib_ctx_onfree(ctx, &foo_cleanup) + } + + int foo_some_function(OSSL_LIB_CTX *ctx) + { + if (!ossl_lib_ctx_run_once(ctx, + OSSL_LIB_CTX_FOO_RUN_ONCE_INDEX, + do_foo_init)) + return 0; + + /* Do some work using foo resources in ctx */ + } + + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_method_construct.pod b/crypto/openssl/doc/internal/man3/ossl_method_construct.pod new file mode 100644 index 000000000000..3683798b06b4 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_method_construct.pod @@ -0,0 +1,158 @@ +=pod + +=head1 NAME + +OSSL_METHOD_CONSTRUCT_METHOD, ossl_method_construct +- generic method constructor + +=head1 SYNOPSIS + + #include "internal/core.h" + + struct ossl_method_construct_method_st { + /* Get a temporary store */ + void *(*get_tmp_store)(void *data); + /* Get an already existing method from a store */ + void *(*get)(void *store, const OSSL_PROVIDER *prov, void *data); + /* Store a method in a store */ + int (*put)(void *store, void *method, const OSSL_PROVIDER *prov, + const char *name, const char *propdef, void *data); + /* Construct a new method */ + void *(*construct)(const OSSL_ALGORITHM *algodef, OSSL_PROVIDER *prov, + void *data); + /* Destruct a method */ + void (*destruct)(void *method, void *data); + }; + typedef struct ossl_method_construct_method OSSL_METHOD_CONSTRUCT_METHOD; + + void *ossl_method_construct(OSSL_LIB_CTX *ctx, int operation_id, + OSSL_PROVIDER *prov, int force_cache, + OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data); + + +=head1 DESCRIPTION + +All libcrypto subsystems that want to create their own methods based +on provider dispatch tables need to do so in exactly the same way. +ossl_method_construct() does this while leaving it to the subsystems +to define more precisely how the methods are created, stored, etc. + +It's important to keep in mind that a method is identified by three things: + +=over 4 + +=item The operation identity + +=item The name of the algorithm + +=item The properties associated with the algorithm implementation + +=back + +=head2 Functions + +ossl_method_construct() creates a method by asking all available +providers for a dispatch table given an I, and then +calling the appropriate functions given by the subsystem specific +method creator through I and the data in I (which is +passed by ossl_method_construct()). +If I is not NULL, only that provider is considered, which is +useful in the case a method must be found in that particular +provider. + +This function assumes that the subsystem method creator implements +reference counting and acts accordingly (i.e. it will call the +subsystem destruct() method to decrement the reference count when +appropriate). + +=head2 Structures + +A central part of constructing a subsystem specific method is to give +ossl_method_construct a set of functions, all in the +B structure, which holds the following +function pointers: + +=over 4 + +=item get_tmp_store() + +Create a temporary method store in the scope of the library context I. +This store is used to temporarily store methods for easier lookup, for +when the provider doesn't want its dispatch table stored in a longer +term cache. + +=item get() + +Look up an already existing method from a store by name. + +The store may be given with I. +NULL is a valid value and means that a subsystem default store +must be used. +This default store should be stored in the library context I. + +The method to be looked up should be identified with data found in I +(which is the I that was passed to ossl_construct_method()). +In other words, the ossl_method_construct() caller is entirely responsible +for ensuring the necesssary data is made available. + +Optionally, I may be given as a search criterion, to narrow down the +search of a method belonging to just one provider. + +This function is expected to increment the resulting method's reference count. + +=item put() + +Places the I created by the construct() function (see below) +in a store. + +The store may be given with I. +NULL is a valid value and means that a subsystem default store +must be used. +This default store should be stored in the library context I. + +The method should be associated with the given provider I, +I and property definition I as well as any +identification data given through I (which is the I +that was passed to ossl_construct_method()). + +This function is expected to increment the I's reference count. + +=item construct() + +Constructs a subsystem method for the given I and the given +dispatch table I. + +The associated provider object I is passed as well, to make +it possible for the subsystem constructor to keep a reference, which +is recommended. +If such a reference is kept, the I reference counter +must be incremented, using ossl_provider_up_ref(). + +This function is expected to set the method's reference count to 1. + +=item destruct() + +Decrement the I's reference count, and destruct it when +the reference count reaches zero. + +=back + +=head1 RETURN VALUES + +ossl_method_construct() returns a constructed method on success, or +NULL on error. + +=head1 HISTORY + +This functionality was added to OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use this +file except in compliance with the License. You can obtain a copy in the file +LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_namemap_new.pod b/crypto/openssl/doc/internal/man3/ossl_namemap_new.pod new file mode 100644 index 000000000000..ff247e87b03c --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_namemap_new.pod @@ -0,0 +1,129 @@ +=pod + +=head1 NAME + +ossl_namemap_new, ossl_namemap_free, ossl_namemap_stored, ossl_namemap_empty, +ossl_namemap_add_name, ossl_namemap_add_name_n, ossl_namemap_add_names, +ossl_namemap_name2num, ossl_namemap_name2num_n, +ossl_namemap_doall_names +- internal number E-E name map + +=head1 SYNOPSIS + + #include "internal/cryptlib.h" + + OSSL_NAMEMAP *ossl_namemap_stored(OSSL_LIB_CTX *libctx); + + OSSL_NAMEMAP *ossl_namemap_new(void); + void ossl_namemap_free(OSSL_NAMEMAP *namemap); + int ossl_namemap_empty(OSSL_NAMEMAP *namemap); + + int ossl_namemap_add_name(OSSL_NAMEMAP *namemap, int number, const char *name); + int ossl_namemap_add_name_n(OSSL_NAMEMAP *namemap, int number, + const char *name, size_t name_len); + + int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name); + int ossl_namemap_name2num_n(const OSSL_NAMEMAP *namemap, + const char *name, size_t name_len); + int ossl_namemap_doall_names(const OSSL_NAMEMAP *namemap, int number, + void (*fn)(const char *name, void *data), + void *data); + + int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number, + const char *names, const char separator); + +=head1 DESCRIPTION + +A B is a one-to-many number E-E names map, which +can be used to give any arbitrary set of names (any string) a unique +dynamic identity that is valid throughout the lifetime of the associated +library context. + +ossl_namemap_new() and ossl_namemap_free() construct and destruct a +new B. +This is suitable to use when the B is embedded in other +structures, or should be independent for any reason. + +ossl_namemap_empty() checks if the given B is empty or +not. + +ossl_namemap_stored() finds or auto-creates the default namemap in the +given library context. +The returned B can't be destructed using +ossl_namemap_free(). + +ossl_namemap_add_name() adds a new name to the namemap if it's not already +present. +If the given I is zero, a new number will be allocated to +identify this I. +If the given I is nonzero, the I is added to the set of +names already associated with that number. + +ossl_namemap_name2num() finds the number corresponding to the given +I. + +ossl_namemap_add_name_n() and ossl_namemap_name2num_n() do the same thing +as ossl_namemap_add_name() and ossl_namemap_name2num(), but take a string +length I as well, allowing the caller to use a fragment of +a string as a name. + +ossl_namemap_doall_names() walks through all names associated with +I in the given I and calls the function I for +each of them. +I is also passed the I argument, which allows any caller to +pass extra data for that function to use. + +ossl_namemap_add_names() divides up a set of names given in I, +separated by I, and adds each to the I, all with +the same number. If some of them already exist in the I, +they must all have the same associated number, which will be adopted +for any name that doesn't exist yet. + +=head1 RETURN VALUES + +ossl_namemap_new() and ossl_namemap_stored() return the pointer to a +B, or NULL on error. + +ossl_namemap_empty() returns 1 if the B is NULL or +empty, 0 if it's not empty, or -1 on internal error (such as inability +to lock). + +ossl_namemap_add_name() and ossl_namemap_add_name_n() return the number +associated with the added string, or zero on error. + +ossl_namemap_num2names() returns a pointer to a NULL-terminated list of +pointers to the names corresponding to the given number, or NULL if +it's undefined in the given B. + +ossl_namemap_name2num() and ossl_namemap_name2num_n() return the number +corresponding to the given name, or 0 if it's undefined in the given +B. + +ossl_namemap_doall_names() returns 1 if the callback was called for all names. A +return value of 0 means that the callback was not called for any names. + +ossl_namemap_add_names() returns the number associated with the added +names, or zero on error. + +=head1 NOTES + +The result from ossl_namemap_num2names() isn't thread safe, other threads +dealing with the same namemap may cause the list of names to change +location. +It is therefore strongly recommended to only use the result in code +guarded by a thread lock. + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_provider_add_conf_module.pod b/crypto/openssl/doc/internal/man3/ossl_provider_add_conf_module.pod new file mode 100644 index 000000000000..7e4d5097f634 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_provider_add_conf_module.pod @@ -0,0 +1,41 @@ +=pod + +=head1 NAME + +ossl_provider_add_conf_module - internal standard configuration module + +=head1 SYNOPSIS + + #include "internal/provider.h" + + /* Configuration */ + void ossl_provider_add_conf_module(void); + +=head1 DESCRIPTION + +ossl_provider_add_conf_module() adds the standard configuration module +for providers. +This allows providers to be configured with an OpenSSL L file. + +=head1 RETURN VALUES + +ossl_provider_add_conf_module() doesn't return any value. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_provider_new.pod b/crypto/openssl/doc/internal/man3/ossl_provider_new.pod new file mode 100644 index 000000000000..8bd5594c484c --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_provider_new.pod @@ -0,0 +1,400 @@ +=pod + +=head1 NAME + +ossl_provider_find, ossl_provider_new, ossl_provider_up_ref, +ossl_provider_free, +ossl_provider_set_fallback, ossl_provider_set_module_path, +ossl_provider_add_parameter, ossl_provider_set_child, ossl_provider_get_parent, +ossl_provider_up_ref_parent, ossl_provider_free_parent, +ossl_provider_default_props_update, ossl_provider_get0_dispatch, +ossl_provider_init_as_child, ossl_provider_deinit_child, +ossl_provider_activate, ossl_provider_deactivate, ossl_provider_add_to_store, +ossl_provider_ctx, +ossl_provider_doall_activated, +ossl_provider_name, ossl_provider_dso, +ossl_provider_module_name, ossl_provider_module_path, +ossl_provider_libctx, +ossl_provider_teardown, ossl_provider_gettable_params, +ossl_provider_get_params, +ossl_provider_query_operation, ossl_provider_unquery_operation, +ossl_provider_set_operation_bit, ossl_provider_test_operation_bit, +ossl_provider_get_capabilities +- internal provider routines + +=head1 SYNOPSIS + + #include "internal/provider.h" + + OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name, + int noconfig); + OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, + ossl_provider_init_fn *init_function + int noconfig); + int ossl_provider_up_ref(OSSL_PROVIDER *prov); + void ossl_provider_free(OSSL_PROVIDER *prov); + + /* Setters */ + int ossl_provider_set_fallback(OSSL_PROVIDER *prov); + int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *path); + int ossl_provider_add_parameter(OSSL_PROVIDER *prov, const char *name, + const char *value); + + /* Child Providers */ + int ossl_provider_set_child(OSSL_PROVIDER *prov, + const OSSL_CORE_HANDLE *handle); + const OSSL_CORE_HANDLE *ossl_provider_get_parent(OSSL_PROVIDER *prov); + int ossl_provider_up_ref_parent(OSSL_PROVIDER *prov, int activate); + int ossl_provider_free_parent(OSSL_PROVIDER *prov, int deactivate); + int ossl_provider_default_props_update(OSSL_LIB_CTX *libctx, + const char *props); + + /* + * Activate the Provider + * If the Provider is a module, the module will be loaded + */ + int ossl_provider_activate(OSSL_PROVIDER *prov, int upcalls, int aschild); + int ossl_provider_deactivate(OSSL_PROVIDER *prov, int removechildren); + int ossl_provider_add_to_store(OSSL_PROVIDER *prov, OSSL_PROVIDER **actualprov, + int retain_fallbacks); + + /* Return pointer to the provider's context */ + void *ossl_provider_ctx(const OSSL_PROVIDER *prov); + + const OSSL_DISPATCH *ossl_provider_get0_dispatch(const OSSL_PROVIDER *prov); + + /* Iterate over all loaded providers */ + int ossl_provider_doall_activated(OSSL_LIB_CTX *, + int (*cb)(OSSL_PROVIDER *provider, + void *cbdata), + void *cbdata); + + /* Getters for other library functions */ + const char *ossl_provider_name(OSSL_PROVIDER *prov); + const DSO *ossl_provider_dso(OSSL_PROVIDER *prov); + const char *ossl_provider_module_name(OSSL_PROVIDER *prov); + const char *ossl_provider_module_path(OSSL_PROVIDER *prov); + OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov); + + /* Thin wrappers around calls to the provider */ + void ossl_provider_teardown(const OSSL_PROVIDER *prov); + const OSSL_PARAM *ossl_provider_gettable_params(const OSSL_PROVIDER *prov); + int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]); + int ossl_provider_get_capabilities(const OSSL_PROVIDER *prov, + const char *capability, + OSSL_CALLBACK *cb, + void *arg); + const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, + int operation_id, + int *no_cache); + void ossl_provider_unquery_operation(const OSSL_PROVIDER *prov, + int operation_id, + const OSSL_ALGORITHM *algs); + + int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum); + int ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum, + int *result); + + int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx, + const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in); + void ossl_provider_deinit_child(OSSL_LIB_CTX *ctx); + +=head1 DESCRIPTION + +I is a type that holds all the necessary information +to handle a provider, regardless of if it's built in to the +application or the OpenSSL libraries, or if it's a loadable provider +module. +Instances of this type are commonly referred to as "provider objects". + +A provider object is always stored in a set of provider objects +in the library context. + +Provider objects are reference counted. + +Provider objects are initially inactive, i.e. they are only recorded +in the store, but are not used. +They are activated with the first call to ossl_provider_activate(), +and are deactivated with the last call to ossl_provider_deactivate(). +Activation affects a separate counter. + +=head2 Functions + +ossl_provider_find() finds an existing provider object in the provider +object store by I. +The config file will be automatically loaded unless I is set. +Typically I should be 0. +We set I to 1 only when calling these functions while processing a +config file in order to avoid recursively attempting to load the file. +The provider object it finds has its reference count incremented. + +ossl_provider_new() creates a new provider object named I and +stores it in the provider object store, unless there already is one +there with the same name. +If there already is one with the same name, it's returned with its +reference count incremented. +The config file will be automatically loaded unless I is set. +Typically I should be 0. +We set I to 1 only when calling these functions while processing a +config file in order to avoid recursively attempting to load the file. +The reference count of a newly created provider object will always +be 2; one for being added to the store, and one for the returned +reference. +If I is NULL, the provider is assumed to be a +dynamically loadable module, with the symbol B as +its initialisation function. +If I isn't NULL, the provider is assumed to be built +in, with I being the pointer to its initialisation +function. +For further description of the initialisation function, see the +description of ossl_provider_activate() below. + +ossl_provider_up_ref() increments the provider object I's +reference count. + +ossl_provider_free() decrements the provider object I's +reference count; when it drops to zero, the provider object is assumed +to have fallen out of use and will be deinitialized (its I +function is called), and the associated module will be unloaded if one +was loaded, and I itself will be freed. + +ossl_provider_set_fallback() marks an available provider I as +fallback. +Note that after this call, the provider object pointer that was +used can simply be dropped, but not freed. + +ossl_provider_set_module_path() sets the module path to load the +provider module given the provider object I. +This will be used in preference to automatically trying to figure out +the path from the provider name and the default module directory (more +on this in L). + +ossl_provider_libctx() returns the library context the given +provider I is registered in. + +ossl_provider_add_parameter() adds a global parameter for the provider +to retrieve as it sees fit. +The parameters are a combination of I and I, and the +provider will use the name to find the value it wants. +Only text parameters can be given, and it's up to the provider to +interpret them. + +ossl_provider_set_child() marks this provider as a child of a provider in the +parent library context. I is the B object passed to +the provider's B function. + +ossl_provider_get_parent() obtains the handle on the parent provider. + +ossl_provider_up_ref_parent() increases the reference count on the parent +provider. If I is nonzero then the parent provider is also activated. + +ossl_provider_free_parent() decreases the reference count on the parent +provider. If I is nonzero then the parent provider is also +deactivated. + +ossl_provider_default_props_update() is responsible for informing any child +providers of an update to the default properties. The new properties are +supplied in the I string. + +ossl_provider_activate() "activates" the provider for the given +provider object I by incrementing its activation count, flagging +it as activated, and initializing it if it isn't already initialized. +Initializing means one of the following: + +=over 4 + +=item * + +If an initialization function was given with ossl_provider_new(), that +function will get called. + +=item * + +If no initialization function was given with ossl_provider_new(), a +loadable module with the I that was given to ossl_provider_new() +will be located and loaded, then the symbol B will +be located in that module, and called. + +=back + +If I is nonzero then, if this is a child provider, upcalls to the +parent libctx will be made to inform it of an up-ref. If I is nonzero +then the provider will only be activated if it is a child provider. Otherwise +no action is taken and ossl_provider_activate() returns success. + +ossl_provider_deactivate() "deactivates" the provider for the given +provider object I by decrementing its activation count. When +that count reaches zero, the activation flag is cleared. If the +I parameter is 0 then no attempt is made to remove any +associated child providers. + +ossl_provider_add_to_store() adds the provider I to the provider store and +makes it available to other threads. This will prevent future automatic loading +of fallback providers, unless I is true. If a provider of the +same name already exists in the store then it is not added but this function +still returns success. On success the I value is populated with a +pointer to the provider of the given name that is now in the store. The +reference passed in the I argument is consumed by this function. A +reference to the provider that should be used is passed back in the +I argument. + +ossl_provider_ctx() returns a context created by the provider. +Outside of the provider, it's completely opaque, but it needs to be +passed back to some of the provider functions. + +ossl_provider_get0_dispatch() returns the dispatch table that the provider +initially returned in the I parameter of its B +function. + +ossl_provider_doall_activated() iterates over all the currently +"activated" providers, and calls I for each of them. +If no providers have been "activated" yet, it tries to activate all +available fallback providers before iterating over them. + +ossl_provider_name() returns the name that was given with +ossl_provider_new(). + +ossl_provider_dso() returns a reference to the module, for providers +that come in the form of loadable modules. + +ossl_provider_module_name() returns the filename of the module, for +providers that come in the form of loadable modules. + +ossl_provider_module_path() returns the full path of the module file, +for providers that come in the form of loadable modules. + +ossl_provider_teardown() calls the provider's I function, if +the provider has one. + +ossl_provider_gettable_params() calls the provider's I +function, if the provider has one. +It should return an array of I to describe all the +parameters that the provider has for the provider object. + +ossl_provider_get_params() calls the provider's parameter request +responder. +It should treat the given I array as described in +L. + +ossl_provider_get_capabilities() calls the provider's I function, +if the provider has one. It provides the name of the I and a +callback I parameter to call for each capability that has a matching name in +the provider. The callback gets passed OSSL_PARAM details about the capability as +well as the caller supplied argument I. + +ossl_provider_query_operation() calls the provider's +I function, if the provider has one. +It should return an array of I for the given +I. + +ossl_provider_unquery_operation() informs the provider that the result of +ossl_provider_query_operation() is no longer going to be directly accessed and +that all relevant information has been copied. + +ossl_provider_set_operation_bit() registers a 1 for operation I +in a bitstring that's internal to I. + +ossl_provider_test_operation_bit() checks if the bit operation I +is set (1) or not (0) in the internal I bitstring, and sets +I<*result> to 1 or 0 accorddingly. + +ossl_provider_init_as_child() stores in the library context I references to +the necessary upcalls for managing child providers. The I and I +parameters are the B and L pointers that were +passed to the provider's B function. + +ossl_provider_deinit_child() deregisters callbacks from the parent library +context about provider creation or removal events for the child library context +I. Must only be called if I is a child library context. + +=head1 NOTES + +Locating a provider module happens as follows: + +=over 4 + +=item 1. + +If a path was given with ossl_provider_set_module_path(), use that as +module path. +Otherwise, use the provider object's name as module path, with +platform specific standard extensions added. + +=item 2. + +If the environment variable B is defined, assume its +value is a directory specification and merge it with the module path. +Otherwise, merge the value of the OpenSSL built in macro B +with the module path. + +=back + +When this process is done, the result is used when trying to load the +provider module. + +The command C can be used to find out the value +of the built in macro B. + +=head1 RETURN VALUES + +ossl_provider_find() and ossl_provider_new() return a pointer to a +provider object (I) on success, or NULL on error. + +ossl_provider_up_ref() returns the value of the reference count after +it has been incremented. + +ossl_provider_free() doesn't return any value. + +ossl_provider_doall_activated() returns 1 if the callback was called for all +activated providers. A return value of 0 means that the callback was not +called for any activated providers. + +ossl_provider_set_module_path(), ossl_provider_set_fallback(), +ossl_provider_activate(), ossl_provider_activate_leave_fallbacks() and +ossl_provider_deactivate(), ossl_provider_add_to_store(), +ossl_provider_default_props_update() return 1 on success, or 0 on error. + +ossl_provider_name(), ossl_provider_dso(), +ossl_provider_module_name(), and ossl_provider_module_path() return a +pointer to their respective data if it's available, otherwise NULL +is returned. + +ossl_provider_libctx() return a pointer to the library context. +This may be NULL, and is perfectly valid, as it denotes the default +global library context. + +ossl_provider_teardown() doesn't return any value. + +ossl_provider_gettable_params() returns a pointer to a constant +I array if this function is available in the provider, +otherwise NULL. + +ossl_provider_get_params() returns 1 on success, or 0 on error. +If this function isn't available in the provider, 0 is returned. + +ossl_provider_set_operation_bit() and ossl_provider_test_operation_bit() +return 1 on success, or 0 on error. + +ossl_provider_get_capabilities() returns 1 on success, or 0 on error. +If this function isn't available in the provider or the provider does not +support the requested capability then 0 is returned. + +=head1 SEE ALSO + +L, L, L + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_punycode_decode.pod b/crypto/openssl/doc/internal/man3/ossl_punycode_decode.pod new file mode 100644 index 000000000000..652626159e3a --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_punycode_decode.pod @@ -0,0 +1,60 @@ +=pod + +=head1 NAME + +ossl_punycode_decode, ossl_a2ulabel, ossl_a2ucompare +- internal punycode-related functions + +=head1 SYNOPSIS + + #include "crypto/punycode.h" + + int ossl_punycode_decode(const char *pEncoded, const size_t enc_len, + unsigned int *pDecoded, unsigned int *pout_length); + + int ossl_a2ulabel(const char *in, char *out, size_t *outlen); + + int ossl_a2ucompare(const char *a, const char *u); + +=head1 DESCRIPTION + +PUNYCODE encoding introduced in RFCs 3490-3492 is widely used for +representation of host names in ASCII-only format. Some specifications, +such as RFC 8398, require comparison of host names encoded in UTF-8 charset. + +ossl_a2ulabel() decodes NUL-terminated hostname from PUNYCODE to UTF-8, +using a provided buffer for output. + +ossl_a2ucompare() accepts two NUL-terminated hostnames, decodes the 1st +from PUNYCODE to UTF-8 and compares it with the 2nd one as is. + +ossl_punycode_decode() decodes one label (one dot-separated part) from +a hostname, with stripped PUNYCODE marker I. + +=head1 RETURN VALUES + +ossl_a2ulabel() returns 1 on success, 0 on not enough buf passed, +-1 on invalid PUNYCODE string passed. When valid string is provided, it sets the +I<*outlen> to the length of required buffer to perform correct decoding. + +ossl_a2ucompare() returns 1 on non-equal strings, 0 on equal strings, +-1 when invalid PUNYCODE string passed. + +ossl_punycode_decode() returns 1 on success, 0 on error. On success, +*pout_length contains the number of codepoints decoded. + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut + diff --git a/crypto/openssl/doc/internal/man3/ossl_rand_get_entropy.pod b/crypto/openssl/doc/internal/man3/ossl_rand_get_entropy.pod new file mode 100644 index 000000000000..4da3f1f4d9db --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_rand_get_entropy.pod @@ -0,0 +1,66 @@ +=pod + +=head1 NAME + +ossl_rand_get_entropy, ossl_rand_cleanup_entropy, +ossl_rand_get_nonce, ossl_rand_cleanup_nonce +- get seed material from the operating system + +=head1 SYNOPSIS + + #include "crypto/rand.h" + + size_t ossl_rand_get_entropy(OSSL_CORE_HANDLE *handle, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len); + void ossl_rand_cleanup_entropy(OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len); + size_t ossl_rand_get_nonce(OSSL_CORE_HANDLE *handle, + unsigned char **pout, size_t min_len, + size_t max_len, const void *salt, size_t salt_len); + void ossl_rand_cleanup_nonce(OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len); + +=head1 DESCRIPTION + +ossl_rand_get_entropy() retrieves seeding material from the operating system. +The seeding material will have at least I bytes of randomness and is +stored in a buffer which contains at least I and at most I +bytes. The buffer address is stored in I<*pout> and the buffer length is +returned to the caller. + +ossl_rand_cleanup_entropy() cleanses and frees any storage allocated by +ossl_rand_get_entropy(). The seeding buffer is pointed to by I and is +of length I bytes. + +ossl_rand_get_nonce() retrieves a nonce using the passed I parameter +of length I and operating system specific information. +The I should contain uniquely identifying information and this is +included, in an unspecified manner, as part of the output. +The output is stored in a buffer which contains at least I and at +most I bytes. The buffer address is stored in I<*pout> and the +buffer length returned to the caller. + +ossl_rand_cleanup_nonce() cleanses and frees any storage allocated by +ossl_rand_get_nonce(). The nonce buffer is pointed to by I and is +of length I bytes. + +=head1 RETURN VALUES + +ossl_rand_get_entropy() and ossl_rand_get_nonce() return the number of bytes +in I<*pout> or 0 on error. + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_random_add_conf_module.pod b/crypto/openssl/doc/internal/man3/ossl_random_add_conf_module.pod new file mode 100644 index 000000000000..6d4f5810dcdd --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_random_add_conf_module.pod @@ -0,0 +1,42 @@ +=pod + +=head1 NAME + +ossl_random_add_conf_module - internal random configuration module + +=head1 SYNOPSIS + + #include "crypto/rand.h" + + /* Configuration */ + void ossl_random_add_conf_module(void); + +=head1 DESCRIPTION + +ossl_random_add_conf_module() adds the random configuration module +for providers. +This allows the type and parameters of the stardard setup of random number +generators to be configured with an OpenSSL L file. + +=head1 RETURN VALUES + +ossl_random_add_conf_module() doesn't return any value. + +=head1 SEE ALSO + +L, L, L + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/ossl_rsa_get0_all_params.pod b/crypto/openssl/doc/internal/man3/ossl_rsa_get0_all_params.pod new file mode 100644 index 000000000000..a7ebb613bb02 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/ossl_rsa_get0_all_params.pod @@ -0,0 +1,75 @@ +=pod + +=head1 NAME + +ossl_rsa_set0_all_params, ossl_rsa_get0_all_params +- Internal routines for getting and setting data in an RSA object + +=head1 SYNOPSIS + + #include "crypto/rsa.h" + + int ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, + STACK_OF(BIGNUM_const) *exps, + STACK_OF(BIGNUM_const) *coeffs); + int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, + const STACK_OF(BIGNUM) *exps, + const STACK_OF(BIGNUM) *coeffs); + +=head1 DESCRIPTION + +ossl_rsa_set0_all_params() sets all primes, CRT exponents and CRT coefficients +in the B object I to the contents of the stacks of BIGNUMs I, +I and I. The B object takes ownership of the BIGNUMs, +but not of the stacks. + +ossl_rsa_get0_all_params() gets all primes, CRT exponents and CRT coefficients +in the B object I and pushes them on the stacks of constant BIGNUMs +I, I and I. The B object retains ownership of the +BIGNUMs, but not of the stacks. + +=head1 NOTES + +For RSA_set0_all_params() and RSA_get0_all_params(): + +=over 4 + +=item * + +the I stack contains I

, I, and then the rest of the primes +if the B object is a multi-prime RSA key. + +=item * + +the I stack contains I, I, and then the rest of the exponents +if the B object is a multi-prime RSA key. + +=item * + +the I stack contains I, and then the rest of the coefficients +if the B object is a multi-prime RSA key. + +=back + +The number of primes must always be equal to the number of exponents, and +the number of coefficients must be one less than the number of primes. + +=head1 RETURN VALUES + +ossl_rsa_get0_all_params() and ossl_rsa_set0_all_params() return 1 on success, +or 0 on failure. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man3/x509v3_cache_extensions.pod b/crypto/openssl/doc/internal/man3/x509v3_cache_extensions.pod new file mode 100644 index 000000000000..cc0aeb6079a8 --- /dev/null +++ b/crypto/openssl/doc/internal/man3/x509v3_cache_extensions.pod @@ -0,0 +1,41 @@ +=pod + +=head1 NAME + +x509v3_cache_extensions +- cache info on various X.509v3 extensions and further derived certificate data + +=head1 SYNOPSIS + + #include + + int x509v3_cache_extensions(X509 *x, OSSL_LIB_CTX *libctx, const char *propq); + +=head1 DESCRIPTION + +This function processes any X509v3 extensions present in an X509 object I +and caches the result of that processing as well as further derived info, +for instance whether the certificate is self-issued or has version X.509v1. +It computes the SHA1 digest of the certificate using the default library context +and property query string and stores the result in x->sha1_hash, +or on failure sets B in x->flags. +It sets B in x->flags if x->siginf was filled successfully, +which may not be possible if a referenced algorithm is unknown or not available. +Many OpenSSL functions that use an X509 object call this function implicitly. + +=head1 RETURN VALUES + +This function returns 0 if the extensions or other portions of the certificate +are invalid or an error occurred. +Otherwise it returns 1. + +=head1 COPYRIGHT + +Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man7/DERlib.pod b/crypto/openssl/doc/internal/man7/DERlib.pod new file mode 100644 index 000000000000..24280b976b34 --- /dev/null +++ b/crypto/openssl/doc/internal/man7/DERlib.pod @@ -0,0 +1,149 @@ +=pod + +=head1 NAME + +DERlib - internal OpenSSL DER library + +=head1 DESCRIPTION + +OpenSSL contains an internal small DER reading and writing library, +as an alternative to the publicly known i2d and d2i functions. It's +solely constituted of functions that work as building blocks to create +more similar functions to encode and decode larger structures. + +All these functions have similar function signatures (C +will vary depending on what the function will encode): + + int DER_w_something(WPACKET *pkt, int tag, ...); + +=begin comment + +When readers are added, add this: + + int DER_r_something(PACKET *pkt, int tag, ...); + +=end comment + +I is the packet context used, and I should be the +context-specific tag value of the element being handled, or -1 if there +is no tag number for that element (you may use the convenience macro +B instead of -1). Any argument following is the C +variable that's being encoded or decoded. + +=head2 DER writers / encoders + +DER writers are based in L, a generic packet writing +library, so before using any of them, I must be initialized +using L or L + +DER writers must be used in reverse order, except for the wrapping +functions that implement a constructed element. The latter are easily +recognised by their function name including the words C and +C. As an example, we can look at the DSA signature structure, +which is defined like this in ASN.1 terms: + + -- Copied from RFC 3279, section 2.2.2 + Dss-Sig-Value ::= SEQUENCE { + r INTEGER, + s INTEGER } + +With the DER library, this is the corresponding code, given two OpenSSL +Bs I and I: + + int ok = ossl_DER_w_begin_sequence(pkt, -1) + && ossl_DER_w_bn(pkg, -1, s) + && ossl_DER_w_bn(pkg, -1, r) + && ossl_DER_w_end_sequence(pkt, -1); + +As an example of the use of I, an ASN.1 element like this: + + v [1] INTEGER OPTIONAL + +Would be encoded like this: + + ossl_DER_w_bn(pkt, 1, v) + +=begin comment + +=head2 DER readers / decoders + +TBA + +=end comment + +=head1 EXAMPLES + +A more complex example, encoding the AlgorithmIdentifier with +RSASSA-PSS values. + +As a reminder, the AlgorithmIdentifier is specified like this: + + -- From RFC 3280, section 4.1.1.2 + AlgorithmIdentifier ::= SEQUENCE { + algorithm OBJECT IDENTIFIER, + parameters ANY DEFINED BY algorithm OPTIONAL } + +And the RSASSA-PSS OID and parameters are specified like this: + + -- From RFC 3279, section 3.1 + id-RSASSA-PSS OBJECT IDENTIFIER ::= { pkcs-1 10 } + + RSASSA-PSS-params ::= SEQUENCE { + hashAlgorithm [0] HashAlgorithm DEFAULT + sha1Identifier, + maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT + mgf1SHA1Identifier, + saltLength [2] INTEGER DEFAULT 20, + trailerField [3] INTEGER DEFAULT 1 } + +The value we want to encode, written in ASN.1 syntax: + + { + algorithm id-RSASSA-PSS, + parameters { + hashAlgorithm sha256Identifier, + maskGenAlgorithm mgf1SHA256Identifier, + saltLength 20 -- unnecessarily explicit + } + } + +Assuming that we have precompiled constants for C, +C and C, the DER writing code +looks as follows. This is a complete function to write that specific +value: + + int DER_w_AlgorithmIdentifier_RSASSA_PSS_special(WPACKET *pkt, + int tag, + RSA *rsa) + { + return ossl_DER_w_begin_sequence(pkt, tag) + && (ossl_DER_w_begin_sequence(pkt, DER_NO_CONTEXT) + && ossl_DER_w_uint32(pkt, 2, 20) + && ossl_DER_w_precompiled(pkt, 1, + der_mgf1SHA256Identifier, + sizeof(der_mgf1SHA256Identifier)) + && ossl_DER_w_precompiled(pkt, 0, + der_sha256Identifier, + sizeof(der_sha256Identifier)) + && ossl_DER_w_end_sequence(pkt, DER_NO_CONTEXT)) + && ossl_DER_w_precompiled(pkt, DER_NO_CONTEXT, + der_id_RSASSA_PSS, + sizeof(der_id_RSASSA_PSS)) + && ossl_DER_w_end_sequence(pkt, tag); + } + +=head1 SEE ALSO + +L, L, +L + +=head1 COPYRIGHT + +Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man7/EVP_PKEY.pod b/crypto/openssl/doc/internal/man7/EVP_PKEY.pod new file mode 100644 index 000000000000..cc738b9c28eb --- /dev/null +++ b/crypto/openssl/doc/internal/man7/EVP_PKEY.pod @@ -0,0 +1,212 @@ +=pod + +=head1 NAME + +EVP_PKEY - an internal description + +=head1 SYNOPSIS + + #include "crypto/evp.h" + + typedef struct evp_pkey_st EVP_PKEY; + +=head1 DESCRIPTION + +I + +B is a complex type that's essentially a container for +private/public key pairs, but has had other uses as well. + +=for comment "uses" could as well be "abuses"... + +The private/public key pair that an B contains is refered to +as its "internal key" or "origin" (the reason for "origin" is +explained further down, in L), +and it can take one of the following forms: + +=over 4 + +=item legacy origin + +This is the form that an B in OpenSSL prior to 3.0 had. The +internal key in the B is a pointer to the low-level key +types, such as B, B and B, or an engine driven +structure, and is governed by an associated L and +an L. + +The functions available through those two method structures get full +access to the B and therefore have a lot of freedom to +modify whatever they want. This also means that an B is a +shared structure between libcrypto and any ENGINE that serves such +methods. + +=item provider-native origin + +This is a new form in OpenSSL 3.0, which permits providers to hold the +key data (see L). The internal key in the +B is a pointer to that key data held by the provider, and +is governed by an associated L method structure. + +The functions available through the L have no access +to the B, and can therefore not make any direct changes. +Similarly, the key data that the B points at is only known +to the functions pointed at in the L. + +=back + +These two forms can never co-exist in the same B, the main +reason being that having both at the same time will create problems +with synchronising between the two forms, and potentially make it +confusing which one of the two is the origin. + +=head2 Key mutability + +The B internal keys are mutable. + +This is especially visible with internal legacy keys, since they can +be extracted with functions like L and then +modified at will with functions like L. Note that if the +internal key is a provider key then the return value from functions such as +L is a cached copy of the key. Changes to the cached +copy are not reflected back in the provider key. + +Internal provider native keys are also possible to be modified, if the +associated L implementation allows it. This is done +with L and its specialised derivatives. The +OpenSSL providers allow it for the following: + +=over 4 + +=item DH, EC, X25519, X448: + +It's possible to set the encoded public key. This is supported in +particular through L. + +=item EC: + +It's possible to flip the ECDH cofactor mode. + +=back + +Every time the B internal key mutates, an internal dirty +count is incremented. The need for a dirty count is explained further +in L. + +For provider native origin keys, this doesn't require any help from +the L, the dirty count is maintained in the B +itself, and is incremented every time L or its +specialised derivatives are called. +For legacy origin keys, this requires the associated +L to implement the dirty_cnt() function. All +of OpenSSL's built-in L implement this +function. + +=head2 Export cache for provider operations + +OpenSSL 3.0 can handle operations such as signing, encrypting, etc in +diverse providers, potentially others than the provider of the +L. Two providers, possibly from different vendors, +can't be expected to share internal key structures. There are +therefore instances where key data will need to be exported to the +provider that is going to perform the operation (this also implies +that every provider that implements a key pair based operation must +also implement an L). + +For performance reasons, libcrypto tries to minimize the need to +perform such an export, so it maintains a cache of such exports in the +B. Each cache entry has two items, a pointer to the +provider side key data and the associated L. + +I + +The export to the operation key cache can be performed independent of +what form the origin has. +For a legacy origin, this requires that the associated +L implements the functions export_to() and +dirty_cnt(). +For a provider native origin, this requires that the associated +L implements the OSSL_FUNC_keymgmt_export() function +(see L). +In all cases, the receiving L (the one associated with +the exported key data) must implement OSSL_FUNC_keymgmt_import(). + +If such caching isn't supported, the operations that can be performed +with that key are limited to the same backend as the origin key +(ENGINE for legacy origin keys, provider for provider side origin +keys). + +=head3 Exporting implementation details + + +Exporting a key to the operation cache involves the following: + +=over 4 + +=item 1. + +Check if the dirty count for the internal origin key has changed since +the previous time. This is done by comparing it with a copy of the +dirty count, which is maintained by the export function. + +If the dirty count has changed, the export cache is cleared. + +=item 2. + +Check if there's an entry in the export cache with the same +L that's the same provider that an export is to be +made to (which is the provider that's going to perform an operation +for which the current B is going to be used). + +If such an entry is found, nothing more is done, the key data and +L found in that export cache entry will be used for +the operation to be performed. + +=item 3. + +Export the internal origin key to the provider, using the appropriate +method. + +For legacy origin keys, that's done with the help of the +L export_to() function. + +For provider native origin keys, that's done by retrieving the key +data in L form from the origin keys, using the +OSSL_FUNC_keymgmt_export() functions of the associated +L, and sending that data to the L of +the provider that's to perform the operation, using its +OSSL_FUNC_keymgmt_import() function. + +=back + +=head2 Changing a key origin + +It is never possible to change the origin of a key. An B with a legacy +origin will I be upgraded to become an B with a provider +native origin. Instead, we have the operation cache as described above, that +takes care of the needs of the diverse operation the application may want to +perform. + +Similarly an B with a provider native origin, will I be +I into an B with a legacy origin. Instead we may have a +cached copy of the provider key in legacy form. Once the cached copy is created +it is never updated. Changes made to the provider key are not reflected back in +the cached legacy copy. Similarly changes made to the cached legacy copy are not +reflected back in the provider key. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man7/VERSION.pod b/crypto/openssl/doc/internal/man7/VERSION.pod new file mode 100644 index 000000000000..4bc8ba6b9327 --- /dev/null +++ b/crypto/openssl/doc/internal/man7/VERSION.pod @@ -0,0 +1,149 @@ +=pod + +=head1 NAME + +VERSION - OpenSSL version information + +=head1 SYNOPSIS + + MAJOR=3 + MINOR=0 + PATCH=0 + PRE_RELEASE_TAG=dev + BUILD_METADATA= + RELEASE_DATE= + SHLIB_VERSION=3 + +=head1 DESCRIPTION + +This file is a set of keyed information looking like simple variable +assignments. When given an empty value, they are seen as unassigned. +The keys that are recognised are: + +=over 4 + +=item B, B, B + +The three parts of OpenSSL's 3 numbered version number, MAJOR.MINOR.PATCH. +These are used to compose the values for the C macros B, +B, B. + +=item B + +This is the added pre-release tag, which is added to the version separated by +a dash. For a value C, the C macro B gets +the string C<-foo> (dash added). + +=item B + +Extra metadata to be used by anyone for their own purposes. This is added to +the version and possible pre-release tag, separated by a plus sign. For a +value C, the C macro B gets the string +C<+bar>. + +=item B + +Defined in releases. When not set, it gets the value C. + +=item B + +The shared library version, which is something other than the project version. + +=back + +It is a configuration error if B, B, B and B +don't have values. Configuration will stop in that case. + +=head2 Affected configuration data + +The following items in %config from F are affected: + +=over 4 + +=item $config{major}, $config{minor}, $config{patch}, $config{shlib_version} + +These items get their values from B, B, B, and +B, respectively. + +=item $config{prerelease} + +If B is assigned a value, $config{prerelease} gets that same value, +prefixed by a dash, otherwise the empty string. + +=item $config{build_metadata} + +If B is assigned a value, $config{build_metadata} gets that same +value, prefixed by a plus sign, otherwise the empty string. + +=item $config{release_date} + +If B is assigned a value, $config{release_date} gets that same +value, otherwise the string C. + +=item $config{version} + +The minimal version number, a string composed from B, B and +B, separated by periods. For C, C and C, +the string will be C<3.0.0>. + +=item $config{full_version} + +The fully loaded version number, a string composed from $config{version}, +$config{prerelease} and $config{build_metadata}. See See L for +a few examples. + +=back + +=head1 EXAMPLES + +=over 4 + +=item 1. + + MAJOR=3 + MINOR=0 + PATCH=0 + PRE_RELEASE_TAG=dev + BUILD_METADATA= + +The fully loaded version number ($config{full_version}) will be +C<3.0.0-dev>. + +=item 2. + + MAJOR=3 + MINOR=0 + PATCH=0 + PRE_RELEASE_TAG= + BUILD_METADATA=something + +The fully loaded version number ($config{full_version}) will be +C<3.0.0+something>. + +=item 3. + + MAJOR=3 + MINOR=0 + PATCH=0 + PRE_RELEASE_TAG=alpha3 + BUILD_METADATA=something + +The fully loaded version number ($config{full_version}) will be +C<3.0.0-alpha3+something>. + +=back + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man7/build.info.pod b/crypto/openssl/doc/internal/man7/build.info.pod new file mode 100644 index 000000000000..080c9e444eea --- /dev/null +++ b/crypto/openssl/doc/internal/man7/build.info.pod @@ -0,0 +1,644 @@ +=pod + +=head1 NAME + +build.info - Building information files + +=head1 SYNOPSIS + +B0|1B<]> + +B0|1B<]> + +B + +B + +B I

... + +B I ... + +B I ... + +B I ... + +B I ... + +BIB<]=> I ... + +BIB<]=> I I ... + +BIB<]=> I ... + +BIB<]=> I ... + +BIB<]=> I[B<=>I] ... + +BIB<]=> I ... + +B<$>IB<=>I + +=head1 DESCRIPTION + +OpenSSL's build system revolves around three questions: + +=over 4 + +=item What to build for? + +This is about choice of platform (combination of hardware, operating +system, and toolchain). + +=item What to build? + +This is about having all the information on what needs to be built and +from what. + +=item How to build it? + +This is about build file generation. + +=back + +This document is all about the second item, "What to build?", and most +of all, how to specify that information. + +For some terms used in this document, please see the L at +the end. + +=head2 F files + +F files are meta data files for OpenSSL's built file +generators, and are used to specify exactly what end product files +(programs, libraries, modules or scripts) are to be produced, and from +what sources. + +Intermediate files, such as object files, are seldom referred to at +all. They sometimes can be, if there's a need, but this should happen +very rarely, and support for that sort of thing is added on as-needed +basis. + +Any time a directory or file is expected in a statement value, Unix +syntax must be used, which means that the slash C must be used as +the directory separator. + +=head2 General syntax + +=head3 Comments + +Comments are any line that start with a hash sign (C<#>). The hash +sign may be preceded by any number of horizontal spaces. + +=head3 Filenames + +F files are platform agnostic. This means that there is +some information in them that is representative rather than specific. + +This is particularly visible with end product names, they work more +like a tag than as the actual filename that's going to be produced. +This is because different platforms have different decorations on +different types of files. + +For example, if we say that we want to produce a program C, it +would look like this: + + PROGRAM=foo + +However, the program filename may end up being just C (typical +for Unix), or C (typical for Windows), or even C +(possible on VMS, depending on policy). + +These platform specific decorations are not the concern of +F files. The build file generators are responsible for +transforming these platform agnostic names to their platform specific +counterparts. + +=head3 Statements + +With the exception of variables and conditions, the general statement +syntax is one of: + +=over 4 + +=item B> B<=> I ... + +=item B[>IB<]> B<=> I ... + +=back + +Every B> represents some particular type of information. + +The first form (sometimes called "plain statement") is used to specify +information on what end products need to be built, for example: + + PROGRAMS=foo bar + LIBS=libpoly libcookie + MODULES=awesome-plugin + SCRIPTS=tool1 tool2 + SUBDIRS=dir1 dir2 + +This says that we want to build programs C and C, the +libraries C and C, an awesome plugin module +C, a couple of scripts C and C, and +finally that there are more F files in subdirectories +C and C. + +The second form (sometimes called "indexed statement") is used to +specify further details for existing items, for example: + + SOURCE[foo]=foo.c details.c + DEPEND[foo]=libcookie + +This says that the program C is built from the source files +F and F, and that it depends on the library +C (in other words, the library will be included when +linking that program together). + +Multiple space separated items are allowed too: + + SOURCE[foo]=foo.c + SOURCE[details]=details.c + DEPEND[foo details]=libcookie + +For any indexed statement for which the items haven't been specified +through any plain statement, or where the items exists but the indexed +statement does not apply, the value is simply ignored by the build +file generators. + +=head3 Statement attributes + +Some statements can have attributes added to them, to allow for +variations on how they are treated. + +=over 4 + +=item B{> I | IB<=>I [,...]B<}> +B<=> I ... + +=item B[>IB<]{> I | IB<=>I +[,...]B<}> B<=> I ... + +=back + +Attributes are passed as they are to the build file generators, and +the exact interpretation of those attributes is entirely up to them +(see L below for details). + +A current example: + + LIBS{noinst,has_main}=libtestutil.a + +This says that the static library C should not be +installed (C), and that it includes an object file that has +the C
symbol (C). Most platforms don't need to know +the latter, but there are some where the program linker will not look +for C
in libraries unless it's explicitly told so, so this is +way to tell the build file generator to emit the necessary command +options to make that happen. + +Attributes are accumulated globally. This means that a library could +be given like this in different places: + + # Location 1 + LIBS=libwhatever + + # Location 2 + LIBS{noinst}=libwhatever + + # Location 3 + LIBS{has_main}=libwhatever + +The end result is that the library C will have the +attributes C and C attached to it. + +=head3 Quoting and tokens + +Statement values are normally split into a list of tokens, separated +by spaces. + +To avoid having a value split up into several tokens, they may be +quoted with double (C<">) or single (C<'>) quotes. + +For example: + + PROGRAMS=foo "space cadet" bar + +This says that we sant to build three programs, C, C +and C. + +=head3 Conditionals + +F files include a very simple condition system, involving +the following keywords: + +=over 4 + +=item B0|1B<]> + +=item B0|1B<]> + +=item B + +=item B + +=back + +This works like any condition system with similar syntax, and the +condition value in B and B can really be any literal value +that perl can interpret as true or false. + +Conditional statements are nesting. + +In itself, this is not very powerful, but together with L, +it can be. + +=head3 Variables + +F handles simple variables. They are defined by +assignment: + +=over 4 + +=item B<$>I B<=> I + +=back + +These variables can then be used as part of any statement value or +indexed statement item. This should be used with some care, as +I. + +I + +Variable references can be one of: + +=over 4 + +=item B<$>I or B<${>IB<}> + +Simple reference; the variable reference is replaced with its value, +verbatim. + +=item B<${>IBIBIB<}> + +Substitution reference; the variable reference is replaced with its +value, modified by replacing all occurrences of I with I. + +=back + +=head2 Scope + +Most of the statement values are accumulated globally from all the +F files that are digested. There are two exceptions, +F variables and B statement, for which the scope +is the F file they are in. + +=head2 Perl nuggets + +Whenever a F file is read, it is passed through the Perl +template processor L, which is a small extension of +L. + +Perl nuggets are anything between C<{-> and C<-}>, and whatever the +result from such a nugget is, that value will replace the nugget in +text form. This is useful to get dynamically generated F +statements, and is most often seen used together with the B and +B conditional statements. + +For example: + + IF[{- $disabled{something} -}] + # do whatever's needed when "something" is disabled + ELSIF[{- $somethingelse eq 'blah' -}] + # do whatever's needed to satisfy this condition + ELSE + # fallback + ENDIF + +Normal Perl scope applies, so it's possible to have an initial perl +nugget that sets diverse global variables that are used in later +nuggets. Each nugget is a Perl block of its own, so B definitions +are only in scope within the same nugget, while B definitions are +in scope within the whole F file. + +=head1 REFERENCE + +=head2 Conditionals + +=over 4 + +=item B0|1B<]> + +If the condition is true (represented as C<1> here), everything +between this B and the next corresponding B or B +applies, and the rest until the corresponding B is skipped +over. + +If the condition is false (represented as C<0> here), everything +from this B is skipped over until the next corresponding B +or B, at which point processing continues. + +=item B + +If F statements have been skipped over to this point since +the corresponding B or B, F processing starts +again following this line. + +=item B0|1B<]> + +This is B and B combined. + +=item B + +Marks the end of a conditional. + +=back + +=head2 Plain statements + +=over 4 + +=item B I ... + +This instructs the F reader to also read the F +file in every specified directory. All directories should be given +relative to the location of the current F file. + +=item B I ... + +Collects names of programs that should be built. + +B statements may have attributes, which apply to all the +programs given in such a statement. For example: + + PROGRAMS=foo + PROGRAMS{noinst}=bar + +With those two lines, the program C will not have the attribute +C, while the program C will. + +=item B I ... + +Collects names of libraries that should be built. + +The normal case is that libraries are built in both static and shared +form. However, if a name ends with C<.a>, only the static form will +be produced. + +Similarly, libraries may be referred in indexed statements as just the +plain name, or the name including the ending C<.a>. If given without +the ending C<.a>, any form available will be used, but if given with +the ending C<.a>, the static library form is used unconditionally. + +B statements may have attributes, which apply to all the +libraries given in such a statement. For example: + + LIBS=libfoo + LIBS{noinst}=libbar + +With those two lines, the library C will not have the +attribute C, while the library C will. + +=item B I + +Collects names of dynamically loadable modules that should be built. + +B statements may have attributes, which apply to all the +modules given in such a statement. For example: + + MODULES=foo + MODULES{noinst}=bar + +With those two lines, the module C will not have the attribute +C, while the module C will. + +=item B I + +Collects names of scripts that should be built, or that just exist. +That is how they differ from programs, as programs are always expected +to be compiled from multiple sources. + +B statements may have attributes, which apply to all the +scripts given in such a statement. For example: + + SCRIPTS=foo + SCRIPTS{noinst}=bar + +With those two lines, the script C will not have the attribute +C, while the script C will. + +=back + +=head2 Indexed statements + +=over 4 + +=item BIB<]> B<=> I ... + +Collects dependencies, where I depend on the given Is. + +As a special case, the I may be empty, for which the build file +generators should make the whole build depend on the given Is, +rather than the specific I. + +The I may be any program, library, module, script, or any +filename used as a value anywhere. + +The I may also be literal build file targets. Those are +recognised by being surrounded be vertical bars (also known as the +"pipe" character), C<|>. For example: + + DEPEND[|tests|]=fipsmodule.cnf + +B statements may have attributes, which apply to each +individual dependency in such a statement. For example: + + DEPEND[libfoo.a]=libmandatory.a + DEPEND[libfoo.a]{weak}=libbar.a libcookie.a + +With those statements, the dependency between C and +C is strong, while the dependency between C +and C and C is weak. See the description of +B in L for more information. + +=item BIB<]> B<=> I I ... + +This specifies that the I is generated using the I +with the Is as arguments, plus the name of the output +file as last argument. + +For Is where this is applicable, any B statement +for the same I will be given to the I as its +inclusion directories. Likewise, any B statement for the same +I will be given to the I as an extra file or module +to load, where this is applicable. + +The build file generators must be able to recognise the I. +Currently, they at least recognise files ending in C<.pl>, and will +execute them to generate the I, and files ending in C<.in>, +which will be used as input for L to generate +I (in other words, we use the exact same style of +L mechanism that is used to read F files). + +=item BIB<]> B<=> I ... + +Collects filenames that will be used as source files for I. + +The I must be a singular item, and may be any program, library, +module or script given with B, B, B and +B. + +Static libraries may be sources. In that case, its object files are +used directly when building I instead of relying on library +dependency and symbol resolution (through B statements). + +B statements may have attributes, which apply to each +individual dependency in such a statement. For example: + + SOURCE[prog]=prog_a.c + SOURCE[prog]{check}=prog_b.c prog_c.c + +With those statements, the association between C and C +comes with no extra attributes, while the association between C +and C as well as C comes with the extra attribute +C. + +=item BIB<]> B<=> I ... + +Collects filenames that will be used as source files for I. + +The I must be a singular item, and may be any library or module +given with B or B. For libraries, the given filenames +are only used for their shared form, so if the item is a library name +ending with C<.a>, the filenames will be ignored. + +B statements may have attributes, just as B +statements. + +=item BIB<]> B<=> I[B<=>I] ... + +Collects I / I pairs (or just I with no defined +value if no I is given) associated with I. + +The build file generators will decide what to do with them. For +example, these pairs should become C macro definitions whenever a +C<.c> file is built into an object file. + +=item BIB<]> B<=> I ... + +Collects inclusion directories that will be used when building the +I components (object files and whatever else). This is used at +the discretion of the build file generators. + +=back + +=head2 Known attributes + +Note: this will never be a complete list of attributes. + +=over 4 + +=item B + +This is used to specify that the end products this is set for should +not be installed, that they are only internal. This is applicable on +internal static libraries, or on test programs. + +=item B + +This is used with B, to specify that some scripts should be +installed in the "misc" directory rather than the normal program +directory. + +=item B + +This is used with B, to specify what modules are engines and +should be installed in the engines directory instead of the modules +directory. + +=item B + +This is used with B where libraries are involved, to specify +that the dependency between two libraries is weak and is only there to +infer order. + +Without this attribute, a dependency between two libraries, expressed +like this, means that if C appears in a linking command +line, so will C: + + DEPEND[libfoo.a]=libmandatory.a + +With this attribute, a dependency between two libraries, expressed +like this, means that if I C and C +appear in a linking command line (because of recursive dependencies +through other libraries), they will be ordered in such a way that this +dependency is maintained: + + DEPEND[libfoo.a]{weak}=libfoo.a libcookie.a + +This is useful in complex dependency trees where two libraries can be +used as alternatives for each other. In this example, C and +C have alternative implementations of the same thing, and +C has unresolved references to that same thing, and is +therefore depending on either of them, but not both at the same time: + + DEPEND[program1]=libmandatory.a lib1.a + DEPEND[program2]=libmandatory.a lib2.a + DEPEND[libmandatory]{weak}=lib1.a lib2.a + +=back + +=head1 GLOSSARY + +=over 4 + +=item "build file" + +This is any platform specific file that describes the complete build, +with platform specific commands. On Unix, this is typically +F; on VMS, this is typically F. + +=item "build file generator" + +Perl code that generates build files, given configuration data and +data collected from F files. + +=item "plain statement" + +Any F statement of the form B>=I, with +the exception of conditional statements and variable assignments. + +=item "indexed statement" + +Any F statement of the form B[>IB<]=>I, +with the exception of conditional statements. + +=item "intermediate file" + +Any file that's an intermediate between a source file and an end +product. + +=item "end product" + +Any file that is mentioned in the B, B, B or +B. + +=back + +=head1 SEE ALSO + +For OpenSSL::Template documentation, +C + +L + +=head1 COPYRIGHT + +Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use this +file except in compliance with the License. You can obtain a copy in the file +LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/internal/man7/deprecation.pod b/crypto/openssl/doc/internal/man7/deprecation.pod new file mode 100644 index 000000000000..13a4b059a04c --- /dev/null +++ b/crypto/openssl/doc/internal/man7/deprecation.pod @@ -0,0 +1,140 @@ +=pod + +=head1 NAME + +OPENSSL_NO_DEPRECATED_3_0, OSSL_DEPRECATEDIN_3_0, +OPENSSL_NO_DEPRECATED_1_1_1, OSSL_DEPRECATEDIN_1_1_1, +OPENSSL_NO_DEPRECATED_1_1_0, OSSL_DEPRECATEDIN_1_1_0, +OPENSSL_NO_DEPRECATED_1_0_2, OSSL_DEPRECATEDIN_1_0_2, +OPENSSL_NO_DEPRECATED_1_0_1, OSSL_DEPRECATEDIN_1_0_1, +OPENSSL_NO_DEPRECATED_1_0_0, OSSL_DEPRECATEDIN_1_0_0, +OPENSSL_NO_DEPRECATED_0_9_8, OSSL_DEPRECATEDIN_0_9_8, +deprecation - How to do deprecation + +=head1 DESCRIPTION + +Deprecation of a symbol is adding an attribute to the declaration of that +symbol (function, type, variable, but we currently only do that for +functions in our public header files, F<< >>). + +Removal of a symbol is not the same thing as deprecation, as it actually +explicitly removes the symbol from public view. + +OpenSSL configuration supports deprecation as well as simulating removal of +symbols from public view (with the configuration option C, or +if the user chooses to do so, with L), and also +supports doing this in terms of a specified OpenSSL version (with the +configuration option C<--api>, or if the user chooses to do so, with +L). + +Deprecation is done using attribute macros named +B>, used with any declaration it applies to. + +Simulating removal is done with C<#ifndef> preprocessor guards using macros +named B>. + +B> and B> are +defined in F<< >>. + +In those macro names, B> corresponds to the OpenSSL release since +which the deprecation applies, with underscores instead of periods. Because +of the change in version scheme with OpenSSL 3.0, the B> for +versions before that are three numbers (such as C<1_1_0>), while they are +two numbers (such as C<3_0>) from 3.0 and on. + +The implementation of a deprecated symbol is kept for one of two reasons: + +=over 4 + +=item Planned to be removed + +The symbol and its implementation are planned to be removed some time in the +future, but needs to remain available until that time. +Such an implementation needs to be guarded appropriately, as shown in +L below. + +=item Planned to remain internally + +The symbol is planned to be removed from public view, but will otherwise +remain for internal purposes. In this case, the implementation doesn't need +to change or be guarded. + +However, it's necessary to ensure that the declaration remains available for +the translation unit where the symbol is used or implemented, even when the +symbol is publicly unavailable through simulated removal. That's done by +including an internal header file very early in the affected translation +units. See L below. + +In the future, when the deprecated declaration is to actually be removed +from public view, it should be moved to an internal header file, with the +deprecation attribute removed, and the translation units that implement or +use that symbol should adjust their header inclusions accordingly. + +=back + +=head1 EXAMPLES + +=head2 Header files + +In public header files (F<< >>), this is what a deprecation is +expected to look like, including the preprocessor wrapping for simulated +removal: + + # ifndef OPENSSL_NO_DEPRECATED_3_0 + /* ... */ + + OSSL_DEPRECATEDIN_3_0 RSA *RSA_new_method(ENGINE *engine); + + /* ... */ + # endif + +=head2 Implementations to be removed + +For a deprecated function that we plan to remove in the future, for example +RSA_new_method(), the following should be found very early (before including +any OpenSSL header file) in the translation unit that implements it and in +any translation unit that uses it: + + /* + * Suppress deprecation warnings for RSA low level implementations that are + * kept until removal. + */ + #define OPENSSL_SUPPRESS_DEPRECATED + +The RSA_new_method() implementation itself must be guarded the same way as +its declaration in the public header file is: + + #ifndef OPENSSL_NO_DEPRECATED_3_0 + RSA *RSA_new_method(ENGINE *engine) + { + /* ... */ + } + #endif + +=head2 Implementations to remain internally + +For a deprecated function that we plan to keep internally, for example +RSA_size(), the following should be found very early (before including any +other OpenSSL header file) in the translation unit that implements it and in +any translation unit that uses it: + + /* + * RSA low level APIs are deprecated for public use, but are kept for + * internal use. + */ + #include "internal/deprecated.h" + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/life-cycles/Makefile b/crypto/openssl/doc/life-cycles/Makefile new file mode 100644 index 000000000000..4c12558e63df --- /dev/null +++ b/crypto/openssl/doc/life-cycles/Makefile @@ -0,0 +1,26 @@ +GRAPHS=cipher.dot digest.dot kdf.dot mac.dot pkey.dot rand.dot +IMAGES= + +all: png txt +png: $(subst .dot,.png,$(GRAPHS)) +txt: $(subst .dot,.txt,$(GRAPHS)) + @echo + @echo Remember to check and manually fix the mistakes before merging + @echo into the man pages. + @echo + +# for the dot program: +# sudo apt install graphviz +%.png: %.dot + dot -Tpng -O $< + @mv $<.png $@ + +# for the graph-easy program: +# sudo apt install cpanminus +# sudo cpanm Graph::Easy +%.txt: %.dot + graph-easy --from=dot --as_ascii < $< > $@ + +clean: + rm -f $(wildcard *.png) $(wildcard *.txt) + diff --git a/crypto/openssl/doc/life-cycles/README.md b/crypto/openssl/doc/life-cycles/README.md new file mode 100644 index 000000000000..e65c3d3435fc --- /dev/null +++ b/crypto/openssl/doc/life-cycles/README.md @@ -0,0 +1,20 @@ +Algorithm Life-Cycle Diagrams +============================= + +This directory contains the algorithm life-cycle diagram sources. + +The canonical life-cycles are in the spreadsheet. + +The various .dot files are graph descriptions for the +[GraphViz](https://www.graphviz.org/) tool. These omit edges and should +be used for guidance only. + +To generate the rendered images, you need to install the following packages: + + sudo apt install graphviz cpanminus + sudo cpanm Graph::Easy + +Running `make` will produce a number of `.txt` and `.png` files. +These are the rendered `.dot` files. The `.txt` files require +additional editing before they can be added to the manual pages in +`internal/man7/life_cycle-*.pod`. diff --git a/crypto/openssl/doc/life-cycles/cipher.dot b/crypto/openssl/doc/life-cycles/cipher.dot new file mode 100644 index 000000000000..c1d5b8346890 --- /dev/null +++ b/crypto/openssl/doc/life-cycles/cipher.dot @@ -0,0 +1,72 @@ +digraph cipher { + bgcolor="transparent"; + + begin [label=start, color="#deeaee", style="filled"]; + newed [fontcolor="#c94c4c", style="solid"]; + + initialised [fontcolor="#c94c4c"]; + updated [fontcolor="#c94c4c"]; + finaled [fontcolor="#c94c4c"]; + end [label="freed", color="#deeaee", style="filled"]; + + d_initialised [label="initialised\n(decryption)", fontcolor="#c94c4c"]; + d_updated [label="updated\n(decryption)", fontcolor="#c94c4c"]; + e_initialised [label="initialised\n(encryption)", fontcolor="#c94c4c"]; + e_updated [label="updated\n(encryption)", fontcolor="#c94c4c"]; + + begin -> newed [label="EVP_CIPHER_CTX_new"]; + newed -> initialised [label="EVP_CipherInit"]; + initialised -> initialised [label="EVP_CipherInit\n(not required but allowed)", + style=dashed]; + initialised -> updated [label="EVP_CipherUpdate", weight=2]; + updated -> updated [label="EVP_CipherUpdate"]; + updated -> finaled [label="EVP_CipherFinal"]; + finaled -> finaled [label="EVP_CIPHER_CTX_get_params\n(AEAD encryption)", + style=dashed]; + finaled -> end [label="EVP_CIPHER_CTX_free"]; + newed -> d_initialised [label="EVP_DecryptInit"]; + d_initialised -> d_initialised [label="EVP_DecryptInit\n(not required but allowed)", + style=dashed]; + d_initialised -> d_updated [label="EVP_DecryptUpdate", weight=2]; + d_updated -> d_updated [label="EVP_DecryptUpdate"]; + d_updated -> finaled [label="EVP_DecryptFinal"]; + newed -> e_initialised [label="EVP_EncryptInit"]; + e_initialised -> e_initialised [label="EVP_EncryptInit\n(not required but allowed)", + style=dashed]; + e_initialised -> e_updated [label="EVP_EncryptUpdate", weight=2]; + e_updated -> e_updated [label="EVP_EncryptUpdate"]; + e_updated -> finaled [label="EVP_EncryptFinal"]; + most -> newed [label="EVP_CIPHER_CTX_reset", style=dashed, + color="#034f84", fontcolor="#034f84"]; + most [label="any of the initialised\nupdated or finaled states", style=dashed, + color="#034f84", fontcolor="#034f84"]; +} + +/* This is a version with a single flavour which is easier to comprehend +digraph cipher { + bgcolor="transparent"; + + begin [label=start, color="#deeaee", style="filled"]; + newed [fontcolor="#c94c4c", style="solid"]; + initialised [fontcolor="#c94c4c"]; + updated [fontcolor="#c94c4c"]; + finaled [fontcolor="#c94c4c"]; + end [label="freed", color="#deeaee", style="filled"]; + + begin -> newed [label="EVP_CIPHER_CTX_new"]; + newed -> initialised [label="EVP_CipherInit"]; + initialised -> initialised [label="EVP_CipherInit\n(not required but allowed)", + style=dashed]; + initialised -> updated [label="EVP_CipherUpdate", weight=2]; + updated -> updated [label="EVP_CipherUpdate"]; + updated -> finaled [label="EVP_CipherFinal"]; + finaled -> finaled [label="EVP_CIPHER_CTX_get_params\n(AEAD encryption)", + style=dashed]; + finaled -> end [label="EVP_CIPHER_CTX_free"]; + finaled -> newed [label="EVP_CIPHER_CTX_reset", style=dashed, + color="#034f84", fontcolor="#034f84"]; + updated -> newed [label="EVP_CIPHER_CTX_reset", style=dashed, + color="#034f84", fontcolor="#034f84"]; +} +*/ + diff --git a/crypto/openssl/doc/life-cycles/digest.dot b/crypto/openssl/doc/life-cycles/digest.dot new file mode 100644 index 000000000000..8d4d72480c9a --- /dev/null +++ b/crypto/openssl/doc/life-cycles/digest.dot @@ -0,0 +1,33 @@ +digraph digest { + bgcolor="transparent"; + + begin [label=start, color="#deeaee", style="filled"]; + newed [label=newed, fontcolor="#c94c4c", style="solid"]; + initialised [label=initialised, fontcolor="#c94c4c"]; + updated [label=updated, fontcolor="#c94c4c"]; + finaled [label="finaled", fontcolor="#c94c4c"]; + end [label="freed", color="#deeaee", style="filled"]; + + begin -> newed [label="EVP_MD_CTX_new"]; + newed -> initialised [label="EVP_DigestInit"]; + initialised -> updated [label="EVP_DigestUpdate", weight=3]; + updated -> updated [label="EVP_DigestUpdate"]; + updated -> finaled [label="EVP_DigestFinal"]; + updated -> finaled [label="EVP_DigestFinalXOF", + fontcolor="#808080", color="#808080"]; + /* Once this works it should go back in: + finaled -> finaled [taillabel="EVP_DigestFinalXOF", + labeldistance=9, labelangle=345, + labelfontcolor="#808080", color="#808080"]; + */ + finaled -> end [label="EVP_MD_CTX_free"]; + finaled -> newed [label="EVP_MD_CTX_reset", style=dashed, weight=2, + color="#034f84", fontcolor="#034f84"]; + updated -> newed [label="EVP_MD_CTX_reset", style=dashed, + color="#034f84", fontcolor="#034f84"]; + updated -> initialised [label="EVP_DigestInit", weight=0, style=dashed, + color="#034f84", fontcolor="#034f84"]; + finaled -> initialised [label="EVP_DigestInit", style=dashed, + color="#034f84", fontcolor="#034f84"]; +} + diff --git a/crypto/openssl/doc/life-cycles/kdf.dot b/crypto/openssl/doc/life-cycles/kdf.dot new file mode 100644 index 000000000000..2dce34377db6 --- /dev/null +++ b/crypto/openssl/doc/life-cycles/kdf.dot @@ -0,0 +1,16 @@ +strict digraph kdf { + bgcolor="transparent"; + + begin [label=start, color="#deeaee", style="filled"]; + newed [label="newed", fontcolor="#c94c4c", style="solid"]; + deriving [label="deriving", fontcolor="#c94c4c"]; + end [label="freed", color="#deeaee", style="filled"]; + + begin -> newed [label="EVP_KDF_CTX_new"]; + newed -> deriving [label="EVP_KDF_derive"]; + deriving -> deriving [label="EVP_KDF_derive", style=dashed]; + deriving -> end [label="EVP_KDF_CTX_free"]; + deriving -> newed [label="EVP_KDF_CTX_reset", style=dashed, + color="#034f84", fontcolor="#034f84"]; +} + diff --git a/crypto/openssl/doc/life-cycles/lifecycles.ods b/crypto/openssl/doc/life-cycles/lifecycles.ods new file mode 100644 index 000000000000..6cc2030a9efa Binary files /dev/null and b/crypto/openssl/doc/life-cycles/lifecycles.ods differ diff --git a/crypto/openssl/doc/life-cycles/mac.dot b/crypto/openssl/doc/life-cycles/mac.dot new file mode 100644 index 000000000000..fe277f8328e6 --- /dev/null +++ b/crypto/openssl/doc/life-cycles/mac.dot @@ -0,0 +1,28 @@ +digraph mac { + bgcolor="transparent"; + + begin [label=start, color="#deeaee", style="filled"]; + newed [fontcolor="#c94c4c", style="solid"]; + initialised [fontcolor="#c94c4c"]; + updated [fontcolor="#c94c4c"]; + finaled [fontcolor="#c94c4c"]; + end [label=freed, color="#deeaee", style="filled"]; + + begin -> newed [label="EVP_MAC_CTX_new"]; + newed -> initialised [label="EVP_MAC_init"]; + initialised -> updated [label="EVP_MAC_update"]; + updated -> updated [label="EVP_MAC_update"]; + updated -> finaled [label="EVP_MAC_final"]; + updated -> finaled [label="EVP_MAC_finalXOF", + fontcolor="#808080", color="#808080"]; + /* Once this works it should go back in: + finaled -> finaled [label="EVP_MAC_final_XOF", + fontcolor="#808080", color="#808080"]; + */ + finaled -> end [label="EVP_MAC_CTX_free"]; + updated -> initialised [label="EVP_MAC_init", style=dashed, + color="#034f84", fontcolor="#034f84"]; + finaled -> initialised [label="EVP_MAC_init", style=dashed, + color="#034f84", fontcolor="#034f84"]; +} + diff --git a/crypto/openssl/doc/life-cycles/pkey.dot b/crypto/openssl/doc/life-cycles/pkey.dot new file mode 100644 index 000000000000..58b3a0c5bb77 --- /dev/null +++ b/crypto/openssl/doc/life-cycles/pkey.dot @@ -0,0 +1,49 @@ +strict digraph pkey { + bgcolor="transparent"; + layout=circo + + begin [label=start, color="#deeaee", style="filled"]; + newed [fontcolor="#c94c4c", style="solid"]; + digestsign [label="digest sign", fontcolor="#AB3910", color="#AB3910"] + verify [fontcolor="#F8CF2C", color="#F8CF2C"] + verifyrecover [label="verify recover", fontcolor="#B19FF9", color="#B19FF9"] + encrypt [fontcolor="#63AAC0", color="#63AAC0"] + decrypt [fontcolor="#425F06", color="#425F06"] + derive [fontcolor="#FEA303", color="#FEA303"] + encapsulate [fontcolor="#D95980", color="#D95980"] + decapsulate [fontcolor="#A16AE8", color="#A16AE8"] + paramgen [label="parameter\ngeneration", fontcolor="#2879C0", color="#2879C0"] + keygen [label="key\ngeneration", fontcolor="#2F7604", color="#2F7604"] + + begin -> newed [label="EVP_PKEY_CTX_new"]; + + newed -> digestsign [label="EVP_PKEY_sign_init", color="#AB3910", fontcolor="#AB3910"]; + digestsign -> digestsign [label="EVP_PKEY_sign", color="#AB3910", fontcolor="#AB3910"]; + + newed -> verify [label="EVP_PKEY_verify_init", fontcolor="#F8CF2C", color="#F8CF2C"]; + verify -> verify [label="EVP_PKEY_verify", fontcolor="#F8CF2C", color="#F8CF2C"]; + + newed -> verifyrecover [label="EVP_PKEY_verify_recover_init", fontcolor="#B19FF9", color="#B19FF9"]; + verifyrecover -> verifyrecover [label="EVP_PKEY_verify_recover", fontcolor="#B19FF9", color="#B19FF9"]; + + newed -> encrypt [label="EVP_PKEY_encrypt_init", fontcolor="#63AAC0", color="#63AAC0"]; + encrypt -> encrypt [label="EVP_PKEY_encrypt", fontcolor="#63AAC0", color="#63AAC0"]; + + newed -> decrypt [label="EVP_PKEY_decrypt_init", fontcolor="#425F06", color="#425F06"]; + decrypt -> decrypt [label="EVP_PKEY_decrypt", fontcolor="#425F06", color="#425F06"]; + + newed -> derive [label="EVP_PKEY_derive_init", fontcolor="#FEA303", color="#FEA303"]; + derive -> derive [label="EVP_PKEY_derive\nEVP_PKEY_derive_set_peer", fontcolor="#FEA303", color="#FEA303"]; + + newed -> encapsulate [label="EVP_PKEY_encapsulate_init", fontcolor="#D95980", color="#D95980"]; + encapsulate -> encapsulate [label="EVP_PKEY_encapsulate", fontcolor="#D95980", color="#D95980"]; + + newed -> decapsulate [label="EVP_PKEY_decapsulate_init", fontcolor="#A16AE8", color="#A16AE8"]; + decapsulate -> decapsulate [label="EVP_PKEY_decapsulate", fontcolor="#A16AE8", color="#A16AE8"]; + + newed -> paramgen [label="EVP_PKEY_paramgen_init", fontcolor="#2879C0", color="#2879C0"]; + paramgen -> paramgen [label="EVP_PKEY_paramgen\nEVP_PKEY_gen", fontcolor="#2879C0", color="#2879C0"]; + + newed -> keygen [label="EVP_PKEY_keygen_init", fontcolor="#2F7604", color="#2F7604"]; + keygen -> keygen [label="EVP_PKEY_keygen\nEVP_PKEY_gen", fontcolor="#2F7604", color="#2F7604"]; +} diff --git a/crypto/openssl/doc/life-cycles/rand.dot b/crypto/openssl/doc/life-cycles/rand.dot new file mode 100644 index 000000000000..a57cf710c75d --- /dev/null +++ b/crypto/openssl/doc/life-cycles/rand.dot @@ -0,0 +1,17 @@ +strict digraph rand { + bgcolor="transparent"; + + begin [label=start, color="#deeaee", style="filled"]; + newed [fontcolor="#c94c4c", style="solid"]; + instantiated [fontcolor="#c94c4c"]; + uninstantiated [fontcolor="#c94c4c"]; + end [label="freed", color="#deeaee", style="filled"]; + + begin -> newed [label="EVP_RAND_CTX_new"]; + newed -> instantiated [label="EVP_RAND_instantiate"]; + instantiated -> instantiated [label="EVP_RAND_generate"]; + instantiated -> uninstantiated [label="EVP_RAND_uninstantiate"]; + uninstantiated -> end [label="EVP_RAND_CTX_free"]; + uninstantiated -> instantiated [label="EVP_RAND_instantiate", style=dashed, color="#034f84", fontcolor="#034f84"]; +} + diff --git a/crypto/openssl/doc/man1/CA.pl.pod b/crypto/openssl/doc/man1/CA.pl.pod index 4e8958e554dd..e05775cdca66 100644 --- a/crypto/openssl/doc/man1/CA.pl.pod +++ b/crypto/openssl/doc/man1/CA.pl.pod @@ -21,45 +21,62 @@ B<-signCA> | B<-signcert> | B<-crl> | B<-newca> -[B<-extra-cmd> extra-params] +[B<-extra-I> I] -B B<-pkcs12> [B<-extra-pkcs12> extra-params] [B] +B B<-pkcs12> [I] -B B<-verify> [B<-extra-verify> extra-params] B... +B B<-verify> I ... -B B<-revoke> [B<-extra-ca> extra-params] B [B] +B B<-revoke> I [I] =head1 DESCRIPTION The B script is a perl script that supplies the relevant command line -arguments to the B command for some common certificate operations. +arguments to the L command for some common certificate operations. It is intended to simplify the process of certificate creation and management by the use of some simple options. +The script is intended as a simple front end for the L program for +use by a beginner. Its behaviour isn't always what is wanted. For more control +over the behaviour of the certificate commands call the L command +directly. + +Most of the filenames mentioned below can be modified by editing the +B script. + +Under some environments it may not be possible to run the B script +directly (for example Win32) and the default configuration file location may +be wrong. In this case the command: + + perl -S CA.pl + +can be used and the B environment variable can be set to point to +the correct path of the configuration file. + =head1 OPTIONS =over 4 -=item B, B<-h>, B<-help> +=item B<-?>, B<-h>, B<-help> Prints a usage message. =item B<-newcert> Creates a new self signed certificate. The private key is written to the file -"newkey.pem" and the request written to the file "newreq.pem". -This argument invokes B command. +F and the request written to the file F. +Invokes L. =item B<-newreq> Creates a new certificate request. The private key is written to the file -"newkey.pem" and the request written to the file "newreq.pem". -Executes B command below the hood. +F and the request written to the file F. +Executes L under the hood. =item B<-newreq-nodes> Is like B<-newreq> except that the private key will not be encrypted. -Uses B command. +Uses L. =item B<-newca> @@ -67,68 +84,73 @@ Creates a new CA hierarchy for use with the B program (or the B<-signcert> and B<-xsign> options). The user is prompted to enter the filename of the CA certificates (which should also contain the private key) or by hitting ENTER details of the CA will be prompted for. The relevant files and directories -are created in a directory called "demoCA" in the current directory. -B and B commands are get invoked. +are created in a directory called F in the current directory. +Uses L and L. + +If the F directory already exists then the B<-newca> command will not +overwrite it and will do nothing. This can happen if a previous call using +the B<-newca> option terminated abnormally. To get the correct behaviour +delete the directory if it already exists. =item B<-pkcs12> Create a PKCS#12 file containing the user certificate, private key and CA certificate. It expects the user certificate and private key to be in the -file "newcert.pem" and the CA certificate to be in the file demoCA/cacert.pem, -it creates a file "newcert.p12". This command can thus be called after the +file F and the CA certificate to be in the file F, +it creates a file F. This command can thus be called after the B<-sign> option. The PKCS#12 file can be imported directly into a browser. If there is an additional argument on the command line it will be used as the "friendly name" for the certificate (which is typically displayed in the browser list box), otherwise the name "My Certificate" is used. -Delegates work to B command. +Delegates work to L. =item B<-sign>, B<-signcert>, B<-xsign> -Calls the B program to sign a certificate request. It expects the request -to be in the file "newreq.pem". The new certificate is written to the file -"newcert.pem" except in the case of the B<-xsign> option when it is written -to standard output. Leverages B command. +Calls the L command to sign a certificate request. It expects the +request to be in the file F. The new certificate is written to the +file F except in the case of the B<-xsign> option when it is +written to standard output. =item B<-signCA> This option is the same as the B<-sign> option except it uses the configuration file section B and so makes the signed request a valid CA certificate. This is useful when creating intermediate CA from -a root CA. Extra params are passed on to B command. +a root CA. Extra params are passed to L. =item B<-signcert> This option is the same as B<-sign> except it expects a self signed certificate -to be present in the file "newreq.pem". -Extra params are passed on to B and B commands. +to be present in the file F. +Extra params are passed to L and L. =item B<-crl> -Generate a CRL. Executes B command. +Generate a CRL. Executes L. -=item B<-revoke certfile [reason]> +=item B<-revoke> I [I] Revoke the certificate contained in the specified B. An optional reason may be specified, and must be one of: B, B, B, B, B, B, B, or B. -Leverages B command. +Leverages L. =item B<-verify> -Verifies certificates against the CA certificate for "demoCA". If no +Verifies certificates against the CA certificate for F. If no certificates are specified on the command line it tries to verify the file -"newcert.pem". Invokes B command. +F. Invokes L. -=item B<-extra-req> | B<-extra-ca> | B<-extra-pkcs12> | B<-extra-x509> | B<-extra-verify> +=item B<-extra-I> I -The purpose of these parameters is to allow optional parameters to be supplied -to B that this command executes. The B<-extra-cmd> are specific to the -option being used and the B command getting invoked. For example -when this command invokes B extra parameters can be passed on -with the B<-extra-req> parameter. The -B commands being invoked per option are documented below. -Users should consult B command documentation for more information. +For each option B>, pass I to the L +sub-command with the same name as I, if that sub-command is invoked. +For example, if L is invoked, the I given with +B<-extra-req> will be passed to it. +For multi-word parameters, either repeat the option or quote the I +so it looks like one word to your shell. +See the individual command documentation for more information. =back @@ -146,67 +168,30 @@ the request and finally create a PKCS#12 file containing it. CA.pl -sign CA.pl -pkcs12 "My Test Certificate" -=head1 DSA CERTIFICATES - -Although the B creates RSA CAs and requests it is still possible to -use it with DSA certificates and requests using the L command -directly. The following example shows the steps that would typically be taken. - -Create some DSA parameters: +=head1 ENVIRONMENT - openssl dsaparam -out dsap.pem 1024 - -Create a DSA CA certificate and private key: - - openssl req -x509 -newkey dsa:dsap.pem -keyout cacert.pem -out cacert.pem - -Create the CA directories and files: - - CA.pl -newca - -enter cacert.pem when prompted for the CA filename. - -Create a DSA certificate request and private key (a different set of parameters -can optionally be created first): - - openssl req -out newreq.pem -newkey dsa:dsap.pem - -Sign the request: - - CA.pl -sign - -=head1 NOTES - -Most of the filenames mentioned can be modified by editing the B script. - -If the demoCA directory already exists then the B<-newca> command will not -overwrite it and will do nothing. This can happen if a previous call using -the B<-newca> option terminated abnormally. To get the correct behaviour -delete the demoCA directory if it already exists. - -Under some environments it may not be possible to run the B script -directly (for example Win32) and the default configuration file location may -be wrong. In this case the command: - - perl -S CA.pl - -can be used and the B environment variable changed to point to -the correct path of the configuration file. +The environment variable B may be used to specify the name of +the OpenSSL program. It can be a full pathname, or a relative one. -The script is intended as a simple front end for the B program for use -by a beginner. Its behaviour isn't always what is wanted. For more control over the -behaviour of the certificate commands call the B command directly. +The environment variable B may be used to specify a +configuration option and value to the B and B commands invoked by +this script. It's value should be the option and pathname, as in +C<-config /path/to/conf-file>. =head1 SEE ALSO -L, L, L, L, +L, +L, +L, +L, +L, L =head1 COPYRIGHT -Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. -Licensed under the OpenSSL license (the "License"). You may not use +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. diff --git a/crypto/openssl/doc/man1/build.info b/crypto/openssl/doc/man1/build.info new file mode 100644 index 000000000000..b796fce42fdd --- /dev/null +++ b/crypto/openssl/doc/man1/build.info @@ -0,0 +1,57 @@ +# All .pod.in files are detected by build.info in the parent directory, and +# turned into appropriate DEPEND and GENERATE lines. All we need here are +# the additional dependencies on ../perlvars.pm. + +DEPEND[openssl-asn1parse.pod]=../perlvars.pm +DEPEND[openssl-ca.pod]=../perlvars.pm +DEPEND[openssl-ciphers.pod]=../perlvars.pm +DEPEND[openssl-cmds.pod]=../perlvars.pm +DEPEND[openssl-cmp.pod]=../perlvars.pm +DEPEND[openssl-cms.pod]=../perlvars.pm +DEPEND[openssl-crl2pkcs7.pod]=../perlvars.pm +DEPEND[openssl-crl.pod]=../perlvars.pm +DEPEND[openssl-dgst.pod]=../perlvars.pm +DEPEND[openssl-dhparam.pod]=../perlvars.pm +DEPEND[openssl-dsaparam.pod]=../perlvars.pm +DEPEND[openssl-dsa.pod]=../perlvars.pm +DEPEND[openssl-ecparam.pod]=../perlvars.pm +DEPEND[openssl-ec.pod]=../perlvars.pm +DEPEND[openssl-enc.pod]=../perlvars.pm +DEPEND[openssl-engine.pod]=../perlvars.pm +DEPEND[openssl-errstr.pod]=../perlvars.pm +DEPEND[openssl-fipsinstall.pod]=../perlvars.pm +DEPEND[openssl-gendsa.pod]=../perlvars.pm +DEPEND[openssl-genpkey.pod]=../perlvars.pm +DEPEND[openssl-genrsa.pod]=../perlvars.pm +DEPEND[openssl-info.pod]=../perlvars.pm +DEPEND[openssl-kdf.pod]=../perlvars.pm +DEPEND[openssl-list.pod]=../perlvars.pm +DEPEND[openssl-mac.pod]=../perlvars.pm +DEPEND[openssl-nseq.pod]=../perlvars.pm +DEPEND[openssl-ocsp.pod]=../perlvars.pm +DEPEND[openssl-passwd.pod]=../perlvars.pm +DEPEND[openssl-pkcs12.pod]=../perlvars.pm +DEPEND[openssl-pkcs7.pod]=../perlvars.pm +DEPEND[openssl-pkcs8.pod]=../perlvars.pm +DEPEND[openssl-pkeyparam.pod]=../perlvars.pm +DEPEND[openssl-pkey.pod]=../perlvars.pm +DEPEND[openssl-pkeyutl.pod]=../perlvars.pm +DEPEND[openssl-prime.pod]=../perlvars.pm +DEPEND[openssl-rand.pod]=../perlvars.pm +DEPEND[openssl-rehash.pod]=../perlvars.pm +DEPEND[openssl-req.pod]=../perlvars.pm +DEPEND[openssl-rsa.pod]=../perlvars.pm +DEPEND[openssl-rsautl.pod]=../perlvars.pm +DEPEND[openssl-s_client.pod]=../perlvars.pm +DEPEND[openssl-sess_id.pod]=../perlvars.pm +DEPEND[openssl-smime.pod]=../perlvars.pm +DEPEND[openssl-speed.pod]=../perlvars.pm +DEPEND[openssl-spkac.pod]=../perlvars.pm +DEPEND[openssl-srp.pod]=../perlvars.pm +DEPEND[openssl-s_server.pod]=../perlvars.pm +DEPEND[openssl-s_time.pod]=../perlvars.pm +DEPEND[openssl-storeutl.pod]=../perlvars.pm +DEPEND[openssl-ts.pod]=../perlvars.pm +DEPEND[openssl-verify.pod]=../perlvars.pm +DEPEND[openssl-version.pod]=../perlvars.pm +DEPEND[openssl-x509.pod]=../perlvars.pm diff --git a/crypto/openssl/doc/man1/crl.pod b/crypto/openssl/doc/man1/crl.pod deleted file mode 100644 index 58f2bf62ddf3..000000000000 --- a/crypto/openssl/doc/man1/crl.pod +++ /dev/null @@ -1,143 +0,0 @@ -=pod - -=head1 NAME - -openssl-crl, -crl - CRL utility - -=head1 SYNOPSIS - -B B -[B<-help>] -[B<-inform PEM|DER>] -[B<-outform PEM|DER>] -[B<-text>] -[B<-in filename>] -[B<-out filename>] -[B<-nameopt option>] -[B<-noout>] -[B<-hash>] -[B<-issuer>] -[B<-lastupdate>] -[B<-nextupdate>] -[B<-CAfile file>] -[B<-CApath dir>] - -=head1 DESCRIPTION - -The B command processes CRL files in DER or PEM format. - -=head1 OPTIONS - -=over 4 - -=item B<-help> - -Print out a usage message. - -=item B<-inform DER|PEM> - -This specifies the input format. B format is DER encoded CRL -structure. B (the default) is a base64 encoded version of -the DER form with header and footer lines. - -=item B<-outform DER|PEM> - -This specifies the output format, the options have the same meaning and default -as the B<-inform> option. - -=item B<-in filename> - -This specifies the input filename to read from or standard input if this -option is not specified. - -=item B<-out filename> - -Specifies the output filename to write to or standard output by -default. - -=item B<-text> - -Print out the CRL in text form. - -=item B<-nameopt option> - -Option which determines how the subject or issuer names are displayed. See -the description of B<-nameopt> in L. - -=item B<-noout> - -Don't output the encoded version of the CRL. - -=item B<-hash> - -Output a hash of the issuer name. This can be use to lookup CRLs in -a directory by issuer name. - -=item B<-hash_old> - -Outputs the "hash" of the CRL issuer name using the older algorithm -as used by OpenSSL before version 1.0.0. - -=item B<-issuer> - -Output the issuer name. - -=item B<-lastupdate> - -Output the lastUpdate field. - -=item B<-nextupdate> - -Output the nextUpdate field. - -=item B<-CAfile file> - -Verify the signature on a CRL by looking up the issuing certificate in -B. - -=item B<-CApath dir> - -Verify the signature on a CRL by looking up the issuing certificate in -B. This directory must be a standard certificate directory: that -is a hash of each subject name (using B) should be linked -to each certificate. - -=back - -=head1 NOTES - -The PEM CRL format uses the header and footer lines: - - -----BEGIN X509 CRL----- - -----END X509 CRL----- - -=head1 EXAMPLES - -Convert a CRL file from PEM to DER: - - openssl crl -in crl.pem -outform DER -out crl.der - -Output the text form of a DER encoded certificate: - - openssl crl -in crl.der -inform DER -text -noout - -=head1 BUGS - -Ideally it should be possible to create a CRL using appropriate options -and files too. - -=head1 SEE ALSO - -L, L, L - -=head1 COPYRIGHT - -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the OpenSSL license (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/crypto/openssl/doc/man1/dgst.pod b/crypto/openssl/doc/man1/dgst.pod deleted file mode 100644 index 8d48c9aed6d6..000000000000 --- a/crypto/openssl/doc/man1/dgst.pod +++ /dev/null @@ -1,251 +0,0 @@ -=pod - -=head1 NAME - -openssl-dgst, -dgst - perform digest operations - -=head1 SYNOPSIS - -B -[B<-I>] -[B<-help>] -[B<-c>] -[B<-d>] -[B<-list>] -[B<-hex>] -[B<-binary>] -[B<-r>] -[B<-out filename>] -[B<-sign filename>] -[B<-keyform arg>] -[B<-passin arg>] -[B<-verify filename>] -[B<-prverify filename>] -[B<-signature filename>] -[B<-sigopt nm:v>] -[B<-hmac key>] -[B<-fips-fingerprint>] -[B<-rand file...>] -[B<-engine id>] -[B<-engine_impl>] -[B] - -B I [B<...>] - -=head1 DESCRIPTION - -The digest functions output the message digest of a supplied file or files -in hexadecimal. The digest functions also generate and verify digital -signatures using message digests. - -The generic name, B, may be used with an option specifying the -algorithm to be used. -The default digest is I. -A supported I name may also be used as the command name. -To see the list of supported algorithms, use the I -command. - -=head1 OPTIONS - -=over 4 - -=item B<-help> - -Print out a usage message. - -=item B<-I> - -Specifies name of a supported digest to be used. To see the list of -supported digests, use the command I. - -=item B<-c> - -Print out the digest in two digit groups separated by colons, only relevant if -B format output is used. - -=item B<-d> - -Print out BIO debugging information. - -=item B<-list> - -Prints out a list of supported message digests. - -=item B<-hex> - -Digest is to be output as a hex dump. This is the default case for a "normal" -digest as opposed to a digital signature. See NOTES below for digital -signatures using B<-hex>. - -=item B<-binary> - -Output the digest or signature in binary form. - -=item B<-r> - -Output the digest in the "coreutils" format, including newlines. -Used by programs like B. - -=item B<-out filename> - -Filename to output to, or standard output by default. - -=item B<-sign filename> - -Digitally sign the digest using the private key in "filename". Note this option -does not support Ed25519 or Ed448 private keys. - -=item B<-keyform arg> - -Specifies the key format to sign digest with. The DER, PEM, P12, -and ENGINE formats are supported. - -=item B<-sigopt nm:v> - -Pass options to the signature algorithm during sign or verify operations. -Names and values of these options are algorithm-specific. - -=item B<-passin arg> - -The private key password source. For more information about the format of B -see L. - -=item B<-verify filename> - -Verify the signature using the public key in "filename". -The output is either "Verification OK" or "Verification Failure". - -=item B<-prverify filename> - -Verify the signature using the private key in "filename". - -=item B<-signature filename> - -The actual signature to verify. - -=item B<-hmac key> - -Create a hashed MAC using "key". - -=item B<-mac alg> - -Create MAC (keyed Message Authentication Code). The most popular MAC -algorithm is HMAC (hash-based MAC), but there are other MAC algorithms -which are not based on hash, for instance B algorithm, -supported by B engine. MAC keys and other options should be set -via B<-macopt> parameter. - -=item B<-macopt nm:v> - -Passes options to MAC algorithm, specified by B<-mac> key. -Following options are supported by both by B and B: - -=over 4 - -=item B - -Specifies MAC key as alphanumeric string (use if key contain printable -characters only). String length must conform to any restrictions of -the MAC algorithm for example exactly 32 chars for gost-mac. - -=item B - -Specifies MAC key in hexadecimal form (two hex digits per byte). -Key length must conform to any restrictions of the MAC algorithm -for example exactly 32 chars for gost-mac. - -=back - -=item B<-rand file...> - -A file or files containing random data used to seed the random number -generator. -Multiple files can be specified separated by an OS-dependent character. -The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for -all others. - -=item [B<-writerand file>] - -Writes random data to the specified I upon exit. -This can be used with a subsequent B<-rand> flag. - -=item B<-fips-fingerprint> - -Compute HMAC using a specific key for certain OpenSSL-FIPS operations. - -=item B<-engine id> - -Use engine B for operations (including private key storage). -This engine is not used as source for digest algorithms, unless it is -also specified in the configuration file or B<-engine_impl> is also -specified. - -=item B<-engine_impl> - -When used with the B<-engine> option, it specifies to also use -engine B for digest operations. - -=item B - -File or files to digest. If no files are specified then standard input is -used. - -=back - - -=head1 EXAMPLES - -To create a hex-encoded message digest of a file: - openssl dgst -md5 -hex file.txt - -To sign a file using SHA-256 with binary file output: - openssl dgst -sha256 -sign privatekey.pem -out signature.sign file.txt - -To verify a signature: - openssl dgst -sha256 -verify publickey.pem \ - -signature signature.sign \ - file.txt - - -=head1 NOTES - -The digest mechanisms that are available will depend on the options -used when building OpenSSL. -The B command can be used to list them. - -New or agile applications should use probably use SHA-256. Other digests, -particularly SHA-1 and MD5, are still widely used for interoperating -with existing formats and protocols. - -When signing a file, B will automatically determine the algorithm -(RSA, ECC, etc) to use for signing based on the private key's ASN.1 info. -When verifying signatures, it only handles the RSA, DSA, or ECDSA signature -itself, not the related data to identify the signer and algorithm used in -formats such as x.509, CMS, and S/MIME. - -A source of random numbers is required for certain signing algorithms, in -particular ECDSA and DSA. - -The signing and verify options should only be used if a single file is -being signed or verified. - -Hex signatures cannot be verified using B. Instead, use "xxd -r" -or similar program to transform the hex signature into a binary signature -prior to verification. - -=head1 HISTORY - -The default digest was changed from MD5 to SHA256 in OpenSSL 1.1.0. -The FIPS-related options were removed in OpenSSL 1.1.0. - -=head1 COPYRIGHT - -Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the OpenSSL license (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/crypto/openssl/doc/man1/dhparam.pod b/crypto/openssl/doc/man1/dhparam.pod deleted file mode 100644 index 1b43b3231083..000000000000 --- a/crypto/openssl/doc/man1/dhparam.pod +++ /dev/null @@ -1,166 +0,0 @@ -=pod - -=head1 NAME - -openssl-dhparam, -dhparam - DH parameter manipulation and generation - -=head1 SYNOPSIS - -B -[B<-help>] -[B<-inform DER|PEM>] -[B<-outform DER|PEM>] -[B<-in> I] -[B<-out> I] -[B<-dsaparam>] -[B<-check>] -[B<-noout>] -[B<-text>] -[B<-C>] -[B<-2>] -[B<-5>] -[B<-rand file...>] -[B<-writerand file>] -[B<-engine id>] -[I] - -=head1 DESCRIPTION - -This command is used to manipulate DH parameter files. - -=head1 OPTIONS - -=over 4 - -=item B<-help> - -Print out a usage message. - -=item B<-inform DER|PEM> - -This specifies the input format. The B option uses an ASN1 DER encoded -form compatible with the PKCS#3 DHparameter structure. The PEM form is the -default format: it consists of the B format base64 encoded with -additional header and footer lines. - -=item B<-outform DER|PEM> - -This specifies the output format, the options have the same meaning and default -as the B<-inform> option. - -=item B<-in> I - -This specifies the input filename to read parameters from or standard input if -this option is not specified. - -=item B<-out> I - -This specifies the output filename parameters to. Standard output is used -if this option is not present. The output filename should B be the same -as the input filename. - -=item B<-dsaparam> - -If this option is used, DSA rather than DH parameters are read or created; -they are converted to DH format. Otherwise, "strong" primes (such -that (p-1)/2 is also prime) will be used for DH parameter generation. - -DH parameter generation with the B<-dsaparam> option is much faster, -and the recommended exponent length is shorter, which makes DH key -exchange more efficient. Beware that with such DSA-style DH -parameters, a fresh DH key should be created for each use to -avoid small-subgroup attacks that may be possible otherwise. - -=item B<-check> - -Performs numerous checks to see if the supplied parameters are valid and -displays a warning if not. - -=item B<-2>, B<-5> - -The generator to use, either 2 or 5. If present then the -input file is ignored and parameters are generated instead. If not -present but B is present, parameters are generated with the -default generator 2. - -=item B<-rand file...> - -A file or files containing random data used to seed the random number -generator. -Multiple files can be specified separated by an OS-dependent character. -The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for -all others. - -=item [B<-writerand file>] - -Writes random data to the specified I upon exit. -This can be used with a subsequent B<-rand> flag. - -=item I - -This option specifies that a parameter set should be generated of size -I. It must be the last option. If this option is present then -the input file is ignored and parameters are generated instead. If -this option is not present but a generator (B<-2> or B<-5>) is -present, parameters are generated with a default length of 2048 bits. - -=item B<-noout> - -This option inhibits the output of the encoded version of the parameters. - -=item B<-text> - -This option prints out the DH parameters in human readable form. - -=item B<-C> - -This option converts the parameters into C code. The parameters can then -be loaded by calling the get_dhNNNN() function. - -=item B<-engine id> - -Specifying an engine (by its unique B string) will cause B -to attempt to obtain a functional reference to the specified engine, -thus initialising it if needed. The engine will then be set as the default -for all available algorithms. - -=back - -=head1 WARNINGS - -The program B combines the functionality of the programs B and -B in previous versions of OpenSSL. The B and B -programs are retained for now but may have different purposes in future -versions of OpenSSL. - -=head1 NOTES - -PEM format DH parameters use the header and footer lines: - - -----BEGIN DH PARAMETERS----- - -----END DH PARAMETERS----- - -OpenSSL currently only supports the older PKCS#3 DH, not the newer X9.42 -DH. - -This program manipulates DH parameters not keys. - -=head1 BUGS - -There should be a way to generate and manipulate DH keys. - -=head1 SEE ALSO - -L - -=head1 COPYRIGHT - -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the OpenSSL license (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/crypto/openssl/doc/man1/dsaparam.pod b/crypto/openssl/doc/man1/dsaparam.pod deleted file mode 100644 index 94ea435cceb8..000000000000 --- a/crypto/openssl/doc/man1/dsaparam.pod +++ /dev/null @@ -1,131 +0,0 @@ -=pod - -=head1 NAME - -openssl-dsaparam, -dsaparam - DSA parameter manipulation and generation - -=head1 SYNOPSIS - -B -[B<-help>] -[B<-inform DER|PEM>] -[B<-outform DER|PEM>] -[B<-in filename>] -[B<-out filename>] -[B<-noout>] -[B<-text>] -[B<-C>] -[B<-rand file...>] -[B<-writerand file>] -[B<-genkey>] -[B<-engine id>] -[B] - -=head1 DESCRIPTION - -This command is used to manipulate or generate DSA parameter files. - -=head1 OPTIONS - -=over 4 - -=item B<-help> - -Print out a usage message. - -=item B<-inform DER|PEM> - -This specifies the input format. The B option uses an ASN1 DER encoded -form compatible with RFC2459 (PKIX) DSS-Parms that is a SEQUENCE consisting -of p, q and g respectively. The PEM form is the default format: it consists -of the B format base64 encoded with additional header and footer lines. - -=item B<-outform DER|PEM> - -This specifies the output format, the options have the same meaning and default -as the B<-inform> option. - -=item B<-in filename> - -This specifies the input filename to read parameters from or standard input if -this option is not specified. If the B parameter is included then -this option will be ignored. - -=item B<-out filename> - -This specifies the output filename parameters to. Standard output is used -if this option is not present. The output filename should B be the same -as the input filename. - -=item B<-noout> - -This option inhibits the output of the encoded version of the parameters. - -=item B<-text> - -This option prints out the DSA parameters in human readable form. - -=item B<-C> - -This option converts the parameters into C code. The parameters can then -be loaded by calling the get_dsaXXX() function. - -=item B<-genkey> - -This option will generate a DSA either using the specified or generated -parameters. - -=item B<-rand file...> - -A file or files containing random data used to seed the random number -generator. -Multiple files can be specified separated by an OS-dependent character. -The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for -all others. - -=item [B<-writerand file>] - -Writes random data to the specified I upon exit. -This can be used with a subsequent B<-rand> flag. - -=item B - -This option specifies that a parameter set should be generated of size -B. It must be the last option. If this option is included then -the input file (if any) is ignored. - -=item B<-engine id> - -Specifying an engine (by its unique B string) will cause B -to attempt to obtain a functional reference to the specified engine, -thus initialising it if needed. The engine will then be set as the default -for all available algorithms. - -=back - -=head1 NOTES - -PEM format DSA parameters use the header and footer lines: - - -----BEGIN DSA PARAMETERS----- - -----END DSA PARAMETERS----- - -DSA parameter generation is a slow process and as a result the same set of -DSA parameters is often used to generate several distinct keys. - -=head1 SEE ALSO - -L, L, L, -L - -=head1 COPYRIGHT - -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the OpenSSL license (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/crypto/openssl/doc/man1/errstr.pod b/crypto/openssl/doc/man1/errstr.pod deleted file mode 100644 index 94198c123ea6..000000000000 --- a/crypto/openssl/doc/man1/errstr.pod +++ /dev/null @@ -1,46 +0,0 @@ -=pod - -=head1 NAME - -openssl-errstr, -errstr - lookup error codes - -=head1 SYNOPSIS - -B - -=head1 DESCRIPTION - -Sometimes an application will not load error message and only -numerical forms will be available. The B utility can be used to -display the meaning of the hex code. The hex code is the hex digits after the -second colon. - -=head1 OPTIONS - -None. - -=head1 EXAMPLES - -The error code: - - 27594:error:2006D080:lib(32):func(109):reason(128):bss_file.c:107: - -can be displayed with: - - openssl errstr 2006D080 - -to produce the error message: - - error:2006D080:BIO routines:BIO_new_file:no such file - -=head1 COPYRIGHT - -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 -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/crypto/openssl/doc/man1/gendsa.pod b/crypto/openssl/doc/man1/gendsa.pod deleted file mode 100644 index b2580b4f0378..000000000000 --- a/crypto/openssl/doc/man1/gendsa.pod +++ /dev/null @@ -1,101 +0,0 @@ -=pod - -=head1 NAME - -openssl-gendsa, -gendsa - generate a DSA private key from a set of parameters - -=head1 SYNOPSIS - -B B -[B<-help>] -[B<-out filename>] -[B<-aes128>] -[B<-aes192>] -[B<-aes256>] -[B<-aria128>] -[B<-aria192>] -[B<-aria256>] -[B<-camellia128>] -[B<-camellia192>] -[B<-camellia256>] -[B<-des>] -[B<-des3>] -[B<-idea>] -[B<-rand file...>] -[B<-writerand file>] -[B<-engine id>] -[B] - -=head1 DESCRIPTION - -The B command generates a DSA private key from a DSA parameter file -(which will be typically generated by the B command). - -=head1 OPTIONS - -=over 4 - -=item B<-help> - -Print out a usage message. - -=item B<-out filename> - -Output the key to the specified file. If this argument is not specified then -standard output is used. - -=item B<-aes128>, B<-aes192>, B<-aes256>, B<-aria128>, B<-aria192>, B<-aria256>, B<-camellia128>, B<-camellia192>, B<-camellia256>, B<-des>, B<-des3>, B<-idea> - -These options encrypt the private key with specified -cipher before outputting it. A pass phrase is prompted for. -If none of these options is specified no encryption is used. - -=item B<-rand file...> - -A file or files containing random data used to seed the random number -generator. -Multiple files can be specified separated by an OS-dependent character. -The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for -all others. - -=item [B<-writerand file>] - -Writes random data to the specified I upon exit. -This can be used with a subsequent B<-rand> flag. - -=item B<-engine id> - -Specifying an engine (by its unique B string) will cause B -to attempt to obtain a functional reference to the specified engine, -thus initialising it if needed. The engine will then be set as the default -for all available algorithms. - -=item B - -This option specifies the DSA parameter file to use. The parameters in this -file determine the size of the private key. DSA parameters can be generated -and examined using the B command. - -=back - -=head1 NOTES - -DSA key generation is little more than random number generation so it is -much quicker that RSA key generation for example. - -=head1 SEE ALSO - -L, L, L, -L - -=head1 COPYRIGHT - -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the OpenSSL license (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/crypto/openssl/doc/man1/genpkey.pod b/crypto/openssl/doc/man1/genpkey.pod deleted file mode 100644 index 6a681ef3d219..000000000000 --- a/crypto/openssl/doc/man1/genpkey.pod +++ /dev/null @@ -1,335 +0,0 @@ -=pod - -=head1 NAME - -openssl-genpkey, -genpkey - generate a private key - -=head1 SYNOPSIS - -B B -[B<-help>] -[B<-out filename>] -[B<-outform PEM|DER>] -[B<-pass arg>] -[B<-I>] -[B<-engine id>] -[B<-paramfile file>] -[B<-algorithm alg>] -[B<-pkeyopt opt:value>] -[B<-genparam>] -[B<-text>] - -=head1 DESCRIPTION - -The B command generates a private key. - -=head1 OPTIONS - -=over 4 - -=item B<-help> - -Print out a usage message. - -=item B<-out filename> - -Output the key to the specified file. If this argument is not specified then -standard output is used. - -=item B<-outform DER|PEM> - -This specifies the output format DER or PEM. The default format is PEM. - -=item B<-pass arg> - -The output file password source. For more information about the format of B -see L. - -=item B<-I> - -This option encrypts the private key with the supplied cipher. Any algorithm -name accepted by EVP_get_cipherbyname() is acceptable such as B. - -=item B<-engine id> - -Specifying an engine (by its unique B string) will cause B -to attempt to obtain a functional reference to the specified engine, -thus initialising it if needed. The engine will then be set as the default -for all available algorithms. If used this option should precede all other -options. - -=item B<-algorithm alg> - -Public key algorithm to use such as RSA, DSA or DH. If used this option must -precede any B<-pkeyopt> options. The options B<-paramfile> and B<-algorithm> -are mutually exclusive. Engines may add algorithms in addition to the standard -built-in ones. - -Valid built-in algorithm names for private key generation are RSA, RSA-PSS, EC, -X25519, X448, ED25519 and ED448. - -Valid built-in algorithm names for parameter generation (see the B<-genparam> -option) are DH, DSA and EC. - -Note that the algorithm name X9.42 DH may be used as a synonym for the DH -algorithm. These are identical and do not indicate the type of parameters that -will be generated. Use the B option to indicate whether PKCS#3 -or X9.42 DH parameters are required. See L -below for more details. - -=item B<-pkeyopt opt:value> - -Set the public key algorithm option B to B. The precise set of -options supported depends on the public key algorithm used and its -implementation. See L and -L below for more details. - -=item B<-genparam> - -Generate a set of parameters instead of a private key. If used this option must -precede any B<-algorithm>, B<-paramfile> or B<-pkeyopt> options. - -=item B<-paramfile filename> - -Some public key algorithms generate a private key based on a set of parameters. -They can be supplied using this option. If this option is used the public key -algorithm used is determined by the parameters. If used this option must -precede any B<-pkeyopt> options. The options B<-paramfile> and B<-algorithm> -are mutually exclusive. - -=item B<-text> - -Print an (unencrypted) text representation of private and public keys and -parameters along with the PEM or DER structure. - -=back - -=head1 KEY GENERATION OPTIONS - -The options supported by each algorithm and indeed each implementation of an -algorithm can vary. The options for the OpenSSL implementations are detailed -below. There are no key generation options defined for the X25519, X448, ED25519 -or ED448 algorithms. - -=head2 RSA Key Generation Options - -=over 4 - -=item B - -The number of bits in the generated key. If not specified 2048 is used. - -=item B - -The number of primes in the generated key. If not specified 2 is used. - -=item B - -The RSA public exponent value. This can be a large decimal or -hexadecimal value if preceded by B<0x>. Default value is 65537. - -=back - -=head2 RSA-PSS Key Generation Options - -Note: by default an B key has no parameter restrictions. - -=over 4 - -=item B, B, B - -These options have the same meaning as the B algorithm. - -=item B - -If set the key is restricted and can only use B for signing. - -=item B - -If set the key is restricted and can only use B as it's MGF1 -parameter. - -=item B - -If set the key is restricted and B specifies the minimum salt length. - -=back - -=head2 EC Key Generation Options - -The EC key generation options can also be used for parameter generation. - -=over 4 - -=item B - -The EC curve to use. OpenSSL supports NIST curve names such as "P-256". - -=item B - -The encoding to use for parameters. The "encoding" parameter must be either -"named_curve" or "explicit". The default value is "named_curve". - -=back - -=head1 PARAMETER GENERATION OPTIONS - -The options supported by each algorithm and indeed each implementation of an -algorithm can vary. The options for the OpenSSL implementations are detailed -below. - -=head2 DSA Parameter Generation Options - -=over 4 - -=item B - -The number of bits in the generated prime. If not specified 2048 is used. - -=item B - -The number of bits in the q parameter. Must be one of 160, 224 or 256. If not -specified 224 is used. - -=item B - -The digest to use during parameter generation. Must be one of B, B -or B. If set, then the number of bits in B will match the output size -of the specified digest and the B parameter will be -ignored. If not set, then a digest will be used that gives an output matching -the number of bits in B, i.e. B if q length is 160, B if it 224 -or B if it is 256. - -=back - -=head2 DH Parameter Generation Options - -=over 4 - -=item B - -The number of bits in the prime parameter B

. The default is 2048. - -=item B - -The number of bits in the sub prime parameter B. The default is 256 if the -prime is at least 2048 bits long or 160 otherwise. Only relevant if used in -conjunction with the B option to generate X9.42 DH parameters. - -=item B - -The value to use for the generator B. The default is 2. - -=item B - -The type of DH parameters to generate. Use 0 for PKCS#3 DH and 1 for X9.42 DH. -The default is 0. - -=item B - -If this option is set, then the appropriate RFC5114 parameters are used -instead of generating new parameters. The value B can take the -values 1, 2 or 3 corresponding to RFC5114 DH parameters consisting of -1024 bit group with 160 bit subgroup, 2048 bit group with 224 bit subgroup -and 2048 bit group with 256 bit subgroup as mentioned in RFC5114 sections -2.1, 2.2 and 2.3 respectively. If present this overrides all other DH parameter -options. - -=back - -=head2 EC Parameter Generation Options - -The EC parameter generation options are the same as for key generation. See -L above. - -=head1 NOTES - -The use of the genpkey program is encouraged over the algorithm specific -utilities because additional algorithm options and ENGINE provided algorithms -can be used. - -=head1 EXAMPLES - -Generate an RSA private key using default parameters: - - openssl genpkey -algorithm RSA -out key.pem - -Encrypt output private key using 128 bit AES and the passphrase "hello": - - openssl genpkey -algorithm RSA -out key.pem -aes-128-cbc -pass pass:hello - -Generate a 2048 bit RSA key using 3 as the public exponent: - - openssl genpkey -algorithm RSA -out key.pem \ - -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:3 - -Generate 2048 bit DSA parameters: - - openssl genpkey -genparam -algorithm DSA -out dsap.pem \ - -pkeyopt dsa_paramgen_bits:2048 - -Generate DSA key from parameters: - - openssl genpkey -paramfile dsap.pem -out dsakey.pem - -Generate 2048 bit DH parameters: - - openssl genpkey -genparam -algorithm DH -out dhp.pem \ - -pkeyopt dh_paramgen_prime_len:2048 - -Generate 2048 bit X9.42 DH parameters: - - openssl genpkey -genparam -algorithm DH -out dhpx.pem \ - -pkeyopt dh_paramgen_prime_len:2048 \ - -pkeyopt dh_paramgen_type:1 - -Output RFC5114 2048 bit DH parameters with 224 bit subgroup: - - openssl genpkey -genparam -algorithm DH -out dhp.pem -pkeyopt dh_rfc5114:2 - -Generate DH key from parameters: - - openssl genpkey -paramfile dhp.pem -out dhkey.pem - -Generate EC parameters: - - openssl genpkey -genparam -algorithm EC -out ecp.pem \ - -pkeyopt ec_paramgen_curve:secp384r1 \ - -pkeyopt ec_param_enc:named_curve - -Generate EC key from parameters: - - openssl genpkey -paramfile ecp.pem -out eckey.pem - -Generate EC key directly: - - openssl genpkey -algorithm EC -out eckey.pem \ - -pkeyopt ec_paramgen_curve:P-384 \ - -pkeyopt ec_param_enc:named_curve - -Generate an X25519 private key: - - openssl genpkey -algorithm X25519 -out xkey.pem - -Generate an ED448 private key: - - openssl genpkey -algorithm ED448 -out xkey.pem - -=head1 HISTORY - -The ability to use NIST curve names, and to generate an EC key directly, -were added in OpenSSL 1.0.2. -The ability to generate X25519 keys was added in OpenSSL 1.1.0. -The ability to generate X448, ED25519 and ED448 keys was added in OpenSSL 1.1.1. - -=head1 COPYRIGHT - -Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the OpenSSL license (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/crypto/openssl/doc/man1/list.pod b/crypto/openssl/doc/man1/list.pod deleted file mode 100644 index bed39b0c7c93..000000000000 --- a/crypto/openssl/doc/man1/list.pod +++ /dev/null @@ -1,94 +0,0 @@ -=pod - -=head1 NAME - -openssl-list, -list - list algorithms and features - -=head1 SYNOPSIS - -B -[B<-help>] -[B<-1>] -[B<-commands>] -[B<-digest-commands>] -[B<-digest-algorithms>] -[B<-cipher-commands>] -[B<-cipher-algorithms>] -[B<-public-key-algorithms>] -[B<-public-key-methods>] -[B<-disabled>] - -=head1 DESCRIPTION - -This command is used to generate list of algorithms or disabled -features. - -=head1 OPTIONS - -=over 4 - -=item B<-help> - -Display a usage message. - -=item B<-1> - -List the commands, digest-commands, or cipher-commands in a single column. -If used, this option must be given first. - -=item B<-commands> - -Display a list of standard commands. - -=item B<-digest-commands> - -Display a list of message digest commands, which are typically used -as input to the L or L commands. - -=item B<-digest-algorithms> - -Display a list of message digest algorithms. -If a line is of the form - foo => bar -then B is an alias for the official algorithm name, B. - -=item B<-cipher-commands> - -Display a list of cipher commands, which are typically used as input -to the L or L commands. - -=item B<-cipher-algorithms> - -Display a list of cipher algorithms. -If a line is of the form - foo => bar -then B is an alias for the official algorithm name, B. - -=item B<-public-key-algorithms> - -Display a list of public key algorithms, with each algorithm as -a block of multiple lines, all but the first are indented. - -=item B<-public-key-methods> - -Display a list of public key method OIDs: this also includes public key methods -without an associated ASN.1 method, for example, KDF algorithms. - -=item B<-disabled> - -Display a list of disabled features, those that were compiled out -of the installation. - -=back - -=head1 COPYRIGHT - -Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the OpenSSL license (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/crypto/openssl/doc/man1/openssl-asn1parse.pod b/crypto/openssl/doc/man1/openssl-asn1parse.pod new file mode 100644 index 000000000000..0adc1fd7b99e --- /dev/null +++ b/crypto/openssl/doc/man1/openssl-asn1parse.pod @@ -0,0 +1,226 @@ +=pod + +=begin comment + +WARNING: do not edit! +Generated by Makefile from doc/man1/openssl-asn1parse.pod.in + +=end comment + +=head1 NAME + +openssl-asn1parse - ASN.1 parsing command + +=head1 SYNOPSIS + +B B +[B<-help>] +[B<-inform> B|B] +[B<-in> I] +[B<-out> I] +[B<-noout>] +[B<-offset> I] +[B<-length> I] +[B<-i>] +[B<-oid> I] +[B<-dump>] +[B<-dlimit> I] +[B<-strparse> I] +[B<-genstr> I] +[B<-genconf> I] +[B<-strictpem>] +[B<-item> I] + +=head1 DESCRIPTION + +This command is a diagnostic utility that can parse ASN.1 structures. +It can also be used to extract data from ASN.1 formatted data. + +=head1 OPTIONS + +=over 4 + +=item B<-help> + +Print out a usage message. + +=item B<-inform> B|B + +The input format; the default is B. +See L for details. + +=item B<-in> I + +The input file, default is standard input. + +=item B<-out> I + +Output file to place the DER encoded data into. If this +option is not present then no data will be output. This is most useful when +combined with the B<-strparse> option. + +=item B<-noout> + +Don't output the parsed version of the input file. + +=item B<-offset> I + +Starting offset to begin parsing, default is start of file. + +=item B<-length> I + +Number of bytes to parse, default is until end of file. + +=item B<-i> + +Indents the output according to the "depth" of the structures. + +=item B<-oid> I + +A file containing additional OBJECT IDENTIFIERs (OIDs). The format of this +file is described in the NOTES section below. + +=item B<-dump> + +Dump unknown data in hex format. + +=item B<-dlimit> I + +Like B<-dump>, but only the first B bytes are output. + +=item B<-strparse> I + +Parse the contents octets of the ASN.1 object starting at B. This +option can be used multiple times to "drill down" into a nested structure. + +=item B<-genstr> I, B<-genconf> I + +Generate encoded data based on I, I or both using +L format. If I only is +present then the string is obtained from the default section using the name +B. The encoded data is passed through the ASN1 parser and printed out as +though it came from a file, the contents can thus be examined and written to a +file using the B<-out> option. + +=item B<-strictpem> + +If this option is used then B<-inform> will be ignored. Without this option any +data in a PEM format input file will be treated as being base64 encoded and +processed whether it has the normal PEM BEGIN and END markers or not. This +option will ignore any data prior to the start of the BEGIN marker, or after an +END marker in a PEM file. + +=item B<-item> I + +Attempt to decode and print the data as an B I. This can be +used to print out the fields of any supported ASN.1 structure if the type is +known. + +=back + +=head2 Output + +The output will typically contain lines like this: + + 0:d=0 hl=4 l= 681 cons: SEQUENCE + +..... + + 229:d=3 hl=3 l= 141 prim: BIT STRING + 373:d=2 hl=3 l= 162 cons: cont [ 3 ] + 376:d=3 hl=3 l= 159 cons: SEQUENCE + 379:d=4 hl=2 l= 29 cons: SEQUENCE + 381:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Subject Key Identifier + 386:d=5 hl=2 l= 22 prim: OCTET STRING + 410:d=4 hl=2 l= 112 cons: SEQUENCE + 412:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Authority Key Identifier + 417:d=5 hl=2 l= 105 prim: OCTET STRING + 524:d=4 hl=2 l= 12 cons: SEQUENCE + +..... + +This example is part of a self-signed certificate. Each line starts with the +offset in decimal. C specifies the current depth. The depth is increased +within the scope of any SET or SEQUENCE. C gives the header length +(tag and length octets) of the current type. C gives the length of +the contents octets. + +The B<-i> option can be used to make the output more readable. + +Some knowledge of the ASN.1 structure is needed to interpret the output. + +In this example the BIT STRING at offset 229 is the certificate public key. +The contents octets of this will contain the public key information. This can +be examined using the option C<-strparse 229> to yield: + + 0:d=0 hl=3 l= 137 cons: SEQUENCE + 3:d=1 hl=3 l= 129 prim: INTEGER :E5D21E1F5C8D208EA7A2166C7FAF9F6BDF2059669C60876DDB70840F1A5AAFA59699FE471F379F1DD6A487E7D5409AB6A88D4A9746E24B91D8CF55DB3521015460C8EDE44EE8A4189F7A7BE77D6CD3A9AF2696F486855CF58BF0EDF2B4068058C7A947F52548DDF7E15E96B385F86422BEA9064A3EE9E1158A56E4A6F47E5897 + 135:d=1 hl=2 l= 3 prim: INTEGER :010001 + +=head1 NOTES + +If an OID is not part of OpenSSL's internal table it will be represented in +numerical form (for example 1.2.3.4). The file passed to the B<-oid> option +allows additional OIDs to be included. Each line consists of three columns, +the first column is the OID in numerical format and should be followed by white +space. The second column is the "short name" which is a single word followed +by whitespace. The final column is the rest of the line and is the +"long name". Example: + +C<1.2.3.4 shortName A long name> + +For any OID with an associated short and long name, this command will display +the long name. + +=head1 EXAMPLES + +Parse a file: + + openssl asn1parse -in file.pem + +Parse a DER file: + + openssl asn1parse -inform DER -in file.der + +Generate a simple UTF8String: + + openssl asn1parse -genstr 'UTF8:Hello World' + +Generate and write out a UTF8String, don't print parsed output: + + openssl asn1parse -genstr 'UTF8:Hello World' -noout -out utf8.der + +Generate using a config file: + + openssl asn1parse -genconf asn1.cnf -noout -out asn1.der + +Example config file: + + asn1=SEQUENCE:seq_sect + + [seq_sect] + + field1=BOOL:TRUE + field2=EXP:0, UTF8:some random string + + +=head1 BUGS + +There should be options to change the format of output lines. The output of some +ASN.1 types is not well handled (if at all). + +=head1 SEE ALSO + +L, +L + +=head1 COPYRIGHT + +Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/crypto/openssl/doc/man1/asn1parse.pod b/crypto/openssl/doc/man1/openssl-asn1parse.pod.in similarity index 72% rename from crypto/openssl/doc/man1/asn1parse.pod rename to crypto/openssl/doc/man1/openssl-asn1parse.pod.in index 0e1fcc686f6c..f098c89c3382 100644 --- a/crypto/openssl/doc/man1/asn1parse.pod +++ b/crypto/openssl/doc/man1/openssl-asn1parse.pod.in @@ -1,34 +1,34 @@ =pod +{- OpenSSL::safe::output_do_not_edit_headers(); -} =head1 NAME -openssl-asn1parse, -asn1parse - ASN.1 parsing tool +openssl-asn1parse - ASN.1 parsing command =head1 SYNOPSIS B B [B<-help>] -[B<-inform PEM|DER>] -[B<-in filename>] -[B<-out filename>] +[B<-inform> B|B] +[B<-in> I] +[B<-out> I] [B<-noout>] -[B<-offset number>] -[B<-length number>] +[B<-offset> I] +[B<-length> I] [B<-i>] -[B<-oid filename>] +[B<-oid> I] [B<-dump>] -[B<-dlimit num>] -[B<-strparse offset>] -[B<-genstr string>] -[B<-genconf file>] +[B<-dlimit> I] +[B<-strparse> I] +[B<-genstr> I] +[B<-genconf> I] [B<-strictpem>] -[B<-item name>] +[B<-item> I] =head1 DESCRIPTION -The B command is a diagnostic utility that can parse ASN.1 -structures. It can also be used to extract data from ASN.1 formatted data. +This command is a diagnostic utility that can parse ASN.1 structures. +It can also be used to extract data from ASN.1 formatted data. =head1 OPTIONS @@ -38,16 +38,16 @@ structures. It can also be used to extract data from ASN.1 formatted data. Print out a usage message. -=item B<-inform> B +=item B<-inform> B|B -The input format. B is binary format and B (the default) is base64 -encoded. +The input format; the default is B. +See L for details. -=item B<-in filename> +=item B<-in> I The input file, default is standard input. -=item B<-out filename> +=item B<-out> I Output file to place the DER encoded data into. If this option is not present then no data will be output. This is most useful when @@ -57,11 +57,11 @@ combined with the B<-strparse> option. Don't output the parsed version of the input file. -=item B<-offset number> +=item B<-offset> I Starting offset to begin parsing, default is start of file. -=item B<-length number> +=item B<-length> I Number of bytes to parse, default is until end of file. @@ -69,7 +69,7 @@ Number of bytes to parse, default is until end of file. Indents the output according to the "depth" of the structures. -=item B<-oid filename> +=item B<-oid> I A file containing additional OBJECT IDENTIFIERs (OIDs). The format of this file is described in the NOTES section below. @@ -78,23 +78,23 @@ file is described in the NOTES section below. Dump unknown data in hex format. -=item B<-dlimit num> +=item B<-dlimit> I Like B<-dump>, but only the first B bytes are output. -=item B<-strparse offset> +=item B<-strparse> I Parse the contents octets of the ASN.1 object starting at B. This option can be used multiple times to "drill down" into a nested structure. -=item B<-genstr string>, B<-genconf file> +=item B<-genstr> I, B<-genconf> I -Generate encoded data based on B, B or both using -L format. If B only is +Generate encoded data based on I, I or both using +L format. If I only is present then the string is obtained from the default section using the name B. The encoded data is passed through the ASN1 parser and printed out as though it came from a file, the contents can thus be examined and written to a -file using the B option. +file using the B<-out> option. =item B<-strictpem> @@ -104,10 +104,11 @@ processed whether it has the normal PEM BEGIN and END markers or not. This option will ignore any data prior to the start of the BEGIN marker, or after an END marker in a PEM file. -=item B<-item name> +=item B<-item> I -Attempt to decode and print the data as B. This can be used to -print out the fields of any supported ASN.1 structure if the type is known. +Attempt to decode and print the data as an B I. This can be +used to print out the fields of any supported ASN.1 structure if the type is +known. =back @@ -133,9 +134,9 @@ The output will typically contain lines like this: ..... This example is part of a self-signed certificate. Each line starts with the -offset in decimal. B specifies the current depth. The depth is increased -within the scope of any SET or SEQUENCE. B gives the header length -(tag and length octets) of the current type. B gives the length of +offset in decimal. C specifies the current depth. The depth is increased +within the scope of any SET or SEQUENCE. C gives the header length +(tag and length octets) of the current type. C gives the length of the contents octets. The B<-i> option can be used to make the output more readable. @@ -144,7 +145,7 @@ Some knowledge of the ASN.1 structure is needed to interpret the output. In this example the BIT STRING at offset 229 is the certificate public key. The contents octets of this will contain the public key information. This can -be examined using the option B<-strparse 229> to yield: +be examined using the option C<-strparse 229> to yield: 0:d=0 hl=3 l= 137 cons: SEQUENCE 3:d=1 hl=3 l= 129 prim: INTEGER :E5D21E1F5C8D208EA7A2166C7FAF9F6BDF2059669C60876DDB70840F1A5AAFA59699FE471F379F1DD6A487E7D5409AB6A88D4A9746E24B91D8CF55DB3521015460C8EDE44EE8A4189F7A7BE77D6CD3A9AF2696F486855CF58BF0EDF2B4068058C7A947F52548DDF7E15E96B385F86422BEA9064A3EE9E1158A56E4A6F47E5897 @@ -157,11 +158,14 @@ numerical form (for example 1.2.3.4). The file passed to the B<-oid> option allows additional OIDs to be included. Each line consists of three columns, the first column is the OID in numerical format and should be followed by white space. The second column is the "short name" which is a single word followed -by white space. The final column is the rest of the line and is the -"long name". B displays the long name. Example: +by whitespace. The final column is the rest of the line and is the +"long name". Example: C<1.2.3.4 shortName A long name> +For any OID with an associated short and long name, this command will display +the long name. + =head1 EXAMPLES Parse a file: @@ -201,13 +205,14 @@ ASN.1 types is not well handled (if at all). =head1 SEE ALSO +L, L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. -Licensed under the OpenSSL license (the "License"). You may not use +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. diff --git a/crypto/openssl/doc/man1/openssl-ca.pod b/crypto/openssl/doc/man1/openssl-ca.pod new file mode 100644 index 000000000000..545c4933c142 --- /dev/null +++ b/crypto/openssl/doc/man1/openssl-ca.pod @@ -0,0 +1,870 @@ +=pod + +=begin comment + +WARNING: do not edit! +Generated by Makefile from doc/man1/openssl-ca.pod.in + +=end comment + +=head1 NAME + +openssl-ca - sample minimal CA application + +=head1 SYNOPSIS + +B B +[B<-help>] +[B<-verbose>] +[B<-config> I] +[B<-name> I

] +[B<-section> I
] +[B<-gencrl>] +[B<-revoke> I] +[B<-valid> I] +[B<-status> I] +[B<-updatedb>] +[B<-crl_reason> I] +[B<-crl_hold> I] +[B<-crl_compromise> I